diff -Nru blender-2.61/build_files/buildbot/slave_compile.py blender-2.62/build_files/buildbot/slave_compile.py --- blender-2.61/build_files/buildbot/slave_compile.py 2011-12-13 19:54:43.000000000 +0000 +++ blender-2.62/build_files/buildbot/slave_compile.py 2012-02-15 19:39:02.000000000 +0000 @@ -115,6 +115,8 @@ bitness = '64' scons_options.append('BF_BITNESS=' + bitness) + scons_options.append('WITH_BF_CYCLES_CUDA_BINARIES=True') + scons_options.append('BF_CYCLES_CUDA_NVCC=nvcc.exe') retcode = subprocess.call(['python', 'scons/scons.py'] + scons_options) sys.exit(retcode) diff -Nru blender-2.61/build_files/buildbot/slave_pack.py blender-2.62/build_files/buildbot/slave_pack.py --- blender-2.61/build_files/buildbot/slave_pack.py 2011-12-13 19:54:43.000000000 +0000 +++ blender-2.62/build_files/buildbot/slave_pack.py 2012-02-15 19:39:02.000000000 +0000 @@ -79,6 +79,8 @@ bitness = '64' scons_options.append('BF_BITNESS=' + bitness) + scons_options.append('WITH_BF_CYCLES_CUDA_BINARIES=True') + scons_options.append('BF_CYCLES_CUDA_NVCC=nvcc.exe') retcode = subprocess.call(['python', 'scons/scons.py'] + scons_options) sys.exit(retcode) diff -Nru blender-2.61/build_files/cmake/cmake_static_check_cppcheck.py blender-2.62/build_files/cmake/cmake_static_check_cppcheck.py --- blender-2.61/build_files/cmake/cmake_static_check_cppcheck.py 2011-12-13 19:54:42.000000000 +0000 +++ blender-2.62/build_files/cmake/cmake_static_check_cppcheck.py 2012-02-15 19:39:01.000000000 +0000 @@ -37,7 +37,8 @@ CHECKER_ARGS = [ # not sure why this is needed, but it is. "-I" + os.path.join(project_source_info.SOURCE_DIR, "extern", "glew", "include"), - + "--suppress=*:%s/extern/glew/include/GL/glew.h:241" % project_source_info.SOURCE_DIR, + # "--max-configs=1", # speeds up execution # "--check-config", # when includes are missing # "--enable=all", # if you want sixty hundred pedantic suggestions ] diff -Nru blender-2.61/build_files/cmake/config/blender_lite.cmake blender-2.62/build_files/cmake/config/blender_lite.cmake --- blender-2.61/build_files/cmake/config/blender_lite.cmake 2011-12-13 19:54:41.000000000 +0000 +++ blender-2.62/build_files/cmake/config/blender_lite.cmake 2012-02-15 19:38:59.000000000 +0000 @@ -15,6 +15,7 @@ set(WITH_CYCLES OFF CACHE FORCE BOOL) set(WITH_FFTW3 OFF CACHE FORCE BOOL) set(WITH_LIBMV OFF CACHE FORCE BOOL) +set(WITH_CARVE OFF CACHE FORCE BOOL) set(WITH_GAMEENGINE OFF CACHE FORCE BOOL) set(WITH_IK_ITASC OFF CACHE FORCE BOOL) set(WITH_IMAGE_CINEON OFF CACHE FORCE BOOL) @@ -33,6 +34,7 @@ set(WITH_MOD_BOOLEAN OFF CACHE FORCE BOOL) set(WITH_MOD_DECIMATE OFF CACHE FORCE BOOL) set(WITH_MOD_FLUID OFF CACHE FORCE BOOL) +set(WITH_MOD_REMESH OFF CACHE FORCE BOOL) set(WITH_MOD_SMOKE OFF CACHE FORCE BOOL) set(WITH_MOD_OCEANSIM OFF CACHE FORCE BOOL) set(WITH_AUDASPACE OFF CACHE FORCE BOOL) @@ -43,3 +45,4 @@ set(WITH_RAYOPTIMIZATION OFF CACHE FORCE BOOL) set(WITH_SDL OFF CACHE FORCE BOOL) set(WITH_X11_XINPUT OFF CACHE FORCE BOOL) +set(WITH_X11_XF86VMODE OFF CACHE FORCE BOOL) diff -Nru blender-2.61/build_files/cmake/macros.cmake blender-2.62/build_files/cmake/macros.cmake --- blender-2.61/build_files/cmake/macros.cmake 2011-12-13 19:54:42.000000000 +0000 +++ blender-2.62/build_files/cmake/macros.cmake 2012-02-15 19:39:01.000000000 +0000 @@ -665,3 +665,16 @@ endif() endfunction() +macro(set_lib_path + lvar + lproj) + + + if(MSVC10 AND EXISTS ${LIBDIR}/vc2010/${lproj}) + set(${lvar} ${LIBDIR}/vc2010/${lproj}) + else() + set(${lvar} ${LIBDIR}/${lproj}) + endif() + + +endmacro() \ No newline at end of file diff -Nru blender-2.61/build_files/cmake/project_info.py blender-2.62/build_files/cmake/project_info.py --- blender-2.61/build_files/cmake/project_info.py 2011-12-13 19:54:42.000000000 +0000 +++ blender-2.62/build_files/cmake/project_info.py 2012-02-15 19:39:01.000000000 +0000 @@ -133,7 +133,7 @@ """ Extracr includes and defines from cmake. """ - def create_eclipse_project(CMAKE_DIR): + def create_eclipse_project(): print("CMAKE_DIR %r" % CMAKE_DIR) if sys.platform == "win32": cmd = 'cmake "%s" -G"Eclipse CDT4 - MinGW Makefiles"' % CMAKE_DIR @@ -145,7 +145,7 @@ includes = [] defines = [] - create_eclipse_project(CMAKE_DIR) + create_eclipse_project() from xml.dom.minidom import parse tree = parse(join(CMAKE_DIR, ".cproject")) diff -Nru blender-2.61/build_files/cmake/project_source_info.py blender-2.62/build_files/cmake/project_source_info.py --- blender-2.61/build_files/cmake/project_source_info.py 2011-12-13 19:54:42.000000000 +0000 +++ blender-2.62/build_files/cmake/project_source_info.py 2012-02-15 19:39:01.000000000 +0000 @@ -160,7 +160,6 @@ def queue_processes(process_funcs, job_total=-1): """ Takes a list of function arg pairs, each function must return a process """ - import sys if job_total == -1: import multiprocessing diff -Nru blender-2.61/build_files/cmake/RpmBuild.cmake blender-2.62/build_files/cmake/RpmBuild.cmake --- blender-2.61/build_files/cmake/RpmBuild.cmake 2011-12-13 19:54:42.000000000 +0000 +++ blender-2.62/build_files/cmake/RpmBuild.cmake 2012-02-15 19:39:01.000000000 +0000 @@ -13,7 +13,7 @@ if(RPMBUILD) message(STATUS "RPM Build Found: ${RPMBUILD}") - else(RPMBUILD) + else() message(STATUS "RPM Build Not Found (rpmbuild). RPM generation will not be available") endif() @@ -21,6 +21,6 @@ if(RPMBUILD) set(RPMBUILD_FOUND TRUE) -else(RPMBUILD) +else() set(RPMBUILD_FOUND FALSE) endif() \ No newline at end of file diff -Nru blender-2.61/build_files/scons/config/darwin-config.py blender-2.62/build_files/scons/config/darwin-config.py --- blender-2.61/build_files/scons/config/darwin-config.py 2011-12-13 19:54:44.000000000 +0000 +++ blender-2.62/build_files/scons/config/darwin-config.py 2012-02-15 19:39:05.000000000 +0000 @@ -99,7 +99,7 @@ # enable ffmpeg support WITH_BF_FFMPEG = True # -DWITH_FFMPEG -BF_FFMPEG = LIBDIR + '/ffmpeg' +BF_FFMPEG = LIBDIR + '/ffmpeg_0.10' BF_FFMPEG_INC = "${BF_FFMPEG}/include" BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib' BF_FFMPEG_LIB = 'avcodec avdevice avformat avutil mp3lame swscale x264 xvidcore theora theoradec theoraenc vorbis vorbisenc vorbisfile ogg bz2' diff -Nru blender-2.61/build_files/scons/config/freebsd7-config.py blender-2.62/build_files/scons/config/freebsd7-config.py --- blender-2.61/build_files/scons/config/freebsd7-config.py 2011-12-13 19:54:44.000000000 +0000 +++ blender-2.62/build_files/scons/config/freebsd7-config.py 2012-02-15 19:39:05.000000000 +0000 @@ -117,7 +117,7 @@ BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib' # enable ogg, vorbis and theora in ffmpeg -WITH_BF_OGG = True # -DWITH_OGG +WITH_BF_OGG = True BF_OGG = '/usr/local' BF_OGG_INC = '${BF_OGG}/include' BF_OGG_LIB = 'ogg vorbis vorbisenc theoraenc theoradec' diff -Nru blender-2.61/build_files/scons/config/freebsd8-config.py blender-2.62/build_files/scons/config/freebsd8-config.py --- blender-2.61/build_files/scons/config/freebsd8-config.py 2011-12-13 19:54:44.000000000 +0000 +++ blender-2.62/build_files/scons/config/freebsd8-config.py 2012-02-15 19:39:05.000000000 +0000 @@ -117,7 +117,7 @@ BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib' # enable ogg, vorbis and theora in ffmpeg -WITH_BF_OGG = True # -DWITH_OGG +WITH_BF_OGG = True BF_OGG = '/usr/local' BF_OGG_INC = '${BF_OGG}/include' BF_OGG_LIB = 'ogg vorbis vorbisenc theoraenc theoradec' diff -Nru blender-2.61/build_files/scons/config/freebsd9-config.py blender-2.62/build_files/scons/config/freebsd9-config.py --- blender-2.61/build_files/scons/config/freebsd9-config.py 2011-12-13 19:54:44.000000000 +0000 +++ blender-2.62/build_files/scons/config/freebsd9-config.py 2012-02-15 19:39:05.000000000 +0000 @@ -117,7 +117,7 @@ BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib' # enable ogg, vorbis and theora in ffmpeg -WITH_BF_OGG = True # -DWITH_OGG +WITH_BF_OGG = True BF_OGG = '/usr/local' BF_OGG_INC = '${BF_OGG}/include' BF_OGG_LIB = 'ogg vorbis vorbisenc theoraenc theoradec' diff -Nru blender-2.61/build_files/scons/config/linux-config.py blender-2.62/build_files/scons/config/linux-config.py --- blender-2.61/build_files/scons/config/linux-config.py 2011-12-13 19:54:44.000000000 +0000 +++ blender-2.62/build_files/scons/config/linux-config.py 2012-02-15 19:39:05.000000000 +0000 @@ -1,6 +1,8 @@ # find library directory import platform import os +from Modules.FindPython import FindPython + bitness = platform.architecture()[0] if bitness == '64bit': LCGDIR = '../lib/linux64' @@ -8,10 +10,12 @@ LCGDIR = '../lib/linux' LIBDIR = "#${LCGDIR}" -BF_PYTHON_ABI_FLAGS = 'm' # Most common for linux distros -BF_PYTHON = '/usr' -BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib' -BF_PYTHON_VERSION = '3.2' +py = FindPython() + +BF_PYTHON_ABI_FLAGS = py['ABI_FLAGS'] +BF_PYTHON = py['PYTHON'] +BF_PYTHON_LIBPATH = py['LIBPATH'] +BF_PYTHON_VERSION = py['VERSION'] WITH_BF_STATICPYTHON = False BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}${BF_PYTHON_ABI_FLAGS}' BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}' @@ -140,7 +144,7 @@ #BF_FFMPEG_LIB_STATIC = '${BF_FFMPEG_LIBPATH}/libavformat.a ${BF_FFMPEG_LIBPATH/libavcodec.a ${BF_FFMPEG_LIBPATH}/libswscale.a ${BF_FFMPEG_LIBPATH}/libavutil.a ${BF_FFMPEG_LIBPATH}/libavdevice.a' # enable ogg, vorbis and theora in ffmpeg -WITH_BF_OGG = False # -DWITH_OGG +WITH_BF_OGG = False BF_OGG = '/usr' BF_OGG_INC = '${BF_OGG}/include' BF_OGG_LIB = 'ogg vorbis vorbisenc theoraenc theoradec' diff -Nru blender-2.61/build_files/scons/config/linuxcross-config.py blender-2.62/build_files/scons/config/linuxcross-config.py --- blender-2.61/build_files/scons/config/linuxcross-config.py 2011-12-13 19:54:44.000000000 +0000 +++ blender-2.62/build_files/scons/config/linuxcross-config.py 2012-02-15 19:39:05.000000000 +0000 @@ -13,7 +13,7 @@ WITH_BF_STATICOPENAL = False BF_OPENAL = LIBDIR + '/openal' BF_OPENAL_INC = '${BF_OPENAL}/include' -BF_OPENAL_LIB = 'OpenAL32 wrap_oal' +BF_OPENAL_LIB = 'OpenAL32' BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib' # Warning, this static lib configuration is untested! users of this OS please confirm. BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a' diff -Nru blender-2.61/build_files/scons/config/Modules/FindPython.py blender-2.62/build_files/scons/config/Modules/FindPython.py --- blender-2.61/build_files/scons/config/Modules/FindPython.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/build_files/scons/config/Modules/FindPython.py 2012-02-15 19:39:04.000000000 +0000 @@ -0,0 +1,32 @@ +import os + +def FindPython(): + all_abi_flags = ['m', 'mu', ''] + + python = "/usr" + abi_flags = "m" # Most common for linux distros + version = "3.2" + + # Determine ABI flags used on this system + include = os.path.join(python, "include") + for cur_flags in all_abi_flags: + inc = os.path.join(include, "python" + version + cur_flags, "Python.h") + if os.path.exists(inc): + abi_flags = cur_flags + break + + # Determine whether python is in /usr/lib or /usr/lib64 + lib32 = os.path.join(python, "lib", "python" + version, "sysconfig.py") + lib64 = os.path.join(python, "lib64", "python" + version, "sysconfig.py") + if os.path.exists(lib32): + libpath = "${BF_PYTHON}/lib" + elif os.path.exists(lib64): + libpath = "${BF_PYTHON}/lib64" + else: + # roll back to default value + libpath = "${BF_PYTHON}/lib" + + return {'PYTHON': python, + "VERSION": version, + 'LIBPATH': libpath, + 'ABI_FLAGS': abi_flags} diff -Nru blender-2.61/build_files/scons/config/win32-mingw-config.py blender-2.62/build_files/scons/config/win32-mingw-config.py --- blender-2.61/build_files/scons/config/win32-mingw-config.py 2011-12-13 19:54:44.000000000 +0000 +++ blender-2.62/build_files/scons/config/win32-mingw-config.py 2012-02-15 19:39:05.000000000 +0000 @@ -14,7 +14,7 @@ WITH_BF_OPENAL = True BF_OPENAL = LIBDIR + '/openal' BF_OPENAL_INC = '${BF_OPENAL}/include' -BF_OPENAL_LIB = 'wrap_oal' +BF_OPENAL_LIB = 'OpenAL32' BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib' WITH_BF_FFMPEG = True @@ -64,7 +64,7 @@ BF_JPEG_LIBPATH = '${BF_JPEG}/lib' WITH_BF_PNG = True -BF_PNG = LIBDIR + '/png' +BF_PNG = LIBDIR + '/gcc/png' BF_PNG_INC = '${BF_PNG}/include' BF_PNG_LIB = 'png' BF_PNG_LIBPATH = '${BF_PNG}/lib' @@ -156,15 +156,15 @@ WITH_BF_OIIO = True BF_OIIO = LIBDIR + '/gcc/openimageio' -BF_OIIO_INC = '#../lib/windows/gcc/openimageio/include' +BF_OIIO_INC = BF_OIIO + '/include' BF_OIIO_LIB = 'OpenImageIO' -BF_OIIO_LIBPATH = '#../lib/windows/gcc/openimageio/lib' +BF_OIIO_LIBPATH = BF_OIIO + '/lib' WITH_BF_BOOST = True BF_BOOST = LIBDIR + '/boost' -BF_BOOST_INC = '#../lib/windows/boost/include' +BF_BOOST_INC = BF_BOOST + '/include' BF_BOOST_LIB = 'boost_date_time-mgw45-mt-s-1_47 boost_filesystem-mgw45-mt-s-1_47 boost_regex-mgw45-mt-s-1_47 boost_system-mgw45-mt-s-1_47 boost_thread-mgw45-mt-s-1_47' -BF_BOOST_LIBPATH = '#../lib/windows/boost/lib/gcc' +BF_BOOST_LIBPATH = BF_BOOST + '/lib/gcc' #Ray trace optimization WITH_BF_RAYOPTIMIZATION = True @@ -190,6 +190,10 @@ PLATFORM_LINKFLAGS = ['-Xlinker', '--stack=2097152'] +## DISABLED, causes linking errors! +## for re-distrobution, so users dont need mingw installed +# PLATFORM_LINKFLAGS += ["-static-libgcc", "-static-libstdc++"] + BF_DEBUG = False BF_DEBUG_CCFLAGS= ['-g', '-D_DEBUG'] diff -Nru blender-2.61/build_files/scons/config/win32-vc-config.py blender-2.62/build_files/scons/config/win32-vc-config.py --- blender-2.61/build_files/scons/config/win32-vc-config.py 2011-12-13 19:54:44.000000000 +0000 +++ blender-2.62/build_files/scons/config/win32-vc-config.py 2012-02-15 19:39:05.000000000 +0000 @@ -20,7 +20,7 @@ WITH_BF_OPENAL = True BF_OPENAL = LIBDIR + '/openal' BF_OPENAL_INC = '${BF_OPENAL}/include ' -BF_OPENAL_LIB = 'wrap_oal' +BF_OPENAL_LIB = 'OpenAL32' BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib' WITH_BF_ICONV = True @@ -57,7 +57,7 @@ BF_OPENEXR = LIBDIR + '/openexr' BF_OPENEXR_INC = '${BF_OPENEXR}/include ${BF_OPENEXR}/include/IlmImf ${BF_OPENEXR}/include/Iex ${BF_OPENEXR}/include/Imath ' BF_OPENEXR_LIB = ' Iex Half IlmImf Imath IlmThread ' -BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib_vs2008' +BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib' # Warning, this static lib configuration is untested! users of this OS please confirm. BF_OPENEXR_LIB_STATIC = '${BF_OPENEXR}/lib/libHalf.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_OPENEXR}/lib/libIex.a ${BF_OPENEXR}/lib/libImath.a ${BF_OPENEXR}/lib/libIlmThread.a' @@ -72,7 +72,7 @@ WITH_BF_PNG = True BF_PNG = LIBDIR + '/png' BF_PNG_INC = '${BF_PNG}/include' -BF_PNG_LIB = 'libpng_st' +BF_PNG_LIB = 'libpng' BF_PNG_LIBPATH = '${BF_PNG}/lib' WITH_BF_TIFF = True @@ -185,7 +185,7 @@ CC = 'cl.exe' CXX = 'cl.exe' -CCFLAGS = ['/nologo', '/Ob1', '/J', '/W0', '/Gd', '/wd4018', '/wd4244', '/wd4305', '/wd4800', '/wd4065', '/wd4267', '/we4013'] +CCFLAGS = ['/nologo', '/Ob1', '/J', '/W1', '/Gd', '/wd4018', '/wd4244', '/wd4305', '/wd4800', '/wd4065', '/wd4267', '/we4013'] CXXFLAGS = ['/EHsc'] BGE_CXXFLAGS = ['/O2', '/EHsc', '/GR', '/fp:fast', '/arch:SSE'] diff -Nru blender-2.61/build_files/scons/config/win64-vc-config.py blender-2.62/build_files/scons/config/win64-vc-config.py --- blender-2.61/build_files/scons/config/win64-vc-config.py 2011-12-13 19:54:44.000000000 +0000 +++ blender-2.62/build_files/scons/config/win64-vc-config.py 2012-02-15 19:39:05.000000000 +0000 @@ -20,7 +20,7 @@ WITH_BF_OPENAL = True BF_OPENAL = LIBDIR + '/openal' BF_OPENAL_INC = '${BF_OPENAL}/include ' -BF_OPENAL_LIB = 'wrap_oal' +BF_OPENAL_LIB = 'OpenAL32' BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib' WITH_BF_SNDFILE = True @@ -61,7 +61,7 @@ BF_OPENEXR = LIBDIR + '/openexr' BF_OPENEXR_INC = '${BF_OPENEXR}/include ${BF_OPENEXR}/include/IlmImf ${BF_OPENEXR}/include/Iex ${BF_OPENEXR}/include/Imath ' BF_OPENEXR_LIB = ' Iex Half IlmImf Imath IlmThread ' -BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib_vs2008' +BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib' # Warning, this static lib configuration is untested! users of this OS please confirm. BF_OPENEXR_LIB_STATIC = '${BF_OPENEXR}/lib/libHalf.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_OPENEXR}/lib/libIex.a ${BF_OPENEXR}/lib/libImath.a ${BF_OPENEXR}/lib/libIlmThread.a' @@ -190,7 +190,7 @@ CXX = 'cl.exe' CFLAGS = [] -CCFLAGS = ['/nologo', '/Ob1', '/J', '/W0', '/Gd', '/we4013', '/wd4018', '/wd4244', '/wd4305', '/wd4800', '/wd4065', '/wd4267'] +CCFLAGS = ['/nologo', '/Ob1', '/J', '/W1', '/Gd', '/we4013', '/wd4018', '/wd4244', '/wd4305', '/wd4800', '/wd4065', '/wd4267'] CXXFLAGS = ['/EHsc'] BGE_CXXFLAGS = ['/O2', '/EHsc', '/GR', '/fp:fast'] diff -Nru blender-2.61/build_files/scons/tools/Blender.py blender-2.62/build_files/scons/tools/Blender.py --- blender-2.61/build_files/scons/tools/Blender.py 2011-12-13 19:54:43.000000000 +0000 +++ blender-2.62/build_files/scons/tools/Blender.py 2012-02-15 19:39:04.000000000 +0000 @@ -272,7 +272,7 @@ syslibs += Split(lenv['BF_PTHREADS_LIB']) if lenv['WITH_BF_COLLADA']: syslibs.append(lenv['BF_PCRE_LIB']) - if lenv['BF_DEBUG']: + if lenv['BF_DEBUG'] and (lenv['OURPLATFORM'] != 'linux'): syslibs += [colladalib+'_d' for colladalib in Split(lenv['BF_OPENCOLLADA_LIB'])] else: syslibs += Split(lenv['BF_OPENCOLLADA_LIB']) @@ -437,8 +437,9 @@ static_ob, shared_ob = SCons.Tool.createObjBuilders(env) static_ob.add_action('.c', mycaction) static_ob.add_action('.cpp', mycppaction) + static_ob.add_action('.cc', mycppaction) shared_ob.add_action('.c', myshcaction) - shared_ob.add_action('.cpp', myshcppaction) + shared_ob.add_action('.cc', myshcppaction) static_lib = SCons.Builder.Builder(action = mylibaction, emitter = '$LIBEMITTER', @@ -648,8 +649,11 @@ dir = os.path.join(env['BF_INSTALLDIR'], VERSION) + lib = env['BF_PYTHON_LIBPATH'].split(os.sep)[-1] + target_lib = "lib64" if lib == "lib64" else "lib" + py_src = env.subst( env['BF_PYTHON_LIBPATH'] + '/python'+env['BF_PYTHON_VERSION'] ) - py_target = env.subst( dir + '/python/lib/python'+env['BF_PYTHON_VERSION'] ) + py_target = env.subst( dir + '/python/' + target_lib + '/python'+env['BF_PYTHON_VERSION'] ) # This is a bit weak, but dont install if its been installed before, makes rebuilds quite slow. if os.path.exists(py_target): diff -Nru blender-2.61/build_files/scons/tools/btools.py blender-2.62/build_files/scons/tools/btools.py --- blender-2.61/build_files/scons/tools/btools.py 2011-12-13 19:54:43.000000000 +0000 +++ blender-2.62/build_files/scons/tools/btools.py 2012-02-15 19:39:04.000000000 +0000 @@ -152,14 +152,16 @@ 'WITH_BF_FLUID', 'WITH_BF_DECIMATE', 'WITH_BF_BOOLEAN', + 'WITH_BF_REMESH', 'WITH_BF_OCEANSIM', 'WITH_BF_CXX_GUARDEDALLOC', 'WITH_BF_JEMALLOC', 'WITH_BF_STATICJEMALLOC', 'BF_JEMALLOC', 'BF_JEMALLOC_INC', 'BF_JEMALLOC_LIBPATH', 'BF_JEMALLOC_LIB', 'BF_JEMALLOC_LIB_STATIC', 'BUILDBOT_BRANCH', 'WITH_BF_3DMOUSE', 'WITH_BF_STATIC3DMOUSE', 'BF_3DMOUSE', 'BF_3DMOUSE_INC', 'BF_3DMOUSE_LIB', 'BF_3DMOUSE_LIBPATH', 'BF_3DMOUSE_LIB_STATIC', - 'WITH_BF_CYCLES', 'WITH_BF_CYCLES_CUDA_BINARIES' 'BF_CYCLES_CUDA_NVCC', 'BF_CYCLES_CUDA_NVCC', 'WITH_BF_CYCLES_CUDA_THREADED_COMPILE', + 'WITH_BF_CYCLES', 'WITH_BF_CYCLES_CUDA_BINARIES', 'BF_CYCLES_CUDA_NVCC', 'BF_CYCLES_CUDA_NVCC', 'WITH_BF_CYCLES_CUDA_THREADED_COMPILE', 'WITH_BF_OIIO', 'WITH_BF_STATICOIIO', 'BF_OIIO', 'BF_OIIO_INC', 'BF_OIIO_LIB', 'BF_OIIO_LIB_STATIC', 'BF_OIIO_LIBPATH', - 'WITH_BF_BOOST', 'WITH_BF_STATICBOOST', 'BF_BOOST', 'BF_BOOST_INC', 'BF_BOOST_LIB', 'BF_BOOST_LIB_STATIC', 'BF_BOOST_LIBPATH' + 'WITH_BF_BOOST', 'WITH_BF_STATICBOOST', 'BF_BOOST', 'BF_BOOST_INC', 'BF_BOOST_LIB', 'BF_BOOST_LIB_STATIC', 'BF_BOOST_LIBPATH', + 'WITH_BF_LIBMV', 'WITH_BF_CARVE' ] # Have options here that scons expects to be lists @@ -220,15 +222,15 @@ newargs = string.join(args[1:], ' ') cmdline = cmd + " " + newargs startupinfo = subprocess.STARTUPINFO() - startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW + #startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW proc = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, startupinfo=startupinfo, shell = False) data, err = proc.communicate() rv = proc.wait() - if rv: - print "=====" - print err - print "=====" + if data: + print(data) + if err: + print(err) return rv def SetupSpawn( env ): @@ -260,6 +262,7 @@ (BoolVariable('WITH_BF_FLUID', 'Build with Fluid simulation (Elbeem)', True)), (BoolVariable('WITH_BF_DECIMATE', 'Build with decimate modifier', True)), (BoolVariable('WITH_BF_BOOLEAN', 'Build with boolean modifier', True)), + (BoolVariable('WITH_BF_REMESH', 'Build with remesh modifier', True)), (BoolVariable('WITH_BF_OCEANSIM', 'Build with ocean simulation', False)), ('BF_PROFILE_FLAGS', 'Profiling compiler flags', ''), (BoolVariable('WITH_BF_OPENAL', 'Use OpenAL if true', False)), @@ -320,7 +323,7 @@ (BoolVariable('WITH_BF_STATICFFMPEG', 'Use static FFMPEG if true', False)), ('BF_FFMPEG_LIB_STATIC', 'Static FFMPEG libraries', ''), - (BoolVariable('WITH_BF_OGG', 'Use OGG, THEORA, VORBIS in FFMPEG if true', + (BoolVariable('WITH_BF_OGG', 'Link OGG, THEORA, VORBIS with FFMPEG if true', False)), ('BF_OGG', 'OGG base path', ''), ('BF_OGG_LIB', 'OGG library', ''), @@ -518,6 +521,7 @@ (BoolVariable('WITH_BF_LZO', 'Enable fast LZO pointcache compression', True)), (BoolVariable('WITH_BF_LZMA', 'Enable best LZMA pointcache compression', True)), + (BoolVariable('WITH_BF_CARVE', 'Enable carve library for mesh boolean operations', True)), (BoolVariable('WITH_BF_LIBMV', 'Enable libmv structure from motion library', True)), diff -Nru blender-2.61/CMakeLists.txt blender-2.62/CMakeLists.txt --- blender-2.61/CMakeLists.txt 2011-12-13 19:57:52.000000000 +0000 +++ blender-2.62/CMakeLists.txt 2012-02-15 19:42:25.000000000 +0000 @@ -156,6 +156,7 @@ if(UNIX AND NOT APPLE) option(WITH_X11_XINPUT "Enable X11 Xinput (tablet support and unicode input)" ON) + option(WITH_X11_XF86VMODE "Enable X11 video mode switching" ON) option(WITH_BUILTIN_GLEW "Use GLEW OpenGL wrapper library bundled with blender" ON) option(WITH_XDG_USER_DIRS "Build with XDG Base Directory Specification (only config and documents for now)" OFF) mark_as_advanced(WITH_XDG_USER_DIRS) @@ -169,6 +170,7 @@ option(WITH_MOD_SMOKE "Enable Smoke Modifier (Smoke Simulation)" ON) option(WITH_MOD_DECIMATE "Enable Decimate Modifier" ON) option(WITH_MOD_BOOLEAN "Enable Boolean Modifier" ON) +option(WITH_MOD_REMESH "Enable Remesh Modifier" ON) option(WITH_MOD_CLOTH_ELTOPO "Enable Experemental cloth solver" OFF) mark_as_advanced(WITH_MOD_CLOTH_ELTOPO) option(WITH_MOD_OCEANSIM "Enable Ocean Modifier" OFF) @@ -206,6 +208,9 @@ # Camera/motion tracking option(WITH_LIBMV "Enable libmv structure from motion library" ON) +# Mesh boolean lib +option(WITH_CARVE "Enable Carve library to handle mesh boolean operations" ON) + # Misc option(WITH_INPUT_NDOF "Enable NDOF input devices (SpaceNavigator and friends)" ON) option(WITH_RAYOPTIMIZATION "Enable use of SIMD (SSE) optimizations for the raytracer" ON) @@ -244,6 +249,12 @@ "Choose the minimum OSX version required: 10.4 or 10.5" FORCE) endif() + if(${CMAKE_GENERATOR} MATCHES "Xcode" AND (${XCODE_VERSION} VERSION_EQUAL 4 OR ${XCODE_VERSION} VERSION_GREATER 4)) + # Xcode 4 defaults to the Apple LLVM Compiler. + # Override the default compiler selection because Blender only compiles with gcc + set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvmgcc42") + message(STATUS "Setting compiler to: " ${CMAKE_XCODE_ATTRIBUTE_GCC_VERSION}) + endif() option(WITH_COCOA "Use Cocoa framework instead of deprecated Carbon" ON) option(USE_QTKIT "Use QtKit instead of Carbon quicktime (needed for having partial quicktime for 64bit)" OFF) option(WITH_LIBS10.5 "Use 10.5 libs (needed for 64bit builds)" OFF) @@ -268,8 +279,8 @@ message(FATAL_ERROR "WITH_GHOST_SDL requires WITH_SDL to be ON") endif() -if(NOT WITH_IMAGE_OPENJPEG AND WITH_IMAGE_REDCODE) - message(FATAL_ERROR "WITH_IMAGE_REDCODE requires WITH_IMAGE_OPENJPEG") +if(WITH_IMAGE_REDCODE AND ((NOT WITH_IMAGE_OPENJPEG) OR (NOT WITH_CODEC_FFMPEG))) + message(FATAL_ERROR "WITH_IMAGE_REDCODE requires WITH_IMAGE_OPENJPEG and WITH_CODEC_FFMPEG") endif() # python module, needs some different options @@ -281,10 +292,12 @@ message(FATAL_ERROR "WITH_PYTHON_MODULE requires WITH_PYTHON_INSTALL to be OFF") endif() -if(WITH_CODEC_QUICKTIME AND MINGW) - message(FATAL_ERROR "MINGW requires WITH_CODEC_QUICKTIME to be OFF " - "because it is currently unsupported, remove this " - "line if youre a developer who wants to add support.") +if(MINGW) + if(WITH_CODEC_QUICKTIME) + message(FATAL_ERROR "MINGW requires WITH_CODEC_QUICKTIME to be OFF " + "because it is currently unsupported, remove this " + "line if youre a developer who wants to add support.") + endif() endif() if(NOT WITH_FFTW3 AND WITH_MOD_OCEANSIM) @@ -296,9 +309,13 @@ set(WITH_HEADLESS ON) endif() -# auto enable openimageio and boost for cycles +# auto enable openimageio for cycles if(WITH_CYCLES) set(WITH_OPENIMAGEIO ON) +endif() + +# auto enable boost for cycles and carve +if(WITH_CYCLES OR WITH_CARVE) set(WITH_BOOST ON) endif() @@ -457,7 +474,8 @@ # use lib dir if available and nothing else specified if(LIBDIR AND NOT FFMPEG) set(FFMPEG ${LIBDIR}/ffmpeg CACHE PATH "FFMPEG Directory") - set(FFMPEG_LIBRARIES avformat avcodec avutil avdevice swscale dirac_encoder mp3lame ogg orc-0.4 schroedinger-1.0 theora theoraenc theoradec vorbis vorbisenc vpx x264 xvidcore faad asound CACHE STRING "FFMPEG Libraries") + # XXX, some distros might need 'theoraenc theoradec' too + set(FFMPEG_LIBRARIES avformat avcodec avutil avdevice swscale dirac_encoder mp3lame ogg orc-0.4 schroedinger-1.0 theora vorbis vorbisenc vpx x264 xvidcore faad asound CACHE STRING "FFMPEG Libraries") else() set(FFMPEG /usr CACHE PATH "FFMPEG Directory") set(FFMPEG_LIBRARIES avformat avcodec avutil avdevice swscale CACHE STRING "FFMPEG Libraries") @@ -581,6 +599,17 @@ if(WITH_X11_XINPUT) set(PLATFORM_LINKLIBS "${PLATFORM_LINKLIBS} ${X11_Xinput_LIB}") endif() + + if(WITH_X11_XF86VMODE) + # XXX, why dont cmake make this available? + FIND_LIBRARY(X11_Xxf86vmode_LIB Xxf86vm ${X11_LIB_SEARCH_PATH}) + mark_as_advanced(X11_Xxf86vmode_LIB) + if(X11_Xxf86vmode_LIB) + set(PLATFORM_LINKLIBS "${PLATFORM_LINKLIBS} ${X11_Xxf86vmode_LIB}") + else() + set(WITH_X11_XF86VMODE OFF) + endif() + endif() endif() if(CMAKE_SYSTEM_NAME MATCHES "Linux") @@ -604,6 +633,10 @@ # CLang is the same as GCC for now. elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing") + # Solaris CC + elseif(CMAKE_CXX_COMPILER_ID MATCHES "SunPro") + set(PLATFORM_CFLAGS "-pipe -features=extensions -fPIC -D__FUNCTION__=__func__") + # Intel C++ Compiler elseif(CMAKE_C_COMPILER_ID MATCHES "Intel") # think these next two are broken @@ -649,10 +682,6 @@ set(ICONV_LIBPATH ${ICONV}/lib) endif() - set(PNG "${LIBDIR}/png") - set(PNG_INCLUDE_DIR "${PNG}/include") - set(PNG_LIBPATH ${PNG}/lib) # not cmake defined - set(JPEG "${LIBDIR}/jpeg") set(JPEG_INCLUDE_DIR "${JPEG}/include") set(JPEG_LIBPATH ${JPEG}/lib) # not cmake defined @@ -662,7 +691,7 @@ if(WITH_OPENAL) set(OPENAL ${LIBDIR}/openal) set(OPENAL_INCLUDE_DIR ${OPENAL}/include) - set(OPENAL_LIBRARY wrap_oal) + set(OPENAL_LIBRARY OpenAL32) set(OPENAL_LIBPATH ${OPENAL}/lib) endif() @@ -700,8 +729,8 @@ add_definitions(/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /D_CONSOLE /D_LIB) - set(CMAKE_CXX_FLAGS "/nologo /J /W0 /Gd /wd4018 /wd4244 /wd4305 /wd4800 /wd4065 /wd4267 /we4013" CACHE STRING "MSVC MT C++ flags " FORCE) - set(CMAKE_C_FLAGS "/nologo /J /W0 /Gd /wd4018 /wd4244 /wd4305 /wd4800 /wd4065 /wd4267 /we4013 /EHsc" CACHE STRING "MSVC MT C++ flags " FORCE) + set(CMAKE_CXX_FLAGS "/nologo /J /W1 /Gd /wd4018 /wd4244 /wd4305 /wd4800 /wd4065 /wd4267 /we4013" CACHE STRING "MSVC MT C++ flags " FORCE) + set(CMAKE_C_FLAGS "/nologo /J /W1 /Gd /wd4018 /wd4244 /wd4305 /wd4800 /wd4065 /wd4267 /we4013 /EHsc" CACHE STRING "MSVC MT C++ flags " FORCE) if(CMAKE_CL_64) set(CMAKE_CXX_FLAGS_DEBUG "/Od /Gm /EHsc /RTC1 /MTd /W3 /nologo /Zi /J" CACHE STRING "MSVC MT flags " FORCE) @@ -727,12 +756,12 @@ set(GETTEXT_LIBRARIES gnu_gettext) endif() - if(CMAKE_CL_64) - set(PNG_LIBRARIES libpng) - else() - set(PNG_LIBRARIES libpng_st) - endif() + set(PNG_LIBRARIES libpng) set(JPEG_LIBRARIES libjpeg) + + set(PNG "${LIBDIR}/png") + set(PNG_INCLUDE_DIR "${PNG}/include") + set(PNG_LIBPATH ${PNG}/lib) # not cmake defined set(ZLIB_INCLUDE_DIRS ${LIBDIR}/zlib/include) if(CMAKE_CL_64) @@ -767,22 +796,27 @@ ${LIBDIR}/opencollada/include/COLLADASaxFrameworkLoader/include ${LIBDIR}/opencollada/include/GeneratedSaxParser/include ) + + set_lib_path(OPENCOLLADA_LIBPATH "opencollada/lib") set(OPENCOLLADA_LIBRARIES - ${LIBDIR}/opencollada/lib/OpenCOLLADASaxFrameworkLoader.lib - ${LIBDIR}/opencollada/lib/OpenCOLLADAFramework.lib - ${LIBDIR}/opencollada/lib/OpenCOLLADABaseUtils.lib - ${LIBDIR}/opencollada/lib/OpenCOLLADAStreamWriter.lib - ${LIBDIR}/opencollada/lib/MathMLSolver.lib - ${LIBDIR}/opencollada/lib/GeneratedSaxParser.lib - ${LIBDIR}/opencollada/lib/xml2.lib - ${LIBDIR}/opencollada/lib/buffer.lib - ${LIBDIR}/opencollada/lib/ftoa.lib - ${LIBDIR}/opencollada/lib/UTF.lib + ${OPENCOLLADA_LIBPATH}/OpenCOLLADASaxFrameworkLoader.lib + ${OPENCOLLADA_LIBPATH}/OpenCOLLADAFramework.lib + ${OPENCOLLADA_LIBPATH}/OpenCOLLADABaseUtils.lib + ${OPENCOLLADA_LIBPATH}/OpenCOLLADAStreamWriter.lib + ${OPENCOLLADA_LIBPATH}/MathMLSolver.lib + ${OPENCOLLADA_LIBPATH}/GeneratedSaxParser.lib + ${OPENCOLLADA_LIBPATH}/xml2.lib + ${OPENCOLLADA_LIBPATH}/buffer.lib + ${OPENCOLLADA_LIBPATH}/ftoa.lib + ${OPENCOLLADA_LIBPATH}/UTF.lib ) set(PCRE_LIBRARIES - ${LIBDIR}/opencollada/lib/pcre.lib + ${OPENCOLLADA_LIBPATH}/pcre.lib ) + + unset(OPENCOLLADA_LIBPATH) + endif() if(WITH_CODEC_FFMPEG) @@ -800,18 +834,8 @@ endif() if(WITH_IMAGE_OPENEXR) - if(MSVC90) - set(MSVC_LIB _vs2008) - set(MSVC_INC) - elseif(MSVC10) - set(MSVC_LIB _vs2010) - set(MSVC_INC _vs2010) - else() - set(MSVC_LIB msvc) - set(MSVC_INC) - endif() - set(OPENEXR ${LIBDIR}/openexr) - set(OPENEXR_LIBPATH ${OPENEXR}/lib${MSVC_LIB}) + set_lib_path(OPENEXR "openexr") + set_lib_path(OPENEXR_LIBPATH "openexr/lib") set(OPENEXR_LIBRARIES ${OPENEXR_LIBPATH}/Iex.lib ${OPENEXR_LIBPATH}/Half.lib @@ -819,7 +843,7 @@ ${OPENEXR_LIBPATH}/Imath.lib ${OPENEXR_LIBPATH}/IlmThread.lib ) - set(OPENEXR_INCUDE ${OPENEXR}/include${MSVC_INC}) + set_lib_path(OPENEXR_INCUDE "openexr/include") set(OPENEXR_INCLUDE_DIRS ${OPENEXR_INCUDE} ${OPENEXR_INCUDE}/IlmImf @@ -846,9 +870,9 @@ if(WITH_PYTHON) # normally cached but not since we include them with blender set(PYTHON_VERSION 3.2) # CACHE STRING) - set(PYTHON_INCLUDE_DIR "${LIBDIR}/python/include/python${PYTHON_VERSION}") # CACHE PATH) - set(PYTHON_LIBRARY "${LIBDIR}/python/lib/python32.lib") #CACHE FILEPATH) - + set_lib_path(PYTHON_INCLUDE_DIR "python/include/python${PYTHON_VERSION}") + set_lib_path(PYTHON_LIBRARY "python/lib/python32.lib") #CACHE FILEPATH) + # uncached vars set(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIR}") set(PYTHON_LIBRARIES "${PYTHON_LIBRARY}") @@ -881,7 +905,7 @@ set(OPENIMAGEIO ${LIBDIR}/openimageio) set(OPENIMAGEIO_INCLUDE_DIRS ${OPENIMAGEIO}/include) set(OPENIMAGEIO_LIBRARIES OpenImageIO) - set(OPENIMAGEIO_LIBPATH ${OPENIMAGEIO}/lib) + set_lib_path(OPENIMAGEIO_LIBPATH "openimageio/lib") set(OPENIMAGEIO_DEFINITIONS) endif() @@ -913,6 +937,10 @@ set(GETTEXT_LIBPATH ${GETTEXT}/lib) set(GETTEXT_LIBRARIES intl) endif() + + set(PNG "${LIBDIR}/gcc/png") + set(PNG_INCLUDE_DIR "${PNG}/include") + set(PNG_LIBPATH ${PNG}/lib) # not cmake defined set(JPEG_LIBRARIES libjpeg) set(PNG_LIBRARIES png) @@ -1016,9 +1044,13 @@ set(OPENIMAGEIO_LIBPATH ${OPENIMAGEIO}/lib) set(OPENIMAGEIO_DEFINITIONS) endif() - + set(PLATFORM_LINKFLAGS "-Xlinker --stack=2097152") + ## DISABLE - causes linking errors + ## for re-distrobution, so users dont need mingw installed + # set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -static-libgcc -static-libstdc++") + endif() # used in many places so include globally, like OpenGL @@ -1066,16 +1098,28 @@ endif() if(WITH_PYTHON) - # we use precompiled libraries for py 3.2 and up by default + if(NOT WITH_PYTHON_MODULE) + # we use precompiled libraries for py 3.2 and up by default - # normally cached but not since we include them with blender - set(PYTHON_VERSION 3.2) - set(PYTHON_INCLUDE_DIR "${LIBDIR}/python/include/python${PYTHON_VERSION}") - # set(PYTHON_BINARY "${LIBDIR}/python/bin/python${PYTHON_VERSION}") # not used yet - set(PYTHON_LIBRARY python${PYTHON_VERSION}) - set(PYTHON_LIBPATH "${LIBDIR}/python/lib/python${PYTHON_VERSION}") - # set(PYTHON_LINKFLAGS "-u _PyMac_Error") # won't build with this enabled + # normally cached but not since we include them with blender + set(PYTHON_VERSION 3.2) + set(PYTHON_INCLUDE_DIR "${LIBDIR}/python/include/python${PYTHON_VERSION}") + # set(PYTHON_BINARY "${LIBDIR}/python/bin/python${PYTHON_VERSION}") # not used yet + set(PYTHON_LIBRARY python${PYTHON_VERSION}) + set(PYTHON_LIBPATH "${LIBDIR}/python/lib/python${PYTHON_VERSION}") + # set(PYTHON_LINKFLAGS "-u _PyMac_Error") # won't build with this enabled + else() + # module must be compiled against Python framework + # normally cached but not since we include them with blender + set(PYTHON_VERSION 3.2) + set(PYTHON_INCLUDE_DIR "/Library/Frameworks/Python.framework/Versions/${PYTHON_VERSION}/include/python${PYTHON_VERSION}m") + set(PYTHON_BINARY "/Library/Frameworks/Python.framework/Versions/${PYTHON_VERSION}/bin/python${PYTHON_VERSION}") + #set(PYTHON_LIBRARY python${PYTHON_VERSION}) + set(PYTHON_LIBPATH "/Library/Frameworks/Python.framework/Versions/${PYTHON_VERSION}/lib/python${PYTHON_VERSION}/config-3.2m") + #set(PYTHON_LINKFLAGS "-u _PyMac_Error -framework Python") # won't build with this enabled + endif() + # uncached vars set(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIR}") set(PYTHON_LIBRARIES "${PYTHON_LIBRARY}") @@ -1170,7 +1214,11 @@ set(PLATFORM_LINKFLAGS "-fexceptions -framework CoreServices -framework Foundation -framework IOKit -framework AppKit -framework Carbon -framework AGL -framework AudioUnit -framework AudioToolbox -framework CoreAudio -framework QuickTime") set(WITH_INPUT_NDOF OFF) # unsupported endif() - + + if(WITH_PYTHON_MODULE) + set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} /Library/Frameworks/Python.framework/Versions/${PYTHON_VERSION}/python")# force cmake to link right framework + endif() + if(WITH_OPENCOLLADA) set(OPENCOLLADA ${LIBDIR}/opencollada) @@ -1395,7 +1443,10 @@ # disable because it gives warnings for printf() & friends. # ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_DOUBLE_PROMOTION -Wdouble-promotion -Wno-error=double-promotion) - ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_ERROR_UNUSED_BUT_SET_VARIABLE -Wno-error=unused-but-set-variable) + + if(NOT APPLE) + ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_ERROR_UNUSED_BUT_SET_VARIABLE -Wno-error=unused-but-set-variable) + endif() ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_ALL -Wall) ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_INVALID_OFFSETOF -Wno-invalid-offsetof) @@ -1407,7 +1458,10 @@ # flags to undo strict flags ADD_CHECK_C_COMPILER_FLAG(CC_REMOVE_STRICT_FLAGS C_WARN_NO_DEPRECATED_DECLARATIONS -Wno-deprecated-declarations) ADD_CHECK_C_COMPILER_FLAG(CC_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_PARAMETER -Wno-unused-parameter) - ADD_CHECK_C_COMPILER_FLAG(CC_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_BUT_SET_VARIABLE -Wno-unused-but-set-variable) + + if(NOT APPLE) + ADD_CHECK_C_COMPILER_FLAG(CC_REMOVE_STRICT_FLAGS C_WARN_NO_ERROR_UNUSED_BUT_SET_VARIABLE -Wno-error=unused-but-set-variable) + endif() elseif(CMAKE_C_COMPILER_ID MATCHES "Intel") @@ -1429,19 +1483,16 @@ if(MSVC10) if(WITH_IMAGE_OPENEXR) message(WARNING "MSVC 2010 does not support OpenEXR, disabling WITH_IMAGE_OPENEXR. To enable support use Use MSVC 2008") - set(WITH_IMAGE_OPENEXR OFF) endif() if(WITH_OPENCOLLADA) message(WARNING "MSVC 2010 does not support OpenCollada, disabling WITH_OPENCOLLADA. To enable support use Use MSVC 2008") - set(WITH_OPENCOLLADA OFF) endif() endif() if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") - if(WITH_IK_ITASC OR WITH_MOD_FLUID) + if(WITH_IK_ITASC) message(WARNING "Using Clang as CXX compiler: disabling WITH_IK_ITASC and WITH_MOD_FLUID, these features will be missing.") set(WITH_IK_ITASC OFF) - set(WITH_MOD_FLUID OFF) endif() endif() @@ -1545,6 +1596,7 @@ info_cfg_text("System Options:") info_cfg_option(WITH_INSTALL_PORTABLE) + info_cfg_option(WITH_X11_XF86VMODE) info_cfg_option(WITH_X11_XINPUT) info_cfg_option(WITH_BUILTIN_GLEW) @@ -1575,6 +1627,7 @@ info_cfg_text("Modifiers:") info_cfg_option(WITH_MOD_BOOLEAN) + info_cfg_option(WITH_MOD_REMESH) info_cfg_option(WITH_MOD_DECIMATE) info_cfg_option(WITH_MOD_FLUID) info_cfg_option(WITH_MOD_OCEANSIM) diff -Nru blender-2.61/debian/changelog blender-2.62/debian/changelog --- blender-2.61/debian/changelog 2012-01-28 12:47:22.000000000 +0000 +++ blender-2.62/debian/changelog 2012-03-16 16:07:49.000000000 +0000 @@ -1,3 +1,17 @@ +blender (2.62-1) unstable; urgency=low + + * New upstream release (Closes: #661063) + + debian/patches: #0002 dropped (applied upstream) + + debian/patches: #0010 dropped (applied upstream) + + debian/patches: #0012 dropped (applied upstream) + + debian/patches: #0013 dropped (applied upstream) + * debian/control: libglew-dev b-deps fixed + * debian/control: libboost-dev added to b-deps + * debian/control: Standards-Version bumped to 3.9.3 + * debian/rules: Ocean Sim support added (Closes: #659442) + + -- Matteo F. Vescovi Mon, 12 Mar 2012 19:04:53 +0100 + blender (2.61-2) unstable; urgency=low [ Antonio Ospite ] diff -Nru blender-2.61/debian/control blender-2.62/debian/control --- blender-2.61/debian/control 2012-01-28 12:47:22.000000000 +0000 +++ blender-2.62/debian/control 2012-03-16 16:07:49.000000000 +0000 @@ -13,9 +13,10 @@ libalut-dev, libavdevice-dev, libavformat-dev, + libboost-dev, libfftw3-dev, libgettextpo-dev, - libglew1.6-dev, + libglew-dev, libgsm1-dev, libjack-dev, libjpeg-dev, @@ -37,7 +38,7 @@ python-support, python3.2-dev Build-Conflicts: nvidia-glx -Standards-Version: 3.9.2 +Standards-Version: 3.9.3 Homepage: http://blender.org Vcs-Git: git://anonscm.debian.org/pkg-multimedia/blender.git Vcs-Browser: http://anonscm.debian.org/gitweb/?p=pkg-multimedia/blender.git diff -Nru blender-2.61/debian/copyright blender-2.62/debian/copyright --- blender-2.61/debian/copyright 2012-01-28 12:47:22.000000000 +0000 +++ blender-2.62/debian/copyright 2012-03-16 16:07:49.000000000 +0000 @@ -1,4 +1,4 @@ -Format: http://anonscm.debian.org/viewvc/dep/web/deps/dep5.mdwn?revision=240 +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: blender Upstream-Author: Blender Foundation Source: http://download.blender.org/source/ @@ -28,6 +28,6 @@ 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. -Comment: + . On Debian systems, the complete text of the GNU General Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". diff -Nru blender-2.61/debian/gbp.conf blender-2.62/debian/gbp.conf --- blender-2.61/debian/gbp.conf 2012-01-28 12:47:22.000000000 +0000 +++ blender-2.62/debian/gbp.conf 2012-03-16 16:07:49.000000000 +0000 @@ -1,3 +1,3 @@ [DEFAULT] pristine-tar = True -compression = bzip2 +#compression = bzip2 diff -Nru blender-2.61/debian/patches/0001-blender_thumbnailer.patch blender-2.62/debian/patches/0001-blender_thumbnailer.patch --- blender-2.61/debian/patches/0001-blender_thumbnailer.patch 2012-01-28 12:47:22.000000000 +0000 +++ blender-2.62/debian/patches/0001-blender_thumbnailer.patch 2012-03-16 16:07:49.000000000 +0000 @@ -29,10 +29,10 @@ import struct diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt -index 79a7f5b..27c13d7 100644 +index 1b4d88a..8bd89d6 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt -@@ -360,7 +360,7 @@ if(UNIX AND NOT APPLE) +@@ -376,7 +376,7 @@ if(UNIX AND NOT APPLE) ) install( PROGRAMS ${CMAKE_SOURCE_DIR}/release/bin/blender-thumbnailer.py @@ -41,4 +41,3 @@ ) install( FILES ${CMAKE_SOURCE_DIR}/doc/manpage/blender.1 --- diff -Nru blender-2.61/debian/patches/0002-disable_tests.patch blender-2.62/debian/patches/0002-disable_tests.patch --- blender-2.61/debian/patches/0002-disable_tests.patch 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/debian/patches/0002-disable_tests.patch 2012-03-16 16:07:49.000000000 +0000 @@ -0,0 +1,21 @@ +From: Kevin Roy +Date: Fri, 15 Apr 2011 19:44:00 +0200 +Subject: disable_tests + +added WITH_TESTS condition to implicitly disable +--- + source/CMakeLists.txt | 4 +++- + 1 files changed, 3 insertions(+), 1 deletions(-) + +diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt +index 529aaac..eb1f32a 100644 +--- a/source/CMakeLists.txt ++++ b/source/CMakeLists.txt +@@ -33,4 +33,6 @@ if(WINDOWS) + add_subdirectory(icons) + endif() + +-add_subdirectory(tests) ++if(WITH_TESTS) ++ add_subdirectory(tests) ++endif() diff -Nru blender-2.61/debian/patches/0002-fix_FTBFS_on_KFreeBSD.patch blender-2.62/debian/patches/0002-fix_FTBFS_on_KFreeBSD.patch --- blender-2.61/debian/patches/0002-fix_FTBFS_on_KFreeBSD.patch 2012-01-28 12:47:22.000000000 +0000 +++ blender-2.62/debian/patches/0002-fix_FTBFS_on_KFreeBSD.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -From: Kevin 'kiniou' Roy -Date: Tue, 28 Sep 2010 15:50:17 +0200 -Subject: fix_FTBFS_on_KFreeBSD - -added __GNU__ and __GLIBC__ to conditional defined in order to compile on KFreeBSD ---- - source/blender/blenlib/intern/storage.c | 4 ++-- - 1 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c -index 001b191..c5b6f46 100644 ---- a/source/blender/blenlib/intern/storage.c -+++ b/source/blender/blenlib/intern/storage.c -@@ -54,7 +54,7 @@ - #include - #endif - --#if defined(linux) || defined(__CYGWIN32__) || defined(__hpux) -+#if defined(linux) || defined(__CYGWIN32__) || defined(__hpux) || defined(__GNU__) || defined(__GLIBC__) - #include - #endif - -@@ -180,7 +180,7 @@ double BLI_dir_free_space(const char *dir) - if (slash) slash[1] = 0; - } else strcpy(name,"/"); - --#if defined (__FreeBSD__) || defined (linux) || defined (__OpenBSD__) || defined (__APPLE__) -+#if defined (__FreeBSD__) || defined (linux) || defined (__OpenBSD__) || defined (__APPLE__) || defined(__GNU__) || defined(__GLIBC__) - if (statfs(name, &disk)) return(-1); - #endif - --- diff -Nru blender-2.61/debian/patches/0003-disable_tests.patch blender-2.62/debian/patches/0003-disable_tests.patch --- blender-2.61/debian/patches/0003-disable_tests.patch 2012-01-28 12:47:22.000000000 +0000 +++ blender-2.62/debian/patches/0003-disable_tests.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -From: Kevin Roy -Date: Fri, 15 Apr 2011 19:44:00 +0200 -Subject: disable_tests - -added WITH_TESTS condition to implicitly disable ---- - source/CMakeLists.txt | 4 +++- - 1 files changed, 3 insertions(+), 1 deletions(-) - -diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt -index 529aaac..eb1f32a 100644 ---- a/source/CMakeLists.txt -+++ b/source/CMakeLists.txt -@@ -33,4 +33,6 @@ if(WINDOWS) - add_subdirectory(icons) - endif() - --add_subdirectory(tests) -+if(WITH_TESTS) -+ add_subdirectory(tests) -+endif() --- diff -Nru blender-2.61/debian/patches/0003-install_in_usr_lib.patch blender-2.62/debian/patches/0003-install_in_usr_lib.patch --- blender-2.61/debian/patches/0003-install_in_usr_lib.patch 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/debian/patches/0003-install_in_usr_lib.patch 2012-03-16 16:07:49.000000000 +0000 @@ -0,0 +1,39 @@ +From: "Matteo F. Vescovi" +Date: Thu, 5 Jan 2012 09:50:48 +0100 +Subject: install_in_usr_lib + + * Arch-specific files go to /usr/lib rather than /usr/share + * Make blender look for systemdir into /usr/lib instead of /usr/share +--- + intern/ghost/intern/GHOST_SystemPathsX11.cpp | 2 +- + source/creator/CMakeLists.txt | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/intern/ghost/intern/GHOST_SystemPathsX11.cpp b/intern/ghost/intern/GHOST_SystemPathsX11.cpp +index 7261491..30ff1da 100644 +--- a/intern/ghost/intern/GHOST_SystemPathsX11.cpp ++++ b/intern/ghost/intern/GHOST_SystemPathsX11.cpp +@@ -47,7 +47,7 @@ + #endif + + #ifdef PREFIX +-static const char *static_path= PREFIX "/share" ; ++static const char *static_path= PREFIX "/lib" ; + #else + static const char *static_path= NULL; + #endif +diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt +index 8bd89d6..7a6a581 100644 +--- a/source/creator/CMakeLists.txt ++++ b/source/creator/CMakeLists.txt +@@ -273,8 +273,8 @@ if(WITH_PYTHON) + endif() + + install( +- DIRECTORY ${CMAKE_SOURCE_DIR}/release/scripts +- DESTINATION ${TARGETDIR_VER} ++ DIRECTORY ${CMAKE_SOURCE_DIR}/release/scripts/ ++ DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/blender/scripts/ + PATTERN ".svn" EXCLUDE + PATTERN "__pycache__" EXCLUDE + PATTERN "${ADDON_EXCLUDE_CONDITIONAL}" EXCLUDE diff -Nru blender-2.61/debian/patches/0004-filter_docs_to_install.patch blender-2.62/debian/patches/0004-filter_docs_to_install.patch --- blender-2.61/debian/patches/0004-filter_docs_to_install.patch 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/debian/patches/0004-filter_docs_to_install.patch 2012-03-16 16:07:49.000000000 +0000 @@ -0,0 +1,22 @@ +From: "Matteo F. Vescovi" +Date: Thu, 22 Dec 2011 18:13:03 +0100 +Subject: filter_docs_to_install + +Install relevant documentation +--- + source/creator/CMakeLists.txt | 2 -- + 1 files changed, 0 insertions(+), 2 deletions(-) + +diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt +index 7a6a581..7480ab8 100644 +--- a/source/creator/CMakeLists.txt ++++ b/source/creator/CMakeLists.txt +@@ -218,8 +218,6 @@ else() + endif() + + set(BLENDER_TEXT_FILES +- ${CMAKE_SOURCE_DIR}/release/text/GPL-license.txt +- ${CMAKE_SOURCE_DIR}/release/text/Python-license.txt + ${CMAKE_SOURCE_DIR}/release/text/copyright.txt + ${CMAKE_SOURCE_DIR}/release/text/readme.html + ) diff -Nru blender-2.61/debian/patches/0004-install_in_usr_lib.patch blender-2.62/debian/patches/0004-install_in_usr_lib.patch --- blender-2.61/debian/patches/0004-install_in_usr_lib.patch 2012-01-28 12:47:22.000000000 +0000 +++ blender-2.62/debian/patches/0004-install_in_usr_lib.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -From: Matteo F. Vescovi -Date: Thu, 5 Jan 2012 09:50:48 +0100 -Subject: install_in_usr_lib - - * Arch-specific files go to /usr/lib rather than /usr/share - * Make blender look for systemdir into /usr/lib instead of /usr/share ---- - intern/ghost/intern/GHOST_SystemPathsX11.cpp | 2 +- - source/creator/CMakeLists.txt | 4 ++-- - 2 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/intern/ghost/intern/GHOST_SystemPathsX11.cpp b/intern/ghost/intern/GHOST_SystemPathsX11.cpp -index 7261491..30ff1da 100644 ---- a/intern/ghost/intern/GHOST_SystemPathsX11.cpp -+++ b/intern/ghost/intern/GHOST_SystemPathsX11.cpp -@@ -47,7 +47,7 @@ - #endif - - #ifdef PREFIX --static const char *static_path= PREFIX "/share" ; -+static const char *static_path= PREFIX "/lib" ; - #else - static const char *static_path= NULL; - #endif -diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt -index 27c13d7..e09fe05 100644 ---- a/source/creator/CMakeLists.txt -+++ b/source/creator/CMakeLists.txt -@@ -257,8 +257,8 @@ if(WITH_PYTHON) - endif() - - install( -- DIRECTORY ${CMAKE_SOURCE_DIR}/release/scripts -- DESTINATION ${TARGETDIR_VER} -+ DIRECTORY ${CMAKE_SOURCE_DIR}/release/scripts/ -+ DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/blender/scripts/ - PATTERN ".svn" EXCLUDE - PATTERN "__pycache__" EXCLUDE - PATTERN "${ADDON_EXCLUDE_CONDITIONAL}" EXCLUDE --- diff -Nru blender-2.61/debian/patches/0005-filter_docs_to_install.patch blender-2.62/debian/patches/0005-filter_docs_to_install.patch --- blender-2.61/debian/patches/0005-filter_docs_to_install.patch 2012-01-28 12:47:22.000000000 +0000 +++ blender-2.62/debian/patches/0005-filter_docs_to_install.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -From: Matteo F. Vescovi -Date: Thu, 22 Dec 2011 18:13:03 +0100 -Subject: filter_docs_to_install - -Install relevant documentation ---- - source/creator/CMakeLists.txt | 2 -- - 1 files changed, 0 insertions(+), 2 deletions(-) - -diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt -index e09fe05..033cbf0 100644 ---- a/source/creator/CMakeLists.txt -+++ b/source/creator/CMakeLists.txt -@@ -206,8 +206,6 @@ else() - endif() - - set(BLENDER_TEXT_FILES -- ${CMAKE_SOURCE_DIR}/release/text/GPL-license.txt -- ${CMAKE_SOURCE_DIR}/release/text/Python-license.txt - ${CMAKE_SOURCE_DIR}/release/text/copyright.txt - ${CMAKE_SOURCE_DIR}/release/text/readme.html - ) --- diff -Nru blender-2.61/debian/patches/0005-locales_directory_install.patch blender-2.62/debian/patches/0005-locales_directory_install.patch --- blender-2.61/debian/patches/0005-locales_directory_install.patch 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/debian/patches/0005-locales_directory_install.patch 2012-03-16 16:07:49.000000000 +0000 @@ -0,0 +1,67 @@ +From: "Matteo F. Vescovi" +Date: Thu, 22 Dec 2011 18:17:18 +0100 +Subject: locales_directory_install + +Change where locales are installed +--- + source/blender/blenfont/intern/blf_lang.c | 2 +- + source/blender/blenlib/BLI_path_util.h | 1 + + source/blender/blenlib/intern/path_util.c | 3 +++ + source/creator/CMakeLists.txt | 4 ++-- + 4 files changed, 7 insertions(+), 3 deletions(-) + +diff --git a/source/blender/blenfont/intern/blf_lang.c b/source/blender/blenfont/intern/blf_lang.c +index d96011f..67d02dc 100644 +--- a/source/blender/blenfont/intern/blf_lang.c ++++ b/source/blender/blenfont/intern/blf_lang.c +@@ -109,7 +109,7 @@ static const char *locales[] = { + + void BLF_lang_init(void) + { +- char *messagepath= BLI_get_folder(BLENDER_DATAFILES, "locale"); ++ char *messagepath= BLI_get_folder(BLENDER_SYSTEM_LOCALE, NULL); + + BLI_strncpy(global_encoding_name, SYSTEM_ENCODING_DEFAULT, sizeof(global_encoding_name)); + +diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h +index 68bb1a7..ba1852e 100644 +--- a/source/blender/blenlib/BLI_path_util.h ++++ b/source/blender/blenlib/BLI_path_util.h +@@ -62,6 +62,7 @@ char *BLI_get_folder_version(const int id, const int ver, const int do_check); + #define BLENDER_SYSTEM_SCRIPTS 53 + #define BLENDER_SYSTEM_PLUGINS 54 + #define BLENDER_SYSTEM_PYTHON 54 ++#define BLENDER_SYSTEM_LOCALE 55 + + /* for BLI_get_folder_version only */ + #define BLENDER_RESOURCE_PATH_USER 0 +diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c +index bbdb9bc..06043a5 100644 +--- a/source/blender/blenlib/intern/path_util.c ++++ b/source/blender/blenlib/intern/path_util.c +@@ -1090,6 +1090,9 @@ char *BLI_get_folder(int folder_id, const char *subfolder) + if (get_path_local(path, "python", subfolder, ver)) break; + if (get_path_system(path, "python", subfolder, "BLENDER_SYSTEM_PYTHON", ver)) break; + return NULL; ++ ++ case BLENDER_SYSTEM_LOCALE: ++ BLI_strncpy(path,"/usr/share/locale",FILE_MAX);break; + } + + return path; +diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt +index 7480ab8..b0469e6 100644 +--- a/source/creator/CMakeLists.txt ++++ b/source/creator/CMakeLists.txt +@@ -285,9 +285,9 @@ endif() + if(WITH_INTERNATIONAL) + install( + DIRECTORY +- ${CMAKE_SOURCE_DIR}/release/datafiles/locale ++ ${CMAKE_SOURCE_DIR}/release/datafiles/locale/ + ${CMAKE_SOURCE_DIR}/release/datafiles/fonts +- DESTINATION ${TARGETDIR_VER}/datafiles ++ DESTINATION ${CMAKE_INSTALL_PREFIX}/share/locale + PATTERN ".svn" EXCLUDE + ) + endif() diff -Nru blender-2.61/debian/patches/0006-locales_directory_install.patch blender-2.62/debian/patches/0006-locales_directory_install.patch --- blender-2.61/debian/patches/0006-locales_directory_install.patch 2012-01-28 12:47:22.000000000 +0000 +++ blender-2.62/debian/patches/0006-locales_directory_install.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,68 +0,0 @@ -From: Matteo F. Vescovi -Date: Thu, 22 Dec 2011 18:17:18 +0100 -Subject: locales_directory_install - -Change where locales are installed ---- - source/blender/blenfont/intern/blf_lang.c | 2 +- - source/blender/blenlib/BLI_path_util.h | 1 + - source/blender/blenlib/intern/path_util.c | 3 +++ - source/creator/CMakeLists.txt | 4 ++-- - 4 files changed, 7 insertions(+), 3 deletions(-) - -diff --git a/source/blender/blenfont/intern/blf_lang.c b/source/blender/blenfont/intern/blf_lang.c -index 2ba23e5..ec585af 100644 ---- a/source/blender/blenfont/intern/blf_lang.c -+++ b/source/blender/blenfont/intern/blf_lang.c -@@ -101,7 +101,7 @@ static const char *locales[] = { - - void BLF_lang_init(void) - { -- char *messagepath= BLI_get_folder(BLENDER_DATAFILES, "locale"); -+ char *messagepath= BLI_get_folder(BLENDER_SYSTEM_LOCALE, NULL); - - BLI_strncpy(global_encoding_name, SYSTEM_ENCODING_DEFAULT, sizeof(global_encoding_name)); - -diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h -index 68bb1a7..ba1852e 100644 ---- a/source/blender/blenlib/BLI_path_util.h -+++ b/source/blender/blenlib/BLI_path_util.h -@@ -62,6 +62,7 @@ char *BLI_get_folder_version(const int id, const int ver, const int do_check); - #define BLENDER_SYSTEM_SCRIPTS 53 - #define BLENDER_SYSTEM_PLUGINS 54 - #define BLENDER_SYSTEM_PYTHON 54 -+#define BLENDER_SYSTEM_LOCALE 55 - - /* for BLI_get_folder_version only */ - #define BLENDER_RESOURCE_PATH_USER 0 -diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c -index e79d850..383e0e8 100644 ---- a/source/blender/blenlib/intern/path_util.c -+++ b/source/blender/blenlib/intern/path_util.c -@@ -1088,6 +1088,9 @@ char *BLI_get_folder(int folder_id, const char *subfolder) - if (get_path_local(path, "python", subfolder, ver)) break; - if (get_path_system(path, "python", subfolder, "BLENDER_SYSTEM_PYTHON", ver)) break; - return NULL; -+ -+ case BLENDER_SYSTEM_LOCALE: -+ BLI_strncpy(path,"/usr/share/locale",FILE_MAX);break; - } - - return path; -diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt -index 033cbf0..4f84792 100644 ---- a/source/creator/CMakeLists.txt -+++ b/source/creator/CMakeLists.txt -@@ -269,9 +269,9 @@ endif() - if(WITH_INTERNATIONAL) - install( - DIRECTORY -- ${CMAKE_SOURCE_DIR}/release/datafiles/locale -+ ${CMAKE_SOURCE_DIR}/release/datafiles/locale/ - ${CMAKE_SOURCE_DIR}/release/datafiles/fonts -- DESTINATION ${TARGETDIR_VER}/datafiles -+ DESTINATION ${CMAKE_INSTALL_PREFIX}/share/locale - PATTERN ".svn" EXCLUDE - ) - endif() --- diff -Nru blender-2.61/debian/patches/0006-update_manpages.patch blender-2.62/debian/patches/0006-update_manpages.patch --- blender-2.61/debian/patches/0006-update_manpages.patch 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/debian/patches/0006-update_manpages.patch 2012-03-16 16:07:49.000000000 +0000 @@ -0,0 +1,174 @@ +From: "Matteo F. Vescovi" +Date: Tue, 21 Feb 2012 21:34:30 +0100 +Subject: update_manpages + + * Update blender manpage with current version + * Add blenderplayer manpage + +Signed-off-by: Kevin Roy +--- + doc/manpage/blenderplayer.1 | 131 +++++++++++++++++++++++++++++++++++++++++ + source/creator/CMakeLists.txt | 5 +- + 2 files changed, 135 insertions(+), 1 deletions(-) + create mode 100644 doc/manpage/blenderplayer.1 + +diff --git a/doc/manpage/blenderplayer.1 b/doc/manpage/blenderplayer.1 +new file mode 100644 +index 0000000..d15b0c9 +--- /dev/null ++++ b/doc/manpage/blenderplayer.1 +@@ -0,0 +1,131 @@ ++.TH "BLENDERPLAYER" "1" "October 17, 2011" "Blender 2\&.60 (sub 0)" ++.SH "NAME" ++blenderplayer \- the blender game engine runner ++.SH "SYNOPSIS" ++usage: blenderplayer [\-w [w h l t]] [\-f [fw fh fb ff]] [\-g gamengineoptions] [\-s stereomode] [\-m aasamples] filename.blend ++.SH "DESCRIPTION" ++.B blenderplayer ++is the 3D and physics game engine ++.SH "OPTIONS" ++.PP ++.B -h ++: Prints this command summary ++.PP ++.B -w ++: display in a window ++ optional parameters ++ w = window width ++ h = window height ++ l = window left coordinate ++ t = window top coordinate ++ Note: If w or h is defined, both must be defined. ++ Also, if l or t is defined, all options must be used. ++.PP ++.B -f ++: start game in full screen mode ++ optional parameters ++ fw = full screen mode pixel width ++ fh = full screen mode pixel height ++ fb = full screen mode bits per pixel ++ ff = full screen mode frequency ++ Note: If fw or fh is defined, both must be defined. ++ Also, if fb is used, fw and fh must be used. ff requires all options. ++.PP ++.B -s ++: start player in stereo ++.PP ++ depending on the type of stereo you want: ++.PP ++ stereomode: hwpageflip ++ (Quad buffered shutter glasses) ++.PP ++ syncdoubling ++ (Above Below) ++.PP ++ sidebyside ++ (Left Right) ++.PP ++ anaglyph ++ (Red\-Blue glasses) ++.PP ++ vinterlace ++ (Vertical interlace for autostereo display) ++.PP ++.B -D ++: start player in dome mode ++.PP ++ Optional parameters: ++.PP ++ angle = field of view in degrees ++.PP ++ tilt = tilt angle in degrees ++.PP ++ warpdata = a file to use for warping the image (absolute path) ++.PP ++ mode = fisheye (Fisheye), truncatedfront (Front\-Truncated), ++ truncatedrear (Rear\-Truncated), cubemap(Cube Map), ++ sphericalpanoramic (Spherical Panoramic) ++.PP ++ depending on the type of dome you are using ++.PP ++.B -m ++: maximum anti-aliasing (eg. 2,4,8,16) ++.PP ++.B -i ++: parent windows ID ++.PP ++.B -d ++: turn debugging on ++.PP ++.B -g ++: game engine options ++.RS 4 ++.TP 29 ++Name ++Default Description ++.TP ++--------------------------- ++------------------------------------ ++.TP ++fixedtime ++0 "Enable all frames" ++.TP ++nomipmap ++0 Disable mipmaps ++.TP ++show_framerate ++0 Show the frame rate ++.TP ++show_properties ++0 Show debug properties ++.TP ++show_profile ++0 Show profiling information ++.TP ++blender_material ++0 Enable material settings ++.TP ++ignore_deprecation_warnings ++1 Ignore deprecation warnings ++.RE ++.PP ++.B - ++: all arguments after this are ignored, allowing python to access them from sys.argv ++.SH "EXAMPLES" ++.TP ++.B blenderplayer -w 320 200 10 10 -g noaudio //home//user//filename.blend ++Launch blenderplayer in window mode with size 320x200 at 10 pixels from left and 10 pixels ++from top of the screen without audio. ++.TP ++.B blenderplayer -g show_framerate = 0 //home//user//filename.blend ++Disable framerate reports. ++.TP ++.B blenderplayer -i 232421 -m 16 //home//user//filename.blend ++Launch blenderplayer embedded in an existing window and set antialiasing to 16. ++ ++.SH "SEE ALSO" ++.B blender(1) ++ ++.br ++.SH AUTHORS ++This manpage was written for a Debian GNU/Linux by Kevin Roy . +diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt +index b0469e6..46b8fe3 100644 +--- a/source/creator/CMakeLists.txt ++++ b/source/creator/CMakeLists.txt +@@ -314,6 +314,7 @@ if(UNIX AND NOT APPLE) + ${CMAKE_SOURCE_DIR}/release/freedesktop/blender.desktop + ${CMAKE_SOURCE_DIR}/release/freedesktop/icons/scalable/apps/blender.svg + ${CMAKE_SOURCE_DIR}/doc/manpage/blender.1 ++ ${CMAKE_SOURCE_DIR}/doc/manpage/blenderplayer.1 + DESTINATION ${TARGETDIR} + ) + +@@ -377,7 +378,9 @@ if(UNIX AND NOT APPLE) + DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/blender/scripts + ) + install( +- FILES ${CMAKE_SOURCE_DIR}/doc/manpage/blender.1 ++ FILES ++ ${CMAKE_SOURCE_DIR}/doc/manpage/blender.1 ++ ${CMAKE_SOURCE_DIR}/doc/manpage/blenderplayer.1 + DESTINATION ${CMAKE_INSTALL_PREFIX}/share/man/man1 + ) + install( diff -Nru blender-2.61/debian/patches/0007-fix_FTBFS_with_ffmpeg_from_debian.patch blender-2.62/debian/patches/0007-fix_FTBFS_with_ffmpeg_from_debian.patch --- blender-2.61/debian/patches/0007-fix_FTBFS_with_ffmpeg_from_debian.patch 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/debian/patches/0007-fix_FTBFS_with_ffmpeg_from_debian.patch 2012-03-16 16:07:49.000000000 +0000 @@ -0,0 +1,106 @@ +From: "Matteo F. Vescovi" +Date: Tue, 21 Feb 2012 19:30:16 +0100 +Subject: fix_FTBFS_with_ffmpeg_from_debian + +avformat_alloc_output_context2() should be in +the libavformat 53.2.0 but it isn't in Debian, +so re-define it. + +Signed-off-by: Antonio Ospite +--- + intern/ffmpeg/ffmpeg_compat.h | 62 ++++++++++++++++++++++++ + source/blender/blenkernel/intern/writeffmpeg.c | 1 + + 2 files changed, 63 insertions(+), 0 deletions(-) + +diff --git a/intern/ffmpeg/ffmpeg_compat.h b/intern/ffmpeg/ffmpeg_compat.h +index 582086d..156073f 100644 +--- a/intern/ffmpeg/ffmpeg_compat.h ++++ b/intern/ffmpeg/ffmpeg_compat.h +@@ -35,6 +35,7 @@ + + #include + #include ++#include + #include + + #if (LIBAVFORMAT_VERSION_MAJOR > 52) || ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 101)) +@@ -49,6 +50,67 @@ + #define FFMPEG_HAVE_AVIO 1 + #endif + ++#if (LIBAVFORMAT_VERSION_MAJOR < 53) || ((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR < 22)) ++/* XXX The last check above should be (LIBAVFORMAT_VERSION_MINOR < 2), ++ * look at http://patches.libav.org/patch/3333/ but ffmpeg in Debian is ++ * strange: 53.2.0 should have avformat_alloc_output_context2() but it does ++ * not. ++ */ ++#include ++static int avformat_alloc_output_context2(AVFormatContext **avctx, AVOutputFormat *oformat, ++ const char *format, const char *filename) ++{ ++ AVFormatContext *s = avformat_alloc_context(); ++ int ret = 0; ++ ++ *avctx = NULL; ++ if (!s) ++ goto nomem; ++ ++ if (!oformat) { ++ if (format) { ++ oformat = av_guess_format(format, NULL, NULL); ++ if (!oformat) { ++ av_log(s, AV_LOG_ERROR, "Requested output format '%s' is not a suitable output format\n", format); ++ ret = AVERROR(EINVAL); ++ goto error; ++ } ++ } else { ++ oformat = av_guess_format(NULL, filename, NULL); ++ if (!oformat) { ++ ret = AVERROR(EINVAL); ++ av_log(s, AV_LOG_ERROR, "Unable to find a suitable output format for '%s'\n", ++ filename); ++ goto error; ++ } ++ } ++ } ++ ++ s->oformat = oformat; ++ if (s->oformat->priv_data_size > 0) { ++ s->priv_data = av_mallocz(s->oformat->priv_data_size); ++ if (!s->priv_data) ++ goto nomem; ++ if (s->oformat->priv_class) { ++ *(const AVClass**)s->priv_data= s->oformat->priv_class; ++ av_opt_set_defaults(s->priv_data); ++ } ++ } else ++ s->priv_data = NULL; ++ ++ if (filename) ++ av_strlcpy(s->filename, filename, sizeof(s->filename)); ++ *avctx = s; ++ return 0; ++nomem: ++ av_log(s, AV_LOG_ERROR, "Out of memory\n"); ++ ret = AVERROR(ENOMEM); ++error: ++ avformat_free_context(s); ++ return ret; ++} ++#endif ++ + #if (LIBAVCODEC_VERSION_MAJOR > 53) || ((LIBAVCODEC_VERSION_MAJOR == 53) && (LIBAVCODEC_VERSION_MINOR > 1)) || ((LIBAVCODEC_VERSION_MAJOR == 53) && (LIBAVCODEC_VERSION_MINOR == 1) && (LIBAVCODEC_VERSION_MICRO >= 1)) || ((LIBAVCODEC_VERSION_MAJOR == 52) && (LIBAVCODEC_VERSION_MINOR >= 121)) + #define FFMPEG_HAVE_DEFAULT_VAL_UNION 1 + #endif +diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c +index c4c3eb4..09ed61d 100644 +--- a/source/blender/blenkernel/intern/writeffmpeg.c ++++ b/source/blender/blenkernel/intern/writeffmpeg.c +@@ -36,6 +36,7 @@ + #include + #include + #include ++#include + #include + #include + diff -Nru blender-2.61/debian/patches/0007-update_manpages.patch blender-2.62/debian/patches/0007-update_manpages.patch --- blender-2.61/debian/patches/0007-update_manpages.patch 2012-01-28 12:47:22.000000000 +0000 +++ blender-2.62/debian/patches/0007-update_manpages.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,173 +0,0 @@ -From: Matteo F. Vescovi -Date: Thu, 22 Dec 2011 18:24:53 +0100 -Subject: update_manpages - - * Update blender manpage with current version - * Add blenderplayer manpage ---- - doc/manpage/blenderplayer.1 | 131 +++++++++++++++++++++++++++++++++++++++++ - source/creator/CMakeLists.txt | 5 +- - 2 files changed, 135 insertions(+), 1 deletions(-) - create mode 100644 doc/manpage/blenderplayer.1 - -diff --git a/doc/manpage/blenderplayer.1 b/doc/manpage/blenderplayer.1 -new file mode 100644 -index 0000000..d15b0c9 ---- /dev/null -+++ b/doc/manpage/blenderplayer.1 -@@ -0,0 +1,131 @@ -+.TH "BLENDERPLAYER" "1" "October 17, 2011" "Blender 2\&.60 (sub 0)" -+.SH "NAME" -+blenderplayer \- the blender game engine runner -+.SH "SYNOPSIS" -+usage: blenderplayer [\-w [w h l t]] [\-f [fw fh fb ff]] [\-g gamengineoptions] [\-s stereomode] [\-m aasamples] filename.blend -+.SH "DESCRIPTION" -+.B blenderplayer -+is the 3D and physics game engine -+.SH "OPTIONS" -+.PP -+.B -h -+: Prints this command summary -+.PP -+.B -w -+: display in a window -+ optional parameters -+ w = window width -+ h = window height -+ l = window left coordinate -+ t = window top coordinate -+ Note: If w or h is defined, both must be defined. -+ Also, if l or t is defined, all options must be used. -+.PP -+.B -f -+: start game in full screen mode -+ optional parameters -+ fw = full screen mode pixel width -+ fh = full screen mode pixel height -+ fb = full screen mode bits per pixel -+ ff = full screen mode frequency -+ Note: If fw or fh is defined, both must be defined. -+ Also, if fb is used, fw and fh must be used. ff requires all options. -+.PP -+.B -s -+: start player in stereo -+.PP -+ depending on the type of stereo you want: -+.PP -+ stereomode: hwpageflip -+ (Quad buffered shutter glasses) -+.PP -+ syncdoubling -+ (Above Below) -+.PP -+ sidebyside -+ (Left Right) -+.PP -+ anaglyph -+ (Red\-Blue glasses) -+.PP -+ vinterlace -+ (Vertical interlace for autostereo display) -+.PP -+.B -D -+: start player in dome mode -+.PP -+ Optional parameters: -+.PP -+ angle = field of view in degrees -+.PP -+ tilt = tilt angle in degrees -+.PP -+ warpdata = a file to use for warping the image (absolute path) -+.PP -+ mode = fisheye (Fisheye), truncatedfront (Front\-Truncated), -+ truncatedrear (Rear\-Truncated), cubemap(Cube Map), -+ sphericalpanoramic (Spherical Panoramic) -+.PP -+ depending on the type of dome you are using -+.PP -+.B -m -+: maximum anti-aliasing (eg. 2,4,8,16) -+.PP -+.B -i -+: parent windows ID -+.PP -+.B -d -+: turn debugging on -+.PP -+.B -g -+: game engine options -+.RS 4 -+.TP 29 -+Name -+Default Description -+.TP -+--------------------------- -+------------------------------------ -+.TP -+fixedtime -+0 "Enable all frames" -+.TP -+nomipmap -+0 Disable mipmaps -+.TP -+show_framerate -+0 Show the frame rate -+.TP -+show_properties -+0 Show debug properties -+.TP -+show_profile -+0 Show profiling information -+.TP -+blender_material -+0 Enable material settings -+.TP -+ignore_deprecation_warnings -+1 Ignore deprecation warnings -+.RE -+.PP -+.B - -+: all arguments after this are ignored, allowing python to access them from sys.argv -+.SH "EXAMPLES" -+.TP -+.B blenderplayer -w 320 200 10 10 -g noaudio //home//user//filename.blend -+Launch blenderplayer in window mode with size 320x200 at 10 pixels from left and 10 pixels -+from top of the screen without audio. -+.TP -+.B blenderplayer -g show_framerate = 0 //home//user//filename.blend -+Disable framerate reports. -+.TP -+.B blenderplayer -i 232421 -m 16 //home//user//filename.blend -+Launch blenderplayer embedded in an existing window and set antialiasing to 16. -+ -+.SH "SEE ALSO" -+.B blender(1) -+ -+.br -+.SH AUTHORS -+This manpage was written for a Debian GNU/Linux by Kevin Roy . -diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt -index 4f84792..1987aa7 100644 ---- a/source/creator/CMakeLists.txt -+++ b/source/creator/CMakeLists.txt -@@ -298,6 +298,7 @@ if(UNIX AND NOT APPLE) - ${CMAKE_SOURCE_DIR}/release/freedesktop/blender.desktop - ${CMAKE_SOURCE_DIR}/release/freedesktop/icons/scalable/apps/blender.svg - ${CMAKE_SOURCE_DIR}/doc/manpage/blender.1 -+ ${CMAKE_SOURCE_DIR}/doc/manpage/blenderplayer.1 - DESTINATION ${TARGETDIR} - ) - -@@ -361,7 +362,9 @@ if(UNIX AND NOT APPLE) - DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/blender/scripts - ) - install( -- FILES ${CMAKE_SOURCE_DIR}/doc/manpage/blender.1 -+ FILES -+ ${CMAKE_SOURCE_DIR}/doc/manpage/blender.1 -+ ${CMAKE_SOURCE_DIR}/doc/manpage/blenderplayer.1 - DESTINATION ${CMAKE_INSTALL_PREFIX}/share/man/man1 - ) - install( --- diff -Nru blender-2.61/debian/patches/0008-do_not_use_version_number_in_the_system_path.patch blender-2.62/debian/patches/0008-do_not_use_version_number_in_the_system_path.patch --- blender-2.61/debian/patches/0008-do_not_use_version_number_in_the_system_path.patch 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/debian/patches/0008-do_not_use_version_number_in_the_system_path.patch 2012-03-16 16:07:49.000000000 +0000 @@ -0,0 +1,32 @@ +From: Antonio Ospite +Date: Fri, 6 Jan 2012 14:31:50 +0100 +Subject: do_not_use_version_number_in_the_system_path + +Global installation expects system patch to be something like +/usr/lib/blender/scripts/ without version numbers. +--- + source/blender/blenlib/intern/path_util.c | 4 ++-- + 1 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c +index 06043a5..c5e1146 100644 +--- a/source/blender/blenlib/intern/path_util.c ++++ b/source/blender/blenlib/intern/path_util.c +@@ -89,7 +89,7 @@ + # else /* new XDG ~/blender/.config/ */ + # define BLENDER_USER_FORMAT "%s/blender/%s" + # endif // WITH_XDG_USER_DIRS +-# define BLENDER_SYSTEM_FORMAT "%s/blender/%s" ++# define BLENDER_SYSTEM_FORMAT "%s/blender" + #endif + + /* local */ +@@ -1027,7 +1027,7 @@ static int get_path_system(char *targetpath, const char *folder_name, const char + + system_base_path = (const char *)GHOST_getSystemDir(); + if (system_base_path) { +- BLI_snprintf(system_path, FILE_MAX, BLENDER_SYSTEM_FORMAT, system_base_path, blender_version_decimal(ver)); ++ BLI_snprintf(system_path, FILE_MAX, BLENDER_SYSTEM_FORMAT, system_base_path); + } + + if(!system_path[0]) diff -Nru blender-2.61/debian/patches/0008-fix_FTBFS_with_ffmpeg_from_debian.patch blender-2.62/debian/patches/0008-fix_FTBFS_with_ffmpeg_from_debian.patch --- blender-2.61/debian/patches/0008-fix_FTBFS_with_ffmpeg_from_debian.patch 2012-01-28 12:47:22.000000000 +0000 +++ blender-2.62/debian/patches/0008-fix_FTBFS_with_ffmpeg_from_debian.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,106 +0,0 @@ -From: Antonio Ospite -Date: Sat, 17 Dec 2011 15:45:16 +0100 -Subject: fix_FTBFS_with_ffmpeg_from_debian - -avformat_alloc_output_context2() should be in the libavformat 53.2.0 but -it isn't in Debian, re-define it. - -Signed-off-by: Antonio Ospite ---- - intern/ffmpeg/ffmpeg_compat.h | 62 ++++++++++++++++++++++++ - source/blender/blenkernel/intern/writeffmpeg.c | 1 + - 2 files changed, 63 insertions(+), 0 deletions(-) - -diff --git a/intern/ffmpeg/ffmpeg_compat.h b/intern/ffmpeg/ffmpeg_compat.h -index dfdad22..bb07576 100644 ---- a/intern/ffmpeg/ffmpeg_compat.h -+++ b/intern/ffmpeg/ffmpeg_compat.h -@@ -35,6 +35,7 @@ - - #include - #include -+#include - - #if (LIBAVFORMAT_VERSION_MAJOR > 52) || ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 101)) - #define FFMPEG_HAVE_PARSE_UTILS 1 -@@ -48,6 +49,67 @@ - #define FFMPEG_HAVE_AVIO 1 - #endif - -+#if (LIBAVFORMAT_VERSION_MAJOR < 53) || ((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR < 21)) -+/* XXX The last check above should be (LIBAVFORMAT_VERSION_MINOR < 2), -+ * look at http://patches.libav.org/patch/3333/ but ffmpeg in Debian is -+ * strange: 53.2.0 should have avformat_alloc_output_context2() but it does -+ * not. -+ */ -+#include -+static int avformat_alloc_output_context2(AVFormatContext **avctx, AVOutputFormat *oformat, -+ const char *format, const char *filename) -+{ -+ AVFormatContext *s = avformat_alloc_context(); -+ int ret = 0; -+ -+ *avctx = NULL; -+ if (!s) -+ goto nomem; -+ -+ if (!oformat) { -+ if (format) { -+ oformat = av_guess_format(format, NULL, NULL); -+ if (!oformat) { -+ av_log(s, AV_LOG_ERROR, "Requested output format '%s' is not a suitable output format\n", format); -+ ret = AVERROR(EINVAL); -+ goto error; -+ } -+ } else { -+ oformat = av_guess_format(NULL, filename, NULL); -+ if (!oformat) { -+ ret = AVERROR(EINVAL); -+ av_log(s, AV_LOG_ERROR, "Unable to find a suitable output format for '%s'\n", -+ filename); -+ goto error; -+ } -+ } -+ } -+ -+ s->oformat = oformat; -+ if (s->oformat->priv_data_size > 0) { -+ s->priv_data = av_mallocz(s->oformat->priv_data_size); -+ if (!s->priv_data) -+ goto nomem; -+ if (s->oformat->priv_class) { -+ *(const AVClass**)s->priv_data= s->oformat->priv_class; -+ av_opt_set_defaults(s->priv_data); -+ } -+ } else -+ s->priv_data = NULL; -+ -+ if (filename) -+ av_strlcpy(s->filename, filename, sizeof(s->filename)); -+ *avctx = s; -+ return 0; -+nomem: -+ av_log(s, AV_LOG_ERROR, "Out of memory\n"); -+ ret = AVERROR(ENOMEM); -+error: -+ avformat_free_context(s); -+ return ret; -+} -+#endif -+ - #if (LIBAVCODEC_VERSION_MAJOR > 53) || ((LIBAVCODEC_VERSION_MAJOR == 53) && (LIBAVCODEC_VERSION_MINOR > 1)) || ((LIBAVCODEC_VERSION_MAJOR == 53) && (LIBAVCODEC_VERSION_MINOR == 1) && (LIBAVCODEC_VERSION_MICRO >= 1)) || ((LIBAVCODEC_VERSION_MAJOR == 52) && (LIBAVCODEC_VERSION_MINOR >= 121)) - #define FFMPEG_HAVE_DEFAULT_VAL_UNION 1 - #endif -diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c -index aa7d71b..2e2633b 100644 ---- a/source/blender/blenkernel/intern/writeffmpeg.c -+++ b/source/blender/blenkernel/intern/writeffmpeg.c -@@ -36,6 +36,7 @@ - #include - #include - #include -+#include - #include - #include - --- diff -Nru blender-2.61/debian/patches/0009-do_not_use_version_number_in_the_system_path.patch blender-2.62/debian/patches/0009-do_not_use_version_number_in_the_system_path.patch --- blender-2.61/debian/patches/0009-do_not_use_version_number_in_the_system_path.patch 2012-01-28 12:47:22.000000000 +0000 +++ blender-2.62/debian/patches/0009-do_not_use_version_number_in_the_system_path.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -From: Antonio Ospite -Date: Fri, 6 Jan 2012 14:31:50 +0100 -Subject: do_not_use_version_number_in_the_system_path - -Global installation expects system patch to be something like -/usr/lib/blender/scripts/ without version numbers. ---- - source/blender/blenlib/intern/path_util.c | 4 ++-- - 1 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c -index 383e0e8..ebe4e2a 100644 ---- a/source/blender/blenlib/intern/path_util.c -+++ b/source/blender/blenlib/intern/path_util.c -@@ -89,7 +89,7 @@ - # else /* new XDG ~/blender/.config/ */ - # define BLENDER_USER_FORMAT "%s/blender/%s" - # endif // WITH_XDG_USER_DIRS --# define BLENDER_SYSTEM_FORMAT "%s/blender/%s" -+# define BLENDER_SYSTEM_FORMAT "%s/blender" - #endif - - /* local */ -@@ -1025,7 +1025,7 @@ static int get_path_system(char *targetpath, const char *folder_name, const char - - system_base_path = (const char *)GHOST_getSystemDir(); - if (system_base_path) { -- BLI_snprintf(system_path, FILE_MAX, BLENDER_SYSTEM_FORMAT, system_base_path, blender_version_decimal(ver)); -+ BLI_snprintf(system_path, FILE_MAX, BLENDER_SYSTEM_FORMAT, system_base_path); - } - - if(!system_path[0]) --- diff -Nru blender-2.61/debian/patches/0009-look_for_droid_ttf_with_fontconfig.patch blender-2.62/debian/patches/0009-look_for_droid_ttf_with_fontconfig.patch --- blender-2.61/debian/patches/0009-look_for_droid_ttf_with_fontconfig.patch 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/debian/patches/0009-look_for_droid_ttf_with_fontconfig.patch 2012-03-16 16:07:49.000000000 +0000 @@ -0,0 +1,270 @@ +From: "Matteo F. Vescovi" +Date: Tue, 21 Feb 2012 19:51:50 +0100 +Subject: look_for_droid_ttf_with_fontconfig + + * Remove bad installation of fonts directory into locales. + * Avoid using the droid font shipped with upstream source + and use fontconfig to get it. + +Signed-off-by: Kevin Roy +--- + CMakeLists.txt | 10 ++++ + build_files/cmake/Modules/FindFontconfig.cmake | 49 ++++++++++++++++++++++ + build_files/cmake/macros.cmake | 6 ++- + source/blender/blenfont/CMakeLists.txt | 7 +++ + source/blender/blenfont/intern/blf_translation.c | 23 ++++++++++ + source/blender/blenlib/BLI_fileops.h | 1 + + source/blender/blenlib/intern/fileops.c | 43 +++++++++++++++++++ + source/creator/CMakeLists.txt | 1 - + 8 files changed, 138 insertions(+), 2 deletions(-) + create mode 100644 build_files/cmake/Modules/FindFontconfig.cmake + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index e0b14b7..139aed8 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -117,6 +117,9 @@ option(WITH_BLENDER "Build blender (disable to build only the blender player)" O + mark_as_advanced(WITH_BLENDER) + + option(WITH_INTERNATIONAL "Enable I18N (International fonts and text)" ON) ++if(UNIX AND NOT APPLE) ++ option(WITH_FONTCONFIG "Enable Fontconfig (discovering fonts installed on linux)" OFF) ++endif() + + option(WITH_PYTHON "Enable Embedded Python API (only disable for development)" ON) + option(WITH_PYTHON_SECURITY "Disables execution of scripts within blend files by default (recommend to leave off)" OFF) +@@ -510,6 +513,13 @@ if(UNIX AND NOT APPLE) + endif() + endif() + ++ if(WITH_FONTCONFIG) ++ find_package(Fontconfig) ++ if(NOT FONTCONFIG_FOUND) ++ set(WITH_FONTCONFIG OFF) ++ endif() ++ endif() ++ + if(WITH_FFTW3) + find_package(Fftw3) + if(NOT FFTW3_FOUND) +diff --git a/build_files/cmake/Modules/FindFontconfig.cmake b/build_files/cmake/Modules/FindFontconfig.cmake +new file mode 100644 +index 0000000..337ece9 +--- /dev/null ++++ b/build_files/cmake/Modules/FindFontconfig.cmake +@@ -0,0 +1,49 @@ ++# - Try to find the Fontconfig ++# Once done this will define ++# ++# FONTCONFIG_FOUND - system has Fontconfig ++# FONTCONFIG_INCLUDE_DIR - The include directory to use for the fontconfig headers ++# FONTCONFIG_LIBRARIES - Link these to use FONTCONFIG ++# FONTCONFIG_DEFINITIONS - Compiler switches required for using FONTCONFIG ++ ++# Copyright (c) 2006,2007 Laurent Montel, ++# ++# Redistribution and use is allowed according to the terms of the BSD license. ++# For details see the accompanying COPYING-CMAKE-SCRIPTS file. ++ ++ ++if (FONTCONFIG_LIBRARIES AND FONTCONFIG_INCLUDE_DIR) ++ ++ # in cache already ++ set(FONTCONFIG_FOUND TRUE) ++ ++else (FONTCONFIG_LIBRARIES AND FONTCONFIG_INCLUDE_DIR) ++ ++ if (NOT WIN32) ++ # use pkg-config to get the directories and then use these values ++ # in the FIND_PATH() and FIND_LIBRARY() calls ++ find_package(PkgConfig) ++ pkg_check_modules(FONTCONFIG fontconfig) ++ ++ set(FONTCONFIG_DEFINITIONS ${FONTCONFIG_CFLAGS_OTHER}) ++ endif (NOT WIN32) ++ ++ find_path(FONTCONFIG_INCLUDE_DIR fontconfig/fontconfig.h ++ PATHS ++ ${FONTCONFIG_INCLUDEDIR} ++ ${FONTCONFIG_INCLUDE_DIRS} ++ /usr/X11/include ++ ) ++ ++ find_library(FONTCONFIG_LIBRARIES NAMES fontconfig ++ PATHS ++ ${FONTCONFIG_LIBDIR} ++ ${FONTCONFIG_LIBRARY_DIRS} ++ ) ++ ++ include(FindPackageHandleStandardArgs) ++ FIND_PACKAGE_HANDLE_STANDARD_ARGS(Fontconfig DEFAULT_MSG FONTCONFIG_LIBRARIES FONTCONFIG_INCLUDE_DIR ) ++ ++ mark_as_advanced(FONTCONFIG_LIBRARIES FONTCONFIG_INCLUDE_DIR) ++ ++endif (FONTCONFIG_LIBRARIES AND FONTCONFIG_INCLUDE_DIR) +diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake +index 406f253..ba88ea8 100644 +--- a/build_files/cmake/macros.cmake ++++ b/build_files/cmake/macros.cmake +@@ -244,6 +244,10 @@ macro(setup_liblinks + endif() + endif() + ++ if(WITH_FONTCONFIG) ++ target_link_libraries(${target} ${FONTCONFIG_LIBRARIES}) ++ endif() ++ + if(WITH_OPENAL) + target_link_libraries(${target} ${OPENAL_LIBRARY}) + endif() +@@ -677,4 +681,4 @@ macro(set_lib_path + endif() + + +-endmacro() +\ No newline at end of file ++endmacro() +diff --git a/source/blender/blenfont/CMakeLists.txt b/source/blender/blenfont/CMakeLists.txt +index ebf9ff4..550aa0d 100644 +--- a/source/blender/blenfont/CMakeLists.txt ++++ b/source/blender/blenfont/CMakeLists.txt +@@ -57,6 +57,13 @@ if(WITH_INTERNATIONAL) + add_definitions(-DWITH_INTERNATIONAL) + endif() + ++if(WITH_FONTCONFIG) ++ list(APPEND INC_SYS ++ ${FONTCONFIG_INCLUDE_DIRS} ++ ) ++ add_definitions(-DWITH_FONTCONFIG) ++endif() ++ + add_definitions(-DGLEW_STATIC) + + blender_add_lib(bf_blenfont "${SRC}" "${INC}" "${INC_SYS}") +diff --git a/source/blender/blenfont/intern/blf_translation.c b/source/blender/blenfont/intern/blf_translation.c +index 0ddb654..83ed78b 100644 +--- a/source/blender/blenfont/intern/blf_translation.c ++++ b/source/blender/blenfont/intern/blf_translation.c +@@ -57,13 +57,35 @@ + #include "DNA_userdef_types.h" /* For user settings. */ + + #ifdef WITH_INTERNATIONAL ++#ifdef WITH_FONTCONFIG ++#include ++#else + static const char unifont_filename[]="droidsans.ttf.gz"; ++#endif + static unsigned char *unifont_ttf= NULL; + static int unifont_size= 0; + + unsigned char *BLF_get_unifont(int *unifont_size_r) + { + if(unifont_ttf==NULL) { ++#ifdef WITH_FONTCONFIG ++ FcFontSet *fontset = NULL; ++ FcValue v; ++ FcPattern *pattern = FcPatternBuild (0, FC_FAMILY, FcTypeString, "Droid Sans",FC_STYLE, FcTypeString, "Regular", (char *) 0); ++ fontset = FcFontList(0,pattern,0); ++ if (fontset->nfont > 0) { ++ //get the file of the first font in the fontset that match pattern ++ FcPatternGet(fontset->fonts[0], FC_FILE, 0, &v); ++ //load the file stored in the union of FcValue into memory ++ unifont_ttf = (unsigned char*)BLI_file_to_mem( ++ (const char *)v.u.s, ++ &unifont_size ++ ); ++ } ++ else { ++ printf("%s: 'Droid Sans Regular' font not found with fontconfig\n",__func__); ++ } ++#else + char *fontpath = BLI_get_folder(BLENDER_DATAFILES, "fonts"); + if (fontpath) { + char unifont_path[1024]; +@@ -75,6 +97,7 @@ unsigned char *BLF_get_unifont(int *unifont_size_r) + else { + printf("%s: 'fonts' data path not found for international font, continuing\n", __func__); + } ++#endif + } + + *unifont_size_r= unifont_size; +diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h +index 2e8f1a5..0e66218 100644 +--- a/source/blender/blenlib/BLI_fileops.h ++++ b/source/blender/blenlib/BLI_fileops.h +@@ -70,6 +70,7 @@ int BLI_file_touch(const char *file); + + int BLI_file_gzip(const char *from, const char *to); + char *BLI_file_ungzip_to_mem(const char *from_file, int *size_r); ++char *BLI_file_to_mem(const char *from_file, int *size_r); + + size_t BLI_file_descriptor_size(int file); + size_t BLI_file_size(const char *file); +diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c +index ad04780..f902106 100644 +--- a/source/blender/blenlib/intern/fileops.c ++++ b/source/blender/blenlib/intern/fileops.c +@@ -147,6 +147,49 @@ char *BLI_file_ungzip_to_mem(const char *from_file, int *size_r) + return mem; + } + ++/* read the file in from_file and write it to memory to_mem, at most size bytes. ++ return the file size ++ */ ++char *BLI_file_to_mem(const char *from_file, int *size_r) { ++ ++ FILE * file; ++ int readsize, size, alloc_size=0; ++ char *mem= NULL; ++ const int chunk_size= 512*1024; ++ ++ size= 0; ++ ++ file = fopen( from_file, "rb" ); ++ ++ for(;;) { ++ if(mem==NULL) { ++ mem= MEM_callocN(chunk_size, "BLI_file_to_mem"); ++ alloc_size= chunk_size; ++ } else { ++ mem= MEM_reallocN(mem, size+chunk_size); ++ alloc_size+= chunk_size; ++ } ++ ++ readsize= fread(mem+size, chunk_size,1,file); ++ if(readsize>0) { ++ size+= readsize; ++ } ++ else break; ++ } ++ ++ if(size==0) { ++ MEM_freeN(mem); ++ mem= NULL; ++ } ++ else if(alloc_size!=size) ++ mem= MEM_reallocN(mem, size); ++ ++ fclose(file); ++ *size_r= size; ++ ++ return mem; ++ ++} + + /* return 1 when file can be written */ + int BLI_file_is_writable(const char *filename) +diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt +index 46b8fe3..f047426 100644 +--- a/source/creator/CMakeLists.txt ++++ b/source/creator/CMakeLists.txt +@@ -286,7 +286,6 @@ if(WITH_INTERNATIONAL) + install( + DIRECTORY + ${CMAKE_SOURCE_DIR}/release/datafiles/locale/ +- ${CMAKE_SOURCE_DIR}/release/datafiles/fonts + DESTINATION ${CMAKE_INSTALL_PREFIX}/share/locale + PATTERN ".svn" EXCLUDE + ) diff -Nru blender-2.61/debian/patches/0010-fix_FTBFS_with_libmv.patch blender-2.62/debian/patches/0010-fix_FTBFS_with_libmv.patch --- blender-2.61/debian/patches/0010-fix_FTBFS_with_libmv.patch 2012-01-28 12:47:22.000000000 +0000 +++ blender-2.62/debian/patches/0010-fix_FTBFS_with_libmv.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ -From: Kevin Roy -Date: Wed, 11 Jan 2012 23:15:16 +0100 -Subject: fix_FTBFS_with_libmv - -This must fix build on debian ports that differs from generic i386/x86_64 -like kFreeBSD ---- - extern/libmv/third_party/glog/src/config.h | 10 +++++----- - extern/libmv/third_party/glog/src/config_linux.h | 4 +++- - 2 files changed, 8 insertions(+), 6 deletions(-) - -diff --git a/extern/libmv/third_party/glog/src/config.h b/extern/libmv/third_party/glog/src/config.h -index 49c0d89..102bf9e 100644 ---- a/extern/libmv/third_party/glog/src/config.h -+++ b/extern/libmv/third_party/glog/src/config.h -@@ -2,14 +2,14 @@ - /* src/config.h.in. Generated from configure.ac by autoheader. */ - - /* Namespace for Google classes */ --#ifdef __APPLE__ -+#if defined(__APPLE__) - #include "config_mac.h" --#elif __FreeBSD__ -+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - #include "config_freebsd.h" --#elif __MINGW32__ -+#elif defined(__MINGW32__) - #include "windows/config.h" --#elif __GNUC__ -+#elif defined(__linux__) - #include "config_linux.h" --#elif _MSC_VER -+#elif defined(_MSC_VER) - #include "windows/config.h" - #endif -diff --git a/extern/libmv/third_party/glog/src/config_linux.h b/extern/libmv/third_party/glog/src/config_linux.h -index ffd4e77..faf0329 100644 ---- a/extern/libmv/third_party/glog/src/config_linux.h -+++ b/extern/libmv/third_party/glog/src/config_linux.h -@@ -133,8 +133,10 @@ - /* How to access the PC from a struct ucontext */ - #if defined(_M_X64) || defined(__amd64__) || defined(__x86_64__) - #define PC_FROM_UCONTEXT uc_mcontext.gregs[REG_RIP] --#else -+#elif defined(_M_IX86) || defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) - #define PC_FROM_UCONTEXT uc_mcontext.gregs[REG_EIP] -+#else -+ #undef PC_FROM_UCONTEXT - #endif - - /* Define to necessary symbol if this constant uses a non-standard name on --- diff -Nru blender-2.61/debian/patches/0011-look_for_droid_ttf_with_fontconfig.patch blender-2.62/debian/patches/0011-look_for_droid_ttf_with_fontconfig.patch --- blender-2.61/debian/patches/0011-look_for_droid_ttf_with_fontconfig.patch 2012-01-28 12:47:22.000000000 +0000 +++ blender-2.62/debian/patches/0011-look_for_droid_ttf_with_fontconfig.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,263 +0,0 @@ -From: Kevin Roy -Date: Wed, 25 Jan 2012 16:07:07 +0100 -Subject: look_for_droid_ttf_with_fontconfig - -* Remove bad installation of fonts directory into locales -* Avoid using the droid font shipped with upstream source and -use fontconfig to get it ---- - CMakeLists.txt | 10 ++++ - build_files/cmake/Modules/FindFontconfig.cmake | 49 ++++++++++++++++++++++ - build_files/cmake/macros.cmake | 5 ++ - source/blender/blenfont/CMakeLists.txt | 7 +++ - source/blender/blenfont/intern/blf_translation.c | 23 ++++++++++ - source/blender/blenlib/BLI_fileops.h | 1 + - source/blender/blenlib/intern/fileops.c | 44 +++++++++++++++++++ - source/creator/CMakeLists.txt | 1 - - 8 files changed, 139 insertions(+), 1 deletions(-) - create mode 100644 build_files/cmake/Modules/FindFontconfig.cmake - -diff --git a/CMakeLists.txt b/CMakeLists.txt -index eaa75dd..2ede279 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -117,6 +117,9 @@ option(WITH_BLENDER "Build blender (disable to build only the blender player)" O - mark_as_advanced(WITH_BLENDER) - - option(WITH_INTERNATIONAL "Enable I18N (International fonts and text)" ON) -+if(UNIX AND NOT APPLE) -+ option(WITH_FONTCONFIG "Enable Fontconfig (discovering fonts installed on linux)" OFF) -+endif() - - option(WITH_PYTHON "Enable Embedded Python API (only disable for development)" ON) - option(WITH_PYTHON_SECURITY "Disables execution of scripts within blend files by default (recommend to leave off)" OFF) -@@ -492,6 +495,13 @@ if(UNIX AND NOT APPLE) - endif() - endif() - -+ if(WITH_FONTCONFIG) -+ find_package(Fontconfig) -+ if(NOT FONTCONFIG_FOUND) -+ set(WITH_FONTCONFIG OFF) -+ endif() -+ endif() -+ - if(WITH_FFTW3) - find_package(Fftw3) - if(NOT FFTW3_FOUND) -diff --git a/build_files/cmake/Modules/FindFontconfig.cmake b/build_files/cmake/Modules/FindFontconfig.cmake -new file mode 100644 -index 0000000..337ece9 ---- /dev/null -+++ b/build_files/cmake/Modules/FindFontconfig.cmake -@@ -0,0 +1,49 @@ -+# - Try to find the Fontconfig -+# Once done this will define -+# -+# FONTCONFIG_FOUND - system has Fontconfig -+# FONTCONFIG_INCLUDE_DIR - The include directory to use for the fontconfig headers -+# FONTCONFIG_LIBRARIES - Link these to use FONTCONFIG -+# FONTCONFIG_DEFINITIONS - Compiler switches required for using FONTCONFIG -+ -+# Copyright (c) 2006,2007 Laurent Montel, -+# -+# Redistribution and use is allowed according to the terms of the BSD license. -+# For details see the accompanying COPYING-CMAKE-SCRIPTS file. -+ -+ -+if (FONTCONFIG_LIBRARIES AND FONTCONFIG_INCLUDE_DIR) -+ -+ # in cache already -+ set(FONTCONFIG_FOUND TRUE) -+ -+else (FONTCONFIG_LIBRARIES AND FONTCONFIG_INCLUDE_DIR) -+ -+ if (NOT WIN32) -+ # use pkg-config to get the directories and then use these values -+ # in the FIND_PATH() and FIND_LIBRARY() calls -+ find_package(PkgConfig) -+ pkg_check_modules(FONTCONFIG fontconfig) -+ -+ set(FONTCONFIG_DEFINITIONS ${FONTCONFIG_CFLAGS_OTHER}) -+ endif (NOT WIN32) -+ -+ find_path(FONTCONFIG_INCLUDE_DIR fontconfig/fontconfig.h -+ PATHS -+ ${FONTCONFIG_INCLUDEDIR} -+ ${FONTCONFIG_INCLUDE_DIRS} -+ /usr/X11/include -+ ) -+ -+ find_library(FONTCONFIG_LIBRARIES NAMES fontconfig -+ PATHS -+ ${FONTCONFIG_LIBDIR} -+ ${FONTCONFIG_LIBRARY_DIRS} -+ ) -+ -+ include(FindPackageHandleStandardArgs) -+ FIND_PACKAGE_HANDLE_STANDARD_ARGS(Fontconfig DEFAULT_MSG FONTCONFIG_LIBRARIES FONTCONFIG_INCLUDE_DIR ) -+ -+ mark_as_advanced(FONTCONFIG_LIBRARIES FONTCONFIG_INCLUDE_DIR) -+ -+endif (FONTCONFIG_LIBRARIES AND FONTCONFIG_INCLUDE_DIR) -diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake -index c6a8340..6a06c58 100644 ---- a/build_files/cmake/macros.cmake -+++ b/build_files/cmake/macros.cmake -@@ -244,6 +244,11 @@ macro(setup_liblinks - endif() - endif() - -+ if(WITH_FONTCONFIG) -+ target_link_libraries(${target} ${FONTCONFIG_LIBRARIES}) -+ endif() -+ -+ - if(WITH_OPENAL) - target_link_libraries(${target} ${OPENAL_LIBRARY}) - endif() -diff --git a/source/blender/blenfont/CMakeLists.txt b/source/blender/blenfont/CMakeLists.txt -index d928297..1fce891 100644 ---- a/source/blender/blenfont/CMakeLists.txt -+++ b/source/blender/blenfont/CMakeLists.txt -@@ -57,5 +57,12 @@ if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) - endif() - -+if(WITH_FONTCONFIG) -+ list(APPEND INC_SYS -+ ${FONTCONFIG_INCLUDE_DIRS} -+ ) -+ add_definitions(-DWITH_FONTCONFIG) -+endif() -+ - blender_add_lib(bf_blenfont "${SRC}" "${INC}" "${INC_SYS}") - -diff --git a/source/blender/blenfont/intern/blf_translation.c b/source/blender/blenfont/intern/blf_translation.c -index fe14f5d..8f89c8b 100644 ---- a/source/blender/blenfont/intern/blf_translation.c -+++ b/source/blender/blenfont/intern/blf_translation.c -@@ -47,13 +47,35 @@ - #include "DNA_userdef_types.h" /* For user settings. */ - - #ifdef WITH_INTERNATIONAL -+#ifdef WITH_FONTCONFIG -+#include -+#else - static const char unifont_filename[]="droidsans.ttf.gz"; -+#endif - static unsigned char *unifont_ttf= NULL; - static int unifont_size= 0; - - unsigned char *BLF_get_unifont(int *unifont_size_r) - { - if(unifont_ttf==NULL) { -+#ifdef WITH_FONTCONFIG -+ FcFontSet *fontset = NULL; -+ FcValue v; -+ FcPattern *pattern = FcPatternBuild (0, FC_FAMILY, FcTypeString, "Droid Sans",FC_STYLE, FcTypeString, "Regular", (char *) 0); -+ fontset = FcFontList(0,pattern,0); -+ if (fontset->nfont > 0) { -+ //get the file of the first font in the fontset that match pattern -+ FcPatternGet(fontset->fonts[0], FC_FILE, 0, &v); -+ //load the file stored in the union of FcValue into memory -+ unifont_ttf = (unsigned char*)BLI_file_to_mem( -+ (const char *)v.u.s, -+ &unifont_size -+ ); -+ } -+ else { -+ printf("%s: 'Droid Sans Regular' font not found with fontconfig\n",__func__); -+ } -+#else - char *fontpath = BLI_get_folder(BLENDER_DATAFILES, "fonts"); - if (fontpath) { - char unifont_path[1024]; -@@ -65,6 +87,7 @@ unsigned char *BLF_get_unifont(int *unifont_size_r) - else { - printf("%s: 'fonts' data path not found for international font, continuing\n", __func__); - } -+#endif - } - - *unifont_size_r= unifont_size; -diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h -index 2e8f1a5..0e66218 100644 ---- a/source/blender/blenlib/BLI_fileops.h -+++ b/source/blender/blenlib/BLI_fileops.h -@@ -70,6 +70,7 @@ int BLI_file_touch(const char *file); - - int BLI_file_gzip(const char *from, const char *to); - char *BLI_file_ungzip_to_mem(const char *from_file, int *size_r); -+char *BLI_file_to_mem(const char *from_file, int *size_r); - - size_t BLI_file_descriptor_size(int file); - size_t BLI_file_size(const char *file); -diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c -index 95b6a97..57f45dd 100644 ---- a/source/blender/blenlib/intern/fileops.c -+++ b/source/blender/blenlib/intern/fileops.c -@@ -148,6 +148,50 @@ char *BLI_file_ungzip_to_mem(const char *from_file, int *size_r) - } - - -+/* read the file in from_file and write it to memory to_mem, at most size bytes. -+ return the file size -+ */ -+char *BLI_file_to_mem(const char *from_file, int *size_r) { -+ -+ FILE * file; -+ int readsize, size, alloc_size=0; -+ char *mem= NULL; -+ const int chunk_size= 512*1024; -+ -+ size= 0; -+ -+ file = fopen( from_file, "rb" ); -+ -+ for(;;) { -+ if(mem==NULL) { -+ mem= MEM_callocN(chunk_size, "BLI_file_to_mem"); -+ alloc_size= chunk_size; -+ } else { -+ mem= MEM_reallocN(mem, size+chunk_size); -+ alloc_size+= chunk_size; -+ } -+ -+ readsize= fread(mem+size, chunk_size,1,file); -+ if(readsize>0) { -+ size+= readsize; -+ } -+ else break; -+ } -+ -+ if(size==0) { -+ MEM_freeN(mem); -+ mem= NULL; -+ } -+ else if(alloc_size!=size) -+ mem= MEM_reallocN(mem, size); -+ -+ fclose(file); -+ *size_r= size; -+ -+ return mem; -+ -+} -+ - /* return 1 when file can be written */ - int BLI_file_is_writable(const char *filename) - { -diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt -index 1987aa7..59cfe64 100644 ---- a/source/creator/CMakeLists.txt -+++ b/source/creator/CMakeLists.txt -@@ -270,7 +270,6 @@ if(WITH_INTERNATIONAL) - install( - DIRECTORY - ${CMAKE_SOURCE_DIR}/release/datafiles/locale/ -- ${CMAKE_SOURCE_DIR}/release/datafiles/fonts - DESTINATION ${CMAKE_INSTALL_PREFIX}/share/locale - PATTERN ".svn" EXCLUDE - ) --- diff -Nru blender-2.61/debian/patches/0012-fix_implicit_declaration_of_av_rescale_q.patch blender-2.62/debian/patches/0012-fix_implicit_declaration_of_av_rescale_q.patch --- blender-2.61/debian/patches/0012-fix_implicit_declaration_of_av_rescale_q.patch 2012-01-28 12:47:22.000000000 +0000 +++ blender-2.62/debian/patches/0012-fix_implicit_declaration_of_av_rescale_q.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -From: Kevin Roy -Date: Thu, 26 Jan 2012 23:54:09 +0100 -Subject: fix_implicit_declaration_of_av_rescale_q - ---- - intern/ffmpeg/ffmpeg_compat.h | 1 + - 1 files changed, 1 insertions(+), 0 deletions(-) - -diff --git a/intern/ffmpeg/ffmpeg_compat.h b/intern/ffmpeg/ffmpeg_compat.h -index bb07576..156073f 100644 ---- a/intern/ffmpeg/ffmpeg_compat.h -+++ b/intern/ffmpeg/ffmpeg_compat.h -@@ -36,6 +36,7 @@ - #include - #include - #include -+#include - - #if (LIBAVFORMAT_VERSION_MAJOR > 52) || ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 101)) - #define FFMPEG_HAVE_PARSE_UTILS 1 --- diff -Nru blender-2.61/debian/patches/0013-fix_implicit_declaration_of_guardealloc.patch blender-2.62/debian/patches/0013-fix_implicit_declaration_of_guardealloc.patch --- blender-2.61/debian/patches/0013-fix_implicit_declaration_of_guardealloc.patch 2012-01-28 12:47:22.000000000 +0000 +++ blender-2.62/debian/patches/0013-fix_implicit_declaration_of_guardealloc.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -From: Kevin Roy -Date: Thu, 26 Jan 2012 23:56:40 +0100 -Subject: fix_implicit_declaration_of_guardealloc - ---- - source/blender/avi/intern/endian.c | 4 ++++ - 1 files changed, 4 insertions(+), 0 deletions(-) - -diff --git a/source/blender/avi/intern/endian.c b/source/blender/avi/intern/endian.c -index 1948806..94734b0 100644 ---- a/source/blender/avi/intern/endian.c -+++ b/source/blender/avi/intern/endian.c -@@ -43,6 +43,10 @@ - #include "avi_intern.h" - - #ifdef __BIG_ENDIAN__ -+#include "MEM_guardedalloc.h" -+#endif -+ -+#ifdef __BIG_ENDIAN__ - static void invert (int *num) { - int new=0,i,j; - --- diff -Nru blender-2.61/debian/patches/series blender-2.62/debian/patches/series --- blender-2.61/debian/patches/series 2012-01-28 12:47:22.000000000 +0000 +++ blender-2.62/debian/patches/series 2012-03-16 16:07:49.000000000 +0000 @@ -1,13 +1,9 @@ 0001-blender_thumbnailer.patch -0002-fix_FTBFS_on_KFreeBSD.patch -0003-disable_tests.patch -0004-install_in_usr_lib.patch -0005-filter_docs_to_install.patch -0006-locales_directory_install.patch -0007-update_manpages.patch -0008-fix_FTBFS_with_ffmpeg_from_debian.patch -0009-do_not_use_version_number_in_the_system_path.patch -0010-fix_FTBFS_with_libmv.patch -0011-look_for_droid_ttf_with_fontconfig.patch -0012-fix_implicit_declaration_of_av_rescale_q.patch -0013-fix_implicit_declaration_of_guardealloc.patch +0002-disable_tests.patch +0003-install_in_usr_lib.patch +0004-filter_docs_to_install.patch +0005-locales_directory_install.patch +0006-update_manpages.patch +0007-fix_FTBFS_with_ffmpeg_from_debian.patch +0008-do_not_use_version_number_in_the_system_path.patch +0009-look_for_droid_ttf_with_fontconfig.patch diff -Nru blender-2.61/debian/rules blender-2.62/debian/rules --- blender-2.61/debian/rules 2012-01-28 12:47:22.000000000 +0000 +++ blender-2.62/debian/rules 2012-03-16 16:07:49.000000000 +0000 @@ -34,7 +34,9 @@ -DWITH_CODEC_FFMPEG=ON \ -DWITH_CODEC_SNDFILE=ON \ -DWITH_BUILTIN_GLEW=OFF \ - -DWITH_FONTCONFIG=ON + -DWITH_FONTCONFIG=ON \ + -DWITH_CYCLES=OFF \ + -DWITH_MOD_OCEANSIM=ON override_dh_auto_install: dh_auto_install --buildsystem=cmake diff -Nru blender-2.61/doc/blender_file_format/BlendFileDnaExporter_25.py blender-2.62/doc/blender_file_format/BlendFileDnaExporter_25.py --- blender-2.61/doc/blender_file_format/BlendFileDnaExporter_25.py 2011-12-13 19:54:45.000000000 +0000 +++ blender-2.62/doc/blender_file_format/BlendFileDnaExporter_25.py 2012-02-15 19:39:06.000000000 +0000 @@ -206,13 +206,13 @@ ${size} """ - if field.Type.Structure == None or field.Name.IsPointer(): + if field.Type.Structure is None or field.Name.IsPointer(): # ${reference} reference = field.Name.AsReference(parentReference) # ${struct} - if parentReference != None: + if parentReference is not None: struct = '{0}'.format(structure.Type.Name) else: struct = structure.Type.Name @@ -240,7 +240,7 @@ structure_field = Template(structure_field_template).substitute(d) - elif field.Type.Structure != None: + elif field.Type.Structure is not None: reference = field.Name.AsReference(parentReference) structure_field = self.StructureFields(field.Type.Structure, reference, offset) diff -Nru blender-2.61/doc/blender_file_format/BlendFileReader.py blender-2.62/doc/blender_file_format/BlendFileReader.py --- blender-2.61/doc/blender_file_format/BlendFileReader.py 2011-12-13 19:54:45.000000000 +0000 +++ blender-2.62/doc/blender_file_format/BlendFileReader.py 2012-02-15 19:39:06.000000000 +0000 @@ -329,7 +329,7 @@ self.Name = name def AsReference(self, parent): - if parent == None: + if parent is None: result = "" else: result = parent+"." diff -Nru blender-2.61/doc/python_api/examples/bge.constraints.py blender-2.62/doc/python_api/examples/bge.constraints.py --- blender-2.61/doc/python_api/examples/bge.constraints.py 2011-12-13 19:54:56.000000000 +0000 +++ blender-2.62/doc/python_api/examples/bge.constraints.py 2012-02-15 19:39:19.000000000 +0000 @@ -1,6 +1,6 @@ """ Basic Physics Constraint -++++++++++++++++++++++ +++++++++++++++++++++++++ Example of how to create a hinge Physics Constraint between two objects. """ from bge import logic diff -Nru blender-2.61/doc/python_api/examples/bge.texture.1.py blender-2.62/doc/python_api/examples/bge.texture.1.py --- blender-2.61/doc/python_api/examples/bge.texture.1.py 2011-12-13 19:54:56.000000000 +0000 +++ blender-2.62/doc/python_api/examples/bge.texture.1.py 2012-02-15 19:39:19.000000000 +0000 @@ -1,6 +1,6 @@ """ -Texture replacement -++++++++++++++++++++++ +Texture Replacement ++++++++++++++++++++ Example of how to replace a texture in game with an external image. createTexture() and removeTexture() are to be called from a module Python Controller. diff -Nru blender-2.61/doc/python_api/examples/bge.texture.py blender-2.62/doc/python_api/examples/bge.texture.py --- blender-2.61/doc/python_api/examples/bge.texture.py 2011-12-13 19:54:56.000000000 +0000 +++ blender-2.62/doc/python_api/examples/bge.texture.py 2012-02-15 19:39:19.000000000 +0000 @@ -1,6 +1,6 @@ """ Basic Video Playback -++++++++++++++++++++++ +++++++++++++++++++++ Example of how to replace a texture in game with a video. It needs to run everyframe """ import bge diff -Nru blender-2.61/doc/python_api/examples/bpy.types.Menu.1.py blender-2.62/doc/python_api/examples/bpy.types.Menu.1.py --- blender-2.61/doc/python_api/examples/bpy.types.Menu.1.py 2011-12-13 19:54:56.000000000 +0000 +++ blender-2.62/doc/python_api/examples/bpy.types.Menu.1.py 2012-02-15 19:39:19.000000000 +0000 @@ -13,8 +13,8 @@ def draw(self, context): layout = self.layout - layout.operator("object.select_all", text="Select/Deselect All") - layout.operator("object.select_inverse", text="Inverse") + layout.operator("object.select_all", text="Select/Deselect All").action = 'TOGGLE' + layout.operator("object.select_all", text="Inverse").action = 'INVERT' layout.operator("object.select_random", text="Random") # access this operator as a submenu diff -Nru blender-2.61/doc/python_api/examples/bpy.types.Menu.py blender-2.62/doc/python_api/examples/bpy.types.Menu.py --- blender-2.61/doc/python_api/examples/bpy.types.Menu.py 2011-12-13 19:54:56.000000000 +0000 +++ blender-2.62/doc/python_api/examples/bpy.types.Menu.py 2012-02-15 19:39:19.000000000 +0000 @@ -27,8 +27,8 @@ def draw(self, context): layout = self.layout - layout.operator("object.select_all", text="Select/Deselect All") - layout.operator("object.select_inverse", text="Inverse") + layout.operator("object.select_all", text="Select/Deselect All").action = 'TOGGLE' + layout.operator("object.select_all", text="Inverse").action = 'INVERT' layout.operator("object.select_random", text="Random") diff -Nru blender-2.61/doc/python_api/examples/bpy.types.Operator.4.py blender-2.62/doc/python_api/examples/bpy.types.Operator.4.py --- blender-2.61/doc/python_api/examples/bpy.types.Operator.4.py 2011-12-13 19:54:56.000000000 +0000 +++ blender-2.62/doc/python_api/examples/bpy.types.Operator.4.py 2012-02-15 19:39:19.000000000 +0000 @@ -22,7 +22,7 @@ my_string = bpy.props.StringProperty(name="String Value") def execute(self, context): - print() + print("Test", self) return {'FINISHED'} def invoke(self, context, event): diff -Nru blender-2.61/doc/python_api/examples/bpy.types.Operator.5.py blender-2.62/doc/python_api/examples/bpy.types.Operator.5.py --- blender-2.61/doc/python_api/examples/bpy.types.Operator.5.py 2011-12-13 19:54:56.000000000 +0000 +++ blender-2.62/doc/python_api/examples/bpy.types.Operator.5.py 2012-02-15 19:39:19.000000000 +0000 @@ -31,6 +31,7 @@ def execute(self, context): context.object.location.x = self.value / 100.0 + return {'FINISHED'} def modal(self, context, event): if event.type == 'MOUSEMOVE': # Apply diff -Nru blender-2.61/doc/python_api/examples/bpy.types.Panel.1.py blender-2.62/doc/python_api/examples/bpy.types.Panel.1.py --- blender-2.61/doc/python_api/examples/bpy.types.Panel.1.py 2011-12-13 19:54:56.000000000 +0000 +++ blender-2.62/doc/python_api/examples/bpy.types.Panel.1.py 2012-02-15 19:39:19.000000000 +0000 @@ -34,9 +34,9 @@ box = layout.box() box.label("Selection Tools") - box.operator("object.select_all") + box.operator("object.select_all").action = 'TOGGLE' row = box.row() - row.operator("object.select_inverse") + row.operator("object.select_all").action = 'INVERT' row.operator("object.select_random") diff -Nru blender-2.61/doc/python_api/rst/bge.constraints.rst blender-2.62/doc/python_api/rst/bge.constraints.rst --- blender-2.61/doc/python_api/rst/bge.constraints.rst 2011-12-13 19:54:55.000000000 +0000 +++ blender-2.62/doc/python_api/rst/bge.constraints.rst 2012-02-15 19:39:18.000000000 +0000 @@ -5,6 +5,11 @@ .. module:: bge.constraints .. literalinclude:: ../examples/bge.constraints.py + :language: rest + :lines: 2-4 + +.. literalinclude:: ../examples/bge.constraints.py + :lines: 6- .. function:: createConstraint(physicsid, physicsid2, constrainttype, [pivotX, pivotY, pivotZ, [axisX, axisY, axisZ, [flag]]]]) diff -Nru blender-2.61/doc/python_api/rst/bge.logic.rst blender-2.62/doc/python_api/rst/bge.logic.rst --- blender-2.61/doc/python_api/rst/bge.logic.rst 2011-12-13 19:54:55.000000000 +0000 +++ blender-2.62/doc/python_api/rst/bge.logic.rst 2012-02-15 19:39:18.000000000 +0000 @@ -69,11 +69,9 @@ :columns: 3 * :class:`~bge.types.BL_ActionActuator` - * :class:`~bge.types.BL_ShapeActionActuator` * :class:`~bge.types.KX_CameraActuator` * :class:`~bge.types.KX_ConstraintActuator` * :class:`~bge.types.KX_GameActuator` - * :class:`~bge.types.KX_IpoActuator` * :class:`~bge.types.KX_NetworkMessageActuator` * :class:`~bge.types.KX_ObjectActuator` * :class:`~bge.types.KX_ParentActuator` @@ -477,6 +475,7 @@ See :class:`bge.types.BL_ActionActuator` .. data:: KX_ACTIONACT_PLAY +.. data:: KX_ACTIONACT_PINGPONG .. data:: KX_ACTIONACT_FLIPPER .. data:: KX_ACTIONACT_LOOPSTOP .. data:: KX_ACTIONACT_LOOPEND @@ -635,21 +634,6 @@ .. data:: KX_GAME_SAVECFG .. data:: KX_GAME_LOADCFG -.. _ipo-actuator: - ------------- -IPO Actuator ------------- - -See :class:`bge.types.KX_IpoActuator` - -.. data:: KX_IPOACT_PLAY -.. data:: KX_IPOACT_PINGPONG -.. data:: KX_IPOACT_FLIPPER -.. data:: KX_IPOACT_LOOPSTOP -.. data:: KX_IPOACT_LOOPEND -.. data:: KX_IPOACT_FROM_PROP - --------------- Parent Actuator --------------- @@ -691,20 +675,6 @@ .. data:: KX_SCENE_SUSPEND .. data:: KX_SCENE_RESUME -.. _shape-action-actuator: - ---------------------- -Shape Action Actuator ---------------------- - -See :class:`bge.types.BL_ActionActuator` - -.. data:: KX_ACTIONACT_PLAY -.. data:: KX_ACTIONACT_FLIPPER -.. data:: KX_ACTIONACT_LOOPSTOP -.. data:: KX_ACTIONACT_LOOPEND -.. data:: KX_ACTIONACT_PROPERTY - .. _logic-sound-actuator: -------------- diff -Nru blender-2.61/doc/python_api/rst/bge.render.rst blender-2.62/doc/python_api/rst/bge.render.rst --- blender-2.61/doc/python_api/rst/bge.render.rst 2011-12-13 19:54:55.000000000 +0000 +++ blender-2.62/doc/python_api/rst/bge.render.rst 2012-02-15 19:39:18.000000000 +0000 @@ -77,6 +77,14 @@ :rtype: integer +.. function:: setWindowSize(width, height) + + Set the width and height of the window (in pixels). This also works for fullscreen applications. + + :type width: integer + :type height: integer + + .. function:: makeScreenshot(filename) Writes a screenshot to the given filename. diff -Nru blender-2.61/doc/python_api/rst/bge.texture.rst blender-2.62/doc/python_api/rst/bge.texture.rst --- blender-2.61/doc/python_api/rst/bge.texture.rst 2011-12-13 19:54:55.000000000 +0000 +++ blender-2.62/doc/python_api/rst/bge.texture.rst 2012-02-15 19:39:18.000000000 +0000 @@ -37,8 +37,18 @@ .. module:: bge.texture .. literalinclude:: ../examples/bge.texture.py + :language: rest + :lines: 2-4 + +.. literalinclude:: ../examples/bge.texture.py + :lines: 6- + +.. literalinclude:: ../examples/bge.texture.1.py + :language: rest + :lines: 2-6 .. literalinclude:: ../examples/bge.texture.1.py + :lines: 8- .. class:: VideoFFmpeg(file [, capture=-1, rate=25.0, width=0, height=0]) @@ -516,7 +526,7 @@ line by line starting from the bottom of the image. The pixel size and format is determined by the mode parameter. -.. function materialID(object,name) +.. function:: materialID(object,name) Returns a numeric value that can be used in :class:`Texture` to create a dynamic texture. @@ -538,7 +548,7 @@ :type name: string :rtype: integer -.. function setLogFile(filename) +.. function:: setLogFile(filename) Sets the name of a text file in which runtime error messages will be written, in addition to the printing of the messages on the Python console. Only the runtime errors specific to the VideoTexture module diff -Nru blender-2.61/doc/python_api/rst/bge.types.rst blender-2.62/doc/python_api/rst/bge.types.rst --- blender-2.61/doc/python_api/rst/bge.types.rst 2011-12-13 19:54:55.000000000 +0000 +++ blender-2.62/doc/python_api/rst/bge.types.rst 2012-02-15 19:39:18.000000000 +0000 @@ -66,6 +66,12 @@ :type: dictionary {:ref:`keycode`::ref:`status`, ...} + .. attribute:: active_events + + A dictionary containing the status of only the active keyboard events or keys. (read-only). + + :type: dictionary {:ref:`keycode`::ref:`status`, ...} + .. class:: SCA_PythonMouse(PyObjectPlus) The current mouse. @@ -75,6 +81,12 @@ a dictionary containing the status of each mouse event. (read-only). :type: dictionary {:ref:`keycode`::ref:`status`, ...} + + .. attribute:: active_events + + a dictionary containing the status of only the active mouse events. (read-only). + + :type: dictionary {:ref:`keycode`::ref:`status`, ...} .. attribute:: position @@ -942,7 +954,7 @@ .. deprecated:: use :data:`localPosition` and :data:`worldPosition`. - :type: :class:`mathurils.Vector` + :type: :class:`mathutils.Vector` .. attribute:: orientation @@ -980,7 +992,7 @@ .. attribute:: worldScale - The object's world scaling factor. Read-only. [sx, sy, sz] + The object's world scaling factor. [sx, sy, sz] :type: :class:`mathutils.Vector` @@ -995,6 +1007,18 @@ The object's world position. [x, y, z] :type: :class:`mathutils.Vector` + + .. attribute:: localTransform + + The object's local space transform matrix. 4x4 Matrix. + + :type: :class:`mathutils.Matrix` + + .. attribute:: worldTransform + + The object's world space transform matrix. 4x4 Matrix. + + :type: :class:`mathutils.Matrix` .. attribute:: localLinearVelocity @@ -1765,33 +1789,29 @@ #. Polygon shape (triangle/quad) #. Game Object - #. Verticies will be split by face if necessary. Verticies can only be shared between faces if: + #. Vertices will be split by face if necessary. Vertices can only be shared between faces if: #. They are at the same position #. UV coordinates are the same #. Their normals are the same (both polygons are "Set Smooth") - #. They are the same colour, for example: a cube has 24 verticies: 6 faces with 4 verticies per face. + #. They are the same colour, for example: a cube has 24 vertices: 6 faces with 4 vertices per face. The correct method of iterating over every :class:`KX_VertexProxy` in a game object .. code-block:: python - import GameLogic + from bge import logic - co = GameLogic.getCurrentController() - obj = co.owner + cont = logic.getCurrentController() + object = cont.owner - m_i = 0 - mesh = obj.getMesh(m_i) # There can be more than one mesh... - while mesh != None: - for mat in range(mesh.getNumMaterials()): + for mesh in object.meshes: + for material in mesh.materials: for v_index in range(mesh.getVertexArrayLength(mat)): vertex = mesh.getVertex(mat, v_index) # Do something with vertex here... # ... eg: colour the vertex red. vertex.colour = [1.0, 0.0, 0.0, 1.0] - m_i += 1 - mesh = obj.getMesh(m_i) .. attribute:: materials @@ -2401,135 +2421,53 @@ Some of the methods/variables are CObjects. If you mix these up, you will crash blender. - This example requires `PyOpenGL `_ and `GLEWPy `_ - .. code-block:: python - import GameLogic - import OpenGL - from OpenGL.GL import * - from OpenGL.GLU import * - import glew - from glew import * - - glewInit() + from bge import logic vertex_shader = """ void main(void) { + // original vertex position, no changes gl_Position = ftransform(); + // coordinate of the 1st texture channel + gl_TexCoord[0] = gl_MultiTexCoord0; + // coordinate of the 2nd texture channel + gl_TexCoord[1] = gl_MultiTexCoord1; } """ fragment_shader =""" - + + uniform sampler2D color_0; + uniform sampler2D color_1; + uniform float factor; + void main(void) { - gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); + vec4 color_0 = texture2D(color_0, gl_TexCoord[0].st); + vec4 color_1 = texture2D(color_1, gl_TexCoord[1].st); + gl_FragColor = mix(color_0, color_1, factor); } """ - - class MyMaterial: - def __init__(self): - self.pass_no = 0 - # Create a shader - self.m_program = glCreateProgramObjectARB() - # Compile the vertex shader - self.shader(GL_VERTEX_SHADER_ARB, (vertex_shader)) - # Compile the fragment shader - self.shader(GL_FRAGMENT_SHADER_ARB, (fragment_shader)) - # Link the shaders together - self.link() - - def PrintInfoLog(self, tag, object): - """ - PrintInfoLog prints the GLSL compiler log - """ - print "Tag: def PrintGLError(self, tag = ""): - - def PrintGLError(self, tag = ""): - """ - Prints the current GL error status - """ - if len(tag): - print tag - err = glGetError() - if err != GL_NO_ERROR: - print "GL Error: %s\\n"%(gluErrorString(err)) - - def shader(self, type, shaders): - """ - shader compiles a GLSL shader and attaches it to the current - program. - - type should be either GL_VERTEX_SHADER_ARB or GL_FRAGMENT_SHADER_ARB - shaders should be a sequence of shader source to compile. - """ - # Create a shader object - shader_object = glCreateShaderObjectARB(type) - - # Add the source code - glShaderSourceARB(shader_object, len(shaders), shaders) - - # Compile the shader - glCompileShaderARB(shader_object) - - # Print the compiler log - self.PrintInfoLog("vertex shader", shader_object) - - # Check if compiled, and attach if it did - compiled = glGetObjectParameterivARB(shader_object, GL_OBJECT_COMPILE_STATUS_ARB) - if compiled: - glAttachObjectARB(self.m_program, shader_object) - - # Delete the object (glAttachObjectARB makes a copy) - glDeleteObjectARB(shader_object) - - # print the gl error log - self.PrintGLError() - - def link(self): - """ - Links the shaders together. - """ - # clear error indicator - glGetError() - - glLinkProgramARB(self.m_program) - - self.PrintInfoLog("link", self.m_program) - - linked = glGetObjectParameterivARB(self.m_program, GL_OBJECT_LINK_STATUS_ARB) - if not linked: - print "Shader failed to link" - return - - glValidateProgramARB(self.m_program) - valid = glGetObjectParameterivARB(self.m_program, GL_OBJECT_VALIDATE_STATUS_ARB) - if not valid: - print "Shader failed to validate" - return - - def activate(self, rasty, cachingInfo, mat): - self.pass_no+=1 - if (self.pass_no == 1): - glDisable(GL_COLOR_MATERIAL) - glUseProgramObjectARB(self.m_program) - return True - - glEnable(GL_COLOR_MATERIAL) - glUseProgramObjectARB(0) - self.pass_no = 0 - return False - - obj = GameLogic.getCurrentController().owner - - mesh = obj.meshes[0] - - for mat in mesh.materials: - mat.setCustomMaterial(MyMaterial()) - print mat.texture + + object = logic.getCurrentController().owner + object = cont.owner + for mesh in object.meshes: + for material in mesh.materials: + shader = material.getShader() + if shader != None: + if not shader.isValid(): + shader.setSource(vertex_shader, fragment_shader, True) + + # get the first texture channel of the material + shader.setSampler('color_0', 0) + # get the second texture channel of the material + shader.setSampler('color_1', 1) + # pass another uniform to the shader + shader.setUniform1f('factor', 0.3) + .. attribute:: texture @@ -2932,7 +2870,7 @@ # +----------+ +-----------+ +-------------------------------------+ # | Always +-----+ Python +-----+ Edit Object (Replace Mesh) LOD.Mesh | # +----------+ +-----------+ +-------------------------------------+ - import GameLogic + from bge import logic # List detail meshes here # Mesh (name, near, far) @@ -2942,16 +2880,16 @@ (".Lo", -40.0, -100.0) ) - co = GameLogic.getCurrentController() - obj = co.owner - act = co.actuators["LOD." + obj.name] - cam = GameLogic.getCurrentScene().active_camera + cont = logic.getCurrentController() + object = cont.owner + actuator = cont.actuators["LOD." + obj.name] + camera = logic.getCurrentScene().active_camera def Depth(pos, plane): return pos[0]*plane[0] + pos[1]*plane[1] + pos[2]*plane[2] + plane[3] # Depth is negative and decreasing further from the camera - depth = Depth(obj.position, cam.world_to_camera[2]) + depth = Depth(object.position, camera.world_to_camera[2]) newmesh = None curmesh = None @@ -2959,15 +2897,15 @@ for mesh in meshes: if depth < mesh[1] and depth > mesh[2]: newmesh = mesh - if "ME" + obj.name + mesh[0] == act.getMesh(): + if "ME" + object.name + mesh[0] == actuator.getMesh(): curmesh = mesh - if newmesh != None and "ME" + obj.name + newmesh[0] != act.getMesh(): + if newmesh != None and "ME" + object.name + newmesh[0] != actuator.mesh: # The mesh is a different mesh - switch it. # Check the current mesh is not a better fit. if curmesh == None or curmesh[1] < depth or curmesh[2] > depth: - act.mesh = obj.getName() + newmesh[0] - GameLogic.addActiveActuator(act, True) + actuator.mesh = object.name + newmesh[0] + cont.activate(actuator) .. attribute:: mesh @@ -3003,31 +2941,31 @@ .. code-block:: python - import GameLogic + from bge import logic # get the scene - scene = GameLogic.getCurrentScene() + scene = logic.getCurrentScene() # print all the objects in the scene - for obj in scene.objects: - print obj.name + for object in scene.objects: + print(object.name) # get an object named 'Cube' - obj = scene.objects["Cube"] + object = scene.objects["Cube"] # get the first object in the scene. - obj = scene.objects[0] + object = scene.objects[0] .. code-block:: python # Get the depth of an object in the camera view. - import GameLogic + from bge import logic - obj = GameLogic.getCurrentController().owner - cam = GameLogic.getCurrentScene().active_camera + object = logic.getCurrentController().owner + cam = logic.getCurrentScene().active_camera # Depth is negative and decreasing further from the camera - depth = obj.position[0]*cam.world_to_camera[2][0] + obj.position[1]*cam.world_to_camera[2][1] + obj.position[2]*cam.world_to_camera[2][2] + cam.world_to_camera[2][3] + depth = object.position[0]*cam.world_to_camera[2][0] + object.position[1]*cam.world_to_camera[2][1] + object.position[2]*cam.world_to_camera[2][2] + cam.world_to_camera[2][3] @bug: All attributes are read only at the moment. @@ -4361,9 +4299,9 @@ .. code-block:: python - import GameLogic - co = GameLogic.getCurrentController() - cam = co.owner + from bge import logic + cont = logic.getCurrentController() + cam = cont.owner # A sphere of radius 4.0 located at [x, y, z] = [1.0, 1.0, 1.0] if (cam.sphereInsideFrustum([1.0, 1.0, 1.0], 4) != cam.OUTSIDE): @@ -4386,9 +4324,9 @@ .. code-block:: python - import GameLogic - co = GameLogic.getCurrentController() - cam = co.owner + from bge import logic + cont = logic.getCurrentController() + cam = cont.owner # Box to test... box = [] @@ -4422,9 +4360,9 @@ .. code-block:: python - import GameLogic - co = GameLogic.getCurrentController() - cam = co.owner + from bge import logic + cont = logic.getCurrentController() + cam = cont.owner # Test point [0.0, 0.0, 0.0] if (cam.pointInsideFrustum([0.0, 0.0, 0.0])): diff -Nru blender-2.61/doc/python_api/rst/change_log.rst blender-2.62/doc/python_api/rst/change_log.rst --- blender-2.61/doc/python_api/rst/change_log.rst 2011-12-13 19:54:55.000000000 +0000 +++ blender-2.62/doc/python_api/rst/change_log.rst 2012-02-15 19:39:18.000000000 +0000 @@ -1480,3 +1480,920 @@ * :class:`bpy.types.SceneGameData.restrict_animation_updates` * :class:`bpy.types.SceneGameData.show_obstacle_simulation` + +2.60 to 2.61 +============ + +bpy.types.BlendDataGroups +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.BlendDataGroups.is_updated` + +bpy.types.BlendDataBrushes +-------------------------- + +Added +^^^^^ + +* :class:`bpy.types.BlendDataBrushes.is_updated` + +bpy.types.Theme +--------------- + +Added +^^^^^ + +* :class:`bpy.types.Theme.clip_editor` + +bpy.types.BlendData +------------------- + +Added +^^^^^ + +* :class:`bpy.types.BlendData.movieclips` + +bpy.types.BlendDataGreasePencils +-------------------------------- + +Added +^^^^^ + +* :class:`bpy.types.BlendDataGreasePencils.is_updated` + +bpy.types.BlendDataImages +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.BlendDataImages.is_updated` + +bpy.types.CompositorNodes +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.CompositorNodes.clear` + +bpy.types.BlendDataScenes +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.BlendDataScenes.is_updated` + +bpy.types.RenderEngine +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.RenderEngine.bl_use_shading_nodes` +* :class:`bpy.types.RenderEngine.is_animation` +* :class:`bpy.types.RenderEngine.is_preview` +* :class:`bpy.types.RenderEngine.tag_redraw` +* :class:`bpy.types.RenderEngine.tag_update` +* :class:`bpy.types.RenderEngine.update` +* :class:`bpy.types.RenderEngine.update_progress` +* :class:`bpy.types.RenderEngine.view_draw` +* :class:`bpy.types.RenderEngine.view_update` + +bpy.types.BackgroundImage +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.BackgroundImage.clip` +* :class:`bpy.types.BackgroundImage.clip_user` +* :class:`bpy.types.BackgroundImage.show_background_image` +* :class:`bpy.types.BackgroundImage.source` +* :class:`bpy.types.BackgroundImage.use_camera_clip` + +bpy.types.BlendDataMetaBalls +---------------------------- + +Added +^^^^^ + +* :class:`bpy.types.BlendDataMetaBalls.is_updated` + +bpy.types.SpaceTimeline +----------------------- + +Added +^^^^^ + +* :class:`bpy.types.SpaceTimeline.cache_dynamicpaint` + +bpy.types.BlendDataMeshes +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.BlendDataMeshes.is_updated` + +bpy.types.BlendDataNodeTrees +---------------------------- + +Added +^^^^^ + +* :class:`bpy.types.BlendDataNodeTrees.is_updated` + +bpy.types.RenderSettings +------------------------ + +Added +^^^^^ + +* :class:`bpy.types.RenderSettings.image_settings` +* :class:`bpy.types.RenderSettings.use_shading_nodes` + +Removed +^^^^^^^ + +* **cineon_black** +* **cineon_gamma** +* **cineon_white** +* **color_mode** +* **exr_codec** +* **exr_preview** +* **exr_zbuf** +* **file_format** +* **file_quality** +* **jpeg2k_depth** +* **jpeg2k_preset** +* **jpeg2k_ycc** +* **use_cineon_log** +* **use_exr_half** +* **use_tiff_16bit** + +bpy.types.RegionView3D +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.RegionView3D.view_camera_offset` +* :class:`bpy.types.RegionView3D.view_camera_zoom` + +bpy.types.Scene +--------------- + +Added +^^^^^ + +* :class:`bpy.types.Scene.active_clip` + +bpy.types.NodeLinks +------------------- + +Added +^^^^^ + +* :class:`bpy.types.NodeLinks.clear` + +bpy.types.BlendDataLattices +--------------------------- + +Added +^^^^^ + +* :class:`bpy.types.BlendDataLattices.is_updated` + +bpy.types.BlendDataParticles +---------------------------- + +Added +^^^^^ + +* :class:`bpy.types.BlendDataParticles.is_updated` + +bpy.types.BlendDataWorlds +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.BlendDataWorlds.is_updated` + +bpy.types.ObjectConstraints +--------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ObjectConstraints.clear` + +bpy.types.RenderLayers +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.RenderLayers.new` +* :class:`bpy.types.RenderLayers.remove` + +bpy.types.Menu +-------------- + +Added +^^^^^ + +* :class:`bpy.types.Menu.bl_description` + +bpy.types.Lamp +-------------- + +Added +^^^^^ + +* :class:`bpy.types.Lamp.node_tree` +* :class:`bpy.types.Lamp.use_nodes` + +bpy.types.CurveSplines +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.CurveSplines.clear` + +bpy.types.Screen +---------------- + +Added +^^^^^ + +* :class:`bpy.types.Screen.use_play_clip_editors` + +bpy.types.BlendDataActions +-------------------------- + +Added +^^^^^ + +* :class:`bpy.types.BlendDataActions.is_updated` + +bpy.types.BlendDataSounds +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.BlendDataSounds.is_updated` + +bpy.types.Object +---------------- + +Added +^^^^^ + +* :class:`bpy.types.Object.slow_parent_offset` + +Removed +^^^^^^^ + +* **time_offset** +* **use_time_offset_add_parent** +* **use_time_offset_edit** +* **use_time_offset_parent** +* **use_time_offset_particle** + +bpy.types.ObjectModifiers +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ObjectModifiers.clear` + +bpy.types.BlendDataMaterials +---------------------------- + +Added +^^^^^ + +* :class:`bpy.types.BlendDataMaterials.is_updated` + +bpy.types.MetaBallElements +-------------------------- + +Added +^^^^^ + +* :class:`bpy.types.MetaBallElements.clear` + +bpy.types.NodeSocket +-------------------- + +Added +^^^^^ + +* :class:`bpy.types.NodeSocket.group_socket` +* :class:`bpy.types.NodeSocket.show_expanded` + +bpy.types.Node +-------------- + +Added +^^^^^ + +* :class:`bpy.types.Node.show_texture` + +bpy.types.CompositorNodeOutputFile +---------------------------------- + +Added +^^^^^ + +* :class:`bpy.types.CompositorNodeOutputFile.image_settings` + +Removed +^^^^^^^ + +* **exr_codec** +* **image_type** +* **quality** +* **use_exr_half** + +bpy.types.BlendDataTexts +------------------------ + +Added +^^^^^ + +* :class:`bpy.types.BlendDataTexts.is_updated` + +bpy.types.ThemeView3D +--------------------- + +Added +^^^^^ + +* :class:`bpy.types.ThemeView3D.bundle_solid` +* :class:`bpy.types.ThemeView3D.camera_path` + +bpy.types.Event +--------------- + +Added +^^^^^ + +* :class:`bpy.types.Event.unicode` + +bpy.types.VertexGroups +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.VertexGroups.clear` + +bpy.types.TexMapping +-------------------- + +Added +^^^^^ + +* :class:`bpy.types.TexMapping.mapping` +* :class:`bpy.types.TexMapping.mapping_x` +* :class:`bpy.types.TexMapping.mapping_y` +* :class:`bpy.types.TexMapping.mapping_z` + +bpy.types.BlendDataObjects +-------------------------- + +Added +^^^^^ + +* :class:`bpy.types.BlendDataObjects.is_updated` + +bpy.types.BlendDataCurves +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.BlendDataCurves.is_updated` + +bpy.types.BlendDataLibraries +---------------------------- + +Added +^^^^^ + +* :class:`bpy.types.BlendDataLibraries.is_updated` + +bpy.types.ThemeUserInterface +---------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ThemeUserInterface.icon_alpha` +* :class:`bpy.types.ThemeUserInterface.panel` + +bpy.types.SpaceNodeEditor +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.SpaceNodeEditor.shader_type` + +bpy.types.SpaceView3D +--------------------- + +Added +^^^^^ + +* :class:`bpy.types.SpaceView3D.show_bundle_names` +* :class:`bpy.types.SpaceView3D.show_camera_path` +* :class:`bpy.types.SpaceView3D.show_reconstruction` +* :class:`bpy.types.SpaceView3D.tracks_draw_size` +* :class:`bpy.types.SpaceView3D.tracks_draw_type` + +bpy.types.BlendDataWindowManagers +--------------------------------- + +Added +^^^^^ + +* :class:`bpy.types.BlendDataWindowManagers.is_updated` + +bpy.types.BlendDataScreens +-------------------------- + +Added +^^^^^ + +* :class:`bpy.types.BlendDataScreens.is_updated` + +bpy.types.BlendDataArmatures +---------------------------- + +Added +^^^^^ + +* :class:`bpy.types.BlendDataArmatures.is_updated` + +bpy.types.UserPreferencesInput +------------------------------ + +Added +^^^^^ + +* :class:`bpy.types.UserPreferencesInput.tweak_threshold` + +Removed +^^^^^^^ + +* **ndof_orbit_invert_axes** + +bpy.types.BlendDataCameras +-------------------------- + +Added +^^^^^ + +* :class:`bpy.types.BlendDataCameras.is_updated` + +bpy.types.UILayout +------------------ + +Added +^^^^^ + +* :class:`bpy.types.UILayout.template_image_settings` +* :class:`bpy.types.UILayout.template_marker` +* :class:`bpy.types.UILayout.template_movieclip` +* :class:`bpy.types.UILayout.template_node_link` +* :class:`bpy.types.UILayout.template_node_view` +* :class:`bpy.types.UILayout.template_texture_user` +* :class:`bpy.types.UILayout.template_track` + +Function Arguments +^^^^^^^^^^^^^^^^^^ + +* :class:`bpy.types.UILayout.template_list` (data, property, active_data, active_property, prop_list, rows, maxrows, type), *was (data, property, active_data, active_property, rows, maxrows, type)* + +bpy.types.ID +------------ + +Added +^^^^^ + +* :class:`bpy.types.ID.is_updated` +* :class:`bpy.types.ID.is_updated_data` + +bpy.types.World +--------------- + +Added +^^^^^ + +* :class:`bpy.types.World.node_tree` +* :class:`bpy.types.World.use_nodes` + +bpy.types.BlendDataTextures +--------------------------- + +Added +^^^^^ + +* :class:`bpy.types.BlendDataTextures.is_updated` + +bpy.types.ShaderNodes +--------------------- + +Added +^^^^^ + +* :class:`bpy.types.ShaderNodes.clear` + +bpy.types.TimelineMarkers +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.TimelineMarkers.clear` + +bpy.types.SpaceFileBrowser +-------------------------- + +Added +^^^^^ + +* :class:`bpy.types.SpaceFileBrowser.active_operator` + +bpy.types.BlendDataSpeakers +--------------------------- + +Added +^^^^^ + +* :class:`bpy.types.BlendDataSpeakers.is_updated` + +bpy.types.Camera +---------------- + +Added +^^^^^ + +* :class:`bpy.types.Camera.angle_x` +* :class:`bpy.types.Camera.angle_y` +* :class:`bpy.types.Camera.sensor_fit` +* :class:`bpy.types.Camera.sensor_height` +* :class:`bpy.types.Camera.sensor_width` +* :class:`bpy.types.Camera.show_sensor` + +bpy.types.BlendDataLamps +------------------------ + +Added +^^^^^ + +* :class:`bpy.types.BlendDataLamps.is_updated` + +bpy.types.TextureNodes +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.TextureNodes.clear` + +bpy.types.BlendDataFonts +------------------------ + +Added +^^^^^ + +* :class:`bpy.types.BlendDataFonts.is_updated` + + +2.61 to 2.62 +============ + +bpy.types.SpaceTimeline +----------------------- + +Added +^^^^^ + +* :class:`bpy.types.SpaceTimeline.show_seconds` + +bpy.types.MovieClipProxy +------------------------ + +Added +^^^^^ + +* :class:`bpy.types.MovieClipProxy.build_undistorted_100` +* :class:`bpy.types.MovieClipProxy.build_undistorted_25` +* :class:`bpy.types.MovieClipProxy.build_undistorted_50` +* :class:`bpy.types.MovieClipProxy.build_undistorted_75` + +Removed +^^^^^^^ + +* **build_undistorted** + +bpy.types.ToolSettings +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.ToolSettings.unified_paint_settings` +* :class:`bpy.types.ToolSettings.use_uv_sculpt` +* :class:`bpy.types.ToolSettings.uv_relax_method` +* :class:`bpy.types.ToolSettings.uv_sculpt` +* :class:`bpy.types.ToolSettings.uv_sculpt_all_islands` +* :class:`bpy.types.ToolSettings.uv_sculpt_lock_borders` +* :class:`bpy.types.ToolSettings.uv_sculpt_tool` + +Removed +^^^^^^^ + +* **sculpt_paint_use_unified_size** +* **sculpt_paint_use_unified_strength** + +bpy.types.DupliObject +--------------------- + +Added +^^^^^ + +* :class:`bpy.types.DupliObject.hide` + +bpy.types.Curve +--------------- + +Added +^^^^^ + +* :class:`bpy.types.Curve.use_fill_caps` + +bpy.types.DomainFluidSettings +----------------------------- + +Added +^^^^^ + +* :class:`bpy.types.DomainFluidSettings.frame_offset` +* :class:`bpy.types.DomainFluidSettings.simulation_rate` + +bpy.types.SceneGameData +----------------------- + +Added +^^^^^ + +* :class:`bpy.types.SceneGameData.exit_key` +* :class:`bpy.types.SceneGameData.samples` +* :class:`bpy.types.SceneGameData.use_desktop` + +bpy.types.Sensor +---------------- + +Added +^^^^^ + +* :class:`bpy.types.Sensor.controllers` + +bpy.types.Scene +--------------- + +Removed +^^^^^^^ + +* **collada_export** + +bpy.types.Controller +-------------------- + +Added +^^^^^ + +* :class:`bpy.types.Controller.actuators` + +bpy.types.SceneRenderLayer +-------------------------- + +Added +^^^^^ + +* :class:`bpy.types.SceneRenderLayer.use_pass_diffuse_color` +* :class:`bpy.types.SceneRenderLayer.use_pass_diffuse_direct` +* :class:`bpy.types.SceneRenderLayer.use_pass_diffuse_indirect` +* :class:`bpy.types.SceneRenderLayer.use_pass_glossy_color` +* :class:`bpy.types.SceneRenderLayer.use_pass_glossy_direct` +* :class:`bpy.types.SceneRenderLayer.use_pass_glossy_indirect` +* :class:`bpy.types.SceneRenderLayer.use_pass_transmission_color` +* :class:`bpy.types.SceneRenderLayer.use_pass_transmission_direct` +* :class:`bpy.types.SceneRenderLayer.use_pass_transmission_indirect` + +bpy.types.ClothSettings +----------------------- + +Added +^^^^^ + +* :class:`bpy.types.ClothSettings.vel_damping` + +bpy.types.FollowTrackConstraint +------------------------------- + +Added +^^^^^ + +* :class:`bpy.types.FollowTrackConstraint.camera` +* :class:`bpy.types.FollowTrackConstraint.depth_object` +* :class:`bpy.types.FollowTrackConstraint.object` + +bpy.types.ImageFormatSettings +----------------------------- + +Removed +^^^^^^^ + +* **exr_codec** +* **use_jpeg2k_cinema_48** +* **use_jpeg2k_cinema_preset** +* **use_jpeg2k_ycc** + +bpy.types.Property +------------------ + +Added +^^^^^ + +* :class:`bpy.types.Property.translation_context` + +bpy.types.MovieTrackingTrack +---------------------------- + +Added +^^^^^ + +* :class:`bpy.types.MovieTrackingTrack.use_grayscale_preview` + +Removed +^^^^^^^ + +* **marker_find_frame** + +bpy.types.Object +---------------- + +Added +^^^^^ + +* :class:`bpy.types.Object.dm_info` + + +bpy.types.UserPreferencesSystem +------------------------------- + +Added +^^^^^ + +* :class:`bpy.types.UserPreferencesSystem.compute_device` +* :class:`bpy.types.UserPreferencesSystem.compute_device_type` +* :class:`bpy.types.UserPreferencesSystem.use_16bit_textures` + +bpy.types.SpaceClipEditor +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.SpaceClipEditor.lock_time_cursor` +* :class:`bpy.types.SpaceClipEditor.show_blue_channel` +* :class:`bpy.types.SpaceClipEditor.show_green_channel` +* :class:`bpy.types.SpaceClipEditor.show_red_channel` +* :class:`bpy.types.SpaceClipEditor.use_grayscale_preview` + +Removed +^^^^^^^ + +* **show_grease_pencil** +* **show_pyramid_levels** + +bpy.types.VertexPaint +--------------------- + +Added +^^^^^ + +* :class:`bpy.types.VertexPaint.use_group_restrict` + +bpy.types.DynamicPaintSurface +----------------------------- + +Added +^^^^^ + +* :class:`bpy.types.DynamicPaintSurface.brush_influence_scale` +* :class:`bpy.types.DynamicPaintSurface.brush_radius_scale` +* :class:`bpy.types.DynamicPaintSurface.color_dry_threshold` +* :class:`bpy.types.DynamicPaintSurface.use_drying` + +bpy.types.RenderLayer +--------------------- + +Added +^^^^^ + +* :class:`bpy.types.RenderLayer.use_pass_diffuse_color` +* :class:`bpy.types.RenderLayer.use_pass_diffuse_direct` +* :class:`bpy.types.RenderLayer.use_pass_diffuse_indirect` +* :class:`bpy.types.RenderLayer.use_pass_glossy_color` +* :class:`bpy.types.RenderLayer.use_pass_glossy_direct` +* :class:`bpy.types.RenderLayer.use_pass_glossy_indirect` +* :class:`bpy.types.RenderLayer.use_pass_transmission_color` +* :class:`bpy.types.RenderLayer.use_pass_transmission_direct` +* :class:`bpy.types.RenderLayer.use_pass_transmission_indirect` + +bpy.types.MovieTracking +----------------------- + +Added +^^^^^ + +* :class:`bpy.types.MovieTracking.active_object_index` +* :class:`bpy.types.MovieTracking.objects` + +bpy.types.MovieTrackingSettings +------------------------------- + +Added +^^^^^ + +* :class:`bpy.types.MovieTrackingSettings.object_distance` +* :class:`bpy.types.MovieTrackingSettings.use_default_blue_channel` +* :class:`bpy.types.MovieTrackingSettings.use_default_green_channel` +* :class:`bpy.types.MovieTrackingSettings.use_default_red_channel` + +bpy.types.Mesh +-------------- + +Added +^^^^^ + +* :class:`bpy.types.Mesh.show_extra_indices` + +bpy.types.SpaceSequenceEditor +----------------------------- + +Added +^^^^^ + +* :class:`bpy.types.SpaceSequenceEditor.show_seconds` + +Removed +^^^^^^^ + +* **offset_x** +* **offset_y** +* **zoom** + +bpy.types.RenderSettings +------------------------ + +Added +^^^^^ + +* :class:`bpy.types.RenderSettings.ffmpeg` +* :class:`bpy.types.RenderSettings.use_color_unpremultiply` + +Removed +^^^^^^^ + +* **ffmpeg_audio_bitrate** +* **ffmpeg_audio_channels** +* **ffmpeg_audio_codec** +* **ffmpeg_audio_mixrate** +* **ffmpeg_audio_volume** +* **ffmpeg_autosplit** +* **ffmpeg_buffersize** +* **ffmpeg_codec** +* **ffmpeg_format** +* **ffmpeg_gopsize** +* **ffmpeg_maxrate** +* **ffmpeg_minrate** +* **ffmpeg_muxrate** +* **ffmpeg_packetsize** +* **ffmpeg_video_bitrate** + diff -Nru blender-2.61/doc/python_api/rst/gpu.rst blender-2.62/doc/python_api/rst/gpu.rst --- blender-2.61/doc/python_api/rst/gpu.rst 2011-12-13 19:54:55.000000000 +0000 +++ blender-2.62/doc/python_api/rst/gpu.rst 2012-02-15 19:39:18.000000000 +0000 @@ -1,13 +1,14 @@ +******************* GPU functions (gpu) -=================== +******************* .. module:: gpu This module provides access to materials GLSL shaders. -***** + Intro -***** +===== Module to provide functions concerning the GPU implementation in Blender, in particular the GLSL shaders that blender generates automatically to render materials in the 3D view @@ -15,16 +16,15 @@ .. warning:: - The API provided by this module should be consider unstable. The data exposed by the API - are are closely related to Blender's internal GLSL code and may change if the GLSL code - is modified (e.g. new uniform type). + The API provided by this module should be consider unstable. The data exposed by the API + are are closely related to Blender's internal GLSL code and may change if the GLSL code + is modified (e.g. new uniform type). -********* Constants -********* +========= + --------------- GLSL data type -------------- @@ -59,15 +59,15 @@ .. data:: GPU_DATA_3F three floats - + :value: 4 - + .. data:: GPU_DATA_4F four floats - + :value: 5 - + .. data:: GPU_DATA_9F matrix 3x3 in column-major order @@ -86,448 +86,450 @@ :value: 8 ------------------ + GLSL uniform type ----------------- .. _uniform-type: -Constants that specify the type of uniform used in a GLSL shader. +Constants that specify the type of uniform used in a GLSL shader. The uniform type determines the data type, origin and method -of calculation used by Blender to compute the uniform value. +of calculation used by Blender to compute the uniform value. The calculation of some of the uniforms is based on matrices available in the scene: - .. _mat4_cam_to_world: - .. _mat4_world_to_cam: + .. _mat4_cam_to_world: + .. _mat4_world_to_cam: + + *mat4_cam_to_world* + Model matrix of the camera. OpenGL 4x4 matrix that converts + camera local coordinates to world coordinates. In blender this is obtained from the + 'matrix_world' attribute of the camera object. + + Some uniform will need the *mat4_world_to_cam* + matrix computed as the inverse of this matrix. + + .. _mat4_object_to_world: + .. _mat4_world_to_object: + + *mat4_object_to_world* + Model matrix of the object that is being rendered. OpenGL 4x4 matric that converts + object local coordinates to world coordinates. In blender this is obtained from the + 'matrix_world' attribute of the object. - *mat4_cam_to_world* - Model matrix of the camera. OpenGL 4x4 matrix that converts - camera local coordinates to world coordinates. In blender this is obtained from the - 'matrix_world' attribute of the camera object. - - Some uniform will need the *mat4_world_to_cam* - matrix computed as the inverse of this matrix. - - .. _mat4_object_to_world: - .. _mat4_world_to_object: - - *mat4_object_to_world* - Model matrix of the object that is being rendered. OpenGL 4x4 matric that converts - object local coordinates to world coordinates. In blender this is obtained from the - 'matrix_world' attribute of the object. - - Some uniform will need the *mat4_world_to_object* matrix, computed as the inverse of this matrix. - - .. _mat4_lamp_to_world: - .. _mat4_world_to_lamp: - - *mat4_lamp_to_world* - Model matrix of the lamp lighting the object. OpenGL 4x4 matrix that converts lamp - local coordinates to world coordinates. In blender this is obtained from the - 'matrix_world' attribute of the lamp object. - - Some uniform will need the *mat4_world_to_lamp* matrix - computed as the inverse of this matrix. + Some uniform will need the *mat4_world_to_object* matrix, computed as the inverse of this matrix. + + .. _mat4_lamp_to_world: + .. _mat4_world_to_lamp: + + *mat4_lamp_to_world* + Model matrix of the lamp lighting the object. OpenGL 4x4 matrix that converts lamp + local coordinates to world coordinates. In blender this is obtained from the + 'matrix_world' attribute of the lamp object. + + Some uniform will need the *mat4_world_to_lamp* matrix + computed as the inverse of this matrix. .. data:: GPU_DYNAMIC_OBJECT_VIEWMAT - The uniform is a 4x4 GL matrix that converts world coordinates to - camera coordinates (see mat4_world_to_cam_). Can be set once per frame. - There is at most one uniform of that type per shader. + The uniform is a 4x4 GL matrix that converts world coordinates to + camera coordinates (see mat4_world_to_cam_). Can be set once per frame. + There is at most one uniform of that type per shader. - :value: 1 + :value: 1 .. data:: GPU_DYNAMIC_OBJECT_MAT - The uniform is a 4x4 GL matrix that converts object coordinates - to world coordinates (see mat4_object_to_world_). Must be set before drawing the object. - There is at most one uniform of that type per shader. + The uniform is a 4x4 GL matrix that converts object coordinates + to world coordinates (see mat4_object_to_world_). Must be set before drawing the object. + There is at most one uniform of that type per shader. - :value: 2 + :value: 2 .. data:: GPU_DYNAMIC_OBJECT_VIEWIMAT - The uniform is a 4x4 GL matrix that converts coordinates - in camera space to world coordinates (see mat4_cam_to_world_). - Can be set once per frame. - There is at most one uniform of that type per shader. + The uniform is a 4x4 GL matrix that converts coordinates + in camera space to world coordinates (see mat4_cam_to_world_). + Can be set once per frame. + There is at most one uniform of that type per shader. - :value: 3 + :value: 3 .. data:: GPU_DYNAMIC_OBJECT_IMAT - The uniform is a 4x4 GL matrix that converts world coodinates - to object coordinates (see mat4_world_to_object_). - Must be set before drawing the object. - There is at most one uniform of that type per shader. - - :value: 4 - + The uniform is a 4x4 GL matrix that converts world coodinates + to object coordinates (see mat4_world_to_object_). + Must be set before drawing the object. + There is at most one uniform of that type per shader. + + :value: 4 + .. data:: GPU_DYNAMIC_OBJECT_COLOR - The uniform is a vector of 4 float representing a RGB color + alpha defined at object level. - Each values between 0.0 and 1.0. In blender it corresponds to the 'color' attribute of the object. - Must be set before drawing the object. - There is at most one uniform of that type per shader. - - :value: 5 - + The uniform is a vector of 4 float representing a RGB color + alpha defined at object level. + Each values between 0.0 and 1.0. In blender it corresponds to the 'color' attribute of the object. + Must be set before drawing the object. + There is at most one uniform of that type per shader. + + :value: 5 + .. data:: GPU_DYNAMIC_LAMP_DYNVEC - The uniform is a vector of 3 float representing the direction of light in camera space. - In Blender, this is computed by + The uniform is a vector of 3 float representing the direction of light in camera space. + In Blender, this is computed by - mat4_world_to_cam_ * (-vec3_lamp_Z_axis) + mat4_world_to_cam_ * (-vec3_lamp_Z_axis) - as the lamp Z axis points to the opposite direction of light. - The norm of the vector should be unity. Can be set once per frame. - There is one uniform of that type per lamp lighting the material. + as the lamp Z axis points to the opposite direction of light. + The norm of the vector should be unity. Can be set once per frame. + There is one uniform of that type per lamp lighting the material. + + :value: 6 - :value: 6 - .. data:: GPU_DYNAMIC_LAMP_DYNCO - The uniform is a vector of 3 float representing the position of the light in camera space. - Computed as - - mat4_world_to_cam_ * vec3_lamp_pos - - Can be set once per frame. - There is one uniform of that type per lamp lighting the material. - - :value: 7 - + The uniform is a vector of 3 float representing the position of the light in camera space. + Computed as + + mat4_world_to_cam_ * vec3_lamp_pos + + Can be set once per frame. + There is one uniform of that type per lamp lighting the material. + + :value: 7 + .. data:: GPU_DYNAMIC_LAMP_DYNIMAT - The uniform is a 4x4 GL matrix that converts vector in camera space to lamp space. - Computed as + The uniform is a 4x4 GL matrix that converts vector in camera space to lamp space. + Computed as - mat4_world_to_lamp_ * mat4_cam_to_world_ + mat4_world_to_lamp_ * mat4_cam_to_world_ - Can be set once per frame. - There is one uniform of that type per lamp lighting the material. + Can be set once per frame. + There is one uniform of that type per lamp lighting the material. - :value: 8 + :value: 8 .. data:: GPU_DYNAMIC_LAMP_DYNPERSMAT - The uniform is a 4x4 GL matrix that converts a vector in camera space to shadow buffer depth space. - Computed as + The uniform is a 4x4 GL matrix that converts a vector in camera space to shadow buffer depth space. + Computed as - mat4_perspective_to_depth_ * mat4_lamp_to_perspective_ * mat4_world_to_lamp_ * mat4_cam_to_world_. + mat4_perspective_to_depth_ * mat4_lamp_to_perspective_ * mat4_world_to_lamp_ * mat4_cam_to_world_. - .. _mat4_perspective_to_depth: + .. _mat4_perspective_to_depth: - *mat4_perspective_to_depth* is a fixed matrix defined as follow:: + *mat4_perspective_to_depth* is a fixed matrix defined as follow:: - 0.5 0.0 0.0 0.5 - 0.0 0.5 0.0 0.5 - 0.0 0.0 0.5 0.5 - 0.0 0.0 0.0 1.0 + 0.5 0.0 0.0 0.5 + 0.0 0.5 0.0 0.5 + 0.0 0.0 0.5 0.5 + 0.0 0.0 0.0 1.0 - This uniform can be set once per frame. There is one uniform of that type per lamp casting shadow in the scene. + This uniform can be set once per frame. There is one uniform of that type per lamp casting shadow in the scene. - :value: 9 + :value: 9 .. data:: GPU_DYNAMIC_LAMP_DYNENERGY - The uniform is a single float representing the lamp energy. In blender it corresponds - to the 'energy' attribute of the lamp data block. - There is one uniform of that type per lamp lighting the material. + The uniform is a single float representing the lamp energy. In blender it corresponds + to the 'energy' attribute of the lamp data block. + There is one uniform of that type per lamp lighting the material. - :value: 10 + :value: 10 .. data:: GPU_DYNAMIC_LAMP_DYNCOL - The uniform is a vector of 3 float representing the lamp color. - Color elements are between 0.0 and 1.0. In blender it corresponds - to the 'color' attribute of the lamp data block. - There is one uniform of that type per lamp lighting the material. + The uniform is a vector of 3 float representing the lamp color. + Color elements are between 0.0 and 1.0. In blender it corresponds + to the 'color' attribute of the lamp data block. + There is one uniform of that type per lamp lighting the material. - :value: 11 + :value: 11 .. data:: GPU_DYNAMIC_SAMPLER_2DBUFFER - The uniform is an integer representing an internal texture used for certain effect - (color band, etc). - - :value: 12 + The uniform is an integer representing an internal texture used for certain effect + (color band, etc). + + :value: 12 .. data:: GPU_DYNAMIC_SAMPLER_2DIMAGE - The uniform is an integer representing a texture loaded from an image file. + The uniform is an integer representing a texture loaded from an image file. - :value: 13 + :value: 13 .. data:: GPU_DYNAMIC_SAMPLER_2DSHADOW - The uniform is an integer representing a shadow buffer corresponding to a lamp - casting shadow. + The uniform is an integer representing a shadow buffer corresponding to a lamp + casting shadow. + + :value: 14 - :value: 14 -------------------- GLSL attribute type ------------------- .. _attribute-type: Type of the vertex attribute used in the GLSL shader. Determines the mesh custom data -layer that contains the vertex attribute. +layer that contains the vertex attribute. .. data:: CD_MTFACE - Vertex attribute is a UV Map. Data type is vector of 2 float. + Vertex attribute is a UV Map. Data type is vector of 2 float. - There can be more than one attribute of that type, they are differenciated by name. - In blender, you can retrieve the attribute data with: + There can be more than one attribute of that type, they are differenciated by name. + In blender, you can retrieve the attribute data with: - .. code-block:: python + .. code-block:: python - mesh.uv_textures[attribute['name']] + mesh.uv_textures[attribute["name"]] - :value: 5 + :value: 5 .. data:: CD_MCOL - Vertex attribute is color layer. Data type is vector 4 unsigned byte (RGBA). + Vertex attribute is color layer. Data type is vector 4 unsigned byte (RGBA). - There can be more than one attribute of that type, they are differenciated by name. - In blender you can retrieve the attribute data with: + There can be more than one attribute of that type, they are differenciated by name. + In blender you can retrieve the attribute data with: - .. code-block:: python + .. code-block:: python - mesh.vertex_colors[attribute['name']] + mesh.vertex_colors[attribute["name"]] - :value: 6 + :value: 6 .. data:: CD_ORCO - Vertex attribute is original coordinates. Data type is vector 3 float. + Vertex attribute is original coordinates. Data type is vector 3 float. + + There can be only 1 attribute of that type per shader. + In blender you can retrieve the attribute data with: - There can be only 1 attribute of that type per shader. - In blender you can retrieve the attribute data with: - - .. code-block:: python + .. code-block:: python - mesh.vertices + mesh.vertices - :value: 14 + :value: 14 .. data:: CD_TANGENT - Vertex attribute is the tangent vector. Data type is vector 4 float. + Vertex attribute is the tangent vector. Data type is vector 4 float. - There can be only 1 attribute of that type per shader. - There is currently no way to retrieve this attribute data via the RNA API but a standalone - C function to compute the tangent layer from the other layers can be obtained from - blender.org. + There can be only 1 attribute of that type per shader. + There is currently no way to retrieve this attribute data via the RNA API but a standalone + C function to compute the tangent layer from the other layers can be obtained from + blender.org. + + :value: 18 - :value: 18 -********* Functions -********* +========= .. _export_shader: .. function:: export_shader(scene,material) - Extracts the GLSL shader producing the visual effect of material in scene for the purpose of - reusing the shader in an external engine. This function is meant to be used in material exporter - so that the GLSL shader can be exported entirely. The return value is a dictionary containing the - shader source code and all associated data. - - :arg scene: the scene in which the material in rendered. - :type scene: :class:`bpy.types.Scene` - :arg material: the material that you want to export the GLSL shader - :type material: :class:`bpy.types.Material` - :return: the shader source code and all associated data in a dictionary - :rtype: dictionary - - The dictionary contains the following elements: - - * ['fragment'] : string - fragment shader source code. - - * ['vertex'] : string - vertex shader source code. - - * ['uniforms'] : sequence - list of uniforms used in fragment shader, can be empty list. Each element of the - sequence is a dictionary with the following elements: - - * ['varname'] : string - name of the uniform in the fragment shader. Always of the form 'unf'. - - * ['datatype'] : integer - data type of the uniform variable. Can be one of the following: - - * :data:`gpu.GPU_DATA_1I` : use glUniform1i - * :data:`gpu.GPU_DATA_1F` : use glUniform1fv - * :data:`gpu.GPU_DATA_2F` : use glUniform2fv - * :data:`gpu.GPU_DATA_3F` : use glUniform3fv - * :data:`gpu.GPU_DATA_4F` : use glUniform4fv - * :data:`gpu.GPU_DATA_9F` : use glUniformMatrix3fv - * :data:`gpu.GPU_DATA_16F` : use glUniformMatrix4fv - - * ['type'] : integer - type of uniform, determines the origin and method of calculation. See uniform-type_. - Depending on the type, more elements will be be present. - - * ['lamp'] : :class:`bpy.types.Object` - Reference to the lamp object from which the uniforms value are extracted. Set for the following uniforms types: - - .. hlist:: - :columns: 3 - - * :data:`gpu.GPU_DYNAMIC_LAMP_DYNVEC` - * :data:`gpu.GPU_DYNAMIC_LAMP_DYNCO` - * :data:`gpu.GPU_DYNAMIC_LAMP_DYNIMAT` - * :data:`gpu.GPU_DYNAMIC_LAMP_DYNPERSMAT` - * :data:`gpu.GPU_DYNAMIC_LAMP_DYNENERGY` - * :data:`gpu.GPU_DYNAMIC_LAMP_DYNCOL` - * :data:`gpu.GPU_DYNAMIC_SAMPLER_2DSHADOW` - - Notes: - - * The uniforms :data:`gpu.GPU_DYNAMIC_LAMP_DYNVEC`, :data:`gpu.GPU_DYNAMIC_LAMP_DYNCO`, :data:`gpu.GPU_DYNAMIC_LAMP_DYNIMAT` and :data:`gpu.GPU_DYNAMIC_LAMP_DYNPERSMAT` - refer to the lamp object position and orientation, both of can be derived from the object world matrix: - - .. code-block:: python - - obmat = uniform['lamp'].matrix_world - - where obmat is the mat4_lamp_to_world_ matrix of the lamp as a 2 dimensional array, - the lamp world location location is in obmat[3]. - - * The uniform types :data:`gpu.GPU_DYNAMIC_LAMP_DYNENERGY` and :data:`gpu.GPU_DYNAMIC_LAMP_DYNCOL` refer to the lamp data bloc that you get from: - - .. code-block:: python - - la = uniform['lamp'].data - - from which you get la.energy and la.color - - * Lamp duplication is not supported: if you have duplicated lamps in your scene - (i.e. lamp that are instantiated by dupligroup, etc), this element will only - give you a reference to the orignal lamp and you will not know which instance - of the lamp it is refering too. You can still handle that case in the exporter - by distributing the uniforms amongst the duplicated lamps. - - * ['image'] : :class:`bpy.types.Image` - Reference to the image databloc. Set for uniform type :data:`gpu.GPU_DYNAMIC_SAMPLER_2DIMAGE`. You can get the image data from: + Extracts the GLSL shader producing the visual effect of material in scene for the purpose of + reusing the shader in an external engine. This function is meant to be used in material exporter + so that the GLSL shader can be exported entirely. The return value is a dictionary containing the + shader source code and all associated data. + + :arg scene: the scene in which the material in rendered. + :type scene: :class:`bpy.types.Scene` + :arg material: the material that you want to export the GLSL shader + :type material: :class:`bpy.types.Material` + :return: the shader source code and all associated data in a dictionary + :rtype: dictionary + + The dictionary contains the following elements: + + * ["fragment"] : string + fragment shader source code. + + * ["vertex"] : string + vertex shader source code. + + * ["uniforms"] : sequence + list of uniforms used in fragment shader, can be empty list. Each element of the + sequence is a dictionary with the following elements: + + * ["varname"] : string + name of the uniform in the fragment shader. Always of the form 'unf'. + + * ["datatype"] : integer + data type of the uniform variable. Can be one of the following: + + * :data:`gpu.GPU_DATA_1I` : use glUniform1i + * :data:`gpu.GPU_DATA_1F` : use glUniform1fv + * :data:`gpu.GPU_DATA_2F` : use glUniform2fv + * :data:`gpu.GPU_DATA_3F` : use glUniform3fv + * :data:`gpu.GPU_DATA_4F` : use glUniform4fv + * :data:`gpu.GPU_DATA_9F` : use glUniformMatrix3fv + * :data:`gpu.GPU_DATA_16F` : use glUniformMatrix4fv + + * ["type"] : integer + type of uniform, determines the origin and method of calculation. See uniform-type_. + Depending on the type, more elements will be be present. + + * ["lamp"] : :class:`bpy.types.Object` + Reference to the lamp object from which the uniforms value are extracted. Set for the following uniforms types: + + .. hlist:: + :columns: 3 + + * :data:`gpu.GPU_DYNAMIC_LAMP_DYNVEC` + * :data:`gpu.GPU_DYNAMIC_LAMP_DYNCO` + * :data:`gpu.GPU_DYNAMIC_LAMP_DYNIMAT` + * :data:`gpu.GPU_DYNAMIC_LAMP_DYNPERSMAT` + * :data:`gpu.GPU_DYNAMIC_LAMP_DYNENERGY` + * :data:`gpu.GPU_DYNAMIC_LAMP_DYNCOL` + * :data:`gpu.GPU_DYNAMIC_SAMPLER_2DSHADOW` + + Notes: + + * The uniforms :data:`gpu.GPU_DYNAMIC_LAMP_DYNVEC`, :data:`gpu.GPU_DYNAMIC_LAMP_DYNCO`, :data:`gpu.GPU_DYNAMIC_LAMP_DYNIMAT` and :data:`gpu.GPU_DYNAMIC_LAMP_DYNPERSMAT` + refer to the lamp object position and orientation, both of can be derived from the object world matrix: + + .. code-block:: python + + obmat = uniform["lamp"].matrix_world + + where obmat is the mat4_lamp_to_world_ matrix of the lamp as a 2 dimensional array, + the lamp world location location is in obmat[3]. + + * The uniform types :data:`gpu.GPU_DYNAMIC_LAMP_DYNENERGY` and :data:`gpu.GPU_DYNAMIC_LAMP_DYNCOL` refer to the lamp data bloc that you get from: .. code-block:: python - # full path to image file - uniform['image'].filepath - # image size as a 2-dimensional array of int - uniform['image'].size - - * ['texnumber'] : integer - Channel number to which the texture is bound when drawing the object. - Set for uniform types :data:`gpu.GPU_DYNAMIC_SAMPLER_2DBUFFER`, :data:`gpu.GPU_DYNAMIC_SAMPLER_2DIMAGE` and :data:`gpu.GPU_DYNAMIC_SAMPLER_2DSHADOW`. - - This is provided for information only: when reusing the shader outside blencer, - you are free to assign the textures to the channel of your choice and to pass - that number channel to the GPU in the uniform. - - * ['texpixels'] : byte array - texture data for uniform type :data:`gpu.GPU_DYNAMIC_SAMPLER_2DBUFFER`. Although - the corresponding uniform is a 2D sampler, the texture is always a 1D texture - of n x 1 pixel. The texture size n is provided in ['texsize'] element. - These texture are only used for computer generated texture (colorband, etc). - The texture data is provided so that you can make a real image out of it in the - exporter. - - * ['texsize'] : integer - horizontal size of texture for uniform type :data:`gpu.GPU_DYNAMIC_SAMPLER_2DBUFFER`. - The texture data is in ['texpixels']. - - * ['attributes'] : sequence - list of attributes used in vertex shader, can be empty. Blender doesn't use - standard attributes except for vertex position and normal. All other vertex - attributes must be passed using the generic glVertexAttrib functions. - The attribute data can be found in the derived mesh custom data using RNA. - Each element of the sequence is a dictionary containing the following elements: - - * ['varname'] : string - name of the uniform in the vertex shader. Always of the form 'att'. - - * ['datatype'] : integer - data type of vertex attribute, can be one of the following: - - * :data:`gpu.GPU_DATA_2F` : use glVertexAttrib2fv - * :data:`gpu.GPU_DATA_3F` : use glVertexAttrib3fv - * :data:`gpu.GPU_DATA_4F` : use glVertexAttrib4fv - * :data:`gpu.GPU_DATA_4UB` : use glVertexAttrib4ubv - - * ['number'] : integer - generic attribute number. This is provided for information only. Blender - doesn't use glBindAttribLocation to place generic attributes at specific location, - it lets the shader compiler place the attributes automatically and query the - placement with glGetAttribLocation. The result of this placement is returned in - this element. - - When using this shader in a render engine, you should either use - glBindAttribLocation to force the attribute at this location or use - glGetAttribLocation to get the placement chosen by the compiler of your GPU. - - * ['type'] : integer - type of the mesh custom data from which the vertex attribute is loaded. - See attribute-type_. - - * ['name'] : string or integer - custom data layer name, used for attribute type :data:`gpu.CD_MTFACE` and :data:`gpu.CD_MCOL`. - - Example: - - .. code-block:: python - - import gpu - # get GLSL shader of material Mat.001 in scene Scene.001 - scene = bpy.data.scenes['Scene.001'] - material = bpy.data.materials['Mat.001'] - shader = gpu.export_shader(scene,material) - # scan the uniform list and find the images used in the shader - for uniform in shader['uniforms']: - if uniform['type'] == gpu.GPU_DYNAMIC_SAMPLER_2DIMAGE: - print("uniform {0} is using image {1}".format(uniform['varname'], uniform['image'].filepath)) - # scan the attribute list and find the UV Map used in the shader - for attribute in shader['attributes']: - if attribute['type'] == gpu.CD_MTFACE: - print("attribute {0} is using UV Map {1}".format(attribute['varname'], attribute['name'])) + la = uniform["lamp"].data + + from which you get la.energy and la.color + + * Lamp duplication is not supported: if you have duplicated lamps in your scene + (i.e. lamp that are instantiated by dupligroup, etc), this element will only + give you a reference to the orignal lamp and you will not know which instance + of the lamp it is refering too. You can still handle that case in the exporter + by distributing the uniforms amongst the duplicated lamps. + + * ["image"] : :class:`bpy.types.Image` + Reference to the image databloc. Set for uniform type :data:`gpu.GPU_DYNAMIC_SAMPLER_2DIMAGE`. You can get the image data from: + + .. code-block:: python + + # full path to image file + uniform["image"].filepath + # image size as a 2-dimensional array of int + uniform["image"].size + + * ["texnumber"] : integer + Channel number to which the texture is bound when drawing the object. + Set for uniform types :data:`gpu.GPU_DYNAMIC_SAMPLER_2DBUFFER`, :data:`gpu.GPU_DYNAMIC_SAMPLER_2DIMAGE` and :data:`gpu.GPU_DYNAMIC_SAMPLER_2DSHADOW`. + + This is provided for information only: when reusing the shader outside blencer, + you are free to assign the textures to the channel of your choice and to pass + that number channel to the GPU in the uniform. + + * ["texpixels"] : byte array + texture data for uniform type :data:`gpu.GPU_DYNAMIC_SAMPLER_2DBUFFER`. Although + the corresponding uniform is a 2D sampler, the texture is always a 1D texture + of n x 1 pixel. The texture size n is provided in ["texsize"] element. + These texture are only used for computer generated texture (colorband, etc). + The texture data is provided so that you can make a real image out of it in the + exporter. + + * ["texsize"] : integer + horizontal size of texture for uniform type :data:`gpu.GPU_DYNAMIC_SAMPLER_2DBUFFER`. + The texture data is in ["texpixels"]. + + * ["attributes"] : sequence + list of attributes used in vertex shader, can be empty. Blender doesn't use + standard attributes except for vertex position and normal. All other vertex + attributes must be passed using the generic glVertexAttrib functions. + The attribute data can be found in the derived mesh custom data using RNA. + Each element of the sequence is a dictionary containing the following elements: + + * ["varname"] : string + name of the uniform in the vertex shader. Always of the form 'att'. + + * ["datatype"] : integer + data type of vertex attribute, can be one of the following: + + * :data:`gpu.GPU_DATA_2F` : use glVertexAttrib2fv + * :data:`gpu.GPU_DATA_3F` : use glVertexAttrib3fv + * :data:`gpu.GPU_DATA_4F` : use glVertexAttrib4fv + * :data:`gpu.GPU_DATA_4UB` : use glVertexAttrib4ubv + + * ["number"] : integer + generic attribute number. This is provided for information only. Blender + doesn't use glBindAttribLocation to place generic attributes at specific location, + it lets the shader compiler place the attributes automatically and query the + placement with glGetAttribLocation. The result of this placement is returned in + this element. + + When using this shader in a render engine, you should either use + glBindAttribLocation to force the attribute at this location or use + glGetAttribLocation to get the placement chosen by the compiler of your GPU. + + * ["type"] : integer + type of the mesh custom data from which the vertex attribute is loaded. + See attribute-type_. + + * ["name"] : string or integer + custom data layer name, used for attribute type :data:`gpu.CD_MTFACE` and :data:`gpu.CD_MCOL`. + + Example: + + .. code-block:: python + + import gpu + # get GLSL shader of material Mat.001 in scene Scene.001 + scene = bpy.data.scenes["Scene.001"] + material = bpy.data.materials["Mat.001"] + shader = gpu.export_shader(scene,material) + # scan the uniform list and find the images used in the shader + for uniform in shader["uniforms"]: + if uniform["type"] == gpu.GPU_DYNAMIC_SAMPLER_2DIMAGE: + print("uniform {0} is using image {1}".format(uniform["varname"], uniform["image"].filepath)) + # scan the attribute list and find the UV Map used in the shader + for attribute in shader["attributes"]: + if attribute["type"] == gpu.CD_MTFACE: + print("attribute {0} is using UV Map {1}".format(attribute["varname"], attribute["name"])) + -***** Notes -***** +===== .. _mat4_lamp_to_perspective: 1. Calculation of the *mat4_lamp_to_perspective* matrix for a spot lamp. - The following pseudo code shows how the *mat4_lamp_to_perspective* matrix is computed + The following pseudo code shows how the *mat4_lamp_to_perspective* matrix is computed in blender for uniforms of :data:`gpu.GPU_DYNAMIC_LAMP_DYNPERSMAT` type:: - #Get the lamp datablock with: - lamp=bpy.data.objects[uniform['lamp']].data + .. code-block:: python + + #Get the lamp datablock with: + lamp = bpy.data.objects[uniform["lamp"]].data - #Compute the projection matrix: - # You will need these lamp attributes: - # lamp.clipsta : near clip plane in world unit - # lamp.clipend : far clip plane in world unit - # lamp.spotsize : angle in degree of the spot light + # Compute the projection matrix: + # You will need these lamp attributes: + # lamp.clipsta : near clip plane in world unit + # lamp.clipend : far clip plane in world unit + # lamp.spotsize : angle in degree of the spot light - #The size of the projection plane is computed with the usual formula: - wsize = lamp.clista * tan(lamp.spotsize/2) + # The size of the projection plane is computed with the usual formula: + wsize = lamp.clista * tan(lamp.spotsize/2) - #And the projection matrix: - mat4_lamp_to_perspective = glFrustum(-wsize,wsize,-wsize,wsize,lamp.clista,lamp.clipend) + #And the projection matrix: + mat4_lamp_to_perspective = glFrustum(-wsize, wsize, -wsize, wsize, lamp.clista, lamp.clipend) 2. Creation of the shadow map for a spot lamp. The shadow map is the depth buffer of a render performed by placing the camera at the - spot light position. The size of the shadow map is given by the attribute lamp.bufsize : + spot light position. The size of the shadow map is given by the attribute lamp.bufsize : shadow map size in pixel, same size in both dimensions. diff -Nru blender-2.61/doc/python_api/rst/info_best_practice.rst blender-2.62/doc/python_api/rst/info_best_practice.rst --- blender-2.61/doc/python_api/rst/info_best_practice.rst 2011-12-13 19:54:55.000000000 +0000 +++ blender-2.62/doc/python_api/rst/info_best_practice.rst 2012-02-15 19:39:18.000000000 +0000 @@ -2,15 +2,15 @@ Best Practice ************* -When writing you're own scripts python is great for new developers to pick up and become productive, but you can also pick up odd habits or at least write scripts that are not easy for others to understand. +When writing your own scripts python is great for new developers to pick up and become productive, but you can also pick up odd habits or at least write scripts that are not easy for others to understand. -For you're own work this is of course fine, but if you want to collaborate with others or have you're work included with blender there are practices we encourage. +For your own work this is of course fine, but if you want to collaborate with others or have your work included with blender there are practices we encourage. Style Conventions ================= -For Blender 2.5 we have chosen to follow python suggested style guide to avoid mixing styles amongst our own scripts and make it easier to use python scripts from other projects. +For Blender/Python development we have chosen to follow python suggested style guide to avoid mixing styles amongst our own scripts and make it easier to use python scripts from other projects. Using our style guide for your own scripts makes it easier if you eventually want to contribute them to blender. @@ -83,7 +83,7 @@ Modifying Lists ^^^^^^^^^^^^^^^ -In python we can add and remove from a list, This is slower when the list length is modifier, especially at the start of the list, since all the data after the index of modification needs to be moved up or down 1 place. +In python we can add and remove from a list, This is slower when the list length is modified, especially at the start of the list, since all the data after the index of modification needs to be moved up or down 1 place. The most simple way to add onto the end of the list is to use ``my_list.append(list_item)`` or ``my_list.extend(some_list)`` and the fastest way to remove an item is ``my_list.pop()`` or ``del my_list[-1]``. @@ -244,7 +244,7 @@ Checking String Start/End ^^^^^^^^^^^^^^^^^^^^^^^^^ -If your checking the start of a string for a keyword, rather than... +If you're checking the start of a string for a keyword, rather than... >>> if line[0:5] == "vert ": ... @@ -279,8 +279,8 @@ In cases where you know you are checking for the same value which is referenced from multiple places, ``is`` is faster. -Time You're Code ----------------- +Time Your Code +-------------- While developing a script its good to time it to be aware of any changes in performance, this can be done simply. diff -Nru blender-2.61/doc/python_api/rst/info_overview.rst blender-2.62/doc/python_api/rst/info_overview.rst --- blender-2.61/doc/python_api/rst/info_overview.rst 2011-12-13 19:54:55.000000000 +0000 +++ blender-2.62/doc/python_api/rst/info_overview.rst 2012-02-15 19:39:18.000000000 +0000 @@ -27,7 +27,7 @@ When developing your own scripts it may help to understand how blender sets up its python environment. Many python scripts come bundled with blender and can be used as a reference because they use the same API that script authors write tools in. Typical usage for scripts include: user interface, import/export, scene manipulation, automation, defining your own toolset and customization. -On startup blender scans the ``scripts/startup/`` directory for python modules and imports them. The exact location of this directory depends on your installation. `See the directory layout docs `_ +On startup blender scans the ``scripts/startup/`` directory for python modules and imports them. The exact location of this directory depends on your installation. `See the directory layout docs `_ Script Loading @@ -71,7 +71,7 @@ The user preferences addon listing uses **bl_info** to display information about each addon. -`See Addons `_ for details on the **bl_info** dictionary. +`See Addons `_ for details on the **bl_info** dictionary. Integration through Classes diff -Nru blender-2.61/doc/python_api/rst/info_quickstart.rst blender-2.62/doc/python_api/rst/info_quickstart.rst --- blender-2.61/doc/python_api/rst/info_quickstart.rst 2011-12-13 19:54:55.000000000 +0000 +++ blender-2.62/doc/python_api/rst/info_quickstart.rst 2012-02-15 19:39:18.000000000 +0000 @@ -40,14 +40,14 @@ Before Starting =============== -This document isn't intended to fully cover each topic. Rather, its purpose is to familiarize you with Blender 2.5's new Python API. +This document isn't intended to fully cover each topic. Rather, its purpose is to familiarize you with Blender Python API. A quick list of helpful things to know before starting: * Blender uses Python 3.x; some 3rd party extensions are not available yet. -* The interactive console in Blender 2.5 has been improved; testing one-liners in the console is a good way to learn. +* The interactive console is great for testing one-liners, It also has autocompleation so you can inspect the api quickly. * Button tool tips show Python attributes and operator names. @@ -113,7 +113,7 @@ bpy.data.materials['MyMaterial'] -For testing what data to access it's useful to use the "Console", which is its own space type in Blender 2.5. This supports auto-complete, giving you a fast way to dig into different data in your file. +For testing what data to access it's useful to use the "Console", which is its own space type. This supports auto-complete, giving you a fast way to dig into different data in your file. Example of a data path that can be quickly found via the console: @@ -123,6 +123,29 @@ 1.0 +Data Creation/Removal +^^^^^^^^^^^^^^^^^^^^^ + +Those of you familiar with other python api's may be surprised that new datablocks in the bpy api can't be created by calling the class: + + >>> bpy.types.Mesh() + Traceback (most recent call last): + File "", line 1, in + TypeError: bpy_struct.__new__(type): expected a single argument + + +This is an intentional part of the API design. +The blender/python api can't create blender data that exists outside the main blender database (accessed through bpy.data), because this data is managed by blender (save/load/undo/append... etc). + +Data is added and removed via methods on the collections in bpy.data, eg: + + >>> mesh = bpy.data.meshes.new(name="MyMesh") + >>> print(mesh) + + + >>> bpy.data.meshes.remove(mesh) + + Custom Properties ^^^^^^^^^^^^^^^^^ @@ -262,8 +285,7 @@ #. Click on the button **Run Script**. -#. Move you're mouse into the 3D view, press spacebar for the operator search - menu, and type "Simple". +#. Move your mouse into the 3D view, press spacebar for the operator search menu, and type "Simple". #. Click on the "Simple Operator" item found in search. diff -Nru blender-2.61/doc/python_api/rst/info_tips_and_tricks.rst blender-2.62/doc/python_api/rst/info_tips_and_tricks.rst --- blender-2.61/doc/python_api/rst/info_tips_and_tricks.rst 2011-12-13 19:54:55.000000000 +0000 +++ blender-2.62/doc/python_api/rst/info_tips_and_tricks.rst 2012-02-15 19:39:18.000000000 +0000 @@ -16,7 +16,7 @@ There are 3 main uses for the terminal, these are: -* You can see the output of ``print()`` as you're script runs, which is useful to view debug info. +* You can see the output of ``print()`` as your script runs, which is useful to view debug info. * The error trace-back is printed in full to the terminal which won't always generate an error popup in blender's user interface (depending on how the script is executed). @@ -26,6 +26,27 @@ For Linux and OSX users this means starting the terminal first, then running blender from within it. On Windows the terminal can be enabled from the help menu. +Interface Tricks +================ + + +Access Operator Commands +------------------------ + +You may have noticed that the tooltip for menu items and buttons includes the ``bpy.ops``... command to run that button, a handy (hidden) feature is that you can press Ctrl+C over any menu item/button to copy this command into the clipboard. + + +Access Data Path +---------------- + +To find the path from an :class:`ID` datablock to its setting isn't always so simple since it may be nested away. To get this quickly you can right click on the setting and select select **Copy Data Path**, +if this can't be generated, only the property name is copied. + +.. note:: + + This uses the same method for creating the animation path used by :class:`FCurve.data_path` and :class:`DriverTarget.data_path` drivers. + + Show All Operators ================== @@ -135,15 +156,15 @@ * if the results can be displayed as text - print them or write them to a file. -This can take a little time to setup, but it can be well worth the effort to reduce the time it takes to test changes - you can even have blender running the script ever few seconds with a viewer updating the results, so no need to leave you're text editor to see changes. +This can take a little time to setup, but it can be well worth the effort to reduce the time it takes to test changes - you can even have blender running the script ever few seconds with a viewer updating the results, so no need to leave your text editor to see changes. Use External Tools ================== -When there are no readily available python modules to perform specific tasks it's worth keeping in mind you may be able to have python execute an external command on you're data and read the result back in. +When there are no readily available python modules to perform specific tasks it's worth keeping in mind you may be able to have python execute an external command on your data and read the result back in. -Using external programs adds an extra dependency and may limit who can use the script but to quickly setup you're own custom pipeline or writing one-off scripts this can be handy. +Using external programs adds an extra dependency and may limit who can use the script but to quickly setup your own custom pipeline or writing one-off scripts this can be handy. Examples include: @@ -157,7 +178,7 @@ Bundled Python & Extensions =========================== -The Blender releases distributed from blender.org include a complete python installation on all platforms, this has the disadvantage that any extensions you have installed in you're systems python wont be found by blender. +The Blender releases distributed from blender.org include a complete python installation on all platforms, this has the disadvantage that any extensions you have installed in your systems python wont be found by blender. There are 2 ways around this: @@ -166,8 +187,8 @@ * copy the extensions into blender's python sub-directory so blender can access them, you could also copy the entire python installation into blenders sub-directory, replacing the one blender comes with. This works as long as the python versions match and the paths are created in the same relative locations. Doing this has the advantage that you can redistribute this bundle to others with blender and/or the game player, including any extensions you rely on. -Drop Into a Python Interpreter in You're Script -=============================================== +Drop Into a Python Interpreter in Your Script +============================================= In the middle of a script you may want to inspect some variables, run some function and generally dig about to see whats going on. @@ -187,7 +208,7 @@ code.interact(local=namespace) -The next example is an equivalent single line version of the script above which is easier to paste into you're code: +The next example is an equivalent single line version of the script above which is easier to paste into your code: .. code-block:: python diff -Nru blender-2.61/doc/python_api/sphinx_doc_gen.py blender-2.62/doc/python_api/sphinx_doc_gen.py --- blender-2.61/doc/python_api/sphinx_doc_gen.py 2011-12-13 19:54:57.000000000 +0000 +++ blender-2.62/doc/python_api/sphinx_doc_gen.py 2012-02-15 19:39:19.000000000 +0000 @@ -1135,7 +1135,9 @@ fw("\n") fw("Welcome, this document is an API reference for Blender %s. built %s.\n" % (version_string, bpy.app.build_date)) fw("\n") - fw("`A PDF version of this document is also available `_\n" % version_string_pdf) + + # fw("`A PDF version of this document is also available `_\n" % version_string_pdf) + fw("`A compressed ZIP file of this site is available `_\n" % version_string_pdf) fw("\n") diff -Nru blender-2.61/doc/python_api/sphinx_doc_gen.sh blender-2.62/doc/python_api/sphinx_doc_gen.sh --- blender-2.61/doc/python_api/sphinx_doc_gen.sh 2011-12-13 19:54:57.000000000 +0000 +++ blender-2.62/doc/python_api/sphinx_doc_gen.sh 2012-02-15 19:39:19.000000000 +0000 @@ -11,7 +11,8 @@ DO_UPLOAD=true DO_EXE_BLENDER=true DO_OUT_HTML=true -DO_OUT_PDF=true +DO_OUT_HTML_ZIP=true +DO_OUT_PDF=false BLENDER="./blender.bin" @@ -61,6 +62,24 @@ # annoying bug in sphinx makes it very slow unless we do this. should report. cd $SPHINXBASE sphinx-build -n -b html sphinx-in sphinx-out + + # XXX, saves space on upload and zip, should move HTML outside + # and zip up there, for now this is OK + rm -rf sphinx-out/.doctrees + + # incase we have a zip already + rm -f blender_python_reference_$BLENDER_VERSION.zip + + # ------------------------------------------------------------------------ + # ZIP the HTML dir for upload + + if $DO_OUT_HTML_ZIP ; then + # lame, temp rename dir + mv sphinx-out blender_python_reference_$BLENDER_VERSION + zip -r -9 blender_python_reference_$BLENDER_VERSION.zip blender_python_reference_$BLENDER_VERSION + mv blender_python_reference_$BLENDER_VERSION sphinx-out + fi + cd - fi @@ -74,6 +93,7 @@ mv $SPHINXBASE/sphinx-out/contents.pdf $SPHINXBASE/sphinx-out/blender_python_reference_$BLENDER_VERSION.pdf fi + # ---------------------------------------------------------------------------- # Upload to blender servers, comment this section for testing @@ -89,8 +109,14 @@ # better redirect ssh $SSH_USER@emo.blender.org 'echo "Redirecting...Redirecting..." > '$SSH_UPLOAD'/250PythonDoc/index.html' - # rename so local PDF has matching name. - rsync --progress -avze "ssh -p 22" $SPHINXBASE/sphinx-out/blender_python_reference_$BLENDER_VERSION.pdf $SSH_HOST:$SSH_UPLOAD_FULL/blender_python_reference_$BLENDER_VERSION.pdf + if $DO_OUT_PDF ; then + # rename so local PDF has matching name. + rsync --progress -avze "ssh -p 22" $SPHINXBASE/sphinx-out/blender_python_reference_$BLENDER_VERSION.pdf $SSH_HOST:$SSH_UPLOAD_FULL/blender_python_reference_$BLENDER_VERSION.pdf + fi + + if $DO_OUT_HTML_ZIP ; then + rsync --progress -avze "ssh -p 22" $SPHINXBASE/blender_python_reference_$BLENDER_VERSION.zip $SSH_HOST:$SSH_UPLOAD_FULL/blender_python_reference_$BLENDER_VERSION.zip + fi fi diff -Nru blender-2.61/extern/binreloc/CMakeLists.txt blender-2.62/extern/binreloc/CMakeLists.txt --- blender-2.61/extern/binreloc/CMakeLists.txt 2011-12-13 19:57:05.000000000 +0000 +++ blender-2.62/extern/binreloc/CMakeLists.txt 2012-02-15 19:41:43.000000000 +0000 @@ -12,7 +12,7 @@ # # 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # The Original Code is Copyright (C) 2008 by The Blender Foundation # All rights reserved. diff -Nru blender-2.61/extern/bullet2/CMakeLists.txt blender-2.62/extern/bullet2/CMakeLists.txt --- blender-2.61/extern/bullet2/CMakeLists.txt 2011-12-13 19:56:02.000000000 +0000 +++ blender-2.62/extern/bullet2/CMakeLists.txt 2012-02-15 19:40:45.000000000 +0000 @@ -12,7 +12,7 @@ # # 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # The Original Code is Copyright (C) 2006, Blender Foundation # All rights reserved. diff -Nru blender-2.61/extern/bullet2/src/BulletSoftBody/btSoftBody.cpp blender-2.62/extern/bullet2/src/BulletSoftBody/btSoftBody.cpp --- blender-2.61/extern/bullet2/src/BulletSoftBody/btSoftBody.cpp 2011-12-13 19:55:31.000000000 +0000 +++ blender-2.62/extern/bullet2/src/BulletSoftBody/btSoftBody.cpp 2012-02-15 19:40:09.000000000 +0000 @@ -2780,21 +2780,23 @@ { const RContact& c = psb->m_rcontacts[i]; const sCti& cti = c.m_cti; - btRigidBody* tmpRigid = btRigidBody::upcast(cti.m_colObj); - const btVector3 va = tmpRigid ? tmpRigid->getVelocityInLocalPoint(c.m_c1)*dt : btVector3(0,0,0); - const btVector3 vb = c.m_node->m_x-c.m_node->m_q; - const btVector3 vr = vb-va; - const btScalar dn = btDot(vr, cti.m_normal); - if(dn<=SIMD_EPSILON) - { - const btScalar dp = btMin( (btDot(c.m_node->m_x, cti.m_normal) + cti.m_offset), mrg ); - const btVector3 fv = vr - (cti.m_normal * dn); - // c0 is the impulse matrix, c3 is 1 - the friction coefficient or 0, c4 is the contact hardness coefficient - const btVector3 impulse = c.m_c0 * ( (vr - (fv * c.m_c3) + (cti.m_normal * (dp * c.m_c4))) * kst ); - c.m_node->m_x -= impulse * c.m_c2; - if (tmpRigid) - tmpRigid->applyImpulse(impulse,c.m_c1); + if (cti.m_colObj->hasContactResponse()) { + btRigidBody* tmpRigid = btRigidBody::upcast(cti.m_colObj); + const btVector3 va = tmpRigid ? tmpRigid->getVelocityInLocalPoint(c.m_c1)*dt : btVector3(0,0,0); + const btVector3 vb = c.m_node->m_x-c.m_node->m_q; + const btVector3 vr = vb-va; + const btScalar dn = btDot(vr, cti.m_normal); + if(dn<=SIMD_EPSILON) + { + const btScalar dp = btMin( (btDot(c.m_node->m_x, cti.m_normal) + cti.m_offset), mrg ); + const btVector3 fv = vr - (cti.m_normal * dn); + // c0 is the impulse matrix, c3 is 1 - the friction coefficient or 0, c4 is the contact hardness coefficient + const btVector3 impulse = c.m_c0 * ( (vr - (fv * c.m_c3) + (cti.m_normal * (dp * c.m_c4))) * kst ); + c.m_node->m_x -= impulse * c.m_c2; + if (tmpRigid) + tmpRigid->applyImpulse(impulse,c.m_c1); + } } } } diff -Nru blender-2.61/extern/carve/bundle.sh blender-2.62/extern/carve/bundle.sh --- blender-2.61/extern/carve/bundle.sh 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/bundle.sh 2012-02-15 19:39:33.000000000 +0000 @@ -0,0 +1,124 @@ +#!/bin/sh + +if [ -d ./.svn ]; then + echo "This script is supposed to work only when using git-svn" + exit 1 +fi + +tmp=`mktemp -d` + +hg clone https://code.google.com/p/carve/ $tmp/carve + +for p in `cat ./patches/series`; do + echo "Applying patch $p..." + cat ./patches/$p | patch -d $tmp/carve -p1 +done + +rm -rf include +rm -rf lib + +cat "files.txt" | while read f; do + mkdir -p `dirname $f` + cp $tmp/carve/$f $f +done + +rm -rf $tmp + +sources=`find ./lib -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | sed -r 's/^\.\//\t/'` +headers=`find ./lib -type f -iname '*.h' -or -iname '*.hpp' | sed -r 's/^\.\//\t/'` +includes=`find ./include -type f -iname '*.h' -or -iname '*.hpp' | sed -r 's/^\.\//\t/'` + +mkdir -p include/carve/external/boost +cp patches/files/random.hpp include/carve/external/boost/random.hpp +cp patches/files/config.h include/carve/config.h + +cat > CMakeLists.txt << EOF +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Jacques Beaurai, Erwin Coumans +# +# ***** END GPL LICENSE BLOCK ***** + +# NOTE: This file is automatically generated by bundle.sh script +# If you're doing changes in this file, please update template +# in that script too + +set(INC + include +) + +set(INC_SYS +) + +set(SRC +${sources} + +${headers} + +${includes} +) + +if(WITH_BOOST) + if(NOT MSVC) + # Boost is setting as preferred collections library in the Carve code when using MSVC compiler + add_definitions( + -DHAVE_BOOST_UNORDERED_COLLECTIONS + ) + endif() + + add_definitions( + -DCARVE_SYSTEM_BOOST + ) + + list(APPEND INC + \${BOOST_INCLUDE_DIR} + ) +endif() + +blender_add_lib(extern_carve "\${SRC}" "\${INC}" "\${INC_SYS}") +EOF + +cat > SConscript << EOF +#!/usr/bin/python + +# NOTE: This file is automatically generated by bundle.sh script +# If you're doing changes in this file, please update template +# in that script too + +Import ('env') + +sources = env.Glob('lib/*.cpp') + +defs = [] +incs = ['include'] + +if env['WITH_BF_BOOST']: + if env['OURPLATFORM'] not in ('win32-vc', 'win64-vc'): + # Boost is setting as preferred collections library in the Carve code when using MSVC compiler + if env['OURPLATFORM'] != 'win32-mingw': + defs.append('HAVE_BOOST_UNORDERED_COLLECTIONS') + + defs.append('CARVE_SYSTEM_BOOST') + incs.append(env['BF_BOOST_INC']) + +env.BlenderLib ('extern_carve', Split(sources), incs, defs, libtype=['extern'], priority=[40] ) +EOF diff -Nru blender-2.61/extern/carve/CMakeLists.txt blender-2.62/extern/carve/CMakeLists.txt --- blender-2.61/extern/carve/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/CMakeLists.txt 2012-02-15 19:39:33.000000000 +0000 @@ -0,0 +1,166 @@ +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the 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. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Jacques Beaurai, Erwin Coumans +# +# ***** END GPL LICENSE BLOCK ***** + +# NOTE: This file is automatically generated by bundle.sh script +# If you're doing changes in this file, please update template +# in that script too + +set(INC + include +) + +set(INC_SYS +) + +set(SRC + lib/carve.cpp + lib/mesh.cpp + lib/intersect_group.cpp + lib/intersect_classify_edge.cpp + lib/intersect_classify_group.cpp + lib/polyhedron.cpp + lib/geom3d.cpp + lib/polyline.cpp + lib/csg_collector.cpp + lib/triangulator.cpp + lib/intersect_face_division.cpp + lib/intersect_half_classify_group.cpp + lib/edge.cpp + lib/math.cpp + lib/geom2d.cpp + lib/tag.cpp + lib/intersection.cpp + lib/convex_hull.cpp + lib/csg.cpp + lib/intersect.cpp + lib/face.cpp + lib/pointset.cpp + lib/timing.cpp + lib/octree.cpp + lib/aabb.cpp + lib/intersect_debug.cpp + + lib/intersect_classify_common.hpp + lib/csg_data.hpp + lib/csg_collector.hpp + lib/intersect_common.hpp + lib/intersect_classify_common_impl.hpp + lib/csg_detail.hpp + lib/intersect_debug.hpp + + include/carve/polyhedron_decl.hpp + include/carve/geom2d.hpp + include/carve/exact.hpp + include/carve/triangulator_impl.hpp + include/carve/collection.hpp + include/carve/pointset.hpp + include/carve/djset.hpp + include/carve/kd_node.hpp + include/carve/polyline.hpp + include/carve/polyline_iter.hpp + include/carve/geom3d.hpp + include/carve/edge_decl.hpp + include/carve/face_decl.hpp + include/carve/aabb_impl.hpp + include/carve/colour.hpp + include/carve/pointset_iter.hpp + include/carve/polyline_decl.hpp + include/carve/rescale.hpp + include/carve/mesh_impl.hpp + include/carve/classification.hpp + include/carve/util.hpp + include/carve/triangulator.hpp + include/carve/polyhedron_base.hpp + include/carve/rtree.hpp + include/carve/math.hpp + include/carve/math_constants.hpp + include/carve/octree_decl.hpp + include/carve/input.hpp + include/carve/mesh_ops.hpp + include/carve/debug_hooks.hpp + include/carve/mesh_simplify.hpp + include/carve/interpolator.hpp + include/carve/poly_decl.hpp + include/carve/csg.hpp + include/carve/mesh.hpp + include/carve/carve.hpp + include/carve/gnu_cxx.h + include/carve/polyhedron_impl.hpp + include/carve/poly_impl.hpp + include/carve/aabb.hpp + include/carve/convex_hull.hpp + include/carve/vertex_decl.hpp + include/carve/win32.h + include/carve/edge_impl.hpp + include/carve/tag.hpp + include/carve/tree.hpp + include/carve/heap.hpp + include/carve/matrix.hpp + include/carve/poly.hpp + include/carve/vector.hpp + include/carve/intersection.hpp + include/carve/faceloop.hpp + include/carve/geom_impl.hpp + include/carve/octree_impl.hpp + include/carve/spacetree.hpp + include/carve/collection/unordered/std_impl.hpp + include/carve/collection/unordered/tr1_impl.hpp + include/carve/collection/unordered/libstdcpp_impl.hpp + include/carve/collection/unordered/boost_impl.hpp + include/carve/collection/unordered/vcpp_impl.hpp + include/carve/collection/unordered/fallback_impl.hpp + include/carve/collection/unordered.hpp + include/carve/face_impl.hpp + include/carve/pointset_impl.hpp + include/carve/cbrt.h + include/carve/vcpp_config.h + include/carve/geom.hpp + include/carve/vertex_impl.hpp + include/carve/polyline_impl.hpp + include/carve/pointset_decl.hpp + include/carve/timing.hpp + include/carve/csg_triangulator.hpp + include/carve/iobj.hpp + include/carve/collection_types.hpp +) + +if(WITH_BOOST) + if(NOT MSVC) + # Boost is setting as preferred collections library in the Carve code when using MSVC compiler + add_definitions( + -DHAVE_BOOST_UNORDERED_COLLECTIONS + ) + endif() + + add_definitions( + -DCARVE_SYSTEM_BOOST + ) + + list(APPEND INC + ${BOOST_INCLUDE_DIR} + ) +endif() + +blender_add_lib(extern_carve "${SRC}" "${INC}" "${INC_SYS}") diff -Nru blender-2.61/extern/carve/files.txt blender-2.62/extern/carve/files.txt --- blender-2.61/extern/carve/files.txt 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/files.txt 2012-02-15 19:39:33.000000000 +0000 @@ -0,0 +1,107 @@ +include/carve/polyhedron_decl.hpp +include/carve/geom2d.hpp +include/carve/exact.hpp +include/carve/triangulator_impl.hpp +include/carve/collection.hpp +include/carve/pointset.hpp +include/carve/djset.hpp +include/carve/kd_node.hpp +include/carve/polyline.hpp +include/carve/polyline_iter.hpp +include/carve/geom3d.hpp +include/carve/edge_decl.hpp +include/carve/face_decl.hpp +include/carve/aabb_impl.hpp +include/carve/colour.hpp +include/carve/pointset_iter.hpp +include/carve/polyline_decl.hpp +include/carve/rescale.hpp +include/carve/mesh_impl.hpp +include/carve/classification.hpp +include/carve/util.hpp +include/carve/triangulator.hpp +include/carve/polyhedron_base.hpp +include/carve/rtree.hpp +include/carve/math.hpp +include/carve/math_constants.hpp +include/carve/octree_decl.hpp +include/carve/input.hpp +include/carve/mesh_ops.hpp +include/carve/debug_hooks.hpp +include/carve/mesh_simplify.hpp +include/carve/interpolator.hpp +include/carve/poly_decl.hpp +include/carve/csg.hpp +include/carve/mesh.hpp +include/carve/carve.hpp +include/carve/gnu_cxx.h +include/carve/polyhedron_impl.hpp +include/carve/poly_impl.hpp +include/carve/aabb.hpp +include/carve/convex_hull.hpp +include/carve/vertex_decl.hpp +include/carve/win32.h +include/carve/edge_impl.hpp +include/carve/tag.hpp +include/carve/tree.hpp +include/carve/heap.hpp +include/carve/matrix.hpp +include/carve/poly.hpp +include/carve/vector.hpp +include/carve/intersection.hpp +include/carve/faceloop.hpp +include/carve/geom_impl.hpp +include/carve/octree_impl.hpp +include/carve/spacetree.hpp +include/carve/collection/unordered/std_impl.hpp +include/carve/collection/unordered/tr1_impl.hpp +include/carve/collection/unordered/libstdcpp_impl.hpp +include/carve/collection/unordered/boost_impl.hpp +include/carve/collection/unordered/vcpp_impl.hpp +include/carve/collection/unordered/fallback_impl.hpp +include/carve/collection/unordered.hpp +include/carve/face_impl.hpp +include/carve/pointset_impl.hpp +include/carve/cbrt.h +include/carve/vcpp_config.h +include/carve/geom.hpp +include/carve/vertex_impl.hpp +include/carve/polyline_impl.hpp +include/carve/pointset_decl.hpp +include/carve/timing.hpp +include/carve/csg_triangulator.hpp +include/carve/iobj.hpp +include/carve/collection_types.hpp +lib/carve.cpp +lib/mesh.cpp +lib/intersect_group.cpp +lib/intersect_classify_common.hpp +lib/intersect_classify_edge.cpp +lib/intersect_classify_group.cpp +lib/csg_data.hpp +lib/polyhedron.cpp +lib/csg_collector.hpp +lib/geom3d.cpp +lib/polyline.cpp +lib/csg_collector.cpp +lib/triangulator.cpp +lib/intersect_face_division.cpp +lib/intersect_half_classify_group.cpp +lib/edge.cpp +lib/math.cpp +lib/geom2d.cpp +lib/tag.cpp +lib/intersection.cpp +lib/convex_hull.cpp +lib/intersect_common.hpp +lib/intersect_classify_common_impl.hpp +lib/csg.cpp +lib/intersect.cpp +lib/csg_detail.hpp +lib/face.cpp +lib/pointset.cpp +lib/timing.cpp +lib/octree.cpp +lib/aabb.cpp +lib/intersect_debug.hpp +lib/intersect_debug.cpp diff -Nru blender-2.61/extern/carve/include/carve/aabb.hpp blender-2.62/extern/carve/include/carve/aabb.hpp --- blender-2.61/extern/carve/include/carve/aabb.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/aabb.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,150 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + +#pragma once + +#include + +#include + +#include + +namespace carve { + namespace geom { + + + + // n-dimensional AABB + template + struct aabb { + typedef vector vector_t; + typedef aabb aabb_t; + + vector_t pos; // the centre of the AABB + vector_t extent; // the extent of the AABB - the vector from the centre to the maximal vertex. + + void empty(); + + bool isEmpty() const; + + void fit(const vector_t &v1); + void fit(const vector_t &v1, const vector_t &v2); + void fit(const vector_t &v1, const vector_t &v2, const vector_t &v3); + + template + void _fit(iter_t begin, iter_t end, value_type); + + template + void _fit(iter_t begin, iter_t end, vector_t); + + template + void _fit(iter_t begin, iter_t end, aabb_t); + + template + void fit(iter_t begin, iter_t end); + + template + void fit(iter_t begin, iter_t end, adapt_t adapt); + + void unionAABB(const aabb &a); + + void expand(double pad); + + bool completelyContains(const aabb &other) const; + + bool containsPoint(const vector_t &v) const; + + bool intersectsLineSegment(const vector_t &v1, const vector_t &v2) const; + + double axisSeparation(const aabb &other, unsigned axis) const; + + double maxAxisSeparation(const aabb &other) const; + + bool intersects(const aabb &other) const; + bool intersects(const sphere &s) const; + bool intersects(const plane &plane) const; + bool intersects(const ray &ray) const; + bool intersects(tri tri) const; + bool intersects(const linesegment &ls) const; + + std::pair rangeInDirection(const carve::geom::vector &v) const; + + vector_t min() const; + vector_t mid() const; + vector_t max() const; + + double min(unsigned dim) const; + double mid(unsigned dim) const; + double max(unsigned dim) const; + + double volume() const; + + int compareAxis(const axis_pos &ap) const; + + void constrainMax(const axis_pos &ap); + void constrainMin(const axis_pos &ap); + + aabb getAABB() const; + + aabb(const vector_t &_pos = vector_t::ZERO(), + const vector_t &_extent = vector_t::ZERO()); + + template + aabb(iter_t begin, iter_t end, adapt_t adapt); + + template + aabb(iter_t begin, iter_t end); + + aabb(const aabb &a, const aabb &b); + }; + + template + bool operator==(const aabb &a, const aabb &b); + + template + bool operator!=(const aabb &a, const aabb &b); + + template + std::ostream &operator<<(std::ostream &o, const aabb &a); + + + + template + struct get_aabb { + aabb operator()(const obj_t &obj) const { + return obj.getAABB(); + } + }; + + template + struct get_aabb { + aabb operator()(const obj_t *obj) const { + return obj->getAABB(); + } + }; + + + + } +} + +namespace carve { + namespace geom3d { + typedef carve::geom::aabb<3> AABB; + } +} + +#include diff -Nru blender-2.61/extern/carve/include/carve/aabb_impl.hpp blender-2.62/extern/carve/include/carve/aabb_impl.hpp --- blender-2.61/extern/carve/include/carve/aabb_impl.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/aabb_impl.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,423 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + +#pragma once + +#include + +#include +#include + +#include + +#include + +namespace carve { + namespace geom { + + template + void aabb::empty() { + pos.setZero(); + extent.setZero(); + } + + template + bool aabb::isEmpty() const { + return extent.exactlyZero(); + } + + template + template + void aabb::_fit(iter_t begin, iter_t end, value_type) { + if (begin == end) { + empty(); + return; + } + + vector_t min, max; + aabb a = get_aabb()(*begin); ++begin; + min = a.min(); + max = a.max(); + while (begin != end) { + aabb a = get_aabb()(*begin); ++begin; + assign_op(min, min, a.min(), carve::util::min_functor()); + assign_op(max, max, a.max(), carve::util::max_functor()); + } + + pos = (min + max) / 2.0; + assign_op(extent, max - pos, pos - min, carve::util::max_functor()); + } + + template + template + void aabb::_fit(iter_t begin, iter_t end, vector_t) { + if (begin == end) { + empty(); + return; + } + + vector_t min, max; + bounds(begin, end, min, max); + pos = (min + max) / 2.0; + assign_op(extent, max - pos, pos - min, carve::util::max_functor()); + } + + template + template + void aabb::_fit(iter_t begin, iter_t end, aabb_t) { + if (begin == end) { + empty(); + return; + } + + vector_t min, max; + aabb a = *begin++; + min = a.min(); + max = a.max(); + while (begin != end) { + aabb a = *begin; ++begin; + assign_op(min, min, a.min(), carve::util::min_functor()); + assign_op(max, max, a.max(), carve::util::max_functor()); + } + + pos = (min + max) / 2.0; + assign_op(extent, max - pos, pos - min, carve::util::max_functor()); + } + + template + void aabb::fit(const vector_t &v1) { + pos = v1; + extent.setZero(); + } + + template + void aabb::fit(const vector_t &v1, const vector_t &v2) { + vector_t min, max; + assign_op(min, v1, v2, carve::util::min_functor()); + assign_op(max, v1, v2, carve::util::max_functor()); + + pos = (min + max) / 2.0; + assign_op(extent, max - pos, pos - min, carve::util::max_functor()); + } + + template + void aabb::fit(const vector_t &v1, const vector_t &v2, const vector_t &v3) { + vector_t min, max; + min = max = v1; + + assign_op(min, min, v2, carve::util::min_functor()); + assign_op(max, max, v2, carve::util::max_functor()); + assign_op(min, min, v3, carve::util::min_functor()); + assign_op(max, max, v3, carve::util::max_functor()); + + pos = (min + max) / 2.0; + assign_op(extent, max - pos, pos - min, carve::util::max_functor()); + } + + template + template + void aabb::fit(iter_t begin, iter_t end, adapt_t adapt) { + vector_t min, max; + + bounds(begin, end, adapt, min, max); + pos = (min + max) / 2.0; + assign_op(extent, max - pos, pos - min, carve::util::max_functor()); + } + + template + template + void aabb::fit(iter_t begin, iter_t end) { + _fit(begin, end, typename std::iterator_traits::value_type()); + } + + template + void aabb::expand(double pad) { + extent += pad; + } + + template + void aabb::unionAABB(const aabb &a) { + vector_t vmin, vmax; + + assign_op(vmin, min(), a.min(), carve::util::min_functor()); + assign_op(vmax, max(), a.max(), carve::util::max_functor()); + pos = (vmin + vmax) / 2.0; + assign_op(extent, vmax - pos, pos - vmin, carve::util::max_functor()); + } + + template + bool aabb::completelyContains(const aabb &other) const { + for (unsigned i = 0; i < ndim; ++i) { + if (fabs(other.pos.v[i] - pos.v[i]) + other.extent.v[i] > extent.v[i]) return false; + } + return true; + } + + template + bool aabb::containsPoint(const vector_t &v) const { + for (unsigned i = 0; i < ndim; ++i) { + if (fabs(v.v[i] - pos.v[i]) > extent.v[i]) return false; + } + return true; + } + + template + double aabb::axisSeparation(const aabb &other, unsigned axis) const { + return fabs(other.pos.v[axis] - pos.v[axis]) - extent.v[axis] - other.extent.v[axis]; + } + + template + double aabb::maxAxisSeparation(const aabb &other) const { + double m = axisSeparation(other, 0); + for (unsigned i = 1; i < ndim; ++i) { + m = std::max(m, axisSeparation(other, i)); + } + return m; + } + + template + bool aabb::intersects(const aabb &other) const { + return maxAxisSeparation(other) <= 0.0; + } + + template + bool aabb::intersects(const sphere &s) const { + double r = 0.0; + for (unsigned i = 0; i < ndim; ++i) { + double t = fabs(s.C[i] - pos[i]) - extent[i]; if (t > 0.0) r += t*t; + } + return r <= s.r*s.r; + } + + template + bool aabb::intersects(const plane &plane) const { + double d1 = fabs(distance(plane, pos)); + double d2 = dot(abs(plane.N), extent); + return d1 <= d2; + } + + template + bool aabb::intersects(const linesegment &ls) const { + return intersectsLineSegment(ls.v1, ls.v2); + } + + template + std::pair aabb::rangeInDirection(const carve::geom::vector &v) const { + double d1 = dot(v, pos); + double d2 = dot(abs(v), extent); + + return std::make_pair(d1 - d2, d1 + d2); + } + + template + typename aabb::vector_t aabb::min() const { return pos - extent; } + + template + typename aabb::vector_t aabb::mid() const { return pos; } + + template + typename aabb::vector_t aabb::max() const { return pos + extent; } + + template + double aabb::min(unsigned dim) const { return pos.v[dim] - extent.v[dim]; } + + template + double aabb::mid(unsigned dim) const { return pos.v[dim]; } + + template + double aabb::max(unsigned dim) const { return pos.v[dim] + extent.v[dim]; } + + template + double aabb::volume() const { + double v = 1.0; + for (size_t dim = 0; dim < ndim; ++dim) { v *= 2.0 * extent.v[dim]; } + return v; + } + + template + int aabb::compareAxis(const axis_pos &ap) const { + double p = ap.pos - pos[ap.axis]; + if (p > extent[ap.axis]) return -1; + if (p < -extent[ap.axis]) return +1; + return 0; + } + + template + void aabb::constrainMax(const axis_pos &ap) { + if (pos[ap.axis] + extent[ap.axis] > ap.pos) { + double min = std::min(ap.pos, pos[ap.axis] - extent[ap.axis]); + pos[ap.axis] = (min + ap.pos) / 2.0; + extent[ap.axis] = ap.pos - pos[ap.axis]; + } + } + + template + void aabb::constrainMin(const axis_pos &ap) { + if (pos[ap.axis] - extent[ap.axis] < ap.pos) { + double max = std::max(ap.pos, pos[ap.axis] + extent[ap.axis]); + pos[ap.axis] = (ap.pos + max) / 2.0; + extent[ap.axis] = pos[ap.axis] - ap.pos; + } + } + + template + aabb aabb::getAABB() const { + return *this; + } + + template + aabb::aabb(const vector_t &_pos, + const vector_t &_extent) : pos(_pos), extent(_extent) { + } + + template + template + aabb::aabb(iter_t begin, iter_t end, adapt_t adapt) { + fit(begin, end, adapt); + } + + template + template + aabb::aabb(iter_t begin, iter_t end) { + fit(begin, end); + } + + template + aabb::aabb(const aabb &a, const aabb &b) { + fit(a, b); + } + + template + bool operator==(const aabb &a, const aabb &b) { + return a.pos == b.pos && a.extent == b.extent; + } + + template + bool operator!=(const aabb &a, const aabb &b) { + return a.pos != b.pos || a.extent != b.extent; + } + + template + std::ostream &operator<<(std::ostream &o, const aabb &a) { + o << (a.pos - a.extent) << "--" << (a.pos + a.extent); + return o; + } + + template<> + inline bool aabb<3>::intersects(const ray<3> &ray) const { + vector<3> t = pos - ray.v; + double r; + + //l.cross(x-axis)? + r = extent.y * fabs(ray.D.z) + extent.z * fabs(ray.D.y); + if (fabs(t.y * ray.D.z - t.z * ray.D.y) > r) return false; + + //ray.D.cross(y-axis)? + r = extent.x * fabs(ray.D.z) + extent.z * fabs(ray.D.x); + if (fabs(t.z * ray.D.x - t.x * ray.D.z) > r) return false; + + //ray.D.cross(z-axis)? + r = extent.x*fabs(ray.D.y) + extent.y*fabs(ray.D.x); + if (fabs(t.x * ray.D.y - t.y * ray.D.x) > r) return false; + + return true; + } + + template<> + inline bool aabb<3>::intersectsLineSegment(const vector<3> &v1, const vector<3> &v2) const { + vector<3> half_length = 0.5 * (v2 - v1); + vector<3> t = pos - half_length - v1; + double r; + + //do any of the principal axes form a separating axis? + if(fabs(t.x) > extent.x + fabs(half_length.x)) return false; + if(fabs(t.y) > extent.y + fabs(half_length.y)) return false; + if(fabs(t.z) > extent.z + fabs(half_length.z)) return false; + + // NOTE: Since the separating axis is perpendicular to the line in + // these last four cases, the line does not contribute to the + // projection. + + //line.cross(x-axis)? + r = extent.y * fabs(half_length.z) + extent.z * fabs(half_length.y); + if (fabs(t.y * half_length.z - t.z * half_length.y) > r) return false; + + //half_length.cross(y-axis)? + r = extent.x * fabs(half_length.z) + extent.z * fabs(half_length.x); + if (fabs(t.z * half_length.x - t.x * half_length.z) > r) return false; + + //half_length.cross(z-axis)? + r = extent.x*fabs(half_length.y) + extent.y*fabs(half_length.x); + if (fabs(t.x * half_length.y - t.y * half_length.x) > r) return false; + + return true; + } + + template + static inline bool intersectsTriangle_axisTest_3(const aabb<3> &aabb, const tri<3> &tri) { + const int d = (c+1) % 3, e = (c+2) % 3; + const vector<3> a = cross(VECTOR(Ax, Ay, Az), tri.v[d] - tri.v[c]); + double p1 = dot(a, tri.v[c]), p2 = dot(a, tri.v[e]); + if (p1 > p2) std::swap(p1, p2); + const double r = dot(abs(a), aabb.extent); + return !(p1 > r || p2 < -r); + } + + template + static inline bool intersectsTriangle_axisTest_2(const aabb<3> &aabb, const tri<3> &tri) { + double vmin = std::min(std::min(tri.v[0][c], tri.v[1][c]), tri.v[2][c]), + vmax = std::max(std::max(tri.v[0][c], tri.v[1][c]), tri.v[2][c]); + return !(vmin > aabb.extent[c] || vmax < -aabb.extent[c]); + } + + static inline bool intersectsTriangle_axisTest_1(const aabb<3> &aabb, const tri<3> &tri) { + vector<3> n = cross(tri.v[1] - tri.v[0], tri.v[2] - tri.v[0]); + double d1 = fabs(dot(n, tri.v[0])); + double d2 = dot(abs(n), aabb.extent); + return d1 <= d2; + } + + template<> + inline bool aabb<3>::intersects(tri<3> tri) const { + tri.v[0] -= pos; + tri.v[1] -= pos; + tri.v[2] -= pos; + + if (!intersectsTriangle_axisTest_2<0>(*this, tri)) return false; + if (!intersectsTriangle_axisTest_2<1>(*this, tri)) return false; + if (!intersectsTriangle_axisTest_2<2>(*this, tri)) return false; + + if (!intersectsTriangle_axisTest_3<1,0,0,0>(*this, tri)) return false; + if (!intersectsTriangle_axisTest_3<1,0,0,1>(*this, tri)) return false; + if (!intersectsTriangle_axisTest_3<1,0,0,2>(*this, tri)) return false; + + if (!intersectsTriangle_axisTest_3<0,1,0,0>(*this, tri)) return false; + if (!intersectsTriangle_axisTest_3<0,1,0,1>(*this, tri)) return false; + if (!intersectsTriangle_axisTest_3<0,1,0,2>(*this, tri)) return false; + + if (!intersectsTriangle_axisTest_3<0,0,1,0>(*this, tri)) return false; + if (!intersectsTriangle_axisTest_3<0,0,1,1>(*this, tri)) return false; + if (!intersectsTriangle_axisTest_3<0,0,1,2>(*this, tri)) return false; + + if (!intersectsTriangle_axisTest_1(*this, tri)) return false; + + return true; + } + + + + } +} diff -Nru blender-2.61/extern/carve/include/carve/carve.hpp blender-2.62/extern/carve/include/carve/carve.hpp --- blender-2.61/extern/carve/include/carve/carve.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/carve.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,238 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + +#pragma once + +#if defined(CMAKE_BUILD) +# include +#elif defined(XCODE_BUILD) +# include +#elif defined(_MSC_VER) +# include +#else +# include +#endif + +#if defined(WIN32) +# include +#elif defined(__GNUC__) +# include +#endif + +#if defined(CARVE_SYSTEM_BOOST) +# define BOOST_INCLUDE(x) +#else +# define BOOST_INCLUDE(x) +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include + +#define STR(x) #x +#define XSTR(x) STR(x) + +/** + * \brief Top level Carve namespace. + */ +namespace carve { + static struct noinit_t {} NOINIT; + + inline std::string fmtstring(const char *fmt, ...); + + /** + * \brief Base class for all Carve exceptions. + */ + struct exception { + private: + mutable std::string err; + mutable std::ostringstream accum; + + public: + exception(const std::string &e) : err(e), accum() { } + exception() : err(), accum() { } + exception(const exception &e) : err(e.str()), accum() { } + exception &operator=(const exception &e) { + if (this != &e) { + err = e.str(); + accum.str(""); + } + return *this; + } + + const std::string &str() const { + if (accum.str().size() > 0) { + err += accum.str(); + accum.str(""); + } + return err; + } + + template + exception &operator<<(const T &t) { + accum << t; + return *this; + } + }; + + template::value_type > > + struct index_sort { + iter_t base; + order_t order; + index_sort(const iter_t &_base) : base(_base), order() { } + index_sort(const iter_t &_base, const order_t &_order) : base(_base), order(_order) { } + template + bool operator()(const U &a, const U &b) { + return order(*(base + a), *(base + b)); + } + }; + + template + index_sort make_index_sort(const iter_t &base, const order_t &order) { + return index_sort(base, order); + } + + template + index_sort make_index_sort(const iter_t &base) { + return index_sort(base); + } + + + enum RayIntersectionClass { + RR_DEGENERATE = -2, + RR_PARALLEL = -1, + RR_NO_INTERSECTION = 0, + RR_INTERSECTION = 1 + }; + + enum LineIntersectionClass { + COLINEAR = -1, + NO_INTERSECTION = 0, + INTERSECTION_LL = 1, + INTERSECTION_PL = 2, + INTERSECTION_LP = 3, + INTERSECTION_PP = 4 + }; + + enum PointClass { + POINT_UNK = -2, + POINT_OUT = -1, + POINT_ON = 0, + POINT_IN = 1, + POINT_VERTEX = 2, + POINT_EDGE = 3 + }; + + enum IntersectionClass { + INTERSECT_BAD = -1, + INTERSECT_NONE = 0, + INTERSECT_FACE = 1, + INTERSECT_VERTEX = 2, + INTERSECT_EDGE = 3, + INTERSECT_PLANE = 4, + }; + + + + extern double EPSILON; + extern double EPSILON2; + + static inline void setEpsilon(double ep) { EPSILON = ep; EPSILON2 = ep * ep; } + + + + template + struct identity_t { + typedef T argument_type; + typedef T result_type; + const T &operator()(const T &t) const { return t; } + }; + + + + template + inline bool is_sorted(iter_t first, iter_t last) { + if (first == last) return true; + + iter_t iter = first; + iter_t next = first; ++next; + for (; next != last; iter = next, ++next) { + if (*next < *iter) { + return false; + } + } + return true; + } + + + + template + inline bool is_sorted(iter_t first, iter_t last, pred_t pred) { + if (first == last) return true; + + iter_t iter = first; + iter_t next = first; ++next; + for (; next != last; iter = next, ++next) { + if (pred(*next, *iter)) { + return false; + } + } + return true; + } + + + + inline double rangeSeparation(const std::pair &a, + const std::pair &b) { + if (a.second < b.first) { + return b.first - a.second; + } else if (b.second < a.first) { + return a.first - b.second; + } else { + return 0.0; + } + } +} + + +#if defined(_MSC_VER) +# define MACRO_BEGIN do { +# define MACRO_END __pragma(warning(push)) __pragma(warning(disable:4127)) } while(0) __pragma(warning(pop)) +#else +# define MACRO_BEGIN do { +# define MACRO_END } while(0) +#endif + +#if !defined(CARVE_NODEBUG) +# define CARVE_ASSERT(x) MACRO_BEGIN if (!(x)) throw carve::exception() << __FILE__ << ":" << __LINE__ << " " << #x; MACRO_END +#else +# define CARVE_ASSERT(X) +#endif + +#define CARVE_FAIL(x) MACRO_BEGIN throw carve::exception() << __FILE__ << ":" << __LINE__ << " " << #x; MACRO_END diff -Nru blender-2.61/extern/carve/include/carve/cbrt.h blender-2.62/extern/carve/include/carve/cbrt.h --- blender-2.61/extern/carve/include/carve/cbrt.h 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/cbrt.h 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,93 @@ +// N.B. only appropriate for IEEE doubles. +// Cube root implementation obtained from code with the following notice: + +/* @(#)s_cbrt.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +/* Sometimes it's necessary to define __LITTLE_ENDIAN explicitly + but these catch some common cases. */ + +#if defined(i386) || defined(i486) || \ + defined(intel) || defined(x86) || defined(i86pc) || \ + defined(__alpha) || defined(__osf__) +#define __LITTLE_ENDIAN +#endif + +#ifdef __LITTLE_ENDIAN +#define __HI(x) *(1+(int*)&x) +#define __LO(x) *(int*)&x +#define __HIp(x) *(1+(int*)x) +#define __LOp(x) *(int*)x +#else +#define __HI(x) *(int*)&x +#define __LO(x) *(1+(int*)&x) +#define __HIp(x) *(int*)x +#define __LOp(x) *(1+(int*)x) +#endif + +/* cbrt(x) + * Return cube root of x + */ + +inline double cbrt(double x) { + + static const unsigned + B1 = 715094163, /* B1 = (682-0.03306235651)*2**20 */ + B2 = 696219795; /* B2 = (664-0.03306235651)*2**20 */ + static const double + C = 5.42857142857142815906e-01, /* 19/35 = 0x3FE15F15, 0xF15F15F1 */ + D = -7.05306122448979611050e-01, /* -864/1225 = 0xBFE691DE, 0x2532C834 */ + E = 1.41428571428571436819e+00, /* 99/70 = 0x3FF6A0EA, 0x0EA0EA0F */ + F = 1.60714285714285720630e+00, /* 45/28 = 0x3FF9B6DB, 0x6DB6DB6E */ + G = 3.57142857142857150787e-01; /* 5/14 = 0x3FD6DB6D, 0xB6DB6DB7 */ + + int hx; + double r,s,t=0.0,w; + unsigned sign; + + hx = __HI(x); /* high word of x */ + sign=hx&0x80000000; /* sign= sign(x) */ + hx ^=sign; + if(hx>=0x7ff00000) return(x+x); /* cbrt(NaN,INF) is itself */ + if((hx|__LO(x))==0) + return(x); /* cbrt(0) is itself */ + + __HI(x) = hx; /* x <- |x| */ + /* rough cbrt to 5 bits */ + if(hx<0x00100000) /* subnormal number */ + {__HI(t)=0x43500000; /* set t= 2**54 */ + t*=x; __HI(t)=__HI(t)/3+B2; + } + else + __HI(t)=hx/3+B1; + + + /* new cbrt to 23 bits, may be implemented in single precision */ + r=t*t/x; + s=C+r*t; + t*=G+F/(s+E+D/s); + + /* chopped to 20 bits and make it larger than cbrt(x) */ + __LO(t)=0; __HI(t)+=0x00000001; + + /* one step newton iteration to 53 bits with error less than 0.667 ulps */ + s=t*t; /* t*t is exact */ + r=x/s; + w=t+t; + r=(r-t)/(w+r); /* r-s is exact */ + t=t+t*r; + + /* retore the sign bit */ + __HI(t) |= sign; + return(t); +} diff -Nru blender-2.61/extern/carve/include/carve/classification.hpp blender-2.62/extern/carve/include/carve/classification.hpp --- blender-2.61/extern/carve/include/carve/classification.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/classification.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,115 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include +#include + +namespace carve { + namespace csg { + + enum FaceClass { + FACE_UNCLASSIFIED = -3, + FACE_ON_ORIENT_OUT = -2, + FACE_OUT = -1, + FACE_ON = 0, + FACE_IN = +1, + FACE_ON_ORIENT_IN = +2 + }; + + enum FaceClassBit { + FACE_ON_ORIENT_OUT_BIT = 0x01, + FACE_OUT_BIT = 0x02, + FACE_IN_BIT = 0x04, + FACE_ON_ORIENT_IN_BIT = 0x08, + + FACE_ANY_BIT = 0x0f, + FACE_ON_BIT = 0x09, + FACE_NOT_ON_BIT = 0x06 + }; + + static inline FaceClass class_bit_to_class(unsigned i) { + if (i & FACE_ON_ORIENT_OUT_BIT) return FACE_ON_ORIENT_OUT; + if (i & FACE_OUT_BIT) return FACE_OUT; + if (i & FACE_IN_BIT) return FACE_IN; + if (i & FACE_ON_ORIENT_IN_BIT) return FACE_ON_ORIENT_IN; + return FACE_UNCLASSIFIED; + } + + static inline unsigned class_to_class_bit(FaceClass f) { + switch (f) { + case FACE_ON_ORIENT_OUT: return FACE_ON_ORIENT_OUT_BIT; + case FACE_OUT: return FACE_OUT_BIT; + case FACE_ON: return FACE_ON_BIT; + case FACE_IN: return FACE_IN_BIT; + case FACE_ON_ORIENT_IN: return FACE_ON_ORIENT_IN_BIT; + case FACE_UNCLASSIFIED: return FACE_ANY_BIT; + default: return 0; + } + } + + enum EdgeClass { + EDGE_UNK = -2, + EDGE_OUT = -1, + EDGE_ON = 0, + EDGE_IN = 1 + }; + + + + const char *ENUM(FaceClass f); + const char *ENUM(PointClass p); + + + + struct ClassificationInfo { + const carve::mesh::Mesh<3> *intersected_mesh; + FaceClass classification; + + ClassificationInfo() : intersected_mesh(NULL), classification(FACE_UNCLASSIFIED) { } + ClassificationInfo(const carve::mesh::Mesh<3> *_intersected_mesh, + FaceClass _classification) : + intersected_mesh(_intersected_mesh), + classification(_classification) { + } + bool intersectedMeshIsClosed() const { + return intersected_mesh->isClosed(); + } + }; + + + + struct EC2 { + EdgeClass cls[2]; + EC2() { cls[0] = cls[1] = EDGE_UNK; } + EC2(EdgeClass a, EdgeClass b) { cls[0] = a; cls[1] = b; } + }; + + struct PC2 { + PointClass cls[2]; + PC2() { cls[0] = cls[1] = POINT_UNK; } + PC2(PointClass a, PointClass b) { cls[0] = a; cls[1] = b; } + }; + + typedef std::unordered_map::vertex_t *, const carve::mesh::MeshSet<3>::vertex_t *>, + EC2> EdgeClassification; + + typedef std::unordered_map *, PC2> VertexClassification; + + } +} diff -Nru blender-2.61/extern/carve/include/carve/collection/unordered/boost_impl.hpp blender-2.62/extern/carve/include/carve/collection/unordered/boost_impl.hpp --- blender-2.61/extern/carve/include/carve/collection/unordered/boost_impl.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/collection/unordered/boost_impl.hpp 2012-02-15 19:39:24.000000000 +0000 @@ -0,0 +1,45 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include BOOST_INCLUDE(unordered_set.hpp) +#include BOOST_INCLUDE(unordered_map.hpp) + +#include + +namespace std { + template , + typename Pred = std::equal_to > + class unordered_map : public boost::unordered_map { + + public: + typedef T data_type; + }; + + template , + typename Pred = std::equal_to > + class unordered_multimap : public boost::unordered_multimap { + }; + + template , + typename Pred = std::equal_to > + class unordered_set : public boost::unordered_set { + }; +} + +#undef UNORDERED_COLLECTIONS_SUPPORT_RESIZE diff -Nru blender-2.61/extern/carve/include/carve/collection/unordered/fallback_impl.hpp blender-2.62/extern/carve/include/carve/collection/unordered/fallback_impl.hpp --- blender-2.61/extern/carve/include/carve/collection/unordered/fallback_impl.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/collection/unordered/fallback_impl.hpp 2012-02-15 19:39:24.000000000 +0000 @@ -0,0 +1,40 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include +#include + +namespace std { + + template + class unordered_map : public std::map { + typedef std::map super; + public: + typedef T data_type; + }; + + template + class unordered_set : public std::set { + typedef std::set super; + public: + }; + +} + +#undef UNORDERED_COLLECTIONS_SUPPORT_RESIZE diff -Nru blender-2.61/extern/carve/include/carve/collection/unordered/libstdcpp_impl.hpp blender-2.62/extern/carve/include/carve/collection/unordered/libstdcpp_impl.hpp --- blender-2.61/extern/carve/include/carve/collection/unordered/libstdcpp_impl.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/collection/unordered/libstdcpp_impl.hpp 2012-02-15 19:39:24.000000000 +0000 @@ -0,0 +1,61 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + +#pragma once + +#include +#include + +namespace __gnu_cxx { + template + struct hash : public std::unary_function { + size_t operator()(T *v) const { + size_t x = (size_t)(v); + return x + (x>>3); + } + }; + + template + struct hash > : public std::unary_function, size_t> { + size_t operator()(const std::pair &v) const { + std::size_t seed = 0; + + seed ^= hash()(v.first); + seed ^= hash()(v.second) + (seed<<6) + (seed>>2); + + return seed; + } + }; +} + +namespace std { + + template > + class unordered_map : public __gnu_cxx::hash_map { + typedef __gnu_cxx::hash_map super; + public: + typedef typename super::mapped_type data_type; + }; + + template > + class unordered_set : public __gnu_cxx::hash_set { + typedef __gnu_cxx::hash_set super; + public: + }; + +} + +#define UNORDERED_COLLECTIONS_SUPPORT_RESIZE 1 diff -Nru blender-2.61/extern/carve/include/carve/collection/unordered/std_impl.hpp blender-2.62/extern/carve/include/carve/collection/unordered/std_impl.hpp --- blender-2.61/extern/carve/include/carve/collection/unordered/std_impl.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/collection/unordered/std_impl.hpp 2012-02-15 19:39:24.000000000 +0000 @@ -0,0 +1,23 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include +#include + +#undef UNORDERED_COLLECTIONS_SUPPORT_RESIZE diff -Nru blender-2.61/extern/carve/include/carve/collection/unordered/tr1_impl.hpp blender-2.62/extern/carve/include/carve/collection/unordered/tr1_impl.hpp --- blender-2.61/extern/carve/include/carve/collection/unordered/tr1_impl.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/collection/unordered/tr1_impl.hpp 2012-02-15 19:39:24.000000000 +0000 @@ -0,0 +1,58 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include +#include +#include + +namespace std { + namespace tr1 { + template + struct hash > : public std::unary_function, size_t> { + size_t operator()(const std::pair &v) const { + std::size_t seed = 0; + + seed ^= hash()(v.first); + seed ^= hash()(v.second) + (seed<<6) + (seed>>2); + + return seed; + } + }; + } + + + + template , + typename Pred = std::equal_to > + class unordered_map : public std::tr1::unordered_map { + public: + typedef T data_type; + }; + + template , + typename Pred = std::equal_to > + class unordered_set : public std::tr1::unordered_set { + public: + }; + +} + +#undef UNORDERED_COLLECTIONS_SUPPORT_RESIZE diff -Nru blender-2.61/extern/carve/include/carve/collection/unordered/vcpp_impl.hpp blender-2.62/extern/carve/include/carve/collection/unordered/vcpp_impl.hpp --- blender-2.61/extern/carve/include/carve/collection/unordered/vcpp_impl.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/collection/unordered/vcpp_impl.hpp 2012-02-15 19:39:24.000000000 +0000 @@ -0,0 +1,65 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include +#include + +namespace std { + + namespace { + + template class hash_traits { + Hash hash_value; + std::less comp; + public: + enum { + bucket_size = 4, + min_buckets = 8 + }; + // hash _Keyval to size_t value + size_t operator()(const Value& v) const { + return ((size_t)hash_value(v)); + } + // test if _Keyval1 ordered before _Keyval2 + bool operator()(const Value& v1, const Value& v2) const { + return (comp(v1, v2)); + } + }; + + } + + template >, typename Pred = std::equal_to > + class unordered_map + : public stdext::hash_map > { + typedef stdext::hash_map > super; + public: + unordered_map() : super() {} + }; + + template >, typename Pred = std::equal_to > + class unordered_set + : public stdext::hash_set > { + typedef stdext::hash_set > super; + public: + unordered_set() : super() {} + }; + +} + +#undef UNORDERED_COLLECTIONS_SUPPORT_RESIZE diff -Nru blender-2.61/extern/carve/include/carve/collection/unordered.hpp blender-2.62/extern/carve/include/carve/collection/unordered.hpp --- blender-2.61/extern/carve/include/carve/collection/unordered.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/collection/unordered.hpp 2012-02-15 19:39:25.000000000 +0000 @@ -0,0 +1,43 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + +#pragma once + +#if defined(HAVE_STD_UNORDERED_COLLECTIONS) + +# include + +#elif defined(HAVE_TR1_UNORDERED_COLLECTIONS) + +# include + +#elif defined(HAVE_BOOST_UNORDERED_COLLECTIONS) + +# include + +#elif defined(HAVE_LIBSTDCPP_UNORDERED_COLLECTIONS) + +# include + +#elif defined(_MSC_VER) && _MSC_VER >= 1300 + +# include + +#else + +# include + +#endif diff -Nru blender-2.61/extern/carve/include/carve/collection.hpp blender-2.62/extern/carve/include/carve/collection.hpp --- blender-2.61/extern/carve/include/carve/collection.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/collection.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,51 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +namespace carve { + + template + class set_insert_iterator : public std::iterator { + + protected: + set_t *set; + public: + + set_insert_iterator(set_t &s) : set(&s) { + } + + set_insert_iterator & + operator=(typename set_t::const_reference value) { + set->insert(value); + return *this; + } + + set_insert_iterator &operator*() { return *this; } + set_insert_iterator &operator++() { return *this; } + set_insert_iterator &operator++(int) { return *this; } + }; + + template + inline set_insert_iterator + set_inserter(set_t &s) { + return set_insert_iterator(s); + } + +} diff -Nru blender-2.61/extern/carve/include/carve/collection_types.hpp blender-2.62/extern/carve/include/carve/collection_types.hpp --- blender-2.61/extern/carve/include/carve/collection_types.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/collection_types.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,63 @@ + +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +#include + +namespace carve { + namespace csg { + + typedef std::pair< + carve::mesh::MeshSet<3>::vertex_t *, + carve::mesh::MeshSet<3>::vertex_t *> V2; + + typedef std::pair< + carve::mesh::MeshSet<3>::face_t *, + carve::mesh::MeshSet<3>::face_t *> F2; + + static inline V2 ordered_edge( + carve::mesh::MeshSet<3>::vertex_t *a, + carve::mesh::MeshSet<3>::vertex_t *b) { + return V2(std::min(a, b), std::max(a, b)); + } + + static inline V2 flip(const V2 &v) { + return V2(v.second, v.first); + } + + // include/carve/csg.hpp include/carve/faceloop.hpp + // lib/intersect.cpp lib/intersect_classify_common_impl.hpp + // lib/intersect_classify_edge.cpp + // lib/intersect_classify_group.cpp + // lib/intersect_classify_simple.cpp + // lib/intersect_face_division.cpp lib/intersect_group.cpp + // lib/intersect_half_classify_group.cpp + typedef std::unordered_set V2Set; + + // include/carve/csg.hpp include/carve/polyhedron_decl.hpp + // lib/csg_collector.cpp lib/intersect.cpp + // lib/intersect_common.hpp lib/intersect_face_division.cpp + // lib/polyhedron.cpp + typedef std::unordered_map< + carve::mesh::MeshSet<3>::vertex_t *, + carve::mesh::MeshSet<3>::vertex_t *> VVMap; + } +} diff -Nru blender-2.61/extern/carve/include/carve/colour.hpp blender-2.62/extern/carve/include/carve/colour.hpp --- blender-2.61/extern/carve/include/carve/colour.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/colour.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,47 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include +#include + +namespace carve { + namespace colour { + static inline void HSV2RGB(float H, float S, float V, float &r, float &g, float &b) { + H = 6.0f * H; + if (S < 5.0e-6) { + r = g = b = V; return; + } else { + int i = (int)H; + float f = H - i; + float p1 = V * (1.0f - S); + float p2 = V * (1.0f - S * f); + float p3 = V * (1.0f - S * (1.0f - f)); + switch (i) { + case 0: r = V; g = p3; b = p1; return; + case 1: r = p2; g = V; b = p1; return; + case 2: r = p1; g = V; b = p3; return; + case 3: r = p1; g = p2; b = V; return; + case 4: r = p3; g = p1; b = V; return; + case 5: r = V; g = p1; b = p2; return; + } + } + r = g = b = 0.0; + } + } +} diff -Nru blender-2.61/extern/carve/include/carve/config.h blender-2.62/extern/carve/include/carve/config.h --- blender-2.61/extern/carve/include/carve/config.h 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/config.h 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,12 @@ +#define CARVE_VERSION "2.0.0a" + +#undef CARVE_DEBUG +#undef CARVE_DEBUG_WRITE_PLY_DATA + +#if defined(__GNUC__) +# if !defined(HAVE_BOOST_UNORDERED_COLLECTIONS) +# define HAVE_TR1_UNORDERED_COLLECTIONS +# endif + +# define HAVE_STDINT_H +#endif diff -Nru blender-2.61/extern/carve/include/carve/convex_hull.hpp blender-2.62/extern/carve/include/carve/convex_hull.hpp --- blender-2.61/extern/carve/include/carve/convex_hull.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/convex_hull.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,52 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include +#include +#include + +#include + +#include + +namespace carve { + namespace geom { + std::vector convexHull(const std::vector &points); + + template + std::vector convexHull(const project_t &project, const polygon_container_t &points) { + std::vector proj; + proj.reserve(points.size()); + for (typename polygon_container_t::const_iterator i = points.begin(); i != points.end(); ++i) { + proj.push_back(project(*i)); + } + return convexHull(proj); + } + + template + std::vector convexHull(const project_t &project, iter_t beg, iter_t end, size_t size_hint = 0) { + std::vector proj; + if (size_hint) proj.reserve(size_hint); + for (; beg != end; ++beg) { + proj.push_back(project(*beg)); + } + return convexHull(proj); + } + } +} diff -Nru blender-2.61/extern/carve/include/carve/csg.hpp blender-2.62/extern/carve/include/carve/csg.hpp --- blender-2.61/extern/carve/include/carve/csg.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/csg.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,498 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include +#include +#include + +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include + +namespace carve { + namespace csg { + + class VertexPool { + typedef carve::mesh::MeshSet<3>::vertex_t vertex_t; + + const static unsigned blocksize = 1024; + typedef std::list > pool_t; + pool_t pool; + public: + void reset(); + vertex_t *get(const vertex_t::vector_t &v = vertex_t::vector_t::ZERO()); + bool inPool(vertex_t *v) const; + + VertexPool(); + ~VertexPool(); + }; + + + + namespace detail { + struct Data; + class LoopEdges; + } + + /** + * \class CSG + * \brief The class responsible for the computation of CSG operations. + * + */ + class CSG { + private: + + public: + typedef carve::mesh::MeshSet<3> meshset_t; + + struct Hook { + /** + * \class Hook + * \brief Provides API access to intermediate steps in CSG calculation. + * + */ + virtual void intersectionVertex(const meshset_t::vertex_t * /* vertex */, + const IObjPairSet & /* intersections */) { + } + virtual void processOutputFace(std::vector & /* faces */, + const meshset_t::face_t * /* orig_face */, + bool /* flipped */) { + } + virtual void resultFace(const meshset_t::face_t * /* new_face */, + const meshset_t::face_t * /* orig_face */, + bool /* flipped */) { + } + + virtual ~Hook() { + } + }; + + /** + * \class Hooks + * \brief Management of API hooks. + * + */ + class Hooks { + public: + enum { + RESULT_FACE_HOOK = 0, + PROCESS_OUTPUT_FACE_HOOK = 1, + INTERSECTION_VERTEX_HOOK = 2, + HOOK_MAX = 3, + + RESULT_FACE_BIT = 0x0001, + PROCESS_OUTPUT_FACE_BIT = 0x0002, + INTERSECTION_VERTEX_BIT = 0x0004 + }; + + std::vector > hooks; + + bool hasHook(unsigned hook_num); + + void intersectionVertex(const meshset_t::vertex_t *vertex, + const IObjPairSet &intersections); + + void processOutputFace(std::vector &faces, + const meshset_t::face_t *orig_face, + bool flipped); + + void resultFace(const meshset_t::face_t *new_face, + const meshset_t::face_t *orig_face, + bool flipped); + + void registerHook(Hook *hook, unsigned hook_bits); + void unregisterHook(Hook *hook); + + void reset(); + + Hooks(); + ~Hooks(); + }; + + /** + * \class Collector + * \brief Base class for objects responsible for selecting result from which form the result polyhedron. + * + */ + class Collector { + Collector(const Collector &); + Collector &operator=(const Collector &); + + protected: + + public: + virtual void collect(FaceLoopGroup *group, CSG::Hooks &) =0; + virtual meshset_t *done(CSG::Hooks &) =0; + + Collector() {} + virtual ~Collector() {} + }; + + private: + typedef carve::geom::RTreeNode<3, carve::mesh::Face<3> *> face_rtree_t; + typedef std::unordered_map *, std::vector *> > face_pairs_t; + + /// The computed intersection data. + Intersections intersections; + + /// A map from intersection point to a set of intersections + /// represented by pairs of intersection objects. + VertexIntersections vertex_intersections; + + /// A pool from which temporary vertices are allocated. Also + /// provides testing for pool membership. + VertexPool vertex_pool; + + void init(); + + void makeVertexIntersections(); + + void groupIntersections(); + + void _generateVertexVertexIntersections(carve::mesh::MeshSet<3>::vertex_t *va, + carve::mesh::MeshSet<3>::edge_t *eb); + void generateVertexVertexIntersections(carve::mesh::MeshSet<3>::face_t *a, + const std::vector::face_t *> &b); + + void _generateVertexEdgeIntersections(carve::mesh::MeshSet<3>::vertex_t *va, + carve::mesh::MeshSet<3>::edge_t *eb); + void generateVertexEdgeIntersections(carve::mesh::MeshSet<3>::face_t *a, + const std::vector::face_t *> &b); + + void _generateEdgeEdgeIntersections(carve::mesh::MeshSet<3>::edge_t *ea, + carve::mesh::MeshSet<3>::edge_t *eb); + void generateEdgeEdgeIntersections(carve::mesh::MeshSet<3>::face_t *a, + const std::vector::face_t *> &b); + + void _generateVertexFaceIntersections(carve::mesh::MeshSet<3>::face_t *fa, + carve::mesh::MeshSet<3>::edge_t *eb); + void generateVertexFaceIntersections(carve::mesh::MeshSet<3>::face_t *a, + const std::vector::face_t *> &b); + + void _generateEdgeFaceIntersections(carve::mesh::MeshSet<3>::face_t *fa, + carve::mesh::MeshSet<3>::edge_t *eb); + void generateEdgeFaceIntersections(carve::mesh::MeshSet<3>::face_t *a, + const std::vector::face_t *> &b); + + void generateIntersectionCandidates(carve::mesh::MeshSet<3> *a, + const face_rtree_t *a_node, + carve::mesh::MeshSet<3> *b, + const face_rtree_t *b_node, + face_pairs_t &face_pairs, + bool descend_a = true); + /** + * \brief Compute all points of intersection between poly \a a and poly \a b + * + * @param a Polyhedron a. + * @param b Polyhedron b. + */ + void generateIntersections(meshset_t *a, + const face_rtree_t *a_node, + meshset_t *b, + const face_rtree_t *b_node, + detail::Data &data); + + /** + * \brief Generate tables of intersecting pairs of faces. + * + * @param[out] data Internal data-structure holding intersection info. + */ + void intersectingFacePairs(detail::Data &data); + + /** + * \brief Divide edges in \a edges that are intersected by polyhedron \a poly + * + * @param edges The edges to divide. + * @param[in] poly The polyhedron to divide against. + * @param[in,out] data Intersection information. + */ + void divideEdges( + const std::vector &edges, + meshset_t *poly, + detail::Data &data); + + void divideIntersectedEdges(detail::Data &data); + + /** + * \brief From the intersection points of pairs of intersecting faces, compute intersection edges. + * + * @param[out] eclass Classification information about created edges. + * @param[in,out] data Intersection information. + */ + void makeFaceEdges( + EdgeClassification &eclass, + detail::Data &data); + + friend void classifyEasyFaces( + FaceLoopList &face_loops, + VertexClassification &vclass, + meshset_t *other_poly, + int other_poly_num, + CSG &csg, + CSG::Collector &collector); + + size_t generateFaceLoops( + meshset_t *poly, + const detail::Data &data, + FaceLoopList &face_loops_out); + + + + // intersect_group.cpp + + /** + * \brief Build a loop edge mapping from a list of face loops. + * + * @param[in] loops A list of face loops. + * @param[in] edge_count A hint as to the number of edges in \a loops. + * @param[out] edge_map The calculated map of edges to loops. + */ + void makeEdgeMap( + const FaceLoopList &loops, + size_t edge_count, + detail::LoopEdges &edge_map); + + /** + * \brief Divide a list of face loops into groups that are connected by at least one edge not present in \a no_cross. + * + * @param[in] src The source mesh from which these loops derive. + * @param[in,out] face_loops The list of loops (will be emptied as a side effect) + * @param[in] loop_edges A loop edge map used for traversing connected loops. + * @param[in] no_cross A set of edges not to cross. + * @param[out] out_loops A list of grouped face loops. + */ + void groupFaceLoops( + carve::mesh::MeshSet<3> *src, + FaceLoopList &face_loops, + const detail::LoopEdges &loop_edges, + const V2Set &no_cross, + FLGroupList &out_loops); + + /** + * \brief Find the set of edges shared between two edge maps. + * + * @param[in] edge_map_a The first edge map. + * @param[in] edge_map_b The second edge map. + * @param[out] shared_edges The resulting set of common edges. + */ + void findSharedEdges( + const detail::LoopEdges &edge_map_a, + const detail::LoopEdges &edge_map_b, + V2Set &shared_edges); + + + // intersect_classify_edge.cpp + + /** + * + * + * @param shared_edges + * @param vclass + * @param poly_a + * @param a_loops_grouped + * @param a_edge_map + * @param poly_b + * @param b_loops_grouped + * @param b_edge_map + * @param collector + */ + void classifyFaceGroupsEdge( + const V2Set &shared_edges, + VertexClassification &vclass, + meshset_t *poly_a, + const face_rtree_t *poly_a_rtree, + FLGroupList &a_loops_grouped, + const detail::LoopEdges &a_edge_map, + meshset_t *poly_b, + const face_rtree_t *poly_b_rtree, + FLGroupList &b_loops_grouped, + const detail::LoopEdges &b_edge_map, + CSG::Collector &collector); + + // intersect_classify_group.cpp + + /** + * + * + * @param shared_edges + * @param vclass + * @param poly_a + * @param a_loops_grouped + * @param a_edge_map + * @param poly_b + * @param b_loops_grouped + * @param b_edge_map + * @param collector + */ + void classifyFaceGroups( + const V2Set &shared_edges, + VertexClassification &vclass, + meshset_t *poly_a, + const face_rtree_t *poly_a_rtree, + FLGroupList &a_loops_grouped, + const detail::LoopEdges &a_edge_map, + meshset_t *poly_b, + const face_rtree_t *poly_b_rtree, + FLGroupList &b_loops_grouped, + const detail::LoopEdges &b_edge_map, + CSG::Collector &collector); + + // intersect_half_classify_group.cpp + + /** + * + * + * @param shared_edges + * @param vclass + * @param poly_a + * @param a_loops_grouped + * @param a_edge_map + * @param poly_b + * @param b_loops_grouped + * @param b_edge_map + * @param FaceClass + * @param b_out + */ + void halfClassifyFaceGroups( + const V2Set &shared_edges, + VertexClassification &vclass, + meshset_t *poly_a, + const face_rtree_t *poly_a_rtree, + FLGroupList &a_loops_grouped, + const detail::LoopEdges &a_edge_map, + meshset_t *poly_b, + const face_rtree_t *poly_b_rtree, + FLGroupList &b_loops_grouped, + const detail::LoopEdges &b_edge_map, + std::list > &b_out); + + // intersect.cpp + + /** + * \brief The main calculation method for CSG. + * + * @param[in] a Polyhedron a + * @param[in] b Polyhedron b + * @param[out] vclass + * @param[out] eclass + * @param[out] a_face_loops + * @param[out] b_face_loops + * @param[out] a_edge_count + * @param[out] b_edge_count + */ + void calc( + meshset_t *a, + const face_rtree_t *a_rtree, + meshset_t *b, + const face_rtree_t *b_rtree, + VertexClassification &vclass, + EdgeClassification &eclass, + FaceLoopList &a_face_loops, + FaceLoopList &b_face_loops, + size_t &a_edge_count, + size_t &b_edge_count); + + public: + /** + * \enum OP + * \brief Enumeration of the supported CSG operations. + */ + enum OP { + UNION, /**< in a or b. */ + INTERSECTION, /**< in a and b. */ + A_MINUS_B, /**< in a, but not b. */ + B_MINUS_A, /**< in b, but not a. */ + SYMMETRIC_DIFFERENCE, /**< in a or b, but not both. */ + ALL /**< all split faces from a and b */ + }; + + /** + * \enum CLASSIFY_TYPE + * \brief The type of classification algorithm to use. + */ + enum CLASSIFY_TYPE { + CLASSIFY_NORMAL, /**< Normal (group) classifier. */ + CLASSIFY_EDGE /**< Edge classifier. */ + }; + + CSG::Hooks hooks; /**< The manager for calculation hooks. */ + + CSG(); + ~CSG(); + + /** + * \brief Compute a CSG operation between two polyhedra, \a a and \a b. + * + * @param a Polyhedron a + * @param b Polyhedron b + * @param collector The collector (determines the CSG operation performed) + * @param shared_edges A pointer to a set that will be populated with shared edges (if not NULL). + * @param classify_type The type of classifier to use. + * + * @return + */ + meshset_t *compute( + meshset_t *a, + meshset_t *b, + CSG::Collector &collector, + V2Set *shared_edges = NULL, + CLASSIFY_TYPE classify_type = CLASSIFY_NORMAL); + + /** + * \brief Compute a CSG operation between two closed polyhedra, \a a and \a b. + * + * @param a Polyhedron a + * @param b Polyhedron b + * @param op The CSG operation (A collector is created automatically). + * @param shared_edges A pointer to a set that will be populated with shared edges (if not NULL). + * @param classify_type The type of classifier to use. + * + * @return + */ + meshset_t *compute( + meshset_t *a, + meshset_t *b, + OP op, + V2Set *shared_edges = NULL, + CLASSIFY_TYPE classify_type = CLASSIFY_NORMAL); + + void slice( + meshset_t *a, + meshset_t *b, + std::list &a_sliced, + std::list &b_sliced, + V2Set *shared_edges = NULL); + + bool sliceAndClassify( + meshset_t *closed, + meshset_t *open, + std::list > &result, + V2Set *shared_edges = NULL); + }; + } +} diff -Nru blender-2.61/extern/carve/include/carve/csg_triangulator.hpp blender-2.62/extern/carve/include/carve/csg_triangulator.hpp --- blender-2.61/extern/carve/include/carve/csg_triangulator.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/csg_triangulator.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,434 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + +#include +#include +#include +#include +#include + +namespace carve { + namespace csg { + + namespace detail { + template + class CarveTriangulator : public csg::CSG::Hook { + + public: + CarveTriangulator() { + } + + virtual ~CarveTriangulator() { + } + + virtual void processOutputFace(std::vector::face_t *> &faces, + const carve::mesh::MeshSet<3>::face_t *orig, + bool flipped) { + std::vector::face_t *> out_faces; + + size_t n_tris = 0; + for (size_t f = 0; f < faces.size(); ++f) { + CARVE_ASSERT(faces[f]->nVertices() >= 3); + n_tris += faces[f]->nVertices() - 2; + } + + out_faces.reserve(n_tris); + + for (size_t f = 0; f < faces.size(); ++f) { + carve::mesh::MeshSet<3>::face_t *face = faces[f]; + + if (face->nVertices() == 3) { + out_faces.push_back(face); + continue; + } + + std::vector result; + + std::vector::vertex_t *> vloop; + face->getVertices(vloop); + + triangulate::triangulate( + carve::mesh::MeshSet<3>::face_t::projection_mapping(face->project), + vloop, + result); + + if (with_improvement) { + triangulate::improve( + carve::mesh::MeshSet<3>::face_t::projection_mapping(face->project), + vloop, + carve::mesh::vertex_distance(), + result); + } + + std::vector::vertex_t *> fv; + fv.resize(3); + for (size_t i = 0; i < result.size(); ++i) { + fv[0] = vloop[result[i].a]; + fv[1] = vloop[result[i].b]; + fv[2] = vloop[result[i].c]; + out_faces.push_back(face->create(fv.begin(), fv.end(), false)); + } + delete face; + } + std::swap(faces, out_faces); + } + }; + } + + typedef detail::CarveTriangulator CarveTriangulator; + typedef detail::CarveTriangulator CarveTriangulatorWithImprovement; + + class CarveTriangulationImprover : public csg::CSG::Hook { + public: + CarveTriangulationImprover() { + } + + virtual ~CarveTriangulationImprover() { + } + + virtual void processOutputFace(std::vector::face_t *> &faces, + const carve::mesh::MeshSet<3>::face_t *orig, + bool flipped) { + if (faces.size() == 1) return; + + // doing improvement as a separate hook is much messier than + // just incorporating it into the triangulation hook. + + typedef std::map::vertex_t *, size_t> vert_map_t; + std::vector::face_t *> out_faces; + vert_map_t vert_map; + + out_faces.reserve(faces.size()); + + + carve::mesh::MeshSet<3>::face_t::projection_mapping projector(faces[0]->project); + + std::vector result; + + for (size_t f = 0; f < faces.size(); ++f) { + carve::mesh::MeshSet<3>::face_t *face = faces[f]; + if (face->nVertices() != 3) { + out_faces.push_back(face); + } else { + triangulate::tri_idx tri; + for (carve::mesh::MeshSet<3>::face_t::edge_iter_t i = face->begin(); i != face->end(); ++i) { + size_t v = 0; + vert_map_t::iterator j = vert_map.find(i->vert); + if (j == vert_map.end()) { + v = vert_map.size(); + vert_map[i->vert] = v; + } else { + v = (*j).second; + } + tri.v[i.idx()] = v; + } + result.push_back(tri); + delete face; + } + } + + std::vector::vertex_t *> verts; + verts.resize(vert_map.size()); + for (vert_map_t::iterator i = vert_map.begin(); i != vert_map.end(); ++i) { + verts[(*i).second] = (*i).first; + } + + triangulate::improve(projector, verts, carve::mesh::vertex_distance(), result); + + std::vector::vertex_t *> fv; + fv.resize(3); + for (size_t i = 0; i < result.size(); ++i) { + fv[0] = verts[result[i].a]; + fv[1] = verts[result[i].b]; + fv[2] = verts[result[i].c]; + out_faces.push_back(orig->create(fv.begin(), fv.end(), false)); + } + + std::swap(faces, out_faces); + } + }; + + class CarveTriangulationQuadMerger : public csg::CSG::Hook { + // this code is incomplete. + typedef std::map edge_map_t; + + public: + CarveTriangulationQuadMerger() { + } + + virtual ~CarveTriangulationQuadMerger() { + } + + double scoreQuad(edge_map_t::iterator i, edge_map_t &edge_map) { + if (!(*i).second.first || !(*i).second.second) return -1; + return 0; + } + + carve::mesh::MeshSet<3>::face_t *mergeQuad(edge_map_t::iterator i, edge_map_t &edge_map) { + return NULL; + } + + void recordEdge(carve::mesh::MeshSet<3>::vertex_t *v1, + carve::mesh::MeshSet<3>::vertex_t *v2, + carve::mesh::MeshSet<3>::face_t *f, + edge_map_t &edge_map) { + if (v1 < v2) { + edge_map[V2(v1, v2)].first = f; + } else { + edge_map[V2(v2, v1)].second = f; + } + } + + virtual void processOutputFace(std::vector::face_t *> &faces, + const carve::mesh::MeshSet<3>::face_t *orig, + bool flipped) { + if (faces.size() == 1) return; + + std::vector::face_t *> out_faces; + edge_map_t edge_map; + + out_faces.reserve(faces.size()); + + poly::p2_adapt_project<3> projector(faces[0]->project); + + for (size_t f = 0; f < faces.size(); ++f) { + carve::mesh::MeshSet<3>::face_t *face = faces[f]; + if (face->nVertices() != 3) { + out_faces.push_back(face); + } else { + carve::mesh::MeshSet<3>::face_t::vertex_t *v1, *v2, *v3; + v1 = face->edge->vert; + v2 = face->edge->next->vert; + v3 = face->edge->next->next->vert; + recordEdge(v1, v2, face, edge_map); + recordEdge(v2, v3, face, edge_map); + recordEdge(v3, v1, face, edge_map); + } + } + + for (edge_map_t::iterator i = edge_map.begin(); i != edge_map.end();) { + if ((*i).second.first && (*i).second.second) { + ++i; + } else { + edge_map.erase(i++); + } + } + + while (edge_map.size()) { + edge_map_t::iterator i = edge_map.begin(); + edge_map_t::iterator best = i; + double best_score = scoreQuad(i, edge_map); + for (++i; i != edge_map.end(); ++i) { + double score = scoreQuad(i, edge_map); + if (score > best_score) best = i; + } + if (best_score < 0) break; + out_faces.push_back(mergeQuad(best, edge_map)); + } + + if (edge_map.size()) { + tagable::tag_begin(); + for (edge_map_t::iterator i = edge_map.begin(); i != edge_map.end(); ++i) { + carve::mesh::MeshSet<3>::face_t *a = const_cast::face_t *>((*i).second.first); + carve::mesh::MeshSet<3>::face_t *b = const_cast::face_t *>((*i).second.first); + if (a && a->tag_once()) out_faces.push_back(a); + if (b && b->tag_once()) out_faces.push_back(b); + } + } + + std::swap(faces, out_faces); + } + }; + + class CarveHoleResolver : public csg::CSG::Hook { + + public: + CarveHoleResolver() { + } + + virtual ~CarveHoleResolver() { + } + + bool findRepeatedEdges(const std::vector::vertex_t *> &vertices, + std::list > &edge_pos) { + std::map edges; + for (size_t i = 0; i < vertices.size() - 1; ++i) { + edges[std::make_pair(vertices[i], vertices[i+1])] = i; + } + edges[std::make_pair(vertices[vertices.size()-1], vertices[0])] = vertices.size() - 1; + + for (std::map::iterator i = edges.begin(); i != edges.end(); ++i) { + V2 rev = V2((*i).first.second, (*i).first.first); + std::map::iterator j = edges.find(rev); + if (j != edges.end()) { + edge_pos.push_back(std::make_pair((*i).second, (*j).second)); + } + } + return edge_pos.size() > 0; + } + + void flood(size_t t1, + size_t t2, + size_t old_grp, + size_t new_grp_1, + size_t new_grp_2, + std::vector &grp, + const std::vector &tris, + const std::map, size_t> &tri_edge) { + grp[t1] = new_grp_1; + grp[t2] = new_grp_2; + + std::deque to_visit; + to_visit.push_back(t1); + to_visit.push_back(t2); + std::vector > rev; + rev.resize(3); + while (to_visit.size()) { + size_t curr = to_visit.front(); + to_visit.pop_front(); + triangulate::tri_idx ct = tris[curr]; + rev[0] = std::make_pair(ct.b, ct.a); + rev[1] = std::make_pair(ct.c, ct.b); + rev[2] = std::make_pair(ct.a, ct.c); + + for (size_t i = 0; i < 3; ++i) { + std::map, size_t>::const_iterator adj = tri_edge.find(rev[i]); + if (adj == tri_edge.end()) continue; + size_t next = (*adj).second; + if (grp[next] != old_grp) continue; + grp[next] = grp[curr]; + to_visit.push_back(next); + } + } + } + + void findPerimeter(const std::vector &tris, + const std::vector::vertex_t *> &verts, + std::vector::vertex_t *> &out) { + std::map, size_t> edges; + for (size_t i = 0; i < tris.size(); ++i) { + edges[std::make_pair(tris[i].a, tris[i].b)] = i; + edges[std::make_pair(tris[i].b, tris[i].c)] = i; + edges[std::make_pair(tris[i].c, tris[i].a)] = i; + } + std::map unpaired; + for (std::map, size_t>::iterator i = edges.begin(); i != edges.end(); ++i) { + if (edges.find(std::make_pair((*i).first.second, (*i).first.first)) == edges.end()) { + CARVE_ASSERT(unpaired.find((*i).first.first) == unpaired.end()); + unpaired[(*i).first.first] = (*i).first.second; + } + } + out.clear(); + out.reserve(unpaired.size()); + size_t start = (*unpaired.begin()).first; + size_t vert = start; + do { + out.push_back(verts[vert]); + CARVE_ASSERT(unpaired.find(vert) != unpaired.end()); + vert = unpaired[vert]; + } while (vert != start); + } + + virtual void processOutputFace(std::vector::face_t *> &faces, + const carve::mesh::MeshSet<3>::face_t *orig, + bool flipped) { + std::vector::face_t *> out_faces; + + for (size_t f = 0; f < faces.size(); ++f) { + carve::mesh::MeshSet<3>::face_t *face = faces[f]; + + if (face->nVertices() == 3) { + out_faces.push_back(face); + continue; + } + + std::vector::vertex_t *> vloop; + face->getVertices(vloop); + + std::list > rep_edges; + if (!findRepeatedEdges(vloop, rep_edges)) { + out_faces.push_back(face); + continue; + } + + std::vector result; + triangulate::triangulate( + carve::mesh::MeshSet<3>::face_t::projection_mapping(face->project), + vloop, + result); + + std::map, size_t> tri_edge; + for (size_t i = 0; i < result.size(); ++i) { + tri_edge[std::make_pair(result[i].a, result[i].b)] = i; + tri_edge[std::make_pair(result[i].b, result[i].c)] = i; + tri_edge[std::make_pair(result[i].c, result[i].a)] = i; + } + + std::vector grp; + grp.resize(result.size(), 0); + + size_t grp_max = 0; + + while (rep_edges.size()) { + std::pair e1, e2; + + e1.first = rep_edges.front().first; + e1.second = (e1.first + 1) % vloop.size(); + + e2.first = rep_edges.front().second; + e2.second = (e2.first + 1) % vloop.size(); + + rep_edges.pop_front(); + + CARVE_ASSERT(tri_edge.find(e1) != tri_edge.end()); + size_t t1 = tri_edge[e1]; + CARVE_ASSERT(tri_edge.find(e2) != tri_edge.end()); + size_t t2 = tri_edge[e2]; + + if (grp[t1] != grp[t2]) { + continue; + } + + size_t t1g = ++grp_max; + size_t t2g = ++grp_max; + + flood(t1, t2, grp[t1], t1g, t2g, grp, result, tri_edge); + } + + std::set groups; + std::copy(grp.begin(), grp.end(), std::inserter(groups, groups.begin())); + + // now construct perimeters for each group. + std::vector grp_tris; + grp_tris.reserve(result.size()); + for (std::set::iterator i = groups.begin(); i != groups.end(); ++i) { + size_t grp_id = *i; + grp_tris.clear(); + for (size_t j = 0; j < grp.size(); ++j) { + if (grp[j] == grp_id) { + grp_tris.push_back(result[j]); + } + } + std::vector::vertex_t *> grp_perim; + findPerimeter(grp_tris, vloop, grp_perim); + out_faces.push_back(face->create(grp_perim.begin(), grp_perim.end(), false)); + } + } + std::swap(faces, out_faces); + } + }; + } +} diff -Nru blender-2.61/extern/carve/include/carve/debug_hooks.hpp blender-2.62/extern/carve/include/carve/debug_hooks.hpp --- blender-2.61/extern/carve/include/carve/debug_hooks.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/debug_hooks.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,97 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +#include +#include +#include + +#include + +template +void map_histogram(std::ostream &out, const MAP &map) { + std::vector hist; + for (typename MAP::const_iterator i = map.begin(); i != map.end(); ++i) { + size_t n = (*i).second.size(); + if (hist.size() <= n) { + hist.resize(n + 1); + } + hist[n]++; + } + int total = map.size(); + std::string bar(50, '*'); + for (size_t i = 0; i < hist.size(); i++) { + if (hist[i] > 0) { + out << std::setw(5) << i << " : " << std::setw(5) << hist[i] << " " << bar.substr(50 - hist[i] * 50 / total) << std::endl; + } + } +} + +namespace carve { + namespace csg { + class IntersectDebugHooks { + public: + virtual void drawIntersections(const VertexIntersections & /* vint */) { + } + + virtual void drawPoint(const carve::mesh::MeshSet<3>::vertex_t * /* v */, + float /* r */, + float /* g */, + float /* b */, + float /* a */, + float /* rad */) { + } + virtual void drawEdge(const carve::mesh::MeshSet<3>::vertex_t * /* v1 */, + const carve::mesh::MeshSet<3>::vertex_t * /* v2 */, + float /* rA */, float /* gA */, float /* bA */, float /* aA */, + float /* rB */, float /* gB */, float /* bB */, float /* aB */, + float /* thickness */ = 1.0) { + } + + virtual void drawFaceLoopWireframe(const std::vector::vertex_t *> & /* face_loop */, + const carve::mesh::MeshSet<3>::vertex_t & /* normal */, + float /* r */, float /* g */, float /* b */, float /* a */, + bool /* inset */ = true) { + } + + virtual void drawFaceLoop(const std::vector::vertex_t *> & /* face_loop */, + const carve::mesh::MeshSet<3>::vertex_t & /* normal */, + float /* r */, float /* g */, float /* b */, float /* a */, + bool /* offset */ = true, + bool /* lit */ = true) { + } + + virtual void drawFaceLoop2(const std::vector::vertex_t *> & /* face_loop */, + const carve::mesh::MeshSet<3>::vertex_t & /* normal */, + float /* rF */, float /* gF */, float /* bF */, float /* aF */, + float /* rB */, float /* gB */, float /* bB */, float /* aB */, + bool /* offset */ = true, + bool /* lit */ = true) { + } + + virtual ~IntersectDebugHooks() { + } + }; + + IntersectDebugHooks *intersect_installDebugHooks(IntersectDebugHooks *hooks); + bool intersect_debugEnabled(); + + } +} diff -Nru blender-2.61/extern/carve/include/carve/djset.hpp blender-2.62/extern/carve/include/carve/djset.hpp --- blender-2.61/extern/carve/include/carve/djset.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/djset.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,134 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include +#include + + + +namespace carve { +namespace djset { + + + + class djset { + + protected: + struct elem { + size_t parent, rank; + elem(size_t p, size_t r) : parent(p), rank(r) {} + elem() {} + }; + + std::vector set; + size_t n_sets; + + public: + djset() : set(), n_sets(0) { + } + + djset(size_t N) { + n_sets = N; + set.reserve(N); + for (size_t i = 0; i < N; ++i) { + set.push_back(elem(i,0)); + } + } + + void init(size_t N) { + if (N == set.size()) { + for (size_t i = 0; i < N; ++i) { + set[i] = elem(i,0); + } + n_sets = N; + } else { + djset temp(N); + std::swap(set, temp.set); + std::swap(n_sets, temp.n_sets); + } + } + + size_t count() const { + return n_sets; + } + + size_t find_set_head(size_t a) { + if (a == set[a].parent) return a; + + size_t a_head = a; + while (set[a_head].parent != a_head) a_head = set[a_head].parent; + set[a].parent = a_head; + return a_head; + } + + bool same_set(size_t a, size_t b) { + return find_set_head(a) == find_set_head(b); + } + + void merge_sets(size_t a, size_t b) { + a = find_set_head(a); + b = find_set_head(b); + if (a != b) { + n_sets--; + if (set[a].rank < set[b].rank) { + set[a].parent = b; + } else if (set[b].rank < set[a].rank) { + set[b].parent = a; + } else { + set[a].rank++; + set[b].parent = a; + } + } + } + + void get_index_to_set(std::vector &index_set, std::vector &set_size) { + index_set.clear(); + index_set.resize(set.size(), n_sets); + set_size.clear(); + set_size.resize(n_sets, 0); + + size_t c = 0; + for (size_t i = 0; i < set.size(); ++i) { + size_t s = find_set_head(i); + if (index_set[s] == n_sets) index_set[s] = c++; + index_set[i] = index_set[s]; + set_size[index_set[s]]++; + } + } + + template + void collate(in_iter_t in, out_collection_t &out) { + std::vector set_id(set.size(), n_sets); + out.clear(); + out.resize(n_sets); + size_t c = 0; + for (size_t i = 0; i < set.size(); ++i) { + size_t s = find_set_head(i); + if (set_id[s] == n_sets) set_id[s] = c++; + s = set_id[s]; + std::insert_iterator j(out[s], out[s].end()); + *j = *in++; + } + } + }; + + + +} +} diff -Nru blender-2.61/extern/carve/include/carve/edge_decl.hpp blender-2.62/extern/carve/include/carve/edge_decl.hpp --- blender-2.61/extern/carve/include/carve/edge_decl.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/edge_decl.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,68 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +#include +#include + +#include +#include + +namespace carve { + namespace poly { + + + + struct Object; + + + + template + class Edge : public tagable { + public: + typedef Vertex vertex_t; + typedef typename Vertex::vector_t vector_t; + typedef Object obj_t; + + const vertex_t *v1, *v2; + const obj_t *owner; + + Edge(const vertex_t *_v1, const vertex_t *_v2, const obj_t *_owner) : + tagable(), v1(_v1), v2(_v2), owner(_owner) { + } + + ~Edge() { + } + }; + + + + struct hash_edge_ptr { + template + size_t operator()(const Edge * const &e) const { + return (size_t)e; + } + }; + + + + } +} + diff -Nru blender-2.61/extern/carve/include/carve/edge_impl.hpp blender-2.62/extern/carve/include/carve/edge_impl.hpp --- blender-2.61/extern/carve/include/carve/edge_impl.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/edge_impl.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,23 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +namespace carve { + namespace poly { + } +} diff -Nru blender-2.61/extern/carve/include/carve/exact.hpp blender-2.62/extern/carve/include/carve/exact.hpp --- blender-2.61/extern/carve/include/carve/exact.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/exact.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,702 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +#include +#include +#include + + +namespace carve { + namespace exact { + + class exact_t : public std::vector { + typedef std::vector super; + + public: + exact_t() : super() { + } + + exact_t(double v, size_t sz = 1) : super(sz, v) { + } + + template + exact_t(iter_t a, iter_t b) : super(a, b) { + } + + exact_t(double a, double b) : super() { + reserve(2); + push_back(a); + push_back(b); + } + + exact_t(double a, double b, double c) : super() { + reserve(3); + push_back(a); + push_back(b); + push_back(c); + } + + exact_t(double a, double b, double c, double d) : super() { + reserve(4); + push_back(a); + push_back(b); + push_back(c); + push_back(d); + } + + exact_t(double a, double b, double c, double d, double e) : super() { + reserve(5); + push_back(a); + push_back(b); + push_back(c); + push_back(d); + push_back(e); + } + + exact_t(double a, double b, double c, double d, double e, double f) : super() { + reserve(6); + push_back(a); + push_back(b); + push_back(c); + push_back(d); + push_back(e); + push_back(f); + } + + exact_t(double a, double b, double c, double d, double e, double f, double g) : super() { + reserve(7); + push_back(a); + push_back(b); + push_back(c); + push_back(d); + push_back(e); + push_back(f); + push_back(g); + } + + exact_t(double a, double b, double c, double d, double e, double f, double g, double h) : super() { + reserve(8); + push_back(a); + push_back(b); + push_back(c); + push_back(d); + push_back(e); + push_back(f); + push_back(g); + push_back(h); + } + + void compress(); + + exact_t compressed() const { + exact_t result(*this); + result.compress(); + return result; + } + + operator double() const { + return std::accumulate(begin(), end(), 0.0); + } + + void removeZeroes() { + erase(std::remove(begin(), end(), 0.0), end()); + } + }; + + inline std::ostream &operator<<(std::ostream &out, const exact_t &p) { + out << '{'; + out << p[0]; + for (size_t i = 1; i < p.size(); ++i) out << ';' << p[i]; + out << '}'; + return out; + } + + + + namespace detail { + const struct constants_t { + double splitter; /* = 2^ceiling(p / 2) + 1. Used to split floats in half. */ + double epsilon; /* = 2^(-p). Used to estimate roundoff errors. */ + /* A set of coefficients used to calculate maximum roundoff errors. */ + double resulterrbound; + double ccwerrboundA, ccwerrboundB, ccwerrboundC; + double o3derrboundA, o3derrboundB, o3derrboundC; + double iccerrboundA, iccerrboundB, iccerrboundC; + double isperrboundA, isperrboundB, isperrboundC; + + constants_t() { + double half; + double check, lastcheck; + int every_other; + + every_other = 1; + half = 0.5; + epsilon = 1.0; + splitter = 1.0; + check = 1.0; + /* Repeatedly divide `epsilon' by two until it is too small to add to */ + /* one without causing roundoff. (Also check if the sum is equal to */ + /* the previous sum, for machines that round up instead of using exact */ + /* rounding. Not that this library will work on such machines anyway. */ + do { + lastcheck = check; + epsilon *= half; + if (every_other) { + splitter *= 2.0; + } + every_other = !every_other; + check = 1.0 + epsilon; + } while ((check != 1.0) && (check != lastcheck)); + splitter += 1.0; + + /* Error bounds for orientation and incircle tests. */ + resulterrbound = (3.0 + 8.0 * epsilon) * epsilon; + ccwerrboundA = (3.0 + 16.0 * epsilon) * epsilon; + ccwerrboundB = (2.0 + 12.0 * epsilon) * epsilon; + ccwerrboundC = (9.0 + 64.0 * epsilon) * epsilon * epsilon; + o3derrboundA = (7.0 + 56.0 * epsilon) * epsilon; + o3derrboundB = (3.0 + 28.0 * epsilon) * epsilon; + o3derrboundC = (26.0 + 288.0 * epsilon) * epsilon * epsilon; + iccerrboundA = (10.0 + 96.0 * epsilon) * epsilon; + iccerrboundB = (4.0 + 48.0 * epsilon) * epsilon; + iccerrboundC = (44.0 + 576.0 * epsilon) * epsilon * epsilon; + isperrboundA = (16.0 + 224.0 * epsilon) * epsilon; + isperrboundB = (5.0 + 72.0 * epsilon) * epsilon; + isperrboundC = (71.0 + 1408.0 * epsilon) * epsilon * epsilon; + } + } constants; + + template + struct op { + enum { + Vlo = V / 2, + Vhi = V - Vlo + }; + + static inline void add(const double *a, const double *b, double *r) { + double t[U + Vlo]; + op::add(a, b, t); + for (size_t i = 0; i < Vlo; ++i) r[i] = t[i]; + op::add(t + Vlo, b + Vlo, r + Vlo); + } + + static inline void sub(const double *a, const double *b, double *r) { + double t[U + Vlo]; + op::sub(a, b, t); + for (size_t i = 0; i < Vlo; ++i) r[i] = t[i]; + op::sub(t + Vlo, b + Vlo, r + Vlo); + } + }; + + template + struct op { + enum { + Ulo = U / 2, + Uhi = U - Ulo + }; + static void add(const double *a, const double *b, double *r) { + double t[Ulo + 1]; + op::add(a, b, t); + for (size_t i = 0; i < Ulo; ++i) r[i] = t[i]; + op::add(a + Ulo, t + Ulo, r + Ulo); + } + + static void sub(const double *a, const double *b, double *r) { + double t[Ulo + 1]; + op::sub(a, b, t); + for (size_t i = 0; i < Ulo; ++i) r[i] = t[i]; + op::add(a + Ulo, t + Ulo, r + Ulo); + } + }; + + template<> + struct op<1, 1> { + static void add_fast(const double *a, const double *b, double *r) { + assert(fabs(a[0]) >= fabs(b[0])); + volatile double sum = a[0] + b[0]; + volatile double bvirt = sum - a[0]; + r[0] = b[0] - bvirt; + r[1] = sum; + } + + static void sub_fast(const double *a, const double *b, double *r) { + assert(fabs(a[0]) >= fabs(b[0])); + volatile double diff = a[0] - b[0]; + volatile double bvirt = a[0] - diff; + r[0] = bvirt - b[0]; + r[1] = diff; + } + + static void add(const double *a, const double *b, double *r) { + volatile double sum = a[0] + b[0]; + volatile double bvirt = sum - a[0]; + double avirt = sum - bvirt; + double bround = b[0] - bvirt; + double around = a[0] - avirt; + r[0] = around + bround; + r[1] = sum; + } + + static void sub(const double *a, const double *b, double *r) { + volatile double diff = a[0] - b[0]; + volatile double bvirt = a[0] - diff; + double avirt = diff + bvirt; + double bround = bvirt - b[0]; + double around = a[0] - avirt; + r[0] = around + bround; + r[1] = diff; + } + }; + + + template + static exact_t add(const double *a, const double *b) { + exact_t result; + result.resize(U + V); + op::add(a, b, &result[0]); + return result; + } + + + template + static exact_t sub(const double *a, const double *b) { + exact_t result; + result.resize(U + V); + op::sub(a, b, &result[0]); + return result; + } + + + template + static exact_t add(const exact_t &a, const exact_t &b) { + assert(a.size() == U); + assert(b.size() == V); + exact_t result; + result.resize(U + V); + std::fill(result.begin(), result.end(), std::numeric_limits::quiet_NaN()); + op::add(&a[0], &b[0], &result[0]); + return result; + } + + + template + static exact_t add(const exact_t &a, const double *b) { + assert(a.size() == U); + exact_t result; + result.resize(U + V); + std::fill(result.begin(), result.end(), std::numeric_limits::quiet_NaN()); + op::add(&a[0], b, &result[0]); + return result; + } + + + template + static exact_t sub(const exact_t &a, const exact_t &b) { + assert(a.size() == U); + assert(b.size() == V); + exact_t result; + result.resize(U + V); + std::fill(result.begin(), result.end(), std::numeric_limits::quiet_NaN()); + op::sub(&a[0], &b[0], &result[0]); + return result; + } + + + template + static exact_t sub(const exact_t &a, const double *b) { + assert(a.size() == U); + exact_t result; + result.resize(U + V); + std::fill(result.begin(), result.end(), std::numeric_limits::quiet_NaN()); + op::sub(&a[0], &b[0], &result[0]); + return result; + } + + + static inline void split(const double a, double *r) { + volatile double c = constants.splitter * a; + volatile double abig = c - a; + r[1] = c - abig; + r[0] = a - r[1]; + } + + static inline void prod_1_1(const double *a, const double *b, double *r) { + r[1] = a[0] * b[0]; + double a_sp[2]; split(a[0], a_sp); + double b_sp[2]; split(b[0], b_sp); + double err1 = r[1] - a_sp[1] * b_sp[1]; + double err2 = err1 - a_sp[0] * b_sp[1]; + double err3 = err2 - a_sp[1] * b_sp[0]; + r[0] = a_sp[0] * b_sp[0] - err3; + } + + static inline void prod_1_1s(const double *a, const double *b, const double *b_sp, double *r) { + r[1] = a[0] * b[0]; + double a_sp[2]; split(a[0], a_sp); + double err1 = r[1] - a_sp[1] * b_sp[1]; + double err2 = err1 - a_sp[0] * b_sp[1]; + double err3 = err2 - a_sp[1] * b_sp[0]; + r[0] = a_sp[0] * b_sp[0] - err3; + } + + static inline void prod_1s_1s(const double *a, const double *a_sp, const double *b, const double *b_sp, double *r) { + r[1] = a[0] * b[0]; + double err1 = r[1] - a_sp[1] * b_sp[1]; + double err2 = err1 - a_sp[0] * b_sp[1]; + double err3 = err2 - a_sp[1] * b_sp[0]; + r[0] = a_sp[0] * b_sp[0] - err3; + } + + static inline void prod_2_1(const double *a, const double *b, double *r) { + double b_sp[2]; split(b[0], b_sp); + double t1[2]; prod_1_1s(a+0, b, b_sp, t1); + r[0] = t1[0]; + double t2[2]; prod_1_1s(a+1, b, b_sp, t2); + double t3[2]; op<1,1>::add(t1+1, t2, t3); + r[1] = t3[0]; + double t4[2]; op<1,1>::add_fast(t2+1, t3+1, r + 2); + } + + static inline void prod_1_2(const double *a, const double *b, double *r) { + prod_2_1(b, a, r); + } + + static inline void prod_4_1(const double *a, const double *b, double *r) { + double b_sp[2]; split(b[0], b_sp); + double t1[2]; prod_1_1s(a+0, b, b_sp, t1); + r[0] = t1[0]; + double t2[2]; prod_1_1s(a+1, b, b_sp, t2); + double t3[2]; op<1,1>::add(t1+1, t2, t3); + r[1] = t3[0]; + double t4[2]; op<1,1>::add_fast(t2+1, t3+1, t4); + r[2] = t4[0]; + double t5[2]; prod_1_1s(a+2, b, b_sp, t5); + double t6[2]; op<1,1>::add(t4+1, t5, t6); + r[3] = t6[0]; + double t7[2]; op<1,1>::add_fast(t5+1, t6+1, t7); + r[4] = t7[0]; + double t8[2]; prod_1_1s(a+3, b, b_sp, t8); + double t9[2]; op<1,1>::add(t7+1, t8, t9); + r[5] = t9[0]; + op<1,1>::add_fast(t8+1, t9+1, r + 6); + } + + static inline void prod_1_4(const double *a, const double *b, double *r) { + prod_4_1(b, a, r); + } + + static inline void prod_2_2(const double *a, const double *b, double *r) { + double a1_sp[2]; split(a[1], a1_sp); + double a0_sp[2]; split(a[0], a0_sp); + double b1_sp[2]; split(b[1], b1_sp); + double b0_sp[2]; split(b[0], b0_sp); + + double t1[2]; prod_1s_1s(a+0, a0_sp, b+0, b0_sp, t1); + r[0] = t1[0]; + double t2[2]; prod_1s_1s(a+1, a1_sp, b+0, b0_sp, t2); + + double t3[2]; op<1,1>::add(t1+1, t2, t3); + double t4[2]; op<1,1>::add_fast(t2+1, t3+1, t4); + + double t5[2]; prod_1s_1s(a+0, a0_sp, b+1, b1_sp, t5); + + double t6[2]; op<1,1>::add(t3, t5, t6); + r[1] = t6[0]; + double t7[2]; op<1,1>::add(t4, t6+1, t7); + double t8[2]; op<1,1>::add(t4+1, t7+1, t8); + + double t9[2]; prod_1s_1s(a+1, a1_sp, b+1, b1_sp, t9); + + double t10[2]; op<1,1>::add(t5+1, t9, t10); + double t11[2]; op<1,1>::add(t7, t10, t11); + r[2] = t11[0]; + double t12[2]; op<1,1>::add(t8, t11+1, t12); + double t13[2]; op<1,1>::add(t8+1, t12+1, t13); + double t14[2]; op<1,1>::add(t9+1, t10+1, t14); + double t15[2]; op<1,1>::add(t12, t14, t15); + r[3] = t15[0]; + double t16[2]; op<1,1>::add(t13, t15+1, t16); + double t17[2]; op<1,1>::add(t13+1, t16+1, t17); + double t18[2]; op<1,1>::add(t16, t14+1, t18); + r[4] = t18[0]; + double t19[2]; op<1,1>::add(t17, t18+1, t19); + r[5] = t19[0]; + double t20[2]; op<1,1>::add(t17+1, t19+1, t20); + r[6] = t20[0]; + r[7] = t20[1]; + } + + + + static inline void square(const double a, double *r) { + r[1] = a * a; + double a_sp[2]; split(a, a_sp); + double err1 = r[1] - (a_sp[1] * a_sp[1]); + double err3 = err1 - ((a_sp[1] + a_sp[1]) * a_sp[0]); + r[0] = a_sp[0] * a_sp[0] - err3; + } + + static inline void square_2(const double *a, double *r) { + double t1[2]; square(a[0], t1); + r[0] = t1[0]; + double t2 = a[0] + a[0]; + double t3[2]; prod_1_1(a+1, &t2, t3); + double t4[3]; op<2,1>::add(t3, t1 + 1, t4); + r[1] = t4[0]; + double t5[2]; square(a[1], t5); + double t6[4]; op<2,2>::add(t5, t4 + 1, r + 2); + } + } + + + + void exact_t::compress() { + double sum[2]; + + int j = size() - 1; + double Q = (*this)[j]; + for (int i = (int)size()-2; i >= 0; --i) { + detail::op<1,1>::add_fast(&Q, &(*this)[i], sum); + if (sum[0] != 0) { + (*this)[j--] = sum[1]; + Q = sum[0]; + } else { + Q = sum[1]; + } + } + int j2 = 0; + for (int i = j + 1; i < (int)size(); ++i) { + detail::op<1,1>::add_fast(&(*this)[i], &Q, sum); + if (sum[0] != 0) { + (*this)[j2++] = sum[0]; + } + Q = sum[1]; + } + (*this)[j2++] = Q; + + erase(begin() + j2, end()); + } + + template + void negate(iter_t begin, iter_t end) { + while (begin != end) { *begin = -*begin; ++begin; } + } + + void negate(exact_t &e) { + negate(&e[0], &e[e.size()]); + } + + template + void scale_zeroelim(iter_t ebegin, + iter_t eend, + double b, + exact_t &h) { + double Q; + + h.clear(); + double b_sp[2]; detail::split(b, b_sp); + + double prod[2], sum[2]; + + detail::prod_1_1s((double *)ebegin++, &b, b_sp, prod); + Q = prod[1]; + if (prod[0] != 0.0) { + h.push_back(prod[0]); + } + while (ebegin != eend) { + double enow = *ebegin++; + detail::prod_1_1s(&enow, &b, b_sp, prod); + detail::op<1,1>::add(&Q, prod, sum); + if (sum[0] != 0) { + h.push_back(sum[0]); + } + detail::op<1,1>::add_fast(prod+1, sum+1, sum); + Q = sum[1]; + if (sum[0] != 0) { + h.push_back(sum[0]); + } + } + if ((Q != 0.0) || (h.size() == 0)) { + h.push_back(Q); + } + } + + void scale_zeroelim(const exact_t &e, + double b, + exact_t &h) { + scale_zeroelim(&e[0], &e[e.size()], b, h); + } + + template + void sum_zeroelim(iter_t ebegin, + iter_t eend, + iter_t fbegin, + iter_t fend, + exact_t &h) { + double Q; + double enow, fnow; + + double sum[2]; + + enow = *ebegin; + fnow = *fbegin; + + h.clear(); + + if ((fnow > enow) == (fnow > -enow)) { + Q = enow; + enow = *++ebegin; + } else { + Q = fnow; + fnow = *++fbegin; + } + + if (ebegin != eend && fbegin != fend) { + if ((fnow > enow) == (fnow > -enow)) { + detail::op<1,1>::add_fast(&enow, &Q, sum); + enow = *++ebegin; + } else { + detail::op<1,1>::add_fast(&fnow, &Q, sum); + fnow = *++fbegin; + } + Q = sum[1]; + if (sum[0] != 0.0) { + h.push_back(sum[0]); + } + while (ebegin != eend && fbegin != fend) { + if ((fnow > enow) == (fnow > -enow)) { + detail::op<1,1>::add(&Q, &enow, sum); + enow = *++ebegin; + } else { + detail::op<1,1>::add(&Q, &fnow, sum); + fnow = *++fbegin; + } + Q = sum[1]; + if (sum[0] != 0.0) { + h.push_back(sum[0]); + } + } + } + + while (ebegin != eend) { + detail::op<1,1>::add(&Q, &enow, sum); + enow = *++ebegin; + Q = sum[1]; + if (sum[0] != 0.0) { + h.push_back(sum[0]); + } + } + while (fbegin != fend) { + detail::op<1,1>::add(&Q, &fnow, sum); + fnow = *++fbegin; + Q = sum[1]; + if (sum[0] != 0.0) { + h.push_back(sum[0]); + } + } + + if (Q != 0.0 || !h.size()) { + h.push_back(Q); + } + } + + void sum_zeroelim(const exact_t &e, + const exact_t &f, + exact_t &h) { + sum_zeroelim(&e[0], &e[e.size()], &f[0], &f[f.size()], h); + } + + void sum_zeroelim(const double *ebegin, + const double *eend, + const exact_t &f, + exact_t &h) { + sum_zeroelim(ebegin, eend, &f[0], &f[f.size()], h); + } + + void sum_zeroelim(const exact_t &e, + const double *fbegin, + const double *fend, + exact_t &h) { + sum_zeroelim(&e[0], &e[e.size()], fbegin, fend, h); + } + + + // XXX: not implemented yet + //exact_t operator+(const exact_t &a, const exact_t &b) { + //} + + + + void diffprod(const double a, const double b, const double c, const double d, double *r) { + // return ab - cd; + double ab[2], cd[2]; + detail::prod_1_1(&a, &b, ab); + detail::prod_1_1(&c, &d, cd); + detail::op<2,2>::sub(ab, cd, r); + } + + double orient3dexact(const double *pa, + const double *pb, + const double *pc, + const double *pd) { + using namespace detail; + + double ab[4]; diffprod(pa[0], pb[1], pb[0], pa[1], ab); + double bc[4]; diffprod(pb[0], pc[1], pc[0], pb[1], bc); + double cd[4]; diffprod(pc[0], pd[1], pd[0], pc[1], cd); + double da[4]; diffprod(pd[0], pa[1], pa[0], pd[1], da); + double ac[4]; diffprod(pa[0], pc[1], pc[0], pa[1], ac); + double bd[4]; diffprod(pb[0], pd[1], pd[0], pb[1], bd); + + exact_t temp; + exact_t cda, dab, abc, bcd; + exact_t adet, bdet, cdet, ddet, abdet, cddet, det; + + sum_zeroelim(cd, cd + 4, da, da + 4, temp); + sum_zeroelim(temp, ac, ac + 4, cda); + + sum_zeroelim(da, da + 4, ab, ab + 4, temp); + sum_zeroelim(temp, bd, bd + 4, dab); + + negate(bd, bd + 4); + negate(ac, bd + 4); + + sum_zeroelim(ab, ab + 4, bc, bc + 4, temp); + sum_zeroelim(temp, ac, ac + 4, abc); + + sum_zeroelim(bc, bc + 4, cd, cd + 4, temp); + sum_zeroelim(temp, bd, bd + 4, bcd); + + scale_zeroelim(bcd, +pa[2], adet); + scale_zeroelim(cda, -pb[2], bdet); + scale_zeroelim(dab, +pc[2], cdet); + scale_zeroelim(abc, -pd[2], ddet); + + sum_zeroelim(adet, bdet, abdet); + sum_zeroelim(cdet, ddet, cddet); + + sum_zeroelim(abdet, cddet, det); + + return det[det.size() - 1]; + } + + } +} diff -Nru blender-2.61/extern/carve/include/carve/external/boost/random.hpp blender-2.62/extern/carve/include/carve/external/boost/random.hpp --- blender-2.61/extern/carve/include/carve/external/boost/random.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/external/boost/random.hpp 2012-02-15 19:39:24.000000000 +0000 @@ -0,0 +1,773 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +#if !defined(_MSC_VER) +#include +#endif + +namespace boost { + +// type_traits could help here, but I don't want to depend on type_traits. +template +struct ptr_helper +{ + typedef T value_type; + typedef T& reference_type; + typedef const T& rvalue_type; + static reference_type ref(T& r) { return r; } + static const T& ref(const T& r) { return r; } +}; + +template +struct ptr_helper +{ + typedef T value_type; + typedef T& reference_type; + typedef T& rvalue_type; + static reference_type ref(T& r) { return r; } + static const T& ref(const T& r) { return r; } +}; + +template +struct ptr_helper +{ + typedef T value_type; + typedef T& reference_type; + typedef T* rvalue_type; + static reference_type ref(T * p) { return *p; } + static const T& ref(const T * p) { return *p; } +}; + +template +class pass_through_engine +{ +private: + typedef ptr_helper helper_type; + +public: + typedef typename helper_type::value_type base_type; + typedef typename base_type::result_type result_type; + + explicit pass_through_engine(UniformRandomNumberGenerator rng) + // make argument an rvalue to avoid matching Generator& constructor + : _rng(static_cast(rng)) + { } + + result_type min () const { return (base().min)(); } + result_type max () const { return (base().max)(); } + base_type& base() { return helper_type::ref(_rng); } + const base_type& base() const { return helper_type::ref(_rng); } + + result_type operator()() { return base()(); } + +private: + UniformRandomNumberGenerator _rng; +}; + +template +class new_uniform_01 +{ +public: + typedef RealType input_type; + typedef RealType result_type; + // compiler-generated copy ctor and copy assignment are fine + result_type min () const { return result_type(0); } + result_type max () const { return result_type(1); } + void reset() { } + + template + result_type operator()(Engine& eng) { + for (;;) { + typedef typename Engine::result_type base_result; + result_type factor = result_type(1) / + (result_type((eng.max)()-(eng.min)()) + + result_type(std::numeric_limits::is_integer ? 1 : 0)); + result_type result = result_type(eng() - (eng.min)()) * factor; + if (result < result_type(1)) + return result; + } + } + + template + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const new_uniform_01&) + { + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& is, new_uniform_01&) + { + return is; + } +}; + +template +class backward_compatible_uniform_01 +{ + typedef ptr_helper traits; + typedef pass_through_engine internal_engine_type; +public: + typedef UniformRandomNumberGenerator base_type; + typedef RealType result_type; + + static const bool has_fixed_range = false; + + explicit backward_compatible_uniform_01(typename traits::rvalue_type rng) + : _rng(rng), + _factor(result_type(1) / + (result_type((_rng.max)()-(_rng.min)()) + + result_type(std::numeric_limits::is_integer ? 1 : 0))) + { + } + // compiler-generated copy ctor and copy assignment are fine + + result_type min () const { return result_type(0); } + result_type max () const { return result_type(1); } + typename traits::value_type& base() { return _rng.base(); } + const typename traits::value_type& base() const { return _rng.base(); } + void reset() { } + + result_type operator()() { + for (;;) { + result_type result = result_type(_rng() - (_rng.min)()) * _factor; + if (result < result_type(1)) + return result; + } + } + + template + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const backward_compatible_uniform_01& u) + { + os << u._rng; + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& is, backward_compatible_uniform_01& u) + { + is >> u._rng; + return is; + } + +private: + typedef typename internal_engine_type::result_type base_result; + internal_engine_type _rng; + result_type _factor; +}; + +// A definition is required even for integral static constants +template +const bool backward_compatible_uniform_01::has_fixed_range; + +template +struct select_uniform_01 +{ + template + struct apply + { + typedef backward_compatible_uniform_01 type; + }; +}; + +template<> +struct select_uniform_01 +{ + template + struct apply + { + typedef new_uniform_01 type; + }; +}; + +template<> +struct select_uniform_01 +{ + template + struct apply + { + typedef new_uniform_01 type; + }; +}; + +template<> +struct select_uniform_01 +{ + template + struct apply + { + typedef new_uniform_01 type; + }; +}; + +// Because it is so commonly used: uniform distribution on the real [0..1) +// range. This allows for specializations to avoid a costly int -> float +// conversion plus float multiplication +template +class uniform_01 + : public select_uniform_01::template apply::type +{ + typedef typename select_uniform_01::template apply::type impl_type; + typedef ptr_helper traits; +public: + + uniform_01() {} + + explicit uniform_01(typename traits::rvalue_type rng) + : impl_type(rng) + { + } + + template + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const uniform_01& u) + { + os << static_cast(u); + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& is, uniform_01& u) + { + is >> static_cast(u); + return is; + } +}; + +template +class uniform_int_float +{ +public: + typedef UniformRandomNumberGenerator base_type; + typedef IntType result_type; + + uniform_int_float(base_type rng, IntType min_arg = 0, IntType max_arg = 0xffffffff) + : _rng(rng), _min(min_arg), _max(max_arg) + { + init(); + } + + result_type min () const { return _min; } + result_type max () const { return _max; } + base_type& base() { return _rng.base(); } + const base_type& base() const { return _rng.base(); } + + result_type operator()() + { + return static_cast(_rng() * _range) + _min; + } + + template + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const uniform_int_float& ud) + { + os << ud._min << " " << ud._max; + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& is, uniform_int_float& ud) + { + is >> std::ws >> ud._min >> std::ws >> ud._max; + ud.init(); + return is; + } + +private: + void init() + { + _range = static_cast(_max-_min)+1; + } + + typedef typename base_type::result_type base_result; + uniform_01 _rng; + result_type _min, _max; + base_result _range; +}; + + +template +std::basic_ostream& +operator<<( + std::basic_ostream& os + , const pass_through_engine& ud + ) +{ + return os << ud.base(); +} + +template +std::basic_istream& +operator>>( + std::basic_istream& is + , const pass_through_engine& ud + ) +{ + return is >> ud.base(); +} + + + +template +class normal_distribution +{ +public: + typedef RealType input_type; + typedef RealType result_type; + + explicit normal_distribution(const result_type& mean_arg = result_type(0), + const result_type& sigma_arg = result_type(1)) + : _mean(mean_arg), _sigma(sigma_arg), _valid(false) + { + //assert(_sigma >= result_type(0)); + } + + // compiler-generated copy constructor is NOT fine, need to purge cache + normal_distribution(const normal_distribution& other) + : _mean(other._mean), _sigma(other._sigma), _valid(false) + { + } + + // compiler-generated copy ctor and assignment operator are fine + + RealType mean() const { return _mean; } + RealType sigma() const { return _sigma; } + + void reset() { _valid = false; } + + template + result_type operator()(Engine& eng) + { +#ifndef BOOST_NO_STDC_NAMESPACE + // allow for Koenig lookup + using std::sqrt; using std::log; using std::sin; using std::cos; +#endif + if(!_valid) { + _r1 = eng(); + _r2 = eng(); + _cached_rho = sqrt(-result_type(2) * log(result_type(1)-_r2)); + _valid = true; + } else { + _valid = false; + } + // Can we have a boost::mathconst please? + const result_type pi = result_type(3.14159265358979323846); + + return _cached_rho * (_valid ? + cos(result_type(2)*pi*_r1) : + sin(result_type(2)*pi*_r1)) + * _sigma + _mean; + } + +#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS + template + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const normal_distribution& nd) + { + os << nd._mean << " " << nd._sigma << " " + << nd._valid << " " << nd._cached_rho << " " << nd._r1; + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& is, normal_distribution& nd) + { + is >> std::ws >> nd._mean >> std::ws >> nd._sigma + >> std::ws >> nd._valid >> std::ws >> nd._cached_rho + >> std::ws >> nd._r1; + return is; + } +#endif +private: + result_type _mean, _sigma; + result_type _r1, _r2, _cached_rho; + bool _valid; +}; + +// http://www.math.keio.ac.jp/matumoto/emt.html +template +class mersenne_twister +{ +public: + typedef UIntType result_type; + static const int word_size = w; + static const int state_size = n; + static const int shift_size = m; + static const int mask_bits = r; + static const UIntType parameter_a = a; + static const int output_u = u; + static const int output_s = s; + static const UIntType output_b = b; + static const int output_t = t; + static const UIntType output_c = c; + static const int output_l = l; + + static const bool has_fixed_range = false; + + mersenne_twister() { seed(); } + + explicit mersenne_twister(const UIntType& value) + { seed(value); } + template mersenne_twister(It& first, It last) { seed(first,last); } + + template \ + explicit mersenne_twister(Generator& gen) + { seed(gen); } + + // compiler-generated copy ctor and assignment operator are fine + + void seed() { seed(UIntType(5489)); } + + void seed(const UIntType& value) + { + // New seeding algorithm from + // http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html + // In the previous versions, MSBs of the seed affected only MSBs of the + // state x[]. + const UIntType mask = ~0u; + x[0] = value & mask; + for (i = 1; i < n; i++) { + // See Knuth "The Art of Computer Programming" Vol. 2, 3rd ed., page 106 + x[i] = (1812433253UL * (x[i-1] ^ (x[i-1] >> (w-2))) + i) & mask; + } + } + + // For GCC, moving this function out-of-line prevents inlining, which may + // reduce overall object code size. However, MSVC does not grok + // out-of-line definitions of member function templates. + template \ + void seed(Generator& gen) + { +/*#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + BOOST_STATIC_ASSERT(!std::numeric_limits::is_signed); +#endif*/ + // I could have used std::generate_n, but it takes "gen" by value + for(int j = 0; j < n; j++) + x[j] = gen(); + i = n; + } + + template + void seed(It& first, It last) + { + int j; + for(j = 0; j < n && first != last; ++j, ++first) + x[j] = *first; + i = n; + if(first == last && j < n) + throw std::invalid_argument("mersenne_twister::seed"); + } + + result_type min () const { return 0; } + result_type max () const + { + // avoid "left shift count >= with of type" warning + result_type res = 0; + for(int j = 0; j < w; ++j) + res |= (1u << j); + return res; + } + + result_type operator()(); + static bool validation(result_type v) { return val == v; } + + template + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const mersenne_twister& mt) + { + for(int j = 0; j < mt.state_size; ++j) + os << mt.compute(j) << " "; + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& is, mersenne_twister& mt) + { + for(int j = 0; j < mt.state_size; ++j) + is >> mt.x[j] >> std::ws; + // MSVC (up to 7.1) and Borland (up to 5.64) don't handle the template + // value parameter "n" available from the class template scope, so use + // the static constant with the same value + mt.i = mt.state_size; + return is; + } + + friend bool operator==(const mersenne_twister& x, const mersenne_twister& y) + { + for(int j = 0; j < state_size; ++j) + if(x.compute(j) != y.compute(j)) + return false; + return true; + } + + friend bool operator!=(const mersenne_twister& x, const mersenne_twister& y) + { return !(x == y); } + +private: + // returns x(i-n+index), where index is in 0..n-1 + UIntType compute(unsigned int index) const + { + // equivalent to (i-n+index) % 2n, but doesn't produce negative numbers + return x[ (i + n + index) % (2*n) ]; + } + void twist(int block); + + // state representation: next output is o(x(i)) + // x[0] ... x[k] x[k+1] ... x[n-1] x[n] ... x[2*n-1] represents + // x(i-k) ... x(i) x(i+1) ... x(i-k+n-1) x(i-k-n) ... x[i(i-k-1)] + // The goal is to always have x(i-n) ... x(i-1) available for + // operator== and save/restore. + + UIntType x[2*n]; + int i; +}; + +// A definition is required even for integral static constants + +template +const bool mersenne_twister::has_fixed_range; +template +const int mersenne_twister::state_size; +template +const int mersenne_twister::shift_size; +template +const int mersenne_twister::mask_bits; +template +const UIntType mersenne_twister::parameter_a; +template +const int mersenne_twister::output_u; +template +const int mersenne_twister::output_s; +template +const UIntType mersenne_twister::output_b; +template +const int mersenne_twister::output_t; +template +const UIntType mersenne_twister::output_c; +template +const int mersenne_twister::output_l; + +template +void mersenne_twister::twist(int block) +{ + const UIntType upper_mask = (~0u) << r; + const UIntType lower_mask = ~upper_mask; + + if(block == 0) { + for(int j = n; j < 2*n; j++) { + UIntType y = (x[j-n] & upper_mask) | (x[j-(n-1)] & lower_mask); + x[j] = x[j-(n-m)] ^ (y >> 1) ^ (y&1 ? a : 0); + } + } else if (block == 1) { + // split loop to avoid costly modulo operations + { // extra scope for MSVC brokenness w.r.t. for scope + for(int j = 0; j < n-m; j++) { + UIntType y = (x[j+n] & upper_mask) | (x[j+n+1] & lower_mask); + x[j] = x[j+n+m] ^ (y >> 1) ^ (y&1 ? a : 0); + } + } + + for(int j = n-m; j < n-1; j++) { + UIntType y = (x[j+n] & upper_mask) | (x[j+n+1] & lower_mask); + x[j] = x[j-(n-m)] ^ (y >> 1) ^ (y&1 ? a : 0); + } + // last iteration + UIntType y = (x[2*n-1] & upper_mask) | (x[0] & lower_mask); + x[n-1] = x[m-1] ^ (y >> 1) ^ (y&1 ? a : 0); + i = 0; + } +} + +template +inline typename mersenne_twister::result_type +mersenne_twister::operator()() +{ + if(i == n) + twist(0); + else if(i >= 2*n) + twist(1); + // Step 4 + UIntType z = x[i]; + ++i; + z ^= (z >> u); + z ^= ((z << s) & b); + z ^= ((z << t) & c); + z ^= (z >> l); + return z; +} + +typedef mersenne_twister mt11213b; + +// validation by experiment from mt19937.c +typedef mersenne_twister mt19937; + + +template > +class uniform_on_sphere +{ +public: + typedef RealType input_type; + typedef Cont result_type; + + explicit uniform_on_sphere(int dim = 2) : _container(dim), _dim(dim) { } + + // compiler-generated copy ctor and assignment operator are fine + + void reset() { _normal.reset(); } + + template + const result_type & operator()(Engine& eng) + { + RealType sqsum = 0; + for(typename Cont::iterator it = _container.begin(); + it != _container.end(); + ++it) { + RealType val = _normal(eng); + *it = val; + sqsum += val * val; + } + using std::sqrt; + // for all i: result[i] /= sqrt(sqsum) + std::transform(_container.begin(), _container.end(), _container.begin(), + std::bind2nd(std::divides(), sqrt(sqsum))); + return _container; + } + + template + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const uniform_on_sphere& sd) + { + os << sd._dim; + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& is, uniform_on_sphere& sd) + { + is >> std::ws >> sd._dim; + sd._container.resize(sd._dim); + return is; + } + +private: + normal_distribution _normal; + result_type _container; + int _dim; +}; + + + +template +struct engine_helper; + + +template<> +struct engine_helper +{ + template + struct impl + { + typedef pass_through_engine type; + }; +}; + +template<> +struct engine_helper +{ + template + struct impl + { + typedef uniform_01 type; + }; +}; + +template<> +struct engine_helper +{ + template + struct impl + { + typedef uniform_01 type; + }; +}; + +template<> +struct engine_helper +{ + template + struct impl + { + typedef uniform_int_float type; + }; +}; + +template +class variate_generator +{ +private: + typedef pass_through_engine decorated_engine; + +public: + typedef typename decorated_engine::base_type engine_value_type; + typedef Engine engine_type; + typedef Distribution distribution_type; + typedef typename Distribution::result_type result_type; + + variate_generator(Engine e, Distribution d) + : _eng(decorated_engine(e)), _dist(d) { } + + result_type operator()() { return _dist(_eng); } + template + result_type operator()(T value) { return _dist(_eng, value); } + + engine_value_type& engine() { return _eng.base().base(); } + const engine_value_type& engine() const { return _eng.base().base(); } + + distribution_type& distribution() { return _dist; } + const distribution_type& distribution() const { return _dist; } + + result_type min () const { return (distribution().min)(); } + result_type max () const { return (distribution().max)(); } + +private: + enum { + have_int = std::numeric_limits::is_integer, + want_int = std::numeric_limits::is_integer + }; + typedef typename engine_helper::template impl::type internal_engine_type; + + internal_engine_type _eng; + distribution_type _dist; +}; + +} // namespace boost diff -Nru blender-2.61/extern/carve/include/carve/face_decl.hpp blender-2.62/extern/carve/include/carve/face_decl.hpp --- blender-2.61/extern/carve/include/carve/face_decl.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/face_decl.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,208 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace carve { + namespace poly { + + + + struct Object; + + template + class Edge; + + + + template + struct p2_adapt_project { + typedef carve::geom2d::P2 (*proj_t)(const carve::geom::vector &); + proj_t proj; + p2_adapt_project(proj_t _proj) : proj(_proj) { } + carve::geom2d::P2 operator()(const carve::geom::vector &v) const { return proj(v); } + carve::geom2d::P2 operator()(const carve::geom::vector *v) const { return proj(*v); } + carve::geom2d::P2 operator()(const Vertex &v) const { return proj(v.v); } + carve::geom2d::P2 operator()(const Vertex *v) const { return proj(v->v); } + }; + + + template + class Face : public tagable { + public: + typedef Vertex vertex_t; + typedef typename Vertex::vector_t vector_t; + typedef Edge edge_t; + typedef Object obj_t; + typedef carve::geom::aabb aabb_t; + typedef carve::geom::plane plane_t; + + typedef carve::geom2d::P2 (*project_t)(const vector_t &); + typedef vector_t (*unproject_t)(const carve::geom2d::P2 &, const plane_t &); + + protected: + std::vector vertices; // pointer into polyhedron.vertices + std::vector edges; // pointer into polyhedron.edges + + project_t getProjector(bool positive_facing, int axis); + unproject_t getUnprojector(bool positive_facing, int axis); + + public: + typedef typename std::vector::iterator vertex_iter_t; + typedef typename std::vector::const_iterator const_vertex_iter_t; + + typedef typename std::vector::iterator edge_iter_t; + typedef typename std::vector::const_iterator const_edge_iter_t; + + obj_t *owner; + + aabb_t aabb; + plane_t plane_eqn; + int manifold_id; + int group_id; + + project_t project; + unproject_t unproject; + + Face(const std::vector &_vertices, bool delay_recalc = false); + Face(const vertex_t *v1, const vertex_t *v2, const vertex_t *v3, bool delay_recalc = false); + Face(const vertex_t *v1, const vertex_t *v2, const vertex_t *v3, const vertex_t *v4, bool delay_recalc = false); + + template + Face(const Face *base, iter_t vbegin, iter_t vend, bool flipped) { + init(base, vbegin, vend, flipped); + } + + Face(const Face *base, const std::vector &_vertices, bool flipped) { + init(base, _vertices, flipped); + } + + Face() {} + ~Face() {} + + bool recalc(); + + template + Face *init(const Face *base, iter_t vbegin, iter_t vend, bool flipped); + Face *init(const Face *base, const std::vector &_vertices, bool flipped); + + template + Face *create(iter_t vbegin, iter_t vend, bool flipped) const; + Face *create(const std::vector &_vertices, bool flipped) const; + + Face *clone(bool flipped = false) const; + void invert(); + + void getVertexLoop(std::vector &loop) const; + + const vertex_t *&vertex(size_t idx); + const vertex_t *vertex(size_t idx) const; + size_t nVertices() const; + + vertex_iter_t vbegin() { return vertices.begin(); } + vertex_iter_t vend() { return vertices.end(); } + const_vertex_iter_t vbegin() const { return vertices.begin(); } + const_vertex_iter_t vend() const { return vertices.end(); } + + std::vector > projectedVertices() const; + + const edge_t *&edge(size_t idx); + const edge_t *edge(size_t idx) const; + size_t nEdges() const; + + edge_iter_t ebegin() { return edges.begin(); } + edge_iter_t eend() { return edges.end(); } + const_edge_iter_t ebegin() const { return edges.begin(); } + const_edge_iter_t eend() const { return edges.end(); } + + bool containsPoint(const vector_t &p) const; + bool containsPointInProjection(const vector_t &p) const; + bool simpleLineSegmentIntersection(const carve::geom::linesegment &line, + vector_t &intersection) const; + IntersectionClass lineSegmentIntersection(const carve::geom::linesegment &line, + vector_t &intersection) const; + vector_t centroid() const; + + p2_adapt_project projector() const { + return p2_adapt_project(project); + } + + void swap(Face &other); + }; + + + + struct hash_face_ptr { + template + size_t operator()(const Face * const &f) const { + return (size_t)f; + } + }; + + + + namespace face { + + + + template + static inline carve::geom2d::P2 project(const Face *f, const typename Face::vector_t &v) { + return f->project(v); + } + + + + template + static inline carve::geom2d::P2 project(const Face &f, const typename Face::vector_t &v) { + return f.project(v); + } + + + + template + static inline typename Face::vector_t unproject(const Face *f, const carve::geom2d::P2 &p) { + return f->unproject(p, f->plane_eqn); + } + + + + template + static inline typename Face::vector_t unproject(const Face &f, const carve::geom2d::P2 &p) { + return f.unproject(p, f.plane_eqn); + } + + + + } + + + + } +} diff -Nru blender-2.61/extern/carve/include/carve/face_impl.hpp blender-2.62/extern/carve/include/carve/face_impl.hpp --- blender-2.61/extern/carve/include/carve/face_impl.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/face_impl.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,140 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +namespace std { + template + inline void swap(carve::poly::Face &a, carve::poly::Face &b) { + a.swap(b); + } +} + +namespace carve { + namespace poly { + template + void Face::swap(Face &other) { + std::swap(vertices, other.vertices); + std::swap(edges, other.edges); + std::swap(owner, other.owner); + std::swap(aabb, other.aabb); + std::swap(plane_eqn, other.plane_eqn); + std::swap(manifold_id, other.manifold_id); + std::swap(group_id, other.group_id); + std::swap(project, other.project); + std::swap(unproject, other.unproject); + } + + template + template + Face *Face::init(const Face *base, iter_t vbegin, iter_t vend, bool flipped) { + vertices.reserve(std::distance(vbegin, vend)); + + if (flipped) { + std::reverse_copy(vbegin, vend, std::back_inserter(vertices)); + plane_eqn = -base->plane_eqn; + } else { + std::copy(vbegin, vend, std::back_inserter(vertices)); + plane_eqn = base->plane_eqn; + } + + edges.clear(); + edges.resize(nVertices(), NULL); + + aabb.fit(vertices.begin(), vertices.end(), vec_adapt_vertex_ptr()); + untag(); + + int da = carve::geom::largestAxis(plane_eqn.N); + + project = getProjector(plane_eqn.N.v[da] > 0, da); + unproject = getUnprojector(plane_eqn.N.v[da] > 0, da); + + return this; + } + + template + template + Face *Face::create(iter_t vbegin, iter_t vend, bool flipped) const { + return (new Face)->init(this, vbegin, vend, flipped); + } + + template + Face *Face::create(const std::vector &_vertices, bool flipped) const { + return (new Face)->init(this, _vertices.begin(), _vertices.end(), flipped); + } + + template + Face *Face::clone(bool flipped) const { + return (new Face)->init(this, vertices, flipped); + } + + template + void Face::getVertexLoop(std::vector &loop) const { + loop.resize(nVertices(), NULL); + std::copy(vbegin(), vend(), loop.begin()); + } + + template + const typename Face::edge_t *&Face::edge(size_t idx) { + return edges[idx]; + } + + template + const typename Face::edge_t *Face::edge(size_t idx) const { + return edges[idx]; + } + + template + size_t Face::nEdges() const { + return edges.size(); + } + + template + const typename Face::vertex_t *&Face::vertex(size_t idx) { + return vertices[idx]; + } + + template + const typename Face::vertex_t *Face::vertex(size_t idx) const { + return vertices[idx]; + } + + template + size_t Face::nVertices() const { + return vertices.size(); + } + + template + typename Face::vector_t Face::centroid() const { + vector_t c; + carve::geom::centroid(vertices.begin(), vertices.end(), vec_adapt_vertex_ptr(), c); + return c; + } + + template + std::vector > Face::projectedVertices() const { + p2_adapt_project proj = projector(); + std::vector > result; + result.reserve(nVertices()); + for (size_t i = 0; i < nVertices(); ++i) { + result.push_back(proj(vertex(i)->v)); + } + return result; + } + + } +} diff -Nru blender-2.61/extern/carve/include/carve/faceloop.hpp blender-2.62/extern/carve/include/carve/faceloop.hpp --- blender-2.61/extern/carve/include/carve/faceloop.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/faceloop.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,103 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include +#include +#include + +namespace carve { + namespace csg { + + struct FaceLoopGroup; + + struct FaceLoop { + FaceLoop *next, *prev; + const carve::mesh::MeshSet<3>::face_t *orig_face; + std::vector::vertex_t *> vertices; + FaceLoopGroup *group; + + FaceLoop(const carve::mesh::MeshSet<3>::face_t *f, const std::vector::vertex_t *> &v) : next(NULL), prev(NULL), orig_face(f), vertices(v), group(NULL) {} + }; + + + struct FaceLoopList { + FaceLoop *head, *tail; + unsigned count; + + FaceLoopList() : head(NULL), tail(NULL), count(0) { } + + void append(FaceLoop *f) { + f->prev = tail; + f->next = NULL; + if (tail) tail->next = f; + tail = f; + if (!head) head = f; + count++; + } + + void prepend(FaceLoop *f) { + f->next = head; + f->prev = NULL; + if (head) head->prev = f; + head = f; + if (!tail) tail = f; + count++; + } + + unsigned size() const { + return count; + } + + FaceLoop *remove(FaceLoop *f) { + FaceLoop *r = f->next; + if (f->prev) { f->prev->next = f->next; } else { head = f->next; } + if (f->next) { f->next->prev = f->prev; } else { tail = f->prev; } + f->next = f->prev = NULL; + count--; + return r; + } + + ~FaceLoopList() { + FaceLoop *a = head, *b; + while (a) { + b = a; + a = a->next; + delete b; + } + } + }; + + struct FaceLoopGroup { + const carve::mesh::MeshSet<3> *src; + FaceLoopList face_loops; + V2Set perimeter; + std::list classification; + + FaceLoopGroup(const carve::mesh::MeshSet<3> *_src) : src(_src) { + } + + FaceClass classificationAgainst(const carve::mesh::MeshSet<3>::mesh_t *mesh) const; + }; + + + + typedef std::list FLGroupList; + + } +} diff -Nru blender-2.61/extern/carve/include/carve/geom2d.hpp blender-2.62/extern/carve/include/carve/geom2d.hpp --- blender-2.61/extern/carve/include/carve/geom2d.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/geom2d.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,403 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +#include +#include + +#include + +#include +#include + +#include + +#if defined(CARVE_DEBUG) +# include +#endif + +#if defined CARVE_USE_EXACT_PREDICATES +# include +#endif + +namespace carve { + namespace geom2d { + + typedef carve::geom::vector<2> P2; + typedef carve::geom::ray<2> Ray2; + typedef carve::geom::linesegment<2> LineSegment2; + + + + struct p2_adapt_ident { + P2 &operator()(P2 &p) const { return p; } + const P2 &operator()(const P2 &p) const { return p; } + }; + + + + typedef std::vector P2Vector; + + /** + * \brief Return the orientation of c with respect to the ray defined by a->b. + * + * (Can be implemented exactly) + * + * @param[in] a + * @param[in] b + * @param[in] c + * + * @return positive, if c to the left of a->b. + * zero, if c is colinear with a->b. + * negative, if c to the right of a->b. + */ +#if defined CARVE_USE_EXACT_PREDICATES + inline double orient2d(const P2 &a, const P2 &b, const P2 &c) { + return shewchuk::orient2d(a.v, b.v, c.v); + } +#else + inline double orient2d(const P2 &a, const P2 &b, const P2 &c) { + double acx = a.x - c.x; + double bcx = b.x - c.x; + double acy = a.y - c.y; + double bcy = b.y - c.y; + return acx * bcy - acy * bcx; + } +#endif + + /** + * \brief Determine whether p is internal to the anticlockwise + * angle abc, where b is the apex of the angle. + * + * @param[in] a + * @param[in] b + * @param[in] c + * @param[in] p + * + * @return true, if p is contained in the anticlockwise angle from + * b->a to b->c. Reflex angles contain p if p lies + * on b->a or on b->c. Acute angles do not contain p + * if p lies on b->a or on b->c. This is so that + * internalToAngle(a,b,c,p) = !internalToAngle(c,b,a,p) + */ + inline bool internalToAngle(const P2 &a, + const P2 &b, + const P2 &c, + const P2 &p) { + bool reflex = (a < c) ? orient2d(b, a, c) <= 0.0 : orient2d(b, c, a) > 0.0; + double d1 = orient2d(b, a, p); + double d2 = orient2d(b, c, p); + if (reflex) { + return d1 >= 0.0 || d2 <= 0.0; + } else { + return d1 > 0.0 && d2 < 0.0; + } + } + + /** + * \brief Determine whether p is internal to the anticlockwise + * angle ac, with apex at (0,0). + * + * @param[in] a + * @param[in] c + * @param[in] p + * + * @return true, if p is contained in a0c. + */ + inline bool internalToAngle(const P2 &a, + const P2 &c, + const P2 &p) { + return internalToAngle(a, P2::ZERO(), c, p); + } + + template + bool isAnticlockwise(const P2vec &tri) { + return orient2d(tri[0], tri[1], tri[2]) > 0.0; + } + + template + bool pointIntersectsTriangle(const P2 &p, const P2vec &tri) { + int orient = isAnticlockwise(tri) ? +1 : -1; + if (orient2d(tri[0], tri[1], p) * orient < 0) return false; + if (orient2d(tri[1], tri[2], p) * orient < 0) return false; + if (orient2d(tri[2], tri[0], p) * orient < 0) return false; + return true; + } + + template + bool lineIntersectsTriangle(const P2 &p1, const P2 &p2, const P2vec &tri) { + double s[3]; + // does tri lie on one side or the other of p1-p2? + s[0] = orient2d(p1, p2, tri[0]); + s[1] = orient2d(p1, p2, tri[1]); + s[2] = orient2d(p1, p2, tri[2]); + if (*std::max_element(s, s+3) < 0) return false; + if (*std::min_element(s, s+3) > 0) return false; + + // does line lie entirely to the right of a triangle edge? + int orient = isAnticlockwise(tri) ? +1 : -1; + if (orient2d(tri[0], tri[1], p1) * orient < 0 && orient2d(tri[0], tri[1], p2) * orient < 0) return false; + if (orient2d(tri[1], tri[2], p1) * orient < 0 && orient2d(tri[1], tri[2], p2) * orient < 0) return false; + if (orient2d(tri[2], tri[0], p1) * orient < 0 && orient2d(tri[2], tri[0], p2) * orient < 0) return false; + return true; + } + + template + int triangleLineOrientation(const P2 &p1, const P2 &p2, const P2vec &tri) { + double lo, hi, tmp; + lo = hi = orient2d(p1, p2, tri[0]); + tmp = orient2d(p1, p2, tri[1]); lo = std::min(lo, tmp); hi = std::max(hi, tmp); + tmp = orient2d(p1, p2, tri[2]); lo = std::min(lo, tmp); hi = std::max(hi, tmp); + if (hi < 0.0) return -1; + if (lo > 0.0) return +1; + return 0; + } + + template + bool triangleIntersectsTriangle(const P2vec &tri_b, const P2vec &tri_a) { + int orient_a = isAnticlockwise(tri_a) ? +1 : -1; + if (triangleLineOrientation(tri_a[0], tri_a[1], tri_b) * orient_a < 0) return false; + if (triangleLineOrientation(tri_a[1], tri_a[2], tri_b) * orient_a < 0) return false; + if (triangleLineOrientation(tri_a[2], tri_a[0], tri_b) * orient_a < 0) return false; + + int orient_b = isAnticlockwise(tri_b) ? +1 : -1; + if (triangleLineOrientation(tri_b[0], tri_b[1], tri_a) * orient_b < 0) return false; + if (triangleLineOrientation(tri_b[1], tri_b[2], tri_a) * orient_b < 0) return false; + if (triangleLineOrientation(tri_b[2], tri_b[0], tri_a) * orient_b < 0) return false; + + return true; + } + + + + static inline double atan2(const P2 &p) { + return ::atan2(p.y, p.x); + } + + + + struct LineIntersectionInfo { + LineIntersectionClass iclass; + P2 ipoint; + int p1, p2; + + LineIntersectionInfo(LineIntersectionClass _iclass, + P2 _ipoint = P2::ZERO(), + int _p1 = -1, + int _p2 = -1) : + iclass(_iclass), ipoint(_ipoint), p1(_p1), p2(_p2) { + } + }; + + struct PolyInclusionInfo { + PointClass iclass; + int iobjnum; + + PolyInclusionInfo(PointClass _iclass, + int _iobjnum = -1) : + iclass(_iclass), iobjnum(_iobjnum) { + } + }; + + struct PolyIntersectionInfo { + IntersectionClass iclass; + P2 ipoint; + size_t iobjnum; + + PolyIntersectionInfo(IntersectionClass _iclass, + const P2 &_ipoint, + size_t _iobjnum) : + iclass(_iclass), ipoint(_ipoint), iobjnum(_iobjnum) { + } + }; + + bool lineSegmentIntersection_simple(const P2 &l1v1, const P2 &l1v2, + const P2 &l2v1, const P2 &l2v2); + bool lineSegmentIntersection_simple(const LineSegment2 &l1, + const LineSegment2 &l2); + + LineIntersectionInfo lineSegmentIntersection(const P2 &l1v1, const P2 &l1v2, + const P2 &l2v1, const P2 &l2v2); + LineIntersectionInfo lineSegmentIntersection(const LineSegment2 &l1, + const LineSegment2 &l2); + + int lineSegmentPolyIntersections(const std::vector &points, + LineSegment2 line, + std::vector &out); + + int sortedLineSegmentPolyIntersections(const std::vector &points, + LineSegment2 line, + std::vector &out); + + + + static inline bool quadIsConvex(const P2 &a, const P2 &b, const P2 &c, const P2 &d) { + double s_1, s_2; + + s_1 = carve::geom2d::orient2d(a, c, b); + s_2 = carve::geom2d::orient2d(a, c, d); + if ((s_1 < 0.0 && s_2 < 0.0) || (s_1 > 0.0 && s_2 > 0.0)) return false; + + s_1 = carve::geom2d::orient2d(b, d, a); + s_2 = carve::geom2d::orient2d(b, d, c); + if ((s_1 < 0.0 && s_2 < 0.0) || (s_1 > 0.0 && s_2 > 0.0)) return false; + + return true; + } + + template + inline bool quadIsConvex(const T &a, const T &b, const T &c, const T &d, adapt_t adapt) { + return quadIsConvex(adapt(a), adapt(b), adapt(c), adapt(d)); + } + + + + double signedArea(const std::vector &points); + + static inline double signedArea(const P2 &a, const P2 &b, const P2 &c) { + return ((b.y + a.y) * (b.x - a.x) + (c.y + b.y) * (c.x - b.x) + (a.y + c.y) * (a.x - c.x)) / 2.0; + } + + template + double signedArea(const std::vector &points, adapt_t adapt) { + P2Vector::size_type l = points.size(); + double A = 0.0; + + for (P2Vector::size_type i = 0; i < l - 1; i++) { + A += (adapt(points[i + 1]).y + adapt(points[i]).y) * (adapt(points[i + 1]).x - adapt(points[i]).x); + } + A += (adapt(points[0]).y + adapt(points[l - 1]).y) * (adapt(points[0]).x - adapt(points[l - 1]).x); + + return A / 2.0; + } + + + + template + double signedArea(iter_t begin, iter_t end, adapt_t adapt) { + double A = 0.0; + P2 p, n; + + if (begin == end) return 0.0; + + p = adapt(*begin); + for (iter_t c = begin; ++c != end; ) { + P2 n = adapt(*c); + A += (n.y + p.y) * (n.x - p.x); + p = n; + } + n = adapt(*begin); + A += (n.y + p.y) * (n.x - p.x); + + return A / 2.0; + } + + + + bool pointInPolySimple(const std::vector &points, const P2 &p); + + template + bool pointInPolySimple(const std::vector &points, adapt_t adapt, const P2 &p) { + CARVE_ASSERT(points.size() > 0); + P2Vector::size_type l = points.size(); + double s = 0.0; + double rp, r0, d; + + rp = r0 = atan2(adapt(points[0]) - p); + + for (P2Vector::size_type i = 1; i < l; i++) { + double r = atan2(adapt(points[i]) - p); + d = r - rp; + if (d > M_PI) d -= M_TWOPI; + if (d < -M_PI) d += M_TWOPI; + s = s + d; + rp = r; + } + + d = r0 - rp; + if (d > M_PI) d -= M_TWOPI; + if (d < -M_PI) d += M_TWOPI; + s = s + d; + + return !carve::math::ZERO(s); + } + + + + PolyInclusionInfo pointInPoly(const std::vector &points, const P2 &p); + + template + PolyInclusionInfo pointInPoly(const std::vector &points, adapt_t adapt, const P2 &p) { + P2Vector::size_type l = points.size(); + for (unsigned i = 0; i < l; i++) { + if (equal(adapt(points[i]), p)) return PolyInclusionInfo(POINT_VERTEX, i); + } + + for (unsigned i = 0; i < l; i++) { + unsigned j = (i + 1) % l; + + if (std::min(adapt(points[i]).x, adapt(points[j]).x) - EPSILON < p.x && + std::max(adapt(points[i]).x, adapt(points[j]).x) + EPSILON > p.x && + std::min(adapt(points[i]).y, adapt(points[j]).y) - EPSILON < p.y && + std::max(adapt(points[i]).y, adapt(points[j]).y) + EPSILON > p.y && + distance2(carve::geom::rayThrough(adapt(points[i]), adapt(points[j])), p) < EPSILON2) { + return PolyInclusionInfo(POINT_EDGE, i); + } + } + + if (pointInPolySimple(points, adapt, p)) { + return PolyInclusionInfo(POINT_IN); + } + + return PolyInclusionInfo(POINT_OUT); + } + + + + bool pickContainedPoint(const std::vector &poly, P2 &result); + + template + bool pickContainedPoint(const std::vector &poly, adapt_t adapt, P2 &result) { +#if defined(CARVE_DEBUG) + std::cerr << "pickContainedPoint "; + for (unsigned i = 0; i < poly.size(); ++i) std::cerr << " " << adapt(poly[i]); + std::cerr << std::endl; +#endif + + const size_t S = poly.size(); + P2 a, b, c; + for (unsigned i = 0; i < S; ++i) { + a = adapt(poly[i]); + b = adapt(poly[(i + 1) % S]); + c = adapt(poly[(i + 2) % S]); + + if (cross(a - b, c - b) < 0) { + P2 p = (a + b + c) / 3; + if (pointInPolySimple(poly, adapt, p)) { + result = p; + return true; + } + } + } + return false; + } + + } +} diff -Nru blender-2.61/extern/carve/include/carve/geom3d.hpp blender-2.62/extern/carve/include/carve/geom3d.hpp --- blender-2.61/extern/carve/include/carve/geom3d.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/geom3d.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,310 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include +#include + +#include +#include + +#include +#include +#include + +#if defined(CARVE_DEBUG) +# include +#endif + +#if defined CARVE_USE_EXACT_PREDICATES +# include +#endif + +namespace carve { + namespace geom3d { + + typedef carve::geom::plane<3> Plane; + typedef carve::geom::ray<3> Ray; + typedef carve::geom::linesegment<3> LineSegment; + typedef carve::geom::vector<3> Vector; + + template + bool fitPlane(iter_t begin, iter_t end, adapt_t adapt, Plane &plane) { + Vector centroid; + carve::geom::centroid(begin, end, adapt, centroid); + iter_t i; + + Vector n = Vector::ZERO(); + Vector v; + Vector p1, p2, p3, c1, c2; + if (begin == end) return false; + + i = begin; + p1 = c1 = adapt(*i); if (++i == end) return false; + p2 = c2 = adapt(*i); if (++i == end) return false; + +#if defined(CARVE_DEBUG) + size_t N = 2; +#endif + do { + p3 = adapt(*i); + v = cross(p3 - p2, p1 - p2); + if (v.v[largestAxis(v)]) v.negate(); + n += v; + p1 = p2; p2 = p3; +#if defined(CARVE_DEBUG) + ++N; +#endif + } while (++i != end); + + p1 = p2; p2 = p3; p3 = c1; + v = cross(p3 - p2, p1 - p2); + if (v.v[largestAxis(v)]) v.negate(); + n += v; + + p1 = p2; p2 = p3; p3 = c2; + v = cross(p3 - p2, p1 - p2); + if (v.v[largestAxis(v)]) v.negate(); + n += v; + + n.normalize(); + plane.N = n; + plane.d = -dot(n, centroid); +#if defined(CARVE_DEBUG) + if (N > 3) { + std::cerr << "N = " << N << " fitted distance:"; + for (i = begin; i != end; ++i) { + Vector p = adapt(*i); + std::cerr << " {" << p << "} " << distance(plane, p); + } + std::cerr << std::endl; + } +#endif + return true; + } + + bool planeIntersection(const Plane &a, const Plane &b, Ray &r); + + IntersectionClass rayPlaneIntersection(const Plane &p, + const Vector &v1, + const Vector &v2, + Vector &v, + double &t); + + IntersectionClass lineSegmentPlaneIntersection(const Plane &p, + const LineSegment &line, + Vector &v); + + RayIntersectionClass rayRayIntersection(const Ray &r1, + const Ray &r2, + Vector &v1, + Vector &v2, + double &mu1, + double &mu2); + + + + // test whether point d is above, below or on the plane formed by the triangle a,b,c. + // return: +ve = d is below a,b,c + // -ve = d is above a,b,c + // 0 = d is on a,b,c +#if defined CARVE_USE_EXACT_PREDICATES + inline double orient3d(const Vector &a, + const Vector &b, + const Vector &c, + const Vector &d) { + return shewchuk::orient3d(a.v, b.v, c.v, d.v); + } +#else + inline double orient3d(const Vector &a, + const Vector &b, + const Vector &c, + const Vector &d) { + return dotcross((a - d), (b - d), (c - d)); + } +#endif + + // Volume of a tetrahedron described by 4 points. Will be + // positive if the anticlockwise normal of a,b,c is oriented out + // of the tetrahedron. + // + // see: http://mathworld.wolfram.com/Tetrahedron.html + inline double tetrahedronVolume(const Vector &a, + const Vector &b, + const Vector &c, + const Vector &d) { + return dotcross((a - d), (b - d), (c - d)) / 6.0; + } + + /** + * \brief Determine whether p is internal to the wedge defined by + * the area between the planes defined by a,b,c and a,b,d + * angle abc, where ab is the apex of the angle. + * + * @param[in] a + * @param[in] b + * @param[in] c + * @param[in] d + * @param[in] p + * + * @return true, if p is contained in the wedge defined by the + * area between the planes defined by a,b,c and + * a,b,d. If the wedge is reflex, p is considered to + * be contained if it lies on either plane. Acute + * wdges do not contain p if p lies on either + * plane. This is so that internalToWedge(a,b,c,d,p) = + * !internalToWedge(a,b,d,c,p) + */ + inline bool internalToWedge(const Vector &a, + const Vector &b, + const Vector &c, + const Vector &d, + const Vector &p) { + bool reflex = (c < d) ? + orient3d(a, b, c, d) >= 0.0 : + orient3d(a, b, d, c) < 0.0; + + double d1 = orient3d(a, b, c, p); + double d2 = orient3d(a, b, d, p); + + if (reflex) { + // above a,b,c or below a,b,d (or coplanar with either) + return d1 <= 0.0 || d2 >= 0.0; + } else { + // above a,b,c and below a,b,d + return d1 < 0.0 && d2 > 0.0; + } + } + + /** + * \brief Determine the ordering relationship of a and b, when + * rotating around direction, starting from base. + * + * @param[in] adirection + * @param[in] base + * @param[in] a + * @param[in] b + * + * @return + * * -1, if a is ordered before b around, rotating about direction. + * * 0, if a and b are equal in angle. + * * +1, if a is ordered after b around, rotating about direction. + */ + inline int compareAngles(const Vector &direction, const Vector &base, const Vector &a, const Vector &b) { + const double d1 = carve::geom3d::orient3d(carve::geom::VECTOR(0,0,0), direction, a, b); + const double d2 = carve::geom3d::orient3d(carve::geom::VECTOR(0,0,0), direction, base, a); + const double d3 = carve::geom3d::orient3d(carve::geom::VECTOR(0,0,0), direction, base, b); + + // CASE: a and b are coplanar wrt. direction. + if (d1 == 0.0) { + // a and b point in the same direction. + if (dot(a, b) > 0.0) { + // Neither is less than the other. + return 0; + } + + // a and b point in opposite directions. + // * if d2 < 0.0, a is above plane(direction, base) and is less + // than b. + // * if d2 == 0.0 a is coplanar with plane(direction, base) and is + // less than b if it points in the same direction as base. + // * if d2 > 0.0, a is below plane(direction, base) and is greater + // than b. + + if (d2 == 0.0) { return dot(a, base) > 0.0 ? -1 : +1; } + if (d3 == 0.0) { return dot(b, base) > 0.0 ? +1 : -1; } + if (d2 < 0.0 && d3 > 0.0) return -1; + if (d2 > 0.0 && d3 < 0.0) return +1; + + // both a and b are to one side of plane(direction, base) - + // rounding error (if a and b are truly coplanar with + // direction, one should be above, and one should be below any + // other plane that is not itself coplanar with + // plane(direction, a|b) - which would imply d2 and d3 == 0.0). + + // If both are below plane(direction, base) then the one that + // points in the same direction as base is greater. + // If both are above plane(direction, base) then the one that + // points in the same direction as base is lesser. + if (d2 > 0.0) { return dot(a, base) > 0.0 ? +1 : -1; } + else { return dot(a, base) > 0.0 ? -1 : +1; } + } + + // CASE: a and b are not coplanar wrt. direction + + if (d2 < 0.0) { + // if a is above plane(direction,base), then a is less than b if + // b is below plane(direction,base) or b is above plane(direction,a) + return (d3 > 0.0 || d1 < 0.0) ? -1 : +1; + } else if (d2 == 0.0) { + // if a is on plane(direction,base) then a is less than b if a + // points in the same direction as base, or b is below + // plane(direction,base) + return (dot(a, base) > 0.0 || d3 > 0.0) ? -1 : +1; + } else { + // if a is below plane(direction,base), then a is less than b if b + // is below plane(direction,base) and b is above plane(direction,a) + return (d3 > 0.0 && d1 < 0.0) ? -1 : +1; + } + } + + // The anticlockwise angle from vector "from" to vector "to", oriented around the vector "orient". + static inline double antiClockwiseAngle(const Vector &from, const Vector &to, const Vector &orient) { + double dp = dot(from, to); + Vector cp = cross(from, to); + if (cp.isZero()) { + if (dp < 0) { + return M_PI; + } else { + return 0.0; + } + } else { + if (dot(cp, orient) > 0.0) { + return acos(dp); + } else { + return M_TWOPI - acos(dp); + } + } + } + + + + static inline double antiClockwiseOrdering(const Vector &from, const Vector &to, const Vector &orient) { + double dp = dot(from, to); + Vector cp = cross(from, to); + if (cp.isZero()) { + if (dp < 0) { + return 2.0; + } else { + return 0.0; + } + } else { + if (dot(cp, orient) > 0.0) { + // 1..-1 -> 0..2 + return 1.0 - dp; + } else { + // -1..1 -> 2..4 + return dp + 1.0; + } + } + } + + + + } +} diff -Nru blender-2.61/extern/carve/include/carve/geom.hpp blender-2.62/extern/carve/include/carve/geom.hpp --- blender-2.61/extern/carve/include/carve/geom.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/geom.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,363 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +#include + +namespace carve { + namespace geom { + + template struct aabb; + + // ======================================================================== + struct _uninitialized { }; + + template + struct base { + double v[ndim]; + }; + + template<> struct base<2> {union { double v[2]; struct { double x, y; }; }; }; + template<> struct base<3> {union { double v[3]; struct { double x, y, z; }; }; }; + template<> struct base<4> {union { double v[4]; struct { double x, y, z, w; }; }; }; + + template + struct vector : public base { + enum { __ndim = ndim }; + + static vector ZERO(); + double length2() const; + double length() const; + vector &normalize(); + vector normalized() const; + bool exactlyZero() const; + bool isZero(double epsilon = EPSILON) const; + void setZero(); + void fill(double val); + vector &scaleBy(double d); + vector &invscaleBy(double d); + vector scaled(double d) const; + vector invscaled(double d) const; + vector &negate(); + vector negated() const; + double &operator[](unsigned i); + const double &operator[](unsigned i) const; + template + vector &operator=(const assign_t &t); + std::string asStr() const; + + aabb getAABB() const; + + vector() { setZero(); } + vector(noinit_t) { } + }; + + template + vector vector::ZERO() { vector r; r.setZero(); return r; } + + static inline vector<2> VECTOR(double x, double y) { vector<2> r; r.x = x; r.y = y; return r; } + static inline vector<3> VECTOR(double x, double y, double z) { vector<3> r; r.x = x; r.y = y; r.z = z; return r; } + static inline vector<4> VECTOR(double x, double y, double z, double w) { vector<4> r; r.x = x; r.y = y; r.z = z; r.w = w; return r; } + + template vector operator+(const vector &a, const vector &b); + template vector operator+(const vector &a, double b); + template vector operator+(const vector &a, const val_t &b); + template vector operator+(const val_t &a, const vector &b); + + template vector &operator+=(vector &a, const vector &b); + template vector &operator+=(vector &a, double b); + template vector &operator+=(vector &a, const val_t &b); + + template vector operator-(const vector &a); + + template vector operator-(const vector &a, const vector &b); + template vector operator-(const vector &a, double b); + template vector operator-(const vector &a, const val_t &b); + template vector operator-(const val_t &a, const vector &b); + + template vector &operator-=(vector &a, const vector &b); + template vector &operator-=(vector &a, double b); + template vector &operator-=(vector &a, const val_t &b); + + template vector operator*(const vector &a, double s); + template vector operator*(double s, const vector &a); + template vector &operator*=(vector &a, double s); + + template vector operator/(const vector &a, double s); + template vector &operator/=(vector &a, double s); + + template bool operator==(const vector &a, const vector &b); + template bool operator!=(const vector &a, const vector &b); + template bool operator<(const vector &a, const vector &b); + template bool operator<=(const vector &a, const vector &b); + template bool operator>(const vector &a, const vector &b); + template bool operator>=(const vector &a, const vector &b); + + template vector abs(const vector &a); + + template double distance2(const vector &a, const vector &b); + + template double distance(const vector &a, const vector &b); + + template bool equal(const vector &a, const vector &b); + + template int smallestAxis(const vector &a); + + template int largestAxis(const vector &a); + + template vector<2> select(const vector &a, int a1, int a2); + + template vector<3> select(const vector &a, int a1, int a2, int a3); + + template + vector &assign_op(vector &a, const assign_t &t, oper_t op); + + template + vector &assign_op(vector &a, const assign1_t &t1, const assign2_t &t2, oper_t op); + + template + void bounds(iter_t begin, iter_t end, vector &min, vector &max); + + template + void bounds(iter_t begin, iter_t end, adapt_t adapt, vector &min, vector &max); + + template + void centroid(iter_t begin, iter_t end, adapt_t adapt, vector &c); + + template double dot(const vector &a, const val_t &b); + + static inline vector<3> cross(const vector<3> &a, const vector<3> &b); + + static inline double cross(const vector<2> &a, const vector<2> &b); + + static inline double dotcross(const vector<3> &a, const vector<3> &b, const vector<3> &c); + + + + // ======================================================================== + struct axis_pos { + int axis; + double pos; + + axis_pos(int _axis, double _pos) : axis(_axis), pos(_pos) { } + }; + + template + double distance(const axis_pos &a, const vector &b); + + template + double distance2(const axis_pos &a, const vector &b); + + template bool operator<(const axis_pos &a, const vector &b); + template bool operator<(const vector &a, const axis_pos &b); + + template bool operator<=(const axis_pos &a, const vector &b); + template bool operator<=(const vector &a, const axis_pos &b); + + template bool operator>(const axis_pos &a, const vector &b); + template bool operator>(const vector &a, const axis_pos &b); + + template bool operator>=(const axis_pos &a, const vector &b); + template bool operator>=(const vector &a, const axis_pos &b); + + template bool operator==(const axis_pos &a, const vector &b); + template bool operator==(const vector &a, const axis_pos &b); + + template bool operator!=(const axis_pos &a, const vector &b); + template bool operator!=(const vector &a, const axis_pos &b); + + + + // ======================================================================== + template + struct ray { + typedef vector vector_t; + + vector_t D, v; + + bool OK() const; + + ray() { } + ray(vector_t _D, vector_t _v) : D(_D), v(_v) { } + }; + + template + ray rayThrough(const vector &a, const vector &b); + + static inline double distance2(const ray<3> &r, const vector<3> &v); + + static inline double distance(const ray<3> &r, const vector<3> &v); + + static inline double distance2(const ray<2> &r, const vector<2> &v); + + static inline double distance(const ray<2> &r, const vector<2> &v); + + + + // ======================================================================== + template + struct linesegment { + typedef vector vector_t; + + vector_t v1; + vector_t v2; + vector_t midpoint; + vector_t half_length; + + void update(); + bool OK() const; + void flip(); + + aabb getAABB() const; + + linesegment(const vector_t &_v1, const vector_t &_v2); + }; + + template + double distance2(const linesegment &l, const vector &v); + + template + double distance(const linesegment &l, const vector &v); + + + + // ======================================================================== + template + struct plane { + typedef vector vector_t; + + vector_t N; + double d; + + void negate(); + + plane(); + plane(const vector_t &_N, vector_t _p); + plane(const vector_t &_N, double _d); + }; + + template + inline plane operator-(const plane &p); + + template + double distance(const plane &plane, const val_t &point); + + template + double distance2(const plane &plane, const val_t &point); + + template + static inline vector closestPoint(const plane &p, const vector &v); + + + + // ======================================================================== + template + struct sphere { + typedef vector vector_t; + + vector_t C; + double r; + + aabb getAABB() const; + + sphere(); + sphere(const vector_t &_C, double _r); + }; + + template + double distance(const sphere &sphere, const val_t &point); + + template + double distance2(const sphere &sphere, const val_t &point); + + template + static inline vector closestPoint(const sphere &sphere, const vector &point); + + + // ======================================================================== + template + struct tri { + typedef vector vector_t; + + vector_t v[3]; + + aabb getAABB() const; + + tri(vector_t _v[3]); + tri(const vector_t &a, const vector_t &b, const vector_t &c); + + vector_t normal() const { + return cross(v[1] - v[0], v[2] - v[1]).normalized(); + } + }; + + + + template std::ostream &operator<<(std::ostream &o, const vector &v); + template std::ostream &operator<<(std::ostream &o, const carve::geom::plane &p); + template std::ostream &operator<<(std::ostream &o, const carve::geom::sphere &sphere); + template std::ostream &operator<<(std::ostream &o, const carve::geom::tri &tri); + + + + template vector closestPoint(const tri &tri, const vector &pt); + template double distance(const tri &tri, const vector &pt); + template double distance2(const tri &tri, const vector &pt); + + + + // ======================================================================== + struct distance_functor { + template + double operator()(const obj1_t &o1, const obj2_t &o2) { + return distance(o1, o2); + } + }; + + + + // ======================================================================== + template struct __pow__ { enum { val = __pow__> 1)>::val * __pow__> 1)>::val }; }; + template struct __pow__ { enum { val = base }; }; + template struct __pow__ { enum { val = 1 }; }; + + template + struct quantize { + typedef __pow__ fac; + + double operator()(double in) { + return round(in * fac::val) / fac::val; + } + + template + vector operator()(const vector &in) { + vector r(NOINIT); + assign_op(r, in, *this); + return r; + } + }; + + + + } +} + + +#include diff -Nru blender-2.61/extern/carve/include/carve/geom_impl.hpp blender-2.62/extern/carve/include/carve/geom_impl.hpp --- blender-2.61/extern/carve/include/carve/geom_impl.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/geom_impl.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,651 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +namespace carve { + namespace geom { + + + + template + double vector::length2() const { return dot(*this, *this); } + template + double vector::length() const { return sqrt(dot(*this, *this)); } + + template + vector &vector::normalize() { *this /= length(); return *this; } + template + vector vector::normalized() const { return *this / length(); } + + template + bool vector::exactlyZero() const { + for (unsigned i = 0; i < ndim; ++i) if (this->v[i]) return false; + return true; + } + template + bool vector::isZero(double epsilon) const { + return length2() < epsilon * epsilon; + } + + template + void vector::setZero() { for (size_t i = 0; i < ndim; ++i) this->v[i] = 0.0; } + + template + void vector::fill(double val) { for (size_t i = 0; i < ndim; ++i) this->v[i] = val; } + + template + vector &vector::scaleBy(double d) { for (unsigned i = 0; i < ndim; ++i) this->v[i] *= d; return *this; } + template + vector &vector::invscaleBy(double d) { for (unsigned i = 0; i < ndim; ++i) this->v[i] /= d; return *this; } + + template + vector vector::scaled(double d) const { return *this * d; } + template + vector vector::invscaled(double d) const { return *this / d; } + + template + vector &vector::negate() { for (unsigned i = 0; i < ndim; ++i) this->v[i] = -this->v[i]; return *this; } + template + vector vector::negated() const { return -*this; } + + template + double &vector::operator[](unsigned i) { return this->v[i]; } + template + const double &vector::operator[](unsigned i) const { return this->v[i]; } + + template + template + vector &vector::operator=(const assign_t &t) { + for (unsigned i = 0; i < ndim; ++i) this->v[i] = t[i]; + return *this; + } + + template + std::string vector::asStr() const { + std::ostringstream out; + out << '<'; + out << std::setprecision(24); + for (unsigned i = 0; i < ndim; ++i) { if (i) out << ','; out << this->v[i]; } + out << '>'; + return out.str(); + } + + + + template + vector operator+(const vector &a, const vector &b) { + vector c(NOINIT); + for (unsigned i = 0; i < ndim; ++i) c[i] = a[i] + b[i]; + return c; + } + + template + vector operator+(const vector &a, double b) { + vector c(NOINIT); + for (unsigned i = 0; i < ndim; ++i) c[i] = a[i] + b; + return c; + } + + template + vector operator+(const vector &a, const val_t &b) { + vector c(NOINIT); + for (unsigned i = 0; i < ndim; ++i) c[i] = a[i] + b[i]; + return c; + } + + template + vector operator+(const val_t &a, const vector &b) { + vector c(NOINIT); + for (unsigned i = 0; i < ndim; ++i) c[i] = a[i] + b[i]; + return c; + } + + template + vector &operator+=(vector &a, const vector &b) { + for (unsigned i = 0; i < ndim; ++i) a[i] += b[i]; + return a; + } + + template + vector &operator+=(vector &a, double b) { + for (unsigned i = 0; i < ndim; ++i) a[i] += b; + return a; + } + + template + vector &operator+=(vector &a, const val_t &b) { + for (unsigned i = 0; i < ndim; ++i) a[i] += b[i]; + return a; + } + + + + template + vector operator-(const vector &a) { + vector c(NOINIT); + for (unsigned i = 0; i < ndim; ++i) c[i] = -a[i]; + return c; + } + + + + template + vector operator-(const vector &a, double b) { + vector c(NOINIT); + for (unsigned i = 0; i < ndim; ++i) c[i] = a[i] - b; + return c; + } + + template + vector operator-(const vector &a, const vector &b) { + vector c(NOINIT); + for (unsigned i = 0; i < ndim; ++i) c[i] = a[i] - b[i]; + return c; + } + + template + vector operator-(const vector &a, const val_t &b) { + vector c(NOINIT); + for (unsigned i = 0; i < ndim; ++i) c[i] = a[i] - b[i]; + return c; + } + + template + vector operator-(const val_t &a, const vector &b) { + vector c(NOINIT); + for (unsigned i = 0; i < ndim; ++i) c[i] = a[i] - b[i]; + return c; + } + + template + vector &operator-=(vector &a, const vector &b) { + for (unsigned i = 0; i < ndim; ++i) a[i] -= b[i]; + return a; + } + + template + vector &operator-=(vector &a, double b) { + for (unsigned i = 0; i < ndim; ++i) a[i] -= b; + return a; + } + + template + vector &operator-=(vector &a, const val_t &b) { + for (unsigned i = 0; i < ndim; ++i) a[i] -= b[i]; + return a; + } + + + + template + vector operator*(const vector &a, double s) { + vector c(NOINIT); + for (unsigned i = 0; i < ndim; ++i) c[i] = a[i] * s; + return c; + } + + template + vector operator*(double s, const vector &a) { + vector c(NOINIT); + for (unsigned i = 0; i < ndim; ++i) c[i] = a[i] * s; + return c; + } + + template + vector &operator*=(vector &a, double s) { + for (unsigned i = 0; i < ndim; ++i) a[i] *= s; + return a; + } + + + + template + vector operator/(const vector &a, double s) { + vector c(NOINIT); + for (unsigned i = 0; i < ndim; ++i) c[i] = a[i] / s; + return c; + } + + template + vector &operator/=(vector &a, double s) { + for (unsigned i = 0; i < ndim; ++i) a[i] /= s; + return a; + } + + + + template + bool operator==(const vector &a, const vector &b) { + for (unsigned i = 0; i < ndim; ++i) { if (a[i] != b[i]) return false; } + return true; + } + + template + bool operator!=(const vector &a, const vector &b) { + return !(a == b); + } + + template + bool operator<(const vector &a, const vector &b) { + for (unsigned i = 0; i < ndim; ++i) { if (a[i] < b[i]) return true; if (a[i] > b[i]) return false; } + return false; + } + + template + bool operator<=(const vector &a, const vector &b) { + return !(b < a); + } + + template + bool operator>(const vector &a, const vector &b) { + return b < a; + } + + template + bool operator>=(const vector &a, const vector &b) { + return !(a < b); + } + + + + template + vector abs(const vector &a) { + vector c(NOINIT); + for (unsigned i = 0; i < ndim; ++i) c[i] = fabs(a[i]); + return c; + } + + template + double distance2(const vector &a, const vector &b) { + return (b - a).length2(); + } + + template + double distance(const vector &a, const vector &b) { + return (b - a).length(); + } + + template + bool equal(const vector &a, const vector &b) { + return (b - a).isZero(); + } + + template + int smallestAxis(const vector &a) { + int x = 0; + double y = fabs(a[0]); + for (unsigned i = 1; i < ndim; ++i) { + double z = fabs(a[i]); + if (z <= y) { y = z; x = i; } + } + return x; + } + + template + int largestAxis(const vector &a) { + int x = 0; + double y = fabs(a[0]); + for (unsigned i = 1; i < ndim; ++i) { + double z = fabs(a[i]); + if (z > y) { y = z; x = i; } + } + return x; + } + + template + vector<2> select(const vector &a, int a1, int a2) { + vector<2> r(NOINIT); + r.v[0] = a.v[a1]; r.v[1] = a.v[a2]; + return r; + } + + template + vector<3> select(const vector &a, int a1, int a2, int a3) { + vector<3> r(NOINIT); + r.v[0] = a.v[a1]; r.v[1] = a.v[a2]; r.v[2] = a.v[a3]; + return r; + } + + template + vector &assign_op(vector &a, const assign_t &t, oper_t op) { + for (unsigned i = 0; i < ndim; ++i) a[i] = op(t[i]); + return a; + } + + template + vector &assign_op(vector &a, const assign1_t &t1, const assign2_t &t2, oper_t op) { + for (unsigned i = 0; i < ndim; ++i) a[i] = op(t1[i], t2[i]); + return a; + } + + template + void bounds(iter_t begin, iter_t end, vector &min, vector &max) { + if (begin == end) { + min.setZero(); + max.setZero(); + } else { + min = max = *begin; + while (++begin != end) { + vector v = *begin; + assign_op(min, min, v, carve::util::min_functor()); + assign_op(max, max, v, carve::util::max_functor()); + } + } + } + + template + void bounds(iter_t begin, iter_t end, adapt_t adapt, vector &min, vector &max) { + if (begin == end) { + min.setZero(); + max.setZero(); + } else { + min = max = adapt(*begin); + while (++begin != end) { + vector v = adapt(*begin); + assign_op(min, min, v, carve::util::min_functor()); + assign_op(max, max, v, carve::util::max_functor()); + } + } + } + + template + void centroid(iter_t begin, iter_t end, adapt_t adapt, vector &c) { + c.setZero(); + int n = 0; + while (begin != end) { c += adapt(*begin++); ++n; } + c /= double(n); + } + + template + double dot(const vector &a, const val_t &b) { + double r = 0.0; + for (unsigned i = 0; i < ndim; ++i) r += a[i] * b[i]; + return r; + } + + static inline vector<3> cross(const vector<3> &a, const vector<3> &b) { + // Compute a x b + return VECTOR(+(a.y * b.z - a.z * b.y), + -(a.x * b.z - a.z * b.x), + +(a.x * b.y - a.y * b.x)); + } + + static inline double cross(const vector<2> &a, const vector<2> &b) { + // Compute a x b + return a.x * b.y - b.x * a.y; + } + + static inline double dotcross(const vector<3> &a, const vector<3> &b, const vector<3> &c) { + // Compute a . (b x c) + return + (a.x * b.y * c.z + a.y * b.z * c.x + a.z * b.x * c.y) - + (a.x * b.z * c.y + a.y * b.x * c.z + a.z * b.y * c.x); + } + + + + template + double distance(const axis_pos &a, const vector &b) { + return fabs(b[a.axis] - a.pos); + } + + template + double distance2(const axis_pos &a, const vector &b) { + double r = fabs(b[a.axis] - a.pos); + return r * r; + } + + template bool operator<(const axis_pos &a, const vector &b) { return a.pos < b[a.axis]; } + template bool operator<(const vector &a, const axis_pos &b) { return a[b.axis] < b.pos; } + + template bool operator<=(const axis_pos &a, const vector &b) { return a.pos <= b[a.axis]; } + template bool operator<=(const vector &a, const axis_pos &b) { return a[b.axis] <= b.pos; } + + template bool operator>(const axis_pos &a, const vector &b) { return a.pos > b[a.axis]; } + template bool operator>(const vector &a, const axis_pos &b) { return a[b.axis] > b.pos; } + + template bool operator>=(const axis_pos &a, const vector &b) { return a.pos >= b[a.axis]; } + template bool operator>=(const vector &a, const axis_pos &b) { return a[b.axis] >= b.pos; } + + template bool operator==(const axis_pos &a, const vector &b) { return a.pos == b[a.axis]; } + template bool operator==(const vector &a, const axis_pos &b) { return a[b.axis] == b.pos; } + + template bool operator!=(const axis_pos &a, const vector &b) { return a.pos != b[a.axis]; } + template bool operator!=(const vector &a, const axis_pos &b) { return a[b.axis] != b.pos; } + + + + template + bool ray::OK() const { + return !D.isZero(); + } + + template + ray rayThrough(const vector &a, const vector &b) { + return ray(b - a, a); + } + + static inline double distance2(const ray<3> &r, const vector<3> &v) { + return cross(r.D, v - r.v).length2() / r.D.length2(); + } + + static inline double distance(const ray<3> &r, const vector<3> &v) { + return sqrt(distance2(r, v)); + } + + static inline double distance2(const ray<2> &r, const vector<2> &v) { + double t = cross(r.D, v - r.v); + return (t * t) / r.D.length2(); + } + + static inline double distance(const ray<2> &r, const vector<2> &v) { + return sqrt(distance2(r, v)); + } + + + + template + void linesegment::update() { + midpoint = (v2 + v1) / 2.0; + half_length = (v2 - v1) / 2.0; + } + + template + bool linesegment::OK() const { + return !half_length.isZero(); + } + + template + void linesegment::flip() { + std::swap(v1, v2); + half_length = (v2 - v1) / 2.0; + } + + template + aabb linesegment::getAABB() const { + aabb r; + r.fit(v1, v2); + return r; + } + + template + linesegment::linesegment(const vector_t &_v1, const vector_t &_v2) : v1(_v1), v2(_v2) { + update(); + } + + + + template + double distance2(const linesegment &l, const vector &v) { + vector D = l.v2 - l.v1; + double t = dot(v - l.v1, D) / dot(D, D); + if (t <= 0.0) return (v - l.v1).length2(); + if (t >= 1.0) return (v - l.v2).length2(); + vector vc = D * t + l.v1; + return (v - vc).length2(); + } + + template + double distance(const linesegment &l, const vector &v) { + return sqrt(distance2(l, v)); + } + + + template + void plane::negate() { + N.negate(); + d = -d; + } + + template + plane::plane() { + N.setZero(); + N[0] = 1.0; + d= 0.0; + } + + template + plane::plane(const vector_t &_N, vector_t _p) : N(_N), d(-dot(_p, _N)) { + } + + template + plane::plane(const vector_t &_N, double _d) : N(_N), d(_d) { + } + + + + template + plane operator-(const plane &p) { + return plane(-p.N, -p.d); + } + + template + double distance(const plane &plane, const val_t &point) { + return dot(plane.N, point) + plane.d; + } + + template + double distance2(const plane &plane, const val_t &point) { + double d = distance(plane, point); + return d * d; + } + + template + vector closestPoint(const plane &p, const vector &v) { + return v - p.N * (p.d + dot(p.N, v)) / dot(p.N, p.N); + } + + + + template + aabb sphere::getAABB() const { + aabb r; + r.fit(C - r, C + r); + } + + template + sphere::sphere() { + C.setZero(); + r = 1.0; + } + + template + sphere::sphere(const vector_t &_C, double _r) : C(_C), r(_r) { + } + + + + template + double distance(const sphere &sphere, const val_t &point) { + return std::max(0.0, distance(sphere.C, point) - sphere.r); + } + + template + double distance2(const sphere &sphere, const val_t &point) { + return std::max(0.0, distance2(sphere.C, point) - sphere.r * sphere.r); + } + + template + vector closestPoint(const sphere &sphere, const vector &point) { + return (point - sphere.C).normalized() * sphere.r; + } + + + + template + aabb tri::getAABB() const { + aabb aabb; + aabb.fit(v[0], v[1], v[2]); + return aabb; + } + + template + tri::tri(vector_t _v[3]) { + std::copy(v, v+3, _v); + } + + template + tri::tri(const vector_t &a, const vector_t &b, const vector_t &c) { + v[0] = a; + v[1] = b; + v[2] = c; + } + + + + template + std::ostream &operator<<(std::ostream &o, const vector &v) { + o << v.asStr(); + return o; + } + + template + std::ostream &operator<<(std::ostream &o, const carve::geom::plane &p) { + o << p.N << ";" << p.d; + return o; + } + + template + std::ostream &operator<<(std::ostream &o, const carve::geom::sphere &sphere) { + o << "{sphere " << sphere.C << ";" << sphere.r << "}"; + return o; + } + + template + std::ostream &operator<<(std::ostream &o, const carve::geom::tri &tri) { + o << "{tri " << tri.v[0] << ";" << tri.v[1] << ";" << tri.v[2] << "}"; + return o; + } + + + + template + double distance(const tri &tri, const vector &pt) { + return distance(closestPoint(tri, pt), pt); + } + + + + template + double distance2(const tri &tri, const vector &pt) { + return distance2(closestPoint(tri, pt), pt); + } + } +} diff -Nru blender-2.61/extern/carve/include/carve/gnu_cxx.h blender-2.62/extern/carve/include/carve/gnu_cxx.h --- blender-2.61/extern/carve/include/carve/gnu_cxx.h 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/gnu_cxx.h 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,4 @@ +// Copyright 2006 Tobias Sargeant (toby@permuted.net) +// All rights reserved. + +#pragma once diff -Nru blender-2.61/extern/carve/include/carve/heap.hpp blender-2.62/extern/carve/include/carve/heap.hpp --- blender-2.61/extern/carve/include/carve/heap.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/heap.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,425 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + +#pragma once +namespace carve { + namespace heap { + namespace detail { + + + + struct ignore_position_t { + template + void operator()(value_t &val, size_t idx) const {} + }; + + + + template + void _adjust_heap(random_access_iter_t begin, + distance_t pos, + distance_t len, + value_t val, + pred_t pred, + pos_notifier_t notify) { + const distance_t top = pos; + + distance_t child = pos * 2 + 2; + while (child < len) { + if (pred(begin[child], begin[child - 1])) child--; + + begin[pos] = begin[child]; + notify(begin[pos], pos); + pos = child; + child = pos * 2 + 2; + } + + if (child == len) { + child--; + begin[pos] = begin[child]; + notify(begin[pos], pos); + pos = child; + } + + distance_t parent = (pos - 1) / 2; + while (pos > top && pred(begin[parent], val)) { + begin[pos] = begin[parent]; + notify(begin[pos], pos); + pos = parent; + parent = (pos - 1) / 2; + } + + begin[pos] = val; + notify(begin[pos], pos); + } + + + + template + void _push_heap(random_access_iter_t begin, + distance_t pos, + value_t val, + pred_t pred, + pos_notifier_t notify) { + distance_t parent = (pos - 1) / 2; + while (pos > 0 && pred(begin[parent], val)) { + begin[pos] = begin[parent]; + notify(begin[pos], pos); + pos = parent; + parent = (pos - 1) / 2; + } + begin[pos] = val; + notify(begin[pos], pos); + } + + + + template + void _remove_heap(random_access_iter_t begin, + distance_t pos, + distance_t len, + pred_t pred, + pos_notifier_t notify) { + --len; + if (pos != len) { + typedef typename std::iterator_traits::value_type value_t; + value_t removed = begin[pos]; + _adjust_heap(begin, pos, len, begin[len], pred, notify); + begin[len] = removed; + notify(begin[len], len); + } + } + + + + template + void _make_heap(random_access_iter_t begin, + distance_t len, + pred_t pred, + pos_notifier_t notify) { + for (distance_t pos = len / 2; pos > 0; ) { + --pos; + _adjust_heap(begin, pos, len, begin[pos], pred, ignore_position_t()); + } + for (distance_t pos = 0; pos < len; ++pos) { + notify(begin[pos], pos); + } + } + + + + template + void _make_heap(random_access_iter_t begin, + distance_t len, + pred_t pred, + ignore_position_t) { + for (distance_t pos = len / 2; pos > 0; ) { + --pos; + _adjust_heap(begin, pos, len, begin[pos], pred, ignore_position_t()); + } + } + + + + template + bool _is_heap(random_access_iter_t begin, + distance_t len, + pred_t pred) { + distance_t parent = 0; + + for (distance_t child = 1; child < len; ++child) { + if (pred(begin[parent], begin[child])) { + return false; + } + if (++child == len) break; + if (pred(begin[parent], begin[child])) { + return false; + } + ++parent; + } + + return true; + } + + + + } + + + + template + void adjust_heap(random_access_iter_t begin, + random_access_iter_t end, + random_access_iter_t pos) { + typedef typename std::iterator_traits::value_type value_t; + + detail::_adjust_heap(begin, pos - begin, end - begin, *pos, std::less()); + } + + + + template + void adjust_heap(random_access_iter_t begin, + random_access_iter_t end, + random_access_iter_t pos, + pred_t pred) { + detail::_adjust_heap(begin, pos - begin, end - begin, *pos, pred); + } + + + + template + void adjust_heap(random_access_iter_t begin, + random_access_iter_t end, + random_access_iter_t pos, + pred_t pred, + pos_notifier_t notify) { + detail::_adjust_heap(begin, pos - begin, end - begin, *pos, pred, notify); + } + + + + template + void remove_heap(random_access_iter_t begin, + random_access_iter_t end, + random_access_iter_t pos) { + typedef typename std::iterator_traits::value_type value_t; + + detail::_remove_heap(begin, pos - begin, end - begin, std::less(), detail::ignore_position_t()); + } + + + + template + void remove_heap(random_access_iter_t begin, + random_access_iter_t end, + random_access_iter_t pos, + pred_t pred) { + detail::_remove_heap(begin, pos - begin, end - begin, pred, detail::ignore_position_t()); + } + + + + template + void remove_heap(random_access_iter_t begin, + random_access_iter_t end, + random_access_iter_t pos, + pred_t pred, + pos_notifier_t notify) { + detail::_remove_heap(begin, pos - begin, end - begin, pred, notify); + } + + + + template + void pop_heap(random_access_iter_t begin, + random_access_iter_t end) { + typedef typename std::iterator_traits::value_type value_t; + typedef typename std::iterator_traits::difference_type distance_t; + + detail::_remove_heap(begin, distance_t(0), end - begin, std::less(), detail::ignore_position_t()); + } + + + + template + void pop_heap(random_access_iter_t begin, + random_access_iter_t end, + pred_t pred) { + typedef typename std::iterator_traits::difference_type distance_t; + + detail::_remove_heap(begin, distance_t(0), end - begin, pred, detail::ignore_position_t()); + } + + + + template + void pop_heap(random_access_iter_t begin, + random_access_iter_t end, + pred_t pred, + pos_notifier_t notify) { + typedef typename std::iterator_traits::difference_type distance_t; + + detail::_remove_heap(begin, distance_t(0), end - begin, pred, notify); + } + + + + template + void push_heap(random_access_iter_t begin, + random_access_iter_t end) { + typedef typename std::iterator_traits::value_type value_t; + typedef typename std::iterator_traits::difference_type distance_t; + + distance_t pos = end - begin - 1; + detail::_push_heap(begin, pos, begin[pos], std::less(), detail::ignore_position_t()); + } + + + + template + void push_heap(random_access_iter_t begin, + random_access_iter_t end, + pred_t pred) { + typedef typename std::iterator_traits::difference_type distance_t; + + distance_t pos = end - begin - 1; + detail::_push_heap(begin, pos, begin[pos], pred, detail::ignore_position_t()); + } + + + + template + void push_heap(random_access_iter_t begin, + random_access_iter_t end, + pred_t pred, + pos_notifier_t notify) { + typedef typename std::iterator_traits::difference_type distance_t; + + distance_t pos = end - begin - 1; + detail::_push_heap(begin, pos, begin[pos], pred, notify); + } + + + + template + void make_heap(random_access_iter_t begin, + random_access_iter_t end) { + typedef typename std::iterator_traits::value_type value_t; + + detail::_make_heap(begin, end - begin, std::less(), detail::ignore_position_t()); + } + + + + template + void make_heap(random_access_iter_t begin, + random_access_iter_t end, + pred_t pred) { + detail::_make_heap(begin, end - begin, pred, detail::ignore_position_t()); + } + + + + template + void make_heap(random_access_iter_t begin, + random_access_iter_t end, + pred_t pred, + pos_notifier_t notify) { + detail::_make_heap(begin, end - begin, pred, notify); + } + + + + template + bool is_heap(random_access_iter_t begin, + random_access_iter_t end) { + typedef typename std::iterator_traits::value_type value_t; + + return detail::_is_heap(begin, end - begin, std::less()); + } + + + + template + bool is_heap(random_access_iter_t begin, + random_access_iter_t end, + pred_t pred) { + return detail::_is_heap(begin, end - begin, pred); + } + + + + template + void sort_heap(random_access_iter_t begin, + random_access_iter_t end) { + typedef typename std::iterator_traits::difference_type distance_t; + typedef typename std::iterator_traits::value_type value_t; + + for (distance_t len = end - begin; len > 1; --len) { + detail::_remove_heap(begin, distance_t(0), len, std::less(), detail::ignore_position_t()); + } + } + + + + template + void sort_heap(random_access_iter_t begin, + random_access_iter_t end, + pred_t pred) { + typedef typename std::iterator_traits::difference_type distance_t; + + for (distance_t len = end - begin; len > 1; --len) { + detail::_remove_heap(begin, distance_t(0), len, pred, detail::ignore_position_t()); + } + } + + + + template + void sort_heap(random_access_iter_t begin, + random_access_iter_t end, + pred_t pred, + pos_notifier_t notify) { + typedef typename std::iterator_traits::difference_type distance_t; + + for (distance_t len = end - begin; len > 1; --len) { + detail::_remove_heap(begin, distance_t(0), len, pred, detail::ignore_position_t()); + notify(begin[len], len); + } + notify(begin[0], 0); + } + + + + } +} diff -Nru blender-2.61/extern/carve/include/carve/input.hpp blender-2.62/extern/carve/include/carve/input.hpp --- blender-2.61/extern/carve/include/carve/input.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/input.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,251 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include +#include +#include +#include +#include + + + +namespace carve { + namespace input { + + struct Data { + Data() { + } + + virtual ~Data() { + } + + virtual void transform(const carve::math::Matrix & /* transform */) { + } + }; + + + + struct VertexData : public Data { + std::vector points; + + VertexData() : Data() { + } + + virtual ~VertexData() { + } + + virtual void transform(const carve::math::Matrix &transform) { + for (size_t i = 0; i < points.size(); ++i) { + points[i] *= transform; + } + } + + size_t addVertex(carve::geom3d::Vector point) { + size_t index = points.size(); + points.push_back(point); + return index; + } + + inline void reserveVertices(int count) { + points.reserve(count); + } + + size_t getVertexCount() const { + return points.size(); + } + + const carve::geom3d::Vector &getVertex(int index) const { + return points[index]; + } + }; + + + + struct PolyhedronData : public VertexData { + std::vector faceIndices; + int faceCount; + + PolyhedronData() : VertexData(), faceIndices(), faceCount(0) { + } + + virtual ~PolyhedronData() { + } + + void reserveFaces(int count, int avgFaceSize) { + faceIndices.reserve(faceIndices.size() + count * (1 + avgFaceSize)); + } + + int getFaceCount() const { + return faceCount; + } + + template + void addFace(Iter begin, Iter end) { + size_t n = std::distance(begin, end); + faceIndices.reserve(faceIndices.size() + n + 1); + faceIndices.push_back(n); + std::copy(begin, end, std::back_inserter(faceIndices)); + ++faceCount; + } + + void addFace(int a, int b, int c) { + faceIndices.push_back(3); + faceIndices.push_back(a); + faceIndices.push_back(b); + faceIndices.push_back(c); + ++faceCount; + } + + void addFace(int a, int b, int c, int d) { + faceIndices.push_back(4); + faceIndices.push_back(a); + faceIndices.push_back(b); + faceIndices.push_back(c); + faceIndices.push_back(d); + ++faceCount; + } + + void clearFaces() { + faceIndices.clear(); + faceCount = 0; + } + + carve::poly::Polyhedron *create() const { + return new carve::poly::Polyhedron(points, faceCount, faceIndices); + } + + carve::mesh::MeshSet<3> *createMesh() const { + return new carve::mesh::MeshSet<3>(points, faceCount, faceIndices); + } + }; + + + + struct PolylineSetData : public VertexData { + typedef std::pair > polyline_data_t; + std::list polylines; + + PolylineSetData() : VertexData(), polylines() { + } + + virtual ~PolylineSetData() { + } + + void beginPolyline(bool closed = false) { + polylines.push_back(std::make_pair(closed, std::vector())); + } + + void reservePolyline(size_t len) { + polylines.back().second.reserve(len); + } + + void addPolylineIndex(int idx) { + polylines.back().second.push_back(idx); + } + + carve::line::PolylineSet *create() const { + carve::line::PolylineSet *p = new carve::line::PolylineSet(points); + + for (std::list::const_iterator i = polylines.begin(); + i != polylines.end(); + ++i) { + p->addPolyline((*i).first, (*i).second.begin(), (*i).second.end()); + } + return p; + } + }; + + + + struct PointSetData : public VertexData { + + PointSetData() : VertexData() { + } + + virtual ~PointSetData() { + } + + carve::point::PointSet *create() const { + carve::point::PointSet *p = new carve::point::PointSet(points); + return p; + } + }; + + + + class Input { + public: + std::list input; + + Input() { + } + + ~Input() { + for (std::list::iterator i = input.begin(); i != input.end(); ++i) { + delete (*i); + } + } + + void addDataBlock(Data *data) { + input.push_back(data); + } + + void transform(const carve::math::Matrix &transform) { + if (transform == carve::math::Matrix::IDENT()) return; + for (std::list::iterator i = input.begin(); i != input.end(); ++i) { + (*i)->transform(transform); + } + } + + template + static inline T *create(Data *d) { + return NULL; + } + }; + + template<> + inline carve::mesh::MeshSet<3> *Input::create(Data *d) { + PolyhedronData *p = dynamic_cast(d); + if (p == NULL) return NULL; + return p->createMesh(); + } + + template<> + inline carve::poly::Polyhedron *Input::create(Data *d) { + PolyhedronData *p = dynamic_cast(d); + if (p == NULL) return NULL; + return p->create(); + } + + template<> + inline carve::line::PolylineSet *Input::create(Data *d) { + PolylineSetData *p = dynamic_cast(d); + if (p == NULL) return NULL; + return p->create(); + } + + template<> + inline carve::point::PointSet *Input::create(Data *d) { + PointSetData *p = dynamic_cast(d); + if (p == NULL) return NULL; + return p->create(); + } + + } +} diff -Nru blender-2.61/extern/carve/include/carve/interpolator.hpp blender-2.62/extern/carve/include/carve/interpolator.hpp --- blender-2.61/extern/carve/include/carve/interpolator.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/interpolator.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,332 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include +#include +#include +#include +#include + +namespace carve { + namespace interpolate { + + static inline std::vector polyInterpolate(const std::vector &s, + const carve::geom2d::P2 &v) { + // see hormann et al. 2006 + const size_t SZ = s.size(); + std::vector r; + std::vector A; + std::vector D; + + std::vector result; + + r.resize(SZ); + A.resize(SZ); + D.resize(SZ); + + result.resize(SZ, 0.0); + + for (size_t i = 0; i < SZ; ++i) { + size_t i2 = (i + 1) % SZ; + carve::geom2d::P2 si = s[i] - v; + carve::geom2d::P2 si2 = s[i2] - v; + + r[i] = sqrt(dot(si, si)); + A[i] = cross(si, si2) / 2.0; + D[i] = dot(si, si2); + if (fabs(r[i]) < 1e-16) { + result[i] = 1.0; + return result; + } else if (fabs(A[i]) < 1e-16 && D[i] < 0.0) { + double r2 = sqrt(dot(si2, si2)); + result[i2] = r[i] / (r[i] + r2); + result[i] = r2 / (r[i] + r2); + return result; + } + } + + double w_sum = 0.0; + + for (size_t i = 0; i < SZ; ++i) { + size_t i_m = (i + SZ - 1) % SZ; + size_t i_p = (i + 1) % SZ; + + double w = 0.0; + if (fabs(A[i_m]) > 1e-16) + w += (r[i_m] - D[i_m] / r[i]) / A[i_m]; + if (fabs(A[i]) > 1e-16) + w += (r[i_p] - D[i] / r[i]) / A[i]; + + result[i] = w; + w_sum += w; + } + + for (size_t i = 0; i < SZ; ++i) { + result[i] /= w_sum; + } + +// carve::geom2d::P2 test; +// for (size_t i = 0; i < SZ; ++i) { +// test = test + result[i] * s[i]; +// } + + return result; + } + + template + val_t interp(iter_t begin, + iter_t end, + adapt_t adapt, + const std::vector &vals, + double x, + double y, + mod_t mod = mod_t()) { + std::vector s; + s.reserve(std::distance(begin, end)); + std::transform(begin, end, std::back_inserter(s), adapt); + std::vector weight = polyInterpolate(s, carve::geom::VECTOR(x, y)); + + val_t v; + for (size_t z = 0; z < weight.size(); z++) { + v += weight[z] * vals[z]; + } + + return mod(v); + } + + template + val_t interp(iter_t begin, + iter_t end, + adapt_t adapt, + const std::vector &vals, + double x, + double y) { + return interp(begin, end, adapt, vals, x, y, identity_t()); + } + + template + val_t interp(const std::vector &poly, + adapt_t adapt, + const std::vector &vals, + double x, + double y, + mod_t mod = mod_t()) { + return interp(poly.begin(), poly.end(), adapt, vals, x, y, mod); + } + + template + val_t interp(const std::vector &poly, + adapt_t adapt, + const std::vector &vals, + double x, + double y) { + return interp(poly.begin(), poly.end(), adapt, vals, x, y, identity_t()); + } + + template + val_t interp(const std::vector &poly, + const std::vector &vals, + double x, + double y, + mod_t mod = mod_t()) { + std::vector weight = polyInterpolate(poly, carve::geom::VECTOR(x, y)); + + val_t v; + for (size_t z = 0; z < weight.size(); z++) { + v += weight[z] * vals[z]; + } + + return mod(v); + } + + template + val_t interp(const std::vector &poly, + const std::vector &vals, + double x, + double y) { + return interp(poly, vals, x, y, identity_t()); + } + + class Interpolator { + public: + virtual void interpolate(const carve::mesh::MeshSet<3>::face_t *new_face, + const carve::mesh::MeshSet<3>::face_t *orig_face, + bool flipped) =0; + + Interpolator() { + } + + virtual ~Interpolator() { + } + + class Hook : public carve::csg::CSG::Hook { + Interpolator *interpolator; + public: + virtual void resultFace(const carve::mesh::MeshSet<3>::face_t *new_face, + const carve::mesh::MeshSet<3>::face_t *orig_face, + bool flipped) { + interpolator->interpolate(new_face, orig_face, flipped); + } + + Hook(Interpolator *_interpolator) : interpolator(_interpolator) { + } + + virtual ~Hook() { + } + }; + + void installHooks(carve::csg::CSG &csg) { + csg.hooks.registerHook(new Hook(this), carve::csg::CSG::Hooks::RESULT_FACE_BIT); + } + }; + + template + class FaceVertexAttr : public Interpolator { + + protected: + struct fv_hash { + size_t operator()(const std::pair::face_t *, unsigned> &v) const { + return size_t(v.first) ^ size_t(v.second); + } + }; + + typedef std::unordered_map::vertex_t *, attr_t> attrvmap_t; + typedef std::unordered_map::face_t *, unsigned>, attr_t, fv_hash> attrmap_t; + + attrmap_t attrs; + + public: + bool hasAttribute(const carve::mesh::MeshSet<3>::face_t *f, unsigned v) { + return attrs.find(std::make_pair(f, v)) != attrs.end(); + } + + attr_t getAttribute(const carve::mesh::MeshSet<3>::face_t *f, unsigned v, const attr_t &def = attr_t()) { + typename attrmap_t::const_iterator fv = attrs.find(std::make_pair(f, v)); + if (fv != attrs.end()) { + return (*fv).second; + } + return def; + } + + void setAttribute(const carve::mesh::MeshSet<3>::face_t *f, unsigned v, const attr_t &attr) { + attrs[std::make_pair(f, v)] = attr; + } + + virtual void interpolate(const carve::mesh::MeshSet<3>::face_t *new_face, + const carve::mesh::MeshSet<3>::face_t *orig_face, + bool flipped) { + std::vector vertex_attrs; + attrvmap_t base_attrs; + vertex_attrs.reserve(orig_face->nVertices()); + + for (carve::mesh::MeshSet<3>::face_t::const_edge_iter_t e = orig_face->begin(); e != orig_face->end(); ++e) { + typename attrmap_t::const_iterator a = attrs.find(std::make_pair(orig_face, e.idx())); + if (a == attrs.end()) return; + vertex_attrs.push_back((*a).second); + base_attrs[e->vert] = vertex_attrs.back(); + } + + for (carve::mesh::MeshSet<3>::face_t::const_edge_iter_t e = new_face->begin(); e != new_face->end(); ++e) { + const carve::mesh::MeshSet<3>::vertex_t *vertex = e->vert; + typename attrvmap_t::const_iterator b = base_attrs.find(vertex); + if (b != base_attrs.end()) { + attrs[std::make_pair(new_face, e.idx())] = (*b).second; + } else { + carve::geom2d::P2 p = orig_face->project(e->vert->v); + attr_t attr = interp(orig_face->begin(), + orig_face->end(), + orig_face->projector(), + vertex_attrs, + p.x, + p.y); + attrs[std::make_pair(new_face, e.idx())] = attr; + } + } + } + + FaceVertexAttr() : Interpolator() { + } + + virtual ~FaceVertexAttr() { + } + + }; + + + template + class FaceAttr : public Interpolator { + + protected: + struct f_hash { + size_t operator()(const carve::mesh::MeshSet<3>::face_t * const &f) const { + return size_t(f); + } + }; + + typedef std::unordered_map::face_t *, attr_t, f_hash> attrmap_t; + + attrmap_t attrs; + + public: + bool hasAttribute(const carve::mesh::MeshSet<3>::face_t *f) { + return attrs.find(f) != attrs.end(); + } + + attr_t getAttribute(const carve::mesh::MeshSet<3>::face_t *f, const attr_t &def = attr_t()) { + typename attrmap_t::const_iterator i = attrs.find(f); + if (i != attrs.end()) { + return (*i).second; + } + return def; + } + + void setAttribute(const carve::mesh::MeshSet<3>::face_t *f, const attr_t &attr) { + attrs[f] = attr; + } + + virtual void interpolate(const carve::mesh::MeshSet<3>::face_t *new_face, + const carve::mesh::MeshSet<3>::face_t *orig_face, + bool flipped) { + typename attrmap_t::const_iterator i = attrs.find(orig_face); + if (i != attrs.end()) { + attrs[new_face] = (*i).second; + } + } + + FaceAttr() : Interpolator() { + } + + virtual ~FaceAttr() { + } + + }; + + } +} diff -Nru blender-2.61/extern/carve/include/carve/intersection.hpp blender-2.62/extern/carve/include/carve/intersection.hpp --- blender-2.61/extern/carve/include/carve/intersection.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/intersection.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,267 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include +#include +#include + +namespace carve { + namespace csg { + + /** + * \class Intersections + * \brief Storage for computed intersections between vertices, edges and faces. + * + */ + struct Intersections : public std::unordered_map { + typedef carve::mesh::MeshSet<3>::vertex_t vertex_t; + typedef carve::mesh::MeshSet<3>::edge_t edge_t; + typedef carve::mesh::MeshSet<3>::face_t face_t; + + typedef std::unordered_map super; + + ~Intersections() { + } + + /** + * \brief Record the position of intersection between a pair of intersection objects. + * + * @param a The first intersecting object. + * @param b The second intersecting object. + * @param p The point of intersection. + */ + void record(IObj a, IObj b, vertex_t *p) { + if (a > b) std::swap(a, b); + (*this)[a][b] = p; + (*this)[b][a] = p; + } + + /** + * \brief Test whether vertex \a v intersects face \a f. + * + * @param v The vertex to test. + * @param f The face to test. + * + * @return true, if \a v intersects \a f. + */ + bool intersectsFace(vertex_t *v, face_t *f) const; + + /** + * \brief Collect sets of vertices, edges and faces that intersect \a obj + * + * @param[in] obj The intersection object to search for intersections. + * @param[out] collect_v A vector of vertices intersecting \a obj. + * @param[out] collect_e A vector of edges intersecting \a obj. + * @param[out] collect_f A vector of faces intersecting \a obj. + */ + void collect(const IObj &obj, + std::vector *collect_v, + std::vector *collect_e, + std::vector *collect_f) const; + + + /** + * \brief Determine whether two intersection objects intersect. + * + * @param a The first intersection object. + * @param b The second intersection object. + * + * @return true, if \a a and \a b intersect. + */ + bool intersectsExactly(const IObj &a, const IObj &b) { + Intersections::const_iterator i = find(a); + if (i == end()) return false; + return i->second.find(b) != i->second.end(); + } + + /** + * \brief Determine whether an intersection object intersects a vertex. + * + * @param a The intersection object. + * @param v The vertex. + * + * @return true, if \a a and \a v intersect. + */ + bool intersects(const IObj &a, vertex_t *v) { + Intersections::const_iterator i = find(a); + if (i == end()) return false; + if (i->second.find(v) != i->second.end()) return true; + return false; + } + + /** + * \brief Determine whether an intersection object intersects an edge. + * + * @param a The intersection object. + * @param e The edge. + * + * @return true, if \a a and \a e intersect (either on the edge, + * or at either endpoint). + */ + bool intersects(const IObj &a, edge_t *e) { + Intersections::const_iterator i = find(a); + if (i == end()) return false; + for (super::data_type::const_iterator j = i->second.begin(); j != i->second.end(); ++j) { + const IObj &obj = j->first; + switch (obj.obtype) { + case IObj::OBTYPE_VERTEX: + if (obj.vertex == e->v1() || obj.vertex == e->v2()) return true; + break; + case IObj::OBTYPE_EDGE: + if (obj.edge == e) return true; + break; + default: + break; + } + } + return false; + } + + /** + * \brief Determine whether an intersection object intersects a face. + * + * @param a The intersection object. + * @param f The face. + * + * @return true, if \a a and \a f intersect (either on the face, + * or at any associated edge or vertex). + */ + bool intersects(const IObj &a, face_t *f) { + Intersections::const_iterator i = find(a); + if (i == end()) return false; + if (i->second.find(f) != i->second.end()) return true; + edge_t *e = f->edge; + do { + if (i->second.find(e) != i->second.end()) return true; + if (i->second.find(e->vert) != i->second.end()) return true; + e = e->next; + } while (e != f->edge); + return false; + } + + /** + * \brief Determine whether an edge intersects another edge. + * + * @param e The edge. + * @param f The face. + * + * @return true, if \a e and \a f intersect. + */ + bool intersects(edge_t *e1, edge_t *e2) { + if (intersects(e1->v1(), e2) || intersects(e1->v2(), e2) || intersects(IObj(e1), e2)) return true; + return false; + } + + /** + * \brief Determine whether an edge intersects a face. + * + * @param e The edge. + * @param f The face. + * + * @return true, if \a e and \a f intersect. + */ + bool intersects(edge_t *e, face_t *f) { + if (intersects(e->v1(), f) || intersects(e->v2(), f) || intersects(IObj(e), f)) return true; + return false; + } + + /** + * \brief Determine the faces intersected by an edge. + * + * @tparam face_set_t A collection type holding face_t * + * @param[in] e The edge. + * @param[out] f The resulting set of faces. + */ + template + void intersectedFaces(edge_t *e, face_set_t &f) const { + std::vector intersected_faces; + std::vector intersected_edges; + std::vector intersected_vertices; + + collect(e, &intersected_vertices, &intersected_edges, &intersected_faces); + + for (unsigned i = 0; i < intersected_vertices.size(); ++i) { + facesForVertex(intersected_vertices[i], f); + } + for (unsigned i = 0; i < intersected_edges.size(); ++i) { + facesForEdge(intersected_edges[i], f); + } + f.insert(intersected_faces.begin(), intersected_faces.end()); + } + + /** + * \brief Determine the faces intersected by a vertex. + * + * @tparam face_set_t A collection type holding face_t * + * @param[in] v The vertex. + * @param[out] f The resulting set of faces. + */ + template + void intersectedFaces(vertex_t *v, face_set_t &f) const { + std::vector intersected_faces; + std::vector intersected_edges; + std::vector intersected_vertices; + + collect(v, &intersected_vertices, &intersected_edges, &intersected_faces); + + for (unsigned i = 0; i < intersected_vertices.size(); ++i) { + facesForVertex(intersected_vertices[i], f); + } + for (unsigned i = 0; i < intersected_edges.size(); ++i) { + facesForEdge(intersected_edges[i], f); + } + f.insert(intersected_faces.begin(), intersected_faces.end()); + } + + /** + * \brief Collect the set of faces that contain all vertices in \a verts. + * + * @tparam vertex_set_t A collection type holding vertex_t * + * @tparam face_set_t A collection type holding face_t * + * @param[in] verts A set of vertices. + * @param[out] result The resulting set of faces. + */ + template + void commonFaces(const vertex_set_t &verts, face_set_t &result) { + + std::set ifaces, temp, out; + typename vertex_set_t::const_iterator i = verts.begin(); + if (i == verts.end()) return; + intersectedFaces((*i), ifaces); + while (++i != verts.end()) { + temp.clear(); + intersectedFaces((*i), temp); + + out.clear(); + std::set_intersection(temp.begin(), temp.end(), + ifaces.begin(), ifaces.end(), + set_inserter(out)); + ifaces.swap(out); + } + std::copy(ifaces.begin(), ifaces.end(), set_inserter(result)); + } + + void clear() { + super::clear(); + } + + }; + + } +} diff -Nru blender-2.61/extern/carve/include/carve/iobj.hpp blender-2.62/extern/carve/include/carve/iobj.hpp --- blender-2.61/extern/carve/include/carve/iobj.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/iobj.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,106 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +namespace carve { + namespace csg { + struct IObj { + enum { + OBTYPE_NONE = 0, + OBTYPE_VERTEX = 1, + OBTYPE_EDGE = 2, + OBTYPE_FACE = 4 + } obtype; + + union { + carve::mesh::MeshSet<3>::vertex_t *vertex; + carve::mesh::MeshSet<3>::edge_t *edge; + carve::mesh::MeshSet<3>::face_t *face; + intptr_t val; + }; + + IObj() : obtype(OBTYPE_NONE), val(0) { } + IObj(carve::mesh::MeshSet<3>::vertex_t *v) : obtype(OBTYPE_VERTEX), vertex(v) { } + IObj(carve::mesh::MeshSet<3>::edge_t *e) : obtype(OBTYPE_EDGE), edge(e) { } + IObj(carve::mesh::MeshSet<3>::face_t *f) : obtype(OBTYPE_FACE), face(f) { } + char typeChar() const { return "NVExF"[obtype]; } + }; + + + + struct IObj_hash { + inline size_t operator()(const IObj &i) const { + return (size_t)i.val; + } + inline size_t operator()(const std::pair &i) const { + return (size_t)i.first.val ^ (size_t)i.second.val; + } + }; + + + + typedef std::unordered_set, IObj_hash> IObjPairSet; + + typedef std::unordered_map::vertex_t *, IObj_hash> IObjVMap; + typedef std::map::vertex_t *> IObjVMapSmall; + + class VertexIntersections : + public std::unordered_map::vertex_t *, IObjPairSet> { + }; + + + + static inline bool operator==(const carve::csg::IObj &a, const carve::csg::IObj &b) { + return a.obtype == b.obtype && a.val == b.val; + } + + static inline bool operator!=(const carve::csg::IObj &a, const carve::csg::IObj &b) { + return a.obtype != b.obtype || a.val != b.val; + } + + static inline bool operator<(const carve::csg::IObj &a, const carve::csg::IObj &b) { + return a.obtype < b.obtype || (a.obtype == b.obtype && a.val < b.val); + } + + static inline bool operator<=(const carve::csg::IObj &a, const carve::csg::IObj &b) { + return a.obtype < b.obtype || (a.obtype == b.obtype && a.val <= b.val); + } + + static inline bool operator>(const carve::csg::IObj &a, const carve::csg::IObj &b) { + return a.obtype > b.obtype || (a.obtype == b.obtype && a.val > b.val); + } + + static inline bool operator>=(const carve::csg::IObj &a, const carve::csg::IObj &b) { + return a.obtype > b.obtype || (a.obtype == b.obtype && a.val >= b.val); + } + + static inline std::ostream &operator<<(std::ostream &o, const carve::csg::IObj &a) { + switch (a.obtype) { + case carve::csg::IObj::OBTYPE_NONE: o << "NONE{}"; break; + case carve::csg::IObj::OBTYPE_VERTEX: o << "VERT{" << a.vertex << "}"; break; + case carve::csg::IObj::OBTYPE_EDGE: o << "EDGE{" << a.edge << "}"; break; + case carve::csg::IObj::OBTYPE_FACE: o << "FACE{" << a.face << "}"; break; + } + return o; + } + + } +} + diff -Nru blender-2.61/extern/carve/include/carve/kd_node.hpp blender-2.62/extern/carve/include/carve/kd_node.hpp --- blender-2.61/extern/carve/include/carve/kd_node.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/kd_node.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,308 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include +#include +#include + +#include +#include +#include + +namespace carve { + namespace geom { + template + class kd_node { + kd_node(const kd_node &); + kd_node &operator=(const kd_node &); + + public: + kd_node *c_neg; + kd_node *c_pos; + kd_node *parent; + axis_pos splitpos; + + typedef vector vector_t; + typedef std::list container_t; + + container_t data; + + kd_node(kd_node *_parent = NULL) : c_neg(NULL), c_pos(NULL), parent(_parent), splitpos(0, 0.0) { + } + + ~kd_node() { + if (c_neg) delete c_neg; + if (c_pos) delete c_pos; + } + + template + void closeNodes(const vector_t &p, double d, visitor_t &visit) const { + if (c_neg) { + double delta = splitpos.pos - p[splitpos.axis]; + if (delta <= d) c_neg->closeNodes(p, d, visit); + if (delta >= -d) c_pos->closeNodes(p, d, visit); + } else { + visit(this); + } + } + + void removeData(const data_t &d) { + typename container_t::iterator i = std::find(data.begin(), data.end(), d); + + if (i != data.end()) { + data.erase(i); + } + } + + void addData(const data_t &d) { + data.push_back(d); + } + + void insert(const data_t &data, inserter_t &inserter) { + inserter.insert(this, data); + } + + void insert(const data_t &data) { + inserter_t inserter; + insert(data, inserter); + } + + void remove(const data_t &data, inserter_t &inserter) { + inserter.remove(this, data); + } + + void remove(const data_t &data) { + inserter_t inserter; + remove(data, inserter); + } + + carve::geom::aabb nodeAABB() const { + carve::geom::aabb aabb; + if (c_neg) { + aabb = c_neg->nodeAABB(); + aabb.unionAABB(c_pos->nodeAABB()); + } else { + if (data.size()) { + typename container_t::const_iterator i = data.begin(); + aabb = aabb_calc_t()(*i); + while (i != data.end()) { + aabb.unionAABB(aabb_calc_t()(*i)); + ++i; + } + } + } + return aabb; + } + + bool split(axis_pos split_at, inserter_t &inserter) { + if (c_neg) { + // already split + return false; + } + + c_neg = new kd_node(this); + c_pos = new kd_node(this); + + // choose an axis and split point. + splitpos = split_at; + + carve::geom::aabb aabb; + + if (splitpos.axis < 0 || + splitpos.axis >= ndim || + splitpos.pos == std::numeric_limits::max()) { + // need an aabb + if (data.size()) { + typename container_t::const_iterator i = data.begin(); + aabb = aabb_calc_t()(*i); + while (i != data.end()) { + aabb.unionAABB(aabb_calc_t()(*i)); + ++i; + } + } + } + + if (splitpos.axis < 0 || splitpos.axis >= ndim) { + + // choose an axis; + + // if no axis was specified, force calculation of the split position. + splitpos.pos = std::numeric_limits::max(); + + // choose the axis of the AABB with the biggest extent. + splitpos.axis = largestAxis(aabb.extent); + + if (parent && splitpos.axis == parent->splitpos.axis) { + // but don't choose the same axis as the parent node; + // choose the axis with the second greatest AABB extent. + double e = -1.0; + int a = -1; + for (unsigned i = 0; i < ndim; ++i) { + if (i == splitpos.axis) continue; + if (e < aabb.extent[i]) { a = i; e = aabb.extent[i]; } + } + if (a != -1) { + splitpos.axis = a; + } + } + } + + if (splitpos.pos == std::numeric_limits::max()) { + carve::geom::vector min = aabb.min(); + carve::geom::vector max = aabb.max(); + splitpos.pos = aabb.pos.v[splitpos.axis]; + } + + inserter.propagate(this); + + return true; + } + + bool split(axis_pos split_at = axis_pos(-1, std::numeric_limits::max())) { + inserter_t inserter; + return split(split_at, inserter); + } + + void splitn(int num, inserter_t &inserter) { + if (num <= 0) return; + if (!c_neg) { + split(inserter); + } + if (c_pos) c_pos->splitn(num-1, inserter); + if (c_neg) c_neg->splitn(num-1, inserter); + } + + void splitn(int num) { + inserter_t inserter; + splitn(num, inserter); + } + + template + void splitn(int num, split_t splitter, inserter_t &inserter) { + if (num <= 0) return; + if (!c_neg) { + split(inserter, splitter(this)); + } + if (c_pos) c_pos->splitn(num-1, inserter, splitter); + if (c_neg) c_neg->splitn(num-1, inserter, splitter); + } + + template + void splitn(int num, split_t splitter) { + inserter_t inserter; + splitn(num, splitter, inserter); + } + + template + void splitpred(pred_t pred, inserter_t &inserter, int depth = 0) { + if (!c_neg) { + axis_pos splitpos(-1, std::numeric_limits::max()); + if (!pred(this, depth, splitpos)) return; + split(splitpos, inserter); + } + if (c_pos) c_pos->splitpred(pred, inserter, depth + 1); + if (c_neg) c_neg->splitpred(pred, inserter, depth + 1); + } + + template + void splitpred(pred_t pred, int depth = 0) { + inserter_t inserter; + splitpred(pred, inserter, depth); + } + + // distance_t must provide: + // double operator()(kd_node::data_t, vector); + // double operator()(axis_pos, vector); + template + struct near_point_query { + + // q_t - the priority queue value type. + // q_t.first: distance from object to query point. + // q_t.second: pointer to object + typedef std::pair q_t; + + // the queue priority should sort from smallest distance to largest, and on equal distance, by object pointer. + struct pcmp { + bool operator()(const q_t &a, const q_t &b) { + return (a.first > b.first) || ((a.first == b.first) && (a.second < b.second)); + } + }; + + vector point; + const kd_node *node; + std::priority_queue, pcmp> pq; + + distance_t dist; + double dist_to_parent_split; + + void addToPQ(kd_node *node) { + if (node->c_neg) { + addToPQ(node->c_neg); + addToPQ(node->c_pos); + } else { + for (typename kd_node::container_t::const_iterator i = node->data.begin(); i != node->data.end(); ++i) { + double d = dist((*i), point); + pq.push(std::make_pair(d, &(*i))); + } + } + } + + const typename kd_node::data_t *next() { + while (1) { + if (pq.size()) { + q_t t = pq.top(); + if (!node->parent || t.first < dist_to_parent_split) { + pq.pop(); + return t.second; + } + } + + if (!node->parent) return NULL; + + if (node->parent->c_neg == node) { + addToPQ(node->parent->c_pos); + } else { + addToPQ(node->parent->c_neg); + } + + node = node->parent; + dist_to_parent_split = dist(node->splitpos, point); + } + } + + near_point_query(const vector _point, const kd_node *_node) : point(_point), node(_node), pq(), dist() { + while (node->c_neg) { + node = (point[node->axis] < node->pos) ? node->c_neg : node->c_pos; + } + if (node->parent) { + dist_to_parent_split = dist(node->parent->splitpos, point); + } else { + dist_to_parent_split = HUGE_VAL; + } + addToPQ(node); + } + }; + + }; + + } +} diff -Nru blender-2.61/extern/carve/include/carve/math_constants.hpp blender-2.62/extern/carve/include/carve/math_constants.hpp --- blender-2.61/extern/carve/include/carve/math_constants.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/math_constants.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,33 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +#ifndef M_SQRT_3 +#define M_SQRT_3 1.73205080756887729352 +#endif + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#ifndef M_TWOPI +#define M_TWOPI (M_PI + M_PI) +#endif + diff -Nru blender-2.61/extern/carve/include/carve/math.hpp blender-2.62/extern/carve/include/carve/math.hpp --- blender-2.61/extern/carve/include/carve/math.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/math.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,60 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +#include + +#include + +namespace carve { + namespace geom { + template struct vector; + } +} + +namespace carve { + namespace math { + struct Matrix3; + int cubic_roots(double c3, double c2, double c1, double c0, double *roots); + + void eigSolveSymmetric(const Matrix3 &m, + double &l1, carve::geom::vector<3> &e1, + double &l2, carve::geom::vector<3> &e2, + double &l3, carve::geom::vector<3> &e3); + + void eigSolve(const Matrix3 &m, double &l1, double &l2, double &l3); + + static inline bool ZERO(double x) { return fabs(x) < carve::EPSILON; } + + static inline double radians(double deg) { return deg * M_PI / 180.0; } + static inline double degrees(double rad) { return rad * 180.0 / M_PI; } + + static inline double ANG(double x) { + return (x < 0) ? x + M_TWOPI : x; + } + + template + static inline const T &clamp(const T &val, const T &min, const T &max) { + if (val < min) return min; + if (val > max) return max; + return val; + } + } +} diff -Nru blender-2.61/extern/carve/include/carve/matrix.hpp blender-2.62/extern/carve/include/carve/matrix.hpp --- blender-2.61/extern/carve/include/carve/matrix.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/matrix.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,262 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +#include + +#include +#include + +namespace carve { + namespace math { + + struct Quaternion { + double x, y, z, w; + + Quaternion(double _x, double _y, double _z, double _w) : x(_x), y(_y), z(_z), w(_w) { + } + + Quaternion(double angle, const carve::geom::vector<3> &axis) { + double s = axis.length(); + if (!carve::math::ZERO(s)) { + double c = 1.0 / s; + double omega = -0.5 * angle; + s = sin(omega); + x = axis.x * c * s; + y = axis.y * c * s; + z = axis.z * c * s; + w = cos(omega); + normalize(); + } else { + x = y = z = 0.0; + w = 1.0; + } + } + + double lengthSquared() const { + return x * x + y * y + z * z + w * w; + } + + double length() const { + return sqrt(lengthSquared()); + } + + Quaternion normalized() const { + return Quaternion(*this).normalize(); + } + + Quaternion &normalize() { + double l = length(); + if (l == 0.0) { + x = 1.0; y = 0.0; z = 0.0; w = 0.0; + } else { + x /= l; y /= l; z /= l; w /= l; + } + return *this; + } + }; + + struct Matrix3 { + // access: .m[col][row], .v[col * 4 + row], ._cr + union { + double m[3][3]; + double v[9]; + struct { + // transposed + double _11, _12, _13; + double _21, _22, _23; + double _31, _32, _33; + }; + }; + Matrix3(double __11, double __21, double __31, + double __12, double __22, double __32, + double __13, double __23, double __33) { + // nb, args are row major, storage is column major. + _11 = __11; _12 = __12; _13 = __13; + _21 = __21; _22 = __22; _23 = __23; + _31 = __31; _32 = __32; _33 = __33; + } + Matrix3(double _m[3][3]) { + std::memcpy(m, _m, sizeof(m)); + } + Matrix3(double _v[9]) { + std::memcpy(v, _v, sizeof(v)); + } + Matrix3() { + _11 = 1.00; _12 = 0.00; _13 = 0.00; + _21 = 0.00; _22 = 1.00; _23 = 0.00; + _31 = 0.00; _32 = 0.00; _33 = 1.00; + } + }; + + struct Matrix { + // access: .m[col][row], .v[col * 4 + row], ._cr + union { + double m[4][4]; + double v[16]; + struct { + // transposed + double _11, _12, _13, _14; + double _21, _22, _23, _24; + double _31, _32, _33, _34; + double _41, _42 ,_43, _44; + }; + }; + Matrix(double __11, double __21, double __31, double __41, + double __12, double __22, double __32, double __42, + double __13, double __23, double __33, double __43, + double __14, double __24, double __34, double __44) { + // nb, args are row major, storage is column major. + _11 = __11; _12 = __12; _13 = __13; _14 = __14; + _21 = __21; _22 = __22; _23 = __23; _24 = __24; + _31 = __31; _32 = __32; _33 = __33; _34 = __34; + _41 = __41; _42 = __42; _43 = __43; _44 = __44; + } + Matrix(double _m[4][4]) { + std::memcpy(m, _m, sizeof(m)); + } + Matrix(double _v[16]) { + std::memcpy(v, _v, sizeof(v)); + } + Matrix() { + _11 = 1.00; _12 = 0.00; _13 = 0.00; _14 = 0.00; + _21 = 0.00; _22 = 1.00; _23 = 0.00; _24 = 0.00; + _31 = 0.00; _32 = 0.00; _33 = 1.00; _34 = 0.00; + _41 = 0.00; _42 = 0.00; _43 = 0.00; _44 = 1.00; + } + + static Matrix ROT(const Quaternion &q) { + const double w = q.w; + const double x = q.x; + const double y = q.y; + const double z = q.z; + return Matrix(1 - 2*y*y - 2*z*z, 2*x*y - 2*z*w, 2*x*z + 2*y*w, 0.0, + 2*x*y + 2*z*w, 1 - 2*x*x - 2*z*z, 2*y*z - 2*x*w, 0.0, + 2*x*z - 2*y*w, 2*y*z + 2*x*w, 1 - 2*x*x - 2*y*y, 0.0, + 0.0, 0.0, 0.0, 1.0); + } + static Matrix ROT(double angle, const carve::geom::vector<3> &axis) { + return ROT(Quaternion(angle, axis)); + } + static Matrix ROT(double angle, double x, double y, double z) { + return ROT(Quaternion(angle, carve::geom::VECTOR(x, y, z))); + } + static Matrix TRANS(double x, double y, double z) { + return Matrix(1.0, 0.0, 0.0, x, + 0.0, 1.0, 0.0, y, + 0.0, 0.0, 1.0, z, + 0.0, 0.0, 0.0, 1.0); + } + static Matrix TRANS(const carve::geom::vector<3> &v) { + return TRANS(v.x, v.y, v.z); + } + static Matrix SCALE(double x, double y, double z) { + return Matrix(x, 0.0, 0.0, 0.0, + 0.0, y, 0.0, 0.0, + 0.0, 0.0, z, 0.0, + 0.0, 0.0, 0.0, 1.0); + } + static Matrix SCALE(const carve::geom::vector<3> &v) { + return SCALE(v.x, v.y, v.z); + } + static Matrix IDENT() { + return Matrix(1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0); + } + }; + + static inline bool operator==(const Matrix &A, const Matrix &B) { + for (size_t i = 0; i < 16; ++i) if (A.v[i] != B.v[i]) return false; + return true; + } + static inline bool operator!=(const Matrix &A, const Matrix &B) { + return !(A == B); + } + static inline carve::geom::vector<3> operator*(const Matrix &A, const carve::geom::vector<3> &b) { + return carve::geom::VECTOR( + A._11 * b.x + A._21 * b.y + A._31 * b.z + A._41, + A._12 * b.x + A._22 * b.y + A._32 * b.z + A._42, + A._13 * b.x + A._23 * b.y + A._33 * b.z + A._43 + ); + } + + static inline carve::geom::vector<3> &operator*=(carve::geom::vector<3> &b, const Matrix &A) { + b = A * b; + return b; + } + + static inline carve::geom::vector<3> operator*(const Matrix3 &A, const carve::geom::vector<3> &b) { + return carve::geom::VECTOR( + A._11 * b.x + A._21 * b.y + A._31 * b.z, + A._12 * b.x + A._22 * b.y + A._32 * b.z, + A._13 * b.x + A._23 * b.y + A._33 * b.z + ); + } + + static inline carve::geom::vector<3> &operator*=(carve::geom::vector<3> &b, const Matrix3 &A) { + b = A * b; + return b; + } + + static inline Matrix operator*(const Matrix &A, const Matrix &B) { + Matrix c; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + c.m[i][j] = 0.0; + for (int k = 0; k < 4; k++) { + c.m[i][j] += A.m[k][j] * B.m[i][k]; + } + } + } + return c; + } + + static inline Matrix3 operator*(const Matrix3 &A, const Matrix3 &B) { + Matrix3 c; + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + c.m[i][j] = 0.0; + for (int k = 0; k < 3; k++) { + c.m[i][j] += A.m[k][j] * B.m[i][k]; + } + } + } + return c; + } + + + + struct matrix_transformation { + Matrix matrix; + + matrix_transformation(const Matrix &_matrix) : matrix(_matrix) { + } + + carve::geom::vector<3> operator()(const carve::geom::vector<3> &vector) const { + return matrix * vector; + } + }; + + + + } +} diff -Nru blender-2.61/extern/carve/include/carve/mesh.hpp blender-2.62/extern/carve/include/carve/mesh.hpp --- blender-2.61/extern/carve/include/carve/mesh.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/mesh.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,845 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +#include +#include +#include +#include +#include +#include + +#include + +namespace carve { + namespace poly { + class Polyhedron; + } + + namespace mesh { + + + template class Edge; + template class Face; + template class Mesh; + template class MeshSet; + + + + // A Vertex may participate in several meshes. If the Mesh belongs + // to a MeshSet, then the vertices come from the vertex_storage + // member of the MeshSet. This allows one to construct one or more + // Meshes out of sets of connected faces (possibly using vertices + // from a variety of MeshSets, and other storage), then create a + // MeshSet from the Mesh(es), causing the vertices to be + // collected, cloned and repointed into the MeshSet. + + // Normally, in a half-edge structure, Vertex would have a member + // pointing to an incident edge, allowing the enumeration of + // adjacent faces and edges. Because we want to support vertex + // sharing between Meshes and groups of Faces, this is made more + // complex. If Vertex contained a list of incident edges, one from + // each disjoint face set, then this could be done (with the + // caveat that you'd need to pass in a Mesh pointer to the + // adjacency queries). However, it seems that this would + // unavoidably complicate the process of incorporating or removing + // a vertex into an edge. + + // In most cases it is expected that a vertex will be arrived at + // via an edge or face in the mesh (implicit or explicit) of + // interest, so not storing this information will not hurt, + // overly. + template + class Vertex : public tagable { + public: + typedef carve::geom::vector vector_t; + typedef MeshSet owner_t; + typedef carve::geom::aabb aabb_t; + + carve::geom::vector v; + + Vertex(const vector_t &_v) : tagable(), v(_v) { + } + + Vertex() : tagable(), v() { + } + + aabb_t getAABB() const { + return aabb_t(v, carve::geom::vector::ZERO()); + } + }; + + + + struct hash_vertex_pair { + template + size_t operator()(const std::pair *, Vertex *> &pair) const { + size_t r = (size_t)pair.first; + size_t s = (size_t)pair.second; + return r ^ ((s >> 16) | (s << 16)); + } + template + size_t operator()(const std::pair *, const Vertex *> &pair) const { + size_t r = (size_t)pair.first; + size_t s = (size_t)pair.second; + return r ^ ((s >> 16) | (s << 16)); + } + }; + + + + struct vertex_distance { + template + double operator()(const Vertex &a, const Vertex &b) const { + return carve::geom::distance(a.v, b.v); + } + + template + double operator()(const Vertex *a, const Vertex *b) const { + return carve::geom::distance(a->v, b->v); + } + }; + + + + namespace detail { + template struct list_iter_t; + template struct mapped_list_iter_t; + } + + + + // The half-edge structure proper (Edge) is maintained by Face + // instances. Together with Face instances, the half-edge + // structure defines a simple mesh (either one or two faces + // incident on each edge). + template + class Edge : public tagable { + public: + typedef Vertex vertex_t; + typedef Face face_t; + + vertex_t *vert; + face_t *face; + Edge *prev, *next, *rev; + + private: + static void _link(Edge *a, Edge *b) { + a->next = b; b->prev = a; + } + + static void _freeloop(Edge *s) { + Edge *e = s; + do { + Edge *n = e->next; + delete e; + e = n; + } while (e != s); + } + + static void _setloopface(Edge *s, face_t *f) { + Edge *e = s; + do { + e->face = f; + e = e->next; + } while (e != s); + } + + static size_t _looplen(Edge *s) { + Edge *e = s; + face_t *f = s->face; + size_t c = 0; + do { + ++c; + CARVE_ASSERT(e->rev->rev == e); + CARVE_ASSERT(e->next->prev == e); + CARVE_ASSERT(e->face == f); + e = e->next; + } while (e != s); + return c; + } + + public: + void validateLoop() { + Edge *e = this; + face_t *f = face; + size_t c = 0; + do { + ++c; + CARVE_ASSERT(e->rev == NULL || e->rev->rev == e); + CARVE_ASSERT(e->next == e || e->next->vert != e->vert); + CARVE_ASSERT(e->prev == e || e->prev->vert != e->vert); + CARVE_ASSERT(e->next->prev == e); + CARVE_ASSERT(e->prev->next == e); + CARVE_ASSERT(e->face == f); + e = e->next; + } while (e != this); + CARVE_ASSERT(f == NULL || c == f->n_edges); + } + + size_t loopLen() { + return _looplen(this); + } + + Edge *mergeFaces(); + + Edge *removeHalfEdge(); + + // Remove and delete this edge. + Edge *removeEdge(); + + // Unlink this edge from its containing edge loop. disconnect + // rev links. The rev links of the previous edge also change, as + // its successor vertex changes. + void unlink(); + + // Insert this edge into a loop before other. If edge was + // already in a loop, it needs to be removed first. + void insertBefore(Edge *other); + + // Insert this edge into a loop after other. If edge was + // already in a loop, it needs to be removed first. + void insertAfter(Edge *other); + + size_t loopSize() const; + + vertex_t *v1() { return vert; } + vertex_t *v2() { return next->vert; } + + const vertex_t *v1() const { return vert; } + const vertex_t *v2() const { return next->vert; } + + Edge *perimNext() const; + Edge *perimPrev() const; + + double length2() const { + return (v1()->v - v2()->v).length2(); + } + + double length() const { + return (v1()->v - v2()->v).length(); + } + + Edge(vertex_t *_vert, face_t *_face); + + ~Edge(); + }; + + + + // A Face contains a pointer to the beginning of the half-edge + // circular list that defines its boundary. + template + class Face : public tagable { + public: + typedef Vertex vertex_t; + typedef Edge edge_t; + typedef Mesh mesh_t; + + typedef typename Vertex::vector_t vector_t; + typedef carve::geom::aabb aabb_t; + typedef carve::geom::plane plane_t; + typedef carve::geom::vector<2> (*project_t)(const vector_t &); + typedef vector_t (*unproject_t)(const carve::geom::vector<2> &, const plane_t &); + + struct vector_mapping { + typedef typename vertex_t::vector_t value_type; + + value_type operator()(const carve::geom::vector &v) const { return v; } + value_type operator()(const carve::geom::vector *v) const { return *v; } + value_type operator()(const Edge &e) const { return e.vert->v; } + value_type operator()(const Edge *e) const { return e->vert->v; } + value_type operator()(const Vertex &v) const { return v.v; } + value_type operator()(const Vertex *v) const { return v->v; } + }; + + struct projection_mapping { + typedef carve::geom::vector<2> value_type; + project_t proj; + projection_mapping(project_t _proj) : proj(_proj) { } + value_type operator()(const carve::geom::vector &v) const { return proj(v); } + value_type operator()(const carve::geom::vector *v) const { return proj(*v); } + value_type operator()(const Edge &e) const { return proj(e.vert->v); } + value_type operator()(const Edge *e) const { return proj(e->vert->v); } + value_type operator()(const Vertex &v) const { return proj(v.v); } + value_type operator()(const Vertex *v) const { return proj(v->v); } + }; + + edge_t *edge; + size_t n_edges; + mesh_t *mesh; + size_t id; + + plane_t plane; + project_t project; + unproject_t unproject; + + private: + Face &operator=(const Face &other); + + protected: + Face() : edge(NULL), n_edges(0), mesh(NULL), id(0), plane(), project(NULL), unproject(NULL) { + } + + Face(const Face &other) : + edge(NULL), n_edges(other.n_edges), mesh(NULL), id(other.id), + plane(other.plane), project(other.project), unproject(other.unproject) { + } + + project_t getProjector(bool positive_facing, int axis) const; + unproject_t getUnprojector(bool positive_facing, int axis) const; + + public: + typedef detail::list_iter_t > edge_iter_t; + typedef detail::list_iter_t > const_edge_iter_t; + + edge_iter_t begin() { return edge_iter_t(edge, 0); } + edge_iter_t end() { return edge_iter_t(edge, n_edges); } + + const_edge_iter_t begin() const { return const_edge_iter_t(edge, 0); } + const_edge_iter_t end() const { return const_edge_iter_t(edge, n_edges); } + + bool containsPoint(const vector_t &p) const; + bool containsPointInProjection(const vector_t &p) const; + bool simpleLineSegmentIntersection( + const carve::geom::linesegment &line, + vector_t &intersection) const; + IntersectionClass lineSegmentIntersection( + const carve::geom::linesegment &line, + vector_t &intersection) const; + + aabb_t getAABB() const; + + bool recalc(); + + void clearEdges(); + + // build an edge loop in forward orientation from an iterator pair + template + void loopFwd(iter_t vbegin, iter_t vend); + + // build an edge loop in reverse orientation from an iterator pair + template + void loopRev(iter_t vbegin, iter_t vend); + + // initialize a face from an ordered list of vertices. + template + void init(iter_t begin, iter_t end); + + // initialization of a triangular face. + void init(vertex_t *a, vertex_t *b, vertex_t *c); + + // initialization of a quad face. + void init(vertex_t *a, vertex_t *b, vertex_t *c, vertex_t *d); + + void getVertices(std::vector &verts) const; + void getProjectedVertices(std::vector > &verts) const; + + projection_mapping projector() const { + return projection_mapping(project); + } + + std::pair rangeInDirection(const vector_t &v, const vector_t &b) const { + edge_t *e = edge; + double lo, hi; + lo = hi = carve::geom::dot(v, e->vert->v - b); + e = e->next; + for (; e != edge; e = e->next) { + double d = carve::geom::dot(v, e->vert->v - b); + lo = std::min(lo, d); + hi = std::max(hi, d); + } + return std::make_pair(lo, hi); + } + + size_t nVertices() const { + return n_edges; + } + + size_t nEdges() const { + return n_edges; + } + + vector_t centroid() const; + + static Face *closeLoop(edge_t *open_edge); + + Face(edge_t *e) : edge(e), n_edges(0), mesh(NULL) { + do { + e->face = this; + n_edges++; + e = e->next; + } while (e != edge); + recalc(); + } + + Face(vertex_t *a, vertex_t *b, vertex_t *c) : edge(NULL), n_edges(0), mesh(NULL) { + init(a, b, c); + recalc(); + } + + Face(vertex_t *a, vertex_t *b, vertex_t *c, vertex_t *d) : edge(NULL), n_edges(0), mesh(NULL) { + init(a, b, c, d); + recalc(); + } + + template + Face(iter_t begin, iter_t end) : edge(NULL), n_edges(0), mesh(NULL) { + init(begin, end); + recalc(); + } + + template + Face *create(iter_t beg, iter_t end, bool reversed) const; + + Face *clone(const vertex_t *old_base, vertex_t *new_base, std::unordered_map &edge_map) const; + + void remove() { + edge_t *e = edge; + do { + if (e->rev) e->rev->rev = NULL; + e = e->next; + } while (e != edge); + } + + void invert() { + // We invert the direction of the edges of the face in this + // way so that the edge rev pointers (if any) are still + // correct. It is expected that invert() will be called on + // every other face in the mesh, too, otherwise everything + // will get messed up. + + { + // advance vertices. + edge_t *e = edge; + vertex_t *va = e->vert; + do { + e->vert = e->next->vert; + e = e->next; + } while (e != edge); + edge->prev->vert = va; + } + + { + // swap prev and next pointers. + edge_t *e = edge; + do { + edge_t *n = e->next; + std::swap(e->prev, e->next); + e = n; + } while (e != edge); + } + + plane.negate(); + + int da = carve::geom::largestAxis(plane.N); + + project = getProjector(plane.N.v[da] > 0, da); + unproject = getUnprojector(plane.N.v[da] > 0, da); + } + + void canonicalize(); + + ~Face() { + clearEdges(); + } + }; + + + + namespace detail { + class FaceStitcher { + typedef Vertex<3> vertex_t; + typedef Edge<3> edge_t; + typedef Face<3> face_t; + + typedef std::pair vpair_t; + typedef std::list edgelist_t; + typedef std::unordered_map edge_map_t; + typedef std::unordered_map > edge_graph_t; + + edge_map_t edges; + edge_map_t complex_edges; + + carve::djset::djset face_groups; + std::vector is_open; + + edge_graph_t edge_graph; + + struct EdgeOrderData { + size_t group_id; + bool is_reversed; + carve::geom::vector<3> face_dir; + edge_t *edge; + + EdgeOrderData(edge_t *_edge, size_t _group_id, bool _is_reversed) : + group_id(_group_id), + is_reversed(_is_reversed) { + if (is_reversed) { + face_dir = -(_edge->face->plane.N); + } else { + face_dir = (_edge->face->plane.N); + } + edge = _edge; + } + + struct TestGroups { + size_t fwd, rev; + + TestGroups(size_t _fwd, size_t _rev) : fwd(_fwd), rev(_rev) { + } + + bool operator()(const EdgeOrderData &eo) const { + return eo.group_id == (eo.is_reversed ? rev : fwd); + } + }; + + struct Cmp { + carve::geom::vector<3> edge_dir; + carve::geom::vector<3> base_dir; + + Cmp(const carve::geom::vector<3> &_edge_dir, + const carve::geom::vector<3> &_base_dir) : + edge_dir(_edge_dir), + base_dir(_base_dir) { + } + bool operator()(const EdgeOrderData &a, const EdgeOrderData &b) const; + }; + }; + + void extractConnectedEdges(std::vector::iterator begin, + std::vector::iterator end, + std::vector *> > &efwd, + std::vector *> > &erev); + + size_t faceGroupID(const Face<3> *face); + size_t faceGroupID(const Edge<3> *edge); + + void resolveOpenEdges(); + + void fuseEdges(std::vector *> &fwd, + std::vector *> &rev); + + void joinGroups(std::vector *> > &efwd, + std::vector *> > &erev, + size_t fwd_grp, + size_t rev_grp); + + void matchOrderedEdges(const std::vector >::iterator begin, + const std::vector >::iterator end, + std::vector *> > &efwd, + std::vector *> > &erev); + + void reorder(std::vector &ordering, size_t fwd_grp); + + void orderForwardAndReverseEdges(std::vector *> > &efwd, + std::vector *> > &erev, + std::vector > &result); + + void edgeIncidentGroups(const vpair_t &e, + const edge_map_t &all_edges, + std::pair, std::set > &groups); + + void buildEdgeGraph(const edge_map_t &all_edges); + void extractPath(std::vector &path); + void removePath(const std::vector &path); + void matchSimpleEdges(); + void construct(); + + template + void initEdges(iter_t begin, iter_t end); + + template + void build(iter_t begin, iter_t end, std::vector *> &meshes); + + public: + template + void create(iter_t begin, iter_t end, std::vector *> &meshes); + }; + } + + + + // A Mesh is a connected set of faces. It may be open (some edges + // have NULL rev members), or closed. On destruction, a Mesh + // should free its Faces (which will in turn free Edges, but not + // Vertices). A Mesh is edge-connected, which is to say that each + // face in the mesh shares an edge with at least one other face in + // the mesh. Touching at a vertex is not sufficient. This means + // that the perimeter of an open mesh visits each vertex no more + // than once. + template + class Mesh { + public: + typedef Vertex vertex_t; + typedef Edge edge_t; + typedef Face face_t; + typedef carve::geom::aabb aabb_t; + typedef MeshSet meshset_t; + + std::vector faces; + + // open_edges is a vector of all the edges in the mesh that + // don't have a matching edge in the opposite direction. + std::vector open_edges; + + // closed_edges is a vector of all the edges in the mesh that + // have a matching edge in the opposite direction, and whose + // address is lower than their counterpart. (i.e. for each pair + // of adjoining faces, one of the two half edges is stored in + // closed_edges). + std::vector closed_edges; + + bool is_negative; + + meshset_t *meshset; + + protected: + Mesh(std::vector &_faces, + std::vector &_open_edges, + std::vector &_closed_edges, + bool _is_negative); + + public: + Mesh(std::vector &_faces); + + ~Mesh(); + + template + static void create(iter_t begin, iter_t end, std::vector *> &meshes); + + aabb_t getAABB() const { + return aabb_t(faces.begin(), faces.end()); + } + + bool isClosed() const { + return open_edges.size() == 0; + } + + bool isNegative() const { + return is_negative; + } + + double volume() const { + if (is_negative || !faces.size()) return 0.0; + + double vol = 0.0; + typename vertex_t::vector_t origin = faces[0]->edge->vert->v; + + for (size_t f = 0; f < faces.size(); ++f) { + face_t *face = faces[f]; + edge_t *e1 = face->edge; + for (edge_t *e2 = e1->next ;e2->next != e1; e2 = e2->next) { + vol += carve::geom3d::tetrahedronVolume(e1->vert->v, e2->vert->v, e2->next->vert->v, origin); + } + } + return vol; + } + + struct IsClosed { + bool operator()(const Mesh &mesh) const { return mesh.isClosed(); } + bool operator()(const Mesh *mesh) const { return mesh->isClosed(); } + }; + + struct IsNegative { + bool operator()(const Mesh &mesh) const { return mesh.isNegative(); } + bool operator()(const Mesh *mesh) const { return mesh->isNegative(); } + }; + + void cacheEdges(); + + void calcOrientation(); + + void recalc() { + for (size_t i = 0; i < faces.size(); ++i) faces[i]->recalc(); + calcOrientation(); + } + + void invert() { + for (size_t i = 0; i < faces.size(); ++i) { + faces[i]->invert(); + } + if (isClosed()) is_negative = !is_negative; + } + + Mesh *clone(const vertex_t *old_base, vertex_t *new_base) const; + }; + + // A MeshSet manages vertex storage, and a collection of meshes. + // It should be easy to turn a vertex pointer into its index in + // its MeshSet vertex_storage. + template + class MeshSet { + MeshSet(); + MeshSet(const MeshSet &); + MeshSet &operator=(const MeshSet &); + + template + void _init_from_faces(iter_t begin, iter_t end); + + public: + typedef Vertex vertex_t; + typedef Edge edge_t; + typedef Face face_t; + typedef Mesh mesh_t; + typedef carve::geom::aabb aabb_t; + + std::vector vertex_storage; + std::vector meshes; + + public: + template + struct FaceIter : public std::iterator { + typedef std::iterator super; + typedef typename super::difference_type difference_type; + + const MeshSet *obj; + size_t mesh, face; + + FaceIter(const MeshSet *_obj, size_t _mesh, size_t _face); + + void fwd(size_t n); + void rev(size_t n); + void adv(int n); + + FaceIter operator++(int) { FaceIter tmp = *this; tmp.fwd(1); return tmp; } + FaceIter operator+(int v) { FaceIter tmp = *this; tmp.adv(v); return tmp; } + FaceIter &operator++() { fwd(1); return *this; } + FaceIter &operator+=(int v) { adv(v); return *this; } + + FaceIter operator--(int) { FaceIter tmp = *this; tmp.rev(1); return tmp; } + FaceIter operator-(int v) { FaceIter tmp = *this; tmp.adv(-v); return tmp; } + FaceIter &operator--() { rev(1); return *this; } + FaceIter &operator-=(int v) { adv(-v); return *this; } + + difference_type operator-(const FaceIter &other) const; + + bool operator==(const FaceIter &other) const { + return obj == other.obj && mesh == other.mesh && face == other.face; + } + bool operator!=(const FaceIter &other) const { + return !(*this == other); + } + bool operator<(const FaceIter &other) const { + CARVE_ASSERT(obj == other.obj); + return mesh < other.mesh || (mesh == other.mesh && face < other.face); + } + bool operator>(const FaceIter &other) const { + return other < *this; + } + bool operator<=(const FaceIter &other) const { + return !(other < *this); + } + bool operator>=(const FaceIter &other) const { + return !(*this < other); + } + + face_type operator*() const { + return obj->meshes[mesh]->faces[face]; + } + }; + + typedef FaceIter const_face_iter; + typedef FaceIter face_iter; + + face_iter faceBegin() { return face_iter(this, 0, 0); } + face_iter faceEnd() { return face_iter(this, meshes.size(), 0); } + + const_face_iter faceBegin() const { return const_face_iter(this, 0, 0); } + const_face_iter faceEnd() const { return const_face_iter(this, meshes.size(), 0); } + + aabb_t getAABB() const { + return aabb_t(meshes.begin(), meshes.end()); + } + + template + void transform(func_t func) { + for (size_t i = 0; i < vertex_storage.size(); ++i) { + vertex_storage[i].v = func(vertex_storage[i].v); + } + for (size_t i = 0; i < meshes.size(); ++i) { + meshes[i]->recalc(); + } + } + + MeshSet(const std::vector &points, + size_t n_faces, + const std::vector &face_indices); + + // Construct a mesh set from a set of disconnected faces. Takes + // posession of the face pointers. + MeshSet(std::vector &faces); + + MeshSet(std::list &faces); + + MeshSet(std::vector &_vertex_storage, + std::vector &_meshes); + + // This constructor consolidates and rewrites vertex pointers in + // each mesh, repointing them to local storage. + MeshSet(std::vector &_meshes); + + MeshSet *clone() const; + + ~MeshSet(); + + bool isClosed() const { + for (size_t i = 0; i < meshes.size(); ++i) { + if (!meshes[i]->isClosed()) return false; + } + return true; + } + + + void invert() { + for (size_t i = 0; i < meshes.size(); ++i) { + meshes[i]->invert(); + } + } + + void collectVertices(); + + void canonicalize(); + }; + + + + carve::PointClass classifyPoint( + const carve::mesh::MeshSet<3> *meshset, + const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *face_rtree, + const carve::geom::vector<3> &v, + bool even_odd = false, + const carve::mesh::Mesh<3> *mesh = NULL, + const carve::mesh::Face<3> **hit_face = NULL); + + + + } + + + + mesh::MeshSet<3> *meshFromPolyhedron(const poly::Polyhedron *, int manifold_id); + poly::Polyhedron *polyhedronFromMesh(const mesh::MeshSet<3> *, int manifold_id); + + + +}; + +#include diff -Nru blender-2.61/extern/carve/include/carve/mesh_impl.hpp blender-2.62/extern/carve/include/carve/mesh_impl.hpp --- blender-2.61/extern/carve/include/carve/mesh_impl.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/mesh_impl.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,1015 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include +#include +#include + +#include +#include + +#include + +namespace carve { + namespace mesh { + + + + namespace detail { + template + struct list_iter_t { + typedef std::bidirectional_iterator_tag iterator_category; + typedef list_t value_type; + typedef ptrdiff_t difference_type; + typedef value_type & reference; + typedef value_type * pointer; + + list_t *curr; + int pos; + + list_iter_t() { } + list_iter_t(list_t *_curr, int _pos) : curr(_curr), pos(_pos) { } + + list_iter_t operator++(int) { list_iter_t result(*this); ++pos; curr = curr->next; return result; } + list_iter_t operator--(int) { list_iter_t result(*this); --pos; curr = curr->prev; return result; } + + list_iter_t operator++() { ++pos; curr = curr->next; return *this; } + list_iter_t operator--() { --pos; curr = curr->prev; return *this; } + + bool operator==(const list_iter_t &other) const { return curr == other.curr && pos == other.pos; } + bool operator!=(const list_iter_t &other) const { return curr != other.curr || pos != other.pos; } + + reference operator*() { return *curr; } + pointer operator->() { return curr; } + + int idx() const { return pos; } + }; + } + + + + template + Edge *Edge::mergeFaces() { + if (rev == NULL) return NULL; + + face_t *fwdface = face; + face_t *revface = rev->face; + + size_t n_removed = 0; + + Edge *splice_beg = this; + do { + splice_beg = splice_beg->prev; + ++n_removed; + } while (splice_beg != this && + splice_beg->rev && + splice_beg->next->rev->prev == splice_beg->rev); + + if (splice_beg == this) { + // edge loops are completely matched. + return NULL; + } + + Edge *splice_end = this; + do { + splice_end = splice_end->next; + ++n_removed; + } while (splice_end->rev && + splice_end->prev->rev->next == splice_end->rev); + + --n_removed; + + Edge *link1_p = splice_beg; + Edge *link1_n = splice_beg->next->rev->next; + + Edge *link2_p = splice_end->prev->rev->prev; + Edge *link2_n = splice_end; + + CARVE_ASSERT(link1_p->face == fwdface); + CARVE_ASSERT(link1_n->face == revface); + + CARVE_ASSERT(link2_p->face == revface); + CARVE_ASSERT(link2_n->face == fwdface); + + Edge *left_loop = link1_p->next; + + CARVE_ASSERT(left_loop->rev == link1_n->prev); + + _link(link2_n->prev, link1_p->next); + _link(link1_n->prev, link2_p->next); + + _link(link1_p, link1_n); + _link(link2_p, link2_n); + + fwdface->edge = link1_p; + + for (Edge *e = link1_n; e != link2_n; e = e->next) { + CARVE_ASSERT(e->face == revface); + e->face = fwdface; + fwdface->n_edges++; + } + for (Edge *e = link2_n; e != link1_n; e = e->next) { + CARVE_ASSERT(e->face == fwdface); + } + + fwdface->n_edges -= n_removed; + + revface->n_edges = 0; + revface->edge = NULL; + + _setloopface(left_loop, NULL); + _setloopface(left_loop->rev, NULL); + + return left_loop; + } + + + + template + Edge *Edge::removeHalfEdge() { + Edge *n = NULL; + if (face) { + face->n_edges--; + } + + if (next == this) { + if (face) face->edge = NULL; + } else { + if (face && face->edge == this) face->edge = next; + next->prev = prev; + prev->next = next; + n = next; + } + delete this; + return n; + } + + + + template + Edge *Edge::removeEdge() { + if (rev) { + rev->removeHalfEdge(); + } + return removeHalfEdge(); + } + + + + template + void Edge::unlink() { + if (rev) { rev->rev = NULL; rev = NULL; } + if (prev->rev) { prev->rev->rev = NULL; prev->rev = NULL; } + + if (face) { + face->n_edges--; + if (face->edge == this) face->edge = next; + face = NULL; + } + + next->prev = prev; + prev->next = next; + + prev = next = this; + } + + + + template + void Edge::insertBefore(Edge *other) { + if (prev != this) unlink(); + prev = other->prev; + next = other; + next->prev = this; + prev->next = this; + + if (prev->rev) { prev->rev->rev = NULL; prev->rev = NULL; } + } + + + + template + void Edge::insertAfter(Edge *other) { + if (prev != this) unlink(); + next = other->next; + prev = other; + next->prev = this; + prev->next = this; + + if (prev->rev) { prev->rev->rev = NULL; prev->rev = NULL; } + } + + + + template + size_t Edge::loopSize() const { + const Edge *e = this; + size_t n = 0; + do { e = e->next; ++n; } while (e != this); + return n; + } + + + + template + Edge *Edge::perimNext() const { + if (rev) return NULL; + Edge *e = next; + while(e->rev) { + e = e->rev->next; + } + return e; + } + + + + template + Edge *Edge::perimPrev() const { + if (rev) return NULL; + Edge *e = prev; + while(e->rev) { + e = e->rev->prev; + } + return e; + } + + + + template + Edge::Edge(vertex_t *_vert, face_t *_face) : + vert(_vert), face(_face), prev(NULL), next(NULL), rev(NULL) { + prev = next = this; + } + + + + template + Edge::~Edge() { + } + + + + template + typename Face::aabb_t Face::getAABB() const { + aabb_t aabb; + aabb.fit(begin(), end(), vector_mapping()); + return aabb; + } + + + + template + bool Face::recalc() { + if (!carve::geom3d::fitPlane(begin(), end(), vector_mapping(), plane)) { + return false; + } + + int da = carve::geom::largestAxis(plane.N); + double A = carve::geom2d::signedArea(begin(), end(), projection_mapping(getProjector(false, da))); + + if ((A < 0.0) ^ (plane.N.v[da] < 0.0)) { + plane.negate(); + } + + project = getProjector(plane.N.v[da] > 0, da); + unproject = getUnprojector(plane.N.v[da] > 0, da); + + return true; + } + + + + template + void Face::clearEdges() { + if (!edge) return; + + edge_t *curr = edge; + do { + edge_t *next = curr->next; + delete curr; + curr = next; + } while (curr != edge); + + edge = NULL; + + n_edges = 0; + } + + + + template + template + void Face::loopFwd(iter_t begin, iter_t end) { + clearEdges(); + if (begin == end) return; + edge = new edge_t(*begin, this); ++n_edges; ++begin; + while (begin != end) { + edge_t *e = new edge_t(*begin, this); + e->insertAfter(edge->prev); + ++n_edges; + ++begin; + } + } + + + + template + template + void Face::loopRev(iter_t begin, iter_t end) { + clearEdges(); + if (begin == end) return; + edge = new edge_t(*begin, this); ++n_edges; ++begin; + while (begin != end) { + edge_t *e = new edge_t(*begin, this); + e->insertBefore(edge->next); + ++n_edges; + ++begin; + } + } + + + + template + template + void Face::init(iter_t begin, iter_t end) { + loopFwd(begin, end); + } + + + + template + void Face::init(vertex_t *a, vertex_t *b, vertex_t *c) { + clearEdges(); + edge_t *ea = new edge_t(a, this); + edge_t *eb = new edge_t(b, this); + edge_t *ec = new edge_t(c, this); + eb->insertAfter(ea); + ec->insertAfter(eb); + edge = ea; + n_edges = 3; + } + + + + template + void Face::init(vertex_t *a, vertex_t *b, vertex_t *c, vertex_t *d) { + clearEdges(); + edge_t *ea = new edge_t(a, this); + edge_t *eb = new edge_t(b, this); + edge_t *ec = new edge_t(c, this); + edge_t *ed = new edge_t(d, this); + eb->insertAfter(ea); + ec->insertAfter(eb); + ed->insertAfter(ec); + edge = ea; + n_edges = 4; + } + + + + template + void Face::getVertices(std::vector &verts) const { + verts.clear(); + verts.reserve(n_edges); + const edge_t *e = edge; + do { verts.push_back(e->vert); e = e->next; } while (e != edge); + } + + + + template + void Face::getProjectedVertices(std::vector > &verts) const { + verts.clear(); + verts.reserve(n_edges); + const edge_t *e = edge; + do { verts.push_back(project(e->vert->v)); e = e->next; } while (e != edge); + } + + + + template + typename Face::vector_t Face::centroid() const { + vector_t v; + edge_t *e = edge; + do { + v += e->vert->v; + e = e->next; + } while(e != edge); + v /= n_edges; + return v; + } + + + + template + void Face::canonicalize() { + edge_t *min = edge; + edge_t *e = edge; + + do { + if (e->vert < min->vert) min = e; + e = e->next; + } while (e != edge); + + edge = min; + } + + + + template + template + Face *Face::create(iter_t beg, iter_t end, bool reversed) const { + Face *r = new Face(); + + if (reversed) { + r->loopRev(beg, end); + r->plane = -plane; + } else { + r->loopFwd(beg, end); + r->plane = plane; + } + + int da = carve::geom::largestAxis(r->plane.N); + + r->project = r->getProjector(r->plane.N.v[da] > 0, da); + r->unproject = r->getUnprojector(r->plane.N.v[da] > 0, da); + + return r; + } + + + + template + Face *Face::clone(const vertex_t *old_base, + vertex_t *new_base, + std::unordered_map &edge_map) const { + Face *r = new Face(*this); + + edge_t *e = edge; + edge_t *r_p = NULL; + edge_t *r_e; + do { + r_e = new edge_t(e->vert - old_base + new_base, r); + edge_map[e] = r_e; + if (r_p) { + r_p->next = r_e; + r_e->prev = r_p; + } else { + r->edge = r_e; + } + r_p = r_e; + + if (e->rev) { + typename std::unordered_map::iterator rev_i = edge_map.find(e->rev); + if (rev_i != edge_map.end()) { + r_e->rev = (*rev_i).second; + (*rev_i).second->rev = r_e; + } + } + + e = e->next; + } while (e != edge); + r_e->next = r->edge; + r->edge->prev = r_e; + return r; + } + + + + template + Mesh::Mesh(std::vector &_faces, + std::vector &_open_edges, + std::vector &_closed_edges, + bool _is_negative) { + std::swap(faces, _faces); + std::swap(open_edges, _open_edges); + std::swap(closed_edges, _closed_edges); + is_negative = _is_negative; + meshset = NULL; + + for (size_t i = 0; i < faces.size(); ++i) { + faces[i]->mesh = this; + } + } + + + + namespace detail { + template + void FaceStitcher::initEdges(iter_t begin, + iter_t end) { + size_t c = 0; + for (iter_t i = begin; i != end; ++i) { + face_t *face = *i; + CARVE_ASSERT(face->mesh == NULL); // for the moment, can only insert a face into a mesh once. + + face->id = c++; + edge_t *e = face->edge; + do { + edges[vpair_t(e->v1(), e->v2())].push_back(e); + e = e->next; + if (e->rev) { e->rev->rev = NULL; e->rev = NULL; } + } while (e != face->edge); + } + face_groups.init(c); + is_open.clear(); + is_open.resize(c, false); + } + + template + void FaceStitcher::build(iter_t begin, + iter_t end, + std::vector *> &meshes) { + // work out what set each face belongs to, and then construct + // mesh instances for each set of faces. + std::vector index_set; + std::vector set_size; + face_groups.get_index_to_set(index_set, set_size); + + std::vector > mesh_faces; + mesh_faces.resize(set_size.size()); + for (size_t i = 0; i < set_size.size(); ++i) { + mesh_faces[i].reserve(set_size[i]); + } + + for (iter_t i = begin; i != end; ++i) { + face_t *face = *i; + mesh_faces[index_set[face->id]].push_back(face); + } + + meshes.clear(); + meshes.reserve(mesh_faces.size()); + for (size_t i = 0; i < mesh_faces.size(); ++i) { + meshes.push_back(new Mesh<3>(mesh_faces[i])); + } + } + + template + void FaceStitcher::create(iter_t begin, + iter_t end, + std::vector *> &meshes) { + initEdges(begin, end); + construct(); + build(begin, end, meshes); + } + } + + + + template + void Mesh::cacheEdges() { + closed_edges.clear(); + open_edges.clear(); + + for (size_t i = 0; i < faces.size(); ++i) { + face_t *face = faces[i]; + edge_t *e = face->edge; + do { + if (e->rev == NULL) { + open_edges.push_back(e); + } else if (e < e->rev) { + closed_edges.push_back(e); + } + e = e->next; + } while (e != face->edge); + } + } + + + + template + Mesh::Mesh(std::vector &_faces) : faces(), open_edges(), closed_edges(), meshset(NULL) { + faces.swap(_faces); + for (size_t i = 0; i < faces.size(); ++i) { + faces[i]->mesh = this; + } + cacheEdges(); + calcOrientation(); + } + + + + template + void Mesh::calcOrientation() { + if (open_edges.size() || !closed_edges.size()) { + is_negative = false; + } else { + edge_t *emin = closed_edges[0]; + if (emin->rev->v1()->v < emin->v1()->v) emin = emin->rev; + for (size_t i = 1; i < closed_edges.size(); ++i) { + if (closed_edges[i]->v1()->v < emin->v1()->v) emin = closed_edges[i]; + if (closed_edges[i]->rev->v1()->v < emin->v1()->v) emin = closed_edges[i]->rev; + } + + std::vector min_faces; + edge_t *e = emin; + do { + min_faces.push_back(e->face); + CARVE_ASSERT(e->rev != NULL); + e = e->rev->next; + CARVE_ASSERT(e->v1() == emin->v1()); + CARVE_ASSERT(e->v1()->v < e->v2()->v); + CARVE_ASSERT(e->v1()->v.x <= e->v2()->v.x); + } while (e != emin); + + double max_abs_x = 0.0; + for (size_t f = 0; f < min_faces.size(); ++f) { + if (fabs(min_faces[f]->plane.N.x) > fabs(max_abs_x)) max_abs_x = min_faces[f]->plane.N.x; + } + is_negative = max_abs_x > 0.0; + } + } + + + + template + Mesh *Mesh::clone(const vertex_t *old_base, + vertex_t *new_base) const { + std::vector r_faces; + std::vector r_open_edges; + std::vector r_closed_edges; + std::unordered_map edge_map; + + r_faces.reserve(faces.size()); + r_open_edges.reserve(r_open_edges.size()); + r_closed_edges.reserve(r_closed_edges.size()); + + for (size_t i = 0; i < faces.size(); ++i) { + r_faces.push_back(faces[i]->clone(old_base, new_base, edge_map)); + } + for (size_t i = 0; i < closed_edges.size(); ++i) { + r_closed_edges.push_back(edge_map[closed_edges[i]]); + r_closed_edges.back()->rev = edge_map[closed_edges[i]->rev]; + } + for (size_t i = 0; i < open_edges.size(); ++i) { + r_open_edges.push_back(edge_map[open_edges[i]]); + } + + return new Mesh(r_faces, r_open_edges, r_closed_edges, is_negative); + } + + + + template + Mesh::~Mesh() { + for (size_t i = 0; i < faces.size(); ++i) { + delete faces[i]; + } + } + + + + template + template + void Mesh::create(iter_t begin, iter_t end, std::vector *> &meshes) { + meshes.clear(); + } + + + + template<> + template + void Mesh<3>::create(iter_t begin, iter_t end, std::vector *> &meshes) { + detail::FaceStitcher().create(begin, end, meshes); + } + + + + template + template + void MeshSet::_init_from_faces(iter_t begin, iter_t end) { + typedef std::unordered_map map_t; + map_t vmap; + + for (iter_t i = begin; i != end; ++i) { + face_t *f = *i; + edge_t *e = f->edge; + do { + typename map_t::const_iterator j = vmap.find(e->vert); + if (j == vmap.end()) { + size_t idx = vmap.size(); + vmap[e->vert] = idx; + } + e = e->next; + } while (e != f->edge); + } + + vertex_storage.resize(vmap.size()); + for (typename map_t::const_iterator i = vmap.begin(); i != vmap.end(); ++i) { + vertex_storage[(*i).second].v = (*i).first->v; + } + + for (iter_t i = begin; i != end; ++i) { + face_t *f = *i; + edge_t *e = f->edge; + do { + e->vert = &vertex_storage[vmap[e->vert]]; + e = e->next; + } while (e != f->edge); + } + + mesh_t::create(begin, end, meshes); + + for (size_t i = 0; i < meshes.size(); ++i) { + meshes[i]->meshset = this; + } + } + + + + template + MeshSet::MeshSet(const std::vector::vertex_t::vector_t> &points, + size_t n_faces, + const std::vector &face_indices) { + vertex_storage.reserve(points.size()); + std::vector faces; + faces.reserve(n_faces); + for (size_t i = 0; i < points.size(); ++i) { + vertex_storage.push_back(vertex_t(points[i])); + } + + std::vector v; + size_t p = 0; + for (size_t i = 0; i < n_faces; ++i) { + const size_t N = face_indices[p++]; + v.clear(); + v.reserve(N); + for (size_t j = 0; j < N; ++j) { + v.push_back(&vertex_storage[face_indices[p++]]); + } + faces.push_back(new face_t(v.begin(), v.end())); + } + CARVE_ASSERT(p == face_indices.size()); + mesh_t::create(faces.begin(), faces.end(), meshes); + + for (size_t i = 0; i < meshes.size(); ++i) { + meshes[i]->meshset = this; + } + } + + + + template + MeshSet::MeshSet(std::vector &faces) { + _init_from_faces(faces.begin(), faces.end()); + } + + + + template + MeshSet::MeshSet(std::list &faces) { + _init_from_faces(faces.begin(), faces.end()); + } + + + + template + MeshSet::MeshSet(std::vector &_vertex_storage, + std::vector &_meshes) { + vertex_storage.swap(_vertex_storage); + meshes.swap(_meshes); + + for (size_t i = 0; i < meshes.size(); ++i) { + meshes[i]->meshset = this; + } + } + + + + template + MeshSet::MeshSet(std::vector::mesh_t *> &_meshes) { + meshes.swap(_meshes); + std::unordered_map vert_idx; + + for (size_t m = 0; m < meshes.size(); ++m) { + mesh_t *mesh = meshes[m]; + CARVE_ASSERT(mesh->meshset == NULL); + mesh->meshset = this; + for (size_t f = 0; f < mesh->faces.size(); ++f) { + face_t *face = mesh->faces[f]; + edge_t *edge = face->edge; + do { + vert_idx[edge->vert] = 0; + edge = edge->next; + } while (edge != face->edge); + } + } + + vertex_storage.reserve(vert_idx.size()); + for (typename std::unordered_map::iterator i = vert_idx.begin(); i != vert_idx.end(); ++i) { + (*i).second = vertex_storage.size(); + vertex_storage.push_back(*(*i).first); + } + + for (size_t m = 0; m < meshes.size(); ++m) { + mesh_t *mesh = meshes[m]; + for (size_t f = 0; f < mesh->faces.size(); ++f) { + face_t *face = mesh->faces[f]; + edge_t *edge = face->edge; + do { + size_t i = vert_idx[edge->vert]; + edge->vert = &vertex_storage[i]; + edge = edge->next; + } while (edge != face->edge); + } + } + } + + + + template + MeshSet *MeshSet::clone() const { + std::vector r_vertex_storage = vertex_storage; + std::vector r_meshes; + for (size_t i = 0; i < meshes.size(); ++i) { + r_meshes.push_back(meshes[i]->clone(&vertex_storage[0], &r_vertex_storage[0])); + } + + return new MeshSet(r_vertex_storage, r_meshes); + } + + + + template + MeshSet::~MeshSet() { + for (size_t i = 0; i < meshes.size(); ++i) { + delete meshes[i]; + } + } + + + + template + template + MeshSet::FaceIter::FaceIter(const MeshSet *_obj, size_t _mesh, size_t _face) : obj(_obj), mesh(_mesh), face(_face) { + } + + + + template + template + void MeshSet::FaceIter::fwd(size_t n) { + if (mesh < obj->meshes.size()) { + face += n; + while (face >= obj->meshes[mesh]->faces.size()) { + face -= obj->meshes[mesh++]->faces.size(); + if (mesh == obj->meshes.size()) { face = 0; break; } + } + } + } + + + + template + template + void MeshSet::FaceIter::rev(size_t n) { + while (n > face) { + n -= face; + if (mesh == 0) { face = 0; return; } + face = obj->meshes[--mesh]->faces.size() - 1; + } + face -= n; + } + + + + template + template + void MeshSet::FaceIter::adv(int n) { + if (n > 0) { + fwd((size_t)n); + } else if (n < 0) { + rev((size_t)-n); + } + } + + + + template + template + typename MeshSet::template FaceIter::difference_type + MeshSet::FaceIter::operator-(const FaceIter &other) const { + CARVE_ASSERT(obj == other.obj); + if (mesh == other.mesh) return face - other.face; + + size_t m = 0; + for (size_t i = std::min(mesh, other.mesh) + 1; i < std::max(mesh, other.mesh); ++i) { + m += obj->meshes[i]->faces.size(); + } + + if (mesh < other.mesh) { + return -(difference_type)((obj->meshes[mesh]->faces.size() - face) + m + other.face); + } else { + return +(difference_type)((obj->meshes[other.mesh]->faces.size() - other.face) + m + face); + } + } + + + + template + struct VPtrSort { + order_t order; + + VPtrSort(const order_t &_order = order_t()) : order(_order) {} + + template + bool operator()(carve::mesh::Vertex *a, + carve::mesh::Vertex *b) const { + return order(a->v, b->v); + } + }; + + + + template + void MeshSet::collectVertices() { + std::unordered_map vert_idx; + + for (size_t m = 0; m < meshes.size(); ++m) { + mesh_t *mesh = meshes[m]; + + for (size_t f = 0; f < mesh->faces.size(); ++f) { + face_t *face = mesh->faces[f]; + edge_t *edge = face->edge; + do { + vert_idx[edge->vert] = 0; + edge = edge->next; + } while (edge != face->edge); + } + } + + std::vector new_vertex_storage; + new_vertex_storage.reserve(vert_idx.size()); + for (typename std::unordered_map::iterator + i = vert_idx.begin(); i != vert_idx.end(); ++i) { + (*i).second = new_vertex_storage.size(); + new_vertex_storage.push_back(*(*i).first); + } + + for (size_t m = 0; m < meshes.size(); ++m) { + mesh_t *mesh = meshes[m]; + for (size_t f = 0; f < mesh->faces.size(); ++f) { + face_t *face = mesh->faces[f]; + edge_t *edge = face->edge; + do { + size_t i = vert_idx[edge->vert]; + edge->vert = &new_vertex_storage[i]; + edge = edge->next; + } while (edge != face->edge); + } + } + + std::swap(vertex_storage, new_vertex_storage); + } + + + + template + void MeshSet::canonicalize() { + std::vector vptr; + std::vector vmap; + std::vector vout; + const size_t N = vertex_storage.size(); + + vptr.reserve(N); + vout.reserve(N); + vmap.resize(N); + + for (size_t i = 0; i != N; ++i) { + vptr.push_back(&vertex_storage[i]); + } + std::sort(vptr.begin(), vptr.end(), VPtrSort >()); + + for (size_t i = 0; i != N; ++i) { + vout.push_back(*vptr[i]); + vmap[vptr[i] - &vertex_storage[0]] = &vout[i]; + } + + for (face_iter i = faceBegin(); i != faceEnd(); ++i) { + for (typename face_t::edge_iter_t j = (*i)->begin(); j != (*i)->end(); ++j) { + (*j).vert = vmap[(*j).vert - &vertex_storage[0]]; + } + (*i)->canonicalize(); + } + + vertex_storage.swap(vout); + } + + } +} diff -Nru blender-2.61/extern/carve/include/carve/mesh_ops.hpp blender-2.62/extern/carve/include/carve/mesh_ops.hpp --- blender-2.61/extern/carve/include/carve/mesh_ops.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/mesh_ops.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,975 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +#include + +#include +#include + +namespace carve { + namespace mesh { + namespace detail { + // make a triangle out of three edges. + template + void link(Edge *e1, Edge *e2, Edge *e3, Face *f = NULL) { + e1->next = e2; e2->next = e3; e3->next = e1; + e3->prev = e2; e2->prev = e1; e1->prev = e3; + e1->face = e2->face = e3->face = f; + if (f) { + f->edge = e1; + f->recalc(); + } + } + + + + template + double loopArea(carve::mesh::Edge *edge, proj_t proj) { + double A = 0.0; + carve::mesh::Edge<3> *e = edge; + do { + carve::geom2d::P2 p1 = proj(e->vert->v); + carve::geom2d::P2 p2 = proj(e->next->vert->v); + A += (p2.y + p1.y) * (p2.x - p1.x); + e = e->next; + } while (e != edge); + return A / 2.0; + } + + + + template + struct TriangulationData { + typedef Edge edge_t; + + struct VertexInfo { + double score; + carve::geom2d::P2 p; + bool convex; + bool failed; + VertexInfo *next, *prev; + edge_t *edge; + + VertexInfo(edge_t *_edge, + const carve::geom2d::P2 &_p) : + score(0.0), p(_p), convex(false), failed(false), next(NULL), prev(NULL), edge(_edge) { + } + + bool isCandidate() const { + return convex && !failed; + } + + void fail() { + failed = true; + } + + static bool isLeft(const VertexInfo *a, const VertexInfo *b, const geom2d::P2 &p) { + if (a < b) { + return carve::geom2d::orient2d(a->p, b->p, p) > 0.0; + } else { + return carve::geom2d::orient2d(b->p, a->p, p) < 0.0; + } + } + + // is the ear prev->edge->next convex? + bool testForConvexVertex() const { + return isLeft(next, prev, p); + } + + static double triScore(const geom2d::P2 &a, const geom2d::P2 &b, const geom2d::P2 &c) { + // score is in the range: [0, 1] + // equilateral triangles score 1 + // sliver triangles score 0 + double dab = (a - b).length(); + double dbc = (b - c).length(); + double dca = (c - a).length(); + + if (dab < 1e-10 || dbc < 1e-10 || dca < 1e-10) return 0.0; + + return std::max(std::min((dab + dbc) / dca, std::min((dab + dca) / dbc, (dbc + dca) / dab)) - 1.0, 0.0); + } + + // calculate a score for the ear edge. + double calcScore() const { + double this_tri = triScore(prev->p, p, next->p); + double next_tri = triScore(prev->p, next->p, next->next->p); + double prev_tri = triScore(prev->prev->p, prev->p, next->p); + + return this_tri + std::max(next_tri, prev_tri) * .2; + } + + void recompute() { + convex = testForConvexVertex(); + failed = false; + if (convex) { + score = calcScore(); + } else { + score = -1e-5; + } + } + + static bool inTriangle(const VertexInfo *a, + const VertexInfo *b, + const VertexInfo *c, + const geom2d::P2 &e) { + return !isLeft(b, a, e) && !isLeft(c, b, e) && !isLeft(a, c, e); + } + + + bool isClipable() const { + for (const VertexInfo *v_test = next->next; v_test != prev; v_test = v_test->next) { + if (v_test->convex) { + continue; + } + + if (v_test->p == prev->p || v_test->p == next->p) { + continue; + } + + if (v_test->p == p) { + if (v_test->next->p == prev->p && v_test->prev->p == next->p) { + return false; + } + + if (v_test->next->p == prev->p || v_test->prev->p == next->p) { + continue; + } + } + + if (inTriangle(prev, this, next, v_test->p)) { + return false; + } + } + return true; + } + }; + + struct order_by_score { + bool operator()(const VertexInfo *a, const VertexInfo *b) const { + return a->score < b->score; + } + }; + + typedef std::pair diag_t; + + proj_t proj; + + geom2d::P2 P(const VertexInfo *vi) const { + return vi->p; + } + + geom2d::P2 P(const edge_t *edge) const { + return proj(edge->vert->v); + } + + bool isLeft(const edge_t *a, const edge_t *b, const geom2d::P2 &p) const { + if (a < b) { + return carve::geom2d::orient2d(P(a), P(b), p) > 0.0; + } else { + return carve::geom2d::orient2d(P(b), P(a), p) < 0.0; + } + } + + bool testForConvexVertex(const edge_t *vert) const { + return isLeft(vert->next, vert->prev, P(vert)); + } + + bool inCone(const VertexInfo *vert, const geom2d::P2 &p) const { + return geom2d::internalToAngle(P(vert->next), P(vert), P(vert->prev), p); + } + + int windingNumber(VertexInfo *vert, const carve::geom2d::P2 &point) const { + int wn = 0; + + VertexInfo *v = vert; + geom2d::P2 v_p = P(vert); + do { + geom2d::P2 n_p = P(v->next); + + if (v_p.y <= point.y) { + if (n_p.y > point.y && carve::geom2d::orient2d(v_p, n_p, point) > 0.0) { + ++wn; + } + } else { + if (n_p.y <= point.y && carve::geom2d::orient2d(v_p, n_p, point) < 0.0) { + --wn; + } + } + v = v->next; + v_p = n_p; + } while (v != vert); + + return wn; + } + + bool diagonalIsCandidate(diag_t diag) const { + VertexInfo *v1 = diag.first; + VertexInfo *v2 = diag.second; + return (inCone(v1, P(v2)) && inCone(v2, P(v1))); + } + + bool testDiagonal(diag_t diag) const { + // test whether v1-v2 is a valid diagonal. + VertexInfo *v1 = diag.first; + VertexInfo *v2 = diag.second; + geom2d::P2 v1p = P(v1); + geom2d::P2 v2p = P(v2); + + bool intersected = false; + + for (VertexInfo *t = v1->next; !intersected && t != v1->prev; t = t->next) { + VertexInfo *u = t->next; + if (t == v2 || u == v2) continue; + + geom2d::P2 tp = P(t); + geom2d::P2 up = P(u); + + double l_a1 = carve::geom2d::orient2d(v1p, v2p, tp); + double l_a2 = carve::geom2d::orient2d(v1p, v2p, up); + + double l_b1 = carve::geom2d::orient2d(tp, up, v1p); + double l_b2 = carve::geom2d::orient2d(tp, up, v2p); + + if (l_a1 > l_a2) std::swap(l_a1, l_a2); + if (l_b1 > l_b2) std::swap(l_b1, l_b2); + + if (l_a1 == 0.0 && l_a2 == 0.0 && + l_b1 == 0.0 && l_b2 == 0.0) { + // colinear + if (std::max(tp.x, up.x) >= std::min(v1p.x, v2p.x) && std::min(tp.x, up.x) <= std::max(v1p.x, v2p.x)) { + // colinear and intersecting + intersected = true; + } + continue; + } + + if (l_a2 <= 0.0 || l_a1 >= 0.0 || l_b2 <= 0.0 || l_b1 >= 0.0) { + // no intersection + continue; + } + + intersected = true; + } + + if (!intersected) { + // test whether midpoint winding == 1 + + carve::geom2d::P2 mid = (v1p + v2p) / 2; + if (windingNumber(v1, mid) == 1) { + // this diagonal is ok + return true; + } + } + return false; + } + + // Find the vertex half way around the loop (rounds upwards). + VertexInfo *findMidpoint(VertexInfo *vert) const { + VertexInfo *v = vert; + VertexInfo *r = vert; + while (1) { + r = r->next; + v = v->next; if (v == vert) return r; + v = v->next; if (v == vert) return r; + } + } + + // Test all diagonals with a separation of a-b by walking both + // pointers around the loop. In the case where a-b divides the + // loop exactly in half, this will test each diagonal twice, + // but avoiding this case is not worth the extra effort + // required. + diag_t scanDiagonals(VertexInfo *a, VertexInfo *b) const { + VertexInfo *v1 = a; + VertexInfo *v2 = b; + + do { + diag_t d(v1, v2); + if (diagonalIsCandidate(d) && testDiagonal(d)) { + return d; + } + v1 = v1->next; + v2 = v2->next; + } while (v1 != a); + + return diag_t(NULL, NULL); + } + + diag_t scanAllDiagonals(VertexInfo *a) const { + // Rationale: We want to find a diagonal that splits the + // loop into two as evenly as possible, to reduce the number + // of times that diagonal splitting is required. Start by + // scanning all diagonals separated by loop_len / 2, then + // decrease the separation until we find something. + + // loops of length 2 or 3 have no possible diagonal. + if (a->next == a || a->next->next == a) return diag_t(NULL, NULL); + + VertexInfo *b = findMidpoint(a); + while (b != a->next) { + diag_t d = scanDiagonals(a, b); + if (d != diag_t(NULL, NULL)) return d; + b = b->prev; + } + + return diag_t(NULL, NULL); + } + + diag_t findDiagonal(VertexInfo *vert) const { + return scanAllDiagonals(vert); + } + + diag_t findHighScoringDiagonal(VertexInfo *vert) const { + typedef std::pair heap_entry_t; + VertexInfo *v1, *v2; + std::vector heap; + size_t loop_len = 0; + + v1 = vert; + do { + ++loop_len; + v1 = v1->next; + } while (v1 != vert); + + v1 = vert; + do { + v2 = v1->next->next; + size_t dist = 2; + do { + if (diagonalIsCandidate(diag_t(v1, v2))) { + double score = std::min(dist, loop_len - dist); + // double score = (v1->edge->vert->v - v2->edge->vert->v).length2(); + heap.push_back(heap_entry_t(score, diag_t(v1, v2))); + } + v2 = v2->next; + ++dist; + } while (v2 != vert && v2 != v1->prev); + v1 = v1->next; + } while (v1->next->next != vert); + + std::make_heap(heap.begin(), heap.end()); + + while (heap.size()) { + std::pop_heap(heap.begin(), heap.end()); + heap_entry_t h = heap.back(); + heap.pop_back(); + + if (testDiagonal(h.second)) return h.second; + } + + // couldn't find a diagonal that was ok. + return diag_t(NULL, NULL); + } + + void splitEdgeLoop(VertexInfo *v1, VertexInfo *v2) { + VertexInfo *v1_copy = new VertexInfo(new Edge(v1->edge->vert, NULL), v1->p); + VertexInfo *v2_copy = new VertexInfo(new Edge(v2->edge->vert, NULL), v2->p); + + v1_copy->edge->rev = v2_copy->edge; + v2_copy->edge->rev = v1_copy->edge; + + v1_copy->edge->prev = v1->edge->prev; + v1_copy->edge->next = v2->edge; + + v2_copy->edge->prev = v2->edge->prev; + v2_copy->edge->next = v1->edge; + + v1->edge->prev->next = v1_copy->edge; + v1->edge->prev = v2_copy->edge; + + v2->edge->prev->next = v2_copy->edge; + v2->edge->prev = v1_copy->edge; + + v1_copy->prev = v1->prev; + v1_copy->next = v2; + + v2_copy->prev = v2->prev; + v2_copy->next = v1; + + v1->prev->next = v1_copy; + v1->prev = v2_copy; + + v2->prev->next = v2_copy; + v2->prev = v1_copy; + } + + VertexInfo *findDegenerateEar(VertexInfo *edge) { + VertexInfo *v = edge; + + if (v->next == v || v->next->next == v) return NULL; + + do { + if (P(v) == P(v->next)) { + return v; + } else if (P(v) == P(v->next->next)) { + if (P(v->next) == P(v->next->next->next)) { + // a 'z' in the loop: z (a) b a b c -> remove a-b-a -> z (a) a b c -> remove a-a-b (next loop) -> z a b c + // z --(a)-- b + // / + // / + // a -- b -- d + return v->next; + } else { + // a 'shard' in the loop: z (a) b a c d -> remove a-b-a -> z (a) a b c d -> remove a-a-b (next loop) -> z a b c d + // z --(a)-- b + // / + // / + // a -- c -- d + // n.b. can only do this if the shard is pointing out of the polygon. i.e. b is outside z-a-c + if (!carve::geom2d::internalToAngle(P(v->next->next->next), P(v), P(v->prev), P(v->next))) { + return v->next; + } + } + } + v = v->next; + } while (v != edge); + + return NULL; + } + + // Clip off a vertex at vert, producing a triangle (with appropriate rev pointers) + template + VertexInfo *clipEar(VertexInfo *vert, out_iter_t out) { + CARVE_ASSERT(testForConvexVertex(vert->edge)); + + edge_t *p_edge = vert->edge->prev; + edge_t *n_edge = vert->edge->next; + + edge_t *p_copy = new edge_t(p_edge->vert, NULL); + edge_t *n_copy = new edge_t(n_edge->vert, NULL); + + n_copy->next = p_copy; + n_copy->prev = vert->edge; + + p_copy->next = vert->edge; + p_copy->prev = n_copy; + + vert->edge->next = n_copy; + vert->edge->prev = p_copy; + + p_edge->next = n_edge; + n_edge->prev = p_edge; + + if (p_edge->rev) { + p_edge->rev->rev = p_copy; + } + p_copy->rev = p_edge->rev; + + p_edge->rev = n_copy; + n_copy->rev = p_edge; + + *out++ = vert->edge; + + if (vert->edge->face) { + if (vert->edge->face->edge == vert->edge) { + vert->edge->face->edge = n_edge; + } + vert->edge->face->n_edges--; + vert->edge->face = NULL; + } + + vert->next->prev = vert->prev; + vert->prev->next = vert->next; + + VertexInfo *n = vert->next; + delete vert; + return n; + } + + template + size_t removeDegeneracies(VertexInfo *&begin, out_iter_t out) { + VertexInfo *v; + size_t count = 0; + + while ((v = findDegenerateEar(begin)) != NULL) { + begin = clipEar(v, out); + ++count; + } + return count; + } + + template + bool splitAndResume(VertexInfo *begin, out_iter_t out) { + diag_t diag; + + diag = findDiagonal(begin); + if (diag == diag_t(NULL, NULL)) { + std::cerr << "failed to find diagonal" << std::endl; + return false; + } + + // add a splitting edge between v1 and v2. + VertexInfo *v1 = diag.first; + VertexInfo *v2 = diag.second; + + splitEdgeLoop(v1, v2); + + v1->recompute(); + v1->next->recompute(); + + v2->recompute(); + v2->next->recompute(); + +#if defined(CARVE_DEBUG) + dumpPoly(v1->edge, v2->edge); +#endif + +#if defined(CARVE_DEBUG) + CARVE_ASSERT(!checkSelfIntersection(v1)); + CARVE_ASSERT(!checkSelfIntersection(v2)); +#endif + + bool r1 = doTriangulate(v1, out); + bool r2 = doTriangulate(v2, out); + + return r1 && r2; + } + + template + bool doTriangulate(VertexInfo *begin, out_iter_t out); + + TriangulationData(proj_t _proj) : proj(_proj) { + } + + VertexInfo *init(edge_t *begin) { + edge_t *e = begin; + VertexInfo *head = NULL, *tail = NULL, *v; + do { + VertexInfo *v = new VertexInfo(e, proj(e->vert->v)); + if (tail != NULL) { + tail->next = v; + v->prev = tail; + } else { + head = v; + } + tail = v; + + e = e->next; + } while (e != begin); + tail->next = head; + head->prev = tail; + + v = head; + do { + v->recompute(); + v = v->next; + } while (v != head); + return head; + } + + class EarQueue { + TriangulationData &data; + std::vector queue; + + void checkheap() { +#ifdef __GNUC__ + CARVE_ASSERT(std::__is_heap(queue.begin(), queue.end(), order_by_score())); +#endif + } + + public: + EarQueue(TriangulationData &_data) : data(_data), queue() { + } + + size_t size() const { + return queue.size(); + } + + void push(VertexInfo *v) { +#if defined(CARVE_DEBUG) + checkheap(); +#endif + queue.push_back(v); + std::push_heap(queue.begin(), queue.end(), order_by_score()); + } + + VertexInfo *pop() { +#if defined(CARVE_DEBUG) + checkheap(); +#endif + std::pop_heap(queue.begin(), queue.end(), order_by_score()); + VertexInfo *v = queue.back(); + queue.pop_back(); + return v; + } + + void remove(VertexInfo *v) { +#if defined(CARVE_DEBUG) + checkheap(); +#endif + CARVE_ASSERT(std::find(queue.begin(), queue.end(), v) != queue.end()); + double score = v->score; + if (v != queue[0]) { + v->score = queue[0]->score + 1; + std::make_heap(queue.begin(), queue.end(), order_by_score()); + } + CARVE_ASSERT(v == queue[0]); + std::pop_heap(queue.begin(), queue.end(), order_by_score()); + CARVE_ASSERT(queue.back() == v); + queue.pop_back(); + v->score = score; + } + + void changeScore(VertexInfo *v, double s_from, double s_to) { +#if defined(CARVE_DEBUG) + checkheap(); +#endif + CARVE_ASSERT(std::find(queue.begin(), queue.end(), v) != queue.end()); + if (s_from != s_to) { + v->score = s_to; + std::make_heap(queue.begin(), queue.end(), order_by_score()); + } + } + + void update(VertexInfo *v) { + VertexInfo pre = *v; + v->recompute(); + VertexInfo post = *v; + + if (pre.isCandidate()) { + if (post.isCandidate()) { + changeScore(v, pre.score, post.score); + } else { + remove(v); + } + } else { + if (post.isCandidate()) { + push(v); + } + } + } + }; + + + bool checkSelfIntersection(const VertexInfo *vert) { + const VertexInfo *v1 = vert; + do { + const VertexInfo *v2 = vert->next->next; + do { + carve::geom2d::P2 a = v1->p; + carve::geom2d::P2 b = v1->next->p; + CARVE_ASSERT(a == proj(v1->edge->vert->v)); + CARVE_ASSERT(b == proj(v1->edge->next->vert->v)); + + carve::geom2d::P2 c = v2->p; + carve::geom2d::P2 d = v2->next->p; + CARVE_ASSERT(c == proj(v2->edge->vert->v)); + CARVE_ASSERT(d == proj(v2->edge->next->vert->v)); + + bool intersected = false; + if (a == c || a == d || b == c || b == d) { + } else { + intersected = true; + + double l_a1 = carve::geom2d::orient2d(a, b, c); + double l_a2 = carve::geom2d::orient2d(a, b, d); + if (l_a1 > l_a2) std::swap(l_a1, l_a2); + if (l_a2 <= 0.0 || l_a1 >= 0.0) { + intersected = false; + } + + double l_b1 = carve::geom2d::orient2d(c, d, a); + double l_b2 = carve::geom2d::orient2d(c, d, b); + if (l_b1 > l_b2) std::swap(l_b1, l_b2); + if (l_b2 <= 0.0 || l_b1 >= 0.0) { + intersected = false; + } + + if (l_a1 == 0.0 && l_a2 == 0.0 && l_b1 == 0.0 && l_b2 == 0.0) { + if (std::max(a.x, b.x) >= std::min(c.x, d.x) && std::min(a.x, b.x) <= std::max(c.x, d.x)) { + // colinear and intersecting. + } else { + // colinear but not intersecting. + intersected = false; + } + } + } + if (intersected) { + carve::geom2d::P2 p[4] = { a, b, c, d }; + carve::geom::aabb<2> A(p, p+4); + A.expand(5); + + std::cerr << "\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n"; + return true; + } + v2 = v2->next; + } while (v2 != vert); + v1 = v1->next; + } while (v1 != vert); + return false; + } + + carve::geom::aabb<2> make2d(const edge_t *edge, std::vector &points) { + const edge_t *e = edge; + do { + points.push_back(P(e)); + e = e->next; + } while(e != edge); + return carve::geom::aabb<2>(points.begin(), points.end()); + } + + void dumpLoop(std::ostream &out, + const std::vector &points, + const char *fill, + const char *stroke, + double stroke_width, + double offx, + double offy, + double scale + ) { + out << "" << std::endl; + } + + void dumpPoly(const edge_t *edge, const edge_t *edge2 = NULL, const char *pfx = "poly_") { + static int step = 0; + std::ostringstream filename; + filename << pfx << step++ << ".svg"; + std::cerr << "dumping to " << filename.str() << std::endl; + std::ofstream out(filename.str().c_str()); + + std::vector points, points2; + + carve::geom::aabb<2> A = make2d(edge, points); + if (edge2) { + A.unionAABB(make2d(edge2, points2)); + } + A.expand(5); + + out << "\ +\n\ +\n\ +\n"; + + dumpLoop(out, points, "rgb(0,0,0)", "blue", 0.1, 0, 0, 1); + if (points2.size()) dumpLoop(out, points2, "rgb(255,0,0)", "blue", 0.1, 0, 0, 1); + + out << "" << std::endl; + } + }; + + template + template + bool TriangulationData::doTriangulate(VertexInfo *begin, out_iter_t out) { + EarQueue vq(*this); + +#if defined(CARVE_DEBUG) + dumpPoly(begin->edge, NULL, "input_"); + CARVE_ASSERT(!checkSelfIntersection(begin)); +#endif + + VertexInfo *v = begin, *n, *p; + size_t remain = 0; + do { + if (v->isCandidate()) vq.push(v); + v = v->next; + remain++; + } while (v != begin); + + while (remain > 3 && vq.size()) { + { static int __c = 0; if (++__c % 50 == 0) { break; } } + v = vq.pop(); + if (!v->isClipable()) { + v->fail(); + continue; + } + + continue_clipping: + n = clipEar(v, out); + p = n->prev; + begin = n; + if (--remain == 3) break; + // if (checkSelfIntersection(begin)) { + // dumpPoly(begin->edge, NULL, "badclip_"); + // CARVE_ASSERT(!!!"clip created self intersection"); + // } + + vq.update(n); + vq.update(p); + + if (n->score < p->score) { std::swap(n, p); } + if (n->score > 0.25 && n->isCandidate() && n->isClipable()) { + vq.remove(n); + v = n; + goto continue_clipping; + } + if (p->score > 0.25 && p->isCandidate() && p->isClipable()) { + vq.remove(p); + v = p; + goto continue_clipping; + } + } + + bool ret = false; + +#if defined(CARVE_DEBUG) + dumpPoly(begin->edge, NULL, "remainder_"); +#endif + + if (remain > 3) { + std::vector temp; + temp.reserve(remain); + VertexInfo *v = begin; + do { + temp.push_back(P(v)); + v = v->next; + } while (v != begin); + + if (carve::geom2d::signedArea(temp) == 0) { + // XXX: this test will fail in cases where the boundary is + // twisted so that a negative area balances a positive area. + std::cerr << "got to here" << std::endl; + dumpPoly(begin->edge, NULL, "interesting_case_"); + goto done; + } + } + + if (remain > 3) { + remain -= removeDegeneracies(begin, out); + } + + if (remain > 3) { + return splitAndResume(begin, out); + } + + { double a = loopArea(begin->edge, proj); CARVE_ASSERT(a <= 0.0); } + *out++ = begin->edge; + + v = begin; + do { + n = v->next; + delete v; + v = n; + } while (v != begin); + + ret = true; + + done: + return ret; + } + } + + + + template + void triangulate(Edge *edge, proj_t proj, out_iter_t out) { + detail::TriangulationData triangulator(proj); + typename detail::TriangulationData::VertexInfo *v = triangulator.init(edge); + triangulator.removeDegeneracies(v, out); + triangulator.doTriangulate(v, out); + } + + // given edge a-b, part of triangles a-b-c and b-a-d, make triangles c-a-d and b-c-d + template + void flipTriEdge(Edge *edge) { + CARVE_ASSERT(edge->rev != NULL); + CARVE_ASSERT(edge->face->nEdges() == 3); + CARVE_ASSERT(edge->rev->face->nEdges() == 3); + + CARVE_ASSERT(edge->prev != edge); + CARVE_ASSERT(edge->next != edge); + CARVE_ASSERT(edge->rev->prev != edge->rev); + CARVE_ASSERT(edge->rev->next != edge->rev); + + typedef Edge edge_t; + typedef Face face_t; + + edge_t *t1[3], *t2[3]; + face_t *f1, *f2; + + t1[1] = edge; t2[1] = edge->rev; + t1[0] = t1[1]->prev; t1[2] = t1[1]->next; + t2[0] = t2[1]->prev; t2[2] = t2[1]->next; + + f1 = t1[1]->face; f2 = t2[1]->face; + + // std::cerr << t1[0]->vert << "->" << t1[1]->vert << "->" << t1[2]->vert << std::endl; + // std::cerr << t2[0]->vert << "->" << t2[1]->vert << "->" << t2[2]->vert << std::endl; + + t1[1]->vert = t2[0]->vert; + t2[1]->vert = t1[0]->vert; + + // std::cerr << t1[0]->vert << "->" << t2[2]->vert << "->" << t1[1]->vert << std::endl; + // std::cerr << t2[0]->vert << "->" << t1[2]->vert << "->" << t2[1]->vert << std::endl; + + detail::link(t1[0], t2[2], t1[1], f1); + detail::link(t2[0], t1[2], t2[1], f2); + + if (t1[0]->rev) CARVE_ASSERT(t1[0]->v2() == t1[0]->rev->v1()); + if (t2[0]->rev) CARVE_ASSERT(t2[0]->v2() == t2[0]->rev->v1()); + if (t1[2]->rev) CARVE_ASSERT(t1[2]->v2() == t1[2]->rev->v1()); + if (t2[2]->rev) CARVE_ASSERT(t2[2]->v2() == t2[2]->rev->v1()); + } + + template + void splitEdgeLoop(Edge *v1, Edge *v2) { + // v1 and v2 end up on different sides of the split. + Edge *v1_copy = new Edge(v1->vert, NULL); + Edge *v2_copy = new Edge(v2->vert, NULL); + + v1_copy->rev = v2_copy; + v2_copy->rev = v1_copy; + + v1_copy->prev = v1->prev; + v1_copy->next = v2; + + v2_copy->prev = v2->prev; + v2_copy->next = v1; + + v1->prev->next = v1_copy; + v1->prev = v2_copy; + + v2->prev->next = v2_copy; + v2->prev = v1_copy; + } + + template + Edge *clipVertex(Edge *edge) { + Edge *prev = edge->prev; + Edge *next = edge->next; + splitEdgeLoop(edge->prev, edge->next); + return next; + } + } +} diff -Nru blender-2.61/extern/carve/include/carve/mesh_simplify.hpp blender-2.62/extern/carve/include/carve/mesh_simplify.hpp --- blender-2.61/extern/carve/include/carve/mesh_simplify.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/mesh_simplify.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,1574 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "write_ply.hpp" + + +namespace carve { + namespace mesh { + + + class MeshSimplifier { + typedef carve::mesh::MeshSet<3> meshset_t; + typedef carve::mesh::Mesh<3> mesh_t; + typedef mesh_t::vertex_t vertex_t; + typedef vertex_t::vector_t vector_t; + typedef mesh_t::edge_t edge_t; + typedef mesh_t::face_t face_t; + typedef face_t::aabb_t aabb_t; + + typedef carve::geom::RTreeNode<3, carve::mesh::Face<3> *> face_rtree_t; + + + struct EdgeInfo { + edge_t *edge; + double delta_v; + + double c[4]; + double l[2], t1[2], t2[2]; + size_t heap_idx; + + void update() { + const vertex_t *v1 = edge->vert; + const vertex_t *v2 = edge->next->vert; + const vertex_t *v3 = edge->next->next->vert; + const vertex_t *v4 = edge->rev ? edge->rev->next->next->vert : NULL; + + l[0] = (v1->v - v2->v).length(); + + t1[0] = (v3->v - v1->v).length(); + t1[1] = (v3->v - v2->v).length(); + + c[0] = std::max((t1[0] + t1[1]) / l[0] - 1.0, 0.0); + + if (v4) { + l[1] = (v3->v - v4->v).length(); + t2[0] = (v4->v - v1->v).length(); + t2[1] = (v4->v - v2->v).length(); + c[1] = std::max((t2[0] + t2[1]) / l[0] - 1.0, 0.0); + c[2] = std::max((t1[0] + t2[0]) / l[1] - 1.0, 0.0); + c[3] = std::max((t1[1] + t2[1]) / l[1] - 1.0, 0.0); + delta_v = carve::geom3d::tetrahedronVolume(v1->v, v2->v, v3->v, v4->v); + } else { + l[1] = 0.0; + t2[0] = t2[1] = 0.0; + c[1] = c[2] = c[3] = 0.0; + delta_v = 0.0; + } + } + + EdgeInfo(edge_t *e) : edge(e) { + update(); + } + + EdgeInfo() : edge(NULL) { + delta_v = 0.0; + c[0] = c[1] = c[2] = c[3] = 0.0; + l[0] = l[1] = 0.0; + t1[0] = t1[1] = 0.0; + t2[0] = t2[1] = 0.0; + } + + struct NotifyPos { + void operator()(EdgeInfo *edge, size_t pos) const { edge->heap_idx = pos; } + void operator()(EdgeInfo &edge, size_t pos) const { edge.heap_idx = pos; } + }; + }; + + + + struct FlippableBase { + double min_dp; + + FlippableBase(double _min_dp = 0.0) : min_dp(_min_dp) { + } + + bool open(const EdgeInfo *e) const { + return e->edge->rev == NULL; + } + + bool wouldCreateDegenerateEdge(const EdgeInfo *e) const { + return e->edge->prev->vert == e->edge->rev->prev->vert; + } + + bool flippable_DotProd(const EdgeInfo *e) const { + using carve::geom::dot; + using carve::geom::cross; + + if (open(e)) return false; + + edge_t *edge = e->edge; + + const vertex_t *v1 = edge->vert; + const vertex_t *v2 = edge->next->vert; + const vertex_t *v3 = edge->next->next->vert; + const vertex_t *v4 = edge->rev->next->next->vert; + + if (dot(cross(v3->v - v2->v, v1->v - v2->v).normalized(), + cross(v4->v - v1->v, v2->v - v1->v).normalized()) < min_dp) return false; + + if (dot(cross(v3->v - v4->v, v1->v - v4->v).normalized(), + cross(v4->v - v3->v, v2->v - v3->v).normalized()) < min_dp) return false; + + return true; + } + + virtual bool canFlip(const EdgeInfo *e) const { + return !open(e) && !wouldCreateDegenerateEdge(e) && score(e) > 0.0; + } + + virtual double score(const EdgeInfo *e) const { + return std::min(e->c[2], e->c[3]) - std::min(e->c[0], e->c[1]); + } + + class Priority { + Priority &operator=(const Priority &); + const FlippableBase &flip; + + public: + Priority(const FlippableBase &_flip) : flip(_flip) {} + bool operator()(const EdgeInfo *a, const EdgeInfo *b) const { return flip.score(a) > flip.score(b); } + }; + + Priority priority() const { + return Priority(*this); + } + }; + + + + struct FlippableConservative : public FlippableBase { + FlippableConservative() : FlippableBase(0.0) { + } + + bool connectsAlmostCoplanarFaces(const EdgeInfo *e) const { + // XXX: remove hard coded constants. + if (e->c[0] < 1e-10 || e->c[1] < 1e-10) return true; + return fabs(carve::geom::dot(e->edge->face->plane.N, e->edge->rev->face->plane.N) - 1.0) < 1e-10; + } + + bool connectsExactlyCoplanarFaces(const EdgeInfo *e) const { + edge_t *edge = e->edge; + return + carve::geom3d::orient3d(edge->vert->v, + edge->next->vert->v, + edge->next->next->vert->v, + edge->rev->next->next->vert->v) == 0.0 && + carve::geom3d::orient3d(edge->rev->vert->v, + edge->rev->next->vert->v, + edge->rev->next->next->vert->v, + edge->next->next->vert->v) == 0.0; + } + + virtual bool canFlip(const EdgeInfo *e) const { + return FlippableBase::canFlip(e) && connectsExactlyCoplanarFaces(e) && flippable_DotProd(e); + } + }; + + + + struct FlippableColinearPair : public FlippableBase { + + FlippableColinearPair() { + } + + + virtual double score(const EdgeInfo *e) const { + return e->l[0] - e->l[1]; + } + + virtual bool canFlip(const EdgeInfo *e) const { + if (!FlippableBase::canFlip(e)) return false; + + if (e->c[0] > 1e-3 || e->c[1] > 1e-3) return false; + + return true; + } + }; + + + + struct Flippable : public FlippableBase { + double min_colinearity; + double min_delta_v; + + Flippable(double _min_colinearity, + double _min_delta_v, + double _min_normal_angle) : + FlippableBase(cos(_min_normal_angle)), + min_colinearity(_min_colinearity), + min_delta_v(_min_delta_v) { + } + + + virtual bool canFlip(const EdgeInfo *e) const { + if (!FlippableBase::canFlip(e)) return false; + + if (fabs(e->delta_v) > min_delta_v) return false; + + // if (std::min(e->c[0], e->c[1]) > min_colinearity) return false; + + return flippable_DotProd(e); + } + }; + + + + struct EdgeMerger { + double min_edgelen; + + virtual bool canMerge(const EdgeInfo *e) const { + return e->l[0] <= min_edgelen; + } + + EdgeMerger(double _min_edgelen) : min_edgelen(_min_edgelen) { + } + + double score(const EdgeInfo *e) const { + return min_edgelen - e->l[0]; + } + + class Priority { + Priority &operator=(const Priority &); + + public: + const EdgeMerger &merger; + Priority(const EdgeMerger &_merger) : merger(_merger) { + } + bool operator()(const EdgeInfo *a, const EdgeInfo *b) const { + // collapse edges in order from shortest to longest. + return merger.score(a) < merger.score(b); + } + }; + + Priority priority() const { + return Priority(*this); + } + }; + + + + typedef std::unordered_map edge_info_map_t; + std::unordered_map edge_info; + + + + void initEdgeInfo(mesh_t *mesh) { + for (size_t i = 0; i < mesh->faces.size(); ++i) { + edge_t *e = mesh->faces[i]->edge; + do { + edge_info[e] = new EdgeInfo(e); + e = e->next; + } while (e != mesh->faces[i]->edge); + } + } + + + + void initEdgeInfo(meshset_t *meshset) { + for (size_t m = 0; m < meshset->meshes.size(); ++m) { + mesh_t *mesh = meshset->meshes[m]; + initEdgeInfo(mesh); + } + } + + + + void clearEdgeInfo() { + for (edge_info_map_t::iterator i = edge_info.begin(); i != edge_info.end(); ++i) { + delete (*i).second; + } + } + + + + void updateEdgeFlipHeap(std::vector &edge_heap, + edge_t *edge, + const FlippableBase &flipper) { + std::unordered_map::const_iterator i = edge_info.find(edge); + CARVE_ASSERT(i != edge_info.end()); + EdgeInfo *e = (*i).second; + + bool heap_pre = e->heap_idx != ~0U; + (*i).second->update(); + bool heap_post = edge->v1() < edge->v2() && flipper.canFlip(e); + + if (!heap_pre && heap_post) { + edge_heap.push_back(e); + carve::heap::push_heap(edge_heap.begin(), + edge_heap.end(), + flipper.priority(), + EdgeInfo::NotifyPos()); + } else if (heap_pre && !heap_post) { + CARVE_ASSERT(edge_heap[e->heap_idx] == e); + carve::heap::remove_heap(edge_heap.begin(), + edge_heap.end(), + edge_heap.begin() + e->heap_idx, + flipper.priority(), + EdgeInfo::NotifyPos()); + CARVE_ASSERT(edge_heap.back() == e); + edge_heap.pop_back(); + e->heap_idx = ~0U; + } else if (heap_pre && heap_post) { + CARVE_ASSERT(edge_heap[e->heap_idx] == e); + carve::heap::adjust_heap(edge_heap.begin(), + edge_heap.end(), + edge_heap.begin() + e->heap_idx, + flipper.priority(), + EdgeInfo::NotifyPos()); + CARVE_ASSERT(edge_heap[e->heap_idx] == e); + } + } + + + std::string vk(const vertex_t *v1, + const vertex_t *v2, + const vertex_t *v3) { + const vertex_t *v[3]; + v[0] = v1; v[1] = v2; v[2] = v3; + std::sort(v, v+3); + std::ostringstream s; + s << v[0] << ";" << v[1] << ";" << v[2]; + return s.str(); + } + + std::string vk(const face_t *f) { return vk(f->edge->vert, f->edge->next->vert, f->edge->next->next->vert); } + + int mapTriangle(const face_t *face, + const vertex_t *remap1, const vertex_t *remap2, + const vector_t &tgt, + vector_t tri[3]) { + edge_t *edge = face->edge; + int n_remaps = 0; + for (size_t i = 0; i < 3; edge = edge->next, ++i) { + if (edge->vert == remap1) { tri[i] = tgt; ++n_remaps; } + else if (edge->vert == remap2) { tri[i] = tgt; ++n_remaps; } + else { tri[i] = edge->vert->v; } + } + return n_remaps; + } + + template + int countIntersectionPairs(iter1_t fabegin, iter1_t faend, + iter2_t fbbegin, iter2_t fbend, + const vertex_t *remap1, const vertex_t *remap2, + const vector_t &tgt) { + vector_t tri_a[3], tri_b[3]; + int remap_a, remap_b; + std::set > ints; + + for (iter1_t i = fabegin; i != faend; ++i) { + remap_a = mapTriangle(*i, remap1, remap2, tgt, tri_a); + if (remap_a >= 2) continue; + for (iter2_t j = fbbegin; j != fbend; ++j) { + remap_b = mapTriangle(*j, remap1, remap2, tgt, tri_b); + if (remap_b >= 2) continue; + if (carve::geom::triangle_intersection_exact(tri_a, tri_b) == carve::geom::TR_TYPE_INT) { + ints.insert(std::make_pair(std::min(*i, *j), std::max(*i, *j))); + } + } + } + + return ints.size(); + } + + int countIntersections(const vertex_t *v1, + const vertex_t *v2, + const vertex_t *v3, + const std::vector &faces) { + int n_int = 0; + vector_t tri_a[3], tri_b[3]; + tri_a[0] = v1->v; + tri_a[1] = v2->v; + tri_a[2] = v3->v; + + for (std::vector::const_iterator i = faces.begin(); i != faces.end(); ++i) { + face_t *fb = *i; + if (fb->nEdges() != 3) continue; + tri_b[0] = fb->edge->vert->v; + tri_b[1] = fb->edge->next->vert->v; + tri_b[2] = fb->edge->next->next->vert->v; + + if (carve::geom::triangle_intersection_exact(tri_a, tri_b) == carve::geom::TR_TYPE_INT) { + n_int++; + } + } + return n_int; + } + + + + int _findSelfIntersections(const face_rtree_t *a_node, + const face_rtree_t *b_node, + bool descend_a = true) { + int r = 0; + + if (!a_node->bbox.intersects(b_node->bbox)) { + return 0; + } + + if (a_node->child && (descend_a || !b_node->child)) { + for (face_rtree_t *node = a_node->child; node; node = node->sibling) { + r += _findSelfIntersections(node, b_node, false); + } + } else if (b_node->child) { + for (face_rtree_t *node = b_node->child; node; node = node->sibling) { + r += _findSelfIntersections(a_node, node, true); + } + } else { + for (size_t i = 0; i < a_node->data.size(); ++i) { + face_t *fa = a_node->data[i]; + if (fa->nVertices() != 3) continue; + + aabb_t aabb_a = fa->getAABB(); + + vector_t tri_a[3]; + tri_a[0] = fa->edge->vert->v; + tri_a[1] = fa->edge->next->vert->v; + tri_a[2] = fa->edge->next->next->vert->v; + + if (!aabb_a.intersects(b_node->bbox)) continue; + + for (size_t j = 0; j < b_node->data.size(); ++j) { + face_t *fb = b_node->data[j]; + if (fb->nVertices() != 3) continue; + + vector_t tri_b[3]; + tri_b[0] = fb->edge->vert->v; + tri_b[1] = fb->edge->next->vert->v; + tri_b[2] = fb->edge->next->next->vert->v; + + if (carve::geom::triangle_intersection_exact(tri_a, tri_b) == carve::geom::TR_TYPE_INT) { + ++r; + } + } + } + } + + return r; + } + + + + int countSelfIntersections(meshset_t *meshset) { + int n_ints = 0; + face_rtree_t *tree = face_rtree_t::construct_STR(meshset->faceBegin(), meshset->faceEnd(), 4, 4); + + for (meshset_t::face_iter f = meshset->faceBegin(); f != meshset->faceEnd(); ++f) { + face_t *fa = *f; + if (fa->nVertices() != 3) continue; + + vector_t tri_a[3]; + tri_a[0] = fa->edge->vert->v; + tri_a[1] = fa->edge->next->vert->v; + tri_a[2] = fa->edge->next->next->vert->v; + + std::vector near_faces; + tree->search(fa->getAABB(), std::back_inserter(near_faces)); + + for (size_t f2 = 0; f2 < near_faces.size(); ++f2) { + const face_t *fb = near_faces[f2]; + if (fb->nVertices() != 3) continue; + + if (fa >= fb) continue; + + vector_t tri_b[3]; + tri_b[0] = fb->edge->vert->v; + tri_b[1] = fb->edge->next->vert->v; + tri_b[2] = fb->edge->next->next->vert->v; + + if (carve::geom::triangle_intersection_exact(tri_a, tri_b) == carve::geom::TR_TYPE_INT) { + ++n_ints; + } + } + } + + delete tree; + + return n_ints; + } + + size_t flipEdges(meshset_t *mesh, + const FlippableBase &flipper) { + face_rtree_t *tree = face_rtree_t::construct_STR(mesh->faceBegin(), mesh->faceEnd(), 4, 4); + + size_t n_mods = 0; + + std::vector edge_heap; + + edge_heap.reserve(edge_info.size()); + + for (edge_info_map_t::iterator i = edge_info.begin(); + i != edge_info.end(); + ++i) { + EdgeInfo *e = (*i).second; + e->update(); + if (e->edge->v1() < e->edge->v2() && flipper.canFlip(e)) { + edge_heap.push_back(e); + } else { + e->heap_idx = ~0U; + } + } + + carve::heap::make_heap(edge_heap.begin(), + edge_heap.end(), + flipper.priority(), + EdgeInfo::NotifyPos()); + + while (edge_heap.size()) { +// std::cerr << "test" << std::endl; +// for (size_t m = 0; m < mesh->meshes.size(); ++m) { +// for (size_t f = 0; f < mesh->meshes[m]->faces.size(); ++f) { +// if (mesh->meshes[m]->faces[f]->edge) mesh->meshes[m]->faces[f]->edge->validateLoop(); +// } +// } + + carve::heap::pop_heap(edge_heap.begin(), + edge_heap.end(), + flipper.priority(), + EdgeInfo::NotifyPos()); + EdgeInfo *e = edge_heap.back(); +// std::cerr << "flip " << e << std::endl; + edge_heap.pop_back(); + e->heap_idx = ~0U; + + aabb_t aabb; + aabb = e->edge->face->getAABB(); + aabb.unionAABB(e->edge->rev->face->getAABB()); + + std::vector overlapping; + tree->search(aabb, std::back_inserter(overlapping)); + + // overlapping.erase(e->edge->face); + // overlapping.erase(e->edge->rev->face); + + const vertex_t *v1 = e->edge->vert; + const vertex_t *v2 = e->edge->next->vert; + const vertex_t *v3 = e->edge->next->next->vert; + const vertex_t *v4 = e->edge->rev->next->next->vert; + + int n_int1 = countIntersections(v1, v2, v3, overlapping); + int n_int2 = countIntersections(v2, v1, v4, overlapping); + int n_int3 = countIntersections(v3, v4, v2, overlapping); + int n_int4 = countIntersections(v4, v3, v1, overlapping); + + if ((n_int3 + n_int4) - (n_int1 + n_int2) > 0) { + std::cerr << "delta[ints] = " << (n_int3 + n_int4) - (n_int1 + n_int2) << std::endl; + // avoid creating a self intersection. + continue; + } + + n_mods++; + CARVE_ASSERT(flipper.canFlip(e)); + edge_info[e->edge]->update(); + edge_info[e->edge->rev]->update(); + + carve::mesh::flipTriEdge(e->edge); + + tree->updateExtents(aabb); + + updateEdgeFlipHeap(edge_heap, e->edge, flipper); + updateEdgeFlipHeap(edge_heap, e->edge->rev, flipper); + + CARVE_ASSERT(!flipper.canFlip(e)); + + updateEdgeFlipHeap(edge_heap, e->edge->next, flipper); + updateEdgeFlipHeap(edge_heap, e->edge->next->next, flipper); + updateEdgeFlipHeap(edge_heap, e->edge->rev->next, flipper); + updateEdgeFlipHeap(edge_heap, e->edge->rev->next->next, flipper); + updateEdgeFlipHeap(edge_heap, e->edge->next->rev, flipper); + updateEdgeFlipHeap(edge_heap, e->edge->next->next->rev, flipper); + updateEdgeFlipHeap(edge_heap, e->edge->rev->next->rev, flipper); + updateEdgeFlipHeap(edge_heap, e->edge->rev->next->next->rev, flipper); + } + + delete tree; + + return n_mods; + } + + + + void removeFromEdgeMergeHeap(std::vector &edge_heap, + EdgeInfo *edge, + const EdgeMerger &merger) { + if (edge->heap_idx != ~0U) { + CARVE_ASSERT(edge_heap[edge->heap_idx] == edge); + carve::heap::remove_heap(edge_heap.begin(), + edge_heap.end(), + edge_heap.begin() + edge->heap_idx, + merger.priority(), + EdgeInfo::NotifyPos()); + CARVE_ASSERT(edge_heap.back() == edge); + edge_heap.pop_back(); + edge->heap_idx = ~0U; + } + } + + void updateEdgeMergeHeap(std::vector &edge_heap, + EdgeInfo *edge, + const EdgeMerger &merger) { + bool heap_pre = edge->heap_idx != ~0U; + edge->update(); + bool heap_post = merger.canMerge(edge); + + if (!heap_pre && heap_post) { + edge_heap.push_back(edge); + carve::heap::push_heap(edge_heap.begin(), + edge_heap.end(), + merger.priority(), + EdgeInfo::NotifyPos()); + } else if (heap_pre && !heap_post) { + CARVE_ASSERT(edge_heap[edge->heap_idx] == edge); + carve::heap::remove_heap(edge_heap.begin(), + edge_heap.end(), + edge_heap.begin() + edge->heap_idx, + merger.priority(), + EdgeInfo::NotifyPos()); + CARVE_ASSERT(edge_heap.back() == edge); + edge_heap.pop_back(); + edge->heap_idx = ~0U; + } else if (heap_pre && heap_post) { + CARVE_ASSERT(edge_heap[edge->heap_idx] == edge); + carve::heap::adjust_heap(edge_heap.begin(), + edge_heap.end(), + edge_heap.begin() + edge->heap_idx, + merger.priority(), + EdgeInfo::NotifyPos()); + CARVE_ASSERT(edge_heap[edge->heap_idx] == edge); + } + } + + + + // collapse edges edges based upon the predicate implemented by EdgeMerger. + size_t collapseEdges(meshset_t *mesh, + const EdgeMerger &merger) { + face_rtree_t *tree = face_rtree_t::construct_STR(mesh->faceBegin(), mesh->faceEnd(), 4, 4); + + size_t n_mods = 0; + + std::vector edge_heap; + std::unordered_map > vert_to_edges; + + edge_heap.reserve(edge_info.size()); + + for (edge_info_map_t::iterator i = edge_info.begin(); + i != edge_info.end(); + ++i) { + EdgeInfo *e = (*i).second; + + vert_to_edges[e->edge->v1()].insert(e); + vert_to_edges[e->edge->v2()].insert(e); + + if (merger.canMerge(e)) { + edge_heap.push_back(e); + } else { + e->heap_idx = ~0U; + } + } + + carve::heap::make_heap(edge_heap.begin(), + edge_heap.end(), + merger.priority(), + EdgeInfo::NotifyPos()); + + while (edge_heap.size()) { +// std::cerr << "test" << std::endl; +// for (size_t m = 0; m < mesh->meshes.size(); ++m) { +// for (size_t f = 0; f < mesh->meshes[m]->faces.size(); ++f) { +// if (mesh->meshes[m]->faces[f]->edge) mesh->meshes[m]->faces[f]->edge->validateLoop(); +// } +// } + carve::heap::pop_heap(edge_heap.begin(), + edge_heap.end(), + merger.priority(), + EdgeInfo::NotifyPos()); + EdgeInfo *e = edge_heap.back(); + edge_heap.pop_back(); + e->heap_idx = ~0U; + + edge_t *edge = e->edge; + vertex_t *v1 = edge->v1(); + vertex_t *v2 = edge->v2(); + + std::set affected_faces; + for (std::set::iterator f = vert_to_edges[v1].begin(); + f != vert_to_edges[v1].end(); + ++f) { + affected_faces.insert((*f)->edge->face); + affected_faces.insert((*f)->edge->rev->face); + } + for (std::set::iterator f = vert_to_edges[v2].begin(); + f != vert_to_edges[v2].end(); + ++f) { + affected_faces.insert((*f)->edge->face); + affected_faces.insert((*f)->edge->rev->face); + } + + std::vector edges_to_merge; + std::vector v1_incident; + std::vector v2_incident; + + std::set_intersection(vert_to_edges[v1].begin(), vert_to_edges[v1].end(), + vert_to_edges[v2].begin(), vert_to_edges[v2].end(), + std::back_inserter(edges_to_merge)); + + CARVE_ASSERT(edges_to_merge.size() > 0); + + std::set_difference(vert_to_edges[v1].begin(), vert_to_edges[v1].end(), + edges_to_merge.begin(), edges_to_merge.end(), + std::back_inserter(v1_incident)); + std::set_difference(vert_to_edges[v2].begin(), vert_to_edges[v2].end(), + edges_to_merge.begin(), edges_to_merge.end(), + std::back_inserter(v2_incident)); + + vector_t aabb_min, aabb_max; + assign_op(aabb_min, v1->v, v2->v, carve::util::min_functor()); + assign_op(aabb_max, v1->v, v2->v, carve::util::max_functor()); + + for (size_t i = 0; i < v1_incident.size(); ++i) { + assign_op(aabb_min, aabb_min, v1_incident[i]->edge->v1()->v, carve::util::min_functor()); + assign_op(aabb_max, aabb_max, v1_incident[i]->edge->v1()->v, carve::util::max_functor()); + assign_op(aabb_min, aabb_min, v1_incident[i]->edge->v2()->v, carve::util::min_functor()); + assign_op(aabb_max, aabb_max, v1_incident[i]->edge->v2()->v, carve::util::max_functor()); + } + + for (size_t i = 0; i < v2_incident.size(); ++i) { + assign_op(aabb_min, aabb_min, v2_incident[i]->edge->v1()->v, carve::util::min_functor()); + assign_op(aabb_max, aabb_max, v2_incident[i]->edge->v1()->v, carve::util::max_functor()); + assign_op(aabb_min, aabb_min, v2_incident[i]->edge->v2()->v, carve::util::min_functor()); + assign_op(aabb_max, aabb_max, v2_incident[i]->edge->v2()->v, carve::util::max_functor()); + } + + aabb_t aabb; + aabb.fit(aabb_min, aabb_max); + + std::vector near_faces; + tree->search(aabb, std::back_inserter(near_faces)); + + double frac = 0.5; // compute this based upon v1_incident and v2_incident? + vector_t merge = frac * v1->v + (1 - frac) * v2->v; + + int i1 = countIntersectionPairs(affected_faces.begin(), affected_faces.end(), + near_faces.begin(), near_faces.end(), + NULL, NULL, merge); + int i2 = countIntersectionPairs(affected_faces.begin(), affected_faces.end(), + near_faces.begin(), near_faces.end(), + v1, v2, merge); + if (i2 != i1) { + std::cerr << "near faces: " << near_faces.size() << " affected faces: " << affected_faces.size() << std::endl; + std::cerr << "merge delta[ints] = " << i2 - i1 << " pre: " << i1 << " post: " << i2 << std::endl; + if (i2 > i1) continue; + } + + std::cerr << "collapse " << e << std::endl; + + v2->v = merge; + ++n_mods; + + for (size_t i = 0; i < v1_incident.size(); ++i) { + if (v1_incident[i]->edge->vert == v1) { + v1_incident[i]->edge->vert = v2; + } + } + + for (size_t i = 0; i < v1_incident.size(); ++i) { + updateEdgeMergeHeap(edge_heap, v1_incident[i], merger); + } + + for (size_t i = 0; i < v2_incident.size(); ++i) { + updateEdgeMergeHeap(edge_heap, v2_incident[i], merger); + } + + vert_to_edges[v2].insert(vert_to_edges[v1].begin(), vert_to_edges[v1].end()); + vert_to_edges.erase(v1); + + for (size_t i = 0; i < edges_to_merge.size(); ++i) { + EdgeInfo *e = edges_to_merge[i]; + + removeFromEdgeMergeHeap(edge_heap, e, merger); + edge_info.erase(e->edge); + + vert_to_edges[v1].erase(e); + vert_to_edges[v2].erase(e); + + face_t *f1 = e->edge->face; + + e->edge->removeHalfEdge(); + + if (f1->n_edges == 2) { + edge_t *e1 = f1->edge; + edge_t *e2 = f1->edge->next; + if (e1->rev) e1->rev->rev = e2->rev; + if (e2->rev) e2->rev->rev = e1->rev; + EdgeInfo *e1i = edge_info[e1]; + EdgeInfo *e2i = edge_info[e2]; + CARVE_ASSERT(e1i != NULL); + CARVE_ASSERT(e2i != NULL); + vert_to_edges[e1->v1()].erase(e1i); + vert_to_edges[e1->v2()].erase(e1i); + vert_to_edges[e2->v1()].erase(e2i); + vert_to_edges[e2->v2()].erase(e2i); + removeFromEdgeMergeHeap(edge_heap, e1i, merger); + removeFromEdgeMergeHeap(edge_heap, e2i, merger); + edge_info.erase(e1); + edge_info.erase(e2); + f1->clearEdges(); + tree->remove(f1, aabb); + + delete e1i; + delete e2i; + } + delete e; + } + + tree->updateExtents(aabb); + } + + delete tree; + + return n_mods; + } + + + + size_t mergeCoplanarFaces(mesh_t *mesh, double min_normal_angle) { + std::unordered_set coplanar_face_edges; + double min_dp = cos(min_normal_angle); + size_t n_merge = 0; + + for (size_t i = 0; i < mesh->closed_edges.size(); ++i) { + edge_t *e = mesh->closed_edges[i]; + face_t *f1 = e->face; + face_t *f2 = e->rev->face; + + if (carve::geom::dot(f1->plane.N, f2->plane.N) < min_dp) { + continue; + } + + coplanar_face_edges.insert(std::min(e, e->rev)); + } + + while (coplanar_face_edges.size()) { + edge_t *edge = *coplanar_face_edges.begin(); + if (edge->face == edge->rev->face) { + coplanar_face_edges.erase(edge); + continue; + } + + edge_t *removed = edge->mergeFaces(); + if (removed == NULL) { + coplanar_face_edges.erase(edge); + ++n_merge; + } else { + edge_t *e = removed; + do { + edge_t *n = e->next; + coplanar_face_edges.erase(std::min(e, e->rev)); + delete e->rev; + delete e; + e = n; + } while (e != removed); + } + } + return n_merge; + } + + + + uint8_t affected_axes(const face_t *face) { + uint8_t r = 0; + if (fabs(carve::geom::dot(face->plane.N, carve::geom::VECTOR(1,0,0))) > 0.001) r |= 1; + if (fabs(carve::geom::dot(face->plane.N, carve::geom::VECTOR(0,1,0))) > 0.001) r |= 2; + if (fabs(carve::geom::dot(face->plane.N, carve::geom::VECTOR(0,0,1))) > 0.001) r |= 4; + return r; + } + + + + double median(std::vector &v) { + if (v.size() & 1) { + size_t N = v.size() / 2 + 1; + std::nth_element(v.begin(), v.begin() + N, v.end()); + return v[N]; + } else { + size_t N = v.size() / 2; + std::nth_element(v.begin(), v.begin() + N, v.end()); + return (v[N] + *std::min_element(v.begin() + N + 1, v.end())) / 2.0; + } + } + + + + double harmonicmean(const std::vector &v) { + double m = 0.0; + for (size_t i = 0; i < v.size(); ++i) { + m *= v[i]; + } + return pow(m, 1.0 / v.size()); + } + + + + double mean(const std::vector &v) { + double m = 0.0; + for (size_t i = 0; i < v.size(); ++i) { + m += v[i]; + } + return m / v.size(); + } + + + + template + void snapFaces(iter_t begin, iter_t end, double grid, int axis) { + std::set vertices; + for (iter_t i = begin; i != end; ++i) { + face_t *face = *i; + edge_t *edge = face->edge; + do { + vertices.insert(edge->vert); + edge = edge->next; + } while (edge != face->edge); + } + + std::vector pos; + pos.reserve(vertices.size()); + for (std::set::iterator i = vertices.begin(); i != vertices.end(); ++i) { + pos.push_back((*i)->v.v[axis]); + } + + double med = median(pos); + + double snap_pos = med; + if (grid) snap_pos = round(snap_pos / grid) * grid; + + for (std::set::iterator i = vertices.begin(); i != vertices.end(); ++i) { + (*i)->v.v[axis] = snap_pos; + } + + for (iter_t i = begin; i != end; ++i) { + face_t *face = *i; + face->recalc(); + edge_t *edge = face->edge; + do { + if (edge->rev && edge->rev->face) edge->rev->face->recalc(); + edge = edge->next; + } while (edge != face->edge); + } + } + + carve::geom::plane<3> quantizePlane(const face_t *face, + int angle_xy_quantization, + int angle_z_quantization) { + if (!angle_xy_quantization && !angle_z_quantization) { + return face->plane; + } + carve::geom::vector<3> normal = face->plane.N; + + if (angle_z_quantization) { + if (normal.x || normal.y) { + double a = asin(std::min(std::max(normal.z, 0.0), 1.0)); + a = round(a * angle_z_quantization / (M_PI * 2)) * (M_PI * 2) / angle_z_quantization; + normal.z = sin(a); + double s = sqrt((1 - normal.z * normal.z) / (normal.x * normal.x + normal.y * normal.y)); + normal.x = normal.x * s; + normal.y = normal.y * s; + } + } + if (angle_xy_quantization) { + if (normal.x || normal.y) { + double a = atan2(normal.y, normal.x); + a = round(a * angle_xy_quantization / (M_PI * 2)) * (M_PI * 2) / angle_xy_quantization; + double s = sqrt(1 - normal.z * normal.z); + s = std::min(std::max(s, 0.0), 1.0); + normal.x = cos(a) * s; + normal.y = sin(a) * s; + } + } + + std::cerr << "normal = " << normal << std::endl; + + std::vector d_vec; + d_vec.reserve(face->nVertices()); + edge_t *e = face->edge; + do { + d_vec.push_back(-carve::geom::dot(normal, e->vert->v)); + e = e->next; + } while (e != face->edge); + + return carve::geom::plane<3>(normal, mean(d_vec)); + } + + + + double summedError(const carve::geom::vector<3> &vert, const std::list > &planes) { + double d = 0; + for (std::list >::const_iterator i = planes.begin(); i != planes.end(); ++i) { + d += fabs(carve::geom::distance2(*i, vert)); + } + return d; + } + + + + double minimize(carve::geom::vector<3> &vert, const std::list > &planes, int axis) { + double num = 0.0; + double den = 0.0; + int a1 = (axis + 1) % 3; + int a2 = (axis + 2) % 3; + for (std::list >::const_iterator i = planes.begin(); i != planes.end(); ++i) { + const carve::geom::vector<3> &N = (*i).N; + const double d = (*i).d; + den += N.v[axis] * N.v[axis]; + num -= N.v[axis] * (N.v[a1] * vert.v[a1] + N.v[a2] * vert.v[a2] + d); + } + if (fabs(den) < 1e-5) return vert.v[axis]; + return num / den; + } + + + + size_t cleanFaceEdges(mesh_t *mesh) { + size_t n_removed = 0; + for (size_t i = 0; i < mesh->faces.size(); ++i) { + face_t *face = mesh->faces[i]; + edge_t *start = face->edge; + edge_t *edge = start; + do { + if (edge->next == edge->rev || edge->prev == edge->rev) { + edge = edge->removeEdge(); + ++n_removed; + start = edge->prev; + } else { + edge = edge->next; + } + } while (edge != start); + } + return n_removed; + } + + + + size_t cleanFaceEdges(meshset_t *mesh) { + size_t n_removed = 0; + for (size_t i = 0; i < mesh->meshes.size(); ++i) { + n_removed += cleanFaceEdges(mesh->meshes[i]); + } + return n_removed; + } + + + + void removeRemnantFaces(mesh_t *mesh) { + size_t n = 0; + for (size_t i = 0; i < mesh->faces.size(); ++i) { + if (mesh->faces[i]->nEdges() == 0) { + delete mesh->faces[i]; + } else { + mesh->faces[n++] = mesh->faces[i]; + } + } + mesh->faces.resize(n); + } + + + + void removeRemnantFaces(meshset_t *mesh) { + for (size_t i = 0; i < mesh->meshes.size(); ++i) { + removeRemnantFaces(mesh->meshes[i]); + } + } + + + + edge_t *removeFin(edge_t *e) { + // e and e->next are shared with the same reverse triangle. + edge_t *e1 = e->prev; + edge_t *e2 = e->rev->next; + CARVE_ASSERT(e1->v2() == e2->v1()); + CARVE_ASSERT(e2->v2() == e1->v1()); + + CARVE_ASSERT(e1->rev != e2 && e2->rev != e1); + + edge_t *e1r = e1->rev; + edge_t *e2r = e2->rev; + if (e1r) e1r->rev = e2r; + if (e2r) e2r->rev = e1r; + + face_t *f1 = e1->face; + face_t *f2 = e2->face; + f1->clearEdges(); + f2->clearEdges(); + + return e1r; + } + + size_t removeFin(face_t *face) { + if (face->edge == NULL || face->nEdges() != 3) return 0; + edge_t *e = face->edge; + do { + if (e->rev != NULL) { + face_t *revface = e->rev->face; + if (revface->nEdges() == 3) { + if (e->next->rev && e->next->rev->face == revface) { + if (e->next->next->rev && e->next->next->rev->face == revface) { + // isolated tripair + face->clearEdges(); + revface->clearEdges(); + return 1; + } + // fin + edge_t *spliced_edge = removeFin(e); + return 1 + removeFin(spliced_edge->face); + } + } + } + e = e->next; + } while (e != face->edge); + return 0; + } + + + + public: + // Merge adjacent coplanar faces (where coplanar is determined + // by dot-product >= cos(min_normal_angle)). + size_t mergeCoplanarFaces(meshset_t *meshset, double min_normal_angle) { + size_t n_removed = 0; + for (size_t i = 0; i < meshset->meshes.size(); ++i) { + n_removed += mergeCoplanarFaces(meshset->meshes[i], min_normal_angle); + removeRemnantFaces(meshset->meshes[i]); + cleanFaceEdges(meshset->meshes[i]); + meshset->meshes[i]->cacheEdges(); + } + return n_removed; + } + + size_t improveMesh_conservative(meshset_t *meshset) { + initEdgeInfo(meshset); + size_t modifications = flipEdges(meshset, FlippableConservative()); + clearEdgeInfo(); + return modifications; + } + + + + size_t improveMesh(meshset_t *meshset, + double min_colinearity, + double min_delta_v, + double min_normal_angle) { + initEdgeInfo(meshset); + size_t modifications = flipEdges(meshset, Flippable(min_colinearity, min_delta_v, min_normal_angle)); + clearEdgeInfo(); + return modifications; + } + + + + size_t eliminateShortEdges(meshset_t *meshset, + double min_length) { + initEdgeInfo(meshset); + size_t modifications = collapseEdges(meshset, EdgeMerger(min_length)); + removeRemnantFaces(meshset); + clearEdgeInfo(); + return modifications; + } + + + + // Snap vertices to grid, aligning almost flat axis-aligned + // faces to the axis, and flattening other faces as much as is + // possible. Passing a number less than DBL_MIN_EXPONENT (-1021) + // turns off snapping to grid (but face alignment is still + // performed). + void snap(meshset_t *meshset, + int log2_grid, + int angle_xy_quantization = 0, + int angle_z_quantization = 0) { + double grid = 0.0; + if (log2_grid >= std::numeric_limits::min_exponent) grid = pow(2.0, (double)log2_grid); + + typedef std::unordered_map axis_influence_map_t; + axis_influence_map_t axis_influence; + + typedef std::unordered_map > interaction_graph_t; + interaction_graph_t interacting_faces; + + for (size_t m = 0; m < meshset->meshes.size(); ++m) { + mesh_t *mesh = meshset->meshes[m]; + for (size_t f = 0; f < mesh->faces.size(); ++f) { + face_t *face = mesh->faces[f]; + axis_influence[face] = affected_axes(face); + } + } + + std::map > > non_axis_vertices; + std::unordered_map vertex_constraints; + + for (axis_influence_map_t::iterator i = axis_influence.begin(); i != axis_influence.end(); ++i) { + face_t *face = (*i).first; + uint8_t face_axes = (*i).second; + edge_t *edge = face->edge; + if (face_axes != 1 && face_axes != 2 && face_axes != 4) { + do { + non_axis_vertices[edge->vert].push_back(quantizePlane(face, + angle_xy_quantization, + angle_z_quantization)); + edge = edge->next; + } while (edge != face->edge); + } else { + interacting_faces[face].insert(face); + do { + vertex_constraints[edge->vert] |= face_axes; + + if (edge->rev && edge->rev->face) { + face_t *face2 = edge->rev->face; + uint8_t face2_axes = axis_influence[face2]; + if (face2_axes == face_axes) { + interacting_faces[face].insert(face2); + } + } + edge = edge->next; + } while (edge != face->edge); + } + } + + while (interacting_faces.size()) { + std::set face_set; + uint8_t axes = 0; + + std::set open; + open.insert((*interacting_faces.begin()).first); + while (open.size()) { + face_t *curr = *open.begin(); + open.erase(open.begin()); + face_set.insert(curr); + axes |= axis_influence[curr]; + for (interaction_graph_t::data_type::iterator i = interacting_faces[curr].begin(), e = interacting_faces[curr].end(); i != e; ++i) { + face_t *f = *i; + if (face_set.find(f) != face_set.end()) continue; + open.insert(f); + } + } + + switch (axes) { + case 1: snapFaces(face_set.begin(), face_set.end(), grid, 0); break; + case 2: snapFaces(face_set.begin(), face_set.end(), grid, 1); break; + case 4: snapFaces(face_set.begin(), face_set.end(), grid, 2); break; + default: CARVE_FAIL("should not be reached"); + } + + for (std::set::iterator i = face_set.begin(); i != face_set.end(); ++i) { + interacting_faces.erase((*i)); + } + } + + for (std::map > >::iterator i = non_axis_vertices.begin(); i != non_axis_vertices.end(); ++i) { + vertex_t *vert = (*i).first; + std::list > &planes = (*i).second; + uint8_t constraint = vertex_constraints[vert]; + + if (constraint == 7) continue; + + double d = summedError(vert->v, planes); + for (size_t N = 0; ; N = (N+1) % 3) { + if (constraint & (1 << N)) continue; + vert->v[N] = minimize(vert->v, planes, N); + double d_next = summedError(vert->v, planes); + if (d - d_next < 1e-20) break; + d = d_next; + } + + if (grid) { + carve::geom::vector<3> v_best = vert->v; + double d_best = 0.0; + + for (size_t axes = 0; axes < 8; ++axes) { + carve::geom::vector<3> v = vert->v; + for (size_t N = 0; N < 3; ++N) { + if (constraint & (1 << N)) continue; + if (axes & (1<v = v_best; + } + } + } + + + + size_t simplify(meshset_t *meshset, + double min_colinearity, + double min_delta_v, + double min_normal_angle, + double min_length) { + size_t modifications = 0; + size_t n, n_flip, n_merge; + + initEdgeInfo(meshset); + + std::cerr << "initial merge" << std::endl; + modifications = collapseEdges(meshset, EdgeMerger(0.0)); + removeRemnantFaces(meshset); + + do { + n_flip = n_merge = 0; + // std::cerr << "flip colinear pairs"; + // n = flipEdges(meshset, FlippableColinearPair()); + // std::cerr << " " << n << std::endl; + // n_flip = n; + + std::cerr << "flip conservative"; + n = flipEdges(meshset, FlippableConservative()); + std::cerr << " " << n << std::endl; + n_flip += n; + + std::cerr << "flip"; + n = flipEdges(meshset, Flippable(min_colinearity, min_delta_v, min_normal_angle)); + std::cerr << " " << n << std::endl; + n_flip += n; + + std::cerr << "merge"; + n = collapseEdges(meshset, EdgeMerger(min_length)); + removeRemnantFaces(meshset); + std::cerr << " " << n << std::endl; + n_merge = n; + + modifications += n_flip + n_merge; + std::cerr << "stats:" << n_flip << " " << n_merge << std::endl; + } while (n_flip || n_merge); + + clearEdgeInfo(); + + for (size_t i = 0; i < meshset->meshes.size(); ++i) { + meshset->meshes[i]->cacheEdges(); + } + + return modifications; + } + + + + size_t removeFins(mesh_t *mesh) { + size_t n_removed = 0; + for (size_t i = 0; i < mesh->faces.size(); ++i) { + n_removed += removeFin(mesh->faces[i]); + } + if (n_removed) removeRemnantFaces(mesh); + return n_removed; + } + + + + size_t removeFins(meshset_t *meshset) { + size_t n_removed = 0; + for (size_t i = 0; i < meshset->meshes.size(); ++i) { + n_removed += removeFins(meshset->meshes[i]); + } + return n_removed; + } + + + + size_t removeLowVolumeManifolds(meshset_t *meshset, double min_abs_volume) { + size_t n_removed; + for (size_t i = 0; i < meshset->meshes.size(); ++i) { + if (fabs(meshset->meshes[i]->volume()) < min_abs_volume) { + delete meshset->meshes[i]; + meshset->meshes[i] = NULL; + ++n_removed; + } + } + meshset->meshes.erase(std::remove_if(meshset->meshes.begin(), + meshset->meshes.end(), + std::bind2nd(std::equal_to(), (mesh_t *)NULL)), + meshset->meshes.end()); + return n_removed; + } + + struct point_enumerator_t { + struct heapval_t { + double dist; + vector_t pt; + heapval_t(double _dist, vector_t _pt) : dist(_dist), pt(_pt) { + } + heapval_t() {} + bool operator==(const heapval_t &other) const { return dist == other.dist && pt == other.pt; } + bool operator<(const heapval_t &other) const { return dist > other.dist || (dist == other.dist && pt > other.pt); } + }; + + vector_t origin; + double rounding_fac; + heapval_t last; + std::vector heap; + + point_enumerator_t(vector_t _origin, int _base, int _n_dp) : origin(_origin), rounding_fac(pow(_base, _n_dp)), last(-1.0, _origin), heap() { + for (size_t i = 0; i < (1 << 3); ++i) { + vector_t t = origin; + for (size_t j = 0; j < 3; ++j) { + if (i & (1U << j)) { + t[j] = ceil(t[j] * rounding_fac) / rounding_fac; + } else { + t[j] = floor(t[j] * rounding_fac) / rounding_fac; + } + } + heap.push_back(heapval_t(carve::geom::distance2(origin, t), t)); + } + std::make_heap(heap.begin(), heap.end()); + } + + vector_t next() { + heapval_t curr; + do { + CARVE_ASSERT(heap.size()); + std::pop_heap(heap.begin(), heap.end()); + curr = heap.back(); + heap.pop_back(); + } while (curr == last); + + vector_t t; + + for (int dx = -1; dx <= +1; ++dx) { + t.x = floor(curr.pt.x * rounding_fac + dx) / rounding_fac; + for (int dy = -1; dy <= +1; ++dy) { + t.y = floor(curr.pt.y * rounding_fac + dy) / rounding_fac; + for (int dz = -1; dz <= +1; ++dz) { + t.z = floor(curr.pt.z * rounding_fac + dz) / rounding_fac; + heapval_t h2(carve::geom::distance2(origin, t), t); + if (h2 < curr) { + heap.push_back(h2); + std::push_heap(heap.begin(), heap.end()); + } + } + } + } + last = curr; + return curr.pt; + } + }; + + struct quantization_info_t { + point_enumerator_t *pt; + std::set faces; + + quantization_info_t() : pt(NULL), faces() { + } + + ~quantization_info_t() { + if (pt) delete pt; + } + + aabb_t getAABB() const { + std::set::iterator i = faces.begin(); + aabb_t aabb = (*i)->getAABB(); + while (++i != faces.end()) { + aabb.unionAABB((*i)->getAABB()); + } + return aabb; + } + }; + + void selfIntersectionAwareQuantize(meshset_t *meshset, int base, int n_dp) { + typedef std::unordered_map vfsmap_t; + + vfsmap_t vertex_qinfo; + + for (size_t m = 0; m < meshset->meshes.size(); ++m) { + mesh_t *mesh = meshset->meshes[m]; + for (size_t f = 0; f < mesh->faces.size(); ++f) { + face_t *face = mesh->faces[f]; + edge_t *e = face->edge; + do { + vertex_qinfo[e->vert].faces.insert(face); + e = e->next; + } while (e != face->edge); + } + } + + face_rtree_t *tree = face_rtree_t::construct_STR(meshset->faceBegin(), meshset->faceEnd(), 4, 4); + + for (vfsmap_t::iterator i = vertex_qinfo.begin(); i != vertex_qinfo.end(); ++i) { + (*i).second.pt = new point_enumerator_t((*i).first->v, base, n_dp); + } + + while (vertex_qinfo.size()) { + std::vector quantized; + + std::cerr << "vertex_qinfo.size() == " << vertex_qinfo.size() << std::endl; + + for (vfsmap_t::iterator i = vertex_qinfo.begin(); i != vertex_qinfo.end(); ++i) { + vertex_t *vert = (*i).first; + quantization_info_t &qi = (*i).second; + vector_t q_pt = qi.pt->next(); + aabb_t aabb = qi.getAABB(); + aabb.unionAABB(aabb_t(q_pt)); + + std::vector overlapping; + tree->search(aabb, std::back_inserter(overlapping)); + + + int n_intersections = countIntersectionPairs(qi.faces.begin(), qi.faces.end(), + overlapping.begin(), overlapping.end(), + vert, NULL, q_pt); + + if (n_intersections == 0) { + vert->v = q_pt; + quantized.push_back((*i).first); + tree->updateExtents(aabb); + } + } + for (size_t i = 0; i < quantized.size(); ++i) { + vertex_qinfo.erase(quantized[i]); + } + + if (!quantized.size()) break; + } + } + + + }; + } +} diff -Nru blender-2.61/extern/carve/include/carve/octree_decl.hpp blender-2.62/extern/carve/include/carve/octree_decl.hpp --- blender-2.61/extern/carve/include/carve/octree_decl.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/octree_decl.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,193 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +#include +#include + +#include + +namespace carve { + + namespace csg { + + const double SLACK_FACTOR=1.0009765625; + const unsigned FACE_SPLIT_THRESHOLD=50U; + const unsigned EDGE_SPLIT_THRESHOLD=50U; + const unsigned POINT_SPLIT_THRESHOLD=20U; + const unsigned MAX_SPLIT_DEPTH=32; + + class Octree { + + public: + class Node { + private: + Node(const Node &node); // undefined. + Node &operator=(const Node &node); // undefined. + + public: + Node *parent; + Node *children[8]; + bool is_leaf; + + carve::geom3d::Vector min; + carve::geom3d::Vector max; + + std::vector::face_t *> faces; + std::vector::edge_t *> edges; + std::vector::vertex_t *> vertices; + + carve::geom3d::AABB aabb; + + Node(); + + Node(const carve::geom3d::Vector &newMin, const carve::geom3d::Vector &newMax); + Node(Node *p, double x1, double y1, double z1, double x2, double y2, double z2); + + ~Node(); + + bool mightContain(const carve::poly::Geometry<3>::face_t &face); + bool mightContain(const carve::poly::Geometry<3>::edge_t &edge); + bool mightContain(const carve::poly::Geometry<3>::vertex_t &p); + bool hasChildren(); + bool hasGeometry(); + + template + void putInside(const T &input, Node *child, T &output); + + bool split(); + }; + + + + Node *root; + + + + struct no_filter { + bool operator()(const carve::poly::Geometry<3>::edge_t *) { return true; } + bool operator()(const carve::poly::Geometry<3>::face_t *) { return true; } + }; + + + + Octree(); + + ~Octree(); + + + + void setBounds(const carve::geom3d::Vector &min, const carve::geom3d::Vector &max); + void setBounds(carve::geom3d::AABB aabb); + + + + void addEdges(const std::vector::edge_t > &edges); + void addFaces(const std::vector::face_t > &faces); + void addVertices(const std::vector::vertex_t *> &vertices); + + + + static carve::geom3d::AABB makeAABB(const Node *node); + + + + void doFindEdges(const carve::geom::aabb<3> &aabb, + Node *node, + std::vector::edge_t *> &out, + unsigned depth) const; + void doFindEdges(const carve::geom3d::LineSegment &l, + Node *node, + std::vector::edge_t *> &out, + unsigned depth) const; + void doFindEdges(const carve::geom3d::Vector &v, + Node *node, + std::vector::edge_t *> &out, + unsigned depth) const; + void doFindFaces(const carve::geom::aabb<3> &aabb, + Node *node, + std::vector::face_t *> &out, + unsigned depth) const; + void doFindFaces(const carve::geom3d::LineSegment &l, + Node *node, + std::vector::face_t *> &out, + unsigned depth) const; + + + + void doFindVerticesAllowDupes(const carve::geom3d::Vector &v, + Node *node, + std::vector::vertex_t *> &out, + unsigned depth) const; + + void findVerticesNearAllowDupes(const carve::geom3d::Vector &v, + std::vector::vertex_t *> &out) const; + + + + template + void doFindEdges(const carve::poly::Geometry<3>::face_t &f, Node *node, + std::vector::edge_t *> &out, + unsigned depth, + filter_t filter) const; + + template + void findEdgesNear(const carve::poly::Geometry<3>::face_t &f, + std::vector::edge_t *> &out, + filter_t filter) const; + + void findEdgesNear(const carve::poly::Geometry<3>::face_t &f, + std::vector::edge_t *> &out) const { + return findEdgesNear(f, out, no_filter()); + } + + + + void findEdgesNear(const carve::geom::aabb<3> &aabb, std::vector::edge_t *> &out) const; + void findEdgesNear(const carve::geom3d::LineSegment &l, std::vector::edge_t *> &out) const; + void findEdgesNear(const carve::poly::Geometry<3>::edge_t &e, std::vector::edge_t *> &out) const; + void findEdgesNear(const carve::geom3d::Vector &v, std::vector::edge_t *> &out) const; + + + + void findFacesNear(const carve::geom::aabb<3> &aabb, std::vector::face_t *> &out) const; + void findFacesNear(const carve::geom3d::LineSegment &l, std::vector::face_t *> &out) const; + void findFacesNear(const carve::poly::Geometry<3>::edge_t &e, std::vector::face_t *> &out) const; + + + + static void doSplit(int maxSplit, Node *node); + + + + template + void doIterate(int level, Node *node, const FUNC &f) const; + + template + void iterateNodes(const FUNC &f) const; + + + + void splitTree(); + + }; + + } +} diff -Nru blender-2.61/extern/carve/include/carve/octree_impl.hpp blender-2.62/extern/carve/include/carve/octree_impl.hpp --- blender-2.61/extern/carve/include/carve/octree_impl.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/octree_impl.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,79 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +namespace carve { + namespace csg { + template + void Octree::doFindEdges(const carve::poly::Geometry<3>::face_t &f, + Node *node, + std::vector::edge_t *> &out, + unsigned depth, + filter_t filter) const { + if (node == NULL) { + return; + } + + if (node->aabb.intersects(f.aabb) && node->aabb.intersects(f.plane_eqn)) { + if (node->hasChildren()) { + for (int i = 0; i < 8; ++i) { + doFindEdges(f, node->children[i], out, depth + 1, filter); + } + } else { + if (depth < MAX_SPLIT_DEPTH && node->edges.size() > EDGE_SPLIT_THRESHOLD) { + if (!node->split()) { + for (int i = 0; i < 8; ++i) { + doFindEdges(f, node->children[i], out, depth + 1, filter); + } + return; + } + } + for (std::vector::edge_t*>::const_iterator it = node->edges.begin(), e = node->edges.end(); it != e; ++it) { + if ((*it)->tag_once()) { + if (filter(*it)) { + out.push_back(*it); + } + } + } + } + } + } + + template + void Octree::findEdgesNear(const carve::poly::Geometry<3>::face_t &f, std::vector::edge_t *> &out, filter_t filter) const { + tagable::tag_begin(); + doFindEdges(f, root, out, 0, filter); + } + + template + void Octree::doIterate(int level, Node *node, const func_t &f) const{ + f(level, node); + if (node->hasChildren()) { + for (int i = 0; i < 8; ++i) { + doIterate(level + 1, node->children[i], f); + } + } + } + + template + void Octree::iterateNodes(const func_t &f) const { + doIterate(0, root, f); + } + + } +} diff -Nru blender-2.61/extern/carve/include/carve/pointset_decl.hpp blender-2.62/extern/carve/include/carve/pointset_decl.hpp --- blender-2.61/extern/carve/include/carve/pointset_decl.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/pointset_decl.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,61 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + +#pragma once + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace carve { + namespace point { + + struct Vertex : public tagable { + carve::geom3d::Vector v; + }; + + + + struct vec_adapt_vertex_ptr { + const carve::geom3d::Vector &operator()(const Vertex * const &v) { return v->v; } + carve::geom3d::Vector &operator()(Vertex *&v) { return v->v; } + }; + + + + struct PointSet { + std::vector vertices; + carve::geom3d::AABB aabb; + + PointSet(const std::vector &points); + PointSet() { + } + + void sortVertices(const carve::geom3d::Vector &axis); + + size_t vertexToIndex_fast(const Vertex *v) const; + }; + + } +} diff -Nru blender-2.61/extern/carve/include/carve/pointset.hpp blender-2.62/extern/carve/include/carve/pointset.hpp --- blender-2.61/extern/carve/include/carve/pointset.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/pointset.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,24 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +#include +#include +#include diff -Nru blender-2.61/extern/carve/include/carve/pointset_impl.hpp blender-2.62/extern/carve/include/carve/pointset_impl.hpp --- blender-2.61/extern/carve/include/carve/pointset_impl.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/pointset_impl.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,36 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + +#pragma once + +#include + +#include +#include +#include +#include +#include +#include + +namespace carve { + namespace point { + + inline size_t PointSet::vertexToIndex_fast(const Vertex *v) const { + return v - &vertices[0]; + } + + } +} diff -Nru blender-2.61/extern/carve/include/carve/pointset_iter.hpp blender-2.62/extern/carve/include/carve/pointset_iter.hpp --- blender-2.61/extern/carve/include/carve/pointset_iter.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/pointset_iter.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,18 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + +#pragma once + diff -Nru blender-2.61/extern/carve/include/carve/poly_decl.hpp blender-2.62/extern/carve/include/carve/poly_decl.hpp --- blender-2.61/extern/carve/include/carve/poly_decl.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/poly_decl.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,25 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +#include +#include +#include +#include diff -Nru blender-2.61/extern/carve/include/carve/polyhedron_base.hpp blender-2.62/extern/carve/include/carve/polyhedron_base.hpp --- blender-2.61/extern/carve/include/carve/polyhedron_base.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/polyhedron_base.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,149 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +#include + +#include +#include +#include + +#include + +namespace carve { + namespace poly { + + + + struct Object { + }; + + + + template + ptrdiff_t ptrToIndex_fast(const array_t &a, const typename array_t::value_type *v) { + return v - &a[0]; + } + + template + ptrdiff_t ptrToIndex(const array_t &a, const typename array_t::value_type *v) { + if (v < &a.front() || v > &a.back()) return -1; + return v - &a[0]; + } + + + template + struct Geometry : public Object { + struct Connectivity { + } connectivity; + }; + + + + template<> + struct Geometry<2> : public Object { + typedef Vertex<2> vertex_t; + typedef Edge<2> edge_t; + + struct Connectivity { + std::vector > vertex_to_edge; + } connectivity; + + std::vector vertices; + std::vector edges; + + ptrdiff_t vertexToIndex_fast(const vertex_t *v) const { return ptrToIndex_fast(vertices, v); } + ptrdiff_t vertexToIndex(const vertex_t *v) const { return ptrToIndex(vertices, v); } + + ptrdiff_t edgeToIndex_fast(const edge_t *e) const { return ptrToIndex_fast(edges, e); } + ptrdiff_t edgeToIndex(const edge_t *e) const { return ptrToIndex(edges, e); } + + + + // *** connectivity queries + + template + int vertexToEdges(const vertex_t *v, T result) const; + }; + + + + template<> + struct Geometry<3> : public Object { + typedef Vertex<3> vertex_t; + typedef Edge<3> edge_t; + typedef Face<3> face_t; + + struct Connectivity { + std::vector > vertex_to_edge; + std::vector > vertex_to_face; + std::vector > edge_to_face; + } connectivity; + + std::vector vertices; + std::vector edges; + std::vector faces; + + ptrdiff_t vertexToIndex_fast(const vertex_t *v) const { return ptrToIndex_fast(vertices, v); } + ptrdiff_t vertexToIndex(const vertex_t *v) const { return ptrToIndex(vertices, v); } + + ptrdiff_t edgeToIndex_fast(const edge_t *e) const { return ptrToIndex_fast(edges, e); } + ptrdiff_t edgeToIndex(const edge_t *e) const { return ptrToIndex(edges, e); } + + ptrdiff_t faceToIndex_fast(const face_t *f) const { return ptrToIndex_fast(faces, f); } + ptrdiff_t faceToIndex(const face_t *f) const { return ptrToIndex(faces, f); } + + template + bool orderVertices(order_t order); + + bool orderVertices() { return orderVertices(std::less()); } + + + + // *** connectivity queries + + const face_t *connectedFace(const face_t *, const edge_t *) const; + + template + int _faceNeighbourhood(const face_t *f, int depth, T *result) const; + + template + int faceNeighbourhood(const face_t *f, int depth, T result) const; + + template + int faceNeighbourhood(const edge_t *e, int m_id, int depth, T result) const; + + template + int faceNeighbourhood(const vertex_t *v, int m_id, int depth, T result) const; + + template + int vertexToEdges(const vertex_t *v, T result) const; + + template + int edgeToFaces(const edge_t *e, T result) const; + + template + int vertexToFaces(const vertex_t *v, T result) const; + }; + + + + } +} diff -Nru blender-2.61/extern/carve/include/carve/polyhedron_decl.hpp blender-2.62/extern/carve/include/carve/polyhedron_decl.hpp --- blender-2.61/extern/carve/include/carve/polyhedron_decl.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/polyhedron_decl.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,184 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +#include + +#include +#include +#include + +#include +#include + + +namespace carve { + namespace mesh { + template + class MeshSet; + } + + namespace poly { + class Polyhedron; + } + + poly::Polyhedron *polyhedronFromMesh(const mesh::MeshSet<3> *, int); + + namespace poly { + + class Polyhedron : public Geometry<3> { + private: + friend Polyhedron *carve::polyhedronFromMesh(const mesh::MeshSet<3> *, int); + + Polyhedron() { + } + + Polyhedron &operator=(const Polyhedron &); // not implemented + + // *** initialization + + bool initSpatialIndex(); + void initVertexConnectivity(); + void setFaceAndVertexOwner(); + + bool initConnectivity(); + bool markManifolds(); + bool calcManifoldEmbedding(); + + bool init(); + void faceRecalc(); + + void commonFaceInit(bool _recalc); + + public: + static void collectFaceVertices(std::vector &faces, + std::vector &vertices, + std::unordered_map &vmap); + + static void collectFaceVertices(std::vector &faces, + std::vector &vertices); + + std::vector manifold_is_closed; + std::vector manifold_is_negative; + + carve::geom3d::AABB aabb; + carve::csg::Octree octree; + + + + // *** construction of Polyhedron objects + + Polyhedron(const Polyhedron &); + + // copy a single manifold + Polyhedron(const Polyhedron &, int m_id); + + // copy a subset of manifolds + Polyhedron(const Polyhedron &, const std::vector &selected_manifolds); + + Polyhedron(std::vector &_faces, + std::vector &_vertices, + bool _recalc = false); + + Polyhedron(std::vector &_faces, + bool _recalc = false); + + Polyhedron(std::list &_faces, + bool _recalc = false); + + Polyhedron(const std::vector &vertices, + int n_faces, + const std::vector &face_indices); + + ~Polyhedron(); + + + + // *** containment queries + + void testVertexAgainstClosedManifolds(const carve::geom3d::Vector &v, + std::map &result, + bool ignore_orentation) const; + + PointClass containsVertex(const carve::geom3d::Vector &v, + const face_t **hit_face = NULL, + bool even_odd = false, + int manifold_id = -1) const; + + + + // *** locality queries + + void findEdgesNear(const carve::geom::aabb<3> &aabb, std::vector &edges) const; + void findEdgesNear(const carve::geom3d::LineSegment &l, std::vector &edges) const; + void findEdgesNear(const carve::geom3d::Vector &v, std::vector &edges) const; + void findEdgesNear(const face_t &face, std::vector &edges) const; + void findEdgesNear(const edge_t &edge, std::vector &edges) const; + + void findFacesNear(const carve::geom::aabb<3> &aabb, std::vector &faces) const; + void findFacesNear(const carve::geom3d::LineSegment &l, std::vector &faces) const; + void findFacesNear(const edge_t &edge, std::vector &faces) const; + + + + // *** manifold queries + + inline bool vertexOnManifold(const vertex_t *v, int m_id) const; + inline bool edgeOnManifold(const edge_t *e, int m_id) const; + + template + int vertexManifolds(const vertex_t *v, T result) const; + + template + int edgeManifolds(const edge_t *e, T result) const; + + size_t manifoldCount() const; + + bool hasOpenManifolds() const; + + + + + // *** transformation + + // flip face directions + void invertAll(); + void invert(const std::vector &selected_manifolds); + + void invert(int m_id); + void invert(); + + // matrix transform of vertices + void transform(const carve::math::Matrix &xform); + + // arbitrary function transform of vertices + template + void transform(const T &xform); + + void print(std::ostream &) const; + + void canonicalize(); + }; + + std::ostream &operator<<(std::ostream &, const Polyhedron &); + + } + +} diff -Nru blender-2.61/extern/carve/include/carve/polyhedron_impl.hpp blender-2.62/extern/carve/include/carve/polyhedron_impl.hpp --- blender-2.61/extern/carve/include/carve/polyhedron_impl.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/polyhedron_impl.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,287 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +#include +#include + +namespace carve { + namespace poly { + + + + template + struct VPtrSort { + order_t order; + + VPtrSort(const order_t &_order) : order(_order) {} + bool operator()(carve::poly::Polyhedron::vertex_t const *a, + carve::poly::Polyhedron::vertex_t const *b) const { + return order(a->v, b->v); + } + }; + + template + bool Geometry<3>::orderVertices(order_t order) { + static carve::TimingName FUNC_NAME("Geometry<3>::orderVertices()"); + carve::TimingBlock block(FUNC_NAME); + + std::vector vptr; + std::vector vmap; + std::vector vout; + const size_t N = vertices.size(); + + vptr.reserve(N); + vout.reserve(N); + vmap.resize(N); + + for (size_t i = 0; i != N; ++i) { + vptr.push_back(&vertices[i]); + } + std::sort(vptr.begin(), vptr.end(), VPtrSort(order)); + + for (size_t i = 0; i != N; ++i) { + vout.push_back(*vptr[i]); + vmap[vertexToIndex_fast(vptr[i])] = &vout[i]; + } + + for (size_t i = 0; i < faces.size(); ++i) { + face_t &f = faces[i]; + for (size_t j = 0; j < f.nVertices(); ++j) { + f.vertex(j) = vmap[vertexToIndex_fast(f.vertex(j))]; + } + } + for (size_t i = 0; i < edges.size(); ++i) { + edges[i].v1 = vmap[vertexToIndex_fast(edges[i].v1)]; + edges[i].v2 = vmap[vertexToIndex_fast(edges[i].v2)]; + } + + vout.swap(vertices); + + return true; + } + + + + template + int Geometry<3>::_faceNeighbourhood(const face_t *f, int depth, T *result) const { + if (depth < 0 || f->is_tagged()) return 0; + + f->tag(); + *(*result)++ = f; + + int r = 1; + for (size_t i = 0; i < f->edges.size(); ++i) { + const std::vector &edge_faces = connectivity.edge_to_face[edgeToIndex_fast(f->edges[i])]; + const face_t *f2 = connectedFace(f, f->edges[i]); + if (f2) { + r += _faceNeighbourhood(f2, depth - 1, (*result)); + } + } + return r; + } + + + + template + int Geometry<3>::faceNeighbourhood(const face_t *f, int depth, T result) const { + tagable::tag_begin(); + + return _faceNeighbourhood(f, depth, &result); + } + + + + template + int Geometry<3>::faceNeighbourhood(const edge_t *e, int m_id, int depth, T result) const { + tagable::tag_begin(); + + int r = 0; + const std::vector &edge_faces = connectivity.edge_to_face[edgeToIndex_fast(e)]; + for (size_t i = 0; i < edge_faces.size(); ++i) { + face_t *f = edge_faces[i]; + if (f && f->manifold_id == m_id) { r += _faceNeighbourhood(f, depth, &result); } + } + return r; + } + + + + template + int Geometry<3>::faceNeighbourhood(const vertex_t *v, int m_id, int depth, T result) const { + tagable::tag_begin(); + + int r = 0; + const std::vector &vertex_faces = connectivity.vertex_to_face[vertexToIndex_fast(v)]; + for (size_t i = 0; i < vertex_faces.size(); ++i) { + face_t *f = vertex_faces[i]; + if (f && f->manifold_id == m_id) { r += _faceNeighbourhood(f, depth, &result); } + } + return r; + } + + + + // accessing connectivity information. + template + int Geometry<3>::vertexToEdges(const vertex_t *v, T result) const { + std::vector &e = connectivity.vertex_to_edge[vertexToIndex_fast(v)]; + std::copy(e.begin(), e.end(), result); + return e.size(); + } + + + + template + int Geometry<3>::vertexToFaces(const vertex_t *v, T result) const { + const std::vector &vertex_faces = connectivity.vertex_to_face[vertexToIndex_fast(v)]; + int c = 0; + for (size_t i = 0; i < vertex_faces.size(); ++i) { + *result++ = vertex_faces[i]; ++c; + } + return c; + } + + + + template + int Geometry<3>::edgeToFaces(const edge_t *e, T result) const { + const std::vector &edge_faces = connectivity.edge_to_face[edgeToIndex_fast(e)]; + int c = 0; + for (size_t i = 0; i < edge_faces.size(); ++i) { + if (edge_faces[i] != NULL) { *result++ = edge_faces[i]; ++c; } + } + return c; + } + + + + inline const Geometry<3>::face_t *Geometry<3>::connectedFace(const face_t *f, const edge_t *e) const { + const std::vector &edge_faces = connectivity.edge_to_face[edgeToIndex_fast(e)]; + for (size_t i = 0; i < (edge_faces.size() & ~1U); i++) { + if (edge_faces[i] == f) return edge_faces[i^1]; + } + return NULL; + } + + + + inline void Polyhedron::invert(int m_id) { + std::vector selected_manifolds(manifold_is_closed.size(), false); + if (m_id >=0 && (unsigned)m_id < selected_manifolds.size()) selected_manifolds[m_id] = true; + invert(selected_manifolds); + } + + + + inline void Polyhedron::invert() { + invertAll(); + } + + + + inline bool Polyhedron::edgeOnManifold(const edge_t *e, int m_id) const { + const std::vector &edge_faces = connectivity.edge_to_face[edgeToIndex_fast(e)]; + + for (size_t i = 0; i < edge_faces.size(); ++i) { + if (edge_faces[i] && edge_faces[i]->manifold_id == m_id) return true; + } + return false; + } + + inline bool Polyhedron::vertexOnManifold(const vertex_t *v, int m_id) const { + const std::vector &f = connectivity.vertex_to_face[vertexToIndex_fast(v)]; + + for (size_t i = 0; i < f.size(); ++i) { + if (f[i]->manifold_id == m_id) return true; + } + return false; + } + + + + template + int Polyhedron::edgeManifolds(const edge_t *e, T result) const { + const std::vector &edge_faces = connectivity.edge_to_face[edgeToIndex_fast(e)]; + + for (size_t i = 0; i < (edge_faces.size() & ~1U); i += 2) { + const face_t *f1 = edge_faces[i]; + const face_t *f2 = edge_faces[i+1]; + assert (f1 || f2); + if (f1) + *result++ = f1->manifold_id; + else if (f2) + *result++ = f2->manifold_id; + } + return edge_faces.size() >> 1; + } + + + + template + int Polyhedron::vertexManifolds(const vertex_t *v, T result) const { + const std::vector &f = connectivity.vertex_to_face[vertexToIndex_fast(v)]; + std::set em; + + for (size_t i = 0; i < f.size(); ++i) { + em.insert(f[i]->manifold_id); + } + + std::copy(em.begin(), em.end(), result); + return em.size(); + } + + + + template + void Polyhedron::transform(const T &xform) { + for (size_t i = 0; i < vertices.size(); i++) { + vertices[i].v = xform(vertices[i].v); + } + faceRecalc(); + init(); + } + + + + inline size_t Polyhedron::manifoldCount() const { + return manifold_is_closed.size(); + } + + + + inline bool Polyhedron::hasOpenManifolds() const { + for (size_t i = 0; i < manifold_is_closed.size(); ++i) { + if (!manifold_is_closed[i]) return true; + } + return false; + } + + + + inline std::ostream &operator<<(std::ostream &o, const Polyhedron &p) { + p.print(o); + return o; + } + + + + } +} diff -Nru blender-2.61/extern/carve/include/carve/poly.hpp blender-2.62/extern/carve/include/carve/poly.hpp --- blender-2.61/extern/carve/include/carve/poly.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/poly.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,24 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +#include + +#include diff -Nru blender-2.61/extern/carve/include/carve/poly_impl.hpp blender-2.62/extern/carve/include/carve/poly_impl.hpp --- blender-2.61/extern/carve/include/carve/poly_impl.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/poly_impl.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,25 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +#include +#include +#include +#include diff -Nru blender-2.61/extern/carve/include/carve/polyline_decl.hpp blender-2.62/extern/carve/include/carve/polyline_decl.hpp --- blender-2.61/extern/carve/include/carve/polyline_decl.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/polyline_decl.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,151 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + +#pragma once + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace carve { + namespace line { + + struct PolylineEdge; + struct Polyline; + struct polyline_vertex_const_iter; + struct polyline_vertex_iter; + struct polyline_edge_const_iter; + struct polyline_edge_iter; + + + + struct Vertex : public tagable { + carve::geom3d::Vector v; + std::list > edge_pairs; + + void addEdgePair(PolylineEdge *in, PolylineEdge *out) { + edge_pairs.push_back(std::make_pair(in, out)); + } + }; + + + + struct vec_adapt_vertex_ptr { + const carve::geom3d::Vector &operator()(const Vertex * const &v) { return v->v; } + carve::geom3d::Vector &operator()(Vertex *&v) { return v->v; } + }; + + + + struct PolylineEdge : public tagable { + Polyline *parent; + unsigned edgenum; + Vertex *v1, *v2; + + PolylineEdge(Polyline *_parent, int _edgenum, Vertex *_v1, Vertex *_v2); + + carve::geom3d::AABB aabb() const; + + inline PolylineEdge *prevEdge() const; + inline PolylineEdge *nextEdge() const; + }; + + + + struct Polyline { + bool closed; + std::vector edges; + + Polyline(); + + size_t vertexCount() const; + + size_t edgeCount() const; + + const PolylineEdge *edge(size_t e) const; + + PolylineEdge *edge(size_t e); + + const Vertex *vertex(size_t v) const; + + Vertex *vertex(size_t v); + + bool isClosed() const; + + polyline_vertex_const_iter vbegin() const; + polyline_vertex_const_iter vend() const; + polyline_vertex_iter vbegin(); + polyline_vertex_iter vend(); + + polyline_edge_const_iter ebegin() const; + polyline_edge_const_iter eend() const; + polyline_edge_iter ebegin(); + polyline_edge_iter eend(); + + carve::geom3d::AABB aabb() const; + + template + void _init(bool c, iter_t begin, iter_t end, std::vector &vertices); + + template + void _init(bool closed, iter_t begin, iter_t end, std::vector &vertices, std::forward_iterator_tag); + + template + void _init(bool closed, iter_t begin, iter_t end, std::vector &vertices, std::random_access_iterator_tag); + + template + Polyline(bool closed, iter_t begin, iter_t end, std::vector &vertices); + + ~Polyline() { + for (size_t i = 0; i < edges.size(); ++i) { + delete edges[i]; + } + } + }; + + + + struct PolylineSet { + typedef std::list line_list; + typedef line_list::iterator line_iter; + typedef line_list::const_iterator const_line_iter; + + std::vector vertices; + line_list lines; + carve::geom3d::AABB aabb; + + PolylineSet(const std::vector &points); + PolylineSet() { + } + + template + void addPolyline(bool closed, iter_t begin, iter_t end); + + void sortVertices(const carve::geom3d::Vector &axis); + + size_t vertexToIndex_fast(const Vertex *v) const; + }; + + } +} diff -Nru blender-2.61/extern/carve/include/carve/polyline.hpp blender-2.62/extern/carve/include/carve/polyline.hpp --- blender-2.61/extern/carve/include/carve/polyline.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/polyline.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,24 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +#include +#include +#include diff -Nru blender-2.61/extern/carve/include/carve/polyline_impl.hpp blender-2.62/extern/carve/include/carve/polyline_impl.hpp --- blender-2.61/extern/carve/include/carve/polyline_impl.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/polyline_impl.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,160 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + +#pragma once + +namespace carve { + namespace line { + + inline PolylineEdge::PolylineEdge(Polyline *_parent, int _edgenum, Vertex *_v1, Vertex *_v2) : + tagable(), parent(_parent), edgenum(_edgenum), v1(_v1), v2(_v2) { + } + + inline carve::geom3d::AABB PolylineEdge::aabb() const { + carve::geom3d::AABB a; + a.fit(v1->v, v2->v); + return a; + } + + inline PolylineEdge *PolylineEdge::prevEdge() const { + if (edgenum) { + return parent->edge(edgenum - 1); + } else { + if (parent->closed) { + return parent->edge(parent->edgeCount() - 1); + } else { + return NULL; + } + } + } + + inline PolylineEdge *PolylineEdge::nextEdge() const { + if (edgenum + 1 < parent->edgeCount()) { + return parent->edge(edgenum + 1); + } else { + if (parent->closed) { + return parent->edge(0); + } else { + return NULL; + } + } + } + + + + inline Polyline::Polyline() : edges() { + } + + inline size_t Polyline::vertexCount() const { + return edgeCount() + (closed ? 0 : 1); + } + + inline size_t Polyline::edgeCount() const { + return edges.size(); + } + + inline const PolylineEdge *Polyline::edge(size_t e) const { + return edges[e % edges.size()]; + } + + inline PolylineEdge *Polyline::edge(size_t e) { + return edges[e % edges.size()]; + } + + inline const Vertex *Polyline::vertex(size_t v) const { + if (closed) { + v %= edgeCount(); + } else if (v >= edgeCount()) { + return v == edgeCount() ? edges.back()->v2 : NULL; + } + return edges[v]->v1; + } + + inline Vertex *Polyline::vertex(size_t v) { + if (closed) { + v %= edgeCount(); + } else if (v >= edgeCount()) { + return v == edgeCount() ? edges.back()->v2 : NULL; + } + return edges[v]->v1; + } + + inline bool Polyline::isClosed() const { + return closed; + } + + template + void Polyline::_init(bool c, iter_t begin, iter_t end, std::vector &vertices) { + closed = c; + + PolylineEdge *e; + if (begin == end) return; + size_t v1 = (int)*begin++; + if (begin == end) return; + + while (begin != end) { + size_t v2 = (int)*begin++; + e = new PolylineEdge(this, edges.size(), &vertices[v1], &vertices[v2]); + edges.push_back(e); + v1 = v2; + } + + if (closed) { + e = new PolylineEdge(this, edges.size(), edges.back()->v2, edges.front()->v1); + edges.push_back(e); + + edges.front()->v1->addEdgePair(edges.back(), edges.front()); + for (size_t i = 1; i < edges.size(); ++i) { + edges[i]->v1->addEdgePair(edges[i-1], edges[i]); + } + } else { + edges.front()->v1->addEdgePair(NULL, edges.front()); + for (size_t i = 1; i < edges.size(); ++i) { + edges[i]->v1->addEdgePair(edges[i-1], edges[i]); + } + edges.back()->v2->addEdgePair(edges.back(), NULL); + } + } + + template + void Polyline::_init(bool closed, iter_t begin, iter_t end, std::vector &vertices, std::forward_iterator_tag) { + _init(closed, begin, end, vertices); + } + + template + void Polyline::_init(bool closed, iter_t begin, iter_t end, std::vector &vertices, std::random_access_iterator_tag) { + edges.reserve(end - begin - (closed ? 0 : 1)); + _init(closed, begin, end, vertices); + } + + template + Polyline::Polyline(bool closed, iter_t begin, iter_t end, std::vector &vertices) { + _init(closed, begin, end, vertices, typename std::iterator_traits::iterator_category()); + } + + + + template + void PolylineSet::addPolyline(bool closed, iter_t begin, iter_t end) { + Polyline *p = new Polyline(closed, begin, end, vertices); + lines.push_back(p); + } + + inline size_t PolylineSet::vertexToIndex_fast(const Vertex *v) const { + return v - &vertices[0]; + } + } +} diff -Nru blender-2.61/extern/carve/include/carve/polyline_iter.hpp blender-2.62/extern/carve/include/carve/polyline_iter.hpp --- blender-2.61/extern/carve/include/carve/polyline_iter.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/polyline_iter.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,199 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + +#pragma once + +#include +#include +#include +#include +#include + +#include + +namespace carve { + namespace line { + + struct polyline_vertex_iter : public std::iterator { + Polyline *base; + size_t idx; + + polyline_vertex_iter(Polyline *_base) : base(_base), idx(0) { + } + + polyline_vertex_iter(Polyline *_base, size_t _idx) : base(_base), idx(_idx) { + } + + polyline_vertex_iter operator++(int) { return polyline_vertex_iter(base, idx++); } + polyline_vertex_iter &operator++() { ++idx; return *this; } + polyline_vertex_iter &operator+=(int v) { idx += v; return *this; } + + polyline_vertex_iter operator--(int) { return polyline_vertex_iter(base, idx--); } + polyline_vertex_iter &operator--() { --idx; return *this; } + polyline_vertex_iter &operator-=(int v) { idx -= v; return *this; } + + Vertex *operator*() const { + return base->vertex(idx); + } + }; + + + + static inline ptrdiff_t operator-(const polyline_vertex_iter &a, const polyline_vertex_iter &b) { return a.idx - b.idx; } + + static inline bool operator==(const polyline_vertex_iter&a, const polyline_vertex_iter &b) { return a.idx == b.idx; } + static inline bool operator!=(const polyline_vertex_iter&a, const polyline_vertex_iter &b) { return a.idx != b.idx; } + static inline bool operator<(const polyline_vertex_iter&a, const polyline_vertex_iter &b) { return a.idx < b.idx; } + static inline bool operator>(const polyline_vertex_iter&a, const polyline_vertex_iter &b) { return a.idx > b.idx; } + static inline bool operator<=(const polyline_vertex_iter&a, const polyline_vertex_iter &b) { return a.idx <= b.idx; } + static inline bool operator>=(const polyline_vertex_iter&a, const polyline_vertex_iter &b) { return a.idx >= b.idx; } + + + + struct polyline_vertex_const_iter : public std::iterator { + const Polyline *base; + size_t idx; + + polyline_vertex_const_iter(const Polyline *_base) : base(_base), idx(0) { + } + + polyline_vertex_const_iter(const Polyline *_base, size_t _idx) : base(_base), idx(_idx) { + } + + polyline_vertex_const_iter operator++(int) { return polyline_vertex_const_iter(base, idx++); } + polyline_vertex_const_iter &operator++() { ++idx; return *this; } + polyline_vertex_const_iter &operator+=(int v) { idx += v; return *this; } + + polyline_vertex_const_iter operator--(int) { return polyline_vertex_const_iter(base, idx--); } + polyline_vertex_const_iter &operator--() { --idx; return *this; } + polyline_vertex_const_iter &operator-=(int v) { idx -= v; return *this; } + + const Vertex *operator*() const { + return base->vertex(idx); + } + }; + + + + static inline ptrdiff_t operator-(const polyline_vertex_const_iter &a, const polyline_vertex_const_iter &b) { return a.idx - b.idx; } + + static inline bool operator==(const polyline_vertex_const_iter&a, const polyline_vertex_const_iter &b) { return a.idx == b.idx; } + static inline bool operator!=(const polyline_vertex_const_iter&a, const polyline_vertex_const_iter &b) { return a.idx != b.idx; } + static inline bool operator<(const polyline_vertex_const_iter&a, const polyline_vertex_const_iter &b) { return a.idx < b.idx; } + static inline bool operator>(const polyline_vertex_const_iter&a, const polyline_vertex_const_iter &b) { return a.idx > b.idx; } + static inline bool operator<=(const polyline_vertex_const_iter&a, const polyline_vertex_const_iter &b) { return a.idx <= b.idx; } + static inline bool operator>=(const polyline_vertex_const_iter&a, const polyline_vertex_const_iter &b) { return a.idx >= b.idx; } + + inline polyline_vertex_const_iter Polyline::vbegin() const { + return polyline_vertex_const_iter(this, 0); + } + inline polyline_vertex_const_iter Polyline::vend() const { + return polyline_vertex_const_iter(this, vertexCount()); + } + inline polyline_vertex_iter Polyline::vbegin() { + return polyline_vertex_iter(this, 0); + } + inline polyline_vertex_iter Polyline::vend() { + return polyline_vertex_iter(this, vertexCount()); + } + + + + struct polyline_edge_iter : public std::iterator { + Polyline *base; + size_t idx; + + polyline_edge_iter(Polyline *_base) : base(_base), idx(0) { + } + + polyline_edge_iter(Polyline *_base, size_t _idx) : base(_base), idx(_idx) { + } + + polyline_edge_iter operator++(int) { return polyline_edge_iter(base, idx++); } + polyline_edge_iter &operator++() { ++idx; return *this; } + polyline_edge_iter &operator+=(int v) { idx += v; return *this; } + + polyline_edge_iter operator--(int) { return polyline_edge_iter(base, idx--); } + polyline_edge_iter &operator--() { --idx; return *this; } + polyline_edge_iter &operator-=(int v) { idx -= v; return *this; } + + PolylineEdge *operator*() const { + return base->edge(idx); + } + }; + + + + static inline int operator-(const polyline_edge_iter&a, const polyline_edge_iter &b) { return a.idx - b.idx; } + + static inline bool operator==(const polyline_edge_iter&a, const polyline_edge_iter &b) { return a.idx == b.idx; } + static inline bool operator!=(const polyline_edge_iter&a, const polyline_edge_iter &b) { return a.idx != b.idx; } + static inline bool operator<(const polyline_edge_iter&a, const polyline_edge_iter &b) { return a.idx < b.idx; } + static inline bool operator>(const polyline_edge_iter&a, const polyline_edge_iter &b) { return a.idx > b.idx; } + static inline bool operator<=(const polyline_edge_iter&a, const polyline_edge_iter &b) { return a.idx <= b.idx; } + static inline bool operator>=(const polyline_edge_iter&a, const polyline_edge_iter &b) { return a.idx >= b.idx; } + + + + struct polyline_edge_const_iter : public std::iterator { + const Polyline *base; + size_t idx; + + polyline_edge_const_iter(const Polyline *_base) : base(_base), idx(0) { + } + + polyline_edge_const_iter(const Polyline *_base, size_t _idx) : base(_base), idx(_idx) { + } + + polyline_edge_const_iter operator++(int) { return polyline_edge_const_iter(base, idx++); } + polyline_edge_const_iter &operator++() { ++idx; return *this; } + polyline_edge_const_iter &operator+=(int v) { idx += v; return *this; } + + polyline_edge_const_iter operator--(int) { return polyline_edge_const_iter(base, idx--); } + polyline_edge_const_iter &operator--() { --idx; return *this; } + polyline_edge_const_iter &operator-=(int v) { idx -= v; return *this; } + + const PolylineEdge *operator*() const { + return base->edge(idx); + } + }; + + + + static inline int operator-(const polyline_edge_const_iter&a, const polyline_edge_const_iter &b) { return a.idx - b.idx; } + + static inline bool operator==(const polyline_edge_const_iter&a, const polyline_edge_const_iter &b) { return a.idx == b.idx; } + static inline bool operator!=(const polyline_edge_const_iter&a, const polyline_edge_const_iter &b) { return a.idx != b.idx; } + static inline bool operator<(const polyline_edge_const_iter&a, const polyline_edge_const_iter &b) { return a.idx < b.idx; } + static inline bool operator>(const polyline_edge_const_iter&a, const polyline_edge_const_iter &b) { return a.idx > b.idx; } + static inline bool operator<=(const polyline_edge_const_iter&a, const polyline_edge_const_iter &b) { return a.idx <= b.idx; } + static inline bool operator>=(const polyline_edge_const_iter&a, const polyline_edge_const_iter &b) { return a.idx >= b.idx; } + + inline polyline_edge_const_iter Polyline::ebegin() const { + return polyline_edge_const_iter(this, 0); + } + inline polyline_edge_const_iter Polyline::eend() const { + return polyline_edge_const_iter(this, edgeCount()); + } + inline polyline_edge_iter Polyline::ebegin() { + return polyline_edge_iter(this, 0); + } + inline polyline_edge_iter Polyline::eend() { + return polyline_edge_iter(this, edgeCount()); + } + + } +} diff -Nru blender-2.61/extern/carve/include/carve/rescale.hpp blender-2.62/extern/carve/include/carve/rescale.hpp --- blender-2.61/extern/carve/include/carve/rescale.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/rescale.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,100 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +#include +#include +#include + +#include + +namespace carve { + namespace rescale { + + template + T calc_scale(T max) { + const int radix = std::numeric_limits::radix; + + T div = T(1); + T m = fabs(max); + while (div < m) div *= radix; + m *= radix; + while (div > m) div /= radix; + return div; + } + + template + T calc_delta(T min, T max) { + const int radix = std::numeric_limits::radix; + + if (min >= T(0) || max <= T(0)) { + bool neg = false; + if (max <= T(0)) { + min = -min; + max = -max; + std::swap(min, max); + neg = true; + } + T t = T(1); + while (t > max) t /= radix; + while (t <= max/radix) t *= radix; + volatile T temp = t + min; + temp -= t; + if (neg) temp = -temp; + return temp; + } else { + return T(0); + } + } + + struct rescale { + double dx, dy, dz, scale; + + void init(double minx, double miny, double minz, double maxx, double maxy, double maxz) { + dx = calc_delta(minx, maxx); minx -= dx; maxx -= dx; + dy = calc_delta(miny, maxy); miny -= dy; maxy -= dy; + dz = calc_delta(minz, maxz); minz -= dz; maxz -= dz; + scale = calc_scale(std::max(std::max(fabs(minz), fabs(maxz)), + std::max(std::max(fabs(minx), fabs(maxx)), + std::max(fabs(miny), fabs(maxy))))); + } + + rescale(double minx, double miny, double minz, double maxx, double maxy, double maxz) { + init(minx, miny, minz, maxx, maxy, maxz); + } + rescale(const carve::geom3d::Vector &min, const carve::geom3d::Vector &max) { + init(min.x, min.y, min.z, max.x, max.y, max.z); + } + }; + + struct fwd { + rescale r; + fwd(const rescale &_r) : r(_r) { } + carve::geom3d::Vector operator()(const carve::geom3d::Vector &v) const { return carve::geom::VECTOR((v.x - r.dx) / r.scale, (v.y - r.dy) / r.scale, (v.z - r.dz) / r.scale); } + }; + + struct rev { + rescale r; + rev(const rescale &_r) : r(_r) { } + carve::geom3d::Vector operator()(const carve::geom3d::Vector &v) const { return carve::geom::VECTOR((v.x * r.scale) + r.dx, (v.y * r.scale) + r.dy, (v.z * r.scale) + r.dz); } + }; + + } +} diff -Nru blender-2.61/extern/carve/include/carve/rtree.hpp blender-2.62/extern/carve/include/carve/rtree.hpp --- blender-2.61/extern/carve/include/carve/rtree.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/rtree.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,501 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +#include +#include + +#include + +#include +#include + +#if defined(HAVE_STDINT_H) +# include +#endif + +namespace carve { + namespace geom { + + template > + struct RTreeNode { + typedef aabb aabb_t; + typedef vector vector_t; + typedef RTreeNode node_t; + + aabb_t bbox; + node_t *child; + node_t *sibling; + std::vector data; + + aabb_t getAABB() const { return bbox; } + + + + struct data_aabb_t { + aabb_t bbox; + data_t data; + + data_aabb_t() { } + data_aabb_t(const data_t &_data) : bbox(aabb_calc_t()(_data)), data(_data) { + } + + aabb_t getAABB() const { return bbox; } + + struct cmp { + size_t dim; + cmp(size_t _dim) : dim(_dim) { } + bool operator()(const data_aabb_t &a, const data_aabb_t &b) { + return a.bbox.pos.v[dim] < b.bbox.pos.v[dim]; + } + }; + }; + + // Fill an rtree node with a set of (data, aabb) pairs. + template + void _fill(iter_t begin, iter_t end, data_aabb_t) { + data.reserve(std::distance(begin, end)); + for (iter_t i = begin; i != end; ++i) { + data.push_back((*i).data); + } + bbox.fit(begin, end); + } + + // Fill an rtree node with a set of data. + template + void _fill(iter_t begin, iter_t end, data_t) { + data.reserve(std::distance(begin, end)); + std::copy(begin, end, std::back_inserter(data)); + bbox.fit(begin, end, aabb_calc_t()); + } + + // Fill an rtree node with a set of child nodes. + template + void _fill(iter_t begin, iter_t end, node_t *) { + iter_t i = begin; + node_t *curr = child = *i; + while (++i != end) { + curr->sibling = *i; + curr = curr->sibling; + } + bbox.fit(begin, end); + } + + // Search the rtree for objects that intersect obj (generally an aabb). + // The aabb class must provide a method intersects(obj_t). + template + void search(const obj_t &obj, out_iter_t out) const { + if (!bbox.intersects(obj)) return; + if (child) { + for (node_t *node = child; node; node = node->sibling) { + node->search(obj, out); + } + } else { + std::copy(data.begin(), data.end(), out); + } + } + + // update the bounding box extents of nodes that intersect obj (generally an aabb). + // The aabb class must provide a method intersects(obj_t). + template + void updateExtents(const obj_t &obj) { + if (!bbox.intersects(obj)) return; + + if (child) { + node_t *node = child; + node->updateExtents(obj); + bbox = node->bbox; + for (node = node->sibling; node; node = node->sibling) { + node->updateExtents(obj); + bbox.unionAABB(node->bbox); + } + } else { + bbox.fit(data.begin(), data.end()); + } + } + + // update the bounding box extents of nodes that intersect obj (generally an aabb). + // The aabb class must provide a method intersects(obj_t). + bool remove(const data_t &val, const aabb_t &val_aabb) { + if (!bbox.intersects(val_aabb)) return false; + + if (child) { + node_t *node = child; + node->remove(val, val_aabb); + bbox = node->bbox; + bool removed = false; + for (node = node->sibling; node; node = node->sibling) { + if (!removed) removed = node->remove(val, val_aabb); + bbox.unionAABB(node->bbox); + } + return removed; + } else { + typename std::vector::iterator i = std::remove(data.begin(), data.end(), val); + if (i == data.end()) { + return false; + } + data.erase(i, data.end()); + bbox.fit(data.begin(), data.end()); + return true; + } + } + + template + RTreeNode(iter_t begin, iter_t end) : bbox(), child(NULL), sibling(NULL), data() { + _fill(begin, end, typename std::iterator_traits::value_type()); + } + + + + // functor for ordering nodes by increasing aabb midpoint, along a specified axis. + struct aabb_cmp_mid { + size_t dim; + aabb_cmp_mid(size_t _dim) : dim(_dim) { } + + bool operator()(const node_t *a, const node_t *b) { + return a->bbox.mid(dim) < b->bbox.mid(dim); + } + bool operator()(const data_aabb_t &a, const data_aabb_t &b) { + return a.bbox.mid(dim) < b.bbox.mid(dim); + } + }; + + // functor for ordering nodes by increasing aabb minimum, along a specified axis. + struct aabb_cmp_min { + size_t dim; + aabb_cmp_min(size_t _dim) : dim(_dim) { } + + bool operator()(const node_t *a, const node_t *b) { + return a->bbox.min(dim) < b->bbox.min(dim); + } + bool operator()(const data_aabb_t &a, const data_aabb_t &b) { + return a.bbox.min(dim) < b.bbox.min(dim); + } + }; + + // functor for ordering nodes by increasing aabb maximum, along a specified axis. + struct aabb_cmp_max { + size_t dim; + aabb_cmp_max(size_t _dim) : dim(_dim) { } + + bool operator()(const node_t *a, const node_t *b) { + return a->bbox.max(dim) < b->bbox.max(dim); + } + bool operator()(const data_aabb_t &a, const data_aabb_t &b) { + return a.bbox.max(dim) < b.bbox.max(dim); + } + }; + + // facade for projecting node bounding box onto an axis. + struct aabb_extent { + size_t dim; + aabb_extent(size_t _dim) : dim(_dim) { } + + double min(const node_t *a) { return a->bbox.pos.v[dim] - a->bbox.extent.v[dim]; } + double max(const node_t *a) { return a->bbox.pos.v[dim] + a->bbox.extent.v[dim]; } + double len(const node_t *a) { return 2.0 * a->bbox.extent.v[dim]; } + double min(const data_aabb_t &a) { return a.bbox.pos.v[dim] - a.bbox.extent.v[dim]; } + double max(const data_aabb_t &a) { return a.bbox.pos.v[dim] + a.bbox.extent.v[dim]; } + double len(const data_aabb_t &a) { return 2.0 * a.bbox.extent.v[dim]; } + }; + + template + static void makeNodes(const iter_t begin, + const iter_t end, + size_t dim_num, + uint32_t dim_mask, + size_t child_size, + std::vector &out) { + const size_t N = std::distance(begin, end); + + size_t dim = ndim; + double r_best = N+1; + + // find the sparsest remaining dimension to partition by. + for (size_t i = 0; i < ndim; ++i) { + if (dim_mask & (1U << i)) continue; + aabb_extent extent(i); + double dmin, dmax, dsum; + + dmin = extent.min(*begin); + dmax = extent.max(*begin); + dsum = 0.0; + for (iter_t j = begin; j != end; ++j) { + dmin = std::min(dmin, extent.min(*j)); + dmax = std::max(dmax, extent.max(*j)); + dsum += extent.len(*j); + } + double r = dsum ? dsum / (dmax - dmin) : 0.0; + if (r_best > r) { + dim = i; + r_best = r; + } + } + + CARVE_ASSERT(dim < ndim); + + // dim = dim_num; + + const size_t P = (N + child_size - 1) / child_size; + const size_t n_parts = (size_t)std::ceil(std::pow((double)P, 1.0 / (ndim - dim_num))); + + std::sort(begin, end, aabb_cmp_mid(dim)); + + if (dim_num == ndim - 1 || n_parts == 1) { + for (size_t i = 0, s = 0, e = 0; i < P; ++i, s = e) { + e = N * (i+1) / P; + CARVE_ASSERT(e - s <= child_size); + out.push_back(new node_t(begin + s, begin + e)); + } + } else { + for (size_t i = 0, s = 0, e = 0; i < n_parts; ++i, s = e) { + e = N * (i+1) / n_parts; + makeNodes(begin + s, begin + e, dim_num + 1, dim_mask | (1U << dim), child_size, out); + } + } + } + + static node_t *construct_STR(std::vector &data, size_t leaf_size, size_t internal_size) { + std::vector out; + makeNodes(data.begin(), data.end(), 0, 0, leaf_size, out); + + while (out.size() > 1) { + std::vector next; + makeNodes(out.begin(), out.end(), 0, 0, internal_size, next); + std::swap(out, next); + } + + CARVE_ASSERT(out.size() == 1); + return out[0]; + } + + template + static node_t *construct_STR(const iter_t &begin, + const iter_t &end, + size_t leaf_size, + size_t internal_size) { + std::vector data; + data.reserve(std::distance(begin, end)); + for (iter_t i = begin; i != end; ++i) { + data.push_back(*i); + } + return construct_STR(data, leaf_size, internal_size); + } + + + template + static node_t *construct_STR(const iter_t &begin1, + const iter_t &end1, + const iter_t &begin2, + const iter_t &end2, + size_t leaf_size, + size_t internal_size) { + std::vector data; + data.reserve(std::distance(begin1, end1) + std::distance(begin2, end2)); + for (iter_t i = begin1; i != end1; ++i) { + data.push_back(*i); + } + for (iter_t i = begin2; i != end2; ++i) { + data.push_back(*i); + } + return construct_STR(data, leaf_size, internal_size); + } + + + struct partition_info { + double score; + size_t partition_pos; + + partition_info() : score(std::numeric_limits::max()), partition_pos(0) { + } + partition_info(double _score, size_t _partition_pos) : + score(_score), + partition_pos(_partition_pos) { + } + }; + + static partition_info findPartition(typename std::vector::iterator base, + std::vector::iterator begin, + std::vector::iterator end, + size_t part_size) { + partition_info best(std::numeric_limits::max(), 0); + const size_t N = std::distance(begin, end); + + std::vector rhs_vol(N, 0.0); + + aabb_t rhs = base[begin[N-1]].aabb; + rhs_vol[N-1] = rhs.volume(); + for (size_t i = N - 1; i > 0; ) { + rhs.unionAABB(base[begin[--i]].aabb); + rhs_vol[i] = rhs.volume(); + } + + aabb_t lhs = base[begin[0]].aabb; + for (size_t i = 1; i < N; ++i) { + lhs.unionAABB(base[begin[i]].aabb); + if (i % part_size == 0 || (N - i) % part_size == 0) { + partition_info curr(lhs.volume() + rhs_vol[i], i); + if (best.score > curr.score) best = curr; + } + } + return best; + } + + static void partition(typename std::vector::iterator base, + std::vector::iterator begin, + std::vector::iterator end, + size_t part_size, + std::vector &part_num, + size_t &part_next) { + const size_t N = std::distance(begin, end); + + partition_info best; + partition_info curr; + size_t part_curr = part_num[*begin]; + + std::vector tmp(begin, end); + + for (size_t dim = 0; dim < ndim; ++dim) { + std::sort(tmp.begin(), tmp.end(), make_index_sort(base, aabb_cmp_min(dim))); + curr = findPartition(base, tmp.begin(), tmp.end(), part_size); + if (best.score > curr.score) { + best = curr; + std::copy(tmp.begin(), tmp.end(), begin); + } + + std::sort(tmp.begin(), tmp.end(), make_index_sort(base, aabb_cmp_mid(dim))); + curr = findPartition(base, tmp.begin(), tmp.end(), part_size); + if (best.score > curr.score) { + best = curr; + std::copy(tmp.begin(), tmp.end(), begin); + } + + std::sort(tmp.begin(), tmp.end(), make_index_sort(base, aabb_cmp_max(dim))); + curr = findPartition(base, tmp.begin(), tmp.end(), part_size); + if (best.score > curr.score) { + best = curr; + std::copy(tmp.begin(), tmp.end(), begin); + } + } + + for (size_t j = 0; j < best.partition_pos; ++j) part_num[begin[j]] = part_curr; + for (size_t j = best.partition_pos; j < N; ++j) part_num[begin[j]] = part_next; + ++part_next; + + if (best.partition_pos > part_size) { + partition(base, begin, begin + best.partition_pos, part_size, part_num, part_next); + } + if (N - best.partition_pos > part_size) { + partition(base, begin + best.partition_pos, end, part_size, part_num, part_next); + } + } + + static size_t makePartitions(typename std::vector::iterator begin, + typename std::vector::iterator end, + size_t part_size, + std::vector &part_num) { + const size_t N = std::distance(begin, end); + std::vector idx; + idx.reserve(N); + for (size_t i = 0; i < N; ++i) { idx.push_back(i); } + size_t part_next = 1; + + partition(begin, idx.begin(), idx.end(), part_size, part_num, part_next); + return part_next; + } + + static node_t *construct_TGS(typename std::vector::iterator begin, + typename std::vector::iterator end, + size_t leaf_size, + size_t internal_size) { + size_t N = std::distance(begin, end); + + if (N <= leaf_size) { + return new node_t(begin, end); + } else { + size_t P = (N + internal_size - 1) / internal_size; + std::vector part_num(N, 0); + P = makePartitions(begin, end, P, part_num); + + size_t S = 0, E = 0; + std::vector children; + for (size_t i = 0; i < P; ++i) { + size_t j = S, k = N; + while (true) { + while (true) { + if (j == k) goto done; + else if (part_num[j] == i) ++j; + else break; + } + --k; + while (true) { + if (j == k) goto done; + else if (part_num[k] != i) --k; + else break; + } + std::swap(*(begin+j), *(begin+k)); + std::swap(part_num[j], part_num[k]); + ++j; + } + done: + E = j; + children.push_back(construct_TGS(begin + S, begin + E, leaf_size, internal_size)); + S = E; + } + return new node_t(children.begin(), children.end()); + } + } + + template + static node_t *construct_TGS(const iter_t &begin, + const iter_t &end, + size_t leaf_size, + size_t internal_size) { + std::vector data; + data.reserve(std::distance(begin, end)); + for (iter_t i = begin; i != end; ++i) { + data.push_back(*i); + } + return construct_TGS(data.begin(), data.end(), leaf_size, internal_size); + } + + template + static node_t *construct_TGS(const iter_t &begin1, + const iter_t &end1, + const iter_t &begin2, + const iter_t &end2, + size_t leaf_size, + size_t internal_size) { + std::vector data; + data.reserve(std::distance(begin1, end1) + std::distance(begin2, end2)); + for (iter_t i = begin1; i != end1; ++i) { + data.push_back(*i); + } + for (iter_t i = begin2; i != end2; ++i) { + data.push_back(*i); + } + return construct_TGS(data.begin(), data.end(), leaf_size, internal_size); + } + }; + + } +} diff -Nru blender-2.61/extern/carve/include/carve/spacetree.hpp blender-2.62/extern/carve/include/carve/spacetree.hpp --- blender-2.61/extern/carve/include/carve/spacetree.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/spacetree.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,264 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +#include +#include +#include +#include +#include + +namespace carve { + + namespace space { + + static inline bool intersection_test(const carve::geom::aabb<3> &aabb, const carve::poly::Face<3> *face) { + if (face->nVertices() == 3) { + return aabb.intersects(carve::geom::tri<3>(face->vertex(0)->v, face->vertex(1)->v, face->vertex(2)->v)); + } else { + // partial, conservative SAT. + return aabb.intersects(face->aabb) && aabb.intersects(face->plane_eqn); + } + } + + static inline bool intersection_test(const carve::geom::aabb<3> &aabb, const carve::poly::Edge<3> *edge) { + return aabb.intersectsLineSegment(edge->v1->v, edge->v2->v); + } + + static inline bool intersection_test(const carve::geom::aabb<3> &aabb, const carve::poly::Vertex<3> *vertex) { + return aabb.intersects(vertex->v); + } + + + + struct nodedata_FaceEdge { + std::vector *> faces; + std::vector *> edges; + + void add(const carve::poly::Face<3> *face) { + faces.push_back(face); + } + + void add(const carve::poly::Edge<3> *edge) { + edges.push_back(edge); + } + + template + void _fetch(iter_t &iter, const carve::poly::Edge<3> *) { + std::copy(edges.begin(), edges.end(), iter); + } + + template + void _fetch(iter_t &iter, const carve::poly::Face<3> *) { + std::copy(faces.begin(), faces.end(), iter); + } + + template + void propagate(node_t *node) { + } + + template + void fetch(iter_t &iter) { + return _fetch(iter, std::iterator_traits::value_type); + } + }; + + + + const static double SLACK_FACTOR = 1.0009765625; + const static unsigned MAX_SPLIT_DEPTH = 32; + + + + template + class SpatialSubdivTree { + + typedef carve::geom::aabb aabb_t; + typedef carve::geom::vector vector_t; + + public: + + class Node { + enum { + n_children = 1 << n_dim + }; + + public: + Node *parent; + Node *children; + + vector_t min; + vector_t max; + + aabb_t aabb; + + nodedata_t data; + + private: + Node(const Node &node); // undefined. + Node &operator=(const Node &node); // undefined. + + Node() { + } + + inline aabb_t makeAABB() const { + vector_t centre = 0.5 * (min + max); + vector_t size = SLACK_FACTOR * 0.5 * (max - min); + return aabb_t(centre, size); + } + + void setup(Node *_parent, const vector_t &_min, const vector_t &_max) { + parent = _parent; + min = _min; + max = _max; + aabb = makeAABB(); + } + + void alloc_children() { + vector_t mid = 0.5 * (min + max); + children = new Node[n_children]; + for (size_t i = 0; i < (n_children); ++i) { + vector_t new_min, new_max; + for (size_t c = 0; c < n_dim; ++c) { + if (i & (1 << c)) { + new_min.v[c] = min.v[c]; + new_max.v[c] = mid.v[c]; + } else { + new_min.v[c] = mid.v[c]; + new_max.v[c] = max.v[c]; + } + } + children[i].setup(this, new_min, new_max); + } + } + + void dealloc_children() { + delete [] children; + } + + public: + + inline bool isLeaf() const { return children == NULL; } + + Node(Node *_parent, const vector_t &_min, const vector_t &_max) : parent(_parent), children(NULL), min(_min), max(_max) { + aabb = makeAABB(); + } + + ~Node() { + dealloc_children(); + } + + bool split() { + if (isLeaf()) { + alloc_children(); + data.propagate(this); + } + return isLeaf(); + } + + template + void insert(const obj_t &object) { + if (!isLeaf()) { + for (size_t i = 0; i < n_children; ++i) { + if (intersection_test(children[i].aabb, object)) { + children[i].insert(object); + } + } + } else { + data.add(object); + } + } + + template + void insertVector(typename std::vector::iterator beg, typename std::vector::iterator end) { + if (isLeaf()) { + while (beg != end) { + data.add(*beg); + } + } else { + for (size_t i = 0; i < n_children; ++i) { + typename std::vector::iterator mid = std::partition(beg, end, std::bind1st(intersection_test, children[i].aabb)); + children[i].insertVector(beg, mid); + } + } + } + + template + void insertMany(iter_t begin, iter_t end) { + if (isLeaf()) { + } + } + + template + void findObjectsNear(const obj_t &object, iter_t &output, filter_t filter) { + if (!isLeaf()) { + for (size_t i = 0; i < n_children; ++i) { + if (intersection_test(children[i].aabb, object)) { + children[i].findObjectsNear(object, output, filter); + } + } + return; + } + data.fetch(output); + } + + // bool hasGeometry(); + + // template + // void putInside(const T &input, Node *child, T &output); + + }; + + + + Node *root; + + SpatialSubdivTree(const vector_t &_min, const vector_t &_max) : root(new Node(NULL, _min, _max)) { + } + + ~SpatialSubdivTree() { + delete root; + } + + struct no_filter { + template + bool operator()(const obj_t &obj) const { + return true; + } + }; + + struct tag_filter { + template + bool operator()(const obj_t &obj) const { + return obj.tag_once(); + } + }; + + // in order to be used as an input, aabb_t::intersect(const obj_t &) must exist. + template + void findObjectsNear(const obj_t &object, iter_t output, filter_t filter) { + if (!intersection_test(root->aabb, object)) return; + root->findObjectsNear(root, object, output, filter); + } + + }; + + } +} diff -Nru blender-2.61/extern/carve/include/carve/tag.hpp blender-2.62/extern/carve/include/carve/tag.hpp --- blender-2.61/extern/carve/include/carve/tag.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/tag.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,44 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +namespace carve { + + class tagable { + private: + static int s_count; + + protected: + mutable int __tag; + + public: + tagable(const tagable &) : __tag(s_count - 1) { } + tagable &operator=(const tagable &) { return *this; } + + tagable() : __tag(s_count - 1) { } + + void tag() const { __tag = s_count; } + void untag() const { __tag = s_count - 1; } + bool is_tagged() const { return __tag == s_count; } + bool tag_once() const { if (__tag == s_count) return false; __tag = s_count; return true; } + + static void tag_begin() { s_count++; } + }; +} diff -Nru blender-2.61/extern/carve/include/carve/timing.hpp blender-2.62/extern/carve/include/carve/timing.hpp --- blender-2.61/extern/carve/include/carve/timing.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/timing.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,96 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +#ifndef CARVE_USE_TIMINGS +#define CARVE_USE_TIMINGS 0 +#endif + +namespace carve { + +#if CARVE_USE_TIMINGS + + class TimingName { + public: + TimingName(const char *name); + int id; + }; + + class TimingBlock { + public: + /** + * Starts timing at the end of this constructor, using the given ID. To + * associate an ID with a textual name, use Timing::registerID. + */ + TimingBlock(int id); + TimingBlock(const TimingName &name); + ~TimingBlock(); + }; + + class Timing { + public: + + /** + * Starts timing against a particular ID. + */ + static void start(int id); + + static void start(const TimingName &id) { + start(id.id); + } + + /** + * Stops the most recent timing block. + */ + static double stop(); + + /** + * This will print out the current state of recorded time blocks. It will + * display the tree of timings, as well as the summaries down the bottom. + */ + static void printTimings(); + + /** + * Associates a particular ID with a text string. This is used when + * printing out the timings. + */ + static void registerID(int id, const char *name); + + }; + +#else + + struct TimingName { + TimingName(const char *) {} + }; + struct TimingBlock { + TimingBlock(int /* id */) {} + TimingBlock(const TimingName & /* name */) {} + }; + struct Timing { + static void start(int /* id */) {} + static void start(const TimingName & /* id */) {} + static double stop() { return 0; } + static void printTimings() {} + static void registerID(int /* id */, const char * /* name */) {} + }; + +#endif +} diff -Nru blender-2.61/extern/carve/include/carve/tree.hpp blender-2.62/extern/carve/include/carve/tree.hpp --- blender-2.61/extern/carve/include/carve/tree.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/tree.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,324 @@ + +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +#include +#include +#include + +namespace carve { + namespace csg { + + class CSG_TreeNode { + CSG_TreeNode(const CSG_TreeNode &); + CSG_TreeNode &operator=(const CSG_TreeNode &); + + protected: + + public: + CSG_TreeNode() { + } + + virtual ~CSG_TreeNode() { + } + + virtual carve::mesh::MeshSet<3> *eval(bool &is_temp, CSG &csg) =0; + + virtual carve::mesh::MeshSet<3> *eval(CSG &csg) { + bool temp; + carve::mesh::MeshSet<3> *r = eval(temp, csg); + if (!temp) r = r->clone(); + return r; + } + }; + + + + class CSG_TransformNode : public CSG_TreeNode { + carve::math::Matrix transform; + CSG_TreeNode *child; + + public: + CSG_TransformNode(const carve::math::Matrix &_transform, CSG_TreeNode *_child) : transform(_transform), child(_child) { + } + virtual ~CSG_TransformNode() { + delete child; + } + + virtual carve::mesh::MeshSet<3> *eval(bool &is_temp, CSG &csg) { + carve::mesh::MeshSet<3> *result = child->eval(is_temp, csg); + if (!is_temp) { + result = result->clone(); + is_temp = true; + } + result->transform(carve::math::matrix_transformation(transform)); + return result; + } + }; + + + + + class CSG_InvertNode : public CSG_TreeNode { + std::vector selected_meshes; + CSG_TreeNode *child; + + public: + CSG_InvertNode(CSG_TreeNode *_child) : selected_meshes(), child(_child) { + } + CSG_InvertNode(int g_id, CSG_TreeNode *_child) : selected_meshes(), child(_child) { + selected_meshes.resize(g_id + 1, false); + selected_meshes[g_id] = true; + } + virtual ~CSG_InvertNode() { + delete child; + } + + template + CSG_InvertNode(T start, T end, CSG_TreeNode *_child) : selected_meshes(), child(_child) { + while (start != end) { + int g_id = (int)(*start); + if (selected_meshes.size() < g_id + 1) selected_meshes.resize(g_id + 1, false); + selected_meshes[g_id] = true; + ++start; + } + } + + virtual carve::mesh::MeshSet<3> *eval(bool &is_temp, CSG &csg) { + bool c_temp; + carve::mesh::MeshSet<3> *c = child->eval(c_temp, csg); + if (!c_temp) c = c->clone(); + if (!selected_meshes.size()) { + c->invert(); + } else { + for (size_t i = 0; i < c->meshes.size() && i < selected_meshes.size(); ++i) { + if (selected_meshes[i]) { + c->meshes[i]->invert(); + } + } + } + is_temp = true; + return c; + } + }; + + + + + class CSG_SelectNode : public CSG_TreeNode { + std::vector selected_meshes; + CSG_TreeNode *child; + + public: + CSG_SelectNode(int m_id, CSG_TreeNode *_child) : selected_meshes(), child(_child) { + selected_meshes.resize(m_id + 1, false); + selected_meshes[m_id] = true; + } + + template + CSG_SelectNode(T start, T end, CSG_TreeNode *_child) : selected_meshes(), child(_child) { + while (start != end) { + int m_id = (int)(*start); + if ((int)selected_meshes.size() < m_id + 1) selected_meshes.resize(m_id + 1, false); + selected_meshes[m_id] = true; + ++start; + } + } + + virtual ~CSG_SelectNode() { + delete child; + } + + virtual carve::mesh::MeshSet<3> *eval(bool &is_temp, CSG &csg) { + bool c_temp; + carve::mesh::MeshSet<3> *c = child->eval(c_temp, csg); + if (!c_temp) c = c->clone(); + size_t i = 0; + size_t j = 0; + for (size_t i = 0; i < c->meshes.size(); ++i) { + if (i >= selected_meshes.size() || !selected_meshes[i]) { + delete c->meshes[i]; + c->meshes[i] = NULL; + } else { + c->meshes[j++] = c->meshes[i]; + } + } + c->meshes.erase(c->meshes.begin() + j, c->meshes.end()); + c->collectVertices(); + is_temp = true; + return c; + } + }; + + + + + class CSG_PolyNode : public CSG_TreeNode { + carve::mesh::MeshSet<3> *poly; + bool del; + + public: + CSG_PolyNode(carve::mesh::MeshSet<3> *_poly, bool _del) : poly(_poly), del(_del) { + } + virtual ~CSG_PolyNode() { + static carve::TimingName FUNC_NAME("delete polyhedron"); + carve::TimingBlock block(FUNC_NAME); + + if (del) { + delete poly; + } + } + + virtual carve::mesh::MeshSet<3> *eval(bool &is_temp, CSG &csg) { + is_temp = false; + return poly; + } + }; + + + + class CSG_OPNode : public CSG_TreeNode { + CSG_TreeNode *left, *right; + CSG::OP op; + bool rescale; + CSG::CLASSIFY_TYPE classify_type; + + public: + CSG_OPNode(CSG_TreeNode *_left, + CSG_TreeNode *_right, + CSG::OP _op, + bool _rescale, + CSG::CLASSIFY_TYPE _classify_type = CSG::CLASSIFY_NORMAL) : left(_left), right(_right), op(_op), rescale(_rescale), classify_type(_classify_type) { + } + + virtual ~CSG_OPNode() { + delete left; + delete right; + } + + void minmax(double &min_x, double &min_y, double &min_z, + double &max_x, double &max_y, double &max_z, + const std::vector &points) { + for (unsigned i = 1; i < points.size(); ++i) { + min_x = std::min(min_x, points[i].x); + max_x = std::max(max_x, points[i].x); + min_y = std::min(min_y, points[i].y); + max_y = std::max(max_y, points[i].y); + min_z = std::min(min_z, points[i].z); + max_z = std::max(max_z, points[i].z); + } + } + + virtual carve::mesh::MeshSet<3> *evalScaled(bool &is_temp, CSG &csg) { + carve::mesh::MeshSet<3> *l, *r; + bool l_temp, r_temp; + + l = left->eval(l_temp, csg); + r = right->eval(r_temp, csg); + + if (!l_temp) { l = l->clone(); } + if (!r_temp) { r = r->clone(); } + + carve::geom3d::Vector min, max; + carve::geom3d::Vector min_l, max_l; + carve::geom3d::Vector min_r, max_r; + + carve::geom::bounds<3>(l->vertex_storage.begin(), + l->vertex_storage.end(), + carve::mesh::Face<3>::vector_mapping(), + min_l, + max_l); + carve::geom::bounds<3>(r->vertex_storage.begin(), + r->vertex_storage.end(), + carve::mesh::Face<3>::vector_mapping(), + min_r, + max_r); + + carve::geom::assign_op(min, min_l, min_r, carve::util::min_functor()); + carve::geom::assign_op(max, max_l, max_r, carve::util::max_functor()); + + carve::rescale::rescale scaler(min.x, min.y, min.z, max.x, max.y, max.z); + + carve::rescale::fwd fwd_r(scaler); + carve::rescale::rev rev_r(scaler); + + l->transform(fwd_r); + r->transform(fwd_r); + + carve::mesh::MeshSet<3> *result = NULL; + { + static carve::TimingName FUNC_NAME("csg.compute()"); + carve::TimingBlock block(FUNC_NAME); + result = csg.compute(l, r, op, NULL, classify_type); + } + + { + static carve::TimingName FUNC_NAME("delete polyhedron"); + carve::TimingBlock block(FUNC_NAME); + + delete l; + delete r; + } + + result->transform(rev_r); + + is_temp = true; + return result; + } + + virtual carve::mesh::MeshSet<3> *evalUnscaled(bool &is_temp, CSG &csg) { + carve::mesh::MeshSet<3> *l, *r; + bool l_temp, r_temp; + + l = left->eval(l_temp, csg); + r = right->eval(r_temp, csg); + + carve::mesh::MeshSet<3> *result = NULL; + { + static carve::TimingName FUNC_NAME("csg.compute()"); + carve::TimingBlock block(FUNC_NAME); + result = csg.compute(l, r, op, NULL, classify_type); + } + + { + static carve::TimingName FUNC_NAME("delete polyhedron"); + carve::TimingBlock block(FUNC_NAME); + + if (l_temp) delete l; + if (r_temp) delete r; + } + + is_temp = true; + return result; + } + + + virtual carve::mesh::MeshSet<3> *eval(bool &is_temp, CSG &csg) { + if (rescale) { + return evalScaled(is_temp, csg); + } else { + return evalUnscaled(is_temp, csg); + } + } + }; + + } +} diff -Nru blender-2.61/extern/carve/include/carve/triangulator.hpp blender-2.62/extern/carve/include/carve/triangulator.hpp --- blender-2.61/extern/carve/include/carve/triangulator.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/triangulator.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,175 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include +#include +#include + +#include + +#include + +namespace carve { + namespace triangulate { + + /** + * \brief Merge a set of holes into a polygon. (templated) + * + * Take a polygon loop and a collection of hole loops, and patch + * the hole loops into the polygon loop, returning a vector of + * vertices from the polygon and holes, which describes a new + * polygon boundary with no holes. The new polygon boundary is + * constructed via the addition of edges * joining the polygon + * loop to the holes. + * + * This may be applied to arbitrary vertex data (generally + * carve::geom3d::Vertex pointers), but a projection function must + * be supplied to convert vertices to coordinates in 2-space, in + * which the work is performed. + * + * @tparam project_t A functor which converts vertices to a 2d + * projection. + * @tparam vert_t The vertex type. + * @param project The projection functor. + * @param f_loop The polygon loop into which holes are to be + * incorporated. + * @param h_loops The set of hole loops to be incorporated. + * + * @return A vector of vertex pointers. + */ + template + static std::vector + incorporateHolesIntoPolygon(const project_t &project, + const std::vector &f_loop, + const std::vector > &h_loops); + + void + incorporateHolesIntoPolygon(const std::vector > &poly, + std::vector > &result, + size_t poly_loop, + const std::vector &hole_loops); + + /** + * \brief Merge a set of holes into a polygon. (2d) + * + * Take a polygon loop and a collection of hole loops, and patch + * the hole loops into the polygon loop, returning a vector of + * containing the vertices from the polygon and holes which + * describes a new polygon boundary with no holes, through the + * addition of edges joining the polygon loop to the holes. + * + * @param poly A vector containing the face loop (the first + * element of poly) and the hole loops (second and + * subsequent elements of poly). + * + * @return A vector of pairs of that + * reference poly and define the result polygon loop. + */ + std::vector > incorporateHolesIntoPolygon(const std::vector > &poly); + + std::vector > > mergePolygonsAndHoles(const std::vector > &poly); + + + struct tri_idx { + union { + unsigned v[3]; + struct { unsigned a, b, c; }; + }; + + tri_idx() : a(0), b(0), c(0) { + } + tri_idx(unsigned _a, unsigned _b, unsigned _c) : a(_a), b(_b), c(_c) { + } + }; + + /** + * \brief Triangulate a 2-dimensional polygon. + * + * Given a 2-dimensional polygon described as a vector of 2-d + * points, with no holes and no self-crossings, produce a + * triangulation using an ear-clipping algorithm. + * + * @param [in] poly A vector containing the input polygon. + * @param [out] result A vector of triangles, represented as + * indicies into poly. + */ + + + void triangulate(const std::vector &poly, std::vector &result); + + /** + * \brief Triangulate a polygon (templated). + * + * @tparam project_t A functor which converts vertices to a 2d + * projection. + * @tparam vert_t The vertex type. + * @param [in] project The projection functor. + * @param [in] poly A vector containing the input polygon, + * represented as vert_t pointers. + * @param [out] result A vector of triangles, represented as + * indicies into poly. + */ + template + void triangulate(const project_t &project, + const std::vector &poly, + std::vector &result); + + /** + * \brief Improve a candidate triangulation of poly by minimising + * the length of internal edges. (templated) + * + * @tparam project_t A functor which converts vertices to a 2d + * projection. + * @tparam vert_t The vertex type. + * @param [in] project The projection functor. + * @param [in] poly A vector containing the input polygon, + * represented as vert_t pointers. + * @param [inout] result A vector of triangles, represented as + * indicies into poly. On input, this vector + * must contain a candidate triangulation of + * poly. Calling improve() modifies the + * contents of the vector, returning an + * improved triangulation. + */ + template + void improve(const project_t &project, + const std::vector &poly, + std::vector &result); + + /** + * \brief Improve a candidate triangulation of poly by minimising + * the length of internal edges. + * + * @param [in] poly A vector containing the input polygon. + + * @param [inout] result A vector of triangles, represented as + * indicies into poly. On input, this vector + * must contain a candidate triangulation of + * poly. Calling improve() modifies the + * contents of the vector, returning an + * improved triangulation. + */ + static inline void improve(const std::vector &poly, std::vector &result) { + improve(carve::geom2d::p2_adapt_ident(), poly, result); + } + + } +} + +#include diff -Nru blender-2.61/extern/carve/include/carve/triangulator_impl.hpp blender-2.62/extern/carve/include/carve/triangulator_impl.hpp --- blender-2.61/extern/carve/include/carve/triangulator_impl.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/triangulator_impl.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,851 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +#if defined(CARVE_DEBUG) +# include +#endif + +namespace carve { + namespace triangulate { + namespace detail { + + + + static inline bool axisOrdering(const carve::geom2d::P2 &a, + const carve::geom2d::P2 &b, + int axis) { + return a.v[axis] < b.v[axis] || (a.v[axis] == b.v[axis] && a.v[1-axis] < b.v[1-axis]); + } + + + + /** + * \class order_h_loops + * \brief Provides an ordering of hole loops based upon a single + * projected axis. + * + * @tparam project_t A functor which converts vertices to a 2d + * projection. + * @tparam hole_t A collection of vertices. + */ + template + class order_h_loops { + const project_t &project; + int axis; + public: + + /** + * + * @param _project The projection functor. + * @param _axis The axis of the 2d projection upon which hole + * loops are ordered. + */ + order_h_loops(const project_t &_project, int _axis) : project(_project), axis(_axis) { } + + bool operator()(const vert_t &a, + const vert_t &b) const { + return axisOrdering(project(a), project(b), axis); + } + + bool operator()( + const std::pair *, typename std::vector::const_iterator> &a, + const std::pair *, typename std::vector::const_iterator> &b) { + return axisOrdering(project(*(a.second)), project(*(b.second)), axis); + } + }; + + + + /** + * \class heap_ordering + * \brief Provides an ordering of vertex indicies in a polygon + * loop according to proximity to a vertex. + * + * @tparam project_t A functor which converts vertices to a 2d + * projection. + * @tparam vert_t A vertex type. + */ + template + class heap_ordering { + const project_t &project; + const std::vector &loop; + const carve::geom2d::P2 p; + int axis; + + public: + /** + * + * @param _project A functor which converts vertices to a 2d + * projection. + * @param _loop The polygon loop which indices address. + * @param _vert The vertex from which distance is measured. + * + */ + heap_ordering(const project_t &_project, + const std::vector &_loop, + vert_t _vert, + int _axis) : + project(_project), + loop(_loop), + p(_project(_vert)), + axis(_axis) { + } + + bool operator()(size_t a, size_t b) const { + carve::geom2d::P2 pa = project(loop[a]); + carve::geom2d::P2 pb = project(loop[b]); + double da = carve::geom::distance2(p, pa); + double db = carve::geom::distance2(p, pb); + if (da > db) return true; + if (da < db) return false; + return axisOrdering(pa, pb, axis); + } + }; + + + + /** + * \brief Given a polygon loop and a hole loop, and attachment + * points, insert the hole loop vertices into the polygon loop. + * + * @param[in,out] f_loop The polygon loop to incorporate the + * hole into. + * @param f_loop_attach[in] The index of the vertex of the + * polygon loop that the hole is to be + * attached to. + * @param hole_attach[in] A pair consisting of a pointer to a + * hole container and an iterator into + * that container reflecting the point of + * attachment of the hole. + */ + template + void patchHoleIntoPolygon(std::vector &f_loop, + unsigned f_loop_attach, + const std::pair *, + typename std::vector::const_iterator> &hole_attach) { + // join the vertex curr of the polygon loop to the hole at + // h_loop_connect + f_loop.insert(f_loop.begin() + f_loop_attach + 1, hole_attach.first->size() + 2, NULL); + typename std::vector::iterator f = f_loop.begin() + f_loop_attach; + + typename std::vector::const_iterator h = hole_attach.second; + + while (h != hole_attach.first->end()) { + *++f = *h++; + } + + h = hole_attach.first->begin(); + typename std::vector::const_iterator he = hole_attach.second; ++he; + while (h != he) { + *++f = *h++; + } + + *++f = f_loop[f_loop_attach]; + } + + + + struct vertex_info; + + + + /** + * \brief Determine whether c is to the left of a->b. + */ + static inline bool isLeft(const vertex_info *a, + const vertex_info *b, + const vertex_info *c); + + + + /** + * \brief Determine whether d is contained in the triangle abc. + */ + static inline bool pointInTriangle(const vertex_info *a, + const vertex_info *b, + const vertex_info *c, + const vertex_info *d); + + + + /** + * \class vertex_info + * \brief Maintains a linked list of untriangulated vertices + * during a triangulation operation. + */ + + struct vertex_info { + vertex_info *prev; + vertex_info *next; + carve::geom2d::P2 p; + size_t idx; + double score; + bool convex; + bool failed; + + vertex_info(const carve::geom2d::P2 &_p, size_t _idx) : + prev(NULL), next(NULL), + p(_p), idx(_idx), + score(0.0), convex(false) { + } + + static double triScore(const vertex_info *p, const vertex_info *v, const vertex_info *n); + + double calcScore() const; + + void recompute() { + score = calcScore(); + convex = isLeft(prev, this, next); + failed = false; + } + + bool isCandidate() const { + return convex && !failed; + } + + void remove() { + next->prev = prev; + prev->next = next; + } + + bool isClipable() const; + }; + + + + static inline bool isLeft(const vertex_info *a, + const vertex_info *b, + const vertex_info *c) { + if (a->idx < b->idx && b->idx < c->idx) { + return carve::geom2d::orient2d(a->p, b->p, c->p) > 0.0; + } else if (a->idx < c->idx && c->idx < b->idx) { + return carve::geom2d::orient2d(a->p, c->p, b->p) < 0.0; + } else if (b->idx < a->idx && a->idx < c->idx) { + return carve::geom2d::orient2d(b->p, a->p, c->p) < 0.0; + } else if (b->idx < c->idx && c->idx < a->idx) { + return carve::geom2d::orient2d(b->p, c->p, a->p) > 0.0; + } else if (c->idx < a->idx && a->idx < b->idx) { + return carve::geom2d::orient2d(c->p, a->p, b->p) > 0.0; + } else { + return carve::geom2d::orient2d(c->p, b->p, a->p) < 0.0; + } + } + + + + static inline bool pointInTriangle(const vertex_info *a, + const vertex_info *b, + const vertex_info *c, + const vertex_info *d) { + return !isLeft(a, c, d) && !isLeft(b, a, d) && !isLeft(c, b, d); + } + + + + size_t removeDegeneracies(vertex_info *&begin, std::vector &result); + + bool splitAndResume(vertex_info *begin, std::vector &result); + + bool doTriangulate(vertex_info *begin, std::vector &result); + + + + typedef std::pair vert_edge_t; + + + + struct hash_vert_edge_t { + size_t operator()(const vert_edge_t &e) const { + size_t r = (size_t)e.first; + size_t s = (size_t)e.second; + return r ^ ((s >> 16) | (s << 16)); + } + }; + + + + static inline vert_edge_t ordered_vert_edge_t(unsigned a, unsigned b) { + return (a < b) ? vert_edge_t(a, b) : vert_edge_t(b, a); + } + + + + struct tri_pair_t { + carve::triangulate::tri_idx *a, *b; + double score; + size_t idx; + + tri_pair_t() : a(NULL), b(NULL), score(0.0) { + } + + static inline unsigned N(unsigned i) { return (i+1)%3; } + static inline unsigned P(unsigned i) { return (i+2)%3; } + + void findSharedEdge(unsigned &ai, unsigned &bi) const { + if (a->v[1] == b->v[0]) { if (a->v[0] == b->v[1]) { ai = 0; bi = 0; } else { ai = 1; bi = 2; } return; } + if (a->v[1] == b->v[1]) { if (a->v[0] == b->v[2]) { ai = 0; bi = 1; } else { ai = 1; bi = 0; } return; } + if (a->v[1] == b->v[2]) { if (a->v[0] == b->v[0]) { ai = 0; bi = 2; } else { ai = 1; bi = 1; } return; } + if (a->v[2] == b->v[0]) { ai = 2; bi = 2; return; } + if (a->v[2] == b->v[1]) { ai = 2; bi = 0; return; } + if (a->v[2] == b->v[2]) { ai = 2; bi = 1; return; } + CARVE_FAIL("should not be reached"); + } + + void flip(vert_edge_t &old_edge, + vert_edge_t &new_edge, + vert_edge_t perim[4]); + + template + double calc(const project_t &project, + const std::vector &poly, + distance_calc_t dist) { + unsigned ai, bi; + unsigned cross_ai, cross_bi; + unsigned ea, eb; + + findSharedEdge(ai, bi); + +#if defined(CARVE_DEBUG) + if (carve::geom2d::signedArea(project(poly[a->v[0]]), project(poly[a->v[1]]), project(poly[a->v[2]])) > 0.0 || + carve::geom2d::signedArea(project(poly[b->v[0]]), project(poly[b->v[1]]), project(poly[b->v[2]])) > 0.0) { + std::cerr << "warning: triangle pair " << this << " contains triangles with incorrect orientation" << std::endl; + } +#endif + + cross_ai = P(ai); + cross_bi = P(bi); + + ea = a->v[cross_ai]; + eb = b->v[cross_bi]; + + double side_1 = carve::geom2d::orient2d(project(poly[ea]), project(poly[eb]), project(poly[a->v[ai]])); + double side_2 = carve::geom2d::orient2d(project(poly[ea]), project(poly[eb]), project(poly[a->v[N(ai)]])); + + bool can_flip = (side_1 < 0.0 && side_2 > 0.0) || (side_1 > 0.0 && side_2 < 0.0); + + if (!can_flip) { + score = -1; + } else { + score = + dist(poly[a->v[ai]], poly[b->v[bi]]) - + dist(poly[a->v[cross_ai]], poly[b->v[cross_bi]]); + } + return score; + } + + template + double edgeLen(const project_t &project, + const std::vector &poly, + distance_calc_t dist) const { + unsigned ai, bi; + findSharedEdge(ai, bi); + return dist(poly[a->v[ai]], poly[b->v[bi]]); + } + }; + + + + struct max_score { + bool operator()(const tri_pair_t *a, const tri_pair_t *b) const { return a->score < b->score; } + }; + + + + struct tri_pairs_t { + typedef std::unordered_map storage_t; + storage_t storage; + + tri_pairs_t() : storage() { + }; + + ~tri_pairs_t() { + for (storage_t::iterator i = storage.begin(); i != storage.end(); ++i) { + if ((*i).second) delete (*i).second; + } + } + + void insert(unsigned a, unsigned b, carve::triangulate::tri_idx *t); + + template + void updateEdge(tri_pair_t *tp, + const project_t &project, + const std::vector &poly, + distance_calc_t dist, + std::vector &edges, + size_t &n) { + double old_score = tp->score; + double new_score = tp->calc(project, poly, dist); +#if defined(CARVE_DEBUG) + std::cerr << "tp:" << tp << " old_score: " << old_score << " new_score: " << new_score << std::endl; +#endif + if (new_score > 0.0 && old_score <= 0.0) { + tp->idx = n; + edges[n++] = tp; + } else if (new_score <= 0.0 && old_score > 0.0) { + std::swap(edges[tp->idx], edges[--n]); + edges[tp->idx]->idx = tp->idx; + } + } + + tri_pair_t *get(vert_edge_t &e) { + storage_t::iterator i; + i = storage.find(e); + if (i == storage.end()) return NULL; + return (*i).second; + } + + template + void flip(const project_t &project, + const std::vector &poly, + distance_calc_t dist, + std::vector &edges, + size_t &n) { + vert_edge_t old_e, new_e; + vert_edge_t perim[4]; + +#if defined(CARVE_DEBUG) + std::cerr << "improvable edges: " << n << std::endl; +#endif + + tri_pair_t *tp = *std::max_element(edges.begin(), edges.begin() + n, max_score()); + +#if defined(CARVE_DEBUG) + std::cerr << "improving tri-pair: " << tp << " with score: " << tp->score << std::endl; +#endif + + tp->flip(old_e, new_e, perim); + +#if defined(CARVE_DEBUG) + std::cerr << "old_e: " << old_e.first << "," << old_e.second << " -> new_e: " << new_e.first << "," << new_e.second << std::endl; +#endif + + CARVE_ASSERT(storage.find(old_e) != storage.end()); + storage.erase(old_e); + storage[new_e] = tp; + + std::swap(edges[tp->idx], edges[--n]); + edges[tp->idx]->idx = tp->idx; + + tri_pair_t *tp2; + + tp2 = get(perim[0]); + if (tp2 != NULL) { + updateEdge(tp2, project, poly, dist, edges, n); + } + + tp2 = get(perim[1]); + if (tp2 != NULL) { + CARVE_ASSERT(tp2->a == tp->b || tp2->b == tp->b); + if (tp2->a == tp->b) { tp2->a = tp->a; } else { tp2->b = tp->a; } + updateEdge(tp2, project, poly, dist, edges, n); + } + + tp2 = get(perim[2]); + if (tp2 != NULL) { + updateEdge(tp2, project, poly, dist, edges, n); + } + + tp2 = get(perim[3]); + if (tp2 != NULL) { + CARVE_ASSERT(tp2->a == tp->a || tp2->b == tp->a); + if (tp2->a == tp->a) { tp2->a = tp->b; } else { tp2->b = tp->b; } + updateEdge(tp2, project, poly, dist, edges, n); + } + } + + template + size_t getInternalEdges(const project_t &project, + const std::vector &poly, + distance_calc_t dist, + std::vector &edges) { + size_t count = 0; + + for (storage_t::iterator i = storage.begin(); i != storage.end();) { + tri_pair_t *tp = (*i).second; + if (tp->a && tp->b) { + tp->calc(project, poly, dist); + count++; +#if defined(CARVE_DEBUG) + std::cerr << "internal edge: " << (*i).first.first << "," << (*i).first.second << " -> " << tp << " " << tp->score << std::endl; +#endif + ++i; + } else { + delete (*i).second; + storage.erase(i++); + } + } + + edges.resize(count); + + size_t fwd = 0; + size_t rev = count; + for (storage_t::iterator i = storage.begin(); i != storage.end(); ++i) { + tri_pair_t *tp = (*i).second; + if (tp && tp->a && tp->b) { + if (tp->score > 0.0) { + edges[fwd++] = tp; + } else { + edges[--rev] = tp; + } + } + } + + CARVE_ASSERT(fwd == rev); + + return fwd; + } + }; + + + + template + static bool + testCandidateAttachment(const project_t &project, + std::vector ¤t_f_loop, + size_t curr, + carve::geom2d::P2 hole_min) { + const size_t SZ = current_f_loop.size(); + + size_t prev, next; + + if (curr == 0) { + prev = SZ - 1; next = 1; + } else if (curr == SZ - 1) { + prev = curr - 1; next = 0; + } else { + prev = curr - 1; next = curr + 1; + } + + if (!carve::geom2d::internalToAngle(project(current_f_loop[next]), + project(current_f_loop[curr]), + project(current_f_loop[prev]), + hole_min)) { + return false; + } + + if (hole_min == project(current_f_loop[curr])) { + return true; + } + + carve::geom2d::LineSegment2 test(hole_min, project(current_f_loop[curr])); + + size_t v1 = current_f_loop.size() - 1; + size_t v2 = 0; + double v1_side = carve::geom2d::orient2d(test.v1, test.v2, project(current_f_loop[v1])); + double v2_side = 0; + + while (v2 != current_f_loop.size()) { + v2_side = carve::geom2d::orient2d(test.v1, test.v2, project(current_f_loop[v2])); + + if (v1_side != v2_side) { + // XXX: need to test vertices, not indices, because they may + // be duplicated. + if (project(current_f_loop[v1]) != project(current_f_loop[curr]) && + project(current_f_loop[v2]) != project(current_f_loop[curr])) { + carve::geom2d::LineSegment2 test2(project(current_f_loop[v1]), project(current_f_loop[v2])); + if (carve::geom2d::lineSegmentIntersection_simple(test, test2)) { + // intersection; failed. + return false; + } + } + } + + v1 = v2; + v1_side = v2_side; + ++v2; + } + return true; + } + + + + } + + + + template + static std::vector + incorporateHolesIntoPolygon(const project_t &project, + const std::vector &f_loop, + const std::vector > &h_loops) { + typedef std::vector hole_t; + typedef typename std::vector::const_iterator vert_iter; + typedef typename std::vector >::const_iterator hole_iter; + + size_t N = f_loop.size(); + + // work out how much space to reserve for the patched in holes. + for (hole_iter i = h_loops.begin(); i != h_loops.end(); ++i) { + N += 2 + (*i).size(); + } + + // this is the vector that we will build the result in. + std::vector current_f_loop; + current_f_loop.reserve(N); + + std::vector f_loop_heap; + f_loop_heap.reserve(N); + + for (unsigned i = 0; i < f_loop.size(); ++i) { + current_f_loop.push_back(f_loop[i]); + } + + std::vector *, vert_iter> > h_loop_min_vertex; + + h_loop_min_vertex.reserve(h_loops.size()); + + // find the major axis for the holes - this is the axis that we + // will sort on for finding vertices on the polygon to join + // holes up to. + // + // it might also be nice to also look for whether it is better + // to sort ascending or descending. + // + // another trick that could be used is to modify the projection + // by 90 degree rotations or flipping about an axis. just as + // long as we keep the carve::geom3d::Vector pointers for the + // real data in sync, everything should be ok. then we wouldn't + // need to accomodate axes or sort order in the main loop. + + // find the bounding box of all the holes. + bool first = true; + double min_x, min_y, max_x, max_y; + for (hole_iter i = h_loops.begin(); i != h_loops.end(); ++i) { + const hole_t &hole(*i); + for (vert_iter j = hole.begin(); j != hole.end(); ++j) { + carve::geom2d::P2 curr = project(*j); + if (first) { + min_x = max_x = curr.x; + min_y = max_y = curr.y; + first = false; + } else { + min_x = std::min(min_x, curr.x); + min_y = std::min(min_y, curr.y); + max_x = std::max(max_x, curr.x); + max_y = std::max(max_y, curr.y); + } + } + } + + // choose the axis for which the bbox is largest. + int axis = (max_x - min_x) > (max_y - min_y) ? 0 : 1; + + // for each hole, find the minimum vertex in the chosen axis. + for (hole_iter i = h_loops.begin(); i != h_loops.end(); ++i) { + const hole_t &hole = *i; + vert_iter best_i = std::min_element(hole.begin(), hole.end(), detail::order_h_loops(project, axis)); + h_loop_min_vertex.push_back(std::make_pair(&hole, best_i)); + } + + // sort the holes by the minimum vertex. + std::sort(h_loop_min_vertex.begin(), h_loop_min_vertex.end(), detail::order_h_loops(project, axis)); + + // now, for each hole, find a vertex in the current polygon loop that it can be joined to. + for (unsigned i = 0; i < h_loop_min_vertex.size(); ++i) { + const size_t N_f_loop = current_f_loop.size(); + + // the index of the vertex in the hole to connect. + vert_iter h_loop_connect = h_loop_min_vertex[i].second; + + carve::geom2d::P2 hole_min = project(*h_loop_connect); + + f_loop_heap.clear(); + // we order polygon loop vertices that may be able to be connected + // to the hole vertex by their distance to the hole vertex + detail::heap_ordering _heap_ordering(project, current_f_loop, *h_loop_connect, axis); + + for (size_t j = 0; j < N_f_loop; ++j) { + // it is guaranteed that there exists a polygon vertex with + // coord < the min hole coord chosen, which can be joined to + // the min hole coord without crossing the polygon + // boundary. also, because we merge holes in ascending + // order, it is also true that this join can never cross + // another hole (and that doesn't need to be tested for). + if (project(current_f_loop[j]).v[axis] <= hole_min.v[axis]) { + f_loop_heap.push_back(j); + std::push_heap(f_loop_heap.begin(), f_loop_heap.end(), _heap_ordering); + } + } + + // we are going to test each potential (according to the + // previous test) polygon vertex as a candidate join. we order + // by closeness to the hole vertex, so that the join we make + // is as small as possible. to test, we need to check the + // joining line segment does not cross any other line segment + // in the current polygon loop (excluding those that have the + // vertex that we are attempting to join with as an endpoint). + size_t attachment_point = current_f_loop.size(); + + while (f_loop_heap.size()) { + std::pop_heap(f_loop_heap.begin(), f_loop_heap.end(), _heap_ordering); + size_t curr = f_loop_heap.back(); + f_loop_heap.pop_back(); + // test the candidate join from current_f_loop[curr] to hole_min + + if (!detail::testCandidateAttachment(project, current_f_loop, curr, hole_min)) { + continue; + } + + attachment_point = curr; + break; + } + + if (attachment_point == current_f_loop.size()) { + CARVE_FAIL("didn't manage to link up hole!"); + } + + detail::patchHoleIntoPolygon(current_f_loop, attachment_point, h_loop_min_vertex[i]); + } + + return current_f_loop; + } + + + + template + void triangulate(const project_t &project, + const std::vector &poly, + std::vector &result) { + std::vector vinfo; + const size_t N = poly.size(); + + result.clear(); + if (N < 3) { + return; + } + + result.reserve(poly.size() - 2); + + if (N == 3) { + result.push_back(tri_idx(0, 1, 2)); + return; + } + + vinfo.resize(N); + + vinfo[0] = new detail::vertex_info(project(poly[0]), 0); + for (size_t i = 1; i < N-1; ++i) { + vinfo[i] = new detail::vertex_info(project(poly[i]), i); + vinfo[i]->prev = vinfo[i-1]; + vinfo[i-1]->next = vinfo[i]; + } + vinfo[N-1] = new detail::vertex_info(project(poly[N-1]), N-1); + vinfo[N-1]->prev = vinfo[N-2]; + vinfo[N-1]->next = vinfo[0]; + vinfo[0]->prev = vinfo[N-1]; + vinfo[N-2]->next = vinfo[N-1]; + + for (size_t i = 0; i < N; ++i) { + vinfo[i]->recompute(); + } + + detail::vertex_info *begin = vinfo[0]; + + removeDegeneracies(begin, result); + doTriangulate(begin, result); + } + + + + template + void improve(const project_t &project, + const std::vector &poly, + distance_calc_t dist, + std::vector &result) { + detail::tri_pairs_t tri_pairs; + +#if defined(CARVE_DEBUG) + bool warn = false; + for (size_t i = 0; i < result.size(); ++i) { + tri_idx &t = result[i]; + if (carve::geom2d::signedArea(project(poly[t.a]), project(poly[t.b]), project(poly[t.c])) > 0) { + warn = true; + } + } + if (warn) { + std::cerr << "carve::triangulate::improve(): Some triangles are incorrectly oriented. Results may be incorrect." << std::endl; + } +#endif + + for (size_t i = 0; i < result.size(); ++i) { + tri_idx &t = result[i]; + tri_pairs.insert(t.a, t.b, &t); + tri_pairs.insert(t.b, t.c, &t); + tri_pairs.insert(t.c, t.a, &t); + } + + std::vector edges; + size_t n = tri_pairs.getInternalEdges(project, poly, dist, edges); + for (size_t i = 0; i < n; ++i) { + edges[i]->idx = i; + } + + // procedure: + // while a tri pair with a positive score exists: + // p = pair with highest positive score + // flip p, rewriting its two referenced triangles. + // negate p's score + // for each q in the up-to-four adjoining tri pairs: + // update q's tri ptr, if changed, and its score. + +#if defined(CARVE_DEBUG) + double initial_score = 0; + for (size_t i = 0; i < edges.size(); ++i) { + initial_score += edges[i]->edgeLen(project, poly, dist); + } + std::cerr << "initial score: " << initial_score << std::endl; +#endif + + while (n) { + tri_pairs.flip(project, poly, dist, edges, n); + } + +#if defined(CARVE_DEBUG) + double final_score = 0; + for (size_t i = 0; i < edges.size(); ++i) { + final_score += edges[i]->edgeLen(project, poly, dist); + } + std::cerr << "final score: " << final_score << std::endl; +#endif + +#if defined(CARVE_DEBUG) + if (!warn) { + for (size_t i = 0; i < result.size(); ++i) { + tri_idx &t = result[i]; + CARVE_ASSERT (carve::geom2d::signedArea(project(poly[t.a]), project(poly[t.b]), project(poly[t.c])) <= 0.0); + } + } +#endif + } + + + + template + void improve(const project_t &project, + const std::vector &poly, + std::vector &result) { + improve(project, poly, carve::geom::distance_functor(), result); + } + + + + } +} diff -Nru blender-2.61/extern/carve/include/carve/util.hpp blender-2.62/extern/carve/include/carve/util.hpp --- blender-2.61/extern/carve/include/carve/util.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/util.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,31 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +namespace carve { + namespace util { + struct min_functor { + template + const T &operator()(const T &a, const T &b) const { return std::min(a, b); } + }; + struct max_functor { + template + const T &operator()(const T &a, const T &b) const { return std::max(a, b); } + }; + } +} diff -Nru blender-2.61/extern/carve/include/carve/vcpp_config.h blender-2.62/extern/carve/include/carve/vcpp_config.h --- blender-2.61/extern/carve/include/carve/vcpp_config.h 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/vcpp_config.h 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,17 @@ +/* include/carve/config.h. Generated from config.h.in by configure. */ +#pragma once + +#include + +/* Define if using boost collections. Preferred, because the visual C++ unordered collections are slow and memory hungry. */ +#define HAVE_BOOST_UNORDERED_COLLECTIONS + +#if defined(_MSC_VER) +# pragma warning(disable:4201) +#endif + +#include + +static inline double round(double value) { + return (value >= 0) ? floor(value + 0.5) : ceil(value - 0.5); +} diff -Nru blender-2.61/extern/carve/include/carve/vector.hpp blender-2.62/extern/carve/include/carve/vector.hpp --- blender-2.61/extern/carve/include/carve/vector.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/vector.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,163 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +#include +#include +#include + +#include +#include + +#include + +namespace carve { + namespace geom3d { + + struct hash_vector_ptr { + size_t operator()(const Vector * const &v) const { + return (size_t)v; + } + size_t operator()(const std::pair &v) const { + size_t r = (size_t)v.first; + size_t s = (size_t)v.second; + return r ^ ((s >> 16) | (s << 16)); + } + }; + + + + struct vec_adapt_ident { + const Vector &operator()(const Vector &v) const { return v; } + Vector &operator()(Vector &v) const { return v; } + }; + + + + struct vec_adapt_ptr { + const Vector &operator()(const Vector * const &v) const { return *v; } + Vector &operator()(Vector *&v) const { return *v; } + }; + + + + struct vec_adapt_pair_first { + template const Vector &operator()(const pair_t &v) const { return v.first; } + template Vector &operator()(pair_t &v) const { return v.first; } + }; + + + + struct vec_adapt_pair_second { + template const Vector &operator()(const pair_t &v) const { return v.second; } + template Vector &operator()(pair_t &v) const { return v.second; } + }; + + + + template + struct vec_cmp_lt_x { + adapt_t adapt; + vec_cmp_lt_x(adapt_t _adapt = adapt_t()) : adapt(_adapt) {} + template bool operator()(const input_t &a, const input_t &b) const { return adapt(a).x < adapt(b).x; } + }; + template vec_cmp_lt_x vec_lt_x(adapt_t &adapt) { return vec_cmp_lt_x(adapt); } + + + + template + struct vec_cmp_lt_y { + adapt_t adapt; + vec_cmp_lt_y(adapt_t _adapt = adapt_t()) : adapt(_adapt) {} + template bool operator()(const input_t &a, const input_t &b) const { return adapt(a).y < adapt(b).y; } + }; + template vec_cmp_lt_y vec_lt_y(adapt_t &adapt) { return vec_cmp_lt_y(adapt); } + + + + template + struct vec_cmp_lt_z { + adapt_t adapt; + vec_cmp_lt_z(adapt_t _adapt = adapt_t()) : adapt(_adapt) {} + template bool operator()(const input_t &a, const input_t &b) const { return adapt(a).z < adapt(b).z; } + }; + template vec_cmp_lt_z vec_lt_z(adapt_t &adapt) { return vec_cmp_lt_z(adapt); } + + + + template + struct vec_cmp_gt_x { + adapt_t adapt; + vec_cmp_gt_x(adapt_t _adapt = adapt_t()) : adapt(_adapt) {} + template bool operator()(const input_t &a, const input_t &b) const { return adapt(a).x > adapt(b).x; } + }; + template vec_cmp_gt_x vec_gt_x(adapt_t &adapt) { return vec_cmp_gt_x(adapt); } + + + + template + struct vec_cmp_gt_y { + adapt_t adapt; + vec_cmp_gt_y(adapt_t _adapt = adapt_t()) : adapt(_adapt) {} + template bool operator()(const input_t &a, const input_t &b) const { return adapt(a).y > adapt(b).y; } + }; + template vec_cmp_gt_y vec_gt_y(adapt_t &adapt) { return vec_cmp_gt_y(adapt); } + + + + template + struct vec_cmp_gt_z { + adapt_t adapt; + vec_cmp_gt_z(adapt_t _adapt = adapt_t()) : adapt(_adapt) {} + template bool operator()(const input_t &a, const input_t &b) const { return adapt(a).z > adapt(b).z; } + }; + template vec_cmp_gt_z vec_gt_z(adapt_t &adapt) { return vec_cmp_gt_z(adapt); } + + + + template + void sortInDirectionOfRay(const Vector &ray_dir, iter_t begin, iter_t end, adapt_t adapt) { + switch (carve::geom::largestAxis(ray_dir)) { + case 0: + if (ray_dir.x > 0) { + std::sort(begin, end, vec_lt_x(adapt)); + } else { + std::sort(begin, end, vec_gt_x(adapt)); + } + break; + case 1: + if (ray_dir.y > 0) { + std::sort(begin, end, vec_lt_y(adapt)); + } else { + std::sort(begin, end, vec_gt_y(adapt)); + } + break; + case 2: + if (ray_dir.z > 0) { + std::sort(begin, end, vec_lt_z(adapt)); + } else { + std::sort(begin, end, vec_gt_z(adapt)); + } + break; + } + } + + } +} diff -Nru blender-2.61/extern/carve/include/carve/vertex_decl.hpp blender-2.62/extern/carve/include/carve/vertex_decl.hpp --- blender-2.61/extern/carve/include/carve/vertex_decl.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/vertex_decl.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,111 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace carve { + namespace poly { + + + + struct Object; + + + + template + class Vertex : public tagable { + public: + typedef carve::geom::vector vector_t; + typedef Object obj_t; + + vector_t v; + obj_t *owner; + + Vertex() : tagable(), v() { + } + + ~Vertex() { + } + + Vertex(const vector_t &_v) : tagable(), v(_v) { + } + }; + + + + struct hash_vertex_ptr { + template + size_t operator()(const Vertex * const &v) const { + return (size_t)v; + } + + template + size_t operator()(const std::pair *, const Vertex *> &v) const { + size_t r = (size_t)v.first; + size_t s = (size_t)v.second; + return r ^ ((s >> 16) | (s << 16)); + } + + }; + + + + template + double distance(const Vertex *v1, const Vertex *v2) { + return distance(v1->v, v2->v); + } + + template + double distance(const Vertex &v1, const Vertex &v2) { + return distance(v1.v, v2.v); + } + + struct vec_adapt_vertex_ref { + template + const typename Vertex::vector_t &operator()(const Vertex &v) const { return v.v; } + + template + typename Vertex::vector_t &operator()(Vertex &v) const { return v.v; } + }; + + + + struct vec_adapt_vertex_ptr { + template + const typename Vertex::vector_t &operator()(const Vertex *v) const { return v->v; } + + template + typename Vertex::vector_t &operator()(Vertex *v) const { return v->v; } + }; + + + + } +} diff -Nru blender-2.61/extern/carve/include/carve/vertex_impl.hpp blender-2.62/extern/carve/include/carve/vertex_impl.hpp --- blender-2.61/extern/carve/include/carve/vertex_impl.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/vertex_impl.hpp 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,24 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +namespace carve { + namespace poly { + + } +} diff -Nru blender-2.61/extern/carve/include/carve/win32.h blender-2.62/extern/carve/include/carve/win32.h --- blender-2.61/extern/carve/include/carve/win32.h 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/include/carve/win32.h 2012-02-15 19:39:27.000000000 +0000 @@ -0,0 +1,55 @@ +// Copyright 2006 Tobias Sargeant (toby@permuted.net) +// All rights reserved. +#pragma once + +#pragma warning (disable : 4996) +#pragma warning (disable : 4786) + +#include +#include + +#if !defined(__MINGW32__) +inline int strcasecmp(const char *a, const char *b) { + return _stricmp(a,b); +} +#endif + +inline void srandom(unsigned long input) { + srand(input); +} + +inline long random() { + return rand(); +} + +#if defined(_MSC_VER) +# include + +#if _MSC_VER < 1300 +// intptr_t is an integer type that is big enough to hold a pointer +// It is not defined in VC6 so include a definition here for the older compiler +typedef long intptr_t; +typedef unsigned long uintptr_t; +#endif + +# if _MSC_VER < 1600 +// stdint.h is not available before VS2010 +#if defined(_WIN32) && !defined(__MINGW32__) +/* The __intXX are built-in types of the visual complier! So we don't + need to include anything else here. + This typedefs should be in sync with types from MEM_sys_types.h */ + +typedef signed __int8 int8_t; +typedef signed __int16 int16_t; +typedef signed __int32 int32_t; + +typedef unsigned __int8 uint8_t; +typedef unsigned __int16 uint16_t; +typedef unsigned __int32 uint32_t; +#endif +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +# else +# include +# endif +#endif diff -Nru blender-2.61/extern/carve/lib/aabb.cpp blender-2.62/extern/carve/lib/aabb.cpp --- blender-2.61/extern/carve/lib/aabb.cpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/aabb.cpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,29 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#if defined(HAVE_CONFIG_H) +# include +#endif + +#include +#include + +namespace carve { + namespace geom3d { + } +} + diff -Nru blender-2.61/extern/carve/lib/carve.cpp blender-2.62/extern/carve/lib/carve.cpp --- blender-2.61/extern/carve/lib/carve.cpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/carve.cpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,29 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#if defined(HAVE_CONFIG_H) +# include +#endif + +#include + +#define DEF_EPSILON 1.4901161193847656e-08 + +namespace carve { + double EPSILON = DEF_EPSILON; + double EPSILON2 = DEF_EPSILON * DEF_EPSILON; +} diff -Nru blender-2.61/extern/carve/lib/convex_hull.cpp blender-2.62/extern/carve/lib/convex_hull.cpp --- blender-2.61/extern/carve/lib/convex_hull.cpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/convex_hull.cpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,100 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#if defined(HAVE_CONFIG_H) +# include +#endif + +#include +#include + +#include + +namespace { + + bool grahamScan(const std::vector &points, + int vpp, int vp, + const std::vector &ordered, + int start, + std::vector &result, int _i = 0) { + carve::geom2d::P2 v1 = points[vp] - points[vpp]; + if (start == (int)ordered.size()) return true; + + for (int i = start; i < (int)ordered.size(); ++i) { + int v = ordered[i]; + carve::geom2d::P2 v2 = points[v] - points[vp]; + + double cp = v1.x * v2.y - v2.x * v1.y; + if (cp < 0) return false; + + int j = i + 1; + while (j < (int)ordered.size() && points[ordered[j]] == points[v]) j++; + + result.push_back(v); + if (grahamScan(points, vp, v, ordered, j, result, _i + 1)) return true; + result.pop_back(); + } + + return false; + } + +} + +namespace carve { + namespace geom { + + std::vector convexHull(const std::vector &points) { + double max_x = points[0].x; + unsigned max_v = 0; + + for (unsigned i = 1; i < points.size(); ++i) { + if (points[i].x > max_x) { + max_x = points[i].x; + max_v = i; + } + } + + std::vector > angle_dist; + std::vector ordered; + angle_dist.reserve(points.size()); + ordered.reserve(points.size() - 1); + for (unsigned i = 0; i < points.size(); ++i) { + if (i == max_v) continue; + angle_dist[i] = std::make_pair(carve::math::ANG(carve::geom2d::atan2(points[i] - points[max_v])), distance2(points[i], points[max_v])); + ordered.push_back(i); + } + + std::sort(ordered.begin(), + ordered.end(), + make_index_sort(angle_dist.begin())); + + std::vector result; + result.push_back(max_v); + result.push_back(ordered[0]); + + if (!grahamScan(points, max_v, ordered[0], ordered, 1, result)) { + result.clear(); + throw carve::exception("convex hull failed!"); + } + + return result; + } + + } +} + + diff -Nru blender-2.61/extern/carve/lib/csg_collector.cpp blender-2.62/extern/carve/lib/csg_collector.cpp --- blender-2.61/extern/carve/lib/csg_collector.cpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/csg_collector.cpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,371 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#if defined(HAVE_CONFIG_H) +# include +#endif + +#include +#include +#include "intersect_debug.hpp" + +#if defined(CARVE_DEBUG_WRITE_PLY_DATA) +void writePLY(const std::string &out_file, const carve::mesh::MeshSet<3> *poly, bool ascii); +#endif + + +namespace carve { + namespace csg { + namespace { + + class BaseCollector : public CSG::Collector { + BaseCollector(); + BaseCollector(const BaseCollector &); + BaseCollector &operator=(const BaseCollector &); + + protected: + struct face_data_t { + carve::mesh::MeshSet<3>::face_t *face; + const carve::mesh::MeshSet<3>::face_t *orig_face; + bool flipped; + face_data_t(carve::mesh::MeshSet<3>::face_t *_face, + const carve::mesh::MeshSet<3>::face_t *_orig_face, + bool _flipped) : face(_face), orig_face(_orig_face), flipped(_flipped) { + }; + }; + + std::list faces; + + const carve::mesh::MeshSet<3> *src_a; + const carve::mesh::MeshSet<3> *src_b; + + BaseCollector(const carve::mesh::MeshSet<3> *_src_a, + const carve::mesh::MeshSet<3> *_src_b) : CSG::Collector(), src_a(_src_a), src_b(_src_b) { + } + + virtual ~BaseCollector() { + } + + void FWD(const carve::mesh::MeshSet<3>::face_t *orig_face, + const std::vector::vertex_t *> &vertices, + carve::geom3d::Vector /* normal */, + bool /* poly_a */, + FaceClass face_class, + CSG::Hooks &hooks) { + std::vector::face_t *> new_faces; + new_faces.reserve(1); + new_faces.push_back(orig_face->create(vertices.begin(), vertices.end(), false)); + hooks.processOutputFace(new_faces, orig_face, false); + for (size_t i = 0; i < new_faces.size(); ++i) { + faces.push_back(face_data_t(new_faces[i], orig_face, false)); + } + +#if defined(CARVE_DEBUG) && defined(DEBUG_PRINT_RESULT_FACES) + std::cerr << "+" << ENUM(face_class) << " "; + for (unsigned i = 0; i < vertices.size(); ++i) std::cerr << " " << vertices[i] << ":" << *vertices[i]; + std::cerr << std::endl; +#endif + } + + void REV(const carve::mesh::MeshSet<3>::face_t *orig_face, + const std::vector::vertex_t *> &vertices, + carve::geom3d::Vector /* normal */, + bool /* poly_a */, + FaceClass face_class, + CSG::Hooks &hooks) { + // normal = -normal; + std::vector::face_t *> new_faces; + new_faces.reserve(1); + new_faces.push_back(orig_face->create(vertices.begin(), vertices.end(), true)); + hooks.processOutputFace(new_faces, orig_face, true); + for (size_t i = 0; i < new_faces.size(); ++i) { + faces.push_back(face_data_t(new_faces[i], orig_face, true)); + } + +#if defined(CARVE_DEBUG) && defined(DEBUG_PRINT_RESULT_FACES) + std::cerr << "-" << ENUM(face_class) << " "; + for (unsigned i = 0; i < vertices.size(); ++i) std::cerr << " " << vertices[i] << ":" << *vertices[i]; + std::cerr << std::endl; +#endif + } + + virtual void collect(const carve::mesh::MeshSet<3>::face_t *orig_face, + const std::vector::vertex_t *> &vertices, + carve::geom3d::Vector normal, + bool poly_a, + FaceClass face_class, + CSG::Hooks &hooks) =0; + + virtual void collect(FaceLoopGroup *grp, CSG::Hooks &hooks) { + std::list &cinfo = (grp->classification); + + if (cinfo.size() == 0) { + std::cerr << "WARNING! group " << grp << " has no classification info!" << std::endl; + return; + } + + FaceClass fc = FACE_UNCLASSIFIED; + + unsigned fc_closed_bits = 0; + unsigned fc_open_bits = 0; + unsigned fc_bits = 0; + + for (std::list::const_iterator i = grp->classification.begin(), e = grp->classification.end(); i != e; ++i) { + + if ((*i).intersected_mesh == NULL) { + // classifier only returns global info + fc_closed_bits = class_to_class_bit((*i).classification); + break; + } + + if ((*i).classification == FACE_UNCLASSIFIED) continue; + if ((*i).intersectedMeshIsClosed()) { + fc_closed_bits |= class_to_class_bit((*i).classification); + } else { + fc_open_bits |= class_to_class_bit((*i).classification); + } + } + + if (fc_closed_bits) { + fc_bits = fc_closed_bits; + } else { + fc_bits = fc_open_bits; + } + + fc = class_bit_to_class(fc_bits); + + // handle the complex cases where a group is classified differently with respect to two or more closed manifolds. + if (fc == FACE_UNCLASSIFIED) { + unsigned inout_bits = fc_bits & FACE_NOT_ON_BIT; + unsigned on_bits = fc_bits & FACE_ON_BIT; + + // both in and out. indicates an invalid manifold embedding. + if (inout_bits == (FACE_IN_BIT | FACE_OUT_BIT)) goto out; + + // on, both orientations. could be caused by two manifolds touching at a face. + if (on_bits == (FACE_ON_ORIENT_IN_BIT | FACE_ON_ORIENT_OUT_BIT)) goto out; + + // in or out, but also on (with orientation). the on classification takes precedence. + fc = class_bit_to_class(on_bits); + } + + out: + + if (fc == FACE_UNCLASSIFIED) { + std::cerr << "group " << grp << " is unclassified!" << std::endl; + +#if defined(CARVE_DEBUG_WRITE_PLY_DATA) + static int uc_count = 0; + + std::vector::face_t *> faces; + + for (FaceLoop *f = grp->face_loops.head; f; f = f->next) { + carve::mesh::MeshSet<3>::face_t *temp = f->orig_face->create(f->vertices.begin(), f->vertices.end(), false); + faces.push_back(temp); + } + + carve::mesh::MeshSet<3> *p = new carve::mesh::MeshSet<3>(faces); + + std::ostringstream filename; + filename << "classifier_fail_" << ++uc_count << ".ply"; + std::string out(filename.str().c_str()); + ::writePLY(out, p, false); + + delete p; +#endif + + return; + } + + bool is_poly_a = grp->src == src_a; + + for (FaceLoop *f = grp->face_loops.head; f; f = f->next) { + collect(f->orig_face, f->vertices, f->orig_face->plane.N, is_poly_a, fc, hooks); + } + } + + virtual carve::mesh::MeshSet<3> *done(CSG::Hooks &hooks) { + std::vector::face_t *> f; + f.reserve(faces.size()); + for (std::list::iterator i = faces.begin(); i != faces.end(); ++i) { + f.push_back((*i).face); + } + + carve::mesh::MeshSet<3> *p = new carve::mesh::MeshSet<3>(f); + + if (hooks.hasHook(carve::csg::CSG::Hooks::RESULT_FACE_HOOK)) { + for (std::list::iterator i = faces.begin(); i != faces.end(); ++i) { + hooks.resultFace((*i).face, (*i).orig_face, (*i).flipped); + } + } + + return p; + } + }; + + + + class AllCollector : public BaseCollector { + public: + AllCollector(const carve::mesh::MeshSet<3> *_src_a, + const carve::mesh::MeshSet<3> *_src_b) : BaseCollector(_src_a, _src_b) { + } + virtual ~AllCollector() { + } + virtual void collect(FaceLoopGroup *grp, CSG::Hooks &hooks) { + for (FaceLoop *f = grp->face_loops.head; f; f = f->next) { + FWD(f->orig_face, f->vertices, f->orig_face->plane.N, f->orig_face->mesh->meshset == src_a, FACE_OUT, hooks); + } + } + virtual void collect(const carve::mesh::MeshSet<3>::face_t *orig_face, + const std::vector::vertex_t *> &vertices, + carve::geom3d::Vector normal, + bool poly_a, + FaceClass face_class, + CSG::Hooks &hooks) { + FWD(orig_face, vertices, normal, poly_a, face_class, hooks); + } + }; + + + + class UnionCollector : public BaseCollector { + public: + UnionCollector(const carve::mesh::MeshSet<3> *_src_a, + const carve::mesh::MeshSet<3> *_src_b) : BaseCollector(_src_a, _src_b) { + } + virtual ~UnionCollector() { + } + virtual void collect(const carve::mesh::MeshSet<3>::face_t *orig_face, + const std::vector::vertex_t *> &vertices, + carve::geom3d::Vector normal, + bool poly_a, + FaceClass face_class, + CSG::Hooks &hooks) { + if (face_class == FACE_OUT || (poly_a && face_class == FACE_ON_ORIENT_OUT)) { + FWD(orig_face, vertices, normal, poly_a, face_class, hooks); + } + } + }; + + + + class IntersectionCollector : public BaseCollector { + public: + IntersectionCollector(const carve::mesh::MeshSet<3> *_src_a, + const carve::mesh::MeshSet<3> *_src_b) : BaseCollector(_src_a, _src_b) { + } + virtual ~IntersectionCollector() { + } + virtual void collect(const carve::mesh::MeshSet<3>::face_t *orig_face, + const std::vector::vertex_t *> &vertices, + carve::geom3d::Vector normal, + bool poly_a, + FaceClass face_class, + CSG::Hooks &hooks) { + if (face_class == FACE_IN || (poly_a && face_class == FACE_ON_ORIENT_OUT)) { + FWD(orig_face, vertices, normal, poly_a, face_class, hooks); + } + } + }; + + + + class SymmetricDifferenceCollector : public BaseCollector { + public: + SymmetricDifferenceCollector(const carve::mesh::MeshSet<3> *_src_a, + const carve::mesh::MeshSet<3> *_src_b) : BaseCollector(_src_a, _src_b) { + } + virtual ~SymmetricDifferenceCollector() { + } + virtual void collect(const carve::mesh::MeshSet<3>::face_t *orig_face, + const std::vector::vertex_t *> &vertices, + carve::geom3d::Vector normal, + bool poly_a, + FaceClass face_class, + CSG::Hooks &hooks) { + if (face_class == FACE_OUT) { + FWD(orig_face, vertices, normal, poly_a, face_class, hooks); + } else if (face_class == FACE_IN) { + REV(orig_face, vertices, normal, poly_a, face_class, hooks); + } + } + }; + + + + class AMinusBCollector : public BaseCollector { + public: + AMinusBCollector(const carve::mesh::MeshSet<3> *_src_a, + const carve::mesh::MeshSet<3> *_src_b) : BaseCollector(_src_a, _src_b) { + } + virtual ~AMinusBCollector() { + } + virtual void collect(const carve::mesh::MeshSet<3>::face_t *orig_face, + const std::vector::vertex_t *> &vertices, + carve::geom3d::Vector normal, + bool poly_a, + FaceClass face_class, + CSG::Hooks &hooks) { + if ((face_class == FACE_OUT || face_class == FACE_ON_ORIENT_IN) && poly_a) { + FWD(orig_face, vertices, normal, poly_a, face_class, hooks); + } else if (face_class == FACE_IN && !poly_a) { + REV(orig_face, vertices, normal, poly_a, face_class, hooks); + } + } + }; + + + + class BMinusACollector : public BaseCollector { + public: + BMinusACollector(const carve::mesh::MeshSet<3> *_src_a, + const carve::mesh::MeshSet<3> *_src_b) : BaseCollector(_src_a, _src_b) { + } + virtual ~BMinusACollector() { + } + virtual void collect(const carve::mesh::MeshSet<3>::face_t *orig_face, + const std::vector::vertex_t *> &vertices, + carve::geom3d::Vector normal, + bool poly_a, + FaceClass face_class, + CSG::Hooks &hooks) { + if ((face_class == FACE_OUT || face_class == FACE_ON_ORIENT_IN) && !poly_a) { + FWD(orig_face, vertices, normal, poly_a, face_class, hooks); + } else if (face_class == FACE_IN && poly_a) { + REV(orig_face, vertices, normal, poly_a, face_class, hooks); + } + } + }; + + } + + CSG::Collector *makeCollector(CSG::OP op, + const carve::mesh::MeshSet<3> *poly_a, + const carve::mesh::MeshSet<3> *poly_b) { + switch (op) { + case CSG::UNION: return new UnionCollector(poly_a, poly_b); + case CSG::INTERSECTION: return new IntersectionCollector(poly_a, poly_b); + case CSG::A_MINUS_B: return new AMinusBCollector(poly_a, poly_b); + case CSG::B_MINUS_A: return new BMinusACollector(poly_a, poly_b); + case CSG::SYMMETRIC_DIFFERENCE: return new SymmetricDifferenceCollector(poly_a, poly_b); + case CSG::ALL: return new AllCollector(poly_a, poly_b); + } + return NULL; + } + } +} diff -Nru blender-2.61/extern/carve/lib/csg_collector.hpp blender-2.62/extern/carve/lib/csg_collector.hpp --- blender-2.61/extern/carve/lib/csg_collector.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/csg_collector.hpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,24 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +namespace carve { + namespace csg { + CSG::Collector *makeCollector(CSG::OP op, + const carve::mesh::MeshSet<3> *poly_a, + const carve::mesh::MeshSet<3> *poly_b); + } +} diff -Nru blender-2.61/extern/carve/lib/csg.cpp blender-2.62/extern/carve/lib/csg.cpp --- blender-2.61/extern/carve/lib/csg.cpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/csg.cpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,93 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#if defined(HAVE_CONFIG_H) +# include +#endif + +#include +#include "csg_detail.hpp" + + +const char *carve::csg::ENUM(carve::csg::FaceClass f) { + if (f == FACE_ON_ORIENT_OUT) return "FACE_ON_ORIENT_OUT"; + if (f == FACE_OUT) return "FACE_OUT"; + if (f == FACE_IN) return "FACE_IN"; + if (f == FACE_ON_ORIENT_IN) return "FACE_ON_ORIENT_IN"; + return "???"; +} + + + +const char *carve::csg::ENUM(carve::PointClass p) { + if (p == POINT_UNK) return "POINT_UNK"; + if (p == POINT_OUT) return "POINT_OUT"; + if (p == POINT_ON) return "POINT_ON"; + if (p == POINT_IN) return "POINT_IN"; + if (p == POINT_VERTEX) return "POINT_VERTEX"; + if (p == POINT_EDGE) return "POINT_EDGE"; + return "???"; +} + + + +void carve::csg::detail::LoopEdges::addFaceLoop(FaceLoop *fl) { + carve::mesh::MeshSet<3>::vertex_t *v1, *v2; + v1 = fl->vertices[fl->vertices.size() - 1]; + for (unsigned j = 0; j < fl->vertices.size(); ++j) { + v2 = fl->vertices[j]; + (*this)[std::make_pair(v1, v2)].push_back(fl); + v1 = v2; + } +} + + + +void carve::csg::detail::LoopEdges::sortFaceLoopLists() { + for (super::iterator i = begin(), e = end(); i != e; ++i) { + (*i).second.sort(); + } +} + + + +void carve::csg::detail::LoopEdges::removeFaceLoop(FaceLoop *fl) { + carve::mesh::MeshSet<3>::vertex_t *v1, *v2; + v1 = fl->vertices[fl->vertices.size() - 1]; + for (unsigned j = 0; j < fl->vertices.size(); ++j) { + v2 = fl->vertices[j]; + iterator l(find(std::make_pair(v1, v2))); + if (l != end()) { + (*l).second.remove(fl); + if (!(*l).second.size()) { + erase(l); + } + } + v1 = v2; + } +} + + + +carve::csg::FaceClass carve::csg::FaceLoopGroup::classificationAgainst(const carve::mesh::MeshSet<3>::mesh_t *mesh) const { + for (std::list::const_iterator i = classification.begin(); i != classification.end(); ++i) { + if ((*i).intersected_mesh == mesh) { + return (*i).classification; + } + } + return FACE_UNCLASSIFIED; +} diff -Nru blender-2.61/extern/carve/lib/csg_data.hpp blender-2.62/extern/carve/lib/csg_data.hpp --- blender-2.61/extern/carve/lib/csg_data.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/csg_data.hpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,52 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +#include "csg_detail.hpp" + +struct carve::csg::detail::Data { +// * @param[out] vmap A mapping from vertex pointer to intersection point. +// * @param[out] emap A mapping from edge pointer to intersection points. +// * @param[out] fmap A mapping from face pointer to intersection points. +// * @param[out] fmap_rev A mapping from intersection points to face pointers. + // map from intersected vertex to intersection point. + VVMap vmap; + + // map from intersected edge to intersection points. + EVSMap emap; + + // map from intersected face to intersection points. + FVSMap fmap; + + // map from intersection point to intersected faces. + VFSMap fmap_rev; + + // created by divideEdges(). + // holds, for each edge, a + EVVMap divided_edges; + + // created by faceSplitEdges. + FV2SMap face_split_edges; + + // mapping from vertex to edge for potentially intersected + // faces. Saves building the vertex to edge map for all faces of + // both meshes. + VEVecMap vert_to_edges; +}; diff -Nru blender-2.61/extern/carve/lib/csg_detail.hpp blender-2.62/extern/carve/lib/csg_detail.hpp --- blender-2.61/extern/carve/lib/csg_detail.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/csg_detail.hpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,71 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include + +#include + +namespace carve { + namespace csg { + namespace detail { + + typedef std::unordered_set::vertex_t *> VSet; + typedef std::unordered_set::face_t *> FSet; + + typedef std::set::vertex_t *> VSetSmall; + typedef std::set V2SetSmall; + typedef std::set::face_t *> FSetSmall; + + typedef std::unordered_map::vertex_t *, VSetSmall> VVSMap; + typedef std::unordered_map::edge_t *, VSetSmall> EVSMap; + typedef std::unordered_map::face_t *, VSetSmall> FVSMap; + + typedef std::unordered_map::vertex_t *, FSetSmall> VFSMap; + typedef std::unordered_map::face_t *, V2SetSmall> FV2SMap; + + typedef std::unordered_map< + carve::mesh::MeshSet<3>::edge_t *, + std::vector::vertex_t *> > EVVMap; + + typedef std::unordered_map::vertex_t *, + std::vector::edge_t *> > VEVecMap; + + + class LoopEdges : public std::unordered_map > { + typedef std::unordered_map > super; + + public: + void addFaceLoop(FaceLoop *fl); + void sortFaceLoopLists(); + void removeFaceLoop(FaceLoop *fl); + }; + + } + } +} + + + +static inline std::ostream &operator<<(std::ostream &o, const carve::csg::detail::FSet &s) { + const char *sep=""; + for (carve::csg::detail::FSet::const_iterator i = s.begin(); i != s.end(); ++i) { + o << sep << *i; sep=","; + } + return o; +} diff -Nru blender-2.61/extern/carve/lib/edge.cpp blender-2.62/extern/carve/lib/edge.cpp --- blender-2.61/extern/carve/lib/edge.cpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/edge.cpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,23 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#if defined(HAVE_CONFIG_H) +# include +#endif + +#include + diff -Nru blender-2.61/extern/carve/lib/face.cpp blender-2.62/extern/carve/lib/face.cpp --- blender-2.61/extern/carve/lib/face.cpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/face.cpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,278 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#if defined(HAVE_CONFIG_H) +# include +#endif + +#include + +double CALC_X(const carve::geom::plane<3> &p, double y, double z) { return -(p.d + p.N.y * y + p.N.z * z) / p.N.x; } +double CALC_Y(const carve::geom::plane<3> &p, double x, double z) { return -(p.d + p.N.x * x + p.N.z * z) / p.N.y; } +double CALC_Z(const carve::geom::plane<3> &p, double x, double y) { return -(p.d + p.N.x * x + p.N.y * y) / p.N.z; } + +namespace carve { + namespace poly { + + carve::geom2d::P2 _project_1(const carve::geom3d::Vector &v) { + return carve::geom::VECTOR(v.z, v.y); + } + + carve::geom2d::P2 _project_2(const carve::geom3d::Vector &v) { + return carve::geom::VECTOR(v.x, v.z); + } + + carve::geom2d::P2 _project_3(const carve::geom3d::Vector &v) { + return carve::geom::VECTOR(v.y, v.x); + } + + carve::geom2d::P2 _project_4(const carve::geom3d::Vector &v) { + return carve::geom::VECTOR(v.y, v.z); + } + + carve::geom2d::P2 _project_5(const carve::geom3d::Vector &v) { + return carve::geom::VECTOR(v.z, v.x); + } + + carve::geom2d::P2 _project_6(const carve::geom3d::Vector &v) { + return carve::geom::VECTOR(v.x, v.y); + } + + + carve::geom3d::Vector _unproject_1(const carve::geom2d::P2 &p, const carve::geom3d::Plane &plane_eqn) { + return carve::geom::VECTOR(CALC_X(plane_eqn, p.y, p.x), p.y, p.x); + } + + carve::geom3d::Vector _unproject_2(const carve::geom2d::P2 &p, const carve::geom3d::Plane &plane_eqn) { + return carve::geom::VECTOR(p.x, CALC_Y(plane_eqn, p.x, p.y), p.y); + } + + carve::geom3d::Vector _unproject_3(const carve::geom2d::P2 &p, const carve::geom3d::Plane &plane_eqn) { + return carve::geom::VECTOR(p.y, p.x, CALC_Z(plane_eqn, p.y, p.x)); + } + + carve::geom3d::Vector _unproject_4(const carve::geom2d::P2 &p, const carve::geom3d::Plane &plane_eqn) { + return carve::geom::VECTOR(CALC_X(plane_eqn, p.x, p.y), p.x, p.y); + } + + carve::geom3d::Vector _unproject_5(const carve::geom2d::P2 &p, const carve::geom3d::Plane &plane_eqn) { + return carve::geom::VECTOR(p.y, CALC_Y(plane_eqn, p.y, p.x), p.x); + } + + carve::geom3d::Vector _unproject_6(const carve::geom2d::P2 &p, const carve::geom3d::Plane &plane_eqn) { + return carve::geom::VECTOR(p.x, p.y, CALC_Z(plane_eqn, p.x, p.y)); + } + + static carve::geom2d::P2 (*project_tab[2][3])(const carve::geom3d::Vector &) = { + { &_project_1, &_project_2, &_project_3 }, + { &_project_4, &_project_5, &_project_6 } + }; + + static carve::geom3d::Vector (*unproject_tab[2][3])(const carve::geom2d::P2 &, const carve::geom3d::Plane &) = { + { &_unproject_1, &_unproject_2, &_unproject_3 }, + { &_unproject_4, &_unproject_5, &_unproject_6 } + }; + + // only implemented for 3d. + template + typename Face::project_t Face::getProjector(bool positive_facing, int axis) { + return NULL; + } + + template<> + Face<3>::project_t Face<3>::getProjector(bool positive_facing, int axis) { + return project_tab[positive_facing ? 1 : 0][axis]; + } + + template + typename Face::unproject_t Face::getUnprojector(bool positive_facing, int axis) { + return NULL; + } + + template<> + Face<3>::unproject_t Face<3>::getUnprojector(bool positive_facing, int axis) { + return unproject_tab[positive_facing ? 1 : 0][axis]; + } + + + + template + Face::Face(const std::vector &_vertices, + bool delay_recalc) : tagable() { + vertices = _vertices; + edges.resize(nVertices(), NULL); + if (!delay_recalc && !recalc()) { } + } + + template + Face::Face(const vertex_t *a, + const vertex_t *b, + const vertex_t *c, + bool delay_recalc) : tagable() { + vertices.reserve(3); + vertices.push_back(a); + vertices.push_back(b); + vertices.push_back(c); + edges.resize(3, NULL); + if (!delay_recalc && !recalc()) { } + } + + template + Face::Face(const vertex_t *a, + const vertex_t *b, + const vertex_t *c, + const vertex_t *d, + bool delay_recalc) : tagable() { + vertices.reserve(4); + vertices.push_back(a); + vertices.push_back(b); + vertices.push_back(c); + vertices.push_back(d); + edges.resize(4, NULL); + if (!delay_recalc && !recalc()) { } + } + + template + void Face::invert() { + size_t n_verts = vertices.size(); + std::reverse(vertices.begin(), vertices.end()); + + if (project != NULL) { + plane_eqn.negate(); + + int da = carve::geom::largestAxis(plane_eqn.N); + + project = getProjector(plane_eqn.N.v[da] > 0, da); + unproject = getUnprojector(plane_eqn.N.v[da] > 0, da); + } + + std::reverse(edges.begin(), edges.end() - 1); + for (size_t i = 0; i < n_verts; i++) { + const vertex_t *v1 = vertices[i]; + const vertex_t *v2 = vertices[(i+1) % n_verts]; + CARVE_ASSERT((edges[i]->v1 == v1 && edges[i]->v2 == v2) || (edges[i]->v1 == v2 && edges[i]->v2 == v1)); + } + } + + template + bool Face::recalc() { + aabb.fit(vertices.begin(), vertices.end(), vec_adapt_vertex_ptr()); + + if (!carve::geom3d::fitPlane(vertices.begin(), vertices.end(), vec_adapt_vertex_ptr(), plane_eqn)) { + return false; + } + + int da = carve::geom::largestAxis(plane_eqn.N); + project = getProjector(false, da); + + double A = carve::geom2d::signedArea(vertices, projector()); + if ((A < 0.0) ^ (plane_eqn.N.v[da] < 0.0)) { + plane_eqn.negate(); + } + + project = getProjector(plane_eqn.N.v[da] > 0, da); + unproject = getUnprojector(plane_eqn.N.v[da] > 0, da); + + return true; + } + + template + Face *Face::init(const Face *base, const std::vector &_vertices, bool flipped) { + return init(base, _vertices.begin(), _vertices.end(), flipped); + } + + template + bool Face::containsPoint(const vector_t &p) const { + if (!carve::math::ZERO(carve::geom::distance(plane_eqn, p))) return false; + // return pointInPolySimple(vertices, projector(), (this->*project)(p)); + return carve::geom2d::pointInPoly(vertices, projector(), face::project(this, p)).iclass != POINT_OUT; + } + + template + bool Face::containsPointInProjection(const vector_t &p) const { + return carve::geom2d::pointInPoly(vertices, projector(), face::project(this, p)).iclass != POINT_OUT; + } + + template + bool Face::simpleLineSegmentIntersection(const carve::geom::linesegment &line, + vector_t &intersection) const { + if (!line.OK()) return false; + + carve::geom3d::Vector p; + IntersectionClass intersects = carve::geom3d::lineSegmentPlaneIntersection(plane_eqn, + line, + p); + if (intersects == INTERSECT_NONE || intersects == INTERSECT_BAD) { + return false; + } + + carve::geom2d::P2 proj_p(face::project(this, p)); + if (carve::geom2d::pointInPolySimple(vertices, projector(), proj_p)) { + intersection = p; + return true; + } + return false; + } + + // XXX: should try to return a pre-existing vertex in the case of a + // line-vertex intersection. as it stands, this code isn't used, + // so... meh. + template + IntersectionClass Face::lineSegmentIntersection(const carve::geom::linesegment &line, + vector_t &intersection) const { + if (!line.OK()) return INTERSECT_NONE; + + + carve::geom3d::Vector p; + IntersectionClass intersects = carve::geom3d::lineSegmentPlaneIntersection(plane_eqn, + line, + p); + if (intersects == INTERSECT_NONE || intersects == INTERSECT_BAD) { + return intersects; + } + + carve::geom2d::P2 proj_p(face::project(this, p)); + + carve::geom2d::PolyInclusionInfo pi = carve::geom2d::pointInPoly(vertices, projector(), proj_p); + switch (pi.iclass) { + case POINT_VERTEX: + intersection = p; + return INTERSECT_VERTEX; + + case POINT_EDGE: + intersection = p; + return INTERSECT_EDGE; + + case POINT_IN: + intersection = p; + return INTERSECT_FACE; + + case POINT_OUT: + return INTERSECT_NONE; + + default: + break; + } + return INTERSECT_NONE; + } + + + } +} + +// explicit instantiations. +template class carve::poly::Face<3>; diff -Nru blender-2.61/extern/carve/lib/geom2d.cpp blender-2.62/extern/carve/lib/geom2d.cpp --- blender-2.61/extern/carve/lib/geom2d.cpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/geom2d.cpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,260 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#if defined(HAVE_CONFIG_H) +# include +#endif + +#include +#include +#include + +#include +#include + +namespace carve { + namespace geom2d { + + bool lineSegmentIntersection_simple(const P2 &l1v1, const P2 &l1v2, + const P2 &l2v1, const P2 &l2v2) { + geom::aabb<2> l1_aabb, l2_aabb; + l1_aabb.fit(l1v1, l1v2); + l2_aabb.fit(l2v1, l2v2); + + if (l1_aabb.maxAxisSeparation(l2_aabb) > 0.0) { + return false; + } + + double l1v1_side = orient2d(l2v1, l2v2, l1v1); + double l1v2_side = orient2d(l2v1, l2v2, l1v2); + + double l2v1_side = orient2d(l1v1, l1v2, l2v1); + double l2v2_side = orient2d(l1v1, l1v2, l2v2); + + if (l1v1_side * l1v2_side > 0.0 || l2v1_side * l2v2_side > 0.0) { + return false; + } + + return true; + } + + bool lineSegmentIntersection_simple(const LineSegment2 &l1, + const LineSegment2 &l2) { + return lineSegmentIntersection_simple(l1.v1, l1.v2, l2.v1, l2.v2); + } + + LineIntersectionInfo lineSegmentIntersection(const P2 &l1v1, const P2 &l1v2, + const P2 &l2v1, const P2 &l2v2) { + geom::aabb<2> l1_aabb, l2_aabb; + l1_aabb.fit(l1v1, l1v2); + l2_aabb.fit(l2v1, l2v2); + + if (l1_aabb.maxAxisSeparation(l2_aabb) > EPSILON) { + return LineIntersectionInfo(NO_INTERSECTION); + } + + if (carve::geom::equal(l1v1, l1v2) || carve::geom::equal(l2v1, l2v2)) { + throw carve::exception("zero length line in intersection test"); + } + + double dx13 = l1v1.x - l2v1.x; + double dy13 = l1v1.y - l2v1.y; + double dx43 = l2v2.x - l2v1.x; + double dy43 = l2v2.y - l2v1.y; + double dx21 = l1v2.x - l1v1.x; + double dy21 = l1v2.y - l1v1.y; + double ua_n = dx43 * dy13 - dy43 * dx13; + double ub_n = dx21 * dy13 - dy21 * dx13; + double u_d = dy43 * dx21 - dx43 * dy21; + + if (carve::math::ZERO(u_d)) { + if (carve::math::ZERO(ua_n)) { + if (carve::geom::equal(l1v2, l2v1)) { + return LineIntersectionInfo(INTERSECTION_PP, l1v2, 1, 2); + } + if (carve::geom::equal(l1v1, l2v2)) { + return LineIntersectionInfo(INTERSECTION_PP, l1v1, 0, 4); + } + if (l1v2.x > l2v1.x && l1v1.x < l2v2.x) { + return LineIntersectionInfo(COLINEAR); + } + } + return LineIntersectionInfo(NO_INTERSECTION); + } + + double ua = ua_n / u_d; + double ub = ub_n / u_d; + + if (-EPSILON <= ua && ua <= 1.0 + EPSILON && -EPSILON <= ub && ub <= 1.0 + EPSILON) { + double x = l1v1.x + ua * (l1v2.x - l1v1.x); + double y = l1v1.y + ua * (l1v2.y - l1v1.y); + + P2 p = carve::geom::VECTOR(x, y); + + double d1 = distance2(p, l1v1); + double d2 = distance2(p, l1v2); + double d3 = distance2(p, l2v1); + double d4 = distance2(p, l2v2); + + int n = -1; + + if (std::min(d1, d2) < EPSILON2) { + if (d1 < d2) { + p = l1v1; n = 0; + } else { + p = l1v2; n = 1; + } + if (std::min(d3, d4) < EPSILON2) { + if (d3 < d4) { + return LineIntersectionInfo(INTERSECTION_PP, p, n, 2); + } else { + return LineIntersectionInfo(INTERSECTION_PP, p, n, 3); + } + } else { + return LineIntersectionInfo(INTERSECTION_PL, p, n, -1); + } + } else if (std::min(d3, d4) < EPSILON2) { + if (d3 < d4) { + return LineIntersectionInfo(INTERSECTION_LP, l2v1, -1, 2); + } else { + return LineIntersectionInfo(INTERSECTION_LP, l2v2, -1, 3); + } + } else { + return LineIntersectionInfo(INTERSECTION_LL, p, -1, -1); + } + } + return LineIntersectionInfo(NO_INTERSECTION); + } + + LineIntersectionInfo lineSegmentIntersection(const LineSegment2 &l1, + const LineSegment2 &l2) { + return lineSegmentIntersection(l1.v1, l1.v2, l2.v1, l2.v2); + } + + double signedArea(const P2Vector &points) { + return signedArea(points, p2_adapt_ident()); + } + + bool pointInPolySimple(const P2Vector &points, const P2 &p) { + return pointInPolySimple(points, p2_adapt_ident(), p); + } + + PolyInclusionInfo pointInPoly(const P2Vector &points, const P2 &p) { + return pointInPoly(points, p2_adapt_ident(), p); + } + + int lineSegmentPolyIntersections(const P2Vector &points, + LineSegment2 line, + std::vector &out) { + int count = 0; + + if (line.v2 < line.v1) { line.flip(); } + out.clear(); + + for (P2Vector::size_type i = 0, l = points.size(); i < l; i++) { + P2Vector::size_type j = (i + 1) % l; + LineIntersectionInfo e = + lineSegmentIntersection(LineSegment2(points[i], points[j]), line); + + switch (e.iclass) { + case INTERSECTION_PL: { + out.push_back(PolyIntersectionInfo(INTERSECT_EDGE, e.ipoint, i)); + count++; + break; + } + case INTERSECTION_PP: { + out.push_back(PolyIntersectionInfo(INTERSECT_VERTEX, e.ipoint, i + e.p2 - 2)); + count++; + break; + } + case INTERSECTION_LP: { + out.push_back(PolyIntersectionInfo(INTERSECT_VERTEX, e.ipoint, i + e.p2 - 2)); + count++; + break; + } + case INTERSECTION_LL: { + out.push_back(PolyIntersectionInfo(INTERSECT_EDGE, e.ipoint, i)); + count++; + break; + } + case COLINEAR: { + int n1 = (int)i, n2 = (int)j; + P2 q1 = points[i], q2 = points[j]; + + if (q2 < q1) { std::swap(q1, q2); std::swap(n1, n2); } + + if (equal(q1, line.v1)) { + out.push_back(PolyIntersectionInfo(INTERSECT_VERTEX, q1, n1)); + } else if (q1.x < line.v1.x) { + out.push_back(PolyIntersectionInfo(INTERSECT_EDGE, line.v1, i)); + } else { + out.push_back(PolyIntersectionInfo(INTERSECT_VERTEX, q1, n1)); + } + if (equal(q2, line.v2)) { + out.push_back(PolyIntersectionInfo(INTERSECT_VERTEX, q2, n2)); + } else if (line.v2.x < q2.x) { + out.push_back(PolyIntersectionInfo(INTERSECT_EDGE, line.v2, i)); + } else { + out.push_back(PolyIntersectionInfo(INTERSECT_VERTEX, q2, n2)); + } + + count += 2; + + break; + } + default: + break; + } + } + return count; + } + + struct FwdSort { + bool operator()(const PolyIntersectionInfo &a, + const PolyIntersectionInfo &b) const { + return a.ipoint < b.ipoint; + } + }; + + struct RevSort { + bool operator()(const PolyIntersectionInfo &a, + const PolyIntersectionInfo &b) const { + return a.ipoint < b.ipoint; + } + }; + + int sortedLineSegmentPolyIntersections(const P2Vector &points, + LineSegment2 line, + std::vector &out) { + + bool swapped = line.v2 < line.v1; + + int count = lineSegmentPolyIntersections(points, line, out); + if (swapped) { + std::sort(out.begin(), out.end(), RevSort()); + } else { + std::sort(out.begin(), out.end(), FwdSort()); + } + return count; + } + + bool pickContainedPoint(const std::vector &poly, P2 &result) { + return pickContainedPoint(poly, p2_adapt_ident(), result); + } + + } +} diff -Nru blender-2.61/extern/carve/lib/geom3d.cpp blender-2.62/extern/carve/lib/geom3d.cpp --- blender-2.61/extern/carve/lib/geom3d.cpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/geom3d.cpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,164 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#if defined(HAVE_CONFIG_H) +# include +#endif + +#include +#include + +#include + +namespace carve { + namespace geom3d { + + namespace { + int is_same(const std::vector &a, + const std::vector &b) { + if (a.size() != b.size()) return false; + + const size_t S = a.size(); + size_t i, j, p; + + for (p = 0; p < S; ++p) { + if (a[0] == b[p]) break; + } + if (p == S) return 0; + + for (i = 1, j = p + 1; j < S; ++i, ++j) if (a[i] != b[j]) goto not_fwd; + for ( j = 0; i < S; ++i, ++j) if (a[i] != b[j]) goto not_fwd; + return +1; + +not_fwd: + for (i = 1, j = p - 1; j != (size_t)-1; ++i, --j) if (a[i] != b[j]) goto not_rev; + for ( j = S - 1; i < S; ++i, --j) if (a[i] != b[j]) goto not_rev; + return -1; + +not_rev: + return 0; + } + } + + bool planeIntersection(const Plane &a, const Plane &b, Ray &r) { + Vector N = cross(a.N, b.N); + if (N.isZero()) { + return false; + } + N.normalize(); + + double dot_aa = dot(a.N, a.N); + double dot_bb = dot(b.N, b.N); + double dot_ab = dot(a.N, b.N); + + double determinant = dot_aa * dot_bb - dot_ab * dot_ab; + + double c1 = ( a.d * dot_bb - b.d * dot_ab) / determinant; + double c2 = ( b.d * dot_aa - a.d * dot_ab) / determinant; + + r.D = N; + r.v = c1 * a.N + c2 * b.N; + + return true; + } + + IntersectionClass rayPlaneIntersection(const Plane &p, + const Vector &v1, + const Vector &v2, + Vector &v, + double &t) { + Vector Rd = v2 - v1; + double Vd = dot(p.N, Rd); + double V0 = dot(p.N, v1) + p.d; + + if (carve::math::ZERO(Vd)) { + if (carve::math::ZERO(V0)) { + return INTERSECT_BAD; + } else { + return INTERSECT_NONE; + } + } + + t = -V0 / Vd; + v = v1 + t * Rd; + return INTERSECT_PLANE; + } + + IntersectionClass lineSegmentPlaneIntersection(const Plane &p, + const LineSegment &line, + Vector &v) { + double t; + IntersectionClass r = rayPlaneIntersection(p, line.v1, line.v2, v, t); + + if (r <= 0) return r; + + if ((t < 0.0 && !equal(v, line.v1)) || (t > 1.0 && !equal(v, line.v2))) + return INTERSECT_NONE; + + return INTERSECT_PLANE; + } + + RayIntersectionClass rayRayIntersection(const Ray &r1, + const Ray &r2, + Vector &v1, + Vector &v2, + double &mu1, + double &mu2) { + if (!r1.OK() || !r2.OK()) return RR_DEGENERATE; + + Vector v_13 = r1.v - r2.v; + + double d1343 = dot(v_13, r2.D); + double d4321 = dot(r2.D, r1.D); + double d1321 = dot(v_13, r1.D); + double d4343 = dot(r2.D, r2.D); + double d2121 = dot(r1.D, r1.D); + + double numer = d1343 * d4321 - d1321 * d4343; + double denom = d2121 * d4343 - d4321 * d4321; + + // dc - eb + // ------- + // ab - cc + + // dc/eb - 1 + // --------- + // a/e - cc/eb + + // dc/b - e + // -------- + // a - cc/b + + // d/b - e/c + // --------- + // a/c - c/b + + if (fabs(denom) * double(1<<10) <= fabs(numer)) { + return RR_PARALLEL; + } + + mu1 = numer / denom; + mu2 = (d1343 + d4321 * mu1) / d4343; + + v1 = r1.v + mu1 * r1.D; + v2 = r2.v + mu2 * r2.D; + + return (equal(v1, v2)) ? RR_INTERSECTION : RR_NO_INTERSECTION; + } + + } +} diff -Nru blender-2.61/extern/carve/lib/intersect_classify_common.hpp blender-2.62/extern/carve/lib/intersect_classify_common.hpp --- blender-2.61/extern/carve/lib/intersect_classify_common.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/intersect_classify_common.hpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,46 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +#include "intersect_common.hpp" + +template +static int is_same(const std::vector &a, + const std::vector &b) { + if (a.size() != b.size()) return false; + + const size_t S = a.size(); + size_t i, j, p; + + for (p = 0; p < S; ++p) { + if (a[0] == b[p]) break; + } + if (p == S) return 0; + + for (i = 1, j = p + 1; j < S; ++i, ++j) if (a[i] != b[j]) goto not_fwd; + for ( j = 0; i < S; ++i, ++j) if (a[i] != b[j]) goto not_fwd; + return +1; + +not_fwd: + for (i = 1, j = p - 1; j != (size_t)-1; ++i, --j) if (a[i] != b[j]) goto not_rev; + for ( j = S - 1; i < S; ++i, --j) if (a[i] != b[j]) goto not_rev; + return -1; + +not_rev: + return 0; +} diff -Nru blender-2.61/extern/carve/lib/intersect_classify_common_impl.hpp blender-2.62/extern/carve/lib/intersect_classify_common_impl.hpp --- blender-2.61/extern/carve/lib/intersect_classify_common_impl.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/intersect_classify_common_impl.hpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,362 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + +namespace carve { + namespace csg { + typedef std::unordered_map< + carve::mesh::MeshSet<3>::vertex_t *, + std::list > GroupLookup; + + + inline bool isSameFwd(const V2Set &a, const V2Set &b) { + if (a.size() != b.size()) return false; + for (V2Set::const_iterator i = a.begin(), e = a.end(); i != e; ++i) { + if (b.find((*i)) == b.end()) return false; + } + return true; + } + + inline bool isSameRev(const V2Set &a, const V2Set &b) { + if (a.size() != b.size()) return false; + for (V2Set::const_iterator i = a.begin(), e = a.end(); i != e; ++i) { + if (b.find(std::make_pair((*i).second, (*i).first)) == b.end()) return false; + } + return true; + } + + + static void performClassifySimpleOnFaceGroups(FLGroupList &a_groups, + FLGroupList &b_groups, + carve::mesh::MeshSet<3> *poly_a, + carve::mesh::MeshSet<3> *poly_b, + CSG::Collector &collector, + CSG::Hooks &hooks) { + // Simple ON faces groups are face groups that consist of a single + // face, and which have copy in both inputs. These are trivially ON. + // This has the side effect of short circuiting the case where the + // two inputs share geometry. + GroupLookup a_map, b_map; + + // First, hash FaceLoopGroups with one FaceLoop based upon their + // minimum vertex pointer - this pointer must be shared between + // FaceLoops that this test catches. + for (FLGroupList::iterator i = a_groups.begin(); i != a_groups.end(); ++i) { + if ((*i).face_loops.size() != 1) continue; + FaceLoop *f = (*i).face_loops.head; + carve::mesh::MeshSet<3>::vertex_t *v = *std::min_element(f->vertices.begin(), f->vertices.end()); + a_map[v].push_back(i); + } + + for (FLGroupList::iterator i = b_groups.begin(); i != b_groups.end(); ++i) { + if ((*i).face_loops.size() != 1) continue; + FaceLoop *f = (*i).face_loops.head; + carve::mesh::MeshSet<3>::vertex_t *v = *std::min_element(f->vertices.begin(), f->vertices.end()); + if (a_map.find(v) != a_map.end()) { + b_map[v].push_back(i); + } + } + + // Then, iterate through the FaceLoops hashed in the first map, and + // find candidate matches in the second map. + for (GroupLookup::iterator j = b_map.begin(), je = b_map.end(); j != je; ++j) { + carve::mesh::MeshSet<3>::vertex_t *v = (*j).first; + GroupLookup::iterator i = a_map.find(v); + + for (std::list::iterator bi = (*j).second.begin(), be = (*j).second.end(); bi != be;) { + FLGroupList::iterator b(*bi); + FaceLoop *f_b = (*b).face_loops.head; + + // For each candidate match pair, see if their vertex pointers + // are the same, allowing for rotation and inversion. + for (std::list::iterator ai = (*i).second.begin(), ae = (*i).second.end(); ai != ae; ++ai) { + FLGroupList::iterator a(*ai); + FaceLoop *f_a = (*a).face_loops.head; + + int s = is_same(f_a->vertices, f_b->vertices); + if (!s) continue; + + // if they are ordered in the same direction, then they are + // oriented out, otherwise oriented in. + FaceClass fc = s == +1 ? FACE_ON_ORIENT_OUT : FACE_ON_ORIENT_IN; + + (*a).classification.push_back(ClassificationInfo(NULL, fc)); + (*b).classification.push_back(ClassificationInfo(NULL, fc)); + + collector.collect(&*a, hooks); + collector.collect(&*b, hooks); + + a_groups.erase(a); + b_groups.erase(b); + + (*i).second.erase(ai); + bi = (*j).second.erase(bi); + + goto done; + } + ++bi; + done:; + } + } + } + + template + static void performClassifyEasyFaceGroups(FLGroupList &group, + carve::mesh::MeshSet<3> *poly_a, + const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *poly_a_rtree, + VertexClassification &vclass, + const CLASSIFIER &classifier, + CSG::Collector &collector, + CSG::Hooks &hooks) { + + for (FLGroupList::iterator i = group.begin(); i != group.end();) { +#if defined(CARVE_DEBUG) + std::cerr << "............group " << &(*i) << std::endl; +#endif + FaceLoopGroup &grp = (*i); + FaceLoopList &curr = (grp.face_loops); + FaceClass fc; + + for (FaceLoop *f = curr.head; f; f = f->next) { + for (size_t j = 0; j < f->vertices.size(); ++j) { + if (!classifier.pointOn(vclass, f, j)) { + PointClass pc = carve::mesh::classifyPoint(poly_a, poly_a_rtree, f->vertices[j]->v); + if (pc == POINT_IN || pc == POINT_OUT) { + classifier.explain(f, j, pc); + } + if (pc == POINT_IN) { fc = FACE_IN; goto accept; } + if (pc == POINT_OUT) { fc = FACE_OUT; goto accept; } + } + } + } + ++i; + continue; + accept: { + grp.classification.push_back(ClassificationInfo(NULL, fc)); + collector.collect(&grp, hooks); + i = group.erase(i); + } + } + } + + + template + static void performClassifyHardFaceGroups(FLGroupList &group, + carve::mesh::MeshSet<3> *poly_a, + const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *poly_a_rtree, + const CLASSIFIER & /* classifier */, + CSG::Collector &collector, + CSG::Hooks &hooks) { + for (FLGroupList::iterator + i = group.begin(); i != group.end();) { + int n_in = 0, n_out = 0, n_on = 0; + FaceLoopGroup &grp = (*i); + FaceLoopList &curr = (grp.face_loops); + V2Set &perim = ((*i).perimeter); + FaceClass fc =FACE_UNCLASSIFIED; + + for (FaceLoop *f = curr.head; f; f = f->next) { + carve::mesh::MeshSet<3>::vertex_t *v1, *v2; + v1 = f->vertices.back(); + for (size_t j = 0; j < f->vertices.size(); ++j) { + v2 = f->vertices[j]; + if (v1 < v2 && perim.find(std::make_pair(v1, v2)) == perim.end()) { + carve::geom3d::Vector c = (v1->v + v2->v) / 2.0; + + PointClass pc = carve::mesh::classifyPoint(poly_a, poly_a_rtree, c); + + switch (pc) { + case POINT_IN: n_in++; break; + case POINT_OUT: n_out++; break; + case POINT_ON: n_on++; break; + default: break; // does not happen. + } + } + v1 = v2; + } + } + +#if defined(CARVE_DEBUG) + std::cerr << ">>> n_in: " << n_in << " n_on: " << n_on << " n_out: " << n_out << std::endl; +#endif + + if (!n_in && !n_out) { + ++i; + continue; + } + + if (n_in) fc = FACE_IN; + if (n_out) fc = FACE_OUT; + + grp.classification.push_back(ClassificationInfo(NULL, fc)); + collector.collect(&grp, hooks); + i = group.erase(i); + } + } + + template + void performFaceLoopWork(carve::mesh::MeshSet<3> *poly_a, + const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *poly_a_rtree, + FLGroupList &b_loops_grouped, + const CLASSIFIER &classifier, + CSG::Collector &collector, + CSG::Hooks &hooks) { + for (FLGroupList::iterator i = b_loops_grouped.begin(), e = b_loops_grouped.end(); i != e;) { + FaceClass fc; + + if (classifier.faceLoopSanityChecker(*i)) { + std::cerr << "UNEXPECTED face loop with size != 1." << std::endl; + ++i; + continue; + } + CARVE_ASSERT((*i).face_loops.size() == 1); + + FaceLoop *fla = (*i).face_loops.head; + + const carve::mesh::MeshSet<3>::face_t *f = (fla->orig_face); + std::vector::vertex_t *> &loop = (fla->vertices); + std::vector proj; + proj.reserve(loop.size()); + for (unsigned j = 0; j < loop.size(); ++j) { + proj.push_back(f->project(loop[j]->v)); + } + carve::geom2d::P2 pv; + if (!carve::geom2d::pickContainedPoint(proj, pv)) { + CARVE_FAIL("Failed"); + } + carve::geom3d::Vector v = f->unproject(pv, f->plane); + + const carve::mesh::MeshSet<3>::face_t *hit_face; + PointClass pc = carve::mesh::classifyPoint(poly_a, poly_a_rtree, v, false, NULL, &hit_face); + switch (pc) { + case POINT_IN: fc = FACE_IN; break; + case POINT_OUT: fc = FACE_OUT; break; + case POINT_ON: { + double d = carve::geom::distance(hit_face->plane, v); +#if defined(CARVE_DEBUG) + std::cerr << "d = " << d << std::endl; +#endif + fc = d < 0 ? FACE_IN : FACE_OUT; + break; + } + default: + CARVE_FAIL("unhandled switch case -- should not happen"); + } +#if defined(CARVE_DEBUG) + std::cerr << "CLASS: " << (fc == FACE_IN ? "FACE_IN" : "FACE_OUT" ) << std::endl; +#endif + + (*i).classification.push_back(ClassificationInfo(NULL, fc)); + collector.collect(&*i, hooks); + i = b_loops_grouped.erase(i); + } + + } + + template + void performClassifyFaceGroups(FLGroupList &a_loops_grouped, + FLGroupList &b_loops_grouped, + VertexClassification &vclass, + carve::mesh::MeshSet<3> *poly_a, + const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *poly_a_rtree, + carve::mesh::MeshSet<3> *poly_b, + const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *poly_b_rtree, + const CLASSIFIER &classifier, + CSG::Collector &collector, + CSG::Hooks &hooks) { + + classifier.classifySimple(a_loops_grouped, b_loops_grouped, vclass, poly_a, poly_b); + classifier.classifyEasy(a_loops_grouped, b_loops_grouped, vclass, poly_a, poly_a_rtree, poly_b, poly_b_rtree); + classifier.classifyHard(a_loops_grouped, b_loops_grouped, vclass, poly_a, poly_a_rtree, poly_b, poly_b_rtree); + + { + GroupLookup a_map; + FLGroupList::iterator i, j; + FaceClass fc; + + for (i = a_loops_grouped.begin(); i != a_loops_grouped.end(); ++i) { + V2Set::iterator it_end = (*i).perimeter.end(); + V2Set::iterator it_begin = (*i).perimeter.begin(); + + if(it_begin != it_end) { + a_map[std::min_element(it_begin, it_end)->first].push_back(i); + } + } + + for (i = b_loops_grouped.begin(); i != b_loops_grouped.end();) { + GroupLookup::iterator a = a_map.end(); + + V2Set::iterator it_end = (*i).perimeter.end(); + V2Set::iterator it_begin = (*i).perimeter.begin(); + + if(it_begin != it_end) { + a = a_map.find(std::min_element(it_begin, it_end)->first); + } + + if (a == a_map.end()) { ++i; continue; } + + for (std::list::iterator ji = (*a).second.begin(), je = (*a).second.end(); ji != je; ++ji) { + j = (*ji); + if (isSameFwd((*i).perimeter, (*j).perimeter)) { +#if defined(CARVE_DEBUG) + std::cerr << "SAME FWD PAIR" << std::endl; +#endif + fc = FACE_ON_ORIENT_OUT; + goto face_pair; + } else if (isSameRev((*i).perimeter, (*j).perimeter)) { +#if defined(CARVE_DEBUG) + std::cerr << "SAME REV PAIR" << std::endl; +#endif + fc = FACE_ON_ORIENT_IN; + goto face_pair; + } + } + ++i; + continue; + + face_pair: { + V2Set::iterator it_end = (*j).perimeter.end(); + V2Set::iterator it_begin = (*j).perimeter.begin(); + + if(it_begin != it_end) { + a_map[std::min_element(it_begin, it_end)->first].remove(j); + } + + (*i).classification.push_back(ClassificationInfo(NULL, fc)); + (*j).classification.push_back(ClassificationInfo(NULL, fc)); + + collector.collect(&*i, hooks); + collector.collect(&*j, hooks); + + j = a_loops_grouped.erase(j); + i = b_loops_grouped.erase(i); + } + } + } + + // XXX: this may leave some face groups that are IN or OUT, and + // consist of a single face loop. + classifier.postRemovalCheck(a_loops_grouped, b_loops_grouped); + + classifier.faceLoopWork(a_loops_grouped, b_loops_grouped, vclass, poly_a, poly_a_rtree, poly_b, poly_b_rtree); + + classifier.finish(a_loops_grouped, b_loops_grouped); + } + + } +} diff -Nru blender-2.61/extern/carve/lib/intersect_classify_edge.cpp blender-2.62/extern/carve/lib/intersect_classify_edge.cpp --- blender-2.61/extern/carve/lib/intersect_classify_edge.cpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/intersect_classify_edge.cpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,820 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#if defined(HAVE_CONFIG_H) +# include +#endif + +#if defined(HAVE_STDINT_H) +#include +#endif + +#include +#include +#include + +#include +#include +#include + +#include + +#include "csg_detail.hpp" + +#include "intersect_common.hpp" +#include "intersect_classify_common.hpp" + +#define ANGLE_EPSILON 1e-6 + +namespace carve { + namespace csg { + + namespace { + + inline bool single_bit_set(uint32_t v) { + v &= v - 1; + return v == 0; + } + + struct EdgeSurface { + FaceLoop *fwd; + double fwd_ang; + FaceLoop *rev; + double rev_ang; + + EdgeSurface() : fwd(NULL), fwd_ang(0.0), rev(NULL), rev_ang(0.0) { } + }; + + + typedef std::map::mesh_t *, EdgeSurface> GrpEdgeSurfMap; + + typedef std::pair::mesh_t *> ClassificationKey; + + struct ClassificationData { + uint32_t class_bits : 5; + uint32_t class_decided : 1; + + int c[5]; + + ClassificationData() { + class_bits = FACE_ANY_BIT; + class_decided = 0; + memset(c, 0, sizeof(c)); + } + }; + + struct hash_classification { + size_t operator()(const ClassificationKey &f) const { + return (size_t)f.first ^ (size_t)f.second; + } + }; + + typedef std::unordered_map Classification; + + + struct hash_group_ptr { + size_t operator()(const FaceLoopGroup * const &f) const { + return (size_t)f; + } + }; + + + typedef std::pair::vertex_t *> PerimKey; + + struct hash_perim_key { + size_t operator()(const PerimKey &v) const { + return (size_t)v.first ^ (size_t)v.second; + } + }; + + typedef std::unordered_map::vertex_t *>, + std::unordered_set, + hash_perim_key> PerimMap; + + + + struct hash_group_pair { + size_t operator()(const std::pair &v) const { + return (size_t)v.first ^ (size_t)v.second; + } + }; + + typedef std::unordered_map, hash_group_pair>, + hash_group_ptr> CandidateOnMap; + + + + static inline void remove(carve::mesh::MeshSet<3>::vertex_t *a, + carve::mesh::MeshSet<3>::vertex_t *b, + carve::csg::detail::VVSMap &shared_edge_graph) { + carve::csg::detail::VVSMap::iterator i = shared_edge_graph.find(a); + CARVE_ASSERT(i != shared_edge_graph.end()); + size_t n = (*i).second.erase(b); + CARVE_ASSERT(n == 1); + if ((*i).second.size() == 0) shared_edge_graph.erase(i); + } + + + + static inline void remove(V2 edge, + carve::csg::detail::VVSMap &shared_edge_graph) { + remove(edge.first, edge.second, shared_edge_graph); + remove(edge.second, edge.first, shared_edge_graph); + } + + + + static void walkGraphSegment(carve::csg::detail::VVSMap &shared_edge_graph, + const carve::csg::detail::VSet &branch_points, + V2 initial, + const carve::csg::detail::LoopEdges & /* a_edge_map */, + const carve::csg::detail::LoopEdges & /* b_edge_map */, + std::list &out) { + V2 curr; + curr = initial; + bool closed = false; + + out.clear(); + for (;;) { + // walk forward. + out.push_back(curr); + remove(curr, shared_edge_graph); + + if (curr.second == initial.first) { closed = true; break; } + if (branch_points.find(curr.second) != branch_points.end()) break; + carve::csg::detail::VVSMap::const_iterator o = shared_edge_graph.find(curr.second); + if (o == shared_edge_graph.end()) break; + CARVE_ASSERT((*o).second.size() == 1); + curr.first = curr.second; + curr.second = *((*o).second.begin()); + // test here that the set of incident groups hasn't changed. + } + + if (!closed) { + // walk backward. + curr = initial; + for (;;) { + if (branch_points.find(curr.first) != branch_points.end()) break; + carve::csg::detail::VVSMap::const_iterator o = shared_edge_graph.find(curr.first); + if (o == shared_edge_graph.end()) break; + curr.second = curr.first; + curr.first = *((*o).second.begin()); + // test here that the set of incident groups hasn't changed. + + out.push_front(curr); + remove(curr, shared_edge_graph); + } + } + +#if defined(CARVE_DEBUG) + std::cerr << "intersection segment: " << out.size() << " edges." << std::endl; +#if defined(DEBUG_DRAW_INTERSECTION_LINE) + { + static float H = 0.0, S = 1.0, V = 1.0; + float r, g, b; + + H = fmod((H + .37), 1.0); + S = 0.5 + fmod((S - 0.37), 0.5); + carve::colour::HSV2RGB(H, S, V, r, g, b); + + if (out.size() > 1) { + drawEdges(out.begin(), ++out.begin(), + 0.0, 0.0, 0.0, 1.0, + r, g, b, 1.0, + 3.0); + drawEdges(++out.begin(), --out.end(), + r, g, b, 1.0, + r, g, b, 1.0, + 3.0); + drawEdges(--out.end(), out.end(), + r, g, b, 1.0, + 1.0, 1.0, 1.0, 1.0, + 3.0); + } else { + drawEdges(out.begin(), out.end(), + r, g, b, 1.0, + r, g, b, 1.0, + 3.0); + } + } +#endif +#endif + } + + + + static carve::geom3d::Vector perpendicular(const carve::geom3d::Vector &v) { + if (fabs(v.x) < fabs(v.y)) { + if (fabs(v.x) < fabs(v.z)) { + return cross(v, carve::geom::VECTOR(1.0, 0.0, 0.0)).normalized(); + } else { + return cross(v, carve::geom::VECTOR(0.0, 0.0, 1.0)).normalized(); + } + } else { + if (fabs(v.y) < fabs(v.z)) { + return cross(v, carve::geom::VECTOR(0.0, 1.0, 0.0)).normalized(); + } else { + return cross(v, carve::geom::VECTOR(1.0, 0.0, 1.0)).normalized(); + } + } + } + + + + static void classifyAB(const GrpEdgeSurfMap &a_edge_surfaces, + const GrpEdgeSurfMap &b_edge_surfaces, + Classification &classifications) { + // two faces in the a surface + for (GrpEdgeSurfMap::const_iterator ib = b_edge_surfaces.begin(), eb = b_edge_surfaces.end(); ib != eb; ++ib) { + + if ((*ib).second.fwd) { + FaceLoopGroup *b_grp = ((*ib).second.fwd->group); + + for (GrpEdgeSurfMap::const_iterator ia = a_edge_surfaces.begin(), ea = a_edge_surfaces.end(); ia != ea; ++ia) { + + if ((*ia).second.fwd && (*ia).second.rev) { + const carve::mesh::MeshSet<3>::mesh_t *a_gid = (*ia).first; + + ClassificationData &data = classifications[std::make_pair(b_grp, a_gid)]; + if (data.class_decided) continue; + + // an angle between (*ia).fwd_ang and (*ia).rev_ang is outside/above group a. + FaceClass fc; + + if (fabs((*ib).second.fwd_ang - (*ia).second.fwd_ang) < ANGLE_EPSILON) { + fc = FACE_ON_ORIENT_OUT; + } else if (fabs((*ib).second.fwd_ang - (*ia).second.rev_ang) < ANGLE_EPSILON) { + fc = FACE_ON_ORIENT_IN; + } else { + double a1 = (*ia).second.fwd_ang; + double a2 = (*ia).second.rev_ang; + if (a1 < a2) { + if (a1 < (*ib).second.fwd_ang && (*ib).second.fwd_ang < a2) { + fc = FACE_IN; + } else { + fc = FACE_OUT; + } + } else { + if (a2 < (*ib).second.fwd_ang && (*ib).second.fwd_ang < a1) { + fc = FACE_OUT; + } else { + fc = FACE_IN; + } + } + } + data.c[fc + 2]++; + } + } + } + + if ((*ib).second.rev) { + FaceLoopGroup *b_grp = ((*ib).second.rev->group); + + for (GrpEdgeSurfMap::const_iterator ia = a_edge_surfaces.begin(), ea = a_edge_surfaces.end(); ia != ea; ++ia) { + + if ((*ia).second.fwd && (*ia).second.rev) { + const carve::mesh::MeshSet<3>::mesh_t *a_gid = (*ia).first; + + ClassificationData &data = (classifications[std::make_pair(b_grp, a_gid)]); + if (data.class_decided) continue; + + // an angle between (*ia).fwd_ang and (*ia).rev_ang is outside/above group a. + FaceClass fc; + + if (fabs((*ib).second.rev_ang - (*ia).second.fwd_ang) < ANGLE_EPSILON) { + fc = FACE_ON_ORIENT_IN; + } else if (fabs((*ib).second.rev_ang - (*ia).second.rev_ang) < ANGLE_EPSILON) { + fc = FACE_ON_ORIENT_OUT; + } else { + double a1 = (*ia).second.fwd_ang; + double a2 = (*ia).second.rev_ang; + if (a1 < a2) { + if (a1 < (*ib).second.rev_ang && (*ib).second.rev_ang < a2) { + fc = FACE_IN; + } else { + fc = FACE_OUT; + } + } else { + if (a2 < (*ib).second.rev_ang && (*ib).second.rev_ang < a1) { + fc = FACE_OUT; + } else { + fc = FACE_IN; + } + } + } + data.c[fc + 2]++; + } + } + } + } + } + + + static bool processForwardEdgeSurfaces(GrpEdgeSurfMap &edge_surfaces, + const std::list &fwd, + const carve::geom3d::Vector &edge_vector, + const carve::geom3d::Vector &base_vector) { + for (std::list::const_iterator i = fwd.begin(), e = fwd.end(); i != e; ++i) { + EdgeSurface &es = (edge_surfaces[(*i)->orig_face->mesh]); + if (es.fwd != NULL) return false; + es.fwd = (*i); + es.fwd_ang = carve::geom3d::antiClockwiseAngle((*i)->orig_face->plane.N, base_vector, edge_vector); + } + return true; + } + + static bool processReverseEdgeSurfaces(GrpEdgeSurfMap &edge_surfaces, + const std::list &rev, + const carve::geom3d::Vector &edge_vector, + const carve::geom3d::Vector &base_vector) { + for (std::list::const_iterator i = rev.begin(), e = rev.end(); i != e; ++i) { + EdgeSurface &es = (edge_surfaces[(*i)->orig_face->mesh]); + if (es.rev != NULL) return false; + es.rev = (*i); + es.rev_ang = carve::geom3d::antiClockwiseAngle(-(*i)->orig_face->plane.N, base_vector, edge_vector); + } + return true; + } + + + + static void processOneEdge(const V2 &edge, + const carve::csg::detail::LoopEdges &a_edge_map, + const carve::csg::detail::LoopEdges &b_edge_map, + Classification &a_classification, + Classification &b_classification) { + GrpEdgeSurfMap a_edge_surfaces; + GrpEdgeSurfMap b_edge_surfaces; + + carve::geom3d::Vector edge_vector = (edge.second->v - edge.first->v).normalized(); + carve::geom3d::Vector base_vector = perpendicular(edge_vector); + + carve::csg::detail::LoopEdges::const_iterator ae_f = a_edge_map.find(edge); + carve::csg::detail::LoopEdges::const_iterator ae_r = a_edge_map.find(flip(edge)); + CARVE_ASSERT(ae_f != a_edge_map.end() || ae_r != a_edge_map.end()); + + carve::csg::detail::LoopEdges::const_iterator be_f = b_edge_map.find(edge); + carve::csg::detail::LoopEdges::const_iterator be_r = b_edge_map.find(flip(edge)); + CARVE_ASSERT(be_f != b_edge_map.end() || be_r != b_edge_map.end()); + + if (ae_f != a_edge_map.end() && !processForwardEdgeSurfaces(a_edge_surfaces, (*ae_f).second, edge_vector, base_vector)) return; + if (ae_r != a_edge_map.end() && !processReverseEdgeSurfaces(a_edge_surfaces, (*ae_r).second, edge_vector, base_vector)) return; + if (be_f != b_edge_map.end() && !processForwardEdgeSurfaces(b_edge_surfaces, (*be_f).second, edge_vector, base_vector)) return; + if (be_r != b_edge_map.end() && !processReverseEdgeSurfaces(b_edge_surfaces, (*be_r).second, edge_vector, base_vector)) return; + + classifyAB(a_edge_surfaces, b_edge_surfaces, b_classification); + classifyAB(b_edge_surfaces, a_edge_surfaces, a_classification); + } + + + + static void traceIntersectionGraph(const V2Set &shared_edges, + const FLGroupList & /* a_loops_grouped */, + const FLGroupList & /* b_loops_grouped */, + const carve::csg::detail::LoopEdges &a_edge_map, + const carve::csg::detail::LoopEdges &b_edge_map) { + + carve::csg::detail::VVSMap shared_edge_graph; + carve::csg::detail::VSet branch_points; + + // first, make the intersection graph. + for (V2Set::const_iterator i = shared_edges.begin(); i != shared_edges.end(); ++i) { + const V2Set::key_type &edge = (*i); + carve::csg::detail::VVSMap::mapped_type &out = (shared_edge_graph[edge.first]); + out.insert(edge.second); + if (out.size() == 3) branch_points.insert(edge.first); + +#if defined(CARVE_DEBUG) && defined(DEBUG_DRAW_INTERSECTION_LINE) + HOOK(drawEdge(edge.first, edge.second, 1, 1, 1, 1, 1, 1, 1, 1, 1.0);); +#endif + } +#if defined(CARVE_DEBUG) + std::cerr << "graph nodes: " << shared_edge_graph.size() << std::endl; + std::cerr << "branch nodes: " << branch_points.size() << std::endl; +#endif + + std::list out; + while (shared_edge_graph.size()) { + carve::csg::detail::VVSMap::iterator i = shared_edge_graph.begin(); + carve::mesh::MeshSet<3>::vertex_t *v1 = (*i).first; + carve::mesh::MeshSet<3>::vertex_t *v2 = *((*i).second.begin()); + walkGraphSegment(shared_edge_graph, branch_points, V2(v1, v2), a_edge_map, b_edge_map, out); + } + } + + void hashByPerimeter(FLGroupList &grp, PerimMap &perim_map) { + for (FLGroupList::iterator i = grp.begin(); i != grp.end(); ++i) { + size_t perim_size = (*i).perimeter.size(); + // can be the case for non intersecting groups. (and groups that intersect at a point?) + if (!perim_size) continue; + const carve::mesh::MeshSet<3>::vertex_t *perim_min = std::min_element((*i).perimeter.begin(), (*i).perimeter.end())->first; + perim_map[std::make_pair(perim_size, perim_min)].insert(&(*i)); + } + } + + + + bool same_edge_set_fwd(const V2Set &a, const V2Set &b) { + if (a.size() != b.size()) return false; + for (V2Set::const_iterator i = a.begin(), e = a.end(); i != e; ++i) { + if (b.find(*i) == b.end()) return false; + } + return true; + } + + + + bool same_edge_set_rev(const V2Set &a, const V2Set &b) { + if (a.size() != b.size()) return false; + for (V2Set::const_iterator i = a.begin(), e = a.end(); i != e; ++i) { + if (b.find(std::make_pair((*i).second, (*i).first)) == b.end()) return false; + } + return true; + } + + + + int same_edge_set(const V2Set &a, const V2Set &b) { + if (same_edge_set_fwd(a, b)) return +1; + if (same_edge_set_rev(a, b)) return -1; + return 0; + } + + + + void generateCandidateOnSets(FLGroupList &a_grp, + FLGroupList &b_grp, + CandidateOnMap &candidate_on_map, + Classification &a_classification, + Classification &b_classification) { + PerimMap a_grp_by_perim, b_grp_by_perim; + + hashByPerimeter(a_grp, a_grp_by_perim); + hashByPerimeter(b_grp, b_grp_by_perim); + + for (PerimMap::iterator i = a_grp_by_perim.begin(), ie = a_grp_by_perim.end(); i != ie; ++i) { + PerimMap::iterator j = b_grp_by_perim.find((*i).first); + if (j == b_grp_by_perim.end()) continue; + + for (PerimMap::mapped_type::iterator a = (*i).second.begin(), ae = (*i).second.end(); a != ae; ++a) { + for (PerimMap::mapped_type::iterator b = (*j).second.begin(), be = (*j).second.end(); b != be; ++b) { + int x = same_edge_set((*a)->perimeter, (*b)->perimeter); + if (!x) continue; + candidate_on_map[(*a)].insert(std::make_pair(x, (*b))); + if ((*a)->face_loops.count == 1 && (*b)->face_loops.count == 1) { + uint32_t fcb = x == +1 ? FACE_ON_ORIENT_OUT_BIT : FACE_ON_ORIENT_IN_BIT; + +#if defined(CARVE_DEBUG) + std::cerr << "paired groups: " << (*a) << ", " << (*b) << std::endl; +#endif + + ClassificationData &a_data = a_classification[std::make_pair((*a), (*b)->face_loops.head->orig_face->mesh)]; + a_data.class_bits = fcb; a_data.class_decided = 1; + + ClassificationData &b_data = b_classification[std::make_pair((*b), (*a)->face_loops.head->orig_face->mesh)]; + b_data.class_bits = fcb; b_data.class_decided = 1; + } + } + } + } + } + + } + + + static inline std::string CODE(const FaceLoopGroup *grp) { + const std::list &cinfo = (grp->classification); + if (cinfo.size() == 0) { + return "?"; + } + + FaceClass fc = FACE_UNCLASSIFIED; + + for (std::list::const_iterator i = grp->classification.begin(), e = grp->classification.end(); i != e; ++i) { + if ((*i).intersected_mesh == NULL) { + // classifier only returns global info + fc = (*i).classification; + break; + } + + if ((*i).intersectedMeshIsClosed()) { + if ((*i).classification == FACE_UNCLASSIFIED) continue; + if (fc == FACE_UNCLASSIFIED) { + fc = (*i).classification; + } else if (fc != (*i).classification) { + return "X"; + } + } + } + if (fc == FACE_IN) return "I"; + if (fc == FACE_ON_ORIENT_IN) return "<"; + if (fc == FACE_ON_ORIENT_OUT) return ">"; + if (fc == FACE_OUT) return "O"; + return "*"; + } + + void CSG::classifyFaceGroupsEdge(const V2Set &shared_edges, + VertexClassification &vclass, + carve::mesh::MeshSet<3> *poly_a, + const face_rtree_t *poly_a_rtree, + FLGroupList &a_loops_grouped, + const detail::LoopEdges &a_edge_map, + carve::mesh::MeshSet<3> *poly_b, + const face_rtree_t *poly_b_rtree, + FLGroupList &b_loops_grouped, + const detail::LoopEdges &b_edge_map, + CSG::Collector &collector) { + Classification a_classification; + Classification b_classification; + + CandidateOnMap candidate_on_map; + +#if defined(CARVE_DEBUG) + std::cerr << "a input loops (" << a_loops_grouped.size() << "): "; + for (FLGroupList::iterator i = a_loops_grouped.begin(); i != a_loops_grouped.end(); ++i) { + std::cerr << &*i << " "; + } + std::cerr << std::endl; + std::cerr << "b input loops (" << b_loops_grouped.size() << "): "; + for (FLGroupList::iterator i = b_loops_grouped.begin(); i != b_loops_grouped.end(); ++i) { + std::cerr << &*i << " "; + } + std::cerr << std::endl; +#endif + +#if defined(DISPLAY_GRP_GRAPH) + // XXX: this is hopelessly inefficient. + std::map > grp_graph_fwd, grp_graph_rev; + { + for (FLGroupList::iterator i = a_loops_grouped.begin(); i != a_loops_grouped.end(); ++i) { + FaceLoopGroup *src = &(*i); + for (V2Set::const_iterator k = src->perimeter.begin(); k != src->perimeter.end(); ++k) { + V2 fwd = *k; + V2 rev = std::make_pair(fwd.second, fwd.first); + for (FLGroupList::iterator j = a_loops_grouped.begin(); j != a_loops_grouped.end(); ++j) { + FaceLoopGroup *tgt = &(*j); + if (tgt->perimeter.find(fwd) != tgt->perimeter.end()) { grp_graph_fwd[src].insert(tgt); } + if (tgt->perimeter.find(rev) != tgt->perimeter.end()) { grp_graph_rev[src].insert(tgt); } + } + for (FLGroupList::iterator j = b_loops_grouped.begin(); j != b_loops_grouped.end(); ++j) { + FaceLoopGroup *tgt = &(*j); + if (tgt->perimeter.find(fwd) != tgt->perimeter.end()) { grp_graph_fwd[src].insert(tgt); } + if (tgt->perimeter.find(rev) != tgt->perimeter.end()) { grp_graph_rev[src].insert(tgt); } + } + } + } + for (FLGroupList::iterator i = b_loops_grouped.begin(); i != b_loops_grouped.end(); ++i) { + FaceLoopGroup *src = &(*i); + for (V2Set::const_iterator k = src->perimeter.begin(); k != src->perimeter.end(); ++k) { + V2 fwd = *k; + V2 rev = std::make_pair(fwd.second, fwd.first); + for (FLGroupList::iterator j = a_loops_grouped.begin(); j != a_loops_grouped.end(); ++j) { + FaceLoopGroup *tgt = &(*j); + if (tgt->perimeter.find(fwd) != tgt->perimeter.end()) { grp_graph_fwd[src].insert(tgt); } + if (tgt->perimeter.find(rev) != tgt->perimeter.end()) { grp_graph_rev[src].insert(tgt); } + } + for (FLGroupList::iterator j = b_loops_grouped.begin(); j != b_loops_grouped.end(); ++j) { + FaceLoopGroup *tgt = &(*j); + if (tgt->perimeter.find(fwd) != tgt->perimeter.end()) { grp_graph_fwd[src].insert(tgt); } + if (tgt->perimeter.find(rev) != tgt->perimeter.end()) { grp_graph_rev[src].insert(tgt); } + } + } + } + } +#endif + + generateCandidateOnSets(a_loops_grouped, b_loops_grouped, candidate_on_map, a_classification, b_classification); + + + for (V2Set::const_iterator i = shared_edges.begin(); i != shared_edges.end(); ++i) { + const V2 &edge = (*i); + processOneEdge(edge, a_edge_map, b_edge_map, a_classification, b_classification); + } + + + for (Classification::iterator i = a_classification.begin(), e = a_classification.end(); i != e; ++i) { + if (!(*i).second.class_decided) { + if ((*i).second.c[FACE_IN + 2] == 0) (*i).second.class_bits &= ~ FACE_IN_BIT; + if ((*i).second.c[FACE_ON_ORIENT_IN + 2] == 0) (*i).second.class_bits &= ~ FACE_ON_ORIENT_IN_BIT; + if ((*i).second.c[FACE_ON_ORIENT_OUT + 2] == 0) (*i).second.class_bits &= ~ FACE_ON_ORIENT_OUT_BIT; + if ((*i).second.c[FACE_OUT + 2] == 0) (*i).second.class_bits &= ~ FACE_OUT_BIT; + + // XXX: this is the wrong thing to do. It's intended just as a test. + if ((*i).second.class_bits == (FACE_IN_BIT | FACE_OUT_BIT)) { + if ((*i).second.c[FACE_OUT + 2] > (*i).second.c[FACE_IN + 2]) { + (*i).second.class_bits = FACE_OUT_BIT; + } else { + (*i).second.class_bits = FACE_IN_BIT; + } + } + + if (single_bit_set((*i).second.class_bits)) (*i).second.class_decided = 1; + } + } + + for (Classification::iterator i = b_classification.begin(), e = b_classification.end(); i != e; ++i) { + if (!(*i).second.class_decided) { + if ((*i).second.c[FACE_IN + 2] == 0) (*i).second.class_bits &= ~ FACE_IN_BIT; + if ((*i).second.c[FACE_ON_ORIENT_IN + 2] == 0) (*i).second.class_bits &= ~ FACE_ON_ORIENT_IN_BIT; + if ((*i).second.c[FACE_ON_ORIENT_OUT + 2] == 0) (*i).second.class_bits &= ~ FACE_ON_ORIENT_OUT_BIT; + if ((*i).second.c[FACE_OUT + 2] == 0) (*i).second.class_bits &= ~ FACE_OUT_BIT; + + // XXX: this is the wrong thing to do. It's intended just as a test. + if ((*i).second.class_bits == (FACE_IN_BIT | FACE_OUT_BIT)) { + if ((*i).second.c[FACE_OUT + 2] > (*i).second.c[FACE_IN + 2]) { + (*i).second.class_bits = FACE_OUT_BIT; + } else { + (*i).second.class_bits = FACE_IN_BIT; + } + } + + if (single_bit_set((*i).second.class_bits)) (*i).second.class_decided = 1; + } + } + + +#if defined(CARVE_DEBUG) + std::cerr << "poly a:" << std::endl; + for (Classification::iterator i = a_classification.begin(), e = a_classification.end(); i != e; ++i) { + FaceLoopGroup *grp = ((*i).first.first); + + std::cerr << " group: " << grp << " gid: " << (*i).first.second + << " " + << ((*i).second.class_decided ? "+" : "-") + << " " + << ((*i).second.class_bits & FACE_IN_BIT ? "I" : ".") + << ((*i).second.class_bits & FACE_ON_ORIENT_IN_BIT ? "<" : ".") + << ((*i).second.class_bits & FACE_ON_ORIENT_OUT_BIT ? ">" : ".") + << ((*i).second.class_bits & FACE_OUT_BIT ? "O" : ".") + << " [" + << std::setw(4) << (*i).second.c[0] << " " + << std::setw(4) << (*i).second.c[1] << " " + << std::setw(4) << (*i).second.c[2] << " " + << std::setw(4) << (*i).second.c[3] << " " + << std::setw(4) << (*i).second.c[4] << "]" << std::endl; + } + + std::cerr << "poly b:" << std::endl; + for (Classification::iterator i = b_classification.begin(), e = b_classification.end(); i != e; ++i) { + FaceLoopGroup *grp = ((*i).first.first); + + std::cerr << " group: " << grp << " gid: " << (*i).first.second + << " " + << ((*i).second.class_decided ? "+" : "-") + << " " + << ((*i).second.class_bits & FACE_IN_BIT ? "I" : ".") + << ((*i).second.class_bits & FACE_ON_ORIENT_IN_BIT ? "<" : ".") + << ((*i).second.class_bits & FACE_ON_ORIENT_OUT_BIT ? ">" : ".") + << ((*i).second.class_bits & FACE_OUT_BIT ? "O" : ".") + << " [" + << std::setw(4) << (*i).second.c[0] << " " + << std::setw(4) << (*i).second.c[1] << " " + << std::setw(4) << (*i).second.c[2] << " " + << std::setw(4) << (*i).second.c[3] << " " + << std::setw(4) << (*i).second.c[4] << "]" << std::endl; + } +#endif + + for (Classification::iterator i = a_classification.begin(), e = a_classification.end(); i != e; ++i) { + FaceLoopGroup *grp = ((*i).first.first); + + grp->classification.push_back(ClassificationInfo()); + ClassificationInfo &info = grp->classification.back(); + + info.intersected_mesh = (*i).first.second; + + if ((*i).second.class_decided) { + info.classification = class_bit_to_class((*i).second.class_bits); + } else { + info.classification = FACE_UNCLASSIFIED; + } + } + + for (Classification::iterator i = b_classification.begin(), e = b_classification.end(); i != e; ++i) { + FaceLoopGroup *grp = ((*i).first.first); + + grp->classification.push_back(ClassificationInfo()); + ClassificationInfo &info = grp->classification.back(); + + info.intersected_mesh = (*i).first.second; + + if ((*i).second.class_decided) { + info.classification = class_bit_to_class((*i).second.class_bits); + } else { + info.classification = FACE_UNCLASSIFIED; + } + } + + for (FLGroupList::iterator i = a_loops_grouped.begin(); i != a_loops_grouped.end(); ++i) { + if ((*i).classification.size() == 0) { +#if defined(CARVE_DEBUG) + std::cerr << " non intersecting group (poly a): " << &(*i) << std::endl; +#endif + bool classified = false; + for (FaceLoop *fl = (*i).face_loops.head; !classified && fl != NULL; fl = fl->next) { + for (size_t fli = 0; !classified && fli < fl->vertices.size(); ++fli) { + if (vclass[fl->vertices[fli]].cls[1] == POINT_UNK) { + vclass[fl->vertices[fli]].cls[1] = carve::mesh::classifyPoint(poly_b, poly_b_rtree, fl->vertices[fli]->v); + } + switch (vclass[fl->vertices[fli]].cls[1]) { + case POINT_IN: + (*i).classification.push_back(ClassificationInfo(NULL, FACE_IN)); + classified = true; + break; + case POINT_OUT: + (*i).classification.push_back(ClassificationInfo(NULL, FACE_OUT)); + classified = true; + break; + default: + break; + } + } + } + if (!classified) { + throw carve::exception("non intersecting group is not IN or OUT! (poly_a)"); + } + } + } + + for (FLGroupList::iterator i = b_loops_grouped.begin(); i != b_loops_grouped.end(); ++i) { + if ((*i).classification.size() == 0) { +#if defined(CARVE_DEBUG) + std::cerr << " non intersecting group (poly b): " << &(*i) << std::endl; +#endif + bool classified = false; + for (FaceLoop *fl = (*i).face_loops.head; !classified && fl != NULL; fl = fl->next) { + for (size_t fli = 0; !classified && fli < fl->vertices.size(); ++fli) { + if (vclass[fl->vertices[fli]].cls[0] == POINT_UNK) { + vclass[fl->vertices[fli]].cls[0] = carve::mesh::classifyPoint(poly_a, poly_a_rtree, fl->vertices[fli]->v); + } + switch (vclass[fl->vertices[fli]].cls[0]) { + case POINT_IN: + (*i).classification.push_back(ClassificationInfo(NULL, FACE_IN)); + classified = true; + break; + case POINT_OUT: + (*i).classification.push_back(ClassificationInfo(NULL, FACE_OUT)); + classified = true; + break; + default: + break; + } + } + } + if (!classified) { + throw carve::exception("non intersecting group is not IN or OUT! (poly_b)"); + } + } + } + +#if defined(DISPLAY_GRP_GRAPH) +#define POLY(grp) (std::string((grp)->face_loops.head->orig_face->polyhedron == poly_a ? "[A:" : "[B:") + CODE(grp) + "]") + + for (std::map >::iterator i = grp_graph_fwd.begin(); i != grp_graph_fwd.end(); ++i) { + const FaceLoopGroup *grp = (*i).first; + + std::cerr << "GRP: " << grp << POLY(grp) << std::endl; + + std::set &fwd_set = grp_graph_fwd[grp]; + std::set &rev_set = grp_graph_rev[grp]; + std::cerr << " FWD: "; + for (std::set::const_iterator j = fwd_set.begin(); j != fwd_set.end(); ++j) { + std::cerr << " " << (*j) << POLY(*j); + } + std::cerr << std::endl; + std::cerr << " REV: "; + for (std::set::const_iterator j = rev_set.begin(); j != rev_set.end(); ++j) { + std::cerr << " " << (*j) << POLY(*j); + } + std::cerr << std::endl; + } +#endif + + for (FLGroupList::iterator i = a_loops_grouped.begin(); i != a_loops_grouped.end(); ++i) { + collector.collect(&*i, hooks); + } + + for (FLGroupList::iterator i = b_loops_grouped.begin(); i != b_loops_grouped.end(); ++i) { + collector.collect(&*i, hooks); + } + + // traceIntersectionGraph(shared_edges, a_loops_grouped, b_loops_grouped, a_edge_map, b_edge_map); + } + + } +} diff -Nru blender-2.61/extern/carve/lib/intersect_classify_group.cpp blender-2.62/extern/carve/lib/intersect_classify_group.cpp --- blender-2.61/extern/carve/lib/intersect_classify_group.cpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/intersect_classify_group.cpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,220 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#if defined(HAVE_CONFIG_H) +# include +#endif + +#include +#include + +#include +#include +#include + +#include + +#include "intersect_common.hpp" +#include "intersect_classify_common.hpp" +#include "intersect_classify_common_impl.hpp" + + +namespace carve { + namespace csg { + + namespace { + +#if defined(_MSC_VER) && _MSC_VER < 1300 + // VC++ 6.0 gets an internal compiler when compiling + // the FaceMaker template. Not sure why but for now we just bypass + // the template + class FaceMaker0 { + public: + CSG::Collector &collector; + CSG::Hooks &hooks; + + FaceMaker0(CSG::Collector &c, CSG::Hooks &h) : collector(c), hooks(h) { + } + bool pointOn(VertexClassification &vclass, FaceLoop *f, size_t index) const { + return vclass[f->vertices[index]].cls[1] == POINT_ON; + } + void explain(FaceLoop *f, size_t index, PointClass pc) const { +#if defined(CARVE_DEBUG) + std::cerr << "face loop " << f << " from poly " << "ab"[0] << " is easy because vertex " << index << " (" << *f->vertices[index] << ") is " << ENUM(pc) << std::endl; +#endif + } + }; + class FaceMaker1 { + public: + CSG::Collector &collector; + CSG::Hooks &hooks; + + FaceMaker1(CSG::Collector &c, CSG::Hooks &h) : collector(c), hooks(h) { + } + bool pointOn(VertexClassification &vclass, FaceLoop *f, size_t index) const { + return vclass[f->vertices[index]].cls[0] == POINT_ON; + } + void explain(FaceLoop *f, size_t index, PointClass pc) const { +#if defined(CARVE_DEBUG) + std::cerr << "face loop " << f << " from poly " << "ab"[1] << " is easy because vertex " << index << " (" << *f->vertices[index] << ") is " << ENUM(pc) << std::endl; +#endif + } + }; +#else + template + class FaceMaker { + FaceMaker &operator=(const FaceMaker &); + + public: + CSG::Collector &collector; + CSG::Hooks &hooks; + + FaceMaker(CSG::Collector &c, CSG::Hooks &h) : collector(c), hooks(h) { + } + + bool pointOn(VertexClassification &vclass, FaceLoop *f, size_t index) const { + return vclass[f->vertices[index]].cls[1 - poly_num] == POINT_ON; + } + + void explain(FaceLoop *f, size_t index, PointClass pc) const { +#if defined(CARVE_DEBUG) + std::cerr << "face loop " << f << " from poly " << "ab"[poly_num] << " is easy because vertex " << index << " (" << f->vertices[index]->v << ") is " << ENUM(pc) << std::endl; +#endif + } + }; + typedef FaceMaker<0> FaceMaker0; + typedef FaceMaker<1> FaceMaker1; +#endif + class ClassifyFaceGroups { + ClassifyFaceGroups &operator=(const ClassifyFaceGroups &); + + public: + CSG::Collector &collector; + CSG::Hooks &hooks; + + ClassifyFaceGroups(CSG::Collector &c, CSG::Hooks &h) : collector(c), hooks(h) { + } + + void classifySimple(FLGroupList &a_loops_grouped, + FLGroupList &b_loops_grouped, + VertexClassification & /* vclass */, + carve::mesh::MeshSet<3> *poly_a, + carve::mesh::MeshSet<3> *poly_b) const { + if (a_loops_grouped.size() < b_loops_grouped.size()) { + performClassifySimpleOnFaceGroups(a_loops_grouped, b_loops_grouped, poly_a, poly_b, collector, hooks); + } else { + performClassifySimpleOnFaceGroups(b_loops_grouped, a_loops_grouped, poly_b, poly_a, collector, hooks); + } +#if defined(CARVE_DEBUG) + std::cerr << "after removal of simple on groups: " << a_loops_grouped.size() << " a groups" << std::endl; + std::cerr << "after removal of simple on groups: " << b_loops_grouped.size() << " b groups" << std::endl; +#endif + } + + void classifyEasy(FLGroupList &a_loops_grouped, + FLGroupList &b_loops_grouped, + VertexClassification &vclass, + carve::mesh::MeshSet<3> *poly_a, + const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *poly_a_rtree, + carve::mesh::MeshSet<3> *poly_b, + const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *poly_b_rtree) const { + performClassifyEasyFaceGroups(a_loops_grouped, poly_b, poly_b_rtree, vclass, FaceMaker0(collector, hooks), collector, hooks); + performClassifyEasyFaceGroups(b_loops_grouped, poly_a, poly_a_rtree, vclass, FaceMaker1(collector, hooks), collector, hooks); +#if defined(CARVE_DEBUG) + std::cerr << "after removal of easy groups: " << a_loops_grouped.size() << " a groups" << std::endl; + std::cerr << "after removal of easy groups: " << b_loops_grouped.size() << " b groups" << std::endl; +#endif + } + + void classifyHard(FLGroupList &a_loops_grouped, + FLGroupList &b_loops_grouped, + VertexClassification & /* vclass */, + carve::mesh::MeshSet<3> *poly_a, + const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *poly_a_rtree, + carve::mesh::MeshSet<3> *poly_b, + const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *poly_b_rtree) const { + performClassifyHardFaceGroups(a_loops_grouped, poly_b, poly_b_rtree, FaceMaker0(collector, hooks), collector, hooks); + performClassifyHardFaceGroups(b_loops_grouped, poly_a, poly_a_rtree, FaceMaker1(collector, hooks), collector, hooks); +#if defined(CARVE_DEBUG) + std::cerr << "after removal of hard groups: " << a_loops_grouped.size() << " a groups" << std::endl; + std::cerr << "after removal of hard groups: " << b_loops_grouped.size() << " b groups" << std::endl; +#endif + } + + void faceLoopWork(FLGroupList &a_loops_grouped, + FLGroupList &b_loops_grouped, + VertexClassification & /* vclass */, + carve::mesh::MeshSet<3> *poly_a, + const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *poly_a_rtree, + carve::mesh::MeshSet<3> *poly_b, + const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *poly_b_rtree) const { + performFaceLoopWork(poly_b, poly_b_rtree, a_loops_grouped, *this, collector, hooks); + performFaceLoopWork(poly_a, poly_a_rtree, b_loops_grouped, *this, collector, hooks); + } + + void postRemovalCheck(FLGroupList &a_loops_grouped, + FLGroupList &b_loops_grouped) const { +#if defined(CARVE_DEBUG) + std::cerr << "after removal of on groups: " << a_loops_grouped.size() << " a groups" << std::endl; + std::cerr << "after removal of on groups: " << b_loops_grouped.size() << " b groups" << std::endl; +#endif + } + + bool faceLoopSanityChecker(FaceLoopGroup &i) const { + return i.face_loops.size() != 1; + } + + void finish(FLGroupList &a_loops_grouped,FLGroupList &b_loops_grouped) const { +#if defined(CARVE_DEBUG) + if (a_loops_grouped.size() || b_loops_grouped.size()) + std::cerr << "UNCLASSIFIED! a=" << a_loops_grouped.size() << ", b=" << b_loops_grouped.size() << std::endl; +#endif + } + }; + } + + void CSG::classifyFaceGroups(const V2Set & /* shared_edges */, + VertexClassification &vclass, + carve::mesh::MeshSet<3> *poly_a, + const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *poly_a_rtree, + FLGroupList &a_loops_grouped, + const detail::LoopEdges & /* a_edge_map */, + carve::mesh::MeshSet<3> *poly_b, + const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *poly_b_rtree, + FLGroupList &b_loops_grouped, + const detail::LoopEdges & /* b_edge_map */, + CSG::Collector &collector) { + ClassifyFaceGroups classifier(collector, hooks); +#if defined(CARVE_DEBUG) + std::cerr << "initial groups: " << a_loops_grouped.size() << " a groups" << std::endl; + std::cerr << "initial groups: " << b_loops_grouped.size() << " b groups" << std::endl; +#endif + performClassifyFaceGroups( + a_loops_grouped, + b_loops_grouped, + vclass, + poly_a, + poly_a_rtree, + poly_b, + poly_b_rtree, + classifier, + collector, + hooks); + } + + } +} diff -Nru blender-2.61/extern/carve/lib/intersect_common.hpp blender-2.62/extern/carve/lib/intersect_common.hpp --- blender-2.61/extern/carve/lib/intersect_common.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/intersect_common.hpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,83 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#pragma once + + +static inline bool facesAreCoplanar(const carve::mesh::MeshSet<3>::face_t *a, const carve::mesh::MeshSet<3>::face_t *b) { + carve::geom3d::Ray temp; + // XXX: Find a better definition. This may be a source of problems + // if floating point inaccuracies cause an incorrect answer. + return !carve::geom3d::planeIntersection(a->plane, b->plane, temp); +} + +#if defined(CARVE_DEBUG) + +#include + +#endif + +namespace carve { + namespace csg { + + static inline carve::mesh::MeshSet<3>::vertex_t *map_vertex(const VVMap &vmap, carve::mesh::MeshSet<3>::vertex_t *v) { + VVMap::const_iterator i = vmap.find(v); + if (i == vmap.end()) return v; + return (*i).second; + } + +#if defined(CARVE_DEBUG) + + class IntersectDebugHooks; + extern IntersectDebugHooks *g_debug; + +#define HOOK(x) do { if (g_debug) { g_debug->x } } while(0) + + static inline void drawFaceLoopList(const FaceLoopList &ll, + float rF, float gF, float bF, float aF, + float rB, float gB, float bB, float aB, + bool lit) { + for (FaceLoop *flb = ll.head; flb; flb = flb->next) { + const carve::mesh::MeshSet<3>::face_t *f = (flb->orig_face); + std::vector::vertex_t *> &loop = flb->vertices; + HOOK(drawFaceLoop2(loop, f->plane.N, rF, gF, bF, aF, rB, gB, bB, aB, true, lit);); + HOOK(drawFaceLoopWireframe(loop, f->plane.N, 1, 1, 1, 0.1f);); + } + } + + static inline void drawFaceLoopListWireframe(const FaceLoopList &ll) { + for (FaceLoop *flb = ll.head; flb; flb = flb->next) { + const carve::mesh::MeshSet<3>::face_t *f = (flb->orig_face); + std::vector::vertex_t *> &loop = flb->vertices; + HOOK(drawFaceLoopWireframe(loop, f->plane.N, 1, 1, 1, 0.1f);); + } + } + + template + static inline void drawEdges(T begin, T end, + float rB, float gB, float bB, float aB, + float rE, float gE, float bE, float aE, + float w) { + for (; begin != end; ++begin) { + HOOK(drawEdge((*begin).first, (*begin).second, rB, gB, bB, aB, rE, gE, bE, aE, w);); + } + } + +#endif + + } +} diff -Nru blender-2.61/extern/carve/lib/intersect.cpp blender-2.62/extern/carve/lib/intersect.cpp --- blender-2.61/extern/carve/lib/intersect.cpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/intersect.cpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,1668 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#if defined(HAVE_CONFIG_H) +# include +#endif + +#include +#include +#include + +#include +#include +#include + +#include + +#include "csg_detail.hpp" +#include "csg_data.hpp" + +#include "intersect_debug.hpp" +#include "intersect_common.hpp" +#include "intersect_classify_common.hpp" + +#include "csg_collector.hpp" + +#include +#include + + + + +carve::csg::VertexPool::VertexPool() { +} + +carve::csg::VertexPool::~VertexPool() { +} + +void carve::csg::VertexPool::reset() { + pool.clear(); +} + +carve::csg::VertexPool::vertex_t *carve::csg::VertexPool::get(const vertex_t::vector_t &v) { + if (!pool.size() || pool.back().size() == blocksize) { + pool.push_back(std::vector()); + pool.back().reserve(blocksize); + } + pool.back().push_back(vertex_t(v)); + return &pool.back().back(); +} + +bool carve::csg::VertexPool::inPool(vertex_t *v) const { + for (pool_t::const_iterator i = pool.begin(); i != pool.end(); ++i) { + if (v >= &(i->front()) && v <= &(i->back())) return true; + } + return false; +} + + + +#if defined(CARVE_DEBUG_WRITE_PLY_DATA) +void writePLY(const std::string &out_file, const carve::point::PointSet *points, bool ascii); +void writePLY(const std::string &out_file, const carve::line::PolylineSet *lines, bool ascii); +void writePLY(const std::string &out_file, const carve::mesh::MeshSet<3> *poly, bool ascii); + +static carve::mesh::MeshSet<3> *faceLoopsToPolyhedron(const carve::csg::FaceLoopList &fl) { + std::vector::face_t *> faces; + faces.reserve(fl.size()); + for (carve::csg::FaceLoop *f = fl.head; f; f = f->next) { + faces.push_back(f->orig_face->create(f->vertices.begin(), f->vertices.end(), false)); + } + carve::mesh::MeshSet<3> *poly = new carve::mesh::MeshSet<3>(faces); + + return poly; +} +#endif + +namespace { + /** + * \brief Sort a range [\a beg, \a end) of vertices in order of increasing dot product of vertex - \a base on \dir. + * + * @tparam[in] T a forward iterator type. + * @param[in] dir The direction in which to sort vertices. + * @param[in] base + * @param[in] beg The start of the vertex range to sort. + * @param[in] end The end of the vertex range to sort. + * @param[out] out The sorted vertex result. + * @param[in] size_hint A hint regarding the size of the output + * vector (to avoid needing to be able to calculate \a + * end - \a beg). + */ + template + void orderVertices(iter_t beg, const iter_t end, + const carve::mesh::MeshSet<3>::vertex_t::vector_t &dir, + const carve::mesh::MeshSet<3>::vertex_t::vector_t &base, + std::vector::vertex_t *> &out) { + typedef std::vector::vertex_t *> > DVVector; + std::vector::vertex_t *> > ordered_vertices; + + ordered_vertices.reserve(std::distance(beg, end)); + + for (; beg != end; ++beg) { + carve::mesh::MeshSet<3>::vertex_t *v = (*beg); + ordered_vertices.push_back(std::make_pair(carve::geom::dot(v->v - base, dir), v)); + } + + std::sort(ordered_vertices.begin(), ordered_vertices.end()); + + out.clear(); + out.reserve(ordered_vertices.size()); + for (DVVector::const_iterator + i = ordered_vertices.begin(), e = ordered_vertices.end(); + i != e; + ++i) { + out.push_back((*i).second); + } + } + + + + /** + * + * + * @param dir + * @param base + * @param beg + * @param end + */ + template + void selectOrderingProjection(iter_t beg, const iter_t end, + carve::mesh::MeshSet<3>::vertex_t::vector_t &dir, + carve::mesh::MeshSet<3>::vertex_t::vector_t &base) { + double dx, dy, dz; + carve::mesh::MeshSet<3>::vertex_t *min_x, *min_y, *min_z, *max_x, *max_y, *max_z; + if (beg == end) return; + min_x = max_x = min_y = max_y = min_z = max_z = *beg++; + for (; beg != end; ++beg) { + if (min_x->v.x > (*beg)->v.x) min_x = *beg; + if (min_y->v.y > (*beg)->v.y) min_y = *beg; + if (min_z->v.z > (*beg)->v.z) min_z = *beg; + if (max_x->v.x < (*beg)->v.x) max_x = *beg; + if (max_y->v.y < (*beg)->v.y) max_y = *beg; + if (max_z->v.z < (*beg)->v.z) max_z = *beg; + } + + dx = max_x->v.x - min_x->v.x; + dy = max_y->v.y - min_y->v.y; + dz = max_z->v.z - min_z->v.z; + + if (dx > dy) { + if (dx > dz) { + dir = max_x->v - min_x->v; base = min_x->v; + } else { + dir = max_z->v - min_z->v; base = min_z->v; + } + } else { + if (dy > dz) { + dir = max_y->v - min_y->v; base = min_y->v; + } else { + dir = max_z->v - min_z->v; base = min_z->v; + } + } + } +} + +namespace { + struct dump_data { + carve::mesh::MeshSet<3>::vertex_t *i_pt; + carve::csg::IObj i_src; + carve::csg::IObj i_tgt; + dump_data(carve::mesh::MeshSet<3>::vertex_t *_i_pt, + carve::csg::IObj _i_src, + carve::csg::IObj _i_tgt) : i_pt(_i_pt), i_src(_i_src), i_tgt(_i_tgt) { + } + }; + + + + struct dump_sort { + bool operator()(const dump_data &a, const dump_data &b) const { + if (a.i_pt->v.x < b.i_pt->v.x) return true; + if (a.i_pt->v.x > b.i_pt->v.x) return false; + if (a.i_pt->v.y < b.i_pt->v.y) return true; + if (a.i_pt->v.y > b.i_pt->v.y) return false; + if (a.i_pt->v.z < b.i_pt->v.z) return true; + if (a.i_pt->v.z > b.i_pt->v.z) return false; + return false; + } + }; + + + + void dump_intersections(std::ostream &out, carve::csg::Intersections &csg_intersections) { + std::vector temp; + + for (carve::csg::Intersections::const_iterator + i = csg_intersections.begin(), + ie = csg_intersections.end(); + i != ie; + ++i) { + const carve::csg::IObj &i_src = ((*i).first); + + for (carve::csg::Intersections::mapped_type::const_iterator + j = (*i).second.begin(), + je = (*i).second.end(); + j != je; + ++j) { + const carve::csg::IObj &i_tgt = ((*j).first); + carve::mesh::MeshSet<3>::vertex_t *i_pt = ((*j).second); + temp.push_back(dump_data(i_pt, i_src, i_tgt)); + } + } + + std::sort(temp.begin(), temp.end(), dump_sort()); + + for (size_t i = 0; i < temp.size(); ++i) { + const carve::csg::IObj &i_src = temp[i].i_src; + const carve::csg::IObj &i_tgt = temp[i].i_tgt; + out + << "INTERSECTION: " << temp[i].i_pt << " (" << temp[i].i_pt->v << ") " + << "is " << i_src << ".." << i_tgt << std::endl; + } + +#if defined(CARVE_DEBUG_WRITE_PLY_DATA) + std::vector vertices; + + for (carve::csg::Intersections::const_iterator + i = csg_intersections.begin(), + ie = csg_intersections.end(); + i != ie; + ++i) { + for (carve::csg::Intersections::mapped_type::const_iterator + j = (*i).second.begin(), + je = (*i).second.end(); + j != je; + ++j) { + carve::mesh::MeshSet<3>::vertex_t *i_pt = ((*j).second); + vertices.push_back(i_pt->v); + } + } + + carve::point::PointSet points(vertices); + + std::string outf("/tmp/intersection-points.ply"); + ::writePLY(outf, &points, true); +#endif + } + + + + /** + * \brief Populate a collection with the faces adjoining an edge. + * + * @tparam face_set_t A collection type. + * @param e The edge for which to collect adjoining faces. + * @param faces + */ + template + inline void facesForVertex(carve::mesh::MeshSet<3>::vertex_t *v, + const carve::csg::detail::VEVecMap &ve, + face_set_t &faces) { + carve::csg::detail::VEVecMap::const_iterator vi = ve.find(v); + if (vi != ve.end()) { + for (carve::csg::detail::VEVecMap::data_type::const_iterator i = (*vi).second.begin(); i != (*vi).second.end(); ++i) { + faces.insert((*i)->face); + } + } + } + + /** + * \brief Populate a collection with the faces adjoining an edge. + * + * @tparam face_set_t A collection type. + * @param e The edge for which to collect adjoining faces. + * @param faces + */ + template + inline void facesForEdge(carve::mesh::MeshSet<3>::edge_t *e, + face_set_t &faces) { + faces.insert(e->face); + } + + /** + * \brief Populate a collection with the faces adjoining a face. + * + * @tparam face_set_t A collection type. + * @param f The face for which to collect adjoining faces. + * @param faces + */ + template + inline void facesForFace(carve::mesh::MeshSet<3>::face_t *f, + face_set_t &faces) { + faces.insert(f); + } + + /** + * \brief Populate a collection with the faces adjoining an intersection object. + * + * @tparam face_set_t A collection type holding const carve::poly::Polyhedron::face_t *. + * @param obj The intersection object for which to collect adjoining faces. + * @param faces + */ + template + void facesForObject(const carve::csg::IObj &obj, + const carve::csg::detail::VEVecMap &ve, + face_set_t &faces) { + switch (obj.obtype) { + case carve::csg::IObj::OBTYPE_VERTEX: + facesForVertex(obj.vertex, ve, faces); + break; + + case carve::csg::IObj::OBTYPE_EDGE: + facesForEdge(obj.edge, faces); + break; + + case carve::csg::IObj::OBTYPE_FACE: + facesForFace(obj.face, faces); + break; + + default: + break; + } + } + + + +} + + + +bool carve::csg::CSG::Hooks::hasHook(unsigned hook_num) { + return hooks[hook_num].size() > 0; +} + +void carve::csg::CSG::Hooks::intersectionVertex(const carve::mesh::MeshSet<3>::vertex_t *vertex, + const IObjPairSet &intersections) { + for (std::list::iterator j = hooks[INTERSECTION_VERTEX_HOOK].begin(); + j != hooks[INTERSECTION_VERTEX_HOOK].end(); + ++j) { + (*j)->intersectionVertex(vertex, intersections); + } +} + +void carve::csg::CSG::Hooks::processOutputFace(std::vector::face_t *> &faces, + const carve::mesh::MeshSet<3>::face_t *orig_face, + bool flipped) { + for (std::list::iterator j = hooks[PROCESS_OUTPUT_FACE_HOOK].begin(); + j != hooks[PROCESS_OUTPUT_FACE_HOOK].end(); + ++j) { + (*j)->processOutputFace(faces, orig_face, flipped); + } +} + +void carve::csg::CSG::Hooks::resultFace(const carve::mesh::MeshSet<3>::face_t *new_face, + const carve::mesh::MeshSet<3>::face_t *orig_face, + bool flipped) { + for (std::list::iterator j = hooks[RESULT_FACE_HOOK].begin(); + j != hooks[RESULT_FACE_HOOK].end(); + ++j) { + (*j)->resultFace(new_face, orig_face, flipped); + } +} + +void carve::csg::CSG::Hooks::registerHook(Hook *hook, unsigned hook_bits) { + for (unsigned i = 0; i < HOOK_MAX; ++i) { + if (hook_bits & (1U << i)) { + hooks[i].push_back(hook); + } + } +} + +void carve::csg::CSG::Hooks::unregisterHook(Hook *hook) { + for (unsigned i = 0; i < HOOK_MAX; ++i) { + hooks[i].erase(std::remove(hooks[i].begin(), hooks[i].end(), hook), hooks[i].end()); + } +} + +void carve::csg::CSG::Hooks::reset() { + for (unsigned i = 0; i < HOOK_MAX; ++i) { + for (std::list::iterator j = hooks[i].begin(); j != hooks[i].end(); ++j) { + delete (*j); + } + hooks[i].clear(); + } +} + +carve::csg::CSG::Hooks::Hooks() : hooks() { + hooks.resize(HOOK_MAX); +} + +carve::csg::CSG::Hooks::~Hooks() { + reset(); +} + + + +void carve::csg::CSG::makeVertexIntersections() { + static carve::TimingName FUNC_NAME("CSG::makeVertexIntersections()"); + carve::TimingBlock block(FUNC_NAME); + vertex_intersections.clear(); + for (Intersections::const_iterator + i = intersections.begin(), + ie = intersections.end(); + i != ie; + ++i) { + const IObj &i_src = ((*i).first); + + for (Intersections::mapped_type::const_iterator + j = (*i).second.begin(), + je = (*i).second.end(); + j != je; + ++j) { + const IObj &i_tgt = ((*j).first); + carve::mesh::MeshSet<3>::vertex_t *i_pt = ((*j).second); + + vertex_intersections[i_pt].insert(std::make_pair(i_src, i_tgt)); + } + } +} + + + +static carve::mesh::MeshSet<3>::vertex_t *chooseWeldPoint( + const carve::csg::detail::VSet &equivalent, + carve::csg::VertexPool &vertex_pool) { + // XXX: choose a better weld point. + if (!equivalent.size()) return NULL; + + for (carve::csg::detail::VSet::const_iterator + i = equivalent.begin(), e = equivalent.end(); + i != e; + ++i) { + if (!vertex_pool.inPool((*i))) return (*i); + } + return *equivalent.begin(); +} + + + +static const carve::mesh::MeshSet<3>::vertex_t *weld( + const carve::csg::detail::VSet &equivalent, + carve::csg::VertexIntersections &vertex_intersections, + carve::csg::VertexPool &vertex_pool) { + carve::mesh::MeshSet<3>::vertex_t *weld_point = chooseWeldPoint(equivalent, vertex_pool); + +#if defined(CARVE_DEBUG) + std::cerr << "weld: " << equivalent.size() << " vertices ( "; + for (carve::csg::detail::VSet::const_iterator + i = equivalent.begin(), e = equivalent.end(); + i != e; + ++i) { + const carve::mesh::MeshSet<3>::vertex_t *v = (*i); + std::cerr << " " << v; + } + std::cerr << ") to " << weld_point << std::endl; +#endif + + if (!weld_point) return NULL; + + carve::csg::VertexIntersections::mapped_type &weld_tgt = (vertex_intersections[weld_point]); + + for (carve::csg::detail::VSet::const_iterator + i = equivalent.begin(), e = equivalent.end(); + i != e; + ++i) { + carve::mesh::MeshSet<3>::vertex_t *v = (*i); + + if (v != weld_point) { + carve::csg::VertexIntersections::iterator j = vertex_intersections.find(v); + + if (j != vertex_intersections.end()) { + weld_tgt.insert((*j).second.begin(), (*j).second.end()); + vertex_intersections.erase(j); + } + } + } + return weld_point; +} + + + +void carve::csg::CSG::groupIntersections() { +#if 0 // old code, to be removed. + static carve::TimingName GROUP_INTERSECTONS("groupIntersections()"); + + carve::TimingBlock block(GROUP_INTERSECTONS); + + std::vector::vertex_t *> vertices; + detail::VVSMap graph; +#if defined(CARVE_DEBUG) + std::cerr << "groupIntersections()" << ": vertex_intersections.size()==" << vertex_intersections.size() << std::endl; +#endif + + vertices.reserve(vertex_intersections.size()); + for (carve::csg::VertexIntersections::const_iterator + i = vertex_intersections.begin(), + e = vertex_intersections.end(); + i != e; + ++i) + { + vertices.push_back((*i).first); + } + carve::geom3d::AABB aabb; + aabb.fit(vertices.begin(), vertices.end(), carve::poly::vec_adapt_vertex_ptr()); + Octree vertex_intersections_octree; + vertex_intersections_octree.setBounds(aabb); + + vertex_intersections_octree.addVertices(vertices); + + std::vector::vertex_t *> out; + for (size_t i = 0, l = vertices.size(); i != l; ++i) { + // let's find all the vertices near this one. + out.clear(); + vertex_intersections_octree.findVerticesNearAllowDupes(vertices[i]->v, out); + + for (size_t j = 0; j < out.size(); ++j) { + if (vertices[i] != out[j] && carve::geom::equal(vertices[i]->v, out[j]->v)) { +#if defined(CARVE_DEBUG) + std::cerr << "EQ: " << vertices[i] << "," << out[j] << " " << vertices[i]->v << "," << out[j]->v << std::endl; +#endif + graph[vertices[i]].insert(out[j]); + graph[out[j]].insert(vertices[i]); + } + } + } + + detail::VSet visited, open; + while (graph.size()) { + visited.clear(); + open.clear(); + detail::VVSMap::iterator i = graph.begin(); + open.insert((*i).first); + while (open.size()) { + detail::VSet::iterator t = open.begin(); + const carve::mesh::MeshSet<3>::vertex_t *o = (*t); + open.erase(t); + i = graph.find(o); + CARVE_ASSERT(i != graph.end()); + visited.insert(o); + for (detail::VVSMap::mapped_type::const_iterator + j = (*i).second.begin(), + je = (*i).second.end(); + j != je; + ++j) { + if (visited.count((*j)) == 0) { + open.insert((*j)); + } + } + graph.erase(i); + } + weld(visited, vertex_intersections, vertex_pool); + } +#endif +} + + + +void carve::csg::CSG::intersectingFacePairs(detail::Data &data) { + static carve::TimingName FUNC_NAME("CSG::intersectingFacePairs()"); + carve::TimingBlock block(FUNC_NAME); + + // iterate over all intersection points. + for (VertexIntersections::const_iterator i = vertex_intersections.begin(), ie = vertex_intersections.end(); i != ie; ++i) { + carve::mesh::MeshSet<3>::vertex_t *i_pt = ((*i).first); + detail::VFSMap::mapped_type &face_set = (data.fmap_rev[i_pt]); + + // for all pairs of intersecting objects at this point + for (VertexIntersections::data_type::const_iterator j = (*i).second.begin(), je = (*i).second.end(); j != je; ++j) { + const IObj &i_src = ((*j).first); + const IObj &i_tgt = ((*j).second); + + // work out the faces involved. this updates fmap_rev. + facesForObject(i_src, data.vert_to_edges, face_set); + facesForObject(i_tgt, data.vert_to_edges, face_set); + + // record the intersection with respect to any involved vertex. + if (i_src.obtype == IObj::OBTYPE_VERTEX) data.vmap[i_src.vertex] = i_pt; + if (i_tgt.obtype == IObj::OBTYPE_VERTEX) data.vmap[i_tgt.vertex] = i_pt; + + // record the intersection with respect to any involved edge. + if (i_src.obtype == IObj::OBTYPE_EDGE) data.emap[i_src.edge].insert(i_pt); + if (i_tgt.obtype == IObj::OBTYPE_EDGE) data.emap[i_tgt.edge].insert(i_pt); + } + + // record the intersection with respect to each face. + for (carve::csg::detail::VFSMap::mapped_type::const_iterator k = face_set.begin(), ke = face_set.end(); k != ke; ++k) { + carve::mesh::MeshSet<3>::face_t *f = (*k); + data.fmap[f].insert(i_pt); + } + } +} + + + +void carve::csg::CSG::_generateVertexVertexIntersections(carve::mesh::MeshSet<3>::vertex_t *va, + carve::mesh::MeshSet<3>::edge_t *eb) { + if (intersections.intersects(va, eb->v1())) { + return; + } + + double d_v1 = carve::geom::distance2(va->v, eb->v1()->v); + + if (d_v1 < carve::EPSILON2) { + intersections.record(va, eb->v1(), va); + } +} + + + +void carve::csg::CSG::generateVertexVertexIntersections(carve::mesh::MeshSet<3>::face_t *a, + const std::vector::face_t *> &b) { + carve::mesh::MeshSet<3>::edge_t *ea, *eb; + + ea = a->edge; + do { + for (size_t i = 0; i < b.size(); ++i) { + carve::mesh::MeshSet<3>::face_t *t = b[i]; + eb = t->edge; + do { + _generateVertexVertexIntersections(ea->v1(), eb); + eb = eb->next; + } while (eb != t->edge); + } + ea = ea->next; + } while (ea != a->edge); +} + + + +void carve::csg::CSG::_generateVertexEdgeIntersections(carve::mesh::MeshSet<3>::vertex_t *va, + carve::mesh::MeshSet<3>::edge_t *eb) { + if (intersections.intersects(va, eb)) { + return; + } + + if (std::min(eb->v1()->v.x, eb->v2()->v.x) - carve::EPSILON > va->v.x || + std::max(eb->v1()->v.x, eb->v2()->v.x) + carve::EPSILON < va->v.x || + std::min(eb->v1()->v.y, eb->v2()->v.y) - carve::EPSILON > va->v.y || + std::max(eb->v1()->v.y, eb->v2()->v.y) + carve::EPSILON < va->v.y || + std::min(eb->v1()->v.z, eb->v2()->v.z) - carve::EPSILON > va->v.z || + std::max(eb->v1()->v.z, eb->v2()->v.z) + carve::EPSILON < va->v.z) { + return; + } + + double a = cross(eb->v2()->v - eb->v1()->v, va->v - eb->v1()->v).length2(); + double b = (eb->v2()->v - eb->v1()->v).length2(); + + if (a < b * carve::EPSILON2) { + // vertex-edge intersection + intersections.record(eb, va, va); + if (eb->rev) intersections.record(eb->rev, va, va); + } +} + + + +void carve::csg::CSG::generateVertexEdgeIntersections(carve::mesh::MeshSet<3>::face_t *a, + const std::vector::face_t *> &b) { + carve::mesh::MeshSet<3>::edge_t *ea, *eb; + + ea = a->edge; + do { + for (size_t i = 0; i < b.size(); ++i) { + carve::mesh::MeshSet<3>::face_t *t = b[i]; + eb = t->edge; + do { + _generateVertexEdgeIntersections(ea->v1(), eb); + eb = eb->next; + } while (eb != t->edge); + } + ea = ea->next; + } while (ea != a->edge); +} + + + +void carve::csg::CSG::_generateEdgeEdgeIntersections(carve::mesh::MeshSet<3>::edge_t *ea, + carve::mesh::MeshSet<3>::edge_t *eb) { + if (intersections.intersects(ea, eb)) { + return; + } + + carve::mesh::MeshSet<3>::vertex_t *v1 = ea->v1(), *v2 = ea->v2(); + carve::mesh::MeshSet<3>::vertex_t *v3 = eb->v1(), *v4 = eb->v2(); + + carve::geom::aabb<3> ea_aabb, eb_aabb; + ea_aabb.fit(v1->v, v2->v); + eb_aabb.fit(v3->v, v4->v); + if (ea_aabb.maxAxisSeparation(eb_aabb) > EPSILON) return; + + carve::mesh::MeshSet<3>::vertex_t::vector_t p1, p2; + double mu1, mu2; + + switch (carve::geom3d::rayRayIntersection(carve::geom3d::Ray(v2->v - v1->v, v1->v), + carve::geom3d::Ray(v4->v - v3->v, v3->v), + p1, p2, mu1, mu2)) { + case carve::RR_INTERSECTION: { + // edges intersect + if (mu1 >= 0.0 && mu1 <= 1.0 && mu2 >= 0.0 && mu2 <= 1.0) { + carve::mesh::MeshSet<3>::vertex_t *p = vertex_pool.get((p1 + p2) / 2.0); + intersections.record(ea, eb, p); + if (ea->rev) intersections.record(ea->rev, eb, p); + if (eb->rev) intersections.record(ea, eb->rev, p); + if (ea->rev && eb->rev) intersections.record(ea->rev, eb->rev, p); + } + break; + } + case carve::RR_PARALLEL: { + // edges parallel. any intersection of this type should have + // been handled by generateVertexEdgeIntersections(). + break; + } + case carve::RR_DEGENERATE: { + throw carve::exception("degenerate edge"); + break; + } + case carve::RR_NO_INTERSECTION: { + break; + } + } +} + + + +void carve::csg::CSG::generateEdgeEdgeIntersections(carve::mesh::MeshSet<3>::face_t *a, + const std::vector::face_t *> &b) { + carve::mesh::MeshSet<3>::edge_t *ea, *eb; + + ea = a->edge; + do { + for (size_t i = 0; i < b.size(); ++i) { + carve::mesh::MeshSet<3>::face_t *t = b[i]; + eb = t->edge; + do { + _generateEdgeEdgeIntersections(ea, eb); + eb = eb->next; + } while (eb != t->edge); + } + ea = ea->next; + } while (ea != a->edge); +} + + + +void carve::csg::CSG::_generateVertexFaceIntersections(carve::mesh::MeshSet<3>::face_t *fa, + carve::mesh::MeshSet<3>::edge_t *eb) { + if (intersections.intersects(eb->v1(), fa)) { + return; + } + + double d1 = carve::geom::distance(fa->plane, eb->v1()->v); + + if (fabs(d1) < carve::EPSILON && + fa->containsPoint(eb->v1()->v)) { + intersections.record(eb->v1(), fa, eb->v1()); + } +} + + + +void carve::csg::CSG::generateVertexFaceIntersections(carve::mesh::MeshSet<3>::face_t *a, + const std::vector::face_t *> &b) { + carve::mesh::MeshSet<3>::edge_t *ea, *eb; + + for (size_t i = 0; i < b.size(); ++i) { + carve::mesh::MeshSet<3>::face_t *t = b[i]; + eb = t->edge; + do { + _generateVertexFaceIntersections(a, eb); + eb = eb->next; + } while (eb != t->edge); + } +} + + + +void carve::csg::CSG::_generateEdgeFaceIntersections(carve::mesh::MeshSet<3>::face_t *fa, + carve::mesh::MeshSet<3>::edge_t *eb) { + if (intersections.intersects(eb, fa)) { + return; + } + + carve::mesh::MeshSet<3>::vertex_t::vector_t _p; + if (fa->simpleLineSegmentIntersection(carve::geom3d::LineSegment(eb->v1()->v, eb->v2()->v), _p)) { + carve::mesh::MeshSet<3>::vertex_t *p = vertex_pool.get(_p); + intersections.record(eb, fa, p); + if (eb->rev) intersections.record(eb->rev, fa, p); + } +} + + + +void carve::csg::CSG::generateEdgeFaceIntersections(carve::mesh::MeshSet<3>::face_t *a, + const std::vector::face_t *> &b) { + carve::mesh::MeshSet<3>::edge_t *ea, *eb; + + for (size_t i = 0; i < b.size(); ++i) { + carve::mesh::MeshSet<3>::face_t *t = b[i]; + eb = t->edge; + do { + _generateEdgeFaceIntersections(a, eb); + eb = eb->next; + } while (eb != t->edge); + } +} + + + +void carve::csg::CSG::generateIntersectionCandidates(carve::mesh::MeshSet<3> *a, + const face_rtree_t *a_node, + carve::mesh::MeshSet<3> *b, + const face_rtree_t *b_node, + face_pairs_t &face_pairs, + bool descend_a) { + if (!a_node->bbox.intersects(b_node->bbox)) { + return; + } + + if (a_node->child && (descend_a || !b_node->child)) { + for (face_rtree_t *node = a_node->child; node; node = node->sibling) { + generateIntersectionCandidates(a, node, b, b_node, face_pairs, false); + } + } else if (b_node->child) { + for (face_rtree_t *node = b_node->child; node; node = node->sibling) { + generateIntersectionCandidates(a, a_node, b, node, face_pairs, true); + } + } else { + for (size_t i = 0; i < a_node->data.size(); ++i) { + carve::mesh::MeshSet<3>::face_t *fa = a_node->data[i]; + carve::geom::aabb<3> aabb_a = fa->getAABB(); + if (aabb_a.maxAxisSeparation(b_node->bbox) > carve::EPSILON) continue; + + for (size_t j = 0; j < b_node->data.size(); ++j) { + carve::mesh::MeshSet<3>::face_t *fb = b_node->data[j]; + carve::geom::aabb<3> aabb_b = fb->getAABB(); + if (aabb_b.maxAxisSeparation(aabb_a) > carve::EPSILON) continue; + + std::pair a_ra = fa->rangeInDirection(fa->plane.N, fa->edge->vert->v); + std::pair b_ra = fb->rangeInDirection(fa->plane.N, fa->edge->vert->v); + if (carve::rangeSeparation(a_ra, b_ra) > carve::EPSILON) continue; + + std::pair a_rb = fa->rangeInDirection(fb->plane.N, fb->edge->vert->v); + std::pair b_rb = fb->rangeInDirection(fb->plane.N, fb->edge->vert->v); + if (carve::rangeSeparation(a_rb, b_rb) > carve::EPSILON) continue; + + if (!facesAreCoplanar(fa, fb)) { + face_pairs[fa].push_back(fb); + face_pairs[fb].push_back(fa); + } + } + } + } +} + + + + +void carve::csg::CSG::generateIntersections(carve::mesh::MeshSet<3> *a, + const face_rtree_t *a_rtree, + carve::mesh::MeshSet<3> *b, + const face_rtree_t *b_rtree, + detail::Data &data) { + face_pairs_t face_pairs; + generateIntersectionCandidates(a, a_rtree, b, b_rtree, face_pairs); + + for (face_pairs_t::const_iterator i = face_pairs.begin(); i != face_pairs.end(); ++i) { + carve::mesh::MeshSet<3>::face_t *f = (*i).first; + carve::mesh::MeshSet<3>::edge_t *e = f->edge; + do { + data.vert_to_edges[e->v1()].push_back(e); + e = e->next; + } while (e != f->edge); + } + + for (face_pairs_t::const_iterator i = face_pairs.begin(); i != face_pairs.end(); ++i) { + generateVertexVertexIntersections((*i).first, (*i).second); + } + + for (face_pairs_t::const_iterator i = face_pairs.begin(); i != face_pairs.end(); ++i) { + generateVertexEdgeIntersections((*i).first, (*i).second); + } + + for (face_pairs_t::const_iterator i = face_pairs.begin(); i != face_pairs.end(); ++i) { + generateEdgeEdgeIntersections((*i).first, (*i).second); + } + + for (face_pairs_t::const_iterator i = face_pairs.begin(); i != face_pairs.end(); ++i) { + generateVertexFaceIntersections((*i).first, (*i).second); + } + + for (face_pairs_t::const_iterator i = face_pairs.begin(); i != face_pairs.end(); ++i) { + generateEdgeFaceIntersections((*i).first, (*i).second); + } + + +#if defined(CARVE_DEBUG) + std::cerr << "makeVertexIntersections" << std::endl; +#endif + makeVertexIntersections(); + +#if defined(CARVE_DEBUG) + std::cerr << " intersections.size() " << intersections.size() << std::endl; + map_histogram(std::cerr, intersections); + std::cerr << " vertex_intersections.size() " << vertex_intersections.size() << std::endl; + map_histogram(std::cerr, vertex_intersections); +#endif + +#if defined(CARVE_DEBUG) && defined(DEBUG_DRAW_INTERSECTIONS) + HOOK(drawIntersections(vertex_intersections);); +#endif + +#if defined(CARVE_DEBUG) + std::cerr << " intersections.size() " << intersections.size() << std::endl; + std::cerr << " vertex_intersections.size() " << vertex_intersections.size() << std::endl; +#endif + + // notify about intersections. + if (hooks.hasHook(Hooks::INTERSECTION_VERTEX_HOOK)) { + for (VertexIntersections::const_iterator i = vertex_intersections.begin(); + i != vertex_intersections.end(); + ++i) { + hooks.intersectionVertex((*i).first, (*i).second); + } + } + + // from here on, only vertex_intersections is used for intersection + // information. + + // intersections still contains the vertex_to_face map. maybe that + // should be moved out into another class. + static_cast(intersections).clear(); +} + + + +carve::csg::CSG::CSG() { +} + + + +/** + * \brief For each intersected edge, decompose into a set of vertex pairs representing an ordered set of edge fragments. + * + * @tparam[in,out] data Internal intersection data. data.emap is used to produce data.divided_edges. + */ +void carve::csg::CSG::divideIntersectedEdges(detail::Data &data) { + static carve::TimingName FUNC_NAME("CSG::divideIntersectedEdges()"); + carve::TimingBlock block(FUNC_NAME); + + for (detail::EVSMap::const_iterator i = data.emap.begin(), ei = data.emap.end(); i != ei; ++i) { + carve::mesh::MeshSet<3>::edge_t *edge = (*i).first; + const detail::EVSMap::mapped_type &vertices = (*i).second; + std::vector::vertex_t *> &verts = data.divided_edges[edge]; + orderVertices(vertices.begin(), vertices.end(), + edge->v2()->v - edge->v1()->v, edge->v1()->v, + verts); + } +} + + + +carve::csg::CSG::~CSG() { +} + + + +void carve::csg::CSG::makeFaceEdges(carve::csg::EdgeClassification &eclass, + detail::Data &data) { + detail::FSet face_b_set; + for (detail::FVSMap::const_iterator + i = data.fmap.begin(), ie = data.fmap.end(); + i != ie; + ++i) { + carve::mesh::MeshSet<3>::face_t *face_a = (*i).first; + const detail::FVSMap::mapped_type &face_a_intersections = ((*i).second); + face_b_set.clear(); + + // work out the set of faces from the opposing polyhedron that intersect face_a. + for (detail::FVSMap::mapped_type::const_iterator + j = face_a_intersections.begin(), je = face_a_intersections.end(); + j != je; + ++j) { + for (detail::VFSMap::mapped_type::const_iterator + k = data.fmap_rev[*j].begin(), ke = data.fmap_rev[*j].end(); + k != ke; + ++k) { + carve::mesh::MeshSet<3>::face_t *face_b = (*k); + if (face_a != face_b && face_b->mesh->meshset != face_a->mesh->meshset) { + face_b_set.insert(face_b); + } + } + } + + // run through each intersecting face. + for (detail::FSet::const_iterator + j = face_b_set.begin(), je = face_b_set.end(); + j != je; + ++j) { + carve::mesh::MeshSet<3>::face_t *face_b = (*j); + const detail::FVSMap::mapped_type &face_b_intersections = (data.fmap[face_b]); + + std::vector::vertex_t *> vertices; + vertices.reserve(std::min(face_a_intersections.size(), face_b_intersections.size())); + + // record the points of intersection between face_a and face_b + std::set_intersection(face_a_intersections.begin(), + face_a_intersections.end(), + face_b_intersections.begin(), + face_b_intersections.end(), + std::back_inserter(vertices)); + +#if defined(CARVE_DEBUG) + std::cerr << "face pair: " + << face_a << ":" << face_b + << " N(verts) " << vertices.size() << std::endl; + for (std::vector::vertex_t *>::const_iterator i = vertices.begin(), e = vertices.end(); i != e; ++i) { + std::cerr << (*i) << " " << (*i)->v << " (" + << carve::geom::distance(face_a->plane, (*i)->v) << "," + << carve::geom::distance(face_b->plane, (*i)->v) << ")" + << std::endl; + //CARVE_ASSERT(carve::geom3d::distance(face_a->plane_eqn, *(*i)) < EPSILON); + //CARVE_ASSERT(carve::geom3d::distance(face_b->plane_eqn, *(*i)) < EPSILON); + } +#endif + + // if there are two points of intersection, then the added edge is simple to determine. + if (vertices.size() == 2) { + carve::mesh::MeshSet<3>::vertex_t *v1 = vertices[0]; + carve::mesh::MeshSet<3>::vertex_t *v2 = vertices[1]; + carve::geom3d::Vector c = (v1->v + v2->v) / 2; + + // determine whether the midpoint of the implied edge is contained in face_a and face_b + +#if defined(CARVE_DEBUG) + std::cerr << "face_a->nVertices() = " << face_a->nVertices() << " face_a->containsPointInProjection(c) = " << face_a->containsPointInProjection(c) << std::endl; + std::cerr << "face_b->nVertices() = " << face_b->nVertices() << " face_b->containsPointInProjection(c) = " << face_b->containsPointInProjection(c) << std::endl; +#endif + + if (face_a->containsPointInProjection(c) && face_b->containsPointInProjection(c)) { +#if defined(CARVE_DEBUG) + std::cerr << "adding edge: " << v1 << "-" << v2 << std::endl; +#if defined(DEBUG_DRAW_FACE_EDGES) + HOOK(drawEdge(v1, v2, 1, 1, 1, 1, 1, 1, 1, 1, 2.0);); +#endif +#endif + // record the edge, with class information. + if (v1 > v2) std::swap(v1, v2); + eclass[ordered_edge(v1, v2)] = carve::csg::EC2(carve::csg::EDGE_ON, carve::csg::EDGE_ON); + data.face_split_edges[face_a].insert(std::make_pair(v1, v2)); + data.face_split_edges[face_b].insert(std::make_pair(v1, v2)); + } + continue; + } + + // otherwise, it's more complex. + carve::geom3d::Vector base, dir; + std::vector::vertex_t *> ordered; + + // skip coplanar edges. this simplifies the resulting + // mesh. eventually all coplanar face regions of two polyhedra + // must reach a point where they are no longer coplanar (or the + // polyhedra are identical). + if (!facesAreCoplanar(face_a, face_b)) { + // order the intersection vertices (they must lie along a + // vector, as the faces aren't coplanar). + selectOrderingProjection(vertices.begin(), vertices.end(), dir, base); + orderVertices(vertices.begin(), vertices.end(), dir, base, ordered); + + // for each possible edge in the ordering, test the midpoint, + // and record if it's contained in face_a and face_b. + for (int k = 0, ke = (int)ordered.size() - 1; k < ke; ++k) { + carve::mesh::MeshSet<3>::vertex_t *v1 = ordered[k]; + carve::mesh::MeshSet<3>::vertex_t *v2 = ordered[k + 1]; + carve::geom3d::Vector c = (v1->v + v2->v) / 2; + +#if defined(CARVE_DEBUG) + std::cerr << "testing edge: " << v1 << "-" << v2 << " at " << c << std::endl; + std::cerr << "a: " << face_a->containsPointInProjection(c) << " b: " << face_b->containsPointInProjection(c) << std::endl; + std::cerr << "face_a->containsPointInProjection(c): " << face_a->containsPointInProjection(c) << std::endl; + std::cerr << "face_b->containsPointInProjection(c): " << face_b->containsPointInProjection(c) << std::endl; +#endif + + if (face_a->containsPointInProjection(c) && face_b->containsPointInProjection(c)) { +#if defined(CARVE_DEBUG) + std::cerr << "adding edge: " << v1 << "-" << v2 << std::endl; +#if defined(DEBUG_DRAW_FACE_EDGES) + HOOK(drawEdge(v1, v2, .5, .5, .5, 1, .5, .5, .5, 1, 2.0);); +#endif +#endif + // record the edge, with class information. + if (v1 > v2) std::swap(v1, v2); + eclass[ordered_edge(v1, v2)] = carve::csg::EC2(carve::csg::EDGE_ON, carve::csg::EDGE_ON); + data.face_split_edges[face_a].insert(std::make_pair(v1, v2)); + data.face_split_edges[face_b].insert(std::make_pair(v1, v2)); + } + } + } + } + } + + +#if defined(CARVE_DEBUG_WRITE_PLY_DATA) + { + V2Set edges; + for (detail::FV2SMap::const_iterator i = data.face_split_edges.begin(); i != data.face_split_edges.end(); ++i) { + edges.insert((*i).second.begin(), (*i).second.end()); + } + + detail::VSet vertices; + for (V2Set::const_iterator i = edges.begin(); i != edges.end(); ++i) { + vertices.insert((*i).first); + vertices.insert((*i).second); + } + + carve::line::PolylineSet intersection_graph; + intersection_graph.vertices.resize(vertices.size()); + std::map::vertex_t *, size_t> vmap; + + size_t j = 0; + for (detail::VSet::const_iterator i = vertices.begin(); i != vertices.end(); ++i) { + intersection_graph.vertices[j].v = (*i)->v; + vmap[(*i)] = j++; + } + + for (V2Set::const_iterator i = edges.begin(); i != edges.end(); ++i) { + size_t line[2]; + line[0] = vmap[(*i).first]; + line[1] = vmap[(*i).second]; + intersection_graph.addPolyline(false, line, line + 2); + } + + std::string out("/tmp/intersection-edges.ply"); + ::writePLY(out, &intersection_graph, true); + } +#endif +} + + + +/** + * + * + * @param fll + */ +static void checkFaceLoopIntegrity(carve::csg::FaceLoopList &fll) { + static carve::TimingName FUNC_NAME("CSG::checkFaceLoopIntegrity()"); + carve::TimingBlock block(FUNC_NAME); + + std::unordered_map counts; + for (carve::csg::FaceLoop *fl = fll.head; fl; fl = fl->next) { + std::vector::vertex_t *> &loop = (fl->vertices); + carve::mesh::MeshSet<3>::vertex_t *v1, *v2; + v1 = loop[loop.size() - 1]; + for (unsigned i = 0; i < loop.size(); ++i) { + v2 = loop[i]; + if (v1 < v2) { + counts[std::make_pair(v1, v2)]++; + } else { + counts[std::make_pair(v2, v1)]--; + } + v1 = v2; + } + } + for (std::unordered_map::const_iterator + x = counts.begin(), xe = counts.end(); x != xe; ++x) { + if ((*x).second) { + std::cerr << "FACE LOOP ERROR: " << (*x).first.first << "-" << (*x).first.second << " : " << (*x).second << std::endl; + } + } +} + + + +/** + * + * + * @param a + * @param b + * @param vclass + * @param eclass + * @param a_face_loops + * @param b_face_loops + * @param a_edge_count + * @param b_edge_count + * @param hooks + */ +void carve::csg::CSG::calc(carve::mesh::MeshSet<3> *a, + const face_rtree_t *a_rtree, + carve::mesh::MeshSet<3> *b, + const face_rtree_t *b_rtree, + carve::csg::VertexClassification &vclass, + carve::csg::EdgeClassification &eclass, + carve::csg::FaceLoopList &a_face_loops, + carve::csg::FaceLoopList &b_face_loops, + size_t &a_edge_count, + size_t &b_edge_count) { + detail::Data data; + +#if defined(CARVE_DEBUG) + std::cerr << "init" << std::endl; +#endif + init(); + + generateIntersections(a, a_rtree, b, b_rtree, data); + +#if defined(CARVE_DEBUG) + std::cerr << "intersectingFacePairs" << std::endl; +#endif + intersectingFacePairs(data); + +#if defined(CARVE_DEBUG) + std::cerr << "emap:" << std::endl; + map_histogram(std::cerr, data.emap); + std::cerr << "fmap:" << std::endl; + map_histogram(std::cerr, data.fmap); + std::cerr << "fmap_rev:" << std::endl; + map_histogram(std::cerr, data.fmap_rev); +#endif + + // std::cerr << "removeCoplanarFaces" << std::endl; + // fp_intersections.removeCoplanarFaces(); + +#if defined(CARVE_DEBUG) && defined(DEBUG_DRAW_OCTREE) + HOOK(drawOctree(a->octree);); + HOOK(drawOctree(b->octree);); +#endif + +#if defined(CARVE_DEBUG) + std::cerr << "divideIntersectedEdges" << std::endl; +#endif + divideIntersectedEdges(data); + +#if defined(CARVE_DEBUG) + std::cerr << "makeFaceEdges" << std::endl; +#endif + // makeFaceEdges(data.face_split_edges, eclass, data.fmap, data.fmap_rev); + makeFaceEdges(eclass, data); + +#if defined(CARVE_DEBUG) + std::cerr << "generateFaceLoops" << std::endl; +#endif + a_edge_count = generateFaceLoops(a, data, a_face_loops); + b_edge_count = generateFaceLoops(b, data, b_face_loops); + +#if defined(CARVE_DEBUG) + std::cerr << "generated " << a_edge_count << " edges for poly a" << std::endl; + std::cerr << "generated " << b_edge_count << " edges for poly b" << std::endl; +#endif + +#if defined(CARVE_DEBUG_WRITE_PLY_DATA) + { + std::string out("/tmp/a_split.ply"); + writePLY(out, faceLoopsToPolyhedron(a_face_loops), false); + } + { + std::string out("/tmp/b_split.ply"); + writePLY(out, faceLoopsToPolyhedron(b_face_loops), false); + } +#endif + + checkFaceLoopIntegrity(a_face_loops); + checkFaceLoopIntegrity(b_face_loops); + +#if defined(CARVE_DEBUG) + std::cerr << "classify" << std::endl; +#endif + // initialize some classification information. + for (std::vector::vertex_t>::iterator + i = a->vertex_storage.begin(), e = a->vertex_storage.end(); i != e; ++i) { + vclass[map_vertex(data.vmap, &(*i))].cls[0] = POINT_ON; + } + for (std::vector::vertex_t>::iterator + i = b->vertex_storage.begin(), e = b->vertex_storage.end(); i != e; ++i) { + vclass[map_vertex(data.vmap, &(*i))].cls[1] = POINT_ON; + } + for (VertexIntersections::const_iterator + i = vertex_intersections.begin(), e = vertex_intersections.end(); i != e; ++i) { + vclass[(*i).first] = PC2(POINT_ON, POINT_ON); + } + +#if defined(CARVE_DEBUG) + std::cerr << data.divided_edges.size() << " edges are split" << std::endl; + std::cerr << data.face_split_edges.size() << " faces are split" << std::endl; + + std::cerr << "poly a: " << a_face_loops.size() << " face loops" << std::endl; + std::cerr << "poly b: " << b_face_loops.size() << " face loops" << std::endl; +#endif + + // std::cerr << "OCTREE A:" << std::endl; + // dump_octree_stats(a->octree.root, 0); + // std::cerr << "OCTREE B:" << std::endl; + // dump_octree_stats(b->octree.root, 0); +} + + + +/** + * + * + * @param shared_edges + * @param result_list + * @param shared_edge_ptr + */ +void returnSharedEdges(carve::csg::V2Set &shared_edges, + std::list *> &result_list, + carve::csg::V2Set *shared_edge_ptr) { + // need to convert shared edges to point into result + typedef std::map::vertex_t *> remap_type; + remap_type remap; + for (std::list *>::iterator list_it = + result_list.begin(); list_it != result_list.end(); list_it++) { + carve::mesh::MeshSet<3> *result = *list_it; + if (result) { + for (std::vector::vertex_t>::iterator it = + result->vertex_storage.begin(); it != result->vertex_storage.end(); it++) { + remap.insert(std::make_pair((*it).v, &(*it))); + } + } + } + for (carve::csg::V2Set::iterator it = shared_edges.begin(); + it != shared_edges.end(); it++) { + remap_type::iterator first_it = remap.find(((*it).first)->v); + remap_type::iterator second_it = remap.find(((*it).second)->v); + CARVE_ASSERT(first_it != remap.end() && second_it != remap.end()); + shared_edge_ptr->insert(std::make_pair(first_it->second, second_it->second)); + } +} + + + +/** + * + * + * @param a + * @param b + * @param collector + * @param hooks + * @param shared_edges_ptr + * @param classify_type + * + * @return + */ +carve::mesh::MeshSet<3> *carve::csg::CSG::compute(carve::mesh::MeshSet<3> *a, + carve::mesh::MeshSet<3> *b, + carve::csg::CSG::Collector &collector, + carve::csg::V2Set *shared_edges_ptr, + CLASSIFY_TYPE classify_type) { + static carve::TimingName FUNC_NAME("CSG::compute"); + carve::TimingBlock block(FUNC_NAME); + + VertexClassification vclass; + EdgeClassification eclass; + + FLGroupList a_loops_grouped; + FLGroupList b_loops_grouped; + + FaceLoopList a_face_loops; + FaceLoopList b_face_loops; + + size_t a_edge_count; + size_t b_edge_count; + + face_rtree_t *a_rtree = face_rtree_t::construct_STR(a->faceBegin(), a->faceEnd(), 4, 4); + face_rtree_t *b_rtree = face_rtree_t::construct_STR(b->faceBegin(), b->faceEnd(), 4, 4); + + { + static carve::TimingName FUNC_NAME("CSG::compute - calc()"); + carve::TimingBlock block(FUNC_NAME); + calc(a, a_rtree, b, b_rtree, vclass, eclass,a_face_loops, b_face_loops, a_edge_count, b_edge_count); + } + + detail::LoopEdges a_edge_map; + detail::LoopEdges b_edge_map; + + { + static carve::TimingName FUNC_NAME("CSG::compute - makeEdgeMap()"); + carve::TimingBlock block(FUNC_NAME); + makeEdgeMap(a_face_loops, a_edge_count, a_edge_map); + makeEdgeMap(b_face_loops, b_edge_count, b_edge_map); + + } + + { + static carve::TimingName FUNC_NAME("CSG::compute - sortFaceLoopLists()"); + carve::TimingBlock block(FUNC_NAME); + a_edge_map.sortFaceLoopLists(); + b_edge_map.sortFaceLoopLists(); + } + + V2Set shared_edges; + + { + static carve::TimingName FUNC_NAME("CSG::compute - findSharedEdges()"); + carve::TimingBlock block(FUNC_NAME); + findSharedEdges(a_edge_map, b_edge_map, shared_edges); + } + + { + static carve::TimingName FUNC_NAME("CSG::compute - groupFaceLoops()"); + carve::TimingBlock block(FUNC_NAME); + groupFaceLoops(a, a_face_loops, a_edge_map, shared_edges, a_loops_grouped); + groupFaceLoops(b, b_face_loops, b_edge_map, shared_edges, b_loops_grouped); +#if defined(CARVE_DEBUG) + std::cerr << "*** a_loops_grouped.size(): " << a_loops_grouped.size() << std::endl; + std::cerr << "*** b_loops_grouped.size(): " << b_loops_grouped.size() << std::endl; +#endif + } + +#if defined(CARVE_DEBUG) && defined(DEBUG_DRAW_GROUPS) + { + float n = 1.0 / (a_loops_grouped.size() + b_loops_grouped.size() + 1); + float H = 0.0, S = 1.0, V = 1.0; + float r, g, b; + for (FLGroupList::const_iterator i = a_loops_grouped.begin(); i != a_loops_grouped.end(); ++i) { + carve::colour::HSV2RGB(H, S, V, r, g, b); H += n; + drawFaceLoopList((*i).face_loops, r, g, b, 1.0, r * .5, g * .5, b * .5, 1.0, true); + } + for (FLGroupList::const_iterator i = b_loops_grouped.begin(); i != b_loops_grouped.end(); ++i) { + carve::colour::HSV2RGB(H, S, V, r, g, b); H += n; + drawFaceLoopList((*i).face_loops, r, g, b, 1.0, r * .5, g * .5, b * .5, 1.0, true); + } + + for (FLGroupList::const_iterator i = a_loops_grouped.begin(); i != a_loops_grouped.end(); ++i) { + drawFaceLoopListWireframe((*i).face_loops); + } + for (FLGroupList::const_iterator i = b_loops_grouped.begin(); i != b_loops_grouped.end(); ++i) { + drawFaceLoopListWireframe((*i).face_loops); + } + } +#endif + + switch (classify_type) { + case CLASSIFY_EDGE: + classifyFaceGroupsEdge(shared_edges, + vclass, + a, + a_rtree, + a_loops_grouped, + a_edge_map, + b, + b_rtree, + b_loops_grouped, + b_edge_map, + collector); + break; + case CLASSIFY_NORMAL: + classifyFaceGroups(shared_edges, + vclass, + a, + a_rtree, + a_loops_grouped, + a_edge_map, + b, + b_rtree, + b_loops_grouped, + b_edge_map, + collector); + break; + } + + carve::mesh::MeshSet<3> *result = collector.done(hooks); + if (result != NULL && shared_edges_ptr != NULL) { + std::list *> result_list; + result_list.push_back(result); + returnSharedEdges(shared_edges, result_list, shared_edges_ptr); + } + return result; +} + + + +/** + * + * + * @param a + * @param b + * @param op + * @param hooks + * @param shared_edges + * @param classify_type + * + * @return + */ +carve::mesh::MeshSet<3> *carve::csg::CSG::compute(carve::mesh::MeshSet<3> *a, + carve::mesh::MeshSet<3> *b, + carve::csg::CSG::OP op, + carve::csg::V2Set *shared_edges, + CLASSIFY_TYPE classify_type) { + Collector *coll = makeCollector(op, a, b); + if (!coll) return NULL; + + carve::mesh::MeshSet<3> *result = compute(a, b, *coll, shared_edges, classify_type); + + delete coll; + + return result; +} + + + +/** + * + * + * @param closed + * @param open + * @param FaceClass + * @param result + * @param hooks + * @param shared_edges_ptr + * + * @return + */ +bool carve::csg::CSG::sliceAndClassify(carve::mesh::MeshSet<3> *closed, + carve::mesh::MeshSet<3> *open, + std::list *> > &result, + carve::csg::V2Set *shared_edges_ptr) { + if (!closed->isClosed()) return false; + carve::csg::VertexClassification vclass; + carve::csg::EdgeClassification eclass; + + carve::csg::FLGroupList a_loops_grouped; + carve::csg::FLGroupList b_loops_grouped; + + carve::csg::FaceLoopList a_face_loops; + carve::csg::FaceLoopList b_face_loops; + + size_t a_edge_count; + size_t b_edge_count; + + face_rtree_t *closed_rtree = face_rtree_t::construct_STR(closed->faceBegin(), closed->faceEnd(), 4, 4); + face_rtree_t *open_rtree = face_rtree_t::construct_STR(open->faceBegin(), open->faceEnd(), 4, 4); + + calc(closed, closed_rtree, open, open_rtree, vclass, eclass,a_face_loops, b_face_loops, a_edge_count, b_edge_count); + + detail::LoopEdges a_edge_map; + detail::LoopEdges b_edge_map; + + makeEdgeMap(a_face_loops, a_edge_count, a_edge_map); + makeEdgeMap(b_face_loops, b_edge_count, b_edge_map); + + carve::csg::V2Set shared_edges; + + findSharedEdges(a_edge_map, b_edge_map, shared_edges); + + groupFaceLoops(closed, a_face_loops, a_edge_map, shared_edges, a_loops_grouped); + groupFaceLoops(open, b_face_loops, b_edge_map, shared_edges, b_loops_grouped); + + halfClassifyFaceGroups(shared_edges, + vclass, + closed, + closed_rtree, + a_loops_grouped, + a_edge_map, + open, + open_rtree, + b_loops_grouped, + b_edge_map, + result); + + if (shared_edges_ptr != NULL) { + std::list *> result_list; + for (std::list *> >::iterator it = result.begin(); it != result.end(); it++) { + result_list.push_back(it->second); + } + returnSharedEdges(shared_edges, result_list, shared_edges_ptr); + } + return true; +} + + + +/** + * + * + * @param a + * @param b + * @param a_sliced + * @param b_sliced + * @param hooks + * @param shared_edges_ptr + */ +void carve::csg::CSG::slice(carve::mesh::MeshSet<3> *a, + carve::mesh::MeshSet<3> *b, + std::list *> &a_sliced, + std::list *> &b_sliced, + carve::csg::V2Set *shared_edges_ptr) { + carve::csg::VertexClassification vclass; + carve::csg::EdgeClassification eclass; + + carve::csg::FLGroupList a_loops_grouped; + carve::csg::FLGroupList b_loops_grouped; + + carve::csg::FaceLoopList a_face_loops; + carve::csg::FaceLoopList b_face_loops; + + size_t a_edge_count; + size_t b_edge_count; + + face_rtree_t *a_rtree = face_rtree_t::construct_STR(a->faceBegin(), a->faceEnd(), 4, 4); + face_rtree_t *b_rtree = face_rtree_t::construct_STR(b->faceBegin(), b->faceEnd(), 4, 4); + + calc(a, a_rtree, b, b_rtree, vclass, eclass,a_face_loops, b_face_loops, a_edge_count, b_edge_count); + + detail::LoopEdges a_edge_map; + detail::LoopEdges b_edge_map; + + makeEdgeMap(a_face_loops, a_edge_count, a_edge_map); + makeEdgeMap(b_face_loops, b_edge_count, b_edge_map); + + carve::csg::V2Set shared_edges; + + findSharedEdges(a_edge_map, b_edge_map, shared_edges); + + groupFaceLoops(a, a_face_loops, a_edge_map, shared_edges, a_loops_grouped); + groupFaceLoops(b, b_face_loops, b_edge_map, shared_edges, b_loops_grouped); + + for (carve::csg::FLGroupList::iterator + i = a_loops_grouped.begin(), e = a_loops_grouped.end(); + i != e; ++i) { + Collector *all = makeCollector(ALL, a, b); + all->collect(&*i, hooks); + a_sliced.push_back(all->done(hooks)); + + delete all; + } + + for (carve::csg::FLGroupList::iterator + i = b_loops_grouped.begin(), e = b_loops_grouped.end(); + i != e; ++i) { + Collector *all = makeCollector(ALL, a, b); + all->collect(&*i, hooks); + b_sliced.push_back(all->done(hooks)); + + delete all; + } + if (shared_edges_ptr != NULL) { + std::list *> result_list; + result_list.insert(result_list.end(), a_sliced.begin(), a_sliced.end()); + result_list.insert(result_list.end(), b_sliced.begin(), b_sliced.end()); + returnSharedEdges(shared_edges, result_list, shared_edges_ptr); + } +} + + + +/** + * + * + */ +void carve::csg::CSG::init() { + intersections.clear(); + vertex_intersections.clear(); + vertex_pool.reset(); +} diff -Nru blender-2.61/extern/carve/lib/intersect_debug.cpp blender-2.62/extern/carve/lib/intersect_debug.cpp --- blender-2.61/extern/carve/lib/intersect_debug.cpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/intersect_debug.cpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,65 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#if defined(HAVE_CONFIG_H) +# include +#endif + +#include + +#include +#include +#include + +#include + +#include "intersect_debug.hpp" + +namespace carve { + namespace csg { + +#if defined(CARVE_DEBUG) + +#define DEBUG_DRAW_FACE_EDGES +#define DEBUG_DRAW_INTERSECTIONS +// #define DEBUG_DRAW_OCTREE +#define DEBUG_DRAW_INTERSECTION_LINE +// #define DEBUG_DRAW_GROUPS +// #define DEBUG_PRINT_RESULT_FACES + + IntersectDebugHooks *g_debug = NULL; + + IntersectDebugHooks *intersect_installDebugHooks(IntersectDebugHooks *hooks) { + IntersectDebugHooks *h = g_debug; + g_debug = hooks; + return h; + } + + bool intersect_debugEnabled() { return true; } + +#else + + IntersectDebugHooks *intersect_installDebugHooks(IntersectDebugHooks * /* hooks */) { + return NULL; + } + + bool intersect_debugEnabled() { return false; } + +#endif + + } +} diff -Nru blender-2.61/extern/carve/lib/intersect_debug.hpp blender-2.62/extern/carve/lib/intersect_debug.hpp --- blender-2.61/extern/carve/lib/intersect_debug.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/intersect_debug.hpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,29 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#include + +#if defined(CARVE_DEBUG) + +#define DEBUG_DRAW_FACE_EDGES +#define DEBUG_DRAW_INTERSECTIONS +// #define DEBUG_DRAW_OCTREE +#define DEBUG_DRAW_INTERSECTION_LINE +// #define DEBUG_DRAW_GROUPS +// #define DEBUG_PRINT_RESULT_FACES + +#endif diff -Nru blender-2.61/extern/carve/lib/intersect_face_division.cpp blender-2.62/extern/carve/lib/intersect_face_division.cpp --- blender-2.61/extern/carve/lib/intersect_face_division.cpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/intersect_face_division.cpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,1744 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#if defined(HAVE_CONFIG_H) +# include +#endif + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "csg_detail.hpp" +#include "csg_data.hpp" + +#include "intersect_common.hpp" + + + +#if defined(CARVE_DEBUG_WRITE_PLY_DATA) +void writePLY(const std::string &out_file, const carve::line::PolylineSet *lines, bool ascii); +#endif + + + +namespace { + + + +#if defined(CARVE_DEBUG_WRITE_PLY_DATA) + template + void dumpFacesAndHoles(iter_t f_begin, iter_t f_end, + iter_t h_begin, iter_t h_end, + const std::string &fname) { + std::cerr << "dumping " << std::distance(f_begin, f_end) << " faces, " << std::distance(h_begin, h_end) << " holes." << std::endl; + std::map::vertex_t *, size_t> v_included; + + for (iter_t i = f_begin; i != f_end; ++i) { + for (size_t j = 0; j < (*i).size(); ++j) { + if (v_included.find((*i)[j]) == v_included.end()) { + size_t &p = v_included[(*i)[j]]; + p = v_included.size() - 1; + } + } + } + + for (iter_t i = h_begin; i != h_end; ++i) { + for (size_t j = 0; j < (*i).size(); ++j) { + if (v_included.find((*i)[j]) == v_included.end()) { + size_t &p = v_included[(*i)[j]]; + p = v_included.size() - 1; + } + } + } + + carve::line::PolylineSet fh; + fh.vertices.resize(v_included.size()); + for (std::map::vertex_t *, size_t>::const_iterator + i = v_included.begin(); i != v_included.end(); ++i) { + fh.vertices[(*i).second].v = (*i).first->v; + } + + { + std::vector connected; + for (iter_t i = f_begin; i != f_end; ++i) { + connected.clear(); + for (size_t j = 0; j < (*i).size(); ++j) { + connected.push_back(v_included[(*i)[j]]); + } + fh.addPolyline(true, connected.begin(), connected.end()); + } + for (iter_t i = h_begin; i != h_end; ++i) { + connected.clear(); + for (size_t j = 0; j < (*i).size(); ++j) { + connected.push_back(v_included[(*i)[j]]); + } + fh.addPolyline(true, connected.begin(), connected.end()); + } + } + + ::writePLY(fname, &fh, true); + } +#endif + + + + template + void populateVectorFromList(std::list &l, std::vector &v) { + v.clear(); + v.reserve(l.size()); + for (typename std::list::iterator i = l.begin(); i != l.end(); ++i) { + v.push_back(T()); + std::swap(*i, v.back()); + } + l.clear(); + } + + template + void populateListFromVector(std::vector &v, std::list &l) { + l.clear(); + for (size_t i = 0; i < v.size(); ++i) { + l.push_back(T()); + std::swap(v[i], l.back()); + } + v.clear(); + } + + + + struct GraphEdge { + GraphEdge *next; + GraphEdge *prev; + GraphEdge *loop_next; + carve::mesh::MeshSet<3>::vertex_t *src; + carve::mesh::MeshSet<3>::vertex_t *tgt; + double ang; + int visited; + + GraphEdge(carve::mesh::MeshSet<3>::vertex_t *_src, carve::mesh::MeshSet<3>::vertex_t *_tgt) : + next(NULL), prev(NULL), loop_next(NULL), + src(_src), tgt(_tgt), + ang(0.0), visited(-1) { + } + }; + + + + struct GraphEdges { + GraphEdge *edges; + carve::geom2d::P2 proj; + + GraphEdges() : edges(NULL), proj() { + } + }; + + + + struct Graph { + typedef std::unordered_map::vertex_t *, GraphEdges> graph_t; + + graph_t graph; + + Graph() : graph() { + } + + ~Graph() { + int c = 0; + + GraphEdge *edge; + for (graph_t::iterator i = graph.begin(), e = graph.end(); i != e; ++i) { + edge = (*i).second.edges; + while (edge) { + GraphEdge *temp = edge; + ++c; + edge = edge->next; + delete temp; + } + } + + if (c) { + std::cerr << "warning: " + << c + << " edges should have already been removed at graph destruction time" + << std::endl; + } + } + + const carve::geom2d::P2 &projection(carve::mesh::MeshSet<3>::vertex_t *v) const { + graph_t::const_iterator i = graph.find(v); + CARVE_ASSERT(i != graph.end()); + return (*i).second.proj; + } + + void computeProjection(carve::mesh::MeshSet<3>::face_t *face) { + for (graph_t::iterator i = graph.begin(), e = graph.end(); i != e; ++i) { + (*i).second.proj = face->project((*i).first->v); + } + for (graph_t::iterator i = graph.begin(), e = graph.end(); i != e; ++i) { + for (GraphEdge *e = (*i).second.edges; e; e = e->next) { + e->ang = carve::math::ANG(carve::geom2d::atan2(projection(e->tgt) - projection(e->src))); + } + } + } + + void print(std::ostream &out, const carve::csg::VertexIntersections *vi) const { + for (graph_t::const_iterator i = graph.begin(), e = graph.end(); i != e; ++i) { + out << (*i).first << (*i).first->v << '(' << projection((*i).first).x << ',' << projection((*i).first).y << ") :"; + for (const GraphEdge *e = (*i).second.edges; e; e = e->next) { + out << ' ' << e->tgt << e->tgt->v << '(' << projection(e->tgt).x << ',' << projection(e->tgt).y << ')'; + } + out << std::endl; + if (vi) { + carve::csg::VertexIntersections::const_iterator j = vi->find((*i).first); + if (j != vi->end()) { + out << " (int) "; + for (carve::csg::IObjPairSet::const_iterator + k = (*j).second.begin(), ke = (*j).second.end(); k != ke; ++k) { + if ((*k).first < (*k).second) { + out << (*k).first << ".." << (*k).second << "; "; + } + } + out << std::endl; + } + } + } + } + + void addEdge(carve::mesh::MeshSet<3>::vertex_t *v1, carve::mesh::MeshSet<3>::vertex_t *v2) { + GraphEdges &edges = graph[v1]; + GraphEdge *edge = new GraphEdge(v1, v2); + if (edges.edges) edges.edges->prev = edge; + edge->next = edges.edges; + edges.edges = edge; + } + + void removeEdge(GraphEdge *edge) { + if (edge->prev != NULL) { + edge->prev->next = edge->next; + } else { + if (edge->next != NULL) { + GraphEdges &edges = (graph[edge->src]); + edges.edges = edge->next; + } else { + graph.erase(edge->src); + } + } + if (edge->next != NULL) { + edge->next->prev = edge->prev; + } + delete edge; + } + + bool empty() const { + return graph.size() == 0; + } + + GraphEdge *pickStartEdge() { + // Try and find a vertex from which there is only one outbound edge. Won't always succeed. + for (graph_t::iterator i = graph.begin(); i != graph.end(); ++i) { + GraphEdges &ge = i->second; + if (ge.edges->next == NULL) { + return ge.edges; + } + } + return (*graph.begin()).second.edges; + } + + GraphEdge *outboundEdges(carve::mesh::MeshSet<3>::vertex_t *v) { + return graph[v].edges; + } + }; + + + + /** + * \brief Take a set of new edges and split a face based upon those edges. + * + * @param[in] face The face to be split. + * @param[in] edges + * @param[out] face_loops Output list of face loops + * @param[out] hole_loops Output list of hole loops + * @param vi + */ + static void splitFace(carve::mesh::MeshSet<3>::face_t *face, + const carve::csg::V2Set &edges, + std::list::vertex_t *> > &face_loops, + std::list::vertex_t *> > &hole_loops, + const carve::csg::VertexIntersections & /* vi */) { + Graph graph; + + for (carve::csg::V2Set::const_iterator + i = edges.begin(), e = edges.end(); + i != e; + ++i) { + carve::mesh::MeshSet<3>::vertex_t *v1 = ((*i).first), *v2 = ((*i).second); + if (carve::geom::equal(v1->v, v2->v)) std::cerr << "WARNING! " << v1->v << "==" << v2->v << std::endl; + graph.addEdge(v1, v2); + } + + graph.computeProjection(face); + + while (!graph.empty()) { + GraphEdge *edge; + GraphEdge *start; + start = edge = graph.pickStartEdge(); + + edge->visited = 0; + + int len = 0; + + for (;;) { + double in_ang = M_PI + edge->ang; + if (in_ang > M_TWOPI) in_ang -= M_TWOPI; + + GraphEdge *opts; + GraphEdge *out = NULL; + double best = M_TWOPI + 1.0; + + for (opts = graph.outboundEdges(edge->tgt); opts; opts = opts->next) { + if (opts->tgt == edge->src) { + if (out == NULL && opts->next == NULL) out = opts; + } else { + double out_ang = carve::math::ANG(in_ang - opts->ang); + + if (out == NULL || out_ang < best) { + out = opts; + best = out_ang; + } + } + } + + CARVE_ASSERT(out != NULL); + + edge->loop_next = out; + + if (out->visited >= 0) { + while (start != out) { + GraphEdge *e = start; + start = start->loop_next; + e->loop_next = NULL; + e->visited = -1; + } + len = edge->visited - out->visited + 1; + break; + } + + out->visited = edge->visited + 1; + edge = out; + } + + std::vector::vertex_t *> loop(len); + std::vector projected(len); + + edge = start; + for (int i = 0; i < len; ++i) { + GraphEdge *next = edge->loop_next; + loop[i] = edge->src; + projected[i] = graph.projection(edge->src); + graph.removeEdge(edge); + edge = next; + } + + CARVE_ASSERT(edge == start); + + if (carve::geom2d::signedArea(projected) < 0) { + face_loops.push_back(std::vector::vertex_t *>()); + face_loops.back().swap(loop); + } else { + hole_loops.push_back(std::vector::vertex_t *>()); + hole_loops.back().swap(loop); + } + } + } + + + + /** + * \brief Determine the relationship between a face loop and a hole loop. + * + * Determine whether a face and hole share an edge, or a vertex, + * or do not touch. Find a hole vertex that is not part of the + * face, and a hole,face vertex pair that are coincident, if such + * a pair exists. + * + * @param[in] f A face loop. + * @param[in] f_sort A vector indexing \a f in address order + * @param[in] h A hole loop. + * @param[in] h_sort A vector indexing \a h in address order + * @param[out] f_idx Index of a face vertex that is shared with the hole. + * @param[out] h_idx Index of the hole vertex corresponding to \a f_idx. + * @param[out] unmatched_h_idx Index of a hole vertex that is not part of the face. + * @param[out] shares_vertex Boolean indicating that the face and the hole share a vertex. + * @param[out] shares_edge Boolean indicating that the face and the hole share an edge. + */ + static void compareFaceLoopAndHoleLoop(const std::vector::vertex_t *> &f, + const std::vector &f_sort, + const std::vector::vertex_t *> &h, + const std::vector &h_sort, + unsigned &f_idx, + unsigned &h_idx, + int &unmatched_h_idx, + bool &shares_vertex, + bool &shares_edge) { + const size_t F = f.size(); + const size_t H = h.size(); + + shares_vertex = shares_edge = false; + unmatched_h_idx = -1; + + unsigned I, J; + for (I = J = 0; I < F && J < H;) { + unsigned i = f_sort[I], j = h_sort[J]; + if (f[i] == h[j]) { + shares_vertex = true; + f_idx = i; + h_idx = j; + if (f[(i + F - 1) % F] == h[(j + 1) % H]) { + shares_edge = true; + } + carve::mesh::MeshSet<3>::vertex_t *t = f[i]; + do { ++I; } while (I < F && f[f_sort[I]] == t); + do { ++J; } while (J < H && h[h_sort[J]] == t); + } else if (f[i] < h[j]) { + ++I; + } else { + unmatched_h_idx = j; + ++J; + } + } + if (J < H) { + unmatched_h_idx = h_sort[J]; + } + } + + + + /** + * \brief Compute an embedding for a set of face loops and hole loops. + * + * Because face and hole loops may be contained within each other, + * it must be determined which hole loops are directly contained + * within a face loop. + * + * @param[in] face The face from which these face and hole loops derive. + * @param[in] face_loops + * @param[in] hole_loops + * @param[out] containing_faces A vector which for each hole loop + * lists the indices of the face + * loops it is containined in. + * @param[out] hole_shared_vertices A map from a face,hole pair to + * a shared vertex pair. + */ + static void computeContainment(carve::mesh::MeshSet<3>::face_t *face, + std::vector::vertex_t *> > &face_loops, + std::vector::vertex_t *> > &hole_loops, + std::vector > &containing_faces, + std::map > > &hole_shared_vertices) { +#if defined(CARVE_DEBUG) + std::cerr << "input: " + << face_loops.size() << "faces, " + << hole_loops.size() << "holes." + << std::endl; +#endif + + std::vector > face_loops_projected, hole_loops_projected; + std::vector > face_loop_aabb, hole_loop_aabb; + std::vector > face_loops_sorted, hole_loops_sorted; + + std::vector face_loop_areas, hole_loop_areas; + + face_loops_projected.resize(face_loops.size()); + face_loops_sorted.resize(face_loops.size()); + face_loop_aabb.resize(face_loops.size()); + face_loop_areas.resize(face_loops.size()); + + hole_loops_projected.resize(hole_loops.size()); + hole_loops_sorted.resize(hole_loops.size()); + hole_loop_aabb.resize(hole_loops.size()); + hole_loop_areas.resize(hole_loops.size()); + + // produce a projection of each face loop onto a 2D plane, and an + // index vector which sorts vertices by address. + for (size_t m = 0; m < face_loops.size(); ++m) { + const std::vector::vertex_t *> &f_loop = (face_loops[m]); + face_loops_projected[m].reserve(f_loop.size()); + face_loops_sorted[m].reserve(f_loop.size()); + for (size_t n = 0; n < f_loop.size(); ++n) { + face_loops_projected[m].push_back(face->project(f_loop[n]->v)); + face_loops_sorted[m].push_back(n); + } + face_loop_areas.push_back(carve::geom2d::signedArea(face_loops_projected[m])); + + std::sort(face_loops_sorted[m].begin(), face_loops_sorted[m].end(), + carve::make_index_sort(face_loops[m].begin())); + face_loop_aabb[m].fit(face_loops_projected[m].begin(), face_loops_projected[m].end()); + } + + // produce a projection of each hole loop onto a 2D plane, and an + // index vector which sorts vertices by address. + for (size_t m = 0; m < hole_loops.size(); ++m) { + const std::vector::vertex_t *> &h_loop = (hole_loops[m]); + hole_loops_projected[m].reserve(h_loop.size()); + hole_loops_projected[m].reserve(h_loop.size()); + for (size_t n = 0; n < h_loop.size(); ++n) { + hole_loops_projected[m].push_back(face->project(h_loop[n]->v)); + hole_loops_sorted[m].push_back(n); + } + hole_loop_areas.push_back(carve::geom2d::signedArea(hole_loops_projected[m])); + + std::sort(hole_loops_sorted[m].begin(), hole_loops_sorted[m].end(), + carve::make_index_sort(hole_loops[m].begin())); + hole_loop_aabb[m].fit(hole_loops_projected[m].begin(), hole_loops_projected[m].end()); + } + + containing_faces.resize(hole_loops.size()); + + for (unsigned i = 0; i < hole_loops.size(); ++i) { + + for (unsigned j = 0; j < face_loops.size(); ++j) { + if (!face_loop_aabb[j].completelyContains(hole_loop_aabb[i])) { +#if defined(CARVE_DEBUG) + std::cerr << "face: " << j + << " hole: " << i + << " skipped test (aabb fail)" + << std::endl; +#endif + continue; + } + + unsigned f_idx, h_idx; + int unmatched_h_idx; + bool shares_vertex, shares_edge; + compareFaceLoopAndHoleLoop(face_loops[j], + face_loops_sorted[j], + hole_loops[i], + hole_loops_sorted[i], + f_idx, h_idx, + unmatched_h_idx, + shares_vertex, + shares_edge); + +#if defined(CARVE_DEBUG) + std::cerr << "face: " << j + << " hole: " << i + << " shares_vertex: " << shares_vertex + << " shares_edge: " << shares_edge + << std::endl; +#endif + + carve::geom3d::Vector test = hole_loops[i][0]->v; + carve::geom2d::P2 test_p = face->project(test); + + if (shares_vertex) { + hole_shared_vertices[i][j] = std::make_pair(h_idx, f_idx); + // Hole touches face. Should be able to connect it up + // trivially. Still need to record its containment, so that + // the assignment below works. + if (unmatched_h_idx != -1) { +#if defined(CARVE_DEBUG) + std::cerr << "using unmatched vertex: " << unmatched_h_idx << std::endl; +#endif + test = hole_loops[i][unmatched_h_idx]->v; + test_p = face->project(test); + } else { + // XXX: hole shares ALL vertices with face. Pick a point + // internal to the projected poly. + if (shares_edge) { + // Hole shares edge with face => face can't contain hole. + continue; + } + + // XXX: how is this possible? Doesn't share an edge, but + // also doesn't have any vertices that are not in + // common. Degenerate hole? + + // XXX: come up with a test case for this. + CARVE_FAIL("implement me"); + } + } + + + // XXX: use loop area to avoid some point-in-poly tests? Loop + // area is faster, but not sure which is more robust. + if (carve::geom2d::pointInPolySimple(face_loops_projected[j], test_p)) { +#if defined(CARVE_DEBUG) + std::cerr << "contains: " << i << " - " << j << std::endl; +#endif + containing_faces[i].push_back(j); + } else { +#if defined(CARVE_DEBUG) + std::cerr << "does not contain: " << i << " - " << j << std::endl; +#endif + } + } + +#if defined(CARVE_DEBUG) + if (containing_faces[i].size() == 0) { + //HOOK(drawFaceLoopWireframe(hole_loops[i], face->normal, 1.0, 0.0, 0.0, 1.0);); + std::cerr << "hole loop: "; + for (unsigned j = 0; j < hole_loops[i].size(); ++j) { + std::cerr << " " << hole_loops[i][j] << ":" << hole_loops[i][j]->v; + } + std::cerr << std::endl; + for (unsigned j = 0; j < face_loops.size(); ++j) { + //HOOK(drawFaceLoopWireframe(face_loops[j], face->normal, 0.0, 1.0, 0.0, 1.0);); + } + } +#endif + + // CARVE_ASSERT(containing_faces[i].size() >= 1); + } + } + + + + /** + * \brief Merge face loops and hole loops to produce a set of face loops without holes. + * + * @param[in] face The face from which these face loops derive. + * @param[in,out] f_loops A list of face loops. + * @param[in] h_loops A list of hole loops to be incorporated into face loops. + */ + static void mergeFacesAndHoles(carve::mesh::MeshSet<3>::face_t *face, + std::list::vertex_t *> > &f_loops, + std::list::vertex_t *> > &h_loops, + carve::csg::CSG::Hooks & /* hooks */) { + std::vector::vertex_t *> > face_loops; + std::vector::vertex_t *> > hole_loops; + + std::vector > containing_faces; + std::map > > hole_shared_vertices; + +#if defined(CARVE_DEBUG_WRITE_PLY_DATA) + dumpFacesAndHoles(f_loops.begin(), f_loops.end(), h_loops.begin(), h_loops.end(), "/tmp/pre_merge.ply"); +#endif + + { + // move input face and hole loops to temp vectors. + size_t m; + face_loops.resize(f_loops.size()); + m = 0; + for (std::list::vertex_t *> >::iterator + i = f_loops.begin(), ie = f_loops.end(); + i != ie; + ++i, ++m) { + face_loops[m].swap((*i)); + } + + hole_loops.resize(h_loops.size()); + m = 0; + for (std::list::vertex_t *> >::iterator + i = h_loops.begin(), ie = h_loops.end(); + i != ie; + ++i, ++m) { + hole_loops[m].swap((*i)); + } + f_loops.clear(); + h_loops.clear(); + } + + // work out the embedding of holes and faces. + computeContainment(face, face_loops, hole_loops, containing_faces, hole_shared_vertices); + + int unassigned = (int)hole_loops.size(); + + std::vector > face_holes; + face_holes.resize(face_loops.size()); + + for (unsigned i = 0; i < containing_faces.size(); ++i) { + if (containing_faces[i].size() == 0) { + std::map > >::iterator it = hole_shared_vertices.find(i); + if (it != hole_shared_vertices.end()) { + std::map >::iterator it2 = (*it).second.begin(); + int f = (*it2).first; + unsigned h_idx = (*it2).second.first; + unsigned f_idx = (*it2).second.second; + + // patch the hole into the face directly. because + // f_loop[f_idx] == h_loop[h_idx], we don't need to + // duplicate the f_loop vertex. + + std::vector::vertex_t *> &f_loop = face_loops[f]; + std::vector::vertex_t *> &h_loop = hole_loops[i]; + + f_loop.insert(f_loop.begin() + f_idx + 1, h_loop.size(), NULL); + + unsigned p = f_idx + 1; + for (unsigned a = h_idx + 1; a < h_loop.size(); ++a, ++p) { + f_loop[p] = h_loop[a]; + } + for (unsigned a = 0; a <= h_idx; ++a, ++p) { + f_loop[p] = h_loop[a]; + } + +#if defined(CARVE_DEBUG) + std::cerr << "hook face " << f << " to hole " << i << "(vertex)" << std::endl; +#endif + } else { + std::cerr << "uncontained hole loop does not share vertices with any face loop!" << std::endl; + } + unassigned--; + } + } + + + // work out which holes are directly contained within which faces. + while (unassigned) { + std::set removed; + + for (unsigned i = 0; i < containing_faces.size(); ++i) { + if (containing_faces[i].size() == 1) { + int f = containing_faces[i][0]; + face_holes[f].push_back(i); +#if defined(CARVE_DEBUG) + std::cerr << "hook face " << f << " to hole " << i << std::endl; +#endif + removed.insert(f); + unassigned--; + } + } + for (std::set::iterator f = removed.begin(); f != removed.end(); ++f) { + for (unsigned i = 0; i < containing_faces.size(); ++i) { + containing_faces[i].erase(std::remove(containing_faces[i].begin(), + containing_faces[i].end(), + *f), + containing_faces[i].end()); + } + } + } + +#if 0 + // use old templated projection code to patch holes into faces. + for (unsigned i = 0; i < face_loops.size(); ++i) { + std::vector::vertex_t *> > face_hole_loops; + face_hole_loops.resize(face_holes[i].size()); + for (unsigned j = 0; j < face_holes[i].size(); ++j) { + face_hole_loops[j].swap(hole_loops[face_holes[i][j]]); + } + if (face_hole_loops.size()) { + + f_loops.push_back(carve::triangulate::incorporateHolesIntoPolygon( + carve::mesh::MeshSet<3>::face_t::projection_mapping(face->project), + face_loops[i], + face_hole_loops)); + } else { + f_loops.push_back(face_loops[i]); + } + } + +#else + // use new 2d-only hole patching code. + for (size_t i = 0; i < face_loops.size(); ++i) { + if (!face_holes[i].size()) { + f_loops.push_back(face_loops[i]); + continue; + } + + std::vector > projected_poly; + projected_poly.resize(face_holes[i].size() + 1); + projected_poly[0].reserve(face_loops[i].size()); + for (size_t j = 0; j < face_loops[i].size(); ++j) { + projected_poly[0].push_back(face->project(face_loops[i][j]->v)); + } + for (size_t j = 0; j < face_holes[i].size(); ++j) { + projected_poly[j+1].reserve(hole_loops[face_holes[i][j]].size()); + for (size_t k = 0; k < hole_loops[face_holes[i][j]].size(); ++k) { + projected_poly[j+1].push_back(face->project(hole_loops[face_holes[i][j]][k]->v)); + } + } + + std::vector > result = carve::triangulate::incorporateHolesIntoPolygon(projected_poly); + + f_loops.push_back(std::vector::vertex_t *>()); + std::vector::vertex_t *> &out = f_loops.back(); + out.reserve(result.size()); + for (size_t j = 0; j < result.size(); ++j) { + if (result[j].first == 0) { + out.push_back(face_loops[i][result[j].second]); + } else { + out.push_back(hole_loops[face_holes[i][result[j].first-1]][result[j].second]); + } + } + } +#endif +#if defined(CARVE_DEBUG_WRITE_PLY_DATA) + dumpFacesAndHoles(f_loops.begin(), f_loops.end(), h_loops.begin(), h_loops.end(), "/tmp/post_merge.ply"); +#endif + + } + + + + /** + * \brief Assemble the base loop for a face. + * + * The base loop is the original face loop, including vertices + * created by intersections crossing any of its edges. + * + * @param[in] face The face to process. + * @param[in] vmap + * @param[in] face_split_edges + * @param[in] divided_edges A mapping from edge pointer to sets of + * ordered vertices corrsponding to the intersection points + * on that edge. + * @param[out] base_loop A vector of the vertices of the base loop. + */ + static bool assembleBaseLoop(carve::mesh::MeshSet<3>::face_t *face, + const carve::csg::detail::Data &data, + std::vector::vertex_t *> &base_loop) { + base_loop.clear(); + + // XXX: assumes that face->edges is in the same order as + // face->vertices. (Which it is) + carve::mesh::MeshSet<3>::edge_t *e = face->edge; + bool face_edge_intersected = false; + do { + base_loop.push_back(carve::csg::map_vertex(data.vmap, e->vert)); + + carve::csg::detail::EVVMap::const_iterator ev = data.divided_edges.find(e); + + if (ev != data.divided_edges.end()) { + const std::vector::vertex_t *> &ev_vec = ((*ev).second); + + for (size_t k = 0, ke = ev_vec.size(); k < ke;) { + base_loop.push_back(ev_vec[k++]); + } + + face_edge_intersected = true; + } + e = e->next; + } while (e != face->edge); + + return face_edge_intersected; + } + + + + // the crossing_data structure holds temporary information regarding + // paths, and their relationship to the loop of edges that forms the + // face perimeter. + struct crossing_data { + std::vector::vertex_t *> *path; + size_t edge_idx[2]; + + crossing_data(std::vector::vertex_t *> *p, size_t e1, size_t e2) : path(p) { + edge_idx[0] = e1; edge_idx[1] = e2; + } + + bool operator<(const crossing_data &c) const { + // the sort order for paths is in order of increasing initial + // position on the edge loop, but decreasing final position. + return edge_idx[0] < c.edge_idx[0] || (edge_idx[0] == c.edge_idx[0] && edge_idx[1] > c.edge_idx[1]); + } + }; + + + + bool processCrossingEdges(carve::mesh::MeshSet<3>::face_t *face, + const carve::csg::VertexIntersections &vertex_intersections, + carve::csg::CSG::Hooks &hooks, + std::vector::vertex_t *> &base_loop, + std::vector::vertex_t *> > &paths, + std::list::vertex_t *> > &face_loops_out) { + const size_t N = base_loop.size(); + std::vector endpoint_indices; + + endpoint_indices.reserve(paths.size()); + + for (size_t i = 0; i < paths.size(); ++i) { + endpoint_indices.push_back(crossing_data(&paths[i], N, N)); + } + + // Step 1: + // locate endpoints of paths on the base loop. + for (size_t i = 0; i < N; ++i) { + for (size_t j = 0; j < paths.size(); ++j) { + // test beginning of path. + if (paths[j].front() == base_loop[i]) { + if (endpoint_indices[j].edge_idx[0] == N) { + endpoint_indices[j].edge_idx[0] = i; + } else { + // there is a duplicated vertex in the face perimeter. The + // path might attach to either of the duplicate instances + // so we have to work out which is the right one to attach + // to. We assume it's the index currently being examined, + // if the path heads in a direction that's internal to the + // angle made by the prior and next edges of the face + // perimeter. Otherwise, leave it as the currently + // selected index (until another duplicate is found, if it + // exists, and is tested). + const std::vector::vertex_t *> &p = *endpoint_indices[j].path; + const size_t pN = p.size(); + + carve::mesh::MeshSet<3>::vertex_t *a, *b, *c; + a = base_loop[(i+N-1)%N]; + b = base_loop[i]; + c = base_loop[(i+1)%N]; + + carve::mesh::MeshSet<3>::vertex_t *adj = (p[0] == base_loop[i]) ? p[1] : p[pN-2]; + + if (carve::geom2d::internalToAngle(face->project(c->v), + face->project(b->v), + face->project(a->v), + face->project(adj->v))) { + endpoint_indices[j].edge_idx[0] = i; + } + } + } + + // test end of path. + if (paths[j].back() == base_loop[i]) { + if (endpoint_indices[j].edge_idx[1] == N) { + endpoint_indices[j].edge_idx[1] = i; + } else { + // Work out which of the duplicated vertices is the right + // one to attach to, as above. + const std::vector::vertex_t *> &p = *endpoint_indices[j].path; + const size_t pN = p.size(); + + carve::mesh::MeshSet<3>::vertex_t *a, *b, *c; + a = base_loop[(i+N-1)%N]; + b = base_loop[i]; + c = base_loop[(i+1)%N]; + + carve::mesh::MeshSet<3>::vertex_t *adj = (p[0] == base_loop[i]) ? p[1] : p[pN-2]; + + if (carve::geom2d::internalToAngle(face->project(c->v), + face->project(b->v), + face->project(a->v), + face->project(adj->v))) { + endpoint_indices[j].edge_idx[1] = i; + } + } + } + } + } + +#if defined(CARVE_DEBUG) + std::cerr << "### N: " << N << std::endl; + for (size_t i = 0; i < paths.size(); ++i) { + std::cerr << "### path: " << i << " endpoints: " << endpoint_indices[i].edge_idx[0] << " - " << endpoint_indices[i].edge_idx[1] << std::endl; + } +#endif + + + // Step 2: + // divide paths up into those that connect to the base loop in two + // places (cross), and those that do not (noncross). + std::vector cross, noncross; + cross.reserve(endpoint_indices.size() + 1); + noncross.reserve(endpoint_indices.size()); + + for (size_t i = 0; i < endpoint_indices.size(); ++i) { +#if defined(CARVE_DEBUG) + std::cerr << "### orienting path: " << i << " endpoints: " << endpoint_indices[i].edge_idx[0] << " - " << endpoint_indices[i].edge_idx[1] << std::endl; +#endif + if (endpoint_indices[i].edge_idx[0] != N && endpoint_indices[i].edge_idx[1] != N) { + // Orient each path correctly. Paths should progress from + // smaller perimeter index to larger, but if the path starts + // and ends at the same perimeter index, then the decision + // needs to be made based upon area. + if (endpoint_indices[i].edge_idx[0] == endpoint_indices[i].edge_idx[1]) { + // The path forms a loop that starts and ends at the same + // vertex of the perimeter. In this case, we need to orient + // the path so that the constructed loop has the right + // signed area. + double area = carve::geom2d::signedArea(endpoint_indices[i].path->begin() + 1, + endpoint_indices[i].path->end(), + carve::mesh::MeshSet<3>::face_t::projection_mapping(face->project)); + if (area < 0) { + // XXX: Create test case to check that this is the correct sign for the area. + std::reverse(endpoint_indices[i].path->begin(), endpoint_indices[i].path->end()); + } + } else { + if (endpoint_indices[i].edge_idx[0] > endpoint_indices[i].edge_idx[1]) { + std::swap(endpoint_indices[i].edge_idx[0], endpoint_indices[i].edge_idx[1]); + std::reverse(endpoint_indices[i].path->begin(), endpoint_indices[i].path->end()); + } + } + } + + if (endpoint_indices[i].edge_idx[0] != N && + endpoint_indices[i].edge_idx[1] != N && + endpoint_indices[i].edge_idx[0] != endpoint_indices[i].edge_idx[1]) { + cross.push_back(endpoint_indices[i]); + } else { + noncross.push_back(endpoint_indices[i]); + } + } + + // Step 3: + // add a temporary crossing path that connects the beginning and the + // end of the base loop. this stops us from needing special case + // code to handle the left over loop after all the other crossing + // paths are considered. + std::vector::vertex_t *> base_loop_temp_path; + base_loop_temp_path.reserve(2); + base_loop_temp_path.push_back(base_loop.front()); + base_loop_temp_path.push_back(base_loop.back()); + + cross.push_back(crossing_data(&base_loop_temp_path, 0, base_loop.size() - 1)); +#if defined(CARVE_DEBUG) + std::cerr << "### crossing edge count (with sentinel): " << cross.size() << std::endl; +#endif + + // Step 4: + // sort paths by increasing beginning point and decreasing ending point. + std::sort(cross.begin(), cross.end()); + std::sort(noncross.begin(), noncross.end()); + + // Step 5: + // divide up the base loop based upon crossing paths. + std::vector::vertex_t *> > divided_base_loop; + divided_base_loop.reserve(cross.size()); + std::vector::vertex_t *> out; + + for (size_t i = 0; i < cross.size(); ++i) { + size_t j; + for (j = i + 1; + j < cross.size() && + cross[i].edge_idx[0] == cross[j].edge_idx[0] && + cross[i].edge_idx[1] == cross[j].edge_idx[1]; + ++j) {} + if (j - i >= 2) { + // when there are multiple paths that begin and end at the + // same point, they need to be ordered so that the constructed + // loops have the right orientation. this means that the loop + // made by taking path(i+1) forward, then path(i) backward + // needs to have negative area. this combined area is equal to + // the area of path(i+1) minus the area of path(i). in turn + // this means that the loop made by path path(i+1) alone has + // to have smaller signed area than loop made by path(i). + // thus, we sort paths in order of decreasing area. + + std::vector::vertex_t *> *> > order; + order.reserve(j - i); + for (size_t k = i; k < j; ++k) { + double area = carve::geom2d::signedArea(cross[k].path->begin(), + cross[k].path->end(), + carve::mesh::MeshSet<3>::face_t::projection_mapping(face->project)); +#if defined(CARVE_DEBUG) + std::cerr << "### k=" << k << " area=" << area << std::endl; +#endif + order.push_back(std::make_pair(-area, cross[k].path)); + } + std::sort(order.begin(), order.end()); + for (size_t k = i; k < j; ++k) { + cross[k].path = order[k-i].second; +#if defined(CARVE_DEBUG) + std::cerr << "### post-sort k=" << k << " cross[k].path->size()=" << cross[k].path->size() << std::endl; +#endif + } + } + } + + // Step 6: + for (size_t i = 0; i < cross.size(); ++i) { +#if defined(CARVE_DEBUG) + std::cerr << "### i=" << i << " working on edge: " << cross[i].edge_idx[0] << " - " << cross[i].edge_idx[1] << std::endl; +#endif + size_t e1_0 = cross[i].edge_idx[0]; + size_t e1_1 = cross[i].edge_idx[1]; + std::vector::vertex_t *> &p1 = *cross[i].path; +#if defined(CARVE_DEBUG) + std::cerr << "### path size = " << p1.size() << std::endl; +#endif + + out.clear(); + + if (i < cross.size() - 1 && + cross[i+1].edge_idx[1] <= cross[i].edge_idx[1]) { +#if defined(CARVE_DEBUG) + std::cerr << "### complex case" << std::endl; +#endif + // complex case. crossing path with other crossing paths embedded within. + size_t pos = e1_0; + + size_t skip = i+1; + + while (pos != e1_1) { + + std::vector::vertex_t *> &p2 = *cross[skip].path; + size_t e2_0 = cross[skip].edge_idx[0]; + size_t e2_1 = cross[skip].edge_idx[1]; + + // copy up to the beginning of the next path. + std::copy(base_loop.begin() + pos, base_loop.begin() + e2_0, std::back_inserter(out)); + + CARVE_ASSERT(base_loop[e2_0] == p2[0]); + // copy the next path in the right direction. + std::copy(p2.begin(), p2.end() - 1, std::back_inserter(out)); + + // move to the position of the end of the path. + pos = e2_1; + + // advance to the next hit path. + do { + ++skip; + } while(skip != cross.size() && cross[skip].edge_idx[0] < e2_1); + + if (skip == cross.size()) break; + + // if the next hit path is past the start point of the current path, we're done. + if (cross[skip].edge_idx[0] >= e1_1) break; + } + + // copy up to the end of the path. + std::copy(base_loop.begin() + pos, base_loop.begin() + e1_1, std::back_inserter(out)); + + CARVE_ASSERT(base_loop[e1_1] == p1.back()); + std::copy(p1.rbegin(), p1.rend() - 1, std::back_inserter(out)); + } else { + size_t loop_size = (e1_1 - e1_0) + (p1.size() - 1); + out.reserve(loop_size); + + std::copy(base_loop.begin() + e1_0, base_loop.begin() + e1_1, std::back_inserter(out)); + std::copy(p1.rbegin(), p1.rend() - 1, std::back_inserter(out)); + + CARVE_ASSERT(out.size() == loop_size); + } + divided_base_loop.push_back(out); + +#if defined(CARVE_DEBUG) + { + std::vector projected; + projected.reserve(out.size()); + for (size_t n = 0; n < out.size(); ++n) { + projected.push_back(face->project(out[n]->v)); + } + + double A = carve::geom2d::signedArea(projected); + std::cerr << "### out area=" << A << std::endl; + CARVE_ASSERT(A <= 0); + } +#endif + } + + if (!noncross.size()) { + // If there are no non-crossing paths then we're done. + populateListFromVector(divided_base_loop, face_loops_out); + return true; + } + + // for each divided base loop, work out which noncrossing paths and + // loops are part of it. use the old algorithm to combine these into + // the divided base loop. if none, the divided base loop is just + // output. + std::vector > proj; + std::vector > proj_aabb; + proj.resize(divided_base_loop.size()); + proj_aabb.resize(divided_base_loop.size()); + + // calculate an aabb for each divided base loop, to avoid expensive + // point-in-poly tests. + for (size_t i = 0; i < divided_base_loop.size(); ++i) { + proj[i].reserve(divided_base_loop[i].size()); + for (size_t j = 0; j < divided_base_loop[i].size(); ++j) { + proj[i].push_back(face->project(divided_base_loop[i][j]->v)); + } + proj_aabb[i].fit(proj[i].begin(), proj[i].end()); + } + + for (size_t i = 0; i < divided_base_loop.size(); ++i) { + std::vector::vertex_t *> *> inc; + carve::geom2d::P2 test; + + // for each noncrossing path, choose an endpoint that isn't on the + // base loop as a test point. + for (size_t j = 0; j < noncross.size(); ++j) { + if (noncross[j].edge_idx[0] < N) { + if (noncross[j].path->front() == base_loop[noncross[j].edge_idx[0]]) { + // noncrossing paths may be loops that run from the edge, back to the same vertex. + if (noncross[j].path->front() == noncross[j].path->back()) { + CARVE_ASSERT(noncross[j].path->size() > 2); + test = face->project((*noncross[j].path)[1]->v); + } else { + test = face->project(noncross[j].path->back()->v); + } + } else { + test = face->project(noncross[j].path->front()->v); + } + } else { + test = face->project(noncross[j].path->front()->v); + } + + if (proj_aabb[i].intersects(test) && + carve::geom2d::pointInPoly(proj[i], test).iclass != carve::POINT_OUT) { + inc.push_back(noncross[j].path); + } + } + +#if defined(CARVE_DEBUG) + std::cerr << "### divided base loop:" << i << " inc.size()=" << inc.size() << std::endl; + std::cerr << "### inc = ["; + for (size_t j = 0; j < inc.size(); ++j) { + std::cerr << " " << inc[j]; + } + std::cerr << " ]" << std::endl; +#endif + + if (inc.size()) { + carve::csg::V2Set face_edges; + + for (size_t j = 0; j < divided_base_loop[i].size() - 1; ++j) { + face_edges.insert(std::make_pair(divided_base_loop[i][j], + divided_base_loop[i][j+1])); + } + + face_edges.insert(std::make_pair(divided_base_loop[i].back(), + divided_base_loop[i].front())); + + for (size_t j = 0; j < inc.size(); ++j) { + std::vector::vertex_t *> &path = *inc[j]; + for (size_t k = 0; k < path.size() - 1; ++k) { + face_edges.insert(std::make_pair(path[k], path[k+1])); + face_edges.insert(std::make_pair(path[k+1], path[k])); + } + } + + std::list::vertex_t *> > face_loops; + std::list::vertex_t *> > hole_loops; + + splitFace(face, face_edges, face_loops, hole_loops, vertex_intersections); + + if (hole_loops.size()) { + mergeFacesAndHoles(face, face_loops, hole_loops, hooks); + } + std::copy(face_loops.begin(), face_loops.end(), std::back_inserter(face_loops_out)); + } else { + face_loops_out.push_back(divided_base_loop[i]); + } + } + return true; + } + + + + void composeEdgesIntoPaths(const carve::csg::V2Set &edges, + const std::vector::vertex_t *> &extra_endpoints, + std::vector::vertex_t *> > &paths, + std::vector::vertex_t *> > &cuts, + std::vector::vertex_t *> > &loops) { + using namespace carve::csg; + + detail::VVSMap vertex_graph; + detail::VSet endpoints; + detail::VSet cut_endpoints; + + typedef std::vector::vertex_t *> vvec_t; + vvec_t path; + + std::list path_list, cut_list, loop_list; + + // build graph from edges. + for (V2Set::const_iterator i = edges.begin(); i != edges.end(); ++i) { +#if defined(CARVE_DEBUG) + std::cerr << "### edge: " << (*i).first << " - " << (*i).second << std::endl; +#endif + vertex_graph[(*i).first].insert((*i).second); + vertex_graph[(*i).second].insert((*i).first); + } + + // find the endpoints in the graph. + // every vertex with number of incident edges != 2 is an endpoint. + for (detail::VVSMap::const_iterator i = vertex_graph.begin(); i != vertex_graph.end(); ++i) { + if ((*i).second.size() != 2) { +#if defined(CARVE_DEBUG) + std::cerr << "### endpoint: " << (*i).first << std::endl; +#endif + endpoints.insert((*i).first); + if ((*i).second.size() == 1) { + cut_endpoints.insert((*i).first); + } + } + } + + // every vertex on the perimeter of the face is also an endpoint. + for (size_t i = 0; i < extra_endpoints.size(); ++i) { + if (vertex_graph.find(extra_endpoints[i]) != vertex_graph.end()) { +#if defined(CARVE_DEBUG) + std::cerr << "### extra endpoint: " << extra_endpoints[i] << std::endl; +#endif + endpoints.insert(extra_endpoints[i]); + cut_endpoints.erase(extra_endpoints[i]); + } + } + + while (endpoints.size()) { + carve::mesh::MeshSet<3>::vertex_t *v = *endpoints.begin(); + detail::VVSMap::iterator p = vertex_graph.find(v); + if (p == vertex_graph.end()) { + endpoints.erase(endpoints.begin()); + continue; + } + + path.clear(); + path.push_back(v); + + for (;;) { + CARVE_ASSERT(p != vertex_graph.end()); + + // pick a connected vertex to move to. + if ((*p).second.size() == 0) break; + + carve::mesh::MeshSet<3>::vertex_t *n = *((*p).second.begin()); + detail::VVSMap::iterator q = vertex_graph.find(n); + + // remove the link. + (*p).second.erase(n); + (*q).second.erase(v); + + // move on. + v = n; + path.push_back(v); + + if ((*p).second.size() == 0) vertex_graph.erase(p); + if ((*q).second.size() == 0) { + vertex_graph.erase(q); + q = vertex_graph.end(); + } + + p = q; + + if (v == path[0] || p == vertex_graph.end() || endpoints.find(v) != endpoints.end()) break; + } + CARVE_ASSERT(endpoints.find(path.back()) != endpoints.end()); + + bool is_cut = + cut_endpoints.find(path.front()) != cut_endpoints.end() && + cut_endpoints.find(path.back()) != cut_endpoints.end(); + + if (is_cut) { + cut_list.push_back(vvec_t()); path.swap(cut_list.back()); + } else { + path_list.push_back(vvec_t()); path.swap(path_list.back()); + } + } + + populateVectorFromList(path_list, paths); + populateVectorFromList(cut_list, cuts); + + // now only loops should remain in the graph. + while (vertex_graph.size()) { + detail::VVSMap::iterator p = vertex_graph.begin(); + carve::mesh::MeshSet<3>::vertex_t *v = (*p).first; + CARVE_ASSERT((*p).second.size() == 2); + + std::vector::vertex_t *> path; + path.clear(); + path.push_back(v); + + for (;;) { + CARVE_ASSERT(p != vertex_graph.end()); + // pick a connected vertex to move to. + + carve::mesh::MeshSet<3>::vertex_t *n = *((*p).second.begin()); + detail::VVSMap::iterator q = vertex_graph.find(n); + + // remove the link. + (*p).second.erase(n); + (*q).second.erase(v); + + // move on. + v = n; + path.push_back(v); + + if ((*p).second.size() == 0) vertex_graph.erase(p); + if ((*q).second.size() == 0) vertex_graph.erase(q); + + p = q; + + if (v == path[0]) break; + } + + loop_list.push_back(vvec_t()); path.swap(loop_list.back()); + } + + populateVectorFromList(loop_list, loops); + } + + + + template + std::string ptrstr(const T *ptr) { + std::ostringstream s; + s << ptr; + return s.str().substr(1); + } + + void dumpAsGraph(carve::mesh::MeshSet<3>::face_t *face, + const std::vector::vertex_t *> &base_loop, + const carve::csg::V2Set &face_edges, + const carve::csg::V2Set &split_edges) { + std::map::vertex_t *, carve::geom2d::P2> proj; + + for (size_t i = 0; i < base_loop.size(); ++i) { + proj[base_loop[i]] = face->project(base_loop[i]->v); + } + for (carve::csg::V2Set::const_iterator i = split_edges.begin(); i != split_edges.end(); ++i) { + proj[(*i).first] = face->project((*i).first->v); + proj[(*i).second] = face->project((*i).second->v); + } + + { + carve::geom2d::P2 lo, hi; + std::map::vertex_t *, carve::geom2d::P2>::iterator i; + i = proj.begin(); + lo = hi = (*i).second; + for (; i != proj.end(); ++i) { + lo.x = std::min(lo.x, (*i).second.x); lo.y = std::min(lo.y, (*i).second.y); + hi.x = std::max(hi.x, (*i).second.x); hi.y = std::max(hi.y, (*i).second.y); + } + for (i = proj.begin(); i != proj.end(); ++i) { + (*i).second.x = ((*i).second.x - lo.x) / (hi.x - lo.x) * 10; + (*i).second.y = ((*i).second.y - lo.y) / (hi.y - lo.y) * 10; + } + } + + std::cerr << "graph G {\nnode [shape=circle,style=filled,fixedsize=true,width=\".1\",height=\".1\"];\nedge [len=4]\n"; + for (std::map::vertex_t *, carve::geom2d::P2>::iterator i = proj.begin(); i != proj.end(); ++i) { + std::cerr << " " << ptrstr((*i).first) << " [pos=\"" << (*i).second.x << "," << (*i).second.y << "!\"];\n"; + } + for (carve::csg::V2Set::const_iterator i = face_edges.begin(); i != face_edges.end(); ++i) { + std::cerr << " " << ptrstr((*i).first) << " -- " << ptrstr((*i).second) << ";\n"; + } + for (carve::csg::V2Set::const_iterator i = split_edges.begin(); i != split_edges.end(); ++i) { + std::cerr << " " << ptrstr((*i).first) << " -- " << ptrstr((*i).second) << " [color=\"blue\"];\n"; + } + std::cerr << "};\n"; + } + + void generateOneFaceLoop(carve::mesh::MeshSet<3>::face_t *face, + const carve::csg::detail::Data &data, + const carve::csg::VertexIntersections &vertex_intersections, + carve::csg::CSG::Hooks &hooks, + std::list::vertex_t *> > &face_loops) { + using namespace carve::csg; + + std::vector::vertex_t *> base_loop; + std::list::vertex_t *> > hole_loops; + + bool face_edge_intersected = assembleBaseLoop(face, data, base_loop); + + detail::FV2SMap::const_iterator fse_iter = data.face_split_edges.find(face); + + face_loops.clear(); + + if (fse_iter == data.face_split_edges.end()) { + // simple case: input face is output face (possibly with the + // addition of vertices at intersections). + face_loops.push_back(base_loop); + return; + } + + // complex case: input face is split into multiple output faces. + V2Set face_edges; + + for (size_t j = 0, je = base_loop.size() - 1; j < je; ++j) { + face_edges.insert(std::make_pair(base_loop[j], base_loop[j + 1])); + } + face_edges.insert(std::make_pair(base_loop.back(), base_loop[0])); + + // collect the split edges (as long as they're not on the perimeter) + const detail::FV2SMap::mapped_type &fse = ((*fse_iter).second); + + // split_edges contains all of the edges created by intersections + // that aren't part of the perimeter of the face. + V2Set split_edges; + + for (detail::FV2SMap::mapped_type::const_iterator + j = fse.begin(), je = fse.end(); + j != je; + ++j) { + carve::mesh::MeshSet<3>::vertex_t *v1 = ((*j).first), *v2 = ((*j).second); + + if (face_edges.find(std::make_pair(v1, v2)) == face_edges.end() && + face_edges.find(std::make_pair(v2, v1)) == face_edges.end()) { + // If the edge isn't part of the face perimeter, add it to + // split_edges. + split_edges.insert(ordered_edge(v1, v2)); + } + } + + // face is unsplit. + if (!split_edges.size()) { + face_loops.push_back(base_loop); + return; + } + +#if defined(CARVE_DEBUG) + dumpAsGraph(face, base_loop, face_edges, split_edges); +#endif + +#if 0 + // old face splitting method. + for (V2Set::const_iterator i = split_edges.begin(); i != split_edges.end(); ++i) { + face_edges.insert(std::make_pair((*i).first, (*i).second)); + face_edges.insert(std::make_pair((*i).second, (*i).first)); + } + splitFace(face, face_edges, face_loops, hole_loops, vertex_intersections); + + if (hole_loops.size()) { + mergeFacesAndHoles(face, face_loops, hole_loops, hooks); + } + return; +#endif + +#if defined(CARVE_DEBUG) + std::cerr << "### split_edges.size(): " << split_edges.size() << std::endl; +#endif + if (split_edges.size() == 1) { + // handle the common case of a face that's split by a single edge. + carve::mesh::MeshSet<3>::vertex_t *v1 = split_edges.begin()->first; + carve::mesh::MeshSet<3>::vertex_t *v2 = split_edges.begin()->second; + + std::vector::vertex_t *>::iterator vi1 = std::find(base_loop.begin(), base_loop.end(), v1); + std::vector::vertex_t *>::iterator vi2 = std::find(base_loop.begin(), base_loop.end(), v2); + + if (vi1 != base_loop.end() && vi2 != base_loop.end()) { + // this is an inserted edge that connects two points on the base loop. nice and simple. + if (vi2 < vi1) std::swap(vi1, vi2); + + size_t loop1_size = vi2 - vi1 + 1; + size_t loop2_size = base_loop.size() + 2 - loop1_size; + + std::vector::vertex_t *> l1; + std::vector::vertex_t *> l2; + + l1.reserve(loop1_size); + l2.reserve(loop2_size); + + std::copy(vi1, vi2+1, std::back_inserter(l1)); + std::copy(vi2, base_loop.end(), std::back_inserter(l2)); + std::copy(base_loop.begin(), vi1+1, std::back_inserter(l2)); + + CARVE_ASSERT(l1.size() == loop1_size); + CARVE_ASSERT(l2.size() == loop2_size); + + face_loops.push_back(l1); + face_loops.push_back(l2); + + return; + } + + // Consider handling cases where one end of the edge touches the + // perimeter, and where neither end does. + } + + std::vector::vertex_t *> > paths; + std::vector::vertex_t *> > cuts; + std::vector::vertex_t *> > loops; + + // Take the split edges and compose them into a set of paths and + // loops. Loops are edge paths that do not touch the boundary, or + // any other path or loop - they are holes cut out of the centre + // of the face. Paths are made up of all the other edge segments, + // and start and end at the face perimeter, or where they meet + // another path (sometimes both cases will be true). + composeEdgesIntoPaths(split_edges, base_loop, paths, cuts, loops); + +#if defined(CARVE_DEBUG) + std::cerr << "### paths.size(): " << paths.size() << std::endl; + std::cerr << "### cuts.size(): " << cuts.size() << std::endl; + std::cerr << "### loops.size(): " << loops.size() << std::endl; +#endif + + if (!paths.size()) { + // No complex paths. + face_loops.push_back(base_loop); + } else { + if (processCrossingEdges(face, vertex_intersections, hooks, base_loop, paths, face_loops)) { + // Worked. + } else { + // complex case - fall back to old edge tracing code. +#if defined(CARVE_DEBUG) + std::cerr << "### processCrossingEdges failed. Falling back to edge tracing code" << std::endl; +#endif + for (size_t i = 0; i < paths.size(); ++i) { + for (size_t j = 0; j < paths[i].size() - 1; ++j) { + face_edges.insert(std::make_pair(paths[i][j], paths[i][j+1])); + face_edges.insert(std::make_pair(paths[i][j+1], paths[i][j])); + } + } + splitFace(face, face_edges, face_loops, hole_loops, vertex_intersections); + } + } + + // Now merge cuts and loops into face loops. + + // every cut creates a hole. + for (size_t i = 0; i < cuts.size(); ++i) { + hole_loops.push_back(std::vector::vertex_t *>()); + hole_loops.back().reserve(2 * cuts[i].size() - 2); + std::copy(cuts[i].begin(), cuts[i].end(), std::back_inserter(hole_loops.back())); + if (cuts[i].size() > 2) { + std::copy(cuts[i].rbegin() + 1, cuts[i].rend() - 1, std::back_inserter(hole_loops.back())); + } + } + + // every loop creates a hole and a corresponding face. + for (size_t i = 0; i < loops.size(); ++i) { + hole_loops.push_back(std::vector::vertex_t *>()); + hole_loops.back().reserve(loops[i].size()-1); + std::copy(loops[i].begin(), loops[i].end()-1, std::back_inserter(hole_loops.back())); + + face_loops.push_back(std::vector::vertex_t *>()); + face_loops.back().reserve(loops[i].size()-1); + std::copy(loops[i].rbegin()+1, loops[i].rend(), std::back_inserter(face_loops.back())); + + std::vector projected; + projected.reserve(face_loops.back().size()); + for (size_t i = 0; i < face_loops.back().size(); ++i) { + projected.push_back(face->project(face_loops.back()[i]->v)); + } + + if (carve::geom2d::signedArea(projected) > 0.0) { + std::swap(face_loops.back(), hole_loops.back()); + } + } + + // if there are holes, then they need to be merged with faces. + if (hole_loops.size()) { + mergeFacesAndHoles(face, face_loops, hole_loops, hooks); + } + } +} + + + +/** + * \brief Build a set of face loops for all (split) faces of a Polyhedron. + * + * @param[in] poly The polyhedron to process + * @param vmap + * @param face_split_edges + * @param divided_edges + * @param[out] face_loops_out The resulting face loops + * + * @return The number of edges generated. + */ +size_t carve::csg::CSG::generateFaceLoops(carve::mesh::MeshSet<3> *poly, + const detail::Data &data, + FaceLoopList &face_loops_out) { + static carve::TimingName FUNC_NAME("CSG::generateFaceLoops()"); + carve::TimingBlock block(FUNC_NAME); + size_t generated_edges = 0; + std::vector::vertex_t *> base_loop; + std::list::vertex_t *> > face_loops; + + for (carve::mesh::MeshSet<3>::face_iter i = poly->faceBegin(); i != poly->faceEnd(); ++i) { + carve::mesh::MeshSet<3>::face_t *face = (*i); + +#if defined(CARVE_DEBUG) + double in_area = 0.0, out_area = 0.0; + + { + std::vector::vertex_t *> base_loop; + assembleBaseLoop(face, data, base_loop); + + { + std::vector projected; + projected.reserve(base_loop.size()); + for (size_t n = 0; n < base_loop.size(); ++n) { + projected.push_back(face->project(base_loop[n]->v)); + } + + in_area = carve::geom2d::signedArea(projected); + std::cerr << "### in_area=" << in_area << std::endl; + } + } +#endif + + generateOneFaceLoop(face, data, vertex_intersections, hooks, face_loops); + +#if defined(CARVE_DEBUG) + { + V2Set face_edges; + + std::vector::vertex_t *> base_loop; + assembleBaseLoop(face, data, base_loop); + + for (size_t j = 0, je = base_loop.size() - 1; j < je; ++j) { + face_edges.insert(std::make_pair(base_loop[j+1], base_loop[j])); + } + face_edges.insert(std::make_pair(base_loop[0], base_loop.back())); + for (std::list::vertex_t *> >::const_iterator fli = face_loops.begin(); fli != face_loops.end(); ++ fli) { + + { + std::vector projected; + projected.reserve((*fli).size()); + for (size_t n = 0; n < (*fli).size(); ++n) { + projected.push_back(face->project((*fli)[n]->v)); + } + + double area = carve::geom2d::signedArea(projected); + std::cerr << "### loop_area[" << std::distance((std::list::vertex_t *> >::const_iterator)face_loops.begin(), fli) << "]=" << area << std::endl; + out_area += area; + } + + const std::vector::vertex_t *> &fl = *fli; + for (size_t j = 0, je = fl.size() - 1; j < je; ++j) { + face_edges.insert(std::make_pair(fl[j], fl[j+1])); + } + face_edges.insert(std::make_pair(fl.back(), fl[0])); + } + for (V2Set::const_iterator j = face_edges.begin(); j != face_edges.end(); ++j) { + if (face_edges.find(std::make_pair((*j).second, (*j).first)) == face_edges.end()) { + std::cerr << "### error: unmatched edge [" << (*j).first << "-" << (*j).second << "]" << std::endl; + } + } + std::cerr << "### out_area=" << out_area << std::endl; + if (out_area != in_area) { + std::cerr << "### error: area does not match. delta = " << (out_area - in_area) << std::endl; + // CARVE_ASSERT(fabs(out_area - in_area) < 1e-5); + } + } +#endif + + // now record all the resulting face loops. +#if defined(CARVE_DEBUG) + std::cerr << "### ======" << std::endl; +#endif + for (std::list::vertex_t *> >::const_iterator + f = face_loops.begin(), fe = face_loops.end(); + f != fe; + ++f) { +#if defined(CARVE_DEBUG) + std::cerr << "### loop:"; + for (size_t i = 0; i < (*f).size(); ++i) { + std::cerr << " " << (*f)[i]; + } + std::cerr << std::endl; +#endif + + face_loops_out.append(new FaceLoop(face, *f)); + generated_edges += (*f).size(); + } +#if defined(CARVE_DEBUG) + std::cerr << "### ======" << std::endl; +#endif + } + return generated_edges; +} diff -Nru blender-2.61/extern/carve/lib/intersect_group.cpp blender-2.62/extern/carve/lib/intersect_group.cpp --- blender-2.61/extern/carve/lib/intersect_group.cpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/intersect_group.cpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,232 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#if defined(HAVE_CONFIG_H) +# include +#endif + +#include +#include + +#include "csg_detail.hpp" +#include "intersect_common.hpp" + +void carve::csg::CSG::makeEdgeMap(const carve::csg::FaceLoopList &loops, + size_t edge_count, + detail::LoopEdges &edge_map) { +#if defined(UNORDERED_COLLECTIONS_SUPPORT_RESIZE) + edge_map.resize(edge_count); +#endif + + for (carve::csg::FaceLoop *i = loops.head; i; i = i->next) { + edge_map.addFaceLoop(i); + i->group = NULL; + } +} + +#include + +#if defined(CARVE_DEBUG_WRITE_PLY_DATA) +void writePLY(const std::string &out_file, const carve::mesh::MeshSet<3> *poly, bool ascii); +void writePLY(const std::string &out_file, const carve::line::PolylineSet *lines, bool ascii); +#endif + +void carve::csg::CSG::findSharedEdges(const detail::LoopEdges &edge_map_a, + const detail::LoopEdges &edge_map_b, + V2Set &shared_edges) { + for (detail::LoopEdges::const_iterator + i = edge_map_a.begin(), e = edge_map_a.end(); + i != e; + ++i) { + detail::LoopEdges::const_iterator j = edge_map_b.find((*i).first); + if (j != edge_map_b.end()) { + shared_edges.insert((*i).first); + } + } + +#if defined(CARVE_DEBUG) + detail::VVSMap edge_graph; + + for (V2Set::const_iterator i = shared_edges.begin(); i != shared_edges.end(); ++i) { + edge_graph[(*i).first].insert((*i).second); + edge_graph[(*i).second].insert((*i).first); + } + + std::cerr << "*** testing consistency of edge graph" << std::endl; + for (detail::VVSMap::const_iterator i = edge_graph.begin(); i != edge_graph.end(); ++i) { + if ((*i).second.size() > 2) { + std::cerr << "branch at: " << (*i).first << std::endl; + } + if ((*i).second.size() == 1) { + std::cerr << "endpoint at: " << (*i).first << std::endl; + std::cerr << "coordinate: " << (*i).first->v << std::endl; + } + } + + { + carve::line::PolylineSet intersection_graph; + intersection_graph.vertices.resize(edge_graph.size()); + std::map::vertex_t *, size_t> vmap; + + size_t j = 0; + for (detail::VVSMap::const_iterator i = edge_graph.begin(); i != edge_graph.end(); ++i) { + intersection_graph.vertices[j].v = (*i).first->v; + vmap[(*i).first] = j++; + } + + while (edge_graph.size()) { + detail::VVSMap::iterator prior_i = edge_graph.begin(); + carve::mesh::MeshSet<3>::vertex_t *prior = (*prior_i).first; + std::vector connected; + connected.push_back(vmap[prior]); + while (prior_i != edge_graph.end() && (*prior_i).second.size()) { + carve::mesh::MeshSet<3>::vertex_t *next = *(*prior_i).second.begin(); + detail::VVSMap::iterator next_i = edge_graph.find(next); + CARVE_ASSERT(next_i != edge_graph.end()); + connected.push_back(vmap[next]); + (*prior_i).second.erase(next); + (*next_i).second.erase(prior); + if (!(*prior_i).second.size()) { edge_graph.erase(prior_i); prior_i = edge_graph.end(); } + if (!(*next_i).second.size()) { edge_graph.erase(next_i); next_i = edge_graph.end(); } + prior_i = next_i; + prior = next; + } + bool closed = connected.front() == connected.back(); + for (size_t k = 0; k < connected.size(); ++k) { + std::cerr << " " << connected[k]; + } + std::cerr << std::endl; + intersection_graph.addPolyline(closed, connected.begin(), connected.end()); + } + +#if defined(CARVE_DEBUG_WRITE_PLY_DATA) + std::string out("/tmp/intersection.ply"); + ::writePLY(out, &intersection_graph, true); +#endif + } + + std::cerr << "*** edge graph consistency test done" << std::endl; +#endif +} + + + +#if defined(CARVE_DEBUG_WRITE_PLY_DATA) +static carve::mesh::MeshSet<3> *groupToPolyhedron(const carve::csg::FaceLoopGroup &grp) { + const carve::csg::FaceLoopList &fl = grp.face_loops; + std::vector::face_t *> faces; + faces.reserve(fl.size()); + for (carve::csg::FaceLoop *f = fl.head; f; f = f->next) { + faces.push_back(f->orig_face->create(f->vertices.begin(), f->vertices.end(), false)); + } + carve::mesh::MeshSet<3> *poly = new carve::mesh::MeshSet<3>(faces); + + poly->canonicalize(); + return poly; +} +#endif + + + +void carve::csg::CSG::groupFaceLoops(carve::mesh::MeshSet<3> *src, + carve::csg::FaceLoopList &face_loops, + const carve::csg::detail::LoopEdges &loop_edges, + const carve::csg::V2Set &no_cross, + carve::csg::FLGroupList &out_loops) { + // Find all the groups of face loops that are connected by edges + // that are not part of no_cross. + // this could potentially be done with a disjoint set data-structure. +#if defined(CARVE_DEBUG_WRITE_PLY_DATA) + static int call_num = 0; + call_num++; +#endif + + static carve::TimingName GROUP_FACE_LOOPS("groupFaceLoops()"); + + carve::TimingBlock block(GROUP_FACE_LOOPS); + + int tag_num = 0; + while (face_loops.size()) { + out_loops.push_back(FaceLoopGroup(src)); + carve::csg::FaceLoopGroup &group = (out_loops.back()); + carve::csg::FaceLoopList &curr = (group.face_loops); + carve::csg::V2Set &perim = (group.perimeter); + + carve::csg::FaceLoop *expand = face_loops.head; + + expand->group = &group; + face_loops.remove(expand); + curr.append(expand); + + while (expand) { + std::vector::vertex_t *> &loop = (expand->vertices); + carve::mesh::MeshSet<3>::vertex_t *v1, *v2; + + v1 = loop.back(); + for (size_t i = 0; i < loop.size(); ++i) { + v2 = loop[i]; + + carve::csg::V2Set::const_iterator nc = no_cross.find(std::make_pair(v1, v2)); + if (nc == no_cross.end()) { + carve::csg::detail::LoopEdges::const_iterator j; + + j = loop_edges.find(std::make_pair(v1, v2)); + if (j != loop_edges.end()) { + for (std::list::const_iterator + k = (*j).second.begin(), ke = (*j).second.end(); + k != ke; ++k) { + if ((*k)->group != NULL || + (*k)->orig_face->mesh != expand->orig_face->mesh) continue; + face_loops.remove((*k)); + curr.append((*k)); + (*k)->group = &group; + } + } + + j = loop_edges.find(std::make_pair(v2, v1)); + if (j != loop_edges.end()) { + for (std::list::const_iterator + k = (*j).second.begin(), ke = (*j).second.end(); + k != ke; ++k) { + if ((*k)->group != NULL || + (*k)->orig_face->mesh != expand->orig_face->mesh) continue; + face_loops.remove((*k)); + curr.append((*k)); + (*k)->group = &group; + } + } + } else { + perim.insert(std::make_pair(v1, v2)); + } + v1 = v2; + } + expand = expand->next; + } + tag_num++; + +#if defined(CARVE_DEBUG_WRITE_PLY_DATA) + { + carve::mesh::MeshSet<3> *poly = groupToPolyhedron(group); + char buf[128]; + sprintf(buf, "/tmp/group-%d-%p.ply", call_num, &curr); + std::string out(buf); + ::writePLY(out, poly, false); + delete poly; + } +#endif + } +} diff -Nru blender-2.61/extern/carve/lib/intersect_half_classify_group.cpp blender-2.62/extern/carve/lib/intersect_half_classify_group.cpp --- blender-2.61/extern/carve/lib/intersect_half_classify_group.cpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/intersect_half_classify_group.cpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,199 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#if defined(HAVE_CONFIG_H) +# include +#endif + +#include +#include + +#include +#include +#include + +#include + +#include "intersect_common.hpp" +#include "intersect_classify_common.hpp" +#include "intersect_classify_common_impl.hpp" + +namespace carve { + namespace csg { + + namespace { + struct GroupPoly : public CSG::Collector { + carve::mesh::MeshSet<3> *want_groups_from; + std::list *> > &out; + + GroupPoly(carve::mesh::MeshSet<3> *poly, + std::list *> > &_out) : CSG::Collector(), want_groups_from(poly), out(_out) { + } + + virtual ~GroupPoly() { + } + + virtual void collect(FaceLoopGroup *grp, CSG::Hooks & /* hooks */) { + if (grp->face_loops.head->orig_face->mesh->meshset != want_groups_from) return; + + std::list &cinfo = (grp->classification); + if (cinfo.size() == 0) { + std::cerr << "WARNING! group " << grp << " has no classification info!" << std::endl; + return; + } + // XXX: check all the cinfo elements for consistency. + FaceClass fc = cinfo.front().classification; + + std::vector::face_t *> faces; + faces.reserve(grp->face_loops.size()); + for (FaceLoop *loop = grp->face_loops.head; loop != NULL; loop = loop->next) { + faces.push_back(loop->orig_face->create(loop->vertices.begin(), loop->vertices.end(), false)); + } + + out.push_back(std::make_pair(fc, new carve::mesh::MeshSet<3>(faces))); + } + + virtual carve::mesh::MeshSet<3> *done(CSG::Hooks & /* hooks */) { + return NULL; + } + }; + + class FaceMaker { + public: + + bool pointOn(VertexClassification &vclass, FaceLoop *f, size_t index) const { + return vclass[f->vertices[index]].cls[0] == POINT_ON; + } + + void explain(FaceLoop *f, size_t index, PointClass pc) const { +#if defined(CARVE_DEBUG) + std::cerr << "face loop " << f << " from poly b is easy because vertex " << index << " (" << f->vertices[index]->v << ") is " << ENUM(pc) << std::endl; +#endif + } + }; + + class HalfClassifyFaceGroups { + HalfClassifyFaceGroups &operator=(const HalfClassifyFaceGroups &); + + public: + std::list *> > &b_out; + CSG::Hooks &hooks; + + HalfClassifyFaceGroups(std::list *> > &c, CSG::Hooks &h) : b_out(c), hooks(h) { + } + + void classifySimple(FLGroupList &a_loops_grouped, + FLGroupList &b_loops_grouped, + VertexClassification & /* vclass */, + carve::mesh::MeshSet<3> *poly_a, + carve::mesh::MeshSet<3> *poly_b) const { + GroupPoly group_poly(poly_b, b_out); + performClassifySimpleOnFaceGroups(a_loops_grouped, b_loops_grouped, poly_a, poly_b, group_poly, hooks); +#if defined(CARVE_DEBUG) + std::cerr << "after removal of simple on groups: " << b_loops_grouped.size() << " b groups" << std::endl; +#endif + } + + void classifyEasy(FLGroupList & /* a_loops_grouped */, + FLGroupList &b_loops_grouped, + VertexClassification & vclass, + carve::mesh::MeshSet<3> *poly_a, + const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *poly_a_rtree, + carve::mesh::MeshSet<3> *poly_b, + const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *poly_b_rtree) const { + GroupPoly group_poly(poly_b, b_out); + performClassifyEasyFaceGroups(b_loops_grouped, poly_a, poly_a_rtree, vclass, FaceMaker(), group_poly, hooks); +#if defined(CARVE_DEBUG) + std::cerr << "after removal of easy groups: " << b_loops_grouped.size() << " b groups" << std::endl; +#endif + } + + void classifyHard(FLGroupList & /* a_loops_grouped */, + FLGroupList &b_loops_grouped, + VertexClassification & /* vclass */, + carve::mesh::MeshSet<3> *poly_a, + const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *poly_a_rtree, + carve::mesh::MeshSet<3> *poly_b, + const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *poly_b_rtree) const { + GroupPoly group_poly(poly_b, b_out); + performClassifyHardFaceGroups(b_loops_grouped, poly_a, poly_a_rtree, FaceMaker(), group_poly, hooks); +#if defined(CARVE_DEBUG) + std::cerr << "after removal of hard groups: " << b_loops_grouped.size() << " b groups" << std::endl; +#endif + + } + + void faceLoopWork(FLGroupList & /* a_loops_grouped */, + FLGroupList &b_loops_grouped, + VertexClassification & /* vclass */, + carve::mesh::MeshSet<3> *poly_a, + const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *poly_a_rtree, + carve::mesh::MeshSet<3> *poly_b, + const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *poly_b_rtree) const { + GroupPoly group_poly(poly_b, b_out); + performFaceLoopWork(poly_a, poly_a_rtree, b_loops_grouped, *this, group_poly, hooks); + } + + void postRemovalCheck(FLGroupList & /* a_loops_grouped */, + FLGroupList &b_loops_grouped) const { +#if defined(CARVE_DEBUG) + std::cerr << "after removal of on groups: " << b_loops_grouped.size() << " b groups" << std::endl; +#endif + } + + bool faceLoopSanityChecker(FaceLoopGroup &i) const { + return false; + return i.face_loops.size() != 1; + } + + void finish(FLGroupList &a_loops_grouped,FLGroupList &b_loops_grouped) const { +#if defined(CARVE_DEBUG) + if (a_loops_grouped.size() || b_loops_grouped.size()) + std::cerr << "UNCLASSIFIED! a=" << a_loops_grouped.size() << ", b=" << b_loops_grouped.size() << std::endl; +#endif + } + }; + } + + void CSG::halfClassifyFaceGroups(const V2Set & /* shared_edges */, + VertexClassification &vclass, + carve::mesh::MeshSet<3> *poly_a, + const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *poly_a_rtree, + FLGroupList &a_loops_grouped, + const detail::LoopEdges & /* a_edge_map */, + carve::mesh::MeshSet<3> *poly_b, + const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *poly_b_rtree, + FLGroupList &b_loops_grouped, + const detail::LoopEdges & /* b_edge_map */, + std::list *> > &b_out) { + HalfClassifyFaceGroups classifier(b_out, hooks); + GroupPoly group_poly(poly_b, b_out); + performClassifyFaceGroups( + a_loops_grouped, + b_loops_grouped, + vclass, + poly_a, + poly_a_rtree, + poly_b, + poly_b_rtree, + classifier, + group_poly, + hooks); + } + + } +} diff -Nru blender-2.61/extern/carve/lib/intersection.cpp blender-2.62/extern/carve/lib/intersection.cpp --- blender-2.61/extern/carve/lib/intersection.cpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/intersection.cpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,92 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#if defined(HAVE_CONFIG_H) +# include +#endif + +#include + +#include +#include +#include +#include + + + +void carve::csg::Intersections::collect(const IObj &obj, + std::vector::vertex_t *> *collect_v, + std::vector::edge_t *> *collect_e, + std::vector::face_t *> *collect_f) const { + carve::csg::Intersections::const_iterator i = find(obj); + if (i != end()) { + Intersections::mapped_type::const_iterator a, b; + for (a = (*i).second.begin(), b = (*i).second.end(); a != b; ++a) { + switch ((*a).first.obtype) { + case carve::csg::IObj::OBTYPE_VERTEX: + if (collect_v) collect_v->push_back((*a).first.vertex); + break; + case carve::csg::IObj::OBTYPE_EDGE: + if (collect_e) collect_e->push_back((*a).first.edge); + break; + case carve::csg::IObj::OBTYPE_FACE: + if (collect_f) collect_f->push_back((*a).first.face); + break; + default: + throw carve::exception("should not happen " __FILE__ ":" XSTR(__LINE__)); + } + } + } +} + + + +bool carve::csg::Intersections::intersectsFace(carve::mesh::MeshSet<3>::vertex_t *v, + carve::mesh::MeshSet<3>::face_t *f) const { + const_iterator i = find(v); + if (i != end()) { + mapped_type::const_iterator a, b; + + for (a = (*i).second.begin(), b = (*i).second.end(); a != b; ++a) { + switch ((*a).first.obtype) { + case IObj::OBTYPE_VERTEX: { + const carve::mesh::MeshSet<3>::edge_t *edge = f->edge; + do { + if (edge->vert == (*a).first.vertex) return true; + edge = edge->next; + } while (edge != f->edge); + break; + } + case carve::csg::IObj::OBTYPE_EDGE: { + const carve::mesh::MeshSet<3>::edge_t *edge = f->edge; + do { + if (edge == (*a).first.edge) return true; + edge = edge->next; + } while (edge != f->edge); + break; + } + case carve::csg::IObj::OBTYPE_FACE: { + if ((*a).first.face == f) return true; + break; + } + default: + throw carve::exception("should not happen " __FILE__ ":" XSTR(__LINE__)); + } + } + } + return false; +} diff -Nru blender-2.61/extern/carve/lib/math.cpp blender-2.62/extern/carve/lib/math.cpp --- blender-2.61/extern/carve/lib/math.cpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/math.cpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,347 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#if defined(HAVE_CONFIG_H) +# include +#endif + +#include +#include + +#include +#include + +#include + +#define M_2PI_3 2.0943951023931953 +#define M_SQRT_3_4 0.8660254037844386 +#define EPS std::numeric_limits::epsilon() + +namespace carve { + namespace math { + + struct Root { + double root; + int multiplicity; + + Root(double r) : root(r), multiplicity(1) {} + Root(double r, int m) : root(r), multiplicity(m) {} + }; + + void cplx_sqrt(double re, double im, + double &re_1, double &im_1, + double &re_2, double &im_2) { + if (re == 0.0 && im == 0.0) { + re_1 = re_2 = re; + im_1 = im_2 = im; + } else { + double d = sqrt(re * re + im * im); + re_1 = sqrt((d + re) / 2.0); + re_2 = re_1; + im_1 = fabs(sqrt((d - re) / 2.0)); + im_2 = -im_1; + } + } + + void cplx_cbrt(double re, double im, + double &re_1, double &im_1, + double &re_2, double &im_2, + double &re_3, double &im_3) { + if (re == 0.0 && im == 0.0) { + re_1 = re_2 = re_3 = re; + im_1 = im_2 = im_3 = im; + } else { + double r = cbrt(sqrt(re * re + im * im)); + double t = atan2(im, re) / 3.0; + re_1 = r * cos(t); + im_1 = r * sin(t); + re_2 = r * cos(t + M_TWOPI / 3.0); + im_2 = r * sin(t + M_TWOPI / 3.0); + re_3 = r * cos(t + M_TWOPI * 2.0 / 3.0); + im_3 = r * sin(t + M_TWOPI * 2.0 / 3.0); + } + } + + void add_root(std::vector &roots, double root) { + for (size_t i = 0; i < roots.size(); ++i) { + if (roots[i].root == root) { + roots[i].multiplicity++; + return; + } + } + roots.push_back(Root(root)); + } + + void linear_roots(double c1, double c0, std::vector &roots) { + roots.push_back(Root(c0 / c1)); + } + + void quadratic_roots(double c2, double c1, double c0, std::vector &roots) { + if (fabs(c2) < EPS) { + linear_roots(c1, c0, roots); + return; + } + + double p = 0.5 * c1 / c2; + double dis = p * p - c0 / c2; + + if (dis > 0.0) { + dis = sqrt(dis); + if (-p - dis != -p + dis) { + roots.push_back(Root(-p - dis)); + roots.push_back(Root(-p + dis)); + } else { + roots.push_back(Root(-p, 2)); + } + } + } + + void cubic_roots(double c3, double c2, double c1, double c0, std::vector &roots) { + int n_sol = 0; + double _r[3]; + + if (fabs(c3) < EPS) { + quadratic_roots(c2, c1, c0, roots); + return; + } + + if (fabs(c0) < EPS) { + quadratic_roots(c3, c2, c1, roots); + add_root(roots, 0.0); + return; + } + + double xN = -c2 / (3.0 * c3); + double yN = c0 + xN * (c1 + xN * (c2 + c3 * xN)); + + double delta_sq = (c2 * c2 - 3.0 * c3 * c1) / (9.0 * c3 * c3); + double h_sq = 4.0 / 9.0 * (c2 * c2 - 3.0 * c3 * c1) * (delta_sq * delta_sq); + double dis = yN * yN - h_sq; + + if (dis > EPS) { + // One real root, two complex roots. + + double dis_sqrt = sqrt(dis); + double r_p = yN - dis_sqrt; + double r_q = yN + dis_sqrt; + double p = cbrt(fabs(r_p)/(2.0 * c3)); + double q = cbrt(fabs(r_q)/(2.0 * c3)); + + if (r_p > 0.0) p = -p; + if (r_q > 0.0) q = -q; + + _r[0] = xN + p + q; + n_sol = 1; + + double re = xN - p * .5 - q * .5; + double im = p * M_SQRT_3_4 - q * M_SQRT_3_4; + + // root 2: xN + p * exp(M_2PI_3.i) + q * exp(-M_2PI_3.i); + // root 3: complex conjugate of root 2 + + if (im < EPS) { + _r[1] = _r[2] = re; + n_sol += 2; + } + } else if (dis < -EPS) { + // Three distinct real roots. + double theta = acos(-yN / sqrt(h_sq)) / 3.0; + double delta = sqrt(c2 * c2 - 3.0 * c3 * c1) / (3.0 * c3); + + _r[0] = xN + (2.0 * delta) * cos(theta); + _r[1] = xN + (2.0 * delta) * cos(M_2PI_3 - theta); + _r[2] = xN + (2.0 * delta) * cos(M_2PI_3 + theta); + n_sol = 3; + } else { + // Three real roots (two or three equal). + double r = yN / (2.0 * c3); + double delta = cbrt(r); + + _r[0] = xN + delta; + _r[1] = xN + delta; + _r[2] = xN - 2.0 * delta; + n_sol = 3; + } + + for (int i=0; i < n_sol; i++) { + add_root(roots, _r[i]); + } + } + + static void U(const Matrix3 &m, + double l, + double u[6], + double &u_max, + int &u_argmax) { + u[0] = (m._22 - l) * (m._33 - l) - m._23 * m._23; + u[1] = m._13 * m._23 - m._12 * (m._33 - l); + u[2] = m._12 * m._23 - m._13 * (m._22 - l); + u[3] = (m._11 - l) * (m._33 - l) - m._13 * m._13; + u[4] = m._12 * m._13 - m._23 * (m._11 - l); + u[5] = (m._11 - l) * (m._22 - l) - m._12 * m._12; + + u_max = -1.0; + u_argmax = -1; + + for (int i = 0; i < 6; ++i) { + if (u_max < fabs(u[i])) { u_max = fabs(u[i]); u_argmax = i; } + } + } + + static void eig1(const Matrix3 &m, double l, carve::geom::vector<3> &e) { + double u[6]; + double u_max; + int u_argmax; + + U(m, l, u, u_max, u_argmax); + + switch(u_argmax) { + case 0: + e.x = u[0]; e.y = u[1]; e.z = u[2]; break; + case 1: case 3: + e.x = u[1]; e.y = u[3]; e.z = u[4]; break; + case 2: case 4: case 5: + e.x = u[2]; e.y = u[4]; e.z = u[5]; break; + } + e.normalize(); + } + + static void eig2(const Matrix3 &m, double l, carve::geom::vector<3> &e1, carve::geom::vector<3> &e2) { + double u[6]; + double u_max; + int u_argmax; + + U(m, l, u, u_max, u_argmax); + + switch(u_argmax) { + case 0: case 1: + e1.x = -m._12; e1.y = m._11; e1.z = 0.0; + e2.x = -m._13 * m._11; e2.y = -m._13 * m._12; e2.z = m._11 * m._11 + m._12 * m._12; + break; + case 2: + e1.x = m._12; e1.y = 0.0; e1.z = -m._11; + e2.x = -m._12 * m._11; e2.y = m._11 * m._11 + m._13 * m._13; e2.z = -m._12 * m._13; + break; + case 3: case 4: + e1.x = 0.0; e1.y = -m._23; e1.z = -m._22; + e2.x = m._22 * m._22 + m._23 * m._23; e2.y = -m._12 * m._22; e2.z = -m._12 * m._23; + break; + case 5: + e1.x = 0.0; e1.y = -m._33; e1.z = m._23; + e2.x = m._23 * m._23 + m._33 * m._33; e2.y = -m._13 * m._23; e2.z = -m._13 * m._33; + } + e1.normalize(); + e2.normalize(); + } + + static void eig3(const Matrix3 &m, + double l, + carve::geom::vector<3> &e1, + carve::geom::vector<3> &e2, + carve::geom::vector<3> &e3) { + e1.x = 1.0; e1.y = 0.0; e1.z = 0.0; + e2.x = 0.0; e2.y = 1.0; e2.z = 0.0; + e3.x = 0.0; e3.y = 0.0; e3.z = 1.0; + } + + void eigSolveSymmetric(const Matrix3 &m, + double &l1, carve::geom::vector<3> &e1, + double &l2, carve::geom::vector<3> &e2, + double &l3, carve::geom::vector<3> &e3) { + double c0 = + m._11 * m._22 * m._33 + + 2.0 * m._12 * m._13 * m._23 - + m._11 * m._23 * m._23 - + m._22 * m._13 * m._13 - + m._33 * m._12 * m._12; + double c1 = + m._11 * m._22 - + m._12 * m._12 + + m._11 * m._33 - + m._13 * m._13 + + m._22 * m._33 - + m._23 * m._23; + double c2 = + m._11 + + m._22 + + m._33; + + double a = (3.0 * c1 - c2 * c2) / 3.0; + double b = (-2.0 * c2 * c2 * c2 + 9.0 * c1 * c2 - 27.0 * c0) / 27.0; + + double Q = b * b / 4.0 + a * a * a / 27.0; + + if (fabs(Q) < 1e-16) { + l1 = m._11; e1.x = 1.0; e1.y = 0.0; e1.z = 0.0; + l2 = m._22; e2.x = 0.0; e2.y = 1.0; e2.z = 0.0; + l3 = m._33; e3.x = 0.0; e3.y = 0.0; e3.z = 1.0; + } else if (Q > 0) { + l1 = l2 = c2 / 3.0 + cbrt(b / 2.0); + l3 = c2 / 3.0 - 2.0 * cbrt(b / 2.0); + + eig2(m, l1, e1, e2); + eig1(m, l3, e3); + } else if (Q < 0) { + double t = atan2(sqrt(-Q), -b / 2.0); + double cos_t3 = cos(t / 3.0); + double sin_t3 = sin(t / 3.0); + double r = cbrt(sqrt(b * b / 4.0 - Q)); + + l1 = c2 / 3.0 + 2 * r * cos_t3; + l2 = c2 / 3.0 - r * (cos_t3 + M_SQRT_3 * sin_t3); + l3 = c2 / 3.0 - r * (cos_t3 - M_SQRT_3 * sin_t3); + + eig1(m, l1, e1); + eig1(m, l2, e2); + eig1(m, l3, e3); + } + } + + void eigSolve(const Matrix3 &m, double &l1, double &l2, double &l3) { + double c3, c2, c1, c0; + std::vector roots; + + c3 = -1.0; + c2 = m._11 + m._22 + m._33; + c1 = + -(m._22 * m._33 + m._11 * m._22 + m._11 * m._33) + +(m._23 * m._32 + m._13 * m._31 + m._12 * m._21); + c0 = + +(m._11 * m._22 - m._12 * m._21) * m._33 + -(m._11 * m._23 - m._13 * m._21) * m._32 + +(m._12 * m._23 - m._13 * m._22) * m._31; + + cubic_roots(c3, c2, c1, c0, roots); + + for (size_t i = 0; i < roots.size(); i++) { + Matrix3 M(m); + M._11 -= roots[i].root; + M._22 -= roots[i].root; + M._33 -= roots[i].root; + // solve M.v = 0 + } + + std::cerr << "n_roots=" << roots.size() << std::endl; + for (size_t i = 0; i < roots.size(); i++) { + fprintf(stderr, " %.24f(%d)", roots[i].root, roots[i].multiplicity); + } + std::cerr << std::endl; + } + + } +} + diff -Nru blender-2.61/extern/carve/lib/mesh.cpp blender-2.62/extern/carve/lib/mesh.cpp --- blender-2.61/extern/carve/lib/mesh.cpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/mesh.cpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,1203 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#if defined(HAVE_CONFIG_H) +# include +#endif + +#include +#include +#include + +#include + +namespace { + inline double CALC_X(const carve::geom::plane<3> &p, double y, double z) { return -(p.d + p.N.y * y + p.N.z * z) / p.N.x; } + inline double CALC_Y(const carve::geom::plane<3> &p, double x, double z) { return -(p.d + p.N.x * x + p.N.z * z) / p.N.y; } + inline double CALC_Z(const carve::geom::plane<3> &p, double x, double y) { return -(p.d + p.N.x * x + p.N.y * y) / p.N.z; } + + carve::geom::vector<2> _project_1(const carve::geom::vector<3> &v) { + return carve::geom::VECTOR(v.z, v.y); + } + + carve::geom::vector<2> _project_2(const carve::geom::vector<3> &v) { + return carve::geom::VECTOR(v.x, v.z); + } + + carve::geom::vector<2> _project_3(const carve::geom::vector<3> &v) { + return carve::geom::VECTOR(v.y, v.x); + } + + carve::geom::vector<2> _project_4(const carve::geom::vector<3> &v) { + return carve::geom::VECTOR(v.y, v.z); + } + + carve::geom::vector<2> _project_5(const carve::geom::vector<3> &v) { + return carve::geom::VECTOR(v.z, v.x); + } + + carve::geom::vector<2> _project_6(const carve::geom::vector<3> &v) { + return carve::geom::VECTOR(v.x, v.y); + } + + carve::geom::vector<3> _unproject_1(const carve::geom::vector<2> &p, const carve::geom3d::Plane &plane) { + return carve::geom::VECTOR(CALC_X(plane, p.y, p.x), p.y, p.x); + } + + carve::geom::vector<3> _unproject_2(const carve::geom::vector<2> &p, const carve::geom3d::Plane &plane) { + return carve::geom::VECTOR(p.x, CALC_Y(plane, p.x, p.y), p.y); + } + + carve::geom::vector<3> _unproject_3(const carve::geom::vector<2> &p, const carve::geom3d::Plane &plane) { + return carve::geom::VECTOR(p.y, p.x, CALC_Z(plane, p.y, p.x)); + } + + carve::geom::vector<3> _unproject_4(const carve::geom::vector<2> &p, const carve::geom3d::Plane &plane) { + return carve::geom::VECTOR(CALC_X(plane, p.x, p.y), p.x, p.y); + } + + carve::geom::vector<3> _unproject_5(const carve::geom::vector<2> &p, const carve::geom3d::Plane &plane) { + return carve::geom::VECTOR(p.y, CALC_Y(plane, p.y, p.x), p.x); + } + + carve::geom::vector<3> _unproject_6(const carve::geom::vector<2> &p, const carve::geom3d::Plane &plane) { + return carve::geom::VECTOR(p.x, p.y, CALC_Z(plane, p.x, p.y)); + } + + static carve::geom::vector<2> (*project_tab[2][3])(const carve::geom::vector<3> &) = { + { &_project_1, &_project_2, &_project_3 }, + { &_project_4, &_project_5, &_project_6 } + }; + + static carve::geom::vector<3> (*unproject_tab[2][3])(const carve::geom::vector<2> &, const carve::geom3d::Plane &) = { + { &_unproject_1, &_unproject_2, &_unproject_3 }, + { &_unproject_4, &_unproject_5, &_unproject_6 } + }; + +} + +namespace carve { + namespace mesh { + + + + template + typename Face::project_t Face::getProjector(bool positive_facing, int axis) const { + return NULL; + } + + + + template<> + Face<3>::project_t Face<3>::getProjector(bool positive_facing, int axis) const { + return project_tab[positive_facing ? 1 : 0][axis]; + } + + + + template + typename Face::unproject_t Face::getUnprojector(bool positive_facing, int axis) const { + return NULL; + } + + + + template<> + Face<3>::unproject_t Face<3>::getUnprojector(bool positive_facing, int axis) const { + return unproject_tab[positive_facing ? 1 : 0][axis]; + } + + + + template + bool Face::containsPoint(const vector_t &p) const { + if (!carve::math::ZERO(carve::geom::distance(plane, p))) return false; + // return pointInPolySimple(vertices, projector(), (this->*project)(p)); + std::vector > verts; + getProjectedVertices(verts); + return carve::geom2d::pointInPoly(verts, project(p)).iclass != carve::POINT_OUT; + } + + + + template + bool Face::containsPointInProjection(const vector_t &p) const { + std::vector > verts; + getProjectedVertices(verts); + return carve::geom2d::pointInPoly(verts, project(p)).iclass != carve::POINT_OUT; + } + + + + template + bool Face::simpleLineSegmentIntersection( + const carve::geom::linesegment &line, + vector_t &intersection) const { + if (!line.OK()) return false; + + carve::mesh::MeshSet<3>::vertex_t::vector_t p; + carve::IntersectionClass intersects = + carve::geom3d::lineSegmentPlaneIntersection(plane, line, p); + if (intersects == carve::INTERSECT_NONE || intersects == carve::INTERSECT_BAD) { + return false; + } + + std::vector > verts; + getProjectedVertices(verts); + if (carve::geom2d::pointInPolySimple(verts, project(p))) { + intersection = p; + return true; + } + return false; + } + + + + template + IntersectionClass Face::lineSegmentIntersection(const carve::geom::linesegment &line, + vector_t &intersection) const { + if (!line.OK()) return INTERSECT_NONE; + + + vector_t p; + IntersectionClass intersects = carve::geom3d::lineSegmentPlaneIntersection(plane, line, p); + if (intersects == INTERSECT_NONE || intersects == INTERSECT_BAD) { + return intersects; + } + + std::vector > verts; + getProjectedVertices(verts); + carve::geom2d::PolyInclusionInfo pi = carve::geom2d::pointInPoly(verts, project(p)); + switch (pi.iclass) { + case POINT_VERTEX: + intersection = p; + return INTERSECT_VERTEX; + + case POINT_EDGE: + intersection = p; + return INTERSECT_EDGE; + + case POINT_IN: + intersection = p; + return INTERSECT_FACE; + + case POINT_OUT: + return INTERSECT_NONE; + + default: + break; + } + return INTERSECT_NONE; + } + + + + template + Face *Face::closeLoop(typename Face::edge_t *start) { + edge_t *e = start; + std::vector loop_edges; + do { + CARVE_ASSERT(e->rev == NULL); + loop_edges.push_back(e); + e = e->perimNext(); + } while (e != start); + + const size_t N = loop_edges.size(); + for (size_t i = 0; i < N; ++i) { + loop_edges[i]->rev = new edge_t(loop_edges[i]->v2(), NULL); + } + + for (size_t i = 0; i < N; ++i) { + edge_t *e1 = loop_edges[i]->rev; + edge_t *e2 = loop_edges[(i+1)%N]->rev; + e1->prev = e2; + e2->next = e1; + } + + Face *f = new Face(start->rev); + + CARVE_ASSERT(f->n_edges == N); + + return f; + } + + + + namespace detail { + + + + bool FaceStitcher::EdgeOrderData::Cmp::operator()(const EdgeOrderData &a, const EdgeOrderData &b) const { + int v = carve::geom3d::compareAngles(edge_dir, base_dir, a.face_dir, b.face_dir); + double da = carve::geom3d::antiClockwiseAngle(base_dir, a.face_dir, edge_dir); + double db = carve::geom3d::antiClockwiseAngle(base_dir, b.face_dir, edge_dir); + int v0 = v; + v = 0; + if (da < db) v = -1; + if (db < da) v = +1; + if (v0 != v) { + std::cerr << "v0= " << v0 << " v= " << v << " da= " << da << " db= " << db << " " << edge_dir << " " << base_dir << " " << a.face_dir << b.face_dir << std::endl; + } + if (v < 0) return true; + if (v == 0) { + if (a.is_reversed && !b.is_reversed) return true; + if (a.is_reversed == b.is_reversed) { + return a.group_id < b.group_id; + } + } + return false; + } + + + + void FaceStitcher::matchSimpleEdges() { + // join faces that share an edge, where no other faces are incident. + for (edge_map_t::iterator i = edges.begin(); i != edges.end(); ++i) { + const vpair_t &ev = (*i).first; + edge_map_t::iterator j = edges.find(vpair_t(ev.second, ev.first)); + if (j == edges.end()) { + for (edgelist_t::iterator k = (*i).second.begin(); k != (*i).second.end(); ++k) { + is_open[ (*k)->face->id] = true; + } + } else if ((*i).second.size() != 1 || (*j).second.size() != 1) { + std::swap(complex_edges[(*i).first], (*i).second); + } else { + // simple edge. + edge_t *a = (*i).second.front(); + edge_t *b = (*j).second.front(); + if (a < b) { + // every simple edge pair is encountered twice. only merge once. + a->rev = b; + b->rev = a; + face_groups.merge_sets(a->face->id, b->face->id); + } + } + } + } + + + + size_t FaceStitcher::faceGroupID(const Face<3> *face) { + return face_groups.find_set_head(face->id); + } + + + + size_t FaceStitcher::faceGroupID(const Edge<3> *edge) { + return face_groups.find_set_head(edge->face->id); + } + + + + void FaceStitcher::orderForwardAndReverseEdges(std::vector *> > &efwd, + std::vector *> > &erev, + std::vector > &result) { + const size_t Nfwd = efwd.size(); + const size_t Nrev = erev.size(); + const size_t N = efwd[0].size(); + + result.resize(N); + + for (size_t i = 0; i < N; ++i) { + Edge<3> *base = efwd[0][i]; + + result[i].reserve(Nfwd + Nrev); + for (size_t j = 0; j < Nfwd; ++j) { + result[i].push_back(EdgeOrderData(efwd[j][i], j, false)); + CARVE_ASSERT(efwd[0][i]->v1() == efwd[j][i]->v1()); + CARVE_ASSERT(efwd[0][i]->v2() == efwd[j][i]->v2()); + } + for (size_t j = 0; j < Nrev; ++j) { + result[i].push_back(EdgeOrderData(erev[j][i], j, true)); + CARVE_ASSERT(erev[0][i]->v1() == erev[j][i]->v1()); + CARVE_ASSERT(erev[0][i]->v2() == erev[j][i]->v2()); + } + + std::sort(result[i].begin(), + result[i].end(), + EdgeOrderData::Cmp(base->v2()->v - base->v1()->v, result[i][0].face_dir)); + } + } + + + + void FaceStitcher::edgeIncidentGroups(const vpair_t &e, + const edge_map_t &all_edges, + std::pair, std::set > &groups) { + groups.first.clear(); + groups.second.clear(); + edge_map_t::const_iterator i; + + i = all_edges.find(e); + if (i != all_edges.end()) { + for (edgelist_t::const_iterator j = (*i).second.begin(); j != (*i).second.end(); ++j) { + groups.first.insert(faceGroupID(*j)); + } + } + + i = all_edges.find(vpair_t(e.second, e.first)); + if (i != all_edges.end()) { + for (edgelist_t::const_iterator j = (*i).second.begin(); j != (*i).second.end(); ++j) { + groups.second.insert(faceGroupID(*j)); + } + } + } + + + + void FaceStitcher::buildEdgeGraph(const edge_map_t &all_edges) { + for (edge_map_t::const_iterator i = all_edges.begin(); + i != all_edges.end(); + ++i) { + edge_graph[(*i).first.first].insert((*i).first.second); + } + } + + + + void FaceStitcher::extractPath(std::vector &path) { + path.clear(); + + edge_graph_t::iterator iter = edge_graph.begin(); + + + const vertex_t *init = (*iter).first; + const vertex_t *next = *(*iter).second.begin(); + const vertex_t *prev = NULL; + const vertex_t *vert = init; + + while ((*iter).second.size() == 2) { + prev = *std::find_if((*iter).second.begin(), + (*iter).second.end(), + std::bind2nd(std::not_equal_to(), next)); + next = vert; + vert = prev; + iter = edge_graph.find(vert); + CARVE_ASSERT(iter != edge_graph.end()); + if (vert == init) break; + } + init = vert; + + std::vector efwd; + std::vector erev; + + edge_map_t::iterator edgeiter; + edgeiter = complex_edges.find(vpair_t(vert, next)); + std::copy((*edgeiter).second.begin(), (*edgeiter).second.end(), std::back_inserter(efwd)); + + edgeiter = complex_edges.find(vpair_t(next, vert)); + std::copy((*edgeiter).second.begin(), (*edgeiter).second.end(), std::back_inserter(erev)); + + path.push_back(vert); + + prev = vert; + vert = next; + path.push_back(vert); + iter = edge_graph.find(vert); + CARVE_ASSERT(iter != edge_graph.end()); + + while (vert != init && (*iter).second.size() == 2) { + next = *std::find_if((*iter).second.begin(), + (*iter).second.end(), + std::bind2nd(std::not_equal_to(), prev)); + + edgeiter = complex_edges.find(vpair_t(vert, next)); + if ((*edgeiter).second.size() != efwd.size()) goto done; + + for (size_t i = 0; i < efwd.size(); ++i) { + Edge<3> *e_next = efwd[i]->perimNext(); + if (e_next->v2() != next) goto done; + efwd[i] = e_next; + } + + edgeiter = complex_edges.find(vpair_t(next, vert)); + if ((*edgeiter).second.size() != erev.size()) goto done; + + for (size_t i = 0; i < erev.size(); ++i) { + Edge<3> *e_prev = erev[i]->perimPrev(); + if (e_prev->v1() != next) goto done; + erev[i] = e_prev; + } + + prev = vert; + vert = next; + path.push_back(vert); + iter = edge_graph.find(vert); + CARVE_ASSERT(iter != edge_graph.end()); + } + done:; + } + + + + void FaceStitcher::removePath(const std::vector &path) { + for (size_t i = 1; i < path.size() - 1; ++i) { + edge_graph.erase(path[i]); + } + + edge_graph[path[0]].erase(path[1]); + if (edge_graph[path[0]].size() == 0) { + edge_graph.erase(path[0]); + } + + edge_graph[path[path.size()-1]].erase(path[path.size()-2]); + if (edge_graph[path[path.size()-1]].size() == 0) { + edge_graph.erase(path[path.size()-1]); + } + } + + + + void FaceStitcher::reorder(std::vector &ordering, + size_t grp) { + if (!ordering[0].is_reversed && ordering[0].group_id == grp) return; + for (size_t i = 1; i < ordering.size(); ++i) { + if (!ordering[i].is_reversed && ordering[i].group_id == grp) { + std::vector temp; + temp.reserve(ordering.size()); + std::copy(ordering.begin() + i, ordering.end(), std::back_inserter(temp)); + std::copy(ordering.begin(), ordering.begin() + i, std::back_inserter(temp)); + std::copy(temp.begin(), temp.end(), ordering.begin()); + return; + } + } + } + + + + struct lt_second { + template + bool operator()(const pair_t &a, const pair_t &b) const { + return a.second < b.second; + } + }; + + + + void FaceStitcher::fuseEdges(std::vector *> &fwd, + std::vector *> &rev) { + for (size_t i = 0; i < fwd.size(); ++i) { + fwd[i]->rev = rev[i]; + rev[i]->rev = fwd[i]; + face_groups.merge_sets(fwd[i]->face->id, rev[i]->face->id); + } + } + + + + void FaceStitcher::joinGroups(std::vector *> > &efwd, + std::vector *> > &erev, + size_t fwd_grp, + size_t rev_grp) { + fuseEdges(efwd[fwd_grp], erev[rev_grp]); + } + + + + void FaceStitcher::matchOrderedEdges(const std::vector >::iterator begin, + const std::vector >::iterator end, + std::vector *> > &efwd, + std::vector *> > &erev) { + typedef std::unordered_map, size_t> pair_counts_t; + for (;;) { + pair_counts_t pair_counts; + + for (std::vector >::iterator i = begin; i != end; ++i) { + std::vector &e = *i; + for (size_t j = 0; j < e.size(); ++j) { + if (!e[j].is_reversed && e[(j+1)%e.size()].is_reversed) { + pair_counts[std::make_pair(e[j].group_id, + e[(j+1)%e.size()].group_id)]++; + } + } + } + + if (!pair_counts.size()) break; + + std::vector > > counts; + counts.reserve(pair_counts.size()); + for (pair_counts_t::iterator iter = pair_counts.begin(); iter != pair_counts.end(); ++iter) { + counts.push_back(std::make_pair((*iter).second, (*iter).first)); + } + std::make_heap(counts.begin(), counts.end()); + + std::set rem_fwd, rem_rev; + + while (counts.size()) { + std::pair join = counts.front().second; + std::pop_heap(counts.begin(), counts.end()); + counts.pop_back(); + if (rem_fwd.find(join.first) != rem_fwd.end()) continue; + if (rem_rev.find(join.second) != rem_rev.end()) continue; + + size_t g1 = join.first; + size_t g2 = join.second; + + joinGroups(efwd, erev, g1, g2); + + for (std::vector >::iterator i = begin; i != end; ++i) { + (*i).erase(std::remove_if((*i).begin(), (*i).end(), EdgeOrderData::TestGroups(g1, g2)), (*i).end()); + } + + rem_fwd.insert(g1); + rem_rev.insert(g2); + } + } + } + + + + void FaceStitcher::resolveOpenEdges() { + // Remove open regions of mesh. Doing this may make additional + // edges simple (for example, removing a fin from the edge of + // a cube), and may also expose more open mesh regions. In the + // latter case, the process must be repeated to deal with the + // newly uncovered regions. + std::unordered_set open_groups; + + for (size_t i = 0; i < is_open.size(); ++i) { + if (is_open[i]) open_groups.insert(face_groups.find_set_head(i)); + } + + while (!open_groups.empty()) { + std::list edge_0, edge_1; + + for (edge_map_t::iterator i = complex_edges.begin(); i != complex_edges.end(); ++i) { + bool was_modified = false; + for(edgelist_t::iterator j = (*i).second.begin(); j != (*i).second.end(); ) { + if (open_groups.find(faceGroupID(*j)) != open_groups.end()) { + j = (*i).second.erase(j); + was_modified = true; + } else { + ++j; + } + } + if (was_modified) { + if ((*i).second.empty()) { + edge_0.push_back((*i).first); + } else if ((*i).second.size() == 1) { + edge_1.push_back((*i).first); + } + } + } + + for (std::list::iterator i = edge_1.begin(); i != edge_1.end(); ++i) { + vpair_t e1 = *i; + edge_map_t::iterator e1i = complex_edges.find(e1); + if (e1i == complex_edges.end()) continue; + vpair_t e2 = vpair_t(e1.second, e1.first); + edge_map_t::iterator e2i = complex_edges.find(e2); + CARVE_ASSERT(e2i != complex_edges.end()); // each complex edge should have a mate. + + if ((*e2i).second.size() == 1) { + // merge newly simple edges, delete both from complex_edges. + edge_t *a = (*e1i).second.front(); + edge_t *b = (*e2i).second.front(); + a->rev = b; + b->rev = a; + face_groups.merge_sets(a->face->id, b->face->id); + complex_edges.erase(e1i); + complex_edges.erase(e2i); + } + } + + open_groups.clear(); + + for (std::list::iterator i = edge_0.begin(); i != edge_0.end(); ++i) { + vpair_t e1 = *i; + edge_map_t::iterator e1i = complex_edges.find(e1); + vpair_t e2 = vpair_t(e1.second, e1.first); + edge_map_t::iterator e2i = complex_edges.find(e2); + if (e2i == complex_edges.end()) { + // This could occur, for example, when two faces share + // an edge in the same direction, but are both not + // touching anything else. Both get removed by the open + // group removal code, leaving an edge map with zero + // edges. The edge in the opposite direction does not + // exist, because there's no face that adjoins either of + // the two open faces. + continue; + } + + for (edgelist_t::iterator j = (*e2i).second.begin(); j != (*e2i).second.end(); ++j) { + open_groups.insert(faceGroupID(*j)); + } + complex_edges.erase(e1i); + complex_edges.erase(e2i); + } + } + } + + + + void FaceStitcher::extractConnectedEdges(std::vector::iterator begin, + std::vector::iterator end, + std::vector *> > &efwd, + std::vector *> > &erev) { + const size_t N = std::distance(begin, end) - 1; + + std::vector::iterator e1, e2; + e1 = e2 = begin; ++e2; + vpair_t start_f = vpair_t(*e1, *e2); + vpair_t start_r = vpair_t(*e2, *e1); + + const size_t Nfwd = complex_edges[start_f].size(); + const size_t Nrev = complex_edges[start_r].size(); + + size_t j; + edgelist_t::iterator ji; + + efwd.clear(); efwd.resize(Nfwd); + erev.clear(); erev.resize(Nrev); + + for (j = 0, ji = complex_edges[start_f].begin(); + ji != complex_edges[start_f].end(); + ++j, ++ji) { + efwd[j].reserve(N); + efwd[j].push_back(*ji); + } + + for (j = 0, ji = complex_edges[start_r].begin(); + ji != complex_edges[start_r].end(); + ++j, ++ji) { + erev[j].reserve(N); + erev[j].push_back(*ji); + } + + std::vector *> temp_f, temp_r; + temp_f.resize(Nfwd); + temp_r.resize(Nrev); + + for (j = 1; j < N; ++j) { + ++e1; ++e2; + vpair_t ef = vpair_t(*e1, *e2); + vpair_t er = vpair_t(*e2, *e1); + + if (complex_edges[ef].size() != Nfwd || complex_edges[ef].size() != Nrev) break; + + for (size_t k = 0; k < Nfwd; ++k) { + Edge<3> *e_next = efwd[k].back()->perimNext(); + CARVE_ASSERT(e_next == NULL || e_next->rev == NULL); + if (e_next == NULL || e_next->v2() != *e2) goto done; + CARVE_ASSERT(e_next->v1() == *e1); + CARVE_ASSERT(std::find(complex_edges[ef].begin(), complex_edges[ef].end(), e_next) != complex_edges[ef].end()); + temp_f[k] = e_next; + } + + for (size_t k = 0; k < Nrev; ++k) { + Edge<3> *e_next = erev[k].back()->perimPrev(); + if (e_next == NULL || e_next->v1() != *e2) goto done; + CARVE_ASSERT(e_next->v2() == *e1); + CARVE_ASSERT(std::find(complex_edges[er].begin(), complex_edges[er].end(), e_next) != complex_edges[er].end()); + temp_r[k] = e_next; + } + + for (size_t k = 0; k < Nfwd; ++k) { + efwd[k].push_back(temp_f[k]); + } + + for (size_t k = 0; k < Nrev; ++k) { + erev[k].push_back(temp_r[k]); + } + } + done:; + } + + + + void FaceStitcher::construct() { + matchSimpleEdges(); + if (!complex_edges.size()) return; + + resolveOpenEdges(); + if (!complex_edges.size()) return; + + buildEdgeGraph(complex_edges); + + std::list > paths; + + while (edge_graph.size()) { + paths.push_back(std::vector()); + extractPath(paths.back()); + removePath(paths.back()); + }; + + + for (std::list >::iterator path = paths.begin(); path != paths.end(); ++path) { + for (size_t i = 0; i < (*path).size() - 1;) { + std::vector *> > efwd, erev; + + extractConnectedEdges((*path).begin() + i, (*path).end(), efwd, erev); + + std::vector > orderings; + orderForwardAndReverseEdges(efwd, erev, orderings); + + matchOrderedEdges(orderings.begin(), orderings.end(), efwd, erev); + i += efwd[0].size(); + } + } + } + } + } + + + + // construct a MeshSet from a Polyhedron, maintaining on the + // connectivity information in the Polyhedron. + mesh::MeshSet<3> *meshFromPolyhedron(const poly::Polyhedron *poly, int manifold_id) { + typedef mesh::Vertex<3> vertex_t; + typedef mesh::Vertex<3>::vector_t vector_t; + typedef mesh::Edge<3> edge_t; + typedef mesh::Face<3> face_t; + typedef mesh::Mesh<3> mesh_t; + typedef mesh::MeshSet<3> meshset_t; + + std::vector vertex_storage; + vertex_storage.reserve(poly->vertices.size()); + for (size_t i = 0; i < poly->vertices.size(); ++i) { + vertex_storage.push_back(vertex_t(poly->vertices[i].v)); + } + + std::vector > faces; + faces.resize(poly->manifold_is_closed.size()); + + std::unordered_map, std::list > vertex_to_edge; + + std::vector vert_ptrs; + for (size_t i = 0; i < poly->faces.size(); ++i) { + const poly::Polyhedron::face_t &src = poly->faces[i]; + if (manifold_id != -1 && src.manifold_id != manifold_id) continue; + vert_ptrs.clear(); + vert_ptrs.reserve(src.nVertices()); + for (size_t j = 0; j < src.nVertices(); ++j) { + size_t vi = poly->vertexToIndex_fast(src.vertex(j)); + vert_ptrs.push_back(&vertex_storage[vi]); + } + face_t *face = new face_t(vert_ptrs.begin(), vert_ptrs.end()); + face->id = src.manifold_id; + faces[src.manifold_id].push_back(face); + + edge_t *edge = face->edge; + do { + vertex_to_edge[std::make_pair(size_t(edge->v1() - &vertex_storage[0]), + size_t(edge->v2() - &vertex_storage[0]))].push_back(edge); + edge = edge->next; + } while (edge != face->edge); + } + + // copy connectivity from Polyhedron. + for (size_t i = 0; i < poly->edges.size(); ++i) { + const poly::Polyhedron::edge_t &src = poly->edges[i]; + size_t v1i = poly->vertexToIndex_fast(src.v1); + size_t v2i = poly->vertexToIndex_fast(src.v2); + + std::list &efwd = vertex_to_edge[std::make_pair(v1i, v2i)]; + std::list &erev = vertex_to_edge[std::make_pair(v2i, v1i)]; + + const std::vector &facepairs = poly->connectivity.edge_to_face[i]; + for (size_t j = 0; j < facepairs.size(); j += 2) { + const poly::Polyhedron::face_t *fa, *fb; + fa = facepairs[j]; + fb = facepairs[j+1]; + if (!fa || !fb) continue; + CARVE_ASSERT(fa->manifold_id == fb->manifold_id); + if (manifold_id != -1 && fa->manifold_id != manifold_id) continue; + + std::list::iterator efwdi, erevi; + for (efwdi = efwd.begin(); efwdi != efwd.end() && (*efwdi)->face->id != (size_t)fa->manifold_id; ++efwdi); + for (erevi = erev.begin(); erevi != erev.end() && (*erevi)->face->id != (size_t)fa->manifold_id; ++erevi); + CARVE_ASSERT(efwdi != efwd.end() && erevi != erev.end()); + + (*efwdi)->rev = (*erevi); + (*erevi)->rev = (*efwdi); + } + } + + std::vector meshes; + meshes.reserve(faces.size()); + for (size_t i = 0; i < faces.size(); ++i) { + if (faces[i].size()) { + meshes.push_back(new mesh_t(faces[i])); + } + } + + return new meshset_t(vertex_storage, meshes); + } + + + + static void copyMeshFaces(const mesh::Mesh<3> *mesh, + size_t manifold_id, + const mesh::Vertex<3> *Vbase, + poly::Polyhedron *poly, + std::unordered_map, std::list *> > &edges, + std::unordered_map *, size_t> &face_map) { + std::vector vert_ptr; + for (size_t f = 0; f < mesh->faces.size(); ++f) { + mesh::Face<3> *src = mesh->faces[f]; + vert_ptr.clear(); + vert_ptr.reserve(src->nVertices()); + mesh::Edge<3> *e = src->edge; + do { + vert_ptr.push_back(&poly->vertices[e->vert - Vbase]); + edges[std::make_pair(e->v1() - Vbase, e->v2() - Vbase)].push_back(e); + e = e->next; + } while (e != src->edge); + + face_map[src] = poly->faces.size();; + + poly->faces.push_back(poly::Polyhedron::face_t(vert_ptr)); + poly->faces.back().manifold_id = manifold_id; + poly->faces.back().owner = poly; + } + } + + + + // construct a Polyhedron from a MeshSet + poly::Polyhedron *polyhedronFromMesh(const mesh::MeshSet<3> *mesh, int manifold_id) { + typedef poly::Polyhedron poly_t; + typedef poly::Polyhedron::vertex_t vertex_t; + typedef poly::Polyhedron::edge_t edge_t; + typedef poly::Polyhedron::face_t face_t; + + poly::Polyhedron *poly = new poly::Polyhedron(); + const mesh::Vertex<3> *Vbase = &mesh->vertex_storage[0]; + + poly->vertices.reserve(mesh->vertex_storage.size()); + for (size_t i = 0; i < mesh->vertex_storage.size(); ++i) { + poly->vertices.push_back(vertex_t(mesh->vertex_storage[i].v)); + poly->vertices.back().owner = poly; + } + + size_t n_faces = 0; + if (manifold_id == -1) { + poly->manifold_is_closed.resize(mesh->meshes.size()); + poly->manifold_is_negative.resize(mesh->meshes.size()); + for (size_t m = 0; m < mesh->meshes.size(); ++m) { + n_faces += mesh->meshes[m]->faces.size(); + poly->manifold_is_closed[m] = mesh->meshes[m]->isClosed(); + poly->manifold_is_negative[m] = mesh->meshes[m]->isNegative(); + } + } else { + poly->manifold_is_closed.resize(1); + poly->manifold_is_negative.resize(1); + n_faces = mesh->meshes[manifold_id]->faces.size(); + poly->manifold_is_closed[manifold_id] = mesh->meshes[manifold_id]->isClosed(); + poly->manifold_is_negative[manifold_id] = mesh->meshes[manifold_id]->isNegative(); + } + + std::unordered_map, std::list *> > edges; + std::unordered_map *, size_t> face_map; + poly->faces.reserve(n_faces); + + if (manifold_id == -1) { + for (size_t m = 0; m < mesh->meshes.size(); ++m) { + copyMeshFaces(mesh->meshes[m], m, Vbase, poly, edges, face_map); + } + } else { + copyMeshFaces(mesh->meshes[manifold_id], 0, Vbase, poly, edges, face_map); + } + + size_t n_edges = 0; + for (std::unordered_map, std::list *> >::iterator i = edges.begin(); i != edges.end(); ++i) { + if ((*i).first.first < (*i).first.second || edges.find(std::make_pair((*i).first.second, (*i).first.first)) == edges.end()) { + n_edges++; + } + } + + poly->edges.reserve(n_edges); + for (std::unordered_map, std::list *> >::iterator i = edges.begin(); i != edges.end(); ++i) { + if ((*i).first.first < (*i).first.second || + edges.find(std::make_pair((*i).first.second, (*i).first.first)) == edges.end()) { + poly->edges.push_back(edge_t(&poly->vertices[(*i).first.first], + &poly->vertices[(*i).first.second], + poly)); + } + } + + poly->initVertexConnectivity(); + + // build edge entries for face. + for (size_t f = 0; f < poly->faces.size(); ++f) { + face_t &face = poly->faces[f]; + size_t N = face.nVertices(); + for (size_t v = 0; v < N; ++v) { + size_t v1i = poly->vertexToIndex_fast(face.vertex(v)); + size_t v2i = poly->vertexToIndex_fast(face.vertex((v+1)%N)); + std::vector found_edge; + std::set_intersection(poly->connectivity.vertex_to_edge[v1i].begin(), poly->connectivity.vertex_to_edge[v1i].end(), + poly->connectivity.vertex_to_edge[v2i].begin(), poly->connectivity.vertex_to_edge[v2i].end(), + std::back_inserter(found_edge)); + CARVE_ASSERT(found_edge.size() == 1); + face.edge(v) = found_edge[0]; + } + } + + poly->connectivity.edge_to_face.resize(poly->edges.size()); + + for (size_t i = 0; i < poly->edges.size(); ++i) { + size_t v1i = poly->vertexToIndex_fast(poly->edges[i].v1); + size_t v2i = poly->vertexToIndex_fast(poly->edges[i].v2); + std::list *> &efwd = edges[std::make_pair(v1i, v2i)]; + std::list *> &erev = edges[std::make_pair(v1i, v2i)]; + + for (std::list *>::iterator j = efwd.begin(); j != efwd.end(); ++j) { + mesh::Edge<3> *edge = *j; + if (face_map.find(edge->face) != face_map.end()) { + poly->connectivity.edge_to_face[i].push_back(&poly->faces[face_map[edge->face]]); + if (edge->rev == NULL) { + poly->connectivity.edge_to_face[i].push_back(NULL); + } else { + poly->connectivity.edge_to_face[i].push_back(&poly->faces[face_map[edge->rev->face]]); + } + } + } + for (std::list *>::iterator j = erev.begin(); j != erev.end(); ++j) { + mesh::Edge<3> *edge = *j; + if (face_map.find(edge->face) != face_map.end()) { + if (edge->rev == NULL) { + poly->connectivity.edge_to_face[i].push_back(NULL); + poly->connectivity.edge_to_face[i].push_back(&poly->faces[face_map[edge->face]]); + } + } + } + + } + + poly->initSpatialIndex(); + + // XXX: at this point, manifold_is_negative is not set up. This + // info should be computed/stored in Mesh instances. + + return poly; + } + + + +} + + + +// explicit instantiation for 2D case. +// XXX: do not compile because of a missing definition for fitPlane in the 2d case. + +// template class carve::mesh::Vertex<2>; +// template class carve::mesh::Edge<2>; +// template class carve::mesh::Face<2>; +// template class carve::mesh::Mesh<2>; +// template class carve::mesh::MeshSet<2>; + +// explicit instantiation for 3D case. +template class carve::mesh::Vertex<3>; +template class carve::mesh::Edge<3>; +template class carve::mesh::Face<3>; +template class carve::mesh::Mesh<3>; +template class carve::mesh::MeshSet<3>; + + + +carve::PointClass carve::mesh::classifyPoint( + const carve::mesh::MeshSet<3> *meshset, + const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *face_rtree, + const carve::geom::vector<3> &v, + bool even_odd, + const carve::mesh::Mesh<3> *mesh, + const carve::mesh::Face<3> **hit_face) { + + if (hit_face) *hit_face = NULL; + +#if defined(DEBUG_CONTAINS_VERTEX) + std::cerr << "{containsVertex " << v << "}" << std::endl; +#endif + + if (!face_rtree->bbox.containsPoint(v)) { +#if defined(DEBUG_CONTAINS_VERTEX) + std::cerr << "{final:OUT(aabb short circuit)}" << std::endl; +#endif + // XXX: if the top level manifolds are negative, this should be POINT_IN. + // for the moment, this only works for a single manifold. + if (meshset->meshes.size() == 1 && meshset->meshes[0]->isNegative()) { + return POINT_IN; + } + return POINT_OUT; + } + + std::vector *> near_faces; + face_rtree->search(v, std::back_inserter(near_faces)); + + for (size_t i = 0; i < near_faces.size(); i++) { + if (mesh != NULL && mesh != near_faces[i]->mesh) continue; + + // XXX: Do allow the tested vertex to be ON an open + // manifold. This was here originally because of the + // possibility of an open manifold contained within a closed + // manifold. + + // if (!near_faces[i]->mesh->isClosed()) continue; + + if (near_faces[i]->containsPoint(v)) { +#if defined(DEBUG_CONTAINS_VERTEX) + std::cerr << "{final:ON(hits face " << near_faces[i] << ")}" << std::endl; +#endif + if (hit_face) *hit_face = near_faces[i]; + return POINT_ON; + } + } + + double ray_len = face_rtree->bbox.extent.length() * 2; + + + std::vector *, carve::geom::vector<3> > > manifold_intersections; + + for (;;) { + double a1 = random() / double(RAND_MAX) * M_TWOPI; + double a2 = random() / double(RAND_MAX) * M_TWOPI; + + carve::geom3d::Vector ray_dir = carve::geom::VECTOR(sin(a1) * sin(a2), cos(a1) * sin(a2), cos(a2)); + +#if defined(DEBUG_CONTAINS_VERTEX) + std::cerr << "{testing ray: " << ray_dir << "}" << std::endl; +#endif + + carve::geom::vector<3> v2 = v + ray_dir * ray_len; + + bool failed = false; + carve::geom::linesegment<3> line(v, v2); + carve::geom::vector<3> intersection; + + near_faces.clear(); + manifold_intersections.clear(); + face_rtree->search(line, std::back_inserter(near_faces)); + + for (unsigned i = 0; !failed && i < near_faces.size(); i++) { + if (mesh != NULL && mesh != near_faces[i]->mesh) continue; + + if (!near_faces[i]->mesh->isClosed()) continue; + + switch (near_faces[i]->lineSegmentIntersection(line, intersection)) { + case INTERSECT_FACE: { + +#if defined(DEBUG_CONTAINS_VERTEX) + std::cerr << "{intersects face: " << near_faces[i] + << " dp: " << dot(ray_dir, near_faces[i]->plane.N) << "}" << std::endl; +#endif + + if (!even_odd && fabs(dot(ray_dir, near_faces[i]->plane.N)) < EPSILON) { + +#if defined(DEBUG_CONTAINS_VERTEX) + std::cerr << "{failing(small dot product)}" << std::endl; +#endif + + failed = true; + break; + } + manifold_intersections.push_back(std::make_pair(near_faces[i], intersection)); + break; + } + case INTERSECT_NONE: { + break; + } + default: { + +#if defined(DEBUG_CONTAINS_VERTEX) + std::cerr << "{failing(degenerate intersection)}" << std::endl; +#endif + failed = true; + break; + } + } + } + + if (!failed) { + if (even_odd) { + return (manifold_intersections.size() & 1) ? POINT_IN : POINT_OUT; + } + +#if defined(DEBUG_CONTAINS_VERTEX) + std::cerr << "{intersections ok [count:" + << manifold_intersections.size() + << "], sorting}" + << std::endl; +#endif + + carve::geom3d::sortInDirectionOfRay(ray_dir, + manifold_intersections.begin(), + manifold_intersections.end(), + carve::geom3d::vec_adapt_pair_second()); + + std::map *, int> crossings; + + for (size_t i = 0; i < manifold_intersections.size(); ++i) { + const carve::mesh::Face<3> *f = manifold_intersections[i].first; + if (dot(ray_dir, f->plane.N) < 0.0) { + crossings[f->mesh]++; + } else { + crossings[f->mesh]--; + } + } + +#if defined(DEBUG_CONTAINS_VERTEX) + for (std::map *, int>::const_iterator i = crossings.begin(); i != crossings.end(); ++i) { + std::cerr << "{mesh " << (*i).first << " crossing count: " << (*i).second << "}" << std::endl; + } +#endif + + for (size_t i = 0; i < manifold_intersections.size(); ++i) { + const carve::mesh::Face<3> *f = manifold_intersections[i].first; + +#if defined(DEBUG_CONTAINS_VERTEX) + std::cerr << "{intersection at " + << manifold_intersections[i].second + << " mesh: " + << f->mesh + << " count: " + << crossings[f->mesh] + << "}" + << std::endl; +#endif + + if (crossings[f->mesh] < 0) { + // inside this manifold. + +#if defined(DEBUG_CONTAINS_VERTEX) + std::cerr << "{final:IN}" << std::endl; +#endif + + return POINT_IN; + } else if (crossings[f->mesh] > 0) { + // outside this manifold, but it's an infinite manifold. (for instance, an inverted cube) + +#if defined(DEBUG_CONTAINS_VERTEX) + std::cerr << "{final:OUT}" << std::endl; +#endif + + return POINT_OUT; + } + } + +#if defined(DEBUG_CONTAINS_VERTEX) + std::cerr << "{final:OUT(default)}" << std::endl; +#endif + + return POINT_OUT; + } + } +} + + + diff -Nru blender-2.61/extern/carve/lib/octree.cpp blender-2.62/extern/carve/lib/octree.cpp --- blender-2.61/extern/carve/lib/octree.cpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/octree.cpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,399 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#if defined(HAVE_CONFIG_H) +# include +#endif + +#include +#include + +#include + +namespace carve { + namespace csg { + + Octree::Node::Node(const carve::geom3d::Vector &newMin, const carve::geom3d::Vector &newMax) : + parent(NULL), is_leaf(true), min(newMin), max(newMax) { + for (int i = 0; i < 8; ++i) children[i] = NULL; + aabb = Octree::makeAABB(this); + } + + Octree::Node::Node(Node *p, double x1, double y1, double z1, double x2, double y2, double z2) : + parent(p), is_leaf(true), min(carve::geom::VECTOR(x1, y1, z1)), max(carve::geom::VECTOR(x2, y2, z2)) { + for (int i = 0; i < 8; ++i) children[i] = NULL; + aabb = Octree::makeAABB(this); + } + + Octree::Node::~Node() { + for (int i = 0; i < 8; ++i) { + if (children[i] != NULL) { + (*children[i]).~Node(); + } + } + if (children[0] != NULL) { + char *ptr = (char*)children[0]; + delete[] ptr; + } + } + + bool Octree::Node::mightContain(const carve::poly::Face<3> &face) { + if (face.nVertices() == 3) { + return aabb.intersects(carve::geom::tri<3>(face.vertex(0)->v, face.vertex(1)->v, face.vertex(2)->v)); + } else { + return aabb.intersects(face.aabb) && aabb.intersects(face.plane_eqn); + } + } + + bool Octree::Node::mightContain(const carve::poly::Edge<3> &edge) { + return aabb.intersectsLineSegment(edge.v1->v, edge.v2->v); + } + + bool Octree::Node::mightContain(const carve::poly::Vertex<3> &p) { + return aabb.containsPoint(p.v); + } + + bool Octree::Node::hasChildren() { + return !is_leaf; + } + + bool Octree::Node::split() { + if (is_leaf && hasGeometry()) { + + carve::geom3d::Vector mid = 0.5 * (min + max); + char *ptr = new char[sizeof(Node)*8]; + children[0] = new (ptr + sizeof(Node) * 0) Node(this, min.x, min.y, min.z, mid.x, mid.y, mid.z); + children[1] = new (ptr + sizeof(Node) * 1) Node(this, mid.x, min.y, min.z, max.x, mid.y, mid.z); + children[2] = new (ptr + sizeof(Node) * 2) Node(this, min.x, mid.y, min.z, mid.x, max.y, mid.z); + children[3] = new (ptr + sizeof(Node) * 3) Node(this, mid.x, mid.y, min.z, max.x, max.y, mid.z); + children[4] = new (ptr + sizeof(Node) * 4) Node(this, min.x, min.y, mid.z, mid.x, mid.y, max.z); + children[5] = new (ptr + sizeof(Node) * 5) Node(this, mid.x, min.y, mid.z, max.x, mid.y, max.z); + children[6] = new (ptr + sizeof(Node) * 6) Node(this, min.x, mid.y, mid.z, mid.x, max.y, max.z); + children[7] = new (ptr + sizeof(Node) * 7) Node(this, mid.x, mid.y, mid.z, max.x, max.y, max.z); + + for (int i = 0; i < 8; ++i) { + putInside(faces, children[i], children[i]->faces); + putInside(edges, children[i], children[i]->edges); + putInside(vertices, children[i], children[i]->vertices); + } + + faces.clear(); + edges.clear(); + vertices.clear(); + is_leaf = false; + } + return is_leaf; + } + + template + void Octree::Node::putInside(const T &input, Node *child, T &output) { + for (typename T::const_iterator it = input.begin(), e = input.end(); it != e; ++it) { + if (child->mightContain(**it)) { + output.push_back(*it); + } + } + } + + bool Octree::Node::hasGeometry() { + return faces.size() > 0 || edges.size() > 0 || vertices.size() > 0; + } + + Octree::Octree() { + root = NULL; + } + + Octree::~Octree() { + if (root) delete root; + } + + void Octree::setBounds(const carve::geom3d::Vector &min, const carve::geom3d::Vector &max) { + if (root) delete root; + root = new Node(min, max); + } + + void Octree::setBounds(carve::geom3d::AABB aabb) { + if (root) delete root; + aabb.extent = 1.1 * aabb.extent; + root = new Node(aabb.min(), aabb.max()); + } + + void Octree::addEdges(const std::vector > &e) { + root->edges.reserve(root->edges.size() + e.size()); + for (size_t i = 0; i < e.size(); ++i) { + root->edges.push_back(&e[i]); + } + } + + void Octree::addFaces(const std::vector > &f) { + root->faces.reserve(root->faces.size() + f.size()); + for (size_t i = 0; i < f.size(); ++i) { + root->faces.push_back(&f[i]); + } + } + + void Octree::addVertices(const std::vector *> &p) { + root->vertices.insert(root->vertices.end(), p.begin(), p.end()); + } + + carve::geom3d::AABB Octree::makeAABB(const Node *node) { + carve::geom3d::Vector centre = 0.5 * (node->min + node->max); + carve::geom3d::Vector size = SLACK_FACTOR * 0.5 * (node->max - node->min); + return carve::geom3d::AABB(centre, size); + } + + void Octree::doFindEdges(const carve::geom::aabb<3> &aabb, + Node *node, + std::vector *> &out, + unsigned depth) const { + if (node == NULL) { + return; + } + + if (node->aabb.intersects(aabb)) { + if (node->hasChildren()) { + for (int i = 0; i < 8; ++i) { + doFindEdges(aabb, node->children[i], out, depth + 1); + } + } else { + if (depth < MAX_SPLIT_DEPTH && node->edges.size() > EDGE_SPLIT_THRESHOLD) { + if (!node->split()) { + for (int i = 0; i < 8; ++i) { + doFindEdges(aabb, node->children[i], out, depth + 1); + } + return; + } + } + for (std::vector*>::const_iterator it = node->edges.begin(), e = node->edges.end(); it != e; ++it) { + if ((*it)->tag_once()) { + out.push_back(*it); + } + } + } + } + } + + void Octree::doFindEdges(const carve::geom3d::LineSegment &l, + Node *node, + std::vector *> &out, + unsigned depth) const { + if (node == NULL) { + return; + } + + if (node->aabb.intersectsLineSegment(l.v1, l.v2)) { + if (node->hasChildren()) { + for (int i = 0; i < 8; ++i) { + doFindEdges(l, node->children[i], out, depth + 1); + } + } else { + if (depth < MAX_SPLIT_DEPTH && node->edges.size() > EDGE_SPLIT_THRESHOLD) { + if (!node->split()) { + for (int i = 0; i < 8; ++i) { + doFindEdges(l, node->children[i], out, depth + 1); + } + return; + } + } + for (std::vector*>::const_iterator it = node->edges.begin(), e = node->edges.end(); it != e; ++it) { + if ((*it)->tag_once()) { + out.push_back(*it); + } + } + } + } + } + + void Octree::doFindEdges(const carve::geom3d::Vector &v, + Node *node, + std::vector *> &out, + unsigned depth) const { + if (node == NULL) { + return; + } + + if (node->aabb.containsPoint(v)) { + if (node->hasChildren()) { + for (int i = 0; i < 8; ++i) { + doFindEdges(v, node->children[i], out, depth + 1); + } + } else { + if (depth < MAX_SPLIT_DEPTH && node->edges.size() > EDGE_SPLIT_THRESHOLD) { + if (!node->split()) { + for (int i = 0; i < 8; ++i) { + doFindEdges(v, node->children[i], out, depth + 1); + } + return; + } + } + for (std::vector*>::const_iterator + it = node->edges.begin(), e = node->edges.end(); it != e; ++it) { + if ((*it)->tag_once()) { + out.push_back(*it); + } + } + } + } + } + + void Octree::doFindFaces(const carve::geom::aabb<3> &aabb, + Node *node, + std::vector*> &out, + unsigned depth) const { + if (node == NULL) { + return; + } + + if (node->aabb.intersects(aabb)) { + if (node->hasChildren()) { + for (int i = 0; i < 8; ++i) { + doFindFaces(aabb, node->children[i], out, depth + 1); + } + } else { + if (depth < MAX_SPLIT_DEPTH && node->faces.size() > FACE_SPLIT_THRESHOLD) { + if (!node->split()) { + for (int i = 0; i < 8; ++i) { + doFindFaces(aabb, node->children[i], out, depth + 1); + } + return; + } + } + for (std::vector*>::const_iterator it = node->faces.begin(), e = node->faces.end(); it != e; ++it) { + if ((*it)->tag_once()) { + out.push_back(*it); + } + } + } + } + } + + void Octree::doFindFaces(const carve::geom3d::LineSegment &l, + Node *node, + std::vector*> &out, + unsigned depth) const { + if (node == NULL) { + return; + } + + if (node->aabb.intersectsLineSegment(l.v1, l.v2)) { + if (node->hasChildren()) { + for (int i = 0; i < 8; ++i) { + doFindFaces(l, node->children[i], out, depth + 1); + } + } else { + if (depth < MAX_SPLIT_DEPTH && node->faces.size() > FACE_SPLIT_THRESHOLD) { + if (!node->split()) { + for (int i = 0; i < 8; ++i) { + doFindFaces(l, node->children[i], out, depth + 1); + } + return; + } + } + for (std::vector*>::const_iterator it = node->faces.begin(), e = node->faces.end(); it != e; ++it) { + if ((*it)->tag_once()) { + out.push_back(*it); + } + } + } + } + } + + void Octree::doFindVerticesAllowDupes(const carve::geom3d::Vector &v, Node *node, std::vector *> &out, unsigned depth) const { + if (node == NULL) { + return; + } + + if (node->aabb.containsPoint(v)) { + if (node->hasChildren()) { + for (int i = 0; i < 8; ++i) { + doFindVerticesAllowDupes(v, node->children[i], out, depth + 1); + } + } else { + if (depth < MAX_SPLIT_DEPTH && node->vertices.size() > POINT_SPLIT_THRESHOLD) { + if (!node->split()) { + for (int i = 0; i < 8; ++i) { + doFindVerticesAllowDupes(v, node->children[i], out, depth + 1); + } + return; + } + } + for (std::vector *>::const_iterator it = node->vertices.begin(), e = node->vertices.end(); it != e; ++it) { + out.push_back(*it); + } + } + } + } + + void Octree::findEdgesNear(const carve::geom::aabb<3> &aabb, std::vector*> &out) const { + tagable::tag_begin(); + doFindEdges(aabb, root, out, 0); + } + + void Octree::findEdgesNear(const carve::geom3d::LineSegment &l, std::vector*> &out) const { + tagable::tag_begin(); + doFindEdges(l, root, out, 0); + } + + void Octree::findEdgesNear(const carve::poly::Edge<3> &e, std::vector*> &out) const { + tagable::tag_begin(); + doFindEdges(carve::geom3d::LineSegment(e.v1->v, e.v2->v), root, out, 0); + } + + void Octree::findEdgesNear(const carve::geom3d::Vector &v, std::vector*> &out) const { + tagable::tag_begin(); + doFindEdges(v, root, out, 0); + } + + void Octree::findFacesNear(const carve::geom::aabb<3> &aabb, std::vector*> &out) const { + tagable::tag_begin(); + doFindFaces(aabb, root, out, 0); + } + + void Octree::findFacesNear(const carve::geom3d::LineSegment &l, std::vector*> &out) const { + tagable::tag_begin(); + doFindFaces(l, root, out, 0); + } + + void Octree::findFacesNear(const carve::poly::Edge<3> &e, std::vector*> &out) const { + tagable::tag_begin(); + doFindFaces(carve::geom3d::LineSegment(e.v1->v, e.v2->v), root, out, 0); + } + + void Octree::findVerticesNearAllowDupes(const carve::geom3d::Vector &v, std::vector *> &out) const { + tagable::tag_begin(); + doFindVerticesAllowDupes(v, root, out, 0); + } + + void Octree::doSplit(int maxSplit, Node *node) { + // Don't split down any further than 4 levels. + if (maxSplit <= 0 || (node->edges.size() < 5 && node->faces.size() < 5)) { + return; + } + + if (!node->split()) { + for (int i = 0; i < 8; ++i) { + doSplit(maxSplit - 1, node->children[i]); + } + } + } + + void Octree::splitTree() { + // initially split 4 levels + doSplit(0, root); + } + + } +} diff -Nru blender-2.61/extern/carve/lib/pointset.cpp blender-2.62/extern/carve/lib/pointset.cpp --- blender-2.61/extern/carve/lib/pointset.cpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/pointset.cpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,59 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#if defined(HAVE_CONFIG_H) +# include +#endif + +#include +#include + +namespace carve { + namespace point { + + PointSet::PointSet(const std::vector &points) { + vertices.resize(points.size()); + for (size_t i = 0; i < points.size(); ++i) { + vertices[i].v = points[i]; + } + aabb.fit(points.begin(), points.end()); + } + + void PointSet::sortVertices(const carve::geom3d::Vector &axis) { + std::vector > temp; + temp.reserve(vertices.size()); + for (size_t i = 0; i < vertices.size(); ++i) { + temp.push_back(std::make_pair(dot(axis, vertices[i].v), i)); + } + std::sort(temp.begin(), temp.end()); + + std::vector vnew; + vnew.reserve(vertices.size()); + + // std::vector revmap; + // revmap.resize(vertices.size()); + + for (size_t i = 0; i < vertices.size(); ++i) { + vnew.push_back(vertices[temp[i].second]); + // revmap[temp[i].second] = i; + } + + vertices.swap(vnew); + } + + } +} diff -Nru blender-2.61/extern/carve/lib/polyhedron.cpp blender-2.62/extern/carve/lib/polyhedron.cpp --- blender-2.61/extern/carve/lib/polyhedron.cpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/polyhedron.cpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,1103 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#if defined(HAVE_CONFIG_H) +# include +#endif + +#if defined(CARVE_DEBUG) +#define DEBUG_CONTAINS_VERTEX +#endif + +#include + +#include +#include + +#include + +#include + +#include + +#include + +#include BOOST_INCLUDE(random.hpp) + +namespace { + bool emb_test(carve::poly::Polyhedron *poly, + std::map > &embedding, + carve::geom3d::Vector v, + int m_id) { + + std::map result; +#if defined(CARVE_DEBUG) + std::cerr << "test " << v << " (m_id:" << m_id << ")" << std::endl; +#endif + poly->testVertexAgainstClosedManifolds(v, result, true); + std::set inside; + for (std::map::iterator j = result.begin(); + j != result.end(); + ++j) { + if ((*j).first == m_id) continue; + if ((*j).second == carve::POINT_IN) inside.insert((*j).first); + else if ((*j).second == carve::POINT_ON) { +#if defined(CARVE_DEBUG) + std::cerr << " FAIL" << std::endl; +#endif + return false; + } + } +#if defined(CARVE_DEBUG) + std::cerr << " OK (inside.size()==" << inside.size() << ")" << std::endl; +#endif + embedding[m_id] = inside; + return true; + } + + + + struct order_faces { + bool operator()(const carve::poly::Polyhedron::face_t * const &a, + const carve::poly::Polyhedron::face_t * const &b) const { + return std::lexicographical_compare(a->vbegin(), a->vend(), b->vbegin(), b->vend()); + } + }; + + + +} + + + +namespace carve { + namespace poly { + + + + bool Polyhedron::initSpatialIndex() { + static carve::TimingName FUNC_NAME("Polyhedron::initSpatialIndex()"); + carve::TimingBlock block(FUNC_NAME); + + octree.setBounds(aabb); + octree.addFaces(faces); + octree.addEdges(edges); + octree.splitTree(); + + return true; + } + + + + void Polyhedron::invertAll() { + for (size_t i = 0; i < faces.size(); ++i) { + faces[i].invert(); + } + + for (size_t i = 0; i < edges.size(); ++i) { + std::vector &f = connectivity.edge_to_face[i]; + for (size_t j = 0; j < (f.size() & ~1U); j += 2) { + std::swap(f[j], f[j+1]); + } + } + + for (size_t i = 0; i < manifold_is_negative.size(); ++i) { + manifold_is_negative[i] = !manifold_is_negative[i]; + } + } + + + + void Polyhedron::invert(const std::vector &selected_manifolds) { + bool altered = false; + for (size_t i = 0; i < faces.size(); ++i) { + if (faces[i].manifold_id >= 0 && + (unsigned)faces[i].manifold_id < selected_manifolds.size() && + selected_manifolds[faces[i].manifold_id]) { + altered = true; + faces[i].invert(); + } + } + + if (altered) { + for (size_t i = 0; i < edges.size(); ++i) { + std::vector &f = connectivity.edge_to_face[i]; + for (size_t j = 0; j < (f.size() & ~1U); j += 2) { + int m_id = -1; + if (f[j]) m_id = f[j]->manifold_id; + if (f[j+1]) m_id = f[j+1]->manifold_id; + if (m_id >= 0 && (unsigned)m_id < selected_manifolds.size() && selected_manifolds[m_id]) { + std::swap(f[j], f[j+1]); + } + } + } + + for (size_t i = 0; i < std::min(selected_manifolds.size(), manifold_is_negative.size()); ++i) { + manifold_is_negative[i] = !manifold_is_negative[i]; + } + } + } + + + + void Polyhedron::initVertexConnectivity() { + static carve::TimingName FUNC_NAME("static Polyhedron initVertexConnectivity()"); + carve::TimingBlock block(FUNC_NAME); + + // allocate space for connectivity info. + connectivity.vertex_to_edge.resize(vertices.size()); + connectivity.vertex_to_face.resize(vertices.size()); + + std::vector vertex_face_count; + + vertex_face_count.resize(vertices.size()); + + // work out how many faces/edges each vertex is connected to, in + // order to save on array reallocs. + for (unsigned i = 0; i < faces.size(); ++i) { + face_t &f = faces[i]; + for (unsigned j = 0; j < f.nVertices(); j++) { + vertex_face_count[vertexToIndex_fast(f.vertex(j))]++; + } + } + + for (size_t i = 0; i < vertices.size(); ++i) { + connectivity.vertex_to_edge[i].reserve(vertex_face_count[i]); + connectivity.vertex_to_face[i].reserve(vertex_face_count[i]); + } + + // record connectivity from vertex to edges. + for (size_t i = 0; i < edges.size(); ++i) { + size_t v1i = vertexToIndex_fast(edges[i].v1); + size_t v2i = vertexToIndex_fast(edges[i].v2); + + connectivity.vertex_to_edge[v1i].push_back(&edges[i]); + connectivity.vertex_to_edge[v2i].push_back(&edges[i]); + } + + // record connectivity from vertex to faces. + for (size_t i = 0; i < faces.size(); ++i) { + face_t &f = faces[i]; + for (unsigned j = 0; j < f.nVertices(); j++) { + size_t vi = vertexToIndex_fast(f.vertex(j)); + connectivity.vertex_to_face[vi].push_back(&f); + } + } + } + + + + bool Polyhedron::initConnectivity() { + static carve::TimingName FUNC_NAME("Polyhedron::initConnectivity()"); + carve::TimingBlock block(FUNC_NAME); + + // temporary measure: initialize connectivity by creating a + // half-edge mesh, and then converting back. + + std::vector > vertex_storage; + vertex_storage.reserve(vertices.size()); + for (size_t i = 0; i < vertices.size(); ++i) { + vertex_storage.push_back(mesh::Vertex<3>(vertices[i].v)); + } + + std::vector *> mesh_faces; + std::unordered_map *, size_t> face_map; + { + std::vector *> vert_ptrs; + for (size_t i = 0; i < faces.size(); ++i) { + const face_t &src = faces[i]; + vert_ptrs.clear(); + vert_ptrs.reserve(src.nVertices()); + for (size_t j = 0; j < src.nVertices(); ++j) { + size_t vi = vertexToIndex_fast(src.vertex(j)); + vert_ptrs.push_back(&vertex_storage[vi]); + } + mesh::Face<3> *face = new mesh::Face<3>(vert_ptrs.begin(), vert_ptrs.end()); + mesh_faces.push_back(face); + face_map[face] = i; + } + } + + std::vector *> meshes; + mesh::Mesh<3>::create(mesh_faces.begin(), mesh_faces.end(), meshes); + mesh::MeshSet<3> *meshset = new mesh::MeshSet<3>(vertex_storage, meshes); + + manifold_is_closed.resize(meshset->meshes.size()); + manifold_is_negative.resize(meshset->meshes.size()); + + std::unordered_map, std::list *> > edge_map; + + if (meshset->vertex_storage.size()) { + mesh::Vertex<3> *Vbase = &meshset->vertex_storage[0]; + for (size_t m = 0; m < meshset->meshes.size(); ++m) { + mesh::Mesh<3> *mesh = meshset->meshes[m]; + manifold_is_closed[m] = mesh->isClosed(); + for (size_t f = 0; f < mesh->faces.size(); ++f) { + mesh::Face<3> *src = mesh->faces[f]; + mesh::Edge<3> *e = src->edge; + faces[face_map[src]].manifold_id = m; + do { + edge_map[std::make_pair(e->v1() - Vbase, e->v2() - Vbase)].push_back(e); + e = e->next; + } while (e != src->edge); + } + } + } + + size_t n_edges = 0; + for (std::unordered_map, std::list *> >::iterator i = edge_map.begin(); i != edge_map.end(); ++i) { + if ((*i).first.first < (*i).first.second || edge_map.find(std::make_pair((*i).first.second, (*i).first.first)) == edge_map.end()) { + n_edges++; + } + } + + edges.clear(); + edges.reserve(n_edges); + for (std::unordered_map, std::list *> >::iterator i = edge_map.begin(); i != edge_map.end(); ++i) { + if ((*i).first.first < (*i).first.second || edge_map.find(std::make_pair((*i).first.second, (*i).first.first)) == edge_map.end()) { + edges.push_back(edge_t(&vertices[(*i).first.first], &vertices[(*i).first.second], this)); + } + } + + initVertexConnectivity(); + + for (size_t f = 0; f < faces.size(); ++f) { + face_t &face = faces[f]; + size_t N = face.nVertices(); + for (size_t v = 0; v < N; ++v) { + size_t v1i = vertexToIndex_fast(face.vertex(v)); + size_t v2i = vertexToIndex_fast(face.vertex((v+1)%N)); + std::vector found_edge; + + CARVE_ASSERT(carve::is_sorted(connectivity.vertex_to_edge[v1i].begin(), connectivity.vertex_to_edge[v1i].end())); + CARVE_ASSERT(carve::is_sorted(connectivity.vertex_to_edge[v2i].begin(), connectivity.vertex_to_edge[v2i].end())); + + std::set_intersection(connectivity.vertex_to_edge[v1i].begin(), connectivity.vertex_to_edge[v1i].end(), + connectivity.vertex_to_edge[v2i].begin(), connectivity.vertex_to_edge[v2i].end(), + std::back_inserter(found_edge)); + + CARVE_ASSERT(found_edge.size() == 1); + + face.edge(v) = found_edge[0]; + } + } + + connectivity.edge_to_face.resize(edges.size()); + + for (size_t i = 0; i < edges.size(); ++i) { + size_t v1i = vertexToIndex_fast(edges[i].v1); + size_t v2i = vertexToIndex_fast(edges[i].v2); + std::list *> &efwd = edge_map[std::make_pair(v1i, v2i)]; + std::list *> &erev = edge_map[std::make_pair(v1i, v2i)]; + + for (std::list *>::iterator j = efwd.begin(); j != efwd.end(); ++j) { + mesh::Edge<3> *edge = *j; + if (face_map.find(edge->face) != face_map.end()) { + connectivity.edge_to_face[i].push_back(&faces[face_map[edge->face]]); + if (edge->rev == NULL) { + connectivity.edge_to_face[i].push_back(NULL); + } else { + connectivity.edge_to_face[i].push_back(&faces[face_map[edge->rev->face]]); + } + } + } + for (std::list *>::iterator j = erev.begin(); j != erev.end(); ++j) { + mesh::Edge<3> *edge = *j; + if (face_map.find(edge->face) != face_map.end()) { + if (edge->rev == NULL) { + connectivity.edge_to_face[i].push_back(NULL); + connectivity.edge_to_face[i].push_back(&faces[face_map[edge->face]]); + } + } + } + } + + delete meshset; + + return true; + } + + + + bool Polyhedron::calcManifoldEmbedding() { + // this could be significantly sped up using bounding box tests + // to work out what pairs of manifolds are embedding candidates. + // A per-manifold AABB could also be used to speed up + // testVertexAgainstClosedManifolds(). + + static carve::TimingName FUNC_NAME("Polyhedron::calcManifoldEmbedding()"); + static carve::TimingName CME_V("Polyhedron::calcManifoldEmbedding() (vertices)"); + static carve::TimingName CME_E("Polyhedron::calcManifoldEmbedding() (edges)"); + static carve::TimingName CME_F("Polyhedron::calcManifoldEmbedding() (faces)"); + + carve::TimingBlock block(FUNC_NAME); + + const unsigned MCOUNT = manifoldCount(); + if (MCOUNT < 2) return true; + + std::set vertex_manifolds; + std::map > embedding; + + carve::Timing::start(CME_V); + for (size_t i = 0; i < vertices.size(); ++i) { + vertex_manifolds.clear(); + if (vertexManifolds(&vertices[i], set_inserter(vertex_manifolds)) != 1) continue; + int m_id = *vertex_manifolds.begin(); + if (embedding.find(m_id) == embedding.end()) { + if (emb_test(this, embedding, vertices[i].v, m_id) && embedding.size() == MCOUNT) { + carve::Timing::stop(); + goto done; + } + } + } + carve::Timing::stop(); + + carve::Timing::start(CME_E); + for (size_t i = 0; i < edges.size(); ++i) { + if (connectivity.edge_to_face[i].size() == 2) { + int m_id; + const face_t *f1 = connectivity.edge_to_face[i][0]; + const face_t *f2 = connectivity.edge_to_face[i][1]; + if (f1) m_id = f1->manifold_id; + if (f2) m_id = f2->manifold_id; + if (embedding.find(m_id) == embedding.end()) { + if (emb_test(this, embedding, (edges[i].v1->v + edges[i].v2->v) / 2, m_id) && embedding.size() == MCOUNT) { + carve::Timing::stop(); + goto done; + } + } + } + } + carve::Timing::stop(); + + carve::Timing::start(CME_F); + for (size_t i = 0; i < faces.size(); ++i) { + int m_id = faces[i].manifold_id; + if (embedding.find(m_id) == embedding.end()) { + carve::geom2d::P2 pv; + if (!carve::geom2d::pickContainedPoint(faces[i].projectedVertices(), pv)) continue; + carve::geom3d::Vector v = carve::poly::face::unproject(faces[i], pv); + if (emb_test(this, embedding, v, m_id) && embedding.size() == MCOUNT) { + carve::Timing::stop(); + goto done; + } + } + } + carve::Timing::stop(); + + CARVE_FAIL("could not find test points"); + + // std::cerr << "could not find test points!!!" << std::endl; + // return true; + done:; + for (std::map >::iterator i = embedding.begin(); i != embedding.end(); ++i) { +#if defined(CARVE_DEBUG) + std::cerr << (*i).first << " : "; + std::copy((*i).second.begin(), (*i).second.end(), std::ostream_iterator(std::cerr, ",")); + std::cerr << std::endl; +#endif + (*i).second.insert(-1); + } + std::set parents, new_parents; + parents.insert(-1); + + while (embedding.size()) { + new_parents.clear(); + for (std::map >::iterator i = embedding.begin(); i != embedding.end(); ++i) { + if ((*i).second.size() == 1) { + if (parents.find(*(*i).second.begin()) != parents.end()) { + new_parents.insert((*i).first); +#if defined(CARVE_DEBUG) + std::cerr << "parent(" << (*i).first << "): " << *(*i).second.begin() << std::endl; +#endif + } else { +#if defined(CARVE_DEBUG) + std::cerr << "no parent: " << (*i).first << " (looking for: " << *(*i).second.begin() << ")" << std::endl; +#endif + } + } + } + for (std::set::const_iterator i = new_parents.begin(); i != new_parents.end(); ++i) { + embedding.erase(*i); + } + for (std::map >::iterator i = embedding.begin(); i != embedding.end(); ++i) { + size_t n = 0; + for (std::set::const_iterator j = parents.begin(); j != parents.end(); ++j) { + n += (*i).second.erase((*j)); + } + CARVE_ASSERT(n != 0); + } + parents.swap(new_parents); + } + + return true; + } + + + + bool Polyhedron::init() { + static carve::TimingName FUNC_NAME("Polyhedron::init()"); + carve::TimingBlock block(FUNC_NAME); + + aabb.fit(vertices.begin(), vertices.end(), vec_adapt_vertex_ref()); + + connectivity.vertex_to_edge.clear(); + connectivity.vertex_to_face.clear(); + connectivity.edge_to_face.clear(); + + if (!initConnectivity()) return false; + if (!initSpatialIndex()) return false; + + return true; + } + + + + void Polyhedron::faceRecalc() { + for (size_t i = 0; i < faces.size(); ++i) { + if (!faces[i].recalc()) { + std::ostringstream out; + out << "face " << i << " recalc failed"; + throw carve::exception(out.str()); + } + } + } + + + + Polyhedron::Polyhedron(const Polyhedron &poly) { + faces.reserve(poly.faces.size()); + + for (size_t i = 0; i < poly.faces.size(); ++i) { + const face_t &src = poly.faces[i]; + faces.push_back(src); + } + commonFaceInit(false); // calls setFaceAndVertexOwner() and init() + } + + + + Polyhedron::Polyhedron(const Polyhedron &poly, const std::vector &selected_manifolds) { + size_t n_faces = 0; + + for (size_t i = 0; i < poly.faces.size(); ++i) { + const face_t &src = poly.faces[i]; + if (src.manifold_id >= 0 && + (unsigned)src.manifold_id < selected_manifolds.size() && + selected_manifolds[src.manifold_id]) { + n_faces++; + } + } + + faces.reserve(n_faces); + + for (size_t i = 0; i < poly.faces.size(); ++i) { + const face_t &src = poly.faces[i]; + if (src.manifold_id >= 0 && + (unsigned)src.manifold_id < selected_manifolds.size() && + selected_manifolds[src.manifold_id]) { + faces.push_back(src); + } + } + + commonFaceInit(false); // calls setFaceAndVertexOwner() and init() + } + + + + Polyhedron::Polyhedron(const Polyhedron &poly, int m_id) { + size_t n_faces = 0; + + for (size_t i = 0; i < poly.faces.size(); ++i) { + const face_t &src = poly.faces[i]; + if (src.manifold_id == m_id) n_faces++; + } + + faces.reserve(n_faces); + + for (size_t i = 0; i < poly.faces.size(); ++i) { + const face_t &src = poly.faces[i]; + if (src.manifold_id == m_id) faces.push_back(src); + } + + commonFaceInit(false); // calls setFaceAndVertexOwner() and init() + } + + + + Polyhedron::Polyhedron(const std::vector &_vertices, + int n_faces, + const std::vector &face_indices) { + // The polyhedron is defined by a vector of vertices, which we + // want to copy, and a face index list, from which we need to + // generate a set of Faces. + + vertices.clear(); + vertices.resize(_vertices.size()); + for (size_t i = 0; i < _vertices.size(); ++i) { + vertices[i].v = _vertices[i]; + } + + faces.reserve(n_faces); + + std::vector::const_iterator iter = face_indices.begin(); + std::vector v; + for (int i = 0; i < n_faces; ++i) { + int vertexCount = *iter++; + + v.clear(); + + while (vertexCount--) { + CARVE_ASSERT(*iter >= 0); + CARVE_ASSERT((unsigned)*iter < vertices.size()); + v.push_back(&vertices[*iter++]); + } + faces.push_back(face_t(v)); + } + + setFaceAndVertexOwner(); + + if (!init()) { + throw carve::exception("polyhedron creation failed"); + } + } + + + + Polyhedron::Polyhedron(std::vector &_faces, + std::vector &_vertices, + bool _recalc) { + faces.swap(_faces); + vertices.swap(_vertices); + + setFaceAndVertexOwner(); + + if (_recalc) faceRecalc(); + + if (!init()) { + throw carve::exception("polyhedron creation failed"); + } + } + + + + Polyhedron::Polyhedron(std::vector &_faces, + bool _recalc) { + faces.swap(_faces); + commonFaceInit(_recalc); // calls setFaceAndVertexOwner() and init() + } + + + + Polyhedron::Polyhedron(std::list &_faces, + bool _recalc) { + faces.reserve(_faces.size()); + std::copy(_faces.begin(), _faces.end(), std::back_inserter(faces)); + commonFaceInit(_recalc); // calls setFaceAndVertexOwner() and init() + } + + + + void Polyhedron::collectFaceVertices(std::vector &faces, + std::vector &vertices, + std::unordered_map &vmap) { + // Given a set of faces, copy all referenced vertices into a + // single vertex array and update the faces to point into that + // array. On exit, vmap contains a mapping from old pointer to + // new pointer. + + vertices.clear(); + vmap.clear(); + + for (size_t i = 0, il = faces.size(); i != il; ++i) { + face_t &f = faces[i]; + + for (size_t j = 0, jl = f.nVertices(); j != jl; ++j) { + vmap[f.vertex(j)] = NULL; + } + } + + vertices.reserve(vmap.size()); + + for (std::unordered_map::iterator i = vmap.begin(), + e = vmap.end(); + i != e; + ++i) { + vertices.push_back(*(*i).first); + (*i).second = &vertices.back(); + } + + for (size_t i = 0, il = faces.size(); i != il; ++i) { + face_t &f = faces[i]; + + for (size_t j = 0, jl = f.nVertices(); j != jl; ++j) { + f.vertex(j) = vmap[f.vertex(j)]; + } + } + } + + + + void Polyhedron::collectFaceVertices(std::vector &faces, + std::vector &vertices) { + std::unordered_map vmap; + collectFaceVertices(faces, vertices, vmap); + } + + + + void Polyhedron::setFaceAndVertexOwner() { + for (size_t i = 0; i < vertices.size(); ++i) vertices[i].owner = this; + for (size_t i = 0; i < faces.size(); ++i) faces[i].owner = this; + } + + + + void Polyhedron::commonFaceInit(bool _recalc) { + collectFaceVertices(faces, vertices); + setFaceAndVertexOwner(); + if (_recalc) faceRecalc(); + + if (!init()) { + throw carve::exception("polyhedron creation failed"); + } + } + + + + Polyhedron::~Polyhedron() { + } + + + + void Polyhedron::testVertexAgainstClosedManifolds(const carve::geom3d::Vector &v, + std::map &result, + bool ignore_orientation) const { + + for (size_t i = 0; i < faces.size(); i++) { + if (!manifold_is_closed[faces[i].manifold_id]) continue; // skip open manifolds + if (faces[i].containsPoint(v)) { + result[faces[i].manifold_id] = POINT_ON; + } + } + + double ray_len = aabb.extent.length() * 2; + + std::vector possible_faces; + + std::vector > manifold_intersections; + + boost::mt19937 rng; + boost::uniform_on_sphere distrib(3); + boost::variate_generator > gen(rng, distrib); + + for (;;) { + carve::geom3d::Vector ray_dir; + ray_dir = gen(); + + carve::geom3d::Vector v2 = v + ray_dir * ray_len; + + bool failed = false; + carve::geom3d::LineSegment line(v, v2); + carve::geom3d::Vector intersection; + + possible_faces.clear(); + manifold_intersections.clear(); + octree.findFacesNear(line, possible_faces); + + for (unsigned i = 0; !failed && i < possible_faces.size(); i++) { + if (!manifold_is_closed[possible_faces[i]->manifold_id]) continue; // skip open manifolds + if (result.find(possible_faces[i]->manifold_id) != result.end()) continue; // already ON + + switch (possible_faces[i]->lineSegmentIntersection(line, intersection)) { + case INTERSECT_FACE: { + manifold_intersections.push_back(std::make_pair(possible_faces[i], intersection)); + break; + } + case INTERSECT_NONE: { + break; + } + default: { + failed = true; + break; + } + } + } + + if (!failed) break; + } + + std::vector crossings(manifold_is_closed.size(), 0); + + for (size_t i = 0; i < manifold_intersections.size(); ++i) { + const face_t *f = manifold_intersections[i].first; + crossings[f->manifold_id]++; + } + + for (size_t i = 0; i < crossings.size(); ++i) { +#if defined(CARVE_DEBUG) + std::cerr << "crossing: " << i << " = " << crossings[i] << " is_negative = " << manifold_is_negative[i] << std::endl; +#endif + if (!manifold_is_closed[i]) continue; + if (result.find(i) != result.end()) continue; + PointClass pc = (crossings[i] & 1) ? POINT_IN : POINT_OUT; + if (!ignore_orientation && manifold_is_negative[i]) pc = (PointClass)-pc; + result[i] = pc; + } + } + + + + PointClass Polyhedron::containsVertex(const carve::geom3d::Vector &v, + const face_t **hit_face, + bool even_odd, + int manifold_id) const { + if (hit_face) *hit_face = NULL; + +#if defined(DEBUG_CONTAINS_VERTEX) + std::cerr << "{containsVertex " << v << "}" << std::endl; +#endif + + if (!aabb.containsPoint(v)) { +#if defined(DEBUG_CONTAINS_VERTEX) + std::cerr << "{final:OUT(aabb short circuit)}" << std::endl; +#endif + // XXX: if the top level manifolds are negative, this should be POINT_IN. + // for the moment, this only works for a single manifold. + if (manifold_is_negative.size() == 1 && manifold_is_negative[0]) return POINT_IN; + return POINT_OUT; + } + + for (size_t i = 0; i < faces.size(); i++) { + if (manifold_id != -1 && manifold_id != faces[i].manifold_id) continue; + + // XXX: Do allow the tested vertex to be ON an open + // manifold. This was here originally because of the + // possibility of an open manifold contained within a closed + // manifold. + + // if (!manifold_is_closed[faces[i].manifold_id]) continue; + + if (faces[i].containsPoint(v)) { +#if defined(DEBUG_CONTAINS_VERTEX) + std::cerr << "{final:ON(hits face " << &faces[i] << ")}" << std::endl; +#endif + if (hit_face) *hit_face = &faces[i]; + return POINT_ON; + } + } + + double ray_len = aabb.extent.length() * 2; + + std::vector possible_faces; + + std::vector > manifold_intersections; + + for (;;) { + double a1 = random() / double(RAND_MAX) * M_TWOPI; + double a2 = random() / double(RAND_MAX) * M_TWOPI; + + carve::geom3d::Vector ray_dir = carve::geom::VECTOR(sin(a1) * sin(a2), cos(a1) * sin(a2), cos(a2)); + +#if defined(DEBUG_CONTAINS_VERTEX) + std::cerr << "{testing ray: " << ray_dir << "}" << std::endl; +#endif + + carve::geom3d::Vector v2 = v + ray_dir * ray_len; + + bool failed = false; + carve::geom3d::LineSegment line(v, v2); + carve::geom3d::Vector intersection; + + possible_faces.clear(); + manifold_intersections.clear(); + octree.findFacesNear(line, possible_faces); + + for (unsigned i = 0; !failed && i < possible_faces.size(); i++) { + if (manifold_id != -1 && manifold_id != faces[i].manifold_id) continue; + + if (!manifold_is_closed[possible_faces[i]->manifold_id]) continue; + + switch (possible_faces[i]->lineSegmentIntersection(line, intersection)) { + case INTERSECT_FACE: { + +#if defined(DEBUG_CONTAINS_VERTEX) + std::cerr << "{intersects face: " << possible_faces[i] + << " dp: " << dot(ray_dir, possible_faces[i]->plane_eqn.N) << "}" << std::endl; +#endif + + if (!even_odd && fabs(dot(ray_dir, possible_faces[i]->plane_eqn.N)) < EPSILON) { + +#if defined(DEBUG_CONTAINS_VERTEX) + std::cerr << "{failing(small dot product)}" << std::endl; +#endif + + failed = true; + break; + } + manifold_intersections.push_back(std::make_pair(possible_faces[i], intersection)); + break; + } + case INTERSECT_NONE: { + break; + } + default: { + +#if defined(DEBUG_CONTAINS_VERTEX) + std::cerr << "{failing(degenerate intersection)}" << std::endl; +#endif + failed = true; + break; + } + } + } + + if (!failed) { + if (even_odd) { + return (manifold_intersections.size() & 1) ? POINT_IN : POINT_OUT; + } + +#if defined(DEBUG_CONTAINS_VERTEX) + std::cerr << "{intersections ok [count:" + << manifold_intersections.size() + << "], sorting}" + << std::endl; +#endif + + carve::geom3d::sortInDirectionOfRay(ray_dir, + manifold_intersections.begin(), + manifold_intersections.end(), + carve::geom3d::vec_adapt_pair_second()); + + std::vector crossings(manifold_is_closed.size(), 0); + + for (size_t i = 0; i < manifold_intersections.size(); ++i) { + const face_t *f = manifold_intersections[i].first; + if (dot(ray_dir, f->plane_eqn.N) < 0.0) { + crossings[f->manifold_id]++; + } else { + crossings[f->manifold_id]--; + } + } + +#if defined(DEBUG_CONTAINS_VERTEX) + for (size_t i = 0; i < crossings.size(); ++i) { + std::cerr << "{manifold " << i << " crossing count: " << crossings[i] << "}" << std::endl; + } +#endif + + for (size_t i = 0; i < manifold_intersections.size(); ++i) { + const face_t *f = manifold_intersections[i].first; + +#if defined(DEBUG_CONTAINS_VERTEX) + std::cerr << "{intersection at " + << manifold_intersections[i].second + << " id: " + << f->manifold_id + << " count: " + << crossings[f->manifold_id] + << "}" + << std::endl; +#endif + + if (crossings[f->manifold_id] < 0) { + // inside this manifold. + +#if defined(DEBUG_CONTAINS_VERTEX) + std::cerr << "{final:IN}" << std::endl; +#endif + + return POINT_IN; + } else if (crossings[f->manifold_id] > 0) { + // outside this manifold, but it's an infinite manifold. (for instance, an inverted cube) + +#if defined(DEBUG_CONTAINS_VERTEX) + std::cerr << "{final:OUT}" << std::endl; +#endif + + return POINT_OUT; + } + } + +#if defined(DEBUG_CONTAINS_VERTEX) + std::cerr << "{final:OUT(default)}" << std::endl; +#endif + + return POINT_OUT; + } + } + } + + + + void Polyhedron::findEdgesNear(const carve::geom::aabb<3> &aabb, + std::vector &outEdges) const { + outEdges.clear(); + octree.findEdgesNear(aabb, outEdges); + } + + + + void Polyhedron::findEdgesNear(const carve::geom3d::LineSegment &line, + std::vector &outEdges) const { + outEdges.clear(); + octree.findEdgesNear(line, outEdges); + } + + + + void Polyhedron::findEdgesNear(const carve::geom3d::Vector &v, + std::vector &outEdges) const { + outEdges.clear(); + octree.findEdgesNear(v, outEdges); + } + + + + void Polyhedron::findEdgesNear(const face_t &face, + std::vector &edges) const { + edges.clear(); + octree.findEdgesNear(face, edges); + } + + + + void Polyhedron::findEdgesNear(const edge_t &edge, + std::vector &outEdges) const { + outEdges.clear(); + octree.findEdgesNear(edge, outEdges); + } + + + + void Polyhedron::findFacesNear(const carve::geom3d::LineSegment &line, + std::vector &outFaces) const { + outFaces.clear(); + octree.findFacesNear(line, outFaces); + } + + + + void Polyhedron::findFacesNear(const carve::geom::aabb<3> &aabb, + std::vector &outFaces) const { + outFaces.clear(); + octree.findFacesNear(aabb, outFaces); + } + + + + void Polyhedron::findFacesNear(const edge_t &edge, + std::vector &outFaces) const { + outFaces.clear(); + octree.findFacesNear(edge, outFaces); + } + + + + void Polyhedron::transform(const carve::math::Matrix &xform) { + for (size_t i = 0; i < vertices.size(); i++) { + vertices[i].v = xform * vertices[i].v; + } + for (size_t i = 0; i < faces.size(); i++) { + faces[i].recalc(); + } + init(); + } + + + + void Polyhedron::print(std::ostream &o) const { + o << "Polyhedron@" << this << " {" << std::endl; + for (std::vector::const_iterator + i = vertices.begin(), e = vertices.end(); i != e; ++i) { + o << " V@" << &(*i) << " " << (*i).v << std::endl; + } + for (std::vector::const_iterator + i = edges.begin(), e = edges.end(); i != e; ++i) { + o << " E@" << &(*i) << " {" << std::endl; + o << " V@" << (*i).v1 << " - " << "V@" << (*i).v2 << std::endl; + const std::vector &faces = connectivity.edge_to_face[edgeToIndex_fast(&(*i))]; + for (size_t j = 0; j < (faces.size() & ~1U); j += 2) { + o << " fp: F@" << faces[j] << ", F@" << faces[j+1] << std::endl; + } + o << " }" << std::endl; + } + for (std::vector::const_iterator + i = faces.begin(), e = faces.end(); i != e; ++i) { + o << " F@" << &(*i) << " {" << std::endl; + o << " vertices {" << std::endl; + for (face_t::const_vertex_iter_t j = (*i).vbegin(), je = (*i).vend(); j != je; ++j) { + o << " V@" << (*j) << std::endl; + } + o << " }" << std::endl; + o << " edges {" << std::endl; + for (face_t::const_edge_iter_t j = (*i).ebegin(), je = (*i).eend(); j != je; ++j) { + o << " E@" << (*j) << std::endl; + } + carve::geom::plane<3> p = (*i).plane_eqn; + o << " }" << std::endl; + o << " normal " << (*i).plane_eqn.N << std::endl; + o << " aabb " << (*i).aabb << std::endl; + o << " plane_eqn "; + carve::geom::operator<< <3>(o, p); + o << std::endl; + o << " }" << std::endl; + } + + o << "}" << std::endl; + } + + + + void Polyhedron::canonicalize() { + orderVertices(); + for (size_t i = 0; i < faces.size(); i++) { + face_t &f = faces[i]; + size_t j = std::distance(f.vbegin(), + std::min_element(f.vbegin(), + f.vend())); + if (j) { + { + std::vector temp; + temp.reserve(f.nVertices()); + std::copy(f.vbegin() + j, f.vend(), std::back_inserter(temp)); + std::copy(f.vbegin(), f.vbegin() + j, std::back_inserter(temp)); + std::copy(temp.begin(), temp.end(), f.vbegin()); + } + { + std::vector temp; + temp.reserve(f.nEdges()); + std::copy(f.ebegin() + j, f.eend(), std::back_inserter(temp)); + std::copy(f.ebegin(), f.ebegin() + j, std::back_inserter(temp)); + std::copy(temp.begin(), temp.end(), f.ebegin()); + } + } + } + + std::vector face_ptrs; + face_ptrs.reserve(faces.size()); + for (size_t i = 0; i < faces.size(); ++i) face_ptrs.push_back(&faces[i]); + std::sort(face_ptrs.begin(), face_ptrs.end(), order_faces()); + std::vector sorted_faces; + sorted_faces.reserve(faces.size()); + for (size_t i = 0; i < faces.size(); ++i) sorted_faces.push_back(*face_ptrs[i]); + std::swap(faces, sorted_faces); + } + + } +} + diff -Nru blender-2.61/extern/carve/lib/polyline.cpp blender-2.62/extern/carve/lib/polyline.cpp --- blender-2.61/extern/carve/lib/polyline.cpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/polyline.cpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,67 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#if defined(HAVE_CONFIG_H) +# include +#endif + +#include +#include +#include + +namespace carve { + namespace line { + carve::geom3d::AABB Polyline::aabb() const { + return carve::geom3d::AABB(vbegin(), vend(), vec_adapt_vertex_ptr()); + } + + PolylineSet::PolylineSet(const std::vector &points) { + vertices.resize(points.size()); + for (size_t i = 0; i < points.size(); ++i) vertices[i].v = points[i]; + aabb.fit(points.begin(), points.end(), carve::geom3d::vec_adapt_ident()); + } + + void PolylineSet::sortVertices(const carve::geom3d::Vector &axis) { + std::vector > temp; + temp.reserve(vertices.size()); + for (size_t i = 0; i < vertices.size(); ++i) { + temp.push_back(std::make_pair(dot(axis, vertices[i].v), i)); + } + std::sort(temp.begin(), temp.end()); + std::vector vnew; + std::vector revmap; + vnew.reserve(vertices.size()); + revmap.resize(vertices.size()); + + for (size_t i = 0; i < vertices.size(); ++i) { + vnew.push_back(vertices[temp[i].second]); + revmap[temp[i].second] = i; + } + + for (line_iter i = lines.begin(); i != lines.end(); ++i) { + Polyline &l = *(*i); + for (size_t j = 0; j < l.edges.size(); ++j) { + PolylineEdge &e = *l.edges[j]; + if (e.v1) e.v1 = &vnew[revmap[vertexToIndex_fast(e.v1)]]; + if (e.v2) e.v2 = &vnew[revmap[vertexToIndex_fast(e.v2)]]; + } + } + vertices.swap(vnew); + } + + } +} diff -Nru blender-2.61/extern/carve/lib/tag.cpp blender-2.62/extern/carve/lib/tag.cpp --- blender-2.61/extern/carve/lib/tag.cpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/tag.cpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,24 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#if defined(HAVE_CONFIG_H) +# include +#endif + +#include + +int carve::tagable::s_count = 0; diff -Nru blender-2.61/extern/carve/lib/timing.cpp blender-2.62/extern/carve/lib/timing.cpp --- blender-2.61/extern/carve/lib/timing.cpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/timing.cpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,436 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#if CARVE_USE_TIMINGS + +#if defined(HAVE_CONFIG_H) +# include +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef WIN32 +#include +#else +#include +#include +#endif + +#ifndef CARVE_USE_GLOBAL_NEW_DELETE +#define CARVE_USE_GLOBAL_NEW_DELETE 0 +#endif + +namespace carve { + static uint64_t memoryCurr = 0; + static uint64_t memoryTotal = 0; + unsigned blkCntCurr[32] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; + unsigned blkCntTotal[32] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; + + void addBlk(unsigned size) { + unsigned i = 0; + while (i < 31 && (1U< +#include + +void* carve_alloc(size_t size) { + void *p = malloc(size); + if (p == 0) throw std::bad_alloc(); // ANSI/ISO compliant behavior + + unsigned sz = malloc_size(p); + carve::memoryCurr += sz; + carve::memoryTotal += sz; + carve::addBlk(sz); + return p; +} + +void carve_free(void *p) { + unsigned sz = malloc_size(p); + carve::memoryCurr -= sz; + carve::remBlk(sz); + free(p); +} + +#else + +void* carve_alloc(size_t size) { + void *p = malloc(size + 4); + if (p == 0) throw std::bad_alloc(); // ANSI/ISO compliant behavior + + int *sizePtr = (int*)p; + *sizePtr = size; + ++sizePtr; + carve::memoryCurr += size; + carve::memoryTotal += size; + carve::addBlk(size); + return sizePtr; +} + +void carve_free(void *p) { + // our memory block is actually a size of an int behind this pointer. + int *sizePtr = (int*)p; + + --sizePtr; + + carve::memoryCurr -= *sizePtr; + int size = *sizePtr; + carve::remBlk(size); + free(sizePtr); +} + +#endif + + +void* operator new (size_t size) { + return carve_alloc(size); +} + +void* operator new[](size_t size) { + return carve_alloc(size); +} + + +void operator delete (void *p) { + carve_free(p); +} + +void operator delete[](void *p) { + carve_free(p); +} + +#endif + +namespace carve { + + + +#ifdef WIN32 + + typedef __int64 precise_time_t; + + precise_time_t g_frequency; + + void initTime() { + ::QueryPerformanceFrequency((LARGE_INTEGER*)&g_frequency); + } + + void getTime(precise_time_t &t) { + ::QueryPerformanceCounter((LARGE_INTEGER*)&t); + } + + double diffTime(precise_time_t from, precise_time_t to) { + return (double)(to - from) / (double)g_frequency; + } + +#else + + typedef double precise_time_t; + + void initTime() { + } + + void getTime(precise_time_t &t) { + struct timeval tv; + gettimeofday(&tv, NULL); + t = tv.tv_sec + tv.tv_usec / 1000000.0; + } + + double diffTime(precise_time_t from, precise_time_t to) { + return to - from; + } + +#endif + + struct Entry { + Entry(int _id) { + id = _id; + time = 0; + parent = NULL; + } + int id; + double time; + int64_t memoryDiff; + int64_t allocTotal; + int delta_blk_cnt_curr[32]; + int delta_blk_cnt_total[32]; + Entry *parent; + std::vector children; + }; + + struct Timer { + struct cmp { + bool operator()(const std::pair &a, const std::pair &b) const { + return b.second < a.second; + } + bool operator()(const Entry * const &a, const Entry * const &b) const { + return b->time < a->time; + } + }; + + Timer() { + initTime(); + } + + struct Snapshot { + precise_time_t time; + uint64_t memory_curr; + uint64_t memory_total; + unsigned blk_cnt_curr[32]; + unsigned blk_cnt_total[32]; + }; + + static void getSnapshot(Snapshot &snapshot) { + getTime(snapshot.time); + snapshot.memory_curr = carve::memoryCurr; + snapshot.memory_total = carve::memoryTotal; + std::memcpy(snapshot.blk_cnt_curr, carve::blkCntCurr, sizeof(carve::blkCntCurr)); + std::memcpy(snapshot.blk_cnt_total, carve::blkCntTotal, sizeof(carve::blkCntTotal)); + } + + static void compareSnapshot(const Snapshot &from, const Snapshot &to, Entry *entry) { + entry->time = diffTime(from.time, to.time); + entry->memoryDiff = to.memory_curr - from.memory_curr; + entry->allocTotal = to.memory_total - from.memory_total; + for (int i = 0; i < 32; i++) { + entry->delta_blk_cnt_curr[i] = to.blk_cnt_curr[i] - from.blk_cnt_curr[i]; + entry->delta_blk_cnt_total[i] = to.blk_cnt_total[i] - from.blk_cnt_total[i]; + } + } + + std::stack > currentTimers; + + void startTiming(int id) { + entries.push_back(Entry(id)); + currentTimers.push(std::make_pair(&entries.back(), Snapshot())); + getSnapshot(currentTimers.top().second); + } + + double endTiming() { + Snapshot end; + getSnapshot(end); + + Entry *entry = currentTimers.top().first; + compareSnapshot(currentTimers.top().second, end, entry); + + currentTimers.pop(); + if (!currentTimers.empty()) { + entry->parent = currentTimers.top().first; + entry->parent->children.push_back(entry); + } else { + root_entries.push_back(entry); + } + //std::sort(entry->children.begin(), entry->children.end(), cmp()); + return entry->time; + } + + typedef std::list EntryList; + EntryList entries; + std::vector root_entries; + + std::map names; + + static std::string formatMemory(int64_t value) { + + std::ostringstream result; + + result << (value >= 0 ? "+" : "-"); + if (value < 0) { + value = -value; + } + + int power = 1; + while (value > pow(10.0, power)) { + power++; + } + + for (power--; power >= 0; power--) { + int64_t base = pow(10.0, power); + int64_t amount = value / base; + result << +#if defined(_MSC_VER) && _MSC_VER < 1300 + (long) +#endif + amount; + if (power > 0 && (power % 3) == 0) { + result << ","; + } + value -= amount * base; + } + + result << " bytes"; + + return result.str(); + } + + void printEntries(std::ostream &o, const std::vector &entries, const std::string &indent, double parent_time) { + if (parent_time <= 0.0) { + parent_time = 0.0; + for (size_t i = 0; i < entries.size(); ++i) { + parent_time += entries[i]->time; + } + } + double t_tot = 0.0; + for (size_t i = 0; i < entries.size(); ++i) { + const Entry *entry = entries[i]; + + std::ostringstream r; + r << indent; + std::string str = names[entry->id]; + if (str.empty()) { + r << "(" << entry->id << ")"; + } else { + r << str; + } + r << " "; + std::string pad(r.str().size(), ' '); + r << " - exectime: " << entry->time << "s (" << (entry->time * 100.0 / parent_time) << "%)" << std::endl; + if (entry->allocTotal || entry->memoryDiff) { + r << pad << " - alloc: " << formatMemory(entry->allocTotal) << " delta: " << formatMemory(entry->memoryDiff) << std::endl; + r << pad << " - alloc blks:"; + for (int i = 0; i < 32; i++) { if (entry->delta_blk_cnt_total[i]) r << ' ' << ((1 << (i - 1)) + 1) << '-' << (1 << i) << ':' << entry->delta_blk_cnt_total[i]; } + r << std::endl; + r << pad << " - delta blks:"; + for (int i = 0; i < 32; i++) { if (entry->delta_blk_cnt_curr[i]) r << ' ' << ((1 << (i - 1)) + 1) << '-' << (1 << i) << ':' << entry->delta_blk_cnt_curr[i]; } + r << std::endl; + } + o << r.str(); + t_tot += entry->time; + if (entry->children.size()) printEntries(o, entry->children, indent + " ", entry->time); + } + if (t_tot < parent_time) { + o << indent << "*** unaccounted: " << (parent_time - t_tot) << "s (" << (100.0 - t_tot * 100.0 / parent_time) << "%)" << std::endl; + } + } + + void print() { + std::map totals; + std::cerr << "Timings: " << std::endl; + // print out all the entries. + + //std::sort(root_entries.begin(), root_entries.end(), cmp()); + + printEntries(std::cerr, root_entries, " ", -1.0); + + for (EntryList::const_iterator it = entries.begin(); it != entries.end(); ++it) { + totals[(*it).id] += (*it).time; + } + + std::cerr << std::endl; + std::cerr << "Totals: " << std::endl; + + std::vector > sorted_totals; + sorted_totals.reserve(totals.size()); + for (std::map::iterator it = totals.begin(); it != totals.end(); ++it) { + sorted_totals.push_back(*it); + } + + std::sort(sorted_totals.begin(), sorted_totals.end(), cmp()); + + for (std::vector >::iterator it = sorted_totals.begin(); it != sorted_totals.end(); ++it) { + std::cerr << " "; + std::string str = names[it->first]; + if (str.empty()) { + std::cerr << "(" << it->first << ")"; + } else { + std::cerr << str; + } + std::cerr << " - " << it->second << "s " << std::endl; + } + } + void registerID(int id, const char *name) { + names[id] = name; + } + int registerID(const char *name) { + int id = names.size() + 1; + names[id] = name; + return id; + } + + }; + + Timer timer; + + + TimingBlock::TimingBlock(int id) { +#if CARVE_USE_TIMINGS + timer.startTiming(id); +#endif + } + + TimingBlock::TimingBlock(const TimingName &name) { +#if CARVE_USE_TIMINGS + timer.startTiming(name.id); +#endif + } + + + TimingBlock::~TimingBlock() { +#if CARVE_USE_TIMINGS + timer.endTiming(); +#endif + } + void Timing::start(int id) { +#if CARVE_USE_TIMINGS + timer.startTiming(id); +#endif + } + + double Timing::stop() { +#if CARVE_USE_TIMINGS + return timer.endTiming(); +#endif + } + + void Timing::printTimings() { + timer.print(); + } + + void Timing::registerID(int id, const char *name) { + timer.registerID(id, name); + } + + TimingName::TimingName(const char *name) { + id = timer.registerID(name); + } + +} + +#endif diff -Nru blender-2.61/extern/carve/lib/triangulator.cpp blender-2.62/extern/carve/lib/triangulator.cpp --- blender-2.61/extern/carve/lib/triangulator.cpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/lib/triangulator.cpp 2012-02-15 19:39:32.000000000 +0000 @@ -0,0 +1,1201 @@ +// Begin License: +// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com). +// All rights reserved. +// +// This file is part of the Carve CSG Library (http://carve-csg.com/) +// +// 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.GPL2 included in the packaging of +// this file. +// +// This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE. +// End: + + +#if defined(HAVE_CONFIG_H) +# include +#endif + +#include +#include + +#include +#include + +#include + + +namespace { + // private code related to hole patching. + + class order_h_loops_2d { + order_h_loops_2d &operator=(const order_h_loops_2d &); + + const std::vector > &poly; + int axis; + public: + + order_h_loops_2d(const std::vector > &_poly, int _axis) : + poly(_poly), axis(_axis) { + } + + bool operator()(const std::pair &a, + const std::pair &b) const { + return carve::triangulate::detail::axisOrdering(poly[a.first][a.second], poly[b.first][b.second], axis); + } + }; + + class heap_ordering_2d { + heap_ordering_2d &operator=(const heap_ordering_2d &); + + const std::vector > &poly; + const std::vector > &loop; + const carve::geom2d::P2 p; + int axis; + + public: + + heap_ordering_2d(const std::vector > &_poly, + const std::vector > &_loop, + const carve::geom2d::P2 _p, + int _axis) : poly(_poly), loop(_loop), p(_p), axis(_axis) { + } + + bool operator()(size_t a, size_t b) const { + double da = carve::geom::distance2(p, poly[loop[a].first][loop[a].second]); + double db = carve::geom::distance2(p, poly[loop[b].first][loop[b].second]); + if (da > db) return true; + if (da < db) return false; + return carve::triangulate::detail::axisOrdering(poly[loop[a].first][loop[a].second], poly[loop[b].first][loop[b].second], axis); + } + }; + + static inline void patchHoleIntoPolygon_2d(std::vector > &f_loop, + size_t f_loop_attach, + size_t h_loop, + size_t h_loop_attach, + size_t h_loop_size) { + f_loop.insert(f_loop.begin() + f_loop_attach + 1, h_loop_size + 2, std::make_pair(h_loop, 0)); + size_t f = f_loop_attach + 1; + + for (size_t h = h_loop_attach; h != h_loop_size; ++h) { + f_loop[f++].second = h; + } + + for (size_t h = 0; h <= h_loop_attach; ++h) { + f_loop[f++].second = h; + } + + f_loop[f] = f_loop[f_loop_attach]; + } + + static inline const carve::geom2d::P2 &pvert(const std::vector > &poly, const std::pair &idx) { + return poly[idx.first][idx.second]; + } +} + + +namespace { + // private code related to triangulation. + + using carve::triangulate::detail::vertex_info; + + struct vertex_info_ordering { + bool operator()(const vertex_info *a, const vertex_info *b) const { + return a->score < b->score; + } + }; + + struct vertex_info_l2norm_inc_ordering { + const vertex_info *v; + vertex_info_l2norm_inc_ordering(const vertex_info *_v) : v(_v) { + } + bool operator()(const vertex_info *a, const vertex_info *b) const { + return carve::geom::distance2(v->p, a->p) > carve::geom::distance2(v->p, b->p); + } + }; + + class EarQueue { + std::vector queue; + + void checkheap() { +#ifdef __GNUC__ + CARVE_ASSERT(std::__is_heap(queue.begin(), queue.end(), vertex_info_ordering())); +#endif + } + + public: + EarQueue() { + } + + size_t size() const { + return queue.size(); + } + + void push(vertex_info *v) { +#if defined(CARVE_DEBUG) + checkheap(); +#endif + queue.push_back(v); + std::push_heap(queue.begin(), queue.end(), vertex_info_ordering()); + } + + vertex_info *pop() { +#if defined(CARVE_DEBUG) + checkheap(); +#endif + std::pop_heap(queue.begin(), queue.end(), vertex_info_ordering()); + vertex_info *v = queue.back(); + queue.pop_back(); + return v; + } + + void remove(vertex_info *v) { +#if defined(CARVE_DEBUG) + checkheap(); +#endif + CARVE_ASSERT(std::find(queue.begin(), queue.end(), v) != queue.end()); + double score = v->score; + if (v != queue[0]) { + v->score = queue[0]->score + 1; + std::make_heap(queue.begin(), queue.end(), vertex_info_ordering()); + } + CARVE_ASSERT(v == queue[0]); + std::pop_heap(queue.begin(), queue.end(), vertex_info_ordering()); + CARVE_ASSERT(queue.back() == v); + queue.pop_back(); + v->score = score; + } + + void changeScore(vertex_info *v, double score) { +#if defined(CARVE_DEBUG) + checkheap(); +#endif + CARVE_ASSERT(std::find(queue.begin(), queue.end(), v) != queue.end()); + if (v->score != score) { + v->score = score; + std::make_heap(queue.begin(), queue.end(), vertex_info_ordering()); + } + } + + // 39% of execution time + void updateVertex(vertex_info *v) { + double spre = v->score; + bool qpre = v->isCandidate(); + v->recompute(); + bool qpost = v->isCandidate(); + double spost = v->score; + + v->score = spre; + + if (qpre) { + if (qpost) { + if (v->score != spre) { + changeScore(v, spost); + } + } else { + remove(v); + } + } else { + if (qpost) { + push(v); + } + } + } + }; + + + + int windingNumber(vertex_info *begin, const carve::geom2d::P2 &point) { + int wn = 0; + + vertex_info *v = begin; + do { + if (v->p.y <= point.y) { + if (v->next->p.y > point.y && carve::geom2d::orient2d(v->p, v->next->p, point) > 0.0) { + ++wn; + } + } else { + if (v->next->p.y <= point.y && carve::geom2d::orient2d(v->p, v->next->p, point) < 0.0) { + --wn; + } + } + v = v->next; + } while (v != begin); + + return wn; + } + + + + bool internalToAngle(const vertex_info *a, + const vertex_info *b, + const vertex_info *c, + const carve::geom2d::P2 &p) { + return carve::geom2d::internalToAngle(a->p, b->p, c->p, p); + } + + + + bool findDiagonal(vertex_info *begin, vertex_info *&v1, vertex_info *&v2) { + vertex_info *t; + std::vector heap; + + v1 = begin; + do { + heap.clear(); + + for (v2 = v1->next->next; v2 != v1->prev; v2 = v2->next) { + if (!internalToAngle(v1->next, v1, v1->prev, v2->p) || + !internalToAngle(v2->next, v2, v2->prev, v1->p)) continue; + + heap.push_back(v2); + std::push_heap(heap.begin(), heap.end(), vertex_info_l2norm_inc_ordering(v1)); + } + + while (heap.size()) { + std::pop_heap(heap.begin(), heap.end(), vertex_info_l2norm_inc_ordering(v1)); + v2 = heap.back(); heap.pop_back(); + +#if defined(CARVE_DEBUG) + std::cerr << "testing: " << v1 << " - " << v2 << std::endl; + std::cerr << " length = " << (v2->p - v1->p).length() << std::endl; + std::cerr << " pos: " << v1->p << " - " << v2->p << std::endl; +#endif + // test whether v1-v2 is a valid diagonal. + double v_min_x = std::min(v1->p.x, v2->p.x); + double v_max_x = std::max(v1->p.x, v2->p.x); + + bool intersected = false; + + for (t = v1->next; !intersected && t != v1->prev; t = t->next) { + vertex_info *u = t->next; + if (t == v2 || u == v2) continue; + + double l1 = carve::geom2d::orient2d(v1->p, v2->p, t->p); + double l2 = carve::geom2d::orient2d(v1->p, v2->p, u->p); + + if ((l1 > 0.0 && l2 > 0.0) || (l1 < 0.0 && l2 < 0.0)) { + // both on the same side; no intersection + continue; + } + + double dx13 = v1->p.x - t->p.x; + double dy13 = v1->p.y - t->p.y; + double dx43 = u->p.x - t->p.x; + double dy43 = u->p.y - t->p.y; + double dx21 = v2->p.x - v1->p.x; + double dy21 = v2->p.y - v1->p.y; + double ua_n = dx43 * dy13 - dy43 * dx13; + double ub_n = dx21 * dy13 - dy21 * dx13; + double u_d = dy43 * dx21 - dx43 * dy21; + + if (carve::math::ZERO(u_d)) { + // parallel + if (carve::math::ZERO(ua_n)) { + // colinear + if (std::max(t->p.x, u->p.x) >= v_min_x && std::min(t->p.x, u->p.x) <= v_max_x) { + // colinear and intersecting + intersected = true; + } + } + } else { + // not parallel + double ua = ua_n / u_d; + double ub = ub_n / u_d; + + if (0.0 <= ua && ua <= 1.0 && 0.0 <= ub && ub <= 1.0) { + intersected = true; + } + } +#if defined(CARVE_DEBUG) + if (intersected) { + std::cerr << " failed on edge: " << t << " - " << u << std::endl; + std::cerr << " pos: " << t->p << " - " << u->p << std::endl; + } +#endif + } + + if (!intersected) { + // test whether midpoint winding == 1 + + carve::geom2d::P2 mid = (v1->p + v2->p) / 2; + if (windingNumber(begin, mid) == 1) { + // this diagonal is ok + return true; + } + } + } + + // couldn't find a diagonal from v1 that was ok. + v1 = v1->next; + } while (v1 != begin); + return false; + } + + + +#if defined(CARVE_DEBUG_WRITE_PLY_DATA) + void dumpPoly(const std::vector &points, + const std::vector &result) { + static int step = 0; + std::ostringstream filename; + filename << "poly_" << step++ << ".svg"; + std::cerr << "dumping to " << filename.str() << std::endl; + std::ofstream out(filename.str().c_str()); + + double minx = points[0].x, maxx = points[0].x; + double miny = points[0].y, maxy = points[0].y; + + for (size_t i = 1; i < points.size(); ++i) { + minx = std::min(points[i].x, minx); maxx = std::max(points[i].x, maxx); + miny = std::min(points[i].y, miny); maxy = std::max(points[i].y, maxy); + } + double scale = 100 / std::max(maxx-minx, maxy-miny); + + maxx *= scale; minx *= scale; + maxy *= scale; miny *= scale; + + double width = maxx - minx + 10; + double height = maxy - miny + 10; + + out << "\ +\n\ +\n\ +\n"; + + out << "" << std::endl; + + for (size_t i = 0; i < result.size(); ++i) { + out << "" << std::endl; + } + + out << "" << std::endl; + } +#endif +} + + + +double carve::triangulate::detail::vertex_info::triScore(const vertex_info *p, const vertex_info *v, const vertex_info *n) { + + // different scoring functions. +#if 0 + bool convex = isLeft(p, v, n); + if (!convex) return -1e-5; + + double a1 = carve::geom2d::atan2(p->p - v->p) - carve::geom2d::atan2(n->p - v->p); + double a2 = carve::geom2d::atan2(v->p - n->p) - carve::geom2d::atan2(p->p - n->p); + if (a1 < 0) a1 += M_PI * 2; + if (a2 < 0) a2 += M_PI * 2; + + return std::min(a1, std::min(a2, M_PI - a1 - a2)) / (M_PI / 3); +#endif + +#if 1 + // range: 0 - 1 + double a, b, c; + + bool convex = isLeft(p, v, n); + if (!convex) return -1e-5; + + a = (n->p - v->p).length(); + b = (p->p - n->p).length(); + c = (v->p - p->p).length(); + + if (a < 1e-10 || b < 1e-10 || c < 1e-10) return 0.0; + + return std::max(std::min((a+b)/c, std::min((a+c)/b, (b+c)/a)) - 1.0, 0.0); +#endif +} + + + +double carve::triangulate::detail::vertex_info::calcScore() const { + +#if 0 + // examine only this triangle. + double this_tri = triScore(prev, this, next); + return this_tri; +#endif + +#if 1 + // attempt to look ahead in the neighbourhood to attempt to clip ears that have good neighbours. + double this_tri = triScore(prev, this, next); + double next_tri = triScore(prev, next, next->next); + double prev_tri = triScore(prev->prev, prev, next); + + return this_tri + std::max(next_tri, prev_tri) * .2; +#endif + +#if 0 + // attempt to penalise ears that will require producing a sliver triangle. + double score = triScore(prev, this, next); + + double a1, a2; + a1 = carve::geom2d::atan2(prev->p - next->p); + a2 = carve::geom2d::atan2(next->next->p - next->p); + if (fabs(a1 - a2) < 1e-5) score -= .5; + + a1 = carve::geom2d::atan2(next->p - prev->p); + a2 = carve::geom2d::atan2(prev->prev->p - prev->p); + if (fabs(a1 - a2) < 1e-5) score -= .5; + + return score; +#endif +} + + + +bool carve::triangulate::detail::vertex_info::isClipable() const { + for (const vertex_info *v_test = next->next; v_test != prev; v_test = v_test->next) { + if (v_test->convex) { + continue; + } + + if (v_test->p == prev->p || + v_test->p == next->p) { + continue; + } + + if (v_test->p == p) { + if (v_test->next->p == prev->p && + v_test->prev->p == next->p) { + return false; + } + if (v_test->next->p == prev->p || + v_test->prev->p == next->p) { + continue; + } + } + + if (pointInTriangle(prev, this, next, v_test)) { + return false; + } + } + return true; +} + + + +size_t carve::triangulate::detail::removeDegeneracies(vertex_info *&begin, std::vector &result) { + vertex_info *v; + vertex_info *n; + size_t count = 0; + size_t remain = 0; + + v = begin; + do { + v = v->next; + ++remain; + } while (v != begin); + + v = begin; + do { + if (remain < 4) break; + + bool remove = false; + if (v->p == v->next->p) { + remove = true; + } else if (v->p == v->next->next->p) { + if (v->next->p == v->next->next->next->p) { + // a 'z' in the loop: z (a) b a b c -> remove a-b-a -> z (a) a b c -> remove a-a-b (next loop) -> z a b c + // z --(a)-- b + // / + // / + // a -- b -- d + remove = true; + } else { + // a 'shard' in the loop: z (a) b a c d -> remove a-b-a -> z (a) a b c d -> remove a-a-b (next loop) -> z a b c d + // z --(a)-- b + // / + // / + // a -- c -- d + // n.b. can only do this if the shard is pointing out of the polygon. i.e. b is outside z-a-c + remove = !internalToAngle(v->next->next->next, v, v->prev, v->next->p); + } + } + + if (remove) { + result.push_back(carve::triangulate::tri_idx(v->idx, v->next->idx, v->next->next->idx)); + n = v->next; + if (n == begin) begin = n->next; + n->remove(); + count++; + remain--; + delete n; + } else { + v = v->next; + } + } while (v != begin); + return count; +} + + + +bool carve::triangulate::detail::splitAndResume(vertex_info *begin, std::vector &result) { + vertex_info *v1, *v2; + +#if defined(CARVE_DEBUG_WRITE_PLY_DATA) + { + std::vector dummy; + std::vector dummy_p; + vertex_info *v = begin; + do { + dummy_p.push_back(v->p); + v = v->next; + } while (v != begin); + std::cerr << "input to splitAndResume:" << std::endl; + dumpPoly(dummy_p, dummy); + } +#endif + + + if (!findDiagonal(begin, v1, v2)) return false; + + vertex_info *v1_copy = new vertex_info(*v1); + vertex_info *v2_copy = new vertex_info(*v2); + + v1->next = v2; + v2->prev = v1; + + v1_copy->next->prev = v1_copy; + v2_copy->prev->next = v2_copy; + + v1_copy->prev = v2_copy; + v2_copy->next = v1_copy; + + bool r1 = doTriangulate(v1, result); + bool r2 = doTriangulate(v1_copy, result); + return r1 && r2; +} + + + +bool carve::triangulate::detail::doTriangulate(vertex_info *begin, std::vector &result) { +#if defined(CARVE_DEBUG) + std::cerr << "entering doTriangulate" << std::endl; +#endif + +#if defined(CARVE_DEBUG_WRITE_PLY_DATA) + { + std::vector dummy; + std::vector dummy_p; + vertex_info *v = begin; + do { + dummy_p.push_back(v->p); + v = v->next; + } while (v != begin); + dumpPoly(dummy_p, dummy); + } +#endif + + EarQueue vq; + + vertex_info *v = begin; + size_t remain = 0; + do { + if (v->isCandidate()) vq.push(v); + v = v->next; + remain++; + } while (v != begin); + +#if defined(CARVE_DEBUG) + std::cerr << "remain = " << remain << std::endl; +#endif + + while (remain > 3 && vq.size()) { + vertex_info *v = vq.pop(); + if (!v->isClipable()) { + v->failed = true; + continue; + } + + continue_clipping: + vertex_info *n = v->next; + vertex_info *p = v->prev; + + result.push_back(carve::triangulate::tri_idx(v->prev->idx, v->idx, v->next->idx)); + +#if defined(CARVE_DEBUG) + { + std::vector temp; + temp.push_back(v->prev->p); + temp.push_back(v->p); + temp.push_back(v->next->p); + std::cerr << "clip " << v << " idx = " << v->idx << " score = " << v->score << " area = " << carve::geom2d::signedArea(temp) << " " << temp[0] << " " << temp[1] << " " << temp[2] << std::endl; + } +#endif + + v->remove(); + if (v == begin) begin = v->next; + delete v; + + if (--remain == 3) break; + + vq.updateVertex(n); + vq.updateVertex(p); + + if (n->score < p->score) { std::swap(n, p); } + + if (n->score > 0.25 && n->isCandidate() && n->isClipable()) { + vq.remove(n); + v = n; +#if defined(CARVE_DEBUG) + std::cerr << " continue clipping (n), score = " << n->score << std::endl; +#endif + goto continue_clipping; + } + + if (p->score > 0.25 && p->isCandidate() && p->isClipable()) { + vq.remove(p); + v = p; +#if defined(CARVE_DEBUG) + std::cerr << " continue clipping (p), score = " << n->score << std::endl; +#endif + goto continue_clipping; + } + +#if defined(CARVE_DEBUG) + std::cerr << "looking for new start point" << std::endl; + std::cerr << "remain = " << remain << std::endl; +#endif + } + +#if defined(CARVE_DEBUG) + std::cerr << "doTriangulate complete; remain=" << remain << std::endl; +#endif + + if (remain > 3) { +#if defined(CARVE_DEBUG) + std::cerr << "before removeDegeneracies: remain=" << remain << std::endl; +#endif + remain -= removeDegeneracies(begin, result); +#if defined(CARVE_DEBUG) + std::cerr << "after removeDegeneracies: remain=" << remain << std::endl; +#endif + + if (remain > 3) { + return splitAndResume(begin, result); + } + } + + if (remain == 3) { + result.push_back(carve::triangulate::tri_idx(begin->idx, begin->next->idx, begin->next->next->idx)); + } + + vertex_info *d = begin; + do { + vertex_info *n = d->next; + delete d; + d = n; + } while (d != begin); + + return true; +} + + + +bool testCandidateAttachment(const std::vector > &poly, + std::vector > ¤t_f_loop, + size_t curr, + carve::geom2d::P2 hole_min) { + const size_t SZ = current_f_loop.size(); + + if (!carve::geom2d::internalToAngle(pvert(poly, current_f_loop[(curr+1) % SZ]), + pvert(poly, current_f_loop[curr]), + pvert(poly, current_f_loop[(curr+SZ-1) % SZ]), + hole_min)) { + return false; + } + + if (hole_min == pvert(poly, current_f_loop[curr])) { + return true; + } + + carve::geom2d::LineSegment2 test(hole_min, pvert(poly, current_f_loop[curr])); + + size_t v1 = current_f_loop.size() - 1; + size_t v2 = 0; + double v1_side = carve::geom2d::orient2d(test.v1, test.v2, pvert(poly, current_f_loop[v1])); + double v2_side = 0; + + while (v2 != current_f_loop.size()) { + v2_side = carve::geom2d::orient2d(test.v1, test.v2, pvert(poly, current_f_loop[v2])); + + if (v1_side != v2_side) { + // XXX: need to test vertices, not indices, because they may + // be duplicated. + if (pvert(poly, current_f_loop[v1]) != pvert(poly, current_f_loop[curr]) && + pvert(poly, current_f_loop[v2]) != pvert(poly, current_f_loop[curr])) { + carve::geom2d::LineSegment2 test2(pvert(poly, current_f_loop[v1]), pvert(poly, current_f_loop[v2])); + if (carve::geom2d::lineSegmentIntersection_simple(test, test2)) { + // intersection; failed. + return false; + } + } + } + + v1 = v2; + v1_side = v2_side; + ++v2; + } + return true; +} + + + +void +carve::triangulate::incorporateHolesIntoPolygon( + const std::vector > &poly, + std::vector > &result, + size_t poly_loop, + const std::vector &hole_loops) { + typedef std::vector loop_t; + + size_t N = poly[poly_loop].size(); + + // work out how much space to reserve for the patched in holes. + for (size_t i = 0; i < hole_loops.size(); i++) { + N += 2 + poly[hole_loops[i]].size(); + } + + // this is the vector that we will build the result in. + result.clear(); + result.reserve(N); + + // this is a heap of result indices that defines the vertex test order. + std::vector f_loop_heap; + f_loop_heap.reserve(N); + + // add the poly loop to result. + for (size_t i = 0; i < poly[poly_loop].size(); ++i) { + result.push_back(std::make_pair((size_t)poly_loop, i)); + } + + if (hole_loops.size() == 0) { + return; + } + + std::vector > h_loop_min_vertex; + + h_loop_min_vertex.reserve(hole_loops.size()); + + // find the major axis for the holes - this is the axis that we + // will sort on for finding vertices on the polygon to join + // holes up to. + // + // it might also be nice to also look for whether it is better + // to sort ascending or descending. + // + // another trick that could be used is to modify the projection + // by 90 degree rotations or flipping about an axis. just as + // long as we keep the carve::geom3d::Vector pointers for the + // real data in sync, everything should be ok. then we wouldn't + // need to accomodate axes or sort order in the main loop. + + // find the bounding box of all the holes. + carve::geom2d::P2 h_min, h_max; + h_min = h_max = poly[hole_loops[0]][0]; + for (size_t i = 0; i < hole_loops.size(); ++i) { + const loop_t &hole = poly[hole_loops[i]]; + for (size_t j = 0; j < hole.size(); ++j) { + assign_op(h_min, h_min, hole[j], carve::util::min_functor()); + assign_op(h_max, h_max, hole[j], carve::util::max_functor()); + } + } + // choose the axis for which the bbox is largest. + int axis = (h_max.x - h_min.x) > (h_max.y - h_min.y) ? 0 : 1; + + // for each hole, find the minimum vertex in the chosen axis. + for (size_t i = 0; i < hole_loops.size(); ++i) { + const loop_t &hole = poly[hole_loops[i]]; + size_t best, curr; + best = 0; + for (curr = 1; curr != hole.size(); ++curr) { + if (detail::axisOrdering(hole[curr], hole[best], axis)) { + best = curr; + } + } + h_loop_min_vertex.push_back(std::make_pair(hole_loops[i], best)); + } + + // sort the holes by the minimum vertex. + std::sort(h_loop_min_vertex.begin(), h_loop_min_vertex.end(), order_h_loops_2d(poly, axis)); + + // now, for each hole, find a vertex in the current polygon loop that it can be joined to. + for (unsigned i = 0; i < h_loop_min_vertex.size(); ++i) { + // the index of the vertex in the hole to connect. + size_t hole_i = h_loop_min_vertex[i].first; + size_t hole_i_connect = h_loop_min_vertex[i].second; + + carve::geom2d::P2 hole_min = poly[hole_i][hole_i_connect]; + + f_loop_heap.clear(); + // we order polygon loop vertices that may be able to be connected + // to the hole vertex by their distance to the hole vertex + heap_ordering_2d _heap_ordering(poly, result, hole_min, axis); + + const size_t SZ = result.size(); + for (size_t j = 0; j < SZ; ++j) { + // it is guaranteed that there exists a polygon vertex with + // coord < the min hole coord chosen, which can be joined to + // the min hole coord without crossing the polygon + // boundary. also, because we merge holes in ascending + // order, it is also true that this join can never cross + // another hole (and that doesn't need to be tested for). + if (pvert(poly, result[j]).v[axis] <= hole_min.v[axis]) { + f_loop_heap.push_back(j); + std::push_heap(f_loop_heap.begin(), f_loop_heap.end(), _heap_ordering); + } + } + + // we are going to test each potential (according to the + // previous test) polygon vertex as a candidate join. we order + // by closeness to the hole vertex, so that the join we make + // is as small as possible. to test, we need to check the + // joining line segment does not cross any other line segment + // in the current polygon loop (excluding those that have the + // vertex that we are attempting to join with as an endpoint). + size_t attachment_point = result.size(); + + while (f_loop_heap.size()) { + std::pop_heap(f_loop_heap.begin(), f_loop_heap.end(), _heap_ordering); + size_t curr = f_loop_heap.back(); + f_loop_heap.pop_back(); + // test the candidate join from result[curr] to hole_min + + if (!testCandidateAttachment(poly, result, curr, hole_min)) { + continue; + } + + attachment_point = curr; + break; + } + + if (attachment_point == result.size()) { + CARVE_FAIL("didn't manage to link up hole!"); + } + + patchHoleIntoPolygon_2d(result, attachment_point, hole_i, hole_i_connect, poly[hole_i].size()); + } +} + + + +std::vector > +carve::triangulate::incorporateHolesIntoPolygon(const std::vector > &poly) { +#if 1 + std::vector > result; + std::vector hole_indices; + hole_indices.reserve(poly.size() - 1); + for (size_t i = 1; i < poly.size(); ++i) { + hole_indices.push_back(i); + } + + incorporateHolesIntoPolygon(poly, result, 0, hole_indices); + + return result; + +#else + typedef std::vector loop_t; + size_t N = poly[0].size(); + // + // work out how much space to reserve for the patched in holes. + for (size_t i = 0; i < poly.size(); i++) { + N += 2 + poly[i].size(); + } + + // this is the vector that we will build the result in. + std::vector > current_f_loop; + current_f_loop.reserve(N); + + // this is a heap of current_f_loop indices that defines the vertex test order. + std::vector f_loop_heap; + f_loop_heap.reserve(N); + + // add the poly loop to current_f_loop. + for (size_t i = 0; i < poly[0].size(); ++i) { + current_f_loop.push_back(std::make_pair((size_t)0, i)); + } + + if (poly.size() == 1) { + return current_f_loop; + } + + std::vector > h_loop_min_vertex; + + h_loop_min_vertex.reserve(poly.size() - 1); + + // find the major axis for the holes - this is the axis that we + // will sort on for finding vertices on the polygon to join + // holes up to. + // + // it might also be nice to also look for whether it is better + // to sort ascending or descending. + // + // another trick that could be used is to modify the projection + // by 90 degree rotations or flipping about an axis. just as + // long as we keep the carve::geom3d::Vector pointers for the + // real data in sync, everything should be ok. then we wouldn't + // need to accomodate axes or sort order in the main loop. + + // find the bounding box of all the holes. + double min_x, min_y, max_x, max_y; + min_x = max_x = poly[1][0].x; + min_y = max_y = poly[1][0].y; + for (size_t i = 1; i < poly.size(); ++i) { + const loop_t &hole = poly[i]; + for (size_t j = 0; j < hole.size(); ++j) { + min_x = std::min(min_x, hole[j].x); + min_y = std::min(min_y, hole[j].y); + max_x = std::max(max_x, hole[j].x); + max_y = std::max(max_y, hole[j].y); + } + } + + // choose the axis for which the bbox is largest. + int axis = (max_x - min_x) > (max_y - min_y) ? 0 : 1; + + // for each hole, find the minimum vertex in the chosen axis. + for (size_t i = 1; i < poly.size(); ++i) { + const loop_t &hole = poly[i]; + size_t best, curr; + best = 0; + for (curr = 1; curr != hole.size(); ++curr) { + if (detail::axisOrdering(hole[curr], hole[best], axis)) { + best = curr; + } + } + h_loop_min_vertex.push_back(std::make_pair(i, best)); + } + + // sort the holes by the minimum vertex. + std::sort(h_loop_min_vertex.begin(), h_loop_min_vertex.end(), order_h_loops_2d(poly, axis)); + + // now, for each hole, find a vertex in the current polygon loop that it can be joined to. + for (unsigned i = 0; i < h_loop_min_vertex.size(); ++i) { + // the index of the vertex in the hole to connect. + size_t hole_i = h_loop_min_vertex[i].first; + size_t hole_i_connect = h_loop_min_vertex[i].second; + + carve::geom2d::P2 hole_min = poly[hole_i][hole_i_connect]; + + f_loop_heap.clear(); + // we order polygon loop vertices that may be able to be connected + // to the hole vertex by their distance to the hole vertex + heap_ordering_2d _heap_ordering(poly, current_f_loop, hole_min, axis); + + const size_t SZ = current_f_loop.size(); + for (size_t j = 0; j < SZ; ++j) { + // it is guaranteed that there exists a polygon vertex with + // coord < the min hole coord chosen, which can be joined to + // the min hole coord without crossing the polygon + // boundary. also, because we merge holes in ascending + // order, it is also true that this join can never cross + // another hole (and that doesn't need to be tested for). + if (pvert(poly, current_f_loop[j]).v[axis] <= hole_min.v[axis]) { + f_loop_heap.push_back(j); + std::push_heap(f_loop_heap.begin(), f_loop_heap.end(), _heap_ordering); + } + } + + // we are going to test each potential (according to the + // previous test) polygon vertex as a candidate join. we order + // by closeness to the hole vertex, so that the join we make + // is as small as possible. to test, we need to check the + // joining line segment does not cross any other line segment + // in the current polygon loop (excluding those that have the + // vertex that we are attempting to join with as an endpoint). + size_t attachment_point = current_f_loop.size(); + + while (f_loop_heap.size()) { + std::pop_heap(f_loop_heap.begin(), f_loop_heap.end(), _heap_ordering); + size_t curr = f_loop_heap.back(); + f_loop_heap.pop_back(); + // test the candidate join from current_f_loop[curr] to hole_min + + if (!testCandidateAttachment(poly, current_f_loop, curr, hole_min)) { + continue; + } + + attachment_point = curr; + break; + } + + if (attachment_point == current_f_loop.size()) { + CARVE_FAIL("didn't manage to link up hole!"); + } + + patchHoleIntoPolygon_2d(current_f_loop, attachment_point, hole_i, hole_i_connect, poly[hole_i].size()); + } + + return current_f_loop; +#endif +} + + + +std::vector > > +carve::triangulate::mergePolygonsAndHoles(const std::vector > &poly) { + std::vector poly_indices, hole_indices; + + poly_indices.reserve(poly.size()); + hole_indices.reserve(poly.size()); + + for (size_t i = 0; i < poly.size(); ++i) { + if (carve::geom2d::signedArea(poly[i]) < 0) { + poly_indices.push_back(i); + } else { + hole_indices.push_back(i); + } + } + + std::vector > > result; + result.resize(poly_indices.size()); + + if (hole_indices.size() == 0) { + for (size_t i = 0; i < poly.size(); ++i) { + result[i].resize(poly[i].size()); + for (size_t j = 0; j < poly[i].size(); ++j) { + result[i].push_back(std::make_pair(i, j)); + } + } + return result; + } + + if (poly_indices.size() == 1) { + incorporateHolesIntoPolygon(poly, result[0], poly_indices[0], hole_indices); + + return result; + } + + throw carve::exception("not implemented"); +} + + + +void carve::triangulate::triangulate(const std::vector &poly, + std::vector &result) { + std::vector vinfo; + const size_t N = poly.size(); + +#if defined(CARVE_DEBUG) + std::cerr << "TRIANGULATION BEGINS" << std::endl; +#endif + +#if defined(CARVE_DEBUG_WRITE_PLY_DATA) + dumpPoly(poly, result); +#endif + + result.clear(); + if (N < 3) { + return; + } + + result.reserve(poly.size() - 2); + + if (N == 3) { + result.push_back(tri_idx(0, 1, 2)); + return; + } + + vinfo.resize(N); + + vinfo[0] = new detail::vertex_info(poly[0], 0); + for (size_t i = 1; i < N-1; ++i) { + vinfo[i] = new detail::vertex_info(poly[i], i); + vinfo[i]->prev = vinfo[i-1]; + vinfo[i-1]->next = vinfo[i]; + } + vinfo[N-1] = new detail::vertex_info(poly[N-1], N-1); + vinfo[N-1]->prev = vinfo[N-2]; + vinfo[N-1]->next = vinfo[0]; + vinfo[0]->prev = vinfo[N-1]; + vinfo[N-2]->next = vinfo[N-1]; + + for (size_t i = 0; i < N; ++i) { + vinfo[i]->recompute(); + } + + detail::vertex_info *begin = vinfo[0]; + + removeDegeneracies(begin, result); + doTriangulate(begin, result); + +#if defined(CARVE_DEBUG) + std::cerr << "TRIANGULATION ENDS" << std::endl; +#endif + +#if defined(CARVE_DEBUG_WRITE_PLY_DATA) + dumpPoly(poly, result); +#endif +} + + + +void carve::triangulate::detail::tri_pair_t::flip(vert_edge_t &old_edge, + vert_edge_t &new_edge, + vert_edge_t perim[4]) { + unsigned ai, bi; + unsigned cross_ai, cross_bi; + + findSharedEdge(ai, bi); + old_edge = ordered_vert_edge_t(a->v[ai], b->v[bi]); + + cross_ai = P(ai); + cross_bi = P(bi); + new_edge = ordered_vert_edge_t(a->v[cross_ai], b->v[cross_bi]); + + score = -score; + + a->v[N(ai)] = b->v[cross_bi]; + b->v[N(bi)] = a->v[cross_ai]; + + perim[0] = ordered_vert_edge_t(a->v[P(ai)], a->v[ai]); + perim[1] = ordered_vert_edge_t(a->v[N(ai)], a->v[ai]); // this edge was a b-edge + + perim[2] = ordered_vert_edge_t(b->v[P(bi)], b->v[bi]); + perim[3] = ordered_vert_edge_t(b->v[N(bi)], b->v[bi]); // this edge was an a-edge +} + + + +void carve::triangulate::detail::tri_pairs_t::insert(unsigned a, unsigned b, carve::triangulate::tri_idx *t) { + tri_pair_t *tp; + if (a < b) { + tp = storage[vert_edge_t(a,b)]; + if (!tp) { + tp = storage[vert_edge_t(a,b)] = new tri_pair_t; + } + tp->a = t; + } else { + tp = storage[vert_edge_t(b,a)]; + if (!tp) { + tp = storage[vert_edge_t(b,a)] = new tri_pair_t; + } + tp->b = t; + } +} diff -Nru blender-2.61/extern/carve/LICENSE.GPL2 blender-2.62/extern/carve/LICENSE.GPL2 --- blender-2.61/extern/carve/LICENSE.GPL2 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/LICENSE.GPL2 2012-02-15 19:39:33.000000000 +0000 @@ -0,0 +1,361 @@ + GNU GENERAL PUBLIC LICENSE + + The Qt GUI Toolkit is Copyright (C) 1994-2008 Trolltech ASA. + + You may use, distribute and copy the Qt GUI Toolkit under the terms of + GNU General Public License version 2, which is displayed below. + +------------------------------------------------------------------------- + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 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. + + 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 St, Fifth Floor, Boston, MA 02110-1301 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. + +------------------------------------------------------------------------- + +In addition, as a special exception, Trolltech gives permission to link the +code of its release of Qt with the OpenSSL project's "OpenSSL" library (or +modified versions of it that use the same license as the "OpenSSL" +library), and distribute the linked executables. You must comply with the GNU +General Public License version 2 or the GNU General Public License version 3 +in all respects for all of the code used other than the "OpenSSL" code. If +you modify this file, you may extend this exception to your version of the +file, but you are not obligated to do so. If you do not wish to do so, +delete this exception statement from your version of this file. diff -Nru blender-2.61/extern/carve/mkfiles.sh blender-2.62/extern/carve/mkfiles.sh --- blender-2.61/extern/carve/mkfiles.sh 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/mkfiles.sh 2012-02-15 19:39:33.000000000 +0000 @@ -0,0 +1,4 @@ +#!/bin/sh + +find ./include/ -type f | sed -r 's/^\.\///' > files.txt +find ./lib/ -type f | sed -r 's/^\.\///' >> files.txt diff -Nru blender-2.61/extern/carve/patches/files/config.h blender-2.62/extern/carve/patches/files/config.h --- blender-2.61/extern/carve/patches/files/config.h 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/patches/files/config.h 2012-02-15 19:39:33.000000000 +0000 @@ -0,0 +1,12 @@ +#define CARVE_VERSION "2.0.0a" + +#undef CARVE_DEBUG +#undef CARVE_DEBUG_WRITE_PLY_DATA + +#if defined(__GNUC__) +# if !defined(HAVE_BOOST_UNORDERED_COLLECTIONS) +# define HAVE_TR1_UNORDERED_COLLECTIONS +# endif + +# define HAVE_STDINT_H +#endif diff -Nru blender-2.61/extern/carve/patches/files/random.hpp blender-2.62/extern/carve/patches/files/random.hpp --- blender-2.61/extern/carve/patches/files/random.hpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/patches/files/random.hpp 2012-02-15 19:39:33.000000000 +0000 @@ -0,0 +1,773 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +#if !defined(_MSC_VER) +#include +#endif + +namespace boost { + +// type_traits could help here, but I don't want to depend on type_traits. +template +struct ptr_helper +{ + typedef T value_type; + typedef T& reference_type; + typedef const T& rvalue_type; + static reference_type ref(T& r) { return r; } + static const T& ref(const T& r) { return r; } +}; + +template +struct ptr_helper +{ + typedef T value_type; + typedef T& reference_type; + typedef T& rvalue_type; + static reference_type ref(T& r) { return r; } + static const T& ref(const T& r) { return r; } +}; + +template +struct ptr_helper +{ + typedef T value_type; + typedef T& reference_type; + typedef T* rvalue_type; + static reference_type ref(T * p) { return *p; } + static const T& ref(const T * p) { return *p; } +}; + +template +class pass_through_engine +{ +private: + typedef ptr_helper helper_type; + +public: + typedef typename helper_type::value_type base_type; + typedef typename base_type::result_type result_type; + + explicit pass_through_engine(UniformRandomNumberGenerator rng) + // make argument an rvalue to avoid matching Generator& constructor + : _rng(static_cast(rng)) + { } + + result_type min () const { return (base().min)(); } + result_type max () const { return (base().max)(); } + base_type& base() { return helper_type::ref(_rng); } + const base_type& base() const { return helper_type::ref(_rng); } + + result_type operator()() { return base()(); } + +private: + UniformRandomNumberGenerator _rng; +}; + +template +class new_uniform_01 +{ +public: + typedef RealType input_type; + typedef RealType result_type; + // compiler-generated copy ctor and copy assignment are fine + result_type min () const { return result_type(0); } + result_type max () const { return result_type(1); } + void reset() { } + + template + result_type operator()(Engine& eng) { + for (;;) { + typedef typename Engine::result_type base_result; + result_type factor = result_type(1) / + (result_type((eng.max)()-(eng.min)()) + + result_type(std::numeric_limits::is_integer ? 1 : 0)); + result_type result = result_type(eng() - (eng.min)()) * factor; + if (result < result_type(1)) + return result; + } + } + + template + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const new_uniform_01&) + { + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& is, new_uniform_01&) + { + return is; + } +}; + +template +class backward_compatible_uniform_01 +{ + typedef ptr_helper traits; + typedef pass_through_engine internal_engine_type; +public: + typedef UniformRandomNumberGenerator base_type; + typedef RealType result_type; + + static const bool has_fixed_range = false; + + explicit backward_compatible_uniform_01(typename traits::rvalue_type rng) + : _rng(rng), + _factor(result_type(1) / + (result_type((_rng.max)()-(_rng.min)()) + + result_type(std::numeric_limits::is_integer ? 1 : 0))) + { + } + // compiler-generated copy ctor and copy assignment are fine + + result_type min () const { return result_type(0); } + result_type max () const { return result_type(1); } + typename traits::value_type& base() { return _rng.base(); } + const typename traits::value_type& base() const { return _rng.base(); } + void reset() { } + + result_type operator()() { + for (;;) { + result_type result = result_type(_rng() - (_rng.min)()) * _factor; + if (result < result_type(1)) + return result; + } + } + + template + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const backward_compatible_uniform_01& u) + { + os << u._rng; + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& is, backward_compatible_uniform_01& u) + { + is >> u._rng; + return is; + } + +private: + typedef typename internal_engine_type::result_type base_result; + internal_engine_type _rng; + result_type _factor; +}; + +// A definition is required even for integral static constants +template +const bool backward_compatible_uniform_01::has_fixed_range; + +template +struct select_uniform_01 +{ + template + struct apply + { + typedef backward_compatible_uniform_01 type; + }; +}; + +template<> +struct select_uniform_01 +{ + template + struct apply + { + typedef new_uniform_01 type; + }; +}; + +template<> +struct select_uniform_01 +{ + template + struct apply + { + typedef new_uniform_01 type; + }; +}; + +template<> +struct select_uniform_01 +{ + template + struct apply + { + typedef new_uniform_01 type; + }; +}; + +// Because it is so commonly used: uniform distribution on the real [0..1) +// range. This allows for specializations to avoid a costly int -> float +// conversion plus float multiplication +template +class uniform_01 + : public select_uniform_01::template apply::type +{ + typedef typename select_uniform_01::template apply::type impl_type; + typedef ptr_helper traits; +public: + + uniform_01() {} + + explicit uniform_01(typename traits::rvalue_type rng) + : impl_type(rng) + { + } + + template + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const uniform_01& u) + { + os << static_cast(u); + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& is, uniform_01& u) + { + is >> static_cast(u); + return is; + } +}; + +template +class uniform_int_float +{ +public: + typedef UniformRandomNumberGenerator base_type; + typedef IntType result_type; + + uniform_int_float(base_type rng, IntType min_arg = 0, IntType max_arg = 0xffffffff) + : _rng(rng), _min(min_arg), _max(max_arg) + { + init(); + } + + result_type min () const { return _min; } + result_type max () const { return _max; } + base_type& base() { return _rng.base(); } + const base_type& base() const { return _rng.base(); } + + result_type operator()() + { + return static_cast(_rng() * _range) + _min; + } + + template + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const uniform_int_float& ud) + { + os << ud._min << " " << ud._max; + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& is, uniform_int_float& ud) + { + is >> std::ws >> ud._min >> std::ws >> ud._max; + ud.init(); + return is; + } + +private: + void init() + { + _range = static_cast(_max-_min)+1; + } + + typedef typename base_type::result_type base_result; + uniform_01 _rng; + result_type _min, _max; + base_result _range; +}; + + +template +std::basic_ostream& +operator<<( + std::basic_ostream& os + , const pass_through_engine& ud + ) +{ + return os << ud.base(); +} + +template +std::basic_istream& +operator>>( + std::basic_istream& is + , const pass_through_engine& ud + ) +{ + return is >> ud.base(); +} + + + +template +class normal_distribution +{ +public: + typedef RealType input_type; + typedef RealType result_type; + + explicit normal_distribution(const result_type& mean_arg = result_type(0), + const result_type& sigma_arg = result_type(1)) + : _mean(mean_arg), _sigma(sigma_arg), _valid(false) + { + //assert(_sigma >= result_type(0)); + } + + // compiler-generated copy constructor is NOT fine, need to purge cache + normal_distribution(const normal_distribution& other) + : _mean(other._mean), _sigma(other._sigma), _valid(false) + { + } + + // compiler-generated copy ctor and assignment operator are fine + + RealType mean() const { return _mean; } + RealType sigma() const { return _sigma; } + + void reset() { _valid = false; } + + template + result_type operator()(Engine& eng) + { +#ifndef BOOST_NO_STDC_NAMESPACE + // allow for Koenig lookup + using std::sqrt; using std::log; using std::sin; using std::cos; +#endif + if(!_valid) { + _r1 = eng(); + _r2 = eng(); + _cached_rho = sqrt(-result_type(2) * log(result_type(1)-_r2)); + _valid = true; + } else { + _valid = false; + } + // Can we have a boost::mathconst please? + const result_type pi = result_type(3.14159265358979323846); + + return _cached_rho * (_valid ? + cos(result_type(2)*pi*_r1) : + sin(result_type(2)*pi*_r1)) + * _sigma + _mean; + } + +#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS + template + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const normal_distribution& nd) + { + os << nd._mean << " " << nd._sigma << " " + << nd._valid << " " << nd._cached_rho << " " << nd._r1; + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& is, normal_distribution& nd) + { + is >> std::ws >> nd._mean >> std::ws >> nd._sigma + >> std::ws >> nd._valid >> std::ws >> nd._cached_rho + >> std::ws >> nd._r1; + return is; + } +#endif +private: + result_type _mean, _sigma; + result_type _r1, _r2, _cached_rho; + bool _valid; +}; + +// http://www.math.keio.ac.jp/matumoto/emt.html +template +class mersenne_twister +{ +public: + typedef UIntType result_type; + static const int word_size = w; + static const int state_size = n; + static const int shift_size = m; + static const int mask_bits = r; + static const UIntType parameter_a = a; + static const int output_u = u; + static const int output_s = s; + static const UIntType output_b = b; + static const int output_t = t; + static const UIntType output_c = c; + static const int output_l = l; + + static const bool has_fixed_range = false; + + mersenne_twister() { seed(); } + + explicit mersenne_twister(const UIntType& value) + { seed(value); } + template mersenne_twister(It& first, It last) { seed(first,last); } + + template \ + explicit mersenne_twister(Generator& gen) + { seed(gen); } + + // compiler-generated copy ctor and assignment operator are fine + + void seed() { seed(UIntType(5489)); } + + void seed(const UIntType& value) + { + // New seeding algorithm from + // http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html + // In the previous versions, MSBs of the seed affected only MSBs of the + // state x[]. + const UIntType mask = ~0u; + x[0] = value & mask; + for (i = 1; i < n; i++) { + // See Knuth "The Art of Computer Programming" Vol. 2, 3rd ed., page 106 + x[i] = (1812433253UL * (x[i-1] ^ (x[i-1] >> (w-2))) + i) & mask; + } + } + + // For GCC, moving this function out-of-line prevents inlining, which may + // reduce overall object code size. However, MSVC does not grok + // out-of-line definitions of member function templates. + template \ + void seed(Generator& gen) + { +/*#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + BOOST_STATIC_ASSERT(!std::numeric_limits::is_signed); +#endif*/ + // I could have used std::generate_n, but it takes "gen" by value + for(int j = 0; j < n; j++) + x[j] = gen(); + i = n; + } + + template + void seed(It& first, It last) + { + int j; + for(j = 0; j < n && first != last; ++j, ++first) + x[j] = *first; + i = n; + if(first == last && j < n) + throw std::invalid_argument("mersenne_twister::seed"); + } + + result_type min () const { return 0; } + result_type max () const + { + // avoid "left shift count >= with of type" warning + result_type res = 0; + for(int j = 0; j < w; ++j) + res |= (1u << j); + return res; + } + + result_type operator()(); + static bool validation(result_type v) { return val == v; } + + template + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const mersenne_twister& mt) + { + for(int j = 0; j < mt.state_size; ++j) + os << mt.compute(j) << " "; + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& is, mersenne_twister& mt) + { + for(int j = 0; j < mt.state_size; ++j) + is >> mt.x[j] >> std::ws; + // MSVC (up to 7.1) and Borland (up to 5.64) don't handle the template + // value parameter "n" available from the class template scope, so use + // the static constant with the same value + mt.i = mt.state_size; + return is; + } + + friend bool operator==(const mersenne_twister& x, const mersenne_twister& y) + { + for(int j = 0; j < state_size; ++j) + if(x.compute(j) != y.compute(j)) + return false; + return true; + } + + friend bool operator!=(const mersenne_twister& x, const mersenne_twister& y) + { return !(x == y); } + +private: + // returns x(i-n+index), where index is in 0..n-1 + UIntType compute(unsigned int index) const + { + // equivalent to (i-n+index) % 2n, but doesn't produce negative numbers + return x[ (i + n + index) % (2*n) ]; + } + void twist(int block); + + // state representation: next output is o(x(i)) + // x[0] ... x[k] x[k+1] ... x[n-1] x[n] ... x[2*n-1] represents + // x(i-k) ... x(i) x(i+1) ... x(i-k+n-1) x(i-k-n) ... x[i(i-k-1)] + // The goal is to always have x(i-n) ... x(i-1) available for + // operator== and save/restore. + + UIntType x[2*n]; + int i; +}; + +// A definition is required even for integral static constants + +template +const bool mersenne_twister::has_fixed_range; +template +const int mersenne_twister::state_size; +template +const int mersenne_twister::shift_size; +template +const int mersenne_twister::mask_bits; +template +const UIntType mersenne_twister::parameter_a; +template +const int mersenne_twister::output_u; +template +const int mersenne_twister::output_s; +template +const UIntType mersenne_twister::output_b; +template +const int mersenne_twister::output_t; +template +const UIntType mersenne_twister::output_c; +template +const int mersenne_twister::output_l; + +template +void mersenne_twister::twist(int block) +{ + const UIntType upper_mask = (~0u) << r; + const UIntType lower_mask = ~upper_mask; + + if(block == 0) { + for(int j = n; j < 2*n; j++) { + UIntType y = (x[j-n] & upper_mask) | (x[j-(n-1)] & lower_mask); + x[j] = x[j-(n-m)] ^ (y >> 1) ^ (y&1 ? a : 0); + } + } else if (block == 1) { + // split loop to avoid costly modulo operations + { // extra scope for MSVC brokenness w.r.t. for scope + for(int j = 0; j < n-m; j++) { + UIntType y = (x[j+n] & upper_mask) | (x[j+n+1] & lower_mask); + x[j] = x[j+n+m] ^ (y >> 1) ^ (y&1 ? a : 0); + } + } + + for(int j = n-m; j < n-1; j++) { + UIntType y = (x[j+n] & upper_mask) | (x[j+n+1] & lower_mask); + x[j] = x[j-(n-m)] ^ (y >> 1) ^ (y&1 ? a : 0); + } + // last iteration + UIntType y = (x[2*n-1] & upper_mask) | (x[0] & lower_mask); + x[n-1] = x[m-1] ^ (y >> 1) ^ (y&1 ? a : 0); + i = 0; + } +} + +template +inline typename mersenne_twister::result_type +mersenne_twister::operator()() +{ + if(i == n) + twist(0); + else if(i >= 2*n) + twist(1); + // Step 4 + UIntType z = x[i]; + ++i; + z ^= (z >> u); + z ^= ((z << s) & b); + z ^= ((z << t) & c); + z ^= (z >> l); + return z; +} + +typedef mersenne_twister mt11213b; + +// validation by experiment from mt19937.c +typedef mersenne_twister mt19937; + + +template > +class uniform_on_sphere +{ +public: + typedef RealType input_type; + typedef Cont result_type; + + explicit uniform_on_sphere(int dim = 2) : _container(dim), _dim(dim) { } + + // compiler-generated copy ctor and assignment operator are fine + + void reset() { _normal.reset(); } + + template + const result_type & operator()(Engine& eng) + { + RealType sqsum = 0; + for(typename Cont::iterator it = _container.begin(); + it != _container.end(); + ++it) { + RealType val = _normal(eng); + *it = val; + sqsum += val * val; + } + using std::sqrt; + // for all i: result[i] /= sqrt(sqsum) + std::transform(_container.begin(), _container.end(), _container.begin(), + std::bind2nd(std::divides(), sqrt(sqsum))); + return _container; + } + + template + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const uniform_on_sphere& sd) + { + os << sd._dim; + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& is, uniform_on_sphere& sd) + { + is >> std::ws >> sd._dim; + sd._container.resize(sd._dim); + return is; + } + +private: + normal_distribution _normal; + result_type _container; + int _dim; +}; + + + +template +struct engine_helper; + + +template<> +struct engine_helper +{ + template + struct impl + { + typedef pass_through_engine type; + }; +}; + +template<> +struct engine_helper +{ + template + struct impl + { + typedef uniform_01 type; + }; +}; + +template<> +struct engine_helper +{ + template + struct impl + { + typedef uniform_01 type; + }; +}; + +template<> +struct engine_helper +{ + template + struct impl + { + typedef uniform_int_float type; + }; +}; + +template +class variate_generator +{ +private: + typedef pass_through_engine decorated_engine; + +public: + typedef typename decorated_engine::base_type engine_value_type; + typedef Engine engine_type; + typedef Distribution distribution_type; + typedef typename Distribution::result_type result_type; + + variate_generator(Engine e, Distribution d) + : _eng(decorated_engine(e)), _dist(d) { } + + result_type operator()() { return _dist(_eng); } + template + result_type operator()(T value) { return _dist(_eng, value); } + + engine_value_type& engine() { return _eng.base().base(); } + const engine_value_type& engine() const { return _eng.base().base(); } + + distribution_type& distribution() { return _dist; } + const distribution_type& distribution() const { return _dist; } + + result_type min () const { return (distribution().min)(); } + result_type max () const { return (distribution().max)(); } + +private: + enum { + have_int = std::numeric_limits::is_integer, + want_int = std::numeric_limits::is_integer + }; + typedef typename engine_helper::template impl::type internal_engine_type; + + internal_engine_type _eng; + distribution_type _dist; +}; + +} // namespace boost diff -Nru blender-2.61/extern/carve/patches/gcc46.patch blender-2.62/extern/carve/patches/gcc46.patch --- blender-2.61/extern/carve/patches/gcc46.patch 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/patches/gcc46.patch 2012-02-15 19:39:33.000000000 +0000 @@ -0,0 +1,11 @@ +diff -r 525472fb477a include/carve/polyline_iter.hpp +--- a/include/carve/polyline_iter.hpp Sun Jan 15 23:07:40 2012 -0500 ++++ b/include/carve/polyline_iter.hpp Wed Jan 18 00:41:13 2012 +0600 +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + + #include + diff -Nru blender-2.61/extern/carve/patches/includes.patch blender-2.62/extern/carve/patches/includes.patch --- blender-2.61/extern/carve/patches/includes.patch 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/patches/includes.patch 2012-02-15 19:39:33.000000000 +0000 @@ -0,0 +1,84 @@ +diff -r c8cbec41cd35 include/carve/exact.hpp +--- a/include/carve/exact.hpp Thu Dec 01 15:51:44 2011 -0500 ++++ b/include/carve/exact.hpp Wed Jan 11 18:48:16 2012 +0600 +@@ -21,7 +21,7 @@ + + #include + #include +- ++#include + + + namespace carve { +diff -r c8cbec41cd35 include/carve/geom2d.hpp +--- a/include/carve/geom2d.hpp Thu Dec 01 15:51:44 2011 -0500 ++++ b/include/carve/geom2d.hpp Wed Jan 11 18:48:16 2012 +0600 +@@ -25,6 +25,7 @@ + #include + + #include ++#include + + #include + +diff -r c8cbec41cd35 include/carve/mesh_impl.hpp +--- a/include/carve/mesh_impl.hpp Thu Dec 01 15:51:44 2011 -0500 ++++ b/include/carve/mesh_impl.hpp Wed Jan 11 18:48:16 2012 +0600 +@@ -24,6 +24,8 @@ + #include + #include + ++#include ++ + namespace carve { + namespace mesh { + +diff -r c8cbec41cd35 include/carve/polyhedron_base.hpp +--- a/include/carve/polyhedron_base.hpp Thu Dec 01 15:51:44 2011 -0500 ++++ b/include/carve/polyhedron_base.hpp Wed Jan 11 18:48:16 2012 +0600 +@@ -25,6 +25,8 @@ + #include + #include + ++#include ++ + namespace carve { + namespace poly { + +diff -r c8cbec41cd35 include/carve/rtree.hpp +--- a/include/carve/rtree.hpp Thu Dec 01 15:51:44 2011 -0500 ++++ b/include/carve/rtree.hpp Wed Jan 11 18:48:16 2012 +0600 +@@ -27,6 +27,10 @@ + #include + #include + ++#if defined(HAVE_STDINT_H) ++# include ++#endif ++ + namespace carve { + namespace geom { + +diff -r c8cbec41cd35 include/carve/vector.hpp +--- a/include/carve/vector.hpp Thu Dec 01 15:51:44 2011 -0500 ++++ b/include/carve/vector.hpp Wed Jan 11 18:48:16 2012 +0600 +@@ -24,6 +24,7 @@ + #include + + #include ++#include + + #include + +diff -r c8cbec41cd35 src/extrude.cpp +--- a/src/extrude.cpp Thu Dec 01 15:51:44 2011 -0500 ++++ b/src/extrude.cpp Wed Jan 11 18:48:16 2012 +0600 +@@ -34,6 +34,8 @@ + #include + #include + ++#include ++ + template + carve::geom::vector lerp( + double t, diff -Nru blender-2.61/extern/carve/patches/mesh_iterator.patch blender-2.62/extern/carve/patches/mesh_iterator.patch --- blender-2.61/extern/carve/patches/mesh_iterator.patch 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/patches/mesh_iterator.patch 2012-02-15 19:39:33.000000000 +0000 @@ -0,0 +1,21 @@ +diff -r c8cbec41cd35 include/carve/mesh.hpp +--- a/include/carve/mesh.hpp Thu Dec 01 15:51:44 2011 -0500 ++++ b/include/carve/mesh.hpp Thu Jan 12 00:19:58 2012 +0600 +@@ -719,13 +719,13 @@ + void rev(size_t n); + void adv(int n); + +- FaceIter operator++(int) { FaceIter tmp = *this; fwd(1); return tmp; } +- FaceIter operator+(int v) { FaceIter tmp = *this; adv(v); return tmp; } ++ FaceIter operator++(int) { FaceIter tmp = *this; tmp.fwd(1); return tmp; } ++ FaceIter operator+(int v) { FaceIter tmp = *this; tmp.adv(v); return tmp; } + FaceIter &operator++() { fwd(1); return *this; } + FaceIter &operator+=(int v) { adv(v); return *this; } + +- FaceIter operator--(int) { FaceIter tmp = *this; rev(1); return tmp; } +- FaceIter operator-(int v) { FaceIter tmp = *this; adv(-v); return tmp; } ++ FaceIter operator--(int) { FaceIter tmp = *this; tmp.rev(1); return tmp; } ++ FaceIter operator-(int v) { FaceIter tmp = *this; tmp.adv(-v); return tmp; } + FaceIter &operator--() { rev(1); return *this; } + FaceIter &operator-=(int v) { adv(-v); return *this; } + diff -Nru blender-2.61/extern/carve/patches/mingw.patch blender-2.62/extern/carve/patches/mingw.patch --- blender-2.61/extern/carve/patches/mingw.patch 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/patches/mingw.patch 2012-02-15 19:39:33.000000000 +0000 @@ -0,0 +1,15 @@ +diff -r 525472fb477a include/carve/win32.h +--- a/include/carve/win32.h Sun Jan 15 23:07:40 2012 -0500 ++++ b/include/carve/win32.h Wed Jan 18 00:40:10 2012 +0600 +@@ -8,9 +8,11 @@ + #include + #include + ++#if !defined(__MINGW32__) + inline int strcasecmp(const char *a, const char *b) { + return _stricmp(a,b); + } ++#endif + + inline void srandom(unsigned long input) { + srand(input); diff -Nru blender-2.61/extern/carve/patches/series blender-2.62/extern/carve/patches/series --- blender-2.61/extern/carve/patches/series 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/patches/series 2012-02-15 19:39:33.000000000 +0000 @@ -0,0 +1,6 @@ +strict_flags.patch +includes.patch +win32.patch +mesh_iterator.patch +mingw.patch +gcc46.patch diff -Nru blender-2.61/extern/carve/patches/strict_flags.patch blender-2.62/extern/carve/patches/strict_flags.patch --- blender-2.61/extern/carve/patches/strict_flags.patch 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/patches/strict_flags.patch 2012-02-15 19:39:33.000000000 +0000 @@ -0,0 +1,46 @@ +diff -r 47dfdaff1dd5 include/carve/csg_triangulator.hpp +--- a/include/carve/csg_triangulator.hpp Thu Jan 12 15:49:04 2012 -0500 ++++ b/include/carve/csg_triangulator.hpp Fri Jan 13 03:13:32 2012 +0600 +@@ -174,6 +174,7 @@ + + double scoreQuad(edge_map_t::iterator i, edge_map_t &edge_map) { + if (!(*i).second.first || !(*i).second.second) return -1; ++ return 0; + } + + carve::mesh::MeshSet<3>::face_t *mergeQuad(edge_map_t::iterator i, edge_map_t &edge_map) { +diff -r 47dfdaff1dd5 include/carve/exact.hpp +--- a/include/carve/exact.hpp Thu Jan 12 15:49:04 2012 -0500 ++++ b/include/carve/exact.hpp Fri Jan 13 03:13:32 2012 +0600 +@@ -379,7 +379,7 @@ + prod_2_1(b, a, r); + } + +- static inline double prod_4_1(const double *a, const double *b, double *r) { ++ static inline void prod_4_1(const double *a, const double *b, double *r) { + double b_sp[2]; split(b[0], b_sp); + double t1[2]; prod_1_1s(a+0, b, b_sp, t1); + r[0] = t1[0]; +@@ -639,8 +639,9 @@ + } + + +- exact_t operator+(const exact_t &a, const exact_t &b) { +- } ++ // XXX: not implemented yet ++ //exact_t operator+(const exact_t &a, const exact_t &b) { ++ //} + + + +diff -r 47dfdaff1dd5 src/selfintersect.cpp +--- a/src/selfintersect.cpp Thu Jan 12 15:49:04 2012 -0500 ++++ b/src/selfintersect.cpp Fri Jan 13 03:13:32 2012 +0600 +@@ -465,6 +465,7 @@ + + // returns true if no intersection, based upon edge^a_i and edge^b_j separating axis. + bool sat_edge(const vec3 tri_a[3], const vec3 tri_b[3], unsigned i, unsigned j) { ++ return false; + } + + diff -Nru blender-2.61/extern/carve/patches/win32.patch blender-2.62/extern/carve/patches/win32.patch --- blender-2.61/extern/carve/patches/win32.patch 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/patches/win32.patch 2012-02-15 19:39:33.000000000 +0000 @@ -0,0 +1,29 @@ +diff -r 47dfdaff1dd5 include/carve/win32.h +--- a/include/carve/win32.h Thu Jan 12 15:49:04 2012 -0500 ++++ b/include/carve/win32.h Fri Jan 13 03:15:51 2012 +0600 +@@ -32,14 +32,19 @@ + + # if _MSC_VER < 1600 + // stdint.h is not available before VS2010 +-typedef char int8_t; +-typedef short int16_t; +-typedef long int32_t; ++#if defined(_WIN32) && !defined(__MINGW32__) ++/* The __intXX are built-in types of the visual complier! So we don't ++ need to include anything else here. ++ This typedefs should be in sync with types from MEM_sys_types.h */ + +-typedef unsigned char uint8_t; +-typedef unsigned short uint16_t; +-typedef unsigned long uint32_t; ++typedef signed __int8 int8_t; ++typedef signed __int16 int16_t; ++typedef signed __int32 int32_t; + ++typedef unsigned __int8 uint8_t; ++typedef unsigned __int16 uint16_t; ++typedef unsigned __int32 uint32_t; ++#endif + typedef __int64 int64_t; + typedef unsigned __int64 uint64_t; + # else diff -Nru blender-2.61/extern/carve/SConscript blender-2.62/extern/carve/SConscript --- blender-2.61/extern/carve/SConscript 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/extern/carve/SConscript 2012-02-15 19:39:33.000000000 +0000 @@ -0,0 +1,23 @@ +#!/usr/bin/python + +# NOTE: This file is automatically generated by bundle.sh script +# If you're doing changes in this file, please update template +# in that script too + +Import ('env') + +sources = env.Glob('lib/*.cpp') + +defs = [] +incs = ['include'] + +if env['WITH_BF_BOOST']: + if env['OURPLATFORM'] not in ('win32-vc', 'win64-vc'): + # Boost is setting as preferred collections library in the Carve code when using MSVC compiler + if env['OURPLATFORM'] != 'win32-mingw': + defs.append('HAVE_BOOST_UNORDERED_COLLECTIONS') + + defs.append('CARVE_SYSTEM_BOOST') + incs.append(env['BF_BOOST_INC']) + +env.BlenderLib ('extern_carve', Split(sources), incs, defs, libtype=['extern'], priority=[40] ) diff -Nru blender-2.61/extern/CMakeLists.txt blender-2.62/extern/CMakeLists.txt --- blender-2.61/extern/CMakeLists.txt 2011-12-13 19:57:20.000000000 +0000 +++ blender-2.62/extern/CMakeLists.txt 2012-02-15 19:42:02.000000000 +0000 @@ -12,7 +12,7 @@ # # 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # The Original Code is Copyright (C) 2006, Blender Foundation # All rights reserved. @@ -45,7 +45,7 @@ endif() if(WITH_GAMEENGINE) - add_subdirectory(recastnavigation) + add_subdirectory(recastnavigation) endif() if(WITH_IMAGE_OPENJPEG AND (NOT UNIX OR APPLE)) @@ -67,3 +67,7 @@ if(WITH_LIBMV) add_subdirectory(libmv) endif() + +if(WITH_CARVE) + add_subdirectory(carve) +endif() diff -Nru blender-2.61/extern/colamd/CMakeLists.txt blender-2.62/extern/colamd/CMakeLists.txt --- blender-2.61/extern/colamd/CMakeLists.txt 2011-12-13 19:55:00.000000000 +0000 +++ blender-2.62/extern/colamd/CMakeLists.txt 2012-02-15 19:39:22.000000000 +0000 @@ -12,7 +12,7 @@ # # 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # The Original Code is Copyright (C) 2011, Blender Foundation # All rights reserved. diff -Nru blender-2.61/extern/eltopo/CMakeLists.txt blender-2.62/extern/eltopo/CMakeLists.txt --- blender-2.61/extern/eltopo/CMakeLists.txt 2011-12-13 19:55:20.000000000 +0000 +++ blender-2.62/extern/eltopo/CMakeLists.txt 2012-02-15 19:39:52.000000000 +0000 @@ -12,7 +12,7 @@ # # 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # The Original Code is Copyright (C) 2006, Blender Foundation # All rights reserved. @@ -45,7 +45,6 @@ common/cubic_ccd_wrapper.cpp common/fe_ccd_wrapper.cpp common/fileio.cpp - common/gluvi.cpp common/levelset.cpp common/makelevelset2.cpp common/makelevelset3.cpp @@ -82,7 +81,6 @@ common/clamped_spline.h common/collisionqueries.h common/fileio.h - common/gluvi.h common/grid3.h common/hashtable.h common/lapack_wrapper.h @@ -122,7 +120,7 @@ common/tunicate/tunicate.h ) -add_definitions(-DNOGUI) +add_definitions(-DNO_GUI) add_definitions(-DUSE_FORTRAN_BLAS) blender_add_lib(extern_eltopo "${SRC}" "${INC}" "${INC_SYS}") diff -Nru blender-2.61/extern/eltopo/common/gluvi.h blender-2.62/extern/eltopo/common/gluvi.h --- blender-2.61/extern/eltopo/common/gluvi.h 2011-12-13 19:55:14.000000000 +0000 +++ blender-2.62/extern/eltopo/common/gluvi.h 2012-02-15 19:39:49.000000000 +0000 @@ -4,11 +4,13 @@ //#include //#include +#ifdef USE_GUI #ifdef __APPLE__ #include // why does Apple have to put glut.h here... #else #include // ...when everyone else puts it here? #endif +#endif //#include "vec.h" @@ -187,8 +189,10 @@ void ppm_screenshot(const char *filename_format, ...); void sgi_screenshot(const char *filename_format, ...); void set_generic_lights(void); +#ifdef USE_GUI void set_generic_material(float r, float g, float b, GLenum face=GL_FRONT_AND_BACK); void set_matte_material(float r, float g, float b, GLenum face=GL_FRONT_AND_BACK); +#endif //@@@@@@@ USEFUL FUNCTIONALITY: void draw_3d_arrow(const float base[3], const float point[3], float arrow_head_length=0); //void draw_2d_arrow(const Vec2f base, const Vec2f point, float arrow_head_length); diff -Nru blender-2.61/extern/eltopo/common/predicates.cpp blender-2.62/extern/eltopo/common/predicates.cpp --- blender-2.61/extern/eltopo/common/predicates.cpp 2011-12-13 19:55:14.000000000 +0000 +++ blender-2.62/extern/eltopo/common/predicates.cpp 2012-02-15 19:39:49.000000000 +0000 @@ -1,6 +1,11 @@ #include #include "predicates.h" +#if defined(_WIN32) && !defined(FREE_WINDOWS) +#define random() rand() // not sure if this define is valid +#define _Ios_Fmtflags ios::fmtflags +#endif + static void print_hex( double d ) { std::_Ios_Fmtflags originalFlags = std::cout.flags(); diff -Nru blender-2.61/extern/eltopo/common/tunicate/orientation.cpp blender-2.62/extern/eltopo/common/tunicate/orientation.cpp --- blender-2.61/extern/eltopo/common/tunicate/orientation.cpp 2011-12-13 19:55:14.000000000 +0000 +++ blender-2.62/extern/eltopo/common/tunicate/orientation.cpp 2012-02-15 19:39:49.000000000 +0000 @@ -1,7 +1,16 @@ // Released into the public domain by Robert Bridson, 2009. #include +#if defined(_WIN32) && !defined(FREE_WINDOWS) +#include +#pragma fenv_access (on) +#define FE_UPWARD _RC_UP +#define FE_DOWNWARD _RC_DOWN +#define FE_TONEAREST _RC_NEAR +#define fesetround(r) (_controlfp(r, _MCW_RC)) +#else #include +#endif #include #include #include "tunicate.h" diff -Nru blender-2.61/extern/eltopo/common/tunicate/sos_orientation.cpp blender-2.62/extern/eltopo/common/tunicate/sos_orientation.cpp --- blender-2.61/extern/eltopo/common/tunicate/sos_orientation.cpp 2011-12-13 19:55:14.000000000 +0000 +++ blender-2.62/extern/eltopo/common/tunicate/sos_orientation.cpp 2012-02-15 19:39:49.000000000 +0000 @@ -2,7 +2,12 @@ #include #include +#if defined(_WIN32) && !defined(FREE_WINDOWS) +#include +#pragma fenv_access (on) +#else #include +#endif #include #include #include "tunicate.h" diff -Nru blender-2.61/extern/eltopo/eltopo3d/dynamicsurface.cpp blender-2.62/extern/eltopo/eltopo3d/dynamicsurface.cpp --- blender-2.61/extern/eltopo/eltopo3d/dynamicsurface.cpp 2011-12-13 19:55:20.000000000 +0000 +++ blender-2.62/extern/eltopo/eltopo3d/dynamicsurface.cpp 2012-02-15 19:39:51.000000000 +0000 @@ -18,6 +18,7 @@ #include #include +#ifdef USE_GUI #ifdef __APPLE__ #include #else @@ -26,6 +27,7 @@ #endif #include #endif +#endif #include #include diff -Nru blender-2.61/extern/eltopo/eltopo3d/surftrack.cpp blender-2.62/extern/eltopo/eltopo3d/surftrack.cpp --- blender-2.61/extern/eltopo/eltopo3d/surftrack.cpp 2011-12-13 19:55:20.000000000 +0000 +++ blender-2.62/extern/eltopo/eltopo3d/surftrack.cpp 2012-02-15 19:39:51.000000000 +0000 @@ -19,6 +19,7 @@ #include #include +#ifdef USE_GUI #ifdef __APPLE__ #include #include @@ -30,6 +31,7 @@ #include #include #endif +#endif #include #include diff -Nru blender-2.61/extern/glew/CMakeLists.txt blender-2.62/extern/glew/CMakeLists.txt --- blender-2.61/extern/glew/CMakeLists.txt 2011-12-13 19:57:16.000000000 +0000 +++ blender-2.62/extern/glew/CMakeLists.txt 2012-02-15 19:41:56.000000000 +0000 @@ -12,7 +12,7 @@ # # 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # The Original Code is Copyright (C) 2006, Blender Foundation # All rights reserved. diff -Nru blender-2.61/extern/libmv/bundle.sh blender-2.62/extern/libmv/bundle.sh --- blender-2.61/extern/libmv/bundle.sh 2011-12-13 19:56:34.000000000 +0000 +++ blender-2.62/extern/libmv/bundle.sh 2012-02-15 19:41:08.000000000 +0000 @@ -33,14 +33,14 @@ chmod 664 ./third_party/glog/src/windows/*.cc ./third_party/glog/src/windows/*.h ./third_party/glog/src/windows/glog/*.h -sources=`find ./libmv -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | sed -r 's/^\.\//\t/'` -headers=`find ./libmv -type f -iname '*.h' | sed -r 's/^\.\//\t/'` +sources=`find ./libmv -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | sed -r 's/^\.\//\t/' | sort -d` +headers=`find ./libmv -type f -iname '*.h' | sed -r 's/^\.\//\t/' | sort -d` -third_sources=`find ./third_party -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | grep -v glog | sed -r 's/^\.\//\t/'` -third_headers=`find ./third_party -type f -iname '*.h' | grep -v glog | sed -r 's/^\.\//\t/'` +third_sources=`find ./third_party -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | grep -v glog | sed -r 's/^\.\//\t/' | sort` +third_headers=`find ./third_party -type f -iname '*.h' | grep -v glog | sed -r 's/^\.\//\t/' | sort` -third_glog_sources=`find ./third_party -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | grep glog | grep -v windows | sed -r 's/^\.\//\t\t/'` -third_glog_headers=`find ./third_party -type f -iname '*.h' | grep glog | grep -v windows | sed -r 's/^\.\//\t\t/'` +third_glog_sources=`find ./third_party -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | grep glog | grep -v windows | sed -r 's/^\.\//\t\t/' | sort` +third_glog_headers=`find ./third_party -type f -iname '*.h' | grep glog | grep -v windows | sed -r 's/^\.\//\t\t/' | sort` src_dir=`find ./libmv -type f -iname '*.cc' -exec dirname {} \; -or -iname '*.cpp' -exec dirname {} \; -or -iname '*.c' -exec dirname {} \; | sed -r 's/^\.\//\t/' | sort | uniq` src_third_dir=`find ./third_party -type f -iname '*.cc' -exec dirname {} \; -or -iname '*.cpp' -exec dirname {} \; -or -iname '*.c' -exec dirname {} \; | sed -r 's/^\.\//\t/' | sort | uniq` @@ -89,7 +89,6 @@ done cat > CMakeLists.txt << EOF -# \$Id\$ # ***** BEGIN GPL LICENSE BLOCK ***** # # This program is free software; you can redistribute it and/or @@ -114,17 +113,21 @@ # # ***** END GPL LICENSE BLOCK ***** +# NOTE: This file is automatically generated by bundle.sh script +# If you're doing changes in this file, please update template +# in that script too + set(INC . ../Eigen3 - ./third_party/ssba - ./third_party/ldl/Include + third_party/ssba + third_party/ldl/Include ../colamd/Include ) set(INC_SYS - ${PNG_INCLUDE_DIR} - ${ZLIB_INCLUDE_DIRS} + \${PNG_INCLUDE_DIR} + \${ZLIB_INCLUDE_DIRS} ) set(SRC @@ -139,7 +142,7 @@ ${third_headers} ) -IF(WIN32) +if(WIN32) list(APPEND SRC third_party/glog/src/logging.cc third_party/glog/src/raw_logging.cc @@ -167,28 +170,23 @@ ) list(APPEND INC - ./third_party/glog/src/windows + third_party/glog/src/windows ) - IF(NOT MINGW) + if(NOT MINGW) list(APPEND INC - ./third_party/msinttypes + third_party/msinttypes ) - ENDIF(MINGW) - - list(APPEND INC - ./third_party/glog/src/windows - ./third_party/msinttypes - ) + endif() - IF(MSVC) + if(MSVC) set(MSVC_OFLAGS O1 O2 Ox) foreach(FLAG \${MSVC_OFLAGS}) string(REPLACE "\${FLAG}" "Od" CMAKE_CXX_FLAGS_RELEASE "\${CMAKE_CXX_FLAGS_RELEASE}") string(REPLACE "\${FLAG}" "Od" CMAKE_C_FLAGS_RELWITHDEBINFO "\${CMAKE_C_FLAGS_RELWITHDEBINFO}") endforeach() - ENDIF(MSVC) -ELSE(WIN32) + endif() +else() list(APPEND SRC ${third_glog_sources} @@ -196,17 +194,25 @@ ) list(APPEND INC - ./third_party/glog/src + third_party/glog/src ) -ENDIF(WIN32) +endif() -add_definitions(-DV3DLIB_ENABLE_SUITESPARSE -DGOOGLE_GLOG_DLL_DECL=) +add_definitions( + -DV3DLIB_ENABLE_SUITESPARSE + -DGOOGLE_GLOG_DLL_DECL= +) blender_add_lib(extern_libmv "\${SRC}" "\${INC}" "\${INC_SYS}") EOF cat > SConscript << EOF #!/usr/bin/python + +# NOTE: This file is automatically generated by bundle.sh script +# If you're doing changes in this file, please update template +# in that script too + import sys import os @@ -230,7 +236,6 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): incs += ' ./third_party/glog/src/windows ./third_party/glog/src/windows/glog' - incs += ' ./third_party/glog/src/windows ./third_party/glog/src/windows/glog' if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): incs += ' ./third_party/msinttypes' ${win_src} @@ -246,16 +251,16 @@ defs.append('NDEBUG') else: if not env['BF_DEBUG']: - cflags_libmv = Split(env['REL_CFLAGS']) - ccflags_libmv = Split(env['REL_CCFLAGS']) - cxxflags_libmv = Split(env['REL_CXXFLAGS']) + cflags_libmv += Split(env['REL_CFLAGS']) + ccflags_libmv += Split(env['REL_CCFLAGS']) + cxxflags_libmv += Split(env['REL_CXXFLAGS']) else: src += env.Glob("third_party/glog/src/*.cc") incs += ' ./third_party/glog/src' if not env['BF_DEBUG']: - cflags_libmv = Split(env['REL_CFLAGS']) - ccflags_libmv = Split(env['REL_CCFLAGS']) - cxxflags_libmv = Split(env['REL_CXXFLAGS']) + cflags_libmv += Split(env['REL_CFLAGS']) + ccflags_libmv += Split(env['REL_CCFLAGS']) + cxxflags_libmv += Split(env['REL_CXXFLAGS']) incs += ' ./third_party/ssba ./third_party/ldl/Include ../colamd/Include' diff -Nru blender-2.61/extern/libmv/CMakeLists.txt blender-2.62/extern/libmv/CMakeLists.txt --- blender-2.61/extern/libmv/CMakeLists.txt 2011-12-13 19:56:34.000000000 +0000 +++ blender-2.62/extern/libmv/CMakeLists.txt 2012-02-15 19:41:08.000000000 +0000 @@ -12,7 +12,7 @@ # # 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # The Original Code is Copyright (C) 2011, Blender Foundation # All rights reserved. @@ -22,6 +22,10 @@ # # ***** END GPL LICENSE BLOCK ***** +# NOTE: This file is automatically generated by bundle.sh script +# If you're doing changes in this file, please update template +# in that script too + set(INC . ../Eigen3 diff -Nru blender-2.61/extern/libmv/files.txt blender-2.62/extern/libmv/files.txt --- blender-2.61/extern/libmv/files.txt 2011-12-13 19:56:34.000000000 +0000 +++ blender-2.62/extern/libmv/files.txt 2012-02-15 19:41:08.000000000 +0000 @@ -1,141 +1,151 @@ +libmv/base/id_generator.h +libmv/base/scoped_ptr.h +libmv/base/vector.h +libmv/base/vector_utils.h +libmv/image/array_nd.cc +libmv/image/array_nd.h +libmv/image/convolve.cc +libmv/image/convolve.h +libmv/image/image.h +libmv/image/sample.h +libmv/image/tuple.h libmv/logging/logging.h +libmv/multiview/conditioning.cc +libmv/multiview/conditioning.h +libmv/multiview/euclidean_resection.cc +libmv/multiview/euclidean_resection.h +libmv/multiview/fundamental.cc +libmv/multiview/fundamental.h +libmv/multiview/nviewtriangulation.h +libmv/multiview/projection.cc +libmv/multiview/projection.h +libmv/multiview/resection.h +libmv/multiview/triangulation.cc +libmv/multiview/triangulation.h libmv/numeric/dogleg.h +libmv/numeric/function_derivative.h libmv/numeric/levenberg_marquardt.h -libmv/numeric/poly.h libmv/numeric/numeric.cc -libmv/numeric/function_derivative.h -libmv/numeric/poly.cc -libmv/numeric/tinyvector.cc libmv/numeric/numeric.h -libmv/simple_pipeline/reconstruction.cc -libmv/simple_pipeline/resect.h -libmv/simple_pipeline/resect.cc -libmv/simple_pipeline/reconstruction.h +libmv/numeric/poly.cc +libmv/numeric/poly.h +libmv/simple_pipeline/bundle.cc +libmv/simple_pipeline/bundle.h +libmv/simple_pipeline/callbacks.cc +libmv/simple_pipeline/callbacks.h +libmv/simple_pipeline/camera_intrinsics.cc libmv/simple_pipeline/camera_intrinsics.h -libmv/simple_pipeline/intersect.cc +libmv/simple_pipeline/detect.cc +libmv/simple_pipeline/detect.h libmv/simple_pipeline/initialize_reconstruction.cc -libmv/simple_pipeline/camera_intrinsics.cc +libmv/simple_pipeline/initialize_reconstruction.h +libmv/simple_pipeline/intersect.cc +libmv/simple_pipeline/intersect.h libmv/simple_pipeline/pipeline.cc -libmv/simple_pipeline/tracks.h -libmv/simple_pipeline/detect.h -libmv/simple_pipeline/detect.cc libmv/simple_pipeline/pipeline.h +libmv/simple_pipeline/reconstruction.cc +libmv/simple_pipeline/reconstruction.h +libmv/simple_pipeline/resect.cc +libmv/simple_pipeline/resect.h libmv/simple_pipeline/tracks.cc -libmv/simple_pipeline/bundle.cc -libmv/simple_pipeline/intersect.h -libmv/simple_pipeline/bundle.h -libmv/simple_pipeline/initialize_reconstruction.h -libmv/image/convolve.h -libmv/image/tuple.h -libmv/image/array_nd.h -libmv/image/convolve.cc -libmv/image/array_nd.cc -libmv/image/sample.h -libmv/image/image.h +libmv/simple_pipeline/tracks.h +libmv/tracking/brute_region_tracker.cc +libmv/tracking/brute_region_tracker.h +libmv/tracking/esm_region_tracker.cc +libmv/tracking/esm_region_tracker.h +libmv/tracking/hybrid_region_tracker.cc +libmv/tracking/hybrid_region_tracker.h +libmv/tracking/klt_region_tracker.cc +libmv/tracking/klt_region_tracker.h +libmv/tracking/lmicklt_region_tracker.cc +libmv/tracking/lmicklt_region_tracker.h libmv/tracking/pyramid_region_tracker.cc +libmv/tracking/pyramid_region_tracker.h libmv/tracking/region_tracker.h -libmv/tracking/sad.cc -libmv/tracking/trklt_region_tracker.cc -libmv/tracking/klt_region_tracker.cc +libmv/tracking/retrack_region_tracker.cc libmv/tracking/retrack_region_tracker.h +libmv/tracking/sad.cc libmv/tracking/sad.h -libmv/tracking/pyramid_region_tracker.h +libmv/tracking/trklt_region_tracker.cc libmv/tracking/trklt_region_tracker.h -libmv/tracking/retrack_region_tracker.cc -libmv/tracking/klt_region_tracker.h -libmv/base/id_generator.h -libmv/base/vector.h -libmv/base/scoped_ptr.h -libmv/base/vector_utils.h -libmv/multiview/projection.cc -libmv/multiview/conditioning.cc -libmv/multiview/nviewtriangulation.h -libmv/multiview/resection.h -libmv/multiview/fundamental.cc -libmv/multiview/euclidean_resection.cc -libmv/multiview/euclidean_resection.h -libmv/multiview/triangulation.h -libmv/multiview/projection.h -libmv/multiview/triangulation.cc -libmv/multiview/fundamental.h -libmv/multiview/conditioning.h -third_party/ssba/README.TXT -third_party/ssba/COPYING.TXT -third_party/ssba/Geometry/v3d_metricbundle.h -third_party/ssba/Geometry/v3d_metricbundle.cpp -third_party/ssba/Geometry/v3d_cameramatrix.h -third_party/ssba/Geometry/v3d_distortion.h -third_party/ssba/README.libmv -third_party/ssba/Math/v3d_linear_utils.h -third_party/ssba/Math/v3d_optimization.h -third_party/ssba/Math/v3d_mathutilities.h -third_party/ssba/Math/v3d_linear.h -third_party/ssba/Math/v3d_optimization.cpp -third_party/gflags/gflags_completions.h -third_party/gflags/mutex.h -third_party/gflags/gflags.cc -third_party/gflags/gflags_reporting.cc -third_party/gflags/README.libmv -third_party/gflags/config.h -third_party/gflags/gflags_completions.cc -third_party/gflags/gflags.h -third_party/fast/fast_9.c third_party/fast/fast_10.c third_party/fast/fast_11.c -third_party/fast/fast.h -third_party/fast/LICENSE third_party/fast/fast_12.c +third_party/fast/fast_9.c third_party/fast/fast.c +third_party/fast/fast.h +third_party/fast/LICENSE +third_party/fast/nonmax.c third_party/fast/README third_party/fast/README.libmv -third_party/fast/nonmax.c -third_party/ldl/Include/ldl.h -third_party/ldl/CMakeLists.txt -third_party/ldl/README.libmv -third_party/ldl/Doc/ChangeLog -third_party/ldl/Doc/lesser.txt -third_party/ldl/README.txt -third_party/ldl/Source/ldl.c +third_party/gflags/config.h +third_party/gflags/gflags.cc +third_party/gflags/gflags_completions.cc +third_party/gflags/gflags_completions.h +third_party/gflags/gflags.h +third_party/gflags/gflags_reporting.cc +third_party/gflags/mutex.h +third_party/gflags/README.libmv +third_party/glog/AUTHORS third_party/glog/ChangeLog third_party/glog/COPYING -third_party/glog/src/utilities.cc -third_party/glog/src/utilities.h -third_party/glog/src/symbolize.cc -third_party/glog/src/stacktrace_generic-inl.h +third_party/glog/NEWS +third_party/glog/README +third_party/glog/README.libmv +third_party/glog/src/base/commandlineflags.h +third_party/glog/src/base/googleinit.h +third_party/glog/src/base/mutex.h +third_party/glog/src/config_freebsd.h +third_party/glog/src/config.h +third_party/glog/src/config_linux.h third_party/glog/src/config_mac.h -third_party/glog/src/vlog_is_on.cc +third_party/glog/src/demangle.cc +third_party/glog/src/demangle.h +third_party/glog/src/glog/logging.h +third_party/glog/src/glog/log_severity.h +third_party/glog/src/glog/raw_logging.h +third_party/glog/src/glog/vlog_is_on.h +third_party/glog/src/logging.cc +third_party/glog/src/raw_logging.cc third_party/glog/src/signalhandler.cc +third_party/glog/src/stacktrace_generic-inl.h third_party/glog/src/stacktrace.h +third_party/glog/src/stacktrace_libunwind-inl.h +third_party/glog/src/stacktrace_powerpc-inl.h third_party/glog/src/stacktrace_x86_64-inl.h +third_party/glog/src/stacktrace_x86-inl.h +third_party/glog/src/symbolize.cc third_party/glog/src/symbolize.h -third_party/glog/src/base/googleinit.h -third_party/glog/src/base/mutex.h -third_party/glog/src/base/commandlineflags.h -third_party/glog/src/windows/preprocess.sh -third_party/glog/src/windows/port.h +third_party/glog/src/utilities.cc +third_party/glog/src/utilities.h +third_party/glog/src/vlog_is_on.cc third_party/glog/src/windows/config.h -third_party/glog/src/windows/glog/raw_logging.h -third_party/glog/src/windows/glog/vlog_is_on.h third_party/glog/src/windows/glog/logging.h third_party/glog/src/windows/glog/log_severity.h +third_party/glog/src/windows/glog/raw_logging.h +third_party/glog/src/windows/glog/vlog_is_on.h third_party/glog/src/windows/port.cc -third_party/glog/src/logging.cc -third_party/glog/src/stacktrace_powerpc-inl.h -third_party/glog/src/stacktrace_x86-inl.h -third_party/glog/src/demangle.cc -third_party/glog/src/config.h -third_party/glog/src/demangle.h -third_party/glog/src/stacktrace_libunwind-inl.h -third_party/glog/src/glog/raw_logging.h -third_party/glog/src/glog/vlog_is_on.h -third_party/glog/src/glog/logging.h -third_party/glog/src/glog/log_severity.h -third_party/glog/src/raw_logging.cc -third_party/glog/src/config_linux.h -third_party/glog/NEWS -third_party/glog/README -third_party/glog/README.libmv -third_party/glog/AUTHORS -third_party/msinttypes/stdint.h +third_party/glog/src/windows/port.h +third_party/glog/src/windows/preprocess.sh +third_party/ldl/CMakeLists.txt +third_party/ldl/Doc/ChangeLog +third_party/ldl/Doc/lesser.txt +third_party/ldl/Include/ldl.h +third_party/ldl/README.libmv +third_party/ldl/README.txt +third_party/ldl/Source/ldl.c third_party/msinttypes/inttypes.h third_party/msinttypes/README.libmv +third_party/msinttypes/stdint.h +third_party/ssba/COPYING.TXT +third_party/ssba/Geometry/v3d_cameramatrix.h +third_party/ssba/Geometry/v3d_distortion.h +third_party/ssba/Geometry/v3d_metricbundle.cpp +third_party/ssba/Geometry/v3d_metricbundle.h +third_party/ssba/Math/v3d_linear.h +third_party/ssba/Math/v3d_linear_utils.h +third_party/ssba/Math/v3d_mathutilities.h +third_party/ssba/Math/v3d_optimization.cpp +third_party/ssba/Math/v3d_optimization.h +third_party/ssba/README.libmv +third_party/ssba/README.TXT diff -Nru blender-2.61/extern/libmv/mkfiles.sh blender-2.62/extern/libmv/mkfiles.sh --- blender-2.61/extern/libmv/mkfiles.sh 2011-12-13 19:56:34.000000000 +0000 +++ blender-2.62/extern/libmv/mkfiles.sh 2012-02-15 19:41:08.000000000 +0000 @@ -1,4 +1,4 @@ #!/bin/sh -find ./libmv/ -type f | sed -r 's/^\.\///' > files.txt -find ./third_party/ -type f | sed -r 's/^\.\///' >> files.txt +find ./libmv/ -type f | sed -r 's/^\.\///' | sort > files.txt +find ./third_party/ -type f | sed -r 's/^\.\///' | sort >> files.txt diff -Nru blender-2.61/extern/libmv/SConscript blender-2.62/extern/libmv/SConscript --- blender-2.61/extern/libmv/SConscript 2011-12-13 19:56:34.000000000 +0000 +++ blender-2.62/extern/libmv/SConscript 2012-02-15 19:41:08.000000000 +0000 @@ -1,4 +1,9 @@ #!/usr/bin/python + +# NOTE: This file is automatically generated by bundle.sh script +# If you're doing changes in this file, please update template +# in that script too + import sys import os diff -Nru blender-2.61/extern/libmv/third_party/glog/src/config.h blender-2.62/extern/libmv/third_party/glog/src/config.h --- blender-2.61/extern/libmv/third_party/glog/src/config.h 2011-12-13 19:56:28.000000000 +0000 +++ blender-2.62/extern/libmv/third_party/glog/src/config.h 2012-02-15 19:41:04.000000000 +0000 @@ -2,14 +2,14 @@ /* src/config.h.in. Generated from configure.ac by autoheader. */ /* Namespace for Google classes */ -#ifdef __APPLE__ +#if defined(__APPLE__) #include "config_mac.h" -#elif __FreeBSD__ +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) #include "config_freebsd.h" -#elif __MINGW32__ +#elif defined(__MINGW32__) #include "windows/config.h" -#elif __GNUC__ +#elif defined(__linux__) #include "config_linux.h" -#elif _MSC_VER +#elif defined(_MSC_VER) #include "windows/config.h" #endif diff -Nru blender-2.61/extern/libmv/third_party/glog/src/config_linux.h blender-2.62/extern/libmv/third_party/glog/src/config_linux.h --- blender-2.61/extern/libmv/third_party/glog/src/config_linux.h 2011-12-13 19:56:28.000000000 +0000 +++ blender-2.62/extern/libmv/third_party/glog/src/config_linux.h 2012-02-15 19:41:04.000000000 +0000 @@ -133,8 +133,10 @@ /* How to access the PC from a struct ucontext */ #if defined(_M_X64) || defined(__amd64__) || defined(__x86_64__) #define PC_FROM_UCONTEXT uc_mcontext.gregs[REG_RIP] -#else +#elif defined(_M_IX86) || defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) #define PC_FROM_UCONTEXT uc_mcontext.gregs[REG_EIP] +#else + #undef PC_FROM_UCONTEXT #endif /* Define to necessary symbol if this constant uses a non-standard name on diff -Nru blender-2.61/extern/libmv/third_party/glog/src/stacktrace_x86_64-inl.h blender-2.62/extern/libmv/third_party/glog/src/stacktrace_x86_64-inl.h --- blender-2.61/extern/libmv/third_party/glog/src/stacktrace_x86_64-inl.h 2011-12-13 19:56:28.000000000 +0000 +++ blender-2.62/extern/libmv/third_party/glog/src/stacktrace_x86_64-inl.h 2012-02-15 19:41:04.000000000 +0000 @@ -33,6 +33,10 @@ extern "C" { #include // for NULL +#if defined(__FreeBSD__) +/* devel/libunwind only includes _Unwind_Backtrace if this is set */ +#define _GNU_SOURCE 1 +#endif #include // ABI defined unwinder } #include "stacktrace.h" diff -Nru blender-2.61/extern/libmv/third_party/glog/src/utilities.cc blender-2.62/extern/libmv/third_party/glog/src/utilities.cc --- blender-2.61/extern/libmv/third_party/glog/src/utilities.cc 2011-12-13 19:56:28.000000000 +0000 +++ blender-2.62/extern/libmv/third_party/glog/src/utilities.cc 2012-02-15 19:41:04.000000000 +0000 @@ -223,7 +223,7 @@ pid_t GetTID() { // On Linux and FreeBSD, we try to use gettid(). -#if defined OS_LINUX || defined OS_FREEBSD || defined OS_MACOSX +#if defined OS_LINUX || defined OS_MACOSX #ifndef __NR_gettid #ifdef OS_MACOSX #define __NR_gettid SYS_gettid diff -Nru blender-2.61/extern/libopenjpeg/CMakeLists.txt blender-2.62/extern/libopenjpeg/CMakeLists.txt --- blender-2.61/extern/libopenjpeg/CMakeLists.txt 2011-12-13 19:57:20.000000000 +0000 +++ blender-2.62/extern/libopenjpeg/CMakeLists.txt 2012-02-15 19:42:02.000000000 +0000 @@ -12,7 +12,7 @@ # # 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # The Original Code is Copyright (C) 2006, Blender Foundation # All rights reserved. diff -Nru blender-2.61/extern/libredcode/CMakeLists.txt blender-2.62/extern/libredcode/CMakeLists.txt --- blender-2.61/extern/libredcode/CMakeLists.txt 2011-12-13 19:57:05.000000000 +0000 +++ blender-2.62/extern/libredcode/CMakeLists.txt 2012-02-15 19:41:42.000000000 +0000 @@ -12,7 +12,7 @@ # # 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # The Original Code is Copyright (C) 2006, Blender Foundation # All rights reserved. diff -Nru blender-2.61/extern/lzma/CMakeLists.txt blender-2.62/extern/lzma/CMakeLists.txt --- blender-2.61/extern/lzma/CMakeLists.txt 2011-12-13 19:55:22.000000000 +0000 +++ blender-2.62/extern/lzma/CMakeLists.txt 2012-02-15 19:39:54.000000000 +0000 @@ -12,7 +12,7 @@ # # 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # The Original Code is Copyright (C) 2006, Blender Foundation # All rights reserved. diff -Nru blender-2.61/extern/lzo/CMakeLists.txt blender-2.62/extern/lzo/CMakeLists.txt --- blender-2.61/extern/lzo/CMakeLists.txt 2011-12-13 19:55:24.000000000 +0000 +++ blender-2.62/extern/lzo/CMakeLists.txt 2012-02-15 19:39:57.000000000 +0000 @@ -12,7 +12,7 @@ # # 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # The Original Code is Copyright (C) 2006, Blender Foundation # All rights reserved. diff -Nru blender-2.61/extern/recastnavigation/CMakeLists.txt blender-2.62/extern/recastnavigation/CMakeLists.txt --- blender-2.61/extern/recastnavigation/CMakeLists.txt 2011-12-13 19:55:07.000000000 +0000 +++ blender-2.62/extern/recastnavigation/CMakeLists.txt 2012-02-15 19:39:40.000000000 +0000 @@ -12,7 +12,7 @@ # # 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # The Original Code is Copyright (C) 2006, Blender Foundation # All rights reserved. diff -Nru blender-2.61/extern/SConscript blender-2.62/extern/SConscript --- blender-2.61/extern/SConscript 2011-12-13 19:57:20.000000000 +0000 +++ blender-2.62/extern/SConscript 2012-02-15 19:42:02.000000000 +0000 @@ -31,3 +31,6 @@ if env['WITH_BF_LIBMV']: SConscript(['libmv/SConscript']) + +if env['WITH_BF_CARVE']: + SConscript(['carve/SConscript']) diff -Nru blender-2.61/GNUmakefile blender-2.62/GNUmakefile --- blender-2.61/GNUmakefile 2011-12-13 19:57:52.000000000 +0000 +++ blender-2.62/GNUmakefile 2012-02-15 19:42:25.000000000 +0000 @@ -169,6 +169,7 @@ @echo " * check_cppcheck - run blender source through cppcheck (C & C++)" @echo " * check_splint - run blenders source through splint (C only)" @echo " * check_sparse - run blenders source through sparse (C only)" + @echo " * check_spelling - check for spelling errors (Python only for now)" @echo "" @echo "Documentation Targets (not assosiated with building blender)" @echo " * doc_py - generate sphinx python api docs" @@ -242,6 +243,9 @@ $(CMAKE_CONFIG) cd $(BUILD_DIR) ; python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_sparse.py +check_spelling: + cd $(BUILD_DIR) ; PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/spell_check_source.py `find $(BLENDER_DIR)/release/scripts -name "*.py" | sort` + # ----------------------------------------------------------------------------- # Documentation diff -Nru blender-2.61/intern/audaspace/intern/AUD_C-API.cpp blender-2.62/intern/audaspace/intern/AUD_C-API.cpp --- blender-2.61/intern/audaspace/intern/AUD_C-API.cpp 2011-12-13 19:42:03.000000000 +0000 +++ blender-2.62/intern/audaspace/intern/AUD_C-API.cpp 2012-02-15 19:26:11.000000000 +0000 @@ -137,8 +137,21 @@ #endif #ifdef WITH_JACK case AUD_JACK_DEVICE: - dev = new AUD_JackDevice("Blender", specs, buffersize); - break; +#ifdef __APPLE__ + struct stat st; + if(stat("/Library/Frameworks/Jackmp.framework", &st) != 0) + { + printf("Warning: Jack Framework not installed\n"); + // No break, fall through to default, to return false + } + else + { +#endif + dev = new AUD_JackDevice("Blender", specs, buffersize); + break; +#ifdef __APPLE__ + } +#endif #endif default: return false; diff -Nru blender-2.61/intern/audaspace/intern/AUD_SequencerReader.cpp blender-2.62/intern/audaspace/intern/AUD_SequencerReader.cpp --- blender-2.61/intern/audaspace/intern/AUD_SequencerReader.cpp 2011-12-13 19:42:03.000000000 +0000 +++ blender-2.62/intern/audaspace/intern/AUD_SequencerReader.cpp 2012-02-15 19:26:11.000000000 +0000 @@ -176,6 +176,8 @@ } m_factory->m_volume.read(frame, &volume); + if(m_factory->m_muted) + volume = 0.0f; m_device.setVolume(volume); m_factory->m_orientation.read(frame, q.get()); diff -Nru blender-2.61/intern/audaspace/intern/AUD_SoftwareDevice.cpp blender-2.62/intern/audaspace/intern/AUD_SoftwareDevice.cpp --- blender-2.61/intern/audaspace/intern/AUD_SoftwareDevice.cpp 2011-12-13 19:42:03.000000000 +0000 +++ blender-2.62/intern/audaspace/intern/AUD_SoftwareDevice.cpp 2012-02-15 19:26:11.000000000 +0000 @@ -121,7 +121,9 @@ if(flags & AUD_RENDER_DISTANCE) { - if(m_device->m_distance_model == AUD_DISTANCE_MODEL_INVERSE_CLAMPED || m_device->m_distance_model == AUD_DISTANCE_MODEL_LINEAR_CLAMPED || m_device->m_distance_model == AUD_DISTANCE_MODEL_EXPONENT_CLAMPED) + if(m_device->m_distance_model == AUD_DISTANCE_MODEL_INVERSE_CLAMPED || + m_device->m_distance_model == AUD_DISTANCE_MODEL_LINEAR_CLAMPED || + m_device->m_distance_model == AUD_DISTANCE_MODEL_EXPONENT_CLAMPED) { distance = AUD_MAX(AUD_MIN(m_distance_max, distance), m_distance_reference); } diff -Nru blender-2.61/intern/boolop/CMakeLists.txt blender-2.62/intern/boolop/CMakeLists.txt --- blender-2.61/intern/boolop/CMakeLists.txt 2011-12-13 19:42:27.000000000 +0000 +++ blender-2.62/intern/boolop/CMakeLists.txt 2012-02-15 19:26:37.000000000 +0000 @@ -23,6 +23,8 @@ # # ***** END GPL LICENSE BLOCK ***** +remove_strict_flags() + set(INC . extern @@ -39,43 +41,71 @@ ) -set(SRC - intern/BOP_BBox.cpp - intern/BOP_BSPNode.cpp - intern/BOP_BSPTree.cpp - intern/BOP_Edge.cpp - intern/BOP_Face.cpp - intern/BOP_Face2Face.cpp - intern/BOP_Interface.cpp - intern/BOP_MathUtils.cpp - intern/BOP_Merge.cpp - intern/BOP_Merge2.cpp - intern/BOP_Mesh.cpp - intern/BOP_Segment.cpp - intern/BOP_Splitter.cpp - intern/BOP_Tag.cpp - intern/BOP_Triangulator.cpp - intern/BOP_Vertex.cpp - - extern/BOP_Interface.h - intern/BOP_BBox.h - intern/BOP_BSPNode.h - intern/BOP_BSPTree.h - intern/BOP_Chrono.h - intern/BOP_Edge.h - intern/BOP_Face.h - intern/BOP_Face2Face.h - intern/BOP_Indexs.h - intern/BOP_MathUtils.h - intern/BOP_Merge.h - intern/BOP_Merge2.h - intern/BOP_Mesh.h - intern/BOP_Misc.h - intern/BOP_Segment.h - intern/BOP_Splitter.h - intern/BOP_Tag.h - intern/BOP_Triangulator.h - intern/BOP_Vertex.h -) +if(NOT WITH_CARVE) + set(SRC + intern/BOP_BBox.cpp + intern/BOP_BSPNode.cpp + intern/BOP_BSPTree.cpp + intern/BOP_Edge.cpp + intern/BOP_Face.cpp + intern/BOP_Face2Face.cpp + intern/BOP_Interface.cpp + intern/BOP_MathUtils.cpp + intern/BOP_Merge.cpp + intern/BOP_Merge2.cpp + intern/BOP_Mesh.cpp + intern/BOP_Segment.cpp + intern/BOP_Splitter.cpp + intern/BOP_Tag.cpp + intern/BOP_Triangulator.cpp + intern/BOP_Vertex.cpp + + extern/BOP_Interface.h + intern/BOP_BBox.h + intern/BOP_BSPNode.h + intern/BOP_BSPTree.h + intern/BOP_Chrono.h + intern/BOP_Edge.h + intern/BOP_Face.h + intern/BOP_Face2Face.h + intern/BOP_Indexs.h + intern/BOP_MathUtils.h + intern/BOP_Merge.h + intern/BOP_Merge2.h + intern/BOP_Mesh.h + intern/BOP_Misc.h + intern/BOP_Segment.h + intern/BOP_Splitter.h + intern/BOP_Tag.h + intern/BOP_Triangulator.h + intern/BOP_Vertex.h + ) +else() + set(SRC + intern/BOP_CarveInterface.cpp + extern/BOP_Interface.h + ) + + list(APPEND INC + ../../extern/carve/include + ) + + if(WITH_BOOST) + if(NOT MSVC) + # Boost is setting as preferred collections library in the Carve code when using MSVC compiler + add_definitions( + -DHAVE_BOOST_UNORDERED_COLLECTIONS + ) + endif() + + add_definitions( + -DCARVE_SYSTEM_BOOST + ) + + list(APPEND INC + ${BOOST_INCLUDE_DIR} + ) + endif() +endif() blender_add_lib(bf_intern_bop "${SRC}" "${INC}" "${INC_SYS}") diff -Nru blender-2.61/intern/boolop/intern/BOP_BSPNode.cpp blender-2.62/intern/boolop/intern/BOP_BSPNode.cpp --- blender-2.61/intern/boolop/intern/BOP_BSPNode.cpp 2011-12-13 19:42:27.000000000 +0000 +++ blender-2.62/intern/boolop/intern/BOP_BSPNode.cpp 2012-02-15 19:26:37.000000000 +0000 @@ -35,7 +35,6 @@ #include "MT_assert.h" #include "MT_MinMax.h" #include -using namespace std; /** * Constructs a new BSP node. @@ -707,13 +706,13 @@ */ void BOP_BSPNode::print(unsigned int deep) { - cout << "(" << deep << "," << m_plane << ")," << endl; + std::cout << "(" << deep << "," << m_plane << ")," << std::endl; if (m_inChild != NULL) m_inChild->print(deep + 1); else - cout << "(" << deep+1 << ",None)," << endl; + std::cout << "(" << deep+1 << ",None)," << std::endl; if (m_outChild != NULL) m_outChild->print(deep + 1); else - cout << "(" << deep+1 << ",None)," << endl; + std::cout << "(" << deep+1 << ",None)," << std::endl; } diff -Nru blender-2.61/intern/boolop/intern/BOP_BSPNode.h blender-2.62/intern/boolop/intern/BOP_BSPNode.h --- blender-2.61/intern/boolop/intern/BOP_BSPNode.h 2011-12-13 19:42:27.000000000 +0000 +++ blender-2.62/intern/boolop/intern/BOP_BSPNode.h 2012-02-15 19:26:37.000000000 +0000 @@ -37,8 +37,8 @@ #include "BOP_Tag.h" #include "BOP_Face.h" -typedef vector BOP_BSPPoints; -typedef vector::const_iterator BOP_IT_BSPPoints; +typedef std::vector BOP_BSPPoints; +typedef std::vector::const_iterator BOP_IT_BSPPoints; class BOP_BSPNode { diff -Nru blender-2.61/intern/boolop/intern/BOP_BSPTree.cpp blender-2.62/intern/boolop/intern/BOP_BSPTree.cpp --- blender-2.61/intern/boolop/intern/BOP_BSPTree.cpp 2011-12-13 19:42:27.000000000 +0000 +++ blender-2.62/intern/boolop/intern/BOP_BSPTree.cpp 2012-02-15 19:26:37.000000000 +0000 @@ -33,7 +33,6 @@ #include "BOP_BSPTree.h" #include #include -using namespace std; /** * Constructs a new BSP tree. diff -Nru blender-2.61/intern/boolop/intern/BOP_CarveInterface.cpp blender-2.62/intern/boolop/intern/BOP_CarveInterface.cpp --- blender-2.61/intern/boolop/intern/BOP_CarveInterface.cpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/intern/boolop/intern/BOP_CarveInterface.cpp 2012-02-15 19:26:37.000000000 +0000 @@ -0,0 +1,783 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + * The Original Code is Copyright (C) 2010 by the Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Ken Hughes, + * Sergey Sharybin. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file boolop/intern/BOP_CarveInterface.cpp + * \ingroup boolopintern + */ + +#include "../extern/BOP_Interface.h" +#include "../../bsp/intern/BSP_CSGMesh_CFIterator.h" + +#include +#include +#include + +#include + +using namespace carve::mesh; +using namespace carve::geom; +typedef unsigned int uint; + +#define MAX(x,y) ((x)>(y)?(x):(y)) +#define MIN(x,y) ((x)<(y)?(x):(y)) + +static bool isQuadPlanar(carve::geom3d::Vector &v1, carve::geom3d::Vector &v2, + carve::geom3d::Vector &v3, carve::geom3d::Vector &v4) +{ + carve::geom3d::Vector vec1, vec2, vec3, cross; + + vec1 = v2 - v1; + vec2 = v4 - v1; + vec3 = v3 - v1; + + cross = carve::geom::cross(vec1, vec2); + + float production = carve::geom::dot(cross, vec3); + float magnitude = 1e-6 * cross.length(); + + return fabs(production) < magnitude; +} + +static bool isFacePlanar(CSG_IFace &face, std::vector &vertices) +{ + if (face.vertex_number == 4) { + return isQuadPlanar(vertices[face.vertex_index[0]], vertices[face.vertex_index[1]], + vertices[face.vertex_index[2]], vertices[face.vertex_index[3]]); + } + + return true; +} + +static void Carve_copyMeshes(std::vector::mesh_t*> &meshes, std::vector::mesh_t*> &new_meshes) +{ + std::vector::mesh_t*>::iterator it = meshes.begin(); + + for(; it!=meshes.end(); it++) { + MeshSet<3>::mesh_t *mesh = *it; + MeshSet<3>::mesh_t *new_mesh = new MeshSet<3>::mesh_t(mesh->faces); + + new_meshes.push_back(new_mesh); + } +} + +static MeshSet<3> *Carve_meshSetFromMeshes(std::vector::mesh_t*> &meshes) +{ + std::vector::mesh_t*> new_meshes; + + Carve_copyMeshes(meshes, new_meshes); + + return new MeshSet<3>(new_meshes); +} + +static MeshSet<3> *Carve_meshSetFromTwoMeshes(std::vector::mesh_t*> &left_meshes, + std::vector::mesh_t*> &right_meshes) +{ + std::vector::mesh_t*> new_meshes; + + Carve_copyMeshes(left_meshes, new_meshes); + Carve_copyMeshes(right_meshes, new_meshes); + + return new MeshSet<3>(new_meshes); +} + +static bool Carve_checkEdgeFaceIntersections_do(carve::csg::Intersections &intersections, + MeshSet<3>::face_t *face_a, MeshSet<3>::edge_t *edge_b) +{ + if(intersections.intersects(edge_b, face_a)) + return true; + + carve::mesh::MeshSet<3>::vertex_t::vector_t _p; + if(face_a->simpleLineSegmentIntersection(carve::geom3d::LineSegment(edge_b->v1()->v, edge_b->v2()->v), _p)) + return true; + + return false; +} + +static bool Carve_checkEdgeFaceIntersections(carve::csg::Intersections &intersections, + MeshSet<3>::face_t *face_a, MeshSet<3>::face_t *face_b) +{ + MeshSet<3>::edge_t *edge_b; + + edge_b = face_b->edge; + do { + if(Carve_checkEdgeFaceIntersections_do(intersections, face_a, edge_b)) + return true; + edge_b = edge_b->next; + } while (edge_b != face_b->edge); + + return false; +} + +static inline bool Carve_facesAreCoplanar(const MeshSet<3>::face_t *a, const MeshSet<3>::face_t *b) +{ + carve::geom3d::Ray temp; + // XXX: Find a better definition. This may be a source of problems + // if floating point inaccuracies cause an incorrect answer. + return !carve::geom3d::planeIntersection(a->plane, b->plane, temp); +} + +static bool Carve_checkMeshSetInterseciton_do(carve::csg::Intersections &intersections, + const RTreeNode<3, Face<3> *> *a_node, + const RTreeNode<3, Face<3> *> *b_node, + bool descend_a = true) +{ + if(!a_node->bbox.intersects(b_node->bbox)) + return false; + + if(a_node->child && (descend_a || !b_node->child)) { + for(RTreeNode<3, Face<3> *> *node = a_node->child; node; node = node->sibling) { + if(Carve_checkMeshSetInterseciton_do(intersections, node, b_node, false)) + return true; + } + } + else if(b_node->child) { + for(RTreeNode<3, Face<3> *> *node = b_node->child; node; node = node->sibling) { + if(Carve_checkMeshSetInterseciton_do(intersections, a_node, node, true)) + return true; + } + } + else { + for(size_t i = 0; i < a_node->data.size(); ++i) { + MeshSet<3>::face_t *fa = a_node->data[i]; + aabb<3> aabb_a = fa->getAABB(); + if(aabb_a.maxAxisSeparation(b_node->bbox) > carve::EPSILON) continue; + + for(size_t j = 0; j < b_node->data.size(); ++j) { + MeshSet<3>::face_t *fb = b_node->data[j]; + aabb<3> aabb_b = fb->getAABB(); + if(aabb_b.maxAxisSeparation(aabb_a) > carve::EPSILON) continue; + + std::pair a_ra = fa->rangeInDirection(fa->plane.N, fa->edge->vert->v); + std::pair b_ra = fb->rangeInDirection(fa->plane.N, fa->edge->vert->v); + if(carve::rangeSeparation(a_ra, b_ra) > carve::EPSILON) continue; + + std::pair a_rb = fa->rangeInDirection(fb->plane.N, fb->edge->vert->v); + std::pair b_rb = fb->rangeInDirection(fb->plane.N, fb->edge->vert->v); + if(carve::rangeSeparation(a_rb, b_rb) > carve::EPSILON) continue; + + if(!Carve_facesAreCoplanar(fa, fb)) { + if(Carve_checkEdgeFaceIntersections(intersections, fa, fb)) { + return true; + } + } + } + } + } + + return false; +} + +static bool Carve_checkMeshSetInterseciton(RTreeNode<3, Face<3> *> *rtree_a, RTreeNode<3, Face<3> *> *rtree_b) +{ + carve::csg::Intersections intersections; + + return Carve_checkMeshSetInterseciton_do(intersections, rtree_a, rtree_b); +} + +static void Carve_getIntersectedOperandMeshes(std::vector::mesh_t*> &meshes, MeshSet<3>::aabb_t &otherAABB, + std::vector::mesh_t*> &operandMeshes) +{ + std::vector::mesh_t*>::iterator it = meshes.begin(); + std::vector< RTreeNode<3, Face<3> *> *> meshRTree; + + while(it != meshes.end()) { + MeshSet<3>::mesh_t *mesh = *it; + bool isAdded = false; + + RTreeNode<3, Face<3> *> *rtree = RTreeNode<3, Face<3> *>::construct_STR(mesh->faces.begin(), mesh->faces.end(), 4, 4); + + if (rtree->bbox.intersects(otherAABB)) { + bool isIntersect = false; + + std::vector::mesh_t*>::iterator operand_it = operandMeshes.begin(); + std::vector *> *>::iterator tree_it = meshRTree.begin(); + for(; operand_it!=operandMeshes.end(); operand_it++, tree_it++) { + RTreeNode<3, Face<3> *> *operandRTree = *tree_it; + + if(Carve_checkMeshSetInterseciton(rtree, operandRTree)) { + isIntersect = true; + break; + } + } + + if(!isIntersect) { + operandMeshes.push_back(mesh); + meshRTree.push_back(rtree); + + it = meshes.erase(it); + isAdded = true; + } + } + + if (!isAdded) { + delete rtree; + it++; + } + } + + std::vector *> *>::iterator tree_it = meshRTree.begin(); + for(; tree_it != meshRTree.end(); tree_it++) { + delete *tree_it; + } +} + +static MeshSet<3> *Carve_getIntersectedOperand(std::vector::mesh_t*> &meshes, MeshSet<3>::aabb_t &otherAABB) +{ + std::vector::mesh_t*> operandMeshes; + Carve_getIntersectedOperandMeshes(meshes, otherAABB, operandMeshes); + + if (operandMeshes.size() == 0) + return NULL; + + return Carve_meshSetFromMeshes(operandMeshes); +} + +static MeshSet<3> *Carve_unionIntersectingMeshes(MeshSet<3> *poly, + MeshSet<3>::aabb_t &otherAABB, + carve::interpolate::FaceAttr &oface_num) +{ + if(poly->meshes.size()<=1) + return poly; + + carve::csg::CSG csg; + + oface_num.installHooks(csg); + csg.hooks.registerHook(new carve::csg::CarveTriangulator, carve::csg::CSG::Hooks::PROCESS_OUTPUT_FACE_BIT); + + std::vector::mesh_t*> orig_meshes = + std::vector::mesh_t*>(poly->meshes.begin(), poly->meshes.end()); + + MeshSet<3> *left = Carve_getIntersectedOperand(orig_meshes, otherAABB); + + if (!left) { + /* no maniforlds which intersects another object at all */ + return poly; + } + + while(orig_meshes.size()) { + MeshSet<3> *right = Carve_getIntersectedOperand(orig_meshes, otherAABB); + + if (!right) { + /* no more intersecting manifolds which intersects other object */ + break; + } + + try { + if(left->meshes.size()==0) { + delete left; + + left = right; + } + else { + MeshSet<3> *result = csg.compute(left, right, carve::csg::CSG::UNION, NULL, carve::csg::CSG::CLASSIFY_EDGE); + + delete left; + delete right; + + left = result; + } + } + catch(carve::exception e) { + std::cerr << "CSG failed, exception " << e.str() << std::endl; + + MeshSet<3> *result = Carve_meshSetFromTwoMeshes(left->meshes, right->meshes); + + delete left; + delete right; + + left = result; + } + catch(...) { + delete left; + delete right; + + throw "Unknown error in Carve library"; + } + } + + /* append all meshes which doesn't have intersection with another operand as-is */ + if (orig_meshes.size()) { + MeshSet<3> *result = Carve_meshSetFromTwoMeshes(left->meshes, orig_meshes); + + delete left; + + return result; + } + + return left; +} + +static void Carve_unionIntersections(MeshSet<3> **left_r, MeshSet<3> **right_r, + carve::interpolate::FaceAttr &oface_num) +{ + MeshSet<3> *left, *right; + + MeshSet<3>::aabb_t leftAABB = (*left_r)->getAABB(); + MeshSet<3>::aabb_t rightAABB = (*right_r)->getAABB(); + + left = Carve_unionIntersectingMeshes(*left_r, rightAABB, oface_num); + right = Carve_unionIntersectingMeshes(*right_r, leftAABB, oface_num); + + if(left != *left_r) + delete *left_r; + + if(right != *right_r) + delete *right_r; + + *left_r = left; + *right_r = right; +} + +static MeshSet<3> *Carve_addMesh(CSG_FaceIteratorDescriptor &face_it, + CSG_VertexIteratorDescriptor &vertex_it, + carve::interpolate::FaceAttr &oface_num, + uint &num_origfaces) +{ + CSG_IVertex vertex; + std::vector vertices; + + while (!vertex_it.Done(vertex_it.it)) { + vertex_it.Fill(vertex_it.it,&vertex); + vertices.push_back(VECTOR(vertex.position[0], + vertex.position[1], + vertex.position[2])); + vertex_it.Step(vertex_it.it); + } + + CSG_IFace face; + std::vector f; + int numfaces = 0; + + // now for the polygons. + // we may need to decalare some memory for user defined face properties. + + std::vector forig; + while (!face_it.Done(face_it.it)) { + face_it.Fill(face_it.it,&face); + + if (isFacePlanar(face, vertices)) { + f.push_back(face.vertex_number); + f.push_back(face.vertex_index[0]); + f.push_back(face.vertex_index[1]); + f.push_back(face.vertex_index[2]); + + if (face.vertex_number == 4) + f.push_back(face.vertex_index[3]); + + forig.push_back(face.orig_face); + ++numfaces; + face_it.Step(face_it.it); + ++num_origfaces; + } + else { + f.push_back(3); + f.push_back(face.vertex_index[0]); + f.push_back(face.vertex_index[1]); + f.push_back(face.vertex_index[2]); + + forig.push_back(face.orig_face); + ++numfaces; + + if (face.vertex_number == 4) { + f.push_back(3); + f.push_back(face.vertex_index[0]); + f.push_back(face.vertex_index[2]); + f.push_back(face.vertex_index[3]); + + forig.push_back(face.orig_face); + ++numfaces; + } + + face_it.Step(face_it.it); + ++num_origfaces; + } + } + + MeshSet<3> *poly = new MeshSet<3> (vertices, numfaces, f); + + uint i; + MeshSet<3>::face_iter face_iter = poly->faceBegin(); + for (i = 0; face_iter != poly->faceEnd(); ++face_iter, ++i) { + MeshSet<3>::face_t *face = *face_iter; + oface_num.setAttribute(face, forig[i]); + } + + return poly; +} + +static bool checkValidQuad(std::vector::vertex_t> &vertex_storage, uint quad[4]) +{ + carve::geom3d::Vector &v1 = vertex_storage[quad[0]].v; + carve::geom3d::Vector &v2 = vertex_storage[quad[1]].v; + carve::geom3d::Vector &v3 = vertex_storage[quad[2]].v; + carve::geom3d::Vector &v4 = vertex_storage[quad[3]].v; + +#if 0 + /* disabled for now to prevent initially non-planar be triangulated + * in theory this might cause some artifacts if intersections happens by non-planar + * non-concave quad, but in practice it's acceptable */ + if (!isQuadPlanar(v1, v2, v3, v4)) { + /* non-planar faces better not be merged because of possible differences in triangulation + * of non-planar faces in opengl and renderer */ + return false; + } +#endif + + carve::geom3d::Vector edges[4]; + carve::geom3d::Vector normal; + bool normal_set = false; + + edges[0] = v2 - v1; + edges[1] = v3 - v2; + edges[2] = v4 - v3; + edges[3] = v1 - v4; + + for (int i = 0; i < 4; i++) { + int n = i + 1; + + if (n == 4) + n = 0; + + carve::geom3d::Vector current_normal = carve::geom::cross(edges[i], edges[n]); + + if (current_normal.length() > 1e-6) { + if (!normal_set) { + normal = current_normal; + normal_set = true; + } + else if (carve::geom::dot(normal, current_normal) < -1e-6) { + return false; + } + } + } + + if (!normal_set) { + /* normal wasn't set means face is degraded and better merge it in such way */ + return false; + } + + return true; +} + +// check whether two faces share an edge, and if so merge them +static uint quadMerge(std::map::vertex_t*, uint> *vertexToIndex_map, + std::vector::vertex_t> &vertex_storage, + MeshSet<3>::face_t *f1, MeshSet<3>::face_t *f2, + uint v, uint quad[4]) +{ + uint current, n1, p1, n2, p2; + uint v1[3]; + uint v2[3]; + + // get the vertex indices for each face + v1[0] = vertexToIndex_map->find(f1->edge->vert)->second; + v1[1] = vertexToIndex_map->find(f1->edge->next->vert)->second; + v1[2] = vertexToIndex_map->find(f1->edge->next->next->vert)->second; + + v2[0] = vertexToIndex_map->find(f2->edge->vert)->second; + v2[1] = vertexToIndex_map->find(f2->edge->next->vert)->second; + v2[2] = vertexToIndex_map->find(f2->edge->next->next->vert)->second; + + // locate the current vertex we're examining, and find the next and + // previous vertices based on the face windings + if (v1[0] == v) {current = 0; p1 = 2; n1 = 1;} + else if (v1[1] == v) {current = 1; p1 = 0; n1 = 2;} + else {current = 2; p1 = 1; n1 = 0;} + + if (v2[0] == v) {p2 = 2; n2 = 1;} + else if (v2[1] == v) {p2 = 0; n2 = 2;} + else {p2 = 1; n2 = 0;} + + // if we find a match, place indices into quad in proper order and return + // success code + if (v1[p1] == v2[n2]) { + quad[0] = v1[current]; + quad[1] = v1[n1]; + quad[2] = v1[p1]; + quad[3] = v2[p2]; + + return checkValidQuad(vertex_storage, quad); + } + else if (v1[n1] == v2[p2]) { + quad[0] = v1[current]; + quad[1] = v2[n2]; + quad[2] = v1[n1]; + quad[3] = v1[p1]; + + return checkValidQuad(vertex_storage, quad); + } + + return 0; +} + +static BSP_CSGMesh *Carve_exportMesh(MeshSet<3>* &poly, carve::interpolate::FaceAttr &oface_num, + uint num_origfaces) +{ + uint i; + BSP_CSGMesh *outputMesh = BSP_CSGMesh::New(); + + if (outputMesh == NULL) + return NULL; + + std::vector *vertices = new std::vector; + + outputMesh->SetVertices(vertices); + + std::map::vertex_t*, uint> vertexToIndex_map; + std::vector::vertex_t>::iterator it = poly->vertex_storage.begin(); + for (i = 0; it != poly->vertex_storage.end(); ++i, ++it) { + MeshSet<3>::vertex_t *vertex = &(*it); + vertexToIndex_map[vertex] = i; + } + + for (i = 0; i < poly->vertex_storage.size(); ++i ) { + BSP_MVertex outVtx(MT_Point3 (poly->vertex_storage[i].v[0], + poly->vertex_storage[i].v[1], + poly->vertex_storage[i].v[2])); + outVtx.m_edges.clear(); + outputMesh->VertexSet().push_back(outVtx); + } + + // build vectors of faces for each original face and each vertex + std::vector > vi(poly->vertex_storage.size()); + std::vector > ofaces(num_origfaces); + MeshSet<3>::face_iter face_iter = poly->faceBegin(); + for (i = 0; face_iter != poly->faceEnd(); ++face_iter, ++i) { + MeshSet<3>::face_t *f = *face_iter; + ofaces[oface_num.getAttribute(f)].push_back(i); + MeshSet<3>::face_t::edge_iter_t edge_iter = f->begin(); + for (; edge_iter != f->end(); ++edge_iter) { + int index = vertexToIndex_map[edge_iter->vert]; + vi[index].push_back(i); + } + } + + uint quadverts[4] = {0, 0, 0, 0}; + // go over each set of faces which belong to an original face + std::vector< std::vector >::const_iterator fii; + uint orig = 0; + for (fii=ofaces.begin(); fii!=ofaces.end(); ++fii, ++orig) { + std::vector fl = *fii; + // go over a single set from an original face + while (fl.size() > 0) { + // remove one new face + uint findex = fl.back(); + fl.pop_back(); + + MeshSet<3>::face_t *f = *(poly->faceBegin() + findex); + + // add all information except vertices to the output mesh + outputMesh->FaceSet().push_back(BSP_MFace()); + BSP_MFace& outFace = outputMesh->FaceSet().back(); + outFace.m_verts.clear(); + outFace.m_plane.setValue(f->plane.N.v); + outFace.m_orig_face = orig; + + // for each vertex of this face, check other faces containing + // that vertex to see if there is a neighbor also belonging to + // the original face + uint result = 0; + + MeshSet<3>::face_t::edge_iter_t edge_iter = f->begin(); + for (; edge_iter != f->end(); ++edge_iter) { + int v = vertexToIndex_map[edge_iter->vert]; + for (uint pos2=0; !result && pos2 < vi[v].size();pos2++) { + + // if we find the current face, ignore it + uint otherf = vi[v][pos2]; + if (findex == otherf) + continue; + + MeshSet<3>::face_t *f2 = *(poly->faceBegin() + otherf); + + // if other face doesn't have the same original face, + // ignore it also + uint other_orig = oface_num.getAttribute(f2); + if (orig != other_orig) + continue; + + // if, for some reason, we don't find the other face in + // the current set of faces, ignore it + uint other_index = 0; + while (other_index < fl.size() && fl[other_index] != otherf) ++other_index; + if (other_index == fl.size()) continue; + + // see if the faces share an edge + result = quadMerge(&vertexToIndex_map, poly->vertex_storage, f, f2, v, quadverts); + // if faces can be merged, then remove the other face + // from the current set + if (result) { + uint replace = fl.back(); + fl.pop_back(); + if(otherf != replace) + fl[other_index] = replace; + } + } + } + + // if we merged faces, use the list of common vertices; otherwise + // use the faces's vertices + if (result) { + // make quat using verts stored in result + outFace.m_verts.push_back(quadverts[0]); + outFace.m_verts.push_back(quadverts[1]); + outFace.m_verts.push_back(quadverts[2]); + outFace.m_verts.push_back(quadverts[3]); + } else { + MeshSet<3>::face_t::edge_iter_t edge_iter = f->begin(); + for (; edge_iter != f->end(); ++edge_iter) { + //int index = ofacevert_num.getAttribute(f, edge_iter.idx()); + int index = vertexToIndex_map[edge_iter->vert]; + outFace.m_verts.push_back( index ); + } + } + } + } + + // Build the mesh edges using topological informtion + outputMesh->BuildEdges(); + + return outputMesh; +} + +/** + * Performs a generic booleam operation, the entry point for external modules. + * @param opType Boolean operation type BOP_INTERSECTION, BOP_UNION, BOP_DIFFERENCE + * @param outputMesh Output mesh, the final result (the object C) + * @param obAFaces Object A faces list + * @param obAVertices Object A vertices list + * @param obBFaces Object B faces list + * @param obBVertices Object B vertices list + * @param interpFunc Interpolating function + * @return operation state: BOP_OK, BOP_NO_SOLID, BOP_ERROR + */ +BoolOpState BOP_performBooleanOperation(BoolOpType opType, + BSP_CSGMesh** outputMesh, + CSG_FaceIteratorDescriptor obAFaces, + CSG_VertexIteratorDescriptor obAVertices, + CSG_FaceIteratorDescriptor obBFaces, + CSG_VertexIteratorDescriptor obBVertices) +{ + carve::csg::CSG::OP op; + MeshSet<3> *left, *right, *output = NULL; + carve::csg::CSG csg; + carve::geom3d::Vector min, max; + carve::interpolate::FaceAttr oface_num; + uint num_origfaces = 0; + + switch (opType) { + case BOP_UNION: + op = carve::csg::CSG::UNION; + break; + case BOP_INTERSECTION: + op = carve::csg::CSG::INTERSECTION; + break; + case BOP_DIFFERENCE: + op = carve::csg::CSG::A_MINUS_B; + break; + default: + return BOP_ERROR; + } + + left = Carve_addMesh(obAFaces, obAVertices, oface_num, num_origfaces ); + right = Carve_addMesh(obBFaces, obBVertices, oface_num, num_origfaces ); + + min.x = max.x = left->vertex_storage[0].v.x; + min.y = max.y = left->vertex_storage[0].v.y; + min.z = max.z = left->vertex_storage[0].v.z; + for (uint i = 1; i < left->vertex_storage.size(); ++i) { + min.x = MIN(min.x,left->vertex_storage[i].v.x); + min.y = MIN(min.y,left->vertex_storage[i].v.y); + min.z = MIN(min.z,left->vertex_storage[i].v.z); + max.x = MAX(max.x,left->vertex_storage[i].v.x); + max.y = MAX(max.y,left->vertex_storage[i].v.y); + max.z = MAX(max.z,left->vertex_storage[i].v.z); + } + for (uint i = 0; i < right->vertex_storage.size(); ++i) { + min.x = MIN(min.x,right->vertex_storage[i].v.x); + min.y = MIN(min.y,right->vertex_storage[i].v.y); + min.z = MIN(min.z,right->vertex_storage[i].v.z); + max.x = MAX(max.x,right->vertex_storage[i].v.x); + max.y = MAX(max.y,right->vertex_storage[i].v.y); + max.z = MAX(max.z,right->vertex_storage[i].v.z); + } + + carve::rescale::rescale scaler(min.x, min.y, min.z, max.x, max.y, max.z); + carve::rescale::fwd fwd_r(scaler); + carve::rescale::rev rev_r(scaler); + + left->transform(fwd_r); + right->transform(fwd_r); + + // prepare operands for actual boolean operation. it's needed because operands might consist of + // several intersecting meshes and in case if another operands intersect an edge loop of intersecting that + // meshes tesselation of operation result can't be done properly. the only way to make such situations + // working is to union intersecting meshes of the same operand + Carve_unionIntersections(&left, &right, oface_num); + + if(left->meshes.size() == 0 || right->meshes.size()==0) { + // normally sohuldn't happen (zero-faces objects are handled by modifier itself), but + // unioning intersecting meshes which doesn't have consistent normals might lead to + // empty result which wouldn't work here + + delete left; + delete right; + + return BOP_ERROR; + } + + csg.hooks.registerHook(new carve::csg::CarveTriangulator, carve::csg::CSG::Hooks::PROCESS_OUTPUT_FACE_BIT); + + oface_num.installHooks(csg); + + try { + output = csg.compute(left, right, op, NULL, carve::csg::CSG::CLASSIFY_EDGE); + } + catch(carve::exception e) { + std::cerr << "CSG failed, exception " << e.str() << std::endl; + } + catch(...) { + delete left; + delete right; + + throw "Unknown error in Carve library"; + } + + delete left; + delete right; + + if(!output) + return BOP_ERROR; + + output->transform(rev_r); + + *outputMesh = Carve_exportMesh(output, oface_num, num_origfaces); + delete output; + + return BOP_OK; +} diff -Nru blender-2.61/intern/boolop/intern/BOP_Edge.cpp blender-2.62/intern/boolop/intern/BOP_Edge.cpp --- blender-2.61/intern/boolop/intern/BOP_Edge.cpp 2011-12-13 19:42:27.000000000 +0000 +++ blender-2.62/intern/boolop/intern/BOP_Edge.cpp 2012-02-15 19:26:37.000000000 +0000 @@ -105,7 +105,6 @@ #ifdef BOP_DEBUG #include -using namespace std; /** * Implements operator <<. diff -Nru blender-2.61/intern/boolop/intern/BOP_Face.h blender-2.62/intern/boolop/intern/BOP_Face.h --- blender-2.61/intern/boolop/intern/BOP_Face.h 2011-12-13 19:42:27.000000000 +0000 +++ blender-2.62/intern/boolop/intern/BOP_Face.h 2012-02-15 19:26:37.000000000 +0000 @@ -40,12 +40,11 @@ #include "BOP_Misc.h" #include #include -using namespace std; class BOP_Face; -typedef vector BOP_Faces; -typedef vector::iterator BOP_IT_Faces; +typedef std::vector BOP_Faces; +typedef std::vector::iterator BOP_IT_Faces; class BOP_Face { diff -Nru blender-2.61/intern/boolop/intern/BOP_Indexs.h blender-2.62/intern/boolop/intern/BOP_Indexs.h --- blender-2.61/intern/boolop/intern/BOP_Indexs.h 2011-12-13 19:42:27.000000000 +0000 +++ blender-2.62/intern/boolop/intern/BOP_Indexs.h 2012-02-15 19:26:37.000000000 +0000 @@ -34,10 +34,9 @@ #define BOP_Indexs_H #include -using namespace std; typedef unsigned int BOP_Index; -typedef vector BOP_Indexs; -typedef vector::iterator BOP_IT_Indexs; +typedef std::vector BOP_Indexs; +typedef std::vector::iterator BOP_IT_Indexs; #endif diff -Nru blender-2.61/intern/boolop/intern/BOP_Interface.cpp blender-2.62/intern/boolop/intern/BOP_Interface.cpp --- blender-2.61/intern/boolop/intern/BOP_Interface.cpp 2011-12-13 19:42:27.000000000 +0000 +++ blender-2.62/intern/boolop/intern/BOP_Interface.cpp 2012-02-15 19:26:37.000000000 +0000 @@ -86,7 +86,7 @@ CSG_VertexIteratorDescriptor obBVertices) { #ifdef BOP_DEBUG - cout << "BEGIN BOP_performBooleanOperation" << endl; + std::cout << "BEGIN BOP_performBooleanOperation" << std::endl; #endif // Set invert flags depending on boolean operation type: @@ -124,7 +124,7 @@ *outputMesh = BOP_exportMesh(&meshC, invertMeshC); #ifdef BOP_DEBUG - cout << "END BOP_performBooleanOperation" << endl; + std::cout << "END BOP_performBooleanOperation" << std::endl; #endif return result; @@ -151,7 +151,7 @@ float t = 0.0f; float c = 0.0f; chrono.start(); - cout << "---" << endl; + std::cout << "---" << std::endl; #endif // Create BSPs trees for mesh A & B @@ -163,7 +163,7 @@ #ifdef BOP_DEBUG c = chrono.stamp(); t += c; - cout << "Create BSP " << c << endl; + std::cout << "Create BSP " << c << std::endl; #endif unsigned int numVertices = meshC->getNumVertexs(); @@ -179,7 +179,7 @@ #ifdef BOP_DEBUG c = chrono.stamp(); t += c; - cout << "mesh Filter " << c << endl; + std::cout << "mesh Filter " << c << std::endl; #endif // Face 2 Face @@ -187,7 +187,7 @@ #ifdef BOP_DEBUG c = chrono.stamp(); t += c; - cout << "Face2Face " << c << endl; + std::cout << "Face2Face " << c << std::endl; #endif // BSP classification @@ -196,7 +196,7 @@ #ifdef BOP_DEBUG c = chrono.stamp(); t += c; - cout << "Classification " << c << endl; + std::cout << "Classification " << c << std::endl; #endif // Process overlapped faces @@ -204,7 +204,7 @@ #ifdef BOP_DEBUG c = chrono.stamp(); t += c; - cout << "Remove overlap " << c << endl; + std::cout << "Remove overlap " << c << std::endl; #endif // Sew two meshes @@ -212,7 +212,7 @@ #ifdef BOP_DEBUG c = chrono.stamp(); t += c; - cout << "Sew " << c << endl; + std::cout << "Sew " << c << std::endl; #endif // Merge faces @@ -229,13 +229,13 @@ static int state = -1; if (G.rt == 100) { if( state != 1 ) { - cout << "Boolean code using old merge technique." << endl; + std::cout << "Boolean code using old merge technique." << std::endl; state = 1; } BOP_Merge::getInstance().mergeFaces(meshC,numVertices); } else { if( state != 0 ) { - cout << "Boolean code using new merge technique." << endl; + std::cout << "Boolean code using new merge technique." << std::endl; state = 0; } BOP_Merge2::getInstance().mergeFaces(meshC,numVertices); @@ -245,8 +245,8 @@ #ifdef BOP_DEBUG c = chrono.stamp(); t += c; - cout << "Merge faces " << c << endl; - cout << "Total " << t << endl; + std::cout << "Merge faces " << c << std::endl; + std::cout << "Total " << t << std::endl; // Test integrity meshC->testMesh(); #endif @@ -460,7 +460,7 @@ BSP_CSGMesh* mesh = BSP_CSGMesh::New(); if (mesh == NULL) return mesh; - vector* vertices = new vector; + std::vector* vertices = new std::vector; mesh->SetVertices(vertices); @@ -481,8 +481,8 @@ if (outputMesh == NULL) return NULL; // vtx index dictionary, to translate indeces from input to output. - map dic; - map::iterator itDic; + std::map dic; + std::map::iterator itDic; unsigned int count = 0; diff -Nru blender-2.61/intern/boolop/intern/BOP_MathUtils.cpp blender-2.62/intern/boolop/intern/BOP_MathUtils.cpp --- blender-2.61/intern/boolop/intern/BOP_MathUtils.cpp 2011-12-13 19:42:27.000000000 +0000 +++ blender-2.62/intern/boolop/intern/BOP_MathUtils.cpp 2012-02-15 19:26:37.000000000 +0000 @@ -34,7 +34,6 @@ #include "BOP_MathUtils.h" #include -using namespace std; /** * Compares two scalars with EPSILON accuracy. diff -Nru blender-2.61/intern/boolop/intern/BOP_Merge2.h blender-2.62/intern/boolop/intern/BOP_Merge2.h --- blender-2.61/intern/boolop/intern/BOP_Merge2.h 2011-12-13 19:42:27.000000000 +0000 +++ blender-2.62/intern/boolop/intern/BOP_Merge2.h 2012-02-15 19:26:37.000000000 +0000 @@ -42,8 +42,8 @@ #include "BOP_MathUtils.h" #include "MEM_SmartPtr.h" -typedef vector< BOP_Faces > BOP_LFaces; -typedef vector< BOP_Faces >::iterator BOP_IT_LFaces; +typedef std::vector< BOP_Faces > BOP_LFaces; +typedef std::vector< BOP_Faces >::iterator BOP_IT_LFaces; class BOP_Merge2 { private: diff -Nru blender-2.61/intern/boolop/intern/BOP_Merge.h blender-2.62/intern/boolop/intern/BOP_Merge.h --- blender-2.61/intern/boolop/intern/BOP_Merge.h 2011-12-13 19:42:27.000000000 +0000 +++ blender-2.62/intern/boolop/intern/BOP_Merge.h 2012-02-15 19:26:37.000000000 +0000 @@ -41,8 +41,8 @@ #include "BOP_MathUtils.h" #include "MEM_SmartPtr.h" -typedef vector< BOP_Faces > BOP_LFaces; -typedef vector< BOP_Faces >::iterator BOP_IT_LFaces; +typedef std::vector< BOP_Faces > BOP_LFaces; +typedef std::vector< BOP_Faces >::iterator BOP_IT_LFaces; class BOP_Merge { private: diff -Nru blender-2.61/intern/boolop/intern/BOP_Mesh.h blender-2.62/intern/boolop/intern/BOP_Mesh.h --- blender-2.61/intern/boolop/intern/BOP_Mesh.h 2011-12-13 19:42:27.000000000 +0000 +++ blender-2.62/intern/boolop/intern/BOP_Mesh.h 2012-02-15 19:26:37.000000000 +0000 @@ -40,10 +40,10 @@ #include "BOP_Face.h" #include "DNA_listBase.h" -typedef vector BOP_Vertexs; -typedef vector BOP_Edges; -typedef vector::iterator BOP_IT_Vertexs; -typedef vector::iterator BOP_IT_Edges; +typedef std::vector BOP_Vertexs; +typedef std::vector BOP_Edges; +typedef std::vector::iterator BOP_IT_Vertexs; +typedef std::vector::iterator BOP_IT_Edges; #ifdef HASH typedef struct EdgeEntry { diff -Nru blender-2.61/intern/boolop/intern/BOP_Segment.cpp blender-2.62/intern/boolop/intern/BOP_Segment.cpp --- blender-2.61/intern/boolop/intern/BOP_Segment.cpp 2011-12-13 19:42:27.000000000 +0000 +++ blender-2.62/intern/boolop/intern/BOP_Segment.cpp 2012-02-15 19:26:37.000000000 +0000 @@ -242,8 +242,8 @@ /** * Implements operator << */ -ostream &operator<<(ostream &stream, const BOP_Segment &c) +std::ostream &operator<<(std::ostream &stream, const BOP_Segment &c) { - cout << "m_v1: " << c.m_v1 << "(" << c.m_cfg1 << ") m_v2: " << c.m_v2 << "(" << c.m_cfg2 << ")"; + std::cout << "m_v1: " << c.m_v1 << "(" << c.m_cfg1 << ") m_v2: " << c.m_v2 << "(" << c.m_cfg2 << ")"; return stream; } diff -Nru blender-2.61/intern/boolop/intern/BOP_Segment.h blender-2.62/intern/boolop/intern/BOP_Segment.h --- blender-2.61/intern/boolop/intern/BOP_Segment.h 2011-12-13 19:42:27.000000000 +0000 +++ blender-2.62/intern/boolop/intern/BOP_Segment.h 2012-02-15 19:26:37.000000000 +0000 @@ -35,7 +35,6 @@ #include "BOP_Indexs.h" #include -using namespace std; class BOP_Segment { @@ -69,7 +68,7 @@ void sort(); unsigned int getConfig(); - friend ostream &operator<<(ostream &stream, const BOP_Segment &c); + friend std::ostream &operator<<(std::ostream &stream, const BOP_Segment &c); }; #endif diff -Nru blender-2.61/intern/boolop/intern/BOP_Splitter.cpp blender-2.62/intern/boolop/intern/BOP_Splitter.cpp --- blender-2.61/intern/boolop/intern/BOP_Splitter.cpp 2011-12-13 19:42:27.000000000 +0000 +++ blender-2.62/intern/boolop/intern/BOP_Splitter.cpp 2012-02-15 19:26:37.000000000 +0000 @@ -34,7 +34,6 @@ #include "BOP_Tag.h" #include -using namespace std; /** * Returns the split point resulting from intersect a plane and a mesh face diff -Nru blender-2.61/intern/boolop/intern/BOP_Triangulator.cpp blender-2.62/intern/boolop/intern/BOP_Triangulator.cpp --- blender-2.61/intern/boolop/intern/BOP_Triangulator.cpp 2011-12-13 19:42:27.000000000 +0000 +++ blender-2.62/intern/boolop/intern/BOP_Triangulator.cpp 2012-02-15 19:26:37.000000000 +0000 @@ -32,7 +32,6 @@ #include "BOP_Triangulator.h" #include -using namespace std; void BOP_addFace(BOP_Mesh* mesh, BOP_Faces *faces, BOP_Face* face, BOP_TAG tag); void BOP_splitQuad(BOP_Mesh* mesh, MT_Plane3 plane, BOP_Index v1, BOP_Index v2, BOP_Index v3, BOP_Index v4, diff -Nru blender-2.61/intern/boolop/SConscript blender-2.62/intern/boolop/SConscript --- blender-2.61/intern/boolop/SConscript 2011-12-13 19:42:27.000000000 +0000 +++ blender-2.62/intern/boolop/SConscript 2012-02-15 19:26:37.000000000 +0000 @@ -1,14 +1,31 @@ #!/usr/bin/python Import ('env') -sources = env.Glob('intern/*.cpp') - incs = '. intern extern ../moto/include ../container ../memutil' incs += ' ../../source/blender/makesdna ../../intern/guardedalloc' incs += ' ../../source/blender/blenlib' +defs = [] + +if not env['WITH_BF_CARVE']: + import os + sources = env.Glob('intern/*.cpp') + sources.remove('intern' + os.sep + 'BOP_CarveInterface.cpp') +else: + sources = env.Glob('intern/BOP_CarveInterface.cpp') + incs += ' ../../extern/carve/include' + + if env['WITH_BF_BOOST']: + if env['OURPLATFORM'] not in ('win32-vc', 'win64-vc'): + # Boost is setting as preferred collections library in the Carve code when using MSVC compiler + if env['OURPLATFORM'] != 'win32-mingw': + defs.append('HAVE_BOOST_UNORDERED_COLLECTIONS') + + defs.append('CARVE_SYSTEM_BOOST') + incs += ' ' + env['BF_BOOST_INC'] + if (env['OURPLATFORM'] == 'win32-mingw'): env.BlenderLib ('bf_intern_bop', sources, Split(incs) , [], libtype='intern', priority = 5 ) else: - env.BlenderLib ('bf_intern_bop', sources, Split(incs) , [], libtype='intern', priority = 5 ) + env.BlenderLib ('bf_intern_bop', sources, Split(incs) , defs, libtype='intern', priority = 5 ) diff -Nru blender-2.61/intern/bsp/test/BSP_GhostTest/BSP_GhostTest3D.cpp blender-2.62/intern/bsp/test/BSP_GhostTest/BSP_GhostTest3D.cpp --- blender-2.61/intern/bsp/test/BSP_GhostTest/BSP_GhostTest3D.cpp 2011-12-13 19:39:59.000000000 +0000 +++ blender-2.62/intern/bsp/test/BSP_GhostTest/BSP_GhostTest3D.cpp 2012-02-15 19:24:22.000000000 +0000 @@ -202,7 +202,7 @@ } - void + void BSP_GhostTestApp3D:: UpdateFrame( ){ @@ -210,9 +210,9 @@ GHOST_Rect v_rect; m_window->getClientBounds(v_rect); - + glViewport(0,0,v_rect.getWidth(),v_rect.getHeight()); - + } } diff -Nru blender-2.61/intern/CMakeLists.txt blender-2.62/intern/CMakeLists.txt --- blender-2.61/intern/CMakeLists.txt 2011-12-13 19:43:03.000000000 +0000 +++ blender-2.62/intern/CMakeLists.txt 2012-02-15 19:27:17.000000000 +0000 @@ -36,6 +36,10 @@ add_subdirectory(audaspace) endif() +if(WITH_MOD_REMESH) + add_subdirectory(dualcon) +endif() + if(WITH_MOD_FLUID) add_subdirectory(elbeem) endif() diff -Nru blender-2.61/intern/cycles/app/cycles_server.cpp blender-2.62/intern/cycles/app/cycles_server.cpp --- blender-2.61/intern/cycles/app/cycles_server.cpp 2011-12-13 19:39:29.000000000 +0000 +++ blender-2.62/intern/cycles/app/cycles_server.cpp 2012-02-15 19:23:46.000000000 +0000 @@ -34,8 +34,9 @@ /* device types */ string devices = ""; string devicename = "cpu"; + bool list = false; - vector types = Device::available_types(); + vector& types = Device::available_types(); foreach(DeviceType type, types) { if(devices != "") @@ -49,6 +50,7 @@ ap.options ("Usage: cycles_server [options]", "--device %s", &devicename, ("Devices to use: " + devices).c_str(), + "--list-devices", &list, "List information about all available devices", NULL); if(ap.parse(argc, argv) < 0) { @@ -56,11 +58,34 @@ ap.usage(); exit(EXIT_FAILURE); } + else if(list) { + vector& devices = Device::available_devices(); - DeviceType dtype = Device::type_from_string(devicename.c_str()); + printf("Devices:\n"); + + foreach(DeviceInfo& info, devices) { + printf(" %s%s\n", + info.description.c_str(), + (info.display_device)? " (display)": ""); + } + + exit(EXIT_SUCCESS); + } + + /* find matching device */ + DeviceType device_type = Device::type_from_string(devicename.c_str()); + vector& devices = Device::available_devices(); + DeviceInfo device_info; + + foreach(DeviceInfo& device, devices) { + if(device_type == device.type) { + device_info = device; + break; + } + } while(1) { - Device *device = Device::create(dtype); + Device *device = Device::create(device_info); printf("Cycles Server with device: %s\n", device->description().c_str()); device->server_run(); delete device; diff -Nru blender-2.61/intern/cycles/app/cycles_test.cpp blender-2.62/intern/cycles/app/cycles_test.cpp --- blender-2.61/intern/cycles/app/cycles_test.cpp 2011-12-13 19:39:29.000000000 +0000 +++ blender-2.62/intern/cycles/app/cycles_test.cpp 2012-02-15 19:23:46.000000000 +0000 @@ -82,10 +82,21 @@ session_print(status); } +static BufferParams& session_buffer_params() +{ + static BufferParams buffer_params; + buffer_params.width = options.width; + buffer_params.height = options.height; + buffer_params.full_width = options.width; + buffer_params.full_height = options.height; + + return buffer_params; +} + static void session_init() { options.session = new Session(options.session_params); - options.session->reset(options.width, options.height, options.session_params.samples); + options.session->reset(session_buffer_params(), options.session_params.samples); options.session->scene = options.scene; if(options.session_params.background && !options.quiet) @@ -98,12 +109,15 @@ options.scene = NULL; } -static void scene_init() +static void scene_init(int width, int height) { options.scene = new Scene(options.scene_params); xml_read_file(options.scene, options.filepath.c_str()); - options.width = options.scene->camera->width; - options.height = options.scene->camera->height; + + if (width == 0 || height == 0) { + options.width = options.scene->camera->width; + options.height = options.scene->camera->height; + } } static void session_exit() @@ -151,7 +165,7 @@ static void display() { - options.session->draw(options.width, options.height); + options.session->draw(session_buffer_params()); display_info(options.session->progress); } @@ -162,13 +176,13 @@ options.height= height; if(options.session) - options.session->reset(options.width, options.height, options.session_params.samples); + options.session->reset(session_buffer_params(), options.session_params.samples); } void keyboard(unsigned char key) { if(key == 'r') - options.session->reset(options.width, options.height, options.session_params.samples); + options.session->reset(session_buffer_params(), options.session_params.samples); else if(key == 27) // escape options.session->progress.set_cancel("Cancelled"); } @@ -183,23 +197,24 @@ static void options_parse(int argc, const char **argv) { - options.width= 1024; - options.height= 512; + options.width= 0; + options.height= 0; options.filepath = ""; options.session = NULL; options.quiet = false; - /* devices */ - string devices = ""; + /* device names */ + string device_names = ""; string devicename = "cpu"; + bool list = false; - vector types = Device::available_types(); + vector& types = Device::available_types(); foreach(DeviceType type, types) { - if(devices != "") - devices += ", "; + if(device_names != "") + device_names += ", "; - devices += Device::string_from_type(type); + device_names += Device::string_from_type(type); } /* shading system */ @@ -216,13 +231,16 @@ ap.options ("Usage: cycles_test [options] file.xml", "%*", files_parse, "", - "--device %s", &devicename, ("Devices to use: " + devices).c_str(), + "--device %s", &devicename, ("Devices to use: " + device_names).c_str(), "--shadingsys %s", &ssname, "Shading system to use: svm, osl", "--background", &options.session_params.background, "Render in background, without user interface", "--quiet", &options.quiet, "In background mode, don't print progress messages", "--samples %d", &options.session_params.samples, "Number of samples to render", "--output %s", &options.session_params.output_path, "File path to write output image", "--threads %d", &options.session_params.threads, "CPU Rendering Threads", + "--width %d", &options.width, "Window width in pixel", + "--height %d", &options.height, "Window height in pixel", + "--list-devices", &list, "List information about all available devices", "--help", &help, "Print help message", NULL); @@ -231,26 +249,44 @@ ap.usage(); exit(EXIT_FAILURE); } + else if(list) { + vector& devices = Device::available_devices(); + printf("Devices:\n"); + + foreach(DeviceInfo& info, devices) { + printf(" %s%s\n", + info.description.c_str(), + (info.display_device)? " (display)": ""); + } + + exit(EXIT_SUCCESS); + } else if(help || options.filepath == "") { ap.usage(); exit(EXIT_SUCCESS); } - options.session_params.device_type = Device::type_from_string(devicename.c_str()); - if(ssname == "osl") options.scene_params.shadingsystem = SceneParams::OSL; else if(ssname == "svm") options.scene_params.shadingsystem = SceneParams::SVM; - /* handle invalid configurations */ - bool type_available = false; - - foreach(DeviceType dtype, types) - if(options.session_params.device_type == dtype) - type_available = true; + /* find matching device */ + DeviceType device_type = Device::type_from_string(devicename.c_str()); + vector& devices = Device::available_devices(); + DeviceInfo device_info; + bool device_available = false; + + foreach(DeviceInfo& device, devices) { + if(device_type == device.type) { + options.session_params.device = device; + device_available = true; + break; + } + } - if(options.session_params.device_type == DEVICE_NONE || !type_available) { + /* handle invalid configurations */ + if(options.session_params.device.type == DEVICE_NONE || !device_available) { fprintf(stderr, "Unknown device: %s\n", devicename.c_str()); exit(EXIT_FAILURE); } @@ -262,7 +298,7 @@ fprintf(stderr, "Unknown shading system: %s\n", ssname.c_str()); exit(EXIT_FAILURE); } - else if(options.scene_params.shadingsystem == SceneParams::OSL && options.session_params.device_type != DEVICE_CPU) { + else if(options.scene_params.shadingsystem == SceneParams::OSL && options.session_params.device.type != DEVICE_CPU) { fprintf(stderr, "OSL shading system only works with CPU device\n"); exit(EXIT_FAILURE); } @@ -276,7 +312,7 @@ } /* load scene */ - scene_init(); + scene_init(options.width, options.height); } CCL_NAMESPACE_END diff -Nru blender-2.61/intern/cycles/app/cycles_xml.cpp blender-2.62/intern/cycles/app/cycles_xml.cpp --- blender-2.61/intern/cycles/app/cycles_xml.cpp 2011-12-13 19:39:29.000000000 +0000 +++ blender-2.62/intern/cycles/app/cycles_xml.cpp 2012-02-15 19:23:46.000000000 +0000 @@ -257,8 +257,18 @@ xml_read_int(&integrator->min_bounce, node, "min_bounce"); xml_read_int(&integrator->max_bounce, node, "max_bounce"); + + xml_read_int(&integrator->max_diffuse_bounce, node, "max_diffuse_bounce"); + xml_read_int(&integrator->max_glossy_bounce, node, "max_glossy_bounce"); + xml_read_int(&integrator->max_transmission_bounce, node, "max_transmission_bounce"); + + xml_read_int(&integrator->transparent_min_bounce, node, "transparent_min_bounce"); + xml_read_int(&integrator->transparent_max_bounce, node, "transparent_max_bounce"); + + xml_read_bool(&integrator->transparent_shadows, node, "transparent_shadows"); xml_read_bool(&integrator->no_caustics, node, "no_caustics"); - xml_read_float(&integrator->blur_caustics, node, "blur_caustics"); + + xml_read_int(&integrator->seed, node, "seed"); } /* Camera */ @@ -339,6 +349,9 @@ else if(string_iequals(node.name(), "noise_texture")) { snode = new NoiseTextureNode(); } + else if(string_iequals(node.name(), "checker_texture")) { + snode = new CheckerTextureNode(); + } else if(string_iequals(node.name(), "gradient_texture")) { GradientTextureNode *blend = new GradientTextureNode(); xml_read_enum(&blend->type, GradientTextureNode::type_enum, node, "type"); @@ -368,6 +381,9 @@ xml_read_enum(&wood->type, WaveTextureNode::type_enum, node, "type"); snode = wood; } + else if(string_iequals(node.name(), "normal")) { + snode = new NormalNode(); + } else if(string_iequals(node.name(), "mapping")) { snode = new MappingNode(); } @@ -443,6 +459,12 @@ xml_read_enum(&mix->type, MixNode::type_enum, node, "type"); snode = mix; } + else if(string_iequals(node.name(), "gamma")) { + snode = new GammaNode(); + } + else if(string_iequals(node.name(), "brightness")) { + snode = new BrightContrastNode(); + } else if(string_iequals(node.name(), "combine_rgb")) { snode = new CombineRGBNode(); } diff -Nru blender-2.61/intern/cycles/app/io_export_cycles_xml.py blender-2.62/intern/cycles/app/io_export_cycles_xml.py --- blender-2.61/intern/cycles/app/io_export_cycles_xml.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/intern/cycles/app/io_export_cycles_xml.py 2012-02-15 19:23:46.000000000 +0000 @@ -0,0 +1,143 @@ +# +# Copyright 2011, Blender Foundation. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the 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. +# + +# XML exporter for generating test files, not intended for end users + +import os +import xml.etree.ElementTree as etree +import xml.dom.minidom as dom + +import bpy +from bpy_extras.io_utils import ExportHelper +from bpy.props import PointerProperty, StringProperty + +def strip(root): + root.text = None + root.tail = None + + for elem in root: + strip(elem) + +def write(node, fname): + strip(node) + + s = etree.tostring(node) + s = dom.parseString(s).toprettyxml() + + f = open(fname, "w") + f.write(s) + +class CyclesXMLSettings(bpy.types.PropertyGroup): + @classmethod + def register(cls): + bpy.types.Scene.cycles_xml = PointerProperty( + type=cls, + name="Cycles XML export Settings", + description="Cycles XML export settings") + cls.filepath = StringProperty( + name='Filepath', + description='Filepath for the .xml file', + maxlen=256, + default='', + subtype='FILE_PATH') + + @classmethod + def unregister(cls): + del bpy.types.Scene.cycles_xml + +# User Interface Drawing Code +class RenderButtonsPanel(): + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = "render" + + @classmethod + def poll(self, context): + rd = context.scene.render + return rd.engine == 'CYCLES' + + +class PHYSICS_PT_fluid_export(RenderButtonsPanel, bpy.types.Panel): + bl_label = "Cycles XML Exporter" + + def draw(self, context): + layout = self.layout + + cycles = context.scene.cycles_xml + + #layout.prop(cycles, "filepath") + layout.operator("export_mesh.cycles_xml") + + +# Export Operator +class ExportCyclesXML(bpy.types.Operator, ExportHelper): + bl_idname = "export_mesh.cycles_xml" + bl_label = "Export Cycles XML" + + filename_ext = ".xml" + + @classmethod + def poll(cls, context): + return (context.active_object is not None) + + def execute(self, context): + filepath = bpy.path.ensure_ext(self.filepath, ".xml") + + # get mesh + scene = context.scene + object = context.active_object + + if not object: + raise Exception("No active object") + + mesh = object.to_mesh(scene, True, 'PREVIEW') + + if not mesh: + raise Exception("No mesh data in active object") + + # generate mesh node + nverts = "" + verts = "" + P = "" + + for v in mesh.vertices: + P += "%f %f %f " % (v.co[0], v.co[1], v.co[2]) + + for i, f in enumerate(mesh.faces): + nverts += str(len(f.vertices)) + " " + + for v in f.vertices: + verts += str(v) + " " + verts += " " + + node = etree.Element('mesh', attrib={'nverts': nverts, 'verts': verts, 'P': P}) + + # write to file + write(node, filepath) + + return {'FINISHED'} + +def register(): + bpy.utils.register_module(__name__) + +def unregister(): + bpy.utils.unregister_module(__name__) + +if __name__ == "__main__": + register() + diff -Nru blender-2.61/intern/cycles/blender/addon/engine.py blender-2.62/intern/cycles/blender/addon/engine.py --- blender-2.61/intern/cycles/blender/addon/engine.py 2011-12-13 19:39:47.000000000 +0000 +++ blender-2.62/intern/cycles/blender/addon/engine.py 2012-02-15 19:24:07.000000000 +0000 @@ -22,19 +22,20 @@ def init(): - import bcycles + import _cycles import os.path path = os.path.dirname(__file__) user_path = os.path.dirname(os.path.abspath(bpy.utils.user_resource('CONFIG', ''))) - bcycles.init(path, user_path) + _cycles.init(path, user_path) def create(engine, data, scene, region=0, v3d=0, rv3d=0): - import bcycles + import _cycles data = data.as_pointer() + userpref = bpy.context.user_preferences.as_pointer() scene = scene.as_pointer() if region: region = region.as_pointer() @@ -43,46 +44,42 @@ if rv3d: rv3d = rv3d.as_pointer() - engine.session = bcycles.create(engine.as_pointer(), data, scene, region, v3d, rv3d) + engine.session = _cycles.create(engine.as_pointer(), userpref, data, scene, region, v3d, rv3d) def free(engine): if hasattr(engine, "session"): if engine.session: - import bcycles - bcycles.free(engine.session) + import _cycles + _cycles.free(engine.session) del engine.session def render(engine): - import bcycles + import _cycles if hasattr(engine, "session"): - bcycles.render(engine.session) + _cycles.render(engine.session) def update(engine, data, scene): - import bcycles - if scene.render.use_border: - engine.report({'ERROR'}, "Border rendering not supported yet") - free(engine) - else: - bcycles.sync(engine.session) + import _cycles + _cycles.sync(engine.session) def draw(engine, region, v3d, rv3d): - import bcycles + import _cycles v3d = v3d.as_pointer() rv3d = rv3d.as_pointer() # draw render image - bcycles.draw(engine.session, v3d, rv3d) + _cycles.draw(engine.session, v3d, rv3d) def available_devices(): - import bcycles - return bcycles.available_devices() + import _cycles + return _cycles.available_devices() def with_osl(): - import bcycles - return bcycles.with_osl() + import _cycles + return _cycles.with_osl diff -Nru blender-2.61/intern/cycles/blender/addon/enums.py blender-2.62/intern/cycles/blender/addon/enums.py --- blender-2.61/intern/cycles/blender/addon/enums.py 2011-12-13 19:39:47.000000000 +0000 +++ blender-2.62/intern/cycles/blender/addon/enums.py 2012-02-15 19:24:07.000000000 +0000 @@ -20,29 +20,9 @@ from . import engine - -def get_gpu_device(): - available_devices = engine.available_devices() - cuda = 'cuda' in available_devices - opencl = 'opencl' in available_devices - if cuda and opencl: - gpu_string = "GPU" - elif cuda and not opencl: - gpu_string = "CUDA GPU" - else: - gpu_string = "OpenCL GPU" - - return gpu_string - devices = ( - ("CPU", "CPU", "Processor"), - ("GPU", get_gpu_device(), "Graphics card"), - ) - -gpu_type = ( - ("CUDA", "CUDA", "NVidia only"), - ("OPENCL", "OpenCL", ""), - ) + ("CPU", "CPU", "Use CPU for rendering"), + ("GPU", "GPU Compute", "Use GPU compute device for rendering, configured in user preferences")) feature_set = ( ("SUPPORTED", "Supported", "Only use finished and supported features"), diff -Nru blender-2.61/intern/cycles/blender/addon/__init__.py blender-2.62/intern/cycles/blender/addon/__init__.py --- blender-2.61/intern/cycles/blender/addon/__init__.py 2011-12-13 19:39:47.000000000 +0000 +++ blender-2.62/intern/cycles/blender/addon/__init__.py 2012-02-15 19:24:07.000000000 +0000 @@ -23,7 +23,6 @@ "author": "", "version": (0, 0), "blender": (2, 6, 0), - "api": 41670, "location": "Info header, render engine menu", "description": "Cycles Render Engine integration.", "warning": "", diff -Nru blender-2.61/intern/cycles/blender/addon/properties.py blender-2.62/intern/cycles/blender/addon/properties.py --- blender-2.61/intern/cycles/blender/addon/properties.py 2011-12-13 19:39:47.000000000 +0000 +++ blender-2.62/intern/cycles/blender/addon/properties.py 2012-02-15 19:24:07.000000000 +0000 @@ -33,79 +33,189 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): @classmethod def register(cls): - bpy.types.Scene.cycles = PointerProperty(type=cls, name="Cycles Render Settings", description="Cycles render settings") - - cls.device = EnumProperty(name="Device", description="Device to use for rendering", - items=enums.devices, default="CPU") - - cls.gpu_type = EnumProperty(name="GPU Type", description="Processing system to use on the GPU", - items=enums.gpu_type, default="CUDA") - - cls.feature_set = EnumProperty(name="Feature Set", description="Feature set to use for rendering", - items=enums.feature_set, default="SUPPORTED") - - cls.shading_system = EnumProperty(name="Shading System", description="Shading system to use for rendering", - items=enums.shading_systems, default="GPU_COMPATIBLE") - - cls.samples = IntProperty(name="Samples", description="Number of samples to render for each pixel", - default=10, min=1, max=2147483647) - cls.preview_samples = IntProperty(name="Preview Samples", description="Number of samples to render in the viewport, unlimited if 0", - default=10, min=0, max=2147483647) - cls.preview_pause = BoolProperty(name="Pause Preview", description="Pause all viewport preview renders", - default=False) - - cls.no_caustics = BoolProperty(name="No Caustics", description="Leave out caustics, resulting in a darker image with less noise", - default=False) - cls.blur_caustics = FloatProperty(name="Blur Caustics", description="Blur caustics to reduce noise", - default=0.0, min=0.0, max=1.0) - - cls.min_bounces = IntProperty(name="Min Bounces", description="Minimum number of bounces, setting this lower than the maximum enables probalistic path termination (faster but noisier)", - default=3, min=0, max=1024) - cls.max_bounces = IntProperty(name="Max Bounces", description="Total maximum number of bounces", - default=8, min=0, max=1024) - - cls.diffuse_bounces = IntProperty(name="Diffuse Bounces", description="Maximum number of diffuse reflection bounces, bounded by total maximum", - default=128, min=0, max=1024) - cls.glossy_bounces = IntProperty(name="Glossy Bounces", description="Maximum number of glossy reflection bounces, bounded by total maximum", - default=128, min=0, max=1024) - cls.transmission_bounces = IntProperty(name="Transmission Bounces", description="Maximum number of transmission bounces, bounded by total maximum", - default=128, min=0, max=1024) - - cls.transparent_min_bounces = IntProperty(name="Transparent Min Bounces", description="Minimum number of transparent bounces, setting this lower than the maximum enables probalistic path termination (faster but noisier)", - default=8, min=0, max=1024) - cls.transparent_max_bounces = IntProperty(name="Transparent Max Bounces", description="Maximum number of transparent bounces", - default=8, min=0, max=1024) - cls.use_transparent_shadows = BoolProperty(name="Transparent Shadows", description="Use transparency of surfaces for rendering shadows", - default=True) - - cls.film_exposure = FloatProperty(name="Exposure", description="Image brightness scale", - default=1.0, min=0.0, max=10.0) - cls.film_transparent = BoolProperty(name="Transparent", description="World background is transparent", - default=False) - - cls.filter_type = EnumProperty(name="Filter Type", description="Pixel filter type", - items=enums.filter_types, default="GAUSSIAN") - cls.filter_width = FloatProperty(name="Filter Width", description="Pixel filter width", - default=1.5, min=0.01, max=10.0) - - cls.seed = IntProperty(name="Seed", description="Seed value for integrator to get different noise patterns", - default=0, min=0, max=2147483647) - - cls.debug_tile_size = IntProperty(name="Tile Size", description="", - default=1024, min=1, max=4096) - cls.debug_min_size = IntProperty(name="Min Size", description="", - default=64, min=1, max=4096) - cls.debug_reset_timeout = FloatProperty(name="Reset timeout", description="", - default=0.1, min=0.01, max=10.0) - cls.debug_cancel_timeout = FloatProperty(name="Cancel timeout", description="", - default=0.1, min=0.01, max=10.0) - cls.debug_text_timeout = FloatProperty(name="Text timeout", description="", - default=1.0, min=0.01, max=10.0) - - cls.debug_bvh_type = EnumProperty(name="Viewport BVH Type", description="Choose between faster updates, or faster render", - items=enums.bvh_types, default="DYNAMIC_BVH") - cls.debug_use_spatial_splits = BoolProperty(name="Use Spatial Splits", description="Use BVH spatial splits: longer builder time, faster render", - default=False) + bpy.types.Scene.cycles = PointerProperty( + name="Cycles Render Settings", + description="Cycles render settings", + type=cls, + ) + cls.device = EnumProperty( + name="Device", + description="Device to use for rendering", + items=enums.devices, + default='CPU', + ) + cls.feature_set = EnumProperty( + name="Feature Set", + description="Feature set to use for rendering", + items=enums.feature_set, + default='SUPPORTED', + ) + cls.shading_system = EnumProperty( + name="Shading System", + description="Shading system to use for rendering", + items=enums.shading_systems, + default='GPU_COMPATIBLE', + ) + + cls.samples = IntProperty( + name="Samples", + description="Number of samples to render for each pixel", + min=1, max=2147483647, + default=10, + ) + cls.preview_samples = IntProperty( + name="Preview Samples", + description="Number of samples to render in the viewport, unlimited if 0", + min=0, max=2147483647, + default=10, + ) + cls.preview_pause = BoolProperty( + name="Pause Preview", + description="Pause all viewport preview renders", + default=False, + ) + + cls.no_caustics = BoolProperty( + name="No Caustics", + description="Leave out caustics, resulting in a darker image with less noise", + default=False, + ) + cls.blur_caustics = FloatProperty( + name="Blur Caustics", + description="Blur caustics to reduce noise", + min=0.0, max=1.0, + default=0.0, + ) + + cls.min_bounces = IntProperty( + name="Min Bounces", + description="Minimum number of bounces, setting this lower than the maximum enables probalistic path termination (faster but noisier)", + min=0, max=1024, + default=3, + ) + cls.max_bounces = IntProperty( + name="Max Bounces", + description="Total maximum number of bounces", + min=0, max=1024, + default=8, + ) + + cls.diffuse_bounces = IntProperty( + name="Diffuse Bounces", + description="Maximum number of diffuse reflection bounces, bounded by total maximum", + min=0, max=1024, + default=128, + ) + cls.glossy_bounces = IntProperty( + name="Glossy Bounces", + description="Maximum number of glossy reflection bounces, bounded by total maximum", + min=0, max=1024, + default=128, + ) + cls.transmission_bounces = IntProperty( + name="Transmission Bounces", + description="Maximum number of transmission bounces, bounded by total maximum", + min=0, max=1024, + default=128, + ) + + cls.transparent_min_bounces = IntProperty( + name="Transparent Min Bounces", + description="Minimum number of transparent bounces, setting this lower than the maximum enables probalistic path termination (faster but noisier)", + min=0, max=1024, + default=8, + ) + cls.transparent_max_bounces = IntProperty( + name="Transparent Max Bounces", + description="Maximum number of transparent bounces", + min=0, max=1024, + default=8, + ) + cls.use_transparent_shadows = BoolProperty( + name="Transparent Shadows", + description="Use transparency of surfaces for rendering shadows", + default=True, + ) + + cls.film_exposure = FloatProperty( + name="Exposure", + description="Image brightness scale", + min=0.0, max=10.0, + default=1.0, + ) + cls.film_transparent = BoolProperty( + name="Transparent", + description="World background is transparent", + default=False, + ) + + cls.filter_type = EnumProperty( + name="Filter Type", + description="Pixel filter type", + items=enums.filter_types, + default='GAUSSIAN', + ) + cls.filter_width = FloatProperty( + name="Filter Width", + description="Pixel filter width", + min=0.01, max=10.0, + default=1.5, + ) + + cls.seed = IntProperty( + name="Seed", + description="Seed value for integrator to get different noise patterns", + min=0, max=2147483647, + default=0, + ) + + cls.debug_tile_size = IntProperty( + name="Tile Size", + description="", + min=1, max=4096, + default=1024, + ) + cls.debug_min_size = IntProperty( + name="Min Size", + description="", + min=1, max=4096, + default=64, + ) + cls.debug_reset_timeout = FloatProperty( + name="Reset timeout", + description="", + min=0.01, max=10.0, + default=0.1, + ) + cls.debug_cancel_timeout = FloatProperty( + name="Cancel timeout", + description="", + min=0.01, max=10.0, + default=0.1, + ) + cls.debug_text_timeout = FloatProperty( + name="Text timeout", + description="", + min=0.01, max=10.0, + default=1.0, + ) + + cls.debug_bvh_type = EnumProperty( + name="Viewport BVH Type", + description="Choose between faster updates, or faster render", + items=enums.bvh_types, + default='DYNAMIC_BVH', + ) + cls.debug_use_spatial_splits = BoolProperty( + name="Use Spatial Splits", + description="Use BVH spatial splits: longer builder time, faster render", + default=False, + ) + cls.use_cache = BoolProperty( + name="Cache BVH", + description="Cache last built BVH to disk for faster re-render if no geometry changed", + default=False, + ) @classmethod def unregister(cls): @@ -115,14 +225,31 @@ class CyclesCameraSettings(bpy.types.PropertyGroup): @classmethod def register(cls): - bpy.types.Camera.cycles = PointerProperty(type=cls, name="Cycles Camera Settings", description="Cycles camera settings") - - cls.aperture_size = FloatProperty(name="Aperture Size", description="Radius of the aperture for depth of field", - default=0.0, min=0.0, max=10.0) - cls.aperture_blades = IntProperty(name="Aperture Blades", description="Number of blades in aperture for polygonal bokeh (at least 3)", - default=0, min=0, max=100) - cls.aperture_rotation = FloatProperty(name="Aperture Rotation", description="Rotation of blades in aperture", - default=0, soft_min=-math.pi, soft_max=math.pi, subtype='ANGLE') + bpy.types.Camera.cycles = PointerProperty( + name="Cycles Camera Settings", + description="Cycles camera settings", + type=cls, + ) + + cls.aperture_size = FloatProperty( + name="Aperture Size", + description="Radius of the aperture for depth of field", + min=0.0, max=10.0, + default=0.0, + ) + cls.aperture_blades = IntProperty( + name="Aperture Blades", + description="Number of blades in aperture for polygonal bokeh (at least 3)", + min=0, max=100, + default=0, + ) + cls.aperture_rotation = FloatProperty( + name="Aperture Rotation", + description="Rotation of blades in aperture", + soft_min=-math.pi, soft_max=math.pi, + subtype='ANGLE', + default=0, + ) @classmethod def unregister(cls): @@ -132,9 +259,21 @@ class CyclesMaterialSettings(bpy.types.PropertyGroup): @classmethod def register(cls): - bpy.types.Material.cycles = PointerProperty(type=cls, name="Cycles Material Settings", description="Cycles material settings") - cls.sample_as_light = BoolProperty(name="Sample as Lamp", description="Use direct light sampling for this material, disabling may reduce overall noise for large objects that emit little light compared to other light sources", default=True) - cls.homogeneous_volume = BoolProperty(name="Homogeneous Volume", description="When using volume rendering, assume volume has the same density everywhere, for faster rendering", default=False) + bpy.types.Material.cycles = PointerProperty( + name="Cycles Material Settings", + description="Cycles material settings", + type=cls, + ) + cls.sample_as_light = BoolProperty( + name="Sample as Lamp", + description="Use direct light sampling for this material, disabling may reduce overall noise for large objects that emit little light compared to other light sources", + default=True, + ) + cls.homogeneous_volume = BoolProperty( + name="Homogeneous Volume", + description="When using volume rendering, assume volume has the same density everywhere, for faster rendering", + default=False, + ) @classmethod def unregister(cls): @@ -144,8 +283,16 @@ class CyclesLampSettings(bpy.types.PropertyGroup): @classmethod def register(cls): - bpy.types.Lamp.cycles = PointerProperty(type=cls, name="Cycles Lamp Settings", description="Cycles lamp settings") - cls.cast_shadow = BoolProperty(name="Cast Shadow", description="Lamp casts shadows", default=True) + bpy.types.Lamp.cycles = PointerProperty( + name="Cycles Lamp Settings", + description="Cycles lamp settings", + type=cls, + ) + cls.cast_shadow = BoolProperty( + name="Cast Shadow", + description="Lamp casts shadows", + default=True, + ) @classmethod def unregister(cls): @@ -155,7 +302,22 @@ class CyclesWorldSettings(bpy.types.PropertyGroup): @classmethod def register(cls): - bpy.types.World.cycles = PointerProperty(type=cls, name="Cycles World Settings", description="Cycles world settings") + bpy.types.World.cycles = PointerProperty( + name="Cycles World Settings", + description="Cycles world settings", + type=cls, + ) + cls.sample_as_light = BoolProperty( + name="Sample as Lamp", + description="Use direct light sampling for the environment, enabling for non-solid colors is recommended", + default=False, + ) + cls.sample_map_resolution = IntProperty( + name="Map Resolution", + description="Importance map size is resolution x resolution; higher values potentially produce less noise, at the cost of memory and speed", + min=4, max=8096, + default=256, + ) @classmethod def unregister(cls): @@ -165,13 +327,37 @@ class CyclesVisibilitySettings(bpy.types.PropertyGroup): @classmethod def register(cls): - bpy.types.Object.cycles_visibility = PointerProperty(type=cls, name="Cycles Visibility Settings", description="Cycles visibility settings") - - cls.camera = BoolProperty(name="Camera", description="Object visibility for camera rays", default=True) - cls.diffuse = BoolProperty(name="Diffuse", description="Object visibility for diffuse reflection rays", default=True) - cls.glossy = BoolProperty(name="Glossy", description="Object visibility for glossy reflection rays", default=True) - cls.transmission = BoolProperty(name="Transmission", description="Object visibility for transmission rays", default=True) - cls.shadow = BoolProperty(name="Shadow", description="Object visibility for shadow rays", default=True) + bpy.types.Object.cycles_visibility = PointerProperty( + name="Cycles Visibility Settings", + description="Cycles visibility settings", + type=cls, + ) + + cls.camera = BoolProperty( + name="Camera", + description="Object visibility for camera rays", + default=True, + ) + cls.diffuse = BoolProperty( + name="Diffuse", + description="Object visibility for diffuse reflection rays", + default=True, + ) + cls.glossy = BoolProperty( + name="Glossy", + description="Object visibility for glossy reflection rays", + default=True, + ) + cls.transmission = BoolProperty( + name="Transmission", + description="Object visibility for transmission rays", + default=True, + ) + cls.shadow = BoolProperty( + name="Shadow", + description="Object visibility for shadow rays", + default=True, + ) @classmethod def unregister(cls): @@ -181,15 +367,39 @@ class CyclesMeshSettings(bpy.types.PropertyGroup): @classmethod def register(cls): - bpy.types.Mesh.cycles = PointerProperty(type=cls, name="Cycles Mesh Settings", description="Cycles mesh settings") - bpy.types.Curve.cycles = PointerProperty(type=cls, name="Cycles Mesh Settings", description="Cycles mesh settings") - bpy.types.MetaBall.cycles = PointerProperty(type=cls, name="Cycles Mesh Settings", description="Cycles mesh settings") - - cls.displacement_method = EnumProperty(name="Displacement Method", description="Method to use for the displacement", - items=enums.displacement_methods, default="BUMP") - cls.use_subdivision = BoolProperty(name="Use Subdivision", description="Subdivide mesh for rendering", - default=False) - cls.dicing_rate = FloatProperty(name="Dicing Rate", description="", default=1.0, min=0.001, max=1000.0) + bpy.types.Mesh.cycles = PointerProperty( + name="Cycles Mesh Settings", + description="Cycles mesh settings", + type=cls, + ) + bpy.types.Curve.cycles = PointerProperty( + name="Cycles Mesh Settings", + description="Cycles mesh settings", + type=cls, + ) + bpy.types.MetaBall.cycles = PointerProperty( + name="Cycles Mesh Settings", + description="Cycles mesh settings", + type=cls, + ) + + cls.displacement_method = EnumProperty( + name="Displacement Method", + description="Method to use for the displacement", + items=enums.displacement_methods, + default='BUMP', + ) + cls.use_subdivision = BoolProperty( + name="Use Subdivision", + description="Subdivide mesh for rendering", + default=False, + ) + cls.dicing_rate = FloatProperty( + name="Dicing Rate", + description="", + min=0.001, max=1000.0, + default=1.0, + ) @classmethod def unregister(cls): diff -Nru blender-2.61/intern/cycles/blender/addon/ui.py blender-2.62/intern/cycles/blender/addon/ui.py --- blender-2.61/intern/cycles/blender/addon/ui.py 2011-12-13 19:39:47.000000000 +0000 +++ blender-2.62/intern/cycles/blender/addon/ui.py 2012-02-15 19:24:07.000000000 +0000 @@ -147,6 +147,7 @@ sub.label(text="Acceleration structure:") sub.prop(cscene, "debug_bvh_type", text="") sub.prop(cscene, "debug_use_spatial_splits") + sub.prop(cscene, "use_cache") class CyclesRender_PT_layers(CyclesButtonsPanel, Panel): @@ -160,18 +161,17 @@ scene = context.scene rd = scene.render - # row = layout.row() - # row.template_list(rd, "layers", rd.layers, "active_index", rows=2) + row = layout.row() + row.template_list(rd, "layers", rd.layers, "active_index", rows=2) - # col = row.column(align=True) - # col.operator("scene.render_layer_add", icon='ZOOMIN', text="") - # col.operator("scene.render_layer_remove", icon='ZOOMOUT', text="") + col = row.column(align=True) + col.operator("scene.render_layer_add", icon='ZOOMIN', text="") + col.operator("scene.render_layer_remove", icon='ZOOMOUT', text="") row = layout.row() - # rl = rd.layers.active - rl = rd.layers[0] + rl = rd.layers.active row.prop(rl, "name") - #row.prop(rd, "use_single_layer", text="", icon_only=True) + row.prop(rd, "use_single_layer", text="", icon_only=True) split = layout.split() @@ -183,6 +183,39 @@ layout.separator() + split = layout.split() + + col = split.column() + col.label(text="Passes:") + col.prop(rl, "use_pass_combined") + col.prop(rl, "use_pass_z") + col.prop(rl, "use_pass_normal") + col.prop(rl, "use_pass_object_index") + col.prop(rl, "use_pass_material_index") + col.prop(rl, "use_pass_emit") + col.prop(rl, "use_pass_environment") + + col = split.column() + col.label() + col.label(text="Diffuse:") + row = col.row(align=True) + row.prop(rl, "use_pass_diffuse_direct", text="Direct", toggle=True) + row.prop(rl, "use_pass_diffuse_indirect", text="Indirect", toggle=True) + row.prop(rl, "use_pass_diffuse_color", text="Color", toggle=True) + col.label(text="Glossy:") + row = col.row(align=True) + row.prop(rl, "use_pass_glossy_direct", text="Direct", toggle=True) + row.prop(rl, "use_pass_glossy_indirect", text="Indirect", toggle=True) + row.prop(rl, "use_pass_glossy_color", text="Color", toggle=True) + col.label(text="Transmission:") + row = col.row(align=True) + row.prop(rl, "use_pass_transmission_direct", text="Direct", toggle=True) + row.prop(rl, "use_pass_transmission_indirect", text="Indirect", toggle=True) + row.prop(rl, "use_pass_transmission_color", text="Color", toggle=True) + + layout.separator() + + rl = rd.layers[0] layout.prop(rl, "material_override", text="Material") @@ -240,7 +273,7 @@ class Cycles_PT_context_material(CyclesButtonsPanel, Panel): - bl_label = "Surface" + bl_label = "" bl_context = "material" bl_options = {'HIDE_HEADER'} @@ -336,16 +369,13 @@ ob = context.object visibility = ob.cycles_visibility - split = layout.split() + flow = layout.column_flow() - col = split.column() - col.prop(visibility, "camera") - col.prop(visibility, "diffuse") - col.prop(visibility, "glossy") - - col = split.column() - col.prop(visibility, "transmission") - col.prop(visibility, "shadow") + flow.prop(visibility, "camera") + flow.prop(visibility, "diffuse") + flow.prop(visibility, "glossy") + flow.prop(visibility, "transmission") + flow.prop(visibility, "shadow") def find_node(material, nodetype): @@ -452,10 +482,34 @@ layout = self.layout world = context.world + if not panel_node_draw(layout, world, 'OUTPUT_WORLD', 'Surface'): layout.prop(world, "horizon_color", text="Color") +class CyclesWorld_PT_settings(CyclesButtonsPanel, Panel): + bl_label = "Settings" + bl_context = "world" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + return context.world and CyclesButtonsPanel.poll(context) + + def draw(self, context): + layout = self.layout + + world = context.world + cworld = world.cycles + + col = layout.column() + + col.prop(cworld, "sample_as_light") + row = col.row() + row.active = cworld.sample_as_light + row.prop(cworld, "sample_map_resolution") + + class CyclesWorld_PT_volume(CyclesButtonsPanel, Panel): bl_label = "Volume" bl_context = "world" @@ -552,6 +606,7 @@ col = split.column() col.prop(cmat, "sample_as_light") + col.prop(mat, "pass_index") class CyclesTexture_PT_context(CyclesButtonsPanel, Panel): @@ -588,14 +643,9 @@ col.template_ID(user, "texture", new="texture.new") if tex: - row = split.row() - row.prop(tex, "use_nodes", icon="NODETREE", text="") - row.label() - - if not tex.use_nodes: - split = layout.split(percentage=0.2) - split.label(text="Type:") - split.prop(tex, "type", text="") + split = layout.split(percentage=0.2) + split.label(text="Type:") + split.prop(tex, "type", text="") class CyclesTexture_PT_nodes(CyclesButtonsPanel, Panel): @@ -708,22 +758,16 @@ scene = context.scene layout = self.layout - if scene.render.engine == "CYCLES": + if scene.render.engine == 'CYCLES': cscene = scene.cycles layout.prop(cscene, "feature_set") - experimental = cscene.feature_set == 'EXPERIMENTAL' - available_devices = engine.available_devices() - available_cuda = 'cuda' in available_devices - available_opencl = experimental and 'opencl' in available_devices - - if available_cuda or available_opencl: + device_type = context.user_preferences.system.compute_device_type + if device_type == 'CUDA': + layout.prop(cscene, "device") + elif device_type == 'OPENCL' and cscene.feature_set == 'EXPERIMENTAL': layout.prop(cscene, "device") - if cscene.device == 'GPU' and available_cuda and available_opencl: - layout.prop(cscene, "gpu_type") - if experimental and cscene.device == 'CPU' and engine.with_osl(): - layout.prop(cscene, "shading_system") def draw_pause(self, context): @@ -733,7 +777,7 @@ if scene.render.engine == "CYCLES": view = context.space_data - if view.viewport_shade == "RENDERED": + if view.viewport_shade == 'RENDERED': cscene = scene.cycles layout.prop(cscene, "preview_pause", icon="PAUSE", text="") @@ -745,6 +789,12 @@ bpy.types.RENDER_PT_encoding, bpy.types.RENDER_PT_dimensions, bpy.types.RENDER_PT_stamp, + bpy.types.SCENE_PT_scene, + bpy.types.SCENE_PT_audio, + bpy.types.SCENE_PT_unit, + bpy.types.SCENE_PT_keying_sets, + bpy.types.SCENE_PT_keying_set_paths, + bpy.types.SCENE_PT_physics, bpy.types.WORLD_PT_context_world, bpy.types.DATA_PT_context_mesh, bpy.types.DATA_PT_context_camera, diff -Nru blender-2.61/intern/cycles/blender/blender_camera.cpp blender-2.62/intern/cycles/blender/blender_camera.cpp --- blender-2.61/intern/cycles/blender/blender_camera.cpp 2011-12-13 19:39:48.000000000 +0000 +++ blender-2.62/intern/cycles/blender/blender_camera.cpp 2012-02-15 19:24:08.000000000 +0000 @@ -72,17 +72,12 @@ if(!b_dof_object) return b_camera.dof_distance(); - /* for dof object, return distance along camera direction. this is - * compatible with blender, but does it fit our dof model? */ - Transform obmat = get_transform(b_ob.matrix_world()); + /* for dof object, return distance along camera Z direction */ + Transform obmat = transform_clear_scale(get_transform(b_ob.matrix_world())); Transform dofmat = get_transform(b_dof_object.matrix_world()); + Transform mat = transform_inverse(obmat) * dofmat; - float3 cam_p = transform_get_column(&obmat, 3); - float3 cam_dir = normalize(transform_get_column(&obmat, 2)); - float3 dof_p = transform_get_column(&dofmat, 3); - float3 proj_p = dot(dof_p, cam_dir) * cam_dir; - - return len(proj_p - cam_p); + return fabsf(transform_get_column(&mat, 3).z); } static void blender_camera_from_object(BlenderCamera *bcam, BL::Object b_ob) @@ -207,6 +202,7 @@ /* transform, note the blender camera points along the negative z-axis */ cam->matrix = bcam->matrix * transform_scale(1.0f, 1.0f, -1.0f); + cam->matrix = transform_clear_scale(cam->matrix); /* set update flag */ if(cam->modified(prevcam)) @@ -286,5 +282,29 @@ blender_camera_sync(scene->camera, &bcam, width, height); } +BufferParams BlenderSync::get_buffer_params(BL::Scene b_scene, BL::RegionView3D b_rv3d, int width, int height) +{ + BufferParams params; + + params.full_width = width; + params.full_height = height; + + /* border render */ + BL::RenderSettings r = b_scene.render(); + + if(!b_rv3d && r.use_border()) { + params.full_x = r.border_min_x()*width; + params.full_y = r.border_min_y()*height; + params.width = (int)(r.border_max_x()*width) - params.full_x; + params.height = (int)(r.border_max_y()*height) - params.full_y; + } + else { + params.width = width; + params.height = height; + } + + return params; +} + CCL_NAMESPACE_END diff -Nru blender-2.61/intern/cycles/blender/blender_mesh.cpp blender-2.62/intern/cycles/blender/blender_mesh.cpp --- blender-2.61/intern/cycles/blender/blender_mesh.cpp 2011-12-13 19:39:48.000000000 +0000 +++ blender-2.62/intern/cycles/blender/blender_mesh.cpp 2012-02-15 19:24:08.000000000 +0000 @@ -78,8 +78,9 @@ for(b_mesh.faces.begin(f); f != b_mesh.faces.end(); ++f) { int4 vi = get_int4(f->vertices_raw()); - int n= (vi[3] == 0)? 3: 4; - int shader = used_shaders[f->material_index()]; + int n = (vi[3] == 0)? 3: 4; + int mi = clamp(f->material_index(), 0, used_shaders.size()-1); + int shader = used_shaders[mi]; bool smooth = f->use_smooth(); mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth); @@ -232,8 +233,10 @@ BL::Object::material_slots_iterator slot; for(b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) { - if(render_layer.material_override) - find_shader(render_layer.material_override, used_shaders, scene->default_surface); + BL::Material material_override = render_layers.front().material_override; + + if(material_override) + find_shader(material_override, used_shaders, scene->default_surface); else find_shader(slot->material(), used_shaders, scene->default_surface); } diff -Nru blender-2.61/intern/cycles/blender/blender_object.cpp blender-2.62/intern/cycles/blender/blender_object.cpp --- blender-2.61/intern/cycles/blender/blender_object.cpp 2011-12-13 19:39:48.000000000 +0000 +++ blender-2.62/intern/cycles/blender/blender_object.cpp 2012-02-15 19:24:08.000000000 +0000 @@ -16,10 +16,13 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include "graph.h" #include "light.h" #include "mesh.h" #include "object.h" #include "scene.h" +#include "nodes.h" +#include "shader.h" #include "blender_sync.h" #include "blender_util.h" @@ -152,9 +155,40 @@ light->tag_update(scene); } +void BlenderSync::sync_background_light() +{ + BL::World b_world = b_scene.world(); + + if(b_world) { + PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles"); + bool sample_as_light = get_boolean(cworld, "sample_as_light"); + + if(sample_as_light) { + /* test if we need to sync */ + Light *light; + ObjectKey key(b_world, 0, b_world); + + if(light_map.sync(&light, b_world, b_world, key) || + world_recalc || + b_world.ptr.data != world_map) + { + light->type = LIGHT_BACKGROUND; + light->map_resolution = get_int(cworld, "sample_map_resolution"); + light->shader = scene->default_background; + + light->tag_update(scene); + light_map.set_recalc(b_world); + } + } + } + + world_map = b_world.ptr.data; + world_recalc = false; +} + /* Object */ -void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::Object b_ob, Transform& tfm, uint visibility) +void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::Object b_ob, Transform& tfm, uint layer_flag) { /* light is handled separately */ if(object_is_light(b_ob)) { @@ -180,12 +214,21 @@ /* object sync */ if(object_updated || (object->mesh && object->mesh->need_update)) { object->name = b_ob.name().c_str(); + object->pass_id = b_ob.pass_index(); object->tfm = tfm; - - object->visibility = object_ray_visibility(b_ob) & visibility; + + /* visibility flags for both parent */ + object->visibility = object_ray_visibility(b_ob) & PATH_RAY_ALL; if(b_parent.ptr.data != b_ob.ptr.data) object->visibility &= object_ray_visibility(b_parent); + /* camera flag is not actually used, instead is tested + against render layer flags */ + if(object->visibility & PATH_RAY_CAMERA) { + object->visibility |= layer_flag << PATH_RAY_LAYER_SHIFT; + object->visibility &= ~PATH_RAY_CAMERA; + } + object->tag_update(scene); } } @@ -195,8 +238,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d) { /* layer data */ - uint scene_layer = render_layer.scene_layer; - uint layer = render_layer.layer; + uint scene_layer = render_layers.front().scene_layer; /* prepare for sync */ light_map.pre_sync(); @@ -212,11 +254,6 @@ uint ob_layer = get_layer(b_ob->layers()); if(!hide && (ob_layer & scene_layer)) { - uint visibility = PATH_RAY_ALL; - - if(!(ob_layer & layer)) - visibility &= ~PATH_RAY_CAMERA; - if(b_ob->is_duplicator()) { /* dupli objects */ object_create_duplilist(*b_ob, b_scene); @@ -226,29 +263,43 @@ for(b_ob->dupli_list.begin(b_dup); b_dup != b_ob->dupli_list.end(); ++b_dup) { Transform tfm = get_transform(b_dup->matrix()); - sync_object(*b_ob, b_index, b_dup->object(), tfm, visibility); + BL::Object b_dup_ob = b_dup->object(); + bool dup_hide = (b_v3d)? b_dup_ob.hide(): b_dup_ob.hide_render(); + + if(!(b_dup->hide() || dup_hide)) + sync_object(*b_ob, b_index, b_dup_ob, tfm, ob_layer); + b_index++; } object_free_duplilist(*b_ob); - /* check if we should render duplicator */ hide = true; - BL::Object::particle_systems_iterator b_psys; + } - for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys) - if(b_psys->settings().use_render_emitter()) - hide = false; + /* check if we should render or hide particle emitter */ + BL::Object::particle_systems_iterator b_psys; + bool render_emitter = false; + + for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys) { + if(b_psys->settings().use_render_emitter()) { + hide = false; + render_emitter = true; + } + else if(!render_emitter) + hide = true; } if(!hide) { /* object itself */ Transform tfm = get_transform(b_ob->matrix_world()); - sync_object(*b_ob, 0, *b_ob, tfm, visibility); + sync_object(*b_ob, 0, *b_ob, tfm, ob_layer); } } } + sync_background_light(); + /* handle removed data and modified pointers */ if(light_map.post_sync()) scene->light_manager->tag_update(scene); diff -Nru blender-2.61/intern/cycles/blender/blender_python.cpp blender-2.62/intern/cycles/blender/blender_python.cpp --- blender-2.61/intern/cycles/blender/blender_python.cpp 2011-12-13 19:39:48.000000000 +0000 +++ blender-2.62/intern/cycles/blender/blender_python.cpp 2012-02-15 19:24:08.000000000 +0000 @@ -18,9 +18,12 @@ #include +#include "CCL_api.h" + #include "blender_sync.h" #include "blender_session.h" +#include "util_foreach.h" #include "util_opengl.h" #include "util_path.h" @@ -35,15 +38,14 @@ path_init(path, user_path); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } static PyObject *create_func(PyObject *self, PyObject *args) { - PyObject *pyengine, *pydata, *pyscene, *pyregion, *pyv3d, *pyrv3d; + PyObject *pyengine, *pyuserpref, *pydata, *pyscene, *pyregion, *pyv3d, *pyrv3d; - if(!PyArg_ParseTuple(args, "OOOOOO", &pyengine, &pydata, &pyscene, &pyregion, &pyv3d, &pyrv3d)) + if(!PyArg_ParseTuple(args, "OOOOOOO", &pyengine, &pyuserpref, &pydata, &pyscene, &pyregion, &pyv3d, &pyrv3d)) return NULL; /* RNA */ @@ -51,6 +53,10 @@ RNA_pointer_create(NULL, &RNA_RenderEngine, (void*)PyLong_AsVoidPtr(pyengine), &engineptr); BL::RenderEngine engine(engineptr); + PointerRNA userprefptr; + RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyuserpref), &userprefptr); + BL::UserPreferences userpref(userprefptr); + PointerRNA dataptr; RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pydata), &dataptr); BL::BlendData data(dataptr); @@ -79,45 +85,33 @@ int width = region.width(); int height = region.height(); - session = new BlenderSession(engine, data, scene, v3d, rv3d, width, height); + session = new BlenderSession(engine, userpref, data, scene, v3d, rv3d, width, height); } else { /* offline session */ - session = new BlenderSession(engine, data, scene); + session = new BlenderSession(engine, userpref, data, scene); } return PyLong_FromVoidPtr(session); } -static PyObject *free_func(PyObject *self, PyObject *args) +static PyObject *free_func(PyObject *self, PyObject *value) { - PyObject *pysession; - - if(!PyArg_ParseTuple(args, "O", &pysession)) - return NULL; - - delete (BlenderSession*)PyLong_AsVoidPtr(pysession); + delete (BlenderSession*)PyLong_AsVoidPtr(value); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } -static PyObject *render_func(PyObject *self, PyObject *args) +static PyObject *render_func(PyObject *self, PyObject *value) { - PyObject *pysession; - - if(!PyArg_ParseTuple(args, "O", &pysession)) - return NULL; - Py_BEGIN_ALLOW_THREADS - BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession); + BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(value); session->render(); Py_END_ALLOW_THREADS - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } static PyObject *draw_func(PyObject *self, PyObject *args) @@ -137,76 +131,105 @@ session->draw(viewport[2], viewport[3]); } - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } -static PyObject *sync_func(PyObject *self, PyObject *args) +static PyObject *sync_func(PyObject *self, PyObject *value) { - PyObject *pysession; - - if(!PyArg_ParseTuple(args, "O", &pysession)) - return NULL; - - BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession); + BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(value); session->synchronize(); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } static PyObject *available_devices_func(PyObject *self, PyObject *args) { - vector types = Device::available_types(); + vector& devices = Device::available_devices(); + PyObject *ret = PyTuple_New(devices.size()); - PyObject *ret = PyTuple_New(types.size()); - - for(size_t i = 0; i < types.size(); i++) { - string name = Device::string_from_type(types[i]); - PyTuple_SetItem(ret, i, PyUnicode_FromString(name.c_str())); + for(size_t i = 0; i < devices.size(); i++) { + DeviceInfo& device = devices[i]; + PyTuple_SET_ITEM(ret, i, PyUnicode_FromString(device.description.c_str())); } return ret; } -static PyObject *with_osl_func(PyObject *self, PyObject *args) -{ -#ifdef WITH_OSL - PyObject *ret = Py_True; -#else - PyObject *ret = Py_False; -#endif - - return Py_INCREF(ret), ret; -} - static PyMethodDef methods[] = { {"init", init_func, METH_VARARGS, ""}, {"create", create_func, METH_VARARGS, ""}, - {"free", free_func, METH_VARARGS, ""}, - {"render", render_func, METH_VARARGS, ""}, + {"free", free_func, METH_O, ""}, + {"render", render_func, METH_O, ""}, {"draw", draw_func, METH_VARARGS, ""}, - {"sync", sync_func, METH_VARARGS, ""}, + {"sync", sync_func, METH_O, ""}, {"available_devices", available_devices_func, METH_NOARGS, ""}, - {"with_osl", with_osl_func, METH_NOARGS, ""}, {NULL, NULL, 0, NULL}, }; static struct PyModuleDef module = { PyModuleDef_HEAD_INIT, - "bcycles", + "_cycles", "Blender cycles render integration", -1, methods, NULL, NULL, NULL, NULL }; +CCLDeviceInfo *compute_device_list(DeviceType type) +{ + /* device list stored static */ + static ccl::vector device_list; + static ccl::DeviceType device_type = DEVICE_NONE; + + /* create device list if it's not already done */ + if(type != device_type) { + ccl::vector& devices = ccl::Device::available_devices(); + + device_type = type; + device_list.clear(); + + /* add devices */ + int i = 0; + + foreach(DeviceInfo& info, devices) { + if(info.type == type || + (info.type == DEVICE_MULTI && info.multi_devices[0].type == type)) { + CCLDeviceInfo cinfo = {info.id.c_str(), info.description.c_str(), i++}; + device_list.push_back(cinfo); + } + } + + /* null terminate */ + if(!device_list.empty()) { + CCLDeviceInfo cinfo = {NULL, NULL, 0}; + device_list.push_back(cinfo); + } + } + + return (device_list.empty())? NULL: &device_list[0]; +} + + CCL_NAMESPACE_END -extern "C" PyObject *CYCLES_initPython(); +void *CCL_python_module_init() +{ + PyObject *mod= PyModule_Create(&ccl::module); + +#ifdef WITH_OSL + PyModule_AddObject(mod, "with_osl", Py_True); + Py_INCREF(Py_True); +#else + PyModule_AddObject(mod, "with_osl", Py_False); + Py_INCREF(Py_False); +#endif + + return (void*)mod; +} -PyObject *CYCLES_initPython() +CCLDeviceInfo *CCL_compute_device_list(int opencl) { - return PyModule_Create(&ccl::module); + ccl::DeviceType type = (opencl)? ccl::DEVICE_OPENCL: ccl::DEVICE_CUDA; + return ccl::compute_device_list(type); } diff -Nru blender-2.61/intern/cycles/blender/blender_session.cpp blender-2.62/intern/cycles/blender/blender_session.cpp --- blender-2.61/intern/cycles/blender/blender_session.cpp 2011-12-13 19:39:48.000000000 +0000 +++ blender-2.62/intern/cycles/blender/blender_session.cpp 2012-02-15 19:24:08.000000000 +0000 @@ -39,23 +39,28 @@ CCL_NAMESPACE_BEGIN -BlenderSession::BlenderSession(BL::RenderEngine b_engine_, BL::BlendData b_data_, BL::Scene b_scene_) -: b_engine(b_engine_), b_data(b_data_), b_scene(b_scene_), b_v3d(PointerRNA_NULL), b_rv3d(PointerRNA_NULL) +BlenderSession::BlenderSession(BL::RenderEngine b_engine_, BL::UserPreferences b_userpref_, + BL::BlendData b_data_, BL::Scene b_scene_) +: b_engine(b_engine_), b_userpref(b_userpref_), b_data(b_data_), b_scene(b_scene_), + b_v3d(PointerRNA_NULL), b_rv3d(PointerRNA_NULL), + b_rr(PointerRNA_NULL), b_rlay(PointerRNA_NULL) { /* offline render */ BL::RenderSettings r = b_scene.render(); - width = (int)(r.resolution_x()*r.resolution_percentage()*0.01f); - height = (int)(r.resolution_y()*r.resolution_percentage()*0.01f); + width = (int)(r.resolution_x()*r.resolution_percentage()/100); + height = (int)(r.resolution_y()*r.resolution_percentage()/100); background = true; last_redraw_time = 0.0f; create_session(); } -BlenderSession::BlenderSession(BL::RenderEngine b_engine_, BL::BlendData b_data_, BL::Scene b_scene_, +BlenderSession::BlenderSession(BL::RenderEngine b_engine_, BL::UserPreferences b_userpref_, + BL::BlendData b_data_, BL::Scene b_scene_, BL::SpaceView3D b_v3d_, BL::RegionView3D b_rv3d_, int width_, int height_) -: b_engine(b_engine_), b_data(b_data_), b_scene(b_scene_), b_v3d(b_v3d_), b_rv3d(b_rv3d_) +: b_engine(b_engine_), b_userpref(b_userpref_), b_data(b_data_), b_scene(b_scene_), + b_v3d(b_v3d_), b_rv3d(b_rv3d_), b_rr(PointerRNA_NULL), b_rlay(PointerRNA_NULL) { /* 3d view render */ width = width_; @@ -64,6 +69,7 @@ last_redraw_time = 0.0f; create_session(); + session->start(); } BlenderSession::~BlenderSession() @@ -74,7 +80,7 @@ void BlenderSession::create_session() { SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background); - SessionParams session_params = BlenderSync::get_session_params(b_scene, background); + SessionParams session_params = BlenderSync::get_session_params(b_userpref, b_scene, background); /* reset status/progress */ last_status= ""; @@ -99,9 +105,9 @@ session->progress.set_cancel_callback(function_bind(&BlenderSession::test_cancel, this)); session->set_pause(BlenderSync::get_session_pause(b_scene, background)); - /* start rendering */ - session->reset(width, height, session_params.samples); - session->start(); + /* set buffer parameters */ + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_rv3d, width, height); + session->reset(buffer_params, session_params.samples); } void BlenderSession::free_session() @@ -110,55 +116,179 @@ delete session; } +static PassType get_pass_type(BL::RenderPass b_pass) +{ + switch(b_pass.type()) { + case BL::RenderPass::type_COMBINED: + return PASS_COMBINED; + + case BL::RenderPass::type_Z: + return PASS_DEPTH; + case BL::RenderPass::type_NORMAL: + return PASS_NORMAL; + case BL::RenderPass::type_OBJECT_INDEX: + return PASS_OBJECT_ID; + case BL::RenderPass::type_UV: + return PASS_UV; + case BL::RenderPass::type_MATERIAL_INDEX: + return PASS_MATERIAL_ID; + + case BL::RenderPass::type_DIFFUSE_DIRECT: + return PASS_DIFFUSE_DIRECT; + case BL::RenderPass::type_GLOSSY_DIRECT: + return PASS_GLOSSY_DIRECT; + case BL::RenderPass::type_TRANSMISSION_DIRECT: + return PASS_TRANSMISSION_DIRECT; + + case BL::RenderPass::type_DIFFUSE_INDIRECT: + return PASS_DIFFUSE_INDIRECT; + case BL::RenderPass::type_GLOSSY_INDIRECT: + return PASS_GLOSSY_INDIRECT; + case BL::RenderPass::type_TRANSMISSION_INDIRECT: + return PASS_TRANSMISSION_INDIRECT; + + case BL::RenderPass::type_DIFFUSE_COLOR: + return PASS_DIFFUSE_COLOR; + case BL::RenderPass::type_GLOSSY_COLOR: + return PASS_GLOSSY_COLOR; + case BL::RenderPass::type_TRANSMISSION_COLOR: + return PASS_TRANSMISSION_COLOR; + + case BL::RenderPass::type_EMIT: + return PASS_EMISSION; + case BL::RenderPass::type_ENVIRONMENT: + return PASS_BACKGROUND; + + case BL::RenderPass::type_DIFFUSE: + case BL::RenderPass::type_SHADOW: + case BL::RenderPass::type_AO: + case BL::RenderPass::type_COLOR: + case BL::RenderPass::type_REFRACTION: + case BL::RenderPass::type_SPECULAR: + case BL::RenderPass::type_REFLECTION: + case BL::RenderPass::type_VECTOR: + case BL::RenderPass::type_MIST: + return PASS_NONE; + } + + return PASS_NONE; +} + void BlenderSession::render() { - session->wait(); + /* get buffer parameters */ + SessionParams session_params = BlenderSync::get_session_params(b_userpref, b_scene, background); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_rv3d, width, height); + int w = buffer_params.width, h = buffer_params.height; - if(session->progress.get_cancel()) - return; + /* create render result */ + RenderResult *rrp = RE_engine_begin_result((RenderEngine*)b_engine.ptr.data, 0, 0, w, h); + PointerRNA rrptr; + RNA_pointer_create(NULL, &RNA_RenderResult, rrp, &rrptr); + b_rr = BL::RenderResult(rrptr); + + BL::RenderSettings r = b_scene.render(); + BL::RenderResult::layers_iterator b_iter; + BL::RenderLayers b_rr_layers(r.ptr); + + /* render each layer */ + for(b_rr.layers.begin(b_iter); b_iter != b_rr.layers.end(); ++b_iter) { + /* set layer */ + b_rlay = *b_iter; + + /* add passes */ + vector passes; + Pass::add(PASS_COMBINED, passes); + + if(session_params.device.advanced_shading) { + BL::RenderLayer::passes_iterator b_pass_iter; + + for(b_rlay.passes.begin(b_pass_iter); b_pass_iter != b_rlay.passes.end(); ++b_pass_iter) { + BL::RenderPass b_pass(*b_pass_iter); + PassType pass_type = get_pass_type(b_pass); + + if(pass_type != PASS_NONE) + Pass::add(pass_type, passes); + } + } + + buffer_params.passes = passes; + scene->film->passes = passes; + scene->film->tag_update(scene); + + /* update session */ + session->reset(buffer_params, session_params.samples); + + /* update scene */ + sync->sync_data(b_v3d, b_iter->name().c_str()); + + /* render */ + session->start(); + session->wait(); + + if(session->progress.get_cancel()) + break; - /* write result */ - write_render_result(); + /* write result */ + write_render_result(); + } + + /* delete render result */ + RE_engine_end_result((RenderEngine*)b_engine.ptr.data, (RenderResult*)b_rr.ptr.data); } void BlenderSession::write_render_result() { - /* get result */ + /* get state */ RenderBuffers *buffers = session->buffers; + + /* copy data from device */ + if(!buffers->copy_from_device()) + return; + + BufferParams& params = buffers->params; float exposure = scene->film->exposure; double total_time, sample_time; int sample; - session->progress.get_sample(sample, total_time, sample_time); - float4 *pixels = buffers->copy_from_device(exposure, sample); - - if(!pixels) - return; + session->progress.get_sample(sample, total_time, sample_time); - struct RenderResult *rrp = RE_engine_begin_result((RenderEngine*)b_engine.ptr.data, 0, 0, width, height); - PointerRNA rrptr; - RNA_pointer_create(NULL, &RNA_RenderResult, rrp, &rrptr); - BL::RenderResult rr(rrptr); + vector pixels(params.width*params.height*4); - BL::RenderResult::layers_iterator layer; - rr.layers.begin(layer); - rna_RenderLayer_rect_set(&layer->ptr, (float*)pixels); + /* copy each pass */ + BL::RenderLayer::passes_iterator b_iter; + + for(b_rlay.passes.begin(b_iter); b_iter != b_rlay.passes.end(); ++b_iter) { + BL::RenderPass b_pass(*b_iter); + + /* find matching pass type */ + PassType pass_type = get_pass_type(b_pass); + int components = b_pass.channels(); + + /* copy pixels */ + if(buffers->get_pass(pass_type, exposure, sample, components, &pixels[0])) + rna_RenderPass_rect_set(&b_pass.ptr, &pixels[0]); + } - RE_engine_end_result((RenderEngine*)b_engine.ptr.data, rrp); + /* copy combined pass */ + if(buffers->get_pass(PASS_COMBINED, exposure, sample, 4, &pixels[0])) + rna_RenderLayer_rect_set(&b_rlay.ptr, &pixels[0]); - delete [] pixels; + /* tag result as updated */ + RE_engine_update_result((RenderEngine*)b_engine.ptr.data, (RenderResult*)b_rr.ptr.data); } void BlenderSession::synchronize() { /* on session/scene parameter changes, we recreate session entirely */ SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background); - SessionParams session_params = BlenderSync::get_session_params(b_scene, background); + SessionParams session_params = BlenderSync::get_session_params(b_userpref, b_scene, background); if(session->params.modified(session_params) || scene->params.modified(scene_params)) { free_session(); create_session(); + session->start(); return; } @@ -188,8 +318,10 @@ session->scene->mutex.unlock(); /* reset if needed */ - if(scene->need_reset()) - session->reset(width, height, session_params.samples); + if(scene->need_reset()) { + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_rv3d, width, height); + session->reset(buffer_params, session_params.samples); + } } bool BlenderSession::draw(int w, int h) @@ -224,8 +356,10 @@ /* reset if requested */ if(reset) { - SessionParams session_params = BlenderSync::get_session_params(b_scene, background); - session->reset(width, height, session_params.samples); + SessionParams session_params = BlenderSync::get_session_params(b_userpref, b_scene, background); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_rv3d, width, height); + + session->reset(buffer_params, session_params.samples); } } @@ -233,7 +367,9 @@ update_status_progress(); /* draw */ - return !session->draw(width, height); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_rv3d, width, height); + + return !session->draw(buffer_params); } void BlenderSession::get_status(string& status, string& substatus) @@ -252,7 +388,7 @@ void BlenderSession::update_status_progress() { - string status, substatus; + string timestatus, status, substatus; float progress; double total_time; char time_str[128]; @@ -260,16 +396,14 @@ get_status(status, substatus); get_progress(progress, total_time); - if(!background) { - BLI_timestr(total_time, time_str); - status = "Time: " + string(time_str) + " | " + status; - } + BLI_timestr(total_time, time_str); + timestatus = "Elapsed: " + string(time_str) + " | "; if(substatus.size() > 0) status += " | " + substatus; if(status != last_status) { - RE_engine_update_stats((RenderEngine*)b_engine.ptr.data, "", status.c_str()); + RE_engine_update_stats((RenderEngine*)b_engine.ptr.data, "", (timestatus + status).c_str()); last_status = status; } if(progress != last_progress) { diff -Nru blender-2.61/intern/cycles/blender/blender_session.h blender-2.62/intern/cycles/blender/blender_session.h --- blender-2.61/intern/cycles/blender/blender_session.h 2011-12-13 19:39:48.000000000 +0000 +++ blender-2.62/intern/cycles/blender/blender_session.h 2012-02-15 19:24:08.000000000 +0000 @@ -32,8 +32,10 @@ class BlenderSession { public: - BlenderSession(BL::RenderEngine b_engine, BL::BlendData b_data, BL::Scene b_scene); - BlenderSession(BL::RenderEngine b_engine, BL::BlendData b_data, BL::Scene b_scene, + BlenderSession(BL::RenderEngine b_engine, BL::UserPreferences b_userpref, + BL::BlendData b_data, BL::Scene b_scene); + BlenderSession(BL::RenderEngine b_engine, BL::UserPreferences b_userpref, + BL::BlendData b_data, BL::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height); ~BlenderSession(); @@ -65,10 +67,13 @@ double last_redraw_time; BL::RenderEngine b_engine; + BL::UserPreferences b_userpref; BL::BlendData b_data; BL::Scene b_scene; BL::SpaceView3D b_v3d; BL::RegionView3D b_rv3d; + BL::RenderResult b_rr; + BL::RenderLayer b_rlay; string last_status; float last_progress; diff -Nru blender-2.61/intern/cycles/blender/blender_shader.cpp blender-2.62/intern/cycles/blender/blender_shader.cpp --- blender-2.61/intern/cycles/blender/blender_shader.cpp 2011-12-13 19:39:48.000000000 +0000 +++ blender-2.62/intern/cycles/blender/blender_shader.cpp 2012-02-15 19:24:08.000000000 +0000 @@ -50,28 +50,6 @@ /* Graph */ -static BL::NodeSocket get_node_input(BL::Node *b_group_node, BL::NodeSocket b_in) -{ - if(b_group_node) { - - BL::NodeTree b_ntree = BL::NodeGroup(*b_group_node).node_tree(); - BL::NodeTree::links_iterator b_link; - - for(b_ntree.links.begin(b_link); b_link != b_ntree.links.end(); ++b_link) { - if(b_link->to_socket().ptr.data == b_in.ptr.data) { - BL::Node::inputs_iterator b_gin; - - for(b_group_node->inputs.begin(b_gin); b_gin != b_group_node->inputs.end(); ++b_gin) - if(b_gin->group_socket().ptr.data == b_link->from_socket().ptr.data) - return *b_gin; - - } - } - } - - return b_in; -} - static BL::NodeSocket get_node_output(BL::Node b_node, const string& name) { BL::Node::outputs_iterator b_out; @@ -121,7 +99,7 @@ mapping->scale = get_float3(b_mapping.scale()); } -static ShaderNode *add_node(BL::BlendData b_data, ShaderGraph *graph, BL::Node *b_group_node, BL::ShaderNode b_node) +static ShaderNode *add_node(BL::BlendData b_data, ShaderGraph *graph, BL::ShaderNode b_node) { ShaderNode *node = NULL; @@ -132,7 +110,6 @@ case BL::ShaderNode::type_GEOMETRY: break; case BL::ShaderNode::type_MATERIAL: break; case BL::ShaderNode::type_MATERIAL_EXT: break; - case BL::ShaderNode::type_NORMAL: break; case BL::ShaderNode::type_OUTPUT: break; case BL::ShaderNode::type_SCRIPT: break; case BL::ShaderNode::type_SQUEEZE: break; @@ -161,6 +138,14 @@ node = new InvertNode(); break; } + case BL::ShaderNode::type_GAMMA: { + node = new GammaNode(); + break; + } + case BL::ShaderNode::type_BRIGHTCONTRAST: { + node = new BrightContrastNode(); + break; + } case BL::ShaderNode::type_MIX_RGB: { BL::ShaderNodeMixRGB b_mix_node(b_node); MixNode *mix = new MixNode(); @@ -198,6 +183,17 @@ node = vmath; break; } + case BL::ShaderNode::type_NORMAL: { + BL::Node::outputs_iterator out_it; + b_node.outputs.begin(out_it); + BL::NodeSocketVectorNone vec_sock(*out_it); + + NormalNode *norm = new NormalNode(); + norm->direction = get_float3(vec_sock.default_value()); + + node = norm; + break; + } case BL::ShaderNode::type_MAPPING: { BL::ShaderNodeMapping b_mapping_node(b_node); MappingNode *mapping = new MappingNode(); @@ -372,6 +368,13 @@ node = wave; break; } + case BL::ShaderNode::type_TEX_CHECKER: { + BL::ShaderNodeTexChecker b_checker_node(b_node); + CheckerTextureNode *checker = new CheckerTextureNode(); + get_tex_mapping(&checker->tex_mapping, b_checker_node.texture_mapping()); + node = checker; + break; + } case BL::ShaderNode::type_TEX_NOISE: { BL::ShaderNodeTexNoise b_noise_node(b_node); NoiseTextureNode *noise = new NoiseTextureNode(); @@ -456,59 +459,115 @@ return SocketPair(node_map[b_node.ptr.data], name); } -static void add_nodes(BL::BlendData b_data, ShaderGraph *graph, BL::ShaderNodeTree b_ntree, BL::Node *b_group_node, PtrSockMap& sockets_map) +static ShaderSocketType convert_socket_type(BL::NodeSocket::type_enum b_type) +{ + switch (b_type) { + case BL::NodeSocket::type_VALUE: + return SHADER_SOCKET_FLOAT; + case BL::NodeSocket::type_VECTOR: + return SHADER_SOCKET_VECTOR; + case BL::NodeSocket::type_RGBA: + return SHADER_SOCKET_COLOR; + case BL::NodeSocket::type_SHADER: + return SHADER_SOCKET_CLOSURE; + + case BL::NodeSocket::type_BOOLEAN: + case BL::NodeSocket::type_MESH: + case BL::NodeSocket::type_INT: + default: + return SHADER_SOCKET_FLOAT; + } +} + +static void set_default_value(ShaderInput *input, BL::NodeSocket sock) +{ + /* copy values for non linked inputs */ + switch(input->type) { + case SHADER_SOCKET_FLOAT: { + BL::NodeSocketFloatNone value_sock(sock); + input->set(value_sock.default_value()); + break; + } + case SHADER_SOCKET_COLOR: { + BL::NodeSocketRGBA rgba_sock(sock); + input->set(get_float3(rgba_sock.default_value())); + break; + } + case SHADER_SOCKET_NORMAL: + case SHADER_SOCKET_POINT: + case SHADER_SOCKET_VECTOR: { + BL::NodeSocketVectorNone vec_sock(sock); + input->set(get_float3(vec_sock.default_value())); + break; + } + case SHADER_SOCKET_CLOSURE: + break; + } +} + +static void add_nodes(BL::BlendData b_data, ShaderGraph *graph, BL::ShaderNodeTree b_ntree, PtrSockMap& sockets_map) { /* add nodes */ BL::ShaderNodeTree::nodes_iterator b_node; PtrNodeMap node_map; - map node_groups; + PtrSockMap proxy_map; for(b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) { if(b_node->is_a(&RNA_NodeGroup)) { + /* add proxy converter nodes for inputs and outputs */ BL::NodeGroup b_gnode(*b_node); BL::ShaderNodeTree b_group_ntree(b_gnode.node_tree()); - - node_groups[b_node->ptr.data] = PtrSockMap(); - add_nodes(b_data, graph, b_group_ntree, &b_gnode, node_groups[b_node->ptr.data]); + BL::Node::inputs_iterator b_input; + BL::Node::outputs_iterator b_output; + + PtrSockMap group_sockmap; + + for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) { + ShaderSocketType extern_type = convert_socket_type(b_input->type()); + ShaderSocketType intern_type = convert_socket_type(b_input->group_socket().type()); + ShaderNode *proxy = graph->add(new ProxyNode(extern_type, intern_type)); + + /* map the external node socket to the proxy node socket */ + proxy_map[b_input->ptr.data] = SocketPair(proxy, proxy->inputs[0]->name); + /* map the internal group socket to the proxy node socket */ + group_sockmap[b_input->group_socket().ptr.data] = SocketPair(proxy, proxy->outputs[0]->name); + + /* default input values of the group node */ + set_default_value(proxy->inputs[0], *b_input); + } + + for(b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) { + ShaderSocketType extern_type = convert_socket_type(b_output->type()); + ShaderSocketType intern_type = convert_socket_type(b_output->group_socket().type()); + ShaderNode *proxy = graph->add(new ProxyNode(intern_type, extern_type)); + + /* map the external node socket to the proxy node socket */ + proxy_map[b_output->ptr.data] = SocketPair(proxy, proxy->outputs[0]->name); + /* map the internal group socket to the proxy node socket */ + group_sockmap[b_output->group_socket().ptr.data] = SocketPair(proxy, proxy->inputs[0]->name); + + /* default input values of internal, unlinked group outputs */ + set_default_value(proxy->inputs[0], b_output->group_socket()); + } + + add_nodes(b_data, graph, b_group_ntree, group_sockmap); } else { - ShaderNode *node = add_node(b_data, graph, b_group_node, BL::ShaderNode(*b_node)); - + ShaderNode *node = add_node(b_data, graph, BL::ShaderNode(*b_node)); + if(node) { BL::Node::inputs_iterator b_input; - BL::Node::outputs_iterator b_output; - + node_map[b_node->ptr.data] = node; - + for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) { SocketPair pair = node_socket_map_pair(node_map, *b_node, *b_input); ShaderInput *input = pair.first->input(pair.second.c_str()); - BL::NodeSocket sock(get_node_input(b_group_node, *b_input)); - + assert(input); - + /* copy values for non linked inputs */ - switch(input->type) { - case SHADER_SOCKET_FLOAT: { - BL::NodeSocketFloatNone value_sock(sock); - input->set(value_sock.default_value()); - break; - } - case SHADER_SOCKET_COLOR: { - BL::NodeSocketRGBA rgba_sock(sock); - input->set(get_float3(rgba_sock.default_value())); - break; - } - case SHADER_SOCKET_NORMAL: - case SHADER_SOCKET_POINT: - case SHADER_SOCKET_VECTOR: { - BL::NodeSocketVectorNone vec_sock(sock); - input->set(get_float3(vec_sock.default_value())); - break; - } - case SHADER_SOCKET_CLOSURE: - break; - } + set_default_value(input, *b_input); } } } @@ -525,48 +584,32 @@ BL::NodeSocket b_from_sock = b_link->from_socket(); BL::NodeSocket b_to_sock = b_link->to_socket(); - /* if link with group socket, add to map so we can connect it later */ - if(b_group_node) { - if(!b_from_node) { - sockets_map[b_from_sock.ptr.data] = - node_socket_map_pair(node_map, b_to_node, b_to_sock); - - continue; - } - else if(!b_to_node) { - sockets_map[b_to_sock.ptr.data] = - node_socket_map_pair(node_map, b_from_node, b_from_sock); - - continue; - } - } - SocketPair from_pair, to_pair; + /* links without a node pointer are connections to group inputs/outputs */ + /* from sock */ - if(b_from_node.is_a(&RNA_NodeGroup)) { - /* group node */ - BL::NodeSocket group_sock = b_from_sock.group_socket(); - from_pair = node_groups[b_from_node.ptr.data][group_sock.ptr.data]; - } - else { - /* regular node */ - from_pair = node_socket_map_pair(node_map, b_from_node, b_from_sock); + if(b_from_node) { + if (b_from_node.is_a(&RNA_NodeGroup)) + from_pair = proxy_map[b_from_sock.ptr.data]; + else + from_pair = node_socket_map_pair(node_map, b_from_node, b_from_sock); } + else + from_pair = sockets_map[b_from_sock.ptr.data]; /* to sock */ - if(b_to_node.is_a(&RNA_NodeGroup)) { - /* group node */ - BL::NodeSocket group_sock = b_to_sock.group_socket(); - to_pair = node_groups[b_to_node.ptr.data][group_sock.ptr.data]; - } - else { - /* regular node */ - to_pair = node_socket_map_pair(node_map, b_to_node, b_to_sock); + if(b_to_node) { + if (b_to_node.is_a(&RNA_NodeGroup)) + to_pair = proxy_map[b_to_sock.ptr.data]; + else + to_pair = node_socket_map_pair(node_map, b_to_node, b_to_sock); } + else + to_pair = sockets_map[b_to_sock.ptr.data]; - /* in case of groups there may not actually be a node inside the group - that the group socket connects to, so from_node or to_node may be NULL */ + /* either node may be NULL when the node was not exported, typically + because the node type is not supported */ if(from_pair.first && to_pair.first) { ShaderOutput *output = from_pair.first->output(from_pair.second.c_str()); ShaderInput *input = to_pair.first->input(to_pair.second.c_str()); @@ -593,13 +636,14 @@ ShaderGraph *graph = new ShaderGraph(); shader->name = b_mat->name().c_str(); + shader->pass_id = b_mat->pass_index(); /* create nodes */ if(b_mat->use_nodes() && b_mat->node_tree()) { PtrSockMap sock_to_node; BL::ShaderNodeTree b_ntree(b_mat->node_tree()); - add_nodes(b_data, graph, b_ntree, NULL, sock_to_node); + add_nodes(b_data, graph, b_ntree, sock_to_node); } else { ShaderNode *closure, *out; @@ -640,7 +684,7 @@ PtrSockMap sock_to_node; BL::ShaderNodeTree b_ntree(b_world.node_tree()); - add_nodes(b_data, graph, b_ntree, NULL, sock_to_node); + add_nodes(b_data, graph, b_ntree, sock_to_node); } else if(b_world) { ShaderNode *closure, *out; @@ -661,9 +705,6 @@ if(background->modified(prevbackground)) background->tag_update(scene); - - world_map = b_world.ptr.data; - world_recalc = false; } /* Sync Lamps */ @@ -689,7 +730,7 @@ PtrSockMap sock_to_node; BL::ShaderNodeTree b_ntree(b_lamp->node_tree()); - add_nodes(b_data, graph, b_ntree, NULL, sock_to_node); + add_nodes(b_data, graph, b_ntree, sock_to_node); } else { ShaderNode *closure, *out; diff -Nru blender-2.61/intern/cycles/blender/blender_sync.cpp blender-2.62/intern/cycles/blender/blender_sync.cpp --- blender-2.61/intern/cycles/blender/blender_sync.cpp 2011-12-13 19:39:48.000000000 +0000 +++ blender-2.62/intern/cycles/blender/blender_sync.cpp 2012-02-15 19:24:08.000000000 +0000 @@ -48,7 +48,8 @@ light_map(&scene_->lights), world_map(NULL), world_recalc(false), - experimental(false) + experimental(false), + active_layer(0) { scene = scene_; preview = preview_; @@ -68,13 +69,13 @@ BL::BlendData::materials_iterator b_mat; for(b_data.materials.begin(b_mat); b_mat != b_data.materials.end(); ++b_mat) - if(b_mat->is_updated()) + if(b_mat->is_updated() || (b_mat->node_tree() && b_mat->node_tree().is_updated())) shader_map.set_recalc(*b_mat); BL::BlendData::lamps_iterator b_lamp; for(b_data.lamps.begin(b_lamp); b_lamp != b_data.lamps.end(); ++b_lamp) - if(b_lamp->is_updated()) + if(b_lamp->is_updated() || (b_lamp->node_tree() && b_lamp->node_tree().is_updated())) shader_map.set_recalc(*b_lamp); BL::BlendData::objects_iterator b_ob; @@ -106,7 +107,8 @@ BL::BlendData::worlds_iterator b_world; for(b_data.worlds.begin(b_world); b_world != b_data.worlds.end(); ++b_world) - if(world_map == b_world->ptr.data && b_world->is_updated()) + if(world_map == b_world->ptr.data && + (b_world->is_updated() || (b_world->node_tree() && b_world->node_tree().is_updated()))) world_recalc = true; bool recalc = @@ -120,18 +122,18 @@ return recalc; } -void BlenderSync::sync_data(BL::SpaceView3D b_v3d) +void BlenderSync::sync_data(BL::SpaceView3D b_v3d, const char *layer) { - sync_integrator(); + sync_render_layers(b_v3d); + sync_integrator(layer); sync_film(); - sync_render_layer(b_v3d); sync_shaders(); sync_objects(b_v3d); } /* Integrator */ -void BlenderSync::sync_integrator() +void BlenderSync::sync_integrator(const char *layer) { PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); @@ -152,10 +154,22 @@ integrator->transparent_shadows = get_boolean(cscene, "use_transparent_shadows"); integrator->no_caustics = get_boolean(cscene, "no_caustics"); - integrator->blur_caustics = get_float(cscene, "blur_caustics"); - integrator->seed = get_int(cscene, "seed"); + /* render layer */ + int active_layer = 0; + + if(layer) { + for(int i = 0; i < render_layers.size(); i++) { + if(render_layers[i].name == layer) { + active_layer = i; + break; + } + } + } + + integrator->layer_flag = render_layers[active_layer].layer; + if(integrator->modified(previntegrator)) integrator->tag_update(scene); } @@ -186,27 +200,33 @@ /* Render Layer */ -void BlenderSync::sync_render_layer(BL::SpaceView3D b_v3d) +void BlenderSync::sync_render_layers(BL::SpaceView3D b_v3d) { + render_layers.clear(); + if(b_v3d) { - render_layer.scene_layer = get_layer(b_v3d.layers()); - render_layer.layer = render_layer.scene_layer; - render_layer.material_override = PointerRNA_NULL; + RenderLayerInfo rlay; + + rlay.scene_layer = get_layer(b_v3d.layers()); + rlay.layer = rlay.scene_layer; + rlay.material_override = PointerRNA_NULL; + + render_layers.push_back(rlay); } else { BL::RenderSettings r = b_scene.render(); BL::RenderSettings::layers_iterator b_rlay; - bool first = true; for(r.layers.begin(b_rlay); b_rlay != r.layers.end(); ++b_rlay) { /* single layer for now */ - if(first) { - render_layer.scene_layer = get_layer(b_scene.layers()); - render_layer.layer = get_layer(b_rlay->layers()); - render_layer.material_override = b_rlay->material_override(); + RenderLayerInfo rlay; - first = false; - } + rlay.name = b_rlay->name(); + rlay.scene_layer = get_layer(b_scene.layers()); + rlay.layer = get_layer(b_rlay->layers()); + rlay.material_override = b_rlay->material_override(); + + render_layers.push_back(rlay); } } } @@ -230,6 +250,7 @@ params.bvh_type = (SceneParams::BVHType)RNA_enum_get(&cscene, "debug_bvh_type"); params.use_bvh_spatial_split = RNA_boolean_get(&cscene, "debug_use_spatial_splits"); + params.use_bvh_cache = (background)? RNA_boolean_get(&cscene, "use_cache"): false; return params; } @@ -242,16 +263,7 @@ return (background)? false: get_boolean(cscene, "preview_pause"); } -static bool device_type_available(vector& types, DeviceType dtype) -{ - foreach(DeviceType dt, types) - if(dt == dtype) - return true; - - return false; -} - -SessionParams BlenderSync::get_session_params(BL::Scene b_scene, bool background) +SessionParams BlenderSync::get_session_params(BL::UserPreferences b_userpref, BL::Scene b_scene, bool background) { SessionParams params; PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); @@ -260,25 +272,26 @@ params.experimental = (RNA_enum_get(&cscene, "feature_set") != 0); /* device type */ - params.device_type = DEVICE_CPU; + vector& devices = Device::available_devices(); + + /* device default CPU */ + params.device = devices[0]; if(RNA_enum_get(&cscene, "device") != 0) { - vector types = Device::available_types(); - DeviceType dtype; - - if(!params.experimental || RNA_enum_get(&cscene, "gpu_type") == 0) - dtype = DEVICE_CUDA; - else - dtype = DEVICE_OPENCL; - - if(device_type_available(types, dtype)) - params.device_type = dtype; - else if(params.experimental && device_type_available(types, DEVICE_OPENCL)) - params.device_type = DEVICE_OPENCL; - else if(device_type_available(types, DEVICE_CUDA)) - params.device_type = DEVICE_CUDA; + /* find GPU device with given id */ + PointerRNA systemptr = b_userpref.system().ptr; + PropertyRNA *deviceprop = RNA_struct_find_property(&systemptr, "compute_device"); + int device_id = b_userpref.system().compute_device(); + + const char *id; + + if(RNA_property_enum_identifier(NULL, &systemptr, deviceprop, device_id, &id)) { + foreach(DeviceInfo& info, devices) + if(info.id == id) + params.device = info; + } } - + /* Background */ params.background = background; @@ -306,6 +319,10 @@ } else params.progressive = true; + + /* todo: multi device only works with single tiles now */ + if(params.device.type == DEVICE_MULTI) + params.tile_size = INT_MAX; return params; } diff -Nru blender-2.61/intern/cycles/blender/blender_sync.h blender-2.62/intern/cycles/blender/blender_sync.h --- blender-2.61/intern/cycles/blender/blender_sync.h 2011-12-13 19:39:48.000000000 +0000 +++ blender-2.62/intern/cycles/blender/blender_sync.h 2012-02-15 19:24:08.000000000 +0000 @@ -54,14 +54,15 @@ /* sync */ bool sync_recalc(); - void sync_data(BL::SpaceView3D b_v3d); + void sync_data(BL::SpaceView3D b_v3d, const char *layer = 0); void sync_camera(int width, int height); void sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height); /* get parameters */ static SceneParams get_scene_params(BL::Scene b_scene, bool background); - static SessionParams get_session_params(BL::Scene b_scene, bool background); + static SessionParams get_session_params(BL::UserPreferences b_userpref, BL::Scene b_scene, bool background); static bool get_session_pause(BL::Scene b_scene, bool background); + static BufferParams get_buffer_params(BL::Scene b_scene, BL::RegionView3D b_rv3d, int width, int height); private: /* sync */ @@ -69,16 +70,17 @@ void sync_materials(); void sync_objects(BL::SpaceView3D b_v3d); void sync_film(); - void sync_integrator(); + void sync_integrator(const char *layer); void sync_view(); void sync_world(); - void sync_render_layer(BL::SpaceView3D b_v3d); + void sync_render_layers(BL::SpaceView3D b_v3d); void sync_shaders(); void sync_nodes(Shader *shader, BL::ShaderNodeTree b_ntree); Mesh *sync_mesh(BL::Object b_ob, bool object_updated); - void sync_object(BL::Object b_parent, int b_index, BL::Object b_object, Transform& tfm, uint visibility); + void sync_object(BL::Object b_parent, int b_index, BL::Object b_object, Transform& tfm, uint layer_flag); void sync_light(BL::Object b_parent, int b_index, BL::Object b_ob, Transform& tfm); + void sync_background_light(); /* util */ void find_shader(BL::ID id, vector& used_shaders, int default_shader); @@ -108,10 +110,14 @@ material_override(PointerRNA_NULL) {} + string name; uint scene_layer; uint layer; BL::Material material_override; - } render_layer; + }; + + vector render_layers; + int active_layer; }; CCL_NAMESPACE_END diff -Nru blender-2.61/intern/cycles/blender/CCL_api.h blender-2.62/intern/cycles/blender/CCL_api.h --- blender-2.61/intern/cycles/blender/CCL_api.h 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/intern/cycles/blender/CCL_api.h 2012-02-15 19:24:08.000000000 +0000 @@ -0,0 +1,46 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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 CCL_API_H +#define CCL_API_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* returns a list of devices for selection, array is name NULL pointer + * terminated and must not be freed */ + +typedef struct CCLDeviceInfo { + const char *identifier; + const char *name; + int value; +} CCLDeviceInfo; + +CCLDeviceInfo *CCL_compute_device_list(int opencl); + +/* create python module _cycles used by addon */ + +void *CCL_python_module_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* CCL_API_H */ + diff -Nru blender-2.61/intern/cycles/blender/CMakeLists.txt blender-2.62/intern/cycles/blender/CMakeLists.txt --- blender-2.61/intern/cycles/blender/CMakeLists.txt 2011-12-13 19:39:48.000000000 +0000 +++ blender-2.62/intern/cycles/blender/CMakeLists.txt 2012-02-15 19:24:08.000000000 +0000 @@ -27,6 +27,7 @@ blender_shader.cpp blender_sync.cpp + CCL_api.h blender_sync.h blender_session.h blender_util.h diff -Nru blender-2.61/intern/cycles/bvh/bvh.cpp blender-2.62/intern/cycles/bvh/bvh.cpp --- blender-2.61/intern/cycles/bvh/bvh.cpp 2011-12-13 19:37:15.000000000 +0000 +++ blender-2.62/intern/cycles/bvh/bvh.cpp 2012-02-15 19:21:39.000000000 +0000 @@ -75,12 +75,18 @@ foreach(Object *ob, objects) { key.add(ob->mesh->verts); key.add(ob->mesh->triangles); + key.add(&ob->bounds, sizeof(ob->bounds)); + key.add(&ob->visibility, sizeof(ob->visibility)); + key.add(&ob->mesh->transform_applied, sizeof(bool)); } CacheData value; if(Cache::global.lookup(key, value)) { + cache_filename = key.get_filename(); + value.read(pack.root_index); + value.read(pack.SAH); value.read(pack.nodes); value.read(pack.object_node); @@ -101,6 +107,7 @@ CacheData value; value.add(pack.root_index); + value.add(pack.SAH); value.add(pack.nodes); value.add(pack.object_node); @@ -111,6 +118,26 @@ value.add(pack.is_leaf); Cache::global.insert(key, value); + + cache_filename = key.get_filename(); +} + +void BVH::clear_cache_except() +{ + set except; + + if(!cache_filename.empty()) + except.insert(cache_filename); + + foreach(Object *ob, objects) { + Mesh *mesh = ob->mesh; + BVH *bvh = mesh->bvh; + + if(bvh && !bvh->cache_filename.empty()) + except.insert(bvh->cache_filename); + } + + Cache::global.clear_except("bvh", except); } /* Building */ @@ -177,6 +204,10 @@ if(params.use_cache) { progress.set_substatus("Writing BVH cache"); cache_write(key); + + /* clear other bvh files from cache */ + if(params.top_level) + clear_cache_except(); } } diff -Nru blender-2.61/intern/cycles/bvh/bvh.h blender-2.62/intern/cycles/bvh/bvh.h --- blender-2.61/intern/cycles/bvh/bvh.h 2011-12-13 19:37:15.000000000 +0000 +++ blender-2.62/intern/cycles/bvh/bvh.h 2012-02-15 19:21:39.000000000 +0000 @@ -20,6 +20,7 @@ #include "bvh_params.h" +#include "util_string.h" #include "util_types.h" #include "util_vector.h" @@ -83,6 +84,7 @@ PackedBVH pack; BVHParams params; vector objects; + string cache_filename; static BVH *create(const BVHParams& params, const vector& objects); virtual ~BVH() {} @@ -90,6 +92,8 @@ void build(Progress& progress); void refit(Progress& progress); + void clear_cache_except(); + protected: BVH(const BVHParams& params, const vector& objects); diff -Nru blender-2.61/intern/cycles/bvh/bvh_params.h blender-2.62/intern/cycles/bvh/bvh_params.h --- blender-2.61/intern/cycles/bvh/bvh_params.h 2011-12-13 19:37:15.000000000 +0000 +++ blender-2.62/intern/cycles/bvh/bvh_params.h 2012-02-15 19:21:39.000000000 +0000 @@ -26,7 +26,7 @@ { public: /* spatial split area threshold */ - bool use_spatial_split; + int use_spatial_split; float spatial_split_alpha; /* SAH costs */ @@ -38,13 +38,15 @@ int max_leaf_size; /* object or mesh level bvh */ - bool top_level; + int top_level; /* disk cache */ - bool use_cache; + int use_cache; /* QBVH */ - bool use_qbvh; + int use_qbvh; + + int pad; /* fixed parameters */ enum { @@ -67,6 +69,7 @@ top_level = false; use_cache = false; use_qbvh = false; + pad = false; } /* SAH costs */ diff -Nru blender-2.61/intern/cycles/CMakeLists.txt blender-2.62/intern/cycles/CMakeLists.txt --- blender-2.61/intern/cycles/CMakeLists.txt 2011-12-13 19:39:53.000000000 +0000 +++ blender-2.62/intern/cycles/CMakeLists.txt 2012-02-15 19:24:16.000000000 +0000 @@ -36,19 +36,19 @@ endif() if(WITH_CYCLES_NETWORK) - add_definitions(-DWITH_NETWORK) + add_definitions(-DWITH_NETWORK) endif() if(WITH_CYCLES_OSL) - add_definitions(-DWITH_OSL) + add_definitions(-DWITH_OSL) endif() if(WITH_CYCLES_PARTIO) - add_definitions(-DWITH_PARTIO) + add_definitions(-DWITH_PARTIO) endif() if(WITH_CYCLES_CUDA_BINARIES) - add_definitions(-DWITH_CUDA_BINARIES) + add_definitions(-DWITH_CUDA_BINARIES) endif() add_definitions(-DWITH_OPENCL) diff -Nru blender-2.61/intern/cycles/device/device.cpp blender-2.62/intern/cycles/device/device.cpp --- blender-2.61/intern/cycles/device/device.cpp 2011-12-13 19:37:17.000000000 +0000 +++ blender-2.62/intern/cycles/device/device.cpp 2012-02-15 19:21:40.000000000 +0000 @@ -24,6 +24,7 @@ #include "util_cuda.h" #include "util_debug.h" +#include "util_foreach.h" #include "util_math.h" #include "util_opencl.h" #include "util_opengl.h" @@ -37,25 +38,50 @@ DeviceTask::DeviceTask(Type type_) : type(type_), x(0), y(0), w(0), h(0), rng_state(0), rgba(0), buffer(0), sample(0), resolution(0), - displace_input(0), displace_offset(0), displace_x(0), displace_w(0) + shader_input(0), shader_output(0), + shader_eval_type(0), shader_x(0), shader_w(0) { } -void DeviceTask::split(ThreadQueue& tasks, int num) +void DeviceTask::split_max_size(list& tasks, int max_size) { - if(type == DISPLACE) { - num = min(displace_w, num); + int num; + + if(type == SHADER) { + num = (shader_w + max_size - 1)/max_size; + } + else { + max_size = max(1, max_size/w); + num = (h + max_size - 1)/max_size; + } + + split(tasks, num); +} + +void DeviceTask::split(ThreadQueue& queue, int num) +{ + list tasks; + split(tasks, num); + + foreach(DeviceTask& task, tasks) + queue.push(task); +} + +void DeviceTask::split(list& tasks, int num) +{ + if(type == SHADER) { + num = min(shader_w, num); for(int i = 0; i < num; i++) { - int tx = displace_x + (displace_w/num)*i; - int tw = (i == num-1)? displace_w - i*(displace_w/num): displace_w/num; + int tx = shader_x + (shader_w/num)*i; + int tw = (i == num-1)? shader_w - i*(shader_w/num): shader_w/num; DeviceTask task = *this; - task.displace_x = tx; - task.displace_w = tw; + task.shader_x = tx; + task.shader_w = tw; - tasks.push(task); + tasks.push_back(task); } } else { @@ -70,7 +96,7 @@ task.y = ty; task.h = th; - tasks.push(task); + tasks.push_back(task); } } } @@ -84,7 +110,7 @@ void Device::pixels_copy_from(device_memory& mem, int y, int w, int h) { - mem_copy_from(mem, sizeof(uint8_t)*4*y*w, sizeof(uint8_t)*4*w*h); + mem_copy_from(mem, y, w, h, sizeof(uint8_t)*4); } void Device::pixels_free(device_memory& mem) @@ -92,7 +118,7 @@ mem_free(mem); } -void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int width, int height, bool transparent) +void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int width, int height, bool transparent) { pixels_copy_from(rgba, y, w, h); @@ -102,7 +128,7 @@ } glPixelZoom((float)width/(float)w, (float)height/(float)h); - glRasterPos2f(0, y); + glRasterPos2f(0, dy); uint8_t *pixels = (uint8_t*)rgba.data_pointer; @@ -119,36 +145,36 @@ glDisable(GL_BLEND); } -Device *Device::create(DeviceType type, bool background, int threads) +Device *Device::create(DeviceInfo& info, bool background, int threads) { Device *device; - switch(type) { + switch(info.type) { case DEVICE_CPU: - device = device_cpu_create(threads); + device = device_cpu_create(info, threads); break; #ifdef WITH_CUDA case DEVICE_CUDA: if(cuLibraryInit()) - device = device_cuda_create(background); + device = device_cuda_create(info, background); else device = NULL; break; #endif #ifdef WITH_MULTI case DEVICE_MULTI: - device = device_multi_create(background); + device = device_multi_create(info, background); break; #endif #ifdef WITH_NETWORK case DEVICE_NETWORK: - device = device_network_create("127.0.0.1"); + device = device_network_create(info, "127.0.0.1"); break; #endif #ifdef WITH_OPENCL case DEVICE_OPENCL: if(clLibraryInit()) - device = device_opencl_create(background); + device = device_opencl_create(info, background); else device = NULL; break; @@ -157,6 +183,9 @@ return NULL; } + if(device) + device->info = info; + return device; } @@ -192,31 +221,68 @@ return ""; } -vector Device::available_types() +vector& Device::available_types() { - vector types; + static vector types; + static bool types_init = false; - types.push_back(DEVICE_CPU); + if(!types_init) { + types.push_back(DEVICE_CPU); #ifdef WITH_CUDA - if(cuLibraryInit()) - types.push_back(DEVICE_CUDA); + if(cuLibraryInit()) + types.push_back(DEVICE_CUDA); #endif #ifdef WITH_OPENCL - if(clLibraryInit()) - types.push_back(DEVICE_OPENCL); + if(clLibraryInit()) + types.push_back(DEVICE_OPENCL); #endif #ifdef WITH_NETWORK - types.push_back(DEVICE_NETWORK); + types.push_back(DEVICE_NETWORK); #endif #ifdef WITH_MULTI - types.push_back(DEVICE_MULTI); + types.push_back(DEVICE_MULTI); #endif + types_init = true; + } + return types; } +vector& Device::available_devices() +{ + static vector devices; + static bool devices_init = false; + + if(!devices_init) { +#ifdef WITH_CUDA + if(cuLibraryInit()) + device_cuda_info(devices); +#endif + +#ifdef WITH_OPENCL + if(clLibraryInit()) + device_opencl_info(devices); +#endif + +#ifdef WITH_MULTI + device_multi_info(devices); +#endif + + device_cpu_info(devices); + +#ifdef WITH_NETWORK + device_network_info(devices); +#endif + + devices_init = true; + } + + return devices; +} + CCL_NAMESPACE_END diff -Nru blender-2.61/intern/cycles/device/device_cpu.cpp blender-2.62/intern/cycles/device/device_cpu.cpp --- blender-2.61/intern/cycles/device/device_cpu.cpp 2011-12-13 19:37:17.000000000 +0000 +++ blender-2.62/intern/cycles/device/device_cpu.cpp 2012-02-15 19:21:40.000000000 +0000 @@ -72,16 +72,11 @@ kernel_globals_free(kg); } - bool support_full_kernel() + bool support_advanced_shading() { return true; } - string description() - { - return system_cpu_brand_string(); - } - void mem_alloc(device_memory& mem, MemoryType type) { mem.device_pointer = mem.data_pointer; @@ -92,7 +87,7 @@ /* no-op */ } - void mem_copy_from(device_memory& mem, size_t offset, size_t size) + void mem_copy_from(device_memory& mem, int y, int w, int h, int elem) { /* no-op */ } @@ -141,8 +136,8 @@ thread_path_trace(task); else if(task.type == DeviceTask::TONEMAP) thread_tonemap(task); - else if(task.type == DeviceTask::DISPLACE) - thread_displace(task); + else if(task.type == DeviceTask::SHADER) + thread_shader(task); tasks.worker_done(); } @@ -162,7 +157,8 @@ if(system_cpu_support_optimized()) { for(int y = task.y; y < task.y + task.h; y++) { for(int x = task.x; x < task.x + task.w; x++) - kernel_cpu_optimized_path_trace(kg, (float4*)task.buffer, (unsigned int*)task.rng_state, task.sample, x, y); + kernel_cpu_optimized_path_trace(kg, (float*)task.buffer, (unsigned int*)task.rng_state, + task.sample, x, y, task.offset, task.stride); if(tasks.worker_cancel()) break; @@ -173,7 +169,8 @@ { for(int y = task.y; y < task.y + task.h; y++) { for(int x = task.x; x < task.x + task.w; x++) - kernel_cpu_path_trace(kg, (float4*)task.buffer, (unsigned int*)task.rng_state, task.sample, x, y); + kernel_cpu_path_trace(kg, (float*)task.buffer, (unsigned int*)task.rng_state, + task.sample, x, y, task.offset, task.stride); if(tasks.worker_cancel()) break; @@ -192,18 +189,20 @@ if(system_cpu_support_optimized()) { for(int y = task.y; y < task.y + task.h; y++) for(int x = task.x; x < task.x + task.w; x++) - kernel_cpu_optimized_tonemap(kg, (uchar4*)task.rgba, (float4*)task.buffer, task.sample, task.resolution, x, y); + kernel_cpu_optimized_tonemap(kg, (uchar4*)task.rgba, (float*)task.buffer, + task.sample, task.resolution, x, y, task.offset, task.stride); } else #endif { for(int y = task.y; y < task.y + task.h; y++) for(int x = task.x; x < task.x + task.w; x++) - kernel_cpu_tonemap(kg, (uchar4*)task.rgba, (float4*)task.buffer, task.sample, task.resolution, x, y); + kernel_cpu_tonemap(kg, (uchar4*)task.rgba, (float*)task.buffer, + task.sample, task.resolution, x, y, task.offset, task.stride); } } - void thread_displace(DeviceTask& task) + void thread_shader(DeviceTask& task) { #ifdef WITH_OSL if(kernel_osl_use(kg)) @@ -212,8 +211,8 @@ #ifdef WITH_OPTIMIZED_KERNEL if(system_cpu_support_optimized()) { - for(int x = task.displace_x; x < task.displace_x + task.displace_w; x++) { - kernel_cpu_optimized_displace(kg, (uint4*)task.displace_input, (float3*)task.displace_offset, x); + for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) { + kernel_cpu_optimized_shader(kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x); if(tasks.worker_cancel()) break; @@ -222,8 +221,8 @@ else #endif { - for(int x = task.displace_x; x < task.displace_x + task.displace_w; x++) { - kernel_cpu_displace(kg, (uint4*)task.displace_input, (float3*)task.displace_offset, x); + for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) { + kernel_cpu_shader(kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x); if(tasks.worker_cancel()) break; @@ -254,10 +253,23 @@ } }; -Device *device_cpu_create(int threads) +Device *device_cpu_create(DeviceInfo& info, int threads) { return new CPUDevice(threads); } +void device_cpu_info(vector& devices) +{ + DeviceInfo info; + + info.type = DEVICE_CPU; + info.description = system_cpu_brand_string(); + info.id = "CPU"; + info.num = 0; + info.advanced_shading = true; + + devices.insert(devices.begin(), info); +} + CCL_NAMESPACE_END diff -Nru blender-2.61/intern/cycles/device/device_cuda.cpp blender-2.62/intern/cycles/device/device_cuda.cpp --- blender-2.61/intern/cycles/device/device_cuda.cpp 2011-12-13 19:37:17.000000000 +0000 +++ blender-2.62/intern/cycles/device/device_cuda.cpp 2012-02-15 19:21:40.000000000 +0000 @@ -106,11 +106,6 @@ } } - static int cuda_align_up(int& offset, int alignment) - { - return (offset + alignment - 1) & ~(alignment - 1); - } - #ifdef NDEBUG #define cuda_abort() #else @@ -159,11 +154,11 @@ cuda_assert(cuCtxSetCurrent(NULL)); } - CUDADevice(bool background_) + CUDADevice(DeviceInfo& info, bool background_) { background = background_; - cuDevId = 0; + cuDevId = info.num; cuDevice = 0; cuContext = 0; @@ -194,26 +189,6 @@ cuda_assert(cuCtxDetach(cuContext)) } - bool support_full_kernel() - { - int major, minor; - cuDeviceComputeCapability(&major, &minor, cuDevId); - - return (major >= 2); - } - - string description() - { - /* print device information */ - char deviceName[100]; - - cuda_push_context(); - cuDeviceGetName(deviceName, 256, cuDevId); - cuda_pop_context(); - - return string("CUDA ") + deviceName; - } - bool support_device(bool experimental) { if(!experimental) { @@ -221,7 +196,7 @@ cuDeviceComputeCapability(&major, &minor, cuDevId); if(major <= 1 && minor <= 2) { - cuda_error(string_printf("CUDA device supported only with shader model 1.3 or up, found %d.%d.", major, minor)); + cuda_error(string_printf("CUDA device supported only with compute capability 1.3 or up, found %d.%d.", major, minor)); return false; } } @@ -253,9 +228,9 @@ #if defined(WITH_CUDA_BINARIES) && defined(_WIN32) if(major <= 1 && minor <= 2) - cuda_error(string_printf("CUDA device supported only with shader model 1.3 or up, found %d.%d.", major, minor)); + cuda_error(string_printf("CUDA device supported only compute capability 1.3 or up, found %d.%d.", major, minor)); else - cuda_error(string_printf("CUDA binary kernel for this graphics card shader model (%d.%d) not found.", major, minor)); + cuda_error(string_printf("CUDA binary kernel for this graphics card compute capability (%d.%d) not found.", major, minor)); return ""; #else /* if not, find CUDA compiler */ @@ -341,9 +316,11 @@ cuda_pop_context(); } - void mem_copy_from(device_memory& mem, size_t offset, size_t size) + void mem_copy_from(device_memory& mem, int y, int w, int h, int elem) { - /* todo: offset is ignored */ + size_t offset = elem*y*w; + size_t size = elem*w*h; + cuda_push_context(); cuda_assert(cuMemcpyDtoH((uchar*)mem.data_pointer + offset, (CUdeviceptr)((uchar*)mem.device_pointer + offset), size)) @@ -503,7 +480,7 @@ offset += sizeof(d_rng_state); int sample = task.sample; - offset = cuda_align_up(offset, __alignof(sample)); + offset = align_up(offset, __alignof(sample)); cuda_assert(cuParamSeti(cuPathTrace, offset, task.sample)) offset += sizeof(task.sample); @@ -520,6 +497,12 @@ cuda_assert(cuParamSeti(cuPathTrace, offset, task.h)) offset += sizeof(task.h); + cuda_assert(cuParamSeti(cuPathTrace, offset, task.offset)) + offset += sizeof(task.offset); + + cuda_assert(cuParamSeti(cuPathTrace, offset, task.stride)) + offset += sizeof(task.stride); + cuda_assert(cuParamSetSize(cuPathTrace, offset)) /* launch kernel: todo find optimal size, cache config for fermi */ @@ -561,7 +544,7 @@ offset += sizeof(d_buffer); int sample = task.sample; - offset = cuda_align_up(offset, __alignof(sample)); + offset = align_up(offset, __alignof(sample)); cuda_assert(cuParamSeti(cuFilmConvert, offset, task.sample)) offset += sizeof(task.sample); @@ -581,6 +564,12 @@ cuda_assert(cuParamSeti(cuFilmConvert, offset, task.h)) offset += sizeof(task.h); + cuda_assert(cuParamSeti(cuFilmConvert, offset, task.offset)) + offset += sizeof(task.offset); + + cuda_assert(cuParamSeti(cuFilmConvert, offset, task.stride)) + offset += sizeof(task.stride); + cuda_assert(cuParamSetSize(cuFilmConvert, offset)) /* launch kernel: todo find optimal size, cache config for fermi */ @@ -603,16 +592,16 @@ cuda_pop_context(); } - void displace(DeviceTask& task) + void shader(DeviceTask& task) { cuda_push_context(); CUfunction cuDisplace; - CUdeviceptr d_input = cuda_device_ptr(task.displace_input); - CUdeviceptr d_offset = cuda_device_ptr(task.displace_offset); + CUdeviceptr d_input = cuda_device_ptr(task.shader_input); + CUdeviceptr d_offset = cuda_device_ptr(task.shader_output); /* get kernel function */ - cuda_assert(cuModuleGetFunction(&cuDisplace, cuModule, "kernel_cuda_displace")) + cuda_assert(cuModuleGetFunction(&cuDisplace, cuModule, "kernel_cuda_shader")) /* pass in parameters */ int offset = 0; @@ -623,11 +612,14 @@ cuda_assert(cuParamSetv(cuDisplace, offset, &d_offset, sizeof(d_offset))) offset += sizeof(d_offset); - int displace_x = task.displace_x; - offset = cuda_align_up(offset, __alignof(displace_x)); + int shader_eval_type = task.shader_eval_type; + offset = align_up(offset, __alignof(shader_eval_type)); - cuda_assert(cuParamSeti(cuDisplace, offset, task.displace_x)) - offset += sizeof(task.displace_x); + cuda_assert(cuParamSeti(cuDisplace, offset, task.shader_eval_type)) + offset += sizeof(task.shader_eval_type); + + cuda_assert(cuParamSeti(cuDisplace, offset, task.shader_x)) + offset += sizeof(task.shader_x); cuda_assert(cuParamSetSize(cuDisplace, offset)) @@ -637,7 +629,7 @@ #else int xthreads = 8; #endif - int xblocks = (task.displace_w + xthreads - 1)/xthreads; + int xblocks = (task.shader_w + xthreads - 1)/xthreads; cuda_assert(cuFuncSetCacheConfig(cuDisplace, CU_FUNC_CACHE_PREFER_L1)) cuda_assert(cuFuncSetBlockShape(cuDisplace, xthreads, 1, 1)) @@ -753,7 +745,7 @@ } } - void draw_pixels(device_memory& mem, int y, int w, int h, int width, int height, bool transparent) + void draw_pixels(device_memory& mem, int y, int w, int h, int dy, int width, int height, bool transparent) { if(!background) { PixelMem pmem = pixel_mem_map[mem.device_pointer]; @@ -779,7 +771,7 @@ glColor3f(1.0f, 1.0f, 1.0f); glPushMatrix(); - glTranslatef(0.0f, (float)y, 0.0f); + glTranslatef(0.0f, (float)dy, 0.0f); glBegin(GL_QUADS); @@ -807,7 +799,7 @@ return; } - Device::draw_pixels(mem, y, w, h, width, height, transparent); + Device::draw_pixels(mem, y, w, h, dy, width, height, transparent); } void task_add(DeviceTask& task) @@ -816,8 +808,8 @@ tonemap(task); else if(task.type == DeviceTask::PATH_TRACE) path_trace(task); - else if(task.type == DeviceTask::DISPLACE) - displace(task); + else if(task.type == DeviceTask::SHADER) + shader(task); } void task_wait() @@ -834,9 +826,51 @@ } }; -Device *device_cuda_create(bool background) +Device *device_cuda_create(DeviceInfo& info, bool background) { - return new CUDADevice(background); + return new CUDADevice(info, background); +} + +void device_cuda_info(vector& devices) +{ + int count = 0; + + if(cuInit(0) != CUDA_SUCCESS) + return; + if(cuDeviceGetCount(&count) != CUDA_SUCCESS) + return; + + vector display_devices; + + for(int num = 0; num < count; num++) { + char name[256]; + int attr; + + if(cuDeviceGetName(name, 256, num) != CUDA_SUCCESS) + continue; + + DeviceInfo info; + + info.type = DEVICE_CUDA; + info.description = string(name); + info.id = string_printf("CUDA_%d", num); + info.num = num; + + int major, minor; + cuDeviceComputeCapability(&major, &minor, num); + info.advanced_shading = (major >= 2); + + /* if device has a kernel timeout, assume it is used for display */ + if(cuDeviceGetAttribute(&attr, CU_DEVICE_ATTRIBUTE_KERNEL_EXEC_TIMEOUT, num) == CUDA_SUCCESS && attr == 1) { + info.display_device = true; + display_devices.push_back(info); + } + else + devices.push_back(info); + } + + if(!display_devices.empty()) + devices.insert(devices.end(), display_devices.begin(), display_devices.end()); } CCL_NAMESPACE_END diff -Nru blender-2.61/intern/cycles/device/device.h blender-2.62/intern/cycles/device/device.h --- blender-2.61/intern/cycles/device/device.h 2011-12-13 19:37:17.000000000 +0000 +++ blender-2.62/intern/cycles/device/device.h 2012-02-15 19:21:40.000000000 +0000 @@ -23,6 +23,7 @@ #include "device_memory.h" +#include "util_list.h" #include "util_string.h" #include "util_thread.h" #include "util_types.h" @@ -32,6 +33,8 @@ class Progress; +/* Device Types */ + enum DeviceType { DEVICE_NONE, DEVICE_CPU, @@ -41,17 +44,31 @@ DEVICE_MULTI }; -enum MemoryType { - MEM_READ_ONLY, - MEM_WRITE_ONLY, - MEM_READ_WRITE +class DeviceInfo { +public: + DeviceType type; + string description; + string id; + int num; + bool display_device; + bool advanced_shading; + vector multi_devices; + + DeviceInfo() + { + type = DEVICE_CPU; + id = "CPU"; + num = 0; + display_device = false; + advanced_shading = true; + } }; /* Device Task */ class DeviceTask { public: - typedef enum { PATH_TRACE, TONEMAP, DISPLACE } Type; + typedef enum { PATH_TRACE, TONEMAP, SHADER } Type; Type type; int x, y, w, h; @@ -60,13 +77,18 @@ device_ptr buffer; int sample; int resolution; + int offset, stride; - device_ptr displace_input; - device_ptr displace_offset; - int displace_x, displace_w; + device_ptr shader_input; + device_ptr shader_output; + int shader_eval_type; + int shader_x, shader_w; DeviceTask(Type type = PATH_TRACE); + + void split(list& tasks, int num); void split(ThreadQueue& tasks, int num); + void split_max_size(list& tasks, int max_size); }; /* Device */ @@ -81,17 +103,15 @@ public: virtual ~Device() {} - virtual bool support_full_kernel() = 0; - /* info */ - virtual string description() = 0; - const string& error_message() { return error_msg; } + DeviceInfo info; + virtual const string& error_message() { return error_msg; } /* regular memory */ virtual void mem_alloc(device_memory& mem, MemoryType type) = 0; virtual void mem_copy_to(device_memory& mem) = 0; virtual void mem_copy_from(device_memory& mem, - size_t offset, size_t size) = 0; + int y, int w, int h, int elem) = 0; virtual void mem_zero(device_memory& mem) = 0; virtual void mem_free(device_memory& mem) = 0; @@ -121,7 +141,7 @@ /* opengl drawing */ virtual void draw_pixels(device_memory& mem, int y, int w, int h, - int width, int height, bool transparent); + int dy, int width, int height, bool transparent); #ifdef WITH_NETWORK /* networking */ @@ -129,11 +149,12 @@ #endif /* static */ - static Device *create(DeviceType type, bool background = true, int threads = 0); + static Device *create(DeviceInfo& info, bool background = true, int threads = 0); static DeviceType type_from_string(const char *name); static string string_from_type(DeviceType type); - static vector available_types(); + static vector& available_types(); + static vector& available_devices(); }; CCL_NAMESPACE_END diff -Nru blender-2.61/intern/cycles/device/device_intern.h blender-2.62/intern/cycles/device/device_intern.h --- blender-2.61/intern/cycles/device/device_intern.h 2011-12-13 19:37:17.000000000 +0000 +++ blender-2.62/intern/cycles/device/device_intern.h 2012-02-15 19:21:40.000000000 +0000 @@ -23,11 +23,17 @@ class Device; -Device *device_cpu_create(int threads); -Device *device_opencl_create(bool background); -Device *device_cuda_create(bool background); -Device *device_network_create(const char *address); -Device *device_multi_create(bool background); +Device *device_cpu_create(DeviceInfo& info, int threads); +Device *device_opencl_create(DeviceInfo& info, bool background); +Device *device_cuda_create(DeviceInfo& info, bool background); +Device *device_network_create(DeviceInfo& info, const char *address); +Device *device_multi_create(DeviceInfo& info, bool background); + +void device_cpu_info(vector& devices); +void device_opencl_info(vector& devices); +void device_cuda_info(vector& devices); +void device_network_info(vector& devices); +void device_multi_info(vector& devices); CCL_NAMESPACE_END diff -Nru blender-2.61/intern/cycles/device/device_memory.h blender-2.62/intern/cycles/device/device_memory.h --- blender-2.61/intern/cycles/device/device_memory.h 2011-12-13 19:37:17.000000000 +0000 +++ blender-2.62/intern/cycles/device/device_memory.h 2012-02-15 19:21:40.000000000 +0000 @@ -36,6 +36,12 @@ CCL_NAMESPACE_BEGIN +enum MemoryType { + MEM_READ_ONLY, + MEM_WRITE_ONLY, + MEM_READ_WRITE +}; + /* Supported Data Types */ enum DataType { diff -Nru blender-2.61/intern/cycles/device/device_multi.cpp blender-2.62/intern/cycles/device/device_multi.cpp --- blender-2.61/intern/cycles/device/device_multi.cpp 2011-12-13 19:37:17.000000000 +0000 +++ blender-2.62/intern/cycles/device/device_multi.cpp 2012-02-15 19:21:40.000000000 +0000 @@ -44,32 +44,18 @@ list devices; device_ptr unique_ptr; - MultiDevice(bool background_) + MultiDevice(DeviceInfo& info, bool background_) : unique_ptr(1) { Device *device; + background = background_; - /* add CPU device */ - device = Device::create(DEVICE_CPU, background); - devices.push_back(SubDevice(device)); - -#ifdef WITH_CUDA - /* try to add GPU device */ - device = Device::create(DEVICE_CUDA, background); - if(device) { + foreach(DeviceInfo& subinfo, info.multi_devices) { + device = Device::create(subinfo, background); devices.push_back(SubDevice(device)); } - else -#endif - { -#ifdef WITH_OPENCL - device = Device::create(DEVICE_OPENCL, background); - if(device) - devices.push_back(SubDevice(device)); -#endif - } -#ifdef WITH_NETWORK +#if 0 //def WITH_NETWORK /* try to add network devices */ ServerDiscovery discovery(true); time_sleep(1.0); @@ -77,7 +63,7 @@ list servers = discovery.get_server_list(); foreach(string& server, servers) { - device = device_network_create(server.c_str()); + device = device_network_create(info, server.c_str()); if(device) devices.push_back(SubDevice(device)); } @@ -90,46 +76,17 @@ delete sub.device; } - bool support_full_kernel() - { - foreach(SubDevice& sub, devices) { - if(!sub.device->support_full_kernel()) - return false; - } - - return true; - } - - string description() + const string& error_message() { - /* create map to find duplicate descriptions */ - map dupli_map; - map::iterator dt; - foreach(SubDevice& sub, devices) { - string key = sub.device->description(); - - if(dupli_map.find(key) == dupli_map.end()) - dupli_map[key] = 1; - else - dupli_map[key]++; - } - - /* generate string */ - stringstream desc; - bool first = true; - - for(dt = dupli_map.begin(); dt != dupli_map.end(); dt++) { - if(!first) desc << ", "; - first = false; - - if(dt->second > 1) - desc << dt->second << "x " << dt->first; - else - desc << dt->first; + if(sub.device->error_message() != "") { + if(error_msg == "") + error_msg = sub.device->error_message(); + break; + } } - return desc.str(); + return error_msg; } bool load_kernels(bool experimental) @@ -164,15 +121,18 @@ mem.device_pointer = tmp; } - void mem_copy_from(device_memory& mem, size_t offset, size_t size) + void mem_copy_from(device_memory& mem, int y, int w, int h, int elem) { device_ptr tmp = mem.device_pointer; + int i = 0, sub_h = h/devices.size(); - /* todo: how does this work? */ foreach(SubDevice& sub, devices) { + int sy = y + i*sub_h; + int sh = (i == (int)devices.size() - 1)? h - sub_h*i: sub_h; + mem.device_pointer = sub.ptr_map[tmp]; - sub.device->mem_copy_from(mem, offset, size); - break; + sub.device->mem_copy_from(mem, sy, w, sh, elem); + i++; } mem.device_pointer = tmp; @@ -274,7 +234,7 @@ mem.device_pointer = tmp; } - void draw_pixels(device_memory& rgba, int y, int w, int h, int width, int height, bool transparent) + void draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int width, int height, bool transparent) { device_ptr tmp = rgba.device_pointer; int i = 0, sub_h = h/devices.size(); @@ -284,10 +244,11 @@ int sy = y + i*sub_h; int sh = (i == (int)devices.size() - 1)? h - sub_h*i: sub_h; int sheight = (i == (int)devices.size() - 1)? height - sub_height*i: sub_height; + int sdy = dy + i*sub_height; /* adjust math for w/width */ rgba.device_pointer = sub.ptr_map[tmp]; - sub.device->draw_pixels(rgba, sy, w, sh, width, sheight, transparent); + sub.device->draw_pixels(rgba, sy, w, sh, sdy, width, sheight, transparent); i++; } @@ -306,8 +267,8 @@ if(task.buffer) subtask.buffer = sub.ptr_map[task.buffer]; if(task.rng_state) subtask.rng_state = sub.ptr_map[task.rng_state]; if(task.rgba) subtask.rgba = sub.ptr_map[task.rgba]; - if(task.displace_input) subtask.displace_input = sub.ptr_map[task.displace_input]; - if(task.displace_offset) subtask.displace_offset = sub.ptr_map[task.displace_offset]; + if(task.shader_input) subtask.shader_input = sub.ptr_map[task.shader_input]; + if(task.shader_output) subtask.shader_output = sub.ptr_map[task.shader_output]; sub.device->task_add(subtask); } @@ -327,9 +288,113 @@ } }; -Device *device_multi_create(bool background) +Device *device_multi_create(DeviceInfo& info, bool background) +{ + return new MultiDevice(info, background); +} + +static void device_multi_add(vector& devices, DeviceType type, bool with_display, const char *id_fmt, int num) +{ + DeviceInfo info; + + /* create map to find duplicate descriptions */ + map dupli_map; + map::iterator dt; + int num_added = 0, num_display = 0; + + info.advanced_shading = true; + + foreach(DeviceInfo& subinfo, devices) { + if(subinfo.type == type) { + if(subinfo.display_device) { + if(with_display) + num_display++; + else + continue; + } + + string key = subinfo.description; + + if(dupli_map.find(key) == dupli_map.end()) + dupli_map[key] = 1; + else + dupli_map[key]++; + + info.multi_devices.push_back(subinfo); + if(subinfo.display_device) + info.display_device = true; + if(!subinfo.advanced_shading) + info.advanced_shading = false; + num_added++; + } + } + + if(num_added <= 1 || (with_display && num_display == 0)) + return; + + /* generate string */ + stringstream desc; + vector last_tokens; + bool first = true; + + for(dt = dupli_map.begin(); dt != dupli_map.end(); dt++) { + if(!first) desc << " + "; + first = false; + + /* get name and count */ + string name = dt->first; + int count = dt->second; + + /* strip common prefixes */ + vector tokens; + string_split(tokens, dt->first); + + if(tokens.size() > 1) { + int i; + + for(i = 0; i < tokens.size() && i < last_tokens.size(); i++) + if(tokens[i] != last_tokens[i]) + break; + + name = ""; + for(; i < tokens.size(); i++) { + name += tokens[i]; + if(i != tokens.size() - 1) + name += " "; + } + } + + last_tokens = tokens; + + /* add */ + if(count > 1) + desc << name << " (" << count << "x)"; + else + desc << name; + } + + /* add info */ + info.type = DEVICE_MULTI; + info.description = desc.str(); + info.id = string_printf(id_fmt, num); + info.display_device = with_display; + info.num = 0; + + if(with_display) + devices.push_back(info); + else + devices.insert(devices.begin(), info); +} + +void device_multi_info(vector& devices) { - return new MultiDevice(background); + int num = 0; + device_multi_add(devices, DEVICE_CUDA, false, "CUDA_MULTI_%d", num++); + device_multi_add(devices, DEVICE_CUDA, true, "CUDA_MULTI_%d", num++); + + num = 0; + device_multi_add(devices, DEVICE_OPENCL, false, "OPENCL_MULTI_%d", num++); + device_multi_add(devices, DEVICE_OPENCL, true, "OPENCL_MULTI_%d", num++); } CCL_NAMESPACE_END diff -Nru blender-2.61/intern/cycles/device/device_network.cpp blender-2.62/intern/cycles/device/device_network.cpp --- blender-2.61/intern/cycles/device/device_network.cpp 2011-12-13 19:37:17.000000000 +0000 +++ blender-2.62/intern/cycles/device/device_network.cpp 2012-02-15 19:21:40.000000000 +0000 @@ -57,24 +57,6 @@ { } - bool support_full_kernel() - { - return false; - } - - string description() - { - RPCSend snd(socket, "description"); - snd.write(); - - RPCReceive rcv(socket); - string desc_string; - - *rcv.archive & desc_string; - - return desc_string + " (remote)"; - } - void mem_alloc(device_memory& mem, MemoryType type) { #if 0 @@ -103,7 +85,7 @@ #endif } - void mem_copy_from(device_memory& mem, size_t offset, size_t size) + void mem_copy_from(device_memory& mem, int y, int w, int h, int elem) { #if 0 RPCSend snd(socket, "mem_copy_from"); @@ -220,11 +202,22 @@ } }; -Device *device_network_create(const char *address) +Device *device_network_create(DeviceInfo& info, const char *address) { return new NetworkDevice(address); } +void device_network_info(vector& devices) +{ + DeviceInfo info; + + info.type = DEVICE_NETWORK; + info.description = "Network Device"; + info.id = "NETWORK"; + info.num = 0; + + devices.push_back(info); +} void Device::server_run() { diff -Nru blender-2.61/intern/cycles/device/device_opencl.cpp blender-2.62/intern/cycles/device/device_opencl.cpp --- blender-2.61/intern/cycles/device/device_opencl.cpp 2011-12-13 19:37:17.000000000 +0000 +++ blender-2.62/intern/cycles/device/device_opencl.cpp 2012-02-15 19:21:40.000000000 +0000 @@ -25,6 +25,7 @@ #include "device.h" #include "device_intern.h" +#include "util_foreach.h" #include "util_map.h" #include "util_math.h" #include "util_md5.h" @@ -52,6 +53,7 @@ map mem_map; device_ptr null_mem; bool device_initialized; + string platform_name; const char *opencl_error_string(cl_int err) { @@ -139,7 +141,7 @@ } } - OpenCLDevice(bool background_) + OpenCLDevice(DeviceInfo& info, bool background_) { background = background_; cpPlatform = NULL; @@ -151,10 +153,9 @@ null_mem = 0; device_initialized = false; - vector platform_ids; + /* setup platform */ cl_uint num_platforms; - /* setup device */ ciErr = clGetPlatformIDs(0, NULL, &num_platforms); if(opencl_error(ciErr)) return; @@ -164,17 +165,37 @@ return; } - platform_ids.resize(num_platforms); - ciErr = clGetPlatformIDs(num_platforms, &platform_ids[0], NULL); + ciErr = clGetPlatformIDs(num_platforms, &cpPlatform, NULL); if(opencl_error(ciErr)) return; - cpPlatform = platform_ids[0]; /* todo: pick specified platform && device */ + char name[256]; + clGetPlatformInfo(cpPlatform, CL_PLATFORM_NAME, sizeof(name), &name, NULL); + platform_name = name; + + /* get devices */ + vector device_ids; + cl_uint num_devices; - ciErr = clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU|CL_DEVICE_TYPE_ACCELERATOR, 1, &cdDevice, NULL); - if(opencl_error(ciErr)) + if(opencl_error(clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU|CL_DEVICE_TYPE_ACCELERATOR, 0, NULL, &num_devices))) + return; + + if(info.num > num_devices) { + if(num_devices == 0) + opencl_error("OpenCL: no devices found."); + else + opencl_error("OpenCL: specified device not found."); return; + } + device_ids.resize(num_devices); + + if(opencl_error(clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU|CL_DEVICE_TYPE_ACCELERATOR, num_devices, &device_ids[0], NULL))) + return; + + cdDevice = device_ids[info.num]; + + /* create context */ cxContext = clCreateContext(0, 1, &cdDevice, NULL, NULL, &ciErr); if(opencl_error(ciErr)) return; @@ -277,14 +298,11 @@ { string build_options = " -cl-fast-relaxed-math "; - /* Full Shading only on NVIDIA cards at the moment */ - char vendor[256]; - - clGetPlatformInfo(cpPlatform, CL_PLATFORM_NAME, sizeof(vendor), &vendor, NULL); - string name = vendor; - - if(name == "NVIDIA CUDA") - build_options += "-D__KERNEL_SHADING__ -D__MULTI_CLOSURE__ "; + /* full shading only on NVIDIA cards at the moment */ + if(platform_name == "NVIDIA CUDA") + build_options += "-D__KERNEL_SHADING__ -D__MULTI_CLOSURE__ -cl-nv-maxrregcount=24 -cl-nv-verbose "; + if(platform_name == "Apple") + build_options += " -D__CL_NO_FLOAT3__ "; return build_options; } @@ -435,20 +453,6 @@ clReleaseContext(cxContext); } - bool support_full_kernel() - { - return false; - } - - string description() - { - char name[1024]; - - clGetDeviceInfo(cdDevice, CL_DEVICE_NAME, sizeof(name), &name, NULL); - - return string("OpenCL ") + name; - } - void mem_alloc(device_memory& mem, MemoryType type) { size_t size = mem.memory_size(); @@ -471,8 +475,11 @@ opencl_assert(ciErr); } - void mem_copy_from(device_memory& mem, size_t offset, size_t size) + void mem_copy_from(device_memory& mem, int y, int w, int h, int elem) { + size_t offset = elem*y*w; + size_t size = elem*w*h; + ciErr = clEnqueueReadBuffer(cqCommandQueue, CL_MEM_PTR(mem.device_pointer), CL_TRUE, offset, size, (uchar*)mem.data_pointer + offset, 0, NULL, NULL); opencl_assert(ciErr); } @@ -541,6 +548,8 @@ cl_int d_w = task.w; cl_int d_h = task.h; cl_int d_sample = task.sample; + cl_int d_offset = task.offset; + cl_int d_stride = task.stride; /* sample arguments */ int narg = 0; @@ -559,6 +568,8 @@ ciErr |= clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_y), (void*)&d_y); ciErr |= clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_w), (void*)&d_w); ciErr |= clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_h), (void*)&d_h); + ciErr |= clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_offset), (void*)&d_offset); + ciErr |= clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_stride), (void*)&d_stride); opencl_assert(ciErr); @@ -611,6 +622,8 @@ cl_int d_h = task.h; cl_int d_sample = task.sample; cl_int d_resolution = task.resolution; + cl_int d_offset = task.offset; + cl_int d_stride = task.stride; /* sample arguments */ int narg = 0; @@ -630,6 +643,8 @@ ciErr |= clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_y), (void*)&d_y); ciErr |= clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_w), (void*)&d_w); ciErr |= clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_h), (void*)&d_h); + ciErr |= clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_offset), (void*)&d_offset); + ciErr |= clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_stride), (void*)&d_stride); opencl_assert(ciErr); @@ -649,12 +664,24 @@ opencl_assert(clFinish(cqCommandQueue)); } - void task_add(DeviceTask& task) + void task_add(DeviceTask& maintask) { - if(task.type == DeviceTask::TONEMAP) - tonemap(task); - else if(task.type == DeviceTask::PATH_TRACE) - path_trace(task); + list tasks; + + /* arbitrary limit to work around apple ATI opencl issue */ + if(platform_name == "Apple") + maintask.split_max_size(tasks, 76800); + else + tasks.push_back(maintask); + + DeviceTask task; + + foreach(DeviceTask& task, tasks) { + if(task.type == DeviceTask::TONEMAP) + tonemap(task); + else if(task.type == DeviceTask::PATH_TRACE) + path_trace(task); + } } void task_wait() @@ -666,9 +693,53 @@ } }; -Device *device_opencl_create(bool background) +Device *device_opencl_create(DeviceInfo& info, bool background) { - return new OpenCLDevice(background); + return new OpenCLDevice(info, background); +} + +void device_opencl_info(vector& devices) +{ + vector device_ids; + cl_uint num_devices; + cl_platform_id platform_id; + cl_uint num_platforms; + + /* get devices */ + if(clGetPlatformIDs(0, NULL, &num_platforms) != CL_SUCCESS || num_platforms == 0) + return; + + if(clGetPlatformIDs(num_platforms, &platform_id, NULL) != CL_SUCCESS) + return; + + if(clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU|CL_DEVICE_TYPE_ACCELERATOR, 0, NULL, &num_devices) != CL_SUCCESS) + return; + + device_ids.resize(num_devices); + + if(clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU|CL_DEVICE_TYPE_ACCELERATOR, num_devices, &device_ids[0], NULL) != CL_SUCCESS) + return; + + /* add devices */ + for(int num = 0; num < num_devices; num++) { + cl_device_id device_id = device_ids[num]; + char name[1024]; + + if(clGetDeviceInfo(device_id, CL_DEVICE_NAME, sizeof(name), &name, NULL) != CL_SUCCESS) + continue; + + DeviceInfo info; + + info.type = DEVICE_OPENCL; + info.description = string(name); + info.id = string_printf("OPENCL_%d", num); + info.num = num; + /* we don't know if it's used for display, but assume it is */ + info.display_device = true; + info.advanced_shading = false; + + devices.push_back(info); + } } CCL_NAMESPACE_END diff -Nru blender-2.61/intern/cycles/kernel/CMakeLists.txt blender-2.62/intern/cycles/kernel/CMakeLists.txt --- blender-2.61/intern/cycles/kernel/CMakeLists.txt 2011-12-13 19:39:43.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/CMakeLists.txt 2012-02-15 19:24:04.000000000 +0000 @@ -15,6 +15,7 @@ set(SRC_HEADERS kernel.h + kernel_accumulate.h kernel_bvh.h kernel_camera.h kernel_compat_cpu.h @@ -30,6 +31,7 @@ kernel_mbvh.h kernel_montecarlo.h kernel_object.h + kernel_passes.h kernel_path.h kernel_qbvh.h kernel_random.h @@ -57,8 +59,11 @@ svm/svm_camera.h svm/svm_closure.h svm/svm_convert.h + svm/svm_checker.h svm/svm_displace.h svm/svm_fresnel.h + svm/svm_gamma.h + svm/svm_brightness.h svm/svm_geometry.h svm/svm_gradient.h svm/svm_hsv.h @@ -72,6 +77,7 @@ svm/svm_musgrave.h svm/svm_noise.h svm/svm_noisetex.h + svm/svm_normal.h svm/svm_sepcomb_rgb.h svm/svm_sky.h svm/svm_tex_coord.h @@ -141,7 +147,7 @@ #set(KERNEL_PREPROCESSED ${CMAKE_CURRENT_BINARY_DIR}/kernel_preprocessed.cl) #add_custom_command( # OUTPUT ${KERNEL_PREPROCESSED} -# COMMAND gcc -x c++ -E ${CMAKE_CURRENT_SOURCE_DIR}/kernel.cl -I ${CMAKE_CURRENT_SOURCE_DIR}/../util/ -DCCL_NAMESPACE_BEGIN= -DCCL_NAMESPACE_END= -DWITH_OPENCL -o ${KERNEL_PREPROCESSED} +# COMMAND gcc -x c++ -E ${CMAKE_CURRENT_SOURCE_DIR}/kernel.cl -I ${CMAKE_CURRENT_SOURCE_DIR}/../util/ -DCCL_NAMESPACE_BEGIN= -DCCL_NAMESPACE_END= -o ${KERNEL_PREPROCESSED} # DEPENDS ${SRC_KERNEL} ${SRC_UTIL_HEADERS}) #add_custom_target(cycles_kernel_preprocess ALL DEPENDS ${KERNEL_PREPROCESSED}) #delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${KERNEL_PREPROCESSED}" ${CYCLES_INSTALL_PATH}/kernel) diff -Nru blender-2.61/intern/cycles/kernel/kernel_accumulate.h blender-2.62/intern/cycles/kernel/kernel_accumulate.h --- blender-2.61/intern/cycles/kernel/kernel_accumulate.h 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/kernel_accumulate.h 2012-02-15 19:24:04.000000000 +0000 @@ -0,0 +1,283 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + */ + +CCL_NAMESPACE_BEGIN + +/* BSDF Eval + * + * BSDF evaluation result, split per BSDF type. This is used to accumulate + * render passes separately. */ + +__device_inline void bsdf_eval_init(BsdfEval *eval, ClosureType type, float3 value, int use_light_pass) +{ +#ifdef __PASSES__ + eval->use_light_pass = use_light_pass; + + if(eval->use_light_pass) { + eval->diffuse = make_float3(0.0f, 0.0f, 0.0f); + eval->glossy = make_float3(0.0f, 0.0f, 0.0f); + eval->transmission = make_float3(0.0f, 0.0f, 0.0f); + eval->transparent = make_float3(0.0f, 0.0f, 0.0f); + + if(type == CLOSURE_BSDF_TRANSPARENT_ID) + eval->transparent = value; + else if(CLOSURE_IS_BSDF_DIFFUSE(type)) + eval->diffuse = value; + else if(CLOSURE_IS_BSDF_GLOSSY(type)) + eval->glossy = value; + else + eval->transmission = value; + } + else + eval->diffuse = value; +#else + *eval = value; +#endif +} + +__device_inline void bsdf_eval_accum(BsdfEval *eval, ClosureType type, float3 value) +{ +#ifdef __PASSES__ + if(eval->use_light_pass) { + if(CLOSURE_IS_BSDF_DIFFUSE(type)) + eval->diffuse += value; + else if(CLOSURE_IS_BSDF_GLOSSY(type)) + eval->glossy += value; + else + eval->transmission += value; + + /* skipping transparent, this function is used by for eval(), will be zero then */ + } + else + eval->diffuse += value; +#else + *eval += value; +#endif +} + +__device_inline bool bsdf_eval_is_zero(BsdfEval *eval) +{ +#ifdef __PASSES__ + if(eval->use_light_pass) { + return is_zero(eval->diffuse) + && is_zero(eval->glossy) + && is_zero(eval->transmission) + && is_zero(eval->transparent); + } + else + return is_zero(eval->diffuse); +#else + return is_zero(*eval); +#endif +} + +__device_inline void bsdf_eval_mul(BsdfEval *eval, float3 value) +{ +#ifdef __PASSES__ + if(eval->use_light_pass) { + eval->diffuse *= value; + eval->glossy *= value; + eval->transmission *= value; + + /* skipping transparent, this function is used by for eval(), will be zero then */ + } + else + eval->diffuse *= value; +#else + *eval *= value; +#endif +} + +/* Path Radiance + * + * We accumulate different render passes separately. After summing at the end + * to get the combined result, it should be identical. We definte directly + * visible as the first non-transparent hit, while indirectly visible are the + * bounces after that. */ + +__device_inline void path_radiance_init(PathRadiance *L, int use_light_pass) +{ + /* clear all */ +#ifdef __PASSES__ + L->use_light_pass = use_light_pass; + + if(use_light_pass) { + L->indirect = make_float3(0.0f, 0.0f, 0.0f); + L->direct_throughput = make_float3(0.0f, 0.0f, 0.0f); + L->direct_emission = make_float3(0.0f, 0.0f, 0.0f); + + L->color_diffuse = make_float3(0.0f, 0.0f, 0.0f); + L->color_glossy = make_float3(0.0f, 0.0f, 0.0f); + L->color_transmission = make_float3(0.0f, 0.0f, 0.0f); + + L->direct_diffuse = make_float3(0.0f, 0.0f, 0.0f); + L->direct_glossy = make_float3(0.0f, 0.0f, 0.0f); + L->direct_transmission = make_float3(0.0f, 0.0f, 0.0f); + + L->indirect_diffuse = make_float3(0.0f, 0.0f, 0.0f); + L->indirect_glossy = make_float3(0.0f, 0.0f, 0.0f); + L->indirect_transmission = make_float3(0.0f, 0.0f, 0.0f); + + L->emission = make_float3(0.0f, 0.0f, 0.0f); + L->background = make_float3(0.0f, 0.0f, 0.0f); + } + else + L->emission = make_float3(0.0f, 0.0f, 0.0f); +#else + *L = make_float3(0.0f, 0.0f, 0.0f); +#endif +} + +__device_inline void path_radiance_bsdf_bounce(PathRadiance *L, float3 *throughput, + BsdfEval *bsdf_eval, float bsdf_pdf, int bounce, int bsdf_label) +{ + float inverse_pdf = 1.0f/bsdf_pdf; + +#ifdef __PASSES__ + if(L->use_light_pass) { + if(bounce == 0) { + if(bsdf_label & LABEL_TRANSPARENT) { + /* transparent bounce before first hit */ + *throughput *= bsdf_eval->transparent*inverse_pdf; + } + else { + /* first on directly visible surface */ + float3 value = *throughput*inverse_pdf; + + L->indirect_diffuse = bsdf_eval->diffuse*value; + L->indirect_glossy = bsdf_eval->glossy*value; + L->indirect_transmission = bsdf_eval->transmission*value; + + *throughput = L->indirect_diffuse + L->indirect_glossy + L->indirect_transmission; + + L->direct_throughput = *throughput; + } + } + else { + /* indirectly visible through BSDF */ + float3 sum = (bsdf_eval->diffuse + bsdf_eval->glossy + bsdf_eval->transmission + bsdf_eval->transparent)*inverse_pdf; + *throughput *= sum; + } + } + else + *throughput *= bsdf_eval->diffuse*inverse_pdf; +#else + *throughput *= *bsdf_eval*inverse_pdf; +#endif +} + +__device_inline void path_radiance_accum_emission(PathRadiance *L, float3 throughput, float3 value, int bounce) +{ +#ifdef __PASSES__ + if(L->use_light_pass) { + if(bounce == 0) + L->emission += throughput*value; + else if(bounce == 1) + L->direct_emission += throughput*value; + else + L->indirect += throughput*value; + } + else + L->emission += throughput*value; +#else + *L += throughput*value; +#endif +} + +__device_inline void path_radiance_accum_light(PathRadiance *L, float3 throughput, BsdfEval *bsdf_eval, int bounce) +{ +#ifdef __PASSES__ + if(L->use_light_pass) { + if(bounce == 0) { + /* directly visible lighting */ + L->direct_diffuse += throughput*bsdf_eval->diffuse; + L->direct_glossy += throughput*bsdf_eval->glossy; + L->direct_transmission += throughput*bsdf_eval->transmission; + } + else { + /* indirectly visible lighting after BSDF bounce */ + float3 sum = bsdf_eval->diffuse + bsdf_eval->glossy + bsdf_eval->transmission; + L->indirect += throughput*sum; + } + } + else + L->emission += throughput*bsdf_eval->diffuse; +#else + *L += throughput*(*bsdf_eval); +#endif +} + +__device_inline void path_radiance_accum_background(PathRadiance *L, float3 throughput, float3 value, int bounce) +{ +#ifdef __PASSES__ + if(L->use_light_pass) { + if(bounce == 0) + L->background += throughput*value; + else if(bounce == 1) + L->direct_emission += throughput*value; + else + L->indirect += throughput*value; + } + else + L->emission += throughput*value; +#else + *L += throughput*value; +#endif +} + +__device_inline float3 safe_divide_color(float3 a, float3 b) +{ + float x, y, z; + + x = (b.x != 0.0f)? a.x/b.x: 0.0f; + y = (b.y != 0.0f)? a.y/b.y: 0.0f; + z = (b.z != 0.0f)? a.z/b.z: 0.0f; + + return make_float3(x, y, z); +} + +__device_inline float3 path_radiance_sum(PathRadiance *L) +{ +#ifdef __PASSES__ + if(L->use_light_pass) { + /* this division is a bit ugly, but means we only have to keep track of + only a single throughput further along the path, here we recover just + the indirect parth that is not influenced by any particular BSDF type */ + L->direct_emission = safe_divide_color(L->direct_emission, L->direct_throughput); + L->direct_diffuse += L->indirect_diffuse*L->direct_emission; + L->direct_glossy += L->indirect_glossy*L->direct_emission; + L->direct_transmission += L->indirect_transmission*L->direct_emission; + + L->indirect = safe_divide_color(L->indirect, L->direct_throughput); + L->indirect_diffuse *= L->indirect; + L->indirect_glossy *= L->indirect; + L->indirect_transmission *= L->indirect; + + return L->emission + L->background + + L->direct_diffuse + L->direct_glossy + L->direct_transmission + + L->indirect_diffuse + L->indirect_glossy + L->indirect_transmission; + } + else + return L->emission; +#else + return *L; +#endif +} + +CCL_NAMESPACE_END + diff -Nru blender-2.61/intern/cycles/kernel/kernel_camera.h blender-2.62/intern/cycles/kernel/kernel_camera.h --- blender-2.61/intern/cycles/kernel/kernel_camera.h 2011-12-13 19:39:43.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/kernel_camera.h 2012-02-15 19:24:04.000000000 +0000 @@ -74,8 +74,8 @@ ray->dP.dx = make_float3(0.0f, 0.0f, 0.0f); ray->dP.dy = make_float3(0.0f, 0.0f, 0.0f); - ray->dD.dx = normalize(Ddiff + kernel_data.cam.dx) - normalize(Ddiff); - ray->dD.dy = normalize(Ddiff + kernel_data.cam.dy) - normalize(Ddiff); + ray->dD.dx = normalize(Ddiff + float4_to_float3(kernel_data.cam.dx)) - normalize(Ddiff); + ray->dD.dy = normalize(Ddiff + float4_to_float3(kernel_data.cam.dy)) - normalize(Ddiff); #endif #ifdef __CAMERA_CLIPPING__ @@ -107,8 +107,8 @@ #ifdef __RAY_DIFFERENTIALS__ /* ray differential */ - ray->dP.dx = kernel_data.cam.dx; - ray->dP.dy = kernel_data.cam.dy; + ray->dP.dx = float4_to_float3(kernel_data.cam.dx); + ray->dP.dy = float4_to_float3(kernel_data.cam.dy); ray->dD.dx = make_float3(0.0f, 0.0f, 0.0f); ray->dD.dy = make_float3(0.0f, 0.0f, 0.0f); diff -Nru blender-2.61/intern/cycles/kernel/kernel.cl blender-2.62/intern/cycles/kernel/kernel.cl --- blender-2.61/intern/cycles/kernel/kernel.cl 2011-12-13 19:39:43.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/kernel.cl 2012-02-15 19:24:04.000000000 +0000 @@ -28,7 +28,7 @@ __kernel void kernel_ocl_path_trace( __constant KernelData *data, - __global float4 *buffer, + __global float *buffer, __global uint *rng_state, #define KERNEL_TEX(type, ttype, name) \ @@ -36,7 +36,7 @@ #include "kernel_textures.h" int sample, - int sx, int sy, int sw, int sh) + int sx, int sy, int sw, int sh, int offset, int stride) { KernelGlobals kglobals, *kg = &kglobals; @@ -50,20 +50,20 @@ int y = sy + get_global_id(1); if(x < sx + sw && y < sy + sh) - kernel_path_trace(kg, buffer, rng_state, sample, x, y); + kernel_path_trace(kg, buffer, rng_state, sample, x, y, offset, stride); } __kernel void kernel_ocl_tonemap( __constant KernelData *data, __global uchar4 *rgba, - __global float4 *buffer, + __global float *buffer, #define KERNEL_TEX(type, ttype, name) \ __global type *name, #include "kernel_textures.h" int sample, int resolution, - int sx, int sy, int sw, int sh) + int sx, int sy, int sw, int sh, int offset, int stride) { KernelGlobals kglobals, *kg = &kglobals; @@ -77,13 +77,13 @@ int y = sy + get_global_id(1); if(x < sx + sw && y < sy + sh) - kernel_film_tonemap(kg, rgba, buffer, sample, resolution, x, y); + kernel_film_tonemap(kg, rgba, buffer, sample, resolution, x, y, offset, stride); } -/*__kernel void kernel_ocl_displace(__global uint4 *input, __global float3 *offset, int sx) +/*__kernel void kernel_ocl_shader(__global uint4 *input, __global float *output, int type, int sx) { int x = sx + get_global_id(0); - kernel_displace(input, offset, x); + kernel_shader_evaluate(input, output, (ShaderEvalType)type, x); }*/ diff -Nru blender-2.61/intern/cycles/kernel/kernel_compat_cpu.h blender-2.62/intern/cycles/kernel/kernel_compat_cpu.h --- blender-2.61/intern/cycles/kernel/kernel_compat_cpu.h 2011-12-13 19:39:43.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/kernel_compat_cpu.h 2012-02-15 19:24:04.000000000 +0000 @@ -141,6 +141,7 @@ }; typedef texture texture_float4; +typedef texture texture_float2; typedef texture texture_float; typedef texture texture_uint; typedef texture texture_int; diff -Nru blender-2.61/intern/cycles/kernel/kernel_compat_cuda.h blender-2.62/intern/cycles/kernel/kernel_compat_cuda.h --- blender-2.61/intern/cycles/kernel/kernel_compat_cuda.h 2011-12-13 19:39:43.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/kernel_compat_cuda.h 2012-02-15 19:24:04.000000000 +0000 @@ -45,6 +45,7 @@ /* Textures */ typedef texture texture_float4; +typedef texture texture_float2; typedef texture texture_float; typedef texture texture_uint; typedef texture texture_int; diff -Nru blender-2.61/intern/cycles/kernel/kernel_compat_opencl.h blender-2.62/intern/cycles/kernel/kernel_compat_opencl.h --- blender-2.61/intern/cycles/kernel/kernel_compat_opencl.h 2011-12-13 19:39:43.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/kernel_compat_opencl.h 2012-02-15 19:24:04.000000000 +0000 @@ -25,12 +25,21 @@ /* no namespaces in opencl */ #define CCL_NAMESPACE_BEGIN #define CCL_NAMESPACE_END -#define WITH_OPENCL + +#ifdef __CL_NO_FLOAT3__ +#define float3 float4 +#endif + +#ifdef __CL_NOINLINE__ +#define __noinline __attribute__((noinline)) +#else +#define __noinline +#endif /* in opencl all functions are device functions, so leave this empty */ #define __device -#define __device_inline -#define __device_noinline +#define __device_inline __device +#define __device_noinline __device __noinline /* no assert in opencl */ #define kernel_assert(cond) @@ -68,7 +77,11 @@ #endif #define make_float2(x, y) ((float2)(x, y)) +#ifdef __CL_NO_FLOAT3__ +#define make_float3(x, y, z) ((float4)(x, y, z, 0.0)) +#else #define make_float3(x, y, z) ((float3)(x, y, z)) +#endif #define make_float4(x, y, z, w) ((float4)(x, y, z, w)) #define make_int2(x, y) ((int2)(x, y)) #define make_int3(x, y, z) ((int3)(x, y, z)) diff -Nru blender-2.61/intern/cycles/kernel/kernel.cpp blender-2.62/intern/cycles/kernel/kernel.cpp --- blender-2.61/intern/cycles/kernel/kernel.cpp 2011-12-13 19:39:43.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/kernel.cpp 2012-02-15 19:24:04.000000000 +0000 @@ -204,23 +204,23 @@ /* Path Tracing */ -void kernel_cpu_path_trace(KernelGlobals *kg, float4 *buffer, unsigned int *rng_state, int sample, int x, int y) +void kernel_cpu_path_trace(KernelGlobals *kg, float *buffer, unsigned int *rng_state, int sample, int x, int y, int offset, int stride) { - kernel_path_trace(kg, buffer, rng_state, sample, x, y); + kernel_path_trace(kg, buffer, rng_state, sample, x, y, offset, stride); } /* Tonemapping */ -void kernel_cpu_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer, int sample, int resolution, int x, int y) +void kernel_cpu_tonemap(KernelGlobals *kg, uchar4 *rgba, float *buffer, int sample, int resolution, int x, int y, int offset, int stride) { - kernel_film_tonemap(kg, rgba, buffer, sample, resolution, x, y); + kernel_film_tonemap(kg, rgba, buffer, sample, resolution, x, y, offset, stride); } -/* Displacement */ +/* Shader Evaluation */ -void kernel_cpu_displace(KernelGlobals *kg, uint4 *input, float3 *offset, int i) +void kernel_cpu_shader(KernelGlobals *kg, uint4 *input, float4 *output, int type, int i) { - kernel_displace(kg, input, offset, i); + kernel_shader_evaluate(kg, input, output, (ShaderEvalType)type, i); } CCL_NAMESPACE_END diff -Nru blender-2.61/intern/cycles/kernel/kernel.cu blender-2.62/intern/cycles/kernel/kernel.cu --- blender-2.61/intern/cycles/kernel/kernel.cu 2011-12-13 19:39:43.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/kernel.cu 2012-02-15 19:24:04.000000000 +0000 @@ -26,28 +26,28 @@ #include "kernel_path.h" #include "kernel_displace.h" -extern "C" __global__ void kernel_cuda_path_trace(float4 *buffer, uint *rng_state, int sample, int sx, int sy, int sw, int sh) +extern "C" __global__ void kernel_cuda_path_trace(float *buffer, uint *rng_state, int sample, int sx, int sy, int sw, int sh, int offset, int stride) { int x = sx + blockDim.x*blockIdx.x + threadIdx.x; int y = sy + blockDim.y*blockIdx.y + threadIdx.y; if(x < sx + sw && y < sy + sh) - kernel_path_trace(NULL, buffer, rng_state, sample, x, y); + kernel_path_trace(NULL, buffer, rng_state, sample, x, y, offset, stride); } -extern "C" __global__ void kernel_cuda_tonemap(uchar4 *rgba, float4 *buffer, int sample, int resolution, int sx, int sy, int sw, int sh) +extern "C" __global__ void kernel_cuda_tonemap(uchar4 *rgba, float *buffer, int sample, int resolution, int sx, int sy, int sw, int sh, int offset, int stride) { int x = sx + blockDim.x*blockIdx.x + threadIdx.x; int y = sy + blockDim.y*blockIdx.y + threadIdx.y; if(x < sx + sw && y < sy + sh) - kernel_film_tonemap(NULL, rgba, buffer, sample, resolution, x, y); + kernel_film_tonemap(NULL, rgba, buffer, sample, resolution, x, y, offset, stride); } -extern "C" __global__ void kernel_cuda_displace(uint4 *input, float3 *offset, int sx) +extern "C" __global__ void kernel_cuda_shader(uint4 *input, float4 *output, int type, int sx) { int x = sx + blockDim.x*blockIdx.x + threadIdx.x; - kernel_displace(NULL, input, offset, x); + kernel_shader_evaluate(NULL, input, output, (ShaderEvalType)type, x); } diff -Nru blender-2.61/intern/cycles/kernel/kernel_differential.h blender-2.62/intern/cycles/kernel/kernel_differential.h --- blender-2.61/intern/cycles/kernel/kernel_differential.h 2011-12-13 19:39:43.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/kernel_differential.h 2012-02-15 19:24:04.000000000 +0000 @@ -71,8 +71,8 @@ * and the same for dudy and dvdy. the denominator is the same for both * solutions, so we compute it only once. * - * dP.dx = dPdu * dudx + dPdv * dvdx; - * dP.dy = dPdu * dudy + dPdv * dvdy; */ + * dP.dx = dPdu * dudx + dPdv * dvdx; + * dP.dy = dPdu * dudy + dPdv * dvdy; */ float det = (dPdu.x*dPdv.y - dPdv.x*dPdu.y); diff -Nru blender-2.61/intern/cycles/kernel/kernel_displace.h blender-2.62/intern/cycles/kernel/kernel_displace.h --- blender-2.61/intern/cycles/kernel/kernel_displace.h 2011-12-13 19:39:43.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/kernel_displace.h 2012-02-15 19:24:04.000000000 +0000 @@ -18,17 +18,51 @@ CCL_NAMESPACE_BEGIN -__device void kernel_displace(KernelGlobals *kg, uint4 *input, float3 *offset, int i) +__device void kernel_shader_evaluate(KernelGlobals *kg, uint4 *input, float4 *output, ShaderEvalType type, int i) { - /* setup shader data */ ShaderData sd; uint4 in = input[i]; - shader_setup_from_displace(kg, &sd, in.x, in.y, __int_as_float(in.z), __int_as_float(in.w)); + float3 out; - /* evaluate */ - float3 P = sd.P; - shader_eval_displacement(kg, &sd); - offset[i] = sd.P - P; + if(type == SHADER_EVAL_DISPLACE) { + /* setup shader data */ + int object = in.x; + int prim = in.y; + float u = __int_as_float(in.z); + float v = __int_as_float(in.w); + + shader_setup_from_displace(kg, &sd, object, prim, u, v); + + /* evaluate */ + float3 P = sd.P; + shader_eval_displacement(kg, &sd); + out = sd.P - P; + } + else { // SHADER_EVAL_BACKGROUND + /* setup ray */ + Ray ray; + + ray.P = make_float3(0.0f, 0.0f, 0.0f); + ray.D = make_float3(__int_as_float(in.x), __int_as_float(in.y), __int_as_float(in.z)); + ray.t = 0.0f; + +#ifdef __RAY_DIFFERENTIALS__ + ray.dD.dx = make_float3(0.0f, 0.0f, 0.0f); + ray.dD.dy = make_float3(0.0f, 0.0f, 0.0f); + ray.dP.dx = make_float3(0.0f, 0.0f, 0.0f); + ray.dP.dy = make_float3(0.0f, 0.0f, 0.0f); +#endif + + /* setup shader data */ + shader_setup_from_background(kg, &sd, &ray); + + /* evaluate */ + int flag = 0; /* we can't know which type of BSDF this is for */ + out = shader_eval_background(kg, &sd, flag); + } + + /* write output */ + output[i] = make_float4(out.x, out.y, out.z, 0.0f); } CCL_NAMESPACE_END diff -Nru blender-2.61/intern/cycles/kernel/kernel_emission.h blender-2.62/intern/cycles/kernel/kernel_emission.h --- blender-2.61/intern/cycles/kernel/kernel_emission.h 2011-12-13 19:39:43.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/kernel_emission.h 2012-02-15 19:24:04.000000000 +0000 @@ -25,21 +25,34 @@ { /* setup shading at emitter */ ShaderData sd; - - shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, u, v); - ls->Ng = sd.Ng; - - /* no path flag, we're evaluating this for all closures. that's weak but - we'd have to do multiple evaluations otherwise */ - shader_eval_surface(kg, &sd, rando, 0); - float3 eval; - /* evaluate emissive closure */ - if(sd.flag & SD_EMISSION) - eval = shader_emissive_eval(kg, &sd); +#ifdef __BACKGROUND_MIS__ + if(ls->type == LIGHT_BACKGROUND) { + Ray ray; + ray.D = ls->D; + ray.P = ls->P; + ray.dP.dx = make_float3(0.0f, 0.0f, 0.0f); + ray.dP.dy = make_float3(0.0f, 0.0f, 0.0f); + shader_setup_from_background(kg, &sd, &ray); + eval = shader_eval_background(kg, &sd, 0); + } else - eval = make_float3(0.0f, 0.0f, 0.0f); +#endif + { + shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, u, v); + ls->Ng = sd.Ng; + + /* no path flag, we're evaluating this for all closures. that's weak but + we'd have to do multiple evaluations otherwise */ + shader_eval_surface(kg, &sd, rando, 0); + + /* evaluate emissive closure */ + if(sd.flag & SD_EMISSION) + eval = shader_emissive_eval(kg, &sd); + else + eval = make_float3(0.0f, 0.0f, 0.0f); + } shader_release(kg, &sd); @@ -47,56 +60,64 @@ } __device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex, - float randt, float rando, float randu, float randv, Ray *ray, float3 *eval) + float randt, float rando, float randu, float randv, Ray *ray, BsdfEval *eval) { LightSample ls; + float pdf = -1.0f; + #ifdef __MULTI_LIGHT__ if(lindex != -1) { /* sample position on a specified light */ - light_select(kg, lindex, randu, randv, sd->P, &ls); + light_select(kg, lindex, randu, randv, sd->P, &ls, &pdf); } else #endif { /* sample a light and position on int */ - light_sample(kg, randt, randu, randv, sd->P, &ls); + light_sample(kg, randt, randu, randv, sd->P, &ls, &pdf); } /* compute pdf */ - float pdf = light_sample_pdf(kg, &ls, -ls.D, ls.t); + if(pdf < 0.0f) + pdf = light_sample_pdf(kg, &ls, -ls.D, ls.t); + + if(pdf == 0.0f) + return false; /* evaluate closure */ - *eval = direct_emissive_eval(kg, rando, &ls, randu, randv, -ls.D); + float3 light_eval = direct_emissive_eval(kg, rando, &ls, randu, randv, -ls.D); - if(is_zero(*eval) || pdf == 0.0f) + if(is_zero(light_eval)) return false; /* todo: use visbility flag to skip lights */ /* evaluate BSDF at shading point */ float bsdf_pdf; - float3 bsdf_eval = shader_bsdf_eval(kg, sd, ls.D, &bsdf_pdf); - - *eval *= bsdf_eval/pdf; - if(is_zero(*eval)) - return false; + shader_bsdf_eval(kg, sd, ls.D, eval, &bsdf_pdf); - if(ls.prim != ~0) { + if(ls.prim != ~0 || ls.type == LIGHT_BACKGROUND) { /* multiple importance sampling */ float mis_weight = power_heuristic(pdf, bsdf_pdf); - *eval *= mis_weight; + light_eval *= mis_weight; } /* todo: clean up these weights */ else if(ls.shader & SHADER_AREA_LIGHT) - *eval *= 0.25f; /* area lamp */ + light_eval *= 0.25f; /* area lamp */ else if(ls.t != FLT_MAX) - *eval *= 0.25f*M_1_PI_F; /* point lamp */ + light_eval *= 0.25f*M_1_PI_F; /* point lamp */ + + bsdf_eval_mul(eval, light_eval/pdf); + + if(bsdf_eval_is_zero(eval)) + return false; if(ls.shader & SHADER_CAST_SHADOW) { /* setup ray */ - ray->P = ray_offset(sd->P, sd->Ng); + bool transmit = (dot(sd->Ng, ls.D) < 0.0f); + ray->P = ray_offset(sd->P, (transmit)? -sd->Ng: sd->Ng); if(ls.t == FLT_MAX) { /* distant light */ @@ -125,7 +146,8 @@ float3 L = shader_emissive_eval(kg, sd); if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_SAMPLE_AS_LIGHT)) { - /* multiple importance sampling */ + /* multiple importance sampling, get triangle light pdf, + and compute weight with respect to BSDF pdf */ float pdf = triangle_light_pdf(kg, sd->Ng, sd->I, t); float mis_weight = power_heuristic(bsdf_pdf, pdf); @@ -135,5 +157,36 @@ return L; } +/* Indirect Background */ + +__device float3 indirect_background(KernelGlobals *kg, Ray *ray, int path_flag, float bsdf_pdf) +{ +#ifdef __BACKGROUND__ + /* evaluate background closure */ + ShaderData sd; + shader_setup_from_background(kg, &sd, ray); + float3 L = shader_eval_background(kg, &sd, path_flag); + shader_release(kg, &sd); + +#ifdef __BACKGROUND_MIS__ + /* check if background light exists or if we should skip pdf */ + int res = kernel_data.integrator.pdf_background_res; + + if(!(path_flag & PATH_RAY_MIS_SKIP) && res) { + /* multiple importance sampling, get background light pdf for ray + direction, and compute weight with respect to BSDF pdf */ + float pdf = background_light_pdf(kg, ray->D); + float mis_weight = power_heuristic(bsdf_pdf, pdf); + + return L*mis_weight; + } +#endif + + return L; +#else + return make_float3(0.8f, 0.8f, 0.8f); +#endif +} + CCL_NAMESPACE_END diff -Nru blender-2.61/intern/cycles/kernel/kernel_film.h blender-2.62/intern/cycles/kernel/kernel_film.h --- blender-2.61/intern/cycles/kernel/kernel_film.h 2011-12-13 19:39:43.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/kernel_film.h 2012-02-15 19:24:04.000000000 +0000 @@ -48,16 +48,22 @@ return result; } -__device void kernel_film_tonemap(KernelGlobals *kg, __global uchar4 *rgba, __global float4 *buffer, int sample, int resolution, int x, int y) +__device void kernel_film_tonemap(KernelGlobals *kg, + __global uchar4 *rgba, __global float *buffer, + int sample, int resolution, int x, int y, int offset, int stride) { - int w = kernel_data.cam.width; - int index = x + y*w; - float4 irradiance = buffer[index]; + /* buffer offset */ + int index = offset + x + y*stride; + rgba += index; + buffer += index*kernel_data.film.pass_stride; + + /* map colors */ + float4 irradiance = *((__global float4*)buffer); float4 float_result = film_map(kg, irradiance, sample); uchar4 byte_result = film_float_to_byte(float_result); - rgba[index] = byte_result; + *rgba = byte_result; } CCL_NAMESPACE_END diff -Nru blender-2.61/intern/cycles/kernel/kernel.h blender-2.62/intern/cycles/kernel/kernel.h --- blender-2.61/intern/cycles/kernel/kernel.h 2011-12-13 19:39:43.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/kernel.h 2012-02-15 19:24:04.000000000 +0000 @@ -36,14 +36,20 @@ void kernel_const_copy(KernelGlobals *kg, const char *name, void *host, size_t size); void kernel_tex_copy(KernelGlobals *kg, const char *name, device_ptr mem, size_t width, size_t height); -void kernel_cpu_path_trace(KernelGlobals *kg, float4 *buffer, unsigned int *rng_state, int sample, int x, int y); -void kernel_cpu_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer, int sample, int resolution, int x, int y); -void kernel_cpu_displace(KernelGlobals *kg, uint4 *input, float3 *offset, int i); +void kernel_cpu_path_trace(KernelGlobals *kg, float *buffer, unsigned int *rng_state, + int sample, int x, int y, int offset, int stride); +void kernel_cpu_tonemap(KernelGlobals *kg, uchar4 *rgba, float *buffer, + int sample, int resolution, int x, int y, int offset, int stride); +void kernel_cpu_shader(KernelGlobals *kg, uint4 *input, float4 *output, + int type, int i); #ifdef WITH_OPTIMIZED_KERNEL -void kernel_cpu_optimized_path_trace(KernelGlobals *kg, float4 *buffer, unsigned int *rng_state, int sample, int x, int y); -void kernel_cpu_optimized_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer, int sample, int resolution, int x, int y); -void kernel_cpu_optimized_displace(KernelGlobals *kg, uint4 *input, float3 *offset, int i); +void kernel_cpu_optimized_path_trace(KernelGlobals *kg, float *buffer, unsigned int *rng_state, + int sample, int x, int y, int offset, int stride); +void kernel_cpu_optimized_tonemap(KernelGlobals *kg, uchar4 *rgba, float *buffer, + int sample, int resolution, int x, int y, int offset, int stride); +void kernel_cpu_optimized_shader(KernelGlobals *kg, uint4 *input, float4 *output, + int type, int i); #endif CCL_NAMESPACE_END diff -Nru blender-2.61/intern/cycles/kernel/kernel_light.h blender-2.62/intern/cycles/kernel/kernel_light.h --- blender-2.61/intern/cycles/kernel/kernel_light.h 2011-12-13 19:39:43.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/kernel_light.h 2012-02-15 19:24:04.000000000 +0000 @@ -26,6 +26,7 @@ int object; int prim; int shader; + LightType type; } LightSample; /* Regular Light */ @@ -58,13 +59,125 @@ return axisu*randu + axisv*randv; } +__device float3 background_light_sample(KernelGlobals *kg, float randu, float randv, float *pdf) +{ + /* for the following, the CDF values are actually a pair of floats, with the + function value as X and the actual CDF as Y. The last entry's function + value is the CDF total. */ + int res = kernel_data.integrator.pdf_background_res; + int cdf_count = res + 1; + + /* this is basically std::lower_bound as used by pbrt */ + int first = 0; + int count = res; + + while(count > 0) { + int step = count >> 1; + int middle = first + step; + + if(kernel_tex_fetch(__light_background_marginal_cdf, middle).y < randv) { + first = middle + 1; + count -= step + 1; + } + else + count = step; + } + + int index_v = max(0, first - 1); + kernel_assert(index_v >= 0 && index_v < res); + + float2 cdf_v = kernel_tex_fetch(__light_background_marginal_cdf, index_v); + float2 cdf_next_v = kernel_tex_fetch(__light_background_marginal_cdf, index_v + 1); + float2 cdf_last_v = kernel_tex_fetch(__light_background_marginal_cdf, res); + + /* importance-sampled V direction */ + float dv = (randv - cdf_v.y) / (cdf_next_v.y - cdf_v.y); + float v = (index_v + dv) / res; + + /* this is basically std::lower_bound as used by pbrt */ + first = 0; + count = res; + while(count > 0) { + int step = count >> 1; + int middle = first + step; + + if(kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_count + middle).y < randu) { + first = middle + 1; + count -= step + 1; + } + else + count = step; + } + + int index_u = max(0, first - 1); + kernel_assert(index_u >= 0 && index_u < res); + + float2 cdf_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_count + index_u); + float2 cdf_next_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_count + index_u + 1); + float2 cdf_last_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_count + res); + + /* importance-sampled U direction */ + float du = (randu - cdf_u.y) / (cdf_next_u.y - cdf_u.y); + float u = (index_u + du) / res; + + /* spherical coordinates */ + float theta = v * M_PI_F; + float phi = u * M_PI_F * 2.0f; + + /* compute pdf */ + float denom = cdf_last_u.x * cdf_last_v.x; + float sin_theta = sinf(theta); + + if(sin_theta == 0.0f || denom == 0.0f) + *pdf = 0.0f; + else + *pdf = (cdf_u.x * cdf_v.x)/(2.0f * M_PI_F * M_PI_F * sin_theta * denom); + + *pdf *= kernel_data.integrator.pdf_lights; + + /* compute direction */ + return spherical_to_direction(theta, phi); +} + +__device float background_light_pdf(KernelGlobals *kg, float3 direction) +{ + float2 uv = direction_to_equirectangular(direction); + int res = kernel_data.integrator.pdf_background_res; + + float sin_theta = sinf(uv.y * M_PI_F); + + if(sin_theta == 0.0f) + return 0.0f; + + int index_u = clamp((int)(uv.x * res), 0, res - 1); + int index_v = clamp((int)(uv.y * res), 0, res - 1); + + /* pdfs in V direction */ + float2 cdf_last_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * (res + 1) + res); + float2 cdf_last_v = kernel_tex_fetch(__light_background_marginal_cdf, res); + + float denom = cdf_last_u.x * cdf_last_v.x; + + if(denom == 0.0f) + return 0.0f; + + /* pdfs in U direction */ + float2 cdf_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * (res + 1) + index_u); + float2 cdf_v = kernel_tex_fetch(__light_background_marginal_cdf, index_v); + + float pdf = (cdf_u.x * cdf_v.x)/(2.0f * M_PI_F * M_PI_F * sin_theta * denom); + + return pdf * kernel_data.integrator.pdf_lights; +} + __device void regular_light_sample(KernelGlobals *kg, int point, - float randu, float randv, float3 P, LightSample *ls) + float randu, float randv, float3 P, LightSample *ls, float *pdf) { float4 data0 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 0); float4 data1 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 1); LightType type = (LightType)__float_as_int(data0.x); + ls->type = type; if(type == LIGHT_DISTANT) { /* distant light */ @@ -79,6 +192,17 @@ ls->D = -D; ls->t = FLT_MAX; } +#ifdef __BACKGROUND_MIS__ + else if(type == LIGHT_BACKGROUND) { + /* infinite area light (e.g. light dome or env light) */ + float3 D = background_light_sample(kg, randu, randv, pdf); + + ls->P = D; + ls->Ng = D; + ls->D = -D; + ls->t = FLT_MAX; + } +#endif else { ls->P = make_float3(data0.y, data0.z, data0.w); @@ -139,6 +263,7 @@ ls->object = object; ls->prim = prim; ls->t = 0.0f; + ls->type = LIGHT_AREA; #ifdef __INSTANCING__ /* instance transform */ @@ -192,7 +317,7 @@ /* Generic Light */ -__device void light_sample(KernelGlobals *kg, float randt, float randu, float randv, float3 P, LightSample *ls) +__device void light_sample(KernelGlobals *kg, float randt, float randu, float randv, float3 P, LightSample *ls, float *pdf) { /* sample index */ int index = light_distribution_sample(kg, randt); @@ -207,7 +332,7 @@ } else { int point = -prim-1; - regular_light_sample(kg, point, randu, randv, P, ls); + regular_light_sample(kg, point, randu, randv, P, ls, pdf); } /* compute incoming direction and distance */ @@ -227,9 +352,9 @@ return pdf; } -__device void light_select(KernelGlobals *kg, int index, float randu, float randv, float3 P, LightSample *ls) +__device void light_select(KernelGlobals *kg, int index, float randu, float randv, float3 P, LightSample *ls, float *pdf) { - regular_light_sample(kg, index, randu, randv, P, ls); + regular_light_sample(kg, index, randu, randv, P, ls, pdf); } __device float light_select_pdf(KernelGlobals *kg, LightSample *ls, float3 I, float t) diff -Nru blender-2.61/intern/cycles/kernel/kernel_montecarlo.h blender-2.62/intern/cycles/kernel/kernel_montecarlo.h --- blender-2.61/intern/cycles/kernel/kernel_montecarlo.h 2011-12-13 19:39:43.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/kernel_montecarlo.h 2012-02-15 19:24:04.000000000 +0000 @@ -104,13 +104,13 @@ __device float3 sample_uniform_sphere(float u1, float u2) { - float z = 1.0f - 2.0f*u1; - float r = sqrtf(fmaxf(0.0f, 1.0f - z*z)); - float phi = 2.0f*M_PI_F*u2; - float x = r*cosf(phi); - float y = r*sinf(phi); + float z = 1.0f - 2.0f*u1; + float r = sqrtf(fmaxf(0.0f, 1.0f - z*z)); + float phi = 2.0f*M_PI_F*u2; + float x = r*cosf(phi); + float y = r*sinf(phi); - return make_float3(x, y, z); + return make_float3(x, y, z); } __device float power_heuristic(float a, float b) @@ -203,6 +203,28 @@ cosf(theta)); } +/* Equirectangular */ + +__device float2 direction_to_equirectangular(float3 dir) +{ + float u = (atan2f(dir.y, dir.x) + M_PI_F)/(2.0f*M_PI_F); + float v = atan2f(dir.z, hypotf(dir.x, dir.y))/M_PI_F + 0.5f; + + return make_float2(u, v); +} + +__device float3 equirectangular_to_direction(float u, float v) +{ + /* XXX check correctness? */ + float theta = M_PI_F*v; + float phi = 2.0f*M_PI_F*u; + + return make_float3( + sin(theta)*cos(phi), + sin(theta)*sin(phi), + cos(theta)); +} + CCL_NAMESPACE_END #endif /* __KERNEL_MONTECARLO_CL__ */ diff -Nru blender-2.61/intern/cycles/kernel/kernel_object.h blender-2.62/intern/cycles/kernel/kernel_object.h --- blender-2.61/intern/cycles/kernel/kernel_object.h 2011-12-13 19:39:43.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/kernel_object.h 2012-02-15 19:24:04.000000000 +0000 @@ -64,5 +64,15 @@ return f.x; } +__device_inline float object_pass_id(KernelGlobals *kg, int object) +{ + if(object == ~0) + return 0.0f; + + int offset = object*OBJECT_SIZE + OBJECT_PROPERTIES; + float4 f = kernel_tex_fetch(__objects, offset); + return f.y; +} + CCL_NAMESPACE_END diff -Nru blender-2.61/intern/cycles/kernel/kernel_optimized.cpp blender-2.62/intern/cycles/kernel/kernel_optimized.cpp --- blender-2.61/intern/cycles/kernel/kernel_optimized.cpp 2011-12-13 19:39:43.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/kernel_optimized.cpp 2012-02-15 19:24:04.000000000 +0000 @@ -35,23 +35,23 @@ /* Path Tracing */ -void kernel_cpu_optimized_path_trace(KernelGlobals *kg, float4 *buffer, unsigned int *rng_state, int sample, int x, int y) +void kernel_cpu_optimized_path_trace(KernelGlobals *kg, float *buffer, unsigned int *rng_state, int sample, int x, int y, int offset, int stride) { - kernel_path_trace(kg, buffer, rng_state, sample, x, y); + kernel_path_trace(kg, buffer, rng_state, sample, x, y, offset, stride); } /* Tonemapping */ -void kernel_cpu_optimized_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer, int sample, int resolution, int x, int y) +void kernel_cpu_optimized_tonemap(KernelGlobals *kg, uchar4 *rgba, float *buffer, int sample, int resolution, int x, int y, int offset, int stride) { - kernel_film_tonemap(kg, rgba, buffer, sample, resolution, x, y); + kernel_film_tonemap(kg, rgba, buffer, sample, resolution, x, y, offset, stride); } -/* Displacement */ +/* Shader Evaluate */ -void kernel_cpu_optimized_displace(KernelGlobals *kg, uint4 *input, float3 *offset, int i) +void kernel_cpu_optimized_shader(KernelGlobals *kg, uint4 *input, float4 *output, int type, int i) { - kernel_displace(kg, input, offset, i); + kernel_shader_evaluate(kg, input, output, (ShaderEvalType)type, i); } CCL_NAMESPACE_END diff -Nru blender-2.61/intern/cycles/kernel/kernel_passes.h blender-2.62/intern/cycles/kernel/kernel_passes.h --- blender-2.61/intern/cycles/kernel/kernel_passes.h 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/kernel_passes.h 2012-02-15 19:24:04.000000000 +0000 @@ -0,0 +1,137 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + */ + +CCL_NAMESPACE_BEGIN + +__device_inline void kernel_write_pass_float(__global float *buffer, int sample, float value) +{ + __global float *buf = buffer; + *buf = (sample == 0)? value: *buf + value; +} + +__device_inline void kernel_write_pass_float3(__global float *buffer, int sample, float3 value) +{ + __global float3 *buf = (__global float3*)buffer; + *buf = (sample == 0)? value: *buf + value; +} + +__device_inline void kernel_write_pass_float4(__global float *buffer, int sample, float4 value) +{ + __global float4 *buf = (__global float4*)buffer; + *buf = (sample == 0)? value: *buf + value; +} + +__device_inline void kernel_write_data_passes(KernelGlobals *kg, __global float *buffer, PathRadiance *L, + ShaderData *sd, int sample, int path_flag, float3 throughput) +{ +#ifdef __PASSES__ + if(!(path_flag & PATH_RAY_CAMERA)) + return; + + int flag = kernel_data.film.pass_flag; + + if(!(flag & PASS_ALL)) + return; + + /* todo: add alpha treshold */ + if(!(path_flag & PATH_RAY_TRANSPARENT)) { + if(sample == 0) { + if(flag & PASS_DEPTH) { + Transform tfm = kernel_data.cam.worldtocamera; + float depth = len(transform(&tfm, sd->P)); + + kernel_write_pass_float(buffer + kernel_data.film.pass_depth, sample, depth); + } + if(flag & PASS_OBJECT_ID) { + float id = object_pass_id(kg, sd->object); + kernel_write_pass_float(buffer + kernel_data.film.pass_object_id, sample, id); + } + if(flag & PASS_MATERIAL_ID) { + float id = shader_pass_id(kg, sd); + kernel_write_pass_float(buffer + kernel_data.film.pass_material_id, sample, id); + } + } + + if(flag & PASS_NORMAL) { + float3 normal = sd->N; + kernel_write_pass_float3(buffer + kernel_data.film.pass_normal, sample, normal); + } + if(flag & PASS_UV) { + float3 uv = make_float3(0.0f, 0.0f, 0.0f); /* todo: request and lookup */ + kernel_write_pass_float3(buffer + kernel_data.film.pass_uv, sample, uv); + } + } + + if(flag & (PASS_DIFFUSE_INDIRECT|PASS_DIFFUSE_COLOR|PASS_DIFFUSE_DIRECT)) + L->color_diffuse += shader_bsdf_diffuse(kg, sd)*throughput; + if(flag & (PASS_GLOSSY_INDIRECT|PASS_GLOSSY_COLOR|PASS_GLOSSY_DIRECT)) + L->color_glossy += shader_bsdf_glossy(kg, sd)*throughput; + if(flag & (PASS_TRANSMISSION_INDIRECT|PASS_TRANSMISSION_COLOR|PASS_TRANSMISSION_DIRECT)) + L->color_transmission += shader_bsdf_transmission(kg, sd)*throughput; +#endif +} + +__device_inline void kernel_write_light_passes(KernelGlobals *kg, __global float *buffer, PathRadiance *L, int sample) +{ +#ifdef __PASSES__ + int flag = kernel_data.film.pass_flag; + + if(!kernel_data.film.use_light_pass) + return; + + if(flag & PASS_DIFFUSE_INDIRECT) { + float3 color = safe_divide_color(L->indirect_diffuse, L->color_diffuse); + kernel_write_pass_float3(buffer + kernel_data.film.pass_diffuse_indirect, sample, color); + } + if(flag & PASS_GLOSSY_INDIRECT) { + float3 color = safe_divide_color(L->indirect_glossy, L->color_glossy); + kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_indirect, sample, color); + } + if(flag & PASS_TRANSMISSION_INDIRECT) { + float3 color = safe_divide_color(L->indirect_transmission, L->color_transmission); + kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_indirect, sample, color); + } + if(flag & PASS_DIFFUSE_DIRECT) { + float3 color = safe_divide_color(L->direct_diffuse, L->color_diffuse); + kernel_write_pass_float3(buffer + kernel_data.film.pass_diffuse_direct, sample, color); + } + if(flag & PASS_GLOSSY_DIRECT) { + float3 color = safe_divide_color(L->direct_glossy, L->color_glossy); + kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_direct, sample, color); + } + if(flag & PASS_TRANSMISSION_DIRECT) { + float3 color = safe_divide_color(L->direct_transmission, L->color_transmission); + kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_direct, sample, color); + } + + if(flag & PASS_EMISSION) + kernel_write_pass_float3(buffer + kernel_data.film.pass_emission, sample, L->emission); + if(flag & PASS_BACKGROUND) + kernel_write_pass_float3(buffer + kernel_data.film.pass_background, sample, L->background); + + if(flag & PASS_DIFFUSE_COLOR) + kernel_write_pass_float3(buffer + kernel_data.film.pass_diffuse_color, sample, L->color_diffuse); + if(flag & PASS_GLOSSY_COLOR) + kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_color, sample, L->color_glossy); + if(flag & PASS_TRANSMISSION_COLOR) + kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_color, sample, L->color_transmission); +#endif +} + +CCL_NAMESPACE_END + diff -Nru blender-2.61/intern/cycles/kernel/kernel_path.h blender-2.62/intern/cycles/kernel/kernel_path.h --- blender-2.61/intern/cycles/kernel/kernel_path.h 2011-12-13 19:39:43.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/kernel_path.h 2012-02-15 19:24:04.000000000 +0000 @@ -25,39 +25,16 @@ #else #include "kernel_bvh.h" #endif +#include "kernel_accumulate.h" #include "kernel_camera.h" #include "kernel_shader.h" #include "kernel_light.h" #include "kernel_emission.h" #include "kernel_random.h" +#include "kernel_passes.h" CCL_NAMESPACE_BEGIN -#ifdef __MODIFY_TP__ -__device float3 path_terminate_modified_throughput(KernelGlobals *kg, __global float3 *buffer, int x, int y, int sample) -{ - /* modify throughput to influence path termination probability, to avoid - darker regions receiving fewer samples than lighter regions. also RGB - are weighted differently. proper validation still remains to be done. */ - const float3 weights = make_float3(1.0f, 1.33f, 0.66f); - const float3 one = make_float3(1.0f, 1.0f, 1.0f); - const int minsample = 5; - const float minL = 0.1f; - - if(sample >= minsample) { - float3 L = buffer[x + y*kernel_data.cam.width]; - float3 Lmin = make_float3(minL, minL, minL); - float correct = (float)(sample+1)/(float)sample; - - L = film_map(L*correct, sample); - - return weights/clamp(L, Lmin, one); - } - - return weights; -} -#endif - typedef struct PathState { uint flag; int bounce; @@ -130,13 +107,16 @@ } } -__device_inline uint path_state_ray_visibility(PathState *state) +__device_inline uint path_state_ray_visibility(KernelGlobals *kg, PathState *state) { uint flag = state->flag; /* for visibility, diffuse/glossy are for reflection only */ if(flag & PATH_RAY_TRANSMIT) flag &= ~(PATH_RAY_DIFFUSE|PATH_RAY_GLOSSY); + /* for camera visibility, use render layer flags */ + if(flag & PATH_RAY_CAMERA) + flag |= kernel_data.integrator.layer_flag; return flag; } @@ -165,7 +145,7 @@ return average(throughput); } -__device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *ray, Intersection *isect, float3 *light_L) +__device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *ray, Intersection *isect, BsdfEval *L_light) { if(ray->t == 0.0f) return false; @@ -205,7 +185,7 @@ } if(!scene_intersect(kg, ray, PATH_RAY_SHADOW_TRANSPARENT, isect)) { - *light_L *= throughput; + bsdf_eval_mul(L_light, throughput); return false; } @@ -231,15 +211,16 @@ return result; } -__device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, Ray ray, float3 throughput) +__device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, Ray ray, __global float *buffer) { /* initialize */ - float3 L = make_float3(0.0f, 0.0f, 0.0f); - float Ltransparent = 0.0f; + PathRadiance L; + float3 throughput = make_float3(1.0f, 1.0f, 1.0f); + float L_transparent = 0.0f; + + path_radiance_init(&L, kernel_data.film.use_light_pass); -#ifdef __EMISSION__ float ray_pdf = 0.0f; -#endif PathState state; int rng_offset = PRNG_BASE_NUM; @@ -249,23 +230,20 @@ for(;; rng_offset += PRNG_BOUNCE_NUM) { /* intersect scene */ Intersection isect; - uint visibility = path_state_ray_visibility(&state); + uint visibility = path_state_ray_visibility(kg, &state); if(!scene_intersect(kg, &ray, visibility, &isect)) { /* eval background shader if nothing hit */ if(kernel_data.background.transparent && (state.flag & PATH_RAY_CAMERA)) { - Ltransparent += average(throughput); + L_transparent += average(throughput); } - else { #ifdef __BACKGROUND__ - ShaderData sd; - shader_setup_from_background(kg, &sd, &ray); - L += throughput*shader_eval_background(kg, &sd, state.flag); - shader_release(kg, &sd); -#else - L += throughput*make_float3(0.8f, 0.8f, 0.8f); -#endif + else { + /* sample background shader */ + float3 L_background = indirect_background(kg, &ray, state.flag, ray_pdf); + path_radiance_accum_background(&L, throughput, L_background, state.bounce); } +#endif break; } @@ -276,19 +254,24 @@ float rbsdf = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF); shader_eval_surface(kg, &sd, rbsdf, state.flag); + kernel_write_data_passes(kg, buffer, &L, &sd, sample, state.flag, throughput); + #ifdef __HOLDOUT__ if((sd.flag & SD_HOLDOUT) && (state.flag & PATH_RAY_CAMERA)) { float3 holdout_weight = shader_holdout_eval(kg, &sd); if(kernel_data.background.transparent) - Ltransparent += average(holdout_weight*throughput); + /* any throughput is ok, should all be identical here */ + L_transparent += average(holdout_weight*throughput); } #endif #ifdef __EMISSION__ /* emission */ - if(sd.flag & SD_EMISSION) - L += throughput*indirect_emission(kg, &sd, isect.t, state.flag, ray_pdf); + if(sd.flag & SD_EMISSION) { + float3 emission = indirect_emission(kg, &sd, isect.t, state.flag, ray_pdf); + path_radiance_accum_emission(&L, throughput, emission, state.bounce); + } #endif /* path termination. this is a strange place to put the termination, it's @@ -312,7 +295,7 @@ float light_v = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT_V); Ray light_ray; - float3 light_L; + BsdfEval L_light; #ifdef __MULTI_LIGHT__ /* index -1 means randomly sample from distribution */ @@ -322,10 +305,10 @@ #else const int i = -1; #endif - if(direct_emission(kg, &sd, i, light_t, light_o, light_u, light_v, &light_ray, &light_L)) { + if(direct_emission(kg, &sd, i, light_t, light_o, light_u, light_v, &light_ray, &L_light)) { /* trace shadow ray */ - if(!shadow_blocked(kg, &state, &light_ray, &isect, &light_L)) - L += throughput*light_L; + if(!shadow_blocked(kg, &state, &light_ray, &isect, &L_light)) + path_radiance_accum_light(&L, throughput, &L_light, state.bounce); } #ifdef __MULTI_LIGHT__ } @@ -340,7 +323,7 @@ /* sample BSDF */ float bsdf_pdf; - float3 bsdf_eval; + BsdfEval bsdf_eval; float3 bsdf_omega_in; differential3 bsdf_domega_in; float bsdf_u = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_U); @@ -352,16 +335,15 @@ shader_release(kg, &sd); - if(bsdf_pdf == 0.0f || is_zero(bsdf_eval)) + if(bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval)) break; /* modify throughput */ - throughput *= bsdf_eval/bsdf_pdf; + path_radiance_bsdf_bounce(&L, &throughput, &bsdf_eval, bsdf_pdf, state.bounce, label); /* set labels */ -#ifdef __EMISSION__ - ray_pdf = bsdf_pdf; -#endif + if(!(label & LABEL_TRANSPARENT)) + ray_pdf = bsdf_pdf; /* update path state */ path_state_next(kg, &state, label); @@ -376,11 +358,24 @@ #endif } - return make_float4(L.x, L.y, L.z, 1.0f - Ltransparent); + float3 L_sum = path_radiance_sum(&L); + + kernel_write_light_passes(kg, buffer, &L, sample); + + return make_float4(L_sum.x, L_sum.y, L_sum.z, 1.0f - L_transparent); } -__device void kernel_path_trace(KernelGlobals *kg, __global float4 *buffer, __global uint *rng_state, int sample, int x, int y) +__device void kernel_path_trace(KernelGlobals *kg, + __global float *buffer, __global uint *rng_state, + int sample, int x, int y, int offset, int stride) { + /* buffer offset */ + int index = offset + x + y*stride; + int pass_stride = kernel_data.film.pass_stride; + + rng_state += index; + buffer += index*pass_stride; + /* initialize random numbers */ RNG rng; @@ -398,23 +393,12 @@ camera_sample(kg, x, y, filter_u, filter_v, lens_u, lens_v, &ray); /* integrate */ -#ifdef __MODIFY_TP__ - float3 throughput = path_terminate_modified_throughput(kg, buffer, x, y, sample); - float4 L = kernel_path_integrate(kg, &rng, sample, ray, throughput)/throughput; -#else - float3 throughput = make_float3(1.0f, 1.0f, 1.0f); - float4 L = kernel_path_integrate(kg, &rng, sample, ray, throughput); -#endif + float4 L = kernel_path_integrate(kg, &rng, sample, ray, buffer); /* accumulate result in output buffer */ - int index = x + y*kernel_data.cam.width; - - if(sample == 0) - buffer[index] = L; - else - buffer[index] += L; + kernel_write_pass_float4(buffer, sample, L); - path_rng_end(kg, rng_state, rng, x, y); + path_rng_end(kg, rng_state, rng); } CCL_NAMESPACE_END diff -Nru blender-2.61/intern/cycles/kernel/kernel_random.h blender-2.62/intern/cycles/kernel/kernel_random.h --- blender-2.61/intern/cycles/kernel/kernel_random.h 2011-12-13 19:39:43.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/kernel_random.h 2012-02-15 19:24:04.000000000 +0000 @@ -135,19 +135,31 @@ *rng ^= kernel_data.integrator.seed; - *fx = size * (float)px * (1.0f/(float)0xFFFFFFFF) - x; - *fy = size * (float)py * (1.0f/(float)0xFFFFFFFF) - y; + if(sample == 0) { + *fx = 0.5f; + *fy = 0.5f; + } + else { + *fx = size * (float)px * (1.0f/(float)0xFFFFFFFF) - x; + *fy = size * (float)py * (1.0f/(float)0xFFFFFFFF) - y; + } #else - *rng = rng_state[x + y*kernel_data.cam.width]; + *rng = *rng_state; *rng ^= kernel_data.integrator.seed; - *fx = path_rng(kg, rng, sample, PRNG_FILTER_U); - *fy = path_rng(kg, rng, sample, PRNG_FILTER_V); + if(sample == 0) { + *fx = 0.5f; + *fy = 0.5f; + } + else { + *fx = path_rng(kg, rng, sample, PRNG_FILTER_U); + *fy = path_rng(kg, rng, sample, PRNG_FILTER_V); + } #endif } -__device void path_rng_end(KernelGlobals *kg, __global uint *rng_state, RNG rng, int x, int y) +__device void path_rng_end(KernelGlobals *kg, __global uint *rng_state, RNG rng) { /* nothing to do */ } @@ -166,18 +178,24 @@ __device void path_rng_init(KernelGlobals *kg, __global uint *rng_state, int sample, RNG *rng, int x, int y, float *fx, float *fy) { /* load state */ - *rng = rng_state[x + y*kernel_data.cam.width]; + *rng = *rng_state; *rng ^= kernel_data.integrator.seed; - *fx = path_rng(kg, rng, sample, PRNG_FILTER_U); - *fy = path_rng(kg, rng, sample, PRNG_FILTER_V); + if(sample == 0) { + *fx = 0.5f; + *fy = 0.5f; + } + else { + *fx = path_rng(kg, rng, sample, PRNG_FILTER_U); + *fy = path_rng(kg, rng, sample, PRNG_FILTER_V); + } } -__device void path_rng_end(KernelGlobals *kg, __global uint *rng_state, RNG rng, int x, int y) +__device void path_rng_end(KernelGlobals *kg, __global uint *rng_state, RNG rng) { /* store state for next sample */ - rng_state[x + y*kernel_data.cam.width] = rng; + *rng_state = rng; } #endif diff -Nru blender-2.61/intern/cycles/kernel/kernel_shader.h blender-2.62/intern/cycles/kernel/kernel_shader.h --- blender-2.61/intern/cycles/kernel/kernel_shader.h 2011-12-13 19:39:43.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/kernel_shader.h 2012-02-15 19:24:04.000000000 +0000 @@ -26,7 +26,6 @@ * */ - #ifdef __OSL__ #include "osl_shader.h" @@ -75,7 +74,7 @@ if(sd->shader & SHADER_SMOOTH_NORMAL) sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v); - sd->flag = kernel_tex_fetch(__shader_flag, sd->shader & SHADER_MASK); + sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2); #ifdef __DPDU__ /* dPdu/dPdv */ @@ -151,7 +150,7 @@ instanced = true; else #endif - sd->object = -sd->object-1; + sd->object = ~sd->object; #ifdef __INSTANCING__ } #endif @@ -166,7 +165,7 @@ #endif } - sd->flag = kernel_tex_fetch(__shader_flag, sd->shader & SHADER_MASK); + sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2); #ifdef __DPDU__ /* dPdu/dPdv */ @@ -243,7 +242,7 @@ sd->Ng = -sd->P; sd->I = -sd->P; sd->shader = kernel_data.background.shader; - sd->flag = kernel_tex_fetch(__shader_flag, sd->shader & SHADER_MASK); + sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2); #ifdef __INSTANCING__ sd->object = ~0; @@ -275,8 +274,8 @@ #ifdef __MULTI_CLOSURE__ -__device_inline float3 _shader_bsdf_multi_eval(const ShaderData *sd, const float3 omega_in, float *pdf, - int skip_bsdf, float3 sum_eval, float sum_pdf, float sum_sample_weight) +__device_inline void _shader_bsdf_multi_eval(const ShaderData *sd, const float3 omega_in, float *pdf, + int skip_bsdf, BsdfEval *bsdf_eval, float sum_pdf, float sum_sample_weight) { for(int i = 0; i< sd->num_closure; i++) { if(i == skip_bsdf) @@ -293,7 +292,7 @@ #endif if(bsdf_pdf != 0.0f) { - sum_eval += eval*sc->weight; + bsdf_eval_accum(bsdf_eval, sc->type, eval*sc->weight); sum_pdf += bsdf_pdf*sc->sample_weight; } @@ -301,26 +300,28 @@ } } - *pdf = sum_pdf/sum_sample_weight; - return sum_eval; + *pdf = (sum_sample_weight > 0.0f)? sum_pdf/sum_sample_weight: 0.0f; } #endif -__device float3 shader_bsdf_eval(KernelGlobals *kg, const ShaderData *sd, - const float3 omega_in, float *pdf) +__device void shader_bsdf_eval(KernelGlobals *kg, const ShaderData *sd, + const float3 omega_in, BsdfEval *eval, float *pdf) { #ifdef __MULTI_CLOSURE__ - return _shader_bsdf_multi_eval(sd, omega_in, pdf, -1, make_float3(0.0f, 0.0f, 0.0f), 0.0f, 0.0f); + bsdf_eval_init(eval, NBUILTIN_CLOSURES, make_float3(0.0f, 0.0f, 0.0f), kernel_data.film.use_light_pass); + + return _shader_bsdf_multi_eval(sd, omega_in, pdf, -1, eval, 0.0f, 0.0f); #else const ShaderClosure *sc = &sd->closure; + *pdf = 0.0f; - return svm_bsdf_eval(sd, sc, omega_in, pdf)*sc->weight; + *eval = svm_bsdf_eval(sd, sc, omega_in, pdf)*sc->weight; #endif } __device int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd, - float randu, float randv, float3 *eval, + float randu, float randv, BsdfEval *bsdf_eval, float3 *omega_in, differential3 *domega_in, float *pdf) { #ifdef __MULTI_CLOSURE__ @@ -359,27 +360,29 @@ const ShaderClosure *sc = &sd->closure[sampled]; int label; + float3 eval; *pdf = 0.0f; #ifdef __OSL__ - label = OSLShader::bsdf_sample(sd, sc, randu, randv, *eval, *omega_in, *domega_in, *pdf); + label = OSLShader::bsdf_sample(sd, sc, randu, randv, eval, *omega_in, *domega_in, *pdf); #else - label = svm_bsdf_sample(sd, sc, randu, randv, eval, omega_in, domega_in, pdf); + label = svm_bsdf_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf); #endif + if(*pdf != 0.0f) { + bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass); - *eval *= sc->weight; - - if(sd->num_closure > 1 && *pdf != 0.0f) { - float sweight = sc->sample_weight; - *eval = _shader_bsdf_multi_eval(sd, *omega_in, pdf, sampled, *eval, *pdf*sweight, sweight); + if(sd->num_closure > 1) { + float sweight = sc->sample_weight; + _shader_bsdf_multi_eval(sd, *omega_in, pdf, sampled, bsdf_eval, *pdf*sweight, sweight); + } } return label; #else /* sample the single closure that we picked */ *pdf = 0.0f; - int label = svm_bsdf_sample(sd, &sd->closure, randu, randv, eval, omega_in, domega_in, pdf); - *eval *= sd->closure.weight; + int label = svm_bsdf_sample(sd, &sd->closure, randu, randv, bsdf_eval, omega_in, domega_in, pdf); + *bsdf_eval *= sd->closure.weight; return label; #endif } @@ -421,6 +424,68 @@ #endif } +__device float3 shader_bsdf_diffuse(KernelGlobals *kg, ShaderData *sd) +{ +#ifdef __MULTI_CLOSURE__ + float3 eval = make_float3(0.0f, 0.0f, 0.0f); + + for(int i = 0; i< sd->num_closure; i++) { + ShaderClosure *sc = &sd->closure[i]; + + if(CLOSURE_IS_BSDF_DIFFUSE(sc->type)) + eval += sc->weight; + } + + return eval; +#else + if(CLOSURE_IS_BSDF_DIFFUSE(sd->closure.type)) + return sd->closure.weight; + else + return make_float3(0.0f, 0.0f, 0.0f); +#endif +} + +__device float3 shader_bsdf_glossy(KernelGlobals *kg, ShaderData *sd) +{ +#ifdef __MULTI_CLOSURE__ + float3 eval = make_float3(0.0f, 0.0f, 0.0f); + + for(int i = 0; i< sd->num_closure; i++) { + ShaderClosure *sc = &sd->closure[i]; + + if(CLOSURE_IS_BSDF_GLOSSY(sc->type)) + eval += sc->weight; + } + + return eval; +#else + if(CLOSURE_IS_BSDF_GLOSSY(sd->closure.type)) + return sd->closure.weight; + else + return make_float3(0.0f, 0.0f, 0.0f); +#endif +} + +__device float3 shader_bsdf_transmission(KernelGlobals *kg, ShaderData *sd) +{ +#ifdef __MULTI_CLOSURE__ + float3 eval = make_float3(0.0f, 0.0f, 0.0f); + + for(int i = 0; i< sd->num_closure; i++) { + ShaderClosure *sc = &sd->closure[i]; + + if(CLOSURE_IS_BSDF_TRANSMISSION(sc->type)) + eval += sc->weight; + } + + return eval; +#else + if(CLOSURE_IS_BSDF_TRANSMISSION(sd->closure.type)) + return sd->closure.weight; + else + return make_float3(0.0f, 0.0f, 0.0f); +#endif +} /* Emission */ @@ -588,12 +653,17 @@ int prim = kernel_tex_fetch(__prim_index, isect->prim); float4 Ns = kernel_tex_fetch(__tri_normal, prim); int shader = __float_as_int(Ns.w); - int flag = kernel_tex_fetch(__shader_flag, shader & SHADER_MASK); + int flag = kernel_tex_fetch(__shader_flag, (shader & SHADER_MASK)*2); return (flag & SD_HAS_SURFACE_TRANSPARENT) != 0; } #endif +__device int shader_pass_id(KernelGlobals *kg, ShaderData *sd) +{ + return kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2 + 1); +} + /* Free ShaderData */ __device void shader_release(KernelGlobals *kg, ShaderData *sd) diff -Nru blender-2.61/intern/cycles/kernel/kernel_textures.h blender-2.62/intern/cycles/kernel/kernel_textures.h --- blender-2.61/intern/cycles/kernel/kernel_textures.h 2011-12-13 19:39:43.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/kernel_textures.h 2012-02-15 19:24:04.000000000 +0000 @@ -33,6 +33,8 @@ /* lights */ KERNEL_TEX(float4, texture_float4, __light_distribution) KERNEL_TEX(float4, texture_float4, __light_data) +KERNEL_TEX(float2, texture_float2, __light_background_marginal_cdf) +KERNEL_TEX(float2, texture_float2, __light_background_conditional_cdf) /* shaders */ KERNEL_TEX(uint4, texture_uint4, __svm_nodes) diff -Nru blender-2.61/intern/cycles/kernel/kernel_types.h blender-2.62/intern/cycles/kernel/kernel_types.h --- blender-2.61/intern/cycles/kernel/kernel_types.h 2011-12-13 19:39:43.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/kernel_types.h 2012-02-15 19:24:04.000000000 +0000 @@ -70,6 +70,8 @@ #ifdef __KERNEL_ADV_SHADING__ #define __MULTI_CLOSURE__ #define __TRANSPARENT_SHADOWS__ +#define __PASSES__ +#define __BACKGROUND_MIS__ #endif //#define __MULTI_LIGHT__ @@ -78,6 +80,13 @@ //#define __MODIFY_TP__ //#define __QBVH__ +/* Shader Evaluation */ + +enum ShaderEvalType { + SHADER_EVAL_DISPLACE, + SHADER_EVAL_BACKGROUND +}; + /* Path Tracing */ enum PathTraceDimension { @@ -100,7 +109,10 @@ /* these flag values correspond exactly to OSL defaults, so be careful not to * change this, or if you do, set the "raytypes" shading system attribute with - * your own new ray types and bitflag values */ + * your own new ray types and bitflag values. + * + * for ray visibility tests in BVH traversal, the upper 20 bits are used for + * layer visibility tests. */ enum PathRayFlag { PATH_RAY_CAMERA = 1, @@ -117,7 +129,9 @@ PATH_RAY_MIS_SKIP = 512, - PATH_RAY_ALL = (1|2|4|8|16|32|64|128|256|512) + PATH_RAY_ALL = (1|2|4|8|16|32|64|128|256|512), + + PATH_RAY_LAYER_SHIFT = (32-20) }; /* Closure Label */ @@ -138,6 +152,75 @@ LABEL_STOP = 2048 } ClosureLabel; +/* Render Passes */ + +typedef enum PassType { + PASS_NONE = 0, + PASS_COMBINED = 1, + PASS_DEPTH = 2, + PASS_NORMAL = 8, + PASS_UV = 16, + PASS_OBJECT_ID = 32, + PASS_MATERIAL_ID = 64, + PASS_DIFFUSE_COLOR = 128, + PASS_GLOSSY_COLOR = 256, + PASS_TRANSMISSION_COLOR = 512, + PASS_DIFFUSE_INDIRECT = 1024, + PASS_GLOSSY_INDIRECT = 2048, + PASS_TRANSMISSION_INDIRECT = 4096, + PASS_DIFFUSE_DIRECT = 8192, + PASS_GLOSSY_DIRECT = 16384, + PASS_TRANSMISSION_DIRECT = 32768, + PASS_EMISSION = 65536, + PASS_BACKGROUND = 131072 +} PassType; + +#define PASS_ALL (~0) + +#ifdef __PASSES__ + +typedef float3 PathThroughput; + +struct PathRadiance { + int use_light_pass; + + float3 emission; + float3 background; + + float3 indirect; + float3 direct_throughput; + float3 direct_emission; + + float3 color_diffuse; + float3 color_glossy; + float3 color_transmission; + + float3 direct_diffuse; + float3 direct_glossy; + float3 direct_transmission; + + float3 indirect_diffuse; + float3 indirect_glossy; + float3 indirect_transmission; +}; + +struct BsdfEval { + int use_light_pass; + + float3 diffuse; + float3 glossy; + float3 transmission; + float3 transparent; +}; + +#else + +typedef float3 PathThroughput; +typedef float3 PathRadiance; +typedef float3 BsdfEval; + +#endif + /* Shader Flag */ typedef enum ShaderFlag { @@ -153,6 +236,7 @@ typedef enum LightType { LIGHT_POINT, LIGHT_DISTANT, + LIGHT_BACKGROUND, LIGHT_AREA } LightType; @@ -295,29 +379,24 @@ #endif } ShaderData; -/* Constrant Kernel Data */ +/* Constrant Kernel Data + * + * These structs are passed from CPU to various devices, and the struct layout + * must match exactly. Structs are padded to ensure 16 byte alignment, and we + * do not use float3 because its size may not be the same on all devices. */ typedef struct KernelCamera { /* type */ int ortho; - int pad; - - /* size */ - int width, height; + int pad1, pad2, pad3; /* matrices */ Transform cameratoworld; Transform rastertocamera; /* differentials */ - float3 dx; -#ifndef WITH_OPENCL - float pad1; -#endif - float3 dy; -#ifndef WITH_OPENCL - float pad2; -#endif + float4 dx; + float4 dy; /* depth of field */ float aperturesize; @@ -345,7 +424,34 @@ typedef struct KernelFilm { float exposure; - int pad1, pad2, pad3; + int pass_flag; + int pass_stride; + int use_light_pass; + + int pass_combined; + int pass_depth; + int pass_normal; + int pass_pad; + + int pass_uv; + int pass_object_id; + int pass_material_id; + int pass_diffuse_color; + + int pass_glossy_color; + int pass_transmission_color; + int pass_diffuse_indirect; + int pass_glossy_indirect; + + int pass_transmission_indirect; + int pass_diffuse_direct; + int pass_glossy_direct; + int pass_transmission_direct; + + int pass_emission; + int pass_background; + int pass_pad1; + int pass_pad2; } KernelFilm; typedef struct KernelBackground { @@ -358,10 +464,6 @@ typedef struct KernelSunSky { /* sun direction in spherical and cartesian */ float theta, phi, pad3, pad4; - float3 dir; -#ifndef WITH_OPENCL - float pad; -#endif /* perez function parameters */ float zenith_Y, zenith_x, zenith_y, pad2; @@ -376,26 +478,30 @@ int num_all_lights; float pdf_triangles; float pdf_lights; + int pdf_background_res; /* bounces */ int min_bounce; int max_bounce; - int max_diffuse_bounce; - int max_glossy_bounce; - int max_transmission_bounce; + int max_diffuse_bounce; + int max_glossy_bounce; + int max_transmission_bounce; /* transparent */ - int transparent_min_bounce; - int transparent_max_bounce; + int transparent_min_bounce; + int transparent_max_bounce; int transparent_shadows; /* caustics */ int no_caustics; - float blur_caustics; /* seed */ int seed; + + /* render layer */ + int layer_flag; + int pad1, pad2, pad3; } KernelIntegrator; typedef struct KernelBVH { diff -Nru blender-2.61/intern/cycles/kernel/osl/nodes/CMakeLists.txt blender-2.62/intern/cycles/kernel/osl/nodes/CMakeLists.txt --- blender-2.61/intern/cycles/kernel/osl/nodes/CMakeLists.txt 2011-12-13 19:39:38.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/osl/nodes/CMakeLists.txt 2012-02-15 19:24:03.000000000 +0000 @@ -19,6 +19,8 @@ node_emission.osl node_environment_texture.osl node_fresnel.osl + node_gamma.osl + node_brightness.osl node_geometry.osl node_glass_bsdf.osl node_glossy_bsdf.osl @@ -33,6 +35,7 @@ node_mix.osl node_mix_closure.osl node_musgrave_texture.osl + node_normal.osl node_blend_weight_texture.osl node_noise_texture.osl node_output_displacement.osl diff -Nru blender-2.61/intern/cycles/kernel/osl/nodes/node_brightness.osl blender-2.62/intern/cycles/kernel/osl/nodes/node_brightness.osl --- blender-2.61/intern/cycles/kernel/osl/nodes/node_brightness.osl 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/osl/nodes/node_brightness.osl 2012-02-15 19:24:03.000000000 +0000 @@ -0,0 +1,50 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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 "stdosl.h" + +shader node_brightness( + color ColorIn = color(0.8, 0.8, 0.8), + float Bright = 0.0, + float Contrast = 0.0, + output ColorOut = color(0.8, 0.8, 0.8) +{ + float delta = Contrast * (1.0/200.0); + float a = 1.0 - delta * 2.0; + float b; + + Bright *= 1.0/100.0; + + /* + * The algorithm is by Werner D. Streidt + * (http://visca.com/ffactory/archives/5-99/msg00021.html) + * Extracted of OpenCV demhist.c + */ + + if (Contrast > 0.0) { + a = (a < 0.0 ? 1.0/a : 0.0); + b = a * (Brightness - delta); + } + else { + delta *= -1.0; + b = a * (Brightness + delta); + } + + ColorOut = a * ColorIn + b; +} + diff -Nru blender-2.61/intern/cycles/kernel/osl/nodes/node_gamma.osl blender-2.62/intern/cycles/kernel/osl/nodes/node_gamma.osl --- blender-2.61/intern/cycles/kernel/osl/nodes/node_gamma.osl 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/osl/nodes/node_gamma.osl 2012-02-15 19:24:03.000000000 +0000 @@ -0,0 +1,33 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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 "stdosl.h" + +shader node_gamma( + color ColorIn = color(0.8, 0.8, 0.8), + float Gamma = 1.0, + output ColorOut = color(0.8, 0.8, 0.8) +{ + int i; + for (i=0;i<3;i++) { + if (ColorIn[i] > 0.0) + ColorIn[i] = powf(ColorIn[i], Gamma); + } + + ColorOut = ColorIn; +} diff -Nru blender-2.61/intern/cycles/kernel/osl/nodes/node_hsv.osl blender-2.62/intern/cycles/kernel/osl/nodes/node_hsv.osl --- blender-2.61/intern/cycles/kernel/osl/nodes/node_hsv.osl 2011-12-13 19:39:38.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/osl/nodes/node_hsv.osl 2012-02-15 19:24:03.000000000 +0000 @@ -30,7 +30,8 @@ float t = clamp(Fac, 0.0, 1.0); color Color = rgb_to_hsv(ColorIn); - Color[0] += Hue - 0.5; + // remember: fmod doesn't work for negative numbers + Color[0] += Hue + 0.5; Color[0] = fmod(Color[0], 1.0); Color[1] *= Saturation; Color[2] *= Value; diff -Nru blender-2.61/intern/cycles/kernel/osl/nodes/node_normal.osl blender-2.62/intern/cycles/kernel/osl/nodes/node_normal.osl --- blender-2.61/intern/cycles/kernel/osl/nodes/node_normal.osl 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/osl/nodes/node_normal.osl 2012-02-15 19:24:03.000000000 +0000 @@ -0,0 +1,31 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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 "stdosl.h" + +shader node_normal( + normal Direction = normal(0.0, 0.0, 0.0), + normal NormalIn = normal(0.0, 0.0, 0.0), + output normal NormalOut = normal(0.0, 0.0, 0.0), + output float Dot = 1.0 +{ + Direction = normalize(Direction); + NormalOut = Direction; + Dot = dot(Direction, NormalIn); +} + diff -Nru blender-2.61/intern/cycles/kernel/svm/svm_brightness.h blender-2.62/intern/cycles/kernel/svm/svm_brightness.h --- blender-2.61/intern/cycles/kernel/svm/svm_brightness.h 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/svm/svm_brightness.h 2012-02-15 19:23:53.000000000 +0000 @@ -0,0 +1,41 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + */ + +CCL_NAMESPACE_BEGIN + +__device void svm_node_brightness(ShaderData *sd, float *stack, uint in_color, uint out_color, uint node) +{ + uint bright_offset, contrast_offset; + float3 color = stack_load_float3(stack, in_color); + + decode_node_uchar4(node, &bright_offset, &contrast_offset, NULL, NULL); + float brightness = stack_load_float(stack, bright_offset); + float contrast = stack_load_float(stack, contrast_offset); + + float a = 1.0f + contrast; + float b = brightness - contrast*0.5f; + + color.x = max(a*color.x + b, 0.0f); + color.y = max(a*color.y + b, 0.0f); + color.z = max(a*color.z + b, 0.0f); + + if (stack_valid(out_color)) + stack_store_float3(stack, out_color, color); +} + +CCL_NAMESPACE_END diff -Nru blender-2.61/intern/cycles/kernel/svm/svm_checker.h blender-2.62/intern/cycles/kernel/svm/svm_checker.h --- blender-2.61/intern/cycles/kernel/svm/svm_checker.h 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/svm/svm_checker.h 2012-02-15 19:23:53.000000000 +0000 @@ -0,0 +1,61 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + */ + +CCL_NAMESPACE_BEGIN + +/* Checker */ + +__device_noinline float svm_checker(float3 p, float scale) +{ + p *= scale; + + /* avoid precision issues on unit coordinates */ + p.x = (p.x + 0.00001f)*0.9999f; + p.y = (p.y + 0.00001f)*0.9999f; + p.z = (p.z + 0.00001f)*0.9999f; + + int xi = (int)fabsf(floorf(p.x)); + int yi = (int)fabsf(floorf(p.y)); + int zi = (int)fabsf(floorf(p.z)); + + return ((xi % 2 == yi % 2) == (zi % 2))? 1.0f: 0.0f; +} + +__device void svm_node_tex_checker(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) +{ + uint co_offset, color1_offset, color2_offset, scale_offset; + uint color_offset, fac_offset; + + decode_node_uchar4(node.y, &co_offset, &color1_offset, &color2_offset, &scale_offset); + decode_node_uchar4(node.z, &color_offset, &fac_offset, NULL, NULL); + + float3 co = stack_load_float3(stack, co_offset); + float3 color1 = stack_load_float3(stack, color1_offset); + float3 color2 = stack_load_float3(stack, color2_offset); + float scale = stack_load_float_default(stack, scale_offset, node.w); + + float f = svm_checker(co, scale); + + if(stack_valid(color_offset)) + stack_store_float3(stack, color_offset, (f == 1.0f)? color1: color2); + if(stack_valid(fac_offset)) + stack_store_float(stack, fac_offset, f); +} + +CCL_NAMESPACE_END + diff -Nru blender-2.61/intern/cycles/kernel/svm/svm_gamma.h blender-2.62/intern/cycles/kernel/svm/svm_gamma.h --- blender-2.61/intern/cycles/kernel/svm/svm_gamma.h 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/svm/svm_gamma.h 2012-02-15 19:23:53.000000000 +0000 @@ -0,0 +1,37 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + */ + +CCL_NAMESPACE_BEGIN + +__device void svm_node_gamma(ShaderData *sd, float *stack, uint in_gamma, uint in_color, uint out_color) +{ + float3 color = stack_load_float3(stack, in_color); + float gamma = stack_load_float(stack, in_gamma); + + if (color.x > 0.0) + color.x = powf(color.x, gamma); + if (color.y > 0.0) + color.y = powf(color.y, gamma); + if (color.z > 0.0) + color.z = powf(color.z, gamma); + + if (stack_valid(out_color)) + stack_store_float3(stack, out_color, color); +} + +CCL_NAMESPACE_END diff -Nru blender-2.61/intern/cycles/kernel/svm/svm.h blender-2.62/intern/cycles/kernel/svm/svm.h --- blender-2.61/intern/cycles/kernel/svm/svm.h 2011-12-13 19:39:43.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/svm/svm.h 2012-02-15 19:23:53.000000000 +0000 @@ -130,10 +130,13 @@ #include "svm_geometry.h" #include "svm_hsv.h" #include "svm_image.h" +#include "svm_gamma.h" +#include "svm_brightness.h" #include "svm_invert.h" #include "svm_light_path.h" #include "svm_magic.h" #include "svm_mapping.h" +#include "svm_normal.h" #include "svm_wave.h" #include "svm_math.h" #include "svm_mix.h" @@ -143,6 +146,7 @@ #include "svm_tex_coord.h" #include "svm_value.h" #include "svm_voronoi.h" +#include "svm_checker.h" CCL_NAMESPACE_BEGIN @@ -233,6 +237,9 @@ case NODE_TEX_MAGIC: svm_node_tex_magic(kg, sd, stack, node, &offset); break; + case NODE_TEX_CHECKER: + svm_node_tex_checker(kg, sd, stack, node, &offset); + break; #endif case NODE_CAMERA: svm_node_camera(kg, sd, stack, node.y, node.z, node.w); @@ -261,6 +268,12 @@ case NODE_INVERT: svm_node_invert(sd, stack, node.y, node.z, node.w); break; + case NODE_GAMMA: + svm_node_gamma(sd, stack, node.y, node.z, node.w); + break; + case NODE_BRIGHTCONTRAST: + svm_node_brightness(sd, stack, node.y, node.z, node.w); + break; case NODE_MIX: svm_node_mix(kg, sd, stack, node.y, node.z, node.w, &offset); break; @@ -300,6 +313,9 @@ case NODE_VECTOR_MATH: svm_node_vector_math(kg, sd, stack, node.y, node.z, node.w, &offset); break; + case NODE_NORMAL: + svm_node_normal(kg, sd, stack, node.y, node.z, node.w, &offset); + break; case NODE_MAPPING: svm_node_mapping(kg, sd, stack, node.y, node.z, &offset); break; diff -Nru blender-2.61/intern/cycles/kernel/svm/svm_hsv.h blender-2.62/intern/cycles/kernel/svm/svm_hsv.h --- blender-2.61/intern/cycles/kernel/svm/svm_hsv.h 2011-12-13 19:39:43.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/svm/svm_hsv.h 2012-02-15 19:23:53.000000000 +0000 @@ -110,7 +110,8 @@ color = rgb_to_hsv(color); - color.x += hue - 0.5f; + // remember: fmod doesn't work for negative numbers + color.x += hue + 0.5f; color.x = fmod(color.x, 1.0f); color.y *= sat; color.z *= val; diff -Nru blender-2.61/intern/cycles/kernel/svm/svm_image.h blender-2.62/intern/cycles/kernel/svm/svm_image.h --- blender-2.61/intern/cycles/kernel/svm/svm_image.h 2011-12-13 19:39:43.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/svm/svm_image.h 2012-02-15 19:23:53.000000000 +0000 @@ -175,9 +175,8 @@ decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &srgb); float3 co = stack_load_float3(stack, co_offset); - float u = (atan2f(co.y, co.x) + M_PI_F)/(2*M_PI_F); - float v = atan2f(co.z, hypotf(co.x, co.y))/M_PI_F + 0.5f; - float4 f = svm_image_texture(kg, id, u, v); + float2 uv = direction_to_equirectangular(co); + float4 f = svm_image_texture(kg, id, uv.x, uv.y); float3 r = make_float3(f.x, f.y, f.z); if(srgb) { diff -Nru blender-2.61/intern/cycles/kernel/svm/svm_musgrave.h blender-2.62/intern/cycles/kernel/svm/svm_musgrave.h --- blender-2.61/intern/cycles/kernel/svm/svm_musgrave.h 2011-12-13 19:39:43.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/svm/svm_musgrave.h 2012-02-15 19:23:53.000000000 +0000 @@ -213,7 +213,7 @@ decode_node_uchar4(node.y, &type, &co_offset, &color_offset, &fac_offset); decode_node_uchar4(node.z, &dimension_offset, &lacunarity_offset, &detail_offset, &offset_offset); - decode_node_uchar4(node.z, &gain_offset, &scale_offset, NULL, NULL); + decode_node_uchar4(node.w, &gain_offset, &scale_offset, NULL, NULL); float3 co = stack_load_float3(stack, co_offset); float dimension = stack_load_float_default(stack, dimension_offset, node2.x); diff -Nru blender-2.61/intern/cycles/kernel/svm/svm_noise.h blender-2.62/intern/cycles/kernel/svm/svm_noise.h --- blender-2.61/intern/cycles/kernel/svm/svm_noise.h 2011-12-13 19:39:43.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/svm/svm_noise.h 2012-02-15 19:23:53.000000000 +0000 @@ -84,8 +84,9 @@ __device float floorfrac(float x, int* i) { - *i = quick_floor(x); - return x - *i; + float f = floorf(x); + *i = (int)f; + return x - f; } __device float fade(float t) diff -Nru blender-2.61/intern/cycles/kernel/svm/svm_normal.h blender-2.62/intern/cycles/kernel/svm/svm_normal.h --- blender-2.61/intern/cycles/kernel/svm/svm_normal.h 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/svm/svm_normal.h 2012-02-15 19:23:53.000000000 +0000 @@ -0,0 +1,41 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + */ + +CCL_NAMESPACE_BEGIN + +__device void svm_node_normal(KernelGlobals *kg, ShaderData *sd, float *stack, uint in_normal_offset, uint out_normal_offset, uint out_dot_offset, int *offset) +{ + /* read extra data */ + uint4 node1 = read_node(kg, offset); + float3 normal = stack_load_float3(stack, in_normal_offset); + + float3 direction; + direction.x = __int_as_float(node1.x); + direction.y = __int_as_float(node1.y); + direction.z = __int_as_float(node1.z); + direction = normalize(direction); + + if (stack_valid(out_normal_offset)) + stack_store_float3(stack, out_normal_offset, direction); + + if (stack_valid(out_dot_offset)) + stack_store_float(stack, out_dot_offset, dot(direction, normalize(normal))); +} + +CCL_NAMESPACE_END + diff -Nru blender-2.61/intern/cycles/kernel/svm/svm_types.h blender-2.62/intern/cycles/kernel/svm/svm_types.h --- blender-2.61/intern/cycles/kernel/svm/svm_types.h 2011-12-13 19:39:43.000000000 +0000 +++ blender-2.62/intern/cycles/kernel/svm/svm_types.h 2012-02-15 19:23:53.000000000 +0000 @@ -84,7 +84,11 @@ NODE_COMBINE_RGB = 5100, NODE_HSV = 5200, NODE_CAMERA = 5300, - NODE_INVERT = 5400 + NODE_INVERT = 5400, + NODE_NORMAL = 5500, + NODE_GAMMA = 5600, + NODE_TEX_CHECKER = 5700, + NODE_BRIGHTCONTRAST = 5800 } NodeType; typedef enum NodeAttributeType { @@ -262,22 +266,26 @@ typedef enum ClosureType { CLOSURE_BSDF_ID, + CLOSURE_BSDF_DIFFUSE_ID, CLOSURE_BSDF_OREN_NAYAR_ID, - CLOSURE_BSDF_TRANSLUCENT_ID, + CLOSURE_BSDF_REFLECTION_ID, - CLOSURE_BSDF_REFRACTION_ID, - CLOSURE_BSDF_GLASS_ID, - CLOSURE_BSDF_TRANSPARENT_ID, CLOSURE_BSDF_MICROFACET_GGX_ID, - CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID, CLOSURE_BSDF_MICROFACET_BECKMANN_ID, - CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID, CLOSURE_BSDF_WARD_ID, - CLOSURE_BSDF_ASHIKHMIN_VELVET_ID, - CLOSURE_BSDF_WESTIN_BACKSCATTER_ID, CLOSURE_BSDF_WESTIN_SHEEN_ID, + CLOSURE_BSDF_TRANSLUCENT_ID, + CLOSURE_BSDF_REFRACTION_ID, + CLOSURE_BSDF_WESTIN_BACKSCATTER_ID, + CLOSURE_BSDF_ASHIKHMIN_VELVET_ID, + CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID, + CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID, + CLOSURE_BSDF_GLASS_ID, + + CLOSURE_BSDF_TRANSPARENT_ID, + CLOSURE_BSSRDF_CUBIC_ID, CLOSURE_EMISSION_ID, CLOSURE_DEBUG_ID, @@ -293,7 +301,10 @@ } ClosureType; /* watch this, being lazy with memory usage */ -#define CLOSURE_IS_BSDF(type) (type <= CLOSURE_BSDF_WESTIN_SHEEN_ID) +#define CLOSURE_IS_BSDF(type) (type <= CLOSURE_BSDF_TRANSPARENT_ID) +#define CLOSURE_IS_BSDF_DIFFUSE(type) (type >= CLOSURE_BSDF_DIFFUSE_ID && type <= CLOSURE_BSDF_OREN_NAYAR_ID) +#define CLOSURE_IS_BSDF_GLOSSY(type) (type >= CLOSURE_BSDF_REFLECTION_ID && type <= CLOSURE_BSDF_WESTIN_SHEEN_ID) +#define CLOSURE_IS_BSDF_TRANSMISSION(type) (type >= CLOSURE_BSDF_TRANSLUCENT_ID && type <= CLOSURE_BSDF_GLASS_ID) #define CLOSURE_IS_VOLUME(type) (type >= CLOSURE_VOLUME_ID && type <= CLOSURE_VOLUME_ISOTROPIC_ID) #define CLOSURE_IS_EMISSION(type) (type == CLOSURE_EMISSION_ID) #define CLOSURE_IS_HOLDOUT(type) (type == CLOSURE_HOLDOUT_ID) diff -Nru blender-2.61/intern/cycles/render/buffers.cpp blender-2.62/intern/cycles/render/buffers.cpp --- blender-2.61/intern/cycles/render/buffers.cpp 2011-12-13 19:39:29.000000000 +0000 +++ blender-2.62/intern/cycles/render/buffers.cpp 2012-02-15 19:23:45.000000000 +0000 @@ -22,6 +22,7 @@ #include "device.h" #include "util_debug.h" +#include "util_foreach.h" #include "util_hash.h" #include "util_image.h" #include "util_math.h" @@ -31,13 +32,53 @@ CCL_NAMESPACE_BEGIN +/* Buffer Params */ + +BufferParams::BufferParams() +{ + width = 0; + height = 0; + + full_x = 0; + full_y = 0; + full_width = 0; + full_height = 0; + + Pass::add(PASS_COMBINED, passes); +} + +void BufferParams::get_offset_stride(int& offset, int& stride) +{ + offset = -(full_x + full_y*width); + stride = width; +} + +bool BufferParams::modified(const BufferParams& params) +{ + return !(full_x == params.full_x + && full_y == params.full_y + && width == params.width + && height == params.height + && full_width == params.full_width + && full_height == params.full_height + && Pass::equals(passes, params.passes)); +} + +int BufferParams::get_passes_size() +{ + int size = 0; + + foreach(Pass& pass, passes) + size += pass.components; + + return align_up(size, 4); +} + /* Render Buffers */ RenderBuffers::RenderBuffers(Device *device_) { device = device_; - width = 0; - height = 0; } RenderBuffers::~RenderBuffers() @@ -58,24 +99,23 @@ } } -void RenderBuffers::reset(Device *device, int width_, int height_) +void RenderBuffers::reset(Device *device, BufferParams& params_) { - width = width_; - height = height_; + params = params_; /* free existing buffers */ device_free(); /* allocate buffer */ - buffer.resize(width, height); + buffer.resize(params.width*params.height*params.get_passes_size()); device->mem_alloc(buffer, MEM_READ_WRITE); device->mem_zero(buffer); /* allocate rng state */ - rng_state.resize(width, height); + rng_state.resize(params.width, params.height); - uint *init_state = rng_state.resize(width, height); - int x, y; + uint *init_state = rng_state.resize(params.width, params.height); + int x, y, width = params.width, height = params.height; for(x=0; xmem_copy_to(rng_state); } -float4 *RenderBuffers::copy_from_device(float exposure, int sample) +bool RenderBuffers::copy_from_device() { if(!buffer.device_pointer) - return NULL; + return false; - device->mem_copy_from(buffer, 0, buffer.memory_size()); + device->mem_copy_from(buffer, 0, params.width, params.height, params.get_passes_size()*sizeof(float)); - float4 *out = new float4[width*height]; - float4 *in = (float4*)buffer.data_pointer; - float scale = 1.0f/(float)sample; - - for(int i = width*height - 1; i >= 0; i--) { - float4 rgba = in[i]*scale; - - rgba.x = rgba.x*exposure; - rgba.y = rgba.y*exposure; - rgba.z = rgba.z*exposure; + return true; +} - /* clamp since alpha might be > 1.0 due to russian roulette */ - rgba.w = clamp(rgba.w, 0.0f, 1.0f); +bool RenderBuffers::get_pass(PassType type, float exposure, int sample, int components, float *pixels) +{ + int pass_offset = 0; + + foreach(Pass& pass, params.passes) { + if(pass.type != type) { + pass_offset += pass.components; + continue; + } + + float *in = (float*)buffer.data_pointer + pass_offset; + int pass_stride = params.get_passes_size(); + + float scale = (pass.filter)? 1.0f/(float)sample: 1.0f; + float scale_exposure = (pass.exposure)? scale*exposure: scale; + + int size = params.width*params.height; + + if(components == 1) { + assert(pass.components == components); + + /* scalar */ + if(type == PASS_DEPTH) { + for(int i = 0; i < size; i++, in += pass_stride, pixels++) { + float f = *in; + pixels[0] = (f == 0.0f)? 1e10f: f*scale_exposure; + } + } + else { + for(int i = 0; i < size; i++, in += pass_stride, pixels++) { + float f = *in; + pixels[0] = f*scale_exposure; + } + } + } + else if(components == 3) { + assert(pass.components == 4); + + /* RGB/vector */ + for(int i = 0; i < size; i++, in += pass_stride, pixels += 3) { + float3 f = make_float3(in[0], in[1], in[2]); + + pixels[0] = f.x*scale_exposure; + pixels[1] = f.y*scale_exposure; + pixels[2] = f.z*scale_exposure; + } + } + else if(components == 4) { + assert(pass.components == components); + + /* RGBA */ + for(int i = 0; i < size; i++, in += pass_stride, pixels += 4) { + float4 f = make_float4(in[0], in[1], in[2], in[3]); + + pixels[0] = f.x*scale_exposure; + pixels[1] = f.y*scale_exposure; + pixels[2] = f.z*scale_exposure; + + /* clamp since alpha might be > 1.0 due to russian roulette */ + pixels[3] = clamp(f.w*scale, 0.0f, 1.0f); + } + } - out[i] = rgba; + return true; } - return out; + return false; } /* Display Buffer */ @@ -117,8 +209,6 @@ DisplayBuffer::DisplayBuffer(Device *device_) { device = device_; - width = 0; - height = 0; draw_width = 0; draw_height = 0; transparent = true; /* todo: determine from background */ @@ -137,28 +227,27 @@ } } -void DisplayBuffer::reset(Device *device, int width_, int height_) +void DisplayBuffer::reset(Device *device, BufferParams& params_) { draw_width = 0; draw_height = 0; - width = width_; - height = height_; + params = params_; /* free existing buffers */ device_free(); /* allocate display pixels */ - rgba.resize(width, height); + rgba.resize(params.width, params.height); device->pixels_alloc(rgba); } -void DisplayBuffer::draw_set(int width_, int height_) +void DisplayBuffer::draw_set(int width, int height) { - assert(width_ <= width && height_ <= height); + assert(width <= params.width && height <= params.height); - draw_width = width_; - draw_height = height_; + draw_width = width; + draw_height = height; } void DisplayBuffer::draw_transparency_grid() @@ -175,11 +264,11 @@ }; glColor4ub(50, 50, 50, 255); - glRectf(0, 0, width, height); + glRectf(0, 0, params.width, params.height); glEnable(GL_POLYGON_STIPPLE); glColor4ub(55, 55, 55, 255); glPolygonStipple(checker_stipple_sml); - glRectf(0, 0, width, height); + glRectf(0, 0, params.width, params.height); glDisable(GL_POLYGON_STIPPLE); } @@ -189,7 +278,7 @@ if(transparent) draw_transparency_grid(); - device->draw_pixels(rgba, 0, draw_width, draw_height, width, height, transparent); + device->draw_pixels(rgba, 0, draw_width, draw_height, 0, params.width, params.height, transparent); } } diff -Nru blender-2.61/intern/cycles/render/buffers.h blender-2.62/intern/cycles/render/buffers.h --- blender-2.61/intern/cycles/render/buffers.h 2011-12-13 19:39:29.000000000 +0000 +++ blender-2.62/intern/cycles/render/buffers.h 2012-02-15 19:23:45.000000000 +0000 @@ -21,6 +21,10 @@ #include "device_memory.h" +#include "film.h" + +#include "kernel_types.h" + #include "util_string.h" #include "util_thread.h" #include "util_types.h" @@ -30,14 +34,41 @@ class Device; struct float4; +/* Buffer Parameters + Size of render buffer and how it fits in the full image (border render). */ + +class BufferParams { +public: + /* width/height of the physical buffer */ + int width; + int height; + + /* offset into and width/height of the full buffer */ + int full_x; + int full_y; + int full_width; + int full_height; + + /* passes */ + vector passes; + + /* functions */ + BufferParams(); + + void get_offset_stride(int& offset, int& stride); + bool modified(const BufferParams& params); + void add_pass(PassType type); + int get_passes_size(); +}; + /* Render Buffers */ class RenderBuffers { public: - /* buffer dimensions */ - int width, height; + /* buffer parameters */ + BufferParams params; /* float buffer */ - device_vector buffer; + device_vector buffer; /* random number generator state */ device_vector rng_state; /* mutex, must be locked manually by callers */ @@ -46,8 +77,10 @@ RenderBuffers(Device *device); ~RenderBuffers(); - void reset(Device *device, int width, int height); - float4 *copy_from_device(float exposure, int sample); + void reset(Device *device, BufferParams& params); + + bool copy_from_device(); + bool get_pass(PassType type, float exposure, int sample, int components, float *pixels); protected: void device_free(); @@ -62,8 +95,8 @@ class DisplayBuffer { public: - /* buffer dimensions */ - int width, height; + /* buffer parameters */ + BufferParams params; /* dimensions for how much of the buffer is actually ready for display. with progressive render we can be using only a subset of the buffer. if these are zero, it means nothing can be drawn yet */ @@ -78,7 +111,7 @@ DisplayBuffer(Device *device); ~DisplayBuffer(); - void reset(Device *device, int width, int height); + void reset(Device *device, BufferParams& params); void write(Device *device, const string& filename); void draw_set(int width, int height); diff -Nru blender-2.61/intern/cycles/render/camera.cpp blender-2.62/intern/cycles/render/camera.cpp --- blender-2.61/intern/cycles/render/camera.cpp 2011-12-13 19:39:29.000000000 +0000 +++ blender-2.62/intern/cycles/render/camera.cpp 2012-02-15 19:23:45.000000000 +0000 @@ -72,8 +72,9 @@ if(!need_update) return; + /* ndc to raster */ Transform screentocamera; - Transform ndctoraster = transform_scale((float)width, (float)height, 1.0f); + Transform ndctoraster = transform_scale(width, height, 1.0f); /* raster to screen */ Transform screentoraster = ndctoraster * @@ -148,13 +149,9 @@ /* type */ kcam->ortho = ortho; - /* size */ - kcam->width = width; - kcam->height = height; - /* store differentials */ - kcam->dx = dx; - kcam->dy = dy; + kcam->dx = float3_to_float4(dx); + kcam->dy = float3_to_float4(dy); /* clipping */ kcam->nearclip = nearclip; diff -Nru blender-2.61/intern/cycles/render/film.cpp blender-2.62/intern/cycles/render/film.cpp --- blender-2.61/intern/cycles/render/film.cpp 2011-12-13 19:39:29.000000000 +0000 +++ blender-2.62/intern/cycles/render/film.cpp 2012-02-15 19:23:45.000000000 +0000 @@ -21,11 +21,123 @@ #include "film.h" #include "scene.h" +#include "util_algorithm.h" +#include "util_foreach.h" + CCL_NAMESPACE_BEGIN +/* Pass */ + +static bool compare_pass_order(const Pass& a, const Pass& b) +{ + if(a.components == b.components) + return (a.type < b.type); + return (a.components > b.components); +} + +void Pass::add(PassType type, vector& passes) +{ + Pass pass; + + pass.type = type; + pass.filter = true; + pass.exposure = false; + + switch(type) { + case PASS_NONE: + pass.components = 0; + break; + case PASS_COMBINED: + pass.components = 4; + pass.exposure = true; + break; + case PASS_DEPTH: + pass.components = 1; + pass.filter = false; + break; + case PASS_NORMAL: + pass.components = 4; + break; + case PASS_UV: + pass.components = 4; + break; + case PASS_OBJECT_ID: + pass.components = 1; + pass.filter = false; + break; + case PASS_MATERIAL_ID: + pass.components = 1; + pass.filter = false; + break; + case PASS_DIFFUSE_COLOR: + pass.components = 4; + break; + case PASS_GLOSSY_COLOR: + pass.components = 4; + break; + case PASS_TRANSMISSION_COLOR: + pass.components = 4; + break; + case PASS_DIFFUSE_INDIRECT: + pass.components = 4; + pass.exposure = true; + break; + case PASS_GLOSSY_INDIRECT: + pass.components = 4; + pass.exposure = true; + break; + case PASS_TRANSMISSION_INDIRECT: + pass.components = 4; + pass.exposure = true; + break; + case PASS_DIFFUSE_DIRECT: + pass.components = 4; + pass.exposure = true; + break; + case PASS_GLOSSY_DIRECT: + pass.components = 4; + pass.exposure = true; + break; + case PASS_TRANSMISSION_DIRECT: + pass.components = 4; + pass.exposure = true; + break; + + case PASS_EMISSION: + pass.components = 4; + pass.exposure = true; + break; + case PASS_BACKGROUND: + pass.components = 4; + pass.exposure = true; + break; + } + + passes.push_back(pass); + + /* order from by components, to ensure alignment so passes with size 4 + come first and then passes with size 1 */ + sort(passes.begin(), passes.end(), compare_pass_order); +} + +bool Pass::equals(const vector& A, const vector& B) +{ + if(A.size() != B.size()) + return false; + + for(int i = 0; i < A.size(); i++) + if(A[i].type != B[i].type) + return false; + + return true; +} + +/* Film */ + Film::Film() { exposure = 0.8f; + Pass::add(PASS_COMBINED, passes); need_update = true; } @@ -42,6 +154,84 @@ /* update __data */ kfilm->exposure = exposure; + kfilm->pass_flag = 0; + kfilm->pass_stride = 0; + kfilm->use_light_pass = 0; + + foreach(Pass& pass, passes) { + kfilm->pass_flag |= pass.type; + + switch(pass.type) { + case PASS_COMBINED: + kfilm->pass_combined = kfilm->pass_stride; + break; + case PASS_DEPTH: + kfilm->pass_depth = kfilm->pass_stride; + break; + case PASS_NORMAL: + kfilm->pass_normal = kfilm->pass_stride; + break; + case PASS_UV: + kfilm->pass_uv = kfilm->pass_stride; + break; + case PASS_OBJECT_ID: + kfilm->pass_object_id = kfilm->pass_stride; + break; + case PASS_MATERIAL_ID: + kfilm->pass_material_id = kfilm->pass_stride; + break; + case PASS_DIFFUSE_COLOR: + kfilm->pass_diffuse_color = kfilm->pass_stride; + kfilm->use_light_pass = 1; + break; + case PASS_GLOSSY_COLOR: + kfilm->pass_glossy_color = kfilm->pass_stride; + kfilm->use_light_pass = 1; + break; + case PASS_TRANSMISSION_COLOR: + kfilm->pass_transmission_color = kfilm->pass_stride; + kfilm->use_light_pass = 1; + break; + case PASS_DIFFUSE_INDIRECT: + kfilm->pass_diffuse_indirect = kfilm->pass_stride; + kfilm->use_light_pass = 1; + break; + case PASS_GLOSSY_INDIRECT: + kfilm->pass_glossy_indirect = kfilm->pass_stride; + kfilm->use_light_pass = 1; + break; + case PASS_TRANSMISSION_INDIRECT: + kfilm->pass_transmission_indirect = kfilm->pass_stride; + kfilm->use_light_pass = 1; + break; + case PASS_DIFFUSE_DIRECT: + kfilm->pass_diffuse_direct = kfilm->pass_stride; + kfilm->use_light_pass = 1; + break; + case PASS_GLOSSY_DIRECT: + kfilm->pass_glossy_direct = kfilm->pass_stride; + kfilm->use_light_pass = 1; + break; + case PASS_TRANSMISSION_DIRECT: + kfilm->pass_transmission_direct = kfilm->pass_stride; + kfilm->use_light_pass = 1; + break; + + case PASS_EMISSION: + kfilm->pass_emission = kfilm->pass_stride; + kfilm->use_light_pass = 1; + break; + case PASS_BACKGROUND: + kfilm->pass_background = kfilm->pass_stride; + kfilm->use_light_pass = 1; + case PASS_NONE: + break; + } + + kfilm->pass_stride += pass.components; + } + + kfilm->pass_stride = align_up(kfilm->pass_stride, 4); need_update = false; } @@ -52,7 +242,8 @@ bool Film::modified(const Film& film) { - return !(exposure == film.exposure); + return !(exposure == film.exposure + && Pass::equals(passes, film.passes)); } void Film::tag_update(Scene *scene) diff -Nru blender-2.61/intern/cycles/render/film.h blender-2.62/intern/cycles/render/film.h --- blender-2.61/intern/cycles/render/film.h 2011-12-13 19:39:29.000000000 +0000 +++ blender-2.62/intern/cycles/render/film.h 2012-02-15 19:23:45.000000000 +0000 @@ -20,6 +20,9 @@ #define __FILM_H__ #include "util_string.h" +#include "util_vector.h" + +#include "kernel_types.h" CCL_NAMESPACE_BEGIN @@ -27,9 +30,21 @@ class DeviceScene; class Scene; +class Pass { +public: + PassType type; + int components; + bool filter; + bool exposure; + + static void add(PassType type, vector& passes); + static bool equals(const vector& A, const vector& B); +}; + class Film { public: float exposure; + vector passes; bool need_update; Film(); diff -Nru blender-2.61/intern/cycles/render/graph.cpp blender-2.62/intern/cycles/render/graph.cpp --- blender-2.61/intern/cycles/render/graph.cpp 2011-12-13 19:39:29.000000000 +0000 +++ blender-2.62/intern/cycles/render/graph.cpp 2012-02-15 19:23:45.000000000 +0000 @@ -292,6 +292,42 @@ } } +void ShaderGraph::remove_proxy_nodes(vector& removed) +{ + foreach(ShaderNode *node, nodes) { + ProxyNode *proxy = dynamic_cast(node); + if (proxy) { + ShaderInput *input = proxy->inputs[0]; + ShaderOutput *output = proxy->outputs[0]; + + /* temp. copy of the output links list. + * output->links is modified when we disconnect! + */ + vector links(output->links); + ShaderOutput *from = input->link; + + /* bypass the proxy node */ + if (from) { + disconnect(input); + foreach(ShaderInput *to, links) { + disconnect(to); + connect(from, to); + } + } + else { + foreach(ShaderInput *to, links) { + disconnect(to); + + /* transfer the default input value to the target socket */ + to->set(input->value); + } + } + + removed[proxy->id] = true; + } + } +} + void ShaderGraph::break_cycles(ShaderNode *node, vector& visited, vector& on_stack) { visited[node->id] = true; @@ -322,15 +358,28 @@ nodes that don't feed into the output. how cycles are broken is undefined, they are invalid input, the important thing is to not crash */ + vector removed(nodes.size(), false); vector visited(nodes.size(), false); vector on_stack(nodes.size(), false); + + list newnodes; + + /* remove proxy nodes */ + remove_proxy_nodes(removed); + + foreach(ShaderNode *node, nodes) { + if(!removed[node->id]) + newnodes.push_back(node); + else + delete node; + } + nodes = newnodes; + newnodes.clear(); /* break cycles */ break_cycles(output(), visited, on_stack); /* remove unused nodes */ - list newnodes; - foreach(ShaderNode *node, nodes) { if(visited[node->id]) newnodes.push_back(node); diff -Nru blender-2.61/intern/cycles/render/graph.h blender-2.62/intern/cycles/render/graph.h --- blender-2.61/intern/cycles/render/graph.h 2011-12-13 19:39:29.000000000 +0000 +++ blender-2.62/intern/cycles/render/graph.h 2012-02-15 19:23:45.000000000 +0000 @@ -217,6 +217,7 @@ void find_dependencies(set& dependencies, ShaderInput *input); void copy_nodes(set& nodes, map& nnodemap); + void remove_proxy_nodes(vector& removed); void break_cycles(ShaderNode *node, vector& visited, vector& on_stack); void clean(); void bump_from_displacement(); diff -Nru blender-2.61/intern/cycles/render/integrator.cpp blender-2.62/intern/cycles/render/integrator.cpp --- blender-2.61/intern/cycles/render/integrator.cpp 2011-12-13 19:39:29.000000000 +0000 +++ blender-2.62/intern/cycles/render/integrator.cpp 2012-02-15 19:23:45.000000000 +0000 @@ -41,9 +41,8 @@ transparent_shadows = false; no_caustics = false; - blur_caustics = 0.0f; - seed = 0; + layer_flag = ~0; need_update = true; } @@ -81,9 +80,8 @@ kintegrator->transparent_shadows = transparent_shadows; kintegrator->no_caustics = no_caustics; - kintegrator->blur_caustics = blur_caustics; - kintegrator->seed = hash_int(seed); + kintegrator->layer_flag = layer_flag << PATH_RAY_LAYER_SHIFT; /* sobol directions table */ int dimensions = PRNG_BASE_NUM + (max_bounce + transparent_max_bounce + 2)*PRNG_BOUNCE_NUM; @@ -115,7 +113,7 @@ transparent_probalistic == integrator.transparent_probalistic && transparent_shadows == integrator.transparent_shadows && no_caustics == integrator.no_caustics && - blur_caustics == integrator.blur_caustics && + layer_flag == integrator.layer_flag && seed == integrator.seed); } diff -Nru blender-2.61/intern/cycles/render/integrator.h blender-2.62/intern/cycles/render/integrator.h --- blender-2.61/intern/cycles/render/integrator.h 2011-12-13 19:39:29.000000000 +0000 +++ blender-2.62/intern/cycles/render/integrator.h 2012-02-15 19:23:45.000000000 +0000 @@ -41,9 +41,9 @@ bool transparent_shadows; bool no_caustics; - float blur_caustics; int seed; + int layer_flag; bool need_update; diff -Nru blender-2.61/intern/cycles/render/light.cpp blender-2.62/intern/cycles/render/light.cpp --- blender-2.61/intern/cycles/render/light.cpp 2011-12-13 19:39:29.000000000 +0000 +++ blender-2.62/intern/cycles/render/light.cpp 2012-02-15 19:23:45.000000000 +0000 @@ -26,8 +26,74 @@ #include "util_foreach.h" #include "util_progress.h" +#include "kernel_montecarlo.h" + CCL_NAMESPACE_BEGIN +static void dump_background_pixels(Device *device, DeviceScene *dscene, int res, vector& pixels) +{ + /* create input */ + int width = res; + int height = res; + + device_vector d_input; + device_vector d_output; + + uint4 *d_input_data = d_input.resize(width*height); + + for(int y = 0; y < height; y++) { + for(int x = 0; x < width; x++) { + float u = x/(float)width; + float v = y/(float)height; + float3 D = -equirectangular_to_direction(u, v); + + uint4 in = make_uint4(__float_as_int(D.x), __float_as_int(D.y), __float_as_int(D.z), 0); + d_input_data[x + y*width] = in; + } + } + + /* compute on device */ + float4 *d_output_data = d_output.resize(width*height); + memset((void*)d_output.data_pointer, 0, d_output.memory_size()); + + device->const_copy_to("__data", &dscene->data, sizeof(dscene->data)); + + device->mem_alloc(d_input, MEM_READ_ONLY); + device->mem_copy_to(d_input); + device->mem_alloc(d_output, MEM_WRITE_ONLY); + + DeviceTask main_task(DeviceTask::SHADER); + main_task.shader_input = d_input.device_pointer; + main_task.shader_output = d_output.device_pointer; + main_task.shader_eval_type = SHADER_EVAL_BACKGROUND; + main_task.shader_x = 0; + main_task.shader_w = width*height; + + list split_tasks; + main_task.split_max_size(split_tasks, 128*128); + + foreach(DeviceTask& task, split_tasks) { + device->task_add(task); + device->task_wait(); + } + + device->mem_copy_from(d_output, 0, 1, d_output.size(), sizeof(float4)); + device->mem_free(d_input); + device->mem_free(d_output); + + d_output_data = reinterpret_cast(d_output.data_pointer); + + pixels.resize(width*height); + + for(int y = 0; y < height; y++) { + for(int x = 0; x < width; x++) { + pixels[y*width + x].x = d_output_data[y*width + x].x; + pixels[y*width + x].y = d_output_data[y*width + x].y; + pixels[y*width + x].z = d_output_data[y*width + x].z; + } + } +} + /* Light */ Light::Light() @@ -44,6 +110,8 @@ axisv = make_float3(0.0f, 0.0f, 0.0f); sizev = 1.0f; + map_resolution = 512; + cast_shadow = true; shader = 0; } @@ -66,6 +134,8 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress) { + progress.set_status("Updating Lights", "Computing distribution"); + /* option to always sample all point lights */ bool multi_light = false; @@ -109,7 +179,7 @@ /* triangles */ size_t offset = 0; - size_t j = 0; + int j = 0; foreach(Object *object, scene->objects) { Mesh *mesh = object->mesh; @@ -128,7 +198,10 @@ /* sum area */ if(have_emission) { Transform tfm = object->tfm; - int object_id = (mesh->transform_applied)? -j-1: j; + int object_id = j; + + if(mesh->transform_applied) + object_id = ~object_id; for(size_t i = 0; i < mesh->triangles.size(); i++) { Shader *shader = scene->shaders[mesh->shader[i]]; @@ -161,9 +234,9 @@ if(!multi_light) { float lightarea = (totarea > 0.0f)? totarea/scene->lights.size(): 1.0f; - for(size_t i = 0; i < scene->lights.size(); i++, offset++) { + for(int i = 0; i < scene->lights.size(); i++, offset++) { distribution[offset].x = totarea; - distribution[offset].y = __int_as_float(-i-1); + distribution[offset].y = __int_as_float(~(int)i); distribution[offset].z = 1.0f; distribution[offset].w = scene->lights[i]->size; totarea += lightarea; @@ -229,6 +302,99 @@ dscene->light_distribution.clear(); } +void LightManager::device_update_background(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress) +{ + KernelIntegrator *kintegrator = &dscene->data.integrator; + Light *background_light = NULL; + + /* find background light */ + foreach(Light *light, scene->lights) { + if(light->type == LIGHT_BACKGROUND) { + background_light = light; + break; + } + } + + /* no background light found, signal renderer to skip sampling */ + if(!background_light) { + kintegrator->pdf_background_res = 0; + return; + } + + progress.set_status("Updating Lights", "Importance map"); + + assert(kintegrator->use_direct_light); + + /* get the resolution from the light's size (we stuff it in there) */ + int res = background_light->map_resolution; + kintegrator->pdf_background_res = res; + + assert(res > 0); + + vector pixels; + dump_background_pixels(device, dscene, res, pixels); + + if(progress.get_cancel()) + return; + + /* build row distributions and column distribution for the infinite area environment light */ + int cdf_count = res + 1; + float2 *marg_cdf = dscene->light_background_marginal_cdf.resize(cdf_count); + float2 *cond_cdf = dscene->light_background_conditional_cdf.resize(cdf_count * cdf_count); + + /* conditional CDFs (rows, U direction) */ + for(int i = 0; i < res; i++) { + float sin_theta = sinf(M_PI_F * (i + 0.5f) / res); + float3 env_color = pixels[i * res]; + float ave_luminamce = average(env_color); + + cond_cdf[i * cdf_count].x = ave_luminamce * sin_theta; + cond_cdf[i * cdf_count].y = 0.0f; + + for(int j = 1; j < res; j++) { + env_color = pixels[i * res + j]; + ave_luminamce = average(env_color); + + cond_cdf[i * cdf_count + j].x = ave_luminamce * sin_theta; + cond_cdf[i * cdf_count + j].y = cond_cdf[i * cdf_count + j - 1].y + cond_cdf[i * cdf_count + j - 1].x / res; + } + + float cdf_total = cond_cdf[i * cdf_count + res - 1].y + cond_cdf[i * cdf_count + res - 1].x / res; + + /* stuff the total into the brightness value for the last entry, because + we are going to normalize the CDFs to 0.0 to 1.0 afterwards */ + cond_cdf[i * cdf_count + res].x = cdf_total; + + if(cdf_total > 0.0f) + for(int j = 1; j < res; j++) + cond_cdf[i * cdf_count + j].y /= cdf_total; + + cond_cdf[i * cdf_count + res].y = 1.0f; + } + + /* marginal CDFs (column, V direction, sum of rows) */ + marg_cdf[0].x = cond_cdf[res].x; + marg_cdf[0].y = 0.0f; + + for(int i = 1; i < res; i++) { + marg_cdf[i].x = cond_cdf[i * cdf_count + res].x; + marg_cdf[i].y = marg_cdf[i - 1].y + marg_cdf[i - 1].x / res; + } + + float cdf_total = marg_cdf[res - 1].y + marg_cdf[res - 1].x / res; + marg_cdf[res].x = cdf_total; + + if(cdf_total > 0.0f) + for(int i = 1; i < res; i++) + marg_cdf[i].y /= cdf_total; + + marg_cdf[res].y = 1.0f; + + /* update device */ + device->tex_alloc("__light_background_marginal_cdf", dscene->light_background_marginal_cdf); + device->tex_alloc("__light_background_conditional_cdf", dscene->light_background_conditional_cdf); +} + void LightManager::device_update_points(Device *device, DeviceScene *dscene, Scene *scene) { if(scene->lights.size() == 0) @@ -236,6 +402,16 @@ float4 *light_data = dscene->light_data.resize(scene->lights.size()*LIGHT_SIZE); + if(!device->info.advanced_shading) { + /* remove unsupported light */ + foreach(Light *light, scene->lights) { + if(light->type == LIGHT_BACKGROUND) { + scene->lights.erase(std::remove(scene->lights.begin(), scene->lights.end(), light), scene->lights.end()); + break; + } + } + } + for(size_t i = 0; i < scene->lights.size(); i++) { Light *light = scene->lights[i]; float3 co = light->co; @@ -261,6 +437,14 @@ light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f); light_data[i*LIGHT_SIZE + 3] = make_float4(0.0f, 0.0f, 0.0f, 0.0f); } + else if(light->type == LIGHT_BACKGROUND) { + shader_id &= ~SHADER_AREA_LIGHT; + + light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), 0.0f, 0.0f, 0.0f); + light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), 0.0f, 0.0f, 0.0f); + light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f); + light_data[i*LIGHT_SIZE + 3] = make_float4(0.0f, 0.0f, 0.0f, 0.0f); + } else if(light->type == LIGHT_AREA) { float3 axisu = light->axisu*(light->sizeu*light->size); float3 axisv = light->axisv*(light->sizev*light->size); @@ -288,6 +472,9 @@ device_update_distribution(device, dscene, scene, progress); if(progress.get_cancel()) return; + device_update_background(device, dscene, scene, progress); + if(progress.get_cancel()) return; + need_update = false; } @@ -295,9 +482,13 @@ { device->tex_free(dscene->light_distribution); device->tex_free(dscene->light_data); + device->tex_free(dscene->light_background_marginal_cdf); + device->tex_free(dscene->light_background_conditional_cdf); dscene->light_distribution.clear(); dscene->light_data.clear(); + dscene->light_background_marginal_cdf.clear(); + dscene->light_background_conditional_cdf.clear(); } void LightManager::tag_update(Scene *scene) diff -Nru blender-2.61/intern/cycles/render/light.h blender-2.62/intern/cycles/render/light.h --- blender-2.61/intern/cycles/render/light.h 2011-12-13 19:39:29.000000000 +0000 +++ blender-2.62/intern/cycles/render/light.h 2012-02-15 19:23:45.000000000 +0000 @@ -46,6 +46,8 @@ float3 axisv; float sizev; + int map_resolution; + bool cast_shadow; int shader; @@ -68,6 +70,7 @@ protected: void device_update_points(Device *device, DeviceScene *dscene, Scene *scene); void device_update_distribution(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress); + void device_update_background(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress); }; CCL_NAMESPACE_END diff -Nru blender-2.61/intern/cycles/render/mesh.cpp blender-2.62/intern/cycles/render/mesh.cpp --- blender-2.61/intern/cycles/render/mesh.cpp 2011-12-13 19:39:29.000000000 +0000 +++ blender-2.62/intern/cycles/render/mesh.cpp 2012-02-15 19:23:45.000000000 +0000 @@ -586,6 +586,7 @@ bparams.top_level = true; bparams.use_qbvh = scene->params.use_qbvh; bparams.use_spatial_split = scene->params.use_bvh_spatial_split; + bparams.use_cache = scene->params.use_bvh_cache; delete bvh; bvh = BVH::create(bparams, scene->objects); diff -Nru blender-2.61/intern/cycles/render/mesh_displace.cpp blender-2.62/intern/cycles/render/mesh_displace.cpp --- blender-2.61/intern/cycles/render/mesh_displace.cpp 2011-12-13 19:39:29.000000000 +0000 +++ blender-2.62/intern/cycles/render/mesh_displace.cpp 2012-02-15 19:23:45.000000000 +0000 @@ -89,25 +89,26 @@ return false; /* run device task */ - device_vector d_offset; - d_offset.resize(d_input.size()); + device_vector d_output; + d_output.resize(d_input.size()); device->mem_alloc(d_input, MEM_READ_ONLY); device->mem_copy_to(d_input); - device->mem_alloc(d_offset, MEM_WRITE_ONLY); + device->mem_alloc(d_output, MEM_WRITE_ONLY); - DeviceTask task(DeviceTask::DISPLACE); - task.displace_input = d_input.device_pointer; - task.displace_offset = d_offset.device_pointer; - task.displace_x = 0; - task.displace_w = d_input.size(); + DeviceTask task(DeviceTask::SHADER); + task.shader_input = d_input.device_pointer; + task.shader_output = d_output.device_pointer; + task.shader_eval_type = SHADER_EVAL_DISPLACE; + task.shader_x = 0; + task.shader_w = d_input.size(); device->task_add(task); device->task_wait(); - device->mem_copy_from(d_offset, 0, sizeof(float3)*d_offset.size()); + device->mem_copy_from(d_output, 0, 1, d_output.size(), sizeof(float4)); device->mem_free(d_input); - device->mem_free(d_offset); + device->mem_free(d_output); if(progress.get_cancel()) return false; @@ -117,7 +118,7 @@ done.resize(mesh->verts.size(), false); int k = 0; - float3 *offset = (float3*)d_offset.data_pointer; + float4 *offset = (float4*)d_output.data_pointer; for(size_t i = 0; i < mesh->triangles.size(); i++) { Mesh::Triangle t = mesh->triangles[i]; @@ -129,7 +130,8 @@ for(int j = 0; j < 3; j++) { if(!done[t.v[j]]) { done[t.v[j]] = true; - mesh->verts[t.v[j]] += offset[k++]; + float3 off = float4_to_float3(offset[k++]); + mesh->verts[t.v[j]] += off; } } } diff -Nru blender-2.61/intern/cycles/render/nodes.cpp blender-2.62/intern/cycles/render/nodes.cpp --- blender-2.61/intern/cycles/render/nodes.cpp 2011-12-13 19:39:29.000000000 +0000 +++ blender-2.62/intern/cycles/render/nodes.cpp 2012-02-15 19:23:45.000000000 +0000 @@ -273,7 +273,6 @@ ksunsky->theta = theta; ksunsky->phi = phi; - ksunsky->dir = dir; float theta2 = theta*theta; float theta3 = theta*theta*theta; @@ -713,6 +712,89 @@ compiler.add(this, "node_magic_texture"); } +/* Checker Texture */ + +CheckerTextureNode::CheckerTextureNode() +: TextureNode("checker_texture") +{ + add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::TEXTURE_GENERATED); + add_input("Color1", SHADER_SOCKET_COLOR); + add_input("Color2", SHADER_SOCKET_COLOR); + add_input("Scale", SHADER_SOCKET_FLOAT, 1.0f); + + add_output("Color", SHADER_SOCKET_COLOR); + add_output("Fac", SHADER_SOCKET_FLOAT); +} + +void CheckerTextureNode::compile(SVMCompiler& compiler) +{ + ShaderInput *vector_in = input("Vector"); + ShaderInput *color1_in = input("Color1"); + ShaderInput *color2_in = input("Color2"); + ShaderInput *scale_in = input("Scale"); + + ShaderOutput *color_out = output("Color"); + ShaderOutput *fac_out = output("Fac"); + + compiler.stack_assign(vector_in); + compiler.stack_assign(color1_in); + compiler.stack_assign(color2_in); + if(scale_in->link) compiler.stack_assign(scale_in); + + if(!tex_mapping.skip()) + tex_mapping.compile(compiler, vector_in->stack_offset, vector_in->stack_offset); + + if(!color_out->links.empty()) + compiler.stack_assign(color_out); + if(!fac_out->links.empty()) + compiler.stack_assign(fac_out); + + compiler.add_node(NODE_TEX_CHECKER, + compiler.encode_uchar4(vector_in->stack_offset, color1_in->stack_offset, color2_in->stack_offset, scale_in->stack_offset), + compiler.encode_uchar4(color_out->stack_offset, fac_out->stack_offset), + __float_as_int(scale_in->value.x)); +} + +void CheckerTextureNode::compile(OSLCompiler& compiler) +{ + compiler.add(this, "node_checker_texture"); +} + +/* Normal */ + +NormalNode::NormalNode() +: ShaderNode("normal") +{ + direction = make_float3(0.0f, 0.0f, 1.0f); + + add_input("Normal", SHADER_SOCKET_NORMAL); + add_output("Normal", SHADER_SOCKET_NORMAL); + add_output("Dot", SHADER_SOCKET_FLOAT); +} + +void NormalNode::compile(SVMCompiler& compiler) +{ + ShaderInput *normal_in = input("Normal"); + ShaderOutput *normal_out = output("Normal"); + ShaderOutput *dot_out = output("Dot"); + + compiler.stack_assign(normal_in); + compiler.stack_assign(normal_out); + compiler.stack_assign(dot_out); + + compiler.add_node(NODE_NORMAL, normal_in->stack_offset, normal_out->stack_offset, dot_out->stack_offset); + compiler.add_node( + __float_as_int(direction.x), + __float_as_int(direction.y), + __float_as_int(direction.z)); +} + +void NormalNode::compile(OSLCompiler& compiler) +{ + compiler.parameter_vector("Direction", direction); + compiler.add(this, "node_normal"); +} + /* Mapping */ MappingNode::MappingNode() @@ -834,6 +916,26 @@ assert(0); } +/* Proxy */ + +ProxyNode::ProxyNode(ShaderSocketType from_, ShaderSocketType to_) +: ShaderNode("proxy") +{ + from = from_; + to = to_; + + add_input("Input", from); + add_output("Output", to); +} + +void ProxyNode::compile(SVMCompiler& compiler) +{ +} + +void ProxyNode::compile(OSLCompiler& compiler) +{ +} + /* BSDF Closure */ BsdfNode::BsdfNode() @@ -1691,6 +1793,65 @@ compiler.add(this, "node_combine_rgb"); } +/* Gamma */ +GammaNode::GammaNode() +: ShaderNode("gamma") +{ + add_input("Color", SHADER_SOCKET_COLOR); + add_input("Gamma", SHADER_SOCKET_FLOAT); + add_output("Color", SHADER_SOCKET_COLOR); +} + +void GammaNode::compile(SVMCompiler& compiler) +{ + ShaderInput *color_in = input("Color"); + ShaderInput *gamma_in = input("Gamma"); + ShaderOutput *color_out = output("Color"); + + compiler.stack_assign(color_in); + compiler.stack_assign(gamma_in); + compiler.stack_assign(color_out); + + compiler.add_node(NODE_GAMMA, gamma_in->stack_offset, color_in->stack_offset, color_out->stack_offset); +} + +void GammaNode::compile(OSLCompiler& compiler) +{ + compiler.add(this, "node_gamma"); +} + +/* Bright Contrast */ +BrightContrastNode::BrightContrastNode() +: ShaderNode("brightness") +{ + add_input("Color", SHADER_SOCKET_COLOR); + add_input("Bright", SHADER_SOCKET_FLOAT); + add_input("Contrast", SHADER_SOCKET_FLOAT); + add_output("Color", SHADER_SOCKET_COLOR); +} + +void BrightContrastNode::compile(SVMCompiler& compiler) +{ + ShaderInput *color_in = input("Color"); + ShaderInput *bright_in = input("Bright"); + ShaderInput *contrast_in = input("Contrast"); + ShaderOutput *color_out = output("Color"); + + compiler.stack_assign(color_in); + compiler.stack_assign(bright_in); + compiler.stack_assign(contrast_in); + compiler.stack_assign(color_out); + + compiler.add_node(NODE_BRIGHTCONTRAST, + color_in->stack_offset, color_out->stack_offset, + compiler.encode_uchar4(bright_in->stack_offset, contrast_in->stack_offset)); +} + +void BrightContrastNode::compile(OSLCompiler& compiler) +{ + compiler.add(this, "node_brightness"); +} + /* Separate RGB */ SeparateRGBNode::SeparateRGBNode() : ShaderNode("separate_rgb") diff -Nru blender-2.61/intern/cycles/render/nodes.h blender-2.62/intern/cycles/render/nodes.h --- blender-2.61/intern/cycles/render/nodes.h 2011-12-13 19:39:29.000000000 +0000 +++ blender-2.62/intern/cycles/render/nodes.h 2012-02-15 19:23:45.000000000 +0000 @@ -143,6 +143,11 @@ int depth; }; +class CheckerTextureNode : public TextureNode { +public: + SHADER_NODE_CLASS(CheckerTextureNode) +}; + class MappingNode : public ShaderNode { public: SHADER_NODE_CLASS(MappingNode) @@ -158,6 +163,14 @@ ShaderSocketType from, to; }; +class ProxyNode : public ShaderNode { +public: + ProxyNode(ShaderSocketType from, ShaderSocketType to); + SHADER_NODE_BASE_CLASS(ProxyNode) + + ShaderSocketType from, to; +}; + class BsdfNode : public ShaderNode { public: SHADER_NODE_CLASS(BsdfNode) @@ -302,6 +315,16 @@ SHADER_NODE_CLASS(CombineRGBNode) }; +class GammaNode : public ShaderNode { +public: + SHADER_NODE_CLASS(GammaNode) +}; + +class BrightContrastNode : public ShaderNode { +public: + SHADER_NODE_CLASS(BrightContrastNode) +}; + class SeparateRGBNode : public ShaderNode { public: SHADER_NODE_CLASS(SeparateRGBNode) @@ -343,6 +366,13 @@ static ShaderEnum type_enum; }; +class NormalNode : public ShaderNode { +public: + SHADER_NODE_CLASS(NormalNode) + + float3 direction; +}; + class VectorMathNode : public ShaderNode { public: SHADER_NODE_CLASS(VectorMathNode) diff -Nru blender-2.61/intern/cycles/render/object.cpp blender-2.62/intern/cycles/render/object.cpp --- blender-2.61/intern/cycles/render/object.cpp 2011-12-13 19:39:29.000000000 +0000 +++ blender-2.62/intern/cycles/render/object.cpp 2012-02-15 19:23:45.000000000 +0000 @@ -36,6 +36,7 @@ mesh = NULL; tfm = transform_identity(); visibility = ~0; + pass_id = 0; } Object::~Object() @@ -135,6 +136,7 @@ /* todo: correct for displacement, and move to a better place */ float uniform_scale; float surface_area = 0.0f; + float pass_id = ob->pass_id; if(transform_uniform_scale(tfm, uniform_scale)) { map::iterator it = surface_area_map.find(mesh); @@ -171,7 +173,7 @@ memcpy(&objects[offset], &tfm, sizeof(float4)*4); memcpy(&objects[offset+4], &itfm, sizeof(float4)*4); memcpy(&objects[offset+8], &ntfm, sizeof(float4)*4); - objects[offset+12] = make_float4(surface_area, 0.0f, 0.0f, 0.0f); + objects[offset+12] = make_float4(surface_area, pass_id, 0.0f, 0.0f); i++; diff -Nru blender-2.61/intern/cycles/render/object.h blender-2.62/intern/cycles/render/object.h --- blender-2.61/intern/cycles/render/object.h 2011-12-13 19:39:29.000000000 +0000 +++ blender-2.62/intern/cycles/render/object.h 2012-02-15 19:23:45.000000000 +0000 @@ -41,6 +41,7 @@ Transform tfm; BoundBox bounds; ustring name; + int pass_id; vector attributes; uint visibility; diff -Nru blender-2.61/intern/cycles/render/scene.h blender-2.62/intern/cycles/render/scene.h --- blender-2.61/intern/cycles/render/scene.h 2011-12-13 19:39:29.000000000 +0000 +++ blender-2.62/intern/cycles/render/scene.h 2012-02-15 19:23:45.000000000 +0000 @@ -78,6 +78,8 @@ /* lights */ device_vector light_distribution; device_vector light_data; + device_vector light_background_marginal_cdf; + device_vector light_background_conditional_cdf; /* shaders */ device_vector svm_nodes; diff -Nru blender-2.61/intern/cycles/render/session.cpp blender-2.62/intern/cycles/render/session.cpp --- blender-2.61/intern/cycles/render/session.cpp 2011-12-13 19:39:29.000000000 +0000 +++ blender-2.62/intern/cycles/render/session.cpp 2012-02-15 19:23:45.000000000 +0000 @@ -35,9 +35,9 @@ : params(params_), tile_manager(params.progressive, params.samples, params.tile_size, params.min_size) { - device_use_gl = ((params.device_type != DEVICE_CPU) && !params.background); + device_use_gl = ((params.device.type != DEVICE_CPU) && !params.background); - device = Device::create(params.device_type, params.background, params.threads); + device = Device::create(params.device, params.background, params.threads); buffers = new RenderBuffers(device); display = new DisplayBuffer(device); @@ -51,8 +51,6 @@ sample = 0; delayed_reset.do_reset = false; - delayed_reset.w = 0; - delayed_reset.h = 0; delayed_reset.samples = 0; display_outdated = false; @@ -108,7 +106,7 @@ /* GPU Session */ -void Session::reset_gpu(int w, int h, int samples) +void Session::reset_gpu(BufferParams& buffer_params, int samples) { /* block for buffer acces and reset immediately. we can't do this in the thread, because we need to allocate an OpenGL buffer, and @@ -119,7 +117,7 @@ display_outdated = true; reset_time = time_dt(); - reset_(w, h, samples); + reset_(buffer_params, samples); gpu_need_tonemap = false; gpu_need_tonemap_cond.notify_all(); @@ -127,7 +125,7 @@ pause_cond.notify_all(); } -bool Session::draw_gpu(int w, int h) +bool Session::draw_gpu(BufferParams& buffer_params) { /* block for buffer access */ thread_scoped_lock display_lock(display->mutex); @@ -136,7 +134,7 @@ if(gpu_draw_ready) { /* then verify the buffers have the expected size, so we don't draw previous results in a resized window */ - if(w == display->width && h == display->height) { + if(!buffer_params.modified(display->params)) { /* for CUDA we need to do tonemapping still, since we can only access GL buffers from the main thread */ if(gpu_need_tonemap) { @@ -164,6 +162,9 @@ reset_time = time_dt(); paused_time = 0.0; + if(!params.background) + progress.set_start_time(start_time - paused_time); + while(!progress.get_cancel()) { /* advance to next tile */ bool no_tiles = !tile_manager.next(); @@ -188,6 +189,9 @@ pause_cond.wait(pause_lock); paused_time += time_dt() - pause_start; + if(!params.background) + progress.set_start_time(start_time - paused_time); + update_status_time(pause, no_tiles); progress.set_update(); @@ -261,15 +265,14 @@ /* CPU Session */ -void Session::reset_cpu(int w, int h, int samples) +void Session::reset_cpu(BufferParams& buffer_params, int samples) { thread_scoped_lock reset_lock(delayed_reset.mutex); display_outdated = true; reset_time = time_dt(); - delayed_reset.w = w; - delayed_reset.h = h; + delayed_reset.params = buffer_params; delayed_reset.samples = samples; delayed_reset.do_reset = true; device->task_cancel(); @@ -277,7 +280,7 @@ pause_cond.notify_all(); } -bool Session::draw_cpu(int w, int h) +bool Session::draw_cpu(BufferParams& buffer_params) { thread_scoped_lock display_lock(display->mutex); @@ -285,7 +288,7 @@ if(display->draw_ready()) { /* then verify the buffers have the expected size, so we don't draw previous results in a resized window */ - if(w == display->width && h == display->height) { + if(!buffer_params.modified(display->params)) { display->draw(device); if(display_outdated && (time_dt() - reset_time) > params.text_timeout) @@ -306,7 +309,7 @@ thread_scoped_lock buffers_lock(buffers->mutex); thread_scoped_lock display_lock(display->mutex); - reset_(delayed_reset.w, delayed_reset.h, delayed_reset.samples); + reset_(delayed_reset.params, delayed_reset.samples); delayed_reset.do_reset = false; } @@ -335,6 +338,9 @@ pause_cond.wait(pause_lock); paused_time += time_dt() - pause_start; + if(!params.background) + progress.set_start_time(start_time - paused_time); + update_status_time(pause, no_tiles); progress.set_update(); @@ -389,7 +395,7 @@ if(delayed_reset.do_reset) { /* reset rendering if request from main thread */ delayed_reset.do_reset = false; - reset_(delayed_reset.w, delayed_reset.h, delayed_reset.samples); + reset_(delayed_reset.params, delayed_reset.samples); } else if(need_tonemap) { /* tonemap only if we do not reset, we don't we don't @@ -438,36 +444,39 @@ progress.set_update(); } -bool Session::draw(int w, int h) +bool Session::draw(BufferParams& buffer_params) { if(device_use_gl) - return draw_gpu(w, h); + return draw_gpu(buffer_params); else - return draw_cpu(w, h); + return draw_cpu(buffer_params); } -void Session::reset_(int w, int h, int samples) +void Session::reset_(BufferParams& buffer_params, int samples) { - if(w != buffers->width || h != buffers->height) { + if(buffer_params.modified(buffers->params)) { gpu_draw_ready = false; - buffers->reset(device, w, h); - display->reset(device, w, h); + buffers->reset(device, buffer_params); + display->reset(device, buffer_params); } - tile_manager.reset(w, h, samples); + tile_manager.reset(buffer_params, samples); start_time = time_dt(); preview_time = 0.0; paused_time = 0.0; sample = 0; + + if(!params.background) + progress.set_start_time(start_time - paused_time); } -void Session::reset(int w, int h, int samples) +void Session::reset(BufferParams& buffer_params, int samples) { if(device_use_gl) - reset_gpu(w, h, samples); + reset_gpu(buffer_params, samples); else - reset_cpu(w, h, samples); + reset_cpu(buffer_params, samples); } void Session::set_samples(int samples) @@ -514,14 +523,16 @@ progress.set_status("Updating Scene"); - /* update camera if dimensions changed for progressive render */ + /* update camera if dimensions changed for progressive render. the camera + knows nothing about progressive or cropped rendering, it just gets the + image dimensions passed in */ Camera *cam = scene->camera; - int w = tile_manager.state.width; - int h = tile_manager.state.height; + int width = tile_manager.state.buffer.full_width; + int height = tile_manager.state.buffer.full_height; - if(cam->width != w || cam->height != h) { - cam->width = w; - cam->height = h; + if(width != cam->width || height != cam->height) { + cam->width = width; + cam->height = height; cam->tag_update(); } @@ -557,15 +568,13 @@ /* update timing */ if(preview_time == 0.0 && resolution == 1) preview_time = time_dt(); - - double total_time = time_dt() - start_time - paused_time; + double sample_time = (sample == 0)? 0.0: (time_dt() - preview_time - paused_time)/(sample); /* negative can happen when we pause a bit before rendering, can discard that */ - if(total_time < 0.0) total_time = 0.0; if(preview_time < 0.0) preview_time = 0.0; - progress.set_sample(sample + 1, total_time, sample_time); + progress.set_sample(sample + 1, sample_time); } void Session::path_trace(Tile& tile) @@ -573,14 +582,15 @@ /* add path trace task */ DeviceTask task(DeviceTask::PATH_TRACE); - task.x = tile.x; - task.y = tile.y; + task.x = tile_manager.state.buffer.full_x + tile.x; + task.y = tile_manager.state.buffer.full_y + tile.y; task.w = tile.w; task.h = tile.h; task.buffer = buffers->buffer.device_pointer; task.rng_state = buffers->rng_state.device_pointer; task.sample = tile_manager.state.sample; task.resolution = tile_manager.state.resolution; + tile_manager.state.buffer.get_offset_stride(task.offset, task.stride); device->task_add(task); } @@ -590,14 +600,15 @@ /* add tonemap task */ DeviceTask task(DeviceTask::TONEMAP); - task.x = 0; - task.y = 0; - task.w = tile_manager.state.width; - task.h = tile_manager.state.height; + task.x = tile_manager.state.buffer.full_x; + task.y = tile_manager.state.buffer.full_y; + task.w = tile_manager.state.buffer.width; + task.h = tile_manager.state.buffer.height; task.rgba = display->rgba.device_pointer; task.buffer = buffers->buffer.device_pointer; task.sample = tile_manager.state.sample; task.resolution = tile_manager.state.resolution; + tile_manager.state.buffer.get_offset_stride(task.offset, task.stride); if(task.w > 0 && task.h > 0) { device->task_add(task); diff -Nru blender-2.61/intern/cycles/render/session.h blender-2.62/intern/cycles/render/session.h --- blender-2.61/intern/cycles/render/session.h 2011-12-13 19:39:29.000000000 +0000 +++ blender-2.62/intern/cycles/render/session.h 2012-02-15 19:23:45.000000000 +0000 @@ -19,6 +19,7 @@ #ifndef __SESSION_H__ #define __SESSION_H__ +#include "buffers.h" #include "device.h" #include "tile.h" @@ -27,6 +28,7 @@ CCL_NAMESPACE_BEGIN +class BufferParams; class Device; class DeviceScene; class DisplayBuffer; @@ -38,7 +40,7 @@ class SessionParams { public: - DeviceType device_type; + DeviceInfo device; bool background; string output_path; @@ -55,7 +57,6 @@ SessionParams() { - device_type = DEVICE_CPU; background = false; output_path = ""; @@ -72,7 +73,8 @@ } bool modified(const SessionParams& params) - { return !(device_type == params.device_type + { return !(device.type == params.device.type + && device.id == params.device.id && background == params.background && output_path == params.output_path /* && samples == params.samples */ @@ -106,11 +108,11 @@ ~Session(); void start(); - bool draw(int w, int h); + bool draw(BufferParams& params); void wait(); bool ready_to_reset(); - void reset(int w, int h, int samples); + void reset(BufferParams& params, int samples); void set_samples(int samples); void set_pause(bool pause); @@ -118,7 +120,7 @@ struct DelayedReset { thread_mutex mutex; bool do_reset; - int w, h; + BufferParams params; int samples; } delayed_reset; @@ -129,15 +131,15 @@ void tonemap(); void path_trace(Tile& tile); - void reset_(int w, int h, int samples); + void reset_(BufferParams& params, int samples); void run_cpu(); - bool draw_cpu(int w, int h); - void reset_cpu(int w, int h, int samples); + bool draw_cpu(BufferParams& params); + void reset_cpu(BufferParams& params, int samples); void run_gpu(); - bool draw_gpu(int w, int h); - void reset_gpu(int w, int h, int samples); + bool draw_gpu(BufferParams& params); + void reset_gpu(BufferParams& params, int samples); TileManager tile_manager; bool device_use_gl; diff -Nru blender-2.61/intern/cycles/render/shader.cpp blender-2.62/intern/cycles/render/shader.cpp --- blender-2.61/intern/cycles/render/shader.cpp 2011-12-13 19:39:29.000000000 +0000 +++ blender-2.62/intern/cycles/render/shader.cpp 2012-02-15 19:23:45.000000000 +0000 @@ -35,6 +35,7 @@ Shader::Shader() { name = ""; + pass_id = 0; graph = NULL; graph_bump = NULL; @@ -167,7 +168,7 @@ if(scene->shaders.size() == 0) return; - uint shader_flag_size = scene->shaders.size()*2; + uint shader_flag_size = scene->shaders.size()*4; uint *shader_flag = dscene->shader_flag.resize(shader_flag_size); uint i = 0; @@ -184,7 +185,9 @@ flag |= SD_HOMOGENEOUS_VOLUME; shader_flag[i++] = flag; + shader_flag[i++] = shader->pass_id; shader_flag[i++] = flag; + shader_flag[i++] = shader->pass_id; } device->tex_alloc("__shader_flag", dscene->shader_flag); diff -Nru blender-2.61/intern/cycles/render/shader.h blender-2.62/intern/cycles/render/shader.h --- blender-2.61/intern/cycles/render/shader.h 2011-12-13 19:39:29.000000000 +0000 +++ blender-2.62/intern/cycles/render/shader.h 2012-02-15 19:23:45.000000000 +0000 @@ -47,6 +47,7 @@ public: /* name */ string name; + int pass_id; /* shader graph */ ShaderGraph *graph; diff -Nru blender-2.61/intern/cycles/render/svm.cpp blender-2.62/intern/cycles/render/svm.cpp --- blender-2.61/intern/cycles/render/svm.cpp 2011-12-13 19:39:29.000000000 +0000 +++ blender-2.62/intern/cycles/render/svm.cpp 2012-02-15 19:23:45.000000000 +0000 @@ -58,7 +58,7 @@ } bool sunsky_done = false; - bool use_multi_closure = device->support_full_kernel(); + bool use_multi_closure = device->info.advanced_shading; for(i = 0; i < scene->shaders.size(); i++) { Shader *shader = scene->shaders[i]; diff -Nru blender-2.61/intern/cycles/render/tile.cpp blender-2.62/intern/cycles/render/tile.cpp --- blender-2.61/intern/cycles/render/tile.cpp 2011-12-13 19:39:29.000000000 +0000 +++ blender-2.62/intern/cycles/render/tile.cpp 2012-02-15 19:23:45.000000000 +0000 @@ -28,21 +28,21 @@ tile_size = tile_size_; min_size = min_size_; - reset(0, 0, 0); + BufferParams buffer_params; + reset(buffer_params, 0); } TileManager::~TileManager() { } -void TileManager::reset(int width_, int height_, int samples_) +void TileManager::reset(BufferParams& params_, int samples_) { - full_width = width_; - full_height = height_; + params = params_; start_resolution = 1; - int w = width_, h = height_; + int w = params.width, h = params.height; if(min_size != INT_MAX) { while(w*h > min_size*min_size) { @@ -55,8 +55,7 @@ samples = samples_; - state.width = 0; - state.height = 0; + state.buffer = BufferParams(); state.sample = -1; state.resolution = start_resolution; state.tiles.clear(); @@ -70,10 +69,10 @@ void TileManager::set_tiles() { int resolution = state.resolution; - int image_w = max(1, full_width/resolution); - int image_h = max(1, full_height/resolution); - int tile_w = (image_w + tile_size - 1)/tile_size; - int tile_h = (image_h + tile_size - 1)/tile_size; + int image_w = max(1, params.width/resolution); + int image_h = max(1, params.height/resolution); + int tile_w = (tile_size >= image_w)? 1: (image_w + tile_size - 1)/tile_size; + int tile_h = (tile_size >= image_h)? 1: (image_h + tile_size - 1)/tile_size; int sub_w = image_w/tile_w; int sub_h = image_h/tile_h; @@ -90,8 +89,13 @@ } } - state.width = image_w; - state.height = image_h; + state.buffer.width = image_w; + state.buffer.height = image_h; + + state.buffer.full_x = params.full_x/resolution; + state.buffer.full_y = params.full_y/resolution; + state.buffer.full_width = max(1, params.full_width/resolution); + state.buffer.full_height = max(1, params.full_height/resolution); } bool TileManager::done() diff -Nru blender-2.61/intern/cycles/render/tile.h blender-2.62/intern/cycles/render/tile.h --- blender-2.61/intern/cycles/render/tile.h 2011-12-13 19:39:29.000000000 +0000 +++ blender-2.62/intern/cycles/render/tile.h 2012-02-15 19:23:45.000000000 +0000 @@ -21,6 +21,7 @@ #include +#include "buffers.h" #include "util_list.h" CCL_NAMESPACE_BEGIN @@ -39,9 +40,10 @@ class TileManager { public: + BufferParams params; + struct State { - int width; - int height; + BufferParams buffer; int sample; int resolution; list tiles; @@ -50,7 +52,7 @@ TileManager(bool progressive, int samples, int tile_size, int min_size); ~TileManager(); - void reset(int width, int height, int samples); + void reset(BufferParams& params, int samples); void set_samples(int samples); bool next(); bool done(); @@ -63,8 +65,6 @@ int tile_size; int min_size; - int full_width; - int full_height; int start_resolution; }; diff -Nru blender-2.61/intern/cycles/SConscript blender-2.62/intern/cycles/SConscript --- blender-2.61/intern/cycles/SConscript 2011-12-13 19:39:53.000000000 +0000 +++ blender-2.62/intern/cycles/SConscript 2012-02-15 19:24:16.000000000 +0000 @@ -39,6 +39,9 @@ else: cxxflags.append('-ffast-math'.split()) +if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): + incs.append(env['BF_PTHREADS_INC']) + # optimized kernel if env['WITH_BF_RAYOPTIMIZATION']: optim_cxxflags = [] diff -Nru blender-2.61/intern/cycles/util/util_cache.cpp blender-2.62/intern/cycles/util/util_cache.cpp --- blender-2.61/intern/cycles/util/util_cache.cpp 2011-12-13 19:39:53.000000000 +0000 +++ blender-2.62/intern/cycles/util/util_cache.cpp 2012-02-15 19:24:15.000000000 +0000 @@ -19,11 +19,18 @@ #include #include "util_cache.h" +#include "util_debug.h" #include "util_foreach.h" +#include "util_map.h" #include "util_md5.h" #include "util_path.h" #include "util_types.h" +#define BOOST_FILESYSTEM_VERSION 2 + +#include +#include + CCL_NAMESPACE_BEGIN /* CacheData */ @@ -32,6 +39,7 @@ { name = name_; f = NULL; + have_filename = false; } CacheData::~CacheData() @@ -40,24 +48,35 @@ fclose(f); } +const string& CacheData::get_filename() +{ + if(!have_filename) { + MD5Hash hash; + + foreach(const CacheBuffer& buffer, buffers) + if(buffer.size) + hash.append((uint8_t*)buffer.data, buffer.size); + + filename = name + "_" + hash.get_hex(); + have_filename = true; + } + + return filename; +} + /* Cache */ Cache Cache::global; -string Cache::data_filename(const CacheData& key) +string Cache::data_filename(CacheData& key) { - MD5Hash hash; - - foreach(const CacheBuffer& buffer, key.buffers) - hash.append((uint8_t*)buffer.data, buffer.size); - - string fname = key.name + "_" + hash.get_hex(); - return path_get("cache/" + fname); + return path_user_get(path_join("cache", key.get_filename())); } -void Cache::insert(const CacheData& key, const CacheData& value) +void Cache::insert(CacheData& key, CacheData& value) { string filename = data_filename(key); + path_create_directories(filename); FILE *f = fopen(filename.c_str(), "wb"); if(!f) { @@ -65,17 +84,18 @@ return; } - foreach(const CacheBuffer& buffer, value.buffers) { + foreach(CacheBuffer& buffer, value.buffers) { if(!fwrite(&buffer.size, sizeof(buffer.size), 1, f)) fprintf(stderr, "Failed to write to file %s.\n", filename.c_str()); - if(!fwrite(buffer.data, buffer.size, 1, f)) - fprintf(stderr, "Failed to write to file %s.\n", filename.c_str()); + if(buffer.size) + if(!fwrite(buffer.data, buffer.size, 1, f)) + fprintf(stderr, "Failed to write to file %s.\n", filename.c_str()); } fclose(f); } -bool Cache::lookup(const CacheData& key, CacheData& value) +bool Cache::lookup(CacheData& key, CacheData& value) { string filename = data_filename(key); FILE *f = fopen(filename.c_str(), "rb"); @@ -89,5 +109,22 @@ return true; } +void Cache::clear_except(const string& name, const set& except) +{ + string dir = path_user_get("cache"); + + if(boost::filesystem::exists(dir)) { + boost::filesystem::directory_iterator it(dir), it_end; + + for(; it != it_end; it++) { + string filename = it->path().filename(); + + if(boost::starts_with(filename, name)) + if(except.find(filename) == except.end()) + boost::filesystem::remove(it->path()); + } + } +} + CCL_NAMESPACE_END diff -Nru blender-2.61/intern/cycles/util/util_cache.h blender-2.62/intern/cycles/util/util_cache.h --- blender-2.61/intern/cycles/util/util_cache.h 2011-12-13 19:39:53.000000000 +0000 +++ blender-2.62/intern/cycles/util/util_cache.h 2012-02-15 19:24:15.000000000 +0000 @@ -32,6 +32,7 @@ * different scenes where it may be hard to detect duplicate work. */ +#include "util_set.h" #include "util_string.h" #include "util_vector.h" @@ -50,25 +51,25 @@ public: vector buffers; string name; + string filename; + bool have_filename; FILE *f; CacheData(const string& name = ""); ~CacheData(); + const string& get_filename(); + template void add(const vector& data) { - if(data.size()) { - CacheBuffer buffer(&data[0], data.size()*sizeof(T)); - buffers.push_back(buffer); - } + CacheBuffer buffer(data.size()? &data[0]: NULL, data.size()*sizeof(T)); + buffers.push_back(buffer); } template void add(const array& data) { - if(data.size()) { - CacheBuffer buffer(&data[0], data.size()*sizeof(T)); - buffers.push_back(buffer); - } + CacheBuffer buffer(data.size()? &data[0]: NULL, data.size()*sizeof(T)); + buffers.push_back(buffer); } void add(void *data, size_t size) @@ -85,6 +86,12 @@ buffers.push_back(buffer); } + void add(float& data) + { + CacheBuffer buffer(&data, sizeof(float)); + buffers.push_back(buffer); + } + void add(size_t& data) { CacheBuffer buffer(&data, sizeof(size_t)); @@ -113,12 +120,30 @@ void read(int& data) { + size_t size; + + if(!fread(&size, sizeof(size), 1, f)) + fprintf(stderr, "Failed to read int size from cache.\n"); if(!fread(&data, sizeof(data), 1, f)) fprintf(stderr, "Failed to read int from cache.\n"); } + void read(float& data) + { + size_t size; + + if(!fread(&size, sizeof(size), 1, f)) + fprintf(stderr, "Failed to read float size from cache.\n"); + if(!fread(&data, sizeof(data), 1, f)) + fprintf(stderr, "Failed to read float from cache.\n"); + } + void read(size_t& data) { + size_t size; + + if(!fread(&size, sizeof(size), 1, f)) + fprintf(stderr, "Failed to read size_t size from cache.\n"); if(!fread(&data, sizeof(data), 1, f)) fprintf(stderr, "Failed to read size_t from cache.\n"); } @@ -128,11 +153,13 @@ public: static Cache global; - void insert(const CacheData& key, const CacheData& value); - bool lookup(const CacheData& key, CacheData& value); + void insert(CacheData& key, CacheData& value); + bool lookup(CacheData& key, CacheData& value); + + void clear_except(const string& name, const set& except); protected: - string data_filename(const CacheData& key); + string data_filename(CacheData& key); }; CCL_NAMESPACE_END diff -Nru blender-2.61/intern/cycles/util/util_math.h blender-2.62/intern/cycles/util/util_math.h --- blender-2.61/intern/cycles/util/util_math.h 2011-12-13 19:39:53.000000000 +0000 +++ blender-2.62/intern/cycles/util/util_math.h 2012-02-15 19:24:16.000000000 +0000 @@ -536,6 +536,11 @@ return make_float3(a.x, a.y, a.z); } +__device_inline float4 float3_to_float4(const float3 a) +{ + return make_float4(a.x, a.y, a.z, 1.0f); +} + #ifndef __KERNEL_GPU__ __device_inline void print_float3(const char *label, const float3& a) diff -Nru blender-2.61/intern/cycles/util/util_progress.h blender-2.62/intern/cycles/util/util_progress.h --- blender-2.61/intern/cycles/util/util_progress.h 2011-12-13 19:39:53.000000000 +0000 +++ blender-2.62/intern/cycles/util/util_progress.h 2012-02-15 19:24:15.000000000 +0000 @@ -27,6 +27,7 @@ #include "util_function.h" #include "util_string.h" +#include "util_time.h" #include "util_thread.h" CCL_NAMESPACE_BEGIN @@ -36,6 +37,7 @@ Progress() { sample = 0; + start_time = time_dt(); total_time = 0.0f; sample_time = 0.0f; status = "Initializing"; @@ -90,12 +92,19 @@ /* sample and timing information */ - void set_sample(int sample_, double total_time_, double sample_time_) + void set_start_time(double start_time_) + { + thread_scoped_lock lock(progress_mutex); + + start_time = start_time_; + } + + void set_sample(int sample_, double sample_time_) { thread_scoped_lock lock(progress_mutex); sample = sample_; - total_time = total_time_; + total_time = time_dt() - start_time; sample_time = sample_time_; } @@ -104,7 +113,7 @@ thread_scoped_lock lock(progress_mutex); sample_ = sample; - total_time_ = total_time; + total_time_ = (total_time > 0.0)? total_time: 0.0; sample_time_ = sample_time; } @@ -116,6 +125,7 @@ thread_scoped_lock lock(progress_mutex); status = status_; substatus = substatus_; + total_time = time_dt() - start_time; } set_update(); @@ -126,6 +136,7 @@ { thread_scoped_lock lock(progress_mutex); substatus = substatus_; + total_time = time_dt() - start_time; } set_update(); @@ -158,6 +169,7 @@ int sample; + double start_time; double total_time; double sample_time; diff -Nru blender-2.61/intern/cycles/util/util_thread.h blender-2.62/intern/cycles/util/util_thread.h --- blender-2.61/intern/cycles/util/util_thread.h 2011-12-13 19:39:53.000000000 +0000 +++ blender-2.62/intern/cycles/util/util_thread.h 2012-02-15 19:24:15.000000000 +0000 @@ -20,29 +20,54 @@ #define __UTIL_THREAD_H__ #include +#include #include +#include "util_function.h" + CCL_NAMESPACE_BEGIN -#if 0 +/* use boost for mutexes */ -/* Use STL for threading */ +typedef boost::mutex thread_mutex; +typedef boost::mutex::scoped_lock thread_scoped_lock; +typedef boost::condition_variable thread_condition_variable; -using std::thread; -using std::thread_mutex; -typedef std::lock_guard thread_scoped_lock; -using std::condition_variable; +/* own pthread based implementation, to avoid boost version conflicts with + dynamically loaded blender plugins */ -#else +class thread { +public: + thread(boost::function run_cb_) + { + joined = false; + run_cb = run_cb_; -/* Use boost for threading */ + pthread_create(&pthread_id, NULL, run, (void*)this); + } -using boost::thread; -typedef boost::mutex thread_mutex; -typedef boost::mutex::scoped_lock thread_scoped_lock; -typedef boost::condition_variable thread_condition_variable; + ~thread() + { + if(!joined) + join(); + } -#endif + static void *run(void *arg) + { + ((thread*)arg)->run_cb();; + return NULL; + } + + bool join() + { + return pthread_join(pthread_id, NULL) == 0; + } + +protected: + boost::function run_cb; + pthread_t pthread_id; + bool joined; +}; /* Thread Safe Queue to pass tasks from one thread to another. Tasks should be * pushed into the queue, while the worker thread waits to pop the next task diff -Nru blender-2.61/intern/cycles/util/util_transform.h blender-2.62/intern/cycles/util/util_transform.h --- blender-2.61/intern/cycles/util/util_transform.h 2011-12-13 19:39:53.000000000 +0000 +++ blender-2.62/intern/cycles/util/util_transform.h 2012-02-15 19:24:15.000000000 +0000 @@ -209,6 +209,13 @@ return make_float3(t->x[column], t->y[column], t->z[column]); } +__device_inline void transform_set_column(Transform *t, int column, float3 value) +{ + t->x[column] = value.x; + t->y[column] = value.y; + t->z[column] = value.z; +} + Transform transform_inverse(const Transform& a); __device_inline bool transform_uniform_scale(const Transform& tfm, float& scale) @@ -244,6 +251,17 @@ return (dot(cross(c0, c1), c2) < 0.0f); } +__device_inline Transform transform_clear_scale(const Transform& tfm) +{ + Transform ntfm = tfm; + + transform_set_column(&ntfm, 0, normalize(transform_get_column(&ntfm, 0))); + transform_set_column(&ntfm, 1, normalize(transform_get_column(&ntfm, 1))); + transform_set_column(&ntfm, 2, normalize(transform_get_column(&ntfm, 2))); + + return ntfm; +} + #endif CCL_NAMESPACE_END diff -Nru blender-2.61/intern/cycles/util/util_types.h blender-2.62/intern/cycles/util/util_types.h --- blender-2.61/intern/cycles/util/util_types.h 2011-12-13 19:39:53.000000000 +0000 +++ blender-2.62/intern/cycles/util/util_types.h 2012-02-15 19:24:15.000000000 +0000 @@ -277,6 +277,11 @@ return a; } +__device int align_up(int offset, int alignment) +{ + return (offset + alignment - 1) & ~(alignment - 1); +} + #endif CCL_NAMESPACE_END diff -Nru blender-2.61/intern/dualcon/CMakeLists.txt blender-2.62/intern/dualcon/CMakeLists.txt --- blender-2.61/intern/dualcon/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/intern/dualcon/CMakeLists.txt 2012-02-15 19:24:40.000000000 +0000 @@ -0,0 +1,46 @@ +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the 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. +# +# ***** END GPL LICENSE BLOCK ***** + +set(INC + . + intern + ../../extern/Eigen3 +) + +set(SRC + intern/manifold_table.cpp + intern/marching_cubes_table.cpp + intern/octree.cpp + intern/Projections.cpp + + intern/cubes.h + intern/GeoCommon.h + intern/manifold_table.h + intern/marching_cubes_table.h + intern/MemoryAllocator.h + intern/ModelReader.h + intern/octree.h + intern/Projections.h + intern/Queue.h + + intern/dualcon_c_api.cpp + dualcon.h +) + +blender_add_lib(bf_intern_dualcon "${SRC}" "${INC}" "") + diff -Nru blender-2.61/intern/dualcon/dualcon.h blender-2.62/intern/dualcon/dualcon.h --- blender-2.61/intern/dualcon/dualcon.h 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/intern/dualcon/dualcon.h 2012-02-15 19:24:40.000000000 +0000 @@ -0,0 +1,95 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + * Contributor(s): Nicholas Bishop + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef DUALCON_H +#define DUALCON_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef float (*DualConCo)[3]; +typedef unsigned int (*DualConFaces)[4]; +struct DerivedMesh; + +typedef struct DualConInput { + DualConCo co; + int co_stride; + int totco; + + DualConFaces faces; + int face_stride; + int totface; + + float min[3], max[3]; +} DualConInput; + +/* callback for allocating memory for output */ +typedef void *(*DualConAllocOutput)(int totvert, int totquad); +/* callback for adding a new vertex to the output */ +typedef void (*DualConAddVert)(void *output, const float co[3]); +/* callback for adding a new quad to the output */ +typedef void (*DualConAddQuad)(void *output, const int vert_indices[4]); + +typedef enum { + DUALCON_FLOOD_FILL = 1, +} DualConFlags; + +typedef enum { + /* blocky */ + DUALCON_CENTROID, + /* smooth */ + DUALCON_MASS_POINT, + /* keeps sharp edges */ + DUALCON_SHARP_FEATURES, +} DualConMode; + +/* Usage: + + The three callback arguments are used for creating the output + mesh. The alloc_output callback takes the total number of vertices + and faces (quads) that will be in the output. It should allocate + and return a structure to hold the output mesh. The add_vert and + add_quad callbacks will then be called for each new vertex and + quad, and the callback should add the new mesh elements to the + structure. +*/ +void *dualcon(const DualConInput *input_mesh, + /* callbacks for output */ + DualConAllocOutput alloc_output, + DualConAddVert add_vert, + DualConAddQuad add_quad, + + /* flags and settings to control the remeshing + algorithm */ + DualConFlags flags, + DualConMode mode, + float threshold, + float hermite_num, + float scale, + int depth); + +#ifdef __cplusplus +} +#endif + +#endif diff -Nru blender-2.61/intern/dualcon/intern/cubes.h blender-2.62/intern/dualcon/intern/cubes.h --- blender-2.61/intern/dualcon/intern/cubes.h 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/intern/dualcon/intern/cubes.h 2012-02-15 19:24:40.000000000 +0000 @@ -0,0 +1,46 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + * Contributor(s): Tao Ju + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef CUBES_H +#define CUBES_H + +#include "marching_cubes_table.h" + +/* simple wrapper for auto-generated marching cubes data */ +class Cubes +{ +public: + /// Get number of triangles + int getNumTriangle(int mask) + { + return marching_cubes_numtri[mask]; + } + + /// Get a triangle + void getTriangle(int mask, int index, int indices[3] ) + { + for(int i = 0; i < 3; i++) + indices[i] = marching_cubes_tris[mask][index][i]; + } +}; + +#endif diff -Nru blender-2.61/intern/dualcon/intern/dualcon_c_api.cpp blender-2.62/intern/dualcon/intern/dualcon_c_api.cpp --- blender-2.61/intern/dualcon/intern/dualcon_c_api.cpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/intern/dualcon/intern/dualcon_c_api.cpp 2012-02-15 19:24:40.000000000 +0000 @@ -0,0 +1,191 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + * Contributor(s): Nicholas Bishop + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#include "dualcon.h" +#include "ModelReader.h" +#include "octree.h" + +#include + +void veccopy(float dst[3], const float src[3]) +{ + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; +} + +#define GET_FACE(_mesh, _n) \ + (*(DualConFaces)(((char*)(_mesh)->faces) + ((_n) * (_mesh)->face_stride))) + +#define GET_CO(_mesh, _n) \ + (*(DualConCo)(((char*)(_mesh)->co) + ((_n) * (_mesh)->co_stride))) + +class DualConInputReader : public ModelReader +{ +private: + const DualConInput *input_mesh; + int tottri, curface, offset; + float min[3], max[3], maxsize; + float scale; +public: + DualConInputReader(const DualConInput *mesh, float _scale) + : input_mesh(mesh), scale(_scale) + { + reset(); + } + + void reset() + { + tottri = 0; + curface = 0; + offset = 0; + maxsize = 0; + + /* initialize tottri */ + for(int i = 0; i < input_mesh->totface; i++) + tottri += GET_FACE(input_mesh, i)[3] ? 2 : 1; + + veccopy(min, input_mesh->min); + veccopy(max, input_mesh->max); + + /* initialize maxsize */ + for(int i = 0; i < 3; i++) { + float d = max[i] - min[i]; + if(d > maxsize) + maxsize = d; + } + + /* redo the bounds */ + for(int i = 0; i < 3; i++) + { + min[i] = (max[i] + min[i]) / 2 - maxsize / 2; + max[i] = (max[i] + min[i]) / 2 + maxsize / 2; + } + + for(int i = 0; i < 3; i++) + min[i] -= maxsize * (1 / scale - 1) / 2; + maxsize *= 1 / scale; + } + + Triangle* getNextTriangle() + { + if(curface == input_mesh->totface) + return 0; + + Triangle* t = new Triangle(); + + unsigned int *f = GET_FACE(input_mesh, curface); + if(offset == 0) { + veccopy(t->vt[0], GET_CO(input_mesh, f[0])); + veccopy(t->vt[1], GET_CO(input_mesh, f[1])); + veccopy(t->vt[2], GET_CO(input_mesh, f[2])); + } + else { + veccopy(t->vt[0], GET_CO(input_mesh, f[2])); + veccopy(t->vt[1], GET_CO(input_mesh, f[3])); + veccopy(t->vt[2], GET_CO(input_mesh, f[0])); + } + + if(offset == 0 && f[3]) + offset++; + else { + offset = 0; + curface++; + } + + return t; + } + + int getNextTriangle(int t[3]) + { + if(curface == input_mesh->totface) + return 0; + + unsigned int *f = GET_FACE(input_mesh, curface); + if(offset == 0) { + t[0] = f[0]; + t[1] = f[1]; + t[2] = f[2]; + } + else { + t[0] = f[2]; + t[1] = f[3]; + t[2] = f[0]; + } + + if(offset == 0 && f[3]) + offset++; + else { + offset = 0; + curface++; + } + + return 1; + } + + int getNumTriangles() + { + return tottri; + } + + int getNumVertices() + { + return input_mesh->totco; + } + + float getBoundingBox(float origin[3]) + { + veccopy(origin, min); + return maxsize ; + } + + /* output */ + void getNextVertex(float v[3]) + { + /* not used */ + } + + /* stubs */ + void printInfo() {} + int getMemory() { return sizeof(DualConInputReader); } +}; + +void *dualcon(const DualConInput *input_mesh, + /* callbacks for output */ + DualConAllocOutput alloc_output, + DualConAddVert add_vert, + DualConAddQuad add_quad, + + DualConFlags flags, + DualConMode mode, + float threshold, + float hermite_num, + float scale, + int depth) +{ + DualConInputReader r(input_mesh, scale); + Octree o(&r, alloc_output, add_vert, add_quad, + flags, mode, depth, threshold, hermite_num); + o.scanConvert(); + return o.getOutputMesh(); +} diff -Nru blender-2.61/intern/dualcon/intern/GeoCommon.h blender-2.62/intern/dualcon/intern/GeoCommon.h --- blender-2.61/intern/dualcon/intern/GeoCommon.h 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/intern/dualcon/intern/GeoCommon.h 2012-02-15 19:24:40.000000000 +0000 @@ -0,0 +1,69 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + * Contributor(s): Tao Ju + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef GEOCOMMON_H +#define GEOCOMMON_H + +#define UCHAR unsigned char +#define USHORT unsigned short + +#define USE_MINIMIZER + +/** + * Structure definitions for points and triangles. + * + * @author Tao Ju + */ + + +// 3d point with integer coordinates +typedef struct +{ + int x, y, z; +} Point3i; + +typedef struct +{ + Point3i begin; + Point3i end; +} BoundingBox; + +// triangle that points to three vertices +typedef struct +{ + float vt[3][3] ; +} Triangle; + +// 3d point with float coordinates +typedef struct +{ + float x, y, z; +} Point3f; + +typedef struct +{ + Point3f begin; + Point3f end; +} BoundingBoxf; + + +#endif diff -Nru blender-2.61/intern/dualcon/intern/manifold_table.cpp blender-2.62/intern/dualcon/intern/manifold_table.cpp --- blender-2.61/intern/dualcon/intern/manifold_table.cpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/intern/dualcon/intern/manifold_table.cpp 2012-02-15 19:24:40.000000000 +0000 @@ -0,0 +1,282 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + * Contributor(s): Tao Ju + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "manifold_table.h" + +const ManifoldIndices manifold_table[256] = { + {0, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}}, + {1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}}, + {1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}}, + {1, {{1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}}, + {1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}}, + {1, {{1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}}}, + {2, {{0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}}}, + {1, {{1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}}, + {1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}}, + {2, {{1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}}}, + {1, {{0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}}}, + {1, {{1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}}, + {1, {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}}, + {1, {{1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}}, + {1, {{0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}}, + {1, {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}}, + {1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}}, + {1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}}}, + {2, {{1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}}}, + {1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}}, + {2, {{1, 1}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}}}, + {1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}}}, + {3, {{1, 1}, {2, 2}, {3, 3}, {0, 0}, {3, 3}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {3, 3}, {1, 1}, {0, 0}}}, + {1, {{0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}}}, + {2, {{1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}}}, + {2, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {0, 0}}}, + {2, {{1, 1}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {2, 2}, {1, 1}, {0, 0}}}, + {1, {{0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}}}, + {2, {{1, 1}, {0, 0}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}}, + {1, {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}}}, + {2, {{1, 1}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}}}, + {1, {{0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}}, + {1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}}, + {2, {{1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {0, 0}}}, + {1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}}}, + {1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}}, + {2, {{0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {0, 0}}}, + {2, {{1, 1}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {2, 2}, {0, 0}}}, + {2, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {2, 2}, {1, 1}, {2, 2}, {0, 0}}}, + {1, {{1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}}}, + {2, {{0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {0, 0}}}, + {3, {{1, 1}, {2, 2}, {0, 0}, {3, 3}, {1, 1}, {3, 3}, {0, 0}, {2, 2}, {1, 1}, {3, 3}, {2, 2}, {0, 0}}}, + {1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}}}, + {1, {{1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}}}, + {2, {{0, 0}, {1, 1}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}}, + {2, {{1, 1}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {0, 0}}}, + {1, {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}}}, + {1, {{1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}}, + {1, {{1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}}, + {1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}}, + {1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}}, + {1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}}, + {2, {{1, 1}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {0, 0}}}, + {1, {{0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}}}, + {2, {{1, 1}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {0, 0}}}, + {1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}}, + {2, {{1, 1}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {0, 0}}}, + {2, {{0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {1, 1}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {0, 0}}}, + {1, {{1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}}}, + {1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}}, + {2, {{1, 1}, {1, 1}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}}, + {2, {{0, 0}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 2}, {2, 2}, {2, 1}, {0, 0}, {0, 0}, {0, 0}}}, + {2, {{1, 1}, {0, 0}, {2, 2}, {1, 2}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {2, 1}, {0, 0}, {0, 0}, {0, 0}}}, + {1, {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}}, + {1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}}, + {2, {{1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}}}, + {2, {{0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}}}, + {2, {{1, 1}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {2, 2}}}, + {1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}}}, + {1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}}}, + {2, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}}}, + {1, {{1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}}}, + {2, {{0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {1, 1}}}, + {3, {{1, 1}, {0, 0}, {2, 2}, {3, 3}, {1, 1}, {3, 3}, {2, 2}, {0, 0}, {1, 1}, {3, 3}, {0, 0}, {2, 2}}}, + {2, {{0, 0}, {1, 1}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {2, 2}}}, + {2, {{1, 1}, {1, 1}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {2, 2}}}, + {1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}}, + {1, {{1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}}}, + {1, {{0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}}}, + {1, {{1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}}, + {1, {{1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}}}, + {1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}}}, + {2, {{1, 1}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {1, 1}}}, + {1, {{0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}}}, + {1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}}}, + {1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}}, + {2, {{1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {1, 1}}}, + {1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}}}, + {2, {{1, 1}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {1, 1}}}, + {2, {{0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {1, 1}}}, + {2, {{1, 1}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {2, 2}, {1, 1}, {1, 1}}}, + {2, {{0, 0}, {1, 2}, {1, 1}, {2, 2}, {2, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {1, 1}}}, + {1, {{1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}}}, + {1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}}}, + {2, {{2, 2}, {1, 1}, {0, 0}, {1, 1}, {2, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 2}}}, + {1, {{0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}}}, + {2, {{0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {2, 2}}}, + {3, {{1, 1}, {2, 2}, {3, 3}, {0, 0}, {1, 1}, {0, 0}, {3, 3}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {3, 3}}}, + {2, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {2, 2}, {0, 0}, {2, 2}, {1, 1}}}, + {2, {{1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {2, 2}}}, + {2, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {2, 2}}}, + {2, {{1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {1, 1}, {2, 2}, {1, 1}}}, + {2, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {2, 2}, {1, 1}, {2, 2}, {1, 1}}}, + {2, {{2, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {0, 0}, {1, 2}, {1, 1}, {2, 2}}}, + {3, {{0, 0}, {1, 1}, {2, 2}, {3, 3}, {0, 0}, {3, 3}, {2, 2}, {1, 1}, {0, 0}, {3, 3}, {1, 1}, {2, 2}}}, + {4, {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {1, 1}, {4, 4}, {3, 3}, {2, 2}, {1, 1}, {4, 4}, {2, 2}, {3, 3}}}, + {2, {{0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 1}}}, + {2, {{1, 1}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {2, 2}}}, + {2, {{0, 0}, {1, 1}, {0, 0}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {2, 2}}}, + {2, {{1, 1}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {1, 1}}}, + {2, {{0, 0}, {0, 0}, {0, 0}, {2, 1}, {1, 1}, {0, 0}, {1, 1}, {2, 2}, {1, 2}, {0, 0}, {2, 2}, {1, 1}}}, + {2, {{1, 2}, {0, 0}, {0, 0}, {2, 1}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {2, 2}, {1, 1}}}, + {1, {{1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}}, + {1, {{0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}}}, + {1, {{1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}}}, + {1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}}, + {1, {{1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}}}, + {1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {1, 1}}}, + {2, {{2, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {1, 2}, {2, 2}, {1, 1}, {0, 0}, {1, 1}}}, + {1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}}}, + {2, {{1, 1}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}}}, + {2, {{0, 0}, {1, 1}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {1, 1}}}, + {2, {{1, 2}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {2, 1}, {1, 1}, {1, 1}, {0, 0}, {2, 2}}}, + {2, {{0, 0}, {0, 0}, {2, 2}, {1, 1}, {1, 2}, {0, 0}, {0, 0}, {2, 1}, {0, 0}, {1, 1}, {0, 0}, {2, 2}}}, + {2, {{1, 1}, {1, 1}, {0, 0}, {2, 2}, {1, 2}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {2, 1}}}, + {2, {{0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {1, 2}, {0, 0}, {0, 0}, {2, 1}}}, + {2, {{1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}}}, + {1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}}, + {1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}}, + {2, {{1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}}}, + {2, {{0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}}}, + {2, {{1, 1}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {2, 2}}}, + {2, {{0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}}}, + {2, {{1, 1}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {2, 2}}}, + {3, {{0, 0}, {1, 1}, {2, 2}, {3, 3}, {2, 2}, {1, 1}, {0, 0}, {3, 3}, {1, 1}, {2, 2}, {0, 0}, {3, 3}}}, + {2, {{1, 1}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}}}, + {1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}}}, + {2, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {2, 2}}}, + {1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {1, 1}}}, + {1, {{1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}}}, + {1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}}, + {1, {{1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}}}, + {1, {{0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}}}, + {1, {{1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}}, + {2, {{1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}}}, + {2, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {1, 1}}}, + {3, {{1, 1}, {2, 2}, {0, 0}, {3, 3}, {0, 0}, {2, 2}, {1, 1}, {3, 3}, {2, 2}, {0, 0}, {1, 1}, {3, 3}}}, + {2, {{0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}}}, + {3, {{1, 1}, {0, 0}, {2, 2}, {3, 3}, {2, 2}, {0, 0}, {1, 1}, {3, 3}, {0, 0}, {2, 2}, {1, 1}, {3, 3}}}, + {2, {{0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {1, 1}, {1, 1}, {2, 2}}}, + {4, {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {3, 3}, {2, 2}, {1, 1}, {4, 4}, {2, 2}, {3, 3}, {1, 1}, {4, 4}}}, + {2, {{0, 0}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {2, 2}}}, + {2, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {2, 2}}}, + {2, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {1, 1}, {2, 2}}}, + {2, {{1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {2, 2}, {2, 2}, {1, 1}, {2, 2}}}, + {2, {{0, 0}, {2, 1}, {0, 0}, {0, 0}, {1, 2}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {1, 1}, {2, 2}, {1, 1}}}, + {2, {{1, 1}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}}}, + {2, {{0, 0}, {0, 0}, {2, 1}, {0, 0}, {0, 0}, {1, 2}, {1, 1}, {2, 2}, {1, 1}, {0, 0}, {1, 1}, {2, 2}}}, + {2, {{1, 1}, {2, 2}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {2, 2}, {2, 2}, {0, 0}, {1, 1}, {2, 2}}}, + {2, {{0, 0}, {1, 2}, {2, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}}}, + {1, {{0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}}}, + {2, {{1, 1}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {2, 2}}}, + {1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}}}, + {1, {{1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}}}, + {2, {{0, 0}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {1, 1}}}, + {2, {{1, 1}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {2, 2}}}, + {2, {{0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {2, 2}}}, + {2, {{1, 1}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 2}, {2, 2}}}, + {1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}}}, + {2, {{1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {2, 2}, {2, 2}}}, + {1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}}, + {1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}}}, + {1, {{0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}}}, + {2, {{2, 2}, {1, 1}, {1, 2}, {0, 0}, {0, 0}, {2, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {1, 1}}}, + {1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}}}, + {1, {{1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}}}, + {1, {{1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}}, + {1, {{0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}}}, + {1, {{1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}}}, + {1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}}, + {2, {{1, 1}, {1, 1}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {1, 1}}}, + {2, {{0, 0}, {1, 1}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 1}, {0, 0}, {1, 2}, {2, 2}, {0, 0}, {1, 1}}}, + {2, {{1, 1}, {0, 0}, {2, 2}, {1, 1}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {1, 1}}}, + {2, {{0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {1, 2}, {2, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {1, 1}}}, + {1, {{1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}}}, + {2, {{0, 0}, {2, 1}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {1, 2}}}, + {1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}}}, + {1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}}}, + {2, {{2, 2}, {1, 2}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {2, 1}}}, + {2, {{0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {2, 2}}}, + {2, {{2, 2}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 2}, {0, 0}, {0, 0}, {2, 1}}}, + {1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}}}, + {1, {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}}, + {2, {{1, 1}, {0, 0}, {2, 2}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}}, + {2, {{0, 0}, {1, 1}, {2, 2}, {2, 2}, {0, 0}, {1, 1}, {2, 2}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}}, + {2, {{1, 1}, {1, 1}, {2, 2}, {2, 2}, {1, 1}, {1, 1}, {2, 2}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}}, + {1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}}, + {1, {{1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}}}, + {2, {{0, 0}, {1, 1}, {0, 0}, {2, 2}, {2, 2}, {1, 1}, {2, 2}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}}}, + {2, {{1, 2}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {2, 1}, {0, 0}, {0, 0}}}, + {1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}}, + {2, {{1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {2, 2}, {2, 2}, {2, 2}, {1, 1}, {2, 2}, {0, 0}, {0, 0}}}, + {1, {{0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}}}, + {2, {{1, 1}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 2}, {0, 0}, {2, 1}, {0, 0}, {0, 0}}}, + {1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}}, + {1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}}, + {1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}}, + {1, {{1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}}, + {1, {{1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}}, + {1, {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}}}, + {2, {{1, 1}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {0, 0}}}, + {2, {{0, 0}, {1, 1}, {1, 2}, {2, 2}, {1, 1}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {2, 1}, {0, 0}}}, + {1, {{1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}}}, + {1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}}}, + {2, {{1, 1}, {2, 2}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {1, 1}, {0, 0}}}, + {2, {{0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 2}, {2, 1}, {0, 0}}}, + {1, {{1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}}}, + {2, {{0, 0}, {0, 0}, {2, 1}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {1, 2}, {0, 0}}}, + {2, {{1, 1}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {2, 1}, {2, 2}, {1, 2}, {1, 1}, {0, 0}}}, + {2, {{0, 0}, {1, 1}, {2, 2}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {1, 1}, {0, 0}}}, + {1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}}, + {1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}}}, + {2, {{1, 1}, {2, 2}, {0, 0}, {0, 0}, {1, 2}, {0, 0}, {0, 0}, {2, 1}, {2, 2}, {0, 0}, {1, 1}, {0, 0}}}, + {1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}}, + {1, {{0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}}, + {2, {{1, 1}, {2, 2}, {2, 2}, {2, 2}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}}}, + {1, {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}}}, + {2, {{2, 2}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {1, 2}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {2, 1}, {0, 0}}}, + {1, {{0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}}}, + {2, {{1, 1}, {2, 2}, {0, 0}, {1, 2}, {0, 0}, {0, 0}, {2, 1}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {0, 0}}}, + {2, {{0, 0}, {0, 0}, {0, 0}, {2, 1}, {2, 2}, {1, 1}, {1, 2}, {0, 0}, {1, 1}, {2, 2}, {1, 1}, {0, 0}}}, + {2, {{1, 1}, {0, 0}, {0, 0}, {2, 2}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}}}, + {1, {{0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}}}, + {2, {{1, 1}, {2, 2}, {2, 2}, {0, 0}, {1, 1}, {2, 2}, {2, 2}, {0, 0}, {1, 1}, {2, 2}, {2, 2}, {0, 0}}}, + {1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}}}, + {2, {{1, 1}, {0, 0}, {2, 2}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}, {0, 0}, {2, 1}, {1, 2}, {0, 0}}}, + {1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}}, + {2, {{1, 1}, {2, 2}, {0, 0}, {0, 0}, {0, 0}, {1, 2}, {2, 1}, {0, 0}, {1, 1}, {0, 0}, {2, 2}, {0, 0}}}, + {1, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}}}, + {1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}}}, + {1, {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}}, + {1, {{0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}}, + {1, {{1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}}, + {1, {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}}, + {1, {{1, 1}, {1, 1}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}}, + {1, {{0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}}}, + {2, {{1, 2}, {0, 0}, {0, 0}, {2, 1}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, {0, 0}, {0, 0}}}, + {1, {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}}, + {1, {{1, 1}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}}, + {2, {{0, 0}, {1, 2}, {2, 1}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}, {2, 2}, {1, 1}, {0, 0}, {0, 0}}}, + {1, {{1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}}}, + {1, {{0, 0}, {0, 0}, {1, 1}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}}}, + {1, {{1, 1}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}}, + {1, {{0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}}, + {1, {{1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {0, 0}, {0, 0}, {0, 0}}}, + {0, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}} +}; diff -Nru blender-2.61/intern/dualcon/intern/manifold_table.h blender-2.62/intern/dualcon/intern/manifold_table.h --- blender-2.61/intern/dualcon/intern/manifold_table.h 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/intern/dualcon/intern/manifold_table.h 2012-02-15 19:24:40.000000000 +0000 @@ -0,0 +1,33 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + * Contributor(s): Tao Ju + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef MANIFOLD_TABLE_H +#define MANIFOLD_TABLE_H + +typedef struct { + int comps; + int pairs[12][2]; +} ManifoldIndices; + +extern const ManifoldIndices manifold_table[256]; + +#endif diff -Nru blender-2.61/intern/dualcon/intern/marching_cubes_table.cpp blender-2.62/intern/dualcon/intern/marching_cubes_table.cpp --- blender-2.61/intern/dualcon/intern/marching_cubes_table.cpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/intern/dualcon/intern/marching_cubes_table.cpp 2012-02-15 19:24:40.000000000 +0000 @@ -0,0 +1,554 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + * Contributor(s): Tao Ju + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "marching_cubes_table.h" + +/* number of triangles in each configuration */ +const int marching_cubes_numtri[TOTCONF] = { + 0, 1, 1, 2, 1, 2, 4, 3, 1, 4, 2, 3, 2, 3, 3, 2, 1, 2, 4, 3, 4, 3, 5, 4, + 6, 5, 5, 4, 5, 4, 4, 3, 1, 4, 2, 3, 6, 5, 5, 4, 4, 5, 3, 4, 5, 4, 4, 3, + 2, 3, 3, 2, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, 1, 4, 6, 5, 2, 3, 5, 4, + 4, 5, 5, 4, 3, 4, 4, 3, 2, 3, 5, 4, 3, 2, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, + 4, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, 3, 4, 4, 3, 4, 3, 3, 2, + 4, 3, 3, 2, 3, 2, 2, 1, 1, 6, 4, 5, 4, 5, 5, 4, 2, 5, 3, 4, 3, 4, 4, 3, + 4, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, 2, 5, 3, 4, 5, 4, 4, 3, + 3, 4, 2, 3, 4, 3, 3, 2, 3, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1, + 2, 5, 5, 4, 3, 4, 4, 3, 3, 4, 4, 3, 2, 3, 3, 2, 3, 4, 4, 3, 4, 3, 3, 2, + 4, 3, 3, 2, 3, 2, 2, 1, 3, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1, + 2, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0 +}; + +/* table of triangles in each configuration */ +const int marching_cubes_tris[TOTCONF][MAX_TRIS][3] = { + {{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,0,8}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,1,5}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,0,1}, {4,1,5}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,9,2}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,8,9}, {0,9,2}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{1,5,9}, {1,9,2}, {1,2,4}, {1,4,8}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,1,5}, {0,5,9}, {0,9,2}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{5,3,9}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,8,5}, {0,5,3}, {0,3,9}, {0,9,4}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,1,3}, {8,3,9}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,0,1}, {4,1,3}, {4,3,9}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,5,3}, {4,3,2}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,8,5}, {0,5,3}, {0,3,2}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,8,1}, {4,1,3}, {4,3,2}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,1,3}, {0,3,2}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,6,10}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,4,6}, {8,6,10}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{6,10,1}, {6,1,5}, {6,5,8}, {6,8,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,6,10}, {4,10,1}, {4,1,5}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,0,4}, {10,4,9}, {10,9,2}, {10,2,6}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{6,10,8}, {6,8,9}, {6,9,2}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,8,0}, {6,10,1}, {6,1,5}, {6,5,9}, {6,9,2}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{6,10,1}, {6,1,5}, {6,5,9}, {6,9,2}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,0,5}, {0,6,9}, {9,5,0}, {6,10,3}, {5,3,10}, + {3,9,6}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,8,5}, {10,5,3}, {9,4,6}, {6,10,3}, {6,3,9}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,1,3}, {9,8,0}, {9,0,6}, {6,10,3}, {6,3,9}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,6,10}, {4,10,1}, {4,1,3}, {4,3,9}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,4,5}, {3,2,6}, {3,6,10}, {10,0,5}, {10,5,3}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{6,10,8}, {6,8,5}, {6,5,3}, {6,3,2}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,8,0}, {6,10,1}, {6,1,3}, {6,3,2}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{6,10,1}, {6,1,3}, {6,3,2}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,7,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,0,10}, {4,10,7}, {4,7,1}, {4,1,8}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,10,7}, {8,7,5}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,0,10}, {4,10,7}, {4,7,5}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,2,4}, {10,4,1}, {7,2,10}, {1,9,7}, {1,4,9}, + {9,2,7}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{1,8,9}, {2,0,10}, {2,10,7}, {7,1,9}, {7,9,2}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,8,10}, {7,5,9}, {7,9,2}, {2,4,10}, {2,10,7}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,10,7}, {0,7,5}, {0,5,9}, {0,9,2}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,7,3}, {10,3,9}, {10,9,5}, {10,5,1}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,5,1}, {4,0,10}, {4,10,7}, {4,7,3}, {4,3,9}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,10,7}, {8,7,3}, {8,3,9}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,0,10}, {4,10,7}, {4,7,3}, {4,3,9}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,5,1}, {4,1,10}, {7,3,2}, {2,4,10}, {2,10,7}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,5,1}, {0,10,7}, {0,7,3}, {0,3,2}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,8,10}, {4,10,7}, {4,7,3}, {4,3,2}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,10,7}, {0,7,3}, {0,3,2}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,6,7}, {0,7,1}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,4,6}, {8,6,7}, {8,7,1}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,0,6}, {8,6,7}, {8,7,5}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,6,7}, {4,7,5}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{1,0,4}, {1,4,9}, {2,6,7}, {7,1,9}, {7,9,2}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{6,7,1}, {6,1,8}, {6,8,9}, {6,9,2}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,8,0}, {6,7,5}, {6,5,9}, {6,9,2}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{6,7,5}, {6,5,9}, {6,9,2}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{5,1,0}, {6,7,3}, {6,3,9}, {9,5,0}, {9,0,6}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,5,1}, {4,6,7}, {4,7,3}, {4,3,9}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,0,6}, {8,6,7}, {8,7,3}, {8,3,9}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,6,7}, {4,7,3}, {4,3,9}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,4,5}, {0,5,1}, {6,7,3}, {6,3,2}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,5,1}, {6,7,3}, {6,3,2}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,8,0}, {6,7,3}, {6,3,2}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{6,7,3}, {6,3,2}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{6,2,11}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,4,2}, {8,2,11}, {8,11,6}, {8,6,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,1,6}, {6,1,11}, {11,1,5}, {2,11,5}, {2,5,8}, + {6,2,8}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{6,0,1}, {5,4,2}, {5,2,11}, {11,6,1}, {11,1,5}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{6,4,9}, {6,9,11}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{6,0,8}, {6,8,9}, {6,9,11}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{6,4,8}, {6,8,1}, {5,9,11}, {11,6,1}, {11,1,5}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{6,0,1}, {6,1,5}, {6,5,9}, {6,9,11}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{6,2,9}, {6,9,5}, {6,5,3}, {6,3,11}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,2,9}, {6,0,8}, {6,8,5}, {6,5,3}, {6,3,11}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{2,9,8}, {1,3,11}, {1,11,6}, {6,2,8}, {6,8,1}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,2,9}, {6,0,1}, {6,1,3}, {6,3,11}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{6,4,5}, {6,5,3}, {6,3,11}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{6,0,8}, {6,8,5}, {6,5,3}, {6,3,11}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{6,4,8}, {6,8,1}, {6,1,3}, {6,3,11}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{6,0,1}, {6,1,3}, {6,3,11}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,0,2}, {10,2,11}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,8,4}, {10,4,2}, {10,2,11}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,0,2}, {11,10,1}, {11,1,5}, {5,8,2}, {5,2,11}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,1,5}, {10,5,4}, {10,4,2}, {10,2,11}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,0,4}, {10,4,9}, {10,9,11}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,8,9}, {10,9,11}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,8,0}, {10,1,5}, {10,5,9}, {10,9,11}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,1,5}, {10,5,9}, {10,9,11}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,2,9}, {0,9,5}, {3,11,10}, {10,0,5}, {10,5,3}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,2,9}, {10,8,5}, {10,5,3}, {10,3,11}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,0,2}, {8,2,9}, {10,1,3}, {10,3,11}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,2,9}, {10,1,3}, {10,3,11}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,0,4}, {10,4,5}, {10,5,3}, {10,3,11}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,8,5}, {10,5,3}, {10,3,11}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,8,0}, {10,1,3}, {10,3,11}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,1,3}, {10,3,11}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{1,10,6}, {1,6,2}, {1,2,11}, {1,11,7}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,10,6}, {7,1,8}, {7,8,4}, {7,4,2}, {7,2,11}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,10,6}, {8,6,2}, {11,7,5}, {5,8,2}, {5,2,11}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,10,6}, {7,5,4}, {7,4,2}, {7,2,11}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,6,4}, {9,11,7}, {9,7,1}, {1,10,4}, {1,4,9}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,10,6}, {7,1,8}, {7,8,9}, {7,9,11}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,8,10}, {4,10,6}, {7,5,9}, {7,9,11}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,10,6}, {7,5,9}, {7,9,11}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{5,1,10}, {5,10,6}, {5,6,2}, {5,2,9}, {7,3,11}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,10,6}, {8,5,1}, {4,2,9}, {7,3,11}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,10,6}, {8,6,2}, {8,2,9}, {7,3,11}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,10,6}, {4,2,9}, {7,3,11}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,6,4}, {10,4,5}, {10,5,1}, {7,3,11}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,10,6}, {8,5,1}, {7,3,11}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,8,10}, {4,10,6}, {7,3,11}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,10,6}, {7,3,11}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{7,1,0}, {7,0,2}, {7,2,11}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{7,1,8}, {7,8,4}, {7,4,2}, {7,2,11}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{7,5,8}, {7,8,0}, {7,0,2}, {7,2,11}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{7,5,4}, {7,4,2}, {7,2,11}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{7,1,0}, {7,0,4}, {7,4,9}, {7,9,11}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{7,1,8}, {7,8,9}, {7,9,11}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,8,0}, {7,5,9}, {7,9,11}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{7,5,9}, {7,9,11}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{5,1,0}, {5,0,2}, {5,2,9}, {7,3,11}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,5,1}, {4,2,9}, {7,3,11}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,0,2}, {8,2,9}, {7,3,11}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,2,9}, {7,3,11}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,4,5}, {0,5,1}, {7,3,11}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,5,1}, {7,3,11}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,8,0}, {7,3,11}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{7,3,11}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{7,11,3}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{7,11,0}, {7,0,8}, {0,11,4}, {8,3,7}, {11,3,4}, + {3,8,4}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,1,7}, {8,7,11}, {8,11,3}, {8,3,5}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,1,7}, {0,7,11}, {3,5,4}, {4,0,11}, {4,11,3}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,9,3}, {4,3,7}, {4,7,11}, {4,11,2}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,9,3}, {8,3,7}, {11,2,0}, {0,8,7}, {0,7,11}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{5,9,3}, {4,8,1}, {4,1,7}, {4,7,11}, {4,11,2}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{5,9,3}, {0,1,7}, {0,7,11}, {0,11,2}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{5,7,11}, {5,11,9}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,5,7}, {11,9,4}, {11,4,0}, {0,8,7}, {0,7,11}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,1,7}, {8,7,11}, {8,11,9}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,0,1}, {4,1,7}, {4,7,11}, {4,11,9}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,5,7}, {4,7,11}, {4,11,2}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,8,5}, {0,5,7}, {0,7,11}, {0,11,2}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,8,1}, {4,1,7}, {4,7,11}, {4,11,2}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,1,7}, {0,7,11}, {0,11,2}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,6,11}, {0,11,3}, {0,3,7}, {0,7,10}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{7,10,8}, {4,6,11}, {4,11,3}, {3,7,8}, {3,8,4}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,1,7}, {5,8,0}, {5,0,6}, {5,6,11}, {5,11,3}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,1,7}, {5,4,6}, {5,6,11}, {5,11,3}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{7,10,0}, {7,0,4}, {7,4,9}, {7,9,3}, {6,11,2}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{7,10,8}, {7,8,9}, {7,9,3}, {6,11,2}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,8,0}, {10,1,7}, {5,9,3}, {6,11,2}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,1,7}, {5,9,3}, {6,11,2}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{5,7,10}, {5,10,0}, {6,11,9}, {9,5,0}, {9,0,6}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,8,5}, {10,5,7}, {4,6,11}, {4,11,9}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,1,7}, {8,0,6}, {8,6,11}, {8,11,9}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,1,7}, {4,6,11}, {4,11,9}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,0,4}, {10,4,5}, {10,5,7}, {6,11,2}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,8,5}, {10,5,7}, {6,11,2}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,8,0}, {10,1,7}, {6,11,2}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,1,7}, {6,11,2}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{1,10,11}, {1,11,3}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,10,11}, {3,1,8}, {3,8,4}, {4,0,11}, {4,11,3}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{5,8,10}, {5,10,11}, {5,11,3}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{5,4,0}, {5,0,10}, {5,10,11}, {5,11,3}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{9,3,1}, {10,11,2}, {10,2,4}, {4,9,1}, {4,1,10}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{1,8,9}, {1,9,3}, {0,10,11}, {0,11,2}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{5,9,3}, {4,8,10}, {4,10,11}, {4,11,2}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{5,9,3}, {0,10,11}, {0,11,2}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{5,1,10}, {5,10,11}, {5,11,9}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,5,1}, {4,0,10}, {4,10,11}, {4,11,9}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,10,11}, {8,11,9}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,0,10}, {4,10,11}, {4,11,9}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,5,1}, {4,1,10}, {4,10,11}, {4,11,2}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,5,1}, {0,10,11}, {0,11,2}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,8,10}, {4,10,11}, {4,11,2}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,10,11}, {0,11,2}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{1,0,6}, {1,6,11}, {1,11,3}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{1,8,4}, {1,4,6}, {1,6,11}, {1,11,3}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{5,8,0}, {5,0,6}, {5,6,11}, {5,11,3}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{5,4,6}, {5,6,11}, {5,11,3}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{1,0,4}, {1,4,9}, {1,9,3}, {6,11,2}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{1,8,9}, {1,9,3}, {6,11,2}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,8,0}, {5,9,3}, {6,11,2}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{5,9,3}, {6,11,2}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{5,1,0}, {5,0,6}, {5,6,11}, {5,11,9}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,5,1}, {4,6,11}, {4,11,9}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,0,6}, {8,6,11}, {8,11,9}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,6,11}, {4,11,9}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,4,5}, {0,5,1}, {6,11,2}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,5,1}, {6,11,2}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,8,0}, {6,11,2}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{6,11,2}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{7,6,2}, {7,2,3}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{7,6,0}, {7,0,8}, {4,2,3}, {3,7,8}, {3,8,4}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{1,7,6}, {2,3,5}, {2,5,8}, {8,1,6}, {8,6,2}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{6,0,1}, {6,1,7}, {5,4,2}, {5,2,3}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{7,6,4}, {7,4,9}, {7,9,3}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{7,6,0}, {7,0,8}, {7,8,9}, {7,9,3}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{6,4,8}, {6,8,1}, {6,1,7}, {5,9,3}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{6,0,1}, {6,1,7}, {5,9,3}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{5,7,6}, {5,6,2}, {5,2,9}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{6,0,8}, {6,8,5}, {6,5,7}, {4,2,9}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,1,7}, {8,7,6}, {8,6,2}, {8,2,9}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{6,0,1}, {6,1,7}, {4,2,9}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{6,4,5}, {6,5,7}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{6,0,8}, {6,8,5}, {6,5,7}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{6,4,8}, {6,8,1}, {6,1,7}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{6,0,1}, {6,1,7}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{7,10,0}, {7,0,2}, {7,2,3}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{7,10,8}, {7,8,4}, {7,4,2}, {7,2,3}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,1,7}, {5,8,0}, {5,0,2}, {5,2,3}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,1,7}, {5,4,2}, {5,2,3}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{7,10,0}, {7,0,4}, {7,4,9}, {7,9,3}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{7,10,8}, {7,8,9}, {7,9,3}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,8,0}, {10,1,7}, {5,9,3}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,1,7}, {5,9,3}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{5,7,10}, {5,10,0}, {5,0,2}, {5,2,9}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,8,5}, {10,5,7}, {4,2,9}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,1,7}, {8,0,2}, {8,2,9}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,1,7}, {4,2,9}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,0,4}, {10,4,5}, {10,5,7}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,8,5}, {10,5,7}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,8,0}, {10,1,7}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,1,7}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{1,10,6}, {1,6,2}, {1,2,3}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,10,6}, {1,8,4}, {1,4,2}, {1,2,3}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{5,8,10}, {5,10,6}, {5,6,2}, {5,2,3}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,10,6}, {5,4,2}, {5,2,3}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{1,10,6}, {1,6,4}, {1,4,9}, {1,9,3}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,10,6}, {1,8,9}, {1,9,3}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,8,10}, {4,10,6}, {5,9,3}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,10,6}, {5,9,3}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{5,1,10}, {5,10,6}, {5,6,2}, {5,2,9}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,10,6}, {8,5,1}, {4,2,9}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,10,6}, {8,6,2}, {8,2,9}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,10,6}, {4,2,9}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{10,6,4}, {10,4,5}, {10,5,1}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,10,6}, {8,5,1}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,8,10}, {4,10,6}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,10,6}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{1,0,2}, {1,2,3}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{1,8,4}, {1,4,2}, {1,2,3}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{5,8,0}, {5,0,2}, {5,2,3}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{5,4,2}, {5,2,3}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{1,0,4}, {1,4,9}, {1,9,3}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{1,8,9}, {1,9,3}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,8,0}, {5,9,3}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{5,9,3}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{5,1,0}, {5,0,2}, {5,2,9}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,5,1}, {4,2,9}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,0,2}, {8,2,9}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,2,9}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,4,5}, {0,5,1}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{8,5,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{4,8,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}}, + {{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, + {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}} +}; diff -Nru blender-2.61/intern/dualcon/intern/marching_cubes_table.h blender-2.62/intern/dualcon/intern/marching_cubes_table.h --- blender-2.61/intern/dualcon/intern/marching_cubes_table.h 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/intern/dualcon/intern/marching_cubes_table.h 2012-02-15 19:24:40.000000000 +0000 @@ -0,0 +1,38 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + * Contributor(s): Tao Ju + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef MARCHING_CUBES_TABLE_H +#define MARCHING_CUBES_TABLE_H + +/* number of configurations */ +#define TOTCONF 256 + +/* maximum number of triangles per configuration */ +#define MAX_TRIS 10 + +/* number of triangles in each configuration */ +extern const int marching_cubes_numtri[TOTCONF]; + +/* table of triangles in each configuration */ +extern const int marching_cubes_tris[TOTCONF][MAX_TRIS][3]; + +#endif diff -Nru blender-2.61/intern/dualcon/intern/MemoryAllocator.h blender-2.62/intern/dualcon/intern/MemoryAllocator.h --- blender-2.61/intern/dualcon/intern/MemoryAllocator.h 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/intern/dualcon/intern/MemoryAllocator.h 2012-02-15 19:24:40.000000000 +0000 @@ -0,0 +1,219 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + * Contributor(s): Tao Ju + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef MEMORYALLOCATOR_H +#define MEMORYALLOCATOR_H + +#include +#include + +#define HEAP_BASE 16 +#define UCHAR unsigned char + +/** + * Customized memory allocators that allocates/deallocates memory in chunks + * + * @author Tao Ju + */ + + + +/** + * Base class of memory allocators + */ +class VirtualMemoryAllocator +{ +public: + virtual UCHAR * allocate( ) = 0 ; + virtual void deallocate( UCHAR * obj ) = 0 ; + virtual void destroy( ) = 0 ; + virtual void printInfo( ) = 0 ; + + virtual int getAllocated( ) = 0 ; + virtual int getAll( ) = 0 ; + virtual int getBytes( ) = 0 ; +}; + +/** + * Dynamic memory allocator - allows allocation/deallocation + * + * Note: there are 4 bytes overhead for each allocated yet unused object. + */ +template < int N > +class MemoryAllocator : public VirtualMemoryAllocator +{ +private: + + /// Constants + int HEAP_UNIT, HEAP_MASK ; + + /// Data array + UCHAR ** data ; + + /// Allocation stack + UCHAR *** stack ; + + /// Number of data blocks + int datablocknum ; + + /// Number of stack blocks + int stackblocknum ; + + /// Size of stack + int stacksize ; + + /// Number of available objects on stack + int available ; + + /** + * Allocate a memory block + */ + void allocateDataBlock ( ) + { + // Allocate a data block + datablocknum += 1 ; + data = ( UCHAR ** )realloc( data, sizeof ( UCHAR * ) * datablocknum ) ; + data[ datablocknum - 1 ] = ( UCHAR * )malloc( HEAP_UNIT * N ) ; + + // Update allocation stack + for ( int i = 0 ; i < HEAP_UNIT ; i ++ ) + { + stack[ 0 ][ i ] = ( data[ datablocknum - 1 ] + i * N ) ; + } + available = HEAP_UNIT ; + } + + /** + * Allocate a stack block, to store more deallocated objects + */ + void allocateStackBlock( ) + { + // Allocate a stack block + stackblocknum += 1 ; + stacksize += HEAP_UNIT ; + stack = ( UCHAR *** )realloc( stack, sizeof ( UCHAR ** ) * stackblocknum ) ; + stack[ stackblocknum - 1 ] = ( UCHAR ** )malloc( HEAP_UNIT * sizeof ( UCHAR * ) ) ; + } + + +public: + /** + * Constructor + */ + MemoryAllocator( ) + { + HEAP_UNIT = 1 << HEAP_BASE ; + HEAP_MASK = ( 1 << HEAP_BASE ) - 1 ; + + data = ( UCHAR ** )malloc( sizeof( UCHAR * ) ) ; + data[ 0 ] = ( UCHAR * )malloc( HEAP_UNIT * N ) ; + datablocknum = 1 ; + + stack = ( UCHAR *** )malloc( sizeof ( UCHAR ** ) ) ; + stack[ 0 ] = ( UCHAR ** )malloc( HEAP_UNIT * sizeof ( UCHAR * ) ) ; + stackblocknum = 1 ; + stacksize = HEAP_UNIT ; + available = HEAP_UNIT ; + + for ( int i = 0 ; i < HEAP_UNIT ; i ++ ) + { + stack[ 0 ][ i ] = ( data[ 0 ] + i * N ) ; + } + } + + /** + * Destructor + */ + void destroy( ) + { + int i ; + for ( i = 0 ; i < datablocknum ; i ++ ) + { + free( data[ i ] ) ; + } + for ( i = 0 ; i < stackblocknum ; i ++ ) + { + free( stack[ i ] ) ; + } + free( data ) ; + free( stack ) ; + } + + /** + * Allocation method + */ + UCHAR * allocate ( ) + { + if ( available == 0 ) + { + allocateDataBlock ( ) ; + } + + // printf("Allocating %d\n", header[ allocated ]) ; + available -- ; + return stack[ available >> HEAP_BASE ][ available & HEAP_MASK ] ; + } + + /** + * De-allocation method + */ + void deallocate ( UCHAR * obj ) + { + if ( available == stacksize ) + { + allocateStackBlock ( ) ; + } + + // printf("De-allocating %d\n", ( obj - data ) / N ) ; + stack[ available >> HEAP_BASE ][ available & HEAP_MASK ] = obj ; + available ++ ; + // printf("%d %d\n", allocated, header[ allocated ]) ; + } + + /** + * Print information + */ + void printInfo ( ) + { + printf("Bytes: %d Used: %d Allocated: %d Maxfree: %d\n", getBytes(), getAllocated(), getAll(), stacksize ) ; + } + + /** + * Query methods + */ + int getAllocated( ) + { + return HEAP_UNIT * datablocknum - available ; + }; + + int getAll( ) + { + return HEAP_UNIT * datablocknum ; + }; + + int getBytes( ) + { + return N ; + }; +}; + +#endif diff -Nru blender-2.61/intern/dualcon/intern/ModelReader.h blender-2.62/intern/dualcon/intern/ModelReader.h --- blender-2.61/intern/dualcon/intern/ModelReader.h 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/intern/dualcon/intern/ModelReader.h 2012-02-15 19:24:40.000000000 +0000 @@ -0,0 +1,64 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + * Contributor(s): Tao Ju + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef MODELREADER_H +#define MODELREADER_H + +#include "GeoCommon.h" + +/* + * Virtual class for input file readers + * + * @author Tao Ju + */ +class ModelReader +{ +public: + /// Constructor + ModelReader(){} ; + + /// Get next triangle + virtual Triangle* getNextTriangle( ) = 0 ; + virtual int getNextTriangle( int t[3] ) = 0 ; + + /// Get bounding box + virtual float getBoundingBox ( float origin[3] ) = 0 ; + + /// Get number of triangles + virtual int getNumTriangles ( ) = 0 ; + + /// Get storage size + virtual int getMemory ( ) = 0 ; + + /// Reset file reading location + virtual void reset( ) = 0 ; + + /// For explicit vertex models + virtual int getNumVertices( ) = 0 ; + + virtual void getNextVertex( float v[3] ) = 0 ; + + virtual void printInfo ( ) = 0 ; +}; + + +#endif diff -Nru blender-2.61/intern/dualcon/intern/octree.cpp blender-2.62/intern/dualcon/intern/octree.cpp --- blender-2.61/intern/dualcon/intern/octree.cpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/intern/dualcon/intern/octree.cpp 2012-02-15 19:24:40.000000000 +0000 @@ -0,0 +1,4311 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + * Contributor(s): Tao Ju + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "octree.h" +#include +#include +#include + +/** + * Implementations of Octree member functions. + * + * @author Tao Ju + */ + +/* set to non-zero value to enable debugging output */ +#define DC_DEBUG 0 + +#if DC_DEBUG +/* enable debug printfs */ +#define dc_printf printf +#else +/* disable debug printfs */ +#define dc_printf(...) do {} while(0) +#endif + +Octree::Octree( ModelReader* mr, + DualConAllocOutput alloc_output_func, + DualConAddVert add_vert_func, + DualConAddQuad add_quad_func, + DualConFlags flags, DualConMode dualcon_mode, int depth, + float threshold, float sharpness ) + : use_flood_fill(flags & DUALCON_FLOOD_FILL), + /* note on `use_manifold': + + After playing around with this option, the only case I could + find where this option gives different results is on + relatively thin corners. Sometimes along these corners two + vertices from seperate sides will be placed in the same + position, so hole gets filled with a 5-sided face, where two + of those vertices are in the same 3D location. If + `use_manifold' is disabled, then the modifier doesn't + generate two separate vertices so the results end up as all + quads. + + Since the results are just as good with all quads, there + doesn't seem any reason to allow this to be toggled in + Blender. -nicholasbishop + */ + use_manifold(false), + hermite_num(sharpness), + mode(dualcon_mode), + alloc_output(alloc_output_func), + add_vert(add_vert_func), + add_quad(add_quad_func) +{ + this->thresh = threshold ; + this->reader = mr ; + this->dimen = 1 << GRID_DIMENSION ; + this->range = reader->getBoundingBox( this->origin ) ; + this->nodeCount = this->nodeSpace = 0; + this->maxDepth = depth ; + this->mindimen = ( dimen >> maxDepth ) ; + this->minshift = ( GRID_DIMENSION - maxDepth ) ; + this->buildTable( ) ; + + flood_bytes = use_flood_fill ? FLOOD_FILL_BYTES : 0; + leaf_extra_bytes = flood_bytes + CINDY_BYTES; + +#ifdef USE_HERMIT + leaf_node_bytes = 7 + leaf_extra_bytes; +#else + leaf_node_bytes = 3 + leaf_extra_bytes; +#endif + +#ifdef QIANYI + dc_printf("Origin: (%f %f %f), Dimension: %f\n", origin[0], origin[1], origin[2], range) ; +#endif + + this->maxTrianglePerCell = 0 ; + + // Initialize memory +#ifdef IN_VERBOSE_MODE + dc_printf("Range: %f origin: %f, %f,%f \n", range, origin[0], origin[1], origin[2] ) ; + dc_printf("Initialize memory...\n") ; +#endif + initMemory( ) ; + this->root = createInternal( 0 ) ; + + // Read MC table +#ifdef IN_VERBOSE_MODE + dc_printf("Reading contour table...\n") ; +#endif + this->cubes = new Cubes(); + +} + +Octree::~Octree( ) +{ + freeMemory( ) ; +} + +void Octree::scanConvert() +{ + // Scan triangles +#if DC_DEBUG + clock_t start, finish ; + start = clock( ) ; +#endif + + this->addTrian( ) ; + this->resetMinimalEdges( ) ; + this->preparePrimalEdgesMask( this->root ) ; + +#if DC_DEBUG + finish = clock( ) ; + dc_printf("Time taken: %f seconds \n", + (double)(finish - start) / CLOCKS_PER_SEC ) ; +#endif + + // Generate signs + // Find holes +#if DC_DEBUG + dc_printf("Patching...\n") ; + start = clock( ) ; +#endif + this->trace( ) ; +#if DC_DEBUG + finish = clock( ) ; + dc_printf("Time taken: %f seconds \n", (double)(finish - start) / CLOCKS_PER_SEC ) ; +#ifdef IN_VERBOSE_MODE + dc_printf("Holes: %d Average Length: %f Max Length: %d \n", numRings, (float)totRingLengths / (float) numRings, maxRingLength ) ; +#endif +#endif + + // Check again + int tnumRings = numRings ; + this->trace( ) ; +#ifdef IN_VERBOSE_MODE + dc_printf("Holes after patching: %d \n", numRings) ; +#endif + numRings = tnumRings ; + +#if DC_DEBUG + dc_printf("Building signs...\n") ; + start = clock( ) ; +#endif + this->buildSigns( ) ; +#if DC_DEBUG + finish = clock( ) ; + dc_printf("Time taken: %f seconds \n", (double)(finish - start) / CLOCKS_PER_SEC ) ; +#endif + + if(use_flood_fill) { + /* + start = clock( ) ; + this->floodFill( ) ; + // Check again + tnumRings = numRings ; + this->trace( ) ; + dc_printf("Holes after filling: %d \n", numRings) ; + numRings = tnumRings ; + this->buildSigns( ) ; + finish = clock( ) ; + dc_printf("Time taken: %f seconds \n", (double)(finish - start) / CLOCKS_PER_SEC ) ; + */ +#if DC_DEBUG + start = clock( ) ; + dc_printf("Removing components...\n"); +#endif + this->floodFill( ) ; + this->buildSigns( ) ; + // dc_printf("Checking...\n"); + // this->floodFill( ) ; +#if DC_DEBUG + finish = clock( ) ; + dc_printf("Time taken: %f seconds \n", (double)(finish - start) / CLOCKS_PER_SEC ) ; +#endif + } + + // Output +#ifdef OUTPUT_REPAIRED +#if DC_DEBUG + start = clock( ) ; +#endif + writeOut(); +#if DC_DEBUG + finish = clock( ) ; +#endif + // dc_printf("Time taken: %f seconds \n", (double)(finish - start) / CLOCKS_PER_SEC ) ; +#ifdef CINDY + this->writeTags( "tags.txt" ) ; + dc_printf("Tags output to tags.txt\n") ; +#endif + +#endif + + // Print info +#ifdef IN_VERBOSE_MODE + printMemUsage( ) ; +#endif +} + +#if 0 +void Octree::writeOut( char* fname ) +{ + dc_printf( "\n" ) ; + if ( strstr( fname, ".ply" ) != NULL ) + { + dc_printf("Writing PLY file format.\n") ; + this->outType = 1 ; + writePLY( fname ) ; + } + else if ( strstr( fname, ".off" ) != NULL ) + { + dc_printf("Writing OFF file format.\n") ; + this->outType = 0 ; + writeOFF( fname ) ; + } + else if ( strstr( fname, ".sof" ) != NULL ) + { + dc_printf("Writing Signed Octree File format.\n") ; + this->outType = 2 ; + writeOctree( fname ) ; + } + else if ( strstr( fname, ".dcf" ) != NULL ) + { +#ifdef USE_HERMIT + dc_printf("Writing Dual Contouring File format.\n") ; + this->outType = 3 ; + writeDCF( fname ) ; +#else + dc_printf("Can not write Dual Contouring File format in non-DC mode.\n") ; +#endif + } +#ifdef USE_HERMIT + else if ( strstr( fname, ".sog" ) != NULL ) + { + dc_printf("Writing signed octree with geometry.\n") ; + this->outType = 4 ; + writeOctreeGeom( fname ) ; + } +#endif + /* + else if ( strstr( fname, ".sof" ) != NULL ) + { + dc_printf("Writing SOF file format.\n") ; + this->outType = 2 ; + writeOctree( fname ) ; + } + */ + else + { + dc_printf("Unknown output format.\n") ; + } + +} +#endif + +void Octree::initMemory( ) +{ +#ifdef USE_HERMIT + const int leaf_node_bytes = 7; +#else + const int leaf_node_bytes = 3; +#endif + + if(use_flood_fill) { + const int bytes = leaf_node_bytes + CINDY_BYTES + FLOOD_FILL_BYTES; + this->leafalloc[ 0 ] = new MemoryAllocator< bytes > ( ) ; + this->leafalloc[ 1 ] = new MemoryAllocator< bytes + EDGE_BYTES > ( ) ; + this->leafalloc[ 2 ] = new MemoryAllocator< bytes + EDGE_BYTES * 2 > ( ) ; + this->leafalloc[ 3 ] = new MemoryAllocator< bytes + EDGE_BYTES * 3 > ( ) ; + } + else { + const int bytes = leaf_node_bytes + CINDY_BYTES; + this->leafalloc[ 0 ] = new MemoryAllocator< bytes > ( ) ; + this->leafalloc[ 1 ] = new MemoryAllocator< bytes + EDGE_BYTES > ( ) ; + this->leafalloc[ 2 ] = new MemoryAllocator< bytes + EDGE_BYTES * 2 > ( ) ; + this->leafalloc[ 3 ] = new MemoryAllocator< bytes + EDGE_BYTES * 3 > ( ) ; + } + + this->alloc[ 0 ] = new MemoryAllocator< INTERNAL_NODE_BYTES > ( ) ; + this->alloc[ 1 ] = new MemoryAllocator< INTERNAL_NODE_BYTES + POINTER_BYTES > ( ) ; + this->alloc[ 2 ] = new MemoryAllocator< INTERNAL_NODE_BYTES + POINTER_BYTES*2 > ( ) ; + this->alloc[ 3 ] = new MemoryAllocator< INTERNAL_NODE_BYTES + POINTER_BYTES*3 > ( ) ; + this->alloc[ 4 ] = new MemoryAllocator< INTERNAL_NODE_BYTES + POINTER_BYTES*4 > ( ) ; + this->alloc[ 5 ] = new MemoryAllocator< INTERNAL_NODE_BYTES + POINTER_BYTES*5 > ( ) ; + this->alloc[ 6 ] = new MemoryAllocator< INTERNAL_NODE_BYTES + POINTER_BYTES*6 > ( ) ; + this->alloc[ 7 ] = new MemoryAllocator< INTERNAL_NODE_BYTES + POINTER_BYTES*7 > ( ) ; + this->alloc[ 8 ] = new MemoryAllocator< INTERNAL_NODE_BYTES + POINTER_BYTES*8 > ( ) ; +} + +void Octree::freeMemory( ) +{ + for ( int i = 0 ; i < 9 ; i ++ ) + { + alloc[i]->destroy() ; + delete alloc[i] ; + } + + for ( int i = 0 ; i < 4 ; i ++ ) + { + leafalloc[i]->destroy() ; + delete leafalloc[i] ; + } +} + +void Octree::printMemUsage( ) +{ + int totalbytes = 0 ; + dc_printf("********* Internal nodes: \n") ; + for ( int i = 0 ; i < 9 ; i ++ ) + { + this->alloc[ i ]->printInfo() ; + + totalbytes += alloc[i]->getAll( ) * alloc[i]->getBytes() ; + } + dc_printf("********* Leaf nodes: \n") ; + int totalLeafs = 0 ; + for ( int i = 0 ; i < 4 ; i ++ ) + { + this->leafalloc[ i ]->printInfo() ; + + totalbytes += leafalloc[i]->getAll( ) * leafalloc[i]->getBytes() ; + totalLeafs += leafalloc[i]->getAllocated() ; + } + + dc_printf("Total allocated bytes on disk: %d \n", totalbytes) ; + dc_printf("Total leaf nodes: %d\n", totalLeafs ) ; +} + +void Octree::resetMinimalEdges( ) +{ + this->cellProcParity( this->root, 0, maxDepth ) ; +} + +void Octree::writeModel( char* fname ) +{ + reader->reset() ; + + int nFace = reader->getNumTriangles() ; + Triangle* trian ; + // int unitcount = 10000; + int count = 0 ; + int nVert = nFace * 3 ; + FILE* modelfout = fopen( "model.off", "w" ) ; + fprintf( modelfout, "OFF\n" ) ; + fprintf( modelfout, "%d %d 0\n", nVert, nFace ) ; + + //int total = this->reader->getNumTriangles() ; + dc_printf( "Start writing model to OFF...\n" ) ; + srand(0) ; + while ( ( trian = reader->getNextTriangle() ) != NULL ) + { + // Drop polygons + { + int i, j ; + + // Blow up the triangle + float mid[3] = {0, 0, 0} ; + for ( i = 0 ; i < 3 ; i ++ ) + for ( j = 0 ; j < 3 ; j ++ ) + { + trian->vt[i][j] = dimen * ( trian->vt[i][j] - origin[j] ) / range ; + + mid[j] += trian->vt[i][j] / 3 ; + } + + // Generate projections + // LONG cube[2][3] = { { 0, 0, 0 }, { dimen, dimen, dimen } } ; + int trig[3][3] ; + + // Blowing up the triangle to the grid + for ( i = 0 ; i < 3 ; i ++ ) + for ( j = 0 ; j < 3 ; j ++ ) + { + trig[i][j] = (int) (trian->vt[i][j]) ; + // Perturb end points, if set so + } + + + for ( i = 0 ; i < 3 ; i ++ ) + { + fprintf( modelfout, "%f %f %f\n", + (float)(((double) trig[i][0] / dimen) * range + origin[0]) , + (float)(((double) trig[i][1] / dimen) * range + origin[1]) , + (float)(((double) trig[i][2] / dimen) * range + origin[2]) ) ; + } + } + delete trian ; + + count ++ ; + + } + + for ( int i = 0 ; i < nFace ; i ++ ) + { + fprintf( modelfout, "3 %d %d %d\n", 3 * i + 2, 3 * i + 1, 3 * i ) ; + } + + fclose( modelfout ) ; + +} + +#ifdef CINDY +void Octree::writeTags( char* fname ) +{ + FILE* fout = fopen( fname, "w" ) ; + + clearCindyBits( root, maxDepth ) ; + readVertices() ; + outputTags( root, maxDepth, fout ) ; + + fclose ( fout ) ; +} + +void Octree::readVertices( ) +{ + int total = this->reader->getNumVertices() ; + reader->reset() ; + float v[3] ; + int st[3] = {0,0,0}; + int unitcount = 1000 ; + dc_printf( "\nRead in original %d vertices...\n", total ) ; + + for ( int i = 0 ; i < total ; i ++ ) + { + reader->getNextVertex( v ) ; + // Blowing up the triangle to the grid + float mid[3] = {0, 0, 0} ; + for ( int j = 0 ; j < 3 ; j ++ ) + { + v[j] = dimen * ( v[j] - origin[j] ) / range ; + } + +// dc_printf("vertex: %f %f %f, dimen: %d\n", v[0], v[1], v[2], dimen ) ; + readVertex ( root, st, dimen, maxDepth, v, i ) ; + + + if ( i % unitcount == 0 ) + { + putchar ( 13 ) ; + + switch ( ( i / unitcount ) % 4 ) + { + case 0 : dc_printf("-"); + break ; + case 1 : dc_printf("/") ; + break ; + case 2 : dc_printf("|"); + break ; + case 3 : dc_printf("\\") ; + break ; + } + + float percent = (float) i / total ; + /* + int totbars = 50 ; + int bars = (int)( percent * totbars ) ; + for ( int i = 0 ; i < bars ; i ++ ) + { + putchar( 219 ) ; + } + for ( i = bars ; i < totbars ; i ++ ) + { + putchar( 176 ) ; + } + */ + + dc_printf(" %d vertices: ", i ) ; + dc_printf( " %f%% complete.", 100 * percent ) ; + } + + } + putchar ( 13 ) ; + dc_printf(" \n"); +} + +void Octree::readVertex( UCHAR* node, int st[3], int len, int height, float v[3], int index ) +{ + int nst[3] ; + nst[0] = ( (int) v[0] / mindimen ) * mindimen ; + nst[1] = ( (int) v[1] / mindimen ) * mindimen ; + nst[2] = ( (int) v[2] / mindimen ) * mindimen ; + + UCHAR* cell = this->locateLeafCheck( nst ) ; + if ( cell == NULL ) + { + dc_printf("Cell %d %d %d is not found!\n", nst[0]/ mindimen, nst[1]/ mindimen, nst[2]/ mindimen) ; + return ; + } + + setOriginalIndex( cell, index ) ; + + + /* + int i ; + if ( height == 0 ) + { + // Leaf cell, assign index + dc_printf("Setting: %d\n", index ) ; + setOriginalIndex( node, index ) ; + } + else + { + len >>= 1 ; + // Internal cell, check and recur + int x = ( v[0] > st[0] + len ) ? 1 : 0 ; + int y = ( v[1] > st[1] + len ) ? 1 : 0 ; + int z = ( v[2] > st[2] + len ) ? 1 : 0 ; + int child = x * 4 + y * 2 + z ; + + int count = 0 ; + for ( i = 0 ; i < 8 ; i ++ ) + { + if ( i == child && hasChild( node, i ) ) + { + int nst[3] ; + nst[0] = st[0] + vertmap[i][0] * len ; + nst[1] = st[1] + vertmap[i][1] * len ; + nst[2] = st[2] + vertmap[i][2] * len ; + + dc_printf("Depth: %d -- child %d vertex: %f %f %f in %f %f %f\n", height - 1, child, v[0]/mindimen, v[1]/mindimen, v[2]/mindimen, + nst[0]/mindimen, nst[1]/mindimen, nst[2]/mindimen, len/mindimen ) ; + + readVertex( getChild( node, count ), nst, len, height - 1, v, index ) ; + count ++ ; + } + } + } + */ +} + +void Octree::outputTags( UCHAR* node, int height, FILE* fout ) +{ + int i ; + + if ( height == 0 ) + { + // Leaf cell, generate + int smask = getSignMask( node ) ; + + if(use_manifold) { + int comps = manifold_table[ smask ].comps ; + if ( comps != 1 ) + { + return ; + } + } + else + { + if ( smask == 0 || smask == 255 ) + { + return ; + } + } + + int rindex = getMinimizerIndex( node ) ; + int oindex = getOriginalIndex( node ) ; + + if ( oindex >= 0 ) + { + fprintf( fout, "%d: %d\n", rindex, oindex ) ; + } + + } + else + { + // Internal cell, recur + int count = 0 ; + for ( i = 0 ; i < 8 ; i ++ ) + { + if ( hasChild( node, i ) ) + { + outputTags( getChild( node, count ), height - 1, fout ) ; + count ++ ; + } + } + } +} + +void Octree::clearCindyBits( UCHAR* node, int height ) +{ + int i; + + if ( height == 0 ) + { + // Leaf cell, + { + setOriginalIndex( node, - 1 ) ; + } + } + else + { + // Internal cell, recur + int count = 0 ; + for ( i = 0 ; i < 8 ; i ++ ) + { + if ( hasChild( node, i ) ) + { + clearCindyBits( getChild( node, count ), height - 1 ) ; + count ++ ; + } + } + } +} +#endif + +void Octree::addTrian( ) +{ + Triangle* trian ; + int count = 0 ; + +#if DC_DEBUG + int total = this->reader->getNumTriangles() ; + int unitcount = 1000 ; + dc_printf( "\nScan converting to depth %d...\n", maxDepth ) ; +#endif + + srand(0) ; + + while ( ( trian = reader->getNextTriangle() ) != NULL ) + { + // Drop triangles + { + addTrian ( trian, count ) ; + } + delete trian ; + + count ++ ; + +#if DC_DEBUG + if ( count % unitcount == 0 ) + { + putchar ( 13 ) ; + + switch ( ( count / unitcount ) % 4 ) + { + case 0 : dc_printf("-"); + break ; + case 1 : dc_printf("/") ; + break ; + case 2 : dc_printf("|"); + break ; + case 3 : dc_printf("\\") ; + break ; + } + + float percent = (float) count / total ; + + /* + int totbars = 50 ; + int bars = (int)( percent * totbars ) ; + for ( int i = 0 ; i < bars ; i ++ ) + { + putchar( 219 ) ; + } + for ( i = bars ; i < totbars ; i ++ ) + { + putchar( 176 ) ; + } + */ + + dc_printf(" %d triangles: ", count ) ; + dc_printf( " %f%% complete.", 100 * percent ) ; + } +#endif + + } + putchar ( 13 ) ; +} + +void Octree::addTrian( Triangle* trian, int triind ) +{ + int i, j ; + + // Blowing up the triangle to the grid + float mid[3] = {0, 0, 0} ; + for ( i = 0 ; i < 3 ; i ++ ) + for ( j = 0 ; j < 3 ; j ++ ) + { + trian->vt[i][j] = dimen * ( trian->vt[i][j] - origin[j] ) / range ; + mid[j] += trian->vt[i][j] / 3 ; + } + + // Generate projections + LONG cube[2][3] = { { 0, 0, 0 }, { dimen, dimen, dimen } } ; + LONG trig[3][3] ; + + for ( i = 0 ; i < 3 ; i ++ ) + for ( j = 0 ; j < 3 ; j ++ ) + { + trig[i][j] = (LONG) (trian->vt[i][j]) ; + // Perturb end points, if set so + } + + // Add to the octree + // int start[3] = { 0, 0, 0 } ; + LONG errorvec = (LONG) ( 0 ) ; + Projections* proj = new Projections( cube, trig, errorvec, triind ) ; + root = addTrian( root, proj, maxDepth ) ; + + delete proj->inherit ; + delete proj ; +} + + +UCHAR* Octree::addTrian( UCHAR* node, Projections* p, int height ) +{ + int i ; + int vertdiff[8][3] = {{0,0,0},{0,0,1},{0,1,-1},{0,0,1},{1,-1,-1},{0,0,1},{0,1,-1},{0,0,1}} ; + UCHAR boxmask = p->getBoxMask( ) ; + Projections* subp = new Projections( p ) ; + + int count = 0 ; + int tempdiff[3] = {0,0,0} ; + for ( i = 0 ; i < 8 ; i ++ ) + { + tempdiff[0] += vertdiff[i][0] ; + tempdiff[1] += vertdiff[i][1] ; + tempdiff[2] += vertdiff[i][2] ; + + /* Quick pruning using bounding box */ + if ( boxmask & ( 1 << i ) ) + { + subp->shift( tempdiff ) ; + tempdiff[0] = tempdiff[1] = tempdiff[2] = 0 ; + + /* Pruning using intersection test */ + if ( subp->isIntersecting() ) + // if ( subp->getIntersectionMasks( cedgemask, edgemask ) ) + { + if ( ! hasChild( node, i ) ) + { + if ( height == 1 ) + { + node = addLeafChild( node, i, count, createLeaf(0) ) ; + } + else + { + node = addInternalChild( node, i, count, createInternal(0) ) ; + } + } + UCHAR* chd = getChild( node, count ) ; + + if ( ! isLeaf( node, i ) ) + { + // setChild( node, count, addTrian ( chd, subp, height - 1, vertmask[i], edgemask ) ) ; + setChild( node, count, addTrian ( chd, subp, height - 1 ) ) ; + } + else + { + setChild( node, count, updateCell( chd, subp ) ) ; + } + } + } + + if ( hasChild( node, i ) ) + { + count ++ ; + } + } + + delete subp ; + return node ; +} + +UCHAR* Octree::updateCell( UCHAR* node, Projections* p ) +{ + int i ; + + // Edge connectivity + int mask[3] = { 0, 4, 8 } ; + int oldc = 0, newc = 0 ; + float offs[3] ; +#ifdef USE_HERMIT + float a[3], b[3], c[3] ; +#endif + + for ( i = 0 ; i < 3 ; i ++ ) + { + if ( ! getEdgeParity( node, mask[i] ) ) + { + if ( p->isIntersectingPrimary( i ) ) + { + // this->actualQuads ++ ; + setEdge( node, mask[i] ) ; + offs[ newc ] = p->getIntersectionPrimary( i ) ; +#ifdef USE_HERMIT + a[ newc ] = (float) p->inherit->norm[0] ; + b[ newc ] = (float) p->inherit->norm[1] ; + c[ newc ] = (float) p->inherit->norm[2] ; +#endif + newc ++ ; + } + } + else + { +#ifndef USE_HERMIT + offs[ newc ] = getEdgeOffset( node, oldc ) ; +#else + offs[ newc ] = getEdgeOffsetNormal( node, oldc, a[ newc ], b[ newc ], c[ newc ] ) ; +#endif + +// if ( p->isIntersectingPrimary( i ) ) + { + // dc_printf("Multiple intersections!\n") ; + +// setPatchEdge( node, i ) ; + } + + oldc ++ ; + newc ++ ; + } + } + + if ( newc > oldc ) + { + // New offsets added, update this node +#ifndef USE_HERMIT + node = updateEdgeOffsets( node, oldc, newc, offs ) ; +#else + node = updateEdgeOffsetsNormals( node, oldc, newc, offs, a, b, c ) ; +#endif + } + + + + return node ; +} + +void Octree::preparePrimalEdgesMask( UCHAR* node ) +{ + int count = 0 ; + for ( int i = 0 ; i < 8 ; i ++ ) + { + if ( hasChild( node, i ) ) + { + if ( isLeaf( node, i ) ) + { + createPrimalEdgesMask( getChild( node, count ) ) ; + } + else + { + preparePrimalEdgesMask( getChild( node, count ) ) ; + } + + count ++ ; + } + } +} + +void Octree::trace( ) +{ + int st[3] = { 0, 0, 0, } ; + this->numRings = 0 ; + this->totRingLengths = 0 ; + this->maxRingLength = 0 ; + + PathList* chdpath = NULL ; + this->root = trace( this->root, st, dimen, maxDepth, chdpath ) ; + + if ( chdpath != NULL ) + { + dc_printf("there are incomplete rings.\n") ; + printPaths( chdpath ) ; + }; +} + +UCHAR* Octree::trace( UCHAR* node, int* st, int len, int depth, PathList*& paths) +{ + UCHAR* newnode = node ; + len >>= 1 ; + PathList* chdpaths[ 8 ] ; + UCHAR* chd[ 8 ] ; + int nst[ 8 ][ 3 ] ; + int i, j ; + + // Get children paths + int chdleaf[ 8 ] ; + fillChildren( newnode, chd, chdleaf ) ; + + // int count = 0 ; + for ( i = 0 ; i < 8 ; i ++ ) + { + for ( j = 0 ; j < 3 ; j ++ ) + { + nst[ i ][ j ] = st[ j ] + len * vertmap[ i ][ j ] ; + } + + if ( chd[ i ] == NULL || isLeaf( node, i ) ) + { + chdpaths[ i ] = NULL ; + } + else + { + trace( chd[ i ], nst[i], len, depth - 1, chdpaths[ i ] ) ; + } + } + + // Get connectors on the faces + PathList* conn[ 12 ] ; + UCHAR* nf[2] ; + int lf[2] ; + int df[2] = { depth - 1, depth - 1 } ; + int* nstf[ 2 ]; + + fillChildren( newnode, chd, chdleaf ) ; + + for ( i = 0 ; i < 12 ; i ++ ) + { + int c[ 2 ] = { cellProcFaceMask[ i ][ 0 ], cellProcFaceMask[ i ][ 1 ] }; + + for ( int j = 0 ; j < 2 ; j ++ ) + { + lf[j] = chdleaf[ c[j] ] ; + nf[j] = chd[ c[j] ] ; + nstf[j] = nst[ c[j] ] ; + } + + conn[ i ] = NULL ; + + findPaths( nf, lf, df, nstf, depth - 1, cellProcFaceMask[ i ][ 2 ], conn[ i ] ) ; + + //if ( conn[i] ) + //{ + // printPath( conn[i] ) ; + //} + } + + // Connect paths + PathList* rings = NULL ; + combinePaths( chdpaths[0], chdpaths[1], conn[8], rings ) ; + combinePaths( chdpaths[2], chdpaths[3], conn[9], rings ) ; + combinePaths( chdpaths[4], chdpaths[5], conn[10], rings ) ; + combinePaths( chdpaths[6], chdpaths[7], conn[11], rings ) ; + + combinePaths( chdpaths[0], chdpaths[2], conn[4], rings ) ; + combinePaths( chdpaths[4], chdpaths[6], conn[5], rings ) ; + combinePaths( chdpaths[0], NULL, conn[6], rings ) ; + combinePaths( chdpaths[4], NULL, conn[7], rings ) ; + + combinePaths( chdpaths[0], chdpaths[4], conn[0], rings ) ; + combinePaths( chdpaths[0], NULL, conn[1], rings ) ; + combinePaths( chdpaths[0], NULL, conn[2], rings ) ; + combinePaths( chdpaths[0], NULL, conn[3], rings ) ; + + // By now, only chdpaths[0] and rings have contents + + // Process rings + if ( rings ) + { + // printPath( rings ) ; + + /* Let's count first */ + PathList* trings = rings ; + while ( trings ) + { + this->numRings ++ ; + this->totRingLengths += trings->length ; + if ( trings->length > this->maxRingLength ) + { + this->maxRingLength = trings->length ; + } + trings = trings->next ; + } + + // printPath( rings ) ; + newnode = patch( newnode, st, ( len << 1 ), rings ) ; + } + + // Return incomplete paths + paths = chdpaths[0] ; + return newnode ; +} + +void Octree::findPaths( UCHAR* node[2], int leaf[2], int depth[2], int* st[2], int maxdep, int dir, PathList*& paths ) +{ + if ( ! ( node[0] && node[1] ) ) + { + return ; + } + + if ( ! ( leaf[0] && leaf[1] ) ) + { + // Not at the bottom, recur + + // Fill children nodes + int i, j ; + UCHAR* chd[ 2 ][ 8 ] ; + int chdleaf[ 2 ][ 8 ] ; + int nst[ 2 ][ 8 ][ 3 ] ; + + for ( j = 0 ; j < 2 ; j ++ ) + { + if ( ! leaf[j] ) + { + fillChildren( node[j], chd[j], chdleaf[j] ) ; + + int len = ( dimen >> ( maxDepth - depth[j] + 1 ) ) ; + for ( i = 0 ; i < 8 ; i ++ ) + { + for ( int k = 0 ; k < 3 ; k ++ ) + { + nst[ j ][ i ][ k ] = st[ j ][ k ] + len * vertmap[ i ][ k ] ; + } + } + + } + } + + // 4 face calls + UCHAR* nf[2] ; + int df[2] ; + int lf[2] ; + int* nstf[2] ; + for ( i = 0 ; i < 4 ; i ++ ) + { + int c[2] = { faceProcFaceMask[ dir ][ i ][ 0 ], faceProcFaceMask[ dir ][ i ][ 1 ] }; + for ( int j = 0 ; j < 2 ; j ++ ) + { + if ( leaf[j] ) + { + lf[j] = leaf[j] ; + nf[j] = node[j] ; + df[j] = depth[j] ; + nstf[j] = st[j] ; + } + else + { + lf[j] = chdleaf[ j ][ c[j] ] ; + nf[j] = chd[ j ][ c[j] ] ; + df[j] = depth[j] - 1 ; + nstf[j] = nst[ j ][ c[j] ] ; + } + } + findPaths( nf, lf, df, nstf, maxdep - 1, faceProcFaceMask[ dir ][ i ][ 2 ], paths ) ; + } + + } + else + { + // At the bottom, check this face + int ind = ( depth[0] == maxdep ? 0 : 1 ) ; + int fcind = 2 * dir + ( 1 - ind ) ; + if ( getFaceParity( node[ ind ], fcind ) ) + { + // Add into path + PathElement* ele1 = new PathElement ; + PathElement* ele2 = new PathElement ; + + ele1->pos[0] = st[0][0] ; + ele1->pos[1] = st[0][1] ; + ele1->pos[2] = st[0][2] ; + + ele2->pos[0] = st[1][0] ; + ele2->pos[1] = st[1][1] ; + ele2->pos[2] = st[1][2] ; + + ele1->next = ele2 ; + ele2->next = NULL ; + + PathList* lst = new PathList ; + lst->head = ele1 ; + lst->tail = ele2 ; + lst->length = 2 ; + lst->next = paths ; + paths = lst ; + + // int l = ( dimen >> maxDepth ) ; + } + } + +} + +void Octree::combinePaths( PathList*& list1, PathList* list2, PathList* paths, PathList*& rings ) +{ + // Make new list of paths + PathList* nlist = NULL ; + + // Search for each connectors in paths + PathList* tpaths = paths ; + PathList* tlist, * pre ; + while ( tpaths ) + { + PathList* singlist = tpaths ; + PathList* templist ; + tpaths = tpaths->next ; + singlist->next = NULL ; + + // Look for hookup in list1 + tlist = list1 ; + pre = NULL ; + while ( tlist ) + { + if ( (templist = combineSinglePath( list1, pre, tlist, singlist, NULL, singlist )) != NULL ) + { + singlist = templist ; + continue ; + } + pre = tlist ; + tlist = tlist->next ; + } + + // Look for hookup in list2 + tlist = list2 ; + pre = NULL ; + while ( tlist ) + { + if ( (templist = combineSinglePath( list2, pre, tlist, singlist, NULL, singlist )) != NULL ) + { + singlist = templist ; + continue ; + } + pre = tlist ; + tlist = tlist->next ; + } + + // Look for hookup in nlist + tlist = nlist ; + pre = NULL ; + while ( tlist ) + { + if ( (templist = combineSinglePath( nlist, pre, tlist, singlist, NULL, singlist )) != NULL ) + { + singlist = templist ; + continue ; + } + pre = tlist ; + tlist = tlist->next ; + } + + // Add to nlist or rings + if ( isEqual( singlist->head, singlist->tail ) ) + { + PathElement* temp = singlist->head ; + singlist->head = temp->next ; + delete temp ; + singlist->length -- ; + singlist->tail->next = singlist->head ; + + singlist->next = rings ; + rings = singlist ; + } + else + { + singlist->next = nlist ; + nlist = singlist ; + } + + } + + // Append list2 and nlist to the end of list1 + tlist = list1 ; + if ( tlist != NULL ) + { + while ( tlist->next != NULL ) + { + tlist = tlist->next ; + } + tlist->next = list2 ; + } + else + { + tlist = list2 ; + list1 = list2 ; + } + + if ( tlist != NULL ) + { + while ( tlist->next != NULL ) + { + tlist = tlist->next ; + } + tlist->next = nlist ; + } + else + { + tlist = nlist ; + list1 = nlist ; + } + +} + +PathList* Octree::combineSinglePath( PathList*& head1, PathList* pre1, PathList*& list1, PathList*& head2, PathList* pre2, PathList*& list2 ) +{ + if ( isEqual( list1->head, list2->head ) || isEqual( list1->tail, list2->tail ) ) + { + // Reverse the list + if ( list1->length < list2->length ) + { + // Reverse list1 + PathElement* prev = list1->head ; + PathElement* next = prev->next ; + prev->next = NULL ; + while ( next != NULL ) + { + PathElement* tnext = next->next ; + next->next = prev ; + + prev = next ; + next = tnext ; + } + + list1->tail = list1->head ; + list1->head = prev ; + } + else + { + // Reverse list2 + PathElement* prev = list2->head ; + PathElement* next = prev->next ; + prev->next = NULL ; + while ( next != NULL ) + { + PathElement* tnext = next->next ; + next->next = prev ; + + prev = next ; + next = tnext ; + } + + list2->tail = list2->head ; + list2->head = prev ; + } + } + + if ( isEqual( list1->head, list2->tail ) ) + { + + // Easy case + PathElement* temp = list1->head->next ; + delete list1->head ; + list2->tail->next = temp ; + + PathList* nlist = new PathList ; + nlist->length = list1->length + list2->length - 1 ; + nlist->head = list2->head ; + nlist->tail = list1->tail ; + nlist->next = NULL ; + + deletePath( head1, pre1, list1 ) ; + deletePath( head2, pre2, list2 ) ; + + return nlist ; + } + else if ( isEqual( list1->tail, list2->head ) ) + { + // Easy case + PathElement* temp = list2->head->next ; + delete list2->head ; + list1->tail->next = temp ; + + PathList* nlist = new PathList ; + nlist->length = list1->length + list2->length - 1 ; + nlist->head = list1->head ; + nlist->tail = list2->tail ; + nlist->next = NULL ; + + deletePath( head1, pre1, list1 ) ; + deletePath( head2, pre2, list2 ) ; + + return nlist ; + } + + return NULL ; +} + +void Octree::deletePath( PathList*& head, PathList* pre, PathList*& curr ) +{ + PathList* temp = curr ; + curr = temp->next ; + delete temp ; + + if ( pre == NULL ) + { + head = curr ; + } + else + { + pre->next = curr ; + } +} + +void Octree::printElement( PathElement* ele ) +{ + if ( ele != NULL ) + { + dc_printf( " (%d %d %d)", ele->pos[0], ele->pos[1], ele->pos[2] ) ; + } +} + +void Octree::printPath( PathList* path ) +{ + PathElement* n = path->head; + int same = 0 ; + +#if DC_DEBUG + int len = ( dimen >> maxDepth ) ; +#endif + while ( n && ( same == 0 || n != path->head ) ) + { + same ++ ; + dc_printf( " (%d %d %d)", n->pos[0] / len, n->pos[1] / len, n->pos[2] / len ) ; + n = n->next ; + } + + if ( n == path->head ) + { + dc_printf(" Ring!\n") ; + } + else + { + dc_printf(" %p end!\n", n) ; + } +} + +void Octree::printPath( PathElement* path ) +{ + PathElement *n = path; + int same = 0 ; +#if DC_DEBUG + int len = ( dimen >> maxDepth ) ; +#endif + while ( n && ( same == 0 || n != path ) ) + { + same ++ ; + dc_printf( " (%d %d %d)", n->pos[0] / len, n->pos[1] / len, n->pos[2] / len ) ; + n = n->next ; + } + + if ( n == path ) + { + dc_printf(" Ring!\n") ; + } + else + { + dc_printf(" %p end!\n", n) ; + } + +} + + +void Octree::printPaths( PathList* path ) +{ + PathList* iter = path ; + int i = 0 ; + while ( iter != NULL ) + { + dc_printf("Path %d:\n", i) ; + printPath( iter ) ; + iter = iter->next ; + i ++ ; + } +} + +UCHAR* Octree::patch( UCHAR* node, int st[3], int len, PathList* rings ) +{ +#ifdef IN_DEBUG_MODE + dc_printf("Call to PATCH with rings: \n"); + printPaths( rings ) ; +#endif + + /* Do nothing but couting + PathList* tlist = rings ; + PathList* ttlist ; + PathElement* telem, * ttelem ; + while ( tlist!= NULL ) + { + // printPath( tlist ) ; + this->numRings ++ ; + this->totRingLengths += tlist->length ; + if ( tlist->length > this->maxRingLength ) + { + this->maxRingLength = tlist->length ; + } + ttlist = tlist ; + tlist = tlist->next ; + } + return node ; + */ + + + /* Pass onto separate calls in each direction */ + UCHAR* newnode = node ; + if ( len == mindimen ) + { + dc_printf("Error! should have no list by now.\n") ; + exit(0) ; + } + + // YZ plane + PathList* xlists[2] ; + newnode = patchSplit( newnode, st, len, rings, 0, xlists[0], xlists[1] ) ; + + // XZ plane + PathList* ylists[4] ; + newnode = patchSplit( newnode, st, len, xlists[0], 1, ylists[0], ylists[1] ) ; + newnode = patchSplit( newnode, st, len, xlists[1], 1, ylists[2], ylists[3] ) ; + + // XY plane + PathList* zlists[8] ; + newnode = patchSplit( newnode, st, len, ylists[0], 2, zlists[0], zlists[1] ) ; + newnode = patchSplit( newnode, st, len, ylists[1], 2, zlists[2], zlists[3] ) ; + newnode = patchSplit( newnode, st, len, ylists[2], 2, zlists[4], zlists[5] ) ; + newnode = patchSplit( newnode, st, len, ylists[3], 2, zlists[6], zlists[7] ) ; + + // Recur + len >>= 1 ; + int count = 0 ; + for ( int i = 0 ; i < 8 ; i ++ ) + { + if ( zlists[i] != NULL ) + { + int nori[3] = { + st[0] + len * vertmap[i][0] , + st[1] + len * vertmap[i][1] , + st[2] + len * vertmap[i][2] } ; + patch( getChild( newnode , count ), nori, len, zlists[i] ) ; + } + + if ( hasChild( newnode, i ) ) + { + count ++ ; + } + } +#ifdef IN_DEBUG_MODE + dc_printf("Return from PATCH\n") ; +#endif + return newnode ; + +} + + +UCHAR* Octree::patchSplit( UCHAR* node, int st[3], int len, PathList* rings, int dir, PathList*& nrings1, PathList*& nrings2 ) +{ +#ifdef IN_DEBUG_MODE + dc_printf("Call to PATCHSPLIT with direction %d and rings: \n", dir); + printPaths( rings ) ; +#endif + + UCHAR* newnode = node ; + nrings1 = NULL ; + nrings2 = NULL ; + PathList* tmp ; + while ( rings != NULL ) + { + // Process this ring + newnode = patchSplitSingle( newnode, st, len, rings->head, dir, nrings1, nrings2 ) ; + + // Delete this ring from the group + tmp = rings ; + rings = rings->next ; + delete tmp ; + } + +#ifdef IN_DEBUG_MODE + dc_printf("Return from PATCHSPLIT with \n"); + dc_printf("Rings gourp 1:\n") ; + printPaths( nrings1 ) ; + dc_printf("Rings group 2:\n") ; + printPaths( nrings2 ) ; +#endif + + return newnode ; +} + +UCHAR* Octree::patchSplitSingle( UCHAR* node, int st[3], int len, PathElement* head, int dir, PathList*& nrings1, PathList*& nrings2 ) +{ +#ifdef IN_DEBUG_MODE + dc_printf("Call to PATCHSPLITSINGLE with direction %d and path: \n", dir ); + printPath( head ) ; +#endif + + UCHAR* newnode = node ; + + if ( head == NULL ) + { +#ifdef IN_DEBUG_MODE + dc_printf("Return from PATCHSPLITSINGLE with head==NULL.\n") ; +#endif + return newnode; + } + else + { + // printPath( head ) ; + } + + // Walk along the ring to find pair of intersections + PathElement* pre1 = NULL ; + PathElement* pre2 = NULL ; + int side = findPair ( head, st[ dir ] + len / 2 , dir, pre1, pre2 ) ; + + /* + if ( pre1 == pre2 ) + { + int edgelen = ( dimen >> maxDepth ) ; + dc_printf("Location: %d %d %d Direction: %d Reso: %d\n", st[0]/edgelen, st[1]/edgelen, st[2]/edgelen, dir, len/edgelen) ; + printPath( head ) ; + exit( 0 ) ; + } + */ + + if ( side ) + { + // Entirely on one side + PathList* nring = new PathList( ) ; + nring->head = head ; + + if ( side == -1 ) + { + nring->next = nrings1 ; + nrings1 = nring ; + } + else + { + nring->next = nrings2 ; + nrings2 = nring ; + } + } + else + { + // Break into two parts + PathElement* nxt1 = pre1->next ; + PathElement* nxt2 = pre2->next ; + pre1->next = nxt2 ; + pre2->next = nxt1 ; + + newnode = connectFace( newnode, st, len, dir, pre1, pre2 ) ; + + if ( isEqual( pre1, pre1->next ) ) + { + if ( pre1 == pre1->next ) + { + delete pre1 ; + pre1 = NULL ; + } + else + { + PathElement* temp = pre1->next ; + pre1->next = temp->next ; + delete temp ; + } + } + if ( isEqual( pre2, pre2->next ) ) + { + if ( pre2 == pre2->next ) + { + delete pre2 ; + pre2 = NULL ; + } + else + { + PathElement* temp = pre2->next ; + pre2->next = temp->next ; + delete temp ; + } + } + + compressRing ( pre1 ) ; + compressRing ( pre2 ) ; + + // Recur + newnode = patchSplitSingle( newnode, st, len, pre1, dir, nrings1, nrings2 ) ; + newnode = patchSplitSingle( newnode, st, len, pre2, dir, nrings1, nrings2 ) ; + + } + +#ifdef IN_DEBUG_MODE + dc_printf("Return from PATCHSPLITSINGLE with \n"); + dc_printf("Rings gourp 1:\n") ; + printPaths( nrings1 ) ; + dc_printf("Rings group 2:\n") ; + printPaths( nrings2 ) ; +#endif + + return newnode ; +} + +UCHAR* Octree::connectFace( UCHAR* node, int st[3], int len, int dir, PathElement* f1, PathElement* f2 ) +{ +#ifdef IN_DEBUG_MODE + dc_printf("Call to CONNECTFACE with direction %d and length %d path: \n", dir, len ); + dc_printf("Path (low side): \n" ) ; + printPath( f1 ) ; +// checkPath( f1 ) ; + dc_printf("Path (high side): \n" ) ; + printPath( f2 ) ; +// checkPath( f2 ) ; +#endif + + UCHAR* newnode = node ; + + // Setup 2D + int pos = st[ dir ] + len / 2 ; + int xdir = ( dir + 1 ) % 3 ; + int ydir = ( dir + 2 ) % 3 ; + + // Use existing intersections on f1 and f2 + int x1, y1, x2, y2 ; + float p1, q1, p2, q2 ; + + getFacePoint( f2->next, dir, x1, y1, p1, q1 ) ; + getFacePoint( f2, dir, x2, y2, p2, q2 ) ; + + float dx = x2 + p2 - x1 - p1 ; + float dy = y2 + q2 - y1 - q1 ; + + // Do adapted Bresenham line drawing + float rx = p1, ry = q1 ; + int incx = 1, incy = 1 ; + int lx = x1, ly = y1 ; + int hx = x2, hy = y2 ; + int choice ; + if ( x2 < x1 ) + { + incx = -1 ; + rx = 1 - rx ; + lx = x2 ; + hx = x1 ; + } + if ( y2 < y1 ) + { + incy = -1 ; + ry = 1 - ry ; + ly = y2 ; + hy = y1 ; + } + + float sx = dx * incx ; + float sy = dy * incy ; + + int ori[3] ; + ori[ dir ] = pos / mindimen ; + ori[ xdir ] = x1 ; + ori[ ydir ] = y1 ; + int walkdir ; + int inc ; + float alpha ; + + PathElement* curEleN = f1 ; + PathElement* curEleP = f2->next ; + UCHAR *nodeN = NULL, *nodeP = NULL ; + UCHAR *curN = locateLeaf( newnode, len, f1->pos ) ; + UCHAR *curP = locateLeaf( newnode, len, f2->next->pos ) ; + if ( curN == NULL || curP == NULL ) + { + exit(0) ; + } + int stN[3], stP[3] ; + int lenN, lenP ; + + /* Unused code, leaving for posterity + + float stpt[3], edpt[3] ; + stpt[ dir ] = edpt[ dir ] = (float) pos ; + stpt[ xdir ] = ( x1 + p1 ) * mindimen ; + stpt[ ydir ] = ( y1 + q1 ) * mindimen ; + edpt[ xdir ] = ( x2 + p2 ) * mindimen ; + edpt[ ydir ] = ( y2 + q2 ) * mindimen ; + */ + while( ori[ xdir ] != x2 || ori[ ydir ] != y2 ) + { + int next ; + if ( sy * (1 - rx) > sx * (1 - ry) ) + { + choice = 1 ; + next = ori[ ydir ] + incy ; + if ( next < ly || next > hy ) + { + choice = 4 ; + next = ori[ xdir ] + incx ; + } + } + else + { + choice = 2 ; + next = ori[ xdir ] + incx ; + if ( next < lx || next > hx ) + { + choice = 3 ; + next = ori[ ydir ] + incy ; + } + } + + if ( choice & 1 ) + { + ori[ ydir ] = next ; + if ( choice == 1 ) + { + rx += ( sy == 0 ? 0 : (1 - ry) * sx / sy ) ; + ry = 0 ; + } + + walkdir = 2 ; + inc = incy ; + alpha = x2 < x1 ? 1 - rx : rx ; + } + else + { + ori[ xdir ] = next ; + if ( choice == 2 ) + { + ry += ( sx == 0 ? 0 : (1 - rx) * sy / sx ) ; + rx = 0 ; + } + + walkdir = 1 ; + inc = incx ; + alpha = y2 < y1 ? 1 - ry : ry ; + } + + + + // Get the exact location of the marcher + int nori[3] = { ori[0] * mindimen, ori[1] * mindimen, ori[2] * mindimen } ; + float spt[3] = { (float) nori[0], (float) nori[1], (float) nori[2] } ; + spt[ ( dir + ( 3 - walkdir ) ) % 3 ] += alpha * mindimen ; + if ( inc < 0 ) + { + spt[ ( dir + walkdir ) % 3 ] += mindimen ; + } + + // dc_printf("new x,y: %d %d\n", ori[ xdir ] / edgelen, ori[ ydir ] / edgelen ) ; + // dc_printf("nori: %d %d %d alpha: %f walkdir: %d\n", nori[0], nori[1], nori[2], alpha, walkdir ) ; + // dc_printf("%f %f %f\n", spt[0], spt[1], spt[2] ) ; + + // Locate the current cells on both sides + newnode = locateCell( newnode, st, len, nori, dir, 1, nodeN, stN, lenN ) ; + newnode = locateCell( newnode, st, len, nori, dir, 0, nodeP, stP, lenP ) ; + + updateParent( newnode, len, st ) ; + + int flag = 0 ; + // Add the cells to the rings and fill in the patch + PathElement* newEleN ; + if ( curEleN->pos[0] != stN[0] || curEleN->pos[1] != stN[1] || curEleN->pos[2] != stN[2] ) + { + if ( curEleN->next->pos[0] != stN[0] || curEleN->next->pos[1] != stN[1] || curEleN->next->pos[2] != stN[2] ) + { + newEleN = new PathElement ; + newEleN->next = curEleN->next ; + newEleN->pos[0] = stN[0] ; + newEleN->pos[1] = stN[1] ; + newEleN->pos[2] = stN[2] ; + + curEleN->next = newEleN ; + } + else + { + newEleN = curEleN->next ; + } + curN = patchAdjacent( newnode, len, curEleN->pos, curN, newEleN->pos, nodeN, walkdir, inc, dir, 1, alpha ) ; + + curEleN = newEleN ; + flag ++ ; + } + + PathElement* newEleP ; + if ( curEleP->pos[0] != stP[0] || curEleP->pos[1] != stP[1] || curEleP->pos[2] != stP[2] ) + { + if ( f2->pos[0] != stP[0] || f2->pos[1] != stP[1] || f2->pos[2] != stP[2] ) + { + newEleP = new PathElement ; + newEleP->next = curEleP ; + newEleP->pos[0] = stP[0] ; + newEleP->pos[1] = stP[1] ; + newEleP->pos[2] = stP[2] ; + + f2->next = newEleP ; + } + else + { + newEleP = f2 ; + } + curP = patchAdjacent( newnode, len, curEleP->pos, curP, newEleP->pos, nodeP, walkdir, inc, dir, 0, alpha ) ; + + + + curEleP = newEleP ; + flag ++ ; + } + + + /* + if ( flag == 0 ) + { + dc_printf("error: non-synchronized patching! at \n") ; + } + */ + } + +#ifdef IN_DEBUG_MODE + dc_printf("Return from CONNECTFACE with \n"); + dc_printf("Path (low side):\n") ; + printPath( f1 ) ; + checkPath( f1 ) ; + dc_printf("Path (high side):\n") ; + printPath( f2 ) ; + checkPath( f2 ) ; +#endif + + + return newnode ; +} + +UCHAR* Octree::patchAdjacent( UCHAR* node, int len, int st1[3], UCHAR* leaf1, int st2[3], UCHAR* leaf2, int walkdir, int inc, int dir, int side, float alpha ) +{ +#ifdef IN_DEBUG_MODE + dc_printf("Before patching.\n") ; + printInfo( st1 ) ; + printInfo( st2 ) ; + dc_printf("-----------------%d %d %d ; %d %d %d\n", st1[0], st2[1], st1[2], st2[0], st2[1], st2[2] ) ; +#endif + + // Get edge index on each leaf + int edgedir = ( dir + ( 3 - walkdir ) ) % 3 ; + int incdir = ( dir + walkdir ) % 3 ; + int ind1 = ( edgedir == 1 ? ( dir + 3 - edgedir ) % 3 - 1 : 2 - ( dir + 3 - edgedir ) % 3 ) ; + int ind2 = ( edgedir == 1 ? ( incdir + 3 - edgedir ) % 3 - 1 : 2 - ( incdir + 3 - edgedir ) % 3 ) ; + + int eind1 = ( ( edgedir << 2 ) | ( side << ind1 ) | ( ( inc > 0 ? 1 : 0 ) << ind2 ) ) ; + int eind2 = ( ( edgedir << 2 ) | ( side << ind1 ) | ( ( inc > 0 ? 0 : 1 ) << ind2 ) ) ; + +#ifdef IN_DEBUG_MODE + dc_printf("Index 1: %d Alpha 1: %f Index 2: %d Alpha 2: %f\n", eind1, alpha, eind2, alpha ) ; + /* + if ( alpha < 0 || alpha > 1 ) + { + dc_printf("Index 1: %d Alpha 1: %f Index 2: %d Alpha 2: %f\n", eind1, alpha, eind2, alpha ) ; + printInfo( st1 ) ; + printInfo( st2 ) ; + } + */ +#endif + + // Flip edge parity + UCHAR* nleaf1 = flipEdge( leaf1, eind1, alpha ) ; + UCHAR* nleaf2 = flipEdge( leaf2, eind2, alpha ) ; + + // Update parent link + updateParent( node, len, st1, nleaf1 ) ; + updateParent( node, len, st2, nleaf2 ) ; + // updateParent( nleaf1, mindimen, st1 ) ; + // updateParent( nleaf2, mindimen, st2 ) ; + + /* + float m[3] ; + dc_printf("Adding new point: %f %f %f\n", spt[0], spt[1], spt[2] ) ; + getMinimizer( leaf1, m ) ; + dc_printf("Cell %d now has minimizer %f %f %f\n", leaf1, m[0], m[1], m[2] ) ; + getMinimizer( leaf2, m ) ; + dc_printf("Cell %d now has minimizer %f %f %f\n", leaf2, m[0], m[1], m[2] ) ; + */ + +#ifdef IN_DEBUG_MODE + dc_printf("After patching.\n") ; + printInfo( st1 ) ; + printInfo( st2 ) ; +#endif + return nleaf2 ; +} + +UCHAR* Octree::locateCell( UCHAR* node, int st[3], int len, int ori[3], int dir, int side, UCHAR*& rleaf, int rst[3], int& rlen ) +{ +#ifdef IN_DEBUG_MODE + // dc_printf("Call to LOCATECELL with node ") ; + // printNode( node ) ; +#endif + UCHAR* newnode = node ; + int i ; + len >>= 1 ; + int ind = 0 ; + for ( i = 0 ; i < 3 ; i ++ ) + { + ind <<= 1 ; + if ( i == dir && side == 1 ) + { + ind |= ( ori[ i ] <= ( st[ i ] + len ) ? 0 : 1 ) ; + } + else + { + ind |= ( ori[ i ] < ( st[ i ] + len ) ? 0 : 1 ) ; + } + } + +#ifdef IN_DEBUG_MODE + // dc_printf("In LOCATECELL index of ori (%d %d %d) with dir %d side %d in st (%d %d %d, %d) is: %d\n", + // ori[0], ori[1], ori[2], dir, side, st[0], st[1], st[2], len, ind ) ; +#endif + + rst[0] = st[0] + vertmap[ ind ][ 0 ] * len ; + rst[1] = st[1] + vertmap[ ind ][ 1 ] * len ; + rst[2] = st[2] + vertmap[ ind ][ 2 ] * len ; + + if ( hasChild( newnode, ind ) ) + { + int count = getChildCount( newnode, ind ) ; + UCHAR* chd = getChild( newnode, count ) ; + if ( isLeaf( newnode, ind ) ) + { + rleaf = chd ; + rlen = len ; + } + else + { + // Recur + setChild( newnode, count, locateCell( chd, rst, len, ori, dir, side, rleaf, rst, rlen ) ) ; + } + } + else + { + // Create a new child here + if ( len == this->mindimen ) + { + UCHAR* chd = createLeaf( 0 ) ; + newnode = addChild( newnode, ind, chd, 1 ) ; + rleaf = chd ; + rlen = len ; + } + else + { + // Subdivide the empty cube + UCHAR* chd = createInternal( 0 ) ; + newnode = addChild( newnode, ind, locateCell( chd, rst, len, ori, dir, side, rleaf, rst, rlen ), 0 ) ; + } + } + +#ifdef IN_DEBUG_MODE + // dc_printf("Return from LOCATECELL with node ") ; + // printNode( newnode ) ; +#endif + return newnode ; +} + +void Octree::checkElement( PathElement* ele ) +{ + /* + if ( ele != NULL && locateLeafCheck( ele->pos ) != ele->node ) + { + dc_printf("Screwed! at pos: %d %d %d\n", ele->pos[0]>>minshift, ele->pos[1]>>minshift, ele->pos[2]>>minshift); + exit( 0 ) ; + } + */ +} + +void Octree::checkPath( PathElement* path ) +{ + PathElement *n = path ; + int same = 0 ; + while ( n && ( same == 0 || n != path ) ) + { + same ++ ; + checkElement( n ) ; + n = n->next ; + } + +} + +void Octree::testFacePoint( PathElement* e1, PathElement* e2 ) +{ + int i ; + PathElement * e = NULL ; + for ( i = 0 ; i < 3 ; i ++ ) + { + if ( e1->pos[i] != e2->pos[i] ) + { + if ( e1->pos[i] < e2->pos[i] ) + { + e = e2 ; + } + else + { + e = e1 ; + } + break ; + } + } + + int x, y ; + float p, q ; + dc_printf("Test.") ; + getFacePoint( e, i, x, y, p, q ) ; +} + +void Octree::getFacePoint( PathElement* leaf, int dir, int& x, int& y, float& p, float& q ) +{ + // Find average intersections + float avg[3] = {0, 0, 0} ; + float off[3] ; + int num = 0, num2 = 0 ; + + UCHAR* leafnode = locateLeaf( leaf->pos ) ; + for ( int i = 0 ; i < 4 ; i ++ ) + { + int edgeind = faceMap[ dir * 2 ][ i ] ; + int nst[3] ; + for ( int j = 0 ; j < 3 ; j ++ ) + { + nst[j] = leaf->pos[j] + mindimen * vertmap[ edgemap[ edgeind][ 0 ] ][ j ] ; + } + + if ( getEdgeIntersectionByIndex( nst, edgeind / 4, off, 1 ) ) + { + avg[0] += off[0] ; + avg[1] += off[1] ; + avg[2] += off[2] ; + num ++ ; + } + if ( getEdgeParity( leafnode, edgeind ) ) + { + num2 ++ ; + } + } + if ( num == 0 ) + { + dc_printf("Wrong! dir: %d pos: %d %d %d num: %d\n", dir, leaf->pos[0]>>minshift, leaf->pos[1]>>minshift, leaf->pos[2]>>minshift, num2); + avg[0] = (float) leaf->pos[0] ; + avg[1] = (float) leaf->pos[1] ; + avg[2] = (float) leaf->pos[2] ; + } + else + { + + avg[0] /= num ; + avg[1] /= num ; + avg[2] /= num ; + + //avg[0] = (float) leaf->pos[0]; + //avg[1] = (float) leaf->pos[1]; + //avg[2] = (float) leaf->pos[2]; + } + + int xdir = ( dir + 1 ) % 3 ; + int ydir = ( dir + 2 ) % 3 ; + + float xf = avg[ xdir ] ; + float yf = avg[ ydir ] ; + +#ifdef IN_DEBUG_MODE + // Is it outside? + // PathElement* leaf = leaf1->len < leaf2->len ? leaf1 : leaf2 ; + /* + float* m = ( leaf == leaf1 ? m1 : m2 ) ; + if ( xf < leaf->pos[ xdir ] || + yf < leaf->pos[ ydir ] || + xf > leaf->pos[ xdir ] + leaf->len || + yf > leaf->pos[ ydir ] + leaf->len) + { + dc_printf("Outside cube (%d %d %d), %d : %d %d %f %f\n", leaf->pos[ 0 ], leaf->pos[1], leaf->pos[2], leaf->len, + pos, dir, xf, yf) ; + + // For now, snap to cell + xf = m[ xdir ] ; + yf = m[ ydir ] ; + } + */ + + /* + if ( alpha < 0 || alpha > 1 || + xf < leaf->pos[xdir] || xf > leaf->pos[xdir] + leaf->len || + yf < leaf->pos[ydir] || yf > leaf->pos[ydir] + leaf->len ) + { + dc_printf("Alpha: %f Address: %d and %d\n", alpha, leaf1->node, leaf2->node ) ; + dc_printf("GETFACEPOINT result: (%d %d %d) %d min: (%f %f %f) ;(%d %d %d) %d min: (%f %f %f).\n", + leaf1->pos[0], leaf1->pos[1], leaf1->pos[2], leaf1->len, m1[0], m1[1], m1[2], + leaf2->pos[0], leaf2->pos[1], leaf2->pos[2], leaf2->len, m2[0], m2[1], m2[2]); + dc_printf("Face point at dir %d pos %d: %f %f\n", dir, pos, xf, yf ) ; + } + */ +#endif + + + // Get the integer and float part + x = ( ( leaf->pos[ xdir ] ) >> minshift ) ; + y = ( ( leaf->pos[ ydir ] ) >> minshift ) ; + + p = ( xf - leaf->pos[ xdir ] ) / mindimen ; + q = ( yf - leaf->pos[ ydir ] ) / mindimen ; + + +#ifdef IN_DEBUG_MODE + dc_printf("Face point at dir %d : %f %f\n", dir, xf, yf ) ; +#endif +} + +int Octree::findPair( PathElement* head, int pos, int dir, PathElement*& pre1, PathElement*& pre2 ) +{ + int side = getSide ( head, pos, dir ) ; + PathElement* cur = head ; + PathElement* anchor ; + PathElement* ppre1, *ppre2 ; + + // Start from this face, find a pair + anchor = cur ; + ppre1 = cur ; + cur = cur->next ; + while ( cur != anchor && ( getSide( cur, pos, dir ) == side ) ) + { + ppre1 = cur ; + cur = cur->next ; + } + if ( cur == anchor ) + { + // No pair found + return side ; + } + + side = getSide( cur, pos, dir ) ; + ppre2 = cur ; + cur = cur->next ; + while ( getSide( cur, pos, dir ) == side ) + { + ppre2 = cur ; + cur = cur->next ; + } + + + // Switch pre1 and pre2 if we start from the higher side + if ( side == -1 ) + { + cur = ppre1 ; + ppre1 = ppre2 ; + ppre2 = cur ; + } + + pre1 = ppre1 ; + pre2 = ppre2 ; + + return 0 ; +} + +int Octree::getSide( PathElement* e, int pos, int dir ) +{ + return ( e->pos[ dir ] < pos ? -1 : 1 ) ; +} + +int Octree::isEqual( PathElement* e1, PathElement* e2 ) +{ + return ( e1->pos[0] == e2->pos[0] && e1->pos[1] == e2->pos[1] && e1->pos[2] == e2->pos[2] ) ; +} + +void Octree::compressRing( PathElement*& ring ) +{ + if ( ring == NULL ) + { + return ; + } +#ifdef IN_DEBUG_MODE + dc_printf("Call to COMPRESSRING with path: \n" ); + printPath( ring ) ; +#endif + + PathElement* cur = ring->next->next ; + PathElement* pre = ring->next ; + PathElement* prepre = ring ; + PathElement* anchor = prepre ; + + do + { + while ( isEqual( cur, prepre ) ) + { + // Delete + if ( cur == prepre ) + { + // The ring has shrinked to a point + delete pre ; + delete cur ; + anchor = NULL ; + break ; + } + else + { + prepre->next = cur->next ; + delete pre ; + delete cur ; + pre = prepre->next ; + cur = pre->next ; + anchor = prepre ; + } + } + + if ( anchor == NULL ) + { + break ; + } + + prepre = pre ; + pre = cur ; + cur = cur->next ; + } while ( prepre != anchor ) ; + + ring = anchor ; + +#ifdef IN_DEBUG_MODE + dc_printf("Return from COMPRESSRING with path: \n" ); + printPath( ring ) ; +#endif +} + +void Octree::buildSigns( ) +{ + // First build a lookup table + // dc_printf("Building up look up table...\n") ; + int size = 1 << 12 ; + unsigned char table[ 1 << 12 ] ; + for ( int i = 0 ; i < size ; i ++ ) + { + table[i] = 0 ; + } + for ( int i = 0 ; i < 256 ; i ++ ) + { + int ind = 0 ; + for ( int j = 11 ; j >= 0 ; j -- ) + { + ind <<= 1 ; + if ( ( ( i >> edgemap[j][0] ) & 1 ) ^ ( ( i >> edgemap[j][1] ) & 1 ) ) + { + ind |= 1 ; + } + } + + table[ ind ] = i ; + } + + // Next, traverse the grid + int sg = 1 ; + int cube[8] ; + buildSigns( table, this->root, 0, sg, cube ) ; +} + +void Octree::buildSigns( unsigned char table[], UCHAR* node, int isLeaf, int sg, int rvalue[8] ) +{ + if ( node == NULL ) + { + for ( int i = 0 ; i < 8 ; i ++ ) + { + rvalue[i] = sg ; + } + return ; + } + + if ( isLeaf == 0 ) + { + // Internal node + UCHAR* chd[8] ; + int leaf[8] ; + fillChildren( node, chd, leaf ) ; + + // Get the signs at the corners of the first cube + rvalue[0] = sg ; + int oris[8] ; + buildSigns( table, chd[0], leaf[0], sg, oris ) ; + + // Get the rest + int cube[8] ; + for ( int i = 1 ; i < 8 ; i ++ ) + { + buildSigns( table, chd[i], leaf[i], oris[i], cube ) ; + rvalue[i] = cube[i] ; + } + + } + else + { + // Leaf node + generateSigns( node, table, sg ) ; + + for ( int i = 0 ; i < 8 ; i ++ ) + { + rvalue[i] = getSign( node, i ) ; + } + } +} + +void Octree::floodFill( ) +{ + // int threshold = (int) ((dimen/mindimen) * (dimen/mindimen) * 0.5f) ; + int st[3] = { 0, 0, 0 } ; + + // First, check for largest component + // size stored in -threshold + this->clearProcessBits( root, maxDepth ) ; + int threshold = this->floodFill( root, st, dimen, maxDepth, 0 ) ; + + // Next remove + dc_printf("Largest component: %d\n", threshold); + threshold *= thresh ; + dc_printf("Removing all components smaller than %d\n", threshold) ; + + int st2[3] = { 0, 0, 0 } ; + this->clearProcessBits( root, maxDepth ) ; + this->floodFill( root, st2, dimen, maxDepth, threshold ) ; + +} + +void Octree::clearProcessBits( UCHAR* node, int height ) +{ + int i; + + if ( height == 0 ) + { + // Leaf cell, + for ( i = 0 ; i < 12 ; i ++ ) + { + setOutProcess( node, i ) ; + } + } + else + { + // Internal cell, recur + int count = 0 ; + for ( i = 0 ; i < 8 ; i ++ ) + { + if ( hasChild( node, i ) ) + { + clearProcessBits( getChild( node, count ), height - 1 ) ; + count ++ ; + } + } + } +} + +/* +void Octree::floodFill( UCHAR* node, int st[3], int len, int height, int threshold ) +{ + int i, j; + + if ( height == 0 ) + { + // Leaf cell, + int par, inp ; + + // Test if the leaf has intersection edges + for ( i = 0 ; i < 12 ; i ++ ) + { + par = getEdgeParity( node, i ) ; + inp = isInProcess( node, i ) ; + + if ( par == 1 && inp == 0 ) + { + // Intersection edge, hasn't been processed + // Let's start filling + GridQueue* queue = new GridQueue() ; + int total = 1 ; + + // Set to in process + int mst[3] ; + mst[0] = st[0] + vertmap[edgemap[i][0]][0] * len ; + mst[1] = st[1] + vertmap[edgemap[i][0]][1] * len ; + mst[2] = st[2] + vertmap[edgemap[i][0]][2] * len; + int mdir = i / 4 ; + setInProcessAll( mst, mdir ) ; + + // Put this edge into queue + queue->pushQueue( mst, mdir ) ; + + // Queue processing + int nst[3], dir ; + while ( queue->popQueue( nst, dir ) == 1 ) + { + // dc_printf("nst: %d %d %d, dir: %d\n", nst[0]/mindimen, nst[1]/mindimen, nst[2]/mindimen, dir) ; + // locations + int stMask[3][3] = { + { 0, 0 - len, 0 - len }, + { 0 - len, 0, 0 - len }, + { 0 - len, 0 - len, 0 } + }; + int cst[2][3] ; + for ( j = 0 ; j < 3 ; j ++ ) + { + cst[0][j] = nst[j] ; + cst[1][j] = nst[j] + stMask[ dir ][ j ] ; + } + + // cells + UCHAR* cs[2] ; + for ( j = 0 ; j < 2 ; j ++ ) + { + cs[ j ] = locateLeaf( cst[j] ) ; + } + + // Middle sign + int s = getSign( cs[0], 0 ) ; + + // Masks + int fcCells[4] = {1,0,1,0}; + int fcEdges[3][4][3] = { + {{9,2,11},{8,1,10},{5,1,7},{4,2,6}}, + {{10,6,11},{8,5,9},{1,5,3},{0,6,2}}, + {{6,10,7},{4,9,5},{2,9,3},{0,10,1}} + }; + + // Search for neighboring connected intersection edges + for ( int find = 0 ; find < 4 ; find ++ ) + { + int cind = fcCells[find] ; + int eind, edge ; + if ( s == 0 ) + { + // Original order + for ( eind = 0 ; eind < 3 ; eind ++ ) + { + edge = fcEdges[dir][find][eind] ; + if ( getEdgeParity( cs[cind], edge ) == 1 ) + { + break ; + } + } + } + else + { + // Inverse order + for ( eind = 2 ; eind >= 0 ; eind -- ) + { + edge = fcEdges[dir][find][eind] ; + if ( getEdgeParity( cs[cind], edge ) == 1 ) + { + break ; + } + } + } + + if ( eind == 3 || eind == -1 ) + { + dc_printf("Wrong! this is not a consistent sign. %d\n", eind ); + } + else + { + int est[3] ; + est[0] = cst[cind][0] + vertmap[edgemap[edge][0]][0] * len ; + est[1] = cst[cind][1] + vertmap[edgemap[edge][0]][1] * len ; + est[2] = cst[cind][2] + vertmap[edgemap[edge][0]][2] * len ; + int edir = edge / 4 ; + + if ( isInProcess( cs[cind], edge ) == 0 ) + { + setInProcessAll( est, edir ) ; + queue->pushQueue( est, edir ) ; + // dc_printf("Pushed: est: %d %d %d, edir: %d\n", est[0]/len, est[1]/len, est[2]/len, edir) ; + total ++ ; + } + else + { + // dc_printf("Processed, not pushed: est: %d %d %d, edir: %d\n", est[0]/len, est[1]/len, est[2]/len, edir) ; + } + } + + } + + } + + dc_printf("Size of component: %d ", total) ; + + if ( total > threshold ) + { + dc_printf("Maintained.\n") ; + continue ; + } + dc_printf("Less then %d, removing...\n", threshold) ; + + // We have to remove this noise + + // Flip parity + // setOutProcessAll( mst, mdir ) ; + flipParityAll( mst, mdir ) ; + + // Put this edge into queue + queue->pushQueue( mst, mdir ) ; + + // Queue processing + while ( queue->popQueue( nst, dir ) == 1 ) + { + // dc_printf("nst: %d %d %d, dir: %d\n", nst[0]/mindimen, nst[1]/mindimen, nst[2]/mindimen, dir) ; + // locations + int stMask[3][3] = { + { 0, 0 - len, 0 - len }, + { 0 - len, 0, 0 - len }, + { 0 - len, 0 - len, 0 } + }; + int cst[2][3] ; + for ( j = 0 ; j < 3 ; j ++ ) + { + cst[0][j] = nst[j] ; + cst[1][j] = nst[j] + stMask[ dir ][ j ] ; + } + + // cells + UCHAR* cs[2] ; + for ( j = 0 ; j < 2 ; j ++ ) + { + cs[ j ] = locateLeaf( cst[j] ) ; + } + + // Middle sign + int s = getSign( cs[0], 0 ) ; + + // Masks + int fcCells[4] = {1,0,1,0}; + int fcEdges[3][4][3] = { + {{9,2,11},{8,1,10},{5,1,7},{4,2,6}}, + {{10,6,11},{8,5,9},{1,5,3},{0,6,2}}, + {{6,10,7},{4,9,5},{2,9,3},{0,10,1}} + }; + + // Search for neighboring connected intersection edges + for ( int find = 0 ; find < 4 ; find ++ ) + { + int cind = fcCells[find] ; + int eind, edge ; + if ( s == 0 ) + { + // Original order + for ( eind = 0 ; eind < 3 ; eind ++ ) + { + edge = fcEdges[dir][find][eind] ; + if ( isInProcess( cs[cind], edge ) == 1 ) + { + break ; + } + } + } + else + { + // Inverse order + for ( eind = 2 ; eind >= 0 ; eind -- ) + { + edge = fcEdges[dir][find][eind] ; + if ( isInProcess( cs[cind], edge ) == 1 ) + { + break ; + } + } + } + + if ( eind == 3 || eind == -1 ) + { + dc_printf("Wrong! this is not a consistent sign. %d\n", eind ); + } + else + { + int est[3] ; + est[0] = cst[cind][0] + vertmap[edgemap[edge][0]][0] * len ; + est[1] = cst[cind][1] + vertmap[edgemap[edge][0]][1] * len ; + est[2] = cst[cind][2] + vertmap[edgemap[edge][0]][2] * len ; + int edir = edge / 4 ; + + if ( getEdgeParity( cs[cind], edge ) == 1 ) + { + flipParityAll( est, edir ) ; + queue->pushQueue( est, edir ) ; + // dc_printf("Pushed: est: %d %d %d, edir: %d\n", est[0]/len, est[1]/len, est[2]/len, edir) ; + total ++ ; + } + else + { + // dc_printf("Processed, not pushed: est: %d %d %d, edir: %d\n", est[0]/len, est[1]/len, est[2]/len, edir) ; + } + } + + } + + } + + } + } + } + else + { + // Internal cell, recur + int count = 0 ; + len >>= 1 ; + for ( i = 0 ; i < 8 ; i ++ ) + { + if ( hasChild( node, i ) ) + { + int nst[3] ; + nst[0] = st[0] + vertmap[i][0] * len ; + nst[1] = st[1] + vertmap[i][1] * len ; + nst[2] = st[2] + vertmap[i][2] * len ; + + floodFill( getChild( node, count ), nst, len, height - 1, threshold ) ; + count ++ ; + } + } + } +} +*/ + +int Octree::floodFill( UCHAR* node, int st[3], int len, int height, int threshold ) +{ + int i, j; + int maxtotal = 0 ; + + if ( height == 0 ) + { + // Leaf cell, + int par, inp ; + + // Test if the leaf has intersection edges + for ( i = 0 ; i < 12 ; i ++ ) + { + par = getEdgeParity( node, i ) ; + inp = isInProcess( node, i ) ; + + if ( par == 1 && inp == 0 ) + { + // Intersection edge, hasn't been processed + // Let's start filling + GridQueue* queue = new GridQueue() ; + int total = 1 ; + + // Set to in process + int mst[3] ; + mst[0] = st[0] + vertmap[edgemap[i][0]][0] * len ; + mst[1] = st[1] + vertmap[edgemap[i][0]][1] * len ; + mst[2] = st[2] + vertmap[edgemap[i][0]][2] * len; + int mdir = i / 4 ; + setInProcessAll( mst, mdir ) ; + + // Put this edge into queue + queue->pushQueue( mst, mdir ) ; + + // Queue processing + int nst[3], dir ; + while ( queue->popQueue( nst, dir ) == 1 ) + { + // dc_printf("nst: %d %d %d, dir: %d\n", nst[0]/mindimen, nst[1]/mindimen, nst[2]/mindimen, dir) ; + // locations + int stMask[3][3] = { + { 0, 0 - len, 0 - len }, + { 0 - len, 0, 0 - len }, + { 0 - len, 0 - len, 0 } + }; + int cst[2][3] ; + for ( j = 0 ; j < 3 ; j ++ ) + { + cst[0][j] = nst[j] ; + cst[1][j] = nst[j] + stMask[ dir ][ j ] ; + } + + // cells + UCHAR* cs[2] ; + for ( j = 0 ; j < 2 ; j ++ ) + { + cs[ j ] = locateLeaf( cst[j] ) ; + } + + // Middle sign + int s = getSign( cs[0], 0 ) ; + + // Masks + int fcCells[4] = {1,0,1,0}; + int fcEdges[3][4][3] = { + {{9,2,11},{8,1,10},{5,1,7},{4,2,6}}, + {{10,6,11},{8,5,9},{1,5,3},{0,6,2}}, + {{6,10,7},{4,9,5},{2,9,3},{0,10,1}} + }; + + // Search for neighboring connected intersection edges + for ( int find = 0 ; find < 4 ; find ++ ) + { + int cind = fcCells[find] ; + int eind, edge ; + if ( s == 0 ) + { + // Original order + for ( eind = 0 ; eind < 3 ; eind ++ ) + { + edge = fcEdges[dir][find][eind] ; + if ( getEdgeParity( cs[cind], edge ) == 1 ) + { + break ; + } + } + } + else + { + // Inverse order + for ( eind = 2 ; eind >= 0 ; eind -- ) + { + edge = fcEdges[dir][find][eind] ; + if ( getEdgeParity( cs[cind], edge ) == 1 ) + { + break ; + } + } + } + + if ( eind == 3 || eind == -1 ) + { + dc_printf("Wrong! this is not a consistent sign. %d\n", eind ); + } + else + { + int est[3] ; + est[0] = cst[cind][0] + vertmap[edgemap[edge][0]][0] * len ; + est[1] = cst[cind][1] + vertmap[edgemap[edge][0]][1] * len ; + est[2] = cst[cind][2] + vertmap[edgemap[edge][0]][2] * len ; + int edir = edge / 4 ; + + if ( isInProcess( cs[cind], edge ) == 0 ) + { + setInProcessAll( est, edir ) ; + queue->pushQueue( est, edir ) ; + // dc_printf("Pushed: est: %d %d %d, edir: %d\n", est[0]/len, est[1]/len, est[2]/len, edir) ; + total ++ ; + } + else + { + // dc_printf("Processed, not pushed: est: %d %d %d, edir: %d\n", est[0]/len, est[1]/len, est[2]/len, edir) ; + } + } + + } + + } + + dc_printf("Size of component: %d ", total) ; + + if ( threshold == 0 ) + { + // Measuring stage + if ( total > maxtotal ) + { + maxtotal = total ; + } + dc_printf(".\n") ; + continue ; + } + + if ( total >= threshold ) + { + dc_printf("Maintained.\n") ; + continue ; + } + dc_printf("Less then %d, removing...\n", threshold) ; + + // We have to remove this noise + + // Flip parity + // setOutProcessAll( mst, mdir ) ; + flipParityAll( mst, mdir ) ; + + // Put this edge into queue + queue->pushQueue( mst, mdir ) ; + + // Queue processing + while ( queue->popQueue( nst, dir ) == 1 ) + { + // dc_printf("nst: %d %d %d, dir: %d\n", nst[0]/mindimen, nst[1]/mindimen, nst[2]/mindimen, dir) ; + // locations + int stMask[3][3] = { + { 0, 0 - len, 0 - len }, + { 0 - len, 0, 0 - len }, + { 0 - len, 0 - len, 0 } + }; + int cst[2][3] ; + for ( j = 0 ; j < 3 ; j ++ ) + { + cst[0][j] = nst[j] ; + cst[1][j] = nst[j] + stMask[ dir ][ j ] ; + } + + // cells + UCHAR* cs[2] ; + for ( j = 0 ; j < 2 ; j ++ ) + { + cs[ j ] = locateLeaf( cst[j] ) ; + } + + // Middle sign + int s = getSign( cs[0], 0 ) ; + + // Masks + int fcCells[4] = {1,0,1,0}; + int fcEdges[3][4][3] = { + {{9,2,11},{8,1,10},{5,1,7},{4,2,6}}, + {{10,6,11},{8,5,9},{1,5,3},{0,6,2}}, + {{6,10,7},{4,9,5},{2,9,3},{0,10,1}} + }; + + // Search for neighboring connected intersection edges + for ( int find = 0 ; find < 4 ; find ++ ) + { + int cind = fcCells[find] ; + int eind, edge ; + if ( s == 0 ) + { + // Original order + for ( eind = 0 ; eind < 3 ; eind ++ ) + { + edge = fcEdges[dir][find][eind] ; + if ( isInProcess( cs[cind], edge ) == 1 ) + { + break ; + } + } + } + else + { + // Inverse order + for ( eind = 2 ; eind >= 0 ; eind -- ) + { + edge = fcEdges[dir][find][eind] ; + if ( isInProcess( cs[cind], edge ) == 1 ) + { + break ; + } + } + } + + if ( eind == 3 || eind == -1 ) + { + dc_printf("Wrong! this is not a consistent sign. %d\n", eind ); + } + else + { + int est[3] ; + est[0] = cst[cind][0] + vertmap[edgemap[edge][0]][0] * len ; + est[1] = cst[cind][1] + vertmap[edgemap[edge][0]][1] * len ; + est[2] = cst[cind][2] + vertmap[edgemap[edge][0]][2] * len ; + int edir = edge / 4 ; + + if ( getEdgeParity( cs[cind], edge ) == 1 ) + { + flipParityAll( est, edir ) ; + queue->pushQueue( est, edir ) ; + // dc_printf("Pushed: est: %d %d %d, edir: %d\n", est[0]/len, est[1]/len, est[2]/len, edir) ; + total ++ ; + } + else + { + // dc_printf("Processed, not pushed: est: %d %d %d, edir: %d\n", est[0]/len, est[1]/len, est[2]/len, edir) ; + } + } + + } + + } + + } + } + + } + else + { + // Internal cell, recur + int count = 0 ; + len >>= 1 ; + for ( i = 0 ; i < 8 ; i ++ ) + { + if ( hasChild( node, i ) ) + { + int nst[3] ; + nst[0] = st[0] + vertmap[i][0] * len ; + nst[1] = st[1] + vertmap[i][1] * len ; + nst[2] = st[2] + vertmap[i][2] * len ; + + int d = floodFill( getChild( node, count ), nst, len, height - 1, threshold ) ; + if ( d > maxtotal) + { + maxtotal = d ; + } + count ++ ; + } + } + } + + + return maxtotal ; + +} + +void Octree::writeOut() +{ + int numQuads = 0 ; + int numVertices = 0 ; + int numEdges = 0 ; +#ifdef USE_HERMIT + countIntersection( root, maxDepth, numQuads, numVertices, numEdges ) ; +#else + countIntersection( root, maxDepth, numQuads, numVertices ) ; + numEdges = numQuads * 3 / 2 ; +#endif + dc_printf("Vertices counted: %d Polys counted: %d \n", numVertices, numQuads ) ; + output_mesh = alloc_output(numVertices, numQuads); + int offset = 0 ; + int st[3] = { 0, 0, 0 } ; + + // First, output vertices + offset = 0 ; + actualVerts = 0 ; + actualQuads = 0 ; +#ifdef USE_HERMIT + generateMinimizer( root, st, dimen, maxDepth, offset ) ; + cellProcContour( this->root, 0, maxDepth ) ; + dc_printf("Vertices written: %d Quads written: %d \n", offset, actualQuads ) ; +#else + writeVertex( root, st, dimen, maxDepth, offset, out ) ; + writeQuad( root, st, dimen, maxDepth, out ) ; + dc_printf("Vertices written: %d Triangles written: %d \n", offset, actualQuads ) ; +#endif +} + +#if 0 +void Octree::writePLY( char* fname ) +{ + int numQuads = 0 ; + int numVertices = 0 ; + int numEdges = 0 ; +#ifdef USE_HERMIT + countIntersection( root, maxDepth, numQuads, numVertices, numEdges ) ; +#else + countIntersection( root, maxDepth, numQuads, numVertices ) ; + numEdges = numQuads * 3 / 2 ; +#endif + // int euler = numVertices + numQuads - numEdges ; + // int genus = ( 2 - euler ) / 2 ; + // dc_printf("%d vertices %d quads %d edges\n", numVertices, numQuads, numEdges ) ; + // dc_printf("Genus: %d Euler: %d\n", genus, euler ) ; + + FILE* fout = fopen ( fname, "wb" ) ; + dc_printf("Vertices counted: %d Polys counted: %d \n", numVertices, numQuads ) ; + PLYWriter::writeHeader( fout, numVertices, numQuads ) ; + int offset = 0 ; + int st[3] = { 0, 0, 0 } ; + + // First, output vertices + offset = 0 ; + actualVerts = 0 ; + actualQuads = 0 ; +#ifdef USE_HERMIT + generateMinimizer( root, st, dimen, maxDepth, offset, fout ) ; +#ifdef TESTMANIFOLD + testfout = fopen("test.txt", "w"); + fprintf(testfout, "{"); +#endif + cellProcContour( this->root, 0, maxDepth, fout ) ; +#ifdef TESTMANIFOLD + fprintf(testfout, "}"); + fclose( testfout ) ; +#endif + dc_printf("Vertices written: %d Quads written: %d \n", offset, actualQuads ) ; +#else + writeVertex( root, st, dimen, maxDepth, offset, fout ) ; + writeQuad( root, st, dimen, maxDepth, fout ) ; + dc_printf("Vertices written: %d Triangles written: %d \n", offset, actualQuads ) ; +#endif + + + fclose( fout ) ; +} +#endif + +void Octree::writeOctree( char* fname ) +{ + FILE* fout = fopen ( fname, "wb" ) ; + + int sized = ( 1 << maxDepth ) ; + fwrite( &sized, sizeof( int ), 1, fout ) ; + writeOctree( fout, root, maxDepth ) ; + dc_printf("Grid dimension: %d\n", sized ) ; + + + fclose( fout ) ; +} +void Octree::writeOctree( FILE* fout, UCHAR* node, int depth ) +{ + char type ; + if ( depth > 0 ) + { + type = 0 ; + fwrite( &type, sizeof( char ), 1, fout ) ; + + // Get sign at the center + char sg = (char) getSign( getChild( node, 0 ), depth - 1, 7 - getChildIndex( node, 0 ) ) ; + + int t = 0 ; + for ( int i = 0 ; i < 8 ; i ++ ) + { + if ( hasChild( node, i ) ) + { + writeOctree( fout, getChild( node, t ), depth - 1 ) ; + t ++ ; + } + else + { + type = 1 ; + fwrite( &type, sizeof( char ), 1, fout ) ; + fwrite( &sg, sizeof( char ), 1, fout ) ; + } + } + } + else + { + type = 2 ; + fwrite( &type, sizeof( char ), 1, fout ) ; + fwrite( &(node[2]), sizeof ( UCHAR ), 1, fout ); + } +} + +#ifdef USE_HERMIT +#if 0 +void Octree::writeOctreeGeom( char* fname ) +{ + FILE* fout = fopen ( fname, "wb" ) ; + + // Write header + char header[]="SOG.Format 1.0"; + int nlen = 128 - 4 * 4 - strlen(header) - 1 ; + char* header2 = new char[ nlen ]; + for ( int i = 0 ; i < nlen ; i ++ ) + { + header2[i] = '\0'; + } + fwrite( header, sizeof( char ), strlen(header) + 1, fout ) ; + fwrite( origin, sizeof( float ), 3, fout ) ; + fwrite( &range, sizeof( float ), 1, fout ) ; + fwrite( header2, sizeof( char ), nlen, fout ) ; + + + int sized = ( 1 << maxDepth ) ; + int st[3] = {0,0,0}; + fwrite( &sized, sizeof( int ), 1, fout ) ; + + writeOctreeGeom( fout, root, st, dimen, maxDepth ) ; + dc_printf("Grid dimension: %d\n", sized ) ; + + + fclose( fout ) ; +} +#endif +void Octree::writeOctreeGeom( FILE* fout, UCHAR* node, int st[3], int len, int depth ) +{ + char type ; + if ( depth > 0 ) + { + type = 0 ; + fwrite( &type, sizeof( char ), 1, fout ) ; + + // Get sign at the center + char sg = (char) getSign( getChild( node, 0 ), depth - 1, 7 - getChildIndex( node, 0 ) ) ; + + int t = 0 ; + len >>= 1 ; + for ( int i = 0 ; i < 8 ; i ++ ) + { + if ( hasChild( node, i ) ) + { + int nst[3] ; + nst[0] = st[0] + vertmap[i][0] * len ; + nst[1] = st[1] + vertmap[i][1] * len ; + nst[2] = st[2] + vertmap[i][2] * len ; + writeOctreeGeom( fout, getChild( node, t ), nst, len, depth - 1 ) ; + t ++ ; + } + else + { + type = 1 ; + fwrite( &type, sizeof( char ), 1, fout ) ; + fwrite( &sg, sizeof( char ), 1, fout ) ; + } + } + } + else + { + type = 2 ; + fwrite( &type, sizeof( char ), 1, fout ) ; + fwrite( &(node[2]), sizeof ( UCHAR ), 1, fout ); + + // Compute minimizer + // First, find minimizer + float rvalue[3] ; + rvalue[0] = (float) st[0] + len / 2 ; + rvalue[1] = (float) st[1] + len / 2 ; + rvalue[2] = (float) st[2] + len / 2 ; + computeMinimizer( node, st, len, rvalue ) ; + + // Update + // float flen = len * range / dimen ; + for ( int j = 0 ; j < 3 ; j ++ ) + { + rvalue[ j ] = rvalue[ j ] * range / dimen + origin[ j ] ; + } + + fwrite( rvalue, sizeof ( float ), 3, fout ); + } +} +#endif + +#ifdef USE_HERMIT +void Octree::writeDCF( char* fname ) +{ + FILE* fout = fopen ( fname, "wb" ) ; + + // Writing out version + char version[10] = "multisign"; + fwrite ( &version, sizeof ( char ), 10, fout ); + + // Writing out size + int sized = ( 1 << maxDepth ) ; + fwrite( &sized, sizeof( int ), 1, fout ) ; + fwrite( &sized, sizeof( int ), 1, fout ) ; + fwrite( &sized, sizeof( int ), 1, fout ) ; + + int st[3] = {0, 0, 0} ; + writeDCF( fout, root, maxDepth, st, dimen ) ; + + dc_printf("Grid dimension: %d\n", sized ) ; + fclose( fout ) ; +} + +void Octree::writeDCF( FILE* fout, UCHAR* node, int height, int st[3], int len ) +{ + nodetype type ; + if ( height > 0 ) + { + type = 0 ; + len >>= 1 ; + fwrite( &type, sizeof( nodetype ), 1, fout ) ; + + // Get sign at the center + signtype sg = 1 - (signtype) getSign( getChild( node, 0 ), height - 1, 7 - getChildIndex( node, 0 ) ) ; + + int t = 0 ; + for ( int i = 0 ; i < 8 ; i ++ ) + { + if ( hasChild( node, i ) ) + { + int nst[3] ; + nst[0] = st[0] + vertmap[i][0] * len ; + nst[1] = st[1] + vertmap[i][1] * len ; + nst[2] = st[2] + vertmap[i][2] * len ; + + + writeDCF( fout, getChild( node, t ), height - 1, nst, len ) ; + t ++ ; + } + else + { + type = 1 ; + fwrite( &type, sizeof( nodetype ), 1, fout ) ; + fwrite ( &(sg), sizeof ( signtype ), 1, fout ); + } + } + } + else + { + type = 2 ; + fwrite( &type, sizeof( nodetype ), 1, fout ) ; + + // Write signs + signtype sgn[8] ; + for ( int i = 0 ; i < 8 ; i ++ ) + { + sgn[ i ] = 1 - (signtype) getSign( node, i ) ; + } + fwrite (sgn, sizeof (signtype), 8, fout ); + + // Write edge data + float pts[12], norms[12][3] ; + int parity[12] ; + fillEdgeOffsetsNormals( node, st, len, pts, norms, parity ) ; + + numtype zero = 0, one = 1 ; + for ( int i = 0 ; i < 12 ; i ++ ) + { + int par = getEdgeParity( node, i ) ; + // Let's check first + if ( par ) + { + if ( sgn[ edgemap[i][0] ] == sgn[ edgemap[i][1] ] ) + { + dc_printf("Wrong! Parity: %d Sign: %d %d\n", parity[i], sgn[ edgemap[i][0] ], sgn[ edgemap[i][1] ]); + exit(0) ; + } + if ( parity[ i ] == 0 ) + { + dc_printf("Wrong! No intersection found.\n"); + exit(0) ; + } + fwrite( &one, sizeof ( numtype ) , 1, fout ) ; + fwrite( &(pts[i]), sizeof( float ), 1, fout ) ; + fwrite( norms[i], sizeof( float ), 3, fout ) ; + + } + else + { + if ( sgn[ edgemap[i][0] ] != sgn[ edgemap[i][1] ] ) + { + dc_printf("Wrong! Parity: %d Sign: %d %d\n", parity[i], sgn[ edgemap[i][0] ], sgn[ edgemap[i][1] ]); + exit(0) ; + } + fwrite ( &zero, sizeof ( numtype ) , 1, fout ); + } + } + } +} +#endif + + +void Octree::writeOpenEdges( FILE* fout ) +{ + // Total number of rings + fprintf( fout, "%d\n", numRings ) ; + dc_printf("Number of rings to write: %d\n", numRings) ; + + // Write each ring + PathList* tlist = ringList ; + for ( int i = 0 ; i < numRings ; i ++ ) + { + fprintf(fout, "%d\n", tlist->length) ; + // dc_printf("Ring length: %d\n", tlist->length ) ; + PathElement* cur = tlist->head ; + for ( int j = 0 ; j < tlist->length ; j ++ ) + { + float cent[3] ; + float flen = mindimen * range / dimen ; + for ( int k = 0 ; k < 3 ; k ++ ) + { + cent[ k ] = cur->pos[ k ] * range / dimen + origin[ k ] + flen / 2 ; + } + fprintf(fout, "%f %f %f\n", cent[0], cent[1], cent[2]) ; + cur = cur->next ; + } + + tlist = tlist->next ; + } +} + +#ifndef USE_HERMIT +void Octree::countIntersection( UCHAR* node, int height, int& nquad, int& nvert ) +{ + if ( height > 0 ) + { + int total = getNumChildren( node ) ; + for ( int i = 0 ; i < total ; i ++ ) + { + countIntersection( getChild( node, i ), height - 1, nquad, nvert ) ; + } + } + else + { + int mask = getSignMask( node ) ; + nvert += getNumEdges2( node ) ; + nquad += cubes->getNumTriangle( mask ) ; + + } +} + +void Octree::writeVertex( UCHAR* node, int st[3], int len, int height, int& offset, FILE* fout ) +{ + int i ; + + if ( height == 0 ) + { + // Leaf cell, generate + int emap[] = { 0, 4, 8 } ; + for ( int i = 0 ; i < 3 ; i ++ ) + { + if ( getEdgeParity( node, emap[i] ) ) + { + // Get intersection location + int count = getEdgeCount( node, i ) ; + float off = getEdgeOffset( node, count ) ; + + float rvalue[3] ; + rvalue[0] = (float) st[0] ; + rvalue[1] = (float) st[1] ; + rvalue[2] = (float) st[2] ; + rvalue[i] += off * mindimen ; + + // Update + float fnst[3] ; + float flen = len * range / dimen ; + for ( int j = 0 ; j < 3 ; j ++ ) + { + rvalue[ j ] = rvalue[ j ] * range / dimen + origin[ j ] ; + fnst[ j ] = st[ j ] * range / dimen + origin[ j ] ; + } + + if ( this->outType == 0 ) + { + fprintf( fout, "%f %f %f\n", rvalue[0], rvalue[1], rvalue[2] ) ; + } + else if ( this->outType == 1 ) + { + PLYWriter::writeVertex( fout, rvalue ) ; + } + + // Store the index + setEdgeIntersectionIndex( node, count, offset ) ; + offset ++ ; + } + } + + } + else + { + // Internal cell, recur + int count = 0 ; + len >>= 1 ; + for ( i = 0 ; i < 8 ; i ++ ) + { + if ( hasChild( node, i ) ) + { + int nst[3] ; + nst[0] = st[0] + vertmap[i][0] * len ; + nst[1] = st[1] + vertmap[i][1] * len ; + nst[2] = st[2] + vertmap[i][2] * len ; + + writeVertex( getChild( node, count ), nst, len, height - 1, offset, fout ) ; + count ++ ; + } + } + } +} + +void Octree::writeQuad( UCHAR* node, int st[3], int len, int height, FILE* fout ) +{ + int i ; + if ( height == 0 ) + { + int mask = getSignMask( node ) ; + int num = cubes->getNumTriangle( mask ) ; + int indices[12] ; + fillEdgeIntersectionIndices( node, st, len, indices ) ; + int einds[3], ind[3] ; + + //int flag1 = 0 ; + //int flag2 = 0 ; + for ( i = 0 ; i < num ; i ++ ) + { + int color = 0 ; + cubes->getTriangle( mask, i, einds ) ; + // dc_printf("(%d %d %d) ", einds[0], einds[1], einds[2] ) ; + + for ( int j = 0 ; j < 3 ; j ++ ) + { + ind[j] = indices[ einds[j] ] ; + /* + if ( ind[j] == 78381 ) + { + flag1 = 1 ; + } + if ( ind[j] == 78384 ) + { + flag2 = 1 ; + } + */ + } + + if ( this->outType == 0 ) + { + // OFF + int numpoly = ( color ? -3 : 3 ) ; + fprintf(fout, "%d %d %d %d\n", numpoly, ind[0], ind[1], ind[2] ) ; + actualQuads ++ ; + } + else if ( this->outType == 1 ) + { + // PLY + PLYWriter::writeFace( fout, 3, ind ) ; + actualQuads ++ ; + } + } + + /* + if (flag1 && flag2) + { + dc_printf("%d\n", mask); + cubes->printTriangles( mask ) ; + } + */ + } + else + { + // Internal cell, recur + int count = 0 ; + len >>= 1 ; + for ( i = 0 ; i < 8 ; i ++ ) + { + if ( hasChild( node, i ) ) + { + int nst[3] ; + nst[0] = st[0] + vertmap[i][0] * len ; + nst[1] = st[1] + vertmap[i][1] * len ; + nst[2] = st[2] + vertmap[i][2] * len ; + + writeQuad( getChild( node, count ), nst, len, height - 1, fout ) ; + count ++ ; + } + } + } +} + +#endif + + +#ifdef USE_HERMIT +void Octree::countIntersection( UCHAR* node, int height, int& nedge, int& ncell, int& nface ) +{ + if ( height > 0 ) + { + int total = getNumChildren( node ) ; + for ( int i = 0 ; i < total ; i ++ ) + { + countIntersection( getChild( node, i ), height - 1, nedge, ncell, nface ) ; + } + } + else + { + nedge += getNumEdges2( node ) ; + + int smask = getSignMask( node ) ; + + if(use_manifold) + { + int comps = manifold_table[ smask ].comps ; + ncell += comps ; + } + else { + if ( smask > 0 && smask < 255 ) + { + ncell ++ ; + } + } + + for ( int i = 0 ; i < 3 ; i ++ ) + { + if ( getFaceEdgeNum( node, i * 2 ) ) + { + nface ++ ; + } + } + } +} + +/* from http://eigen.tuxfamily.org/bz/show_bug.cgi?id=257 */ +template +void pseudoInverse(const _Matrix_Type_ &a, + _Matrix_Type_ &result, + double epsilon = std::numeric_limits::epsilon()) +{ + Eigen::JacobiSVD< _Matrix_Type_ > svd = a.jacobiSvd(Eigen::ComputeFullU | + Eigen::ComputeFullV); + + typename _Matrix_Type_::Scalar tolerance = epsilon * std::max(a.cols(), + a.rows()) * + svd.singularValues().array().abs().maxCoeff(); + + result = svd.matrixV() * + _Matrix_Type_((svd.singularValues().array().abs() > + tolerance).select(svd.singularValues(). + array().inverse(), 0)).asDiagonal() * + svd.matrixU().adjoint(); +} + +void solve_least_squares(const float halfA[], const float b[], + const float midpoint[], float rvalue[]) +{ + /* calculate pseudo-inverse */ + Eigen::MatrixXf A(3, 3), pinv(3, 3); + A << halfA[0], halfA[1], halfA[2], + halfA[1], halfA[3], halfA[4], + halfA[2], halfA[4], halfA[5]; + pseudoInverse(A, pinv); + + Eigen::Vector3f b2(b), mp(midpoint), result; + b2 = b2 + A * -mp; + result = pinv * b2 + mp; + + for(int i = 0; i < 3; i++) + rvalue[i] = result(i); +} + +void minimize(float rvalue[3], float mp[3], const float pts[12][3], + const float norms[12][3], const int parity[12]) +{ + float ata[6] = { 0, 0, 0, 0, 0, 0 }; + float atb[3] = { 0, 0, 0 } ; + int ec = 0 ; + + for ( int i = 0 ; i < 12 ; i ++ ) + { + // if ( getEdgeParity( leaf, i) ) + if ( parity[ i ] ) + { + const float* norm = norms[i] ; + const float* p = pts[i] ; + + // QEF + ata[ 0 ] += (float) ( norm[ 0 ] * norm[ 0 ] ); + ata[ 1 ] += (float) ( norm[ 0 ] * norm[ 1 ] ); + ata[ 2 ] += (float) ( norm[ 0 ] * norm[ 2 ] ); + ata[ 3 ] += (float) ( norm[ 1 ] * norm[ 1 ] ); + ata[ 4 ] += (float) ( norm[ 1 ] * norm[ 2 ] ); + ata[ 5 ] += (float) ( norm[ 2 ] * norm[ 2 ] ); + + double pn = p[0] * norm[0] + p[1] * norm[1] + p[2] * norm[2] ; + + atb[ 0 ] += (float) ( norm[ 0 ] * pn ) ; + atb[ 1 ] += (float) ( norm[ 1 ] * pn ) ; + atb[ 2 ] += (float) ( norm[ 2 ] * pn ) ; + + // Minimizer + mp[0] += p[0] ; + mp[1] += p[1] ; + mp[2] += p[2] ; + + ec ++ ; + } + } + + if ( ec == 0 ) + { + return ; + } + mp[0] /= ec ; + mp[1] /= ec ; + mp[2] /= ec ; + + // Solve least squares + solve_least_squares(ata, atb, mp, rvalue); +} + +void Octree::computeMinimizer( UCHAR* leaf, int st[3], int len, float rvalue[3] ) +{ + // First, gather all edge intersections + float pts[12][3], norms[12][3] ; + // fillEdgeIntersections( leaf, st, len, pts, norms ) ; + int parity[12] ; + fillEdgeIntersections( leaf, st, len, pts, norms, parity ) ; + + // Next, construct QEF and minimizer + float mp[3] = {0, 0, 0}; + minimize(rvalue, mp, pts, norms, parity); + + /* Restraining the location of the minimizer */ + float nh1 = hermite_num * len ; + float nh2 = ( 1 + hermite_num ) * len ; + if((mode == DUALCON_MASS_POINT || mode == DUALCON_CENTROID) || + ( rvalue[0] < st[0] - nh1 || rvalue[1] < st[1] - nh1 || rvalue[2] < st[2] - nh1 || + rvalue[0] > st[0] + nh2 || rvalue[1] > st[1] + nh2 || rvalue[2] > st[2] + nh2 )) + { + if(mode == DUALCON_CENTROID) { + // Use centroids + rvalue[0] = (float) st[0] + len / 2 ; + rvalue[1] = (float) st[1] + len / 2 ; + rvalue[2] = (float) st[2] + len / 2 ; + } + else { + // Use mass point instead + rvalue[0] = mp[0] ; + rvalue[1] = mp[1] ; + rvalue[2] = mp[2] ; + } + } +} + +void Octree::generateMinimizer( UCHAR* node, int st[3], int len, int height, int& offset ) +{ + int i, j ; + + if ( height == 0 ) + { + // Leaf cell, generate + + // First, find minimizer + float rvalue[3] ; + rvalue[0] = (float) st[0] + len / 2 ; + rvalue[1] = (float) st[1] + len / 2 ; + rvalue[2] = (float) st[2] + len / 2 ; + computeMinimizer( node, st, len, rvalue ) ; + + // Update + //float fnst[3] ; + for ( j = 0 ; j < 3 ; j ++ ) + { + rvalue[ j ] = rvalue[ j ] * range / dimen + origin[ j ] ; + //fnst[ j ] = st[ j ] * range / dimen + origin[ j ] ; + } + + int mult = 0, smask = getSignMask( node ) ; + + if(use_manifold) + { + mult = manifold_table[ smask ].comps ; + } + else + { + if ( smask > 0 && smask < 255 ) + { + mult = 1 ; + } + } + + for ( j = 0 ; j < mult ; j ++ ) + { + add_vert(output_mesh, rvalue); + } + + // Store the index + setMinimizerIndex( node, offset ) ; + + offset += mult ; + } + else + { + // Internal cell, recur + int count = 0 ; + len >>= 1 ; + for ( i = 0 ; i < 8 ; i ++ ) + { + if ( hasChild( node, i ) ) + { + int nst[3] ; + nst[0] = st[0] + vertmap[i][0] * len ; + nst[1] = st[1] + vertmap[i][1] * len ; + nst[2] = st[2] + vertmap[i][2] * len ; + + generateMinimizer( getChild( node, count ), nst, len, height - 1, offset ) ; + count ++ ; + } + } + } +} + +void Octree::processEdgeWrite( UCHAR* node[4], int depth[4], int maxdep, int dir ) +{ + //int color = 0 ; + + int i = 3 ; + { + if ( getEdgeParity( node[i], processEdgeMask[dir][i] ) ) + { + int flip = 0 ; + int edgeind = processEdgeMask[dir][i] ; + if ( getSign( node[i], edgemap[ edgeind ][ 1 ] ) > 0 ) + { + flip = 1 ; + } + + int num = 0 ; + { + int ind[8]; + if(use_manifold) + { + /* Deprecated + int ind[4] = { + getMinimizerIndex( node[0], processEdgeMask[dir][0] ), + getMinimizerIndex( node[1], processEdgeMask[dir][1] ), + getMinimizerIndex( node[3], processEdgeMask[dir][3] ), + getMinimizerIndex( node[2], processEdgeMask[dir][2] ) + } ; + num = 4 ; + */ + int vind[2] ; + int seq[4] = {0,1,3,2}; + for ( int k = 0 ; k < 4 ; k ++ ) + { + getMinimizerIndices( node[seq[k]], processEdgeMask[dir][seq[k]], vind ) ; + ind[num] = vind[0] ; + num ++ ; + + if ( vind[1] != -1 ) + { + ind[num] = vind[1] ; + num ++ ; + if ( flip == 0 ) + { + ind[num-1] = vind[0] ; + ind[num-2] = vind[1] ; + } + } + } +#ifdef TESTMANIFOLD + if ( num != 4 ) + { + dc_printf("Polygon: %d\n", num); + } + for ( k = 0 ; k < num ; k ++ ) + { + fprintf(testfout, "{%d,%d},", ind[k], ind[(k+1)%num] ); + } +#endif + + /* we don't use the manifold option, but if it is + ever enabled again note that it can output + non-quads */ + } + else { + if(flip) { + ind[0] = getMinimizerIndex( node[2] ); + ind[1] = getMinimizerIndex( node[3] ); + ind[2] = getMinimizerIndex( node[1] ); + ind[3] = getMinimizerIndex( node[0] ); + } + else { + ind[0] = getMinimizerIndex( node[0] ); + ind[1] = getMinimizerIndex( node[1] ); + ind[2] = getMinimizerIndex( node[3] ); + ind[3] = getMinimizerIndex( node[2] ); + } + + add_quad(output_mesh, ind); + } + /* + if ( this->outType == 0 ) + { + // OFF + + num = ( color ? -num : num ) ; + + fprintf(fout, "%d ", num); + + if ( flip ) + { + for ( int k = num - 1 ; k >= 0 ; k -- ) + { + fprintf(fout, "%d ", ind[k] ) ; + } + } + else + { + for ( int k = 0 ; k < num ; k ++ ) + { + fprintf(fout, "%d ", ind[k] ) ; + } + } + + fprintf( fout, "\n") ; + + actualQuads ++ ; + } + else if ( this->outType == 1 ) + { + // PLY + + if ( flip ) + { + int tind[8]; + for ( int k = num - 1 ; k >= 0 ; k -- ) + { + tind[k] = ind[num-1-k] ; + } + // PLYWriter::writeFace( fout, num, tind ) ; + } + else + { + // PLYWriter::writeFace( fout, num, ind ) ; + } + + actualQuads ++ ; + }*/ + } + return ; + } + else + { + return ; + } + } +} + + +void Octree::edgeProcContour( UCHAR* node[4], int leaf[4], int depth[4], int maxdep, int dir ) +{ + if ( ! ( node[0] && node[1] && node[2] && node[3] ) ) + { + return ; + } + if ( leaf[0] && leaf[1] && leaf[2] && leaf[3] ) + { + processEdgeWrite( node, depth, maxdep, dir ) ; + } + else + { + int i, j ; + UCHAR* chd[ 4 ][ 8 ] ; + for ( j = 0 ; j < 4 ; j ++ ) + { + for ( i = 0 ; i < 8 ; i ++ ) + { + chd[ j ][ i ] = ((!leaf[j]) && hasChild( node[j], i ) )? getChild( node[j], getChildCount( node[j], i ) ) : NULL ; + } + } + + // 2 edge calls + UCHAR* ne[4] ; + int le[4] ; + int de[4] ; + for ( i = 0 ; i < 2 ; i ++ ) + { + int c[ 4 ] = { edgeProcEdgeMask[ dir ][ i ][ 0 ], + edgeProcEdgeMask[ dir ][ i ][ 1 ], + edgeProcEdgeMask[ dir ][ i ][ 2 ], + edgeProcEdgeMask[ dir ][ i ][ 3 ] } ; + + for ( int j = 0 ; j < 4 ; j ++ ) + { + if ( leaf[j] ) + { + le[j] = leaf[j] ; + ne[j] = node[j] ; + de[j] = depth[j] ; + } + else + { + le[j] = isLeaf( node[j], c[j] ) ; + ne[j] = chd[ j ][ c[j] ] ; + de[j] = depth[j] - 1 ; + } + } + + edgeProcContour( ne, le, de, maxdep - 1, edgeProcEdgeMask[ dir ][ i ][ 4 ] ) ; + } + + } +} + +void Octree::faceProcContour( UCHAR* node[2], int leaf[2], int depth[2], int maxdep, int dir ) +{ + if ( ! ( node[0] && node[1] ) ) + { + return ; + } + + if ( ! ( leaf[0] && leaf[1] ) ) + { + int i, j ; + // Fill children nodes + UCHAR* chd[ 2 ][ 8 ] ; + for ( j = 0 ; j < 2 ; j ++ ) + { + for ( i = 0 ; i < 8 ; i ++ ) + { + chd[ j ][ i ] = ((!leaf[j]) && hasChild( node[j], i )) ? getChild( node[j], getChildCount( node[j], i ) ) : NULL ; + } + } + + // 4 face calls + UCHAR* nf[2] ; + int df[2] ; + int lf[2] ; + for ( i = 0 ; i < 4 ; i ++ ) + { + int c[2] = { faceProcFaceMask[ dir ][ i ][ 0 ], faceProcFaceMask[ dir ][ i ][ 1 ] }; + for ( int j = 0 ; j < 2 ; j ++ ) + { + if ( leaf[j] ) + { + lf[j] = leaf[j] ; + nf[j] = node[j] ; + df[j] = depth[j] ; + } + else + { + lf[j] = isLeaf( node[j], c[j] ) ; + nf[j] = chd[ j ][ c[j] ] ; + df[j] = depth[j] - 1 ; + } + } + faceProcContour( nf, lf, df, maxdep - 1, faceProcFaceMask[ dir ][ i ][ 2 ] ) ; + } + + // 4 edge calls + int orders[2][4] = {{ 0, 0, 1, 1 }, { 0, 1, 0, 1 }} ; + UCHAR* ne[4] ; + int le[4] ; + int de[4] ; + + for ( i = 0 ; i < 4 ; i ++ ) + { + int c[4] = { faceProcEdgeMask[ dir ][ i ][ 1 ], faceProcEdgeMask[ dir ][ i ][ 2 ], + faceProcEdgeMask[ dir ][ i ][ 3 ], faceProcEdgeMask[ dir ][ i ][ 4 ] }; + int* order = orders[ faceProcEdgeMask[ dir ][ i ][ 0 ] ] ; + + for ( int j = 0 ; j < 4 ; j ++ ) + { + if ( leaf[order[j]] ) + { + le[j] = leaf[order[j]] ; + ne[j] = node[order[j]] ; + de[j] = depth[order[j]] ; + } + else + { + le[j] = isLeaf( node[order[j]], c[j] ) ; + ne[j] = chd[ order[ j ] ][ c[j] ] ; + de[j] = depth[order[j]] - 1 ; + } + } + + edgeProcContour( ne, le, de, maxdep - 1, faceProcEdgeMask[ dir ][ i ][ 5 ] ) ; + } + } +} + + +void Octree::cellProcContour( UCHAR* node, int leaf, int depth ) +{ + if ( node == NULL ) + { + return ; + } + + if ( ! leaf ) + { + int i ; + + // Fill children nodes + UCHAR* chd[ 8 ] ; + for ( i = 0 ; i < 8 ; i ++ ) + { + chd[ i ] = ((!leaf) && hasChild( node, i )) ? getChild( node, getChildCount( node, i ) ) : NULL ; + } + + // 8 Cell calls + for ( i = 0 ; i < 8 ; i ++ ) + { + cellProcContour( chd[ i ], isLeaf( node, i ), depth - 1 ) ; + } + + // 12 face calls + UCHAR* nf[2] ; + int lf[2] ; + int df[2] = { depth - 1, depth - 1 } ; + for ( i = 0 ; i < 12 ; i ++ ) + { + int c[ 2 ] = { cellProcFaceMask[ i ][ 0 ], cellProcFaceMask[ i ][ 1 ] }; + + lf[0] = isLeaf( node, c[0] ) ; + lf[1] = isLeaf( node, c[1] ) ; + + nf[0] = chd[ c[0] ] ; + nf[1] = chd[ c[1] ] ; + + faceProcContour( nf, lf, df, depth - 1, cellProcFaceMask[ i ][ 2 ] ) ; + } + + // 6 edge calls + UCHAR* ne[4] ; + int le[4] ; + int de[4] = { depth - 1, depth - 1, depth - 1, depth - 1 } ; + for ( i = 0 ; i < 6 ; i ++ ) + { + int c[ 4 ] = { cellProcEdgeMask[ i ][ 0 ], cellProcEdgeMask[ i ][ 1 ], cellProcEdgeMask[ i ][ 2 ], cellProcEdgeMask[ i ][ 3 ] }; + + for ( int j = 0 ; j < 4 ; j ++ ) + { + le[j] = isLeaf( node, c[j] ) ; + ne[j] = chd[ c[j] ] ; + } + + edgeProcContour( ne, le, de, depth - 1, cellProcEdgeMask[ i ][ 4 ] ) ; + } + } + +} + +#endif + + + +void Octree::processEdgeParity( UCHAR* node[4], int depth[4], int maxdep, int dir ) +{ + int con = 0 ; + for ( int i = 0 ; i < 4 ; i ++ ) + { + // Minimal cell + // if ( op == 0 ) + { + if ( getEdgeParity( node[i], processEdgeMask[dir][i] ) ) + { + con = 1 ; + break ; + } + } + } + + if ( con == 1 ) + { + for ( int i = 0 ; i < 4 ; i ++ ) + { + setEdge( node[ i ], processEdgeMask[dir][i] ) ; + } + } + +} + +void Octree::edgeProcParity( UCHAR* node[4], int leaf[4], int depth[4], int maxdep, int dir ) +{ + if ( ! ( node[0] && node[1] && node[2] && node[3] ) ) + { + return ; + } + if ( leaf[0] && leaf[1] && leaf[2] && leaf[3] ) + { + processEdgeParity( node, depth, maxdep, dir ) ; + } + else + { + int i, j ; + UCHAR* chd[ 4 ][ 8 ] ; + for ( j = 0 ; j < 4 ; j ++ ) + { + for ( i = 0 ; i < 8 ; i ++ ) + { + chd[ j ][ i ] = ((!leaf[j]) && hasChild( node[j], i ) )? getChild( node[j], getChildCount( node[j], i ) ) : NULL ; + } + } + + // 2 edge calls + UCHAR* ne[4] ; + int le[4] ; + int de[4] ; + for ( i = 0 ; i < 2 ; i ++ ) + { + int c[ 4 ] = { edgeProcEdgeMask[ dir ][ i ][ 0 ], + edgeProcEdgeMask[ dir ][ i ][ 1 ], + edgeProcEdgeMask[ dir ][ i ][ 2 ], + edgeProcEdgeMask[ dir ][ i ][ 3 ] } ; + + // int allleaf = 1 ; + for ( int j = 0 ; j < 4 ; j ++ ) + { + + if ( leaf[j] ) + { + le[j] = leaf[j] ; + ne[j] = node[j] ; + de[j] = depth[j] ; + } + else + { + le[j] = isLeaf( node[j], c[j] ) ; + ne[j] = chd[ j ][ c[j] ] ; + de[j] = depth[j] - 1 ; + + } + + } + + edgeProcParity( ne, le, de, maxdep - 1, edgeProcEdgeMask[ dir ][ i ][ 4 ] ) ; + } + + } +} + +void Octree::faceProcParity( UCHAR* node[2], int leaf[2], int depth[2], int maxdep, int dir ) +{ + if ( ! ( node[0] && node[1] ) ) + { + return ; + } + + if ( ! ( leaf[0] && leaf[1] ) ) + { + int i, j ; + // Fill children nodes + UCHAR* chd[ 2 ][ 8 ] ; + for ( j = 0 ; j < 2 ; j ++ ) + { + for ( i = 0 ; i < 8 ; i ++ ) + { + chd[ j ][ i ] = ((!leaf[j]) && hasChild( node[j], i )) ? getChild( node[j], getChildCount( node[j], i ) ) : NULL ; + } + } + + // 4 face calls + UCHAR* nf[2] ; + int df[2] ; + int lf[2] ; + for ( i = 0 ; i < 4 ; i ++ ) + { + int c[2] = { faceProcFaceMask[ dir ][ i ][ 0 ], faceProcFaceMask[ dir ][ i ][ 1 ] }; + for ( int j = 0 ; j < 2 ; j ++ ) + { + if ( leaf[j] ) + { + lf[j] = leaf[j] ; + nf[j] = node[j] ; + df[j] = depth[j] ; + } + else + { + lf[j] = isLeaf( node[j], c[j] ) ; + nf[j] = chd[ j ][ c[j] ] ; + df[j] = depth[j] - 1 ; + } + } + faceProcParity( nf, lf, df, maxdep - 1, faceProcFaceMask[ dir ][ i ][ 2 ] ) ; + } + + // 4 edge calls + int orders[2][4] = {{ 0, 0, 1, 1 }, { 0, 1, 0, 1 }} ; + UCHAR* ne[4] ; + int le[4] ; + int de[4] ; + + for ( i = 0 ; i < 4 ; i ++ ) + { + int c[4] = { faceProcEdgeMask[ dir ][ i ][ 1 ], faceProcEdgeMask[ dir ][ i ][ 2 ], + faceProcEdgeMask[ dir ][ i ][ 3 ], faceProcEdgeMask[ dir ][ i ][ 4 ] }; + int* order = orders[ faceProcEdgeMask[ dir ][ i ][ 0 ] ] ; + + for ( int j = 0 ; j < 4 ; j ++ ) + { + if ( leaf[order[j]] ) + { + le[j] = leaf[order[j]] ; + ne[j] = node[order[j]] ; + de[j] = depth[order[j]] ; + } + else + { + le[j] = isLeaf( node[order[j]], c[j] ) ; + ne[j] = chd[ order[ j ] ][ c[j] ] ; + de[j] = depth[order[j]] - 1 ; + } + } + + edgeProcParity( ne, le, de, maxdep - 1, faceProcEdgeMask[ dir ][ i ][ 5 ] ) ; + } + } +} + + +void Octree::cellProcParity( UCHAR* node, int leaf, int depth ) +{ + if ( node == NULL ) + { + return ; + } + + if ( ! leaf ) + { + int i ; + + // Fill children nodes + UCHAR* chd[ 8 ] ; + for ( i = 0 ; i < 8 ; i ++ ) + { + chd[ i ] = ((!leaf) && hasChild( node, i )) ? getChild( node, getChildCount( node, i ) ) : NULL ; + } + + // 8 Cell calls + for ( i = 0 ; i < 8 ; i ++ ) + { + cellProcParity( chd[ i ], isLeaf( node, i ), depth - 1 ) ; + } + + // 12 face calls + UCHAR* nf[2] ; + int lf[2] ; + int df[2] = { depth - 1, depth - 1 } ; + for ( i = 0 ; i < 12 ; i ++ ) + { + int c[ 2 ] = { cellProcFaceMask[ i ][ 0 ], cellProcFaceMask[ i ][ 1 ] }; + + lf[0] = isLeaf( node, c[0] ) ; + lf[1] = isLeaf( node, c[1] ) ; + + nf[0] = chd[ c[0] ] ; + nf[1] = chd[ c[1] ] ; + + faceProcParity( nf, lf, df, depth - 1, cellProcFaceMask[ i ][ 2 ] ) ; + } + + // 6 edge calls + UCHAR* ne[4] ; + int le[4] ; + int de[4] = { depth - 1, depth - 1, depth - 1, depth - 1 } ; + for ( i = 0 ; i < 6 ; i ++ ) + { + int c[ 4 ] = { cellProcEdgeMask[ i ][ 0 ], cellProcEdgeMask[ i ][ 1 ], cellProcEdgeMask[ i ][ 2 ], cellProcEdgeMask[ i ][ 3 ] }; + + for ( int j = 0 ; j < 4 ; j ++ ) + { + le[j] = isLeaf( node, c[j] ) ; + ne[j] = chd[ c[j] ] ; + } + + edgeProcParity( ne, le, de, depth - 1, cellProcEdgeMask[ i ][ 4 ] ) ; + } + } + +} + +/* definitions for global arrays */ +const int edgemask[3] = {5, 3, 6}; + +const int faceMap[6][4] = { + {4, 8, 5, 9}, + {6, 10, 7, 11}, + {0, 8, 1, 10}, + {2, 9, 3, 11}, + {0, 4, 2, 6}, + {1, 5, 3, 7} +}; + +const int cellProcFaceMask[12][3] = { + {0, 4, 0}, + {1, 5, 0}, + {2, 6, 0}, + {3, 7, 0}, + {0, 2, 1}, + {4, 6, 1}, + {1, 3, 1}, + {5, 7, 1}, + {0, 1, 2}, + {2, 3, 2}, + {4, 5, 2}, + {6, 7, 2} +}; + +const int cellProcEdgeMask[6][5] = { + {0, 1, 2, 3, 0}, + {4, 5, 6, 7, 0}, + {0, 4, 1, 5, 1}, + {2, 6, 3, 7, 1}, + {0, 2, 4, 6, 2}, + {1, 3, 5, 7, 2} +}; + +const int faceProcFaceMask[3][4][3] = { + {{4, 0, 0}, + {5, 1, 0}, + {6, 2, 0}, + {7, 3, 0}}, + {{2, 0, 1}, + {6, 4, 1}, + {3, 1, 1}, + {7, 5, 1}}, + {{1, 0, 2}, + {3, 2, 2}, + {5, 4, 2}, + {7, 6, 2}} +}; + +const int faceProcEdgeMask[3][4][6] = { + {{1, 4, 0, 5, 1, 1}, + {1, 6, 2, 7, 3, 1}, + {0, 4, 6, 0, 2, 2}, + {0, 5, 7, 1, 3, 2}}, + {{0, 2, 3, 0, 1, 0}, + {0, 6, 7, 4, 5, 0}, + {1, 2, 0, 6, 4, 2}, + {1, 3, 1, 7, 5, 2}}, + {{1, 1, 0, 3, 2, 0}, + {1, 5, 4, 7, 6, 0}, + {0, 1, 5, 0, 4, 1}, + {0, 3, 7, 2, 6, 1}} +}; + +const int edgeProcEdgeMask[3][2][5] = { + {{3, 2, 1, 0, 0}, + {7, 6, 5, 4, 0}}, + {{5, 1, 4, 0, 1}, + {7, 3, 6, 2, 1}}, + {{6, 4, 2, 0, 2}, + {7, 5, 3, 1, 2}}, +}; + +const int processEdgeMask[3][4] = { + {3, 2, 1, 0}, + {7, 5, 6, 4}, + {11, 10, 9, 8} +}; + +const int dirCell[3][4][3] = { + {{0, -1, -1}, + {0, -1, 0}, + {0, 0, -1}, + {0, 0, 0}}, + {{-1, 0, -1}, + {-1, 0, 0}, + {0, 0, -1}, + {0, 0, 0}}, + {{-1, -1, 0}, + {-1, 0, 0}, + {0, -1, 0}, + {0, 0, 0}} +}; + +const int dirEdge[3][4] = { + {3, 2, 1, 0}, + {7, 6, 5, 4}, + {11, 10, 9, 8} +}; diff -Nru blender-2.61/intern/dualcon/intern/octree.h blender-2.62/intern/dualcon/intern/octree.h --- blender-2.61/intern/dualcon/intern/octree.h 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/intern/dualcon/intern/octree.h 2012-02-15 19:24:40.000000000 +0000 @@ -0,0 +1,1596 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + * Contributor(s): Tao Ju + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef OCTREE_H +#define OCTREE_H + +#include +#include +#include "GeoCommon.h" +#include "Projections.h" +#include "ModelReader.h" +#include "MemoryAllocator.h" +#include "cubes.h" +#include "Queue.h" +#include "manifold_table.h" +#include "dualcon.h" + +/** + * Main class and structures for scan-convertion, sign-generation, + * and surface reconstruction. + * + * @author Tao Ju + */ + + +/* Global defines */ +// Uncomment to see debug information +// #define IN_DEBUG_MODE + +// Uncomment to see more output messages during repair +// #define IN_VERBOSE_MODE + +/* Set scan convert params */ +// Uncomment to use Dual Contouring on Hermit representation +// for better sharp feature reproduction, but more mem is required +// The number indicates how far do we allow the minimizer to shoot +// outside the cell +#define USE_HERMIT 1.0f + +#ifdef USE_HERMIT +//#define CINDY +#endif + +///#define QIANYI + +//#define TESTMANIFOLD + + +/* Set output options */ +// Comment out to prevent writing output files +#define OUTPUT_REPAIRED + + +/* Set node bytes */ +#ifdef USE_HERMIT +#define EDGE_BYTES 16 +#define EDGE_FLOATS 4 +#else +#define EDGE_BYTES 4 +#define EDGE_FLOATS 1 +#endif + +#define CINDY_BYTES 0 + +/*#define LEAF_EXTRA_BYTES FLOOD_BYTES + CINDY_BYTES + +#ifdef USE_HERMIT +#define LEAF_NODE_BYTES 7 + LEAF_EXTRA_BYTES +#else +#define LEAF_NODE_BYTES 3 + LEAF_EXTRA_BYTES +#endif*/ + +#define INTERNAL_NODE_BYTES 2 +#define POINTER_BYTES 8 +#define FLOOD_FILL_BYTES 2 + +#define signtype short +#define nodetype int +#define numtype int + +/* Global variables */ +extern const int edgemask[3]; +extern const int faceMap[6][4]; +extern const int cellProcFaceMask[12][3]; +extern const int cellProcEdgeMask[6][5]; +extern const int faceProcFaceMask[3][4][3]; +extern const int edgeProcEdgeMask[3][2][5]; +extern const int faceProcEdgeMask[3][4][6]; +extern const int processEdgeMask[3][4]; +extern const int dirCell[3][4][3]; +extern const int dirEdge[3][4]; + +/** + * Structures for detecting/patching open cycles on the dual surface + */ + +struct PathElement +{ + // Origin + int pos[3] ; + + // link + PathElement* next ; +}; + +struct PathList +{ + // Head + PathElement* head ; + PathElement* tail ; + + // Length of the list + int length ; + + // Next list + PathList* next ; +}; + + +/** + * Class for building and processing an octree + */ +class Octree +{ +public: + /* Public members */ + + /// Memory allocators + VirtualMemoryAllocator * alloc[ 9 ] ; + VirtualMemoryAllocator * leafalloc[ 4 ] ; + + /// Root node + UCHAR* root ; + + /// Model reader + ModelReader* reader ; + + /// Marching cubes table + Cubes* cubes ; + + /// Length of grid + int dimen ; + int mindimen, minshift ; + + /// Maximum depth + int maxDepth ; + + /// The lower corner of the bounding box and the size + float origin[3]; + float range; + + /// Counting information + int nodeCount ; + int nodeSpace ; + int nodeCounts[ 9 ] ; + + int actualQuads, actualVerts ; + + PathList* ringList ; + + int maxTrianglePerCell ; + int outType ; // 0 for OFF, 1 for PLY, 2 for VOL + + // For flood filling + int use_flood_fill; + float thresh ; + + int use_manifold; + + // testing + FILE* testfout ; + + float hermite_num; + + DualConMode mode; + + int leaf_node_bytes; + int leaf_extra_bytes; + int flood_bytes; + +public: + /** + * Construtor + */ + Octree ( ModelReader* mr, + DualConAllocOutput alloc_output_func, + DualConAddVert add_vert_func, + DualConAddQuad add_quad_func, + DualConFlags flags, DualConMode mode, int depth, + float threshold, float hermite_num ) ; + + /** + * Destructor + */ + ~Octree ( ) ; + + /** + * Scan convert + */ + void scanConvert() ; + + void *getOutputMesh() { return output_mesh; } + +private: + /* Helper functions */ + + /** + * Initialize memory allocators + */ + void initMemory ( ) ; + + /** + * Release memory + */ + void freeMemory ( ) ; + + /** + * Print memory usage + */ + void printMemUsage( ) ; + + + /** + * Methods to set / restore minimum edges + */ + void resetMinimalEdges( ) ; + + void cellProcParity ( UCHAR* node, int leaf, int depth ) ; + void faceProcParity ( UCHAR* node[2], int leaf[2], int depth[2], int maxdep, int dir ) ; + void edgeProcParity ( UCHAR* node[4], int leaf[4], int depth[4], int maxdep, int dir ) ; + + void processEdgeParity ( UCHAR* node[4], int depths[4], int maxdep, int dir ) ; + + /** + * Add triangles to the tree + */ + void addTrian ( ); + void addTrian ( Triangle* trian, int triind ); + UCHAR* addTrian ( UCHAR* node, Projections* p, int height ); + + /** + * Method to update minimizer in a cell: update edge intersections instead + */ + UCHAR* updateCell( UCHAR* node, Projections* p ) ; + + /* Routines to detect and patch holes */ + int numRings ; + int totRingLengths ; + int maxRingLength ; + + /** + * Entry routine. + */ + void trace ( ) ; + /** + * Trace the given node, find patches and fill them in + */ + UCHAR* trace ( UCHAR* node, int* st, int len, int depth, PathList*& paths ) ; + /** + * Look for path on the face and add to paths + */ + void findPaths ( UCHAR* node[2], int leaf[2], int depth[2], int* st[2], int maxdep, int dir, PathList*& paths ) ; + /** + * Combine two list1 and list2 into list1 using connecting paths list3, + * while closed paths are appended to rings + */ + void combinePaths ( PathList*& list1, PathList* list2, PathList* paths, PathList*& rings ) ; + /** + * Helper function: combine current paths in list1 and list2 to a single path and append to list3 + */ + PathList* combineSinglePath ( PathList*& head1, PathList* pre1, PathList*& list1, PathList*& head2, PathList* pre2, PathList*& list2 ) ; + + /** + * Functions to patch rings in a node + */ + UCHAR* patch ( UCHAR* node, int st[3], int len, PathList* rings ) ; + UCHAR* patchSplit ( UCHAR* node, int st[3], int len, PathList* rings, int dir, PathList*& nrings1, PathList*& nrings2 ) ; + UCHAR* patchSplitSingle ( UCHAR* node, int st[3], int len, PathElement* head, int dir, PathList*& nrings1, PathList*& nrings2 ) ; + UCHAR* connectFace ( UCHAR* node, int st[3], int len, int dir, PathElement* f1, PathElement* f2 ) ; + UCHAR* locateCell( UCHAR* node, int st[3], int len, int ori[3], int dir, int side, UCHAR*& rleaf, int rst[3], int& rlen ) ; + void compressRing ( PathElement*& ring ) ; + void getFacePoint( PathElement* leaf, int dir, int& x, int& y, float& p, float& q ) ; + UCHAR* patchAdjacent( UCHAR* node, int len, int st1[3], UCHAR* leaf1, int st2[3], UCHAR* leaf2, int walkdir, int inc, int dir, int side, float alpha ) ; + int findPair ( PathElement* head, int pos, int dir, PathElement*& pre1, PathElement*& pre2 ) ; + int getSide( PathElement* e, int pos, int dir ) ; + int isEqual( PathElement* e1, PathElement* e2 ) ; + void preparePrimalEdgesMask( UCHAR* node ) ; + void testFacePoint( PathElement* e1, PathElement* e2 ) ; + + /** + * Path-related functions + */ + void deletePath ( PathList*& head, PathList* pre, PathList*& curr ) ; + void printPath( PathList* path ) ; + void printPath( PathElement* path ) ; + void printElement( PathElement* ele ) ; + void printPaths( PathList* path ) ; + void checkElement ( PathElement* ele ) ; + void checkPath( PathElement* path ) ; + + + /** + * Routines to build signs to create a partitioned volume + * (after patching rings) + */ + void buildSigns( ) ; + void buildSigns( unsigned char table[], UCHAR* node, int isLeaf, int sg, int rvalue[8] ) ; + + /************************************************************************/ + /* To remove disconnected components */ + /************************************************************************/ + void floodFill( ) ; + void clearProcessBits( UCHAR* node, int height ) ; + int floodFill( UCHAR* node, int st[3], int len, int height, int threshold ) ; + + /** + * Write out polygon file + */ + void writeOut(); + void writeOFF ( char* fname ) ; + void writePLY ( char* fname ) ; + void writeOpenEdges( FILE* fout ) ; + void writeAllEdges( FILE* fout, int mode ) ; + void writeAllEdges( FILE* fout, UCHAR* node, int height, int st[3], int len, int mode ) ; + + void writeOctree( char* fname ) ; + void writeOctree( FILE* fout, UCHAR* node, int depth ) ; +#ifdef USE_HERMIT + void writeOctreeGeom( char* fname ) ; + void writeOctreeGeom( FILE* fout, UCHAR* node, int st[3], int len, int depth ) ; +#endif +#ifdef USE_HERMIT + void writeDCF ( char* fname ) ; + void writeDCF ( FILE* fout, UCHAR* node, int height, int st[3], int len ) ; + void countEdges ( UCHAR* node, int height, int& nedge, int mode ) ; + void countIntersection( UCHAR* node, int height, int& nedge, int& ncell, int& nface ) ; + void generateMinimizer( UCHAR* node, int st[3], int len, int height, int& offset ) ; + void computeMinimizer( UCHAR* leaf, int st[3], int len, float rvalue[3] ) ; + /** + * Traversal functions to generate polygon model + * op: 0 for counting, 1 for writing OBJ, 2 for writing OFF, 3 for writing PLY + */ + void cellProcContour ( UCHAR* node, int leaf, int depth ) ; + void faceProcContour ( UCHAR* node[2], int leaf[2], int depth[2], int maxdep, int dir ) ; + void edgeProcContour ( UCHAR* node[4], int leaf[4], int depth[4], int maxdep, int dir ) ; + void processEdgeWrite ( UCHAR* node[4], int depths[4], int maxdep, int dir ) ; +#else + void countIntersection( UCHAR* node, int height, int& nquad, int& nvert ) ; + void writeVertex( UCHAR* node, int st[3], int len, int height, int& offset, FILE* fout ) ; + void writeQuad( UCHAR* node, int st[3], int len, int height, FILE* fout ) ; +#endif + + /** + * Write out original model + */ + void writeModel( char* fname ) ; + + /************************************************************************/ + /* Write out original vertex tags */ + /************************************************************************/ +#ifdef CINDY + void writeTags( char* fname ) ; + void readVertices( ) ; + void readVertex( UCHAR* node, int st[3], int len, int height, float v[3], int index ) ; + void outputTags( UCHAR* node, int height, FILE* fout ) ; + void clearCindyBits( UCHAR* node, int height ) ; +#endif + + /* output callbacks/data */ + DualConAllocOutput alloc_output; + DualConAddVert add_vert; + DualConAddQuad add_quad; + void *output_mesh; + +private: + /************ Operators for all nodes ************/ + + /** + * Bits order + * + * Leaf node: + * Byte 0,1 (0-11): edge parity + * Byte 1 (4,5,6): mask of primary edges intersections stored + * Byte 1 (7): in flood fill mode, whether the cell is in process + * Byte 2 (0-8): signs + * Byte 3 (or 5) -- : edge intersections ( 4 bytes per inter, or 12 bytes if USE_HERMIT ) + * Byte 3,4: in coloring mode, the mask for edges + * + * Internal node: + * Byte 0: child mask + * Byte 1: leaf child mask + */ + + /// Lookup table + int numChildrenTable[ 256 ] ; + int childrenCountTable[ 256 ][ 8 ] ; + int childrenIndexTable[ 256 ][ 8 ] ; + int numEdgeTable[ 8 ] ; + int edgeCountTable[ 8 ][ 3 ] ; + + /// Build up lookup table + void buildTable ( ) + { + for ( int i = 0 ; i < 256 ; i ++ ) + { + numChildrenTable[ i ] = 0 ; + int count = 0 ; + for ( int j = 0 ; j < 8 ; j ++ ) + { + numChildrenTable[ i ] += ( ( i >> j ) & 1 ) ; + childrenCountTable[ i ][ j ] = count ; + childrenIndexTable[ i ][ count ] = j ; + count += ( ( i >> j ) & 1 ) ; + } + } + + for ( int i = 0 ; i < 8 ; i ++ ) + { + numEdgeTable[ i ] = 0 ; + int count = 0 ; + for ( int j = 0 ; j < 3 ; j ++ ) + { + numEdgeTable[ i ] += ( ( i >> j ) & 1 ) ; + edgeCountTable[ i ][ j ] = count ; + count += ( ( i >> j ) & 1 ) ; + } + } + }; + + int getSign( UCHAR* node, int height, int index ) + { + if ( height == 0 ) + { + return getSign( node, index ) ; + } + else + { + if ( hasChild( node, index ) ) + { + return getSign( getChild( node, getChildCount( node, index ) ), height - 1, index ) ; + } + else + { + return getSign( getChild( node, 0 ), height - 1, 7 - getChildIndex( node, 0 ) ) ; + } + } + } + + /************ Operators for leaf nodes ************/ + + void printInfo( int st[3] ) + { + printf("INFO AT: %d %d %d\n", st[0] >> minshift, st[1] >>minshift, st[2] >> minshift ) ; + UCHAR* leaf = locateLeafCheck( st ) ; + if ( leaf == NULL ) + { + printf("Leaf not exists!\n") ; + } + else + { + printInfo( leaf ) ; + } + } + + void printInfo( UCHAR* leaf ) + { + /* + printf("Edge mask: ") ; + for ( int i = 0 ; i < 12 ; i ++ ) + { + printf("%d ", getEdgeParity( leaf, i ) ) ; + } + printf("\n") ; + printf("Stored edge mask: ") ; + for ( i = 0 ; i < 3 ; i ++ ) + { + printf("%d ", getStoredEdgesParity( leaf, i ) ) ; + } + printf("\n") ; + */ + printf("Sign mask: ") ; + for ( int i = 0 ; i < 8 ; i ++ ) + { + printf("%d ", getSign( leaf, i ) ) ; + } + printf("\n") ; + + } + + /// Retrieve signs + int getSign ( UCHAR* leaf, int index ) + { + return (( leaf[2] >> index ) & 1 ); + }; + + /// Set sign + void setSign ( UCHAR* leaf, int index ) + { + leaf[2] |= ( 1 << index ) ; + }; + + void setSign ( UCHAR* leaf, int index, int sign ) + { + leaf[2] &= ( ~ ( 1 << index ) ) ; + leaf[2] |= ( ( sign & 1 ) << index ) ; + }; + + int getSignMask( UCHAR* leaf ) + { + return leaf[2] ; + } + + void setInProcessAll( int st[3], int dir ) + { + int nst[3], eind ; + for ( int i = 0 ; i < 4 ; i ++ ) + { + nst[0] = st[0] + dirCell[dir][i][0] * mindimen ; + nst[1] = st[1] + dirCell[dir][i][1] * mindimen ; + nst[2] = st[2] + dirCell[dir][i][2] * mindimen ; + eind = dirEdge[dir][i] ; + + UCHAR* cell = locateLeafCheck( nst ) ; + if ( cell == NULL ) + { + printf("Wrong!\n") ; + } + setInProcess( cell, eind ) ; + } + } + + void flipParityAll( int st[3], int dir ) + { + int nst[3], eind ; + for ( int i = 0 ; i < 4 ; i ++ ) + { + nst[0] = st[0] + dirCell[dir][i][0] * mindimen ; + nst[1] = st[1] + dirCell[dir][i][1] * mindimen ; + nst[2] = st[2] + dirCell[dir][i][2] * mindimen ; + eind = dirEdge[dir][i] ; + + UCHAR* cell = locateLeaf( nst ) ; + flipEdge( cell, eind ) ; + } + } + + void setInProcess( UCHAR* leaf, int eind ) + { + // leaf[1] |= ( 1 << 7 ) ; + ( (USHORT*) (leaf + leaf_node_bytes - (flood_bytes + CINDY_BYTES)))[0] |= ( 1 << eind ) ; + } + void setOutProcess( UCHAR* leaf, int eind ) + { + // leaf[1] &= ( ~ ( 1 << 7 ) ) ; + ( (USHORT*) (leaf + leaf_node_bytes - (flood_bytes + CINDY_BYTES)))[0] &= ( ~ ( 1 << eind ) ) ; + } + + int isInProcess( UCHAR* leaf, int eind ) + { + //int a = ( ( leaf[1] >> 7 ) & 1 ) ; + int a = ( ( ( (USHORT*) (leaf + leaf_node_bytes - (flood_bytes + CINDY_BYTES)))[0] >> eind ) & 1 ) ; + return a ; + } + +#ifndef USE_HERMIT + /// Set minimizer index + void setEdgeIntersectionIndex( UCHAR* leaf, int count, int index ) + { + ((int *)( leaf + leaf_node_bytes ))[ count ] = index ; + } + + /// Get minimizer index + int getEdgeIntersectionIndex( UCHAR* leaf, int count ) + { + return ((int *)( leaf + leaf_node_bytes ))[ count ] ; + } + + /// Get all intersection indices associated with a cell + void fillEdgeIntersectionIndices( UCHAR* leaf, int st[3], int len, int inds[12] ) + { + int i ; + + // The three primal edges are easy + int pmask[3] = { 0, 4, 8 } ; + for ( i = 0 ; i < 3 ; i ++ ) + { + if ( getEdgeParity( leaf, pmask[i] ) ) + { + inds[pmask[i]] = getEdgeIntersectionIndex( leaf, getEdgeCount( leaf, i ) ) ; + } + } + + // 3 face adjacent cubes + int fmask[3][2] = {{6,10},{2,9},{1,5}} ; + int femask[3][2] = {{1,2},{0,2},{0,1}} ; + for ( i = 0 ; i < 3 ; i ++ ) + { + int e1 = getEdgeParity( leaf, fmask[i][0] ) ; + int e2 = getEdgeParity( leaf, fmask[i][1] ) ; + if ( e1 || e2 ) + { + int nst[3] = {st[0], st[1], st[2]} ; + nst[ i ] += len ; + // int nstt[3] = {0, 0, 0} ; + // nstt[ i ] += 1 ; + UCHAR* node = locateLeaf( nst ) ; + + if ( e1 ) + { + inds[ fmask[i][0] ] = getEdgeIntersectionIndex( node, getEdgeCount( node, femask[i][0] ) ) ; + } + if ( e2 ) + { + inds[ fmask[i][1] ] = getEdgeIntersectionIndex( node, getEdgeCount( node, femask[i][1] ) ) ; + } + } + } + + // 3 edge adjacent cubes + int emask[3] = {3, 7, 11} ; + int eemask[3] = {0, 1, 2} ; + for ( i = 0 ; i < 3 ; i ++ ) + { + if ( getEdgeParity( leaf, emask[i] ) ) + { + int nst[3] = {st[0] + len, st[1] + len, st[2] + len} ; + nst[ i ] -= len ; + // int nstt[3] = {1, 1, 1} ; + // nstt[ i ] -= 1 ; + UCHAR* node = locateLeaf( nst ) ; + + inds[ emask[i] ] = getEdgeIntersectionIndex( node, getEdgeCount( node, eemask[i] ) ) ; + } + } + } + + +#endif + + /// Generate signs at the corners from the edge parity + void generateSigns ( UCHAR* leaf, UCHAR table[], int start ) + { + leaf[2] = table[ ( ((USHORT *) leaf)[ 0 ] ) & ( ( 1 << 12 ) - 1 ) ] ; + + if ( ( start ^ leaf[2] ) & 1 ) + { + leaf[2] = ~ ( leaf[2] ) ; + } + } + + /// Get edge parity + int getEdgeParity( UCHAR* leaf, int index ) + { + int a = ( ( ((USHORT *) leaf)[ 0 ] >> index ) & 1 ) ; + return a ; + }; + + /// Get edge parity on a face + int getFaceParity ( UCHAR* leaf, int index ) + { + int a = getEdgeParity( leaf, faceMap[ index ][ 0 ] ) + + getEdgeParity( leaf, faceMap[ index ][ 1 ] ) + + getEdgeParity( leaf, faceMap[ index ][ 2 ] ) + + getEdgeParity( leaf, faceMap[ index ][ 3 ] ) ; + return ( a & 1 ) ; + } + int getFaceEdgeNum ( UCHAR* leaf, int index ) + { + int a = getEdgeParity( leaf, faceMap[ index ][ 0 ] ) + + getEdgeParity( leaf, faceMap[ index ][ 1 ] ) + + getEdgeParity( leaf, faceMap[ index ][ 2 ] ) + + getEdgeParity( leaf, faceMap[ index ][ 3 ] ) ; + return a ; + } + + /// Set edge parity + void flipEdge( UCHAR* leaf, int index ) + { + ((USHORT *) leaf)[ 0 ] ^= ( 1 << index ) ; + }; + /// Set 1 + void setEdge( UCHAR* leaf, int index ) + { + ((USHORT *) leaf)[ 0 ] |= ( 1 << index ) ; + }; + /// Set 0 + void resetEdge( UCHAR* leaf, int index ) + { + ((USHORT *) leaf)[ 0 ] &= ( ~ ( 1 << index ) ) ; + }; + + /// Flipping with a new intersection offset + void createPrimalEdgesMask( UCHAR* leaf ) + { + int mask = (( leaf[0] & 1 ) | ( (leaf[0] >> 3) & 2 ) | ( (leaf[1] & 1) << 2 ) ) ; + leaf[1] |= ( mask << 4 ) ; + + } + + void setStoredEdgesParity( UCHAR* leaf, int pindex ) + { + leaf[1] |= ( 1 << ( 4 + pindex ) ) ; + } + int getStoredEdgesParity( UCHAR* leaf, int pindex ) + { + return ( ( leaf[1] >> ( 4 + pindex ) ) & 1 ) ; + } + + UCHAR* flipEdge( UCHAR* leaf, int index, float alpha ) + { + flipEdge( leaf, index ) ; + + if ( ( index & 3 ) == 0 ) + { + int ind = index / 4 ; + if ( getEdgeParity( leaf, index ) && ! getStoredEdgesParity( leaf, ind ) ) + { + // Create a new node + int num = getNumEdges( leaf ) + 1 ; + setStoredEdgesParity( leaf, ind ) ; + int count = getEdgeCount( leaf, ind ) ; + UCHAR* nleaf = createLeaf( num ) ; + for ( int i = 0 ; i < leaf_node_bytes ; i ++ ) + { + nleaf[i] = leaf[i] ; + } + + setEdgeOffset( nleaf, alpha, count ) ; + + if ( num > 1 ) + { + float * pts = ( float * ) ( leaf + leaf_node_bytes ) ; + float * npts = ( float * ) ( nleaf + leaf_node_bytes ) ; + for ( int i = 0 ; i < count ; i ++ ) + { + for ( int j = 0 ; j < EDGE_FLOATS ; j ++ ) + { + npts[i * EDGE_FLOATS + j] = pts[i * EDGE_FLOATS + j] ; + } + } + for ( int i = count + 1 ; i < num ; i ++ ) + { + for ( int j = 0 ; j < EDGE_FLOATS ; j ++ ) + { + npts[i * EDGE_FLOATS + j] = pts[ (i - 1) * EDGE_FLOATS + j] ; + } + } + } + + + removeLeaf( num-1, leaf ) ; + leaf = nleaf ; + } + } + + return leaf ; + }; + + /// Update parent link + void updateParent( UCHAR* node, int len, int st[3], UCHAR* leaf ) + { + // First, locate the parent + int count ; + UCHAR* parent = locateParent( node, len, st, count ) ; + + // UPdate + setChild( parent, count, leaf ) ; + } + + void updateParent( UCHAR* node, int len, int st[3] ) + { + if ( len == dimen ) + { + root = node ; + return ; + } + + // First, locate the parent + int count ; + UCHAR* parent = locateParent( len, st, count ) ; + + // UPdate + setChild( parent, count, node ) ; + } + + /// Find edge intersection on a given edge + int getEdgeIntersectionByIndex( int st[3], int index, float pt[3], int check ) + { + // First, locat the leaf + UCHAR* leaf ; + if ( check ) + { + leaf = locateLeafCheck( st ) ; + } + else + { + leaf = locateLeaf( st ) ; + } + + if ( leaf && getStoredEdgesParity( leaf, index ) ) + { + float off = getEdgeOffset( leaf, getEdgeCount( leaf, index ) ) ; + pt[0] = (float) st[0] ; + pt[1] = (float) st[1] ; + pt[2] = (float) st[2] ; + pt[index] += off * mindimen ; + + return 1 ; + } + else + { + return 0 ; + } + } + + /// Retrieve number of edges intersected + int getPrimalEdgesMask( UCHAR* leaf ) + { + // return (( leaf[0] & 1 ) | ( (leaf[0] >> 3) & 2 ) | ( (leaf[1] & 1) << 2 ) ) ; + return ( ( leaf[1] >> 4 ) & 7 ) ; + } + + int getPrimalEdgesMask2( UCHAR* leaf ) + { + return (( leaf[0] & 1 ) | ( (leaf[0] >> 3) & 2 ) | ( (leaf[1] & 1) << 2 ) ) ; + } + + /// Get the count for a primary edge + int getEdgeCount( UCHAR* leaf, int index ) + { + return edgeCountTable[ getPrimalEdgesMask( leaf ) ][ index ] ; + } + int getNumEdges( UCHAR* leaf ) + { + return numEdgeTable[ getPrimalEdgesMask( leaf ) ] ; + } + + int getNumEdges2( UCHAR* leaf ) + { + return numEdgeTable[ getPrimalEdgesMask2( leaf ) ] ; + } + + /// Set edge intersection + void setEdgeOffset( UCHAR* leaf, float pt, int count ) + { + float * pts = ( float * ) ( leaf + leaf_node_bytes ) ; +#ifdef USE_HERMIT + pts[ EDGE_FLOATS * count ] = pt ; + pts[ EDGE_FLOATS * count + 1 ] = 0 ; + pts[ EDGE_FLOATS * count + 2 ] = 0 ; + pts[ EDGE_FLOATS * count + 3 ] = 0 ; +#else + pts[ count ] = pt ; +#endif + } + + /// Set multiple edge intersections + void setEdgeOffsets( UCHAR* leaf, float pt[3], int len ) + { + float * pts = ( float * ) ( leaf + leaf_node_bytes ) ; + for ( int i = 0 ; i < len ; i ++ ) + { + pts[i] = pt[i] ; + } + } + + /// Retrieve edge intersection + float getEdgeOffset( UCHAR* leaf, int count ) + { +#ifdef USE_HERMIT + return (( float * ) ( leaf + leaf_node_bytes ))[ 4 * count ] ; +#else + return (( float * ) ( leaf + leaf_node_bytes ))[ count ] ; +#endif + } + + /// Update method + UCHAR* updateEdgeOffsets( UCHAR* leaf, int oldlen, int newlen, float offs[3] ) + { + // First, create a new leaf node + UCHAR* nleaf = createLeaf( newlen ) ; + for ( int i = 0 ; i < leaf_node_bytes ; i ++ ) + { + nleaf[i] = leaf[i] ; + } + + // Next, fill in the offsets + setEdgeOffsets( nleaf, offs, newlen ) ; + + // Finally, delete the old leaf + removeLeaf( oldlen, leaf ) ; + + return nleaf ; + } + + /// Set original vertex index + void setOriginalIndex( UCHAR* leaf, int index ) + { + ((int *)( leaf + leaf_node_bytes ))[ 0 ] = index ; + } + int getOriginalIndex( UCHAR* leaf ) + { + return ((int *)( leaf + leaf_node_bytes ))[ 0 ] ; + } +#ifdef USE_HERMIT + /// Set minimizer index + void setMinimizerIndex( UCHAR* leaf, int index ) + { + ((int *)( leaf + leaf_node_bytes - leaf_extra_bytes - 4 ))[ 0 ] = index ; + } + + /// Get minimizer index + int getMinimizerIndex( UCHAR* leaf ) + { + return ((int *)( leaf + leaf_node_bytes - leaf_extra_bytes - 4 ))[ 0 ] ; + } + + int getMinimizerIndex( UCHAR* leaf, int eind ) + { + int add = manifold_table[ getSignMask( leaf ) ].pairs[ eind ][ 0 ] - 1 ; + if ( add < 0 ) + { + printf("Manifold components wrong!\n") ; + } + return ((int *)( leaf + leaf_node_bytes - leaf_extra_bytes - 4 ))[ 0 ] + add ; + } + + void getMinimizerIndices( UCHAR* leaf, int eind, int inds[2] ) + { + const int* add = manifold_table[ getSignMask( leaf ) ].pairs[ eind ] ; + inds[0] = ((int *)( leaf + leaf_node_bytes - leaf_extra_bytes - 4 ))[ 0 ] + add[0] - 1 ; + if ( add[0] == add[1] ) + { + inds[1] = -1 ; + } + else + { + inds[1] = ((int *)( leaf + leaf_node_bytes - leaf_extra_bytes - 4 ))[ 0 ] + add[1] - 1 ; + } + } + + + /// Set edge intersection + void setEdgeOffsetNormal( UCHAR* leaf, float pt, float a, float b, float c, int count ) + { + float * pts = ( float * ) ( leaf + leaf_node_bytes ) ; + pts[ 4 * count ] = pt ; + pts[ 4 * count + 1 ] = a ; + pts[ 4 * count + 2 ] = b ; + pts[ 4 * count + 3 ] = c ; + } + + float getEdgeOffsetNormal( UCHAR* leaf, int count, float& a, float& b, float& c ) + { + float * pts = ( float * ) ( leaf + leaf_node_bytes ) ; + a = pts[ 4 * count + 1 ] ; + b = pts[ 4 * count + 2 ] ; + c = pts[ 4 * count + 3 ] ; + return pts[ 4 * count ] ; + } + + /// Set multiple edge intersections + void setEdgeOffsetsNormals( UCHAR* leaf, float pt[], float a[], float b[], float c[], int len ) + { + float * pts = ( float * ) ( leaf + leaf_node_bytes ) ; + for ( int i = 0 ; i < len ; i ++ ) + { + if ( pt[i] > 1 || pt[i] < 0 ) + { + printf("\noffset: %f\n", pt[i]) ; + } + pts[ i * 4 ] = pt[i] ; + pts[ i * 4 + 1 ] = a[i] ; + pts[ i * 4 + 2 ] = b[i] ; + pts[ i * 4 + 3 ] = c[i] ; + } + } + + /// Retrieve complete edge intersection + void getEdgeIntersectionByIndex( UCHAR* leaf, int index, int st[3], int len, float pt[3], float nm[3] ) + { + int count = getEdgeCount( leaf, index ) ; + float * pts = ( float * ) ( leaf + leaf_node_bytes ) ; + + float off = pts[ 4 * count ] ; + + pt[0] = (float) st[0] ; + pt[1] = (float) st[1] ; + pt[2] = (float) st[2] ; + pt[ index ] += ( off * len ) ; + + nm[0] = pts[ 4 * count + 1 ] ; + nm[1] = pts[ 4 * count + 2 ] ; + nm[2] = pts[ 4 * count + 3 ] ; + } + + float getEdgeOffsetNormalByIndex( UCHAR* leaf, int index, float nm[3] ) + { + int count = getEdgeCount( leaf, index ) ; + float * pts = ( float * ) ( leaf + leaf_node_bytes ) ; + + float off = pts[ 4 * count ] ; + + nm[0] = pts[ 4 * count + 1 ] ; + nm[1] = pts[ 4 * count + 2 ] ; + nm[2] = pts[ 4 * count + 3 ] ; + + return off ; + } + + void fillEdgeIntersections( UCHAR* leaf, int st[3], int len, float pts[12][3], float norms[12][3] ) + { + int i ; + // int stt[3] = { 0, 0, 0 } ; + + // The three primal edges are easy + int pmask[3] = { 0, 4, 8 } ; + for ( i = 0 ; i < 3 ; i ++ ) + { + if ( getEdgeParity( leaf, pmask[i] ) ) + { + // getEdgeIntersectionByIndex( leaf, i, stt, 1, pts[ pmask[i] ], norms[ pmask[i] ] ) ; + getEdgeIntersectionByIndex( leaf, i, st, len, pts[ pmask[i] ], norms[ pmask[i] ] ) ; + } + } + + // 3 face adjacent cubes + int fmask[3][2] = {{6,10},{2,9},{1,5}} ; + int femask[3][2] = {{1,2},{0,2},{0,1}} ; + for ( i = 0 ; i < 3 ; i ++ ) + { + int e1 = getEdgeParity( leaf, fmask[i][0] ) ; + int e2 = getEdgeParity( leaf, fmask[i][1] ) ; + if ( e1 || e2 ) + { + int nst[3] = {st[0], st[1], st[2]} ; + nst[ i ] += len ; + // int nstt[3] = {0, 0, 0} ; + // nstt[ i ] += 1 ; + UCHAR* node = locateLeaf( nst ) ; + + if ( e1 ) + { + // getEdgeIntersectionByIndex( node, femask[i][0], nstt, 1, pts[ fmask[i][0] ], norms[ fmask[i][0] ] ) ; + getEdgeIntersectionByIndex( node, femask[i][0], nst, len, pts[ fmask[i][0] ], norms[ fmask[i][0] ] ) ; + } + if ( e2 ) + { + // getEdgeIntersectionByIndex( node, femask[i][1], nstt, 1, pts[ fmask[i][1] ], norms[ fmask[i][1] ] ) ; + getEdgeIntersectionByIndex( node, femask[i][1], nst, len, pts[ fmask[i][1] ], norms[ fmask[i][1] ] ) ; + } + } + } + + // 3 edge adjacent cubes + int emask[3] = {3, 7, 11} ; + int eemask[3] = {0, 1, 2} ; + for ( i = 0 ; i < 3 ; i ++ ) + { + if ( getEdgeParity( leaf, emask[i] ) ) + { + int nst[3] = {st[0] + len, st[1] + len, st[2] + len} ; + nst[ i ] -= len ; + // int nstt[3] = {1, 1, 1} ; + // nstt[ i ] -= 1 ; + UCHAR* node = locateLeaf( nst ) ; + + // getEdgeIntersectionByIndex( node, eemask[i], nstt, 1, pts[ emask[i] ], norms[ emask[i] ] ) ; + getEdgeIntersectionByIndex( node, eemask[i], nst, len, pts[ emask[i] ], norms[ emask[i] ] ) ; + } + } + } + + + void fillEdgeIntersections( UCHAR* leaf, int st[3], int len, float pts[12][3], float norms[12][3], int parity[12] ) + { + int i ; + for ( i = 0 ; i < 12 ; i ++ ) + { + parity[ i ] = 0 ; + } + // int stt[3] = { 0, 0, 0 } ; + + // The three primal edges are easy + int pmask[3] = { 0, 4, 8 } ; + for ( i = 0 ; i < 3 ; i ++ ) + { + if ( getStoredEdgesParity( leaf, i ) ) + { + // getEdgeIntersectionByIndex( leaf, i, stt, 1, pts[ pmask[i] ], norms[ pmask[i] ] ) ; + getEdgeIntersectionByIndex( leaf, i, st, len, pts[ pmask[i] ], norms[ pmask[i] ] ) ; + parity[ pmask[i] ] = 1 ; + } + } + + // 3 face adjacent cubes + int fmask[3][2] = {{6,10},{2,9},{1,5}} ; + int femask[3][2] = {{1,2},{0,2},{0,1}} ; + for ( i = 0 ; i < 3 ; i ++ ) + { + { + int nst[3] = {st[0], st[1], st[2]} ; + nst[ i ] += len ; + // int nstt[3] = {0, 0, 0} ; + // nstt[ i ] += 1 ; + UCHAR* node = locateLeafCheck( nst ) ; + if ( node == NULL ) + { + continue ; + } + + int e1 = getStoredEdgesParity( node, femask[i][0] ) ; + int e2 = getStoredEdgesParity( node, femask[i][1] ) ; + + if ( e1 ) + { + // getEdgeIntersectionByIndex( node, femask[i][0], nstt, 1, pts[ fmask[i][0] ], norms[ fmask[i][0] ] ) ; + getEdgeIntersectionByIndex( node, femask[i][0], nst, len, pts[ fmask[i][0] ], norms[ fmask[i][0] ] ) ; + parity[ fmask[i][0] ] = 1 ; + } + if ( e2 ) + { + // getEdgeIntersectionByIndex( node, femask[i][1], nstt, 1, pts[ fmask[i][1] ], norms[ fmask[i][1] ] ) ; + getEdgeIntersectionByIndex( node, femask[i][1], nst, len, pts[ fmask[i][1] ], norms[ fmask[i][1] ] ) ; + parity[ fmask[i][1] ] = 1 ; + } + } + } + + // 3 edge adjacent cubes + int emask[3] = {3, 7, 11} ; + int eemask[3] = {0, 1, 2} ; + for ( i = 0 ; i < 3 ; i ++ ) + { +// if ( getEdgeParity( leaf, emask[i] ) ) + { + int nst[3] = {st[0] + len, st[1] + len, st[2] + len} ; + nst[ i ] -= len ; + // int nstt[3] = {1, 1, 1} ; + // nstt[ i ] -= 1 ; + UCHAR* node = locateLeafCheck( nst ) ; + if ( node == NULL ) + { + continue ; + } + + if ( getStoredEdgesParity( node, eemask[i] ) ) + { + // getEdgeIntersectionByIndex( node, eemask[i], nstt, 1, pts[ emask[i] ], norms[ emask[i] ] ) ; + getEdgeIntersectionByIndex( node, eemask[i], nst, len, pts[ emask[i] ], norms[ emask[i] ] ) ; + parity[ emask[ i ] ] = 1 ; + } + } + } + } + + void fillEdgeOffsetsNormals( UCHAR* leaf, int st[3], int len, float pts[12], float norms[12][3], int parity[12] ) + { + int i ; + for ( i = 0 ; i < 12 ; i ++ ) + { + parity[ i ] = 0 ; + } + // int stt[3] = { 0, 0, 0 } ; + + // The three primal edges are easy + int pmask[3] = { 0, 4, 8 } ; + for ( i = 0 ; i < 3 ; i ++ ) + { + if ( getStoredEdgesParity( leaf, i ) ) + { + pts[ pmask[i] ] = getEdgeOffsetNormalByIndex( leaf, i, norms[ pmask[i] ] ) ; + parity[ pmask[i] ] = 1 ; + } + } + + // 3 face adjacent cubes + int fmask[3][2] = {{6,10},{2,9},{1,5}} ; + int femask[3][2] = {{1,2},{0,2},{0,1}} ; + for ( i = 0 ; i < 3 ; i ++ ) + { + { + int nst[3] = {st[0], st[1], st[2]} ; + nst[ i ] += len ; + // int nstt[3] = {0, 0, 0} ; + // nstt[ i ] += 1 ; + UCHAR* node = locateLeafCheck( nst ) ; + if ( node == NULL ) + { + continue ; + } + + int e1 = getStoredEdgesParity( node, femask[i][0] ) ; + int e2 = getStoredEdgesParity( node, femask[i][1] ) ; + + if ( e1 ) + { + pts[ fmask[i][0] ] = getEdgeOffsetNormalByIndex( node, femask[i][0], norms[ fmask[i][0] ] ) ; + parity[ fmask[i][0] ] = 1 ; + } + if ( e2 ) + { + pts[ fmask[i][1] ] = getEdgeOffsetNormalByIndex( node, femask[i][1], norms[ fmask[i][1] ] ) ; + parity[ fmask[i][1] ] = 1 ; + } + } + } + + // 3 edge adjacent cubes + int emask[3] = {3, 7, 11} ; + int eemask[3] = {0, 1, 2} ; + for ( i = 0 ; i < 3 ; i ++ ) + { +// if ( getEdgeParity( leaf, emask[i] ) ) + { + int nst[3] = {st[0] + len, st[1] + len, st[2] + len} ; + nst[ i ] -= len ; + // int nstt[3] = {1, 1, 1} ; + // nstt[ i ] -= 1 ; + UCHAR* node = locateLeafCheck( nst ) ; + if ( node == NULL ) + { + continue ; + } + + if ( getStoredEdgesParity( node, eemask[i] ) ) + { + pts[ emask[i] ] = getEdgeOffsetNormalByIndex( node, eemask[i], norms[ emask[i] ] ) ; + parity[ emask[ i ] ] = 1 ; + } + } + } + } + + + /// Update method + UCHAR* updateEdgeOffsetsNormals( UCHAR* leaf, int oldlen, int newlen, float offs[3], float a[3], float b[3], float c[3] ) + { + // First, create a new leaf node + UCHAR* nleaf = createLeaf( newlen ) ; + for ( int i = 0 ; i < leaf_node_bytes ; i ++ ) + { + nleaf[i] = leaf[i] ; + } + + // Next, fill in the offsets + setEdgeOffsetsNormals( nleaf, offs, a, b, c, newlen ) ; + + // Finally, delete the old leaf + removeLeaf( oldlen, leaf ) ; + + return nleaf ; + } +#endif + + /// Locate a leaf + /// WARNING: assuming this leaf already exists! + + UCHAR* locateLeaf( int st[3] ) + { + UCHAR* node = root ; + for ( int i = GRID_DIMENSION - 1 ; i > GRID_DIMENSION - maxDepth - 1 ; i -- ) + { + int index = ( ( ( st[0] >> i ) & 1 ) << 2 ) | + ( ( ( st[1] >> i ) & 1 ) << 1 ) | + ( ( ( st[2] >> i ) & 1 ) ) ; + node = getChild( node, getChildCount( node, index ) ) ; + } + + return node ; + } + + UCHAR* locateLeaf( UCHAR* node, int len, int st[3] ) + { + int index ; + for ( int i = len / 2 ; i >= mindimen ; i >>= 1 ) + { + index = ( ( ( st[0] & i ) ? 4 : 0 ) | + ( ( st[1] & i ) ? 2 : 0 ) | + ( ( st[2] & i ) ? 1 : 0 ) ) ; + node = getChild( node, getChildCount( node, index ) ) ; + } + + return node ; + } + UCHAR* locateLeafCheck( int st[3] ) + { + UCHAR* node = root ; + for ( int i = GRID_DIMENSION - 1 ; i > GRID_DIMENSION - maxDepth - 1 ; i -- ) + { + int index = ( ( ( st[0] >> i ) & 1 ) << 2 ) | + ( ( ( st[1] >> i ) & 1 ) << 1 ) | + ( ( ( st[2] >> i ) & 1 ) ) ; + if ( ! hasChild( node, index ) ) + { + return NULL ; + } + node = getChild( node, getChildCount( node, index ) ) ; + } + + return node ; + } + UCHAR* locateParent( int len, int st[3], int& count ) + { + UCHAR* node = root ; + UCHAR* pre = NULL ; + int index = 0 ; + for ( int i = dimen / 2 ; i >= len ; i >>= 1 ) + { + index = ( ( ( st[0] & i ) ? 4 : 0 ) | + ( ( st[1] & i ) ? 2 : 0 ) | + ( ( st[2] & i ) ? 1 : 0 ) ) ; + pre = node ; + node = getChild( node, getChildCount( node, index ) ) ; + } + + count = getChildCount( pre, index ) ; + return pre ; + } + UCHAR* locateParent( UCHAR* papa, int len, int st[3], int& count ) + { + UCHAR* node = papa ; + UCHAR* pre = NULL ; + int index = 0; + for ( int i = len / 2 ; i >= mindimen ; i >>= 1 ) + { + index = ( ( ( st[0] & i ) ? 4 : 0 ) | + ( ( st[1] & i ) ? 2 : 0 ) | + ( ( st[2] & i ) ? 1 : 0 ) ) ; + pre = node ; + node = getChild( node, getChildCount( node, index ) ) ; + } + + count = getChildCount( pre, index ) ; + return pre ; + } + /************ Operators for internal nodes ************/ + + /// Print the node information + void printNode( UCHAR* node ) + { + printf("Address: %p ", node ) ; + printf("Leaf Mask: ") ; + for ( int i = 0 ; i < 8 ; i ++ ) + { + printf( "%d ", isLeaf( node, i ) ) ; + } + printf("Child Mask: ") ; + for ( int i = 0 ; i < 8 ; i ++ ) + { + printf( "%d ", hasChild( node, i ) ) ; + } + printf("\n") ; + } + + /// Get size of an internal node + int getSize ( int length ) + { + return INTERNAL_NODE_BYTES + length * 4 ; + }; + + /// If child index exists + int hasChild( UCHAR* node, int index ) + { + return ( node[0] >> index ) & 1 ; + }; + + /// Test if child is leaf + int isLeaf ( UCHAR* node, int index ) + { + return ( node[1] >> index ) & 1 ; + }; + + /// Get the pointer to child index + UCHAR* getChild ( UCHAR* node, int count ) + { + return (( UCHAR ** ) ( node + INTERNAL_NODE_BYTES )) [ count ] ; + }; + + /// Get total number of children + int getNumChildren( UCHAR* node ) + { + return numChildrenTable[ node[0] ] ; + }; + + /// Get the count of children + int getChildCount( UCHAR* node, int index ) + { + return childrenCountTable[ node[0] ][ index ] ; + } + int getChildIndex( UCHAR* node, int count ) + { + return childrenIndexTable[ node[0] ][ count ] ; + } + int* getChildCounts( UCHAR* node ) + { + return childrenCountTable[ node[0] ] ; + } + + /// Get all children + void fillChildren( UCHAR* node, UCHAR* chd[ 8 ], int leaf[ 8 ] ) + { + int count = 0 ; + for ( int i = 0 ; i < 8 ; i ++ ) + { + leaf[ i ] = isLeaf( node, i ) ; + if ( hasChild( node, i ) ) + { + chd[ i ] = getChild( node, count ) ; + count ++ ; + } + else + { + chd[ i ] = NULL ; + leaf[ i ] = 0 ; + } + } + } + + /// Sets the child pointer + void setChild ( UCHAR* node, int count, UCHAR* chd ) + { + (( UCHAR ** ) ( node + INTERNAL_NODE_BYTES )) [ count ] = chd ; + } + void setInternalChild ( UCHAR* node, int index, int count, UCHAR* chd ) + { + setChild( node, count, chd ) ; + node[0] |= ( 1 << index ) ; + }; + void setLeafChild ( UCHAR* node, int index, int count, UCHAR* chd ) + { + setChild( node, count, chd ) ; + node[0] |= ( 1 << index ) ; + node[1] |= ( 1 << index ) ; + }; + + /// Add a kid to an existing internal node + /// Fix me: can we do this without wasting memory ? + /// Fixed: using variable memory + UCHAR* addChild( UCHAR* node, int index, UCHAR* chd, int aLeaf ) + { + // Create new internal node + int num = getNumChildren( node ) ; + UCHAR* rnode = createInternal( num + 1 ) ; + + // Establish children + int i ; + int count1 = 0, count2 = 0 ; + for ( i = 0 ; i < 8 ; i ++ ) + { + if ( i == index ) + { + if ( aLeaf ) + { + setLeafChild( rnode, i, count2, chd ) ; + } + else + { + setInternalChild( rnode, i, count2, chd ) ; + } + count2 ++ ; + } + else if ( hasChild( node, i ) ) + { + if ( isLeaf( node, i ) ) + { + setLeafChild( rnode, i, count2, getChild( node, count1 ) ) ; + } + else + { + setInternalChild( rnode, i, count2, getChild( node, count1 ) ) ; + } + count1 ++ ; + count2 ++ ; + } + } + + removeInternal( num, node ) ; + return rnode ; + } + + /// Allocate a node + UCHAR* createInternal( int length ) + { + UCHAR* inode = alloc[ length ]->allocate( ) ; + inode[0] = inode[1] = 0 ; + return inode ; + }; + UCHAR* createLeaf( int length ) + { + if ( length > 3 ) + { + printf("wierd"); + } + UCHAR* lnode = leafalloc[ length ]->allocate( ) ; + lnode[0] = lnode[1] = lnode[2] = 0 ; + + return lnode ; + }; + + void removeInternal ( int num, UCHAR* node ) + { + alloc[ num ]->deallocate( node ) ; + } + + void removeLeaf ( int num, UCHAR* leaf ) + { + if ( num > 3 || num < 0 ) + { + printf("wierd"); + } + leafalloc[ num ]->deallocate( leaf ) ; + } + + /// Add a leaf (by creating a new par node with the leaf added) + UCHAR* addLeafChild ( UCHAR* par, int index, int count, UCHAR* leaf ) + { + int num = getNumChildren( par ) + 1 ; + UCHAR* npar = createInternal( num ) ; + npar[0] = par[0] ; + npar[1] = par[1] ; + + if ( num == 1 ) + { + setLeafChild( npar, index, 0, leaf ) ; + } + else + { + int i ; + for ( i = 0 ; i < count ; i ++ ) + { + setChild( npar, i, getChild( par, i ) ) ; + } + setLeafChild( npar, index, count, leaf ) ; + for ( i = count + 1 ; i < num ; i ++ ) + { + setChild( npar, i, getChild( par, i - 1 ) ) ; + } + } + + removeInternal( num-1, par ) ; + return npar ; + }; + + UCHAR* addInternalChild ( UCHAR* par, int index, int count, UCHAR* node ) + { + int num = getNumChildren( par ) + 1 ; + UCHAR* npar = createInternal( num ) ; + npar[0] = par[0] ; + npar[1] = par[1] ; + + if ( num == 1 ) + { + setInternalChild( npar, index, 0, node ) ; + } + else + { + int i ; + for ( i = 0 ; i < count ; i ++ ) + { + setChild( npar, i, getChild( par, i ) ) ; + } + setInternalChild( npar, index, count, node ) ; + for ( i = count + 1 ; i < num ; i ++ ) + { + setChild( npar, i, getChild( par, i - 1 ) ) ; + } + } + + removeInternal( num-1, par ) ; + return npar ; + }; +}; + + + +#endif diff -Nru blender-2.61/intern/dualcon/intern/Projections.cpp blender-2.62/intern/dualcon/intern/Projections.cpp --- blender-2.61/intern/dualcon/intern/Projections.cpp 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/intern/dualcon/intern/Projections.cpp 2012-02-15 19:24:40.000000000 +0000 @@ -0,0 +1,76 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + * Contributor(s): Tao Ju + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#include "Projections.h" + +const int vertmap[8][3] = { + {0, 0, 0}, + {0, 0, 1}, + {0, 1, 0}, + {0, 1, 1}, + {1, 0, 0}, + {1, 0, 1}, + {1, 1, 0}, + {1, 1, 1} +}; + +const int centmap[3][3][3][2] = { + {{{0, 0}, {0, 1}, {1, 1}}, + {{0, 2}, {0, 3}, {1, 3}}, + {{2, 2}, {2, 3}, {3, 3}} + }, + + {{{0, 4}, {0, 5}, {1, 5}}, + {{0, 6}, {0, 7}, {1, 7}}, + {{2, 6}, {2, 7}, {3, 7}} + }, + + {{{4, 4}, {4, 5}, {5, 5}}, + {{4, 6}, {4, 7}, {5, 7}}, + {{6, 6}, {6, 7}, {7, 7}} + } +}; + +const int edgemap[12][2] = { + {0, 4}, + {1, 5}, + {2, 6}, + {3, 7}, + {0, 2}, + {1, 3}, + {4, 6}, + {5, 7}, + {0, 1}, + {2, 3}, + {4, 5}, + {6, 7} +}; + +const int facemap[6][4] = { + {0, 1, 2, 3}, + {4, 5, 6, 7}, + {0, 1, 4, 5}, + {2, 3, 6, 7}, + {0, 2, 4, 6}, + {1, 3, 5, 7} +}; diff -Nru blender-2.61/intern/dualcon/intern/Projections.h blender-2.62/intern/dualcon/intern/Projections.h --- blender-2.61/intern/dualcon/intern/Projections.h 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/intern/dualcon/intern/Projections.h 2012-02-15 19:24:40.000000000 +0000 @@ -0,0 +1,845 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + * Contributor(s): Tao Ju + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef PROJECTIONS_H +#define PROJECTIONS_H + +#include +#include + +#define CONTAINS_INDEX +#define GRID_DIMENSION 20 + +#if defined(_WIN32) && !defined(__MINGW32__) +#define LONG __int64 +#else +#include +#define LONG int64_t +#endif +#define UCHAR unsigned char + +/** + * Structures and classes for computing projections of triangles + * onto separating axes during scan conversion + * + * @author Tao Ju + */ + + +extern const int vertmap[8][3]; +extern const int centmap[3][3][3][2]; +extern const int edgemap[12][2]; +extern const int facemap[6][4]; + +/** + * Structure for the projections inheritable from parent + */ +struct InheritableProjections +{ + /// Projections of triangle + LONG trigProj[13][2] ; + + /// Projections of triangle vertices on primary axes + LONG trigVertProj[13][3] ; + + /// Projections of triangle edges + LONG trigEdgeProj[13][3][2] ; + + /// Normal of the triangle + double norm[3] ; + double normA, normB ; + + /// End points along each axis + //int cubeEnds[13][2] ; + + /// Error range on each axis + /// LONG errorProj[13]; + +#ifdef CONTAINS_INDEX + /// Index of polygon + int index ; +#endif +}; + + +/** + * Class for projections of cube / triangle vertices on the separating axes + */ +class Projections +{ +public: + /// Inheritable portion + InheritableProjections* inherit ; + + /// Projections of the cube vertices + LONG cubeProj[13][6] ; + +public: + + Projections( ) + { + } + + /** + * Construction + * from a cube (axes aligned) and triangle + */ + Projections( LONG cube[2][3], LONG trig[3][3], LONG error, int triind ) + { + int i, j ; + inherit = new InheritableProjections ; +#ifdef CONTAINS_INDEX + inherit->index = triind ; +#endif + /// Create axes + LONG axes[13][3] ; + + // Cube faces + axes[0][0] = 1 ; + axes[0][1] = 0 ; + axes[0][2] = 0 ; + + axes[1][0] = 0 ; + axes[1][1] = 1 ; + axes[1][2] = 0 ; + + axes[2][0] = 0 ; + axes[2][1] = 0 ; + axes[2][2] = 1 ; + + // Triangle face + LONG trigedge[3][3] ; + for ( i = 0 ; i < 3 ; i ++ ) + { + for ( j = 0 ; j < 3 ; j ++ ) + { + trigedge[i][j] = trig[(i+1)%3][j] - trig[i][j] ; + } + } + crossProduct( trigedge[0], trigedge[1], axes[3] ) ; + + /// Normalize face normal and store + double dedge1[] = { (double) trig[1][0] - (double) trig[0][0], + (double) trig[1][1] - (double) trig[0][1], + (double) trig[1][2] - (double) trig[0][2] } ; + double dedge2[] = { (double) trig[2][0] - (double) trig[1][0], + (double) trig[2][1] - (double) trig[1][1], + (double) trig[2][2] - (double) trig[1][2] } ; + crossProduct( dedge1, dedge2, inherit->norm ) ; + normalize( inherit->norm ) ; +// inherit->normA = norm[ 0 ] ; +// inherit->normB = norm[ 2 ] > 0 ? norm[ 1 ] : 2 + norm[ 1 ] ; + + // Face edges and triangle edges + int ct = 4 ; + for ( i = 0 ; i < 3 ; i ++ ) + for ( j = 0 ; j < 3 ; j ++ ) + { + crossProduct( axes[j], trigedge[i], axes[ct] ) ; + ct ++ ; + } + + /// Generate projections + LONG cubeedge[3][3] ; + for ( i = 0 ; i < 3 ; i ++ ) + { + for ( j = 0 ; j < 3 ; j ++ ) + { + cubeedge[i][j] = 0 ; + } + cubeedge[i][i] = cube[1][i] - cube[0][i] ; + } + + for ( j = 0 ; j < 13 ; j ++ ) + { + // Origin + cubeProj[j][0] = dotProduct( axes[j], cube[0] ) ; + + // 3 direction vectors + for ( i = 1 ; i < 4 ; i ++ ) + { + cubeProj[j][i] = dotProduct( axes[j], cubeedge[i-1] ) ; + } + + // Offsets of 2 ends of cube projection + LONG max = 0 ; + LONG min = 0 ; + for ( i = 1 ; i < 8 ; i ++ ) + { + LONG proj = vertmap[i][0] * cubeProj[j][1] + vertmap[i][1] * cubeProj[j][2] + vertmap[i][2] * cubeProj[j][3] ; + if ( proj > max ) + { + max = proj ; + } + if ( proj < min ) + { + min = proj ; + } + } + cubeProj[j][4] = min ; + cubeProj[j][5] = max ; + + } + + for ( j = 0 ; j < 13 ; j ++ ) + { + LONG vts[3] = { dotProduct( axes[j], trig[0] ), + dotProduct( axes[j], trig[1] ), + dotProduct( axes[j], trig[2] ) } ; + + // Vertex + inherit->trigVertProj[j][0] = vts[0] ; + inherit->trigVertProj[j][1] = vts[1] ; + inherit->trigVertProj[j][2] = vts[2] ; + + // Edge + for ( i = 0 ; i < 3 ; i ++ ) + { + if ( vts[i] < vts[(i+1) % 3] ) + { + inherit->trigEdgeProj[j][i][0] = vts[i] ; + inherit->trigEdgeProj[j][i][1] = vts[(i+1) % 3] ; + } + else + { + inherit->trigEdgeProj[j][i][1] = vts[i] ; + inherit->trigEdgeProj[j][i][0] = vts[(i+1) % 3] ; + } + } + + // Triangle + inherit->trigProj[j][0] = vts[0] ; + inherit->trigProj[j][1] = vts[0] ; + for ( i = 1 ; i < 3 ; i ++ ) + { + if ( vts[i] < inherit->trigProj[j][0] ) + { + inherit->trigProj[j][0] = vts[i] ; + } + if ( vts[i] > inherit->trigProj[j][1] ) + { + inherit->trigProj[j][1] = vts[i] ; + } + } + } + + } + + /** + * Construction + * from a parent Projections object and the index of the children + */ + Projections ( Projections* parent ) + { + // Copy inheritable projections + this->inherit = parent->inherit ; + + // Shrink cube projections + for ( int i = 0 ; i < 13 ; i ++ ) + { + cubeProj[i][0] = parent->cubeProj[i][0] ; + for ( int j = 1 ; j < 6 ; j ++ ) + { + cubeProj[i][j] = parent->cubeProj[i][j] >> 1 ; + } + } + }; + + Projections ( Projections* parent, int box[3], int depth ) + { + int mask = ( 1 << depth ) - 1 ; + int nbox[3] = { box[0] & mask, box[1] & mask, box[2] & mask } ; + + // Copy inheritable projections + this->inherit = parent->inherit ; + + // Shrink cube projections + for ( int i = 0 ; i < 13 ; i ++ ) + { + for ( int j = 1 ; j < 6 ; j ++ ) + { + cubeProj[i][j] = parent->cubeProj[i][j] >> depth ; + } + + cubeProj[i][0] = parent->cubeProj[i][0] + nbox[0] * cubeProj[i][1] + nbox[1] * cubeProj[i][2] + nbox[2] * cubeProj[i][3] ; + } + }; + + /** + * Testing intersection based on vertex/edge masks + */ + int getIntersectionMasks( UCHAR cedgemask, UCHAR& edgemask ) + { + int i, j ; + edgemask = cedgemask ; + + // Pre-processing + /* + if ( cvertmask & 1 ) + { + edgemask |= 5 ; + } + if ( cvertmask & 2 ) + { + edgemask |= 3 ; + } + if ( cvertmask & 4 ) + { + edgemask |= 6 ; + } + + */ + + // Test axes for edge intersection + UCHAR bit = 1 ; + for ( j = 0 ; j < 3 ; j ++ ) + { + if ( edgemask & bit ) + { + for ( i = 0 ; i < 13 ; i ++ ) + { + LONG proj0 = cubeProj[i][0] + cubeProj[i][4] ; + LONG proj1 = cubeProj[i][0] + cubeProj[i][5] ; + + if ( proj0 > inherit->trigEdgeProj[i][j][1] || + proj1 < inherit->trigEdgeProj[i][j][0] ) + { + edgemask &= ( ~ bit ) ; + break ; + } + } + } + bit <<= 1 ; + } + + /* + if ( edgemask != 0 ) + { + printf("%d %d\n", cedgemask, edgemask) ; + } + */ + + // Test axes for triangle intersection + if ( edgemask ) + { + return 1 ; + } + + for ( i = 3 ; i < 13 ; i ++ ) + { + LONG proj0 = cubeProj[i][0] + cubeProj[i][4] ; + LONG proj1 = cubeProj[i][0] + cubeProj[i][5] ; + + if ( proj0 > inherit->trigProj[i][1] || + proj1 < inherit->trigProj[i][0] ) + { + return 0 ; + } + } + + return 1 ; + } + + /** + * Retrieving children masks using PRIMARY AXES + */ + UCHAR getChildrenMasks( UCHAR cvertmask, UCHAR vertmask[8] ) + { + int i, j, k ; + int bmask[3][2] = {{0,0},{0,0},{0,0}} ; + int vmask[3][3][2] = {{{0,0},{0,0},{0,0}},{{0,0},{0,0},{0,0}},{{0,0},{0,0},{0,0}}} ; + UCHAR boxmask = 0 ; + LONG len = cubeProj[0][1] >> 1 ; + + for ( i = 0 ; i < 3 ; i ++ ) + { + LONG mid = cubeProj[i][0] + len ; + + // Check bounding box + if ( mid >= inherit->trigProj[i][0] ) + { + bmask[i][0] = 1 ; + } + if ( mid <= inherit->trigProj[i][1] ) + { + bmask[i][1] = 1 ; + } + + // Check vertex mask + if ( cvertmask ) + { + for ( j = 0 ; j < 3 ; j ++ ) + { + if ( cvertmask & ( 1 << j ) ) + { + // Only check if it's contained this node + if ( mid >= inherit->trigVertProj[i][j] ) + { + vmask[i][j][0] = 1 ; + } + if ( mid <= inherit->trigVertProj[i][j] ) + { + vmask[i][j][1] = 1 ; + } + } + } + } + + /* + // Check edge mask + if ( cedgemask ) + { + for ( j = 0 ; j < 3 ; j ++ ) + { + if ( cedgemask & ( 1 << j ) ) + { + // Only check if it's contained this node + if ( mid >= inherit->trigEdgeProj[i][j][0] ) + { + emask[i][j][0] = 1 ; + } + if ( mid <= inherit->trigEdgeProj[i][j][1] ) + { + emask[i][j][1] = 1 ; + } + } + } + } + */ + + } + + // Fill in masks + int ct = 0 ; + for ( i = 0 ; i < 2 ; i ++ ) + for ( j = 0 ; j < 2 ; j ++ ) + for ( k = 0 ; k < 2 ; k ++ ) + { + boxmask |= ( ( bmask[0][i] & bmask[1][j] & bmask[2][k] ) << ct ) ; + vertmask[ct] = (( vmask[0][0][i] & vmask[1][0][j] & vmask[2][0][k] ) | + (( vmask[0][1][i] & vmask[1][1][j] & vmask[2][1][k] ) << 1 ) | + (( vmask[0][2][i] & vmask[1][2][j] & vmask[2][2][k] ) << 2 ) ) ; + /* + edgemask[ct] = (( emask[0][0][i] & emask[1][0][j] & emask[2][0][k] ) | + (( emask[0][1][i] & emask[1][1][j] & emask[2][1][k] ) << 1 ) | + (( emask[0][2][i] & emask[1][2][j] & emask[2][2][k] ) << 2 ) ) ; + edgemask[ct] = cedgemask ; + */ + ct ++ ; + } + + // Return bounding box masks + return boxmask ; + } + + UCHAR getBoxMask( ) + { + int i, j, k ; + int bmask[3][2] = {{0,0},{0,0},{0,0}} ; + UCHAR boxmask = 0 ; + LONG len = cubeProj[0][1] >> 1 ; + + for ( i = 0 ; i < 3 ; i ++ ) + { + LONG mid = cubeProj[i][0] + len ; + + // Check bounding box + if ( mid >= inherit->trigProj[i][0] ) + { + bmask[i][0] = 1 ; + } + if ( mid <= inherit->trigProj[i][1] ) + { + bmask[i][1] = 1 ; + } + + } + + // Fill in masks + int ct = 0 ; + for ( i = 0 ; i < 2 ; i ++ ) + for ( j = 0 ; j < 2 ; j ++ ) + for ( k = 0 ; k < 2 ; k ++ ) + { + boxmask |= ( ( bmask[0][i] & bmask[1][j] & bmask[2][k] ) << ct ) ; + ct ++ ; + } + + // Return bounding box masks + return boxmask ; + } + + + /** + * Get projections for sub-cubes (simple axes) + */ + void getSubProjectionsSimple( Projections* p[8] ) + { + // Process the axes cooresponding to the triangle's normal + int ind = 3 ; + LONG len = cubeProj[ 0 ][ 1 ] >> 1 ; + LONG trigproj[3] = { cubeProj[ ind ][ 1 ] >> 1, cubeProj[ ind ][ 2 ] >> 1, cubeProj[ ind ][ 3 ] >> 1 } ; + + int ct = 0 ; + for ( int i = 0 ; i < 2 ; i ++ ) + for ( int j = 0 ; j < 2 ; j ++ ) + for ( int k = 0 ; k < 2 ; k ++ ) + { + p[ct] = new Projections( ) ; + p[ct]->inherit = inherit ; + + p[ct]->cubeProj[ 0 ][ 0 ] = cubeProj[ 0 ][ 0 ] + i * len ; + p[ct]->cubeProj[ 1 ][ 0 ] = cubeProj[ 1 ][ 0 ] + j * len ; + p[ct]->cubeProj[ 2 ][ 0 ] = cubeProj[ 2 ][ 0 ] + k * len ; + p[ct]->cubeProj[ 0 ][ 1 ] = len ; + + for ( int m = 1 ; m < 4 ; m ++ ) + { + p[ct]->cubeProj[ ind ][ m ] = trigproj[ m - 1 ] ; + } + p[ct]->cubeProj[ ind ][ 0 ] = cubeProj[ ind ][0] + i * trigproj[0] + j * trigproj[1] + k * trigproj[2] ; + + ct ++ ; + } + } + + /** + * Shifting a cube to a new origin + */ + void shift ( int off[3] ) + { + for ( int i = 0 ; i < 13 ; i ++ ) + { + cubeProj[i][0] += off[0] * cubeProj[i][1] + off[1] * cubeProj[i][2] + off[2] * cubeProj[i][3] ; + } + } + + void shiftNoPrimary ( int off[3] ) + { + for ( int i = 3 ; i < 13 ; i ++ ) + { + cubeProj[i][0] += off[0] * cubeProj[i][1] + off[1] * cubeProj[i][2] + off[2] * cubeProj[i][3] ; + } + } + + /** + * Method to test intersection of the triangle and the cube + */ + int isIntersecting ( ) + { + for ( int i = 0 ; i < 13 ; i ++ ) + { + /* + LONG proj0 = cubeProj[i][0] + + vertmap[inherit->cubeEnds[i][0]][0] * cubeProj[i][1] + + vertmap[inherit->cubeEnds[i][0]][1] * cubeProj[i][2] + + vertmap[inherit->cubeEnds[i][0]][2] * cubeProj[i][3] ; + LONG proj1 = cubeProj[i][0] + + vertmap[inherit->cubeEnds[i][1]][0] * cubeProj[i][1] + + vertmap[inherit->cubeEnds[i][1]][1] * cubeProj[i][2] + + vertmap[inherit->cubeEnds[i][1]][2] * cubeProj[i][3] ; + */ + + LONG proj0 = cubeProj[i][0] + cubeProj[i][4] ; + LONG proj1 = cubeProj[i][0] + cubeProj[i][5] ; + + if ( proj0 > inherit->trigProj[i][1] || + proj1 < inherit->trigProj[i][0] ) + { + return 0 ; + } + } + + return 1 ; + }; + + int isIntersectingNoPrimary ( ) + { + for ( int i = 3 ; i < 13 ; i ++ ) + { + /* + LONG proj0 = cubeProj[i][0] + + vertmap[inherit->cubeEnds[i][0]][0] * cubeProj[i][1] + + vertmap[inherit->cubeEnds[i][0]][1] * cubeProj[i][2] + + vertmap[inherit->cubeEnds[i][0]][2] * cubeProj[i][3] ; + LONG proj1 = cubeProj[i][0] + + vertmap[inherit->cubeEnds[i][1]][0] * cubeProj[i][1] + + vertmap[inherit->cubeEnds[i][1]][1] * cubeProj[i][2] + + vertmap[inherit->cubeEnds[i][1]][2] * cubeProj[i][3] ; + */ + + LONG proj0 = cubeProj[i][0] + cubeProj[i][4] ; + LONG proj1 = cubeProj[i][0] + cubeProj[i][5] ; + + if ( proj0 > inherit->trigProj[i][1] || + proj1 < inherit->trigProj[i][0] ) + { + return 0 ; + } + } + + return 1 ; + }; + + /** + * Method to test intersection of the triangle and one edge + */ + int isIntersecting ( int edgeInd ) + { + for ( int i = 0 ; i < 13 ; i ++ ) + { + + LONG proj0 = cubeProj[i][0] + + vertmap[edgemap[edgeInd][0]][0] * cubeProj[i][1] + + vertmap[edgemap[edgeInd][0]][1] * cubeProj[i][2] + + vertmap[edgemap[edgeInd][0]][2] * cubeProj[i][3] ; + LONG proj1 = cubeProj[i][0] + + vertmap[edgemap[edgeInd][1]][0] * cubeProj[i][1] + + vertmap[edgemap[edgeInd][1]][1] * cubeProj[i][2] + + vertmap[edgemap[edgeInd][1]][2] * cubeProj[i][3] ; + + + if ( proj0 < proj1 ) + { + if ( proj0 > inherit->trigProj[i][1] || + proj1 < inherit->trigProj[i][0] ) + { + return 0 ; + } + } + else + { + if ( proj1 > inherit->trigProj[i][1] || + proj0 < inherit->trigProj[i][0] ) + { + return 0 ; + } + } + } + + // printf( "Intersecting: %d %d\n", edgemap[edgeInd][0], edgemap[edgeInd][1] ) ; + return 1 ; + }; + + /** + * Method to test intersection of one triangle edge and one cube face + */ + int isIntersecting ( int edgeInd, int faceInd ) + { + for ( int i = 0 ; i < 13 ; i ++ ) + { + LONG trigproj0 = inherit->trigVertProj[i][edgeInd] ; + LONG trigproj1 = inherit->trigVertProj[i][(edgeInd+1)%3] ; + + if ( trigproj0 < trigproj1 ) + { + int t1 = 1 , t2 = 1 ; + for ( int j = 0 ; j < 4 ; j ++ ) + { + LONG proj = cubeProj[i][0] + + vertmap[facemap[faceInd][j]][0] * cubeProj[i][1] + + vertmap[facemap[faceInd][j]][1] * cubeProj[i][2] + + vertmap[facemap[faceInd][j]][2] * cubeProj[i][3] ; + if ( proj >= trigproj0 ) + { + t1 = 0 ; + } + if ( proj <= trigproj1 ) + { + t2 = 0 ; + } + } + if ( t1 || t2 ) + { + return 0 ; + } + } + else + { + int t1 = 1 , t2 = 1 ; + for ( int j = 0 ; j < 4 ; j ++ ) + { + LONG proj = cubeProj[i][0] + + vertmap[facemap[faceInd][j]][0] * cubeProj[i][1] + + vertmap[facemap[faceInd][j]][1] * cubeProj[i][2] + + vertmap[facemap[faceInd][j]][2] * cubeProj[i][3] ; + if ( proj >= trigproj1 ) + { + t1 = 0 ; + } + if ( proj <= trigproj0 ) + { + t2 = 0 ; + } + } + if ( t1 || t2 ) + { + return 0 ; + } + } + } + + return 1 ; + }; + + + int isIntersectingPrimary ( int edgeInd ) + { + for ( int i = 0 ; i < 13 ; i ++ ) + { + + LONG proj0 = cubeProj[i][0] ; + LONG proj1 = cubeProj[i][0] + cubeProj[i][edgeInd + 1] ; + + if ( proj0 < proj1 ) + { + if ( proj0 > inherit->trigProj[i][1] || + proj1 < inherit->trigProj[i][0] ) + { + return 0 ; + } + } + else + { + if ( proj1 > inherit->trigProj[i][1] || + proj0 < inherit->trigProj[i][0] ) + { + return 0 ; + } + } + + } + + // printf( "Intersecting: %d %d\n", edgemap[edgeInd][0], edgemap[edgeInd][1] ) ; + return 1 ; + }; + + double getIntersection ( int edgeInd ) + { + int i = 3 ; + + LONG proj0 = cubeProj[i][0] + + vertmap[edgemap[edgeInd][0]][0] * cubeProj[i][1] + + vertmap[edgemap[edgeInd][0]][1] * cubeProj[i][2] + + vertmap[edgemap[edgeInd][0]][2] * cubeProj[i][3] ; + LONG proj1 = cubeProj[i][0] + + vertmap[edgemap[edgeInd][1]][0] * cubeProj[i][1] + + vertmap[edgemap[edgeInd][1]][1] * cubeProj[i][2] + + vertmap[edgemap[edgeInd][1]][2] * cubeProj[i][3] ; + LONG proj2 = inherit->trigProj[i][1] ; + + /* + if ( proj0 < proj1 ) + { + if ( proj2 < proj0 || proj2 > proj1 ) + { + return -1 ; + } + } + else + { + if ( proj2 < proj1 || proj2 > proj0 ) + { + return -1 ; + } + } + */ + + double alpha = (double)( proj2 - proj0 ) / (double)( proj1 - proj0 ) ; + /* + if ( alpha < 0 ) + { + alpha = 0.5 ; + } + else if ( alpha > 1 ) + { + alpha = 0.5 ; + } + */ + + return alpha ; + }; + + float getIntersectionPrimary ( int edgeInd ) + { + int i = 3 ; + + + LONG proj0 = cubeProj[i][0] ; + LONG proj1 = cubeProj[i][0] + cubeProj[i][edgeInd + 1] ; + LONG proj2 = inherit->trigProj[i][1] ; + + // double alpha = (double)( ( proj2 - proj0 ) * cubeProj[edgeInd][edgeInd + 1] ) / (double)( proj1 - proj0 ) ; + double alpha = (double)( ( proj2 - proj0 ) ) / (double)( proj1 - proj0 ) ; + + if ( alpha < 0 ) + { + alpha = 0.5 ; + } + else if ( alpha > 1 ) + { + alpha = 0.5 ; + } + + + return (float)alpha ; + }; + + /** + * Method to perform cross-product + */ + void crossProduct ( LONG a[3], LONG b[3], LONG res[3] ) + { + res[0] = a[1] * b[2] - a[2] * b[1] ; + res[1] = a[2] * b[0] - a[0] * b[2] ; + res[2] = a[0] * b[1] - a[1] * b[0] ; + } + void crossProduct ( double a[3], double b[3], double res[3] ) + { + res[0] = a[1] * b[2] - a[2] * b[1] ; + res[1] = a[2] * b[0] - a[0] * b[2] ; + res[2] = a[0] * b[1] - a[1] * b[0] ; + } + + /** + * Method to perform dot product + */ + LONG dotProduct ( LONG a[3], LONG b[3] ) + { + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] ; + } + + void normalize( double a[3] ) + { + double mag = a[0] * a[0] + a[1] * a[1] + a[2] * a[2] ; + if ( mag > 0 ) + { + mag = sqrt( mag ) ; + a[0] /= mag ; + a[1] /= mag ; + a[2] /= mag ; + } + } + +}; + +#endif diff -Nru blender-2.61/intern/dualcon/intern/Queue.h blender-2.62/intern/dualcon/intern/Queue.h --- blender-2.61/intern/dualcon/intern/Queue.h 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/intern/dualcon/intern/Queue.h 2012-02-15 19:24:40.000000000 +0000 @@ -0,0 +1,110 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + * Contributor(s): Tao Ju + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef QUEUE_H +#define QUEUE_H + +struct gridQueueEle +{ + int x, y, z; + UCHAR dir ; + gridQueueEle* next ; +}; + +class GridQueue +{ + gridQueueEle* head ; + gridQueueEle* tail ; + int numEles ; + +public: + + GridQueue( ) + { + head = NULL ; + tail = NULL ; + numEles = 0 ; + } + + gridQueueEle* getHead( ) + { + return head ; + } + + int getNumElements( ) + { + return numEles ; + } + + + void pushQueue( int st[3], int dir ) + { + gridQueueEle* ele = new gridQueueEle ; + ele->x = st[0] ; + ele->y = st[1] ; + ele->z = st[2] ; + ele->dir = (UCHAR) dir ; + ele->next = NULL ; + if ( head == NULL ) + { + head = ele ; + } + else + { + tail->next = ele ; + } + tail = ele ; + numEles ++ ; + } + + int popQueue( int st[3], int& dir ) + { + if ( head == NULL ) + { + return 0 ; + } + + st[0] = head->x ; + st[1] = head->y ; + st[2] = head->z ; + dir = (int) (head->dir) ; + + gridQueueEle* temp = head ; + head = head->next ; + delete temp ; + + if ( head == NULL ) + { + tail = NULL ; + } + numEles -- ; + + return 1 ; + } + +}; + + + + + +#endif diff -Nru blender-2.61/intern/dualcon/intern/readme.txt blender-2.62/intern/dualcon/intern/readme.txt --- blender-2.61/intern/dualcon/intern/readme.txt 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/intern/dualcon/intern/readme.txt 2012-02-15 19:24:40.000000000 +0000 @@ -0,0 +1,112 @@ +PolyMender program for robustly repairing a polygonal model. + +Author: Tao Ju (jutao@cs.wustl.edu) + +Version: 1.6 (Updated: Oct. 12, 2006) + +Platform: Windows + + +I. What's new in v1.6: + + +> Removal of disconnected components + +> Topologically manifold dual contouring + +> Output signed octree with geometry + + + +II. Introduction + + +PolyMender is based on the algorithm presented in the paper "Robust Repair of Polygonal Models" (SIGGRAPH 2004). The program reads in a polygonal model (i.e., a bag of polygons) and produces a closed surface that approximates the original model. PolyMender consumes a small amount of time and memory space, and can accurately reproduce the original geometry. PolyMender is suitable for repairing CAD models and gigantic polygonal models. Alternatively, PolyMender can also be used to generate a signed volume from any polygonal models. + + + +III. How to run + + +The executable package contains three programs: + +1. PolyMender, PolyMender-clean + +Purpose: repairs general purpose models, such as those created from range scanners. The repaired surface is constructed using Marching Cubes. Consumes minimal memory and time and generates closed, manifold triangular surfaces. The -clean option removes isolated pieces. + +2. PolyMender-qd, PolyMender-qd-clean + +Purpose: same as PolyMender and PolyMender-clean, but outputs a quad-mesh. + +3. PolyMender-dc, PolyMender-dc-clean + +Purpose: repairs models containing sharp features, such as CAD models. The repaired surface is constructed using Dual Contouring with a manifold topology, which is capable of reproducing sharp edges and corners. However, more memory is required. Generates closed triangular and quadrilateral surfaces. The -clean option removes isolated pieces. + + +Type the program names (e.g., PolyMender) on the DOS prompt and you will see their usages: + +Usage: PolyMender + +Example: PolyMender bunny.ply 6 0.9 closedbunny.ply + +Description: + + Polygonal file of format STL (binary only), ASC, or PLY. + + Integer depth of octree. The dimension of the volumetric + grid is 2^ on each side. + + Floating point number between 0 and 1 denoting the ratio of + the largest dimension of the model over the size of the grid. + + Output in polygonal format PLY or signed-octree format SOF (or SOG). + + +Additional notes: + +1. STL(binary) is preferred input format, since the program does not need to store the model in memory at all. ASC or PLY formats require additional storage of vertices, due to their topology-geometry file structure. + +2. The running time and memory consumption of the program depends on several factors: the number of input polygons, the depth of the octree, and the surface area of the model (hence the number of leaf nodes on the octree). To give an idea, processing the David model with 56 million triangles at depth 13 takes 45 minutes using 500 MB RAM (excluding the mem allocated for storing vertices when reading PLY format) on a PC with AMD 1.5Hz CPU. + +3. The number of output polygons can be finely controlled using the scale argument. The large the scale, the more polygons are generated, since the model occupies a larger portion of the volume grid. + +4. As an alternative of output repaired models, the intermediate signed octree can be generated as a SOF or SOG file. The signed octree can be used for generating signed distance field, extracting isosurfaces, or multiresolution spatial representation of the polygonal model. + + +IV SOF format + +SOF (Signed Octree Format) records an octree grid with signes attached to the 8 corners of each leaf node. All leaf nodes appear at the same depth that is specified by the argument to the program. The tree is recorded in SOF file using pre-order traversal. Here is the structure of a SOF file (binary): + +
+ + + +
is a 4-bytes integer that equals 2 ^ octree_depth. The first byte of a is either 0 (denoting an intermediate node) or 1 (denoting an empty node) or 2 (denoting a leaf node). After the first byte, an intermediate node contains (after the first byte) eight structures for its eight children; an empty node contains one byte of value 0 or 1 denoting if it is inside or outside; and a leaf node contains one byte whose eight bits correspond to the signs at its eight corners (0 for inside and 1 for outside). The order of enumeration of the eight children nodes in an intermediate nodeis the following (expressed in coordinates ): <0,0,0>,<0,0,1>,<0,1,0>,<0,1,1>,<1,0,0>,<1,0,1>,<1,1,0>,<1,1,1>. The enumeration of the eight corners in a leaf node follows the same order (e.g., the lowest bit records the sign at <0,0,0>). + + + +V SOG format + +SOF (Signed Octree with Geometry) has the same data structure with SOG, with the addition of following features: + +1. The file starts with a 128-byte long header. Currently, the header begins with the string "SOG.Format 1.0" followed by 3 floats representing the lower-left-near corner of the octree follwed by 1 float denoting the length of the octree (in one direction). The locations and lengths are in the input model's coordinate space. The rest of the header is left empty. + +2. Each leaf node has additioanl three floats {x,y,z} (following the signs) denoting the geometric location of a feature vertex within the cell. + + + +VI Test data + +Three models are included in the testmodels package. (Suggested arguments are provided in the parathesis). + +bunny.ply (octree depth: 7, scale: 0.9) + +- The Stanford Bunny (containing big holes at the bottom) + +horse.stl (octree depth: 8, scale: 0.9) + +- The horse model with 1/3 of all polygons removed and vertices randomly perturbed. + +mechanic.asc (octree depth: 6, scale: 0.9) + +- A mechanic part with hanging triangles diff -Nru blender-2.61/intern/dualcon/SConscript blender-2.62/intern/dualcon/SConscript --- blender-2.61/intern/dualcon/SConscript 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/intern/dualcon/SConscript 2012-02-15 19:24:40.000000000 +0000 @@ -0,0 +1,9 @@ +#!/usr/bin/python +Import ('env') + +sources = env.Glob('intern/*.cpp') + +incs = '. ../../extern/Eigen3' +defs = '' + +env.BlenderLib ('bf_intern_dualcon', sources, Split(incs), Split(defs), libtype=['intern'], priority=[100] ) diff -Nru blender-2.61/intern/elbeem/intern/ntl_vector3dim.h blender-2.62/intern/elbeem/intern/ntl_vector3dim.h --- blender-2.61/intern/elbeem/intern/ntl_vector3dim.h 2011-12-13 19:42:21.000000000 +0000 +++ blender-2.62/intern/elbeem/intern/ntl_vector3dim.h 2012-02-15 19:26:31.000000000 +0000 @@ -27,6 +27,12 @@ #include #include +/* absolute value */ +template < class T > +inline T +ABS( T a ) +{ return (0 < a) ? a : -a ; } + // hack for MSVC6.0 compiler #ifdef _MSC_VER #if _MSC_VER < 1300 diff -Nru blender-2.61/intern/elbeem/intern/utilities.h blender-2.62/intern/elbeem/intern/utilities.h --- blender-2.61/intern/elbeem/intern/utilities.h 2011-12-13 19:42:21.000000000 +0000 +++ blender-2.62/intern/elbeem/intern/utilities.h 2012-02-15 19:26:31.000000000 +0000 @@ -177,12 +177,6 @@ MAX( T a, T b ) { return (a < b) ? b : a ; } -/* absolute value */ -template < class T > -inline T -ABS( T a ) -{ return (0 < a) ? a : -a ; } - /* sign of the value */ template < class T > inline T diff -Nru blender-2.61/intern/ffmpeg/ffmpeg_compat.h blender-2.62/intern/ffmpeg/ffmpeg_compat.h --- blender-2.61/intern/ffmpeg/ffmpeg_compat.h 2011-12-13 19:42:45.000000000 +0000 +++ blender-2.62/intern/ffmpeg/ffmpeg_compat.h 2012-02-15 19:26:59.000000000 +0000 @@ -35,6 +35,7 @@ #include #include +#include #if (LIBAVFORMAT_VERSION_MAJOR > 52) || ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 101)) #define FFMPEG_HAVE_PARSE_UTILS 1 diff -Nru blender-2.61/intern/ghost/CMakeLists.txt blender-2.62/intern/ghost/CMakeLists.txt --- blender-2.61/intern/ghost/CMakeLists.txt 2011-12-13 19:40:18.000000000 +0000 +++ blender-2.62/intern/ghost/CMakeLists.txt 2012-02-15 19:24:37.000000000 +0000 @@ -234,6 +234,13 @@ ) endif() + if(WITH_X11_XF86VMODE) + add_definitions(-DWITH_X11_XF86VMODE) + list(APPEND INC_SYS + ${X11_xf86vmode_INCLUDE_PATH} + ) + endif() + if(WITH_INPUT_NDOF) list(APPEND SRC intern/GHOST_NDOFManagerX11.cpp diff -Nru blender-2.61/intern/ghost/GHOST_C-api.h blender-2.62/intern/ghost/GHOST_C-api.h --- blender-2.61/intern/ghost/GHOST_C-api.h 2011-12-13 19:40:18.000000000 +0000 +++ blender-2.62/intern/ghost/GHOST_C-api.h 2012-02-15 19:24:37.000000000 +0000 @@ -81,7 +81,8 @@ * @param eventCallback The event callback routine. * @param userdata Pointer to user data returned to the callback routine. */ -extern GHOST_EventConsumerHandle GHOST_CreateEventConsumer(GHOST_EventCallbackProcPtr eventCallback, GHOST_TUserDataPtr userdata); +extern GHOST_EventConsumerHandle GHOST_CreateEventConsumer(GHOST_EventCallbackProcPtr eventCallback, + GHOST_TUserDataPtr userdata); /** * Disposes an event consumer object diff -Nru blender-2.61/intern/ghost/GHOST_ISystem.h blender-2.62/intern/ghost/GHOST_ISystem.h --- blender-2.61/intern/ghost/GHOST_ISystem.h 2011-12-13 19:40:18.000000000 +0000 +++ blender-2.62/intern/ghost/GHOST_ISystem.h 2012-02-15 19:24:37.000000000 +0000 @@ -68,13 +68,28 @@ *
  • Access to the state of the mouse buttons and the keyboard.
  • *
  • Menus for windows with events generated when they are accessed (this is * work in progress).
  • + *
  • Video mode switching.
  • + *
  • Copy/Paste buffers.
  • + *
  • System paths.
  • * * Font management has been moved to a separate library. * * \section platforms Platforms * + * GHOST supports the following platforms: + *
      + *
    • OSX Cocoa.
    • + *
    • OSX Carbon.
    • + *
    • Windows.
    • + *
    • X11.
    • + *
    • SDL1.3 (experemental).
    • + *
    • NULL (headless mode).
    • + *
    + * * \section Building GHOST * + * GHOST is not build standalone however there are tests in intern/ghost/test + * * \section interface Interface * GHOST has two programming interfaces: *
      @@ -181,7 +196,10 @@ * @param userData Placeholder for user data. * @return A timer task (0 if timer task installation failed). */ - virtual GHOST_ITimerTask* installTimer(GHOST_TUns64 delay, GHOST_TUns64 interval, GHOST_TimerProcPtr timerProc, GHOST_TUserDataPtr userData = 0) = 0; + virtual GHOST_ITimerTask* installTimer(GHOST_TUns64 delay, + GHOST_TUns64 interval, + GHOST_TimerProcPtr timerProc, + GHOST_TUserDataPtr userData = 0) = 0; /** * Removes a timer. @@ -252,7 +270,16 @@ * @return Indication of success. */ virtual GHOST_TSuccess beginFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow** window, - const bool stereoVisual) = 0; + const bool stereoVisual, const GHOST_TUns16 numOfAASamples=0) = 0; + + /** + * Updates the resolution while in fullscreen mode. + * @param setting The new setting of the display. + * @param window Window displayed in full screen. + * + * @return Indication of success. + */ + virtual GHOST_TSuccess updateFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow** window) = 0; /** * Ends full screen mode. diff -Nru blender-2.61/intern/ghost/GHOST_IWindow.h blender-2.62/intern/ghost/GHOST_IWindow.h --- blender-2.61/intern/ghost/GHOST_IWindow.h 2011-12-13 19:40:18.000000000 +0000 +++ blender-2.62/intern/ghost/GHOST_IWindow.h 2012-02-15 19:24:37.000000000 +0000 @@ -303,7 +303,7 @@ * @param grab The new grab state of the cursor. * @return Indication of success. */ - virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_Rect *bounds) { return GHOST_kSuccess; }; + virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_Rect *bounds) { return GHOST_kSuccess; } #ifdef WITH_CXX_GUARDEDALLOC public: diff -Nru blender-2.61/intern/ghost/intern/GHOST_CallbackEventConsumer.cpp blender-2.62/intern/ghost/intern/GHOST_CallbackEventConsumer.cpp --- blender-2.61/intern/ghost/intern/GHOST_CallbackEventConsumer.cpp 2011-12-13 19:40:13.000000000 +0000 +++ blender-2.62/intern/ghost/intern/GHOST_CallbackEventConsumer.cpp 2012-02-15 19:24:34.000000000 +0000 @@ -42,7 +42,7 @@ #include "GHOST_CallbackEventConsumer.h" GHOST_CallbackEventConsumer::GHOST_CallbackEventConsumer(GHOST_EventCallbackProcPtr eventCallback, - GHOST_TUserDataPtr userData) + GHOST_TUserDataPtr userData) { m_eventCallback = eventCallback; m_userData = userData; diff -Nru blender-2.61/intern/ghost/intern/GHOST_C-api.cpp blender-2.62/intern/ghost/intern/GHOST_C-api.cpp --- blender-2.61/intern/ghost/intern/GHOST_C-api.cpp 2011-12-13 19:40:13.000000000 +0000 +++ blender-2.62/intern/ghost/intern/GHOST_C-api.cpp 2012-02-15 19:24:34.000000000 +0000 @@ -65,7 +65,8 @@ } -GHOST_EventConsumerHandle GHOST_CreateEventConsumer(GHOST_EventCallbackProcPtr eventCallback, GHOST_TUserDataPtr userdata) +GHOST_EventConsumerHandle GHOST_CreateEventConsumer(GHOST_EventCallbackProcPtr eventCallback, + GHOST_TUserDataPtr userdata) { return (GHOST_EventConsumerHandle) new GHOST_CallbackEventConsumer (eventCallback, userdata); } diff -Nru blender-2.61/intern/ghost/intern/GHOST_Debug.h blender-2.62/intern/ghost/intern/GHOST_Debug.h --- blender-2.61/intern/ghost/intern/GHOST_Debug.h 2011-12-13 19:40:13.000000000 +0000 +++ blender-2.62/intern/ghost/intern/GHOST_Debug.h 2012-02-15 19:24:34.000000000 +0000 @@ -34,35 +34,42 @@ #define _GHOST_DEBUG_H_ #if defined(WIN32) && !defined(FREE_WINDOWS) - #ifdef DEBUG - #pragma warning (disable:4786) // suppress stl-MSVC debug info warning - // #define GHOST_DEBUG - #endif // DEBUG +# ifdef DEBUG +# pragma warning (disable:4786) // suppress stl-MSVC debug info warning + // #define GHOST_DEBUG +# endif // DEBUG #endif // WIN32 #ifdef WITH_GHOST_DEBUG - #define GHOST_DEBUG // spit ghost events to stdout +# define GHOST_DEBUG // spit ghost events to stdout #endif // WITH_GHOST_DEBUG #ifdef GHOST_DEBUG - #include - #include //for printf() +# include +# include //for printf() #endif // GHOST_DEBUG #ifdef GHOST_DEBUG - #define GHOST_PRINT(x) { std::cout << x; } - #define GHOST_PRINTF(x, ...) { printf(x, __VA_ARGS__); } +# define GHOST_PRINT(x) { std::cout << x; } +# define GHOST_PRINTF(x, ...) { printf(x, __VA_ARGS__); } #else // GHOST_DEBUG - #define GHOST_PRINT(x) - #define GHOST_PRINTF(x, ...) +# define GHOST_PRINT(x) +# define GHOST_PRINTF(x, ...) #endif // GHOST_DEBUG #ifdef GHOST_DEBUG - #define GHOST_ASSERT(x, info) { if (!(x)) {GHOST_PRINT("assertion failed: "); GHOST_PRINT(info); GHOST_PRINT("\n"); } } +# define GHOST_ASSERT(x, info) \ + { \ + if (!(x)) { \ + GHOST_PRINT("assertion failed: "); \ + GHOST_PRINT(info); \ + GHOST_PRINT("\n"); \ + } \ + } #else // GHOST_DEBUG - #define GHOST_ASSERT(x, info) +# define GHOST_ASSERT(x, info) #endif // GHOST_DEBUG #endif // _GHOST_DEBUG_H_ diff -Nru blender-2.61/intern/ghost/intern/GHOST_DisplayManager.h blender-2.62/intern/ghost/intern/GHOST_DisplayManager.h --- blender-2.61/intern/ghost/intern/GHOST_DisplayManager.h 2011-12-13 19:40:13.000000000 +0000 +++ blender-2.62/intern/ghost/intern/GHOST_DisplayManager.h 2012-02-15 19:24:34.000000000 +0000 @@ -75,7 +75,8 @@ * @param numSettings The number of settings of the display device with this index. * @return Indication of success. */ - virtual GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32& numSettings) const; + virtual GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, + GHOST_TInt32& numSettings) const; /** * Returns the current setting for this display device. @@ -84,7 +85,9 @@ * @param setting The setting of the display device with this index. * @return Indication of success. */ - virtual GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const; + virtual GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display, + GHOST_TInt32 index, + GHOST_DisplaySetting& setting) const; /** * Returns the current setting for this display device. @@ -92,7 +95,8 @@ * @param setting The current setting of the display device with this index. * @return Indication of success. */ - virtual GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting& setting) const; + virtual GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display, + GHOST_DisplaySetting& setting) const; /** * Changes the current setting for this display device. @@ -102,7 +106,8 @@ * @param setting The setting of the display device to be matched and activated. * @return Indication of success. */ - virtual GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting& setting); + virtual GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display, + const GHOST_DisplaySetting& setting); protected: typedef std::vector GHOST_DisplaySettings; @@ -114,7 +119,9 @@ * @param match The optimal display setting. * @return Indication of success. */ - GHOST_TSuccess findMatch(GHOST_TUns8 display, const GHOST_DisplaySetting& setting, GHOST_DisplaySetting& match) const; + GHOST_TSuccess findMatch(GHOST_TUns8 display, + const GHOST_DisplaySetting& setting, + GHOST_DisplaySetting& match) const; /** * Retrieves settings for each display device and stores them. diff -Nru blender-2.61/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp blender-2.62/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp --- blender-2.61/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp 2011-12-13 19:40:13.000000000 +0000 +++ blender-2.62/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp 2012-02-15 19:24:34.000000000 +0000 @@ -17,6 +17,11 @@ * * Contributor(s): Campbell Barton * + * Mode switching + * Copyright (C) 1997-2001 Id Software, Inc. + * Copyright (c) 1993-2011 Tim Riker + * Copyright (C) 2012 Alex Fraser + * * ***** END GPL LICENSE BLOCK ***** */ @@ -36,7 +41,7 @@ } GHOST_TSuccess -GHOST_DisplayManagerSDL::getNumDisplays(GHOST_TUns8& numDisplays) +GHOST_DisplayManagerSDL::getNumDisplays(GHOST_TUns8& numDisplays) const { numDisplays= SDL_GetNumVideoDisplays(); return GHOST_kSuccess; @@ -44,49 +49,164 @@ GHOST_TSuccess GHOST_DisplayManagerSDL::getNumDisplaySettings(GHOST_TUns8 display, - GHOST_TInt32& numSettings) + GHOST_TInt32& numSettings) const { GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); - numSettings= GHOST_TInt32(1); + int i; + SDL_Rect **vidmodes; + + vidmodes = SDL_ListModes(NULL, SDL_HWSURFACE | SDL_OPENGL | + SDL_FULLSCREEN | SDL_HWPALETTE); + if (!vidmodes) { + fprintf(stderr, "Could not get available video modes: %s.\n", + SDL_GetError()); + return GHOST_kFailure; + } + for (i = 0; vidmodes[i]; i++); + numSettings = GHOST_TInt32(i); + return GHOST_kSuccess; } GHOST_TSuccess GHOST_DisplayManagerSDL::getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, - GHOST_DisplaySetting& setting) + GHOST_DisplaySetting& setting) const { - GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); - GHOST_ASSERT(index < 1, "Requested setting outside of valid range.\n"); - SDL_DisplayMode mode; - SDL_GetDesktopDisplayMode(display, &mode); - - setting.xPixels= mode.w; - setting.yPixels= mode.h; - setting.bpp= SDL_BYTESPERPIXEL(mode.format); - /* assume 60 when unset */ - setting.frequency= mode.refresh_rate ? mode.refresh_rate : 60; + int i; + SDL_Rect **vidmodes; + /* NULL is passed in here to get the modes for the current bit depth. + * Other bit depths may be possible; in that case, an SDL_PixelFormat struct + * should be passed in. To get a complete profile, all possible bit depths + * would need to be iterated over. - z0r */ + vidmodes = SDL_ListModes(NULL, SDL_HWSURFACE | SDL_OPENGL | + SDL_FULLSCREEN | SDL_HWPALETTE); + if (!vidmodes) { + fprintf(stderr, "Could not get available video modes: %s.\n", + SDL_GetError()); + return GHOST_kFailure; + } + for (i = 0; vidmodes[i]; i++); + GHOST_ASSERT(index < i, "Requested setting outside of valid range.\n"); + + setting.xPixels = vidmodes[index]->w; + setting.yPixels = vidmodes[index]->h; + + SDL_Surface *surf; + surf = SDL_GetVideoSurface(); + if (surf == NULL) { + fprintf(stderr, "Getting display setting: %s\n", SDL_GetError()); + /* Just guess the bit depth */ + setting.bpp = 32; + } else { + setting.bpp = surf->format->BitsPerPixel; + } + /* Just guess the frequency :( */ + setting.frequency = 60; return GHOST_kSuccess; } GHOST_TSuccess GHOST_DisplayManagerSDL::getCurrentDisplaySetting(GHOST_TUns8 display, - GHOST_DisplaySetting& setting) + GHOST_DisplaySetting& setting) const { - return getDisplaySetting(display,GHOST_TInt32(0),setting); + SDL_Surface *surf; + const SDL_VideoInfo *info; + + /* Note: not using SDL_GetDesktopDisplayMode because that does not return + * the current mode. Try to use GetVideoSurface first, as it seems more + * accurate. If that fails, try other methods. - z0r */ + surf = SDL_GetVideoSurface(); + + if (surf != NULL) { + setting.xPixels = surf->w; + setting.yPixels = surf->h; + setting.bpp = surf->format->BitsPerPixel; + /* Just guess the frequency :( */ + setting.frequency = 60; + } else { + /* This may happen if the surface hasn't been created yet, e.g. on + * application startup. */ + info = SDL_GetVideoInfo(); + setting.xPixels = info->current_w; + setting.yPixels = info->current_h; + setting.bpp = info->vfmt->BitsPerPixel; + /* Just guess the frequency :( */ + setting.frequency = 60; + } + + return GHOST_kSuccess; } GHOST_TSuccess GHOST_DisplayManagerSDL:: setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting& setting) { - // This is never going to work robustly in X - // but it's currently part of the full screen interface - // we fudge it for now. + /* + * Mode switching code ported from Quake 2 version 3.21 and bzflag version + * 2.4.0: + * ftp://ftp.idsoftware.com/idstuff/source/q2source-3.21.zip + * See linux/gl_glx.c:GLimp_SetMode + * http://wiki.bzflag.org/BZFlag_Source + * See src/platform/SDLDisplay.cxx:SDLDisplay and createWindow + */ + SDL_Surface *surf; + int best_fit, best_dist, dist, x, y; + + SDL_Rect **vidmodes = SDL_ListModes(NULL, SDL_HWSURFACE | SDL_OPENGL | + SDL_FULLSCREEN | SDL_HWPALETTE); + if (!vidmodes) { + fprintf(stderr, "Could not get available video modes: %s.\n", + SDL_GetError()); + } + + best_dist = 9999999; + best_fit = -1; + + if (vidmodes == (SDL_Rect **) -1) { + /* Any mode is OK. */ + x = setting.xPixels; + y = setting.yPixels; + } else { + for (int i = 0; vidmodes[i]; i++) { + if (setting.xPixels > vidmodes[i]->w || + setting.yPixels > vidmodes[i]->h) + continue; + + x = setting.xPixels - vidmodes[i]->w; + y = setting.yPixels - vidmodes[i]->h; + dist = (x * x) + (y * y); + if (dist < best_dist) { + best_dist = dist; + best_fit = i; + } + } + + if (best_fit == -1) + return GHOST_kFailure; + + x = vidmodes[best_fit]->w; + y = vidmodes[best_fit]->h; + } + +# ifdef _DEBUG + printf("Switching to video mode %dx%d\n", x, y); +# endif + + // limit us to the main display + static char singleDisplayEnv[] = "SDL_SINGLEDISPLAY=1"; + putenv(singleDisplayEnv); + + // change to the mode + surf = SDL_SetVideoMode(x, y, setting.bpp, SDL_OPENGL | SDL_FULLSCREEN); + if (surf == NULL) { + fprintf(stderr, "Could not set video mode: %s.\n", SDL_GetError()); + return GHOST_kFailure; + } return GHOST_kSuccess; } diff -Nru blender-2.61/intern/ghost/intern/GHOST_DisplayManagerSDL.h blender-2.62/intern/ghost/intern/GHOST_DisplayManagerSDL.h --- blender-2.61/intern/ghost/intern/GHOST_DisplayManagerSDL.h 2011-12-13 19:40:13.000000000 +0000 +++ blender-2.62/intern/ghost/intern/GHOST_DisplayManagerSDL.h 2012-02-15 19:24:34.000000000 +0000 @@ -46,20 +46,20 @@ GHOST_DisplayManagerSDL(GHOST_SystemSDL *system); GHOST_TSuccess - getNumDisplays(GHOST_TUns8& numDisplays); + getNumDisplays(GHOST_TUns8& numDisplays) const; GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, - GHOST_TInt32& numSettings); + GHOST_TInt32& numSettings) const; GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, - GHOST_DisplaySetting& setting); + GHOST_DisplaySetting& setting) const; GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display, - GHOST_DisplaySetting& setting); + GHOST_DisplaySetting& setting) const; GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display, diff -Nru blender-2.61/intern/ghost/intern/GHOST_DisplayManagerX11.cpp blender-2.62/intern/ghost/intern/GHOST_DisplayManagerX11.cpp --- blender-2.61/intern/ghost/intern/GHOST_DisplayManagerX11.cpp 2011-12-13 19:40:13.000000000 +0000 +++ blender-2.62/intern/ghost/intern/GHOST_DisplayManagerX11.cpp 2012-02-15 19:24:34.000000000 +0000 @@ -20,7 +20,9 @@ * * The Original Code is: all of this file. * - * Contributor(s): none yet. + * Video mode switching + * Copyright (C) 1997-2001 Id Software, Inc. + * Ported from Quake 2 by Alex Fraser * * ***** END GPL LICENSE BLOCK ***** */ @@ -29,6 +31,10 @@ * \ingroup GHOST */ +#ifdef WITH_X11_XF86VMODE +# include +# include +#endif #include "GHOST_DisplayManagerX11.h" #include "GHOST_SystemX11.h" @@ -61,10 +67,32 @@ GHOST_TUns8 display, GHOST_TInt32& numSettings ) const{ - +#ifdef WITH_X11_XF86VMODE + int majorVersion, minorVersion; + XF86VidModeModeInfo **vidmodes; + Display *dpy = m_system->getXDisplay(); + + GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); + + if (dpy == NULL) + return GHOST_kFailure; + + majorVersion = minorVersion = 0; + if (!XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) { + fprintf(stderr, "Error: XF86VidMode extension missing!\n"); + return GHOST_kFailure; + } + + /* The X11 man page says vidmodes needs to be freed, but doing so causes a + * segfault. - z0r */ + XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &numSettings, &vidmodes); + +#else // We only have one X11 setting at the moment. GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); numSettings = GHOST_TInt32(1); +#endif + return GHOST_kSuccess; } @@ -75,7 +103,34 @@ GHOST_TInt32 index, GHOST_DisplaySetting& setting ) const { - + +#ifdef WITH_X11_XF86VMODE + int majorVersion, minorVersion; + XF86VidModeModeInfo **vidmodes; + Display *dpy = m_system->getXDisplay(); + int numSettings; + + GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); + + if (dpy == NULL) + return GHOST_kFailure; + + majorVersion = minorVersion = 0; + if (!XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) { + fprintf(stderr, "Error: XF86VidMode extension missing!\n"); + return GHOST_kFailure; + } + + /* The X11 man page says vidmodes needs to be freed, but doing so causes a + * segfault. - z0r */ + XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &numSettings, &vidmodes); + GHOST_ASSERT(index < numSettings, "Requested setting outside of valid range.\n"); + + setting.xPixels = vidmodes[index]->hdisplay; + setting.yPixels = vidmodes[index]->vdisplay; + setting.bpp = DefaultDepth(dpy,DefaultScreen(dpy)); + +#else GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); GHOST_ASSERT(index < 1, "Requested setting outside of valid range.\n"); @@ -88,6 +143,7 @@ setting.xPixels = DisplayWidth(x_display, DefaultScreen(x_display)); setting.yPixels = DisplayHeight(x_display, DefaultScreen(x_display)); setting.bpp = DefaultDepth(x_display,DefaultScreen(x_display)); +#endif // Don't think it's possible to get this value from X! // So let's guess!! @@ -102,6 +158,9 @@ GHOST_TUns8 display, GHOST_DisplaySetting& setting ) const { + /* According to the xf86vidmodegetallmodelines man page, + * "The first element of the array corresponds to the current video mode." + */ return getDisplaySetting(display,GHOST_TInt32(0),setting); } @@ -112,12 +171,79 @@ GHOST_TUns8 display, const GHOST_DisplaySetting& setting ){ - // This is never going to work robustly in X - // but it's currently part of the full screen interface +#ifdef WITH_X11_XF86VMODE + // + // Mode switching code ported from Quake 2: + // ftp://ftp.idsoftware.com/idstuff/source/q2source-3.21.zip + // See linux/gl_glx.c:GLimp_SetMode + // + int majorVersion, minorVersion; + XF86VidModeModeInfo **vidmodes; + Display *dpy = m_system->getXDisplay(); + int scrnum, num_vidmodes; + int best_fit, best_dist, dist, x, y; + + if (dpy == NULL) + return GHOST_kFailure; + + scrnum = DefaultScreen(dpy); - // we fudge it for now. + // Get video mode list + majorVersion = minorVersion = 0; + if (!XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) { + fprintf(stderr, "Error: XF86VidMode extension missing!\n"); + return GHOST_kFailure; + } +# ifdef _DEBUG + printf("Using XFree86-VidModeExtension Version %d.%d\n", + majorVersion, minorVersion); +# endif + + /* The X11 man page says vidmodes needs to be freed, but doing so causes a + * segfault. - z0r */ + XF86VidModeGetAllModeLines(dpy, scrnum, &num_vidmodes, &vidmodes); + + best_dist = 9999999; + best_fit = -1; + + for (int i = 0; i < num_vidmodes; i++) { + if (setting.xPixels > vidmodes[i]->hdisplay || + setting.yPixels > vidmodes[i]->vdisplay) + continue; + + x = setting.xPixels - vidmodes[i]->hdisplay; + y = setting.yPixels - vidmodes[i]->vdisplay; + dist = (x * x) + (y * y); + if (dist < best_dist) { + best_dist = dist; + best_fit = i; + } + } + + if (best_fit != -1) { +# ifdef _DEBUG + int actualWidth, actualHeight; + actualWidth = vidmodes[best_fit]->hdisplay; + actualHeight = vidmodes[best_fit]->vdisplay; + printf("Switching to video mode %dx%d\n", + actualWidth, actualHeight); +# endif + + // change to the mode + XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]); + + // Move the viewport to top left + XF86VidModeSetViewPort(dpy, scrnum, 0, 0); + } else + return GHOST_kFailure; + + XFlush(dpy); + return GHOST_kSuccess; +#else + // Just pretend the request was successful. return GHOST_kSuccess; +#endif } diff -Nru blender-2.61/intern/ghost/intern/GHOST_EventDragnDrop.h blender-2.62/intern/ghost/intern/GHOST_EventDragnDrop.h --- blender-2.61/intern/ghost/intern/GHOST_EventDragnDrop.h 2011-12-13 19:40:13.000000000 +0000 +++ blender-2.62/intern/ghost/intern/GHOST_EventDragnDrop.h 2012-02-15 19:24:34.000000000 +0000 @@ -44,19 +44,21 @@ * * The dragging sequence is performed in four phases: * - *
    • Start sequence (GHOST_kEventDraggingEntered) that tells a drag'n'drop operation has started. Already gives the object data type, - * and the entering mouse location + *
    • Start sequence (GHOST_kEventDraggingEntered) that tells a drag'n'drop operation has started. + * Already gives the object data type, and the entering mouse location * - *
    • Update mouse position (GHOST_kEventDraggingUpdated) sent upon each mouse move until the drag'n'drop operation stops, to give the updated mouse position. - * Useful to highlight a potential destination, and update the status (through GHOST_setAcceptDragOperation) telling if the object can be dropped at + *
    • Update mouse position (GHOST_kEventDraggingUpdated) sent upon each mouse move until the drag'n'drop operation + * stops, to give the updated mouse position. Useful to highlight a potential destination, and update the status + * (through GHOST_setAcceptDragOperation) telling if the object can be dropped at * the current cursor position. * *
    • Abort drag'n'drop sequence (GHOST_kEventDraggingExited) sent when the user moved the mouse outside the window. * *
    • Send the dropped data (GHOST_kEventDraggingDropDone) * - *
    • Outside of the normal sequence, dropped data can be sent (GHOST_kEventDraggingDropOnIcon). This can happen when the user drops an object - * on the application icon. (Also used in OSX to pass the filename of the document the user doubled-clicked in the finder) + *
    • Outside of the normal sequence, dropped data can be sent (GHOST_kEventDraggingDropOnIcon). + * This can happen when the user drops an object on the application icon. + * (Also used in OSX to pass the filename of the document the user doubled-clicked in the finder) * *

      Note that the mouse positions are given in Blender coordinates (y=0 at bottom) * @@ -78,7 +80,10 @@ * @param y The y-coordinate of the location the cursor was at at the time of the event. * @param data The "content" dropped in the window */ - GHOST_EventDragnDrop(GHOST_TUns64 time, GHOST_TEventType type, GHOST_TDragnDropTypes dataType, GHOST_IWindow* window, + GHOST_EventDragnDrop(GHOST_TUns64 time, + GHOST_TEventType type, + GHOST_TDragnDropTypes dataType, + GHOST_IWindow* window, int x, int y, GHOST_TEventDataPtr data) : GHOST_Event(time, type, window) { diff -Nru blender-2.61/intern/ghost/intern/GHOST_EventKey.h blender-2.62/intern/ghost/intern/GHOST_EventKey.h --- blender-2.61/intern/ghost/intern/GHOST_EventKey.h 2011-12-13 19:40:13.000000000 +0000 +++ blender-2.62/intern/ghost/intern/GHOST_EventKey.h 2012-02-15 19:24:34.000000000 +0000 @@ -49,7 +49,10 @@ * @param type The type of key event. * @param key The key code of the key. */ - GHOST_EventKey(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow* window, GHOST_TKey key) + GHOST_EventKey(GHOST_TUns64 msec, + GHOST_TEventType type, + GHOST_IWindow* window, + GHOST_TKey key) : GHOST_Event(msec, type, window) { m_keyEventData.key = key; @@ -65,7 +68,12 @@ * @param key The key code of the key. * @param ascii The ascii code for the key event. */ - GHOST_EventKey(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow* window, GHOST_TKey key, char ascii, const char utf8_buf[6]) + GHOST_EventKey(GHOST_TUns64 msec, + GHOST_TEventType type, + GHOST_IWindow* window, + GHOST_TKey key, + char ascii, + const char utf8_buf[6]) : GHOST_Event(msec, type, window) { m_keyEventData.key = key; diff -Nru blender-2.61/intern/ghost/intern/GHOST_EventNDOF.h blender-2.62/intern/ghost/intern/GHOST_EventNDOF.h --- blender-2.61/intern/ghost/intern/GHOST_EventNDOF.h 2011-12-13 19:40:13.000000000 +0000 +++ blender-2.62/intern/ghost/intern/GHOST_EventNDOF.h 2012-02-15 19:24:34.000000000 +0000 @@ -19,7 +19,11 @@ * * ***** END GPL LICENSE BLOCK ***** */ - + +/** \file ghost/intern/GHOST_EventNDOF.h + * \ingroup GHOST + * Declaration of GHOST_EventManager class. + */ #ifndef _GHOST_EVENT_NDOF_H_ #define _GHOST_EVENT_NDOF_H_ diff -Nru blender-2.61/intern/ghost/intern/GHOST_EventTrackpad.h blender-2.62/intern/ghost/intern/GHOST_EventTrackpad.h --- blender-2.61/intern/ghost/intern/GHOST_EventTrackpad.h 2011-12-13 19:40:13.000000000 +0000 +++ blender-2.62/intern/ghost/intern/GHOST_EventTrackpad.h 2012-02-15 19:24:34.000000000 +0000 @@ -50,7 +50,11 @@ * @param x The x-delta of the pan event. * @param y The y-delta of the pan event. */ - GHOST_EventTrackpad(GHOST_TUns64 msec, GHOST_IWindow* window, GHOST_TTrackpadEventSubTypes subtype, GHOST_TInt32 x, GHOST_TInt32 y, GHOST_TInt32 deltaX, GHOST_TInt32 deltaY) + GHOST_EventTrackpad(GHOST_TUns64 msec, + GHOST_IWindow* window, + GHOST_TTrackpadEventSubTypes subtype, + GHOST_TInt32 x, GHOST_TInt32 y, + GHOST_TInt32 deltaX, GHOST_TInt32 deltaY) : GHOST_Event(msec, GHOST_kEventTrackpad, window) { m_trackpadEventData.subtype = subtype; diff -Nru blender-2.61/intern/ghost/intern/GHOST_NDOFManager.cpp blender-2.62/intern/ghost/intern/GHOST_NDOFManager.cpp --- blender-2.61/intern/ghost/intern/GHOST_NDOFManager.cpp 2011-12-13 19:40:13.000000000 +0000 +++ blender-2.62/intern/ghost/intern/GHOST_NDOFManager.cpp 2012-02-15 19:24:34.000000000 +0000 @@ -77,6 +77,12 @@ "NDOF_BUTTON_8", "NDOF_BUTTON_9", "NDOF_BUTTON_10", + // more general-purpose buttons + "NDOF_BUTTON_A", + "NDOF_BUTTON_B", + "NDOF_BUTTON_C", + // the end + "NDOF_BUTTON_LAST" }; #endif @@ -137,8 +143,39 @@ NDOF_BUTTON_MINUS }; +// latest HW: button-compatible with SpacePilotPro, just fewer of them +static const NDOF_ButtonT SpaceMousePro_HID_map[] = { + NDOF_BUTTON_MENU, + NDOF_BUTTON_FIT, + NDOF_BUTTON_TOP, + NDOF_BUTTON_NONE, // left + NDOF_BUTTON_RIGHT, + NDOF_BUTTON_FRONT, + NDOF_BUTTON_NONE, // bottom + NDOF_BUTTON_NONE, // back + NDOF_BUTTON_ROLL_CW, + NDOF_BUTTON_NONE, // roll ccw + NDOF_BUTTON_NONE, // iso 1 + NDOF_BUTTON_NONE, // iso 2 + NDOF_BUTTON_1, + NDOF_BUTTON_2, + NDOF_BUTTON_3, + NDOF_BUTTON_4, + NDOF_BUTTON_NONE, // 5 + NDOF_BUTTON_NONE, // 6 + NDOF_BUTTON_NONE, // 7 + NDOF_BUTTON_NONE, // 8 + NDOF_BUTTON_NONE, // 9 + NDOF_BUTTON_NONE, // 10 + NDOF_BUTTON_NONE, // esc key + NDOF_BUTTON_NONE, // alt key + NDOF_BUTTON_NONE, // shift key + NDOF_BUTTON_NONE, // ctrl key + NDOF_BUTTON_ROTATE, +}; + /* this is the older SpacePilot (sans Pro) - * thanks to polosson for the info in this table */ + * thanks to polosson for info about this device */ static const NDOF_ButtonT SpacePilot_HID_map[] = { NDOF_BUTTON_1, NDOF_BUTTON_2, @@ -163,6 +200,23 @@ NDOF_BUTTON_NONE // the CONFIG button -- what does it do? }; +/* this is the older Spaceball 5000 USB + * thanks to Tehrasha Darkon for info about this device */ +static const NDOF_ButtonT Spaceball5000_HID_map[] = { + NDOF_BUTTON_1, + NDOF_BUTTON_2, + NDOF_BUTTON_3, + NDOF_BUTTON_4, + NDOF_BUTTON_5, + NDOF_BUTTON_6, + NDOF_BUTTON_7, + NDOF_BUTTON_8, + NDOF_BUTTON_9, + NDOF_BUTTON_A, + NDOF_BUTTON_B, + NDOF_BUTTON_C +}; + GHOST_NDOFManager::GHOST_NDOFManager(GHOST_System& sys) : m_system(sys) , m_deviceType(NDOF_UnknownDevice) // each platform has its own device detection code @@ -206,10 +260,16 @@ m_buttonCount = 15; break; case 0xC629: - puts("ndof: using SpacePilotPro"); + puts("ndof: using SpacePilot Pro"); m_deviceType = NDOF_SpacePilotPro; m_buttonCount = 31; break; + case 0xC62B: + puts("ndof: using SpaceMouse Pro"); + m_deviceType = NDOF_SpaceMousePro; + m_buttonCount = 27; + // ^^ actually has 15 buttons, but their HID codes range from 0 to 26 + break; // -- older devices -- case 0xC625: @@ -218,6 +278,12 @@ m_buttonCount = 21; break; + case 0xC621: + puts("ndof: using Spaceball 5000"); + m_deviceType = NDOF_Spaceball5000; + m_buttonCount = 12; + break; + case 0xC623: puts("ndof: SpaceTraveler not supported, please file a bug report"); m_buttonCount = 8; @@ -237,6 +303,8 @@ else { m_buttonMask = ~(-1 << m_buttonCount); + // special case for SpaceMousePro? maybe... + #ifdef DEBUG_NDOF_BUTTONS printf("ndof: %d buttons -> hex:%X\n", m_buttonCount, m_buttonMask); #endif @@ -261,6 +329,16 @@ void GHOST_NDOFManager::sendButtonEvent(NDOF_ButtonT button, bool press, GHOST_TUns64 time, GHOST_IWindow* window) { + if (button == NDOF_BUTTON_NONE) { + // just being exceptionally cautious... + // air-tight button masking and proper function key emulation + // should guarantee we never get to this point +#ifdef DEBUG_NDOF_BUTTONS + printf("discarding NDOF_BUTTON_NONE (should not escape the NDOF manager)\n"); +#endif + return; + } + GHOST_EventNDOFButton* event = new GHOST_EventNDOFButton(time, window); GHOST_TEventNDOFButtonData* data = (GHOST_TEventNDOFButtonData*) event->getData(); @@ -317,6 +395,15 @@ default: sendButtonEvent(SpacePilotPro_HID_map[button_number], press, time, window); } break; + case NDOF_SpaceMousePro: + switch (button_number) { + case 22: sendKeyEvent(GHOST_kKeyEsc, press, time, window); break; + case 23: sendKeyEvent(GHOST_kKeyLeftAlt, press, time, window); break; + case 24: sendKeyEvent(GHOST_kKeyLeftShift, press, time, window); break; + case 25: sendKeyEvent(GHOST_kKeyLeftControl, press, time, window); break; + default: sendButtonEvent(SpaceMousePro_HID_map[button_number], press, time, window); + } + break; case NDOF_SpacePilot: switch (button_number) { case 10: sendKeyEvent(GHOST_kKeyEsc, press, time, window); break; @@ -327,8 +414,21 @@ default: sendButtonEvent(SpacePilot_HID_map[button_number], press, time, window); } break; + case NDOF_Spaceball5000: + // has no special 'keyboard' buttons + sendButtonEvent(Spaceball5000_HID_map[button_number], press, time, window); + break; case NDOF_UnknownDevice: - printf("ndof: button %d on unknown device (ignoring)\n", button_number); + printf("ndof: button %d on unknown device (", button_number); + // map to the 'general purpose' buttons + // this is mainly for old serial devices + if (button_number < NDOF_BUTTON_LAST - NDOF_BUTTON_1) { + printf("sending)\n"); + sendButtonEvent((NDOF_ButtonT)(NDOF_BUTTON_1 + button_number), press, time, window); + } + else { + printf("discarding)\n"); + } } int mask = 1 << button_number; diff -Nru blender-2.61/intern/ghost/intern/GHOST_NDOFManager.h blender-2.62/intern/ghost/intern/GHOST_NDOFManager.h --- blender-2.61/intern/ghost/intern/GHOST_NDOFManager.h 2011-12-13 19:40:13.000000000 +0000 +++ blender-2.62/intern/ghost/intern/GHOST_NDOFManager.h 2012-02-15 19:24:34.000000000 +0000 @@ -37,9 +37,11 @@ NDOF_SpaceNavigator, NDOF_SpaceExplorer, NDOF_SpacePilotPro, + NDOF_SpaceMousePro, // older devices - NDOF_SpacePilot + NDOF_SpacePilot, + NDOF_Spaceball5000 } NDOF_DeviceT; @@ -86,7 +88,12 @@ NDOF_BUTTON_8, NDOF_BUTTON_9, NDOF_BUTTON_10, - + // more general-purpose buttons + NDOF_BUTTON_A, + NDOF_BUTTON_B, + NDOF_BUTTON_C, + // the end + NDOF_BUTTON_LAST } NDOF_ButtonT; class GHOST_NDOFManager diff -Nru blender-2.61/intern/ghost/intern/GHOST_SystemCarbon.cpp blender-2.62/intern/ghost/intern/GHOST_SystemCarbon.cpp --- blender-2.61/intern/ghost/intern/GHOST_SystemCarbon.cpp 2011-12-13 19:40:13.000000000 +0000 +++ blender-2.62/intern/ghost/intern/GHOST_SystemCarbon.cpp 2012-02-15 19:24:34.000000000 +0000 @@ -579,7 +579,8 @@ static bool g_hasFirstFile = false; static char g_firstFileBuf[512]; -extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG]) { +extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG]) +{ if (g_hasFirstFile) { strncpy(buf, g_firstFileBuf, FIRSTFILEBUFLG - 1); buf[FIRSTFILEBUFLG - 1] = '\0'; diff -Nru blender-2.61/intern/ghost/intern/GHOST_SystemCocoa.h blender-2.62/intern/ghost/intern/GHOST_SystemCocoa.h --- blender-2.61/intern/ghost/intern/GHOST_SystemCocoa.h 2011-12-13 19:40:13.000000000 +0000 +++ blender-2.62/intern/ghost/intern/GHOST_SystemCocoa.h 2012-02-15 19:24:34.000000000 +0000 @@ -241,7 +241,9 @@ /** * Handles a tablet event. * @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++) - * @param eventType The type of the event. It needs to be passed separately as it can be either directly in the event type, or as a subtype if combined with a mouse button event + * @param eventType The type of the event. + * It needs to be passed separately as it can be either directly in the event type, + * or as a subtype if combined with a mouse button event. * @return Indication whether the event was handled. */ GHOST_TSuccess handleTabletEvent(void *eventPtr, short eventType); diff -Nru blender-2.61/intern/ghost/intern/GHOST_SystemCocoa.mm blender-2.62/intern/ghost/intern/GHOST_SystemCocoa.mm --- blender-2.61/intern/ghost/intern/GHOST_SystemCocoa.mm 2011-12-13 19:40:13.000000000 +0000 +++ blender-2.62/intern/ghost/intern/GHOST_SystemCocoa.mm 2012-02-15 19:24:34.000000000 +0000 @@ -451,7 +451,8 @@ static char g_firstFileBuf[512]; //TODO:Need to investigate this. Function called too early in creator.c to have g_hasFirstFile == true -extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG]) { +extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG]) +{ if (g_hasFirstFile) { strncpy(buf, g_firstFileBuf, FIRSTFILEBUFLG - 1); buf[FIRSTFILEBUFLG - 1] = '\0'; diff -Nru blender-2.61/intern/ghost/intern/GHOST_System.cpp blender-2.62/intern/ghost/intern/GHOST_System.cpp --- blender-2.61/intern/ghost/intern/GHOST_System.cpp 2011-12-13 19:40:13.000000000 +0000 +++ blender-2.62/intern/ghost/intern/GHOST_System.cpp 2012-02-15 19:24:34.000000000 +0000 @@ -73,7 +73,10 @@ } -GHOST_ITimerTask* GHOST_System::installTimer(GHOST_TUns64 delay, GHOST_TUns64 interval, GHOST_TimerProcPtr timerProc, GHOST_TUserDataPtr userData) +GHOST_ITimerTask* GHOST_System::installTimer(GHOST_TUns64 delay, + GHOST_TUns64 interval, + GHOST_TimerProcPtr timerProc, + GHOST_TUserDataPtr userData) { GHOST_TUns64 millis = getMilliSeconds(); GHOST_TimerTask* timer = new GHOST_TimerTask(millis+delay, interval, timerProc, userData); @@ -136,7 +139,7 @@ GHOST_TSuccess GHOST_System::beginFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow** window, - const bool stereoVisual) + const bool stereoVisual, const GHOST_TUns16 numOfAASamples) { GHOST_TSuccess success = GHOST_kFailure; GHOST_ASSERT(m_windowManager, "GHOST_System::beginFullScreen(): invalid window manager") @@ -148,7 +151,7 @@ success = m_displayManager->setCurrentDisplaySetting(GHOST_DisplayManager::kMainDisplay, setting); if (success == GHOST_kSuccess) { //GHOST_PRINT("GHOST_System::beginFullScreen(): creating full-screen window\n"); - success = createFullScreenWindow((GHOST_Window**)window, stereoVisual); + success = createFullScreenWindow((GHOST_Window**)window, stereoVisual, numOfAASamples); if (success == GHOST_kSuccess) { m_windowManager->beginFullScreen(*window, stereoVisual); } @@ -165,6 +168,19 @@ } +GHOST_TSuccess GHOST_System::updateFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow** window) +{ + GHOST_TSuccess success = GHOST_kFailure; + GHOST_ASSERT(m_windowManager, "GHOST_System::updateFullScreen(): invalid window manager"); + if(m_displayManager) { + if (m_windowManager->getFullScreen()) { + success = m_displayManager->setCurrentDisplaySetting(GHOST_DisplayManager::kMainDisplay, setting); + } + } + + return success; +} + GHOST_TSuccess GHOST_System::endFullScreen(void) { GHOST_TSuccess success = GHOST_kFailure; @@ -330,7 +346,7 @@ } -GHOST_TSuccess GHOST_System::createFullScreenWindow(GHOST_Window** window, const bool stereoVisual) +GHOST_TSuccess GHOST_System::createFullScreenWindow(GHOST_Window** window, const bool stereoVisual, const GHOST_TUns16 numOfAASamples) { GHOST_TSuccess success; GHOST_ASSERT(m_displayManager, "GHOST_System::createFullScreenWindow(): invalid display manager") @@ -344,7 +360,8 @@ 0, 0, settings.xPixels, settings.yPixels, GHOST_kWindowStateFullScreen, GHOST_kDrawingContextTypeOpenGL, - stereoVisual); + stereoVisual, + numOfAASamples); success = *window == 0 ? GHOST_kFailure : GHOST_kSuccess; } return success; diff -Nru blender-2.61/intern/ghost/intern/GHOST_System.h blender-2.62/intern/ghost/intern/GHOST_System.h --- blender-2.61/intern/ghost/intern/GHOST_System.h 2011-12-13 19:40:13.000000000 +0000 +++ blender-2.62/intern/ghost/intern/GHOST_System.h 2012-02-15 19:24:34.000000000 +0000 @@ -97,7 +97,10 @@ * @param userData Placeholder for user data. * @return A timer task (0 if timer task installation failed). */ - virtual GHOST_ITimerTask* installTimer(GHOST_TUns64 delay, GHOST_TUns64 interval, GHOST_TimerProcPtr timerProc, GHOST_TUserDataPtr userData = 0); + virtual GHOST_ITimerTask* installTimer(GHOST_TUns64 delay, + GHOST_TUns64 interval, + GHOST_TimerProcPtr timerProc, + GHOST_TUserDataPtr userData = 0); /** * Removes a timer. @@ -141,7 +144,16 @@ * @return Indication of success. */ virtual GHOST_TSuccess beginFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow** window, - const bool stereoVisual); + const bool stereoVisual, const GHOST_TUns16 numOfAASamples=0); + + /** + * Updates the resolution while in fullscreen mode. + * @param setting The new setting of the display. + * @param window Window displayed in full screen. + * + * @return Indication of success. + */ + virtual GHOST_TSuccess updateFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow** window); /** * Ends full screen mode. @@ -305,7 +317,7 @@ * @return Indication of success. */ virtual GHOST_TSuccess createFullScreenWindow(GHOST_Window** window, - const bool stereoVisual); + const bool stereoVisual, const GHOST_TUns16 numOfAASamples=0); /** The display manager (platform dependant). */ GHOST_DisplayManager* m_displayManager; diff -Nru blender-2.61/intern/ghost/intern/GHOST_SystemWin32.cpp blender-2.62/intern/ghost/intern/GHOST_SystemWin32.cpp --- blender-2.61/intern/ghost/intern/GHOST_SystemWin32.cpp 2011-12-13 19:40:13.000000000 +0000 +++ blender-2.62/intern/ghost/intern/GHOST_SystemWin32.cpp 2012-02-15 19:24:34.000000000 +0000 @@ -438,8 +438,12 @@ GHOST_ModifierKeys modifiers; system->retrieveModifierKeys(modifiers); - - *keyDown = !(raw.data.keyboard.Flags & RI_KEY_BREAK); + + // RI_KEY_BREAK doesn't work for sticky keys release, so we also + // check for the up message + unsigned int msg = raw.data.keyboard.Message; + *keyDown = !(raw.data.keyboard.Flags & RI_KEY_BREAK) && msg != WM_KEYUP && msg != WM_SYSKEYUP; + key = this->convertKey(window, raw.data.keyboard.VKey, raw.data.keyboard.MakeCode, (raw.data.keyboard.Flags&(RI_KEY_E1|RI_KEY_E0))); // extra handling of modifier keys: don't send repeats out from GHOST @@ -713,10 +717,11 @@ if (key != GHOST_kKeyUnknown) { char utf8_char[6] = {0} ; + char ascii = 0; wchar_t utf16[2]={0}; - BYTE state[256]; - GetKeyboardState((PBYTE)state); + BYTE state[256] ={0}; + GetKeyboardState(state); if(ToUnicodeEx(vk, 0, state, utf16, 2, 0, system->m_keylayout)) WideCharToMultiByte(CP_UTF8, 0, @@ -724,9 +729,14 @@ (LPSTR) utf8_char, 5, NULL,NULL); else *utf8_char = 0; - if(!keyDown) utf8_char[0] = '\0'; - event = new GHOST_EventKey(system->getMilliSeconds(), keyDown ? GHOST_kEventKeyDown: GHOST_kEventKeyUp, window, key, (*utf8_char & 0x80)?'?':*utf8_char, utf8_char); + + if(!keyDown) {utf8_char[0] = '\0'; ascii='\0';} + else ascii = utf8_char[0]& 0x80?'?':utf8_char[0]; + + if(0x80&state[VK_MENU]) utf8_char[0]='\0'; + + event = new GHOST_EventKey(system->getMilliSeconds(), keyDown ? GHOST_kEventKeyDown: GHOST_kEventKeyUp, window, key, ascii, utf8_char); #ifdef GHOST_DEBUG std::cout << ascii << std::endl; @@ -1236,26 +1246,25 @@ GHOST_TUns8* GHOST_SystemWin32::getClipboard(bool selection) const { - char *buffer; + wchar_t *buffer; char *temp_buff; - if ( IsClipboardFormatAvailable(CF_TEXT) && OpenClipboard(NULL) ) { + if ( IsClipboardFormatAvailable(CF_UNICODETEXT) && OpenClipboard(NULL) ) { size_t len = 0; - HANDLE hData = GetClipboardData( CF_TEXT ); + HANDLE hData = GetClipboardData( CF_UNICODETEXT ); if (hData == NULL) { CloseClipboard(); return NULL; } - buffer = (char*)GlobalLock( hData ); + buffer = (wchar_t*)GlobalLock( hData ); if (!buffer) { CloseClipboard(); return NULL; } - len = strlen(buffer); - temp_buff = (char*) malloc(len+1); - strncpy(temp_buff, buffer, len); - temp_buff[len] = '\0'; + len = WideCharToMultiByte(CP_UTF8, 0, buffer, -1, NULL, 0, NULL, NULL); + temp_buff = (char*) malloc(len); + WideCharToMultiByte(CP_UTF8, 0, buffer, -1, temp_buff, len, NULL, NULL); /* Buffer mustn't be accessed after CloseClipboard it would like accessing free-d memory */ @@ -1274,18 +1283,20 @@ if (OpenClipboard(NULL)) { HLOCAL clipbuffer; - char *data; + wchar_t *data; if (buffer) { EmptyClipboard(); - clipbuffer = LocalAlloc(LMEM_FIXED,((strlen(buffer)+1))); - data = (char*)GlobalLock(clipbuffer); - - strcpy(data, (char*)buffer); - data[strlen(buffer)] = '\0'; + int wlen = MultiByteToWideChar(CP_UTF8, 0, buffer, -1, NULL, 0); + + clipbuffer = LocalAlloc(LMEM_FIXED, wlen * sizeof(wchar_t)); + data = (wchar_t*)GlobalLock(clipbuffer); + + MultiByteToWideChar(CP_UTF8, 0, buffer, -1, data, wlen); + LocalUnlock(clipbuffer); - SetClipboardData(CF_TEXT,clipbuffer); + SetClipboardData(CF_UNICODETEXT,clipbuffer); } CloseClipboard(); } else { diff -Nru blender-2.61/intern/ghost/intern/GHOST_SystemX11.cpp blender-2.62/intern/ghost/intern/GHOST_SystemX11.cpp --- blender-2.61/intern/ghost/intern/GHOST_SystemX11.cpp 2011-12-13 19:40:13.000000000 +0000 +++ blender-2.62/intern/ghost/intern/GHOST_SystemX11.cpp 2012-02-15 19:24:34.000000000 +0000 @@ -296,7 +296,8 @@ } -static void SleepTillEvent(Display *display, GHOST_TInt64 maxSleep) { +static void SleepTillEvent(Display *display, GHOST_TInt64 maxSleep) +{ int fd = ConnectionNumber(display); fd_set fds; @@ -421,6 +422,18 @@ return anyProcessed; } + +#ifdef WITH_X11_XINPUT +/* set currently using tablet mode (stylus or eraser) depending on device ID */ +static void setTabletMode(GHOST_WindowX11 * window, XID deviceid) +{ + if(deviceid == window->GetXTablet().StylusID) + window->GetXTablet().CommonData.Active= GHOST_kTabletModeStylus; + else if(deviceid == window->GetXTablet().EraserID) + window->GetXTablet().CommonData.Active= GHOST_kTabletModeEraser; +} +#endif /* WITH_X11_XINPUT */ + void GHOST_SystemX11::processEvent(XEvent *xe) { @@ -766,10 +779,11 @@ case SelectionRequest: { XEvent nxe; - Atom target, string, compound_text, c_string; + Atom target, utf8_string, string, compound_text, c_string; XSelectionRequestEvent *xse = &xe->xselectionrequest; target = XInternAtom(m_display, "TARGETS", False); + utf8_string = XInternAtom(m_display, "UTF8_STRING", False); string = XInternAtom(m_display, "STRING", False); compound_text = XInternAtom(m_display, "COMPOUND_TEXT", False); c_string = XInternAtom(m_display, "C_STRING", False); @@ -788,19 +802,23 @@ nxe.xselection.time = xse->time; /*Check to see if the requestor is asking for String*/ - if(xse->target == string || xse->target == compound_text || xse->target == c_string) { + if(xse->target == utf8_string || xse->target == string || xse->target == compound_text || xse->target == c_string) { if (xse->selection == XInternAtom(m_display, "PRIMARY", False)) { - XChangeProperty(m_display, xse->requestor, xse->property, xse->target, 8, PropModeReplace, (unsigned char*)txt_select_buffer, strlen(txt_select_buffer)); + XChangeProperty(m_display, xse->requestor, xse->property, xse->target, 8, PropModeReplace, + (unsigned char*)txt_select_buffer, strlen(txt_select_buffer)); } else if (xse->selection == XInternAtom(m_display, "CLIPBOARD", False)) { - XChangeProperty(m_display, xse->requestor, xse->property, xse->target, 8, PropModeReplace, (unsigned char*)txt_cut_buffer, strlen(txt_cut_buffer)); + XChangeProperty(m_display, xse->requestor, xse->property, xse->target, 8, PropModeReplace, + (unsigned char*)txt_cut_buffer, strlen(txt_cut_buffer)); } } else if (xse->target == target) { - Atom alist[4]; + Atom alist[5]; alist[0] = target; - alist[1] = string; - alist[2] = compound_text; - alist[3] = c_string; - XChangeProperty(m_display, xse->requestor, xse->property, xse->target, 32, PropModeReplace, (unsigned char*)alist, 4); + alist[1] = utf8_string; + alist[2] = string; + alist[3] = compound_text; + alist[4] = c_string; + XChangeProperty(m_display, xse->requestor, xse->property, xse->target, 32, PropModeReplace, + (unsigned char*)alist, 5); XFlush(m_display); } else { //Change property to None because we do not support anything but STRING @@ -818,6 +836,12 @@ if(xe->type == window->GetXTablet().MotionEvent) { XDeviceMotionEvent* data = (XDeviceMotionEvent*)xe; + + /* stroke might begin without leading ProxyIn event, + * this happens when window is opened when stylus is already hovering + * around tablet surface */ + setTabletMode(window, data->deviceid); + window->GetXTablet().CommonData.Pressure= data->axis_data[2]/((float)window->GetXTablet().PressureLevels); @@ -831,10 +855,8 @@ else if(xe->type == window->GetXTablet().ProxInEvent) { XProximityNotifyEvent* data = (XProximityNotifyEvent*)xe; - if(data->deviceid == window->GetXTablet().StylusID) - window->GetXTablet().CommonData.Active= GHOST_kTabletModeStylus; - else if(data->deviceid == window->GetXTablet().EraserID) - window->GetXTablet().CommonData.Active= GHOST_kTabletModeEraser; + + setTabletMode(window, data->deviceid); } else if(xe->type == window->GetXTablet().ProxOutEvent) window->GetXTablet().CommonData.Active= GHOST_kTabletModeNone; @@ -1338,7 +1360,7 @@ GHOST_TUns8 *GHOST_SystemX11::getClipboard(bool selection) const { Atom sseln; - Atom target= m_string; + Atom target= m_utf8_string; Window owner; // from xclip.c doOut() v0.11 diff -Nru blender-2.61/intern/ghost/intern/GHOST_TimerTask.h blender-2.62/intern/ghost/intern/GHOST_TimerTask.h --- blender-2.61/intern/ghost/intern/GHOST_TimerTask.h 2011-12-13 19:40:13.000000000 +0000 +++ blender-2.62/intern/ghost/intern/GHOST_TimerTask.h 2012-02-15 19:24:34.000000000 +0000 @@ -51,8 +51,16 @@ * @param timerProc The callbak invoked when the interval expires. * @param data The timer user data. */ - GHOST_TimerTask(GHOST_TUns64 start, GHOST_TUns64 interval, GHOST_TimerProcPtr timerProc, GHOST_TUserDataPtr userData = 0) - : m_start(start), m_interval(interval), m_next(start), m_timerProc(timerProc), m_userData(userData), m_auxData(0) + GHOST_TimerTask(GHOST_TUns64 start, + GHOST_TUns64 interval, + GHOST_TimerProcPtr timerProc, + GHOST_TUserDataPtr userData = 0) + : m_start(start), + m_interval(interval), + m_next(start), + m_timerProc(timerProc), + m_userData(userData), + m_auxData(0) { } diff -Nru blender-2.61/intern/ghost/intern/GHOST_WindowCarbon.cpp blender-2.62/intern/ghost/intern/GHOST_WindowCarbon.cpp --- blender-2.61/intern/ghost/intern/GHOST_WindowCarbon.cpp 2011-12-13 19:40:13.000000000 +0000 +++ blender-2.62/intern/ghost/intern/GHOST_WindowCarbon.cpp 2012-02-15 19:24:34.000000000 +0000 @@ -70,7 +70,8 @@ { kEventClassWindow, kEventWindowZoom }, /* for new zoom behaviour */ }; -static OSStatus myWEventHandlerProc(EventHandlerCallRef handler, EventRef event, void* userData) { +static OSStatus myWEventHandlerProc(EventHandlerCallRef handler, EventRef event, void* userData) +{ WindowRef mywindow; GHOST_WindowCarbon *ghost_window; OSStatus err; diff -Nru blender-2.61/intern/ghost/intern/GHOST_WindowCocoa.mm blender-2.62/intern/ghost/intern/GHOST_WindowCocoa.mm --- blender-2.61/intern/ghost/intern/GHOST_WindowCocoa.mm 2011-12-13 19:40:13.000000000 +0000 +++ blender-2.62/intern/ghost/intern/GHOST_WindowCocoa.mm 2012-02-15 19:24:34.000000000 +0000 @@ -34,6 +34,7 @@ #endif #include +#include /***** Multithreaded opengl code : uncomment for enabling #include */ @@ -485,7 +486,14 @@ // needed for 'Draw Overlap' drawing method pixelFormatAttrsWindow[i++] = NSOpenGLPFABackingStore; - pixelFormatAttrsWindow[i++] = NSOpenGLPFAAccelerated; + // Force software OpenGL, for debugging + if(getenv("BLENDER_SOFTWAREGL")) { + pixelFormatAttrsWindow[i++] = NSOpenGLPFARendererID; + pixelFormatAttrsWindow[i++] = kCGLRendererGenericID; + } + else + pixelFormatAttrsWindow[i++] = NSOpenGLPFAAccelerated; + //pixelFormatAttrsWindow[i++] = NSOpenGLPFAAllowOfflineRenderers,; // Removed to allow 10.4 builds, and 2 GPUs rendering is not used anyway pixelFormatAttrsWindow[i++] = NSOpenGLPFADepthSize; @@ -521,7 +529,14 @@ // needed for 'Draw Overlap' drawing method pixelFormatAttrsWindow[i++] = NSOpenGLPFABackingStore; - pixelFormatAttrsWindow[i++] = NSOpenGLPFAAccelerated; + // Force software OpenGL, for debugging + if(getenv("BLENDER_SOFTWAREGL")) { + pixelFormatAttrsWindow[i++] = NSOpenGLPFARendererID; + pixelFormatAttrsWindow[i++] = kCGLRendererGenericID; + } + else + pixelFormatAttrsWindow[i++] = NSOpenGLPFAAccelerated; + //pixelFormatAttrsWindow[i++] = NSOpenGLPFAAllowOfflineRenderers,; // Removed to allow 10.4 builds, and 2 GPUs rendering is not used anyway pixelFormatAttrsWindow[i++] = NSOpenGLPFADepthSize; diff -Nru blender-2.61/intern/ghost/intern/GHOST_Window.cpp blender-2.62/intern/ghost/intern/GHOST_Window.cpp --- blender-2.61/intern/ghost/intern/GHOST_Window.cpp 2011-12-13 19:40:13.000000000 +0000 +++ blender-2.62/intern/ghost/intern/GHOST_Window.cpp 2012-02-15 19:24:34.000000000 +0000 @@ -145,15 +145,15 @@ } GHOST_TSuccess GHOST_Window::setCustomCursorShape(GHOST_TUns8 bitmap[16][2], GHOST_TUns8 mask[16][2], - int hotX, int hotY) + int hotX, int hotY) { - return setCustomCursorShape( (GHOST_TUns8 *)bitmap, (GHOST_TUns8 *)mask, - 16, 16, hotX, hotY, 0, 1 ); + return setCustomCursorShape((GHOST_TUns8 *)bitmap, (GHOST_TUns8 *)mask, + 16, 16, hotX, hotY, 0, 1 ); } GHOST_TSuccess GHOST_Window::setCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask, - int sizex, int sizey, int hotX, int hotY, - int fg_color, int bg_color ) + int sizex, int sizey, int hotX, int hotY, + int fg_color, int bg_color) { if (setWindowCustomCursorShape(bitmap, mask, sizex, sizey,hotX, hotY, fg_color, bg_color)) { m_cursorShape = GHOST_kStandardCursorCustom; diff -Nru blender-2.61/intern/ghost/intern/GHOST_Window.h blender-2.62/intern/ghost/intern/GHOST_Window.h --- blender-2.61/intern/ghost/intern/GHOST_Window.h 2011-12-13 19:40:13.000000000 +0000 +++ blender-2.62/intern/ghost/intern/GHOST_Window.h 2012-02-15 19:24:34.000000000 +0000 @@ -289,8 +289,9 @@ * Sets the cursor shape on the window using * native window system calls. */ - virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], GHOST_TUns8 mask[16][2], - int hotX, int hotY) = 0; + virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], + GHOST_TUns8 mask[16][2], + int hotX, int hotY) = 0; virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask, int szx, int szy, int hotX, int hotY, int fg, int bg) = 0; diff -Nru blender-2.61/intern/ghost/intern/GHOST_WindowWin32.cpp blender-2.62/intern/ghost/intern/GHOST_WindowWin32.cpp --- blender-2.61/intern/ghost/intern/GHOST_WindowWin32.cpp 2011-12-13 19:40:13.000000000 +0000 +++ blender-2.62/intern/ghost/intern/GHOST_WindowWin32.cpp 2012-02-15 19:24:34.000000000 +0000 @@ -1196,10 +1196,11 @@ return shrt; } GHOST_TSuccess GHOST_WindowWin32::setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], - GHOST_TUns8 mask[16][2], int hotX, int hotY) + GHOST_TUns8 mask[16][2], + int hotX, int hotY) { return setWindowCustomCursorShape((GHOST_TUns8*)bitmap, (GHOST_TUns8*)mask, - 16, 16, hotX, hotY, 0, 1); + 16, 16, hotX, hotY, 0, 1); } GHOST_TSuccess GHOST_WindowWin32::setWindowCustomCursorShape(GHOST_TUns8 *bitmap, @@ -1268,7 +1269,8 @@ /* Ron Fosner's code for weighting pixel formats and forcing software. See http://www.opengl.org/resources/faq/technical/weight.cpp */ -static int WeightPixelFormat(PIXELFORMATDESCRIPTOR& pfd) { +static int WeightPixelFormat(PIXELFORMATDESCRIPTOR& pfd) +{ int weight = 0; /* assume desktop color depth is 32 bits per pixel */ @@ -1301,7 +1303,8 @@ /* A modification of Ron Fosner's replacement for ChoosePixelFormat */ /* returns 0 on error, else returns the pixel format number to be used */ -static int EnumPixelFormats(HDC hdc) { +static int EnumPixelFormats(HDC hdc) +{ int iPixelFormat; int i, n, w, weight = 0; PIXELFORMATDESCRIPTOR pfd; diff -Nru blender-2.61/intern/ghost/intern/GHOST_WindowWin32.h blender-2.62/intern/ghost/intern/GHOST_WindowWin32.h --- blender-2.61/intern/ghost/intern/GHOST_WindowWin32.h 2011-12-13 19:40:13.000000000 +0000 +++ blender-2.62/intern/ghost/intern/GHOST_WindowWin32.h 2012-02-15 19:24:34.000000000 +0000 @@ -309,7 +309,9 @@ * Sets the cursor shape on the window using * native window system calls. */ - virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], GHOST_TUns8 mask[16][2], int hotX, int hotY); + virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], + GHOST_TUns8 mask[16][2], + int hotX, int hotY); virtual GHOST_TSuccess setWindowCustomCursorShape( GHOST_TUns8 *bitmap, diff -Nru blender-2.61/intern/ghost/intern/GHOST_WindowX11.cpp blender-2.62/intern/ghost/intern/GHOST_WindowX11.cpp --- blender-2.61/intern/ghost/intern/GHOST_WindowX11.cpp 2011-12-13 19:40:13.000000000 +0000 +++ blender-2.62/intern/ghost/intern/GHOST_WindowX11.cpp 2012-02-15 19:24:34.000000000 +0000 @@ -239,7 +239,8 @@ } } else { if (m_numOfAASamples && (m_numOfAASamples > samples)) { - printf("%s:%d: oversampling requested %i but using %i samples\n", __FILE__, __LINE__, m_numOfAASamples, samples); + printf("%s:%d: oversampling requested %i but using %i samples\n", + __FILE__, __LINE__, m_numOfAASamples, samples); } break; } @@ -471,7 +472,8 @@ is configured but not plugged in. */ -static int ApplicationErrorHandler(Display *display, XErrorEvent *theEvent) { +static int ApplicationErrorHandler(Display *display, XErrorEvent *theEvent) +{ fprintf(stderr, "Ignoring Xlib error: error code %d request code %d\n", theEvent->error_code, theEvent->request_code) ; @@ -1343,7 +1345,9 @@ if (!s_firstContext) { s_firstContext = m_context; } - glXMakeCurrent(m_display, m_window,m_context); + glXMakeCurrent(m_display, m_window,m_context); + glClearColor(0.447, 0.447, 0.447, 0); + glClear(GL_COLOR_BUFFER_BIT); success = GHOST_kSuccess; } else { success = GHOST_kFailure; @@ -1491,7 +1495,8 @@ } #ifdef GHOST_X11_GRAB - XGrabPointer(m_display, m_window, False, ButtonPressMask| ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); + XGrabPointer(m_display, m_window, False, ButtonPressMask | ButtonReleaseMask | PointerMotionMask, + GrabModeAsync, GrabModeAsync, None, None, CurrentTime); #endif } else { diff -Nru blender-2.61/intern/ghost/test/CMakeLists.txt blender-2.62/intern/ghost/test/CMakeLists.txt --- blender-2.61/intern/ghost/test/CMakeLists.txt 2011-12-13 19:40:16.000000000 +0000 +++ blender-2.62/intern/ghost/test/CMakeLists.txt 2012-02-15 19:24:36.000000000 +0000 @@ -35,6 +35,25 @@ # ----------------------------------------------------------------------------- +# Defines + +# set the endian define +if(MSVC) + # for some reason this fails on msvc + add_definitions(-D__LITTLE_ENDIAN__) +else() + include(TestBigEndian) + test_big_endian(_SYSTEM_BIG_ENDIAN) + if(_SYSTEM_BIG_ENDIAN) + add_definitions(-D__BIG_ENDIAN__) + else() + add_definitions(-D__LITTLE_ENDIAN__) + endif() + unset(_SYSTEM_BIG_ENDIAN) +endif() + + +# ----------------------------------------------------------------------------- # Libraries # ghost @@ -74,6 +93,7 @@ "../../../source/blender/blenlib/intern/fileops.c" "../../../source/blender/blenlib/intern/rct.c" "../../../source/blender/blenlib/intern/string.c" + "../../../source/blender/blenlib/intern/string_utf8.c" "../../../source/blender/blenlib/intern/listbase.c" "../../../source/blender/blenlib/intern/storage.c" "../../../source/blender/blenlib/intern/path_util.c" @@ -87,6 +107,8 @@ find_package(Freetype REQUIRED) +find_package(ZLIB REQUIRED) + include_directories(${CMAKE_SOURCE_DIR}/../) include_directories(${OPENGL_INCLUDE_DIR}) include_directories(${FREETYPE_INCLUDE_DIRS}) @@ -151,5 +173,6 @@ ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${FREETYPE_LIBRARY} + ${ZLIB_LIBRARIES} ${PLATFORM_LINKLIBS} ) diff -Nru blender-2.61/intern/guardedalloc/MEM_sys_types.h blender-2.62/intern/guardedalloc/MEM_sys_types.h --- blender-2.61/intern/guardedalloc/MEM_sys_types.h 2011-12-13 19:42:12.000000000 +0000 +++ blender-2.62/intern/guardedalloc/MEM_sys_types.h 2012-02-15 19:26:18.000000000 +0000 @@ -93,6 +93,16 @@ /* Linux-i386, Linux-Alpha, Linux-ppc */ #include +/* XXX */ + +#ifndef UINT64_MAX +# define UINT64_MAX 18446744073709551615 +typedef uint8_t u_int8_t; +typedef uint16_t u_int16_t; +typedef uint32_t u_int32_t; +typedef uint64_t u_int64_t; +#endif + #elif defined (__APPLE__) #include diff -Nru blender-2.61/intern/iksolver/intern/IK_Solver.cpp blender-2.62/intern/iksolver/intern/IK_Solver.cpp --- blender-2.61/intern/iksolver/intern/IK_Solver.cpp 2011-12-13 19:42:37.000000000 +0000 +++ blender-2.62/intern/iksolver/intern/IK_Solver.cpp 2012-02-15 19:26:48.000000000 +0000 @@ -225,11 +225,12 @@ void IK_GetBasisChange(IK_Segment *seg, float basis_change[][3]) { IK_QSegment *qseg = (IK_QSegment*)seg; - const MT_Matrix3x3& change = qseg->BasisChange(); if (qseg->Translational() && qseg->Composite()) qseg = qseg->Composite(); + const MT_Matrix3x3& change = qseg->BasisChange(); + // convert from moto row major to blender column major basis_change[0][0] = (float)change[0][0]; basis_change[1][0] = (float)change[0][1]; diff -Nru blender-2.61/intern/memutil/intern/MEM_CacheLimiterC-Api.cpp blender-2.62/intern/memutil/intern/MEM_CacheLimiterC-Api.cpp --- blender-2.61/intern/memutil/intern/MEM_CacheLimiterC-Api.cpp 2011-12-13 19:42:45.000000000 +0000 +++ blender-2.62/intern/memutil/intern/MEM_CacheLimiterC-Api.cpp 2012-02-15 19:27:01.000000000 +0000 @@ -29,18 +29,18 @@ #include "MEM_CacheLimiter.h" #include "MEM_CacheLimiterC-Api.h" -static intptr_t & get_max() +static size_t & get_max() { - static intptr_t m = 32*1024*1024; + static size_t m = 32*1024*1024; return m; } -void MEM_CacheLimiter_set_maximum(intptr_t m) +void MEM_CacheLimiter_set_maximum(size_t m) { get_max() = m; } -intptr_t MEM_CacheLimiter_get_maximum() +size_t MEM_CacheLimiter_get_maximum() { return get_max(); } diff -Nru blender-2.61/intern/memutil/MEM_CacheLimiterC-Api.h blender-2.62/intern/memutil/MEM_CacheLimiterC-Api.h --- blender-2.61/intern/memutil/MEM_CacheLimiterC-Api.h 2011-12-13 19:42:46.000000000 +0000 +++ blender-2.62/intern/memutil/MEM_CacheLimiterC-Api.h 2012-02-15 19:27:01.000000000 +0000 @@ -42,10 +42,10 @@ typedef void(*MEM_CacheLimiter_Destruct_Func)(void*); /* function used to measure stored data element size */ -typedef intptr_t(*MEM_CacheLimiter_DataSize_Func) (void*); +typedef size_t(*MEM_CacheLimiter_DataSize_Func) (void*); #ifndef MEM_CACHELIMITER_H -extern void MEM_CacheLimiter_set_maximum(int m); +extern void MEM_CacheLimiter_set_maximum(size_t m); extern int MEM_CacheLimiter_get_maximum(void); #endif // MEM_CACHELIMITER_H /** diff -Nru blender-2.61/intern/memutil/MEM_CacheLimiter.h blender-2.62/intern/memutil/MEM_CacheLimiter.h --- blender-2.61/intern/memutil/MEM_CacheLimiter.h 2011-12-13 19:42:46.000000000 +0000 +++ blender-2.62/intern/memutil/MEM_CacheLimiter.h 2012-02-15 19:27:01.000000000 +0000 @@ -65,8 +65,8 @@ #ifndef __MEM_cache_limiter_c_api_h_included__ extern "C" { - extern void MEM_CacheLimiter_set_maximum(intptr_t m); - extern intptr_t MEM_CacheLimiter_get_maximum(); + extern void MEM_CacheLimiter_set_maximum(size_t m); + extern size_t MEM_CacheLimiter_get_maximum(); }; #endif @@ -125,7 +125,7 @@ public: typedef typename std::list *, MEM_Allocator *> >::iterator iterator; - typedef intptr_t (*MEM_CacheLimiter_DataSize_Func) (void *data); + typedef size_t (*MEM_CacheLimiter_DataSize_Func) (void *data); MEM_CacheLimiter(MEM_CacheLimiter_DataSize_Func getDataSize_) : getDataSize(getDataSize_) { } @@ -146,8 +146,8 @@ delete handle; } void enforce_limits() { - intptr_t max = MEM_CacheLimiter_get_maximum(); - intptr_t mem_in_use, cur_size; + size_t max = MEM_CacheLimiter_get_maximum(); + size_t mem_in_use, cur_size; if (max == 0) { return; @@ -188,8 +188,8 @@ handle->me = it; } private: - intptr_t total_size() { - intptr_t size = 0; + size_t total_size() { + size_t size = 0; for (iterator it = queue.begin(); it != queue.end(); it++) { size+= getDataSize((*it)->get()->get_data()); } diff -Nru blender-2.61/intern/mikktspace/mikktspace.c blender-2.62/intern/mikktspace/mikktspace.c --- blender-2.61/intern/mikktspace/mikktspace.c 2011-12-13 19:42:33.000000000 +0000 +++ blender-2.62/intern/mikktspace/mikktspace.c 2012-02-15 19:26:44.000000000 +0000 @@ -1350,7 +1350,6 @@ for(s=0; snb_rhs; j++, b+=n, x+=n) { /* Create superlu array for B */ diff -Nru blender-2.61/intern/opennl/superlu/get_perm_c.c blender-2.62/intern/opennl/superlu/get_perm_c.c --- blender-2.61/intern/opennl/superlu/get_perm_c.c 2011-12-13 19:42:31.000000000 +0000 +++ blender-2.62/intern/opennl/superlu/get_perm_c.c 2012-02-15 19:26:43.000000000 +0000 @@ -368,7 +368,7 @@ int m, n, bnz, *b_colptr, i; int delta, maxint, nofsub, *invp; int *b_rowind, *dhead, *qsize, *llist, *marker; - double t, SuperLU_timer_(); + /* double t, SuperLU_timer_(); */ /* make gcc happy */ b_rowind=NULL; @@ -377,7 +377,7 @@ m = A->nrow; n = A->ncol; - t = SuperLU_timer_(); + /* t = SuperLU_timer_(); */ switch ( ispec ) { case 0: /* Natural ordering */ for (i = 0; i < n; ++i) perm_c[i] = i; @@ -391,8 +391,8 @@ #if ( PRNTlevel>=1 ) printf("Use minimum degree ordering on A'*A.\n"); #endif - t = SuperLU_timer_() - t; - /*printf("Form A'*A time = %8.3f\n", t);*/ + /*t = SuperLU_timer_() - t; + printf("Form A'*A time = %8.3f\n", t);*/ break; case 2: /* Minimum degree ordering on A'+A */ if ( m != n ) ABORT("Matrix is not square"); @@ -401,8 +401,8 @@ #if ( PRNTlevel>=1 ) printf("Use minimum degree ordering on A'+A.\n"); #endif - t = SuperLU_timer_() - t; - /*printf("Form A'+A time = %8.3f\n", t);*/ + /*t = SuperLU_timer_() - t; + printf("Form A'+A time = %8.3f\n", t);*/ break; case 3: /* Approximate minimum degree column ordering. */ get_colamd(m, n, Astore->nnz, Astore->colptr, Astore->rowind, @@ -417,7 +417,7 @@ } if ( bnz != 0 ) { - t = SuperLU_timer_(); + /* t = SuperLU_timer_(); */ /* Initialize and allocate storage for GENMMD. */ delta = 1; /* DELTA is a parameter to allow the choice of nodes @@ -452,8 +452,8 @@ SUPERLU_FREE(llist); SUPERLU_FREE(marker); - t = SuperLU_timer_() - t; - /* printf("call GENMMD time = %8.3f\n", t);*/ + /* t = SuperLU_timer_() - t; + printf("call GENMMD time = %8.3f\n", t);*/ } else { /* Empty adjacency structure */ for (i = 0; i < n; ++i) perm_c[i] = i; diff -Nru blender-2.61/intern/opennl/superlu/scolumn_bmod.c blender-2.62/intern/opennl/superlu/scolumn_bmod.c --- blender-2.61/intern/opennl/superlu/scolumn_bmod.c 2011-12-13 19:42:31.000000000 +0000 +++ blender-2.62/intern/opennl/superlu/scolumn_bmod.c 2012-02-15 19:26:43.000000000 +0000 @@ -303,7 +303,6 @@ d_fsupc=0 if fsupc >= fpanelc. */ d_fsupc = fst_col - fsupc; - lptr = xlsub[fsupc] + d_fsupc; luptr = xlusup[fst_col] + d_fsupc; nsupr = xlsub[fsupc+1] - xlsub[fsupc]; /* Leading dimension */ nsupc = jcol - fst_col; /* Excluding jcol */ diff -Nru blender-2.61/intern/opennl/superlu/strsv.c blender-2.62/intern/opennl/superlu/strsv.c --- blender-2.61/intern/opennl/superlu/strsv.c 2011-12-13 19:42:31.000000000 +0000 +++ blender-2.62/intern/opennl/superlu/strsv.c 2012-02-15 19:26:43.000000000 +0000 @@ -9,9 +9,6 @@ { - /* System generated locals */ - int i__1, i__2; - /* Local variables */ static int info; static float temp; @@ -213,14 +210,12 @@ } } else { if (*incx == 1) { - i__1 = *n; for (j = 1; j <= *n; ++j) { if (X(j) != 0.f) { if (nounit) { X(j) /= A(j,j); } temp = X(j); - i__2 = *n; for (i = j + 1; i <= *n; ++i) { X(i) -= temp * A(i,j); /* L50: */ @@ -230,7 +225,6 @@ } } else { jx = kx; - i__1 = *n; for (j = 1; j <= *n; ++j) { if (X(jx) != 0.f) { if (nounit) { @@ -238,7 +232,6 @@ } temp = X(jx); ix = jx; - i__2 = *n; for (i = j + 1; i <= *n; ++i) { ix += *incx; X(ix) -= temp * A(i,j); @@ -256,10 +249,8 @@ if (lsame_(uplo, "U")) { if (*incx == 1) { - i__1 = *n; for (j = 1; j <= *n; ++j) { temp = X(j); - i__2 = j - 1; for (i = 1; i <= j-1; ++i) { temp -= A(i,j) * X(i); /* L90: */ @@ -272,11 +263,9 @@ } } else { jx = kx; - i__1 = *n; for (j = 1; j <= *n; ++j) { temp = X(jx); ix = kx; - i__2 = j - 1; for (i = 1; i <= j-1; ++i) { temp -= A(i,j) * X(ix); ix += *incx; @@ -294,7 +283,6 @@ if (*incx == 1) { for (j = *n; j >= 1; --j) { temp = X(j); - i__1 = j + 1; for (i = *n; i >= j+1; --i) { temp -= A(i,j) * X(i); /* L130: */ @@ -311,7 +299,6 @@ for (j = *n; j >= 1; --j) { temp = X(jx); ix = kx; - i__1 = j + 1; for (i = *n; i >= j+1; --i) { temp -= A(i,j) * X(ix); ix -= *incx; diff -Nru blender-2.61/intern/opennl/superlu/sutil.c blender-2.62/intern/opennl/superlu/sutil.c --- blender-2.61/intern/opennl/superlu/sutil.c 2011-12-13 19:42:31.000000000 +0000 +++ blender-2.62/intern/opennl/superlu/sutil.c 2012-02-15 19:26:43.000000000 +0000 @@ -370,8 +370,6 @@ sFillRHS(trans_t trans, int nrhs, float *x, int ldx, SuperMatrix *A, SuperMatrix *B) { - NCformat *Astore; - float *Aval; DNformat *Bstore; float *rhs; float one = 1.0; @@ -379,8 +377,6 @@ int ldc; char transc[1]; - Astore = A->Store; - Aval = (float *) Astore->nzval; Bstore = B->Store; rhs = Bstore->nzval; ldc = Bstore->lda; diff -Nru blender-2.61/intern/opennl/superlu/util.h blender-2.62/intern/opennl/superlu/util.h --- blender-2.61/intern/opennl/superlu/util.h 2011-12-13 19:42:31.000000000 +0000 +++ blender-2.62/intern/opennl/superlu/util.h 2012-02-15 19:26:43.000000000 +0000 @@ -24,7 +24,8 @@ #define NUM_TEMPV(m,w,t,b) ( SUPERLU_MAX(m, (t + b)*w) ) #ifndef USER_ABORT -#define USER_ABORT(msg) superlu_abort_and_exit(msg) +#define USER_ABORT(msg) \ + { fprintf(stderr, "%s", msg); exit (-1); } #endif #define ABORT(err_msg) \ diff -Nru blender-2.61/intern/SConscript blender-2.62/intern/SConscript --- blender-2.61/intern/SConscript 2011-12-13 19:43:03.000000000 +0000 +++ blender-2.62/intern/SConscript 2012-02-15 19:27:17.000000000 +0000 @@ -22,6 +22,9 @@ # perhaps get rid of intern/csg? NEW_CSG='false' +if env ['WITH_BF_REMESH']: + SConscript(['dualcon/SConscript']) + if env['WITH_BF_FLUID']: SConscript(['elbeem/SConscript']) diff -Nru blender-2.61/intern/smoke/intern/smoke_API.cpp blender-2.62/intern/smoke/intern/smoke_API.cpp --- blender-2.61/intern/smoke/intern/smoke_API.cpp 2011-12-13 19:43:02.000000000 +0000 +++ blender-2.62/intern/smoke/intern/smoke_API.cpp 2012-02-15 19:27:17.000000000 +0000 @@ -211,7 +211,8 @@ wt->initBlenderRNA(strength); } -template < class T > inline T ABS( T a ) { +template < class T > inline T ABS( T a ) +{ return (0 < a) ? a : -a ; } diff -Nru blender-2.61/intern/tools/dump_rna2xml.py blender-2.62/intern/tools/dump_rna2xml.py --- blender-2.61/intern/tools/dump_rna2xml.py 2011-12-13 19:42:39.000000000 +0000 +++ blender-2.62/intern/tools/dump_rna2xml.py 2012-02-15 19:26:51.000000000 +0000 @@ -28,150 +28,39 @@ # Example usage # blender some.blend --background -noaudio --python intern/tools/dump_rna2xml.py +import os import bpy - -invalid_classes = (bpy.types.Operator, - bpy.types.Panel, - bpy.types.KeyingSet, - bpy.types.Header) - - -def build_property_typemap(): - - property_typemap = {} - - for attr in dir(bpy.types): - cls = getattr(bpy.types, attr) - if issubclass(cls, invalid_classes): - continue - - properties = cls.bl_rna.properties.keys() - properties.remove("rna_type") - property_typemap[attr] = properties - - return property_typemap - - -def print_ln(data): - print(data, end="") - - -def rna2xml(fw=print_ln, ident_val=" "): - from xml.sax.saxutils import quoteattr - property_typemap = build_property_typemap() - - def rna2xml_node(ident, value, parent): - ident_next = ident + ident_val - - # divide into attrs and nodes. - node_attrs = [] - nodes_items = [] - nodes_lists = [] - - value_type = type(value) - - if issubclass(value_type, invalid_classes): - return - - # XXX, fixme, pointcache has eternal nested pointer to its self. - if value == parent: - return - - value_type_name = value_type.__name__ - for prop in property_typemap[value_type_name]: - - subvalue = getattr(value, prop) - subvalue_type = type(subvalue) - - if subvalue_type == int: - node_attrs.append("%s=\"%d\"" % (prop, subvalue)) - elif subvalue_type == float: - node_attrs.append("%s=\"%.4g\"" % (prop, subvalue)) - elif subvalue_type == bool: - node_attrs.append("%s=\"%s\"" % (prop, "TRUE" if subvalue else "FALSE")) - elif subvalue_type is str: - node_attrs.append("%s=%s" % (prop, quoteattr(subvalue))) - elif subvalue_type == set: - node_attrs.append("%s=%s" % (prop, quoteattr("{" + ",".join(list(subvalue)) + "}"))) - elif subvalue is None: - node_attrs.append("%s=\"NONE\"" % prop) - elif issubclass(subvalue_type, bpy.types.ID): - # special case, ID's are always referenced. - node_attrs.append("%s=%s" % (prop, quoteattr(subvalue_type.__name__ + ":" + subvalue.name))) - else: - try: - subvalue_ls = list(subvalue) - except: - subvalue_ls = None - - if subvalue_ls is None: - nodes_items.append((prop, subvalue, subvalue_type)) - else: - # check if the list contains native types - subvalue_rna = value.path_resolve(prop, False) - if type(subvalue_rna).__name__ == "bpy_prop_array": - # TODO, multi-dim! - def str_recursive(s): - if type(s) in (int, float, bool): - return str(s) - else: - return " ".join([str_recursive(si) for si in s]) - - node_attrs.append("%s=\"%s\"" % (prop, " ".join(str_recursive(v) for v in subvalue_rna))) - else: - nodes_lists.append((prop, subvalue_ls, subvalue_type)) - - # declare + attributes - fw("%s<%s %s>\n" % (ident, value_type_name, " ".join(node_attrs))) - - # unique members - for prop, subvalue, subvalue_type in nodes_items: - rna2xml_node(ident_next, subvalue, value) - - # list members - for prop, subvalue, subvalue_type in nodes_lists: - fw("%s<%s>\n" % (ident_next, prop)) - for subvalue_item in subvalue: - if subvalue_item is not None: - rna2xml_node(ident_next + ident_val, subvalue_item, value) - fw("%s\n" % (ident_next, prop)) - - fw("%s\n" % (ident, value_type_name)) - - fw("\n") - for attr in dir(bpy.data): - - # exceptions - if attr.startswith("_"): - continue - elif attr == "window_managers": - continue - - value = getattr(bpy.data, attr) - try: - ls = value[:] - except: - ls = None - - if type(ls) == list: - fw("%s<%s>\n" % (ident_val, attr)) - for blend_id in ls: - rna2xml_node(ident_val + ident_val, blend_id, None) - fw("%s\n" % (ident_val, attr)) - - fw("\n") +import rna_xml def main(): - filename = bpy.data.filepath.rstrip(".blend") + ".xml" + filename = os.path.splitext(bpy.data.filepath)[0] + ".xml" + file = open(filename, 'w') - rna2xml(file.write) - file.close() - # read back. + if 0: + # blend file + rna_xml.rna2xml(file.write, + root_rna=bpy.data, + root_rna_skip={"window_managers"}) + else: + # theme. just another test + rna_xml.rna2xml(file.write, + root_rna=bpy.context.user_preferences.themes[0], + method='ATTR') + + file.close() + + # read back to ensure this is valid! from xml.dom.minidom import parse xml_nodes = parse(filename) print("Written:", filename) + # test reading back theme + if 1: + theme = xml_nodes.getElementsByTagName("Theme")[0] + rna_xml.xml2rna(theme, + root_rna=bpy.context.user_preferences.themes[0],) + if __name__ == "__main__": main() Binary files /tmp/Hbut4VSIdq/blender-2.61/release/datafiles/blender_icons.png and /tmp/8U6hTXcDGf/blender-2.62/release/datafiles/blender_icons.png differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/datafiles/locale/ar/LC_MESSAGES/blender.mo and /tmp/8U6hTXcDGf/blender-2.62/release/datafiles/locale/ar/LC_MESSAGES/blender.mo differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/datafiles/locale/bg/LC_MESSAGES/blender.mo and /tmp/8U6hTXcDGf/blender-2.62/release/datafiles/locale/bg/LC_MESSAGES/blender.mo differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/datafiles/locale/ca/LC_MESSAGES/blender.mo and /tmp/8U6hTXcDGf/blender-2.62/release/datafiles/locale/ca/LC_MESSAGES/blender.mo differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/datafiles/locale/cs/LC_MESSAGES/blender.mo and /tmp/8U6hTXcDGf/blender-2.62/release/datafiles/locale/cs/LC_MESSAGES/blender.mo differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/datafiles/locale/de/LC_MESSAGES/blender.mo and /tmp/8U6hTXcDGf/blender-2.62/release/datafiles/locale/de/LC_MESSAGES/blender.mo differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/datafiles/locale/el/LC_MESSAGES/blender.mo and /tmp/8U6hTXcDGf/blender-2.62/release/datafiles/locale/el/LC_MESSAGES/blender.mo differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/datafiles/locale/es/LC_MESSAGES/blender.mo and /tmp/8U6hTXcDGf/blender-2.62/release/datafiles/locale/es/LC_MESSAGES/blender.mo differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/datafiles/locale/es_ES/LC_MESSAGES/blender.mo and /tmp/8U6hTXcDGf/blender-2.62/release/datafiles/locale/es_ES/LC_MESSAGES/blender.mo differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/datafiles/locale/es_MX/LC_MESSAGES/blender.mo and /tmp/8U6hTXcDGf/blender-2.62/release/datafiles/locale/es_MX/LC_MESSAGES/blender.mo differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/datafiles/locale/fa/LC_MESSAGES/blender.mo and /tmp/8U6hTXcDGf/blender-2.62/release/datafiles/locale/fa/LC_MESSAGES/blender.mo differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/datafiles/locale/fi/LC_MESSAGES/blender.mo and /tmp/8U6hTXcDGf/blender-2.62/release/datafiles/locale/fi/LC_MESSAGES/blender.mo differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/datafiles/locale/fr/LC_MESSAGES/blender.mo and /tmp/8U6hTXcDGf/blender-2.62/release/datafiles/locale/fr/LC_MESSAGES/blender.mo differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/datafiles/locale/id/LC_MESSAGES/blender.mo and /tmp/8U6hTXcDGf/blender-2.62/release/datafiles/locale/id/LC_MESSAGES/blender.mo differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/datafiles/locale/it/LC_MESSAGES/blender.mo and /tmp/8U6hTXcDGf/blender-2.62/release/datafiles/locale/it/LC_MESSAGES/blender.mo differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/datafiles/locale/ja/LC_MESSAGES/blender.mo and /tmp/8U6hTXcDGf/blender-2.62/release/datafiles/locale/ja/LC_MESSAGES/blender.mo differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/datafiles/locale/ky/LC_MESSAGES/blender.mo and /tmp/8U6hTXcDGf/blender-2.62/release/datafiles/locale/ky/LC_MESSAGES/blender.mo differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/datafiles/locale/ne/LC_MESSAGES/blender.mo and /tmp/8U6hTXcDGf/blender-2.62/release/datafiles/locale/ne/LC_MESSAGES/blender.mo differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/datafiles/locale/pl/LC_MESSAGES/blender.mo and /tmp/8U6hTXcDGf/blender-2.62/release/datafiles/locale/pl/LC_MESSAGES/blender.mo differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/datafiles/locale/pt_BR/LC_MESSAGES/blender.mo and /tmp/8U6hTXcDGf/blender-2.62/release/datafiles/locale/pt_BR/LC_MESSAGES/blender.mo differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/datafiles/locale/ru/LC_MESSAGES/blender.mo and /tmp/8U6hTXcDGf/blender-2.62/release/datafiles/locale/ru/LC_MESSAGES/blender.mo differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/datafiles/locale/sr/LC_MESSAGES/blender.mo and /tmp/8U6hTXcDGf/blender-2.62/release/datafiles/locale/sr/LC_MESSAGES/blender.mo differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/datafiles/locale/sr@latin/LC_MESSAGES/blender.mo and /tmp/8U6hTXcDGf/blender-2.62/release/datafiles/locale/sr@latin/LC_MESSAGES/blender.mo differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/datafiles/locale/sv/LC_MESSAGES/blender.mo and /tmp/8U6hTXcDGf/blender-2.62/release/datafiles/locale/sv/LC_MESSAGES/blender.mo differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/datafiles/locale/zh_CN/LC_MESSAGES/blender.mo and /tmp/8U6hTXcDGf/blender-2.62/release/datafiles/locale/zh_CN/LC_MESSAGES/blender.mo differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/datafiles/locale/zh_TW/LC_MESSAGES/blender.mo and /tmp/8U6hTXcDGf/blender-2.62/release/datafiles/locale/zh_TW/LC_MESSAGES/blender.mo differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/datafiles/splash.png and /tmp/8U6hTXcDGf/blender-2.62/release/datafiles/splash.png differ diff -Nru blender-2.61/release/plugins/sequence/color-correction-hsv.c blender-2.62/release/plugins/sequence/color-correction-hsv.c --- blender-2.61/release/plugins/sequence/color-correction-hsv.c 2011-12-13 19:43:04.000000000 +0000 +++ blender-2.62/release/plugins/sequence/color-correction-hsv.c 2012-02-15 19:27:19.000000000 +0000 @@ -62,7 +62,8 @@ void plugin_but_changed(int but) {} void plugin_init() {} -void plugin_getinfo(PluginInfo *info) { +void plugin_getinfo(PluginInfo *info) +{ info->name= name; info->nvars= sizeof(varstr)/sizeof(VarStruct); info->cfra= &cfra; diff -Nru blender-2.61/release/plugins/sequence/color-correction-yuv.c blender-2.62/release/plugins/sequence/color-correction-yuv.c --- blender-2.61/release/plugins/sequence/color-correction-yuv.c 2011-12-13 19:43:04.000000000 +0000 +++ blender-2.62/release/plugins/sequence/color-correction-yuv.c 2012-02-15 19:27:19.000000000 +0000 @@ -62,7 +62,8 @@ void plugin_but_changed(int but) {} void plugin_init() {} -void plugin_getinfo(PluginInfo *info) { +void plugin_getinfo(PluginInfo *info) +{ info->name= name; info->nvars= sizeof(varstr)/sizeof(VarStruct); info->cfra= &cfra; @@ -74,7 +75,8 @@ info->callback= plugin_but_changed; } -static void rgb_to_yuv(float rgb[3], float yuv[3]) { +static void rgb_to_yuv(float rgb[3], float yuv[3]) +{ yuv[0]= 0.299*rgb[0] + 0.587*rgb[1] + 0.114*rgb[2]; yuv[1]= 0.492*(rgb[2] - yuv[0]); yuv[2]= 0.877*(rgb[0] - yuv[0]); @@ -84,7 +86,8 @@ yuv[2] /= 0.615; } -static void yuv_to_rgb(float yuv[3], float rgb[3]) { +static void yuv_to_rgb(float yuv[3], float rgb[3]) +{ yuv[1] *= 0.436; yuv[2] *= 0.615; diff -Nru blender-2.61/release/plugins/sequence/dnr.c blender-2.62/release/plugins/sequence/dnr.c --- blender-2.61/release/plugins/sequence/dnr.c 2011-12-13 19:43:04.000000000 +0000 +++ blender-2.62/release/plugins/sequence/dnr.c 2012-02-15 19:27:19.000000000 +0000 @@ -90,7 +90,8 @@ free(d); } -void plugin_getinfo(PluginInfo *info) { +void plugin_getinfo(PluginInfo *info) +{ info->name= name; info->nvars= sizeof(varstr)/sizeof(VarStruct); info->cfra= &cfra; diff -Nru blender-2.61/release/plugins/sequence/gamma.c blender-2.62/release/plugins/sequence/gamma.c --- blender-2.61/release/plugins/sequence/gamma.c 2011-12-13 19:43:04.000000000 +0000 +++ blender-2.62/release/plugins/sequence/gamma.c 2012-02-15 19:27:19.000000000 +0000 @@ -67,7 +67,8 @@ void plugin_but_changed(int but) {} void plugin_init() {} -void plugin_getinfo(PluginInfo *info) { +void plugin_getinfo(PluginInfo *info) +{ info->name= name; info->nvars= sizeof(varstr)/sizeof(VarStruct); info->cfra= &cfra; diff -Nru blender-2.61/release/scripts/addons/add_curve_aceous_galore.py blender-2.62/release/scripts/addons/add_curve_aceous_galore.py --- blender-2.61/release/scripts/addons/add_curve_aceous_galore.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/add_curve_aceous_galore.py 2012-02-15 19:43:32.000000000 +0000 @@ -21,7 +21,6 @@ 'author': 'Jimmy Hazevoet, testscreenings', 'version': (0,2), "blender": (2, 5, 9), - "api": 39685, 'location': 'View3D > Add > Curve', 'description': 'Adds many different types of Curves', 'warning': '', # used for warning icon and text in addons panel diff -Nru blender-2.61/release/scripts/addons/add_curve_ivygen.py blender-2.62/release/scripts/addons/add_curve_ivygen.py --- blender-2.61/release/scripts/addons/add_curve_ivygen.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/add_curve_ivygen.py 2012-02-15 19:43:32.000000000 +0000 @@ -23,7 +23,6 @@ "author": "testscreenings, PKHG, TrumanBlending", "version": (0, 1, 1), "blender": (2, 5, 9), - "api": 39307, "location": "View3D > Add > Curve", "description": "Adds generated ivy to a mesh object starting at the 3D"\ " cursor", diff -Nru blender-2.61/release/scripts/addons/add_curve_sapling/__init__.py blender-2.62/release/scripts/addons/add_curve_sapling/__init__.py --- blender-2.61/release/scripts/addons/add_curve_sapling/__init__.py 2011-12-13 19:59:06.000000000 +0000 +++ blender-2.62/release/scripts/addons/add_curve_sapling/__init__.py 2012-02-15 19:43:31.000000000 +0000 @@ -21,7 +21,6 @@ "author": "Andrew Hale (TrumanBlending)", "version": (0, 2, 5), "blender": (2, 5, 9), - "api": 39307, "location": "View3D > Add > Curve", "description": ("Adds a parametric tree. The method is presented by " "Jason Weber & Joseph Penn in their paper 'Creation and Rendering of " @@ -153,7 +152,7 @@ class AddTree(bpy.types.Operator): bl_idname = "curve.tree_add" - bl_label = "Sapling" + bl_label = "Sapling: Add Tree" bl_options = {'REGISTER', 'UNDO'} diff -Nru blender-2.61/release/scripts/addons/add_curve_torus_knots.py blender-2.62/release/scripts/addons/add_curve_torus_knots.py --- blender-2.61/release/scripts/addons/add_curve_torus_knots.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/add_curve_torus_knots.py 2012-02-15 19:43:32.000000000 +0000 @@ -22,7 +22,6 @@ "author": "testscreenings", "version": (0,1), "blender": (2, 5, 9), - "api": 39685, "location": "View3D > Add > Curve", "description": "Adds many types of (torus) knots", "warning": "", @@ -131,7 +130,7 @@ torus_res = IntProperty(name="Resoulution", default=100, min=3, soft_min=3, - description='Resolution, Number of controlverticies.') + description='Resolution, Number of controlverticies') torus_p = IntProperty(name="p", default=2, min=1, soft_min=1, diff -Nru blender-2.61/release/scripts/addons/add_mesh_ant_landscape.py blender-2.62/release/scripts/addons/add_mesh_ant_landscape.py --- blender-2.61/release/scripts/addons/add_mesh_ant_landscape.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/add_mesh_ant_landscape.py 2012-02-15 19:43:32.000000000 +0000 @@ -19,9 +19,8 @@ bl_info = { "name": "ANT Landscape", "author": "Jimmy Hazevoet", - "version": (0,1,1), - "blender": (2, 5, 9), - "api": 39685, + "version": (0,1,2), + "blender": (2, 6, 1), "location": "View3D > Add > Mesh", "description": "Add a landscape primitive", "warning": "", # used for warning icon and text in addons panel @@ -434,7 +433,7 @@ '''Add a landscape mesh''' bl_idname = "mesh.landscape_add" bl_label = "Landscape" - bl_options = {'REGISTER', 'UNDO'} + bl_options = {'REGISTER', 'UNDO', 'PRESET'} bl_description = "Add landscape mesh" # properties diff -Nru blender-2.61/release/scripts/addons/add_mesh_BoltFactory/Boltfactory.py blender-2.62/release/scripts/addons/add_mesh_BoltFactory/Boltfactory.py --- blender-2.61/release/scripts/addons/add_mesh_BoltFactory/Boltfactory.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/add_mesh_BoltFactory/Boltfactory.py 2012-02-15 19:43:32.000000000 +0000 @@ -45,7 +45,7 @@ '''''' bl_idname = "mesh.bolt_add" bl_label = "Add Bolt" - bl_options = {'REGISTER', 'UNDO'} + bl_options = {'REGISTER', 'UNDO', 'PRESET'} bl_description = "adds many types of Bolts" align_matrix = mathutils.Matrix() diff -Nru blender-2.61/release/scripts/addons/add_mesh_BoltFactory/createMesh.py blender-2.62/release/scripts/addons/add_mesh_BoltFactory/createMesh.py --- blender-2.61/release/scripts/addons/add_mesh_BoltFactory/createMesh.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/add_mesh_BoltFactory/createMesh.py 2012-02-15 19:43:32.000000000 +0000 @@ -20,7 +20,7 @@ import mathutils from math import * -from itertools import * +from itertools import * NARROW_UI = 180 MAX_INPUT_NUMBER = 50 @@ -47,14 +47,14 @@ if len(face) != 3 and len(face) != 4: raise RuntimeError("{0} vertices in face".format(len(face))) - + # rotate indices if the 4th is 0 if len(face) == 4 and face[3] == 0: face = [face[3], face[0], face[1], face[2]] if len(face) == 3: face.append(0) - + l.extend(face) return l @@ -76,7 +76,7 @@ new_faces = [] dict_verts = {} Rounded_Verts = [] - + for v in verts: Rounded_Verts.append([round(v[0],Decimal_Places),round(v[1],Decimal_Places),round(v[2],Decimal_Places)]) @@ -89,12 +89,12 @@ if Rounded_co not in dict_verts: dict_verts[Rounded_co] = len(dict_verts) new_verts.append(Real_co) - if dict_verts[Rounded_co] not in new_face: + if dict_verts[Rounded_co] not in new_face: new_face.append(dict_verts[Rounded_co]) if len(new_face) == 3 or len(new_face) == 4: new_faces.append(new_face) - return new_verts,new_faces + return new_verts,new_faces @@ -123,19 +123,19 @@ # * axis (Vector object. (optional)) - The arbitrary axis of rotation used with "R" # #Returns: Matrix object. -# A new rotation matrix. +# A new rotation matrix. def Simple_RotationMatrix(angle, matSize, axisFlag): if matSize != 4 : print ("Simple_RotationMatrix can only do 4x4") - + q = radians(angle) #make the rotation go clockwise - + if axisFlag == 'x': - matrix = mathutils.Matrix(((1,0,0,0),(0,cos(q),sin(q),0),(0,-sin(q),cos(q),0),(0,0,0,1))) + matrix = mathutils.Matrix.Rotation(q, 4, 'X') elif axisFlag == 'y': - matrix = mathutils.Matrix(((cos(q),0,-sin(q),0),(0,1,0,0),(sin(q),0,cos(q),0),(0,0,0,1))) + matrix = mathutils.Matrix.Rotation(q, 4, 'Y') elif axisFlag == 'z': - matrix = mathutils.Matrix(((cos(q),sin(q),0,0),(-sin(q),cos(q),0,0),(0,0,1,0),(0,0,0,1))) + matrix = mathutils.Matrix.Rotation(q, 4, 'Z') else: print ("Simple_RotationMatrix can only do x y z axis") return matrix @@ -143,7 +143,7 @@ ########################################################################################## ########################################################################################## -## Converter Functions For Bolt Factory +## Converter Functions For Bolt Factory ########################################################################################## ########################################################################################## @@ -157,7 +157,7 @@ Bit_Rad = Bit_Dia / 2.0 x = Bit_Rad - Flat_Width_half y = tan(radians(60))*x - return float(y) + return float(y) ########################################################################################## @@ -168,11 +168,11 @@ # Returns a list of verts rotated by the given matrix. Used by SpinDup def Rot_Mesh(verts, matrix): - Vector = mathutils.Vector + from mathutils import Vector return [(matrix * Vector(v))[:] for v in verts] -# Returns a list of faces that has there index incremented by offset +# Returns a list of faces that has there index incremented by offset def Copy_Faces(faces,offset): return [[(i + offset) for i in f] for f in faces] @@ -181,60 +181,60 @@ def SpinDup(VERTS,FACES,DEGREE,DIVISIONS,AXIS): verts=[] faces=[] - + if DIVISIONS == 0: - DIVISIONS = 1 - + DIVISIONS = 1 + step = DEGREE/DIVISIONS # set step so pieces * step = degrees in arc - + for i in range(int(DIVISIONS)): rotmat = Simple_RotationMatrix(step*i, 4, AXIS) # 4x4 rotation matrix, 30d about the x axis. Rot = Rot_Mesh(VERTS,rotmat) - faces.extend(Copy_Faces(FACES,len(verts))) + faces.extend(Copy_Faces(FACES,len(verts))) verts.extend(Rot) return verts,faces # Returns a list of verts that have been moved up the z axis by DISTANCE -def Move_Verts_Up_Z(VERTS,DISTANCE): +def Move_Verts_Up_Z(VERTS,DISTANCE): ret = [] for v in VERTS: ret.append([v[0],v[1],v[2]+DISTANCE]) return ret -# Returns a list of verts and faces that has been mirrored in the AXIS +# Returns a list of verts and faces that has been mirrored in the AXIS def Mirror_Verts_Faces(VERTS,FACES,AXIS,FLIP_POINT =0): ret_vert = [] ret_face = [] - offset = len(VERTS) + offset = len(VERTS) if AXIS == 'y': for v in VERTS: Delta = v[0] - FLIP_POINT - ret_vert.append([FLIP_POINT-Delta,v[1],v[2]]) + ret_vert.append([FLIP_POINT-Delta,v[1],v[2]]) if AXIS == 'x': for v in VERTS: Delta = v[1] - FLIP_POINT - ret_vert.append([v[0],FLIP_POINT-Delta,v[2]]) + ret_vert.append([v[0],FLIP_POINT-Delta,v[2]]) if AXIS == 'z': for v in VERTS: Delta = v[2] - FLIP_POINT - ret_vert.append([v[0],v[1],FLIP_POINT-Delta]) - + ret_vert.append([v[0],v[1],FLIP_POINT-Delta]) + for f in FACES: fsub = [] for i in range(len(f)): fsub.append(f[i]+ offset) fsub.reverse() # flip the order to make norm point out ret_face.append(fsub) - + return ret_vert,ret_face -# Returns a list of faces that -# make up an array of 4 point polygon. +# Returns a list of faces that +# make up an array of 4 point polygon. def Build_Face_List_Quads(OFFSET,COLUM,ROW,FLIP = 0): Ret =[] RowStart = 0; @@ -252,7 +252,7 @@ return Ret -# Returns a list of faces that makes up a fill pattern for a +# Returns a list of faces that makes up a fill pattern for a # circle def Fill_Ring_Face(OFFSET,NUM,FACE_DOWN = 0): Ret =[] @@ -275,7 +275,7 @@ else: TempFace[0] =Face[C]; if Face[C] == 0: - TempFace[1] = NUM-1; + TempFace[1] = NUM-1; else: TempFace[1] = Face[C] - 1; TempFace[2] = Face[B]; @@ -283,12 +283,12 @@ Ret.append([OFFSET+Face[0],OFFSET+Face[1],OFFSET+Face[2]]) else: Ret.append([OFFSET+Face[2],OFFSET+Face[1],OFFSET+Face[0]]) - + Face[0] = TempFace[0] Face[1] = TempFace[1] Face[2] = TempFace[2] return Ret - + ###################################################################################### ########################################################################################## ########################################################################################## @@ -309,16 +309,16 @@ [20,7,6], [20,8,7], [20,9,8], - + [20,21,9], - + [21,10,9], [21,11,10], [21,12,11], [21,13,12], [21,14,13], [21,15,14], - + [21,22,15], [22,16,15], [22,17,16], @@ -329,62 +329,62 @@ faces.append([OFFSET+i[2],OFFSET+i[1],OFFSET+i[0]]) else: faces.append([OFFSET+i[0],OFFSET+i[1],OFFSET+i[2]]) - + return faces def Allen_Bit_Dia(FLAT_DISTANCE): Flat_Radius = (float(FLAT_DISTANCE)/2.0)/cos(radians(30)) return (Flat_Radius * 1.05) * 2.0 - + def Allen_Bit_Dia_To_Flat(DIA): Flat_Radius = (DIA/2.0)/1.05 return (Flat_Radius * cos (radians(30)))* 2.0 - - + + def Create_Allen_Bit(FLAT_DISTANCE,HEIGHT): Div = 36 verts = [] faces = [] - + Flat_Radius = (float(FLAT_DISTANCE)/2.0)/cos(radians(30)) OUTTER_RADIUS = Flat_Radius * 1.05 Outter_Radius_Height = Flat_Radius * (0.1/5.77) FaceStart_Outside = len(verts) Deg_Step = 360.0 /float(Div) - + for i in range(int(Div/2)+1): # only do half and mirror later x = sin(radians(i*Deg_Step))*OUTTER_RADIUS y = cos(radians(i*Deg_Step))*OUTTER_RADIUS verts.append([x,y,0]) - + FaceStart_Inside = len(verts) - - Deg_Step = 360.0 /float(6) - for i in range(int(6/2)+1): + + Deg_Step = 360.0 /float(6) + for i in range(int(6/2)+1): x = sin(radians(i*Deg_Step))* Flat_Radius y = cos(radians(i*Deg_Step))* Flat_Radius - verts.append([x,y,0-Outter_Radius_Height]) - + verts.append([x,y,0-Outter_Radius_Height]) + faces.extend(Allen_Fill(FaceStart_Outside,0)) - - + + FaceStart_Bottom = len(verts) - - Deg_Step = 360.0 /float(6) - for i in range(int(6/2)+1): + + Deg_Step = 360.0 /float(6) + for i in range(int(6/2)+1): x = sin(radians(i*Deg_Step))* Flat_Radius y = cos(radians(i*Deg_Step))* Flat_Radius - verts.append([x,y,0-HEIGHT]) - + verts.append([x,y,0-HEIGHT]) + faces.extend(Build_Face_List_Quads(FaceStart_Inside,3,1,True)) faces.extend(Fill_Ring_Face(FaceStart_Bottom,4)) - - + + M_Verts,M_Faces = Mirror_Verts_Faces(verts,faces,'y') verts.extend(M_Verts) faces.extend(M_Faces) - + return verts,faces,OUTTER_RADIUS * 2.0 @@ -401,32 +401,32 @@ [1,11,10], [1,2,11], [2,12,11], - + [2,3,12], [3,4,12], [4,5,12], [5,6,12], [6,7,12], - + [7,13,12], [7,8,13], [8,14,13], [8,9,14], - - + + [10,11,16,15], [11,12,16], [12,13,16], [13,14,17,16], [15,16,17,18] - - + + ] for i in Lookup: if FLIP: if len(i) == 3: faces.append([OFFSET+i[2],OFFSET+i[1],OFFSET+i[0]]) - else: + else: faces.append([OFFSET+i[3],OFFSET+i[2],OFFSET+i[1],OFFSET+i[0]]) else: if len(i) == 3: @@ -441,20 +441,20 @@ Div = 36 verts = [] faces = [] - + FLAT_RADIUS = FLAT_DIA * 0.5 OUTTER_RADIUS = FLAT_RADIUS * 1.05 - + Flat_Half = float(FLAT_WIDTH)/2.0 - + FaceStart_Outside = len(verts) Deg_Step = 360.0 /float(Div) for i in range(int(Div/4)+1): # only do half and mirror later x = sin(radians(i*Deg_Step))*OUTTER_RADIUS y = cos(radians(i*Deg_Step))*OUTTER_RADIUS verts.append([x,y,0]) - - + + # FaceStart_Inside = len(verts) # UNUSED verts.append([0,FLAT_RADIUS,0]) #10 verts.append([Flat_Half,FLAT_RADIUS,0]) #11 @@ -462,19 +462,19 @@ verts.append([FLAT_RADIUS,Flat_Half,0]) #13 verts.append([FLAT_RADIUS,0,0]) #14 - + verts.append([0,Flat_Half,0-HEIGHT]) #15 verts.append([Flat_Half,Flat_Half,0-HEIGHT]) #16 verts.append([Flat_Half,0,0-HEIGHT]) #17 - + verts.append([0,0,0-HEIGHT]) #18 - + faces.extend(Phillips_Fill(FaceStart_Outside,True)) Spin_Verts,Spin_Face = SpinDup(verts,faces,360,4,'z') - + return Spin_Verts,Spin_Face,OUTTER_RADIUS * 2 - + ########################################################################################## ########################################################################################## @@ -504,7 +504,7 @@ EndRad = HEAD_RADIUS * 0.284 EndZOffset = HEAD_RADIUS * 0.432 HEIGHT = HEAD_RADIUS * 0.59 - + # Dome_Rad = 5.6 # RAD_Offset = 4.9 # OtherRad = 0.8 @@ -515,7 +515,7 @@ # EndRad = 1.42 # EndZOffset = 2.16 # HEIGHT = 2.95 - + FaceStart = FACE_OFFSET z = cos(radians(10))*ZRad @@ -538,23 +538,23 @@ else: verts.append([(HEAD_RADIUS -EndRad)+x,0.0,(0.0 - EndZOffset)+z]) Row += 1 - - + + verts.append([SHANK_RADIUS,0.0,(0.0-HEIGHT)]) Row += 1 - + verts.append([SHANK_RADIUS,0.0,(0.0-HEIGHT)-Start_Height]) Row += 1 sVerts,sFaces = SpinDup(verts,faces,360,DIV,'z') sVerts.extend(verts) #add the start verts to the Spin verts to complete the loop - + faces.extend(Build_Face_List_Quads(FaceStart,Row-1,DIV)) # Global_Head_Height = HEIGHT # UNUSED - + return Move_Verts_Up_Z(sVerts,Start_Height),faces,HEIGHT @@ -564,13 +564,13 @@ HOLE_RADIUS = HOLE_DIA * 0.5 HEAD_RADIUS = HEAD_DIA * 0.5 SHANK_RADIUS = SHANK_DIA * 0.5 - + verts = [] faces = [] Row = 0 # BEVEL = HEIGHT * 0.01 # UNUSED #Dome_Rad = HEAD_RADIUS * (1.0/1.75) - + Dome_Rad = HEAD_RADIUS * 1.12 #Head_Height = HEAD_RADIUS * 0.78 RAD_Offset = HEAD_RADIUS * 0.98 @@ -578,18 +578,18 @@ OtherRad = HEAD_RADIUS * 0.16 OtherRad_X_Offset = HEAD_RADIUS * 0.84 OtherRad_Z_Offset = HEAD_RADIUS * 0.504 - - + + # Dome_Rad = 5.6 # RAD_Offset = 4.9 # Dome_Height = 3.2 # OtherRad = 0.8 # OtherRad_X_Offset = 4.2 # OtherRad_Z_Offset = 2.52 -# - +# + FaceStart = FACE_OFFSET - + verts.append([HOLE_RADIUS,0.0,0.0]) Row += 1 @@ -610,14 +610,14 @@ z = (0.0-Dome_Height) verts.append([OtherRad_X_Offset+x,0.0,z]) Row += 1 - + verts.append([SHANK_RADIUS,0.0,(0.0-Dome_Height)]) Row += 1 sVerts,sFaces = SpinDup(verts,faces,360,DIV,'z') sVerts.extend(verts) #add the start verts to the Spin verts to complete the loop - + faces.extend(Build_Face_List_Quads(FaceStart,Row-1,DIV)) return sVerts,faces,Dome_Height @@ -626,12 +626,12 @@ def Create_CounterSink_Head(HOLE_DIA,HEAD_DIA,SHANK_DIA,HEIGHT,RAD1): DIV = 36 - + HOLE_RADIUS = HOLE_DIA * 0.5 HEAD_RADIUS = HEAD_DIA * 0.5 SHANK_RADIUS = SHANK_DIA * 0.5 - - + + verts = [] faces = [] Row = 0 @@ -639,20 +639,20 @@ # HEAD_RADIUS = (HEIGHT/tan(radians(60))) + SHANK_RADIUS HEIGHT = tan(radians(60)) * (HEAD_RADIUS - SHANK_RADIUS) #print (RAD1) - + FaceStart = len(verts) verts.append([HOLE_RADIUS,0.0,0.0]) Row += 1 #rad - + for i in range(0,100,10): x = sin(radians(i))*RAD1 z = cos(radians(i))*RAD1 verts.append([(HEAD_RADIUS-RAD1)+x,0.0,(0.0-RAD1)+z]) Row += 1 - + verts.append([SHANK_RADIUS,0.0,0.0-HEIGHT]) Row += 1 @@ -660,10 +660,10 @@ sVerts,sFaces = SpinDup(verts,faces,360,DIV,'z') sVerts.extend(verts) #add the start verts to the Spin verts to complete the loop - + faces.extend(Build_Face_List_Quads(FaceStart,Row-1,DIV,1)) - + return sVerts,faces,HEIGHT @@ -671,31 +671,31 @@ def Create_Cap_Head(HOLE_DIA,HEAD_DIA,SHANK_DIA,HEIGHT,RAD1,RAD2): DIV = 36 - + HOLE_RADIUS = HOLE_DIA * 0.5 HEAD_RADIUS = HEAD_DIA * 0.5 SHANK_RADIUS = SHANK_DIA * 0.5 - + verts = [] faces = [] Row = 0 BEVEL = HEIGHT * 0.01 - - + + FaceStart = len(verts) verts.append([HOLE_RADIUS,0.0,0.0]) Row += 1 #rad - + for i in range(0,100,10): x = sin(radians(i))*RAD1 z = cos(radians(i))*RAD1 verts.append([(HEAD_RADIUS-RAD1)+x,0.0,(0.0-RAD1)+z]) Row += 1 - - + + verts.append([HEAD_RADIUS,0.0,0.0-HEIGHT+BEVEL]) Row += 1 @@ -703,246 +703,246 @@ Row += 1 #rad2 - + for i in range(0,100,10): x = sin(radians(i))*RAD2 z = cos(radians(i))*RAD2 verts.append([(SHANK_RADIUS+RAD2)-x,0.0,(0.0-HEIGHT-RAD2)+z]) Row += 1 - + sVerts,sFaces = SpinDup(verts,faces,360,DIV,'z') sVerts.extend(verts) #add the start verts to the Spin verts to complete the loop - + faces.extend(Build_Face_List_Quads(FaceStart,Row-1,DIV)) - + return sVerts,faces,HEIGHT+RAD2 def Create_Hex_Head(FLAT,HOLE_DIA,SHANK_DIA,HEIGHT): - + verts = [] faces = [] HOLE_RADIUS = HOLE_DIA * 0.5 Half_Flat = FLAT/2 TopBevelRadius = Half_Flat - (Half_Flat* (0.05/8)) Undercut_Height = (Half_Flat* (0.05/8)) - Shank_Bevel = (Half_Flat* (0.05/8)) + Shank_Bevel = (Half_Flat* (0.05/8)) Flat_Height = HEIGHT - Undercut_Height - Shank_Bevel #Undercut_Height = 5 SHANK_RADIUS = SHANK_DIA/2 Row = 0; verts.append([0.0,0.0,0.0]) - - + + FaceStart = len(verts) #inner hole - + x = sin(radians(0))*HOLE_RADIUS y = cos(radians(0))*HOLE_RADIUS verts.append([x,y,0.0]) - - + + x = sin(radians(60/6))*HOLE_RADIUS y = cos(radians(60/6))*HOLE_RADIUS verts.append([x,y,0.0]) - - + + x = sin(radians(60/3))*HOLE_RADIUS y = cos(radians(60/3))*HOLE_RADIUS verts.append([x,y,0.0]) - - + + x = sin(radians(60/2))*HOLE_RADIUS y = cos(radians(60/2))*HOLE_RADIUS verts.append([x,y,0.0]) Row += 1 - + #bevel - + x = sin(radians(0))*TopBevelRadius y = cos(radians(0))*TopBevelRadius vec1 = mathutils.Vector([x,y,0.0]) verts.append([x,y,0.0]) - - + + x = sin(radians(60/6))*TopBevelRadius y = cos(radians(60/6))*TopBevelRadius vec2 = mathutils.Vector([x,y,0.0]) verts.append([x,y,0.0]) - - + + x = sin(radians(60/3))*TopBevelRadius y = cos(radians(60/3))*TopBevelRadius vec3 = mathutils.Vector([x,y,0.0]) verts.append([x,y,0.0]) - - + + x = sin(radians(60/2))*TopBevelRadius y = cos(radians(60/2))*TopBevelRadius vec4 = mathutils.Vector([x,y,0.0]) verts.append([x,y,0.0]) Row += 1 - + #Flats - + x = tan(radians(0))*Half_Flat dvec = vec1 - mathutils.Vector([x,Half_Flat,0.0]) verts.append([x,Half_Flat,-dvec.length]) - - + + x = tan(radians(60/6))*Half_Flat dvec = vec2 - mathutils.Vector([x,Half_Flat,0.0]) verts.append([x,Half_Flat,-dvec.length]) - + x = tan(radians(60/3))*Half_Flat dvec = vec3 - mathutils.Vector([x,Half_Flat,0.0]) Lowest_Point = -dvec.length verts.append([x,Half_Flat,-dvec.length]) - + x = tan(radians(60/2))*Half_Flat dvec = vec4 - mathutils.Vector([x,Half_Flat,0.0]) Lowest_Point = -dvec.length verts.append([x,Half_Flat,-dvec.length]) Row += 1 - + #down Bits Tri x = tan(radians(0))*Half_Flat verts.append([x,Half_Flat,Lowest_Point]) - + x = tan(radians(60/6))*Half_Flat verts.append([x,Half_Flat,Lowest_Point]) x = tan(radians(60/3))*Half_Flat verts.append([x,Half_Flat,Lowest_Point]) - + x = tan(radians(60/2))*Half_Flat verts.append([x,Half_Flat,Lowest_Point]) Row += 1 #down Bits - + x = tan(radians(0))*Half_Flat verts.append([x,Half_Flat,-Flat_Height]) - + x = tan(radians(60/6))*Half_Flat verts.append([x,Half_Flat,-Flat_Height]) x = tan(radians(60/3))*Half_Flat verts.append([x,Half_Flat,-Flat_Height]) - + x = tan(radians(60/2))*Half_Flat verts.append([x,Half_Flat,-Flat_Height]) Row += 1 - - - #under cut - + + + #under cut + x = sin(radians(0))*Half_Flat y = cos(radians(0))*Half_Flat vec1 = mathutils.Vector([x,y,0.0]) verts.append([x,y,-Flat_Height]) - + x = sin(radians(60/6))*Half_Flat y = cos(radians(60/6))*Half_Flat vec2 = mathutils.Vector([x,y,0.0]) verts.append([x,y,-Flat_Height]) - + x = sin(radians(60/3))*Half_Flat y = cos(radians(60/3))*Half_Flat vec3 = mathutils.Vector([x,y,0.0]) verts.append([x,y,-Flat_Height]) - + x = sin(radians(60/2))*Half_Flat y = cos(radians(60/2))*Half_Flat vec3 = mathutils.Vector([x,y,0.0]) verts.append([x,y,-Flat_Height]) Row += 1 - + #under cut down bit x = sin(radians(0))*Half_Flat y = cos(radians(0))*Half_Flat vec1 = mathutils.Vector([x,y,0.0]) verts.append([x,y,-Flat_Height-Undercut_Height]) - + x = sin(radians(60/6))*Half_Flat y = cos(radians(60/6))*Half_Flat vec2 = mathutils.Vector([x,y,0.0]) verts.append([x,y,-Flat_Height-Undercut_Height]) - + x = sin(radians(60/3))*Half_Flat y = cos(radians(60/3))*Half_Flat vec3 = mathutils.Vector([x,y,0.0]) verts.append([x,y,-Flat_Height-Undercut_Height]) - + x = sin(radians(60/2))*Half_Flat y = cos(radians(60/2))*Half_Flat vec3 = mathutils.Vector([x,y,0.0]) verts.append([x,y,-Flat_Height-Undercut_Height]) Row += 1 - + #under cut to Shank BEVEAL x = sin(radians(0))*(SHANK_RADIUS+Shank_Bevel) y = cos(radians(0))*(SHANK_RADIUS+Shank_Bevel) vec1 = mathutils.Vector([x,y,0.0]) verts.append([x,y,-Flat_Height-Undercut_Height]) - + x = sin(radians(60/6))*(SHANK_RADIUS+Shank_Bevel) y = cos(radians(60/6))*(SHANK_RADIUS+Shank_Bevel) vec2 = mathutils.Vector([x,y,0.0]) verts.append([x,y,-Flat_Height-Undercut_Height]) - + x = sin(radians(60/3))*(SHANK_RADIUS+Shank_Bevel) y = cos(radians(60/3))*(SHANK_RADIUS+Shank_Bevel) vec3 = mathutils.Vector([x,y,0.0]) verts.append([x,y,-Flat_Height-Undercut_Height]) - + x = sin(radians(60/2))*(SHANK_RADIUS+Shank_Bevel) y = cos(radians(60/2))*(SHANK_RADIUS+Shank_Bevel) vec3 = mathutils.Vector([x,y,0.0]) verts.append([x,y,-Flat_Height-Undercut_Height]) Row += 1 - + #under cut to Shank BEVEAL x = sin(radians(0))*SHANK_RADIUS y = cos(radians(0))*SHANK_RADIUS vec1 = mathutils.Vector([x,y,0.0]) verts.append([x,y,-Flat_Height-Undercut_Height-Shank_Bevel]) - + x = sin(radians(60/6))*SHANK_RADIUS y = cos(radians(60/6))*SHANK_RADIUS vec2 = mathutils.Vector([x,y,0.0]) verts.append([x,y,-Flat_Height-Undercut_Height-Shank_Bevel]) - + x = sin(radians(60/3))*SHANK_RADIUS y = cos(radians(60/3))*SHANK_RADIUS vec3 = mathutils.Vector([x,y,0.0]) verts.append([x,y,-Flat_Height-Undercut_Height-Shank_Bevel]) - + x = sin(radians(60/2))*SHANK_RADIUS y = cos(radians(60/2))*SHANK_RADIUS vec3 = mathutils.Vector([x,y,0.0]) verts.append([x,y,-Flat_Height-Undercut_Height-Shank_Bevel]) Row += 1 - - + + #Global_Head_Height = 0 - (-HEIGHT-0.1) faces.extend(Build_Face_List_Quads(FaceStart,3,Row - 1)) - - + + Mirror_Verts,Mirror_Faces = Mirror_Verts_Faces(verts,faces,'y') verts.extend(Mirror_Verts) faces.extend(Mirror_Faces) - + Spin_Verts,Spin_Faces = SpinDup(verts,faces,360,6,'z') - - + + return Spin_Verts,Spin_Faces,0 - (-HEIGHT) - + ########################################################################################## ########################################################################################## @@ -953,26 +953,26 @@ def Thread_Start3(verts,INNER_RADIUS,OUTTER_RADIUS,PITCH,DIV,CREST_PERCENT,ROOT_PERCENT,Height_Offset): - - + + Ret_Row = 0; - + # Half_Pitch = float(PITCH)/2 # UNUSED Height_Start = Height_Offset - PITCH Height_Step = float(PITCH)/float(DIV) Deg_Step = 360.0 /float(DIV) - + Crest_Height = float(PITCH) * float(CREST_PERCENT)/float(100) Root_Height = float(PITCH) * float(ROOT_PERCENT)/float(100) Root_to_Crest_Height = Crest_to_Root_Height = (float(PITCH) - (Crest_Height + Root_Height))/2.0 - + #theard start Rank = float(OUTTER_RADIUS - INNER_RADIUS)/float(DIV) for j in range(4): - + for i in range(DIV+1): - z = Height_Offset - (Height_Step*i) + z = Height_Offset - (Height_Step*i) if z > Height_Start: z = Height_Start x = sin(radians(i*Deg_Step))*OUTTER_RADIUS @@ -980,24 +980,24 @@ verts.append([x,y,z]) Height_Offset -= Crest_Height Ret_Row += 1 - + for i in range(DIV+1): - z = Height_Offset - (Height_Step*i) + z = Height_Offset - (Height_Step*i) if z > Height_Start: z = Height_Start - + x = sin(radians(i*Deg_Step))*OUTTER_RADIUS y = cos(radians(i*Deg_Step))*OUTTER_RADIUS verts.append([x,y,z ]) Height_Offset -= Crest_to_Root_Height Ret_Row += 1 - - + + for i in range(DIV+1): - z = Height_Offset - (Height_Step*i) + z = Height_Offset - (Height_Step*i) if z > Height_Start: z = Height_Start - + x = sin(radians(i*Deg_Step))*INNER_RADIUS y = cos(radians(i*Deg_Step))*INNER_RADIUS if j == 0: @@ -1006,12 +1006,12 @@ verts.append([x,y,z ]) Height_Offset -= Root_Height Ret_Row += 1 - + for i in range(DIV+1): - z = Height_Offset - (Height_Step*i) + z = Height_Offset - (Height_Step*i) if z > Height_Start: z = Height_Start - + x = sin(radians(i*Deg_Step))*INNER_RADIUS y = cos(radians(i*Deg_Step))*INNER_RADIUS @@ -1021,7 +1021,7 @@ verts.append([x,y,z ]) Height_Offset -= Root_to_Crest_Height Ret_Row += 1 - + return Ret_Row,Height_Offset @@ -1029,29 +1029,29 @@ verts = [] DIV = 36 - + START_RADIUS = START_DIA/2 OUTTER_RADIUS = OUTTER_DIA/2 - + Opp = abs(START_RADIUS - OUTTER_RADIUS) Taper_Lentgh = Opp/tan(radians(31)); - + if Taper_Lentgh > LENGTH: Taper_Lentgh = 0 - + Stright_Length = LENGTH - Taper_Lentgh - + Deg_Step = 360.0 /float(DIV) - + Row = 0 - - Lowest_Z_Vert = 0; - + + Lowest_Z_Vert = 0; + Height_Offset = Z_LOCATION #ring - for i in range(DIV+1): + for i in range(DIV+1): x = sin(radians(i*Deg_Step))*START_RADIUS y = cos(radians(i*Deg_Step))*START_RADIUS z = Height_Offset - 0 @@ -1060,7 +1060,7 @@ Height_Offset -= Stright_Length Row += 1 - for i in range(DIV+1): + for i in range(DIV+1): x = sin(radians(i*Deg_Step))*START_RADIUS y = cos(radians(i*Deg_Step))*START_RADIUS z = Height_Offset - 0 @@ -1074,37 +1074,37 @@ def Create_Thread_Start_Verts(INNER_DIA,OUTTER_DIA,PITCH,CREST_PERCENT,ROOT_PERCENT,Z_LOCATION = 0): - + verts = [] DIV = 36 - + INNER_RADIUS = INNER_DIA/2 OUTTER_RADIUS = OUTTER_DIA/2 - + # Half_Pitch = float(PITCH)/2 # UNUSED Deg_Step = 360.0 /float(DIV) Height_Step = float(PITCH)/float(DIV) Row = 0 - - Lowest_Z_Vert = 0; - + + Lowest_Z_Vert = 0; + Height_Offset = Z_LOCATION - - Height_Start = Height_Offset - + + Height_Start = Height_Offset + Crest_Height = float(PITCH) * float(CREST_PERCENT)/float(100) Root_Height = float(PITCH) * float(ROOT_PERCENT)/float(100) Root_to_Crest_Height = Crest_to_Root_Height = (float(PITCH) - (Crest_Height + Root_Height))/2.0 Rank = float(OUTTER_RADIUS - INNER_RADIUS)/float(DIV) - - Height_Offset = Z_LOCATION + PITCH + + Height_Offset = Z_LOCATION + PITCH Cut_off = Z_LOCATION - - + + for j in range(1): - + for i in range(DIV+1): x = sin(radians(i*Deg_Step))*OUTTER_RADIUS y = cos(radians(i*Deg_Step))*OUTTER_RADIUS @@ -1114,7 +1114,7 @@ Lowest_Z_Vert = min(Lowest_Z_Vert,z) Height_Offset -= Crest_Height Row += 1 - + for i in range(DIV+1): x = sin(radians(i*Deg_Step))*OUTTER_RADIUS y = cos(radians(i*Deg_Step))*OUTTER_RADIUS @@ -1124,31 +1124,31 @@ Lowest_Z_Vert = min(Lowest_Z_Vert,z) Height_Offset -= Crest_to_Root_Height Row += 1 - + for i in range(DIV+1): x = sin(radians(i*Deg_Step))*OUTTER_RADIUS y = cos(radians(i*Deg_Step))*OUTTER_RADIUS z = Height_Offset - (Height_Step*i) - if z > Cut_off : z = Cut_off + if z > Cut_off : z = Cut_off verts.append([x,y,z]) Lowest_Z_Vert = min(Lowest_Z_Vert,z) Height_Offset -= Root_Height Row += 1 - + for i in range(DIV+1): x = sin(radians(i*Deg_Step))*OUTTER_RADIUS y = cos(radians(i*Deg_Step))*OUTTER_RADIUS z = Height_Offset - (Height_Step*i) - if z > Cut_off : z = Cut_off + if z > Cut_off : z = Cut_off verts.append([x,y,z]) Lowest_Z_Vert = min(Lowest_Z_Vert,z) Height_Offset -= Root_to_Crest_Height Row += 1 - - + + for j in range(2): for i in range(DIV+1): - z = Height_Offset - (Height_Step*i) + z = Height_Offset - (Height_Step*i) if z > Height_Start: z = Height_Start x = sin(radians(i*Deg_Step))*OUTTER_RADIUS @@ -1157,25 +1157,25 @@ Lowest_Z_Vert = min(Lowest_Z_Vert,z) Height_Offset -= Crest_Height Row += 1 - + for i in range(DIV+1): - z = Height_Offset - (Height_Step*i) + z = Height_Offset - (Height_Step*i) if z > Height_Start: z = Height_Start - + x = sin(radians(i*Deg_Step))*OUTTER_RADIUS y = cos(radians(i*Deg_Step))*OUTTER_RADIUS verts.append([x,y,z ]) Lowest_Z_Vert = min(Lowest_Z_Vert,z) Height_Offset -= Crest_to_Root_Height Row += 1 - - + + for i in range(DIV+1): - z = Height_Offset - (Height_Step*i) + z = Height_Offset - (Height_Step*i) if z > Height_Start: z = Height_Start - + x = sin(radians(i*Deg_Step))*INNER_RADIUS y = cos(radians(i*Deg_Step))*INNER_RADIUS if j == 0: @@ -1185,12 +1185,12 @@ Lowest_Z_Vert = min(Lowest_Z_Vert,z) Height_Offset -= Root_Height Row += 1 - + for i in range(DIV+1): - z = Height_Offset - (Height_Step*i) + z = Height_Offset - (Height_Step*i) if z > Height_Start: z = Height_Start - + x = sin(radians(i*Deg_Step))*INNER_RADIUS y = cos(radians(i*Deg_Step))*INNER_RADIUS @@ -1201,20 +1201,20 @@ Lowest_Z_Vert = min(Lowest_Z_Vert,z) Height_Offset -= Root_to_Crest_Height Row += 1 - - + + return verts,Row,Height_Offset def Create_Thread_Verts(INNER_DIA,OUTTER_DIA,PITCH,HEIGHT,CREST_PERCENT,ROOT_PERCENT,Z_LOCATION = 0): verts = [] - + DIV = 36 - + INNER_RADIUS = INNER_DIA/2 OUTTER_RADIUS = OUTTER_DIA/2 - + # Half_Pitch = float(PITCH)/2 # UNUSED Deg_Step = 360.0 /float(DIV) Height_Step = float(PITCH)/float(DIV) @@ -1223,7 +1223,7 @@ NUM_OF_END_THREADS = 3.0 Num = int((HEIGHT- ((NUM_OF_START_THREADS*PITCH) + (NUM_OF_END_THREADS*PITCH) ))/PITCH) Row = 0 - + Crest_Height = float(PITCH) * float(CREST_PERCENT)/float(100) Root_Height = float(PITCH) * float(ROOT_PERCENT)/float(100) @@ -1231,20 +1231,20 @@ Height_Offset = Z_LOCATION - + Lowest_Z_Vert = 0; for j in range(Num): - + for i in range(DIV+1): x = sin(radians(i*Deg_Step))*OUTTER_RADIUS y = cos(radians(i*Deg_Step))*OUTTER_RADIUS - z = Height_Offset - (Height_Step*i) + z = Height_Offset - (Height_Step*i) verts.append([x,y,z]) Lowest_Z_Vert = min(Lowest_Z_Vert,z) Height_Offset -= Crest_Height Row += 1 - + for i in range(DIV+1): x = sin(radians(i*Deg_Step))*OUTTER_RADIUS y = cos(radians(i*Deg_Step))*OUTTER_RADIUS @@ -1253,38 +1253,38 @@ Lowest_Z_Vert = min(Lowest_Z_Vert,z) Height_Offset -= Crest_to_Root_Height Row += 1 - - + + for i in range(DIV+1): x = sin(radians(i*Deg_Step))*INNER_RADIUS y = cos(radians(i*Deg_Step))*INNER_RADIUS - z = Height_Offset - (Height_Step*i) + z = Height_Offset - (Height_Step*i) verts.append([x,y,z]) Lowest_Z_Vert = min(Lowest_Z_Vert,z) Height_Offset -= Root_Height Row += 1 - + for i in range(DIV+1): x = sin(radians(i*Deg_Step))*INNER_RADIUS y = cos(radians(i*Deg_Step))*INNER_RADIUS - z = Height_Offset - (Height_Step*i) + z = Height_Offset - (Height_Step*i) verts.append([x,y,z]) Lowest_Z_Vert = min(Lowest_Z_Vert,z) Height_Offset -= Root_to_Crest_Height Row += 1 - + return verts,Row,Height_Offset def Create_Thread_End_Verts(INNER_DIA,OUTTER_DIA,PITCH,CREST_PERCENT,ROOT_PERCENT,Z_LOCATION = 0): verts = [] - + DIV = 36 INNER_RADIUS = INNER_DIA/2 OUTTER_RADIUS = OUTTER_DIA/2 - + # Half_Pitch = float(PITCH)/2 # UNUSED Deg_Step = 360.0 /float(DIV) Height_Step = float(PITCH)/float(DIV) @@ -1292,21 +1292,21 @@ Crest_Height = float(PITCH) * float(CREST_PERCENT)/float(100) Root_Height = float(PITCH) * float(ROOT_PERCENT)/float(100) Root_to_Crest_Height = Crest_to_Root_Height = (float(PITCH) - (Crest_Height + Root_Height))/2.0 - + # Col = 0 # UNUSED Row = 0 - - Height_Offset = Z_LOCATION - - Tapper_Height_Start = Height_Offset - PITCH - PITCH - - Max_Height = Tapper_Height_Start - PITCH - + + Height_Offset = Z_LOCATION + + Tapper_Height_Start = Height_Offset - PITCH - PITCH + + Max_Height = Tapper_Height_Start - PITCH + Lowest_Z_Vert = 0; - + # FaceStart = len(verts) # UNUSED for j in range(4): - + for i in range(DIV+1): z = Height_Offset - (Height_Step*i) z = max(z,Max_Height) @@ -1320,7 +1320,7 @@ Lowest_Z_Vert = min(Lowest_Z_Vert,z) Height_Offset -= Crest_Height Row += 1 - + for i in range(DIV+1): z = Height_Offset - (Height_Step*i) z = max(z,Max_Height) @@ -1334,80 +1334,80 @@ Lowest_Z_Vert = min(Lowest_Z_Vert,z) Height_Offset -= Crest_to_Root_Height Row += 1 - - + + for i in range(DIV+1): z = Height_Offset - (Height_Step*i) z = max(z,Max_Height) Tapper_Radius = OUTTER_RADIUS - (Tapper_Height_Start - z) if Tapper_Radius > INNER_RADIUS: Tapper_Radius = INNER_RADIUS - + x = sin(radians(i*Deg_Step))*(Tapper_Radius) y = cos(radians(i*Deg_Step))*(Tapper_Radius) verts.append([x,y,z]) Lowest_Z_Vert = min(Lowest_Z_Vert,z) Height_Offset -= Root_Height Row += 1 - + for i in range(DIV+1): z = Height_Offset - (Height_Step*i) z = max(z,Max_Height) Tapper_Radius = OUTTER_RADIUS - (Tapper_Height_Start - z) if Tapper_Radius > INNER_RADIUS: Tapper_Radius = INNER_RADIUS - + x = sin(radians(i*Deg_Step))*(Tapper_Radius) y = cos(radians(i*Deg_Step))*(Tapper_Radius) verts.append([x,y,z]) Lowest_Z_Vert = min(Lowest_Z_Vert,z) Height_Offset -= Root_to_Crest_Height Row += 1 - + return verts,Row,Height_Offset,Lowest_Z_Vert def Create_External_Thread(SHANK_DIA,SHANK_LENGTH,INNER_DIA,OUTTER_DIA,PITCH,LENGTH,CREST_PERCENT,ROOT_PERCENT): - + verts = [] faces = [] DIV = 36 - + Total_Row = 0 # Thread_Len = 0 # UNUSED - + Face_Start = len(verts) Offset = 0.0; - - + + Shank_Verts,Shank_Row,Offset = Create_Shank_Verts(SHANK_DIA,OUTTER_DIA,SHANK_LENGTH,Offset) Total_Row += Shank_Row Thread_Start_Verts,Thread_Start_Row,Offset = Create_Thread_Start_Verts(INNER_DIA,OUTTER_DIA,PITCH,CREST_PERCENT,ROOT_PERCENT,Offset) Total_Row += Thread_Start_Row - - + + Thread_Verts,Thread_Row,Offset = Create_Thread_Verts(INNER_DIA,OUTTER_DIA,PITCH,LENGTH,CREST_PERCENT,ROOT_PERCENT,Offset) Total_Row += Thread_Row - - + + Thread_End_Verts,Thread_End_Row,Offset,Lowest_Z_Vert = Create_Thread_End_Verts(INNER_DIA,OUTTER_DIA,PITCH,CREST_PERCENT,ROOT_PERCENT,Offset ) - Total_Row += Thread_End_Row - - + Total_Row += Thread_End_Row + + verts.extend(Shank_Verts) verts.extend(Thread_Start_Verts) verts.extend(Thread_Verts) verts.extend(Thread_End_Verts) - + faces.extend(Build_Face_List_Quads(Face_Start,DIV,Total_Row -1,0)) faces.extend(Fill_Ring_Face(len(verts)-DIV,DIV,1)) - + return verts,faces,0.0 - Lowest_Z_Vert - + ########################################################################################## ########################################################################################## @@ -1418,89 +1418,89 @@ def add_Hex_Nut(FLAT,HOLE_DIA,HEIGHT): global Global_Head_Height global Global_NutRad - + verts = [] faces = [] HOLE_RADIUS = HOLE_DIA * 0.5 Half_Flat = FLAT/2 Half_Height = HEIGHT/2 TopBevelRadius = Half_Flat - 0.05 - + Global_NutRad = TopBevelRadius - + Row = 0; Lowest_Z_Vert = 0.0; verts.append([0.0,0.0,0.0]) - - + + FaceStart = len(verts) #inner hole - + x = sin(radians(0))*HOLE_RADIUS y = cos(radians(0))*HOLE_RADIUS #print ("rad 0 x;", x, "y:" ,y ) verts.append([x,y,0.0]) - - + + x = sin(radians(60/6))*HOLE_RADIUS y = cos(radians(60/6))*HOLE_RADIUS #print ("rad 60/6x;", x, "y:" ,y ) verts.append([x,y,0.0]) - - + + x = sin(radians(60/3))*HOLE_RADIUS y = cos(radians(60/3))*HOLE_RADIUS #print ("rad 60/3x;", x, "y:" ,y ) verts.append([x,y,0.0]) - - + + x = sin(radians(60/2))*HOLE_RADIUS y = cos(radians(60/2))*HOLE_RADIUS #print ("rad 60/2x;", x, "y:" ,y ) verts.append([x,y,0.0]) Row += 1 - - + + #bevel - + x = sin(radians(0))*TopBevelRadius y = cos(radians(0))*TopBevelRadius vec1 = mathutils.Vector([x,y,0.0]) verts.append([x,y,0.0]) - - + + x = sin(radians(60/6))*TopBevelRadius y = cos(radians(60/6))*TopBevelRadius vec2 = mathutils.Vector([x,y,0.0]) verts.append([x,y,0.0]) - - + + x = sin(radians(60/3))*TopBevelRadius y = cos(radians(60/3))*TopBevelRadius vec3 = mathutils.Vector([x,y,0.0]) verts.append([x,y,0.0]) - - + + x = sin(radians(60/2))*TopBevelRadius y = cos(radians(60/2))*TopBevelRadius vec4 = mathutils.Vector([x,y,0.0]) verts.append([x,y,0.0]) Row += 1 - + #Flats - + x = tan(radians(0))*Half_Flat dvec = vec1 - mathutils.Vector([x,Half_Flat,0.0]) verts.append([x,Half_Flat,-dvec.length]) Lowest_Z_Vert = min(Lowest_Z_Vert,-dvec.length) - - + + x = tan(radians(60/6))*Half_Flat dvec = vec2 - mathutils.Vector([x,Half_Flat,0.0]) verts.append([x,Half_Flat,-dvec.length]) Lowest_Z_Vert = min(Lowest_Z_Vert,-dvec.length) - + x = tan(radians(60/3))*Half_Flat dvec = vec3 - mathutils.Vector([x,Half_Flat,0.0]) @@ -1514,53 +1514,53 @@ verts.append([x,Half_Flat,-dvec.length]) Lowest_Z_Vert = min(Lowest_Z_Vert,-dvec.length) Row += 1 - + #down Bits Tri x = tan(radians(0))*Half_Flat verts.append([x,Half_Flat,Lowest_Point]) - - + + x = tan(radians(60/6))*Half_Flat verts.append([x,Half_Flat,Lowest_Point]) x = tan(radians(60/3))*Half_Flat verts.append([x,Half_Flat,Lowest_Point]) - + x = tan(radians(60/2))*Half_Flat verts.append([x,Half_Flat,Lowest_Point]) Lowest_Z_Vert = min(Lowest_Z_Vert,Lowest_Point) Row += 1 #down Bits - + x = tan(radians(0))*Half_Flat verts.append([x,Half_Flat,-Half_Height]) - + x = tan(radians(60/6))*Half_Flat verts.append([x,Half_Flat,-Half_Height]) x = tan(radians(60/3))*Half_Flat verts.append([x,Half_Flat,-Half_Height]) - + x = tan(radians(60/2))*Half_Flat verts.append([x,Half_Flat,-Half_Height]) Lowest_Z_Vert = min(Lowest_Z_Vert,-Half_Height) Row += 1 - + faces.extend(Build_Face_List_Quads(FaceStart,3,Row - 1)) Global_Head_Height = HEIGHT - + Tvert,tface = Mirror_Verts_Faces(verts,faces,'z',Lowest_Z_Vert) verts.extend(Tvert) faces.extend(tface) - - + + Tvert,tface = Mirror_Verts_Faces(verts,faces,'y') verts.extend(Tvert) faces.extend(tface) - + S_verts,S_faces = SpinDup(verts,faces,360,6,'z') - + #return verts,faces,TopBevelRadius return S_verts,S_faces,TopBevelRadius @@ -1576,44 +1576,44 @@ EDGE_THICKNESS = (OUTSIDE_RADIUS * (0.4/4.75)) RAD1 = (OUTSIDE_RADIUS * (0.5/4.75)) OVER_ALL_HEIGTH = (OUTSIDE_RADIUS * (2.0/4.75)) - - + + FaceStart = len(verts) # Start_Height = 0 - 3 # UNUSED Height_Offset = Z_LOCATION Lowest_Z_Vert = 0 - + x = INNER_HOLE z = (Height_Offset - OVER_ALL_HEIGTH) + EDGE_THICKNESS verts.append([x,0.0,z]) Lowest_Z_Vert = min(Lowest_Z_Vert,z) Row += 1 - + x = INNER_HOLE z = (Height_Offset - OVER_ALL_HEIGTH) verts.append([x,0.0,z]) Lowest_Z_Vert = min(Lowest_Z_Vert,z) Row += 1 - - + + for i in range(180,80,-10): x = sin(radians(i))*RAD1 z = cos(radians(i))*RAD1 verts.append([(OUTSIDE_RADIUS-RAD1)+x,0.0,((Height_Offset - OVER_ALL_HEIGTH)+RAD1)+z]) Lowest_Z_Vert = min(Lowest_Z_Vert,z) Row += 1 - - + + x = OUTSIDE_RADIUS - 0 - z = Height_Offset + z = Height_Offset verts.append([x,0.0,z]) Lowest_Z_Vert = min(Lowest_Z_Vert,z) Row += 1 sVerts,sFaces = SpinDup(verts,faces,360,DIV,'z') sVerts.extend(verts) #add the start verts to the Spin verts to complete the loop - + faces.extend(Build_Face_List_Quads(FaceStart,Row-1,DIV)) return Move_Verts_Up_Z(sVerts,0),faces,Lowest_Z_Vert @@ -1632,32 +1632,32 @@ OVER_ALL_HEIGTH = (OUTSIDE_RADIUS * (2.0/4.75)) PART_THICKNESS = OVER_ALL_HEIGTH - EDGE_THICKNESS PART_INNER_HOLE = (OUTSIDE_RADIUS * (2.5/4.75)) - + FaceStart = len(verts) # Start_Height = 0 - 3 # UNUSED Height_Offset = Z_LOCATION Lowest_Z_Vert = 0 - + x = INNER_HOLE + EDGE_THICKNESS - z = Height_Offset + z = Height_Offset verts.append([x,0.0,z]) Lowest_Z_Vert = min(Lowest_Z_Vert,z) Row += 1 - + x = PART_INNER_HOLE z = Height_Offset verts.append([x,0.0,z]) Lowest_Z_Vert = min(Lowest_Z_Vert,z) Row += 1 - + x = PART_INNER_HOLE z = Height_Offset - PART_THICKNESS verts.append([x,0.0,z]) Lowest_Z_Vert = min(Lowest_Z_Vert,z) Row += 1 - + x = INNER_HOLE + EDGE_THICKNESS z = Height_Offset - PART_THICKNESS verts.append([x,0.0,z]) @@ -1667,7 +1667,7 @@ sVerts,sFaces = SpinDup(verts,faces,360,DIV,'z') sVerts.extend(verts) #add the start verts to the Spin verts to complete the loop - + faces.extend(Build_Face_List_Quads(FaceStart,Row-1,DIV,1)) return sVerts,faces,0 - Lowest_Z_Vert @@ -1681,28 +1681,28 @@ def Create_Internal_Thread_Start_Verts(verts,INNER_RADIUS,OUTTER_RADIUS,PITCH,DIV,CREST_PERCENT,ROOT_PERCENT,Height_Offset): - - + + Ret_Row = 0; - - Height_Offset = Height_Offset + PITCH #Move the offset up so that the verts start at + + Height_Offset = Height_Offset + PITCH #Move the offset up so that the verts start at #at the correct place (Height_Start) - + # Half_Pitch = float(PITCH)/2 # UNUSED - Height_Start = Height_Offset - PITCH + Height_Start = Height_Offset - PITCH Height_Step = float(PITCH)/float(DIV) Deg_Step = 360.0 /float(DIV) - + Crest_Height = float(PITCH) * float(CREST_PERCENT)/float(100) Root_Height = float(PITCH) * float(ROOT_PERCENT)/float(100) Root_to_Crest_Height = Crest_to_Root_Height = (float(PITCH) - (Crest_Height + Root_Height))/2.0 - + Rank = float(OUTTER_RADIUS - INNER_RADIUS)/float(DIV) - for j in range(1): - + for j in range(1): #FIXME - for j in range(1) what?! + for i in range(DIV+1): - z = Height_Offset - (Height_Step*i) + z = Height_Offset - (Height_Step*i) if z > Height_Start: z = Height_Start x = sin(radians(i*Deg_Step))*OUTTER_RADIUS @@ -1710,24 +1710,24 @@ verts.append([x,y,z]) Height_Offset -= Crest_Height Ret_Row += 1 - + for i in range(DIV+1): - z = Height_Offset - (Height_Step*i) + z = Height_Offset - (Height_Step*i) if z > Height_Start: z = Height_Start - + x = sin(radians(i*Deg_Step))*OUTTER_RADIUS y = cos(radians(i*Deg_Step))*OUTTER_RADIUS verts.append([x,y,z ]) Height_Offset -= Crest_to_Root_Height Ret_Row += 1 - - + + for i in range(DIV+1): - z = Height_Offset - (Height_Step*i) + z = Height_Offset - (Height_Step*i) if z > Height_Start: z = Height_Start - + x = sin(radians(i*Deg_Step))*INNER_RADIUS y = cos(radians(i*Deg_Step))*INNER_RADIUS if j == 0: @@ -1736,12 +1736,12 @@ verts.append([x,y,z ]) Height_Offset -= Root_Height Ret_Row += 1 - + for i in range(DIV+1): - z = Height_Offset - (Height_Step*i) + z = Height_Offset - (Height_Step*i) if z > Height_Start: z = Height_Start - + x = sin(radians(i*Deg_Step))*INNER_RADIUS y = cos(radians(i*Deg_Step))*INNER_RADIUS @@ -1751,35 +1751,35 @@ verts.append([x,y,z ]) Height_Offset -= Root_to_Crest_Height Ret_Row += 1 - + return Ret_Row,Height_Offset def Create_Internal_Thread_End_Verts(verts,INNER_RADIUS,OUTTER_RADIUS,PITCH,DIV,CREST_PERCENT,ROOT_PERCENT,Height_Offset): - - + + Ret_Row = 0; - + # Half_Pitch = float(PITCH)/2 # UNUSED #Height_End = Height_Offset - PITCH - PITCH - PITCH- PITCH - PITCH- PITCH - Height_End = Height_Offset - PITCH + Height_End = Height_Offset - PITCH #Height_End = -2.1 Height_Step = float(PITCH)/float(DIV) Deg_Step = 360.0 /float(DIV) - + Crest_Height = float(PITCH) * float(CREST_PERCENT)/float(100) Root_Height = float(PITCH) * float(ROOT_PERCENT)/float(100) Root_to_Crest_Height = Crest_to_Root_Height = (float(PITCH) - (Crest_Height + Root_Height))/2.0 - + Rank = float(OUTTER_RADIUS - INNER_RADIUS)/float(DIV) - + Num = 0 - + for j in range(2): - + for i in range(DIV+1): - z = Height_Offset - (Height_Step*i) + z = Height_Offset - (Height_Step*i) if z < Height_End: z = Height_End x = sin(radians(i*Deg_Step))*OUTTER_RADIUS @@ -1787,25 +1787,25 @@ verts.append([x,y,z]) Height_Offset -= Crest_Height Ret_Row += 1 - - + + for i in range(DIV+1): - z = Height_Offset - (Height_Step*i) + z = Height_Offset - (Height_Step*i) if z < Height_End: z = Height_End - + x = sin(radians(i*Deg_Step))*OUTTER_RADIUS y = cos(radians(i*Deg_Step))*OUTTER_RADIUS verts.append([x,y,z ]) Height_Offset -= Crest_to_Root_Height Ret_Row += 1 - - + + for i in range(DIV+1): - z = Height_Offset - (Height_Step*i) + z = Height_Offset - (Height_Step*i) if z < Height_End: z = Height_End - + x = sin(radians(i*Deg_Step))*INNER_RADIUS y = cos(radians(i*Deg_Step))*INNER_RADIUS if j == Num: @@ -1814,17 +1814,17 @@ if j > Num: x = sin(radians(i*Deg_Step))*(OUTTER_RADIUS) y = cos(radians(i*Deg_Step))*(OUTTER_RADIUS ) - + verts.append([x,y,z ]) Height_Offset -= Root_Height Ret_Row += 1 - - + + for i in range(DIV+1): - z = Height_Offset - (Height_Step*i) + z = Height_Offset - (Height_Step*i) if z < Height_End: z = Height_End - + x = sin(radians(i*Deg_Step))*INNER_RADIUS y = cos(radians(i*Deg_Step))*INNER_RADIUS @@ -1834,80 +1834,80 @@ if j > Num: x = sin(radians(i*Deg_Step))*(OUTTER_RADIUS ) y = cos(radians(i*Deg_Step))*(OUTTER_RADIUS ) - + verts.append([x,y,z ]) Height_Offset -= Root_to_Crest_Height Ret_Row += 1 - + return Ret_Row,Height_End # send back Height End as this is the lowest point def Create_Internal_Thread(INNER_DIA,OUTTER_DIA,PITCH,HEIGHT,CREST_PERCENT,ROOT_PERCENT,INTERNAL = 1): verts = [] faces = [] - + DIV = 36 - + INNER_RADIUS = INNER_DIA/2 OUTTER_RADIUS = OUTTER_DIA/2 - + # Half_Pitch = float(PITCH)/2 # UNUSED Deg_Step = 360.0 /float(DIV) Height_Step = float(PITCH)/float(DIV) - - Num = int(round((HEIGHT- PITCH)/PITCH)) # less one pitch for the start and end that is 1/2 pitch high - + + Num = int(round((HEIGHT- PITCH)/PITCH)) # less one pitch for the start and end that is 1/2 pitch high + # Col = 0 # UNUSED Row = 0 - - + + Crest_Height = float(PITCH) * float(CREST_PERCENT)/float(100) Root_Height = float(PITCH) * float(ROOT_PERCENT)/float(100) Root_to_Crest_Height = Crest_to_Root_Height = (float(PITCH) - (Crest_Height + Root_Height))/2.0 - + Height_Offset = 0 FaceStart = len(verts) - + Row_Inc,Height_Offset = Create_Internal_Thread_Start_Verts(verts,INNER_RADIUS,OUTTER_RADIUS,PITCH,DIV,CREST_PERCENT,ROOT_PERCENT,Height_Offset) Row += Row_Inc - + for j in range(Num): - + for i in range(DIV+1): x = sin(radians(i*Deg_Step))*OUTTER_RADIUS y = cos(radians(i*Deg_Step))*OUTTER_RADIUS verts.append([x,y,Height_Offset - (Height_Step*i) ]) Height_Offset -= Crest_Height Row += 1 - + for i in range(DIV+1): x = sin(radians(i*Deg_Step))*OUTTER_RADIUS y = cos(radians(i*Deg_Step))*OUTTER_RADIUS verts.append([x,y,Height_Offset - (Height_Step*i) ]) Height_Offset -= Crest_to_Root_Height Row += 1 - + for i in range(DIV+1): x = sin(radians(i*Deg_Step))*INNER_RADIUS y = cos(radians(i*Deg_Step))*INNER_RADIUS verts.append([x,y,Height_Offset - (Height_Step*i) ]) Height_Offset -= Root_Height Row += 1 - + for i in range(DIV+1): x = sin(radians(i*Deg_Step))*INNER_RADIUS y = cos(radians(i*Deg_Step))*INNER_RADIUS verts.append([x,y,Height_Offset - (Height_Step*i) ]) Height_Offset -= Root_to_Crest_Height Row += 1 - + Row_Inc,Height_Offset = Create_Internal_Thread_End_Verts(verts,INNER_RADIUS,OUTTER_RADIUS,PITCH,DIV,CREST_PERCENT,ROOT_PERCENT,Height_Offset) Row += Row_Inc - + faces.extend(Build_Face_List_Quads(FaceStart,DIV,Row -1,INTERNAL)) - + return verts,faces,0 - Height_Offset @@ -1920,30 +1920,30 @@ #sc = context.scene New_Nut_Height = 5 - + Face_Start = len(verts) Thread_Verts,Thread_Faces,New_Nut_Height = Create_Internal_Thread(props.bf_Minor_Dia,props.bf_Major_Dia,props.bf_Pitch,props.bf_Hex_Nut_Height,props.bf_Crest_Percent,props.bf_Root_Percent,1) verts.extend(Thread_Verts) faces.extend(Copy_Faces(Thread_Faces,Face_Start)) - + Face_Start = len(verts) Head_Verts,Head_Faces,Lock_Nut_Rad = add_Hex_Nut(props.bf_Hex_Nut_Flat_Distance,props.bf_Major_Dia,New_Nut_Height) verts.extend((Head_Verts)) faces.extend(Copy_Faces(Head_Faces,Face_Start)) - + LowZ = 0 - New_Nut_Height - + if props.bf_Nut_Type == 'bf_Nut_Lock': Face_Start = len(verts) - Nylon_Head_Verts,Nylon_Head_faces,LowZ = add_Nylon_Head(Lock_Nut_Rad,0-New_Nut_Height) + Nylon_Head_Verts,Nylon_Head_faces,LowZ = add_Nylon_Head(Lock_Nut_Rad,0-New_Nut_Height) verts.extend((Nylon_Head_Verts)) faces.extend(Copy_Faces(Nylon_Head_faces,Face_Start)) - + Face_Start = len(verts) - Nylon_Verts,Nylon_faces,Temp_LowZ = add_Nylon_Part(Lock_Nut_Rad,0-New_Nut_Height) + Nylon_Verts,Nylon_faces,Temp_LowZ = add_Nylon_Part(Lock_Nut_Rad,0-New_Nut_Height) verts.extend((Nylon_Verts)) faces.extend(Copy_Faces(Nylon_faces,Face_Start)) - + return Move_Verts_Up_Z(verts,0 - LowZ),faces @@ -1960,7 +1960,7 @@ def Bolt_Mesh(props, context): - + verts = [] faces = [] Bit_Verts = [] @@ -1971,41 +1971,41 @@ Head_Height = 0.0 #sc = context.scene - ReSized_Allen_Bit_Flat_Distance = props.bf_Allen_Bit_Flat_Distance # set default - - + ReSized_Allen_Bit_Flat_Distance = props.bf_Allen_Bit_Flat_Distance # set default + + Head_Height = props.bf_Hex_Head_Height # will be changed by the Head Functions - - + + if props.bf_Bit_Type == 'bf_Bit_Allen' and props.bf_Head_Type == 'bf_Head_Pan': #need to size Allen bit if it is too big. if Allen_Bit_Dia(props.bf_Allen_Bit_Flat_Distance) > Max_Pan_Bit_Dia(props.bf_Pan_Head_Dia): ReSized_Allen_Bit_Flat_Distance = Allen_Bit_Dia_To_Flat(Max_Pan_Bit_Dia(props.bf_Pan_Head_Dia)) * 1.05 - #print ("Resized Allen Bit Flat Distance to ",ReSized_Allen_Bit_Flat_Distance) - + #print ("Resized Allen Bit Flat Distance to ",ReSized_Allen_Bit_Flat_Distance) + #bit Mesh if props.bf_Bit_Type == 'bf_Bit_Allen': Bit_Verts,Bit_Faces,Bit_Dia = Create_Allen_Bit(ReSized_Allen_Bit_Flat_Distance,props.bf_Allen_Bit_Depth) - + if props.bf_Bit_Type == 'bf_Bit_Philips': Bit_Verts,Bit_Faces,Bit_Dia = Create_Phillips_Bit(props.bf_Philips_Bit_Dia,props.bf_Philips_Bit_Dia*(0.5/1.82),props.bf_Phillips_Bit_Depth) - - + + #Head Mesh - - if props.bf_Head_Type =='bf_Head_Hex': + + if props.bf_Head_Type =='bf_Head_Hex': Head_Verts,Head_Faces,Head_Height = Create_Hex_Head(props.bf_Hex_Head_Flat_Distance,Bit_Dia,props.bf_Shank_Dia,props.bf_Hex_Head_Height) - elif props.bf_Head_Type == 'bf_Head_Cap': + elif props.bf_Head_Type == 'bf_Head_Cap': Head_Verts,Head_Faces,Head_Height = Create_Cap_Head(Bit_Dia,props.bf_Cap_Head_Dia,props.bf_Shank_Dia,props.bf_Cap_Head_Height,props.bf_Cap_Head_Dia*(1.0/19.0),props.bf_Cap_Head_Dia*(1.0/19.0)) - elif props.bf_Head_Type =='bf_Head_Dome': + elif props.bf_Head_Type =='bf_Head_Dome': Head_Verts,Head_Faces,Head_Height = Create_Dome_Head(Bit_Dia,props.bf_Dome_Head_Dia,props.bf_Shank_Dia,props.bf_Hex_Head_Height,1,1,0) - elif props.bf_Head_Type == 'bf_Head_Pan': + elif props.bf_Head_Type == 'bf_Head_Pan': Head_Verts,Head_Faces,Head_Height = Create_Pan_Head(Bit_Dia,props.bf_Pan_Head_Dia,props.bf_Shank_Dia,props.bf_Hex_Head_Height,1,1,0) - elif props.bf_Head_Type == 'bf_Head_CounterSink': + elif props.bf_Head_Type == 'bf_Head_CounterSink': Head_Verts,Head_Faces,Head_Height = Create_CounterSink_Head(Bit_Dia,props.bf_CounterSink_Head_Dia,props.bf_Shank_Dia,props.bf_CounterSink_Head_Dia,props.bf_CounterSink_Head_Dia*(0.09/6.31)) #Head_Verts,Head_Faces,Head_Height = Create_CounterSink_Head(Bit_Dia,props.bf_CounterSink_Head_Dia,props.bf_Shank_Dia,props.bf_CounterSink_Head_Dia,props.bf_CounterSink_Head_Dia*(1.0/19.0)) @@ -2022,7 +2022,7 @@ verts.extend(Move_Verts_Up_Z(Thread_Verts,00)) faces.extend(Copy_Faces(Thread_Faces,Face_Start)) - + return Move_Verts_Up_Z(verts,Thread_Height),faces # calculates the matrix for the new object @@ -2135,27 +2135,27 @@ faces = [] # sMeshName ='' # UNUSED sObjName ='' - + if props.bf_Model_Type == 'bf_Model_Bolt': #print('Create Bolt') verts, faces = Bolt_Mesh(props, context) # sMeshName = 'Bolt' # UNUSED sObjName = 'Bolt' - + if props.bf_Model_Type == 'bf_Model_Nut': #print('Create Nut') verts, faces = Nut_Mesh(props, context) # sMeshName = 'Nut' # UNUSED sObjName = 'Nut' - + verts, faces = RemoveDoubles(verts, faces) - + verts = Scale_Mesh_Verts(verts,GLOBAL_SCALE) - + obj = create_mesh_object(context, verts, [], faces,sObjName, props.edit, align_matrix) return obj - + diff -Nru blender-2.61/release/scripts/addons/add_mesh_BoltFactory/__init__.py blender-2.62/release/scripts/addons/add_mesh_BoltFactory/__init__.py --- blender-2.61/release/scripts/addons/add_mesh_BoltFactory/__init__.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/add_mesh_BoltFactory/__init__.py 2012-02-15 19:43:32.000000000 +0000 @@ -21,7 +21,6 @@ "author": "Aaron Keith", "version": (3, 9), "blender": (2, 5, 9), - "api": 39685, "location": "View3D > Add > Mesh", "description": "Add a bolt or nut", "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\ diff -Nru blender-2.61/release/scripts/addons/add_mesh_extra_objects/add_mesh_3d_function_surface.py blender-2.62/release/scripts/addons/add_mesh_extra_objects/add_mesh_3d_function_surface.py --- blender-2.61/release/scripts/addons/add_mesh_extra_objects/add_mesh_3d_function_surface.py 2011-12-13 19:57:59.000000000 +0000 +++ blender-2.62/release/scripts/addons/add_mesh_extra_objects/add_mesh_3d_function_surface.py 2012-02-15 19:42:30.000000000 +0000 @@ -21,7 +21,6 @@ "author": "Buerbaum Martin (Pontiac), Elod Csirmaz", "version": (0, 3, 8), "blender": (2, 5, 7), - "api": 37329, "location": "View3D > Add > Mesh", "description": "Create Objects using Math Formulas", "warning": "", @@ -149,7 +148,7 @@ '''Add a surface defined defined by a function z=f(x,y)''' bl_idname = "mesh.primitive_z_function_surface" bl_label = "Add Z Function Surface" - bl_options = {'REGISTER', 'UNDO'} + bl_options = {'REGISTER', 'UNDO', 'PRESET'} equation = StringProperty(name="Z Equation", description="Equation for z=f(x,y)", @@ -403,7 +402,7 @@ + ''' x=F1(u,v), y=F2(u,v) and z=F3(u,v)''' bl_idname = "mesh.primitive_xyz_function_surface" bl_label = "Add X,Y,Z Function Surface" - bl_options = {'REGISTER', 'UNDO'} + bl_options = {'REGISTER', 'UNDO', 'PRESET'} x_eq = StringProperty(name="X equation", description="Equation for x=F(u,v). " \ diff -Nru blender-2.61/release/scripts/addons/add_mesh_extra_objects/add_mesh_extra_objects.py blender-2.62/release/scripts/addons/add_mesh_extra_objects/add_mesh_extra_objects.py --- blender-2.61/release/scripts/addons/add_mesh_extra_objects/add_mesh_extra_objects.py 2011-12-13 19:57:59.000000000 +0000 +++ blender-2.62/release/scripts/addons/add_mesh_extra_objects/add_mesh_extra_objects.py 2012-02-15 19:42:30.000000000 +0000 @@ -357,10 +357,10 @@ return verts,faces class AddSqorus(bpy.types.Operator): - '''Add a sqorus mesh.''' + '''Add a sqorus mesh''' bl_idname = "mesh.primitive_sqorus_add" bl_label = "Add Sqorus" - bl_options = {'REGISTER', 'UNDO'} + bl_options = {'REGISTER', 'UNDO', 'PRESET'} hole_size = FloatProperty(name="Hole Size", description="Size of the Hole", @@ -386,10 +386,10 @@ class AddWedge(bpy.types.Operator): - '''Add a wedge mesh.''' + '''Add a wedge mesh''' bl_idname = "mesh.primitive_wedge_add" bl_label = "Add Wedge" - bl_options = {'REGISTER', 'UNDO'} + bl_options = {'REGISTER', 'UNDO', 'PRESET'} size_x = FloatProperty(name="Size X", description="Size along the X axis", @@ -420,10 +420,10 @@ class AddStar(bpy.types.Operator): - '''Add a star mesh.''' + '''Add a star mesh''' bl_idname = "mesh.primitive_star_add" bl_label = "Add Star" - bl_options = {'REGISTER', 'UNDO'} + bl_options = {'REGISTER', 'UNDO', 'PRESET'} points = IntProperty(name="Points", description="Number of points for the star", @@ -464,7 +464,7 @@ bl_idname = "mesh.primitive_trapezohedron_add" bl_label = "Add trapezohedron" bl_description = "Create one of the regular solids" - bl_options = {'REGISTER', 'UNDO'} + bl_options = {'REGISTER', 'UNDO', 'PRESET'} segments = IntProperty(name = "Segments", description = "Number of repeated segments", diff -Nru blender-2.61/release/scripts/addons/add_mesh_extra_objects/add_mesh_gears.py blender-2.62/release/scripts/addons/add_mesh_extra_objects/add_mesh_gears.py --- blender-2.61/release/scripts/addons/add_mesh_extra_objects/add_mesh_gears.py 2011-12-13 19:57:59.000000000 +0000 +++ blender-2.62/release/scripts/addons/add_mesh_extra_objects/add_mesh_gears.py 2012-02-15 19:42:30.000000000 +0000 @@ -24,7 +24,6 @@ "author": "Michel J. Anders (varkenvarken)", "version": (2, 4, 2), "blender": (2, 5, 7), - "api": 35853, "location": "View3D > Add > Mesh > Gears ", "description": "Adds a mesh Gear to the Add Mesh menu", "warning": "", @@ -571,10 +570,10 @@ class AddGear(bpy.types.Operator): - '''Add a gear mesh.''' + '''Add a gear mesh''' bl_idname = "mesh.primitive_gear" bl_label = "Add Gear" - bl_options = {'REGISTER', 'UNDO'} + bl_options = {'REGISTER', 'UNDO', 'PRESET'} number_of_teeth = IntProperty(name="Number of Teeth", description="Number of teeth on the gear", @@ -677,10 +676,10 @@ class AddWormGear(bpy.types.Operator): - '''Add a worm gear mesh.''' + '''Add a worm gear mesh''' bl_idname = "mesh.primitive_worm_gear" bl_label = "Add Worm Gear" - bl_options = {'REGISTER', 'UNDO'} + bl_options = {'REGISTER', 'UNDO', 'PRESET'} number_of_teeth = IntProperty(name="Number of Teeth", description="Number of teeth on the gear", diff -Nru blender-2.61/release/scripts/addons/add_mesh_extra_objects/add_mesh_gemstones.py blender-2.62/release/scripts/addons/add_mesh_extra_objects/add_mesh_gemstones.py --- blender-2.61/release/scripts/addons/add_mesh_extra_objects/add_mesh_gemstones.py 2011-12-13 19:57:59.000000000 +0000 +++ blender-2.62/release/scripts/addons/add_mesh_extra_objects/add_mesh_gemstones.py 2012-02-15 19:42:30.000000000 +0000 @@ -21,7 +21,6 @@ "author": "Pontiac, Fourmadmen, Dreampainter", "version": (0, 4), "blender": (2, 5, 7), - "api": 35853, "location": "View3D > Add > Mesh > Gemstones", "description": "Adds various gemstone (Diamond & Gem) meshes.", "warning": "", @@ -239,10 +238,10 @@ class AddDiamond(bpy.types.Operator): - '''Add a diamond mesh.''' + '''Add a diamond mesh''' bl_idname = "mesh.primitive_diamond_add" bl_label = "Add Diamond" - bl_options = {'REGISTER', 'UNDO'} + bl_options = {'REGISTER', 'UNDO', 'PRESET'} segments = IntProperty(name="Segments", description="Number of segments for the diamond", @@ -287,7 +286,7 @@ bl_idname = "mesh.primitive_gem_add" bl_label = "Add Gem" bl_description = "Create an offset faceted gem" - bl_options = {'REGISTER', 'UNDO'} + bl_options = {'REGISTER', 'UNDO', 'PRESET'} segments = IntProperty(name="Segments", description="Longitudial segmentation", diff -Nru blender-2.61/release/scripts/addons/add_mesh_extra_objects/add_mesh_polysphere.py blender-2.62/release/scripts/addons/add_mesh_extra_objects/add_mesh_polysphere.py --- blender-2.61/release/scripts/addons/add_mesh_extra_objects/add_mesh_polysphere.py 2011-12-13 19:57:59.000000000 +0000 +++ blender-2.62/release/scripts/addons/add_mesh_extra_objects/add_mesh_polysphere.py 2012-02-15 19:42:30.000000000 +0000 @@ -21,7 +21,6 @@ "author": "Andy Davies (metalliandy)", "version": (0,1,5), "blender": (2, 5, 8), - "api": 37702, "location": "View3D > Add > Mesh > PolySphere", "description": "Adds a PolySphere (all quads) for sculpting", "warning": "", diff -Nru blender-2.61/release/scripts/addons/add_mesh_extra_objects/add_mesh_pyramid.py blender-2.62/release/scripts/addons/add_mesh_extra_objects/add_mesh_pyramid.py --- blender-2.61/release/scripts/addons/add_mesh_extra_objects/add_mesh_pyramid.py 2011-12-13 19:57:59.000000000 +0000 +++ blender-2.62/release/scripts/addons/add_mesh_extra_objects/add_mesh_pyramid.py 2012-02-15 19:42:30.000000000 +0000 @@ -24,7 +24,6 @@ 'author': 'Phil Cote, cotejrp1, (http://www.blenderaddons.com)', 'version': (0, 3), "blender": (2, 5, 8), - "api": 37702, 'location': 'View3D > Add > Mesh', 'description': 'Create an egyption-style step pyramid', 'warning': '', # used for warning icon and text in addons panel @@ -113,7 +112,7 @@ """Add a Mesh Object""" bl_idname = "mesh.primitive_steppyramid_add" bl_label = "Pyramid" - bl_options = {'REGISTER', 'UNDO'} + bl_options = {'REGISTER', 'UNDO', 'PRESET'} initial_size = FloatProperty(name="Initial Size", default=2.0, min=0.0, max=20.0, @@ -152,4 +151,4 @@ if __name__ == "__main__": register() -''' \ No newline at end of file +''' diff -Nru blender-2.61/release/scripts/addons/add_mesh_extra_objects/add_mesh_supertoroid.py blender-2.62/release/scripts/addons/add_mesh_extra_objects/add_mesh_supertoroid.py --- blender-2.61/release/scripts/addons/add_mesh_extra_objects/add_mesh_supertoroid.py 2011-12-13 19:57:59.000000000 +0000 +++ blender-2.62/release/scripts/addons/add_mesh_extra_objects/add_mesh_supertoroid.py 2012-02-15 19:42:30.000000000 +0000 @@ -152,7 +152,7 @@ bl_idname = "mesh.primitive_supertoroid_add" bl_label = "Add SuperToroid" bl_description = "Create a SuperToroid" - bl_options = {'REGISTER', 'UNDO'} + bl_options = {'REGISTER', 'UNDO', 'PRESET'} R = FloatProperty(name = "big radius", description = "The radius inside the tube", diff -Nru blender-2.61/release/scripts/addons/add_mesh_extra_objects/add_mesh_twisted_torus.py blender-2.62/release/scripts/addons/add_mesh_extra_objects/add_mesh_twisted_torus.py --- blender-2.61/release/scripts/addons/add_mesh_extra_objects/add_mesh_twisted_torus.py 2011-12-13 19:57:59.000000000 +0000 +++ blender-2.62/release/scripts/addons/add_mesh_extra_objects/add_mesh_twisted_torus.py 2012-02-15 19:42:30.000000000 +0000 @@ -25,7 +25,6 @@ "author": "Paulo_Gomes", "version": (0, 11, 1), "blender": (2, 5, 7), - "api": 35853, "location": "View3D > Add > Mesh ", "description": "Adds a mesh Twisted Torus to the Add Mesh menu", "warning": "", @@ -186,7 +185,7 @@ '''Add a torus mesh''' bl_idname = "mesh.primitive_twisted_torus_add" bl_label = "Add Torus" - bl_options = {'REGISTER', 'UNDO'} + bl_options = {'REGISTER', 'UNDO', 'PRESET'} major_radius = FloatProperty(name="Major Radius", description="Radius from the origin to the" \ diff -Nru blender-2.61/release/scripts/addons/add_mesh_extra_objects/__init__.py blender-2.62/release/scripts/addons/add_mesh_extra_objects/__init__.py --- blender-2.61/release/scripts/addons/add_mesh_extra_objects/__init__.py 2011-12-13 19:57:59.000000000 +0000 +++ blender-2.62/release/scripts/addons/add_mesh_extra_objects/__init__.py 2012-02-15 19:42:30.000000000 +0000 @@ -23,7 +23,6 @@ "author": "Multiple Authors", "version": (0, 3), "blender": (2, 6, 1), - "api": 42524, "location": "View3D > Add > Mesh > Extra Objects", "description": "Add extra object types", "warning": "", diff -Nru blender-2.61/release/scripts/addons/add_mesh_pipe_joint.py blender-2.62/release/scripts/addons/add_mesh_pipe_joint.py --- blender-2.61/release/scripts/addons/add_mesh_pipe_joint.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/add_mesh_pipe_joint.py 2012-02-15 19:43:32.000000000 +0000 @@ -20,8 +20,7 @@ "name": "Pipe Joints", "author": "Buerbaum Martin (Pontiac)", "version": (0, 10, 7), - "blender": (2, 5, 9), - "api": 39685, + "blender": (2, 6, 1), "location": "View3D > Add > Mesh > Pipe Joints", "description": "Add different types of pipe joints", "warning": "", @@ -127,7 +126,7 @@ '''Add an Elbow pipe mesh''' bl_idname = "mesh.primitive_elbow_joint_add" bl_label = "Add Pipe Elbow" - bl_options = {'REGISTER', 'UNDO'} + bl_options = {'REGISTER', 'UNDO', 'PRESET'} radius = FloatProperty(name="Radius", description="The radius of the pipe", @@ -228,7 +227,7 @@ '''Add a Tee-Joint mesh''' bl_idname = "mesh.primitive_tee_joint_add" bl_label = "Add Pipe Tee-Joint" - bl_options = {'REGISTER', 'UNDO'} + bl_options = {'REGISTER', 'UNDO', 'PRESET'} radius = FloatProperty(name="Radius", description="The radius of the pipe", @@ -405,7 +404,7 @@ '''Add a Wye-Joint mesh''' bl_idname = "mesh.primitive_wye_joint_add" bl_label = "Add Pipe Wye-Joint" - bl_options = {'REGISTER', 'UNDO'} + bl_options = {'REGISTER', 'UNDO', 'PRESET'} radius = FloatProperty(name="Radius", description="The radius of the pipe", @@ -600,7 +599,7 @@ # Create the vertices and polygons for a coss (+ or X) pipe joint. bl_idname = "mesh.primitive_cross_joint_add" bl_label = "Add Pipe Cross-Joint" - bl_options = {'REGISTER', 'UNDO'} + bl_options = {'REGISTER', 'UNDO', 'PRESET'} radius = FloatProperty(name="Radius", description="The radius of the pipe", @@ -855,7 +854,7 @@ # Create the vertices and polygons for a regular n-joint. bl_idname = "mesh.primitive_n_joint_add" bl_label = "Add Pipe N-Joint" - bl_options = {'REGISTER', 'UNDO'} + bl_options = {'REGISTER', 'UNDO', 'PRESET'} radius = FloatProperty(name="Radius", description="The radius of the pipe", diff -Nru blender-2.61/release/scripts/addons/add_mesh_solid.py blender-2.62/release/scripts/addons/add_mesh_solid.py --- blender-2.61/release/scripts/addons/add_mesh_solid.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/add_mesh_solid.py 2012-02-15 19:43:32.000000000 +0000 @@ -22,7 +22,6 @@ "author": "DreamPainter", "version": (2, 0), "blender": (2, 5, 9), - "api": 39685, "location": "View3D > Add > Mesh > Solids", "description": "Add a regular solid", "warning": "", @@ -339,7 +338,7 @@ bl_idname = "mesh.primitive_solid_add" bl_label = "(Regular) solids" bl_description = "Add one of the Platonic, Archimedean or Catalan solids" - bl_options = {'REGISTER', 'UNDO'} + bl_options = {'REGISTER', 'UNDO', 'PRESET'} source = EnumProperty(items = (("4","Tetrahedron",""), ("6","Hexahedron",""), diff -Nru blender-2.61/release/scripts/addons/animation_add_corrective_shape_key.py blender-2.62/release/scripts/addons/animation_add_corrective_shape_key.py --- blender-2.61/release/scripts/addons/animation_add_corrective_shape_key.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/animation_add_corrective_shape_key.py 2012-02-15 19:43:32.000000000 +0000 @@ -16,18 +16,19 @@ # # ##### END GPL LICENSE BLOCK ##### +# + bl_info = { 'name': 'Corrective shape keys', 'author': 'Ivo Grigull (loolarge), Tal Trachtman', 'version': (1, 0), "blender": (2, 5, 7), - "api": 36157, 'location': 'Object Data > Shape Keys (Search: corrective) ', 'description': 'Creates a corrective shape key for the current pose', - "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\ - "Scripts/Animation/Corrective_Shape_Key", - "tracker_url": "https://projects.blender.org/tracker/index.php?"\ - "func=detail&aid=22129", + "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/" + "Scripts/Animation/Corrective_Shape_Key", + "tracker_url": "https://projects.blender.org/tracker/index.php?" + "func=detail&aid=22129", 'category': 'Animation'} """ @@ -37,7 +38,7 @@ The first selected object will be added to the second selected object as a new shape key. -- Original 2.4x script by ? (brecht?) +- Original 2.4x script by Brecht - Unpose-function reused from a script by Tal Trachtman in 2007 http://www.apexbow.com/randd.html - Converted to Blender 2.5 by Ivo Grigull @@ -51,91 +52,53 @@ import bpy -import mathutils +from mathutils import Vector, Matrix iterations = 20 threshold = 1e-16 + def reset_transform(ob): - m = mathutils.Matrix() - ob.matrix_local = m + ob.matrix_local.identity() -# flips rotation matrix -def flip_matrix_direction(m): - mat = mathutils.Matrix() - - mat[0][0] = m[0][0] - mat[0][1] = m[1][0] - mat[0][2] = m[2][0] - - mat[1][0] = m[0][1] - mat[1][1] = m[1][1] - mat[1][2] = m[2][1] - - mat[2][0] = m[0][2] - mat[2][1] = m[1][2] - mat[2][2] = m[2][2] - - return mat # this version is for shape_key data -def extractX(ob, mesh): - x = [] - - for i in range(0, len(mesh)): - v = mesh[i] - x += [mathutils.Vector(v.co)] - - return x - -# this version is for mesh data -def extractX_2(ob, mesh): - x = [] - - for i in range(0, len(mesh.vertices)): - v = mesh.vertices[i] - x += [mathutils.Vector(v.co)] - - return x - -def extractMappedX(ob, mesh): - totvert = len(mesh) - - mesh = ob.to_mesh( bpy.context.scene, True, 'PREVIEW' ) +def extract_vert_coords(ob, verts): + return [v.co.copy() for v in verts] + + +def extract_mapped_coords(ob, shape_verts): + totvert = len(shape_verts) - x = [] + mesh = ob.to_mesh(bpy.context.scene, True, 'PREVIEW') # cheating, the original mapped verts happen # to be at the end of the vertex array - for i in range(len(mesh.vertices)-totvert, len(mesh.vertices)): - v = mesh.vertices[i] - x += [mathutils.Vector(v.co)] + verts = mesh.vertices + arr = [verts[i].co.copy() for i in range(len(verts) - totvert, len(verts))] mesh.user_clear() - bpy.data.meshes.remove(mesh) - - return x - -def applyX(ob, mesh, x ): - for i in range(0, len(mesh)): - v = mesh[i] + bpy.data.meshes.remove(mesh) + + return arr + + +def apply_vert_coords(ob, mesh, x): + for i, v in enumerate(mesh): v.co = x[i] - ob.data.update() - - return x -def func_add_corrective_pose_shape( source, target): - - ob_1 = target +def func_add_corrective_pose_shape(source, target): + + ob_1 = target mesh_1 = target.data - ob_2 = source + ob_2 = source mesh_2 = source.data reset_transform(target) - + # If target object doesn't have Basis shape key, create it. if not mesh_1.shape_keys: basis = ob_1.shape_key_add() @@ -147,75 +110,73 @@ if key_index == 0: new_shapekey = ob_1.shape_key_add() new_shapekey.name = "Shape_" + ob_2.name - - key_index = len(mesh_1.shape_keys.key_blocks)-1 + + key_index = len(mesh_1.shape_keys.key_blocks) - 1 ob_1.active_shape_key_index = key_index - + # else, the active shape will be used (updated) - + ob_1.show_only_shape_key = True vgroup = ob_1.active_shape_key.vertex_group ob_1.active_shape_key.vertex_group = "" - - mesh_1_key_verts = mesh_1.shape_keys.key_blocks[ key_index ].data - - - x = extractX(ob_1, mesh_1_key_verts) - - targetx = extractX_2(ob_2, mesh_2) - + + mesh_1_key_verts = mesh_1.shape_keys.key_blocks[key_index].data + + x = extract_vert_coords(ob_1, mesh_1_key_verts) + + targetx = extract_vert_coords(ob_2, mesh_2.vertices) + for iteration in range(0, iterations): dx = [[], [], [], [], [], []] - - mapx = extractMappedX(ob_1, mesh_1_key_verts) - + + mapx = extract_mapped_coords(ob_1, mesh_1_key_verts) + # finite differencing in X/Y/Z to get approximate gradient for i in range(0, len(mesh_1.vertices)): epsilon = (targetx[i] - mapx[i]).length - + if epsilon < threshold: epsilon = 0.0 - - dx[0] += [x[i] + 0.5 * epsilon * mathutils.Vector((1, 0, 0))] - dx[1] += [x[i] + 0.5 * epsilon * mathutils.Vector((-1, 0, 0))] - dx[2] += [x[i] + 0.5 * epsilon * mathutils.Vector((0, 1, 0))] - dx[3] += [x[i] + 0.5 * epsilon * mathutils.Vector((0, -1, 0))] - dx[4] += [x[i] + 0.5 * epsilon * mathutils.Vector((0, 0, 1))] - dx[5] += [x[i] + 0.5 * epsilon * mathutils.Vector((0, 0, -1))] - + + dx[0] += [x[i] + 0.5 * epsilon * Vector((1, 0, 0))] + dx[1] += [x[i] + 0.5 * epsilon * Vector((-1, 0, 0))] + dx[2] += [x[i] + 0.5 * epsilon * Vector((0, 1, 0))] + dx[3] += [x[i] + 0.5 * epsilon * Vector((0, -1, 0))] + dx[4] += [x[i] + 0.5 * epsilon * Vector((0, 0, 1))] + dx[5] += [x[i] + 0.5 * epsilon * Vector((0, 0, -1))] + for j in range(0, 6): - applyX(ob_1, mesh_1_key_verts, dx[j]) - dx[j] = extractMappedX(ob_1, mesh_1_key_verts) - + apply_vert_coords(ob_1, mesh_1_key_verts, dx[j]) + dx[j] = extract_mapped_coords(ob_1, mesh_1_key_verts) + # take a step in the direction of the gradient for i in range(0, len(mesh_1.vertices)): epsilon = (targetx[i] - mapx[i]).length - + if epsilon >= threshold: Gx = list((dx[0][i] - dx[1][i]) / epsilon) Gy = list((dx[2][i] - dx[3][i]) / epsilon) Gz = list((dx[4][i] - dx[5][i]) / epsilon) - G = mathutils.Matrix((Gx, Gy, Gz)) - G = flip_matrix_direction(G) - + G = Matrix((Gx, Gy, Gz)) x[i] += G * (targetx[i] - mapx[i]) - - applyX(ob_1, mesh_1_key_verts, x ) - + + apply_vert_coords(ob_1, mesh_1_key_verts, x) ob_1.active_shape_key.vertex_group = vgroup - + # set the new shape key value to 1.0, so we see the result instantly ob_1.active_shape_key.value = 1.0 - + #mesh_1.update() ob_1.show_only_shape_key = False - -class add_corrective_pose_shape(bpy.types.Operator): - '''Adds first object as shape to second object for the current pose while maintaining modifiers (i.e. anisculpt, avoiding crazy space) Beware of slowness!!!''' - + +class add_corrective_pose_shape(bpy.types.Operator): + """Adds first object as shape to second object for the current pose """ \ + """while maintaining modifiers """ \ + """(i.e. anisculpt, avoiding crazy space) Beware of slowness!""" + bl_idname = "object.add_corrective_pose_shape" bl_label = "Add object as corrective pose shape" @@ -235,91 +196,67 @@ else: source = selection[0] - func_add_corrective_pose_shape( source, target) + func_add_corrective_pose_shape(source, target) return {'FINISHED'} -def func_object_duplicate_flatten_modifiers(ob, scene): - mesh = ob.to_mesh( bpy.context.scene, True, 'PREVIEW' ) - name = ob.name + "_clean" - new_object = bpy.data.objects.new( name, mesh) +def func_object_duplicate_flatten_modifiers(scene, obj): + mesh = obj.to_mesh(scene, True, 'PREVIEW') + name = obj.name + "_clean" + new_object = bpy.data.objects.new(name, mesh) new_object.data = mesh scene.objects.link(new_object) return new_object -class object_duplicate_flatten_modifiers(bpy.types.Operator): + +class object_duplicate_flatten_modifiers(bpy.types.Operator): '''Duplicates the selected object with modifiers applied''' - + bl_idname = "object.object_duplicate_flatten_modifiers" bl_label = "Duplicate and apply all" @classmethod def poll(cls, context): - return context.active_object != None + return context.active_object is not None def execute(self, context): - new_object = func_object_duplicate_flatten_modifiers( context.active_object, context.scene ) - context.scene.objects.active = new_object + scene = context.scene + obj_act = context.active_object - for n in bpy.data.objects: - if n != new_object: - n.select = False - else: - n.select = True - return {'FINISHED'} + new_object = func_object_duplicate_flatten_modifiers(obj_act, scene) + # setup the context + bpy.ops.object.select_all(action='DESELECT') + scene.objects.active = new_object + new_object.select = True + return {'FINISHED'} -def flip_matrix_direction_4x4(m): - mat = mathutils.Matrix() - - mat[0][0] = m[0][0] - mat[0][1] = m[1][0] - mat[0][2] = m[2][0] - mat[0][3] = m[3][0] - - mat[1][0] = m[0][1] - mat[1][1] = m[1][1] - mat[1][2] = m[2][1] - mat[1][3] = m[3][1] - - mat[2][0] = m[0][2] - mat[2][1] = m[1][2] - mat[2][2] = m[2][2] - mat[2][3] = m[3][2] - - mat[3][0] = m[0][3] - mat[3][1] = m[1][3] - mat[3][2] = m[2][3] - mat[3][3] = m[3][3] - return mat - def unposeMesh(meshObToUnpose, meshObToUnposeWeightSrc, armatureOb): psdMeshData = meshObToUnpose psdMesh = psdMeshData - I = mathutils.Matrix() #identity matrix - + I = Matrix() # identity matrix + meshData = meshObToUnposeWeightSrc.data mesh = meshData - + armData = armatureOb.data pose = armatureOb.pose - pbones = pose.bones - + pbones = pose.bones for index, v in enumerate(mesh.vertices): - # above is python shortcut for:index goes up from 0 to tot num of verts in mesh, - # with index incrementing by 1 each iteration - + # above is python shortcut for:index goes up from 0 to tot num of + # verts in mesh, with index incrementing by 1 each iteration + psdMeshVert = psdMesh[index] listOfBoneNameWeightPairs = [] - for n in mesh.vertices[index].groups: + for n in mesh.vertices[index].groups: try: name = meshObToUnposeWeightSrc.vertex_groups[n.group].name weight = n.weight @@ -330,7 +267,7 @@ break # ignore non-bone vertex groups if is_bone: - listOfBoneNameWeightPairs.append( [name, weight] ) + listOfBoneNameWeightPairs.append([name, weight]) except: print('error') pass @@ -341,13 +278,15 @@ totalWeight += pair[1] for pair in listOfBoneNameWeightPairs: - if (totalWeight>0): #avoid divide by zero! - weightedAverageDictionary[pair[0]] = pair[1]/totalWeight + if totalWeight > 0: # avoid divide by zero! + weightedAverageDictionary[pair[0]] = pair[1] / totalWeight else: weightedAverageDictionary[pair[0]] = 0 - - sigma = mathutils.Matrix(I-I) #Matrix filled with zeros - + + # Matrix filled with zeros + sigma = Matrix() + sigma.zero() + list = [] for n in pbones: list.append(n) @@ -358,9 +297,9 @@ #~ print("found key %s", pbone.name) vertexWeight = weightedAverageDictionary[pbone.name] m = pbone.matrix_channel.copy() - #m = flip_matrix_direction_4x4(m) + #m.transpose() sigma += (m - I) * vertexWeight - + else: pass #~ print("no key for bone " + pbone.name) @@ -370,45 +309,42 @@ psdMeshVert.co = psdMeshVert.co * sigma - def func_add_corrective_pose_shape_fast(source, target): - - + reset_transform(target) - + # If target object doesn't have Basis shape key, create it. if not target.data.shape_keys: basis = target.shape_key_add() basis.name = "Basis" target.data.update() - + key_index = target.active_shape_key_index if key_index == 0: - + # Insert new shape key new_shapekey = target.shape_key_add() new_shapekey.name = "Shape_" + source.name - - key_index = len(target.data.shape_keys.key_blocks)-1 + + key_index = len(target.data.shape_keys.key_blocks) - 1 target.active_shape_key_index = key_index - + # else, the active shape will be used (updated) - + target.show_only_shape_key = True - - shape_key_verts = target.data.shape_keys.key_blocks[ key_index ].data + + shape_key_verts = target.data.shape_keys.key_blocks[key_index].data try: vgroup = target.active_shape_key.vertex_group target.active_shape_key.vertex_group = '' except: - print("blub") pass # copy the local vertex positions to the new shape verts = source.data.vertices - for n in range( len(verts)): + for n in range(len(verts)): shape_key_verts[n].co = verts[n].co # go to all armature modifies and unpose the shape @@ -419,29 +355,28 @@ n.use_deform_preserve_volume = False n.use_vertex_groups = True armature = n.object - unposeMesh( shape_key_verts, target, armature) + unposeMesh(shape_key_verts, target, armature) break - + # set the new shape key value to 1.0, so we see the result instantly - target.data.shape_keys.key_blocks[ target.active_shape_key_index].value = 1.0 + target.active_shape_key.value = 1.0 try: target.active_shape_key.vertex_group = vgroup except: - #~ print("bluba") pass - + target.show_only_shape_key = False target.data.update() - -class add_corrective_pose_shape_fast(bpy.types.Operator): - '''Adds 1st object as shape to 2nd object as pose shape (only 1 armature)''' - +class add_corrective_pose_shape_fast(bpy.types.Operator): + """Adds 1st object as shape to 2nd object as pose shape + (only 1 armature)""" + bl_idname = "object.add_corrective_pose_shape_fast" bl_label = "Add object as corrective shape faster" - + @classmethod def poll(cls, context): return context.active_object != None @@ -458,20 +393,26 @@ else: source = selection[0] - func_add_corrective_pose_shape_fast( source, target) + func_add_corrective_pose_shape_fast(source, target) return {'FINISHED'} +# ----------------------------------------------------------------------------- +# GUI - -## GUI def vgroups_draw(self, context): layout = self.layout - layout.row().operator("object.object_duplicate_flatten_modifiers", text='Create duplicate for editing' ) - layout.row().operator("object.add_corrective_pose_shape_fast", text='Add as corrective pose-shape (fast, armatures only)', icon='COPY_ID') # icon is not ideal - layout.row().operator("object.add_corrective_pose_shape", text='Add as corrective pose-shape (slow, all modifiers)', icon='COPY_ID') # icon is not ideal + layout.operator("object.object_duplicate_flatten_modifiers", + text='Create duplicate for editing') + layout.operator("object.add_corrective_pose_shape_fast", + text='Add as corrective pose-shape (fast, armatures only)', + icon='COPY_ID') # icon is not ideal + layout.operator("object.add_corrective_pose_shape", + text='Add as corrective pose-shape (slow, all modifiers)', + icon='COPY_ID') # icon is not ideal + def modifiers_draw(self, context): pass @@ -480,8 +421,9 @@ def register(): bpy.utils.register_module(__name__) - bpy.types.MESH_MT_shape_key_specials.append( vgroups_draw ) - bpy.types.DATA_PT_modifiers.append( modifiers_draw ) + bpy.types.MESH_MT_shape_key_specials.append(vgroups_draw) + bpy.types.DATA_PT_modifiers.append(modifiers_draw) + def unregister(): bpy.utils.unregister_module(__name__) diff -Nru blender-2.61/release/scripts/addons/animation_animall.py blender-2.62/release/scripts/addons/animation_animall.py --- blender-2.61/release/scripts/addons/animation_animall.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/animation_animall.py 2012-02-15 19:43:32.000000000 +0000 @@ -21,7 +21,6 @@ 'author': 'Daniel Salazar ', 'version': (0, 4), "blender": (2, 5, 7), - "api": 35622, 'location': 'Select a Mesh: Tool Shelf > AnimAll panel', 'description': 'Allows animation of mesh and lattice data (Shape Keys, VCols, VGroups, UVs)', 'warning': '', diff -Nru blender-2.61/release/scripts/addons/animation_rotobezier.py blender-2.62/release/scripts/addons/animation_rotobezier.py --- blender-2.61/release/scripts/addons/animation_rotobezier.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/animation_rotobezier.py 2012-02-15 19:43:32.000000000 +0000 @@ -21,7 +21,6 @@ 'author': 'Daniel Salazar ', 'version': (0, 8), "blender": (2, 5, 7), - "api": 35622, 'location': 'Select a Curve: Tool Shelf > RotoBezier Panel', 'description': 'Allows animation of Bezier and NURBS curves', 'warning': '', diff -Nru blender-2.61/release/scripts/addons/curve_simplify.py blender-2.62/release/scripts/addons/curve_simplify.py --- blender-2.61/release/scripts/addons/curve_simplify.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/curve_simplify.py 2012-02-15 19:43:32.000000000 +0000 @@ -21,7 +21,6 @@ "author": "testscreenings", "version": (1,), "blender": (2, 5, 9), - "api": 39685, "location": "Search > Simplify Curves", "description": "Simplifies 3D curves and fcurves", "warning": "", diff -Nru blender-2.61/release/scripts/addons/development_api_navigator.py blender-2.62/release/scripts/addons/development_api_navigator.py --- blender-2.61/release/scripts/addons/development_api_navigator.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/development_api_navigator.py 2012-02-15 19:43:32.000000000 +0000 @@ -24,7 +24,6 @@ "author": "Dany Lebel (Axon_D)", "version": (1, 0, 2), "blender": (2, 5, 7), - "api": 36079, "location": "Text Editor > Properties > API Navigator Panel", "description": "Allows exploration of the python api via the user interface", "warning": "", @@ -660,15 +659,17 @@ def register_keymaps(): kc = bpy.context.window_manager.keyconfigs.addon - km = kc.keymaps.new(name="Text", space_type='TEXT_EDITOR') - km.keymap_items.new('api_navigator.toggle_doc', 'ESC', 'PRESS') + if kc: + km = kc.keymaps.new(name="Text", space_type='TEXT_EDITOR') + km.keymap_items.new('api_navigator.toggle_doc', 'ESC', 'PRESS') def unregister_keymaps(): kc = bpy.context.window_manager.keyconfigs.addon - km = kc.keymaps["Text"] - kmi = km.keymap_items["api_navigator.toggle_doc"] - km.keymap_items.remove(kmi) + if kc: + km = kc.keymaps["Text"] + kmi = km.keymap_items["api_navigator.toggle_doc"] + km.keymap_items.remove(kmi) def register(): diff -Nru blender-2.61/release/scripts/addons/development_icon_get.py blender-2.62/release/scripts/addons/development_icon_get.py --- blender-2.61/release/scripts/addons/development_icon_get.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/development_icon_get.py 2012-02-15 19:43:32.000000000 +0000 @@ -24,7 +24,6 @@ 'author': 'Crouch, N.tox, PKHG, Campbell Barton, Dany Lebel', 'version': (1, 5, 1), "blender": (2, 5, 7), - "api": 35850, 'location': 'Text Editor > Properties or '\ 'Console > Console Menu', 'warning': '', diff -Nru blender-2.61/release/scripts/addons/game_engine_save_as_runtime.py blender-2.62/release/scripts/addons/game_engine_save_as_runtime.py --- blender-2.61/release/scripts/addons/game_engine_save_as_runtime.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/game_engine_save_as_runtime.py 2012-02-15 19:43:32.000000000 +0000 @@ -21,7 +21,6 @@ 'author': 'Mitchell Stokes (Moguri)', 'version': (0, 3, 1), "blender": (2, 6, 1), - "api": 42107, 'location': 'File > Export', 'description': 'Bundle a .blend file with the Blenderplayer', 'warning': '', diff -Nru blender-2.61/release/scripts/addons/io_anim_acclaim/__init__.py blender-2.62/release/scripts/addons/io_anim_acclaim/__init__.py --- blender-2.61/release/scripts/addons/io_anim_acclaim/__init__.py 2011-12-13 19:58:40.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_anim_acclaim/__init__.py 2012-02-15 19:42:59.000000000 +0000 @@ -27,7 +27,6 @@ 'author': "Daniel Monteiro Basso ", 'version': (2011, 11, 2, 1), 'blender': (2, 6, 0), - 'api': 41226, 'location': "File > Import", 'description': "Imports Acclaim Skeleton and Motion Capture Files", 'wiki_url': "http://wiki.blender.org/index.php/Extensions:2.5/Py/" diff -Nru blender-2.61/release/scripts/addons/io_anim_bvh/import_bvh.py blender-2.62/release/scripts/addons/io_anim_bvh/import_bvh.py --- blender-2.61/release/scripts/addons/io_anim_bvh/import_bvh.py 2011-12-13 19:59:08.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_anim_bvh/import_bvh.py 2012-02-15 19:43:31.000000000 +0000 @@ -94,7 +94,7 @@ # Split by whitespace. file_lines = [ll for ll in [l.split() for l in file_lines] if ll] - # Create Hirachy as empties + # Create hierarchy as empties if file_lines[0][0].lower() == 'hierarchy': #print 'Importing the BVH Hierarchy for:', file_path pass @@ -409,10 +409,10 @@ bvh_node.temp.parent = bvh_node.parent.temp # Set the connection state - if not bvh_node.has_loc and\ - bvh_node.parent and\ - bvh_node.parent.temp.name not in ZERO_AREA_BONES and\ - bvh_node.parent.rest_tail_local == bvh_node.rest_head_local: + if((not bvh_node.has_loc) and + (bvh_node.parent.temp.name not in ZERO_AREA_BONES) and + (bvh_node.parent.rest_tail_local == bvh_node.rest_head_local)): + bvh_node.temp.use_connect = True # Replace the editbone with the editbone name, diff -Nru blender-2.61/release/scripts/addons/io_anim_bvh/__init__.py blender-2.62/release/scripts/addons/io_anim_bvh/__init__.py --- blender-2.61/release/scripts/addons/io_anim_bvh/__init__.py 2011-12-13 19:59:08.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_anim_bvh/__init__.py 2012-02-15 19:43:31.000000000 +0000 @@ -22,7 +22,6 @@ "name": "BioVision Motion Capture (BVH) format", "author": "Campbell Barton", "blender": (2, 5, 7), - "api": 35622, "location": "File > Import-Export", "description": "Import-Export BVH from armature objects", "warning": "", diff -Nru blender-2.61/release/scripts/addons/io_anim_c3d/__init__.py blender-2.62/release/scripts/addons/io_anim_c3d/__init__.py --- blender-2.61/release/scripts/addons/io_anim_c3d/__init__.py 2011-12-13 19:58:06.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_anim_c3d/__init__.py 2012-02-15 19:42:36.000000000 +0000 @@ -27,7 +27,6 @@ 'author': "Daniel Monteiro Basso ", 'version': (2011, 11, 3, 1), 'blender': (2, 6, 0), - 'api': 41226, 'location': "File > Import", 'description': "Imports C3D Graphics Lab Motion Capture files", 'wiki_url': "http://wiki.blender.org/index.php/Extensions:2.5/Py/" diff -Nru blender-2.61/release/scripts/addons/io_anim_camera.py blender-2.62/release/scripts/addons/io_anim_camera.py --- blender-2.61/release/scripts/addons/io_anim_camera.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_anim_camera.py 2012-02-15 19:43:32.000000000 +0000 @@ -23,7 +23,6 @@ "author": "Campbell Barton", "version": (0, 1), "blender": (2, 5, 7), - "api": 36079, "location": "File > Export > Cameras & Markers (.py)", "description": "Export Cameras & Markers (.py)", "warning": "", diff -Nru blender-2.61/release/scripts/addons/io_anim_nuke_chan/__init__.py blender-2.62/release/scripts/addons/io_anim_nuke_chan/__init__.py --- blender-2.61/release/scripts/addons/io_anim_nuke_chan/__init__.py 2011-12-13 19:58:53.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_anim_nuke_chan/__init__.py 2012-02-15 19:43:21.000000000 +0000 @@ -23,7 +23,6 @@ "author": "Michael Krupa", "version": (1, 0), "blender": (2, 6, 1), - "api": 36079, "location": "File > Import/Export > Nuke (.chan)", "description": "Import/Export object's animation with nuke", "warning": "", diff -Nru blender-2.61/release/scripts/addons/io_coat3D/coat.py blender-2.62/release/scripts/addons/io_coat3D/coat.py --- blender-2.61/release/scripts/addons/io_coat3D/coat.py 2011-12-13 19:58:49.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_coat3D/coat.py 2012-02-15 19:43:18.000000000 +0000 @@ -42,8 +42,14 @@ bpy.coat3D['status'] = 1 if(platform == 'win32'): exchange_path = os.path.expanduser("~") + os.sep + 'Documents' + os.sep + '3DC2Blender' + os.sep + 'Exchange_folder.txt' + applink_folder = os.path.expanduser("~") + os.sep + 'Documents' + os.sep + '3DC2Blender' + if(not(os.path.isdir(applink_folder))): + os.makedirs(applink_folder) else: - exchange_path = os.path.expanduser("~") + os.sep + '3DC2Blender' + os.sep + 'Exchange_folder.txt' + exchange_path = os.path.expanduser("~") + os.sep + 'Documents' + os.sep + '3DC2Blender' + os.sep + 'Exchange_folder.txt' + applink_folder = os.path.expanduser("~") + os.sep + 'Documents' + os.sep + '3DC2Blender' + if(not(os.path.isdir(applink_folder))): + os.makedirs(applink_folder) file = open(exchange_path, "w") file.write("%s"%(coat3D.exchangedir)) file.close() diff -Nru blender-2.61/release/scripts/addons/io_coat3D/__init__.py blender-2.62/release/scripts/addons/io_coat3D/__init__.py --- blender-2.61/release/scripts/addons/io_coat3D/__init__.py 2011-12-13 19:58:49.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_coat3D/__init__.py 2012-02-15 19:43:18.000000000 +0000 @@ -21,7 +21,6 @@ "author": "Kalle-Samuli Riihikoski (haikalle)", "version": (3, 5, 20), "blender": (2, 5, 9), - "api": 39685, "location": "Scene > 3D-Coat Applink", "description": "Transfer data between 3D-Coat/Blender", "warning": "", diff -Nru blender-2.61/release/scripts/addons/io_convert_image_to_mesh_img/__init__.py blender-2.62/release/scripts/addons/io_convert_image_to_mesh_img/__init__.py --- blender-2.61/release/scripts/addons/io_convert_image_to_mesh_img/__init__.py 2011-12-13 19:58:01.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_convert_image_to_mesh_img/__init__.py 2012-02-15 19:42:31.000000000 +0000 @@ -21,7 +21,6 @@ "author": "Tim Spriggs (tims@uahirise.org)", "version": (0, 1, 2), "blender": (2, 5, 7), - "api": 35622, "location": "File > Import > HiRISE DTM from PDS IMG (.IMG)", "description": "Import a HiRISE DTM formatted as a PDS IMG file", "warning": "May consume a lot of memory", diff -Nru blender-2.61/release/scripts/addons/io_curve_svg/import_svg.py blender-2.62/release/scripts/addons/io_curve_svg/import_svg.py --- blender-2.61/release/scripts/addons/io_curve_svg/import_svg.py 2011-12-13 19:58:45.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_curve_svg/import_svg.py 2012-02-15 19:43:15.000000000 +0000 @@ -206,10 +206,10 @@ w = SVGParseCoord(node.getAttribute('width') or str(rect[0]), rect[0]) h = SVGParseCoord(node.getAttribute('height') or str(rect[1]), rect[1]) - m = m.Translation(Vector((x, y, 0.0))) + m = Matrix.Translation(Vector((x, y, 0.0))) if len(context['rects']) > 1: - m = m * m.Scale(w / rect[0], 4, Vector((1.0, 0.0, 0.0))) - m = m * m.Scale(h / rect[1], 4, Vector((0.0, 1.0, 0.0))) + m = m * Matrix.Scale(w / rect[0], 4, Vector((1.0, 0.0, 0.0))) + m = m * Matrix.Scale(h / rect[1], 4, Vector((0.0, 1.0, 0.0))) if node.getAttribute('viewBox'): viewBox = node.getAttribute('viewBox').replace(',', ' ').split() @@ -224,11 +224,11 @@ tx = (w - vw * scale) / 2 ty = (h - vh * scale) / 2 - m = m * m.Translation(Vector((tx, ty, 0.0))) + m = m * Matrix.Translation(Vector((tx, ty, 0.0))) - m = m * m.Translation(Vector((-vx, -vy, 0.0))) - m = m * m.Scale(scale, 4, Vector((1.0, 0.0, 0.0))) - m = m * m.Scale(scale, 4, Vector((0.0, 1.0, 0.0))) + m = m * Matrix.Translation(Vector((-vx, -vy, 0.0))) + m = m * Matrix.Scale(scale, 4, Vector((1.0, 0.0, 0.0))) + m = m * Matrix.Scale(scale, 4, Vector((0.0, 1.0, 0.0))) return m @@ -313,10 +313,10 @@ e = float(params[4]) f = float(params[5]) - return Matrix(((a, b, 0.0, 0.0), - (c, d, 0.0, 0.0), - (0, 0, 1.0, 0.0), - (e, f, 0.0, 1.0))) + return Matrix(((a, c, 0.0, e), + (b, d, 0.0, f), + (0, 0, 1.0, 0), + (0, 0, 0.0, 1))) def SVGTransformScale(params): @@ -329,8 +329,8 @@ m = Matrix() - m = m * m.Scale(sx, 4, Vector((1.0, 0.0, 0.0))) - m = m * m.Scale(sy, 4, Vector((0.0, 1.0, 0.0))) + m = m * Matrix.Scale(sx, 4, Vector((1.0, 0.0, 0.0))) + m = m * Matrix.Scale(sy, 4, Vector((0.0, 1.0, 0.0))) return m @@ -442,9 +442,9 @@ SVG Path data token supplier """ - __slots__ = ('_data', # List of tokens + __slots__ = ('_data', # List of tokens '_index', # Index of current token in tokens list - '_len') # Lenght og tokens list + '_len') # Lenght og tokens list def __init__(self, d): """ @@ -454,7 +454,7 @@ """ spaces = ' ,\t' - commands = ['m', 'l', 'h', 'v', 'c', 's', 'q', '', 't', 'a', 'z'] + commands = {'m', 'l', 'h', 'v', 'c', 's', 'q', '', 't', 'a', 'z'} tokens = [] i = 0 @@ -1755,8 +1755,8 @@ node = xml.dom.minidom.parse(filepath) m = Matrix() - m = m * m.Scale(1.0 / 90.0, 4, Vector((1.0, 0.0, 0.0))) - m = m * m.Scale(-1.0 / 90.0, 4, Vector((0.0, 1.0, 0.0))) + m = m * Matrix.Scale(1.0 / 90.0, 4, Vector((1.0, 0.0, 0.0))) + m = m * Matrix.Scale(-1.0 / 90.0, 4, Vector((0.0, 1.0, 0.0))) rect = (1, 1) diff -Nru blender-2.61/release/scripts/addons/io_curve_svg/__init__.py blender-2.62/release/scripts/addons/io_curve_svg/__init__.py --- blender-2.61/release/scripts/addons/io_curve_svg/__init__.py 2011-12-13 19:58:45.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_curve_svg/__init__.py 2012-02-15 19:43:15.000000000 +0000 @@ -22,7 +22,6 @@ "name": "Scalable Vector Graphics (SVG) 1.1 format", "author": "JM Soler, Sergey Sharybin", "blender": (2, 5, 7), - "api": 36079, "location": "File > Import > Scalable Vector Graphics (.svg)", "description": "Import SVG as curves", "warning": "", diff -Nru blender-2.61/release/scripts/addons/io_export_after_effects.py blender-2.62/release/scripts/addons/io_export_after_effects.py --- blender-2.61/release/scripts/addons/io_export_after_effects.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_export_after_effects.py 2012-02-15 19:43:32.000000000 +0000 @@ -1,9 +1,9 @@ -# ***** BEGIN GPL LICENSE BLOCK ***** +# ##### BEGIN GPL LICENSE BLOCK ##### # -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. +# This program is free software; you can redistribute it and/or +# modify it under the terms of the 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 @@ -11,29 +11,33 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -# The Original Code is: all of this file. -# -# ***** END GPL LICENSE BLOCK ***** +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # +# ##### END GPL LICENSE BLOCK ##### + +# + bl_info = { 'name': 'Export: Adobe After Effects (.jsx)', - 'description': 'Export selected cameras, objects & bundles to Adobe After Effects CS3 and above', + 'description': 'Export cameras, selected objects & camera solution 3D Markers to Adobe After Effects CS3 and above', 'author': 'Bartek Skorupa', - 'version': (0, 58), - 'blender': (2, 6, 0), - 'api': 42052, + 'version': (0, 6, 0), + 'blender': (2, 6, 1), 'location': 'File > Export > Adobe After Effects (.jsx)', - 'category': 'Import-Export', "warning": "", - "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Import-Export/Adobe_After_Effects" + "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\ + "Scripts/Import-Export/Adobe_After_Effects", + "tracker_url": "https://projects.blender.org/tracker/index.php?"\ + "func=detail&aid=29858", + 'category': 'Import-Export', } -from math import pi import bpy import datetime +from math import pi +from mathutils import Matrix # create list of static blender's data @@ -42,6 +46,9 @@ aspect_x = scene.render.pixel_aspect_x aspect_y = scene.render.pixel_aspect_y aspect = aspect_x / aspect_y + start = scene.frame_start + end = scene.frame_end + active_cam_frames = get_active_cam_for_each_frame(scene, start, end) fps = scene.render.fps return { @@ -50,64 +57,104 @@ 'height': scene.render.resolution_y, 'aspect': aspect, 'fps': fps, - 'start': scene.frame_start, - 'end': scene.frame_end, - 'duration': (scene.frame_end - scene.frame_start + 1.0) / fps, + 'start': start, + 'end': end, + 'duration': (end - start + 1.0) / fps, + 'active_cam_frames': active_cam_frames, 'curframe': scene.frame_current, } +# create list of active camera for each frame in case active camera is set by markers +def get_active_cam_for_each_frame(scene, start, end): + active_cam_frames = [] + sorted_markers = [] + markers = scene.timeline_markers + if markers: + for marker in markers: + if marker.camera: + sorted_markers.append([marker.frame, marker]) + sorted_markers = sorted(sorted_markers) + + if sorted_markers: + for frame in range(start, end + 1): + for m, marker in enumerate(sorted_markers): + if marker[0] > frame: + if m != 0: + active_cam_frames.append(sorted_markers[m - 1][1].camera) + else: + active_cam_frames.append(marker[1].camera) + break + elif m == len(sorted_markers) - 1: + active_cam_frames.append(marker[1].camera) + if not active_cam_frames: + if scene.camera: + # in this case active_cam_frames array will have legth of 1. This will indicate that there is only one active cam in all frames + active_cam_frames.append(scene.camera) + + return(active_cam_frames) + + # create managable list of selected objects -# (only selected objects will be analyzed and exported) -def get_selected(context, prefix): +def get_selected(context): cameras = [] # list of selected cameras - cams_names = [] # list of selected cameras' names (prevent from calling "ConvertName(ob)" function too many times) + solids = [] # list of all selected meshes that can be exported as AE's solids + lights = [] # list of all selected lamps that can be exported as AE's lights nulls = [] # list of all selected objects exept cameras (will be used to create nulls in AE) - nulls_names = [] # list of above objects names (prevent from calling "ConvertName(ob)" function too many times) obs = context.selected_objects for ob in obs: if ob.type == 'CAMERA': - cameras.append(ob) - cams_names.append(convert_name(False, ob, prefix)) + cameras.append([ob, convert_name(ob.name)]) + + elif is_plane(ob): + # not ready yet. is_plane(object) returns False in all cases. This is temporary + solids.append([ob, convert_name(ob.name)]) + + elif ob.type == 'LAMP': + # not ready yet. Lamps will be exported as nulls. This is temporary + nulls.append([ob, convert_name(ob.name)]) + else: - nulls.append(ob) - nulls_names.append(convert_name(False, ob, prefix)) + nulls.append([ob, convert_name(ob.name)]) selection = { 'cameras': cameras, - 'cams_names': cams_names, + 'solids': solids, + 'lights': lights, 'nulls': nulls, - 'nulls_names': nulls_names, } return selection -# convert names of objects to avoid errors in AE. Add user specified prefix -def convert_name(is_comp, ob, prefix): - if is_comp: - ob_name = prefix + ob - ob_name = ob_name.replace('"', "_") - else: - ob_name = prefix + "_" + ob.name +# check if object is plane and can be exported as AE's solid +def is_plane(object): + # work in progress. Not ready yet + return False + - if ob_name[0].isdigit(): - ob_name = "_" + ob_name - - ob_name = bpy.path.clean_name(ob_name) - ob_name = ob_name.replace("-", "_") +# convert names of objects to avoid errors in AE. +def convert_name(name): + name = "_" + name - return ob_name + if name[0].isdigit(): + name = "_" + name + name = bpy.path.clean_name(name) + name = name.replace("-", "_") -# get object's blender's location and rotation and return AE's Position and Rotation/Orientation + return name + + +# get object's blender's location rotation and scale and return AE's Position, Rotation/Orientation and scale # this function will be called for every object for every frame -def convert_pos_rot_matrix(matrix, width, height, aspect, x_rot_correction=False): +def convert_transform_matrix(matrix, width, height, aspect, x_rot_correction=False): # get blender location for ob b_loc_x, b_loc_y, b_loc_z = matrix.to_translation() b_rot_x, b_rot_y, b_rot_z = matrix.to_euler() + b_scale_x, b_scale_y, b_scale_z = matrix.to_scale() # get blender rotation for ob if x_rot_correction: @@ -117,23 +164,20 @@ b_rot_y = b_rot_y / pi * 180.0 b_rot_z = b_rot_z / pi * 180.0 - # convert to AE Position and Rotation + # convert to AE Position Rotation and Scale # Axes in AE are different. AE's X is blender's X, AE's Y is negative Blender's Z, AE's Z is Blender's Y x = (b_loc_x * 100.0) / aspect + width / 2.0 # calculate AE's X position y = (-b_loc_z * 100.0) + (height / 2.0) # calculate AE's Y position z = b_loc_y * 100.0 # calculate AE's Z position + # Using AE's rotation combined with AE's orientation allows to compensate for different euler rotation order. rx = b_rot_x # calculate AE's X rotation. Will become AE's RotationX property ry = -b_rot_z # calculate AE's Y rotation. Will become AE's OrientationY property rz = b_rot_y # calculate AE's Z rotation. Will become AE's OrentationZ property - # Using AE's rotation combined with AE's orientation allows to compensate for different euler rotation order. - - return x, y, z, rx, ry, rz - - -def convert_pos_rot(obj, width, height, aspect, x_rot_correction=False): - matrix = obj.matrix_world.copy() - return convert_pos_rot_matrix(matrix, width, height, aspect, x_rot_correction) + sx = b_scale_x * 100.0 # scale of 1.0 is 100% in AE + sy = b_scale_z * 100.0 # scale of 1.0 is 100% in AE + sz = b_scale_y * 100.0 # scale of 1.0 is 100% in AE + return x, y, z, rx, ry, rz, sx, sy, sz # get camera's lens and convert to AE's "zoom" value in pixels # this function will be called for every camera for every frame @@ -179,27 +223,28 @@ # # above is true if square pixels are used. If not - aspect compensation is needed, so final formula is: # zoom = lens * dimension / sensor * aspect -# + + def convert_lens(camera, width, height, aspect): - if hasattr(camera.data, "sensor_width"): # Preserve compatibility with versions not supporting camera sensor. - if camera.data.sensor_fit == 'VERTICAL': - sensor = camera.data.sensor_height - dimension = height - else: - sensor = camera.data.sensor_width - dimension = width + if camera.data.sensor_fit == 'VERTICAL': + sensor = camera.data.sensor_height + dimension = height else: - sensor = 32 # standard blender's sensor size + sensor = camera.data.sensor_width dimension = width - + zoom = camera.data.lens * dimension / sensor * aspect return zoom +# convert object bundle's matrix. Not ready yet. Temporarily not active +#def get_ob_bundle_matrix_world(cam_matrix_world, bundle_matrix): +# matrix = cam_matrix_basis +# return matrix + # jsx script for AE creation -def write_jsx_file(file, data, selection, export_bundles, comp_name, prefix): - from mathutils import Matrix +def write_jsx_file(file, data, selection, include_active_cam, include_selected_cams, include_selected_objects, include_cam_bundles, include_rotation, include_scale): print("\n---------------------------\n- Export to After Effects -\n---------------------------") #store the current frame to restore it at the enf of export @@ -208,12 +253,22 @@ js_data = { 'times': '', 'cameras': {}, - 'objects': {}, + 'solids': {}, + 'lights': {}, + 'nulls': {}, + 'bundles_cam': {}, + 'bundles_ob': {}, # not ready yet } - # create camera structure - for i, cam in enumerate(selection['cameras']): # more than one camera can be selected - name_ae = selection['cams_names'][i] + # create structure for active camera/cameras + active_cam_name = '' + if include_active_cam and data['active_cam_frames'] != []: + # check if more that one active cam exist (true if active cams set by markers) + if len(data['active_cam_frames']) is 1: + name_ae = convert_name(data['active_cam_frames'][0].name) # take name of the only active camera in scene + else: + name_ae = 'Active_Camera' + active_cam_name = name_ae # store name to be used when creating keyframes for active cam. js_data['cameras'][name_ae] = { 'position': '', 'pointOfInterest': '', @@ -222,48 +277,169 @@ 'zoom': '', } - # create object structure - for i, obj in enumerate(selection['nulls']): # nulls representing blender's obs except cameras - name_ae = selection['nulls_names'][i] - js_data['objects'][name_ae] = { + # create camera structure for selected cameras + if include_selected_cams: + for i, cam in enumerate(selection['cameras']): # more than one camera can be selected + if cam[1] != active_cam_name: + name_ae = selection['cameras'][i][1] + js_data['cameras'][name_ae] = { + 'position': '', + 'pointOfInterest': '', + 'orientation': '', + 'rotationX': '', + 'zoom': '', + } + ''' + # create structure for solids. Not ready yet. Temporarily not active + for i, obj in enumerate(selection['solids']): + name_ae = selection['solids'][i][1] + js_data['solids'][name_ae] = { 'position': '', 'orientation': '', 'rotationX': '', + 'scale': '', } - # get all keyframes for each objects and store into dico + # create structure for lights. Not ready yet. Temporarily not active + for i, obj in enumerate(selection['lights']): + name_ae = selection['lights'][i][1] + js_data['nulls'][name_ae] = { + 'position': '', + 'orientation': '', + 'rotationX': '', + 'scale': '', + } + ''' + + # create structure for nulls + for i, obj in enumerate(selection['nulls']): # nulls representing blender's obs except cameras, lamps and solids + if include_selected_objects: + name_ae = selection['nulls'][i][1] + js_data['nulls'][name_ae] = { + 'position': '', + 'orientation': '', + 'rotationX': '', + 'scale': '', + } + + # create structure for cam bundles including positions (cam bundles don't move) + if include_cam_bundles: + # go through each selected Camera and active cameras + selected_cams = [] + active_cams = [] + if include_active_cam: + active_cams = data['active_cam_frames'] + if include_selected_cams: + for cam in selection['cameras']: + selected_cams.append(cam[0]) + # list of cameras that will be checked for 'CAMERA SOLVER' + cams = list(set.union(set(selected_cams), set(active_cams))) + + for cam in cams: + # go through each constraints of this camera + for constraint in cam.constraints: + # does the camera have a Camera Solver constraint + if constraint.type == 'CAMERA_SOLVER': + # Which movie clip does it use ? + if constraint.use_active_clip: + clip = data['scn'].active_clip + else: + clip = constraint.clip + + # go through each tracking point + for track in clip.tracking.tracks: + # Does this tracking point have a bundle (has its 3D position been solved) + if track.has_bundle: + # get the name of the tracker + name_ae = convert_name(str(cam.name) + '__' + str(track.name)) + js_data['bundles_cam'][name_ae] = { + 'position': '', + } + # bundles are in camera space. Transpose to world space + matrix = Matrix.Translation(cam.matrix_basis.copy() * track.bundle) + # convert the position into AE space + ae_transform = convert_transform_matrix(matrix, data['width'], data['height'], data['aspect'], x_rot_correction=False) + js_data['bundles_cam'][name_ae]['position'] += '[%f,%f,%f],' % (ae_transform[0], ae_transform[1], ae_transform[2]) + + # get all keyframes for each object and store in dico for frame in range(data['start'], data['end'] + 1): print("working on frame: " + str(frame)) data['scn'].frame_set(frame) - #get time for this loop + # get time for this loop js_data['times'] += '%f ,' % ((frame - data['start']) / data['fps']) - # keyframes for all cameras - for i, cam in enumerate(selection['cameras']): - #get cam name - name_ae = selection['cams_names'][i] - #convert cam position to AE space - ae_pos_rot = convert_pos_rot(cam, data['width'], data['height'], data['aspect'], x_rot_correction=True) - #convert Blender's cam zoom to AE's - zoom = convert_lens(cam, data['width'], data['height'], data['aspect']) - #store all the value into dico - js_data['cameras'][name_ae]['position'] += '[%f,%f,%f],' % (ae_pos_rot[0], ae_pos_rot[1], ae_pos_rot[2]) - js_data['cameras'][name_ae]['pointOfInterest'] += '[%f,%f,%f],' % (ae_pos_rot[0], ae_pos_rot[1], ae_pos_rot[2]) - js_data['cameras'][name_ae]['orientation'] += '[%f,%f,%f],' % (0, ae_pos_rot[4], ae_pos_rot[5]) - js_data['cameras'][name_ae]['rotationX'] += '%f ,' % (ae_pos_rot[3]) + # keyframes for active camera/cameras + if include_active_cam and data['active_cam_frames'] != []: + if len(data['active_cam_frames']) == 1: + cur_cam_index = 0 + else: + cur_cam_index = frame - data['start'] + active_cam = data['active_cam_frames'][cur_cam_index] + # get cam name + name_ae = active_cam_name + # convert cam transform properties to AE space + ae_transform = convert_transform_matrix(active_cam.matrix_world.copy(), data['width'], data['height'], data['aspect'], x_rot_correction=True) + # convert Blender's lens to AE's zoom in pixels + zoom = convert_lens(active_cam, data['width'], data['height'], data['aspect']) + # store all values in dico + js_data['cameras'][name_ae]['position'] += '[%f,%f,%f],' % (ae_transform[0], ae_transform[1], ae_transform[2]) + js_data['cameras'][name_ae]['pointOfInterest'] += '[%f,%f,%f],' % (ae_transform[0], ae_transform[1], ae_transform[2]) + js_data['cameras'][name_ae]['orientation'] += '[%f,%f,%f],' % (0, ae_transform[4], ae_transform[5]) + js_data['cameras'][name_ae]['rotationX'] += '%f ,' % (ae_transform[3]) js_data['cameras'][name_ae]['zoom'] += '[%f],' % (zoom) - #keyframes for all nulls - for i, ob in enumerate(selection['nulls']): + # keyframes for selected cameras + if include_selected_cams: + for i, cam in enumerate(selection['cameras']): + if cam[1] != active_cam_name: + # get cam name + name_ae = selection['cameras'][i][1] + # convert cam transform properties to AE space + ae_transform = convert_transform_matrix(cam[0].matrix_world.copy(), data['width'], data['height'], data['aspect'], x_rot_correction=True) + # convert Blender's lens to AE's zoom in pixels + zoom = convert_lens(cam[0], data['width'], data['height'], data['aspect']) + # store all values in dico + js_data['cameras'][name_ae]['position'] += '[%f,%f,%f],' % (ae_transform[0], ae_transform[1], ae_transform[2]) + js_data['cameras'][name_ae]['pointOfInterest'] += '[%f,%f,%f],' % (ae_transform[0], ae_transform[1], ae_transform[2]) + js_data['cameras'][name_ae]['orientation'] += '[%f,%f,%f],' % (0, ae_transform[4], ae_transform[5]) + js_data['cameras'][name_ae]['rotationX'] += '%f ,' % (ae_transform[3]) + js_data['cameras'][name_ae]['zoom'] += '[%f],' % (zoom) + + ''' + # keyframes for all solids. Not ready yet. Temporarily not active + for i, ob in enumerate(selection['solids']): + #get object name + name_ae = selection['solids'][i][1] + #convert ob position to AE space + + + # keyframes for all lights. Not ready yet. Temporarily not active + for i, ob in enumerate(selection['lights']): #get object name - name_ae = selection['nulls_names'][i] + name_ae = selection['lights'][i][1] #convert ob position to AE space - ae_pos_rot = convert_pos_rot(ob, data['width'], data['height'], data['aspect'], x_rot_correction=False) - #store all datas into dico - js_data['objects'][name_ae]['position'] += '[%f,%f,%f],' % (ae_pos_rot[0], ae_pos_rot[1], ae_pos_rot[2]) - js_data['objects'][name_ae]['orientation'] += '[%f,%f,%f],' % (0, ae_pos_rot[4], ae_pos_rot[5]) - js_data['objects'][name_ae]['rotationX'] += '%f ,' % (ae_pos_rot[3]) + ''' + + # keyframes for all nulls + if include_selected_objects: + for i, ob in enumerate(selection['nulls']): + # get object name + name_ae = selection['nulls'][i][1] + # convert ob transform properties to AE space + ae_transform = convert_transform_matrix(ob[0].matrix_world.copy(), data['width'], data['height'], data['aspect'], x_rot_correction=False) + # store all values in dico + js_data['nulls'][name_ae]['position'] += '[%f,%f,%f],' % (ae_transform[0], ae_transform[1], ae_transform[2]) + if include_rotation: + js_data['nulls'][name_ae]['orientation'] += '[%f,%f,%f],' % (0, ae_transform[4], ae_transform[5]) + js_data['nulls'][name_ae]['rotationX'] += '%f ,' % (ae_transform[3]) + if include_scale: + js_data['nulls'][name_ae]['scale'] += '[%f,%f,%f],' % (ae_transform[6], ae_transform[7], ae_transform[8]) + + # keyframes for all object bundles. Not ready yet. + # + # + # # ---- write JSX file jsx_file = open(file, 'w') @@ -279,12 +455,45 @@ jsx_file.write('Exported with io_export_after_effects.py\n') jsx_file.write('**************************************/\n\n\n\n') - #wrap in function + # wrap in function jsx_file.write("function compFromBlender(){\n") # create new comp - jsx_file.write('\nvar compName = "%s";' % (comp_name)) - jsx_file.write('\nvar newComp = app.project.items.addComp(compName, %i, %i, %f, %f, %i);\n\n\n' % + jsx_file.write('\nvar compName = prompt("Blender Comp\'s Name \\nEnter Name of newly created Composition","BlendComp","Composition\'s Name");\n') + jsx_file.write('if (compName){') + jsx_file.write('\nvar newComp = app.project.items.addComp(compName, %i, %i, %f, %f, %i);' % (data['width'], data['height'], data['aspect'], data['duration'], data['fps'])) + jsx_file.write('\nnewComp.displayStartTime = %f;\n\n\n' % ((data['start'] + 1.0) / data['fps'])) + + # create camera bundles (nulls) + jsx_file.write('// ************** CAMERA 3D MARKERS **************\n\n\n') + for i, obj in enumerate(js_data['bundles_cam']): + name_ae = obj + jsx_file.write('var %s = newComp.layers.addNull();\n' % (name_ae)) + jsx_file.write('%s.threeDLayer = true;\n' % name_ae) + jsx_file.write('%s.source.name = "%s";\n' % (name_ae, name_ae)) + jsx_file.write('%s.property("position").setValue(%s);\n\n\n' % (name_ae, js_data['bundles_cam'][obj]['position'])) + + # create object bundles (not ready yet) + + # create objects (nulls) + jsx_file.write('// ************** OBJECTS **************\n\n\n') + for i, obj in enumerate(js_data['nulls']): + name_ae = obj + jsx_file.write('var %s = newComp.layers.addNull();\n' % (name_ae)) + jsx_file.write('%s.threeDLayer = true;\n' % name_ae) + jsx_file.write('%s.source.name = "%s";\n' % (name_ae, name_ae)) + jsx_file.write('%s.property("position").setValuesAtTimes([%s],[%s]);\n' % (name_ae, js_data['times'], js_data['nulls'][obj]['position'])) + if include_rotation: + jsx_file.write('%s.property("orientation").setValuesAtTimes([%s],[%s]);\n' % (name_ae, js_data['times'], js_data['nulls'][obj]['orientation'])) + jsx_file.write('%s.property("rotationX").setValuesAtTimes([%s],[%s]);\n' % (name_ae, js_data['times'], js_data['nulls'][obj]['rotationX'])) + jsx_file.write('%s.property("rotationY").setValue(0);\n' % name_ae) + jsx_file.write('%s.property("rotationZ").setValue(0);\n\n\n' % name_ae) + if include_scale: + jsx_file.write('%s.property("scale").setValuesAtTimes([%s],[%s]);\n\n\n' % (name_ae, js_data['times'], js_data['nulls'][obj]['scale'])) + + # create solids (not ready yet) + + # create lights (not ready yet) # create cameras jsx_file.write('// ************** CAMERAS **************\n\n\n') @@ -299,55 +508,7 @@ jsx_file.write('%s.property("rotationZ").setValue(0);\n' % name_ae) jsx_file.write('%s.property("zoom").setValuesAtTimes([%s],[%s]);\n\n\n' % (name_ae, js_data['times'], js_data['cameras'][cam]['zoom'])) - # create objects - jsx_file.write('// ************** OBJECTS **************\n\n\n') - for i, obj in enumerate(js_data['objects']): # more than one camera can be selected - name_ae = obj - jsx_file.write('var %s = newComp.layers.addNull();\n' % (name_ae)) - jsx_file.write('%s.threeDLayer = true;\n' % name_ae) - jsx_file.write('%s.source.name = "%s";\n' % (name_ae, name_ae)) - jsx_file.write('%s.property("position").setValuesAtTimes([%s],[%s]);\n' % (name_ae, js_data['times'], js_data['objects'][obj]['position'])) - jsx_file.write('%s.property("orientation").setValuesAtTimes([%s],[%s]);\n' % (name_ae, js_data['times'], js_data['objects'][obj]['orientation'])) - jsx_file.write('%s.property("rotationX").setValuesAtTimes([%s],[%s]);\n' % (name_ae, js_data['times'], js_data['objects'][obj]['rotationX'])) - jsx_file.write('%s.property("rotationY").setValue(0);\n' % name_ae) - jsx_file.write('%s.property("rotationZ").setValue(0);\n\n\n' % name_ae) - - # create Bundles - if export_bundles: - - jsx_file.write('// ************** BUNDLES (3d tracks) **************\n\n\n') - - #Bundles are linked to MovieClip, so we have to find which MC is linked to our selected camera (if any?) - mc = '' - - #go through each selected Cameras - for cam in selection['cameras']: - #go through each constrains of this camera - for constrain in cam.constraints: - #does the camera have a Camera Solver constrain - if constrain.type == 'CAMERA_SOLVER': - #Which movie clip does it use ? - if constrain.use_active_clip: - mc = data['scn'].active_clip - else: - mc = constrain.clip - - #go throuhg each tracking point - for track in mc.tracking.tracks: - #is this tracking point has a Bundles (does it's 3D position has been solved) - if track.has_bundle: - # bundle are in camera space, so transpose it to world space - matrix = Matrix.Translation(cam.matrix_basis * track.bundle) - #convert the position into AE space - ae_pos_rot = convert_pos_rot_matrix(matrix, data['width'], data['height'], data['aspect'], x_rot_correction=False) - #get the name of the tracker - name_ae = convert_name(False, track, prefix) - #write JS script for this Bundle - jsx_file.write('var %s = newComp.layers.addNull();\n' % name_ae) - jsx_file.write('%s.threeDLayer = true;\n' % name_ae) - jsx_file.write('%s.source.name = "%s";\n' % (name_ae, name_ae)) - jsx_file.write('%s.property("position").setValue([%f,%f,%f]);\n\n\n' % (name_ae, ae_pos_rot[0], ae_pos_rot[1], ae_pos_rot[2])) - + jsx_file.write('\n}else{alert ("Exit Import Blender animation data \\nNo Comp\'s name has been chosen","EXIT")};') jsx_file.write("}\n\n\n") jsx_file.write('app.beginUndoGroup("Import Blender animation data");\n') jsx_file.write('compFromBlender();\n') @@ -361,11 +522,10 @@ ########################################## -def main(file, context, export_bundles, comp_name, prefix): +def main(file, context, include_active_cam, include_selected_cams, include_selected_objects, include_cam_bundles, include_rotation, include_scale): data = get_comp_data(context) - selection = get_selected(context, prefix) - comp_name = convert_name(True, comp_name, "") - write_jsx_file(file, data, selection, export_bundles, comp_name, prefix) + selection = get_selected(context) + write_jsx_file(file, data, selection, include_active_cam, include_selected_cams, include_selected_objects, include_cam_bundles, include_rotation, include_scale) print ("\nExport to After Effects Completed") return {'FINISHED'} @@ -384,28 +544,67 @@ filename_ext = ".jsx" filter_glob = StringProperty(default="*.jsx", options={'HIDDEN'}) - comp_name = StringProperty( - name="Comp Name", - description="Name of composition to be created in After Effects", - default="BlendComp" + include_active_cam = BoolProperty( + name="Active Camera", + description="Include Active Camera Data", + default=True, + ) + include_selected_cams = BoolProperty( + name="Selected Cameras", + description="Add Selected Cameras Data", + default=True, + ) + include_selected_objects = BoolProperty( + name="Selected Objects", + description="Add Selected Objects Data", + default=True, + ) + include_rotation = BoolProperty( + name="Rotation", + description="Include rotation of selected objects", + default=True, ) - prefix = StringProperty( - name="Layer's Prefix", - description="Prefix to use before AE layer's name", - #default="bl_" + include_scale = BoolProperty( + name="Scale", + description="Include scale of selected object", + default=True, ) - export_bundles = BoolProperty( - name="Export Bundles", - description="Export 3D Tracking points of a selected camera", - default=False, + include_cam_bundles = BoolProperty( + name="Camera 3D Markers", + description="Include 3D Markers of Camera Motion Solution for selected cameras", + default=True, ) +# include_ob_bundles = BoolProperty( +# name="Objects 3D Markers", +# description="Include 3D Markers of Object Motion Solution for selected cameras", +# default=True, +# ) + + def draw(self, context): + layout = self.layout + + box = layout.box() + box.label('Include Cameras and Objects:') + box.prop(self, 'include_active_cam') + box.prop(self, 'include_selected_cams') + box.prop(self, 'include_selected_objects') + box.label("Include Objects' Properties:") + box.prop(self, 'include_rotation') + box.prop(self, 'include_scale') + box.label("Include Tracking Data:") + box.prop(self, 'include_cam_bundles') +# box.prop(self, 'include_ob_bundles') @classmethod def poll(cls, context): - return context.active_object is not None + active = context.active_object + selected = context.selected_objects + camera = context.scene.camera + ok = selected or camera + return ok def execute(self, context): - return main(self.filepath, context, self.export_bundles, self.comp_name, self.prefix) + return main(self.filepath, context, self.include_active_cam, self.include_selected_cams, self.include_selected_objects, self.include_cam_bundles, self.include_rotation, self.include_scale) def menu_func(self, context): diff -Nru blender-2.61/release/scripts/addons/io_export_directx_x.py blender-2.62/release/scripts/addons/io_export_directx_x.py --- blender-2.61/release/scripts/addons/io_export_directx_x.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_export_directx_x.py 2012-02-15 19:43:32.000000000 +0000 @@ -20,7 +20,6 @@ "author": "Chris Foster (Kira Vakaan)", "version": (2, 1, 2), "blender": (2, 5, 8), - "api": 37702, "location": "File > Export > DirectX (.x)", "description": "Export DirectX Model Format (.x)", "warning": "", @@ -236,10 +235,10 @@ Config.File.write("{}FrameTransformMatrix {{\n".format(" " * Config.Whitespace)) Config.Whitespace += 1 - Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, Config.SystemMatrix[0][0], Config.SystemMatrix[0][1], Config.SystemMatrix[0][2], Config.SystemMatrix[0][3])) - Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, Config.SystemMatrix[1][0], Config.SystemMatrix[1][1], Config.SystemMatrix[1][2], Config.SystemMatrix[1][3])) - Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, Config.SystemMatrix[2][0], Config.SystemMatrix[2][1], Config.SystemMatrix[2][2], Config.SystemMatrix[2][3])) - Config.File.write("{}{:9f},{:9f},{:9f},{:9f};;\n".format(" " * Config.Whitespace, Config.SystemMatrix[3][0], Config.SystemMatrix[3][1], Config.SystemMatrix[3][2], Config.SystemMatrix[3][3])) + Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, Config.SystemMatrix[0][0], Config.SystemMatrix[1][0], Config.SystemMatrix[2][0], Config.SystemMatrix[3][0])) + Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, Config.SystemMatrix[0][1], Config.SystemMatrix[1][1], Config.SystemMatrix[2][1], Config.SystemMatrix[3][1])) + Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, Config.SystemMatrix[0][2], Config.SystemMatrix[1][2], Config.SystemMatrix[2][2], Config.SystemMatrix[3][2])) + Config.File.write("{}{:9f},{:9f},{:9f},{:9f};;\n".format(" " * Config.Whitespace, Config.SystemMatrix[0][3], Config.SystemMatrix[1][3], Config.SystemMatrix[2][3], Config.SystemMatrix[3][3])) Config.Whitespace -= 1 Config.File.write("{}}}\n".format(" " * Config.Whitespace)) @@ -313,10 +312,10 @@ Config.File.write("{}FrameTransformMatrix {{\n".format(" " * Config.Whitespace)) Config.Whitespace += 1 - Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, LocalMatrix[0][0], LocalMatrix[0][1], LocalMatrix[0][2], LocalMatrix[0][3])) - Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, LocalMatrix[1][0], LocalMatrix[1][1], LocalMatrix[1][2], LocalMatrix[1][3])) - Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, LocalMatrix[2][0], LocalMatrix[2][1], LocalMatrix[2][2], LocalMatrix[2][3])) - Config.File.write("{}{:9f},{:9f},{:9f},{:9f};;\n".format(" " * Config.Whitespace, LocalMatrix[3][0], LocalMatrix[3][1], LocalMatrix[3][2], LocalMatrix[3][3])) + Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, LocalMatrix[0][0], LocalMatrix[1][0], LocalMatrix[2][0], LocalMatrix[3][0])) + Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, LocalMatrix[0][1], LocalMatrix[1][1], LocalMatrix[2][1], LocalMatrix[3][1])) + Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, LocalMatrix[0][2], LocalMatrix[1][2], LocalMatrix[2][2], LocalMatrix[3][2])) + Config.File.write("{}{:9f},{:9f},{:9f},{:9f};;\n".format(" " * Config.Whitespace, LocalMatrix[0][3], LocalMatrix[1][3], LocalMatrix[2][3], LocalMatrix[3][3])) Config.Whitespace -= 1 Config.File.write("{}}}\n".format(" " * Config.Whitespace)) @@ -340,10 +339,10 @@ Config.File.write("{}FrameTransformMatrix {{\n".format(" " * Config.Whitespace)) Config.Whitespace += 1 - Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, BoneMatrix[0][0], BoneMatrix[0][1], BoneMatrix[0][2], BoneMatrix[0][3])) - Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, BoneMatrix[1][0], BoneMatrix[1][1], BoneMatrix[1][2], BoneMatrix[1][3])) - Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, BoneMatrix[2][0], BoneMatrix[2][1], BoneMatrix[2][2], BoneMatrix[2][3])) - Config.File.write("{}{:9f},{:9f},{:9f},{:9f};;\n".format(" " * Config.Whitespace, BoneMatrix[3][0], BoneMatrix[3][1], BoneMatrix[3][2], BoneMatrix[3][3])) + Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, BoneMatrix[0][0], BoneMatrix[1][0], BoneMatrix[2][0], BoneMatrix[3][0])) + Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, BoneMatrix[0][1], BoneMatrix[1][1], BoneMatrix[2][1], BoneMatrix[3][1])) + Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, BoneMatrix[0][2], BoneMatrix[1][2], BoneMatrix[2][2], BoneMatrix[3][2])) + Config.File.write("{}{:9f},{:9f},{:9f},{:9f};;\n".format(" " * Config.Whitespace, BoneMatrix[0][3], BoneMatrix[1][3], BoneMatrix[2][3], BoneMatrix[3][3])) Config.Whitespace -= 1 Config.File.write("{}}}\n".format(" " * Config.Whitespace)) @@ -655,10 +654,10 @@ BoneMatrix *= ArmatureObject.matrix_world.inverted() BoneMatrix *= Object.matrix_world - Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, BoneMatrix[0][0], BoneMatrix[0][1], BoneMatrix[0][2], BoneMatrix[0][3])) - Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, BoneMatrix[1][0], BoneMatrix[1][1], BoneMatrix[1][2], BoneMatrix[1][3])) - Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, BoneMatrix[2][0], BoneMatrix[2][1], BoneMatrix[2][2], BoneMatrix[2][3])) - Config.File.write("{}{:9f},{:9f},{:9f},{:9f};;\n".format(" " * Config.Whitespace, BoneMatrix[3][0], BoneMatrix[3][1], BoneMatrix[3][2], BoneMatrix[3][3])) + Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, BoneMatrix[0][0], BoneMatrix[1][0], BoneMatrix[2][0], BoneMatrix[3][0])) + Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, BoneMatrix[0][1], BoneMatrix[1][1], BoneMatrix[2][1], BoneMatrix[3][1])) + Config.File.write("{}{:9f},{:9f},{:9f},{:9f},\n".format(" " * Config.Whitespace, BoneMatrix[0][2], BoneMatrix[1][2], BoneMatrix[2][2], BoneMatrix[3][2])) + Config.File.write("{}{:9f},{:9f},{:9f},{:9f};;\n".format(" " * Config.Whitespace, BoneMatrix[0][3], BoneMatrix[1][3], BoneMatrix[2][3], BoneMatrix[3][3])) Config.Whitespace -= 1 Config.File.write("{}}} //End of {} Skin Weights\n".format(" " * Config.Whitespace, LegalName(ArmatureObject.name) + "_" + LegalName(Bone.name))) diff -Nru blender-2.61/release/scripts/addons/io_export_pc2.py blender-2.62/release/scripts/addons/io_export_pc2.py --- blender-2.61/release/scripts/addons/io_export_pc2.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_export_pc2.py 2012-02-15 19:43:32.000000000 +0000 @@ -21,7 +21,6 @@ "author": "Florian Meyer (tstscr)", "version": (1, 0), "blender": (2, 5, 7), - "api": 36079, "location": "File > Export > Pointcache (.pc2)", "description": "Export mesh Pointcache data (.pc2)", "warning": "", @@ -106,7 +105,7 @@ ###### EXPORT OPERATOR ####### class Export_pc2(bpy.types.Operator, ExportHelper): - '''Exports the active Object as a .pc2 Pointcache file.''' + '''Exports the active Object as a .pc2 Pointcache file''' bl_idname = "export_shape.pc2" bl_label = "Export Pointcache (.pc2)" diff -Nru blender-2.61/release/scripts/addons/io_export_unreal_psk_psa.py blender-2.62/release/scripts/addons/io_export_unreal_psk_psa.py --- blender-2.61/release/scripts/addons/io_export_unreal_psk_psa.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_export_unreal_psk_psa.py 2012-02-15 19:43:32.000000000 +0000 @@ -20,7 +20,6 @@ "author": "Darknet/Optimus_P-Fat/Active_Trash/Sinsoft/VendorX", "version": (2, 4), "blender": (2, 6, 0), - "api": 36079, "location": "File > Export > Skeletal Mesh/Animation Data (.psk/.psa)", "description": "Export Skeleletal Mesh/Animation Data", "warning": "", @@ -1809,7 +1808,7 @@ bpy.types.Scene.unrealexport_settings = EnumProperty( name="Export:", - description="Select a export settings (psk/psa/all)...", + description="Select a export settings (psk/psa/all)", items = [("0","PSK","Export PSK"), ("1","PSA","Export PSA"), ("2","ALL","Export ALL")], @@ -1825,7 +1824,7 @@ bpy.types.Scene.unrealtriangulatebool = BoolProperty( name="Triangulate Mesh", - description="Convert Quad to Tri Mesh Boolean...", + description="Convert Quad to Tri Mesh Boolean", default=False) bpy.types.Scene.unrealignoreactionmatchcount = BoolProperty( @@ -1873,7 +1872,7 @@ class OBJECT_OT_add_remove_Collection_Items_UE(bpy.types.Operator): bl_label = "Add or Remove" bl_idname = "collection.add_remove_ueactions" - __doc__ = """Button for Add, Remove, Refresh Action Set(s) list.""" + __doc__ = """Button for Add, Remove, Refresh Action Set(s) list""" set = bpy.props.StringProperty() def invoke(self, context, event): @@ -1932,7 +1931,7 @@ '''Export Skeleton Mesh / Animation Data file(s)''' bl_idname = "export_anim.udk" # this is important since its how bpy.ops.export.udk_anim_data is constructed bl_label = "Export PSK/PSA" - __doc__ = """One mesh and one armature else select one mesh or armature to be exported.""" + __doc__ = """One mesh and one armature else select one mesh or armature to be exported""" # List of operator properties, the attributes will be assigned # to the class instance from the operator settings before calling. @@ -2068,7 +2067,7 @@ global exportmessage bl_idname = "export_mesh.udk" # XXX, name??? bl_label = "Unreal Export" - __doc__ = """Select export setting for .psk/.psa or both.""" + __doc__ = """Select export setting for .psk/.psa or both""" def invoke(self, context, event): print("Init Export Script:") @@ -2095,7 +2094,7 @@ global exportmessage bl_idname = "object.toggleconsle" # XXX, name??? bl_label = "Toggle Console" - __doc__ = "Show or Hide Console." + __doc__ = "Show or Hide Console" def invoke(self, context, event): bpy.ops.wm.console_toggle() @@ -2104,7 +2103,7 @@ class OBJECT_OT_UTSelectedFaceSmooth(bpy.types.Operator): bl_idname = "object.utselectfacesmooth" # XXX, name??? bl_label = "Select Smooth faces" - __doc__ = """It will only select smooth faces that is select mesh.""" + __doc__ = """It will only select smooth faces that is select mesh""" def invoke(self, context, event): print("----------------------------------------") @@ -2159,7 +2158,7 @@ class OBJECT_OT_MeshClearWeights(bpy.types.Operator): bl_idname = "object.meshclearweights" # XXX, name??? bl_label = "Mesh Clear Weights" - __doc__ = """Clear selected mesh vertex group weights for the bones. Be sure you unparent the armature.""" + __doc__ = """Clear selected mesh vertex group weights for the bones. Be sure you unparent the armature""" def invoke(self, context, event): for obj in bpy.data.objects: @@ -2172,7 +2171,7 @@ class OBJECT_OT_UTRebuildArmature(bpy.types.Operator): bl_idname = "object.utrebuildarmature" # XXX, name??? bl_label = "Rebuild Armature" - __doc__ = """If mesh is deform when importing to unreal engine try this. It rebuild the bones one at the time by select one armature object scrape to raw setup build. Note the scale will be 1:1 for object mode. To keep from deforming.""" + __doc__ = """If mesh is deform when importing to unreal engine try this. It rebuild the bones one at the time by select one armature object scrape to raw setup build. Note the scale will be 1:1 for object mode. To keep from deforming""" def invoke(self, context, event): print("----------------------------------------") @@ -2243,7 +2242,7 @@ class OBJECT_OT_UTRebuildMesh(bpy.types.Operator): bl_idname = "object.utrebuildmesh" # XXX, name??? bl_label = "Rebuild Mesh" - __doc__ = """It rebuild the mesh from scrape from the selected mesh object. Note the scale will be 1:1 for object mode. To keep from deforming.""" + __doc__ = """It rebuild the mesh from scrape from the selected mesh object. Note the scale will be 1:1 for object mode. To keep from deforming""" def invoke(self, context, event): print("----------------------------------------") diff -Nru blender-2.61/release/scripts/addons/io_import_gimp_image_to_scene.py blender-2.62/release/scripts/addons/io_import_gimp_image_to_scene.py --- blender-2.61/release/scripts/addons/io_import_gimp_image_to_scene.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_import_gimp_image_to_scene.py 2012-02-15 19:43:32.000000000 +0000 @@ -21,23 +21,22 @@ "author": "Daniel Salazar (ZanQdo)", "version": (2, 0, 0), "blender": (2, 5, 7), - "api": 36079, "location": "File > Import > GIMP Image to Scene(.xcf/.xjt)", "description": "Imports GIMP multilayer image files as a series of multiple planes", "warning": "XCF import requires xcftools installed", - "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\ - "Scripts/Import-Export/GIMPImageToScene", - "tracker_url": "http://projects.blender.org/tracker/index.php?"\ - "func=detail&aid=25136", + "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/" + "Scripts/Import-Export/GIMPImageToScene", + "tracker_url": "http://projects.blender.org/tracker/index.php?" + "func=detail&aid=25136", "category": "Import-Export"} """ This script imports GIMP layered image files into 3D Scenes (.xcf, .xjt) """ -def main(File, Path, LayerViewers, MixerViewers, LayerOffset,\ - LayerScale, OpacityMode, PremulAlpha, ShadelessMats,\ - SetCamera, SetupCompo, GroupUntagged, Ext): +def main(File, Path, LayerViewers, MixerViewers, LayerOffset, + LayerScale, OpacityMode, PremulAlpha, ShadelessMats, + SetCamera, SetupCompo, GroupUntagged, Ext): #------------------------------------------------- @@ -147,8 +146,8 @@ os.rename(PathSaveRaw+imageFile, PathSaveRaw+NameShort+'.jpg') if HasAlpha: os.rename(PathSaveRaw+imageFileAlpha, PathSaveRaw+NameShort+'_A'+'.jpg') - IMGs.append({'LayerMode':md, 'LayerOpacity':op,\ - 'LayerName':n, 'LayerNameShort':NameShort,\ + IMGs.append({'LayerMode':md, 'LayerOpacity':op, + 'LayerName':n, 'LayerNameShort':NameShort, 'RenderLayer':RenderLayer, 'LayerCoords':[ow, oh, ox, oy], 'HasAlpha':HasAlpha}) else: # Ext == '.xcf': @@ -194,14 +193,14 @@ Mode = LineThree[:Slash] Opacity = float(LineThree[Slash+1:LineThree.find('%')])*.01 - IMGs.append ({\ - 'LayerMode':Mode,\ - 'LayerOpacity':Opacity,\ - 'LayerName':Line[4].rstrip(),\ - 'LayerNameShort':NameShort,\ - 'LayerCoords':list(map(int, Line[1].replace('x', ' ').replace('+', ' +').replace('-', ' -').split())),\ - 'RenderLayer':RenderLayer,\ - 'HasAlpha':True,\ + IMGs.append ({ + 'LayerMode': Mode, + 'LayerOpacity': Opacity, + 'LayerName': Line[4].rstrip(), + 'LayerNameShort': NameShort, + 'LayerCoords': list(map(int, Line[1].replace('x', ' ').replace('+', ' +').replace('-', ' -').split())), + 'RenderLayer': RenderLayer, + 'HasAlpha': True, }) elif Line.startswith('Version'): ResX, ResY = map (int, Line.split()[2].split('x')) @@ -213,8 +212,8 @@ else: Opacity = ' --percent 100' for Layer in IMGs: - CMD = '%s -C %s%s -o %s%s.png "%s"%s' %\ - (XCF2PNG, Path, File, PathSave, Layer['LayerName'].replace(' ', '_'), Layer['LayerName'], Opacity) + CMD = ('%s -C %s%s -o %s%s.png "%s"%s' % + (XCF2PNG, Path, File, PathSave, Layer['LayerName'].replace(' ', '_'), Layer['LayerName'], Opacity)) os.system(CMD) #------------------------------------------------- @@ -286,13 +285,12 @@ LayerList.append([RenderLayer, LayerMode, LayerOpacity]) LayerNum += 1 - + # Object - bpy.ops.mesh.primitive_plane_add(\ - view_align=False,\ - enter_editmode=False,\ - rotation=(0, 0, pi)) - + bpy.ops.mesh.primitive_plane_add(view_align=False, + enter_editmode=False, + rotation=(0, 0, pi)) + bpy.ops.object.transform_apply(location=False, rotation=True, scale=False) @@ -301,8 +299,8 @@ if SetupCompo: Active.layers = LayerFlags[RenderLayer] - Active.location = (\ - (float(Coords[2])-(ResX*0.5))*LayerScale,\ + Active.location = ( + (float(Coords[2])-(ResX*0.5))*LayerScale, (-float(Coords[3])+(ResY*0.5))*LayerScale, Z) for Vert in Active.data.vertices: @@ -420,16 +418,15 @@ LayerList = [] for Layer in IMGs: - Make3DLayer(\ - Layer['LayerName'].replace(' ', '_'),\ - Layer['LayerNameShort'].replace(' ', '_'),\ - Z,\ - Layer['LayerCoords'],\ - Layer['RenderLayer'],\ - Layer['LayerMode'],\ - Layer['LayerOpacity'],\ - Layer['HasAlpha'],\ - ) + Make3DLayer(Layer['LayerName'].replace(' ', '_'), + Layer['LayerNameShort'].replace(' ', '_'), + Z, + Layer['LayerCoords'], + Layer['RenderLayer'], + Layer['LayerMode'], + Layer['LayerOpacity'], + Layer['HasAlpha'], + ) Z -= LayerOffset @@ -647,9 +644,9 @@ # Call Main Function if Ext: - main(filename, directory, LayerViewers, MixerViewers, LayerOffset,\ - LayerScale, OpacityMode, PremulAlpha, ShadelessMats,\ - SetCamera, SetupCompo, GroupUntagged, Ext) + main(filename, directory, LayerViewers, MixerViewers, LayerOffset, + LayerScale, OpacityMode, PremulAlpha, ShadelessMats, + SetCamera, SetupCompo, GroupUntagged, Ext) else: self.report({'ERROR'},"Selected file wasn't valid, try .xcf or .xjt") diff -Nru blender-2.61/release/scripts/addons/io_import_images_as_planes.py blender-2.62/release/scripts/addons/io_import_images_as_planes.py --- blender-2.61/release/scripts/addons/io_import_images_as_planes.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_import_images_as_planes.py 2012-02-15 19:43:32.000000000 +0000 @@ -20,108 +20,135 @@ "name": "Import Images as Planes", "author": "Florian Meyer (tstscr)", "version": (1, 0), - "blender": (2, 5, 7), - "api": 35622, + "blender": (2, 6, 1), "location": "File > Import > Images as Planes", - "description": "Imports images and creates planes with the appropriate aspect ratio. "\ - "The images are mapped to the planes.", + "description": "Imports images and creates planes with the appropriate " + "aspect ratio. The images are mapped to the planes.", "warning": "", - "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\ - "Scripts/Add_Mesh/Planes_from_Images", - "tracker_url": "https://projects.blender.org/tracker/index.php?"\ - "func=detail&aid=21751", + "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/" + "Scripts/Add_Mesh/Planes_from_Images", + "tracker_url": "https://projects.blender.org/tracker/index.php?" + "func=detail&aid=21751", "category": "Import-Export"} -import bpy, os, mathutils -from bpy.props import * -from add_utils import * +import bpy +from bpy.types import Operator +import mathutils +import os + +from bpy.props import (BoolProperty, + EnumProperty, + IntProperty, + FloatProperty, + ) + +from add_utils import AddObjectHelper, add_object_data from bpy_extras.io_utils import ImportHelper from bpy_extras.image_utils import load_image -## GLOBAL VARS ## +# ----------------------------------------------------------------------------- +# Global Vars + EXT_LIST = { - 'jpeg': ['jpeg', 'jpg', 'jpe'], - 'png': ['png'], - 'tga': ['tga', 'tpic'], - 'tiff': ['tiff', 'tif'], - 'exr': ['exr'], - 'hdr': ['hdr'], - 'avi': ['avi'], - 'mov': ['mov', 'qt'], - 'mp4': ['mp4'], - 'ogg': ['ogg', 'ogv'], - 'bmp': ['bmp', 'dib'], - 'cin': ['cin'], - 'dpx': ['dpx'], - 'psd': ['psd']} -EXT_VALS = [val for val in EXT_LIST.values()] -EXTENSIONS = [] -for i in EXT_VALS: - EXTENSIONS.extend(i) - -## FUNCTIONS ## + 'jpeg': ('jpeg', 'jpg', 'jpe'), + 'png': ('png', ), + 'tga': ('tga', 'tpic'), + 'tiff': ('tiff', 'tif'), + 'exr': ('exr', ), + 'hdr': ('hdr', ), + 'avi': ('avi', ), + 'mov': ('mov', 'qt'), + 'mp4': ('mp4', ), + 'ogg': ('ogg', 'ogv'), + 'bmp': ('bmp', 'dib'), + 'cin': ('cin', ), + 'dpx': ('dpx', ), + 'psd': ('psd', ), + } + +EXTENSIONS = [ext for ext_ls in EXT_LIST.values() for ext in ext_ls] + + +# ----------------------------------------------------------------------------- +# Functions def set_image_options(self, image): image.use_premultiply = self.use_premultiply - + + if self.relative: + image.filepath = bpy.path.relpath(image.filepath) + + +def is_image_fn_any(fn): + ext = os.path.splitext(fn)[1].lstrip(".").lower() + return ext in EXTENSIONS + + +def is_image_fn_single(fn, ext_key): + ext = os.path.splitext(fn)[1].lstrip(".").lower() + return ext in EXT_LIST[ext_key] + + def create_image_textures(self, image): - #look for texture with importsettings + + fn_full = os.path.normpath(bpy.path.abspath(image.filepath)) + + # look for texture with importsettings for texture in bpy.data.textures: - if texture.type == 'IMAGE'\ - and texture.image\ - and texture.image.filepath == image.filepath: - if self.use_transparency: - texture.use_alpha = True - else: - texture.use_alpha = False - return texture - - #if no texture is found: create one - texture = bpy.data.textures.new(name=os.path.split(image.filepath)[1], - type='IMAGE') + if texture.type == 'IMAGE': + tex_img = texture.image + if (tex_img is not None) and (tex_img.library is None): + fn_tex_full = os.path.normpath(bpy.path.abspath(tex_img.filepath)) + if fn_full == fn_tex_full: + texture.use_alpha = self.use_transparency + return texture + + # if no texture is found: create one + name_compat = bpy.path.display_name_from_filepath(image.filepath) + texture = bpy.data.textures.new(name=name_compat, type='IMAGE') texture.image = image - if self.use_transparency: - texture.use_alpha = True - else: - texture.use_alpha = False + texture.use_alpha = self.use_transparency return texture + def create_material_for_texture(self, texture): - #look for material with the needed texture + # look for material with the needed texture for material in bpy.data.materials: - if material.texture_slots[0]\ - and material.texture_slots[0].texture == texture: + slot = material.texture_slots[0] + if slot and slot.texture == texture: if self.use_transparency: - material.alpha = 0 - material.specular_alpha = 0 - material.texture_slots[0].use_map_alpha = True + material.alpha = 0.0 + material.specular_alpha = 0.0 + slot.use_map_alpha = True else: - material.alpha = 1 - material.specular_alpha = 1 - material.texture_slots[0].use_map_alpha = False + material.alpha = 1.0 + material.specular_alpha = 1.0 + slot.use_map_alpha = False material.use_transparency = self.use_transparency material.transparency_method = self.transparency_method material.use_shadeless = self.use_shadeless return material - + # if no material found: create one - material = bpy.data.materials.new(name=os.path.split(texture.image.filepath)[1]) + name_compat = bpy.path.display_name_from_filepath(texture.image.filepath) + material = bpy.data.materials.new(name=name_compat) slot = material.texture_slots.add() slot.texture = texture slot.texture_coords = 'UV' if self.use_transparency: slot.use_map_alpha = True - material.alpha = 0 - material.specular_alpha = 0 + material.alpha = 0.0 + material.specular_alpha = 0.0 else: - material.alpha = 1 - material.specular_alpha = 1 + material.alpha = 1.0 + material.specular_alpha = 1.0 slot.use_map_alpha = False material.use_transparency = self.use_transparency material.transparency_method = self.transparency_method material.use_shadeless = self.use_shadeless - + return material + def create_image_plane(self, context, material): img = material.texture_slots[0].texture.image px, py = img.size @@ -137,11 +164,12 @@ x = (px * (1.0 / self.factor)) * 0.5 y = (py * (1.0 / self.factor)) * 0.5 - verts = [(-x, -y, 0), - (x, -y, 0), - (x, y, 0), - (-x, y, 0)] - faces = [[0, 1, 2, 3]] + verts = ((-x, -y, 0.0), + (+x, -y, 0.0), + (+x, +y, 0.0), + (-x, +y, 0.0), + ) + faces = ((0, 1, 2, 3), ) mesh_data = bpy.data.meshes.new(img.name) mesh_data.from_pydata(verts, [], faces) @@ -156,54 +184,58 @@ material.game_settings.alpha_blend = 'ALPHA' return plane + def generate_paths(self): - directory, file = os.path.split(self.filepath) + directory, fn = os.path.split(self.filepath) - if file and not self.all_in_directory: - #test for extension - if not os.path.splitext(file)[1].lstrip('.').lower() in EXTENSIONS: + if fn and not self.all_in_directory: + # test for extension + if not is_image_fn_any(fn): return [], directory - + return [self.filepath], directory - - if not file or self.all_in_directory: + + if not fn or self.all_in_directory: imagepaths = [] files_in_directory = os.listdir(directory) - #clean files from nonimages - files_in_directory = [file for file in files_in_directory - if os.path.splitext(file)[1].lstrip('.').lower() - in EXTENSIONS] - #clean from unwanted extensions - if self.extension != '*': - files_in_directory = [file for file in files_in_directory - if os.path.splitext(file)[1].lstrip('.').lower() - in EXT_LIST[self.extension]] - #create paths - for file in files_in_directory: - imagepaths.append(os.path.join(directory, file)) - + # clean files from nonimages + files_in_directory = [fn for fn in files_in_directory + if is_image_fn_any(fn)] + # clean from unwanted extensions + if self.extension != "*": + files_in_directory = [fn for fn in files_in_directory + if is_image_fn_single(fn, self.extension)] + # create paths + for fn in files_in_directory: + imagepaths.append(os.path.join(directory, fn)) + #print(imagepaths) return imagepaths, directory + def align_planes(self, planes): gap = self.align_offset offset = 0 for i, plane in enumerate(planes): - offset += (plane.dimensions.x / 2) + gap - if i == 0: continue - move_local = mathutils.Vector((offset, 0, 0)) + offset += (plane.dimensions.x / 2.0) + gap + if i == 0: + continue + move_local = mathutils.Vector((offset, 0.0, 0.0)) move_world = plane.location + move_local * plane.matrix_world.inverted() plane.location += move_world - offset += (plane.dimensions.x / 2) - -##### MAIN ##### + offset += (plane.dimensions.x / 2.0) + + +# ----------------------------------------------------------------------------- +# Main + def import_images(self, context): import_list, directory = generate_paths(self) images = [] textures = [] materials = [] planes = [] - + for path in import_list: images.append(load_image(path, directory)) @@ -217,27 +249,30 @@ for material in materials: plane = create_image_plane(self, context, material) planes.append(plane) - + context.scene.update() if self.align: align_planes(self, planes) - + for plane in planes: plane.select = True - - self.report(type={'INFO'}, - message='Added %i Image Plane(s)' %len(planes)) - -##### OPERATOR ##### -class IMPORT_OT_image_to_plane(bpy.types.Operator, ImportHelper, AddObjectHelper): - '''''' + + self.report({'INFO'}, "Added %i Image Plane(s)" % len(planes)) + + +# ----------------------------------------------------------------------------- +# Operator + +class IMPORT_OT_image_to_plane(Operator, ImportHelper, AddObjectHelper): + """Create mesh plane(s) from image files """ \ + """with the appropiate aspect ratio""" + bl_idname = "import.image_to_plane" bl_label = "Import Images as Planes" - bl_description = "Create mesh plane(s) from image files" \ - " with the appropiate aspect ratio" bl_options = {'REGISTER', 'UNDO'} - ## OPTIONS ## + # ------- + # Options all_in_directory = BoolProperty( name="All in directory", description=("Import all image files (of the selected type) " @@ -256,39 +291,40 @@ soft_min=0, default=0.1, ) - extEnum = ( - ('*', 'All image formats', - 'Import all know image (or movie) formats.'), - ('jpeg', 'JPEG (.jpg, .jpeg, .jpe)', - 'Joint Photographic Experts Group'), - ('png', 'PNG (.png)', 'Portable Network Graphics'), - ('tga', 'Truevision TGA (.tga, tpic)', ''), - ('tiff', 'TIFF (.tif, .tiff)', 'Tagged Image File Format'), - ('exr', 'OpenEXR (.exr)', 'OpenEXR HDR imaging image file format'), - ('hdr', 'Radiance HDR (.hdr, .pic)', ''), - ('avi', 'AVI (.avi)', 'Audio Video Interleave'), - ('mov', 'QuickTime (.mov, .qt)', ''), - ('mp4', 'MPEG-4 (.mp4)', ' MPEG-4 Part 14'), - ('ogg', 'OGG Theora (.ogg, .ogv)', ''), - ('bmp', 'BMP (.bmp, .dib)', 'Windows Bitmap'), - ('cin', 'CIN (.cin)', ''), - ('dpx', 'DPX (.dpx)', 'DPX (Digital Picture Exchange)'), - ('psd', 'PSD (.psd)', 'Photoshop Document'), - ) extension = EnumProperty( name="Extension", description="Only import files of this type", - items=extEnum) + items=( + ('*', 'All image formats', + 'Import all know image (or movie) formats.'), + ('jpeg', 'JPEG (.jpg, .jpeg, .jpe)', + 'Joint Photographic Experts Group'), + ('png', 'PNG (.png)', 'Portable Network Graphics'), + ('tga', 'Truevision TGA (.tga, tpic)', ''), + ('tiff', 'TIFF (.tif, .tiff)', 'Tagged Image File Format'), + ('exr', 'OpenEXR (.exr)', 'OpenEXR HDR imaging image file format'), + ('hdr', 'Radiance HDR (.hdr, .pic)', ''), + ('avi', 'AVI (.avi)', 'Audio Video Interleave'), + ('mov', 'QuickTime (.mov, .qt)', ''), + ('mp4', 'MPEG-4 (.mp4)', ' MPEG-4 Part 14'), + ('ogg', 'OGG Theora (.ogg, .ogv)', ''), + ('bmp', 'BMP (.bmp, .dib)', 'Windows Bitmap'), + ('cin', 'CIN (.cin)', ''), + ('dpx', 'DPX (.dpx)', 'DPX (Digital Picture Exchange)'), + ('psd', 'PSD (.psd)', 'Photoshop Document')), + ) use_dimension = BoolProperty(name="Use image dimensions", - description="Use the images pixels to derive the size of the plane", - default=False) + description="Use the images pixels to derive planes size", + default=False, + ) factor = IntProperty(name="Pixels/BU", description="Number of pixels per Blenderunit", min=1, default=500, ) - ## MATERIAL OPTIONS ## + # ---------------- + # Material Options use_shadeless = BoolProperty( name="Shadeless", description="Set material to shadeless", @@ -299,79 +335,95 @@ description="Use alphachannel for transparency", default=False, ) - tEnum = ( + + transparency_method = EnumProperty( + name="Transp. Method", + description="Transparency Method", + items=( ('Z_TRANSPARENCY', 'Z Transparency', 'Use alpha buffer for transparent faces'), ('RAYTRACE', 'Raytrace', - 'Use raytracing for transparent refraction rendering.')) - transparency_method = EnumProperty( - name="Transp. Method", - description="Transparency Method", - items=tEnum, + 'Use raytracing for transparent refraction rendering.')), ) - ## IMAGE OPTIONS ## + # ------------- + # Image Options use_premultiply = BoolProperty(name="Premultiply", description="Premultiply image", default=False) - ## DRAW ## + relative = BoolProperty( + name="Relative", + description="Apply relative paths", + default=True, + ) + def draw(self, context): layout = self.layout - - box = layout.box() - box.label('Import Options:', icon='FILTER') - box.prop(self, 'all_in_directory') - box.prop(self, 'extension', icon='FILE_IMAGE') - box.prop(self, 'align') - box.prop(self, 'align_offset') - + box = layout.box() - box.label('Material mappings:', icon='MATERIAL') - box.prop(self, 'use_shadeless') - box.prop(self, 'use_transparency') - box.prop(self, 'use_premultiply') - box.prop(self, 'transparency_method', expand=True) - + box.label("Import Options:", icon='FILTER') + box.prop(self, "all_in_directory") + box.prop(self, "extension", icon='FILE_IMAGE') + box.prop(self, "align") + box.prop(self, "align_offset") + + row = box.row() + row.active = bpy.data.is_saved + row.prop(self, "relative") + box = layout.box() - box.label('Plane dimensions:', icon='ARROW_LEFTRIGHT') - box.prop(self, 'use_dimension') - box.prop(self, 'factor', expand=True) + box.label("Material mappings:", icon='MATERIAL') + box.prop(self, "use_shadeless") + box.prop(self, "use_transparency") + box.prop(self, "use_premultiply") + box.prop(self, "transparency_method", expand=True) + box = layout.box() + box.label("Plane dimensions:", icon='ARROW_LEFTRIGHT') + box.prop(self, "use_dimension") + box.prop(self, "factor", expand=True) - ## EXECUTE ## def execute(self, context): - #the add utils don't work in this case - #because many objects are added - #disable relevant things beforehand + + if not bpy.data.is_saved: + self.relative = False + + # the add utils don't work in this case + # because many objects are added + # disable relevant things beforehand editmode = context.user_preferences.edit.use_enter_edit_mode context.user_preferences.edit.use_enter_edit_mode = False if context.active_object\ and context.active_object.mode == 'EDIT': bpy.ops.object.mode_set(mode='OBJECT') - + import_images(self, context) - + context.user_preferences.edit.use_enter_edit_mode = editmode return {'FINISHED'} +# ----------------------------------------------------------------------------- +# Register -##### REGISTER ##### - def import_images_button(self, context): - self.layout.operator(IMPORT_OT_image_to_plane.bl_idname, text="Images as Planes", icon='PLUGIN') + self.layout.operator(IMPORT_OT_image_to_plane.bl_idname, + text="Images as Planes", + icon='PLUGIN') + def register(): bpy.utils.register_module(__name__) - bpy.types.INFO_MT_file_import.append(import_images_button) + + def unregister(): bpy.utils.unregister_module(__name__) - bpy.types.INFO_MT_file_import.remove(import_images_button) + if __name__ == '__main__': register() diff -Nru blender-2.61/release/scripts/addons/io_import_scene_dxf.py blender-2.62/release/scripts/addons/io_import_scene_dxf.py --- blender-2.61/release/scripts/addons/io_import_scene_dxf.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_import_scene_dxf.py 2012-02-15 19:43:32.000000000 +0000 @@ -19,12 +19,12 @@ bl_info = { 'name': 'Import Autocad DXF Format (.dxf)', 'author': 'Thomas Larsson, Remigiusz Fiedler', - 'version': (0, 1, 5), - "blender": (2, 6, 0), - "api": 40791, + 'version': (0, 1, 6), + "blender": (2, 6, 1), 'location': 'File > Import > Autocad (.dxf)', 'description': 'Import files in the Autocad DXF format (.dxf)', - 'warning': 'Only subset of DXF specification is supported, work in progress.', + 'warning': 'Only a subset of DXF specification is supported now.'\ + ' Please support further development!', 'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.5/Py/'\ 'Scripts/Import-Export/DXF_Importer', 'tracker_url': 'https://projects.blender.org/tracker/index.php?'\ @@ -48,16 +48,18 @@ - ignores COLOR, LINEWIDTH, LINESTYLE This script is a temporary solution. -Probably no more improvements will be done to this script. -The full-feature importer script from 2.49 will be back in 2.6 release. +No functionality improvements are planed for this version. +The advanced importer from 2.49 will replace it in the future. Installation: Place this file to Blender addons directory (on Windows it is %Blender_directory%\2.53\scripts\addons\) -You must activate the script in the "Addons" tab (user preferences). +The script must be activated in "Addons" tab (user preferences). Access it from File > Import menu. History: +ver 0.1.6 - 2012.01.03 by migius and trumanblending for r.42615 +- modified for recent changes to matrix indexing ver 0.1.5 - 2011.02.05 by migius for r.34661 - changed support level to OFFICIAL - fixed missing last point at building Mesh-ARCs (by pildanovak) @@ -1402,7 +1404,7 @@ if az.z > 0.0: return False elif az.z < 0.0: - return Matrix((-WORLDX, WORLDY*1, -WORLDZ)) + return Matrix((-WORLDX, WORLDY*1, -WORLDZ)).transposed() cap = 0.015625 # square polar cap value (1/64.0) if abs(az.x) < cap and abs(az.y) < cap: @@ -1412,27 +1414,27 @@ ax.normalize() ay = az.cross(ax) ay.normalize() - return Matrix((ax, ay, az)) + # Matrices are now constructed from rows, transpose to make the rows into cols + return Matrix((ax, ay, az)).transposed() def transform(normal, rotation, obj): #-------------------------------------------- """Use the calculated ocs to determine the objects location/orientation in space. """ - ma = Matrix(((1,0,0,0),(0,1,0,0),(0,0,1,0),(0,0,0,1))) + ma = Matrix() o = Vector(obj.location) ma_new = getOCS(normal) if ma_new: + ma_new.resize_4x4() ma = ma_new - ma.resize_4x4() o = ma * o if rotation != 0: - g = radians(-rotation) - rmat = Matrix(((cos(g), -sin(g), 0), (sin(g), cos(g), 0), (0, 0, 1))) - ma = ma * rmat.to_4x4() + rmat = Matrix.Rotation(radians(rotation), 4, 'Z') + ma = ma * rmat - obj.matrix_world = ma #must be matrix4x4 + obj.matrix_world = ma obj.location = o diff -Nru blender-2.61/release/scripts/addons/io_import_scene_lwo.py blender-2.62/release/scripts/addons/io_import_scene_lwo.py --- blender-2.61/release/scripts/addons/io_import_scene_lwo.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_import_scene_lwo.py 2012-02-15 19:43:32.000000000 +0000 @@ -21,7 +21,6 @@ "author": "Ken Nign (Ken9)", "version": (1, 2), "blender": (2, 5, 7), - "api": 35622, "location": "File > Import > LightWave Object (.lwo)", "description": "Imports a LWO file including any UV, Morph and Color maps. "\ "Can convert Skelegons to an Armature.", diff -Nru blender-2.61/release/scripts/addons/io_import_scene_mhx.py blender-2.62/release/scripts/addons/io_import_scene_mhx.py --- blender-2.61/release/scripts/addons/io_import_scene_mhx.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_import_scene_mhx.py 2012-02-15 19:43:32.000000000 +0000 @@ -9,8 +9,8 @@ # 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. # @@ -26,7 +26,7 @@ """ Abstract MHX (MakeHuman eXchange format) importer for Blender 2.5x. -Version 1.9.0 +Version 1.10.2 This script should be distributed with Blender. If not, place it in the .blender/scripts/addons dir @@ -39,9 +39,8 @@ bl_info = { 'name': 'Import: MakeHuman (.mhx)', 'author': 'Thomas Larsson', - 'version': (1, 9, 1), + 'version': (1, 10, 2), "blender": (2, 5, 9), - "api": 40335, 'location': "File > Import > MakeHuman (.mhx)", 'description': 'Import files in the MakeHuman eXchange format (.mhx)', 'warning': '', @@ -51,8 +50,8 @@ 'category': 'Import-Export'} MAJOR_VERSION = 1 -MINOR_VERSION = 9 -SUB_VERSION = 0 +MINOR_VERSION = 10 +SUB_VERSION = 2 BLENDER_VERSION = (2, 59, 2) # @@ -113,68 +112,17 @@ T_Opcns = 0x2000 T_Symm = 0x4000 -toggle = (T_EnforceVersion + T_Replace + T_Mesh + T_Armature + +toggle = (T_EnforceVersion + T_Mesh + T_Armature + T_Face + T_Shape + T_Proxy + T_Clothes + T_Rigify) # -# setFlagsAndFloats(rigFlags): -# -# Global floats -#fFingerPanel = 0.0 -#fFingerIK = 0.0 -fNoStretch = 0.0 - -# rigLeg and rigArm flags -T_Toes = 0x0001 -#T_GoboFoot = 0x0002 - -#T_InvFoot = 0x0010 -#T_InvFootPT = 0x0020 -#T_InvFootNoPT = 0x0040 - -#T_FingerPanel = 0x100 -#T_FingerRot = 0x0200 -#T_FingerIK = 0x0400 - - -#T_LocalFKIK = 0x8000 - -#rigLeg = 0 -#rigArm = 0 - -def setFlagsAndFloats(): - ''' - global toggle, rigLeg, rigArm - - (footRig, fingerRig) = rigFlags - rigLeg = 0 - if footRig == 'Reverse foot': - rigLeg |= T_InvFoot - if toggle & T_PoleTar: - rigLeg |= T_InvFootPT - else: - rigLeg |= T_InvFootNoPT - elif footRig == 'Gobo': rigLeg |= T_GoboFoot - - rigArm = 0 - if fingerRig == 'Panel': rigArm |= T_FingerPanel - elif fingerRig == 'Rotation': rigArm |= T_FingerRot - elif fingerRig == 'IK': rigArm |= T_FingerIK - - toggle |= T_Panel - ''' - global fNoStretch - if toggle&T_Stretch: fNoStretch == 0.0 - else: fNoStretch = 1.0 - - return - - -# # Dictionaries # -loadedData = { +def initLoadedData(): + global loadedData + + loadedData = { 'NONE' : {}, 'Object' : {}, @@ -207,7 +155,16 @@ 'ObjectConstraints' : {}, 'ObjectModifiers' : {}, 'MaterialSlot' : {}, -} + } + return + +def reinitGlobalData(): + global loadedData + for key in [ + 'MeshTextureFaceLayer', 'MeshColorLayer', 'VertexGroup', 'ShapeKey', + 'ParticleSystem', 'ObjectConstraints', 'ObjectModifiers', 'MaterialSlot']: + loadedData[key] = {} + return Plural = { 'Object' : 'objects', @@ -262,6 +219,7 @@ defaultScale = theScale One = 1.0/theScale warnedVersion = False + initLoadedData() fileName = os.path.expanduser(filePath) (shortName, ext) = os.path.splitext(fileName) @@ -280,8 +238,6 @@ comment = 0 nesting = 0 - setFlagsAndFloats() - file= open(fileName, "rU") print( "Tokenizing" ) lineNo = 0 @@ -447,6 +403,7 @@ elif key == "Object": parseObject(val, sub) elif key == "Mesh": + reinitGlobalData() data = parseMesh(val, sub) elif key == "Armature": data = parseArmature(val, sub) @@ -1456,8 +1413,11 @@ return if (toggle & T_Armature) or (grpName in ['Eye_L', 'Eye_R', 'Gums', 'Head', 'Jaw', 'Left', 'Middle', 'Right', 'Scalp']): - group = ob.vertex_groups.new(grpName) - loadedData['VertexGroup'][grpName] = group + try: + group = loadedData['VertexGroup'][grpName] + except KeyError: + group = ob.vertex_groups.new(grpName) + loadedData['VertexGroup'][grpName] = group for (key, val, sub) in tokens: if key == 'wv': group.add( [int(val[0])], float(val[1]), 'REPLACE' ) @@ -1497,7 +1457,7 @@ if invalid(args[2]): return - if lr == 'Sym' or toggle & T_Symm: + if lr == 'Sym': # or toggle & T_Symm: addShapeKey(ob, name, None, tokens) elif lr == 'LR': addShapeKey(ob, name+'_L', 'Left', tokens) @@ -2065,10 +2025,18 @@ bpy.ops.mesh.select_all(action='DESELECT') bpy.ops.object.mode_set(mode='OBJECT') me = ob.data - for f in me.faces: - if f.material_index == 1: - for vn in f.vertices: - me.vertices[vn].select = True + invisioNum = -1 + for mn,mat in enumerate(me.materials): + if "Invis" in mat.name: + invisioNum = mn + break + if invisioNum < 0: + print("WARNING: Nu Invisio material found. Cannot delete helper geometry") + else: + for f in me.faces: + if f.material_index >= invisioNum: + for vn in f.vertices: + me.vertices[vn].select = True bpy.ops.object.mode_set(mode='EDIT') bpy.ops.mesh.delete(type='VERT') bpy.ops.object.mode_set(mode='OBJECT') @@ -2332,6 +2300,7 @@ scn = bpy.context.scene for n in range(len(scn.layers)): scn.layers[n] = True + return scn print("clearScene %s %s" % (toggle & T_Replace, scn)) if not toggle & T_Replace: return scn @@ -2846,13 +2815,13 @@ ("mesh", "Mesh", "Use main mesh", T_Mesh), ("proxy", "Proxies", "Use proxies", T_Proxy), ("armature", "Armature", "Use armature", T_Armature), - ("replace", "Replace scene", "Replace scene", T_Replace), + #("replace", "Replace scene", "Replace scene", T_Replace), ("cage", "Cage", "Load mesh deform cage", T_Cage), ("clothes", "Clothes", "Include clothes", T_Clothes), - ("stretch", "Stretchy limbs", "Stretchy limbs", T_Stretch), + #("stretch", "Stretchy limbs", "Stretchy limbs", T_Stretch), ("face", "Face shapes", "Include facial shapekeys", T_Face), ("shape", "Body shapes", "Include body shapekeys", T_Shape), - ("symm", "Symmetric shapes", "Keep shapekeys symmetric", T_Symm), + #("symm", "Symmetric shapes", "Keep shapekeys symmetric", T_Symm), ("diamond", "Helper geometry", "Keep helper geometry", T_Diamond), ("rigify", "Rigify", "Create rigify control rig", T_Rigify), ] @@ -3117,6 +3086,100 @@ ] # +# makeVisemes(ob, scn): +# class VIEW3D_OT_MhxMakeVisemesButton(bpy.types.Operator): +# + +def makeVisemes(ob, scn): + if ob.type != 'MESH': + print("Active object %s is not a mesh" % ob) + return + if not ob.data.shape_keys: + print("%s has no shapekeys" % ob) + return + adata = ob.data.shape_keys.animation_data + if not adata: + print("Shapekeys have not drivers") + return + try: + ob.data.shape_keys.key_blocks["VIS_Rest"] + print("Visemes already created") + return + except: + pass + rig = ob.parent + scale = rig.data.bones['PFace'].length*0.2 + + boneShapes = {} + for fcu in adata.drivers: + name = fcu.data_path.split('"')[1] + for var in fcu.driver.variables: + if var.type == 'TRANSFORMS': + targ = var.targets[0] + fmod = fcu.modifiers[0] + try: + list = boneShapes[targ.bone_target] + except: + list = [] + boneShapes[targ.bone_target] = list + list.append((targ.transform_type, fmod, ob.data.shape_keys.key_blocks[name])) + + verts = ob.data.vertices + for (vis,bones) in bodyLanguageVisemes.items(): + if vis in ['Blink', 'Unblink']: + continue + vkey = ob.shape_key_add(name="VIS_%s" % vis) + print(vkey.name) + for n,v in enumerate(verts): + vkey.data[n].co = v.co + for (bone, xz) in bones: + try: + boneShapes[bone] + single = True + except: + single = False + if single: + addToVisShapeKey(boneShapes[bone], vkey, verts, xz, 1, scale) + else: + try: + boneShapes[bone+"_L"] + double = True + except: + double = False + if double: + addToVisShapeKey(boneShapes[bone+"_L"], vkey, verts, xz, 1, scale) + #addToVisShapeKey(boneShapes[bone+"_R"], vkey, verts, xz, -1, scale) + print("Visemes made") + return + +def addToVisShapeKey(shapes, vkey, verts, xz, sign, scale): + for (typ, fmod, skey) in shapes: + factor = fmod.coefficients[1]*scale + (x,z) = xz + if typ == 'LOC_X': + k = factor*sign*x + elif typ == 'LOC_Z': + k = factor*z + if k < skey.slider_min: + k = skey.slider_min + if k > skey.slider_max: + k = skey.slider_max + if abs(k) < 0.001: + continue + print(" %s %.3f %.3f %.3f %.3f" % (skey.name, factor, x, z, k)) + for n,v in enumerate(verts): + vkey.data[n].co += k*(skey.data[n].co - v.co) + return + +class VIEW3D_OT_MhxMakeVisemesButton(bpy.types.Operator): + bl_idname = "mhx.make_visemes" + bl_label = "Generate viseme shapekeys" + + def execute(self, context): + makeVisemes(context.object, context.scene) + return{'FINISHED'} + +# # mohoVisemes # magpieVisemes # @@ -3302,6 +3365,7 @@ bl_label = "MHX Lipsync" bl_space_type = "VIEW_3D" bl_region_type = "UI" + bl_options = {'DEFAULT_CLOSED'} @classmethod def poll(cls, context): @@ -3328,6 +3392,8 @@ row.operator("mhx.pose_load_moho") row.operator("mhx.pose_load_magpie") layout.operator("mhx.update") + layout.separator() + layout.operator("mhx.make_visemes") return # @@ -3439,6 +3505,7 @@ bl_label = "MHX Expressions" bl_space_type = "VIEW_3D" bl_region_type = "UI" + bl_options = {'DEFAULT_CLOSED'} @classmethod def poll(cls, context): @@ -3476,6 +3543,7 @@ bl_label = "MHX Drivers" bl_space_type = "VIEW_3D" bl_region_type = "UI" + bl_options = {'DEFAULT_CLOSED'} @classmethod def poll(cls, context): @@ -3523,6 +3591,7 @@ bl_label = "MHX Visibility" bl_space_type = "VIEW_3D" bl_region_type = "UI" + bl_options = {'DEFAULT_CLOSED'} @classmethod def poll(cls, context): @@ -3551,7 +3620,7 @@ (( 1, 'FK Spine', 'MhxFKSpine'), (17, 'IK Spine', 'MhxIKSpine')), ((13, 'Inv FK Spine', 'MhxInvFKSpine'), - (29, 'Inv IK Spine', 'MhxInvIKSpine')), + (16, 'Clothes', 'MhxClothes')), ('Left', 'Right'), (( 2, 'IK Arm', 'MhxIKArm'), (18, 'IK Arm', 'MhxIKArm')), @@ -3579,6 +3648,7 @@ bl_label = "MHX Layers" bl_space_type = "VIEW_3D" bl_region_type = "UI" + bl_options = {'DEFAULT_CLOSED'} @classmethod def poll(cls, context): diff -Nru blender-2.61/release/scripts/addons/io_import_scene_unreal_psk.py blender-2.62/release/scripts/addons/io_import_scene_unreal_psk.py --- blender-2.61/release/scripts/addons/io_import_scene_unreal_psk.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_import_scene_unreal_psk.py 2012-02-15 19:43:32.000000000 +0000 @@ -21,7 +21,6 @@ "author": "Darknet", "version": (2, 0), "blender": (2, 5, 9), - "api": 41077, "location": "File > Import > Skeleton Mesh (.psk)", "description": "Import Skeleleton Mesh", "warning": "", @@ -446,9 +445,9 @@ newbone.head.y = parentbone.head.y + pos_y newbone.head.z = parentbone.head.z + pos_z #print("head:",newbone.head) - newbone.tail.x = parentbone.head.x + (pos_x + bonesize * rotmatrix[1][0]) + newbone.tail.x = parentbone.head.x + (pos_x + bonesize * rotmatrix[0][1]) newbone.tail.y = parentbone.head.y + (pos_y + bonesize * rotmatrix[1][1]) - newbone.tail.z = parentbone.head.z + (pos_z + bonesize * rotmatrix[1][2]) + newbone.tail.z = parentbone.head.z + (pos_z + bonesize * rotmatrix[2][1]) #newbone.roll = fixRoll(newbone) else: #print("rotmatrix:",dir(bone.bindmat.to_matrix().resize_4x4())) @@ -458,9 +457,9 @@ newbone.head.x = bone.bindpos[0] newbone.head.y = bone.bindpos[1] newbone.head.z = bone.bindpos[2] - newbone.tail.x = bone.bindpos[0] + bonesize * rotmatrix[1][0] + newbone.tail.x = bone.bindpos[0] + bonesize * rotmatrix[0][1] newbone.tail.y = bone.bindpos[1] + bonesize * rotmatrix[1][1] - newbone.tail.z = bone.bindpos[2] + bonesize * rotmatrix[1][2] + newbone.tail.z = bone.bindpos[2] + bonesize * rotmatrix[2][1] #newbone.roll = fixRoll(newbone) #print("no parent") diff -Nru blender-2.61/release/scripts/addons/io_mesh_pdb/import_pdb.py blender-2.62/release/scripts/addons/io_mesh_pdb/import_pdb.py --- blender-2.61/release/scripts/addons/io_mesh_pdb/import_pdb.py 2011-12-13 19:58:36.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_mesh_pdb/import_pdb.py 2012-02-15 19:42:55.000000000 +0000 @@ -25,7 +25,7 @@ # # Start of project : 2011-08-31 by Clemens Barth # First publication in Blender : 2011-11-11 -# Last modified : 2011-12-01 +# Last modified : 2012-02-07 # # Acknowledgements: Thanks to ideasman, meta_androcto, truman, kilon, # dairin0d, PKHG, Valter, etc @@ -35,8 +35,10 @@ import io import math import os +import copy from math import pi, cos, sin from mathutils import Vector, Matrix +from copy import copy # These are variables, which contain the name of the PDB file and # the path of the PDB file. @@ -207,10 +209,12 @@ # This is the class, which stores the two atoms of one stick. class CLASS_atom_pdb_stick(object): - __slots__ = ('atom1', 'atom2') - def __init__(self, atom1, atom2): + __slots__ = ('atom1', 'atom2', 'number', 'dist') + def __init__(self, atom1, atom2, number, dist): self.atom1 = atom1 self.atom2 = atom2 + self.number = number + self.dist = dist # ----------------------------------------------------------------------------- @@ -284,8 +288,7 @@ return str(dv.length) -# Routine to modify the radii via the type: -# pre-defined, atomic or van der Waals +# Routine to modify the radii via the type: predefined, atomic or van der Waals # Explanations here are also valid for the next 3 DEFs. def DEF_atom_pdb_radius_type(rtype,how): @@ -351,22 +354,26 @@ if len(obj.children) != 0: if obj.children[0].type == "SURFACE" or obj.children[0].type == "MESH": if atomname in obj.name: - obj.children[0].scale = (radius_pm/100,) * 3 + if "Stick" not in obj.name: + obj.children[0].scale = (radius_pm/100,) * 3 else: if obj.type == "SURFACE" or obj.type == "MESH": if atomname in obj.name: - obj.scale = (radius_pm/100,) * 3 + if "Stick" not in obj.name: + obj.scale = (radius_pm/100,) * 3 if how == "ALL_ACTIVE": for obj in bpy.context.selected_objects: if len(obj.children) != 0: if obj.children[0].type == "SURFACE" or obj.children[0].type == "MESH": if atomname in obj.name: - obj.children[0].scale = (radius_pm/100,) * 3 + if "Stick" not in obj.name: + obj.children[0].scale = (radius_pm/100,) * 3 else: if obj.type == "SURFACE" or obj.type == "MESH": if atomname in obj.name: - obj.scale = (radius_pm/100,) * 3 + if "Stick" not in obj.name: + obj.scale = (radius_pm/100,) * 3 # Routine to scale the radii of all atoms @@ -408,7 +415,90 @@ obj.scale *= scale -# This reads a custom data file. +# This routine downscales all atom radii onto the value of the stick radius +# for showing the sticks. +def DEF_atom_pdb_radius_sticks(radius, how): + + # Are there any sticks? + Found = False + if how == "ALL_IN_LAYER": + + layers = [] + for i in range(20): + if bpy.context.scene.layers[i] == True: + layers.append(i) + + change_objects = [] + for obj in bpy.context.scene.objects: + for layer in layers: + if obj.layers[layer] == True: + change_objects.append(obj) + + for obj in change_objects: + if len(obj.children) != 0: + if obj.children[0].type == "SURFACE" or obj.children[0].type == "MESH": + if "Stick" in obj.name: + Found = True + else: + if obj.type == "SURFACE" or obj.type == "MESH": + if "Stick" in obj.name: + Found = True + + if how == "ALL_ACTIVE": + for obj in bpy.context.selected_objects: + if len(obj.children) != 0: + if obj.children[0].type == "SURFACE" or obj.children[0].type == "MESH": + if "Stick" in obj.name: + Found = True + else: + if obj.type == "SURFACE" or obj.type == "MESH": + if "Stick" in obj.name: + Found = True + + if Found == False: + return False + + if how == "ALL_IN_LAYER": + + layers = [] + for i in range(20): + if bpy.context.scene.layers[i] == True: + layers.append(i) + + change_objects = [] + for obj in bpy.context.scene.objects: + for layer in layers: + if obj.layers[layer] == True: + change_objects.append(obj) + + + for obj in change_objects: + if len(obj.children) != 0: + if obj.children[0].type == "SURFACE" or obj.children[0].type == "MESH": + if "Stick" not in obj.name: + obj.children[0].scale = (radius,) * 3 + else: + if obj.type == "SURFACE" or obj.type == "MESH": + if "Stick" not in obj.name: + obj.scale = (radius,) * 3 + + if how == "ALL_ACTIVE": + for obj in bpy.context.selected_objects: + if len(obj.children) != 0: + if obj.children[0].type == "SURFACE" or obj.children[0].type == "MESH": + if "Stick" not in obj.name: + obj.children[0].scale = (radius,) * 3 + else: + if obj.type == "SURFACE" or obj.type == "MESH": + if "Stick" not in obj.name: + obj.scale = (radius,) * 3 + + return True + + +# ----------------------------------------------------------------------------- +# The custom data file + def DEF_atom_pdb_custom_datafile(path_datafile): if path_datafile == "": @@ -476,7 +566,9 @@ def DEF_atom_pdb_main(use_mesh,Ball_azimuth,Ball_zenith, Ball_radius_factor,radiustype,Ball_distance_factor, - use_stick,Stick_sectors,Stick_diameter,put_to_center, + use_sticks,use_sticks_color,use_sticks_smooth, + use_sticks_bonds,Stick_dist, + Stick_sectors,Stick_diameter,put_to_center, use_camera,use_lamp,path_datafile): # The list of all atoms as read from the PDB file. @@ -557,17 +649,39 @@ elif "ATOM" in line or "HETATM" in line: # What follows is due to deviations which appear from PDB to - # PDB file. It is very special. PLEASE, DO NOT CHANGE! From here ... - short_name = line[13:14] - if short_name.isupper() == True: + # PDB file. It is very special! + # + # PLEASE, DO NOT CHANGE! ............................... from here + if line[12:13] == " " or line[12:13].isdigit() == True: + short_name = line[13:14] if line[14:15].islower() == True: - short_name = short_name + line[14:15] - else: + short_name = short_name + line[14:15] + elif line[12:13].isupper() == True: short_name = line[12:13] - if short_name.isupper() == True: - if line[13:14].islower() == True: - short_name = short_name + line[13:14] - # ... to here. + if line[13:14].isalpha() == True: + short_name = short_name + line[13:14] + else: + print("Atomic Blender: Strange error in PDB file.\n" + "Look for element names at positions 13-16 and 78-79.\n") + return -1 + + if len(line) >= 78: + + if line[76:77] == " ": + short_name2 = line[76:77] + else: + short_name2 = line[76:78] + + if short_name2.isalpha() == True: + FOUND = False + for element in ATOM_PDB_ELEMENTS: + if str.upper(short_name2) == str.upper(element.short_name): + FOUND = True + break + if FOUND == False: + short_name = short_name2 + # ....................................................... to here. + # Go through all elements and find the element of the current atom. FLAG_FOUND = False @@ -743,10 +857,34 @@ atom1 = atom_list[0] # For all the other atoms in the list do: - for each_atom in atom_list[1:]: - - # The second, third, ... partner atom - atom2 = each_atom + for atom2 in atom_list[1:]: + + if use_sticks_bonds == True: + number = atom_list[1:].count(atom2) + if number == 2 or number == 3: + basis_list = list(set(atom_list[1:])) + + if len(basis_list) > 1: + basis1 = (all_atoms[atom1-1].location + - all_atoms[basis_list[0]-1].location) + basis2 = (all_atoms[atom1-1].location + - all_atoms[basis_list[1]-1].location) + plane_n = basis1.cross(basis2) + + dist_n = (all_atoms[atom1-1].location + - all_atoms[atom2-1].location) + dist_n = dist_n.cross(plane_n) + dist_n = dist_n / dist_n.length + else: + dist_n = Vector((0,0,0)) + elif number > 3: + number = 1 + dist_n = None + else: + dist_n = None + else: + number = 1 + dist_n = None # Note that in a PDB file, sticks of one atom pair can appear a # couple of times. (Only god knows why ...) @@ -763,7 +901,7 @@ # If the stick is not yet registered (FLAG_BAR == False), then # register it! if FLAG_BAR == False: - all_sticks.append(CLASS_atom_pdb_stick(atom1,atom2)) + all_sticks.append(CLASS_atom_pdb_stick(atom1,atom2,number,dist_n)) Number_of_sticks += 1 j += 1 @@ -1046,69 +1184,154 @@ # ------------------------------------------------------------------------ # DRAWING THE STICKS - - if use_stick == True and all_sticks != []: - - # Create a new material with the corresponding color. The - # color is taken from the all_atom list, it is the last entry - # in the data file (index -1). - bpy.ops.object.material_slot_add() - stick_material = bpy.data.materials.new(ATOM_PDB_ELEMENTS[-1].name) - stick_material.diffuse_color = ATOM_PDB_ELEMENTS[-1].color - - vertices = [] - faces = [] - dl = 0.2 - - i = 0 - # For all sticks, do ... - for stick in all_sticks: - + if use_sticks == True and all_sticks != []: + + dl = 0.05 + + if use_sticks_color == False: + bpy.ops.object.material_slot_add() + stick_material = bpy.data.materials.new(ATOM_PDB_ELEMENTS[-1].name) + stick_material.diffuse_color = ATOM_PDB_ELEMENTS[-1].color + + # Sort the sticks and put them into a new list such that ... + sticks_all_lists = [] + if use_sticks_color == True: + for atom_type in atom_all_types_list: + if atom_type[0] == "TER": + continue + sticks_list = [] + for stick in all_sticks: + + for repeat in range(stick.number): + + atom1 = copy(all_atoms[stick.atom1-1].location) + atom2 = copy(all_atoms[stick.atom2-1].location) + + dist = Stick_diameter * Stick_dist + + if stick.number == 2: + if repeat == 0: + atom1 += (stick.dist * dist) + atom2 += (stick.dist * dist) + if repeat == 1: + atom1 -= (stick.dist * dist) + atom2 -= (stick.dist * dist) + + if stick.number == 3: + if repeat == 0: + atom1 += (stick.dist * dist) + atom2 += (stick.dist * dist) + if repeat == 2: + atom1 -= (stick.dist * dist) + atom2 -= (stick.dist * dist) + + dv = atom1 - atom2 + n = dv / dv.length + if atom_type[0] == all_atoms[stick.atom1-1].name: + location = atom1 + name = "_" + all_atoms[stick.atom1-1].name + material = all_atoms[stick.atom1-1].material + sticks_list.append([name, location, dv, material]) + if atom_type[0] == all_atoms[stick.atom2-1].name: + location = atom1 - n * dl * int(math.ceil(dv.length / (2.0 * dl))) + name = "_" + all_atoms[stick.atom2-1].name + material = all_atoms[stick.atom2-1].material + sticks_list.append([name, location, dv, material]) + + if sticks_list != []: + sticks_all_lists.append(sticks_list) + else: + sticks_list = [] + for stick in all_sticks: + + if stick.number > 3: + stick.number = 1 + + for repeat in range(stick.number): + + atom1 = copy(all_atoms[stick.atom1-1].location) + atom2 = copy(all_atoms[stick.atom2-1].location) + + dist = Stick_diameter * Stick_dist + + if stick.number == 2: + if repeat == 0: + atom1 += (stick.dist * dist) + atom2 += (stick.dist * dist) + if repeat == 1: + atom1 -= (stick.dist * dist) + atom2 -= (stick.dist * dist) + if stick.number == 3: + if repeat == 0: + atom1 += (stick.dist * dist) + atom2 += (stick.dist * dist) + if repeat == 2: + atom1 -= (stick.dist * dist) + atom2 -= (stick.dist * dist) + + dv = atom1 - atom2 + n = dv / dv.length + location = atom1 + material = stick_material + sticks_list.append(["", location, dv, material]) + + sticks_all_lists.append(sticks_list) + + + # ... the sticks in the list can be drawn: + for stick_list in sticks_all_lists: + vertices = [] + faces = [] + i = 0 + # What follows is school mathematics! :-) - v1 = all_atoms[stick.atom2-1].location - v2 = all_atoms[stick.atom1-1].location - - dv = (v1 - v2) - - n = dv / dv.length - # m = v1 - dv / 2.0 # UNUSED - - gamma = -n * v1 - b = v1 + gamma * n - n_b = b / b.length - - loops = int(dv.length / dl) - - for j in range(loops): - - g = v1 - n * dl / 2.0 - n * dl * j - - p1 = g + n_b * Stick_diameter - p2 = g - n_b * Stick_diameter - p3 = g - n_b.cross(n) * Stick_diameter - p4 = g + n_b.cross(n) * Stick_diameter - - vertices.append(p1) - vertices.append(p2) - vertices.append(p3) - vertices.append(p4) - faces.append((i*4+0,i*4+2,i*4+1,i*4+3)) - i += 1 - - mesh = bpy.data.meshes.new("Sticks") - mesh.from_pydata(vertices, [], faces) - mesh.update() - new_mesh = bpy.data.objects.new("Sticks", mesh) - bpy.context.scene.objects.link(new_mesh) - - current_layers = bpy.context.scene.layers - stick_cylinder = DEF_atom_pdb_build_stick(Stick_diameter, dl, Stick_sectors) - + for stick in stick_list: + + dv = stick[2] + v1 = stick[1] + n = dv / dv.length + gamma = -n * v1 + b = v1 + gamma * n + n_b = b / b.length + + if use_sticks_color == True: + loops = int(math.ceil(dv.length / (2.0 * dl))) + else: + loops = int(math.ceil(dv.length / dl)) + + for j in range(loops): + + g = v1 - n * dl / 2.0 - n * dl * j + p1 = g + n_b * Stick_diameter + p2 = g - n_b * Stick_diameter + p3 = g - n_b.cross(n) * Stick_diameter + p4 = g + n_b.cross(n) * Stick_diameter + + vertices.append(p1) + vertices.append(p2) + vertices.append(p3) + vertices.append(p4) + faces.append((i*4+0,i*4+2,i*4+1,i*4+3)) + i += 1 + + mesh = bpy.data.meshes.new("Sticks"+stick[0]) + mesh.from_pydata(vertices, [], faces) + mesh.update() + new_mesh = bpy.data.objects.new("Sticks"+stick[0], mesh) + bpy.context.scene.objects.link(new_mesh) + + current_layers = bpy.context.scene.layers + stick_cylinder = DEF_atom_pdb_build_stick(Stick_diameter, dl, Stick_sectors) + stick_cylinder.active_material = stick[3] + + if use_sticks_smooth == True: + for face in stick_cylinder.data.faces: + face.use_smooth = True + + stick_cylinder.parent = new_mesh + new_mesh.dupli_type = 'FACES' + atom_object_list.append(new_mesh) - stick_cylinder.active_material = stick_material - stick_cylinder.parent = new_mesh - new_mesh.dupli_type = 'FACES' - atom_object_list.append(new_mesh) # ------------------------------------------------------------------------ diff -Nru blender-2.61/release/scripts/addons/io_mesh_pdb/__init__.py blender-2.62/release/scripts/addons/io_mesh_pdb/__init__.py --- blender-2.61/release/scripts/addons/io_mesh_pdb/__init__.py 2011-12-13 19:58:36.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_mesh_pdb/__init__.py 2012-02-15 19:42:55.000000000 +0000 @@ -20,18 +20,16 @@ "name": "PDB Atomic Blender", "description": "Loading and manipulating atoms from PDB files", "author": "Clemens Barth", - "version": (1,0), + "version": (1,2), "blender": (2,6), - "api": 31236, "location": "File -> Import -> PDB (.pdb), Panel: View 3D - Tools", "warning": "", - "wiki_url": "http://development.root-1.de/Atomic_Blender.php", + "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Import-Export/PDB", "tracker_url": "http://projects.blender.org/tracker/" - "index.php?func=detail&aid=29226&group_id=153&atid=468", + "index.php?func=detail&aid=29226", "category": "Import-Export" } - import bpy from bpy.types import Operator, Panel from bpy_extras.io_utils import ImportHelper @@ -45,6 +43,8 @@ # TODO, allow reload from . import import_pdb +ATOM_PDB_ERROR = "" + # ----------------------------------------------------------------------------- # GUI @@ -57,24 +57,9 @@ #bl_context = "physics" # This could be also an option ... : bl_space_type = "VIEW_3D" + #bl_region_type = "TOOLS" bl_region_type = "TOOL_PROPS" - # This 'poll thing' has taken 3 hours of a hard search and understanding. - # I explain it in the following from my point of view: - # - # Before this class is entirely treaten (here: drawing the panel) the - # poll method is called first. Basically, some conditions are - # checked before other things in the class are done afterwards. If a - # condition is not valid, one returns 'False' such that nothing further - # is done. 'True' means: 'Go on' - # - # In the case here, it is verified if the ATOM_PDB_FILEPATH variable contains - # a name. If not - and this is the case directly after having started the - # script - the panel does not appear because 'False' is returned. However, - # as soon as a file has been chosen, the panel appears because - # ATOM_PDB_FILEPATH contains a name. - # - # Please, correct me if I'm wrong. @classmethod def poll(self, context): if import_pdb.ATOM_PDB_FILEPATH == "": @@ -87,85 +72,105 @@ scn = bpy.context.scene row = layout.row() + row.label(text="Outputs and custom data file") + + box = layout.box() + row = box.row() row.label(text="Custom data file") - row = layout.row() + row = box.row() col = row.column() col.prop(scn, "atom_pdb_datafile") col.operator("atom_pdb.datafile_apply") - row = layout.row() + row = box.row() col = row.column(align=True) col.prop(scn, "atom_pdb_PDB_file") - layout.separator() - row = layout.row() - col = row.column(align=True) + row.label(text="Reload structure") + + box = layout.box() + row = box.row() + col = row.column() col.prop(scn, "use_atom_pdb_mesh") + col = row.column() + col.label(text="Scaling factors") + row = box.row() + col = row.column(align=True) + col.active = scn.use_atom_pdb_mesh col.prop(scn, "atom_pdb_mesh_azimuth") col.prop(scn, "atom_pdb_mesh_zenith") - - col = row.column(align=True) - col.label(text="Scaling factors") col.prop(scn, "atom_pdb_scale_ballradius") col.prop(scn, "atom_pdb_scale_distances") - row = layout.row() - col = row.column() + row = box.row() + col = row.column() col.prop(scn, "use_atom_pdb_sticks") + row = box.row() + row.active = scn.use_atom_pdb_sticks col = row.column(align=True) col.prop(scn, "atom_pdb_sticks_sectors") col.prop(scn, "atom_pdb_sticks_radius") - - row = layout.row() + col = row.column(align=True) + col.prop(scn, "use_atom_pdb_sticks_color") + col.prop(scn, "use_atom_pdb_sticks_smooth") + col.prop(scn, "use_atom_pdb_sticks_bonds") + row = box.row() + row.active = scn.use_atom_pdb_sticks + col = row.column(align=True) + col = row.column(align=True) + col.active = scn.use_atom_pdb_sticks and scn.use_atom_pdb_sticks_bonds + col.prop(scn, "atom_pdb_sticks_dist") + row = box.row() row.prop(scn, "use_atom_pdb_center") - - row = layout.row() + row = box.row() col = row.column() col.prop(scn, "use_atom_pdb_cam") col.prop(scn, "use_atom_pdb_lamp") col = row.column() col.operator("atom_pdb.button_reload") - - # TODO, use lanel() instead col.prop(scn, "atom_pdb_number_atoms") - - layout.separator() - - row = layout.row() + row = box.row() row.operator("atom_pdb.button_distance") row.prop(scn, "atom_pdb_distance") - layout.separator() row = layout.row() + row.label(text="Modify atom radii") + + box = layout.box() + row = box.row() row.label(text="All changes concern:") - row = layout.row() + row = box.row() row.prop(scn, "atom_pdb_radius_how") - - row = layout.row() + row = box.row() row.label(text="1. Change type of radii") - row = layout.row() + row = box.row() row.prop(scn, "atom_pdb_radius_type") - - row = layout.row() + row = box.row() row.label(text="2. Change atom radii in pm") - row = layout.row() + row = box.row() row.prop(scn, "atom_pdb_radius_pm_name") - row = layout.row() + row = box.row() row.prop(scn, "atom_pdb_radius_pm") - - row = layout.row() + row = box.row() row.label(text="3. Change atom radii by scale") - row = layout.row() + row = box.row() col = row.column() col.prop(scn, "atom_pdb_radius_all") col = row.column(align=True) col.operator( "atom_pdb.radius_all_bigger" ) col.operator( "atom_pdb.radius_all_smaller" ) + row = box.row() + row.label(text="4. Show sticks only") + row = box.row() + col = row.column() + col.operator( "atom_pdb.radius_sticks" ) if bpy.context.mode == 'EDIT_MESH': - layout.separator() row = layout.row() + row.label(text="Separate atom") + box = layout.box() + row = box.row() row.operator( "atom_pdb.separate_atom" ) @@ -196,7 +201,7 @@ description = "Do you need a lamp?") scn.use_atom_pdb_mesh = BoolProperty( name = "Mesh balls", default=False, - description = "Do you want to use mesh balls instead of NURBS?") + description = "Use mesh balls instead of NURBS") scn.atom_pdb_mesh_azimuth = IntProperty( name = "Azimuth", default=32, min=0, description = "Number of sectors (azimuth)") @@ -211,17 +216,28 @@ description = "Scale factor for all distances") scn.use_atom_pdb_center = BoolProperty( name = "Object to origin", default=True, - description = "Shall the object first put into the global origin " - "before applying the offsets on the left?") + description = "Put the object into the global origin") scn.use_atom_pdb_sticks = BoolProperty( - name="Use sticks", default=False, - description="Do you want to display also the sticks?") + name="Use sticks", default=True, + description="Do you want to display the sticks?") scn.atom_pdb_sticks_sectors = IntProperty( name = "Sector", default=20, min=0, description="Number of sectors of a stick") scn.atom_pdb_sticks_radius = FloatProperty( name = "Radius", default=0.1, min=0.0, description ="Radius of a stick") + scn.use_atom_pdb_sticks_color = BoolProperty( + name="Color", default=True, + description="The sticks appear in the color of the atoms") + scn.use_atom_pdb_sticks_smooth = BoolProperty( + name="Smooth", default=False, + description="The sticks are round (sectors are not visible)") + scn.use_atom_pdb_sticks_bonds = BoolProperty( + name="Bonds", default=False, + description="Show double and tripple bonds") + scn.atom_pdb_sticks_dist = FloatProperty( + name="Distance", default = 1.1, min=1.0, max=3.0, + description="Distance between sticks measured in stick diameter") scn.atom_pdb_atomradius = EnumProperty( name="Type of radius", description="Choose type of atom radius", @@ -235,9 +251,8 @@ name = "", description="Path to your custom data file", maxlen = 256, default = "", subtype='FILE_PATH') scn.atom_pdb_PDB_file = StringProperty( - name = "Path to file", default="", + name = "PDB file", default="", description = "Path of the PDB file") - # TODO, remove this property, its used for display only! scn.atom_pdb_number_atoms = StringProperty(name="", default="Number", description = "This output shows " "the number of atoms which have been loaded") @@ -273,7 +288,7 @@ class CLASS_atom_pdb_datafile_apply(Operator): bl_idname = "atom_pdb.datafile_apply" bl_label = "Apply" - bl_description = "Use color and radii values stored in a custom file" + bl_description = "Use color and radii values stored in the custom file" def execute(self, context): scn = bpy.context.scene @@ -302,7 +317,7 @@ return {'FINISHED'} -# Button for measuring the distance of the active objects +# Button for separating single objects from a atom mesh class CLASS_atom_pdb_separate_atom(Operator): bl_idname = "atom_pdb.separate_atom" bl_label = "Separate atom" @@ -378,7 +393,7 @@ class CLASS_atom_pdb_distance_button(Operator): bl_idname = "atom_pdb.button_distance" bl_label = "Measure ..." - bl_description = "Measure the distance between two objects" + bl_description = "Measure the distance between two objects (only in Object Mode)" def execute(self, context): scn = bpy.context.scene @@ -427,7 +442,31 @@ return {'FINISHED'} -# The button for loading the atoms and creating the scene +# Button for showing the sticks only - the radii of the atoms downscaled onto +# 90% of the stick radius +class CLASS_atom_pdb_radius_sticks_button(Operator): + bl_idname = "atom_pdb.radius_sticks" + bl_label = "Show sticks" + bl_description = "Show only the sticks (atom radii = stick radii)" + + def execute(self, context): + global ATOM_PDB_ERROR + + scn = bpy.context.scene + + result = import_pdb.DEF_atom_pdb_radius_sticks( + scn.atom_pdb_sticks_radius * 0.9, + scn.atom_pdb_radius_how, + ) + + if result == False: + ATOM_PDB_ERROR = "No sticks => no changes" + bpy.ops.atom_pdb.error_dialog('INVOKE_DEFAULT') + + return {'FINISHED'} + + +# The button for reloading the atoms and creating the scene class CLASS_atom_pdb_load_button(Operator): bl_idname = "atom_pdb.button_reload" bl_label = "RELOAD" @@ -443,19 +482,23 @@ radiustype = scn.atom_pdb_atomradius center = scn.use_atom_pdb_center sticks = scn.use_atom_pdb_sticks + sticks_col = scn.use_atom_pdb_sticks_color + sticks_sm = scn.use_atom_pdb_sticks_smooth ssector = scn.atom_pdb_sticks_sectors sradius = scn.atom_pdb_sticks_radius + stick_bond = scn.use_atom_pdb_sticks_bonds + stick_dist = scn.atom_pdb_sticks_dist + cam = scn.use_atom_pdb_cam lamp = scn.use_atom_pdb_lamp mesh = scn.use_atom_pdb_mesh datafile = scn.atom_pdb_datafile - + # Execute main routine an other time ... from the panel atom_number = import_pdb.DEF_atom_pdb_main( - mesh, azimuth, zenith, bradius, - radiustype, bdistance, sticks, - ssector, sradius, center, cam, lamp, datafile, - ) + mesh, azimuth, zenith, bradius, radiustype, bdistance, + sticks, sticks_col, sticks_sm, stick_bond, + stick_dist, ssector, sradius, center, cam, lamp, datafile) scn.atom_pdb_number_atoms = str(atom_number) + " atoms" return {'FINISHED'} @@ -464,7 +507,7 @@ # This is the class for the file dialog. class ImportPDB(Operator, ImportHelper): bl_idname = "import_mesh.pdb" - bl_label = "Import Protein Data Bank (*.pdb)" + bl_label = "Import Protein Data Bank(*.pdb)" filename_ext = ".pdb" filter_glob = StringProperty(default="*.pdb", options={'HIDDEN'},) @@ -480,6 +523,7 @@ col = row.column() col.prop(scn, "use_atom_pdb_mesh") col = row.column(align=True) + col.active = scn.use_atom_pdb_mesh col.prop(scn, "atom_pdb_mesh_azimuth") col.prop(scn, "atom_pdb_mesh_zenith") @@ -492,9 +536,21 @@ row = layout.row() col = row.column() col.prop(scn, "use_atom_pdb_sticks") + row = layout.row() + row.active = scn.use_atom_pdb_sticks col = row.column(align=True) col.prop(scn, "atom_pdb_sticks_sectors") col.prop(scn, "atom_pdb_sticks_radius") + col = row.column(align=True) + col.prop(scn, "use_atom_pdb_sticks_color") + col.prop(scn, "use_atom_pdb_sticks_smooth") + col.prop(scn, "use_atom_pdb_sticks_bonds") + row = layout.row() + row.active = scn.use_atom_pdb_sticks + col = row.column(align=True) + col = row.column(align=True) + col.active = scn.use_atom_pdb_sticks and scn.use_atom_pdb_sticks_bonds + col.prop(scn, "atom_pdb_sticks_dist") row = layout.row() row.prop(scn, "use_atom_pdb_center") @@ -517,24 +573,44 @@ radiustype = scn.atom_pdb_atomradius center = scn.use_atom_pdb_center sticks = scn.use_atom_pdb_sticks + sticks_col = scn.use_atom_pdb_sticks_color + sticks_sm = scn.use_atom_pdb_sticks_smooth ssector = scn.atom_pdb_sticks_sectors sradius = scn.atom_pdb_sticks_radius + stick_bond = scn.use_atom_pdb_sticks_bonds + stick_dist = scn.atom_pdb_sticks_dist + cam = scn.use_atom_pdb_cam lamp = scn.use_atom_pdb_lamp mesh = scn.use_atom_pdb_mesh datafile = scn.atom_pdb_datafile - + # Execute main routine atom_number = import_pdb.DEF_atom_pdb_main( - mesh, azimuth, zenith, bradius, - radiustype, bdistance, sticks, - ssector, sradius, center, cam, lamp, datafile) + mesh, azimuth, zenith, bradius, radiustype, bdistance, + sticks, sticks_col, sticks_sm, stick_bond, + stick_dist, ssector, sradius, center, cam, lamp, datafile) scn.atom_pdb_number_atoms = str(atom_number) + " atoms" return {'FINISHED'} +class CLASS_atom_pdb_error_dialog(bpy.types.Operator): + bl_idname = "atom_pdb.error_dialog" + bl_label = "Attention !" + + def draw(self, context): + layout = self.layout + row = layout.row() + row.label(text=" "+ATOM_PDB_ERROR) + def execute(self, context): + print("Atomic Blender - Error: "+ATOM_PDB_ERROR+"\n") + return {'FINISHED'} + def invoke(self, context, event): + return context.window_manager.invoke_props_dialog(self) + + # The entry into the menu 'file -> import' def menu_func(self, context): self.layout.operator(ImportPDB.bl_idname, text="Protein Data Bank (.pdb)") diff -Nru blender-2.61/release/scripts/addons/io_mesh_ply/export_ply.py blender-2.62/release/scripts/addons/io_mesh_ply/export_ply.py --- blender-2.61/release/scripts/addons/io_mesh_ply/export_ply.py 2011-12-13 19:58:49.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_mesh_ply/export_ply.py 2012-02-15 19:43:18.000000000 +0000 @@ -18,9 +18,6 @@ # -# Copyright (C) 2004, 2005: Bruce Merry, bmerry@cs.uct.ac.za -# Contributors: Bruce Merry, Campbell Barton - """ This script exports Stanford PLY files from Blender. It supports normals, colours, and texture coordinates per face or per vertex. diff -Nru blender-2.61/release/scripts/addons/io_mesh_ply/__init__.py blender-2.62/release/scripts/addons/io_mesh_ply/__init__.py --- blender-2.61/release/scripts/addons/io_mesh_ply/__init__.py 2011-12-13 19:58:49.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_mesh_ply/__init__.py 2012-02-15 19:43:18.000000000 +0000 @@ -22,16 +22,18 @@ "name": "Stanford PLY format", "author": "Bruce Merry, Campbell Barton", "blender": (2, 5, 7), - "api": 35622, "location": "File > Import-Export", "description": "Import-Export PLY mesh data withs UV's and vertex colors", "warning": "", - "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\ - "Scripts/Import-Export/Stanford_PLY", + "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/" + "Scripts/Import-Export/Stanford_PLY", "tracker_url": "", "support": 'OFFICIAL', "category": "Import-Export"} +# Copyright (C) 2004, 2005: Bruce Merry, bmerry@cs.uct.ac.za +# Contributors: Bruce Merry, Campbell Barton + # To support reload properly, try to access a package var, # if it's there, reload everything if "bpy" in locals(): diff -Nru blender-2.61/release/scripts/addons/io_mesh_raw/export_raw.py blender-2.62/release/scripts/addons/io_mesh_raw/export_raw.py --- blender-2.61/release/scripts/addons/io_mesh_raw/export_raw.py 2011-12-13 19:59:01.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_mesh_raw/export_raw.py 2012-02-15 19:43:27.000000000 +0000 @@ -16,11 +16,9 @@ # # ##### END GPL LICENSE BLOCK ##### -# +# -__author__ = ["Aurel Wildfellner"] -__version__ = '0.2' -__bpydoc__ = """\ +""" This script exports a Mesh to a RAW triangle format file. The raw triangle format is very simple; it has no verts or faces lists. @@ -40,7 +38,7 @@ def faceToTriangles(face): triangles = [] - if (len(face) == 4): + if len(face) == 4: triangles.append([face[0], face[1], face[2]]) triangles.append([face[2], face[3], face[0]]) else: diff -Nru blender-2.61/release/scripts/addons/io_mesh_raw/import_raw.py blender-2.62/release/scripts/addons/io_mesh_raw/import_raw.py --- blender-2.61/release/scripts/addons/io_mesh_raw/import_raw.py 2011-12-13 19:59:01.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_mesh_raw/import_raw.py 2012-02-15 19:43:27.000000000 +0000 @@ -16,11 +16,9 @@ # # ##### END GPL LICENSE BLOCK ##### -# +# -__author__ = ["Anthony D'Agostino (Scorpius)", "Aurel Wildfellner"] -__version__ = '0.2' -__bpydoc__ = """\ +""" This script imports Raw Triangle File format files to Blender. The raw triangle format is very simple; it has no verts or faces lists. @@ -45,7 +43,7 @@ def readMesh(filename, objName): - file = open(filename, "rb") + filehandle = open(filename, "rb") def line_to_face(line): # Each triplet is an xyz float @@ -61,12 +59,12 @@ return None faces = [] - for line in file.readlines(): + for line in filehandle.readlines(): face = line_to_face(line) if face: faces.append(face) - file.close() + filehandle.close() # Generate verts and faces lists, without duplicates verts = [] diff -Nru blender-2.61/release/scripts/addons/io_mesh_raw/__init__.py blender-2.62/release/scripts/addons/io_mesh_raw/__init__.py --- blender-2.61/release/scripts/addons/io_mesh_raw/__init__.py 2011-12-13 19:59:01.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_mesh_raw/__init__.py 2012-02-15 19:43:27.000000000 +0000 @@ -16,7 +16,7 @@ # # ##### END GPL LICENSE BLOCK ##### -# +# bl_info = { @@ -24,14 +24,13 @@ "author": "Anthony D,Agostino (Scorpius), Aurel Wildfellner", "version": (0, 2), "blender": (2, 5, 7), - "api": 36103, "location": "File > Import-Export > Raw Faces (.raw) ", "description": "Import-Export Raw Faces", "warning": "", - "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\ - "Scripts/Import-Export/Raw_Mesh_IO", - "tracker_url": "https://projects.blender.org/tracker/index.php?"\ - "func=detail&aid=25692", + "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/" + "Scripts/Import-Export/Raw_Mesh_IO", + "tracker_url": "https://projects.blender.org/tracker/index.php?" + "func=detail&aid=25692", "category": "Import-Export"} if "bpy" in locals(): diff -Nru blender-2.61/release/scripts/addons/io_mesh_stl/__init__.py blender-2.62/release/scripts/addons/io_mesh_stl/__init__.py --- blender-2.61/release/scripts/addons/io_mesh_stl/__init__.py 2011-12-13 19:58:06.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_mesh_stl/__init__.py 2012-02-15 19:42:36.000000000 +0000 @@ -23,7 +23,6 @@ "author": "Guillaume Bouchard (Guillaum)", "version": (1, 0), "blender": (2, 5, 7), - "api": 35622, "location": "File > Import-Export > Stl", "description": "Import-Export STL files", "warning": "", diff -Nru blender-2.61/release/scripts/addons/io_mesh_uv_layout/export_uv_eps.py blender-2.62/release/scripts/addons/io_mesh_uv_layout/export_uv_eps.py --- blender-2.61/release/scripts/addons/io_mesh_uv_layout/export_uv_eps.py 2011-12-13 19:59:00.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_mesh_uv_layout/export_uv_eps.py 2012-02-15 19:43:26.000000000 +0000 @@ -16,7 +16,7 @@ # # ##### END GPL LICENSE BLOCK ##### -# +# import bpy @@ -27,7 +27,8 @@ fw("%%Pages: 1\n") fw("%%Orientation: Portrait\n") fw("%%%%BoundingBox: 0 0 %d %d\n" % (image_width, image_height)) - fw("%%%%HiResBoundingBox: 0.0 0.0 %.4f %.4f\n" % (image_width, image_height)) + fw("%%%%HiResBoundingBox: 0.0 0.0 %.4f %.4f\n" % + (image_width, image_height)) fw("%%EndComments\n") fw("%%Page: 1 1\n") fw("0 0 translate\n") @@ -45,7 +46,8 @@ fw("/DRAW_%d {" % i) fw("gsave\n") if mat: - color = tuple((1.0 - ((1.0 - c) * opacity)) for c in mat.diffuse_color) + color = tuple((1.0 - ((1.0 - c) * opacity)) + for c in mat.diffuse_color) else: color = 1.0, 1.0, 1.0 fw("%.3g %.3g %.3g setrgbcolor\n" % color) diff -Nru blender-2.61/release/scripts/addons/io_mesh_uv_layout/export_uv_png.py blender-2.62/release/scripts/addons/io_mesh_uv_layout/export_uv_png.py --- blender-2.61/release/scripts/addons/io_mesh_uv_layout/export_uv_png.py 2011-12-13 19:59:00.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_mesh_uv_layout/export_uv_png.py 2012-02-15 19:43:26.000000000 +0000 @@ -16,7 +16,7 @@ # # ##### END GPL LICENSE BLOCK ##### -# +# import bpy @@ -25,7 +25,9 @@ filepath = fw.__self__.name fw.__self__.close() - material_solids = [bpy.data.materials.new("uv_temp_solid") for i in range(max(1, len(mesh_source.materials)))] + material_solids = [bpy.data.materials.new("uv_temp_solid") + for i in range(max(1, len(mesh_source.materials)))] + material_wire = bpy.data.materials.new("uv_temp_wire") scene = bpy.data.scenes.new("uv_temp") @@ -39,15 +41,21 @@ faces_source = mesh_source.faces - # get unique UV's in case there are many overlapping which slow down filling. + # get unique UV's in case there are many overlapping + # which slow down filling. face_hash_3 = set() face_hash_4 = set() for i, uv in face_iter_func(): material_index = faces_source[i].material_index if len(uv) == 3: - face_hash_3.add((uv[0][0], uv[0][1], uv[1][0], uv[1][1], uv[2][0], uv[2][1], material_index)) + face_hash_3.add((uv[0][0], uv[0][1], + uv[1][0], uv[1][1], + uv[2][0], uv[2][1], material_index)) else: - face_hash_4.add((uv[0][0], uv[0][1], uv[1][0], uv[1][1], uv[2][0], uv[2][1], uv[3][0], uv[3][1], material_index)) + face_hash_4.add((uv[0][0], uv[0][1], + uv[1][0], uv[1][1], + uv[2][0], uv[2][1], + uv[3][0], uv[3][1], material_index)) # now set the faces coords and locations # build mesh data @@ -58,13 +66,20 @@ current_vert = 0 for face_data in face_hash_3: - mesh_new_vertices.extend([face_data[0], face_data[1], 0.0, face_data[2], face_data[3], 0.0, face_data[4], face_data[5], 0.0]) - mesh_new_face_vertices.extend([current_vert, current_vert + 1, current_vert + 2, 0]) + mesh_new_vertices.extend([face_data[0], face_data[1], 0.0, + face_data[2], face_data[3], 0.0, + face_data[4], face_data[5], 0.0]) + mesh_new_face_vertices.extend([current_vert, current_vert + 1, + current_vert + 2, 0]) mesh_new_materials.append(face_data[6]) current_vert += 3 for face_data in face_hash_4: - mesh_new_vertices.extend([face_data[0], face_data[1], 0.0, face_data[2], face_data[3], 0.0, face_data[4], face_data[5], 0.0, face_data[6], face_data[7], 0.0]) - mesh_new_face_vertices.extend([current_vert, current_vert + 1, current_vert + 2, current_vert + 3]) + mesh_new_vertices.extend([face_data[0], face_data[1], 0.0, + face_data[2], face_data[3], 0.0, + face_data[4], face_data[5], 0.0, + face_data[6], face_data[7], 0.0]) + mesh_new_face_vertices.extend([current_vert, current_vert + 1, + current_vert + 2, current_vert + 3]) mesh_new_materials.append(face_data[8]) current_vert += 4 diff -Nru blender-2.61/release/scripts/addons/io_mesh_uv_layout/export_uv_svg.py blender-2.62/release/scripts/addons/io_mesh_uv_layout/export_uv_svg.py --- blender-2.61/release/scripts/addons/io_mesh_uv_layout/export_uv_svg.py 2011-12-13 19:59:00.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_mesh_uv_layout/export_uv_svg.py 2012-02-15 19:43:26.000000000 +0000 @@ -16,7 +16,7 @@ # # ##### END GPL LICENSE BLOCK ##### -# +# import bpy @@ -29,9 +29,11 @@ fw('\n') fw('\n') - fw('\n') - desc = "%r, %s, (Blender %s)" % (basename(bpy.data.filepath), mesh.name, bpy.app.version_string) + desc = ("%r, %s, (Blender %s)" % + (basename(bpy.data.filepath), mesh.name, bpy.app.version_string)) fw('%s\n' % escape(desc)) # svg colors @@ -39,7 +41,9 @@ fill_default = 'fill="grey"' for mat in mesh.materials if mesh.materials else [None]: if mat: - fill_settings.append('fill="rgb(%d, %d, %d)"' % tuple(int(c * 255) for c in mat.diffuse_color)) + fill_settings.append('fill="rgb(%d, %d, %d)"' % + tuple(int(c * 255) + for c in mat.diffuse_color)) else: fill_settings.append(fill_default) diff -Nru blender-2.61/release/scripts/addons/io_mesh_uv_layout/__init__.py blender-2.62/release/scripts/addons/io_mesh_uv_layout/__init__.py --- blender-2.61/release/scripts/addons/io_mesh_uv_layout/__init__.py 2011-12-13 19:59:00.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_mesh_uv_layout/__init__.py 2012-02-15 19:43:26.000000000 +0000 @@ -23,7 +23,6 @@ "author": "Campbell Barton, Matt Ebb", "version": (1, 0), "blender": (2, 5, 8), - "api": 35622, "location": "Image-Window > UVs > Export UV Layout", "description": "Export the UV layout as a 2D graphic", "warning": "", @@ -76,6 +75,11 @@ description="Export all UVs in this mesh (not just visible ones)", default=False, ) + modified = BoolProperty( + name="Modified", + description="Exports UVs from the modified mesh", + default=False, + ) mode = EnumProperty( items=(('SVG', "Scalable Vector Graphic (.svg)", "Export the UV layout to a vector SVG file"), @@ -127,9 +131,7 @@ return image_width, image_height - def _face_uv_iter(self, context): - obj = context.active_object - mesh = obj.data + def _face_uv_iter(self, context, mesh): uv_layer = mesh.uv_textures.active.data uv_layer_len = len(uv_layer) @@ -167,8 +169,6 @@ if is_editmode: bpy.ops.object.mode_set(mode='OBJECT', toggle=False) - mesh = obj.data - mode = self.mode filepath = self.filepath @@ -186,8 +186,16 @@ from . import export_uv_svg func = export_uv_svg.write + if self.modified: + mesh = obj.to_mesh(context.scene, True, 'PREVIEW') + else: + mesh = obj.data + func(fw, mesh, self.size[0], self.size[1], self.opacity, - lambda: self._face_uv_iter(context)) + lambda: self._face_uv_iter(context, mesh)) + + if self.modified: + bpy.data.meshes.remove(mesh) if is_editmode: bpy.ops.object.mode_set(mode='EDIT', toggle=False) diff -Nru blender-2.61/release/scripts/addons/io_scene_3ds/export_3ds.py blender-2.62/release/scripts/addons/io_scene_3ds/export_3ds.py --- blender-2.61/release/scripts/addons/io_scene_3ds/export_3ds.py 2011-12-13 19:58:20.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_scene_3ds/export_3ds.py 2012-02-15 19:42:44.000000000 +0000 @@ -713,7 +713,7 @@ def make_matrix_4x3_chunk(matrix): matrix_chunk = _3ds_chunk(OBJECT_TRANS_MATRIX) - for vec in matrix: + for vec in matrix.col: for f in vec[:3]: matrix_chunk.add_variable("matrix_f", _3ds_float(f)) return matrix_chunk diff -Nru blender-2.61/release/scripts/addons/io_scene_3ds/import_3ds.py blender-2.62/release/scripts/addons/io_scene_3ds/import_3ds.py --- blender-2.61/release/scripts/addons/io_scene_3ds/import_3ds.py 2011-12-13 19:58:20.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_scene_3ds/import_3ds.py 2012-02-15 19:42:44.000000000 +0000 @@ -365,7 +365,7 @@ #print 'MAT_TEXTURE_MAP..while', new_chunk.bytes_read, new_chunk.length read_chunk(file, temp_chunk) - if (temp_chunk.ID == MAT_MAP_FILEPATH): + if temp_chunk.ID == MAT_MAP_FILEPATH: texture_name, read_str_len = read_string(file) img = TEXTURE_DICT[contextMaterial.name] = load_image(texture_name, dirname) new_chunk.bytes_read += read_str_len # plus one for the null character that gets removed @@ -389,8 +389,8 @@ read_chunk(file, new_chunk) #is it a Version chunk? - if (new_chunk.ID == VERSION): - #print 'if (new_chunk.ID == VERSION):' + if new_chunk.ID == VERSION: + #print 'if new_chunk.ID == VERSION:' #print 'found a VERSION chunk' #read in the version of the file #it's an unsigned short (H) @@ -398,12 +398,12 @@ version = struct.unpack(' 3): + if version > 3: print('\tNon-Fatal Error: Version greater than 3, may not load correctly: ', version) #is it an object info chunk? - elif (new_chunk.ID == OBJECTINFO): - #print 'elif (new_chunk.ID == OBJECTINFO):' + elif new_chunk.ID == OBJECTINFO: + #print 'elif new_chunk.ID == OBJECTINFO:' # print 'found an OBJECTINFO chunk' process_next_chunk(file, new_chunk, importedObjects, IMAGE_SEARCH) @@ -411,7 +411,7 @@ new_chunk.bytes_read += temp_chunk.bytes_read #is it an object chunk? - elif (new_chunk.ID == OBJECT): + elif new_chunk.ID == OBJECT: if CreateBlenderObject: putContextMesh(contextMesh_vertls, contextMesh_facels, contextMeshMaterials) @@ -431,15 +431,15 @@ new_chunk.bytes_read += read_str_len #is it a material chunk? - elif (new_chunk.ID == MATERIAL): + elif new_chunk.ID == MATERIAL: # print("read material") - #print 'elif (new_chunk.ID == MATERIAL):' + #print 'elif new_chunk.ID == MATERIAL:' contextMaterial = bpy.data.materials.new('Material') - elif (new_chunk.ID == MAT_NAME): - #print 'elif (new_chunk.ID == MAT_NAME):' + elif new_chunk.ID == MAT_NAME: + #print 'elif new_chunk.ID == MAT_NAME:' material_name, read_str_len = read_string(file) # print("material name", material_name) @@ -450,15 +450,15 @@ contextMaterial.name = material_name.rstrip() # remove trailing whitespace MATDICT[material_name] = contextMaterial - elif (new_chunk.ID == MAT_AMBIENT): - #print 'elif (new_chunk.ID == MAT_AMBIENT):' + elif new_chunk.ID == MAT_AMBIENT: + #print 'elif new_chunk.ID == MAT_AMBIENT:' read_chunk(file, temp_chunk) - if (temp_chunk.ID == MAT_FLOAT_COLOR): + if temp_chunk.ID == MAT_FLOAT_COLOR: contextMaterial.mirror_color = read_float_color(temp_chunk) # temp_data = file.read(struct.calcsize('3f')) # temp_chunk.bytes_read += 12 # contextMaterial.mirCol = [float(col) for col in struct.unpack('<3f', temp_data)] - elif (temp_chunk.ID == MAT_24BIT_COLOR): + elif temp_chunk.ID == MAT_24BIT_COLOR: contextMaterial.mirror_color = read_byte_color(temp_chunk) # temp_data = file.read(struct.calcsize('3B')) # temp_chunk.bytes_read += 3 @@ -467,15 +467,15 @@ skip_to_end(file, temp_chunk) new_chunk.bytes_read += temp_chunk.bytes_read - elif (new_chunk.ID == MAT_DIFFUSE): - #print 'elif (new_chunk.ID == MAT_DIFFUSE):' + elif new_chunk.ID == MAT_DIFFUSE: + #print 'elif new_chunk.ID == MAT_DIFFUSE:' read_chunk(file, temp_chunk) - if (temp_chunk.ID == MAT_FLOAT_COLOR): + if temp_chunk.ID == MAT_FLOAT_COLOR: contextMaterial.diffuse_color = read_float_color(temp_chunk) # temp_data = file.read(struct.calcsize('3f')) # temp_chunk.bytes_read += 12 # contextMaterial.rgbCol = [float(col) for col in struct.unpack('<3f', temp_data)] - elif (temp_chunk.ID == MAT_24BIT_COLOR): + elif temp_chunk.ID == MAT_24BIT_COLOR: contextMaterial.diffuse_color = read_byte_color(temp_chunk) # temp_data = file.read(struct.calcsize('3B')) # temp_chunk.bytes_read += 3 @@ -487,15 +487,15 @@ new_chunk.bytes_read += temp_chunk.bytes_read - elif (new_chunk.ID == MAT_SPECULAR): - #print 'elif (new_chunk.ID == MAT_SPECULAR):' + elif new_chunk.ID == MAT_SPECULAR: + #print 'elif new_chunk.ID == MAT_SPECULAR:' read_chunk(file, temp_chunk) - if (temp_chunk.ID == MAT_FLOAT_COLOR): + if temp_chunk.ID == MAT_FLOAT_COLOR: contextMaterial.specular_color = read_float_color(temp_chunk) # temp_data = file.read(struct.calcsize('3f')) # temp_chunk.bytes_read += 12 # contextMaterial.mirCol = [float(col) for col in struct.unpack('<3f', temp_data)] - elif (temp_chunk.ID == MAT_24BIT_COLOR): + elif temp_chunk.ID == MAT_24BIT_COLOR: contextMaterial.specular_color = read_byte_color(temp_chunk) # temp_data = file.read(struct.calcsize('3B')) # temp_chunk.bytes_read += 3 @@ -504,20 +504,20 @@ skip_to_end(file, temp_chunk) new_chunk.bytes_read += temp_chunk.bytes_read - elif (new_chunk.ID == MAT_TEXTURE_MAP): + elif new_chunk.ID == MAT_TEXTURE_MAP: read_texture(new_chunk, temp_chunk, "Diffuse", "COLOR") - elif (new_chunk.ID == MAT_SPECULAR_MAP): + elif new_chunk.ID == MAT_SPECULAR_MAP: read_texture(new_chunk, temp_chunk, "Specular", "SPECULARITY") - elif (new_chunk.ID == MAT_OPACITY_MAP): + elif new_chunk.ID == MAT_OPACITY_MAP: read_texture(new_chunk, temp_chunk, "Opacity", "ALPHA") - elif (new_chunk.ID == MAT_BUMP_MAP): + elif new_chunk.ID == MAT_BUMP_MAP: read_texture(new_chunk, temp_chunk, "Bump", "NORMAL") - elif (new_chunk.ID == MAT_TRANSPARENCY): - #print 'elif (new_chunk.ID == MAT_TRANSPARENCY):' + elif new_chunk.ID == MAT_TRANSPARENCY: + #print 'elif new_chunk.ID == MAT_TRANSPARENCY:' read_chunk(file, temp_chunk) temp_data = file.read(STRUCT_SIZE_UNSIGNED_SHORT) @@ -525,7 +525,7 @@ contextMaterial.alpha = 1 - (float(struct.unpack(' Import-Export", "description": "Import-Export 3DS, meshes, uvs, materials, textures, " "cameras & lamps", diff -Nru blender-2.61/release/scripts/addons/io_scene_fbx/export_fbx.py blender-2.62/release/scripts/addons/io_scene_fbx/export_fbx.py --- blender-2.61/release/scripts/addons/io_scene_fbx/export_fbx.py 2011-12-13 19:58:53.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_scene_fbx/export_fbx.py 2012-02-15 19:43:21.000000000 +0000 @@ -128,7 +128,12 @@ def mat4x4str(mat): - return '%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f' % tuple([f for v in mat for f in v]) + # blender matrix is row major, fbx is col major so transpose on write + return ("%.15f,%.15f,%.15f,%.15f," + "%.15f,%.15f,%.15f,%.15f," + "%.15f,%.15f,%.15f,%.15f," + "%.15f,%.15f,%.15f,%.15f" % + tuple([f for v in mat.transposed() for f in v])) def action_bone_names(obj, action): @@ -1000,7 +1005,7 @@ do_shadow = False else: do_light = not (light.use_only_shadow or (not light.use_diffuse and not light.use_specular)) - do_shadow = (light.shadow_method in ('RAY_SHADOW', 'BUFFER_SHADOW')) + do_shadow = (light.shadow_method in {'RAY_SHADOW', 'BUFFER_SHADOW'}) # scale = abs(global_matrix.to_scale()[0]) # scale is always uniform in this case # UNUSED diff -Nru blender-2.61/release/scripts/addons/io_scene_fbx/__init__.py blender-2.62/release/scripts/addons/io_scene_fbx/__init__.py --- blender-2.61/release/scripts/addons/io_scene_fbx/__init__.py 2011-12-13 19:58:53.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_scene_fbx/__init__.py 2012-02-15 19:43:21.000000000 +0000 @@ -22,7 +22,6 @@ "name": "Autodesk FBX format", "author": "Campbell Barton", "blender": (2, 5, 9), - "api": 38691, "location": "File > Import-Export", "description": "Export FBX meshes, UV's, vertex colors, materials, " "textures, cameras, lamps and actions", diff -Nru blender-2.61/release/scripts/addons/io_scene_m3/__init__.py blender-2.62/release/scripts/addons/io_scene_m3/__init__.py --- blender-2.61/release/scripts/addons/io_scene_m3/__init__.py 2011-12-13 19:58:14.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_scene_m3/__init__.py 2012-02-15 19:42:41.000000000 +0000 @@ -23,7 +23,6 @@ 'author': 'Cory Perry', 'version': (0, 2, 1), "blender": (2, 5, 7), - "api": 36079, 'location': 'File > Import > Blizzard M3 (.m3)', 'description': 'Imports the Blizzard M3 format (.m3)', 'warning': '', diff -Nru blender-2.61/release/scripts/addons/io_scene_map/__init__.py blender-2.62/release/scripts/addons/io_scene_map/__init__.py --- blender-2.61/release/scripts/addons/io_scene_map/__init__.py 2011-12-13 19:58:01.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_scene_map/__init__.py 2012-02-15 19:42:31.000000000 +0000 @@ -22,7 +22,6 @@ "name": "Quake MAP format", "author": "Campbell Barton", "blender": (2, 5, 7), - "api": 35622, "location": "File > Export", "description": "Export MAP brushes, nurbs surfaces, " "lamps and empties as map nodes", diff -Nru blender-2.61/release/scripts/addons/io_scene_obj/import_obj.py blender-2.62/release/scripts/addons/io_scene_obj/import_obj.py --- blender-2.61/release/scripts/addons/io_scene_obj/import_obj.py 2011-12-13 19:58:13.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_scene_obj/import_obj.py 2012-02-15 19:42:40.000000000 +0000 @@ -860,29 +860,32 @@ file = open(filepath, 'rb') for line in file: # .readlines(): - line = line.lstrip() # rare cases there is white space at the start of the line + line_split = line.split() - if line.startswith(b"v "): - line_split = line.split() + if not line_split: + continue + + line_start = line_split[0] # we compare with this a _lot_ + + if line_start == b'v': verts_loc.append((float_func(line_split[1]), float_func(line_split[2]), float_func(line_split[3]))) - elif line.startswith(b"vn "): + elif line_start == b'vn': pass - elif line.startswith(b"vt "): - line_split = line.split() + elif line_start == b'vt': verts_tex.append((float_func(line_split[1]), float_func(line_split[2]))) # Handel faces lines (as faces) and the second+ lines of fa multiline face here # use 'f' not 'f ' because some objs (very rare have 'fo ' for faces) - elif line.startswith(b'f') or context_multi_line == b'f': + elif line_start == b'f' or context_multi_line == b'f': if context_multi_line: # use face_vert_loc_indices and face_vert_tex_indices previously defined and used the obj_face - line_split = line.split() + pass else: - line_split = line[2:].split() + line_split = line_split[1:] face_vert_loc_indices = [] face_vert_tex_indices = [] @@ -930,15 +933,15 @@ if len(face_vert_loc_indices) > 4: has_ngons = True - elif use_edges and (line.startswith(b'l ') or context_multi_line == b'l'): + elif use_edges and (line_start == b'l' or context_multi_line == b'l'): # very similar to the face load function above with some parts removed if context_multi_line: # use face_vert_loc_indices and face_vert_tex_indices previously defined and used the obj_face - line_split = line.split() + pass else: - line_split = line[2:].split() + line_split = line_split[1:] face_vert_loc_indices = [] face_vert_tex_indices = [] @@ -955,7 +958,7 @@ else: context_multi_line = b'' - # isline = line.startswith(b'l') # UNUSED + # isline = line_start == b'l' # UNUSED for v in line_split: vert_loc_index = int(v) - 1 @@ -966,20 +969,20 @@ face_vert_loc_indices.append(vert_loc_index) - elif line.startswith(b's'): + elif line_start == b's': if use_smooth_groups: - context_smooth_group = line_value(line.split()) + context_smooth_group = line_value(line_split) if context_smooth_group == b'off': context_smooth_group = None elif context_smooth_group: # is not None unique_smooth_groups[context_smooth_group] = None - elif line.startswith(b'o'): + elif line_start == b'o': if use_split_objects: - context_object = line_value(line.split()) + context_object = line_value(line_split) # unique_obects[context_object]= None - elif line.startswith(b'g'): + elif line_start == b'g': if use_split_groups: context_object = line_value(line.split()) # print 'context_object', context_object @@ -991,18 +994,16 @@ else: context_vgroup = None # dont assign a vgroup - elif line.startswith(b'usemtl'): + elif line_start == b'usemtl': context_material = line_value(line.split()) unique_materials[context_material] = None - elif line.startswith(b'mtllib'): # usemap or usemat + elif line_start == b'mtllib': # usemap or usemat material_libs = list(set(material_libs) | set(line.split()[1:])) # can have multiple mtllib filenames per line, mtllib can appear more than once, so make sure only occurance of material exists # Nurbs support - elif line.startswith(b'cstype '): + elif line_start == b'cstype': context_nurbs[b'cstype'] = line_value(line.split()) # 'rat bspline' / 'bspline' - elif line.startswith(b'curv ') or context_multi_line == b'curv': - line_split = line.split() - + elif line_start == b'curv' or context_multi_line == b'curv': curv_idx = context_nurbs[b'curv_idx'] = context_nurbs.get(b'curv_idx', []) # in case were multiline if not context_multi_line: @@ -1022,9 +1023,7 @@ curv_idx.append(vert_loc_index) - elif line.startswith(b'parm') or context_multi_line == b'parm': - line_split = line.split() - + elif line_start == b'parm' or context_multi_line == b'parm': if context_multi_line: context_multi_line = b'' else: @@ -1042,9 +1041,9 @@ context_nurbs.setdefault(b'parm_v', []).extend([float_func(f) for f in line_split]) # else: # may want to support other parm's ? - elif line.startswith(b'deg '): + elif line_start == b'deg': context_nurbs[b'deg'] = [int(i) for i in line.split()[1:]] - elif line.startswith(b'end'): + elif line_start == b'end': # Add the nurbs curve if context_object: context_nurbs[b'name'] = context_object @@ -1053,8 +1052,8 @@ context_parm = b'' ''' # How to use usemap? depricated? - elif line.startswith(b'usema'): # usemap or usemat - context_image= line_value(line.split()) + elif line_start == b'usema': # usemap or usemat + context_image= line_value(line_split) ''' file.close() diff -Nru blender-2.61/release/scripts/addons/io_scene_obj/__init__.py blender-2.62/release/scripts/addons/io_scene_obj/__init__.py --- blender-2.61/release/scripts/addons/io_scene_obj/__init__.py 2011-12-13 19:58:13.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_scene_obj/__init__.py 2012-02-15 19:42:40.000000000 +0000 @@ -22,7 +22,6 @@ "name": "Wavefront OBJ format", "author": "Campbell Barton", "blender": (2, 5, 8), - "api": 35622, "location": "File > Import-Export", "description": "Import-Export OBJ, Import OBJ mesh, UV's, " "materials and textures", diff -Nru blender-2.61/release/scripts/addons/io_scene_x3d/export_x3d.py blender-2.62/release/scripts/addons/io_scene_x3d/export_x3d.py --- blender-2.61/release/scripts/addons/io_scene_x3d/export_x3d.py 2011-12-13 19:58:48.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_scene_x3d/export_x3d.py 2012-02-15 19:43:17.000000000 +0000 @@ -246,6 +246,7 @@ use_hierarchy=True, use_h3d=False, path_mode='AUTO', + name_decorations=True, ): # ------------------------------------------------------------------------- @@ -255,13 +256,49 @@ from bpy_extras.io_utils import unique_name from xml.sax.saxutils import quoteattr, escape - uuid_cache_object = {} # object - uuid_cache_lamp = {} # 'LA_' + object.name - uuid_cache_view = {} # object, different namespace - uuid_cache_mesh = {} # mesh - uuid_cache_material = {} # material - uuid_cache_image = {} # image - uuid_cache_world = {} # world + if name_decorations: + # If names are decorated, the uuid map can be split up + # by type for efficiency of collision testing + # since objects of different types will always have + # different decorated names. + uuid_cache_object = {} # object + uuid_cache_lamp = {} # 'LA_' + object.name + uuid_cache_view = {} # object, different namespace + uuid_cache_mesh = {} # mesh + uuid_cache_material = {} # material + uuid_cache_image = {} # image + uuid_cache_world = {} # world + CA_ = 'CA_' + OB_ = 'OB_' + ME_ = 'ME_' + IM_ = 'IM_' + WO_ = 'WO_' + MA_ = 'MA_' + LA_ = 'LA_' + group_ = 'group_' + else: + # If names are not decorated, it may be possible for two objects to + # have the same name, so there has to be a unified dictionary to + # prevent uuid collisions. + uuid_cache = {} + uuid_cache_object = uuid_cache # object + uuid_cache_lamp = uuid_cache # 'LA_' + object.name + uuid_cache_view = uuid_cache # object, different namespace + uuid_cache_mesh = uuid_cache # mesh + uuid_cache_material = uuid_cache # material + uuid_cache_image = uuid_cache # image + uuid_cache_world = uuid_cache # world + del uuid_cache + CA_ = '' + OB_ = '' + ME_ = '' + IM_ = '' + WO_ = '' + MA_ = '' + LA_ = '' + group_ = '' + + _TRANSFORM = '_TRANSFORM' # store files to copy copy_set = set() @@ -328,7 +365,7 @@ return ident def writeViewpoint(ident, obj, matrix, scene): - view_id = quoteattr(unique_name(obj, 'CA_' + obj.name, uuid_cache_view, clean_func=clean_def, sep="_")) + view_id = quoteattr(unique_name(obj, CA_ + obj.name, uuid_cache_view, clean_func=clean_def, sep="_")) loc, rot, scale = matrix.decompose() rot = rot.to_axis_angle() @@ -396,7 +433,7 @@ def writeSpotLight(ident, obj, matrix, lamp, world): # note, lamp_id is not re-used - lamp_id = quoteattr(unique_name(obj, 'LA_' + obj.name, uuid_cache_lamp, clean_func=clean_def, sep="_")) + lamp_id = quoteattr(unique_name(obj, LA_ + obj.name, uuid_cache_lamp, clean_func=clean_def, sep="_")) if world: ambi = world.ambient_color @@ -432,7 +469,7 @@ def writeDirectionalLight(ident, obj, matrix, lamp, world): # note, lamp_id is not re-used - lamp_id = quoteattr(unique_name(obj, 'LA_' + obj.name, uuid_cache_lamp, clean_func=clean_def, sep="_")) + lamp_id = quoteattr(unique_name(obj, LA_ + obj.name, uuid_cache_lamp, clean_func=clean_def, sep="_")) if world: ambi = world.ambient_color @@ -457,7 +494,7 @@ def writePointLight(ident, obj, matrix, lamp, world): # note, lamp_id is not re-used - lamp_id = quoteattr(unique_name(obj, 'LA_' + obj.name, uuid_cache_lamp, clean_func=clean_def, sep="_")) + lamp_id = quoteattr(unique_name(obj, LA_ + obj.name, uuid_cache_lamp, clean_func=clean_def, sep="_")) if world: ambi = world.ambient_color @@ -482,9 +519,9 @@ fw(ident_step + '/>\n') def writeIndexedFaceSet(ident, obj, mesh, matrix, world): - obj_id = quoteattr(unique_name(obj, 'OB_' + obj.name, uuid_cache_object, clean_func=clean_def, sep="_")) - mesh_id = quoteattr(unique_name(mesh, 'ME_' + mesh.name, uuid_cache_mesh, clean_func=clean_def, sep="_")) - mesh_id_group = prefix_quoted_str(mesh_id, 'group_') + obj_id = quoteattr(unique_name(obj, OB_ + obj.name, uuid_cache_object, clean_func=clean_def, sep="_")) + mesh_id = quoteattr(unique_name(mesh, ME_ + mesh.name, uuid_cache_mesh, clean_func=clean_def, sep="_")) + mesh_id_group = prefix_quoted_str(mesh_id, group_) mesh_id_coords = prefix_quoted_str(mesh_id, 'coords_') mesh_id_normals = prefix_quoted_str(mesh_id, 'normals_') @@ -501,7 +538,7 @@ # use _ifs_TRANSFORM suffix so we dont collide with transform node when # hierarchys are used. - ident = writeTransform_begin(ident, matrix, suffix_quoted_str(obj_id, "_ifs_TRANSFORM")) + ident = writeTransform_begin(ident, matrix, suffix_quoted_str(obj_id, "_ifs" + _TRANSFORM)) if mesh.tag: fw('%s\n' % (ident, mesh_id_group)) @@ -918,7 +955,7 @@ fw('%s\n' % ident) def writeMaterial(ident, material, world): - material_id = quoteattr(unique_name(material, 'MA_' + material.name, uuid_cache_material, clean_func=clean_def, sep="_")) + material_id = quoteattr(unique_name(material, MA_ + material.name, uuid_cache_material, clean_func=clean_def, sep="_")) # look up material name, use it if available if material.tag: @@ -1084,7 +1121,7 @@ frag_uniform_var_map[uniform['varname']] = lamp_obj if uniform['datatype'] == gpu.GPU_DATA_3F: # should always be true! - lamp_obj_id = quoteattr(unique_name(lamp_obj, 'LA_' + lamp_obj.name, uuid_cache_lamp, clean_func=clean_def, sep="_")) + lamp_obj_id = quoteattr(unique_name(lamp_obj, LA_ + lamp_obj.name, uuid_cache_lamp, clean_func=clean_def, sep="_")) lamp_obj_transform_id = quoteattr(unique_name(lamp_obj, lamp_obj.name, uuid_cache_object, clean_func=clean_def, sep="_")) value = '%.6f %.6f %.6f' % (global_matrix * lamp_obj.matrix_world).to_translation()[:] @@ -1100,7 +1137,7 @@ frag_vars.append("uniform mat4 %s_transform;" % uniform['varname']) h3d_material_route.append( '%s' % - (suffix_quoted_str(lamp_obj_transform_id, "_TRANSFORM"), material_id, uniform['varname'], field_descr)) + (suffix_quoted_str(lamp_obj_transform_id, _TRANSFORM), material_id, uniform['varname'], field_descr)) h3d_material_route.append( ' %s' % @@ -1141,7 +1178,7 @@ # route so we can have the lamp update the view if h3d_is_object_view(scene, lamp_obj): - lamp_id = quoteattr(unique_name(lamp_obj, 'LA_' + lamp_obj.name, uuid_cache_lamp, clean_func=clean_def, sep="_")) + lamp_id = quoteattr(unique_name(lamp_obj, LA_ + lamp_obj.name, uuid_cache_lamp, clean_func=clean_def, sep="_")) h3d_material_route.append( '%s' % (lamp_id, material_id, uniform['varname'], field_descr)) @@ -1152,18 +1189,19 @@ elif uniform['type'] == gpu.GPU_DYNAMIC_OBJECT_VIEWIMAT: frag_uniform_var_map[uniform['varname']] = None if uniform['datatype'] == gpu.GPU_DATA_16F: - # must be updated dynamically - # TODO, write out 'viewpointMatrices.py' - value = ' '.join(['%.6f' % f for v in mathutils.Matrix() for f in v]) - field_descr = " " % obj.name - fw('%s%s\n' % (ident, uniform['varname'], value, field_descr)) + field_descr = " " % obj.name + fw('%s%s\n' % (ident, uniform['varname'], field_descr)) + + h3d_material_route.append( + '%s' % + (H3D_TOP_LEVEL, material_id, uniform['varname'], field_descr)) else: assert(0) elif uniform['type'] == gpu.GPU_DYNAMIC_OBJECT_IMAT: frag_uniform_var_map[uniform['varname']] = None if uniform['datatype'] == gpu.GPU_DATA_16F: - value = ' '.join(['%.6f' % f for v in (global_matrix * obj.matrix_world).inverted() for f in v]) + value = ' '.join(['%.6f' % f for v in (global_matrix * obj.matrix_world).inverted().transposed() for f in v]) field_descr = " " % obj.name fw('%s%s\n' % (ident, uniform['varname'], value, field_descr)) else: @@ -1233,7 +1271,7 @@ fw('%s\n' % ident) def writeImageTexture(ident, image): - image_id = quoteattr(unique_name(image, 'IM_' + image.name, uuid_cache_image, clean_func=clean_def, sep="_")) + image_id = quoteattr(unique_name(image, IM_ + image.name, uuid_cache_image, clean_func=clean_def, sep="_")) if image.tag: fw('%s\n' % (ident, image_id)) @@ -1269,7 +1307,7 @@ return # note, not re-used - world_id = quoteattr(unique_name(world, 'WO_' + world.name, uuid_cache_world, clean_func=clean_def, sep="_")) + world_id = quoteattr(unique_name(world, WO_ + world.name, uuid_cache_world, clean_func=clean_def, sep="_")) blending = world.use_sky_blend, world.use_sky_paper, world.use_sky_real @@ -1349,7 +1387,7 @@ obj_main_id = quoteattr(unique_name(obj_main, obj_main.name, uuid_cache_object, clean_func=clean_def, sep="_")) - ident = writeTransform_begin(ident, obj_main_matrix if obj_main_parent else global_matrix * obj_main_matrix, suffix_quoted_str(obj_main_id, "_TRANSFORM")) + ident = writeTransform_begin(ident, obj_main_matrix if obj_main_parent else global_matrix * obj_main_matrix, suffix_quoted_str(obj_main_id, _TRANSFORM)) for obj, obj_matrix in (() if derived is None else derived): obj_type = obj.type @@ -1496,6 +1534,23 @@ ########################################################## +def gzip_open_utf8(filepath, mode): + """Workaround for py3k only allowing binary gzip writing""" + + import gzip + + # need to investigate encoding + file = gzip.open(filepath, mode) + write_real = file.write + + def write_wrap(data): + return write_real(data.encode("utf-8")) + + file.write = write_wrap + + return file + + def save(operator, context, filepath="", use_selection=True, use_apply_modifiers=False, @@ -1506,6 +1561,7 @@ use_h3d=False, global_matrix=None, path_mode='AUTO', + name_decorations=True, ): bpy.path.ensure_ext(filepath, '.x3dz' if use_compress else '.x3d') @@ -1514,9 +1570,7 @@ bpy.ops.object.mode_set(mode='OBJECT') if use_compress: - import gzip - # need to investigate encoding - file = gzip.open(filepath, 'w') + file = gzip_open_utf8(filepath, 'w') else: file = open(filepath, 'w', encoding='utf-8') @@ -1533,6 +1587,7 @@ use_hierarchy=use_hierarchy, use_h3d=use_h3d, path_mode=path_mode, + name_decorations=name_decorations, ) return {'FINISHED'} diff -Nru blender-2.61/release/scripts/addons/io_scene_x3d/import_x3d.py blender-2.62/release/scripts/addons/io_scene_x3d/import_x3d.py --- blender-2.61/release/scripts/addons/io_scene_x3d/import_x3d.py 2011-12-13 19:58:48.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_scene_x3d/import_x3d.py 2012-02-15 19:43:17.000000000 +0000 @@ -1414,16 +1414,8 @@ # ----------------------------------------------------------------------------------- import bpy from bpy_extras import image_utils -# import BPyImage -# import BPySys -# reload(BPySys) -# reload(BPyImage) -# import Blender -# from Blender import Texture, Material, Mathutils, Mesh, Types, Window from mathutils import Vector, Matrix -RAD_TO_DEG = 57.29578 - GLOBALS = {'CIRCLE_DETAIL': 16} diff -Nru blender-2.61/release/scripts/addons/io_scene_x3d/__init__.py blender-2.62/release/scripts/addons/io_scene_x3d/__init__.py --- blender-2.61/release/scripts/addons/io_scene_x3d/__init__.py 2011-12-13 19:58:48.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_scene_x3d/__init__.py 2012-02-15 19:43:17.000000000 +0000 @@ -22,7 +22,6 @@ "name": "Web3D X3D/VRML format", "author": "Campbell Barton, Bart", "blender": (2, 5, 7), - "api": 35622, "location": "File > Import-Export", "description": "Import-Export X3D, Import VRML", "warning": "", @@ -135,11 +134,18 @@ description="Export parent child relationships", default=True, ) + name_decorations = BoolProperty( + name="Name decorations", + description=("Add prefixes to the names of exported nodes to " + "indicate their type"), + default=True, + ) use_h3d = BoolProperty( name="H3D Extensions", description="Export shaders for H3D", default=False, ) + axis_forward = EnumProperty( name="Forward", items=(('X', "X Forward", ""), @@ -148,9 +154,9 @@ ('-X', "-X Forward", ""), ('-Y', "-Y Forward", ""), ('-Z', "-Z Forward", ""), - ), - default='Z', - ) + ), + default='Z', + ) axis_up = EnumProperty( name="Up", diff -Nru blender-2.61/release/scripts/addons/io_shape_mdd/__init__.py blender-2.62/release/scripts/addons/io_shape_mdd/__init__.py --- blender-2.61/release/scripts/addons/io_shape_mdd/__init__.py 2011-12-13 19:59:08.000000000 +0000 +++ blender-2.62/release/scripts/addons/io_shape_mdd/__init__.py 2012-02-15 19:43:31.000000000 +0000 @@ -22,7 +22,6 @@ "name": "NewTek MDD format", "author": "Bill L.Nieuwendorp", "blender": (2, 5, 7), - "api": 35622, "location": "File > Import-Export", "description": "Import-Export MDD as mesh shape keys", "warning": "", diff -Nru blender-2.61/release/scripts/addons/light_field_tools/__init__.py blender-2.62/release/scripts/addons/light_field_tools/__init__.py --- blender-2.61/release/scripts/addons/light_field_tools/__init__.py 2011-12-13 19:58:19.000000000 +0000 +++ blender-2.62/release/scripts/addons/light_field_tools/__init__.py 2012-02-15 19:42:43.000000000 +0000 @@ -23,7 +23,6 @@ 'description': 'Tools to create a light field camera and projector', 'version': (0, 2, 1), 'blender': (2, 5, 7), - 'api': 36103, 'location': 'View3D > Tool Shelf > Light Field Tools', 'url': 'http://www.jku.at/cg/', "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Render/Light_Field_Tools", diff -Nru blender-2.61/release/scripts/addons/mesh_bsurfaces.py blender-2.62/release/scripts/addons/mesh_bsurfaces.py --- blender-2.61/release/scripts/addons/mesh_bsurfaces.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/mesh_bsurfaces.py 2012-02-15 19:43:32.000000000 +0000 @@ -21,7 +21,6 @@ "author": "Eclectiel", "version": (0,9), "blender": (2, 5, 7), - "api": 35733, "location": "View3D > EditMode > ToolShelf", "description": "Draw meshes and re-topologies with Grease Pencil", "warning": "Beta", @@ -823,9 +822,10 @@ bpy.types.Scene.SURFSK_keep_strokes = bpy.props.BoolProperty(name="Keep strokes", description="Keeps the sketched strokes after adding the surface", default=False) kc = bpy.context.window_manager.keyconfigs.addon - km = kc.keymaps.new(name="3D View", space_type="VIEW_3D") - keymap_item_add_surf = km.keymap_items.new("gpencil.surfsk_add_surface","E","PRESS", key_modifier="D") - keymap_item_stroke_to_curve = km.keymap_items.new("gpencil.surfsk_strokes_to_curves","C","PRESS", key_modifier="D") + if kc: + km = kc.keymaps.new(name="3D View", space_type="VIEW_3D") + keymap_item_add_surf = km.keymap_items.new("gpencil.surfsk_add_surface","E","PRESS", key_modifier="D") + keymap_item_stroke_to_curve = km.keymap_items.new("gpencil.surfsk_strokes_to_curves","C","PRESS", key_modifier="D") def unregister(): @@ -839,15 +839,16 @@ del bpy.types.Scene.SURFSK_keep_strokes kc = bpy.context.window_manager.keyconfigs.addon - km = kc.keymaps["3D View"] - for kmi in km.keymap_items: - if kmi.idname == 'wm.call_menu': - if kmi.properties.name == "GPENCIL_OT_SURFSK_add_surface": - km.keymap_items.remove(kmi) - elif kmi.properties.name == "GPENCIL_OT_SURFSK_strokes_to_curves": - km.keymap_items.remove(kmi) - else: - continue + if kc: + km = kc.keymaps["3D View"] + for kmi in km.keymap_items: + if kmi.idname == 'wm.call_menu': + if kmi.properties.name == "GPENCIL_OT_SURFSK_add_surface": + km.keymap_items.remove(kmi) + elif kmi.properties.name == "GPENCIL_OT_SURFSK_strokes_to_curves": + km.keymap_items.remove(kmi) + else: + continue if __name__ == "__main__": diff -Nru blender-2.61/release/scripts/addons/mesh_inset/__init__.py blender-2.62/release/scripts/addons/mesh_inset/__init__.py --- blender-2.61/release/scripts/addons/mesh_inset/__init__.py 2011-12-13 19:59:03.000000000 +0000 +++ blender-2.62/release/scripts/addons/mesh_inset/__init__.py 2012-02-15 19:43:29.000000000 +0000 @@ -23,7 +23,6 @@ "author": "Howard Trickey", "version": (0, 3), "blender": (2, 5, 7), - "api": 36147, "location": "View3D > Tools", "description": "Make an inset polygon inside selection.", "warning": "", diff -Nru blender-2.61/release/scripts/addons/mesh_looptools.py blender-2.62/release/scripts/addons/mesh_looptools.py --- blender-2.61/release/scripts/addons/mesh_looptools.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/mesh_looptools.py 2012-02-15 19:43:32.000000000 +0000 @@ -19,9 +19,8 @@ bl_info = { 'name': "LoopTools", 'author': "Bart Crouch", - 'version': (3, 2, 2), - 'blender': (2, 6, 0), - 'api': 42162, + 'version': (3, 2, 3), + 'blender': (2, 6, 1), 'location': "View3D > Toolbar and View3D > Specials (W-key)", 'warning': "", 'description': "Mesh modelling toolkit. Several tools to aid modelling", @@ -223,13 +222,13 @@ )) for loc in locs: mat[0][0] += (loc[0]-x)**2 - mat[0][1] += (loc[0]-x)*(loc[1]-y) - mat[0][2] += (loc[0]-x)*(loc[2]-z) - mat[1][0] += (loc[1]-y)*(loc[0]-x) + mat[1][0] += (loc[0]-x)*(loc[1]-y) + mat[2][0] += (loc[0]-x)*(loc[2]-z) + mat[0][1] += (loc[1]-y)*(loc[0]-x) mat[1][1] += (loc[1]-y)**2 - mat[1][2] += (loc[1]-y)*(loc[2]-z) - mat[2][0] += (loc[2]-z)*(loc[0]-x) - mat[2][1] += (loc[2]-z)*(loc[1]-y) + mat[2][1] += (loc[1]-y)*(loc[2]-z) + mat[0][2] += (loc[2]-z)*(loc[0]-x) + mat[1][2] += (loc[2]-z)*(loc[1]-y) mat[2][2] += (loc[2]-z)**2 # calculating the normal to the plane @@ -244,12 +243,20 @@ elif sum(mat[2]) == 0.0: normal = mathutils.Vector((0.0, 0.0, 1.0)) if not normal: + # warning! this is different from .normalize() + itermax = 500 + iter = 0 vec = mathutils.Vector((1.0, 1.0, 1.0)) - normal = (mat * vec)/(mat * vec).length - if normal.length == 0: - normal = vec - else: - normal.normalize() + vec2 = (mat * vec)/(mat * vec).length + while vec != vec2 and iter Specials > Relax ", "description": "Relax the selected verts while retaining the shape", "warning": "", diff -Nru blender-2.61/release/scripts/addons/mocap/__init__.py blender-2.62/release/scripts/addons/mocap/__init__.py --- blender-2.61/release/scripts/addons/mocap/__init__.py 2011-12-13 19:58:05.000000000 +0000 +++ blender-2.62/release/scripts/addons/mocap/__init__.py 2012-02-15 19:42:35.000000000 +0000 @@ -22,7 +22,6 @@ "name": "Motion Capture Tools", "author": "Benjy Cook", "blender": (2, 5, 9), - "api": 39523, "location": "Object UI -> Mocap tools", "description": "Various tools for working with motion capture animation", "warning": "", diff -Nru blender-2.61/release/scripts/addons/modules/add_utils.py blender-2.62/release/scripts/addons/modules/add_utils.py --- blender-2.61/release/scripts/addons/modules/add_utils.py 2011-12-13 19:58:08.000000000 +0000 +++ blender-2.62/release/scripts/addons/modules/add_utils.py 2012-02-15 19:42:39.000000000 +0000 @@ -112,16 +112,12 @@ return base -def flatten_vector_list(list): +def flatten_vector_list(ls): '''flatten a list of vetcors to use in foreach_set and the like''' - if not list: + if not ls: return None - result = [] - for vec in list: - result.extend([i for i in vec]) - - return result + return [i for v in ls for i in v] def list_to_vector_list(list, dimension=3): diff -Nru blender-2.61/release/scripts/addons/modules/cursor_utils.py blender-2.62/release/scripts/addons/modules/cursor_utils.py --- blender-2.61/release/scripts/addons/modules/cursor_utils.py 2011-12-13 19:58:08.000000000 +0000 +++ blender-2.62/release/scripts/addons/modules/cursor_utils.py 2012-02-15 19:42:39.000000000 +0000 @@ -56,6 +56,3 @@ def getCursor(cls): spc = cls.findSpace() return spc.cursor_location - - - diff -Nru blender-2.61/release/scripts/addons/modules/extensions_framework/__init__.py blender-2.62/release/scripts/addons/modules/extensions_framework/__init__.py --- blender-2.61/release/scripts/addons/modules/extensions_framework/__init__.py 2011-12-13 19:58:08.000000000 +0000 +++ blender-2.62/release/scripts/addons/modules/extensions_framework/__init__.py 2012-02-15 19:42:39.000000000 +0000 @@ -33,339 +33,339 @@ del EF_OT_msg def log(str, popup=False, module_name='EF'): - """Print a message to the console, prefixed with the module_name - and the current time. If the popup flag is True, the message will - be raised in the UI as a warning using the operator bpy.ops.ef.msg. - - """ - print("[%s %s] %s" % - (module_name, time.strftime('%Y-%b-%d %H:%M:%S'), str)) - if popup: - bpy.ops.ef.msg( - msg_type='WARNING', - msg_text=str - ) + """Print a message to the console, prefixed with the module_name + and the current time. If the popup flag is True, the message will + be raised in the UI as a warning using the operator bpy.ops.ef.msg. + + """ + print("[%s %s] %s" % + (module_name, time.strftime('%Y-%b-%d %H:%M:%S'), str)) + if popup: + bpy.ops.ef.msg( + msg_type='WARNING', + msg_text=str + ) added_property_cache = {} def init_properties(obj, props, cache=True): - """Initialise custom properties in the given object or type. - The props list is described in the declarative_property_group - class definition. If the cache flag is False, this function - will attempt to redefine properties even if they have already been - added. - - """ - - if not obj in added_property_cache.keys(): - added_property_cache[obj] = [] - - for prop in props: - try: - if cache and prop['attr'] in added_property_cache[obj]: - continue - - if prop['type'] == 'bool': - t = bpy.props.BoolProperty - a = {k: v for k,v in prop.items() if k in ["name", - "description","default","options","subtype","update"]} - elif prop['type'] == 'bool_vector': - t = bpy.props.BoolVectorProperty - a = {k: v for k,v in prop.items() if k in ["name", - "description","default","options","subtype","size", - "update"]} - elif prop['type'] == 'collection': - t = bpy.props.CollectionProperty - a = {k: v for k,v in prop.items() if k in ["ptype","name", - "description","default","options"]} - a['type'] = a['ptype'] - del a['ptype'] - elif prop['type'] == 'enum': - t = bpy.props.EnumProperty - a = {k: v for k,v in prop.items() if k in ["items","name", - "description","default","options","update"]} - elif prop['type'] == 'float': - t = bpy.props.FloatProperty - a = {k: v for k,v in prop.items() if k in ["name", - "description","default","min","max","soft_min","soft_max", - "step","precision","options","subtype","unit","update"]} - elif prop['type'] == 'float_vector': - t = bpy.props.FloatVectorProperty - a = {k: v for k,v in prop.items() if k in ["name", - "description","default","min","max","soft_min","soft_max", - "step","precision","options","subtype","size","update"]} - elif prop['type'] == 'int': - t = bpy.props.IntProperty - a = {k: v for k,v in prop.items() if k in ["name", - "description","default","min","max","soft_min","soft_max", - "step","options","subtype","update"]} - elif prop['type'] == 'int_vector': - t = bpy.props.IntVectorProperty - a = {k: v for k,v in prop.items() if k in ["name", - "description","default","min","max","soft_min","soft_max", - "options","subtype","size","update"]} - elif prop['type'] == 'pointer': - t = bpy.props.PointerProperty - a = {k: v for k,v in prop.items() if k in ["ptype", "name", - "description","options","update"]} - a['type'] = a['ptype'] - del a['ptype'] - elif prop['type'] == 'string': - t = bpy.props.StringProperty - a = {k: v for k,v in prop.items() if k in ["name", - "description","default","maxlen","options","subtype", - "update"]} - else: - continue - - setattr(obj, prop['attr'], t(**a)) - - added_property_cache[obj].append(prop['attr']) - except KeyError: - # Silently skip invalid entries in props - continue + """Initialise custom properties in the given object or type. + The props list is described in the declarative_property_group + class definition. If the cache flag is False, this function + will attempt to redefine properties even if they have already been + added. + + """ + + if not obj in added_property_cache.keys(): + added_property_cache[obj] = [] + + for prop in props: + try: + if cache and prop['attr'] in added_property_cache[obj]: + continue + + if prop['type'] == 'bool': + t = bpy.props.BoolProperty + a = {k: v for k,v in prop.items() if k in ["name", + "description","default","options","subtype","update"]} + elif prop['type'] == 'bool_vector': + t = bpy.props.BoolVectorProperty + a = {k: v for k,v in prop.items() if k in ["name", + "description","default","options","subtype","size", + "update"]} + elif prop['type'] == 'collection': + t = bpy.props.CollectionProperty + a = {k: v for k,v in prop.items() if k in ["ptype","name", + "description","default","options"]} + a['type'] = a['ptype'] + del a['ptype'] + elif prop['type'] == 'enum': + t = bpy.props.EnumProperty + a = {k: v for k,v in prop.items() if k in ["items","name", + "description","default","options","update"]} + elif prop['type'] == 'float': + t = bpy.props.FloatProperty + a = {k: v for k,v in prop.items() if k in ["name", + "description","default","min","max","soft_min","soft_max", + "step","precision","options","subtype","unit","update"]} + elif prop['type'] == 'float_vector': + t = bpy.props.FloatVectorProperty + a = {k: v for k,v in prop.items() if k in ["name", + "description","default","min","max","soft_min","soft_max", + "step","precision","options","subtype","size","update"]} + elif prop['type'] == 'int': + t = bpy.props.IntProperty + a = {k: v for k,v in prop.items() if k in ["name", + "description","default","min","max","soft_min","soft_max", + "step","options","subtype","update"]} + elif prop['type'] == 'int_vector': + t = bpy.props.IntVectorProperty + a = {k: v for k,v in prop.items() if k in ["name", + "description","default","min","max","soft_min","soft_max", + "options","subtype","size","update"]} + elif prop['type'] == 'pointer': + t = bpy.props.PointerProperty + a = {k: v for k,v in prop.items() if k in ["ptype", "name", + "description","options","update"]} + a['type'] = a['ptype'] + del a['ptype'] + elif prop['type'] == 'string': + t = bpy.props.StringProperty + a = {k: v for k,v in prop.items() if k in ["name", + "description","default","maxlen","options","subtype", + "update"]} + else: + continue + + setattr(obj, prop['attr'], t(**a)) + + added_property_cache[obj].append(prop['attr']) + except KeyError: + # Silently skip invalid entries in props + continue class declarative_property_group(bpy.types.PropertyGroup): - """A declarative_property_group describes a set of logically - related properties, using a declarative style to list each - property type, name, values, and other relevant information. - The information provided for each property depends on the - property's type. - - The properties list attribute in this class describes the - properties present in this group. - - Some additional information about the properties in this group - can be specified, so that a UI can be generated to display them. - To that end, the controls list attribute and the visibility dict - attribute are present here, to be read and interpreted by a - property_group_renderer object. - See extensions_framework.ui.property_group_renderer. - - """ - - ef_initialised = False - - """This property tells extensions_framework which bpy.type(s) - to attach this PropertyGroup to. If left as an empty list, - it will not be attached to any type, but its properties will - still be initialised. The type(s) given in the list should be - a string, such as 'Scene'. - - """ - ef_attach_to = [] - - @classmethod - def initialise_properties(cls): - """This is a function that should be called on - sub-classes of declarative_property_group in order - to ensure that they are initialised when the addon - is loaded. - the init_properties is called without caching here, - as it is assumed that any addon calling this function - will also call ef_remove_properties when it is - unregistered. - - """ - - if not cls.ef_initialised: - for property_group_parent in cls.ef_attach_to: - if property_group_parent is not None: - prototype = getattr(bpy.types, property_group_parent) - if not hasattr(prototype, cls.__name__): - init_properties(prototype, [{ - 'type': 'pointer', - 'attr': cls.__name__, - 'ptype': cls, - 'name': cls.__name__, - 'description': cls.__name__ - }], cache=False) - - init_properties(cls, cls.properties, cache=False) - cls.ef_initialised = True - - return cls - - @classmethod - def register_initialise_properties(cls): - """As ef_initialise_properties, but also registers the - class with RNA. Note that this isn't a great idea - because it's non-trivial to unregister the class, unless - you keep track of it yourself. - """ - - bpy.utils.register_class(cls) - cls.initialise_properties() - return cls - - @classmethod - def remove_properties(cls): - """This is a function that should be called on - sub-classes of declarative_property_group in order - to ensure that they are un-initialised when the addon - is unloaded. - - """ - - if cls.ef_initialised: - prototype = getattr(bpy.types, cls.__name__) - for prop in cls.properties: - if hasattr(prototype, prop['attr']): - delattr(prototype, prop['attr']) - - for property_group_parent in cls.ef_attach_to: - if property_group_parent is not None: - prototype = getattr(bpy.types, property_group_parent) - if hasattr(prototype, cls.__name__): - delattr(prototype, cls.__name__) - - cls.ef_initialised = False - - return cls - - - """This list controls the order of property layout when rendered - by a property_group_renderer. This can be a nested list, where each - list becomes a row in the panel layout. Nesting may be to any depth. - - """ - controls = [] - - """The visibility dict controls the visibility of properties based on - the value of other properties. See extensions_framework.validate - for test syntax. - - """ - visibility = {} - - """The enabled dict controls the enabled state of properties based on - the value of other properties. See extensions_framework.validate - for test syntax. - - """ - enabled = {} - - """The alert dict controls the alert state of properties based on - the value of other properties. See extensions_framework.validate - for test syntax. - - """ - alert = {} - - """The properties list describes each property to be created. Each - item should be a dict of args to pass to a - bpy.props.Property function, with the exception of 'type' - which is used and stripped by extensions_framework in order to - determine which Property creation function to call. - - Example item: - { - 'type': 'int', # bpy.props.IntProperty - 'attr': 'threads', # bpy.types..threads - 'name': 'Render Threads', # Rendered next to the UI - 'description': 'Number of threads to use', # Tooltip text in the UI - 'default': 1, - 'min': 1, - 'soft_min': 1, - 'max': 64, - 'soft_max': 64 - } - - """ - properties = [] - - def draw_callback(self, context): - """Sub-classes can override this to get a callback when - rendering is completed by a property_group_renderer sub-class. - - """ - - pass - - @classmethod - def get_exportable_properties(cls): - """Return a list of properties which have the 'save_in_preset' key - set to True, and hence should be saved into preset files. - - """ - - out = [] - for prop in cls.properties: - if 'save_in_preset' in prop.keys() and prop['save_in_preset']: - out.append(prop) - return out - - def reset(self): - """Reset all properties in this group to the default value, - if specified""" - for prop in self.properties: - pk = prop.keys() - if 'attr' in pk and 'default' in pk and hasattr(self, prop['attr']): - setattr(self, prop['attr'], prop['default']) + """A declarative_property_group describes a set of logically + related properties, using a declarative style to list each + property type, name, values, and other relevant information. + The information provided for each property depends on the + property's type. + + The properties list attribute in this class describes the + properties present in this group. + + Some additional information about the properties in this group + can be specified, so that a UI can be generated to display them. + To that end, the controls list attribute and the visibility dict + attribute are present here, to be read and interpreted by a + property_group_renderer object. + See extensions_framework.ui.property_group_renderer. + + """ + + ef_initialised = False + + """This property tells extensions_framework which bpy.type(s) + to attach this PropertyGroup to. If left as an empty list, + it will not be attached to any type, but its properties will + still be initialised. The type(s) given in the list should be + a string, such as 'Scene'. + + """ + ef_attach_to = [] + + @classmethod + def initialise_properties(cls): + """This is a function that should be called on + sub-classes of declarative_property_group in order + to ensure that they are initialised when the addon + is loaded. + the init_properties is called without caching here, + as it is assumed that any addon calling this function + will also call ef_remove_properties when it is + unregistered. + + """ + + if not cls.ef_initialised: + for property_group_parent in cls.ef_attach_to: + if property_group_parent is not None: + prototype = getattr(bpy.types, property_group_parent) + if not hasattr(prototype, cls.__name__): + init_properties(prototype, [{ + 'type': 'pointer', + 'attr': cls.__name__, + 'ptype': cls, + 'name': cls.__name__, + 'description': cls.__name__ + }], cache=False) + + init_properties(cls, cls.properties, cache=False) + cls.ef_initialised = True + + return cls + + @classmethod + def register_initialise_properties(cls): + """As ef_initialise_properties, but also registers the + class with RNA. Note that this isn't a great idea + because it's non-trivial to unregister the class, unless + you keep track of it yourself. + """ + + bpy.utils.register_class(cls) + cls.initialise_properties() + return cls + + @classmethod + def remove_properties(cls): + """This is a function that should be called on + sub-classes of declarative_property_group in order + to ensure that they are un-initialised when the addon + is unloaded. + + """ + + if cls.ef_initialised: + prototype = getattr(bpy.types, cls.__name__) + for prop in cls.properties: + if hasattr(prototype, prop['attr']): + delattr(prototype, prop['attr']) + + for property_group_parent in cls.ef_attach_to: + if property_group_parent is not None: + prototype = getattr(bpy.types, property_group_parent) + if hasattr(prototype, cls.__name__): + delattr(prototype, cls.__name__) + + cls.ef_initialised = False + + return cls + + + """This list controls the order of property layout when rendered + by a property_group_renderer. This can be a nested list, where each + list becomes a row in the panel layout. Nesting may be to any depth. + + """ + controls = [] + + """The visibility dict controls the visibility of properties based on + the value of other properties. See extensions_framework.validate + for test syntax. + + """ + visibility = {} + + """The enabled dict controls the enabled state of properties based on + the value of other properties. See extensions_framework.validate + for test syntax. + + """ + enabled = {} + + """The alert dict controls the alert state of properties based on + the value of other properties. See extensions_framework.validate + for test syntax. + + """ + alert = {} + + """The properties list describes each property to be created. Each + item should be a dict of args to pass to a + bpy.props.Property function, with the exception of 'type' + which is used and stripped by extensions_framework in order to + determine which Property creation function to call. + + Example item: + { + 'type': 'int', # bpy.props.IntProperty + 'attr': 'threads', # bpy.types..threads + 'name': 'Render Threads', # Rendered next to the UI + 'description': 'Number of threads to use', # Tooltip text in the UI + 'default': 1, + 'min': 1, + 'soft_min': 1, + 'max': 64, + 'soft_max': 64 + } + + """ + properties = [] + + def draw_callback(self, context): + """Sub-classes can override this to get a callback when + rendering is completed by a property_group_renderer sub-class. + + """ + + pass + + @classmethod + def get_exportable_properties(cls): + """Return a list of properties which have the 'save_in_preset' key + set to True, and hence should be saved into preset files. + + """ + + out = [] + for prop in cls.properties: + if 'save_in_preset' in prop.keys() and prop['save_in_preset']: + out.append(prop) + return out + + def reset(self): + """Reset all properties in this group to the default value, + if specified""" + for prop in self.properties: + pk = prop.keys() + if 'attr' in pk and 'default' in pk and hasattr(self, prop['attr']): + setattr(self, prop['attr'], prop['default']) class Addon(object): - """A list of classes registered by this addon""" - static_addon_count = 0 - - addon_serial = 0 - addon_classes = None - bl_info = None - - BL_VERSION = None - BL_IDNAME = None - - def __init__(self, bl_info=None): - self.addon_classes = [] - self.bl_info = bl_info - - # Keep a count in case we have to give this addon an anonymous name - self.addon_serial = Addon.static_addon_count - Addon.static_addon_count += 1 - - if self.bl_info: - self.BL_VERSION = '.'.join(['%s'%v for v in self.bl_info['version']]).lower() - self.BL_IDNAME = self.bl_info['name'].lower() + '-' + self.BL_VERSION - else: - # construct anonymous name - self.BL_VERSION = '0' - self.BL_IDNAME = 'Addon-%03d'%self.addon_serial - - def addon_register_class(self, cls): - """This method is designed to be used as a decorator on RNA-registerable - classes defined by the addon. By using this decorator, this class will - keep track of classes registered by this addon so that they can be - unregistered later in the correct order. - - """ - self.addon_classes.append(cls) - return cls - - def register(self): - """This is the register function that should be exposed in the addon's - __init__. - - """ - for cls in self.addon_classes: - bpy.utils.register_class(cls) - if hasattr(cls, 'ef_attach_to'): cls.initialise_properties() - - def unregister(self): - """This is the unregister function that should be exposed in the addon's - __init__. - - """ - for cls in self.addon_classes[::-1]: # unregister in reverse order - if hasattr(cls, 'ef_attach_to'): cls.remove_properties() - bpy.utils.unregister_class(cls) - - def init_functions(self): - """Returns references to the three functions that this addon needs - for successful class registration management. In the addon's __init__ - you would use like this: - - addon_register_class, register, unregister = Addon().init_functions() - - """ - - return self.register, self.unregister + """A list of classes registered by this addon""" + static_addon_count = 0 + + addon_serial = 0 + addon_classes = None + bl_info = None + + BL_VERSION = None + BL_IDNAME = None + + def __init__(self, bl_info=None): + self.addon_classes = [] + self.bl_info = bl_info + + # Keep a count in case we have to give this addon an anonymous name + self.addon_serial = Addon.static_addon_count + Addon.static_addon_count += 1 + + if self.bl_info: + self.BL_VERSION = '.'.join(['%s'%v for v in self.bl_info['version']]).lower() + self.BL_IDNAME = self.bl_info['name'].lower() + '-' + self.BL_VERSION + else: + # construct anonymous name + self.BL_VERSION = '0' + self.BL_IDNAME = 'Addon-%03d'%self.addon_serial + + def addon_register_class(self, cls): + """This method is designed to be used as a decorator on RNA-registerable + classes defined by the addon. By using this decorator, this class will + keep track of classes registered by this addon so that they can be + unregistered later in the correct order. + + """ + self.addon_classes.append(cls) + return cls + + def register(self): + """This is the register function that should be exposed in the addon's + __init__. + + """ + for cls in self.addon_classes: + bpy.utils.register_class(cls) + if hasattr(cls, 'ef_attach_to'): cls.initialise_properties() + + def unregister(self): + """This is the unregister function that should be exposed in the addon's + __init__. + + """ + for cls in self.addon_classes[::-1]: # unregister in reverse order + if hasattr(cls, 'ef_attach_to'): cls.remove_properties() + bpy.utils.unregister_class(cls) + + def init_functions(self): + """Returns references to the three functions that this addon needs + for successful class registration management. In the addon's __init__ + you would use like this: + + addon_register_class, register, unregister = Addon().init_functions() + + """ + + return self.register, self.unregister diff -Nru blender-2.61/release/scripts/addons/modules/extensions_framework/ui.py blender-2.62/release/scripts/addons/modules/extensions_framework/ui.py --- blender-2.61/release/scripts/addons/modules/extensions_framework/ui.py 2011-12-13 19:58:08.000000000 +0000 +++ blender-2.62/release/scripts/addons/modules/extensions_framework/ui.py 2012-02-15 19:42:39.000000000 +0000 @@ -29,309 +29,309 @@ from extensions_framework.validate import Logician class EF_OT_msg(bpy.types.Operator): - """An operator to show simple messages in the UI""" - bl_idname = 'ef.msg' - bl_label = 'Show UI Message' - msg_type = bpy.props.StringProperty(default='INFO') - msg_text = bpy.props.StringProperty(default='') - def execute(self, context): - self.report({self.properties.msg_type}, self.properties.msg_text) - return {'FINISHED'} + """An operator to show simple messages in the UI""" + bl_idname = 'ef.msg' + bl_label = 'Show UI Message' + msg_type = bpy.props.StringProperty(default='INFO') + msg_text = bpy.props.StringProperty(default='') + def execute(self, context): + self.report({self.properties.msg_type}, self.properties.msg_text) + return {'FINISHED'} def _get_item_from_context(context, path): - """Utility to get an object when the path to it is known: - _get_item_from_context(context, ['a','b','c']) returns - context.a.b.c - No error checking is performed other than checking that context - is not None. Exceptions caused by invalid path should be caught in - the calling code. - - """ - - if context is not None: - for p in path: - context = getattr(context, p) - return context + """Utility to get an object when the path to it is known: + _get_item_from_context(context, ['a','b','c']) returns + context.a.b.c + No error checking is performed other than checking that context + is not None. Exceptions caused by invalid path should be caught in + the calling code. + + """ + + if context is not None: + for p in path: + context = getattr(context, p) + return context class property_group_renderer(bpy.types.Panel): - """Mix-in class for sub-classes of bpy.types.Panel. This class - will provide the draw() method which implements drawing one or - more property groups derived from - extensions_framework.declarative_propery_group. - The display_property_groups list attribute describes which - declarative_property_groups should be drawn in the Panel, and - how to extract those groups from the context passed to draw(). - - """ - - """The display_property_groups list attribute specifies which - custom declarative_property_groups this panel should draw, and - where to find that property group in the active context. - Example item: - ( ('scene',), 'myaddon_property_group') - In this case, this renderer will look for properties in - context.scene.myaddon_property_group to draw in the Panel. - - """ - display_property_groups = [] - - def draw(self, context): - """Sub-classes should override this if they need to display - other (object-related) property groups. super().draw(context) - can be a useful call in those cases. - - """ - for property_group_path, property_group_name in \ - self.display_property_groups: - ctx = _get_item_from_context(context, property_group_path) - property_group = getattr(ctx, property_group_name) - for p in property_group.controls: - self.draw_column(p, self.layout, ctx, context, - property_group=property_group) - property_group.draw_callback(context) - - def check_visibility(self, lookup_property, property_group): - """Determine if the lookup_property should be drawn in the Panel""" - vt = Logician(property_group) - if lookup_property in property_group.visibility.keys(): - if hasattr(property_group, lookup_property): - member = getattr(property_group, lookup_property) - else: - member = None - return vt.test_logic(member, - property_group.visibility[lookup_property]) - else: - return True - - def check_enabled(self, lookup_property, property_group): - """Determine if the lookup_property should be enabled in the Panel""" - et = Logician(property_group) - if lookup_property in property_group.enabled.keys(): - if hasattr(property_group, lookup_property): - member = getattr(property_group, lookup_property) - else: - member = None - return et.test_logic(member, - property_group.enabled[lookup_property]) - else: - return True - - def check_alert(self, lookup_property, property_group): - """Determine if the lookup_property should be in an alert state in the Panel""" - et = Logician(property_group) - if lookup_property in property_group.alert.keys(): - if hasattr(property_group, lookup_property): - member = getattr(property_group, lookup_property) - else: - member = None - return et.test_logic(member, - property_group.alert[lookup_property]) - else: - return False - - def is_real_property(self, lookup_property, property_group): - for prop in property_group.properties: - if prop['attr'] == lookup_property: - return prop['type'] not in ['text', 'prop_search'] - - return False - - def draw_column(self, control_list_item, layout, context, - supercontext=None, property_group=None): - """Draw a column's worth of UI controls in this Panel""" - if type(control_list_item) is list: - draw_row = False - - found_percent = None - for sp in control_list_item: - if type(sp) is float: - found_percent = sp - elif type(sp) is list: - for ssp in [s for s in sp if self.is_real_property(s, property_group)]: - draw_row = draw_row or self.check_visibility(ssp, - property_group) - else: - draw_row = draw_row or self.check_visibility(sp, - property_group) - - next_items = [s for s in control_list_item if type(s) in [str, list]] - if draw_row and len(next_items) > 0: - if found_percent is not None: - splt = layout.split(percentage=found_percent) - else: - splt = layout.row(True) - for sp in next_items: - col2 = splt.column() - self.draw_column(sp, col2, context, supercontext, - property_group) - else: - if self.check_visibility(control_list_item, property_group): - - for current_property in property_group.properties: - if current_property['attr'] == control_list_item: - current_property_keys = current_property.keys() - - sub_layout_created = False - if not self.check_enabled(control_list_item, property_group): - last_layout = layout - sub_layout_created = True - - layout = layout.row() - layout.enabled = False - - if self.check_alert(control_list_item, property_group): - if not sub_layout_created: - last_layout = layout - sub_layout_created = True - layout = layout.row() - layout.alert = True - - if 'type' in current_property_keys: - if current_property['type'] in ['int', 'float', - 'float_vector', 'string']: - layout.prop( - property_group, - control_list_item, - text = current_property['name'], - expand = current_property['expand'] \ - if 'expand' in current_property_keys \ - else False, - slider = current_property['slider'] \ - if 'slider' in current_property_keys \ - else False, - toggle = current_property['toggle'] \ - if 'toggle' in current_property_keys \ - else False, - icon_only = current_property['icon_only'] \ - if 'icon_only' in current_property_keys \ - else False, - event = current_property['event'] \ - if 'event' in current_property_keys \ - else False, - full_event = current_property['full_event'] \ - if 'full_event' in current_property_keys \ - else False, - emboss = current_property['emboss'] \ - if 'emboss' in current_property_keys \ - else True, - ) - if current_property['type'] in ['enum']: - if 'use_menu' in current_property_keys and \ - current_property['use_menu']: - layout.prop_menu_enum( - property_group, - control_list_item, - text = current_property['name'] - ) - else: - layout.prop( - property_group, - control_list_item, - text = current_property['name'], - expand = current_property['expand'] \ - if 'expand' in current_property_keys \ - else False, - slider = current_property['slider'] \ - if 'slider' in current_property_keys \ - else False, - toggle = current_property['toggle'] \ - if 'toggle' in current_property_keys \ - else False, - icon_only = current_property['icon_only'] \ - if 'icon_only' in current_property_keys \ - else False, - event = current_property['event'] \ - if 'event' in current_property_keys \ - else False, - full_event = current_property['full_event'] \ - if 'full_event' in current_property_keys \ - else False, - emboss = current_property['emboss'] \ - if 'emboss' in current_property_keys \ - else True, - ) - if current_property['type'] in ['bool']: - layout.prop( - property_group, - control_list_item, - text = current_property['name'], - toggle = current_property['toggle'] \ - if 'toggle' in current_property_keys \ - else False, - icon_only = current_property['icon_only'] \ - if 'icon_only' in current_property_keys \ - else False, - event = current_property['event'] \ - if 'event' in current_property_keys \ - else False, - full_event = current_property['full_event'] \ - if 'full_event' in current_property_keys \ - else False, - emboss = current_property['emboss'] \ - if 'emboss' in current_property_keys \ - else True, - ) - elif current_property['type'] in ['operator']: - args = {} - for optional_arg in ('text', 'icon'): - if optional_arg in current_property_keys: - args.update({ - optional_arg: current_property[optional_arg], - }) - layout.operator( current_property['operator'], **args ) - - elif current_property['type'] in ['menu']: - args = {} - for optional_arg in ('text', 'icon'): - if optional_arg in current_property_keys: - args.update({ - optional_arg: current_property[optional_arg], - }) - layout.menu(current_property['menu'], **args) - - elif current_property['type'] in ['text']: - layout.label( - text = current_property['name'] - ) - - elif current_property['type'] in ['template_list']: - layout.template_list( - current_property['src'](supercontext, context), - current_property['src_attr'], - current_property['trg'](supercontext, context), - current_property['trg_attr'], - rows = 4 \ - if not 'rows' in current_property_keys \ - else current_property['rows'], - maxrows = 4 \ - if not 'rows' in current_property_keys \ - else current_property['rows'], - type = 'DEFAULT' \ - if not 'list_type' in current_property_keys \ - else current_property['list_type'] - ) - - elif current_property['type'] in ['prop_search']: - layout.prop_search( - current_property['trg'](supercontext, - context), - current_property['trg_attr'], - current_property['src'](supercontext, - context), - current_property['src_attr'], - text = current_property['name'], - ) - - elif current_property['type'] in ['ef_callback']: - getattr(self, current_property['method'])(supercontext) - else: - layout.prop(property_group, control_list_item) - - if sub_layout_created: - layout = last_layout - - # Fire a draw callback if specified - if 'draw' in current_property_keys: - current_property['draw'](supercontext, context) - - break + """Mix-in class for sub-classes of bpy.types.Panel. This class + will provide the draw() method which implements drawing one or + more property groups derived from + extensions_framework.declarative_propery_group. + The display_property_groups list attribute describes which + declarative_property_groups should be drawn in the Panel, and + how to extract those groups from the context passed to draw(). + + """ + + """The display_property_groups list attribute specifies which + custom declarative_property_groups this panel should draw, and + where to find that property group in the active context. + Example item: + ( ('scene',), 'myaddon_property_group') + In this case, this renderer will look for properties in + context.scene.myaddon_property_group to draw in the Panel. + + """ + display_property_groups = [] + + def draw(self, context): + """Sub-classes should override this if they need to display + other (object-related) property groups. super().draw(context) + can be a useful call in those cases. + + """ + for property_group_path, property_group_name in \ + self.display_property_groups: + ctx = _get_item_from_context(context, property_group_path) + property_group = getattr(ctx, property_group_name) + for p in property_group.controls: + self.draw_column(p, self.layout, ctx, context, + property_group=property_group) + property_group.draw_callback(context) + + def check_visibility(self, lookup_property, property_group): + """Determine if the lookup_property should be drawn in the Panel""" + vt = Logician(property_group) + if lookup_property in property_group.visibility.keys(): + if hasattr(property_group, lookup_property): + member = getattr(property_group, lookup_property) + else: + member = None + return vt.test_logic(member, + property_group.visibility[lookup_property]) + else: + return True + + def check_enabled(self, lookup_property, property_group): + """Determine if the lookup_property should be enabled in the Panel""" + et = Logician(property_group) + if lookup_property in property_group.enabled.keys(): + if hasattr(property_group, lookup_property): + member = getattr(property_group, lookup_property) + else: + member = None + return et.test_logic(member, + property_group.enabled[lookup_property]) + else: + return True + + def check_alert(self, lookup_property, property_group): + """Determine if the lookup_property should be in an alert state in the Panel""" + et = Logician(property_group) + if lookup_property in property_group.alert.keys(): + if hasattr(property_group, lookup_property): + member = getattr(property_group, lookup_property) + else: + member = None + return et.test_logic(member, + property_group.alert[lookup_property]) + else: + return False + + def is_real_property(self, lookup_property, property_group): + for prop in property_group.properties: + if prop['attr'] == lookup_property: + return prop['type'] not in ['text', 'prop_search'] + + return False + + def draw_column(self, control_list_item, layout, context, + supercontext=None, property_group=None): + """Draw a column's worth of UI controls in this Panel""" + if type(control_list_item) is list: + draw_row = False + + found_percent = None + for sp in control_list_item: + if type(sp) is float: + found_percent = sp + elif type(sp) is list: + for ssp in [s for s in sp if self.is_real_property(s, property_group)]: + draw_row = draw_row or self.check_visibility(ssp, + property_group) + else: + draw_row = draw_row or self.check_visibility(sp, + property_group) + + next_items = [s for s in control_list_item if type(s) in [str, list]] + if draw_row and len(next_items) > 0: + if found_percent is not None: + splt = layout.split(percentage=found_percent) + else: + splt = layout.row(True) + for sp in next_items: + col2 = splt.column() + self.draw_column(sp, col2, context, supercontext, + property_group) + else: + if self.check_visibility(control_list_item, property_group): + + for current_property in property_group.properties: + if current_property['attr'] == control_list_item: + current_property_keys = current_property.keys() + + sub_layout_created = False + if not self.check_enabled(control_list_item, property_group): + last_layout = layout + sub_layout_created = True + + layout = layout.row() + layout.enabled = False + + if self.check_alert(control_list_item, property_group): + if not sub_layout_created: + last_layout = layout + sub_layout_created = True + layout = layout.row() + layout.alert = True + + if 'type' in current_property_keys: + if current_property['type'] in ['int', 'float', + 'float_vector', 'string']: + layout.prop( + property_group, + control_list_item, + text = current_property['name'], + expand = current_property['expand'] \ + if 'expand' in current_property_keys \ + else False, + slider = current_property['slider'] \ + if 'slider' in current_property_keys \ + else False, + toggle = current_property['toggle'] \ + if 'toggle' in current_property_keys \ + else False, + icon_only = current_property['icon_only'] \ + if 'icon_only' in current_property_keys \ + else False, + event = current_property['event'] \ + if 'event' in current_property_keys \ + else False, + full_event = current_property['full_event'] \ + if 'full_event' in current_property_keys \ + else False, + emboss = current_property['emboss'] \ + if 'emboss' in current_property_keys \ + else True, + ) + if current_property['type'] in ['enum']: + if 'use_menu' in current_property_keys and \ + current_property['use_menu']: + layout.prop_menu_enum( + property_group, + control_list_item, + text = current_property['name'] + ) + else: + layout.prop( + property_group, + control_list_item, + text = current_property['name'], + expand = current_property['expand'] \ + if 'expand' in current_property_keys \ + else False, + slider = current_property['slider'] \ + if 'slider' in current_property_keys \ + else False, + toggle = current_property['toggle'] \ + if 'toggle' in current_property_keys \ + else False, + icon_only = current_property['icon_only'] \ + if 'icon_only' in current_property_keys \ + else False, + event = current_property['event'] \ + if 'event' in current_property_keys \ + else False, + full_event = current_property['full_event'] \ + if 'full_event' in current_property_keys \ + else False, + emboss = current_property['emboss'] \ + if 'emboss' in current_property_keys \ + else True, + ) + if current_property['type'] in ['bool']: + layout.prop( + property_group, + control_list_item, + text = current_property['name'], + toggle = current_property['toggle'] \ + if 'toggle' in current_property_keys \ + else False, + icon_only = current_property['icon_only'] \ + if 'icon_only' in current_property_keys \ + else False, + event = current_property['event'] \ + if 'event' in current_property_keys \ + else False, + full_event = current_property['full_event'] \ + if 'full_event' in current_property_keys \ + else False, + emboss = current_property['emboss'] \ + if 'emboss' in current_property_keys \ + else True, + ) + elif current_property['type'] in ['operator']: + args = {} + for optional_arg in ('text', 'icon'): + if optional_arg in current_property_keys: + args.update({ + optional_arg: current_property[optional_arg], + }) + layout.operator( current_property['operator'], **args ) + + elif current_property['type'] in ['menu']: + args = {} + for optional_arg in ('text', 'icon'): + if optional_arg in current_property_keys: + args.update({ + optional_arg: current_property[optional_arg], + }) + layout.menu(current_property['menu'], **args) + + elif current_property['type'] in ['text']: + layout.label( + text = current_property['name'] + ) + + elif current_property['type'] in ['template_list']: + layout.template_list( + current_property['src'](supercontext, context), + current_property['src_attr'], + current_property['trg'](supercontext, context), + current_property['trg_attr'], + rows = 4 \ + if not 'rows' in current_property_keys \ + else current_property['rows'], + maxrows = 4 \ + if not 'rows' in current_property_keys \ + else current_property['rows'], + type = 'DEFAULT' \ + if not 'list_type' in current_property_keys \ + else current_property['list_type'] + ) + + elif current_property['type'] in ['prop_search']: + layout.prop_search( + current_property['trg'](supercontext, + context), + current_property['trg_attr'], + current_property['src'](supercontext, + context), + current_property['src_attr'], + text = current_property['name'], + ) + + elif current_property['type'] in ['ef_callback']: + getattr(self, current_property['method'])(supercontext) + else: + layout.prop(property_group, control_list_item) + + if sub_layout_created: + layout = last_layout + + # Fire a draw callback if specified + if 'draw' in current_property_keys: + current_property['draw'](supercontext, context) + + break diff -Nru blender-2.61/release/scripts/addons/modules/extensions_framework/util.py blender-2.62/release/scripts/addons/modules/extensions_framework/util.py --- blender-2.61/release/scripts/addons/modules/extensions_framework/util.py 2011-12-13 19:58:08.000000000 +0000 +++ blender-2.62/release/scripts/addons/modules/extensions_framework/util.py 2012-02-15 19:42:39.000000000 +0000 @@ -49,222 +49,222 @@ export_path = ''; def path_relative_to_export(p): - """Return a path that is relative to the export path""" - global export_path - p = filesystem_path(p) - ep = os.path.dirname(export_path) - - if os.sys.platform[:3] == "win": - # Prevent an error whereby python thinks C: and c: are different drives - if p[1] == ':': p = p[0].lower() + p[1:] - if ep[1] == ':': ep = ep[0].lower() + ep[1:] - - try: - relp = os.path.relpath(p, ep) - except ValueError: # path on different drive on windows - relp = p - - return relp.replace('\\', '/') + """Return a path that is relative to the export path""" + global export_path + p = filesystem_path(p) + ep = os.path.dirname(export_path) + + if os.sys.platform[:3] == "win": + # Prevent an error whereby python thinks C: and c: are different drives + if p[1] == ':': p = p[0].lower() + p[1:] + if ep[1] == ':': ep = ep[0].lower() + ep[1:] + + try: + relp = os.path.relpath(p, ep) + except ValueError: # path on different drive on windows + relp = p + + return relp.replace('\\', '/') def filesystem_path(p): - """Resolve a relative Blender path to a real filesystem path""" - if p.startswith('//'): - pout = bpy.path.abspath(p) - else: - pout = os.path.realpath(p) - - return pout.replace('\\', '/') + """Resolve a relative Blender path to a real filesystem path""" + if p.startswith('//'): + pout = bpy.path.abspath(p) + else: + pout = os.path.realpath(p) + + return pout.replace('\\', '/') # TODO: - somehow specify TYPES to get/set from config def find_config_value(module, section, key, default): - """Attempt to find the configuration value specified by string key - in the specified section of module's configuration file. If it is - not found, return default. - - """ - global config_paths - fc = [] - for p in config_paths: - if os.path.exists(p) and os.path.isdir(p) and os.access(p, os.W_OK): - fc.append( '/'.join([p, '%s.cfg' % module])) - - if len(fc) < 1: - print('Cannot find %s config file path' % module) - return default - - cp = configparser.SafeConfigParser() - - cfg_files = cp.read(fc) - if len(cfg_files) > 0: - try: - val = cp.get(section, key) - if val == 'true': - return True - elif val == 'false': - return False - else: - return val - except: - return default - else: - return default + """Attempt to find the configuration value specified by string key + in the specified section of module's configuration file. If it is + not found, return default. + + """ + global config_paths + fc = [] + for p in config_paths: + if os.path.exists(p) and os.path.isdir(p) and os.access(p, os.W_OK): + fc.append( '/'.join([p, '%s.cfg' % module])) + + if len(fc) < 1: + print('Cannot find %s config file path' % module) + return default + + cp = configparser.SafeConfigParser() + + cfg_files = cp.read(fc) + if len(cfg_files) > 0: + try: + val = cp.get(section, key) + if val == 'true': + return True + elif val == 'false': + return False + else: + return val + except: + return default + else: + return default def write_config_value(module, section, key, value): - """Attempt to write the configuration value specified by string key - in the specified section of module's configuration file. - - """ - global config_paths - fc = [] - for p in config_paths: - if os.path.exists(p) and os.path.isdir(p) and os.access(p, os.W_OK): - fc.append( '/'.join([p, '%s.cfg' % module])) - - if len(fc) < 1: - raise Exception('Cannot find a writable path to store %s config file' % - module) - - cp = configparser.SafeConfigParser() - - cfg_files = cp.read(fc) - - if not cp.has_section(section): - cp.add_section(section) - - if value == True: - cp.set(section, key, 'true') - elif value == False: - cp.set(section, key, 'false') - else: - cp.set(section, key, value) - - if len(cfg_files) < 1: - cfg_files = fc - - fh=open(cfg_files[0],'w') - cp.write(fh) - fh.close() - - return True + """Attempt to write the configuration value specified by string key + in the specified section of module's configuration file. + + """ + global config_paths + fc = [] + for p in config_paths: + if os.path.exists(p) and os.path.isdir(p) and os.access(p, os.W_OK): + fc.append( '/'.join([p, '%s.cfg' % module])) + + if len(fc) < 1: + raise Exception('Cannot find a writable path to store %s config file' % + module) + + cp = configparser.SafeConfigParser() + + cfg_files = cp.read(fc) + + if not cp.has_section(section): + cp.add_section(section) + + if value == True: + cp.set(section, key, 'true') + elif value == False: + cp.set(section, key, 'false') + else: + cp.set(section, key, value) + + if len(cfg_files) < 1: + cfg_files = fc + + fh=open(cfg_files[0],'w') + cp.write(fh) + fh.close() + + return True def scene_filename(): - """Construct a safe scene filename, using 'untitled' instead of ''""" - filename = os.path.splitext(os.path.basename(bpy.data.filepath))[0] - if filename == '': - filename = 'untitled' - return bpy.path.clean_name(filename) + """Construct a safe scene filename, using 'untitled' instead of ''""" + filename = os.path.splitext(os.path.basename(bpy.data.filepath))[0] + if filename == '': + filename = 'untitled' + return bpy.path.clean_name(filename) def temp_directory(): - """Return the system temp directory""" - return tempfile.gettempdir() + """Return the system temp directory""" + return tempfile.gettempdir() def temp_file(ext='tmp'): - """Get a temporary filename with the given extension. This function - will actually attempt to create the file.""" - tf, fn = tempfile.mkstemp(suffix='.%s'%ext) - os.close(tf) - return fn + """Get a temporary filename with the given extension. This function + will actually attempt to create the file.""" + tf, fn = tempfile.mkstemp(suffix='.%s'%ext) + os.close(tf) + return fn class TimerThread(threading.Thread): - """Periodically call self.kick(). The period of time in seconds - between calling is given by self.KICK_PERIOD, and the first call - may be delayed by setting self.STARTUP_DELAY, also in seconds. - self.kick() will continue to be called at regular intervals until - self.stop() is called. Since this is a thread, calling self.join() - may be wise after calling self.stop() if self.kick() is performing - a task necessary for the continuation of the program. - The object that creates this TimerThread may pass into it data - needed during self.kick() as a dict LocalStorage in __init__(). - - """ - STARTUP_DELAY = 0 - KICK_PERIOD = 8 - - active = True - timer = None - - LocalStorage = None - - def __init__(self, LocalStorage=dict()): - threading.Thread.__init__(self) - self.LocalStorage = LocalStorage - - def set_kick_period(self, period): - """Adjust the KICK_PERIOD between __init__() and start()""" - self.KICK_PERIOD = period + self.STARTUP_DELAY - - def stop(self): - """Stop this timer. This method does not join()""" - self.active = False - if self.timer is not None: - self.timer.cancel() - - def run(self): - """Timed Thread loop""" - while self.active: - self.timer = threading.Timer(self.KICK_PERIOD, self.kick_caller) - self.timer.start() - if self.timer.isAlive(): self.timer.join() - - def kick_caller(self): - """Intermediary between the kick-wait-loop and kick to allow - adjustment of the first KICK_PERIOD by STARTUP_DELAY - - """ - if self.STARTUP_DELAY > 0: - self.KICK_PERIOD -= self.STARTUP_DELAY - self.STARTUP_DELAY = 0 - - self.kick() - - def kick(self): - """Sub-classes do their work here""" - pass + """Periodically call self.kick(). The period of time in seconds + between calling is given by self.KICK_PERIOD, and the first call + may be delayed by setting self.STARTUP_DELAY, also in seconds. + self.kick() will continue to be called at regular intervals until + self.stop() is called. Since this is a thread, calling self.join() + may be wise after calling self.stop() if self.kick() is performing + a task necessary for the continuation of the program. + The object that creates this TimerThread may pass into it data + needed during self.kick() as a dict LocalStorage in __init__(). + + """ + STARTUP_DELAY = 0 + KICK_PERIOD = 8 + + active = True + timer = None + + LocalStorage = None + + def __init__(self, LocalStorage=dict()): + threading.Thread.__init__(self) + self.LocalStorage = LocalStorage + + def set_kick_period(self, period): + """Adjust the KICK_PERIOD between __init__() and start()""" + self.KICK_PERIOD = period + self.STARTUP_DELAY + + def stop(self): + """Stop this timer. This method does not join()""" + self.active = False + if self.timer is not None: + self.timer.cancel() + + def run(self): + """Timed Thread loop""" + while self.active: + self.timer = threading.Timer(self.KICK_PERIOD, self.kick_caller) + self.timer.start() + if self.timer.isAlive(): self.timer.join() + + def kick_caller(self): + """Intermediary between the kick-wait-loop and kick to allow + adjustment of the first KICK_PERIOD by STARTUP_DELAY + + """ + if self.STARTUP_DELAY > 0: + self.KICK_PERIOD -= self.STARTUP_DELAY + self.STARTUP_DELAY = 0 + + self.kick() + + def kick(self): + """Sub-classes do their work here""" + pass def format_elapsed_time(t): - """Format a duration in seconds as an HH:MM:SS format time""" - - td = datetime.timedelta(seconds=t) - min = td.days*1440 + td.seconds/60.0 - hrs = td.days*24 + td.seconds/3600.0 - - return '%i:%02i:%02i' % (hrs, min%60, td.seconds%60) + """Format a duration in seconds as an HH:MM:SS format time""" + + td = datetime.timedelta(seconds=t) + min = td.days*1440 + td.seconds/60.0 + hrs = td.days*24 + td.seconds/3600.0 + + return '%i:%02i:%02i' % (hrs, min%60, td.seconds%60) def getSequenceTexturePath(it, f): - import bpy.path - import os.path - import string - fd = it.image_user.frame_duration - fs = it.image_user.frame_start - fo = it.image_user.frame_offset - cyclic = it.image_user.use_cyclic - ext = os.path.splitext(it.image.filepath)[-1] - fb = bpy.path.display_name_from_filepath(it.image.filepath) - dn = os.path.dirname(it.image.filepath) - rf = fb[::-1] - nl = 0 - for i in range (len(fb)): - if rf[i] in string.digits: - nl += 1 - else: - break - head = fb[:len(fb)-nl] - fnum = f - if fs != 1: - if f != fs: - fnum -= (fs-1) - elif f == fs: - fnum = 1 - if fnum <= 0: - if cyclic: - fnum = fd - abs(fnum) % fd - else: - fnum = 1 - elif fnum > fd: - if cyclic: - fnum = fnum % fd - else: - fnum = fd - fnum += fo - return dn + "/" + head + str(fnum).rjust(nl, "0") + ext + import bpy.path + import os.path + import string + fd = it.image_user.frame_duration + fs = it.image_user.frame_start + fo = it.image_user.frame_offset + cyclic = it.image_user.use_cyclic + ext = os.path.splitext(it.image.filepath)[-1] + fb = bpy.path.display_name_from_filepath(it.image.filepath) + dn = os.path.dirname(it.image.filepath) + rf = fb[::-1] + nl = 0 + for i in range (len(fb)): + if rf[i] in string.digits: + nl += 1 + else: + break + head = fb[:len(fb)-nl] + fnum = f + if fs != 1: + if f != fs: + fnum -= (fs-1) + elif f == fs: + fnum = 1 + if fnum <= 0: + if cyclic: + fnum = fd - abs(fnum) % fd + else: + fnum = 1 + elif fnum > fd: + if cyclic: + fnum = fnum % fd + else: + fnum = fd + fnum += fo + return dn + "/" + head + str(fnum).rjust(nl, "0") + ext diff -Nru blender-2.61/release/scripts/addons/modules/extensions_framework/validate.py blender-2.62/release/scripts/addons/modules/extensions_framework/validate.py --- blender-2.61/release/scripts/addons/modules/extensions_framework/validate.py 2011-12-13 19:58:08.000000000 +0000 +++ blender-2.62/release/scripts/addons/modules/extensions_framework/validate.py 2012-02-15 19:42:39.000000000 +0000 @@ -34,13 +34,13 @@ A Subject can be any object whose members are readable with getattr() : class Subject(object): - a = 0 - b = 1 - c = 'foo' - d = True - e = False - f = 8 - g = 'bar' + a = 0 + b = 1 + c = 'foo' + d = True + e = False + f = 8 + g = 'bar' Tests are described thus: @@ -51,27 +51,27 @@ With regards to Subject, each of these evaluate to True: TESTA = { - 'a': 0, - 'c': Logic_OR([ 'foo', 'bar' ]), - 'd': Logic_AND([True, True]), - 'f': Logic_AND([8, {'b': 1}]), - 'e': {'b': Logic_Operator({'gte':1, 'lt':3}) }, - 'g': Logic_OR([ 'baz', Logic_AND([{'b': 1}, {'f': 8}]) ]) + 'a': 0, + 'c': Logic_OR([ 'foo', 'bar' ]), + 'd': Logic_AND([True, True]), + 'f': Logic_AND([8, {'b': 1}]), + 'e': {'b': Logic_Operator({'gte':1, 'lt':3}) }, + 'g': Logic_OR([ 'baz', Logic_AND([{'b': 1}, {'f': 8}]) ]) } With regards to Subject, each of these evaluate to False: TESTB = { - 'a': 'foo', - 'c': Logic_OR([ 'bar', 'baz' ]), - 'd': Logic_AND([ True, 'foo' ]), - 'f': Logic_AND([9, {'b': 1}]), - 'e': {'b': Logic_Operator({'gte':-10, 'lt': 1}) }, - 'g': Logic_OR([ 'baz', Logic_AND([{'b':0}, {'f': 8}]) ]) + 'a': 'foo', + 'c': Logic_OR([ 'bar', 'baz' ]), + 'd': Logic_AND([ True, 'foo' ]), + 'f': Logic_AND([9, {'b': 1}]), + 'e': {'b': Logic_Operator({'gte':-10, 'lt': 1}) }, + 'g': Logic_OR([ 'baz', Logic_AND([{'b':0}, {'f': 8}]) ]) } With regards to Subject, this test is invalid TESTC = { - 'n': 0 + 'n': 0 } Tests are executed thus: @@ -82,132 +82,132 @@ """ class Logic_AND(list): - pass + pass class Logic_OR(list): - pass + pass class Logic_Operator(dict): - pass + pass class Logician(object): - """Given a subject and a dict that describes tests to perform on - its members, this class will evaluate True or False results for - each member/test pair. See the examples below for test syntax. - - """ - - subject = None - def __init__(self, subject): - self.subject = subject - - def get_member(self, member_name): - """Get a member value from the subject object. Raise exception - if subject is None or member not found. - - """ - if self.subject is None: - raise Exception('Cannot run tests on a subject which is None') - - return getattr(self.subject, member_name) - - def test_logic(self, member, logic, operator='eq'): - """Find the type of test to run on member, and perform that test""" - - if type(logic) is dict: - return self.test_dict(member, logic) - elif type(logic) is Logic_AND: - return self.test_and(member, logic) - elif type(logic) is Logic_OR: - return self.test_or(member, logic) - elif type(logic) is Logic_Operator: - return self.test_operator(member, logic) - else: - # compare the value, I think using Logic_Operator() here - # allows completeness in test_operator(), but I can't put - # my finger on why for the minute - return self.test_operator(member, - Logic_Operator({operator: logic})) - - def test_operator(self, member, value): - """Execute the operators contained within value and expect that - ALL operators are True - - """ - - # something in this method is incomplete, what if operand is - # a dict, Logic_AND, Logic_OR or another Logic_Operator ? - # Do those constructs even make any sense ? - - result = True - for operator, operand in value.items(): - operator = operator.lower().strip() - if operator in ['eq', '==']: - result &= member==operand - if operator in ['not', '!=']: - result &= member!=operand - if operator in ['lt', '<']: - result &= member']: - result &= member>operand - if operator in ['gte', '>=']: - result &= member>=operand - if operator in ['and', '&']: - result &= member&operand - if operator in ['or', '|']: - result &= member|operand - if operator in ['len']: - result &= len(member)==operand - # I can think of some more, but they're probably not useful. - - return result - - def test_or(self, member, logic): - """Member is a value, logic is a set of values, ANY of which - can be True - - """ - result = False - for test in logic: - result |= self.test_logic(member, test) - - return result - - def test_and(self, member, logic): - """Member is a value, logic is a list of values, ALL of which - must be True - - """ - result = True - for test in logic: - result &= self.test_logic(member, test) - - return result - - def test_dict(self, member, logic): - """Member is a value, logic is a dict of other members to - compare to. All other member tests must be True - - """ - result = True - for other_member, test in logic.items(): - result &= self.test_logic(self.get_member(other_member), test) - - return result - - def execute(self, test): - """Subject is an object, test is a dict of {member: test} pairs - to perform on subject's members. Wach key in test is a member - of subject. - - """ - - for member_name, logic in test.items(): - result = self.test_logic(self.get_member(member_name), logic) - print('member %s is %s' % (member_name, result)) + """Given a subject and a dict that describes tests to perform on + its members, this class will evaluate True or False results for + each member/test pair. See the examples below for test syntax. + + """ + + subject = None + def __init__(self, subject): + self.subject = subject + + def get_member(self, member_name): + """Get a member value from the subject object. Raise exception + if subject is None or member not found. + + """ + if self.subject is None: + raise Exception('Cannot run tests on a subject which is None') + + return getattr(self.subject, member_name) + + def test_logic(self, member, logic, operator='eq'): + """Find the type of test to run on member, and perform that test""" + + if type(logic) is dict: + return self.test_dict(member, logic) + elif type(logic) is Logic_AND: + return self.test_and(member, logic) + elif type(logic) is Logic_OR: + return self.test_or(member, logic) + elif type(logic) is Logic_Operator: + return self.test_operator(member, logic) + else: + # compare the value, I think using Logic_Operator() here + # allows completeness in test_operator(), but I can't put + # my finger on why for the minute + return self.test_operator(member, + Logic_Operator({operator: logic})) + + def test_operator(self, member, value): + """Execute the operators contained within value and expect that + ALL operators are True + + """ + + # something in this method is incomplete, what if operand is + # a dict, Logic_AND, Logic_OR or another Logic_Operator ? + # Do those constructs even make any sense ? + + result = True + for operator, operand in value.items(): + operator = operator.lower().strip() + if operator in ['eq', '==']: + result &= member==operand + if operator in ['not', '!=']: + result &= member!=operand + if operator in ['lt', '<']: + result &= member']: + result &= member>operand + if operator in ['gte', '>=']: + result &= member>=operand + if operator in ['and', '&']: + result &= member&operand + if operator in ['or', '|']: + result &= member|operand + if operator in ['len']: + result &= len(member)==operand + # I can think of some more, but they're probably not useful. + + return result + + def test_or(self, member, logic): + """Member is a value, logic is a set of values, ANY of which + can be True + + """ + result = False + for test in logic: + result |= self.test_logic(member, test) + + return result + + def test_and(self, member, logic): + """Member is a value, logic is a list of values, ALL of which + must be True + + """ + result = True + for test in logic: + result &= self.test_logic(member, test) + + return result + + def test_dict(self, member, logic): + """Member is a value, logic is a dict of other members to + compare to. All other member tests must be True + + """ + result = True + for other_member, test in logic.items(): + result &= self.test_logic(self.get_member(other_member), test) + + return result + + def execute(self, test): + """Subject is an object, test is a dict of {member: test} pairs + to perform on subject's members. Wach key in test is a member + of subject. + + """ + + for member_name, logic in test.items(): + result = self.test_logic(self.get_member(member_name), logic) + print('member %s is %s' % (member_name, result)) -# A couple of name aliases +# A couple of name aliases class Validation(Logician): - pass + pass class Visibility(Logician): - pass + pass diff -Nru blender-2.61/release/scripts/addons/modules/selection_utils.py blender-2.62/release/scripts/addons/modules/selection_utils.py --- blender-2.61/release/scripts/addons/modules/selection_utils.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons/modules/selection_utils.py 2012-02-15 19:42:39.000000000 +0000 @@ -0,0 +1,80 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the 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. +# +# ##### END GPL LICENSE BLOCK ##### + +# + +# Contributors: Mackraken, Andrew Hale (TrumanBlending) +# Adapted from Mackraken's "Tools for Curves" addon + +import bpy + +selected = [] + + +class SelectionOrder(bpy.types.Operator): + '''Store the object names in the order they are selected. + Use RETURN key to confirm selection, ESCAPE key to cancel''' + bl_idname = "object.select_order" + bl_label = "Select with Order" + bl_options = {'UNDO'} + + num_selected = 0 + + @classmethod + def poll(self, context): + return bpy.context.mode == 'OBJECT' + + def update(self, context): + # Get the currently selected objects + sel = context.selected_objects + num = len(sel) + + if num == 0: + # Reset the list + selected[:] = [] + elif num > self.num_selected: + # Get all the newly selected objects and add + new = [ob.name for ob in sel if ob.name not in selected] + selected.extend(new) + elif num < self.num_selected: + # Get the selected objects and remove from list + curnames = {ob.name for ob in sel} + selected[:] = [name for name in selected if name in curnames] + + # Set the number of currently select objects + self.num_selected = len(selected) + + def modal(self, context, event): + if event.type == 'RET': + # If return is pressed, finish the operator + return {'FINISHED'} + elif event.type == 'ESC': + # If escape is pressed, cancel the operator + return {'CANCELLED'} + + # Update selection if we need to + self.update(context) + return {'PASS_THROUGH'} + + def invoke(self, context, event): + context.window_manager.modal_handler_add(self) + self.update(context) + return {'RUNNING_MODAL'} + + +bpy.utils.register_module(__name__) diff -Nru blender-2.61/release/scripts/addons/netrender/baking.py blender-2.62/release/scripts/addons/netrender/baking.py --- blender-2.61/release/scripts/addons/netrender/baking.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons/netrender/baking.py 2012-02-15 19:43:14.000000000 +0000 @@ -0,0 +1,145 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the 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. +# +# ##### END GPL LICENSE BLOCK ##### + +import bpy +import sys, subprocess, re + +from netrender.utils import * + +BLENDER_PATH = sys.argv[0] + +def commandToTask(command): + i = command.index("|") + ri = command.rindex("|") + return (command[:i], command[i+1:ri], command[ri+1:]) + +def taskToCommand(task): + return "|".join(task) + +def bake(job, tasks): + main_file = job.files[0] + job_full_path = main_file.filepath + + task_commands = [] + for task in tasks: + task_commands.extend(task) + + process = subprocess.Popen([BLENDER_PATH, "-b", "-noaudio", job_full_path, "-P", __file__, "--"] + task_commands, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + + return process + +result_pattern = re.compile("BAKE FILE\[ ([0-9]+) \]: (.*)") +def resultsFromOuput(lines): + results = [] + for line in lines: + match = result_pattern.match(line) + + if match: + task_id = int(match.groups()[0]) + task_filename = match.groups()[1] + + results.append((task_id, task_filename)) + + return results + +def bake_cache(obj, point_cache, task_index): + if point_cache.is_baked: + bpy.ops.ptcache.free_bake({"point_cache": point_cache}) + + point_cache.use_disk_cache = True + point_cache.use_external = False + + bpy.ops.ptcache.bake({"point_cache": point_cache}, bake=True) + + results = cache_results(obj, point_cache) + + print() + + for filename in results: + print("BAKE FILE[", task_index, "]:", filename) + + +def cache_results(obj, point_cache): + name = cacheName(obj, point_cache) + default_path = cachePath(bpy.data.filepath) + + cache_path = bpy.path.abspath(point_cache.filepath) if point_cache.use_external else default_path + + index = "%02i" % point_cache.index + + if os.path.exists(cache_path): + pattern = re.compile(name + "_([0-9]+)_" + index + "\.bphys") + + cache_files = [] + + for cache_file in sorted(os.listdir(cache_path)): + match = pattern.match(cache_file) + + if match: + cache_files.append(os.path.join(cache_path, cache_file)) + + cache_files.sort() + + return cache_files + + return [] + +def process_generic(obj, index, task_index): + modifier = obj.modifiers[index] + point_cache = modifier.point_cache + bake_cache(obj, point_cache, task_index) + +def process_smoke(obj, index, task_index): + modifier = obj.modifiers[index] + point_cache = modifier.domain_settings.point_cache + bake_cache(obj, point_cache, task_index) + +def process_particle(obj, index, task_index): + psys = obj.particle_systems[index] + point_cache = psys.point_cache + bake_cache(obj, point_cache, task_index) + +def process_paint(obj, index, task_index): + modifier = obj.modifiers[index] + for surface in modifier.canvas_settings.canvas_surfaces: + bake_cache(obj, surface.point_cache, task_index) + +def process_null(obj, index, task_index): + raise ValueException("No baking possible with arguments: " + " ".join(sys.argv)) + +process_funcs = {} +process_funcs["CLOTH"] = process_generic +process_funcs["SOFT_BODY"] = process_generic +process_funcs["PARTICLE_SYSTEM"] = process_particle +process_funcs["SMOKE"] = process_smoke +process_funcs["DYNAMIC_PAINT"] = process_paint + +if __name__ == "__main__": + try: + i = sys.argv.index("--") + except: + i = 0 + + if i: + task_args = sys.argv[i+1:] + for i in range(0, len(task_args), 3): + bake_type = task_args[i] + obj = bpy.data.objects[task_args[i+1]] + index = int(task_args[i+2]) + + process_funcs.get(bake_type, process_null)(obj, index, i) diff -Nru blender-2.61/release/scripts/addons/netrender/balancing.py blender-2.62/release/scripts/addons/netrender/balancing.py --- blender-2.61/release/scripts/addons/netrender/balancing.py 2011-12-13 19:58:44.000000000 +0000 +++ blender-2.62/release/scripts/addons/netrender/balancing.py 2012-02-15 19:43:14.000000000 +0000 @@ -24,6 +24,7 @@ class RatingRule: def __init__(self): self.enabled = True + self.editable = False def id(self): return str(id(self)) @@ -34,7 +35,7 @@ class ExclusionRule: def __init__(self): self.enabled = True - + self.editable = True def id(self): return str(id(self)) @@ -44,7 +45,7 @@ class PriorityRule: def __init__(self): self.enabled = True - + self.editable = True def id(self): return str(id(self)) @@ -118,6 +119,13 @@ def rate(self, job): # less usage is better return job.usage / job.priority + def serialize(self): + return { "type": "rating", + "enabled": self.enabled, + "descritpiton":str(self), + "limit":"", + "id":self.id() + } class RatingUsageByCategory(RatingRule): def __init__(self, get_jobs): @@ -134,6 +142,16 @@ # less usage is better return total_category_usage / maximum_priority + def serialize(self): + return { "type": "rating", + "enabled": self.enabled, + "editable": self.editable, + "descritpiton":str(self), + "limit":"", + "id":self.id() + } + + class NewJobPriority(PriorityRule): def __init__(self, limit = 1): super().__init__() @@ -149,7 +167,16 @@ return "Priority to new jobs" def test(self, job): - return job.countFrames(status = DONE) < self.limit + return job.countFrames(status = FRAME_DONE) < self.limit + def serialize(self): + return { "type": "priority", + "enabled": self.enabled, + "editable": self.editable, + "descritpiton":str(self), + "limit": self.limit, + "limit_str":self.str_limit(), + "id":self.id() + } class MinimumTimeBetweenDispatchPriority(PriorityRule): def __init__(self, limit = 10): @@ -166,14 +193,38 @@ return "Priority to jobs that haven't been dispatched recently" def test(self, job): - return job.countFrames(status = DISPATCHED) == 0 and (time.time() - job.last_dispatched) / 60 > self.limit + return job.countFrames(status = FRAME_DISPATCHED) == 0 and (time.time() - job.last_dispatched) / 60 > self.limit + + def serialize(self): + return { "type": "priority", + "enabled": self.enabled, + "editable": self.editable, + "descritpiton":str(self), + "limit": self.limit, + "limit_str":self.str_limit(), + "id":self.id() + + } class ExcludeQueuedEmptyJob(ExclusionRule): + def __init__(self): + super().__init__() + self.editable= False def __str__(self): return "Exclude non queued or empty jobs" def test(self, job): - return job.status != JOB_QUEUED or job.countFrames(status = QUEUED) == 0 + return job.status != JOB_QUEUED or job.countFrames(status = FRAME_QUEUED) == 0 + + def serialize(self): + return { "type": "exception", + "enabled": self.enabled, + "editable": self.editable, + "descritpiton":str(self), + "limit": "", + "limit_str":"", + "id":self.id() + } class ExcludeSlavesLimit(ExclusionRule): def __init__(self, count_jobs, count_slaves, limit = 0.75): @@ -193,3 +244,13 @@ def test(self, job): return not ( self.count_jobs() == 1 or self.count_slaves() <= 1 or float(job.countSlaves() + 1) / self.count_slaves() <= self.limit ) + + def serialize(self): + return { "type": "exception", + "enabled": self.enabled, + "editable": self.editable, + "descritpiton":str(self), + "limit": self.limit, + "limit_str":self.str_limit(), + "id":self.id() + } diff -Nru blender-2.61/release/scripts/addons/netrender/client.py blender-2.62/release/scripts/addons/netrender/client.py --- blender-2.61/release/scripts/addons/netrender/client.py 2011-12-13 19:58:44.000000000 +0000 +++ blender-2.62/release/scripts/addons/netrender/client.py 2012-02-15 19:43:14.000000000 +0000 @@ -39,16 +39,14 @@ # fluid frames starts at 0, which explains the +1 # This is stupid current_frame = int(match.groups()[1]) + 1 - job.addFile(path + fluid_file, current_frame, current_frame) + job.addFile(os.path.join(path, fluid_file), current_frame, current_frame) def addPointCache(job, ob, point_cache, default_path): if not point_cache.use_disk_cache: return - name = point_cache.name - if name == "": - name = "".join(["%02X" % ord(c) for c in ob.name]) + name = cacheName(ob, point_cache) cache_path = bpy.path.abspath(point_cache.filepath) if point_cache.use_external else default_path @@ -70,7 +68,7 @@ if len(cache_files) == 1: cache_frame, cache_file = cache_files[0] - job.addFile(cache_path + cache_file, cache_frame, cache_frame) + job.addFile(os.path.join(cache_path, cache_file), cache_frame, cache_frame) else: for i in range(len(cache_files)): current_item = cache_files[i] @@ -79,18 +77,18 @@ current_frame, current_file = current_item - if not next_item and not previous_item: - job.addFile(cache_path + current_file, current_frame, current_frame) + if not next_item and not previous_item: + job.addFile(os.path.join(cache_path, current_file), current_frame, current_frame) elif next_item and not previous_item: next_frame = next_item[0] - job.addFile(cache_path + current_file, current_frame, next_frame - 1) + job.addFile(os.path.join(cache_path, current_file), current_frame, next_frame) elif not next_item and previous_item: previous_frame = previous_item[0] - job.addFile(cache_path + current_file, previous_frame + 1, current_frame) + job.addFile(os.path.join(cache_path, current_file), previous_frame, current_frame) else: next_frame = next_item[0] previous_frame = previous_item[0] - job.addFile(cache_path + current_file, previous_frame + 1, next_frame - 1) + job.addFile(os.path.join(cache_path, current_file), previous_frame, next_frame) def fillCommonJobSettings(job, job_name, netsettings): job.name = job_name @@ -101,7 +99,12 @@ job.chunks = netsettings.chunks job.priority = netsettings.priority - + + if netsettings.job_render_engine == "OTHER": + job.render = netsettings.job_render_engine_other + else: + job.render = netsettings.job_render_engine + if netsettings.job_type == "JOB_BLENDER": job.type = netrender.model.JOB_BLENDER elif netsettings.job_type == "JOB_PROCESS": @@ -109,14 +112,14 @@ elif netsettings.job_type == "JOB_VCS": job.type = netrender.model.JOB_VCS -def clientSendJob(conn, scene, anim = False): +def sendJob(conn, scene, anim = False, can_save = True): netsettings = scene.network_render if netsettings.job_type == "JOB_BLENDER": - return clientSendJobBlender(conn, scene, anim) + return sendJobBlender(conn, scene, anim, can_save) elif netsettings.job_type == "JOB_VCS": - return clientSendJobVCS(conn, scene, anim) + return sendJobVCS(conn, scene, anim) -def clientSendJobVCS(conn, scene, anim = False): +def sendJobVCS(conn, scene, anim = False): netsettings = scene.network_render job = netrender.model.RenderJob() @@ -137,8 +140,6 @@ if filename[0] in (os.sep, os.altsep): filename = filename[1:] - print("CREATING VCS JOB", filename) - job.addFile(filename, signed=False) job_name = netsettings.job_name @@ -155,6 +156,8 @@ job.version_info.wpath = netsettings.vcs_wpath job.version_info.rpath = netsettings.vcs_rpath job.version_info.revision = netsettings.vcs_revision + + job.tags.add(netrender.model.TAG_RENDER) # try to send path first with ConnectionContext(): @@ -168,7 +171,87 @@ return job_id -def clientSendJobBlender(conn, scene, anim = False): +def sendJobBaking(conn, scene, can_save = True): + netsettings = scene.network_render + job = netrender.model.RenderJob() + + filename = bpy.data.filepath + + if not os.path.exists(filename): + raise RuntimeError("Current file path not defined\nSave your file before sending a job") + + if can_save and netsettings.save_before_job: + bpy.ops.wm.save_mainfile(filepath=filename, check_existing=False) + + job.addFile(filename) + + job_name = netsettings.job_name + path, name = os.path.split(filename) + if job_name == "[default]": + job_name = name + + ############################### + # LIBRARIES (needed for baking) + ############################### + for lib in bpy.data.libraries: + file_path = bpy.path.abspath(lib.filepath) + if os.path.exists(file_path): + job.addFile(file_path) + + tasks = set() + + #################################### + # FLUID + POINT CACHE (what we bake) + #################################### + def pointCacheFunc(object, owner, point_cache): + if type(owner) == bpy.types.ParticleSystem: + index = [index for index, data in enumerate(object.particle_systems) if data == owner][0] + tasks.add(("PARTICLE_SYSTEM", object.name, str(index))) + else: # owner is modifier + index = [index for index, data in enumerate(object.modifiers) if data == owner][0] + tasks.add((owner.type, object.name, str(index))) + + def fluidFunc(object, modifier, cache_path): + pass + + def multiresFunc(object, modifier, cache_path): + pass + + processObjectDependencies(pointCacheFunc, fluidFunc, multiresFunc) + + fillCommonJobSettings(job, job_name, netsettings) + + job.tags.add(netrender.model.TAG_BAKING) + job.subtype = netrender.model.JOB_SUB_BAKING + job.chunks = 1 # No chunking for baking + + for i, task in enumerate(tasks): + job.addFrame(i + 1) + job.frames[-1].command = netrender.baking.taskToCommand(task) + + # try to send path first + with ConnectionContext(): + conn.request("POST", "/job", json.dumps(job.serialize())) + response = conn.getresponse() + response.read() + + job_id = response.getheader("job-id") + + # if not ACCEPTED (but not processed), send files + if response.status == http.client.ACCEPTED: + for rfile in job.files: + f = open(rfile.filepath, "rb") + with ConnectionContext(): + conn.request("PUT", fileURL(job_id, rfile.index), f) + f.close() + response = conn.getresponse() + response.read() + + # server will reply with ACCEPTED until all files are found + + return job_id + +def sendJobBlender(conn, scene, anim = False, can_save = True): netsettings = scene.network_render job = netrender.model.RenderJob() @@ -179,10 +262,13 @@ job.addFrame(scene.frame_current) filename = bpy.data.filepath - + if not os.path.exists(filename): raise RuntimeError("Current file path not defined\nSave your file before sending a job") + if can_save and netsettings.save_before_job: + bpy.ops.wm.save_mainfile(filepath=filename, check_existing=False) + job.addFile(filename) job_name = netsettings.job_name @@ -214,31 +300,24 @@ ########################### # FLUID + POINT CACHE ########################### - root, ext = os.path.splitext(name) - default_path = path + os.sep + "blendcache_" + root + os.sep # need an API call for that - - for object in bpy.data.objects: - for modifier in object.modifiers: - if modifier.type == 'FLUID_SIMULATION' and modifier.settings.type == "DOMAIN": - addFluidFiles(job, bpy.path.abspath(modifier.settings.filepath)) - elif modifier.type == "CLOTH": - addPointCache(job, object, modifier.point_cache, default_path) - elif modifier.type == "SOFT_BODY": - addPointCache(job, object, modifier.point_cache, default_path) - elif modifier.type == "SMOKE" and modifier.smoke_type == "TYPE_DOMAIN": - addPointCache(job, object, modifier.domain_settings.point_cache, default_path) - elif modifier.type == "MULTIRES" and modifier.is_external: - file_path = bpy.path.abspath(modifier.filepath) - job.addFile(file_path) - - # particles modifier are stupid and don't contain data - # we have to go through the object property - for psys in object.particle_systems: - addPointCache(job, object, psys.point_cache, default_path) + default_path = cachePath(filename) + + def pointCacheFunc(object, owner, point_cache): + addPointCache(job, object, point_cache, default_path) + + def fluidFunc(object, modifier, cache_path): + addFluidFiles(job, cache_path) + + def multiresFunc(object, modifier, cache_path): + job.addFile(cache_path) + + processObjectDependencies(pointCacheFunc, fluidFunc, multiresFunc) #print(job.files) fillCommonJobSettings(job, job_name, netsettings) + + job.tags.add(netrender.model.TAG_RENDER) # try to send path first with ConnectionContext(): @@ -289,7 +368,16 @@ address = "" if netsettings.server_address == "[default]" else netsettings.server_address - master.runMaster((address, netsettings.server_port), netsettings.use_master_broadcast, netsettings.use_master_clear, bpy.path.abspath(netsettings.path), self.update_stats, self.test_break) + master.runMaster(address = (address, netsettings.server_port), + broadcast = netsettings.use_master_broadcast, + clear = netsettings.use_master_clear, + force = netsettings.use_master_force_upload, + path = bpy.path.abspath(netsettings.path), + update_stats = self.update_stats, + test_break = self.test_break, + use_ssl=netsettings.use_ssl, + cert_path=netsettings.cert_path, + key_path=netsettings.key_path) def render_slave(self, scene): @@ -300,7 +388,7 @@ self.update_stats("", "Network render client initiation") - conn = clientConnection(netsettings.server_address, netsettings.server_port) + conn = clientConnection(netsettings) if conn: # Sending file @@ -322,7 +410,7 @@ if response.status == http.client.NO_CONTENT: new_job = True - netsettings.job_id = clientSendJob(conn, scene) + netsettings.job_id = sendJob(conn, scene, can_save = False) job_id = netsettings.job_id requestResult(conn, job_id, scene.frame_current) Binary files /tmp/Hbut4VSIdq/blender-2.61/release/scripts/addons/netrender/css/images/themes.gif and /tmp/8U6hTXcDGf/blender-2.62/release/scripts/addons/netrender/css/images/themes.gif differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/scripts/addons/netrender/css/images/themes-preview.gif and /tmp/8U6hTXcDGf/blender-2.62/release/scripts/addons/netrender/css/images/themes-preview.gif differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/scripts/addons/netrender/css/images/ui-bg_flat_30_cccccc_40x100.png and /tmp/8U6hTXcDGf/blender-2.62/release/scripts/addons/netrender/css/images/ui-bg_flat_30_cccccc_40x100.png differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/scripts/addons/netrender/css/images/ui-bg_flat_50_5c5c5c_40x100.png and /tmp/8U6hTXcDGf/blender-2.62/release/scripts/addons/netrender/css/images/ui-bg_flat_50_5c5c5c_40x100.png differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/scripts/addons/netrender/css/images/ui-bg_glass_20_555555_1x400.png and /tmp/8U6hTXcDGf/blender-2.62/release/scripts/addons/netrender/css/images/ui-bg_glass_20_555555_1x400.png differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/scripts/addons/netrender/css/images/ui-bg_glass_40_0078a3_1x400.png and /tmp/8U6hTXcDGf/blender-2.62/release/scripts/addons/netrender/css/images/ui-bg_glass_40_0078a3_1x400.png differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/scripts/addons/netrender/css/images/ui-bg_glass_40_ffc73d_1x400.png and /tmp/8U6hTXcDGf/blender-2.62/release/scripts/addons/netrender/css/images/ui-bg_glass_40_ffc73d_1x400.png differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/scripts/addons/netrender/css/images/ui-bg_gloss-wave_25_333333_500x100.png and /tmp/8U6hTXcDGf/blender-2.62/release/scripts/addons/netrender/css/images/ui-bg_gloss-wave_25_333333_500x100.png differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/scripts/addons/netrender/css/images/ui-bg_highlight-soft_80_eeeeee_1x100.png and /tmp/8U6hTXcDGf/blender-2.62/release/scripts/addons/netrender/css/images/ui-bg_highlight-soft_80_eeeeee_1x100.png differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/scripts/addons/netrender/css/images/ui-bg_inset-soft_25_000000_1x100.png and /tmp/8U6hTXcDGf/blender-2.62/release/scripts/addons/netrender/css/images/ui-bg_inset-soft_25_000000_1x100.png differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/scripts/addons/netrender/css/images/ui-bg_inset-soft_30_f58400_1x100.png and /tmp/8U6hTXcDGf/blender-2.62/release/scripts/addons/netrender/css/images/ui-bg_inset-soft_30_f58400_1x100.png differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/scripts/addons/netrender/css/images/ui-icons_222222_256x240.png and /tmp/8U6hTXcDGf/blender-2.62/release/scripts/addons/netrender/css/images/ui-icons_222222_256x240.png differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/scripts/addons/netrender/css/images/ui-icons_4b8e0b_256x240.png and /tmp/8U6hTXcDGf/blender-2.62/release/scripts/addons/netrender/css/images/ui-icons_4b8e0b_256x240.png differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/scripts/addons/netrender/css/images/ui-icons_a83300_256x240.png and /tmp/8U6hTXcDGf/blender-2.62/release/scripts/addons/netrender/css/images/ui-icons_a83300_256x240.png differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/scripts/addons/netrender/css/images/ui-icons_cccccc_256x240.png and /tmp/8U6hTXcDGf/blender-2.62/release/scripts/addons/netrender/css/images/ui-icons_cccccc_256x240.png differ Binary files /tmp/Hbut4VSIdq/blender-2.61/release/scripts/addons/netrender/css/images/ui-icons_ffffff_256x240.png and /tmp/8U6hTXcDGf/blender-2.62/release/scripts/addons/netrender/css/images/ui-icons_ffffff_256x240.png differ diff -Nru blender-2.61/release/scripts/addons/netrender/css/jquery.themes.css blender-2.62/release/scripts/addons/netrender/css/jquery.themes.css --- blender-2.61/release/scripts/addons/netrender/css/jquery.themes.css 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons/netrender/css/jquery.themes.css 2012-02-15 19:43:04.000000000 +0000 @@ -0,0 +1,60 @@ +/* jQuery Themes styles */ +.themes_list { + list-style-type: none; + font-size: 80%; + margin: 0px; + padding: 0px; +} +@media screen and (-webkit-min-device-pixel-ratio:0) { /* Safari3/Opera9 */ + .themes_list { + font-size: 100%; + } +} +.themes_list { + float: left; +} +.themes_list li { + float: left; + width: 120px; + height: 22px; + padding: 2px; + border: 1px inset; + overflow: hidden; +} +.themes_list li a { + white-space: nowrap; +} +.themes_compact { + border: 1px inset; +} +.themes_compact li { + width: 24px; + height: 22px; + background-color: transparent; + border: none; +} +li.themes_current { + background-color: #ffffa0; +} +.themes_list span { + display: inline-block; + width: 23px; + height: 20px; + vertical-align: top; +} +.themes_list img { + border: none; + vertical-align: top; +} +.themes_preview { + display: none; + position: absolute; + z-index: 20; + padding: 2px; + border: 1px inset; + background: #fff; + text-align: center; +} +.themes_preview img { + align: top; +} diff -Nru blender-2.61/release/scripts/addons/netrender/css/jquery-ui.css blender-2.62/release/scripts/addons/netrender/css/jquery-ui.css --- blender-2.61/release/scripts/addons/netrender/css/jquery-ui.css 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons/netrender/css/jquery-ui.css 2012-02-15 19:43:04.000000000 +0000 @@ -0,0 +1,568 @@ +/* + * jQuery UI CSS Framework 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + */ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { display: none; } +.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } +.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } +.ui-helper-clearfix { display: inline-block; } +/* required comment for clearfix to work in Opera \*/ +* html .ui-helper-clearfix { height:1%; } +.ui-helper-clearfix { display:block; } +/* end clearfix */ +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { cursor: default !important; } + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } + + +/* + * jQuery UI CSS Framework 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + * + * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Segoe%20UI,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=6px&bgColorHeader=333333&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=25&borderColorHeader=333333&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=000000&bgTextureContent=05_inset_soft.png&bgImgOpacityContent=25&borderColorContent=666666&fcContent=ffffff&iconColorContent=cccccc&bgColorDefault=555555&bgTextureDefault=02_glass.png&bgImgOpacityDefault=20&borderColorDefault=666666&fcDefault=eeeeee&iconColorDefault=cccccc&bgColorHover=0078a3&bgTextureHover=02_glass.png&bgImgOpacityHover=40&borderColorHover=59b4d4&fcHover=ffffff&iconColorHover=ffffff&bgColorActive=f58400&bgTextureActive=05_inset_soft.png&bgImgOpacityActive=30&borderColorActive=ffaf0f&fcActive=ffffff&iconColorActive=222222&bgColorHighlight=eeeeee&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=80&borderColorHighlight=cccccc&fcHighlight=2e7db2&iconColorHighlight=4b8e0b&bgColorError=ffc73d&bgTextureError=02_glass.png&bgImgOpacityError=40&borderColorError=ffb73d&fcError=111111&iconColorError=a83300&bgColorOverlay=5c5c5c&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=50&opacityOverlay=80&bgColorShadow=cccccc&bgTextureShadow=01_flat.png&bgImgOpacityShadow=30&opacityShadow=60&thicknessShadow=7px&offsetTopShadow=-7px&offsetLeftShadow=-7px&cornerRadiusShadow=8px + */ + + +/* Component containers +----------------------------------*/ +.ui-widget { font-family: Segoe UI, Arial, sans-serif; font-size: 1.1em; } +.ui-widget .ui-widget { font-size: 1em; } +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Segoe UI, Arial, sans-serif; font-size: 1em; } +.ui-widget-content { border: 1px solid #666666; background: #000000 url(images/ui-bg_inset-soft_25_000000_1x100.png) 50% bottom repeat-x; color: #ffffff; } +.ui-widget-content a { color: #ffffff; } +.ui-widget-header { border: 1px solid #333333; background: #333333 url(images/ui-bg_gloss-wave_25_333333_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; } +.ui-widget-header a { color: #ffffff; } + +/* Interaction states +----------------------------------*/ +.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #666666; background: #555555 url(images/ui-bg_glass_20_555555_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #eeeeee; } +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #eeeeee; text-decoration: none; } +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #59b4d4; background: #0078a3 url(images/ui-bg_glass_40_0078a3_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #ffffff; } +.ui-state-hover a, .ui-state-hover a:hover { color: #ffffff; text-decoration: none; } +.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #ffaf0f; background: #f58400 url(images/ui-bg_inset-soft_30_f58400_1x100.png) 50% 50% repeat-x; font-weight: bold; color: #ffffff; } +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #ffffff; text-decoration: none; } +.ui-widget :active { outline: none; } + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #cccccc; background: #eeeeee url(images/ui-bg_highlight-soft_80_eeeeee_1x100.png) 50% top repeat-x; color: #2e7db2; } +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #2e7db2; } +.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #ffb73d; background: #ffc73d url(images/ui-bg_glass_40_ffc73d_1x400.png) 50% 50% repeat-x; color: #111111; } +.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #111111; } +.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #111111; } +.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } +.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_cccccc_256x240.png); } +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_cccccc_256x240.png); } +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); } +.ui-state-default .ui-icon { background-image: url(images/ui-icons_cccccc_256x240.png); } +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); } +.ui-state-active .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_4b8e0b_256x240.png); } +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_a83300_256x240.png); } + +/* positioning */ +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-off { background-position: -96px -144px; } +.ui-icon-radio-on { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; -khtml-border-top-left-radius: 6px; border-top-left-radius: 6px; } +.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 6px; -webkit-border-top-right-radius: 6px; -khtml-border-top-right-radius: 6px; border-top-right-radius: 6px; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; -khtml-border-bottom-left-radius: 6px; border-bottom-left-radius: 6px; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 6px; -webkit-border-bottom-right-radius: 6px; -khtml-border-bottom-right-radius: 6px; border-bottom-right-radius: 6px; } + +/* Overlays */ +.ui-widget-overlay { background: #5c5c5c url(images/ui-bg_flat_50_5c5c5c_40x100.png) 50% 50% repeat-x; opacity: .80;filter:Alpha(Opacity=80); } +.ui-widget-shadow { margin: -7px 0 0 -7px; padding: 7px; background: #cccccc url(images/ui-bg_flat_30_cccccc_40x100.png) 50% 50% repeat-x; opacity: .60;filter:Alpha(Opacity=60); -moz-border-radius: 8px; -khtml-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/* + * jQuery UI Resizable 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Resizable#theming + */ +.ui-resizable { position: relative;} +.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block; } +.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } +.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } +.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } +.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } +.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } +.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } +.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } +.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } +.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* + * jQuery UI Selectable 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Selectable#theming + */ +.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } +/* + * jQuery UI Accordion 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Accordion#theming + */ +/* IE/Win - Fix animation bug - #4615 */ +.ui-accordion { width: 100%; } +.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; } +.ui-accordion .ui-accordion-li-fix { display: inline; } +.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; } +.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; } +.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; } +.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } +.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; } +.ui-accordion .ui-accordion-content-active { display: block; } +/* + * jQuery UI Autocomplete 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Autocomplete#theming + */ +.ui-autocomplete { position: absolute; cursor: default; } + +/* workarounds */ +* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ + +/* + * jQuery UI Menu 1.8.16 + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Menu#theming + */ +.ui-menu { + list-style:none; + padding: 2px; + margin: 0; + display:block; + float: left; +} +.ui-menu .ui-menu { + margin-top: -3px; +} +.ui-menu .ui-menu-item { + margin:0; + padding: 0; + zoom: 1; + float: left; + clear: left; + width: 100%; +} +.ui-menu .ui-menu-item a { + text-decoration:none; + display:block; + padding:.2em .4em; + line-height:1.5; + zoom:1; +} +.ui-menu .ui-menu-item a.ui-state-hover, +.ui-menu .ui-menu-item a.ui-state-active { + font-weight: normal; + margin: -1px; +} +/* + * jQuery UI Button 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Button#theming + */ +.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ +.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ +button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ +.ui-button-icons-only { width: 3.4em; } +button.ui-button-icons-only { width: 3.7em; } + +/*button text element */ +.ui-button .ui-button-text { display: block; line-height: 1.4; } +.ui-button-text-only .ui-button-text { padding: .4em 1em; } +.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } +.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } +.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } +.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } +/* no icon support for input elements, provide padding by default */ +input.ui-button { padding: .4em 1em; } + +/*button icon element(s) */ +.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } +.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } +.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } +.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } +.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } + +/*button sets*/ +.ui-buttonset { margin-right: 7px; } +.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } + +/* workarounds */ +button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ +/* + * jQuery UI Dialog 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Dialog#theming + */ +.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; } +.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; } +.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; } +.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; } +.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } +.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } +.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } +.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } +.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; } +.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; } +.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } +.ui-draggable .ui-dialog-titlebar { cursor: move; } +/* + * jQuery UI Slider 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Slider#theming + */ +.ui-slider { position: relative; text-align: left; } +.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; } +.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } + +.ui-slider-horizontal { height: .8em; } +.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; } +.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } +.ui-slider-horizontal .ui-slider-range-min { left: 0; } +.ui-slider-horizontal .ui-slider-range-max { right: 0; } + +.ui-slider-vertical { width: .8em; height: 100px; } +.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } +.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } +.ui-slider-vertical .ui-slider-range-min { bottom: 0; } +.ui-slider-vertical .ui-slider-range-max { top: 0; }/* + * jQuery UI Tabs 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Tabs#theming + */ +.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ +.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } +.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } +.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } +.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ +.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } +.ui-tabs .ui-tabs-hide { display: none !important; } +/* + * jQuery UI Datepicker 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Datepicker#theming + */ +.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } +.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } +.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } +.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } +.ui-datepicker .ui-datepicker-prev { left:2px; } +.ui-datepicker .ui-datepicker-next { right:2px; } +.ui-datepicker .ui-datepicker-prev-hover { left:1px; } +.ui-datepicker .ui-datepicker-next-hover { right:1px; } +.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } +.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } +.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } +.ui-datepicker select.ui-datepicker-month-year {width: 100%;} +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { width: 49%;} +.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } +.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } +.ui-datepicker td { border: 0; padding: 1px; } +.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } +.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } +.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { width:auto; } +.ui-datepicker-multi .ui-datepicker-group { float:left; } +.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } +.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } +.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } +.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } +.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; } + +/* RTL support */ +.ui-datepicker-rtl { direction: rtl; } +.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } +.ui-datepicker-rtl .ui-datepicker-group { float:right; } +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } + +/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ +.ui-datepicker-cover { + display: none; /*sorry for IE5*/ + display/**/: block; /*sorry for IE5*/ + position: absolute; /*must have*/ + z-index: -1; /*must have*/ + filter: mask(); /*must have*/ + top: -4px; /*must have*/ + left: -4px; /*must have*/ + width: 200px; /*must have*/ + height: 200px; /*must have*/ +}/* + * jQuery UI Progressbar 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Progressbar#theming + */ +.ui-progressbar { height:2em; text-align: left; } +.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; } \ No newline at end of file diff -Nru blender-2.61/release/scripts/addons/netrender/__init__.py blender-2.62/release/scripts/addons/netrender/__init__.py --- blender-2.61/release/scripts/addons/netrender/__init__.py 2011-12-13 19:58:44.000000000 +0000 +++ blender-2.62/release/scripts/addons/netrender/__init__.py 2012-02-15 19:43:14.000000000 +0000 @@ -21,9 +21,8 @@ bl_info = { "name": "Network Renderer", "author": "Martin Poirier", - "version": (1, 3), - "blender": (2, 5, 6), - "api": 35011, + "version": (1, 8), + "blender": (2, 6, 0), "location": "Render > Engine > Network Render", "description": "Distributed rendering for Blender", "warning": "Stable but still work in progress", @@ -45,6 +44,7 @@ imp.reload(ui) imp.reload(repath) imp.reload(versioning) + imp.reload(baking) else: from netrender import model from netrender import operators @@ -57,6 +57,7 @@ from netrender import ui from netrender import repath from netrender import versioning + from netrender import baking jobs = [] slaves = [] diff -Nru blender-2.61/release/scripts/addons/netrender/js/jquery.js blender-2.62/release/scripts/addons/netrender/js/jquery.js --- blender-2.61/release/scripts/addons/netrender/js/jquery.js 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons/netrender/js/jquery.js 2012-02-15 19:43:14.000000000 +0000 @@ -0,0 +1,9266 @@ +/*! + * jQuery JavaScript Library v1.7.1 + * http://jquery.com/ + * + * Copyright 2011, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Mon Nov 21 21:11:03 2011 -0500 + */ +(function( window, undefined ) { + +// Use the correct document accordingly with window argument (sandbox) +var document = window.document, + navigator = window.navigator, + location = window.location; +var jQuery = (function() { + +// Define a local copy of jQuery +var jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context, rootjQuery ); + }, + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$, + + // A central reference to the root jQuery(document) + rootjQuery, + + // A simple way to check for HTML strings or ID strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, + + // Check if a string has a non-whitespace character in it + rnotwhite = /\S/, + + // Used for trimming whitespace + trimLeft = /^\s+/, + trimRight = /\s+$/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, + rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + + // Useragent RegExp + rwebkit = /(webkit)[ \/]([\w.]+)/, + ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, + rmsie = /(msie) ([\w.]+)/, + rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, + + // Matches dashed string for camelizing + rdashAlpha = /-([a-z]|[0-9])/ig, + rmsPrefix = /^-ms-/, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return ( letter + "" ).toUpperCase(); + }, + + // Keep a UserAgent string for use with jQuery.browser + userAgent = navigator.userAgent, + + // For matching the engine and version of the browser + browserMatch, + + // The deferred used on DOM ready + readyList, + + // The ready event handler + DOMContentLoaded, + + // Save a reference to some core methods + toString = Object.prototype.toString, + hasOwn = Object.prototype.hasOwnProperty, + push = Array.prototype.push, + slice = Array.prototype.slice, + trim = String.prototype.trim, + indexOf = Array.prototype.indexOf, + + // [[Class]] -> type pairs + class2type = {}; + +jQuery.fn = jQuery.prototype = { + constructor: jQuery, + init: function( selector, context, rootjQuery ) { + var match, elem, ret, doc; + + // Handle $(""), $(null), or $(undefined) + if ( !selector ) { + return this; + } + + // Handle $(DOMElement) + if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + } + + // The body element only exists once, optimize finding it + if ( selector === "body" && !context && document.body ) { + this.context = document; + this[0] = document.body; + this.selector = selector; + this.length = 1; + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + // Are we dealing with HTML string or an ID? + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = quickExpr.exec( selector ); + } + + // Verify a match, and that no context was specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + doc = ( context ? context.ownerDocument || context : document ); + + // If a single string is passed in and it's a single tag + // just do a createElement and skip the rest + ret = rsingleTag.exec( selector ); + + if ( ret ) { + if ( jQuery.isPlainObject( context ) ) { + selector = [ document.createElement( ret[1] ) ]; + jQuery.fn.attr.call( selector, context, true ); + + } else { + selector = [ doc.createElement( ret[1] ) ]; + } + + } else { + ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); + selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes; + } + + return jQuery.merge( this, selector ); + + // HANDLE: $("#id") + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return rootjQuery.ready( selector ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }, + + // Start with an empty selector + selector: "", + + // The current version of jQuery being used + jquery: "1.7.1", + + // The default length of a jQuery object is 0 + length: 0, + + // The number of elements contained in the matched element set + size: function() { + return this.length; + }, + + toArray: function() { + return slice.call( this, 0 ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num == null ? + + // Return a 'clean' array + this.toArray() : + + // Return just the object + ( num < 0 ? this[ this.length + num ] : this[ num ] ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems, name, selector ) { + // Build a new jQuery matched element set + var ret = this.constructor(); + + if ( jQuery.isArray( elems ) ) { + push.apply( ret, elems ); + + } else { + jQuery.merge( ret, elems ); + } + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + ret.context = this.context; + + if ( name === "find" ) { + ret.selector = this.selector + ( this.selector ? " " : "" ) + selector; + } else if ( name ) { + ret.selector = this.selector + "." + name + "(" + selector + ")"; + } + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + ready: function( fn ) { + // Attach the listeners + jQuery.bindReady(); + + // Add the callback + readyList.add( fn ); + + return this; + }, + + eq: function( i ) { + i = +i; + return i === -1 ? + this.slice( i ) : + this.slice( i, i + 1 ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ), + "slice", slice.call(arguments).join(",") ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: [].sort, + splice: [].splice +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( length === i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + noConflict: function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; + }, + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + // Either a released hold or an DOMready/load event and not yet ready + if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready, 1 ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.fireWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.trigger ) { + jQuery( document ).trigger( "ready" ).off( "ready" ); + } + } + }, + + bindReady: function() { + if ( readyList ) { + return; + } + + readyList = jQuery.Callbacks( "once memory" ); + + // Catch cases where $(document).ready() is called after the + // browser event has already occurred. + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + return setTimeout( jQuery.ready, 1 ); + } + + // Mozilla, Opera and webkit nightlies currently support this event + if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", jQuery.ready, false ); + + // If IE event model is used + } else if ( document.attachEvent ) { + // ensure firing before onload, + // maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", DOMContentLoaded ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", jQuery.ready ); + + // If IE and not a frame + // continually check to see if the document is ready + var toplevel = false; + + try { + toplevel = window.frameElement == null; + } catch(e) {} + + if ( document.documentElement.doScroll && toplevel ) { + doScrollCheck(); + } + } + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + // A crude way of determining if an object is a window + isWindow: function( obj ) { + return obj && typeof obj === "object" && "setInterval" in obj; + }, + + isNumeric: function( obj ) { + return !isNaN( parseFloat(obj) ) && isFinite( obj ); + }, + + type: function( obj ) { + return obj == null ? + String( obj ) : + class2type[ toString.call(obj) ] || "object"; + }, + + isPlainObject: function( obj ) { + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !hasOwn.call(obj, "constructor") && + !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + + var key; + for ( key in obj ) {} + + return key === undefined || hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + for ( var name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw new Error( msg ); + }, + + parseJSON: function( data ) { + if ( typeof data !== "string" || !data ) { + return null; + } + + // Make sure leading/trailing whitespace is removed (IE can't handle it) + data = jQuery.trim( data ); + + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + return window.JSON.parse( data ); + } + + // Make sure the incoming data is actual JSON + // Logic borrowed from http://json.org/json2.js + if ( rvalidchars.test( data.replace( rvalidescape, "@" ) + .replace( rvalidtokens, "]" ) + .replace( rvalidbraces, "")) ) { + + return ( new Function( "return " + data ) )(); + + } + jQuery.error( "Invalid JSON: " + data ); + }, + + // Cross-browser xml parsing + parseXML: function( data ) { + var xml, tmp; + try { + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data , "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; + }, + + noop: function() {}, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && rnotwhite.test( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); + }, + + // args is for internal usage only + each: function( object, callback, args ) { + var name, i = 0, + length = object.length, + isObj = length === undefined || jQuery.isFunction( object ); + + if ( args ) { + if ( isObj ) { + for ( name in object ) { + if ( callback.apply( object[ name ], args ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.apply( object[ i++ ], args ) === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isObj ) { + for ( name in object ) { + if ( callback.call( object[ name ], name, object[ name ] ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { + break; + } + } + } + } + + return object; + }, + + // Use native String.trim function wherever possible + trim: trim ? + function( text ) { + return text == null ? + "" : + trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); + }, + + // results is for internal usage only + makeArray: function( array, results ) { + var ret = results || []; + + if ( array != null ) { + // The window, strings (and functions) also have 'length' + // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 + var type = jQuery.type( array ); + + if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { + push.call( ret, array ); + } else { + jQuery.merge( ret, array ); + } + } + + return ret; + }, + + inArray: function( elem, array, i ) { + var len; + + if ( array ) { + if ( indexOf ) { + return indexOf.call( array, elem, i ); + } + + len = array.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in array && array[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var i = first.length, + j = 0; + + if ( typeof second.length === "number" ) { + for ( var l = second.length; j < l; j++ ) { + first[ i++ ] = second[ j ]; + } + + } else { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, inv ) { + var ret = [], retVal; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( var i = 0, length = elems.length; i < length; i++ ) { + retVal = !!callback( elems[ i ], i ); + if ( inv !== retVal ) { + ret.push( elems[ i ] ); + } + } + + return ret; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, key, ret = [], + i = 0, + length = elems.length, + // jquery objects are treated as arrays + isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; + + // Go through the array, translating each of the items to their + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + + // Go through every key on the object, + } else { + for ( key in elems ) { + value = callback( elems[ key ], key, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + } + + // Flatten any nested arrays + return ret.concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + if ( typeof context === "string" ) { + var tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + var args = slice.call( arguments, 2 ), + proxy = function() { + return fn.apply( context, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; + + return proxy; + }, + + // Mutifunctional method to get and set values to a collection + // The value/s can optionally be executed if it's a function + access: function( elems, key, value, exec, fn, pass ) { + var length = elems.length; + + // Setting many attributes + if ( typeof key === "object" ) { + for ( var k in key ) { + jQuery.access( elems, k, key[k], exec, fn, value ); + } + return elems; + } + + // Setting one attribute + if ( value !== undefined ) { + // Optionally, function values get executed if exec is true + exec = !pass && exec && jQuery.isFunction(value); + + for ( var i = 0; i < length; i++ ) { + fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); + } + + return elems; + } + + // Getting an attribute + return length ? fn( elems[0], key ) : undefined; + }, + + now: function() { + return ( new Date() ).getTime(); + }, + + // Use of jQuery.browser is frowned upon. + // More details: http://docs.jquery.com/Utilities/jQuery.browser + uaMatch: function( ua ) { + ua = ua.toLowerCase(); + + var match = rwebkit.exec( ua ) || + ropera.exec( ua ) || + rmsie.exec( ua ) || + ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || + []; + + return { browser: match[1] || "", version: match[2] || "0" }; + }, + + sub: function() { + function jQuerySub( selector, context ) { + return new jQuerySub.fn.init( selector, context ); + } + jQuery.extend( true, jQuerySub, this ); + jQuerySub.superclass = this; + jQuerySub.fn = jQuerySub.prototype = this(); + jQuerySub.fn.constructor = jQuerySub; + jQuerySub.sub = this.sub; + jQuerySub.fn.init = function init( selector, context ) { + if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { + context = jQuerySub( context ); + } + + return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); + }; + jQuerySub.fn.init.prototype = jQuerySub.fn; + var rootjQuerySub = jQuerySub(document); + return jQuerySub; + }, + + browser: {} +}); + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +browserMatch = jQuery.uaMatch( userAgent ); +if ( browserMatch.browser ) { + jQuery.browser[ browserMatch.browser ] = true; + jQuery.browser.version = browserMatch.version; +} + +// Deprecated, use jQuery.browser.webkit instead +if ( jQuery.browser.webkit ) { + jQuery.browser.safari = true; +} + +// IE doesn't match non-breaking spaces with \s +if ( rnotwhite.test( "\xA0" ) ) { + trimLeft = /^[\s\xA0]+/; + trimRight = /[\s\xA0]+$/; +} + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); + +// Cleanup functions for the document ready method +if ( document.addEventListener ) { + DOMContentLoaded = function() { + document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + jQuery.ready(); + }; + +} else if ( document.attachEvent ) { + DOMContentLoaded = function() { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( document.readyState === "complete" ) { + document.detachEvent( "onreadystatechange", DOMContentLoaded ); + jQuery.ready(); + } + }; +} + +// The DOM ready check for Internet Explorer +function doScrollCheck() { + if ( jQuery.isReady ) { + return; + } + + try { + // If IE is used, use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + document.documentElement.doScroll("left"); + } catch(e) { + setTimeout( doScrollCheck, 1 ); + return; + } + + // and execute any waiting functions + jQuery.ready(); +} + +return jQuery; + +})(); + + +// String to Object flags format cache +var flagsCache = {}; + +// Convert String-formatted flags into Object-formatted ones and store in cache +function createFlags( flags ) { + var object = flagsCache[ flags ] = {}, + i, length; + flags = flags.split( /\s+/ ); + for ( i = 0, length = flags.length; i < length; i++ ) { + object[ flags[i] ] = true; + } + return object; +} + +/* + * Create a callback list using the following parameters: + * + * flags: an optional list of space-separated flags that will change how + * the callback list behaves + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible flags: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( flags ) { + + // Convert flags from String-formatted to Object-formatted + // (we check in cache first) + flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {}; + + var // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = [], + // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Add one or several callbacks to the list + add = function( args ) { + var i, + length, + elem, + type, + actual; + for ( i = 0, length = args.length; i < length; i++ ) { + elem = args[ i ]; + type = jQuery.type( elem ); + if ( type === "array" ) { + // Inspect recursively + add( elem ); + } else if ( type === "function" ) { + // Add if not in unique mode and callback is not in + if ( !flags.unique || !self.has( elem ) ) { + list.push( elem ); + } + } + } + }, + // Fire callbacks + fire = function( context, args ) { + args = args || []; + memory = !flags.memory || [ context, args ]; + firing = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) { + memory = true; // Mark as halted + break; + } + } + firing = false; + if ( list ) { + if ( !flags.once ) { + if ( stack && stack.length ) { + memory = stack.shift(); + self.fireWith( memory[ 0 ], memory[ 1 ] ); + } + } else if ( memory === true ) { + self.disable(); + } else { + list = []; + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + var length = list.length; + add( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away, unless previous + // firing was halted (stopOnFalse) + } else if ( memory && memory !== true ) { + firingStart = length; + fire( memory[ 0 ], memory[ 1 ] ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + var args = arguments, + argIndex = 0, + argLength = args.length; + for ( ; argIndex < argLength ; argIndex++ ) { + for ( var i = 0; i < list.length; i++ ) { + if ( args[ argIndex ] === list[ i ] ) { + // Handle firingIndex and firingLength + if ( firing ) { + if ( i <= firingLength ) { + firingLength--; + if ( i <= firingIndex ) { + firingIndex--; + } + } + } + // Remove the element + list.splice( i--, 1 ); + // If we have some unicity property then + // we only need to do this once + if ( flags.unique ) { + break; + } + } + } + } + } + return this; + }, + // Control if a given callback is in the list + has: function( fn ) { + if ( list ) { + var i = 0, + length = list.length; + for ( ; i < length; i++ ) { + if ( fn === list[ i ] ) { + return true; + } + } + } + return false; + }, + // Remove all callbacks from the list + empty: function() { + list = []; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory || memory === true ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( stack ) { + if ( firing ) { + if ( !flags.once ) { + stack.push( [ context, args ] ); + } + } else if ( !( flags.once && memory ) ) { + fire( context, args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!memory; + } + }; + + return self; +}; + + + + +var // Static reference to slice + sliceDeferred = [].slice; + +jQuery.extend({ + + Deferred: function( func ) { + var doneList = jQuery.Callbacks( "once memory" ), + failList = jQuery.Callbacks( "once memory" ), + progressList = jQuery.Callbacks( "memory" ), + state = "pending", + lists = { + resolve: doneList, + reject: failList, + notify: progressList + }, + promise = { + done: doneList.add, + fail: failList.add, + progress: progressList.add, + + state: function() { + return state; + }, + + // Deprecated + isResolved: doneList.fired, + isRejected: failList.fired, + + then: function( doneCallbacks, failCallbacks, progressCallbacks ) { + deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks ); + return this; + }, + always: function() { + deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); + return this; + }, + pipe: function( fnDone, fnFail, fnProgress ) { + return jQuery.Deferred(function( newDefer ) { + jQuery.each( { + done: [ fnDone, "resolve" ], + fail: [ fnFail, "reject" ], + progress: [ fnProgress, "notify" ] + }, function( handler, data ) { + var fn = data[ 0 ], + action = data[ 1 ], + returned; + if ( jQuery.isFunction( fn ) ) { + deferred[ handler ](function() { + returned = fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); + } + }); + } else { + deferred[ handler ]( newDefer[ action ] ); + } + }); + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + if ( obj == null ) { + obj = promise; + } else { + for ( var key in promise ) { + obj[ key ] = promise[ key ]; + } + } + return obj; + } + }, + deferred = promise.promise({}), + key; + + for ( key in lists ) { + deferred[ key ] = lists[ key ].fire; + deferred[ key + "With" ] = lists[ key ].fireWith; + } + + // Handle state + deferred.done( function() { + state = "resolved"; + }, failList.disable, progressList.lock ).fail( function() { + state = "rejected"; + }, doneList.disable, progressList.lock ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( firstParam ) { + var args = sliceDeferred.call( arguments, 0 ), + i = 0, + length = args.length, + pValues = new Array( length ), + count = length, + pCount = length, + deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ? + firstParam : + jQuery.Deferred(), + promise = deferred.promise(); + function resolveFunc( i ) { + return function( value ) { + args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + if ( !( --count ) ) { + deferred.resolveWith( deferred, args ); + } + }; + } + function progressFunc( i ) { + return function( value ) { + pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + deferred.notifyWith( promise, pValues ); + }; + } + if ( length > 1 ) { + for ( ; i < length; i++ ) { + if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) { + args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) ); + } else { + --count; + } + } + if ( !count ) { + deferred.resolveWith( deferred, args ); + } + } else if ( deferred !== firstParam ) { + deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); + } + return promise; + } +}); + + + + +jQuery.support = (function() { + + var support, + all, + a, + select, + opt, + input, + marginDiv, + fragment, + tds, + events, + eventName, + i, + isSupported, + div = document.createElement( "div" ), + documentElement = document.documentElement; + + // Preliminary tests + div.setAttribute("className", "t"); + div.innerHTML = "
      a"; + + all = div.getElementsByTagName( "*" ); + a = div.getElementsByTagName( "a" )[ 0 ]; + + // Can't get basic test support + if ( !all || !all.length || !a ) { + return {}; + } + + // First batch of supports tests + select = document.createElement( "select" ); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName( "input" )[ 0 ]; + + support = { + // IE strips leading whitespace when .innerHTML is used + leadingWhitespace: ( div.firstChild.nodeType === 3 ), + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + tbody: !div.getElementsByTagName("tbody").length, + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + htmlSerialize: !!div.getElementsByTagName("link").length, + + // Get the style information from getAttribute + // (IE uses .cssText instead) + style: /top/.test( a.getAttribute("style") ), + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + hrefNormalized: ( a.getAttribute("href") === "/a" ), + + // Make sure that element opacity exists + // (IE uses filter instead) + // Use a regex to work around a WebKit issue. See #5145 + opacity: /^0.55/.test( a.style.opacity ), + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + cssFloat: !!a.style.cssFloat, + + // Make sure that if no value is specified for a checkbox + // that it defaults to "on". + // (WebKit defaults to "" instead) + checkOn: ( input.value === "on" ), + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + optSelected: opt.selected, + + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + getSetAttribute: div.className !== "t", + + // Tests for enctype support on a form(#6743) + enctype: !!document.createElement("form").enctype, + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", + + // Will be defined later + submitBubbles: true, + changeBubbles: true, + focusinBubbles: false, + deleteExpando: true, + noCloneEvent: true, + inlineBlockNeedsLayout: false, + shrinkWrapBlocks: false, + reliableMarginRight: true + }; + + // Make sure checked status is properly cloned + input.checked = true; + support.noCloneChecked = input.cloneNode( true ).checked; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Test to see if it's possible to delete an expando from an element + // Fails in Internet Explorer + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + + if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { + div.attachEvent( "onclick", function() { + // Cloning a node shouldn't copy over any + // bound event handlers (IE does this) + support.noCloneEvent = false; + }); + div.cloneNode( true ).fireEvent( "onclick" ); + } + + // Check if a radio maintains its value + // after being appended to the DOM + input = document.createElement("input"); + input.value = "t"; + input.setAttribute("type", "radio"); + support.radioValue = input.value === "t"; + + input.setAttribute("checked", "checked"); + div.appendChild( input ); + fragment = document.createDocumentFragment(); + fragment.appendChild( div.lastChild ); + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + fragment.removeChild( input ); + fragment.appendChild( div ); + + div.innerHTML = ""; + + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. For more + // info see bug #3333 + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + if ( window.getComputedStyle ) { + marginDiv = document.createElement( "div" ); + marginDiv.style.width = "0"; + marginDiv.style.marginRight = "0"; + div.style.width = "2px"; + div.appendChild( marginDiv ); + support.reliableMarginRight = + ( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; + } + + // Technique from Juriy Zaytsev + // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ + // We only care about the case where non-standard event systems + // are used, namely in IE. Short-circuiting here helps us to + // avoid an eval call (in setAttribute) which can cause CSP + // to go haywire. See: https://developer.mozilla.org/en/Security/CSP + if ( div.attachEvent ) { + for( i in { + submit: 1, + change: 1, + focusin: 1 + }) { + eventName = "on" + i; + isSupported = ( eventName in div ); + if ( !isSupported ) { + div.setAttribute( eventName, "return;" ); + isSupported = ( typeof div[ eventName ] === "function" ); + } + support[ i + "Bubbles" ] = isSupported; + } + } + + fragment.removeChild( div ); + + // Null elements to avoid leaks in IE + fragment = select = opt = marginDiv = div = input = null; + + // Run tests that need a body at doc ready + jQuery(function() { + var container, outer, inner, table, td, offsetSupport, + conMarginTop, ptlm, vb, style, html, + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + conMarginTop = 1; + ptlm = "position:absolute;top:0;left:0;width:1px;height:1px;margin:0;"; + vb = "visibility:hidden;border:0;"; + style = "style='" + ptlm + "border:5px solid #000;padding:0;'"; + html = "
      " + + "" + + "
      "; + + container = document.createElement("div"); + container.style.cssText = vb + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px"; + body.insertBefore( container, body.firstChild ); + + // Construct the test element + div = document.createElement("div"); + container.appendChild( div ); + + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + // (only IE 8 fails this test) + div.innerHTML = "
      t
      "; + tds = div.getElementsByTagName( "td" ); + isSupported = ( tds[ 0 ].offsetHeight === 0 ); + + tds[ 0 ].style.display = ""; + tds[ 1 ].style.display = "none"; + + // Check if empty table cells still have offsetWidth/Height + // (IE <= 8 fail this test) + support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); + + // Figure out if the W3C box model works as expected + div.innerHTML = ""; + div.style.width = div.style.paddingLeft = "1px"; + jQuery.boxModel = support.boxModel = div.offsetWidth === 2; + + if ( typeof div.style.zoom !== "undefined" ) { + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + // (IE < 8 does this) + div.style.display = "inline"; + div.style.zoom = 1; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 ); + + // Check if elements with layout shrink-wrap their children + // (IE 6 does this) + div.style.display = ""; + div.innerHTML = "
      "; + support.shrinkWrapBlocks = ( div.offsetWidth !== 2 ); + } + + div.style.cssText = ptlm + vb; + div.innerHTML = html; + + outer = div.firstChild; + inner = outer.firstChild; + td = outer.nextSibling.firstChild.firstChild; + + offsetSupport = { + doesNotAddBorder: ( inner.offsetTop !== 5 ), + doesAddBorderForTableAndCells: ( td.offsetTop === 5 ) + }; + + inner.style.position = "fixed"; + inner.style.top = "20px"; + + // safari subtracts parent border width here which is 5px + offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 ); + inner.style.position = inner.style.top = ""; + + outer.style.overflow = "hidden"; + outer.style.position = "relative"; + + offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 ); + offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop ); + + body.removeChild( container ); + div = container = null; + + jQuery.extend( support, offsetSupport ); + }); + + return support; +})(); + + + + +var rbrace = /^(?:\{.*\}|\[.*\])$/, + rmultiDash = /([A-Z])/g; + +jQuery.extend({ + cache: {}, + + // Please use with caution + uuid: 0, + + // Unique for each copy of jQuery on the page + // Non-digits removed to match rinlinejQuery + expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), + + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", + "applet": true + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var privateCache, thisCache, ret, + internalKey = jQuery.expando, + getByName = typeof name === "string", + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey, + isEvents = name === "events"; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + elem[ internalKey ] = id = ++jQuery.uuid; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + + // Avoids exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = jQuery.noop; + } + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + privateCache = thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Users should not attempt to inspect the internal events object using jQuery.data, + // it is undocumented and subject to change. But does anyone listen? No. + if ( isEvents && !thisCache[ name ] ) { + return privateCache.events; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( getByName ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; + }, + + removeData: function( elem, name, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, l, + + // Reference to internal data cache key + internalKey = jQuery.expando, + + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + + // See jQuery.data for more information + id = isNode ? elem[ internalKey ] : internalKey; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split( " " ); + } + } + } + + for ( i = 0, l = name.length; i < l; i++ ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject(cache[ id ]) ) { + return; + } + } + + // Browsers that fail expando deletion also refuse to delete expandos on + // the window, but it will allow it on all other JS objects; other browsers + // don't care + // Ensure that `cache` is not a window object #10080 + if ( jQuery.support.deleteExpando || !cache.setInterval ) { + delete cache[ id ]; + } else { + cache[ id ] = null; + } + + // We destroyed the cache and need to eliminate the expando on the node to avoid + // false lookups in the cache for entries that no longer exist + if ( isNode ) { + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( jQuery.support.deleteExpando ) { + delete elem[ internalKey ]; + } else if ( elem.removeAttribute ) { + elem.removeAttribute( internalKey ); + } else { + elem[ internalKey ] = null; + } + } + }, + + // For internal use only. + _data: function( elem, name, data ) { + return jQuery.data( elem, name, data, true ); + }, + + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + if ( elem.nodeName ) { + var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; + + if ( match ) { + return !(match === true || elem.getAttribute("classid") !== match); + } + } + + return true; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var parts, attr, name, + data = null; + + if ( typeof key === "undefined" ) { + if ( this.length ) { + data = jQuery.data( this[0] ); + + if ( this[0].nodeType === 1 && !jQuery._data( this[0], "parsedAttrs" ) ) { + attr = this[0].attributes; + for ( var i = 0, l = attr.length; i < l; i++ ) { + name = attr[i].name; + + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.substring(5) ); + + dataAttr( this[0], name, data[ name ] ); + } + } + jQuery._data( this[0], "parsedAttrs", true ); + } + } + + return data; + + } else if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + parts = key.split("."); + parts[1] = parts[1] ? "." + parts[1] : ""; + + if ( value === undefined ) { + data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); + + // Try to fetch any internally stored data first + if ( data === undefined && this.length ) { + data = jQuery.data( this[0], key ); + data = dataAttr( this[0], key, data ); + } + + return data === undefined && parts[1] ? + this.data( parts[0] ) : + data; + + } else { + return this.each(function() { + var self = jQuery( this ), + args = [ parts[0], value ]; + + self.triggerHandler( "setData" + parts[1] + "!", args ); + jQuery.data( this, key, value ); + self.triggerHandler( "changeData" + parts[1] + "!", args ); + }); + } + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + jQuery.isNumeric( data ) ? parseFloat( data ) : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + for ( var name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} + + + + +function handleQueueMarkDefer( elem, type, src ) { + var deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + defer = jQuery._data( elem, deferDataKey ); + if ( defer && + ( src === "queue" || !jQuery._data(elem, queueDataKey) ) && + ( src === "mark" || !jQuery._data(elem, markDataKey) ) ) { + // Give room for hard-coded callbacks to fire first + // and eventually mark/queue something else on the element + setTimeout( function() { + if ( !jQuery._data( elem, queueDataKey ) && + !jQuery._data( elem, markDataKey ) ) { + jQuery.removeData( elem, deferDataKey, true ); + defer.fire(); + } + }, 0 ); + } +} + +jQuery.extend({ + + _mark: function( elem, type ) { + if ( elem ) { + type = ( type || "fx" ) + "mark"; + jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 ); + } + }, + + _unmark: function( force, elem, type ) { + if ( force !== true ) { + type = elem; + elem = force; + force = false; + } + if ( elem ) { + type = type || "fx"; + var key = type + "mark", + count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 ); + if ( count ) { + jQuery._data( elem, key, count ); + } else { + jQuery.removeData( elem, key, true ); + handleQueueMarkDefer( elem, type, "mark" ); + } + } + }, + + queue: function( elem, type, data ) { + var q; + if ( elem ) { + type = ( type || "fx" ) + "queue"; + q = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !q || jQuery.isArray(data) ) { + q = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + q.push( data ); + } + } + return q || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + fn = queue.shift(), + hooks = {}; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + } + + if ( fn ) { + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + jQuery._data( elem, type + ".run", hooks ); + fn.call( elem, function() { + jQuery.dequeue( elem, type ); + }, hooks ); + } + + if ( !queue.length ) { + jQuery.removeData( elem, type + "queue " + type + ".run", true ); + handleQueueMarkDefer( elem, type, "queue" ); + } + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + } + + if ( data === undefined ) { + return jQuery.queue( this[0], type ); + } + return this.each(function() { + var queue = jQuery.queue( this, type, data ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + // Based off of the plugin by Clint Helfers, with permission. + // http://blindsignals.com/index.php/2009/07/jquery-delay/ + delay: function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, object ) { + if ( typeof type !== "string" ) { + object = type; + type = undefined; + } + type = type || "fx"; + var defer = jQuery.Deferred(), + elements = this, + i = elements.length, + count = 1, + deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + tmp; + function resolve() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + } + while( i-- ) { + if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || + ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) || + jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && + jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) { + count++; + tmp.add( resolve ); + } + } + resolve(); + return defer.promise(); + } +}); + + + + +var rclass = /[\n\t\r]/g, + rspace = /\s+/, + rreturn = /\r/g, + rtype = /^(?:button|input)$/i, + rfocusable = /^(?:button|input|object|select|textarea)$/i, + rclickable = /^a(?:rea)?$/i, + rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, + getSetAttribute = jQuery.support.getSetAttribute, + nodeHook, boolHook, fixSpecified; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, name, value, true, jQuery.attr ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, name, value, true, jQuery.prop ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + }, + + addClass: function( value ) { + var classNames, i, l, elem, + setClass, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call(this, j, this.className) ); + }); + } + + if ( value && typeof value === "string" ) { + classNames = value.split( rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 ) { + if ( !elem.className && classNames.length === 1 ) { + elem.className = value; + + } else { + setClass = " " + elem.className + " "; + + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) { + setClass += classNames[ c ] + " "; + } + } + elem.className = jQuery.trim( setClass ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classNames, i, l, elem, className, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call(this, j, this.className) ); + }); + } + + if ( (value && typeof value === "string") || value === undefined ) { + classNames = ( value || "" ).split( rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 && elem.className ) { + if ( value ) { + className = (" " + elem.className + " ").replace( rclass, " " ); + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + className = className.replace(" " + classNames[ c ] + " ", " "); + } + elem.className = jQuery.trim( className ); + + } else { + elem.className = ""; + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isBool = typeof stateVal === "boolean"; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + state = stateVal, + classNames = value.split( rspace ); + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space seperated list + state = isBool ? state : !self.hasClass( className ); + self[ state ? "addClass" : "removeClass" ]( className ); + } + + } else if ( type === "undefined" || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // toggle whole className + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var hooks, ret, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var self = jQuery(this), val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, self.val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map(val, function ( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // attributes.value is undefined in Blackberry 4.7 but + // uses .value. See #6932 + var val = elem.attributes.value; + return !val || val.specified ? elem.value : elem.text; + } + }, + select: { + get: function( elem ) { + var value, i, max, option, + index = elem.selectedIndex, + values = [], + options = elem.options, + one = elem.type === "select-one"; + + // Nothing was selected + if ( index < 0 ) { + return null; + } + + // Loop through all the selected options + i = one ? index : 0; + max = one ? index + 1 : options.length; + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Don't return options that are disabled or in a disabled optgroup + if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && + (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + // Fixes Bug #2551 -- select.val() broken in IE after form.reset() + if ( one && !values.length && options.length ) { + return jQuery( options[ index ] ).val(); + } + + return values; + }, + + set: function( elem, value ) { + var values = jQuery.makeArray( value ); + + jQuery(elem).find("option").each(function() { + this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; + }); + + if ( !values.length ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + + attrFn: { + val: true, + css: true, + html: true, + text: true, + data: true, + width: true, + height: true, + offset: true + }, + + attr: function( elem, name, value, pass ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( pass && name in jQuery.attrFn ) { + return jQuery( elem )[ name ]( value ); + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( notxml ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + + } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, "" + value ); + return value; + } + + } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + + ret = elem.getAttribute( name ); + + // Non-existent attributes return null, we normalize to undefined + return ret === null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var propName, attrNames, name, l, + i = 0; + + if ( value && elem.nodeType === 1 ) { + attrNames = value.toLowerCase().split( rspace ); + l = attrNames.length; + + for ( ; i < l; i++ ) { + name = attrNames[ i ]; + + if ( name ) { + propName = jQuery.propFix[ name ] || name; + + // See #9699 for explanation of this approach (setting first, then removal) + jQuery.attr( elem, name, "" ); + elem.removeAttribute( getSetAttribute ? name : propName ); + + // Set corresponding property to false for boolean attributes + if ( rboolean.test( name ) && propName in elem ) { + elem[ propName ] = false; + } + } + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + // We can't allow the type property to be changed (since it causes problems in IE) + if ( rtype.test( elem.nodeName ) && elem.parentNode ) { + jQuery.error( "type property can't be changed" ); + } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to it's default in case type is set after value + // This is for element creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + }, + // Use the value property for back compat + // Use the nodeHook for button elements in IE6/7 (#1954) + value: { + get: function( elem, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.get( elem, name ); + } + return name in elem ? + elem.value : + null; + }, + set: function( elem, value, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.set( elem, value, name ); + } + // Does not return so that setAttribute is also used + elem.value = value; + } + } + }, + + propFix: { + tabindex: "tabIndex", + readonly: "readOnly", + "for": "htmlFor", + "class": "className", + maxlength: "maxLength", + cellspacing: "cellSpacing", + cellpadding: "cellPadding", + rowspan: "rowSpan", + colspan: "colSpan", + usemap: "useMap", + frameborder: "frameBorder", + contenteditable: "contentEditable" + }, + + prop: function( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + return ( elem[ name ] = value ); + } + + } else { + if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + return elem[ name ]; + } + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + var attributeNode = elem.getAttributeNode("tabindex"); + + return attributeNode && attributeNode.specified ? + parseInt( attributeNode.value, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + undefined; + } + } + } +}); + +// Add the tabIndex propHook to attrHooks for back-compat (different case is intentional) +jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex; + +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + // Align boolean attributes with corresponding properties + // Fall back to attribute presence where some booleans are not supported + var attrNode, + property = jQuery.prop( elem, name ); + return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? + name.toLowerCase() : + undefined; + }, + set: function( elem, value, name ) { + var propName; + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + // value is true since we know at this point it's type boolean and not false + // Set boolean attributes to the same name and set the DOM property + propName = jQuery.propFix[ name ] || name; + if ( propName in elem ) { + // Only set the IDL specifically if it already exists on the element + elem[ propName ] = true; + } + + elem.setAttribute( name, name.toLowerCase() ); + } + return name; + } +}; + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !getSetAttribute ) { + + fixSpecified = { + name: true, + id: true + }; + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = jQuery.valHooks.button = { + get: function( elem, name ) { + var ret; + ret = elem.getAttributeNode( name ); + return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ? + ret.nodeValue : + undefined; + }, + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + ret = document.createAttribute( name ); + elem.setAttributeNode( ret ); + } + return ( ret.nodeValue = value + "" ); + } + }; + + // Apply the nodeHook to tabindex + jQuery.attrHooks.tabindex.set = nodeHook.set; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }); + }); + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + get: nodeHook.get, + set: function( elem, value, name ) { + if ( value === "" ) { + value = "false"; + } + nodeHook.set( elem, value, name ); + } + }; +} + + +// Some attributes require a special call on IE +if ( !jQuery.support.hrefNormalized ) { + jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + get: function( elem ) { + var ret = elem.getAttribute( name, 2 ); + return ret === null ? undefined : ret; + } + }); + }); +} + +if ( !jQuery.support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Normalize to lowercase since IE uppercases css property names + return elem.style.cssText.toLowerCase() || undefined; + }, + set: function( elem, value ) { + return ( elem.style.cssText = "" + value ); + } + }; +} + +// Safari mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !jQuery.support.optSelected ) { + jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + return null; + } + }); +} + +// IE6/7 call enctype encoding +if ( !jQuery.support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + +// Radios and checkboxes getter/setter +if ( !jQuery.support.checkOn ) { + jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + get: function( elem ) { + // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + } + }; + }); +} +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); + } + } + }); +}); + + + + +var rformElems = /^(?:textarea|input|select)$/i, + rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/, + rhoverHack = /\bhover(\.\S+)?\b/, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/, + quickParse = function( selector ) { + var quick = rquickIs.exec( selector ); + if ( quick ) { + // 0 1 2 3 + // [ _, tag, id, class ] + quick[1] = ( quick[1] || "" ).toLowerCase(); + quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" ); + } + return quick; + }, + quickIs = function( elem, m ) { + var attrs = elem.attributes || {}; + return ( + (!m[1] || elem.nodeName.toLowerCase() === m[1]) && + (!m[2] || (attrs.id || {}).value === m[2]) && + (!m[3] || m[3].test( (attrs[ "class" ] || {}).value )) + ); + }, + hoverHack = function( events ) { + return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); + }; + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + add: function( elem, types, handler, data, selector ) { + + var elemData, eventHandle, events, + t, tns, type, namespaces, handleObj, + handleObjIn, quick, handlers, special; + + // Don't attach events to noData or text/comment nodes (allow plain objects tho) + if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + events = elemData.events; + if ( !events ) { + elemData.events = events = {}; + } + eventHandle = elemData.handle; + if ( !eventHandle ) { + elemData.handle = eventHandle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + // jQuery(...).bind("mouseover mouseout", fn); + types = jQuery.trim( hoverHack(types) ).split( " " ); + for ( t = 0; t < types.length; t++ ) { + + tns = rtypenamespace.exec( types[t] ) || []; + type = tns[1]; + namespaces = ( tns[2] || "" ).split( "." ).sort(); + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: tns[1], + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + quick: quickParse( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + handlers = events[ type ]; + if ( !handlers ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + global: {}, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var elemData = jQuery.hasData( elem ) && jQuery._data( elem ), + t, tns, type, origType, namespaces, origCount, + j, events, special, handle, eventType, handleObj; + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = jQuery.trim( hoverHack( types || "" ) ).split(" "); + for ( t = 0; t < types.length; t++ ) { + tns = rtypenamespace.exec( types[t] ) || []; + type = origType = tns[1]; + namespaces = tns[2]; + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector? special.delegateType : special.bindType ) || type; + eventType = events[ type ] || []; + origCount = eventType.length; + namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + + // Remove matching events + for ( j = 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !namespaces || namespaces.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + eventType.splice( j--, 1 ); + + if ( handleObj.selector ) { + eventType.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( eventType.length === 0 && origCount !== eventType.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + handle = elemData.handle; + if ( handle ) { + handle.elem = null; + } + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery.removeData( elem, [ "events", "handle" ], true ); + } + }, + + // Events that are safe to short-circuit if no handlers are attached. + // Native DOM events should not be added, they may have inline handlers. + customEvent: { + "getData": true, + "setData": true, + "changeData": true + }, + + trigger: function( event, data, elem, onlyHandlers ) { + // Don't do events on text and comment nodes + if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { + return; + } + + // Event object or event type + var type = event.type || event, + namespaces = [], + cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType; + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "!" ) >= 0 ) { + // Exclusive events trigger only for the exact event (no namespaces) + type = type.slice(0, -1); + exclusive = true; + } + + if ( type.indexOf( "." ) >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + + if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { + // No jQuery handlers for this event type, and it can't have inline handlers + return; + } + + // Caller can pass in an Event, Object, or just an event type string + event = typeof event === "object" ? + // jQuery.Event object + event[ jQuery.expando ] ? event : + // Object literal + new jQuery.Event( type, event ) : + // Just the event type (string) + new jQuery.Event( type ); + + event.type = type; + event.isTrigger = true; + event.exclusive = exclusive; + event.namespace = namespaces.join( "." ); + event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; + + // Handle a global trigger + if ( !elem ) { + + // TODO: Stop taunting the data cache; remove global events and always attach to document + cache = jQuery.cache; + for ( i in cache ) { + if ( cache[ i ].events && cache[ i ].events[ type ] ) { + jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); + } + } + return; + } + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data != null ? jQuery.makeArray( data ) : []; + data.unshift( event ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + eventPath = [[ elem, special.bindType || type ]]; + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; + old = null; + for ( ; cur; cur = cur.parentNode ) { + eventPath.push([ cur, bubbleType ]); + old = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( old && old === elem.ownerDocument ) { + eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); + } + } + + // Fire handlers on the event path + for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { + + cur = eventPath[i][0]; + event.type = eventPath[i][1]; + + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + // Note that this is a bare JS function and not a jQuery handler + handle = ontype && cur[ ontype ]; + if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && + !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + // IE<9 dies on focus/blur to hidden element (#1486) + if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + old = elem[ ontype ]; + + if ( old ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( old ) { + elem[ ontype ] = old; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event || window.event ); + + var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), + delegateCount = handlers.delegateCount, + args = [].slice.call( arguments, 0 ), + run_all = !event.exclusive && !event.namespace, + handlerQueue = [], + i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Determine handlers that should run if there are delegated events + // Avoid disabled elements in IE (#6911) and non-left-click bubbling in Firefox (#3861) + if ( delegateCount && !event.target.disabled && !(event.button && event.type === "click") ) { + + // Pregenerate a single jQuery object for reuse with .is() + jqcur = jQuery(this); + jqcur.context = this.ownerDocument || this; + + for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { + selMatch = {}; + matches = []; + jqcur[0] = cur; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + sel = handleObj.selector; + + if ( selMatch[ sel ] === undefined ) { + selMatch[ sel ] = ( + handleObj.quick ? quickIs( cur, handleObj.quick ) : jqcur.is( sel ) + ); + } + if ( selMatch[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, matches: matches }); + } + } + } + + // Add the remaining (directly-bound) handlers + if ( handlers.length > delegateCount ) { + handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); + } + + // Run delegates first; they may want to stop propagation beneath us + for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { + matched = handlerQueue[ i ]; + event.currentTarget = matched.elem; + + for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { + handleObj = matched.matches[ j ]; + + // Triggered event must either 1) be non-exclusive and have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { + + event.data = handleObj.data; + event.handleObj = handleObj; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + event.result = ret; + if ( ret === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + return event.result; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** + props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, + originalEvent = event, + fixHook = jQuery.event.fixHooks[ event.type ] || {}, + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = jQuery.Event( originalEvent ); + + for ( i = copy.length; i; ) { + prop = copy[ --i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Target should not be a text node (#504, Safari) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8) + if ( event.metaKey === undefined ) { + event.metaKey = event.ctrlKey; + } + + return fixHook.filter? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + ready: { + // Make sure the ready event is setup + setup: jQuery.bindReady + }, + + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + + focus: { + delegateType: "focusin" + }, + blur: { + delegateType: "focusout" + }, + + beforeunload: { + setup: function( data, namespaces, eventHandle ) { + // We only want to do this special case on windows + if ( jQuery.isWindow( this ) ) { + this.onbeforeunload = eventHandle; + } + }, + + teardown: function( namespaces, eventHandle ) { + if ( this.onbeforeunload === eventHandle ) { + this.onbeforeunload = null; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +// Some plugins are using, but it's undocumented/deprecated and will be removed. +// The 1.7 special event interface should provide all the hooks needed now. +jQuery.event.handle = jQuery.event.dispatch; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + if ( elem.detachEvent ) { + elem.detachEvent( "on" + type, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || + src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +function returnFalse() { + return false; +} +function returnTrue() { + return true; +} + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + preventDefault: function() { + this.isDefaultPrevented = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + + // if preventDefault exists run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // otherwise set the returnValue property of the original event to false (IE) + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + this.isPropagationStopped = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + // if stopPropagation exists run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + // otherwise set the cancelBubble property of the original event to true (IE) + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + }, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var target = this, + related = event.relatedTarget, + handleObj = event.handleObj, + selector = handleObj.selector, + ret; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !form._submit_attached ) { + jQuery.event.add( form, "submit._submit", function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + }); + form._submit_attached = true; + } + }); + // return undefined since we don't need an event listener + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !jQuery.support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + jQuery.event.simulate( "change", this, event, true ); + } + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + elem._change_attached = true; + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !jQuery.support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler while someone wants focusin/focusout + var attaches = 0, + handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + // ( types-Object, data ) + data = selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on.call( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + var handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace? handleObj.type + "." + handleObj.namespace : handleObj.type, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( var type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + live: function( types, data, fn ) { + jQuery( this.context ).on( types, this.selector, data, fn ); + return this; + }, + die: function( types, fn ) { + jQuery( this.context ).off( types, this.selector || "**", fn ); + return this; + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn ); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + if ( this[0] ) { + return jQuery.event.trigger( type, data, this[0], true ); + } + }, + + toggle: function( fn ) { + // Save reference to arguments for access in closure + var args = arguments, + guid = fn.guid || jQuery.guid++, + i = 0, + toggler = function( event ) { + // Figure out which function to execute + var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; + jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); + + // Make sure that clicks stop + event.preventDefault(); + + // and execute the function + return args[ lastToggle ].apply( this, arguments ) || false; + }; + + // link all the functions, so any of them can unbind this click handler + toggler.guid = guid; + while ( i < args.length ) { + args[ i++ ].guid = guid; + } + + return this.click( toggler ); + }, + + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); + } +}); + +jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + if ( fn == null ) { + fn = data; + data = null; + } + + return arguments.length > 0 ? + this.on( name, null, data, fn ) : + this.trigger( name ); + }; + + if ( jQuery.attrFn ) { + jQuery.attrFn[ name ] = true; + } + + if ( rkeyEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; + } + + if ( rmouseEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; + } +}); + + + +/*! + * Sizzle CSS Selector Engine + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){ + +var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, + expando = "sizcache" + (Math.random() + '').replace('.', ''), + done = 0, + toString = Object.prototype.toString, + hasDuplicate = false, + baseHasDuplicate = true, + rBackslash = /\\/g, + rReturn = /\r\n/g, + rNonWord = /\W/; + +// Here we check if the JavaScript engine is using some sort of +// optimization where it does not always call our comparision +// function. If that is the case, discard the hasDuplicate value. +// Thus far that includes Google Chrome. +[0, 0].sort(function() { + baseHasDuplicate = false; + return 0; +}); + +var Sizzle = function( selector, context, results, seed ) { + results = results || []; + context = context || document; + + var origContext = context; + + if ( context.nodeType !== 1 && context.nodeType !== 9 ) { + return []; + } + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + var m, set, checkSet, extra, ret, cur, pop, i, + prune = true, + contextXML = Sizzle.isXML( context ), + parts = [], + soFar = selector; + + // Reset the position of the chunker regexp (start from head) + do { + chunker.exec( "" ); + m = chunker.exec( soFar ); + + if ( m ) { + soFar = m[3]; + + parts.push( m[1] ); + + if ( m[2] ) { + extra = m[3]; + break; + } + } + } while ( m ); + + if ( parts.length > 1 && origPOS.exec( selector ) ) { + + if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { + set = posProcess( parts[0] + parts[1], context, seed ); + + } else { + set = Expr.relative[ parts[0] ] ? + [ context ] : + Sizzle( parts.shift(), context ); + + while ( parts.length ) { + selector = parts.shift(); + + if ( Expr.relative[ selector ] ) { + selector += parts.shift(); + } + + set = posProcess( selector, set, seed ); + } + } + + } else { + // Take a shortcut and set the context if the root selector is an ID + // (but not if it'll be faster if the inner selector is an ID) + if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && + Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { + + ret = Sizzle.find( parts.shift(), context, contextXML ); + context = ret.expr ? + Sizzle.filter( ret.expr, ret.set )[0] : + ret.set[0]; + } + + if ( context ) { + ret = seed ? + { expr: parts.pop(), set: makeArray(seed) } : + Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); + + set = ret.expr ? + Sizzle.filter( ret.expr, ret.set ) : + ret.set; + + if ( parts.length > 0 ) { + checkSet = makeArray( set ); + + } else { + prune = false; + } + + while ( parts.length ) { + cur = parts.pop(); + pop = cur; + + if ( !Expr.relative[ cur ] ) { + cur = ""; + } else { + pop = parts.pop(); + } + + if ( pop == null ) { + pop = context; + } + + Expr.relative[ cur ]( checkSet, pop, contextXML ); + } + + } else { + checkSet = parts = []; + } + } + + if ( !checkSet ) { + checkSet = set; + } + + if ( !checkSet ) { + Sizzle.error( cur || selector ); + } + + if ( toString.call(checkSet) === "[object Array]" ) { + if ( !prune ) { + results.push.apply( results, checkSet ); + + } else if ( context && context.nodeType === 1 ) { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { + results.push( set[i] ); + } + } + + } else { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && checkSet[i].nodeType === 1 ) { + results.push( set[i] ); + } + } + } + + } else { + makeArray( checkSet, results ); + } + + if ( extra ) { + Sizzle( extra, origContext, results, seed ); + Sizzle.uniqueSort( results ); + } + + return results; +}; + +Sizzle.uniqueSort = function( results ) { + if ( sortOrder ) { + hasDuplicate = baseHasDuplicate; + results.sort( sortOrder ); + + if ( hasDuplicate ) { + for ( var i = 1; i < results.length; i++ ) { + if ( results[i] === results[ i - 1 ] ) { + results.splice( i--, 1 ); + } + } + } + } + + return results; +}; + +Sizzle.matches = function( expr, set ) { + return Sizzle( expr, null, null, set ); +}; + +Sizzle.matchesSelector = function( node, expr ) { + return Sizzle( expr, null, null, [node] ).length > 0; +}; + +Sizzle.find = function( expr, context, isXML ) { + var set, i, len, match, type, left; + + if ( !expr ) { + return []; + } + + for ( i = 0, len = Expr.order.length; i < len; i++ ) { + type = Expr.order[i]; + + if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { + left = match[1]; + match.splice( 1, 1 ); + + if ( left.substr( left.length - 1 ) !== "\\" ) { + match[1] = (match[1] || "").replace( rBackslash, "" ); + set = Expr.find[ type ]( match, context, isXML ); + + if ( set != null ) { + expr = expr.replace( Expr.match[ type ], "" ); + break; + } + } + } + } + + if ( !set ) { + set = typeof context.getElementsByTagName !== "undefined" ? + context.getElementsByTagName( "*" ) : + []; + } + + return { set: set, expr: expr }; +}; + +Sizzle.filter = function( expr, set, inplace, not ) { + var match, anyFound, + type, found, item, filter, left, + i, pass, + old = expr, + result = [], + curLoop = set, + isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); + + while ( expr && set.length ) { + for ( type in Expr.filter ) { + if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { + filter = Expr.filter[ type ]; + left = match[1]; + + anyFound = false; + + match.splice(1,1); + + if ( left.substr( left.length - 1 ) === "\\" ) { + continue; + } + + if ( curLoop === result ) { + result = []; + } + + if ( Expr.preFilter[ type ] ) { + match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); + + if ( !match ) { + anyFound = found = true; + + } else if ( match === true ) { + continue; + } + } + + if ( match ) { + for ( i = 0; (item = curLoop[i]) != null; i++ ) { + if ( item ) { + found = filter( item, match, i, curLoop ); + pass = not ^ found; + + if ( inplace && found != null ) { + if ( pass ) { + anyFound = true; + + } else { + curLoop[i] = false; + } + + } else if ( pass ) { + result.push( item ); + anyFound = true; + } + } + } + } + + if ( found !== undefined ) { + if ( !inplace ) { + curLoop = result; + } + + expr = expr.replace( Expr.match[ type ], "" ); + + if ( !anyFound ) { + return []; + } + + break; + } + } + } + + // Improper expression + if ( expr === old ) { + if ( anyFound == null ) { + Sizzle.error( expr ); + + } else { + break; + } + } + + old = expr; + } + + return curLoop; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Utility function for retreiving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +var getText = Sizzle.getText = function( elem ) { + var i, node, + nodeType = elem.nodeType, + ret = ""; + + if ( nodeType ) { + if ( nodeType === 1 || nodeType === 9 ) { + // Use textContent || innerText for elements + if ( typeof elem.textContent === 'string' ) { + return elem.textContent; + } else if ( typeof elem.innerText === 'string' ) { + // Replace IE's carriage returns + return elem.innerText.replace( rReturn, '' ); + } else { + // Traverse it's children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + } else { + + // If no nodeType, this is expected to be an array + for ( i = 0; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + if ( node.nodeType !== 8 ) { + ret += getText( node ); + } + } + } + return ret; +}; + +var Expr = Sizzle.selectors = { + order: [ "ID", "NAME", "TAG" ], + + match: { + ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, + ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, + TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, + CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, + POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, + PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ + }, + + leftMatch: {}, + + attrMap: { + "class": "className", + "for": "htmlFor" + }, + + attrHandle: { + href: function( elem ) { + return elem.getAttribute( "href" ); + }, + type: function( elem ) { + return elem.getAttribute( "type" ); + } + }, + + relative: { + "+": function(checkSet, part){ + var isPartStr = typeof part === "string", + isTag = isPartStr && !rNonWord.test( part ), + isPartStrNotTag = isPartStr && !isTag; + + if ( isTag ) { + part = part.toLowerCase(); + } + + for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { + if ( (elem = checkSet[i]) ) { + while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} + + checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? + elem || false : + elem === part; + } + } + + if ( isPartStrNotTag ) { + Sizzle.filter( part, checkSet, true ); + } + }, + + ">": function( checkSet, part ) { + var elem, + isPartStr = typeof part === "string", + i = 0, + l = checkSet.length; + + if ( isPartStr && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + var parent = elem.parentNode; + checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; + } + } + + } else { + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + checkSet[i] = isPartStr ? + elem.parentNode : + elem.parentNode === part; + } + } + + if ( isPartStr ) { + Sizzle.filter( part, checkSet, true ); + } + } + }, + + "": function(checkSet, part, isXML){ + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); + }, + + "~": function( checkSet, part, isXML ) { + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); + } + }, + + find: { + ID: function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + }, + + NAME: function( match, context ) { + if ( typeof context.getElementsByName !== "undefined" ) { + var ret = [], + results = context.getElementsByName( match[1] ); + + for ( var i = 0, l = results.length; i < l; i++ ) { + if ( results[i].getAttribute("name") === match[1] ) { + ret.push( results[i] ); + } + } + + return ret.length === 0 ? null : ret; + } + }, + + TAG: function( match, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( match[1] ); + } + } + }, + preFilter: { + CLASS: function( match, curLoop, inplace, result, not, isXML ) { + match = " " + match[1].replace( rBackslash, "" ) + " "; + + if ( isXML ) { + return match; + } + + for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { + if ( elem ) { + if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { + if ( !inplace ) { + result.push( elem ); + } + + } else if ( inplace ) { + curLoop[i] = false; + } + } + } + + return false; + }, + + ID: function( match ) { + return match[1].replace( rBackslash, "" ); + }, + + TAG: function( match, curLoop ) { + return match[1].replace( rBackslash, "" ).toLowerCase(); + }, + + CHILD: function( match ) { + if ( match[1] === "nth" ) { + if ( !match[2] ) { + Sizzle.error( match[0] ); + } + + match[2] = match[2].replace(/^\+|\s*/g, ''); + + // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' + var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( + match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || + !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); + + // calculate the numbers (first)n+(last) including if they are negative + match[2] = (test[1] + (test[2] || 1)) - 0; + match[3] = test[3] - 0; + } + else if ( match[2] ) { + Sizzle.error( match[0] ); + } + + // TODO: Move to normal caching system + match[0] = done++; + + return match; + }, + + ATTR: function( match, curLoop, inplace, result, not, isXML ) { + var name = match[1] = match[1].replace( rBackslash, "" ); + + if ( !isXML && Expr.attrMap[name] ) { + match[1] = Expr.attrMap[name]; + } + + // Handle if an un-quoted value was used + match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); + + if ( match[2] === "~=" ) { + match[4] = " " + match[4] + " "; + } + + return match; + }, + + PSEUDO: function( match, curLoop, inplace, result, not ) { + if ( match[1] === "not" ) { + // If we're dealing with a complex expression, or a simple one + if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { + match[3] = Sizzle(match[3], null, null, curLoop); + + } else { + var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); + + if ( !inplace ) { + result.push.apply( result, ret ); + } + + return false; + } + + } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { + return true; + } + + return match; + }, + + POS: function( match ) { + match.unshift( true ); + + return match; + } + }, + + filters: { + enabled: function( elem ) { + return elem.disabled === false && elem.type !== "hidden"; + }, + + disabled: function( elem ) { + return elem.disabled === true; + }, + + checked: function( elem ) { + return elem.checked === true; + }, + + selected: function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + parent: function( elem ) { + return !!elem.firstChild; + }, + + empty: function( elem ) { + return !elem.firstChild; + }, + + has: function( elem, i, match ) { + return !!Sizzle( match[3], elem ).length; + }, + + header: function( elem ) { + return (/h\d/i).test( elem.nodeName ); + }, + + text: function( elem ) { + var attr = elem.getAttribute( "type" ), type = elem.type; + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null ); + }, + + radio: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; + }, + + checkbox: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; + }, + + file: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; + }, + + password: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; + }, + + submit: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "submit" === elem.type; + }, + + image: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "image" === elem.type; + }, + + reset: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "reset" === elem.type; + }, + + button: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && "button" === elem.type || name === "button"; + }, + + input: function( elem ) { + return (/input|select|textarea|button/i).test( elem.nodeName ); + }, + + focus: function( elem ) { + return elem === elem.ownerDocument.activeElement; + } + }, + setFilters: { + first: function( elem, i ) { + return i === 0; + }, + + last: function( elem, i, match, array ) { + return i === array.length - 1; + }, + + even: function( elem, i ) { + return i % 2 === 0; + }, + + odd: function( elem, i ) { + return i % 2 === 1; + }, + + lt: function( elem, i, match ) { + return i < match[3] - 0; + }, + + gt: function( elem, i, match ) { + return i > match[3] - 0; + }, + + nth: function( elem, i, match ) { + return match[3] - 0 === i; + }, + + eq: function( elem, i, match ) { + return match[3] - 0 === i; + } + }, + filter: { + PSEUDO: function( elem, match, i, array ) { + var name = match[1], + filter = Expr.filters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + + } else if ( name === "contains" ) { + return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0; + + } else if ( name === "not" ) { + var not = match[3]; + + for ( var j = 0, l = not.length; j < l; j++ ) { + if ( not[j] === elem ) { + return false; + } + } + + return true; + + } else { + Sizzle.error( name ); + } + }, + + CHILD: function( elem, match ) { + var first, last, + doneName, parent, cache, + count, diff, + type = match[1], + node = elem; + + switch ( type ) { + case "only": + case "first": + while ( (node = node.previousSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + if ( type === "first" ) { + return true; + } + + node = elem; + + case "last": + while ( (node = node.nextSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + return true; + + case "nth": + first = match[2]; + last = match[3]; + + if ( first === 1 && last === 0 ) { + return true; + } + + doneName = match[0]; + parent = elem.parentNode; + + if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) { + count = 0; + + for ( node = parent.firstChild; node; node = node.nextSibling ) { + if ( node.nodeType === 1 ) { + node.nodeIndex = ++count; + } + } + + parent[ expando ] = doneName; + } + + diff = elem.nodeIndex - last; + + if ( first === 0 ) { + return diff === 0; + + } else { + return ( diff % first === 0 && diff / first >= 0 ); + } + } + }, + + ID: function( elem, match ) { + return elem.nodeType === 1 && elem.getAttribute("id") === match; + }, + + TAG: function( elem, match ) { + return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match; + }, + + CLASS: function( elem, match ) { + return (" " + (elem.className || elem.getAttribute("class")) + " ") + .indexOf( match ) > -1; + }, + + ATTR: function( elem, match ) { + var name = match[1], + result = Sizzle.attr ? + Sizzle.attr( elem, name ) : + Expr.attrHandle[ name ] ? + Expr.attrHandle[ name ]( elem ) : + elem[ name ] != null ? + elem[ name ] : + elem.getAttribute( name ), + value = result + "", + type = match[2], + check = match[4]; + + return result == null ? + type === "!=" : + !type && Sizzle.attr ? + result != null : + type === "=" ? + value === check : + type === "*=" ? + value.indexOf(check) >= 0 : + type === "~=" ? + (" " + value + " ").indexOf(check) >= 0 : + !check ? + value && result !== false : + type === "!=" ? + value !== check : + type === "^=" ? + value.indexOf(check) === 0 : + type === "$=" ? + value.substr(value.length - check.length) === check : + type === "|=" ? + value === check || value.substr(0, check.length + 1) === check + "-" : + false; + }, + + POS: function( elem, match, i, array ) { + var name = match[2], + filter = Expr.setFilters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + } + } + } +}; + +var origPOS = Expr.match.POS, + fescape = function(all, num){ + return "\\" + (num - 0 + 1); + }; + +for ( var type in Expr.match ) { + Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); + Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); +} + +var makeArray = function( array, results ) { + array = Array.prototype.slice.call( array, 0 ); + + if ( results ) { + results.push.apply( results, array ); + return results; + } + + return array; +}; + +// Perform a simple check to determine if the browser is capable of +// converting a NodeList to an array using builtin methods. +// Also verifies that the returned array holds DOM nodes +// (which is not the case in the Blackberry browser) +try { + Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; + +// Provide a fallback method if it does not work +} catch( e ) { + makeArray = function( array, results ) { + var i = 0, + ret = results || []; + + if ( toString.call(array) === "[object Array]" ) { + Array.prototype.push.apply( ret, array ); + + } else { + if ( typeof array.length === "number" ) { + for ( var l = array.length; i < l; i++ ) { + ret.push( array[i] ); + } + + } else { + for ( ; array[i]; i++ ) { + ret.push( array[i] ); + } + } + } + + return ret; + }; +} + +var sortOrder, siblingCheck; + +if ( document.documentElement.compareDocumentPosition ) { + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { + return a.compareDocumentPosition ? -1 : 1; + } + + return a.compareDocumentPosition(b) & 4 ? -1 : 1; + }; + +} else { + sortOrder = function( a, b ) { + // The nodes are identical, we can exit early + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Fallback to using sourceIndex (in IE) if it's available on both nodes + } else if ( a.sourceIndex && b.sourceIndex ) { + return a.sourceIndex - b.sourceIndex; + } + + var al, bl, + ap = [], + bp = [], + aup = a.parentNode, + bup = b.parentNode, + cur = aup; + + // If the nodes are siblings (or identical) we can do a quick check + if ( aup === bup ) { + return siblingCheck( a, b ); + + // If no parents were found then the nodes are disconnected + } else if ( !aup ) { + return -1; + + } else if ( !bup ) { + return 1; + } + + // Otherwise they're somewhere else in the tree so we need + // to build up a full list of the parentNodes for comparison + while ( cur ) { + ap.unshift( cur ); + cur = cur.parentNode; + } + + cur = bup; + + while ( cur ) { + bp.unshift( cur ); + cur = cur.parentNode; + } + + al = ap.length; + bl = bp.length; + + // Start walking down the tree looking for a discrepancy + for ( var i = 0; i < al && i < bl; i++ ) { + if ( ap[i] !== bp[i] ) { + return siblingCheck( ap[i], bp[i] ); + } + } + + // We ended someplace up the tree so do a sibling check + return i === al ? + siblingCheck( a, bp[i], -1 ) : + siblingCheck( ap[i], b, 1 ); + }; + + siblingCheck = function( a, b, ret ) { + if ( a === b ) { + return ret; + } + + var cur = a.nextSibling; + + while ( cur ) { + if ( cur === b ) { + return -1; + } + + cur = cur.nextSibling; + } + + return 1; + }; +} + +// Check to see if the browser returns elements by name when +// querying by getElementById (and provide a workaround) +(function(){ + // We're going to inject a fake input element with a specified name + var form = document.createElement("div"), + id = "script" + (new Date()).getTime(), + root = document.documentElement; + + form.innerHTML = ""; + + // Inject it into the root element, check its status, and remove it quickly + root.insertBefore( form, root.firstChild ); + + // The workaround has to do additional checks after a getElementById + // Which slows things down for other browsers (hence the branching) + if ( document.getElementById( id ) ) { + Expr.find.ID = function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + + return m ? + m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? + [m] : + undefined : + []; + } + }; + + Expr.filter.ID = function( elem, match ) { + var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + + return elem.nodeType === 1 && node && node.nodeValue === match; + }; + } + + root.removeChild( form ); + + // release memory in IE + root = form = null; +})(); + +(function(){ + // Check to see if the browser returns only elements + // when doing getElementsByTagName("*") + + // Create a fake element + var div = document.createElement("div"); + div.appendChild( document.createComment("") ); + + // Make sure no comments are found + if ( div.getElementsByTagName("*").length > 0 ) { + Expr.find.TAG = function( match, context ) { + var results = context.getElementsByTagName( match[1] ); + + // Filter out possible comments + if ( match[1] === "*" ) { + var tmp = []; + + for ( var i = 0; results[i]; i++ ) { + if ( results[i].nodeType === 1 ) { + tmp.push( results[i] ); + } + } + + results = tmp; + } + + return results; + }; + } + + // Check to see if an attribute returns normalized href attributes + div.innerHTML = ""; + + if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && + div.firstChild.getAttribute("href") !== "#" ) { + + Expr.attrHandle.href = function( elem ) { + return elem.getAttribute( "href", 2 ); + }; + } + + // release memory in IE + div = null; +})(); + +if ( document.querySelectorAll ) { + (function(){ + var oldSizzle = Sizzle, + div = document.createElement("div"), + id = "__sizzle__"; + + div.innerHTML = "

      "; + + // Safari can't handle uppercase or unicode characters when + // in quirks mode. + if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { + return; + } + + Sizzle = function( query, context, extra, seed ) { + context = context || document; + + // Only use querySelectorAll on non-XML documents + // (ID selectors don't work in non-HTML documents) + if ( !seed && !Sizzle.isXML(context) ) { + // See if we find a selector to speed up + var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); + + if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { + // Speed-up: Sizzle("TAG") + if ( match[1] ) { + return makeArray( context.getElementsByTagName( query ), extra ); + + // Speed-up: Sizzle(".CLASS") + } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { + return makeArray( context.getElementsByClassName( match[2] ), extra ); + } + } + + if ( context.nodeType === 9 ) { + // Speed-up: Sizzle("body") + // The body element only exists once, optimize finding it + if ( query === "body" && context.body ) { + return makeArray( [ context.body ], extra ); + + // Speed-up: Sizzle("#ID") + } else if ( match && match[3] ) { + var elem = context.getElementById( match[3] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id === match[3] ) { + return makeArray( [ elem ], extra ); + } + + } else { + return makeArray( [], extra ); + } + } + + try { + return makeArray( context.querySelectorAll(query), extra ); + } catch(qsaError) {} + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + var oldContext = context, + old = context.getAttribute( "id" ), + nid = old || id, + hasParent = context.parentNode, + relativeHierarchySelector = /^\s*[+~]/.test( query ); + + if ( !old ) { + context.setAttribute( "id", nid ); + } else { + nid = nid.replace( /'/g, "\\$&" ); + } + if ( relativeHierarchySelector && hasParent ) { + context = context.parentNode; + } + + try { + if ( !relativeHierarchySelector || hasParent ) { + return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); + } + + } catch(pseudoError) { + } finally { + if ( !old ) { + oldContext.removeAttribute( "id" ); + } + } + } + } + + return oldSizzle(query, context, extra, seed); + }; + + for ( var prop in oldSizzle ) { + Sizzle[ prop ] = oldSizzle[ prop ]; + } + + // release memory in IE + div = null; + })(); +} + +(function(){ + var html = document.documentElement, + matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector; + + if ( matches ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9 fails this) + var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ), + pseudoWorks = false; + + try { + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( document.documentElement, "[test!='']:sizzle" ); + + } catch( pseudoError ) { + pseudoWorks = true; + } + + Sizzle.matchesSelector = function( node, expr ) { + // Make sure that attribute selectors are quoted + expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); + + if ( !Sizzle.isXML( node ) ) { + try { + if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { + var ret = matches.call( node, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || !disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9, so check for that + node.document && node.document.nodeType !== 11 ) { + return ret; + } + } + } catch(e) {} + } + + return Sizzle(expr, null, null, [node]).length > 0; + }; + } +})(); + +(function(){ + var div = document.createElement("div"); + + div.innerHTML = "
      "; + + // Opera can't find a second classname (in 9.6) + // Also, make sure that getElementsByClassName actually exists + if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { + return; + } + + // Safari caches class attributes, doesn't catch changes (in 3.2) + div.lastChild.className = "e"; + + if ( div.getElementsByClassName("e").length === 1 ) { + return; + } + + Expr.order.splice(1, 0, "CLASS"); + Expr.find.CLASS = function( match, context, isXML ) { + if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { + return context.getElementsByClassName(match[1]); + } + }; + + // release memory in IE + div = null; +})(); + +function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem[ expando ] === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 && !isXML ){ + elem[ expando ] = doneName; + elem.sizset = i; + } + + if ( elem.nodeName.toLowerCase() === cur ) { + match = elem; + break; + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem[ expando ] === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 ) { + if ( !isXML ) { + elem[ expando ] = doneName; + elem.sizset = i; + } + + if ( typeof cur !== "string" ) { + if ( elem === cur ) { + match = true; + break; + } + + } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { + match = elem; + break; + } + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +if ( document.documentElement.contains ) { + Sizzle.contains = function( a, b ) { + return a !== b && (a.contains ? a.contains(b) : true); + }; + +} else if ( document.documentElement.compareDocumentPosition ) { + Sizzle.contains = function( a, b ) { + return !!(a.compareDocumentPosition(b) & 16); + }; + +} else { + Sizzle.contains = function() { + return false; + }; +} + +Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; + + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +var posProcess = function( selector, context, seed ) { + var match, + tmpSet = [], + later = "", + root = context.nodeType ? [context] : context; + + // Position selectors must be done after the filter + // And so must :not(positional) so we move all PSEUDOs to the end + while ( (match = Expr.match.PSEUDO.exec( selector )) ) { + later += match[0]; + selector = selector.replace( Expr.match.PSEUDO, "" ); + } + + selector = Expr.relative[selector] ? selector + "*" : selector; + + for ( var i = 0, l = root.length; i < l; i++ ) { + Sizzle( selector, root[i], tmpSet, seed ); + } + + return Sizzle.filter( later, tmpSet ); +}; + +// EXPOSE +// Override sizzle attribute retrieval +Sizzle.attr = jQuery.attr; +Sizzle.selectors.attrMap = {}; +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.filters; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})(); + + +var runtil = /Until$/, + rparentsprev = /^(?:parents|prevUntil|prevAll)/, + // Note: This RegExp should be improved, or likely pulled from Sizzle + rmultiselector = /,/, + isSimple = /^.[^:#\[\.,]*$/, + slice = Array.prototype.slice, + POS = jQuery.expr.match.POS, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend({ + find: function( selector ) { + var self = this, + i, l; + + if ( typeof selector !== "string" ) { + return jQuery( selector ).filter(function() { + for ( i = 0, l = self.length; i < l; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }); + } + + var ret = this.pushStack( "", "find", selector ), + length, n, r; + + for ( i = 0, l = this.length; i < l; i++ ) { + length = ret.length; + jQuery.find( selector, this[i], ret ); + + if ( i > 0 ) { + // Make sure that the results are unique + for ( n = length; n < ret.length; n++ ) { + for ( r = 0; r < length; r++ ) { + if ( ret[r] === ret[n] ) { + ret.splice(n--, 1); + break; + } + } + } + } + } + + return ret; + }, + + has: function( target ) { + var targets = jQuery( target ); + return this.filter(function() { + for ( var i = 0, l = targets.length; i < l; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector, false), "not", selector); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector, true), "filter", selector ); + }, + + is: function( selector ) { + return !!selector && ( + typeof selector === "string" ? + // If this is a positional selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + POS.test( selector ) ? + jQuery( selector, this.context ).index( this[0] ) >= 0 : + jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); + }, + + closest: function( selectors, context ) { + var ret = [], i, l, cur = this[0]; + + // Array (deprecated as of jQuery 1.7) + if ( jQuery.isArray( selectors ) ) { + var level = 1; + + while ( cur && cur.ownerDocument && cur !== context ) { + for ( i = 0; i < selectors.length; i++ ) { + + if ( jQuery( cur ).is( selectors[ i ] ) ) { + ret.push({ selector: selectors[ i ], elem: cur, level: level }); + } + } + + cur = cur.parentNode; + level++; + } + + return ret; + } + + // String + var pos = POS.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( i = 0, l = this.length; i < l; i++ ) { + cur = this[i]; + + while ( cur ) { + if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { + ret.push( cur ); + break; + + } else { + cur = cur.parentNode; + if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) { + break; + } + } + } + } + + ret = ret.length > 1 ? jQuery.unique( ret ) : ret; + + return this.pushStack( ret, "closest", selectors ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + jQuery( selector, context ) : + jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), + all = jQuery.merge( this.get(), set ); + + return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? + all : + jQuery.unique( all ) ); + }, + + andSelf: function() { + return this.add( this.prevObject ); + } +}); + +// A painfully simple check to see if an element is disconnected +// from a document (should be improved, where feasible). +function isDisconnected( node ) { + return !node || !node.parentNode || node.parentNode.nodeType === 11; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return jQuery.nth( elem, 2, "nextSibling" ); + }, + prev: function( elem ) { + return jQuery.nth( elem, 2, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( elem.parentNode.firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.makeArray( elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( !runtil.test( name ) ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; + + if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + + return this.pushStack( ret, name, slice.call( arguments ).join(",") ); + }; +}); + +jQuery.extend({ + filter: function( expr, elems, not ) { + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 ? + jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : + jQuery.find.matches(expr, elems); + }, + + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + nth: function( cur, result, dir, elem ) { + result = result || 1; + var num = 0; + + for ( ; cur; cur = cur[dir] ) { + if ( cur.nodeType === 1 && ++num === result ) { + break; + } + } + + return cur; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, keep ) { + + // Can't pass null or undefined to indexOf in Firefox 4 + // Set to 0 to skip string check + qualifier = qualifier || 0; + + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep(elements, function( elem, i ) { + var retVal = !!qualifier.call( elem, i, elem ); + return retVal === keep; + }); + + } else if ( qualifier.nodeType ) { + return jQuery.grep(elements, function( elem, i ) { + return ( elem === qualifier ) === keep; + }); + + } else if ( typeof qualifier === "string" ) { + var filtered = jQuery.grep(elements, function( elem ) { + return elem.nodeType === 1; + }); + + if ( isSimple.test( qualifier ) ) { + return jQuery.filter(qualifier, filtered, !keep); + } else { + qualifier = jQuery.filter( qualifier, filtered ); + } + } + + return jQuery.grep(elements, function( elem, i ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; + }); +} + + + + +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, + rtagName = /<([\w:]+)/, + rtbody = /", "" ], + legend: [ 1, "
      ", "
      " ], + thead: [ 1, "", "
      " ], + tr: [ 2, "", "
      " ], + td: [ 3, "", "
      " ], + col: [ 2, "", "
      " ], + area: [ 1, "", "" ], + _default: [ 0, "", "" ] + }, + safeFragment = createSafeFragment( document ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// IE can't serialize and ") -# output("") output("") output(title) output("") @@ -88,21 +112,197 @@ def checkbox(title, value, script=""): return """""" % (title, "checked" if value else "", ("onclick=\"%s\"" % script) if script else "") + + def sendjson(message): + handler.send_head(content = "application/json") + output(json.dumps(message,sort_keys=False)) + + def sendFile(filename,content_type): + f = open(os.path.join(src_folder,filename), 'rb') - if handler.path == "/html/netrender.js": - f = open(os.path.join(src_folder, "netrender.js"), 'rb') - - handler.send_head(content = "text/javascript") + handler.send_head(content = content_type) shutil.copyfileobj(f, handler.wfile) f.close() + # return serialized version of job for html interface + # job: the base job + # includeFiles: boolean to indicate if we want file to be serialized too into job + # includeFrames; boolean to indicate if we want frame to be serialized too into job + def gethtmlJobInfo(job,includeFiles=True,includeFrames=True): + if (job): + results = job.framesStatus() + serializedJob = job.serialize(withFiles=includeFiles, withFrames=includeFrames) + serializedJob["p_rule"] = handler.server.balancer.applyPriorities(job) + serializedJob["e_rule"] = handler.server.balancer.applyExceptions(job) + serializedJob["wait"] = int(time.time() - job.last_dispatched) if job.status != JOB_FINISHED else "N/A" + serializedJob["length"] = len(job); + serializedJob["done"] = results[FRAME_DONE] + serializedJob["dispatched"] = results[FRAME_DISPATCHED] + serializedJob["error"] = results[FRAME_ERROR] + tot_cache, tot_fluid, tot_other = countFiles(job) + serializedJob["totcache"] = tot_cache + serializedJob["totfluid"] = tot_fluid + serializedJob["totother"] = tot_other + serializedJob["wktime"] = (time.time()-job.start_time ) if job.status != JOB_FINISHED else (job.finish_time-job.start_time) + else: + serializedJob={"name":"invalid job"} + + return serializedJob; + + # return serialized files based on cumulative file_type + # job_id: id of the job + # message: serialized content + # file_type: any combinaison of CACHE_FILE,FLUID_FILES, OTHER_FILES + + def getFiles(job_id,message,file_type): + + job=handler.server.getJobID(job_id) + print ("job.files.length="+str(len(job.files))) + + for file in job.files: + filedata=file.serialize() + filedata["name"] = os.path.split(file.filepath)[1] + + if file.filepath.endswith(".bphys") and (file_type & CACHE_FILES): + message.append(filedata); + continue + if (file.filepath.endswith(".bobj.gz") or file.filepath.endswith(".bvel.gz")) and (file_type & FLUID_FILES): + message.append(filedata); + continue + if (not file == job.files[0]) and (file_type & OTHER_FILES) and ( not (file.filepath.endswith(".bobj.gz") or file.filepath.endswith(".bvel.gz"))) and not file.filepath.endswith(".bphys"): + message.append(filedata); + continue + + + + if handler.path == "/html/netrender.js": + sendFile("netrender.js","text/javascript") + elif handler.path == "/html/netrender.css": - f = open(os.path.join(src_folder, "netrender.css"), 'rb') - - handler.send_head(content = "text/css") - shutil.copyfileobj(f, handler.wfile) - - f.close() + sendFile("netrender.css","text/css") + + elif handler.path =="/html/newui": + sendFile("newui.html","text/html") + + elif handler.path.startswith("/html/js"): + path, filename = os.path.split(handler.path) + sendFile("js/"+filename,"text/javascript") + + elif handler.path.startswith("/html/css/images"): + path, filename = os.path.split(handler.path) + sendFile("css/images/"+filename,"image/png") + + elif handler.path.startswith("/html/css"): + path, filename = os.path.split(handler.path) + sendFile("css/"+filename,"text/css") + # return all master rules information + elif handler.path == "/html/rules": + message = [] + for rule in handler.server.balancer.rules: + message.append(rule.serialize()) + for rule in handler.server.balancer.priorities: + message.append(rule.serialize()) + for rule in handler.server.balancer.exceptions: + message.append(rule.serialize()) + sendjson(message) + #return all slaves list + elif handler.path == "/html/slaves": + message = [] + for slave in handler.server.slaves: + serializedSlave = slave.serialize() + if slave.job: + serializedSlave["job_name"] = slave.job.name + serializedSlave["job_id"] = slave.job.id + else: + serializedSlave["job_name"] = "None" + serializedSlave["job_id"] = "0" + message.append(serializedSlave) + sendjson(message) + # return all job list + elif handler.path == "/html/jobs": + message = [] + for job in handler.server.jobs: + if job: + message.append(gethtmlJobInfo(job, False, False)) + sendjson(message) + #return a job information + elif handler.path.startswith("/html/job_"): + + job_id = handler.path[10:] + job = handler.server.getJobID(job_id) + + message = [] + if job: + + message.append(gethtmlJobInfo(job, includeFiles=False)) + sendjson(message) + # return all frames for a job + elif handler.path.startswith("/html/frames_"): + + job_id = handler.path[13:] + job = handler.server.getJobID(job_id) + + message = [] + if job: + for f in job.frames: + message.append(f.serialize()) + + sendjson(message) + # return physic cache files + elif handler.path.startswith("/html/cachefiles_"): + job_id = handler.path[17:] + message = [] + getFiles(job_id, message, CACHE_FILES); + sendjson(message) + #return fluid cache files + elif handler.path.startswith("/html/fluidfiles_"): + job_id = handler.path[17:] + + message = [] + getFiles(job_id, message, FLUID_FILES); + sendjson(message) + + #return list of other files ( images, sequences ...) + elif handler.path.startswith("/html/otherfiles_"): + job_id = handler.path[17:] + + message = [] + getFiles(job_id, message, OTHER_FILES); + sendjson(message) + # return blend file info + elif handler.path.startswith("/html/blendfile_"): + job_id = handler.path[16:] + job = handler.server.getJobID(job_id) + message = [] + if job: + if job.files: + message.append(job.files[0].serialize()) + sendjson(message) + # return black listed slaves for a job + elif handler.path.startswith("/html/blacklist_"): + + job_id = handler.path[16:] + job = handler.server.getJobID(job_id) + + message = [] + if job: + for slave_id in job.blacklist: + slave = handler.server.slaves_map.get(slave_id, None) + message.append(slave.serialize()) + sendjson(message) + # return all slaves currently assigned to a job + + elif handler.path.startswith("/html/slavesjob_"): + + job_id = handler.path[16:] + job = handler.server.getJobID(job_id) + message = [] + if job: + for slave in handler.server.slaves: + if slave.job and slave.job == job: + message.append(slave.serialize()) + sendjson(message) + # here begin code for simple ui elif handler.path == "/html" or handler.path == "/": handler.send_head(content = "text/html") head("NetRender", refresh = True) @@ -115,13 +315,14 @@ "id", "name", "category", + "tags", "type", "chunks", "priority", "usage", "wait", "status", - "length", + "total", "done", "dispatched", "error", @@ -140,7 +341,8 @@ job.id, link(job.name, "/html/job" + job.id), job.category if job.category else "None", - netrender.model.JOB_TYPES[job.type], + ";".join(sorted(job.tags)) if job.tags else "None", + "%s [%s]" % (netrender.model.JOB_TYPES[job.type], netrender.model.JOB_SUBTYPES[job.subtype]), str(job.chunks) + """""" % (job.id, job.chunks + 1) + """""" % (job.id, job.chunks - 1, "disabled=True" if job.chunks == 1 else ""), @@ -148,13 +350,13 @@ """""" % (job.id, job.priority + 1) + """""" % (job.id, job.priority - 1, "disabled=True" if job.priority == 1 else ""), "%0.1f%%" % (job.usage * 100), - "%is" % int(time.time() - job.last_dispatched), + "%is" % int(time.time() - job.last_dispatched) if job.status != JOB_FINISHED else "N/A", job.statusText(), len(job), - results[DONE], - results[DISPATCHED], - str(results[ERROR]) + - """""" % (job.id, "disabled=True" if not results[ERROR] else ""), + results[FRAME_DONE], + results[FRAME_DISPATCHED], + str(results[FRAME_ERROR]) + + """""" % (job.id, "disabled=True" if not results[FRAME_ERROR] else ""), "yes" if handler.server.balancer.applyPriorities(job) else "no", "yes" if handler.server.balancer.applyExceptions(job) else "no" ) @@ -164,16 +366,19 @@ output("

      Slaves

      ") startTable() - headerTable("name", "address", "last seen", "stats", "job") + headerTable("name", "address", "tags", "last seen", "stats", "job") for slave in handler.server.slaves: - rowTable(slave.name, slave.address[0], time.ctime(slave.last_seen), slave.stats, link(slave.job.name, "/html/job" + slave.job.id) if slave.job else "None") - + rowTable(slave.name, slave.address[0], ";".join(sorted(slave.tags)) if slave.tags else "All", time.ctime(slave.last_seen), slave.stats, link(slave.job.name, "/html/job" + slave.job.id) if slave.job else "None") endTable() output("

      Configuration

      ") output("""""") + + output("
      ") + + output(link("new interface", "/html/newui")) startTable(caption = "Rules", class_style = "rules") @@ -207,7 +412,6 @@ ) endTable() - output("") elif handler.path.startswith("/html/job"): @@ -215,11 +419,13 @@ job_id = handler.path[9:] head("NetRender") + + output(link("Back to Main Page", "/html")) job = handler.server.getJobID(job_id) if job: - output("

      Render Information

      ") + output("

      Job Information

      ") job.initInfo() @@ -227,6 +433,10 @@ rowTable("resolution", "%ix%i at %i%%" % job.resolution) + rowTable("tags", ";".join(sorted(job.tags)) if job.tags else "None") + + rowTable("results", link("download all", resultURL(job_id))) + endTable() @@ -238,19 +448,11 @@ tot_cache = 0 tot_fluid = 0 + tot_other = 0 - rowTable(job.files[0].filepath) - rowTable("Other Files", class_style = "toggle", extra = "onclick='toggleDisplay(".other", "none", "table-row")'") - - for file in job.files: - if file.filepath.endswith(".bphys"): - tot_cache += 1 - elif file.filepath.endswith(".bobj.gz") or file.filepath.endswith(".bvel.gz"): - tot_fluid += 1 - else: - if file != job.files[0]: - rowTable(file.filepath, class_style = "other") - + rowTable(job.files[0].original_path) + tot_cache, tot_fluid, tot_other = countFiles(job) + if tot_cache > 0: rowTable("%i physic cache files" % tot_cache, class_style = "toggle", extra = "onclick='toggleDisplay(".cache", "none", "table-row")'") for file in job.files: @@ -263,6 +465,17 @@ if file.filepath.endswith(".bobj.gz") or file.filepath.endswith(".bvel.gz"): rowTable(os.path.split(file.filepath)[1], class_style = "fluid") + if tot_other > 0: + rowTable("%i other files" % tot_other, class_style = "toggle", extra = "onclick='toggleDisplay(".other", "none", "table-row")'") + for file in job.files: + if ( + not file.filepath.endswith(".bphys") + and not file.filepath.endswith(".bobj.gz") or file.filepath.endswith(".bvel.gz") + and not file == job.files[0] + ): + + rowTable(file.filepath, class_style = "other") + endTable() elif job.type == netrender.model.JOB_VCS: output("

      Versioning

      ") @@ -293,23 +506,38 @@ output("

      Frames

      ") startTable() - headerTable("no", "status", "render time", "slave", "log", "result", "") - - for frame in job.frames: - rowTable( - frame.number, - frame.statusText(), - "%.1fs" % frame.time, - frame.slave.name if frame.slave else " ", - link("view log", logURL(job_id, frame.number)) if frame.log_path else " ", - link("view result", renderURL(job_id, frame.number)) + " [" + - tag("span", "show", attr="class='thumb' onclick='showThumb(%s, %i)'" % (job.id, frame.number)) + "]" if frame.status == DONE else " ", - "" % (frame.number, job.id, frame.number) - ) + + if job.hasRenderResult(): + headerTable("no", "status", "render time", "slave", "log", "result", "") + + for frame in job.frames: + rowTable( + frame.number, + frame.statusText(), + "%.1fs" % frame.time, + frame.slave.name if frame.slave else " ", + link("view log", logURL(job_id, frame.number)) if frame.log_path else " ", + link("view result", renderURL(job_id, frame.number)) + " [" + + tag("span", "show", attr="class='thumb' onclick='showThumb(%s, %i)'" % (job.id, frame.number)) + "]" if frame.status == FRAME_DONE else " ", + "" % (frame.number, job.id, frame.number) + ) + else: + headerTable("no", "status", "process time", "slave", "log") + + for frame in job.frames: + rowTable( + frame.number, + frame.statusText(), + "%.1fs" % frame.time, + frame.slave.name if frame.slave else " ", + link("view log", logURL(job_id, frame.number)) if frame.log_path else " " + ) endTable() else: output("no such job") + output(link("Back to Main Page", "/html")) + output("") diff -Nru blender-2.61/release/scripts/addons/netrender/master.py blender-2.62/release/scripts/addons/netrender/master.py --- blender-2.61/release/scripts/addons/netrender/master.py 2011-12-13 19:58:44.000000000 +0000 +++ blender-2.62/release/scripts/addons/netrender/master.py 2012-02-15 19:43:14.000000000 +0000 @@ -4,7 +4,7 @@ # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. -# +#s # 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 @@ -20,9 +20,11 @@ import http, http.client, http.server, socket, socketserver import shutil, time, hashlib import pickle +import zipfile import select # for select.error import json + from netrender.utils import * import netrender.model import netrender.balancing @@ -34,23 +36,31 @@ super().__init__(filepath, index, start, end, signature) self.found = False - def test(self): + def updateStatus(self): self.found = os.path.exists(self.filepath) + if self.found and self.signature != None: found_signature = hashFile(self.filepath) self.found = self.signature == found_signature + if not self.found: + print("Signature mismatch", self.signature, found_signature) + + return self.found + + def test(self): + # don't check when forcing upload and only until found + if not self.force and not self.found: + self.updateStatus() return self.found class MRenderSlave(netrender.model.RenderSlave): - def __init__(self, name, address, stats): - super().__init__() - self.id = hashlib.md5(bytes(repr(name) + repr(address), encoding='utf8')).hexdigest() - self.name = name - self.address = address - self.stats = stats + def __init__(self, slave_info): + super().__init__(slave_info) + self.id = hashlib.md5(bytes(repr(slave_info.name) + repr(slave_info.address), encoding='utf8')).hexdigest() self.last_seen = time.time() + self.job = None self.job_frames = [] @@ -74,7 +84,8 @@ super().__init__(job_info) self.id = job_id self.last_dispatched = time.time() - + self.start_time = time.time() + self.finish_time = self.start_time # force one chunk for process jobs if self.type == netrender.model.JOB_PROCESS: self.chunks = 1 @@ -86,6 +97,10 @@ self.last_update = 0 self.save_path = "" self.files = [MRenderFile(rfile.filepath, rfile.index, rfile.start, rfile.end, rfile.signature) for rfile in job_info.files] + + def setForceUpload(self, force): + for rfile in self.files: + rfile.force = force def initInfo(self): if not self.resolution: @@ -120,10 +135,11 @@ def testFinished(self): for f in self.frames: - if f.status == QUEUED or f.status == DISPATCHED: + if f.status == FRAME_QUEUED or f.status == FRAME_DISPATCHED: break else: self.status = JOB_FINISHED + self.finish_time=time.time() def pause(self, status = None): if self.status not in {JOB_PAUSED, JOB_QUEUED}: @@ -138,9 +154,11 @@ def start(self): self.status = JOB_QUEUED + def addLog(self, frames): - log_name = "_".join(("%06d" % f for f in frames)) + ".log" + frames = sorted(frames) + log_name = "%06d_%06d.log" % (frames[0], frames[-1]) log_path = os.path.join(self.save_path, log_name) for number in frames: @@ -156,17 +174,23 @@ def reset(self, all): for f in self.frames: f.reset(all) + + if all: + self.status = JOB_QUEUED def getFrames(self): frames = [] for f in self.frames: - if f.status == QUEUED: + if f.status == FRAME_QUEUED: self.last_dispatched = time.time() frames.append(f) if len(frames) >= self.chunks: break return frames + + def getResultPath(self, filename): + return os.path.join(self.save_path, filename) class MRenderFrame(netrender.model.RenderFrame): def __init__(self, frame, command): @@ -174,17 +198,23 @@ self.number = frame self.slave = None self.time = 0 - self.status = QUEUED + self.status = FRAME_QUEUED self.command = command self.log_path = None + def addDefaultRenderResult(self): + self.results.append(self.getRenderFilename()) + + def getRenderFilename(self): + return "%06d.exr" % self.number + def reset(self, all): - if all or self.status == ERROR: + if all or self.status == FRAME_ERROR: self.log_path = None self.slave = None self.time = 0 - self.status = QUEUED + self.status = FRAME_QUEUED # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= @@ -193,6 +223,7 @@ # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- file_pattern = re.compile("/file_([a-zA-Z0-9]+)_([0-9]+)") render_pattern = re.compile("/render_([a-zA-Z0-9]+)_([0-9]+).exr") +result_pattern = re.compile("/result_([a-zA-Z0-9]+).zip") thumb_pattern = re.compile("/thumb_([a-zA-Z0-9]+)_([0-9]+).jpg") log_pattern = re.compile("/log_([a-zA-Z0-9]+)_([0-9]+).log") reset_pattern = re.compile("/reset(all|)_([a-zA-Z0-9]+)_([0-9]+)") @@ -226,7 +257,7 @@ def send_head(self, code = http.client.OK, headers = {}, content = "application/octet-stream"): self.send_response(code) - if code != http.client.OK and content: + if code == http.client.OK and content: self.send_header("Content-type", content) for key, value in headers.items(): @@ -280,18 +311,18 @@ frame = job[frame_number] if frame: - if frame.status in (QUEUED, DISPATCHED): + if frame.status in (FRAME_QUEUED, FRAME_DISPATCHED): self.send_head(http.client.ACCEPTED) - elif frame.status == DONE: + elif frame.status == FRAME_DONE: self.server.stats("", "Sending result to client") - filename = os.path.join(job.save_path, "%06d.exr" % frame_number) + filename = job.getResultPath(frame.getRenderFilename()) f = open(filename, 'rb') self.send_head(content = "image/x-exr") shutil.copyfileobj(f, self.wfile) f.close() - elif frame.status == ERROR: + elif frame.status == FRAME_ERROR: self.send_head(http.client.PARTIAL_CONTENT) else: # no such frame @@ -303,6 +334,38 @@ # invalid url self.send_head(http.client.NO_CONTENT) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + elif self.path.startswith("/result"): + match = result_pattern.match(self.path) + + if match: + job_id = match.groups()[0] + + job = self.server.getJobID(job_id) + + if job: + self.server.stats("", "Sending result to client") + + zip_filepath = job.getResultPath("results.zip") + with zipfile.ZipFile(zip_filepath, "w") as zfile: + for frame in job.frames: + if frame.status == FRAME_DONE: + for filename in frame.results: + filepath = job.getResultPath(filename) + + zfile.write(filepath, filename) + + + f = open(zip_filepath, 'rb') + self.send_head(content = "application/x-zip-compressed") + shutil.copyfileobj(f, self.wfile) + f.close() + else: + # no such job id + self.send_head(http.client.NO_CONTENT) + else: + # invalid url + self.send_head(http.client.NO_CONTENT) + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- elif self.path.startswith("/thumb"): match = thumb_pattern.match(self.path) @@ -316,10 +379,10 @@ frame = job[frame_number] if frame: - if frame.status in (QUEUED, DISPATCHED): + if frame.status in (FRAME_QUEUED, FRAME_DISPATCHED): self.send_head(http.client.ACCEPTED) - elif frame.status == DONE: - filename = os.path.join(job.save_path, "%06d.exr" % frame_number) + elif frame.status == FRAME_DONE: + filename = job.getResultPath(frame.getRenderFilename()) thumbname = thumbnail.generate(filename) @@ -331,7 +394,7 @@ else: # thumbnail couldn't be generated self.send_head(http.client.PARTIAL_CONTENT) return - elif frame.status == ERROR: + elif frame.status == FRAME_ERROR: self.send_head(http.client.PARTIAL_CONTENT) else: # no such frame @@ -356,7 +419,7 @@ frame = job[frame_number] if frame: - if not frame.log_path or frame.status in (QUEUED, DISPATCHED): + if not frame.log_path or frame.status in (FRAME_QUEUED, FRAME_DISPATCHED): self.send_head(http.client.PROCESSING) else: self.server.stats("", "Sending log to client") @@ -420,12 +483,12 @@ slave = self.server.getSeenSlave(slave_id) if slave: # only if slave id is valid - job, frames = self.server.newDispatch(slave_id) + job, frames = self.server.newDispatch(slave) if job and frames: for f in frames: print("dispatch", f.number) - f.status = DISPATCHED + f.status = FRAME_DISPATCHED f.slave = slave slave.job = job @@ -434,7 +497,6 @@ self.send_head(headers={"job-id": job.id}) message = job.serialize(frames) - self.wfile.write(bytes(json.dumps(message), encoding='utf8')) self.server.stats("", "Sending job to slave") @@ -512,10 +574,11 @@ length = int(self.headers['content-length']) job_info = netrender.model.RenderJob.materialize(json.loads(str(self.rfile.read(length), encoding='utf8'))) - job_id = self.server.nextJobID() job = MRenderJob(job_id, job_info) + + job.setForceUpload(self.server.force) for frame in job_info.frames: frame = job.addFrame(frame.number, frame.command) @@ -665,8 +728,10 @@ self.server.stats("", "New slave connected") slave_info = netrender.model.RenderSlave.materialize(json.loads(str(self.rfile.read(length), encoding='utf8')), cache = False) + + slave_info.address = self.client_address - slave_id = self.server.addSlave(slave_info.name, self.client_address, slave_info.stats) + slave_id = self.server.addSlave(slave_info) self.send_head(headers = {"slave-id": slave_id}, content = None) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- @@ -703,9 +768,8 @@ match = file_pattern.match(self.path) if match: - self.server.stats("", "Receiving job") + self.server.stats("", "Receiving job file") - length = int(self.headers['content-length']) job_id = match.groups()[0] file_index = int(match.groups()[1]) @@ -713,15 +777,15 @@ if job: - render_file = job.files[file_index] + rfile = job.files[file_index] - if render_file: - main_file = job.files[0].filepath # filename of the first file + if rfile: + main_file = job.files[0].original_path # original path of the first file main_path, main_name = os.path.split(main_file) if file_index > 0: - file_path = prefixPath(job.save_path, render_file.filepath, main_path) + file_path = createLocalPath(rfile, job.save_path, main_path, True) else: file_path = os.path.join(job.save_path, main_name) @@ -729,13 +793,17 @@ self.write_file(file_path) - render_file.filepath = file_path # set the new path - - if job.testStart(): + rfile.filepath = file_path # set the new path + found = rfile.updateStatus() # make sure we have the right file + + if not found: # checksum mismatch + self.server.stats("", "File upload but checksum mismatch, this shouldn't happen") + self.send_head(http.client.CONFLICT) + elif job.testStart(): # started correctly self.server.stats("", "File upload, starting job") self.send_head(content = None) else: - self.server.stats("", "File upload, file missings") + self.server.stats("", "File upload, dependency files still missing") self.send_head(http.client.ACCEPTED) else: # invalid file print("file not found", job_id, file_index) @@ -770,10 +838,11 @@ self.send_head(content = None) if job.hasRenderResult(): - if job_result == DONE: - self.write_file(os.path.join(job.save_path, "%06d.exr" % job_frame)) + if job_result == FRAME_DONE: + frame.addDefaultRenderResult() + self.write_file(job.getResultPath(frame.getRenderFilename())) - elif job_result == ERROR: + elif job_result == FRAME_ERROR: # blacklist slave on this job on error # slaves might already be in blacklist if errors on the whole chunk if not slave.id in job.blacklist: @@ -793,6 +862,50 @@ else: # invalid slave id self.send_head(http.client.NO_CONTENT) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + elif self.path == "/result": + self.server.stats("", "Receiving job result") + + slave_id = self.headers['slave-id'] + + slave = self.server.getSeenSlave(slave_id) + + if slave: # only if slave id is valid + job_id = self.headers['job-id'] + + job = self.server.getJobID(job_id) + + if job: + job_frame = int(self.headers['job-frame']) + + frame = job[job_frame] + + if frame: + job_result = int(self.headers['job-result']) + job_finished = self.headers['job-finished'] == str(True) + + self.send_head(content = None) + + if job_result == FRAME_DONE: + result_filename = self.headers['result-filename'] + + frame.results.append(result_filename) + self.write_file(job.getResultPath(result_filename)) + + if job_finished: + job_time = float(self.headers['job-time']) + slave.finishedFrame(job_frame) + + frame.status = job_result + frame.time = job_time + + job.testFinished() + else: # frame not found + self.send_head(http.client.NO_CONTENT) + else: # job not found + self.send_head(http.client.NO_CONTENT) + else: # invalid slave id + self.send_head(http.client.NO_CONTENT) + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- elif self.path == "/thumb": self.server.stats("", "Receiving thumbnail result") @@ -853,12 +966,13 @@ self.send_head(http.client.NO_CONTENT) class RenderMasterServer(socketserver.ThreadingMixIn, http.server.HTTPServer): - def __init__(self, address, handler_class, path, subdir=True): + def __init__(self, address, handler_class, path, force=False, subdir=True): self.jobs = [] self.jobs_map = {} self.slaves = [] self.slaves_map = {} self.job_id = 0 + self.force = force if subdir: self.path = os.path.join(path, "master_" + str(os.getpid())) @@ -900,8 +1014,8 @@ self.job_id += 1 return str(self.job_id) - def addSlave(self, name, address, stats): - slave = MRenderSlave(name, address, stats) + def addSlave(self, slave_info): + slave = MRenderSlave(slave_info) self.slaves.append(slave) self.slaves_map[slave.id] = slave @@ -932,7 +1046,7 @@ if slave.job: for f in slave.job_frames: - slave.job[f].status = ERROR + slave.job[f].status = FRAME_ERROR for slave in removed: self.removeSlave(slave) @@ -1003,10 +1117,15 @@ for job in self.jobs: yield job - def newDispatch(self, slave_id): + def newDispatch(self, slave): if self.jobs: for job in self.jobs: - if not self.balancer.applyExceptions(job) and slave_id not in job.blacklist: + if ( + not self.balancer.applyExceptions(job) # No exceptions + and slave.id not in job.blacklist # slave is not blacklisted + and (not slave.tags or job.tags.issubset(slave.tags)) # slave doesn't use tags or slave has all job tags + ): + return job, job.getFrames() return None, None @@ -1014,7 +1133,7 @@ def clearMaster(path): shutil.rmtree(path) -def createMaster(address, clear, path): +def createMaster(address, clear, force, path): filepath = os.path.join(path, "blender_master.data") if not clear and os.path.exists(filepath): @@ -1022,12 +1141,12 @@ with open(filepath, 'rb') as f: path, jobs, slaves = pickle.load(f) - httpd = RenderMasterServer(address, RenderHandler, path, subdir=False) + httpd = RenderMasterServer(address, RenderHandler, path, force=force, subdir=False) httpd.restore(jobs, slaves) return httpd - return RenderMasterServer(address, RenderHandler, path) + return RenderMasterServer(address, RenderHandler, path, force=force) def saveMaster(path, httpd): filepath = os.path.join(path, "blender_master.data") @@ -1035,11 +1154,13 @@ with open(filepath, 'wb') as f: pickle.dump((httpd.path, httpd.jobs, httpd.slaves), f, pickle.HIGHEST_PROTOCOL) -def runMaster(address, broadcast, clear, path, update_stats, test_break): - httpd = createMaster(address, clear, path) +def runMaster(address, broadcast, clear, force, path, update_stats, test_break,use_ssl=False,cert_path="",key_path=""): + httpd = createMaster(address, clear, force, path) httpd.timeout = 1 httpd.stats = update_stats - + if use_ssl: + import ssl + httpd.socket=ssl.wrap_socket(httpd.socket,certfile=cert_path,server_side=True,keyfile=key_path,ciphers="ALL",ssl_version=ssl.PROTOCOL_SSLv3) if broadcast: s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) diff -Nru blender-2.61/release/scripts/addons/netrender/model.py blender-2.62/release/scripts/addons/netrender/model.py --- blender-2.61/release/scripts/addons/netrender/model.py 2011-12-13 19:58:44.000000000 +0000 +++ blender-2.62/release/scripts/addons/netrender/model.py 2012-02-15 19:43:14.000000000 +0000 @@ -19,6 +19,11 @@ import netrender.versioning as versioning from netrender.utils import * +TAG_BAKING = "baking" +TAG_RENDER = "render" + +TAG_ALL = set((TAG_BAKING, TAG_RENDER)) + class LogFile: def __init__(self, job_id = 0, slave_id = 0, frames = []): self.job_id = job_id @@ -47,14 +52,22 @@ class RenderSlave: _slave_map = {} - def __init__(self): + def __init__(self, info = None): self.id = "" - self.name = "" - self.address = ("",0) - self.stats = "" self.total_done = 0 self.total_error = 0 self.last_seen = 0.0 + + if info: + self.name = info.name + self.address = info.address + self.stats = info.stats + self.tags = info.tags + else: + self.name = "" + self.address = ("",0) + self.stats = "" + self.tags = set() def serialize(self): return { @@ -64,7 +77,8 @@ "stats": self.stats, "total_done": self.total_done, "total_error": self.total_error, - "last_seen": self.last_seen + "last_seen": self.last_seen, + "tags": tuple(self.tags) } @staticmethod @@ -85,6 +99,7 @@ slave.total_done = data["total_done"] slave.total_error = data["total_error"] slave.last_seen = data["last_seen"] + slave.tags = set(data["tags"]) if cache: RenderSlave._slave_map[slave_id] = slave @@ -101,6 +116,14 @@ JOB_VCS: "Versioned", } +JOB_SUB_RENDER = 1 +JOB_SUB_BAKING = 2 + +JOB_SUBTYPES = { + JOB_SUB_RENDER: "Render", + JOB_SUB_BAKING: "Baking", + } + class VersioningInfo: def __init__(self, info = None): self._system = None @@ -154,13 +177,15 @@ class RenderFile: - def __init__(self, filepath = "", index = 0, start = -1, end = -1, signature=0): + def __init__(self, filepath = "", index = 0, start = -1, end = -1, signature = 0): self.filepath = filepath self.original_path = filepath self.signature = signature self.index = index self.start = start self.end = end + self.force = False + def serialize(self): return { @@ -169,7 +194,9 @@ "index": self.index, "start": self.start, "end": self.end, - "signature": self.signature + "signature": self.signature, + "force": self.force + } @staticmethod @@ -179,22 +206,13 @@ rfile = RenderFile(data["filepath"], data["index"], data["start"], data["end"], data["signature"]) rfile.original_path = data["original_path"] + rfile.force = data["force"] return rfile class RenderJob: - def __init__(self, job_info = None): + def __init__(self, info = None): self.id = "" - self.type = JOB_BLENDER - self.name = "" - self.category = "None" - self.status = JOB_WAITING - self.files = [] - self.chunks = 0 - self.priority = 0 - self.blacklist = [] - - self.version_info = None self.resolution = None @@ -202,29 +220,57 @@ self.last_dispatched = 0.0 self.frames = [] - if job_info: - self.type = job_info.type - self.name = job_info.name - self.category = job_info.category - self.status = job_info.status - self.files = job_info.files - self.chunks = job_info.chunks - self.priority = job_info.priority - self.blacklist = job_info.blacklist - self.version_info = job_info.version_info + if info: + self.type = info.type + self.subtype = info.subtype + self.name = info.name + self.category = info.category + self.tags = info.tags + self.status = info.status + self.files = info.files + self.chunks = info.chunks + self.priority = info.priority + self.blacklist = info.blacklist + self.version_info = info.version_info + self.render = info.render + else: + self.type = JOB_BLENDER + self.subtype = JOB_SUB_RENDER + self.name = "" + self.category = "None" + self.tags = set() + self.status = JOB_WAITING + self.files = [] + self.chunks = 0 + self.priority = 0 + self.blacklist = [] + self.version_info = None + self.render = "BLENDER_RENDER" def hasRenderResult(self): - return self.type in (JOB_BLENDER, JOB_VCS) + return self.subtype == JOB_SUB_RENDER def rendersWithBlender(self): - return self.type in (JOB_BLENDER, JOB_VCS) + return self.subtype == JOB_SUB_RENDER def addFile(self, file_path, start=-1, end=-1, signed=True): - if signed: - signature = hashFile(file_path) - else: - signature = None - self.files.append(RenderFile(file_path, len(self.files), start, end, signature)) + def isFileInFrames(): + if start == end == -1: + return True + + for rframe in self.frames: + if start <= rframe.number<= end: + return True + + return False + + + if isFileInFrames(): + if signed: + signature = hashFile(file_path) + else: + signature = None + self.files.append(RenderFile(file_path, len(self.files), start, end, signature)) def addFrame(self, frame_number, command = ""): frame = RenderFrame(frame_number, command) @@ -234,7 +280,7 @@ def __len__(self): return len(self.frames) - def countFrames(self, status=QUEUED): + def countFrames(self, status=FRAME_QUEUED): total = 0 for f in self.frames: if f.status == status: @@ -243,17 +289,17 @@ return total def countSlaves(self): - return len(set((frame.slave for frame in self.frames if frame.status == DISPATCHED))) + return len(set((frame.slave for frame in self.frames if frame.status == FRAME_DISPATCHED))) def statusText(self): return JOB_STATUS_TEXT[self.status] def framesStatus(self): results = { - QUEUED: 0, - DISPATCHED: 0, - DONE: 0, - ERROR: 0 + FRAME_QUEUED: 0, + FRAME_DISPATCHED: 0, + FRAME_DONE: 0, + FRAME_ERROR: 0 } for frame in self.frames: @@ -275,26 +321,33 @@ else: return None - def serialize(self, frames = None): + def serialize(self, frames = None,withFiles=True,withFrames=True): min_frame = min((f.number for f in frames)) if frames else -1 max_frame = max((f.number for f in frames)) if frames else -1 - return { + data={ "id": self.id, "type": self.type, + "subtype": self.subtype, "name": self.name, "category": self.category, + "tags": tuple(self.tags), "status": self.status, - "files": [f.serialize() for f in self.files if f.start == -1 or not frames or (f.start <= max_frame and f.end >= min_frame)], - "frames": [f.serialize() for f in self.frames if not frames or f in frames], "chunks": self.chunks, "priority": self.priority, "usage": self.usage, "blacklist": self.blacklist, "last_dispatched": self.last_dispatched, "version_info": self.version_info.serialize() if self.version_info else None, - "resolution": self.resolution + "resolution": self.resolution, + "render": self.render } - + if (withFiles): + data["files"]=[f.serialize() for f in self.files if f.start == -1 or not frames or (f.start <= max_frame and f.end >= min_frame)] + + if (withFrames): + data["frames"]=[f.serialize() for f in self.frames if not frames or f in frames] + + return data @staticmethod def materialize(data): if not data: @@ -303,8 +356,10 @@ job = RenderJob() job.id = data["id"] job.type = data["type"] + job.subtype = data["subtype"] job.name = data["name"] job.category = data["category"] + job.tags = set(data["tags"]) job.status = data["status"] job.files = [RenderFile.materialize(f) for f in data["files"]] job.frames = [RenderFrame.materialize(f) for f in data["frames"]] @@ -314,6 +369,7 @@ job.blacklist = data["blacklist"] job.last_dispatched = data["last_dispatched"] job.resolution = data["resolution"] + job.render=data["render"] version_info = data.get("version_info", None) if version_info: @@ -325,9 +381,10 @@ def __init__(self, number = 0, command = ""): self.number = number self.time = 0 - self.status = QUEUED + self.status = FRAME_QUEUED self.slave = None self.command = command + self.results = [] # List of filename of result files associated with this frame def statusText(self): return FRAME_STATUS_TEXT[self.status] @@ -338,7 +395,8 @@ "time": self.time, "status": self.status, "slave": None if not self.slave else self.slave.serialize(), - "command": self.command + "command": self.command, + "results": self.results } @staticmethod @@ -352,5 +410,6 @@ frame.status = data["status"] frame.slave = RenderSlave.materialize(data["slave"]) frame.command = data["command"] + frame.results = data["results"] return frame diff -Nru blender-2.61/release/scripts/addons/netrender/netrender.js blender-2.62/release/scripts/addons/netrender/netrender.js --- blender-2.61/release/scripts/addons/netrender/netrender.js 2011-12-13 19:58:44.000000000 +0000 +++ blender-2.62/release/scripts/addons/netrender/netrender.js 2012-02-15 19:43:14.000000000 +0000 @@ -52,7 +52,8 @@ function showThumb(job, frame) { - if (lastFrame != -1) { + if (lastFrame != -1) { + if (maxFrame != -1 && minFrame != -1) { if (frame >= minFrame && frame <= maxFrame) { for(i = minFrame; i <= maxFrame; i=i+1) { @@ -143,4 +144,4 @@ return classes[x]; } } -} \ No newline at end of file +} diff -Nru blender-2.61/release/scripts/addons/netrender/newui.html blender-2.62/release/scripts/addons/netrender/newui.html --- blender-2.61/release/scripts/addons/netrender/newui.html 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons/netrender/newui.html 2012-02-15 19:43:14.000000000 +0000 @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + diff -Nru blender-2.61/release/scripts/addons/netrender/operators.py blender-2.62/release/scripts/addons/netrender/operators.py --- blender-2.61/release/scripts/addons/netrender/operators.py 2011-12-13 19:58:44.000000000 +0000 +++ blender-2.62/release/scripts/addons/netrender/operators.py 2012-02-15 19:43:14.000000000 +0000 @@ -28,10 +28,10 @@ import netrender.model import netrender.versioning as versioning -class RENDER_OT_netslave_bake(bpy.types.Operator): - '''NEED DESCRIPTION''' - bl_idname = "render.netslavebake" - bl_label = "Bake all in file" +class RENDER_OT_netclientsendbake(bpy.types.Operator): + '''Send a baking job to the Network''' + bl_idname = "render.netclientsendbake" + bl_label = "Bake on network" @classmethod def poll(cls, context): @@ -39,45 +39,19 @@ def execute(self, context): scene = context.scene - # netsettings = scene.network_render # UNUSED - - filename = bpy.data.filepath - path, name = os.path.split(filename) - root, ext = os.path.splitext(name) - # default_path = path + os.sep + "blendcache_" + root + os.sep # need an API call for that, UNUSED - relative_path = "//blendcache_" + root + os.sep - - # Force all point cache next to the blend file - for object in bpy.data.objects: - for modifier in object.modifiers: - if modifier.type == 'FLUID_SIMULATION' and modifier.settings.type == "DOMAIN": - modifier.settings.path = relative_path - bpy.ops.fluid.bake({"active_object": object, "scene": scene}) - elif modifier.type == "CLOTH": - modifier.point_cache.frame_step = 1 - modifier.point_cache.use_disk_cache = True - modifier.point_cache.use_external = False - elif modifier.type == "SOFT_BODY": - modifier.point_cache.frame_step = 1 - modifier.point_cache.use_disk_cache = True - modifier.point_cache.use_external = False - elif modifier.type == "SMOKE" and modifier.smoke_type == "TYPE_DOMAIN": - modifier.domain_settings.point_cache.use_step = 1 - modifier.domain_settings.point_cache.use_disk_cache = True - modifier.domain_settings.point_cache.use_external = False - - # particles modifier are stupid and don't contain data - # we have to go through the object property - for psys in object.particle_systems: - psys.point_cache.use_step = 1 - psys.point_cache.use_disk_cache = True - psys.point_cache.use_external = False - psys.point_cache.filepath = relative_path - - bpy.ops.ptcache.bake_all() + netsettings = scene.network_render - #bpy.ops.wm.save_mainfile(filepath = path + os.sep + root + "_baked.blend") + try: + conn = clientConnection(netsettings, report = self.report) + if conn: + # Sending file + client.sendJobBaking(conn, scene) + conn.close() + self.report({'INFO'}, "Job sent to master") + except Exception as err: + self.report({'ERROR'}, str(err)) + return {'FINISHED'} def invoke(self, context, event): @@ -96,11 +70,11 @@ scene = context.scene netsettings = scene.network_render - conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report) + conn = clientConnection(netsettings, report = self.report) if conn: # Sending file - scene.network_render.job_id = client.clientSendJob(conn, scene, True) + scene.network_render.job_id = client.sendJob(conn, scene, True) conn.close() bpy.ops.render.render('INVOKE_AREA', animation=True) @@ -141,11 +115,11 @@ netsettings = scene.network_render try: - conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report) + conn = clientConnection(netsettings, report = self.report) if conn: # Sending file - scene.network_render.job_id = client.clientSendJob(conn, scene, True) + scene.network_render.job_id = client.sendJob(conn, scene, True) conn.close() self.report({'INFO'}, "Job sent to master") except Exception as err: @@ -171,11 +145,11 @@ netsettings = scene.network_render try: - conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report) + conn = clientConnection(netsettings, report = self.report) if conn: # Sending file - scene.network_render.job_id = client.clientSendJob(conn, scene, False) + scene.network_render.job_id = client.sendJob(conn, scene, False) conn.close() self.report({'INFO'}, "Job sent to master") except Exception as err: @@ -198,7 +172,7 @@ def execute(self, context): netsettings = context.scene.network_render - conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report) + conn = clientConnection(netsettings, report = self.report) if conn: with ConnectionContext(): @@ -300,7 +274,7 @@ def execute(self, context): netsettings = context.scene.network_render - conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report) + conn = clientConnection(netsettings, report = self.report) if conn: with ConnectionContext(): @@ -352,7 +326,7 @@ def execute(self, context): netsettings = context.scene.network_render - conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report) + conn = clientConnection(netsettings, report = self.report) if conn: job = netrender.jobs[netsettings.active_job_index] @@ -381,7 +355,7 @@ def execute(self, context): netsettings = context.scene.network_render - conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report) + conn = clientConnection(netsettings, report = self.report) if conn: with ConnectionContext(): @@ -411,7 +385,7 @@ def execute(self, context): netsettings = context.scene.network_render - conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report) + conn = clientConnection(netsettings, report = self.report) if conn: job_id = netrender.jobs[netsettings.active_job_index].id @@ -436,9 +410,9 @@ nb_missing = 0 for frame in job.frames: - if frame.status == DONE: + if frame.status == FRAME_DONE: finished_frames.append(frame.number) - elif frame.status == ERROR: + elif frame.status == FRAME_ERROR: nb_error += 1 else: nb_missing += 1 @@ -556,13 +530,14 @@ # open connection to make sure server exists - conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report) + conn = clientConnection(netsettings, report = self.report) if conn: conn.close() - - webbrowser.open("http://%s:%i" % (netsettings.server_address, netsettings.server_port)) - + if netsettings.use_ssl: + webbrowser.open("https://%s:%i" % (netsettings.server_address, netsettings.server_port)) + else: + webbrowser.open("http://%s:%i" % (netsettings.server_address, netsettings.server_port)) return {'FINISHED'} def invoke(self, context, event): diff -Nru blender-2.61/release/scripts/addons/netrender/repath.py blender-2.62/release/scripts/addons/netrender/repath.py --- blender-2.61/release/scripts/addons/netrender/repath.py 2011-12-13 19:58:44.000000000 +0000 +++ blender-2.62/release/scripts/addons/netrender/repath.py 2012-02-15 19:43:14.000000000 +0000 @@ -21,6 +21,8 @@ import bpy +DEBUG = False + from netrender.utils import * BLENDER_PATH = sys.argv[0] @@ -44,7 +46,9 @@ path, ext = os.path.splitext(job_full_path) - new_path = path + ".remap" + ext + new_path = path + ".remap" + ext + + original_path = main_file.original_path # Disable for now. Partial repath should work anyway #all = main_file.filepath != main_file.original_path @@ -57,42 +61,43 @@ # Only update if needed if paths: - process = subprocess.Popen([BLENDER_PATH, "-b", "-noaudio", job_full_path, "-P", __file__, "--", new_path] + paths, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + process = subprocess.Popen([BLENDER_PATH, "-b", "-noaudio", job_full_path, "-P", __file__, "--", new_path, original_path] + paths, stdout=sys.stdout, stderr=subprocess.STDOUT) process.wait() os.renames(job_full_path, job_full_path + ".bak") os.renames(new_path, job_full_path) -def process(paths): - def processPointCache(point_cache): - point_cache.use_external = False - - def processFluid(fluid): - new_path = path_map.get(fluid.filepath, None) - if new_path: - fluid.path = new_path - +def process(original_path, paths): + if DEBUG: print("==========================================================") + original_directory = os.path.dirname(original_path) path_map = {} for i in range(0, len(paths), 2): # special case for point cache if paths[i].endswith(".bphys"): - pass # Don't need them in the map, they all use the default external path - # NOTE: This is probably not correct all the time, need to be fixed. + path, filename = os.path.split(paths[i+1]) + cache_name = filename.split("_")[0] + if DEBUG: print(cache_name, path) + path_map[cache_name] = path # special case for fluids elif paths[i].endswith(".bobj.gz"): + if DEBUG: print(os.path.split(paths[i])[0], os.path.split(paths[i+1])[0]) path_map[os.path.split(paths[i])[0]] = os.path.split(paths[i+1])[0] else: - path_map[os.path.split(paths[i])[1]] = paths[i+1] + if DEBUG: print(paths[i], paths[i+1]) + path_map[paths[i]] = paths[i+1] - # TODO original paths aren't really the orignal path (they are the normalized path + if DEBUG: print("----------------------------------------------------------") + + # TODO original paths aren't really the original path, they are the normalized path # so we repath using the filenames only. ########################### # LIBRARIES ########################### for lib in bpy.data.libraries: - file_path = bpy.path.abspath(lib.filepath) - new_path = path_map.get(os.path.split(file_path)[1], None) + file_path = bpy.path.abspath(lib.filepath, start=original_directory) + new_path = path_map.get(file_path, None) + if DEBUG: print(file_path, new_path) if new_path: lib.filepath = new_path @@ -101,8 +106,9 @@ ########################### for image in bpy.data.images: if image.source == "FILE" and not image.packed_file: - file_path = bpy.path.abspath(image.filepath) - new_path = path_map.get(os.path.split(file_path)[1], None) + file_path = bpy.path.abspath(image.filepath, start=original_directory) + new_path = path_map.get(file_path, None) + if DEBUG: print(file_path, new_path) if new_path: image.filepath = new_path @@ -110,28 +116,31 @@ ########################### # FLUID + POINT CACHE ########################### - for object in bpy.data.objects: - for modifier in object.modifiers: - if modifier.type == 'FLUID_SIMULATION' and modifier.settings.type == "DOMAIN": - processFluid(modifier.settings) - elif modifier.type == "CLOTH": - processPointCache(modifier.point_cache) - elif modifier.type == "SOFT_BODY": - processPointCache(modifier.point_cache) - elif modifier.type == "SMOKE" and modifier.smoke_type == "TYPE_DOMAIN": - processPointCache(modifier.domain_settings.point_cache_low) - if modifier.domain_settings.use_high_resolution: - processPointCache(modifier.domain_settings.point_cache_high) - elif modifier.type == "MULTIRES" and modifier.is_external: - file_path = bpy.path.abspath(modifier.filepath) - new_path = path_map.get(file_path, None) - if new_path: - modifier.filepath = new_path - - # particles modifier are stupid and don't contain data - # we have to go through the object property - for psys in object.particle_systems: - processPointCache(psys.point_cache) + def pointCacheFunc(object, owner, point_cache): + if not point_cache.use_disk_cache: + return + + cache_name = cacheName(object, point_cache) + new_path = path_map.get(cache_name, None) + if DEBUG: print(cache_name, new_path) + if new_path: + point_cache.use_external = True + point_cache.filepath = new_path + point_cache.name = cache_name + + def fluidFunc(object, modifier, cache_path): + fluid = modifier.settings + new_path = path_map.get(cache_path, None) + if new_path: + fluid.path = new_path + + def multiresFunc(object, modifier, cache_path): + new_path = path_map.get(cache_path, None) + if new_path: + modifier.filepath = new_path + + processObjectDependencies(pointCacheFunc, fluidFunc, multiresFunc) + if DEBUG: print("==========================================================") if __name__ == "__main__": @@ -141,9 +150,8 @@ i = 0 if i: - new_path = sys.argv[i+1] - args = sys.argv[i+2:] + new_path, original_path, *args = sys.argv[i+1:] - process(args) + process(original_path, args) bpy.ops.wm.save_as_mainfile(filepath=new_path, check_existing=False) diff -Nru blender-2.61/release/scripts/addons/netrender/slave.py blender-2.62/release/scripts/addons/netrender/slave.py --- blender-2.61/release/scripts/addons/netrender/slave.py 2011-12-13 19:58:44.000000000 +0000 +++ blender-2.62/release/scripts/addons/netrender/slave.py 2012-02-15 19:43:14.000000000 +0000 @@ -18,7 +18,7 @@ import sys, os, platform, shutil import http, http.client, http.server -import subprocess, time +import subprocess, time, threading import json import bpy @@ -26,6 +26,7 @@ from netrender.utils import * import netrender.model import netrender.repath +import netrender.baking import netrender.thumbnail as thumbnail BLENDER_PATH = sys.argv[0] @@ -34,36 +35,17 @@ MAX_TIMEOUT = 10 INCREMENT_TIMEOUT = 1 MAX_CONNECT_TRY = 10 -try: - system = platform.system() -except UnicodeDecodeError: - import sys - system = sys.platform - -if system in ('Windows', 'win32') and platform.version() >= '5': # Error mode is only available on Win2k or higher, that's version 5 - import ctypes - def SetErrorMode(): - val = ctypes.windll.kernel32.SetErrorMode(0x0002) - ctypes.windll.kernel32.SetErrorMode(val | 0x0002) - return val - - def RestoreErrorMode(val): - ctypes.windll.kernel32.SetErrorMode(val) -else: - def SetErrorMode(): - return 0 - - def RestoreErrorMode(val): - pass def clearSlave(path): shutil.rmtree(path) -def slave_Info(): +def slave_Info(netsettings): sysname, nodename, release, version, machine, processor = platform.uname() slave = netrender.model.RenderSlave() slave.name = nodename slave.stats = sysname + " " + release + " " + machine + " " + processor + if netsettings.slave_tags: + slave.tags = set(netsettings.slave_tags.split(";")) return slave def testCancel(conn, job_id, frame_number): @@ -77,7 +59,7 @@ return False def testFile(conn, job_id, slave_id, rfile, JOB_PREFIX, main_path=None): - job_full_path = prefixPath(JOB_PREFIX, rfile.filepath, main_path) + job_full_path = createLocalPath(rfile, JOB_PREFIX, main_path, rfile.force) found = os.path.exists(job_full_path) @@ -88,11 +70,11 @@ if not found: print("Found file %s at %s but signature mismatch!" % (rfile.filepath, job_full_path)) os.remove(job_full_path) - job_full_path = prefixPath(JOB_PREFIX, rfile.filepath, main_path, force=True) if not found: # Force prefix path if not found - job_full_path = prefixPath(JOB_PREFIX, rfile.filepath, main_path, force=True) + job_full_path = createLocalPath(rfile, JOB_PREFIX, main_path, True) + print("Downloading", job_full_path) temp_path = os.path.join(JOB_PREFIX, "slave.temp") with ConnectionContext(): conn.request("GET", fileURL(job_id, rfile.index), headers={"slave-id":slave_id}) @@ -136,8 +118,8 @@ if not os.access(slave_path, os.W_OK): print("Slave working path ( %s ) is not writable" % netsettings.path) return - - conn = clientConnection(netsettings.server_address, netsettings.server_port) + + conn = clientConnection(netsettings) if not conn: print("Connection failed, will try connecting again at most %i times" % MAX_CONNECT_TRY) @@ -146,7 +128,7 @@ for i in range(MAX_CONNECT_TRY): bisleep.sleep() - conn = clientConnection(netsettings.server_address, netsettings.server_port) + conn = clientConnection(netsettings) if conn or engine.test_break(): break @@ -155,7 +137,7 @@ if conn: with ConnectionContext(): - conn.request("POST", "/slave", json.dumps(slave_Info().serialize())) + conn.request("POST", "/slave", json.dumps(slave_Info(netsettings).serialize())) response = conn.getresponse() response.read() @@ -188,7 +170,7 @@ if job.type == netrender.model.JOB_BLENDER: - job_path = job.files[0].filepath # path of main file + job_path = job.files[0].original_path # original path of the first file main_path, main_file = os.path.split(job_path) job_full_path = testFile(conn, job.id, slave_id, job.files[0], JOB_PREFIX) @@ -237,50 +219,96 @@ print("frame", frame.number) frame_args += ["-f", str(frame.number)] - val = SetErrorMode() - process = subprocess.Popen([BLENDER_PATH, "-b", "-noaudio", job_full_path, "-t", str(threads), "-o", os.path.join(JOB_PREFIX, "######"), "-E", "BLENDER_RENDER", "-F", "MULTILAYER"] + frame_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - RestoreErrorMode(val) + with NoErrorDialogContext(): + process = subprocess.Popen([BLENDER_PATH, "-b", "-noaudio", job_full_path, "-t", str(threads), "-o", os.path.join(JOB_PREFIX, "######"), "-E", job.render, "-F", "MULTILAYER"] + frame_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + + elif job.subtype == netrender.model.JOB_SUB_BAKING: + tasks = [] + for frame in job.frames: + tasks.append(netrender.baking.commandToTask(frame.command)) + + with NoErrorDialogContext(): + process = netrender.baking.bake(job, tasks) + elif job.type == netrender.model.JOB_PROCESS: command = job.frames[0].command - val = SetErrorMode() - process = subprocess.Popen(command.split(" "), stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - RestoreErrorMode(val) + with NoErrorDialogContext(): + process = subprocess.Popen(command.split(" "), stdout=subprocess.PIPE, stderr=subprocess.STDOUT) headers = {"slave-id":slave_id} + + results = [] + + line = "" + + class ProcessData: + def __init__(self): + self.lock = threading.Lock() + self.stdout = bytes() + self.cancelled = False + self.start_time = time.time() + self.last_time = time.time() + + data = ProcessData() + + def run_process(process, data): + while not data.cancelled and process.poll() is None: + buf = process.stdout.read(1024) + + data.lock.acquire() + data.stdout += buf + data.lock.release() + + process_thread = threading.Thread(target=run_process, args=(process, data)) + + process_thread.start() + + while not data.cancelled and process_thread.is_alive(): + time.sleep(CANCEL_POLL_SPEED / 2) + current_time = time.time() + data.cancelled = engine.test_break() + if current_time - data.last_time > CANCEL_POLL_SPEED: - cancelled = False - stdout = bytes() - run_t = time.time() - while not cancelled and process.poll() is None: - stdout += process.stdout.read(1024) - current_t = time.time() - cancelled = engine.test_break() - if current_t - run_t > CANCEL_POLL_SPEED: + data.lock.acquire() # update logs if needed - if stdout: + if data.stdout: # (only need to update on one frame, they are linked with ConnectionContext(): - conn.request("PUT", logURL(job.id, first_frame), stdout, headers=headers) + conn.request("PUT", logURL(job.id, first_frame), data.stdout, headers=headers) responseStatus(conn) + stdout_text = str(data.stdout, encoding='utf8') + # Also output on console if netsettings.use_slave_output_log: - print(str(stdout, encoding='utf8'), end="") + print(stdout_text, end="") + + lines = stdout_text.split("\n") + lines[0] = line + lines[0] + line = lines.pop() + if job.subtype == netrender.model.JOB_SUB_BAKING: + results.extend(netrender.baking.resultsFromOuput(lines)) - stdout = bytes() + data.stdout = bytes() + + data.lock.release() - run_t = current_t + data.last_time = current_time if testCancel(conn, job.id, first_frame): - cancelled = True + engine.update_stats("", "Job canceled by Master") + data.cancelled = True + + process_thread.join() + del process_thread if job.type == netrender.model.JOB_BLENDER: netrender.repath.reset(job) # read leftovers if needed - stdout += process.stdout.read() + data.stdout += process.stdout.read() - if cancelled: + if data.cancelled: # kill process if needed if process.poll() is None: try: @@ -290,19 +318,26 @@ continue # to next frame # flush the rest of the logs - if stdout: + if data.stdout: + stdout_text = str(data.stdout, encoding='utf8') + # Also output on console - if netsettings.use_slave_thumb: - print(str(stdout, encoding='utf8'), end="") + if netsettings.use_slave_output_log: + print(stdout_text, end="") + lines = stdout_text.split("\n") + lines[0] = line + lines[0] + if job.subtype == netrender.model.JOB_SUB_BAKING: + results.extend(netrender.baking.resultsFromOuput(lines)) + # (only need to update on one frame, they are linked with ConnectionContext(): - conn.request("PUT", logURL(job.id, first_frame), stdout, headers=headers) + conn.request("PUT", logURL(job.id, first_frame), data.stdout, headers=headers) if responseStatus(conn) == http.client.NO_CONTENT: continue - total_t = time.time() - start_t + total_t = time.time() - data.start_time avg_t = total_t / len(job.frames) @@ -314,7 +349,7 @@ if status == 0: # non zero status is error - headers["job-result"] = str(DONE) + headers["job-result"] = str(FRAME_DONE) for frame in job.frames: headers["job-frame"] = str(frame.number) if job.hasRenderResult(): @@ -340,13 +375,30 @@ if responseStatus(conn) == http.client.NO_CONTENT: continue + elif job.subtype == netrender.model.JOB_SUB_BAKING: + index = job.frames.index(frame) + + frame_results = [result_filepath for task_index, result_filepath in results if task_index == index] + + for result_filepath in frame_results: + result_path, result_filename = os.path.split(result_filepath) + headers["result-filename"] = result_filename + headers["job-finished"] = str(result_filepath == frame_results[-1]) + + f = open(result_filepath, 'rb') + with ConnectionContext(): + conn.request("PUT", "/result", f, headers=headers) + f.close() + if responseStatus(conn) == http.client.NO_CONTENT: + continue + elif job.type == netrender.model.JOB_PROCESS: with ConnectionContext(): conn.request("PUT", "/render", headers=headers) if responseStatus(conn) == http.client.NO_CONTENT: continue else: - headers["job-result"] = str(ERROR) + headers["job-result"] = str(FRAME_ERROR) for frame in job.frames: headers["job-frame"] = str(frame.number) # send error result back to server diff -Nru blender-2.61/release/scripts/addons/netrender/ui.py blender-2.62/release/scripts/addons/netrender/ui.py --- blender-2.61/release/scripts/addons/netrender/ui.py 2011-12-13 19:58:44.000000000 +0000 +++ blender-2.62/release/scripts/addons/netrender/ui.py 2012-02-15 19:43:14.000000000 +0000 @@ -30,11 +30,6 @@ PATH_PREFIX = "/tmp/" -QUEUED = 0 -DISPATCHED = 1 -DONE = 2 -ERROR = 3 - LAST_ADDRESS_TEST = 0 ADDRESS_TEST_TIMEOUT = 30 @@ -75,7 +70,7 @@ LAST_ADDRESS_TEST = time.time() try: - conn = clientConnection(netsettings.server_address, netsettings.server_port, scan = False, timeout = 1) + conn = clientConnection(netsettings, scan = False, timeout = 1) except: conn = None @@ -125,25 +120,34 @@ layout.operator("render.netclientstart", icon='PLAY') layout.prop(netsettings, "path") + + row = layout.row() - split = layout.split(percentage=0.7) + split = layout.split(percentage=0.5) col = split.column() - col.label(text="Server Address:") - col.prop(netsettings, "server_address", text="") + col.prop(netsettings, "server_address", text="Address") col = split.column() - col.label(text="Port:") - col.prop(netsettings, "server_port", text="") + row = col.row() + row.prop(netsettings, "server_port", text="Port") + row.prop(netsettings, "use_ssl", text="SSL") if netsettings.mode != "RENDER_MASTER": layout.operator("render.netclientscan", icon='FILE_REFRESH', text="") if not netrender.valid_address: layout.label(text="No master at specified address") + + + if netsettings.use_ssl and netsettings.mode == "RENDER_MASTER": + layout.prop(netsettings, "cert_path", text="Certificate") + layout.prop(netsettings, "key_path", text="Key") layout.operator("render.netclientweb", icon='QUESTION') + + class RENDER_PT_network_slave_settings(NetRenderButtonsPanel, bpy.types.Panel): bl_label = "Slave Settings" COMPAT_ENGINES = {'NET_RENDER'} @@ -159,6 +163,7 @@ rd = context.scene.render netsettings = context.scene.network_render + layout.prop(netsettings, "slave_tags", text="Tags") layout.prop(netsettings, "use_slave_clear") layout.prop(netsettings, "use_slave_thumb") layout.prop(netsettings, "use_slave_output_log") @@ -184,6 +189,7 @@ netsettings = context.scene.network_render layout.prop(netsettings, "use_master_broadcast") + layout.prop(netsettings, "use_master_force_upload") layout.prop(netsettings, "use_master_clear") class RENDER_PT_network_job(NetRenderButtonsPanel, bpy.types.Panel): @@ -205,27 +211,30 @@ if netsettings.server_address != "[default]": layout.operator("render.netclientanim", icon='RENDER_ANIMATION') layout.operator("render.netclientsend", icon='FILE_BLEND') + layout.operator("render.netclientsendbake", icon='PHYSICS') layout.operator("render.netclientsendframe", icon='RENDER_STILL') if netsettings.job_id: row = layout.row() row.operator("render.render", text="Get Image", icon='RENDER_STILL') row.operator("render.render", text="Get Animation", icon='RENDER_ANIMATION').animation = True - split = layout.split(percentage=0.3) - - col = split.column() - col.label(text="Type:") - col.label(text="Name:") - col.label(text="Category:") - - col = split.column() - col.prop(netsettings, "job_type", text="") - col.prop(netsettings, "job_name", text="") - col.prop(netsettings, "job_category", text="") + layout.prop(netsettings, "job_type", text="Type") + layout.prop(netsettings, "job_name", text="Name") + layout.prop(netsettings, "job_category", text="Category") + layout.prop(netsettings, "job_tags", text="Tags") + layout.prop(netsettings, "job_render_engine", text="Engine") + + if netsettings.job_render_engine == "OTHER": + layout.prop(netsettings, "job_render_engine_other", text="Other Engine") row = layout.row() row.prop(netsettings, "priority") row.prop(netsettings, "chunks") + + if netsettings.job_type == "JOB_BLENDER": + layout.prop(netsettings, "save_before_job") + + class RENDER_PT_network_job_vcs(NetRenderButtonsPanel, bpy.types.Panel): bl_label = "VCS Job Settings" @@ -341,8 +350,8 @@ layout.label(text="Name: %s" % job.name) layout.label(text="Length: %04i" % len(job)) - layout.label(text="Done: %04i" % job.results[DONE]) - layout.label(text="Error: %04i" % job.results[ERROR]) + layout.label(text="Done: %04i" % job.results[FRAME_DONE]) + layout.label(text="Error: %04i" % job.results[FRAME_ERROR]) import bl_ui.properties_render as properties_render class RENDER_PT_network_output(NeedValidAddress, NetRenderButtonsPanel, bpy.types.Panel): @@ -403,6 +412,22 @@ name="Broadcast", description="broadcast master server address on local network", default = True) + NetRenderSettings.use_ssl = BoolProperty( + name="use ssl", + description="use ssl encryption for communication", + default = False) + NetRenderSettings.cert_path = StringProperty( + name="CertPath", + description="Path to ssl certifcate", + maxlen = 128, + default = "", + subtype='FILE_PATH') + NetRenderSettings.key_path = StringProperty( + name="key", + description="Path to ssl key file", + maxlen = 128, + default = "", + subtype='FILE_PATH') NetRenderSettings.use_slave_clear = BoolProperty( name="Clear on exit", @@ -414,6 +439,12 @@ description="Generate thumbnails on slaves instead of master", default = False) + NetRenderSettings.slave_tags = StringProperty( + name="Tags", + description="Tags to associate with the slave (semi-colon separated)", + maxlen = 256, + default = "") + NetRenderSettings.use_slave_output_log = BoolProperty( name="Output render log on console", description="Output render text log to console as well as sending it to the master", @@ -421,7 +452,12 @@ NetRenderSettings.use_master_clear = BoolProperty( name="Clear on exit", - description="delete saved files on exit", + description="Delete saved files on exit", + default = False) + + NetRenderSettings.use_master_force_upload = BoolProperty( + name="Force Dependency Upload", + description="Force client to upload dependency files to master", default = False) default_path = os.environ.get("TEMP") @@ -462,7 +498,34 @@ description="Category of the job", maxlen = 128, default = "") + + NetRenderSettings.job_tags = StringProperty( + name="Tags", + description="Tags to associate with the job (semi-colon separated)", + maxlen = 256, + default = "") + + NetRenderSettings.job_render_engine = EnumProperty( + items = ( + ("BLENDER_RENDER", "BLENDER", "Standard Blender Render"), + ("CYCLES", "CYCLES", "Cycle Render"), + ("OTHER", "OTHER", "Other non-default Render"), + ), + name="render", + description="Render engine used to render this job", + default="BLENDER_RENDER") + + NetRenderSettings.job_render_engine_other = StringProperty( + name="Render engine", + description="Render engine other than the builtin defaults (POVRAY_RENDER, ...)", + maxlen = 128, + default = "") + NetRenderSettings.save_before_job = BoolProperty( + name="Save Before Job", + description="Save current file before sending a job", + default = False) + NetRenderSettings.chunks = IntProperty( name="Chunks", description="Number of frame to dispatch to each slave in one chunk", @@ -495,11 +558,11 @@ maxlen = 256, default = "") - NetRenderSettings.vcs_system = StringProperty( - name="VCS", - description="Version Control System", - maxlen = 64, - default = "Subversion") + NetRenderSettings.vcs_system = EnumProperty( + items= netrender.versioning.ITEMS, + name="VCS mode", + description="Version Control System", + default=netrender.versioning.ITEMS[0][0]) NetRenderSettings.job_id = StringProperty( name="Network job id", diff -Nru blender-2.61/release/scripts/addons/netrender/utils.py blender-2.62/release/scripts/addons/netrender/utils.py --- blender-2.61/release/scripts/addons/netrender/utils.py 2011-12-13 19:58:44.000000000 +0000 +++ blender-2.62/release/scripts/addons/netrender/utils.py 2012-02-15 19:43:14.000000000 +0000 @@ -45,19 +45,26 @@ # Frames status -QUEUED = 0 -DISPATCHED = 1 -DONE = 2 -ERROR = 3 +FRAME_QUEUED = 0 +FRAME_DISPATCHED = 1 +FRAME_DONE = 2 +FRAME_ERROR = 3 FRAME_STATUS_TEXT = { - QUEUED: "Queued", - DISPATCHED: "Dispatched", - DONE: "Done", - ERROR: "Error" + FRAME_QUEUED: "Queued", + FRAME_DISPATCHED: "Dispatched", + FRAME_DONE: "Done", + FRAME_ERROR: "Error" } -if platform.system() == "Darwin": +try: + system = platform.system() +except UnicodeDecodeError: + import sys + system = sys.platform + + +if system == "Darwin": class ConnectionContext: def __init__(self, timeout = None): self.old_timeout = socket.getdefaulttimeout() @@ -81,6 +88,29 @@ def __exit__(self, exc_type, exc_value, traceback): pass +if system in {'Windows', 'win32'} and platform.version() >= '5': # Error mode is only available on Win2k or higher, that's version 5 + import ctypes + class NoErrorDialogContext: + def __init__(self): + self.val = 0 + + def __enter__(self): + self.val = ctypes.windll.kernel32.SetErrorMode(0x0002) + ctypes.windll.kernel32.SetErrorMode(self.val | 0x0002) + + def __exit__(self, exc_type, exc_value, traceback): + ctypes.windll.kernel32.SetErrorMode(self.val) +else: + class NoErrorDialogContext: + def __init__(self): + pass + + def __enter__(self): + pass + + def __exit__(self, exc_type, exc_value, traceback): + pass + class DirectoryContext: def __init__(self, path): self.path = path @@ -156,25 +186,30 @@ return ("", 8000) # return default values -def clientConnection(address, port, report = None, scan = True, timeout = 5): - if address == "[default]": +def clientConnection(netsettings, report = None, scan = True, timeout = 5): + address = netsettings.server_address + port = netsettings.server_port + use_ssl = netsettings.use_ssl + + if address== "[default]": # calling operator from python is fucked, scene isn't in context -# if bpy: -# bpy.ops.render.netclientscan() -# else: +# if bpy: +# bpy.ops.render.netclientscan() +# else: if not scan: return None address, port = clientScan() if address == "": return None - + conn = None try: + HTTPConnection = http.client.HTTPSConnection if use_ssl else http.client.HTTPConnection if platform.system() == "Darwin": with ConnectionContext(timeout): - conn = http.client.HTTPConnection(address, port) + conn = HTTPConnection(address, port) else: - conn = http.client.HTTPConnection(address, port, timeout = timeout) + conn = HTTPConnection(address, port, timeout = timeout) if conn: if clientVerifyVersion(conn): @@ -214,6 +249,9 @@ def logURL(job_id, frame_number): return "/log_%s_%i.log" % (job_id, frame_number) +def resultURL(job_id): + return "/result_%s.zip" % job_id + def renderURL(job_id, frame_number): return "/render_%s_%i.exr" % (job_id, frame_number) @@ -230,32 +268,94 @@ m = hashlib.md5() m.update(data) return m.hexdigest() + +def cacheName(ob, point_cache): + name = point_cache.name + if name == "": + name = "".join(["%02X" % ord(c) for c in ob.name]) + + return name + +def cachePath(file_path): + path, name = os.path.split(file_path) + root, ext = os.path.splitext(name) + return path + os.sep + "blendcache_" + root # need an API call for that + +# Process dependencies of all objects with user defined functions +# pointCacheFunction(object, owner, point_cache) (owner is modifier or psys) +# fluidFunction(object, modifier, cache_path) +# multiresFunction(object, modifier, cache_path) +def processObjectDependencies(pointCacheFunction, fluidFunction, multiresFunction): + for object in bpy.data.objects: + for modifier in object.modifiers: + if modifier.type == 'FLUID_SIMULATION' and modifier.settings.type == "DOMAIN": + fluidFunction(object, modifier, bpy.path.abspath(modifier.settings.filepath)) + elif modifier.type == "CLOTH": + pointCacheFunction(object, modifier, modifier.point_cache) + elif modifier.type == "SOFT_BODY": + pointCacheFunction(object, modifier, modifier.point_cache) + elif modifier.type == "SMOKE" and modifier.smoke_type == "DOMAIN": + pointCacheFunction(object, modifier, modifier.domain_settings.point_cache) + elif modifier.type == "MULTIRES" and modifier.is_external: + multiresFunction(object, modifier, bpy.path.abspath(modifier.filepath)) + elif modifier.type == "DYNAMIC_PAINT" and modifier.canvas_settings: + for surface in modifier.canvas_settings.canvas_surfaces: + pointCacheFunction(object, modifier, surface.point_cache) + + # particles modifier are stupid and don't contain data + # we have to go through the object property + for psys in object.particle_systems: + pointCacheFunction(object, psys, psys.point_cache) -def prefixPath(prefix_directory, file_path, prefix_path, force = False): - if (os.path.isabs(file_path) or - len(file_path) >= 3 and (file_path[1:3] == ":/" or file_path[1:3] == ":\\") or # Windows absolute path don't count as absolute on unix, have to handle them myself - file_path[0] == "/" or file_path[0] == "\\"): # and vice versa +def createLocalPath(rfile, prefixdirectory, prefixpath, forcelocal): + filepath = rfile.original_path + prefixpath = os.path.normpath(prefixpath) if prefixpath else None + if (os.path.isabs(filepath) or + filepath[1:3] == ":/" or filepath[1:3] == ":\\" or # Windows absolute path don't count as absolute on unix, have to handle them ourself + filepath[:1] == "/" or filepath[:1] == "\\"): # and vice versa # if an absolute path, make sure path exists, if it doesn't, use relative local path - full_path = file_path - if force or not os.path.exists(full_path): - p, n = os.path.split(os.path.normpath(full_path)) - - if prefix_path and p.startswith(prefix_path): - if len(prefix_path) < len(p): - directory = os.path.join(prefix_directory, p[len(prefix_path)+1:]) # +1 to remove separator - if not os.path.exists(directory): - os.mkdir(directory) - else: - directory = prefix_directory - full_path = os.path.join(directory, n) + finalpath = filepath + if forcelocal or not os.path.exists(finalpath): + path, name = os.path.split(os.path.normpath(finalpath)) + + # Don't add signatures to cache files, relink fails otherwise + if not name.endswith(".bphys") and not name.endswith(".bobj.gz"): + name, ext = os.path.splitext(name) + name = name + "_" + rfile.signature + ext + + if prefixpath and path.startswith(prefixpath): + suffix = "" + while path != prefixpath: + path, last = os.path.split(path) + suffix = os.path.join(last, suffix) + + directory = os.path.join(prefixdirectory, suffix) + + if not os.path.exists(directory): + os.mkdir(directory) + + finalpath = os.path.join(directory, name) else: - full_path = os.path.join(prefix_directory, n) + finalpath = os.path.join(prefixdirectory, name) else: - full_path = os.path.join(prefix_directory, file_path) + directory, name = os.path.split(filepath) + + # Don't add signatures to cache files + if not name.endswith(".bphys") and not name.endswith(".bobj.gz"): + name, ext = os.path.splitext(name) + name = name + "_" + rfile.signature + ext + + directory = directory.replace("../") + directory = os.path.join(prefixdirectory, directory) + + if not os.path.exists(directory): + os.mkdir(directory) + + finalpath = os.path.join(directory, name) - return full_path + return finalpath def getResults(server_address, server_port, job_id, resolution_x, resolution_y, resolution_percentage, frame_ranges): if bpy.app.debug: diff -Nru blender-2.61/release/scripts/addons/netrender/versioning.py blender-2.62/release/scripts/addons/netrender/versioning.py --- blender-2.61/release/scripts/addons/netrender/versioning.py 2011-12-13 19:58:44.000000000 +0000 +++ blender-2.62/release/scripts/addons/netrender/versioning.py 2012-02-15 19:43:14.000000000 +0000 @@ -46,6 +46,7 @@ class Subversion(AbstractVCS): name = "Subversion" + description = "Use the Subversion version control system" def __init__(self): super().__init__() self.version_exp = re.compile("([0-9]*)") @@ -87,6 +88,7 @@ class Git(AbstractVCS): name = "Git" + description = "Use the Git distributed version control system" def __init__(self): super().__init__() self.version_exp = re.compile("^commit (.*)") @@ -124,3 +126,9 @@ Subversion.name: Subversion(), Git.name: Git() } + +ITEMS = ( + (Subversion.name, Subversion.name, Subversion.description), + (Git.name, Git.name, Git.description), + ) + diff -Nru blender-2.61/release/scripts/addons/object_add_chain.py blender-2.62/release/scripts/addons/object_add_chain.py --- blender-2.61/release/scripts/addons/object_add_chain.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/object_add_chain.py 2012-02-15 19:43:32.000000000 +0000 @@ -21,7 +21,6 @@ "author": "Brian Hinton (Nichod)", "version": (0,1), "blender": (2, 5, 9), - "api": 39685, "location": "View3D > Add > Mesh", "description": "Adds Chain with curve guide for easy creation", "warning": "", @@ -143,7 +142,7 @@ #makes AddChain an operator class AddChain(bpy.types.Operator): - '''Add a Chain.''' + '''Add a Chain''' bl_idname = "mesh.primitive_chain_add" bl_label = "Add Chain" bl_options = {'REGISTER', 'UNDO'} diff -Nru blender-2.61/release/scripts/addons/object_animrenderbake.py blender-2.62/release/scripts/addons/object_animrenderbake.py --- blender-2.61/release/scripts/addons/object_animrenderbake.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/object_animrenderbake.py 2012-02-15 19:43:32.000000000 +0000 @@ -21,7 +21,6 @@ "author": "Janne Karhu (jahka)", "version": (1, 0), "blender": (2, 5, 8), - "api": 35622, "location": "Properties > Render > Bake Panel", "description": "Renderbakes a series of frames", "category": "Object", diff -Nru blender-2.61/release/scripts/addons/object_cloud_gen.py blender-2.62/release/scripts/addons/object_cloud_gen.py --- blender-2.61/release/scripts/addons/object_cloud_gen.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/object_cloud_gen.py 2012-02-15 19:43:32.000000000 +0000 @@ -21,7 +21,6 @@ "author": "Nick Keeline(nrk)", "version": (1,0), "blender": (2, 5, 9), - "api": 39685, "location": "View3D > Tool Shelf > Cloud Generator Panel", "description": "Creates Volumetric Clouds", "warning": "", diff -Nru blender-2.61/release/scripts/addons/object_fracture/fracture_ops.py blender-2.62/release/scripts/addons/object_fracture/fracture_ops.py --- blender-2.61/release/scripts/addons/object_fracture/fracture_ops.py 2011-12-13 19:58:33.000000000 +0000 +++ blender-2.62/release/scripts/addons/object_fracture/fracture_ops.py 2012-02-15 19:42:53.000000000 +0000 @@ -342,13 +342,13 @@ class FractureSimple(bpy.types.Operator): - '''Split object with boolean operations for simulation, uses an object.''' + '''Split object with boolean operations for simulation, uses an object''' bl_idname = "object.fracture_simple" bl_label = "Fracture Object" bl_options = {'REGISTER', 'UNDO'} exe = BoolProperty(name="Execute", - description="If it shall actually run, for optimal performance...", + description="If it shall actually run, for optimal performance", default=False) hierarchy = BoolProperty(name="Generate hierarchy", @@ -388,13 +388,13 @@ class FractureGroup(bpy.types.Operator): - '''Split object with boolean operations for simulation, uses a group.''' + '''Split object with boolean operations for simulation, uses a group''' bl_idname = "object.fracture_group" bl_label = "Fracture Object (Group)" bl_options = {'REGISTER', 'UNDO'} exe = BoolProperty(name="Execute", - description="If it shall actually run, for optimal performance...", + description="If it shall actually run, for optimal performance", default=False) group = StringProperty(name="Group", diff -Nru blender-2.61/release/scripts/addons/object_fracture/__init__.py blender-2.62/release/scripts/addons/object_fracture/__init__.py --- blender-2.61/release/scripts/addons/object_fracture/__init__.py 2011-12-13 19:58:33.000000000 +0000 +++ blender-2.62/release/scripts/addons/object_fracture/__init__.py 2012-02-15 19:42:53.000000000 +0000 @@ -21,7 +21,6 @@ "author": "pildanovak", "version": (2, 0), "blender": (2, 5, 7), - "api": 36147, "location": "Search > Fracture Object & Add -> Fracture Helper Objects", "description": "Fractured Object, Bomb, Projectile, Recorder", "warning": "", diff -Nru blender-2.61/release/scripts/addons/object_grease_scatter.py blender-2.62/release/scripts/addons/object_grease_scatter.py --- blender-2.61/release/scripts/addons/object_grease_scatter.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/object_grease_scatter.py 2012-02-15 19:43:32.000000000 +0000 @@ -25,7 +25,6 @@ "author": "Campbell Barton", "version": (0, 1), "blender": (2, 5, 8), - "api": 36079, "location": "3D View, Add Mesh", "description": "Scatter a group of objects onto the active mesh using " "the grease pencil lines", diff -Nru blender-2.61/release/scripts/addons/paint_palette.py blender-2.62/release/scripts/addons/paint_palette.py --- blender-2.61/release/scripts/addons/paint_palette.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/paint_palette.py 2012-02-15 19:43:32.000000000 +0000 @@ -25,7 +25,6 @@ "author": "Dany Lebel (Axon D)", "version": (0,9,0), "blender": (2, 5, 8), - "api": 37815, "location": "Image Editor and 3D View > Any Paint mode > Color Palette or Weight Palette panel", "description": "Palettes for color and weight paint modes", "warning": "", diff -Nru blender-2.61/release/scripts/addons/render_copy_settings/__init__.py blender-2.62/release/scripts/addons/render_copy_settings/__init__.py --- blender-2.61/release/scripts/addons/render_copy_settings/__init__.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons/render_copy_settings/__init__.py 2012-02-15 19:43:15.000000000 +0000 @@ -0,0 +1,125 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the 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. +# +# ##### END GPL LICENSE BLOCK ##### + +# + +bl_info = { + "name": "Copy Settings", + "author": "Bastien Montagne", + "version": (0, 1, 4), + "blender": (2, 6, 1), + "location": "Render buttons (Properties window)", + "description": "Allows to copy a selection of render settings from " + "current scene to others.", + "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/" + "Scripts/Render/Copy Settings", + "tracker_url": "http://projects.blender.org/tracker/index.php?" + "func=detail&aid=25832", + "category": "Render"} + + +if "bpy" in locals(): + import imp + imp.reload(operator) + imp.reload(panel) + +else: + from . import operator, panel + + +import bpy +from bpy.props import (StringProperty, + BoolProperty, + IntProperty, + CollectionProperty, + PointerProperty) + + +############################################################################### +# Global properties for the script, for UI (as there’s no way to let them in +# the operator…). +############################################################################### + +class RenderCopySettingsScene(bpy.types.PropertyGroup): + allowed = BoolProperty(default=True) + + # A string of identifiers (colon delimited) which property’s controls + # should be displayed in a template_list. + template_list_controls = StringProperty(default="allowed", + options={"HIDDEN"}) + + +class RenderCopySettingsSetting(bpy.types.PropertyGroup): + strid = StringProperty(default="") + copy = BoolProperty(default=False) + + # A string of identifiers (colon delimited) which property’s controls + # should be displayed in a template_list. + template_list_controls = StringProperty(default="copy", + options={"HIDDEN"}) + + +class RenderCopySettings(bpy.types.PropertyGroup): + # XXX: The consistency of this collection is delegated to the UI code. + # It should only contain one element for each render setting. + affected_settings = CollectionProperty(type=RenderCopySettingsSetting, + name="Affected Settings", + description="The list of all " + "available render " + "settings") + # XXX Unused, but needed for template_list… + aff_sett_idx = IntProperty() + + # XXX: The consistency of this collection is delegated to the UI code. + # It should only contain one element for each scene. + allowed_scenes = CollectionProperty(type=RenderCopySettingsScene, + name="Allowed Scenes", + description="The list all scenes " + "in the file") + # XXX Unused, but needed for template_list… + allw_scenes_idx = IntProperty() + + filter_scene = StringProperty(name="Filter Scene", + description="Regex to only affect scenes " + "which name matches it", + default="") + + +def register(): + # Register properties. + bpy.utils.register_class(RenderCopySettingsScene) + bpy.utils.register_class(RenderCopySettingsSetting) + bpy.utils.register_class(RenderCopySettings) + bpy.types.Scene.render_copy_settings = \ + PointerProperty(type=RenderCopySettings) + + bpy.utils.register_module(__name__) + + +def unregister(): + # Unregister properties. + bpy.utils.unregister_class(RenderCopySettingsScene) + bpy.utils.unregister_class(RenderCopySettingsSetting) + bpy.utils.unregister_class(RenderCopySettings) + del bpy.types.Scene.render_copy_settings + + bpy.utils.unregister_module(__name__) + + +if __name__ == "__main__": + register() diff -Nru blender-2.61/release/scripts/addons/render_copy_settings/operator.py blender-2.62/release/scripts/addons/render_copy_settings/operator.py --- blender-2.61/release/scripts/addons/render_copy_settings/operator.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons/render_copy_settings/operator.py 2012-02-15 19:43:15.000000000 +0000 @@ -0,0 +1,205 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the 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. +# +# ##### END GPL LICENSE BLOCK ##### + +# + +import bpy +from . import presets + +# These operators are only defined because it seems impossible to directly +# edit properties from UI code… + + +# A sorting func for collections (working in-place). +# XXX Not optimized at all… +# XXX If some items in the collection do not have the sortkey property, +# they are just ignored… +def collection_property_sort(collection, sortkey, start_idx=0): + while start_idx + 1 < len(collection): + while not hasattr(collection[start_idx], sortkey): + start_idx += 1 + if start_idx + 1 >= len(collection): + return collection + min_idx = start_idx + min_prop = collection[start_idx] + for i, prop in enumerate(collection[start_idx + 1:]): + if not hasattr(prop, sortkey): + continue + if getattr(prop, sortkey) < getattr(min_prop, sortkey): + min_prop = prop + min_idx = i + start_idx + 1 + collection.move(min_idx, start_idx) + start_idx += 1 + return collection + + +class RenderCopySettingsPrepare(bpy.types.Operator): + ''' + Prepare internal data for render_copy_settings (gathering all existing + render settings, and scenes) + ''' + bl_idname = "scene.render_copy_settings_prepare" + bl_label = "Render: Copy Settings Prepare" + bl_option = {'REGISTER'} + + @classmethod + def poll(cls, context): + return context.scene != None + + def execute(self, context): + cp_sett = context.scene.render_copy_settings + + # Get all available render settings, and update accordingly + # affected_settings… + props = {} + for prop in context.scene.render.bl_rna.properties: + if prop.identifier in {'rna_type'}: + continue + if prop.is_readonly: + continue + props[prop.identifier] = prop.name + corr = 0 + for i, sett in enumerate(cp_sett.affected_settings): + if sett.strid not in props: + cp_sett.affected_settings.remove(i - corr) + corr += 1 + else: + del props[sett.strid] + for strid, name in props.items(): + sett = cp_sett.affected_settings.add() + sett.name = "{} [{}]".format(name, strid) + sett.strid = strid + collection_property_sort(cp_sett.affected_settings, "name") + + # Get all available scenes, and update accordingly allowed_scenes… + regex = None + if cp_sett.filter_scene: + try: + import re + try: + regex = re.compile(cp_sett.filter_scene) + except Exception as e: + self.report('ERROR_INVALID_INPUT', "The filter-scene " + "regex did not compile:\n (%s)." % str(e)) + return {'CANCELLED'} + except: + regex = None + self.report('WARNING', "Unable to import the re module. " + "Regex scene filtering will be disabled!") + scenes = set() + for scene in bpy.data.scenes: + if scene == bpy.context.scene: # Exclude current scene! + continue + # If a valid filtering regex, only keep scenes matching it. + if regex: + if regex.match(scene.name): + scenes.add(scene.name) + else: + scenes.add(scene.name) + for i, scene in enumerate(cp_sett.allowed_scenes): + if scene.name not in scenes: + cp_sett.allowed_scenes.remove(i) + else: + scenes.remove(scene.name) + for scene in scenes: + sett = cp_sett.allowed_scenes.add() + sett.name = scene + collection_property_sort(cp_sett.allowed_scenes, "name") + + return {'FINISHED'} + + +from bpy.props import EnumProperty + + +class RenderCopySettingsPreset(bpy.types.Operator): + '''Apply some presets of render settings to copy to other scenes''' + bl_idname = "scene.render_copy_settings_preset" + bl_label = "Render: Copy Settings Preset" + bl_description = "Apply or clear this preset of render settings" + # Enable undo… + bl_option = {'REGISTER', 'UNDO'} + + presets = EnumProperty(items=(p.rna_enum for p in presets.presets), + default=set(), + options={"ENUM_FLAG"}) + + @staticmethod + def process_elements(settings, elts): + setts = [] + val = True + for sett in settings: + if sett.strid in elts: + setts.append(sett) + val = val and sett.copy + for e in setts: + e.copy = not val + + @classmethod + def poll(cls, context): + return context.scene != None + + def execute(self, context): + cp_sett = context.scene.render_copy_settings + for p in presets.presets: + if p.rna_enum[0] in self.presets: + self.process_elements(cp_sett.affected_settings, p.elements) + return {'FINISHED'} + + +# Real interesting stuff… + +def do_copy(context, affected_settings, allowed_scenes): + # Stores render settings from current scene. + p = {sett: getattr(context.scene.render, sett) + for sett in affected_settings} + # put it in all other (valid) scenes’ render settings! + for scene in bpy.data.scenes: + # If scene not in allowed scenes, skip. + if scene.name not in allowed_scenes: + continue + # Propagate all affected settings. + for sett, val in p.items(): + setattr(scene.render, sett, val) + + +class RenderCopySettings(bpy.types.Operator): + '''Copy render settings from current scene to others''' + bl_idname = "scene.render_copy_settings" + bl_label = "Render: Copy Settings" + # Enable undo… + bl_option = {'REGISTER', 'UNDO'} + + @classmethod + def poll(cls, context): + return context.scene != None + + def execute(self, context): + regex = None + cp_sett = context.scene.render_copy_settings + affected_settings = {sett.strid for sett in cp_sett.affected_settings + if sett.copy} + allowed_scenes = {sce.name for sce in cp_sett.allowed_scenes + if sce.allowed} + do_copy(context, affected_settings=affected_settings, + allowed_scenes=allowed_scenes) + return {'FINISHED'} + + +if __name__ == "__main__": + bpy.ops.scene.render_copy_settings() diff -Nru blender-2.61/release/scripts/addons/render_copy_settings/panel.py blender-2.62/release/scripts/addons/render_copy_settings/panel.py --- blender-2.61/release/scripts/addons/render_copy_settings/panel.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons/render_copy_settings/panel.py 2012-02-15 19:43:15.000000000 +0000 @@ -0,0 +1,70 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the 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. +# +# ##### END GPL LICENSE BLOCK ##### + +# + +import bpy +from . import presets + + +class RENDER_PT_copy_settings(bpy.types.Panel): + bl_label = "Copy Settings" + bl_space_type = "PROPERTIES" + bl_region_type = "WINDOW" + bl_context = "render" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER'} + + def draw(self, context): + layout = self.layout + cp_sett = context.scene.render_copy_settings + + layout.operator("scene.render_copy_settings", + text="Copy Render Settings") + + # This will update affected_settings/allowed_scenes (as this seems + # to be impossible to do it from here…). + if bpy.ops.scene.render_copy_settings_prepare.poll(): + bpy.ops.scene.render_copy_settings_prepare() + + split = layout.split(0.75) + split.template_list(cp_sett, "affected_settings", cp_sett, + "aff_sett_idx", + prop_list="template_list_controls", rows=6) + + col = split.column() + all_set = {sett.strid for sett in cp_sett.affected_settings + if sett.copy} + for p in presets.presets: + label = "" + if p.elements & all_set == p.elements: + label = "Clear {}".format(p.ui_name) + else: + label = "Set {}".format(p.ui_name) + col.operator("scene.render_copy_settings_preset", + text=label).presets = {p.rna_enum[0]} + + layout.prop(cp_sett, "filter_scene") + if len(cp_sett.allowed_scenes): + layout.label("Affected Scenes:") + # XXX Unfortunately, there can only be one template_list per panel… + col = layout.column_flow(columns=0) + for i, prop in enumerate(cp_sett.allowed_scenes): + col.prop(prop, "allowed", toggle=True, text=prop.name) + else: + layout.label(text="No Affectable Scenes!", icon="ERROR") diff -Nru blender-2.61/release/scripts/addons/render_copy_settings/presets.py blender-2.62/release/scripts/addons/render_copy_settings/presets.py --- blender-2.61/release/scripts/addons/render_copy_settings/presets.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons/render_copy_settings/presets.py 2012-02-15 19:43:15.000000000 +0000 @@ -0,0 +1,51 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the 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. +# +# ##### END GPL LICENSE BLOCK ##### + +# + + +class CopyPreset(object): + def __init__(self, ui_name, rna_enum, elements): + self.ui_name = ui_name + self.rna_enum = rna_enum + self.elements = elements + + +presets = (CopyPreset("Resolution", + ("resolution", "Render Resolution", + "Render resolution and aspect ratio settings"), + {"resolution_x", "resolution_y", + "pixel_aspect_x", "pixel_aspect_y"}), + CopyPreset("Scale", + ("scale", "Render Scale", "The “Render Scale” setting"), + {"resolution_percentage"}), + CopyPreset("OSA", + ("osa", "Render OSA", + "The OSA toggle and sample settings"), + {"use_antialiasing", "antialiasing_samples"}), + CopyPreset("Threads", + ("threads", "Render Threads", + "The thread mode and number settings"), + {"threads_mode", "threads"}), + CopyPreset("Fields", + ("fields", "Render Fields", "The Fields settings"), + {"use_fields", "field_order", "use_fields_still"}), + CopyPreset("Stamp", + ("stamp", "Render Stamp", "The Stamp toggle"), + {"use_stamp"}) + ) diff -Nru blender-2.61/release/scripts/addons/render_povray/__init__.py blender-2.62/release/scripts/addons/render_povray/__init__.py --- blender-2.61/release/scripts/addons/render_povray/__init__.py 2011-12-13 19:58:39.000000000 +0000 +++ blender-2.62/release/scripts/addons/render_povray/__init__.py 2012-02-15 19:42:59.000000000 +0000 @@ -23,7 +23,6 @@ "author": "Campbell Barton, Silvio Falcinelli, Maurice Raybaud, Constantin Rahn, Bastien Montagne", "version": (0, 0, 9), "blender": (2, 5, 7), - "api": 35622, "location": "Render > Engine > POV-Ray 3.7", "description": "Basic POV-Ray 3.7 integration for blender", "warning": "both POV-Ray 3.7 and this script are beta", diff -Nru blender-2.61/release/scripts/addons/render_povray/render.py blender-2.62/release/scripts/addons/render_povray/render.py --- blender-2.61/release/scripts/addons/render_povray/render.py 2011-12-13 19:58:39.000000000 +0000 +++ blender-2.62/release/scripts/addons/render_povray/render.py 2012-02-15 19:42:59.000000000 +0000 @@ -210,16 +210,18 @@ return name def writeMatrix(matrix): - tabWrite("matrix <%.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, " \ - "%.6f>\n" % (matrix[0][0], matrix[0][1], matrix[0][2], matrix[1][0], matrix[1][1], - matrix[1][2], matrix[2][0], matrix[2][1], matrix[2][2], matrix[3][0], - matrix[3][1], matrix[3][2])) + tabWrite("matrix <%.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f>\n" % + (matrix[0][0], matrix[1][0], matrix[2][0], + matrix[0][1], matrix[1][1], matrix[2][1], + matrix[0][2], matrix[1][2], matrix[2][2], + matrix[0][3], matrix[1][3], matrix[2][3])) def MatrixAsPovString(matrix): - sMatrix = ("matrix <%.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, " \ - "%.6f>\n" % (matrix[0][0], matrix[0][1], matrix[0][2], matrix[1][0], matrix[1][1], - matrix[1][2], matrix[2][0], matrix[2][1], matrix[2][2], matrix[3][0], - matrix[3][1], matrix[3][2])) + sMatrix = ("matrix <%.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f>\n" % + (matrix[0][0], matrix[1][0], matrix[2][0], + matrix[0][1], matrix[1][1], matrix[2][1], + matrix[0][2], matrix[1][2], matrix[2][2], + matrix[0][3], matrix[1][3], matrix[2][3])) return sMatrix def writeObjectMaterial(material, ob): @@ -524,9 +526,9 @@ # compute resolution Qsize = float(render.resolution_x) / float(render.resolution_y) - tabWrite("#declare camLocation = <%.6f, %.6f, %.6f>;\n" % \ - (matrix[3][0], matrix[3][1], matrix[3][2])) - tabWrite("#declare camLookAt = <%.6f, %.6f, %.6f>;\n" % \ + tabWrite("#declare camLocation = <%.6f, %.6f, %.6f>;\n" % + matrix.translation[:]) + tabWrite("#declare camLookAt = <%.6f, %.6f, %.6f>;\n" % tuple([degrees(e) for e in matrix.to_3x3().to_euler()])) tabWrite("camera {\n") @@ -546,7 +548,7 @@ tabWrite("rotate <%.6f, %.6f, %.6f>\n" % \ tuple([degrees(e) for e in matrix.to_3x3().to_euler()])) - tabWrite("translate <%.6f, %.6f, %.6f>\n" % (matrix[3][0], matrix[3][1], matrix[3][2])) + tabWrite("translate <%.6f, %.6f, %.6f>\n" % matrix.translation[:]) if camera.data.pov.dof_enable and focal_point != 0: tabWrite("aperture %.3g\n" % camera.data.pov.dof_aperture) tabWrite("blur_samples %d %d\n" % \ diff -Nru blender-2.61/release/scripts/addons/render_povray/update_files.py blender-2.62/release/scripts/addons/render_povray/update_files.py --- blender-2.61/release/scripts/addons/render_povray/update_files.py 2011-12-13 19:58:39.000000000 +0000 +++ blender-2.62/release/scripts/addons/render_povray/update_files.py 2012-02-15 19:42:59.000000000 +0000 @@ -20,8 +20,12 @@ import bpy -from bpy.props import StringProperty, BoolProperty, IntProperty, FloatProperty, \ - FloatVectorProperty, EnumProperty +from bpy.props import (StringProperty, + BoolProperty, + IntProperty, + FloatProperty, + FloatVectorProperty, + EnumProperty) def update2_0_0_9(): diff -Nru blender-2.61/release/scripts/addons/render_renderfarmfi.py blender-2.62/release/scripts/addons/render_renderfarmfi.py --- blender-2.61/release/scripts/addons/render_renderfarmfi.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/render_renderfarmfi.py 2012-02-15 19:43:32.000000000 +0000 @@ -16,12 +16,13 @@ # # ##### END GPL LICENSE BLOCK ##### +DEV = False + bl_info = { "name": "Renderfarm.fi", "author": "Nathan Letwory , Jesse Kaukonen ", - "version": (12,), - "blender": (2, 6, 0), - "api": 41934, + "version": (15,), + "blender": (2, 6, 1), "location": "Render > Engine > Renderfarm.fi", "description": "Send .blend as session to http://www.renderfarm.fi to render", "warning": "", @@ -86,6 +87,15 @@ bpy.simulationWarning = False bpy.ready = False +if DEV: + rffi_xmlrpc_secure = r'http://192.168.0.109/burp/xmlrpc' + rffi_xmlrpc = r'http://192.168.0.109/burp/xmlrpc' + rffi_xmlrpc_upload = '192.168.0.109' +else: + rffi_xmlrpc_secure = r'https://xmlrpc.renderfarm.fi/burp/xmlrpc' + rffi_xmlrpc = r'http://xmlrpc.renderfarm.fi/burp/xmlrpc' + rffi_xmlrpc_upload = 'xmlrpc.renderfarm.fi' + def renderEngine(render_engine): bpy.utils.register_class(render_engine) return render_engine @@ -536,7 +546,7 @@ layout.label(text="Optional advanced settings", icon='MODIFIER') row = layout.row() row.prop(ore, 'memusage') - row.prop(ore, 'parts') + #row.prop(ore, 'parts') layout.separator() row = layout.row() @@ -616,9 +626,9 @@ return body, headers -def send_post(url, data, files): - connection = http.client.HTTPConnection('xmlrpc.renderfarm.fi') - connection.request('POST', '/file', *encode_multipart_data(data, files)) +def send_post(data, files): + connection = http.client.HTTPConnection(rffi_xmlrpc_upload) + connection.request('POST', '/burp/storage', *encode_multipart_data(data, files)) # was /file response = connection.getresponse() res = response.read() return res @@ -634,7 +644,7 @@ md5hash.update(data) return md5hash.hexdigest() -def upload_file(key, userid, sessionid, server, path): +def upload_file(key, userid, sessionid, path): assert isabs(path) assert isfile(path) data = { @@ -646,16 +656,16 @@ files = { 'blenderfile': path } - r = send_post(server, data, files) - #print 'Uploaded %r' % (path) + r = send_post(data, files) return r def run_upload(key, userid, sessionid, path): - #print('Upload', path) - r = upload_file(key, userid, sessionid, r'http://xmlrpc.renderfarm.fi/file', path) + print("Starting upload"); + r = upload_file(key, userid, sessionid, path) + print("Upload finished") o = xmlrpc.client.loads(r) - print("Done!") + print("Loaded xmlrpc response") return o[0][0] def ore_upload(op, context): @@ -669,17 +679,24 @@ bpy.context.scene.render.engine = 'RENDERFARMFI_RENDER' return {'CANCELLED'} try: - authproxy = xmlrpc.client.ServerProxy(r'https://xmlrpc.renderfarm.fi/auth') + print("Creating auth proxy") + authproxy = xmlrpc.client.ServerProxy(rffi_xmlrpc_secure) + print("Getting session key") res = authproxy.auth.getSessionKey(ore.username, ore.hash) key = res['key'] userid = res['userId'] - proxy = xmlrpc.client.ServerProxy(r'http://xmlrpc.renderfarm.fi/session') + print("Creating server proxy") + proxy = xmlrpc.client.ServerProxy(rffi_xmlrpc) #r'http://xmlrpc.renderfarm.fi/session') proxy._ServerProxy__transport.user_agent = 'Renderfarm.fi Uploader/%s' % (bpy.CURRENT_VERSION) + print("Creating a new session") res = proxy.session.createSession(userid, key) sessionid = res['sessionId'] key = res['key'] + print("Session id is " + str(sessionid)) res = run_upload(key, userid, sessionid, bpy.data.filepath) + print("Getting fileid from xmlrpc response data") fileid = int(res['fileId']) + print("Sending session details for session " + str(sessionid) + " with fileid " + str(fileid)) res = proxy.session.setTitle(userid, res['key'], sessionid, ore.title) res = proxy.session.setLongDescription(userid, res['key'], sessionid, ore.longdesc) res = proxy.session.setShortDescription(userid, res['key'], sessionid, ore.shortdesc) @@ -694,20 +711,23 @@ res = proxy.session.setFrameRate(userid, res['key'], sessionid, ore.fps) res = proxy.session.setOutputLicense(userid, res['key'], sessionid, int(ore.outlicense)) res = proxy.session.setInputLicense(userid, res['key'], sessionid, int(ore.inlicense)) + print("Setting primary input file") res = proxy.session.setPrimaryInputFile(userid, res['key'], sessionid, fileid) + print("Submitting session") res = proxy.session.submit(userid, res['key'], sessionid) + print("Session submitted") op.report(set(['INFO']), 'Submission sent to Renderfarm.fi') except xmlrpc.client.Error as v: bpy.context.scene.render.engine = 'RENDERFARMFI_RENDER' print('ERROR:', v) - op.report(set(['ERROR']), 'An error occurred while sending submission to Renderfarm.fi') + op.report(set(['ERROR']), 'An XMLRPC error occurred while sending submission to Renderfarm.fi') except Exception as e: bpy.context.scene.render.engine = 'RENDERFARMFI_RENDER' print('Unhandled error:', e) - op.report(set(['ERROR']), 'An error occurred while sending submission to Renderfarm.fi') + op.report(set(['ERROR']), 'A generic error occurred while sending submission to Renderfarm.fi') bpy.context.scene.render.engine = 'RENDERFARMFI_RENDER' - doRefresh() + doRefresh(op) return {'FINISHED'} def setStatus(property, status): @@ -750,53 +770,71 @@ def percentageComplete(self): totFrames = self.endframe - self.startframe + done = 0 if totFrames != 0: done = math.floor((self.frames / totFrames)*100) - else: - done = math.floor((self.frames / (totFrames+0.01))*100) if done > 100: done = 100 return done -def xmlSessionsToOreSessions(sessions, queue): - #bpy.ore_sessions = [] +def xmlSessionsToOreSessions(sessions, stage=None): #, queue): output = [] - sessionFilter = [] - sessionFilter = sessions[queue] - for sid in sessionFilter: - s = sessionFilter[sid]['title'] - t = sessionFilter[sid]['timestamps'] - sinfo = OreSession(sid, s) - if queue in ('completed', 'active'): - sinfo.frames = sessionFilter[sid]['framesRendered'] - sinfo.startframe = sessionFilter[sid]['startFrame'] - sinfo.endframe = sessionFilter[sid]['endFrame'] - #bpy.ore_sessions.append(sinfo) + for session in sessions: + s = session['title'] + if stage: + s = s + ' (' + stage + ')' + #t = session['timestamps'] + sinfo = OreSession(session['sessionId'], s) + if stage in {'Completed', 'Active'}: + sinfo.frames = session['framesRendered'] + sinfo.startframe = session['startFrame'] + sinfo.endframe = session['endFrame'] output.append(sinfo) return output -def doRefresh(): +def doRefresh(op, rethrow=False): sce = bpy.context.scene ore = sce.ore_render try: - userproxy = xmlrpc.client.ServerProxy(r'https://xmlrpc.renderfarm.fi/user') - sessions = userproxy.user.getAllSessions(ore.username, ore.hash, 'completed') + + proxy = xmlrpc.client.ServerProxy(rffi_xmlrpc_secure) + res = proxy.auth.getSessionKey(ore.username, ore.hash) + userid = res['userID'] + proxy = xmlrpc.client.ServerProxy(rffi_xmlrpc) + bpy.ore_sessions = [] - bpy.ore_sessions = xmlSessionsToOreSessions(sessions, 'completed') + + sessions = proxy.session.getSessions(userid, 'accept', 0, 100, 'full') + bpy.ore_sessions = xmlSessionsToOreSessions(sessions, stage='Pending') + bpy.ore_pending_sessions = bpy.ore_sessions + + sessions = proxy.session.getSessions(userid, 'completed', 0, 100, 'full') + bpy.ore_sessions = xmlSessionsToOreSessions(sessions, stage='Completed') bpy.ore_completed_sessions = bpy.ore_sessions - bpy.ore_cancelled_sessions = xmlSessionsToOreSessions(sessions, 'canceled') - sessions = userproxy.user.getAllSessions(ore.username, ore.hash, 'accept') - bpy.ore_pending_sessions = xmlSessionsToOreSessions(sessions, 'accept') - sessions = userproxy.user.getAllSessions(ore.username, ore.hash, 'active') - bpy.ore_active_sessions = xmlSessionsToOreSessions(sessions, 'active') + + sessions = proxy.session.getSessions(userid, 'cancelled', 0, 100, 'full') + bpy.ore_sessions = xmlSessionsToOreSessions(sessions, stage='Cancelled') + bpy.ore_cancelled_sessions = bpy.ore_sessions + + sessions = proxy.session.getSessions(userid, 'render', 0, 100, 'full') + bpy.ore_sessions = xmlSessionsToOreSessions(sessions, stage='Rendering') + bpy.ore_active_sessions = bpy.ore_sessions updateCompleteSessionList(ore) return 0 except xmlrpc.client.Error as v: - self.report({'WARNING'}, "Error at refresh") + op.report({'WARNING'}, "Error at refresh : " + str(type(v)) + " -> " + str(v.faultCode) + ": " + v.faultString) print(v) + if rethrow: + raise v + return 1 + except Exception as v: + op.report({'WARNING'}, "Non XMLRPC Error at refresh: " + str(v)) + print(v) + if rethrow: + raise v return 1 class ORE_RefreshOp(bpy.types.Operator): @@ -804,7 +842,7 @@ bl_label = 'Refresh' def execute(self, context): - result = doRefresh() + result = doRefresh(self) if (result == 0): return {'FINISHED'} else: @@ -834,8 +872,8 @@ bpy.ore_complete_session_queue = [] bpy.ore_complete_session_queue.extend(bpy.ore_pending_sessions) bpy.ore_complete_session_queue.extend(bpy.ore_active_sessions) - #bpy.ore_complete_session_queue.extend(bpy.ore_completed_sessions) - #bpy.ore_complete_session_queue.extend(bpy.ore_cancelled_sessions) + bpy.ore_complete_session_queue.extend(bpy.ore_completed_sessions) + bpy.ore_complete_session_queue.extend(bpy.ore_cancelled_sessions) bpy.ore_active_session_queue = bpy.ore_complete_session_queue updateSessionList(ore.all_sessions, ore) @@ -856,15 +894,19 @@ def execute(self, context): sce = context.scene ore = sce.ore_render - userproxy = xmlrpc.client.ServerProxy(r'https://xmlrpc.renderfarm.fi/user') + proxy = xmlrpc.client.ServerProxy(rffi_xmlrpc_secure) if len(bpy.ore_complete_session_queue)>0: s = bpy.ore_complete_session_queue[ore.selected_session] try: - userproxy.user.cancelSession(ore.username, ore.hash, int(s.id)) - doRefresh() - self.report(set(['INFO']), 'Session ' + s.title + ' with id ' + s.id + ' cancelled') - except: - self.report(set(['ERROR']), 'Could not cancel session ' + s.title + ' with id ' + s.id) + res = proxy.auth.getSessionKey(ore.username, ore.hash) + key = res['key'] + userid = res['userId'] + res = proxy.session.cancelSession(userid, key, s.id) + doRefresh(self) + self.report(set(['INFO']), 'Session ' + s.title + ' with id ' + str(s.id) + ' cancelled') + except xmlrpc.client.Error as v: + self.report(set(['ERROR']), 'Could not cancel session ' + s.title + ' with id ' + str(s.id)) + print(v) bpy.cancelError = True bpy.errorStartTime = time.time() @@ -927,7 +969,7 @@ bl_label = 'Check for a new version' def execute(self, context): - blenderproxy = xmlrpc.client.ServerProxy(r'http://xmlrpc.renderfarm.fi/blender') + blenderproxy = xmlrpc.client.ServerProxy(r'http://xmlrpc.renderfarm.fi/renderfarmfi/blender') try: self.report(set(['INFO']), 'Checking for newer version on Renderfarm.fi') dl_url = blenderproxy.blender.getCurrentVersion(bpy.CURRENT_VERSION) @@ -940,7 +982,10 @@ self.report(set(['INFO']), 'Done checking for newer version on Renderfarm.fi') except xmlrpc.client.Fault as f: print('ERROR:', f) - self.report(set(['ERROR']), 'An error occurred while checking for newer version on Renderfarm.fi') + self.report(set(['ERROR']), 'An error occurred while checking for newer version on Renderfarm.fi: ' + f.faultString) + except xmlrpc.client.ProtocolError as e: + print('ERROR:', e) + self.report(set(['ERROR']), 'An HTTP error occurred while checking for newer version on Renderfarm.fi: ' + str(e.errcode) + ' ' + e.errmsg) return {'FINISHED'} @@ -959,27 +1004,7 @@ ore.loginInserted = False try: - userproxy = xmlrpc.client.ServerProxy(r'https://xmlrpc.renderfarm.fi/user') - sessions = userproxy.user.getAllSessions(ore.username, ore.hash, 'completed') - bpy.ore_sessions = xmlSessionsToOreSessions(sessions, 'completed') - bpy.ore_completed_sessions = bpy.ore_sessions - bpy.ore_cancelled_sessions = xmlSessionsToOreSessions(sessions, 'canceled') - sessions = userproxy.user.getAllSessions(ore.username, ore.hash, 'accept') - bpy.ore_pending_sessions = xmlSessionsToOreSessions(sessions, 'accept') - sessions = userproxy.user.getAllSessions(ore.username, ore.hash, 'active') - bpy.ore_active_sessions = xmlSessionsToOreSessions(sessions, 'active') - - bpy.ore_active_session_queue = bpy.ore_completed_sessions - updateSessionList(ore.completed_sessions, ore) - - bpy.ore_active_session_queue = bpy.ore_pending_sessions - updateSessionList(ore.pending_sessions, ore) - - bpy.ore_active_session_queue = bpy.ore_active_sessions - updateSessionList(ore.active_sessions, ore) - - bpy.ore_active_session_queue = bpy.ore_cancelled_sessions - updateSessionList(ore.rejected_sessions, ore) + doRefresh(self, True) ore.passwordCorrect = True ore.loginInserted = True @@ -990,21 +1015,10 @@ ore.passwordCorrect = False ore.hash = '' ore.password = '' - self.report({'WARNING'}, "Incorrect login") + self.report({'WARNING'}, "Incorrect login: " + v.faultString) print(v) return {'CANCELLED'} - all_sessions = [] - bpy.ore_complete_session_queue = [] - - bpy.ore_complete_session_queue.extend(bpy.ore_pending_sessions) - bpy.ore_complete_session_queue.extend(bpy.ore_active_sessions) - #bpy.ore_complete_session_queue.extend(bpy.ore_completed_sessions) - #bpy.ore_complete_session_queue.extend(bpy.ore_cancelled_sessions) - - bpy.ore_active_session_queue = bpy.ore_complete_session_queue - updateSessionList(ore.all_sessions, ore) - return {'FINISHED'} class ORE_ResetOp(bpy.types.Operator): diff -Nru blender-2.61/release/scripts/addons/rigify/generate.py blender-2.62/release/scripts/addons/rigify/generate.py --- blender-2.61/release/scripts/addons/rigify/generate.py 2011-12-13 19:59:00.000000000 +0000 +++ blender-2.62/release/scripts/addons/rigify/generate.py 2012-02-15 19:43:25.000000000 +0000 @@ -16,6 +16,8 @@ # #======================= END GPL LICENSE BLOCK ======================== +# + import bpy import re import time @@ -166,7 +168,7 @@ getattr(bone.rigify_parameters[0], prop)) except AttributeError: print("FAILED TO COPY PARAMETER: " + str(prop)) - + # Custom properties for prop in bone.keys(): try: diff -Nru blender-2.61/release/scripts/addons/rigify/__init__.py blender-2.62/release/scripts/addons/rigify/__init__.py --- blender-2.61/release/scripts/addons/rigify/__init__.py 2011-12-13 19:59:00.000000000 +0000 +++ blender-2.62/release/scripts/addons/rigify/__init__.py 2012-02-15 19:43:25.000000000 +0000 @@ -16,18 +16,19 @@ # #======================= END GPL LICENSE BLOCK ======================== +# + bl_info = { "name": "Rigify", "author": "Nathan Vegdahl", "blender": (2, 5, 7), - "api": 35622, "location": "View3D > Add > Armature", "description": "Adds various Rig Templates", "location": "Armature properties", - "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\ - "Scripts/Rigging/Rigify", - "tracker_url": "http://projects.blender.org/tracker/index.php?"\ - "func=detail&aid=25546", + "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/" + "Scripts/Rigging/Rigify", + "tracker_url": "http://projects.blender.org/tracker/index.php?" + "func=detail&aid=25546", "category": "Rigging"} diff -Nru blender-2.61/release/scripts/addons/rigify/metarig_menu.py blender-2.62/release/scripts/addons/rigify/metarig_menu.py --- blender-2.61/release/scripts/addons/rigify/metarig_menu.py 2011-12-13 19:59:00.000000000 +0000 +++ blender-2.62/release/scripts/addons/rigify/metarig_menu.py 2012-02-15 19:43:25.000000000 +0000 @@ -16,6 +16,8 @@ # # ##### END GPL LICENSE BLOCK ##### +# + import bpy from rigify.metarigs import human @@ -53,4 +55,3 @@ bpy.utils.unregister_class(AddHuman) bpy.types.INFO_MT_armature_add.remove(menu_func) - diff -Nru blender-2.61/release/scripts/addons/rigify/metarigs/human.py blender-2.62/release/scripts/addons/rigify/metarigs/human.py --- blender-2.61/release/scripts/addons/rigify/metarigs/human.py 2011-12-13 19:59:00.000000000 +0000 +++ blender-2.62/release/scripts/addons/rigify/metarigs/human.py 2012-02-15 19:43:25.000000000 +0000 @@ -16,6 +16,8 @@ # # ##### END GPL LICENSE BLOCK ##### +# + import bpy @@ -1146,4 +1148,3 @@ arm.edit_bones.active = bone arm.layers = [(x in [0, 2, 4, 6, 8, 10, 12]) for x in range(0, 32)] - diff -Nru blender-2.61/release/scripts/addons/rigify/rigs/basic/copy_chain.py blender-2.62/release/scripts/addons/rigify/rigs/basic/copy_chain.py --- blender-2.61/release/scripts/addons/rigify/rigs/basic/copy_chain.py 2011-12-13 19:58:56.000000000 +0000 +++ blender-2.62/release/scripts/addons/rigify/rigs/basic/copy_chain.py 2012-02-15 19:43:22.000000000 +0000 @@ -16,6 +16,8 @@ # #======================= END GPL LICENSE BLOCK ======================== +# + import bpy from rigify.utils import MetarigError from rigify.utils import copy_bone @@ -127,7 +129,6 @@ group.make_controls = bpy.props.BoolProperty(name="Controls", default=True, description="Create control bones for the copy") group.make_deforms = bpy.props.BoolProperty(name="Deform", default=True, description="Create deform bones for the copy") - @classmethod def parameters_ui(self, layout, obj, bone): """ Create the ui for the rig parameters. @@ -206,5 +207,3 @@ bone.select_head = True bone.select_tail = True arm.edit_bones.active = bone - - diff -Nru blender-2.61/release/scripts/addons/rigify/rigs/basic/copy.py blender-2.62/release/scripts/addons/rigify/rigs/basic/copy.py --- blender-2.61/release/scripts/addons/rigify/rigs/basic/copy.py 2011-12-13 19:58:56.000000000 +0000 +++ blender-2.62/release/scripts/addons/rigify/rigs/basic/copy.py 2012-02-15 19:43:22.000000000 +0000 @@ -16,6 +16,8 @@ # #======================= END GPL LICENSE BLOCK ======================== +# + import bpy from rigify.utils import copy_bone from rigify.utils import strip_org, make_deformer_name @@ -88,7 +90,6 @@ group.make_control = bpy.props.BoolProperty(name="Control", default=True, description="Create a control bone for the copy") group.make_deform = bpy.props.BoolProperty(name="Deform", default=True, description="Create a deform bone for the copy") - @classmethod def parameters_ui(self, layout, obj, bone): """ Create the ui for the rig parameters. @@ -139,4 +140,3 @@ bone.select_head = True bone.select_tail = True arm.edit_bones.active = bone - diff -Nru blender-2.61/release/scripts/addons/rigify/rigs/biped/arm/deform.py blender-2.62/release/scripts/addons/rigify/rigs/biped/arm/deform.py --- blender-2.61/release/scripts/addons/rigify/rigs/biped/arm/deform.py 2011-12-13 19:58:57.000000000 +0000 +++ blender-2.62/release/scripts/addons/rigify/rigs/biped/arm/deform.py 2012-02-15 19:43:23.000000000 +0000 @@ -16,6 +16,8 @@ # #======================= END GPL LICENSE BLOCK ======================== +# + import bpy from math import acos from mathutils import Vector, Matrix @@ -227,4 +229,3 @@ con.name = "track_to" con.target = self.obj con.subtarget = ftip - diff -Nru blender-2.61/release/scripts/addons/rigify/rigs/biped/arm/fk.py blender-2.62/release/scripts/addons/rigify/rigs/biped/arm/fk.py --- blender-2.61/release/scripts/addons/rigify/rigs/biped/arm/fk.py 2011-12-13 19:58:57.000000000 +0000 +++ blender-2.62/release/scripts/addons/rigify/rigs/biped/arm/fk.py 2012-02-15 19:43:23.000000000 +0000 @@ -16,6 +16,8 @@ # #======================= END GPL LICENSE BLOCK ======================== +# + import bpy from rigify.utils import MetarigError from rigify.utils import copy_bone @@ -213,4 +215,3 @@ mod.levels = 2 return [uarm, farm, hand] - diff -Nru blender-2.61/release/scripts/addons/rigify/rigs/biped/arm/ik.py blender-2.62/release/scripts/addons/rigify/rigs/biped/arm/ik.py --- blender-2.61/release/scripts/addons/rigify/rigs/biped/arm/ik.py 2011-12-13 19:58:57.000000000 +0000 +++ blender-2.62/release/scripts/addons/rigify/rigs/biped/arm/ik.py 2012-02-15 19:43:23.000000000 +0000 @@ -16,6 +16,8 @@ # #======================= END GPL LICENSE BLOCK ======================== +# + import bpy from mathutils import Vector from math import pi, acos @@ -335,4 +337,3 @@ mod.levels = 2 return [uarm, farm, hand, pole] - diff -Nru blender-2.61/release/scripts/addons/rigify/rigs/biped/arm/__init__.py blender-2.62/release/scripts/addons/rigify/rigs/biped/arm/__init__.py --- blender-2.61/release/scripts/addons/rigify/rigs/biped/arm/__init__.py 2011-12-13 19:58:57.000000000 +0000 +++ blender-2.62/release/scripts/addons/rigify/rigs/biped/arm/__init__.py 2012-02-15 19:43:23.000000000 +0000 @@ -16,6 +16,8 @@ # #======================= END GPL LICENSE BLOCK ======================== +# + import bpy import imp from . import fk, ik, deform @@ -36,21 +38,21 @@ except KeyError: pass if is_selected(fk_arm+ik_arm): - p = layout.operator("pose.rigify_arm_fk2ik_" + rig_id, text="Snap FK->IK (" + fk_arm[0] + ")") - p.uarm_fk = fk_arm[0] - p.farm_fk = fk_arm[1] - p.hand_fk = fk_arm[2] - p.uarm_ik = ik_arm[0] - p.farm_ik = ik_arm[1] - p.hand_ik = ik_arm[2] - p = layout.operator("pose.rigify_arm_ik2fk_" + rig_id, text="Snap IK->FK (" + fk_arm[0] + ")") - p.uarm_fk = fk_arm[0] - p.farm_fk = fk_arm[1] - p.hand_fk = fk_arm[2] - p.uarm_ik = ik_arm[0] - p.farm_ik = ik_arm[1] - p.hand_ik = ik_arm[2] - p.pole = ik_arm[3] + props = layout.operator("pose.rigify_arm_fk2ik_" + rig_id, text="Snap FK->IK (" + fk_arm[0] + ")") + props.uarm_fk = fk_arm[0] + props.farm_fk = fk_arm[1] + props.hand_fk = fk_arm[2] + props.uarm_ik = ik_arm[0] + props.farm_ik = ik_arm[1] + props.hand_ik = ik_arm[2] + props = layout.operator("pose.rigify_arm_ik2fk_" + rig_id, text="Snap IK->FK (" + fk_arm[0] + ")") + props.uarm_fk = fk_arm[0] + props.farm_fk = fk_arm[1] + props.hand_fk = fk_arm[2] + props.uarm_ik = ik_arm[0] + props.farm_ik = ik_arm[1] + props.hand_ik = ik_arm[2] + props.pole = ik_arm[3] """ @@ -231,4 +233,3 @@ bone.select_head = True bone.select_tail = True arm.edit_bones.active = bone - diff -Nru blender-2.61/release/scripts/addons/rigify/rigs/biped/leg/deform.py blender-2.62/release/scripts/addons/rigify/rigs/biped/leg/deform.py --- blender-2.61/release/scripts/addons/rigify/rigs/biped/leg/deform.py 2011-12-13 19:58:58.000000000 +0000 +++ blender-2.62/release/scripts/addons/rigify/rigs/biped/leg/deform.py 2012-02-15 19:43:24.000000000 +0000 @@ -16,6 +16,8 @@ # #======================= END GPL LICENSE BLOCK ======================== +# + import bpy from math import acos from mathutils import Vector, Matrix diff -Nru blender-2.61/release/scripts/addons/rigify/rigs/biped/leg/fk.py blender-2.62/release/scripts/addons/rigify/rigs/biped/leg/fk.py --- blender-2.61/release/scripts/addons/rigify/rigs/biped/leg/fk.py 2011-12-13 19:58:58.000000000 +0000 +++ blender-2.62/release/scripts/addons/rigify/rigs/biped/leg/fk.py 2012-02-15 19:43:24.000000000 +0000 @@ -16,6 +16,8 @@ # #======================= END GPL LICENSE BLOCK ======================== +# + import bpy from mathutils import Vector from rigify.utils import MetarigError @@ -251,4 +253,3 @@ mod.levels = 2 return [thigh, shin, foot, foot_mch] - diff -Nru blender-2.61/release/scripts/addons/rigify/rigs/biped/leg/ik.py blender-2.62/release/scripts/addons/rigify/rigs/biped/leg/ik.py --- blender-2.61/release/scripts/addons/rigify/rigs/biped/leg/ik.py 2011-12-13 19:58:58.000000000 +0000 +++ blender-2.62/release/scripts/addons/rigify/rigs/biped/leg/ik.py 2012-02-15 19:43:24.000000000 +0000 @@ -16,6 +16,8 @@ # #======================= END GPL LICENSE BLOCK ======================== +# + import bpy from mathutils import Vector from math import pi, acos @@ -604,4 +606,3 @@ mod.levels = 2 return [thigh, shin, foot, pole, foot_roll, foot_ik_target] - diff -Nru blender-2.61/release/scripts/addons/rigify/rigs/biped/leg/__init__.py blender-2.62/release/scripts/addons/rigify/rigs/biped/leg/__init__.py --- blender-2.61/release/scripts/addons/rigify/rigs/biped/leg/__init__.py 2011-12-13 19:58:58.000000000 +0000 +++ blender-2.62/release/scripts/addons/rigify/rigs/biped/leg/__init__.py 2012-02-15 19:43:24.000000000 +0000 @@ -16,6 +16,8 @@ # #======================= END GPL LICENSE BLOCK ======================== +# + import bpy import imp from . import fk, ik, deform @@ -268,4 +270,3 @@ bone.select_head = True bone.select_tail = True arm.edit_bones.active = bone - diff -Nru blender-2.61/release/scripts/addons/rigify/rigs/finger.py blender-2.62/release/scripts/addons/rigify/rigs/finger.py --- blender-2.61/release/scripts/addons/rigify/rigs/finger.py 2011-12-13 19:58:59.000000000 +0000 +++ blender-2.62/release/scripts/addons/rigify/rigs/finger.py 2012-02-15 19:43:24.000000000 +0000 @@ -16,6 +16,8 @@ # #======================= END GPL LICENSE BLOCK ======================== +# + import bpy from mathutils import Vector from rigify.utils import MetarigError @@ -408,4 +410,3 @@ bone.select_head = True bone.select_tail = True arm.edit_bones.active = bone - diff -Nru blender-2.61/release/scripts/addons/rigify/rigs/misc/delta.py blender-2.62/release/scripts/addons/rigify/rigs/misc/delta.py --- blender-2.61/release/scripts/addons/rigify/rigs/misc/delta.py 2011-12-13 19:58:59.000000000 +0000 +++ blender-2.62/release/scripts/addons/rigify/rigs/misc/delta.py 2012-02-15 19:43:24.000000000 +0000 @@ -16,6 +16,8 @@ # #======================= END GPL LICENSE BLOCK ======================== +# + import bpy from math import acos from rigify.utils import MetarigError @@ -158,4 +160,3 @@ a.roll = roll_1 else: a.roll = roll_2 - diff -Nru blender-2.61/release/scripts/addons/rigify/rigs/neck_short.py blender-2.62/release/scripts/addons/rigify/rigs/neck_short.py --- blender-2.61/release/scripts/addons/rigify/rigs/neck_short.py 2011-12-13 19:58:59.000000000 +0000 +++ blender-2.62/release/scripts/addons/rigify/rigs/neck_short.py 2012-02-15 19:43:24.000000000 +0000 @@ -16,6 +16,8 @@ # #======================= END GPL LICENSE BLOCK ======================== +# + import bpy from rigify.utils import MetarigError from rigify.utils import copy_bone, new_bone, put_bone @@ -388,4 +390,3 @@ bone.select_head = True bone.select_tail = True arm.edit_bones.active = bone - diff -Nru blender-2.61/release/scripts/addons/rigify/rigs/palm.py blender-2.62/release/scripts/addons/rigify/rigs/palm.py --- blender-2.61/release/scripts/addons/rigify/rigs/palm.py 2011-12-13 19:58:59.000000000 +0000 +++ blender-2.62/release/scripts/addons/rigify/rigs/palm.py 2012-02-15 19:43:24.000000000 +0000 @@ -16,6 +16,8 @@ # #======================= END GPL LICENSE BLOCK ======================== +# + import bpy from math import cos, pi from rigify.utils import MetarigError @@ -270,4 +272,3 @@ bone.select_head = True bone.select_tail = True arm.edit_bones.active = bone - diff -Nru blender-2.61/release/scripts/addons/rigify/rigs/spine.py blender-2.62/release/scripts/addons/rigify/rigs/spine.py --- blender-2.61/release/scripts/addons/rigify/rigs/spine.py 2011-12-13 19:58:59.000000000 +0000 +++ blender-2.62/release/scripts/addons/rigify/rigs/spine.py 2012-02-15 19:43:24.000000000 +0000 @@ -16,6 +16,8 @@ # #======================= END GPL LICENSE BLOCK ======================== +# + """ TODO: - Add parameters for bone transform alphas. """ @@ -71,8 +73,8 @@ self.control_indices.sort() self.pivot_rest = self.params.rest_pivot_slide - self.pivot_rest = max(self.pivot_rest, 1.0/len(self.org_bones)) - self.pivot_rest = min(self.pivot_rest, 1.0-(1.0/len(self.org_bones))) + self.pivot_rest = max(self.pivot_rest, 1.0 / len(self.org_bones)) + self.pivot_rest = min(self.pivot_rest, 1.0 - (1.0 / len(self.org_bones))) if len(self.org_bones) <= 1: raise MetarigError("RIGIFY ERROR: Bone '%s': input to rig type must be a chain of 2 or more bones" % (strip_org(bone_name))) @@ -532,7 +534,6 @@ group.rest_pivot_slide = bpy.props.FloatProperty(name="Rest Pivot Slide", default=0.0, min=0.0, max=1.0, soft_min=0.0, soft_max=1.0, description="The pivot slide value in the rest pose") group.chain_bone_controls = bpy.props.StringProperty(name="Control bone list", default="", description="Define which bones have controls") - @classmethod def parameters_ui(self, layout, obj, bone): """ Create the ui for the rig parameters. diff -Nru blender-2.61/release/scripts/addons/rigify/rig_ui_template.py blender-2.62/release/scripts/addons/rigify/rig_ui_template.py --- blender-2.61/release/scripts/addons/rigify/rig_ui_template.py 2011-12-13 19:59:00.000000000 +0000 +++ blender-2.62/release/scripts/addons/rigify/rig_ui_template.py 2012-02-15 19:43:25.000000000 +0000 @@ -16,6 +16,8 @@ # #======================= END GPL LICENSE BLOCK ======================== +# + UI_SLIDERS = ''' import bpy from mathutils import Matrix, Vector @@ -52,9 +54,7 @@ # Compensate for non-local location #if not pose_bone.bone.use_local_location: # loc = smat.to_translation() * (par_rest.inverted() * rest).to_quaternion() - # smat[3][0] = loc[0] - # smat[3][1] = loc[1] - # smat[3][2] = loc[2] + # smat.translation = loc return smat @@ -543,7 +543,6 @@ code += "\n row = col.row()\n" code += " row.prop(context.active_object.data, 'layers', index=28, toggle=True, text='Root')\n" - return code @@ -567,4 +566,3 @@ register() ''' - diff -Nru blender-2.61/release/scripts/addons/rigify/ui.py blender-2.62/release/scripts/addons/rigify/ui.py --- blender-2.61/release/scripts/addons/rigify/ui.py 2011-12-13 19:59:00.000000000 +0000 +++ blender-2.62/release/scripts/addons/rigify/ui.py 2012-02-15 19:43:25.000000000 +0000 @@ -16,8 +16,10 @@ # #======================= END GPL LICENSE BLOCK ======================== +# + import bpy -from bpy.props import * +from bpy.props import StringProperty import rigify from rigify.utils import get_rig_type from rigify import generate @@ -36,7 +38,7 @@ return False #obj = context.object #if obj: - # return (obj.mode in ('POSE', 'OBJECT', 'EDIT')) + # return (obj.mode in {'POSE', 'OBJECT', 'EDIT'}) #return False return True @@ -131,7 +133,7 @@ return False obj = context.object if obj: - return (obj.mode in ('POSE')) + return obj.mode == 'POSE' return False def draw(self, context): @@ -188,19 +190,19 @@ rig.Rig.parameters_ui(box, C.active_object, bone.name) -#class INFO_MT_armature_metarig_add(bpy.types.Menu): -# bl_idname = "INFO_MT_armature_metarig_add" -# bl_label = "Meta-Rig" - -# def draw(self, context): - #import rigify - - #layout = self.layout - #layout.operator_context = 'INVOKE_REGION_WIN' - - #for submodule_type in rigify.get_submodule_types(): - # text = bpy.path.display_name(submodule_type) - # layout.operator("pose.metarig_sample_add", text=text, icon='OUTLINER_OB_ARMATURE').metarig_type = submodule_type +#~ class INFO_MT_armature_metarig_add(bpy.types.Menu): + #~ bl_idname = "INFO_MT_armature_metarig_add" + #~ bl_label = "Meta-Rig" + + #~ def draw(self, context): + #~ import rigify + + #~ layout = self.layout + #~ layout.operator_context = 'INVOKE_REGION_WIN' + + #~ for submodule_type in rigify.get_submodule_types(): + #~ text = bpy.path.display_name(submodule_type) + #~ layout.operator("pose.metarig_sample_add", text=text, icon='OUTLINER_OB_ARMATURE').metarig_type = submodule_type def rigify_report_exception(operator, exception): @@ -249,13 +251,17 @@ class Sample(bpy.types.Operator): - '''Create a sample metarig to be modified before generating the final rig.''' + '''Create a sample metarig to be modified before generating the final rig''' bl_idname = "armature.metarig_sample_add" bl_label = "Add a sample metarig for a rig type" bl_options = {'UNDO'} - metarig_type = StringProperty(name="Type", description="Name of the rig type to generate a sample of", maxlen=128, default="") + metarig_type = StringProperty( + name="Type", + description="Name of the rig type to generate a sample of", + maxlen=128, + ) def execute(self, context): if context.mode == 'EDIT_ARMATURE' and self.metarig_type != "": diff -Nru blender-2.61/release/scripts/addons/rigify/utils.py blender-2.62/release/scripts/addons/rigify/utils.py --- blender-2.61/release/scripts/addons/rigify/utils.py 2011-12-13 19:59:00.000000000 +0000 +++ blender-2.62/release/scripts/addons/rigify/utils.py 2012-02-15 19:43:25.000000000 +0000 @@ -16,6 +16,8 @@ # #======================= END GPL LICENSE BLOCK ======================== +# + import bpy import imp import random @@ -358,6 +360,7 @@ mesh.from_pydata(verts, edges, []) mesh.update() + def create_root_widget(rig, bone_name): """ Creates a widget for the root bone. """ @@ -536,7 +539,7 @@ return "\n".join(code) -def random_id(length = 8): +def random_id(length=8): """ Generates a random alphanumeric id string. """ tlength = int(length / 2) @@ -548,4 +551,3 @@ text += random.choice(chars) text += str(hex(int(time.time())))[2:][-tlength:].rjust(tlength, '0')[::-1] return text - diff -Nru blender-2.61/release/scripts/addons/space_view3d_3d_navigation.py blender-2.62/release/scripts/addons/space_view3d_3d_navigation.py --- blender-2.61/release/scripts/addons/space_view3d_3d_navigation.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/space_view3d_3d_navigation.py 2012-02-15 19:43:32.000000000 +0000 @@ -26,7 +26,6 @@ "author": "Demohero, uriel", "version": (1, 2), "blender": (2, 5, 7), - "api": 35853, "location": "View3D > Tool Shelf > 3D Nav", "description": "Navigate the Camera & 3D View from the Toolshelf", "warning": "", diff -Nru blender-2.61/release/scripts/addons/space_view3d_copy_attributes.py blender-2.62/release/scripts/addons/space_view3d_copy_attributes.py --- blender-2.61/release/scripts/addons/space_view3d_copy_attributes.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/space_view3d_copy_attributes.py 2012-02-15 19:43:32.000000000 +0000 @@ -21,15 +21,14 @@ bl_info = { 'name': 'Copy Attributes Menu', 'author': 'Bassam Kurdali, Fabian Fricke, wiseman303', - 'version': (0, 4, 4), - "blender": (2, 5, 7), - "api": 36695, + 'version': (0, 4, 6), + "blender": (2, 6, 1), 'location': 'View3D > Ctrl-C', 'description': 'Copy Attributes Menu from Blender 2.4', - 'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.5/Py/'\ - 'Scripts/3D_interaction/Copy_Attributes_Menu', - 'tracker_url': 'https://projects.blender.org/tracker/index.php?'\ - 'func=detail&aid=22588', + 'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.5/Py/' + 'Scripts/3D_interaction/Copy_Attributes_Menu', + 'tracker_url': 'https://projects.blender.org/tracker/index.php?' + 'func=detail&aid=22588', 'category': '3D View'} import bpy @@ -92,22 +91,16 @@ '''Helper function for visual transform copy, gets the active transform in bone space ''' - data_bone = context.active_object.data.bones[bone.name] + obj_act = context.active_object + data_bone = obj_act.data.bones[bone.name] #all matrices are in armature space unless commented otherwise otherloc = active.matrix # final 4x4 mat of target, location. - bonemat_local = Matrix(data_bone.matrix_local) # self rest matrix + bonemat_local = data_bone.matrix_local.copy() # self rest matrix if data_bone.parent: - parentposemat = Matrix( - context.active_object.pose.bones[data_bone.parent.name].matrix) - parentbonemat = Matrix(data_bone.parent.matrix_local) + parentposemat = obj_act.pose.bones[data_bone.parent.name].matrix.copy() + parentbonemat = data_bone.parent.matrix_local.copy() else: - parentposemat = bonemat_local.copy() - parentbonemat = bonemat_local.copy() - - # FIXME! why copy from the parent if setting identity ?, Campbell - parentposemat.identity() - parentbonemat.identity() - + parentposemat = parentbonemat = Matrix() if parentbonemat == parentposemat or ignoreparent: newmat = bonemat_local.inverted() * otherloc else: @@ -123,8 +116,7 @@ item.rotation_quaternion = mat.to_3x3().to_quaternion() elif item.rotation_mode == 'AXIS_ANGLE': quat = mat.to_3x3().to_quaternion() - item.rotation_axis_angle = Vector([quat.axis[0], - quat.axis[1], quat.axis[2], quat.angle]) + item.rotation_axis_angle = quat.axis[:] + (quat.angle, ) else: item.rotation_euler = mat.to_3x3().to_euler(item.rotation_mode) @@ -365,8 +357,7 @@ ob.lock_location[index] = state for index, state in enumerate(active.lock_rotation): ob.lock_rotation[index] = state - for index, state in enumerate(active.lock_rotations_4d): - ob.lock_rotations_4d[index] = state + ob.lock_rotations_4d = active.lock_rotations_4d ob.lock_rotation_w = active.lock_rotation_w for index, state in enumerate(active.lock_scale): ob.lock_scale[index] = state @@ -408,6 +399,13 @@ return('INFO', "modifiers copied") +def obGrp(ob, active, context): + for grp in bpy.data.groups: + if active.name in grp.objects and ob.name not in grp.objects: + grp.objects.link(ob) + return('INFO', "groups copied") + + def obWei(ob, active, context): me_source = active.data me_target = ob.data @@ -453,18 +451,19 @@ vgroupIndex_weight[i][1], "REPLACE") return('INFO', "weights copied") -object_copies = (('obj_loc', "Location", - "Copy Location from Active to Selected", obLoc), - ('obj_rot', "Rotation", - "Copy Rotation from Active to Selected", obRot), - ('obj_sca', "Scale", - "Copy Scale from Active to Selected", obSca), - ('obj_vis_loc', "Visual Location", - "Copy Visual Location from Active to Selected", obVisLoc), - ('obj_vis_rot', "Visual Rotation", - "Copy Visual Rotation from Active to Selected", obVisRot), - ('obj_vis_sca', "Visual Scale", - "Copy Visual Scale from Active to Selected", obVisSca), +object_copies = ( + #('obj_loc', "Location", + #"Copy Location from Active to Selected", obLoc), + #('obj_rot', "Rotation", + #"Copy Rotation from Active to Selected", obRot), + #('obj_sca', "Scale", + #"Copy Scale from Active to Selected", obSca), + ('obj_vis_loc', "Location", + "Copy Location from Active to Selected", obVisLoc), + ('obj_vis_rot', "Rotation", + "Copy Rotation from Active to Selected", obVisRot), + ('obj_vis_sca', "Scale", + "Copy Scale from Active to Selected", obVisSca), ('obj_drw', "Draw Options", "Copy Draw Options from Active to Selected", obDrw), ('obj_ofs', "Time Offset", @@ -500,7 +499,9 @@ ('obj_mod', "Modifiers", "Copy Modifiers from Active to Selected", obMod), ('obj_wei', "Vertex Weights", - "Copy vertex weights based on indices", obWei)) + "Copy vertex weights based on indices", obWei), + ('obj_grp', "Group Links", + "Copy selected into active object's groups", obGrp)) @classmethod @@ -737,49 +738,52 @@ ''' mostly to get the keymap working ''' kc = bpy.context.window_manager.keyconfigs.addon - km = kc.keymaps.new(name="Object Mode") - kmi = km.keymap_items.new('wm.call_menu', 'C', 'PRESS', ctrl=True) - kmi.properties.name = 'VIEW3D_MT_copypopup' - - km = kc.keymaps.new(name="Pose") - kmi = km.keymap_items.get("pose.copy") - if kmi is not None: - kmi.idname = 'wm.call_menu' - else: + if kc: + km = kc.keymaps.new(name="Object Mode") kmi = km.keymap_items.new('wm.call_menu', 'C', 'PRESS', ctrl=True) - kmi.properties.name = 'VIEW3D_MT_posecopypopup' - for menu in _layer_menus: - bpy.utils.register_class(menu) - - km = kc.keymaps.new(name="Mesh") - kmi = km.keymap_items.new('wm.call_menu', 'C', 'PRESS') - kmi.ctrl = True - kmi.properties.name = 'MESH_MT_CopyFaceSettings' + kmi.properties.name = 'VIEW3D_MT_copypopup' + + km = kc.keymaps.new(name="Pose") + kmi = km.keymap_items.get("pose.copy") + if kmi is not None: + kmi.idname = 'wm.call_menu' + else: + kmi = km.keymap_items.new('wm.call_menu', 'C', 'PRESS', ctrl=True) + kmi.properties.name = 'VIEW3D_MT_posecopypopup' + for menu in _layer_menus: + bpy.utils.register_class(menu) + + km = kc.keymaps.new(name="Mesh") + kmi = km.keymap_items.new('wm.call_menu', 'C', 'PRESS') + kmi.ctrl = True + kmi.properties.name = 'MESH_MT_CopyFaceSettings' def unregister(): bpy.utils.unregister_module(__name__) ''' mostly to remove the keymap ''' - kms = bpy.context.window_manager.keyconfigs.addon.keymaps['Pose'] - for item in kms.keymap_items: - if item.name == 'Call Menu' and item.idname == 'wm.call_menu' and \ - item.properties.name == 'VIEW3D_MT_posecopypopup': - item.idname = 'pose.copy' - break - for menu in _layer_menus: - bpy.utils.unregister_class(menu) - km = bpy.context.window_manager.keyconfigs.addon.keymaps['Mesh'] - for kmi in km.keymap_items: - if kmi.idname == 'wm.call_menu': - if kmi.properties.name == 'MESH_MT_CopyFaceSettings': - km.keymap_items.remove(kmi) - - km = bpy.context.window_manager.keyconfigs.addon.keymaps['Object Mode'] - for kmi in km.keymap_items: - if kmi.idname == 'wm.call_menu': - if kmi.properties.name == 'VIEW3D_MT_copypopup': - km.keymap_items.remove(kmi) + kc = bpy.context.window_manager.keyconfigs.addon + if kc: + kms = kc.keymaps['Pose'] + for item in kms.keymap_items: + if item.name == 'Call Menu' and item.idname == 'wm.call_menu' and \ + item.properties.name == 'VIEW3D_MT_posecopypopup': + item.idname = 'pose.copy' + break + for menu in _layer_menus: + bpy.utils.unregister_class(menu) + km = kc.keymaps['Mesh'] + for kmi in km.keymap_items: + if kmi.idname == 'wm.call_menu': + if kmi.properties.name == 'MESH_MT_CopyFaceSettings': + km.keymap_items.remove(kmi) + + km = kc.addon.keymaps['Object Mode'] + for kmi in km.keymap_items: + if kmi.idname == 'wm.call_menu': + if kmi.properties.name == 'VIEW3D_MT_copypopup': + km.keymap_items.remove(kmi) if __name__ == "__main__": register() diff -Nru blender-2.61/release/scripts/addons/space_view3d_materials_utils.py blender-2.62/release/scripts/addons/space_view3d_materials_utils.py --- blender-2.61/release/scripts/addons/space_view3d_materials_utils.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/space_view3d_materials_utils.py 2012-02-15 19:43:32.000000000 +0000 @@ -27,38 +27,45 @@ "author": "michaelw", "version": (1, 3), "blender": (2, 5, 6), - "api": 35324, "location": "View3D > Q key", - "description": "Menu of material tools (assign, select by etc) in the 3D View", + "description": "Menu of material tools (assign, select..) in the 3D View", "warning": "", - "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\ - "Scripts/3D interaction/Materials Utils", - "tracker_url": "https://projects.blender.org/tracker/index.php?"\ - "func=detail&aid=22140", + "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/" + "Scripts/3D interaction/Materials Utils", + "tracker_url": "https://projects.blender.org/tracker/index.php?" + "func=detail&aid=22140", "category": "3D View"} """ This script has several functions and operators... grouped for convenience * assign material: - offers the user a list of ALL the materials in the blend file and an additional "new" entry - the chosen material will be assigned to all the selected objects in object mode. - + offers the user a list of ALL the materials in the blend file and an + additional "new" entry the chosen material will be assigned to all the + selected objects in object mode. + in edit mode the selected faces get the selected material applied. - if the user chose "new" the new material can be renamed using the "last operator" section of the toolbox - After assigning the material "clean material slots" and "material to texface" are auto run to keep things tidy (see description bellow) + if the user chose "new" the new material can be renamed using the + "last operator" section of the toolbox. + After assigning the material "clean material slots" and + "material to texface" are auto run to keep things tidy + (see description bellow) * select by material - in object mode this offers the user a menu of all materials in the blend file - any objects using the selected material will become selected, any objects without the material will be removed from selection. - - in edit mode: the menu offers only the materials attached to the current object. It will select the faces that use the material and deselect those that do not. + in object mode this offers the user a menu of all materials in the blend + file any objects using the selected material will become selected, any + objects without the material will be removed from selection. + + in edit mode: the menu offers only the materials attached to the current + object. It will select the faces that use the material and deselect those + that do not. * clean material slots - for all selected objects any empty material slots or material slots with materials that are not used by the mesh faces will be removed. + for all selected objects any empty material slots or material slots with + materials that are not used by the mesh faces will be removed. -* Any un-used materials and slots will be removed +* Any un-used materials and slots will be removed """ @@ -66,92 +73,92 @@ from bpy.props import* -def replace_material(m1 , m2, all_objects = False): - #replace material named m1 with material named m2 - #m1 is the name of original material - #m2 is the name of the material to replace it with - #'all' will replace throughout the blend file - try: - matorg = bpy.data.materials[m1] - matrep = bpy.data.materials[m2] - - +def replace_material(m1, m2, all_objects=False): + # replace material named m1 with material named m2 + # m1 is the name of original material + # m2 is the name of the material to replace it with + # 'all' will replace throughout the blend file + + matorg = bpy.data.materials.get(m1) + matrep = bpy.data.materials.get(m2) + + if matorg and matrep: #store active object scn = bpy.context.scene ob_active = bpy.context.active_object - + if all_objects: objs = bpy.data.objects - + else: objs = bpy.context.selected_editable_objects - + for ob in objs: if ob.type == 'MESH': scn.objects.active = ob - print(ob.name) - ms = ob.material_slots.values() - - for m in ms: + + for m in ob.material_slots.values(): if m.material == matorg: m.material = matrep - #don't break the loop as the material can be + # don't break the loop as the material can be # ref'd more than once - - #restore active object - scn.objects.active = ob_active - except: + + else: print('no match to replace') -def select_material_by_name(find_mat): - #in object mode selects all objects with material find_mat - #in edit mode selects all faces with material find_mat - + +def select_material_by_name(find_mat_name): + #in object mode selects all objects with material find_mat_name + #in edit mode selects all faces with material find_mat_name + + find_mat = bpy.data.materials.get(find_mat_name) + + if find_mat is None: + return + #check for editmode editmode = False scn = bpy.context.scene - + #set selection mode to faces - scn.tool_settings.mesh_select_mode =[False,False,True] - + scn.tool_settings.mesh_select_mode = False, False, True + actob = bpy.context.active_object if actob.mode == 'EDIT': - editmode =True + editmode = True bpy.ops.object.mode_set() - - + if not editmode: - objs = bpy.data.objects + objs = bpy.data.objects for ob in objs: - typ = ['MESH','CURVE', 'SURFACE', 'FONT', 'META'] - if ob.type in typ: + if ob.type in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META'}: ms = ob.material_slots.values() for m in ms: - if m.material.name == find_mat: + if m.material == find_mat: ob.select = True - #the active object may not have the mat! - #set it to one that does! + # the active object may not have the mat! + # set it to one that does! scn.objects.active = ob break else: ob.select = False - - #deselect non-meshes + + #deselect non-meshes else: ob.select = False - + else: #it's editmode, so select the faces ob = actob ms = ob.material_slots.values() - + #same material can be on multiple slots - slot_indeces =[] + slot_indeces = [] i = 0 # found = False # UNUSED for m in ms: - if m.material.name == find_mat: + if m.material == find_mat: slot_indeces.append(i) # found = True # UNUSED i += 1 @@ -161,29 +168,30 @@ f.select = True else: f.select = False - me.update() + me.update() if editmode: - bpy.ops.object.mode_set(mode = 'EDIT') + bpy.ops.object.mode_set(mode='EDIT') + def mat_to_texface(): - #assigns the first image in each material to the faces in the active uvlayer - #for all selected objects - + # assigns the first image in each material to the faces in the active + # uvlayer for all selected objects + #check for editmode editmode = False - + actob = bpy.context.active_object if actob.mode == 'EDIT': - editmode =True + editmode = True bpy.ops.object.mode_set() - + for ob in bpy.context.selected_editable_objects: if ob.type == 'MESH': #get the materials from slots ms = ob.material_slots.values() - + #build a list of images, one per material - images=[] + images = [] #get the textures from the mats for m in ms: gotimage = False @@ -195,17 +203,16 @@ if tex.type == 'IMAGE': img = tex.image images.append(img) - gotimage =True + gotimage = True break - + if not gotimage: print('noimage on', m.name) images.append(None) - - #now we have the images - #applythem to the uvlayer - - + + # now we have the images + # applythem to the uvlayer + me = ob.data #got uvs? if not me.uv_textures: @@ -213,7 +220,7 @@ scn.objects.active = ob bpy.ops.mesh.uv_texture_add() scn.objects.active = actob - + #get active uvlayer for t in me.uv_textures: if t.active: @@ -224,14 +231,12 @@ uvtex[f.index].image = images[f.material_index] else: uvtex[f.index].image = None - + me.update() - - + if editmode: - bpy.ops.object.mode_set(mode = 'EDIT') - - + bpy.ops.object.mode_set(mode='EDIT') + def assignmatslots(ob, matlist): #given an object and a list of material names @@ -246,15 +251,14 @@ for s in ob.material_slots: bpy.ops.object.material_slot_remove() - - #re-add them and assign material + # re-add them and assign material i = 0 for m in matlist: mat = bpy.data.materials[m] ob.data.materials.append(mat) i += 1 - #restore active object: + # restore active object: scn.objects.active = ob_active @@ -263,52 +267,49 @@ editmode = False actob = bpy.context.active_object if actob.mode == 'EDIT': - editmode =True + editmode = True bpy.ops.object.mode_set() - objs = bpy.context.selected_editable_objects - + for ob in objs: if ob.type == 'MESH': mats = ob.material_slots.keys() - + #check the faces on the mesh to build a list of used materials - usedMatIndex =[] #we'll store used materials indices here - faceMats =[] + usedMatIndex = [] # we'll store used materials indices here + faceMats = [] me = ob.data for f in me.faces: #get the material index for this face... faceindex = f.material_index - + #indices will be lost: Store face mat use by name currentfacemat = mats[faceindex] faceMats.append(currentfacemat) - - - #check if index is already listed as used or not + + # check if index is already listed as used or not found = 0 for m in usedMatIndex: if m == faceindex: found = 1 #break - + if found == 0: - #add this index to the list + #add this index to the list usedMatIndex.append(faceindex) - + #re-assign the used mats to the mesh and leave out the unused ml = [] mnames = [] for u in usedMatIndex: - ml.append( mats[u] ) + ml.append(mats[u]) #we'll need a list of names to get the face indices... mnames.append(mats[u]) - + assignmatslots(ob, ml) - - - #restore face indices: + + # restore face indices: i = 0 for f in me.faces: matindex = mnames.index(faceMats[i]) @@ -316,81 +317,73 @@ i += 1 if editmode: - bpy.ops.object.mode_set(mode = 'EDIT') - - + bpy.ops.object.mode_set(mode='EDIT') - -def assign_mat(matname="Default"): - #get active object so we can restore it later +def assign_mat(matname="Default"): + # get active object so we can restore it later actob = bpy.context.active_object - - #check if material exists, if it doesn't then create it - mats =bpy.data.materials + + # check if material exists, if it doesn't then create it found = False - for m in mats: + for m in bpy.data.materials: if m.name == matname: target = m found = True break if not found: target = bpy.data.materials.new(matname) - - - #if objectmode then set all faces + + # if objectmode then set all faces editmode = False allfaces = True if actob.mode == 'EDIT': - editmode =True - allfaces = False + editmode = True + allfaces = False bpy.ops.object.mode_set() - + objs = bpy.context.selected_editable_objects - - for ob in objs: - #set the active object to our object + + for ob in objs: + # set the active object to our object scn = bpy.context.scene scn.objects.active = ob - - - other = ['CURVE', 'SURFACE', 'FONT', 'META'] - if ob.type in other: - found=False + + if ob.type in {'CURVE', 'SURFACE', 'FONT', 'META'}: + found = False i = 0 - mats = bpy.data.materials - for m in mats: + for m in bpy.data.materials: if m.name == matname: - found =True + found = True index = i break i += 1 if not found: - index = i-1 - targetlist =[index] + index = i - 1 + targetlist = [index] assignmatslots(ob, targetlist) - - elif ob.type =='MESH': - #check material slots for matname material - found=False + + elif ob.type == 'MESH': + # check material slots for matname material + found = False i = 0 mats = ob.material_slots for m in mats: if m.name == matname: - found =True + found = True index = i #make slot active ob.active_material_index = i break i += 1 - + if not found: - index=i - #the material is not attached to the object - ob.data.materials.append(target) - + index = i + #the material is not attached to the object + ob.data.materials.append(target) + #now assign the material: - me =ob.data + me = ob.data if allfaces: for f in me.faces: f.material_index = index @@ -399,17 +392,14 @@ if f.select: f.material_index = index me.update() - - #restore the active object bpy.context.scene.objects.active = actob if editmode: - bpy.ops.object.mode_set(mode = 'EDIT') - + bpy.ops.object.mode_set(mode='EDIT') -def check_texture(img,mat): +def check_texture(img, mat): #finds a texture from an image #makes a texture if needed #adds it to the material if it isn't there already @@ -434,11 +424,12 @@ mtex.texture_coords = 'UV' mtex.use_map_color_diffuse = True + def texface_to_mat(): # editmode check here! editmode = False ob = bpy.context.object - if ob.mode =='EDIT': + if ob.mode == 'EDIT': editmode = True bpy.ops.object.mode_set() @@ -446,11 +437,11 @@ faceindex = [] unique_images = [] - + # get the texface images and store indices if (ob.data.uv_textures): for f in ob.data.uv_textures.active.data: - if f.image: + if f.image: img = f.image #build list of unique images if img not in unique_images: @@ -459,30 +450,26 @@ else: img = None - faceindex.append(None) - - + faceindex.append(None) - #check materials for images exist; create if needed + # check materials for images exist; create if needed matlist = [] for i in unique_images: if i: - print(i.name) try: m = bpy.data.materials[i.name] - except: - m = bpy.data.materials.new(name = i.name) + m = bpy.data.materials.new(name=i.name) continue finally: matlist.append(m.name) # add textures if needed - check_texture(i,m) + check_texture(i, m) - #set up the object material slots + # set up the object material slots assignmatslots(ob, matlist) - + #set texface indices to material slot indices.. me = ob.data @@ -492,11 +479,11 @@ me.faces[i].material_index = f i += 1 if editmode: - bpy.ops.object.mode_set(mode = 'EDIT') + bpy.ops.object.mode_set(mode='EDIT') -#operator classes: -#--------------------------------------------------------------------- +# ----------------------------------------------------------------------------- +# operator classes: class VIEW3D_OT_texface_to_material(bpy.types.Operator): '''''' @@ -513,19 +500,24 @@ texface_to_mat() return {'FINISHED'} else: - self.report({'WARNING'}, "No editable selected objects, could not finish") + self.report({'WARNING'}, + "No editable selected objects, could not finish") return {'CANCELLED'} + class VIEW3D_OT_assign_material(bpy.types.Operator): '''assign a material to the selection''' bl_idname = "view3d.assign_material" bl_label = "MW Assign Material" bl_options = {'REGISTER', 'UNDO'} - matname = StringProperty(name = 'Material Name', - description = 'Name of Material to Assign', - default = "", maxlen = 21) - + matname = StringProperty( + name='Material Name', + description='Name of Material to Assign', + default="", + maxlen=21, + ) + @classmethod def poll(cls, context): return context.active_object != None @@ -538,8 +530,9 @@ mat_to_texface() return {'FINISHED'} + class VIEW3D_OT_clean_material_slots(bpy.types.Operator): - '''removes any material slots from the + '''removes any material slots from the selected objects that are not used by the mesh''' bl_idname = "view3d.clean_material_slots" bl_label = "MW Clean Material Slots" @@ -553,6 +546,7 @@ cleanmatslots() return {'FINISHED'} + class VIEW3D_OT_material_to_texface(bpy.types.Operator): '''''' bl_idname = "view3d.material_to_texface" @@ -567,14 +561,17 @@ mat_to_texface() return {'FINISHED'} + class VIEW3D_OT_select_material_by_name(bpy.types.Operator): '''''' bl_idname = "view3d.select_material_by_name" bl_label = "MW Select Material By Name" bl_options = {'REGISTER', 'UNDO'} - matname = StringProperty(name = 'Material Name', - description = 'Name of Material to Select', - default = "", maxlen = 21) + matname = StringProperty( + name='Material Name', + description='Name of Material to Select', + maxlen=21, + ) @classmethod def poll(cls, context): @@ -592,18 +589,21 @@ bl_label = "MW Replace Material" bl_options = {'REGISTER', 'UNDO'} - matorg = StringProperty(name = 'Material to Replace', - description = 'Name of Material to Assign', - default = "", maxlen = 21) - - matrep = StringProperty(name = 'Replacement material', - description = 'Name of Material to Assign', - default = "", maxlen = 21) - - all_objects = BoolProperty(name ='all_objects', - description="replace for all objects in this blend file", - default = True) - + matorg = StringProperty( + name='Material to Replace', + description="Name of Material to Assign", + maxlen=21, + ) + matrep = StringProperty(name="Replacement material", + description='Name of Material to Assign', + maxlen=21, + ) + all_objects = BoolProperty( + name="all_objects", + description="replace for all objects in this blend file", + default=True, + ) + @classmethod def poll(cls, context): return context.active_object != None @@ -612,11 +612,13 @@ m1 = self.matorg m2 = self.matrep all = self.all_objects - replace_material(m1,m2,all) + replace_material(m1, m2, all) return {'FINISHED'} -#menu classes -#------------------------------------------------------------------------------- + +# ----------------------------------------------------------------------------- +# menu classes + class VIEW3D_MT_master_material(bpy.types.Menu): bl_label = "Master Material Menu" @@ -627,17 +629,20 @@ layout.menu("VIEW3D_MT_assign_material", icon='ZOOMIN') layout.menu("VIEW3D_MT_select_material", icon='HAND') layout.separator() - layout.operator("view3d.clean_material_slots", - text = 'Clean Material Slots', icon='CANCEL') + layout.operator("view3d.clean_material_slots", + text='Clean Material Slots', + icon='CANCEL') layout.operator("view3d.material_to_texface", - text = 'Material to Texface',icon='FACESEL_HLT') + text='Material to Texface', + icon='FACESEL_HLT') layout.operator("view3d.texface_to_material", - text = 'Texface to Material',icon='FACESEL_HLT') + text="Texface to Material", + icon='FACESEL_HLT') layout.separator() - layout.operator("view3d.replace_material", - text = 'Replace Material', icon='ARROW_LEFTRIGHT') - + layout.operator("view3d.replace_material", + text='Replace Material', + icon='ARROW_LEFTRIGHT') class VIEW3D_MT_assign_material(bpy.types.Menu): @@ -646,14 +651,15 @@ def draw(self, context): layout = self.layout layout.operator_context = 'INVOKE_REGION_WIN' - for i in range (len(bpy.data.materials)): - + for material_name in bpy.data.materials.keys(): layout.operator("view3d.assign_material", - text=bpy.data.materials[i].name, - icon='MATERIAL_DATA').matname = bpy.data.materials[i].name + text=material_name, + icon='MATERIAL_DATA').matname = material_name + + layout.operator("view3d.assign_material", + text="Add New", + icon='ZOOMIN') - layout.operator("view3d.assign_material",text="Add New", - icon='ZOOMIN') class VIEW3D_MT_select_material(bpy.types.Menu): bl_label = "Select by Material" @@ -666,41 +672,43 @@ layout.label if ob.mode == 'OBJECT': #show all used materials in entire blend file - for i in range (len(bpy.data.materials)): - if bpy.data.materials[i].users > 0: + for material_name, material in bpy.data.materials.items(): + if material.users > 0: layout.operator("view3d.select_material_by_name", - text=bpy.data.materials[i].name, - icon='MATERIAL_DATA').matname = bpy.data.materials[i].name - + text=material_name, + icon='MATERIAL_DATA', + ).matname = material_name elif ob.mode == 'EDIT': #show only the materials on this object mats = ob.material_slots.keys() for m in mats: layout.operator("view3d.select_material_by_name", - text=m, + text=m, icon='MATERIAL_DATA').matname = m def register(): bpy.utils.register_module(__name__) - + kc = bpy.context.window_manager.keyconfigs.addon - km = kc.keymaps.new(name="3D View", space_type="VIEW_3D") - kmi = km.keymap_items.new('wm.call_menu', 'Q', 'PRESS') - kmi.properties.name = "VIEW3D_MT_master_material" + if kc: + km = kc.keymaps.new(name="3D View", space_type="VIEW_3D") + kmi = km.keymap_items.new('wm.call_menu', 'Q', 'PRESS') + kmi.properties.name = "VIEW3D_MT_master_material" + def unregister(): bpy.utils.unregister_module(__name__) kc = bpy.context.window_manager.keyconfigs.addon - km = kc.keymaps["3D View"] - for kmi in km.keymap_items: - if kmi.idname == 'wm.call_menu': - if kmi.properties.name == "VIEW3D_MT_master_material": - km.keymap_items.remove(kmi) - break + if kc: + km = kc.keymaps["3D View"] + for kmi in km.keymap_items: + if kmi.idname == 'wm.call_menu': + if kmi.properties.name == "VIEW3D_MT_master_material": + km.keymap_items.remove(kmi) + break if __name__ == "__main__": register() - diff -Nru blender-2.61/release/scripts/addons/space_view3d_math_vis/draw.py blender-2.62/release/scripts/addons/space_view3d_math_vis/draw.py --- blender-2.61/release/scripts/addons/space_view3d_math_vis/draw.py 2011-12-13 19:58:06.000000000 +0000 +++ blender-2.62/release/scripts/addons/space_view3d_math_vis/draw.py 2012-02-15 19:42:36.000000000 +0000 @@ -220,12 +220,12 @@ loc = context.scene.cursor_location.copy() for quat in data_quat.values(): mat = quat.to_matrix().to_4x4() - mat[3][0:3] = loc + mat.translation = loc draw_matrix(mat) if data_euler: loc = context.scene.cursor_location.copy() for eul in data_euler.values(): mat = eul.to_matrix().to_4x4() - mat[3][0:3] = loc + mat.translation = loc draw_matrix(mat) diff -Nru blender-2.61/release/scripts/addons/space_view3d_math_vis/__init__.py blender-2.62/release/scripts/addons/space_view3d_math_vis/__init__.py --- blender-2.61/release/scripts/addons/space_view3d_math_vis/__init__.py 2011-12-13 19:58:06.000000000 +0000 +++ blender-2.62/release/scripts/addons/space_view3d_math_vis/__init__.py 2012-02-15 19:42:36.000000000 +0000 @@ -23,13 +23,12 @@ "author": "Campbell Barton", "version": (0, 1), "blender": (2, 5, 7), - "api": 35622, "location": "View3D > Tool Shelf or Console", "description": "Display console defined mathutils variables in the 3D view", - "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\ - "Scripts/3D_interaction/Math_Viz", - "tracker_url": "http://projects.blender.org/tracker/index.php?"\ - "func=detail&aid=25545", + "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/" + "Scripts/3D_interaction/Math_Viz", + "tracker_url": "http://projects.blender.org/tracker/index.php?" + "func=detail&aid=25545", "support": "OFFICIAL", "category": "3D View"} diff -Nru blender-2.61/release/scripts/addons/space_view3d_math_vis/utils.py blender-2.62/release/scripts/addons/space_view3d_math_vis/utils.py --- blender-2.61/release/scripts/addons/space_view3d_math_vis/utils.py 2011-12-13 19:58:06.000000000 +0000 +++ blender-2.62/release/scripts/addons/space_view3d_math_vis/utils.py 2012-02-15 19:42:36.000000000 +0000 @@ -41,8 +41,8 @@ var_type = type(var) if var_type is Matrix: - if var.col_size != 4 or var.row_size != 4: - if var.row_size == var.col_size: + if len(var.col) != 4 or len(var.row) != 4: + if len(var.col) == len(var.row): var = var.to_4x4() else: # todo, support 4x3 matrix continue diff -Nru blender-2.61/release/scripts/addons/space_view3d_panel_measure.py blender-2.62/release/scripts/addons/space_view3d_panel_measure.py --- blender-2.61/release/scripts/addons/space_view3d_panel_measure.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/space_view3d_panel_measure.py 2012-02-15 19:43:32.000000000 +0000 @@ -28,7 +28,6 @@ " Benjamin Lauritzen (Loonsbury; Volume code)", "version": (0, 8, 2), "blender": (2, 6, 0), - "api": 42508, "location": "View3D > Properties > Measure Panel", "description": "Measure distances between objects", "warning": "Script needs repairs", @@ -105,10 +104,10 @@ # Get a single selected object (or nothing). obj = getSingleObject(context) - if (context.mode == 'EDIT_MESH'): + if context.mode == 'EDIT_MESH': obj = context.active_object - if (obj and obj.type == 'MESH' and obj.data): + if obj and obj.type == 'MESH' and obj.data: # Get mesh data from Object. mesh = obj.data @@ -175,7 +174,7 @@ else: return None - elif (context.mode == 'OBJECT'): + elif context.mode == 'OBJECT': # We are working in object mode. if len(context.selected_objects) > 2: @@ -188,7 +187,7 @@ obj2_loc = obj2.matrix_world.to_translation() return (obj1_loc, obj2_loc, COLOR_GLOBAL) - elif (obj): + elif obj: # One object selected. # We measure the distance from the object to the 3D cursor. cur_loc = sce.cursor_location @@ -235,7 +234,7 @@ # running this with selectedOnly=1! # @todo Support other object types (surfaces, etc...)? def objectEdgeLength(obj, selectedOnly, globalSpace): - if (obj and obj.type == 'MESH' and obj.data): + if obj and obj.type == 'MESH' and obj.data: edgeTotal = 0 mesh = obj.data @@ -260,7 +259,8 @@ def faceAreaGlobal(face, obj): area = 0.0 - mat = obj.matrix_world + mesh = obj.data + mat = obj.matrix_world.copy() if len(face.vertices) == 4: # Quad @@ -269,10 +269,10 @@ v1, v2, v3, v4 = face.vertices # Get vertex data - v1 = obj.data.vertices[v1] - v2 = obj.data.vertices[v2] - v3 = obj.data.vertices[v3] - v4 = obj.data.vertices[v4] + v1 = mesh.vertices[v1] + v2 = mesh.vertices[v2] + v3 = mesh.vertices[v3] + v4 = mesh.vertices[v4] # Apply transform matrix to vertex coordinates. v1 = mat * v1.co @@ -301,9 +301,9 @@ v1, v2, v3 = face.vertices # Get vertex data - v1 = obj.data.vertices[v1] - v2 = obj.data.vertices[v2] - v3 = obj.data.vertices[v3] + v1 = mesh.vertices[v1] + v2 = mesh.vertices[v2] + v3 = mesh.vertices[v3] # Apply transform matrix to vertex coordinates. v1 = mat * v1.co @@ -328,7 +328,7 @@ # running this with selectedOnly=1! # @todo Support other object types (surfaces, etc...)? def objectSurfaceArea(obj, selectedOnly, globalSpace): - if (obj and obj.type == 'MESH' and obj.data): + if obj and obj.type == 'MESH' and obj.data: areaTotal = 0 normTotal = Vector((0.0, 0.0, 0.0)) @@ -354,7 +354,7 @@ # Calculate the volume of a mesh object. # Copyright Loonsbury (loonsbury@yahoo.com) def objectVolume(obj, globalSpace): - if (obj and obj.type == 'MESH' and obj.data): + if obj and obj.type == 'MESH' and obj.data: # Check if mesh is non-manifold if not checkManifold(obj): @@ -372,9 +372,9 @@ else: v1, v2, v3 = face.vertices - v1 = obj.data.vertices[v1] - v2 = obj.data.vertices[v2] - v3 = obj.data.vertices[v3] + v1 = mesh.vertices[v1] + v2 = mesh.vertices[v2] + v3 = mesh.vertices[v3] # Scaled vert coordinates with object XYZ offsets for # selection extremes/sizing. @@ -405,7 +405,7 @@ # Allowing for quads if len(face.vertices) == 4: # Get vertex data - v4 = obj.data.vertices[v4] + v4 = mesh.vertices[v4] if globalSpace: x4 = v4.co[0] * obj.scale[0] + obj.location[0] @@ -444,7 +444,7 @@ # Manifold Checks # Copyright Loonsbury (loonsbury@yahoo.com) def checkManifold(obj): - if (obj and obj.type == 'MESH' and obj.data): + if obj and obj.type == 'MESH' and obj.data: mesh = obj.data mc = dict([(ed.key, 0) for ed in mesh.edges]) # TODO @@ -495,14 +495,14 @@ # Get measured 3D points and colors. line = getMeasurePoints(context) - if (line and draw): + if line and draw: p1, p2, color = line # Get and convert the Perspective Matrix of the current view/region. view3d = bpy.context region = view3d.region_data perspMatrix = region.perspective_matrix - tempMat = [perspMatrix[i][j] for i in range(4) for j in range(4)] + tempMat = [perspMatrix[j][i] for i in range(4) for j in range(4)] perspBuff = bgl.Buffer(bgl.GL_FLOAT, 16, tempMat) # --- @@ -632,19 +632,19 @@ loc_y -= OFFSET_Y - if (sce.measure_panel_calc_edge_length): - if (context.mode == 'EDIT_MESH'): + if sce.measure_panel_calc_edge_length: + if context.mode == 'EDIT_MESH': obj = context.active_object length_total = objectEdgeLength(obj, True, measureGlobal(sce)) sce.measure_panel_edge_length = length_total - elif (context.mode == 'OBJECT'): + elif context.mode == 'OBJECT': length_total = -1 for o in context.selected_objects: - if (o.type == 'MESH'): + if o.type == 'MESH': length = objectEdgeLength(o, False, measureGlobal(sce)) if length >= 0: @@ -656,14 +656,14 @@ sce.measure_panel_edge_length = length_total # Handle mesh surface area calulations - if (sce.measure_panel_calc_area): + if sce.measure_panel_calc_area: # Get a single selected object (or nothing). obj = getSingleObject(context) - if (context.mode == 'EDIT_MESH'): + if context.mode == 'EDIT_MESH': obj = context.active_object - if (obj and obj.type == 'MESH' and obj.data): + if obj and obj.type == 'MESH' and obj.data: # "Note: a Mesh will return the selection state of the mesh # when EditMode was last exited. A Python script operating # in EditMode must exit EditMode before getting the current @@ -695,11 +695,11 @@ if len(faces_selected) > 0: area, normal = objectSurfaceArea(obj, True, measureGlobal(sce)) - if (area >= 0): + if area >= 0.0: sce.measure_panel_area1 = area sce.measure_panel_normal1 = normal - elif (context.mode == 'OBJECT'): + elif context.mode == 'OBJECT': # We are working in object mode. if len(context.selected_objects) > 2: @@ -708,15 +708,15 @@ # # We have more that 2 objects selected... # # mesh_objects = [o for o in context.selected_objects -# if (o.type == 'MESH')] +# if o.type == 'MESH'] -# if (len(mesh_objects) > 0): +# if len(mesh_objects) > 0: # # ... and at least one of them is a mesh. # # for o in mesh_objects: # area = objectSurfaceArea(o, False, # measureGlobal(sce)) -# if (area >= 0): +# if area >= 0: # #row.label(text=o.name, icon='OBJECT_DATA') # #row.label(text=str(round(area, PRECISION)) # # + " BU^2") @@ -736,7 +736,7 @@ sce.measure_panel_normal1 = normal1 sce.measure_panel_normal2 = normal2 - elif (obj): + elif obj: # One object selected. # Calculate surface area of the object. @@ -746,10 +746,10 @@ sce.measure_panel_area1 = area sce.measure_panel_normal1 = normal - if (sce.measure_panel_calc_volume): + if sce.measure_panel_calc_volume: obj = getSingleObject(context) - if (context.mode == 'OBJECT'): + if context.mode == 'OBJECT': # We are working in object mode. #if len(context.selected_objects) > 2: # TODO @@ -767,7 +767,7 @@ sce.measure_panel_volume1 = volume1 sce.measure_panel_volume2 = volume2 - elif (obj): + elif obj: # One object selected. # Calculate surface area of the object. @@ -838,7 +838,7 @@ # Get the active object. obj = context.active_object - if (obj and obj.type == 'MESH' and context.mode == 'EDIT_MESH'): + if obj and obj.type == 'MESH' and context.mode == 'EDIT_MESH': # Exit and re-enter mesh EditMode. bpy.ops.object.mode_set(mode='OBJECT') bpy.ops.object.mode_set(mode='EDIT') @@ -890,7 +890,7 @@ drawTansformButtons = 1 - if (context.mode == 'EDIT_MESH'): + if context.mode == 'EDIT_MESH': obj = context.active_object row = layout.row() @@ -903,7 +903,7 @@ # " to do this manually, after you changed" \ # " the selection") - if (obj and obj.type == 'MESH' and obj.data): + if obj and obj.type == 'MESH' and obj.data: # "Note: a Mesh will return the selection state of the mesh # when EditMode was last exited. A Python script operating # in EditMode must exit EditMode before getting the current @@ -987,8 +987,8 @@ row.prop(sce, "measure_panel_calc_edge_length", text="Edge Length (selected edges)") - if (sce.measure_panel_calc_edge_length): - if (sce.measure_panel_edge_length >= 0): + if sce.measure_panel_calc_edge_length: + if sce.measure_panel_edge_length >= 0: box = layout.box() row = box.row() row.label( @@ -1004,14 +1004,14 @@ row.prop(sce, "measure_panel_calc_area", text="Surface area (selected faces)") - if (sce.measure_panel_calc_area): + if sce.measure_panel_calc_area: # Get selected faces # @todo: Better (more efficient) way to do this? faces_selected = [f for f in mesh.faces if f.select == 1] if len(faces_selected) > 0: - if (sce.measure_panel_area1 >= 0): + if sce.measure_panel_area1 >= 0: box = layout.box() row = box.row() row.label( @@ -1038,11 +1038,11 @@ "measure_panel_transform", expand=True) - elif (context.mode == 'OBJECT'): + elif context.mode == 'OBJECT': # We are working in object mode. mesh_objects = [o for o in context.selected_objects - if (o.type == 'MESH')] + if o.type == 'MESH'] if len(context.selected_objects) > 2: # We have more that 2 objects selected... @@ -1052,8 +1052,8 @@ row.prop(sce, "measure_panel_calc_edge_length", text="Edge Length") - if (sce.measure_panel_calc_edge_length): - if (len(mesh_objects) > 0): + if sce.measure_panel_calc_edge_length: + if len(mesh_objects) > 0: box = layout.box() row = box.row() @@ -1065,8 +1065,8 @@ row.prop(sce, "measure_panel_calc_area", text="Surface area") - if (sce.measure_panel_calc_area): - if (len(mesh_objects) > 0): + if sce.measure_panel_calc_area: + if len(mesh_objects) > 0: # ... and at least one of them is a mesh. # Calculate and display surface area of the objects. @@ -1083,7 +1083,7 @@ # for o in mesh_objects: # area = objectSurfaceArea(o, False, # measureGlobal(sce)) -# if (area >= 0): +# if area >= 0: # row = layout.row() # row.label(text=o.name, icon='OBJECT_DATA') # row.label(text=str(round(area, PRECISION)) @@ -1116,9 +1116,9 @@ row.prop(sce, "measure_panel_calc_edge_length", text="Edge Length") - if (sce.measure_panel_calc_edge_length): - if (sce.measure_panel_edge_length >= 0): - if (len(mesh_objects) > 0): + if sce.measure_panel_calc_edge_length: + if sce.measure_panel_edge_length >= 0: + if len(mesh_objects) > 0: box = layout.box() row = box.row() @@ -1131,11 +1131,11 @@ row.prop(sce, "measure_panel_calc_area", text="Surface area") - if (sce.measure_panel_calc_area): + if sce.measure_panel_calc_area: # Display surface area of the objects. if (sce.measure_panel_area1 >= 0 or sce.measure_panel_area2 >= 0): - if (sce.measure_panel_area1 >= 0): + if sce.measure_panel_area1 >= 0: box = layout.box() row = box.row() row.label(text=obj1.name, icon='OBJECT_DATA') @@ -1149,7 +1149,7 @@ row = box.row() row.prop(sce, "measure_panel_normal1") - if (sce.measure_panel_area2 >= 0): + if sce.measure_panel_area2 >= 0: box = layout.box() row = box.row() row.label(text=obj2.name, icon='OBJECT_DATA') @@ -1168,14 +1168,14 @@ row.prop(sce, "measure_panel_calc_volume", text="Volume") - if (sce.measure_panel_calc_volume): + if sce.measure_panel_calc_volume: # Display volume of the objects. - if (sce.measure_panel_volume1 >= -1): + if sce.measure_panel_volume1 >= -1: box = layout.box() row = box.row() row.label(text=obj1.name, icon='OBJECT_DATA') - if (sce.measure_panel_volume1 >= 0): + if sce.measure_panel_volume1 >= 0: row = box.row() row.label(text="Volume") row.prop(sce, "measure_panel_volume1") @@ -1184,12 +1184,12 @@ row.label(text="Mesh is non-manifold!", icon='INFO') - if (sce.measure_panel_volume2 >= -1): + if sce.measure_panel_volume2 >= -1: box = layout.box() row = box.row() row.label(text=obj2.name, icon='OBJECT_DATA') - if (sce.measure_panel_volume2 >= 0): + if sce.measure_panel_volume2 >= 0: row = box.row() row.label(text="Volume") row.prop(sce, "measure_panel_volume2") @@ -1198,7 +1198,7 @@ row.label(text="Mesh is non-manifold!", icon='INFO') - elif (obj): + elif obj: # One object selected. # We measure the distance from the object to the 3D cursor. layout.label(text="Distance") @@ -1222,9 +1222,9 @@ row.prop(sce, "measure_panel_calc_edge_length", text="Edge Length") - if (sce.measure_panel_calc_edge_length): - if (sce.measure_panel_edge_length >= 0): - if (len(mesh_objects) > 0): + if sce.measure_panel_calc_edge_length: + if sce.measure_panel_edge_length >= 0: + if len(mesh_objects) > 0: box = layout.box() row = box.row() @@ -1236,10 +1236,10 @@ row.prop(sce, "measure_panel_calc_area", text="Surface area") - if (sce.measure_panel_calc_area): + if sce.measure_panel_calc_area: # Display surface area of the object. - if (sce.measure_panel_area1 >= 0): + if sce.measure_panel_area1 >= 0.0: box = layout.box() row = box.row() row.label(text=obj.name, icon='OBJECT_DATA') @@ -1258,14 +1258,14 @@ row.prop(sce, "measure_panel_calc_volume", text="Volume") - if (sce.measure_panel_calc_volume): + if sce.measure_panel_calc_volume: # Display volume of the objects. - if (sce.measure_panel_volume1 >= -1): + if sce.measure_panel_volume1 >= -1: box = layout.box() row = box.row() row.label(text=obj.name, icon='OBJECT_DATA') - if (sce.measure_panel_volume1 >= 0): + if sce.measure_panel_volume1 >= 0: row = box.row() row.label(text="Volume") row.prop(sce, "measure_panel_volume1") @@ -1358,14 +1358,14 @@ # Define property for the calc-area setting. # @todo prevent double calculations for each refresh automatically? bpy.types.Scene.measure_panel_calc_area = bpy.props.BoolProperty( - description="Calculate mesh surface area (heavy CPU" \ - " usage on bigger meshes)", + description="Calculate mesh surface area (heavy CPU " + "usage on bigger meshes)", default=0) # Define property for the calc-volume setting. bpy.types.Scene.measure_panel_calc_volume = bpy.props.BoolProperty( - description="Calculate mesh volume (heavy CPU" \ - " usage on bigger meshes)", + description="Calculate mesh volume (heavy CPU " + "usage on bigger meshes)", default=0) pass diff -Nru blender-2.61/release/scripts/addons/space_view3d_screencast_keys.py blender-2.62/release/scripts/addons/space_view3d_screencast_keys.py --- blender-2.61/release/scripts/addons/space_view3d_screencast_keys.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/space_view3d_screencast_keys.py 2012-02-15 19:43:32.000000000 +0000 @@ -16,70 +16,65 @@ # # ##### END GPL LICENSE BLOCK ##### +# + bl_info = { 'name': 'Screencast Keys', - 'author': 'Paulo Gomes, Bart Crouch, John E. Herrenyo', - 'version': (1, 4), - 'blender': (2, 5, 9), - 'api': 39933, + 'author': 'Paulo Gomes, Bart Crouch, John E. Herrenyo, Gaia Clary', + 'version': (1, 5), + 'blender': (2, 6, 1), 'location': 'View3D > Properties panel > Screencast Keys', 'warning': '', 'description': 'Display keys pressed in the 3d-view, '\ 'useful for screencasts.', - 'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.5/'\ - 'Py/Scripts/3D_interaction/Screencast_Key_Status_Tool', - 'tracker_url': 'http://projects.blender.org/tracker/index.php?'\ - 'func=detail&aid=21612', + 'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.5/' + 'Py/Scripts/3D_interaction/Screencast_Key_Status_Tool', + 'tracker_url': 'http://projects.blender.org/tracker/index.php?' + 'func=detail&aid=21612', 'category': '3D View'} -# ##### -# -# Modification history: -# - Version 1,4 -# - 07-sep-2011 (Gaia Clary): -# - settings now stored in blend file -# - grouping mouse&text -# - mouse_size and font_size separated -# - boundingBox for improved readability. -# - missing mouse "release" clicks added -# -# #### - - import bgl import blf import bpy import time + MOUSE_RATIO = 0.535 + def getDisplayLocation(context): - sc = context.scene - mouse_size = sc.screencast_keys_mouse_size - pos_x = int( (context.region.width - mouse_size*MOUSE_RATIO) * sc.screencast_keys_pos_x / 100) - pos_y = int( (context.region.height - mouse_size) * sc.screencast_keys_pos_y / 100) - return pos_x, pos_y + scene = context.scene + mouse_size = scene.screencast_keys_mouse_size + + pos_x = int( (context.region.width - mouse_size * MOUSE_RATIO) * \ + scene.screencast_keys_pos_x / 100) + pos_y = int( (context.region.height - mouse_size) * + scene.screencast_keys_pos_y / 100) + + return(pos_x, pos_y) + def getBoundingBox(current_width, current_height, new_text): w,h = blf.dimensions(0,new_text) if w > current_width: current_width = w current_height += h - return current_width, current_height + + return(current_width, current_height) + def draw_callback_px(self, context): wm = context.window_manager sc = context.scene if not wm.screencast_keys_keys: return - + font_size = sc.screencast_keys_font_size mouse_size = sc.screencast_keys_mouse_size link = sc.screencast_keys_link pos_x, pos_y = getDisplayLocation(context) - # draw text in the 3d-view # ======================== blf.size(0, sc.screencast_keys_font_size, 72) @@ -101,23 +96,23 @@ label_time = time.time() - self.time[i] if label_time < 2: # only display key-presses of last 2 seconds - keypos_y = pos_y + shift + font_size*(i+0.1) + keypos_y = pos_y + shift + font_size*(i+0.1) blf.position(0, keypos_x, keypos_y , 0) alpha = min(1.0, max(0.0, 2 * (2 - label_time))) bgl.glColor4f(r, g, b, alpha) blf.draw(0, self.key[i]) - text_width, text_height = getBoundingBox(text_width, text_height, self.key[i]) + text_width, text_height = getBoundingBox(text_width, text_height, + self.key[i]) row_count += 1 - final = i + final = i + 1 else: break # get rid of status texts that aren't displayed anymore - self.key = self.key[:final+1] - self.time = self.time[:final+1] - - + self.key = self.key[:final] + self.time = self.time[:final] + # draw graphical representation of the mouse # ========================================== if sc.screencast_keys_mouse == 'icon': @@ -132,49 +127,32 @@ if shape: alpha = min(1.0, max(0.0, 2 * (2 - click_time))) draw_mouse(context, shape, "filled", alpha) - final = i + final = i + 1 else: break - # get rid of mouse clicks that aren't displayed anymore - self.mouse = self.mouse[:final+1] - self.mouse_time = self.mouse_time[:final+1] - + self.mouse = self.mouse[:final] + self.mouse_time = self.mouse_time[:final] # Draw border (if enabled) # ======================== - if link == True and row_count > 0: - bgl.glEnable(bgl.GL_BLEND) - bgl.glBegin(bgl.GL_QUADS) - bgl.glLineWidth(2) - bgl.glColor4f(r, g, b, 0.2) - drawRectangle(pos_x , pos_y , text_width+mouse_size*MOUSE_RATIO*1.3 , max(mouse_size, font_size*row_count), 4 ) - bgl.glEnd() - bgl.glBegin(bgl.GL_LINES) - bgl.glColor4f(r, g, b, alpha ) - drawRectangle(pos_x , pos_y , text_width+mouse_size*MOUSE_RATIO*1.3 , max(mouse_size, font_size*row_count), 4 ) - bgl.glEnd() - - -# Draw a line. currently not used. -def drawLinef(from_x, from_y, to_x, to_y): - bgl.glVertex2f(from_x, from_y) - bgl.glVertex2f(to_x, to_y) - - -# Draw a rectangle. Currently not used -def drawRectangle (ox, oy, ow, oh, padding=0): - - x = ox - 2*padding - y = oy - padding - w = ow + 4 * padding - h = oh + 2 * padding - - drawLinef(x, y, x+w, y) - drawLinef(x+w, y, x+w, y+h) - drawLinef(x+w, y+h, x , y+h) - drawLinef(x , y+h, x , y) + if link and row_count > 0: + padding = 8 + x0 = max(0, pos_x - padding) + y0 = max(0, pos_y - padding) + x1 = pos_x + text_width + mouse_size * MOUSE_RATIO * 1.3 + padding + y1 = pos_y + max(mouse_size, font_size * row_count) + padding + positions = [[x0, y0], [x0, y1], [x1, y1], [x1, y0]] + settings = [[bgl.GL_QUADS, min(0.2, alpha)], [bgl.GL_LINE_LOOP, alpha]] + + for mode, box_alpha in settings: + bgl.glEnable(bgl.GL_BLEND) + bgl.glBegin(mode) + bgl.glColor4f(r, g, b, box_alpha) + for v1, v2 in positions: + bgl.glVertex2f(v1, v2) + bgl.glEnd() def draw_mouse(context, shape, style, alpha): @@ -185,7 +163,7 @@ link = sc.screencast_keys_link pos_x, pos_y = getDisplayLocation(context) - if link==True: + if link: offset_x = pos_x else: offset_x = context.region.width - pos_x - (mouse_size * MOUSE_RATIO) @@ -193,7 +171,7 @@ offset_y = pos_y if font_size > mouse_size: offset_y += (font_size - mouse_size) / 2 - + shape_data = get_shape_data(shape) bgl.glTranslatef(offset_x, offset_y, 0) @@ -201,15 +179,14 @@ # color r, g, b = sc.screencast_keys_color bgl.glEnable(bgl.GL_BLEND) - #bgl.glBlendFunc(bgl.GL_SRC_ALPHA, bgl.GL_ONE_MINUS_SRC_ALPHA) - #bgl.glColor4f(r, g, b, alpha) - + bgl.glColor4f(r, g, b, alpha) + # inner shape for filled style if style == "filled": inner_shape = [] for i in shape_data: inner_shape.append(i[0]) - + # outer shape for i in shape_data: shape_segment = i @@ -217,16 +194,14 @@ shape_segment[1] = [mouse_size * k for k in shape_segment[1]] shape_segment[2] = [mouse_size * k for k in shape_segment[2]] shape_segment[3] = [mouse_size * k for k in shape_segment[3]] - + # create the buffer shape_buffer = bgl.Buffer(bgl.GL_FLOAT, [4, 3], shape_segment) - + # create the map and draw the triangle fan bgl.glMap1f(bgl.GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, shape_buffer) bgl.glEnable(bgl.GL_MAP1_VERTEX_3) - bgl.glColor4f(r, g, b, alpha) - if style == "outline": bgl.glBegin(bgl.GL_LINE_STRIP) else: # style == "filled" @@ -234,22 +209,21 @@ for j in range(10): bgl.glEvalCoord1f(j / 10.0) x, y, z = shape_segment[3] - + # make sure the last vertex is indeed the last one, to avoid gaps bgl.glVertex3f(x, y, z) bgl.glEnd() bgl.glDisable(bgl.GL_MAP1_VERTEX_3) - + # draw interior if style == "filled": - bgl.glColor4f(r, g, b, alpha) bgl.glBegin(bgl.GL_TRIANGLE_FAN) for i in inner_shape: j = [mouse_size * k for k in i] x, y, z = j bgl.glVertex3f(x, y, z) bgl.glEnd() - + bgl.glTranslatef(-offset_x, -offset_y, 0) @@ -257,127 +231,170 @@ def get_shape_data(shape): data = [] if shape == "mouse": - data = [[[0.264, 0.002, 0.0], - [0.096, 0.002, 0.0], - [0.059, 0.226, 0.0], - [0.04, 0.313, 0.0]], - [[0.04, 0.313, 0.0], - [-0.015, 0.565, 0.0], - [-0.005, 0.664, 0.0], - [0.032, 0.87, 0.0]], - [[0.032, 0.87, 0.0], - [0.05, 0.973, 0.0], - [0.16, 1.002, 0.0], - [0.264, 1.002, 0.0]], - [[0.264, 1.002, 0.0], - [0.369, 1.002, 0.0], - [0.478, 0.973, 0.0], - [0.497, 0.87, 0.0]], - [[0.497, 0.87, 0.0], - [0.533, 0.664, 0.0], - [0.544, 0.565, 0.0], - [0.489, 0.313, 0.0]], - [[0.489, 0.313, 0.0], - [0.47, 0.226, 0.0], - [0.432, 0.002, 0.0], + data = [[[0.264, 0.002, 0.0], + [0.096, 0.002, 0.0], + [0.059, 0.226, 0.0], + [0.04, 0.313, 0.0]], + [[0.04, 0.313, 0.0], + [-0.015, 0.565, 0.0], + [-0.005, 0.664, 0.0], + [0.032, 0.87, 0.0]], + [[0.032, 0.87, 0.0], + [0.05, 0.973, 0.0], + [0.16, 1.002, 0.0], + [0.264, 1.002, 0.0]], + [[0.264, 1.002, 0.0], + [0.369, 1.002, 0.0], + [0.478, 0.973, 0.0], + [0.497, 0.87, 0.0]], + [[0.497, 0.87, 0.0], + [0.533, 0.664, 0.0], + [0.544, 0.565, 0.0], + [0.489, 0.313, 0.0]], + [[0.489, 0.313, 0.0], + [0.47, 0.226, 0.0], + [0.432, 0.002, 0.0], [0.264, 0.002, 0.0]]] elif shape == "left_button": - data = [[[0.154, 0.763, 0.0], - [0.126, 0.755, 0.0], - [0.12, 0.754, 0.0], - [0.066, 0.751, 0.0]], - [[0.066, 0.751, 0.0], - [0.043, 0.75, 0.0], - [0.039, 0.757, 0.0], - [0.039, 0.767, 0.0]], - [[0.039, 0.767, 0.0], - [0.047, 0.908, 0.0], - [0.078, 0.943, 0.0], - [0.155, 0.97, 0.0]], - [[0.155, 0.97, 0.0], - [0.174, 0.977, 0.0], - [0.187, 0.975, 0.0], - [0.191, 0.972, 0.0]], - [[0.191, 0.972, 0.0], - [0.203, 0.958, 0.0], - [0.205, 0.949, 0.0], - [0.199, 0.852, 0.0]], - [[0.199, 0.852, 0.0], - [0.195, 0.77, 0.0], - [0.18, 0.771, 0.0], + data = [[[0.154, 0.763, 0.0], + [0.126, 0.755, 0.0], + [0.12, 0.754, 0.0], + [0.066, 0.751, 0.0]], + [[0.066, 0.751, 0.0], + [0.043, 0.75, 0.0], + [0.039, 0.757, 0.0], + [0.039, 0.767, 0.0]], + [[0.039, 0.767, 0.0], + [0.047, 0.908, 0.0], + [0.078, 0.943, 0.0], + [0.155, 0.97, 0.0]], + [[0.155, 0.97, 0.0], + [0.174, 0.977, 0.0], + [0.187, 0.975, 0.0], + [0.191, 0.972, 0.0]], + [[0.191, 0.972, 0.0], + [0.203, 0.958, 0.0], + [0.205, 0.949, 0.0], + [0.199, 0.852, 0.0]], + [[0.199, 0.852, 0.0], + [0.195, 0.77, 0.0], + [0.18, 0.771, 0.0], [0.154, 0.763, 0.0]]] elif shape == "middle_button": - data = [[[0.301, 0.8, 0.0], - [0.298, 0.768, 0.0], - [0.231, 0.768, 0.0], - [0.228, 0.8, 0.0]], - [[0.228, 0.8, 0.0], - [0.226, 0.817, 0.0], - [0.225, 0.833, 0.0], - [0.224, 0.85, 0.0]], - [[0.224, 0.85, 0.0], - [0.222, 0.873, 0.0], - [0.222, 0.877, 0.0], - [0.224, 0.9, 0.0]], - [[0.224, 0.9, 0.0], - [0.225, 0.917, 0.0], - [0.226, 0.933, 0.0], - [0.228, 0.95, 0.0]], - [[0.228, 0.95, 0.0], - [0.231, 0.982, 0.0], - [0.298, 0.982, 0.0], - [0.301, 0.95, 0.0]], - [[0.301, 0.95, 0.0], - [0.302, 0.933, 0.0], - [0.303, 0.917, 0.0], - [0.305, 0.9, 0.0]], - [[0.305, 0.9, 0.0], - [0.307, 0.877, 0.0], - [0.307, 0.873, 0.0], - [0.305, 0.85, 0.0]], - [[0.305, 0.85, 0.0], - [0.303, 0.833, 0.0], - [0.302, 0.817, 0.0], + data = [[[0.301, 0.8, 0.0], + [0.298, 0.768, 0.0], + [0.231, 0.768, 0.0], + [0.228, 0.8, 0.0]], + [[0.228, 0.8, 0.0], + [0.226, 0.817, 0.0], + [0.225, 0.833, 0.0], + [0.224, 0.85, 0.0]], + [[0.224, 0.85, 0.0], + [0.222, 0.873, 0.0], + [0.222, 0.877, 0.0], + [0.224, 0.9, 0.0]], + [[0.224, 0.9, 0.0], + [0.225, 0.917, 0.0], + [0.226, 0.933, 0.0], + [0.228, 0.95, 0.0]], + [[0.228, 0.95, 0.0], + [0.231, 0.982, 0.0], + [0.298, 0.982, 0.0], + [0.301, 0.95, 0.0]], + [[0.301, 0.95, 0.0], + [0.302, 0.933, 0.0], + [0.303, 0.917, 0.0], + [0.305, 0.9, 0.0]], + [[0.305, 0.9, 0.0], + [0.307, 0.877, 0.0], + [0.307, 0.873, 0.0], + [0.305, 0.85, 0.0]], + [[0.305, 0.85, 0.0], + [0.303, 0.833, 0.0], + [0.302, 0.817, 0.0], [0.301, 0.8, 0.0]]] + elif shape == "middle_down_button": + data = [[[0.301, 0.8, 0.0], + [0.298, 0.768, 0.0], + [0.231, 0.768, 0.0], + [0.228, 0.8, 0.0]], + [[0.228, 0.8, 0.0], + [0.226, 0.817, 0.0], + [0.225, 0.833, 0.0], + [0.224, 0.85, 0.0]], + [[0.224, 0.85, 0.0], + [0.264, 0.873, 0.0], + [0.284, 0.873, 0.0], + [0.305, 0.85, 0.0]], + [[0.305, 0.85, 0.0], + [0.303, 0.833, 0.0], + [0.302, 0.817, 0.0], + [0.301, 0.8, 0.0]]] + elif shape == "middle_up_button": + data = [[[0.270, 0.873, 0.0], + [0.264, 0.873, 0.0], + [0.222, 0.877, 0.0], + [0.224, 0.9, 0.0]], + [[0.224, 0.9, 0.0], + [0.225, 0.917, 0.0], + [0.226, 0.933, 0.0], + [0.228, 0.95, 0.0]], + [[0.228, 0.95, 0.0], + [0.231, 0.982, 0.0], + [0.298, 0.982, 0.0], + [0.301, 0.95, 0.0]], + [[0.301, 0.95, 0.0], + [0.302, 0.933, 0.0], + [0.303, 0.917, 0.0], + [0.305, 0.9, 0.0]], + [[0.305, 0.9, 0.0], + [0.307, 0.877, 0.0], + [0.284, 0.873, 0.0], + [0.270, 0.873, 0.0]]] elif shape == "right_button": - data = [[[0.375, 0.763, 0.0], - [0.402, 0.755, 0.0], - [0.408, 0.754, 0.0], - [0.462, 0.751, 0.0]], - [[0.462, 0.751, 0.0], - [0.486, 0.75, 0.0], - [0.49, 0.757, 0.0], - [0.489, 0.767, 0.0]], - [[0.489, 0.767, 0.0], - [0.481, 0.908, 0.0], - [0.451, 0.943, 0.0], - [0.374, 0.97, 0.0]], - [[0.374, 0.97, 0.0], - [0.354, 0.977, 0.0], - [0.341, 0.975, 0.0], - [0.338, 0.972, 0.0]], - [[0.338, 0.972, 0.0], - [0.325, 0.958, 0.0], - [0.324, 0.949, 0.0], - [0.329, 0.852, 0.0]], - [[0.329, 0.852, 0.0], - [0.334, 0.77, 0.0], - [0.348, 0.771, 0.0], + data = [[[0.375, 0.763, 0.0], + [0.402, 0.755, 0.0], + [0.408, 0.754, 0.0], + [0.462, 0.751, 0.0]], + [[0.462, 0.751, 0.0], + [0.486, 0.75, 0.0], + [0.49, 0.757, 0.0], + [0.489, 0.767, 0.0]], + [[0.489, 0.767, 0.0], + [0.481, 0.908, 0.0], + [0.451, 0.943, 0.0], + [0.374, 0.97, 0.0]], + [[0.374, 0.97, 0.0], + [0.354, 0.977, 0.0], + [0.341, 0.975, 0.0], + [0.338, 0.972, 0.0]], + [[0.338, 0.972, 0.0], + [0.325, 0.958, 0.0], + [0.324, 0.949, 0.0], + [0.329, 0.852, 0.0]], + [[0.329, 0.852, 0.0], + [0.334, 0.77, 0.0], + [0.348, 0.771, 0.0], [0.375, 0.763, 0.0]]] - + return(data) # return the shape that belongs to the given event def map_mouse_event(event): shape = False - + if event == 'LEFTMOUSE': shape = "left_button" elif event == 'MIDDLEMOUSE': shape = "middle_button" elif event == 'RIGHTMOUSE': shape = "right_button" + elif event == 'WHEELDOWNMOUSE': + shape = "middle_down_button" + elif event == 'WHEELUPMOUSE': + shape = "middle_up_button" + return(shape) @@ -387,34 +404,38 @@ bl_description = "Display keys pressed in the 3D-view" last_activity = 'NONE' + _handle = None + _timer = None + def modal(self, context, event): if context.area: context.area.tag_redraw() - sc = context.scene + + if event.type == 'TIMER': + # no input, so no need to change the display + return {'PASS_THROUGH'} + + scene = context.scene # keys that shouldn't show up in the 3d-view mouse_keys = ['MOUSEMOVE','MIDDLEMOUSE','LEFTMOUSE', 'RIGHTMOUSE', 'WHEELDOWNMOUSE','WHEELUPMOUSE'] ignore_keys = ['LEFT_SHIFT', 'RIGHT_SHIFT', 'LEFT_ALT', 'RIGHT_ALT', 'LEFT_CTRL', 'RIGHT_CTRL', 'TIMER'] - if sc.screencast_keys_mouse != 'text': + if scene.screencast_keys_mouse != 'text': ignore_keys.extend(mouse_keys) - - #if (event.value != "NOTHING" and event.value != "PRESS"): - # print (event.value, event.type, "Previous activity was: ", self.last_activity) - - if event.value == 'PRESS' or (event.value == 'RELEASE' and self.last_activity == 'KEYBOARD' and event.type in mouse_keys ) : + if event.value == 'PRESS' or (event.value == 'RELEASE' and \ + self.last_activity == 'KEYBOARD' and event.type in mouse_keys): # add key-press to display-list sc_keys = [] - if event.ctrl: sc_keys.append("Ctrl ") if event.alt: sc_keys.append("Alt ") if event.shift: sc_keys.append("Shift ") - + sc_amount = "" if self.key: @@ -430,39 +451,40 @@ sc_amount = " x2" del self.key[0] del self.time[0] - + if event.type not in ignore_keys: #print("Recorded as key") sc_keys.append(event.type) self.key.insert(0, "+ ".join(sc_keys) + sc_amount) self.time.insert(0, time.time()) - - elif event.type in mouse_keys and sc.screencast_keys_mouse == 'icon': + + elif event.type in mouse_keys and \ + scene.screencast_keys_mouse == 'icon': #print("Recorded as mouse press") self.mouse.insert(0, event.type) - self.mouse_time.insert(0, time.time()) + self.mouse_time.insert(0, time.time()) if event.type in mouse_keys: self.last_activity = 'MOUSE' else: self.last_activity = 'KEYBOARD' #print("Last activity set to:", self.last_activity) - + if not context.window_manager.screencast_keys_keys: # stop script + context.window_manager.event_timer_remove(self._timer) context.region.callback_remove(self._handle) return {'CANCELLED'} return {'PASS_THROUGH'} - def cancel(self, context): if context.window_manager.screencast_keys_keys: + context.window_manager.event_timer_remove(self._timer) context.region.callback_remove(self._handle) context.window_manager.screencast_keys_keys = False return {'CANCELLED'} - def invoke(self, context, event): if context.area.type == 'VIEW_3D': if context.window_manager.screencast_keys_keys == False: @@ -475,6 +497,8 @@ self.mouse_time = [] self._handle = context.region.callback_add(draw_callback_px, (self, context), 'POST_PIXEL') + self._timer = context.window_manager.event_timer_add(0.05, + context.window) return {'RUNNING_MODAL'} else: # operator is called again, stop displaying @@ -491,62 +515,52 @@ # properties used by the script def init_properties(): - - sc = bpy.types.Scene + scene = bpy.types.Scene wm = bpy.types.WindowManager - sc.screencast_keys_pos_x = bpy.props.IntProperty( - name="Pos X", - description="Margin on the x axis", - default=5, - min=0, - max=100) - - sc.screencast_keys_pos_y = bpy.props.IntProperty( - name="Pos Y", - description="Margin on the y axis", - default=10, - min=0, - max=100) - - sc.screencast_keys_font_size = bpy.props.IntProperty( - name="Font", - description="Fontsize", - default=20, min=10, max=150) - - sc.screencast_keys_mouse_size = bpy.props.IntProperty( - name="Mouse", - description="Mousesize", - default=60, min=10, max=150) - - - sc.screencast_keys_color = bpy.props.FloatVectorProperty( - name="Color", - description="Font color", - default=(1.0, 1.0, 1.0), - min=0, - max=1, - subtype='COLOR') - - sc.screencast_keys_mouse = bpy.props.EnumProperty( - items=(("none", "None", "Don't display mouse events"), - ("icon", "Icon", "Display graphical represenation of "\ - "the mouse"), - ("text", "Text", "Display mouse events as text lines")), - name="Mouse display", - description="Display mouse events", - default='text') - - sc.screencast_keys_link = bpy.props.BoolProperty( - name="Group Mouse & Text", - description = "Link mouse to text", - default = False) - - print ("Screencast Keys: initialized from AddOn default settings.") + scene.screencast_keys_pos_x = bpy.props.IntProperty( + name="Pos X", + description="Margin on the x axis", + default=5, + min=0, + max=100) + scene.screencast_keys_pos_y = bpy.props.IntProperty( + name="Pos Y", + description="Margin on the y axis", + default=10, + min=0, + max=100) + scene.screencast_keys_font_size = bpy.props.IntProperty( + name="Font", + description="Fontsize", + default=20, min=10, max=150) + scene.screencast_keys_mouse_size = bpy.props.IntProperty( + name="Mouse", + description="Mousesize", + default=60, min=10, max=150) + scene.screencast_keys_color = bpy.props.FloatVectorProperty( + name="Color", + description="Font color", + default=(1.0, 1.0, 1.0), + min=0, + max=1, + subtype='COLOR') + scene.screencast_keys_mouse = bpy.props.EnumProperty( + items=(("none", "None", "Don't display mouse events"), + ("icon", "Icon", "Display graphical represenation of "\ + "the mouse"), + ("text", "Text", "Display mouse events as text lines")), + name="Mouse display", + description="Display mouse events", + default='text') + scene.screencast_keys_link = bpy.props.BoolProperty( + name="Group Mouse & Text", + description = "Link mouse to text", + default = False) # Runstate initially always set to False # note: it is not stored in the Scene, but in window manager: - wm.screencast_keys_keys = bpy.props.BoolProperty(default=False) + wm.screencast_keys_keys = bpy.props.BoolProperty(default=False) # removal of properties when script is disabled @@ -569,19 +583,19 @@ bl_label = "Screencast Keys" bl_space_type = "VIEW_3D" bl_region_type = "UI" - + def draw(self, context): sc = context.scene wm = context.window_manager layout = self.layout - + if not wm.screencast_keys_keys: layout.operator("view3d.screencast_keys", text="Start display", icon='PLAY') else: layout.operator("view3d.screencast_keys", text="Stop display", icon='PAUSE') - + col = layout.column(align=True) row = col.row(align=True) row.prop(sc, "screencast_keys_pos_x") @@ -593,7 +607,7 @@ row.prop(sc, "screencast_keys_mouse", text="Mouse") row = col.row(align=True) row.prop(sc, "screencast_keys_link") - + layout.prop(sc, "screencast_keys_color") @@ -615,4 +629,3 @@ if __name__ == "__main__": register() - diff -Nru blender-2.61/release/scripts/addons/space_view3d_spacebar_menu.py blender-2.62/release/scripts/addons/space_view3d_spacebar_menu.py --- blender-2.61/release/scripts/addons/space_view3d_spacebar_menu.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/space_view3d_spacebar_menu.py 2012-02-15 19:43:32.000000000 +0000 @@ -805,8 +805,8 @@ layout.operator("view3d.select_circle") layout.separator() - layout.operator("object.select_all", text="Select/Deselect All") - layout.operator("object.select_inverse", text="Inverse") + layout.operator("object.select_all", text="Select/Deselect All").action = 'TOGGLE' + layout.operator("object.select_all", text="Inverse").action = 'INVERT' layout.operator("object.select_random", text="Random") layout.operator("object.select_mirror", text="Mirror") layout.operator("object.select_by_layer", text="Select All by Layer") @@ -831,8 +831,8 @@ layout.operator("view3d.select_circle") layout.separator() - layout.operator("mesh.select_all", text="Select/Deselect All") - layout.operator("mesh.select_inverse", text="Inverse") + layout.operator("mesh.select_all", text="Select/Deselect All").action = 'TOGGLE' + layout.operator("mesh.select_all", text="Inverse").action = 'INVERT' layout.separator() layout.operator("mesh.select_random", text="Random") @@ -881,8 +881,8 @@ layout.operator("view3d.select_circle") layout.separator() - layout.operator("curve.select_all", text="Select/Deselect All") - layout.operator("curve.select_inverse") + layout.operator("curve.select_all", text="Select/Deselect All").action = 'TOGGLE' + layout.operator("curve.select_all").action = 'INVERT' layout.operator("curve.select_random") layout.operator("curve.select_nth") layout.separator() @@ -937,8 +937,8 @@ layout.operator("view3d.select_border") layout.separator() - layout.operator("pose.select_all", text="Select/Deselect All") - layout.operator("pose.select_inverse", text="Inverse") + layout.operator("pose.select_all", text="Select/Deselect All").action = 'TOGGLE' + layout.operator("pose.select_all", text="Inverse").action = 'INVERT' layout.operator("pose.select_constraint_target", text="Constraint Target") layout.operator("pose.select_linked", text="Linked") @@ -1003,8 +1003,8 @@ layout.separator() - layout.operator("curve.select_all", text="Select/Deselect All") - layout.operator("curve.select_inverse") + layout.operator("curve.select_all", text="Select/Deselect All").action = 'TOGGLE' + layout.operator("curve.select_all").action = 'INVERT' layout.operator("curve.select_random") layout.operator("curve.select_nth") @@ -1028,7 +1028,7 @@ layout.separator() layout.operator("mball.select_all").action = 'TOGGLE' - layout.operator("mball.select_inverse_metaelems") + layout.operator("mball.select_all").action = 'INVERT' layout.operator("mball.select_random_metaelems") class VIEW3D_MT_edit_TK(bpy.types.Menu): @@ -1394,20 +1394,24 @@ bpy.utils.register_module(__name__) wm = bpy.context.window_manager - km = wm.keyconfigs.addon.keymaps.new(name='3D View', space_type='VIEW_3D') - kmi = km.keymap_items.new('wm.call_menu', 'SPACE', 'PRESS') - kmi.properties.name = "VIEW3D_MT_Space_Dynamic_Menu" + kc = wm.keyconfigs.addon + if kc: + km = kc.keymaps.new(name='3D View', space_type='VIEW_3D') + kmi = km.keymap_items.new('wm.call_menu', 'SPACE', 'PRESS') + kmi.properties.name = "VIEW3D_MT_Space_Dynamic_Menu" def unregister(): bpy.utils.unregister_module(__name__) wm = bpy.context.window_manager - km = wm.keyconfigs.addon.keymaps['3D View'] - for kmi in km.keymap_items: - if kmi.idname == 'wm.call_menu': - if kmi.properties.name == "VIEW3D_MT_Space_Dynamic_Menu": - km.keymap_items.remove(kmi) - break + kc = wm.keyconfigs.addon + if kc: + km = kc.addon.keymaps['3D View'] + for kmi in km.keymap_items: + if kmi.idname == 'wm.call_menu': + if kmi.properties.name == "VIEW3D_MT_Space_Dynamic_Menu": + km.keymap_items.remove(kmi) + break if __name__ == "__main__": register() diff -Nru blender-2.61/release/scripts/addons/system_blend_info.py blender-2.62/release/scripts/addons/system_blend_info.py --- blender-2.61/release/scripts/addons/system_blend_info.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/system_blend_info.py 2012-02-15 19:43:32.000000000 +0000 @@ -25,7 +25,6 @@ "author": "uselessdreamer", "version": (0,3), "blender": (2, 5, 9), - "api": 39685, "location": "Properties > Scene > Blend Info Panel", "description": "Show information about the .blend", "warning": "", diff -Nru blender-2.61/release/scripts/addons/system_demo_mode/__init__.py blender-2.62/release/scripts/addons/system_demo_mode/__init__.py --- blender-2.61/release/scripts/addons/system_demo_mode/__init__.py 2011-12-13 19:58:02.000000000 +0000 +++ blender-2.62/release/scripts/addons/system_demo_mode/__init__.py 2012-02-15 19:42:32.000000000 +0000 @@ -22,7 +22,6 @@ "name": "Demo Mode", "author": "Campbell Barton", "blender": (2, 5, 7), - "api": 35622, "location": "Demo Menu", "description": "Demo mode lets you select multiple blend files and loop over them.", "warning": "", @@ -174,7 +173,7 @@ layout.separator() sub = layout.column() - sub.active = (mode in ('AUTO', 'PLAY')) + sub.active = (mode in {'AUTO', 'PLAY'}) sub.label("Animate Settings:") sub.prop(self, "anim_cycles") sub.prop(self, "anim_time_min") @@ -183,7 +182,7 @@ layout.separator() sub = layout.column() - sub.active = (mode in ('AUTO', 'RENDER')) + sub.active = (mode in {'AUTO', 'RENDER'}) sub.label("Render Settings:") sub.prop(self, "display_render") diff -Nru blender-2.61/release/scripts/addons/system_property_chart.py blender-2.62/release/scripts/addons/system_property_chart.py --- blender-2.61/release/scripts/addons/system_property_chart.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/system_property_chart.py 2012-02-15 19:43:32.000000000 +0000 @@ -23,7 +23,6 @@ "author": "Campbell Barton (ideasman42)", "version": (0, 1), "blender": (2, 5, 7), - "api": 35622, "location": "Tool Shelf", "description": "Edit arbitrary selected properties for objects of the same type", "warning": "", diff -Nru blender-2.61/release/scripts/addons/texture_paint_layer_manager.py blender-2.62/release/scripts/addons/texture_paint_layer_manager.py --- blender-2.61/release/scripts/addons/texture_paint_layer_manager.py 2011-12-13 19:59:11.000000000 +0000 +++ blender-2.62/release/scripts/addons/texture_paint_layer_manager.py 2012-02-15 19:43:32.000000000 +0000 @@ -3,7 +3,6 @@ "author": "Michael Wiliamson", "version": (1, 0), "blender": (2, 5, 7), - "api": 35964, "location": "Texture Paint > Properties > Texture Paint Layers Panels", "description": "Adds a layer manager for image based texture slots in paint and quick add layer tools", "warning": "", diff -Nru blender-2.61/release/scripts/addons_contrib/add_mesh_beam_builder.py blender-2.62/release/scripts/addons_contrib/add_mesh_beam_builder.py --- blender-2.61/release/scripts/addons_contrib/add_mesh_beam_builder.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/add_mesh_beam_builder.py 2012-02-15 19:43:59.000000000 +0000 @@ -1,15 +1,36 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the 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. +# +# ##### END GPL LICENSE BLOCK ##### + bl_info = { "name": "Beam Builder", "description": "Creates various types of beams.", "author": "revolt_randy", - "version": (0, 1, 2), - "blender": (2, 5, 6), - "api": 35968, + "version": (0, 1, 3), + "blender": (2, 6, 0), "location": "View3D > Add > Mesh", "warning": "Currently under development.", - "wiki_url": "", - "tracker_url": "", + "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Add_Mesh/BeamBuilder", + "tracker_url": "https://projects.blender.org/tracker/index.php?func=detail&aid=26911", "category": "Add Mesh"} + +# +# Creates a rectangluar, 'C', 'L', 'T', or 'I' - type beam. +# # Version History # @@ -24,95 +45,60 @@ # (x,y,z). Added ability to taper beams as well. # Add 'L' - type beam # Add 'T' - type beam -# Add 'I' - type beam - -# Creates a rectangluar, or 'C', or 'L' or 'T' or 'I' - type beam. +# Add 'I' - type beam +# +# v0.1.3 - Updated to work with api r41226, including using object_utils.py - +# part of blender's bpy_extras scripts. This is what handles +# the 'align to view', 'location', & 'rotation' options in the +# toolshelf when creating mesh. Added wiki & tracker url. Fixed +# a few bugs & fixed some debug prints that were still printing +# to console. +# import bpy -import math -import mathutils -#import space_info - -# The following bit of code was taken from spindle.py -# a script by Campbell Barton that creates a spindle mesh. -# The script was found someplace at blender.org -# Code determines the align_matrix to align the new object to -def align_matrix(context): - loc = mathutils.Matrix.Translation(context.scene.cursor_location) - obj_align = context.user_preferences.edit.object_align - if (context.space_data.type == 'VIEW_3D' - and obj_align == 'VIEW'): - rot = context.space_data.region_3d.view_matrix.rotation_part().invert().resize4x4() - else: - rot = mathutils.Matrix() - align_matrix = loc * rot - return align_matrix +from bpy_extras import object_utils -def create_mesh (name, verts, faces, align_matrix): + +def create_mesh (self, context, name, verts, faces, debug): # Creates mesh and object # name - name of object to create # verts - a list of vertex tuples # faces - a list of face tuples - # align_matrix - alignment of the mesh based on user prefs - see above code - - # Check if in edit mode, if so, get name of active object and enter object mode - if bpy.context.mode == 'EDIT_MESH': - # toggle to object mode - bpy.ops.object.editmode_toggle() - # get name of active object - obj_act = bpy.context.scene.objects.active - #print ("\n\nTRAP WORKS", "\nactive object =", obj_act) - else: - obj_act = False - - # Unselect any objects - bpy.ops.object.select_all(action="DESELECT") - + # debug - debug flag - if true prints data to console + # Actually create mesh and object mesh = bpy.data.meshes.new(name) - obj = bpy.data.objects.new(name, mesh) # add verts & faces to object mesh.from_pydata(verts, [], faces) - mesh.update(calc_edges=True) + mesh.update(calc_edges=True) - # Move object to 3d cursor & align - #obj.location = bpy.context.scene.cursor_location - obj.matrix_world = align_matrix - - # link object to scene - bpy.context.scene.objects.link(obj) - - #print(obj_act, obj) - - # Were we in edit mode - if so need to join new mesh to active mesh object - if obj_act: - bpy.ops.object.select_all(action="DESELECT") - # Select first object - obj_act.select = True - # Select new object - obj.select = True - # Join objects - bpy.ops.object.join() - - #print("\n\n2nd TRAP Works") + if debug: + print("create_mesh function called and finished") + + return object_utils.object_data_add(context, mesh, operator=self) - else: - # Not in edit mode, so just make new object active object - bpy.context.scene.objects.active = obj - obj.select = True - - # Enter edit mode - bpy.ops.object.editmode_toggle() + +def recalc_normals(debug): + # Recalculate normals + # parts of this script creates faces that are backwards or + # have thier normals facing the wrong way, so recalculate them + # debug - debug flag - if true prints data to console - # Recalcuate normals - bpy.ops.mesh.normals_make_consistent() - # Return to object mode if mesh created in object mode - if not obj_act: + if bpy.context.mode != 'EDIT_MESH': bpy.ops.object.editmode_toggle() - + # Recalcuate normals + bpy.ops.mesh.normals_make_consistent() + bpy.ops.object.editmode_toggle() + if debug: + print("\nObjectMode") + else: + bpy.ops.mesh.normals_make_consistent() + if debug: + print("\nEditMode") + return @@ -233,9 +219,8 @@ if debug: print ("\ncalc_end_verts Function Starts\n") - - print("\nsize = ",size) - print("y_off = ",y_off) + print("\nsize = ",size) + print("y_off = ",y_off) # Create vertices by calculation x_pos = 0 + size[0]/2 @@ -297,7 +282,7 @@ # This function corrects vertex locations to properly shape the # beam, because creating a c beam uses the same code as the - # create_multi_side_box function does. Therefore the 5th & 6th + # create_rectangular_beam function does. Therefore the 5th & 6th # vertice's z location needs to be changed to match the 1st & 2nd # vertice's z location. @@ -312,8 +297,7 @@ # get value of 5th vert vert_temp = verts[4] - print ("vert_orig = ",vert_orig[0]) - print ("vert_x = ",vert_x) + # calculate the amount of taper, updating vert_x # with the new value calculated. @@ -322,6 +306,9 @@ vert_new = (vert_x,vert_temp[1],vert_z) if debug: + print ("\nadjust_c_beam_verts function starting") + print ("vert_orig = ",vert_orig[0]) + print ("vert_x = ",vert_x) print("vert_temp =",vert_temp) print("vert_new =",vert_new) @@ -338,8 +325,7 @@ # get value of 5th vert vert_temp = verts[5] - print ("vert_orig = ",vert_orig[0]) - print ("vert_x = ",vert_x) + # calculate the amount of taper, updating vert_x # with the new value calculated. @@ -348,6 +334,8 @@ vert_new = (vert_x,vert_temp[1],vert_z) if debug: + print ("vert_orig = ",vert_orig[0]) + print ("vert_x = ",vert_x) print("vert_temp =",vert_temp) print("vert_new =",vert_new) @@ -478,7 +466,7 @@ return verts_final, faces_final -def create_U_beam(size, thick, taper, debug): +def create_C_beam(size, thick, taper, debug): # Creates a C or U shaped mesh beam object # size - tuple of x,y,z dimensions of beam # thick - thickness, the amount the inner faces will be @@ -492,11 +480,10 @@ # print debug info to console if debug: - print ("\ncreate_U_beam - function called") + print ("\ncreate_C_beam - function called") # Get y offset of vertices from center y_off = size[1] / 2 - print("\n y_off =",y_off) # Create temporarylists to hold vertices locations verts_front_temp=[] @@ -508,25 +495,22 @@ # needed because the calc_end_verts creates a rectangluar beam # the insides are inset, for a U channel we need the inside # verts on the open end to match the z-loc of the outside verts - verts_front_temp = adjust_c_beam_verts(verts_front_temp, taper, 1) - print("\n front verts =",verts_front_temp) + verts_front_temp = adjust_c_beam_verts(verts_front_temp, taper, debug) # recalculate y_off for other end vertices y_off = 0 - y_off - print("\n y_off =",y_off) # Create back vertices by calculation verts_back_temp = calc_end_verts(size, y_off, thick, debug) # Additional adjustment to the verts needed - the z location - verts_back_temp = adjust_c_beam_verts(verts_back_temp, taper, debug) - print("\n back verts =",verts_back_temp) + verts_back_temp = adjust_c_beam_verts(verts_back_temp, taper, debug) # Combine all vertices into a final list of tuples verts_final = verts_front_temp + verts_back_temp # Print debug info to console if debug: - print("\ncreate_U_beam function start") + print("\ncreate_C_beam function start") print("\n Front vertices :", verts_front_temp) print("\n Back vertices:", verts_back_temp) print("\n All vertices:", verts_final) @@ -585,9 +569,9 @@ # Print debug info to console if debug: - print("\ncreate_U_beam function") + print("\ncreate_C_beam function") print("\nAll faces =", faces_final) - print("\ncreate_c_beam function ending") + print("\ncreate_C_beam function ending") return verts_final, faces_final @@ -955,7 +939,7 @@ bl_idname = "mesh.primitive_rectangle_add" bl_label = "Add Rectangluar Beam" - bl_description = "Create a Rectangular Beam mesh." + bl_description = "Create a Rectangular Beam mesh" bl_options = {'REGISTER', 'UNDO'} mesh_z_size = bpy.props.FloatProperty(name = "Height(z)", @@ -986,8 +970,23 @@ max = 1, default = 0.1) - align_matrix = mathutils.Matrix() - + # generic transform props + # required by object_utils.py - part of blender's + # code and is what handles alignment amongst other + # things. + view_align = bpy.props.BoolProperty( + name="Align to View", + default=False + ) + location = bpy.props.FloatVectorProperty( + name="Location", + subtype='TRANSLATION', + ) + rotation = bpy.props.FloatVectorProperty( + name="Rotation", + subtype='EULER', + ) + # Define tool parameter layout def draw(self, context): layout = self.layout @@ -995,7 +994,12 @@ layout.prop(self, 'mesh_x_size') layout.prop(self, 'mesh_y_size') layout.prop(self, 'thick_bool') - layout.prop(self, 'thick') + if self.thick_bool: + layout.prop(self, 'thick') + layout.prop(self, 'view_align') + col = layout.column() + col.prop(self, 'location') + col.prop(self, 'rotation') def execute(self, context): # debug flag - True prints debug info to console @@ -1013,14 +1017,18 @@ print("\nCreated Verts:", verts) print("\nCreated Faces:", faces) - create_mesh("Rectangular Beam", verts, faces, self.align_matrix) + create_mesh(self, context, "Rectangular Beam", verts, faces, debug) + + recalc_normals(debug) return {'FINISHED'} +''' def invoke(self, context, event): - self.align_matrix = align_matrix(context) + #self.align_matrix = align_matrix(context) self.execute(context) return {'FINISHED'} +''' # Define "Add_C_Beam" operator @@ -1028,7 +1036,7 @@ bl_idname = "mesh.primitive_c_beam_add" bl_label = "Add C or U Channel" - bl_description = "Create a C or U channel mesh." + bl_description = "Create a C or U channel mesh" bl_options = {'REGISTER', 'UNDO'} @@ -1064,9 +1072,24 @@ type = bpy.props.BoolProperty(name = "U-shaped", description = "Create the beam in a U orientation rather than the defualt C orientation", - default = False) + default = True) - align_matrix = mathutils.Matrix() + # generic transform props + # required by object_utils.py - part of blender's + # code and is what handles alignment amongst other + # things. + view_align = bpy.props.BoolProperty( + name="Align to View", + default=False + ) + location = bpy.props.FloatVectorProperty( + name="Location", + subtype='TRANSLATION', + ) + rotation = bpy.props.FloatVectorProperty( + name="Rotation", + subtype='EULER', + ) # Define tool parameter layout def draw(self, context): @@ -1077,6 +1100,11 @@ layout.prop(self, 'thick') layout.prop(self, 'taper') layout.prop(self, 'type') + layout.prop(self, 'view_align') + col = layout.column() + col.prop(self, 'location') + col.prop(self, 'rotation') + def execute(self, context): # debug flag - True prints debug info to console @@ -1085,37 +1113,38 @@ # if type == true beam is U chanel, otherwise it's a C if self.type: size = (self.mesh_x_size, self.mesh_y_size, self.mesh_z_size) + mesh_name = "U Beam" else: size = (self.mesh_z_size, self.mesh_y_size, self.mesh_x_size) - - verts, faces = create_U_beam(size, self.thick, self.taper, debug) - + mesh_name = "C Beam" + + verts, faces = create_C_beam(size, self.thick, self.taper, debug) + if debug: print("\nCreated Verts:", verts) print("\nCreated Faces:", faces) - create_mesh("C Beam", verts, faces, self.align_matrix) + create_mesh(self, context, mesh_name, verts, faces, debug) + recalc_normals(debug) + if not self.type: # C-type beam is actually created as a u-type beam # so rotate 90 degrees on y-axis to make a c-type - # and apply rotation & location to reset those values - # and reset object origin to 3d cursor if self.type is false. + # and apply rotation to reset those values # if self.type is true, do nothing as beam is alreay u-type. # rotation value is in radians bpy.ops.transform.rotate(value=[1.570796], constraint_axis=[False, True, False]) - bpy.ops.object.rotation_clear() - bpy.ops.object.location_clear() - bpy.ops.object.origin_set(type="ORIGIN_CURSOR") - # The above code might not work right if rotation set to view - # Need to test further! + bpy.ops.object.transform_apply(location=False, rotation =True, scale=False) return {'FINISHED'} +''' def invoke(self, context, event): - self.align_matrix = align_matrix(context) + #self.align_matrix = align_matrix(context) self.execute(context) return {'FINISHED'} +''' # Define "Add_L_Beam" operator @@ -1123,7 +1152,7 @@ bl_idname = "mesh.primitive_l_beam_add" bl_label = "Add L Beam" - bl_description = "Create a L shaped mesh." + bl_description = "Create a L shaped mesh" bl_options = {'REGISTER', 'UNDO'} mesh_z_size = bpy.props.FloatProperty(name = "Height(z)", @@ -1156,7 +1185,22 @@ max = 100, default = 0) - align_matrix = mathutils.Matrix() + # generic transform props + # required by object_utils.py - part of blender's + # code and is what handles alignment amongst other + # things. + view_align = bpy.props.BoolProperty( + name="Align to View", + default=False + ) + location = bpy.props.FloatVectorProperty( + name="Location", + subtype='TRANSLATION', + ) + rotation = bpy.props.FloatVectorProperty( + name="Rotation", + subtype='EULER', + ) # Define tool parameter layout def draw(self, context): @@ -1166,6 +1210,11 @@ layout.prop(self, 'mesh_y_size') layout.prop(self, 'thick') layout.prop(self, 'taper') + layout.prop(self, 'view_align') + col = layout.column() + col.prop(self, 'location') + col.prop(self, 'rotation') + def execute(self, context): # debug flag - True prints debug info to console @@ -1179,14 +1228,18 @@ print("\nCreated Verts:", verts) print("\nCreated Faces:", faces) - create_mesh("L Beam", verts, faces, self.align_matrix) + create_mesh(self, context, "L Beam", verts, faces, debug) + + recalc_normals(debug) return {'FINISHED'} +''' def invoke(self, context, event): self.align_matrix = align_matrix(context) self.execute(context) return {'FINISHED'} +''' # Define "Add_T_Beam" operator @@ -1194,7 +1247,7 @@ bl_idname = "mesh.primitive_t_beam_add" bl_label = "Add T Beam" - bl_description = "Create a T shaped mesh." + bl_description = "Create a T shaped mesh" bl_options = {'REGISTER', 'UNDO'} mesh_z_size = bpy.props.FloatProperty(name = "Height(z)", @@ -1227,7 +1280,22 @@ max = 100, default = 0) - align_matrix = mathutils.Matrix() + # generic transform props + # required by object_utils.py - part of blender's + # code and is what handles alignment amongst other + # things. + view_align = bpy.props.BoolProperty( + name="Align to View", + default=False + ) + location = bpy.props.FloatVectorProperty( + name="Location", + subtype='TRANSLATION', + ) + rotation = bpy.props.FloatVectorProperty( + name="Rotation", + subtype='EULER', + ) # Define tool parameter layout def draw(self, context): @@ -1237,6 +1305,11 @@ layout.prop(self, 'mesh_y_size') layout.prop(self, 'thick') layout.prop(self, 'taper') + layout.prop(self, 'view_align') + col = layout.column() + col.prop(self, 'location') + col.prop(self, 'rotation') + def execute(self, context): # debug flag - True prints debug info to console @@ -1250,14 +1323,18 @@ print("\nCreated Verts:", verts) print("\nCreated Faces:", faces) - create_mesh("T Beam", verts, faces, self.align_matrix) + create_mesh(self, context, "T Beam", verts, faces, debug) + + recalc_normals(debug) return {'FINISHED'} +''' def invoke(self, context, event): self.align_matrix = align_matrix(context) self.execute(context) return {'FINISHED'} +''' # Define "Add_I_Beam" operator @@ -1265,7 +1342,7 @@ bl_idname = "mesh.primitive_i_beam_add" bl_label = "Add I Beam" - bl_description = "Create a I shaped mesh." + bl_description = "Create a I shaped mesh" bl_options = {'REGISTER', 'UNDO'} mesh_z_size = bpy.props.FloatProperty(name = "Height(z)", @@ -1298,7 +1375,22 @@ max = 100, default = 0) - align_matrix = mathutils.Matrix() + # generic transform props + # required by object_utils.py - part of blender's + # code and is what handles alignment amongst other + # things. + view_align = bpy.props.BoolProperty( + name="Align to View", + default=False + ) + location = bpy.props.FloatVectorProperty( + name="Location", + subtype='TRANSLATION', + ) + rotation = bpy.props.FloatVectorProperty( + name="Rotation", + subtype='EULER', + ) # Define tool parameter layout def draw(self, context): @@ -1308,6 +1400,11 @@ layout.prop(self, 'mesh_y_size') layout.prop(self, 'thick') layout.prop(self, 'taper') + layout.prop(self, 'view_align') + col = layout.column() + col.prop(self, 'location') + col.prop(self, 'rotation') + def execute(self, context): # debug flag - True prints debug info to console @@ -1321,14 +1418,19 @@ print("\nCreated Verts:", verts) print("\nCreated Faces:", faces) - create_mesh("I Beam", verts, faces, self.align_matrix) + create_mesh(self, context, "I Beam", verts, faces, debug) + + recalc_normals(debug) return {'FINISHED'} + +''' def invoke(self, context, event): self.align_matrix = align_matrix(context) self.execute(context) return {'FINISHED'} +''' # Register all operators and define menus diff -Nru blender-2.61/release/scripts/addons_contrib/add_mesh_column.py blender-2.62/release/scripts/addons_contrib/add_mesh_column.py --- blender-2.61/release/scripts/addons_contrib/add_mesh_column.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/add_mesh_column.py 2012-02-15 19:43:59.000000000 +0000 @@ -28,7 +28,6 @@ "author": "Jim Bates, jambay", "version": (0, 11), "blender": (2, 5, 7), - "api": 36339, "location": "View3D > Add > Mesh > Columns", "description": "Add architectural column(s).", "warning": "WIP - Initial implementation; updates pending and API not final for Blender", diff -Nru blender-2.61/release/scripts/addons_contrib/add_mesh_rocks/__init__.py blender-2.62/release/scripts/addons_contrib/add_mesh_rocks/__init__.py --- blender-2.61/release/scripts/addons_contrib/add_mesh_rocks/__init__.py 2011-12-13 19:59:37.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/add_mesh_rocks/__init__.py 2012-02-15 19:43:57.000000000 +0000 @@ -36,8 +36,7 @@ "name": "Rock Generator", "author": "Paul Marshall (brikbot)", "version": (1, 3), - "blender": (2, 6, 0), - "api": 41875, + "blender": (2, 6, 1), "location": "View3D > Add > Rock Generator", "description": "Adds a mesh rock to the Add Mesh menu", "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5"\ diff -Nru blender-2.61/release/scripts/addons_contrib/add_mesh_stairs/general.py blender-2.62/release/scripts/addons_contrib/add_mesh_stairs/general.py --- blender-2.61/release/scripts/addons_contrib/add_mesh_stairs/general.py 2011-12-13 19:59:34.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/add_mesh_stairs/general.py 2012-02-15 19:43:54.000000000 +0000 @@ -9,16 +9,16 @@ # # Paul "BrikBot" Marshall # Created: September 19, 2011 -# Last Modified: September 20, 2011 +# Last Modified: January 29, 2011 # Homepage (blog): http://post.darkarsenic.com/ # //blog.darkarsenic.com/ # -# Coded in IDLE, tested in Blender 2.59. +# Coded in IDLE, tested in Blender 2.61. # Search for "@todo" to quickly find sections that need work. # # ##### BEGIN GPL LICENSE BLOCK ##### # -# The Blender Rock Creation tool is for rapid generation of mesh rocks in Blender. +# Stairbuilder is for quick stair generation. # Copyright (C) 2011 Paul Marshall # # This program is free software: you can redistribute it and/or modify diff -Nru blender-2.61/release/scripts/addons_contrib/add_mesh_stairs/__init__.py blender-2.62/release/scripts/addons_contrib/add_mesh_stairs/__init__.py --- blender-2.61/release/scripts/addons_contrib/add_mesh_stairs/__init__.py 2011-12-13 19:59:34.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/add_mesh_stairs/__init__.py 2012-02-15 19:43:54.000000000 +0000 @@ -31,8 +31,7 @@ "name": "StairBuilder", "author": "Nick van Adium", "version": (1,1), - "blender": (2, 6, 0), - "api": 41875, + "blender": (2, 6, 1), "location": "View3D > Add > Stairs", "description": "Creates a straight-run staircase with railings and stringer", "warning": "Add-on is very feature incomplete beyond basic functionality.", diff -Nru blender-2.61/release/scripts/addons_contrib/add_mesh_stairs/post.py blender-2.62/release/scripts/addons_contrib/add_mesh_stairs/post.py --- blender-2.61/release/scripts/addons_contrib/add_mesh_stairs/post.py 2011-12-13 19:59:34.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/add_mesh_stairs/post.py 2012-02-15 19:43:54.000000000 +0000 @@ -9,16 +9,16 @@ # # Paul "BrikBot" Marshall # Created: September 19, 2011 -# Last Modified: September 20, 2011 +# Last Modified: January 29, 2011 # Homepage (blog): http://post.darkarsenic.com/ # //blog.darkarsenic.com/ # -# Coded in IDLE, tested in Blender 2.59. +# Coded in IDLE, tested in Blender 2.61. # Search for "@todo" to quickly find sections that need work. # # ##### BEGIN GPL LICENSE BLOCK ##### # -# The Blender Rock Creation tool is for rapid generation of mesh rocks in Blender. +# Stairbuilder is for quick stair generation. # Copyright (C) 2011 Paul Marshall # # This program is free software: you can redistribute it and/or modify diff -Nru blender-2.61/release/scripts/addons_contrib/add_mesh_stairs/rail.py blender-2.62/release/scripts/addons_contrib/add_mesh_stairs/rail.py --- blender-2.61/release/scripts/addons_contrib/add_mesh_stairs/rail.py 2011-12-13 19:59:34.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/add_mesh_stairs/rail.py 2012-02-15 19:43:54.000000000 +0000 @@ -9,16 +9,16 @@ # # Paul "BrikBot" Marshall # Created: September 19, 2011 -# Last Modified: September 20, 2011 +# Last Modified: January 29, 2011 # Homepage (blog): http://post.darkarsenic.com/ # //blog.darkarsenic.com/ # -# Coded in IDLE, tested in Blender 2.59. +# Coded in IDLE, tested in Blender 2.61. # Search for "@todo" to quickly find sections that need work. # # ##### BEGIN GPL LICENSE BLOCK ##### # -# The Blender Rock Creation tool is for rapid generation of mesh rocks in Blender. +# Stairbuilder is for quick stair generation. # Copyright (C) 2011 Paul Marshall # # This program is free software: you can redistribute it and/or modify diff -Nru blender-2.61/release/scripts/addons_contrib/add_mesh_stairs/retainer.py blender-2.62/release/scripts/addons_contrib/add_mesh_stairs/retainer.py --- blender-2.61/release/scripts/addons_contrib/add_mesh_stairs/retainer.py 2011-12-13 19:59:34.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/add_mesh_stairs/retainer.py 2012-02-15 19:43:54.000000000 +0000 @@ -9,16 +9,16 @@ # # Paul "BrikBot" Marshall # Created: September 19, 2011 -# Last Modified: September 20, 2011 +# Last Modified: January 29, 2011 # Homepage (blog): http://post.darkarsenic.com/ # //blog.darkarsenic.com/ # -# Coded in IDLE, tested in Blender 2.59. +# Coded in IDLE, tested in Blender 2.61. # Search for "@todo" to quickly find sections that need work. # # ##### BEGIN GPL LICENSE BLOCK ##### # -# The Blender Rock Creation tool is for rapid generation of mesh rocks in Blender. +# Stairbuilder is for quick stair generation. # Copyright (C) 2011 Paul Marshall # # This program is free software: you can redistribute it and/or modify diff -Nru blender-2.61/release/scripts/addons_contrib/add_mesh_stairs/stairbuilder.py blender-2.62/release/scripts/addons_contrib/add_mesh_stairs/stairbuilder.py --- blender-2.61/release/scripts/addons_contrib/add_mesh_stairs/stairbuilder.py 2011-12-13 19:59:34.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/add_mesh_stairs/stairbuilder.py 2012-02-15 19:43:54.000000000 +0000 @@ -44,7 +44,27 @@ # - "T" staircase # # Last Modified By: Paul "brikbot" Marshall -# Last Modification: November 20, 2011 +# Last Modification: January 29, 2011 +# +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# Stairbuilder is for quick stair generation. +# Copyright (C) 2011 Paul Marshall +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (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, see . +# +# ##### END GPL LICENSE BLOCK ##### #----------------------------------------------------------- # BEGIN NEW B2.5/Py3.2 CODE @@ -110,15 +130,17 @@ rad1 = FloatProperty(name = "Inner Radius", description = "Inner radius for circular staircase", min = 0.0, max = 1024.0, - default = 0.2) + soft_max = 10.0, + default = 0.25) rad2 = FloatProperty(name = "Outer Radius", description = "Outer radius for circular staircase", - min = 0.0001, max = 1024.0001, - default = 0.5) - deg = IntProperty(name = "Degrees", - description = "Degrees per step", - min = 5, max = 45, step = 5, - default = 20) + min = 0.0, max = 1024.0, + soft_min = 0.015625, soft_max = 32.0, + default = 1.0) + deg = FloatProperty(name = "Degrees", + description = "Number of degrees the stairway rotates", + min = 0.0, max = 92160.0, step = 5.0, + default = 450.0) center = BoolProperty(name = "Center Pillar", description = "Generate a central pillar", default = False) @@ -166,6 +188,12 @@ description = "Number of cross section supports", min = 2, max = 1024, default = 4) + #special circular tread properties: + tread_slc = IntProperty(name = "Slices", + description = "Number of slices each tread is composed of", + min = 1, max = 1024, + soft_max = 16, + default = 4) #for posts make_posts = BoolProperty(name = "Make Posts", @@ -294,14 +322,15 @@ box = layout.box() box.prop(self, 'make_treads') if self.make_treads: - if not self.use_original: + if not self.use_original and self.typ != "id4": box.prop(self, 'typ_t') else: self.typ_t = "tId1" - box.prop(self, 'tread_w') + if self.typ != "id4": + box.prop(self, 'tread_w') box.prop(self, 'tread_h') box.prop(self, 'tread_t') - if self.typ != "id2": + if self.typ not in ["id2", "id4"]: box.prop(self, 'tread_o') else: self.tread_o = 0.0 @@ -313,6 +342,8 @@ box.prop(self, 'tread_sp') if self.typ_t in ["tId3", "tId4", "tId5"]: box.prop(self, 'tread_sn') + elif self.typ == "id4": + box.prop(self, "tread_slc") # Posts box = layout.box() @@ -384,21 +415,39 @@ run = self.run G=General(rise,run,self.tread_n) if self.make_treads: - Treads(G, - typ, - typ_t, - run, - self.tread_w, - self.tread_h, - self.run, - self.rise, - self.tread_t, - self.tread_o, - self.tread_n, - self.tread_tk, - self.tread_sec, - self.tread_sp, - self.tread_sn) + if typ != "id4": + Treads(G, + typ, + typ_t, + run, + self.tread_w, + self.tread_h, + self.run, + self.rise, + self.tread_t, + self.tread_o, + self.tread_n, + self.tread_tk, + self.tread_sec, + self.tread_sp, + self.tread_sn) + else: + Treads(G, + typ, + typ_t, + self.deg, + self.rad2, + self.tread_h, + self.run, + self.rise, + self.tread_t, + self.rad1, + self.tread_n, + self.tread_tk, + self.tread_sec, + self.tread_sp, + self.tread_sn, + self.tread_slc) if self.make_posts and (self.rEnable or self.lEnable): Posts(G, rise, @@ -468,6 +517,27 @@ self.string_tp, not self.string_g, 1, False, False) + elif typ == "id4": + Stringer(G, + typ, + typ_s, + rise, + self.deg, + self.string_w, + self.string_h, + self.tread_n, + self.tread_h, + self.rad2 - self.rad1, + self.tread_t, + self.rad1, + self.string_tw, + self.string_tf, + self.string_tp, + not self.string_g, + self.string_n, + self.string_dis, + self.use_original, + self.tread_slc) else: Stringer(G, typ, diff -Nru blender-2.61/release/scripts/addons_contrib/add_mesh_stairs/stringer.py blender-2.62/release/scripts/addons_contrib/add_mesh_stairs/stringer.py --- blender-2.61/release/scripts/addons_contrib/add_mesh_stairs/stringer.py 2011-12-13 19:59:34.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/add_mesh_stairs/stringer.py 2012-02-15 19:43:54.000000000 +0000 @@ -13,16 +13,16 @@ # # Paul "BrikBot" Marshall # Created: September 19, 2011 -# Last Modified: November 20, 2011 +# Last Modified: January 29, 2011 # Homepage (blog): http://post.darkarsenic.com/ # //blog.darkarsenic.com/ # -# Coded in IDLE, tested in Blender 2.59. +# Coded in IDLE, tested in Blender 2.61. # Search for "@todo" to quickly find sections that need work. # # ##### BEGIN GPL LICENSE BLOCK ##### # -# The Blender Rock Creation tool is for rapid generation of mesh rocks in Blender. +# Stairbuilder is for quick stair generation. # Copyright (C) 2011 Paul Marshall # # This program is free software: you can redistribute it and/or modify @@ -40,18 +40,19 @@ # # ##### END GPL LICENSE BLOCK ##### -from math import atan, cos, tan -from mathutils import Vector +from math import atan, cos, radians, tan +from mathutils import Matrix, Vector from mathutils.geometry import (intersect_line_plane, intersect_line_line) class Stringer: - def __init__(self,G,typ,typ_s,rise,run,w,h,nT,hT,wT,tT,tO,tw,tf,tp,g,nS=1,dis=False,notMulti=True): + def __init__(self,G,typ,typ_s,rise,run,w,h,nT,hT,wT,tT,tO,tw,tf,tp,g, + nS=1,dis=False,notMulti=True,deg=4): self.G = G #General self.typ = typ # Stair type self.typ_s = typ_s # Stringer type self.rise = rise #Stair rise - self.run = run #Stair run + self.run = run #Stair run. Degrees if self.typ == "id4" if notMulti: self.w = w / 100 #stringer width else: @@ -61,13 +62,14 @@ self.hT = hT #tread height self.wT = wT #tread width self.tT = tT #tread toe - self.tO = tO #Tread overhang + self.tO = tO #Tread overhang. Inner radius if self.typ == "id4" self.tw = self.w * (tw / 100) #stringer web thickness self.tf = tf #stringer flange thickness self.tp = 1 - (tp / 100) #stringer flange taper self.g = g #does stringer intersect the ground? self.nS = nS #number of stringers self.dis = dis #Use distributed stringers + self.deg = deg #number of sections per "slice". Only applys if self.typ == "id4" # Default stringer object (classic / sId1): self.faces1=[[0,1,3,2],[1,5,3],[3,5,4],[6,7,9,8],[7,11,9],[9,11,10], [0,2,8,6],[0,1,7,6],[1,5,11,7],[2,3,9,8],[3,4,10,9],[4,5,11,10]] @@ -86,19 +88,22 @@ [6,7,15,14],[7,0,8,15],[0,1,6,7],[1,2,5,6],[2,3,4,5],[8,9,14,15], [9,10,13,14],[10,11,12,13]] # I-beam stringer (id3 / sId2 / Taper < 100%): - self.faces3c=[[0,1,2,7],[2,3,6,7],[3,4,5,6],[1,2,23,16],[2,3,22,23],[3,4,21,22], - [16,17,18,23],[18,19,22,23],[19,20,21,22],[17,8,15,18],[18,15,14,19], - [19,14,13,20],[8,9,10,15],[10,11,14,15],[11,12,13,14],[9,10,53,52], - [10,11,54,53],[11,12,55,54],[52,53,61,60],[53,54,62,61],[54,55,63,62], - [60,61,34,33],[61,62,35,34],[62,63,36,35],[32,33,34,39],[34,35,38,39], - [35,36,37,38],[41,32,39,42],[42,39,38,43],[43,38,37,44],[40,41,42,47], - [42,43,46,47],[43,44,45,46],[25,26,47,40],[26,27,46,47],[27,28,45,46], - [24,25,26,31],[26,27,30,31],[27,28,29,30],[24,31,57,56],[31,30,58,57], - [30,29,59,58],[48,49,57,56],[49,50,58,57],[50,51,59,58],[0,7,49,48], - [7,6,50,49],[6,5,51,50],[0,1,16,48],[16,40,56,48],[24,25,40,56], - [16,17,41,40],[8,9,52,17],[17,52,60,41],[32,33,60,41],[12,13,20,55], - [20,44,63,55],[37,44,63,36],[20,21,45,44],[28,29,51,21],[21,51,59,45], - [28,45,59,29],[4,5,51,21]] + self.faces3c=[[0,1,2,7],[2,3,6,7],[3,4,5,6],[1,2,23,16],[2,3,22,23], + [3,4,21,22],[16,17,18,23],[18,19,22,23],[19,20,21,22], + [17,8,15,18],[18,15,14,19],[19,14,13,20],[8,9,10,15], + [10,11,14,15],[11,12,13,14],[9,10,53,52],[10,11,54,53], + [11,12,55,54],[52,53,61,60],[53,54,62,61],[54,55,63,62], + [60,61,34,33],[61,62,35,34],[62,63,36,35],[32,33,34,39], + [34,35,38,39],[35,36,37,38],[41,32,39,42],[42,39,38,43], + [43,38,37,44],[40,41,42,47],[42,43,46,47],[43,44,45,46], + [25,26,47,40],[26,27,46,47],[27,28,45,46],[24,25,26,31], + [26,27,30,31],[27,28,29,30],[24,31,57,56],[31,30,58,57], + [30,29,59,58],[48,49,57,56],[49,50,58,57],[50,51,59,58], + [0,7,49,48],[7,6,50,49],[6,5,51,50],[0,1,16,48],[16,40,56,48], + [24,25,40,56],[16,17,41,40],[8,9,52,17],[17,52,60,41], + [32,33,60,41],[12,13,20,55],[20,44,63,55],[37,44,63,36], + [20,21,45,44],[28,29,51,21],[21,51,59,45],[28,45,59,29], + [4,5,51,21]] # C-beam stringer (id3 / sId3 / Taper < 100%): self.faces4c=[[0,1,2,7],[2,3,6,7],[3,4,5,6],[1,2,23,16],[2,3,22,23],[3,4,21,22], [16,17,18,23],[18,19,22,23],[19,20,21,22],[17,8,15,18],[18,15,14,19], @@ -168,6 +173,49 @@ for j in range(4): coords.append(coords[j] + Vector([0,self.wT,0])) self.G.Make_mesh(coords, self.G.faces, 'stringer') + elif self.typ == "id4": + offset = (self.wT / (self.nS + 1)) - (self.w / 2) + for s in range(self.nS): + base = self.tO + (offset * (s + 1)) + start = [Vector([0, -base, -self.hT]), + Vector([0, -base, -self.hT - self.rise]), + Vector([0, -base - self.w, -self.hT]), + Vector([0, -base - self.w, -self.hT - self.rise])] + self.d = radians(self.run) / self.nT + for i in range(self.nT): + coords = [] + # Base faces. Should be able to append more sections: + tId4_faces = [[0, 1, 3, 2]] + t_inner = Matrix.Rotation(self.d * i, 3, 'Z') + coords.append((t_inner * start[0]) + Vector([0, 0, self.rise * i])) + coords.append((t_inner * start[1]) + Vector([0, 0, self.rise * i])) + t_outer = Matrix.Rotation(self.d * i, 3, 'Z') + coords.append((t_outer * start[2]) + Vector([0, 0, self.rise * i])) + coords.append((t_outer * start[3]) + Vector([0, 0, self.rise * i])) + k = 0 + for j in range(self.deg): + k = (j * 4) + 4 + tId4_faces.append([k, k - 4, k - 3, k + 1]) + tId4_faces.append([k - 2, k - 1, k + 3, k + 2]) + tId4_faces.append([k + 1, k - 3, k - 1, k + 3]) + tId4_faces.append([k, k - 4, k - 2, k + 2]) + rot = Matrix.Rotation(((self.d * (j + 1)) / self.deg) + (self.d * i), 3, 'Z') + for v in start: + coords.append((rot * v) + Vector([0, 0, self.rise * i])) + for j in range(self.deg): + k = ((j + self.deg) * 4) + 4 + tId4_faces.append([k, k - 4, k - 3, k + 1]) + tId4_faces.append([k - 2, k - 1, k + 3, k + 2]) + tId4_faces.append([k + 1, k - 3, k - 1, k + 3]) + tId4_faces.append([k, k - 4, k - 2, k + 2]) + rot = Matrix.Rotation(((self.d * ((j + self.deg) + 1)) / self.deg) + (self.d * i), 3, 'Z') + for v in range(4): + if v in [1, 3]: + incline = (self.rise * i) + (self.rise / self.deg) * (j + 1) + coords.append((rot * start[v]) + Vector([0, 0, incline])) + else: + coords.append((rot * start[v]) + Vector([0, 0, self.rise * i])) + self.G.Make_mesh(coords, tId4_faces, 'treads') return {'FINISHED'} diff -Nru blender-2.61/release/scripts/addons_contrib/add_mesh_stairs/tread.py blender-2.62/release/scripts/addons_contrib/add_mesh_stairs/tread.py --- blender-2.61/release/scripts/addons_contrib/add_mesh_stairs/tread.py 2011-12-13 19:59:34.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/add_mesh_stairs/tread.py 2012-02-15 19:43:54.000000000 +0000 @@ -15,16 +15,16 @@ # # Paul "BrikBot" Marshall # Created: September 19, 2011 -# Last Modified: September 20, 2011 +# Last Modified: January 26, 2012 # Homepage (blog): http://post.darkarsenic.com/ # //blog.darkarsenic.com/ # -# Coded in IDLE, tested in Blender 2.59. +# Coded in IDLE, tested in Blender 2.61. # Search for "@todo" to quickly find sections that need work. # # ##### BEGIN GPL LICENSE BLOCK ##### # -# The Blender Rock Creation tool is for rapid generation of mesh rocks in Blender. +# Stairbuilder is for quick stair generation. # Copyright (C) 2011 Paul Marshall # # This program is free software: you can redistribute it and/or modify @@ -42,22 +42,23 @@ # # ##### END GPL LICENSE BLOCK ##### +import mathutils from copy import copy -from math import sqrt -from mathutils import Vector +from math import radians, sqrt +from mathutils import Matrix, Vector class Treads: - def __init__(self,G,typ,typ_t,run,w,h,d,r,toe,o,n,tk,sec,sp,sn): + def __init__(self,G,typ,typ_t,run,w,h,d,r,toe,o,n,tk,sec,sp,sn,deg=4): self.G = G #General self.typ = typ #Stair type self.typ_t = typ_t #Tread type - self.run = run #Stair run - self.w=w #tread width + self.run = run #Stair run. Degrees if self.typ == "id4" + self.w=w #tread width. Is outer radius if self.typ == "id4" self.h=h #tread height - self.d=d #tread run + self.d=d #tread run. Ignore for now if self.typ == "id4" self.r=r #tread rise self.t=toe #tread nosing - self.o=o #tread side overhang + self.o=o #tread side overhang. Is inner radius if self.typ == "id4" self.n=n #number of treads self.tk=tk #thickness of tread metal self.sec=sec #metal sections for tread @@ -68,6 +69,7 @@ else: self.sp=0 self.sn=sn #number of cross sections + self.deg = deg #number of section per "slice". Only applys if self.typ == "id4" self.tId2_faces = [[0,1,2,3],[0,3,4,5],[4,5,6,7],[6,7,8,9],[8,9,10,11], [12,13,14,15],[12,15,16,17],[16,17,18,19], [18,19,20,21],[20,21,22,23],[0,1,13,12],[1,2,14,13], @@ -175,7 +177,7 @@ coords3.append(Vector([self.d - self.tk, baseY, height])) for i in range(4): coords3.append(coords3[i] + Vector([0, cW, 0])) - + # Make the treads: for i in range(self.n): if self.typ_t == "tId1": @@ -210,3 +212,31 @@ j += Vector([self.d, 0, self.r]) for j in coords: j += Vector([self.d,0,self.r]) + # Circular staircase: + elif self.typ in ["id4"]: + start = [Vector([0, -self.o, 0]), Vector([0, -self.o, -self.h]), + Vector([0, -self.w, 0]), Vector([0, -self.w, -self.h])] + self.d = radians(self.run) / self.n + for i in range(self.n): + coords = [] + # Base faces. Should be able to append more sections: + tId4_faces = [[0, 1, 3, 2]] + t_inner = Matrix.Rotation((-self.t / self.o) + (self.d * i), 3, 'Z') + coords.append((t_inner * start[0]) + Vector([0, 0, self.r * i])) + coords.append((t_inner * start[1]) + Vector([0, 0, self.r * i])) + t_outer = Matrix.Rotation((-self.t / self.w) + (self.d * i), 3, 'Z') + coords.append((t_outer * start[2]) + Vector([0, 0, self.r * i])) + coords.append((t_outer * start[3]) + Vector([0, 0, self.r * i])) + k = 0 + for j in range(self.deg + 1): + k = (j * 4) + 4 + tId4_faces.append([k, k - 4, k - 3, k + 1]) + tId4_faces.append([k - 2, k - 1, k + 3, k + 2]) + tId4_faces.append([k + 1, k - 3, k - 1, k + 3]) + tId4_faces.append([k, k - 4, k - 2, k + 2]) + rot = Matrix.Rotation(((self.d * j) / self.deg) + (self.d * i), 3, 'Z') + for v in start: + coords.append((rot * v) + Vector([0, 0, self.r * i])) + tId4_faces.append([k, k + 1, k + 3, k + 2]) + self.G.Make_mesh(coords, tId4_faces, 'treads') + return diff -Nru blender-2.61/release/scripts/addons_contrib/add_mesh_walls/Blocks.py blender-2.62/release/scripts/addons_contrib/add_mesh_walls/Blocks.py --- blender-2.61/release/scripts/addons_contrib/add_mesh_walls/Blocks.py 2011-12-13 19:59:25.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/add_mesh_walls/Blocks.py 2012-02-15 19:43:42.000000000 +0000 @@ -13,9 +13,9 @@ # 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 +# the Free Software Foundation Inc. +# 51 Franklin Street, Fifth Floor +# Boston, MA 02110-1301, USA # # or go online at: http://www.gnu.org/licenses/ to view license options. # @@ -49,35 +49,35 @@ #A few constants SMALL = 0.000000000001 -NOTZERO = 0.01 # for values that must be != 0; see UI options/variables - +NOTZERO = 0.01 # for values that must be != 0; see UI options/variables - # sort of a bug to be fixed. PI = math.pi #global variables #General masonry Settings -settings = {'w': 1.2, 'wv': 0.3, 'h': .6, 'hv': 0.3, 'd': 0.3, 'dv': 0.1, - 'g': 0.1, 'gv': 0.07, 'gd': 0.01, 'gdv': 0.0, 'b': 0, 'bv': 0, - 'f': 0.0, 'fv': 0.0, 't': 0.0, 'sdv': 0.1, 'hwt': 0.5, 'aln':0, - 'wm': 0.8, 'hm': 0.3, 'dm':0.1, - 'woff':0.0, 'woffv':0.0, 'eoff':0.3, 'eoffv':0.0, 'rwhl':1, +settings = {'w': 1.2, 'wv': 0.3, 'h': .6, 'hv': 0.3, 'd': 0.3, 'dv': 0.1, + 'g': 0.1, 'gv': 0.07, 'gd': 0.01, 'gdv': 0.0, 'b': 0, 'bv': 0, + 'f': 0.0, 'fv': 0.0, 't': 0.0, 'sdv': 0.1, 'hwt': 0.5, 'aln':0, + 'wm': 0.8, 'hm': 0.3, 'dm':0.1, + 'woff':0.0, 'woffv':0.0, 'eoff':0.3, 'eoffv':0.0, 'rwhl':1, 'hb':0, 'ht':0, 'ge':0, 'physics':0} -# 'w':width 'wv':widthVariation -# 'h':height 'hv':heightVariation +# 'w':width 'wv':widthVariation +# 'h':height 'hv':heightVariation # 'd':depth 'dv':depthVariation -# 'g':grout 'gv':groutVariation 'gd':groutDepth 'gdv':groutDepthVariation +# 'g':grout 'gv':groutVariation 'gd':groutDepth 'gdv':groutDepthVariation # 'b':bevel 'bv':bevelVariation -# 'f':flawSize 'fv':flawSizeVariation 'ff':flawFraction -# 't':taper +# 'f':flawSize 'fv':flawSizeVariation 'ff':flawFraction +# 't':taper # 'sdv':subdivision(distance or angle) -# 'hwt':row height effect on block widths in the row (0=no effect, +# 'hwt':row height effect on block widths in the row (0=no effect, # 1=1:1 relationship, negative values allowed, 0.5 works well) # 'aln':alignment(0=none, 1=rows w/features, 2=features w/rows) # (currently un-used) # 'wm':width minimum 'hm':height minimum 'dm':depth minimum -# 'woff':row start offset(fraction of width) +# 'woff':row start offset(fraction of width) # 'woffv':width offset variation(fraction of width) -# 'eoff':edge offset 'eoffv':edge offset variation +# 'eoff':edge offset 'eoffv':edge offset variation # 'rwhl':row height lock(1 is all blocks in row have same height) # 'hb':bottom row height 'ht': top row height 'ge': grout the edges # 'physics': set up for physics @@ -91,16 +91,16 @@ radialized = 0 # Radiating from one point - round/disc; instead of square slope = 0 # Warp/slope; curved over like a vaulted tunnel -# 'bigblock': merge adjacent blocks into single large blocks +# 'bigblock': merge adjacent blocks into single large blocks bigBlock = 0 # Merge blocks # Gaps in blocks for various apertures. #openingSpecs = [] -openingSpecs = [{'w':0.5, 'h':0.5, 'x':0.8, 'z':2.7, 'rp':1, 'b':0.0, +openingSpecs = [{'w':0.5, 'h':0.5, 'x':0.8, 'z':2.7, 'rp':1, 'b':0.0, 'v':0, 'vl':0, 't':0, 'tl':0}] -# 'w': opening width, 'h': opening height, -# 'x': horizontal position, 'z': vertical position, -# 'rp': make multiple openings, with a spacing of x, +# 'w': opening width, 'h': opening height, +# 'x': horizontal position, 'z': vertical position, +# 'rp': make multiple openings, with a spacing of x, # 'b': bevel the opening, inside only, like an arrow slit. # 'v': height of the top arch, 'vl':height of the bottom arch, # 't': thickness of the top arch, 'tl': thickness of the bottom arch @@ -115,7 +115,7 @@ # Add blocks to make steps. stepMod = 0 stepSpecs = {'x':0.0, 'z':-10, 'w':10.0, 'h':10.0, - 'v':0.7, 't':1.0, 'd':1.0 } + 'v':0.7, 't':1.0, 'd':1.0 } # 'x': horizontal start position, 'z': vertical start position, # 'w': step area width, 'h': step area height, # 'v': riser height, 't': tread width, 'd': block depth (step size; offset from wall) @@ -145,9 +145,9 @@ t = 0.3 + random() tl = 0.3 + random() rn = random()*2 - openingSpecs += [{'w':3.1 + rn, 'h':0.3 + rn, 'x':float(x), - 'z':float(z), 'rp':0, 'b':0., - 'v':float(v), 'vl':float(vl), + openingSpecs += [{'w':3.1 + rn, 'h':0.3 + rn, 'x':float(x), + 'z':float(z), 'rp':0, 'b':0., + 'v':float(v), 'vl':float(vl), 't':float(t), 'tl':float(tl)}] return dims, openingSpecs @@ -155,29 +155,29 @@ #For filling a linear space with divisions -def fill(left, right, avedst, mindst=0.0, dev=0.0, pad=(0.0,0.0), num=0, +def fill(left, right, avedst, mindst=0.0, dev=0.0, pad=(0.0,0.0), num=0, center=0): __doc__ = '''\ - Fills a linear range with points and returns an ordered list of those points - including the end points. + Fills a linear range with points and returns an ordered list of those points + including the end points. - left: the lower boundary - right: the upper boundary - avedst: the average distance between points - mindst: the minimum distance between points - dev: the maximum random deviation from avedst - pad: tends to move the points near the bounds right (positive) or - left (negative). - element 0 pads the lower bounds, element 1 pads the upper bounds - num: substitutes a numerical limit for the right limit. fill will then make - a num+1 element list - center: flag to center the elements in the range, 0 == disabled + left: the lower boundary + right: the upper boundary + avedst: the average distance between points + mindst: the minimum distance between points + dev: the maximum random deviation from avedst + pad: tends to move the points near the bounds right (positive) or + left (negative). + element 0 pads the lower bounds, element 1 pads the upper bounds + num: substitutes a numerical limit for the right limit. fill will then make + a num+1 element list + center: flag to center the elements in the range, 0 == disabled ''' poslist = [left] curpos = left+pad[0] - # Set offset by average spacing, then add blocks (fall through); + # Set offset by average spacing, then add blocks (fall through); # if not at right edge. if center: curpos += ((right-left-mindst*2)%avedst)/2+mindst @@ -205,8 +205,8 @@ # make block edges else: - while True: # loop for blocks - curpos += avedst+rndd()*dev + while True: # loop for blocks + curpos += avedst+rndd()*dev if curpos-poslist[-1] r: return None elif offs == r: return 0. @@ -371,11 +371,11 @@ #class openings in the wall class opening: __doc__ = """\ - This is the class for holding the data for the openings in the wall. - It has methods for returning the edges of the opening for any given position value, - as well as bevel settings and top and bottom positions. - It stores the 'style' of the opening, and all other pertinent information. - """ + This is the class for holding the data for the openings in the wall. + It has methods for returning the edges of the opening for any given position value, + as well as bevel settings and top and bottom positions. + It stores the 'style' of the opening, and all other pertinent information. + """ # x = 0. # x position of the opening # z = 0. # x position of the opening # w = 0. # width of the opening @@ -396,12 +396,12 @@ def btm(self): if self.vl <= self.w/2 : return self.z-self.h/2-self.vl-self.rtl - else: return self.z - sqrt((self.rl+self.rtl)**2 - (self.rl - self.w/2 )**2) - self.h/2 + else: return self.z - sqrt((self.rl+self.rtl)**2 - (self.rl - self.w/2 )**2) - self.h/2 def top(self): if self.v <= self.w/2 : return self.z+self.h/2+self.v+self.rt - else: return sqrt((self.r+self.rt)**2 - (self.r - self.w/2 )**2) + self.z + self.h/2 + else: return sqrt((self.r+self.rt)**2 - (self.r - self.w/2 )**2) + self.z + self.h/2 #crits returns the critical split points, or discontinuities, used for making rows @@ -497,14 +497,14 @@ dist = abs(self.x-ht) def radialAdjust(dist, sideVal): '''take the distance and adjust for radial geometry, return dist. - ''' + ''' if radialized: if slope: dist = dist * abs(dims['t']*sin(sideVal*PI/(dims['t']*2))) else: dist = dist * sideVal return dist - + if s > 0 :#and (dist <= self.edgeS(self.z+self.h/2+self.c,1)-self.x): #check top down #hack for radialized masonry, import approx Z instead of self.top() dist = radialAdjust(dist, self.top()) @@ -540,7 +540,7 @@ return None else: return self.z-self.h/2-circVal - #old conditional? if (dist-self.w/2+self.rl)<=(self.rl+self.rtl): + #old conditional? if (dist-self.w/2+self.rl)<=(self.rl+self.rtl): #domed arch on bottom else: circVal = circ(dist,self.rl+self.rtl) # dist-self.w/2+self.rl @@ -548,7 +548,7 @@ return None else: return self.z-self.h/2-self.vl+self.rl-circVal - # and this never happens - but, leave it as failsafe :) + # and this never happens - but, leave it as failsafe :) print("got all the way out of the edgeV! Not good!") print("opening x = ", self.x, ", opening z = ", self.z) return 0.0 @@ -622,10 +622,10 @@ #class rows in the wall class rowOb: __doc__ = """\ - This is the class for holding the data for individual rows of blocks. - each row is required to have some edge blocks, and can also have - intermediate sections of "normal" blocks. - """ + This is the class for holding the data for individual rows of blocks. + each row is required to have some edge blocks, and can also have + intermediate sections of "normal" blocks. + """ #z = 0. #h = 0. @@ -701,16 +701,16 @@ # def arch(ra,rt,x,z, archStart, archEnd, bevel, bevAngle, vll): __doc__ = '''\ - Makes a list of faces and vertexes for arches. - ra: the radius of the arch, to the center of the bricks - rt: the thickness of the arch - x: x center location of the circular arc, as if the arch opening were centered on x = 0 - z: z center location of the arch - anglebeg: start angle of the arch, in radians, from vertical? - angleend: end angle of the arch, in radians, from vertical? - bevel: how much to bevel the inside of the arch. - vll: how long is the vertex list already? - ''' + Makes a list of faces and vertexes for arches. + ra: the radius of the arch, to the center of the bricks + rt: the thickness of the arch + x: x center location of the circular arc, as if the arch opening were centered on x = 0 + z: z center location of the arch + anglebeg: start angle of the arch, in radians, from vertical? + angleend: end angle of the arch, in radians, from vertical? + bevel: how much to bevel the inside of the arch. + vll: how long is the vertex list already? + ''' avlist = [] aflist = [] @@ -728,11 +728,11 @@ SetDepthVar = settings['dv'] # Init loop variables - + def bevelEdgeOffset(offsets, bevel, side): ''' Take the block offsets and modify it for the correct bevel. - + offsets = the offset list. See MakeABlock bevel = how much to offset the edge side = -1 for left (right side), 1 for right (left side) @@ -773,7 +773,7 @@ geom = MakeABlock([divs[i]+grt, divs[i+1]-grt, ArchInner, ArchOuter, DepthBack, DepthFront], subdivision, len(avlist) + vll, ThisOffset, [], None, ra) - + avlist += geom[0] aflist += geom[1] @@ -802,9 +802,9 @@ # def sketch(): __doc__ = """\ - The 'sketch' function creates a list of openings from the general specifications passed to it. - It takes curved and domed walls into account, placing the openings at the appropriate angular locations - """ + The 'sketch' function creates a list of openings from the general specifications passed to it. + It takes curved and domed walls into account, placing the openings at the appropriate angular locations + """ boundlist = [] for x in openingSpecs: if x['rp']: @@ -829,12 +829,12 @@ def wedgeBlocks(row, opening, leftPos, rightPos, edgeBinary, r1): __doc__ = """\ - Makes wedge blocks for the left and right sides, depending - example: - wedgeBlocks(row, LeftWedgeEdge, LNerEdge, LEB, r1) - wedgeBlocks(row, RNerEdge, RightWedgeEdge, REB, r1) - """ - wedgeEdges = fill(leftPos, rightPos, settings['w']/r1, settings['wm']/r1, + Makes wedge blocks for the left and right sides, depending + example: + wedgeBlocks(row, LeftWedgeEdge, LNerEdge, LEB, r1) + wedgeBlocks(row, RNerEdge, RightWedgeEdge, REB, r1) + """ + wedgeEdges = fill(leftPos, rightPos, settings['w']/r1, settings['wm']/r1, settings['wv']/r1) for i in range(len(wedgeEdges)-1): @@ -872,12 +872,12 @@ def bevelBlockOffsets(offsets, bevel, side): ''' - Take the block offsets and modify it for the correct bevel. - + Take the block offsets and modify it for the correct bevel. + offsets = the offset list. See MakeABlock bevel = how much to offset the edge side = -1 for left (right side), 1 for right (left side) - ''' + ''' # left = (4,6) # right = (0,2) if side == 1: pointsToAffect = (0,2) # right @@ -888,8 +888,8 @@ def rowProcessing(row, Thesketch, WallBoundaries): __doc__ = """\ - Take row and opening data and process a single row, adding edge and fill blocks to the row data. - """ + Take row and opening data and process a single row, adding edge and fill blocks to the row data. + """ #set end blocks #check for openings, record top and bottom of row for right and left of each #if both top and bottom intersect create blocks on each edge, appropriate to the size of the overlap @@ -980,7 +980,7 @@ LFarEdge = LTop #The furthest edge left LNerEdge = LBtm #the nearer edge left LEB = 1 #Left Edge Boolean, set to 1 if furthest edge is top, -1 if it is bottom - else: + else: LFarEdge = LBtm LNerEdge = LTop LEB = -1 @@ -990,7 +990,7 @@ RNerEdge = RBtm #the nearer edge right REB = 1 #Right Edge Boolean, set to 1 if furthest edge is top, -1 if it is bottom - else: + else: RFarEdge = RBtm #The furthest edge right RNerEdge = RTop REB = -1 #Right Edge Boolean, set to 1 if furthest edge is top, -1 if it is bottom @@ -1041,7 +1041,7 @@ ThisBlockDepth = rndd()*settings['dv']+settings['d'] BtmOff = LBtm - LNerEdge TopOff = LTop - LNerEdge - ThisBlockOffsets = [[BtmOff,0,0]]*2 + [[TopOff,0,0]]*2 + ThisBlockOffsets = [[BtmOff,0,0]]*2 + [[TopOff,0,0]]*2 BtmOff = RBtm - RNerEdge TopOff = RTop - RNerEdge ThisBlockOffsets += [[BtmOff,0,0]]*2 + [[TopOff,0,0]]*2 @@ -1051,7 +1051,7 @@ bevelBlockOffsets(ThisBlockOffsets, bevel, -1) row.BlocksEdge.append([x,row.z,w,row.h,ThisBlockDepth,ThisBlockOffsets]) continue - + # it's not one block, must be two or more # set up the offsets for the left BtmOff = LBtm - LNerEdge @@ -1069,7 +1069,7 @@ if (InnerDiff < MaxWid*2): #this row is just two blocks! Left block, then right block #div is the x position of the dividing point between the two bricks - div = InnerMid + (rndd()*settings['wv'])/r1 + div = InnerMid + (rndd()*settings['wv'])/r1 #set the grout distance, since we need grout seperation between the blocks grt = (settings['g'] + rndc()*settings['gv'])/r1 #set the x position and width for the left block @@ -1123,12 +1123,12 @@ def plan(Thesketch, oldrows = 0): __doc__ = """\ - The 'plan' function takes the data generated by the sketch function and the global settings - and creates a list of blocks. - It passes out a list of row heights, edge positions, edge blocks, and rows of blocks. - """ + The 'plan' function takes the data generated by the sketch function and the global settings + and creates a list of blocks. + It passes out a list of row heights, edge positions, edge blocks, and rows of blocks. + """ # if we were passed a list of rows already, use those; else make a list. - if oldrows: rows = oldrows + if oldrows: rows = oldrows else: #rows holds the important information common to all rows #rows = [list of row objects] @@ -1209,16 +1209,16 @@ def archGeneration(hole, vlist, flist, sideSign): __doc__ = """\ - Makes arches for the top and bottom, depending on sideSign - example, Lower arch: - archGeneration(hole, vlist, flist, -1) - example, Upper arch: - archGeneration(hole, vlist, flist, 1) + Makes arches for the top and bottom, depending on sideSign + example, Lower arch: + archGeneration(hole, vlist, flist, -1) + example, Upper arch: + archGeneration(hole, vlist, flist, 1) hole is the opening object that the arch is for add the verticies to vlist add the faces to flist sideSign is + or - 1, for the top or bottom arch. Other values may cause errors. - """ + """ # working arrays for vectors and faces avlist = [] @@ -1360,7 +1360,7 @@ topSide = zstart btmSide = zstart-height # Do some stuff to incorporate bev here - bevelBlockOffsets(offsets, bev, -1) + bevelBlockOffsets(offsets, bev, -1) avlist,aflist = MakeABlock([x-xstart-width, x-xstart- woffset, btmSide, topSide, -depth/2, depth/2], subdivision, len(vlist), Offsets=offsets, xBevScl=1) @@ -1372,11 +1372,11 @@ flist += aflist # keep sizing same - neat arches = master masons :) -# grt = (settings['g'] + rndc()*settings['gv']) -# height = c - grt*(0.5 + c/(width + grt)) +# grt = (settings['g'] + rndc()*settings['gv']) +# height = c - grt*(0.5 + c/(width + grt)) # if grout varies may as well change width too... width = sqrt(rt**2 - c**2) - grt -# voff = sideSign * (settings['hm'] - height) -# woffset = width*(settings['hm'] + grt/2)/(c - grt/2) +# voff = sideSign * (settings['hm'] - height) +# woffset = width*(settings['hm'] + grt/2)/(c - grt/2) if sideSign == 1: offsets = [[0]*3]*2 + [[0]*2 + [voff]]*2 + [[0]*3]*4 @@ -1402,12 +1402,12 @@ def build(Aplan): __doc__ = """\ - Build creates the geometry for the wall, based on the - "Aplan" object from the "plan" function. If physics is - enabled, then it make a number of individual blocks with - physics interaction enabled. Otherwise it creates - geometry for the blocks, arches, etc. of the wall. - """ + Build creates the geometry for the wall, based on the + "Aplan" object from the "plan" function. If physics is + enabled, then it make a number of individual blocks with + physics interaction enabled. Otherwise it creates + geometry for the blocks, arches, etc. of the wall. + """ vlist = [] flist = [] @@ -1416,40 +1416,40 @@ #dead code... #Physics setup is horribly broken. Revisit when new API is in place. '''if False: #settings['physics']: - geom = MakeABlock([-0.5,0.5,-0.5,0.5,-0.5,0.5], 3, 0, None,[], 3*settings['b']/(settings['w'] + settings['h'] + settings['d'])) - blockmesh = Blender.Mesh.New('block') - vlist += geom[0] - flist += geom[1] - blockmesh.verts.extend(vlist) - blockmesh.faces.extend(flist) - - for block in Aplan[1]: - x,z,w,h,d = block[:5] - block = scn.objects.new(blockmesh, 'block') - block.loc = [x, 0, z] - block.size = [w,d,h] - block.rbFlags = Blender.Object.RBFlags['BOUNDS'] | Blender.Object.RBFlags['ACTOR'] | Blender.Object.RBFlags['DYNAMIC'] | Blender.Object.RBFlags['RIGIDBODY'] - block.rbShapeBoundType = Blender.Object.RBShapes['BOX'] - - - for row in Aplan[2]:#row=[xstart,xend,z,h] - #currently, radial geometry is disabled for physics blocks setup - if radialized: - if slope: r1 = dims['t']*sin(row[2]*PI/(dims['t']*2)) - else: r1 = row[2] - - else: r1 = 1 - - divs = fill(row[0], row[1], settings['w'], settings['wm'], settings['wv']) - for i in range(len(divs)-1): - block = scn.objects.new(blockmesh, 'block') - block.loc = [(divs[i]+divs[i+1])/2, 0, row[2]] - block.size = [(divs[i + 1] - divs[i]) - settings['g'], (settings['d'] + rndd()*settings['dv'])*(1-settings['t']*((row[3]-dims['b'])/(dims['t'] - dims['b']))), row[3]] - block.rbFlags = Blender.Object.RBFlags['BOUNDS'] | Blender.Object.RBFlags['ACTOR'] | Blender.Object.RBFlags['DYNAMIC'] | Blender.Object.RBFlags['RIGIDBODY'] - block.rbShapeBoundType = Blender.Object.RBShapes['BOX'] + geom = MakeABlock([-0.5,0.5,-0.5,0.5,-0.5,0.5], 3, 0, None,[], 3*settings['b']/(settings['w'] + settings['h'] + settings['d'])) + blockmesh = Blender.Mesh.New('block') + vlist += geom[0] + flist += geom[1] + blockmesh.verts.extend(vlist) + blockmesh.faces.extend(flist) + + for block in Aplan[1]: + x,z,w,h,d = block[:5] + block = scn.objects.new(blockmesh, 'block') + block.loc = [x, 0, z] + block.size = [w,d,h] + block.rbFlags = Blender.Object.RBFlags['BOUNDS'] | Blender.Object.RBFlags['ACTOR'] | Blender.Object.RBFlags['DYNAMIC'] | Blender.Object.RBFlags['RIGIDBODY'] + block.rbShapeBoundType = Blender.Object.RBShapes['BOX'] - return None''' -#end dead code... + + for row in Aplan[2]:#row=[xstart,xend,z,h] + #currently, radial geometry is disabled for physics blocks setup + if radialized: + if slope: r1 = dims['t']*sin(row[2]*PI/(dims['t']*2)) + else: r1 = row[2] + + else: r1 = 1 + + divs = fill(row[0], row[1], settings['w'], settings['wm'], settings['wv']) + for i in range(len(divs)-1): + block = scn.objects.new(blockmesh, 'block') + block.loc = [(divs[i]+divs[i+1])/2, 0, row[2]] + block.size = [(divs[i + 1] - divs[i]) - settings['g'], (settings['d'] + rndd()*settings['dv'])*(1-settings['t']*((row[3]-dims['b'])/(dims['t'] - dims['b']))), row[3]] + block.rbFlags = Blender.Object.RBFlags['BOUNDS'] | Blender.Object.RBFlags['ACTOR'] | Blender.Object.RBFlags['DYNAMIC'] | Blender.Object.RBFlags['RIGIDBODY'] + block.rbShapeBoundType = Blender.Object.RBShapes['BOX'] + + return None''' +#end dead code... # all the edge blocks, redacted #AllBlocks = [[x,z,w,h,d,[corner offset matrix]],[etc.]] @@ -1499,7 +1499,7 @@ else: idxThat -= 1 # - # + # # Add blocks to create a "shelf/platform". # Does not account for openings (crosses gaps - which is a good thing) if shelfExt: @@ -1526,7 +1526,7 @@ else: ShelfOffsets = [[0,-wallDepth,0],[0,-ShelfThk/2,0],[0,-wallDepth,0],[0,-ShelfThk/2,0],[0,-wallDepth,0],[0,-ShelfThk/2,0],[0,-wallDepth,0],[0,-ShelfThk/2,0]] - # Add blocks for each "shelf row" in area + # Add blocks for each "shelf row" in area while ShelfBtm < ShelfTop: # Make blocks for each row - based on rowOb::fillblocks @@ -1542,7 +1542,7 @@ ShelfBtm += SetBH + SetGrtOff # moving up to next row... # - # + # # Add blocks to create "steps". # Does not account for openings (crosses gaps - which is a good thing) if stepMod: @@ -1571,7 +1571,7 @@ else: StepOffsets = [[0,-wallDepth,0],[0,-StepThk/2,0],[0,-wallDepth,0],[0,-StepThk/2,0],[0,-wallDepth,0],[0,-StepThk/2,0],[0,-wallDepth,0],[0,-StepThk/2,0]] - # Add steps for each "step row" in area (neg width is interesting but prevented) + # Add steps for each "step row" in area (neg width is interesting but prevented) while StepBtm < StepTop and StepWide > 0: # Make blocks for each step row - based on rowOb::fillblocks @@ -1650,8 +1650,8 @@ def createWall(radial, curve, openings, mergeBlox, shelf, shelfSide, steps, stepDir, stepBare, stepSide): __doc__ = """\ - Call all the funcitons you need to make a wall, return the verts and faces. - """ + Call all the funcitons you need to make a wall, return the verts and faces. + """ global radialized global slope global openingSpecs diff -Nru blender-2.61/release/scripts/addons_contrib/add_mesh_walls/__init__.py blender-2.62/release/scripts/addons_contrib/add_mesh_walls/__init__.py --- blender-2.61/release/scripts/addons_contrib/add_mesh_walls/__init__.py 2011-12-13 19:59:25.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/add_mesh_walls/__init__.py 2012-02-15 19:43:42.000000000 +0000 @@ -24,9 +24,8 @@ bl_info = { "name": "WallFactory", "author": "Jambay, Brikbot", - "version": (0, 59), - "blender": (2, 5, 9), - "api": 40077, + "version": (0, 6, 0), + "blender": (2, 6, 1), "location": "View3D > Add > Mesh", "description": "Adds a block/rock wall.", "warning": "WIP - updates pending and API not final for Blender", diff -Nru blender-2.61/release/scripts/addons_contrib/animation_motion_trail.py blender-2.62/release/scripts/addons_contrib/animation_motion_trail.py --- blender-2.61/release/scripts/addons_contrib/animation_motion_trail.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/animation_motion_trail.py 2012-02-15 19:43:59.000000000 +0000 @@ -22,9 +22,8 @@ bl_info = { 'name': "Motion Trail", 'author': "Bart Crouch", - 'version': (3, 1, 0), - 'blender': (2, 6, 0), - 'api': 42181, + 'version': (3, 1, 1), + 'blender': (2, 6, 1), 'location': "View3D > Toolbar > Motion Trail tab", 'warning': "", 'description': "Display and edit motion trails in the 3d-view", @@ -849,7 +848,8 @@ if kf.co[0] == frame: if side == "left": # change handle type, if necessary - if kf.handle_left_type in ['AUTO', 'ANIM_CLAMPED']: + if kf.handle_left_type in ['AUTO', 'AUTO_CLAMPED', + 'ANIM_CLAMPED']: kf.handle_left_type = 'ALIGNED' elif kf.handle_left_type == 'VECTOR': kf.handle_left_type = 'FREE' @@ -857,7 +857,7 @@ kf.handle_left[1] = handles_ori[objectname][frame]\ ["left"][i][1] + d[i] if kf.handle_left_type in ['ALIGNED', 'ANIM_CLAMPED', - 'AUTO']: + 'AUTO', 'AUTO_CLAMPED']: dif = (abs(handles_ori[objectname][frame]["right"]\ [i][0] - kf.co[0]) / abs(kf.handle_left[0] - \ kf.co[0])) * d[i] @@ -865,7 +865,8 @@ [frame]["right"][i][1] - dif elif side == "right": # change handle type, if necessary - if kf.handle_right_type in ['AUTO', 'ANIM_CLAMPED']: + if kf.handle_right_type in ['AUTO', 'AUTO_CLAMPED', + 'ANIM_CLAMPED']: kf.handle_left_type = 'ALIGNED' kf.handle_right_type = 'ALIGNED' elif kf.handle_right_type == 'VECTOR': @@ -875,7 +876,7 @@ kf.handle_right[1] = handles_ori[objectname][frame]\ ["right"][i][1] + d[i] if kf.handle_right_type in ['ALIGNED', 'ANIM_CLAMPED', - 'AUTO']: + 'AUTO', 'AUTO_CLAMPED']: dif = (abs(handles_ori[objectname][frame]["left"]\ [i][0] - kf.co[0]) / abs(kf.handle_right[0] - \ kf.co[0])) * d[i] @@ -1267,13 +1268,14 @@ if kf.co[0] == frame: # align if necessary if side in ["right", "both"] and new_type in \ - ["AUTO", "ALIGNED"]: + ["AUTO", "AUTO_CLAMPED", "ALIGNED"]: # change right handle normal = (kf.co - kf.handle_left).normalized() size = (kf.handle_right[0] - kf.co[0]) / normal[0] normal = normal*size + kf.co kf.handle_right[1] = normal[1] - elif side == "left" and new_type in ["AUTO", "ALIGNED"]: + elif side == "left" and new_type in ["AUTO", "AUTO_CLAMPED", + "ALIGNED"]: # change left handle normal = (kf.co - kf.handle_right).normalized() size = (kf.handle_left[0] - kf.co[0]) / normal[0] @@ -1624,8 +1626,8 @@ handle_type_action_ob = bpy.props.StringProperty() handle_type_child = bpy.props.StringProperty() handle_type_old = bpy.props.EnumProperty(items=(("AUTO", "", ""), - ("VECTOR", "", ""), ("ALIGNED", "", ""), ("FREE", "", "")), - default='AUTO',) + ("AUTO_CLAMPED", "", ""), ("VECTOR", "", ""), ("ALIGNED", "", ""), + ("FREE", "", "")), default='AUTO',) # visible in user interface calculate = bpy.props.EnumProperty(name="Calculate", @@ -1646,6 +1648,7 @@ update=internal_update) handle_type = bpy.props.EnumProperty(name="Type", items=(("AUTO", "Automatic", ""), + ("AUTO_CLAMPED", "Auto Clamped", ""), ("VECTOR", "Vector", ""), ("ALIGNED", "Aligned", ""), ("FREE", "Free", "")), diff -Nru blender-2.61/release/scripts/addons_contrib/btrace/bTrace.py blender-2.62/release/scripts/addons_contrib/btrace/bTrace.py --- blender-2.61/release/scripts/addons_contrib/btrace/bTrace.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/btrace/bTrace.py 2012-02-15 19:43:39.000000000 +0000 @@ -0,0 +1,1114 @@ +#BEGIN GPL LICENSE BLOCK + +#This program is free software; you can redistribute it and/or +#modify it under the terms of the 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#END GPL LICENCE BLOCK + +bl_info = { + 'name': "bTrace", + 'author': "liero, crazycourier, Atom, Meta-Androcto, MacKracken", + 'version': (1, 1, ), + 'blender': (2, 61, 1), + 'location': "View3D > Tools", + 'description': "Tools for converting/animating objects/particles into curves", + 'warning': "Still under development, bug reports appreciated", + 'wiki_url': "", + 'tracker_url': "http://projects.blender.org/tracker/?func=detail&atid=468&aid=29563&group_id=153", + 'category': "Mesh" + } + +#### TO DO LIST #### +### [ ] Add more options to curve radius/modulation plus cyclic/connect curve option + +import bpy, selection_utils +from bpy.props import FloatProperty, EnumProperty, IntProperty, BoolProperty + +# Class to define properties +class TracerProperties(bpy.types.PropertyGroup): + enabled = IntProperty(default=0) + # Object Curve Settings + curve_spline = EnumProperty(name="Spline", items=(("POLY", "Poly", "Use Poly spline type"), ("NURBS", "Nurbs", "Use Nurbs spline type"), ("BEZIER", "Bezier", "Use Bezier spline type")), description="Choose which type of spline to use when curve is created", default="BEZIER") + curve_handle = EnumProperty(name="Handle", items=(("ALIGNED", "Aligned", "Use Aligned Handle Type"), ("AUTOMATIC", "Automatic", "Use Auto Handle Type"), ("FREE_ALIGN", "Free Align", "Use Free Handle Type"), ("VECTOR", "Vector", "Use Vector Handle Type")), description="Choose which type of handle to use when curve is created", default="VECTOR") + curve_resolution = IntProperty(name="Bevel Resolution" , min=1, max=32, default=4, description="Adjust the Bevel resolution") + curve_depth = FloatProperty(name="Bevel Depth", min=0.0, max=100.0, default=0.125, description="Adjust the Bevel depth") + curve_u = IntProperty(name="Resolution U", min=0, max=64, default=12, description="Adjust the Surface resolution") + curve_join = BoolProperty(name="Join Curves", default=False, description="Join all the curves after they have been created") + curve_smooth = BoolProperty(name="Smooth", default=True, description="Render curve smooth") + # Option to Duplicate Mesh + object_duplicate = BoolProperty(name="Apply to Copy", default=False, description="Apply curve to a copy of object") + # Distort Mesh options + distort_modscale = IntProperty(name="Modulation Scale", min=0, max=50, default=2, description="Add a scale to modulate the curve at random points, set to 0 to disable") + distort_noise = FloatProperty(name="Mesh Noise", min=0.0, max=50.0, default=0.00, description="Adjust noise added to mesh before adding curve") + # Particle Options + particle_step = IntProperty(name="Step Size", min=1, max=50, default=5, description="Sample one every this number of frames") + particle_auto = BoolProperty(name='Auto Frame Range', default=True, description='Calculate Frame Range from particles life') + particle_f_start = IntProperty( name='Start Frame', min=1, max=5000, default=1, description='Start frame') + particle_f_end = IntProperty( name='End Frame', min=1, max=5000, default=250, description='End frame') + # F-Curve Modifier Properties + fcnoise_rot = BoolProperty(name="Rotation", default=False, description="Affect Rotation") + fcnoise_loc = BoolProperty(name="Location", default=True, description="Affect Location") + fcnoise_scale = BoolProperty(name="Scale", default=False, description="Affect Scale") + fcnoise_amp = IntProperty(name="Amp", min=1, max=500, default=5, description="Adjust the amplitude") + fcnoise_timescale = FloatProperty(name="Time Scale", min=1, max=500, default=50, description="Adjust the time scale") + fcnoise_key = BoolProperty(name="Add Keyframe", default=True, description="Keyframe is needed for tool, this adds a LocRotScale keyframe") + # Toolbar Settings/Options Booleans + curve_settings = BoolProperty(name="Curve Settings", default=False, description="Change the settings for the created curve") + particle_settings = BoolProperty(name="Particle Settings", default=False, description="Show the settings for the created curve") + animation_settings = BoolProperty(name="Animation Settings", default=False, description="Show the settings for the Animations") + distort_curve = BoolProperty(name="Add Distortion", default=False, description="Set options to distort the final curve") + connect_noise = BoolProperty(name="F-Curve Noise", default=False, description="Adds F-Curve Noise Modifier to selected objects") + settings_objectTrace = BoolProperty(name="Object Trace Settings", default=False, description="Trace selected mesh object with a curve") + settings_objectsConnect = BoolProperty(name="Objects Connect Settings", default=False, description="Connect objects with a curve controlled by hooks") + respect_order = BoolProperty(name="Order", default=False, description="Remember order objects were selected") + settings_particleTrace = BoolProperty(name="Particle Trace Settings", default=False, description="Trace particle path with a curve") + settings_particleConnect = BoolProperty(name="Particle Connect Settings", default=False, description="Connect particles with a curves and animated over particle lifetime") + settings_growCurve = BoolProperty(name="Grow Curve Settings", default=False, description="Animate curve bevel over time by keyframing points radius") + settings_fcurve = BoolProperty(name="F-Curve Settings", default=False, description="F-Curve Settings") + # Toolbar Tool show/hide booleans + tool_objectTrace = BoolProperty(name="Object Trace", default=False, description="Trace selected mesh object with a curve") + tool_objectsConnect = BoolProperty(name="Objects Connect", default=False, description="Connect objects with a curve controlled by hooks") + tool_particleTrace = BoolProperty(name="Particle Trace", default=False, description="Trace particle path with a curve") + tool_particleConnect = BoolProperty(name="Particle Connect", default=False, description="Connect particles with a curves and animated over particle lifetime") + tool_growCurve = BoolProperty(name="Grow Curve", default=False, description="Animate curve bevel over time by keyframing points radius") + tool_handwrite = BoolProperty(name="Handwriting", default=False, description="Create and Animate curve using the grease pencil") + tool_fcurve = BoolProperty(name="F-Curve Noise", default=False, description="Add F-Curve noise to selected objects") + # Animation Options + anim_auto = BoolProperty(name='Auto Frame Range', default=True, description='Automatically calculate Frame Range') + anim_f_start = IntProperty(name='Start', min=1, max=2500, default=1, description='Start frame / Hidden object') + anim_length = IntProperty(name='Duration', min=1, soft_max=1000, max=2500, default=100, description='Animation Length') + anim_f_fade = IntProperty(name='Fade After', min=0, soft_max=250, max=2500, default=10, description='Fade after this frames / Zero means no fade') + anim_delay = IntProperty(name='Grow', min=0, max=50, default=5, description='Frames it takes a point to grow') + anim_tails = BoolProperty(name='Tails', default=True, description='Set radius to zero for open splines endpoints') + anim_keepr = BoolProperty(name='Radius', default=True, description='Try to keep radius data from original curve') + animate = BoolProperty(name="Animate Result", default=False, description='Animate the final curve objects') + # Convert to Curve options + convert_conti = BoolProperty(name='Continuous', default=True, description='Create a continuous curve using verts from mesh') + convert_everyedge = BoolProperty(name='Every Edge', default=False, description='Create a curve from all verts in a mesh') + convert_edgetype = EnumProperty(name="Edge Type for Curves", + items=(("CONTI", "Continuous", "Create a continuous curve using verts from mesh"), ("EDGEALL", "All Edges", "Create a curve from every edge in a mesh")), + description="Choose which type of spline to use when curve is created", default="CONTI") + convert_joinbefore = BoolProperty(name="Join objects before convert", default=False, description='Join all selected mesh to one object before converting to mesh') + + +############################ +## Draw Brush panel in Toolbar +############################ +class addTracerObjectPanel(bpy.types.Panel): + bl_label = "bTrace: Panel" + bl_space_type = 'VIEW_3D' + bl_region_type = 'TOOLS' + bl_context = 'objectmode' + + def draw(self, context): + layout = self.layout + bTrace=bpy.context.window_manager.curve_tracer + obj = bpy.context.object + + ############################ + ## Curve options + ############################ + curve_settings = bTrace.curve_settings + row = self.layout.row() + row.label(text="Universal Curve Settings") + box = self.layout.box() + row = box.row() + CurveSettingText="Show: Curve Settings" + if curve_settings: + CurveSettingText="Hide: Curve Settings" + else: + CurveSettingText="Show: Curve Settings" + row.prop(bTrace, 'curve_settings', icon='CURVE_BEZCURVE', text=CurveSettingText) + if curve_settings: + box.label(text="Curve Settings", icon="CURVE_BEZCURVE") + if len(bpy.context.selected_objects) > 0: + if obj.type == 'CURVE': + col = box.column(align=True) + col.label(text="Edit Curves for") + col.label(text="Selected Curve") + col.prop(obj.data, 'bevel_depth') + col.prop(obj.data, 'bevel_resolution') + col.prop(obj.data, 'resolution_u') + else: + ############################ + ## Object Curve Settings + ############################ + curve_spline, curve_handle, curve_depth, curve_resolution, curve_u = bTrace.curve_spline, bTrace.curve_handle, bTrace.curve_depth, bTrace.curve_resolution, bTrace.curve_u + box.label(text="New Curve Settings") + box.prop(bTrace, "curve_spline") + box.prop(bTrace, "curve_handle") + col = box.column(align=True) + col.prop(bTrace, "curve_depth") + col.prop(bTrace, "curve_resolution") + col.prop(bTrace, "curve_u") + + ###################### + ## Start Object Tools ### + ###################### + row = self.layout.row() + row.label(text="Object Tools") + distort_curve = bTrace.distort_curve + tool_objectTrace, settings_objectTrace, convert_joinbefore, convert_edgetype = bTrace.tool_objectTrace, bTrace.settings_objectTrace, bTrace.convert_joinbefore, bTrace.convert_edgetype + animate = bTrace.animate + anim_auto, curve_join = bTrace.anim_auto, bTrace.curve_join + settings_particleTrace, settings_particleConnect = bTrace.settings_particleTrace, bTrace.settings_particleConnect + sel = bpy.context.selected_objects + ############################ + ### Object Trace + ############################ + box = self.layout.box() + row = box.row () + ObjectText="Show: Objects Trace" + if tool_objectTrace: + ObjectText="Hide: Objects Trace" + else: + ObjectText="Show: Objects Trace" + row.prop(bTrace, "tool_objectTrace", text=ObjectText, icon="FORCE_MAGNETIC") + if tool_objectTrace: + row = box.row () + row.label(text="Object Trace", icon="FORCE_MAGNETIC") + row.operator("object.btobjecttrace", text="Run!", icon="PLAY") + row = box.row () + row.prop(bTrace, "settings_objectTrace", icon='MODIFIER', text='Settings') + row.label(text="") + if settings_objectTrace: + row = box.row() + row.label(text='Edge Draw Method') + row = box.row(align=True) + row.prop(bTrace, 'convert_edgetype') + box.prop(bTrace, "object_duplicate") + if len(sel) > 1 : + box.prop(bTrace, 'convert_joinbefore') + else: + convert_joinbefore = False + row = box.row() + row.prop(bTrace, "distort_curve") + if distort_curve: + col = box.column(align=True) + col.prop(bTrace, "distort_modscale") + col.prop(bTrace, "distort_noise") + row = box.row() + row.prop(bTrace, "animate", text="Add Grow Curve Animation") + if animate: + # animation settings here + box.label(text='Frame Animation Settings:') + col = box.column(align=True) + col.prop(bTrace, 'anim_auto') + if not anim_auto: + row = col.row(align=True) + row.prop(bTrace,'anim_f_start') + row.prop(bTrace,'anim_length') + row = col.row(align=True) + row.prop(bTrace,'anim_delay') + row.prop(bTrace,'anim_f_fade') + + box.label(text='Additional Settings') + row = box.row() + row.prop(bTrace,'anim_tails') + row.prop(bTrace,'anim_keepr') + + ############################ + ### Objects Connect + ############################ + connect_noise = bTrace.connect_noise + tool_objectsConnect, settings_objectsConnect, respect_order = bTrace.tool_objectsConnect, bTrace.settings_objectsConnect, bTrace.respect_order + box = self.layout.box() + row = box.row () + ObjectConnText="Show: Objects Connect" + if tool_objectsConnect: + ObjectConnText="Hide: Objects Connect" + else: + ObjectConnText="Show: Objects Connect" + row.prop(bTrace, "tool_objectsConnect", text=ObjectConnText, icon="OUTLINER_OB_EMPTY") + if tool_objectsConnect: + row = box.row () + row.label(text="Objects Connect", icon="OUTLINER_OB_EMPTY") + row.operator("object.btobjectsconnect", text="Run!", icon="PLAY") + row = box.row() + row.prop(bTrace, "settings_objectsConnect", icon='MODIFIER', text='Settings') + row.prop(bTrace, "respect_order") + if respect_order: + box.operator("object.select_order") + if settings_objectsConnect: + box.prop(bTrace, "connect_noise") + if connect_noise: + row = box.row() + row.label(text="F-Curve Noise") + row = box.row(align=True) + row.prop(bTrace, "fcnoise_rot") + row.prop(bTrace, "fcnoise_loc") + row.prop(bTrace, "fcnoise_scale") + col = box.column(align=True) + col.prop(bTrace, "fcnoise_amp") + col.prop(bTrace, "fcnoise_timescale") + box.prop(bTrace, "fcnoise_key") + # Grow settings here + row = box.row() + row.prop(bTrace, "animate", text="Add Grow Curve Animation") + if animate: + box.label(text='Frame Animation Settings:') + col = box.column(align=True) + col.prop(bTrace, 'anim_auto') + if not anim_auto: + row = col.row(align=True) + row.prop(bTrace,'anim_f_start') + row.prop(bTrace,'anim_length') + row = col.row(align=True) + row.prop(bTrace,'anim_delay') + row.prop(bTrace,'anim_f_fade') + + box.label(text='Additional Settings') + row = box.row() + row.prop(bTrace,'anim_tails') + row.prop(bTrace,'anim_keepr') + + ############################ + ### Handwriting Tools + ############################ + tool_handwrite = bTrace.tool_handwrite + box = self.layout.box() + row = box.row() + handText="Show: Handwriting Tool" + if tool_handwrite: + handText="Hide: Handwriting Tool" + else: + handText="Show: Handwriting Tool" + row.prop(bTrace, 'tool_handwrite', text=handText, icon='BRUSH_DATA') + if tool_handwrite: + row = box.row() + row.label(text='Handwriting', icon='BRUSH_DATA') + row.operator("curve.btwriting", text="Run!", icon='PLAY') + box.prop(bTrace, "animate", text="Grow Curve Animation Settings") + if animate: + # animation settings here + box.label(text='Frame Animation Settings:') + col = box.column(align=True) + col.prop(bTrace, 'anim_auto') + if not anim_auto: + row = col.row(align=True) + row.prop(bTrace,'anim_f_start') + row.prop(bTrace,'anim_length') + row = col.row(align=True) + row.prop(bTrace,'anim_delay') + row.prop(bTrace,'anim_f_fade') + + box.label(text='Additional Settings') + row = box.row() + row.prop(bTrace,'anim_tails') + row.prop(bTrace,'anim_keepr') + box.label(text='Grease Pencil Writing Tools') + col = box.column(align=True) + row = col.row() + row.operator("gpencil.draw", text="Draw", icon='BRUSH_DATA').mode = 'DRAW' + row.operator("gpencil.draw", text="Poly", icon='VPAINT_HLT').mode = 'DRAW_POLY' + row = col.row(align=True) + row.operator("gpencil.draw", text="Line", icon='ZOOMOUT').mode = 'DRAW_STRAIGHT' + row.operator("gpencil.draw", text="Erase", icon='TPAINT_HLT').mode = 'ERASER' + row = box.row() + row.operator("gpencil.data_unlink", text="Delete Grease Pencil Layer", icon="CANCEL") + row = box.row() + + + ############################ + ### Particle Trace + ############################ + tool_particleTrace = bTrace.tool_particleTrace + box = self.layout.box() + row = box.row() + ParticleText="Show: Particle Trace" + if tool_particleTrace: + ParticleText="Hide: Particle Trace" + else: + ParticleText="Show: Particle Trace" + row.prop(bTrace, "tool_particleTrace", icon="PARTICLES", text=ParticleText) + if tool_particleTrace: + row = box.row() + row.label(text="Particle Trace", icon="PARTICLES") + row.operator("particles.particletrace", text="Run!", icon="PLAY") + row = box.row() + row.prop(bTrace, 'settings_particleTrace', icon='MODIFIER', text='Settings') + row.label(text='') + if settings_particleTrace: + box.prop(bTrace, "particle_step") + row = box.row() + row.prop(bTrace, "curve_join") + row.prop(bTrace, "animate", text="Add Grow Curve Animation") + if animate: + # animation settings here + box.label(text='Frame Animation Settings:') + col = box.column(align=True) + col.prop(bTrace, 'anim_auto') + if not anim_auto: + row = col.row(align=True) + row.prop(bTrace,'anim_f_start') + row.prop(bTrace,'anim_length') + row = col.row(align=True) + row.prop(bTrace,'anim_delay') + row.prop(bTrace,'anim_f_fade') + + box.label(text='Additional Settings') + row = box.row() + row.prop(bTrace,'anim_tails') + row.prop(bTrace,'anim_keepr') + + ############################ + ### Connect Particles + ############################ + particle_auto = bTrace.particle_auto + tool_particleConnect = bTrace.tool_particleConnect + box = self.layout.box() + row = box.row() + ParticleConnText="Show: Particle Connect" + if tool_particleConnect: + ParticleConnText="Hide: Particle Connect" + else: + ParticleConnText="Show: Particle Connect" + row.prop(bTrace, "tool_particleConnect", icon="MOD_PARTICLES", text=ParticleConnText) + if tool_particleConnect: + row = box.row() + row.label(text='Particle Connect', icon='MOD_PARTICLES') + row.operator("particles.connect", icon="PLAY", text='Run!') + row = box.row() + row.prop(bTrace, 'settings_particleConnect', icon='MODIFIER', text='Settings') + row.label(text='') + if settings_particleConnect: + box.prop(bTrace, "particle_step") + row= box.row() + row.prop(bTrace, 'particle_auto') + row.prop(bTrace, 'animate', text='Add Grow Curve Animation') + col = box.column(align=True) + if not particle_auto: + row = box.row(align=True) + row.prop(bTrace, 'particle_f_start') + row.prop(bTrace, 'particle_f_end') + if animate: + # animation settings here + box.label(text='Frame Animation Settings:') + col = box.column(align=True) + col.prop(bTrace, 'anim_auto') + if not anim_auto: + row = col.row(align=True) + row.prop(bTrace,'anim_f_start') + row.prop(bTrace,'anim_length') + row = col.row(align=True) + row.prop(bTrace,'anim_delay') + row.prop(bTrace,'anim_f_fade') + + box.label(text='Additional Settings') + row = box.row() + row.prop(bTrace,'anim_tails') + row.prop(bTrace,'anim_keepr') + + ####################### + #### Animate Curve #### + ####################### + row = self.layout.row() + row.label(text="Curve Animation Tools") + + animation_settings = bTrace.animation_settings + settings_growCurve = bTrace.settings_growCurve + box = self.layout.box() + row = box.row() + GrowText="Show: Grow Curve Animation" + if animation_settings: + GrowText="Hide: Grow Curve Animation" + else: + GrowText="Show: Grow Curve Animation" + row.prop(bTrace, 'animation_settings', icon="META_BALL", text=GrowText) + if animation_settings: + row = box.row() + row.label(text="Grow Curve", icon="META_BALL") + row.operator('curve.btgrow', text='Run!', icon='PLAY') + row = box.row() + row.prop(bTrace, "settings_growCurve", icon='MODIFIER', text='Settings') + row.operator('object.btreset', icon='KEY_DEHLT') + if settings_growCurve: + box.label(text='Frame Animation Settings:') + col = box.column(align=True) + col.prop(bTrace, 'anim_auto') + if not anim_auto: + row = col.row(align=True) + row.prop(bTrace,'anim_f_start') + row.prop(bTrace,'anim_length') + row = col.row(align=True) + row.prop(bTrace,'anim_delay') + row.prop(bTrace,'anim_f_fade') + + box.label(text='Additional Settings') + row = box.row() + row.prop(bTrace,'anim_tails') + row.prop(bTrace,'anim_keepr') + + ####################### + #### F-Curve Noise Curve #### + ####################### + tool_fcurve = bTrace.tool_fcurve + settings_fcurve = bTrace.settings_fcurve + box = self.layout.box() + row = box.row() + fcurveText="Show: F-Curve Noise" + if tool_fcurve: + fcurveText="Hide: F-Curve Noise" + else: + fcurveText="Show: F-Curve Noise" + row.prop(bTrace, "tool_fcurve", text=fcurveText, icon='RNDCURVE') + if tool_fcurve: + row = box.row() + row.label(text="F-Curve Noise", icon='RNDCURVE') + row.operator("object.btfcnoise", icon='PLAY', text="Run!") + row = box.row() + row.prop(bTrace, "settings_fcurve", icon='MODIFIER', text='Settings') + row.operator('object.btreset', icon='KEY_DEHLT') + if settings_fcurve: + row = box.row(align=True) + row.prop(bTrace, "fcnoise_rot") + row.prop(bTrace, "fcnoise_loc") + row.prop(bTrace, "fcnoise_scale") + col = box.column(align=True) + col.prop(bTrace, "fcnoise_amp") + col.prop(bTrace, "fcnoise_timescale") + box.prop(bTrace, "fcnoise_key") +###### END PANEL ############## +############################### + + +################## ################## ################## ############ +## Object Trace +## creates a curve with a modulated radius connecting points of a mesh +################## ################## ################## ############ + +class OBJECT_OT_objecttrace(bpy.types.Operator): + bl_idname = "object.btobjecttrace" + bl_label = "bTrace: Object Trace" + bl_description = "Trace selected mesh object with a curve with the option to animate" + bl_options = {'REGISTER', 'UNDO'} + + @classmethod + def poll(cls, context): + return (context.object and context.object.type in {'MESH','FONT'}) + + def invoke(self, context, event): + import bpy + + # Run through each selected object and convert to to a curved object + brushObj = bpy.context.selected_objects + objectDupli = bpy.context.window_manager.curve_tracer.object_duplicate # Get duplicate check setting + convert_joinbefore = bpy.context.window_manager.curve_tracer.convert_joinbefore + animate = bpy.context.window_manager.curve_tracer.animate + # Duplicate Mesh + if objectDupli: + bpy.ops.object.duplicate_move() + brushObj = bpy.context.selected_objects + # Join Mesh + if convert_joinbefore: + if len(brushObj) > 1: # Only run if multiple objects selected + bpy.ops.object.join() + brushObj = bpy.context.selected_objects + + for i in brushObj: + bpy.context.scene.objects.active = i + if i and i.type != 'CURVE': + bpy.ops.object.btconvertcurve() + addtracemat(bpy.context.object.data) + if animate: + bpy.ops.curve.btgrow() + return{"FINISHED"} + + +################## ################## ################## ############ +## Objects Connect +## connect selected objects with a curve + hooks to each node +## possible handle types: 'FREE' 'AUTO' 'VECTOR' 'ALIGNED' +################## ################## ################## ############ + + +class OBJECT_OT_objectconnect(bpy.types.Operator): + bl_idname = "object.btobjectsconnect" + bl_label = "bTrace: Objects Connect" + bl_description = "Connect selected objects with a curve and add hooks to each node" + bl_options = {'REGISTER', 'UNDO'} + + @classmethod + def poll(cls, context): + return len(bpy.context.selected_objects) > 1 + + def invoke(self, context, event): + import bpy, selection_utils + list = [] + bTrace = bpy.context.window_manager.curve_tracer + objectHandle = bTrace.curve_handle # Get Handle selection + if objectHandle == 'AUTOMATIC': # hackish because of naming conflict in api + objectHandle = 'AUTO' + objectrez = bTrace.curve_resolution # Get Bevel resolution + objectdepth = bTrace.curve_depth # Get Bevel Depth + animate = bTrace.animate # add Grow Curve + respect_order = bTrace.respect_order # respect object selection order + connect_noise = bTrace.connect_noise + # Check if bTrace group exists, if not create + bgroup = bpy.data.groups.keys() + if 'bTrace' not in bgroup: + bpy.ops.group.create(name="bTrace") + # check if noise + if connect_noise: + bpy.ops.object.btfcnoise() + # check if respect order is checked, create list of objects + if respect_order == True: + selobnames = selection_utils.selected + obnames = [] + for ob in selobnames: + obnames.append(bpy.data.objects[ob]) + else: + obnames = bpy.context.selected_objects # No selection order + + + for a in obnames: + list.append(a) + a.select = False + + # trace the origins + tracer = bpy.data.curves.new('tracer','CURVE') + tracer.dimensions = '3D' + spline = tracer.splines.new('BEZIER') + spline.bezier_points.add(len(list)-1) + curve = bpy.data.objects.new('curve',tracer) + bpy.context.scene.objects.link(curve) + + # render ready curve + tracer.resolution_u = 64 + tracer.bevel_resolution = objectrez # Set bevel resolution from Panel options + tracer.fill_mode = 'FULL' + tracer.bevel_depth = objectdepth # Set bevel depth from Panel options + + # move nodes to objects + for i in range(len(list)): + p = spline.bezier_points[i] + p.co = list[i].location + p.handle_right_type=objectHandle + p.handle_left_type=objectHandle + + bpy.context.scene.objects.active = curve + bpy.ops.object.mode_set(mode='OBJECT') + + # place hooks + for i in range(len(list)): + list[i].select = True + curve.data.splines[0].bezier_points[i].select_control_point = True + bpy.ops.object.mode_set(mode='EDIT') + bpy.ops.object.hook_add_selob() + bpy.ops.object.mode_set(mode='OBJECT') + curve.data.splines[0].bezier_points[i].select_control_point = False + list[i].select = False + + bpy.ops.object.select_all(action='DESELECT') + curve.select = True # selected curve after it's created + addtracemat(bpy.context.object.data) # Add material + if animate: # Add Curve Grow it? + bpy.ops.curve.btgrow() + bpy.ops.object.group_link(group="bTrace") # add to bTrace group + if bTrace.animate: + bpy.ops.curve.btgrow() # Add grow curve + return{"FINISHED"} + + +################## ################## ################## ############ +## Particle Trace +## creates a curve from each particle of a system +################## ################## ################## ############ +def curvetracer(curvename, splinename): + bTrace = bpy.context.window_manager.curve_tracer + tracer = bpy.data.curves.new(splinename,'CURVE') + tracer.dimensions = '3D' + curve = bpy.data.objects.new(curvename, tracer) + bpy.context.scene.objects.link(curve) + addtracemat(tracer) #Add material + # tracer.materials.append(bpy.data.materials.get('TraceMat')) + try: tracer.fill_mode = 'FULL' + except: tracer.use_fill_front = tracer.use_fill_back = False + tracer.bevel_resolution = bTrace.curve_resolution + tracer.bevel_depth = bTrace.curve_depth + tracer.resolution_u = bTrace.curve_u + return tracer, curve + + +class OBJECT_OT_particletrace(bpy.types.Operator): + bl_idname = "particles.particletrace" + bl_label = "bTrace: Particle Trace" + bl_description = "Creates a curve from each particle of a system. Keeping particle amount under 250 will make this run faster" + bl_options = {'REGISTER', 'UNDO'} + + @classmethod + def poll(cls, context): + return (bpy.context.object and bpy.context.object.particle_systems) + + def execute(self, context): + bTrace = bpy.context.window_manager.curve_tracer + objectHandle = bTrace.curve_handle + stepSize = bTrace.particle_step # step size in frames + curve_join = bTrace.curve_join # join curves after created + obj = bpy.context.object + ps = obj.particle_systems.active + curvelist = [] + if objectHandle == 'AUTOMATIC': # hackish because of naming conflict in api + objectHandle = 'AUTO' + if objectHandle == 'FREE_ALIGN': + objectHandle = 'FREE' + + # Check if bTrace group exists, if not create + bgroup = bpy.data.groups.keys() + if 'bTrace' not in bgroup: + bpy.ops.group.create(name="bTrace") + + if bTrace.curve_join: + tracer = curvetracer('Tracer', 'Splines') + for x in ps.particles: + if not bTrace.curve_join: + tracer = curvetracer('Tracer.000', 'Spline.000') + spline = tracer[0].splines.new('BEZIER') + spline.bezier_points.add((x.lifetime-1)//stepSize) #add point to spline based on step size + for t in list(range(int(x.lifetime))): + bpy.context.scene.frame_set(t+x.birth_time) + if not t%stepSize: + p = spline.bezier_points[t//stepSize] + p.co = x.location + p.handle_right_type = objectHandle + p.handle_left_type = objectHandle + particlecurve = tracer[1] + curvelist.append(particlecurve) + # add to group + bpy.ops.object.select_all(action='DESELECT') + for curvename in curvelist: + curvename.select = True + bpy.context.scene.objects.active = curvename + bpy.ops.object.group_link(group="bTrace") + + if bTrace.animate: + bpy.ops.curve.btgrow() # Add grow curve + + return{"FINISHED"} + + +########################################################################### +## Particle Connect +## connect all particles in active system with a continuous animated curve +########################################################################### + +class OBJECT_OT_traceallparticles(bpy.types.Operator): + bl_idname = 'particles.connect' + bl_label = 'Connect Particles' + bl_description = 'Create a continuous animated curve from particles in active system' + bl_options = {'REGISTER', 'UNDO'} + + @classmethod + def poll(cls, context): + return (bpy.context.object and bpy.context.object.particle_systems) + + def execute(self, context): + + obj = bpy.context.object + ps = obj.particle_systems.active + set = ps.settings + + # Grids distribution not supported + if set.distribution == 'GRID': + self.report('INFO',"Grid distribution mode for particles not supported.") + return{'FINISHED'} + + bTrace = bpy.context.window_manager.curve_tracer + particleHandle = bTrace.curve_handle # Get Handle selection + particleSpline = bTrace.curve_spline # Get Spline selection + stepSize = bTrace.particle_step # step size in frames + particlerez = bTrace.curve_resolution # Get Bevel resolution + particledepth = bTrace.curve_depth # Get Bevel Depth + particleauto = bTrace.particle_auto # Get Auto Time Range + particle_f_start = bTrace.particle_f_start # Get frame start + particle_f_end = bTrace.particle_f_end # Get frame end + if particleHandle == 'AUTOMATIC': # hackish because of naming conflict in api + particleHandle = 'AUTO' + if particleHandle == 'FREE_ALIGN': + particleHandle = 'FREE' + tracer = bpy.data.curves.new('Splines','CURVE') # define what kind of object to create + curve = bpy.data.objects.new('Tracer',tracer) # Create new object with settings listed above + bpy.context.scene.objects.link(curve) # Link newly created object to the scene + spline = tracer.splines.new('BEZIER') # add a new Bezier point in the new curve + spline.bezier_points.add(set.count-1) + + tracer.dimensions = '3D' + tracer.resolution_u = 32 + tracer.bevel_resolution = particlerez + tracer.fill_mode = 'FULL' + tracer.bevel_depth = particledepth + + addtracemat(tracer) #Add material + + if particleauto: + f_start = int(set.frame_start) + f_end = int(set.frame_end + set.lifetime) + else: + if particle_f_end <= particle_f_start: + particle_f_end = particle_f_start + 1 + f_start = particle_f_start + f_end = particle_f_end + print ('range: ', f_start, '/', f_end) + + for bFrames in range(f_start, f_end): + bpy.context.scene.frame_set(bFrames) + if not (bFrames-f_start) % stepSize: + print ('done frame: ',bFrames) + for bFrames in range(set.count): + if ps.particles[bFrames].alive_state != 'UNBORN': + e = bFrames + bp = spline.bezier_points[bFrames] + pt = ps.particles[e] + bp.co = pt.location + #bp.handle_left = pt.location + #bp.handle_right = pt.location + bp.handle_right_type = particleHandle + bp.handle_left_type = particleHandle + bp.keyframe_insert('co') + bp.keyframe_insert('handle_left') + bp.keyframe_insert('handle_right') + # Select new curve + bpy.ops.object.select_all(action='DESELECT') + curve .select = True + bpy.context.scene.objects.active = curve + if bTrace.animate: + bpy.ops.curve.btgrow() + return{'FINISHED'} + +################## ################## ################## ############ +## Writing Tool +## Writes a curve by animating its point's radii +## +################## ################## ################## ############ +class OBJECT_OT_writing(bpy.types.Operator): + bl_idname = 'curve.btwriting' + bl_label = 'Write' + bl_description = 'Use Grease Pencil to write and convert to curves' + bl_options = {'REGISTER', 'UNDO'} + + @classmethod ### Removed so panel still draws if nothing is selected + def poll(cls, context): + return (context.scene.grease_pencil != None) + + def execute(self, context): + bTrace, obj = bpy.context.window_manager.curve_tracer, bpy.context.object + animate = bTrace.animate + gactive = bpy.context.active_object # set selected object before convert + bpy.ops.gpencil.convert(type='CURVE') + gactiveCurve = bpy.context.active_object # get curve after convert + writeObj = bpy.context.selected_objects + for i in writeObj: + bpy.context.scene.objects.active = i + bpy.ops.curve.btgrow() + addtracemat(bpy.context.object.data) #Add material + # Delete grease pencil strokes + bpy.context.scene.objects.active = gactive + bpy.ops.gpencil.data_unlink() + bpy.context.scene.objects.active = gactiveCurve + # Smooth object + bpy.ops.object.shade_smooth() + # Return to first frame + bpy.context.scene.frame_set(bTrace.anim_f_start) + + return{'FINISHED'} + +################## ################## ################## ############ +## Create Curve +## Convert mesh to curve using either Continuous, All Edges, or Sharp Edges +## Option to create noise +################## ################## ################## ############ + +class OBJECT_OT_convertcurve(bpy.types.Operator): + bl_idname = "object.btconvertcurve" + bl_label = "bTrace: Create Curve" + bl_description = "Convert mesh to curve using either Continuous, All Edges, or Sharp Edges" + bl_options = {'REGISTER', 'UNDO'} + + def execute(self, context): + import bpy, random, mathutils + from mathutils import Vector + + bTrace = bpy.context.window_manager.curve_tracer + distort_modscale = bTrace.distort_modscale # add a scale to the modular random + distort_curve = bTrace.distort_curve # modulate the resulting curve + objectHandle = bTrace.curve_handle # Get Handle selection + objectSpline = bTrace.curve_spline # Get Spline selection + objectDupli = bTrace.object_duplicate # Get duplicate check setting + objectrez = bTrace.curve_resolution # Get Bevel resolution + objectdepth = bTrace.curve_depth # Get Bevel Depth + objectU = bTrace.curve_u # Get Bevel Depth + objectnoise = bTrace.distort_noise # Get Bevel Depth + convert_joinbefore = bTrace.convert_joinbefore + convert_edgetype = bTrace.convert_edgetype + traceobjects = bpy.context.selected_objects # create a list with all the selected objects + + obj = bpy.context.object + + ### Convert Font + if obj.type == 'FONT': + bpy.ops.object.mode_set(mode='OBJECT') + bpy.ops.object.convert(target='CURVE') # Convert edges to curve + bpy.context.object.data.dimensions = '3D' + + # make a continuous edge through all vertices + if obj.type == 'MESH': + # Add noise to mesh + if distort_curve: + for v in obj.data.vertices: + for u in range(3): + v.co[u] += objectnoise*(random.uniform(-1,1)) + + if convert_edgetype == 'CONTI': + ## Start Continuous edge + bpy.ops.object.mode_set(mode='EDIT') + bpy.ops.mesh.select_all(action='SELECT') + bpy.ops.mesh.delete(type='EDGE_FACE') + bpy.ops.mesh.select_all(action='DESELECT') + verts = bpy.context.object.data.vertices + bpy.ops.object.mode_set(mode='OBJECT') + li = [] + p1 = random.randint(0,len(verts)-1) + + for v in verts: + li.append(v.index) + li.remove(p1) + for z in range(len(li)): + x = [] + for px in li: + d = verts[p1].co - verts[px].co # find distance from first vert + x.append(d.length) + p2 = li[x.index(min(x))] # find the shortest distance list index + verts[p1].select = verts[p2].select = True + bpy.ops.object.mode_set(mode='EDIT') + bpy.context.tool_settings.mesh_select_mode = [True, False, False] + bpy.ops.mesh.edge_face_add() + bpy.ops.object.mode_set(mode='OBJECT') + verts[p1].select = verts[p2].select = False + li.remove(p2) # remove item from list. + p1 = p2 + # Convert edges to curve + bpy.ops.object.mode_set(mode='OBJECT') + bpy.ops.object.convert(target='CURVE') + + if convert_edgetype == 'EDGEALL': + ## Start All edges + bpy.ops.object.mode_set(mode='EDIT') + bpy.ops.mesh.select_all(action='SELECT') + bpy.ops.mesh.delete(type='ONLY_FACE') + bpy.ops.object.mode_set() + bpy.ops.object.convert(target='CURVE') + for sp in obj.data.splines: + sp.type = objectSpline + + obj = bpy.context.object + # Set spline type to custom property in panel + bpy.ops.object.editmode_toggle() + bpy.ops.curve.spline_type_set(type=objectSpline) + # Set handle type to custom property in panel + bpy.ops.curve.handle_type_set(type=objectHandle) + bpy.ops.object.editmode_toggle() + obj.data.fill_mode = 'FULL' + # Set resolution to custom property in panel + obj.data.bevel_resolution = objectrez + obj.data.resolution_u = objectU + # Set depth to custom property in panel + obj.data.bevel_depth = objectdepth + # Smooth object + bpy.ops.object.shade_smooth() + # Modulate curve radius and add distortion + if distort_curve: + scale = distort_modscale + if scale == 0: + return{"FINISHED"} + for u in obj.data.splines: + for v in u.bezier_points: + v.radius = scale*round(random.random(),3) + return{"FINISHED"} + + +################################################################### +#### Add Tracer Material +################################################################### + +def addtracemat(matobj): + if 'TraceMat' not in bpy.data.materials: + TraceMat = bpy.data.materials.new('TraceMat') + TraceMat.diffuse_color = [0,.5,1] + TraceMat.specular_intensity = 0.5 + matobj.materials.append(bpy.data.materials.get('TraceMat')) + return {'FINISHED'} + +################## ################## ################## ############ +## F-Curve Noise +## will add noise modifiers to each selected object f-curves +## change type to: 'rotation' | 'location' | 'scale' | '' to effect all +## first record a keyframe for this to work (to generate the f-curves) +################## ################## ################## ############ + +class OBJECT_OT_fcnoise(bpy.types.Operator): + bl_idname = "object.btfcnoise" + bl_label = "bTrace: F-curve Noise" + bl_options = {'REGISTER', 'UNDO'} + + def execute(self, context): + import bpy, random + + bTrace = bpy.context.window_manager.curve_tracer + amp = bTrace.fcnoise_amp + timescale = bTrace.fcnoise_timescale + addkeyframe = bTrace.fcnoise_key + + # This sets properties for Loc, Rot and Scale if they're checked in the Tools window + noise_rot = 'rotation' + noise_loc = 'location' + noise_scale = 'scale' + if not bTrace.fcnoise_rot: + noise_rot = 'none' + if not bTrace.fcnoise_loc: + noise_loc = 'none' + if not bTrace.fcnoise_scale: + noise_scale = 'none' + + type = noise_loc, noise_rot, noise_scale # Add settings from panel for type of keyframes + amplitude = amp + time_scale = timescale + + for i in bpy.context.selected_objects: + # Add keyframes, this is messy and should only add keyframes for what is checked + if addkeyframe == True: + bpy.ops.anim.keyframe_insert(type="LocRotScale") + for obj in bpy.context.selected_objects: + if obj.animation_data: + for c in obj.animation_data.action.fcurves: + if c.data_path.startswith(type): + # clean modifiers + for m in c.modifiers : + c.modifiers.remove(m) + # add noide modifiers + n = c.modifiers.new('NOISE') + n.strength = amplitude + n.scale = time_scale + n.phase = random.randint(0,999) + return{"FINISHED"} + +################## ################## ################## ############ +## Curve Grow Animation +## Animate curve radius over length of time +################## ################## ################## ############ +class OBJECT_OT_curvegrow(bpy.types.Operator): + bl_idname = 'curve.btgrow' + bl_label = 'Run Script' + bl_description = 'Keyframe points radius' + bl_options = {'REGISTER', 'UNDO'} + + @classmethod + def poll(cls, context): + return (context.object and context.object.type in {'CURVE'}) + + def execute(self, context): + bTrace = bpy.context.window_manager.curve_tracer + anim_f_start, anim_length, anim_auto = bTrace.anim_f_start, bTrace.anim_length, bTrace.anim_auto + curve_resolution, curve_depth = bTrace.curve_resolution, bTrace.curve_depth + # make the curve visible + objs = bpy.context.selected_objects + for i in objs: # Execute on multiple selected objects + bpy.context.scene.objects.active = i + obj = bpy.context.active_object + try: obj.data.fill_mode = 'FULL' + except: obj.data.use_fill_front = obj.data.use_fill_back = False + if not obj.data.bevel_resolution: + obj.data.bevel_resolution = curve_resolution + if not obj.data.bevel_depth: + obj.data.bevel_depth = curve_depth + if anim_auto: + anim_f_start = bpy.context.scene.frame_start + anim_length = bpy.context.scene.frame_end + # get points data and beautify + actual, total = anim_f_start, 0 + for sp in obj.data.splines: + total += len(sp.points) + len(sp.bezier_points) + step = anim_length / total + for sp in obj.data.splines: + sp.radius_interpolation = 'BSPLINE' + po = [p for p in sp.points] + [p for p in sp.bezier_points] + if not bTrace.anim_keepr: + for p in po: + p.radius = 1 + if bTrace.anim_tails and not sp.use_cyclic_u: + po[0].radius = po[-1].radius = 0 + po[1].radius = po[-2].radius = .65 + ra = [p.radius for p in po] + + # record the keyframes + for i in range(len(po)): + po[i].radius = 0 + po[i].keyframe_insert('radius', frame=actual) + actual += step + po[i].radius = ra[i] + po[i].keyframe_insert('radius', frame=(actual + bTrace.anim_delay)) + + if bTrace.anim_f_fade: + po[i].radius = ra[i] + po[i].keyframe_insert('radius', frame=(actual + bTrace.anim_f_fade - step)) + po[i].radius = 0 + po[i].keyframe_insert('radius', frame=(actual + bTrace.anim_delay + bTrace.anim_f_fade)) + + bpy.context.scene.frame_set(bTrace.anim_f_start) + return{'FINISHED'} + +################## ################## ################## ############ +## Remove animation and curve radius data +################## ################## ################## ############ +class OBJECT_OT_reset(bpy.types.Operator): + bl_idname = 'object.btreset' + bl_label = 'Clear animation' + bl_description = 'Remove animation / curve radius data' + bl_options = {'REGISTER', 'UNDO'} + + def execute(self, context): + objs = bpy.context.selected_objects + for i in objs: # Execute on multiple selected objects + bpy.context.scene.objects.active = i + obj = bpy.context.active_object + obj.animation_data_clear() + if obj.type == 'CURVE': + for sp in obj.data.splines: + po = [p for p in sp.points] + [p for p in sp.bezier_points] + for p in po: + p.radius = 1 + return{'FINISHED'} + +### Define Classes to register +classes = [TracerProperties, + addTracerObjectPanel, + OBJECT_OT_convertcurve, + OBJECT_OT_objecttrace, + OBJECT_OT_objectconnect, + OBJECT_OT_writing, + OBJECT_OT_particletrace, + OBJECT_OT_traceallparticles, + OBJECT_OT_curvegrow, + OBJECT_OT_reset, + OBJECT_OT_fcnoise] + +def register(): + for c in classes: + bpy.utils.register_class(c) + bpy.types.WindowManager.curve_tracer = bpy.props.PointerProperty(type=TracerProperties) +def unregister(): + for c in classes: + bpy.utils.unregister_class(c) + del bpy.types.WindowManager.curve_tracer +if __name__ == "__main__": + register() diff -Nru blender-2.61/release/scripts/addons_contrib/btrace/__init__.py blender-2.62/release/scripts/addons_contrib/btrace/__init__.py --- blender-2.61/release/scripts/addons_contrib/btrace/__init__.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/btrace/__init__.py 2012-02-15 19:43:39.000000000 +0000 @@ -0,0 +1,57 @@ +#BEGIN GPL LICENSE BLOCK + +#This program is free software; you can redistribute it and/or +#modify it under the terms of the 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#END GPL LICENCE BLOCK + +bl_info = { + 'name': "bTrace", + 'author': "liero, crazycourier, Atom, Meta-Androcto, MacKracken", + 'version': (1, 1, ), + 'blender': (2, 61, 1), + 'location': "View3D > Tools", + 'description': "Tools for converting/animating objects/particles into curves", + 'warning': "Still under development, bug reports appreciated", + 'wiki_url': "", + 'tracker_url': "http://projects.blender.org/tracker/?func=detail&atid=468&aid=29563&group_id=153", + 'category': "Mesh" + } +import bpy +from .bTrace import * +from bpy.props import * + +### Define Classes to register +classes = [TracerProperties, + addTracerObjectPanel, + OBJECT_OT_convertcurve, + OBJECT_OT_objecttrace, + OBJECT_OT_objectconnect, + OBJECT_OT_writing, + OBJECT_OT_particletrace, + OBJECT_OT_traceallparticles, + OBJECT_OT_curvegrow, + OBJECT_OT_reset, + OBJECT_OT_fcnoise] + +def register(): + for c in classes: + bpy.utils.register_class(c) + bpy.types.WindowManager.curve_tracer = bpy.props.PointerProperty(type=TracerProperties) +def unregister(): + for c in classes: + bpy.utils.unregister_class(c) + del bpy.types.WindowManager.curve_tracer +if __name__ == "__main__": + register() diff -Nru blender-2.61/release/scripts/addons_contrib/cmu_mocap_browser/__init__.py blender-2.62/release/scripts/addons_contrib/cmu_mocap_browser/__init__.py --- blender-2.61/release/scripts/addons_contrib/cmu_mocap_browser/__init__.py 2011-12-13 19:59:39.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/cmu_mocap_browser/__init__.py 2012-02-15 19:43:57.000000000 +0000 @@ -27,7 +27,6 @@ 'author': "Daniel Monteiro Basso ", 'version': (2011, 10, 30, 1), 'blender': (2, 6, 0), - 'api': 41226, 'location': "View3D > Tools", 'description': "Assistant for using CMU Motion Capture data", 'warning': '', @@ -296,11 +295,12 @@ label = "Download and Import Selected" else: label = "Download Selected" - op = layout.operator("mocap.download_import", - text=label, icon='ARMATURE_DATA') - op.remote_file = remote_fname - op.local_file = local_fname - op.do_import = do_import + + props = layout.operator("mocap.download_import", + text=label, icon='ARMATURE_DATA') + props.remote_file = remote_fname + props.local_file = local_fname + props.do_import = do_import class CMUMocapMotionBrowser(bpy.types.Panel): @@ -351,10 +351,10 @@ else: label = "Download {0}".format(target) row = layout.row() - op = row.operator("mocap.download_import", text=label, icon=icon) - op.remote_file = remote_fname + ext - op.local_file = local_fname - op.do_import = do_import + props = row.operator("mocap.download_import", text=label, icon=icon) + props.remote_file = remote_fname + ext + props.local_file = local_fname + props.do_import = do_import row.active = ext in motion['files'] diff -Nru blender-2.61/release/scripts/addons_contrib/cursor_control/__init__.py blender-2.62/release/scripts/addons_contrib/cursor_control/__init__.py --- blender-2.61/release/scripts/addons_contrib/cursor_control/__init__.py 2011-12-13 19:59:32.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/cursor_control/__init__.py 2012-02-15 19:43:48.000000000 +0000 @@ -25,7 +25,6 @@ 'author': 'Morgan Mörtsell (Seminumerical)', 'version': (0, 7, 0), 'blender': (2, 5, 9), - 'api': 39307, 'location': 'View3D > Properties > Cursor', 'description': 'Control the Cursor', 'warning': '', # used for warning icon and text in addons panel diff -Nru blender-2.61/release/scripts/addons_contrib/curve_tools.py blender-2.62/release/scripts/addons_contrib/curve_tools.py --- blender-2.61/release/scripts/addons_contrib/curve_tools.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/curve_tools.py 2012-02-15 19:43:59.000000000 +0000 @@ -17,21 +17,20 @@ # #####END GPL LICENSE BLOCK ##### bl_info = { - "name": "Curve Tools", - "author": "Zak", - "version": (0, 1, 5), - "blender": (2, 5, 9), - "api": 39685, - "location": "Properties > Object data", - "description": "Creates driven Lofts or Birails between curves", - "warning": "", + "name": "Curve Tools", + "author": "Zak", + "version": (0, 1, 5), + "blender": (2, 5, 9), + "location": "Properties > Object data", + "description": "Creates driven Lofts or Birails between curves", + "warning": "", "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\ "Scripts/Curve/Curve_Tools", "tracker_url": "https://projects.blender.org/tracker/index.php?"\ "func=detail&aid=27720", - "category": "Add Curve"} + "category": "Add Curve"} -### UPDATES +### UPDATES #1.5 #-Fixed birail function @@ -60,7 +59,7 @@ ### PROPERTIES class sprops(bpy.types.PropertyGroup): - pass + pass bpy.utils.register_class(sprops) @@ -70,7 +69,7 @@ #dodriver a simple checker to chosse whether you want a driven mesh or not. -bpy.types.Scene.dodriver = BoolProperty(name = "dodriver", default=False) +bpy.types.Scene.dodriver = BoolProperty(name = "dodriver", default=False) #interpolation types myitems = (('0','Linear', ''),('1','Cubic',''),('2','Catmull',''), ('3','Hermite','')) @@ -84,278 +83,278 @@ bpy.types.Scene.tension = FloatProperty(name = "tension", min=0.0, default=0.0) bpy.types.Scene.bias = FloatProperty(name = "bias", min=0.0, default = 0.5) -#proportional birail +#proportional birail bpy.types.Scene.proportional = BoolProperty(name="proportional", default=False) #this stores the result of calculating the curve length bpy.types.Scene.clen = FloatProperty(name="clen", default=0.0, precision=5) #minimun distance for merge curve tool -bpy.types.Scene.limit = FloatProperty(name="limit", default=0.1, precision=3) - +bpy.types.Scene.limit = FloatProperty(name="limit", default=0.1, precision=3) + ### SELECT BY ORDER BLOCK #i dont know what to do with this. Im not using it yet. def selected_points(curve): - - selp = [] - for spl in curve.splines: - if spl.type=="BEZIER": - points = spl.bezier_points - for p in points: - if p.select_control_point: - selp.append(p) - - elif spl.type=="NURBS": - points = spl.points - for p in points: - if p.select: - selp.append(p) - return selp - + + selp = [] + for spl in curve.splines: + if spl.type=="BEZIER": + points = spl.bezier_points + for p in points: + if p.select_control_point: + selp.append(p) + + elif spl.type=="NURBS": + points = spl.points + for p in points: + if p.select: + selp.append(p) + return selp + #writes bpy.selection when a new object is selected or deselected #it compares bpy.selection with bpy.context.selected_objects - + def select(): - - #print(bpy.context.mode) - if bpy.context.mode=="OBJECT": - obj = bpy.context.object - sel = len(bpy.context.selected_objects) - - if sel==0: - bpy.selection=[] - else: - if sel==1: - bpy.selection=[] - bpy.selection.append(obj) - elif sel>len(bpy.selection): - for sobj in bpy.context.selected_objects: - if (sobj in bpy.selection)==False: - bpy.selection.append(sobj) - - elif sellen(bpy.selection): + for sobj in bpy.context.selected_objects: + if (sobj in bpy.selection)==False: + bpy.selection.append(sobj) + + elif sel=order and i<=n: - k+=1.0 - elif type==2: - if order==4: - k=0.34 - for a in range(0,t): - if a>=order and a<=n: k+=0.5 - kv.append(floor(k)) - k+=1.0/3.0 - - elif order==3: - k=0.6 - for a in range(0, t): - if a >=order and a<=n: k+=0.5 - kv.append(floor(k)) - - ##normalize the knot vector - for i in range(0, len(kv)): - kv[i]=kv[i]/kv[-1] - - return kv + + kv = [] + + t = n+order + if type==0: + for i in range(0, t): + kv.append(1.0*i) + + elif type==1: + k=0.0 + for i in range(1, t+1): + kv.append(k) + if i>=order and i<=n: + k+=1.0 + elif type==2: + if order==4: + k=0.34 + for a in range(0,t): + if a>=order and a<=n: k+=0.5 + kv.append(floor(k)) + k+=1.0/3.0 + + elif order==3: + k=0.6 + for a in range(0, t): + if a >=order and a<=n: k+=0.5 + kv.append(floor(k)) + + ##normalize the knot vector + for i in range(0, len(kv)): + kv[i]=kv[i]/kv[-1] + + return kv #nurbs curve evaluation def C(t, order, points, weights, knots): - #c = Point([0,0,0]) - c = Vector() - rational = 0 - i = 0 - while i < len(points): - b = B(i, order, t, knots) - p = points[i] * (b * weights[i]) - c = c + p - rational = rational + b*weights[i] - i = i + 1 - - return c * (1.0/rational) + #c = Point([0,0,0]) + c = Vector() + rational = 0 + i = 0 + while i < len(points): + b = B(i, order, t, knots) + p = points[i] * (b * weights[i]) + c = c + p + rational = rational + b*weights[i] + i = i + 1 + + return c * (1.0/rational) #nurbs basis function def B(i,k,t,knots): - ret = 0 - if k>0: - n1 = (t-knots[i])*B(i,k-1,t,knots) - d1 = knots[i+k] - knots[i] - n2 = (knots[i+k+1] - t) * B(i+1,k-1,t,knots) - d2 = knots[i+k+1] - knots[i+1] - if d1 > 0.0001 or d1 < -0.0001: - a = n1 / d1 - else: - a = 0 - if d2 > 0.0001 or d2 < -0.0001: - b = n2 / d2 - else: - b = 0 - ret = a + b - #print "B i = %d, k = %d, ret = %g, a = %g, b = %g\n"%(i,k,ret,a,b) - else: - if knots[i] <= t and t <= knots[i+1]: - ret = 1 - else: - ret = 0 - return ret + ret = 0 + if k>0: + n1 = (t-knots[i])*B(i,k-1,t,knots) + d1 = knots[i+k] - knots[i] + n2 = (knots[i+k+1] - t) * B(i+1,k-1,t,knots) + d2 = knots[i+k+1] - knots[i+1] + if d1 > 0.0001 or d1 < -0.0001: + a = n1 / d1 + else: + a = 0 + if d2 > 0.0001 or d2 < -0.0001: + b = n2 / d2 + else: + b = 0 + ret = a + b + #print "B i = %d, k = %d, ret = %g, a = %g, b = %g\n"%(i,k,ret,a,b) + else: + if knots[i] <= t and t <= knots[i+1]: + ret = 1 + else: + ret = 0 + return ret #calculates a global parameter t along all control points #t=0 begining of the curve #t=1 ending of the curve def calct(obj, t): - - spl=None - mw = obj.matrix_world - if obj.data.splines.active==None: - if len(obj.data.splines)>0: - spl=obj.data.splines[0] - else: - spl = obj.data.splines.active - - if spl==None: - return False - - if spl.type=="BEZIER": - points = spl.bezier_points - nsegs = len(points)-1 - - d = 1.0/nsegs - seg = int(t/d) - t1 = t/d - int(t/d) - - if t==1: - seg-=1 - t1 = 1.0 - - p = getbezpoints(spl,mw, seg) - - coord = cubic(p, t1) - - return coord - - elif spl.type=="NURBS": - data = getnurbspoints(spl, mw) - pts = data[0] - ws = data[1] - order = spl.order_u - n = len(pts) - ctype = spl.use_endpoint_u - kv = knots(n, order, ctype) - - coord = C(t, order-1, pts, ws, kv) - - return coord + + spl=None + mw = obj.matrix_world + if obj.data.splines.active==None: + if len(obj.data.splines)>0: + spl=obj.data.splines[0] + else: + spl = obj.data.splines.active + + if spl==None: + return False + + if spl.type=="BEZIER": + points = spl.bezier_points + nsegs = len(points)-1 + + d = 1.0/nsegs + seg = int(t/d) + t1 = t/d - int(t/d) + + if t==1: + seg-=1 + t1 = 1.0 + + p = getbezpoints(spl,mw, seg) + + coord = cubic(p, t1) + + return coord + + elif spl.type=="NURBS": + data = getnurbspoints(spl, mw) + pts = data[0] + ws = data[1] + order = spl.order_u + n = len(pts) + ctype = spl.use_endpoint_u + kv = knots(n, order, ctype) + + coord = C(t, order-1, pts, ws, kv) + + return coord #length of the curve def arclength(objs): - length = 0.0 - - for obj in objs: - if obj.type=="CURVE": - prec = 1000 #precision - inc = 1/prec #increments - - ### TODO: set a custom precision value depending the number of curve points - #that way it can gain on accuracy in less operations. - - #subdivide the curve in 1000 lines and sum its magnitudes - for i in range(0, prec): - ti = i*inc - tf = (i+1)*inc - a = calct(obj, ti) - b = calct(obj, tf) - r = (b-a).magnitude - length+=r - - return length + length = 0.0 + + for obj in objs: + if obj.type=="CURVE": + prec = 1000 #precision + inc = 1/prec #increments + + ### TODO: set a custom precision value depending the number of curve points + #that way it can gain on accuracy in less operations. + + #subdivide the curve in 1000 lines and sum its magnitudes + for i in range(0, prec): + ti = i*inc + tf = (i+1)*inc + a = calct(obj, ti) + b = calct(obj, tf) + r = (b-a).magnitude + length+=r + + return length class ArcLengthOperator(bpy.types.Operator): - bl_idname = "curve.arc_length_operator" - bl_label = "Measures the length of a curve" + bl_idname = "curve.arc_length_operator" + bl_label = "Measures the length of a curve" + + @classmethod + def poll(cls, context): + return context.active_object != None + + def execute(self, context): + objs = context.selected_objects + context.scene.clen = arclength(objs) + return {'FINISHED'} - @classmethod - def poll(cls, context): - return context.active_object != None - - def execute(self, context): - objs = context.selected_objects - context.scene.clen = arclength(objs) - return {'FINISHED'} - ### LOFT INTERPOLATIONS #objs = selected objects @@ -365,12 +364,12 @@ #linear def intl(objs, i, t, tr): - p1 = calct(objs[i],t) - p2 = calct(objs[i+1], t) - - r = p1 + (p2 - p1)*tr - - return r + p1 = calct(objs[i],t) + p2 = calct(objs[i+1], t) + + r = p1 + (p2 - p1)*tr + + return r #tipo = interpolation type #tension and bias are for hermite interpolation @@ -378,70 +377,70 @@ #cubic def intc(objs, i, t, tr, tipo=3, tension=0.0, bias=0.0): - - ncurves =len(objs) - - #if 2 curves go to linear interpolation regardless the one you choose - if ncurves<3: - return intl(objs, i, t, tr) - else: - - #calculates the points to be interpolated on each curve - if i==0: - p0 = calct(objs[i], t) - p1 = p0 - p2 = calct(objs[i+1], t) - p3 = calct(objs[i+2], t) - else: - if ncurves-2 == i: - p0 = calct(objs[i-1], t) - p1 = calct(objs[i], t) - p2 = calct(objs[i+1], t) - p3 = p2 - else: - p0 = calct(objs[i-1], t) - p1 = calct(objs[i], t) - p2 = calct(objs[i+1], t) - p3 = calct(objs[i+2], t) - - - #calculates the interpolation between those points - #i used methods from this page: http://paulbourke.net/miscellaneous/interpolation/ - - if tipo==0: - #linear - return intl(objs, i, t, tr) - elif tipo == 1: - #natural cubic - t2 = tr*tr - a0 = p3-p2-p0+p1 - a1 = p0-p1-a0 - a2 = p2-p0 - a3 = p1 - return a0*tr*t2 + a1*t2+a2*tr+a3 - elif tipo == 2: - #catmull it seems to be working. ill leave it for now. - t2 = tr*tr - a0 = -0.5*p0 +1.5*p1 -1.5*p2 +0.5*p3 - a1 = p0 - 2.5*p1 + 2*p2 -0.5*p3 - a2 = -0.5*p0 + 0.5 *p2 - a3 = p1 - return a0*tr*tr + a1*t2+a2*tr+a3 - - elif tipo == 3: - #hermite - tr2 = tr*tr - tr3 = tr2*tr - m0 = (p1-p0)*(1+bias)*(1-tension)/2 - m0+= (p2-p1)*(1-bias)*(1-tension)/2 - m1 = (p2-p1)*(1+bias)*(1-tension)/2 - m1+= (p3-p2)*(1-bias)*(1-tension)/2 - a0 = 2*tr3 - 3*tr2 + 1 - a1 = tr3 - 2 * tr2+ tr - a2 = tr3 - tr2 - a3 = -2*tr3 + 3*tr2 - - return a0*p1+a1*m0+a2*m1+a3*p2 + + ncurves =len(objs) + + #if 2 curves go to linear interpolation regardless the one you choose + if ncurves<3: + return intl(objs, i, t, tr) + else: + + #calculates the points to be interpolated on each curve + if i==0: + p0 = calct(objs[i], t) + p1 = p0 + p2 = calct(objs[i+1], t) + p3 = calct(objs[i+2], t) + else: + if ncurves-2 == i: + p0 = calct(objs[i-1], t) + p1 = calct(objs[i], t) + p2 = calct(objs[i+1], t) + p3 = p2 + else: + p0 = calct(objs[i-1], t) + p1 = calct(objs[i], t) + p2 = calct(objs[i+1], t) + p3 = calct(objs[i+2], t) + + + #calculates the interpolation between those points + #i used methods from this page: http://paulbourke.net/miscellaneous/interpolation/ + + if tipo==0: + #linear + return intl(objs, i, t, tr) + elif tipo == 1: + #natural cubic + t2 = tr*tr + a0 = p3-p2-p0+p1 + a1 = p0-p1-a0 + a2 = p2-p0 + a3 = p1 + return a0*tr*t2 + a1*t2+a2*tr+a3 + elif tipo == 2: + #catmull it seems to be working. ill leave it for now. + t2 = tr*tr + a0 = -0.5*p0 +1.5*p1 -1.5*p2 +0.5*p3 + a1 = p0 - 2.5*p1 + 2*p2 -0.5*p3 + a2 = -0.5*p0 + 0.5 *p2 + a3 = p1 + return a0*tr*tr + a1*t2+a2*tr+a3 + + elif tipo == 3: + #hermite + tr2 = tr*tr + tr3 = tr2*tr + m0 = (p1-p0)*(1+bias)*(1-tension)/2 + m0+= (p2-p1)*(1-bias)*(1-tension)/2 + m1 = (p2-p1)*(1+bias)*(1-tension)/2 + m1+= (p3-p2)*(1-bias)*(1-tension)/2 + a0 = 2*tr3 - 3*tr2 + 1 + a1 = tr3 - 2 * tr2+ tr + a2 = tr3 - tr2 + a3 = -2*tr3 + 3*tr2 + + return a0*p1+a1*m0+a2*m1+a3*p2 #handles loft driver expression @@ -452,48 +451,48 @@ #3 interpolation type def loftdriver(name, objs, intype): - #print("ejecutando "+name) - intype = int(intype) - - tension = 0.0 - bias = 0.5 - #if the loft object still exists proceed normal - try: - resobj = bpy.data.objects[name] - spans = resobj["spans"] - steps = resobj["steps"] - if intype==3: #hermite - tension = resobj['tension'] - bias = resobj['bias'] - - #if not delete the driver - except: - curve = bpy.context.object - for it in curve.keys(): - if it == "driver": - curve.driver_remove('["driver"]') - return False - - objs = objs.split(";") - #objs = objs[0:-1] - - - #retrieves the curves from the objs string - for i, l in enumerate(objs): - objs[i] = bpy.data.objects[l] - - - - #calcs the new vertices coordinates if we change the curves. - vxs = loft(objs, steps, spans, intype, tension, bias) - - #apply the new cordinates to the loft object - me = resobj.data - - for i in range(0, len(me.vertices)): - me.vertices[i].co = vxs[i] - me.update() - return spans + #print("ejecutando "+name) + intype = int(intype) + + tension = 0.0 + bias = 0.5 + #if the loft object still exists proceed normal + try: + resobj = bpy.data.objects[name] + spans = resobj["spans"] + steps = resobj["steps"] + if intype==3: #hermite + tension = resobj['tension'] + bias = resobj['bias'] + + #if not delete the driver + except: + curve = bpy.context.object + for it in curve.keys(): + if it == "driver": + curve.driver_remove('["driver"]') + return False + + objs = objs.split(";") + #objs = objs[0:-1] + + + #retrieves the curves from the objs string + for i, l in enumerate(objs): + objs[i] = bpy.data.objects[l] + + + + #calcs the new vertices coordinates if we change the curves. + vxs = loft(objs, steps, spans, intype, tension, bias) + + #apply the new cordinates to the loft object + me = resobj.data + + for i in range(0, len(me.vertices)): + me.vertices[i].co = vxs[i] + me.update() + return spans #NOTES: #loftdriver function will fail or produce weird results if: @@ -504,152 +503,152 @@ #creates the drivers expressions for each curve def createloftdriver(objs, res, intype): - - line = "" - for obj in objs: - line+=obj.name+";" - line=line[0:-1] - name = res.name - - interp = str(intype) - - for obj in objs: - obj["driver"] = 1.0 - - obj.driver_add('["driver"]') - obj.animation_data.drivers[0].driver.expression = "loftdriver('"+ name +"', '" + line + "', "+interp+")" - - - ### creating this driver will execute loft all the time without reason, - #and if i cant drive the mesh i cannot implement live tension and bias - -# res['driver'] = 1.0 -# if res.animation_data==None: -# res.animation_data_create() -# res.driver_add('["driver"]') -# res.animation_data.drivers[0].driver.expression = "loftdriver('"+ name +"', '" + line + "', "+interp+")" + + line = "" + for obj in objs: + line+=obj.name+";" + line=line[0:-1] + name = res.name + + interp = str(intype) + + for obj in objs: + obj["driver"] = 1.0 + + obj.driver_add('["driver"]') + obj.animation_data.drivers[0].driver.expression = "loftdriver('"+ name +"', '" + line + "', "+interp+")" + + + ### creating this driver will execute loft all the time without reason, + #and if i cant drive the mesh i cannot implement live tension and bias + +# res['driver'] = 1.0 +# if res.animation_data==None: +# res.animation_data_create() +# res.driver_add('["driver"]') +# res.animation_data.drivers[0].driver.expression = "loftdriver('"+ name +"', '" + line + "', "+interp+")" #calculates the vertices position of the loft object def loft(objs, steps, spans, interpolation=1, tension=0.0, bias=0.5): - verts=[] - - for i in range(0, len(objs)): - - for j in range(0,steps+1): - t = 1.0*j/steps - verts.append(calct(objs[i], t)) - - temp2=[] - if i0: - for drv in obj.animation_data.drivers: - if drv.data_path=='["driver"]': - cad = drv.driver.expression - drv.driver.expression = "" - drv.driver.expression = cad - - return {'FINISHED'} + '''Tooltip''' + bl_idname = "mesh.update_fix" + bl_label = "Update fix" + + @classmethod + def poll(cls, context): + return context.active_object != None + + def execute(self, context): + #print("------------") +# for it in bpy.app.driver_namespace: +# print(it) + bpy.app.driver_namespace['loftdriver'] = loftdriver + bpy.app.driver_namespace['birail1driver'] = birail1driver + for obj in context.scene.objects: + if obj.type=="CURVE" and obj.animation_data!=None and len(obj.animation_data.drivers)>0: + for drv in obj.animation_data.drivers: + if drv.data_path=='["driver"]': + cad = drv.driver.expression + drv.driver.expression = "" + drv.driver.expression = cad + + return {'FINISHED'} #derives a curve at a given parameter def deriv(curve, t, unit=False): - - a = t + 0.001 - if t==1: a=t-0.001 - - pos = calct(curve, t) - der = (pos-calct(curve, a))/(t-a) - if unit: - der = der/der.magnitude - return der + + a = t + 0.001 + if t==1: a=t-0.001 + + pos = calct(curve, t) + der = (pos-calct(curve, a))/(t-a) + if unit: + der = der/der.magnitude + return der ### BIRAIL1 BLOCK @@ -662,165 +661,165 @@ ### TODO: when the 3 curves are coplanar it should fail, cause the cross product. check that def birail1(objs, steps, spans, proportional): - profile=objs[0] - ### TODO: identify which path is left or right - path1 = objs[1] - path2 = objs[2] - - trans = [] - - r0 = [calct(path1,0), calct(path2, 0)] - r0mag = (r0[1]-r0[0]).magnitude - - for i in range(0, steps): - u = i/(steps-1) - appr0 = r0[0]+(r0[1]-r0[0])*u - trans.append(calct(profile, u)-appr0) - - der10 = deriv(path1, 0) - der20 = deriv(path2, 0) - - verts = [] - - mult = 1.0 - - for i in range(0, spans): - v = i/(spans-1) - r = [calct(path1, v),calct(path2, v)] - rmag = (r[1]-r[0]).magnitude - - der1 = deriv(path1, v) - der2 = deriv(path2, v) - - angle1 = der10.angle(der1) - angle2 = der20.angle(der2) - - #if angle1!=0.0 and angle2!=0: we can avoid some operations by doing this check but im lazy - cr1 = der1.cross(der10) - rot1 = Matrix().Rotation(-angle1, 3, cr1) - - cr2 = der2.cross(der20) - rot2 = Matrix().Rotation(-angle2, 3, cr2) - - if proportional: - mult = rmag/r0mag - - for j in range(0, steps): - u = j/(steps-1) - - app = r[0]+(r[1]-r[0])*u - - newtr1 = trans[j].copy() - newtr1.rotate(rot1) - - newtr2 = trans[j].copy() - newtr2.rotate(rot2) - - r1 = (newtr1-trans[j])*(1-u) - r2 = (newtr2-trans[j])*(u) - - res = r1+r2+app+mult*trans[j] - - verts.append(res) - - return verts + profile=objs[0] + ### TODO: identify which path is left or right + path1 = objs[1] + path2 = objs[2] + + trans = [] + + r0 = [calct(path1,0), calct(path2, 0)] + r0mag = (r0[1]-r0[0]).magnitude + + for i in range(0, steps): + u = i/(steps-1) + appr0 = r0[0]+(r0[1]-r0[0])*u + trans.append(calct(profile, u)-appr0) + + der10 = deriv(path1, 0) + der20 = deriv(path2, 0) + + verts = [] + + mult = 1.0 + + for i in range(0, spans): + v = i/(spans-1) + r = [calct(path1, v),calct(path2, v)] + rmag = (r[1]-r[0]).magnitude + + der1 = deriv(path1, v) + der2 = deriv(path2, v) + + angle1 = der10.angle(der1) + angle2 = der20.angle(der2) + + #if angle1!=0.0 and angle2!=0: we can avoid some operations by doing this check but im lazy + cr1 = der1.cross(der10) + rot1 = Matrix().Rotation(-angle1, 3, cr1) + + cr2 = der2.cross(der20) + rot2 = Matrix().Rotation(-angle2, 3, cr2) + + if proportional: + mult = rmag/r0mag + + for j in range(0, steps): + u = j/(steps-1) + + app = r[0]+(r[1]-r[0])*u + + newtr1 = trans[j].copy() + newtr1.rotate(rot1) + + newtr2 = trans[j].copy() + newtr2.rotate(rot2) + + r1 = (newtr1-trans[j])*(1-u) + r2 = (newtr2-trans[j])*(u) + + res = r1+r2+app+mult*trans[j] + + verts.append(res) + + return verts #same as loft driver ### TODO check if it is registered def birail1driver(name, objs): - objs = objs.split(";") - #objs = objs[0:-1] - - for i, l in enumerate(objs): - objs[i] = bpy.data.objects[l] - - try: - resobj = bpy.data.objects[name] - spans = resobj["spans"] - steps = resobj["steps"] - prop = resobj["prop"] - - except: - curve = bpy.context.object - curve.driver_remove('["driver"]') - return False - - vxs = birail1(objs, steps, spans, prop) - - me = resobj.data - - for i in range(0, len(me.vertices)): - me.vertices[i].co = vxs[i] - me.update() - return spans - + objs = objs.split(";") + #objs = objs[0:-1] + + for i, l in enumerate(objs): + objs[i] = bpy.data.objects[l] + + try: + resobj = bpy.data.objects[name] + spans = resobj["spans"] + steps = resobj["steps"] + prop = resobj["prop"] + + except: + curve = bpy.context.object + curve.driver_remove('["driver"]') + return False + + vxs = birail1(objs, steps, spans, prop) + + me = resobj.data + + for i in range(0, len(me.vertices)): + me.vertices[i].co = vxs[i] + me.update() + return spans + def createbirail1driver(objs, res): - - line = "" - for obj in objs: - line+=obj.name+";" - line=line[0:-1] - for obj in objs: - obj["driver"] = 1.0 - obj.driver_add('["driver"]') - obj.animation_data.drivers[0].driver.expression = "birail1driver('"+ res.name +"', '" + line + "')" + + line = "" + for obj in objs: + line+=obj.name+";" + line=line[0:-1] + for obj in objs: + obj["driver"] = 1.0 + obj.driver_add('["driver"]') + obj.animation_data.drivers[0].driver.expression = "birail1driver('"+ res.name +"', '" + line + "')" ### TODO: check polls and if initial variables are ok to perform the birail class Birail1Operator(bpy.types.Operator): - bl_idname = "mesh.birail1_operator" - bl_label = "Birail between 3 bezier curves" - - @classmethod - def poll(cls, context): - return context.active_object != None - - def execute(self, context): - - objs = bpy.selection - - if len(objs)!=3: - self.report("ERROR","Please select 3 curves") - return {'FINISHED'} - - scn = context.scene - spans = scn.spans - steps = scn.steps - prop = scn.proportional - - verts = birail1(objs, steps, spans, prop) - - if verts!=[]: - faces=[] - - nfaces = (steps-1)*(spans-1) - - for i in range(0, nfaces): - d = int(i/(steps-1)) - f = [i+d+1, i+d, i+d+steps, i+d+steps+1 ] - faces.append(f) - - me = bpy.data.meshes.new("Birail") - me.from_pydata(verts,[], faces) - me.update() - newobj = bpy.data.objects.new("Birail", me) - newobj.data = me - - scn.objects.link(newobj) - scn.objects.active = newobj - newobj.select = True - bpy.ops.object.shade_smooth() - newobj['steps']=steps - newobj['spans']=spans - newobj['prop']=prop - - if scn.dodriver: - createbirail1driver(objs, newobj) - - return {'FINISHED'} - + bl_idname = "mesh.birail1_operator" + bl_label = "Birail between 3 bezier curves" + + @classmethod + def poll(cls, context): + return context.active_object != None + + def execute(self, context): + + objs = bpy.selection + + if len(objs)!=3: + self.report("ERROR","Please select 3 curves") + return {'FINISHED'} + + scn = context.scene + spans = scn.spans + steps = scn.steps + prop = scn.proportional + + verts = birail1(objs, steps, spans, prop) + + if verts!=[]: + faces=[] + + nfaces = (steps-1)*(spans-1) + + for i in range(0, nfaces): + d = int(i/(steps-1)) + f = [i+d+1, i+d, i+d+steps, i+d+steps+1 ] + faces.append(f) + + me = bpy.data.meshes.new("Birail") + me.from_pydata(verts,[], faces) + me.update() + newobj = bpy.data.objects.new("Birail", me) + newobj.data = me + + scn.objects.link(newobj) + scn.objects.active = newobj + newobj.select = True + bpy.ops.object.shade_smooth() + newobj['steps']=steps + newobj['spans']=spans + newobj['prop']=prop + + if scn.dodriver: + createbirail1driver(objs, newobj) + + return {'FINISHED'} + #register the drivers bpy.app.driver_namespace['loftdriver'] = loftdriver bpy.app.driver_namespace['birail1driver'] = birail1driver @@ -831,28 +830,28 @@ #spl spline to read #rev reads the spline forward or backwards def readspline(spl, rev=0): - res = [] - - if spl.type=="BEZIER": - points = spl.bezier_points - for p in points: - if rev: - h2 = p.handle_left - h1 = p.handle_right - h2type = p.handle_left_type - h1type = p.handle_right_type - else: - h1 = p.handle_left - h2 = p.handle_right - h1type = p.handle_left_type - h2type = p.handle_right_type - - co = p.co - res.append([h1, co, h2, h1type, h2type]) - if rev: - res.reverse() - - return res + res = [] + + if spl.type=="BEZIER": + points = spl.bezier_points + for p in points: + if rev: + h2 = p.handle_left + h1 = p.handle_right + h2type = p.handle_left_type + h1type = p.handle_right_type + else: + h1 = p.handle_left + h2 = p.handle_right + h1type = p.handle_left_type + h2type = p.handle_right_type + + co = p.co + res.append([h1, co, h2, h1type, h2type]) + if rev: + res.reverse() + + return res #returns a new merged spline #cu curve object @@ -860,139 +859,139 @@ #pts2 points from the second spline def merge(cu, pts1, pts2): - newspl = cu.data.splines.new(type="BEZIER") - for i, p in enumerate(pts1): - - if i>0: newspl.bezier_points.add() - newspl.bezier_points[i].handle_left = p[0] - newspl.bezier_points[i].co = p[1] - newspl.bezier_points[i].handle_right = p[2] - newspl.bezier_points[i].handle_left_type = p[3] - newspl.bezier_points[i].handle_right_type = p[4] - - newspl.bezier_points[-1].handle_right_type="FREE" - newspl.bezier_points[-1].handle_left_type="FREE" - - newspl.bezier_points[-1].handle_right = pts2[0][2] - - - for j in range(1, len(pts2)): - - newspl.bezier_points.add() - newspl.bezier_points[-1].handle_left = pts2[j][0] - newspl.bezier_points[-1].co = pts2[j][1] - newspl.bezier_points[-1].handle_right = pts2[j][2] - newspl.bezier_points[-1].handle_left_type = pts2[j][3] - newspl.bezier_points[-1].handle_right_type = pts2[j][4] + newspl = cu.data.splines.new(type="BEZIER") + for i, p in enumerate(pts1): + + if i>0: newspl.bezier_points.add() + newspl.bezier_points[i].handle_left = p[0] + newspl.bezier_points[i].co = p[1] + newspl.bezier_points[i].handle_right = p[2] + newspl.bezier_points[i].handle_left_type = p[3] + newspl.bezier_points[i].handle_right_type = p[4] - return newspl + newspl.bezier_points[-1].handle_right_type="FREE" + newspl.bezier_points[-1].handle_left_type="FREE" -#looks if the splines first and last points are close to another spline + newspl.bezier_points[-1].handle_right = pts2[0][2] + + + for j in range(1, len(pts2)): + + newspl.bezier_points.add() + newspl.bezier_points[-1].handle_left = pts2[j][0] + newspl.bezier_points[-1].co = pts2[j][1] + newspl.bezier_points[-1].handle_right = pts2[j][2] + newspl.bezier_points[-1].handle_left_type = pts2[j][3] + newspl.bezier_points[-1].handle_right_type = pts2[j][4] + + return newspl + +#looks if the splines first and last points are close to another spline ### TODO: Check if the objects selected are valid ### if possible implement nurbs class MergeSplinesOperator(bpy.types.Operator): - bl_idname = "curve.merge_splines" - bl_label = "Merges spline points inside a limit" - - @classmethod - def poll(cls, context): - return context.active_object != None - - def execute(self, context): - curves = [] - limit = context.scene.limit - print("merguing") - for obj in context.selected_objects: - if obj.type=="CURVE": - curves.append(obj) - - for cu in curves: - splines = [] - for spl in cu.data.splines: - splines.append(spl) - print(splines) - #compares all the splines inside a curve object - for spl1 in splines: - for spl2 in splines: - print(spl1, spl2) - if spl1!=spl2 and spl1.type==spl2.type=="BEZIER" and spl1.use_cyclic_u==spl2.use_cyclic_u==False: - print("not cyclic") - if len(spl1.bezier_points)>1 and len(spl2.bezier_points)>1: - - #edges of the 2 splines - p1i = spl1.bezier_points[0].co - p1f = spl1.bezier_points[-1].co - p2i = spl2.bezier_points[0].co - p2f = spl2.bezier_points[-1].co - - if dist(p1i, p2i)1 and len(spl2.bezier_points)>1: + + #edges of the 2 splines + p1i = spl1.bezier_points[0].co + p1f = spl1.bezier_points[-1].co + p2i = spl2.bezier_points[0].co + p2f = spl2.bezier_points[-1].co + + if dist(p1i, p2i)=1.0: - t=1.0 - seg-=1 - t1 = 1.0 - - #if t1 is not inside a segment dont perform any action - if t1>0.0 and t1<1.0: - mw = obj.matrix_world - mwi = obj.matrix_world.copy().inverted() - - pts = getbezpoints(spline, mw, seg) - - #position on the curve to perform the action - pos = calct(obj, t) - - #De Casteljau's algorithm to get the handles - #http://en.wikipedia.org/wiki/De_Casteljau%27s_algorithm - h1 = pts[0]+(pts[1]-pts[0])*t1 - h4 = pts[2]+(pts[3]-pts[2])*t1 - r = pts[1]+(pts[2]-pts[1])*t1 - h2 = h1+(r-h1)*t1 - h3 = r+(h4-r)*t1 - - - if method: - #SUBDIVIDE - splp = [] - type = "ALIGNED" - for i, p in enumerate(points): - ph1 = p.handle_left*mw - pco = p.co*mw - ph2 = p.handle_right*mw - ph1type = p.handle_left_type - ph2type = p.handle_right_type - splp.append([ph1, pco, ph2, ph1type, ph2type]) - p.handle_left_type = type - p.handle_right_type = type - - if i==seg: - splp[-1][2]=h1 - splp.append([h2, pos, h3, type, type]) - - if i==seg+1: - splp[-1][0]=h4 - splp[-1][3]=type - splp[-1][4]=type - #if i dont set all the handles to "FREE" - #it returns weirds result - ### TODO: find out how to preserve handle's types - - points.add() - for i, p in enumerate(points): - p.handle_left_type = "FREE" - p.handle_right_type ="FREE" - p.handle_left = splp[i][0]*mwi - p.co = splp[i][1]*mwi - p.handle_right=splp[i][2]*mwi - p.handle_left_type = splp[i][3] - p.handle_right_type =splp[i][4] - else: - #SPLIT CURVE - spl1 = [] - spl2 = [] - k=0 #changes to 1 when the first spline is processed - type = "ALIGNED" - for i, p in enumerate(points): - ph1 = p.handle_left*mw - pco = p.co*mw - ph2 = p.handle_right*mw - ph1type = p.handle_left_type - ph2type = p.handle_right_type - if k==0: - spl1.append([ph1, pco, ph2, ph1type, ph2type]) - else: - spl2.append([ph1, pco, ph2, ph1type, ph2type]) - - if i==seg: - spl1[-1][2]=h1 - spl1.append([h2, pos, h3, type, type]) - spl2.append([h2, pos, h3, type, type]) - k=1 - - if i==seg+1: - spl2[-1][0]=h4 - spl2[-1][3]=type - spl2[-1][4]=type - - sp1 = obj.data.splines.new(type="BEZIER") - for i, p in enumerate(spl1): - if i>0: sp1.bezier_points.add() - sp1.bezier_points[i].handle_left_type = "FREE" - sp1.bezier_points[i].handle_right_type ="FREE" - sp1.bezier_points[i].handle_left = spl1[i][0]*mwi - sp1.bezier_points[i].co = spl1[i][1]*mwi - sp1.bezier_points[i].handle_right=spl1[i][2]*mwi - #i tried to preserve the handles here but - #didnt work well - - sp1.bezier_points[i].handle_left_type = spl1[i][3] - sp1.bezier_points[i].handle_right_type =spl1[i][4] - - sp2 = obj.data.splines.new(type="BEZIER") - for i, p in enumerate(spl2): - if i>0: sp2.bezier_points.add() - sp2.bezier_points[i].handle_left_type = "FREE" - sp2.bezier_points[i].handle_right_type = "FREE" - sp2.bezier_points[i].handle_left = spl2[i][0]*mwi - sp2.bezier_points[i].co = spl2[i][1]*mwi - sp2.bezier_points[i].handle_right=spl2[i][2]*mwi - sp2.bezier_points[i].handle_left_type = spl2[i][3] - sp2.bezier_points[i].handle_right_type =spl2[i][4] - - obj.data.splines.remove(spline) + #flocal to global transforms or viceversa + + + #retrieves the active spline or the first spline if there no one active + + spline=None + if obj.data.splines.active==None: + for sp in obj.data.splines: + if sp.type=="BEZIER": + spline= sp + break + else: + if obj.data.splines.active.type!="BEZIER": + return False + else: + spline=obj.data.splines.active + + if spline==None: return False + + points = spline.bezier_points + nsegs = len(points)-1 + + #transform global t into local t1 + d = 1.0/nsegs + seg = int(t/d) + t1 = t/d-int(t/d) + if t>=1.0: + t=1.0 + seg-=1 + t1 = 1.0 + + #if t1 is not inside a segment dont perform any action + if t1>0.0 and t1<1.0: + mw = obj.matrix_world + mwi = obj.matrix_world.copy().inverted() + + pts = getbezpoints(spline, mw, seg) + + #position on the curve to perform the action + pos = calct(obj, t) + + #De Casteljau's algorithm to get the handles + #http://en.wikipedia.org/wiki/De_Casteljau%27s_algorithm + h1 = pts[0]+(pts[1]-pts[0])*t1 + h4 = pts[2]+(pts[3]-pts[2])*t1 + r = pts[1]+(pts[2]-pts[1])*t1 + h2 = h1+(r-h1)*t1 + h3 = r+(h4-r)*t1 + + + if method: + #SUBDIVIDE + splp = [] + type = "ALIGNED" + for i, p in enumerate(points): + ph1 = p.handle_left*mw + pco = p.co*mw + ph2 = p.handle_right*mw + ph1type = p.handle_left_type + ph2type = p.handle_right_type + splp.append([ph1, pco, ph2, ph1type, ph2type]) + p.handle_left_type = type + p.handle_right_type = type + + if i==seg: + splp[-1][2]=h1 + splp.append([h2, pos, h3, type, type]) + + if i==seg+1: + splp[-1][0]=h4 + splp[-1][3]=type + splp[-1][4]=type + #if i dont set all the handles to "FREE" + #it returns weirds result + ### TODO: find out how to preserve handle's types + + points.add() + for i, p in enumerate(points): + p.handle_left_type = "FREE" + p.handle_right_type ="FREE" + p.handle_left = splp[i][0]*mwi + p.co = splp[i][1]*mwi + p.handle_right=splp[i][2]*mwi + p.handle_left_type = splp[i][3] + p.handle_right_type =splp[i][4] + else: + #SPLIT CURVE + spl1 = [] + spl2 = [] + k=0 #changes to 1 when the first spline is processed + type = "ALIGNED" + for i, p in enumerate(points): + ph1 = p.handle_left*mw + pco = p.co*mw + ph2 = p.handle_right*mw + ph1type = p.handle_left_type + ph2type = p.handle_right_type + if k==0: + spl1.append([ph1, pco, ph2, ph1type, ph2type]) + else: + spl2.append([ph1, pco, ph2, ph1type, ph2type]) + + if i==seg: + spl1[-1][2]=h1 + spl1.append([h2, pos, h3, type, type]) + spl2.append([h2, pos, h3, type, type]) + k=1 + + if i==seg+1: + spl2[-1][0]=h4 + spl2[-1][3]=type + spl2[-1][4]=type + + sp1 = obj.data.splines.new(type="BEZIER") + for i, p in enumerate(spl1): + if i>0: sp1.bezier_points.add() + sp1.bezier_points[i].handle_left_type = "FREE" + sp1.bezier_points[i].handle_right_type ="FREE" + sp1.bezier_points[i].handle_left = spl1[i][0]*mwi + sp1.bezier_points[i].co = spl1[i][1]*mwi + sp1.bezier_points[i].handle_right=spl1[i][2]*mwi + #i tried to preserve the handles here but + #didnt work well + + sp1.bezier_points[i].handle_left_type = spl1[i][3] + sp1.bezier_points[i].handle_right_type =spl1[i][4] + + sp2 = obj.data.splines.new(type="BEZIER") + for i, p in enumerate(spl2): + if i>0: sp2.bezier_points.add() + sp2.bezier_points[i].handle_left_type = "FREE" + sp2.bezier_points[i].handle_right_type = "FREE" + sp2.bezier_points[i].handle_left = spl2[i][0]*mwi + sp2.bezier_points[i].co = spl2[i][1]*mwi + sp2.bezier_points[i].handle_right=spl2[i][2]*mwi + sp2.bezier_points[i].handle_left_type = spl2[i][3] + sp2.bezier_points[i].handle_right_type =spl2[i][4] + + obj.data.splines.remove(spline) class CutCurveOperator(bpy.types.Operator): - '''Subdivide / Split a bezier curve.''' - bl_idname = "curve.cut_operator" - bl_label = "Cut curve operator" - - #cut or split - method = bpy.props.BoolProperty(default=False) - t = 0.0 - - @classmethod - def poll(self, context): - if context.active_object!=None: - return context.active_object.type=="CURVE" - else: - return False - - - def modal(self, context, event): - - if event.type == 'MOUSEMOVE': - #full screen width - #not tested for multiple monitors - fullw = context.window_manager.windows[0].screen.areas[0].regions[0].width - - self.t = event.mouse_x/fullw - - #limit t to [0,...,1] - if self.t<0: - self.t=0.0 - elif self.t>1.0: - self.t=1.0 - - obj = context.object - pos = calct(obj, self.t) - - #if calct() detects a non bezier spline returns false - if pos==False: - return {'CANCELLED'} - cursor(pos) - - elif event.type == 'LEFTMOUSE': - #print(self.method, self.t) - cutcurve(context.object, self.t, self.method) - return {'FINISHED'} - - elif event.type in ('RIGHTMOUSE', 'ESC'): - #print("Cancelled") - - return {'CANCELLED'} - - return {'RUNNING_MODAL'} - - def invoke(self, context, event): - - if context.object: - - context.window_manager.modal_handler_add(self) - return {'RUNNING_MODAL'} - else: - self.report({'WARNING'}, "No active object, could not finish") - return {'CANCELLED'} + '''Subdivide / Split a bezier curve.''' + bl_idname = "curve.cut_operator" + bl_label = "Cut curve operator" + + #cut or split + method = bpy.props.BoolProperty(default=False) + t = 0.0 + + @classmethod + def poll(self, context): + if context.active_object!=None: + return context.active_object.type=="CURVE" + else: + return False + + + def modal(self, context, event): + + if event.type == 'MOUSEMOVE': + #full screen width + #not tested for multiple monitors + fullw = context.window_manager.windows[0].screen.areas[0].regions[0].width + + self.t = event.mouse_x/fullw + + #limit t to [0,...,1] + if self.t<0: + self.t=0.0 + elif self.t>1.0: + self.t=1.0 + + obj = context.object + pos = calct(obj, self.t) + + #if calct() detects a non bezier spline returns false + if pos==False: + return {'CANCELLED'} + cursor(pos) + + elif event.type == 'LEFTMOUSE': + #print(self.method, self.t) + cutcurve(context.object, self.t, self.method) + return {'FINISHED'} + + elif event.type in {'RIGHTMOUSE', 'ESC'}: + #print("Cancelled") + + return {'CANCELLED'} + + return {'RUNNING_MODAL'} + + def invoke(self, context, event): + + if context.object: + + context.window_manager.modal_handler_add(self) + return {'RUNNING_MODAL'} + else: + self.report({'WARNING'}, "No active object, could not finish") + return {'CANCELLED'} ### CURVE SNAP BLOCK class AllowCurveSnap(bpy.types.Operator): - bl_idname = "curve.allow_curve_snap" - bl_label = "Allow Curve Snap" - - add = bpy.props.BoolProperty() - - @classmethod - def poll(cls, context): - return context.active_object!=None - - def execute(self, context): - add = self.add - - scn = context.scene - - if add==False: - for helper in context.scene.objects: - for key in helper.keys(): - print(key) - if key=="is_snap_helper" and helper[key]==1: - scn.objects.unlink(helper) - else: - #objs = context.selected_objects - objs = context.scene.objects - for obj in objs: - if obj.type=="CURVE": - - res = obj.data.resolution_u - - obj.data.resolution_u = 100 - - me = obj.to_mesh(scene=scn, apply_modifiers=True,settings = "PREVIEW" ) - obj.data.resolution_u = res - newobj = bpy.data.objects.new(obj.name+"_snap", me) - scn.objects.link(newobj) - newobj.layers = obj.layers - newobj.matrix_world = obj.matrix_world - newobj["is_snap_helper"]=True - newobj.hide_render=True - newobj.hide_select = True - cons = newobj.constraints.new(type="COPY_TRANSFORMS") - cons.target =obj - - return {'FINISHED'} + bl_idname = "curve.allow_curve_snap" + bl_label = "Allow Curve Snap" + + add = bpy.props.BoolProperty() + + @classmethod + def poll(cls, context): + return context.active_object!=None + + def execute(self, context): + add = self.add + + scn = context.scene + + if add==False: + for helper in context.scene.objects: + for key in helper.keys(): + print(key) + if key=="is_snap_helper" and helper[key]==1: + scn.objects.unlink(helper) + else: + #objs = context.selected_objects + objs = context.scene.objects + for obj in objs: + if obj.type=="CURVE": + + res = obj.data.resolution_u + + obj.data.resolution_u = 100 + + me = obj.to_mesh(scene=scn, apply_modifiers=True,settings = "PREVIEW" ) + obj.data.resolution_u = res + newobj = bpy.data.objects.new(obj.name+"_snap", me) + scn.objects.link(newobj) + newobj.layers = obj.layers + newobj.matrix_world = obj.matrix_world + newobj["is_snap_helper"]=True + newobj.hide_render=True + newobj.hide_select = True + cons = newobj.constraints.new(type="COPY_TRANSFORMS") + cons.target =obj + + return {'FINISHED'} def menu_func(self, context): - self.layout.operator("curve.allow_curve_snap").add=True - self.layout.operator("curve.allow_curve_snap", text = "Delete Snap Helpers").add=False - + self.layout.operator("curve.allow_curve_snap").add=True + self.layout.operator("curve.allow_curve_snap", text = "Delete Snap Helpers").add=False + ### PANEL class CurvePanel(bpy.types.Panel): - bl_label = "Curve Tools" - bl_space_type = "VIEW_3D" - bl_region_type = "TOOLS" - #bl_options = {'REGISTER', 'UNDO'} - #bl_context = "data" - - steps = IntProperty(min=2, default = 12) - - @classmethod - def poll(cls, context): - return (context.active_object != None) and (context.active_object.type=="CURVE") - def draw(self, context): - layout = self.layout - - obj = context.object - scn = context.scene - - align = True - row = layout.row(align=align) - - row.prop(context.scene, "intype", text = "") - row.prop(context.scene, "dodriver", text = "Driven") - if scn.intype=='3': #Hermite interp - row = layout.row(align=align) - row.prop(scn, "tension") - row.prop(scn, "bias") - - row = layout.row(align=align) - row.prop(context.scene, "steps") - row.prop(context.scene, "spans") - row = layout.row(align=align) - row.operator("mesh.loft_operator", text = "Loft") - row.operator("mesh.update_fix", text = "Update Fix") - row = layout.row(align=align) - row.operator("mesh.birail1_operator", text = "Birail 1") - row.prop(context.scene, "proportional", text = "Proportional") - row = layout.row(align=align) - row.operator("curve.arc_length_operator", text = "Calc Length") - row.prop(context.scene, "clen", text = "") - row = layout.row(align=align) - row.operator("curve.merge_splines", text = "Merge") - row.prop(context.scene,"limit", text = "Limit") - row = layout.row(align=align) - row.operator("curve.cut_operator", text="Subdivide").method=True - row.operator("curve.cut_operator", text="Split").method=False - -# col1 = row.column() -# col1.prop(context.scene, "intype", text = "") -# col1.prop(context.scene, "dodriver", text = "Driven") -# row = layout.row(align=align) -# col2 = row.column(align=align) -# col2.prop(context.scene, "steps") -# col2.prop(context.scene, "spans") -# row = layout.row(align=align) -# row.operator("mesh.loft_operator", text = "Loft") -# row.operator("mesh.update_fix", text = "Update Fix") -# row = layout.row(align=align) -# row.operator("mesh.birail1_operator", text = "Birail 1") -# row.prop(context.scene, "proportional", text = "Proportional") -# row = layout.row(align=align) -# row.operator("curve.arc_length_operator", text = "Calc Length") -# row.prop(context.scene, "clen", text = "") -# row = layout.row(align=align) -# row.operator("curve.merge_splines", text = "Merge") -# row.prop(context.scene,"limit", text = "Limit") -# row = layout.row(align=align) -# row.operator("curve.cut_operator", text="Subdivide").method=True -# row.operator("curve.cut_operator", text="Split").method=False - + bl_label = "Curve Tools" + bl_space_type = "VIEW_3D" + bl_region_type = "TOOLS" + #bl_options = {'REGISTER', 'UNDO'} + #bl_context = "data" + + steps = IntProperty(min=2, default = 12) + + @classmethod + def poll(cls, context): + return (context.active_object != None) and (context.active_object.type=="CURVE") + def draw(self, context): + layout = self.layout + + obj = context.object + scn = context.scene + + align = True + row = layout.row(align=align) + + row.prop(context.scene, "intype", text = "") + row.prop(context.scene, "dodriver", text = "Driven") + if scn.intype=='3': #Hermite interp + row = layout.row(align=align) + row.prop(scn, "tension") + row.prop(scn, "bias") + + row = layout.row(align=align) + row.prop(context.scene, "steps") + row.prop(context.scene, "spans") + row = layout.row(align=align) + row.operator("mesh.loft_operator", text = "Loft") + row.operator("mesh.update_fix", text = "Update Fix") + row = layout.row(align=align) + row.operator("mesh.birail1_operator", text = "Birail 1") + row.prop(context.scene, "proportional", text = "Proportional") + row = layout.row(align=align) + row.operator("curve.arc_length_operator", text = "Calc Length") + row.prop(context.scene, "clen", text = "") + row = layout.row(align=align) + row.operator("curve.merge_splines", text = "Merge") + row.prop(context.scene,"limit", text = "Limit") + row = layout.row(align=align) + row.operator("curve.cut_operator", text="Subdivide").method=True + row.operator("curve.cut_operator", text="Split").method=False + +# col1 = row.column() +# col1.prop(context.scene, "intype", text = "") +# col1.prop(context.scene, "dodriver", text = "Driven") +# row = layout.row(align=align) +# col2 = row.column(align=align) +# col2.prop(context.scene, "steps") +# col2.prop(context.scene, "spans") +# row = layout.row(align=align) +# row.operator("mesh.loft_operator", text = "Loft") +# row.operator("mesh.update_fix", text = "Update Fix") +# row = layout.row(align=align) +# row.operator("mesh.birail1_operator", text = "Birail 1") +# row.prop(context.scene, "proportional", text = "Proportional") +# row = layout.row(align=align) +# row.operator("curve.arc_length_operator", text = "Calc Length") +# row.prop(context.scene, "clen", text = "") +# row = layout.row(align=align) +# row.operator("curve.merge_splines", text = "Merge") +# row.prop(context.scene,"limit", text = "Limit") +# row = layout.row(align=align) +# row.operator("curve.cut_operator", text="Subdivide").method=True +# row.operator("curve.cut_operator", text="Split").method=False + classes = [AllowCurveSnap, Selection, LoftOperator, Birail1Operator, - ArcLengthOperator, UpdateFix, MergeSplinesOperator, CutCurveOperator, NurbsWeightsPanel, CurvePanel] - + ArcLengthOperator, UpdateFix, MergeSplinesOperator, CutCurveOperator, NurbsWeightsPanel, CurvePanel] + bpy.app.driver_namespace['loftdriver'] = loftdriver bpy.app.driver_namespace['birail1driver'] = birail1driver def register(): - - domenu=1 - for op in dir(bpy.types): - if op=="CURVE_OT_allow_curve_snap": - domenu=0 - break - if domenu: - bpy.types.VIEW3D_MT_object_specials.append(menu_func) - - for c in classes: - bpy.utils.register_class(c) - + + domenu=1 + for op in dir(bpy.types): + if op=="CURVE_OT_allow_curve_snap": + domenu=0 + break + if domenu: + bpy.types.VIEW3D_MT_object_specials.append(menu_func) + + for c in classes: + bpy.utils.register_class(c) + def unregister(): - for c in classes: - bpy.utils.unregister_class(c) + for c in classes: + bpy.utils.unregister_class(c) - bpy.types.VIEW3D_MT_object_specials.remove(menu_func) + bpy.types.VIEW3D_MT_object_specials.remove(menu_func) if __name__ == "__main__": - register() + register() diff -Nru blender-2.61/release/scripts/addons_contrib/development_class_viewer.py blender-2.62/release/scripts/addons_contrib/development_class_viewer.py --- blender-2.61/release/scripts/addons_contrib/development_class_viewer.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/development_class_viewer.py 2012-02-15 19:43:59.000000000 +0000 @@ -17,16 +17,15 @@ # ##### END GPL LICENSE BLOCK ##### bl_info = { - 'name': "Class Viewer", - 'author': "Mackraken", "batFinger" - 'version': (0, 1, 2), - 'blender': (2, 5, 8), - 'api': 37702, - 'location': "Text Editor > Toolbar, Text Editor > Right Click", - 'warning': "", - 'description': "List text's classes and definitions", - 'wiki_url': "https://sites.google.com/site/aleonserra/home/scripts/class-viewer", - 'category': "Development"} + 'name': "Class Viewer", + 'author': "Mackraken", "batFinger" + 'version': (0, 1, 2), + 'blender': (2, 5, 8), + 'location': "Text Editor > Toolbar, Text Editor > Right Click", + 'warning': "", + 'description': "List text's classes and definitions", + 'wiki_url': "https://sites.google.com/site/aleonserra/home/scripts/class-viewer", + 'category': "Development"} import bpy @@ -37,159 +36,159 @@ #escape = character right next to the class or def name def getfunc(space, sort, tipo="def ", escape= ""): - defs = [] - if space.type=="TEXT_EDITOR": - if space.text!=None: - txt = space.text - - for i, l in enumerate(txt.lines): - try: - line = l.body - except: - line="" - - if line[0:len(tipo)]==tipo: - end = line.find(escape) - if end==0: - func = line[len(tipo)::] - else: - func = line[len(tipo):end] - defs.append([func, i+1]) - - if sort: defs.sort() - - return defs + defs = [] + if space.type=="TEXT_EDITOR": + if space.text!=None: + txt = space.text + + for i, l in enumerate(txt.lines): + try: + line = l.body + except: + line="" + + if line[0:len(tipo)]==tipo: + end = line.find(escape) + if end==0: + func = line[len(tipo)::] + else: + func = line[len(tipo):end] + defs.append([func, i+1]) + + if sort: defs.sort() + + return defs class TEXT_OT_Jumptoline(bpy.types.Operator): - bl_label = "Jump" - bl_idname = "text.jumptoline" - __doc__ = "Jump to line" - line = bpy.props.IntProperty(default=-1) - - @classmethod - def poll(cls, context): - if context.area.spaces[0].type!="TEXT_EDITOR": - return False - else: - return context.area.spaces[0].text!=None - - def execute(self, context): - - scn = context.scene + bl_label = "Jump" + bl_idname = "text.jumptoline" + __doc__ = "Jump to line" + line = bpy.props.IntProperty(default=-1) + + @classmethod + def poll(cls, context): + if context.area.spaces[0].type!="TEXT_EDITOR": + return False + else: + return context.area.spaces[0].text!=None + + def execute(self, context): + + scn = context.scene - if self.line!=-1: - bpy.ops.text.jump(line=self.line) + if self.line!=-1: + bpy.ops.text.jump(line=self.line) - return {'FINISHED'} + return {'FINISHED'} class CommentsMenu(bpy.types.Menu): - bl_idname = "OBJECT_MT_select_comments" - bl_label = "Select" - - - - @classmethod - def poll(cls, context): - if context.area.spaces[0].type!="TEXT_EDITOR": - return False - else: - return context.area.spaces[0].text!=None - - def draw(self, context): - - layout = self.layout - space = context.area.spaces[0] - - items = getfunc(space, 1, "### ", "") - - for it in items: - layout.operator("text.jumptoline",text=it[0]).line = it[1] + bl_idname = "OBJECT_MT_select_comments" + bl_label = "Select" + + + + @classmethod + def poll(cls, context): + if context.area.spaces[0].type!="TEXT_EDITOR": + return False + else: + return context.area.spaces[0].text!=None + + def draw(self, context): + + layout = self.layout + space = context.area.spaces[0] + + items = getfunc(space, 1, "### ", "") + + for it in items: + layout.operator("text.jumptoline",text=it[0]).line = it[1] class DefsMenu(bpy.types.Menu): - bl_idname = "OBJECT_MT_select_defs" - bl_label = "Select" - - tipo = bpy.props.BoolProperty(default=False) - - @classmethod - def poll(cls, context): - if context.area.spaces[0].type!="TEXT_EDITOR": - return False - else: - return context.area.spaces[0].text!=None - - def draw(self, context): - scn = context.scene - layout = self.layout - space = context.area.spaces[0] - tipo = self.tipo - - - items = getfunc(space, 1, "def ", "(") - - for it in items: - layout.operator("text.jumptoline",text=it[0]).line = it[1] - + bl_idname = "OBJECT_MT_select_defs" + bl_label = "Select" + + tipo = bpy.props.BoolProperty(default=False) + + @classmethod + def poll(cls, context): + if context.area.spaces[0].type!="TEXT_EDITOR": + return False + else: + return context.area.spaces[0].text!=None + + def draw(self, context): + scn = context.scene + layout = self.layout + space = context.area.spaces[0] + tipo = self.tipo + + + items = getfunc(space, 1, "def ", "(") + + for it in items: + layout.operator("text.jumptoline",text=it[0]).line = it[1] + class ClassesMenu(bpy.types.Menu): - bl_idname = "OBJECT_MT_select_classes" - bl_label = "Select" - - - - @classmethod - def poll(cls, context): - if context.area.spaces[0].type!="TEXT_EDITOR": - return False - else: - return context.area.spaces[0].text!=None - - def draw(self, context): - - layout = self.layout - space = context.area.spaces[0] - - - - items = getfunc(space, 1, "class ", "(") - - for it in items: - layout.operator("text.jumptoline",text=it[0]).line = it[1] + bl_idname = "OBJECT_MT_select_classes" + bl_label = "Select" + + + + @classmethod + def poll(cls, context): + if context.area.spaces[0].type!="TEXT_EDITOR": + return False + else: + return context.area.spaces[0].text!=None + + def draw(self, context): + + layout = self.layout + space = context.area.spaces[0] + + + + items = getfunc(space, 1, "class ", "(") + + for it in items: + layout.operator("text.jumptoline",text=it[0]).line = it[1] - + def GotoComments(self, context): - self.layout.menu("OBJECT_MT_select_comments", text="Comments", icon='PLUGIN') - return False + self.layout.menu("OBJECT_MT_select_comments", text="Comments", icon='PLUGIN') + return False def GotoDefs(self, context): - self.layout.menu("OBJECT_MT_select_defs", text="Defs", icon='PLUGIN') - return False + self.layout.menu("OBJECT_MT_select_defs", text="Defs", icon='PLUGIN') + return False def GotoClasses(self, context): - self.layout.menu("OBJECT_MT_select_classes", text="Classes", icon='PLUGIN') - return False + self.layout.menu("OBJECT_MT_select_classes", text="Classes", icon='PLUGIN') + return False classes = [TEXT_OT_Jumptoline, ClassesMenu, DefsMenu, CommentsMenu] def register(): - for c in classes: - bpy.utils.register_class(c) - - bpy.types.TEXT_MT_toolbox.append(GotoComments) - bpy.types.TEXT_MT_toolbox.append(GotoDefs) - bpy.types.TEXT_MT_toolbox.append(GotoClasses) + for c in classes: + bpy.utils.register_class(c) + + bpy.types.TEXT_MT_toolbox.append(GotoComments) + bpy.types.TEXT_MT_toolbox.append(GotoDefs) + bpy.types.TEXT_MT_toolbox.append(GotoClasses) def unregister(): - for c in classes: - bpy.utils.unregister_class(c) - - bpy.types.TEXT_MT_toolbox.remove(GotoComments) - bpy.types.TEXT_MT_toolbox.remove(GotoDefs) - bpy.types.TEXT_MT_toolbox.remove(GotoClasses) - + for c in classes: + bpy.utils.unregister_class(c) + + bpy.types.TEXT_MT_toolbox.remove(GotoComments) + bpy.types.TEXT_MT_toolbox.remove(GotoDefs) + bpy.types.TEXT_MT_toolbox.remove(GotoClasses) + if __name__ == "__main__": - register() + register() diff -Nru blender-2.61/release/scripts/addons_contrib/game_engine_ragdolls_kit/__init__.py blender-2.62/release/scripts/addons_contrib/game_engine_ragdolls_kit/__init__.py --- blender-2.61/release/scripts/addons_contrib/game_engine_ragdolls_kit/__init__.py 2011-12-13 19:59:36.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/game_engine_ragdolls_kit/__init__.py 2012-02-15 19:43:55.000000000 +0000 @@ -24,7 +24,6 @@ "author": "FunkyWyrm", "version": (0,2), "blender": (2, 5, 5), - "api": 31965, "location": "View 3D > Tool Shelf > BRIK Panel", "description": "Kit for creating ragdoll structures from armatures and implementing them in the game engine.", "warning": "Preliminary release for testing purposes. Use with caution on important files.", diff -Nru blender-2.61/release/scripts/addons_contrib/geodesic_domes/add_shape_geodesic.py blender-2.62/release/scripts/addons_contrib/geodesic_domes/add_shape_geodesic.py --- blender-2.61/release/scripts/addons_contrib/geodesic_domes/add_shape_geodesic.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/geodesic_domes/add_shape_geodesic.py 2012-02-15 19:43:43.000000000 +0000 @@ -0,0 +1,100 @@ +import bpy +import mathutils + +def reset_transform(ob): + m = mathutils.Matrix() + ob.matrix_local = m + +def func_add_corrective_pose_shape_fast(source, target): + result = "" + reset_transform(target) + # If target object doesn't have Basis shape key, create it. + try: + num_keys = len( target.data.shape_keys.key_blocks ) + except: + basis = target.shape_key_add() + basis.name = "Basis" + target.data.update() + key_index = target.active_shape_key_index + if key_index == 0: + # Insert new shape key + new_shapekey = target.shape_key_add() + new_shapekey.name = "Shape_" + source.name + new_shapekey_name = new_shapekey.name + key_index = len(target.data.shape_keys.key_blocks)-1 + target.active_shape_key_index = key_index + # else, the active shape will be used (updated) + target.show_only_shape_key = True + shape_key_verts = target.data.shape_keys.key_blocks[ key_index ].data + try: + vgroup = target.active_shape_key.vertex_group + target.active_shape_key.vertex_group = '' + except: + print("blub") + result = "***ERROR*** blub" + pass + # copy the local vertex positions to the new shape + verts = source.data.vertices + try: + for n in range( len(verts)): + shape_key_verts[n].co = verts[n].co + # go to all armature modifies and unpose the shape + except: + message = "***ERROR***, meshes have different number of vertices" + result = message + for n in target.modifiers: + if n.type == 'ARMATURE' and n.show_viewport: + #~ print("got one") + n.use_bone_envelopes = False + n.use_deform_preserve_volume = False + n.use_vertex_groups = True + armature = n.object + unposeMesh( shape_key_verts, target, armature) + break + + # set the new shape key value to 1.0, so we see the result instantly + target.data.shape_keys.key_blocks[ target.active_shape_key_index].value = 1.0 + try: + target.active_shape_key.vertex_group = vgroup + except: + print("bluba") + result = result + "bluba" + pass + target.show_only_shape_key = False + target.data.update() + return result + +class add_corrective_pose_shape_fast(bpy.types.Operator): + '''Adds 1st object as shape to 2nd object as pose shape (only 1 armature)''' + bl_idname = "object.add_corrective_pose_shape_fast" + bl_label = "Add object as corrective shape faster" + + @classmethod + def poll(cls, context): + return context.active_object != None + + def execute(self, context): + + if len(context.selected_objects) > 2: + print("Select source and target objects please") + return {'FINISHED'} + + selection = context.selected_objects + target = context.active_object + if context.active_object == selection[0]: + source = selection[1] + else: + source = selection[0] + print(source) + print(target) + func_add_corrective_pose_shape_fast( source, target) + return {'FINISHED'} + +def register(): + bpy.utils.register_module(__name__) + +def unregister(): + bpy.utils.unregister_module(__name__) + +if __name__ == "__main__": + register() diff -Nru blender-2.61/release/scripts/addons_contrib/geodesic_domes/forms_259.py blender-2.62/release/scripts/addons_contrib/geodesic_domes/forms_259.py --- blender-2.61/release/scripts/addons_contrib/geodesic_domes/forms_259.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/geodesic_domes/forms_259.py 2012-02-15 19:43:43.000000000 +0000 @@ -0,0 +1,222 @@ +import math +from math import pi,sin,cos,atan,tan,fabs +from geodesic_domes.vefm_259 import * +class form(mesh): + def __init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform): + mesh.__init__(self) + #PKHG alredey in vefm259 mesh: self.a360 = pi * 2.0 + self.PKHG_parameters = [uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform] + self.ures = uresolution + self.vres = vresolution + + self.uscale = uscale + self.vscale = vscale + self.upart = upart + self.vpart = vpart + self.uphase = uphase * self.a360 + self.vphase = vphase * self.a360 + self.utwist = utwist + self.vtwist = vtwist + + self.xscale = xscale + self.yscale = yscale + self.sform = sform + + if self.upart != 1.0: ## there is a gap in the major radius + self.uflag = 1 + else: + self.uflag = 0 + if self.vpart != 1.0: ## there is a gap in the minor radius + self.vflag = 1 + else: + self.vflag = 0 + if self.uflag: + self.ufinish = self.ures + 1 + else: + self.ufinish = self.ures + if self.vflag: + self.vfinish = self.vres + 1 + else: + self.vfinish = self.vres + self.ustep = (self.a360 / self.ures) * self.upart + self.vstep = (self.a360 / self.vres) * self.vpart + if self.xscale != 1.0: + self.xscaleflag = 1 + else: + self.xscaleflag = 0 + if self.yscale != 1.0: + self.yscaleflag = 1 + else: + self.yscaleflag = 0 + self.rowlist=[] + + def generatepoints(self): + for i in range(self.ufinish): + row=[] + for j in range(self.vfinish): + u = self.ustep * i + self.uphase + v = self.vstep * j + self.vphase + # if self.xscaleflag: + # u = self.ellipsecomp(self.xscale,u) + # if self.yscaleflag: + # v = self.ellipsecomp(self.yscale,v) + if self.sform[12]: + r1 = self.superform(self.sform[0],self.sform[1],self.sform[2],self.sform[3],self.sform[14] + u,self.sform[4],self.sform[5],self.sform[16] * v) + else: + r1 = 1.0 + if self.sform[13]: + r2 = self.superform(self.sform[6],self.sform[7],self.sform[8],self.sform[9],self.sform[15] + v,self.sform[10],self.sform[11],self.sform[17] * v) + else: + r2 = 1.0 + x,y,z = self.formula(u,v,r1,r2) + point = vertex((x,y,z)) + row.append(point) + self.verts.append(point) + self.rowlist.append(row) + if self.vflag: + pass + else: + for i in range(len(self.rowlist)): + self.rowlist[i].append(self.rowlist[i][0]) + if self.uflag: + pass + else: + self.rowlist.append(self.rowlist[0]) + +# def formula(self,u,v,r1,r2): +# pass + + def generatefaces(self): + ufin = len(self.rowlist) - 1 + vfin = len(self.rowlist[0]) - 1 + for i in range(ufin): + for j in range(vfin): + top = i + bottom = i + 1 + left = j + right = j + 1 + a = self.rowlist[top][left] + b = self.rowlist[top][right] + c = self.rowlist[bottom][right] + d = self.rowlist[bottom][left] + face1 = face([a,b,c,d]) + self.faces.append(face1) + edge1 = edge(a,b) + edge2 = edge(a,d) + self.edges.append(edge1) + self.edges.append(edge2) + if i + 1 == ufin: + edge3 = edge(d,c) + self.edges.append(edge3) + if j + 1 == vfin: + edge4 = edge(b,c) + self.edges.append(edge4) + +class grid(form): + def __init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform): + form.__init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform) + unit = 1.0 / self.a360 + if self.ures == 1 : + print("\n***ERRORin forms_259.grid L121***, ures is 1, changed into 2\n\n") + self.ures = 2 + if self.vres == 1 : + print("\n***ERROR in grid forms_259.grid L124***, vres is 1, changed into 2\n\n") + self.vres = 2 + self.ustep = self.a360 / (self.ures - 1) + self.vstep = self.a360 / (self.vres - 1) + + self.uflag = 1 + self.vflag = 1 + + self.xscaleflag = 0 + self.yscaleflag = 0 + self.uexpand = unit * self.uscale + self.vexpand = unit * self.vscale + self.ushift = self.uscale * 0.5 + self.vshift = self.vscale * 0.5 + + self.generatepoints() + self.generatefaces() + for i in range(len(self.verts)): + self.verts[i].index = i + self.connectivity() + + def formula(self,u,v,r1,r2): + x = u * self.uexpand - self.ushift + y = v * self.vexpand - self.vshift + z = r1 * r2 - 1.0 + return x,y,z + + +class cylinder(form): + def __init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform): + form.__init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform) + unit = 1.0 / self.a360 + self.vshift = self.vscale * 0.5 + self.vexpand = unit * self.vscale + self.vflag = 1 + self.generatepoints() + self.generatefaces() + for i in range(len(self.verts)): + self.verts[i].index = i + self.connectivity() + + def formula(self,u,v,r1,r2): + x = sin(u) * self.uscale * r1 * r2 * self.xscale + y = cos(u) * self.uscale * r1 * r2 + z = v * self.vexpand - self.vshift + return x,y,z + +class parabola(form): + def __init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform): + form.__init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform) + unit = 1.0 / self.a360 + self.vshift = self.vscale * 0.5 + self.vexpand = unit * self.vscale + self.vflag = 1 + self.generatepoints() + self.generatefaces() + for i in range(len(self.verts)): + self.verts[i].index = i + self.connectivity() + + def formula(self,u,v,r1,r2): + factor = sqrt(v) + 0.001 + x = sin(u) * factor * self.uscale * r1 * r2 * self.xscale + y = cos(u) * factor * self.uscale * r1 * r2 + z = - v * self.vexpand + self.vshift + return x,y,z + +class torus(form): + def __init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform): + form.__init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform) + self.generatepoints() + self.generatefaces() + for i in range(len(self.verts)): + self.verts[i].index = i + self.connectivity() + + def formula(self,u,v,r1,r2): + z = sin(v) * self.uscale * r2 * self.yscale + y = (self.vscale + self.uscale * cos(v)) * cos(u) * r1 * r2 + x = (self.vscale + self.uscale * cos(v)) * sin(u) * r1 * r2 * self.xscale + return x,y,z + +class sphere(form): + + def __init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform): + form.__init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform) + self.vstep = (self.a360 / (self.vres - 1)) * self.vpart + self.vflag = 1 + self.generatepoints() + self.generatefaces() + for i in range(len(self.verts)): + self.verts[i].index = i + self.connectivity() + + def formula(self,u,v,r1,r2): + v = (v * 0.5) - (self.a360 * 0.25) + x = r1 * cos(u) * r2 * cos(v) * self.uscale * self.xscale + y = r1 * sin(u) * r2 * cos(v) * self.uscale + z = r2 * sin(v) * self.uscale * self.yscale + return x,y,z diff -Nru blender-2.61/release/scripts/addons_contrib/geodesic_domes/geodesic_classes_259.py blender-2.62/release/scripts/addons_contrib/geodesic_domes/geodesic_classes_259.py --- blender-2.61/release/scripts/addons_contrib/geodesic_domes/geodesic_classes_259.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/geodesic_domes/geodesic_classes_259.py 2012-02-15 19:43:43.000000000 +0000 @@ -0,0 +1,754 @@ +#werkt from geodesic_domes.vefm_259 import * +from geodesic_domes.vefm_259 import mesh, vertex, edge, face + +import math +from math import pi,acos,sin,cos,atan,tan,fabs, sqrt + +def check_contains(cl,name , print_value = False): + dir_class = dir(cl) + for el in dir_class: + if el.startswith("_"): + pass + else: + if print_value: + tmp = getattr(cl,el) + print(name , " contains ==>",el," value = ", tmp) + else: + print(name , " contains ==>",el) + print("\ncheck_contains finished\n\n") + +class geodesic(mesh): + def __init__(self): + mesh.__init__(self) + self.PKHG_parameters = None +# print("\n------ geodesic L11 PKHG_parameters",PKHG_parameters) + self.panels = [] + self.vertsdone = [] + self.skeleton = [] ## List of verts in the full skeleton edges. + self.vertskeleton = [] # config needs this member + self.edgeskeleton = [] # config needs this member + self.sphericalverts = [] + self.a45 = pi * 0.25 + self.a90 = pi * 0.5 + self.a180 = pi + self.a270 = pi * 1.5 + self.a360 = pi * 2 + #define members here + #setparams needs: + self.frequency = None + self.eccentricity = None + self.squish = None + self.radius = None + self.square = None + self.squarez = None + self.cart = None + self.shape = None + self.baselevel = None + self.faceshape = None + self.dualflag = None + self.rotxy = None + self.rotz = None + self.klass = None + self.sform = None + self.super = None + self.odd = None + #config needs + self.panelpoints = None + self.paneledges = None + self.reversepanel = None + self.edgelength = None + self.vertsdone = None + self.panels = [] + +#PKHG because of unittest approach for a while the following three lines commentd +#PKHG do not understand the problems with the next three lines +#no does not work self.setparameters() +# self.makegeodesic() +# self.connectivity() + + def setparameters(self,params): + parameters = self.PKHG_parameters = params + self.frequency = parameters[0] ## How many subdivisions - up to 20. + self.eccentricity = parameters[1] ## Elliptical if >1.0. + self.squish = parameters[2] ## Flattened if < 1.0. + self.radius = parameters[3] ## Exactly what it says. + self.square = parameters[4] ## Controls amount of superellipse in X/Y plane. + self.squarez = parameters[5] ## Controls amount of superellipse in Z dimension. + self.cart = parameters[6] ## Cuts out sphericalisation step. + self.shape = parameters[7] ## Full sphere, dome, flatbase. + self.baselevel = parameters[8] ## Where the base is cut on a flatbase dome. + self.faceshape = parameters[9] ## Triangular, hexagonal, tri-hex. + self.dualflag = parameters[10] + self.rotxy = parameters[11] + self.rotz = parameters[12] + self.klass = parameters[13] + self.sform = parameters[14] + self.super = 0 ## Toggles superellipse. + if self.square != 2.0 or self.squarez != 2.0: + self.super = 1 + self.odd = 0 ## Is the frequency odd. It matters for dome building. + if self.frequency % 2 != 0: + self.odd = 1 + + def makegeodesic(self): + self.vertedgefacedata() #PKHG only a pass 13okt11 + self.config() ## Generate all the configuration information. + if self.klass: + self.class2() + if self.faceshape == 1: + self.hexify() ## Hexagonal faces + elif self.faceshape == 2: + self.starify() ## Hex and Triangle faces + if self.dualflag: + self.dual() + if not self.cart: + self.sphericalize() ## Convert x,y,z positions into spherical u,v. + self.sphere2cartesian() ## Convert spherical uv back into cartesian x,y,z for final shape. + for i in range(len( self.verts)): + self.verts[i].index = i + for edg in self.edges: + edg.findvect() + + def vertedgefacedata(self): + pass + +#PKHG 23.1 def config(self, frequency = 1): #???PKHG frequency problem 20 oct. + def config(self): #???PKHG frequency problem 20 oct. +#PKHG_OK print("\n20-11 >>>>>>>>>DBG geodesic_classes_259 config L117 called") + for i in range(len(self.vertskeleton)): + self.vertskeleton[i].index = i + for edges in self.edgeskeleton: +#???PKHG TODO s = skeletonrow(self.frequency, edges, 0, self) #self a geodesic + s = skeletonrow(self.frequency, edges, 0, self) #self a geodesic + self.skeleton.append(s) + for i in range(len( self.verts)): + self.verts[i].index = i + for i in range(len(self.panelpoints)): + a = self.vertsdone[self.panelpoints[i][0]][1] + b = self.vertsdone[self.panelpoints[i][1]][1] + c = self.vertsdone[self.panelpoints[i][2]][1] + panpoints = [ self.verts[a], + self.verts[b], + self.verts[c]] + panedges = [ self.skeleton[self.paneledges[i][0]], + self.skeleton[self.paneledges[i][1]], + self.skeleton[self.paneledges[i][2]] ] + reverseflag = 0 + for flag in self.reversepanel: + if flag == i: + reverseflag = 1 + p = panel(panpoints, panedges, reverseflag, self) +#PKHG_panels not used?! self.panels.append(p) + + def sphericalize(self): + if self.shape == 2: + self.cutbasecomp() + for vert in(self.verts): +#PKHG test 20111030 +# x = vert.x +# y = vert.y +# z = vert.z + x = vert.vector.x + y = vert.vector.y + z = vert.vector.z + + u = self.usphericalise(x,y,z) + v = self.vsphericalise(x,y,z) + self.sphericalverts.append([u,v]) + + def sphere2cartesian(self): +#PKHG_TODOnot_now check_contains(self,"sphereto self",True) + for i in range(len(self.verts)): + if self.cart: +#PKHG test 20111030 +# x = self.verts[i].x * self.radius * self.eccentricity +# y = self.verts[i].y * self.radius +# z = self.verts[i].z * self.radius * self.squish + x = self.verts[i].vector.x * self.radius * self.eccentricity + y = self.verts[i].vector.y * self.radius + z = self.verts[i].vector.z * self.radius * self.squish + else: + u = self.sphericalverts[i][0] + v = self.sphericalverts[i][1] + if self.squish != 1.0 or self.eccentricity>1.0: + scalez = 1 / self.squish + v = self.ellipsecomp(scalez,v) + u = self.ellipsecomp(self.eccentricity,u) + if self.super: + r1 = self.superell(self.square,u,self.rotxy) + r2 = self.superell(self.squarez,v,self.rotz) + else: + r1 = 1.0 + r2 = 1.0 + + # print "sform",self.sform," u",u," v",v + if self.sform[12]: + + r1 = r1 * self.superform(self.sform[0],self.sform[1],self.sform[2],self.sform[3],self.sform[14] + u,self.sform[4],self.sform[5],self.sform[16] * v) + if self.sform[13]: + + r2 = r2 * self.superform(self.sform[6],self.sform[7],self.sform[8],self.sform[9],self.sform[15] + v,self.sform[10],self.sform[11],self.sform[17] * v) + x,y,z = self.cartesian(u,v,r1,r2) +#PKHG test 20111030 +# self.verts[i].x = x +# self.verts[i].y = y +# self.verts[i].z = z + self.verts[i] = vertex((x,y,z)) + + def usphericalise(self,x,y,z): + if y == 0.0: + if x>0: + theta = 0.0 + else: + theta = self.a180 + elif x == 0.0: + if y>0: + theta = self.a90 + else: + theta = self.a270 + + else: + theta = atan(y / x) + if x < 0.0 and y < 0.0: + theta = theta + self.a180 + elif x < 0.0 and y>0.0: + theta = theta + self.a180 + u = theta + return u + + def vsphericalise(self,x,y,z) : + if z == 0.0: + phi = self.a90 + else: + rho = sqrt(x ** 2 + y**2 + z**2) + phi = acos(z / rho) + v = phi + return v + def ellipsecomp(self,efactor,theta): + if theta == self.a90: + result = self.a90 + elif theta == self.a270: + result = self.a270 + else: + result = atan(tan(theta) / efactor**0.5) + if result>=0.0: + x = result + y = self.a180 + result + if fabs(x - theta) <= fabs(y - theta): + result = x + else: + result = y + else: + x = self.a180 + result + y = result + + if fabs(x - theta) <= fabs(y - theta): + result = x + else: + result = y + return result + def cutbasecomp(self): + pass + + def cartesian(self,u,v,r1,r2): + x = r1 * cos(u) * r2 * sin(v) * self.radius * self.eccentricity + y = r1 * sin(u) * r2 * sin(v) * self.radius + z = r2 * cos(v) * self.radius * self.squish + return x,y,z +# def connectivity(self): +# +# self.dovertedge() +# self.dovertface() +# self.dofaceedge() + +class edgerow: + def __init__(self, count, anchor, leftindex, rightindex, stepvector, endflag, parentgeo): + self.points = [] + self.edges = [] + ## Make a row of evenly spaced points. + for i in range(count + 1): + if i == 0: + self.points.append(leftindex) + elif i == count and not endflag: + self.points.append(rightindex) + else: #PKHG Vectors added! + newpoint = anchor + (stepvector * i) + vertcount = len(parentgeo.verts) + self.points.append(vertcount) + newpoint.index = vertcount + parentgeo.verts.append(newpoint) + for i in range(count): + a = parentgeo.verts[self.points[i]] + b = parentgeo.verts[self.points[i + 1]] + line = edge(a,b) + self.edges.append(len(parentgeo.edges)) + parentgeo.edges.append(line) + +class skeletonrow: + def __init__(self, count, skeletonedge, shortflag, parentgeo): + self.points = [] + self.edges = [] + self.vect = skeletonedge.vect + self.step = skeletonedge.vect / float(count) + ## Make a row of evenly spaced points. + for i in range(count + 1): + vert1 = skeletonedge.a + vert2 = skeletonedge.b + if i == 0: + if parentgeo.vertsdone[vert1.index][0]: + self.points.append(parentgeo.vertsdone[vert1.index][1]) + else: +#PKHG test 20111030 +# newpoint = vertex((vert1.x, vert1.y, vert1.z)) + newpoint = vertex(vert1.vector) + vertcount = len(parentgeo.verts) + self.points.append(vertcount) + newpoint.index = vertcount + parentgeo.vertsdone[vert1.index] = [1,vertcount] + parentgeo.verts.append(newpoint) + + elif i == count: + if parentgeo.vertsdone[vert2.index][0]: + self.points.append(parentgeo.vertsdone[vert2.index][1]) + else: +#PKHG test 20111030 +# newpoint = vertex((vert2.x, vert2.y, vert2.z)) + newpoint = vertex(vert2.vector) + vertcount = len(parentgeo.verts) + self.points.append(vertcount) + newpoint.index = vertcount + parentgeo.vertsdone[vert2.index] = [1,vertcount] + parentgeo.verts.append(newpoint) + else: + newpoint = vertex(vert1.vector + (self.step * i)) #must be a vertex! + vertcount = len(parentgeo.verts) + self.points.append(vertcount) + newpoint.index = vertcount + parentgeo.verts.append(newpoint) + for i in range(count): + a = parentgeo.verts[self.points[i]] + b = parentgeo.verts[self.points[i + 1]] + line = edge(a,b) + self.edges.append(len(parentgeo.edges)) + parentgeo.edges.append(line) + +class facefill: + def __init__(self, upper, lower, reverseflag, parentgeo, finish): + for i in range(finish): + a,b,c = upper.points[i],lower.points[i + 1],lower.points[i] + if reverseflag: + upface = face([parentgeo.verts[a],parentgeo.verts[c],parentgeo.verts[b]]) + else: + upface = face([parentgeo.verts[a],parentgeo.verts[b],parentgeo.verts[c]]) + parentgeo.faces.append(upface) + if i == finish - 1: + pass + else: + d = upper.points[i + 1] + if reverseflag: + downface = face([parentgeo.verts[b],parentgeo.verts[d],parentgeo.verts[a]]) + else: + downface = face([parentgeo.verts[b],parentgeo.verts[a],parentgeo.verts[d]]) + line = edge(parentgeo.verts[a],parentgeo.verts[b]) + line2 = edge(parentgeo.verts[d],parentgeo.verts[b]) + parentgeo.faces.append(downface) + parentgeo.edges.append(line) + parentgeo.edges.append(line2) +class panel: + def __init__(self, points, edges, reverseflag, parentgeo): + self.cardinal = points[0] + self.leftv = points[1] + self.rightv = points[2] + self.leftedge = edges[0] + self.rightedge = edges[1] + self.baseedge = edges[2] + self.rows=[] + self.orient(parentgeo,edges) + self.createrows(parentgeo) + self.createfaces(parentgeo,reverseflag) + + def orient(self,parentgeo,edges): + if self.leftedge.points[0] != self.cardinal.index: + self.leftedge.points.reverse() + self.leftedge.vect.negative() + + if self.rightedge.points[0] != self.cardinal.index: + self.rightedge.points.reverse() + self.rightedge.vect.negative() + + if self.baseedge.points[0] != self.leftv.index: + + self.baseedge.points.reverse() + self.baseedge.vect.negative() + + def createrows(self, parentgeo): + for i in range(len(self.leftedge.points)): + if i == parentgeo.frequency: + newrow = self.baseedge + else: + newrow = edgerow(i, parentgeo.verts[self.leftedge.points[i]], self.leftedge.points[i], self.rightedge.points[i], self.baseedge.step, 0, parentgeo ) + self.rows.append(newrow) + def createfaces(self, parentgeo,reverseflag): + for i in range(len(self.leftedge.points) - 1): + facefill(self.rows[i], self.rows[i + 1], reverseflag, parentgeo, len(self.rows[i].points)) +############################# +############################# + +#for point on top? YES! +class tetrahedron(geodesic,mesh): + def __init__(self,parameter): + geodesic.__init__(mesh) + geodesic.setparameters(self,parameter) + self.set_vert_edge_skeleons() + + def set_vert_edge_skeleons(self): + self.vertskeleton=[ vertex(( 0.0 , 0.0 , 1.73205080757 )), + vertex(( 0.0 , -1.63299316185 , -0.577350269185 )), + vertex(( 1.41421356237 , 0.816496580927 , -0.57735026919 )), + vertex(( -1.41421356237 , 0.816496580927 , -0.57735026919 )) ] + self.edgeskeleton=[ edge(self.vertskeleton[0],self.vertskeleton[1]), + edge(self.vertskeleton[0],self.vertskeleton[2]), + edge(self.vertskeleton[0],self.vertskeleton[3]), + edge(self.vertskeleton[1],self.vertskeleton[2]), + edge(self.vertskeleton[2],self.vertskeleton[3]), + edge(self.vertskeleton[1],self.vertskeleton[3]) ] + +### probably to be removed, other gui! : "#??? delete PKHG" + self.panelpoints=[[0,1,2],[0,2,3],[0,1,3],[1,2,3]] + self.paneledges=[[0,1,3],[1,2,4],[0,2,5],[3,5,4]] + self.reversepanel=[2,3] + self.edgelength=[] + self.vertsdone=[[0,0]] * len(self.vertskeleton) + +#for edge on top? YES +class tetraedge(geodesic): + def __init__(self,parameter): + geodesic.__init__(mesh) + geodesic.setparameters(self,parameter) + self.set_vert_edge_skeleons() + def set_vert_edge_skeleons(self): + self.vertskeleton=[ vertex(( 0.0 , -1.41421356237 , 1.0 )), + vertex(( 0.0 , 1.41421356237 , 1.0 )), + vertex(( 1.41421356237 , 0.0 , -1.0 )), + vertex(( -1.41421356237 , 0.0 , -1.0 )) ] + self.edgeskeleton=[ edge(self.vertskeleton[0],self.vertskeleton[1]), + edge(self.vertskeleton[0],self.vertskeleton[2]), + edge(self.vertskeleton[0],self.vertskeleton[3]), + edge(self.vertskeleton[1],self.vertskeleton[3]), + edge(self.vertskeleton[1],self.vertskeleton[2]), + edge(self.vertskeleton[2],self.vertskeleton[3]) ] + for i in range(len(self.vertskeleton)): + self.vertskeleton[i].index = i + self.panelpoints=[[0,1,2],[1,2,3],[0,1,3],[0,2,3]] + self.paneledges=[[0,1,4],[4,3,5],[0,2,3],[1,2,5]] + self.reversepanel=[0,3] + self.edgelength=[] + self.vertsdone=[[0,0]] * len(self.vertskeleton) + +#for face on top? YES +class tetraface(geodesic): + def __init__(self,parameter): + geodesic.__init__(mesh) + geodesic.setparameters(self,parameter) + self.set_vert_edge_skeleons() + def set_vert_edge_skeleons(self): + self.vertskeleton=[ vertex(( -1.41421356237 , -0.816496580927 , 0.57735026919 )), + vertex(( 1.41421356237 , -0.816496580927 , 0.57735026919 )), + vertex(( 0.0 , 1.63299316185 , 0.577350269185 )), + vertex(( 0.0 , 0.0 , -1.73205080757 )) ] + self.edgeskeleton=[ edge(self.vertskeleton[0],self.vertskeleton[1]), + edge(self.vertskeleton[2],self.vertskeleton[1]), + edge(self.vertskeleton[2],self.vertskeleton[0]), + edge(self.vertskeleton[0],self.vertskeleton[3]), + edge(self.vertskeleton[1],self.vertskeleton[3]), + edge(self.vertskeleton[2],self.vertskeleton[3]) ] + self.panelpoints=[[2,0,1],[0,1,3],[2,1,3],[2,0,3]] + self.paneledges=[[2,1,0],[0,3,4],[1,5,4],[2,5,3]] + self.reversepanel=[1,3] + self.edgelength=[] + self.vertsdone=[[0,0]] * len(self.vertskeleton) + +class octahedron(geodesic): + def __init__(self,parameter): + geodesic.__init__(mesh) + geodesic.setparameters(self,parameter) + self.set_vert_edge_skeleons() + def set_vert_edge_skeleons(self): + self.vertskeleton=[ vertex((0.0,0.0,1.0)), + vertex((0.0,1.0,0.0)), + vertex((-1.0,0.0,0.0)), + vertex((0.0,-1.0,0.0)), + vertex((1.0,0.0,0.0)), + vertex((0.0,0.0,-1.0)) ] + for i in range(len(self.vertskeleton)): + self.vertskeleton[i].index = i + self.edgeskeleton=[ edge(self.vertskeleton[0],self.vertskeleton[1]), + edge(self.vertskeleton[0],self.vertskeleton[2]), + edge(self.vertskeleton[0],self.vertskeleton[3]), + edge(self.vertskeleton[0],self.vertskeleton[4]), + edge(self.vertskeleton[1],self.vertskeleton[2]), + edge(self.vertskeleton[2],self.vertskeleton[3]), + edge(self.vertskeleton[3],self.vertskeleton[4]), + edge(self.vertskeleton[4],self.vertskeleton[1]), + edge(self.vertskeleton[1],self.vertskeleton[5]), + edge(self.vertskeleton[2],self.vertskeleton[5]), + edge(self.vertskeleton[3],self.vertskeleton[5]), + edge(self.vertskeleton[4],self.vertskeleton[5]) ] + self.panelpoints=[[0,1,2],[0,2,3],[0,3,4],[0,4,1],[1,2,5],[2,3,5],[3,4,5],[4,1,5]] + self.paneledges=[[0,1,4],[1,2,5],[2,3,6],[3,0,7],[4,8,9],[5,9,10],[6,10,11],[7,11,8]] + self.reversepanel=[4,5,6,7] + self.edgelength=[] + self.vertsdone=[[0,0]] * len(self.vertskeleton) +class octaedge(geodesic): + def __init__(self,parameter): + geodesic.__init__(mesh) + geodesic.setparameters(self,parameter) + self.set_vert_edge_skeleons() + def set_vert_edge_skeleons(self): + self.vertskeleton=[ vertex(( 0.0 , -0.707106781187 , 0.707106781187 )), + vertex(( 0.0 , 0.707106781187 , 0.707106781187 )), + vertex(( 1.0 , 0.0 , 0.0 )), + vertex(( -1.0 , 0.0 , 0.0 )), + vertex(( 0.0 , -0.707106781187 , -0.707106781187 )), + vertex(( 0.0 , 0.707106781187 , -0.707106781187 )) ] + self.edgeskeleton=[ edge(self.vertskeleton[0],self.vertskeleton[1]), + edge(self.vertskeleton[0],self.vertskeleton[4]), + edge(self.vertskeleton[0],self.vertskeleton[2]), + edge(self.vertskeleton[1],self.vertskeleton[2]), + edge(self.vertskeleton[1],self.vertskeleton[5]), + edge(self.vertskeleton[1],self.vertskeleton[3]), + edge(self.vertskeleton[0],self.vertskeleton[3]), + edge(self.vertskeleton[2],self.vertskeleton[4]), + edge(self.vertskeleton[2],self.vertskeleton[5]), + edge(self.vertskeleton[3],self.vertskeleton[5]), + edge(self.vertskeleton[3],self.vertskeleton[4]), + edge(self.vertskeleton[4],self.vertskeleton[5]) ] + self.panelpoints=[[0,1,2],[0,1,3],[0,2,4],[1,2,5],[1,3,5],[0,3,4],[2,4,5],[3,4,5]] + self.paneledges=[[0,2,3],[0,6,5],[2,1,7],[3,4,8],[5,4,9],[6,1,10],[7,8,11],[10,9,11]] + self.reversepanel=[0,2,4,7] + self.edgelength=[] + self.vertsdone=[[0,0]] * len(self.vertskeleton) +class octaface(geodesic): + def __init__(self,parameter): + geodesic.__init__(mesh) + geodesic.setparameters(self,parameter) + self.set_vert_edge_skeleons() + def set_vert_edge_skeleons(self): + self.vertskeleton=[ vertex(( 0.408248458663 , -0.707106781187 , 0.577350150255 )), + vertex(( 0.408248458663 , 0.707106781187 , 0.577350150255 )), + vertex(( -0.816496412728 , 0.0 , 0.577350507059 )), + vertex(( -0.408248458663 , -0.707106781187 , -0.577350150255 )), + vertex(( 0.816496412728 , 0.0 , -0.577350507059 )), + vertex(( -0.408248458663 , 0.707106781187 , -0.577350150255 )) ] + self.edgeskeleton=[ edge(self.vertskeleton[0],self.vertskeleton[1]), + edge(self.vertskeleton[2],self.vertskeleton[1]), + edge(self.vertskeleton[2],self.vertskeleton[0]), + edge(self.vertskeleton[0],self.vertskeleton[3]), + edge(self.vertskeleton[0],self.vertskeleton[4]), + edge(self.vertskeleton[1],self.vertskeleton[4]), + edge(self.vertskeleton[1],self.vertskeleton[5]), + edge(self.vertskeleton[2],self.vertskeleton[5]), + edge(self.vertskeleton[2],self.vertskeleton[3]), + edge(self.vertskeleton[3],self.vertskeleton[4]), + edge(self.vertskeleton[4],self.vertskeleton[5]), + edge(self.vertskeleton[3],self.vertskeleton[5]) ] + self.panelpoints=[[2,0,1],[0,3,4],[0,1,4],[1,4,5],[2,1,5],[2,3,5],[2,0,3],[3,4,5]] + self.paneledges=[[2,1,0],[3,4,9],[0,4,5],[5,6,10],[1,7,6],[8,7,11],[2,8,3],[9,11,10]] + self.reversepanel=[2,5,6,7] + self.edgelength=[] + self.vertsdone=[[0,0]] * len(self.vertskeleton) +class icosahedron(geodesic): + def __init__(self,parameter): + geodesic.__init__(mesh) + geodesic.setparameters(self,parameter) + self.set_vert_edge_skeleons() + def set_vert_edge_skeleons(self): + self.vertskeleton=[ vertex(( 0.0 , 0.0 , 0.587785252292 )), + vertex(( 0.0 , -0.525731096637 , 0.262865587024 )), + vertex(( 0.5 , -0.162459832634 , 0.262865565628 )), + vertex(( 0.309016994375 , 0.425325419658 , 0.262865531009 )), + vertex(( -0.309016994375 , 0.425325419658 , 0.262865531009 )), + vertex(( -0.5 , -0.162459832634 , 0.262865565628 )), + vertex(( 0.309016994375 , -0.425325419658 , -0.262865531009 )), + vertex(( 0.5 , 0.162459832634 , -0.262865565628 )), + vertex(( 0.0 , 0.525731096637 , -0.262865587024 )), + vertex(( -0.5 , 0.162459832634 , -0.262865565628 )), + vertex(( -0.309016994375 , -0.425325419658 , -0.262865531009 )), + vertex(( 0.0 , 0.0 , -0.587785252292 )) ] + self.edgeskeleton=[ edge(self.vertskeleton[0],self.vertskeleton[1]), + edge(self.vertskeleton[0],self.vertskeleton[2]), + edge(self.vertskeleton[0],self.vertskeleton[3]), + edge(self.vertskeleton[0],self.vertskeleton[4]), + edge(self.vertskeleton[0],self.vertskeleton[5]), + edge(self.vertskeleton[1],self.vertskeleton[2]), + edge(self.vertskeleton[2],self.vertskeleton[3]), + edge(self.vertskeleton[3],self.vertskeleton[4]), + edge(self.vertskeleton[4],self.vertskeleton[5]), + edge(self.vertskeleton[5],self.vertskeleton[1]), + edge(self.vertskeleton[1],self.vertskeleton[6]), + edge(self.vertskeleton[2],self.vertskeleton[6]), + edge(self.vertskeleton[2],self.vertskeleton[7]), + edge(self.vertskeleton[3],self.vertskeleton[7]), + edge(self.vertskeleton[3],self.vertskeleton[8]), + edge(self.vertskeleton[4],self.vertskeleton[8]), + edge(self.vertskeleton[4],self.vertskeleton[9]), + edge(self.vertskeleton[5],self.vertskeleton[9]), + edge(self.vertskeleton[5],self.vertskeleton[10]), + edge(self.vertskeleton[1],self.vertskeleton[10]), + edge(self.vertskeleton[6],self.vertskeleton[7]), + edge(self.vertskeleton[7],self.vertskeleton[8]), + edge(self.vertskeleton[8],self.vertskeleton[9]), + edge(self.vertskeleton[9],self.vertskeleton[10]), + edge(self.vertskeleton[10],self.vertskeleton[6]), + edge(self.vertskeleton[6],self.vertskeleton[11]), + edge(self.vertskeleton[7],self.vertskeleton[11]), + edge(self.vertskeleton[8],self.vertskeleton[11]), + edge(self.vertskeleton[9],self.vertskeleton[11]), + edge(self.vertskeleton[10],self.vertskeleton[11]) ] + self.panelpoints=[[0,1,2],[0,2,3],[0,3,4],[0,4,5],[0,5,1],[1,2,6],[2,6,7],[2,3,7],[3,7,8],[3,4,8],[4,8,9],[4,5,9],[5,9,10],[5,1,10],[1,10,6],[6,7,11],[7,8,11],[8,9,11],[9,10,11],[10,6,11]] + self.paneledges=[[0,1,5],[1,2,6],[2,3,7],[3,4,8],[4,0,9],[5,10,11],[11,12,20],[6,12,13],[13,14,21],[7,14,15],[15,16,22],[8,16,17],[17,18,23],[9,18,19],[19,10,24],[20,25,26],[21,26,27],[22,27,28],[23,28,29],[24,29,25]] + self.reversepanel=[5,7,9,11,13,15,16,17,18,19] + self.edgelength=[] + self.vertsdone=[[0,0]] * len(self.vertskeleton) +class icoedge(geodesic): + def __init__(self,parameter): + geodesic.__init__(mesh) + geodesic.setparameters(self,parameter) + self.set_vert_edge_skeleons() + def set_vert_edge_skeleons(self): + self.vertskeleton=[ vertex(( 0 , 0.309016994375 , 0.5 )), + vertex(( 0 , -0.309016994375 , 0.5 )), + vertex(( -0.5 , 0 , 0.309016994375 )), + vertex(( 0.5 , 0 , 0.309016994375 )), + vertex(( -0.309016994375 , -0.5 , 0 )), + vertex(( 0.309016994375 , -0.5 , 0 )), + vertex(( 0.309016994375 , 0.5 , 0 )), + vertex(( -0.309016994375 , 0.5 , 0 )), + vertex(( -0.5 , 0 , -0.309016994375 )), + vertex(( 0.5 , 0 , -0.309016994375 )), + vertex(( 0 , 0.309016994375 , -0.5 )), + vertex(( 0 , -0.309016994375 , -0.5 )) ] + self.edgeskeleton=[ edge(self.vertskeleton[0],self.vertskeleton[1]), + edge(self.vertskeleton[0],self.vertskeleton[7]), + edge(self.vertskeleton[0],self.vertskeleton[2]), + edge(self.vertskeleton[1],self.vertskeleton[2]), + edge(self.vertskeleton[1],self.vertskeleton[4]), + edge(self.vertskeleton[1],self.vertskeleton[5]), + edge(self.vertskeleton[1],self.vertskeleton[3]), + edge(self.vertskeleton[0],self.vertskeleton[3]), + edge(self.vertskeleton[0],self.vertskeleton[6]), + edge(self.vertskeleton[2],self.vertskeleton[7]), + edge(self.vertskeleton[2],self.vertskeleton[8]), + edge(self.vertskeleton[2],self.vertskeleton[4]), + edge(self.vertskeleton[4],self.vertskeleton[5]), + edge(self.vertskeleton[3],self.vertskeleton[5]), + edge(self.vertskeleton[3],self.vertskeleton[9]), + edge(self.vertskeleton[3],self.vertskeleton[6]), + edge(self.vertskeleton[6],self.vertskeleton[7]), + edge(self.vertskeleton[7],self.vertskeleton[10]), + edge(self.vertskeleton[7],self.vertskeleton[8]), + edge(self.vertskeleton[4],self.vertskeleton[8]), + edge(self.vertskeleton[4],self.vertskeleton[11]), + edge(self.vertskeleton[5],self.vertskeleton[11]), + edge(self.vertskeleton[5],self.vertskeleton[9]), + edge(self.vertskeleton[6],self.vertskeleton[9]), + edge(self.vertskeleton[6],self.vertskeleton[10]), + edge(self.vertskeleton[8],self.vertskeleton[10]), + edge(self.vertskeleton[8],self.vertskeleton[11]), + edge(self.vertskeleton[9],self.vertskeleton[11]), + edge(self.vertskeleton[9],self.vertskeleton[10]), + edge(self.vertskeleton[10],self.vertskeleton[11]) ] + self.panelpoints=[ [0,1,2],[0,1,3],[0,2,7],[1,2,4],[1,4,5],[1,3,5],[0,3,6],[0,6,7],[2,7,8],[2,4,8], + [3,5,9],[3,6,9],[7,8,10],[4,8,11],[4,5,11],[5,9,11],[6,9,10],[6,7,10],[8,10,11],[9,10,11]] + self.paneledges=[[0,2,3],[0,7,6],[2,1,9],[3,4,11],[4,5,12],[6,5,13],[7,8,15],[8,1,16],[9,10,18],[11,10,19], + [13,14,22],[15,14,23],[18,17,25],[19,20,26],[12,20,21],[22,21,27],[23,24,28],[16,24,17],[25,26,29],[28,27,29]] + self.reversepanel=[0,2,5,9,11,12,14,15,17,19] + self.edgelength=[] + self.vertsdone=[[0,0]] * len(self.vertskeleton) +class icoface(geodesic): + def __init__(self,parameter): + geodesic.__init__(mesh) + geodesic.setparameters(self,parameter) + self.set_vert_edge_skeleons() + def set_vert_edge_skeleons(self): + self.vertskeleton=[ vertex(( -0.17841104489 , 0.309016994375 , 0.46708617948 )), + vertex(( -0.17841104489 , -0.309016994375 , 0.46708617948 )), + vertex(( 0.35682208977 , 0.0 , 0.467086179484 )), + vertex(( -0.57735026919 , 0.0 , 0.110264089705 )), + vertex(( -0.288675134594 , -0.5 , -0.11026408971 )), + vertex(( 0.288675134594 , -0.5 , 0.11026408971 )), + vertex(( 0.57735026919 , 0.0 , -0.110264089705 )), + vertex(( 0.288675134594 , 0.5 , 0.11026408971 )), + vertex(( -0.288675134594 , 0.5 , -0.11026408971 )), + vertex(( -0.35682208977 , 0.0 , -0.467086179484 )), + vertex(( 0.17841104489 , -0.309016994375 , -0.46708617948 )), + vertex(( 0.17841104489 , 0.309016994375 , -0.46708617948 )) ] + self.edgeskeleton=[ edge(self.vertskeleton[0],self.vertskeleton[1]), + edge(self.vertskeleton[2],self.vertskeleton[1]), + edge(self.vertskeleton[2],self.vertskeleton[0]), + edge(self.vertskeleton[0],self.vertskeleton[3]), + edge(self.vertskeleton[1],self.vertskeleton[3]), + edge(self.vertskeleton[1],self.vertskeleton[4]), + edge(self.vertskeleton[1],self.vertskeleton[5]), + edge(self.vertskeleton[2],self.vertskeleton[5]), + edge(self.vertskeleton[2],self.vertskeleton[6]), + edge(self.vertskeleton[2],self.vertskeleton[7]), + edge(self.vertskeleton[0],self.vertskeleton[7]), + edge(self.vertskeleton[0],self.vertskeleton[8]), + edge(self.vertskeleton[3],self.vertskeleton[9]), + edge(self.vertskeleton[3],self.vertskeleton[4]), + edge(self.vertskeleton[5],self.vertskeleton[4]), + edge(self.vertskeleton[5],self.vertskeleton[10]), + edge(self.vertskeleton[5],self.vertskeleton[6]), + edge(self.vertskeleton[7],self.vertskeleton[6]), + edge(self.vertskeleton[7],self.vertskeleton[11]), + edge(self.vertskeleton[7],self.vertskeleton[8]), + edge(self.vertskeleton[3],self.vertskeleton[8]), + edge(self.vertskeleton[4],self.vertskeleton[9]), + edge(self.vertskeleton[4],self.vertskeleton[10]), + edge(self.vertskeleton[6],self.vertskeleton[10]), + edge(self.vertskeleton[6],self.vertskeleton[11]), + edge(self.vertskeleton[8],self.vertskeleton[11]), + edge(self.vertskeleton[8],self.vertskeleton[9]), + edge(self.vertskeleton[9],self.vertskeleton[10]), + edge(self.vertskeleton[11],self.vertskeleton[10]), + edge(self.vertskeleton[11],self.vertskeleton[9]) ] + self.panelpoints=[[2,0,1],[0,1,3],[2,1,5],[2,0,7],[1,3,4],[1,5,4],[2,5,6],[2,7,6],[0,7,8],[0,3,8],[3,4,9],[5,4,10],[5,6,10],[7,6,11],[7,8,11],[3,8,9],[4,9,10],[6,11,10],[8,11,9],[11,9,10]] + self.paneledges=[[2,1,0],[0,3,4],[1,7,6],[2,9,10],[4,5,13],[6,5,14],[7,8,16],[9,8,17],[10,11,19],[3,11,20], + [13,12,21],[14,15,22],[16,15,23],[17,18,24],[19,18,25],[20,12,26],[21,22,27],[24,23,28],[25,26,29],[29,28,27]] + self.reversepanel=[1,3,5,7,9,10,12,14,17,19] + self.edgelength=[] + self.vertsdone=[[0,0]] * len(self.vertskeleton) + +##???PKHG TODO this does not work yet ... +def creategeo(geo,polytype,orientation,parameters): + + if polytype == 'Tetrahedron': + if orientation == 'PointUp': + #return + #geo(parameters) +# geo.setparameters() + my_tetrahedron = tetrahedron(geodesic) + my_tetrahedron.set_vert_edge_skeleons() + my_tetrahedron.config() + check_contains(my_tetrahedron,"my_tetra",True) + vefm_add_object(geo) + elif orientation == 'EdgeUp': + geo = tetraedge(parameters) + else: # orientation==2: + geo=tetraface(parameters) + elif polytype == 'Octahedron': # octahedron + if orientation == 'PointUp': + geo = octahedron(parameters) + elif orientation == 'EdgeUp': + geo = octaedge(parameters) + else: #if orientation==2: + geo = octaface(parameters) + elif polytype == 'Icosahedron': # icosahedron + if orientation == 'PointUp': + geo = icosahedron(parameters) + elif orientation == 'EdgeUp': + geo = icoedge(parameters) + else: #if orientation==2: + geo = icoface(parameters) + return geo diff -Nru blender-2.61/release/scripts/addons_contrib/geodesic_domes/__init__.py blender-2.62/release/scripts/addons_contrib/geodesic_domes/__init__.py --- blender-2.61/release/scripts/addons_contrib/geodesic_domes/__init__.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/geodesic_domes/__init__.py 2012-02-15 19:43:43.000000000 +0000 @@ -0,0 +1,55 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the 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. +# +# ##### END GPL LICENSE BLOCK ##### + +bl_info = { + "name": "Geodesic Domes", + "author": "PKHG , Meta Androcto, Kilon original for 2.49 from Andy Houston", + "version": (0,2,3), + "blender": (2, 6, 1), + "location": "View3D > UI > Geodesic...", + "description": "Choice for objects", + "warning": "not yet finished", + "wiki_url": "http://wiki.blender.org/index.php?title=Extensions:2.5/Py/Scripts/Modeling/Geodesic_Domes", + "tracker_url": "", + "category": "Mesh"} + +""" +Added save and load of parameters 14-12-2011 PKHG +Added one possible *.bak for GD_0.GD (one time) 17-12-2011 +""" +if "bpy" in locals(): + import imp + imp.reload(third_domes_panel) + +else: + from geodesic_domes import third_domes_panel + +import bpy +from bpy.props import * + +def register(): + bpy.utils.register_module(__name__) + +def unregister(): + bpy.utils.unregister_module(__name__) + +if __name__ == "__main__": + register() + + + diff -Nru blender-2.61/release/scripts/addons_contrib/geodesic_domes/read_me.txt blender-2.62/release/scripts/addons_contrib/geodesic_domes/read_me.txt --- blender-2.61/release/scripts/addons_contrib/geodesic_domes/read_me.txt 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/geodesic_domes/read_me.txt 2012-02-15 19:43:43.000000000 +0000 @@ -0,0 +1,28 @@ +Geodesic_Domes +Based on a script by Andy Houston (serendipiti) for Blender 2.49 +Original Script Documentation: +http://wiki.blender.org/index.php/Extensions:2.4/Py/Scripts/Wizards/Geodesic_dome +Licence: +GPL + +PKHG (did the conversion) +BIG change after revision 2551 GUI adjusted ... +You should download anew if older then 24-november-2011 + +In principle all parts work: +the *hedrons with superformparameters +Grid ... Sphere with superformparameters +Faces ** +Hubs ** +Struts ** + +** means will be adjusted ... at the moment you have to name objects and +execute eventually again ;-( ... + +but PKHG is content with a this nearly 95% converted version. + +TODO, ranges of parameters could be chosen differently. Inform PKHG! + +Uplaod will be done today (25-11 at about 19.30... GMT -+1) + +_259 in the names is not important ... but let it be so (now) ;-) diff -Nru blender-2.61/release/scripts/addons_contrib/geodesic_domes/third_domes_panel.py blender-2.62/release/scripts/addons_contrib/geodesic_domes/third_domes_panel.py --- blender-2.61/release/scripts/addons_contrib/geodesic_domes/third_domes_panel.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/geodesic_domes/third_domes_panel.py 2012-02-15 19:43:43.000000000 +0000 @@ -0,0 +1,1061 @@ +import bpy +import os +from geodesic_domes import vefm_259 +from geodesic_domes import forms_259 +from geodesic_domes import geodesic_classes_259 +from geodesic_domes import add_shape_geodesic + +from bpy.props import EnumProperty, IntProperty, FloatProperty, StringProperty, BoolProperty +import math +from math import pi +from mathutils import Vector #needed to check vertex.vector values +try: + breakpoint = bpy.types.bp.bp +except: + print("add breakpoint addon!") + + +########global###### +last_generated_object = None +last_imported_mesh = None +basegeodesic = None +imported_hubmesh_to_use = None +########global end###### + +########EIND FOR SHAPEKEYS###### +### error messages?! +bpy.types.Scene.error_message = StringProperty(name="actual error", default = "") + + +bpy.types.Scene.geodesic_not_yet_called = BoolProperty(name="geodesic_not_called",default = True) + +bpy.types.Scene.gd_help_text_width = IntProperty(name = "Text Width" , description = "The width above which the text wraps" , default = 60 , max = 180 , min = 20) + +class Geodesic_Domes_Operator_Panel(bpy.types.Panel): + """start a GD object here""" + bl_label = "Geodesic Domes" + bl_region_type = "TOOLS" #UI possible too + bl_space_type = "VIEW_3D" + + def draw(self,context): + sce = context.scene + layout = self.layout + col = layout.column() + col.label("To start an GD object: ") + col.operator(GenerateGeodesicDome.bl_idname,"execute me!") + +class GenerateGeodesicDome(bpy.types.Operator): + bl_label = "Modify Geodesic Objects" + bl_idname = "mesh.generate_geodesic_dome" + bl_description = "Create object dependent on selection" + bl_options = {'REGISTER','UNDO'} + +#PKHG_NEW saving and loading parameters + save_parameters = BoolProperty(name = "save params",\ + description = "activation save */tmp/GD_0.GD", default = False) + load_parameters = BoolProperty(name = "load params",\ + description = "read */tmp/GD_0.GD", default = False) + + gd_help_text_width = IntProperty(name = "Text Width" , description = "The width above which the text wraps" , default = 60 , max = 180 , min = 20) + + + mainpages = EnumProperty( + name="Menu", + description="Create Faces, Struts & Hubs", + items=[("Main","Main","Geodesic objects"), + ("Faces","Faces","Generate Faces"), + ("Struts","Struts","Generate Struts"), + ("Hubs","Hubs","Generate Hubs"), + ("Help","Help","Not implemented"), + ], + default='Main') + +#for Faces! + facetype_menu = EnumProperty( + name="Faces", + description="choose a facetype", + items=[("0","strip","strip"), + ("1","open vertical","vertical"), + ("2","opwn slanted","slanted"), + ("3","closed point","closed point"), + ("4","pillow","pillow"), + ("5","closed vertical","closed vertical"), + ("6","stepped","stepped"), + ("7","spikes","spikes"), + ("8","boxed","boxed"), + ("9","diamond","diamond"), + ("10","bar","bar"), + ], + default='0') + + facetoggle = BoolProperty(name="Activate: Face Object", description = "Activate Faces for Geodesic object", default = False ) +# faceimporttoggle = BoolProperty(name="faceimporttoggle", default = False ) + face_use_imported_object = BoolProperty(name="Use: Imported Object",\ + description = "Activate faces on your Imported object", default = False) + facewidth = FloatProperty(name="facewidth", min = -8, max = 8, default = .50) + fwtog = BoolProperty(name="fwtog", default = False ) + faceheight = FloatProperty(name="faceheight", min = -8, max = 8, default = 1 ) + fhtog = BoolProperty(name="fhtog", default = False ) + face_detach = BoolProperty(name="face_detach", default = False ) + fmeshname = StringProperty(name="fmeshname", default = "defaultface") + + + geodesic_types = EnumProperty( + name="Objects", + description="Choose Geodesic, Grid, Cylinder,Parabola, Torus, Sphere, Import your mesh or Superparameters", + items=[("Geodesic","Geodesic","Generate Geodesic"), + ("Grid","Grid","Generate Grid"), + ("Cylinder","Cylinder","Generate Cylinder"), + ("Parabola","Parabola","Generate Parabola"), + ("Torus","Torus","Generate Torus"), + ("Sphere","Sphere","Generate Sphere"), + ("Import your mesh","Import your mesh","Import Your Mesh"), + ], + default='Geodesic') + + import_mesh_name = StringProperty(name = "mesh to import",\ + description = "the name has to be the name of a meshobject", default = "None") + + base_type = EnumProperty( + name="Hedron", + description="Choose between Tetrahedron, Octahedron, Icosahedron ", + items=[("Tetrahedron","Tetrahedron","Generate Tetrahedron"), + ("Octahedron","Octahedron","Generate Octahedron"), + ("Icosahedron","Icosahedron","Generate Icosahedron"), + ], + default='Tetrahedron') + + orientation = EnumProperty( + name="Point^", + description="Point (Vert), Edge or Face pointing upwards", + items=[("PointUp","PointUp","Point up"), + ("EdgeUp","EdgeUp","Edge up"), + ("FaceUp","FaceUp","Face up"), + ], + default='PointUp') + + geodesic_class = EnumProperty( + name="Class", + description="Subdivide Basic/Triacon", + items=[("Class 1","Class 1","class one"), + ("Class 2","Class 2","class two"), + ], + default='Class 1') + + tri_hex_star = EnumProperty( + name="Shape", + description="Choose between tri hex star face types", + items=[("tri","tri","tri faces"), + ("hex","hex","hex faces(by tri)"), + ("star","star","star faces(by tri)"), + ], + default='tri') + + spherical_flat = EnumProperty( + name="Round", + description="Choose between spherical or flat ", + items=[("spherical","spherical","Generate spherical"), + ("flat","flat","Generate flat"), + ], + default='spherical') + + use_imported_mesh = BoolProperty(name="use import",\ + description = "Use an imported mesh", default = False) + +#Cylinder + cyxres= IntProperty(name="Resolution x/y", min = 3, max = 32,\ + description = "number of faces around x/y", default = 5 ) + cyyres= IntProperty(name="Resolution z", min = 3, max = 32,\ + description = "number of faces in z direction", default = 5 ) + cyxsz= FloatProperty(name="Scale x/y", min = 0.01, max = 10,\ + description = "scale in x/y direction", default = 1 ) + cyysz= FloatProperty(name="Scale z", min = 0.01, max = 10,\ + description = "scale in z direction", default = 1 ) + cyxell= FloatProperty(name="Stretch x", min = 0.001, max = 4,\ + description = "stretch in x direction", default = 1 ) + cygap= FloatProperty(name="Gap", min = -2, max = 2, precision = 4,\ + description = "shrink in % around radius", default = 1 ) + cygphase= FloatProperty(name="Phase", min = -4, max = 4,\ + description = "rotate around pivot x/y", default = 0 ) +#Parabola + paxres= IntProperty(name="Resolution x/y", min = 3, max = 32,\ + description = "number of faces around x/y", default = 5 ) + payres= IntProperty(name="Resolution z", min = 3, max = 32,\ + description = "number of faces in z direction", default = 5 ) + paxsz= FloatProperty(name="Scale x/y", min = 0.001, max = 10,\ + description = "scale in x/y direction", default = 0.30) + paysz= FloatProperty(name="Scale z", min = 0.001, max = 10,\ + description = "scale in z direction", default = 1 ) + paxell= FloatProperty(name="Stretch x", min = 0.001, max = 4,\ + description = "stretch in x direction", default = 1 ) + pagap= FloatProperty(name="Gap", min = -2, max = 2,\ + description = "shrink in % around radius", precision = 4, default = 1 ) + pagphase= FloatProperty(name="Phase", min = -4, max = 4,\ + description = "rotate around pivot x/y", default = 0 ) +#Torus + ures= IntProperty(name="Resolution x/y",min = 3, max = 32,\ + description = "number of faces around x/y", default = 8 ) + vres= IntProperty(name="Resolution z", min = 3, max = 32,\ + description = "number of faces in z direction", default = 8 ) + urad= FloatProperty(name="Radius x/y", min = 0.001, max = 10,\ + description = "radius in x/y plane", default = 1 ) + vrad= FloatProperty(name="Radius z", min = 0.001, max = 10,\ + description = "radius in z plane", default = 0.250) + uellipse= FloatProperty(name="Stretch x", min = 0.001, max = 10,\ + description = "number of faces in z direction", default = 1 ) + vellipse= FloatProperty(name="Stretch z", min = 0.001, max = 10,\ + description = "number of faces in z direction", default = 1 ) + upart= FloatProperty(name="Gap x/y", min = -4, max = 4, precision = 4,\ + description = "shrink faces around x/y", default = 1 ) + vpart= FloatProperty(name="Gap z", min = -4, max = 4, precision = 4,\ + description = "shrink faces in z direction", default = 1 ) + ugap= FloatProperty(name="Phase x/y", min = -4, max = 4, precision = 4,\ + description = "rotate around pivot x/y", default = 0 ) + vgap= FloatProperty(name="Phase z", min = -4, max = 4, precision = 4,\ + description = "rotate around pivot z", default = 0 ) + uphase= FloatProperty(name="uphase", min = -4, max = 4,\ + description = "number of faces in z direction", default = 0 ) + vphase= FloatProperty(name="vphase", min = -4, max = 4,\ + description = "number of faces in z direction", default = 0 ) + uexp= FloatProperty(name="uexp", min = -4, max = 4,\ + description = "number of faces in z direction", default = 0 ) + vexp= FloatProperty(name="vexp", min = -4, max = 4,\ + description = "number of faces in z direction", default = 0 ) + usuper= FloatProperty(name="usuper", min = -4, max = 4,\ + description = "first set of superform parameters", default = 2 ) + vsuper= FloatProperty(name="vsuper", min = -4, max = 4,\ + description = "second set of superform parameters", default = 2 ) + utwist= FloatProperty(name="Twist x/y", min = -4, max = 4,\ + description = " use with superformular u", default = 0 ) + vtwist= FloatProperty(name="Twist z", min = -4, max = 4,\ + description = "use with superformular v", default = 0 ) + +#Sphere + bures= IntProperty(name="Resolution x/y", min = 3, max = 32,\ + description = "number of faces around x/y", default = 8 ) + bvres= IntProperty(name="Resolution z", min = 3, max = 32,\ + description = "number of faces in z direction", default = 8 ) + burad= FloatProperty(name="Radius", min = -4, max = 4,\ + description = "overall radius", default = 1 ) + bupart= FloatProperty(name="Gap x/y", min = -4, max = 4, precision = 4,\ + description = "shrink faces around x/y", default = 1 ) + bvpart= FloatProperty(name="Gap z", min = -4, max = 4, precision = 4,\ + description = "shrink faces in z direction", default = 1 ) + buphase= FloatProperty(name="Phase x/y", min = -4, max = 4, + description = "rotate around pivot x/y", default = 0 ) + bvphase= FloatProperty(name="Phase z", min = -4, max = 4,\ + description = "rotate around pivot z", default = 0 ) + buellipse= FloatProperty(name="Stretch x", min = 0.001, max = 4,\ + description = "stretch in the x direction", default = 1 ) + bvellipse= FloatProperty(name="Stretch z", min = 0.001, max = 4,\ + description = "stretch in the z direction", default = 1 ) +#Grid + grxres = IntProperty(name="Resolution x", min = 2, soft_max = 10, max = 20,\ + description = "number of faces in x direction", default = 5 ) + gryres = IntProperty(name="Resolution z",min = 2, soft_min = 2, soft_max=10, max = 20,\ + description = "number of faces in x direction", default = 2) + grxsz = FloatProperty(name = "X size", min = 1, soft_min=0.01, soft_max=5, max = 10,\ + description = "x size", default = 2.0) + grysz = FloatProperty(name="Y size",min = 1, soft_min=0.01, soft_max=5, max = 10,\ + description = "y size", default = 1.0) + +#PKHG_TODO_??? what means cart + cart = IntProperty(name = "cart",min = 0, max = 2, default = 0) + + frequency = IntProperty(name="Frequency", min = 1, max = 8,\ + description ="subdivide base triangles", default = 1 ) + eccentricity = FloatProperty(name = "Eccentricity", min = 0.01 , max = 4,\ + description = "scaling in x/y dimension", default = 1 ) + squish = FloatProperty(name = "Squish",min = 0.01, soft_max = 4, max = 10,\ + description = "scaling in z dimension", default = 1 ) + radius = FloatProperty(name = "Radius",min = 0.01, soft_max = 4, max = 10,\ + description = "overall radius", default = 1 ) + squareness = FloatProperty(name="Square x/y", min = 0.1, max = 5,\ + description = "superelipse action in x/y", default = 2 ) + squarez = FloatProperty(name="Square z", min = 0.1, soft_max = 5, max = 10,\ + description = "superelipse action in z", default = 2 ) + baselevel = IntProperty(name="baselevel", default = 5 ) + dual = BoolProperty(name="Dual", description = "faces become verts, verts become faces, edges flip", default = False) + rotxy = FloatProperty(name="Rotate x/y", min= -4, max = 4,\ + description = "rotate superelipse action in x/y", default = 0 ) + rotz = FloatProperty(name="Rotate z", min= -4, max = 4,\ + description = "rotate superelipse action in z", default = 0 ) + +#for choice of superformula + uact = BoolProperty(name = 'superformula u (x/y)', description = "activate superformula u parameters", default = False) + vact = BoolProperty(name = 'superformula v (z)', description = "activate superformula v parameters", default = False) + um = FloatProperty(name = 'um', min = 0, soft_min=0.1, soft_max = 10, max = 20,\ + description = "to do", default = 3) + un1 = FloatProperty(name = 'un1', min = 0, soft_min=0.1, soft_max = 10,max = 20,\ + description = "to do", default = 1) + un2 = FloatProperty(name = 'un2', min = 0, soft_min=0.1, soft_max = 10,max = 20,\ + description = "to do", default = 1) + un3 = FloatProperty(name = 'un3', min = 0, soft_min=0.1, soft_max = 10, max = 20,\ + description = "to do", default = 1) + ua = FloatProperty(name = 'ua', min = 0.01, soft_min=0.1, soft_max = 8, max = 16,\ + description = "semi-diameter (has both soft pars!)", default = 1.0) + ub = FloatProperty(name = 'ub', min = 0.01, soft_min = 0.1, soft_max = 8, max = 16,\ + description = "semi-diameter (has both soft pars!)", default = 1.0) + vm = FloatProperty(name = 'vm', min = 0, soft_min=0.1, soft_max=5,max = 10,\ + description = "to do", default = 1) + vn1 = FloatProperty(name = 'vn1', min = 0, soft_min=0.1, soft_max=5,max = 10,\ + description = "to do", default = 1) + vn2 = FloatProperty(name = 'vn2', min = 0, soft_min=0.1, soft_max=5,max = 10,\ + description = "to do", default = 1) + vn3 = FloatProperty(name = 'vn3', min = 0, soft_min=0.1, soft_max=5,max = 10,\ + description = "to do", default = 1) + va = FloatProperty(name = 'va', min = 0, soft_min=0.1, soft_max=5,max = 10,\ + description = "to do", default = 1) + vb = FloatProperty(name = 'vb', min = 0, soft_min=0.1, soft_max=5,max = 10,\ + description = "to do", default = 1) + + uturn = FloatProperty(name = 'uturn', min = -5, soft_min=0, soft_max=5,max = 10,\ + description = "to do", default = 0) + vturn = FloatProperty(name = 'vturn', min = 0, soft_min=0.1, soft_max=5,max = 10,\ + description = "to do", default = 0) + utwist = FloatProperty(name = 'utwist', min = 0, soft_min=0.1, soft_max=5,max = 10,\ + description = "to do", default = 0) + vtwist = FloatProperty(name = 'vtwist', min = 0, soft_min=0.1, soft_max=5,max = 10,\ + description = "to do", default = 0) + +#Strut + struttype= IntProperty(name="struttype", default= 0) + struttoggle = BoolProperty(name="struttoggle", default = False ) + strutimporttoggle= BoolProperty(name="strutimporttoggle", default = False ) + strutimpmesh= StringProperty(name="strutimpmesh", default = "None") + strutwidth= FloatProperty(name="strutwidth", min = -10, soft_min = 5, soft_max = 5, max = 10, default = 1 ) + swtog= BoolProperty(name="swtog", default = False ) + strutheight= FloatProperty(name="strutheight", min = -5, soft_min = -1, soft_max = 5, max = 10, default = 1 ) + shtog= BoolProperty(name="shtog", default = False ) + strutshrink= FloatProperty(name="strutshrink", min = 0.001, max = 4, default = 1 ) + sstog= BoolProperty(name="sstog", default = False ) + stretch= FloatProperty(name="stretch", min= -4, max = 4, default = 1.0 ) + lift= FloatProperty(name="lift", min = 0.001, max = 10, default = 0 ) + smeshname= StringProperty(name="smeshname", default = "defaultstrut") + +#Hubs + hubtype = BoolProperty(name ="hubtype", description = "not used", default = True ) + hubtoggle = BoolProperty(name ="hubtoggle", default = False ) + hubimporttoggle = BoolProperty(name="new import", description = "import a mesh", default = False ) + hubimpmesh = StringProperty(name="hubimpmesh",\ + description = "name of mesh to import", default = "None") + hubwidth = FloatProperty(name="hubwidth", min = 0.01, max = 10,\ + default = 1 ) + hwtog = BoolProperty(name="hwtog", default = False ) + hubheight = FloatProperty(name="hubheight", min = 0.01, max = 10,\ + default = 1 ) + hhtog = BoolProperty(name="hhtog", default = False ) + hublength = FloatProperty(name ="hublength", min = 0.1, max = 10,\ + default = 1 ) + hstog= BoolProperty(name="hstog", default = False ) + hmeshname= StringProperty(name="hmeshname", description = "Name of an existing mesh needed!", default = "None") + + name_list = ['facetype_menu','facetoggle','face_use_imported_object', +'facewidth','fwtog','faceheight','fhtog', +'face_detach','fmeshname','geodesic_types','import_mesh_name', +'base_type','orientation','geodesic_class','tri_hex_star', +'spherical_flat','use_imported_mesh','cyxres','cyyres', +'cyxsz','cyysz','cyxell','cygap', +'cygphase','paxres','payres','paxsz', +'paysz','paxell','pagap','pagphase', +'ures','vres','urad','vrad', +'uellipse','vellipse','upart','vpart', +'ugap','vgap','uphase','vphase', +'uexp','vexp','usuper','vsuper', +'utwist','vtwist','bures','bvres', +'burad','bupart','bvpart','buphase', +'bvphase','buellipse','bvellipse','grxres', +'gryres','grxsz','grysz', +'cart','frequency','eccentricity','squish', +'radius','squareness','squarez','baselevel', +'dual','rotxy','rotz', +'uact','vact','um','un1', +'un2','un3','ua','ub', +'vm','vn1','vn2','vn3', +'va','vb','uturn','vturn', +'utwist','vtwist','struttype','struttoggle', +'strutimporttoggle','strutimpmesh','strutwidth','swtog', +'strutheight','shtog','strutshrink','sstog', +'stretch','lift','smeshname','hubtype', +'hubtoggle','hubimporttoggle','hubimpmesh','hubwidth', +'hwtog','hubheight','hhtog','hublength', +'hstog','hmeshname'] + + def write_params(self,filename): + file = open(filename, "w", encoding="utf8", newline="\n") + fw = file.write + #for Faces! + for el in self.name_list: + fw(el + ",") + fw(repr(getattr(self,el))) + fw(",\n") + file.close() + + def read_file(self,filename): + file = open(filename, "r", newline="\n") + result = [] + line = file.readline() + while(line): + tmp = line.split(",") + result.append(eval(tmp[1])) + line = file.readline() + return result + + + def draw(self,context): + sce = context.scene + layout = self.layout + row = layout.row() + row.prop(self,"save_parameters") + row.prop(self,"load_parameters") + col = layout.column() + col.label(" ") + col.prop(self,"mainpages") + which_mainpages = self.mainpages + if which_mainpages == 'Main': + col = layout.column() + col.prop(self,"geodesic_types") + tmp = self.geodesic_types + if tmp == "Geodesic": + col.label(text="Geodesic Object Types:") + col.prop(self, "geodesic_class") + col.prop(self, "base_type") + col.prop(self, "orientation") + col.prop(self, "tri_hex_star") + col.prop(self, "spherical_flat") + col.label("Geodesic Object Parameters:") + row = layout.row() + row.prop(self,"frequency") + row = layout.row() + row.prop(self,"radius") + row = layout.row() + row.prop(self,"eccentricity") + row = layout.row() + row.prop(self,"squish") + row = layout.row() + row.prop(self,"squareness") + row = layout.row() + row.prop(self,"squarez") + row = layout.row() + row.prop(self,"rotxy") + row = layout.row() + row.prop(self,"rotz") + row = layout.row() + row.prop(self,"dual") + elif tmp == 'Torus': + col.label("Torus Parameters") + row = layout.row() + row.prop(self, "ures") + row = layout.row() + row.prop(self, "vres") + row = layout.row() + row.prop(self, "urad") + row = layout.row() + row.prop(self, "vrad") + row = layout.row() + row.prop(self, "uellipse") + row = layout.row() + row.prop(self, "vellipse") + row = layout.row() + row.prop(self, "upart") + row = layout.row() + row.prop(self, "vpart") + row = layout.row() + row.prop(self, "ugap") + row.prop(self, "vgap") + row = layout.row() + row.prop(self, "uphase") + row.prop(self, "vphase") + row = layout.row() + row.prop(self, "uexp") + row.prop(self, "vexp") + row = layout.row() + row.prop(self, "usuper") + row.prop(self, "vsuper") + row = layout.row() + row.prop(self, "vgap") + row = layout.row() + elif tmp == 'Sphere': + col.label("Sphere Parameters") + row = layout.row() + row.prop(self,"bures") + row = layout.row() + row.prop(self,"bvres") + row = layout.row() + row.prop(self,"burad") + row = layout.row() + row.prop(self,"bupart") + row = layout.row() + row.prop(self,"buphase") + row = layout.row() + row.prop(self,"bvpart") + row = layout.row() + row.prop(self,"bvphase") + row = layout.row() + row.prop(self,"buellipse") + row = layout.row() + row.prop(self,"bvellipse") + elif tmp == 'Parabola': + col.label("Parabola Parameters") + row = layout.row() + row.prop(self, "paxres") + row = layout.row() + row.prop(self, "payres") + row = layout.row() + row.prop(self, "paxsz") + row = layout.row() + row.prop(self, "paysz") + row = layout.row() + row.prop(self, "paxell") + row = layout.row() + row.prop(self, "pagap") + row = layout.row() + row.prop(self, "pagphase") + elif tmp == 'Cylinder': + col.label("Cylinder Parameters") + col.prop(self, "cyxres") + col.prop(self, "cyyres") + col.prop(self, "cyxsz") + col.prop(self, "cyysz") + col.prop(self, "cyxell") + col.prop(self, "cygap") + col.prop(self, "cygphase") + elif tmp == 'Grid': + col.label("Grid Parameters") + row = layout.row() + row.prop(self, "grxres") + row = layout.row() + row.prop(self, "gryres") + row = layout.row() + row.prop(self, "grxsz") + row = layout.row() + row.prop(self, "grysz") + elif tmp == 'Import your mesh': + col.prop(self,"use_imported_mesh") + col.prop(self, "import_mesh_name") +#######superform parameters only where possible + row = layout.row() + row.prop(self,"uact") + row = layout.row() + row.prop(self,"vact") + row = layout.row() + if not(tmp == 'Import your mesh'): + if (self.uact == False) and (self.vact == False): + row.label("no checkbox active!") + else: + row.label("Superform Parameters") + if self.uact: + row = layout.row() + row.prop(self,"um") + row = layout.row() + row.prop(self,"un1") + row = layout.row() + row.prop(self,"un2") + row = layout.row() + row.prop(self,"un3") + row = layout.row() + row.prop(self,"ua") + row = layout.row() + row.prop(self,"ub") + row = layout.row() + row.prop(self,"uturn") + row = layout.row() + row.prop(self,"utwist") + if self.vact: + row = layout.row() + row.prop(self,"vm") + row = layout.row() + row.prop(self,"vn1") + row = layout.row() + row.prop(self,"vn2") + row = layout.row() + row.prop(self,"vn3") + row = layout.row() + row.prop(self,"va") + row = layout.row() + row.prop(self,"vb") + row = layout.row() + row.prop(self,"vturn") + row = layout.row() + row.prop(self,"vtwist") +########einde superfo + elif which_mainpages == "Hubs": + row = layout.row() + row.prop(self, "hubtoggle") +#PKHG_NOT_USDED_YET_24-11 row.prop(self, "hubtype") + row = layout.row() +#25-11 not needed row.prop(self, "hubimporttoggle") + row = layout.row() + if self.hubimpmesh == "None": + row = layout.row() + row.label("name of a hub to use") + row = layout.row() + row.prop(self, "hubimpmesh") + row = layout.row() + if self.hmeshname == "None": + row = layout.row() + row.label("name of mesh to be filled in!") + row = layout.row() + row.prop(self,"hmeshname") + row = layout.row() + row.prop(self, "hwtog") + if self.hwtog: + row.prop(self, "hubwidth") + row = layout.row() + row.prop(self, "hhtog") + if self.hhtog: + row.prop(self, "hubheight") + row = layout.row() + row.prop(self, "hublength") + elif which_mainpages == "Struts": + row = layout.row() +# row.prop(self, "struttype") + row.prop(self, "struttoggle") +# row = layout.row() +# row.prop(self, "strutimporttoggle") + row = layout.row() + row.prop(self, "strutimpmesh") + row = layout.row() + row.prop(self, "swtog") + if self.swtog: + row.prop(self, "strutwidth") + row = layout.row() + row.prop(self, "shtog") + if self.shtog: + row.prop(self, "strutheight") + row = layout.row() + row.prop(self, "sstog") + if self.sstog: + row.prop(self, "strutshrink") + row = layout.row() + row.prop(self, "stretch") + row = layout.row() + row.prop(self, "lift") + row = layout.row() + row.prop(self, "smeshname") + elif which_mainpages == "Faces": + row = layout.row() + row.prop(self,"facetoggle") + row = layout.row() + row.prop(self,"face_use_imported_object") + row = layout.row() + row.prop(self,"facetype_menu") + row = layout.row() + row.prop(self,"fwtog") + if self.fwtog: + row.prop(self,"facewidth") + row = layout.row() + row.prop(self,"fhtog") + if self.fhtog: + row.prop(self,"faceheight") + row = layout.row() + row.prop(self,"face_detach") + row = layout.row() + row.prop(self,"fmeshname") + row = layout.row() + + #help menu GUI + elif which_mainpages == "Help": + import textwrap + + # a function that allows for multiple labels with text that wraps + # you can allow the user to set where the text wraps with the + # text_width parameter + # other parameters are ui : here you usually pass layout + # text: is a list with each index representing a line of text + + def multi_label(text, ui,text_width=120): + for x in range(0,len(text)): + el = textwrap.wrap(text[x], width = text_width ) + + for y in range(0,len(el)): + ui.label(text=el[y]) + + box = layout.box() + help_text = ["NEW! ", + "New facility: save or load (nearly all) parameters ", + "A file GD_0.GD will be used, living in: ", + "geodesic_domes/tmp ", + "and if possible two backups " + "--------", + "After loading you have to change a ", + "parameter back and forth " + "to see it"] + text_width = self.gd_help_text_width + box.prop(self,"gd_help_text_width",slider=True) + multi_label(help_text,box, text_width) + + def execute(self, context): + global last_generated_object, last_imported_mesh, basegeodesic, imported_hubmesh_to_use + #default superformparam = [3, 10, 10, 10, 1, 1, 4, 10, 10, 10, 1, 1, 0, 0, 0.0, 0.0, 0, 0]] + superformparam = [self.um, self.un1, self.un2, self.un3, self.ua,\ + self.ub, self.vm, self.vn1, self.vn2, self.vn3,\ + self.va, self.vb, self.uact, self.vact,\ + self.uturn*pi, self.vturn*pi, \ + self.utwist, self.vtwist] + context.scene.error_message = "" + if self.mainpages == 'Main': + if self.geodesic_types == "Geodesic": + tmp_fs = self.tri_hex_star + faceshape = 0 # tri! + if tmp_fs == "hex": + faceshape = 1 + elif tmp_fs == "star": + faceshape = 2 + tmp_cl = self.geodesic_class + klass = 0 + if tmp_cl == "Class 2": + klass = 1 + shape = 0 + parameters = [self.frequency, self.eccentricity, self.squish,\ + self.radius, self.squareness, self.squarez, 0,\ + shape, self.baselevel, faceshape, self.dual,\ + self.rotxy, self.rotz, klass, superformparam] + basegeodesic = creategeo(self.base_type,self.orientation,parameters) + basegeodesic.makegeodesic() + basegeodesic.connectivity() + mesh = vefm_259.mesh() + vefm_259.finalfill(basegeodesic,mesh) #always! for hexifiy etc. necessarry!!! + vefm_259.vefm_add_object(mesh) + last_generated_object = context.active_object + last_generated_object.location = (0,0,0) + context.scene.objects.active = last_generated_object + elif self.geodesic_types == 'Grid': + basegeodesic = forms_259.grid(self.grxres,self.gryres,\ + self.grxsz,self.grysz,1.0,1.0,0,0,0,\ + 0,1.0,1.0,superformparam) + vefm_259.vefm_add_object(basegeodesic) + bpy.data.objects[-1].location = (0,0,0) + elif self.geodesic_types == "Cylinder": + basegeodesic = forms_259.cylinder(self.cyxres, self.cyyres, \ + self.cyxsz, self.cyysz, self.cygap, \ + 1.0, self.cygphase, 0, 0, 0, self.cyxell,\ + 1.0, superformparam) + vefm_259.vefm_add_object(basegeodesic) + bpy.data.objects[-1].location = (0,0,0) + + elif self.geodesic_types == "Parabola": + basegeodesic=forms_259.parabola(self.paxres, self.payres,\ + self.paxsz, self.paysz, self.pagap,1.0, self.pagphase,\ + 0,0,0, self.paxell,1.0,superformparam) + vefm_259.vefm_add_object(basegeodesic) + bpy.data.objects[-1].location = (0,0,0) + elif self.geodesic_types == "Torus": + basegeodesic = forms_259.torus(self.ures, self.vres,\ + self.vrad, self.urad, self.upart, self.vpart,\ + self.ugap, self.vgap,0,0, self.uellipse,\ + self.vellipse, superformparam) + vefm_259.vefm_add_object(basegeodesic) + bpy.data.objects[-1].location = (0,0,0) + elif self.geodesic_types == "Sphere": + basegeodesic=forms_259.sphere(self.bures, self.bvres,\ + self.burad,1.0, self.bupart, self.bvpart,\ + self.buphase, self.bvphase,0,0, self.buellipse,\ + self.bvellipse,superformparam) + + vefm_259.vefm_add_object(basegeodesic) + bpy.data.objects[-1].location = (0,0,0) + elif self.geodesic_types == "Import your mesh": + obj_name = self.import_mesh_name + if obj_name == "None": + message = "fill in a name \nof an existing mesh\nto be imported" + context.scene.error_message = message + self.report({"INFO"}, message) + print("***INFO*** you have to fill in the name of an existing mesh") + else: +# obj_in_scene = context.objects + names = [el.name for el in context.scene.objects] + if obj_name in names and context.scene.objects[obj_name].type == "MESH": + obj = context.scene.objects[obj_name] +# if obj.type == "MESH": + your_obj = vefm_259.importmesh(obj.name,False) + last_imported_mesh = your_obj + vefm_259.vefm_add_object(your_obj) + last_generated_object = bpy.context.active_object + last_generated_object.name ="Imported mesh" + bpy.context.active_object.location = (0,0,0) + else: + message = obj_name +" does not exist \nor is not a MESH" + context.scene.error_message = message + bpy.ops.object.dialog_operator('INVOKE_DEFAULT') + self.report({'ERROR'}, message) + print("***ERROR***" + obj_name +" does not exist or is not a MESH") + elif self.mainpages == "Hubs": + hubtype = self.hubtype + hubtoggle = self.hubtoggle + hubimporttoggle = self.hubimporttoggle + hubimpmesh = self.hubimpmesh + hubwidth = self.hubwidth + hwtog = self.hwtog + hubheight = self.hubheight + hhtog = self.hhtog + hublength = self.hublength + hstog = self.hstog + hmeshname= self.hmeshname +#PKHG_TODO_27-11 better info!?? + if not (hmeshname == "None") and not (hubimpmesh == "None") and hubtoggle: + try: + hub_obj = vefm_259.importmesh(hmeshname,0) + hub = vefm_259.hub(hub_obj, True,\ + hubwidth, hubheight, hublength,\ + hwtog, hhtog, hstog, hubimpmesh) + mesh = vefm_259.mesh("test") + vefm_259.finalfill(hub,mesh) + vefm_259.vefm_add_object(mesh) + bpy.data.objects[-1].location = (0,0,0) + except: + message = "***ERROR*** \neither no mesh for hub\nor " + hmeshname + " available" + context.scene.error_message = message + bpy.ops.object.dialog_operator('INVOKE_DEFAULT') + print(message) + else: + message = "***INFO***\nuse the hub toggle!" + context.scene.error_message = message + print("\n***INFO*** use the hub toggle!") + elif self.mainpages == "Struts": + struttype = self.struttype + struttoggle = self.struttoggle + strutimporttoggle = self.strutimporttoggle + strutimpmesh = self.strutimpmesh + strutwidth = self.strutwidth + swtog = self.swtog + strutheight = self.strutheight + shtog = self.shtog + strutshrink = self.strutshrink + sstog = self.sstog + stretch = self.stretch + lift = self.lift + smeshname = self.smeshname + if not (strutimpmesh == "None") and struttoggle: + names = [el.name for el in context.scene.objects] + if strutimpmesh in names and context.scene.objects[strutimpmesh].type == "MESH": + strut = vefm_259.strut(basegeodesic, struttype,strutwidth,strutheight,stretch,swtog,shtog,swtog,strutimpmesh,sstog,lift) + strutmesh = vefm_259.mesh() + vefm_259.finalfill(strut,strutmesh) + vefm_259.vefm_add_object(strutmesh) + last_generated_object = context.active_object + last_generated_object.name = smeshname + last_generated_object.location = (0,0,0) + else: + message = "***ERROR***\n" + strutimpmesh + "\nis not a MESH" + context.scene.error_message = message + bpy.ops.object.dialog_operator('INVOKE_DEFAULT') + print("***ERROR*** strut obj is not a MESH") + else: + vefm_259.vefm_add_object(basegeodesic) + elif self.mainpages == "Faces": + if self.facetoggle: + faceparams=[[self.face_detach,0,[[0.5,0.0]]], #0 strip + [self.face_detach,0,[[0.0,0.5]]], #1 vertical + [self.face_detach,0,[[0.5,0.5]]], #2 slanted + [self.face_detach,1,[[0.25,0.25],[0.5,0.5]]], #3 closed point + [self.face_detach,1,[[0.1,0.03],[0.33,0.06],[0.0,0.1]]], #4 pillow + [self.face_detach,2,[[0.0,0.5]]], #5 closed vertical + [self.face_detach,2,[[0.0,0.25],[0.25,0.25],[0.25,0.5]]], #6 stepped + [self.face_detach,1,[[0.2,0.1],[0.4,0.2],[0.0,1.0]]], #7 spikes + [self.face_detach,3,[[0.25,0.0],[0.25,0.5],[0.0,0.5]]], #8 boxed + [self.face_detach,3,[[0.25,0.5],[0.5,0.0],[0.25,-0.5]]], #9 diamond + [self.face_detach,4,[[0.5,0.0],[0.5,0.5],[0.0,0.5]]],] #10 bar + facedata = faceparams[int(self.facetype_menu)] + if not self.face_use_imported_object: + faceobject = vefm_259.facetype(basegeodesic,facedata,self.facewidth,self.faceheight,self.fwtog) + else: + if last_imported_mesh: + faceobject = vefm_259.facetype(last_imported_mesh, facedata,self.facewidth,self.faceheight,self.fwtog) + else: + message = "***ERROR***\nno imported message available\n" + "last geodesic used" + self.face_use_imported_object = False + context.scene.error_message = message + bpy.ops.object.dialog_operator('INVOKE_DEFAULT') + print("\n***ERROR*** no imported mesh available") + print("last geodesic used!") + faceobject = vefm_259.facetype(basegeodesic,facedata,\ + self.facewidth,self.faceheight,self.fwtog) + facemesh = vefm_259.mesh() + finalfill(faceobject,facemesh) + + vefm_259.vefm_add_object(facemesh) + obj = bpy.data.objects[-1] + obj.name = self.fmeshname + obj.location = (0,0,0) +#PKHG save or load (nearly) all parameters + if self.save_parameters: + self.save_parameters = False + try: + print("DBG L884") + message = "" + scriptpath = bpy.utils.script_paths()[0] + sep = os.path.sep + tmpdir = os.path.join(scriptpath,"addons", "geodesic_domes" , "tmp") +#scriptpath + sep + "addons" + sep + "geodesic_domes" + sep + "tmp" + print("tmpdirL890 = ",tmpdir) + if not os.path.isdir(tmpdir): + message += "***ERROR***\n" + tmpdir + "\nnot (yet) available\n" + print(message) + else: + filename = tmpdir + sep + "GD_0.GD" + filename_ren = tmpdir + sep + "GD_0.GD.bak" + filename_ren2 = tmpdir + sep + "GD_0.GD.2bak" + if os.path.isfile(filename_ren2): + try: + os.remove(filename_ren2) + message = "***Info***\nGD_0.GD.2bak removed\n" + except: + message = "***ERROR***\n,GD_0.GD.2bak could not be removed\n" + print(message) + if os.path.isfile(filename_ren): + try: + os.rename(filename_ren,filename_ren2) + message += "***INFO***\nGD_0.GD.bak renamed into GD_0.GD.2bak\n" + except: + message += "***Info***\nrenaming GD_0.GD.bak not possible\n" + if os.path.isfile(filename): + try: + os.rename(filename,filename_ren) + message += "***INFO***\nGD_0.GD renamed into GD_0.GD.bak\n" + except: + message += "***ERROR***\ncreation of GD_0.GD.bak not possible\n" + try: + print("DBG L921") + self.write_params(filename) + message += "***OK***\nparameters saved in\n" + filename + print(message) + except: + message = "***ERRROR***\n" + "writing " + filename + "\nnot possible" + print(message) + except: + + message += "***ERROR***\n Contakt PKHG, something wrong happened" + print(message) + + context.scene.error_message = message + bpy.ops.object.dialog_operator('INVOKE_DEFAULT') + + if self.load_parameters: + self.load_parameters = False + try: + scriptpath = bpy.utils.script_paths()[0] + sep = os.path.sep + tmpdir = os.path.join(scriptpath,"addons", "geodesic_domes" , "tmp") +#scriptpath + sep + "addons" + sep + "geodesic_domes" + sep + "tmp" + if not os.path.isdir(tmpdir): + message = "***ERROR***\n" + tmpdir + "\nnot available" + print(message) + filename = tmpdir + sep + "GD_0.GD" +# self.read_file(filename) + try: + res = self.read_file(filename) + for i,el in enumerate(self.name_list): + setattr(self,el,res[i]) + + message = "***OK***\nparameters read from\n" + filename + print(message) + + except: + message = "***ERRROR***\n" + "writing " + filename + "\nnot possible" + #bpy.context.scene.instant_filenames = filenames + + except: + message = "***ERROR***\n Contakt PKHG,\nsomething went wrong reading params happened" + context.scene.error_message = message + bpy.ops.object.dialog_operator('INVOKE_DEFAULT') + return {'FINISHED'} + + def invoke(self, context, event): + global basegeodesic + bpy.ops.view3d.snap_cursor_to_center() + tmp = context.scene.geodesic_not_yet_called + if tmp: + context.scene.geodesic_not_yet_called = False + self.execute(context) + return {'FINISHED'} + +def creategeo(polytype,orientation,parameters): + geo = None + if polytype == "Tetrahedron": + if orientation == "PointUp": + geo = geodesic_classes_259.tetrahedron(parameters) + elif orientation == "EdgeUp": + geo=geodesic_classes_259.tetraedge(parameters) + elif orientation == "FaceUp": + geo=geodesic_classes_259.tetraface(parameters) + elif polytype == "Octahedron": + if orientation == "PointUp": + geo=geodesic_classes_259.octahedron(parameters) + elif orientation == "EdgeUp": + geo=geodesic_classes_259.octaedge(parameters) + elif orientation == "FaceUp": + geo=geodesic_classes_259.octaface(parameters) + elif polytype == "Icosahedron": + if orientation == "PointUp": + geo=geodesic_classes_259.icosahedron(parameters) + elif orientation == "EdgeUp": + geo=geodesic_classes_259.icoedge(parameters) + elif orientation == "FaceUp": + geo=geodesic_classes_259.icoface(parameters) + return geo + +basegeodesic,fmeshname,smeshname,hmeshname,outputmeshname,strutimpmesh,hubimpmesh = [None]*7 + +def finalfill(source,target): + count=0 + for point in source.verts: + newvert = vefm_259.vertex(point.vector) + target.verts.append(newvert) + point.index = count + count += 1 + for facey in source.faces: + row=len(facey.vertices) + if row >= 5: + newvert = vefm_259.average(facey.vertices).centroid() + centre = vefm_259.vertex(newvert.vector) + target.verts.append(centre) + for i in range(row): + if i == row - 1: + a = target.verts[facey.vertices[-1].index] + b = target.verts[facey.vertices[0].index] + else: + a = target.verts[facey.vertices[i].index] + b = target.verts[facey.vertices[i+1].index] + c = centre + f = [a,b,c] + target.faces.append(f) + else: + f = [] + for j in range(len(facey.vertices)): + + a = facey.vertices[j] + f.append(target.verts[a.index]) + target.faces.append(f) + +###for error messages +class DialogOperator(bpy.types.Operator): + bl_idname = "object.dialog_operator" + bl_label = "INFO" + + def draw(self,context): + layout = self.layout + message = context.scene.error_message + col = layout.column() + tmp = message.split("\n") + for el in tmp: + col.label(el) + + def execute(self, context): + return {'FINISHED'} + + def invoke(self, context, event): + wm = context.window_manager + return wm.invoke_props_dialog(self) + + +######### register all +def register(): + bpy.utils.register_module(__name__) + +def unregister(): + bpy.utils.unregister_module(__name__) + +if __name__ == "__main__": + register() + diff -Nru blender-2.61/release/scripts/addons_contrib/geodesic_domes/tmp/GD_0.GD blender-2.62/release/scripts/addons_contrib/geodesic_domes/tmp/GD_0.GD --- blender-2.61/release/scripts/addons_contrib/geodesic_domes/tmp/GD_0.GD 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/geodesic_domes/tmp/GD_0.GD 2012-02-15 19:43:42.000000000 +0000 @@ -0,0 +1,115 @@ +facetype_menu,'3', +facetoggle,True, +face_use_imported_object,False, +facewidth,0.26006004214286804, +fwtog,True, +faceheight,1.0, +fhtog,False, +face_detach,False, +fmeshname,'defaultface', +geodesic_types,'Geodesic', +import_mesh_name,'None', +base_type,'Octahedron', +orientation,'EdgeUp', +geodesic_class,'Class 1', +tri_hex_star,'tri', +spherical_flat,'spherical', +use_imported_mesh,False, +cyxres,5, +cyyres,5, +cyxsz,1.0, +cyysz,1.0, +cyxell,1.0, +cygap,1.0, +cygphase,0.0, +paxres,5, +payres,5, +paxsz,0.30000001192092896, +paysz,1.0, +paxell,1.0, +pagap,1.0, +pagphase,0.0, +ures,8, +vres,8, +urad,1.0, +vrad,0.25, +uellipse,1.0, +vellipse,1.0, +upart,1.0, +vpart,1.0, +ugap,0.0, +vgap,0.0, +uphase,0.0, +vphase,0.0, +uexp,0.0, +vexp,0.0, +usuper,2.0, +vsuper,2.0, +utwist,0.0, +vtwist,0.0, +bures,8, +bvres,8, +burad,1.0, +bupart,1.0, +bvpart,1.0, +buphase,0.0, +bvphase,0.0, +buellipse,1.0, +bvellipse,1.0, +grxres,5, +gryres,2, +grxsz,2.0, +grysz,1.0, +cart,0, +frequency,2, +eccentricity,1.0, +squish,1.0, +radius,2.8912599086761475, +squareness,2.0, +squarez,2.0, +baselevel,5, +dual,False, +rotxy,0.0, +rotz,0.0, +uact,False, +vact,False, +um,3.0, +un1,1.0, +un2,1.0, +un3,1.0, +ua,1.0, +ub,4.0, +vm,1.0, +vn1,1.0, +vn2,1.0, +vn3,1.0, +va,1.0, +vb,1.0, +uturn,0.0, +vturn,0.0, +utwist,0.0, +vtwist,0.0, +struttype,0, +struttoggle,True, +strutimporttoggle,False, +strutimpmesh,'GD_mesh', +strutwidth,1.0, +swtog,False, +strutheight,1.0, +shtog,False, +strutshrink,1.0, +sstog,False, +stretch,1.0, +lift,0.0010000000474974513, +smeshname,'defaultstrut', +hubtype,True, +hubtoggle,False, +hubimporttoggle,False, +hubimpmesh,'None', +hubwidth,1.0, +hwtog,False, +hubheight,1.0, +hhtog,False, +hublength,1.0, +hstog,False, +hmeshname,'None', diff -Nru blender-2.61/release/scripts/addons_contrib/geodesic_domes/tmp/GD_start.GD blender-2.62/release/scripts/addons_contrib/geodesic_domes/tmp/GD_start.GD --- blender-2.61/release/scripts/addons_contrib/geodesic_domes/tmp/GD_start.GD 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/geodesic_domes/tmp/GD_start.GD 2012-02-15 19:43:42.000000000 +0000 @@ -0,0 +1,115 @@ +facetype_menu,'0', +facetoggle,False, +face_use_imported_object,False, +facewidth,0.5, +fwtog,False, +faceheight,1.0, +fhtog,False, +face_detach,False, +fmeshname,'defaultface', +geodesic_types,'Geodesic', +import_mesh_name,'None', +base_type,'Tetrahedron', +orientation,'PointUp', +geodesic_class,'Class 1', +tri_hex_star,'tri', +spherical_flat,'spherical', +use_imported_mesh,False, +cyxres,5, +cyyres,5, +cyxsz,1.0, +cyysz,1.0, +cyxell,1.0, +cygap,1.0, +cygphase,0.0, +paxres,5, +payres,5, +paxsz,0.30000001192092896, +paysz,1.0, +paxell,1.0, +pagap,1.0, +pagphase,0.0, +ures,8, +vres,8, +urad,1.0, +vrad,0.25, +uellipse,1.0, +vellipse,1.0, +upart,1.0, +vpart,1.0, +ugap,0.0, +vgap,0.0, +uphase,0.0, +vphase,0.0, +uexp,0.0, +vexp,0.0, +usuper,2.0, +vsuper,2.0, +utwist,0.0, +vtwist,0.0, +bures,8, +bvres,8, +burad,1.0, +bupart,1.0, +bvpart,1.0, +buphase,0.0, +bvphase,0.0, +buellipse,1.0, +bvellipse,1.0, +grxres,5, +gryres,2, +grxsz,2.0, +grysz,1.0, +cart,0, +frequency,1, +eccentricity,1.0, +squish,1.0, +radius,1.0, +squareness,2.0, +squarez,2.0, +baselevel,5, +dual,False, +rotxy,0.0, +rotz,0.0, +uact,False, +vact,False, +um,3.0, +un1,1.0, +un2,1.0, +un3,1.0, +ua,1.0, +ub,4.0, +vm,1.0, +vn1,1.0, +vn2,1.0, +vn3,1.0, +va,1.0, +vb,1.0, +uturn,0.0, +vturn,0.0, +utwist,0.0, +vtwist,0.0, +struttype,0, +struttoggle,False, +strutimporttoggle,False, +strutimpmesh,'None', +strutwidth,1.0, +swtog,False, +strutheight,1.0, +shtog,False, +strutshrink,1.0, +sstog,False, +stretch,1.0, +lift,0.0, +smeshname,'defaultstrut', +hubtype,True, +hubtoggle,False, +hubimporttoggle,False, +hubimpmesh,'None', +hubwidth,1.0, +hwtog,False, +hubheight,1.0, +hhtog,False, +hublength,1.0, +hstog,False, +hmeshname,'None', diff -Nru blender-2.61/release/scripts/addons_contrib/geodesic_domes/vefm_259.py blender-2.62/release/scripts/addons_contrib/geodesic_domes/vefm_259.py --- blender-2.61/release/scripts/addons_contrib/geodesic_domes/vefm_259.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/geodesic_domes/vefm_259.py 2012-02-15 19:43:43.000000000 +0000 @@ -0,0 +1,1217 @@ +# vert class and overloading experiments +import bpy +import math +from math import sqrt,acos,pi,sin,cos,atan,tan,fabs +from mathutils import Vector + +#dbg = True +sgn = lambda x : (x>0) - (x<0) #missing signum functin in Python +try: + breakpoint = bpy.types.bp.bp +except: + pass + +from add_utils import AddObjectHelper, add_object_data +from collections import Counter + +'''PKHG not needed? +def find_twice_vert(l1,l2): + tmp = [el for el in l1] + tmp.extend(l2) + tt = Counter(tmp) + result = max(tt.keys(),key = lambda k:tt[k]) + print("twice give", result) + return result +''' + +def vefm_add_object(selfobj): + for i in range(len(selfobj.verts)): + selfobj.verts[i].index = i + v = [el.vector for el in selfobj.verts] +# e = [[edge.a.index,edge.b.index] for edge in selfobj.edges] + e = [] + if type(selfobj.faces[0]) == type([]): +# print("\n=========== selfobj.faces[0]", selfobj.faces[0],type(selfobj.faces[0])) +#PKHG should be a list of vertices, which have an index + f = [[v.index for v in face] for face in selfobj.faces] + else: + f = [[v.index for v in face.vertices] for face in selfobj.faces] +#PKHG_DBG_25-11 print("dbg 25-11 f list =",f) +#PKHG_DBG_25-11 print("dgb 25-11 v list +",v) + m = bpy.data.meshes.new(name= selfobj.name) + m.from_pydata(v, e, f ) + # useful for development when the mesh may be invalid. + m.validate(verbose = False) + add_object_data(bpy.context, m, operator = None) +#???ERROR PKHG in AddSelf setMaterial(bpy.context.active_object,pkhg_red_color) + +#extra test phase + + + + +class vertex: + + def __init__(self,vec=(0,0,0)): #default x = 0,y = 0,z = 0): + self.vector = Vector(vec) + self.length = self.vector.length + self.index = 0 + self.normal = 0 + self.edges = [] + self.faces = [] + self.boundary = 0 + + def findlength(self): + self.length = self.vector.length + + def normalize(self): + self.findlength() + if self.length > 0: + tmp = 1.0/self.length + self.vector = tmp * self.vector +# self.x = self.vector[0] #(1.0/self.length) +# self.y = self.vector[1] #(1.0/self.length) +# self.z = self.vector[2] #(1.0/self.length) + self.length = 1.0 + + def findnormal(self): + target = [] + if self.faces[:] == []: + print("vefm vertex L81 pkhg:*****ERROR**** findnormal has no faces") + return + for currentface in self.faces: + target.append(currentface.normal) + self.normal = average(target).centroid() + self.normal.findlength() + if self.length == 0: + print("******ERROR*** lenght zero in findnormal, j = (0,1,0) replcaced") + self.normal = vertex((0,1,0)) + self.normal.normalize() + + def clockwise(self): #PKHG self is a vertex + if self.boundary: + start = self.boundarystart() #???PKHG TODO error + else: + start = self.faces[0] +#PKHG TODO do understand 21-11 solves starify of a normal tetrahedron +# start = self.faces[0] #PKHG TODO see error above! +# start.docorners() #PKHG???? + self.tempedges = [] + self.tempfaces = [] + for i in range(len(self.edges)): + #print("\n----------------------voor breakpunt pkhg in clockwise") + #breakpoint(locals(), self.index == 0) + self.tempfaces.append(start) + for corner in start.corners: + if corner[0] is not self: + pass + elif corner[0] is self: + self.tempedges.append(corner[1]) + nextedge = corner[2] + for facey in nextedge.faces: + if facey is not start: + start = facey + break + self.edges = self.tempedges + self.faces = self.tempfaces + + def boundarystart(self): + #PKHG not implemented, needed? + pass + +#???PKHG TODO why are add and sub different? Solved check the two cases used + def __add__(self,other): + if "" == str(type(other)): + tmp = self.vector + other + else: + tmp = self.vector + other.vector + return vertex(tmp) + + def __sub__(self,other): + if "" == str(type(other)): + tmp = self.vector - other + else: + tmp = self.vector - other.vector +# tmp = self.vector - other.vector + return vertex(tmp) + + def __mul__(self,other): + tmp = self.vector * other + return vertex(tmp) + + def __truediv__(self,other): + denom = 1.0/other + tmp = self.vector * denom + return (tmp) + + def negative(self): + return vertex(-self.vector) + +class crossp: + ## Takes in two vertices(vectors), returns the cross product. + def __init__(self,v1,v2): + self.v1 = v1 + self.v2 = v2 +# + def docrossproduct(self): + tmp = self.v1.vector.cross(self.v2.vector) + return vertex(tmp) + +class average: + ## Takes a list of vertices and returns the average. If two verts are passed, returns midpoint. + def __init__(self,vertlist): + self.vertlist = vertlist + + def centroid(self): + tmp = Vector() +#PKHG avoid emptylist problems + divisor = 1.0 + nr_vertices = len(self.vertlist) + if nr_vertices > 1: + divisor = 1.0 / len(self.vertlist) + elif nr_vertices == 0: + print("\n***WARNING*** empty list in vefm_259.centroid! L180") + for vert in self.vertlist: + tmp = tmp + vert.vector + tmp = tmp * divisor + return vertex(tmp) + +class edge: + def __init__(self,a = 0,b = 0): + self.a = a + self.b = b + self.index = 0 + self.normal = 0 + self.cross = 0 + self.unit = 0 + self.faces = [] + self.vect = 0 #PKHG becomes b - a + self.vectb = 0 #PKHG becomes a - b +# self.length = 0 + self.boundary = 0 + self.findvect() +# print("vect len before",self.vect.length) + self.findlength() +# print("vect after",self.vect.length) + + def findvect(self): + self.vect = self.b - self.a + self.vectb = self.a - self.b + + def findlength(self): + self.vect.findlength() + self.vectb.length = self.vect.length + + def findnormal(self): + + if self.boundary: + self.normal = self.faces[0].normal #average([self.a,self.b]).centroid() + else: + self.normal = average([self.faces[0].normal,self.faces[1].normal]).centroid() + self.normal.normalize() +# def findother(self,vertindex): +# +# if vertindex==self.a: +# +# return self.b +# +# else: +# return self.a +## different classes for 3,4,> sides?? + +class face: + def __init__(self,vertices=[]): +#PKHG ok good for tri's at least print("\n ========= vefm L226======dbg face vertices = ",vertices) + self.vertices = vertices ## List of vertex instances. + self.edges=[] ## Will be filled with the sides of the face. + self.boundary = 0 ## When set will have bool and id of edge concerned. + self.normal = 0 ## Face normal found through cross product. + self.corners=[] + self.spokes=[] ## Vectors of the bisecting angles from each corner to the centre + dotproduct. + self.index = 0 + + #dotproduct is misleading name, it is the hook between two vectors! + def dotproduct(self,v1,v2): + v1.findlength() + v2.findlength() + if v1.length == 0 or v2.length == 0: + print("\nPKHG warning, =====vefm_259 dotproduct L245====== at least one zero vector 0 used") + return 0 # pi * 0.25 #PKHT_TEST04nov pi * 0.25 #45 degrees??? #PKHG???TODO + dot = v1.vector.dot(v2.vector) + costheta = dot / (v1.length * v2.length) + tmp = acos(costheta) + return tmp + + def orderedges(self): + temp=[] + finish = len(self.vertices) + for i in range(finish): + current = self.vertices[i] + if i==finish-1: + next = self.vertices[0] + else: + next = self.vertices[i+1] + for edge in face.edges: + if edge.a==current and edge.b==next: + face.clockw.append(edge.vect) + face.aclockw.append(edge.vectb) + temp.append(edge) + if edge.b==current and edge.a==next: + face.clockw.append(edge.vectb) + face.aclockw.append(edge.vect) + temp.append(edge) + for edge in face.edges: + if edge.a==current and edge.b==next: + face.clockw.append(edge.vect) + face.aclockw.append(edge.vectb) + temp.append(edge) + if edge.b==current and edge.a==next: + face.clockw.append(edge.vectb) + face.aclockw.append(edge.vect) + temp.append(edge) + face.vertices = temp + + + def docorners(self): + ## This function identifies and stores the vectors coming from each vertex + ## allowing easier calculation of cross and dot products. + finish = len(self.vertices) + ''' + which = None + occur1 = None + occur2 = None + if finish == 3 and len(self.edges) == 2 : + print("\n***ERROR*** only two edges should be three") + # return + occur1 = [self.vertices.index(self.edges[0].a),self.vertices.index(self.edges[0].b)] + occur2 = [self.vertices.index(self.edges[1].a),self.vertices.index(self.edges[1].b)] + #occur2 = [self.edges[1].a.index, self.edges[1].b.index] + twice = find_twice_vert(occur1,occur2) + occur1.remove(twice) + occur2.remove(twice) + #new_edge = edge(self.vertices[occur1[0]],self.vertices[occur2[0]]) + #self.edges.append(new_edge) + ''' + for i in range(finish): + current = self.vertices[i] + if i==finish-1: + next = self.vertices[0] + else: + next = self.vertices[i+1] + if i==0: + previous = self.vertices[-1] + else: + previous = self.vertices[i-1] + corner=[current] #PKHG new for each vertex = current + #corner = current + rightedge = None + leftedge = None + teller = -1 + for edge in self.edges: + # if finish == 3 and len(self.edges) == 2 and i == 2: + # return + teller += 1 + currentinfo = (current, edge.a, edge.b, edge.a is current, edge.b is current) + #next and previous are vertex with respect to ith vertex + if edge.a is current or edge.b is current: ## does this edge contain our current vert + if edge.a is current: + if edge.b is next: + rightedge = edge + rightvect = edge.vect + if edge.b is previous: + leftedge = edge + leftvect = edge.vect + elif edge.b is current: + if edge.a is next: + rightedge = edge + rightvect = edge.vectb + if edge.a is previous: + leftedge = edge + leftvect = edge.vectb + corner.append(rightedge) + corner.append(leftedge) + if rightedge and leftedge: + ''' + if rightedge: + print("rightedge",rightedge.index) + if leftedge: + print( "leftedge",leftedge.index) + print("corner",corner) + #''' + dotty = self.dotproduct(rightvect,leftvect) + corner.append(dotty) + self.corners.append(corner) + + + def findnormal(self): + one = self.corners[1][2] + two = self.corners[1][1] + if one.a is self.corners[1][0]: + one = one.vect + elif one.b is self.corners[1][0]: + one = one.vectb + if two.a is self.corners[1][0]: + two = two.vect + elif two.b is self.corners[1][0]: + two = two.vectb + self.normal = crossp(one,two).docrossproduct() + self.normal.findlength() + self.normal.normalize() + + def dospokes(self): +#PKHG_OK_24-11 print("\n============vefm L375==============dbg, dospokes called corners =", self.corners[:]) + for corner in self.corners: + vert = corner[0] + right = corner[1] + left = corner[2] + if right.a is vert: + one = vertex(right.vect.vector) + elif right.b is vert: + one = vertex(right.vectb.vector) + if left.a is vert: + two = vertex(left.vect.vector) + elif left.b is vert: + two = vertex(left.vectb.vector) + + one.normalize() + two.normalize() + spoke = one+two + spoke.normalize() + self.spokes.append(spoke) + + def artspokes(self): + centre = average(self.vertices).centroid() + for point in self.vertices: + newedge = edge(point,centre) + spokes.append(newedge) + +class mesh: + def __init__(self , name="GD_mesh"): + self.name = name #pkhg test phase at least ;-) + self.verts=[] + self.edges=[] + self.faces=[] + self.edgeflag = 0 + self.faceflag = 0 + self.vertexflag = 0 + self.vertedgeflag = 0 + self.vertfaceflag = 0 + self.faceedgeflag = 0 + self.boundaryflag = 0 + self.vertnormalflag = 0 + self.edgenormalflag = 0 + self.facenormalflag = 0 + #found in geodesic.py ??? needed for test here! + self.a45 = pi * 0.25 + self.a90 = pi * 0.5 + self.a180 = pi + self.a270 = pi * 1.5 + self.a360 = pi * 2 + + + def power(self,a,b): ## Returns a power, including negative numbers + result = sgn(a)*(abs(a)**b) + return result + + def sign(self,d): ## Works out the sign of a number. + return sgn(d) + + def ellipsecomp(self,efactor,theta): + if theta==self.a90: + result = self.a90 + elif theta==self.a180: + result = self.a180 + elif theta==self.a270: + result = self.a270 + elif theta==self.a360: + result = 0.0 + else: + result = atan(tan(theta)/efactor**0.5) + if result<0.0: + if theta>self.a180: + result = result+self.a180 + elif theta0.0: + if theta>self.a180: + result = result+self.a180 + elif theta dovertedge, dovertface, dofaceedge, boundary() + self.connectivity() + hexvert_counter = 0 + for edge in self.edges: +# print("21-11 >>>>>>>>>>>>>>dbg hexify L552") +# breakpoint(locals(),True) + self.hexshorten(edge,hexvert_counter) + hexvert_counter += 2 #PKHG two new vertices done +#PKHG 21-11 print("21-11 <<<<<<<<<<<<<<< na hexshorten L557", hexvert_counter) +#PKHG 21-11 breakpoint(locals(),True) + + for face in self.faces: + self.makehexfaces(face) + + for vert in self.verts: + vert.clockwise() + self.hexvertface(vert) + self.verts = self.hexverts + self.edges = self.hexedges + self.faces = self.hexfaces + self.vertedgeflag = 0 + self.vertfaceflag = 0 + self.faceedgeflag = 0 +#PKHG_DBG print("\n ==========================self hexified I hope") + #breakpoint(locals(),True) + + def hexshorten(self,currentedge, hexvert_counter): + third = vertex(currentedge.vect/3.0) + newvert1 = vertex(currentedge.a.vector) + newvert2 = vertex(currentedge.b.vector) + newvert1 = newvert1 + third + newvert1.index = hexvert_counter + newvert2 = newvert2 - third + newvert2.index = hexvert_counter + 1 #PKHG caller adjusts +=2 + newedge = edge(newvert1,newvert2) + newedge.index = currentedge.index + self.hexverts.append(newvert1) + self.hexverts.append(newvert2) + self.hexedges.append(newedge) + + def makehexfaces(self,currentface): + vertices=[] + currentface.docorners() + for corner in currentface.corners: + vert = corner[0] + rightedge = corner[1] + leftedge = corner[2] + lid = leftedge.index + rid = rightedge.index + + if leftedge.a is vert: + vertices.append(self.hexedges[lid].a) + elif leftedge.b is vert: + vertices.append(self.hexedges[lid].b) + + if rightedge.a is vert: + vertices.append(self.hexedges[rid].a) + elif rightedge.b is vert: + vertices.append(self.hexedges[rid].b) + + newface = face(vertices) + newedge1 = edge(vertices[0],vertices[1]) + newedge2 = edge(vertices[2],vertices[3]) + newedge3 = edge(vertices[4],vertices[5]) + self.hexfaces.append(newface) + self.hexedges.append(newedge1) + self.hexedges.append(newedge2) + self.hexedges.append(newedge3) + + def hexvertface(self,vert): + vertices=[] + for edge in vert.edges: + eid = edge.index + if edge.a is vert: + vertices.append(self.hexedges[eid].a) + elif edge.b is vert: + vertices.append(self.hexedges[eid].b) + newface = face(vertices) + self.hexfaces.append(newface) + + def starify(self): + self.starverts=[] + self.staredges=[] + self.starfaces=[] + for i in range(len(self.verts)): + self.verts[i].index = i + for i in range(len(self.edges)): + self.edges[i].index = i + self.connectivity() + star_vert_counter = 0 + for currentedge in self.edges: + newvert = average([currentedge.a,currentedge.b]).centroid() + newvert.index = star_vert_counter + star_vert_counter += 1 + self.starverts.append(newvert) + star_face_counter = 0 + star_edge_counter = 0 + for currentface in self.faces: + currentface.docorners() + vertices=[] + for corner in currentface.corners: + vert = self.starverts[corner[1].index] +# vert.index = star_vert_counter +# star_vert_counter += 1 + vertices.append(vert) + newface = face(vertices) + newface.index = star_face_counter + star_face_counter += 1 + newedge1 = edge(vertices[0],vertices[1]) + newedge1.index = star_edge_counter + newedge2 = edge(vertices[1],vertices[2]) + newedge2.index = star_edge_counter + 1 + newedge3 = edge(vertices[2],vertices[0]) + newedge3.index = star_edge_counter + 2 + star_edge_counter += 3 + self.starfaces.append(newface) + self.staredges.append(newedge1) + self.staredges.append(newedge2) + self.staredges.append(newedge3) + for vert in self.verts: + vertices=[] + vert.clockwise() + for currentedge in vert.edges: + eid = currentedge.index + vertices.append(self.starverts[eid]) + newface = face(vertices) + newface.index = star_face_counter + star_face_counter += 1 + self.starfaces.append(newface) + self.verts = self.starverts + self.edges = self.staredges + self.faces = self.starfaces + self.vertedgeflag = 0 + self.vertfaceflag = 0 + self.faceedgeflag = 0 + + def class2(self): + self.class2verts=[] #PKHG_??? used? + self.class2edges=[] #PKHG_??? used? + self.class2faces=[] + + newvertstart = len(self.verts) + newedgestart = len(self.edges) + counter_verts = len(self.verts) #PKHG +# for i in range(len(self.verts)): + for i in range(counter_verts): + self.verts[i].index = i + for i in range(len(self.edges)): + self.edges[i].index = i + for i in range(len(self.faces)): + self.faces[i].index = i + self.connectivity() + for currentface in self.faces: + currentface.docorners() + newvert = average(currentface.vertices).centroid() + newvert.index = counter_verts +#PKHG_??? 20-11 + counter_verts += 1 + self.verts.append(newvert) + newedge1 = edge(currentface.vertices[0],newvert) + newedge2 = edge(currentface.vertices[1],newvert) + newedge3 = edge(currentface.vertices[2],newvert) + self.edges.append(newedge1) + self.edges.append(newedge2) + self.edges.append(newedge3) + for currentedge in range(newedgestart): + self.edges[currentedge].a = self.verts[self.edges[currentedge].faces[0].index+newvertstart] + self.edges[currentedge].b = self.verts[self.edges[currentedge].faces[1].index+newvertstart] + self.edges[currentedge].findvect() + #breakpoint(locals(),True) + for currentvert in range(newvertstart): + vert = self.verts[currentvert] + vertices=[] + vert.clockwise() + for currentface in vert.faces: + eid = currentface.index +#PKHG_OK print(">>>>eid = ", eid,newvertstart + eid) + vertices.append(self.verts[newvertstart + eid]) + #print("21-11 L710 currentvert is=", currentvert) + #breakpoint(locals(),True) + for i in range(len(vertices)): + if i == len(vertices) - 1: + next = vertices[0] + else: + next = vertices[i+1] + #print("21-11 L710 i is=", i) + #breakpoint(locals(),True) + newface = face([vert,vertices[i],next]) + self.class2faces.append(newface) + #self.verts = self.class2verts + #self.edges = self.class2edges + self.faces = self.class2faces + self.vertedgeflag = 0 + self.vertfaceflag = 0 + self.faceedgeflag = 0 + + def dual(self): + self.dualverts=[] +# self.dualedges=[] + self.dualfaces=[] +#PKHG 21-11 dual problem?! + counter_verts = len(self.verts) + for i in range(counter_verts): + self.verts[i].index = i + for i in range(len(self.edges)): + self.edges[i].index = i + for i in range(len(self.faces)): + self.faces[i].index = i + self.connectivity() + counter_verts = 0 + for currentface in self.faces: + currentface.docorners() + newvert = average(currentface.vertices).centroid() + newvert.index = counter_verts #PKHG needed in >= 2.59 + counter_verts += 1 + self.dualverts.append(newvert) + for vert in self.verts: + vertices=[] + vert.clockwise() + for currentface in vert.faces: + eid = currentface.index + vertices.append(self.dualverts[eid]) + newface = face(vertices) + self.dualfaces.append(newface) + for currentedge in self.edges: + currentedge.a = self.dualverts[currentedge.faces[0].index] + currentedge.b = self.dualverts[currentedge.faces[1].index] + self.verts = self.dualverts +# self.edges = self.staredges + self.faces = self.dualfaces + self.vertedgeflag = 0 + self.vertfaceflag = 0 + self.faceedgeflag = 0 + +class facetype(mesh): + def __init__(self,basegeodesic,parameters,width,height,relative): + mesh.__init__(self) + self.detatch = parameters[0] + self.endtype = parameters[1] + self.coords = parameters[2] + self.base = basegeodesic + self.relative = relative + self.width = width + + if not self.relative: + newwidth = self.findrelative() + self.width = width*newwidth + self.height = height + self.base.connectivity() + for coord in self.coords: + coord[0]=coord[0]*self.width + coord[1]=coord[1]*self.height + if not self.base.facenormalflag: + for currentface in self.base.faces: + # print("face normal ",currentface.normal) + currentface.docorners() + currentface.findnormal() + # print("face normal ",currentface.normal.x,currentface.normal.y,currentface.normal.z) + self.base.facenormalflag = 1 + if self.endtype==4 and not self.base.vertnormalflag: + for currentvert in self.base.verts: + currentvert.findnormal() + self.base.vertnormalflag = 1 + self.createfaces() + + def findrelative(self): + centre = average(self.base.faces[0].vertices).centroid() + edgelist=[] + for point in self.base.faces[0].vertices: + newedge = edge(centre,point) + edgelist.append(newedge) + length = 0 + for edg in edgelist: + extra = edg.vect.length + length = length+extra + # print("length",length,"extra",extra) + length = length/len(edgelist) + # print("find relative",length) + return length + + def createfaces(self): + if not self.detatch: + for point in self.base.verts: + self.verts.append(point) + if self.endtype==4: + self.createghostverts() + for currentface in self.base.faces: + self.doface(currentface) + + def createghostverts(self): + self.ghoststart = len(self.verts) + for vert in self.base.verts: + newvert = vert + (vert.normal * self.coords[-1][1]) + self.verts.append(newvert) + + def doface(self,candidate): + grid=[] + candidate.dospokes() + # print("Candidate normal",candidate.normal.x,candidate.normal.y,candidate.normal.z) + if not self.detatch: + line=[] + for vert in candidate.vertices: + line.append(vert) + grid.append(line) + else: + line=[] + for point in candidate.vertices: + newvert = vertex(point.vector) + self.verts.append(newvert) + line.append(newvert) + grid.append(line) + finish = len(self.coords) + if self.endtype==1 or self.endtype==4: + finish = finish-1 + for i in range(finish): + up = candidate.normal*self.coords[i][1] + line=[] + for j in range(len(candidate.vertices)): + dotfac = candidate.corners[j][3]*0.5 + vec=(candidate.spokes[j]*(self.coords[i][0]/sin(dotfac))) #self.coords[i][0])#(self.coords[i][0]/sin(dotfac)))#+up + newvert = candidate.vertices[j]+vec+up + line.append(newvert) + self.verts.append(newvert) + grid.append(line) + if self.endtype==4: + line=[] + for i in range(len(candidate.vertices)): + vert = self.verts[candidate.vertices[i].index+self.ghoststart] + line.append(vert) + # self.verts.append(vert) + grid.append(line) + for line in grid: + line.append(line[0]) + if self.endtype==3: + grid.append(grid[0]) + for i in range(len(grid)-1): + for j in range(len(grid[i])-1): + one = grid[i][j] + two = grid[i][j+1] + three = grid[i+1][j+1] + four = grid[i+1][j] + newface = face([one, two, three, four]) + self.faces.append(newface) + if self.endtype==2: + finalfaceverts = grid[-1] + newface = face(finalfaceverts[:-1]) + self.faces.append(newface) + if self.endtype==1: + lastvert = average(candidate.vertices).centroid() + up = candidate.normal*self.coords[-1][1] + newvert = lastvert+up + self.verts.append(newvert) + ring = grid[-1] + for i in range(len(ring)-1): + newface = face([newvert,ring[i],ring[i+1]]) + self.faces.append(newface) + +class importmesh(mesh): + def __init__(self,meshname,breakquadflag): + mesh.__init__(self) +# print("mesh and breakquad",meshname,breakquadflag) +# impmesh = NMesh.GetRawFromObject(meshname) + impmesh = bpy.data.objects[meshname] + copied_mesh = None + if breakquadflag: + name = impmesh.name +#PKHG???needed???NO 3-11-2011 impmesh.name = "Original_" + name + impmesh.name = name +#PKHG TODO use a copy? no not necessary bpy.ops.object.duplicate_move(OBJECT_OT_duplicate={"linked":False, "mode":'TRANSLATION'}, TRANSFORM_OT_translate={"value":(0, 0,0})) +#PKHG TODO use a copy? copied_mesh = bpy.context.active_object + bpy.ops.object.mode_set(mode='EDIT') + bpy.ops.mesh.quads_convert_to_tris() + bpy.ops.object.mode_set(mode='OBJECT') + + for v in impmesh.data.vertices: + vert = vertex(v.co) + vert.index = v.index + self.verts.append(vert) +#PKHG verts is now a list of vertex, so to say a copy of the Vectors + +#PKHG edges + for e in impmesh.data.edges: + tmp = [] + for vert in e.vertices: + a = self.verts[vert] + tmp.append(a) + newedge = edge(tmp[0],tmp[1]) + newedge.index = e.index + self.edges.append(newedge) +#PKHG faces + for f in impmesh.data.faces: + temp=[] + for vert in f.vertices: #PKHG a list! of indices + a = self.verts[vert] #PKHG verts contains already vertex objects + temp.append(a) + newface = face(temp) + newface.index = f.index #indexcount + self.faces.append(newface) + self.dovertedge() + self.dovertface() + self.temp=[] + + for i in range(len(self.verts)): + self.temp.append([]) + self.verts[i].index = i + for i in range(len(self.verts)): + target = self.surroundingverts(self.verts[i]) + for j in range(len(target)): ## go through those verts + temptarg = self.temp[target[j].index] + flag = 0 ## set a flag up + + for k in range(len(temptarg)): ## go through temp list for each of those verts + + if temptarg[k]==i: ## if we find a match to the current vert... + flag = 1 ## raise the flag + + if flag==0: ## if there is no flag after all that... + self.temp[target[j].index].append(i) ## add current vert to temp list of this surrounding vert + self.temp[i].append(target[j].index) ## add this surrounding vert to the current temp list + newedge = edge(self.verts[i],self.verts[target[j].index]) + self.edges.append(newedge) ## add the newly found edge to the edges list + + for edg in self.edges: + edg.findvect() + self.vertedgeflag = 0 + self.vertedgeflag = 0 + self.connectivity() +#PKHG_DBG_OK print("\n======= mesh imported") + + def surroundingverts(self,vert): + ''' Find the verts surrounding vert''' + surround=[] ## list to be filled and returned + for faces in vert.faces: ## loop through faces attached to vert + finish = len(faces.vertices) + for i in range(finish): + if i==finish-1: + next = faces.vertices[0] + else: + next = faces.vertices[i+1] + if vert == faces.vertices[i]: + surround.append(next) + return surround + + def breakquad(self,quad_face): + ''' turn quads into triangles''' + distance1 = quad_face.vertices[0]-quad_face.vertices[2] + distance2 = quad_face.vertices[1]-quad_face.vertices[3] + distance1.findlength() + distance2.findlength() + if abs(distance1.length)maxx: + if vert.vector.x > maxx: +# maxx = vert.x + maxx = vert.vector.x +# if vert.x 0.0: + if point.vector.x > 0.0: +# be = edj.unit * self.shrink * (point.x + diffplus) + be = edj.unit * self.shrink * (point.vector.x + diffplus) +# elif point.x < 0.0: + elif point.vector.x < 0.0: +# be = edj.unit * self.shrink * (point.x + diffminus) + be = edj.unit * self.shrink * (point.vector.x + diffminus) +# elif point.x == 0.0: + elif point.vector.x == 0.0: +# be = edj.unit * self.shrink * point.x + be = edj.unit * self.shrink * point.vector.x + de = ay + be + ce + newvert = centre + de + self.verts.append(newvert) + for edjy in template.edges: + one = edjy.a.index+start + two = edjy.b.index+start + newedge = edge(self.verts[one],self.verts[two]) + self.edges.append(newedge) + for facey in template.faces: + faceverts=[] + for verty in facey.vertices: + index = verty.index+start + faceverts.append(self.verts[index]) + newface = face(faceverts) + self.faces.append(newface) + self.vertedgeflag = 0 + self.vertedgeflag = 0 + self.connectivity() + +class hub(mesh): + def __init__(self,base,hubtype,width,height,length,widthtog,heighttog,lengthtog,meshname): + mesh.__init__(self) + self.width = 1.0 + self.height = 1.0 + self.shrink = 1.0 + ## put in strut prep stuff here + if hubtype==None: + return + total = 0 + divvy = len(base.faces[0].edges) + for lengf in base.verts[0].edges: + lengf.vect.findlength() + total = total+lengf.vect.length + yardstick = total / divvy + if widthtog: + self.width = width + else: + self.width = width * yardstick + if heighttog: + self.height = height + else: + self.height = height * yardstick + if lengthtog: + self.shrink = length + else: + self.shrink = length * yardstick + + if not base.facenormalflag: + for currentface in base.faces: + currentface.docorners() + currentface.findnormal() + base.facenormalflag = 1 +#PKHG_2411 breakpoint(locals(),True) #PKHG_DBG 24-11 reason ERROR**** findnormal has no faces + + + for apex in base.verts: + apex.findnormal() + side = edge(apex.edges[0].a,apex.edges[0].b) + apex.unit = side.vect #PKHG is Vector: b -a + apex.unit.normalize() + apex.cross = crossp(apex.normal,apex.unit).docrossproduct() + apex.unit = crossp(apex.cross,apex.normal).docrossproduct() + + template = importmesh(meshname,0) + for apex in base.verts: + start = len(self.verts) + centre = apex + for point in template.verts: + ay = apex.normal * point.vector.z * self.height + ce = apex.cross * point.vector.y * self.width + be = apex.unit * point.vector.x * self.shrink + de = ay+be+ce + newvert = centre+de + self.verts.append(newvert) + for edjy in template.edges: + one = edjy.a.index+start + two = edjy.b.index+start + newedge = edge(self.verts[one],self.verts[two]) + self.edges.append(newedge) + for facey in template.faces: + faceverts=[] + for verty in facey.vertices: + index = verty.index+start + faceverts.append(self.verts[index]) + newface = face(faceverts) + self.faces.append(newface) + self.vertedgeflag = 0 + self.vertedgeflag = 0 + self.connectivity() + +#???PKHG TODO Nmesh used yet wrong! +def finalfill(source,target): + if source == target: #PKHG: otherewise >infinite< loop + print("\n***WARNING*** vefm_259.finalfill L1148 source == target empty mesh used") + target = mesh() # +#PKHG_??? maybe renumverting and checkkin faces wiht >=4 5 vertices? + count = 0 +#PKHG_OK print("\n>>>>>>>>20-11 DBG vefm_259 in finalfill L1152, len(source.verts) =",len(source.verts)) + for point in source.verts: +# newvert = NMesh.Vert(point.x,point.y,point.z) + newvert = vertex(point.vector) +#PKHG_??? needed??? + newvert.index = count + target.verts.append(newvert) + point.index = count #PKHG_INFO source renumbered too! +#PKHG_OK print("test gelijk",newvert.vector == point.vector) + count += 1 #count+1 + + #PKHG indices of the vertex in faceyvertices are renumbered! +#PKHG_OK print("\n>>>>>>>>20-11 DBG vefm_259 in finalfill L1163, len(source.faces) =",len(source.faces)) + for facey in source.faces: + row = len(facey.vertices) + if row >= 5: +#PKHG does not take the good vectors??? newvert = average(facey.vertices).centroid() + tmp = Vector() + for el in facey.vertices: + tmp = tmp + target.verts[el.index].vector + tmp = tmp / row + centre = vertex(tmp) #does not work here!==> average(facey.vertices).centroid() + centre.index = count #PKHG_??? give it a good index + count += 1 +#PKHG_DBG 21-11 + #breakpoint(locals(),True) + + target.verts.append(centre) + for i in range(row): + if i == row - 1: + a = target.verts[facey.vertices[-1].index] + b = target.verts[facey.vertices[0].index] + else: + a = target.verts[facey.vertices[i].index] + b = target.verts[facey.vertices[i+1].index] + target.faces.append([a,b,centre]) + else: + f = [] +#PKHG_DBG 21-11 +# print("\n-----++++ L1217 dbg final dual", facey ) +#PKHG_DBG 21-11 +# breakpoint(locals(),True) + + for j in range(len(facey.vertices)): + a = facey.vertices[j] +#PKHG_NOTNEEDED tmp = a.index + f.append(target.verts[a.index]) + target.faces.append(f) + diff -Nru blender-2.61/release/scripts/addons_contrib/gpencil_retopo/__init__.py blender-2.62/release/scripts/addons_contrib/gpencil_retopo/__init__.py --- blender-2.61/release/scripts/addons_contrib/gpencil_retopo/__init__.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/gpencil_retopo/__init__.py 2012-02-15 19:43:58.000000000 +0000 @@ -24,7 +24,6 @@ "author": "Campbell Barton, Bart Crouch", "version": (1, 0, 0), "blender": (2, 5, 7), - "api": 36007, "location": "View3D > Properties > Grease Pencil", "warning": "", "description": "Use Grease Pencil to retopologise a mesh.", diff -Nru blender-2.61/release/scripts/addons_contrib/gyes/__init__.py blender-2.62/release/scripts/addons_contrib/gyes/__init__.py --- blender-2.61/release/scripts/addons_contrib/gyes/__init__.py 2011-12-13 19:59:41.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/gyes/__init__.py 2012-02-15 19:43:58.000000000 +0000 @@ -25,7 +25,6 @@ "author": "Kilon", "version": (1, 0, 0), "blender": (2, 6, 0), - "api": 40500, "location": "View3D > Left panel ", "warning": '', # used for warning icon and text in addons panel "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/System/Gyes", diff -Nru blender-2.61/release/scripts/addons_contrib/gyes/random_material_generator.py blender-2.62/release/scripts/addons_contrib/gyes/random_material_generator.py --- blender-2.61/release/scripts/addons_contrib/gyes/random_material_generator.py 2011-12-13 19:59:41.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/gyes/random_material_generator.py 2012-02-15 19:43:58.000000000 +0000 @@ -66,7 +66,7 @@ if hasattr(bpy.context.scene , "historybak")==False: bpy.types.Scene.historybak = StringProperty() - print("created history backup") + print("Gyes log : created history backup") # non read only material properties where keyframes can be inserted or removed self.animated_properties=["alpha", @@ -231,7 +231,7 @@ history_index = scn.history_index h_name = scn.h_selected self.rm_history[h_name][history_index]={"name" : mat.name} - print("mat stored : "+self.rm_history[h_name][history_index]["name"]+" in history name : "+h_name+" in index : "+str(history_index)) + print("Gyes log : mat stored : "+self.rm_history[h_name][history_index]["name"]+" in history name : "+h_name+" in index : "+str(history_index)) mat.use_fake_user = True bpy.context.scene.historybak = str(self.rm_history) @@ -241,19 +241,19 @@ h_name = bpy.context.scene.h_selected for i in bpy.context.selected_objects : - if random_assign == False and i.type == 'MESH' and ( bpy.context.scene.history_index in rm.rm_history[h_name] ) and rm.rm_history[h_name][bpy.context.scene.history_index] and rm.rm_history[h_name][bpy.context.scene.history_index]["name"]: + if random_assign == False and ( bpy.context.scene.history_index in rm.rm_history[h_name] ) and rm.rm_history[h_name][bpy.context.scene.history_index] and rm.rm_history[h_name][bpy.context.scene.history_index]["name"]: scn = bpy.context.scene mat = i.active_material index = scn.history_index if len(i.material_slots) == 0: - print("no slot found creating a new one") + print("Gyes log : no slot found creating a new one") i.active_material= bpy.data.materials[self.rm_history[h_name][index]["name"]] else: - print("found slot assigning material") + print("Gyes log : found slot assigning material") i.material_slots[i.active_material_index].material= bpy.data.materials[self.rm_history[h_name][index]["name"]] - if random_assign == True and i.type == 'MESH' and ( bpy.context.scene.history_index in rm.rm_history[h_name] ) and rm.rm_history[h_name][bpy.context.scene.history_index] and rm.rm_history[h_name][bpy.context.scene.history_index]["name"]: + if random_assign == True and ( bpy.context.scene.history_index in rm.rm_history[h_name] ) and rm.rm_history[h_name][bpy.context.scene.history_index] and rm.rm_history[h_name][bpy.context.scene.history_index]["name"]: index = round(len(self.rm_history) * random.random()) @@ -265,10 +265,10 @@ scn.history_index=index if len(i.material_slots) == 0: - print("no slot found creating a new one") + print("Gyes log : no slot found creating a new one") i.active_material= bpy.data.materials[self.rm_history[h_name][index]["name"]] else: - print("found slot assigning material") + print("Gyes log : found slot assigning material") i.material_slots[i.active_material_index].material= bpy.data.materials[self.rm_history[h_name][index]["name"]] @@ -452,24 +452,22 @@ def execute(self, context): for i in context.selected_objects : - if i.type == 'MESH' : - - if not i.material_slots: - print("no material_slot found , creating new with material") - new_random = bpy.data.materials.new("Random") - i.active_material=new_random - rm.random_material(i.active_material,'Random') - - - if i.material_slots[0].material: - print("found an existing material, using this one ") - rm.random_material(i.active_material,'Random') - - if not i.material_slots[0].material: - print("no material found , creating new") - new_random = bpy.data.materials.new("Random") - i.active_material=new_random - rm.random_material(i.active_material,'Random') + if not i.material_slots: + print("Gyes log : no material_slot found , creating new with material") + new_random = bpy.data.materials.new("Random") + i.active_material=new_random + rm.random_material(i.active_material,'Random') + + + if i.material_slots[0].material: + print("Gyes log : found an existing material, using this one ") + rm.random_material(i.active_material,'Random') + + if not i.material_slots[0].material: + print("Gyes log : no material found , creating new") + new_random = bpy.data.materials.new("Random") + i.active_material=new_random + rm.random_material(i.active_material,'Random') return{'FINISHED'} @@ -634,7 +632,7 @@ rm.rm_history=eval(s) - print("restored history dictionary") + print("Gyes log : restored history dictionary") return{'FINISHED'} diff -Nru blender-2.61/release/scripts/addons_contrib/gyes/random_texture_generator.py blender-2.62/release/scripts/addons_contrib/gyes/random_texture_generator.py --- blender-2.61/release/scripts/addons_contrib/gyes/random_texture_generator.py 2011-12-13 19:59:41.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/gyes/random_texture_generator.py 2012-02-15 19:43:58.000000000 +0000 @@ -159,9 +159,9 @@ if material.texture_slots[material.active_texture_index] and material.texture_slots[material.active_texture_index].texture: texture = material.texture_slots[material.active_texture_index].texture if not scn.rtexture_type=='RANDOM': - texture.type = scn.rtexture_type + texture.type = scn.rtexture_type else: - texture.type = random.choice(['BLEND','CLOUDS','DISTORTED_NOISE','MAGIC','MARBLE','MUSGRAVE','NOISE','STUCCI','VORONOI','WOOD']) + texture.type = random.choice(['BLEND','CLOUDS','DISTORTED_NOISE','MAGIC','MARBLE','MUSGRAVE','NOISE','STUCCI','VORONOI','WOOD']) material.texture_slots[material.active_texture_index].texture = texture else: material.texture_slots.create(material.active_texture_index) @@ -778,9 +778,7 @@ def execute(self, context): for i in context.selected_objects : - if i.type == 'MESH' : - - rt.random_texture(i.active_material) + rt.random_texture(i.active_material) return{'FINISHED'} diff -Nru blender-2.61/release/scripts/addons_contrib/io_directx_bel/bel/fs.py blender-2.62/release/scripts/addons_contrib/io_directx_bel/bel/fs.py --- blender-2.61/release/scripts/addons_contrib/io_directx_bel/bel/fs.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/io_directx_bel/bel/fs.py 2012-02-15 19:43:58.000000000 +0000 @@ -0,0 +1,71 @@ +# v0.1 +import bpy +from os import path as os_path, listdir as os_listdir +from bpy import path as bpy_path + +# cross platform paths (since ms conform to / path ;) ) +# maybe add utf8 replace to old ascii blender builtin +# // can be omitted for relative +def clean(path) : + path = path.strip().replace('\\','/') + if ('/') not in path : path = '//'+path + return path + +## test for existence of a file or a dir +def exist(path) : + if isfile(path) or isdir(path) : return True + return False + +## test for existence of a file +def isfile(path) : + if os_path.isfile(path) : return True + # could be blender relative + path = bpy_path.abspath(path) + if os_path.isfile(path) : return True + return False + +## test for existence of a dir +def isdir(path) : + if os_path.isdir(path) : return True + # could be blender relative + path = bpy_path.abspath(path) + if os_path.isdir(path) : return True + return False + +## returns a list of every absolute filepath +# to each file within the 'ext' extensions +# from a folder and its subfolders +def scanDir(path,ext='all') : + files = [] + fields = os_listdir(path) + if ext != 'all' and type(ext) != list : ext = [ext] + for item in fields : + if os_path.isfile(path + '/' + item) and (ext == 'all' or item.split('.')[-1] in ext) : + #print(' file %s'%item) + files.append(path + '/' + item) + elif os_path.isdir(path + '/' + item) : + print('folder %s/%s :'%(path,item)) + files.extend(scanDir(path + '/' + item)) + return files + +def saveOptions(operator_name, tokens, filename='last_run'): + target_path = os_path.join("operator", operator_name) + target_path = os_path.join("presets", target_path) + target_path = bpy.utils.user_resource('SCRIPTS',target_path,create=True) + if target_path: + filepath = os_path.join(target_path, filename) + ".py" + file_preset = open(filepath, 'w') + file_preset.write("import bpy\nop = bpy.context.active_operator\n\n") + properties_blacklist = bpy.types.Operator.bl_rna.properties.keys() + for key, value in tokens.items() : + if key not in properties_blacklist : + # convert thin wrapped sequences to simple lists to repr() + try: + value = value[:] + except: + pass + + file_preset.write("op.%s = %r\n" % (key, value)) + + file_preset.close() + diff -Nru blender-2.61/release/scripts/addons_contrib/io_directx_bel/bel/image.py blender-2.62/release/scripts/addons_contrib/io_directx_bel/bel/image.py --- blender-2.61/release/scripts/addons_contrib/io_directx_bel/bel/image.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/io_directx_bel/bel/image.py 2012-02-15 19:43:58.000000000 +0000 @@ -0,0 +1,264 @@ +import bpy +import bpy.path +import io_directx_bel.bel.fs +from io_directx_bel import bel + +debuglevel = 0 + +def dprint(str,l=2) : + if l <= debuglevel : + print(str) + +# create or retrieve a bdata image +# given its path +def new(path, name=False, relative = True, premul = True) : + path = bel.fs.clean(path) + # check file + if bel.fs.isfile(path) == False : + dprint('Texture image not found') + return False + + if relative : + try : + path = bpy.path.relpath(path) + path = bel.fs.clean(path) + except : + print('cant turn path into relative one (.blend and img path drive letters ?) ') + + # retrieve paths to image file from existing image slot + # returns img if paths match + for img in bpy.data.images : + if img.filepath != '' : + if bpy.path.abspath(path) == bpy.path.abspath(bel.fs.clean(img.filepath)) : + return img + + # create a unique name in image slot + if name == False : + name = bpy.path.basename(path) + name = bel.bpyname(name,bpy.data.images.keys()) + + # finally : + img = bpy.data.images.load(filepath=path) + img.name = name + img.use_premultiply = premul + return img + + +def applyShader(mat,config) : + + # matslot.link = 'DATA' + #mat = bpy.data.materials['Female_Body'] + + texslot = mat.texture_slots[0] + tex = texslot.texture + img = tex.image + + #config = shaders[shadername] + alpha = True if 'alpha' in config else False + + ## MAT + + mat.type = 'SURFACE' + # diffuse + mat.diffuse_color = Color((0.6, 0.6, 0.6)) + mat.diffuse_intensity = 0.8 + mat.diffuse_shader = 'LAMBERT' + mat.use_diffuse_ramp = False + + # specular + mat.specular_color = Color((1.0, 1.0, 1.0)) + mat.specular_intensity = 0.25 + mat.specular_shader = 'COOKTORR' + mat.use_specular_ramp = False + mat.specular_hardness = 1.0 + + # shading + mat.emit = 0.0 + mat.ambient = 0.5 + mat.translucency = 0.0 + mat.use_shadeless = False + mat.use_tangent_shading = False + mat.use_cubic = False + + # transparency + mat.use_transparency = alpha + mat.transparency_method = 'Z_TRANSPARENCY' + mat.alpha = not(alpha) + mat.specular_alpha = not(alpha) + mat.raytrace_transparency.fresnel = 0.0 + mat.raytrace_transparency.fresnel_factor = 1.25 + + # mirror + mat.raytrace_mirror.use = False + + # subsurface_scattering + mat.subsurface_scattering.use + + # strand + # options + # shadow + mat.use_shadows = True + mat.use_transparent_shadows = True + mat.use_cast_shadows_only = False + mat.shadow_cast_alpha = 1.0 + mat.use_only_shadow = False + mat.shadow_only_type = 'SHADOW_ONLY_OLD' + mat.use_cast_buffer_shadows = True + mat.shadow_buffer_bias = 0.0 + mat.use_ray_shadow_bias = True + mat.shadow_ray_bias = 0.0 + mat.use_cast_approximate = True + + # TEXTURE SLOT 0 + + # diffuse + texslot.diffuse_factor = 1.0 + texslot.use_map_diffuse = True + texslot.diffuse_color_factor = 1.0 + texslot.use_map_color_diffuse = True + texslot.alpha_factor = 1.0 + texslot.use_map_alpha = alpha + texslot.translucency_factor = 0.0 + texslot.use_map_translucency = False + + # specular + texslot.specular_factor = 0.3 + texslot.use_map_specular = True + texslot.specular_color_factor = 1.0 + texslot.use_map_color_spec = True + texslot.hardness_factor = 0.1 + texslot.use_map_hardness = True + + # shading + texslot.ambient_factor = 0.0 + texslot.use_map_ambient = False + texslot.emit_factor = 0.1 + texslot.use_map_emit = True + texslot.mirror_factor = 0.0 + texslot.use_map_mirror = False + texslot.raymir_factor = 0.0 + texslot.use_map_raymir = False + + # geometry + texslot.normal_factor = 0.0 + texslot.use_map_normal = False + texslot.warp_factor = 0.1 + texslot.use_map_warp = False + texslot.displacement_factor = 0.0 + texslot.use_map_displacement = False + + texslot.blend_type = 'MIX' + texslot.invert = False + texslot.use_rgb_to_intensity = False + texslot.color = Color((1.0, 0.0, 1.0)) # default + texslot.use_stencil = False + texslot.default_value = 1.0 + + # TEXTURE + tex.use_alpha = alpha + tex.use_preview_alpha = alpha + + # IMAGE + if type(img) != type(None) : + img.use_premultiply = True + +def BSshader(nodes,pointer) : + tkm = bpy.context.scene.tkm + typ, nodename = pointer.split(' ') + RenderShader = nodes[typ][nodename] + name = BSname(nodename,RenderShader['Object.Name']) + if name in bpy.data.materials : + mat = bpy.data.materials[name] + else : + mat = bpy.data.materials.new(name=name) + # Unused + DepthWriteEnable = RenderShader['DepthWriteEnable'] if 'DepthWriteEnable' in RenderShader else False # an integer + ShaderTransparency = RenderShader['MultiDrawLayer'] if 'MultiDrawLayer' in RenderShader else False # an integer + LightEnable = RenderShader['LightEnable'] if 'LightEnable' in RenderShader else False # an integer + + ShaderPhong = BSnode(nodes,RenderShader['Surface']) + #print('mat : %s'%ShaderPhong['Material']) + RenderMaterial = BSnode(nodes,ShaderPhong['Material']) + DiffuseColor = RenderMaterial['DiffuseColor'] if 'DiffuseColor' in RenderMaterial else False + SpecularColor = RenderMaterial['SpecularColor'] if 'SpecularColor' in RenderMaterial else False + AmbientColor = RenderMaterial['AmbientColor'] if 'AmbientColor' in RenderMaterial else False + EmissionColor = RenderMaterial['Shininess'] if 'EmissionColor' in RenderMaterial else False + Shininess = RenderMaterial['Shininess'] if 'Shininess' in RenderMaterial else False + Transparency = RenderMaterial['Transparency'] if 'Transparency' in RenderMaterial else False + for key in RenderMaterial.keys() : + if key not in ['DiffuseColor','SpecularColor','AmbientColor','EmissionColor','Shininess','Transparency'] : + print('NEW RENDERMATERIAL PROP ! : %s'%key) + + #print(AmbientColor) + if DiffuseColor : mat.diffuse_color = Color(DiffuseColor) #[0][0],DiffuseColor[0][1],DiffuseColor[0][2]) + if SpecularColor : mat.specular_color = Color(SpecularColor)#[0][0],SpecularColor[0][1],SpecularColor[0][2]) + if AmbientColor : mat.ambient = AmbientColor[0] # source value is a vector3f with x=y=z + if EmissionColor : mat.emit = EmissionColor[0] # source value is a vector3f with x=y=z + #if Shininess : mat. + #alpha is a boolean, whereas Transparency is a float or False + if Transparency : + mat.use_transparency = True + mat.transparency_method = 'Z_TRANSPARENCY' + mat.alpha = Transparency + mat.specular_alpha = 0 + alpha = True + else : alpha = False + texinfluence = False + if 'Color' in ShaderPhong : + ShaderTexture = BSnode(nodes,ShaderPhong['Color']) + texinfluence = 'Color' + if 'Reflection' in ShaderPhong : + ShaderTexture = BSnode(nodes,ShaderPhong['Reflection']) + texinfluence = 'Reflection' + if texinfluence == False : + print('neither color nor refl. in ShaderPhong %s'%RenderShader['Surface']) + print('other props are : %s'%ShaderPhong.keys()) + return mat + + ShaderTextureName = ShaderTexture['Object.Name'] + + Texture2D = BSnode(nodes,ShaderTexture['Texture']) + Texture2DName = Texture2D['Object.Name'] + + FileObject = BSnode(nodes,Texture2D['Texture.FileObject']) + imgpath = FileObject['FileName'] + imgname = imgpath.split('/')[-1] + imgpath = tkm.path_archives+'/Images/Q=Tex032M/'+imgpath + + if imgname not in bpy.data.images : + if os.path.isfile(imgpath+'.png') : ext = '.png' + elif os.path.isfile(imgpath+'.jp2') : ext = '.jp2' + else : + print('Texture image not found ! %s'%Texture2D['Texture.FileObject']) + print('path : %s.png or .jp2 '%imgpath) + return mat + img = bpy.data.images.load(filepath=imgpath+ext) + img.name = imgname + img.use_premultiply = True + else : img = bpy.data.images[imgname] + + ''' + texslot = mat.texture_slots[0] + mat.texture_slots[0] + tex = texslot.texture + tex.type = 'IMAGE' + img = tex.image + img.name + ''' + #img = bpy.data.images.new(name='imgname',width=640, height=512) + + if ShaderTextureName not in bpy.data.textures : + tex = bpy.data.textures.new(name=ShaderTextureName,type='IMAGE') + tex.image = img + tex.use_alpha = alpha + tex.use_preview_alpha = alpha + else : tex = bpy.data.textures[ShaderTextureName] + + texslot = mat.texture_slots.create(index=0) + texslot.texture = tex + texslot.texture_coords = 'UV' + texslot.uv_layer = 'UV0' + texslot.use_map_alpha = alpha + texslot.alpha_factor = 1.0 + + return mat diff -Nru blender-2.61/release/scripts/addons_contrib/io_directx_bel/bel/__init__.py blender-2.62/release/scripts/addons_contrib/io_directx_bel/bel/__init__.py --- blender-2.61/release/scripts/addons_contrib/io_directx_bel/bel/__init__.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/io_directx_bel/bel/__init__.py 2012-02-15 19:43:58.000000000 +0000 @@ -0,0 +1,23 @@ +# set a given name to a unique +# blender data name in its collection +def bpyname(name,collection,suffix=4) : + name = name[:20-suffix] + tpl = '%s.%.'+str(suffix)+'d' + bname = name + id = 0 + while bname in collection : + id += 1 + bname = tpl%(name,id) + return bname + +## check if there's nested lists in a list. used by functions that need +# list(s) of vertices/faces/edges etc as input +# @param lst a list of vector or a list of list of vectors +# @returns always nested list(s) +# a boolean True if was nested, False if was not +def nested(lst) : + try : + t = lst[0][0][0] + return lst, True + except : + return [lst], False diff -Nru blender-2.61/release/scripts/addons_contrib/io_directx_bel/bel/material.py blender-2.62/release/scripts/addons_contrib/io_directx_bel/bel/material.py --- blender-2.61/release/scripts/addons_contrib/io_directx_bel/bel/material.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/io_directx_bel/bel/material.py 2012-02-15 19:43:58.000000000 +0000 @@ -0,0 +1,32 @@ +import bpy + +''' +given name < 21 +if material name exists : +naming_method = 0 blender default (increment name) +naming_method = 1 do nothing, abort creation and use existing +naming_method = 2 create new, rename existing, +naming_method = 3 create new, replace existing +''' + +def new(name, naming_method=0) : + if name not in bpy.data.materials or naming_method == 0: + return bpy.data.materials.new(name=name) + + elif naming_method == 1 : + return bpy.data.materials[name] + + mat = bpy.data.materials.new(name=name) + + if naming_method == 2 : + mat.name = name + return mat + + # naming_method = 3 : replace + prevmat = bpy.data.materials[name] + for ob in bpy.data.objects : + for matslot in ob.material_slots : + if matslot.material == prevmat : + matslot.material = mat + bpy.data.materials.remove(prevmat) + return mat diff -Nru blender-2.61/release/scripts/addons_contrib/io_directx_bel/bel/mesh.py blender-2.62/release/scripts/addons_contrib/io_directx_bel/bel/mesh.py --- blender-2.61/release/scripts/addons_contrib/io_directx_bel/bel/mesh.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/io_directx_bel/bel/mesh.py 2012-02-15 19:43:58.000000000 +0000 @@ -0,0 +1,209 @@ +##\file +# raw extract quick cleaning from blended cities2.6 project. thanks to myself for cooperation, but what a messy code we have here. +import bpy +import mathutils +from mathutils import * + +import io_directx_bel.bel.uv +import io_directx_bel.bel.ob +from io_directx_bel import bel + +debuglevel = 0 +''' +wip.. naming behaviour previous to any data +name exist ? +no : create +yes : + naming_method = 0 blender default (increment name) + naming_method = 1 do nothing, abort creation and use existing + naming_method = 2 create new, rename existing, + naming_method = 3 create new, remove existing + +for now, and mesh data, 0 2 or 3 +''' + +## material MUST exist before creation of material slots +## map only uvmap 0 to its image defined in mat for now (multitex view) +def write(obname,name, + verts=[], edges=[], faces=[], + matslots=[], mats=[], uvs=[], + groupnames=[], vindices=[], vweights=[], + smooth=False, + naming_method = 0, + ) : + + + obj = bpy.data.objects[obname] if obname in bpy.data.objects else False + me = bpy.data.meshes[name] if name in bpy.data.meshes else False + + #print(naming_method,type(obj),type(me)) + #print(obj,me) + #print() + if naming_method == 1 and me and obj and obj.data == me : + #print('%s and %s exist, reuse'%(obj.name,me.name)) + return obj + + if naming_method == 3 : + if obj : + #print('remove ob %s'%obj.name) + bel.ob.remove(obj,False) + if me : + #print('remove me %s'%me.name) + bel.ob.removeData(me) + + + me = bpy.data.meshes.new(name) + if naming_method == 2 : me.name = name + + me.from_pydata(verts, edges, faces) + me.update() + + if smooth : shadesmooth(me) + + # material slots + matimage=[] + if len(matslots) > 0 : + for matname in matslots : + ''' + if matname not in bpy.data.materials : + mat = bpy.data.materials.new(name=matname) + mat.diffuse_color=( random.uniform(0.0,1.0),random.uniform(0.0,1.0),random.uniform(0.0,1.0)) + mat.use_fake_user = True + warn.append('Created missing material : %s'%matname) + else : + ''' + mat = bpy.data.materials[matname] + me.materials.append(mat) + texslot_nb = len(mat.texture_slots) + if texslot_nb : + texslot = mat.texture_slots[0] + if type(texslot) != type(None) : + tex = texslot.texture + if tex.type == 'IMAGE' : + img = tex.image + if type(img) != type(None) : + matimage.append(img) + continue + matimage.append(False) + + # map a material to each face + if len(mats) > 0 : + for fi,f in enumerate(me.faces) : + f.material_index = mats[fi] + + # uvs + if len(uvs) > 0 : + bel.uv.write(me, uvs, matimage) + + + obj = bpy.data.objects.new(name=obname, object_data=me) + if naming_method != 0 : + obj.name = obname + + ''' + else : + ob = bpy.data.objects[name] + ob.data = me + if naming_method == 2 : ob.name = + ob.parent = None + ob.matrix_local = Matrix() + print(' reuse object %s'%ob.name) + ''' + + # vertexgroups + if len(groupnames) > 0 : + for gpi, groupname in enumerate(groupnames) : + weightsadd(obj, groupname, vindices[gpi], vweights[gpi]) + + # scene link check + if obj.name not in bpy.context.scene.objects.keys() : + bpy.context.scene.objects.link(obj) + + return obj + +def shadesmooth(me,lst=True) : + if type(lst) == list : + for fi in lst : + me.faces[fi].use_smooth = True + else : + for fi,face in enumerate(me.faces) : + face.use_smooth = True + +def shadeflat(me,lst=True) : + if type(lst) == list : + for fi in lst : + me.faces[fi].use_smooth = False + else : + for fi,face in enumerate(me.faces) : + face.use_smooth = False + +def weightsadd(ob, groupname, vindices, vweights=False) : + if vweights == False : vweights = [1.0 for i in range(len(vindices))] + elif type(vweights) == float : vweights = [vweights for i in range(len(vindices))] + group = ob.vertex_groups.new(groupname) + for vi,v in enumerate(vindices) : + group.add([v], vweights[vi], 'REPLACE') + +def matToString(mat) : + #print('*** %s %s'%(mat,type(mat))) + return str(mat).replace('\n ','')[6:] + +def stringToMat(string) : + return Matrix(eval(string)) + + +def objectBuild(elm, verts, edges=[], faces=[], matslots=[], mats=[], uvs=[] ) : + #print('build element %s (%s)'%(elm,elm.className())) + dprint('object build',2) + city = bpy.context.scene.city + # apply current scale + verts = metersToBu(verts) + + if type(elm) != str : + obname = elm.objectName() + if obname == 'not built' : + obname = elm.name + else : obname= elm + + obnew = createMeshObject(obname, True, verts, edges, faces, matslots, mats, uvs) + #elm.asElement().pointer = str(ob.as_pointer()) + if type(elm) != str : + if elm.className() == 'outlines' : + obnew.lock_scale[2] = True + if elm.parent : + obnew.parent = elm.Parent().object() + else : + #otl = elm.asOutline() + #ob.parent = otl.object() + objectLock(obnew,True) + #ob.matrix_local = Matrix() # not used + #ob.matrix_world = Matrix() # world + return obnew + +def dprint(str,l=2) : + if l <= debuglevel : + print(str) + + +def materialsCheck(bld) : + if hasattr(bld,'materialslots') == False : + #print(bld.__class__.__name__) + builderclass = eval('bpy.types.%s'%(bld.__class__.__name__)) + builderclass.materialslots=[bld.className()] + + matslots = bld.materialslots + if len(matslots) > 0 : + for matname in matslots : + if matname not in bpy.data.materials : + mat = bpy.data.materials.new(name=matname) + mat.use_fake_user = True + if hasattr(bld,'mat_%s'%(matname)) : + method = 'defined by builder' + matdef = eval('bld.mat_%s'%(matname)) + mat.diffuse_color = matdef['diffuse_color'] + else : + method = 'random' + mat.diffuse_color=( random.uniform(0.0,1.0),random.uniform(0.0,1.0),random.uniform(0.0,1.0)) + dprint('Created missing material %s (%s)'%(matname,method),2) + + diff -Nru blender-2.61/release/scripts/addons_contrib/io_directx_bel/bel/ob.py blender-2.62/release/scripts/addons_contrib/io_directx_bel/bel/ob.py --- blender-2.61/release/scripts/addons_contrib/io_directx_bel/bel/ob.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/io_directx_bel/bel/ob.py 2012-02-15 19:43:58.000000000 +0000 @@ -0,0 +1,116 @@ +import bpy +from bpy.types import Mesh, PointLamp, SpotLamp, HemiLamp, AreaLamp, SunLamp, Camera, TextCurve, MetaBall, Lattice, Armature + + +def new(name,datatype,naming_method): + if name in bpy.data.objects and naming_method : + ob = bpy.data.objects[name] + if naming_method == 1 : + ob.parent = None + ob.user_clear() + elif naming_method == 2 : + ob = bpy.data.objects.new(name,datatype) + ob.name = name + elif naming_method == 3 : + bpy.context.scene.objects.unlink(ob) + ob.user_clear() + bpy.data.objects.remove(ob) + ob = bpy.data.objects.new(name,datatype) + else : + ob = bpy.data.objects.new(name,datatype) + if ob.name not in bpy.context.scene.objects.keys() : + bpy.context.scene.objects.link(ob) + return ob + +## returns an object or a list of objects +# @param ob 'all', 'active', 'selected', , 'objectname' +# @return a list of objects or an empty list +def get(ob) : + if type(ob) == str : + if ob == 'all' : return bpy.context.scene.objects + elif ob == 'active' : return [bpy.context.active_object] if bpy.context.active_object != None else [] + elif ob == 'selected' : return bpy.context.selected_objects + else : + try : return [bpy.data.objects[ob]] + except : return [] + return [ob] + + +## remove an object from blender internal +def remove(ob,with_data=True) : + objs = get(ob) + #if objs : + # if type(objs) == bpy.types.Object : objs = [objs] + for ob in objs : + data = ob.data + #and_data=False + # never wipe data before unlink the ex-user object of the scene else crash (2.58 3 770 2) + # if there's more than one user for this data, never wipeOutData. will be done with the last user + # if in the list + and_data = with_data + try : + if data.users > 1 : + and_data=False + except : + and_data=False # empties + + # odd (pre 2.60) : + # ob=bpy.data.objects[ob.name] + # if the ob (board) argument comes from bpy.data.groups['aGroup'].objects, + # bpy.data.groups['board'].objects['board'].users_scene + ob.name = '_dead' + for sc in ob.users_scene : + sc.objects.unlink(ob) + + #try : + #print(' removing object %s...'%(ob.name)), + bpy.data.objects.remove(ob) + #print(' done.') + #except : + # print('removing failed, but renamed %s and unlinked'%ob.name) + + # never wipe data before unlink the ex-user object of the scene else crash (2.58 3 770 2) + if and_data : + wipeOutData(data) + + +## remove an object data from blender internal +## or rename it _dead if there's still users +def removeData(data) : + #print('%s has %s user(s) !'%(data.name,data.users)) + + if data.users <= 0 : + + #data.user_clear() + data_type = type(data) + + # mesh + if data_type == Mesh : + bpy.data.meshes.remove(data) + # lamp + elif data_type in [ PointLamp, SpotLamp, HemiLamp, AreaLamp, SunLamp ] : + bpy.data.lamps.remove(data) + # camera + elif data_type == Camera : + bpy.data.cameras.remove(data) + # Text, Curve + elif data_type in [ Curve, TextCurve ] : + bpy.data.curves.remove(data) + # metaball + elif data_type == MetaBall : + bpy.data.metaballs.remove(data) + # lattice + elif data_type == Lattice : + bpy.data.lattices.remove(data) + # armature + elif data_type == Armature : + bpy.data.armatures.remove(data) + else : + print(' data still here : forgot %s type'%type(data)) + #except : + # empty, field + # print('%s has no user_clear attribute ? (%s).'%(data.name,type(data))) + else : + #print(' not done, %s has %s user'%(data.name,data.users)) + data.name = '_dead' + diff -Nru blender-2.61/release/scripts/addons_contrib/io_directx_bel/bel/uv.py blender-2.62/release/scripts/addons_contrib/io_directx_bel/bel/uv.py --- blender-2.61/release/scripts/addons_contrib/io_directx_bel/bel/uv.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/io_directx_bel/bel/uv.py 2012-02-15 19:43:58.000000000 +0000 @@ -0,0 +1,81 @@ +from mathutils import Vector +from .. import bel + +def write(me, uvs, matimage = False) : + uvs, nest = bel.nested(uvs) + newuvs = [] + append = newuvs.append + for uvi, uvlist in enumerate(uvs) : + + uv = me.uv_textures.new() + uv.name = 'UV%s'%uvi + + for uvfi, uvface in enumerate(uvlist) : + #uv.data[uvfi].use_twoside = True # 2.60 changes mat ways + mslotid = me.faces[uvfi].material_index + #mat = mesh.materials[mslotid] + if matimage : + if matimage[mslotid] : + img = matimage[mslotid] + uv.data[uvfi].image=img + #uv.data[uvfi].use_image = True + + uv.data[uvfi].uv1 = Vector((uvface[0],uvface[1])) + uv.data[uvfi].uv2 = Vector((uvface[2],uvface[3])) + uv.data[uvfi].uv3 = Vector((uvface[4],uvface[5])) + if len(uvface) == 8 : + uv.data[uvfi].uv4 = Vector((uvface[6],uvface[7])) + append(uv) + if nest : return newuvs + else : return newuvs[0] + + +# face are squared or rectangular, +# any orientation +# vert order width then height 01 and 23 = x 12 and 03 = y +# normal default when face has been built +def row(vertices,faces,normals=True) : + uvs = [] + append = uvs.append + for face in faces : + v0 = vertices[face[0]] + v1 = vertices[face[1]] + v2 = vertices[face[-1]] + #print(v0,v1) + lx = (v1 - v0).length + ly = (v2 - v0).length + # init uv + if len(uvs) == 0 : + x = 0 + y = 0 + elif normals : + x = uvs[-1][2] + y = uvs[-1][3] + else : + x = uvs[-1][0] + y = uvs[-1][1] + if normals : append([x,y,x+lx,y,x+lx,y+ly,x,y+ly]) + else : append([x+lx,y,x,y,x,y+ly,x+lx,y+ly]) + return uvs + +## convert UV given as verts location to blender format +# eg : [ [v0x,v0y] , [vnx , vny] ... ] -> [ [ v1x,v1y,v0x,v0y,v4x,v4y] ... ] +# this format is found in directx files +''' +def asVertsLocation(verts2d, faces) : + uv = [] + for f in faces : + uvface = [] + for vi in f : + uvface.extend(verts2d[vi]) + uv.append(uvface) + return uv +''' +def asVertsLocation(verts2d, idFaces) : + coFaces = [] + uvBlender = [] + conv0 = coFaces.extend + conv1 = uvBlender.extend + for f in idFaces : conv0([verts2d[vi] for vi in f]) + for f in coFaces : conv1(f) + return uvBlender \ No newline at end of file diff -Nru blender-2.61/release/scripts/addons_contrib/io_directx_bel/import_x.py blender-2.62/release/scripts/addons_contrib/io_directx_bel/import_x.py --- blender-2.61/release/scripts/addons_contrib/io_directx_bel/import_x.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/io_directx_bel/import_x.py 2012-02-15 19:43:59.000000000 +0000 @@ -0,0 +1,976 @@ +# Blender directX importer +# version baby + +# litterature explaining the parser directions : + +# I don't want to load the whole file as it can be huge : go chunks +# also I want random access to 3d datas to import pieces, not always everything +# so step1 is a whole file fast parsing, retrieving tokens name and building the internal dict +# with no 3d datas inside. +# step 2 is to call any token by their names and retrieve the 3d datas thanks to a pointer stored in dicts +# between stp1 and step 2 a script ui should be provided to select, transform etc before import. +# > I need to know the pointer position of tokens but data.tell() is slow +# a += pointer computed from line length is way faster. so I need eol -> rb mode +# and readline() is ok in binary mode 'rb' with \r\n (win) \n (unix) but not \r mac.. +# 2chrs for windows, 1 for mac and lunix > win eol \r\n becomes \n\n (add a line) +# mac eol \r becomes \n so win lines info are wrong +# this also allows support for wrong files format (mixed \r and \r\n) +# for now it only works for text format, but the used methods will be independant of the container type. + +# TEST FILES +# http://assimp.svn.sourceforge.net/viewvc/assimp/trunk/test/models/X/ + + +import os +import re +import struct, binascii +import time + +import bpy +from mathutils import Vector, Matrix + + +import io_directx_bel.bel.mesh +import io_directx_bel.bel.image +import io_directx_bel.bel.uv +import io_directx_bel.bel.material +import io_directx_bel.bel.ob +import io_directx_bel.bel.fs +from io_directx_bel import bel + +# XXX, should use explicit names +from .templates_x import * + +''' +# just a temp hack to reload bel everytime +import imp +imp.reload(bel) +imp.reload(bel.fs) +imp.reload(bel.image) +imp.reload(bel.material) +imp.reload(bel.mesh) +imp.reload(bel.ob) +imp.reload(bel.uv) +''' + +################################################### + +def load(operator, context, filepath, + global_clamp_size=0.0, + show_tree=False, + show_templates=False, + show_geninfo=False, + quickmode=False, + parented=False, + use_templates=False, + bone_maxlength=1.0, + chunksize=2048, + naming_method=0, + use_ngons=True, + use_edges=True, + use_smooth_groups=True, + use_split_objects=True, + use_split_groups=True, + use_groups_as_vgroups=False, + use_image_search=True, + global_matrix=None, + ): + + + if quickmode : + parented = False + + bone_minlength = bone_maxlength / 100.0 + + #global templates, tokens + rootTokens = [] + namelookup = {} + imgnamelookup = {} + chunksize = int(chunksize) + reserved_type = ( + 'dword', + 'float', + 'string' + ) + + ''' + 'array', + 'Matrix4x4', + 'Vector', + ''' + ''' + with * : defined in dXdata + + WORD 16 bits + * DWORD 32 bits + * FLOAT IEEE float + DOUBLE 64 bits + CHAR 8 bits + UCHAR 8 bits + BYTE 8 bits + * STRING NULL-terminated string + CSTRING Formatted C-string (currently unsupported) + UNICODE UNICODE string (currently unsupported) + +BINARY FORMAT +# TOKENS in little-endian WORDs +#define TOKEN_NAME 1 +#define TOKEN_STRING 2 +#define TOKEN_INTEGER 3 +#define TOKEN_GUID 5 +#define TOKEN_INTEGER_LIST 6 +#define TOKEN_FLOAT_LIST 7 +#define TOKEN_OBRACE 10 +#define TOKEN_CBRACE 11 +#define TOKEN_OPAREN 12 +#define TOKEN_CPAREN 13 +#define TOKEN_OBRACKET 14 +#define TOKEN_CBRACKET 15 +#define TOKEN_OANGLE 16 +#define TOKEN_CANGLE 17 +#define TOKEN_DOT 18 +#define TOKEN_COMMA 19 +#define TOKEN_SEMICOLON 20 +#define TOKEN_TEMPLATE 31 +#define TOKEN_WORD 40 +#define TOKEN_DWORD 41 +#define TOKEN_FLOAT 42 +#define TOKEN_DOUBLE 43 +#define TOKEN_CHAR 44 +#define TOKEN_UCHAR 45 +#define TOKEN_SWORD 46 +#define TOKEN_SDWORD 47 +#define TOKEN_VOID 48 +#define TOKEN_LPSTR 49 +#define TOKEN_UNICODE 50 +#define TOKEN_CSTRING 51 +#define TOKEN_ARRAY 52 + + ''' + + # COMMON REGEX + space = '[\ \t]{1,}' # at least one space / tab + space0 = '[\ \t]{0,}' # zero or more space / tab + + # DIRECTX REGEX TOKENS + r_template = r'template' + space + '[\w]*' + space0 + '\{' + if quickmode : + r_sectionname = r'Mesh' + space + '[\W-]*' + else : + r_sectionname = r'[\w]*' + space + '[\w-]*' + space0 + '\{' + r_refsectionname = r'\{' + space0 + '[\w-]*' + space0 + '\}' + r_endsection = r'\{|\}' + + # dX comments + r_ignore = r'#|//' + + #r_frame = r'Frame' + space + '[\w]*' + #r_matrix = r'FrameTransformMatrix' + space + '\{[\s\d.,-]*' + #r_mesh = r'Mesh' + space + '[\W]*' + + ################### + ## STEP 1 FUNCTIONS + ################### + + ## HEADER + # returns header values or False if directx reco tag is missing + # assuming there's never comment header and that xof if the 1st + # string of the file + ''' + they look like xof 0303txt 0032 + 4 Magic Number (required) "xof " + 2 Minor Version 03 + 2 Major Version 02 + 4 Format Type (required) + "txt " Text File + "bin " Binary File + "tzip" MSZip Compressed Text File + "bzip" MSZip Compressed Binary File + 4 Float Accuracy "0032" 32 bit or "0064" 64 bit + ''' + def dXheader(data) : + l = data.read(4) + if l != b'xof ' : + print ('no header found !') + data.seek(0) + return False + minor = data.read(2).decode() + major = data.read(2).decode() + format = data.read(4).decode().strip() + accuracy = int(data.read(4).decode()) + data.seek(0) + return ( minor, major, format, accuracy ) + + + ## + def dXtree(data,quickmode = False) : + tokens = {} + templates = {} + tokentypes = {} + c = 0 + lvl = 0 + tree = [''] + ptr = 0 + eol = 0 + trunkated = False + previouslvl = False + while True : + lines, trunkated = nextFileChunk(data,trunkated) + if lines == None : break + for l in lines : + + # compute pointer position + ptr += eol + c += 1 + eol = len(l) + 1 + #print(c,data.tell(),ptr+eol) + #if l != '' : print('***',l) + #if l == '' : break + l = l.strip() + + # remove blank and comment lines + if l == '' or re.match(r_ignore,l) : + continue + + # one line token cases level switch + if previouslvl : + lvl -= 1 + previouslvl = False + + #print('%s lines in %.2f\''%(c,time.clock()-t),end='\r') + #print(c,len(l)+1,ptr,data.tell()) + if '{' in l : + lvl += 1 + if '}' in l : previouslvl = True #; print('got one line token : \n%s'%l) + elif '}' in l : + lvl -= 1 + #print(c,lvl,tree) + + if quickmode == False : + ## look for templates + if use_templates and re.match(r_template,l) : + tname = l.split(' ')[1] + templates[tname] = {'pointer' : ptr, 'line' : c} + continue + + ## look for {references} + if re.match(r_refsectionname,l) : + refname = namelookup[ l[1:-1].strip() ] + #print('FOUND reference to %s in %s at line %s (level %s)'%(refname,tree[lvl-1],c,lvl)) + #tree = tree[0:lvl] + parent = tree[lvl-1] + # tag it as a reference, since it's not exactly a child. + # put it in childs since order can matter in sub tokens declaration + tokens[parent]['childs'].append('*'+refname) + if refname not in tokens : + print('reference to %s done before its declaration (line %s)\ncreated dummy'%(refname,c)) + tokens[refname] = {} + if 'user' not in tokens[refname] : tokens[refname]['users'] = [parent] + else : tokens[refname]['users'].append(parent) + continue + + ## look for any token or only Mesh token in quickmode + if re.match(r_sectionname,l) : + tokenname = getName(l,tokens) + #print('FOUND %s %s %s %s'%(tokenname,c,lvl,tree)) + #print('pointer %s %s'%(data.tell(),ptr)) + if lvl == 1 : rootTokens.append(tokenname) + typ = l.split(' ')[0].strip().lower() + tree = tree[0:lvl] + if typ not in tokentypes : tokentypes[typ] = [tokenname] + else : tokentypes[typ].append(tokenname) + parent = tree[-1] + if tokenname in tokens : + tokens[tokenname]['pointer'] = ptr + tokens[tokenname]['line'] = c + tokens[tokenname]['parent'] = parent + tokens[tokenname]['childs'] = [] + tokens[tokenname]['type'] = typ + + else : tokens[tokenname] = {'pointer': ptr, + 'line' : c, + 'parent' : parent, + 'childs' : [], + 'users' : [], + 'type' : typ + } + tree.append(tokenname) + if lvl > 1 and quickmode == False : + tokens[parent]['childs'].append(tokenname) + + return tokens, templates, tokentypes + + ## returns file binary chunks + def nextFileChunk(data,trunkated=False,chunksize=1024) : + if chunksize == 0 : chunk = data.read() + else : chunk = data.read(chunksize) + if format == 'txt' : + lines = chunk.decode('utf-8', errors='ignore') + #if stream : return lines.replace('\r','').replace('\n','') + #lines = [ l + '\n' for l in lines.replace('\r','\n').split('\n') ] + lines = lines.replace('\r','\n').split('\n') + if trunkated : lines[0] = trunkated + lines[0] + if len(lines) == 1 : + if lines[0] == '' : return None, None + return lines, False + return lines, lines.pop() + # wip, todo for binaries + else : + print(chunk) + for word in range(0,len(chunk)) : + w = chunk[word:word+4] + print(word,w,struct.unpack(" 0 or tokens[tokenname]['parent'] == '' : + if tokenname not in tokens : + tokenname = tokenname[1:] + ref = 'ref: ' + else : ref = False + + frame_type = tokens[tokenname]['type'] + line = ('{:7}'.format(tokens[tokenname]['line'])) + log = ' %s%s (%s)'%( ref if ref else '', tokenname, frame_type ) + print('%s.%s%s'%(line, tab, log)) + if fi == len(field) - 1 : tab = tab[:-3] + ' ' + + if ref == False : + for user in tokens[tokenname]['users'] : + print('%s.%s |__ user: %s'%(line, tab.replace('_',' '), user)) + walk_dXtree(tokens[tokenname]['childs'],lvl+1,tab.replace('_',' ')+' |__') + + if fi == len(field) - 1 and len(tokens[tokenname]['childs']) == 0 : + print('%s.%s'%(line,tab)) + + ## remove eol, comments, spaces from a raw block of datas + def cleanBlock(block) : + while '//' in block : + s = block.index('//') + e = block.index('\n',s+1) + block = block[0:s] + block[e:] + while '#' in block : + s = block.index('#') + e = block.index('\n',s+1) + block = block[0:s] + block[e:] + block = block.replace('\n','').replace(' ','').replace('\t ','') + return block + + def readToken(tokenname) : + token = tokens[tokenname] + datatype = token['type'].lower() + if datatype in templates : tpl = templates[datatype] + elif datatype in defaultTemplates : tpl = defaultTemplates[datatype] + else : + print("can't find any template to read %s (type : %s)"%(tokenname,datatype)) + return False + #print('> use template %s'%datatype) + block = readBlock(data,token) + ptr = 0 + #return dXtemplateData(tpl,block) + fields, ptr = dXtemplateData(tpl,block) + if datatype in templatesConvert : + fields = eval( templatesConvert[datatype] ) + return fields + + def dXtemplateData(tpl,block,ptr=0) : + #print('dxTPL',block[ptr]) + pack = [] + append = pack.append + namespace = locals() + for member in tpl['members'] : + #print(member) + datatype = member[0].lower() + dataname = member[-1] + if datatype == 'array' : + datatype = member[1].lower() + s = dataname.index('[') + 1 + e = dataname.index(']') + #print(dataname[s:e]) + length = eval(dataname[s:e]) + #print("array %s type %s length defined by '%s' : %s"%(dataname[:s-1],datatype,dataname[s:e],length)) + dataname = dataname[:s-1] + datavalue, ptr = dXarray(block, datatype, length, ptr) + #print('back to %s'%(dataname)) + else : + length = 1 + datavalue, ptr = dXdata(block, datatype, length, ptr) + + #if len(str(datavalue)) > 50 : dispvalue = str(datavalue[0:25]) + ' [...] ' + str(datavalue[-25:]) + #else : dispvalue = str(datavalue) + #print('%s : %s %s'%(dataname,dispvalue,type(datavalue))) + #exec('%s = datavalue'%(dataname)) + namespace[dataname] = datavalue + append( datavalue ) + return pack, ptr + 1 + + def dXdata(block,datatype,length,s=0,eof=';') : + #print('dxDTA',block[s]) + # at last, the data we need + # should be a ';' but one meet ',' often, like in meshface + if datatype == 'dword' : + e = block.index(';',s+1) + try : field = int(block[s:e]) + except : + e = block.index(',',s+1) + field = int(block[s:e]) + return field, e+1 + elif datatype == 'float' : + e = block.index(eof,s+1) + return float(block[s:e]), e+1 + elif datatype == 'string' : + e = block.index(eof,s+1) + return str(block[s+1:e-1]) , e+1 + else : + if datatype in templates : tpl = templates[datatype] + elif datatype in defaultTemplates : tpl = defaultTemplates[datatype] + else : + print("can't find any template for type : %s"%(datatype)) + return False + #print('> use template %s'%datatype) + fields, ptr = dXtemplateData(tpl,block,s) + if datatype in templatesConvert : + fields = eval( templatesConvert[datatype] ) + return fields, ptr + + def dXarray(block, datatype, length, s=0) : + #print('dxARR',block[s]) + lst = [] + append = lst.append + if datatype in reserved_type : + eoi=',' + for i in range(length) : + if i+1 == length : eoi = ';' + datavalue, s = dXdata(block,datatype,1,s,eoi) + append( datavalue ) + + else : + eoi = ';,' + for i in range(length) : + if i+1 == length : eoi = ';;' + #print(eoi) + e = block.index(eoi,s) + #except : print(block,s) ; popo() + datavalue, na = dXdata(block[s:e+1],datatype,1) + append( datavalue ) + s = e + 2 + return lst, s + + ################################################### + + ## populate a template with its datas + # this make them available in the internal dict. should be used in step 2 for unknown data type at least + def readTemplate(data,tpl_name,display=False) : + ptr = templates[tpl_name]['pointer'] + line = templates[tpl_name]['line'] + #print('> %s at line %s (chr %s)'%(tpl_name,line,ptr)) + data.seek(ptr) + lines = [] + append = lines.append + trunkated = False + go = True + while go : + rawlines, trunkated = nextFileChunk(data,trunkated,chunksize) # stream ? + if rawlines == None : break + for l in rawlines : + append(l.strip()) + if '}' in l : + go = False + break + block = ''.join(lines) + uuid = re.search(r'<.+>',block).group() + templates[tpl_name]['uuid'] = uuid.lower() + templates[tpl_name]['members'] = [] + templates[tpl_name]['restriction'] = 'closed' + + members = re.search(r'>.+',block).group()[1:-1].split(';') + for member in members : + if member == '' : continue + if member[0] == '[' : + templates[tpl_name]['restriction'] = member + continue + templates[tpl_name]['members'].append( member.split(' ') ) + + if display : + print('\ntemplate %s :'%tpl_name) + for k,v in templates[tpl_name].items() : + if k != 'members' : + print(' %s : %s'%(k,v)) + else : + for member in v : + print(' %s'%str(member)[1:-1].replace(',',' ').replace("'",'')) + + if tpl_name in defaultTemplates : + defaultTemplates[tpl_name]['line'] = templates[tpl_name]['line'] + defaultTemplates[tpl_name]['pointer'] = templates[tpl_name]['pointer'] + if defaultTemplates[tpl_name] != templates[tpl_name] : + print('! DIFFERS FROM BUILTIN TEMPLATE :') + print('raw template %s :'%tpl_name) + print(templates[tpl_name]) + print('raw default template %s :'%tpl_name) + print(defaultTemplates[tpl_name]) + #for k,v in defaultTemplates[tpl_name].items() : + # if k != 'members' : + # print(' %s : %s'%(k,v)) + # else : + # for member in v : + # print(' %s'%str(member)[1:-1].replace(',',' ').replace("'",'')) + else : + print('MATCHES BUILTIN TEMPLATE') + + ## read any kind of token data block + # by default the block is cleaned from inline comment space etc to allow data parsing + # useclean = False (retrieve all bytes) if you need to compute a file byte pointer + # to mimic the file.tell() function and use it with file.seek() later + def readBlock(data,token, clean=True) : + data.seek(token['pointer']) + lines = [] + append = lines.append + strip = str.strip + go = True + init = True + + def cleanLine(l): + if '//' in l : l = l[0:l.index('//')] + if '#' in l : l = l[0:l.index('#')] + return l.strip().replace(' ','').replace('\t','') + + while go : + chunk = data.read(512).decode('utf-8', errors='ignore') + chunk = chunk.replace('\r','\n').split('\n') + for l in map(cleanLine, chunk) : + if l == '' : continue + if init : + l = l[l.index('{')+1:] + init = False + if '}' in l : + append(l[0:l.index('}')]) + go = False + break + append(l) + + block = ''.join(lines) + return block + + + def getChilds(tokenname) : + childs = [] + # '*' in childname means it's a reference. always perform this test + # when using the childs field + for childname in tokens[tokenname]['childs'] : + if childname[0] == '*' : childname = childname[1:] + childs.append( childname ) + return childs + + # the input nested list of [bonename, matrix, [child0,child1..]] is given by import_dXtree() + def buildArm(armdata, child,lvl=0,parent_matrix=False) : + + bonename, bonemat, bonechilds = child + + if lvl == 0 : + armname = armdata + armdata = bpy.data.armatures.new(name=armname) + arm = bpy.data.objects.new(armname,armdata) + bpy.context.scene.objects.link(arm) + arm.select = True + bpy.context.scene.objects.active = arm + bpy.ops.object.mode_set(mode='EDIT') + parent_matrix = Matrix() + + bone = armdata.edit_bones.new(name=bonename) + bonematW = parent_matrix * bonemat + bone.head = bonematW.to_translation() + #bone.roll.. ? + bone_length = bone_maxlength + for bonechild in bonechilds : + bonechild = buildArm(armdata,bonechild,lvl+1,bonematW) + bonechild.parent = bone + bone_length = min((bonechild.head - bone.head).length, bone_length) + bone.tail = bonematW * Vector((0,bone_length,0)) + if lvl == 0 : + bpy.ops.object.mode_set(mode='OBJECT') + return arm + return bone + + def import_dXtree(field,lvl=0) : + tab = ' '*lvl*2 + if field == [] : + if show_geninfo : print('%s>> no childs, return False'%(tab)) + return False + ob = False + mat = False + is_root = False + frames = [] + obs = [] + + parentname = tokens[field[0]]['parent'] + if show_geninfo : print('%s>>childs in frame %s :'%(tab,parentname)) + + for tokenname in field : + + tokentype = tokens[tokenname]['type'] + + # frames can contain more than one mesh + if tokentype == 'mesh' : + # object and mesh naming : + # if parent frame has several meshes : obname = meshname = mesh token name, + # if parent frame has only one mesh : obname = parent frame name, meshname = mesh token name. + if parentname : + meshcount = 0 + for child in getChilds(parentname) : + if tokens[child]['type'] == 'mesh' : + meshcount += 1 + if meshcount == 2 : + parentname = tokenname + break + else : parentname = tokenname + + ob = getMesh(parentname,tokenname) + obs.append(ob) + + if show_geninfo : print('%smesh : %s'%(tab,tokenname)) + + # frames contain one matrix (empty or bone) + elif tokentype == 'frametransformmatrix' : + [mat] = readToken(tokenname) + if show_geninfo : print('%smatrix : %s'%(tab,tokenname)) + + # frames can contain 0 or more frames + elif tokentype == 'frame' : + frames.append(tokenname) + if show_geninfo : print('%sframe : %s'%(tab,tokenname)) + + # matrix is used for mesh transform if some mesh(es) exist(s) + if ob : + is_root = True + if mat == False : + mat = Matrix() + if show_geninfo : print('%smesh token without matrix, set it to default\n%splease report in bug tracker if you read this !'%(tab,tab)) + if parentname == '' : + mat = mat * global_matrix + if len(obs) == 1 : + ob.matrix_world = mat + else : + ob = bel.ob.new(parentname, None, naming_method) + ob.matrix_world = mat + for child in obs : + child.parent = ob + + # matrix only, store it as a list as we don't know if + # it's a bone or an empty yet + elif mat : + ob = [parentname, mat,[]] + + # nothing case ? + else : + ob = [parentname, Matrix() * global_matrix,[]] + if show_geninfo : print('%snothing here'%(tab)) + + childs = [] + + for tokenname in frames : + if show_geninfo : print('%s'%(tab,tokenname)) + + if is_root and parentname != '' : + + if show_geninfo : print('%send of tree a this point'%(tab)) + if type(ob) == list : + mat = ob[1] + ob = bel.ob.new(parentname, None, naming_method) + ob.matrix_world = mat + + for tokenname, child in childs : + if show_geninfo : print('%sbegin2 %s>'%(tab,tokenname)) + # returned a list of object(s) or matrice(s) + if child : + + # current frame is an object or an empty, we parent this frame to it + #if eot or (ob and ( type(ob.data) == type(None) or type(ob.data) == bpy.types.Mesh ) ) : + if is_root : + # this branch is an armature, convert it + if type(child) == list : + if show_geninfo : print('%sconvert to armature %s'%(tab,tokenname)) + child = buildArm(tokenname, child) + + # parent the obj/empty/arm to current + # or apply the global user defined matrix to the object root + if parentname != '' : + child.parent = ob + else : + child.matrix_world = global_matrix + + # returned a list of parented matrices. append it in childs list + elif type(child[0]) == str : + ob[2].append(child) + + # child is an empty or a mesh, so current frame is an empty, not an armature + elif ob and ( type(child.data) == type(None) or type(child.data) == bpy.types.Mesh ) : + #print(' child data type: %s'%type(child.data)) + child.parent = ob + #print('%s parented to %s'%(child.name,ob.name)) + + # returned False + else : + if show_geninfo : print('%sreturned %s, nothing'%(tab,child)) + + #print('>> %s return %s'%(field,ob)) + return ob# if ob else False + + # build from mesh token type + def getMesh(obname,tokenname,debug = False): + + if debug : print('\nmesh name : %s'%tokenname) + + verts = [] + edges = [] + faces = [] + matslots = [] + facemats = [] + uvs = [] + groupnames = [] + groupindices = [] + groupweights = [] + + nVerts, verts, nFaces, faces = readToken(tokenname) + + if debug : + print('verts : %s %s\nfaces : %s %s'%(nVerts, len(verts),nFaces, len(faces))) + + #for childname in token['childs'] : + for childname in getChilds(tokenname) : + + tokentype = tokens[childname]['type'] + + # UV + if tokentype == 'meshtexturecoords' : + uv = readToken(childname) + uv = bel.uv.asVertsLocation(uv, faces) + uvs.append(uv) + + if debug : print('uv : %s'%(len(uv))) + + # MATERIALS + elif tokentype == 'meshmateriallist' : + nbslots, facemats = readToken(childname) + + if debug : print('facemats : %s'%(len(facemats))) + + # mat can exist but with no datas so we prepare the mat slot + # with dummy ones + for slot in range(nbslots) : + matslots.append('dXnoname%s'%slot ) + + # length does not match (could be tuned more, need more cases) + if len(facemats) != len(faces) : + facemats = [ facemats[0] for i in faces ] + + # seek for materials then textures if any mapped in this mesh. + # no type test, only one option type in token meshmateriallist : 'Material' + for slotid, matname in enumerate(getChilds(childname)) : + + # rename dummy mats with the right name + matslots[slotid] = matname + + # blender material creation (need tuning) + mat = bel.material.new(matname,naming_method) + matslots[slotid] = mat.name + + if naming_method != 1 : + #print('matname : %s'%matname) + (diffuse_color,alpha), power, specCol, emitCol = readToken(matname) + #if debug : print(diffuse_color,alpha, power, specCol, emitCol) + mat.diffuse_color = diffuse_color + mat.diffuse_intensity = power + mat.specular_color = specCol + # dX emit don't use diffuse color but is a color itself + # convert it to a kind of intensity + mat.emit = (emitCol[0] + emitCol[1] + emitCol[2] ) / 3 + + if alpha != 1.0 : + mat.use_transparency = True + mat.transparency_method = 'Z_TRANSPARENCY' + mat.alpha = alpha + mat.specular_alpha = 0 + transp = True + else : transp = False + + # texture + # only 'TextureFilename' can be here, no type test + # textures have no name in .x so we build + # image and texture names from the image file name + # bdata texture slot name = bdata image name + btexnames = [] + for texname in getChilds(matname) : + + # create/rename/reuse etc corresponding data image + # (returns False if not found) + [filename] = readToken(texname) + img = bel.image.new(path+'/'+filename) + + if img == False : + imgname = 'not_found' + else : + imgname = img.name + + #print('texname : %s'%texname) + #print('filename : %s'%filename) + #print('btex/img name : %s'%imgname) + + # associated texture (no naming check.. maybe tune more) + # tex and texslot are created even if img not found + if imgname in bpy.data.textures and ( img == False or bpy.data.textures[imgname].image == img ) : + tex = bpy.data.textures[imgname] + else : + tex = bpy.data.textures.new(name=imgname,type='IMAGE') + if img : tex.image = img + + tex.use_alpha = transp + tex.use_preview_alpha = transp + + # then create texture slot + texslot = mat.texture_slots.create(index=0) + texslot.texture = tex + texslot.texture_coords = 'UV' + texslot.uv_layer = 'UV0' + texslot.use_map_alpha = transp + texslot.alpha_factor = alpha + + # create remaining dummy mat + for slotid, matname in enumerate(matslots) : + if matname not in bpy.data.materials : + mat = bel.material.new(matname,naming_method) + matslots[slotid] = mat.name + + if debug : print('matslots : %s'%matslots) + + # VERTICES GROUPS/WEIGHTS + elif tokentype == 'skinweights' : + groupname, nverts, vindices, vweights, mat = readToken(childname) + groupname = namelookup[groupname] + if debug : + print('vgroup : %s (%s/%s verts) %s'%(groupname,len(vindices),len(vweights),'bone' if groupname in tokens else '')) + + #if debug : print('matrix : %s\n%s'%(type(mat),mat)) + + groupnames.append(groupname) + groupindices.append(vindices) + groupweights.append(vweights) + + ob = bel.mesh.write(obname,tokenname, + verts, edges, faces, + matslots, facemats, uvs, + groupnames, groupindices, groupweights, + use_smooth_groups, + naming_method) + + return ob + + ## here we go + + file = os.path.basename(filepath) + + print('\nimporting %s...'%file) + start = time.clock() + path = os.path.dirname(filepath) + filepath = os.fsencode(filepath) + data = open(filepath,'rb') + header = dXheader(data) + + if global_matrix is None: + global_matrix = mathutils.Matrix() + + if header : + minor, major, format, accuracy = header + + if show_geninfo : + print('\n%s directX header'%file) + print(' minor : %s'%(minor)) + print(' major : %s'%(major)) + print(' format : %s'%(format)) + print(' floats are %s bits'%(accuracy)) + + if format in [ 'txt' ] : #, 'bin' ] : + + ## FILE READ : STEP 1 : STRUCTURE + if show_geninfo : print('\nBuilding internal .x tree') + t = time.clock() + tokens, templates, tokentypes = dXtree(data,quickmode) + readstruct_time = time.clock()-t + if show_geninfo : print('builded tree in %.2f\''%(readstruct_time)) # ,end='\r') + + ## populate templates with datas + for tplname in templates : + readTemplate(data,tplname,show_templates) + + ## DATA TREE CHECK + if show_tree : + print('\nDirectX Data Tree :\n') + walk_dXtree(tokens.keys()) + + ## DATA IMPORTATION + if show_geninfo : + print('Root frames :\n %s'%rootTokens) + if parented : + import_dXtree(rootTokens) + else : + for tokenname in tokentypes['mesh'] : + obname = tokens[tokenname]['parent'] + # object and mesh naming : + # if parent frame has several meshes : obname = meshname = mesh token name, + # if parent frame has only one mesh : obname = parent frame name, meshname = mesh token name. + if obname : + meshcount = 0 + for child in getChilds(obname) : + if tokens[child]['type'] == 'mesh' : + meshcount += 1 + if meshcount == 2 : + obname = tokenname + break + else : obname = tokenname + + ob = getMesh(obname,tokenname,show_geninfo) + ob.matrix_world = global_matrix + + print('done in %.2f\''%(time.clock()-start)) # ,end='\r') + + else : + print('only .x files in text format are currently supported') + print('please share your file to make the importer evolve') + + + return {'FINISHED'} + \ No newline at end of file diff -Nru blender-2.61/release/scripts/addons_contrib/io_directx_bel/__init__.py blender-2.62/release/scripts/addons_contrib/io_directx_bel/__init__.py --- blender-2.61/release/scripts/addons_contrib/io_directx_bel/__init__.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/io_directx_bel/__init__.py 2012-02-15 19:43:59.000000000 +0000 @@ -0,0 +1,321 @@ +# Blender directX importer +bl_info = { + "name": "DirectX Importer", + "description": "Import directX Model Format (.x)", + "author": "Littleneo (Jerome Mahieux)", + "version": (0, 17), + "blender": (2, 6, 1), + "location": "File > Import > DirectX (.x)", + "warning": "", + "wiki_url": "https://github.com/littleneo/directX_blender/wiki", + "tracker_url": "https://github.com/littleneo/directX_blender/issues", + "category": "Import-Export", + "dependencies": "" +} + +if "bpy" in locals(): + import imp + if "import_x" in locals(): + imp.reload(import_x) + #if "export_x" in locals(): + # imp.reload(export_x) + + +import bpy +from bpy.props import (BoolProperty, + FloatProperty, + StringProperty, + EnumProperty, + ) +from bpy_extras.io_utils import (ExportHelper, + ImportHelper, + path_reference_mode, + axis_conversion, + ) + +''' +class DisplayTree(bpy.types.Operator) : + bl_idname = 'city.selector' + bl_label = 'preview' + + def execute(self,context) : +''' + +def hide_templates(self,context) : + if self.use_templates == False : self.show_templates = False + +def not_parented(self,context) : + self.parented = False + self.use_templates = False + +class ImportX(bpy.types.Operator, ImportHelper): + '''Load a Direct x File''' + bl_idname = "import_scene.x" + bl_label = "Import X" + bl_options = {'PRESET', 'UNDO'} + + filename_ext = ".x" + filter_glob = StringProperty( + default="*.x", + options={'HIDDEN'}, + ) + show_tree = BoolProperty( + name="Show x tokens tree", + description="display relationships between x items in the console", + default=False, + ) + show_templates = BoolProperty( + name="Show x templates", + description="display any token structure definition found in the .x file", + default=False, + ) + show_geninfo = BoolProperty( + name="Show processing", + description="display details for each imported thing", + default=False, + ) + + quickmode = BoolProperty( + name="Quick mode", + description="only retrieve mesh basics", + default=False, + update=not_parented + ) + + parented = BoolProperty( + name="Object Relationships", + description="import armatures, empties, rebuild parent-childs relations", + default=True, + ) + + use_templates = BoolProperty( + name="Use infile x templates", + description="parse any token structure definition found in the .x file, use it prior to standard ones", + default=False, + update=hide_templates + ) + + bone_maxlength = FloatProperty( + name="Bone length", + description="Bones max length", + min=0.1, max=10.0, + soft_min=0.1, soft_max=10.0, + default=1.0, + ) + + chunksize = EnumProperty( + name="Chunksize", + items=(('0', "all", ""), + ('16384', "16KB", ""), + ('8192', "8KB", ""), + ('4096', "4KB", ""), + ('2048', "2KB", ""), + ('1024', "1KB", ""), + ), + default='2048', + description="number of bytes red in a row", + ) + naming_method = EnumProperty( + name="Naming method", + items=(('0', "increment name if exists", "blender default"), + ('1', "use existing", "this only append new elements"), + ('2', "rename existing", "names are forced"), + ('3', "replace existing", ""), + ), + default='0', + description="behaviour when a name already exists in Blender Data", + ) + use_ngons = BoolProperty( + name="NGons", + description="Import faces with more then 4 verts as fgons", + default=True, + ) + use_edges = BoolProperty( + name="Lines", + description="Import lines and faces with 2 verts as edge", + default=True, + ) + use_smooth_groups = BoolProperty( + name="Smooth Groups", + description="Surround smooth groups by sharp edges", + default=True, + ) + + use_split_objects = BoolProperty( + name="Object", + description="Import OBJ Objects into Blender Objects", + default=True, + ) + use_split_groups = BoolProperty( + name="Group", + description="Import OBJ Groups into Blender Objects", + default=True, + ) + + use_groups_as_vgroups = BoolProperty( + name="Poly Groups", + description="Import OBJ groups as vertex groups", + default=False, + ) + + use_image_search = BoolProperty( + name="Image Search", + description="Search subdirs for any assosiated images " \ + "(Warning, may be slow)", + default=True, + ) + + split_mode = EnumProperty( + name="Split", + items=(('ON', "Split", "Split geometry, omits unused verts"), + ('OFF', "Keep Vert Order", "Keep vertex order from file"), + ), + ) + + global_clamp_size = FloatProperty( + name="Clamp Scale", + description="Clamp the size to this maximum (Zero to Disable)", + min=0.0, max=1000.0, + soft_min=0.0, soft_max=1000.0, + default=0.0, + ) + + axis_forward = EnumProperty( + name="Forward", + items=(('X', "Left (x)", ""), + ('Y', "Same (y)", ""), + ('Z', "Bottom (z)", ""), + ('-X', "Right (-x)", ""), + ('-Y', "Back (-y)", ""), + ('-Z', "Up (-z)", ""), + ), + default='-Z', + ) + + axis_up = EnumProperty( + name="Up", + items=(('X', "Right (x)", ""), + ('Y', "Back (y)", ""), + ('Z', "Same (z)", ""), + ('-X', "Left (-x)", ""), + ('-Y', "Front (-y)", ""), + ('-Z', "Bottom (-z)", ""), + ), + default='Y', + ) + + def execute(self, context): + from . import bel + from . import import_x + if self.split_mode == 'OFF': + self.use_split_objects = False + self.use_split_groups = False + else: + self.use_groups_as_vgroups = False + + keywords = self.as_keywords(ignore=("axis_forward", + "axis_up", + "filter_glob", + "split_mode", + )) + + keywords["naming_method"] = int(self.naming_method) + + global_matrix = axis_conversion(from_forward=self.axis_forward, + from_up=self.axis_up, + ).to_4x4() + keywords["global_matrix"] = global_matrix + + + bel.fs.saveOptions('import_scene.x', self.as_keywords(ignore=( + "filter_glob", + "filepath", + ))) + return import_x.load(self, context, **keywords) + + def draw(self, context): + layout = self.layout + + # import box + box = layout.box() + col = box.column(align=True) + col.label('Import Options :') + col.prop(self, "chunksize") + col.prop(self, "use_smooth_groups") + col.prop(self, "quickmode") + row = col.row() + row.enabled = not(self.quickmode) + row.prop(self, "parented") + #if self.parented : + row = col.row() + row.enabled = self.parented + row.prop(self, "bone_maxlength") + + # source orientation box + box = layout.box() + col = box.column(align=True) + col.label('Source Orientation :') + col.prop(self, "axis_forward") + col.prop(self, "axis_up") + + # naming methods box + box = layout.box() + col = box.column(align=True) + col.label('Naming Method :') + col.props_enum(self,"naming_method") + + # info/debug box + box = layout.box() + col = box.column(align=True) + col.label('Info / Debug :') + col.prop(self, "show_tree") + col.prop(self, "show_geninfo") + col.prop(self, "use_templates") + row = col.row() + row.enabled = self.use_templates + row.prop(self, "show_templates") + + #row = layout.row(align=True) + #row.prop(self, "use_ngons") + #row.prop(self, "use_edges") + + ''' + box = layout.box() + row = box.row() + row.prop(self, "split_mode", expand=True) + + row = box.row() + if self.split_mode == 'ON': + row.label(text="Split by:") + row.prop(self, "use_split_objects") + row.prop(self, "use_split_groups") + else: + row.prop(self, "use_groups_as_vgroups") + + row = layout.split(percentage=0.67) + row.prop(self, "global_clamp_size") + + layout.prop(self, "use_image_search") + ''' + +def menu_func_import(self, context): + self.layout.operator(ImportX.bl_idname, text="DirectX (.x)") + +#def menu_func_export(self, context): +# self.layout.operator(ExportX.bl_idname, text="DirectX (.x)") + +def register(): + bpy.utils.register_module(__name__) + + bpy.types.INFO_MT_file_import.append(menu_func_import) + #bpy.types.INFO_MT_file_export.append(menu_func_export) + + +def unregister(): + bpy.utils.unregister_module(__name__) + + bpy.types.INFO_MT_file_import.remove(menu_func_import) + #bpy.types.INFO_MT_file_export.remove(menu_func_export) + +if __name__ == "__main__": + register() diff -Nru blender-2.61/release/scripts/addons_contrib/io_directx_bel/README blender-2.62/release/scripts/addons_contrib/io_directx_bel/README --- blender-2.61/release/scripts/addons_contrib/io_directx_bel/README 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/io_directx_bel/README 2012-02-15 19:43:59.000000000 +0000 @@ -0,0 +1,262 @@ +a DirectX importer addon for Blender 2.6 + +first goals : + +. to import anything from an .x file. + obviously verts, faces but uv, armatures, weights, normals... +. import .x in binary format too + +horizon : +. export to .x or mod/co-maintain the existing x exporter. +. this project is also a prototype for a 'Blender Exchange Layer' project. + BEL would be a common layer logically located between an importer/exporter + addon and the blender data format, that would allow : + . to provide a common set of methods to retrieve/inject objects in Blender + . to provide a common set of transformation and selection tools between an + import/export script and Blender datas (rotate, rescale, filters...) + . to provide a common set of parsing helpers for new io addons + +PLY won't be used unfortunately (it's way too slow as far as I tested) + + +TO TEST THE SCRIPT : + . copy the 'io_directx_bel' in /scripts/addons or addons_contrib + . start blender + . enable then addon in user prefs > addons + . run the script with file > import > directX + +25/01/12 0.17 + . faster, 60% faster in some case : various loops improvements, infile templates parsing disabled by default + saw another bottleneck about data chunks as string but will wait for binary support for better point of view. + . interface cosmetics + +23/01/12 rc 0.16 +. committed to svn (and littleneo git as usual) +. corrected a bug about referenced token parenting +. corrected a bug about non parented meshes +. armatures/empties importation enabled by default +. last run importer options are saved in a 'last_run' preset, + so it can be replayed or saved under another name once a + particular .x profile has been defined +. tagged script for 2.6.1 + +12/01/12 rc 0.15 :) +. name conversion changed from 5 to 4 digits +. matname, imagename and texturename fixes : +. a path test is made at image import time with any existing data images, + so a same file cant be loaded twice wathever the naming method, / or \, rel or abs etc + (bel.material.new() and after line 835) +. image and texture names should be ok now (tested with : incrediblylongname.x) +. materials are replaced accordingly in existing objs when using the 'replace' naming method +. fyi, the Dx exporter has the following inconveniences : + . split linked faces into individual faces + . inversed uvmapping (y axis) ? + -> see testfiles/blender_x_export/incrediblylongname.x + +29 and 31/12/11 +. Cosmetics, code cleaning and optimizations +. bpy.ops.object.select_name methods replaced with + ob.select = True + bpy.context.scene.objects.active = ob +. corrected a big bug about tokens info appending in dXtree() +. new bpyname() method in bel module. removed bel.common + +26/12/11 +. armature import and bone max. length option + +23/11/11 +. contrib candidate :) +. solved some naming cases, added bel methods. +. added experimental option about parenting (no armature yet just empties, when needed) +. a bit faster +. added some test files (empty parenting, armature etc) + +22/11/11 +campbell feedback (cont): +. added naming methods as options (default is blender name inc. if name exists) + me and ob remove() should be ok with special cases (empties, mesh with multi-users) +. improved ui + + +21/11/11 +campbell feedback : +. converted immutables to tuples : templates_x.py and some other vars. + http://stackoverflow.com/questions/3340539/why-tuple-is-faster-than-list +. dprint() (console debug) removed, replaced by a inloop tests (a bit faster) + I'd like to keep it for now for easier debug (eg user feedbacks with 'processing' option) + +19/11/11 +. object parenting support. parsing the x tree from roots using import_dxtree() + actually faster than before + +16/11/11 +. weight group import +. improved ui a bit and console logs +. x matrices to blender ones conversion + +14/11/11 +. global matrix options +. added messy code about binary (not working) + +11/11/11 +. import materials and textures (basics) : uv and image mapped (multitex mode) + and material created with tex slot if any. alpha should be ok.. ? +. added a smooth options +. better tolerance with faulty .x (upper/lower case of template names) +. token names length from x to blender conversion should be ok also (long name cases) +. corrected a parser pointer error after one array parsing case. +. added more templates (for mat and tex support) +. removed texture files from repo in testfile (tex does not match meshes ) + added some other x files for further tests in binary and compressed format + ( http://assimp.svn.sourceforge.net/viewvc/assimp/trunk/test/models/X/ ) + +08/11/11 +. turned into an addon (fork from obj import so unused functions atm) + enable it in addon, then file > import > directx +. splitted directx parser (io_directx_bel folder) and bel draft + the bel folder is intended to be located in /scripts/modules (shared components) + but it's ok in scripts/addons too (tbd) + bel folder (will) includes anything related to blender data helper (read/write) +. corrected duplicated quotes for x string type + +07/11/11 +. uv import +. generic directx token parser. templates items are used to read datas of any token type + a bit slower but cool since it should support non strict standard directx files + virtually it can retrieve everything from now supposing the template is know + by default or given in the file. calls are now like : + nbslots, mats = readToken('MeshMaterialList001') or + uv = readToken('uv001') or + nVerts, verts, nFaces, faces = readToken('Hydralisk_backbone1') etc +. removed the specific mesh parser the 'rigid' file is the last before mutation to + generic parser. a bit faster but harder to make evolve or adapt. keep it as a faster + strict 'branch' +. added some default templates + goals / wip : + . to compare template declaration in file and default one. + so either use the default one (strict) or the .x one (could differ) + . use by the generic data parser to avoid a parser for each kind of token +. cleaner code (grouping methods, function names, docs etc) + functions separated from calls + renamed token dict as tokens etc +. added tweaks at the beginning of the file : + chunksize = 1024 # size of file streams red in a row + quickmode = False # this to only find meshes (no parenting, no other tokens than Mesh ones) + showtree = False # display the entire token tree in the console + showtemplate = True # display template datas found in file +. added a patch for malformed datas of vertices (meshFaces) : + # patch for malformed datas not completely clear yet ( I guess + # there's bunch of us when looking at meshface syntax in .x files) : + # when array members are like 3;v0,v1,v2;, + # and not like 3;v0;v1;v2;, depending on template declarations. + # http://paulbourke.net/dataformats/directx/#xfilefrm_Use_of_commas +. the script now generates linked faces (was not my fault !) + > it seems Dx always separate each face : + so it defines (vert * linked faces) verts for one needed vert + the readvertices loop now remove duplicates at source + it uses a verts lookup list to redirect vert id defined in faces + +06/11/11 +. vertices and faces imported from each test files +. added some info to test yourself in README +. switched to binary for .x as text to retrieve eol (pointer bugs). should be ok whatever it's win, mac or unix text format, + also works with mixed eol. + it seems python 3.1 can't return a 'line' when data.realine() when read mode is 'rb' (U default and universal ? really ? ;) ) + when file has mac eol (\r) + -> read(1024) in binary, decode, and replace any \r with \n. yes, it doubles lines for windows and lines value is wrong for now + -> but the used pointer value is always ok now whatever the file format and still way faster than a data.tell() + see CRCF folder to compare output wispwind.x by format. +. files are still splitted into chunks (1024 B) and readable as lines +. references : added 'user' fields when token is used. users store a reference with their childs but with a '*' tag at chr0. + the tree reflects the changes +. now read anything and add it to the 'tree'. this includes unknow tokens. +. references are recognized. by reference I mean fields like { cube0 } rather than an inline frame cube0 { + declaration. + I don't know if one item can be referenced several time or referenced before declaration + should be.. waiting for a case. for now only one 'parent' token, messages will show up + multi references to one token if cases arise. +. more permissive syntax : 'frame spam{', 'frame spam egg{', 'frame spam egg {'.. +. comments are recognized (inlines ones not done yet, since still no useful data red :) ) +. header is red +. found other .x test files here : + http://www.xbdev.net/3dformats/x/xfileformat.php + created from 3ds max +. added .x files in repo. line 70 and following to switch. +. some token comes with no names, add a noname<00000> to them +. console gives line number (more useful than char position I guess) + + +05/11/11 day 0 : + +. made some disapointing test with ply (from a speed point of view, else it looks really cool) +. made my own parser +. nothing imported for now, it's more about self-eduction to .x and concept +. but it reads the .x structure and can gather some info + +resource gathered : + +http://paulbourke.net/dataformats/directx/ +http://www.informikon.com/various/the-simplest-skeletal-animation-possible.html +http://msdn.microsoft.com/en-us/library/windows/desktop/bb173011%28v=VS.85%29.aspx +http://www.toymaker.info/Games/index.html + + + +step 1 : read main structure : + + read main token names (any 'template', any 'frame', any 'mesh') + stores names in a token directory : + token['template'] for templates : + token['template'][templatename] + token['template'][templatename]['pointer'] (int) chr position in .x file (tell() like*) + token['template'][templatename]['line'] (int) line number in .x file + token['frame'] for frame and mesh type : + token['template'][frame or mesh name] + token['template'][frame or mesh name]['pointer'] (int) chr position in .x file (tell() like*) + token['template'][frame or mesh name]['line'] (int) line number in .x file + token['template'][frame or mesh name]['type'] (str) 'ob/bone' or 'mesh' + token['template'][frame or mesh name]['parent'] (str) frame parent of current item + token['template'][frame or mesh name]['childs'] (str list) list of child frame or mesh names + token['template'][frame or mesh name]['matrix'] (int) for now chr position of FrameTransformMatrix + +at the end of step 1 the script prints a tree of these datas + +step 2 : read template definitions : + + for each template in dict, populate definitions in it. + it creates new fields in each token['template'][templatename] + according to values found in .x : + token['template'][templatename]['uuid'] (str) + token['template'][templatename]['members']['name'] (str) member name + token['template'][templatename]['members']['type'] (str) DWORD,FLOAT etc keywords or template name + token['template'][templatename]['restriction'] (str) 'open' , 'closed' , or the specidied (restricted) value + +that's all for now. + +idea would be to allow 2 steps importation and random access to file : + + . first the file is quickly parsed. we only retrieve main info, nothing about verts, faces etc + info like number of mats, textures, objects/mesh/bone trees + for now : 150000 lines in 5 secs for step 1 + . then user select what to import + . then the script retrieve selected datas according to selection, using the 'pointer' value + to seek() to the needed data, then grab/parse/translate in something usable. + . template are used at this point to know how to parse a specific part (adaptive parser) + + so far this looks fast. + +tested on windows. can be important because of eol and the code I wrote to compute pointer value. +(data.tell() is slow) +only one .x file tested, header is : xof 0303txt 0032 (windows \r\n eol) + +don't know a lot about .x format : + +uuid : + are the member/restriction always the same for a same uuid/template ? + template name can vary for a same uuid ? +syntax : + blank lines IN a stream of a {} section, after ; ? + comments // and # IN a stream of data ? + '{' and '' and '}' on the same line or '{' '}' are always unique ? + + \ No newline at end of file diff -Nru blender-2.61/release/scripts/addons_contrib/io_directx_bel/templates_x.py blender-2.62/release/scripts/addons_contrib/io_directx_bel/templates_x.py --- blender-2.61/release/scripts/addons_contrib/io_directx_bel/templates_x.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/io_directx_bel/templates_x.py 2012-02-15 19:43:59.000000000 +0000 @@ -0,0 +1,162 @@ +# dx 'strict' templates +# lower() since some apps does not respect it, +# and to keep the 'as it should be' syntax + +defaultTemplates={} +templatesConvert={} + +# mesh template +defaultTemplates['Mesh'.lower()] = { + 'uuid' : '<3d82ab44-62da-11cf-ab39-0020af71e433>', + 'restriction' : '[...]', + 'members' : ( + ('dword', 'nVertices'), + ('array', 'vector', 'vertices[nVertices]'), + ('dword', 'nFaces'), + ('array', 'MeshFace', 'faces[nFaces]'), + ) +} + +defaultTemplates['FrameTransformMatrix'.lower()] = { + 'uuid' : '', + 'restriction' : 'closed', + 'members' : ( + ('matrix4x4', 'frameMatrix'), + ) +} + +templatesConvert['matrix4x4'] = 'Matrix( [fields[0][0:4], fields[0][4:8] , fields[0][8:12] , fields[0][12:16]] )' +defaultTemplates['matrix4x4'.lower()] = { + 'uuid' : '', + 'restriction' : 'closed', + 'members' : ( + ('array', 'float', 'matrix[16]'), + ) +} + +#returns [ [vid0,vid1,vid2], [vid1,vid2,vid3,vid4] .. ] +templatesConvert['meshface'] = 'fields[1]' +defaultTemplates['MeshFace'.lower()] = { + 'uuid' : '<3d82ab5f-62da-11cf-ab39-0020af71e433>', + 'restriction' : 'closed', + 'members' : ( + ('dword', 'nFaceVertexIndices'), + ('array', 'dword', 'faceVertexIndices[nFaceVertexIndices]') + ) +} + +defaultTemplates['vector'.lower()] = { + 'uuid' : '<3d82ab5e-62da-11cf-ab39-0020af71e433>', + 'restriction' : 'closed', + 'members' : ( + ('float', 'x'), + ('float', 'y'), + ('float', 'z') + ) +} + +defaultTemplates['Coords2d'.lower()] = { + 'uuid' : '', + 'restriction' : 'closed', + 'members' : ( + ('float', 'u'), + ('float', 'v') + ) +} + +# returns [ uvAsVertsLocation ] +templatesConvert['meshtexturecoords'] = 'fields[1]' +defaultTemplates['MeshTextureCoords'.lower()] = { + 'uuid' : '', + 'restriction' : 'closed', + 'members' : ( + ('dword', 'nTextureCoords'), + ('array', 'Coords2d', 'textureCoords[nTextureCoords]') + ) +} + +defaultTemplates['meshnormals'.lower()] = { + 'uuid' : '', + 'restriction' : 'closed', + 'members' : ( + ('dword', 'nNormals'), + ('array', 'vector', 'normals[nNormals]'), + ('dword', 'nFaceNormals'), + ('array', 'MeshFace', 'faceNormals[nFaceNormals]') + ) +} + +# returns [ nMaterials, [ materialindex of each face ] ] +templatesConvert['meshmateriallist'] = '[fields[0],fields[2]]' +defaultTemplates['MeshMaterialList'.lower()] = { + 'uuid' : '', + 'restriction' : '[Material]', + 'members' : ( + ('dword', 'nMaterials'), + ('dword', 'nFaceIndexes'), + ('array', 'dword', 'faceIndexes[nFaceIndexes]') + ) +} + +defaultTemplates['Material'.lower()] = { + 'uuid' : '<3d82ab4d-62da-11cf-ab39-0020af71e433>', + 'restriction' : '[...]', + 'members' : ( + ('colorrgba', 'faceColor'), + ('float', 'power'), + ('colorrgb', 'specularColor'), + ('colorrgb', 'emissiveColor') + ) +} + +templatesConvert['colorrgba'] = 'fields[:3],fields[3]' +defaultTemplates['colorrgba'.lower()] = { + 'uuid' : '<35ff44e0-6c7c-11cf-8f52-0040333594a3>', + 'restriction' : 'closed', + 'members' : ( + ('float', 'red'), + ('float', 'green'), + ('float', 'blue'), + ('float', 'alpha') + ) +} + +defaultTemplates['colorrgb'.lower()] = { + 'uuid' : '', + 'restriction' : 'closed', + 'members' : ( + ('float', 'red'), + ('float', 'green'), + ('float', 'blue') + ) +} + +defaultTemplates['TextureFilename'.lower()] = { + 'uuid' : '', + 'restriction' : 'closed', + 'members' : ( + ('string', 'filename'), + ) +} + +defaultTemplates['SkinWeights'.lower()] = { + 'uuid' : '<6f0d123b-bad2-4167-a0d0-80224f25fabb>', + 'restriction' : 'closed', + 'members' : ( + ('string', 'transformNodeName'), + ('dword', 'nWeights'), + ('array', 'dword', 'vertexIndices[nWeights]'), + ('array', 'float', 'weights[nWeights]'), + ('matrix4x4', 'matrixOffset') + ) +} + +defaultTemplates['XSkinMeshHeader'.lower()] = { + 'uuid' : '3cf169ce-ff7c-44ab-93c0-f78f62d172e2', + 'restriction' : 'closed', + 'members' : ( + ('word', 'nMaxSkinWeightsPerVertex'), + ('word', 'nMaxSkinWeightsPerFace'), + ('word', 'nBones') + ) +} diff -Nru blender-2.61/release/scripts/addons_contrib/io_export_dxf/__init__.py blender-2.62/release/scripts/addons_contrib/io_export_dxf/__init__.py --- blender-2.61/release/scripts/addons_contrib/io_export_dxf/__init__.py 2011-12-13 19:59:27.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/io_export_dxf/__init__.py 2012-02-15 19:43:46.000000000 +0000 @@ -20,7 +20,6 @@ "author": "Remigiusz Fiedler (AKA migius), Vaclav Klecanda", "version": (2, 1, 2), "blender": (2, 6, 0), - "api": 40791, "location": "File > Export > Autodesk (.dxf)", "description": "The script exports Blender geometry to DXF format r12 version.", "warning": "Only subset of DXF specification is supported, work in progress.", diff -Nru blender-2.61/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/mesh_exporter.py blender-2.62/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/mesh_exporter.py --- blender-2.61/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/mesh_exporter.py 2011-12-13 19:59:27.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/mesh_exporter.py 2012-02-15 19:43:45.000000000 +0000 @@ -108,7 +108,7 @@ args = copy.copy(kwargs) args['points'] = points entities.append(('Line', args)) - elif c in ('POLYFACE','POLYLINE'): + elif c in {'POLYFACE','POLYLINE'}: if faces and allpoints: #TODO: purge allpoints: left only vertices used by faces # if exportsettings['verbose']: diff -Nru blender-2.61/release/scripts/addons_contrib/io_export_md3.py blender-2.62/release/scripts/addons_contrib/io_export_md3.py --- blender-2.61/release/scripts/addons_contrib/io_export_md3.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/io_export_md3.py 2012-02-15 19:43:59.000000000 +0000 @@ -21,7 +21,6 @@ 'author': 'Xembie', 'version': (0, 7), 'blender': (2, 5, 3), - 'api': 31667, 'location': 'File > Export', 'description': 'Save a Quake Model 3 File)', 'warning': '', # used for warning icon and text in addons panel diff -Nru blender-2.61/release/scripts/addons_contrib/io_import_BrushSet.py blender-2.62/release/scripts/addons_contrib/io_import_BrushSet.py --- blender-2.61/release/scripts/addons_contrib/io_import_BrushSet.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/io_import_BrushSet.py 2012-02-15 19:43:59.000000000 +0000 @@ -16,104 +16,129 @@ # # ***** END GPL LICENCE BLOCK ***** +# ----------------------------------------------------------------------------# + ''' todo: - add file selection for single and multiple files changelog: - "version": (1,1,4), - filename will be used as texture name (still limited by stringlength) + "version": (1,1,4), + filename will be used as texture name (still limited by stringlength) - "version": (1,1,3), - fixed operator and registration - added tracker and wiki url\ - + "version": (1,1,3), + fixed operator and registration + added tracker and wiki url\ + version": (1,1,2) - replaced image.new() with image.load() - changed addon category - removed some unused/old code - + replaced image.new() with image.load() + changed addon category + removed some unused/old code + version":1.11: - added type arg to texture.new() [L48] - cleared default filename + added type arg to texture.new() [L48] + cleared default filename ''' +# ----------------------------------------------------------------------------# + import bpy import os from bpy.props import * #addon description bl_info = { - "name": "import BrushSet", - "author": "Daniel Grauer", - "version": (1,1,4), - "blender": (2, 5, 6), - "api": "", - "category": "Import-Export", - "location": "File > Import > BrushSet", - "description": "imports all image files from a folder", - "warning": '', # used for warning icon and text in addons panel - "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Import-Export/BrushSet", - "tracker_url": "http://projects.blender.org/tracker/index.php?func=detail&aid=25702&group_id=153&atid=467", - } + "name": "import BrushSet", + "author": "Daniel Grauer", + "version": (1, 1, 5), + "blender": (2, 5, 6), + "category": "Import-Export", + "location": "File > Import > BrushSet", + "description": "imports all image files from a folder", + "warning": '', # used for warning icon and text in addons panel + "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Import-Export/BrushSet", + "tracker_url": "http://projects.blender.org/tracker/index.php?func=detail&aid=25702&group_id=153&atid=467", + } + +print(" ") +print("*------------------------------------------------------------------------------*") +print("* initializing BrushSet import *") +print("*------------------------------------------------------------------------------*") +print(" ") #extension filter (alternative use mimetypes) -ext_list = ['jpg','bmp', 'iris', 'png', 'jpeg', 'targa', 'tga']; +ext_list = ['jpg', + 'bmp', + 'iris', + 'png', + 'jpeg', + 'targa', + 'tga']; def LoadBrushSet(filepath, filename): - for file in os.listdir(filepath): - path=(filepath+file) - #get folder name - (f1,f2) = os.path.split(filepath) - (f3,foldername) = os.path.split(f1) - - texturename = foldername # file "texture" foldername - - #filter ext_list - if file.split('.')[-1].lower() in ext_list: - #create new texture - texture = bpy.data.textures.new(texturename, 'IMAGE') #watch it, string limit 21 ?! - - #create new image - image = bpy.data.images.load(path) - image.source = "FILE" - image.filepath = path - bpy.data.textures[texture.name].image = image - - print("imported: "+file) - print("Brush Set imported!") + for file in os.listdir(filepath): + path = (filepath + file) + #get folder name + (f1, f2) = os.path.split(filepath) + (f3, foldername) = os.path.split(f1) + + texturename = foldername # file "texture" foldername + + #filter ext_list + if file.split('.')[-1].lower() in ext_list: + #create new texture + texture = bpy.data.textures.new(texturename, 'IMAGE') #watch it, string limit 21 ?! + + #create new image + image = bpy.data.images.load(path) + image.source = "FILE" + image.filepath = path + bpy.data.textures[texture.name].image = image + + print("imported: " + file) + print("Brush Set imported!") + +# ----------------------------------------------------------------------------# class BrushSetImporter(bpy.types.Operator): - '''Load Brush Set''' - bl_idname = "import_image.brushset" - bl_label = "Import BrushSet" - - filename = StringProperty(name="File Name", description="filepath", default="", maxlen=1024, options={'ANIMATABLE'}, subtype='NONE') - filepath = StringProperty(name="File Name", description="filepath", default="", maxlen=1024, options={'ANIMATABLE'}, subtype='NONE') - - def execute(self, context): - LoadBrushSet(self.properties.filepath, self.properties.filename) - return {'FINISHED'} - - def invoke(self, context, event): - wm = context.window_manager - wm.fileselect_add(self) - return {'RUNNING_MODAL'} + '''Load Brush Set''' + bl_idname = "import_image.brushset" + bl_label = "Import BrushSet" + + filename = StringProperty(name="File Name", description="filepath", default="", maxlen=1024, options={'ANIMATABLE'}, subtype='NONE') + filepath = StringProperty(name="File Name", description="filepath", default="", maxlen=1024, options={'ANIMATABLE'}, subtype='NONE') + + def execute(self, context): + LoadBrushSet(self.properties.filepath, self.properties.filename) + return {'FINISHED'} + + def invoke(self, context, event): + wm = context.window_manager + wm.fileselect_add(self) + return {'RUNNING_MODAL'} + +# ----------------------------------------------------------------------------# def menu_func(self, context): - #clear the default name for import - default_name = "" + #clear the default name for import + default_name = "" + + self.layout.operator(BrushSetImporter.bl_idname, text="Brush Set").filename = default_name - self.layout.operator(BrushSetImporter.bl_idname, text="Brush Set").filename = default_name +# ----------------------------------------------------------------------------# def register(): - bpy.utils.register_module(__name__) - bpy.types.INFO_MT_file_import.append(menu_func) + bpy.utils.register_module(__name__) + bpy.types.INFO_MT_file_import.append(menu_func) def unregister(): - bpy.utils.unregister_module(__name__) - bpy.types.INFO_MT_file_import.remove(menu_func) + bpy.utils.unregister_module(__name__) + bpy.types.INFO_MT_file_import.remove(menu_func) if __name__ == "__main__": - register() + register() + +print(" ") +print("*------------------------------------------------------------------------------*") +print(" ") diff -Nru blender-2.61/release/scripts/addons_contrib/io_import_fbx.py blender-2.62/release/scripts/addons_contrib/io_import_fbx.py --- blender-2.61/release/scripts/addons_contrib/io_import_fbx.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/io_import_fbx.py 2012-02-15 19:43:59.000000000 +0000 @@ -23,7 +23,6 @@ "author": "Campbell Barton", "version": (0, 0, 1), "blender": (2, 5, 6), - "api": 32516, "location": "File > Import ", "description": "This script is WIP and not intended for general use yet!", "warning": "Work in progress", @@ -250,12 +249,12 @@ blen_faces_edges = [] # faces that have a length of 2 blen_poly_mapping = {} poly_idx = 0 - + for idx, f in enumerate(faces): - + if f < 0: face.append(f ^ -1) - edge_points[idx] = [face[-1],face[0]] + edge_points[idx] = [face[-1], face[0]] face = [] if len(blen_faces[-1]) == 2: @@ -265,25 +264,24 @@ blen_faces.append(face) poly_idx += 1 - - else: + else: face.append(f) edge_final = [] - if(len(faces) == 2): # Special case if there is only one edge in scene. + if len(faces) == 2: # Special case if there is only one edge in scene. edge1 = faces[0] - if(edge1<0): - edge1 ^= -1 + if edge1 < 0: + edge1 ^= -1 edge2 = faces[1] - if(edge2<0): + if edge2 < 0: edge2 ^= -1 - edge_final.append((edge1,edge2)) - - else: # More than one edges. + edge_final.append((edge1, edge2)) + + else: # More than one edges for idx, e in enumerate(edges): - if (faces[e]<0): #If this is the faces last point, use edge_points to create edge between last and first points of face + if faces[e] < 0: # If this is the faces last point, use edge_points to create edge between last and first points of face edge1 = edge_points[e][0] edge2 = edge_points[e][1] else: @@ -293,10 +291,9 @@ edge2 ^= -1 edge_final.append((edge1, edge2)) - + if not blen_faces[-1]: del blen_faces[-1] - me.from_pydata(blen_verts, edge_final, blen_faces) me.update() @@ -321,8 +318,6 @@ else: print("WARNING: %s, unsupported smoothing type: %s" % (fbx_name, type)) - - # Handle edge weighting for i in tag_get_iter(value2, "LayerElementEdgeCrease"): i = i[1] @@ -343,12 +338,12 @@ else: print("WARNING: %s, unsupported smoothing type: %s" % (fbx_name, type)) - # Create the Uv-sets + # Create the Uv-sets for i in tag_get_iter(value2, "LayerElementUV"): - i=i[1] + i = i[1] uv_in = 0 uv_face = [] - uv_name = tag_get_single(i,"Name")[1] + uv_name = tag_get_single(i, "Name")[1] print(uv_name) uv_verts = tag_get_single(i, "UV")[1] uv_index = tag_get_single(i, "UVIndex")[1] @@ -356,12 +351,12 @@ if(uv_verts): blen_uv_verts = [uv_verts[i - 2:i] for i in range(2, len(uv_verts) + 2, 2)] - for ind,uv_i in enumerate(uv_index): + for ind, uv_i in enumerate(uv_index): if(uv_i == -1): - uv_face.append([-0.1,-0.1]) + uv_face.append([-0.1, -0.1]) else: uv_face.append(blen_uv_verts[uv_i]) - uv_in +=1 + uv_in += 1 me.uv_textures.new(uv_name) uv_layer = me.uv_textures[-1].data @@ -370,16 +365,15 @@ for fi, uv in enumerate(uv_layer): if(len(me.faces[fi].vertices) == 4): uv.uv1 = uv_face[uv_counter] - uv.uv2 = uv_face[uv_counter+1] - uv.uv3 = uv_face[uv_counter+2] - uv.uv4 = uv_face[uv_counter+3] + uv.uv2 = uv_face[uv_counter + 1] + uv.uv3 = uv_face[uv_counter + 2] + uv.uv4 = uv_face[uv_counter + 3] uv_counter += 4 else: uv.uv1 = uv_face[uv_counter] - uv.uv2 = uv_face[uv_counter+1] - uv.uv3 = uv_face[uv_counter+2] + uv.uv2 = uv_face[uv_counter + 1] + uv.uv3 = uv_face[uv_counter + 2] uv_counter += 3 - obj = bpy.data.objects.new(fbx_name, me) base = scene.objects.link(obj) diff -Nru blender-2.61/release/scripts/addons_contrib/io_import_lipSync_Importer.py blender-2.62/release/scripts/addons_contrib/io_import_lipSync_Importer.py --- blender-2.61/release/scripts/addons_contrib/io_import_lipSync_Importer.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/io_import_lipSync_Importer.py 2012-02-15 19:43:59.000000000 +0000 @@ -19,9 +19,8 @@ bl_info = { "name": "LipSync Importer & Blinker", "author": "Yousef Harfoush - bat3a ;)", - "version": (0, 4, 0), - "blender": (2, 5, 9), - "api": 39900, + "version": (0, 5, 0), + "blender": (2, 6, 2), "location": "3D window > Tool Shelf", "description": "Plot Moho (Papagayo, Jlipsync, Yolo) file to frames and adds automatic blinking", "warning": "", @@ -35,8 +34,8 @@ from bpy.props import * from bpy.props import IntProperty, FloatProperty, StringProperty -global phnmlst -phnmlst="nothing" +global lastPhoneme +lastPhoneme="nothing" # truning off relative path - it causes an error if it was true if bpy.context.user_preferences.filepaths.use_relative_paths == True: @@ -48,32 +47,111 @@ scn = bpy.context.scene obj = bpy.context.object - global blink, blinkphnm + if scn.regMenuTypes.enumBlinkTypes == '0': + modifier = 0 + elif scn.regMenuTypes.enumBlinkTypes == '1': + modifier = scn.blinkMod + + #creating keys with blinkNm count + for y in range(scn.blinkNm): + frame = y * scn.blinkSp + int(random()*modifier) + createShapekey('blink', frame) + +# -----------code contributed by dalai felinto adds armature support modified by me------------------- + +bone_keys = { +"AI": ('location', 0), +"E": ('location', 1), +"FV": ('location', 2), +"L": ('rotation_euler', 0), +"MBP": ('rotation_euler', 1), +"O": ('rotation_euler', 2), +"U": ('scale', 0), +"WQ": ('scale', 1), +"etc": ('scale', 2), +"rest": ('ik_stretch', -1) +} + +def lipsyncerBone(): + # reading imported file & creating keys + object = bpy.context.object + scene = bpy.context.scene + bone = bpy.context.active_pose_bone + + resetBoneScale(bone) + + f=open(scene.fpath) # importing file + f.readline() # reading the 1st line that we don"t need + + for line in f: + # removing new lines + lsta = re.split("\n+", line) + + # building a list of frames & shapes indexes + lst = re.split(":? ", lsta[0])# making a list of a frame & number + frame = int(lst[0]) + + for key,attribute in bone_keys.items(): + if lst[1] == key: + createBoneKeys(key, bone, attribute, frame) + +def resetBoneScale(bone): + # set the attributes used by papagayo to 0.0 + for attribute,index in bone_keys.values(): + if index != -1: + #bone.location[0] = 0.0 + exec("bone.%s[%d] = %f" % (attribute, index, 0.0)) + else: + exec("bone.%s = %f" % (attribute, 0.0)) - blink="off" - blinkphnm=-1 +def addBoneKey(bone, data_path, index=-1, value=None, frame=bpy.context.scene.frame_current, group=""): + # set a value and keyframe for the bone + # it assumes the 'bone' variable was defined before + # and it's the current selected bone + + if value != None: + if index != -1: + # bone.location[0] = 0.0 + exec("bone.%s[%d] = %f" % (data_path, index, value)) + else: + exec("bone.%s = %f" % (data_path, value)) - sk=len(obj.data.shape_keys.key_blocks) + # bone.keyframe_insert("location", 0, 10.0, "Lipsync") + exec('bone.keyframe_insert("%s", %d, %f, "%s")' % (data_path, index, frame, group)) - # searching for blink shapekey index - for x in range(sk): - obj.active_shape_key_index = x - if obj.active_shape_key.name=="blink": blink="on"; blinkphnm=x - - if blinkphnm!=-1: - - if scn.remnuTypes.enumBlinks == '0': - modifier = 0 - elif scn.remnuTypes.enumBlinks == '1': - modifier = scn.blinkMod +# creating keys with offset and eases for a phonem @ the Skframe +def createBoneKeys(phoneme, bone, attribute, frame): + global lastPhoneme + + scene = bpy.context.scene + object = bpy.context.object + + offst = scene.offset # offset value + skVlu = scene.skscale # shape key value + + #in case of Papagayo format + if scene.regMenuTypes.enumFileTypes == '0' : + frmIn = scene.easeIn # ease in value + frmOut = scene.easeOut # ease out value + hldIn = scene.holdGap # holding time value - #creating keys with blinkNm count - for y in range(scn.blinkNm): - - blinkfrm = y * scn.blinkSp + int(random()*modifier) - - crtkey(blinkphnm, blinkfrm) + #in case of Jlipsync format or Yolo + elif scene.regMenuTypes.enumFileTypes == '1' : + frmIn = 1 + frmOut = 1 + hldIn = 0 + # inserting the In key only when phonem change or when blinking + if lastPhoneme!=phoneme or eval(scene.regMenuTypes.enumModeTypes) == 1: + addBoneKey(bone, attribute[0], attribute[1], 0.0, offst+frame-frmIn, "Lipsync") + + addBoneKey(bone, attribute[0], attribute[1], skVlu, offst+frame, "Lipsync") + addBoneKey(bone, attribute[0], attribute[1], skVlu, offst+frame+hldIn, "Lipsync") + addBoneKey(bone, attribute[0], attribute[1], 0.0, offst+frame+hldIn+frmOut, "Lipsync") + + lastPhoneme=phoneme + +# ------------------------------------------------------------------------------- # reading imported file & creating keys def lipsyncer(): @@ -90,85 +168,57 @@ lsta = re.split("\n+", line) # building a list of frames & shapes indexes - lst = re.split(":? ", lsta[0])# making a list of a frame number & - frm = int(lst[0]) + lst = re.split(":? ", lsta[0])# making a list of a frame & number + frame = int(lst[0]) - sk=len(obj.data.shape_keys.key_blocks) - for x in range(sk): - obj.active_shape_key_index = x - oask=obj.active_shape_key.name - if lst[1]==oask: crtkey(x, frm) + for key in obj.data.shape_keys.key_blocks: + if lst[1] == key.name: + createShapekey(key.name, frame) -# retargetting?? ------WIP -def retargeter(): - - scn = bpy.context.scene - - f=open(scn.fpath) # importing file - f.readline() # reading the 1st line that we don"t need - - for line in f: - # removing new lines - lsta = re.split("\n+", line) - - # building a list of frames & shapes indexes - lst = re.split(":? ", lsta[0])# making a list of a frame number & - frm = int(lst[0]) - - sk=len(obj.data.shape_keys.key_blocks) - - for x in range(sk): - obj.active_shape_key_index = x - oask=obj.active_shape_key.name - if lst[1]==oask: crtkey(x, frm) - -# creating keys with offset and eases for a phonem @ the Skframe -def crtkey(phoneme, Skframe): +# creating keys with offset and eases for a phonem @ the frame +def createShapekey(phoneme, frame): - global phnmlst + global lastPhoneme scn = bpy.context.scene obj = bpy.context.object - objSK=obj.data.shape_keys + objSK = obj.data.shape_keys - #setting the active shape key to phonem - obj.active_shape_key_index=phoneme - offst = scn.offset # offset value skVlu = scn.skscale # shape key value #in case of Papagayo format - if scn.remnuTypes.enumFiles == '0' : + if scn.regMenuTypes.enumFileTypes == '0' : frmIn = scn.easeIn # ease in value frmOut = scn.easeOut # ease out value hldIn = scn.holdGap # holding time value #in case of Jlipsync format or Yolo - elif scn.remnuTypes.enumFiles == '1' : + elif scn.regMenuTypes.enumFileTypes == '1' : frmIn = 1 frmOut = 1 hldIn = 0 # inserting the In key only when phonem change or when blinking - if phnmlst!=phoneme or eval(scn.mnuFunc) == 1: - obj.active_shape_key.value=0.0 + if lastPhoneme!=phoneme or eval(scn.regMenuTypes.enumModeTypes) == 1: + objSK.key_blocks[phoneme].value=0.0 objSK.key_blocks[phoneme].keyframe_insert("value", - -1, offst+Skframe-frmIn, "Lipsync") + -1, offst+frame-frmIn, "Lipsync") - obj.active_shape_key.value=skVlu + objSK.key_blocks[phoneme].value=skVlu objSK.key_blocks[phoneme].keyframe_insert("value", - -1, offst+Skframe, "Lipsync") + -1, offst+frame, "Lipsync") - obj.active_shape_key.value=skVlu + objSK.key_blocks[phoneme].value=skVlu objSK.key_blocks[phoneme].keyframe_insert("value", - -1, offst+Skframe+hldIn, "Lipsync") + -1, offst+frame+hldIn, "Lipsync") - obj.active_shape_key.value=0.0 + objSK.key_blocks[phoneme].value=0.0 objSK.key_blocks[phoneme].keyframe_insert("value", - -1, offst+Skframe+hldIn+frmOut, "Lipsync") + -1, offst+frame+hldIn+frmOut, "Lipsync") - phnmlst=phoneme - + lastPhoneme = phoneme + # lipsyncer operation start class btn_lipsyncer(bpy.types.Operator): bl_idname = 'lipsync.go' @@ -178,149 +228,166 @@ def execute(self, context): scn = context.scene - obj = context.object + obj = context.active_object - # testing if a mesh object with shape keys is selected - if obj!=None and obj.type=="MESH": - if obj.data.shape_keys!=None: - if scn.fpath!='': lipsyncer() - else: print ("select a Moho file") - else: print("add shape keys PLEASE") - else: print ("Object is not mesh or not selected ") + # testing if object is valid + if obj!=None: + if obj.type=="MESH": + if obj.data.shape_keys!=None: + if scn.fpath!='': lipsyncer() + else: print ("select a Moho file") + else: print("No shape keys") + + elif obj.type=="ARMATURE": + if 1:#XXX add prop test + if scn.fpath!='': lipsyncerBone() + else: print ("select a Moho file") + else: print("Create Pose properties") + + else: print ("Object is not a mesh ot bone") + else: print ("Select object") return {'FINISHED'} # blinker operation start class btn_blinker(bpy.types.Operator): bl_idname = 'blink.go' bl_label = 'Start Processing' - bl_description = 'Adds random or specifice blinks' + bl_description = 'Add blinks at random or specifice frames' def execute(self, context): scn = context.scene obj = context.object - # testing if a mesh object with blink shape keys is selected - if obj!=None and obj.type=="MESH": - if obj.data.shape_keys!=None: blinker() - else: print("add shape keys PLEASE") - else: print ("Object is not mesh or not selected ") + # testing if object is valid + if obj!=None: + if obj.type=="MESH": + if obj.data.shape_keys!=None: + for key in obj.data.shape_keys.key_blocks: + if key.name=='blink': + blinker() + #return + else: print("No shape keys") + else: print ("Object is not a mesh ot bone") + else: print ("Select object") return {'FINISHED'} -# retargetting operation start -class btn_retarget(bpy.types.Operator): - bl_idname = 'retarget.go' - bl_label = 'Start Processing' - bl_description = 'Refresh Shape Keys List' - - def execute(self, context): - - obj = context.object - # testing if a mesh object with blink shape keys is selected - if obj!=None and obj.type=="MESH": - if obj.data.shape_keys!=None: retargeter() - else: print("add shape keys PLEASE") - else: print ("Object is not mesh or not selected ") - return {'FINISHED'} +#defining custom enumeratos +class menuTypes(bpy.types.PropertyGroup): -# getting props from current shape keys -class btn_refresh(bpy.types.Operator): - bl_idname = 'refresh.go' - bl_label = 'Start Processing' - bl_description = 'Refresh Shape Keys List' + enumFileTypes = EnumProperty(items =(('0', 'Papagayo', ''), + ('1', 'Jlipsync Or Yolo', '') + #,('2', 'Retarget', '') + ), + name = 'Choose FileType', + default = '0') + + enumBlinkTypes = EnumProperty(items =(('0', 'Specific', ''), + ('1', 'Random','')), + name = 'Choose BlinkType', + default = '0') + + enumModeTypes = EnumProperty(items =(('0', 'Lipsyncer',''), + ('1', 'Blinker','')), + name = 'Choose Mode', + default = '0') + +# drawing the user interface +class LipSyncBoneUI(bpy.types.Panel): + bl_space_type = "VIEW_3D" + bl_region_type = "UI" + bl_label = "Phonemes" + + def draw(self, context): + layout = self.layout + col = layout.column() - def execute(self, context): + bone = bpy.context.active_pose_bone - scn = context.scene - obj = context.object - - # testing if a mesh object with blink shape keys is selected - if obj!=None and obj.type=="MESH": - if obj.data.shape_keys!=None: - - obj = bpy.context.object - typ = bpy.types.Scene - sk = len(obj.data.shape_keys.key_blocks) - - for x in range(sk): - obj.active_shape_key_index=x - exec("typ.sk"+str(x)+"=StringProperty(name="+"obj.active_shape_key.name"+")") - - else: print("add shape keys PLEASE") - else: print ("Object is not mesh or not selected ") - return {'FINISHED'} - -#defining custom enumeratos -class mnuTypes(bpy.types.PropertyGroup): - - enumFiles = EnumProperty( items =( ('0', 'Papagayo', ''), - ('1', 'Jlipsync Or Yolo', '') - #,('2', 'Retarget', '') - ), - name = 'test', - default = '0' ) - - enumBlinks = EnumProperty( items =( ('0', 'Specific', ''), - ('1', 'Random','')), - name = 'test', - default = '0' ) - + #showing the current object type + if bone: #and if scn.regMenuTypes.enumModeTypes == '0': + col.prop(bone, "location", index=0, text="AI") + col.prop(bone, "location", index=1, text="E") + col.prop(bone, "location", index=2, text="FV") + if bpy.context.scene.unit_settings.system_rotation == 'RADIANS': + col.prop(bone, "rotation_euler", index=0, text="L") + col.prop(bone, "rotation_euler", index=1, text="MBP") + col.prop(bone, "rotation_euler", index=2, text="O") + else: + row=col.row() + row.prop(bone, "rotation_euler", index=0, text="L") + row.label(text=str("%4.2f" % (bone.rotation_euler.x))) + row=col.row() + row.prop(bone, "rotation_euler", index=1, text="MBP") + row.label(text=str("%4.2f" % (bone.rotation_euler.y))) + row=col.row() + row.prop(bone, "rotation_euler", index=2, text="O") + row.label(text=str("%4.2f" % (bone.rotation_euler.z))) + col.prop(bone, "scale", index=0, text="U") + col.prop(bone, "scale", index=1, text="WQ") + col.prop(bone, "scale", index=2, text="etc") + else: + layout.label(text="No good bone is selected") + # drawing the user interface class LipSyncUI(bpy.types.Panel): bl_space_type = "VIEW_3D" bl_region_type = "TOOL_PROPS" bl_label = "LipSync Importer & Blinker" - typ = bpy.types.Scene + newType= bpy.types.Scene scn = bpy.context.scene - typ.mnuFunc = EnumProperty(name="Select Mode ", description="Select function", - items=(('0', 'Lipsyncer', ''), ('1', 'Blinker', '')), default='0') - - typ.fpath = StringProperty(name="Import File ", description="Select your voice file", subtype="FILE_PATH") - typ.skscale = FloatProperty(description="Smoothing shape key values", min=0.1, max=1.0, default=0.8) - typ.offset = IntProperty(description="Offset your frames", default=0) + newType.fpath = StringProperty(name="Import File ", description="Select your voice file", subtype="FILE_PATH") + newType.skscale = FloatProperty(description="Smoothing shape key values", min=0.1, max=1.0, default=0.8) + newType.offset = IntProperty(description="Offset your frames", default=0) + + newType.easeIn = IntProperty(description="Smoothing In curve", min=1, default=3) + newType.easeOut = IntProperty(description="Smoothing Out curve", min=1, default=3) + newType.holdGap = IntProperty(description="Holding for slow keys", min=0, default=0) - typ.easeIn = IntProperty(description="Smoothing In curve", min=1, default=3) - typ.easeOut = IntProperty(description="Smoothing Out curve", min=1, default=3) - typ.holdGap = IntProperty(description="Holding for slow keys", min=0, default=0) - - typ.blinkSp = IntProperty(description="Space between blinks", min=1, default=100) - typ.blinkNm = IntProperty(description="Number of blinks", min=1, default=10) - - typ.blinkMod = IntProperty(description="Randomzing blinks keyframe placment", min=1, default=10) + newType.blinkSp = IntProperty(description="Space between blinks", min=1, default=100) + newType.blinkNm = IntProperty(description="Number of blinks", min=1, default=10) + newType.blinkMod = IntProperty(description="Randomzing keyframe placment", min=1, default=10) def draw(self, context): - obj = bpy.context.object + obj = bpy.context.active_object scn = bpy.context.scene layout = self.layout col = layout.column() - #showing the current object type + # showing the current object type if obj != None: if obj.type == "MESH": split = col.split(align=True) split.label(text="The active object is: ", icon="OBJECT_DATA") split.label(obj.name, icon="EDITMODE_HLT") - elif obj.type!="MESH": - col.label(text="The active object is not a Mesh !", icon="OBJECT_DATA") + elif obj.type == "ARMATURE": # bone needs to be selected + if obj.mode == "POSE": # mode needs to be pose + split = col.split(align=True) + split.label(text="The active object is: ", icon="ARMATURE_DATA") + split.label(obj.name, icon="EDITMODE_HLT") + else: + col.label(text="You need to select Pose mode!", icon="OBJECT_DATA") + else: + col.label(text="The active object is not a Mesh or Armature!", icon="OBJECT_DATA") else: layout.label(text="No object is selected", icon="OBJECT_DATA") - col.prop(context.scene, "mnuFunc") + col.row().prop(scn.regMenuTypes, 'enumModeTypes') col.separator() - # the lipsyncer panel - if bpy.context.scene.mnuFunc == '0': - - col.row().prop(context.scene.remnuTypes, 'enumFiles', text = ' ', expand = True) - + # the lipsyncer panel + if scn.regMenuTypes.enumModeTypes == '0': + # choose the file format + col.row().prop(scn.regMenuTypes, 'enumFileTypes', text = ' ', expand = True) + # Papagayo panel - if scn.remnuTypes.enumFiles == '0': + if scn.regMenuTypes.enumFileTypes == '0': col.prop(context.scene, "fpath") split = col.split(align=True) split.label("Key Value :") @@ -333,10 +400,10 @@ split.prop(context.scene, "holdGap", "Hold Gap") split.prop(context.scene, "easeOut", "Ease Out") - col.operator('lipsync.go', text='Plot Keys PLEASE') + col.operator('lipsync.go', text='Plot Keys to the Timeline') # Jlipsync & Yolo panel - elif scn.remnuTypes.enumFiles == '1': + elif scn.regMenuTypes.enumFileTypes == '1': col.prop(context.scene, "fpath") split = col.split(align=True) split.label("Key Value :") @@ -345,44 +412,15 @@ split.label("Frame Offset :") split.prop(context.scene, "offset") - col.operator('lipsync.go', text='Plot Keys PLEASE') - -# # Retarget panel -# elif scn.remnuTypes.enumFiles == '2': -# col.prop(context.scene, "fpath") -# split = col.split(align=True) -# split.label("Key Value :") -# split.prop(context.scene, "skscale") -# split = col.split(align=True) -# split.label("Frame Offset :") -# split.prop(context.scene, "offset") -# split = col.split(align=True) -# split.prop(context.scene, "easeIn", "Ease In") -# split.prop(context.scene, "holdGap", "Hold Gap") -# split.prop(context.scene, "easeOut", "Ease Out") -# -# col.operator('refresh.go', text='Refresh Shape Key List') -# -# split = col.split(align=True) -# split.label("Current shape keys:") -# split.label("Mapping to custom keys:") -# -# obj = bpy.context.object -# sk=len(obj.data.shape_keys.key_blocks) -# -# for x in range(sk): -# split = col.split(align=True) -# split.prop(context.scene, "sk"+str(x)) -# -# col.operator('retarget.go', text='Plot Keys PLEASE') - + col.operator('lipsync.go', text='Plot Keys to the Timeline') + # the blinker panel - elif bpy.context.scene.mnuFunc == '1': - - col.row().prop(context.scene.remnuTypes, 'enumBlinks', text = ' ', expand = True) + elif scn.regMenuTypes.enumModeTypes == '1': + # choose blink type + col.row().prop(scn.regMenuTypes, 'enumBlinkTypes', text = ' ', expand = True) # specific panel - if scn.remnuTypes.enumBlinks == '0': + if scn.regMenuTypes.enumBlinkTypes == '0': split = col.split(align=True) split.label("Key Value :") split.prop(context.scene, "skscale") @@ -395,10 +433,10 @@ split.prop(context.scene, "easeOut", "Ease Out") col.prop(context.scene, "blinkSp", "Spacing") col.prop(context.scene, "blinkNm", "Times") - col.operator('blink.go', text='Blink Keys PLEASE') + col.operator('blink.go', text='Add Keys to the Timeline') # Random panel - elif scn.remnuTypes.enumBlinks == '1': + elif scn.regMenuTypes.enumBlinkTypes == '1': split = col.split(align=True) split.label("Key Value :") split.prop(context.scene, "skscale") @@ -413,20 +451,17 @@ split.prop(context.scene, "blinkSp", "Spacing") split.prop(context.scene, "blinkMod", "Random Modifier") col.prop(context.scene, "blinkNm", "Times") - col.operator('blink.go', text='Blink Keys PLEASE') - - col.separator() - col.label("Version 0.4 By Yousef Harfoush" ) - col.label("Updated 04/09/2011") - + col.operator('blink.go', text='Add Keys to the Timeline') + + # clearing vars def clear_properties(): # can happen on reload if bpy.context.scene is None: return - - props = ["offset", "skscale", "easeIn", "easeOut", "blinkSp", "blinkNm", "holdGap", "blinkMod"] + + props = ["fpath", "skscale", "offset", "easeIn", "easeOut", "holdGap", "blinkSp", "blinkNm", "blinkMod"] for p in props: if p in bpy.types.Scene.bl_rna.properties: exec("del bpy.types.Scene."+p) @@ -436,13 +471,13 @@ # registering the script def register(): bpy.utils.register_module(__name__) - bpy.types.Scene.remnuTypes = PointerProperty(type = mnuTypes) + bpy.types.Scene.regMenuTypes = PointerProperty(type = menuTypes) def unregister(): bpy.utils.unregister_module(__name__) - del bpy.context.scene.remnuTypes + del bpy.context.scene.regMenuTypes clear_properties() if __name__ == "__main__": - register() + register() \ No newline at end of file diff -Nru blender-2.61/release/scripts/addons_contrib/io_import_LRO_Lola_MGS_Mola_img.py blender-2.62/release/scripts/addons_contrib/io_import_LRO_Lola_MGS_Mola_img.py --- blender-2.61/release/scripts/addons_contrib/io_import_LRO_Lola_MGS_Mola_img.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/io_import_LRO_Lola_MGS_Mola_img.py 2012-02-15 19:43:59.000000000 +0000 @@ -21,7 +21,6 @@ "author": "Valter Battioli (ValterVB)", "version": (1, 1, 8), "blender": (2, 5, 8), - "api": 37806, "location": "3D window > Tool Shelf", "description": "Import DTM from LRO Lola and MGS Mola", "warning": "May consume a lot of memory", diff -Nru blender-2.61/release/scripts/addons_contrib/io_import_voodoo_camera.py blender-2.62/release/scripts/addons_contrib/io_import_voodoo_camera.py --- blender-2.61/release/scripts/addons_contrib/io_import_voodoo_camera.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/io_import_voodoo_camera.py 2012-02-15 19:43:59.000000000 +0000 @@ -21,7 +21,6 @@ "author": "Fazekas Laszlo", "version": (0, 7), "blender": (2, 5, 7), - "api": 36339, "location": "File > Import > Voodoo camera", "description": "Imports a Blender (2.4x or 2.5x) Python script from the Voodoo camera tracker software.", "warning": "", diff -Nru blender-2.61/release/scripts/addons_contrib/io_mesh_xyz/atom_info.dat blender-2.62/release/scripts/addons_contrib/io_mesh_xyz/atom_info.dat --- blender-2.61/release/scripts/addons_contrib/io_mesh_xyz/atom_info.dat 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/io_mesh_xyz/atom_info.dat 2012-02-15 19:43:39.000000000 +0000 @@ -0,0 +1,1536 @@ +Atom +==== +Number : 1 +Name : Hydrogen +Short name : H +Color : 0.99,0.99,0.99 +Radius used : 0.320000 +Radius, covalent : 0.320000 +Radius, atomic : 0.790000 +Charge state : -1 +Radius, ionic : 1.540000 + + +Atom +==== +Number : 2 +Name : Helium +Short name : He +Color : 0.84,0.99,0.99 +Radius used : 0.930000 +Radius, covalent : 0.930000 +Radius, atomic : 0.490000 + + +Atom +==== +Number : 3 +Name : Lithium +Short name : Li +Color : 0.79,0.5,0.99 +Radius used : 1.230000 +Radius, covalent : 1.230000 +Radius, atomic : 2.050000 +Charge state : 1 +Radius, ionic : 0.680000 + + +Atom +==== +Number : 4 +Name : Beryllium +Short name : Be +Color : 0.75,0.99,0.0 +Radius used : 0.900000 +Radius, covalent : 0.900000 +Radius, atomic : 1.400000 +Charge state : 1 +Radius, ionic : 0.440000 +Charge state : 2 +Radius, ionic : 0.350000 + + +Atom +==== +Number : 5 +Name : Boron +Short name : B +Color : 0.99,0.70,0.70 +Radius used : 0.820000 +Radius, covalent : 0.820000 +Radius, atomic : 1.170000 +Charge state : 1 +Radius, ionic : 0.350000 +Charge state : 3 +Radius, ionic : 0.230000 + + +Atom +==== +Number : 6 +Name : Carbon +Short name : C +Color : 0.3,0.3,0.3 +Radius used : 0.910000 +Radius, covalent : 0.770000 +Radius, atomic : 0.910000 +Charge state : -4 +Radius, ionic : 2.600000 +Charge state : 4 +Radius, ionic : 0.160000 + + +Atom +==== +Number : 7 +Name : Nitrogen +Short name : N +Color : 0.18,0.31,0.96 +Radius used : 0.750000 +Radius, covalent : 0.750000 +Radius, atomic : 0.750000 +Charge state : -3 +Radius, ionic : 1.710000 +Charge state : 1 +Radius, ionic : 0.250000 +Charge state : 3 +Radius, ionic : 0.160000 +Charge state : 5 +Radius, ionic : 0.130000 + + +Atom +==== +Number : 8 +Name : Oxygen +Short name : O +Color : 0.99,0.05,0.05 +Radius used : 0.730000 +Radius, covalent : 0.730000 +Radius, atomic : 0.650000 +Charge state : -2 +Radius, ionic : 1.320000 +Charge state : -1 +Radius, ionic : 1.760000 +Charge state : 1 +Radius, ionic : 0.220000 +Charge state : 6 +Radius, ionic : 0.090000 + + +Atom +==== +Number : 9 +Name : Fluorine +Short name : F +Color : 0.0,1.0,0.0 +Radius used : 1.330000 +Radius, covalent : 0.720000 +Radius, atomic : 0.570000 +Charge state : -1 +Radius, ionic : 1.330000 +Charge state : 7 +Radius, ionic : 0.080000 + + +Atom +==== +Number : 10 +Name : Neon +Short name : Ne +Color : 0.69,0.88,0.95 +Radius used : 0.710000 +Radius, covalent : 0.710000 +Radius, atomic : 0.510000 +Charge state : 1 +Radius, ionic : 1.120000 + + +Atom +==== +Number : 11 +Name : Sodium +Short name : Na +Color : 0.5,0.5,0.5 +Radius used : 0.970000 +Radius, covalent : 1.540000 +Radius, atomic : 2.230000 +Charge state : 1 +Radius, ionic : 0.970000 + + +Atom +==== +Number : 12 +Name : Magnesium +Short name : Mg +Color : 0.38,0.066,1.0 +Radius used : 0.660000 +Radius, covalent : 1.360000 +Radius, atomic : 1.720000 +Charge state : 1 +Radius, ionic : 0.820000 +Charge state : 2 +Radius, ionic : 0.660000 + + +Atom +==== +Number : 13 +Name : Aluminium +Short name : Al +Color : 0.74,0.64,0.64 +Radius used : 1.180000 +Radius, covalent : 1.180000 +Radius, atomic : 1.820000 +Charge state : 3 +Radius, ionic : 0.510000 + + +Atom +==== +Number : 14 +Name : Silicon +Short name : Si +Color : 0.93,0.78,0.62 +Radius used : 1.110000 +Radius, covalent : 1.110000 +Radius, atomic : 1.460000 +Charge state : -4 +Radius, ionic : 2.710000 +Charge state : -1 +Radius, ionic : 3.840000 +Charge state : 1 +Radius, ionic : 0.650000 +Charge state : 4 +Radius, ionic : 0.420000 + + +Atom +==== +Number : 15 +Name : Phosphorus +Short name : P +Color : 0.99,0.5,0.0 +Radius used : 1.060000 +Radius, covalent : 1.060000 +Radius, atomic : 1.230000 +Charge state : -3 +Radius, ionic : 2.120000 +Charge state : 3 +Radius, ionic : 0.440000 +Charge state : 5 +Radius, ionic : 0.350000 + + +Atom +==== +Number : 16 +Name : Sulfur +Short name : S +Color : 0.99,0.99,0.18 +Radius used : 1.020000 +Radius, covalent : 1.020000 +Radius, atomic : 1.090000 +Charge state : -2 +Radius, ionic : 1.840000 +Charge state : 2 +Radius, ionic : 2.190000 +Charge state : 4 +Radius, ionic : 0.370000 +Charge state : 6 +Radius, ionic : 0.300000 + + +Atom +==== +Number : 17 +Name : Chlorine +Short name : Cl +Color : 0.095,0.411,1.0 +Radius used : 1.810000 +Radius, covalent : 0.990000 +Radius, atomic : 0.970000 +Charge state : -1 +Radius, ionic : 1.810000 +Charge state : 5 +Radius, ionic : 0.340000 +Charge state : 7 +Radius, ionic : 0.270000 + + +Atom +==== +Number : 18 +Name : Argon +Short name : Ar +Color : 0.5,0.81,0.88 +Radius used : 0.980000 +Radius, covalent : 0.980000 +Radius, atomic : 0.880000 +Charge state : 1 +Radius, ionic : 1.540000 + + +Atom +==== +Number : 19 +Name : Potassium +Short name : K +Color : 0.55,0.25,0.82 +Radius used : 2.030000 +Radius, covalent : 2.030000 +Radius, atomic : 2.770000 +Charge state : 1 +Radius, ionic : 0.810000 + + +Atom +==== +Number : 20 +Name : Calcium +Short name : Ca +Color : 0.23,0.99,0.0 +Radius used : 1.740000 +Radius, covalent : 1.740000 +Radius, atomic : 2.230000 +Charge state : 1 +Radius, ionic : 1.180000 +Charge state : 2 +Radius, ionic : 0.990000 + + +Atom +==== +Number : 21 +Name : Scandium +Short name : Sc +Color : 0.89,0.89,0.89 +Radius used : 1.440000 +Radius, covalent : 1.440000 +Radius, atomic : 2.090000 +Charge state : 3 +Radius, ionic : 0.732000 + + +Atom +==== +Number : 22 +Name : Titanium +Short name : Ti +Color : 0.74,0.75,0.77 +Radius used : 1.320000 +Radius, covalent : 1.320000 +Radius, atomic : 2.000000 +Charge state : 1 +Radius, ionic : 0.960000 +Charge state : 2 +Radius, ionic : 0.940000 +Charge state : 3 +Radius, ionic : 0.760000 +Charge state : 4 +Radius, ionic : 0.680000 + + +Atom +==== +Number : 23 +Name : Vanadium +Short name : V +Color : 0.64,0.64,0.66 +Radius used : 1.220000 +Radius, covalent : 1.220000 +Radius, atomic : 1.920000 +Charge state : 2 +Radius, ionic : 0.880000 +Charge state : 3 +Radius, ionic : 0.740000 +Charge state : 4 +Radius, ionic : 0.630000 +Charge state : 5 +Radius, ionic : 0.590000 + + +Atom +==== +Number : 24 +Name : Chromium +Short name : Cr +Color : 0.53,0.59,0.77 +Radius used : 1.180000 +Radius, covalent : 1.180000 +Radius, atomic : 1.850000 +Charge state : 1 +Radius, ionic : 0.810000 +Charge state : 2 +Radius, ionic : 0.890000 +Charge state : 3 +Radius, ionic : 0.630000 +Charge state : 6 +Radius, ionic : 0.520000 + + +Atom +==== +Number : 25 +Name : Manganese +Short name : Mn +Color : 0.60,0.47,0.77 +Radius used : 1.170000 +Radius, covalent : 1.170000 +Radius, atomic : 1.790000 +Charge state : 2 +Radius, ionic : 0.800000 +Charge state : 3 +Radius, ionic : 0.660000 +Charge state : 4 +Radius, ionic : 0.600000 +Charge state : 7 +Radius, ionic : 0.460000 + + +Atom +==== +Number : 26 +Name : Iron +Short name : Fe +Color : 0.87,0.39,0.19 +Radius used : 1.170000 +Radius, covalent : 1.170000 +Radius, atomic : 1.720000 +Charge state : 2 +Radius, ionic : 0.740000 +Charge state : 3 +Radius, ionic : 0.640000 + + +Atom +==== +Number : 27 +Name : Cobalt +Short name : Co +Color : 0.93,0.56,0.62 +Radius used : 1.160000 +Radius, covalent : 1.160000 +Radius, atomic : 1.670000 +Charge state : 2 +Radius, ionic : 0.720000 +Charge state : 3 +Radius, ionic : 0.630000 + + +Atom +==== +Number : 28 +Name : Nickel +Short name : Ni +Color : 0.31,0.81,0.31 +Radius used : 1.150000 +Radius, covalent : 1.150000 +Radius, atomic : 1.620000 +Charge state : 2 +Radius, ionic : 0.690000 + + +Atom +==== +Number : 29 +Name : Copper +Short name : Cu +Color : 0.78,0.5,0.19 +Radius used : 1.170000 +Radius, covalent : 1.170000 +Radius, atomic : 1.570000 +Charge state : 1 +Radius, ionic : 0.960000 +Charge state : 2 +Radius, ionic : 0.720000 + + +Atom +==== +Number : 30 +Name : Zinc +Short name : Zn +Color : 0.48,0.5,0.68 +Radius used : 1.250000 +Radius, covalent : 1.250000 +Radius, atomic : 1.530000 +Charge state : 1 +Radius, ionic : 0.880000 +Charge state : 2 +Radius, ionic : 0.740000 + + +Atom +==== +Number : 31 +Name : Gallium +Short name : Ga +Color : 0.75,0.55,0.55 +Radius used : 1.260000 +Radius, covalent : 1.260000 +Radius, atomic : 1.810000 +Charge state : 1 +Radius, ionic : 0.810000 +Charge state : 3 +Radius, ionic : 0.620000 + + +Atom +==== +Number : 32 +Name : Germanium +Short name : Ge +Color : 0.39,0.55,0.55 +Radius used : 1.220000 +Radius, covalent : 1.220000 +Radius, atomic : 1.520000 +Charge state : -4 +Radius, ionic : 2.720000 +Charge state : 2 +Radius, ionic : 0.730000 +Charge state : 4 +Radius, ionic : 0.530000 + + +Atom +==== +Number : 33 +Name : Arsenic +Short name : As +Color : 0.73,0.5,0.88 +Radius used : 1.200000 +Radius, covalent : 1.200000 +Radius, atomic : 1.330000 +Charge state : -3 +Radius, ionic : 2.220000 +Charge state : 3 +Radius, ionic : 0.580000 +Charge state : 5 +Radius, ionic : 0.460000 + + +Atom +==== +Number : 34 +Name : Selenium +Short name : Se +Color : 0.99,0.62,0.0 +Radius used : 1.160000 +Radius, covalent : 1.160000 +Radius, atomic : 1.220000 +Charge state : -2 +Radius, ionic : 1.910000 +Charge state : -1 +Radius, ionic : 2.320000 +Charge state : 1 +Radius, ionic : 0.660000 +Charge state : 4 +Radius, ionic : 0.500000 +Charge state : 6 +Radius, ionic : 0.420000 + + +Atom +==== +Number : 35 +Name : Bromine +Short name : Br +Color : 0.64,0.16,0.16 +Radius used : 1.140000 +Radius, covalent : 1.140000 +Radius, atomic : 1.120000 +Charge state : -1 +Radius, ionic : 1.960000 +Charge state : 5 +Radius, ionic : 0.470000 +Charge state : 7 +Radius, ionic : 0.390000 + + +Atom +==== +Number : 36 +Name : Krypton +Short name : Kr +Color : 0.35,0.71,0.81 +Radius used : 1.310000 +Radius, covalent : 1.310000 +Radius, atomic : 1.240000 + + +Atom +==== +Number : 37 +Name : Rubidium +Short name : Rb +Color : 0.43,0.17,0.68 +Radius used : 2.160000 +Radius, covalent : 2.160000 +Radius, atomic : 2.980000 +Charge state : 1 +Radius, ionic : 1.470000 + + +Atom +==== +Number : 38 +Name : Strontium +Short name : Sr +Color : 0.0,0.99,0.0 +Radius used : 1.910000 +Radius, covalent : 1.910000 +Radius, atomic : 2.450000 +Charge state : 2 +Radius, ionic : 1.120000 + + +Atom +==== +Number : 39 +Name : Yttrium +Short name : Y +Color : 0.57,0.99,0.99 +Radius used : 1.620000 +Radius, covalent : 1.620000 +Radius, atomic : 2.270000 +Charge state : 3 +Radius, ionic : 0.893000 + + +Atom +==== +Number : 40 +Name : Zirconium +Short name : Zr +Color : 0.57,0.87,0.87 +Radius used : 1.450000 +Radius, covalent : 1.450000 +Radius, atomic : 2.160000 +Charge state : 1 +Radius, ionic : 1.090000 +Charge state : 4 +Radius, ionic : 0.790000 + + +Atom +==== +Number : 41 +Name : Niobium +Short name : Nb +Color : 0.44,0.75,0.78 +Radius used : 1.340000 +Radius, covalent : 1.340000 +Radius, atomic : 2.080000 +Charge state : 1 +Radius, ionic : 1.000000 +Charge state : 4 +Radius, ionic : 0.740000 +Charge state : 5 +Radius, ionic : 0.690000 + + +Atom +==== +Number : 42 +Name : Molybdenum +Short name : Mo +Color : 0.32,0.70,0.70 +Radius used : 1.300000 +Radius, covalent : 1.300000 +Radius, atomic : 2.010000 +Charge state : 1 +Radius, ionic : 0.930000 +Charge state : 4 +Radius, ionic : 0.700000 +Charge state : 6 +Radius, ionic : 0.620000 + + +Atom +==== +Number : 43 +Name : Technetium +Short name : Tc +Color : 0.23,0.61,0.61 +Radius used : 1.270000 +Radius, covalent : 1.270000 +Radius, atomic : 1.950000 +Charge state : 7 +Radius, ionic : 0.979000 + + +Atom +==== +Number : 44 +Name : Ruthenium +Short name : Ru +Color : 0.14,0.55,0.55 +Radius used : 1.250000 +Radius, covalent : 1.250000 +Radius, atomic : 1.890000 +Charge state : 4 +Radius, ionic : 0.670000 + + +Atom +==== +Number : 45 +Name : Rhodium +Short name : Rh +Color : 0.03,0.48,0.54 +Radius used : 1.250000 +Radius, covalent : 1.250000 +Radius, atomic : 1.830000 +Charge state : 3 +Radius, ionic : 0.680000 + + +Atom +==== +Number : 46 +Name : Palladium +Short name : Pd +Color : 0.0,0.41,0.51 +Radius used : 1.280000 +Radius, covalent : 1.280000 +Radius, atomic : 1.790000 +Charge state : 2 +Radius, ionic : 0.800000 +Charge state : 4 +Radius, ionic : 0.650000 + + +Atom +==== +Number : 47 +Name : Silver +Short name : Ag +Color : 0.75,0.75,0.75 +Radius used : 1.340000 +Radius, covalent : 1.340000 +Radius, atomic : 1.750000 +Charge state : 1 +Radius, ionic : 1.260000 +Charge state : 2 +Radius, ionic : 0.890000 + + +Atom +==== +Number : 48 +Name : Cadmium +Short name : Cd +Color : 0.99,0.84,0.55 +Radius used : 1.480000 +Radius, covalent : 1.480000 +Radius, atomic : 1.710000 +Charge state : 1 +Radius, ionic : 1.140000 +Charge state : 2 +Radius, ionic : 0.970000 + + +Atom +==== +Number : 49 +Name : Indium +Short name : In +Color : 0.64,0.45,0.44 +Radius used : 1.440000 +Radius, covalent : 1.440000 +Radius, atomic : 2.000000 +Charge state : 3 +Radius, ionic : 0.810000 + + +Atom +==== +Number : 50 +Name : Tin +Short name : Sn +Color : 0.39,0.5,0.5 +Radius used : 1.410000 +Radius, covalent : 1.410000 +Radius, atomic : 1.720000 +Charge state : -4 +Radius, ionic : 2.940000 +Charge state : -1 +Radius, ionic : 3.700000 +Charge state : 2 +Radius, ionic : 0.930000 +Charge state : 4 +Radius, ionic : 0.710000 + + +Atom +==== +Number : 51 +Name : Antimony +Short name : Sb +Color : 0.61,0.38,0.70 +Radius used : 1.400000 +Radius, covalent : 1.400000 +Radius, atomic : 1.530000 +Charge state : -3 +Radius, ionic : 2.450000 +Charge state : 3 +Radius, ionic : 0.760000 +Charge state : 5 +Radius, ionic : 0.620000 + + +Atom +==== +Number : 52 +Name : Tellurium +Short name : Te +Color : 0.82,0.47,0.0 +Radius used : 1.360000 +Radius, covalent : 1.360000 +Radius, atomic : 1.420000 +Charge state : -2 +Radius, ionic : 2.110000 +Charge state : -1 +Radius, ionic : 2.500000 +Charge state : 1 +Radius, ionic : 0.820000 +Charge state : 4 +Radius, ionic : 0.700000 +Charge state : 6 +Radius, ionic : 0.560000 + + +Atom +==== +Number : 53 +Name : Iodine +Short name : I +Color : 0.57,0.0,0.57 +Radius used : 1.330000 +Radius, covalent : 1.330000 +Radius, atomic : 1.320000 +Charge state : -1 +Radius, ionic : 2.200000 +Charge state : 5 +Radius, ionic : 0.620000 +Charge state : 7 +Radius, ionic : 0.500000 + + +Atom +==== +Number : 54 +Name : Xenon +Short name : Xe +Color : 0.25,0.61,0.68 +Radius used : 1.310000 +Radius, covalent : 1.310000 +Radius, atomic : 1.240000 + + +Atom +==== +Number : 55 +Name : Caesium +Short name : Cs +Color : 0.33,0.08,0.55 +Radius used : 2.350000 +Radius, covalent : 2.350000 +Radius, atomic : 3.350000 +Charge state : 1 +Radius, ionic : 1.670000 + + +Atom +==== +Number : 56 +Name : Barium +Short name : Ba +Color : 0.0,0.78,0.0 +Radius used : 1.980000 +Radius, covalent : 1.980000 +Radius, atomic : 2.780000 +Charge state : 1 +Radius, ionic : 1.530000 +Charge state : 2 +Radius, ionic : 1.340000 + + +Atom +==== +Number : 57 +Name : Lanthanum +Short name : La +Color : 0.43,0.82,0.99 +Radius used : 1.690000 +Radius, covalent : 1.690000 +Radius, atomic : 2.740000 +Charge state : 1 +Radius, ionic : 1.390000 +Charge state : 3 +Radius, ionic : 1.061000 + + +Atom +==== +Number : 58 +Name : Cerium +Short name : Ce +Color : 0.99,0.99,0.77 +Radius used : 1.650000 +Radius, covalent : 1.650000 +Radius, atomic : 2.700000 +Charge state : 1 +Radius, ionic : 1.270000 +Charge state : 3 +Radius, ionic : 1.034000 +Charge state : 4 +Radius, ionic : 0.920000 + + +Atom +==== +Number : 59 +Name : Praseodymium +Short name : Pr +Color : 0.84,0.99,0.77 +Radius used : 1.650000 +Radius, covalent : 1.650000 +Radius, atomic : 2.670000 +Charge state : 3 +Radius, ionic : 1.013000 +Charge state : 4 +Radius, ionic : 0.900000 + + +Atom +==== +Number : 60 +Name : Neodymium +Short name : Nd +Color : 0.77,0.99,0.77 +Radius used : 1.640000 +Radius, covalent : 1.640000 +Radius, atomic : 2.640000 +Charge state : 3 +Radius, ionic : 0.995000 + + +Atom +==== +Number : 61 +Name : Promethium +Short name : Pm +Color : 0.63,0.99,0.77 +Radius used : 1.630000 +Radius, covalent : 1.630000 +Radius, atomic : 2.620000 +Charge state : 3 +Radius, ionic : 0.979000 + + +Atom +==== +Number : 62 +Name : Samarium +Short name : Sm +Color : 0.55,0.99,0.77 +Radius used : 1.620000 +Radius, covalent : 1.620000 +Radius, atomic : 2.590000 +Charge state : 3 +Radius, ionic : 0.964000 + + +Atom +==== +Number : 63 +Name : Europium +Short name : Eu +Color : 0.37,0.99,0.77 +Radius used : 1.850000 +Radius, covalent : 1.850000 +Radius, atomic : 2.560000 +Charge state : 2 +Radius, ionic : 1.090000 +Charge state : 3 +Radius, ionic : 0.950000 + + +Atom +==== +Number : 64 +Name : Gadolinium +Short name : Gd +Color : 0.26,0.99,0.77 +Radius used : 1.610000 +Radius, covalent : 1.610000 +Radius, atomic : 2.540000 +Charge state : 3 +Radius, ionic : 0.938000 + + +Atom +==== +Number : 65 +Name : Terbium +Short name : Tb +Color : 0.18,0.99,0.77 +Radius used : 1.590000 +Radius, covalent : 1.590000 +Radius, atomic : 2.510000 +Charge state : 3 +Radius, ionic : 0.923000 +Charge state : 4 +Radius, ionic : 0.840000 + + +Atom +==== +Number : 66 +Name : Dysprosium +Short name : Dy +Color : 0.12,0.99,0.77 +Radius used : 1.590000 +Radius, covalent : 1.590000 +Radius, atomic : 2.490000 +Charge state : 3 +Radius, ionic : 0.908000 + + +Atom +==== +Number : 67 +Name : Holmium +Short name : Ho +Color : 0.0,0.99,0.60 +Radius used : 1.580000 +Radius, covalent : 1.580000 +Radius, atomic : 2.470000 +Charge state : 3 +Radius, ionic : 0.894000 + + +Atom +==== +Number : 68 +Name : Erbium +Short name : Er +Color : 0.0,0.89,0.45 +Radius used : 1.570000 +Radius, covalent : 1.570000 +Radius, atomic : 2.450000 +Charge state : 3 +Radius, ionic : 0.881000 + + +Atom +==== +Number : 69 +Name : Thulium +Short name : Tm +Color : 0.0,0.82,0.32 +Radius used : 1.560000 +Radius, covalent : 1.560000 +Radius, atomic : 2.420000 +Charge state : 3 +Radius, ionic : 0.870000 + + +Atom +==== +Number : 70 +Name : Ytterbium +Short name : Yb +Color : 0.0,0.74,0.21 +Radius used : 1.740000 +Radius, covalent : 1.740000 +Radius, atomic : 2.400000 +Charge state : 2 +Radius, ionic : 0.930000 +Charge state : 3 +Radius, ionic : 0.858000 + + +Atom +==== +Number : 71 +Name : Lutetium +Short name : Lu +Color : 0.0,0.66,0.14 +Radius used : 1.560000 +Radius, covalent : 1.560000 +Radius, atomic : 2.250000 +Charge state : 3 +Radius, ionic : 0.850000 + + +Atom +==== +Number : 72 +Name : Hafnium +Short name : Hf +Color : 0.30,0.75,0.99 +Radius used : 1.440000 +Radius, covalent : 1.440000 +Radius, atomic : 2.160000 +Charge state : 4 +Radius, ionic : 0.780000 + + +Atom +==== +Number : 73 +Name : Tantalum +Short name : Ta +Color : 0.30,0.64,0.99 +Radius used : 1.340000 +Radius, covalent : 1.340000 +Radius, atomic : 2.090000 +Charge state : 5 +Radius, ionic : 0.680000 + + +Atom +==== +Number : 74 +Name : Tungsten +Short name : W +Color : 0.12,0.57,0.83 +Radius used : 1.300000 +Radius, covalent : 1.300000 +Radius, atomic : 2.020000 +Charge state : 4 +Radius, ionic : 0.700000 +Charge state : 6 +Radius, ionic : 0.620000 + + +Atom +==== +Number : 75 +Name : Rhenium +Short name : Re +Color : 0.14,0.48,0.66 +Radius used : 1.280000 +Radius, covalent : 1.280000 +Radius, atomic : 1.970000 +Charge state : 4 +Radius, ionic : 0.720000 +Charge state : 7 +Radius, ionic : 0.560000 + + +Atom +==== +Number : 76 +Name : Osmium +Short name : Os +Color : 0.14,0.39,0.58 +Radius used : 1.260000 +Radius, covalent : 1.260000 +Radius, atomic : 1.920000 +Charge state : 4 +Radius, ionic : 0.880000 +Charge state : 6 +Radius, ionic : 0.690000 + + +Atom +==== +Number : 77 +Name : Iridium +Short name : Ir +Color : 0.08,0.32,0.52 +Radius used : 1.270000 +Radius, covalent : 1.270000 +Radius, atomic : 1.870000 +Charge state : 4 +Radius, ionic : 0.680000 + + +Atom +==== +Number : 78 +Name : Platinium +Short name : Pt +Color : 0.81,0.81,0.87 +Radius used : 1.300000 +Radius, covalent : 1.300000 +Radius, atomic : 1.830000 +Charge state : 2 +Radius, ionic : 0.800000 +Charge state : 4 +Radius, ionic : 0.650000 + + +Atom +==== +Number : 79 +Name : Gold +Short name : Au +Color : 0.99,0.81,0.13 +Radius used : 1.340000 +Radius, covalent : 1.340000 +Radius, atomic : 1.790000 +Charge state : 1 +Radius, ionic : 1.370000 +Charge state : 3 +Radius, ionic : 0.850000 + + +Atom +==== +Number : 80 +Name : Mercury +Short name : Hg +Color : 0.71,0.71,0.81 +Radius used : 1.490000 +Radius, covalent : 1.490000 +Radius, atomic : 1.760000 +Charge state : 1 +Radius, ionic : 1.270000 +Charge state : 2 +Radius, ionic : 1.100000 + + +Atom +==== +Number : 81 +Name : Thallium +Short name : Tl +Color : 0.64,0.32,0.30 +Radius used : 1.480000 +Radius, covalent : 1.480000 +Radius, atomic : 2.080000 +Charge state : 1 +Radius, ionic : 1.470000 +Charge state : 3 +Radius, ionic : 0.950000 + + +Atom +==== +Number : 82 +Name : Lead +Short name : Pb +Color : 0.33,0.34,0.37 +Radius used : 1.470000 +Radius, covalent : 1.470000 +Radius, atomic : 1.810000 +Charge state : 2 +Radius, ionic : 1.200000 +Charge state : 4 +Radius, ionic : 0.840000 + + +Atom +==== +Number : 83 +Name : Bismuth +Short name : Bi +Color : 0.61,0.30,0.70 +Radius used : 1.460000 +Radius, covalent : 1.460000 +Radius, atomic : 1.630000 +Charge state : 1 +Radius, ionic : 0.980000 +Charge state : 3 +Radius, ionic : 0.960000 +Charge state : 5 +Radius, ionic : 0.740000 + + +Atom +==== +Number : 84 +Name : Polonium +Short name : Po +Color : 0.66,0.35,0.0 +Radius used : 1.460000 +Radius, covalent : 1.460000 +Radius, atomic : 1.530000 +Charge state : 6 +Radius, ionic : 0.670000 + + +Atom +==== +Number : 85 +Name : Astatine +Short name : At +Color : 0.45,0.30,0.26 +Radius used : 1.450000 +Radius, covalent : 1.450000 +Radius, atomic : 1.430000 +Charge state : -3 +Radius, ionic : 2.220000 +Charge state : 3 +Radius, ionic : 0.850000 +Charge state : 5 +Radius, ionic : 0.460000 + + +Atom +==== +Number : 86 +Name : Radon +Short name : Rn +Color : 0.25,0.50,0.58 +Radius used : 1.000000 +Radius, covalent : 1.000000 +Radius, atomic : 1.340000 + + +Atom +==== +Number : 87 +Name : Francium +Short name : Fr +Color : 0.25,0.0,0.39 +Radius used : 1.000000 +Radius, covalent : 1.000000 +Radius, atomic : 1.000000 +Charge state : 1 +Radius, ionic : 1.800000 + + +Atom +==== +Number : 88 +Name : Radium +Short name : Ra +Color : 0.0,0.48,0.0 +Radius used : 1.000000 +Radius, covalent : 1.000000 +Radius, atomic : 1.000000 +Charge state : 2 +Radius, ionic : 1.430000 + + +Atom +==== +Number : 89 +Name : Actinium +Short name : Ac +Color : 0.43,0.66,0.97 +Radius used : 1.000000 +Radius, covalent : 1.000000 +Radius, atomic : 1.000000 +Charge state : 3 +Radius, ionic : 1.180000 + + +Atom +==== +Number : 90 +Name : Thorium +Short name : Th +Color : 0.0,0.72,0.99 +Radius used : 1.650000 +Radius, covalent : 1.650000 +Radius, atomic : 1.000000 +Charge state : 4 +Radius, ionic : 1.020000 + + +Atom +==== +Number : 91 +Name : Protactinium +Short name : Pa +Color : 0.0,0.62,0.99 +Radius used : 1.000000 +Radius, covalent : 1.000000 +Radius, atomic : 1.000000 +Charge state : 3 +Radius, ionic : 1.130000 +Charge state : 4 +Radius, ionic : 0.980000 +Charge state : 5 +Radius, ionic : 0.890000 + + +Atom +==== +Number : 92 +Name : Uranium +Short name : U +Color : 0.0,0.55,0.99 +Radius used : 1.420000 +Radius, covalent : 1.420000 +Radius, atomic : 1.000000 +Charge state : 4 +Radius, ionic : 0.970000 +Charge state : 6 +Radius, ionic : 0.800000 + + +Atom +==== +Number : 93 +Name : Neptunium +Short name : Np +Color : 0.0,0.5,0.99 +Radius used : 1.000000 +Radius, covalent : 1.000000 +Radius, atomic : 1.000000 +Charge state : 3 +Radius, ionic : 1.100000 +Charge state : 4 +Radius, ionic : 0.950000 +Charge state : 7 +Radius, ionic : 0.710000 + + +Atom +==== +Number : 94 +Name : Plutonium +Short name : Pu +Color : 0.0,0.41,0.99 +Radius used : 1.000000 +Radius, covalent : 1.000000 +Radius, atomic : 1.000000 +Charge state : 3 +Radius, ionic : 1.080000 +Charge state : 4 +Radius, ionic : 0.930000 + + +Atom +==== +Number : 95 +Name : Americium +Short name : Am +Color : 0.32,0.35,0.94 +Radius used : 1.000000 +Radius, covalent : 1.000000 +Radius, atomic : 1.000000 +Charge state : 3 +Radius, ionic : 1.070000 +Charge state : 4 +Radius, ionic : 0.920000 + + +Atom +==== +Number : 96 +Name : Curium +Short name : Cm +Color : 0.46,0.35,0.88 +Radius used : 1.000000 +Radius, covalent : 1.000000 +Radius, atomic : 1.000000 + + +Atom +==== +Number : 97 +Name : Berkelium +Short name : Bk +Color : 0.53,0.30,0.88 +Radius used : 1.000000 +Radius, covalent : 1.000000 +Radius, atomic : 1.000000 + + +Atom +==== +Number : 98 +Name : Californium +Short name : Cf +Color : 0.62,0.21,0.82 +Radius used : 1.000000 +Radius, covalent : 1.000000 +Radius, atomic : 1.000000 + + +Atom +==== +Number : 99 +Name : Einsteinium +Short name : Es +Color : 0.69,0.12,0.82 +Radius used : 1.000000 +Radius, covalent : 1.000000 +Radius, atomic : 1.000000 + + +Atom +==== +Number : 100 +Name : Fermium +Short name : Fm +Color : 0.69,0.12,0.72 +Radius used : 1.000000 +Radius, covalent : 1.000000 +Radius, atomic : 1.000000 + + +Atom +==== +Number : 101 +Name : Mendelevium +Short name : Md +Color : 0.69,0.05,0.64 +Radius used : 1.000000 +Radius, covalent : 1.000000 +Radius, atomic : 1.000000 + + +Atom +==== +Number : 102 +Name : Nobelium +Short name : No +Color : 0.73,0.05,0.52 +Radius used : 1.000000 +Radius, covalent : 1.000000 +Radius, atomic : 1.000000 + + +Atom +==== +Number : 103 +Name : Lawrencium +Short name : Lr +Color : 0.77,0.0,0.39 +Radius used : 1.000000 +Radius, covalent : 1.000000 +Radius, atomic : 1.000000 + + +Atom +==== +Number : 104 +Name : Vacancy +Short name : Vac +Color : 0.5,0.5,0.5 +Radius used : 1.2 +Radius, covalent : 1.0 +Radius, atomic : 1.0 + + +Atom +==== +Number : 105 +Name : Default +Short name : Default +Color : 0.5,0.5,0.5 +Radius used : 1.0 +Radius, covalent : 1.0 +Radius, atomic : 1.0 + + +Atom +==== +Number : 106 +Name : Stick +Short name : Stick +Color : 0.5,0.5,0.5 +Radius used : 1.0 +Radius, covalent : 1.0 +Radius, atomic : 1.0 diff -Nru blender-2.61/release/scripts/addons_contrib/io_mesh_xyz/import_xyz.py blender-2.62/release/scripts/addons_contrib/io_mesh_xyz/import_xyz.py --- blender-2.61/release/scripts/addons_contrib/io_mesh_xyz/import_xyz.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/io_mesh_xyz/import_xyz.py 2012-02-15 19:43:39.000000000 +0000 @@ -0,0 +1,968 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the 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. +# +# ##### END GPL LICENSE BLOCK ##### + +# +# +# Authors : Clemens Barth (Blendphys@root-1.de), ... +# +# Homepage(Wiki) : http://development.root-1.de/Atomic_Blender.php +# Tracker : ... soon +# +# Start of project : 2011-12-01 by Clemens Barth +# First publication in Blender : 2011-12-18 +# Last modified : 2011-12-18 +# +# Acknowledgements: Thanks to ideasman, meta_androcto, truman, kilon, +# dairin0d, PKHG, Valter, etc +# + +import bpy +import io +import math +import os +from math import pi, cos, sin +from mathutils import Vector, Matrix + +# These are variables, which contain the name of the XYZ file and +# the path of the XYZ file. +# They are used almost everywhere, which is the reason why they +# should stay global. First, they are empty and get 'filled' directly +# after having chosen the XYZ file (see 'class LoadXYZ' further below). + +ATOM_XYZ_FILEPATH = "" + +# Some string stuff for the console. +ATOM_XYZ_STRING = "Atomic Blender\n===================" + + +# ----------------------------------------------------------------------------- +# Atom and element data + + +# This is a list that contains some data of all possible elements. The structure +# is as follows: +# +# 1, "Hydrogen", "H", [0.0,0.0,1.0], 0.32, 0.32, 0.32 , -1 , 1.54 means +# +# No., name, short name, color, radius (used), radius (covalent), radius (atomic), +# +# charge state 1, radius (ionic) 1, charge state 2, radius (ionic) 2, ... all +# charge states for any atom are listed, if existing. +# The list is fixed and cannot be changed ... (see below) + +ATOM_XYZ_ELEMENTS_DEFAULT = ( +( 1, "Hydrogen", "H", ( 1.0, 1.0, 1.0), 0.32, 0.32, 0.79 , -1 , 1.54 ), +( 2, "Helium", "He", ( 0.85, 1.0, 1.0), 0.93, 0.93, 0.49 ), +( 3, "Lithium", "Li", ( 0.8, 0.50, 1.0), 1.23, 1.23, 2.05 , 1 , 0.68 ), +( 4, "Beryllium", "Be", ( 0.76, 1.0, 0.0), 0.90, 0.90, 1.40 , 1 , 0.44 , 2 , 0.35 ), +( 5, "Boron", "B", ( 1.0, 0.70, 0.70), 0.82, 0.82, 1.17 , 1 , 0.35 , 3 , 0.23 ), +( 6, "Carbon", "C", ( 0.56, 0.56, 0.56), 0.77, 0.77, 0.91 , -4 , 2.60 , 4 , 0.16 ), +( 7, "Nitrogen", "N", ( 0.18, 0.31, 0.97), 0.75, 0.75, 0.75 , -3 , 1.71 , 1 , 0.25 , 3 , 0.16 , 5 , 0.13 ), +( 8, "Oxygen", "O", ( 1.0, 0.05, 0.05), 0.73, 0.73, 0.65 , -2 , 1.32 , -1 , 1.76 , 1 , 0.22 , 6 , 0.09 ), +( 9, "Fluorine", "F", ( 0.56, 0.87, 0.31), 0.72, 0.72, 0.57 , -1 , 1.33 , 7 , 0.08 ), +(10, "Neon", "Ne", ( 0.70, 0.89, 0.96), 0.71, 0.71, 0.51 , 1 , 1.12 ), +(11, "Sodium", "Na", ( 0.67, 0.36, 0.94), 1.54, 1.54, 2.23 , 1 , 0.97 ), +(12, "Magnesium", "Mg", ( 0.54, 1.0, 0.0), 1.36, 1.36, 1.72 , 1 , 0.82 , 2 , 0.66 ), +(13, "Aluminium", "Al", ( 0.74, 0.65, 0.65), 1.18, 1.18, 1.82 , 3 , 0.51 ), +(14, "Silicon", "Si", ( 0.94, 0.78, 0.62), 1.11, 1.11, 1.46 , -4 , 2.71 , -1 , 3.84 , 1 , 0.65 , 4 , 0.42 ), +(15, "Phosphorus", "P", ( 1.0, 0.50, 0.0), 1.06, 1.06, 1.23 , -3 , 2.12 , 3 , 0.44 , 5 , 0.35 ), +(16, "Sulfur", "S", ( 1.0, 1.0, 0.18), 1.02, 1.02, 1.09 , -2 , 1.84 , 2 , 2.19 , 4 , 0.37 , 6 , 0.30 ), +(17, "Chlorine", "Cl", ( 0.12, 0.94, 0.12), 0.99, 0.99, 0.97 , -1 , 1.81 , 5 , 0.34 , 7 , 0.27 ), +(18, "Argon", "Ar", ( 0.50, 0.81, 0.89), 0.98, 0.98, 0.88 , 1 , 1.54 ), +(19, "Potassium", "K", ( 0.56, 0.25, 0.83), 2.03, 2.03, 2.77 , 1 , 0.81 ), +(20, "Calcium", "Ca", ( 0.23, 1.0, 0.0), 1.74, 1.74, 2.23 , 1 , 1.18 , 2 , 0.99 ), +(21, "Scandium", "Sc", ( 0.90, 0.90, 0.90), 1.44, 1.44, 2.09 , 3 , 0.73 ), +(22, "Titanium", "Ti", ( 0.74, 0.76, 0.78), 1.32, 1.32, 2.00 , 1 , 0.96 , 2 , 0.94 , 3 , 0.76 , 4 , 0.68 ), +(23, "Vanadium", "V", ( 0.65, 0.65, 0.67), 1.22, 1.22, 1.92 , 2 , 0.88 , 3 , 0.74 , 4 , 0.63 , 5 , 0.59 ), +(24, "Chromium", "Cr", ( 0.54, 0.6, 0.78), 1.18, 1.18, 1.85 , 1 , 0.81 , 2 , 0.89 , 3 , 0.63 , 6 , 0.52 ), +(25, "Manganese", "Mn", ( 0.61, 0.47, 0.78), 1.17, 1.17, 1.79 , 2 , 0.80 , 3 , 0.66 , 4 , 0.60 , 7 , 0.46 ), +(26, "Iron", "Fe", ( 0.87, 0.4, 0.2), 1.17, 1.17, 1.72 , 2 , 0.74 , 3 , 0.64 ), +(27, "Cobalt", "Co", ( 0.94, 0.56, 0.62), 1.16, 1.16, 1.67 , 2 , 0.72 , 3 , 0.63 ), +(28, "Nickel", "Ni", ( 0.31, 0.81, 0.31), 1.15, 1.15, 1.62 , 2 , 0.69 ), +(29, "Copper", "Cu", ( 0.78, 0.50, 0.2), 1.17, 1.17, 1.57 , 1 , 0.96 , 2 , 0.72 ), +(30, "Zinc", "Zn", ( 0.49, 0.50, 0.69), 1.25, 1.25, 1.53 , 1 , 0.88 , 2 , 0.74 ), +(31, "Gallium", "Ga", ( 0.76, 0.56, 0.56), 1.26, 1.26, 1.81 , 1 , 0.81 , 3 , 0.62 ), +(32, "Germanium", "Ge", ( 0.4, 0.56, 0.56), 1.22, 1.22, 1.52 , -4 , 2.72 , 2 , 0.73 , 4 , 0.53 ), +(33, "Arsenic", "As", ( 0.74, 0.50, 0.89), 1.20, 1.20, 1.33 , -3 , 2.22 , 3 , 0.58 , 5 , 0.46 ), +(34, "Selenium", "Se", ( 1.0, 0.63, 0.0), 1.16, 1.16, 1.22 , -2 , 1.91 , -1 , 2.32 , 1 , 0.66 , 4 , 0.50 , 6 , 0.42 ), +(35, "Bromine", "Br", ( 0.65, 0.16, 0.16), 1.14, 1.14, 1.12 , -1 , 1.96 , 5 , 0.47 , 7 , 0.39 ), +(36, "Krypton", "Kr", ( 0.36, 0.72, 0.81), 1.31, 1.31, 1.24 ), +(37, "Rubidium", "Rb", ( 0.43, 0.18, 0.69), 2.16, 2.16, 2.98 , 1 , 1.47 ), +(38, "Strontium", "Sr", ( 0.0, 1.0, 0.0), 1.91, 1.91, 2.45 , 2 , 1.12 ), +(39, "Yttrium", "Y", ( 0.58, 1.0, 1.0), 1.62, 1.62, 2.27 , 3 , 0.89 ), +(40, "Zirconium", "Zr", ( 0.58, 0.87, 0.87), 1.45, 1.45, 2.16 , 1 , 1.09 , 4 , 0.79 ), +(41, "Niobium", "Nb", ( 0.45, 0.76, 0.78), 1.34, 1.34, 2.08 , 1 , 1.00 , 4 , 0.74 , 5 , 0.69 ), +(42, "Molybdenum", "Mo", ( 0.32, 0.70, 0.70), 1.30, 1.30, 2.01 , 1 , 0.93 , 4 , 0.70 , 6 , 0.62 ), +(43, "Technetium", "Tc", ( 0.23, 0.61, 0.61), 1.27, 1.27, 1.95 , 7 , 0.97 ), +(44, "Ruthenium", "Ru", ( 0.14, 0.56, 0.56), 1.25, 1.25, 1.89 , 4 , 0.67 ), +(45, "Rhodium", "Rh", ( 0.03, 0.49, 0.54), 1.25, 1.25, 1.83 , 3 , 0.68 ), +(46, "Palladium", "Pd", ( 0.0, 0.41, 0.52), 1.28, 1.28, 1.79 , 2 , 0.80 , 4 , 0.65 ), +(47, "Silver", "Ag", ( 0.75, 0.75, 0.75), 1.34, 1.34, 1.75 , 1 , 1.26 , 2 , 0.89 ), +(48, "Cadmium", "Cd", ( 1.0, 0.85, 0.56), 1.48, 1.48, 1.71 , 1 , 1.14 , 2 , 0.97 ), +(49, "Indium", "In", ( 0.65, 0.45, 0.45), 1.44, 1.44, 2.00 , 3 , 0.81 ), +(50, "Tin", "Sn", ( 0.4, 0.50, 0.50), 1.41, 1.41, 1.72 , -4 , 2.94 , -1 , 3.70 , 2 , 0.93 , 4 , 0.71 ), +(51, "Antimony", "Sb", ( 0.61, 0.38, 0.70), 1.40, 1.40, 1.53 , -3 , 2.45 , 3 , 0.76 , 5 , 0.62 ), +(52, "Tellurium", "Te", ( 0.83, 0.47, 0.0), 1.36, 1.36, 1.42 , -2 , 2.11 , -1 , 2.50 , 1 , 0.82 , 4 , 0.70 , 6 , 0.56 ), +(53, "Iodine", "I", ( 0.58, 0.0, 0.58), 1.33, 1.33, 1.32 , -1 , 2.20 , 5 , 0.62 , 7 , 0.50 ), +(54, "Xenon", "Xe", ( 0.25, 0.61, 0.69), 1.31, 1.31, 1.24 ), +(55, "Caesium", "Cs", ( 0.34, 0.09, 0.56), 2.35, 2.35, 3.35 , 1 , 1.67 ), +(56, "Barium", "Ba", ( 0.0, 0.78, 0.0), 1.98, 1.98, 2.78 , 1 , 1.53 , 2 , 1.34 ), +(57, "Lanthanum", "La", ( 0.43, 0.83, 1.0), 1.69, 1.69, 2.74 , 1 , 1.39 , 3 , 1.06 ), +(58, "Cerium", "Ce", ( 1.0, 1.0, 0.78), 1.65, 1.65, 2.70 , 1 , 1.27 , 3 , 1.03 , 4 , 0.92 ), +(59, "Praseodymium", "Pr", ( 0.85, 1.0, 0.78), 1.65, 1.65, 2.67 , 3 , 1.01 , 4 , 0.90 ), +(60, "Neodymium", "Nd", ( 0.78, 1.0, 0.78), 1.64, 1.64, 2.64 , 3 , 0.99 ), +(61, "Promethium", "Pm", ( 0.63, 1.0, 0.78), 1.63, 1.63, 2.62 , 3 , 0.97 ), +(62, "Samarium", "Sm", ( 0.56, 1.0, 0.78), 1.62, 1.62, 2.59 , 3 , 0.96 ), +(63, "Europium", "Eu", ( 0.38, 1.0, 0.78), 1.85, 1.85, 2.56 , 2 , 1.09 , 3 , 0.95 ), +(64, "Gadolinium", "Gd", ( 0.27, 1.0, 0.78), 1.61, 1.61, 2.54 , 3 , 0.93 ), +(65, "Terbium", "Tb", ( 0.18, 1.0, 0.78), 1.59, 1.59, 2.51 , 3 , 0.92 , 4 , 0.84 ), +(66, "Dysprosium", "Dy", ( 0.12, 1.0, 0.78), 1.59, 1.59, 2.49 , 3 , 0.90 ), +(67, "Holmium", "Ho", ( 0.0, 1.0, 0.61), 1.58, 1.58, 2.47 , 3 , 0.89 ), +(68, "Erbium", "Er", ( 0.0, 0.90, 0.45), 1.57, 1.57, 2.45 , 3 , 0.88 ), +(69, "Thulium", "Tm", ( 0.0, 0.83, 0.32), 1.56, 1.56, 2.42 , 3 , 0.87 ), +(70, "Ytterbium", "Yb", ( 0.0, 0.74, 0.21), 1.74, 1.74, 2.40 , 2 , 0.93 , 3 , 0.85 ), +(71, "Lutetium", "Lu", ( 0.0, 0.67, 0.14), 1.56, 1.56, 2.25 , 3 , 0.85 ), +(72, "Hafnium", "Hf", ( 0.30, 0.76, 1.0), 1.44, 1.44, 2.16 , 4 , 0.78 ), +(73, "Tantalum", "Ta", ( 0.30, 0.65, 1.0), 1.34, 1.34, 2.09 , 5 , 0.68 ), +(74, "Tungsten", "W", ( 0.12, 0.58, 0.83), 1.30, 1.30, 2.02 , 4 , 0.70 , 6 , 0.62 ), +(75, "Rhenium", "Re", ( 0.14, 0.49, 0.67), 1.28, 1.28, 1.97 , 4 , 0.72 , 7 , 0.56 ), +(76, "Osmium", "Os", ( 0.14, 0.4, 0.58), 1.26, 1.26, 1.92 , 4 , 0.88 , 6 , 0.69 ), +(77, "Iridium", "Ir", ( 0.09, 0.32, 0.52), 1.27, 1.27, 1.87 , 4 , 0.68 ), +(78, "Platinium", "Pt", ( 0.81, 0.81, 0.87), 1.30, 1.30, 1.83 , 2 , 0.80 , 4 , 0.65 ), +(79, "Gold", "Au", ( 1.0, 0.81, 0.13), 1.34, 1.34, 1.79 , 1 , 1.37 , 3 , 0.85 ), +(80, "Mercury", "Hg", ( 0.72, 0.72, 0.81), 1.49, 1.49, 1.76 , 1 , 1.27 , 2 , 1.10 ), +(81, "Thallium", "Tl", ( 0.65, 0.32, 0.30), 1.48, 1.48, 2.08 , 1 , 1.47 , 3 , 0.95 ), +(82, "Lead", "Pb", ( 0.34, 0.34, 0.38), 1.47, 1.47, 1.81 , 2 , 1.20 , 4 , 0.84 ), +(83, "Bismuth", "Bi", ( 0.61, 0.30, 0.70), 1.46, 1.46, 1.63 , 1 , 0.98 , 3 , 0.96 , 5 , 0.74 ), +(84, "Polonium", "Po", ( 0.67, 0.36, 0.0), 1.46, 1.46, 1.53 , 6 , 0.67 ), +(85, "Astatine", "At", ( 0.45, 0.30, 0.27), 1.45, 1.45, 1.43 , -3 , 2.22 , 3 , 0.85 , 5 , 0.46 ), +(86, "Radon", "Rn", ( 0.25, 0.50, 0.58), 1.00, 1.00, 1.34 ), +(87, "Francium", "Fr", ( 0.25, 0.0, 0.4), 1.00, 1.00, 1.00 , 1 , 1.80 ), +(88, "Radium", "Ra", ( 0.0, 0.49, 0.0), 1.00, 1.00, 1.00 , 2 , 1.43 ), +(89, "Actinium", "Ac", ( 0.43, 0.67, 0.98), 1.00, 1.00, 1.00 , 3 , 1.18 ), +(90, "Thorium", "Th", ( 0.0, 0.72, 1.0), 1.65, 1.65, 1.00 , 4 , 1.02 ), +(91, "Protactinium", "Pa", ( 0.0, 0.63, 1.0), 1.00, 1.00, 1.00 , 3 , 1.13 , 4 , 0.98 , 5 , 0.89 ), +(92, "Uranium", "U", ( 0.0, 0.56, 1.0), 1.42, 1.42, 1.00 , 4 , 0.97 , 6 , 0.80 ), +(93, "Neptunium", "Np", ( 0.0, 0.50, 1.0), 1.00, 1.00, 1.00 , 3 , 1.10 , 4 , 0.95 , 7 , 0.71 ), +(94, "Plutonium", "Pu", ( 0.0, 0.41, 1.0), 1.00, 1.00, 1.00 , 3 , 1.08 , 4 , 0.93 ), +(95, "Americium", "Am", ( 0.32, 0.36, 0.94), 1.00, 1.00, 1.00 , 3 , 1.07 , 4 , 0.92 ), +(96, "Curium", "Cm", ( 0.47, 0.36, 0.89), 1.00, 1.00, 1.00 ), +(97, "Berkelium", "Bk", ( 0.54, 0.30, 0.89), 1.00, 1.00, 1.00 ), +(98, "Californium", "Cf", ( 0.63, 0.21, 0.83), 1.00, 1.00, 1.00 ), +(99, "Einsteinium", "Es", ( 0.70, 0.12, 0.83), 1.00, 1.00, 1.00 ), +(100, "Fermium", "Fm", ( 0.70, 0.12, 0.72), 1.00, 1.00, 1.00 ), +(101, "Mendelevium", "Md", ( 0.70, 0.05, 0.65), 1.00, 1.00, 1.00 ), +(102, "Nobelium", "No", ( 0.74, 0.05, 0.52), 1.00, 1.00, 1.00 ), +(103, "Lawrencium", "Lr", ( 0.78, 0.0, 0.4), 1.00, 1.00, 1.00 ), +(104, "Vacancy", "Vac", ( 0.5, 0.5, 0.5), 1.00, 1.00, 1.00), +(105, "Default", "Default", ( 1.0, 1.0, 1.0), 1.00, 1.00, 1.00), +(106, "Stick", "Stick", ( 0.5, 0.5, 0.5), 1.00, 1.00, 1.00), +) + +# This list here contains all data of the elements and will be used during +# runtime. It is a list of classes. +# During executing Atomic Blender, the list will be initialized with the fixed +# data from above via the class structure below (CLASS_atom_xyz_Elements). We +# have then one fixed list (above), which will never be changed, and a list of +# classes with same data. The latter can be modified via loading a separate +# custom data file for instance. +ATOM_XYZ_ELEMENTS = [] + +# This is the list, which contains all atoms of all frames! Each item is a +# list which contains the atoms of a single frame. It is a list of +# 'CLASS_atom_xyz_atom'. +ALL_FRAMES = [] +NUMBER_FRAMES = 0 + +# A list of ALL balls which are put into the scene +STRUCTURE = [] + +# This is the class, which stores the properties for one element. +class CLASS_atom_xyz_Elements(object): + __slots__ = ('number', 'name', 'short_name', 'color', 'radii', 'radii_ionic') + def __init__(self, number, name, short_name, color, radii, radii_ionic): + self.number = number + self.name = name + self.short_name = short_name + self.color = color + self.radii = radii + self.radii_ionic = radii_ionic + +# This is the class, which stores the properties of one atom. +class CLASS_atom_xyz_atom(object): + __slots__ = ('element', 'name', 'location', 'radius', 'color', 'material') + def __init__(self, element, name, location, radius, color, material): + self.element = element + self.name = name + self.location = location + self.radius = radius + self.color = color + self.material = material + + +# ----------------------------------------------------------------------------- +# Some small routines + + + +# This function measures the distance between two objects (atoms), +# which are active. +def DEF_atom_xyz_distance(): + + if len(bpy.context.selected_bases) > 1: + object_1 = bpy.context.selected_objects[0] + object_2 = bpy.context.selected_objects[1] + else: + return "N.A." + + dv = object_2.location - object_1.location + return str(dv.length) + + +# Routine to modify the radii via the type: +# +# pre-defined, atomic or van der Waals +# +# Explanations here are also valid for the next 3 DEFs. +def DEF_atom_xyz_radius_type(rtype,how): + + if how == "ALL_IN_LAYER": + + # Note all layers that are active. + layers = [] + for i in range(20): + if bpy.context.scene.layers[i] == True: + layers.append(i) + + # Put all objects, which are in the layers, into a list. + change_objects = [] + for obj in bpy.context.scene.objects: + for layer in layers: + if obj.layers[layer] == True: + change_objects.append(obj) + + # Consider all objects, which are in the list 'change_objects'. + for obj in change_objects: + if len(obj.children) != 0: + if obj.children[0].type == "SURFACE" or obj.children[0].type == "MESH": + for element in ATOM_XYZ_ELEMENTS: + if element.name in obj.name: + obj.children[0].scale = (element.radii[int(rtype)],) * 3 + else: + if obj.type == "SURFACE" or obj.type == "MESH": + for element in ATOM_XYZ_ELEMENTS: + if element.name in obj.name: + obj.scale = (element.radii[int(rtype)],) * 3 + + if how == "ALL_ACTIVE": + for obj in bpy.context.selected_objects: + if len(obj.children) != 0: + if obj.children[0].type == "SURFACE" or obj.children[0].type == "MESH": + for element in ATOM_XYZ_ELEMENTS: + if element.name in obj.name: + obj.children[0].scale = (element.radii[int(rtype)],) * 3 + else: + if obj.type == "SURFACE" or obj.type == "MESH": + for element in ATOM_XYZ_ELEMENTS: + if element.name in obj.name: + obj.scale = (element.radii[int(rtype)],) * 3 + + +# Routine to modify the radii in picometer of a specific type of atom +def DEF_atom_xyz_radius_pm(atomname, radius_pm, how): + + if how == "ALL_IN_LAYER": + + layers = [] + for i in range(20): + if bpy.context.scene.layers[i] == True: + layers.append(i) + + change_objects = [] + for obj in bpy.context.scene.objects: + for layer in layers: + if obj.layers[layer] == True: + change_objects.append(obj) + + for obj in change_objects: + if len(obj.children) != 0: + if obj.children[0].type == "SURFACE" or obj.children[0].type == "MESH": + if atomname in obj.name: + obj.children[0].scale = (radius_pm/100,) * 3 + else: + if obj.type == "SURFACE" or obj.type == "MESH": + if atomname in obj.name: + obj.scale = (radius_pm/100,) * 3 + + if how == "ALL_ACTIVE": + for obj in bpy.context.selected_objects: + if len(obj.children) != 0: + if obj.children[0].type == "SURFACE" or obj.children[0].type == "MESH": + if atomname in obj.name: + obj.children[0].scale = (radius_pm/100,) * 3 + else: + if obj.type == "SURFACE" or obj.type == "MESH": + if atomname in obj.name: + obj.scale = (radius_pm/100,) * 3 + + +# Routine to scale the radii of all atoms +def DEF_atom_xyz_radius_all(scale, how): + + if how == "ALL_IN_LAYER": + + layers = [] + for i in range(20): + if bpy.context.scene.layers[i] == True: + layers.append(i) + + change_objects = [] + for obj in bpy.context.scene.objects: + for layer in layers: + if obj.layers[layer] == True: + change_objects.append(obj) + + + for obj in change_objects: + if len(obj.children) != 0: + if obj.children[0].type == "SURFACE" or obj.children[0].type == "MESH": + obj.children[0].scale *= scale + else: + if obj.type == "SURFACE" or obj.type == "MESH": + obj.scale *= scale + + if how == "ALL_ACTIVE": + for obj in bpy.context.selected_objects: + if len(obj.children) != 0: + if obj.children[0].type == "SURFACE" or obj.children[0].type == "MESH": + obj.children[0].scale *= scale + else: + if obj.type == "SURFACE" or obj.type == "MESH": + obj.scale *= scale + + + +def DEF_atom_xyz_read_elements(): + + ATOM_XYZ_ELEMENTS[:] = [] + + for item in ATOM_XYZ_ELEMENTS_DEFAULT: + + # All three radii into a list + radii = [item[4],item[5],item[6]] + # The handling of the ionic radii will be done later. So far, it is an + # empty list. + radii_ionic = [] + + li = CLASS_atom_xyz_Elements(item[0],item[1],item[2],item[3], + radii,radii_ionic) + ATOM_XYZ_ELEMENTS.append(li) + + + + +def DEF_atom_xyz_read_xyz_file(filepath,radiustype): + + global NUMBER_FRAMES + + # Open the file ... + ATOM_XYZ_FILEPATH_p = io.open(ATOM_XYZ_FILEPATH, "r") + + #Go through the whole file. + FLAG = False + for line in ATOM_XYZ_FILEPATH_p: + + # ... the loop is broken here (EOF) ... + if line == "": + continue + + split_list = line.rsplit() + + if len(split_list) == 1: + number_atoms = int(split_list[0]) + FLAG = True + + if FLAG == True: + + line = ATOM_XYZ_FILEPATH_p.readline() + line = line.rstrip() + comment = line + + all_atoms= [] + + for i in range(number_atoms): + + line = ATOM_XYZ_FILEPATH_p.readline() + line = line.rstrip() + split_list = line.rsplit() + + short_name = str(split_list[0]) + + # Go through all elements and find the element of the current atom. + FLAG_FOUND = False + for element in ATOM_XYZ_ELEMENTS: + if str.upper(short_name) == str.upper(element.short_name): + # Give the atom its proper names, color and radius: + name = element.name + # int(radiustype) => type of radius: + # pre-defined (0), atomic (1) or van der Waals (2) + radius = float(element.radii[int(radiustype)]) + color = element.color + FLAG_FOUND = True + break + + # Is it a vacancy or an 'unknown atom' ? + if FLAG_FOUND == False: + # Give this atom also a name. If it is an 'X' then it is a + # vacancy. Otherwise ... + if "X" in short_name: + short_name = "VAC" + name = "Vacancy" + radius = float(ATOM_XYZ_ELEMENTS[-3].radii[int(radiustype)]) + color = ATOM_XYZ_ELEMENTS[-3].color + # ... take what is written in the xyz file. These are somewhat + # unknown atoms. This should never happen, the element list is + # almost complete. However, we do this due to security reasons. + else: + name = str.upper(short_name) + radius = float(ATOM_XYZ_ELEMENTS[-2].radii[int(radiustype)]) + color = ATOM_XYZ_ELEMENTS[-2].color + + x = float(split_list[1]) + y = float(split_list[2]) + z = float(split_list[3]) + + location = Vector((x,y,z)) + + all_atoms.append([short_name, name, location, radius, color]) + + # We note here all elements. This needs to be done only once. + if NUMBER_FRAMES == 0: + elements = [] + for atom in all_atoms: + FLAG_FOUND = False + for element in elements: + # If the atom name is already in the list, + # FLAG on 'True'. + if element == atom[1]: + FLAG_FOUND = True + break + # No name in the current list has been found? => New entry. + if FLAG_FOUND == False: + # Stored are: Atom label (e.g. 'Na'), the corresponding + # atom name (e.g. 'Sodium') and its color. + elements.append(atom[1]) + + + structure = [] + for element in elements: + atoms_one_type = [] + for atom in all_atoms: + if atom[1] == element: + atoms_one_type.append(CLASS_atom_xyz_atom( + atom[0], + atom[1], + atom[2], + atom[3], + atom[4],[])) + structure.append(atoms_one_type) + + + ALL_FRAMES.append(structure) + NUMBER_FRAMES += 1 + FLAG = False + + ATOM_XYZ_FILEPATH_p.close() + + """ + for frame in ALL_FRAMES: + for element in frame: + for atom in element: + print(atom.element + " " + str(atom.location)) + print() + """ + + return number_atoms + + + + + +# This reads a custom data file. +def DEF_atom_xyz_custom_datafile(path_datafile): + + if path_datafile == "": + return False + + path_datafile = bpy.path.abspath(path_datafile) + + if os.path.isfile(path_datafile) == False: + return False + + # The whole list gets deleted! We build it new. + ATOM_XYZ_ELEMENTS[:] = [] + + # Read the data file, which contains all data + # (atom name, radii, colors, etc.) + data_file_p = io.open(path_datafile, "r") + + for line in data_file_p: + + if "Atom" in line: + + line = data_file_p.readline() + + # Number + line = data_file_p.readline() + number = line[19:-1] + # Name + line = data_file_p.readline() + name = line[19:-1] + # Short name + line = data_file_p.readline() + short_name = line[19:-1] + # Color + line = data_file_p.readline() + color_value = line[19:-1].split(',') + color = [float(color_value[0]), + float(color_value[1]), + float(color_value[2])] + # Used radius + line = data_file_p.readline() + radius_used = float(line[19:-1]) + # Atomic radius + line = data_file_p.readline() + radius_atomic = float(line[19:-1]) + # Van der Waals radius + line = data_file_p.readline() + radius_vdW = float(line[19:-1]) + + radii = [radius_used,radius_atomic,radius_vdW] + radii_ionic = [] + + element = CLASS_atom_xyz_Elements(number,name,short_name,color, + radii, radii_ionic) + + ATOM_XYZ_ELEMENTS.append(element) + + data_file_p.close() + + return True + + +# ----------------------------------------------------------------------------- +# The main routine + + +def DEF_atom_xyz_main(use_mesh,Ball_azimuth,Ball_zenith, + Ball_radius_factor,radiustype,Ball_distance_factor, + put_to_center, use_camera,use_lamp,path_datafile): + + + # List of materials + atom_material_list = [] + + # ------------------------------------------------------------------------ + # INITIALIZE THE ELEMENT LIST + + DEF_atom_xyz_read_elements() + + # ------------------------------------------------------------------------ + # READING DATA OF ATOMS + + + Number_of_total_atoms = DEF_atom_xyz_read_xyz_file(ATOM_XYZ_FILEPATH, + radiustype) + + # We show the atoms of the first frame. + first_frame = ALL_FRAMES[0] + + + # ------------------------------------------------------------------------ + # MATERIAL PROPERTIES FOR ATOMS + + + + # Create first a new list of materials for each type of atom + # (e.g. hydrogen) + for atoms_of_one_type in first_frame: + # Take the first atom + atom = atoms_of_one_type[0] + material = bpy.data.materials.new(atom.name) + material.name = atom.name + material.diffuse_color = atom.color + atom_material_list.append(material) + + # Now, we go through all atoms and give them a material. For all atoms ... + for atoms_of_one_type in first_frame: + for atom in atoms_of_one_type: + # ... and all materials ... + for material in atom_material_list: + # ... select the correct material for the current atom via + # comparison of names ... + if atom.name in material.name: + # ... and give the atom its material properties. + # However, before we check, if it is a vacancy + # The vacancy is represented by a transparent cube. + if atom.name == "Vacancy": + material.transparency_method = 'Z_TRANSPARENCY' + material.alpha = 1.3 + material.raytrace_transparency.fresnel = 1.6 + material.raytrace_transparency.fresnel_factor = 1.6 + material.use_transparency = True + # The atom gets its properties. + atom.material = material + + + + # ------------------------------------------------------------------------ + # TRANSLATION OF THE STRUCTURE TO THE ORIGIN + + + # It may happen that the structure in a XYZ file already has an offset + # If chosen, the structure is first put into the center of the scene + # (the offset is substracted). + + + if put_to_center == True: + + sum_vec = Vector((0.0,0.0,0.0)) + + # Sum of all atom coordinates + for atoms_of_one_type in first_frame: + sum_vec = sum([atom.location for atom in atoms_of_one_type], sum_vec) + + # Then the average is taken + sum_vec = sum_vec / Number_of_total_atoms + + # After, for each atom the center of gravity is substracted + for atoms_of_one_type in first_frame: + for atom in atoms_of_one_type: + atom.location -= sum_vec + + + # ------------------------------------------------------------------------ + # SCALING + + + # Take all atoms and adjust their radii and scale the distances. + for atoms_of_one_type in first_frame: + for atom in atoms_of_one_type: + atom.location *= Ball_distance_factor + + + # ------------------------------------------------------------------------ + # DETERMINATION OF SOME GEOMETRIC PROPERTIES + + + # In the following, some geometric properties of the whole object are + # determined: center, size, etc. + sum_vec = Vector((0.0,0.0,0.0)) + + # First the center is determined. All coordinates are summed up ... + for atoms_of_one_type in first_frame: + sum_vec = sum([atom.location for atom in atoms_of_one_type], sum_vec) + + # ... and the average is taken. This gives the center of the object. + object_center_vec = sum_vec / Number_of_total_atoms + + # Now, we determine the size.The farest atom from the object center is + # taken as a measure. The size is used to place well the camera and light + # into the scene. + + object_size_vec = [] + for atoms_of_one_type in first_frame: + object_size_vec += [atom.location - object_center_vec for atom in atoms_of_one_type] + + object_size = 0.0 + object_size = max(object_size_vec).length + + + # ------------------------------------------------------------------------ + # CAMERA AND LAMP + + camera_factor = 15.0 + + # If chosen a camera is put into the scene. + if use_camera == True: + + # Assume that the object is put into the global origin. Then, the + # camera is moved in x and z direction, not in y. The object has its + # size at distance math.sqrt(object_size) from the origin. So, move the + # camera by this distance times a factor of camera_factor in x and z. + # Then add x, y and z of the origin of the object. + object_camera_vec = Vector((math.sqrt(object_size) * camera_factor, + 0.0, + math.sqrt(object_size) * camera_factor)) + camera_xyz_vec = object_center_vec + object_camera_vec + + # Create the camera + current_layers=bpy.context.scene.layers + bpy.ops.object.camera_add(view_align=False, enter_editmode=False, + location=camera_xyz_vec, + rotation=(0.0, 0.0, 0.0), layers=current_layers) + # Some properties of the camera are changed. + camera = bpy.context.scene.objects.active + camera.name = "A_camera" + camera.data.name = "A_camera" + camera.data.lens = 45 + camera.data.clip_end = 500.0 + + # Here the camera is rotated such it looks towards the center of + # the object. The [0.0, 0.0, 1.0] vector along the z axis + z_axis_vec = Vector((0.0, 0.0, 1.0)) + # The angle between the last two vectors + angle = object_camera_vec.angle(z_axis_vec, 0) + # The cross-product of z_axis_vec and object_camera_vec + axis_vec = z_axis_vec.cross(object_camera_vec) + # Rotate 'axis_vec' by 'angle' and convert this to euler parameters. + # 4 is the size of the matrix. + euler = Matrix.Rotation(angle, 4, axis_vec).to_euler() + camera.rotation_euler = euler + + # Rotate the camera around its axis by 90° such that we have a nice + # camera position and view onto the object. + bpy.ops.transform.rotate(value=(90.0*2*math.pi/360.0,), + axis=object_camera_vec, + constraint_axis=(False, False, False), + constraint_orientation='GLOBAL', + mirror=False, proportional='DISABLED', + proportional_edit_falloff='SMOOTH', + proportional_size=1, snap=False, + snap_target='CLOSEST', snap_point=(0, 0, 0), + snap_align=False, snap_normal=(0, 0, 0), + release_confirm=False) + + + # This does not work, I don't know why. + # + #for area in bpy.context.screen.areas: + # if area.type == 'VIEW_3D': + # area.spaces[0].region_3d.view_perspective = 'CAMERA' + + + # Here a lamp is put into the scene, if chosen. + if use_lamp == True: + + # This is the distance from the object measured in terms of % + # of the camera distance. It is set onto 50% (1/2) distance. + lamp_dl = math.sqrt(object_size) * 15 * 0.5 + # This is a factor to which extend the lamp shall go to the right + # (from the camera point of view). + lamp_dy_right = lamp_dl * (3.0/4.0) + + # Create x, y and z for the lamp. + object_lamp_vec = Vector((lamp_dl,lamp_dy_right,lamp_dl)) + lamp_xyz_vec = object_center_vec + object_lamp_vec + + # Create the lamp + current_layers=bpy.context.scene.layers + bpy.ops.object.lamp_add (type = 'POINT', view_align=False, + location=lamp_xyz_vec, + rotation=(0.0, 0.0, 0.0), + layers=current_layers) + # Some properties of the lamp are changed. + lamp = bpy.context.scene.objects.active + lamp.data.name = "A_lamp" + lamp.name = "A_lamp" + lamp.data.distance = 500.0 + lamp.data.energy = 3.0 + lamp.data.shadow_method = 'RAY_SHADOW' + + bpy.context.scene.world.light_settings.use_ambient_occlusion = True + bpy.context.scene.world.light_settings.ao_factor = 0.2 + + + # ------------------------------------------------------------------------ + # SOME OUTPUT ON THE CONSOLE + + + print() + print() + print() + print(ATOM_XYZ_STRING) + print() + print("Total number of atoms : " + str(Number_of_total_atoms)) + print("Center of object : ", object_center_vec) + print("Size of object : ", object_size) + print() + + + + + + # ------------------------------------------------------------------------ + # DRAWING THE ATOMS + + + bpy.ops.object.select_all(action='DESELECT') + + # For each list of atoms of ONE type (e.g. Hydrogen) + for atoms_of_one_type in first_frame: + + # Create first the vertices composed of the coordinates of all + # atoms of one type + atom_vertices = [] + for atom in atoms_of_one_type: + # In fact, the object is created in the World's origin. + # This is why 'object_center_vec' is substracted. At the end + # the whole object is translated back to 'object_center_vec'. + atom_vertices.append( atom.location - object_center_vec ) + + # Build the mesh + atom_mesh = bpy.data.meshes.new("Mesh_"+atom.name) + atom_mesh.from_pydata(atom_vertices, [], []) + atom_mesh.update() + new_atom_mesh = bpy.data.objects.new(atom.name, atom_mesh) + bpy.context.scene.objects.link(new_atom_mesh) + + # Now, build a representative sphere (atom) + current_layers=bpy.context.scene.layers + + if atom.name == "Vacancy": + bpy.ops.mesh.primitive_cube_add( + view_align=False, enter_editmode=False, + location=(0.0, 0.0, 0.0), + rotation=(0.0, 0.0, 0.0), + layers=current_layers) + else: + # NURBS balls + if use_mesh == False: + bpy.ops.surface.primitive_nurbs_surface_sphere_add( + view_align=False, enter_editmode=False, + location=(0,0,0), rotation=(0.0, 0.0, 0.0), + layers=current_layers) + # UV balls + else: + bpy.ops.mesh.primitive_uv_sphere_add( + segments=Ball_azimuth, ring_count=Ball_zenith, + size=1, view_align=False, enter_editmode=False, + location=(0,0,0), rotation=(0, 0, 0), + layers=current_layers) + + ball = bpy.context.scene.objects.active + ball.scale = (atom.radius*Ball_radius_factor,) * 3 + + if atom.name == "Vacancy": + ball.name = "Cube_"+atom.name + else: + ball.name = "Ball (NURBS)_"+atom.name + ball.active_material = atom.material + ball.parent = new_atom_mesh + new_atom_mesh.dupli_type = 'VERTS' + # The object is back translated to 'object_center_vec'. + new_atom_mesh.location = object_center_vec + STRUCTURE.append(new_atom_mesh) + + print() + + + # ------------------------------------------------------------------------ + # SELECT ALL LOADED OBJECTS + + + bpy.ops.object.select_all(action='DESELECT') + obj = None + for obj in STRUCTURE: + obj.select = True + + # activate the last selected object (perhaps another should be active?) + if obj: + bpy.context.scene.objects.active = obj + + print("\n\nAll atoms (%d) have been drawn - finished.\n\n" + % (Number_of_total_atoms)) + + return Number_of_total_atoms + + + + +def DEF_atom_xyz_build_frames(frame_delta, frame_skip): + + scn = bpy.context.scene + current_layers = scn.layers + + # Introduce the basis for all elements that appear in the structure. + for element in STRUCTURE: + + bpy.ops.object.select_all(action='DESELECT') + bpy.context.scene.objects.active = element + element.select = True + bpy.ops.object.shape_key_add(None) + + frame_skip += 1 + + # Introduce the keys and reference the atom positions for each key. + i = 0 + for j, frame in enumerate(ALL_FRAMES): + + if j % frame_skip == 0: + + for elements_frame, elements_structure in zip(frame,STRUCTURE): + + key = elements_structure.shape_key_add() + + for atom_frame, atom_structure in zip(elements_frame, key.data): + + atom_structure.co = atom_frame.location - elements_structure.location + + key.name = atom_frame.name + "_frame_" + str(i) + + i += 1 + + num_frames = i + + scn.frame_start = 0 + scn.frame_end = frame_delta * num_frames + + # Manage the values of the keys + for element in STRUCTURE: + + scn.frame_current = 0 + + element.data.shape_keys.key_blocks[1].value = 1.0 + element.data.shape_keys.key_blocks[2].value = 0.0 + + element.data.shape_keys.key_blocks[1].keyframe_insert("value") + element.data.shape_keys.key_blocks[2].keyframe_insert("value") + + scn.frame_current += frame_delta + + for number in range(num_frames)[2:]:#-1]: + + element.data.shape_keys.key_blocks[number-1].value = 0.0 + element.data.shape_keys.key_blocks[number].value = 1.0 + element.data.shape_keys.key_blocks[number+1].value = 0.0 + + element.data.shape_keys.key_blocks[number-1].keyframe_insert("value") + element.data.shape_keys.key_blocks[number].keyframe_insert("value") + element.data.shape_keys.key_blocks[number+1].keyframe_insert("value") + + scn.frame_current += frame_delta + + number += 1 + + element.data.shape_keys.key_blocks[number].value = 1.0 + element.data.shape_keys.key_blocks[number-1].value = 0.0 + + element.data.shape_keys.key_blocks[number].keyframe_insert("value") + element.data.shape_keys.key_blocks[number-1].keyframe_insert("value") + + + diff -Nru blender-2.61/release/scripts/addons_contrib/io_mesh_xyz/__init__.py blender-2.62/release/scripts/addons_contrib/io_mesh_xyz/__init__.py --- blender-2.61/release/scripts/addons_contrib/io_mesh_xyz/__init__.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/io_mesh_xyz/__init__.py 2012-02-15 19:43:39.000000000 +0000 @@ -0,0 +1,727 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the 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. +# +# ##### END GPL LICENSE BLOCK ##### + +bl_info = { + "name": "XYZ Atomic Blender", + "description": "Loading and manipulating atoms from XYZ files", + "author": "Clemens Barth", + "version": (0,5), + "blender": (2,6), + "location": "File -> Import -> XYZ (.xyz), Panel: View 3D - Tools", + "warning": "", + "wiki_url": "http://development.root-1.de/Atomic_Blender.php", + "tracker_url": "http://projects.blender.org/tracker/" + "index.php?func=detail&aid=29646&group_id=153&atid=468", + "category": "Import-Export" +} + + +import bpy +from bpy.types import Operator, Panel +from bpy_extras.io_utils import ImportHelper +from bpy.props import (StringProperty, + BoolProperty, + EnumProperty, + IntProperty, + FloatProperty) + + + +from . import import_xyz +ATOM_XYZ_ERROR = "" + +# ----------------------------------------------------------------------------- +# GUI + +# This is the panel, which can be used to prepare the scene. +# It is loaded after the file has been chosen via the menu 'File -> Import' +class CLASS_atom_xyz_prepare_panel(Panel): + bl_label = "XYZ - Atomic Blender" + #bl_space_type = "PROPERTIES" + #bl_region_type = "WINDOW" + #bl_context = "physics" + # This could be also an option ... : + bl_space_type = "VIEW_3D" + bl_region_type = "TOOL_PROPS" + + @classmethod + def poll(self, context): + if import_xyz.ATOM_XYZ_FILEPATH == "": + return False + else: + return True + + def draw(self, context): + layout = self.layout + scn = bpy.context.scene + + row = layout.row() + row.label(text="Outputs and custom data file") + + box = layout.box() + row = box.row() + row.label(text="Custom data file") + row = box.row() + col = row.column() + col.prop(scn, "atom_xyz_datafile") + col.operator("atom_xyz.datafile_apply") + row = box.row() + col = row.column(align=True) + col.prop(scn, "atom_xyz_XYZ_file") + row = box.row() + # TODO, use lanel() instead + row.prop(scn, "atom_xyz_number_atoms") + row = box.row() + row.operator("atom_xyz.button_distance") + row.prop(scn, "atom_xyz_distance") + + row = layout.row() + row.label(text="Choice of atom radii") + box = layout.box() + + row = box.row() + row.label(text="All changes concern:") + row = box.row() + row.prop(scn, "atom_xyz_radius_how") + + row = box.row() + row.label(text="1. Change type of radii") + row = box.row() + row.prop(scn, "atom_xyz_radius_type") + + row = box.row() + row.label(text="2. Change atom radii in pm") + row = box.row() + row.prop(scn, "atom_xyz_radius_pm_name") + row = box.row() + row.prop(scn, "atom_xyz_radius_pm") + + row = box.row() + row.label(text="3. Change atom radii by scale") + row = box.row() + col = row.column() + col.prop(scn, "atom_xyz_radius_all") + col = row.column(align=True) + col.operator( "atom_xyz.radius_all_bigger" ) + col.operator( "atom_xyz.radius_all_smaller" ) + + if bpy.context.mode == 'EDIT_MESH': + + layout.separator() + row = box.row() + row.operator( "atom_xyz.separate_atom" ) + + row = layout.row() + row.label(text="Loading frames") + + box = layout.box() + row = box.row() + col = row.column() + col.label(text="Frames") + col = row.column() + col.prop(scn, "atom_xyz_number_frames") + row = box.row() + col = row.column() + col.label(text="Skip frames") + col = row.column() + col.prop(scn, "atom_xyz_skip_frames") + row = box.row() + col = row.column() + col.label(text="Frames/key") + col = row.column() + col.prop(scn, "atom_xyz_images_per_key") + + row = box.row() + row.operator("atom_xyz.load_frames") + row = box.row() + row.operator("atom_xyz.delete_keys") + row = box.row() + row.operator( "atom_xyz.create_command") + row = box.row() + row.operator( "atom_xyz.render") + + +class CLASS_atom_xyz_IO(bpy.types.PropertyGroup): + + def Callback_radius_type(self, context): + scnn = bpy.context.scene + import_xyz.DEF_atom_xyz_radius_type( + scnn.atom_xyz_radius_type, + scnn.atom_xyz_radius_how, + ) + + def Callback_radius_pm(self, context): + scnn = bpy.context.scene + import_xyz.DEF_atom_xyz_radius_pm( + scnn.atom_xyz_radius_pm_name, + scnn.atom_xyz_radius_pm, + scnn.atom_xyz_radius_how, + ) + + # In the file dialog window + scn = bpy.types.Scene + scn.use_atom_xyz_cam = BoolProperty( + name="Camera", default=False, + description="Do you need a camera?") + scn.use_atom_xyz_lamp = BoolProperty( + name="Lamp", default=False, + description = "Do you need a lamp?") + scn.use_atom_xyz_mesh = BoolProperty( + name = "Mesh balls", default=False, + description = "Do you want to use mesh balls instead of NURBS?") + scn.atom_xyz_mesh_azimuth = IntProperty( + name = "Azimuth", default=32, min=0, + description = "Number of sectors (azimuth)") + scn.atom_xyz_mesh_zenith = IntProperty( + name = "Zenith", default=32, min=0, + description = "Number of sectors (zenith)") + scn.atom_xyz_scale_ballradius = FloatProperty( + name = "Balls", default=1.0, min=0.0, + description = "Scale factor for all atom radii") + scn.atom_xyz_scale_distances = FloatProperty ( + name = "Distances", default=1.0, min=0.0, + description = "Scale factor for all distances") + scn.use_atom_xyz_center = BoolProperty( + name = "Object to origin", default=False, + description = "Shall the object first put into the global origin " + "before applying the offsets on the left?") + scn.atom_xyz_atomradius = EnumProperty( + name="Type of radius", + description="Choose type of atom radius", + items=(('0', "Pre-defined", "Use pre-defined radii"), + ('1', "Atomic", "Use atomic radii"), + ('2', "van der Waals", "Use van der Waals radii")), + default='0',) + + # In the panel, first part + scn.atom_xyz_datafile = StringProperty( + name = "", description="Path to your custom data file", + maxlen = 256, default = "", subtype='FILE_PATH') + scn.atom_xyz_XYZ_file = StringProperty( + name = "Path to file", default="", + description = "Path of the XYZ file") + # TODO, remove this property, its used for display only! + scn.atom_xyz_number_atoms = StringProperty(name="", + default="Number", description = "This output shows " + "the number of atoms which have been loaded") + scn.atom_xyz_distance = StringProperty( + name="", default="Distance (A)", + description="Distance of 2 objects in Angstrom") + scn.atom_xyz_radius_how = EnumProperty( + name="", + description="Which objects shall be modified?", + items=(('ALL_ACTIVE',"all active objects", "in the current layer"), + ('ALL_IN_LAYER',"all"," in active layer(s)")), + default='ALL_ACTIVE',) + scn.atom_xyz_radius_type = EnumProperty( + name="Type", + description="Which type of atom radii?", + items=(('0',"predefined", "Use pre-defined radii"), + ('1',"atomic", "Use atomic radii"), + ('2',"van der Waals","Use van der Waals radii")), + default='0',update=Callback_radius_type) + scn.atom_xyz_radius_pm_name = StringProperty( + name="", default="Atom name", + description="Put in the name of the atom (e.g. Hydrogen)") + scn.atom_xyz_radius_pm = FloatProperty( + name="", default=100.0, min=0.0, + description="Put in the radius of the atom (in pm)", + update=Callback_radius_pm) + scn.atom_xyz_radius_all = FloatProperty( + name="Scale", default = 1.05, min=1.0, + description="Put in the scale factor") + + + # In the panel, second part + scn.atom_xyz_number_frames = StringProperty( + name="", default="0", + description="This is the total number of frames stored in the xyz file") + scn.atom_xyz_skip_frames = IntProperty( + name="", default=0, min=0, + description="Number of frames you want to skip.") + scn.atom_xyz_images_per_key = IntProperty( + name="", default=1, min=0, + description="Choose the number of images between 2 keys.") + + + +# Button for creating a file that contains the command for rendering +class CLASS_atom_xyz_create_command(Operator): + bl_idname = "atom_xyz.create_command" + bl_label = "Create command" + bl_description = "Create a shell command for rendering the scene" + + def execute(self, context): + global ATOM_XYZ_ERROR + import os + + scn = bpy.context.scene + + fstart = scn.frame_start + fend = scn.frame_end + file_blend = bpy.context.blend_data.filepath + + if file_blend == "": + ATOM_XYZ_ERROR = "Save your scene first !" + bpy.ops.atom_xyz.error_dialog('INVOKE_DEFAULT') + return {'FINISHED'} + + cameras = [] + FOUND = False + for obj in bpy.context.scene.objects: + if obj.type == "CAMERA": + cameras.append(obj) + FOUND = True + if FOUND == False: + ATOM_XYZ_ERROR = "No camera => no images !" + bpy.ops.atom_xyz.error_dialog('INVOKE_DEFAULT') + return {'FINISHED'} + if bpy.context.scene.camera == None: + bpy.context.scene.camera = cameras[0] + + KEYS_PRESENT = True + for element in import_xyz.STRUCTURE: + bpy.ops.object.select_all(action='DESELECT') + bpy.context.scene.objects.active = element + element.select = True + if element.data.shape_keys == None: + KEYS_PRESENT = False + break + if KEYS_PRESENT == False: + ATOM_XYZ_ERROR = "No frames => no movie !" + bpy.ops.atom_xyz.error_dialog('INVOKE_DEFAULT') + return {'FINISHED'} + + bpy.ops.wm.save_mainfile() + + file_name = bpy.path.basename(file_blend) + file_path = file_blend.replace(file_name,"") + file_movie = bpy.path.display_name_from_filepath(file_blend) + blender_exe = bpy.app.binary_path + + if os.name == "posix": + execute = (blender_exe+" -b \'"+file_blend+"\' -x 1 -o //"+file_movie+ + "_ -F AVIJPEG -s "+str(fstart)+" -e "+str(scn.frame_end)+" -a") + else: + execute = ("\""+blender_exe+"\" -b "+file_blend+" -x 1 -o //"+file_movie+ + "_ -F AVIJPEG -s "+str(fstart)+" -e "+str(scn.frame_end)+" -a") + + if os.name == "posix": + command_file = file_path + file_movie + ".sh" + else: + command_file = file_path + file_movie + ".txt" + command_fp = open(command_file,"w") + + if os.name == "posix": + command_fp.write("#!/bin/sh\n") + command_fp.write("\n"+execute+"\n") + command_fp.close() + + return {'FINISHED'} + + +# Button for rendering the scene in a terminal +class CLASS_atom_xyz_render(Operator): + bl_idname = "atom_xyz.render" + bl_label = "Render" + bl_description = "Render the scene" + + def execute(self, context): + global ATOM_XYZ_ERROR + import os + + scn = bpy.context.scene + + fstart = scn.frame_start + fend = scn.frame_end + file_blend = bpy.context.blend_data.filepath + + if file_blend == "": + ATOM_XYZ_ERROR = "Save your scene first!" + bpy.ops.atom_xyz.error_dialog('INVOKE_DEFAULT') + return {'FINISHED'} + + cameras = [] + FOUND = False + for obj in bpy.context.scene.objects: + if obj.type == "CAMERA": + cameras.append(obj) + FOUND = True + if FOUND == False: + ATOM_XYZ_ERROR = "No camera => no images !" + bpy.ops.atom_xyz.error_dialog('INVOKE_DEFAULT') + return {'FINISHED'} + if bpy.context.scene.camera == None: + bpy.context.scene.camera = cameras[0] + + + KEYS_PRESENT = True + for element in import_xyz.STRUCTURE: + bpy.ops.object.select_all(action='DESELECT') + bpy.context.scene.objects.active = element + element.select = True + if element.data.shape_keys == None: + KEYS_PRESENT = False + break + if KEYS_PRESENT == False: + ATOM_XYZ_ERROR = "No frames => no movie !" + bpy.ops.atom_xyz.error_dialog('INVOKE_DEFAULT') + return {'FINISHED'} + + bpy.ops.wm.save_mainfile() + + file_name = bpy.path.basename(file_blend) + file_path = file_blend.replace(file_name,"") + file_movie = bpy.path.display_name_from_filepath(file_blend) + blender_exe = bpy.app.binary_path + + if os.name == "posix": + execute = (blender_exe+" -b \'"+file_blend+"\' -x 1 -o //"+file_movie+ + "_ -F AVIJPEG -s "+str(fstart)+" -e "+str(scn.frame_end)+" -a") + os_str = "xterm -e \"" + execute + "\" &" + else: + execute = ("\""+blender_exe+"\" -b "+file_blend+" -x 1 -o //"+file_movie+ + "_ -F AVIJPEG -s "+str(fstart)+" -e "+str(scn.frame_end)+" -a") + os_str = "C:\WINDOWS\system32\cmd.exe /C " + execute + + #print(os_str) + os.system(os_str) + + return {'FINISHED'} + + +# Button deleting all shape keys of the structure +class CLASS_atom_xyz_delete_keys(Operator): + bl_idname = "atom_xyz.delete_keys" + bl_label = "Delete keys" + bl_description = "Delete the shape keys" + + def execute(self, context): + + for element in import_xyz.STRUCTURE: + + if element.data.shape_keys == None: + break + + bpy.ops.object.select_all(action='DESELECT') + bpy.context.scene.objects.active = element + element.select = True + + for key in element.data.shape_keys.key_blocks: + + bpy.ops.object.shape_key_remove() + + + return {'FINISHED'} + + +# Button loading the shape keys +class CLASS_atom_xyz_load_frames(Operator): + bl_idname = "atom_xyz.load_frames" + bl_label = "Load frames" + bl_description = "Load the frames" + + def execute(self, context): + global ATOM_XYZ_ERROR + + scn = bpy.context.scene + + KEYS_PRESENT = False + for element in import_xyz.STRUCTURE: + bpy.ops.object.select_all(action='DESELECT') + bpy.context.scene.objects.active = element + element.select = True + if element.data.shape_keys != None: + KEYS_PRESENT = True + break + + if KEYS_PRESENT == True: + ATOM_XYZ_ERROR = "Delete first the keys" + bpy.ops.atom_xyz.error_dialog('INVOKE_DEFAULT') + return {'FINISHED'} + + + import_xyz.DEF_atom_xyz_build_frames(scn.atom_xyz_images_per_key, scn.atom_xyz_skip_frames) + + return {'FINISHED'} + + + +# Button loading a custom data file +class CLASS_atom_xyz_datafile_apply(Operator): + bl_idname = "atom_xyz.datafile_apply" + bl_label = "Apply" + bl_description = "Use color and radii values stored in the custom file" + + def execute(self, context): + + scn = bpy.context.scene + + if scn.atom_xyz_datafile == "": + return {'FINISHED'} + + import_xyz.DEF_atom_xyz_custom_datafile(scn.atom_xyz_datafile) + + # TODO, move this into 'import_xyz' and call the function + for obj in bpy.context.selected_objects: + if len(obj.children) != 0: + child = obj.children[0] + if child.type == "SURFACE" or child.type == "MESH": + for element in import_xyz.ATOM_XYZ_ELEMENTS: + if element.name in obj.name: + child.scale = (element.radii[0],) * 3 + child.active_material.diffuse_color = element.color + else: + if obj.type == "SURFACE" or obj.type == "MESH": + for element in import_xyz.ATOM_XYZ_ELEMENTS: + if element.name in obj.name: + obj.scale = (element.radii[0],) * 3 + obj.active_material.diffuse_color = element.color + + return {'FINISHED'} + + +# Button for separating a single atom from a structure +class CLASS_atom_xyz_separate_atom(Operator): + bl_idname = "atom_xyz.separate_atom" + bl_label = "Separate atom" + bl_description = "Separate the atom you have chosen" + + def execute(self, context): + scn = bpy.context.scene + + # Get first all important properties from the atom which the user + # has chosen: location, color, scale + obj = bpy.context.edit_object + name = obj.name + loc_obj_vec = obj.location + scale = obj.children[0].scale + material = obj.children[0].active_material + + # Separate the vertex from the main mesh and create a new mesh. + bpy.ops.mesh.separate() + new_object = bpy.context.scene.objects[0] + # Keep in mind the coordinates <= We only need this + loc_vec = new_object.data.vertices[0].co + + # And now, switch to the OBJECT mode such that we can ... + bpy.ops.object.mode_set(mode='OBJECT', toggle=False) + # ... delete the new mesh including the separated vertex + bpy.ops.object.select_all(action='DESELECT') + new_object.select = True + bpy.ops.object.delete() # TODO, use scene.objects.unlink() + + # Create a new atom/vacancy at the position of the old atom + current_layers=bpy.context.scene.layers + + if "Vacancy" not in name: + if scn.use_atom_xyz_mesh == False: + bpy.ops.surface.primitive_nurbs_surface_sphere_add( + view_align=False, enter_editmode=False, + location=loc_vec+loc_obj_vec, + rotation=(0.0, 0.0, 0.0), + layers=current_layers) + else: + bpy.ops.mesh.primitive_uv_sphere_add( + segments=scn.atom_xyz_mesh_azimuth, + ring_count=scn.atom_xyz_mesh_zenith, + size=1, view_align=False, enter_editmode=False, + location=loc_vec+loc_obj_vec, + rotation=(0, 0, 0), + layers=current_layers) + else: + bpy.ops.mesh.primitive_cube_add( + view_align=False, enter_editmode=False, + location=loc_vec+loc_obj_vec, + rotation=(0.0, 0.0, 0.0), + layers=current_layers) + + new_atom = bpy.context.scene.objects.active + # Scale, material and name it. + new_atom.scale = scale + new_atom.active_material = material + new_atom.name = name + "_sep" + + # Switch back into the 'Edit mode' because we would like to seprate + # other atoms may be (more convinient) + new_atom.select = False + obj.select = True + bpy.context.scene.objects.active = obj + bpy.ops.object.select_all(action='DESELECT') + bpy.ops.object.mode_set(mode='EDIT', toggle=False) + + return {'FINISHED'} + + +# Button for measuring the distance of the active objects +class CLASS_atom_xyz_distance_button(Operator): + bl_idname = "atom_xyz.button_distance" + bl_label = "Measure ..." + bl_description = "Measure the distance between two objects" + + def execute(self, context): + scn = bpy.context.scene + dist = import_xyz.DEF_atom_xyz_distance() + + if dist != "N.A.": + # The string length is cut, 3 digits after the first 3 digits + # after the '.'. Append also "Angstrom". + # Remember: 1 Angstrom = 10^(-10) m + pos = str.find(dist, ".") + dist = dist[:pos+4] + dist = dist + " A" + + # Put the distance into the string of the output field. + scn.atom_xyz_distance = dist + return {'FINISHED'} + + +# Button for increasing the radii of all atoms +class CLASS_atom_xyz_radius_all_bigger_button(Operator): + bl_idname = "atom_xyz.radius_all_bigger" + bl_label = "Bigger ..." + bl_description = "Increase the radii of the atoms" + + def execute(self, context): + scn = bpy.context.scene + import_xyz.DEF_atom_xyz_radius_all( + scn.atom_xyz_radius_all, + scn.atom_xyz_radius_how, + ) + return {'FINISHED'} + + +# Button for decreasing the radii of all atoms +class CLASS_atom_xyz_radius_all_smaller_button(Operator): + bl_idname = "atom_xyz.radius_all_smaller" + bl_label = "Smaller ..." + bl_description = "Decrease the radii of the atoms" + + def execute(self, context): + scn = bpy.context.scene + import_xyz.DEF_atom_xyz_radius_all( + 1.0/scn.atom_xyz_radius_all, + scn.atom_xyz_radius_how, + ) + return {'FINISHED'} + + + +# This is the class for the file dialog. +class ImportXYZ(Operator, ImportHelper): + bl_idname = "import_mesh.xyz" + bl_label = "Import XYZ (*.xyz)" + + filename_ext = ".xyz" + filter_glob = StringProperty(default="*.xyz", options={'HIDDEN'},) + + def draw(self, context): + layout = self.layout + scn = bpy.context.scene + + row = layout.row() + row.prop(scn, "use_atom_xyz_cam") + row.prop(scn, "use_atom_xyz_lamp") + row = layout.row() + col = row.column() + col.prop(scn, "use_atom_xyz_mesh") + col = row.column(align=True) + col.prop(scn, "atom_xyz_mesh_azimuth") + col.prop(scn, "atom_xyz_mesh_zenith") + + row = layout.row() + col = row.column() + col.label(text="Scaling factors") + col = row.column(align=True) + col.prop(scn, "atom_xyz_scale_ballradius") + col.prop(scn, "atom_xyz_scale_distances") + + row = layout.row() + row.prop(scn, "use_atom_xyz_center") + + row = layout.row() + row.prop(scn, "atom_xyz_atomradius") + + def execute(self, context): + scn = bpy.context.scene + + import_xyz.ALL_FRAMES[:] = [] + import_xyz.NUMBER_FRAMES = 0 + import_xyz.ATOM_XYZ_ELEMENTS[:] = [] + import_xyz.ATOM_XYZ_FILEPATH = "" + import_xyz.STRUCTURE[:] = [] + + # This is in order to solve this strange 'relative path' thing. + import_xyz.ATOM_XYZ_FILEPATH = bpy.path.abspath(self.filepath) + + scn.atom_xyz_XYZ_file = import_xyz.ATOM_XYZ_FILEPATH + + azimuth = scn.atom_xyz_mesh_azimuth + zenith = scn.atom_xyz_mesh_zenith + bradius = scn.atom_xyz_scale_ballradius + bdistance = scn.atom_xyz_scale_distances + radiustype = scn.atom_xyz_atomradius + center = scn.use_atom_xyz_center + cam = scn.use_atom_xyz_cam + lamp = scn.use_atom_xyz_lamp + mesh = scn.use_atom_xyz_mesh + datafile = scn.atom_xyz_datafile + + # Execute main routine + atom_number = import_xyz.DEF_atom_xyz_main( + mesh, azimuth, zenith, bradius, + radiustype, bdistance, + center, cam, lamp, datafile) + + scn.atom_xyz_number_atoms = str(atom_number) + " atoms" + scn.atom_xyz_number_frames = str(import_xyz.NUMBER_FRAMES) + + return {'FINISHED'} + + +class CLASS_atom_xyz_error_dialog(bpy.types.Operator): + bl_idname = "atom_xyz.error_dialog" + bl_label = "Attention !" + + def draw(self, context): + layout = self.layout + row = layout.row() + row.label(text=" "+ATOM_XYZ_ERROR) + def execute(self, context): + print("Atomic Blender - Error: "+ATOM_XYZ_ERROR+"\n") + return {'FINISHED'} + def invoke(self, context, event): + return context.window_manager.invoke_props_dialog(self) + + +# The entry into the menu 'file -> import' +def menu_func(self, context): + self.layout.operator(ImportXYZ.bl_idname, text="XYZ (.xyz)") + + +def register(): + bpy.utils.register_module(__name__) + bpy.types.INFO_MT_file_import.append(menu_func) + +def unregister(): + bpy.utils.unregister_module(__name__) + bpy.types.INFO_MT_file_import.remove(menu_func) + +if __name__ == "__main__": + + register() diff -Nru blender-2.61/release/scripts/addons_contrib/io_points_pcd/__init__.py blender-2.62/release/scripts/addons_contrib/io_points_pcd/__init__.py --- blender-2.61/release/scripts/addons_contrib/io_points_pcd/__init__.py 2011-12-13 19:59:34.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/io_points_pcd/__init__.py 2012-02-15 19:43:53.000000000 +0000 @@ -21,7 +21,6 @@ "author": "Aurel Wildfellner", "version": (0, 1), "blender": (2, 5, 7), - "api": 37304, "location": "File > Import-Export > Point Cloud Data", "description": "Imports and Exports PCD (Point Cloud Data) files. PCD files are the default format used by pcl (Point Cloud Library).", "warning": "", diff -Nru blender-2.61/release/scripts/addons_contrib/io_scene_ms3d/__init__.py blender-2.62/release/scripts/addons_contrib/io_scene_ms3d/__init__.py --- blender-2.61/release/scripts/addons_contrib/io_scene_ms3d/__init__.py 2011-12-13 19:59:29.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/io_scene_ms3d/__init__.py 2012-02-15 19:43:47.000000000 +0000 @@ -16,11 +16,27 @@ # # ##### END GPL LICENSE BLOCK ##### +# + +bl_info = { + "name": "MilkShape3D MS3D format (.ms3d)", + "description": "Import / Export MilkShape3D MS3D files" + " (conform with v1.8.4)", + "author": "Alexander Nussbaumer", + "version": (0, 3, 8), + "blender": (2, 60, 0), + "location": "File > Import-Export", + "warning": "[2012-01-17] side-by-side implementation for Matrix handling around rev.42816", + "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\ + "Scripts/Import-Export/MilkShape3D_MS3D", + "tracker_url": "http://projects.blender.org/tracker/index.php"\ + "?func=detail&aid=29404", + "category": 'Import-Export', + } ############################################################################### #234567890123456789012345678901234567890123456789012345678901234567890123456789 #--------1---------2---------3---------4---------5---------6---------7--------- -# # ##### BEGIN COPYRIGHT BLOCK ##### @@ -34,6 +50,8 @@ # if it's there, reload everything if ("bpy" in locals()): import imp + if "ms3d_utils" in locals(): + imp.reload(ms3d_utils) if "ms3d_export" in locals(): imp.reload(ms3d_export) if "ms3d_import" in locals(): @@ -41,6 +59,7 @@ pass else: + from . import ms3d_utils from . import ms3d_export from . import ms3d_import pass @@ -51,25 +70,6 @@ import bpy_extras -bl_info = { - "name": "MilkShape3D MS3D format (.ms3d)", - "description": "Import / Export MilkShape3D MS3D files" - " (conform with v1.8.4)", - "author": "Alexander Nussbaumer", - "version": (0, 3, 6), - "blender": (2, 60, 0), - "api": 41226, - "location": "File > Import-Export", - "warning": "imports and exports only geometry and material of ms3d"\ - " file. (poor performance)", - "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\ - "Scripts/Import-Export/MilkShape3D_MS3D", - "tracker_url": "http://projects.blender.org/tracker/index.php"\ - "?func=detail&aid=29404", - "category": 'Import-Export', - } - - ############################################################################### # registration def menu_func_import(self, context): diff -Nru blender-2.61/release/scripts/addons_contrib/io_scene_ms3d/ms3d_export.py blender-2.62/release/scripts/addons_contrib/io_scene_ms3d/ms3d_export.py --- blender-2.61/release/scripts/addons_contrib/io_scene_ms3d/ms3d_export.py 2011-12-13 19:59:29.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/io_scene_ms3d/ms3d_export.py 2012-02-15 19:43:47.000000000 +0000 @@ -16,11 +16,11 @@ # # ##### END GPL LICENSE BLOCK ##### +# ############################################################################### #234567890123456789012345678901234567890123456789012345678901234567890123456789 #--------1---------2---------3---------4---------5---------6---------7--------- -# # ##### BEGIN COPYRIGHT BLOCK ##### @@ -59,7 +59,12 @@ import bpy import bpy_extras.io_utils -from bpy.props import * +from bpy.props import ( + BoolProperty, + EnumProperty, + FloatProperty, + StringProperty, + ) # registered entry point export @@ -77,14 +82,14 @@ bl_region_type = 'WINDOW' filename_ext = ms3d_utils.FILE_EXT - filter_glob = bpy.props.StringProperty( + filter_glob = StringProperty( default=ms3d_utils.FILE_FILTER, options={'HIDDEN'} ) - filepath = bpy.props.StringProperty(subtype='FILE_PATH') + filepath = StringProperty(subtype='FILE_PATH') - prop_verbose = bpy.props.BoolProperty( + prop_verbose = BoolProperty( name=ms3d_utils.PROP_NAME_VERBOSE, description=ms3d_utils.PROP_DESC_VERBOSE, default=ms3d_utils.PROP_DEFAULT_VERBOSE, @@ -118,27 +123,20 @@ options=ms3d_utils.PROP_OPT_OBJECTS_EXP, ) - prop_selected = bpy.props.BoolProperty( + prop_selected = BoolProperty( name=ms3d_utils.PROP_NAME_SELECTED, description=ms3d_utils.PROP_DESC_SELECTED, default=ms3d_utils.PROP_DEFAULT_SELECTED, options=ms3d_utils.PROP_OPT_SELECTED, ) - prop_animation = bpy.props.BoolProperty( + prop_animation = BoolProperty( name=ms3d_utils.PROP_NAME_ANIMATION, description=ms3d_utils.PROP_DESC_ANIMATION, default=ms3d_utils.PROP_DEFAULT_ANIMATION, options=ms3d_utils.PROP_OPT_ANIMATION, ) - prop_animation_fp = bpy.props.BoolProperty( - name=ms3d_utils.PROP_NAME_ANIMATION_FP, - description=ms3d_utils.PROP_DESC_ANIMATION_FP, - default=ms3d_utils.PROP_DEFAULT_ANIMATION_FP, - options=ms3d_utils.PROP_OPT_ANIMATION_FP, - ) - # draw the option panel def draw(self, context): diff -Nru blender-2.61/release/scripts/addons_contrib/io_scene_ms3d/ms3d_import.py blender-2.62/release/scripts/addons_contrib/io_scene_ms3d/ms3d_import.py --- blender-2.61/release/scripts/addons_contrib/io_scene_ms3d/ms3d_import.py 2011-12-13 19:59:29.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/io_scene_ms3d/ms3d_import.py 2012-02-15 19:43:47.000000000 +0000 @@ -16,11 +16,11 @@ # # ##### END GPL LICENSE BLOCK ##### +# ############################################################################### #234567890123456789012345678901234567890123456789012345678901234567890123456789 #--------1---------2---------3---------4---------5---------6---------7--------- -# # ##### BEGIN COPYRIGHT BLOCK ##### @@ -60,7 +60,12 @@ import bpy_extras.io_utils from bpy_extras.image_utils import load_image -from bpy.props import * +from bpy.props import ( + BoolProperty, + EnumProperty, + FloatProperty, + StringProperty, + ) ############################################################################### @@ -78,6 +83,15 @@ ############################################################################### +_idb_ms3d = 0 +_idb_blender = 1 +_idb_roll = 2 + +_bone_dummy = 1.0 +_bone_distort = 0.00001 # sys.float_info.epsilon + + +############################################################################### # registered entry point import class ImportMS3D( bpy.types.Operator, @@ -93,14 +107,14 @@ bl_region_type = 'WINDOW' filename_ext = ms3d_utils.FILE_EXT - filter_glob = bpy.props.StringProperty( + filter_glob = StringProperty( default=ms3d_utils.FILE_FILTER, options={'HIDDEN'} ) - filepath = bpy.props.StringProperty(subtype='FILE_PATH') + filepath = StringProperty(subtype='FILE_PATH') - prop_verbose = bpy.props.BoolProperty( + prop_verbose = BoolProperty( name=ms3d_utils.PROP_NAME_VERBOSE, description=ms3d_utils.PROP_DESC_VERBOSE, default=ms3d_utils.PROP_DEFAULT_VERBOSE, @@ -126,7 +140,7 @@ options=ms3d_utils.PROP_OPT_SCALE, ) - prop_unit_mm = bpy.props.BoolProperty( + prop_unit_mm = BoolProperty( name=ms3d_utils.PROP_NAME_UNIT_MM, description=ms3d_utils.PROP_DESC_UNIT_MM, default=ms3d_utils.PROP_DEFAULT_UNIT_MM, @@ -141,7 +155,7 @@ options=ms3d_utils.PROP_OPT_OBJECTS_IMP, ) - prop_animation = bpy.props.BoolProperty( + prop_animation = BoolProperty( name=ms3d_utils.PROP_NAME_ANIMATION, description=ms3d_utils.PROP_DESC_ANIMATION, default=ms3d_utils.PROP_DEFAULT_ANIMATION, @@ -202,6 +216,7 @@ # handle internal ms3d names to external blender names # to prevent potential name collisions on multiple imports # with same names but different content + self.dict_actions = {} self.dict_armatures = {} self.dict_armature_objects = {} self.dict_groups = {} @@ -254,24 +269,17 @@ ms3dTemplate.modelComment.comment if (ms3d_utils.PROP_ITEM_OBJECT_JOINT in self.prop_objects): - dict_bones = self.CreateArmature(blenderContext, ms3dTemplate) + dict_bones, blenderArmatureObject = self.CreateArmature( + blenderContext, ms3dTemplate) if self.prop_animation: - bpy.context.scene.render.fps = ms3dTemplate.fAnimationFPS - if ms3dTemplate.fAnimationFPS: - bpy.context.scene.render.fps_base = ( - bpy.context.scene.render.fps / - ms3dTemplate.fAnimationFPS) - bpy.context.scene.frame_start = 1 - bpy.context.scene.frame_end = (ms3dTemplate.iTotalFrames - + bpy.context.scene.frame_start) - 1 - bpy.context.scene.frame_current = ( - ms3dTemplate.fCurrentTime - * bpy.context.scene.render.fps) + self.CreateAnimation(blenderContext, ms3dTemplate, + dict_bones, blenderArmatureObject) + pass for ms3dGroupIndex, ms3dGroup in enumerate(ms3dTemplate.groups): blenderMesh = self.CreateMesh(blenderContext, ms3dTemplate, - ms3dGroup, ms3dGroupIndex, dict_bones) + ms3dGroup, ms3dGroupIndex) # apply material if available if ((ms3d_utils.PROP_ITEM_OBJECT_MATERIAL in self.prop_objects) @@ -327,7 +335,7 @@ ########################################################################### def CreateArmature(self, blenderContext, ms3dTemplate): if (ms3dTemplate.nNumJoints <= 0): - return None + return None, None blenderScene = blenderContext.scene @@ -350,8 +358,8 @@ dict_bones = {} for iBone, ms3dJoint in enumerate(ms3dTemplate.joints): - blenderBone = blenderArmature.edit_bones.new(ms3dJoint.name) + blenderBone[prop(ms3d_spec.PROP_NAME_NAME)] = ms3dJoint.name blenderBone[prop(ms3d_spec.PROP_NAME_FLAGS)] = ms3dJoint.flags ms3dComment = ms3dTemplate.get_joint_comment_by_key(iBone) @@ -367,8 +375,8 @@ blenderBone.select = True blenderArmature.edit_bones.active = blenderBone - # [blender bone, ms3d bone, number of references, roll vector] - dict_bones[ms3dJoint.name] = [blenderBone, ms3dJoint, 0, None] + # [ms3d bone, number of references, blender bone, roll vector] + dict_bones[ms3dJoint.name] = [ms3dJoint, blenderBone, None] mathVector = mathutils.Vector(ms3dJoint.position) mathVector = mathVector * self.matrixViewport @@ -379,14 +387,16 @@ #dummy tail blenderBone.tail = blenderBone.head + mathutils.Vector( - (0.00001, 0.0, 0.0)) + (_bone_dummy, 0.0, 0.0)) else: boneItem = dict_bones[ms3dJoint.parentName] - boneItem[2] += 1 - blenderBoneParent = boneItem[0] + blenderBoneParent = boneItem[_idb_blender] blenderBone.parent = blenderBoneParent + if self.prop_animation: + blenderBone.use_inherit_rotation = False + blenderBone.use_inherit_scale = False matrixRotation = mathutils.Matrix() for blenderBoneParent in blenderBone.parent_recursive: @@ -394,56 +404,155 @@ # correct rotaion axis rotationAxis = mathutils.Vector(( - -dict_bones[key][1].rotation[0], - -dict_bones[key][1].rotation[1], - -dict_bones[key][1].rotation[2])) + -dict_bones[key][_idb_ms3d].rotation[0], + -dict_bones[key][_idb_ms3d].rotation[1], + -dict_bones[key][_idb_ms3d].rotation[2])) rotationAxis = rotationAxis * self.matrixSwapAxis mathRotation = mathutils.Euler(rotationAxis, 'XZY') matrixRotation = matrixRotation * mathRotation.to_matrix( ).to_4x4() - blenderBone.head = blenderBone.parent.head + (mathVector + mathVector = blenderBone.parent.head + (mathVector * matrixRotation) + # at some very rare models, bones share the same place. + # but blender removes bones that share the same space, + # so distort the location a little bit + if mathVector == blenderBone.parent.head: + mathVector -= mathutils.Vector((_bone_distort, 0.0, 0.0)) + print("Info: distort bone in blender: '{0}'".format(blenderBone.name)) + + blenderBone.head = mathVector + # dummy tail blenderBone.tail = blenderBone.head + ( - mathutils.Vector((0.00001, 0.0, 0.0)) + mathutils.Vector((_bone_dummy, 0.0, 0.0)) * self.matrixSwapAxis * matrixRotation) if matrixRotation is not None: mathRollVector = (mathutils.Vector((0.0, 0.0, 1.0)) * matrixRotation) - boneItem[3] = mathRollVector + boneItem[_idb_roll] = mathRollVector # an adjustment pass - # to adjust connection and tails of its parent bones - for key in dict_bones: - boneItem = dict_bones[key] - blenderBone = boneItem[0] - ms3dBone = boneItem[1] - - # skip if parent has more than one bone references - parentBoneItem = dict_bones.get(ms3dBone.parentName) - if (parentBoneItem is None) or (parentBoneItem[2] > 1): + # to adjust connection and tails of bones + for blenderBone in blenderArmature.edit_bones: + # skip if it has no parent + if blenderBone.parent is None: continue - blenderBone.parent.tail = blenderBone.head - blenderBone.use_connect = True + # make nice blunt ending + if not blenderBone.children: + blenderBone.tail = blenderBone.parent.head + + # skip if parent has more than one children + numberChildren = len(blenderBone.children) + if (numberChildren == 1): + blenderBone.tail = blenderBone.children[0].head + blenderBone.children[0].use_connect = True # an extra additional adjustment pass # to re-correct possible modified bonerolls for key in dict_bones: boneItem = dict_bones[key] - blenderBone = boneItem[0] - mathRollVector = boneItem[3] + blenderBone = boneItem[_idb_blender] + mathRollVector = boneItem[_idb_roll] if mathRollVector is not None: blenderBone.align_roll(mathRollVector) + # make dict lightweight + boneItem[_idb_blender] = boneItem[_idb_blender].name + #boneItem[_idb_ms3d] = boneItem[_idb_ms3d] + boneItem[_idb_roll] = None + ms3d_utils.EnableEditMode(False) - return dict_bones + return dict_bones, blenderObject + + + ########################################################################### + def CreateAnimation(self, blenderContext, ms3dTemplate, dict_bones, blenderObject): + if (ms3dTemplate.nNumJoints <= 0): + return None + + blenderScene = blenderContext.scene + + blenderScene.render.fps = ms3dTemplate.fAnimationFPS + if ms3dTemplate.fAnimationFPS: + blenderScene.render.fps_base = (blenderScene.render.fps / + ms3dTemplate.fAnimationFPS) + blenderScene.frame_start = 1 + blenderScene.frame_end = (ms3dTemplate.iTotalFrames + + blenderScene.frame_start) - 1 + blenderScene.frame_current = (ms3dTemplate.fCurrentTime + * blenderScene.render.fps + / blenderScene.render.fps_base) + + blenderAction, setupAction = self.GetAction(ms3dTemplate) + if blenderObject.animation_data is None: + blenderObject.animation_data_create() + blenderObject.animation_data.action = blenderAction + + for boneName in dict_bones: + item = dict_bones[boneName] + blenderBoneName = item[_idb_blender] + ms3dJoint = item[_idb_ms3d] + + blenderBoneObject = blenderObject.pose.bones.get(blenderBoneName) + if blenderBoneObject is None: + # no idea why at some models are + # bones are missing in blender, but are present in dict + print("Info: missing bone in blender: '{0}'".format(blenderBoneName)) + continue + + blenderBone = blenderObject.data.bones.get(blenderBoneName) + + data_path = blenderBoneObject.path_from_id("location") + fcurveTransX = blenderAction.fcurves.new(data_path, index=0) + fcurveTransY = blenderAction.fcurves.new(data_path, index=1) + fcurveTransZ = blenderAction.fcurves.new(data_path, index=2) + for keyFramesTrans in ms3dJoint.keyFramesTrans: + frame = (keyFramesTrans.time + * blenderScene.render.fps + / blenderScene.render.fps_base) + translationAxis = mathutils.Vector(( + keyFramesTrans.position[0], + keyFramesTrans.position[1], + keyFramesTrans.position[2])) + translationAxis = translationAxis * self.matrixSwapAxis + fcurveTransX.keyframe_points.insert(frame, translationAxis[0]) + fcurveTransY.keyframe_points.insert(frame, translationAxis[1]) + fcurveTransZ.keyframe_points.insert(frame, translationAxis[2]) + + data_path = blenderBoneObject.path_from_id("rotation_euler") + blenderBoneObject.rotation_mode = 'XZY' + #data_path = blenderBoneObject.path_from_id("rotation_quaternion") + #fcurveRotW = blenderAction.fcurves.new(data_path, index=0) + fcurveRotX = blenderAction.fcurves.new(data_path, index=0) + fcurveRotY = blenderAction.fcurves.new(data_path, index=1) + fcurveRotZ = blenderAction.fcurves.new(data_path, index=2) + for keyFramesRot in ms3dJoint.keyFramesRot: + frame = (keyFramesRot.time + * blenderScene.render.fps + / blenderScene.render.fps_base) + rotationAxis = mathutils.Vector(( + -keyFramesRot.rotation[0], + -keyFramesRot.rotation[1], + -keyFramesRot.rotation[2])) + rotationAxis = rotationAxis * self.matrixSwapAxis + mathRotEuler = mathutils.Euler(rotationAxis, 'XZY') + + fcurveRotX.keyframe_points.insert(frame, mathRotEuler.x) + fcurveRotY.keyframe_points.insert(frame, mathRotEuler.y) + fcurveRotZ.keyframe_points.insert(frame, mathRotEuler.z) + + #mathRotQuaternion = mathRotEuler.to_quaternion() + #fcurveRotW.keyframe_points.insert(frame, mathRotQuaternion.w) + #fcurveRotX.keyframe_points.insert(frame, mathRotQuaternion.x) + #fcurveRotY.keyframe_points.insert(frame, mathRotQuaternion.y) + #fcurveRotZ.keyframe_points.insert(frame, mathRotQuaternion.z) ########################################################################### @@ -566,7 +675,7 @@ ########################################################################### def CreateMesh(self, blenderContext, ms3dTemplate, ms3dGroup, - ms3dGroupIndex, bones): + ms3dGroupIndex): vertices = [] edges = [] faces = [] @@ -593,7 +702,7 @@ if iBone is not None: iBone.append(iiVertex) else: - boneIds[ms3dVertex.boneId] = [iiVertex] + boneIds[ms3dVertex.boneId] = [iiVertex, ] face.append(iiVertex) faces.append(face) @@ -781,7 +890,9 @@ ########################################################################### - def GetAction(self, nameAction): + def GetAction(self, ms3dObject): + nameAction = ms3dObject.name + # already available blenderAction = self.dict_actions.get(nameAction) if blenderAction is not None: diff -Nru blender-2.61/release/scripts/addons_contrib/io_scene_ms3d/ms3d_spec.py blender-2.62/release/scripts/addons_contrib/io_scene_ms3d/ms3d_spec.py --- blender-2.61/release/scripts/addons_contrib/io_scene_ms3d/ms3d_spec.py 2011-12-13 19:59:29.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/io_scene_ms3d/ms3d_spec.py 2012-02-15 19:43:47.000000000 +0000 @@ -16,11 +16,11 @@ # # ##### END GPL LICENSE BLOCK ##### +# ############################################################################### #234567890123456789012345678901234567890123456789012345678901234567890123456789 #--------1---------2---------3---------4---------5---------6---------7--------- -# # ##### BEGIN COPYRIGHT BLOCK ##### diff -Nru blender-2.61/release/scripts/addons_contrib/io_scene_ms3d/ms3d_utils.py blender-2.62/release/scripts/addons_contrib/io_scene_ms3d/ms3d_utils.py --- blender-2.61/release/scripts/addons_contrib/io_scene_ms3d/ms3d_utils.py 2011-12-13 19:59:29.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/io_scene_ms3d/ms3d_utils.py 2012-02-15 19:43:47.000000000 +0000 @@ -16,11 +16,11 @@ # # ##### END GPL LICENSE BLOCK ##### +# ############################################################################### #234567890123456789012345678901234567890123456789012345678901234567890123456789 #--------1---------2---------3---------4---------5---------6---------7--------- -# # ##### BEGIN COPYRIGHT BLOCK ##### @@ -210,14 +210,6 @@ ############################################################################### -PROP_NAME_ANIMATION_FP = "Generate FuturePinball Script **)" -PROP_DESC_ANIMATION_FP = "Generates an animation script for FuturePinball and"\ - " exports bones as separate file" -PROP_DEFAULT_ANIMATION_FP = False -PROP_OPT_ANIMATION_FP = {OPT_ANIMATABLE} - - -############################################################################### REMARKS_1 = "*) partial implemented yet" REMARKS_2 = "**) not implemented yet" REMARKS_3 = "***) risk of unwanted results" @@ -277,9 +269,6 @@ box = layout.box() box.label(LABEL_NAME_ANIMATION, icon=LABEL_ICON_ANIMATION) box.prop(self, "prop_animation") - if (self.prop_animation): - box.prop(self, "prop_animation_fp") - box.label(REMARKS_2, icon='ERROR') ############################################################################### @@ -337,32 +326,63 @@ def CreateMatrixViewport(coordinate_system, scale): matrixSwapAxis = None - if (coordinate_system == PROP_ITEM_COORDINATESYSTEM_IMP): - # MS3D -> Blender - matrixSwapAxis = mathutils.Matrix(( - (0.0, 0.0, 1.0, 0.0), - (1.0, 0.0, 0.0, 0.0), - (0.0, 1.0, 0.0, 0.0), - (0.0, 0.0, 0.0, 1.0) - )) - - elif (coordinate_system == PROP_ITEM_COORDINATESYSTEM_EXP): - # Blender -> MS3D - matrixSwapAxis = mathutils.Matrix(( - (0.0, 1.0, 0.0, 0.0), - (0.0, 0.0, 1.0, 0.0), - (1.0, 0.0, 0.0, 0.0), - (0.0, 0.0, 0.0, 1.0) - )) - + if bpy.app.build_revision < '42816': + # for OLD implementation, older than blender rev. 42816 + if (coordinate_system == PROP_ITEM_COORDINATESYSTEM_IMP): + # MS3D -> Blender + matrixSwapAxis = mathutils.Matrix(( + (0.0, 0.0, 1.0, 0.0), + (1.0, 0.0, 0.0, 0.0), + (0.0, 1.0, 0.0, 0.0), + (0.0, 0.0, 0.0, 1.0) + )) + + elif (coordinate_system == PROP_ITEM_COORDINATESYSTEM_EXP): + # Blender -> MS3D + matrixSwapAxis = mathutils.Matrix(( + (0.0, 1.0, 0.0, 0.0), + (0.0, 0.0, 1.0, 0.0), + (1.0, 0.0, 0.0, 0.0), + (0.0, 0.0, 0.0, 1.0) + )) + + else: + # 1:1 + matrixSwapAxis = mathutils.Matrix(( + (1.0, 0.0, 0.0, 0.0), + (0.0, 1.0, 0.0, 0.0), + (0.0, 0.0, 1.0, 0.0), + (0.0, 0.0, 0.0, 1.0) + )) else: - # 1:1 - matrixSwapAxis = mathutils.Matrix(( - (1.0, 0.0, 0.0, 0.0), - (0.0, 1.0, 0.0, 0.0), - (0.0, 0.0, 1.0, 0.0), - (0.0, 0.0, 0.0, 1.0) - )) + # for new implementation since blender rev. 42816 + if (coordinate_system == PROP_ITEM_COORDINATESYSTEM_IMP): + # MS3D -> Blender (since Blender rev.42816) + matrixSwapAxis = mathutils.Matrix(( + (0.0, 1.0, 0.0, 0.0), + (0.0, 0.0, 1.0, 0.0), + (1.0, 0.0, 0.0, 0.0), + (0.0, 0.0, 0.0, 1.0) + )) + + elif (coordinate_system == PROP_ITEM_COORDINATESYSTEM_EXP): + # Blender -> MS3D (since Blender rev.42816) + matrixSwapAxis = mathutils.Matrix(( + (0.0, 0.0, 1.0, 0.0), + (1.0, 0.0, 0.0, 0.0), + (0.0, 1.0, 0.0, 0.0), + (0.0, 0.0, 0.0, 1.0) + )) + + else: + # 1:1 + matrixSwapAxis = mathutils.Matrix(( + (1.0, 0.0, 0.0, 0.0), + (0.0, 1.0, 0.0, 0.0), + (0.0, 0.0, 1.0, 0.0), + (0.0, 0.0, 0.0, 1.0) + )) + return matrixSwapAxis * scale, matrixSwapAxis diff -Nru blender-2.61/release/scripts/addons_contrib/io_scene_ms3d/__README__.txt blender-2.62/release/scripts/addons_contrib/io_scene_ms3d/__README__.txt --- blender-2.61/release/scripts/addons_contrib/io_scene_ms3d/__README__.txt 2011-12-13 19:59:29.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/io_scene_ms3d/__README__.txt 2012-02-15 19:43:47.000000000 +0000 @@ -16,11 +16,11 @@ # # ##### END GPL LICENSE BLOCK ##### +# ############################################################################### #234567890123456789012345678901234567890123456789012345678901234567890123456789 #--------1---------2---------3---------4---------5---------6---------7--------- -# # ##### BEGIN COPYRIGHT BLOCK ##### @@ -89,6 +89,10 @@ changelog: +changed: (0, 3, 8), +mod: changed matrix handling, in account to matrix changes since blender rev.42816; for a while with side-by-side implementation by checking 'bpy.app.build_revision' +del: removed unused option for export FuturePinball animation script (i will make an extra addon future_pinball_tool collection) + changed: (0, 3, 6, "beta (2011-12-13 00:00)"), mod: exporter use an other logic to reduces the total number of smooth groups mod: correct "version" and "blender" in __init__.py diff -Nru blender-2.61/release/scripts/addons_contrib/io_sequencer_edl/import_edl.py blender-2.62/release/scripts/addons_contrib/io_sequencer_edl/import_edl.py --- blender-2.61/release/scripts/addons_contrib/io_sequencer_edl/import_edl.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/io_sequencer_edl/import_edl.py 2012-02-15 19:43:40.000000000 +0000 @@ -0,0 +1,1011 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the 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. +# +# ##### END GPL LICENSE BLOCK ##### + +# + +""" +Name: "Video Sequence (.edl)..." +Blender: 248 +Group: "Import" +Tooltip: "Load a CMX formatted EDL into the sequencer" +""" + + +class TimeCode(object): + """ + Simple timecode class + also supports conversion from other time strings used by EDL + """ + def __init__(self, data, fps): + self.fps = fps + if type(data) == str: + self.fromString(data) + frame = self.asFrame() + self.fromFrame(frame) + else: + self.fromFrame(data) + + def fromString(self, text): + # hh:mm:ss:ff + # No dropframe support yet + + if text.lower().endswith("mps"): # 5.2mps + return self.fromFrame(int(float(text[:-3]) * self.fps)) + elif text.lower().endswith("s"): # 5.2s + return self.fromFrame(int(float(text[:-1]) * self.fps)) + elif text.isdigit(): # 1234 + return self.fromFrame(int(text)) + elif ":" in text: # hh:mm:ss:ff + text = text.replace(";", ":").replace(",", ":").replace(".", ":") + text = text.split(":") + + self.hours = int(text[0]) + self.minutes = int(text[1]) + self.seconds = int(text[2]) + self.frame = int(text[3]) + return self + else: + print("ERROR: could not convert this into timecode %r" % test) + return self + + def fromFrame(self, frame): + + if frame < 0: + frame = -frame + neg = True + else: + neg = False + + fpm = 60 * self.fps + fph = 60 * fpm + + if frame < fph: + self.hours = 0 + else: + self.hours = int(frame / fph) + frame = frame % fph + + if frame < fpm: + self.minutes = 0 + else: + self.minutes = int(frame / fpm) + frame = frame % fpm + + if frame < self.fps: + self.seconds = 0 + else: + self.seconds = int(frame / self.fps) + frame = frame % self.fps + + self.frame = frame + + if neg: + self.frame = -self.frame + self.seconds = -self.seconds + self.minutes = -self.minutes + self.hours = -self.hours + + return self + + def asFrame(self): + abs_frame = self.frame + abs_frame += self.seconds * self.fps + abs_frame += self.minutes * 60 * self.fps + abs_frame += self.hours * 60 * 60 * self.fps + + return abs_frame + + def asString(self): + self.fromFrame(int(self)) + return "%.2d:%.2d:%.2d:%.2d" % (self.hours, self.minutes, self.seconds, self.frame) + + def __repr__(self): + return self.asString() + + # Numeric stuff, may as well have this + def __neg__(self): + return TimeCode(-int(self), self.fps) + + def __int__(self): + return self.asFrame() + + def __sub__(self, other): + return TimeCode(int(self) - int(other), self.fps) + + def __add__(self, other): + return TimeCode(int(self) + int(other), self.fps) + + def __mul__(self, other): + return TimeCode(int(self) * int(other), self.fps) + + def __div__(self, other): + return TimeCode(int(self) // int(other), self.fps) + + def __abs__(self): + return TimeCode(abs(int(self)), self.fps) + + def __iadd__(self, other): + return self.fromFrame(int(self) + int(other)) + + def __imul__(self, other): + return self.fromFrame(int(self) * int(other)) + + def __idiv__(self, other): + return self.fromFrame(int(self) // int(other)) +# end timecode + + +"""Comments +Comments can appear at the beginning of the EDL file (header) or between the edit lines in the EDL. The first block of comments in the file is defined to be the header comments and they are associated with the EDL as a whole. Subsequent comments in the EDL file are associated with the first edit line that appears after them. +Edit Entries + [num] [duration] [srcIn] [srcOut] [recIn] [recOut] + + * : Filename or tag value. Filename can be for an MPEG file, Image file, or Image file template. Image file templates use the same pattern matching as for command line glob, and can be used to specify images to encode into MPEG. i.e. /usr/data/images/image*.jpg + * : 'V' | 'A' | 'VA' | 'B' | 'v' | 'a' | 'va' | 'b' which equals Video, Audio, Video_Audio edits (note B or b can be used in place of VA or va). + * : 'C' | 'D' | 'E' | 'FI' | 'FO' | 'W' | 'c' | 'd' | 'e' | 'fi' | 'fo' | 'w'. which equals Cut, Dissolve, Effect, FadeIn, FadeOut, Wipe. + * [num]: if TransitionType = Wipe, then a wipe number must be given. At the moment only wipe 'W0' and 'W1' are supported. + * [duration]: if the TransitionType is not equal to Cut, then an effect duration must be given. Duration is in frames. + * [srcIn]: Src in. If no srcIn is given, then it defaults to the first frame of the video or the first frame in the image pattern. If srcIn isn't specified, then srcOut, recIn, recOut can't be specified. + * [srcOut]: Src out. If no srcOut is given, then it defaults to the last frame of the video - or last image in the image pattern. if srcOut isn't given, then recIn and recOut can't be specified. + * [recIn]: Rec in. If no recIn is given, then it is calculated based on its position in the EDL and the length of its input. + [recOut]: Rec out. If no recOut is given, then it is calculated based on its position in the EDL and the length of its input. first frame of the video. + +For srcIn, srcOut, recIn, recOut, the values can be specified as either timecode, frame number, seconds, or mps seconds. i.e. +[tcode | fnum | sec | mps], where: + + * tcode : SMPTE timecode in hh:mm:ss:ff + * fnum : frame number (the first decodable frame in the video is taken to be frame 0). + * sec : seconds with 's' suffix (e.g. 5.2s) + * mps : seconds with 'mps' suffix (e.g. 5.2mps). This corresponds to the 'seconds' value displayed by Windows MediaPlayer. + +More notes, +Key + +""" + +enum = 0 +TRANSITION_UNKNOWN = enum +TRANSITION_CUT = enum +enum += 1 +TRANSITION_DISSOLVE = enum +enum += 1 +TRANSITION_EFFECT = enum +enum += 1 +TRANSITION_FADEIN = enum +enum += 1 +TRANSITION_FADEOUT = enum +enum += 1 +TRANSITION_WIPE = enum +enum += 1 +TRANSITION_KEY = enum +enum += 1 + +TRANSITION_DICT = { + "c": TRANSITION_CUT, + "d": TRANSITION_DISSOLVE, + "e": TRANSITION_EFFECT, + "fi": TRANSITION_FADEIN, + "fo": TRANSITION_FADEOUT, + "w": TRANSITION_WIPE, + "k": TRANSITION_KEY, + } + +enum = 0 +EDIT_UNKNOWN = 1 << enum +enum += 1 +EDIT_VIDEO = 1 << enum +enum += 1 +EDIT_AUDIO = 1 << enum +enum += 1 +EDIT_AUDIO_STEREO = 1 << enum +enum += 1 +EDIT_VIDEO_AUDIO = 1 << enum +enum += 1 + +EDIT_DICT = { + "v": EDIT_VIDEO, + "a": EDIT_AUDIO, + "aa": EDIT_AUDIO_STEREO, + "va": EDIT_VIDEO_AUDIO, + "b": EDIT_VIDEO_AUDIO, + } + + +enum = 0 +WIPE_UNKNOWN = enum +WIPE_0 = enum +enum += 1 +WIPE_1 = enum +enum += 1 + +enum = 0 +KEY_UNKNOWN = enum +KEY_BG = enum # K B +enum += 1 +KEY_IN = enum # This is assumed if no second type is set +enum += 1 +KEY_OUT = enum # K O +enum += 1 + + +""" +Most sytems: +Non-dropframe: 1:00:00:00 - colon in last position +Dropframe: 1:00:00;00 - semicolon in last position +PAL/SECAM: 1:00:00:00 - colon in last position + +SONY: +Non-dropframe: 1:00:00.00 - period in last position +Dropframe: 1:00:00,00 - comma in last position +PAL/SECAM: 1:00:00.00 - period in last position +""" + +""" +t = abs(timecode('-124:-12:-43:-22', 25)) +t /= 2 +print t +""" + + +def editFlagsToText(flag): + items = [] + for item, val in EDIT_DICT.items(): + if val & flag: + items.append(item) + return "/".join(items) + + +class EditDecision(object): + def __init__(self, text=None, fps=25): + # print text + self.number = -1 + self.reel = "" # Uniqie name for this 'file' but not filename, when BL signifies black + self.transition_duration = 0 + self.edit_type = EDIT_UNKNOWN + self.transition_type = TRANSITION_UNKNOWN + self.wipe_type = WIPE_UNKNOWN + self.key_type = KEY_UNKNOWN + self.key_fade = -1 # true/false + self.srcIn = None # Where on the original field recording the event begins + self.srcOut = None # Where on the original field recording the event ends + self.recIn = None # Beginning of the original event in the edited program + self.recOut = None # End of the original event in the edited program + self.m2 = None # fps set by the m2 command + self.filename = "" + + self.custom_data = [] # use for storing any data you want (blender strip for eg) + + if text != None: + self.read(text, fps) + + def __repr__(self): + txt = "num: %d, " % self.number + txt += "reel: %s, " % self.reel + txt += "edit_type: " + txt += editFlagsToText(self.edit_type) + ", " + + txt += "trans_type: " + for item, val in TRANSITION_DICT.items(): + if val == self.transition_type: + txt += item + ", " + break + + txt += "m2: " + if self.m2: + txt += "%g" % float(self.m2.fps) + txt += "\n\t" + txt += self.m2.data + else: + txt += "nil" + + txt += ", " + txt += "recIn: " + str(self.recIn) + ", " + txt += "recOut: " + str(self.recOut) + ", " + txt += "srcIn: " + str(self.srcIn) + ", " + txt += "srcOut: " + str(self.srcOut) + ", " + + return txt + + def read(self, line, fps): + line = line.split() + index = 0 + self.number = int(line[index]) + index += 1 + self.reel = line[index].lower() + index += 1 + + # AA/V can be an edit type + self.edit_type = 0 + for edit_type in line[index].lower().split("/"): + self.edit_type |= EDIT_DICT[edit_type] + index += 1 + + tx_name = "".join([c for c in line[index].lower() if not c.isdigit()]) + self.transition_type = TRANSITION_DICT[tx_name] # advance the index later + + if self.transition_type == TRANSITION_WIPE: + tx_num = "".join([c for c in line[index].lower() if c.isdigit()]) + if tx_num: + tx_num = int(tx_num) + else: + tx_num = 0 + + self.wipe_type = tx_num + + elif self.transition_type == TRANSITION_KEY: # UNTESTED + + val = line[index + 1].lower() + + if val == "b": + self.key_type = KEY_BG + index += 1 + elif val == "o": + self.key_type = KEY_OUT + index += 1 + else: + self.key_type = KEY_IN # if no args given + + # there may be an (F) after, eg 'K B (F)' + # in the docs this should only be after K B but who knows, it may be after K O also? + val = line[index + 1].lower() + if val == "(f)": + index += 1 + self.key_fade = True + else: + self.key_fade = False + + index += 1 + + if self.transition_type in {TRANSITION_DISSOLVE, TRANSITION_EFFECT, TRANSITION_FADEIN, TRANSITION_FADEOUT, TRANSITION_WIPE}: + self.transition_duration = TimeCode(line[index], fps) + index += 1 + + if index < len(line): + self.srcIn = TimeCode(line[index], fps) + index += 1 + if index < len(line): + self.srcOut = TimeCode(line[index], fps) + index += 1 + + if index < len(line): + self.recIn = TimeCode(line[index], fps) + index += 1 + if index < len(line): + self.recOut = TimeCode(line[index], fps) + index += 1 + + def renumber(self): + self.edits.sort(key=lambda e: int(e.recIn)) + for i, edit in enumerate(self.edits): + edit.number = i + + def clean(self): + """ + Clean up double ups + """ + self.renumber() + + # TODO + def asName(self): + cut_type = "nil" + for k, v in TRANSITION_DICT.items(): + if v == self.transition_type: + cut_type = k + break + + return "%d_%s_%s" % (self.number, self.reel, cut_type) + + +class M2(object): + def __init__(self): + self.reel = None + self.fps = None + self.time = None + self.data = None + + self.index = -1 + self.tot = -1 + + def read(self, line, fps): + + # M2 TAPEC 050.5 00:08:11:08 + words = line.split() + + self.reel = words[1].lower() + self.fps = float(words[2]) + self.time = TimeCode(words[3], fps) + + self.data = line + + +class EditList(object): + def __init__(self): + self.edits = [] + self.title = "" + + def parse(self, filename, fps): + try: + file = open(filename, "rU") + except: + return False + + self.edits = [] + edits_m2 = [] # edits with m2's + + has_m2 = False + + for line in file: + line = " ".join(line.split()) + + if not line or line.startswith("*") or line.startswith("#"): + continue + elif line.startswith("TITLE:"): + self.title = " ".join(line.split()[1:]) + elif line.split()[0].lower() == "m2": + has_m2 = True + m2 = M2() + m2.read(line, fps) + edits_m2.append(m2) + elif not line.split()[0].isdigit(): + print("Ignoring:", line) + else: + self.edits.append(EditDecision(line, fps)) + edits_m2.append(self.edits[-1]) + + if has_m2: + # Group indexes + i = 0 + for item in edits_m2: + if isinstance(item, M2): + item.index = i + i += 1 + else: + # not an m2 + i = 0 + + # Set total group indexes + for item in reversed(edits_m2): + if isinstance(item, M2): + if tot_m2 == -1: + tot_m2 = item.index + 1 + + item.tot = tot_m2 + else: + # not an m2 + tot_m2 = -1 + + for i, item in enumerate(edits_m2): + if isinstance(item, M2): + # make a list of all items that match the m2's reel name + edits_m2_tmp = [item_tmp for item_tmp in edits_m2 if (isinstance(item, M2) or item_tmp.reel == item.reel)] + + # get the new index + i_tmp = edits_m2_tmp.index(item) + + # Seek back to get the edit. + edit = edits_m2[i_tmp - item.tot] + + # Note, docs say time should also match with edit start time + # but from final cut pro, this seems not to be the case + if not isinstance(edit, EditDecision): + print("ERROR!", "M2 incorrect") + else: + edit.m2 = item + + return True + + def testOverlap(self, edit_test): + recIn = int(edit_test.recIn) + recOut = int(edit_test.recOut) + + for edit in self.edits: + if edit is edit_test: + break + + recIn_other = int(edit.recIn) + recOut_other = int(edit.recOut) + + if recIn_other < recIn < recOut_other: + return True + if recIn_other < recOut < recOut_other: + return True + + if recIn < recIn_other < recOut: + return True + if recIn < recOut_other < recOut: + return True + + return False + + def getReels(self): + reels = {} + for edit in self.edits: + reels.setdefault(edit.reel, []).append(edit) + + return reels + +# from DNA +SEQ_IMAGE = 0 +SEQ_META = 1 +SEQ_SCENE = 2 +SEQ_MOVIE = 3 +SEQ_RAM_SOUND = 4 +SEQ_HD_SOUND = 5 +SEQ_MOVIE_AND_HD_SOUND = 6 + +SEQ_EFFECT = 8 +SEQ_CROSS = 8 +SEQ_ADD = 9 +SEQ_SUB = 10 +SEQ_ALPHAOVER = 11 +SEQ_ALPHAUNDER = 12 +SEQ_GAMCROSS = 13 +SEQ_MUL = 14 +SEQ_OVERDROP = 15 +SEQ_PLUGIN = 24 +SEQ_WIPE = 25 +SEQ_GLOW = 26 +SEQ_TRANSFORM = 27 +SEQ_COLOR = 28 +SEQ_SPEED = 29 + +# Blender spesific stuff starts here +import bpy +import Blender + + +def scale_meta_speed(seq, mov, scale): + # Add an effect + speed = seq.new((SEQ_SPEED, mov,), 199, mov.channel + 1) + speed.speedEffectFrameBlending = True + meta = seq.new([mov, speed], 199, mov.channel) + + if scale >= 1.0: + mov.endStill = int(mov.length * (scale - 1.0)) + else: + speed.speedEffectGlobalSpeed = 1.0 / scale + meta.endOffset = mov.length - int(mov.length * scale) + + speed.update() + meta.update() + return meta + + +def apply_dissolve_ipo(mov, blendin): + len_disp = float(mov.endDisp - mov.startDisp) + + if len_disp <= 0.0: + print("Error, strip is zero length") + return + + mov.ipo = ipo = bpy.data.ipos.new("fade", "Sequence") + icu = ipo.addCurve("Fac") + + icu.interpolation = Blender.IpoCurve.InterpTypes.LINEAR + icu.append((0, 0)) + icu.append(((int(blendin) / len_disp) * 100, 1)) + + if mov.type not in (SEQ_HD_SOUND, SEQ_RAM_SOUND): + mov.blendMode = Blender.Scene.Sequence.BlendModes.ALPHAOVER + + +def replace_ext(path, ext): + return path[:path.rfind(".") + 1] + ext + + +def load_edl(filename, reel_files, reel_offsets): + """ + reel_files - key:reel <--> reel:filename + """ + + # For test file + # frame_offset = -769 + + sce = bpy.data.scenes.active + fps = sce.render.fps + + elist = EditList() + if not elist.parse(filename, fps): + return "Unable to parse %r" % filename + # elist.clean() + + seq = sce.sequence + + track = 0 + + edits = elist.edits[:] + # edits.sort(key = lambda edit: int(edit.recIn)) + + prev_edit = None + for edit in edits: + print(edit) + frame_offset = reel_offsets[edit.reel] + + src_start = int(edit.srcIn) + frame_offset + src_end = int(edit.srcOut) + frame_offset + src_length = src_end - src_start + + rec_start = int(edit.recIn) + 1 + rec_end = int(edit.recOut) + 1 + rec_length = rec_end - rec_start + + # print src_length, rec_length, src_start + + if edit.m2 != None: + scale = fps / edit.m2.fps + else: + scale = 1.0 + + unedited_start = rec_start - src_start + offset_start = src_start - int(src_start * scale) # works for scaling up AND down + + if edit.transition_type == TRANSITION_CUT and (not elist.testOverlap(edit)): + track = 1 + + strip = None + final_strips = [] + if edit.reel.lower() == "bw": + strip = seq.new((0, 0, 0), rec_start, track + 1) + strip.length = rec_length # for color its simple + final_strips.append(strip) + else: + + path_full = reel_files[edit.reel] + path_fileonly = path_full.split("/")[-1].split("\\")[-1] # os.path.basename(full) + path_dironly = path_full[:-len(path_fileonly)] # os.path.dirname(full) + + if edit.edit_type & EDIT_VIDEO: # and edit.transition_type == TRANSITION_CUT: + + try: + strip = seq.new((path_fileonly, path_dironly, path_full, "movie"), unedited_start + offset_start, track + 1) + except: + return "Invalid input for movie" + + # Apply scaled rec in bounds + if scale != 1.0: + meta = scale_meta_speed(seq, strip, scale) + final_strip = meta + else: + final_strip = strip + + final_strip.update() + final_strip.startOffset = rec_start - final_strip.startDisp + final_strip.endOffset = rec_end - final_strip.endDisp + final_strip.update() + final_strip.endOffset += (final_strip.endDisp - rec_end) + final_strip.update() + + if edit.transition_duration: + if not prev_edit: + print("Error no previous strip") + else: + new_end = rec_start + int(edit.transition_duration) + for other in prev_edit.custom_data: + if other.type != SEQ_HD_SOUND and other.type != SEQ_RAM_SOUND: + other.endOffset += (other.endDisp - new_end) + other.update() + + # Apply disolve + if edit.transition_type == TRANSITION_DISSOLVE: + apply_dissolve_ipo(final_strip, edit.transition_duration) + + if edit.transition_type == TRANSITION_WIPE: + other_track = track + 2 + for other in prev_edit.custom_data: + if other.type != SEQ_HD_SOUND and other.type != SEQ_RAM_SOUND: + + strip_wipe = seq.new((SEQ_WIPE, other, final_strip), 1, other_track) + + if edit.wipe_type == WIPE_0: + strip_wipe.wipeEffectAngle = +90 + else: + strip_wipe.wipeEffectAngle = -90 + + other_track += 1 + + # strip.endOffset = strip.length - int(edit.srcOut) + # end_offset = (unedited_start+strip.length) - end + # print start, end, end_offset + # strip.endOffset = end_offset + # + # break + # print(strip) + + final_strips.append(final_strip) + + if edit.edit_type & (EDIT_AUDIO | EDIT_AUDIO_STEREO | EDIT_VIDEO_AUDIO): + + if scale == 1.0: # TODO - scaled audio + + try: + strip = seq.new((path_fileonly, path_dironly, path_full, "audio_hd"), unedited_start + offset_start, track + 6) + except: + + # See if there is a wave file there + path_full_wav = replace_ext(path_full, "wav") + path_fileonly_wav = replace_ext(path_fileonly, "wav") + + #try: + strip = seq.new((path_fileonly_wav, path_dironly, path_full_wav, "audio_hd"), unedited_start + offset_start, track + 6) + #except: + # return "Invalid input for audio" + + final_strip = strip + + # Copied from above + final_strip.update() + final_strip.startOffset = rec_start - final_strip.startDisp + final_strip.endOffset = rec_end - final_strip.endDisp + final_strip.update() + final_strip.endOffset += (final_strip.endDisp - rec_end) + final_strip.update() + + if edit.transition_type == TRANSITION_DISSOLVE: + apply_dissolve_ipo(final_strip, edit.transition_duration) + + final_strips.append(final_strip) + + # strip = seq.new((0.6, 0.6, 0.6), start, track+1) + + if final_strips: + for strip in final_strips: + # strip.length = length + final_strip.name = edit.asName() + edit.custom_data[:] = final_strips + # track = not track + prev_edit = edit + track += 1 + + #break + + def recursive_update(s): + s.update(1) + for s_kid in s: + recursive_update(s_kid) + + for s in seq: + recursive_update(s) + + return "" + + +#load_edl("/fe/edl/EP30CMXtrk1.edl") # /tmp/test.edl +#load_edl("/fe/edl/EP30CMXtrk2.edl") # /tmp/test.edl +#load_edl("/fe/edl/EP30CMXtrk3.edl") # /tmp/test.edl +#load_edl("/root/vid/rush/blender_edl.edl", ["/root/vid/rush/rushes3.avi",]) # /tmp/test.edl + +# ---------------------- Blender UI part +from Blender import Draw, Window +import BPyWindow + +if 0: + DEFAULT_FILE_EDL = "/root/vid/rush/blender_edl.edl" + DEFAULT_FILE_MEDIA = "/root/vid/rush/rushes3_wav.avi" + DEFAULT_FRAME_OFFSET = -769 +else: + DEFAULT_FILE_EDL = "" + DEFAULT_FILE_MEDIA = "" + DEFAULT_FRAME_OFFSET = 0 + +B_EVENT_IMPORT = 1 +B_EVENT_RELOAD = 2 +B_EVENT_FILESEL_EDL = 3 +B_EVENT_NOP = 4 + +B_EVENT_FILESEL = 100 # or greater + + +class ReelItemUI(object): + __slots__ = "filename_but", "offset_but", "ui_text" + + def __init__(self): + self.filename_but = Draw.Create(DEFAULT_FILE_MEDIA) + self.offset_but = Draw.Create(DEFAULT_FRAME_OFFSET) + self.ui_text = "" + + +REEL_UI = {} # reel:ui_string + + +#REEL_FILENAMES = {} # reel:filename +#REEL_OFFSETS = {} # reel:filename + +PREF = {} + +PREF["filename"] = Draw.Create(DEFAULT_FILE_EDL) +PREF["reel_act"] = "" + + +def edl_reload(): + Window.WaitCursor(1) + filename = PREF["filename"].val + sce = bpy.data.scenes.active + fps = sce.render.fps + + elist = EditList() + + if filename: + if not elist.parse(filename, fps): + Draw.PupMenu("Error%t|Could not open the file %r" % filename) + reels = elist.getReels() + else: + reels = {} + + REEL_UI.clear() + for reel_key, edits in reels.items(): + + if reel_key == "bw": + continue + + flag = 0 + for edit in edits: + flag |= edit.edit_type + + reel_item = REEL_UI[reel_key] = ReelItemUI() + + reel_item.ui_text = "%s (%s): " % (reel_key, editFlagsToText(flag)) + + Window.WaitCursor(0) + + +def edl_set_path(filename): + PREF["filename"].val = filename + edl_reload() + Draw.Redraw() + + +def edl_set_path_reel(filename): + REEL_UI[PREF["reel_act"]].filename_but.val = filename + Draw.Redraw() + + +def edl_reel_keys(): + reel_keys = REEL_UI.keys() + + if "bw" in reel_keys: + reel_keys.remove("bw") + + reel_keys.sort() + return reel_keys + + +def edl_draw(): + + MARGIN = 4 + rect = BPyWindow.spaceRect() + but_width = int((rect[2] - MARGIN * 2) / 4.0) # 72 + # Clamp + if but_width > 100: + but_width = 100 + but_height = 17 + + x = MARGIN + y = rect[3] - but_height - MARGIN + xtmp = x + + # ---------- ---------- ---------- ---------- + Blender.Draw.BeginAlign() + PREF["filename"] = Draw.String("edl path: ", B_EVENT_RELOAD, xtmp, y, (but_width * 3) - 20, but_height, PREF["filename"].val, 256, "EDL Path") + xtmp += (but_width * 3) - 20 + + Draw.PushButton("..", B_EVENT_FILESEL_EDL, xtmp, y, 20, but_height, "Select an EDL file") + xtmp += 20 + + Blender.Draw.EndAlign() + + Draw.PushButton("Reload", B_EVENT_RELOAD, xtmp + MARGIN, y, but_width - MARGIN, but_height, "Read the ID Property settings from the active curve object") + xtmp += but_width + + y -= but_height + MARGIN + xtmp = x + # ---------- ---------- ---------- ---------- + + reel_keys = edl_reel_keys() + + if reel_keys: + text = "Reel file list..." + elif PREF["filename"].val == "": + text = "No EDL loaded." + else: + text = "No reels found!" + + Draw.Label(text, xtmp + MARGIN, y, but_width * 4, but_height) + xtmp += but_width * 4 + + y -= but_height + MARGIN + xtmp = x + + # ---------- ---------- ---------- ---------- + + for i, reel_key in enumerate(reel_keys): + reel_item = REEL_UI[reel_key] + + Blender.Draw.BeginAlign() + REEL_UI[reel_key].filename_but = Draw.String(reel_item.ui_text, B_EVENT_NOP, xtmp, y, (but_width * 3) - 20, but_height, REEL_UI[reel_key].filename_but.val, 256, "Select the reel path") + xtmp += (but_width * 3) - 20 + Draw.PushButton("..", B_EVENT_FILESEL + i, xtmp, y, 20, but_height, "Media path to use for this reel") + xtmp += 20 + Blender.Draw.EndAlign() + + reel_item.offset_but = Draw.Number("ofs:", B_EVENT_NOP, xtmp + MARGIN, y, but_width - MARGIN, but_height, reel_item.offset_but.val, -100000, 100000, "Start offset in frames when applying timecode") + xtmp += but_width - MARGIN + + y -= but_height + MARGIN + xtmp = x + + # ---------- ---------- ---------- ---------- + + Draw.PushButton("Import CMX-EDL Sequencer Strips", B_EVENT_IMPORT, xtmp + MARGIN, MARGIN, but_width * 4 - MARGIN, but_height, "Load the EDL file into the sequencer") + xtmp += but_width * 4 + y -= but_height + MARGIN + xtmp = x + + +def edl_event(evt, val): + pass + + +def edl_bevent(evt): + + if evt == B_EVENT_NOP: + pass + elif evt == B_EVENT_IMPORT: + """ + Load the file into blender with UI settings + """ + filename = PREF["filename"].val + + reel_files = {} + reel_offsets = {} + + for reel_key, reel_item in REEL_UI.items(): + reel_files[reel_key] = reel_item.filename_but.val + reel_offsets[reel_key] = reel_item.offset_but.val + + error = load_edl(filename, reel_files, reel_offsets) + if error != "": + Draw.PupMenu("Error%t|" + error) + else: + Window.RedrawAll() + + elif evt == B_EVENT_RELOAD: + edl_reload() + Draw.Redraw() + + elif evt == B_EVENT_FILESEL_EDL: + filename = PREF["filename"].val + if not filename: + filename = Blender.sys.join(Blender.sys.expandpath("//"), "*.edl") + + Window.FileSelector(edl_set_path, "Select EDL", filename) + + elif evt >= B_EVENT_FILESEL: + reel_keys = edl_reel_keys() + reel_key = reel_keys[evt - B_EVENT_FILESEL] + + filename = REEL_UI[reel_key].filename_but.val + if not filename: + filename = Blender.sys.expandpath("//") + + PREF["reel_act"] = reel_key # so file set path knows which one to set + Window.FileSelector(edl_set_path_reel, "Reel Media", filename) + + +if __name__ == "__main__": + Draw.Register(edl_draw, edl_event, edl_bevent) + edl_reload() diff -Nru blender-2.61/release/scripts/addons_contrib/lamp_geographical_sun.py blender-2.62/release/scripts/addons_contrib/lamp_geographical_sun.py --- blender-2.61/release/scripts/addons_contrib/lamp_geographical_sun.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/lamp_geographical_sun.py 2012-02-15 19:43:59.000000000 +0000 @@ -39,543 +39,542 @@ # Addon setup #----------------------------------------------------------------------------- bl_info = { - "name": "Geographical Sun", - "author": "Doug Hammond (dougal2)", - "version": (0, 0, 1), - "blender": (2, 5, 6), - "api": 35078, - "category": "Object", - "location": "Lamp data > Geographical Sun", - "warning": "", - "wiki_url": "", - "tracker_url": "", - "description": "Set SUN Lamp rotation according to geographical time and location." + "name": "Geographical Sun", + "author": "Doug Hammond (dougal2)", + "version": (0, 0, 1), + "blender": (2, 5, 6), + "category": "Object", + "location": "Lamp data > Geographical Sun", + "warning": "", + "wiki_url": "", + "tracker_url": "", + "description": "Set SUN Lamp rotation according to geographical time and location." } GeoSunAddon = Addon(bl_info) # Sun rotation calculator implementation #----------------------------------------------------------------------------- class sun_calculator(object): - """ - Based on SunLight v1.0 by Miguel Kabantsov (miguelkab@gmail.com) - Replaces the faulty sun position calculation algorythm with a precise calculation (Source for algorythm: http://de.wikipedia.org/wiki/Sonnenstand), - Co-Ordinates: http://www.bcca.org/misc/qiblih/latlong.html - Author: Nils-Peter Fischer (Nils-Peter.Fischer@web.de) - """ - - location_list = [ - ("EUROPE",[ - ("Antwerp, Belgium", 67), - ("Berlin, Germany", 1), - ("Bratislava, Slovak Republic", 70), - ("Brno, Czech Republic", 72), - ("Brussles, Belgium", 68), - ("Geneva, Switzerland", 65), - ("Helsinki, Finland", 7), - ("Innsbruck, Austria", 62), - ("Kyiv, Ukraine", 64), - ("London, England", 10), - ("Lyon, France", 66), - ("Nitra, Slovak Republic", 69), - ("Oslo, Norway", 58), - ("Paris, France", 15), - ("Praha, Czech Republic", 71), - ("Rome, Italy", 18), - ("Telfs, Austria", 63), - ("Warsaw, Poland", 74), - ("Wroclaw, Poland", 73), - ("Zurich, Switzerland", 21), - ]), - - ("WORLD CITIES", [ - ("Beijing, China", 0), - ("Bombay, India", 2), - ("Buenos Aires, Argentina", 3), - ("Cairo, Egypt", 4), - ("Cape Town, South Africa", 5), - ("Caracas, Venezuela", 6), - ("Curitiba, Brazil", 60), - ("Hong Kong, China", 8), - ("Jerusalem, Israel", 9), - ("Joinville, Brazil", 61), - ("Mexico City, Mexico", 11), - ("Moscow, Russia", 12), - ("New Delhi, India", 13), - ("Ottawa, Canada", 14), - ("Rio de Janeiro, Brazil", 16), - ("Riyadh, Saudi Arabia", 17), - ("Sao Paulo, Brazil", 59), - ("Sydney, Australia", 19), - ("Tokyo, Japan", 20), - ]), - - ("US CITIES", [ - ("Albuquerque, NM", 22), - ("Anchorage, AK", 23), - ("Atlanta, GA", 24), - ("Austin, TX", 25), - ("Birmingham, AL", 26), - ("Bismarck, ND", 27), - ("Boston, MA", 28), - ("Boulder, CO", 29), - ("Chicago, IL", 30), - ("Dallas, TX", 31), - ("Denver, CO", 32), - ("Detroit, MI", 33), - ("Honolulu, HI", 34), - ("Houston, TX", 35), - ("Indianapolis, IN", 36), - ("Jackson, MS", 37), - ("Kansas City, MO", 38), - ("Los Angeles, CA", 39), - ("Menomonee Falls, WI", 40), - ("Miami, FL", 41), - ("Minneapolis, MN", 42), - ("New Orleans, LA", 43), - ("New York City, NY", 44), - ("Oklahoma City, OK", 45), - ("Philadelphia, PA", 46), - ("Phoenix, AZ", 47), - ("Pittsburgh, PA", 48), - ("Portland, ME", 49), - ("Portland, OR", 50), - ("Raleigh, NC", 51), - ("Richmond, VA", 52), - ("Saint Louis, MO", 53), - ("San Diego, CA", 54), - ("San Francisco, CA", 55), - ("Seattle, WA", 56), - ("Washington DC", 57), - ]) - ] - - location_data = { - # Europe - 67: ( 51.2167, -4.4, 1), - 1: ( 52.33, -13.30, 1), - 70: ( 48.17, -17.17, 1), - 72: ( 49.2, -16.63, 1), - 68: ( 58.8467, -4.3525, 1), - 65: ( 46.217, -6.150, 1), - 7: ( 60.1667, -24.9667,2), - 62: ( 47.2672, -11.3928, 1), - 64: ( 50.75, -30.0833, 2), - 10: ( 51.50, 0.0, 0), - 66: ( 45.767, -4.833, 1), - 69: ( 48.32, -18.07, 1), - 58: ( 59.56, -10.41, 1), - 15: ( 48.8667, -2.667, 1), - 71: ( 50.08, -14.46, 1), - 18: ( 41.90, -12.4833, 1), - 63: ( 47.3, -11.0667, 1), - 74: ( 52.232, -21.008, 1), - 73: ( 51.108, -17.038, 1), - 21: ( 47.3833, -8.5333, 1), - - # World Cities - 0: ( 39.9167, -116.4167, 8), - 2: ( 18.9333, -72.8333, 5.5), - 3: (-34.60, 58.45, -3), - 4: ( 30.10, -31.3667, 2), - 5: (-33.9167, -18.3667, 2), - 6: ( 10.50, 66.9333, -4), - 60: (-25.4278, 49.2731, -3), - 8: ( 22.25, -114.1667, 8), - 9: ( 31.7833, -35.2333, 2), - 61: (-29.3044, 48.8456, -3), - 11: ( 19.4, 99.15, -6), - 12: ( 55.75, -37.5833, 3), - 13: ( 28.6, -77.2, 5.5), - 14: ( 45.41667, 75.7, -5), - 16: (-22.90, 43.2333, -3), - 17: ( 24.633, -46.71667, 3), - 59: ( -23.5475, 46.6361, -3), - 19: (-33.8667, -151.2167,10), - 20: ( 35.70, -139.7667, 9), - - # US Cities - 22: ( 35.0833, 106.65, -7), - 23: ( 61.217, 149.90, -9), - 24: ( 33.733, 84.383, -5), - 25: ( 30.283, 97.733, -6), - 26: ( 33.521, 86.8025, -6), - 27: ( 46.817, 100.783, -6), - 28: ( 42.35, 71.05, -5), - 29: ( 40.125, 105.237, -7), - 30: ( 41.85, 87.65, -6), - 31: ( 32.46, 96.47, -6), - 32: ( 39.733, 104.983, -7), - 33: ( 42.333, 83.05, -5), - 34: ( 21.30, 157.85, -10), - 35: ( 29.75, 95.35, -6), - 36: ( 39.767, 86.15, -5), - 37: ( 32.283, 90.183, -6), - 38: ( 39.083, 94.567, -6), - 39: ( 34.05, 118.233, -8), - 40: ( 43.11, 88.10, -6), - 41: ( 25.767, 80.183, -5), - 42: ( 44.967, 93.25, -6), - 43: ( 29.95, 90.067, -6), - 44: ( 40.7167, 74.0167, -5), - 45: ( 35.483, 97.533, -6), - 46: ( 39.95, 75.15, -5), - 47: ( 33.433, 112.067,-7), - 48: ( 40.433, 79.9833, -5), - 49: ( 43.666, 70.283, -5), - 50: ( 45.517, 122.65, -8), - 51: ( 35.783, 78.65, -5), - 52: ( 37.5667, 77.450, -5), - 53: ( 38.6167, 90.1833, -6), - 54: ( 32.7667, 117.2167, -8), - 55: ( 37.7667, 122.4167, -8), - 56: ( 47.60, 122.3167, -8), - 57: ( 38.8833, 77.0333, -5), - } - - # mathematical helpers - @staticmethod - def sind(deg): - return math.sin(math.radians(deg)) - - @staticmethod - def cosd(deg): - return math.cos(math.radians(deg)) - - @staticmethod - def tand(deg): - return math.tan(math.radians(deg)) - - @staticmethod - def asind(deg): - return math.degrees(math.asin(deg)) - - @staticmethod - def atand(deg): - return math.degrees(math.atan(deg)) - - @staticmethod - def geo_sun_astronomicJulianDate(Year, Month, Day, LocalTime, Timezone): - if Month > 2.0: - Y = Year - M = Month - else: - Y = Year - 1.0 - M = Month + 12.0 - - UT = LocalTime - Timezone - hour = UT / 24.0 - A = int(Y/100.0) - - JD = math.floor(365.25*(Y+4716.0)) + math.floor(30.6001*(M+1.0)) + Day + hour - 1524.4 - - # The following section is adopted from netCDF4 netcdftime implementation. - # Copyright: 2008 by Jeffrey Whitaker - # License: http://www.opensource.org/licenses/mit-license.php - if JD >= 2299170.5: - # 1582 October 15 (Gregorian Calendar) - B = 2.0 - A + int(A/4.0) - elif JD < 2299160.5: - # 1582 October 5 (Julian Calendar) - B = 0 - else: - raise Exception('ERROR: Date falls in the gap between Julian and Gregorian calendars.') - B = 0 - - return JD+B - - @staticmethod - def geoSunData(Latitude, Longitude, Year, Month, Day, LocalTime, Timezone): - JD = sun_calculator.geo_sun_astronomicJulianDate(Year, Month, Day, LocalTime, Timezone) - - phi = Latitude - llambda = Longitude - - n = JD - 2451545.0 - LDeg = (280.460 + 0.9856474*n) - (math.floor((280.460 + 0.9856474*n)/360.0) * 360.0) - gDeg = (357.528 + 0.9856003*n) - (math.floor((357.528 + 0.9856003*n)/360.0) * 360.0) - LambdaDeg = LDeg + 1.915 * sun_calculator.sind(gDeg) + 0.02 * sun_calculator.sind(2.0*gDeg) - - epsilonDeg = 23.439 - 0.0000004*n - - alphaDeg = sun_calculator.atand( (sun_calculator.cosd(epsilonDeg) * sun_calculator.sind(LambdaDeg)) / sun_calculator.cosd(LambdaDeg) ) - if sun_calculator.cosd(LambdaDeg) < 0.0: - alphaDeg += 180.0 - - deltaDeg = sun_calculator.asind( sun_calculator.sind(epsilonDeg) * sun_calculator.sind(LambdaDeg) ) - - JDNull = sun_calculator.geo_sun_astronomicJulianDate(Year, Month, Day, 0.0, 0.0) - - TNull = (JDNull - 2451545.0) / 36525.0 - T = LocalTime - Timezone - - thetaGh = 6.697376 + 2400.05134*TNull + 1.002738*T - thetaGh -= math.floor(thetaGh/24.0) * 24.0 - - thetaG = thetaGh * 15.0 - theta = thetaG + llambda - - tau = theta - alphaDeg - - a = sun_calculator.atand( sun_calculator.sind(tau) / ( sun_calculator.cosd(tau)*sun_calculator.sind(phi) - sun_calculator.tand(deltaDeg)*sun_calculator.cosd(phi)) ) - if sun_calculator.cosd(tau)*sun_calculator.sind(phi) - sun_calculator.tand(deltaDeg)*sun_calculator.cosd(phi) < 0.0: - a += 180.0 - - h = sun_calculator.asind( sun_calculator.cosd(deltaDeg)*sun_calculator.cosd(tau)*sun_calculator.cosd(phi) + sun_calculator.sind(deltaDeg)*sun_calculator.sind(phi) ) - - R = 1.02 / (sun_calculator.tand (h+(10.3/(h+5.11)))) - hR = h + R/60.0 - - azimuth = a - elevation = hR - - return azimuth, elevation + """ + Based on SunLight v1.0 by Miguel Kabantsov (miguelkab@gmail.com) + Replaces the faulty sun position calculation algorythm with a precise calculation (Source for algorythm: http://de.wikipedia.org/wiki/Sonnenstand), + Co-Ordinates: http://www.bcca.org/misc/qiblih/latlong.html + Author: Nils-Peter Fischer (Nils-Peter.Fischer@web.de) + """ + + location_list = [ + ("EUROPE",[ + ("Antwerp, Belgium", 67), + ("Berlin, Germany", 1), + ("Bratislava, Slovak Republic", 70), + ("Brno, Czech Republic", 72), + ("Brussles, Belgium", 68), + ("Geneva, Switzerland", 65), + ("Helsinki, Finland", 7), + ("Innsbruck, Austria", 62), + ("Kyiv, Ukraine", 64), + ("London, England", 10), + ("Lyon, France", 66), + ("Nitra, Slovak Republic", 69), + ("Oslo, Norway", 58), + ("Paris, France", 15), + ("Praha, Czech Republic", 71), + ("Rome, Italy", 18), + ("Telfs, Austria", 63), + ("Warsaw, Poland", 74), + ("Wroclaw, Poland", 73), + ("Zurich, Switzerland", 21), + ]), + + ("WORLD CITIES", [ + ("Beijing, China", 0), + ("Bombay, India", 2), + ("Buenos Aires, Argentina", 3), + ("Cairo, Egypt", 4), + ("Cape Town, South Africa", 5), + ("Caracas, Venezuela", 6), + ("Curitiba, Brazil", 60), + ("Hong Kong, China", 8), + ("Jerusalem, Israel", 9), + ("Joinville, Brazil", 61), + ("Mexico City, Mexico", 11), + ("Moscow, Russia", 12), + ("New Delhi, India", 13), + ("Ottawa, Canada", 14), + ("Rio de Janeiro, Brazil", 16), + ("Riyadh, Saudi Arabia", 17), + ("Sao Paulo, Brazil", 59), + ("Sydney, Australia", 19), + ("Tokyo, Japan", 20), + ]), + + ("US CITIES", [ + ("Albuquerque, NM", 22), + ("Anchorage, AK", 23), + ("Atlanta, GA", 24), + ("Austin, TX", 25), + ("Birmingham, AL", 26), + ("Bismarck, ND", 27), + ("Boston, MA", 28), + ("Boulder, CO", 29), + ("Chicago, IL", 30), + ("Dallas, TX", 31), + ("Denver, CO", 32), + ("Detroit, MI", 33), + ("Honolulu, HI", 34), + ("Houston, TX", 35), + ("Indianapolis, IN", 36), + ("Jackson, MS", 37), + ("Kansas City, MO", 38), + ("Los Angeles, CA", 39), + ("Menomonee Falls, WI", 40), + ("Miami, FL", 41), + ("Minneapolis, MN", 42), + ("New Orleans, LA", 43), + ("New York City, NY", 44), + ("Oklahoma City, OK", 45), + ("Philadelphia, PA", 46), + ("Phoenix, AZ", 47), + ("Pittsburgh, PA", 48), + ("Portland, ME", 49), + ("Portland, OR", 50), + ("Raleigh, NC", 51), + ("Richmond, VA", 52), + ("Saint Louis, MO", 53), + ("San Diego, CA", 54), + ("San Francisco, CA", 55), + ("Seattle, WA", 56), + ("Washington DC", 57), + ]) + ] + + location_data = { + # Europe + 67: ( 51.2167, -4.4, 1), + 1: ( 52.33, -13.30, 1), + 70: ( 48.17, -17.17, 1), + 72: ( 49.2, -16.63, 1), + 68: ( 58.8467, -4.3525, 1), + 65: ( 46.217, -6.150, 1), + 7: ( 60.1667, -24.9667,2), + 62: ( 47.2672, -11.3928, 1), + 64: ( 50.75, -30.0833, 2), + 10: ( 51.50, 0.0, 0), + 66: ( 45.767, -4.833, 1), + 69: ( 48.32, -18.07, 1), + 58: ( 59.56, -10.41, 1), + 15: ( 48.8667, -2.667, 1), + 71: ( 50.08, -14.46, 1), + 18: ( 41.90, -12.4833, 1), + 63: ( 47.3, -11.0667, 1), + 74: ( 52.232, -21.008, 1), + 73: ( 51.108, -17.038, 1), + 21: ( 47.3833, -8.5333, 1), + + # World Cities + 0: ( 39.9167, -116.4167, 8), + 2: ( 18.9333, -72.8333, 5.5), + 3: (-34.60, 58.45, -3), + 4: ( 30.10, -31.3667, 2), + 5: (-33.9167, -18.3667, 2), + 6: ( 10.50, 66.9333, -4), + 60: (-25.4278, 49.2731, -3), + 8: ( 22.25, -114.1667, 8), + 9: ( 31.7833, -35.2333, 2), + 61: (-29.3044, 48.8456, -3), + 11: ( 19.4, 99.15, -6), + 12: ( 55.75, -37.5833, 3), + 13: ( 28.6, -77.2, 5.5), + 14: ( 45.41667, 75.7, -5), + 16: (-22.90, 43.2333, -3), + 17: ( 24.633, -46.71667, 3), + 59: ( -23.5475, 46.6361, -3), + 19: (-33.8667, -151.2167,10), + 20: ( 35.70, -139.7667, 9), + + # US Cities + 22: ( 35.0833, 106.65, -7), + 23: ( 61.217, 149.90, -9), + 24: ( 33.733, 84.383, -5), + 25: ( 30.283, 97.733, -6), + 26: ( 33.521, 86.8025, -6), + 27: ( 46.817, 100.783, -6), + 28: ( 42.35, 71.05, -5), + 29: ( 40.125, 105.237, -7), + 30: ( 41.85, 87.65, -6), + 31: ( 32.46, 96.47, -6), + 32: ( 39.733, 104.983, -7), + 33: ( 42.333, 83.05, -5), + 34: ( 21.30, 157.85, -10), + 35: ( 29.75, 95.35, -6), + 36: ( 39.767, 86.15, -5), + 37: ( 32.283, 90.183, -6), + 38: ( 39.083, 94.567, -6), + 39: ( 34.05, 118.233, -8), + 40: ( 43.11, 88.10, -6), + 41: ( 25.767, 80.183, -5), + 42: ( 44.967, 93.25, -6), + 43: ( 29.95, 90.067, -6), + 44: ( 40.7167, 74.0167, -5), + 45: ( 35.483, 97.533, -6), + 46: ( 39.95, 75.15, -5), + 47: ( 33.433, 112.067,-7), + 48: ( 40.433, 79.9833, -5), + 49: ( 43.666, 70.283, -5), + 50: ( 45.517, 122.65, -8), + 51: ( 35.783, 78.65, -5), + 52: ( 37.5667, 77.450, -5), + 53: ( 38.6167, 90.1833, -6), + 54: ( 32.7667, 117.2167, -8), + 55: ( 37.7667, 122.4167, -8), + 56: ( 47.60, 122.3167, -8), + 57: ( 38.8833, 77.0333, -5), + } + + # mathematical helpers + @staticmethod + def sind(deg): + return math.sin(math.radians(deg)) + + @staticmethod + def cosd(deg): + return math.cos(math.radians(deg)) + + @staticmethod + def tand(deg): + return math.tan(math.radians(deg)) + + @staticmethod + def asind(deg): + return math.degrees(math.asin(deg)) + + @staticmethod + def atand(deg): + return math.degrees(math.atan(deg)) + + @staticmethod + def geo_sun_astronomicJulianDate(Year, Month, Day, LocalTime, Timezone): + if Month > 2.0: + Y = Year + M = Month + else: + Y = Year - 1.0 + M = Month + 12.0 + + UT = LocalTime - Timezone + hour = UT / 24.0 + A = int(Y/100.0) + + JD = math.floor(365.25*(Y+4716.0)) + math.floor(30.6001*(M+1.0)) + Day + hour - 1524.4 + + # The following section is adopted from netCDF4 netcdftime implementation. + # Copyright: 2008 by Jeffrey Whitaker + # License: http://www.opensource.org/licenses/mit-license.php + if JD >= 2299170.5: + # 1582 October 15 (Gregorian Calendar) + B = 2.0 - A + int(A/4.0) + elif JD < 2299160.5: + # 1582 October 5 (Julian Calendar) + B = 0 + else: + raise Exception('ERROR: Date falls in the gap between Julian and Gregorian calendars.') + B = 0 + + return JD+B + + @staticmethod + def geoSunData(Latitude, Longitude, Year, Month, Day, LocalTime, Timezone): + JD = sun_calculator.geo_sun_astronomicJulianDate(Year, Month, Day, LocalTime, Timezone) + + phi = Latitude + llambda = Longitude + + n = JD - 2451545.0 + LDeg = (280.460 + 0.9856474*n) - (math.floor((280.460 + 0.9856474*n)/360.0) * 360.0) + gDeg = (357.528 + 0.9856003*n) - (math.floor((357.528 + 0.9856003*n)/360.0) * 360.0) + LambdaDeg = LDeg + 1.915 * sun_calculator.sind(gDeg) + 0.02 * sun_calculator.sind(2.0*gDeg) + + epsilonDeg = 23.439 - 0.0000004*n + + alphaDeg = sun_calculator.atand( (sun_calculator.cosd(epsilonDeg) * sun_calculator.sind(LambdaDeg)) / sun_calculator.cosd(LambdaDeg) ) + if sun_calculator.cosd(LambdaDeg) < 0.0: + alphaDeg += 180.0 + + deltaDeg = sun_calculator.asind( sun_calculator.sind(epsilonDeg) * sun_calculator.sind(LambdaDeg) ) + + JDNull = sun_calculator.geo_sun_astronomicJulianDate(Year, Month, Day, 0.0, 0.0) + + TNull = (JDNull - 2451545.0) / 36525.0 + T = LocalTime - Timezone + + thetaGh = 6.697376 + 2400.05134*TNull + 1.002738*T + thetaGh -= math.floor(thetaGh/24.0) * 24.0 + + thetaG = thetaGh * 15.0 + theta = thetaG + llambda + + tau = theta - alphaDeg + + a = sun_calculator.atand( sun_calculator.sind(tau) / ( sun_calculator.cosd(tau)*sun_calculator.sind(phi) - sun_calculator.tand(deltaDeg)*sun_calculator.cosd(phi)) ) + if sun_calculator.cosd(tau)*sun_calculator.sind(phi) - sun_calculator.tand(deltaDeg)*sun_calculator.cosd(phi) < 0.0: + a += 180.0 + + h = sun_calculator.asind( sun_calculator.cosd(deltaDeg)*sun_calculator.cosd(tau)*sun_calculator.cosd(phi) + sun_calculator.sind(deltaDeg)*sun_calculator.sind(phi) ) + + R = 1.02 / (sun_calculator.tand (h+(10.3/(h+5.11)))) + hR = h + R/60.0 + + azimuth = a + elevation = hR + + return azimuth, elevation # Addon classes #----------------------------------------------------------------------------- @GeoSunAddon.addon_register_class class OBJECT_OT_set_geographical_sun_now(bpy.types.Operator): - bl_idname = 'object.set_geographical_sun_now' - bl_label = 'Set time to NOW' - - @classmethod - def poll(cls, context): - cl = context.lamp - return cl and cl.type == 'SUN' - - def execute(self, context): - GSP = context.lamp.GeoSunProperties - - now = datetime.datetime.now() - for p in ('hour', 'minute', 'day', 'month', 'year'): - setattr( - GSP, - p, - getattr(now, p) - ) - GSP.tz = time.timezone - GSP.dst = False - - return {'FINISHED'} + bl_idname = 'object.set_geographical_sun_now' + bl_label = 'Set time to NOW' + + @classmethod + def poll(cls, context): + cl = context.lamp + return cl and cl.type == 'SUN' + + def execute(self, context): + GSP = context.lamp.GeoSunProperties + + now = datetime.datetime.now() + for p in ("hour", "minute", "day", "month", "year"): + setattr( + GSP, + p, + getattr(now, p) + ) + GSP.tz = time.timezone + GSP.dst = False + + return {'FINISHED'} @GeoSunAddon.addon_register_class class OBJECT_OT_set_geographical_sun_pos(bpy.types.Operator): - bl_idname = 'object.set_geographical_sun_pos' - bl_label = 'Set SUN position' - - @classmethod - def poll(cls, context): - cl = context.lamp - return cl and cl.type == 'SUN' - - def execute(self, context): - try: - GSP = context.lamp.GeoSunProperties - - dst = 1 if GSP.dst else 0 - - az,el = sun_calculator.geoSunData( - GSP.lat, - GSP.long, - GSP.year, - GSP.month, - GSP.day, - GSP.hour + GSP.minute/60.0, - -GSP.tz + dst - ) - - context.object.rotation_euler = ( math.radians(90-el), 0, math.radians(-az) ) - return {'FINISHED'} - except Exception as err: - self.report({'ERROR'}, str(err)) - return {'CANCELLED'} + bl_idname = 'object.set_geographical_sun_pos' + bl_label = 'Set SUN position' + + @classmethod + def poll(cls, context): + cl = context.lamp + return cl and cl.type == 'SUN' + + def execute(self, context): + try: + GSP = context.lamp.GeoSunProperties + + dst = 1 if GSP.dst else 0 + + az,el = sun_calculator.geoSunData( + GSP.lat, + GSP.long, + GSP.year, + GSP.month, + GSP.day, + GSP.hour + GSP.minute/60.0, + -GSP.tz + dst + ) + + context.object.rotation_euler = ( math.radians(90-el), 0, math.radians(-az) ) + return {'FINISHED'} + except Exception as err: + self.report({'ERROR'}, str(err)) + return {'CANCELLED'} @GeoSunAddon.addon_register_class class OBJECT_OT_set_geographical_location_preset(bpy.types.Operator): - bl_idname = 'object.set_geographical_location_preset' - bl_label = 'Apply location preset' - - index = bpy.props.IntProperty() - - @classmethod - def poll(cls, context): - cl = context.lamp - return cl and cl.type == 'SUN' - - def execute(self, context): - GSP = context.lamp.GeoSunProperties - GSP.lat, GSP.long, GSP.tz = sun_calculator.location_data[self.properties.index] - return {'FINISHED'} + bl_idname = 'object.set_geographical_location_preset' + bl_label = 'Apply location preset' + + index = bpy.props.IntProperty() + + @classmethod + def poll(cls, context): + cl = context.lamp + return cl and cl.type == 'SUN' + + def execute(self, context): + GSP = context.lamp.GeoSunProperties + GSP.lat, GSP.long, GSP.tz = sun_calculator.location_data[self.properties.index] + return {'FINISHED'} # Dynamic submenu magic ! def draw_generator(locations): - def draw(self, context): - sl = self.layout - for location in locations: - location_name, location_index = location - sl.operator('OBJECT_OT_set_geographical_location_preset', text=location_name).index = location_index - return draw + def draw(self, context): + sl = self.layout + for location in locations: + location_name, location_index = location + sl.operator('OBJECT_OT_set_geographical_location_preset', text=location_name).index = location_index + return draw submenus = [] for label, locations in sun_calculator.location_list: - submenu_idname = 'OBJECT_MT_geo_sun_location_cat%d'%len(submenus) - submenu = type( - submenu_idname, - (bpy.types.Menu,), - { - 'bl_idname': submenu_idname, - 'bl_label': label, - 'draw': draw_generator(locations) - } - ) - GeoSunAddon.addon_register_class(submenu) - submenus.append(submenu) + submenu_idname = 'OBJECT_MT_geo_sun_location_cat%d'%len(submenus) + submenu = type( + submenu_idname, + (bpy.types.Menu,), + { + 'bl_idname': submenu_idname, + 'bl_label': label, + 'draw': draw_generator(locations) + } + ) + GeoSunAddon.addon_register_class(submenu) + submenus.append(submenu) @GeoSunAddon.addon_register_class class OBJECT_MT_geo_sun_location(bpy.types.Menu): - bl_label = 'Location preset' - - def draw(self, context): - sl = self.layout - for sm in submenus: - sl.menu(sm.bl_idname) + bl_label = 'Location preset' + + def draw(self, context): + sl = self.layout + for sm in submenus: + sl.menu(sm.bl_idname) @GeoSunAddon.addon_register_class class GeoSunProperties(declarative_property_group): - ef_attach_to = ['Lamp'] - - controls = [ - ['hour', 'minute'], - ['day', 'month', 'year'], - ['tz', 'dst'], - 'location_menu', - ['lat', 'long'], - ['set_time', 'set_posn'], - ] - - properties = [ - { - 'type': 'int', - 'attr': 'minute', - 'name': 'Minute', - 'min': 0, - 'soft_min': 0, - 'max': 59, - 'soft_max': 59, - 'default': today.minute - }, - { - 'type': 'int', - 'attr': 'hour', - 'name': 'Hour', - 'min': 0, - 'soft_min': 0, - 'max': 24, - 'soft_max': 24, - 'default': today.hour - }, - { - 'type': 'int', - 'attr': 'day', - 'name': 'Day', - 'min': 1, - 'soft_min': 1, - 'max': 31, - 'soft_max': 31, - 'default': today.day - }, - { - 'type': 'int', - 'attr': 'month', - 'name': 'Month', - 'min': 1, - 'soft_min': 1, - 'max': 12, - 'soft_max': 12, - 'default': today.month - }, - { - 'type': 'int', - 'attr': 'year', - 'name': 'Year', - 'min': datetime.MINYEAR, - 'soft_min': datetime.MINYEAR, - 'max': datetime.MAXYEAR, - 'soft_max': datetime.MAXYEAR, - 'default': today.year - }, - { - 'type': 'int', - 'attr': 'tz', - 'name': 'Time zone', - 'min': -13, - 'soft_min': -13, - 'max': 13, - 'soft_max': 13, - 'default': time.timezone - }, - { - 'type': 'bool', - 'attr': 'dst', - 'name': 'DST', - 'default': False - }, - { - 'type': 'float', - 'attr': 'lat', - 'name': 'Lat.', - 'min': -180.0, - 'soft_min': -180.0, - 'max': 180.0, - 'soft_max': 180.0, - 'default': 0.0 - }, - { - 'type': 'float', - 'attr': 'long', - 'name': 'Long.', - 'min': -90.0, - 'soft_min': -90.0, - 'max': 90.0, - 'soft_max': 90.0, - 'default': 0.0 - }, - - # draw operators and menus - { - 'attr': 'location_menu', - 'type': 'menu', - 'menu': 'OBJECT_MT_geo_sun_location' - }, - { - 'attr': 'set_time', - 'type': 'operator', - 'operator': 'object.set_geographical_sun_now', - 'icon': 'PREVIEW_RANGE' - }, - { - 'attr': 'set_posn', - 'type': 'operator', - 'operator': 'object.set_geographical_sun_pos', - 'icon': 'WORLD_DATA' - }, - ] + ef_attach_to = ['Lamp'] + + controls = [ + ['hour', 'minute'], + ['day', 'month', 'year'], + ['tz', 'dst'], + 'location_menu', + ['lat', 'long'], + ['set_time', 'set_posn'], + ] + + properties = [ + { + 'type': 'int', + 'attr': 'minute', + 'name': 'Minute', + 'min': 0, + 'soft_min': 0, + 'max': 59, + 'soft_max': 59, + 'default': today.minute + }, + { + 'type': 'int', + 'attr': 'hour', + 'name': 'Hour', + 'min': 0, + 'soft_min': 0, + 'max': 24, + 'soft_max': 24, + 'default': today.hour + }, + { + 'type': 'int', + 'attr': 'day', + 'name': 'Day', + 'min': 1, + 'soft_min': 1, + 'max': 31, + 'soft_max': 31, + 'default': today.day + }, + { + 'type': 'int', + 'attr': 'month', + 'name': 'Month', + 'min': 1, + 'soft_min': 1, + 'max': 12, + 'soft_max': 12, + 'default': today.month + }, + { + 'type': 'int', + 'attr': 'year', + 'name': 'Year', + 'min': datetime.MINYEAR, + 'soft_min': datetime.MINYEAR, + 'max': datetime.MAXYEAR, + 'soft_max': datetime.MAXYEAR, + 'default': today.year + }, + { + 'type': 'int', + 'attr': 'tz', + 'name': 'Time zone', + 'min': -13, + 'soft_min': -13, + 'max': 13, + 'soft_max': 13, + 'default': time.timezone + }, + { + 'type': 'bool', + 'attr': 'dst', + 'name': 'DST', + 'default': False + }, + { + 'type': 'float', + 'attr': 'lat', + 'name': 'Lat.', + 'min': -180.0, + 'soft_min': -180.0, + 'max': 180.0, + 'soft_max': 180.0, + 'default': 0.0 + }, + { + 'type': 'float', + 'attr': 'long', + 'name': 'Long.', + 'min': -90.0, + 'soft_min': -90.0, + 'max': 90.0, + 'soft_max': 90.0, + 'default': 0.0 + }, + + # draw operators and menus + { + 'attr': 'location_menu', + 'type': 'menu', + 'menu': 'OBJECT_MT_geo_sun_location' + }, + { + 'attr': 'set_time', + 'type': 'operator', + 'operator': 'object.set_geographical_sun_now', + 'icon': 'PREVIEW_RANGE' + }, + { + 'attr': 'set_posn', + 'type': 'operator', + 'operator': 'object.set_geographical_sun_pos', + 'icon': 'WORLD_DATA' + }, + ] @GeoSunAddon.addon_register_class class GeoSunPanel(property_group_renderer): - bl_space_type = 'PROPERTIES' - bl_region_type = 'WINDOW' - bl_context = 'data' - bl_label = 'Geographical Sun' - - display_property_groups = [ - ( ('lamp',), 'GeoSunProperties' ) - ] - - @classmethod - def poll(cls, context): - cl = context.lamp - return cl and cl.type == 'SUN' + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = 'data' + bl_label = 'Geographical Sun' + + display_property_groups = [ + ( ('lamp',), 'GeoSunProperties' ) + ] + + @classmethod + def poll(cls, context): + cl = context.lamp + return cl and cl.type == 'SUN' # Bootstrap the Addon #----------------------------------------------------------------------------- diff -Nru blender-2.61/release/scripts/addons_contrib/mesh_edge_intersection_tools.py blender-2.62/release/scripts/addons_contrib/mesh_edge_intersection_tools.py --- blender-2.61/release/scripts/addons_contrib/mesh_edge_intersection_tools.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/mesh_edge_intersection_tools.py 2012-02-15 19:43:59.000000000 +0000 @@ -23,7 +23,6 @@ "author": "zeffii", "version": (0, 5, 1), "blender": (2, 5, 6), - "api": 34840, "category": "Mesh", "location": "View3D > EditMode > (w) Specials", "warning": "Still under development, bug reports appreciated", diff -Nru blender-2.61/release/scripts/addons_contrib/mesh_inset_extrude.py blender-2.62/release/scripts/addons_contrib/mesh_inset_extrude.py --- blender-2.61/release/scripts/addons_contrib/mesh_inset_extrude.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/mesh_inset_extrude.py 2012-02-15 19:43:59.000000000 +0000 @@ -4,7 +4,6 @@ 'author': "Jon Sandstrom", 'version': (0, 6), 'blender': (2, 5, 9), - 'api': 39514, 'location': 'Search for Inset Extrude, map a key to the operator "mesh.inset_extrude", or use the default "I-key"', 'warning': "", 'category': 'Mesh', @@ -577,7 +576,7 @@ self.run_modal = False return {'FINISHED'} - elif event.type in ('RIGHTMOUSE', 'ESC'): + elif event.type in {'RIGHTMOUSE', 'ESC'}: context.area.header_text_set() context.region.callback_remove(self._handle) self.run_modal = False diff -Nru blender-2.61/release/scripts/addons_contrib/mesh_normal_smooth.py blender-2.62/release/scripts/addons_contrib/mesh_normal_smooth.py --- blender-2.61/release/scripts/addons_contrib/mesh_normal_smooth.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/mesh_normal_smooth.py 2012-02-15 19:43:59.000000000 +0000 @@ -26,7 +26,6 @@ "author": "Dolf Veenvliet", "version": (7,), "blender": (2, 5, 7), - "api": 39104, "location": "View3D > Specials > Normal Smooth ", "description": "Smooth the vertex position based on the normals", "warning": "", diff -Nru blender-2.61/release/scripts/addons_contrib/mesh_seam_from_uv_isles.py blender-2.62/release/scripts/addons_contrib/mesh_seam_from_uv_isles.py --- blender-2.61/release/scripts/addons_contrib/mesh_seam_from_uv_isles.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/mesh_seam_from_uv_isles.py 2012-02-15 19:43:59.000000000 +0000 @@ -21,7 +21,6 @@ "author": "Fredrik Hansson", "version": (1,1), "blender": (2, 5, 7), - "api": 37360, "location": "UV/Image editor> UVs > Seam from UV isles", "description": "Marks seams based on UV isles", "warning": "", # used for warning icon and text in addons panel @@ -34,60 +33,60 @@ import bpy def main(context): - obj = context.active_object - mesh = obj.data + obj = context.active_object + mesh = obj.data - if not obj or obj.type != 'MESH': - print("no active Mesh") - return - if not mesh.uv_textures.active: - print("no active UV Texture") - return - bpy.ops.object.mode_set(mode='OBJECT') - - - uvtex=mesh.uv_textures.active.data - - wrap_q = [1,2,3,0] - wrap_t = [1,2,0] - edge_uvs = {} - - for i,uvface in enumerate(uvtex): - f=mesh.faces[i] - f_uv = [(round(uv[0], 6), round(uv[1], 6)) for uv in uvface.uv] - f_vi = [vertices for vertices in f.vertices] - for i, key in enumerate(f.edge_keys): - if len(f.vertices)==3: - uv1, uv2 = f_uv[i], f_uv[wrap_t[i]] - vi1, vi2 = f_vi[i], f_vi[wrap_t[i]] - else: # quad - uv1, uv2 = f_uv[i], f_uv[wrap_q[i]] - vi1, vi2 = f_vi[i], f_vi[wrap_q[i]] - - if vi1 > vi2: vi1,uv1,uv2 = vi2,uv2,uv1 - - edge_uvs.setdefault(key, []).append((uv1, uv2)) - - for ed in mesh.edges: - if(len(set(edge_uvs[ed.key])) > 1): - ed.use_seam=1 + if not obj or obj.type != 'MESH': + print("no active Mesh") + return + if not mesh.uv_textures.active: + print("no active UV Texture") + return + bpy.ops.object.mode_set(mode='OBJECT') + + + uvtex=mesh.uv_textures.active.data + + wrap_q = [1,2,3,0] + wrap_t = [1,2,0] + edge_uvs = {} + + for i,uvface in enumerate(uvtex): + f=mesh.faces[i] + f_uv = [(round(uv[0], 6), round(uv[1], 6)) for uv in uvface.uv] + f_vi = [vertices for vertices in f.vertices] + for i, key in enumerate(f.edge_keys): + if len(f.vertices)==3: + uv1, uv2 = f_uv[i], f_uv[wrap_t[i]] + vi1, vi2 = f_vi[i], f_vi[wrap_t[i]] + else: # quad + uv1, uv2 = f_uv[i], f_uv[wrap_q[i]] + vi1, vi2 = f_vi[i], f_vi[wrap_q[i]] + + if vi1 > vi2: vi1,uv1,uv2 = vi2,uv2,uv1 + + edge_uvs.setdefault(key, []).append((uv1, uv2)) + + for ed in mesh.edges: + if(len(set(edge_uvs[ed.key])) > 1): + ed.use_seam=1 - bpy.ops.object.mode_set(mode='EDIT') + bpy.ops.object.mode_set(mode='EDIT') class UvIsleSeamsOperator(bpy.types.Operator): - '''''' - bl_idname = "mesh.seam_from_uv_isles" - bl_label = "Seams from UV isles" - bl_options = {'REGISTER', 'UNDO'} + '''''' + bl_idname = "mesh.seam_from_uv_isles" + bl_label = "Seams from UV isles" + bl_options = {'REGISTER', 'UNDO'} # def poll(self, context): -# obj = context.active_object -# return (obj and obj.type == 'MESH') +# obj = context.active_object +# return (obj and obj.type == 'MESH') + + def execute(self, context): + main(context) + return {'FINISHED'} - def execute(self, context): - main(context) - return {'FINISHED'} - def menu_func(self, context): self.layout.operator(UvIsleSeamsOperator.bl_idname) diff -Nru blender-2.61/release/scripts/addons_contrib/mesh_select_vertex_groups.py blender-2.62/release/scripts/addons_contrib/mesh_select_vertex_groups.py --- blender-2.61/release/scripts/addons_contrib/mesh_select_vertex_groups.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/mesh_select_vertex_groups.py 2012-02-15 19:43:59.000000000 +0000 @@ -21,7 +21,6 @@ 'author': 'Martin Ellison', 'version': (1, 0), 'blender': (2, 5, 9), - 'api': 39685, 'location': 'Toolbox', 'description': 'Finds all the vertex groups that chosen verts are in, & any verts that are not in any group', 'warning': '', # used for warning icon and text in addons panel diff -Nru blender-2.61/release/scripts/addons_contrib/mesh_vertex_slide.py blender-2.62/release/scripts/addons_contrib/mesh_vertex_slide.py --- blender-2.61/release/scripts/addons_contrib/mesh_vertex_slide.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/mesh_vertex_slide.py 2012-02-15 19:43:59.000000000 +0000 @@ -23,7 +23,6 @@ "author": "Valter Battioli (ValterVB) and PKHG", "version": (1, 1, 6), "blender": (2, 6, 0), - "api": 41099, "location": "View3D > Mesh > Vertices (CTRL V-key)", "description": "Slide a vertex along an edge or a line", "warning": "", @@ -359,7 +358,7 @@ context.region.callback_remove(self._handle) return {'FINISHED'} - elif event.type in ('RIGHTMOUSE', 'ESC'): # Restore and exit + elif event.type in {'RIGHTMOUSE', 'ESC'}: # Restore and exit Vertices = bpy.context.object.data.vertices bpy.ops.mesh.select_all(action='DESELECT') bpy.ops.object.mode_set(mode='OBJECT') diff -Nru blender-2.61/release/scripts/addons_contrib/object_batch_rename_datablocks.py blender-2.62/release/scripts/addons_contrib/object_batch_rename_datablocks.py --- blender-2.61/release/scripts/addons_contrib/object_batch_rename_datablocks.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/object_batch_rename_datablocks.py 2012-02-15 19:43:59.000000000 +0000 @@ -21,7 +21,6 @@ "author": "tstscr", "version": (1, 0), "blender": (2, 5, 9), - "api": 39685, "location": "Search > (rename)", "description": "Batch renaming of datablocks (e.g. rename materials after objectnames)", "warning": "", diff -Nru blender-2.61/release/scripts/addons_contrib/object_drop_to_ground.py blender-2.62/release/scripts/addons_contrib/object_drop_to_ground.py --- blender-2.61/release/scripts/addons_contrib/object_drop_to_ground.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/object_drop_to_ground.py 2012-02-15 19:43:59.000000000 +0000 @@ -20,7 +20,6 @@ "author": "Unnikrishnan(kodemax), Florian Meyer(testscreenings)", "version": (1, 1), "blender": (2, 5, 9), - "api": 39740, "location": "Tool shelf", "description": "Drops the selected objects to the active object", "warning": "Before using it do :- ctrl+a -> apply rotation on the object to be dropped", diff -Nru blender-2.61/release/scripts/addons_contrib/object_laplace_lightning.py blender-2.62/release/scripts/addons_contrib/object_laplace_lightning.py --- blender-2.61/release/scripts/addons_contrib/object_laplace_lightning.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/object_laplace_lightning.py 2012-02-15 19:43:59.000000000 +0000 @@ -0,0 +1,1243 @@ +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ***** END GPL LICENCE BLOCK ***** +bl_info = { + "name": "Laplacian Lightning", + "author": "teldredge", + "version": (0, 2, 6), + "blender": (2, 6, 1), + "location": "View3D > ToolShelf > Laplacian Lightning", + "description": "Lightning mesh generator using laplacian growth algorithm", + "warning": "Beta/Buggy.", + "wiki_url": "http://www.funkboxing.com/wordpress/?p=301", + "tracker_url": "https://projects.blender.org/tracker/index.php?" + "func=detail&aid=27189", + "category": "Object"} + +###################################################################### +###################################################################### +##################### BLENDER LAPLACIAN LIGHTNING #################### +############################ teldredge ############################### +######################## www.funkboxing.com ########################## +###################################################################### +######################## using algorithm from ######################## +###################################################################### +############## FAST SIMULATION OF LAPLACIAN GROWTH (FSLG) ############ +#################### http://gamma.cs.unc.edu/FRAC/ ################### +###################################################################### +###################### and a few ideas ideas from #################### +###################################################################### +##### FAST ANIMATION OF LIGHTNING USING AN ADAPTIVE MESH (FALUAM) #### +################ http://gamma.cs.unc.edu/FAST_LIGHTNING/ ############# +###################################################################### +###################################################################### +""" -----RELEASE LOG/NOTES/PONTIFICATIONS----- +v0.1.0 - 04.11.11 + basic generate functions and UI + object creation report (Custom Properties: FSLG_REPORT) +v0.2.0 - 04.15.11 + started spelling laplacian right. + add curve function (not in UI) ...twisting problem + classify stroke by MAIN path, h-ORDER paths, TIP paths + jitter cells for mesh creation + add materials if present +v0.2.1 - 04.16.11 + mesh classification speedup +v0.2.2 - 04.21.11 + fxns to write/read array to file + restrict growth to insulator cells (object bounding box) + origin/ground defineable by object + gridunit more like 'resolution' +v0.2.3 - 04.24.11 + cloud attractor object (termintates loop if hit) + secondary path orders (hOrder) disabled in UI (set to 1) +v0.2.4 - 04.26.11 + fixed object selection in UI + will not run if required object not selected + moved to view 3d > toolbox +v0.2.5 - 05.08.11 + testing for 2.57b + single mesh output (for build modifier) + speedups (dist fxn) +v0.2.6 - 06.20.11 + scale/pos on 'write to cubes' works now + if origin obj is mesh, uses all verts as initial charges + semi-helpful tooltips + speedups, faster dedupe fxn, faster classification + use any shape mesh obj as insulator mesh + must have rot=0, scale=1, origin set to geometry + often fails to block bolt with curved/complex shapes + separate single and multi mesh creation + +v0.x - + -fix vis fxn to only buildCPGraph once for VM or VS + -improve list fxns (rid of ((x,y,z),w) and use (x,y,z,w)), use 'sets' + -create python cmodule for a few of most costly fxns + i have pretty much no idea how to do this yet + -cloud and insulator can be groups of MESH objs + -?text output, possibly to save on interrupt, allow continue from text + -?hook modifiers from tips->sides->main, weight w/ vert groups + -user defined 'attractor' path + -fix add curve function + -animated arcs via. ionization path + -environment map boundary conditions - requires Eqn. 15 from FSLG... + -?assign wattage at each segment for HDRI + -?default settings for -lightning, -teslacoil, -spark/arc + -fix hOrder functionality + -multiple 'MAIN' brances for non-lightning discharges + -n-symmetry option, create mirror images, snowflakes, etc... +""" + +###################################################################### +###################################################################### +###################################################################### +import bpy +import time +import random +from math import sqrt +from mathutils import Vector +import struct +import bisect +import os.path +notZero = 0.0000000001 +scn = bpy.context.scene + +###################################################################### +########################### UTILITY FXNS ############################# +###################################################################### +def within(x,y,d): +###---CHECK IF x-d <= y <= x+d + if x-d <= y and x + d >= y: + return True + else: return False + +def dist(ax, ay, az ,bx, by, bz): + dv = Vector((ax,ay,az)) - Vector((bx,by,bz)) + d = dv.length + return d + +def splitList(aList, idx): + ll = [] + for x in aList: + ll.append(x[idx]) + return ll + +def splitListCo(aList): + ll = [] + for p in aList: + ll.append((p[0], p[1], p[2])) + return ll + +def getLowHigh(aList): + tLow = aList[0]; tHigh = aList[0] + for a in aList: + if a < tLow: tLow = a + if a > tHigh: tHigh = a + return tLow, tHigh + +def weightedRandomChoice(aList): + tL = [] + tweight = 0 + for a in range(len(aList)): + idex = a; weight = aList[a] + if weight > 0.0: + tweight += weight + tL.append((tweight, idex)) + i = bisect.bisect(tL, (random.uniform(0, tweight), None)) + r = tL[i][1] + return r + +def getStencil3D_26(x,y,z): + nL = [] + for xT in range(x-1, x+2): + for yT in range(y-1, y+2): + for zT in range(z-1, z+2): + nL.append((xT, yT, zT)) + nL.remove((x,y,z)) + return nL + +def jitterCells(aList, jit): + j = jit/2 + bList = [] + for a in aList: + ax = a[0] + random.uniform(-j, j) + ay = a[1] + random.uniform(-j, j) + az = a[2] + random.uniform(-j, j) + bList.append((ax, ay, az)) + return bList + +def deDupe(seq, idfun=None): +###---THANKS TO THIS GUY - http://www.peterbe.com/plog/uniqifiers-benchmark + if idfun is None: + def idfun(x): return x + seen = {} + result = [] + for item in seq: + marker = idfun(item) + if marker in seen: continue + seen[marker] = 1 + result.append(item) + return result + +###################################################################### +######################## VISUALIZATION FXNS ########################## +###################################################################### +def writeArrayToVoxel(arr, filename): + gridS = 64 + half = int(gridS/2) + bitOn = 255 + aGrid = [[[0 for z in range(gridS)] for y in range(gridS)] for x in range(gridS)] + for a in arr: + try: + aGrid[a[0]+half][a[1]+half][a[2]+half] = bitOn + except: + print('Particle beyond voxel domain') + file = open(filename, "wb") + for z in range(gridS): + for y in range(gridS): + for x in range(gridS): + file.write(struct.pack('B', aGrid[x][y][z])) + file.flush() + file.close() + +def writeArrayToFile(arr, filename): + file = open(filename, "w") + for a in arr: + tstr = str(a[0]) + ',' + str(a[1]) + ',' + str(a[2]) + '\n' + file.write(tstr) + file.close + +def readArrayFromFile(filename): + file = open(filename, "r") + arr = [] + for f in file: + pt = f[0:-1].split(',') + arr.append((int(pt[0]), int(pt[1]), int(pt[2]))) + return arr + +def makeMeshCube(msize): + msize = msize/2 + mmesh = bpy.data.meshes.new('q') + mmesh.vertices.add(8) + mmesh.vertices[0].co = [-msize, -msize, -msize] + mmesh.vertices[1].co = [-msize, msize, -msize] + mmesh.vertices[2].co = [ msize, msize, -msize] + mmesh.vertices[3].co = [ msize, -msize, -msize] + mmesh.vertices[4].co = [-msize, -msize, msize] + mmesh.vertices[5].co = [-msize, msize, msize] + mmesh.vertices[6].co = [ msize, msize, msize] + mmesh.vertices[7].co = [ msize, -msize, msize] + mmesh.faces.add(6) + mmesh.faces[0].vertices_raw = [0,1,2,3] + mmesh.faces[1].vertices_raw = [0,4,5,1] + mmesh.faces[2].vertices_raw = [2,1,5,6] + mmesh.faces[3].vertices_raw = [3,2,6,7] + mmesh.faces[4].vertices_raw = [0,3,7,4] + mmesh.faces[5].vertices_raw = [5,4,7,6] + mmesh.update(calc_edges=True) + return(mmesh) + +def writeArrayToCubes(arr, gridBU, orig, cBOOL = False, jBOOL = True): + for a in arr: + x = a[0]; y = a[1]; z = a[2] + me = makeMeshCube(gridBU) + ob = bpy.data.objects.new('xCUBE', me) + ob.location.x = (x*gridBU) + orig[0] + ob.location.y = (y*gridBU) + orig[1] + ob.location.z = (z*gridBU) + orig[2] + if cBOOL: ###---!!!MOSTLY UNUSED + ### POS+BLUE, NEG-RED, ZERO:BLACK + col = (1.0, 1.0, 1.0, 1.0) + if a[3] == 0: col = (0.0, 0.0, 0.0, 1.0) + if a[3] < 0: col = (-a[3], 0.0, 0.0, 1.0) + if a[3] > 0: col = (0.0, 0.0, a[3], 1.0) + ob.color = col + bpy.context.scene.objects.link(ob) + bpy.context.scene.update() + if jBOOL: + ###---SELECTS ALL CUBES w/ ?bpy.ops.object.join() b/c + ### CAN'T JOIN ALL CUBES TO A SINGLE MESH RIGHT... ARGH... + for q in bpy.context.scene.objects: + q.select = False + if q.name[0:5] == 'xCUBE': + q.select = True + bpy.context.scene.objects.active = q + +def addVert(ob, pt, conni = -1): + mmesh = ob.data + mmesh.vertices.add(1) + vcounti = len(mmesh.vertices)-1 + mmesh.vertices[vcounti].co = [pt[0], pt[1], pt[2]] + if conni > -1: + mmesh.edges.add(1) + ecounti = len(mmesh.edges)-1 + mmesh.edges[ecounti].vertices = [conni, vcounti] + mmesh.update() + +def addEdge(ob, va, vb): + mmesh = ob.data + mmesh.edges.add(1) + ecounti = len(mmesh.edges)-1 + mmesh.edges[ecounti].vertices = [va, vb] + mmesh.update() + +def newMesh(mname): + mmesh = bpy.data.meshes.new(mname) + omesh = bpy.data.objects.new(mname, mmesh) + bpy.context.scene.objects.link(omesh) + return omesh + +def writeArrayToMesh(mname, arr, gridBU, rpt = None): + mob = newMesh(mname) + mob.scale = (gridBU, gridBU, gridBU) + if rpt: addReportProp(mob, rpt) + addVert(mob, arr[0], -1) + for ai in range(1, len(arr)): + a = arr[ai] + addVert(mob, a, ai-1) + return mob + +###---!!!OUT OF ORDER - SOME PROBLEM WITH IT ADDING (0,0,0) +def writeArrayToCurves(cname, arr, gridBU, bd = .05, rpt = None): + cur = bpy.data.curves.new('fslg_curve', 'CURVE') + cur.use_fill_front = False + cur.use_fill_back = False + cur.bevel_depth = bd + cur.bevel_resolution = 2 + cob = bpy.data.objects.new(cname, cur) + cob.scale = (gridBU, gridBU, gridBU) + if rpt: addReportProp(cob, rpt) + bpy.context.scene.objects.link(cob) + cur.splines.new('BEZIER') + cspline = cur.splines[0] + div = 1 ### SPACING FOR HANDLES (2 - 1/2 WAY, 1 - NEXT BEZIER) + for a in range(len(arr)): + cspline.bezier_points.add(1) + bp = cspline.bezier_points[len(cspline.bezier_points)-1] + if a-1 < 0: hL = arr[a] + else: + hx = arr[a][0] - ((arr[a][0]-arr[a-1][0]) / div) + hy = arr[a][1] - ((arr[a][1]-arr[a-1][1]) / div) + hz = arr[a][2] - ((arr[a][2]-arr[a-1][2]) / div) + hL = (hx,hy,hz) + + if a+1 > len(arr)-1: hR = arr[a] + else: + hx = arr[a][0] + ((arr[a+1][0]-arr[a][0]) / div) + hy = arr[a][1] + ((arr[a+1][1]-arr[a][1]) / div) + hz = arr[a][2] + ((arr[a+1][2]-arr[a][2]) / div) + hR = (hx,hy,hz) + bp.co = arr[a] + bp.handle_left = hL + bp.handle_right = hR + +def addArrayToMesh(mob, arr): + addVert(mob, arr[0], -1) + mmesh = mob.data + vcounti = len(mmesh.vertices)-1 + for ai in range(1, len(arr)): + a = arr[ai] + addVert(mob, a, len(mmesh.vertices)-1) + +def addMaterial(ob, matname): + mat = bpy.data.materials[matname] + ob.active_material = mat + +def writeStokeToMesh(arr, jarr, MAINi, HORDERi, TIPSi, orig, gs, rpt=None): + ###---MAIN BRANCH + print(' WRITING MAIN BRANCH') + llmain = [] + for x in MAINi: + llmain.append(jarr[x]) + mob = writeArrayToMesh('la0MAIN', llmain, gs) + mob.location = orig + + ###---hORDER BRANCHES + for hOi in range(len(HORDERi)): + print(' WRITING ORDER', hOi) + hO = HORDERi[hOi] + hob = newMesh('la1H'+str(hOi)) + + for y in hO: + llHO = [] + for x in y: + llHO.append(jarr[x]) + addArrayToMesh(hob, llHO) + hob.scale = (gs, gs, gs) + hob.location = orig + + ###---TIPS + print(' WRITING TIP PATHS') + tob = newMesh('la2TIPS') + for y in TIPSi: + llt = [] + for x in y: + llt.append(jarr[x]) + addArrayToMesh(tob, llt) + tob.scale = (gs, gs, gs) + tob.location = orig + + ###---ADD MATERIALS TO OBJECTS (IF THEY EXIST) + try: + addMaterial(mob, 'edgeMAT-h0') + addMaterial(hob, 'edgeMAT-h1') + addMaterial(tob, 'edgeMAT-h2') + print(' ADDED MATERIALS') + except: print(' MATERIALS NOT FOUND') + ###---ADD GENERATION REPORT TO ALL MESHES + if rpt: + addReportProp(mob, rpt) + addReportProp(hob, rpt) + addReportProp(tob, rpt) + +def writeStokeToSingleMesh(arr, jarr, orig, gs, mct, rpt=None): + sgarr = buildCPGraph(arr, mct) + llALL = [] + + Aob = newMesh('laALL') + for pt in jarr: + addVert(Aob, pt) + for cpi in range(len(sgarr)): + ci = sgarr[cpi][0] + pi = sgarr[cpi][1] + addEdge(Aob, pi, ci) + Aob.location = orig + Aob.scale = ((gs,gs,gs)) + + if rpt: + addReportProp(Aob, rpt) + +def visualizeArray(cg, oob, gs, vm, vs, vc, vv, rst): +###---IN: (cellgrid, origin, gridscale, +### mulimesh, single mesh, cubes, voxels, report sting) + origin = oob.location + + ###---DEAL WITH VERT MULTI-ORIGINS + oct = 2 + if oob.type == 'MESH': oct = len(oob.data.vertices) + + ###---JITTER CELLS + if vm or vs: cjarr = jitterCells(cg, 1) + + + if vm: ###---WRITE ARRAY TO MULTI MESH + + aMi, aHi, aTi = classifyStroke(cg, oct, scn.HORDER) + print(':::WRITING TO MULTI-MESH') + writeStokeToMesh(cg, cjarr, aMi, aHi, aTi, origin, gs, rst) + print(':::MULTI-MESH WRITTEN') + + if vs: ###---WRITE TO SINGLE MESH + print(':::WRITING TO SINGLE MESH') + writeStokeToSingleMesh(cg, cjarr, origin, gs, oct, rst) + print(':::SINGLE MESH WRITTEN') + + if vc: ###---WRITE ARRAY TO CUBE OBJECTS + print(':::WRITING TO CUBES') + writeArrayToCubes(cg, gs, origin) + print(':::CUBES WRITTEN') + + if vv: ###---WRITE ARRAY TO VOXEL DATA FILE + print(':::WRITING TO VOXELS') + fname = "FSLGvoxels.raw" + path = os.path.dirname(bpy.data.filepath) + writeArrayToVoxel(cg, path + "\\" + fname) + print(':::VOXEL DATA WRITTEN TO - ', path + "\\" + fname) + + ###---READ/WRITE ARRAY TO FILE (MIGHT NOT BE NECESSARY) + #tfile = 'c:\\testarr.txt' + #writeArrayToFile(cg, tfile) + #cg = readArrayFromFile(tfile) + + ###---READ/WRITE ARRAY TO CURVES (OUT OF ORDER) + #writeArrayToCurves('laMAIN', llmain, .10, .25) + +###################################################################### +########################### ALGORITHM FXNS ########################### +########################## FROM FALUAM PAPER ######################### +###################### PLUS SOME STUFF I MADE UP ##################### +###################################################################### +def buildCPGraph(arr, sti = 2): +###---IN -XYZ ARRAY AS BUILT BY GENERATOR +###---OUT -[(CHILDindex, PARENTindex)] +### sti - start index, 2 for Empty, len(me.vertices) for Mesh + sgarr = [] + sgarr.append((1, 0)) # + for ai in range(sti, len(arr)): + cs = arr[ai] + cpts = arr[0:ai] + cslap = getStencil3D_26(cs[0], cs[1], cs[2]) + + for nc in cslap: + ct = cpts.count(nc) + if ct>0: + cti = cpts.index(nc) + sgarr.append((ai, cti)) + return sgarr + +def buildCPGraph_WORKINPROGRESS(arr, sti = 2): +###---IN -XYZ ARRAY AS BUILT BY GENERATOR +###---OUT -[(CHILDindex, PARENTindex)] +### sti - start index, 2 for Empty, len(me.vertices) for Mesh + sgarr = [] + sgarr.append((1, 0)) # + ctix = 0 + for ai in range(sti, len(arr)): + cs = arr[ai] + #cpts = arr[0:ai] + cpts = arr[ctix:ai] + cslap = getStencil3D_26(cs[0], cs[1], cs[2]) + for nc in cslap: + ct = cpts.count(nc) + if ct>0: + #cti = cpts.index(nc) + cti = ctix + cpts.index(nc) + ctix = cpts.index(nc) + + sgarr.append((ai, cti)) + return sgarr + +def findChargePath(oc, fc, ngraph, restrict = [], partial = True): + ###---oc -ORIGIN CHARGE INDEX, fc -FINAL CHARGE INDEX + ###---ngraph -NODE GRAPH, restrict- INDEX OF SITES CANNOT TRAVERSE + ###---partial -RETURN PARTIAL PATH IF RESTRICTION ENCOUNTERD + cList = splitList(ngraph, 0) + pList = splitList(ngraph, 1) + aRi = [] + cNODE = fc + for x in range(len(ngraph)): + pNODE = pList[cList.index(cNODE)] + aRi.append(cNODE) + cNODE = pNODE + npNODECOUNT = cList.count(pNODE) + if cNODE == oc: ### STOP IF ORIGIN FOUND + aRi.append(cNODE) ### RETURN PATH + return aRi + if npNODECOUNT == 0: ### STOP IF NO PARENTS + return [] ### RETURN [] + if pNODE in restrict: ### STOP IF PARENT IS IN RESTRICTION + if partial: ### RETURN PARTIAL OR [] + aRi.append(cNODE) + return aRi + else: return [] + +def findTips(arr): + lt = [] + for ai in arr[0:len(arr)-1]: + a = ai[0] + cCOUNT = 0 + for bi in arr: + b = bi[1] + if a == b: + cCOUNT += 1 + if cCOUNT == 0: + lt.append(a) + return lt + +def findChannelRoots(path, ngraph, restrict = []): + roots = [] + for ai in range(len(ngraph)): + chi = ngraph[ai][0] + par = ngraph[ai][1] + if par in path and not chi in path and \ + not chi in restrict: + roots.append(par) + droots = deDupe(roots) + return droots + +def findChannels(roots, tips, ngraph, restrict): + cPATHS = [] + for ri in range(len(roots)): + r = roots[ri] + sL = 1 + sPATHi = [] + for ti in range(len(tips)): + t = tips[ti] + if t < r: continue + tPATHi = findChargePath(r, t, ngraph, restrict, False) + tL = len(tPATHi) + if tL > sL: + if countChildrenOnPath(tPATHi, ngraph) > 1: + sL = tL + sPATHi = tPATHi + tTEMP = t; tiTEMP = ti + if len(sPATHi) > 0: + print(' found path/idex from', ri, 'of', + len(roots), 'possible | tips:', tTEMP, tiTEMP) + cPATHS.append(sPATHi) + tips.remove(tTEMP) + return cPATHS + +def findChannels_WORKINPROGRESS(roots, ttips, ngraph, restrict): + cPATHS = [] + tips = list(ttips) + for ri in range(len(roots)): + r = roots[ri] + sL = 1 + sPATHi = [] + tipREMOVE = [] ###---CHECKED TIP INDEXES, TO BE REMOVED FOR NEXT LOOP + for ti in range(len(tips)): + t = tips[ti] + #print('-CHECKING RT/IDEX:', r, ri, 'AGAINST TIP', t, ti) + #if t < r: continue + if ti < ri: continue + tPATHi = findChargePath(r, t, ngraph, restrict, False) + tL = len(tPATHi) + if tL > sL: + if countChildrenOnPath(tPATHi, ngraph) > 1: + sL = tL + sPATHi = tPATHi + tTEMP = t; tiTEMP = ti + if tL > 0: + tipREMOVE.append(t) + if len(sPATHi) > 0: + print(' found path from root idex', ri, 'of', + len(roots), 'possible roots | #oftips=', len(tips)) + cPATHS.append(sPATHi) + for q in tipREMOVE: tips.remove(q) + + return cPATHS + +def countChildrenOnPath(aPath, ngraph, quick = True): + ###---RETURN HOW MANY BRANCHES + ### COUNT WHEN NODE IS A PARENT >1 TIMES + ### quick -STOP AND RETURN AFTER FIRST + cCOUNT = 0 + pList = splitList(ngraph,1) + for ai in range(len(aPath)-1): + ap = aPath[ai] + pc = pList.count(ap) + if quick and pc > 1: + return pc + return cCOUNT + +###---CLASSIFY CHANNELS INTO 'MAIN', 'hORDER/SECONDARY' and 'SIDE' +def classifyStroke(sarr, mct, hORDER = 1): + print(':::CLASSIFYING STROKE') + ###---BUILD CHILD/PARENT GRAPH (INDEXES OF sarr) + sgarr = buildCPGraph(sarr, mct) + + ###---FIND MAIN CHANNEL + print(' finding MAIN') + oCharge = sgarr[0][1] + fCharge = sgarr[len(sgarr)-1][0] + aMAINi = findChargePath(oCharge, fCharge, sgarr) + + ###---FIND TIPS + print(' finding TIPS') + aTIPSi = findTips(sgarr) + + ###---FIND hORDER CHANNEL ROOTS + ### hCOUNT = ORDERS BEWTEEN MAIN and SIDE/TIPS + ### !!!STILL BUGGY!!! + hRESTRICT = list(aMAINi) ### ADD TO THIS AFTER EACH TIME + allHPATHSi = [] ### ALL hO PATHS: [[h0], [h1]...] + curPATHSi = [aMAINi] ### LIST OF PATHS FIND ROOTS ON + for h in range(hORDER): + allHPATHSi.append([]) + for pi in range(len(curPATHSi)): ### LOOP THROUGH ALL PATHS IN THIS ORDER + p = curPATHSi[pi] + ### GET ROOTS FOR THIS PATH + aHROOTSi = findChannelRoots(p, sgarr, hRESTRICT) + print(' found', len(aHROOTSi), 'roots in ORDER', h, ':#paths:', len(curPATHSi)) + ### GET CHANNELS FOR THESE ROOTS + if len(aHROOTSi) == 0: + print('NO ROOTS FOR FOUND FOR CHANNEL') + aHPATHSi = [] + continue + else: + aHPATHSiD = findChannels(aHROOTSi, aTIPSi, sgarr, hRESTRICT) + aHPATHSi = aHPATHSiD + allHPATHSi[h] += aHPATHSi + ### SET THESE CHANNELS AS RESTRICTIONS FOR NEXT ITERATIONS + for hri in aHPATHSi: + hRESTRICT += hri + curPATHSi = aHPATHSi + + ###---SIDE BRANCHES, FINAL ORDER OF HEIRARCHY + ### FROM TIPS THAT ARE NOT IN AN EXISTING PATH + ### BACK TO ANY OTHER POINT THAT IS ALREADY ON A PATH + aDRAWNi = [] + aDRAWNi += aMAINi + for oH in allHPATHSi: + for o in oH: + aDRAWNi += o + aTPATHSi = [] + for a in aTIPSi: + if not a in aDRAWNi: + aPATHi = findChargePath(oCharge, a, sgarr, aDRAWNi) + aDRAWNi += aPATHi + aTPATHSi.append(aPATHi) + + return aMAINi, allHPATHSi, aTPATHSi + +def voxelByVertex(ob, gs): +###---'VOXELIZES' VERTS IN A MESH TO LIST [(x,y,z),(x,y,z)] +### W/ RESPECT GSCALE AND OB ORIGIN (B/C SHOULD BE ORIGIN OBJ) + orig = ob.location + ll = [] + for v in ob.data.vertices: + x = int( v.co.x / gs ) + y = int( v.co.y / gs ) + z = int( v.co.z / gs ) + ll.append((x,y,z)) + return ll + +def voxelByRays(ob, orig, gs): +###--- MESH INTO A 3DGRID W/ RESPECT GSCALE AND BOLT ORIGIN +### -DOES NOT TAKE OBJECT ROTATION/SCALE INTO ACCOUNT +### -THIS IS A HORRIBLE, INEFFICIENT FUNCTION +### MAYBE THE RAYCAST/GRID THING ARE A BAD IDEA. BUT I +### HAVE TO 'VOXELIZE THE OBJECT W/ RESCT TO GSCALE/ORIGIN + bbox = ob.bound_box + bbxL = bbox[0][0]; bbxR = bbox[4][0] + bbyL = bbox[0][1]; bbyR = bbox[2][1] + bbzL = bbox[0][2]; bbzR = bbox[1][2] + xct = int((bbxR - bbxL) / gs) + yct = int((bbyR - bbyL) / gs) + zct = int((bbzR - bbzL) / gs) + xs = int(xct/2); ys = int(yct/2); zs = int(zct/2) + print(' CASTING', xct, '/', yct, '/', zct, 'cells, total:', xct*yct*zct, 'in obj-', ob.name) + ll = [] + rc = 100 ###---DISTANCE TO CAST FROM + ###---RAYCAST TOP/BOTTOM + print(' RAYCASTING TOP/BOTTOM') + for x in range(xct): + for y in range(yct): + xco = bbxL + (x*gs); yco = bbyL + (y*gs) + v1 = ((xco, yco, rc)); v2 = ((xco, yco, -rc)) + vz1 = ob.ray_cast(v1,v2); vz2 = ob.ray_cast(v2,v1) + if vz1[2] != -1: ll.append((x-xs, y-ys, int(vz1[0][2] * (1/gs)) )) + if vz2[2] != -1: ll.append((x-xs, y-ys, int(vz2[0][2] * (1/gs)) )) + ###---RAYCAST FRONT/BACK + print(' RAYCASTING FRONT/BACK') + for x in range(xct): + for z in range(zct): + xco = bbxL + (x*gs); zco = bbzL + (z*gs) + v1 = ((xco, rc, zco)); v2 = ((xco, -rc, zco)) + vy1 = ob.ray_cast(v1,v2); vy2 = ob.ray_cast(v2,v1) + if vy1[2] != -1: ll.append((x-xs, int(vy1[0][1] * (1/gs)), z-zs)) + if vy2[2] != -1: ll.append((x-xs, int(vy2[0][1] * (1/gs)), z-zs)) + ###---RAYCAST LEFT/RIGHT + print(' RAYCASTING LEFT/RIGHT') + for y in range(yct): + for z in range(zct): + yco = bbyL + (y*gs); zco = bbzL + (z*gs) + v1 = ((rc, yco, zco)); v2 = ((-rc, yco, zco)) + vx1 = ob.ray_cast(v1,v2); vx2 = ob.ray_cast(v2,v1) + if vx1[2] != -1: ll.append((int(vx1[0][0] * (1/gs)), y-ys, z-zs)) + if vx2[2] != -1: ll.append((int(vx2[0][0] * (1/gs)), y-ys, z-zs)) + + ###---ADD IN NEIGHBORS SO BOLT WONT GO THRU + nlist = [] + for l in ll: + nl = getStencil3D_26(l[0], l[1], l[2]) + nlist += nl + + ###---DEDUPE + print(' ADDED NEIGHBORS, DEDUPING...') + rlist = deDupe(ll+nlist) + qlist = [] + + ###---RELOCATE GRID W/ RESPECT GSCALE AND BOLT ORIGIN + ### !!!NEED TO ADD IN OBJ ROT/SCALE HERE SOMEHOW... + od = Vector(( (ob.location[0] - orig[0]) / gs, + (ob.location[1] - orig[1]) / gs, + (ob.location[2] - orig[2]) / gs )) + for r in rlist: + qlist.append((r[0]+int(od[0]), r[1]+int(od[1]), r[2]+int(od[2]) )) + + return qlist + +def fakeGroundChargePlane(z, charge): + eCL = [] + xy = abs(z)/2 + eCL += [(0, 0, z, charge)] + eCL += [(xy, 0, z, charge)] + eCL += [(0, xy, z, charge)] + eCL += [(-xy, 0, z, charge)] + eCL += [(0, -xy, z, charge)] + return eCL + +def addCharges(ll, charge): +###---IN: ll - [(x,y,z), (x,y,z)], charge - w +### OUT clist - [(x,y,z,w), (x,y,z,w)] + clist = [] + for l in ll: + clist.append((l[0], l[1], l[2], charge)) + return clist + +###################################################################### +########################### ALGORITHM FXNS ########################### +############################## FROM FSLG ############################# +###################################################################### +def getGrowthProbability_KEEPFORREFERENCE(uN, aList): + ###---IN: uN -USER TERM, cList -CANDIDATE SITES, oList -CANDIDATE SITE CHARGES + ### OUT: LIST OF [(XYZ), POT, PROB] + cList = splitList(aList, 0) + oList = splitList(aList, 1) + Omin, Omax = getLowHigh(oList) + if Omin == Omax: Omax += notZero; Omin -= notZero + PdL = [] + E = 0 + E = notZero ###===DIVISOR FOR (FSLG - Eqn. 12) + for o in oList: + Uj = (o - Omin) / (Omax - Omin) ###===(FSLG - Eqn. 13) + E += pow(Uj, uN) + for oi in range(len(oList)): + o = oList[oi] + Ui = (o - Omin) / (Omax - Omin) + Pd = (pow(Ui, uN)) / E ###===(FSLG - Eqn. 12) + PdINT = Pd * 100 + PdL.append(Pd) + return PdL + +###---WORK IN PROGRESS, TRYING TO SPEED THESE UP +def fslg_e13(x, min, max, u): return pow((x - min) / (max - min), u) +def addit(x,y):return x+y +def fslg_e12(x, min, max, u, e): return (fslg_e13(x, min, max, u) / e) * 100 + +def getGrowthProbability(uN, aList): + ###---IN: uN -USER TERM, cList -CANDIDATE SITES, oList -CANDIDATE SITE CHARGES + ### OUT: LIST OF PROB + cList = splitList(aList, 0) + oList = splitList(aList, 1) + Omin, Omax = getLowHigh(oList) + if Omin == Omax: Omax += notZero; Omin -= notZero + PdL = [] + E = notZero + minL = [Omin for q in range(len(oList))] + maxL = [Omax for q in range(len(oList))] + uNL = [uN for q in range(len(oList))] + E = sum(map(fslg_e13, oList, minL, maxL, uNL)) + EL = [E for q in range(len(oList))] + mp = map(fslg_e12, oList, minL, maxL, uNL, EL) + for m in mp: PdL.append(m) + return PdL + +def updatePointCharges(p, cList, eList = []): + ###---IN: pNew -NEW GROWTH CELL + ### cList -OLD CANDIDATE SITES, eList -SAME + ### OUT: LIST OF NEW CHARGE AT CANDIDATE SITES + r1 = 1/2 ###===(FSLG - Eqn. 10) + nOiL = [] + for oi in range(len(cList)): + o = cList[oi][1] + c = cList[oi][0] + iOe = 0 + rit = dist(c[0], c[1], c[2], p[0], p[1], p[2]) + iOe += (1 - (r1/rit)) + Oit = o + iOe + nOiL.append((c, Oit)) + return nOiL + +def initialPointCharges(pList, cList, eList = []): + ###---IN: p -CHARGED CELL (XYZ), cList -CANDIDATE SITES (XYZ, POT, PROB) + ### OUT: cList -WITH POTENTIAL CALCULATED + r1 = 1/2 ###===(FSLG - Eqn. 10) + npList = [] + for p in pList: + npList.append(((p[0], p[1], p[2]), 1.0)) + for e in eList: + npList.append(((e[0], e[1], e[2]), e[3])) + OiL = [] + for i in cList: + Oi = 0 + for j in npList: + if i != j[0]: + rij = dist(i[0], i[1], i[2], j[0][0], j[0][1], j[0][2]) + Oi += (1 - (r1 / rij)) * j[1] ### CHARGE INFLUENCE + OiL.append(((i[0], i[1], i[2]), Oi)) + return OiL + +def getCandidateSites(aList, iList = []): + ###---IN: aList -(X,Y,Z) OF CHARGED CELL SITES, iList -insulator sites + ### OUT: CANDIDATE LIST OF GROWTH SITES [(X,Y,Z)] + tt1 = time.clock() + cList = [] + for c in aList: + tempList = getStencil3D_26(c[0], c[1], c[2]) + for t in tempList: + if not t in aList and not t in iList: + cList.append(t) + ncList = deDupe(cList) + tt2 = time.clock() + #print('FXNTIMER:getCandidateSites:', tt2-tt1, 'check 26 against:', len(aList)+len(iList)) + return ncList + +###################################################################### +############################# SETUP FXNS ############################# +###################################################################### +def setupObjects(): + oOB = bpy.data.objects.new('ELorigin', None) + oOB.location = ((0,0,10)) + bpy.context.scene.objects.link(oOB) + + gOB = bpy.data.objects.new('ELground', None) + gOB.empty_draw_type = 'ARROWS' + bpy.context.scene.objects.link(gOB) + + cME = makeMeshCube(1) + cOB = bpy.data.objects.new('ELcloud', cME) + cOB.location = ((-2,8,12)) + cOB.hide_render = True + bpy.context.scene.objects.link(cOB) + + iME = makeMeshCube(1) + for v in iME.vertices: + xyl = 6.5; zl = .5 + v.co[0] = v.co[0] * xyl + v.co[1] = v.co[1] * xyl + v.co[2] = v.co[2] * zl + iOB = bpy.data.objects.new('ELinsulator', iME) + iOB.location = ((0,0,5)) + iOB.hide_render = True + bpy.context.scene.objects.link(iOB) + + try: + scn.OOB = 'ELorigin' + scn.GOB = 'ELground' + scn.COB = 'ELcloud' + scn.IOB = 'ELinsulator' + except: pass + +def checkSettings(): + check = True + if scn.OOB == "": + print('ERROR: NO ORIGIN OBJECT SELECTED') + check = False + if scn.GROUNDBOOL and scn.GOB == "": + print('ERROR: NO GROUND OBJECT SELECTED') + check = False + if scn.CLOUDBOOL and scn.COB == "": + print('ERROR: NO CLOUD OBJECT SELECTED') + check = False + if scn.IBOOL and scn.IOB == "": + print('ERROR: NO INSULATOR OBJECT SELECTED') + check = False + #should make a popup here + return check + + +###################################################################### +############################### MAIN ################################# +###################################################################### +def FSLG(): +###======FAST SIMULATION OF LAPLACIAN GROWTH======### + print('\n<<<<<<------GO GO GADGET: FAST SIMULATION OF LAPLACIAN GROWTH!') + tc1 = time.clock() + TSTEPS = scn.TSTEPS + + obORIGIN = scn.objects[scn.OOB] + obGROUND = scn.objects[scn.GOB] + scn.ORIGIN = obORIGIN.location + scn.GROUNDZ = int((obGROUND.location[2] - scn.ORIGIN[2]) / scn.GSCALE) + + ###====== 1) INSERT INTIAL CHARGE(S) POINT (USES VERTS IF MESH) + cgrid = [(0, 0, 0)] + if obORIGIN.type == 'MESH': + print("<<<<<<------ORIGIN OBJECT IS MESH, 'VOXELIZING' INTIAL CHARGES FROM VERTS") + cgrid = voxelByVertex(obORIGIN, scn.GSCALE) + if scn.VMMESH: + print("<<<<<<------CANNOT CLASSIFY STROKE FROM VERT ORIGINS YET, NO MULTI-MESH OUTPUT") + scn.VMMESH = False; scn.VSMESH = True + + ###---GROUND CHARGE CELL / INSULATOR LISTS (eChargeList/icList) + eChargeList = []; icList = [] + if scn.GROUNDBOOL: + eChargeList = fakeGroundChargePlane(scn.GROUNDZ, scn.GROUNDC) + if scn.CLOUDBOOL: + print("<<<<<<------'VOXELIZING' CLOUD OBJECT (COULD TAKE SOME TIME)") + obCLOUD = scn.objects[scn.COB] + eChargeListQ = voxelByRays(obCLOUD, scn.ORIGIN, scn.GSCALE) + eChargeList = addCharges(eChargeListQ, scn.CLOUDC) + print('<<<<<<------CLOUD OBJECT CELL COUNT = ', len(eChargeList) ) + if scn.IBOOL: + print("<<<<<<------'VOXELIZING' INSULATOR OBJECT (COULD TAKE SOME TIME)") + obINSULATOR = scn.objects[scn.IOB] + icList = voxelByRays(obINSULATOR, scn.ORIGIN, scn.GSCALE) + print('<<<<<<------INSULATOR OBJECT CELL COUNT = ', len(icList) ) + #writeArrayToCubes(icList, scn.GSCALE, scn.ORIGIN) + #return 'THEEND' + + ###====== 2) LOCATE CANDIDATE SITES AROUND CHARGE + cSites = getCandidateSites(cgrid, icList) + + ###====== 3) CALC POTENTIAL AT EACH SITE (Eqn. 10) + cSites = initialPointCharges(cgrid, cSites, eChargeList) + + ts = 1 + while ts <= TSTEPS: + ###====== 1) SELECT NEW GROWTH SITE (Eqn. 12) + ###===GET PROBABILITIES AT CANDIDATE SITES + gProbs = getGrowthProbability(scn.BIGVAR, cSites) + ###===CHOOSE NEW GROWTH SITE BASED ON PROBABILITIES + gSitei = weightedRandomChoice(gProbs) + gsite = cSites[gSitei][0] + + ###====== 2) ADD NEW POINT CHARGE AT GROWTH SITE + ###===ADD NEW GROWTH CELL TO GRID + cgrid.append(gsite) + ###===REMOVE NEW GROWTH CELL FROM CANDIDATE SITES + cSites.remove(cSites[gSitei]) + + ###====== 3) UPDATE POTENTIAL AT CANDIDATE SITES (Eqn. 11) + cSites = updatePointCharges(gsite, cSites, eChargeList) + + ###====== 4) ADD NEW CANDIDATES SURROUNDING GROWTH SITE + ###===GET CANDIDATE 'STENCIL' + ncSitesT = getCandidateSites([gsite], icList) + ###===REMOVE CANDIDATES ALREADY IN CANDIDATE LIST OR CHARGE GRID + ncSites = [] + cSplit = splitList(cSites, 0) + for cn in ncSitesT: + if not cn in cSplit and \ + not cn in cgrid: + ncSites.append((cn, 0)) + + ###====== 5) CALC POTENTIAL AT NEW CANDIDATE SITES (Eqn. 10) + ncSplit = splitList(ncSites, 0) + ncSites = initialPointCharges(cgrid, ncSplit, eChargeList) + + ###===ADD NEW CANDIDATE SITES TO CANDIDATE LIST + for ncs in ncSites: + cSites.append(ncs) + + ###===ITERATION COMPLETE + istr1 = ':::T-STEP: ' + str(ts) + '/' + str(TSTEPS) + istr12 = ' | GROUNDZ: ' + str(scn.GROUNDZ) + ' | ' + istr2 = 'CANDS: ' + str(len(cSites)) + ' | ' + istr3 = 'GSITE: ' + str(gsite) + print(istr1 + istr12 + istr2 + istr3) + ts += 1 + + ###---EARLY TERMINATION FOR GROUND/CLOUD STRIKE + if scn.GROUNDBOOL: + if gsite[2] == scn.GROUNDZ: + ts = TSTEPS+1 + print('<<<<<<------EARLY TERMINATION DUE TO GROUNDSTRIKE') + continue + if scn.CLOUDBOOL: + #if gsite in cloudList: + if gsite in splitListCo(eChargeList): + ts = TSTEPS+1 + print('<<<<<<------EARLY TERMINATION DUE TO CLOUDSTRIKE') + continue + + tc2 = time.clock() + tcRUN = tc2 - tc1 + print('<<<<<<------LAPLACIAN GROWTH LOOP COMPLETED: ' + str(len(cgrid)) + ' / ' + str(tcRUN)[0:5] + ' SECONDS') + print('<<<<<<------VISUALIZING DATA') + + reportSTRING = getReportString(tcRUN) + ###---VISUALIZE ARRAY + visualizeArray(cgrid, obORIGIN, scn.GSCALE, scn.VMMESH, scn.VSMESH, scn.VCUBE, scn.VVOX, reportSTRING) + print('<<<<<<------COMPLETE') + +###################################################################### +################################ GUI ################################# +###################################################################### +###---NOT IN UI +bpy.types.Scene.ORIGIN = bpy.props.FloatVectorProperty(name = "origin charge") +bpy.types.Scene.GROUNDZ = bpy.props.IntProperty(name = "ground Z coordinate") +bpy.types.Scene.HORDER = bpy.props.IntProperty(name = "secondary paths orders") +###---IN UI +bpy.types.Scene.TSTEPS = bpy.props.IntProperty( + name = "iterations", description = "number of cells to create, will end early if hits ground plane or cloud") +bpy.types.Scene.GSCALE = bpy.props.FloatProperty( + name = "grid unit size", description = "scale of cells, .25 = 4 cells per blenderUnit") +bpy.types.Scene.BIGVAR = bpy.props.FloatProperty( + name = "straightness", description = "straightness/branchiness of bolt, <2 is mush, >12 is staight line, 6.3 is good") +bpy.types.Scene.GROUNDBOOL = bpy.props.BoolProperty( + name = "use ground object", description = "use ground plane or not") +bpy.types.Scene.GROUNDC = bpy.props.IntProperty( + name = "ground charge", description = "charge of ground plane") +bpy.types.Scene.CLOUDBOOL = bpy.props.BoolProperty( + name = "use cloud object", description = "use cloud obj, attracts and terminates like ground but any obj instead of z plane, can slow down loop if obj is large, overrides ground") +bpy.types.Scene.CLOUDC = bpy.props.IntProperty( + name = "cloud charge", description = "charge of a cell in cloud object (so total charge also depends on obj size)") + +bpy.types.Scene.VMMESH = bpy.props.BoolProperty( + name = "multi mesh", description = "output to multi-meshes for different materials on main/sec/side branches") +bpy.types.Scene.VSMESH = bpy.props.BoolProperty( + name = "single mesh", description = "output to single mesh for using build modifier and particles for effects") +bpy.types.Scene.VCUBE = bpy.props.BoolProperty( + name = "cubes", description = "CTRL-J after run to JOIN, outputs a bunch of cube objest, mostly for testing") +bpy.types.Scene.VVOX = bpy.props.BoolProperty( + name = "voxel (experimental)", description = "output to a voxel file to bpy.data.filepath\FSLGvoxels.raw - doesn't work well right now") +bpy.types.Scene.IBOOL = bpy.props.BoolProperty( + name = "use insulator object", description = "use insulator mesh object to prevent growth of bolt in areas") +bpy.types.Scene.OOB = bpy.props.StringProperty(description = "origin of bolt, can be an Empty, if obj is mesh will use all verts as charges") +bpy.types.Scene.GOB = bpy.props.StringProperty(description = "object to use as ground plane, uses z coord only") +bpy.types.Scene.COB = bpy.props.StringProperty(description = "object to use as cloud, best to use a cube") +bpy.types.Scene.IOB = bpy.props.StringProperty(description = "object to use as insulator, 'voxelized' before generating bolt, can be slow") + +###---DEFAULT USER SETTINGS +scn.TSTEPS = 350 +scn.HORDER = 1 +scn.GSCALE = 0.12 +scn.BIGVAR = 6.3 +scn.GROUNDBOOL = True +scn.GROUNDC = -250 +scn.CLOUDBOOL = False +scn.CLOUDC = -1 +scn.VMMESH = True +scn.VSMESH = False +scn.VCUBE = False +scn.VVOX = False +scn.IBOOL = False +try: + scn.OOB = "ELorigin" + scn.GOB = "ELground" + scn.COB = "ELcloud" + scn.IOB = "ELinsulator" +except: pass +### TESTING +if False: +#if True: + #scn.BIGVAR = 6.3 + #scn.VSMESH = True + #scn.VMMESH = False + #scn.VCUBE = True + #scn.TSTEPS = 7500 + scn.TSTEPS = 100 + #scn.GROUNDC = -500 + #scn.CLOUDC = -5 + #scn.GROUNDBOOL = False + #scn.CLOUDBOOL = True + + #scn.IBOOL = True + +class runFSLGLoopOperator(bpy.types.Operator): + '''By The Mighty Hammer Of Thor!!!''' + bl_idname = "object.runfslg_operator" + bl_label = "run FSLG Loop Operator" + + def execute(self, context): + if checkSettings(): + FSLG() + else: pass + return {'FINISHED'} + +class setupObjectsOperator(bpy.types.Operator): + '''create origin/ground/cloud/insulator objects''' + bl_idname = "object.setup_objects_operator" + bl_label = "Setup Objects Operator" + + def execute(self, context): + setupObjects() + return {'FINISHED'} + +class OBJECT_PT_fslg(bpy.types.Panel): + bl_label = "Laplacian Lightning - v0.2.6" + bl_space_type = "VIEW_3D" + bl_region_type = "TOOLS" + bl_context = "objectmode" + + def draw(self, context): + scn = context.scene + layout = self.layout + colR = layout.column() + #row1 = layout.row() + #colL = row1.column() + #colR = row1.column() + colR.label('-for progress open console-') + colR.label('Help > Toggle System Console') + colR.prop(scn, 'TSTEPS') + colR.prop(scn, 'GSCALE') + colR.prop(scn, 'BIGVAR') + colR.operator('object.setup_objects_operator', text = 'create setup objects') + colR.label('origin object') + colR.prop_search(scn, "OOB", context.scene, "objects") + colR.prop(scn, 'GROUNDBOOL') + colR.prop_search(scn, "GOB", context.scene, "objects") + colR.prop(scn, 'GROUNDC') + colR.prop(scn, 'CLOUDBOOL') + colR.prop_search(scn, "COB", context.scene, "objects") + colR.prop(scn, 'CLOUDC') + colR.prop(scn, 'IBOOL') + colR.prop_search(scn, "IOB", context.scene, "objects") + colR.operator('object.runfslg_operator', text = 'generate lightning') + #col.prop(scn, 'HORDER') + colR.prop(scn, 'VMMESH') + colR.prop(scn, 'VSMESH') + colR.prop(scn, 'VCUBE') + colR.prop(scn, 'VVOX') + +def getReportString(rtime): + rSTRING1 = 't:' + str(scn.TSTEPS) + ',sc:' + str(scn.GSCALE)[0:4] + ',uv:' + str(scn.BIGVAR)[0:4] + ',' + rSTRING2 = 'ori:' + str(scn. ORIGIN[0]) + '/' + str(scn. ORIGIN[1]) + '/' + str(scn. ORIGIN[2]) + ',' + rSTRING3 = 'gz:' + str(scn.GROUNDZ) + ',gc:' + str(scn.GROUNDC) + ',rtime:' + str(int(rtime)) + return rSTRING1 + rSTRING2 + rSTRING3 + +def addReportProp(ob, str): + bpy.types.Object.FSLG_REPORT = bpy.props.StringProperty( + name = 'fslg_report', default = '') + ob.FSLG_REPORT = str + +def register(): + bpy.utils.register_class(runFSLGLoopOperator) + bpy.utils.register_class(setupObjectsOperator) + bpy.utils.register_class(OBJECT_PT_fslg) + +def unregister(): + bpy.utils.unregister_class(runFSLGLoopOperator) + bpy.utils.unregister_class(setupObjectsOperator) + bpy.utils.unregister_class(OBJECT_PT_fslg) + +if __name__ == "__main__": + ### RUN FOR TESTING + #FSLG() + + ### UI + register() + pass + +########################### +##### FXN BENCHMARKS ###### +########################### +def BENCH(): + print('\n\n\n--->BEGIN BENCHMARK') + bt0 = time.clock() + ###---MAKE A BIG LIST + tsize = 25 + tlist = [] + for x in range(tsize): + for y in range(tsize): + for z in range(tsize): + tlist.append((x,y,z)) + tlist.append((x,y,z)) + + ###---FUNCTION TO TEST + bt1 = time.clock() + + #ll = deDupe(tlist) + #ll = f5(tlist) + print('LENS - ', len(tlist), len(ll) ) + + bt2 = time.clock() + btRUNb = bt2 - bt1 + btRUNa = bt1 - bt0 + print('--->SETUP TIME : ', btRUNa) + print('--->BENCHMARK TIME: ', btRUNb) + print('--->GRIDSIZE: ', tsize, ' - ', tsize*tsize*tsize) + +#BENCH() + + +################################## +################################ diff -Nru blender-2.61/release/scripts/addons_contrib/oscurart_futurism.py blender-2.62/release/scripts/addons_contrib/oscurart_futurism.py --- blender-2.61/release/scripts/addons_contrib/oscurart_futurism.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/oscurart_futurism.py 2012-02-15 19:43:59.000000000 +0000 @@ -0,0 +1,128 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the 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. +# +# ##### END GPL LICENSE BLOCK ##### + +bl_info = { + "name": "Futurism", + "author": "Oscurart", + "version": (1, 1), + "blender": (2, 5, 9), + "api": 40900, + "location": "Object > Futurism", + "description": "Adds a new Mesh Object", + "warning": "", + "wiki_url": "", + "tracker_url": "", + "category": "Add Mesh"} + + +import bpy + +def object_osc_futurism (self, context,STEP, HOLD): + ACTOBJ=bpy.context.active_object # OBJETO ACTIVO + FS=bpy.context.scene.frame_start # FRAME START + FE=bpy.context.scene.frame_end # FRAME END + OBJLIST=[] # LISTA PARA OBJETOS ???? + FC=FS # FRAME CURRENT + OBJNUMBER=1 # SUFIJO DE NUMERO PARA OBJETOS + STEPINC=0 # NUMERO PARA EVALUAR LOS PASOS + # SETEO EL FRAME CURRENT + bpy.context.scene.frame_set(FS) + + OBACT = bpy.context.active_object + + ## CREO EMPTY + bpy.ops.object.add() + bpy.context.active_object.name = "FuturismContainer" + EMPTY = bpy.context.active_object + + bpy.context.scene.objects.active = OBACT + + for OBJETO in range((FE+1)-FS): + if STEPINC == STEP: + # CREO UN MESH A PARTIR DE OBJETO + MESH=ACTOBJ.to_mesh(bpy.context.scene, True, 'PREVIEW') + # CREO OBJETO + OBJECT=bpy.data.objects.new(ACTOBJ.name[:3]+str(FC), MESH) + # CONECTO A LA ESCENA + bpy.context.scene.objects.link(OBJECT) + # SETEO FRAME CURRENT + bpy.context.scene.frame_set(FC) + # MARCO EXPRESIONES PARA VIEW + OBJECT.driver_add("hide") + OBJECT.animation_data.drivers[0].driver.variables.new() + OBJECT.animation_data.drivers[0].driver.expression= "False if frame >= "+str(FC)+" and frame <= "+str(FC+HOLD)+" else True" + OBJECT.animation_data.drivers[0].driver.variables[0].targets[0].id_type = 'SCENE' + OBJECT.animation_data.drivers[0].driver.variables[0].targets[0].id= bpy.context.scene + OBJECT.animation_data.drivers[0].driver.variables[0].targets[0].data_path = "current_frame" + # MARCO EXPRESIONES PARA RENDER + OBJECT.driver_add("hide_render") + OBJECT.animation_data.drivers[1].driver.variables.new() + OBJECT.animation_data.drivers[1].driver.expression= "False if frame >= "+str(FC)+" and frame <= "+str(FC+HOLD)+" else True" + OBJECT.animation_data.drivers[1].driver.variables[0].targets[0].id_type = 'SCENE' + OBJECT.animation_data.drivers[1].driver.variables[0].targets[0].id= bpy.context.scene + OBJECT.animation_data.drivers[1].driver.variables[0].targets[0].data_path = "current_frame" + # RESETEO STEPINC + STEPINC=0 + # COPIAMOS S R T + OBJECT.matrix_world=ACTOBJ.matrix_world + #EMPARENTO + OBJECT.parent=EMPTY + # AVANZO STEP Y FRAME + FC+=1 + STEPINC+=1 + + + +# CLASE PARA OPERADOR +class Oscurart_futurism (bpy.types.Operator): + bl_idname = "object.duplicate_futurism" + bl_label = "Duplicate Futurism" + bl_description = "Duplicate object per frame" + bl_options = {'REGISTER', 'UNDO'} + + scale = bpy.props.IntProperty(name='Step',default=1, min=1, max=1000) + + hold = bpy.props.IntProperty(name='Hold', default=0, min=0) + + def execute(self, context): + object_osc_futurism(self, context, self.scale, self.hold) + + return {'FINISHED'} + + +# Registration + +def add_osc_futurism_button(self, context): + self.layout.operator( + Oscurart_futurism.bl_idname, + text="Futurism", + icon="PLUGIN") + + +def register(): + bpy.utils.register_class(Oscurart_futurism) + bpy.types.VIEW3D_MT_object.append(add_osc_futurism_button) + + +def unregister(): + bpy.utils.unregister_class(Oscurart_futurism) + bpy.types.VIEW3D_MT_object.remove(add_osc_futurism_button) + + +if __name__ == '__main__': + register() diff -Nru blender-2.61/release/scripts/addons_contrib/presets/interface_theme/default_theme.xml blender-2.62/release/scripts/addons_contrib/presets/interface_theme/default_theme.xml --- blender-2.61/release/scripts/addons_contrib/presets/interface_theme/default_theme.xml 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/presets/interface_theme/default_theme.xml 2012-02-15 19:43:51.000000000 +0000 @@ -0,0 +1,813 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru blender-2.61/release/scripts/addons_contrib/presets/interface_theme/theme_3ds_max.xml blender-2.62/release/scripts/addons_contrib/presets/interface_theme/theme_3ds_max.xml --- blender-2.61/release/scripts/addons_contrib/presets/interface_theme/theme_3ds_max.xml 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/presets/interface_theme/theme_3ds_max.xml 2012-02-15 19:43:51.000000000 +0000 @@ -0,0 +1,812 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru blender-2.61/release/scripts/addons_contrib/presets/interface_theme/theme_blender_25x.xml blender-2.62/release/scripts/addons_contrib/presets/interface_theme/theme_blender_25x.xml --- blender-2.61/release/scripts/addons_contrib/presets/interface_theme/theme_blender_25x.xml 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/presets/interface_theme/theme_blender_25x.xml 2012-02-15 19:43:51.000000000 +0000 @@ -0,0 +1,806 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru blender-2.61/release/scripts/addons_contrib/presets/interface_theme/theme_maya.xml blender-2.62/release/scripts/addons_contrib/presets/interface_theme/theme_maya.xml --- blender-2.61/release/scripts/addons_contrib/presets/interface_theme/theme_maya.xml 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/presets/interface_theme/theme_maya.xml 2012-02-15 19:43:51.000000000 +0000 @@ -0,0 +1,812 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru blender-2.61/release/scripts/addons_contrib/presets/interface_theme/theme_pinkified.xml blender-2.62/release/scripts/addons_contrib/presets/interface_theme/theme_pinkified.xml --- blender-2.61/release/scripts/addons_contrib/presets/interface_theme/theme_pinkified.xml 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/presets/interface_theme/theme_pinkified.xml 2012-02-15 19:43:51.000000000 +0000 @@ -0,0 +1,813 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru blender-2.61/release/scripts/addons_contrib/presets/interface_theme/theme_softblend.xml blender-2.62/release/scripts/addons_contrib/presets/interface_theme/theme_softblend.xml --- blender-2.61/release/scripts/addons_contrib/presets/interface_theme/theme_softblend.xml 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/presets/interface_theme/theme_softblend.xml 2012-02-15 19:43:51.000000000 +0000 @@ -0,0 +1,812 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru blender-2.61/release/scripts/addons_contrib/presets/interface_theme/theme_softdefault.xml blender-2.62/release/scripts/addons_contrib/presets/interface_theme/theme_softdefault.xml --- blender-2.61/release/scripts/addons_contrib/presets/interface_theme/theme_softdefault.xml 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/presets/interface_theme/theme_softdefault.xml 2012-02-15 19:43:51.000000000 +0000 @@ -0,0 +1,813 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru blender-2.61/release/scripts/addons_contrib/presets/interface_theme/theme_zbrush.xml blender-2.62/release/scripts/addons_contrib/presets/interface_theme/theme_zbrush.xml --- blender-2.61/release/scripts/addons_contrib/presets/interface_theme/theme_zbrush.xml 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/presets/interface_theme/theme_zbrush.xml 2012-02-15 19:43:51.000000000 +0000 @@ -0,0 +1,812 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru blender-2.61/release/scripts/addons_contrib/render_clay.py blender-2.62/release/scripts/addons_contrib/render_clay.py --- blender-2.61/release/scripts/addons_contrib/render_clay.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/render_clay.py 2012-02-15 19:43:59.000000000 +0000 @@ -23,7 +23,6 @@ "author": "Fabio Russo ", "version": (1, 2), "blender": (2, 5, 6), - "api": 35115, "location": "Render > Clay Render", "description": "This script, applies a temporary material to all objects"\ " of the scene.", @@ -202,7 +201,6 @@ description='Use as Clay', default=False) - bpy.utils.register_class(ClayPinned) bpy.utils.register_class(CheckClay) bpy.types.RENDER_PT_render.prepend(draw_clay_render) diff -Nru blender-2.61/release/scripts/addons_contrib/render_copy_settings/__init__.py blender-2.62/release/scripts/addons_contrib/render_copy_settings/__init__.py --- blender-2.61/release/scripts/addons_contrib/render_copy_settings/__init__.py 2011-12-13 19:59:21.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/render_copy_settings/__init__.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,154 +0,0 @@ -# ##### BEGIN GPL LICENSE BLOCK ##### -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the 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. -# -# ##### END GPL LICENSE BLOCK ##### - -# - -# ##### CHANGELOG ##### -# -# 0.0.1 -# Initial release. -# -# 0.0.2 -# Updates to follow Blender API: -# * bl_addon_info renamed in bl_info! -# * adding bpy.utils.(un)register_module calls. -# Also, in standard import, using “from . import …” now. -# -# 0.1.0 -# Renamed in “Render Copy Settings”. -# Huge changes: -# * It is now possible to individually copy each render setting. -# * It is now possible to individually select each affected scene, and then filter them out -# even further with a regex. -# WARNING: this addon now needs a Blender patched with the ui_template_list diff, else it won’t -# be fully functional… -# -# 0.1.1 -# Minor changes: -# * PEP8 compliant. -# * Moved to contrib… -# WARNING: this addon now needs a Blender patched with the ui_template_list diff, else it won’t -# be fully functional (even though working)… -# -# 0.1.2 -# Minor changes: -# * Updated accordingly to the changes in enhanced ui_template_list proposal. -# WARNING: this addon now needs a Blender patched with the ui_template_list diff, else it won’t -# be fully functional (even though working)… -# -# 0.1.3 -# Minor changes: -# * Fixed a small bug that was disabling the whole UI when entering a filtering regex -# matching no scene. -# WARNING: this addon now needs a Blender patched with the ui_template_list diff, else it won’t -# be fully functional (even though working)… -# -# ##### END OF CHANGELOG ##### - -bl_info = { - "name": "Copy Settings", - "author": "Bastien Montagne", - "version": (0, 1, 3), - "blender": (2, 5, 9), - "api": 36380, - "location": "Render buttons (Properties window)", - "description": "Allows to copy a selection of render settings from current scene to others.", - "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\ - "Scripts/Render/Copy Settings", - "tracker_url": "http://projects.blender.org/tracker/index.php?func=detail&aid=25832", - "category": "Render"} - - -if "bpy" in locals(): - import imp - imp.reload(operator) - imp.reload(panel) - -else: - from . import operator, panel - - -import bpy -from bpy.props import StringProperty, BoolProperty, IntProperty, CollectionProperty - - -#################################################################################################### -# Global properties for the script, for UI (as there’s no way to let them in the operator…). -#################################################################################################### - -class RenderCopySettingsScene(bpy.types.PropertyGroup): - allowed = BoolProperty(default=True) - - # A string of identifiers (colon delimited) which property’s controls should be displayed - # in a template_list. - template_list_controls = StringProperty(default="allowed", options={"HIDDEN"}) - - -class RenderCopySettingsSetting(bpy.types.PropertyGroup): - copy = BoolProperty(default=False) - - # A string of identifiers (colon delimited) which property’s controls should be displayed - # in a template_list. - template_list_controls = StringProperty(default="copy", options={"HIDDEN"}) - - -class RenderCopySettings(bpy.types.PropertyGroup): - # XXX: The consistency of this collection is delegated to the UI code. - # It should only contain one element for each render setting. - affected_settings = CollectionProperty(type=RenderCopySettingsSetting, - name="Affected Settings", - description="The list of all available render settings.") - # XXX Unused, but needed for template_list… - aff_sett_idx = IntProperty() - - # XXX: The consistency of this collection is delegated to the UI code. - # It should only contain one element for each scene. - allowed_scenes = CollectionProperty(type=RenderCopySettingsScene, - name="Allowed Scenes", - description="The list all scenes in the file.") - # XXX Unused, but needed for template_list… - allw_scenes_idx = IntProperty() - - filter_scene = StringProperty(name="Filter Scene", - description="Regex to only affect scenes which name matches it.", - default="") - - -def register(): - # Register properties. - bpy.utils.register_class(RenderCopySettingsScene) - bpy.utils.register_class(RenderCopySettingsSetting) - bpy.utils.register_class(RenderCopySettings) - bpy.types.Scene.render_copy_settings = \ - bpy.props.PointerProperty(type=RenderCopySettings) - - bpy.utils.register_module(__name__) - - -def unregister(): - # Unregister properties. - bpy.utils.unregister_class(RenderCopySettingsScene) - bpy.utils.unregister_class(RenderCopySettingsSetting) - bpy.utils.unregister_class(RenderCopySettings) - del bpy.types.Scene.render_copy_settings - - bpy.utils.unregister_module(__name__) - - -if __name__ == "__main__": - register() diff -Nru blender-2.61/release/scripts/addons_contrib/render_copy_settings/operator.py blender-2.62/release/scripts/addons_contrib/render_copy_settings/operator.py --- blender-2.61/release/scripts/addons_contrib/render_copy_settings/operator.py 2011-12-13 19:59:21.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/render_copy_settings/operator.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,237 +0,0 @@ -# ##### BEGIN GPL LICENSE BLOCK ##### -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the 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. -# -# ##### END GPL LICENSE BLOCK ##### - -# - -import bpy - -# These operators are only defined because it seems impossible to directly edit properties from -# UI code… - - -# A sorting func for collections (working in-place). -# XXX Not optimized at all… -# XXX If some items in the collection do not have the sortkey property, they are just ignored… -def collection_property_sort(collection, sortkey, start_idx=0): - while start_idx + 1 < len(collection): - while not hasattr(collection[start_idx], sortkey): - start_idx += 1 - if start_idx + 1 >= len(collection): - return collection - min_idx = start_idx - min_prop = collection[start_idx] - for i, prop in enumerate(collection[start_idx + 1:]): - if not hasattr(prop, sortkey): - continue - if getattr(prop, sortkey) < getattr(min_prop, sortkey): - min_prop = prop - min_idx = i + start_idx + 1 - collection.move(min_idx, start_idx) - start_idx += 1 - return collection - - -class RenderCopySettingsPrepare(bpy.types.Operator): - ''' - Prepare internal data for render_copy_settings (gathering all existing render settings, - and scenes). - ''' - bl_idname = "scene.render_copy_settings_prepare" - bl_label = "Render: Copy Settings Prepare" - bl_option = {'REGISTER'} - - @classmethod - def poll(cls, context): - return context.scene != None - - def execute(self, context): - cp_sett = context.scene.render_copy_settings - - # Get all available render settings, and update accordingly affected_settings… - props = set() - for prop in context.scene.render.bl_rna.properties: - if prop.identifier in {'rna_type'}: - continue - if prop.is_readonly: - continue - props.add(prop.identifier) - for i, sett in enumerate(cp_sett.affected_settings): - if sett.name not in props: - cp_sett.affected_settings.remove(i) - else: - props.remove(sett.name) - for prop in props: - sett = cp_sett.affected_settings.add() - sett.name = prop -# sett.init_TemplateListControls() - collection_property_sort(cp_sett.affected_settings, "name") - - # Get all available scenes, and update accordingly allowed_scenes… - regex = None - if cp_sett.filter_scene: - try: - import re - try: - regex = re.compile(cp_sett.filter_scene) - except Exception as e: - self.report('ERROR_INVALID_INPUT', "The filter-scene regex " \ - "did not compile:\n (%s)." % str(e)) - return {'CANCELLED'} - except: - regex = None - self.report('WARNING', "Unable to import the re module. Regex " \ - "scene filtering will be disabled!") - scenes = set() - for scene in bpy.data.scenes: - if scene == bpy.context.scene: # Exclude current scene! - continue - if regex: # If a valid filtering regex, only keep scenes matching it. - if regex.match(scene.name): - scenes.add(scene.name) - else: - scenes.add(scene.name) - for i, scene in enumerate(cp_sett.allowed_scenes): - if scene.name not in scenes: - cp_sett.allowed_scenes.remove(i) - else: - scenes.remove(scene.name) - for scene in scenes: - sett = cp_sett.allowed_scenes.add() - sett.name = scene -# sett.init_TemplateListControls() - collection_property_sort(cp_sett.allowed_scenes, "name") - - return {'FINISHED'} - - -from bpy.props import EnumProperty - - -class RenderCopySettingsPreset(bpy.types.Operator): - ''' - Apply some presets of render settings to copy to other scenes. - ''' - bl_idname = "scene.render_copy_settings_preset" - bl_label = "Render: Copy Settings Preset" - bl_description = "Apply or clear this preset of render settings." - # Enable undo… - bl_option = {'REGISTER', 'UNDO'} - - presets = EnumProperty(items=(("resolution", "Render Resolution", "Render resolution and aspect ratio settings"), - ("scale", "Render Scale", "The “Render Scale” setting."), - ("osa", "Render OSA", "The OSA toggle and sample settings."), - ("threads", "Render Threads", "The thread mode and number settings."), - ("fields", "Render Fields", "The Fields settings."), - ("stamp", "Render Stamp", "The Stamp toggle."), - ), - default=set(), - options={"ENUM_FLAG"}) - - @classmethod - def poll(cls, context): - return context.scene != None - - def execute(self, context): - cp_sett = context.scene.render_copy_settings - if "resolution" in self.presets: - res_x = cp_sett.affected_settings["resolution_x"] - res_y = cp_sett.affected_settings["resolution_y"] - asp_x = cp_sett.affected_settings["pixel_aspect_x"] - asp_y = cp_sett.affected_settings["pixel_aspect_y"] - if res_x.copy and res_y.copy and asp_x.copy and asp_y.copy: - res_x.copy = res_y.copy = asp_x.copy = asp_y.copy = False - else: - res_x.copy = res_y.copy = asp_x.copy = asp_y.copy = True - if "scale" in self.presets: - scale = cp_sett.affected_settings["resolution_percentage"] - if scale.copy: - scale.copy = False - else: - scale.copy = True - if "osa" in self.presets: - osa = cp_sett.affected_settings["use_antialiasing"] - osa_lvl = cp_sett.affected_settings["antialiasing_samples"] - if osa.copy and osa_lvl.copy: - osa.copy = osa_lvl.copy = False - else: - osa.copy = osa_lvl.copy = True - if "threads" in self.presets: - thrd_mode = cp_sett.affected_settings["threads_mode"] - threads = cp_sett.affected_settings["threads"] - if thrd_mode.copy and threads.copy: - thrd_mode.copy = threads.copy = False - else: - thrd_mode.copy = threads.copy = True - if "fields" in self.presets: - fields = cp_sett.affected_settings["use_fields"] - field_ord = cp_sett.affected_settings["field_order"] - fields_still = cp_sett.affected_settings["use_fields_still"] - if fields.copy and field_ord.copy and fields_still.copy: - fields.copy = field_ord.copy = fields_still.copy = False - else: - fields.copy = field_ord.copy = fields_still.copy = True - if "stamp" in self.presets: - stamp = cp_sett.affected_settings["use_stamp"] - if stamp.copy: - stamp.copy = False - else: - stamp.copy = True - return {'FINISHED'} - - -# Real interesting stuff… - -def do_copy(context, affected_settings, allowed_scenes): - # Stores render settings from current scene. - p = dict((n, None) for n in affected_settings) - # put it in all other (valid) scenes’ render settings! - for scene in bpy.data.scenes: - # If scene not in allowed scenes, skip. - if scene.name not in allowed_scenes: - continue - # Propagate all affected settings. - for sett in affected_settings: - if p[sett] is None: - p[sett] = getattr(context.scene.render, sett) - setattr(scene.render, sett, p[sett]) - - -class RenderCopySettings(bpy.types.Operator): - ''' - Copy render settings from current scene to others. - ''' - bl_idname = "scene.render_copy_settings" - bl_label = "Render: Copy Settings" - # Enable undo… - bl_option = {'REGISTER', 'UNDO'} - - @classmethod - def poll(cls, context): - return context.scene != None - - def execute(self, context): - regex = None - cp_sett = context.scene.render_copy_settings - affected_settings = set([sett.name for sett in cp_sett.affected_settings if sett.copy]) - allowed_scenes = set([sce.name for sce in cp_sett.allowed_scenes if sce.allowed]) - do_copy(context, affected_settings=affected_settings, allowed_scenes=allowed_scenes) - return {'FINISHED'} - - -if __name__ == "__main__": - bpy.ops.scene.render_copy_settings() diff -Nru blender-2.61/release/scripts/addons_contrib/render_copy_settings/panel.py blender-2.62/release/scripts/addons_contrib/render_copy_settings/panel.py --- blender-2.61/release/scripts/addons_contrib/render_copy_settings/panel.py 2011-12-13 19:59:21.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/render_copy_settings/panel.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,95 +0,0 @@ -# ##### BEGIN GPL LICENSE BLOCK ##### -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the 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. -# -# ##### END GPL LICENSE BLOCK ##### - -# - -import bpy - - -class RENDER_PT_copy_settings(bpy.types.Panel): - bl_label = "Copy Settings" - bl_space_type = "PROPERTIES" - bl_region_type = "WINDOW" - bl_context = "render" - bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} - - def draw(self, context): - layout = self.layout - cp_sett = context.scene.render_copy_settings - - layout.operator("scene.render_copy_settings", text="Copy Render Settings") - - # This will update affected_settings/allowed_scenes (as this seems to be impossible - # to do it from here…). - if bpy.ops.scene.render_copy_settings_prepare.poll(): - bpy.ops.scene.render_copy_settings_prepare() - - split = layout.split(0.75) - split.template_list(cp_sett, "affected_settings", cp_sett, "aff_sett_idx", - enum_ctrls_name="template_list_controls", rows=6) - col = split.column() - label = "" - if (cp_sett.affected_settings["resolution_x"].copy and - cp_sett.affected_settings["resolution_y"].copy and - cp_sett.affected_settings["pixel_aspect_x"].copy and - cp_sett.affected_settings["pixel_aspect_y"].copy): - label = "Clear Resolution" - else: - label = "Set Resolution" - col.operator("scene.render_copy_settings_preset", text=label, ).presets = {"resolution"} - if cp_sett.affected_settings["resolution_percentage"].copy: - label = "Clear Scale" - else: - label = "Set Scale" - col.operator("scene.render_copy_settings_preset", text=label).presets = {"scale"} - if (cp_sett.affected_settings["use_antialiasing"].copy and - cp_sett.affected_settings["antialiasing_samples"].copy): - label = "Clear OSA" - else: - label = "Set OSA" - col.operator("scene.render_copy_settings_preset", text=label).presets = {"osa"} - if (cp_sett.affected_settings["threads_mode"].copy and - cp_sett.affected_settings["threads"].copy): - label = "Clear Threads" - else: - label = "Set Threads" - col.operator("scene.render_copy_settings_preset", text=label).presets = {"threads"} - if (cp_sett.affected_settings["use_fields"].copy and - cp_sett.affected_settings["field_order"].copy and - cp_sett.affected_settings["use_fields_still"].copy): - label = "Clear Fields" - else: - label = "Set Fields" - col.operator("scene.render_copy_settings_preset", text=label).presets = {"fields"} - if cp_sett.affected_settings["use_stamp"].copy: - label = "Clear Stamp" - else: - label = "Set Stamp" - col.operator("scene.render_copy_settings_preset", text=label).presets = {"stamp"} - - layout.prop(cp_sett, "filter_scene") - if len(cp_sett.allowed_scenes): - layout.label("Affected Scenes:") - # XXX Unfortunately, there can only be one template_list per panel… -# layout.template_list(cp_sett, "allowed_scenes", cp_sett, "allw_scenes_idx", rows=5) - col = layout.column_flow(columns=0) - for i, prop in enumerate(cp_sett.allowed_scenes): - col.prop(prop, "allowed", toggle=True, text=prop.name) - else: - layout.label(text="No Affectable Scenes!", icon="ERROR") diff -Nru blender-2.61/release/scripts/addons_contrib/render_to_print.py blender-2.62/release/scripts/addons_contrib/render_to_print.py --- blender-2.61/release/scripts/addons_contrib/render_to_print.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/render_to_print.py 2012-02-15 19:43:59.000000000 +0000 @@ -1,4 +1,3 @@ -import bpy # ##### BEGIN GPL LICENSE BLOCK ##### # # This program is free software; you can redistribute it and/or @@ -17,11 +16,12 @@ # # ##### END GPL LICENSE BLOCK ##### +# bl_info = { 'name': 'Render to Print', - 'author': 'Marco Crippa ', - 'version': (0,2), + 'author': 'Marco Crippa , Dealga McArdle', + 'version': (0, 2), 'blender': (2, 5, 8), 'location': 'Render > Render to Print', 'description': 'Set the size of the render for a print', @@ -32,147 +32,204 @@ 'category': 'Render'} -import bpy import math -from bpy.props import * +import bpy +from bpy.types import Panel, Operator, Scene, PropertyGroup +from bpy.props import (IntProperty, + FloatProperty, + StringProperty, + EnumProperty, + PointerProperty, + ) + + +paper_presets = ( + ("custom_1_1", "custom", ""), + ("A0_84.1_118.9", "A0 (84.1x118.9 cm)", ""), + ("A1_59.4_84.1", "A1 (59.4x84.1 cm)", ""), + ("A2_42.0_59.4", "A2 (42.0x59.4 cm)", ""), + ("A3_29.7_42.0", "A3 (29.7 42.0 cm)", ""), + ("A4_21.0_29.7", "A4 (21.0x29.7 cm)", ""), + ("A5_14.8_21.0", "A5 (14.8x21.0 cm)", ""), + ("A6_10.5_14.8", "A6 (10.5x14.8 cm)", ""), + ("A7_7.4_10.5", "A7 (7.4x10.5 cm)", ""), + ("A8_5.2_7.4", "A8 (5.2x7.4 cm)", ""), + ("A9_3.7_5.2", "A9 (3.7x5.2 cm)", ""), + ("A10_2.6_3.7", "A10 (2.6x3.7 cm)", ""), + + ("B0_100.0_141.4", "B0 (100.0x141.4 cm)", ""), + ("B1_70.7_100.0", "B1 (70.7x100.0 cm)", ""), + ("B2_50.0_70.7", "B2 (50.0x70.7 cm)", ""), + ("B3_35.3_50.0", "B3 (35.3x50.0 cm)", ""), + ("B4_25.0_35.3", "B4 (25.0x35.3 cm)", ""), + ("B5_17.6_25.0", "B5 (17.6x25.0 cm)", ""), + ("B6_12.5_17.6", "B6 (12.5x17.6 cm)", ""), + ("B7_8.8_12.5", "B7 (8.8x12.5 cm)", ""), + ("B8_6.2_8.8", "B8 (6.2x8.8 cm)", ""), + ("B9_4.4_6.2", "B9 (4.4x6.2 cm)", ""), + ("B10_3.1_4.4", "B10 (3.1x4.4 cm)", ""), + + ("C0_91.7_129.7", "C0 (91.7x129.7 cm)", ""), + ("C1_64.8_91.7", "C1 (64.8x91.7 cm)", ""), + ("C2_45.8_64.8", "C2 (45.8x64.8 cm)", ""), + ("C3_32.4_45.8", "C3 (32.4x45.8 cm)", ""), + ("C4_22.9_32.4", "C4 (22.9x32.4 cm)", ""), + ("C5_16.2_22.9", "C5 (16.2x22.9 cm)", ""), + ("C6_11.4_16.2", "C6 (11.4x16.2 cm)", ""), + ("C7_8.1_11.4", "C7 (8.1x11.4 cm)", ""), + ("C8_5.7_8.1", "C8 (5.7x8.1 cm)", ""), + ("C9_4.0_5.7", "C9 (4.0x5.7 cm)", ""), + ("C10_2.8_4.0", "C10 (2.8x4.0 cm)", ""), + + ("Letter_21.6_27.9", "Letter (21.6x27.9 cm)", ""), + ("Legal_21.6_35.6", "Legal (21.6x35.6 cm)", ""), + ("Legal junior_20.3_12.7", "Legal junior (20.3x12.7 cm)", ""), + ("Ledger_43.2_27.9", "Ledger (43.2x27.9 cm)", ""), + ("Tabloid_27.9_43.2", "Tabloid (27.9x43.2 cm)", ""), + + ("ANSI C_43.2_55.9", "ANSI C (43.2x55.9 cm)", ""), + ("ANSI D_55.9_86.4", "ANSI D (55.9x86.4 cm)", ""), + ("ANSI E_86.4_111.8", "ANSI E (86.4x111.8 cm)", ""), + + ("Arch A_22.9_30.5", "Arch A (22.9x30.5 cm)", ""), + ("Arch B_30.5_45.7", "Arch B (30.5x45.7 cm)", ""), + ("Arch C_45.7_61.0", "Arch C (45.7x61.0 cm)", ""), + ("Arch D_61.0_91.4", "Arch D (61.0x91.4 cm)", ""), + ("Arch E_91.4_121.9", "Arch E (91.4x121.9 cm)", ""), + ("Arch E1_76.2_106.7", "Arch E1 (76.2x106.7 cm)", ""), + ("Arch E2_66.0_96.5", "Arch E2 (66.0x96.5 cm)", ""), + ("Arch E3_68.6_99.1", "Arch E3 (68.6x99.1 cm)", ""), + ) -# minor update by Dealga McArdle, Thu July 7 2011. +def paper_enum_parse(idname): + tipo, dim_w, dim_h = idname.split("_") + return tipo, float(dim_w), float(dim_h) + + +paper_presets_data = {idname: paper_enum_parse(idname) + for idname, name, descr in paper_presets} + + +def update_settings_cb(self, context): + # annoying workaround for recursive call + if update_settings_cb.level == False: + update_settings_cb.level = True + pixels_from_print(self) + update_settings_cb.level = False + +update_settings_cb.level = False + + +class RenderPrintSertings(PropertyGroup): + unit_from = EnumProperty( + name="Set from", + description="Set from", + items=( + ("CM_TO_PIXELS", "CM -> Pixel", "Centermeters to Pixels"), + ("PIXELS_TO_CM", "Pixel -> CM", "Pixels to Centermeters") + ), + default="CM_TO_PIXELS", + ) + orientation = EnumProperty( + name="Page Orientation", + description="Set orientation", + items=( + ("Portrait", "Portrait", "Portrait"), + ("Landscape", "Landscape", "Landscape") + ), + default="Portrait", + update=update_settings_cb, + ) + preset = EnumProperty( + name="Select Preset", + description="Select from preset", + items=paper_presets, + default="custom_1_1", + update=update_settings_cb, + ) + dpi = IntProperty( + name="DPI", + description="Dots per Inch", + default=300, + min=72, max=1800, + update=update_settings_cb, + ) + width_cm = FloatProperty( + name="Width", + description="Width in CM", + default=5.0, + min=1.0, max=100000.0, + update=update_settings_cb, + ) + height_cm = FloatProperty( + name="Height", + description="Height in CM", + default=3.0, + min=1.0, max=100000.0, + update=update_settings_cb, + ) + width_px = IntProperty( + name="Pixel Width", + description="Pixel Width", + default=900, + min=4, max=10000, + update=update_settings_cb, + ) + height_px = IntProperty( + name="Pixel Height", + description="Pixel Height", + default=600, + min=4, max=10000, + update=update_settings_cb, + ) + + +def pixels_from_print(ps): + tipo, dim_w, dim_h = paper_presets_data[ps.preset] + + if ps.unit_from == "CM_TO_PIXELS": + if tipo == "custom": + dim_w = ps.width_cm + dim_h = ps.height_cm + ps.width_cm = dim_w + ps.height_cm = dim_h + elif tipo != "custom" and ps.orientation == "Landscape": + ps.width_cm = dim_h + ps.height_cm = dim_w + elif tipo != "custom" and ps.orientation == "Portrait": + ps.width_cm = dim_w + ps.height_cm = dim_h + + ps.width_px = math.ceil((ps.width_cm * ps.dpi) / 2.54) + ps.height_px = math.ceil((ps.height_cm * ps.dpi) / 2.54) + else: + if tipo != "custom" and ps.orientation == "Landscape": + ps.width_cm = dim_h + ps.height_cm = dim_w + ps.width_px = math.ceil((ps.width_cm * ps.dpi) / 2.54) + ps.height_px = math.ceil((ps.height_cm * ps.dpi) / 2.54) + elif tipo != "custom" and ps.orientation == "Portrait": + ps.width_cm = dim_w + ps.height_cm = dim_h + ps.width_px = math.ceil((ps.width_cm * ps.dpi) / 2.54) + ps.height_px = math.ceil((ps.height_cm * ps.dpi) / 2.54) -class RENDER_PT_Print(bpy.types.Panel): + ps.width_cm = (ps.width_px / ps.dpi) * 2.54 + ps.height_cm = (ps.height_px / ps.dpi) * 2.54 + + +class RENDER_PT_print(Panel): bl_label = "Render to Print" bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' bl_context = 'render' - - bpy.types.Scene.MyFrom = bpy.props.EnumProperty( - name="Set from", - description="Set from", - items=( - ("Cm--->Pixel", "Cm--->Pixel", "Cm--->Pixel"), - ("Pixel--->Cm", "Pixel--->Cm", "Pixel--->Cm") - ), - default="Cm--->Pixel") - - bpy.types.Scene.MyOrientation = bpy.props.EnumProperty( - name="Set orientation", - description="Set orientation", - items=( - ("Portrait", "Portrait", "Portrait"), - ("Landscape", "Landscape", "Landscape") - ), - default="Portrait") - - bpy.types.Scene.MyPreset = bpy.props.EnumProperty( - name="Select preset", - description="Select from preset", - items=( - ("custom_1_1", "custom", ""), - ("A0_84.1_118.9", "A0 (84.1x118.9 cm)", ""), - ("A1_59.4_84.1", "A1 (59.4x84.1 cm)", ""), - ("A2_42.0_59.4", "A2 (42.0x59.4 cm)", ""), - ("A3_29.7_42.0", "A3 (29.7 42.0 cm)", ""), - ("A4_21.0_29.7", "A4 (21.0x29.7 cm)", ""), - ("A5_14.8_21.0", "A5 (14.8x21.0 cm)", ""), - ("A6_10.5_14.8", "A6 (10.5x14.8 cm)", ""), - ("A7_7.4_10.5", "A7 (7.4x10.5 cm)", ""), - ("A8_5.2_7.4", "A8 (5.2x7.4 cm)", ""), - ("A9_3.7_5.2", "A9 (3.7x5.2 cm)", ""), - ("A10_2.6_3.7", "A10 (2.6x3.7 cm)", ""), - - ("B0_100.0_141.4", "B0 (100.0x141.4 cm)", ""), - ("B1_70.7_100.0", "B1 (70.7x100.0 cm)", ""), - ("B2_50.0_70.7", "B2 (50.0x70.7 cm)", ""), - ("B3_35.3_50.0", "B3 (35.3x50.0 cm)", ""), - ("B4_25.0_35.3", "B4 (25.0x35.3 cm)", ""), - ("B5_17.6_25.0", "B5 (17.6x25.0 cm)", ""), - ("B6_12.5_17.6", "B6 (12.5x17.6 cm)", ""), - ("B7_8.8_12.5", "B7 (8.8x12.5 cm)", ""), - ("B8_6.2_8.8", "B8 (6.2x8.8 cm)", ""), - ("B9_4.4_6.2", "B9 (4.4x6.2 cm)", ""), - ("B10_3.1_4.4", "B10 (3.1x4.4 cm)", ""), - - ("C0_91.7_129.7", "C0 (91.7x129.7 cm)", ""), - ("C1_64.8_91.7", "C1 (64.8x91.7 cm)", ""), - ("C2_45.8_64.8", "C2 (45.8x64.8 cm)", ""), - ("C3_32.4_45.8", "C3 (32.4x45.8 cm)", ""), - ("C4_22.9_32.4", "C4 (22.9x32.4 cm)", ""), - ("C5_16.2_22.9", "C5 (16.2x22.9 cm)", ""), - ("C6_11.4_16.2", "C6 (11.4x16.2 cm)", ""), - ("C7_8.1_11.4", "C7 (8.1x11.4 cm)", ""), - ("C8_5.7_8.1", "C8 (5.7x8.1 cm)", ""), - ("C9_4.0_5.7", "C9 (4.0x5.7 cm)", ""), - ("C10_2.8_4.0", "C10 (2.8x4.0 cm)", ""), - - ("Letter_21.6_27.9", "Letter (21.6x27.9 cm)", ""), - ("Legal_21.6_35.6", "Legal (21.6x35.6 cm)", ""), - ("Legal junior_20.3_12.7", "Legal junior (20.3x12.7 cm)", ""), - ("Ledger_43.2_27.9", "Ledger (43.2x27.9 cm)", ""), - ("Tabloid_27.9_43.2", "Tabloid (27.9x43.2 cm)", ""), - - ("ANSI C_43.2_55.9", "ANSI C (43.2x55.9 cm)", ""), - ("ANSI D_55.9_86.4", "ANSI D (55.9x86.4 cm)", ""), - ("ANSI E_86.4_111.8", "ANSI E (86.4x111.8 cm)", ""), - - ("Arch A_22.9_30.5", "Arch A (22.9x30.5 cm)", ""), - ("Arch B_30.5_45.7", "Arch B (30.5x45.7 cm)", ""), - ("Arch C_45.7_61.0", "Arch C (45.7x61.0 cm)", ""), - ("Arch D_61.0_91.4", "Arch D (61.0x91.4 cm)", ""), - ("Arch E_91.4_121.9", "Arch E (91.4x121.9 cm)", ""), - ("Arch E1_76.2_106.7", "Arch E1 (76.2x106.7 cm)", ""), - ("Arch E2_66.0_96.5", "Arch E2 (66.0x96.5 cm)", ""), - ("Arch E3_68.6_99.1", "Arch E3 (68.6x99.1 cm)", "") - ), - default="custom_1_1" - ) - - - - bpy.types.Scene.MyDPI = bpy.props.IntProperty( name="DPI", - description="Dots per Inch", - default=300, min=72, max=1800) - - bpy.types.Scene.MyWidth = bpy.props.FloatProperty( - name = "Width", - description = "Width", - default = 5.0, - min = 1.0, - max = 100000.0) - bpy.types.Scene.MyHeight = FloatProperty( - name = "Height", - description = "Height", - default = 3.0, - min = 1.0, - max = 100000.0) - - bpy.types.Scene.MyPWidth = IntProperty( - name = "Pixel Width", - description = "Pixel Width", - default = 900, - min = 4, - max = 10000) - bpy.types.Scene.MyPHeight = IntProperty( - name = "Pixel Height", - description = "Pixel Height", - default = 600, - min = 4, - max = 10000) - - bpy.types.Scene.MyWInch = StringProperty( - name = "Inch Width", - description = "", - default = "") - bpy.types.Scene.MyHInch = StringProperty( - name = "Inch Height", - description = "", - default = "") - - - + def draw(self, context): - + layout = self.layout - scn = context.scene + scene = context.scene + ps = scene.print_settings row = layout.row(align=True) row1 = layout.row(align=True) @@ -183,137 +240,106 @@ row6 = layout.row(align=True) row7 = layout.row(align=True) col = layout.column(align=True) - - row.prop(scn, "MyFrom") - row1.prop(scn, "MyOrientation") - row2.prop(scn, "MyPreset") + + row.prop(ps, "unit_from") + row1.prop(ps, "orientation") + row2.prop(ps, "preset") col.separator() - row3.prop(scn, "MyWidth") + row3.prop(ps, "width_cm") row3.separator() - row3.prop(scn, "MyHeight") + row3.prop(ps, "height_cm") col.separator() - row4.prop(scn, "MyDPI") + row4.prop(ps, "dpi") col.separator() - row5.prop(scn, "MyPWidth") + row5.prop(ps, "width_px") row5.separator() - row5.prop(scn, "MyPHeight") + row5.prop(ps, "height_px") col.separator() - row6.prop(scn, "MyWInch") - row6.prop(scn, "MyHInch") - row6.active=False - row6.enabled=False + row6.label("Inch Width: %.2f" % (ps.width_cm / 2.54)) + row6.label("Inch Height: %.2f" % (ps.height_cm / 2.54)) col.separator() - - row7.operator("object.dop2r", text="SET !", icon="RENDER_STILL") - + + row7.operator("render.apply_size", icon="RENDER_STILL") + # this if else deals with hiding UI elements when logic demands it. - tipo,dim_w,dim_h = scn.MyPreset.split("_") + tipo = paper_presets_data[ps.preset][0] if tipo != "custom": - row.active=False - row.enabled=False + row.active = False + row.enabled = False - if scn.MyFrom == "Cm--->Pixel": - row5.active=False - row5.enabled=False - - if tipo=="custom": - row3.active=True - row3.enabled=True - row1.active=False - row1.enabled=False - elif tipo!="custom" and scn.MyOrientation=="Landscape": - row3.active=False - row3.enabled=False - row1.active=True - row1.enabled=True - elif tipo!="custom" and scn.MyOrientation=="Portrait": - row3.active=False - row3.enabled=False - row1.active=True - row1.enabled=True + if ps.unit_from == "CM_TO_PIXELS": + row5.active = False + row5.enabled = False + + if tipo == "custom": + row3.active = True + row3.enabled = True + row1.active = False + row1.enabled = False + elif tipo != "custom" and ps.orientation == "Landscape": + row3.active = False + row3.enabled = False + row1.active = True + row1.enabled = True + elif tipo != "custom" and ps.orientation == "Portrait": + row3.active = False + row3.enabled = False + row1.active = True + row1.enabled = True else: - row3.active=False - row3.enabled=False + row3.active = False + row3.enabled = False - if tipo=="custom": - row1.active=False - row1.enabled=False - elif tipo!="custom" and scn.MyOrientation=="Landscape": - row1.active=True - row1.enabled=True - row5.active=False - row5.enabled=False - elif tipo!="custom" and scn.MyOrientation=="Portrait": - row1.active=True - row1.enabled=True - row5.active=False - row5.enabled=False - - -class OBJECT_OT_DoP2R(bpy.types.Operator): - bl_idname = "object.dop2r" - bl_label = "Run P2R" + if tipo == "custom": + row1.active = False + row1.enabled = False + elif tipo != "custom" and ps.orientation == "Landscape": + row1.active = True + row1.enabled = True + row5.active = False + row5.enabled = False + elif tipo != "custom" and ps.orientation == "Portrait": + row1.active = True + row1.enabled = True + row5.active = False + row5.enabled = False + + +class RENDER_OT_apply_size(Operator): + bl_idname = "render.apply_size" + bl_label = "Apply Print to Render" bl_description = "Set the render dimension" - - # COMPAT_ENGINES = {'BLENDER_RENDER'} def execute(self, context): - - scn = context.scene - rnd = bpy.context.scene.render - #set render resolution - - tipo,dim_w,dim_h = scn.MyPreset.split("_") - if scn.MyFrom == "Cm--->Pixel": - if tipo=="custom": - dim_w=scn.MyWidth - dim_h=scn.MyHeight - scn.MyWidth=float(dim_w) - scn.MyHeight=float(dim_h) - elif tipo!="custom" and scn.MyOrientation=="Landscape": - scn.MyWidth=float(dim_h) - scn.MyHeight=float(dim_w) - elif tipo!="custom" and scn.MyOrientation=="Portrait": - scn.MyWidth=float(dim_w) - scn.MyHeight=float(dim_h) - scn.MyPWidth=math.ceil((scn.MyWidth*scn.MyDPI)/2.54) - scn.MyPHeight=math.ceil((scn.MyHeight*scn.MyDPI)/2.54) - else: - if tipo!="custom" and scn.MyOrientation=="Landscape": - scn.MyWidth=float(dim_h) - scn.MyHeight=float(dim_w) - scn.MyPWidth=math.ceil((scn.MyWidth*scn.MyDPI)/2.54) - scn.MyPHeight=math.ceil((scn.MyHeight*scn.MyDPI)/2.54) - elif tipo!="custom" and scn.MyOrientation=="Portrait": - scn.MyWidth=float(dim_w) - scn.MyHeight=float(dim_h) - scn.MyPWidth=math.ceil((scn.MyWidth*scn.MyDPI)/2.54) - scn.MyPHeight=math.ceil((scn.MyHeight*scn.MyDPI)/2.54) - - scn.MyWidth=float(scn.MyPWidth/scn.MyDPI)*2.54 - scn.MyHeight=float(scn.MyPHeight/scn.MyDPI)*2.54 - - scn.MyWInch="%.2f" % (scn.MyWidth/2.54) - scn.MyHInch="%.2f" % (scn.MyHeight/2.54) - rnd.resolution_x=scn.MyPWidth - rnd.resolution_y=scn.MyPHeight + scene = context.scene + ps = scene.print_settings + + pixels_from_print(ps) + + render = scene.render + render.resolution_x = ps.width_px + render.resolution_y = ps.height_px - # bpy.ops.render.render(scene="scn") return {'FINISHED'} def register(): - bpy.utils.register_class(OBJECT_OT_DoP2R) - bpy.utils.register_class(RENDER_PT_Print) + bpy.utils.register_class(RENDER_OT_apply_size) + bpy.utils.register_class(RENDER_PT_print) + bpy.utils.register_class(RenderPrintSertings) + + Scene.print_settings = PointerProperty(type=RenderPrintSertings) def unregister(): - bpy.utils.unregister_class(OBJECT_OT_DoP2R) - bpy.utils.unregister_class(RENDER_PT_Print) + bpy.utils.unregister_class(RENDER_OT_apply_size) + bpy.utils.unregister_class(RENDER_PT_print) + bpy.utils.unregister_class(RenderPrintSertings) + del Scene.print_settings if __name__ == "__main__": diff -Nru blender-2.61/release/scripts/addons_contrib/space_view3d_add_surround_cameras.py blender-2.62/release/scripts/addons_contrib/space_view3d_add_surround_cameras.py --- blender-2.61/release/scripts/addons_contrib/space_view3d_add_surround_cameras.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/space_view3d_add_surround_cameras.py 2012-02-15 19:43:59.000000000 +0000 @@ -24,7 +24,6 @@ 'wiki_url': "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/3D_interaction/Surround_Projection_Tools", 'version': (0,1,2), 'blender': (2, 6, 0), - 'api': 41769, 'category': '3D View' } @@ -34,6 +33,8 @@ from math import pi import re +CAMERA_ORIGIN_NAME = "CameraOrigin" + # property for how many screens to add bpy.types.WindowManager.num_surround_screens = IntProperty( name="Number of screens", @@ -98,22 +99,16 @@ def execute(self, context): + scene = context.scene numScreens = context.window_manager.num_surround_screens # add an empty for the camera origin if not already present - originExists = False - for object in bpy.data.objects: - if object.name == "CameraOrigin": - bpy.ops.object.select_name(name="CameraOrigin") - origin = context.active_object - originExists = True - break - - if not originExists: + obj_origin = scene.objects.get(CAMERA_ORIGIN_NAME) + if not obj_origin: bpy.ops.object.add() - origin = context.active_object - origin.name = "CameraOrigin" - origin.location = context.scene.cursor_location + obj_origin = context.active_object + obj_origin.name = CAMERA_ORIGIN_NAME + obj_origin.location = scene.cursor_location for i in range(0,numScreens): @@ -136,9 +131,13 @@ cam.data.angle = (2*pi)/numScreens # make the parent of the camera the origin - cam.parent = origin + cam.parent = obj_origin + + # sel/activate origin + bpy.ops.object.select_all(action='DESELECT') + obj_origin.select = True + scene.objects.active = obj_origin - bpy.ops.object.select_name(name="CameraOrigin") context.window_manager.previous_num_surround_screens = numScreens return {'FINISHED'} @@ -220,12 +219,14 @@ return False def execute(self, context): - numScreens = context.window_manager.previous_num_surround_screens - for object in bpy.data.objects: - if object.type == 'CAMERA': - bpy.ops.object.select_name(name=object.name) - bpy.ops.object.delete() + scene = context.scene + + # XXX. shouldnt there be some less general way to do this? + # like check if they are the child of origin? - campbell + for obj in scene.objects[:]: + if obj.type == 'CAMERA': + scene.objects.unlink(obj) context.window_manager.previous_num_surround_screens = -1 return {'FINISHED'} diff -Nru blender-2.61/release/scripts/addons_contrib/space_view3d_align_tools.py blender-2.62/release/scripts/addons_contrib/space_view3d_align_tools.py --- blender-2.61/release/scripts/addons_contrib/space_view3d_align_tools.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/space_view3d_align_tools.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,342 +0,0 @@ -# AlingTools.py (c) 2009, 2010 Gabriel Beaudin (gabhead) -# -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the 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. -# -# ***** END GPL LICENCE BLOCK ***** - -bl_info = { - "name": "Align Tools", - "author": "Gabriel Beaudin (gabhead)", - "version": (0,1), - "blender": (2, 5, 7), - "api": 35853, - "location": "View3D > Tool Shelf > Align Tools Panel", - "description": "Align Selected Objects to Active Object", - "warning": "", - "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\ - "Scripts/3D interaction/Align_Tools", - "tracker_url": "https://projects.blender.org/tracker/index.php?"\ - "func=detail&aid==22389", - "category": "3D View"} - -"""Align Selected Objects""" - -import bpy - - -class AlignUi(bpy.types.Panel): - bl_space_type = 'VIEW_3D' - bl_region_type = 'TOOLS' - - bl_label = "Align Tools" - bl_context = "objectmode" - - def draw(self, context): - layout = self.layout - obj = context.object - - if obj != None: - row = layout.row() - row.label(text="Active object is: ", icon='OBJECT_DATA') - row = layout.row() - row.label(obj.name, icon='EDITMODE_HLT') - - layout.separator() - - col = layout.column() - col.label(text="Align Loc + Rot:", icon='MANIPUL') - - - col = layout.column(align=False) - col.operator("object.align",text="XYZ") - - col = layout.column() - col.label(text="Align Location:", icon='MAN_TRANS') - - col = layout.column_flow(columns=5,align=True) - col.operator("object.align_location_x",text="X") - col.operator("object.align_location_y",text="Y") - col.operator("object.align_location_z",text="Z") - col.operator("object.align_location_all",text="All") - - col = layout.column() - col.label(text="Align Rotation:", icon='MAN_ROT') - - col = layout.column_flow(columns=5,align=True) - col.operator("object.align_rotation_x",text="X") - col.operator("object.align_rotation_y",text="Y") - col.operator("object.align_rotation_z",text="Z") - col.operator("object.align_rotation_all",text="All") - - col = layout.column() - col.label(text="Align Scale:", icon='MAN_SCALE') - - col = layout.column_flow(columns=5,align=True) - col.operator("object.align_objects_scale_x",text="X") - col.operator("object.align_objects_scale_y",text="Y") - col.operator("object.align_objects_scale_z",text="Z") - col.operator("object.align_objects_scale_all",text="All") - - -##Align all -def main(context): - for i in bpy.context.selected_objects: - i.location = bpy.context.active_object.location - i.rotation_euler = bpy.context.active_object.rotation_euler - -## Align Location - -def LocAll(context): - for i in bpy.context.selected_objects: - i.location = bpy.context.active_object.location - -def LocX(context): - for i in bpy.context.selected_objects: - i.location.x = bpy.context.active_object.location.x - -def LocY(context): - for i in bpy.context.selected_objects: - i.location.y = bpy.context.active_object.location.y - -def LocZ(context): - for i in bpy.context.selected_objects: - i.location.z = bpy.context.active_object.location.z - -## Aling Rotation -def RotAll(context): - for i in bpy.context.selected_objects: - i.rotation_euler = bpy.context.active_object.rotation_euler - -def RotX(context): - for i in bpy.context.selected_objects: - i.rotation_euler.x = bpy.context.active_object.rotation_euler.x - -def RotY(context): - for i in bpy.context.selected_objects: - i.rotation_euler.y = bpy.context.active_object.rotation_euler.y - -def RotZ(context): - for i in bpy.context.selected_objects: - i.rotation_euler.z = bpy.context.active_object.rotation_euler.z -## Aling Scale -def ScaleAll(context): - for i in bpy.context.selected_objects: - i.scale = bpy.context.active_object.scale - -def ScaleX(context): - for i in bpy.context.selected_objects: - i.scale.x = bpy.context.active_object.scale.x - -def ScaleY(context): - for i in bpy.context.selected_objects: - i.scale.y = bpy.context.active_object.scale.y - -def ScaleZ(context): - for i in bpy.context.selected_objects: - i.scale.z = bpy.context.active_object.scale.z - -## Classes - -## Align All Rotation And Location -class AlignOperator(bpy.types.Operator): - '''''' - bl_idname = "object.align" - bl_label = "Align Selected To Active" - - @classmethod - def poll(cls, context): - return context.active_object != None - - def execute(self, context): - main(context) - return {'FINISHED'} - -#######################Align Location######################## -## Align LocationAll -class AlignLocationOperator(bpy.types.Operator): - '''''' - bl_idname = "object.align_location_all" - bl_label = "Align Selected Location To Active" - - @classmethod - def poll(cls, context): - return context.active_object != None - - def execute(self, context): - LocAll(context) - return {'FINISHED'} -## Align LocationX -class AlignLocationXOperator(bpy.types.Operator): - '''''' - bl_idname = "object.align_location_x" - bl_label = "Align Selected Location X To Active" - - @classmethod - def poll(cls, context): - return context.active_object != None - - def execute(self, context): - LocX(context) - return {'FINISHED'} -## Align LocationY -class AlignLocationYOperator(bpy.types.Operator): - '''''' - bl_idname = "object.align_location_y" - bl_label = "Align Selected Location Y To Active" - - @classmethod - def poll(cls, context): - return context.active_object != None - - def execute(self, context): - LocY(context) - return {'FINISHED'} -## Align LocationZ -class AlignLocationZOperator(bpy.types.Operator): - '''''' - bl_idname = "object.align_location_z" - bl_label = "Align Selected Location Z To Active" - - @classmethod - def poll(cls, context): - return context.active_object != None - - def execute(self, context): - LocZ(context) - return {'FINISHED'} - -#######################Align Rotation######################## -## Align RotationAll -class AlignRotationOperator(bpy.types.Operator): - '''''' - bl_idname = "object.align_rotation_all" - bl_label = "Align Selected Rotation To Active" - - @classmethod - def poll(cls, context): - return context.active_object != None - - def execute(self, context): - RotAll(context) - return {'FINISHED'} -## Align RotationX -class AlignRotationXOperator(bpy.types.Operator): - '''''' - bl_idname = "object.align_rotation_x" - bl_label = "Align Selected Rotation X To Active" - - @classmethod - def poll(cls, context): - return context.active_object != None - - def execute(self, context): - RotX(context) - return {'FINISHED'} -## Align RotationY -class AlignRotationYOperator(bpy.types.Operator): - '''''' - bl_idname = "object.align_rotation_y" - bl_label = "Align Selected Rotation Y To Active" - - @classmethod - def poll(cls, context): - return context.active_object != None - - def execute(self, context): - RotY(context) - return {'FINISHED'} -## Align RotationZ -class AlignRotationZOperator(bpy.types.Operator): - '''''' - bl_idname = "object.align_rotation_z" - bl_label = "Align Selected Rotation Z To Active" - - @classmethod - def poll(cls, context): - return context.active_object != None - - def execute(self, context): - RotZ(context) - return {'FINISHED'} -#######################Align Scale######################## -## Scale All -class AlignScaleOperator(bpy.types.Operator): - '''''' - bl_idname = "object.align_objects_scale_all" - bl_label = "Align Selected Scale To Active" - - @classmethod - def poll(cls, context): - return context.active_object != None - - def execute(self, context): - ScaleAll(context) - return {'FINISHED'} -## Align ScaleX -class AlignScaleXOperator(bpy.types.Operator): - '''''' - bl_idname = "object.align_objects_scale_x" - bl_label = "Align Selected Scale X To Active" - - @classmethod - def poll(cls, context): - return context.active_object != None - - def execute(self, context): - ScaleX(context) - return {'FINISHED'} -## Align ScaleY -class AlignScaleYOperator(bpy.types.Operator): - '''''' - bl_idname = "object.align_objects_scale_y" - bl_label = "Align Selected Scale Y To Active" - - @classmethod - def poll(cls, context): - return context.active_object != None - - def execute(self, context): - ScaleY(context) - return {'FINISHED'} -## Align ScaleZ -class AlignScaleZOperator(bpy.types.Operator): - '''''' - bl_idname = "object.align_objects_scale_z" - bl_label = "Align Selected Scale Z To Active" - - @classmethod - def poll(cls, context): - return context.active_object != None - - def execute(self, context): - ScaleZ(context) - return {'FINISHED'} - -## registring -def register(): - bpy.utils.register_module(__name__) - - pass - -def unregister(): - bpy.utils.unregister_module(__name__) - - pass - -if __name__ == "__main__": - register() diff -Nru blender-2.61/release/scripts/addons_contrib/space_view3d_enhanced_3d_cursor.py blender-2.62/release/scripts/addons_contrib/space_view3d_enhanced_3d_cursor.py --- blender-2.61/release/scripts/addons_contrib/space_view3d_enhanced_3d_cursor.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/space_view3d_enhanced_3d_cursor.py 2012-02-15 19:43:59.000000000 +0000 @@ -21,7 +21,7 @@ "name": "Enhanced 3D Cursor", "description": "Cursor history and bookmarks; drag/snap cursor.", "author": "dairin0d", - "version": (2, 8, 0), + "version": (2, 8, 1), "blender": (2, 6, 0), "api": 35853, # just copied from some Blender 2.59 script # 31236 ? "location": "View3D > Action mouse; F10; Properties panel", @@ -599,7 +599,11 @@ sys_matrix = self.csu.get_matrix() - view_dir = sys_matrix.inverted().to_3x3() * view_dir + try: + view_dir = sys_matrix.inverted().to_3x3() * view_dir + except: + # this is some degenerate system + pass view_dir.normalize() rot = Matrix.Rotation(offset, 3, view_dir) @@ -637,7 +641,11 @@ def rotate_matrix(self, matrix): sys_matrix = self.csu.get_matrix() - matrix = sys_matrix.inverted() * matrix + try: + matrix = sys_matrix.inverted() * matrix + except: + # this is some degenerate system + pass # Blender's order of rotation [in local axes] rotation_order = [2, 1, 0] @@ -687,7 +695,11 @@ def scale_matrix(self, matrix): sys_matrix = self.csu.get_matrix() - matrix = sys_matrix.inverted() * matrix + try: + matrix = sys_matrix.inverted() * matrix + except: + # this is some degenerate system + pass for i in range(3): sys_matrix[i] *= self.scales[i] @@ -735,7 +747,11 @@ pivot = self.csu.get_pivot_name(raw=force_pivot) p = self.csu.get_origin(relative=False, pivot=pivot) m = self.csu.get_matrix() - p = m.inverted() * p + try: + p = m.inverted() * p + except: + # this is some degenerate system + pass for i in range(3): self.set_axis_input(i, str(p[i])) elif self.transform_mode == 'ROTATE': @@ -748,7 +764,7 @@ def get_axes_values(self, as_string=False): if self.transform_mode == 'MOVE': localmat = CursorDynamicSettings.local_matrix - raw_axes = localmat[3] + raw_axes = localmat.translation elif self.transform_mode == 'ROTATE': raw_axes = Vector(self.angles) * (180.0 / math.pi) elif self.transform_mode == 'SCALE': @@ -884,7 +900,7 @@ sys_matrix = self.csu.get_matrix() if tfm_opts.use_relative_coords: - sys_matrix[3] = initial_matrix[3].copy() + sys_matrix.translation = initial_matrix.translation.copy() sys_origin = sys_matrix.to_translation() dest_point = self.particles[0].get_location() @@ -923,7 +939,11 @@ if settings.draw_guides: p0 = dest_point - p00 = sys_matrix.inverted() * p0 + try: + p00 = sys_matrix.inverted() * p0 + except: + # this is some degenerate system + p00 = p0.copy() axes_line_params = [ (Vector((0, p00.y, p00.z)), (1, 0, 0)), @@ -1349,14 +1369,10 @@ self.set_location(self.initial_pos) def get_location(self): - return self.v3d.cursor_location.copy() + return get_cursor_location(v3d=self.v3d) def set_location(self, value): - # !!! ATTENTION !!! - # Accessing scene.cursor_location is SLOW - # (well, at least assigning to it). - # Accessing v3d.cursor_location is fast. - self.v3d.cursor_location = Vector(value).to_3d() + set_cursor_location(Vector(value), v3d=self.v3d) def get_rotation(self): return Quaternion() @@ -1536,7 +1552,7 @@ elif context_mode == 'POSE': active_bone = active_object.data.bones.active if active_bone: - active_element = active_bone.matrix_local[3].to_3d() + active_element = active_bone.matrix_local.translation.to_3d() active_element = active_object.\ matrix_world * active_element @@ -1552,7 +1568,7 @@ parents.add(bone) for bone in parents: - positions.append(bone.matrix_local[3].to_3d()) + positions.append(bone.matrix_local.translation.to_3d()) else: for spline in active_object.data.splines: for point in spline.bezier_points: @@ -1638,8 +1654,8 @@ matrix_world.to_translation() # These are equivalent (though scene's is slower) - #cursor_pos = scene.cursor_location - cursor_pos = space_data.cursor_location + #cursor_pos = get_cursor_location(scene=scene) + cursor_pos = get_cursor_location(v3d=space_data) #elif area_type == 'IMAGE_EDITOR': # currently there is no way to get UV editor's @@ -2056,7 +2072,7 @@ else: return obj.matrix_world.to_translation() elif v3d.lock_cursor: - return v3d.cursor_location.copy() + return get_cursor_location(v3d=v3d) else: return rv3d.view_location.copy() @@ -2072,16 +2088,19 @@ if rv3d.view_perspective == 'CAMERA': d = self.get_direction() - v3d.camera.matrix_world[3][:3] = pos - d * rv3d.view_distance + v3d.camera.matrix_world.translation[:3] = pos - d * rv3d.view_distance else: if v3d.lock_object: obj, bone = self._get_lock_obj_bone() if bone: - bone.matrix[3][:3] = obj.matrix_world.inverted() * pos + try: + bone.matrix.translation[:3] = obj.matrix_world.inverted() * pos + except: + # this is some degenerate object + bone.matrix.translation[:3] = pos else: - obj.matrix_world[3][:3] = pos + obj.matrix_world.translation[:3] = pos elif v3d.lock_cursor: - #v3d.cursor_location = pos set_cursor_location(pos, v3d=v3d) else: rv3d.view_location = pos @@ -2116,7 +2135,7 @@ def get_matrix(self): m = self.get_rotation().to_matrix() m.resize_4x4() - m[3][:3] = self.get_viewpoint() + m.translation[:3] = self.get_viewpoint() return m def get_point(self, xy, pos): @@ -2217,7 +2236,7 @@ sys_matrix = csu.get_matrix() if use_relative_coords: - sys_matrix[3] = initial_matrix[3].copy() + sys_matrix.translation = initial_matrix.translation.copy() # Axes of freedom and line/plane parameters start = Vector(((0 if v is None else v) for v in axes_coords)) @@ -2276,8 +2295,13 @@ else: pos = orig_obj.matrix_world.to_translation() - set_stick_obj(csu.tou.scene, orig_obj.name, - orig_obj.matrix_world.inverted() * pos) + try: + local_pos = orig_obj.matrix_world.inverted() * pos + except: + # this is some degenerate object + local_pos = pos + + set_stick_obj(csu.tou.scene, orig_obj.name, local_pos) modify_Surface = modify_Surface and \ (snap_type != 'VOLUME') and (not use_object_centers) @@ -2320,7 +2344,11 @@ pos = i_p[1] #end if do_raycast - sys_matrix_inv = sys_matrix.inverted() + try: + sys_matrix_inv = sys_matrix.inverted() + except: + # this is some degenerate system + sys_matrix_inv = Matrix() _pos = sys_matrix_inv * pos @@ -2421,7 +2449,11 @@ m = obj.matrix_world if is_local: sys_matrix = m.copy() - sys_matrix_inv = sys_matrix.inverted() + try: + sys_matrix_inv = sys_matrix.inverted() + except: + # this is some degenerate system + sys_matrix_inv = Matrix() m_combined = sys_matrix_inv * m bbox = [None, None] @@ -2452,7 +2484,7 @@ m[0][:3] = sys_matrix3 * Vector((half[0], 0, 0)) m[1][:3] = sys_matrix3 * Vector((0, half[1], 0)) m[2][:3] = sys_matrix3 * Vector((0, 0, half[2])) - m[3][:3] = sys_matrix * (bbox[0] + half) + m.translation[:3] = sys_matrix * (bbox[0] + half) self.bbox_obj.matrix_world = m return self.bbox_obj @@ -2496,7 +2528,11 @@ continue m = obj.matrix_world.copy() - mi = m.inverted() + try: + mi = m.inverted() + except: + # this is some degenerate object + continue la = mi * a lb = mi * b @@ -2570,7 +2606,11 @@ sys_matrix_key = list(c for v in sys_matrix for c in v) sys_matrix_key.append(self.editmode) sys_matrix = sys_matrix.to_4x4() - sys_matrix_inv = sys_matrix.inverted() + try: + sys_matrix_inv = sys_matrix.inverted() + except: + # this is some degenerate system + return None if self.sys_matrix_key != sys_matrix_key: self.bbox_cache.clear() @@ -2707,7 +2747,7 @@ matrix[0][:3] = t1 matrix[1][:3] = t2 matrix[2][:3] = n - matrix[3][:3] = p + matrix.translation[:3] = p return (matrix, face_id, obj, orig_obj) @@ -3147,9 +3187,8 @@ pos = history.get_pos() if pos is not None: - cursor_pos = scene.cursor_location.copy() + cursor_pos = get_cursor_location(scene=scene) if pos != cursor_pos: - #scene.cursor_location = pos.copy() set_cursor_location(pos, scene=scene) if (history.current_id == 0) and (history.last_id <= 1): @@ -3225,7 +3264,7 @@ bgl.glColor4f(1.0, 0.75, 0.5, 1.0) bgl.glVertex3f(p[0], p[1], p[2]) - p = context.scene.cursor_location.copy() + p = get_cursor_location(scene=scene) bgl.glColor4f(1.0, 1.0, 0.25, 1.0) bgl.glVertex3f(p[0], p[1], p[2]) @@ -3276,7 +3315,7 @@ bookmark = library.bookmarks.add(name=self.name) - cusor_pos = context.scene.cursor_location.copy() + cusor_pos = get_cursor_location(scene=context.scene) try: bookmark.pos = library.convert_from_abs(cusor_pos, True) @@ -3323,7 +3362,7 @@ if not bookmark: return {'CANCELLED'} - cusor_pos = context.scene.cursor_location.copy() + cusor_pos = get_cursor_location(scene=context.scene) try: bookmark.pos = library.convert_from_abs(cusor_pos, True) @@ -3356,7 +3395,6 @@ try: bookmark_pos = library.convert_to_abs(bookmark.pos, True) - #context.scene.cursor_location = bookmark_pos.copy() set_cursor_location(bookmark_pos, scene=context.scene) except Exception as exc: self.report('ERROR_INVALID_CONTEXT', exc.args[0]) @@ -3385,12 +3423,11 @@ if not bookmark: return {'CANCELLED'} - cusor_pos = context.scene.cursor_location.copy() + cusor_pos = get_cursor_location(scene=context.scene) try: bookmark_pos = library.convert_to_abs(bookmark.pos, True) - #context.scene.cursor_location = bookmark_pos.copy() set_cursor_location(bookmark_pos, scene=context.scene) bookmark.pos = library.convert_from_abs(cusor_pos, True, @@ -3505,7 +3542,7 @@ if self.offset: # history? or keep separate for each scene? if not use_history: - csu.source_pos = csu.tou.scene.cursor_location.copy() + csu.source_pos = get_cursor_location(scene=csu.tou.scene) else: settings = find_settings() history = settings.history @@ -3564,7 +3601,12 @@ matrix = self.get_matrix(use_history, warn, **kwargs) if not matrix: return None - return matrix.inverted() * pos + + try: + return matrix.inverted() * pos + except: + # this is some degenerate object + return Vector() def draw_bookmark(self, context): r = context.region @@ -3900,7 +3942,6 @@ self.matrix = self.csu.get_matrix() pos = self.matrix * self.pos - #scene.cursor_location = pos set_cursor_location(pos, scene=context.scene) return {'FINISHED'} @@ -3908,14 +3949,18 @@ def invoke(self, context, event): scene = context.scene - cursor_pos = scene.cursor_location.copy() + cursor_pos = get_cursor_location(scene=scene) particles, self.csu = gather_particles(context=context) self.csu.source_pos = cursor_pos self.matrix = self.csu.get_matrix() - self.pos = self.matrix.inverted() * cursor_pos + try: + self.pos = self.matrix.inverted() * cursor_pos + except: + # this is some degenerate system + self.pos = Vector() wm = context.window_manager return wm.invoke_props_dialog(self, width=160) @@ -4031,7 +4076,7 @@ last_locations = {} for scene in bpy.data.scenes: - curr_pos = scene.cursor_location.copy() + curr_pos = get_cursor_location(scene=scene) last_locations[scene.name] = curr_pos @@ -4056,7 +4101,7 @@ break if v3d is not None: - curr_pos = v3d.cursor_location.copy() + curr_pos = get_cursor_location(v3d=v3d) last_locations[scene.name] = curr_pos @@ -4164,7 +4209,7 @@ if not isinstance(orient, Matrix): orient = orient.to_matrix() m = orient.to_4x4() - m[3] = pos.to_4d() + m.translation = pos.to_3d() return m def angle_axis_to_quat(angle, axis): @@ -4636,17 +4681,29 @@ obj = scene.objects[name] pos = settings_scene.stick_obj_pos pos = obj.matrix_world * pos - #scene.cursor_location = pos context.space_data.cursor_location = pos except Exception as e: pass +def get_cursor_location(v3d=None, scene=None): + if v3d: + pos = v3d.cursor_location + elif scene: + pos = scene.cursor_location + + return pos.copy() + def set_cursor_location(pos, v3d=None, scene=None): + pos = pos.to_3d().copy() + if v3d: - v3d.cursor_location = pos.to_3d() scene = bpy.context.scene + # Accessing scene.cursor_location is SLOW + # (well, at least assigning to it). + # Accessing v3d.cursor_location is fast. + v3d.cursor_location = pos elif scene: - scene.cursor_location = pos.to_3d() + scene.cursor_location = pos set_stick_obj(scene, None) diff -Nru blender-2.61/release/scripts/addons_contrib/space_view3d_game_props_visualiser.py blender-2.62/release/scripts/addons_contrib/space_view3d_game_props_visualiser.py --- blender-2.61/release/scripts/addons_contrib/space_view3d_game_props_visualiser.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/space_view3d_game_props_visualiser.py 2012-02-15 19:43:59.000000000 +0000 @@ -24,7 +24,6 @@ 'author': 'Bartius Crouch/Vilem Novak', 'version': (2,5), 'blender': (2, 5, 3), - 'api': 31667, 'location': 'View3D > Properties panel > Display tab', 'description': 'Display the game properties next to selected objects '\ 'in the 3d-view', diff -Nru blender-2.61/release/scripts/addons_contrib/space_view3d_index_visualiser.py blender-2.62/release/scripts/addons_contrib/space_view3d_index_visualiser.py --- blender-2.61/release/scripts/addons_contrib/space_view3d_index_visualiser.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/space_view3d_index_visualiser.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,261 +0,0 @@ -# ##### BEGIN GPL LICENSE BLOCK ##### -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the 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. -# -# ##### END GPL LICENSE BLOCK ##### - -# - -bl_info = { - 'name': 'Index Visualiser', - 'author': 'Bartius Crouch', - 'version': (2, 6, 12), - 'blender': (2, 6, 0), - 'api': 42181, - 'location': 'View3D > Properties panel > Mesh Display tab', - 'warning': '', # used for warning icon and text in addons panel - 'description': 'Display the indices of vertices, edges and faces '\ - 'in the 3d-view', - 'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.5/Py/'\ - 'Scripts/3D_interaction/Index_Visualiser', - 'tracker_url': 'http://projects.blender.org/tracker/index.php?'\ - 'func=detail&aid=21557', - 'category': '3D View'} - - -""" -Display the indices of vertices, edges and faces in the 3d-view. - -How to use: -- Select a mesh and go into editmode -- Display the properties panel (N-key) -- Go to the Mesh Display tab, it helps to fold the tabs above it -- Press the 'Visualise indices button' - -""" - -import bgl -import blf -import bpy -import mathutils - - -# calculate locations and store them as ID property in the mesh -def calc_callback(self, context): - # polling - if context.mode != "EDIT_MESH": - return - - # get screen information - mid_x = context.region.width/2.0 - mid_y = context.region.height/2.0 - width = context.region.width - height = context.region.height - - # get matrices - view_mat = context.space_data.region_3d.perspective_matrix - ob_mat = context.active_object.matrix_world - total_mat = view_mat * ob_mat - - # calculate location info - texts = [] - locs = [] - me = context.active_object.data - if bpy.context.scene.live_mode: - bpy.ops.object.editmode_toggle() - bpy.ops.object.editmode_toggle() - if bpy.context.scene.display_vert_index: - for v in me.vertices: - if not v.hide and \ - (v.select or not bpy.context.scene.display_sel_only): - locs.append([1.0, 1.0, 1.0, v.index, v.co.to_4d()]) - if bpy.context.scene.display_edge_index: - for ed in me.edges: - if not ed.hide and \ - (ed.select or not bpy.context.scene.display_sel_only): - v1, v2 = ed.vertices - v1 = me.vertices[v1].co.copy() - v2 = me.vertices[v2].co.copy() - loc = v1 + ((v2-v1)/2.0) - locs.append([1.0, 1.0, 0.0, ed.index, loc.to_4d()]) - if bpy.context.scene.display_face_index: - for f in me.faces: - if not f.hide and \ - (f.select or not bpy.context.scene.display_sel_only): - locs.append([1.0, 0.0, 0.5, f.index, f.center.to_4d()]) - - for loc in locs: - vec = total_mat * loc[4] # order is important - # dehomogenise - vec = mathutils.Vector((vec[0]/vec[3],vec[1]/vec[3],vec[2]/vec[3])) - x = int(mid_x + vec[0]*width/2.0) - y = int(mid_y + vec[1]*height/2.0) - texts+=[loc[0], loc[1], loc[2], loc[3], x, y, 0] - - # store as ID property in mesh - context.scene["IndexVisualiser"] = texts - - -# draw in 3d-view -def draw_callback(self, context): - # polling - if context.mode != "EDIT_MESH": - return - # retrieving ID property data - try: - texts = context.scene["IndexVisualiser"] - except: - return - if not texts: - return - - # draw - blf.size(0, 13, 72) - for i in range(0,len(texts),7): - bgl.glColor3f(texts[i], texts[i+1], texts[i+2]) - blf.position(0, texts[i+4], texts[i+5], texts[i+6]) - blf.draw(0, str(int(texts[i+3]))) - - -# operator -class IndexVisualiser(bpy.types.Operator): - bl_idname = "view3d.index_visualiser" - bl_label = "Index Visualiser" - bl_description = "Toggle the visualisation of indices" - - @classmethod - def poll(cls, context): - return context.mode=="EDIT_MESH" - - def __del__(self): - bpy.context.scene.display_indices = -1 - clear_properties(full=False) - - def modal(self, context, event): - if context.area: - context.area.tag_redraw() - - # removal of callbacks when operator is called again - if context.scene.display_indices == -1: - context.region.callback_remove(self.handle1) - context.region.callback_remove(self.handle2) - context.scene.display_indices = 0 - return {"CANCELLED"} - - return {"PASS_THROUGH"} - - def invoke(self, context, event): - if context.area.type == "VIEW_3D": - if context.scene.display_indices < 1: - # operator is called for the first time, start everything - context.scene.display_indices = 1 - context.window_manager.modal_handler_add(self) - self.handle1 = context.region.callback_add(calc_callback, - (self, context), "POST_VIEW") - self.handle2 = context.region.callback_add(draw_callback, - (self, context), "POST_PIXEL") - return {"RUNNING_MODAL"} - else: - # operator is called again, stop displaying - context.scene.display_indices = -1 - clear_properties(full=False) - return {'RUNNING_MODAL'} - else: - self.report({"WARNING"}, "View3D not found, can't run operator") - return {"CANCELLED"} - - -# properties used by the script -class InitProperties(bpy.types.Operator): - bl_idname = "view3d.init_index_visualiser" - bl_label = "init properties for index visualiser" - - def execute(self, context): - bpy.types.Scene.display_indices = bpy.props.IntProperty( - name="Display indices", - default=0) - context.scene.display_indices = 0 - bpy.types.Scene.display_sel_only = bpy.props.BoolProperty( - name="Selected only", - description="Only display indices of selected vertices/edges/faces", - default=True) - bpy.types.Scene.display_vert_index = bpy.props.BoolProperty( - name="Vertices", - description="Display vertex indices", default=True) - bpy.types.Scene.display_edge_index = bpy.props.BoolProperty( - name="Edges", - description="Display edge indices") - bpy.types.Scene.display_face_index = bpy.props.BoolProperty( - name="Faces", - description="Display face indices") - bpy.types.Scene.live_mode = bpy.props.BoolProperty( - name="Live", - description="Toggle live update of the selection, can be slow", - default=False) - return {'FINISHED'} - - -# removal of ID-properties when script is disabled -def clear_properties(full=True): - # can happen on reload - if bpy.context.scene is None: - return - - if "IndexVisualiser" in bpy.context.scene.keys(): - del bpy.context.scene["IndexVisualiser"] - if full: - props = ["display_indices", "display_sel_only", "display_vert_index", - "display_edge_index", "display_face_index", "live_mode"] - for p in props: - if p in bpy.types.Scene.bl_rna.properties: - exec("del bpy.types.Scene."+p) - if p in bpy.context.scene.keys(): - del bpy.context.scene[p] - - -# defining the panel -def menu_func(self, context): - self.layout.separator() - col = self.layout.column(align=True) - col.operator(IndexVisualiser.bl_idname, text="Visualise indices") - row = col.row(align=True) - row.active = (context.mode=="EDIT_MESH" and \ - context.scene.display_indices==1) - row.prop(context.scene, "display_vert_index", toggle=True) - row.prop(context.scene, "display_edge_index", toggle=True) - row.prop(context.scene, "display_face_index", toggle=True) - row = col.row(align=True) - row.active = (context.mode=="EDIT_MESH" and \ - context.scene.display_indices==1) - row.prop(context.scene, "display_sel_only") - row.prop(context.scene, "live_mode", toggle=False) - - -def register(): - bpy.utils.register_class(IndexVisualiser) - bpy.utils.register_class(InitProperties) - bpy.ops.view3d.init_index_visualiser() - bpy.types.VIEW3D_PT_view3d_meshdisplay.append(menu_func) - - -def unregister(): - bpy.utils.unregister_class(IndexVisualiser) - bpy.utils.unregister_class(InitProperties) - clear_properties() - bpy.types.VIEW3D_PT_view3d_meshdisplay.remove(menu_func) - - -if __name__ == "__main__": - register() diff -Nru blender-2.61/release/scripts/addons_contrib/space_view3d_manipulator_Menu.py blender-2.62/release/scripts/addons_contrib/space_view3d_manipulator_Menu.py --- blender-2.61/release/scripts/addons_contrib/space_view3d_manipulator_Menu.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/space_view3d_manipulator_Menu.py 2012-02-15 19:43:59.000000000 +0000 @@ -24,7 +24,6 @@ 'author': 'MichaelW', 'version': (1, 2 ,1), 'blender': (2, 6, 1), - "api": 41599, 'location': 'View3D > Ctrl Space ', 'description': 'Menu to change the manipulator type and/or disable it', 'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.5/Py/'\ @@ -64,29 +63,27 @@ layout = self.layout layout.operator_context = 'INVOKE_REGION_WIN' + props = layout.operator("view3d.enable_manipulator",text ='Translate', icon='MAN_TRANS') + props.translate = True + props = layout.operator("view3d.enable_manipulator",text ='Rotate', icon='MAN_ROT') + props.rotate = True - prop = layout.operator("view3d.enable_manipulator",text ='Translate', icon='MAN_TRANS') - prop.translate = True - - prop = layout.operator("view3d.enable_manipulator",text ='Rotate', icon='MAN_ROT') - prop.rotate = True - - prop = layout.operator("view3d.enable_manipulator",text ='Scale', icon='MAN_SCALE') - prop.scale = True + props = layout.operator("view3d.enable_manipulator",text ='Scale', icon='MAN_SCALE') + props.scale = True layout.separator() - prop = layout.operator("view3d.enable_manipulator",text ='Combo', icon='MAN_SCALE') - prop.scale = True - prop.rotate = True - prop.translate = True + props = layout.operator("view3d.enable_manipulator",text ='Combo', icon='MAN_SCALE') + props.scale = True + props.rotate = True + props.translate = True layout.separator() - prop = layout.operator("view3d.enable_manipulator",text ='Hide', icon='MAN_SCALE') - prop.scale = False - prop.rotate = False - prop.translate = False + props = layout.operator("view3d.enable_manipulator",text ='Hide', icon='MAN_SCALE') + props.scale = False + props.rotate = False + props.translate = False layout.separator() diff -Nru blender-2.61/release/scripts/addons_contrib/space_view3d_multiselect_menu.py blender-2.62/release/scripts/addons_contrib/space_view3d_multiselect_menu.py --- blender-2.61/release/scripts/addons_contrib/space_view3d_multiselect_menu.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/space_view3d_multiselect_menu.py 2012-02-15 19:43:59.000000000 +0000 @@ -0,0 +1,121 @@ +#view3d_multiselect_menu.py (c) 2011 Sean Olson (liquidApe) +#Original Script by: Mariano Hidalgo (uselessdreamer) +#contributed to by: Crouch, sim88, sam, meta-androcto, and Michael W +# +#Tested with r37702 +# +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the 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. +# +# ##### END GPL LICENSE BLOCK ##### + +bl_info = { + 'name': '3D View: Multiselect Menu', + 'author': 'Sean Olson (liquidApe)', + 'version': (1, 2), + 'blender': (2, 6, 1), + 'location': 'View3D > Mouse > Menu ', + 'warning':'', + 'description': 'Added options for multiselect to the ctrl-tab menu', + 'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.5/Py/' \ + 'Scripts/3D_interaction/multiselect_Menu', + 'tracker_url': 'https://projects.blender.org/tracker/index.php?' + 'func=detail&aid=22132', + 'category': '3D View'} + +import bpy + +# multiselect menu +class VIEW3D_MT_Multiselect_Menu(bpy.types.Menu): + bl_label = "MultiSelect Menu" + + def draw(self, context): + layout = self.layout + layout.operator_context = 'INVOKE_REGION_WIN' + + layout.separator() + prop = layout.operator("wm.context_set_value", text="Vertex Select", + icon='VERTEXSEL') + prop.value = "(True, False, False)" + prop.data_path = "tool_settings.mesh_select_mode" + + prop = layout.operator("wm.context_set_value", text="Edge Select", + icon='EDGESEL') + prop.value = "(False, True, False)" + prop.data_path = "tool_settings.mesh_select_mode" + + prop = layout.operator("wm.context_set_value", text="Face Select", + icon='FACESEL') + prop.value = "(False, False, True)" + prop.data_path = "tool_settings.mesh_select_mode" + layout.separator() + + prop = layout.operator("wm.context_set_value", + text="Vertex & Edge Select", icon='EDITMODE_HLT') + prop.value = "(True, True, False)" + prop.data_path = "tool_settings.mesh_select_mode" + + prop = layout.operator("wm.context_set_value", + text="Vertex & Face Select", icon='ORTHO') + prop.value = "(True, False, True)" + prop.data_path = "tool_settings.mesh_select_mode" + + prop = layout.operator("wm.context_set_value", + text="Edge & Face Select", icon='SNAP_FACE') + prop.value = "(False, True, True)" + prop.data_path = "tool_settings.mesh_select_mode" + layout.separator() + + prop = layout.operator("wm.context_set_value", + text="Vertex & Edge & Face Select", icon='SNAP_VOLUME') + prop.value = "(True, True, True)" + prop.data_path = "tool_settings.mesh_select_mode" + layout.separator() + +def register(): + bpy.utils.register_module(__name__) + + #add multiselect keybinding + km = bpy.context.window_manager.keyconfigs.active.keymaps['Mesh'] + kmi = km.keymap_items.new('wm.call_menu', 'TAB', 'PRESS', ctrl=True) + kmi.properties.name = "VIEW3D_MT_Multiselect_Menu" + + #remove default keybinding + km = bpy.context.window_manager.keyconfigs.active.keymaps['Mesh'] + for kmi in km.keymap_items: + if kmi.idname == 'wm.call_menu': + if kmi.properties.name == "VIEW3D_MT_edit_mesh_select_mode": + km.keymap_items.remove(kmi) + break + +def unregister(): + bpy.utils.unregister_module(__name__) + + #remove multiselect keybinding + km = bpy.context.window_manager.keyconfigs.active.keymaps['Mesh'] + for kmi in km.keymap_items: + if kmi.idname == 'wm.call_menu': + if kmi.properties.name == "VIEW3D_MT_Multiselect_Menu": + km.keymap_items.remove(kmi) + break + + #replace default keymap + km = bpy.context.window_manager.keyconfigs.active.keymaps['Mesh'] + kmi = km.keymap_items.new('wm.call_menu', 'TAB', 'PRESS', ctrl=True) + kmi.properties.name = "VIEW3D_MT_edit_mesh_select_mode" + +if __name__ == "__main__": + register() diff -Nru blender-2.61/release/scripts/addons_contrib/space_view3d_objects_panel.py blender-2.62/release/scripts/addons_contrib/space_view3d_objects_panel.py --- blender-2.61/release/scripts/addons_contrib/space_view3d_objects_panel.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/space_view3d_objects_panel.py 2012-02-15 19:43:59.000000000 +0000 @@ -21,7 +21,6 @@ "author": "Murat Egretli (Demohero)", "version": (1,2), "blender": (2, 6, 1), - "api": 41599, "location": "View3D > Toolbar", "description": "add objects(mesh, curve etc.) from Toolbar", "warning": "", diff -Nru blender-2.61/release/scripts/addons_contrib/space_view3d_simple_align.py blender-2.62/release/scripts/addons_contrib/space_view3d_simple_align.py --- blender-2.61/release/scripts/addons_contrib/space_view3d_simple_align.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/space_view3d_simple_align.py 2012-02-15 19:43:59.000000000 +0000 @@ -0,0 +1,341 @@ +# AlingTools.py (c) 2009, 2010 Gabriel Beaudin (gabhead) +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the 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. +# +# ***** END GPL LICENCE BLOCK ***** + +bl_info = { + "name": "Simple Align", + "author": "Gabriel Beaudin (gabhead)", + "version": (0,1), + "blender": (2, 6, 1), + "location": "View3D > Tool Shelf > Simple Align Panel", + "description": "Align Selected Objects to Active Object", + "warning": "", + "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\ + "Scripts/3D interaction/Align_Tools", + "tracker_url": "https://projects.blender.org/tracker/index.php?"\ + "func=detail&aid==22389", + "category": "3D View"} + +"""Align Selected Objects""" + +import bpy + + +class AlignUi(bpy.types.Panel): + bl_space_type = 'VIEW_3D' + bl_region_type = 'TOOLS' + + bl_label = "Simple Align" + bl_context = "objectmode" + + def draw(self, context): + layout = self.layout + obj = context.object + + if obj != None: + row = layout.row() + row.label(text="Active object is: ", icon='OBJECT_DATA') + row = layout.row() + row.label(obj.name, icon='EDITMODE_HLT') + + layout.separator() + + col = layout.column() + col.label(text="Align Loc + Rot:", icon='MANIPUL') + + + col = layout.column(align=False) + col.operator("object.align",text="XYZ") + + col = layout.column() + col.label(text="Align Location:", icon='MAN_TRANS') + + col = layout.column_flow(columns=5,align=True) + col.operator("object.align_location_x",text="X") + col.operator("object.align_location_y",text="Y") + col.operator("object.align_location_z",text="Z") + col.operator("object.align_location_all",text="All") + + col = layout.column() + col.label(text="Align Rotation:", icon='MAN_ROT') + + col = layout.column_flow(columns=5,align=True) + col.operator("object.align_rotation_x",text="X") + col.operator("object.align_rotation_y",text="Y") + col.operator("object.align_rotation_z",text="Z") + col.operator("object.align_rotation_all",text="All") + + col = layout.column() + col.label(text="Align Scale:", icon='MAN_SCALE') + + col = layout.column_flow(columns=5,align=True) + col.operator("object.align_objects_scale_x",text="X") + col.operator("object.align_objects_scale_y",text="Y") + col.operator("object.align_objects_scale_z",text="Z") + col.operator("object.align_objects_scale_all",text="All") + + +##Align all +def main(context): + for i in bpy.context.selected_objects: + i.location = bpy.context.active_object.location + i.rotation_euler = bpy.context.active_object.rotation_euler + +## Align Location + +def LocAll(context): + for i in bpy.context.selected_objects: + i.location = bpy.context.active_object.location + +def LocX(context): + for i in bpy.context.selected_objects: + i.location.x = bpy.context.active_object.location.x + +def LocY(context): + for i in bpy.context.selected_objects: + i.location.y = bpy.context.active_object.location.y + +def LocZ(context): + for i in bpy.context.selected_objects: + i.location.z = bpy.context.active_object.location.z + +## Aling Rotation +def RotAll(context): + for i in bpy.context.selected_objects: + i.rotation_euler = bpy.context.active_object.rotation_euler + +def RotX(context): + for i in bpy.context.selected_objects: + i.rotation_euler.x = bpy.context.active_object.rotation_euler.x + +def RotY(context): + for i in bpy.context.selected_objects: + i.rotation_euler.y = bpy.context.active_object.rotation_euler.y + +def RotZ(context): + for i in bpy.context.selected_objects: + i.rotation_euler.z = bpy.context.active_object.rotation_euler.z +## Aling Scale +def ScaleAll(context): + for i in bpy.context.selected_objects: + i.scale = bpy.context.active_object.scale + +def ScaleX(context): + for i in bpy.context.selected_objects: + i.scale.x = bpy.context.active_object.scale.x + +def ScaleY(context): + for i in bpy.context.selected_objects: + i.scale.y = bpy.context.active_object.scale.y + +def ScaleZ(context): + for i in bpy.context.selected_objects: + i.scale.z = bpy.context.active_object.scale.z + +## Classes + +## Align All Rotation And Location +class AlignOperator(bpy.types.Operator): + '''''' + bl_idname = "object.align" + bl_label = "Align Selected To Active" + + @classmethod + def poll(cls, context): + return context.active_object != None + + def execute(self, context): + main(context) + return {'FINISHED'} + +#######################Align Location######################## +## Align LocationAll +class AlignLocationOperator(bpy.types.Operator): + '''''' + bl_idname = "object.align_location_all" + bl_label = "Align Selected Location To Active" + + @classmethod + def poll(cls, context): + return context.active_object != None + + def execute(self, context): + LocAll(context) + return {'FINISHED'} +## Align LocationX +class AlignLocationXOperator(bpy.types.Operator): + '''''' + bl_idname = "object.align_location_x" + bl_label = "Align Selected Location X To Active" + + @classmethod + def poll(cls, context): + return context.active_object != None + + def execute(self, context): + LocX(context) + return {'FINISHED'} +## Align LocationY +class AlignLocationYOperator(bpy.types.Operator): + '''''' + bl_idname = "object.align_location_y" + bl_label = "Align Selected Location Y To Active" + + @classmethod + def poll(cls, context): + return context.active_object != None + + def execute(self, context): + LocY(context) + return {'FINISHED'} +## Align LocationZ +class AlignLocationZOperator(bpy.types.Operator): + '''''' + bl_idname = "object.align_location_z" + bl_label = "Align Selected Location Z To Active" + + @classmethod + def poll(cls, context): + return context.active_object != None + + def execute(self, context): + LocZ(context) + return {'FINISHED'} + +#######################Align Rotation######################## +## Align RotationAll +class AlignRotationOperator(bpy.types.Operator): + '''''' + bl_idname = "object.align_rotation_all" + bl_label = "Align Selected Rotation To Active" + + @classmethod + def poll(cls, context): + return context.active_object != None + + def execute(self, context): + RotAll(context) + return {'FINISHED'} +## Align RotationX +class AlignRotationXOperator(bpy.types.Operator): + '''''' + bl_idname = "object.align_rotation_x" + bl_label = "Align Selected Rotation X To Active" + + @classmethod + def poll(cls, context): + return context.active_object != None + + def execute(self, context): + RotX(context) + return {'FINISHED'} +## Align RotationY +class AlignRotationYOperator(bpy.types.Operator): + '''''' + bl_idname = "object.align_rotation_y" + bl_label = "Align Selected Rotation Y To Active" + + @classmethod + def poll(cls, context): + return context.active_object != None + + def execute(self, context): + RotY(context) + return {'FINISHED'} +## Align RotationZ +class AlignRotationZOperator(bpy.types.Operator): + '''''' + bl_idname = "object.align_rotation_z" + bl_label = "Align Selected Rotation Z To Active" + + @classmethod + def poll(cls, context): + return context.active_object != None + + def execute(self, context): + RotZ(context) + return {'FINISHED'} +#######################Align Scale######################## +## Scale All +class AlignScaleOperator(bpy.types.Operator): + '''''' + bl_idname = "object.align_objects_scale_all" + bl_label = "Align Selected Scale To Active" + + @classmethod + def poll(cls, context): + return context.active_object != None + + def execute(self, context): + ScaleAll(context) + return {'FINISHED'} +## Align ScaleX +class AlignScaleXOperator(bpy.types.Operator): + '''''' + bl_idname = "object.align_objects_scale_x" + bl_label = "Align Selected Scale X To Active" + + @classmethod + def poll(cls, context): + return context.active_object != None + + def execute(self, context): + ScaleX(context) + return {'FINISHED'} +## Align ScaleY +class AlignScaleYOperator(bpy.types.Operator): + '''''' + bl_idname = "object.align_objects_scale_y" + bl_label = "Align Selected Scale Y To Active" + + @classmethod + def poll(cls, context): + return context.active_object != None + + def execute(self, context): + ScaleY(context) + return {'FINISHED'} +## Align ScaleZ +class AlignScaleZOperator(bpy.types.Operator): + '''''' + bl_idname = "object.align_objects_scale_z" + bl_label = "Align Selected Scale Z To Active" + + @classmethod + def poll(cls, context): + return context.active_object != None + + def execute(self, context): + ScaleZ(context) + return {'FINISHED'} + +## registring +def register(): + bpy.utils.register_module(__name__) + + pass + +def unregister(): + bpy.utils.unregister_module(__name__) + + pass + +if __name__ == "__main__": + register() diff -Nru blender-2.61/release/scripts/addons_contrib/system_keyboard_svg.py blender-2.62/release/scripts/addons_contrib/system_keyboard_svg.py --- blender-2.61/release/scripts/addons_contrib/system_keyboard_svg.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/system_keyboard_svg.py 2012-02-15 19:43:59.000000000 +0000 @@ -27,7 +27,6 @@ "author": "Jbakker", "version": (0, 1), "blender": (2, 6, 0), - "api": 41875, "location": "", "description": "Save the hotkeys as a .svg file (search: Keyboard)", "warning": "may not work in recent svn", diff -Nru blender-2.61/release/scripts/addons_contrib/system_theme_manager.py blender-2.62/release/scripts/addons_contrib/system_theme_manager.py --- blender-2.61/release/scripts/addons_contrib/system_theme_manager.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/system_theme_manager.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,510 +0,0 @@ -# ##### BEGIN GPL LICENSE BLOCK ##### -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the 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. -# -# ##### END GPL LICENSE BLOCK ##### - -# - - -bl_info = { - 'name': "Theme manager", - 'author': "Bart Crouch", - 'version': (1, 4, 0), - 'blender': (2, 5, 9), - 'api': 39720, - 'location': "User Preferences > Themes > Header", - 'warning': "", - 'description': "Load or save a custom theme", - 'wiki_url': "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\ - "Scripts/System/Theme_manager", - 'tracker_url': "http://projects.blender.org/tracker/index.php?"\ - "func=detail&aid=26659", - 'category': 'System'} - - -import bpy -import gzip -from bpy_extras.io_utils import ExportHelper, ImportHelper -import os -import pickle -import shutil - - -# function to change the theme -def apply_theme(self, context): - theme = context.window_manager.theme_list - if theme == "internal_tm_42_default": - bpy.ops.ui.reset_default_theme() - print("Applied Default theme") - return - - match = False - for (sort_name, theme_name, author, version, filename) in \ - context.window_manager["theme_list_id"]: - if theme_name == theme: - match = True - break - if not match: - # should be impossible - print("Could not find theme(internal mismatch)") - return - else: - filepath = filename - - # load file - try: - file = gzip.open(filepath, mode='r') - dump = pickle.load(file) - file.close() - dump["info"]["script"] - except: - print("Could not read theme") - return - - # apply theme - theme = bpy.context.user_preferences.themes["Default"] - for ts, props in dump["values"].items(): - theme_struct = getattr(theme, ts) - for prop, val in props.items(): - if type(val) != type({}): - setattr(theme_struct, prop, val) - else: - # one level deeper - if type(prop) == type(1): - # collection property (bone color set) - prop_struct = theme_struct[prop] - else: - prop_struct = getattr(theme_struct, prop) - for subprop, subval in val.items(): - setattr(prop_struct, subprop, subval) - - # restore default values for miscellaneous items, before assigning - bpy.context.user_preferences.view.object_origin_size = 6 - bpy.context.user_preferences.view.mini_axis_size = 25 - bpy.context.user_preferences.view.mini_axis_brightness = 8 - bpy.context.user_preferences.view.manipulator_size = 15 - bpy.context.user_preferences.view.manipulator_handle_size = 25 - bpy.context.user_preferences.view.manipulator_hotspot = 14 - bpy.context.user_preferences.edit.sculpt_paint_overlay_color = \ - [0.0, 0.0, 0.0] - bpy.context.user_preferences.system.dpi = 72 - bpy.context.user_preferences.system.use_weight_color_range = False - color_range = bpy.context.user_preferences.system.weight_color_range - color_range.interpolation = 'LINEAR' - while len(color_range.elements) > 1: - color_range.elements.remove(color_range.elements[0]) - if len(color_range.elements) == 1: - color_range.elements[0].position = 1.0 - color_range.elements[0].color = [0.0, 1.0, 0.0, 0.0] - lights = bpy.context.user_preferences.system.solid_lights - light_settings = [{"diffuse_color":[0.8, 0.8, 0.8], - "direction":[-0.892, 0.3, 0.9], "specular_color":[0.5, 0.5, 0.5], - "use":True}, {"diffuse_color":[0.498, 0.5, 0.6], - "direction":[0.588, 0.460, 0.248], - "specular_color":[0.2, 0.2, 0.2], "use":True}, - {"diffuse_color":[0.798, 0.838, 1.0], - "direction":[0.216, -0.392, -0.216], - "specular_color":[0.066, 0.0, 0.0], "use":True}] - for i, light in enumerate(lights): - settings = light_settings[i] - for prop, value in settings.items(): - setattr(light, prop, value) - - # theme file created with script version >= 1.3 - if "misc" in dump: - for category, props in dump["misc"].items(): - category_struct = getattr(bpy.context.user_preferences, - category) - for prop_name, val in props.items(): - if type(val) != type({}): - # simple miscellaneous setting - setattr(category_struct, prop_name, val) - else: - structs = getattr(category_struct, prop_name) - for subkey, subval in val.items(): - if type(subkey) == type(1): - # solid_lights - struct = structs[subkey] - for subprop_name, subprop_val in \ - subval.items(): - setattr(struct, subprop_name, subprop_val) - else: - # weight paint color-range - if type(subval) != type({}): - setattr(structs, subkey, subval) - else: - elements = getattr(structs, subkey) - add_new = len(subval) - len(elements) - for i in range(add_new): - elements.new(i / len(subval)) - for i, element_prop in subval.items(): - for element_key, element_value in \ - element_prop.items(): - setattr(elements[i], element_key, - element_value) - - # report to user - author = dump["info"]["author"] - theme_name = dump["info"]["theme_name"] - print("Applied " + theme_name + " by " + author) - - -# create list for dynamic EnumProperty -def dynamic_list(self, context): - d_list = [('internal_tm_42_default', "Default", "Reset to the "\ - "default theme colors")] - if "theme_list_id" in context.window_manager: - for i, theme, author, version, path in \ - context.window_manager["theme_list_id"]: - if version: - version = " " + version - d_list.append((theme, theme + version + " by " + author, - "Apply " + theme + version)) - - return(d_list) - - -# return path of the folder where all themes are located -def get_paths(): - # locate theme preset folder - paths = bpy.utils.preset_paths("theme") - if not paths: - # theme preset folder doesn't exist, so create it - paths = [os.path.join(bpy.utils.user_resource('SCRIPTS'), "presets", - "theme")] - if not os.path.exists(paths[0]): - os.makedirs(paths[0]) - - return(paths) - - -# create list of all themes available -def load_presets(): - # find theme files - paths = get_paths() - theme_files = [] - for path in paths: - for root, dirs, files in os.walk(path): - for file in files: - if file.endswith(".blt"): - theme_files.append(os.path.join(root, file)) - - # read author and theme names - theme_list = [] - for filename in theme_files: - # load file - try: - file = gzip.open(filename, mode='r') - dump = pickle.load(file) - file.close() - author = dump["info"]["author"] - theme_name = dump["info"]["theme_name"] - sort_name = theme_name.lower() - # theme_version available if created with script version >= 1.4 - theme_version = dump["info"].get("theme_version", "") - theme_list.append([sort_name, theme_name, author, theme_version, - filename]) - except: - continue - theme_list.sort() - - # store list in window-manager - bpy.context.window_manager["theme_list_id"] = theme_list - try: - # check if EnumProp exists: overwrite might cause memory corruption - bpy.context.window_manager.theme_list - except: - # create EnumProp, because it doesn't exist yet - bpy.types.WindowManager.theme_list = bpy.props.EnumProperty(\ - name="Load Theme", - items=dynamic_list, - description="Load a theme", - update=apply_theme) - - -def unload_presets(): - # remove settings from window-manager - del bpy.context.window_manager["theme_list_id"] - try: - del bpy.types.WindowManager.theme_list - print('successfully removed theme_list enum property') - except: - pass - - -# install operator -class InstallTheme(bpy.types.Operator, ImportHelper): - bl_idname = "ui.install_theme" - bl_label = "Install new theme" - bl_description = "Install a new theme" - - filename_ext = ".blt" - filter_glob = bpy.props.StringProperty(default="*.blt", options={'HIDDEN'}) - - def execute(self, context): - # copy theme to presets folder - filename = os.path.basename(self.filepath) - try: - shutil.copyfile(self.filepath, - os.path.join(get_paths()[0], filename)) - except: - self.report({'ERROR'}, "Installing failed") - return{'CANCELLED'} - - # reload presets list - load_presets() - - # change active theme - try: - file = gzip.open(self.filepath, mode='r') - dump = pickle.load(file) - file.close() - theme = dump["info"]["theme_name"] - except: - self.report({"ERROR"}, "Installing succeeded, but could not read "\ - "theme") - return{'CANCELLED'} - context.window_manager.theme_list = theme - - return{'FINISHED'} - - -# save operator -class SaveTheme(bpy.types.Operator, ExportHelper): - bl_idname = "ui.save_theme" - bl_label = "Save Theme" - bl_description = "Save the current theme to a .blt file" - - filename_ext = ".blt" - filepath = bpy.props.StringProperty(\ - default=os.path.join(get_paths()[0], "untitled")) - filter_glob = bpy.props.StringProperty(default="*.blt", options={'HIDDEN'}) - author = bpy.props.StringProperty(name="Author", - default=bpy.context.user_preferences.system.author, - description="Name of the person who created the theme") - theme_name = bpy.props.StringProperty(name="Theme name", - default="", - description="Name of the theme") - version = bpy.props.StringProperty(name="Version", - default="", - description="Version number of the theme, eg: 1.0", - maxlen=8) - - def execute(self, context): - # create dictionary with all information - dump = {"info":{}, "misc":{}, "values":{}} - dump["info"]["script"] = bl_info['name'] - dump["info"]["script_version"] = bl_info['version'] - dump["info"]["version"] = bpy.app.version - dump["info"]["build_revision"] = bpy.app.build_revision - dump["info"]["author"] = self.author - dump["info"]["theme_name"] = self.theme_name - dump["info"]["theme_version"] = self.version - - # defaults - if not self.author: - dump["info"]["author"] = "Unknown" - if not self.theme_name: - dump["info"]["theme_name"] = "Custom theme" - - # get current theme settings - theme = bpy.context.user_preferences.themes["Default"] - theme_structs = [[ts.lower(), getattr(theme, ts.lower())] for ts in \ - bpy.types.Theme.bl_rna.properties['theme_area'].enum_items.keys()] - for name, ts in theme_structs: - dump["values"][name] = {} - if str(type(ts)) == "": - # bone color sets - for i, struct in enumerate(ts): - dump["values"][name][i] = {} - for prop in struct.bl_rna.properties: - if prop.identifier == "rna_type": - # not a setting, so skip - continue - val = getattr(ts[i], prop.identifier) - if str(type(val)) in ["", - ""]: - # array - dump["values"][name][i][prop.identifier] = [v \ - for v in val] - else: - # single value - dump["values"][name][i][prop.identifier] = val - continue - for prop in ts.bl_rna.properties: - if prop.identifier == "rna_type": - # not a setting, so skip - continue - val = getattr(ts, prop.identifier) - if prop.type != 'POINTER': - if str(type(val)) in ["", - ""]: - # array - dump["values"][name][prop.identifier] = [v for v in \ - val] - else: - # single value - dump["values"][name][prop.identifier] = val - else: - # one level deeper - dump["values"][name][prop.identifier] = {} - for subprop in val.bl_rna.properties: - if subprop.identifier == "rna_type": - # not a setting, so skip - continue - subval = getattr(val, subprop.identifier) - if subprop.type != 'POINTER': - if str(type(subval)) in [\ - "", - ""]: - # array - dump["values"][name][prop.identifier]\ - [subprop.identifier] = [v for v in subval] - else: - # single value - dump["values"][name][prop.identifier]\ - [subprop.identifier] = subval - - # get simple settings which are spread out over various sections - save_props = ["view.object_origin_size", "view.mini_axis_size", - "view.mini_axis_brightness", "view.manipulator_size", - "view.manipulator_handle_size", "view.manipulator_hotspot", - "edit.sculpt_paint_overlay_color", "system.dpi", - "system.use_weight_color_range"] - for property in save_props: - category, prop_name = property.split(".", 1) - if not dump["misc"].get(category, False): - dump["misc"][category] = {} - prop = getattr(getattr(bpy.context.user_preferences, category), - prop_name) - if str(type(prop)) in ["", - ""]: - prop = [val for val in prop] - dump["misc"][category][prop_name] = prop - - # solid_light settings - dump["misc"]["system"]["solid_lights"] = {} - for i, light in enumerate(bpy.context.user_preferences.system. - solid_lights): - dump["misc"]["system"]["solid_lights"][i] = {} - save_props = ["diffuse_color", "direction", "specular_color", - "use"] - for property in save_props: - prop = getattr(bpy.context.user_preferences.system.\ - solid_lights[i], property) - if str(type(prop)) in ["", - "", ""]: - prop = [val for val in prop] - dump["misc"]["system"]["solid_lights"][i][property] = prop - - # weight paint color-range settings - dump["misc"]["system"]["weight_color_range"] = {} - dump["misc"]["system"]["weight_color_range"]["interpolation"] = bpy.\ - context.user_preferences.system.weight_color_range.interpolation - dump["misc"]["system"]["weight_color_range"]["elements"] = {} - for i, element in enumerate(context.user_preferences.system.\ - weight_color_range.elements): - dump["misc"]["system"]["weight_color_range"]["elements"][i] = {} - dump["misc"]["system"]["weight_color_range"]["elements"][i]\ - ["position"] = bpy.context.user_preferences.system.\ - weight_color_range.elements[i].position - dump["misc"]["system"]["weight_color_range"]["elements"][i]\ - ["color"] = [c for c in bpy.context.user_preferences.system.\ - weight_color_range.elements[i].color] - - # save to file - filepath = self.filepath - filepath = bpy.path.ensure_ext(filepath, self.filename_ext) - file = gzip.open(filepath, mode='w') - pickle.dump(dump, file) - file.close() - load_presets() - context.window_manager.theme_list = dump["info"]["theme_name"] - - return{'FINISHED'} - - -# uninstall operator -class UninstallTheme(bpy.types.Operator): - bl_idname = "ui.uninstall_theme" - bl_label = "Uninstall theme" - bl_description = "Uninstall this theme preset" - - def execute(self, context): - theme = context.window_manager.theme_list - match = False - for (sort_name, theme_name, author, version, filename) in \ - context.window_manager["theme_list_id"]: - if theme_name == theme: - match = True - break - if not match: - # should be impossible - self.report({'ERROR'}, "Could not remove theme preset (internal "\ - "mismatch)") - return{'CANCELLED'} - else: - filepath = filename - - try: - os.remove(filepath) - except: - self.report({'ERROR'}, "Could not remove theme preset") - return{'CANCELLED'} - - # reload presets list and reset to default - load_presets() - bpy.ops.ui.reset_default_theme() - context.window_manager.theme_list = 'internal_tm_42_default' - - return{'FINISHED'} - - -# draw function for integration in header -def header_func(self, context): - if context.user_preferences.active_section == 'THEMES': - self.layout.separator() - row = self.layout.row(align=True) - row.prop(context.window_manager, "theme_list", text="") - row.operator("ui.install_theme", icon='ZOOMIN', text="") - row = row.row() - row.enabled = context.window_manager.theme_list != \ - 'internal_tm_42_default' - row.operator("ui.uninstall_theme", icon='X', text="") - self.layout.operator("ui.save_theme") - - -classes = [InstallTheme, - SaveTheme, - UninstallTheme] - - -def register(): - load_presets() - for c in classes: - bpy.utils.register_class(c) - bpy.types.USERPREF_HT_header.append(header_func) - - -def unregister(): - for c in classes: - bpy.utils.unregister_class(c) - bpy.types.USERPREF_HT_header.remove(header_func) - unload_presets() - - -if __name__ == "__main__": - register() diff -Nru blender-2.61/release/scripts/addons_contrib/text_editor_pasteall.py blender-2.62/release/scripts/addons_contrib/text_editor_pasteall.py --- blender-2.61/release/scripts/addons_contrib/text_editor_pasteall.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/text_editor_pasteall.py 2012-02-15 19:43:59.000000000 +0000 @@ -21,7 +21,6 @@ "author": "Dalai Felinto (dfelinto)", "version": (0,7), "blender": (2, 6, 0), - "api": 41374, "location": "Text editor > Properties panel", "description": "Send your selection or text to www.pasteall.org", "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\ diff -Nru blender-2.61/release/scripts/addons_contrib/wetted_mesh.py blender-2.62/release/scripts/addons_contrib/wetted_mesh.py --- blender-2.61/release/scripts/addons_contrib/wetted_mesh.py 2011-12-13 19:59:42.000000000 +0000 +++ blender-2.62/release/scripts/addons_contrib/wetted_mesh.py 2012-02-15 19:43:59.000000000 +0000 @@ -21,7 +21,6 @@ "author": "freejack", "version": (0, 2, 1), "blender": (2, 5, 8), - "api": 37699, "location": "View3D > Tool Shelf > Wetted Mesh Panel", "description": "Adds separated fluid, dry and wetted mesh for selected pair.", "warning": "", diff -Nru blender-2.61/release/scripts/modules/addon_utils.py blender-2.62/release/scripts/modules/addon_utils.py --- blender-2.61/release/scripts/modules/addon_utils.py 2011-12-13 19:43:30.000000000 +0000 +++ blender-2.62/release/scripts/modules/addon_utils.py 2012-02-15 19:27:47.000000000 +0000 @@ -38,17 +38,17 @@ def paths(): # RELEASE SCRIPTS: official scripts distributed in Blender releases - paths = _bpy.utils.script_paths("addons") + addon_paths = _bpy.utils.script_paths("addons") # CONTRIB SCRIPTS: good for testing but not official scripts yet # if folder addons_contrib/ exists, scripts in there will be loaded too - paths += _bpy.utils.script_paths("addons_contrib") + addon_paths += _bpy.utils.script_paths("addons_contrib") # EXTERN SCRIPTS: external projects scripts # if folder addons_extern/ exists, scripts in there will be loaded too - paths += _bpy.utils.script_paths("addons_extern") + addon_paths += _bpy.utils.script_paths("addons_extern") - return paths + return addon_paths def modules(module_cache): @@ -361,7 +361,6 @@ "author": "", "version": (), "blender": (), - "api": 0, "location": "", "description": "", "wiki_url": "", diff -Nru blender-2.61/release/scripts/modules/animsys_refactor.py blender-2.62/release/scripts/modules/animsys_refactor.py --- blender-2.61/release/scripts/modules/animsys_refactor.py 2011-12-13 19:43:30.000000000 +0000 +++ blender-2.62/release/scripts/modules/animsys_refactor.py 2012-02-15 19:27:47.000000000 +0000 @@ -38,6 +38,7 @@ """ Dummy class used to parse fcurve and driver data paths. """ __slots__ = ("data_path", ) + def __init__(self, attrs): self.data_path = attrs @@ -531,8 +532,6 @@ ("ShaderNodeMapping", "minimum", "min"), ("ShaderNodeMapping", "clamp_maximum", "use_max"), ("ShaderNodeMapping", "clamp_minimum", "use_min"), - ("VertexPaint", "all_faces", "use_all_faces"), - ("VertexPaint", "spray", "use_spray"), ("ParticleEdit", "add_keys", "default_key_count"), ("ParticleEdit", "selection_mode", "select_mode"), ("ParticleEdit", "auto_velocity", "use_auto_velocity"), diff -Nru blender-2.61/release/scripts/modules/bpy/utils.py blender-2.62/release/scripts/modules/bpy/utils.py --- blender-2.61/release/scripts/modules/bpy/utils.py 2011-12-13 19:43:27.000000000 +0000 +++ blender-2.62/release/scripts/modules/bpy/utils.py 2012-02-15 19:27:45.000000000 +0000 @@ -281,10 +281,7 @@ prefs = _bpy.context.user_preferences # add user scripts dir - if user_pref: - user_script_path = prefs.filepaths.script_directory - else: - user_script_path = None + user_script = prefs.filepaths.script_directory if user_pref else None if check_all: # all possible paths @@ -294,7 +291,7 @@ # only paths blender uses base_paths = _bpy_script_paths() - for path in base_paths + (user_script_path, ): + for path in base_paths + (user_script, ): if path: path = _os.path.normpath(path) if path not in scripts and _os.path.isdir(path): @@ -303,13 +300,13 @@ if subdir is None: return scripts - script_paths = [] + scripts_subdir = [] for path in scripts: path_subdir = _os.path.join(path, subdir) if _os.path.isdir(path_subdir): - script_paths.append(path_subdir) + scripts_subdir.append(path_subdir) - return script_paths + return scripts_subdir def refresh_script_paths(): @@ -330,9 +327,6 @@ _sys_path_ensure(path) -_presets = _os.path.join(_scripts[0], "presets") # FIXME - multiple paths - - def preset_paths(subdir): """ Returns a list of paths for a specific preset. @@ -349,6 +343,14 @@ raise Exception("invalid subdir given %r" % subdir) elif _os.path.isdir(directory): dirs.append(directory) + + # Find addons preset paths + import addon_utils + for path in addon_utils.paths(): + directory = _os.path.join(path, "presets", subdir) + if _os.path.isdir(directory): + dirs.append(directory) + return dirs @@ -400,7 +402,7 @@ return smpte_from_seconds((frame * fps_base) / fps, fps) -def preset_find(name, preset_path, display_name=False): +def preset_find(name, preset_path, display_name=False, ext=".py"): if not name: return None @@ -409,11 +411,11 @@ if display_name: filename = "" for fn in _os.listdir(directory): - if fn.endswith(".py") and name == _bpy.path.display_name(fn): + if fn.endswith(ext) and name == _bpy.path.display_name(fn): filename = fn break else: - filename = name + ".py" + filename = name + ext if filename: filepath = _os.path.join(directory, filename) @@ -456,7 +458,7 @@ keyconfigs.active = kc_new -def user_resource(type, path="", create=False): +def user_resource(resource_type, path="", create=False): """ Return a user resource path (normally from the users home directory). @@ -471,7 +473,7 @@ :rtype: string """ - target_path = _user_resource(type, path) + target_path = _user_resource(resource_type, path) if create: # should always be true. diff -Nru blender-2.61/release/scripts/modules/bpy_extras/anim_utils.py blender-2.62/release/scripts/modules/bpy_extras/anim_utils.py --- blender-2.61/release/scripts/modules/bpy_extras/anim_utils.py 2011-12-13 19:43:26.000000000 +0000 +++ blender-2.62/release/scripts/modules/bpy_extras/anim_utils.py 2012-02-15 19:27:43.000000000 +0000 @@ -158,7 +158,7 @@ # ------------------------------------------------------------------------- # Create action - # in case animation data hassnt been created + # in case animation data hasn't been created atd = obj.animation_data_create() if action is None: action = bpy.data.actions.new("Action") diff -Nru blender-2.61/release/scripts/modules/bpy_extras/io_utils.py blender-2.62/release/scripts/modules/bpy_extras/io_utils.py --- blender-2.61/release/scripts/modules/bpy_extras/io_utils.py 2011-12-13 19:43:26.000000000 +0000 +++ blender-2.62/release/scripts/modules/bpy_extras/io_utils.py 2012-02-15 19:27:43.000000000 +0000 @@ -121,24 +121,24 @@ ((-1.0, 0.0, 0.0), (0.0, 0.0, 1.0), (0.0, 1.0, 0.0)), ((-1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, -1.0)), ((0.0, -1.0, 0.0), (-1.0, 0.0, 0.0), (0.0, 0.0, -1.0)), - ((0.0, -1.0, 0.0), (0.0, 0.0, -1.0), (1.0, 0.0, 0.0)), - ((0.0, -1.0, 0.0), (0.0, 0.0, 1.0), (-1.0, 0.0, 0.0)), - ((0.0, -1.0, 0.0), (1.0, 0.0, 0.0), (0.0, 0.0, 1.0)), + ((0.0, 0.0, 1.0), (-1.0, 0.0, 0.0), (0.0, -1.0, 0.0)), ((0.0, 0.0, -1.0), (-1.0, 0.0, 0.0), (0.0, 1.0, 0.0)), + ((0.0, 1.0, 0.0), (-1.0, 0.0, 0.0), (0.0, 0.0, 1.0)), + ((0.0, -1.0, 0.0), (0.0, 0.0, 1.0), (-1.0, 0.0, 0.0)), ((0.0, 0.0, -1.0), (0.0, -1.0, 0.0), (-1.0, 0.0, 0.0)), - ((0.0, 0.0, -1.0), (0.0, 1.0, 0.0), (1.0, 0.0, 0.0)), - ((0.0, 0.0, -1.0), (1.0, 0.0, 0.0), (0.0, -1.0, 0.0)), - ((0.0, 0.0, 1.0), (-1.0, 0.0, 0.0), (0.0, -1.0, 0.0)), - ((0.0, 0.0, 1.0), (0.0, -1.0, 0.0), (1.0, 0.0, 0.0)), ((0.0, 0.0, 1.0), (0.0, 1.0, 0.0), (-1.0, 0.0, 0.0)), - ((0.0, 0.0, 1.0), (1.0, 0.0, 0.0), (0.0, 1.0, 0.0)), - ((0.0, 1.0, 0.0), (-1.0, 0.0, 0.0), (0.0, 0.0, 1.0)), ((0.0, 1.0, 0.0), (0.0, 0.0, -1.0), (-1.0, 0.0, 0.0)), + ((0.0, -1.0, 0.0), (0.0, 0.0, -1.0), (1.0, 0.0, 0.0)), + ((0.0, 0.0, 1.0), (0.0, -1.0, 0.0), (1.0, 0.0, 0.0)), + ((0.0, 0.0, -1.0), (0.0, 1.0, 0.0), (1.0, 0.0, 0.0)), ((0.0, 1.0, 0.0), (0.0, 0.0, 1.0), (1.0, 0.0, 0.0)), + ((0.0, -1.0, 0.0), (1.0, 0.0, 0.0), (0.0, 0.0, 1.0)), + ((0.0, 0.0, -1.0), (1.0, 0.0, 0.0), (0.0, -1.0, 0.0)), + ((0.0, 0.0, 1.0), (1.0, 0.0, 0.0), (0.0, 1.0, 0.0)), ((0.0, 1.0, 0.0), (1.0, 0.0, 0.0), (0.0, 0.0, -1.0)), ((1.0, 0.0, 0.0), (0.0, -1.0, 0.0), (0.0, 0.0, -1.0)), - ((1.0, 0.0, 0.0), (0.0, 0.0, -1.0), (0.0, 1.0, 0.0)), ((1.0, 0.0, 0.0), (0.0, 0.0, 1.0), (0.0, -1.0, 0.0)), + ((1.0, 0.0, 0.0), (0.0, 0.0, -1.0), (0.0, 1.0, 0.0)), ) # store args as a single int diff -Nru blender-2.61/release/scripts/modules/bpy_extras/keyconfig_utils.py blender-2.62/release/scripts/modules/bpy_extras/keyconfig_utils.py --- blender-2.61/release/scripts/modules/bpy_extras/keyconfig_utils.py 2011-12-13 19:43:26.000000000 +0000 +++ blender-2.62/release/scripts/modules/bpy_extras/keyconfig_utils.py 2012-02-15 19:27:43.000000000 +0000 @@ -70,6 +70,7 @@ ('Image', 'IMAGE_EDITOR', 'WINDOW', [ ('UV Editor', 'EMPTY', 'WINDOW', []), # image (reverse order, UVEdit before Image ('Image Paint', 'EMPTY', 'WINDOW', []), # image and view3d + ('UV Sculpt', 'EMPTY', 'WINDOW', []), ('Image Generic', 'IMAGE_EDITOR', 'WINDOW', []) ]), @@ -89,7 +90,6 @@ ('Property Editor', 'PROPERTIES', 'WINDOW', []), # align context menu - ('Script', 'SCRIPTS_WINDOW', 'WINDOW', []), ('Text', 'TEXT_EDITOR', 'WINDOW', []), ('Console', 'CONSOLE', 'WINDOW', []), ('Clip', 'CLIP_EDITOR', 'WINDOW', [ diff -Nru blender-2.61/release/scripts/modules/bpy_extras/mesh_utils.py blender-2.62/release/scripts/modules/bpy_extras/mesh_utils.py --- blender-2.61/release/scripts/modules/bpy_extras/mesh_utils.py 2011-12-13 19:43:26.000000000 +0000 +++ blender-2.62/release/scripts/modules/bpy_extras/mesh_utils.py 2012-02-15 19:27:43.000000000 +0000 @@ -167,7 +167,7 @@ flipped = False while 1: - # from knowing the last 2, look for th next. + # from knowing the last 2, look for the next. ed_adj = edges[context_loop[-1]] if len(ed_adj) != 2: # the original edge had 2 other edges @@ -175,7 +175,7 @@ flipped = True # only flip the list once context_loop.reverse() ed_adj[:] = [] - context_loop.append(other_dir) # save 1 lookiup + context_loop.append(other_dir) # save 1 look-up ed_adj = edges[context_loop[-1]] if len(ed_adj) != 2: @@ -375,7 +375,7 @@ if s1[0][1] == s1[-1][1]: # remove endpoints double s1.pop() - s2[:] = [] # Empty this segment s2 so we dont use it again. + s2[:] = [] # Empty this segment s2 so we don't use it again. return True joining_segments = True diff -Nru blender-2.61/release/scripts/modules/bpy_extras/object_utils.py blender-2.62/release/scripts/modules/bpy_extras/object_utils.py --- blender-2.61/release/scripts/modules/bpy_extras/object_utils.py 2011-12-13 19:43:26.000000000 +0000 +++ blender-2.62/release/scripts/modules/bpy_extras/object_utils.py 2012-02-15 19:27:43.000000000 +0000 @@ -44,7 +44,7 @@ properties = operator.properties if operator is not None else None space_data = context.space_data - if space_data.type != 'VIEW_3D': + if space_data and space_data.type != 'VIEW_3D': space_data = None # location diff -Nru blender-2.61/release/scripts/modules/bpy_extras/view3d_utils.py blender-2.62/release/scripts/modules/bpy_extras/view3d_utils.py --- blender-2.61/release/scripts/modules/bpy_extras/view3d_utils.py 2011-12-13 19:43:26.000000000 +0000 +++ blender-2.62/release/scripts/modules/bpy_extras/view3d_utils.py 2012-02-15 19:27:43.000000000 +0000 @@ -42,6 +42,7 @@ """ from mathutils import Vector + viewinv = rv3d.view_matrix.inverted() if rv3d.is_perspective: persinv = rv3d.perspective_matrix.inverted() @@ -50,13 +51,11 @@ -0.5 )) - w = ((out[0] * persinv[0][3]) + - (out[1] * persinv[1][3]) + - (out[2] * persinv[2][3]) + persinv[3][3]) + w = out.dot(persinv[3].xyz) + persinv[3][3] - return ((persinv * out) / w) - rv3d.view_matrix.inverted()[3].xyz + return ((persinv * out) / w) - viewinv.translation else: - return rv3d.view_matrix.inverted()[2].xyz.normalized() + return viewinv.col[2].xyz.normalized() def region_2d_to_location_3d(region, rv3d, coord, depth_location): @@ -81,15 +80,16 @@ from mathutils.geometry import intersect_point_line persmat = rv3d.perspective_matrix.copy() + viewinv = rv3d.view_matrix.inverted() coord_vec = region_2d_to_vector_3d(region, rv3d, coord) depth_location = Vector(depth_location) if rv3d.is_perspective: from mathutils.geometry import intersect_line_plane - origin_start = rv3d.view_matrix.inverted()[3].to_3d() + origin_start = viewinv.translation.copy() origin_end = origin_start + coord_vec - view_vec = rv3d.view_matrix.inverted()[2] + view_vec = viewinv.col[2].copy() return intersect_line_plane(origin_start, origin_end, depth_location, @@ -100,8 +100,9 @@ dy = (2.0 * coord[1] / region.height) - 1.0 persinv = persmat.inverted() viewinv = rv3d.view_matrix.inverted() - origin_start = ((persinv[0].xyz * dx) + - (persinv[1].xyz * dy) + viewinv[3].xyz) + origin_start = ((persinv.col[0].xyz * dx) + + (persinv.col[1].xyz * dy) + + viewinv.translation) origin_end = origin_start + coord_vec return intersect_point_line(depth_location, origin_start, diff -Nru blender-2.61/release/scripts/modules/console/complete_import.py blender-2.62/release/scripts/modules/console/complete_import.py --- blender-2.61/release/scripts/modules/console/complete_import.py 2011-12-13 19:43:29.000000000 +0000 +++ blender-2.62/release/scripts/modules/console/complete_import.py 2012-02-15 19:27:46.000000000 +0000 @@ -44,7 +44,7 @@ import os import sys -TIMEOUT_STORAGE = 3 # Time in secs after which the rootmodules will be stored +TIMEOUT_STORAGE = 3 # Time in secs after which the root-modules will be stored TIMEOUT_GIVEUP = 20 # Time in secs after which we give up ROOT_MODULES = None @@ -53,7 +53,7 @@ def get_root_modules(): """ Returns a list containing the names of all the modules available in the - folders of the pythonpath. + folders of the python-path. :returns: modules :rtype: list diff -Nru blender-2.61/release/scripts/modules/rna_prop_ui.py blender-2.62/release/scripts/modules/rna_prop_ui.py --- blender-2.61/release/scripts/modules/rna_prop_ui.py 2011-12-13 19:43:30.000000000 +0000 +++ blender-2.62/release/scripts/modules/rna_prop_ui.py 2012-02-15 19:27:47.000000000 +0000 @@ -145,11 +145,11 @@ if use_edit: row = split.row(align=True) - prop = row.operator("wm.properties_edit", text="edit") - assign_props(prop, val_draw, key) + props = row.operator("wm.properties_edit", text="edit") + assign_props(props, val_draw, key) - prop = row.operator("wm.properties_remove", text="", icon='ZOOMOUT') - assign_props(prop, val_draw, key) + props = row.operator("wm.properties_remove", text="", icon='ZOOMOUT') + assign_props(props, val_draw, key) class PropertyPanel(): diff -Nru blender-2.61/release/scripts/modules/rna_xml.py blender-2.62/release/scripts/modules/rna_xml.py --- blender-2.61/release/scripts/modules/rna_xml.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/modules/rna_xml.py 2012-02-15 19:27:47.000000000 +0000 @@ -0,0 +1,370 @@ +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the 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. +# +# Contributor(s): Campbell Barton +# +# ***** END GPL LICENSE BLOCK ***** + +# + +import bpy + + +def build_property_typemap(skip_classes): + + property_typemap = {} + + for attr in dir(bpy.types): + cls = getattr(bpy.types, attr) + if issubclass(cls, skip_classes): + continue + + ## to support skip-save we cant get all props + # properties = cls.bl_rna.properties.keys() + properties = [] + for prop_id, prop in cls.bl_rna.properties.items(): + if not prop.is_skip_save: + properties.append(prop_id) + + properties.remove("rna_type") + property_typemap[attr] = properties + + return property_typemap + + +def print_ln(data): + print(data, end="") + + +def rna2xml(fw=print_ln, + root_node="", + root_rna=None, # must be set + root_rna_skip=set(), + root_ident="", + ident_val=" ", + skip_classes=(bpy.types.Operator, + bpy.types.Panel, + bpy.types.KeyingSet, + bpy.types.Header, + ), + pretty_format=True, + method='DATA'): + + from xml.sax.saxutils import quoteattr + property_typemap = build_property_typemap(skip_classes) + + def number_to_str(val, val_type): + if val_type == int: + return "%d" % val + elif val_type == float: + return "%.6g" % val + elif val_type == bool: + return "TRUE" if val else "FALSE" + else: + raise NotImplemented("this type is not a number %s" % val_type) + + def rna2xml_node(ident, value, parent): + ident_next = ident + ident_val + + # divide into attrs and nodes. + node_attrs = [] + nodes_items = [] + nodes_lists = [] + + value_type = type(value) + + if issubclass(value_type, skip_classes): + return + + # XXX, fixme, pointcache has eternal nested pointer to its self. + if value == parent: + return + + value_type_name = value_type.__name__ + for prop in property_typemap[value_type_name]: + + subvalue = getattr(value, prop) + subvalue_type = type(subvalue) + + if subvalue_type in (int, bool, float): + node_attrs.append("%s=\"%s\"" % (prop, number_to_str(subvalue, subvalue_type))) + elif subvalue_type is str: + node_attrs.append("%s=%s" % (prop, quoteattr(subvalue))) + elif subvalue_type == set: + node_attrs.append("%s=%s" % (prop, quoteattr("{" + ",".join(list(subvalue)) + "}"))) + elif subvalue is None: + node_attrs.append("%s=\"NONE\"" % prop) + elif issubclass(subvalue_type, bpy.types.ID): + # special case, ID's are always referenced. + node_attrs.append("%s=%s" % (prop, quoteattr(subvalue_type.__name__ + "::" + subvalue.name))) + else: + try: + subvalue_ls = list(subvalue) + except: + subvalue_ls = None + + if subvalue_ls is None: + nodes_items.append((prop, subvalue, subvalue_type)) + else: + # check if the list contains native types + subvalue_rna = value.path_resolve(prop, False) + if type(subvalue_rna).__name__ == "bpy_prop_array": + # check if this is a 0-1 color (rgb, rgba) + # in that case write as a hexidecimal + prop_rna = value.bl_rna.properties[prop] + if (prop_rna.subtype == 'COLOR_GAMMA' and + prop_rna.hard_min == 0.0 and + prop_rna.hard_max == 1.0 and + prop_rna.array_length in {3, 4}): + # ----- + # color + array_value = "#" + "".join(("%.2x" % int(v * 255) for v in subvalue_rna)) + + else: + # default + def str_recursive(s): + subsubvalue_type = type(s) + if subsubvalue_type in (int, float, bool): + return number_to_str(s, subsubvalue_type) + else: + return " ".join([str_recursive(si) for si in s]) + + array_value = " ".join(str_recursive(v) for v in subvalue_rna) + + node_attrs.append("%s=\"%s\"" % (prop, array_value)) + else: + nodes_lists.append((prop, subvalue_ls, subvalue_type)) + + # declare + attributes + if pretty_format: + if node_attrs: + tmp_str = "<%s " % value_type_name + tmp_ident = "\n" + ident + (" " * len(tmp_str)) + fw("%s%s%s>\n" % (ident, tmp_str, tmp_ident.join(node_attrs))) + del tmp_str + del tmp_ident + else: + fw("%s<%s>\n" % (ident, value_type_name)) + else: + fw("%s<%s %s>\n" % (ident, value_type_name, " ".join(node_attrs))) + + # unique members + for prop, subvalue, subvalue_type in nodes_items: + fw("%s<%s>\n" % (ident_next, prop)) # XXX, this is awkward, how best to solve? + rna2xml_node(ident_next + ident_val, subvalue, value) + fw("%s\n" % (ident_next, prop)) # XXX, need to check on this. + + # list members + for prop, subvalue, subvalue_type in nodes_lists: + fw("%s<%s>\n" % (ident_next, prop)) + for subvalue_item in subvalue: + if subvalue_item is not None: + rna2xml_node(ident_next + ident_val, subvalue_item, value) + fw("%s\n" % (ident_next, prop)) + + fw("%s\n" % (ident, value_type_name)) + + # ------------------------------------------------------------------------- + # needs re-workign to be generic + + if root_node: + fw("%s<%s>\n" % (root_ident, root_node)) + + # bpy.data + if method == 'DATA': + ident = root_ident + ident_val + for attr in dir(root_rna): + + # exceptions + if attr.startswith("_"): + continue + elif attr in root_rna_skip: + continue + + value = getattr(root_rna, attr) + try: + ls = value[:] + except: + ls = None + + if type(ls) == list: + fw("%s<%s>\n" % (ident, attr)) + for blend_id in ls: + rna2xml_node(ident + ident_val, blend_id, None) + fw("%s\n" % (ident_val, attr)) + # any attribute + elif method == 'ATTR': + rna2xml_node(root_ident, root_rna, None) + + if root_node: + fw("%s\n" % (root_ident, root_node)) + + +def xml2rna(root_xml, + root_rna=None, # must be set + ): + + def rna2xml_node(xml_node, value): +# print("evaluating:", xml_node.nodeName) + + # --------------------------------------------------------------------- + # Simple attributes + + for attr in xml_node.attributes.keys(): +# print(" ", attr) + subvalue = getattr(value, attr, Ellipsis) + + if subvalue is Ellipsis: + print("%s.%s not found" % (type(value).__name__, attr)) + else: + value_xml = xml_node.attributes[attr].value + + subvalue_type = type(subvalue) + tp_name = 'UNKNOWN' + if subvalue_type == float: + value_xml_coerce = float(value_xml) + tp_name = 'FLOAT' + elif subvalue_type == int: + value_xml_coerce = int(value_xml) + tp_name = 'INT' + elif subvalue_type == bool: + value_xml_coerce = {'TRUE': True, 'FALSE': False}[value_xml] + tp_name = 'BOOL' + elif subvalue_type == str: + value_xml_coerce = value_xml + tp_name = 'STR' + elif hasattr(subvalue, "__len__"): + if value_xml.startswith("#"): + # read hexidecimal value as float array + value_xml_split = value_xml[1:] + value_xml_coerce = [int(value_xml_split[i:i + 2], 16) / 255 for i in range(0, len(value_xml_split), 2)] + del value_xml_split + else: + value_xml_split = value_xml.split() + try: + value_xml_coerce = [int(v) for v in value_xml_split] + except ValueError: + value_xml_coerce = [float(v) for v in value_xml_split] + del value_xml_split + tp_name = 'ARRAY' + +# print(" %s.%s (%s) --- %s" % (type(value).__name__, attr, tp_name, subvalue_type)) + setattr(value, attr, value_xml_coerce) + + # --------------------------------------------------------------------- + # Complex attributes + for child_xml in xml_node.childNodes: + if child_xml.nodeType == child_xml.ELEMENT_NODE: + # print() + # print(child_xml.nodeName) + subvalue = getattr(value, child_xml.nodeName, None) + if subvalue is not None: + + elems = [] + for child_xml_real in child_xml.childNodes: + if child_xml_real.nodeType == child_xml_real.ELEMENT_NODE: + elems.append(child_xml_real) + del child_xml_real + + if hasattr(subvalue, "__len__"): + # Collection + if len(elems) != len(subvalue): + print("Size Mismatch! collection:", child_xml.nodeName) + else: + for i in range(len(elems)): + child_xml_real = elems[i] + subsubvalue = subvalue[i] + + if child_xml_real is None or subsubvalue is None: + print("None found %s - %d collection:", (child_xml.nodeName, i)) + else: + rna2xml_node(child_xml_real, subsubvalue) + + else: +# print(elems) + + if len(elems) == 1: + # sub node named by its type + child_xml_real, = elems + + # print(child_xml_real, subvalue) + rna2xml_node(child_xml_real, subvalue) + else: + # empty is valid too + pass + + rna2xml_node(root_xml, root_rna) + + +# ----------------------------------------------------------------------------- +# Utility function used by presets. +# The idea is you can run a preset like a script with a few args. +# +# This roughly matches the operator 'bpy.ops.script.python_file_run' + + +def _get_context_val(context, path): + path_full = "context." + path + try: + value = eval(path_full) + except: + import traceback + traceback.print_exc() + print("Error: %r could not be found" % path_full) + + value = Ellipsis + + return value + + +def xml_file_run(context, filepath, rna_map): + + import xml.dom.minidom + + xml_nodes = xml.dom.minidom.parse(filepath) + bpy_xml = xml_nodes.getElementsByTagName("bpy")[0] + + for rna_path, xml_tag in rna_map: + + # first get xml + # TODO, error check + xml_node = bpy_xml.getElementsByTagName(xml_tag)[0] + + value = _get_context_val(context, rna_path) + + if value is not Ellipsis and value is not None: + print(" loading XML: %r" % rna_path) + xml2rna(xml_node, root_rna=value) + + +def xml_file_write(context, filepath, rna_map): + + file = open(filepath, 'w', encoding='utf-8') + fw = file.write + + fw("\n") + + for rna_path, xml_tag in rna_map: + # xml_tag is ignored, we get this from the rna + value = _get_context_val(context, rna_path) + rna2xml(fw, + root_rna=value, + method='ATTR', + root_ident=" ", + ident_val=" ") + + fw("\n") + file.close() diff -Nru blender-2.61/release/scripts/modules/sys_info.py blender-2.62/release/scripts/modules/sys_info.py --- blender-2.61/release/scripts/modules/sys_info.py 2011-12-13 19:43:30.000000000 +0000 +++ blender-2.62/release/scripts/modules/sys_info.py 2012-02-15 19:27:47.000000000 +0000 @@ -94,6 +94,16 @@ output.write('autosave: {}\n'.format(bpy.utils.user_resource('AUTOSAVE'))) output.write('tempdir: {}\n'.format(bpy.app.tempdir)) + output.write('\nFFmpeg:\n') + output.write(lilies) + ffmpeg = bpy.app.ffmpeg + if ffmpeg.supported: + for lib in ['avcodec', 'avdevice', 'avformat', 'avutil', 'swscale']: + output.write('{}:{}{}\n'.format(lib, " " * (10 - len(lib)), + getattr(ffmpeg, lib + '_version_string'))) + else: + output.write('Blender was built without FFmpeg support\n') + if bpy.app.background: output.write('\nOpenGL: missing, background mode\n') else: diff -Nru blender-2.61/release/scripts/presets/ffmpeg/DVD.py blender-2.62/release/scripts/presets/ffmpeg/DVD.py --- blender-2.61/release/scripts/presets/ffmpeg/DVD.py 2011-12-13 19:43:22.000000000 +0000 +++ blender-2.62/release/scripts/presets/ffmpeg/DVD.py 2012-02-15 19:27:36.000000000 +0000 @@ -1,24 +1,24 @@ import bpy is_ntsc = (bpy.context.scene.render.fps != 25) -bpy.context.scene.render.ffmpeg_format = "MPEG2" +bpy.context.scene.render.ffmpeg.format = "MPEG2" bpy.context.scene.render.resolution_x = 720 if is_ntsc: bpy.context.scene.render.resolution_y = 480 - bpy.context.scene.render.ffmpeg_gopsize = 18 + bpy.context.scene.render.ffmpeg.gopsize = 18 else: bpy.context.scene.render.resolution_y = 576 - bpy.context.scene.render.ffmpeg_gopsize = 15 + bpy.context.scene.render.ffmpeg.gopsize = 15 -bpy.context.scene.render.ffmpeg_video_bitrate = 6000 -bpy.context.scene.render.ffmpeg_maxrate = 9000 -bpy.context.scene.render.ffmpeg_minrate = 0 -bpy.context.scene.render.ffmpeg_buffersize = 224 * 8 -bpy.context.scene.render.ffmpeg_packetsize = 2048 -bpy.context.scene.render.ffmpeg_muxrate = 10080000 +bpy.context.scene.render.ffmpeg.video_bitrate = 6000 +bpy.context.scene.render.ffmpeg.maxrate = 9000 +bpy.context.scene.render.ffmpeg.minrate = 0 +bpy.context.scene.render.ffmpeg.buffersize = 224 * 8 +bpy.context.scene.render.ffmpeg.packetsize = 2048 +bpy.context.scene.render.ffmpeg.muxrate = 10080000 -bpy.context.scene.render.ffmpeg_audio_codec = "AC3" -bpy.context.scene.render.ffmpeg_audio_bitrate = 448 -bpy.context.scene.render.ffmpeg_audio_mixrate = 48000 -bpy.context.scene.render.ffmpeg_audio_channels = 6 +bpy.context.scene.render.ffmpeg.audio_codec = "AC3" +bpy.context.scene.render.ffmpeg.audio_bitrate = 448 +bpy.context.scene.render.ffmpeg.audio_mixrate = 48000 +bpy.context.scene.render.ffmpeg.audio_channels = "SURROUND51" diff -Nru blender-2.61/release/scripts/presets/ffmpeg/DV.py blender-2.62/release/scripts/presets/ffmpeg/DV.py --- blender-2.61/release/scripts/presets/ffmpeg/DV.py 2011-12-13 19:43:22.000000000 +0000 +++ blender-2.62/release/scripts/presets/ffmpeg/DV.py 2012-02-15 19:27:36.000000000 +0000 @@ -1,7 +1,7 @@ import bpy is_ntsc = (bpy.context.scene.render.fps != 25) -bpy.context.scene.render.ffmpeg_format = "DV" +bpy.context.scene.render.ffmpeg.format = "DV" bpy.context.scene.render.resolution_x = 720 if is_ntsc: @@ -9,6 +9,6 @@ else: bpy.context.scene.render.resolution_y = 576 -bpy.context.scene.render.ffmpeg_audio_mixrate = 48000 -bpy.context.scene.render.ffmpeg_audio_codec = "PCM" -bpy.context.scene.render.ffmpeg_audio_channels = 2 +bpy.context.scene.render.ffmpeg.audio_mixrate = 48000 +bpy.context.scene.render.ffmpeg.audio_codec = "PCM" +bpy.context.scene.render.ffmpeg.audio_channels = "STEREO" diff -Nru blender-2.61/release/scripts/presets/ffmpeg/h264.py blender-2.62/release/scripts/presets/ffmpeg/h264.py --- blender-2.61/release/scripts/presets/ffmpeg/h264.py 2011-12-13 19:43:22.000000000 +0000 +++ blender-2.62/release/scripts/presets/ffmpeg/h264.py 2012-02-15 19:27:36.000000000 +0000 @@ -1,17 +1,17 @@ import bpy is_ntsc = (bpy.context.scene.render.fps != 25) -bpy.context.scene.render.ffmpeg_format = "H264" -bpy.context.scene.render.ffmpeg_codec = "H264" +bpy.context.scene.render.ffmpeg.format = "H264" +bpy.context.scene.render.ffmpeg.codec = "H264" if is_ntsc: - bpy.context.scene.render.ffmpeg_gopsize = 18 + bpy.context.scene.render.ffmpeg.gopsize = 18 else: - bpy.context.scene.render.ffmpeg_gopsize = 15 + bpy.context.scene.render.ffmpeg.gopsize = 15 -bpy.context.scene.render.ffmpeg_video_bitrate = 6000 -bpy.context.scene.render.ffmpeg_maxrate = 9000 -bpy.context.scene.render.ffmpeg_minrate = 0 -bpy.context.scene.render.ffmpeg_buffersize = 224 * 8 -bpy.context.scene.render.ffmpeg_packetsize = 2048 -bpy.context.scene.render.ffmpeg_muxrate = 10080000 +bpy.context.scene.render.ffmpeg.video_bitrate = 6000 +bpy.context.scene.render.ffmpeg.maxrate = 9000 +bpy.context.scene.render.ffmpeg.minrate = 0 +bpy.context.scene.render.ffmpeg.buffersize = 224 * 8 +bpy.context.scene.render.ffmpeg.packetsize = 2048 +bpy.context.scene.render.ffmpeg.muxrate = 10080000 diff -Nru blender-2.61/release/scripts/presets/ffmpeg/SVCD.py blender-2.62/release/scripts/presets/ffmpeg/SVCD.py --- blender-2.61/release/scripts/presets/ffmpeg/SVCD.py 2011-12-13 19:43:22.000000000 +0000 +++ blender-2.62/release/scripts/presets/ffmpeg/SVCD.py 2012-02-15 19:27:36.000000000 +0000 @@ -1,24 +1,24 @@ import bpy is_ntsc = (bpy.context.scene.render.fps != 25) -bpy.context.scene.render.ffmpeg_format = "MPEG2" +bpy.context.scene.render.ffmpeg.format = "MPEG2" bpy.context.scene.render.resolution_x = 480 if is_ntsc: bpy.context.scene.render.resolution_y = 480 - bpy.context.scene.render.ffmpeg_gopsize = 18 + bpy.context.scene.render.ffmpeg.gopsize = 18 else: bpy.context.scene.render.resolution_y = 576 - bpy.context.scene.render.ffmpeg_gopsize = 15 + bpy.context.scene.render.ffmpeg.gopsize = 15 -bpy.context.scene.render.ffmpeg_video_bitrate = 2040 -bpy.context.scene.render.ffmpeg_maxrate = 2516 -bpy.context.scene.render.ffmpeg_minrate = 0 -bpy.context.scene.render.ffmpeg_buffersize = 224 * 8 -bpy.context.scene.render.ffmpeg_packetsize = 2324 -bpy.context.scene.render.ffmpeg_muxrate = 0 +bpy.context.scene.render.ffmpeg.video_bitrate = 2040 +bpy.context.scene.render.ffmpeg.maxrate = 2516 +bpy.context.scene.render.ffmpeg.minrate = 0 +bpy.context.scene.render.ffmpeg.buffersize = 224 * 8 +bpy.context.scene.render.ffmpeg.packetsize = 2324 +bpy.context.scene.render.ffmpeg.muxrate = 0 -bpy.context.scene.render.ffmpeg_audio_bitrate = 224 -bpy.context.scene.render.ffmpeg_audio_mixrate = 44100 -bpy.context.scene.render.ffmpeg_audio_codec = "MP2" -bpy.context.scene.render.ffmpeg_audio_channels = 2 +bpy.context.scene.render.ffmpeg.audio_bitrate = 224 +bpy.context.scene.render.ffmpeg.audio_mixrate = 44100 +bpy.context.scene.render.ffmpeg.audio_codec = "MP2" +bpy.context.scene.render.ffmpeg.audio_channels = "STEREO" diff -Nru blender-2.61/release/scripts/presets/ffmpeg/theora.py blender-2.62/release/scripts/presets/ffmpeg/theora.py --- blender-2.61/release/scripts/presets/ffmpeg/theora.py 2011-12-13 19:43:22.000000000 +0000 +++ blender-2.62/release/scripts/presets/ffmpeg/theora.py 2012-02-15 19:27:36.000000000 +0000 @@ -1,17 +1,17 @@ import bpy is_ntsc = (bpy.context.scene.render.fps != 25) -bpy.context.scene.render.ffmpeg_format = "OGG" -bpy.context.scene.render.ffmpeg_codec = "THEORA" +bpy.context.scene.render.ffmpeg.format = "OGG" +bpy.context.scene.render.ffmpeg.codec = "THEORA" if is_ntsc: - bpy.context.scene.render.ffmpeg_gopsize = 18 + bpy.context.scene.render.ffmpeg.gopsize = 18 else: - bpy.context.scene.render.ffmpeg_gopsize = 15 + bpy.context.scene.render.ffmpeg.gopsize = 15 -bpy.context.scene.render.ffmpeg_video_bitrate = 6000 -bpy.context.scene.render.ffmpeg_maxrate = 9000 -bpy.context.scene.render.ffmpeg_minrate = 0 -bpy.context.scene.render.ffmpeg_buffersize = 224 * 8 -bpy.context.scene.render.ffmpeg_packetsize = 2048 -bpy.context.scene.render.ffmpeg_muxrate = 10080000 +bpy.context.scene.render.ffmpeg.video_bitrate = 6000 +bpy.context.scene.render.ffmpeg.maxrate = 9000 +bpy.context.scene.render.ffmpeg.minrate = 0 +bpy.context.scene.render.ffmpeg.buffersize = 224 * 8 +bpy.context.scene.render.ffmpeg.packetsize = 2048 +bpy.context.scene.render.ffmpeg.muxrate = 10080000 diff -Nru blender-2.61/release/scripts/presets/ffmpeg/VCD.py blender-2.62/release/scripts/presets/ffmpeg/VCD.py --- blender-2.61/release/scripts/presets/ffmpeg/VCD.py 2011-12-13 19:43:22.000000000 +0000 +++ blender-2.62/release/scripts/presets/ffmpeg/VCD.py 2012-02-15 19:27:36.000000000 +0000 @@ -1,24 +1,24 @@ import bpy is_ntsc = (bpy.context.scene.render.fps != 25) -bpy.context.scene.render.ffmpeg_format = "MPEG1" +bpy.context.scene.render.ffmpeg.format = "MPEG1" bpy.context.scene.render.resolution_x = 352 if is_ntsc: bpy.context.scene.render.resolution_y = 240 - bpy.context.scene.render.ffmpeg_gopsize = 18 + bpy.context.scene.render.ffmpeg.gopsize = 18 else: bpy.context.scene.render.resolution_y = 288 - bpy.context.scene.render.ffmpeg_gopsize = 15 + bpy.context.scene.render.ffmpeg.gopsize = 15 -bpy.context.scene.render.ffmpeg_video_bitrate = 1150 -bpy.context.scene.render.ffmpeg_maxrate = 1150 -bpy.context.scene.render.ffmpeg_minrate = 1150 -bpy.context.scene.render.ffmpeg_buffersize = 40 * 8 -bpy.context.scene.render.ffmpeg_packetsize = 2324 -bpy.context.scene.render.ffmpeg_muxrate = 2352 * 75 * 8 +bpy.context.scene.render.ffmpeg.video_bitrate = 1150 +bpy.context.scene.render.ffmpeg.maxrate = 1150 +bpy.context.scene.render.ffmpeg.minrate = 1150 +bpy.context.scene.render.ffmpeg.buffersize = 40 * 8 +bpy.context.scene.render.ffmpeg.packetsize = 2324 +bpy.context.scene.render.ffmpeg.muxrate = 2352 * 75 * 8 -bpy.context.scene.render.ffmpeg_audio_bitrate = 224 -bpy.context.scene.render.ffmpeg_audio_mixrate = 44100 -bpy.context.scene.render.ffmpeg_audio_codec = "MP2" -bpy.context.scene.render.ffmpeg_audio_channels = 2 +bpy.context.scene.render.ffmpeg.audio_bitrate = 224 +bpy.context.scene.render.ffmpeg.audio_mixrate = 44100 +bpy.context.scene.render.ffmpeg.audio_codec = "MP2" +bpy.context.scene.render.ffmpeg.audio_channels = "STEREO" diff -Nru blender-2.61/release/scripts/presets/ffmpeg/xvid.py blender-2.62/release/scripts/presets/ffmpeg/xvid.py --- blender-2.61/release/scripts/presets/ffmpeg/xvid.py 2011-12-13 19:43:22.000000000 +0000 +++ blender-2.62/release/scripts/presets/ffmpeg/xvid.py 2012-02-15 19:27:36.000000000 +0000 @@ -1,16 +1,16 @@ import bpy is_ntsc = (bpy.context.scene.render.fps != 25) -bpy.context.scene.render.ffmpeg_format = "XVID" +bpy.context.scene.render.ffmpeg.format = "XVID" if is_ntsc: - bpy.context.scene.render.ffmpeg_gopsize = 18 + bpy.context.scene.render.ffmpeg.gopsize = 18 else: - bpy.context.scene.render.ffmpeg_gopsize = 15 + bpy.context.scene.render.ffmpeg.gopsize = 15 -bpy.context.scene.render.ffmpeg_video_bitrate = 6000 -bpy.context.scene.render.ffmpeg_maxrate = 9000 -bpy.context.scene.render.ffmpeg_minrate = 0 -bpy.context.scene.render.ffmpeg_buffersize = 224 * 8 -bpy.context.scene.render.ffmpeg_packetsize = 2048 -bpy.context.scene.render.ffmpeg_muxrate = 10080000 +bpy.context.scene.render.ffmpeg.video_bitrate = 6000 +bpy.context.scene.render.ffmpeg.maxrate = 9000 +bpy.context.scene.render.ffmpeg.minrate = 0 +bpy.context.scene.render.ffmpeg.buffersize = 224 * 8 +bpy.context.scene.render.ffmpeg.packetsize = 2048 +bpy.context.scene.render.ffmpeg.muxrate = 10080000 diff -Nru blender-2.61/release/scripts/presets/interface_theme/back_to_black.xml blender-2.62/release/scripts/presets/interface_theme/back_to_black.xml --- blender-2.61/release/scripts/presets/interface_theme/back_to_black.xml 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/presets/interface_theme/back_to_black.xml 2012-02-15 19:27:36.000000000 +0000 @@ -0,0 +1,813 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru blender-2.61/release/scripts/presets/interface_theme/blender_24x.xml blender-2.62/release/scripts/presets/interface_theme/blender_24x.xml --- blender-2.61/release/scripts/presets/interface_theme/blender_24x.xml 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/presets/interface_theme/blender_24x.xml 2012-02-15 19:27:36.000000000 +0000 @@ -0,0 +1,813 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru blender-2.61/release/scripts/presets/interface_theme/elsyiun.xml blender-2.62/release/scripts/presets/interface_theme/elsyiun.xml --- blender-2.61/release/scripts/presets/interface_theme/elsyiun.xml 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/presets/interface_theme/elsyiun.xml 2012-02-15 19:27:36.000000000 +0000 @@ -0,0 +1,813 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru blender-2.61/release/scripts/presets/interface_theme/hexagon.xml blender-2.62/release/scripts/presets/interface_theme/hexagon.xml --- blender-2.61/release/scripts/presets/interface_theme/hexagon.xml 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/presets/interface_theme/hexagon.xml 2012-02-15 19:27:36.000000000 +0000 @@ -0,0 +1,813 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru blender-2.61/release/scripts/presets/interface_theme/ubuntu_ambiance.xml blender-2.62/release/scripts/presets/interface_theme/ubuntu_ambiance.xml --- blender-2.61/release/scripts/presets/interface_theme/ubuntu_ambiance.xml 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/presets/interface_theme/ubuntu_ambiance.xml 2012-02-15 19:27:36.000000000 +0000 @@ -0,0 +1,813 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru blender-2.61/release/scripts/presets/keyconfig/maya.py blender-2.62/release/scripts/presets/keyconfig/maya.py --- blender-2.61/release/scripts/presets/keyconfig/maya.py 2011-12-13 19:43:25.000000000 +0000 +++ blender-2.62/release/scripts/presets/keyconfig/maya.py 2012-02-15 19:27:40.000000000 +0000 @@ -219,7 +219,8 @@ kmi.properties.value_2 = 'ENABLED' kmi = km.keymap_items.new('view3d.game_start', 'P', 'PRESS') kmi = km.keymap_items.new('object.select_all', 'A', 'PRESS') -kmi = km.keymap_items.new('object.select_inverse', 'I', 'PRESS', ctrl=True) +kmi = km.keymap_items.new('object.select_all', 'I', 'PRESS', ctrl=True) +kmi.properties.action = 'INVERT' kmi = km.keymap_items.new('object.select_linked', 'L', 'PRESS', shift=True) kmi = km.keymap_items.new('object.select_grouped', 'G', 'PRESS', shift=True) kmi = km.keymap_items.new('object.select_mirror', 'M', 'PRESS', shift=True, ctrl=True) @@ -304,7 +305,8 @@ kmi = km.keymap_items.new('mesh.select_all', 'A', 'PRESS') kmi = km.keymap_items.new('mesh.select_more', 'NUMPAD_PLUS', 'PRESS', ctrl=True) kmi = km.keymap_items.new('mesh.select_less', 'NUMPAD_MINUS', 'PRESS', ctrl=True) -kmi = km.keymap_items.new('mesh.select_inverse', 'I', 'PRESS', ctrl=True) +kmi = km.keymap_items.new('mesh.select_all', 'I', 'PRESS', ctrl=True) +kmi.properties.action = 'INVERT' kmi = km.keymap_items.new('mesh.select_non_manifold', 'M', 'PRESS', shift=True, ctrl=True, alt=True) kmi = km.keymap_items.new('mesh.select_linked', 'L', 'PRESS', ctrl=True) kmi = km.keymap_items.new('mesh.select_linked_pick', 'L', 'PRESS') diff -Nru blender-2.61/release/scripts/presets/tracking_settings/blurry_footage.py blender-2.62/release/scripts/presets/tracking_settings/blurry_footage.py --- blender-2.61/release/scripts/presets/tracking_settings/blurry_footage.py 2011-12-13 19:43:22.000000000 +0000 +++ blender-2.62/release/scripts/presets/tracking_settings/blurry_footage.py 2012-02-15 19:27:36.000000000 +0000 @@ -9,3 +9,6 @@ settings.default_frames_limit = 0 settings.default_pattern_match = 'PREV_FRAME' settings.default_margin = 0 +settings.use_default_red_channel = True +settings.use_default_green_channel = True +settings.use_default_blue_channel = True diff -Nru blender-2.61/release/scripts/presets/tracking_settings/default.py blender-2.62/release/scripts/presets/tracking_settings/default.py --- blender-2.61/release/scripts/presets/tracking_settings/default.py 2011-12-13 19:43:22.000000000 +0000 +++ blender-2.62/release/scripts/presets/tracking_settings/default.py 2012-02-15 19:27:36.000000000 +0000 @@ -9,3 +9,6 @@ settings.default_frames_limit = 0 settings.default_pattern_match = 'KEYFRAME' settings.default_margin = 0 +settings.use_default_red_channel = True +settings.use_default_green_channel = True +settings.use_default_blue_channel = True diff -Nru blender-2.61/release/scripts/presets/tracking_settings/fast_motion.py blender-2.62/release/scripts/presets/tracking_settings/fast_motion.py --- blender-2.61/release/scripts/presets/tracking_settings/fast_motion.py 2011-12-13 19:43:22.000000000 +0000 +++ blender-2.62/release/scripts/presets/tracking_settings/fast_motion.py 2012-02-15 19:27:36.000000000 +0000 @@ -9,3 +9,6 @@ settings.default_frames_limit = 0 settings.default_pattern_match = 'PREV_FRAME' settings.default_margin = 5 +settings.use_default_red_channel = True +settings.use_default_green_channel = True +settings.use_default_blue_channel = True diff -Nru blender-2.61/release/scripts/presets/tracking_track_color/object.py blender-2.62/release/scripts/presets/tracking_track_color/object.py --- blender-2.61/release/scripts/presets/tracking_track_color/object.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/presets/tracking_track_color/object.py 2012-02-15 19:27:36.000000000 +0000 @@ -0,0 +1,5 @@ +import bpy +track = bpy.context.edit_movieclip.tracking.tracks.active + +track.color = (1.0, 0.0, 1.0) +track.use_custom_color = True diff -Nru blender-2.61/release/scripts/startup/bl_operators/anim.py blender-2.62/release/scripts/startup/bl_operators/anim.py --- blender-2.61/release/scripts/startup/bl_operators/anim.py 2011-12-13 19:43:21.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_operators/anim.py 2012-02-15 19:27:33.000000000 +0000 @@ -161,7 +161,7 @@ class BakeAction(Operator): - """Bake animation to an Action""" + """Bake object/pose loc/scale/rotation animation to a new action""" bl_idname = "nla.bake" bl_label = "Bake Action" bl_options = {'REGISTER', 'UNDO'} @@ -227,7 +227,7 @@ class ClearUselessActions(Operator): - """Mark actions with no F-Curves for deletion after save+reload of """ \ + """Mark actions with no F-Curves for deletion after save & reload of """ \ """file preserving \"action libraries\"""" bl_idname = "anim.clear_useless_actions" bl_label = "Clear Useless Actions" @@ -239,7 +239,7 @@ @classmethod def poll(cls, context): - return len(bpy.data.actions) != 0 + return bool(bpy.data.actions) def execute(self, context): removed = 0 diff -Nru blender-2.61/release/scripts/startup/bl_operators/clip.py blender-2.62/release/scripts/startup/bl_operators/clip.py --- blender-2.61/release/scripts/startup/bl_operators/clip.py 2011-12-13 19:43:21.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_operators/clip.py 2012-02-15 19:27:33.000000000 +0000 @@ -24,7 +24,7 @@ from mathutils import Vector, Matrix -def CLIP_spacees_walk(context, all_screens, tarea, tspace, callback, *args): +def CLIP_spaces_walk(context, all_screens, tarea, tspace, callback, *args): screens = bpy.data.screens if all_screens else [context.screen] for screen in screens: @@ -56,10 +56,27 @@ space_v3d.show_background_images = True - CLIP_spacees_walk(context, all_screens, 'VIEW_3D', 'VIEW_3D', + CLIP_spaces_walk(context, all_screens, 'VIEW_3D', 'VIEW_3D', set_background, clip, clip_user) +def CLIP_camera_for_clip(context, clip): + scene = context.scene + + camera = scene.camera + + for ob in scene.objects: + if ob.type == 'CAMERA': + for con in ob.constraints: + if con.type == 'CAMERA_SOLVER': + cur_clip = scene.active_clip if con.use_active_clip else con.clip + + if cur_clip == clip: + return ob + + return camera + + def CLIP_track_view_selected(sc, track): if track.select_anchor: return True @@ -73,6 +90,34 @@ return False +def CLIP_default_settings_from_track(clip, track): + settings = clip.tracking.settings + + width = clip.size[0] + height = clip.size[1] + + pattern = track.pattern_max - track.pattern_min + search = track.search_max - track.search_min + + pattern[0] = pattern[0] * clip.size[0] + pattern[1] = pattern[1] * clip.size[1] + + search[0] = search[0] * clip.size[0] + search[1] = search[1] * clip.size[1] + + settings.default_tracker = track.tracker + settings.default_pyramid_levels = track.pyramid_levels + settings.default_correlation_min = track.correlation_min + settings.default_pattern_size = max(pattern[0], pattern[1]) + settings.default_search_size = max(search[0], search[1]) + settings.default_frames_limit = track.frames_limit + settings.default_pattern_match = track.pattern_match + settings.default_margin = track.margin + settings.use_default_red_channel = track.use_red_channel + settings.use_default_green_channel = track.use_green_channel + settings.use_default_blue_channel = track.use_blue_channel + + class CLIP_OT_track_to_empty(Operator): """Create an Empty object which will be copying movement of active track""" @@ -80,7 +125,7 @@ bl_label = "Link Empty to Track" bl_options = {'UNDO', 'REGISTER'} - def _link_track(self, context, track): + def _link_track(self, context, clip, tracking_object, track): sc = context.space_data constraint = None ob = None @@ -98,17 +143,21 @@ if constraint is None: constraint = ob.constraints.new(type='FOLLOW_TRACK') + constraint.use_active_clip = False constraint.clip = sc.clip constraint.track = track.name constraint.use_3d_position = False + constraint.object = tracking_object.name + constraint.camera = CLIP_camera_for_clip(context, clip) def execute(self, context): sc = context.space_data clip = sc.clip + tracking_object = clip.tracking.objects.active - for track in clip.tracking.tracks: + for track in tracking_object.tracks: if CLIP_track_view_selected(sc, track): - self._link_track(context, track) + self._link_track(context, clip, tracking_object, track) return {'FINISHED'} @@ -130,11 +179,12 @@ sc = context.space_data clip = sc.clip + tracking_object = clip.tracking.objects.active new_verts = [] mesh = bpy.data.meshes.new(name="Tracks") - for track in clip.tracking.tracks: + for track in tracking_object.tracks: if track.has_bundle: new_verts.append(track.bundle) @@ -188,7 +238,7 @@ proxydir = clip.proxy.directory else: clipdir = os.path.dirname(clip.filepath) - proxydir = os.path.join(clipdir, 'BL_proxy') + proxydir = os.path.join(clipdir, "BL_proxy") clipfile = os.path.basename(clip.filepath) proxy = os.path.join(proxydir, clipfile) @@ -196,15 +246,15 @@ # proxy_[_undostorted] for x in (25, 50, 75, 100): - d = os.path.join(absproxy, 'proxy_' + str(x)) + d = os.path.join(absproxy, "proxy_%d" % x) self._rmproxy(d) - self._rmproxy(d + '_undistorted') - self._rmproxy(os.path.join(absproxy, 'proxy_' + str(x) + '.avi')) + self._rmproxy(d + "_undistorted") + self._rmproxy(os.path.join(absproxy, "proxy_%d.avi" % x)) - tc = ('free_run.blen_tc', - 'interp_free_run.blen_tc', - 'record_run.blen_tc') + tc = ("free_run.blen_tc", + "interp_free_run.blen_tc", + "record_run.blen_tc") for x in tc: self._rmproxy(os.path.join(absproxy, x)) @@ -226,8 +276,8 @@ class CLIP_OT_set_viewport_background(Operator): - """Set current movie clip as a camera background in 3D viewport \ -(works only when a 3D viewport is visible)""" + """Set current movie clip as a camera background in 3D view-port """ \ + """(works only when a 3D view-port is visible)""" bl_idname = "clip.set_viewport_background" bl_label = "Set as Background" @@ -265,11 +315,11 @@ frame_current = scene.frame_current matrices = [] - # Find constraint which would eb converting + # Find constraint which would be converting # TODO: several camera solvers and track followers would fail, - # but can't think about eal workflow where it'll be useful + # but can't think about real work-flow where it'll be useful for x in ob.constraints: - if x.type in ('CAMERA_SOLVER', 'FOLLOW_TRACK'): + if x.type in {'CAMERA_SOLVER', 'FOLLOW_TRACK', 'OBJECT_SOLVER'}: con = x if not con: @@ -319,7 +369,7 @@ ob.animation_data_create() - # Apply matrices on object and insert keyframes + # Apply matrices on object and insert key-frames i = 0 for x in range(sfra, efra + 1): scene.frame_set(x) @@ -340,7 +390,8 @@ def execute(self, context): scene = context.scene - + # XXX, should probably use context.selected_editable_objects + # since selected objects can be from a lib or in hidden layer! for ob in scene.objects: if ob.select: self._bake_object(scene, ob) @@ -508,7 +559,7 @@ def setup_space(space): space.show_backdrop = True - CLIP_spacees_walk(context, True, 'NODE_EDITOR', 'NODE_EDITOR', + CLIP_spaces_walk(context, True, 'NODE_EDITOR', 'NODE_EDITOR', setup_space) sc = context.space_data @@ -741,7 +792,7 @@ all_layers = self._mergeLayers(fg.layers, bg.layers) - # enshure all lamps are active on foreground and background + # ensure all lamps are active on foreground and background has_lamp = False has_mesh = False for ob in scene.objects: @@ -783,3 +834,30 @@ self._setupObjects(context) return {'FINISHED'} + + +class CLIP_OT_track_settings_as_default(Operator): + """Copy tracking settings from active track to default settings""" + + bl_idname = "clip.track_settings_as_default" + bl_label = "Track Settings As Default" + bl_options = {'UNDO', 'REGISTER'} + + @classmethod + def poll(cls, context): + sc = context.space_data + + if sc.type != 'CLIP_EDITOR': + return False + + clip = sc.clip + + return clip and clip.tracking.tracks.active + + def execute(self, context): + sc = context.space_data + clip = sc.clip + + CLIP_default_settings_from_track(clip, clip.tracking.tracks.active) + + return {'FINISHED'} diff -Nru blender-2.61/release/scripts/startup/bl_operators/image.py blender-2.62/release/scripts/startup/bl_operators/image.py --- blender-2.61/release/scripts/startup/bl_operators/image.py 2011-12-13 19:43:21.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_operators/image.py 2012-02-15 19:27:33.000000000 +0000 @@ -128,7 +128,7 @@ class ProjectEdit(Operator): - """Edit a snapshot of the viewport in an external image editor""" + """Edit a snapshot of the view-port in an external image editor""" bl_idname = "image.project_edit" bl_label = "Project Edit" bl_options = {'REGISTER'} diff -Nru blender-2.61/release/scripts/startup/bl_operators/mesh.py blender-2.62/release/scripts/startup/bl_operators/mesh.py --- blender-2.61/release/scripts/startup/bl_operators/mesh.py 2011-12-13 19:43:21.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_operators/mesh.py 2012-02-15 19:27:33.000000000 +0000 @@ -25,7 +25,7 @@ class MeshSelectInteriorFaces(Operator): - '''Select faces where all edges have more then 2 face users''' + '''Select faces where all edges have more than 2 face users''' bl_idname = "mesh.faces_select_interior" bl_label = "Select Interior Faces" diff -Nru blender-2.61/release/scripts/startup/bl_operators/object.py blender-2.62/release/scripts/startup/bl_operators/object.py --- blender-2.61/release/scripts/startup/bl_operators/object.py 2011-12-13 19:43:21.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_operators/object.py 2012-02-15 19:27:33.000000000 +0000 @@ -20,7 +20,10 @@ import bpy from bpy.types import Operator -from bpy.props import StringProperty, BoolProperty, EnumProperty, IntProperty +from bpy.props import (StringProperty, + BoolProperty, + EnumProperty, + IntProperty) class SelectPattern(Operator): @@ -54,7 +57,7 @@ pattern_match = fnmatch.fnmatchcase else: pattern_match = (lambda a, b: - fnmatch.fnmatchcase(a.upper(), b.upper())) + fnmatch.fnmatchcase(a.upper(), b.upper())) is_ebone = False obj = context.object if obj and obj.mode == 'POSE': @@ -331,8 +334,8 @@ orig_shape_coords = me_cos(ob_act.active_shape_key.data) orig_normals = me_nos(me.vertices) - # the actual mverts location isn't as reliable as the base shape :S - # orig_coords = me_cos(me.vertices) + # actual mesh vertex location isn't as reliable as the base shape :S + #~ orig_coords = me_cos(me.vertices) orig_coords = me_cos(me.shape_keys.key_blocks[0].data) for ob_other in objects: @@ -489,9 +492,9 @@ return (obj and obj.mode != 'EDIT') def execute(self, context): - C = bpy.context - ob_act = C.active_object - objects = [ob for ob in C.selected_editable_objects if ob != ob_act] + ob_act = context.active_object + objects = [ob for ob in context.selected_editable_objects + if ob != ob_act] if 1: # swap from/to, means we cant copy to many at once. if len(objects) != 1: @@ -585,11 +588,6 @@ bl_idname = "object.make_dupli_face" bl_label = "Make Dupli-Face" - @classmethod - def poll(cls, context): - obj = context.active_object - return (obj and obj.type == 'MESH') - def _main(self, context): from mathutils import Vector @@ -601,22 +599,22 @@ Vector((-offset, +offset, 0.0)), ) - def matrix_to_quat(matrix): + def matrix_to_quad(matrix): # scale = matrix.median_scale trans = matrix.to_translation() rot = matrix.to_3x3() # also contains scale return [(rot * b) + trans for b in base_tri] - scene = bpy.context.scene + scene = context.scene linked = {} - for obj in bpy.context.selected_objects: + for obj in context.selected_objects: data = obj.data if data: linked.setdefault(data, []).append(obj) for data, objects in linked.items(): face_verts = [axis for obj in objects - for v in matrix_to_quat(obj.matrix_world) + for v in matrix_to_quad(obj.matrix_world) for axis in v] faces = list(range(len(face_verts) // 3)) @@ -655,8 +653,8 @@ class IsolateTypeRender(Operator): - '''Hide unselected render objects of same type as active ''' \ - '''by setting the hide render flag''' + """Hide unselected render objects of same type as active """ \ + """by setting the hide render flag""" bl_idname = "object.isolate_type_render" bl_label = "Restrict Render Unselected" bl_options = {'REGISTER', 'UNDO'} diff -Nru blender-2.61/release/scripts/startup/bl_operators/object_randomize_transform.py blender-2.62/release/scripts/startup/bl_operators/object_randomize_transform.py --- blender-2.61/release/scripts/startup/bl_operators/object_randomize_transform.py 2011-12-13 19:43:21.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_operators/object_randomize_transform.py 2012-02-15 19:27:33.000000000 +0000 @@ -49,7 +49,7 @@ rotation_mode = obj.rotation_mode if rotation_mode in {'QUATERNION', 'AXIS_ANGLE'}: obj.rotation_mode = 'XYZ' - + if delta: obj.delta_rotation_euler[0] += vec[0] obj.delta_rotation_euler[1] += vec[1] diff -Nru blender-2.61/release/scripts/startup/bl_operators/presets.py blender-2.62/release/scripts/startup/bl_operators/presets.py --- blender-2.61/release/scripts/startup/bl_operators/presets.py 2011-12-13 19:43:21.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_operators/presets.py 2012-02-15 19:27:33.000000000 +0000 @@ -35,10 +35,11 @@ name="Name", description="Name of the preset, used to make the path name", maxlen=64, + options={'SKIP_SAVE'}, ) remove_active = bpy.props.BoolProperty( default=False, - options={'HIDDEN'}, + options={'HIDDEN', 'SKIP_SAVE'}, ) @staticmethod @@ -55,6 +56,13 @@ preset_menu_class = getattr(bpy.types, self.preset_menu) + is_xml = getattr(preset_menu_class, "preset_type", None) == 'XML' + + if is_xml: + ext = ".xml" + else: + ext = ".py" + if not self.remove_active: name = self.name.strip() if not name: @@ -71,31 +79,40 @@ self.report({'WARNING'}, "Failed to create presets path") return {'CANCELLED'} - filepath = os.path.join(target_path, filename) + ".py" + filepath = os.path.join(target_path, filename) + ext if hasattr(self, "add"): self.add(context, filepath) else: - file_preset = open(filepath, 'w') - file_preset.write("import bpy\n") + print("Writing Preset: %r" % filepath) - if hasattr(self, "preset_defines"): - for rna_path in self.preset_defines: - exec(rna_path) - file_preset.write("%s\n" % rna_path) - file_preset.write("\n") - - for rna_path in self.preset_values: - value = eval(rna_path) - # convert thin wrapped sequences to simple lists to repr() - try: - value = value[:] - except: - pass + if is_xml: + import rna_xml + rna_xml.xml_file_write(context, + filepath, + preset_menu_class.preset_xml_map) + else: + file_preset = open(filepath, 'w') + file_preset.write("import bpy\n") + + if hasattr(self, "preset_defines"): + for rna_path in self.preset_defines: + exec(rna_path) + file_preset.write("%s\n" % rna_path) + file_preset.write("\n") + + for rna_path in self.preset_values: + value = eval(rna_path) + # convert thin wrapped sequences + # to simple lists to repr() + try: + value = value[:] + except: + pass - file_preset.write("%s = %r\n" % (rna_path, value)) + file_preset.write("%s = %r\n" % (rna_path, value)) - file_preset.close() + file_preset.close() preset_menu_class.bl_label = bpy.path.display_name(filename) @@ -103,12 +120,15 @@ preset_active = preset_menu_class.bl_label # fairly sloppy but convenient. - filepath = bpy.utils.preset_find(preset_active, self.preset_subdir) + filepath = bpy.utils.preset_find(preset_active, + self.preset_subdir, + ext=ext) if not filepath: filepath = bpy.utils.preset_find(preset_active, self.preset_subdir, - display_name=True) + display_name=True, + ext=ext) if not filepath: return {'CANCELLED'} @@ -157,15 +177,27 @@ ) def execute(self, context): - from os.path import basename + from os.path import basename, splitext filepath = self.filepath # change the menu title to the most recently chosen option preset_class = getattr(bpy.types, self.menu_idname) preset_class.bl_label = bpy.path.display_name(basename(filepath)) + ext = splitext(filepath)[1].lower() + # execute the preset using script.python_file_run - bpy.ops.script.python_file_run(filepath=filepath) + if ext == ".py": + bpy.ops.script.python_file_run(filepath=filepath) + elif ext == ".xml": + import rna_xml + rna_xml.xml_file_run(context, + filepath, + preset_class.preset_xml_map) + else: + self.report({'ERROR'}, "unknown filetype: %r" % ext) + return {'CANCELLED'} + return {'FINISHED'} @@ -378,14 +410,25 @@ "settings.default_search_size", "settings.default_frames_limit", "settings.default_pattern_match", - "settings.default_margin" + "settings.default_margin", + "settings.use_default_red_channel", + "settings.use_default_green_channel", + "settings.use_default_blue_channel" ] preset_subdir = "tracking_settings" +class AddPresetInterfaceTheme(AddPresetBase, Operator): + '''Add a theme preset''' + bl_idname = "wm.interface_theme_preset_add" + bl_label = "Add Tracking Settings Preset" + preset_menu = "USERPREF_MT_interface_theme_presets" + preset_subdir = "interface_theme" + + class AddPresetKeyconfig(AddPresetBase, Operator): - '''Add a Keyconfig Preset''' + '''Add a Key-config Preset''' bl_idname = "wm.keyconfig_preset_add" bl_label = "Add Keyconfig Preset" preset_menu = "USERPREF_MT_keyconfigs" diff -Nru blender-2.61/release/scripts/startup/bl_operators/sequencer.py blender-2.62/release/scripts/startup/bl_operators/sequencer.py --- blender-2.61/release/scripts/startup/bl_operators/sequencer.py 2011-12-13 19:43:21.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_operators/sequencer.py 2012-02-15 19:27:33.000000000 +0000 @@ -25,7 +25,7 @@ class SequencerCrossfadeSounds(Operator): - '''Do crossfading volume animation of two selected sound strips''' + '''Do cross-fading volume animation of two selected sound strips''' bl_idname = "sequencer.crossfade_sounds" bl_label = "Crossfade sounds" @@ -60,14 +60,14 @@ if seq1.frame_final_end > seq2.frame_final_start: tempcfra = context.scene.frame_current context.scene.frame_current = seq2.frame_final_start - seq1.keyframe_insert('volume') + seq1.keyframe_insert("volume") context.scene.frame_current = seq1.frame_final_end seq1.volume = 0 - seq1.keyframe_insert('volume') - seq2.keyframe_insert('volume') + seq1.keyframe_insert("volume") + seq2.keyframe_insert("volume") context.scene.frame_current = seq2.frame_final_start seq2.volume = 0 - seq2.keyframe_insert('volume') + seq2.keyframe_insert("volume") context.scene.frame_current = tempcfra return {'FINISHED'} else: @@ -76,7 +76,7 @@ class SequencerCutMulticam(Operator): - '''Cut multicam strip and select camera''' + '''Cut multi-cam strip and select camera''' bl_idname = "sequencer.cut_multicam" bl_label = "Cut multicam" diff -Nru blender-2.61/release/scripts/startup/bl_operators/uvcalc_follow_active.py blender-2.62/release/scripts/startup/bl_operators/uvcalc_follow_active.py --- blender-2.61/release/scripts/startup/bl_operators/uvcalc_follow_active.py 2011-12-13 19:43:21.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_operators/uvcalc_follow_active.py 2012-02-15 19:27:33.000000000 +0000 @@ -99,7 +99,7 @@ iA = 1 iB = 0 - # Set the target UV's touching source face, no tricky calc needed, + # Set the target UV's touching source face, no tricky calculations needed, uvs_vhash_target[edgepair_inner_target[0]][:] = uvs_vhash_source[edgepair_inner_source[iA]] uvs_vhash_target[edgepair_inner_target[1]][:] = uvs_vhash_source[edgepair_inner_source[iB]] @@ -156,8 +156,8 @@ return # Modes - # 0 unsearched - # 1:mapped, use search from this face. - removed!! + # 0 not yet searched for. + # 1:mapped, use search from this face - removed! # 2:all siblings have been searched. don't search again. face_modes = [0] * len(face_sel) face_modes[face_act_local_index] = 1 # extend UV's from this face. diff -Nru blender-2.61/release/scripts/startup/bl_operators/uvcalc_lightmap.py blender-2.62/release/scripts/startup/bl_operators/uvcalc_lightmap.py --- blender-2.61/release/scripts/startup/bl_operators/uvcalc_lightmap.py 2011-12-13 19:43:21.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_operators/uvcalc_lightmap.py 2012-02-15 19:27:33.000000000 +0000 @@ -246,10 +246,10 @@ pretty_faces = [prettyface(f) for f in face_sel if len(f.vertices) == 4] - # Do we have any tri's + # Do we have any triangles? if len(pretty_faces) != len(face_sel): - # Now add tri's, not so simple because we need to pair them up. + # Now add triangles, not so simple because we need to pair them up. def trylens(f): # f must be a tri diff -Nru blender-2.61/release/scripts/startup/bl_operators/uvcalc_smart_project.py blender-2.62/release/scripts/startup/bl_operators/uvcalc_smart_project.py --- blender-2.61/release/scripts/startup/bl_operators/uvcalc_smart_project.py 2011-12-13 19:43:21.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_operators/uvcalc_smart_project.py 2012-02-15 19:27:33.000000000 +0000 @@ -71,7 +71,7 @@ mtx = Matrix((side1, side2, nor)) - # Zero area 2d tri, even tho we throw away zerop area faces + # Zero area 2d tri, even tho we throw away zero area faces # the projection UV can result in a zero area UV. if not mtx.determinant(): dict_matrix[key] = None @@ -162,7 +162,7 @@ return length_sorted_edges, [v.to_3d() for v in unique_points.values()] # ========================= NOT WORKING???? -# Find if a points inside an edge loop, un-ordered. +# Find if a points inside an edge loop, unordered. # pt is and x/y # edges are a non ordered loop of edges. # offsets are the edge x and y offset. @@ -756,7 +756,7 @@ class thickface(object): - __slost__= 'v', 'uv', 'no', 'area', 'edge_keys' + __slost__= "v", "uv", "no", "area", "edge_keys" def __init__(self, face, uvface, mesh_verts): self.v = [mesh_verts[i] for i in face.vertices] if len(self.v)==4: diff -Nru blender-2.61/release/scripts/startup/bl_operators/vertexpaint_dirt.py blender-2.62/release/scripts/startup/bl_operators/vertexpaint_dirt.py --- blender-2.61/release/scripts/startup/bl_operators/vertexpaint_dirt.py 2011-12-13 19:43:21.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_operators/vertexpaint_dirt.py 2012-02-15 19:27:33.000000000 +0000 @@ -21,15 +21,6 @@ # -# History -# -# Originally written by Campbell Barton aka ideasman42 -# -# 2009-11-01: * 2.5 port by Keith "Wahooney" Boshoff -# * Replaced old method with my own, speed is similar (about 0.001 sec on Suzanne) -# but results are far more accurate -# - def applyVertexDirt(me, blur_iterations, blur_strength, clamp_dirt, clamp_clean, dirt_only): from mathutils import Vector diff -Nru blender-2.61/release/scripts/startup/bl_operators/wm.py blender-2.62/release/scripts/startup/bl_operators/wm.py --- blender-2.61/release/scripts/startup/bl_operators/wm.py 2011-12-13 19:43:21.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_operators/wm.py 2012-02-15 19:27:33.000000000 +0000 @@ -29,6 +29,9 @@ from rna_prop_ui import rna_idprop_ui_prop_get, rna_idprop_ui_prop_clear +import subprocess +import os + class MESH_OT_delete_edgeloop(Operator): '''Delete an edge loop by merging the faces on each side to a single face loop''' @@ -163,9 +166,10 @@ if attr is None: return {'CANCELLED'} + toolsettings = context.tool_settings for i, brush in enumerate((cur for cur in bpy.data.brushes if getattr(cur, attr))): if i == self.index: - getattr(context.tool_settings, self.mode).brush = brush + getattr(toolsettings, self.mode).brush = brush return {'FINISHED'} return {'CANCELLED'} @@ -393,7 +397,7 @@ exec("context.%s = value" % data_path) if value != eval("context.%s" % data_path): - # relies on rna clamping int's out of the range + # relies on rna clamping integers out of the range if self.reverse: value = (1 << 31) - 1 else: @@ -499,9 +503,9 @@ values = [(i.name, i.identifier) for i in value_base.bl_rna.properties[prop_string].enum_items] for name, identifier in values: - prop = self.layout.operator("wm.context_set_enum", text=name) - prop.data_path = data_path - prop.value = identifier + props = self.layout.operator("wm.context_set_enum", text=name) + props.data_path = data_path + props.value = identifier class WM_OT_context_menu_enum(Operator): @@ -727,7 +731,7 @@ class WM_OT_url_open(Operator): - "Open a website in the Webbrowser" + "Open a website in the web-browser" bl_idname = "wm.url_open" bl_label = "" @@ -764,12 +768,12 @@ return {'CANCELLED'} if sys.platform[:3] == "win": - subprocess.Popen(['start', filepath], shell=True) - elif sys.platform == 'darwin': - subprocess.Popen(['open', filepath]) + subprocess.Popen(["start", filepath], shell=True) + elif sys.platform == "darwin": + subprocess.Popen(["open", filepath]) else: try: - subprocess.Popen(['xdg-open', filepath]) + subprocess.Popen(["xdg-open", filepath]) except OSError: # xdg-open *should* be supported by recent Gnome, KDE, Xfce pass @@ -845,8 +849,8 @@ print("sending data:", data_dict) import xmlrpc.client - user = 'blenderuser' - pwd = 'blender>user' + user = "blenderuser" + pwd = "blender>user" docblog = xmlrpc.client.ServerProxy(self._url) docblog.metaWeblog.newPost(1, user, pwd, data_dict, 1) @@ -984,9 +988,8 @@ prop_ui = rna_idprop_ui_prop_get(item, prop) if prop_type in {float, int}: - - prop_ui['soft_min'] = prop_ui['min'] = prop_type(self.min) - prop_ui['soft_max'] = prop_ui['max'] = prop_type(self.max) + prop_ui["soft_min"] = prop_ui["min"] = prop_type(self.min) + prop_ui["soft_max"] = prop_ui["max"] = prop_type(self.max) prop_ui['description'] = self.description @@ -1033,7 +1036,7 @@ item = eval("context.%s" % data_path) def unique_name(names): - prop = 'prop' + prop = "prop" prop_new = prop i = 1 while prop_new in names: @@ -1161,10 +1164,10 @@ # in 2.57 and earlier windows installers, system scripts were copied # into the configuration directory, don't want to copy those - system_script = os.path.join(path_dst, 'scripts/modules/bpy_types.py') + system_script = os.path.join(path_dst, "scripts/modules/bpy_types.py") if os.path.isfile(system_script): - shutil.rmtree(os.path.join(path_dst, 'scripts')) - shutil.rmtree(os.path.join(path_dst, 'plugins')) + shutil.rmtree(os.path.join(path_dst, "scripts")) + shutil.rmtree(os.path.join(path_dst, "plugins")) # don't loose users work if they open the splash later. if bpy.data.is_saved is bpy.data.is_dirty is False: @@ -1176,8 +1179,30 @@ return {'CANCELLED'} +class WM_OT_blenderplayer_start(Operator): + '''Launch the blender-player with the current blend-file''' + bl_idname = "wm.blenderplayer_start" + bl_label = "Start" + + blender_bin_path = bpy.app.binary_path + blender_bin_dir = os.path.dirname(blender_bin_path) + ext = os.path.splitext(blender_bin_path)[-1] + player_path = os.path.join(blender_bin_dir, "blenderplayer" + ext) + + def execute(self, context): + import sys + + if sys.platform == "darwin": + self.player_path = os.path.join(self.blender_bin_dir, "../../../blenderplayer.app/Contents/MacOS/blenderplayer") + + filepath = bpy.app.tempdir + "game.blend" + bpy.ops.wm.save_as_mainfile(filepath=filepath, check_existing=False, copy=True) + subprocess.call([self.player_path, filepath]) + return {'FINISHED'} + + class WM_OT_keyconfig_test(Operator): - "Test keyconfig for conflicts" + "Test key-config for conflicts" bl_idname = "wm.keyconfig_test" bl_label = "Test Key Configuration for Conflicts" @@ -1429,7 +1454,7 @@ for op_submodule_name in dir(op_module): op = getattr(op_module, op_submodule_name) text = repr(op) - if text.split("\n")[-1].startswith('bpy.ops.'): + if text.split("\n")[-1].startswith("bpy.ops."): op_strings.append(text) tot += 1 @@ -1442,6 +1467,9 @@ return {'FINISHED'} +# ----------------------------------------------------------------------------- +# Addon Operators + class WM_OT_addon_enable(Operator): "Enable an addon" bl_idname = "wm.addon_enable" diff -Nru blender-2.61/release/scripts/startup/bl_ui/__init__.py blender-2.62/release/scripts/startup/bl_ui/__init__.py --- blender-2.61/release/scripts/startup/bl_ui/__init__.py 2011-12-13 19:43:16.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_ui/__init__.py 2012-02-15 19:27:28.000000000 +0000 @@ -86,7 +86,7 @@ # space_userprefs.py from bpy.props import StringProperty, EnumProperty - WindowManager = bpy.types.WindowManager + from bpy.types import WindowManager def addon_filter_items(self, context): import addon_utils diff -Nru blender-2.61/release/scripts/startup/bl_ui/properties_data_curve.py blender-2.62/release/scripts/startup/bl_ui/properties_data_curve.py --- blender-2.61/release/scripts/startup/bl_ui/properties_data_curve.py 2011-12-13 19:43:16.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_ui/properties_data_curve.py 2012-02-15 19:27:28.000000000 +0000 @@ -111,7 +111,7 @@ sub = col.column() sub.active = (curve.dimensions == '2D' or (curve.bevel_object is None and curve.dimensions == '3D')) sub.prop(curve, "fill_mode", text="") - col.prop(curve, "use_fill_deform", text="Fill Deformed") + col.prop(curve, "use_fill_deform") class DATA_PT_curve_texture_space(CurveButtonsPanel, Panel): @@ -165,6 +165,10 @@ col.label(text="Bevel Object:") col.prop(curve, "bevel_object", text="") + row = col.row() + row.active = (curve.bevel_object is not None) + row.prop(curve, "use_fill_caps") + class DATA_PT_pathanim(CurveButtonsPanelCurve, Panel): bl_label = "Path Animation" @@ -213,13 +217,12 @@ if is_poly: # These settings are below but its easier to have - # poly's set aside since they use so few settings - col = split.column() - col.label(text="Cyclic:") - col.prop(act_spline, "use_smooth") - col = split.column() - col.prop(act_spline, "use_cyclic_u", text="U") + # polys set aside since they use so few settings + row = layout.row() + row.label(text="Cyclic:") + row.prop(act_spline, "use_cyclic_u", text="U") + layout.prop(act_spline, "use_smooth") else: col = split.column() col.label(text="Cyclic:") @@ -247,7 +250,7 @@ col = split.column() col.prop(act_spline, "use_cyclic_v", text="V") - # its a surface, assume its a nurb. + # its a surface, assume its a nurbs sub = col.column() sub.active = (not act_spline.use_cyclic_v) sub.prop(act_spline, "use_bezier_v", text="V") @@ -257,13 +260,13 @@ sub.prop(act_spline, "resolution_v", text="V") if not is_surf: - split = layout.split() - col = split.column() - + col = layout.column() col.label(text="Interpolation:") - colsub = col.column() - colsub.active = (curve.dimensions == '3D') - colsub.prop(act_spline, "tilt_interpolation", text="Tilt") + + sub = col.column() + sub.active = (curve.dimensions == '3D') + sub.prop(act_spline, "tilt_interpolation", text="Tilt") + col.prop(act_spline, "radius_interpolation", text="Radius") layout.prop(act_spline, "use_smooth") diff -Nru blender-2.61/release/scripts/startup/bl_ui/properties_data_mesh.py blender-2.62/release/scripts/startup/bl_ui/properties_data_mesh.py --- blender-2.61/release/scripts/startup/bl_ui/properties_data_mesh.py 2011-12-13 19:43:16.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_ui/properties_data_mesh.py 2012-02-15 19:27:28.000000000 +0000 @@ -158,7 +158,7 @@ row = layout.row() row.prop(group, "name") - if ob.mode == 'EDIT' and len(ob.vertex_groups) > 0: + if ob.vertex_groups and (ob.mode == 'EDIT' or (ob.mode == 'WEIGHT_PAINT' and ob.type == 'MESH' and ob.data.use_paint_mask_vertex)): row = layout.row() sub = row.row(align=True) @@ -226,10 +226,10 @@ row.alignment = 'RIGHT' sub = row.row(align=True) + sub.label() # XXX, for alignment only subsub = sub.row(align=True) subsub.active = enable_edit_value subsub.prop(ob, "show_only_shape_key", text="") - subsub.prop(kb, "mute", text="") sub.prop(ob, "use_shape_key_edit_mode", text="") sub = row.row() diff -Nru blender-2.61/release/scripts/startup/bl_ui/properties_data_modifier.py blender-2.62/release/scripts/startup/bl_ui/properties_data_modifier.py --- blender-2.61/release/scripts/startup/bl_ui/properties_data_modifier.py 2011-12-13 19:43:16.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_ui/properties_data_modifier.py 2012-02-15 19:27:28.000000000 +0000 @@ -587,11 +587,10 @@ layout.prop(md, "use_keep_above_surface") def SIMPLE_DEFORM(self, layout, ob, md): - split = layout.split() - col = split.column() - col.label(text="Mode:") - col.prop(md, "deform_method", text="") + layout.row().prop(md, "deform_method", expand=True) + + split = layout.split() col = split.column() col.label(text="Vertex Group:") @@ -610,7 +609,7 @@ col.label(text="Deform:") col.prop(md, "factor") col.prop(md, "limits", slider=True) - if md.deform_method in {'TAPER', 'STRETCH'}: + if md.deform_method in {'TAPER', 'STRETCH', 'TWIST'}: col.prop(md, "lock_x") col.prop(md, "lock_y") @@ -813,6 +812,21 @@ col.prop(md, "width", slider=True) col.prop(md, "narrowness", slider=True) + def REMESH(self, layout, ob, md): + layout.prop(md, "mode") + + row = layout.row() + row.prop(md, "octree_depth") + row.prop(md, "scale") + + if md.mode == 'SHARP': + layout.prop(md, "sharpness") + + layout.prop(md, "remove_disconnected_pieces") + row = layout.row() + row.active = md.remove_disconnected_pieces + row.prop(md, "threshold") + @staticmethod def vertex_weight_mask(layout, ob, md): layout.label(text="Influence/Mask Options:") diff -Nru blender-2.61/release/scripts/startup/bl_ui/properties_game.py blender-2.62/release/scripts/startup/bl_ui/properties_game.py --- blender-2.61/release/scripts/startup/bl_ui/properties_game.py 2011-12-13 19:43:16.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_ui/properties_game.py 2012-02-15 19:27:28.000000000 +0000 @@ -244,16 +244,23 @@ return (rd.engine in cls.COMPAT_ENGINES) -class RENDER_PT_game(RenderButtonsPanel, Panel): - bl_label = "Game" +class RENDER_PT_embedded(RenderButtonsPanel, Panel): + bl_label = "Embedded Player" COMPAT_ENGINES = {'BLENDER_GAME'} def draw(self, context): layout = self.layout + rd = context.scene.render + row = layout.row() row.operator("view3d.game_start", text="Start") row.label() + row = layout.row() + row.label(text="Resolution:") + row = layout.row(align=True) + row.prop(rd, "resolution_x", slider=False, text="X") + row.prop(rd, "resolution_y", slider=False, text="Y") class RENDER_PT_game_player(RenderButtonsPanel, Panel): @@ -265,28 +272,28 @@ gs = context.scene.game_settings - layout.prop(gs, "show_fullscreen") - - split = layout.split() - - col = split.column() - col.label(text="Resolution:") - sub = col.column(align=True) - sub.prop(gs, "resolution_x", slider=False, text="X") - sub.prop(gs, "resolution_y", slider=False, text="Y") + row = layout.row() + row.operator("wm.blenderplayer_start", text="Start") + row.label() - col = split.column() - col.label(text="Quality:") - sub = col.column(align=True) - sub.prop(gs, "depth", text="Bit Depth", slider=False) - sub.prop(gs, "frequency", text="FPS", slider=False) + row = layout.row() + row.label(text="Resolution:") + row = layout.row(align=True) + row.prop(gs, "resolution_x", slider=False, text="X") + row.prop(gs, "resolution_y", slider=False, text="Y") + row = layout.row() + col = row.column() + col.prop(gs, "show_fullscreen") + col = row.column() + col.prop(gs, "use_desktop") + col.active = gs.show_fullscreen - # framing: col = layout.column() - col.label(text="Framing:") - col.row().prop(gs, "frame_type", expand=True) - if gs.frame_type == 'LETTERBOX': - col.prop(gs, "frame_color", text="") + col.label(text="Quality:") + col.prop(gs, "samples") + col = layout.column(align=True) + col.prop(gs, "depth", text="Bit Depth", slider=False) + col.prop(gs, "frequency", text="Refresh Rate", slider=False) class RENDER_PT_game_stereo(RenderButtonsPanel, Panel): @@ -368,20 +375,24 @@ col.prop(gs, "use_glsl_extra_textures", text="Extra Textures") -class RENDER_PT_game_performance(RenderButtonsPanel, Panel): - bl_label = "Performance" +class RENDER_PT_game_system(RenderButtonsPanel, Panel): + bl_label = "System" COMPAT_ENGINES = {'BLENDER_GAME'} def draw(self, context): layout = self.layout gs = context.scene.game_settings - col = layout.column() - row = col.row() + row = layout.row() row.prop(gs, "use_frame_rate") + row.prop(gs, "restrict_animation_updates") + + row = layout.row() row.prop(gs, "use_display_lists") - col.prop(gs, "restrict_animation_updates") + row = layout.row() + row.label("Exit Key") + row.prop(gs, "exit_key", text="", event=True) class RENDER_PT_game_display(RenderButtonsPanel, Panel): @@ -391,6 +402,9 @@ def draw(self, context): layout = self.layout + row = layout.row() + row.prop(context.scene.render, "fps", text="Animation Frame Rate", slider=False) + gs = context.scene.game_settings flow = layout.column_flow() flow.prop(gs, "show_debug_properties", text="Debug Properties") @@ -399,6 +413,12 @@ flow.prop(gs, "use_deprecation_warnings") flow.prop(gs, "show_mouse", text="Mouse Cursor") + col = layout.column() + col.label(text="Framing:") + col.row().prop(gs, "frame_type", expand=True) + if gs.frame_type == 'LETTERBOX': + col.prop(gs, "frame_color", text="") + class SceneButtonsPanel(): bl_space_type = 'PROPERTIES' @@ -464,6 +484,22 @@ row.prop(rd, "sample_max_error") +class RENDER_PT_game_sound(RenderButtonsPanel, Panel): + bl_label = "Sound" + COMPAT_ENGINES = {'BLENDER_GAME'} + + def draw(self, context): + layout = self.layout + + scene = context.scene + + layout.prop(scene, "audio_distance_model") + + col = layout.column(align=True) + col.prop(scene, "audio_doppler_speed", text="Speed") + col.prop(scene, "audio_doppler_factor") + + class WorldButtonsPanel(): bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' @@ -533,10 +569,14 @@ world = context.world layout.active = world.mist_settings.use_mist - row = layout.row() + row.prop(world.mist_settings, "falloff") + + row = layout.row(align=True) row.prop(world.mist_settings, "start") row.prop(world.mist_settings, "depth") + row = layout.row() + row.prop(world.mist_settings, "intensity", text="Minimum Intensity") class WORLD_PT_game_physics(WorldButtonsPanel, Panel): diff -Nru blender-2.61/release/scripts/startup/bl_ui/properties_object_constraint.py blender-2.62/release/scripts/startup/bl_ui/properties_object_constraint.py --- blender-2.61/release/scripts/startup/bl_ui/properties_object_constraint.py 2011-12-13 19:43:16.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_ui/properties_object_constraint.py 2012-02-15 19:27:28.000000000 +0000 @@ -434,25 +434,28 @@ def ACTION(self, context, layout, con): self.target_template(layout, con) - layout.prop(con, "action") + split = layout.split() - layout.prop(con, "transform_channel") + col = split.column() + col.label(text="From Target:") + col.prop(con, "transform_channel", text="") + col.prop(con, "target_space", text="") - split = layout.split() + col = split.column() + col.label(text="To Action:") + col.prop(con, "action", text="") - col = split.column(align=True) - col.label(text="Action Length:") - col.prop(con, "frame_start", text="Start") - col.prop(con, "frame_end", text="End") + split = layout.split() col = split.column(align=True) col.label(text="Target Range:") col.prop(con, "min", text="Min") col.prop(con, "max", text="Max") - row = layout.row() - row.label(text="Convert:") - row.prop(con, "target_space", text="") + col = split.column(align=True) + col.label(text="Action Range:") + col.prop(con, "frame_start", text="Start") + col.prop(con, "frame_end", text="End") def LOCKED_TRACK(self, context, layout, con): self.target_template(layout, con) @@ -755,7 +758,16 @@ col = layout.column() col.prop(con, "rotation_range", text="Pivot When") + @staticmethod + def _getConstraintClip(context, con): + if not con.use_active_clip: + return con.clip + else: + return context.scene.active_clip + def FOLLOW_TRACK(self, context, layout, con): + clip = self._getConstraintClip(context, con) + row = layout.row() row.prop(con, "use_active_clip") row.prop(con, "use_3d_position") @@ -763,7 +775,15 @@ if not con.use_active_clip: layout.prop(con, "clip") - layout.prop(con, "track") + if clip: + layout.prop_search(con, "object", clip.tracking, "objects", icon='OBJECT_DATA') + layout.prop_search(con, "track", clip.tracking, "tracks", icon='ANIM_DATA') + + layout.prop(con, "camera") + + row = layout.row() + row.active = not con.use_3d_position + row.prop(con, "depth_object") layout.operator("clip.constraint_to_fcurve") @@ -775,6 +795,26 @@ layout.operator("clip.constraint_to_fcurve") + def OBJECT_SOLVER(self, context, layout, con): + scene = context.scene + clip = self._getConstraintClip(context, con) + + layout.prop(con, "use_active_clip") + + if not con.use_active_clip: + layout.prop(con, "clip") + + if clip: + layout.prop_search(con, "object", clip.tracking, "objects", icon='OBJECT_DATA') + + layout.prop(con, "camera") + + row = layout.row() + row.operator("constraint.objectsolver_set_inverse") + row.operator("constraint.objectsolver_clear_inverse") + + layout.operator("clip.constraint_to_fcurve") + def SCRIPT(self, context, layout, con): layout.label("Blender 2.5 has no py-constraints") diff -Nru blender-2.61/release/scripts/startup/bl_ui/properties_object.py blender-2.62/release/scripts/startup/bl_ui/properties_object.py --- blender-2.61/release/scripts/startup/bl_ui/properties_object.py 2011-12-13 19:43:16.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_ui/properties_object.py 2012-02-15 19:27:28.000000000 +0000 @@ -181,9 +181,9 @@ col = split.column() col.prop(group, "dupli_offset", text="") - prop = col.operator("wm.context_set_value", text="From Cursor") - prop.data_path = "object.users_group[%d].dupli_offset" % index - prop.value = value + props = col.operator("wm.context_set_value", text="From Cursor") + props.data_path = "object.users_group[%d].dupli_offset" % index + props.value = value index += 1 diff -Nru blender-2.61/release/scripts/startup/bl_ui/properties_paint_common.py blender-2.62/release/scripts/startup/bl_ui/properties_paint_common.py --- blender-2.61/release/scripts/startup/bl_ui/properties_paint_common.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_ui/properties_paint_common.py 2012-02-15 19:27:28.000000000 +0000 @@ -0,0 +1,61 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the 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. +# +# ##### END GPL LICENSE BLOCK ##### + +# + + +class UnifiedPaintPanel(): + # subclass must set + # bl_space_type = 'IMAGE_EDITOR' + # bl_region_type = 'UI' + + @staticmethod + def paint_settings(context): + toolsettings = context.tool_settings + + if context.sculpt_object: + return toolsettings.sculpt + elif context.vertex_paint_object: + return toolsettings.vertex_paint + elif context.weight_paint_object: + return toolsettings.weight_paint + elif context.image_paint_object: + return toolsettings.image_paint + elif context.particle_edit_object: + return toolsettings.particle_edit + + return None + + @staticmethod + def unified_paint_settings(parent, context): + ups = context.tool_settings.unified_paint_settings + parent.label(text="Unified Settings:") + parent.prop(ups, "use_unified_size", text="Size") + parent.prop(ups, "use_unified_strength", text="Strength") + + @staticmethod + def prop_unified_size(parent, context, brush, prop_name, icon='NONE', text="", slider=False): + ups = context.tool_settings.unified_paint_settings + ptr = ups if ups.use_unified_size else brush + parent.prop(ptr, prop_name, icon=icon, text=text, slider=slider) + + @staticmethod + def prop_unified_strength(parent, context, brush, prop_name, icon='NONE', text="", slider=False): + ups = context.tool_settings.unified_paint_settings + ptr = ups if ups.use_unified_strength else brush + parent.prop(ptr, prop_name, icon=icon, text=text, slider=slider) diff -Nru blender-2.61/release/scripts/startup/bl_ui/properties_particle.py blender-2.62/release/scripts/startup/bl_ui/properties_particle.py --- blender-2.61/release/scripts/startup/bl_ui/properties_particle.py 2011-12-13 19:43:16.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_ui/properties_particle.py 2012-02-15 19:27:28.000000000 +0000 @@ -76,7 +76,7 @@ class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} @classmethod def poll(cls, context): @@ -86,6 +86,10 @@ def draw(self, context): layout = self.layout + if context.scene.render.engine == "BLENDER_GAME": + layout.label("Not available in the Game Engine") + return + ob = context.object psys = context.particle_system part = 0 @@ -907,7 +911,7 @@ col.prop_search(psys, "billboard_time_index_uv", ob.data, "uv_textures") split = layout.split(percentage=0.33) - split.label(text="Split uv's:") + split.label(text="Split UVs:") split.prop(part, "billboard_uv_split", text="Number of splits") if psys: diff -Nru blender-2.61/release/scripts/startup/bl_ui/properties_physics_cloth.py blender-2.62/release/scripts/startup/bl_ui/properties_physics_cloth.py --- blender-2.61/release/scripts/startup/bl_ui/properties_physics_cloth.py 2011-12-13 19:43:16.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_ui/properties_physics_cloth.py 2012-02-15 19:27:28.000000000 +0000 @@ -87,6 +87,7 @@ col.label(text="Damping:") col.prop(cloth, "spring_damping", text="Spring") col.prop(cloth, "air_damping", text="Air") + col.prop(cloth, "vel_damping", text="Velocity") col.prop(cloth, "use_pin_cloth", text="Pinning") sub = col.column() diff -Nru blender-2.61/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py blender-2.62/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py --- blender-2.61/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py 2011-12-13 19:43:16.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py 2012-02-15 19:27:28.000000000 +0000 @@ -137,11 +137,14 @@ # dissolve if surface_type == 'PAINT': split = layout.split(percentage=0.35) - split.label(text="Wetmap drying:") + split.prop(surface, "use_drying", text="Dry:") col = split.column() + col.active = surface.use_drying split = col.split(percentage=0.7) - split.prop(surface, "dry_speed", text="Time") + col = split.column(align=True) + col.prop(surface, "dry_speed", text="Time") + col.prop(surface, "color_dry_threshold") split.prop(surface, "use_dry_log", text="Slow") if surface_type != 'WAVE': @@ -179,7 +182,10 @@ col.prop(surface, "wave_spring") layout.separator() - layout.prop(surface, "brush_group", text="Brush Group") + layout.prop(surface, "brush_group") + row = layout.row() + row.prop(surface, "brush_influence_scale") + row.prop(surface, "brush_radius_scale") class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, Panel): @@ -209,7 +215,7 @@ # toggle active preview layout.prop(surface, "preview_id") - # paintmap output + # paint-map output row = layout.row() row.prop_search(surface, "output_name_a", ob.data, "vertex_colors", text="Paintmap layer: ") if surface.output_exists(object=ob, index=0): @@ -219,7 +225,7 @@ row.operator("dpaint.output_toggle", icon=ic, text="").output = 'A' - # wetmap output + # wet-map output row = layout.row() row.prop_search(surface, "output_name_b", ob.data, "vertex_colors", text="Wetmap layer: ") if surface.output_exists(object=ob, index=1): @@ -406,14 +412,14 @@ col.prop(brush, "paint_distance", text="Paint Distance") split = layout.row().split(percentage=0.4) sub = split.column() - if brush.paint_source == 'DISTANCE': + if brush.paint_source in {'DISTANCE', 'VOLUME_DISTANCE'}: sub.prop(brush, "use_proximity_project") - elif brush.paint_source == 'VOLUME_DISTANCE': + if brush.paint_source == 'VOLUME_DISTANCE': sub.prop(brush, "invert_proximity") sub.prop(brush, "use_negative_volume") sub = split.column() - if brush.paint_source == 'DISTANCE': + if brush.paint_source in {'DISTANCE', 'VOLUME_DISTANCE'}: column = sub.column() column.active = brush.use_proximity_project column.prop(brush, "ray_direction") diff -Nru blender-2.61/release/scripts/startup/bl_ui/properties_physics_fluid.py blender-2.62/release/scripts/startup/bl_ui/properties_physics_fluid.py --- blender-2.61/release/scripts/startup/bl_ui/properties_physics_fluid.py 2011-12-13 19:43:16.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_ui/properties_physics_fluid.py 2012-02-15 19:27:28.000000000 +0000 @@ -56,6 +56,7 @@ layout.active = fluid.use if fluid.type == 'DOMAIN': + # odd formatting here so translation script can extract string layout.operator("fluid.bake", text="Bake (Req. Memory:" + " %s)" % fluid.memory_estimate, icon='MOD_FLUIDSIM') split = layout.split() @@ -78,11 +79,13 @@ sub = col.column(align=True) sub.prop(fluid, "start_time", text="Start") sub.prop(fluid, "end_time", text="End") + col.prop(fluid, "simulation_rate", text="Speed") col = split.column() col.label() col.prop(fluid, "use_speed_vectors") col.prop(fluid, "use_reverse_frames") + col.prop(fluid, "frame_offset", text="Offset") layout.prop(fluid, "filepath", text="") @@ -229,6 +232,10 @@ if fluid.viscosity_preset == 'MANUAL': sub.prop(fluid, "viscosity_base", text="Base") sub.prop(fluid, "viscosity_exponent", text="Exponent", slider=True) + else: + # just for padding to prevent jumping around + sub.separator() + sub.separator() col.label(text="Optimization:") col.prop(fluid, "grid_levels", slider=True) diff -Nru blender-2.61/release/scripts/startup/bl_ui/properties_render.py blender-2.62/release/scripts/startup/bl_ui/properties_render.py --- blender-2.61/release/scripts/startup/bl_ui/properties_render.py 2011-12-13 19:43:16.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_ui/properties_render.py 2012-02-15 19:27:28.000000000 +0000 @@ -51,7 +51,7 @@ @classmethod def poll(cls, context): rd = context.scene.render - return (context.scene and rd.use_game_engine is False) and (rd.engine in cls.COMPAT_ENGINES) + return context.scene and (rd.engine in cls.COMPAT_ENGINES) class RENDER_PT_render(RenderButtonsPanel, Panel): @@ -316,6 +316,9 @@ col = split.column() col.prop(rd, "use_raytrace", text="Ray Tracing") col.prop(rd, "use_color_management") + sub = col.row() + sub.active = rd.use_color_management == True + sub.prop(rd, "use_color_unpremultiply") col.prop(rd, "alpha_mode", text="Alpha") @@ -416,6 +419,12 @@ layout.active = rd.use_stamp + layout.prop(rd, "stamp_font_size", text="Font Size") + + row = layout.row() + row.column().prop(rd, "stamp_foreground", slider=True) + row.column().prop(rd, "stamp_background", slider=True) + split = layout.split() col = split.column() @@ -424,19 +433,14 @@ col.prop(rd, "use_stamp_render_time", text="RenderTime") col.prop(rd, "use_stamp_frame", text="Frame") col.prop(rd, "use_stamp_scene", text="Scene") + + col = split.column() col.prop(rd, "use_stamp_camera", text="Camera") col.prop(rd, "use_stamp_lens", text="Lens") col.prop(rd, "use_stamp_filename", text="Filename") col.prop(rd, "use_stamp_marker", text="Marker") col.prop(rd, "use_stamp_sequencer_strip", text="Seq. Strip") - col = split.column() - col.active = rd.use_stamp - col.prop(rd, "stamp_foreground", slider=True) - col.prop(rd, "stamp_background", slider=True) - col.separator() - col.prop(rd, "stamp_font_size", text="Font Size") - row = layout.split(percentage=0.2) row.prop(rd, "use_stamp_note", text="Note") sub = row.row() @@ -468,33 +472,35 @@ layout.operator("scene.render_data_set_quicktime_codec") elif file_format == 'QUICKTIME_QTKIT': + quicktime = rd.quicktime + split = layout.split() col = split.column() - col.prop(rd, "quicktime_codec_type", text="Video Codec") - col.prop(rd, "quicktime_codec_spatial_quality", text="Quality") + col.prop(quicktime, "codec_type", text="Video Codec") + col.prop(quicktime, "codec_spatial_quality", text="Quality") # Audio - col.prop(rd, "quicktime_audiocodec_type", text="Audio Codec") - if rd.quicktime_audiocodec_type != 'No audio': + col.prop(quicktime, "audiocodec_type", text="Audio Codec") + if quicktime.audiocodec_type != 'No audio': split = layout.split() - if rd.quicktime_audiocodec_type == 'LPCM': - split.prop(rd, "quicktime_audio_bitdepth", text="") + if quicktime.audiocodec_type == 'LPCM': + split.prop(quicktime, "audio_bitdepth", text="") - split.prop(rd, "quicktime_audio_samplerate", text="") + split.prop(quicktime, "audio_samplerate", text="") split = layout.split() col = split.column() - if rd.quicktime_audiocodec_type == 'AAC': - col.prop(rd, "quicktime_audio_bitrate") + if quicktime.audiocodec_type == 'AAC': + col.prop(quicktime, "audio_bitrate") subsplit = split.split() col = subsplit.column() - if rd.quicktime_audiocodec_type == 'AAC': - col.prop(rd, "quicktime_audio_codec_isvbr") + if quicktime.audiocodec_type == 'AAC': + col.prop(quicktime, "audio_codec_isvbr") col = subsplit.column() - col.prop(rd, "quicktime_audio_resampling_hq") + col.prop(quicktime, "audio_resampling_hq") class RENDER_PT_encoding(RenderButtonsPanel, Panel): @@ -511,49 +517,52 @@ layout = self.layout rd = context.scene.render + ffmpeg = rd.ffmpeg layout.menu("RENDER_MT_ffmpeg_presets", text="Presets") split = layout.split() - split.prop(rd, "ffmpeg_format") - if rd.ffmpeg_format in {'AVI', 'QUICKTIME', 'MKV', 'OGG'}: - split.prop(rd, "ffmpeg_codec") + split.prop(rd.ffmpeg, "format") + if ffmpeg.format in {'AVI', 'QUICKTIME', 'MKV', 'OGG'}: + split.prop(ffmpeg, "codec") + elif rd.ffmpeg.format == 'H264': + split.prop(ffmpeg, 'use_lossless_output') else: split.label() row = layout.row() - row.prop(rd, "ffmpeg_video_bitrate") - row.prop(rd, "ffmpeg_gopsize") + row.prop(ffmpeg, "video_bitrate") + row.prop(ffmpeg, "gopsize") split = layout.split() col = split.column() col.label(text="Rate:") - col.prop(rd, "ffmpeg_minrate", text="Minimum") - col.prop(rd, "ffmpeg_maxrate", text="Maximum") - col.prop(rd, "ffmpeg_buffersize", text="Buffer") + col.prop(ffmpeg, "minrate", text="Minimum") + col.prop(ffmpeg, "maxrate", text="Maximum") + col.prop(ffmpeg, "buffersize", text="Buffer") col = split.column() - col.prop(rd, "ffmpeg_autosplit") + col.prop(ffmpeg, "use_autosplit") col.label(text="Mux:") - col.prop(rd, "ffmpeg_muxrate", text="Rate") - col.prop(rd, "ffmpeg_packetsize", text="Packet Size") + col.prop(ffmpeg, "muxrate", text="Rate") + col.prop(ffmpeg, "packetsize", text="Packet Size") layout.separator() # Audio: - if rd.ffmpeg_format not in {'MP3'}: - layout.prop(rd, "ffmpeg_audio_codec", text="Audio Codec") + if ffmpeg.format != 'MP3': + layout.prop(ffmpeg, "audio_codec", text="Audio Codec") row = layout.row() - row.prop(rd, "ffmpeg_audio_bitrate") - row.prop(rd, "ffmpeg_audio_volume", slider=True) + row.prop(ffmpeg, "audio_bitrate") + row.prop(ffmpeg, "audio_volume", slider=True) class RENDER_PT_bake(RenderButtonsPanel, Panel): bl_label = "Bake" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} def draw(self, context): layout = self.layout diff -Nru blender-2.61/release/scripts/startup/bl_ui/properties_scene.py blender-2.62/release/scripts/startup/bl_ui/properties_scene.py --- blender-2.61/release/scripts/startup/bl_ui/properties_scene.py 2011-12-13 19:43:16.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_ui/properties_scene.py 2012-02-15 19:27:28.000000000 +0000 @@ -29,12 +29,13 @@ @classmethod def poll(cls, context): - return context.scene + rd = context.scene.render + return context.scene and (rd.engine in cls.COMPAT_ENGINES) class SCENE_PT_scene(SceneButtonsPanel, Panel): bl_label = "Scene" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} def draw(self, context): layout = self.layout @@ -53,6 +54,7 @@ layout = self.layout scene = context.scene rd = context.scene.render + ffmpeg = rd.ffmpeg layout.prop(scene, "audio_volume") layout.operator("sound.bake_animation") @@ -67,15 +69,15 @@ col = split.column() col.label("Format:") - col.prop(rd, "ffmpeg_audio_channels", text="") - col.prop(rd, "ffmpeg_audio_mixrate", text="Rate") + col.prop(ffmpeg, "audio_channels", text="") + col.prop(ffmpeg, "audio_mixrate", text="Rate") layout.operator("sound.mixdown") class SCENE_PT_unit(SceneButtonsPanel, Panel): bl_label = "Units" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} def draw(self, context): layout = self.layout @@ -93,6 +95,7 @@ class SCENE_PT_keying_sets(SceneButtonsPanel, Panel): bl_label = "Keying Sets" + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} def draw(self, context): layout = self.layout @@ -125,6 +128,7 @@ class SCENE_PT_keying_set_paths(SceneButtonsPanel, Panel): bl_label = "Active Keying Set" + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} @classmethod def poll(cls, context): diff -Nru blender-2.61/release/scripts/startup/bl_ui/properties_texture.py blender-2.62/release/scripts/startup/bl_ui/properties_texture.py --- blender-2.61/release/scripts/startup/bl_ui/properties_texture.py 2011-12-13 19:43:16.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_ui/properties_texture.py 2012-02-15 19:27:28.000000000 +0000 @@ -19,6 +19,14 @@ # import bpy from bpy.types import Menu, Panel + +from bpy.types import (Brush, + Lamp, + Material, + ParticleSettings, + Texture, + World) + from rna_prop_ui import PropertyPanel @@ -91,7 +99,7 @@ engine = context.scene.render.engine if not (hasattr(context, "texture_slot") or hasattr(context, "texture_node")): return False - return ((context.material or context.world or context.lamp or context.brush or context.texture or context.particle_system or isinstance(context.space_data.pin_id, bpy.types.ParticleSettings)) + return ((context.material or context.world or context.lamp or context.brush or context.texture or context.particle_system or isinstance(context.space_data.pin_id, ParticleSettings)) and (engine in cls.COMPAT_ENGINES)) def draw(self, context): @@ -103,14 +111,14 @@ idblock = context_tex_datablock(context) pin_id = space.pin_id - if space.use_pin_id and not isinstance(pin_id, bpy.types.Texture): + if space.use_pin_id and not isinstance(pin_id, Texture): idblock = pin_id pin_id = None if not space.use_pin_id: layout.prop(space, "texture_context", expand=True) - tex_collection = (pin_id is None) and (node is None) and (not isinstance(idblock, bpy.types.Brush)) + tex_collection = (pin_id is None) and (node is None) and (not isinstance(idblock, Brush)) if tex_collection: row = layout.row() @@ -413,7 +421,7 @@ col = split.column() #Only for Material based textures, not for Lamp/World... - if slot and isinstance(idblock, bpy.types.Material): + if slot and isinstance(idblock, Material): col.prop(tex, "use_normal_map") row = col.row() row.active = tex.use_normal_map @@ -801,7 +809,7 @@ @classmethod def poll(cls, context): idblock = context_tex_datablock(context) - if isinstance(idblock, bpy.types.Brush) and not context.sculpt_object: + if isinstance(idblock, Brush) and not context.sculpt_object: return False if not getattr(context, "texture_slot", None): @@ -816,9 +824,8 @@ idblock = context_tex_datablock(context) tex = context.texture_slot - # textype = context.texture - if not isinstance(idblock, bpy.types.Brush): + if not isinstance(idblock, Brush): split = layout.split(percentage=0.3) col = split.column() col.label(text="Coordinates:") @@ -847,7 +854,7 @@ split.label(text="Object:") split.prop(tex, "object", text="") - if isinstance(idblock, bpy.types.Brush): + if isinstance(idblock, Brush): if context.sculpt_object: layout.label(text="Brush Mapping:") layout.prop(tex, "map_mode", expand=True) @@ -856,7 +863,7 @@ row.active = tex.map_mode in {'FIXED', 'TILED'} row.prop(tex, "angle") else: - if isinstance(idblock, bpy.types.Material): + if isinstance(idblock, Material): split = layout.split(percentage=0.3) split.label(text="Projection:") split.prop(tex, "mapping", text="") @@ -889,7 +896,7 @@ @classmethod def poll(cls, context): idblock = context_tex_datablock(context) - if isinstance(idblock, bpy.types.Brush): + if isinstance(idblock, Brush): return False if not getattr(context, "texture_slot", None): @@ -904,7 +911,6 @@ idblock = context_tex_datablock(context) - # textype = context.texture tex = context.texture_slot def factor_but(layout, toggle, factor, name): @@ -915,7 +921,7 @@ sub.prop(tex, factor, text=name, slider=True) return sub # XXX, temp. use_map_normal needs to override. - if isinstance(idblock, bpy.types.Material): + if isinstance(idblock, Material): if idblock.type in {'SURFACE', 'WIRE'}: split = layout.split() @@ -978,7 +984,7 @@ factor_but(col, "use_map_color_transmission", "transmission_color_factor", "Transmission Color") factor_but(col, "use_map_color_reflection", "reflection_color_factor", "Reflection Color") - elif isinstance(idblock, bpy.types.Lamp): + elif isinstance(idblock, Lamp): split = layout.split() col = split.column() @@ -987,7 +993,7 @@ col = split.column() factor_but(col, "use_map_shadow", "shadow_factor", "Shadow") - elif isinstance(idblock, bpy.types.World): + elif isinstance(idblock, World): split = layout.split() col = split.column() @@ -997,7 +1003,7 @@ col = split.column() factor_but(col, "use_map_zenith_up", "zenith_up_factor", "Zenith Up") factor_but(col, "use_map_zenith_down", "zenith_down_factor", "Zenith Down") - elif isinstance(idblock, bpy.types.ParticleSettings): + elif isinstance(idblock, ParticleSettings): split = layout.split() col = split.column() @@ -1028,7 +1034,7 @@ layout.separator() - if not isinstance(idblock, bpy.types.ParticleSettings): + if not isinstance(idblock, ParticleSettings): split = layout.split() col = split.column() @@ -1041,10 +1047,10 @@ col.prop(tex, "invert", text="Negative") col.prop(tex, "use_stencil") - if isinstance(idblock, bpy.types.Material) or isinstance(idblock, bpy.types.World): + if isinstance(idblock, Material) or isinstance(idblock, World): col.prop(tex, "default_value", text="DVar", slider=True) - if isinstance(idblock, bpy.types.Material): + if isinstance(idblock, Material): layout.label(text="Bump Mapping:") # only show bump settings if activated but not for normal-map images @@ -1056,14 +1062,14 @@ # the space setting is supported for: derivative-maps + bump-maps (DEFAULT,BEST_QUALITY), not for normal-maps sub = row.row() - sub.active = (tex.use_map_normal or tex.use_map_warp) and not (tex.texture.type == 'IMAGE' and tex.texture.use_normal_map) and ((tex.bump_method in {'BUMP_DEFAULT', 'BUMP_BEST_QUALITY'}) or (tex.texture.type == 'IMAGE' and tex.texture.use_derivative_map)) + sub.active = (tex.use_map_normal or tex.use_map_warp) and not (tex.texture.type == 'IMAGE' and tex.texture.use_normal_map) and ((tex.bump_method in {'BUMP_LOW_QUALITY', 'BUMP_MEDIUM_QUALITY', 'BUMP_BEST_QUALITY'}) or (tex.texture.type == 'IMAGE' and tex.texture.use_derivative_map)) sub.prop(tex, "bump_objectspace", text="Space") class TEXTURE_PT_custom_props(TextureButtonsPanel, PropertyPanel, Panel): COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} _context_path = "texture" - _property_type = bpy.types.Texture + _property_type = Texture if __name__ == "__main__": # only for live edit. bpy.utils.register_module(__name__) diff -Nru blender-2.61/release/scripts/startup/bl_ui/space_clip.py blender-2.62/release/scripts/startup/bl_ui/space_clip.py --- blender-2.61/release/scripts/startup/bl_ui/space_clip.py 2011-12-13 19:43:16.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_ui/space_clip.py 2012-02-15 19:27:28.000000000 +0000 @@ -16,7 +16,8 @@ # # ##### END GPL LICENSE BLOCK ##### -# +# + import bpy from bpy.types import Panel, Header, Menu @@ -70,7 +71,13 @@ row.template_ID(sc, "clip", open='clip.open') if clip: - r = clip.tracking.reconstruction + tracking = clip.tracking + active = tracking.objects.active + + if active and not active.is_camera: + r = active.reconstruction + else: + r = tracking.reconstruction if r.is_valid: layout.label(text="Average solve error: %.4f" % @@ -110,7 +117,7 @@ if settings.show_default_expanded: col = box.column() row = col.row(align=True) - label = bpy.types.CLIP_MT_tracking_settings_presets.bl_label + label = CLIP_MT_tracking_settings_presets.bl_label row.menu('CLIP_MT_tracking_settings_presets', text=label) row.operator("clip.tracking_settings_preset_add", text="", icon='ZOOMIN') @@ -120,6 +127,16 @@ col.separator() + row = col.row(align=True) + row.prop(settings, "use_default_red_channel", + text="R", toggle=True) + row.prop(settings, "use_default_green_channel", + text="G", toggle=True) + row.prop(settings, "use_default_blue_channel", + text="B", toggle=True) + + col.separator() + sub = col.column(align=True) sub.prop(settings, "default_pattern_size") sub.prop(settings, "default_search_size") @@ -140,6 +157,10 @@ col.label(text="Match:") col.prop(settings, "default_pattern_match", text="") + col.separator() + col.operator('clip.track_settings_as_default', + text="Copy From Active Track") + class CLIP_PT_tools_tracking(Panel): bl_space_type = 'CLIP_EDITOR' @@ -155,17 +176,17 @@ def draw(self, context): layout = self.layout - # clip = context.space_data.clip # UNUSED row = layout.row(align=True) props = row.operator("clip.track_markers", text="", icon='FRAME_PREV') props.backwards = True props = row.operator("clip.track_markers", text="", - icon='PLAY_REVERSE') + icon='PLAY_REVERSE') props.backwards = True props.sequence = True props = row.operator("clip.track_markers", text="", icon='PLAY') + props.backwards = False props.sequence = True row.operator("clip.track_markers", text="", icon='FRAME_NEXT') @@ -175,9 +196,7 @@ props = col.operator("clip.clear_track_path", text="Clear Before") props.action = 'UPTO' - - props = col.operator("clip.clear_track_path", text="Clear") - props.action = 'ALL' + col.operator("clip.clear_track_path", text="Clear").action = 'ALL' layout.operator("clip.join_tracks", text="Join") @@ -197,10 +216,15 @@ def draw(self, context): layout = self.layout clip = context.space_data.clip - settings = clip.tracking.settings + tracking = clip.tracking + settings = tracking.settings + tracking_object = tracking.objects.active col = layout.column(align=True) - col.operator("clip.solve_camera", text="Camera Motion") + + col.operator("clip.solve_camera", + text="Camera Motion" if tracking_object.is_camera + else "Object Motion") col.operator("clip.clear_solution") col = layout.column(align=True) @@ -208,6 +232,7 @@ col.prop(settings, "keyframe_b") col = layout.column(align=True) + col.active = tracking_object.is_camera col.label(text="Refine:") col.prop(settings, "refine_intrinsics", text="") @@ -287,6 +312,40 @@ col.prop(settings, "distance") +class CLIP_PT_tools_object(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'TOOLS' + bl_label = "Object" + + @classmethod + def poll(cls, context): + sc = context.space_data + clip = sc.clip + + if clip and sc.mode == 'RECONSTRUCTION': + tracking_object = clip.tracking.objects.active + return not tracking_object.is_camera + + return False + + def draw(self, context): + layout = self.layout + + sc = context.space_data + clip = sc.clip + tracking_object = clip.tracking.objects.active + settings = sc.clip.tracking.settings + + col = layout.column() + + col.prop(tracking_object, "scale") + + col.separator() + + col.operator("clip.set_solution_scale", text="Set Scale") + col.prop(settings, "object_distance") + + class CLIP_PT_tools_grease_pencil(Panel): bl_space_type = 'CLIP_EDITOR' bl_region_type = 'TOOLS' @@ -316,6 +375,38 @@ row.prop(context.tool_settings, "use_grease_pencil_sessions") +class CLIP_PT_objects(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'UI' + bl_label = "Objects" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + sc = context.space_data + + return sc.clip + + def draw(self, context): + layout = self.layout + + sc = context.space_data + tracking = sc.clip.tracking + + row = layout.row() + row.template_list(tracking, "objects", + tracking, "active_object_index", rows=3) + + sub = row.column(align=True) + + sub.operator("clip.tracking_object_new", icon='ZOOMIN', text="") + sub.operator("clip.tracking_object_remove", icon='ZOOMOUT', text="") + + active = tracking.objects.active + if active: + layout.prop(active, "name") + + class CLIP_PT_track(Panel): bl_space_type = 'CLIP_EDITOR' bl_region_type = 'UI' @@ -352,9 +443,15 @@ layout.template_track(sc, "scopes") row = layout.row(align=True) - row.prop(act_track, "use_red_channel", text="R", toggle=True) - row.prop(act_track, "use_green_channel", text="G", toggle=True) - row.prop(act_track, "use_blue_channel", text="B", toggle=True) + sub = row.row() + sub.prop(act_track, "use_red_channel", text="R", toggle=True) + sub.prop(act_track, "use_green_channel", text="G", toggle=True) + sub.prop(act_track, "use_blue_channel", text="B", toggle=True) + + row.separator() + + sub = row.row() + sub.prop(act_track, "use_grayscale_preview", text="B/W", toggle=True) layout.separator() @@ -387,7 +484,7 @@ def poll(cls, context): sc = context.space_data - return sc.mode in ['TRACKING', 'DISTORTION'] and sc.clip + return sc.mode in {'TRACKING', 'DISTORTION'} and sc.clip def draw(self, context): layout = self.layout @@ -422,7 +519,7 @@ col.operator("clip.set_center_principal", text="Center") col = layout.column(align=True) - col.label(text="Undistortion:") + col.label(text="Lens Distortion:") col.prop(clip.tracking.camera, "k1") col.prop(clip.tracking.camera, "k2") col.prop(clip.tracking.camera, "k3") @@ -437,25 +534,28 @@ layout = self.layout sc = context.space_data - col = layout.column(align=True) + row = layout.row(align=True) + sub = row.row() + sub.prop(sc, "show_red_channel", text="R", toggle=True) + sub.prop(sc, "show_green_channel", text="G", toggle=True) + sub.prop(sc, "show_blue_channel", text="B", toggle=True) - col.prop(sc, "show_marker_pattern", text="Pattern") - col.prop(sc, "show_marker_search", text="Search") - col.prop(sc, "show_pyramid_levels", text="Pyramid") + row.separator() - col.prop(sc, "show_track_path", text="Path") - row = col.row() - row.active = sc.show_track_path - row.prop(sc, "path_length", text="Length") + sub = row.row() + sub.prop(sc, "use_grayscale_preview", text="B/W", toggle=True) + + col = layout.column(align=True) col.prop(sc, "show_disabled", "Disabled Tracks") + col.prop(sc, "show_names", text="Names and Status") col.prop(sc, "show_bundles", text="3D Markers") - col.prop(sc, "show_names", text="Names and Status") - col.prop(sc, "show_tiny_markers", text="Compact Markers") + col.prop(sc, "use_mute_footage", text="Mute Footage") + col.prop(sc, "lock_selection") - col.prop(sc, "show_grease_pencil", text="Grease Pencil") - col.prop(sc, "use_mute_footage", text="Mute") + if sc.view == 'GRAPH': + col.prop(sc, "lock_time_cursor") if sc.mode == 'DISTORTION': col.prop(sc, "show_grid", text="Grid") @@ -463,12 +563,34 @@ elif sc.mode == 'RECONSTRUCTION': col.prop(sc, "show_stable", text="Stable") - col.prop(sc, "lock_selection") - clip = sc.clip if clip: col.label(text="Display Aspect Ratio:") - col.prop(clip, "display_aspect", text="") + row = col.row() + row.prop(clip, "display_aspect", text="") + + +class CLIP_PT_marker_display(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'UI' + bl_label = "Marker Display" + + def draw(self, context): + layout = self.layout + sc = context.space_data + + col = layout.column(align=True) + + row = col.row() + row.prop(sc, "show_marker_pattern", text="Pattern") + row.prop(sc, "show_marker_search", text="Search") + + col.prop(sc, "show_tiny_markers", text="Thin Markers") + col.prop(sc, "show_track_path", text="Path") + + row = col.row() + row.active = sc.show_track_path + row.prop(sc, "path_length", text="Length") class CLIP_PT_track_settings(Panel): @@ -613,17 +735,21 @@ layout.active = clip.use_proxy - layout.label(text="Build Sizes:") + layout.label(text="Build Original:") - row = layout.row() - row.prop(clip.proxy, "build_25") - row.prop(clip.proxy, "build_50") + row = layout.row(align=True) + row.prop(clip.proxy, "build_25", toggle=True) + row.prop(clip.proxy, "build_50", toggle=True) + row.prop(clip.proxy, "build_75", toggle=True) + row.prop(clip.proxy, "build_100", toggle=True) - row = layout.row() - row.prop(clip.proxy, "build_75") - row.prop(clip.proxy, "build_100") + layout.label(text="Build Undistorted:") - layout.prop(clip.proxy, "build_undistorted") + row = layout.row(align=True) + row.prop(clip.proxy, "build_undistorted_25", toggle=True) + row.prop(clip.proxy, "build_undistorted_50", toggle=True) + row.prop(clip.proxy, "build_undistorted_75", toggle=True) + row.prop(clip.proxy, "build_undistorted_100", toggle=True) layout.prop(clip.proxy, "quality") @@ -631,7 +757,7 @@ if clip.use_proxy_custom_directory: layout.prop(clip.proxy, "directory") - layout.operator("clip.rebuild_proxy", text="Rebuild Proxy") + layout.operator("clip.rebuild_proxy", text="Build Proxy") if clip.source == 'MOVIE': col = layout.column() @@ -771,6 +897,10 @@ layout.operator("clip.clean_tracks") layout.separator() + layout.operator("clip.copy_tracks") + layout.operator("clip.paste_tracks") + + layout.separator() props = layout.operator("clip.track_markers", text="Track Frame Backwards") props.backwards = True @@ -849,7 +979,8 @@ layout.separator() - layout.operator("clip.select_all", text="Select/Deselect all") + props = layout.operator("clip.select_all", text="Select/Deselect all") + props.action = 'TOGGLE' layout.operator("clip.select_all", text="Inverse").action = 'INVERT' layout.menu("CLIP_MT_select_grouped") @@ -874,7 +1005,8 @@ def draw(self, context): layout = self.layout - props = layout.operator("clip.disable_markers", text="Enable Markers") + props = layout.operator("clip.disable_markers", + text="Enable Markers") props.action = 'ENABLE' props = layout.operator("clip.disable_markers", text="Disable markers") @@ -900,7 +1032,7 @@ bl_label = "Camera Presets" preset_subdir = "tracking_camera" preset_operator = "script.execute_preset" - draw = bpy.types.Menu.draw_preset + draw = Menu.draw_preset class CLIP_MT_track_color_presets(Menu): @@ -908,7 +1040,7 @@ bl_label = "Color Presets" preset_subdir = "tracking_track_color" preset_operator = "script.execute_preset" - draw = bpy.types.Menu.draw_preset + draw = Menu.draw_preset class CLIP_MT_tracking_settings_presets(Menu): @@ -916,7 +1048,7 @@ bl_label = "Tracking Presets" preset_subdir = "tracking_settings" preset_operator = "script.execute_preset" - draw = bpy.types.Menu.draw_preset + draw = Menu.draw_preset class CLIP_MT_track_color_specials(Menu): diff -Nru blender-2.61/release/scripts/startup/bl_ui/space_dopesheet.py blender-2.62/release/scripts/startup/bl_ui/space_dopesheet.py --- blender-2.61/release/scripts/startup/bl_ui/space_dopesheet.py 2011-12-13 19:43:16.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_ui/space_dopesheet.py 2012-02-15 19:27:28.000000000 +0000 @@ -152,10 +152,7 @@ layout.prop(st, "use_auto_merge_keyframes") layout.prop(st, "use_marker_sync") - if st.show_seconds: - layout.operator("anim.time_toggle", text="Show Frames") - else: - layout.operator("anim.time_toggle", text="Show Seconds") + layout.prop(st, "show_seconds") layout.separator() layout.operator("anim.previewrange_set") @@ -179,11 +176,11 @@ layout = self.layout # This is a bit misleading as the operator's default text is "Select All" while it actually *toggles* All/None - layout.operator("action.select_all_toggle") + layout.operator("action.select_all_toggle").invert = False layout.operator("action.select_all_toggle", text="Invert Selection").invert = True layout.separator() - layout.operator("action.select_border") + layout.operator("action.select_border").axis_range = False layout.operator("action.select_border", text="Border Axis Range").axis_range = True layout.separator() diff -Nru blender-2.61/release/scripts/startup/bl_ui/space_graph.py blender-2.62/release/scripts/startup/bl_ui/space_graph.py --- blender-2.61/release/scripts/startup/bl_ui/space_graph.py 2011-12-13 19:43:16.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_ui/space_graph.py 2012-02-15 19:27:28.000000000 +0000 @@ -81,13 +81,13 @@ layout.prop(st, "use_beauty_drawing") layout.separator() - if st.show_handles: - layout.operator("graph.handles_view_toggle", icon='CHECKBOX_HLT', text="Show All Handles") - else: - layout.operator("graph.handles_view_toggle", icon='CHECKBOX_DEHLT', text="Show All Handles") + + layout.prop(st, "show_handles") + layout.prop(st, "use_only_selected_curves_handles") layout.prop(st, "use_only_selected_keyframe_handles") - layout.operator("anim.time_toggle") + + layout.prop(st, "show_seconds") layout.separator() layout.operator("anim.previewrange_set") @@ -111,7 +111,7 @@ layout = self.layout # This is a bit misleading as the operator's default text is "Select All" while it actually *toggles* All/None - layout.operator("graph.select_all_toggle") + layout.operator("graph.select_all_toggle").invert = False layout.operator("graph.select_all_toggle", text="Invert Selection").invert = True layout.separator() diff -Nru blender-2.61/release/scripts/startup/bl_ui/space_image.py blender-2.62/release/scripts/startup/bl_ui/space_image.py --- blender-2.61/release/scripts/startup/bl_ui/space_image.py 2011-12-13 19:43:16.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_ui/space_image.py 2012-02-15 19:27:28.000000000 +0000 @@ -19,6 +19,12 @@ # import bpy from bpy.types import Header, Menu, Panel +from .properties_paint_common import UnifiedPaintPanel + + +class ImagePaintPanel(UnifiedPaintPanel): + bl_space_type = 'IMAGE_EDITOR' + bl_region_type = 'UI' class BrushButtonsPanel(): @@ -52,7 +58,8 @@ layout.prop(sima, "use_realtime_update") if show_uvedit: layout.prop(toolsettings, "show_uv_local_view") - layout.prop(uv, "show_other_objects") + + layout.prop(uv, "show_other_objects") layout.separator() @@ -85,8 +92,8 @@ def draw(self, context): layout = self.layout - layout.operator("uv.select_border") - layout.operator("uv.select_border").pinned = True + layout.operator("uv.select_border").pinned = False + layout.operator("uv.select_border", text="Border Select Pinned").pinned = True layout.separator() @@ -143,12 +150,14 @@ # only for dirty && specific image types, perhaps # this could be done in operator poll too if ima.is_dirty: - if ima.source in {'FILE', 'GENERATED'} and ima.type != 'MULTILAYER': + if ima.source in {'FILE', 'GENERATED'} and ima.type != 'OPEN_EXR_MULTILAYER': layout.operator("image.pack", text="Pack As PNG").as_png = True - layout.separator() + if not context.tool_settings.use_uv_sculpt: + layout.separator() + layout.prop(sima, "use_image_paint") - layout.prop(sima, "use_image_paint") + layout.separator() class IMAGE_MT_image_invert(Menu): @@ -184,7 +193,7 @@ layout = self.layout layout.operator("uv.reveal") - layout.operator("uv.hide", text="Hide Selected") + layout.operator("uv.hide", text="Hide Selected").unselected = False layout.operator("uv.hide", text="Hide Unselected").unselected = True @@ -256,6 +265,10 @@ layout.separator() + layout.prop(toolsettings, "use_uv_sculpt") + + layout.separator() + layout.prop(uv, "use_live_unwrap") layout.operator("uv.unwrap") layout.operator("uv.pin", text="Unpin").clear = True @@ -267,6 +280,8 @@ layout.operator("uv.average_islands_scale") layout.operator("uv.minimize_stretch") layout.operator("uv.stitch") + layout.operator("uv.mark_seam") + layout.operator("uv.seams_from_islands") layout.operator("mesh.faces_mirror_uv") layout.separator() @@ -298,34 +313,34 @@ # do smart things depending on whether uv_select_sync is on if toolsettings.use_uv_select_sync: - prop = layout.operator("wm.context_set_value", text="Vertex", icon='VERTEXSEL') - prop.value = "(True, False, False)" - prop.data_path = "tool_settings.mesh_select_mode" - - prop = layout.operator("wm.context_set_value", text="Edge", icon='EDGESEL') - prop.value = "(False, True, False)" - prop.data_path = "tool_settings.mesh_select_mode" - - prop = layout.operator("wm.context_set_value", text="Face", icon='FACESEL') - prop.value = "(False, False, True)" - prop.data_path = "tool_settings.mesh_select_mode" + props = layout.operator("wm.context_set_value", text="Vertex", icon='VERTEXSEL') + props.value = "(True, False, False)" + props.data_path = "tool_settings.mesh_select_mode" + + props = layout.operator("wm.context_set_value", text="Edge", icon='EDGESEL') + props.value = "(False, True, False)" + props.data_path = "tool_settings.mesh_select_mode" + + props = layout.operator("wm.context_set_value", text="Face", icon='FACESEL') + props.value = "(False, False, True)" + props.data_path = "tool_settings.mesh_select_mode" else: - prop = layout.operator("wm.context_set_string", text="Vertex", icon='UV_VERTEXSEL') - prop.value = 'VERTEX' - prop.data_path = "tool_settings.uv_select_mode" - - prop = layout.operator("wm.context_set_string", text="Edge", icon='UV_EDGESEL') - prop.value = 'EDGE' - prop.data_path = "tool_settings.uv_select_mode" - - prop = layout.operator("wm.context_set_string", text="Face", icon='UV_FACESEL') - prop.value = 'FACE' - prop.data_path = "tool_settings.uv_select_mode" - - prop = layout.operator("wm.context_set_string", text="Island", icon='UV_ISLANDSEL') - prop.value = 'ISLAND' - prop.data_path = "tool_settings.uv_select_mode" + props = layout.operator("wm.context_set_string", text="Vertex", icon='UV_VERTEXSEL') + props.value = 'VERTEX' + props.data_path = "tool_settings.uv_select_mode" + + props = layout.operator("wm.context_set_string", text="Edge", icon='UV_EDGESEL') + props.value = 'EDGE' + props.data_path = "tool_settings.uv_select_mode" + + props = layout.operator("wm.context_set_string", text="Face", icon='UV_FACESEL') + props.value = 'FACE' + props.data_path = "tool_settings.uv_select_mode" + + props = layout.operator("wm.context_set_string", text="Island", icon='UV_ISLANDSEL') + props.value = 'ISLAND' + props.data_path = "tool_settings.uv_select_mode" class IMAGE_HT_header(Header): @@ -632,7 +647,7 @@ sub.row().prop(uvedit, "draw_stretch_type", expand=True) -class IMAGE_PT_paint(Panel): +class IMAGE_PT_paint(Panel, ImagePaintPanel): bl_space_type = 'IMAGE_EDITOR' bl_region_type = 'UI' bl_label = "Paint" @@ -657,12 +672,12 @@ col.prop(brush, "color", text="") row = col.row(align=True) - row.prop(brush, "size", slider=True) - row.prop(brush, "use_pressure_size", toggle=True, text="") + self.prop_unified_size(row, context, brush, "size", slider=True, text="Radius") + self.prop_unified_size(row, context, brush, "use_pressure_size") row = col.row(align=True) - row.prop(brush, "strength", slider=True) - row.prop(brush, "use_pressure_strength", toggle=True, text="") + self.prop_unified_strength(row, context, brush, "strength", slider=True, text="Strength") + self.prop_unified_strength(row, context, brush, "use_pressure_strength") row = col.row(align=True) row.prop(brush, "jitter", slider=True) @@ -697,8 +712,8 @@ def draw(self, context): layout = self.layout - settings = context.tool_settings.image_paint - brush = settings.brush + toolsettings = context.tool_settings.image_paint + brush = toolsettings.brush layout.prop(brush, "image_tool", text="") @@ -753,5 +768,80 @@ row.operator("brush.curve_preset", icon='LINCURVE', text="").shape = 'LINE' row.operator("brush.curve_preset", icon='NOCURVE', text="").shape = 'MAX' + +class IMAGE_UV_sculpt_curve(Panel): + bl_space_type = 'IMAGE_EDITOR' + bl_region_type = 'UI' + bl_label = "UV Sculpt Curve" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + sima = context.space_data + toolsettings = context.tool_settings.image_paint + return sima.show_uvedit and context.tool_settings.use_uv_sculpt and not (sima.show_paint and toolsettings.brush) + + def draw(self, context): + layout = self.layout + + toolsettings = context.tool_settings + uvsculpt = toolsettings.uv_sculpt + brush = uvsculpt.brush + + layout.template_curve_mapping(brush, "curve") + + row = layout.row(align=True) + row.operator("brush.curve_preset", icon="SMOOTHCURVE", text="").shape = 'SMOOTH' + row.operator("brush.curve_preset", icon="SPHERECURVE", text="").shape = 'ROUND' + row.operator("brush.curve_preset", icon="ROOTCURVE", text="").shape = 'ROOT' + row.operator("brush.curve_preset", icon="SHARPCURVE", text="").shape = 'SHARP' + row.operator("brush.curve_preset", icon="LINCURVE", text="").shape = 'LINE' + row.operator("brush.curve_preset", icon="NOCURVE", text="").shape = 'MAX' + + +class IMAGE_UV_sculpt(Panel, ImagePaintPanel): + bl_space_type = 'IMAGE_EDITOR' + bl_region_type = 'UI' + bl_label = "UV Sculpt" + + @classmethod + def poll(cls, context): + sima = context.space_data + toolsettings = context.tool_settings.image_paint + return sima.show_uvedit and context.tool_settings.use_uv_sculpt and not (sima.show_paint and toolsettings.brush) + + def draw(self, context): + layout = self.layout + + toolsettings = context.tool_settings + uvsculpt = toolsettings.uv_sculpt + brush = uvsculpt.brush + + if brush: + col = layout.column() + + row = col.row(align=True) + self.prop_unified_size(row, context, brush, "size", slider=True, text="Radius") + self.prop_unified_size(row, context, brush, "use_pressure_size") + + row = col.row(align=True) + self.prop_unified_strength(row, context, brush, "strength", slider=True, text="Strength") + self.prop_unified_strength(row, context, brush, "use_pressure_strength") + + split = layout.split() + col = split.column() + + col.prop(toolsettings, "uv_sculpt_lock_borders") + col.prop(toolsettings, "uv_sculpt_all_islands") + + split = layout.split() + col = split.column() + + col.prop(toolsettings, "uv_sculpt_tool") + + if toolsettings.uv_sculpt_tool == 'RELAX': + col.prop(toolsettings, "uv_relax_method") + + if __name__ == "__main__": # only for live edit. bpy.utils.register_module(__name__) diff -Nru blender-2.61/release/scripts/startup/bl_ui/space_info.py blender-2.62/release/scripts/startup/bl_ui/space_info.py --- blender-2.61/release/scripts/startup/bl_ui/space_info.py 2011-12-13 19:43:16.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_ui/space_info.py 2012-02-15 19:27:28.000000000 +0000 @@ -273,7 +273,9 @@ def draw(self, context): layout = self.layout - layout.operator_context = 'EXEC_SCREEN' + # note, don't use 'EXEC_SCREEN' or operators wont get the 'v3d' context. + + layout.operator_context = 'EXEC_AREA' #layout.operator_menu_enum("object.mesh_add", "type", text="Mesh", icon='OUTLINER_OB_MESH') layout.menu("INFO_MT_mesh_add", icon='OUTLINER_OB_MESH') @@ -296,7 +298,7 @@ layout.separator() layout.operator("object.camera_add", text="Camera", icon='OUTLINER_OB_CAMERA') - layout.operator_context = 'EXEC_SCREEN' + layout.operator_context = 'EXEC_AREA' layout.operator_menu_enum("object.lamp_add", "type", text="Lamp", icon='OUTLINER_OB_LAMP') layout.separator() @@ -360,7 +362,7 @@ layout = self.layout layout.operator("wm.url_open", text="Manual", icon='HELP').url = 'http://wiki.blender.org/index.php/Doc:2.6/Manual' - layout.operator("wm.url_open", text="Release Log", icon='URL').url = 'http://www.blender.org/development/release-logs/blender-261/' + layout.operator("wm.url_open", text="Release Log", icon='URL').url = 'http://www.blender.org/development/release-logs/blender-262/' layout.separator() diff -Nru blender-2.61/release/scripts/startup/bl_ui/space_logic.py blender-2.62/release/scripts/startup/bl_ui/space_logic.py --- blender-2.61/release/scripts/startup/bl_ui/space_logic.py 2011-12-13 19:43:16.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_ui/space_logic.py 2012-02-15 19:27:28.000000000 +0000 @@ -36,16 +36,40 @@ ob = context.active_object game = ob.game + is_font = (ob.type == 'FONT') - layout.operator("object.game_property_new", text="Add Game Property", icon='ZOOMIN') + if is_font: + prop_index = game.properties.find("Text") + if prop_index != -1: + layout.operator("object.game_property_remove", text="Remove Text Game Property", icon='X').index = prop_index + row = layout.row() + sub = row.row() + sub.enabled = 0 + prop = game.properties[prop_index] + sub.prop(prop, "name", text="") + row.prop(prop, "type", text="") + # get the property from the body, not the game property + # note, don't do this - it's too slow and body can potentially be a really long string. + #~ row.prop(ob.data, "body", text="") + row.label("See Text Object") + else: + props = layout.operator("object.game_property_new", text="Add Text Game Property", icon='ZOOMIN') + props.name = 'Text' + props.type = 'STRING' + + props = layout.operator("object.game_property_new", text="Add Game Property", icon='ZOOMIN') + props.name = '' for i, prop in enumerate(game.properties): + if is_font and i == prop_index: + continue + box = layout.box() row = box.row() row.prop(prop, "name", text="") row.prop(prop, "type", text="") - row.prop(prop, "value", text="", toggle=True) # we don't care about the type. rna will display correctly + row.prop(prop, "value", text="") row.prop(prop, "show_debug", text="", toggle=True, icon='INFO') row.operator("object.game_property_remove", text="", icon='X', emboss=False).index = i @@ -70,7 +94,9 @@ layout.template_header() if context.area.show_menus: - layout.menu("LOGIC_MT_view") + row = layout.row(align=True) + row.menu("LOGIC_MT_view") + row.menu("LOGIC_MT_logicbricks_add") class LOGIC_MT_view(Menu): diff -Nru blender-2.61/release/scripts/startup/bl_ui/space_nla.py blender-2.62/release/scripts/startup/bl_ui/space_nla.py --- blender-2.61/release/scripts/startup/bl_ui/space_nla.py 2011-12-13 19:43:16.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_ui/space_nla.py 2012-02-15 19:27:28.000000000 +0000 @@ -62,7 +62,7 @@ layout.prop(st, "use_realtime_update") layout.prop(st, "show_frame_indicator") - layout.operator("anim.time_toggle", text="Show Frames" if st.show_seconds else "Show Seconds") + layout.prop(st, "show_seconds") layout.prop(st, "show_strip_curves") @@ -86,11 +86,11 @@ layout = self.layout # This is a bit misleading as the operator's default text is "Select All" while it actually *toggles* All/None - layout.operator("nla.select_all_toggle") + layout.operator("nla.select_all_toggle").invert = False layout.operator("nla.select_all_toggle", text="Invert Selection").invert = True layout.separator() - layout.operator("nla.select_border") + layout.operator("nla.select_border").axis_range = False layout.operator("nla.select_border", text="Border Axis Range").axis_range = True layout.separator() @@ -143,7 +143,7 @@ layout.operator_menu_enum("anim.channels_move", "direction", text="Track Ordering...") layout.separator() - # TODO: names of these tools for 'tweakmode' need changing? + # TODO: names of these tools for 'tweak-mode' need changing? if scene.is_nla_tweakmode: layout.operator("nla.tweakmode_exit", text="Stop Tweaking Strip Actions") else: @@ -165,7 +165,7 @@ layout.operator("nla.meta_remove") layout.separator() - layout.operator("nla.tracks_add") + layout.operator("nla.tracks_add").above_selected = False layout.operator("nla.tracks_add", text="Add Tracks Above Selected").above_selected = True diff -Nru blender-2.61/release/scripts/startup/bl_ui/space_node.py blender-2.62/release/scripts/startup/bl_ui/space_node.py --- blender-2.61/release/scripts/startup/bl_ui/space_node.py 2011-12-13 19:43:16.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_ui/space_node.py 2012-02-15 19:27:28.000000000 +0000 @@ -28,6 +28,7 @@ layout = self.layout scene = context.scene + ob = context.object snode = context.space_data snode_id = snode.id id_from = snode.id_from @@ -47,9 +48,19 @@ if scene.render.use_shading_nodes: layout.prop(snode, "shader_type", text="", expand=True) - if not scene.render.use_shading_nodes or snode.shader_type == 'OBJECT': - if id_from: + if (not scene.render.use_shading_nodes or snode.shader_type == 'OBJECT') and ob: + # Show material.new when no active ID/slot exists + if not id_from and ob.type in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'METABALL'}: + layout.template_ID(ob, "active_material", new="material.new") + # Material ID, but not for Lamps + if id_from and ob.type != 'LAMP': layout.template_ID(id_from, "active_material", new="material.new") + # Don't show "Use Nodes" Button when Engine is BI for Lamps + if snode_id and not (scene.render.use_shading_nodes == 0 and ob.type == 'LAMP'): + layout.prop(snode_id, "use_nodes") + + if snode.shader_type == 'WORLD': + layout.template_ID(scene, "world", new="world.new") if snode_id: layout.prop(snode_id, "use_nodes") @@ -156,6 +167,7 @@ layout.operator("node.mute_toggle") layout.operator("node.preview_toggle") layout.operator("node.hide_socket_toggle") + layout.operator("node.options_toggle") layout.separator() diff -Nru blender-2.61/release/scripts/startup/bl_ui/space_sequencer.py blender-2.62/release/scripts/startup/bl_ui/space_sequencer.py --- blender-2.61/release/scripts/startup/bl_ui/space_sequencer.py 2011-12-13 19:43:16.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_ui/space_sequencer.py 2012-02-15 19:27:28.000000000 +0000 @@ -114,10 +114,7 @@ layout.operator("sequencer.view_selected") - if st.show_frames: - layout.operator("anim.time_toggle", text="Show Seconds") - else: - layout.operator("anim.time_toggle", text="Show Frames") + layout.prop(st, "show_seconds") layout.prop(st, "show_frame_indicator") if st.display_mode == 'IMAGE': @@ -148,8 +145,8 @@ layout.separator() layout.operator_menu_enum("object.select_grouped", "type", text="Grouped") layout.operator("sequencer.select_linked") - layout.operator("sequencer.select_all_toggle") - layout.operator("sequencer.select_inverse") + layout.operator("sequencer.select_all").action = 'TOGGLE' + layout.operator("sequencer.select_all").action = 'INVERT' class SEQUENCER_MT_marker(Menu): @@ -285,7 +282,7 @@ layout.separator() layout.operator("sequencer.lock") layout.operator("sequencer.unlock") - layout.operator("sequencer.mute") + layout.operator("sequencer.mute").unselected = False layout.operator("sequencer.unmute") layout.operator("sequencer.mute", text="Mute Deselected Strips").unselected = True @@ -625,6 +622,7 @@ layout = self.layout strip = act_strip(context) + sound = strip.sound layout.template_ID(strip, "sound", open="sound.open") @@ -632,12 +630,12 @@ layout.prop(strip, "filepath", text="") row = layout.row() - if strip.sound.packed_file: + if sound.packed_file: row.operator("sound.unpack", icon='PACKAGE', text="Unpack") else: row.operator("sound.pack", icon='UGLYPACKAGE', text="Pack") - row.prop(strip.sound, "use_memory_cache") + row.prop(sound, "use_memory_cache") layout.prop(strip, "waveform") layout.prop(strip, "volume") diff -Nru blender-2.61/release/scripts/startup/bl_ui/space_text.py blender-2.62/release/scripts/startup/bl_ui/space_text.py --- blender-2.61/release/scripts/startup/bl_ui/space_text.py 2011-12-13 19:43:16.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_ui/space_text.py 2012-02-15 19:27:28.000000000 +0000 @@ -174,9 +174,7 @@ st = context.space_data text = st.text - layout.operator_context = 'EXEC_AREA' layout.operator("text.new") - layout.operator_context = 'INVOKE_AREA' layout.operator("text.open") if text: diff -Nru blender-2.61/release/scripts/startup/bl_ui/space_time.py blender-2.62/release/scripts/startup/bl_ui/space_time.py --- blender-2.61/release/scripts/startup/bl_ui/space_time.py 2011-12-13 19:43:16.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_ui/space_time.py 2012-02-15 19:27:28.000000000 +0000 @@ -28,7 +28,7 @@ layout = self.layout scene = context.scene - tools = context.tool_settings + toolsettings = context.tool_settings screen = context.screen row = layout.row(align=True) @@ -61,7 +61,7 @@ # if using JACK and A/V sync: # hide the play-reversed button # since JACK transport doesn't support reversed playback - if (context.user_preferences.system.audio_device == 'JACK' and scene.sync_mode == 'AUDIO_SYNC'): + if scene.sync_mode == 'AUDIO_SYNC' and context.user_preferences.system.audio_device == 'JACK': sub = row.row() sub.scale_x = 2.0 sub.operator("screen.animation_play", text="", icon='PLAY') @@ -80,11 +80,11 @@ layout.separator() row = layout.row(align=True) - row.prop(tools, "use_keyframe_insert_auto", text="", toggle=True) - row.prop(tools, "use_keyframe_insert_keyingset", text="", toggle=True) - if screen.is_animation_playing and tools.use_keyframe_insert_auto: + row.prop(toolsettings, "use_keyframe_insert_auto", text="", toggle=True) + row.prop(toolsettings, "use_keyframe_insert_keyingset", text="", toggle=True) + if screen.is_animation_playing and toolsettings.use_keyframe_insert_auto: subsub = row.row() - subsub.prop(tools, "use_record_with_nla", toggle=True) + subsub.prop(toolsettings, "use_record_with_nla", toggle=True) row = layout.row(align=True) row.prop_search(scene.keying_sets_all, "active", scene, "keying_sets_all", text="") @@ -109,7 +109,7 @@ st = context.space_data - layout.operator("anim.time_toggle") + layout.prop(st, "show_seconds") layout.operator("time.view_all") layout.separator() @@ -193,10 +193,10 @@ def draw(self, context): layout = self.layout - tools = context.tool_settings + toolsettings = context.tool_settings - layout.prop_enum(tools, "auto_keying_mode", 'ADD_REPLACE_KEYS') - layout.prop_enum(tools, "auto_keying_mode", 'REPLACE_KEYS') + layout.prop_enum(toolsettings, "auto_keying_mode", 'ADD_REPLACE_KEYS') + layout.prop_enum(toolsettings, "auto_keying_mode", 'REPLACE_KEYS') def marker_menu_generic(layout): diff -Nru blender-2.61/release/scripts/startup/bl_ui/space_userpref_keymap.py blender-2.62/release/scripts/startup/bl_ui/space_userpref_keymap.py --- blender-2.61/release/scripts/startup/bl_ui/space_userpref_keymap.py 2011-12-13 19:43:16.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_ui/space_userpref_keymap.py 2012-02-15 19:27:28.000000000 +0000 @@ -180,7 +180,7 @@ sub.prop(kmi, "propvalue", text="") else: # One day... - # sub.prop_search(kmi, "idname", bpy.context.window_manager, "operators_all", text="") + #~ sub.prop_search(kmi, "idname", bpy.context.window_manager, "operators_all", text="") sub.prop(kmi, "idname", text="") sub = split.column() @@ -219,7 +219,7 @@ filtered_items = [kmi for kmi in km.keymap_items if filter_text in kmi.name.lower()] - if len(filtered_items) != 0: + if filtered_items: col = layout.column() row = col.row() diff -Nru blender-2.61/release/scripts/startup/bl_ui/space_userpref.py blender-2.62/release/scripts/startup/bl_ui/space_userpref.py --- blender-2.61/release/scripts/startup/bl_ui/space_userpref.py 2011-12-13 19:43:16.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_ui/space_userpref.py 2012-02-15 19:27:28.000000000 +0000 @@ -89,8 +89,8 @@ layout.operator_context = 'INVOKE_DEFAULT' if userpref.active_section == 'INPUT': - layout.operator("wm.keyconfig_export") layout.operator("wm.keyconfig_import") + layout.operator("wm.keyconfig_export") elif userpref.active_section == 'ADDONS': layout.operator("wm.addon_install") layout.menu("USERPREF_MT_addons_dev_guides") @@ -293,7 +293,7 @@ col.label(text="Grease Pencil:") col.prop(edit, "grease_pencil_manhattan_distance", text="Manhattan Distance") col.prop(edit, "grease_pencil_euclidean_distance", text="Euclidean Distance") - #col.prop(edit, "use_grease_pencil_simplify_stroke", text="Simplify Stroke") + #~ col.prop(edit, "use_grease_pencil_simplify_stroke", text="Simplify Stroke") col.prop(edit, "grease_pencil_eraser_radius", text="Eraser Radius") col.prop(edit, "use_grease_pencil_smooth_stroke", text="Smooth Stroke") col.separator() @@ -316,7 +316,7 @@ sub = col.column() - # sub.active = edit.use_keyframe_insert_auto # incorrect, timeline can enable + #~ sub.active = edit.use_keyframe_insert_auto # incorrect, time-line can enable sub.prop(edit, "use_keyframe_insert_available", text="Only Insert Available") col.separator() @@ -386,13 +386,9 @@ col.prop(system, "dpi") col.prop(system, "frame_server_port") col.prop(system, "scrollback", text="Console Scrollback") - col.prop(system, "author", text="Author") - col.prop(system, "use_scripts_auto_execute") - col.prop(system, "use_tabs_as_spaces") col.separator() col.separator() - col.separator() col.label(text="Sound:") col.row().prop(system, "audio_device", expand=True) @@ -406,14 +402,20 @@ col.separator() col.separator() - col.separator() col.label(text="Screencast:") col.prop(system, "screencast_fps") col.prop(system, "screencast_wait_time") + col.separator() col.separator() - col.separator() + + if hasattr(system, 'compute_device'): + col.label(text="Compute Device:") + col.row().prop(system, "compute_device_type", expand=True) + sub = col.row() + sub.active = system.compute_device_type != 'CPU' + sub.prop(system, "compute_device", text="") # 2. Column column = split.column() @@ -423,6 +425,7 @@ col.label(text="OpenGL:") col.prop(system, "gl_clip_alpha", slider=True) col.prop(system, "use_mipmaps") + col.prop(system, "use_16bit_textures") col.label(text="Anisotropic Filtering") col.prop(system, "anisotropic_filter", text="") col.prop(system, "use_vertex_buffer_objects") @@ -487,6 +490,15 @@ row.prop(system, "use_translate_tooltips", text="Tooltips") +class USERPREF_MT_interface_theme_presets(Menu): + bl_label = "Presets" + preset_subdir = "interface_theme" + preset_operator = "script.execute_preset" + preset_type = 'XML' + preset_xml_map = (("user_preferences.themes[0]", "Theme"), ) + draw = Menu.draw_preset + + class USERPREF_PT_theme(Panel): bl_space_type = 'USER_PREFERENCES' bl_label = "Themes" @@ -496,32 +508,40 @@ @staticmethod def _theme_generic(split, themedata): - row = split.row() + col = split.column() - subsplit = row.split(percentage=0.95) + def theme_generic_recurse(data): + col.label(data.rna_type.name) + row = col.row() + subsplit = row.split(percentage=0.95) - padding1 = subsplit.split(percentage=0.15) - padding1.column() + padding1 = subsplit.split(percentage=0.15) + padding1.column() - subsplit = row.split(percentage=0.85) + subsplit = row.split(percentage=0.85) - padding2 = subsplit.split(percentage=0.15) - padding2.column() + padding2 = subsplit.split(percentage=0.15) + padding2.column() - colsub_pair = padding1.column(), padding2.column() + colsub_pair = padding1.column(), padding2.column() - props_type = {} + props_type = {} - for i, prop in enumerate(themedata.rna_type.properties): - attr = prop.identifier - if attr == "rna_type": - continue + for i, prop in enumerate(data.rna_type.properties): + if prop.identifier == "rna_type": + continue - props_type.setdefault((prop.type, prop.subtype), []).append(prop.identifier) + props_type.setdefault((prop.type, prop.subtype), []).append(prop) - for props_type, props_ls in sorted(props_type.items()): - for i, attr in enumerate(props_ls): - colsub_pair[i % 2].row().prop(themedata, attr) + for props_type, props_ls in sorted(props_type.items()): + if props_type[0] == 'POINTER': + for i, prop in enumerate(props_ls): + theme_generic_recurse(getattr(data, prop.identifier)) + else: + for i, prop in enumerate(props_ls): + colsub_pair[i % 2].row().prop(data, prop.identifier) + + theme_generic_recurse(themedata) @classmethod def poll(cls, context): @@ -534,7 +554,18 @@ theme = context.user_preferences.themes[0] split_themes = layout.split(percentage=0.2) - split_themes.prop(theme, "theme_area", expand=True) + + sub = split_themes.column() + + sub.label(text="Presets:") + subrow = sub.row(align=True) + + subrow.menu("USERPREF_MT_interface_theme_presets", text=USERPREF_MT_interface_theme_presets.bl_label) + subrow.operator("wm.interface_theme_preset_add", text="", icon='ZOOMIN') + subrow.operator("wm.interface_theme_preset_add", text="", icon='ZOOMOUT').remove_active = True + sub.separator() + + sub.prop(theme, "theme_area", expand=True) split = layout.split(percentage=0.4) @@ -725,6 +756,7 @@ userpref = context.user_preferences paths = userpref.filepaths + system = userpref.system split = layout.split(percentage=0.7) @@ -760,6 +792,14 @@ subsplit.prop(paths, "animation_player_preset", text="") subsplit.prop(paths, "animation_player", text="") + col.separator() + col.separator() + + colsplit = col.split(percentage=0.95) + sub = colsplit.column() + sub.label(text="Author:") + sub.prop(system, "author", text="") + col = split.column() col.label(text="Save & Load:") col.prop(paths, "use_relative_paths") @@ -782,11 +822,18 @@ sub.active = paths.use_auto_save_temporary_files sub.prop(paths, "auto_save_time", text="Timer (mins)") + col.separator() + + col.label(text="Scripts:") + col.prop(system, "use_scripts_auto_execute") + col.prop(system, "use_tabs_as_spaces") + + from .space_userpref_keymap import InputKeyMapPanel class USERPREF_MT_ndof_settings(Menu): - # accessed from the window keybindings in C (only) + # accessed from the window key-bindings in C (only) bl_label = "3D Mouse Settings" def draw(self, context): @@ -918,7 +965,7 @@ class USERPREF_MT_addons_dev_guides(Menu): bl_label = "Development Guides" - # menu to open webpages with addons development guides + # menu to open web-pages with addons development guides def draw(self, context): layout = self.layout layout.operator("wm.url_open", text="API Concepts", icon='URL').url = "http://wiki.blender.org/index.php/Dev:2.5/Py/API/Intro" @@ -1050,7 +1097,7 @@ else: row.operator("wm.addon_enable", icon='CHECKBOX_DEHLT', text="", emboss=False).module = module_name - # Expanded UI (only if additional infos are available) + # Expanded UI (only if additional info is available) if info["show_expanded"]: if info["description"]: split = colsub.row().split(percentage=0.15) diff -Nru blender-2.61/release/scripts/startup/bl_ui/space_view3d.py blender-2.62/release/scripts/startup/bl_ui/space_view3d.py --- blender-2.61/release/scripts/startup/bl_ui/space_view3d.py 2011-12-13 19:43:16.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_ui/space_view3d.py 2012-02-15 19:27:28.000000000 +0000 @@ -263,7 +263,7 @@ layout.separator() layout.operator_context = 'EXEC_REGION_WIN' - layout.operator("uv.project_from_view") + layout.operator("uv.project_from_view").scale_to_bounds = False layout.operator("uv.project_from_view", text="Project from View (Bounds)").scale_to_bounds = True layout.separator() @@ -421,8 +421,8 @@ layout.separator() - layout.operator("object.select_all", text="Select/Deselect All") - layout.operator("object.select_inverse", text="Inverse") + layout.operator("object.select_all", text="Select/Deselect All").action = 'TOGGLE' + layout.operator("object.select_all", text="Inverse").action = 'INVERT' layout.operator("object.select_random", text="Random") layout.operator("object.select_mirror", text="Mirror") layout.operator("object.select_by_layer", text="Select All by Layer") @@ -446,8 +446,8 @@ layout.separator() - layout.operator("pose.select_all", text="Select/Deselect All") - layout.operator("pose.select_inverse", text="Inverse") + layout.operator("pose.select_all", text="Select/Deselect All").action = 'TOGGLE' + layout.operator("pose.select_all", text="Inverse").action = 'INVERT' layout.operator("pose.select_flip_active", text="Flip Active") layout.operator("pose.select_constraint_target", text="Constraint Target") layout.operator("pose.select_linked", text="Linked") @@ -483,9 +483,9 @@ layout.separator() - layout.operator("particle.select_all", text="Select/Deselect All") + layout.operator("particle.select_all", text="Select/Deselect All").action = 'TOGGLE' layout.operator("particle.select_linked") - layout.operator("particle.select_inverse") + layout.operator("particle.select_all").action = 'INVERT' layout.separator() @@ -509,8 +509,8 @@ layout.separator() - layout.operator("mesh.select_all", text="Select/Deselect All") - layout.operator("mesh.select_inverse", text="Inverse") + layout.operator("mesh.select_all", text="Select/Deselect All").action = 'TOGGLE' + layout.operator("mesh.select_all", text="Inverse").action = 'INVERT' layout.separator() @@ -541,7 +541,7 @@ layout.operator("mesh.select_linked", text="Linked") layout.operator("mesh.select_vertex_path", text="Vertex Path") - layout.operator("mesh.loop_multi_select", text="Edge Loop") + layout.operator("mesh.loop_multi_select", text="Edge Loop").ring = False layout.operator("mesh.loop_multi_select", text="Edge Ring").ring = True layout.separator() @@ -561,8 +561,8 @@ layout.separator() - layout.operator("curve.select_all", text="Select/Deselect All") - layout.operator("curve.select_inverse") + layout.operator("curve.select_all", text="Select/Deselect All").action = 'TOGGLE' + layout.operator("curve.select_all", text="Inverse").action = 'INVERT' layout.operator("curve.select_random") layout.operator("curve.select_nth", text="Every Nth Number of Points") @@ -590,8 +590,8 @@ layout.separator() - layout.operator("curve.select_all", text="Select/Deselect All") - layout.operator("curve.select_inverse") + layout.operator("curve.select_all", text="Select/Deselect All").action = 'TOGGLE' + layout.operator("curve.select_all", text="Inverse").action = 'INVERT' layout.operator("curve.select_random") layout.operator("curve.select_nth", text="Every Nth Number of Points") @@ -616,7 +616,7 @@ layout.separator() layout.operator("mball.select_all").action = 'TOGGLE' - layout.operator("mball.select_inverse_metaelems") + layout.operator("mball.select_all").action = 'INVERT' layout.separator() @@ -646,8 +646,8 @@ layout.separator() - layout.operator("armature.select_all", text="Select/Deselect All") - layout.operator("armature.select_inverse", text="Inverse") + layout.operator("armature.select_all", text="Select/Deselect All").action = 'TOGGLE' + layout.operator("armature.select_all", text="Inverse").action = 'INVERT' layout.separator() @@ -751,6 +751,10 @@ layout.operator("anim.keyframe_delete_v3d", text="Delete Keyframe...") layout.operator("anim.keying_set_active_set", text="Change Keying Set...") + layout.separator() + + layout.operator("nla.bake", text="Bake Action...") + class VIEW3D_MT_object_clear(Menu): bl_label = "Clear" @@ -865,12 +869,16 @@ def draw(self, context): layout = self.layout - layout.operator("object.transform_apply", text="Location").location = True - layout.operator("object.transform_apply", text="Rotation").rotation = True - layout.operator("object.transform_apply", text="Scale").scale = True + props = layout.operator("object.transform_apply", text="Location") + props.location, props.rotation, props.scale = True, False, False + + props = layout.operator("object.transform_apply", text="Rotation") + props.location, props.rotation, props.scale = False, True, False + + props = layout.operator("object.transform_apply", text="Scale") + props.location, props.rotation, props.scale = False, False, True props = layout.operator("object.transform_apply", text="Rotation & Scale") - props.scale = True - props.rotation = True + props.location, props.rotation, props.scale = False, True, True layout.separator() @@ -943,7 +951,7 @@ layout = self.layout layout.operator("object.hide_view_clear", text="Show Hidden") - layout.operator("object.hide_view_set", text="Hide Selected") + layout.operator("object.hide_view_set", text="Hide Selected").unselected = False layout.operator("object.hide_view_set", text="Hide Unselected").unselected = True @@ -993,6 +1001,7 @@ layout = self.layout layout.operator("object.logic_bricks_copy", text="Copy Logic Bricks") + layout.operator("object.game_physics_copy", text="Copy Physics Properties") layout.separator() @@ -1051,17 +1060,17 @@ layout.operator("object.vertex_group_assign", text="Assign to New Group").new = True ob = context.active_object - if ob.mode == 'EDIT': + if ob.mode == 'EDIT' or (ob.mode == 'WEIGHT_PAINT' and ob.type == 'MESH' and ob.data.use_paint_mask_vertex): if ob.vertex_groups.active: layout.separator() layout.operator("object.vertex_group_assign", text="Assign to Active Group") - layout.operator("object.vertex_group_remove_from", text="Remove from Active Group") + layout.operator("object.vertex_group_remove_from", text="Remove from Active Group").all = False layout.operator("object.vertex_group_remove_from", text="Remove from All").all = True layout.separator() if ob.vertex_groups.active: layout.operator_menu_enum("object.vertex_group_set_active", "group", text="Set Active Group") - layout.operator("object.vertex_group_remove", text="Remove Active Group") + layout.operator("object.vertex_group_remove", text="Remove Active Group").all = False layout.operator("object.vertex_group_remove", text="Remove All Groups").all = True # ********** Weight paint menu ********** @@ -1105,9 +1114,9 @@ def draw(self, context): layout = self.layout - tool_settings = context.tool_settings - sculpt = tool_settings.sculpt - brush = tool_settings.sculpt.brush + toolsettings = context.tool_settings + sculpt = toolsettings.sculpt + brush = toolsettings.sculpt.brush layout.operator("ed.undo") layout.operator("ed.redo") @@ -1143,8 +1152,8 @@ layout.prop(sculpt, "show_brush") # TODO, make available from paint menu! - layout.prop(tool_settings, "sculpt_paint_use_unified_size", text="Unify Size") - layout.prop(tool_settings, "sculpt_paint_use_unified_strength", text="Unify Strength") + layout.prop(toolsettings, "sculpt_paint_use_unified_size", text="Unify Size") + layout.prop(toolsettings, "sculpt_paint_use_unified_strength", text="Unify Strength") # ********** Particle menu ********** @@ -1310,7 +1319,7 @@ def draw(self, context): layout = self.layout - layout.operator("pose.propagate") + layout.operator("pose.propagate").mode = 'WHILE_HELD' layout.separator() @@ -1448,7 +1457,7 @@ def draw(self, context): layout = self.layout - settings = context.tool_settings + toolsettings = context.tool_settings layout.operator("ed.undo") layout.operator("ed.redo") @@ -1480,9 +1489,9 @@ layout.separator() - layout.prop(settings, "use_mesh_automerge") - layout.prop_menu_enum(settings, "proportional_edit") - layout.prop_menu_enum(settings, "proportional_edit_falloff") + layout.prop(toolsettings, "use_mesh_automerge") + layout.prop_menu_enum(toolsettings, "proportional_edit") + layout.prop_menu_enum(toolsettings, "proportional_edit_falloff") layout.separator() @@ -1497,13 +1506,13 @@ layout.operator_context = 'INVOKE_REGION_WIN' - layout.operator("mesh.subdivide", text="Subdivide") + layout.operator("mesh.subdivide", text="Subdivide").smoothness = 0.0 layout.operator("mesh.subdivide", text="Subdivide Smooth").smoothness = 1.0 layout.operator("mesh.merge", text="Merge...") layout.operator("mesh.remove_doubles") layout.operator("mesh.hide", text="Hide") layout.operator("mesh.reveal", text="Reveal") - layout.operator("mesh.select_inverse") + layout.operator("mesh.select_all").action = 'INVERT' layout.operator("mesh.flip_normals") layout.operator("mesh.vertices_smooth", text="Smooth") # layout.operator("mesh.bevel", text="Bevel") @@ -1522,17 +1531,17 @@ layout.operator_context = 'INVOKE_REGION_WIN' - prop = layout.operator("wm.context_set_value", text="Vertex", icon='VERTEXSEL') - prop.value = "(True, False, False)" - prop.data_path = "tool_settings.mesh_select_mode" - - prop = layout.operator("wm.context_set_value", text="Edge", icon='EDGESEL') - prop.value = "(False, True, False)" - prop.data_path = "tool_settings.mesh_select_mode" - - prop = layout.operator("wm.context_set_value", text="Face", icon='FACESEL') - prop.value = "(False, False, True)" - prop.data_path = "tool_settings.mesh_select_mode" + props = layout.operator("wm.context_set_value", text="Vertex", icon='VERTEXSEL') + props.value = "(True, False, False)" + props.data_path = "tool_settings.mesh_select_mode" + + props = layout.operator("wm.context_set_value", text="Edge", icon='EDGESEL') + props.value = "(False, True, False)" + props.data_path = "tool_settings.mesh_select_mode" + + props = layout.operator("wm.context_set_value", text="Face", icon='FACESEL') + props.value = "(False, False, True)" + props.data_path = "tool_settings.mesh_select_mode" class VIEW3D_MT_edit_mesh_extrude(Menu): @@ -1613,12 +1622,12 @@ layout.separator() - layout.operator("mesh.mark_seam") + layout.operator("mesh.mark_seam").clear = False layout.operator("mesh.mark_seam", text="Clear Seam").clear = True layout.separator() - layout.operator("mesh.mark_sharp") + layout.operator("mesh.mark_sharp").clear = False layout.operator("mesh.mark_sharp", text="Clear Sharp").clear = True layout.separator() @@ -1630,10 +1639,10 @@ layout.operator("TRANSFORM_OT_edge_slide") layout.operator("TRANSFORM_OT_edge_crease") - layout.operator("mesh.loop_multi_select", text="Edge Loop") + layout.operator("mesh.loop_multi_select", text="Edge Loop").ring = False - # uiItemO(layout, "Loopcut", 0, "mesh.loop_cut"); // CutEdgeloop(em, 1); - # uiItemO(layout, "Edge Slide", 0, "mesh.edge_slide"); // EdgeSlide(em, 0,0.0); + #~ uiItemO(layout, "Loopcut", 0, "mesh.loop_cut"); // CutEdgeloop(em, 1); + #~ uiItemO(layout, "Edge Slide", 0, "mesh.edge_slide"); // EdgeSlide(em, 0,0.0); layout.operator("mesh.loop_multi_select", text="Edge Ring").ring = True @@ -1695,7 +1704,7 @@ def draw(self, context): layout = self.layout - layout.operator("mesh.normals_make_consistent", text="Recalculate Outside") + layout.operator("mesh.normals_make_consistent", text="Recalculate Outside").inside = False layout.operator("mesh.normals_make_consistent", text="Recalculate Inside").inside = True layout.separator() @@ -1713,7 +1722,7 @@ def draw_curve(self, context): layout = self.layout - settings = context.tool_settings + toolsettings = context.tool_settings layout.menu("VIEW3D_MT_transform") layout.menu("VIEW3D_MT_mirror") @@ -1735,8 +1744,8 @@ layout.separator() - layout.prop_menu_enum(settings, "proportional_edit") - layout.prop_menu_enum(settings, "proportional_edit_falloff") + layout.prop_menu_enum(toolsettings, "proportional_edit") + layout.prop_menu_enum(toolsettings, "proportional_edit_falloff") layout.separator() @@ -1865,7 +1874,7 @@ def draw(self, context): layout = self.layout - settings = context.tool_settings + toolsettings = context.tool_settings layout.operator("ed.undo") layout.operator("ed.redo") @@ -1884,8 +1893,8 @@ layout.separator() - layout.prop_menu_enum(settings, "proportional_edit") - layout.prop_menu_enum(settings, "proportional_edit_falloff") + layout.prop_menu_enum(toolsettings, "proportional_edit") + layout.prop_menu_enum(toolsettings, "proportional_edit_falloff") layout.separator() @@ -1909,7 +1918,7 @@ def draw(self, context): layout = self.layout - settings = context.tool_settings + toolsettings = context.tool_settings layout.menu("VIEW3D_MT_transform") layout.menu("VIEW3D_MT_mirror") @@ -1921,8 +1930,8 @@ layout.separator() - layout.prop_menu_enum(settings, "proportional_edit") - layout.prop_menu_enum(settings, "proportional_edit_falloff") + layout.prop_menu_enum(toolsettings, "proportional_edit") + layout.prop_menu_enum(toolsettings, "proportional_edit_falloff") class VIEW3D_MT_edit_armature(Menu): @@ -2246,6 +2255,8 @@ col.prop(mesh, "show_extra_edge_length") col.prop(mesh, "show_extra_face_angle") col.prop(mesh, "show_extra_face_area") + if bpy.app.debug: + col.prop(mesh, "show_extra_indices") class VIEW3D_PT_view3d_curvedisplay(Panel): @@ -2366,13 +2377,14 @@ view = context.space_data orientation = view.current_orientation - col = layout.column() - col.prop(view, "transform_orientation") - col.operator("transform.create_orientation", text="Create") + row = layout.row(align=True) + row.prop(view, "transform_orientation", text="") + row.operator("transform.create_orientation", text="", icon='ZOOMIN') if orientation: - col.prop(orientation, "name") - col.operator("transform.delete_orientation", text="Delete") + row = layout.row(align=True) + row.prop(orientation, "name", text="") + row.operator("transform.delete_orientation", text="", icon="X") class VIEW3D_PT_etch_a_ton(Panel): diff -Nru blender-2.61/release/scripts/startup/bl_ui/space_view3d_toolbar.py blender-2.62/release/scripts/startup/bl_ui/space_view3d_toolbar.py --- blender-2.61/release/scripts/startup/bl_ui/space_view3d_toolbar.py 2011-12-13 19:43:16.000000000 +0000 +++ blender-2.62/release/scripts/startup/bl_ui/space_view3d_toolbar.py 2012-02-15 19:27:28.000000000 +0000 @@ -19,6 +19,7 @@ # import bpy from bpy.types import Menu, Panel +from .properties_paint_common import UnifiedPaintPanel class View3DPanel(): @@ -155,7 +156,7 @@ col = layout.column(align=True) col.label(text="UV Mapping:") col.operator("wm.call_menu", text="Unwrap").name = "VIEW3D_MT_uv_map" - col.operator("mesh.mark_seam") + col.operator("mesh.mark_seam").clear = False col.operator("mesh.mark_seam", text="Clear Seam").clear = True col = layout.column(align=True) @@ -447,29 +448,12 @@ # ********** default tools for paint modes **************** -class PaintPanel(): +class View3DPaintPanel(UnifiedPaintPanel): bl_space_type = 'VIEW_3D' bl_region_type = 'TOOLS' - @staticmethod - def paint_settings(context): - ts = context.tool_settings - if context.sculpt_object: - return ts.sculpt - elif context.vertex_paint_object: - return ts.vertex_paint - elif context.weight_paint_object: - return ts.weight_paint - elif context.image_paint_object: - return ts.image_paint - elif context.particle_edit_object: - return ts.particle_edit - - return None - - -class VIEW3D_PT_tools_brush(PaintPanel, Panel): +class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel): bl_label = "Brush" @classmethod @@ -479,6 +463,7 @@ def draw(self, context): layout = self.layout + toolsettings = context.tool_settings settings = self.paint_settings(context) brush = settings.brush @@ -523,14 +508,16 @@ row = col.row(align=True) - if brush.use_locked_size: - row.prop(brush, "use_locked_size", toggle=True, text="", icon='LOCKED') - row.prop(brush, "unprojected_radius", text="Radius", slider=True) + ups = toolsettings.unified_paint_settings + if ((ups.use_unified_size and ups.use_locked_size) or + ((not ups.use_unified_size) and brush.use_locked_size)): + self.prop_unified_size(row, context, brush, "use_locked_size", icon='LOCKED') + self.prop_unified_size(row, context, brush, "unprojected_radius", slider=True, text="Radius") else: - row.prop(brush, "use_locked_size", toggle=True, text="", icon='UNLOCKED') - row.prop(brush, "size", slider=True) + self.prop_unified_size(row, context, brush, "use_locked_size", icon='UNLOCKED') + self.prop_unified_size(row, context, brush, "size", slider=True, text="Radius") - row.prop(brush, "use_pressure_size", toggle=True, text="") + self.prop_unified_size(row, context, brush, "use_pressure_size") if tool not in {'SNAKE_HOOK', 'GRAB', 'ROTATE'}: col.separator() @@ -543,13 +530,13 @@ else: row.prop(brush, "use_space_atten", toggle=True, text="", icon='UNLOCKED') - row.prop(brush, "strength", text="Strength", slider=True) - row.prop(brush, "use_pressure_strength", text="") + self.prop_unified_strength(row, context, brush, "strength", text="Strength") + self.prop_unified_strength(row, context, brush, "use_pressure_strength") if tool == 'ROTATE': row = col.row(align=True) - row.prop(brush, "strength", text="Strength", slider=True) - row.prop(brush, "use_pressure_strength", text="") + self.prop_unified_strength(row, context, brush, "strength", text="Strength") + self.prop_unified_strength(row, context, brush, "use_pressure_strength") if tool != 'SMOOTH': col.separator() @@ -636,12 +623,12 @@ col.prop(brush, "color", text="") row = col.row(align=True) - row.prop(brush, "size", slider=True) - row.prop(brush, "use_pressure_size", toggle=True, text="") + self.prop_unified_size(row, context, brush, "size", slider=True, text="Radius") + self.prop_unified_size(row, context, brush, "use_pressure_size") row = col.row(align=True) - row.prop(brush, "strength", text="Strength", slider=True) - row.prop(brush, "use_pressure_strength", toggle=True, text="") + self.prop_unified_strength(row, context, brush, "strength", text="Strength") + self.prop_unified_strength(row, context, brush, "use_pressure_strength") row = col.row(align=True) row.prop(brush, "jitter", slider=True) @@ -655,19 +642,19 @@ # Weight Paint Mode # elif context.weight_paint_object and brush: - layout.prop(context.tool_settings, "vertex_group_weight", text="Weight", slider=True) - layout.prop(context.tool_settings, "use_auto_normalize", text="Auto Normalize") - layout.prop(context.tool_settings, "use_multipaint", text="Multi-Paint") + layout.prop(toolsettings, "vertex_group_weight", text="Weight", slider=True) + layout.prop(toolsettings, "use_auto_normalize", text="Auto Normalize") + layout.prop(toolsettings, "use_multipaint", text="Multi-Paint") col = layout.column() row = col.row(align=True) - row.prop(brush, "size", slider=True) - row.prop(brush, "use_pressure_size", toggle=True, text="") + self.prop_unified_size(row, context, brush, "size", slider=True, text="Radius") + self.prop_unified_size(row, context, brush, "use_pressure_size") row = col.row(align=True) - row.prop(brush, "strength", text="Strength", slider=True) - row.prop(brush, "use_pressure_strength", toggle=True, text="") + self.prop_unified_strength(row, context, brush, "strength", text="Strength") + self.prop_unified_strength(row, context, brush, "use_pressure_strength") row = col.row(align=True) row.prop(brush, "jitter", slider=True) @@ -680,12 +667,12 @@ col.prop(brush, "color", text="") row = col.row(align=True) - row.prop(brush, "size", slider=True) - row.prop(brush, "use_pressure_size", toggle=True, text="") + self.prop_unified_size(row, context, brush, "size", slider=True, text="Radius") + self.prop_unified_size(row, context, brush, "use_pressure_size") row = col.row(align=True) - row.prop(brush, "strength", text="Strength", slider=True) - row.prop(brush, "use_pressure_strength", toggle=True, text="") + self.prop_unified_strength(row, context, brush, "strength", text="Strength") + self.prop_unified_strength(row, context, brush, "use_pressure_strength") # XXX - TODO #row = col.row(align=True) @@ -693,7 +680,7 @@ #row.prop(brush, "use_pressure_jitter", toggle=True, text="") -class VIEW3D_PT_tools_brush_texture(PaintPanel, Panel): +class VIEW3D_PT_tools_brush_texture(Panel, View3DPaintPanel): bl_label = "Texture" bl_options = {'DEFAULT_CLOSED'} @@ -772,7 +759,7 @@ sub.prop(brush, "texture_overlay_alpha", text="Alpha") -class VIEW3D_PT_tools_brush_tool(PaintPanel, Panel): +class VIEW3D_PT_tools_brush_tool(Panel, View3DPaintPanel): bl_label = "Tool" bl_options = {'DEFAULT_CLOSED'} @@ -806,7 +793,7 @@ row.prop(brush, "use_paint_image", text="", icon='TPAINT_HLT') -class VIEW3D_PT_tools_brush_stroke(PaintPanel, Panel): +class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel): bl_label = "Stroke" bl_options = {'DEFAULT_CLOSED'} @@ -898,7 +885,7 @@ # row.prop(brush, "use_pressure_spacing", toggle=True, text="") -class VIEW3D_PT_tools_brush_curve(PaintPanel, Panel): +class VIEW3D_PT_tools_brush_curve(Panel, View3DPaintPanel): bl_label = "Curve" bl_options = {'DEFAULT_CLOSED'} @@ -925,7 +912,7 @@ row.operator("brush.curve_preset", icon='NOCURVE', text="").shape = 'MAX' -class VIEW3D_PT_sculpt_options(PaintPanel, Panel): +class VIEW3D_PT_sculpt_options(Panel, View3DPaintPanel): bl_label = "Options" bl_options = {'DEFAULT_CLOSED'} @@ -936,8 +923,8 @@ def draw(self, context): layout = self.layout - tool_settings = context.tool_settings - sculpt = tool_settings.sculpt + toolsettings = context.tool_settings + sculpt = toolsettings.sculpt layout.label(text="Lock:") row = layout.row(align=True) @@ -950,12 +937,10 @@ layout.prop(sculpt, "show_brush") layout.prop(sculpt, "use_deform_only") - layout.label(text="Unified Settings:") - layout.prop(tool_settings, "sculpt_paint_use_unified_size", text="Size") - layout.prop(tool_settings, "sculpt_paint_use_unified_strength", text="Strength") + self.unified_paint_settings(layout, context) -class VIEW3D_PT_sculpt_symmetry(PaintPanel, Panel): +class VIEW3D_PT_sculpt_symmetry(Panel, View3DPaintPanel): bl_label = "Symmetry" bl_options = {'DEFAULT_CLOSED'} @@ -979,17 +964,17 @@ layout.prop(sculpt, "use_symmetry_feather", text="Feather") -class VIEW3D_PT_tools_brush_appearance(PaintPanel, Panel): +class VIEW3D_PT_tools_brush_appearance(Panel, View3DPaintPanel): bl_label = "Appearance" bl_options = {'DEFAULT_CLOSED'} @classmethod def poll(cls, context): - ts = context.tool_settings - return ((context.sculpt_object and ts.sculpt) or - (context.vertex_paint_object and ts.vertex_paint) or - (context.weight_paint_object and ts.weight_paint) or - (context.image_paint_object and ts.image_paint)) + toolsettings = context.tool_settings + return ((context.sculpt_object and toolsettings.sculpt) or + (context.vertex_paint_object and toolsettings.vertex_paint) or + (context.weight_paint_object and toolsettings.weight_paint) or + (context.image_paint_object and toolsettings.image_paint)) def draw(self, context): layout = self.layout @@ -1041,7 +1026,7 @@ col.operator("object.vertex_group_fix", text="Fix Deforms") -class VIEW3D_PT_tools_weightpaint_options(View3DPanel, Panel): +class VIEW3D_PT_tools_weightpaint_options(Panel, View3DPaintPanel): bl_context = "weightpaint" bl_label = "Options" @@ -1052,9 +1037,10 @@ wpaint = tool_settings.weight_paint col = layout.column() - col.prop(wpaint, "use_all_faces") + col.prop(wpaint, "use_normal") col.prop(wpaint, "use_spray") + col.prop(wpaint, "use_group_restrict") obj = context.weight_paint_object if obj.type == 'MESH': @@ -1062,15 +1048,13 @@ col.prop(mesh, "use_mirror_x") col.prop(mesh, "use_mirror_topology") - col.label(text="Unified Settings:") - col.prop(tool_settings, "sculpt_paint_use_unified_size", text="Size") - col.prop(tool_settings, "sculpt_paint_use_unified_strength", text="Strength") + self.unified_paint_settings(col, context) # Commented out because the Apply button isn't an operator yet, making these settings useless -# col.label(text="Gamma:") -# col.prop(wpaint, "gamma", text="") -# col.label(text="Multiply:") -# col.prop(wpaint, "mul", text="") +#~ col.label(text="Gamma:") +#~ col.prop(wpaint, "gamma", text="") +#~ col.label(text="Multiply:") +#~ col.prop(wpaint, "mul", text="") # Also missing now: # Soft, Vertex-Group, X-Mirror and "Clear" Operator. @@ -1078,15 +1062,15 @@ # ********** default tools for vertex-paint **************** -class VIEW3D_PT_tools_vertexpaint(View3DPanel, Panel): +class VIEW3D_PT_tools_vertexpaint(Panel, View3DPaintPanel): bl_context = "vertexpaint" bl_label = "Options" def draw(self, context): layout = self.layout - tool_settings = context.tool_settings - vpaint = tool_settings.vertex_paint + toolsettings = context.tool_settings + vpaint = toolsettings.vertex_paint col = layout.column() #col.prop(vpaint, "mode", text="") @@ -1094,15 +1078,13 @@ col.prop(vpaint, "use_normal") col.prop(vpaint, "use_spray") - col.label(text="Unified Settings:") - col.prop(tool_settings, "sculpt_paint_use_unified_size", text="Size") - col.prop(tool_settings, "sculpt_paint_use_unified_strength", text="Strength") + self.unified_paint_settings(col, context) # Commented out because the Apply button isn't an operator yet, making these settings useless -# col.label(text="Gamma:") -# col.prop(vpaint, "gamma", text="") -# col.label(text="Multiply:") -# col.prop(vpaint, "mul", text="") +#~ col.label(text="Gamma:") +#~ col.prop(vpaint, "gamma", text="") +#~ col.label(text="Multiply:") +#~ col.prop(vpaint, "mul", text="") # ********** default tools for texture-paint **************** @@ -1126,8 +1108,9 @@ ob = context.active_object mesh = ob.data - ipaint = context.tool_settings.image_paint - settings = context.tool_settings.image_paint + toolsettings = context.tool_settings + ipaint = toolsettings.image_paint + settings = toolsettings.image_paint use_projection = ipaint.use_projection col = layout.column() @@ -1173,7 +1156,7 @@ col.operator("image.save_dirty", text="Save All Edited") -class VIEW3D_PT_imagepaint_options(PaintPanel): +class VIEW3D_PT_imagepaint_options(View3DPaintPanel): bl_label = "Options" bl_options = {'DEFAULT_CLOSED'} @@ -1184,12 +1167,8 @@ def draw(self, context): layout = self.layout - tool_settings = context.tool_settings - col = layout.column() - col.label(text="Unified Settings:") - col.prop(tool_settings, "sculpt_paint_use_unified_size", text="Size") - col.prop(tool_settings, "sculpt_paint_use_unified_strength", text="Strength") + self.unified_paint_settings(col, context) class VIEW3D_MT_tools_projectpaint_clone(Menu): @@ -1198,9 +1177,9 @@ def draw(self, context): layout = self.layout for i, tex in enumerate(context.active_object.data.uv_textures): - prop = layout.operator("wm.context_set_int", text=tex.name) - prop.data_path = "active_object.data.uv_texture_clone_index" - prop.value = i + props = layout.operator("wm.context_set_int", text=tex.name) + props.data_path = "active_object.data.uv_texture_clone_index" + props.value = i class VIEW3D_MT_tools_projectpaint_stencil(Menu): @@ -1209,9 +1188,9 @@ def draw(self, context): layout = self.layout for i, tex in enumerate(context.active_object.data.uv_textures): - prop = layout.operator("wm.context_set_int", text=tex.name) - prop.data_path = "active_object.data.uv_texture_stencil_index" - prop.value = i + props = layout.operator("wm.context_set_int", text=tex.name) + props.data_path = "active_object.data.uv_texture_stencil_index" + props.value = i class VIEW3D_PT_tools_particlemode(View3DPanel, Panel): diff -Nru blender-2.61/release/scripts/startup/keyingsets_builtins.py blender-2.62/release/scripts/startup/keyingsets_builtins.py --- blender-2.61/release/scripts/startup/keyingsets_builtins.py 2011-12-13 19:43:21.000000000 +0000 +++ blender-2.62/release/scripts/startup/keyingsets_builtins.py 2012-02-15 19:27:33.000000000 +0000 @@ -326,7 +326,7 @@ for i in range(3): if not bone.lock_rotation[i]: - ksi.addProp(ks, bone, prop, i + 1) # i + 1, since here x,y,z = 1,2,3, and w=0 + ksi.addProp(ks, bone, prop, i + 1) # i + 1, since here x/y/z = 1,2,3, and w=0 elif True not in bone.lock_rotation: # if axis-angle rotations get locked as eulers, then it's too messy to allow anything # other than all open unless we keyframe the whole lot diff -Nru blender-2.61/release/scripts/templates/addon_add_object.py blender-2.62/release/scripts/templates/addon_add_object.py --- blender-2.61/release/scripts/templates/addon_add_object.py 2011-12-13 19:43:31.000000000 +0000 +++ blender-2.62/release/scripts/templates/addon_add_object.py 2012-02-15 19:27:49.000000000 +0000 @@ -3,7 +3,6 @@ "author": "YourNameHere", "version": (1, 0), "blender": (2, 5, 5), - "api": 33333, "location": "View3D > Add > Mesh > New Object", "description": "Adds a new Mesh Object", "warning": "", diff -Nru blender-2.61/release/scripts/templates/ui_menu.py blender-2.62/release/scripts/templates/ui_menu.py --- blender-2.61/release/scripts/templates/ui_menu.py 2011-12-13 19:43:31.000000000 +0000 +++ blender-2.62/release/scripts/templates/ui_menu.py 2012-02-15 19:27:49.000000000 +0000 @@ -15,7 +15,7 @@ layout.label(text="Hello world!", icon='WORLD_DATA') - # use an operator enum property to populate a submenu + # use an operator enum property to populate a sub-menu layout.operator_menu_enum("object.select_by_type", property="type", text="Select All by Type...", diff -Nru blender-2.61/release/text/readme.html blender-2.62/release/text/readme.html --- blender-2.61/release/text/readme.html 2011-12-13 19:43:05.000000000 +0000 +++ blender-2.62/release/text/readme.html 2012-02-15 19:27:19.000000000 +0000 @@ -12,18 +12,18 @@ -

      Blender 2.61

      +

      Blender 2.62


      About

      Welcome to Blender, the free, open source 3D application for modeling, animation, rendering, compositing, video editing and game creation. Blender is available for Linux, Mac OS X, Windows, Solaris and FreeBSD and has a large world-wide community.

      Blender can be used freely for any purpose, including commercial use and distribution. It's free and open-source software, released under the GNU GPL licence. The entire source code is available on our website.

      For more information, visit blender.org.


      -

      2.61

      -

      The Blender Foundation and online developer community is proud to present Blender 2.61. This release is the second official stable release of the Blender 2.6 series, in which we will refine the 2.5 series and add exciting new features again.More information about this release.

      +

      2.62

      +

      The Blender Foundation and online developer community is proud to present Blender 2.62. This release is the third official stable release of the Blender 2.6 series, in which we will refine the 2.5 series and add exciting new features again.More information about this release.


      Bugs

      -

      Although Blender 2.61 is considered a stable release, you may encounter a bug. If you do, please help us by posting it in the bug tracker or using Help → Report a Bug from inside Blender. If it wasn’t reported yet, please log in (or register) and fill in detailed information about the error. Please post detailed instructions on how to reproduce it or post a .blend file showcasing the bug.

      +

      Although Blender 2.62 is considered a stable release, you may encounter a bug. If you do, please help us by posting it in the bug tracker or using Help → Report a Bug from inside Blender. If it wasn’t reported yet, please log in (or register) and fill in detailed information about the error. Please post detailed instructions on how to reproduce it or post a .blend file showcasing the bug.


      Package Contents

      The downloaded Blender package includes:

      @@ -47,7 +47,7 @@

      Links

      Users:

      General information www.blender.org
      - Full release log www.blender.org/development/release-logs/blender-261/
      + Full release log www.blender.org/development/release-logs/blender-262/
      Tutorials www.blender.org/education-help/
      Manual wiki.blender.org/index.php/Doc:Manual
      User Forum www.blenderartists.org
      diff -Nru blender-2.61/SConstruct blender-2.62/SConstruct --- blender-2.61/SConstruct 2011-12-13 19:57:52.000000000 +0000 +++ blender-2.62/SConstruct 2012-02-15 19:42:25.000000000 +0000 @@ -147,9 +147,8 @@ env.Tool('mstoolkit', [toolpath]) else: env = BlenderEnvironment(tools=[toolset], ENV = os.environ) - # xxx commented out, as was supressing warnings under mingw.. - #if env: - # btools.SetupSpawn(env) + if env: + btools.SetupSpawn(env) else: if bitness==64 and platform=='win32': env = BlenderEnvironment(ENV = os.environ, MSVS_ARCH='amd64') @@ -264,6 +263,7 @@ target_env_defs['WITH_BF_OCEANSIM'] = False target_env_defs['WITH_BF_DECIMATE'] = False target_env_defs['WITH_BF_BOOLEAN'] = False + target_env_defs['WITH_BF_REMESH'] = False target_env_defs['WITH_BF_PYTHON'] = False target_env_defs['WITH_BF_3DMOUSE'] = False @@ -726,10 +726,6 @@ # For MinGW and linuxcross static linking will be used dllsources += ['${LCGDIR}/gettext/lib/gnu_gettext.dll'] - #currently win64-vc doesn't appear to have libpng.dll - if env['OURPLATFORM'] != 'win64-vc': - dllsources += ['${BF_PNG_LIBPATH}/libpng.dll'] - dllsources += ['${BF_ZLIB_LIBPATH}/zlib.dll'] # Used when linking to libtiff was dynamic # keep it here until compilation on all platform would be ok @@ -760,7 +756,6 @@ if env['WITH_BF_OPENAL']: dllsources.append('${LCGDIR}/openal/lib/OpenAL32.dll') - dllsources.append('${LCGDIR}/openal/lib/wrap_oal.dll') if env['WITH_BF_SNDFILE']: dllsources.append('${LCGDIR}/sndfile/lib/libsndfile-1.dll') diff -Nru blender-2.61/source/blender/avi/intern/avi.c blender-2.62/source/blender/avi/intern/avi.c --- blender-2.61/source/blender/avi/intern/avi.c 2011-12-13 19:48:21.000000000 +0000 +++ blender-2.62/source/blender/avi/intern/avi.c 2012-02-15 19:33:04.000000000 +0000 @@ -63,7 +63,8 @@ /* implemetation */ -unsigned int GET_FCC (FILE *fp) { +unsigned int GET_FCC (FILE *fp) +{ unsigned char tmp[4]; tmp[0] = getc(fp); @@ -74,7 +75,8 @@ return FCC (tmp); } -unsigned int GET_TCC (FILE *fp) { +unsigned int GET_TCC (FILE *fp) +{ char tmp[5]; tmp[0] = getc(fp); @@ -85,7 +87,8 @@ return FCC (tmp); } -char *fcc_to_char (unsigned int fcc) { +char *fcc_to_char (unsigned int fcc) +{ DEBUG_FCC[0]= (fcc)&127; DEBUG_FCC[1]= (fcc>>8)&127; DEBUG_FCC[2]= (fcc>>16)&127; @@ -94,7 +97,8 @@ return DEBUG_FCC; } -char *tcc_to_char (unsigned int tcc) { +char *tcc_to_char (unsigned int tcc) +{ DEBUG_FCC[0]= (tcc)&127; DEBUG_FCC[1]= (tcc>>8)&127; DEBUG_FCC[2]= 0; @@ -103,7 +107,8 @@ return DEBUG_FCC; } -int AVI_get_stream (AviMovie *movie, int avist_type, int stream_num) { +int AVI_get_stream (AviMovie *movie, int avist_type, int stream_num) +{ int cur_stream; if (movie == NULL) @@ -121,7 +126,8 @@ return -AVI_ERROR_FOUND; } -static int fcc_get_stream (int fcc) { +static int fcc_get_stream (int fcc) +{ char fccs[4]; fccs[0] = fcc; @@ -132,7 +138,8 @@ return 10*(fccs[0]-'0') + (fccs[1]-'0'); } -static int fcc_is_data (int fcc) { +static int fcc_is_data (int fcc) +{ char fccs[4]; fccs[0] = fcc; @@ -148,7 +155,8 @@ return 1; } -AviError AVI_print_error (AviError in_error) { +AviError AVI_print_error (AviError in_error) +{ int error; if ((int) in_error < 0) @@ -190,12 +198,14 @@ return in_error; } /* -void AVI_set_debug (int mode) { +void AVI_set_debug (int mode) +{ AVI_DEBUG= mode; } */ /* -int AVI_is_avi (char *name) { +int AVI_is_avi (char *name) +{ FILE *fp; int ret; @@ -216,7 +226,8 @@ } */ -int AVI_is_avi (const char *name) { +int AVI_is_avi (const char *name) +{ int temp, fcca, j; AviMovie movie= {NULL}; AviMainHeader header; @@ -407,7 +418,8 @@ } -AviError AVI_open_movie (const char *name, AviMovie *movie) { +AviError AVI_open_movie (const char *name, AviMovie *movie) +{ int temp, fcca, size, j; DEBUG_PRINT("opening movie\n"); @@ -619,7 +631,11 @@ movie->entries[temp].Offset = GET_FCC (movie->fp); movie->entries[temp].Size = GET_FCC (movie->fp); - if (AVI_DEBUG) printf ("Index entry %04d: ChunkId:%s Flags:%d Offset:%d Size:%d\n", temp, fcc_to_char(movie->entries[temp].ChunkId), movie->entries[temp].Flags, movie->entries[temp].Offset, movie->entries[temp].Size); + if (AVI_DEBUG) { + printf("Index entry %04d: ChunkId:%s Flags:%d Offset:%d Size:%d\n", + temp, fcc_to_char(movie->entries[temp].ChunkId), movie->entries[temp].Flags, + movie->entries[temp].Offset, movie->entries[temp].Size); + } } /* Some AVI's have offset entries in absolute coordinates @@ -637,7 +653,8 @@ return AVI_ERROR_NONE; } -void *AVI_read_frame (AviMovie *movie, AviFormat format, int frame, int stream) { +void *AVI_read_frame (AviMovie *movie, AviFormat format, int frame, int stream) +{ int cur_frame=-1, temp, i=0, rewind=1; void *buffer; @@ -681,7 +698,8 @@ return buffer; } -AviError AVI_close (AviMovie *movie) { +AviError AVI_close (AviMovie *movie) +{ int i; fclose (movie->fp); @@ -703,7 +721,8 @@ return AVI_ERROR_NONE; } -AviError AVI_open_compress (char *name, AviMovie *movie, int streams, ...) { +AviError AVI_open_compress (char *name, AviMovie *movie, int streams, ...) +{ va_list ap; AviList list; AviChunk chunk; @@ -892,7 +911,8 @@ return AVI_ERROR_NONE; } -AviError AVI_write_frame (AviMovie *movie, int frame_num, ...) { +AviError AVI_write_frame (AviMovie *movie, int frame_num, ...) +{ AviList list; AviChunk chunk; AviIndexEntry *temp; @@ -999,7 +1019,8 @@ return AVI_ERROR_NONE; } -AviError AVI_close_compress (AviMovie *movie) { +AviError AVI_close_compress (AviMovie *movie) +{ int temp, movi_size, i; fseek (movie->fp, 0L, SEEK_END); diff -Nru blender-2.61/source/blender/avi/intern/codecs.c blender-2.62/source/blender/avi/intern/codecs.c --- blender-2.61/source/blender/avi/intern/codecs.c 2011-12-13 19:48:21.000000000 +0000 +++ blender-2.62/source/blender/avi/intern/codecs.c 2012-02-15 19:33:04.000000000 +0000 @@ -40,7 +40,8 @@ #include "mjpeg.h" #include "rgb32.h" -void *avi_format_convert (AviMovie *movie, int stream, void *buffer, AviFormat from, AviFormat to, int *size) { +void *avi_format_convert (AviMovie *movie, int stream, void *buffer, AviFormat from, AviFormat to, int *size) +{ if (from == to) return buffer; @@ -82,7 +83,8 @@ return buffer; } -int avi_get_data_id (AviFormat format, int stream) { +int avi_get_data_id (AviFormat format, int stream) +{ char fcc[5]; if (avi_get_format_type (format) == FCC("vids")) @@ -95,7 +97,8 @@ return FCC(fcc); } -int avi_get_format_type (AviFormat format) { +int avi_get_format_type (AviFormat format) +{ switch (format) { case AVI_FORMAT_RGB24: case AVI_FORMAT_RGB32: @@ -109,7 +112,8 @@ } } -int avi_get_format_fcc (AviFormat format) { +int avi_get_format_fcc (AviFormat format) +{ switch (format) { case AVI_FORMAT_RGB24: case AVI_FORMAT_RGB32: @@ -125,7 +129,8 @@ } } -int avi_get_format_compression (AviFormat format) { +int avi_get_format_compression (AviFormat format) +{ switch (format) { case AVI_FORMAT_RGB24: case AVI_FORMAT_RGB32: diff -Nru blender-2.61/source/blender/avi/intern/endian.c blender-2.62/source/blender/avi/intern/endian.c --- blender-2.61/source/blender/avi/intern/endian.c 2011-12-13 19:48:21.000000000 +0000 +++ blender-2.62/source/blender/avi/intern/endian.c 2012-02-15 19:33:04.000000000 +0000 @@ -43,7 +43,12 @@ #include "avi_intern.h" #ifdef __BIG_ENDIAN__ -static void invert (int *num) { +#include "MEM_guardedalloc.h" +#endif + +#ifdef __BIG_ENDIAN__ +static void invert (int *num) +{ int new=0,i,j; for (j=0; j < 4; j++) { @@ -55,7 +60,8 @@ *num = new; } -static void sinvert (short int *num) { +static void sinvert (short int *num) +{ short int new=0; int i,j; @@ -68,20 +74,23 @@ *num = new; } -static void Ichunk (AviChunk *chunk) { +static void Ichunk (AviChunk *chunk) +{ invert (&chunk->fcc); invert (&chunk->size); } #endif #ifdef __BIG_ENDIAN__ -static void Ilist (AviList *list){ +static void Ilist (AviList *list) +{ invert (&list->fcc); invert (&list->size); invert (&list->ids); } -static void Imainh (AviMainHeader *mainh) { +static void Imainh (AviMainHeader *mainh) +{ invert (&mainh->fcc); invert (&mainh->size); invert (&mainh->MicroSecPerFrame); @@ -100,7 +109,8 @@ invert (&mainh->Reserved[3]); } -static void Istreamh (AviStreamHeader *streamh) { +static void Istreamh (AviStreamHeader *streamh) +{ invert (&streamh->fcc); invert (&streamh->size); invert (&streamh->Type); @@ -122,7 +132,8 @@ sinvert (&streamh->bottom); } -static void Ibitmaph (AviBitmapInfoHeader *bitmaph) { +static void Ibitmaph (AviBitmapInfoHeader *bitmaph) +{ invert (&bitmaph->fcc); invert (&bitmaph->size); invert (&bitmaph->Size); @@ -138,7 +149,8 @@ invert (&bitmaph->ClrImportant); } -static void Imjpegu (AviMJPEGUnknown *mjpgu) { +static void Imjpegu (AviMJPEGUnknown *mjpgu) +{ invert (&mjpgu->a); invert (&mjpgu->b); invert (&mjpgu->c); @@ -148,7 +160,8 @@ invert (&mjpgu->g); } -static void Iindexe (AviIndexEntry *indexe) { +static void Iindexe (AviIndexEntry *indexe) +{ invert (&indexe->ChunkId); invert (&indexe->Flags); invert (&indexe->Offset); @@ -156,7 +169,8 @@ } #endif /* __BIG_ENDIAN__ */ -void awrite (AviMovie *movie, void *datain, int block, int size, FILE *fp, int type) { +void awrite (AviMovie *movie, void *datain, int block, int size, FILE *fp, int type) +{ #ifdef __BIG_ENDIAN__ void *data; diff -Nru blender-2.61/source/blender/avi/intern/mjpeg.c blender-2.62/source/blender/avi/intern/mjpeg.c --- blender-2.61/source/blender/avi/intern/mjpeg.c 2011-12-13 19:48:21.000000000 +0000 +++ blender-2.62/source/blender/avi/intern/mjpeg.c 2012-02-15 19:33:04.000000000 +0000 @@ -50,7 +50,8 @@ static int numbytes; -static void add_huff_table (j_decompress_ptr dinfo, JHUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val) { +static void add_huff_table (j_decompress_ptr dinfo, JHUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val) +{ if (*htblptr == NULL) *htblptr = jpeg_alloc_huff_table((j_common_ptr) dinfo); @@ -64,7 +65,8 @@ /* Set up the standard Huffman tables (cf. JPEG standard section K.3) */ /* IMPORTANT: these are only valid for 8-bit data precision! */ -static void std_huff_tables (j_decompress_ptr dinfo) { +static void std_huff_tables (j_decompress_ptr dinfo) +{ static const UINT8 bits_dc_luminance[17] = { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }; @@ -142,7 +144,8 @@ bits_ac_chrominance, val_ac_chrominance); } -static int Decode_JPEG(unsigned char *inBuffer, unsigned char *outBuffer, unsigned int width, unsigned int height, int bufsize) { +static int Decode_JPEG(unsigned char *inBuffer, unsigned char *outBuffer, unsigned int width, unsigned int height, int bufsize) +{ int rowstride; unsigned int y; struct jpeg_decompress_struct dinfo; @@ -194,7 +197,8 @@ return 1; } -static void Compress_JPEG(int quality, unsigned char *outbuffer, unsigned char *inBuffer, int width, int height, int bufsize) { +static void Compress_JPEG(int quality, unsigned char *outbuffer, unsigned char *inBuffer, int width, int height, int bufsize) +{ int i, rowstride; unsigned int y; struct jpeg_compress_struct cinfo; @@ -255,7 +259,8 @@ jpeg_destroy_compress(&cinfo); } -static void interlace(unsigned char *to, unsigned char *from, int width, int height) { +static void interlace(unsigned char *to, unsigned char *from, int width, int height) +{ int i, rowstride= width*3; for (i=0; idest->free_in_buffer; MEM_freeN(cinfo->dest); } -static void jpegmemdestmgr_build(j_compress_ptr cinfo, unsigned char *buffer, int bufsize) { +static void jpegmemdestmgr_build(j_compress_ptr cinfo, unsigned char *buffer, int bufsize) +{ cinfo->dest= MEM_mallocN(sizeof(*(cinfo->dest)), "avi.jpegmemdestmgr_build"); cinfo->dest->init_destination= jpegmemdestmgr_init_destination; @@ -410,11 +424,13 @@ /* Decompression from memory */ -static void jpegmemsrcmgr_init_source(j_decompress_ptr dinfo) { +static void jpegmemsrcmgr_init_source(j_decompress_ptr dinfo) +{ (void)dinfo; } -static boolean jpegmemsrcmgr_fill_input_buffer(j_decompress_ptr dinfo) { +static boolean jpegmemsrcmgr_fill_input_buffer(j_decompress_ptr dinfo) +{ unsigned char *buf= (unsigned char*) dinfo->src->next_input_byte-2; /* if we get called, must have run out of data */ @@ -429,7 +445,8 @@ return TRUE; } -static void jpegmemsrcmgr_skip_input_data(j_decompress_ptr dinfo, long skipcnt) { +static void jpegmemsrcmgr_skip_input_data(j_decompress_ptr dinfo, long skipcnt) +{ if (dinfo->src->bytes_in_buffersrc->bytes_in_buffer; @@ -437,13 +454,15 @@ dinfo->src->bytes_in_buffer-= skipcnt; } -static void jpegmemsrcmgr_term_source(j_decompress_ptr dinfo) { +static void jpegmemsrcmgr_term_source(j_decompress_ptr dinfo) +{ numbytes-= dinfo->src->bytes_in_buffer; MEM_freeN(dinfo->src); } -static void jpegmemsrcmgr_build(j_decompress_ptr dinfo, unsigned char *buffer, int bufsize) { +static void jpegmemsrcmgr_build(j_decompress_ptr dinfo, unsigned char *buffer, int bufsize) +{ dinfo->src= MEM_mallocN(sizeof(*(dinfo->src)), "avi.jpegmemsrcmgr_build"); dinfo->src->init_source= jpegmemsrcmgr_init_source; diff -Nru blender-2.61/source/blender/avi/intern/options.c blender-2.62/source/blender/avi/intern/options.c --- blender-2.61/source/blender/avi/intern/options.c 2011-12-13 19:48:21.000000000 +0000 +++ blender-2.62/source/blender/avi/intern/options.c 2012-02-15 19:33:04.000000000 +0000 @@ -43,7 +43,8 @@ /* avi_set_compress_options gets its own file... now don't WE feel important? */ -AviError AVI_set_compress_option (AviMovie *movie, int option_type, int stream, AviOption option, void *opt_data) { +AviError AVI_set_compress_option (AviMovie *movie, int option_type, int stream, AviOption option, void *opt_data) +{ int i; int useconds; diff -Nru blender-2.61/source/blender/avi/intern/rgb32.c blender-2.62/source/blender/avi/intern/rgb32.c --- blender-2.61/source/blender/avi/intern/rgb32.c 2011-12-13 19:48:21.000000000 +0000 +++ blender-2.62/source/blender/avi/intern/rgb32.c 2012-02-15 19:33:04.000000000 +0000 @@ -40,7 +40,8 @@ #include "MEM_guardedalloc.h" #include "rgb32.h" -void *avi_converter_from_rgb32 (AviMovie *movie, int stream, unsigned char *buffer, int *size) { +void *avi_converter_from_rgb32 (AviMovie *movie, int stream, unsigned char *buffer, int *size) +{ int y, x, rowstridea, rowstrideb; unsigned char *buf; @@ -65,7 +66,8 @@ return buf; } -void *avi_converter_to_rgb32 (AviMovie *movie, int stream, unsigned char *buffer, int *size) { +void *avi_converter_to_rgb32 (AviMovie *movie, int stream, unsigned char *buffer, int *size) +{ int i; unsigned char *buf; unsigned char *to, *from; diff -Nru blender-2.61/source/blender/blenfont/BLF_api.h blender-2.62/source/blender/blenfont/BLF_api.h --- blender-2.61/source/blender/blenfont/BLF_api.h 2011-12-13 19:51:08.000000000 +0000 +++ blender-2.62/source/blender/blenfont/BLF_api.h 2012-02-15 19:35:55.000000000 +0000 @@ -198,6 +198,8 @@ #define BLF_MATRIX (1<<4) #define BLF_ASPECT (1<<5) +#define BLF_DRAW_STR_DUMMY_MAX 1024 + // XXX, bad design extern int blf_mono_font; extern int blf_mono_font_render; // dont mess drawing with render threads. diff -Nru blender-2.61/source/blender/blenfont/BLF_translation.h blender-2.62/source/blender/blenfont/BLF_translation.h --- blender-2.61/source/blender/blenfont/BLF_translation.h 2011-12-13 19:51:08.000000000 +0000 +++ blender-2.62/source/blender/blenfont/BLF_translation.h 2012-02-15 19:35:55.000000000 +0000 @@ -33,6 +33,8 @@ #ifndef BLF_TRANSLATION_H #define BLF_TRANSLATION_H +#define TEXT_DOMAIN_NAME "blender" + /* blf_translation.c */ #ifdef WITH_INTERNATIONAL @@ -40,7 +42,8 @@ void BLF_free_unifont(void); #endif -const char* BLF_gettext(const char *msgid); +const char *BLF_gettext(const char *msgid); +const char *BLF_pgettext(const char *context, const char *message); /* blf_lang.c */ diff -Nru blender-2.61/source/blender/blenfont/CMakeLists.txt blender-2.62/source/blender/blenfont/CMakeLists.txt --- blender-2.61/source/blender/blenfont/CMakeLists.txt 2011-12-13 19:51:08.000000000 +0000 +++ blender-2.62/source/blender/blenfont/CMakeLists.txt 2012-02-15 19:35:55.000000000 +0000 @@ -57,5 +57,7 @@ add_definitions(-DWITH_INTERNATIONAL) endif() +add_definitions(-DGLEW_STATIC) + blender_add_lib(bf_blenfont "${SRC}" "${INC}" "${INC_SYS}") diff -Nru blender-2.61/source/blender/blenfont/intern/blf.c blender-2.62/source/blender/blenfont/intern/blf.c --- blender-2.61/source/blender/blenfont/intern/blf.c 2011-12-13 19:51:08.000000000 +0000 +++ blender-2.62/source/blender/blenfont/intern/blf.c 2012-02-15 19:35:55.000000000 +0000 @@ -479,7 +479,7 @@ } } -static void blf_draw__start(FontBLF *font) +static void blf_draw__start(FontBLF *font, GLint *mode, GLint *param) { /* * The pixmap alignment hack is handle @@ -490,6 +490,14 @@ glEnable(GL_TEXTURE_2D); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + /* Save the current matrix mode. */ + glGetIntegerv(GL_MATRIX_MODE, mode); + + glMatrixMode(GL_TEXTURE); + glPushMatrix(); + glLoadIdentity(); + + glMatrixMode(GL_MODELVIEW); glPushMatrix(); if (font->flags & BLF_MATRIX) @@ -509,11 +517,27 @@ /* always bind the texture for the first glyph */ font->tex_bind_state= -1; + /* Save the current parameter to restore it later. */ + glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, param); + if (*param != GL_MODULATE) + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } -static void blf_draw__end(void) +static void blf_draw__end(GLint mode, GLint param) { + /* and restore the original value. */ + if (param != GL_MODULATE) + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, param); + + glMatrixMode(GL_TEXTURE); glPopMatrix(); + + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + if (mode != GL_MODELVIEW) + glMatrixMode(mode); + glDisable(GL_BLEND); glDisable(GL_TEXTURE_2D); } @@ -521,22 +545,24 @@ void BLF_draw(int fontid, const char *str, size_t len) { FontBLF *font= BLF_get(fontid); + GLint mode, param; if (font && font->glyph_cache) { - blf_draw__start(font); + blf_draw__start(font, &mode, ¶m); blf_font_draw(font, str, len); - blf_draw__end(); + blf_draw__end(mode, param); } } void BLF_draw_ascii(int fontid, const char *str, size_t len) { FontBLF *font= BLF_get(fontid); + GLint mode, param; if (font && font->glyph_cache) { - blf_draw__start(font); + blf_draw__start(font, &mode, ¶m); blf_font_draw_ascii(font, str, len); - blf_draw__end(); + blf_draw__end(mode, param); } } diff -Nru blender-2.61/source/blender/blenfont/intern/blf_lang.c blender-2.62/source/blender/blenfont/intern/blf_lang.c --- blender-2.61/source/blender/blenfont/intern/blf_lang.c 2011-12-13 19:51:08.000000000 +0000 +++ blender-2.62/source/blender/blenfont/intern/blf_lang.c 2012-02-15 19:35:55.000000000 +0000 @@ -32,6 +32,8 @@ #include #include +#include "BKE_global.h" + #include "BLF_api.h" #include "BLF_translation.h" /* own include */ @@ -58,7 +60,6 @@ #include "BLI_utildefines.h" #include "BLI_path_util.h" -#define DOMAIN_NAME "blender" #define SYSTEM_ENCODING_DEFAULT "UTF-8" #define FONT_SIZE_DEFAULT 12 @@ -82,8 +83,13 @@ "catalan", "ca_AD", "czech", "cs_CZ", "ptb", "pt_BR", +#if defined (_WIN32) && !defined(FREE_WINDOWS) "Chinese (Simplified)_China.1252", "zh_CN", "Chinese (Traditional)_China.1252", "zh_TW", +#else + "chs", "zh_CN", + "cht", "zh_TW", +#endif "russian", "ru_RU", "croatian", "hr_HR", "serbian", "sr_RS", @@ -96,7 +102,9 @@ "korean", "ko_KR", "nepali", "ne_NP", "persian", "fa_PE", - "indonesian", "id_ID" + "indonesian", "id_ID", + "serbian (latin)", "sr_RS@latin", + "kyrgyz", "ky", }; void BLF_lang_init(void) @@ -115,15 +123,50 @@ } +/* get LANG/LANGUAGE environment variable */ +static void get_language_variable(const char *varname, char *var, int maxlen) +{ + char *env= getenv(varname); + + if(env) { + char *s; + + /* store defaul locale */ + BLI_strncpy(var, env, maxlen); + + /* use first language as default */ + s= strchr(var, ':'); + if(s) + s[0]= 0; + } +} + +/* get language to be used based on locale(which might be empty when using default language) and + * LANG environment variable + */ +static void get_language(const char *locale, const char *lang, char *language, int maxlen) +{ + if(locale[0]) { + BLI_strncpy(language, locale, maxlen); + } + else { + char *s; + + BLI_strncpy(language, lang, maxlen); + + s= strchr(language, '.'); + if(s) + s[0]= 0; + } +} + /* XXX WARNING!!! IN osx somehow the previous function call jumps in this one??? (ton, ppc) */ void BLF_lang_set(const char *str) { char *locreturn; const char *short_locale; int ok= 1; -#if defined (_WIN32) && !defined(FREE_WINDOWS) - const char *long_locale = locales[ 2 * U.language]; -#endif + const char *long_locale = locales[2 * U.language]; if((U.transopts&USER_DOTRANSLATE)==0) return; @@ -149,50 +192,72 @@ locreturn= setlocale(LC_ALL, long_locale); if (locreturn == NULL) { - printf("Could not change locale to %s\n", long_locale); + if(G.f & G_DEBUG) + printf("Could not change locale to %s\n", long_locale); + ok= 0; } #else { - const char *locale; - static char default_locale[64]="\0"; + static char default_lang[64]="\0"; + static char default_language[64]="\0"; - if(default_locale[0]==0) { - char *env_language= getenv("LANGUAGE"); + if(default_lang[0]==0) + get_language_variable("LANG", default_lang, sizeof(default_lang)); - if(env_language) { - char *s; + if(default_language[0]==0) + get_language_variable("LANGUAGE", default_language, sizeof(default_language)); - /* store defaul locale */ - BLI_strncpy(default_locale, env_language, sizeof(default_locale)); + if(short_locale[0]) { + if(G.f & G_DEBUG) + printf("Setting LANG= and LANGUAGE to %s\n", short_locale); - /* use first language as default */ - s= strchr(default_locale, ':'); - if(s) s[0]= 0; - } + BLI_setenv("LANG", short_locale); + BLI_setenv("LANGUAGE", short_locale); } + else { + if(G.f & G_DEBUG) + printf("Setting LANG=%s and LANGUAGE=%s\n", default_lang, default_language); - if(short_locale[0]) - locale= short_locale; - else - locale= default_locale; - - BLI_setenv("LANG", locale); - BLI_setenv("LANGUAGE", locale); + BLI_setenv("LANG", default_lang); + BLI_setenv("LANGUAGE", default_language); + } - locreturn= setlocale(LC_ALL, locale); + locreturn= setlocale(LC_ALL, short_locale); - if (locreturn == NULL) { - char *short_locale_utf8= BLI_sprintfN("%s.UTF-8", short_locale); + if(locreturn == NULL) { + char *short_locale_utf8= NULL; - locreturn= setlocale(LC_ALL, short_locale_utf8); + if(short_locale[0]) { + short_locale_utf8= BLI_sprintfN("%s.UTF-8", short_locale); + locreturn= setlocale(LC_ALL, short_locale_utf8); + } if (locreturn == NULL) { - printf("Could not change locale to %s nor %s\n", short_locale, short_locale_utf8); + char language[65]; + + get_language(long_locale, default_lang, language, sizeof(language)); + + if(G.f & G_DEBUG) { + if(short_locale[0]) + printf("Could not change locale to %s nor %s\n", short_locale, short_locale_utf8); + else + printf("Could not reset locale\n"); + + printf("Fallback to LANG=%s and LANGUAGE=%s\n", default_lang, language); + } + + /* fallback to default settings */ + BLI_setenv("LANG", default_lang); + BLI_setenv("LANGUAGE", language); + + locreturn= setlocale(LC_ALL, ""); + ok= 0; } - MEM_freeN(short_locale_utf8); + if(short_locale_utf8) + MEM_freeN(short_locale_utf8); } } #endif @@ -204,15 +269,15 @@ setlocale(LC_NUMERIC, "C"); - textdomain(DOMAIN_NAME); - bindtextdomain(DOMAIN_NAME, global_messagepath); - bind_textdomain_codeset(DOMAIN_NAME, global_encoding_name); + textdomain(TEXT_DOMAIN_NAME); + bindtextdomain(TEXT_DOMAIN_NAME, global_messagepath); + bind_textdomain_codeset(TEXT_DOMAIN_NAME, global_encoding_name); } void BLF_lang_encoding(const char *str) { BLI_strncpy(global_encoding_name, str, sizeof(global_encoding_name)); - /* bind_textdomain_codeset(DOMAIN_NAME, encoding_name); */ + /* bind_textdomain_codeset(TEXT_DOMAIN_NAME, encoding_name); */ } #else /* ! WITH_INTERNATIONAL */ diff -Nru blender-2.61/source/blender/blenfont/intern/blf_translation.c blender-2.62/source/blender/blenfont/intern/blf_translation.c --- blender-2.61/source/blender/blenfont/intern/blf_translation.c 2011-12-13 19:51:08.000000000 +0000 +++ blender-2.62/source/blender/blenfont/intern/blf_translation.c 2012-02-15 19:35:55.000000000 +0000 @@ -29,9 +29,19 @@ */ #include +#include #ifdef WITH_INTERNATIONAL #include +#include + +#define GETTEXT_CONTEXT_GLUE "\004" + +/* needed for windows version of gettext */ +#ifndef LC_MESSAGES +# define LC_MESSAGES 1729 +#endif + #endif #include "MEM_guardedalloc.h" @@ -91,6 +101,41 @@ #endif } +const char *BLF_pgettext(const char *context, const char *message) +{ +#ifdef WITH_INTERNATIONAL + char static_msg_ctxt_id[1024]; + char *dynamic_msg_ctxt_id = NULL; + char *msg_ctxt_id; + const char *translation; + + size_t overall_length = strlen(context) + strlen(message) + sizeof(GETTEXT_CONTEXT_GLUE) + 1; + + if (overall_length > sizeof(static_msg_ctxt_id)) { + dynamic_msg_ctxt_id = malloc(overall_length); + msg_ctxt_id = dynamic_msg_ctxt_id; + } + else { + msg_ctxt_id = static_msg_ctxt_id; + } + + sprintf(msg_ctxt_id, "%s%s%s", context, GETTEXT_CONTEXT_GLUE, message); + + translation = (char*)dcgettext(TEXT_DOMAIN_NAME, msg_ctxt_id, LC_MESSAGES); + + if (dynamic_msg_ctxt_id) + free(dynamic_msg_ctxt_id); + + if (translation == msg_ctxt_id) + translation = message; + + return translation; +#else + (void)context; + return message; +#endif +} + int BLF_translate_iface(void) { #ifdef WITH_INTERNATIONAL @@ -132,4 +177,3 @@ return msgid; #endif } - diff -Nru blender-2.61/source/blender/blenfont/SConscript blender-2.62/source/blender/blenfont/SConscript --- blender-2.61/source/blender/blenfont/SConscript 2011-12-13 19:51:08.000000000 +0000 +++ blender-2.62/source/blender/blenfont/SConscript 2012-02-15 19:35:55.000000000 +0000 @@ -9,7 +9,7 @@ incs += ' ' + env['BF_FREETYPE_INC'] incs += ' ' + env['BF_GETTEXT_INC'] -defs = [] +defs = ['GLEW_STATIC'] if sys.platform == 'win32' or env['OURPLATFORM'] == 'linuxcross': defs.append('_WIN32') diff -Nru blender-2.61/source/blender/blenkernel/BKE_anim.h blender-2.62/source/blender/blenkernel/BKE_anim.h --- blender-2.61/source/blender/blenkernel/BKE_anim.h 2011-12-13 19:49:19.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/BKE_anim.h 2012-02-15 19:34:08.000000000 +0000 @@ -61,7 +61,7 @@ void free_path(struct Path *path); void calc_curvepath(struct Object *ob); int interval_test(int min, int max, int p1, int cycl); -int where_on_path(struct Object *ob, float ctime, float *vec, float *dir, float *quat, float *radius, float *weight); +int where_on_path(struct Object *ob, float ctime, float vec[4], float dir[3], float quat[4], float *radius, float *weight); /* ---------------------------------------------------- */ /* Dupli-Geometry */ diff -Nru blender-2.61/source/blender/blenkernel/BKE_armature.h blender-2.62/source/blender/blenkernel/BKE_armature.h --- blender-2.61/source/blender/blenkernel/BKE_armature.h 2011-12-13 19:49:19.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/BKE_armature.h 2012-02-15 19:34:08.000000000 +0000 @@ -82,11 +82,11 @@ void make_local_armature(struct bArmature *arm); struct bArmature *copy_armature(struct bArmature *arm); -int bone_autoside_name (char name[32], int strip_number, short axis, float head, float tail); +int bone_autoside_name (char name[64], int strip_number, short axis, float head, float tail); struct Bone *get_named_bone (struct bArmature *arm, const char *name); -float distfactor_to_bone (float vec[3], float b1[3], float b2[3], float rad1, float rad2, float rdist); +float distfactor_to_bone(const float vec[3], const float b1[3], const float b2[3], float rad1, float rad2, float rdist); void where_is_armature (struct bArmature *arm); void where_is_armature_bone(struct Bone *bone, struct Bone *prevbone); @@ -109,11 +109,17 @@ void armature_loc_pose_to_bone(struct bPoseChannel *pchan, float *inloc, float *outloc); void armature_mat_pose_to_delta(float delta_mat[][4], float pose_mat[][4], float arm_mat[][4]); +void armature_mat_pose_to_bone_ex(struct Object *ob, struct bPoseChannel *pchan, float inmat[][4], float outmat[][4]); + void pchan_mat3_to_rot(struct bPoseChannel *pchan, float mat[][3], short use_compat); void pchan_apply_mat4(struct bPoseChannel *pchan, float mat[][4], short use_comat); void pchan_to_mat4(struct bPoseChannel *pchan, float chan_mat[4][4]); void pchan_calc_mat(struct bPoseChannel *pchan); +/* Get the "pchan to pose" transform matrix. These matrices apply the effects of + * HINGE/NO_SCALE/NO_LOCAL_LOCATION options over the pchan loc/rot/scale transformations. */ +void pchan_to_pose_mat(struct bPoseChannel *pchan, float rotscale_mat[][4], float loc_mat[][4]); + /* Rotation Mode Conversions - Used for PoseChannels + Objects... */ void BKE_rotMode_change_values(float quat[4], float eul[3], float axis[3], float *angle, short oldMode, short newMode); diff -Nru blender-2.61/source/blender/blenkernel/BKE_array_mallocn.h blender-2.62/source/blender/blenkernel/BKE_array_mallocn.h --- blender-2.61/source/blender/blenkernel/BKE_array_mallocn.h 2011-12-13 19:49:19.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/BKE_array_mallocn.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,85 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the 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. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifndef BKE_ARRAY_MALLOCN_H -#define BKE_ARRAY_MALLOCN_H - -/** \file BKE_array_mallocn.h - * \ingroup bke - * \brief little array macro library. - */ - -/* example of usage: - -int *arr = NULL; -V_DECLARE(arr); -int i; - -for (i=0; i<10; i++) { - V_GROW(arr); - arr[i] = something; -} -V_FREE(arr); - -arrays are buffered, using double-buffering (so on each reallocation, -the array size is doubled). supposedly this should give good Big Oh -behaviour, though it may not be the best in practice. -*/ - -#define V_DECLARE(vec) int _##vec##_count=0; void *_##vec##_tmp - -/*in the future, I plan on having V_DECLARE allocate stack memory it'll - use at first, and switch over to heap when it needs more. that'll mess - up cases where you'd want to use this API to build a dynamic list for - non-local use, so all such cases should use this macro.*/ -#define V_DYNDECLARE(vec) V_DECLARE(vec) - -/*this returns the entire size of the array, including any buffering.*/ -#define V_SIZE(vec) ((signed int)((vec)==NULL ? 0 : MEM_allocN_len(vec) / sizeof(*vec))) - -/*this returns the logical size of the array, not including buffering.*/ -#define V_COUNT(vec) _##vec##_count - -/*grow the array by one. zeroes the new elements.*/ -#define V_GROW(vec) \ - V_SIZE(vec) > _##vec##_count ? _##vec##_count++ : \ - ((_##vec##_tmp = MEM_callocN(sizeof(*vec)*(_##vec##_count*2+2), #vec " " __FILE__ " ")),\ - (void)(vec && memcpy(_##vec##_tmp, vec, sizeof(*vec) * _##vec##_count)),\ - (void)(vec && (MEM_freeN(vec),1)),\ - (vec = _##vec##_tmp),\ - _##vec##_count++) - -#define V_FREE(vec) if (vec) MEM_freeN(vec); - -/*resets the logical size of an array to zero, but doesn't - free the memory.*/ -#define V_RESET(vec) _##vec##_count=0 - -/*set the count of the array*/ -#define V_SETCOUNT(vec, count) _##vec##_count = (count) - -#endif // BKE_ARRAY_MALLOCN_H diff -Nru blender-2.61/source/blender/blenkernel/BKE_blender.h blender-2.62/source/blender/blenkernel/BKE_blender.h --- blender-2.61/source/blender/blenkernel/BKE_blender.h 2011-12-13 19:49:19.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/BKE_blender.h 2012-02-15 19:34:08.000000000 +0000 @@ -41,7 +41,7 @@ /* these lines are grep'd, watch out for our not-so-awesome regex * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ -#define BLENDER_VERSION 261 +#define BLENDER_VERSION 262 #define BLENDER_SUBVERSION 0 #define BLENDER_MINVERSION 250 diff -Nru blender-2.61/source/blender/blenkernel/BKE_booleanops_mesh.h blender-2.62/source/blender/blenkernel/BKE_booleanops_mesh.h --- blender-2.61/source/blender/blenkernel/BKE_booleanops_mesh.h 2011-12-13 19:49:19.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/BKE_booleanops_mesh.h 2012-02-15 19:34:08.000000000 +0000 @@ -24,8 +24,8 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef BKE_PyBooleanOps_h -#define BKE_PyBooleanOps_h +#ifndef BKE_BOOLEANOPS_MESH_H +#define BKE_BOOLEANOPS_MESH_H /** \file BKE_booleanops_mesh.h * \ingroup bke diff -Nru blender-2.61/source/blender/blenkernel/BKE_brush.h blender-2.62/source/blender/blenkernel/BKE_brush.h --- blender-2.61/source/blender/blenkernel/BKE_brush.h 2011-12-13 19:49:19.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/BKE_brush.h 2012-02-15 19:34:08.000000000 +0000 @@ -59,7 +59,8 @@ int brush_clone_image_delete(struct Brush *brush); /* jitter */ -void brush_jitter_pos(struct Brush *brush, float *pos, float *jitterpos); +void brush_jitter_pos(const struct Scene *scene, struct Brush *brush, + float *pos, float *jitterpos); /* brush curve */ void brush_curve_preset(struct Brush *b, /*enum CurveMappingPreset*/int preset); @@ -67,8 +68,8 @@ float brush_curve_strength(struct Brush *br, float p, const float len); /* used for sculpt */ /* sampling */ -void brush_sample_tex(struct Brush *brush, float *xy, float *rgba, const int thread); -void brush_imbuf_new(struct Brush *brush, short flt, short texfalloff, int size, +void brush_sample_tex(const struct Scene *scene, struct Brush *brush, const float xy[2], float rgba[4], const int thread); +void brush_imbuf_new(const struct Scene *scene, struct Brush *brush, short flt, short texfalloff, int size, struct ImBuf **imbuf, int use_color_correction); /* painting */ @@ -76,7 +77,7 @@ typedef struct BrushPainter BrushPainter; typedef int (*BrushFunc)(void *user, struct ImBuf *ibuf, float *lastpos, float *pos); -BrushPainter *brush_painter_new(struct Brush *brush); +BrushPainter *brush_painter_new(struct Scene *scene, struct Brush *brush); void brush_painter_require_imbuf(BrushPainter *painter, short flt, short texonly, int size); int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, @@ -92,23 +93,27 @@ /* unified strength and size */ -int brush_size(struct Brush *brush); -void brush_set_size(struct Brush *brush, int value); +int brush_size(const struct Scene *scene, struct Brush *brush); +void brush_set_size(struct Scene *scene, struct Brush *brush, int value); -int brush_use_locked_size(struct Brush *brush); -void brush_set_use_locked_size(struct Brush *brush, int value); +float brush_unprojected_radius(const struct Scene *scene, struct Brush *brush); +void brush_set_unprojected_radius(struct Scene *scene, struct Brush *brush, float value); -int brush_use_alpha_pressure(struct Brush *brush); -void brush_set_use_alpha_pressure(struct Brush *brush, int value); +float brush_alpha(const struct Scene *scene, struct Brush *brush); -int brush_use_size_pressure(struct Brush *brush); -void brush_set_use_size_pressure(struct Brush *brush, int value); - -float brush_unprojected_radius(struct Brush *brush); -void brush_set_unprojected_radius(struct Brush *brush, float value); - -float brush_alpha(struct Brush *brush); -void brush_set_alpha(struct Brush *brush, float value); +int brush_use_locked_size(const struct Scene *scene, struct Brush *brush); +int brush_use_alpha_pressure(const struct Scene *scene, struct Brush *brush); +int brush_use_size_pressure(const struct Scene *scene, struct Brush *brush); + +/* scale unprojected radius to reflect a change in the brush's 2D size */ +void brush_scale_unprojected_radius(float *unprojected_radius, + int new_brush_size, + int old_brush_size); + +/* scale brush size to reflect a change in the brush's unprojected radius */ +void brush_scale_size(int *brush_size, + float new_unprojected_radius, + float old_unprojected_radius); /* debugging only */ void brush_debug_print_state(struct Brush *br); diff -Nru blender-2.61/source/blender/blenkernel/BKE_cloth.h blender-2.62/source/blender/blenkernel/BKE_cloth.h --- blender-2.61/source/blender/blenkernel/BKE_cloth.h 2011-12-13 19:49:19.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/BKE_cloth.h 2012-02-15 19:34:08.000000000 +0000 @@ -85,6 +85,7 @@ struct Implicit_Data *implicit; /* our implicit solver connects to this pointer */ struct Implicit_Data *implicitEM; /* our implicit solver connects to this pointer */ struct EdgeHash *edgehash; /* used for selfcollisions */ + int last_frame, pad4; } Cloth; /** @@ -215,7 +216,7 @@ void cloth_free_modifier_extern ( struct ClothModifierData *clmd ); void cloth_free_modifier ( struct ClothModifierData *clmd ); void cloth_init ( struct ClothModifierData *clmd ); -struct DerivedMesh *clothModifier_do ( struct ClothModifierData *clmd, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm); +void clothModifier_do ( struct ClothModifierData *clmd, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm, float (*vertexCos)[3]); void cloth_update_normals ( ClothVertex *verts, int nVerts, struct MFace *face, int totface ); int cloth_uses_vgroup(struct ClothModifierData *clmd); diff -Nru blender-2.61/source/blender/blenkernel/BKE_colortools.h blender-2.62/source/blender/blenkernel/BKE_colortools.h --- blender-2.61/source/blender/blenkernel/BKE_colortools.h 2011-12-13 19:49:19.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/BKE_colortools.h 2012-02-15 19:34:08.000000000 +0000 @@ -45,9 +45,6 @@ # define DO_INLINE static inline #endif -void floatbuf_to_srgb_byte(float *rectf, unsigned char *rectc, int x1, int x2, int y1, int y2, int w); -void floatbuf_to_byte(float *rectf, unsigned char *rectc, int x1, int x2, int y1, int y2, int w); - struct CurveMapping *curvemapping_add(int tot, float minx, float miny, float maxx, float maxy); void curvemapping_free(struct CurveMapping *cumap); struct CurveMapping *curvemapping_copy(struct CurveMapping *cumap); diff -Nru blender-2.61/source/blender/blenkernel/BKE_customdata.h blender-2.62/source/blender/blenkernel/BKE_customdata.h --- blender-2.61/source/blender/blenkernel/BKE_customdata.h 2011-12-13 19:49:19.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/BKE_customdata.h 2012-02-15 19:34:08.000000000 +0000 @@ -38,10 +38,12 @@ extern "C" { #endif +#include "../blenloader/BLO_sys_types.h" /* XXX, should have a more generic include for this */ + struct ID; struct CustomData; struct CustomDataLayer; -typedef unsigned int CustomDataMask; +typedef uint64_t CustomDataMask; extern const CustomDataMask CD_MASK_BAREMESH; extern const CustomDataMask CD_MASK_MESH; @@ -65,12 +67,17 @@ #define CD_DUPLICATE 4 /* do a full copy of all layers, only allowed if source has same number of elements */ +#define CD_TYPE_AS_MASK(_type) (CustomDataMask)((CustomDataMask)1 << (CustomDataMask)(_type)) + /* initialises a CustomData object with the same layer setup as source. * mask is a bitfield where (mask & (1 << (layer type))) indicates * if a layer should be copied or not. alloctype must be one of the above. */ void CustomData_copy(const struct CustomData *source, struct CustomData *dest, CustomDataMask mask, int alloctype, int totelem); +/* BMESH_TODO, not really a public function but readfile.c needs it */ +void CustomData_update_typemap(struct CustomData *data); + /* same as the above, except that this will preserve existing layers, and only * add the layers that were not there yet */ void CustomData_merge(const struct CustomData *source, struct CustomData *dest, @@ -121,9 +128,10 @@ /* duplicate data of a layer with flag NOFREE, and remove that flag. * returns the layer data */ -void *CustomData_duplicate_referenced_layer(struct CustomData *data, int type); +void *CustomData_duplicate_referenced_layer(struct CustomData *data, const int type, const int totelem); void *CustomData_duplicate_referenced_layer_named(struct CustomData *data, - int type, const char *name); + const int type, const char *name, const int totelem); +int CustomData_is_referenced_layer(struct CustomData *data, int type); /* set the CD_FLAG_NOCOPY flag in custom data layers where the mask is * zero for the layer type, so only layer types specified by the mask @@ -140,12 +148,13 @@ void CustomData_copy_data(const struct CustomData *source, struct CustomData *dest, int source_index, int dest_index, int count); +void CustomData_copy_elements(int type, void *source, void *dest, int count); void CustomData_em_copy_data(const struct CustomData *source, struct CustomData *dest, void *src_block, void **dest_block); void CustomData_bmesh_copy_data(const struct CustomData *source, - struct CustomData *dest,void *src_block, - void **dest_block); + struct CustomData *dest, void *src_block, + void **dest_block); void CustomData_em_validate_data(struct CustomData *data, void *block, int sub_elements); /* frees data in a CustomData object @@ -187,11 +196,18 @@ * returns NULL if there is no layer of type */ void *CustomData_get(const struct CustomData *data, int index, int type); +void *CustomData_get_n(const struct CustomData *data, int type, int index, int n); void *CustomData_em_get(const struct CustomData *data, void *block, int type); void *CustomData_em_get_n(const struct CustomData *data, void *block, int type, int n); void *CustomData_bmesh_get(const struct CustomData *data, void *block, int type); void *CustomData_bmesh_get_n(const struct CustomData *data, void *block, int type, int n); +/* gets the layer at physical index n, with no type checking. + */ +void *CustomData_bmesh_get_layer_n(const struct CustomData *data, void *block, int n); + +int CustomData_set_layer_name(const struct CustomData *data, int type, int n, const char *name); + /* gets a pointer to the active or first layer of type * returns NULL if there is no layer of type */ @@ -201,6 +217,7 @@ const char *name); int CustomData_get_layer_index(const struct CustomData *data, int type); +int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n); int CustomData_get_named_layer_index(const struct CustomData *data, int type, const char *name); int CustomData_get_active_layer_index(const struct CustomData *data, int type); int CustomData_get_render_layer_index(const struct CustomData *data, int type); @@ -227,6 +244,11 @@ void CustomData_bmesh_set_n(struct CustomData *data, void *block, int type, int n, void *source); +/*sets the data of the block at physical layer n. no real type checking + *is performed. + */ +void CustomData_bmesh_set_layer_n(struct CustomData *data, void *block, int n, + void *source); /* set the pointer of to the first layer of type. the old data is not freed. * returns the value of ptr if the layer is found, NULL otherwise diff -Nru blender-2.61/source/blender/blenkernel/BKE_deform.h blender-2.62/source/blender/blenkernel/BKE_deform.h --- blender-2.61/source/blender/blenkernel/BKE_deform.h 2011-12-13 19:49:19.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/BKE_deform.h 2012-02-15 19:34:08.000000000 +0000 @@ -43,7 +43,6 @@ void defgroup_copy_list(struct ListBase *lb1, struct ListBase *lb2); struct bDeformGroup *defgroup_duplicate(struct bDeformGroup *ingroup); struct bDeformGroup *defgroup_find_name(struct Object *ob, const char *name); -int defgroup_find_index(struct Object *ob, struct bDeformGroup *dg); int *defgroup_flip_map(struct Object *ob, int *flip_map_len, int use_default); int *defgroup_flip_map_single(struct Object *ob, int *flip_map_len, int use_default, int defgroup); int defgroup_flip_index(struct Object *ob, int index, int use_default); @@ -66,10 +65,11 @@ void defvert_remap (struct MDeformVert *dvert, int *map, const int map_len); void defvert_flip(struct MDeformVert *dvert, const int *flip_map, const int flip_map_len); void defvert_normalize(struct MDeformVert *dvert); +void defvert_normalize_lock(struct MDeformVert *dvert, const int def_nr_lock); /* utility function, note that 32 chars is the maximum string length since its only * used with defgroups currently */ -void flip_side_name(char name[32], const char from_name[32], int strip_number); +void flip_side_name(char name[64], const char from_name[64], int strip_number); #endif diff -Nru blender-2.61/source/blender/blenkernel/BKE_DerivedMesh.h blender-2.62/source/blender/blenkernel/BKE_DerivedMesh.h --- blender-2.61/source/blender/blenkernel/BKE_DerivedMesh.h 2011-12-13 19:49:19.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/BKE_DerivedMesh.h 2012-02-15 19:34:08.000000000 +0000 @@ -538,6 +538,15 @@ float (**deformmats)[3][3], float (**deformcos)[3]); void weight_to_rgb(float r_rgb[3], const float weight); +/* Update the weight MCOL preview layer. + * If weights are NULL, use object's active vgroup(s). + * Else, weights must be an array of weight float values. + * If indices is NULL, it must be of numVerts length. + * Else, it must be of num length, as indices, which contains vertices' idx to apply weights to. + * (other vertices are assumed zero weight). + */ +void DM_update_weight_mcol(struct Object *ob, struct DerivedMesh *dm, int const draw_flag, + float *weights, int num, const int *indices); /* convert layers requested by a GLSL material to actually available layers in * the DerivedMesh, with both a pointer for arrays and an offset for editmesh */ @@ -584,5 +593,10 @@ /* Set object's bounding box based on DerivedMesh min/max data */ void DM_set_object_boundbox(struct Object *ob, DerivedMesh *dm); +/* debug only */ +#ifndef NDEBUG +char *DM_debug_info(DerivedMesh *dm); +void DM_debug_print(DerivedMesh *dm); #endif +#endif diff -Nru blender-2.61/source/blender/blenkernel/BKE_global.h blender-2.62/source/blender/blenkernel/BKE_global.h --- blender-2.61/source/blender/blenkernel/BKE_global.h 2011-12-13 19:49:19.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/BKE_global.h 2012-02-15 19:34:08.000000000 +0000 @@ -53,7 +53,7 @@ struct Main *main; /* strings: lastsaved */ - char ima[256], lib[256]; + char ima[1024], lib[1024]; /* 1024 = FILE_MAX */ /* flag: if != 0 G.main->name contains valid relative base path */ int relbase_valid; @@ -141,6 +141,7 @@ #define G_FILE_RECOVER (1 << 23) #define G_FILE_RELATIVE_REMAP (1 << 24) #define G_FILE_HISTORY (1 << 25) +#define G_FILE_MESH_COMPAT (1 << 26) /* BMesh option to save as older mesh format */ /* G.windowstate */ #define G_WINDOWSTATE_USERDEF 0 diff -Nru blender-2.61/source/blender/blenkernel/BKE_image.h blender-2.62/source/blender/blenkernel/BKE_image.h --- blender-2.61/source/blender/blenkernel/BKE_image.h 2011-12-13 19:49:19.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/BKE_image.h 2012-02-15 19:34:08.000000000 +0000 @@ -186,7 +186,7 @@ int BKE_image_has_alpha(struct Image *image); /* image_gen.c */ -void BKE_image_buf_fill_color(unsigned char *rect, float *rect_float, int width, int height, float color[4]); +void BKE_image_buf_fill_color(unsigned char *rect, float *rect_float, int width, int height, const float color[4]); void BKE_image_buf_fill_checker(unsigned char *rect, float *rect_float, int height, int width); void BKE_image_buf_fill_checker_color(unsigned char *rect, float *rect_float, int height, int width); diff -Nru blender-2.61/source/blender/blenkernel/BKE_lattice.h blender-2.62/source/blender/blenkernel/BKE_lattice.h --- blender-2.61/source/blender/blenkernel/BKE_lattice.h 2011-12-13 19:49:19.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/BKE_lattice.h 2012-02-15 19:34:08.000000000 +0000 @@ -59,7 +59,7 @@ struct DerivedMesh *dm, float (*vertexCos)[3], int numVerts, const char *vgroup, short defaxis); void curve_deform_vector(struct Scene *scene, struct Object *cuOb, struct Object *target, - float *orco, float *vec, float mat[][3], int no_rot_axis); + float orco[3], float vec[3], float mat[][3], int no_rot_axis); void lattice_deform_verts(struct Object *laOb, struct Object *target, struct DerivedMesh *dm, float (*vertexCos)[3], diff -Nru blender-2.61/source/blender/blenkernel/BKE_main.h blender-2.62/source/blender/blenkernel/BKE_main.h --- blender-2.61/source/blender/blenkernel/BKE_main.h 2011-12-13 19:49:19.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/BKE_main.h 2012-02-15 19:34:08.000000000 +0000 @@ -50,7 +50,7 @@ typedef struct Main { struct Main *next, *prev; - char name[240]; + char name[1024]; /* 1024 = FILE_MAX */ short versionfile, subversionfile; short minversionfile, minsubversionfile; int revision; /* svn revision of binary that saved file */ diff -Nru blender-2.61/source/blender/blenkernel/BKE_mesh.h blender-2.62/source/blender/blenkernel/BKE_mesh.h --- blender-2.61/source/blender/blenkernel/BKE_mesh.h 2011-12-13 19:49:19.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/BKE_mesh.h 2012-02-15 19:34:08.000000000 +0000 @@ -37,11 +37,13 @@ struct DispList; struct ListBase; struct EditMesh; -struct MDeformVert; struct Mesh; +struct MPoly; +struct MLoop; struct MFace; struct MEdge; struct MVert; +struct MDeformVert; struct MCol; struct Object; struct MTFace; @@ -49,7 +51,11 @@ struct CustomData; struct DerivedMesh; struct Scene; - +struct MLoopUV; +struct UvVertMap; +struct UvMapVert; +struct UvElementMap; +struct UvElement; #ifdef __cplusplus extern "C" { #endif @@ -57,6 +63,11 @@ struct EditMesh *BKE_mesh_get_editmesh(struct Mesh *me); void BKE_mesh_end_editmesh(struct Mesh *me, struct EditMesh *em); +/* for forwards compat only quad->tri polys to mface, skip ngons. + */ +int mesh_mpoly_to_mface(struct CustomData *fdata, struct CustomData *ldata, + struct CustomData *pdata, int totface, int totloop, int totpoly); + void unlink_mesh(struct Mesh *me); void free_mesh(struct Mesh *me); struct Mesh *add_mesh(const char *name); @@ -118,6 +129,39 @@ unsigned char tfindex, separate, flag; } UvMapVert; +typedef struct UvElementMap { + /* address UvElements by their vertex */ + struct UvElement **vert; + /* UvElement Store */ + struct UvElement *buf; + /* Total number of UVs in the layer. Useful to know */ + int totalUVs; + /* Number of Islands in the mesh */ + int totalIslands; + /* Stores the starting index in buf where each island begins */ + int *islandIndices; +} UvElementMap; + +typedef struct UvElement { + /* Next UvElement corresponding to same vertex */ + struct UvElement *next; + /* Face the element belongs to */ + struct EditFace *face; + /* Index in the editFace of the uv */ + unsigned char tfindex; + /* Whether this element is the first of coincident elements */ + unsigned char separate; + /* general use flag */ + unsigned char flag; + /* If generating element map with island sorting, this stores the island index */ + unsigned short island; +} UvElement; + +/* invalid island index is max short. If any one has the patience + * to make that many islands, he can bite me :p */ +#define INVALID_ISLAND 0xFFFF + + UvVertMap *make_uv_vert_map(struct MFace *mface, struct MTFace *tface, unsigned int totface, unsigned int totvert, int selected, float *limit); UvMapVert *get_uv_map_vert(UvVertMap *vmap, unsigned int v); void free_uv_vert_map(UvVertMap *vmap); @@ -127,9 +171,9 @@ struct IndexNode *next, *prev; int index; } IndexNode; -void create_vert_face_map(ListBase **map, IndexNode **mem, const struct MFace *mface, +void create_vert_face_map(struct ListBase **map, IndexNode **mem, const struct MFace *mface, const int totvert, const int totface); -void create_vert_edge_map(ListBase **map, IndexNode **mem, const struct MEdge *medge, +void create_vert_edge_map(struct ListBase **map, IndexNode **mem, const struct MEdge *medge, const int totvert, const int totedge); /* functions for making menu's from customdata layers */ @@ -159,6 +203,12 @@ void BKE_mesh_ensure_navmesh(struct Mesh *me); +/*convert a triangle of loop facedata to mface facedata*/ +void mesh_loops_to_mface_corners(struct CustomData *fdata, struct CustomData *ldata, + struct CustomData *pdata, int lindex[4], int findex, + const int polyindex, const int mf_len, + const int numTex, const int numCol, const int hasWCol); + #ifdef __cplusplus } #endif diff -Nru blender-2.61/source/blender/blenkernel/BKE_modifier.h blender-2.62/source/blender/blenkernel/BKE_modifier.h --- blender-2.61/source/blender/blenkernel/BKE_modifier.h 2011-12-13 19:49:19.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/BKE_modifier.h 2012-02-15 19:34:08.000000000 +0000 @@ -65,6 +65,11 @@ * unless it's a mesh and can be exploded -> curve can also emit particles */ eModifierTypeType_DeformOrConstruct, + + /* Like eModifierTypeType_Nonconstructive, but does not affect the geometry + * of the object, rather some of its CustomData layers. + * E.g. UVProject and WeightVG modifiers. */ + eModifierTypeType_NonGeometrical, } ModifierTypeType; typedef enum { @@ -94,7 +99,10 @@ eModifierTypeFlag_Single = (1<<7), /* Some modifier can't be added manually by user */ - eModifierTypeFlag_NoUserAdd = (1<<8) + eModifierTypeFlag_NoUserAdd = (1<<8), + + /* For modifiers that use CD_WEIGHT_MCOL for preview. */ + eModifierTypeFlag_UsesPreview = (1<<9) } ModifierTypeFlag; typedef void (*ObjectWalkFunc)(void *userData, struct Object *ob, struct Object **obpoin); @@ -311,12 +319,14 @@ int modifier_couldBeCage(struct Scene *scene, struct ModifierData *md); int modifier_isCorrectableDeformed(struct ModifierData *md); int modifier_sameTopology(ModifierData *md); +int modifier_nonGeometrical(ModifierData *md); int modifier_isEnabled(struct Scene *scene, struct ModifierData *md, int required_mode); void modifier_setError(struct ModifierData *md, const char *format, ...) #ifdef __GNUC__ __attribute__ ((format (printf, 2, 3))) #endif ; +int modifier_isPreview(struct ModifierData *md); void modifiers_foreachObjectLink(struct Object *ob, ObjectWalkFunc walk, @@ -343,6 +353,7 @@ int modifiers_usesArmature(struct Object *ob, struct bArmature *arm); int modifiers_isCorrectableDeformed(struct Object *ob); void modifier_freeTemporaryData(struct ModifierData *md); +int modifiers_isPreview(struct Object *ob); int modifiers_indexInObject(struct Object *ob, struct ModifierData *md); @@ -356,6 +367,9 @@ struct ModifierData *md, CustomDataMask dataMask, int required_mode); +struct ModifierData *modifiers_getLastPreview(struct Scene *scene, + struct ModifierData *md, + int required_mode); struct ModifierData *modifiers_getVirtualModifierList(struct Object *ob); /* ensure modifier correctness when changing ob->data */ diff -Nru blender-2.61/source/blender/blenkernel/BKE_movieclip.h blender-2.62/source/blender/blenkernel/BKE_movieclip.h --- blender-2.61/source/blender/blenkernel/BKE_movieclip.h 2011-12-13 19:49:19.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/BKE_movieclip.h 2012-02-15 19:34:08.000000000 +0000 @@ -47,8 +47,9 @@ void BKE_movieclip_reload(struct MovieClip *clip); struct ImBuf *BKE_movieclip_get_ibuf(struct MovieClip *clip, struct MovieClipUser *user); -struct ImBuf *BKE_movieclip_get_stable_ibuf(struct MovieClip *clip, struct MovieClipUser *user, float loc[2], float *scale, float *angle); -struct ImBuf *BKE_movieclip_get_ibuf_flag(struct MovieClip *clip, struct MovieClipUser *user, int flag); +struct ImBuf *BKE_movieclip_get_postprocessed_ibuf(struct MovieClip *clip, struct MovieClipUser *user, int postprocess_flag); +struct ImBuf *BKE_movieclip_get_stable_ibuf(struct MovieClip *clip, struct MovieClipUser *user, float loc[2], float *scale, float *angle, int postprocess_flag); +struct ImBuf *BKE_movieclip_get_ibuf_flag(struct MovieClip *clip, struct MovieClipUser *user, int flag, int cache_flag); void BKE_movieclip_get_size(struct MovieClip *clip, struct MovieClipUser *user, int *width, int *height); void BKE_movieclip_aspect(struct MovieClip *clip, float *aspx, float *aspy); int BKE_movieclip_has_frame(struct MovieClip *clip, struct MovieClipUser *user); @@ -60,11 +61,16 @@ void BKE_movieclip_get_cache_segments(struct MovieClip *clip, struct MovieClipUser *user, int *totseg_r, int **points_r); -void BKE_movieclip_build_proxy_frame(struct MovieClip *clip, struct MovieDistortion *distortion, +void BKE_movieclip_build_proxy_frame(struct MovieClip *clip, int clip_flag, struct MovieDistortion *distortion, int cfra, int *build_sizes, int build_count, int undistorted); -#define TRACK_CLEAR_UPTO 0 -#define TRACK_CLEAR_REMAINED 1 -#define TRACK_CLEAR_ALL 2 +/* cacheing flags */ +#define MOVIECLIP_CACHE_SKIP (1<<0) + +/* postprocessing flags */ +#define MOVIECLIP_DISABLE_RED (1<<0) +#define MOVIECLIP_DISABLE_GREEN (1<<1) +#define MOVIECLIP_DISABLE_BLUE (1<<2) +#define MOVIECLIP_PREVIEW_GRAYSCALE (1<<3) #endif diff -Nru blender-2.61/source/blender/blenkernel/BKE_node.h blender-2.62/source/blender/blenkernel/BKE_node.h --- blender-2.61/source/blender/blenkernel/BKE_node.h 2011-12-13 19:49:19.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/BKE_node.h 2012-02-15 19:34:08.000000000 +0000 @@ -76,7 +76,7 @@ */ typedef struct bNodeSocketTemplate { int type, limit; - char name[32]; + char name[64]; /* MAX_NAME */ float val1, val2, val3, val4; /* default alloc value for inputs */ float min, max; PropertySubType subtype; @@ -95,7 +95,7 @@ */ typedef struct bNodeSocketType { int type; - char ui_name[32]; + char ui_name[64]; /* MAX_NAME */ char ui_description[128]; int ui_icon; char ui_color[4]; @@ -125,7 +125,7 @@ short needs_free; /* set for allocated types that need to be freed */ int type; - char name[32]; + char name[64]; /* MAX_NAME */ float width, minwidth, maxwidth; float height, minheight, maxheight; short nclass, flag, compatibility; @@ -305,8 +305,6 @@ void ntreeMakeLocal(struct bNodeTree *ntree); int ntreeHasType(struct bNodeTree *ntree, int type); -void ntreeSocketUseFlags(struct bNodeTree *ntree); - void ntreeUpdateTree(struct bNodeTree *ntree); /* XXX Currently each tree update call does call to ntreeVerifyNodes too. * Some day this should be replaced by a decent depsgraph automatism! @@ -376,6 +374,8 @@ void nodeFreePreview(struct bNode *node); +int nodeSocketIsHidden(struct bNodeSocket *sock); + /* ************** NODE TYPE ACCESS *************** */ struct bNodeTemplate nodeMakeTemplate(struct bNode *node); @@ -521,6 +521,9 @@ #define SH_NODE_LAYER_WEIGHT 160 #define SH_NODE_VOLUME_TRANSPARENT 161 #define SH_NODE_VOLUME_ISOTROPIC 162 +#define SH_NODE_GAMMA 163 +#define SH_NODE_TEX_CHECKER 164 +#define SH_NODE_BRIGHTCONTRAST 165 /* custom defines options for Material node */ #define SH_NODE_MAT_DIFF 1 @@ -554,25 +557,34 @@ /* ************** COMPOSITE NODES *************** */ /* output socket defines */ -#define RRES_OUT_IMAGE 0 -#define RRES_OUT_ALPHA 1 -#define RRES_OUT_Z 2 -#define RRES_OUT_NORMAL 3 -#define RRES_OUT_UV 4 -#define RRES_OUT_VEC 5 -#define RRES_OUT_RGBA 6 -#define RRES_OUT_DIFF 7 -#define RRES_OUT_SPEC 8 -#define RRES_OUT_SHADOW 9 -#define RRES_OUT_AO 10 -#define RRES_OUT_REFLECT 11 -#define RRES_OUT_REFRACT 12 -#define RRES_OUT_INDIRECT 13 -#define RRES_OUT_INDEXOB 14 -#define RRES_OUT_INDEXMA 15 -#define RRES_OUT_MIST 16 -#define RRES_OUT_EMIT 17 -#define RRES_OUT_ENV 18 +#define RRES_OUT_IMAGE 0 +#define RRES_OUT_ALPHA 1 +#define RRES_OUT_Z 2 +#define RRES_OUT_NORMAL 3 +#define RRES_OUT_UV 4 +#define RRES_OUT_VEC 5 +#define RRES_OUT_RGBA 6 +#define RRES_OUT_DIFF 7 +#define RRES_OUT_SPEC 8 +#define RRES_OUT_SHADOW 9 +#define RRES_OUT_AO 10 +#define RRES_OUT_REFLECT 11 +#define RRES_OUT_REFRACT 12 +#define RRES_OUT_INDIRECT 13 +#define RRES_OUT_INDEXOB 14 +#define RRES_OUT_INDEXMA 15 +#define RRES_OUT_MIST 16 +#define RRES_OUT_EMIT 17 +#define RRES_OUT_ENV 18 +#define RRES_OUT_DIFF_DIRECT 19 +#define RRES_OUT_DIFF_INDIRECT 20 +#define RRES_OUT_DIFF_COLOR 21 +#define RRES_OUT_GLOSSY_DIRECT 22 +#define RRES_OUT_GLOSSY_INDIRECT 23 +#define RRES_OUT_GLOSSY_COLOR 24 +#define RRES_OUT_TRANSM_DIRECT 25 +#define RRES_OUT_TRANSM_INDIRECT 26 +#define RRES_OUT_TRANSM_COLOR 27 /* note: types are needed to restore callbacks, don't change values */ #define CMP_NODE_VIEWER 201 @@ -640,6 +652,7 @@ #define CMP_NODE_STABILIZE2D 263 #define CMP_NODE_TRANSFORM 264 #define CMP_NODE_MOVIEDISTORTION 265 +#define CMP_NODE_DOUBLEEDGEMASK 266 #define CMP_NODE_GLARE 301 #define CMP_NODE_TONEMAP 302 diff -Nru blender-2.61/source/blender/blenkernel/BKE_object.h blender-2.62/source/blender/blenkernel/BKE_object.h --- blender-2.61/source/blender/blenkernel/BKE_object.h 2011-12-13 19:49:19.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/BKE_object.h 2012-02-15 19:34:08.000000000 +0000 @@ -120,6 +120,8 @@ const short flag, void (*func_cb)(const float[3], void *), void *user_data); +int BKE_object_parent_loop_check(const struct Object *parent, const struct Object *ob); + void solve_tracking (struct Object *ob, float targetmat[][4]); int ray_hit_boundbox(struct BoundBox *bb, float ray_start[3], float ray_normal[3]); diff -Nru blender-2.61/source/blender/blenkernel/BKE_particle.h blender-2.62/source/blender/blenkernel/BKE_particle.h --- blender-2.61/source/blender/blenkernel/BKE_particle.h 2011-12-13 19:49:19.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/BKE_particle.h 2012-02-15 19:34:08.000000000 +0000 @@ -63,7 +63,8 @@ #define LOOP_PARTICLES for(p=0, pa=psys->particles; ptotpart; p++, pa++) #define LOOP_EXISTING_PARTICLES for(p=0, pa=psys->particles; ptotpart; p++, pa++) if(!(pa->flag & PARS_UNEXIST)) #define LOOP_SHOWN_PARTICLES for(p=0, pa=psys->particles; ptotpart; p++, pa++) if(!(pa->flag & (PARS_UNEXIST|PARS_NO_DISP))) -#define LOOP_DYNAMIC_PARTICLES for(p=0, pa=psys->particles; ptotpart; p++, pa++) if(pa->state.time > 0.f) +/* OpenMP: Can only advance one variable within loop definition. */ +#define LOOP_DYNAMIC_PARTICLES for(p=0; ptotpart; p++ ) if((pa=psys->particles+p)->state.time > 0.f) #define PSYS_FRAND_COUNT 1024 #define PSYS_FRAND(seed) psys->frand[(seed) % PSYS_FRAND_COUNT] diff -Nru blender-2.61/source/blender/blenkernel/BKE_sequencer.h blender-2.62/source/blender/blenkernel/BKE_sequencer.h --- blender-2.61/source/blender/blenkernel/BKE_sequencer.h 2011-12-13 19:49:19.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/BKE_sequencer.h 2012-02-15 19:34:08.000000000 +0000 @@ -306,7 +306,7 @@ int tot_error; int len; /* only for image strips */ char path[512]; - char name[32]; + char name[64]; } SeqLoadInfo; /* SeqLoadInfo.flag */ diff -Nru blender-2.61/source/blender/blenkernel/BKE_sound.h blender-2.62/source/blender/blenkernel/BKE_sound.h --- blender-2.61/source/blender/blenkernel/BKE_sound.h 2011-12-13 19:49:19.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/BKE_sound.h 2012-02-15 19:34:08.000000000 +0000 @@ -94,14 +94,17 @@ void sound_update_scene_listener(struct Scene *scene); void* sound_scene_add_scene_sound(struct Scene *scene, struct Sequence* sequence, int startframe, int endframe, int frameskip); +void* sound_scene_add_scene_sound_defaults(struct Scene *scene, struct Sequence* sequence); void* sound_add_scene_sound(struct Scene *scene, struct Sequence* sequence, int startframe, int endframe, int frameskip); +void* sound_add_scene_sound_defaults(struct Scene *scene, struct Sequence* sequence); void sound_remove_scene_sound(struct Scene *scene, void* handle); void sound_mute_scene_sound(void* handle, char mute); void sound_move_scene_sound(struct Scene *scene, void* handle, int startframe, int endframe, int frameskip); +void sound_move_scene_sound_defaults(struct Scene *scene, struct Sequence *sequence); void sound_update_scene_sound(void* handle, struct bSound* sound); diff -Nru blender-2.61/source/blender/blenkernel/BKE_text.h blender-2.62/source/blender/blenkernel/BKE_text.h --- blender-2.61/source/blender/blenkernel/BKE_text.h 2011-12-13 19:49:19.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/BKE_text.h 2012-02-15 19:34:08.000000000 +0000 @@ -46,7 +46,8 @@ void txt_set_undostate (int u); int txt_get_undostate (void); struct Text* add_empty_text (const char *name); -int reopen_text (struct Text *text); +int txt_extended_ascii_as_utf8(char **str); +int reopen_text (struct Text *text); struct Text* add_text (const char *file, const char *relpath); struct Text* copy_text (struct Text *ta); void unlink_text (struct Main *bmain, struct Text *text); @@ -59,6 +60,8 @@ int txt_find_string (struct Text *text, const char *findstr, int wrap, int match_case); int txt_has_sel (struct Text *text); int txt_get_span (struct TextLine *from, struct TextLine *to); +int txt_utf8_offset_to_index(char *str, int offset); +int txt_utf8_index_to_offset(char *str, int index); void txt_move_up (struct Text *text, short sel); void txt_move_down (struct Text *text, short sel); void txt_move_left (struct Text *text, short sel); @@ -86,9 +89,9 @@ void txt_split_curline (struct Text *text); void txt_backspace_char (struct Text *text); void txt_backspace_word (struct Text *text); -int txt_add_char (struct Text *text, char add); -int txt_add_raw_char (struct Text *text, char add); -int txt_replace_char (struct Text *text, char add); +int txt_add_char (struct Text *text, unsigned int add); +int txt_add_raw_char (struct Text *text, unsigned int add); +int txt_replace_char (struct Text *text, unsigned int add); void txt_export_to_object(struct Text *text); void txt_export_to_objects(struct Text *text); void txt_unindent (struct Text *text); @@ -127,34 +130,48 @@ #define UNDO_SLEFT 005 #define UNDO_SRIGHT 006 #define UNDO_SUP 007 -#define UNDO_SDOWN 021 +#define UNDO_SDOWN 010 /* Complex movement (opcode is followed * by 4 character line ID + a 2 character * position ID and opcode (repeat)) */ -#define UNDO_CTO 022 -#define UNDO_STO 023 +#define UNDO_CTO 011 +#define UNDO_STO 012 -/* Complex editing (opcode is followed - * by 1 character ID and opcode (repeat)) */ -#define UNDO_INSERT 024 -#define UNDO_BS 025 -#define UNDO_DEL 026 +/* Complex editing */ +/* 1 - opcode is followed by 1 byte for ascii character and opcode (repeat)) */ +/* 2 - opcode is followed by 2 bytes for utf-8 character and opcode (repeat)) */ +/* 3 - opcode is followed by 3 bytes for utf-8 character and opcode (repeat)) */ +/* 4 - opcode is followed by 4 bytes for unicode character and opcode (repeat)) */ +#define UNDO_INSERT_1 013 +#define UNDO_INSERT_2 014 +#define UNDO_INSERT_3 015 +#define UNDO_INSERT_4 016 + +#define UNDO_BS_1 017 +#define UNDO_BS_2 020 +#define UNDO_BS_3 021 +#define UNDO_BS_4 022 + +#define UNDO_DEL_1 023 +#define UNDO_DEL_2 024 +#define UNDO_DEL_3 025 +#define UNDO_DEL_4 026 /* Text block (opcode is followed * by 4 character length ID + the text * block itself + the 4 character length * ID (repeat) and opcode (repeat)) */ -#define UNDO_DBLOCK 027 /* Delete block */ -#define UNDO_IBLOCK 030 /* Insert block */ +#define UNDO_DBLOCK 027 /* Delete block */ +#define UNDO_IBLOCK 030 /* Insert block */ /* Misc */ -#define UNDO_SWAP 031 /* Swap cursors */ +#define UNDO_SWAP 031 /* Swap cursors */ -#define UNDO_INDENT 032 -#define UNDO_UNINDENT 033 -#define UNDO_COMMENT 034 -#define UNDO_UNCOMMENT 035 +#define UNDO_INDENT 032 +#define UNDO_UNINDENT 033 +#define UNDO_COMMENT 034 +#define UNDO_UNCOMMENT 035 /* Marker flags */ #define TMARK_TEMP 0x01 /* Remove on non-editing events, don't save */ diff -Nru blender-2.61/source/blender/blenkernel/BKE_texture.h blender-2.62/source/blender/blenkernel/BKE_texture.h --- blender-2.61/source/blender/blenkernel/BKE_texture.h 2011-12-13 19:49:19.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/BKE_texture.h 2012-02-15 19:34:08.000000000 +0000 @@ -67,11 +67,11 @@ void init_colorband(struct ColorBand *coba, int rangetype); struct ColorBand *add_colorband(int rangetype); -int do_colorband(struct ColorBand *coba, float in, float out[4]); +int do_colorband(const struct ColorBand *coba, float in, float out[4]); void colorband_table_RGBA(struct ColorBand *coba, float **array, int *size); -int vergcband(const void *a1, const void *a2); struct CBData *colorband_element_add(struct ColorBand *coba, float position); int colorband_element_remove(struct ColorBand *coba, int index); +void colorband_update_sort(struct ColorBand *coba); void default_tex(struct Tex *tex); struct Tex *add_texture(const char *name); diff -Nru blender-2.61/source/blender/blenkernel/BKE_tracking.h blender-2.62/source/blender/blenkernel/BKE_tracking.h --- blender-2.61/source/blender/blenkernel/BKE_tracking.h 2011-12-13 19:49:19.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/BKE_tracking.h 2012-02-15 19:34:08.000000000 +0000 @@ -34,11 +34,13 @@ struct bGPDlayer; struct ImBuf; +struct ListBase; struct MovieReconstructContext; struct MovieTrackingTrack; struct MovieTrackingMarker; struct MovieTracking; struct MovieTrackingContext; +struct MovieTrackingObject; struct MovieClipUser; struct MovieDistortion; struct Camera; @@ -49,15 +51,17 @@ void BKE_tracking_clamp_track(struct MovieTrackingTrack *track, int event); void BKE_tracking_track_flag(struct MovieTrackingTrack *track, int area, int flag, int clear); -struct MovieTrackingTrack *BKE_tracking_add_track(struct MovieTracking *tracking, float x, float y, - int framenr, int width, int height); -void BKE_tracking_insert_marker(struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker); +struct MovieTrackingTrack *BKE_tracking_add_track(struct MovieTracking *tracking, struct ListBase *tracksbase, + float x, float y, int framenr, int width, int height); +struct MovieTrackingMarker *BKE_tracking_insert_marker(struct MovieTrackingTrack *track, + struct MovieTrackingMarker *marker); void BKE_tracking_delete_marker(struct MovieTrackingTrack *track, int framenr); struct MovieTrackingMarker *BKE_tracking_get_marker(struct MovieTrackingTrack *track, int framenr); struct MovieTrackingMarker *BKE_tracking_ensure_marker(struct MovieTrackingTrack *track, int framenr); struct MovieTrackingMarker *BKE_tracking_exact_marker(struct MovieTrackingTrack *track, int framenr); int BKE_tracking_has_marker(struct MovieTrackingTrack *track, int framenr); +int BKE_tracking_has_enabled_marker(struct MovieTrackingTrack *track, int framenr); void BKE_tracking_free_track(struct MovieTrackingTrack *track); @@ -72,40 +76,62 @@ struct ImBuf *BKE_tracking_get_search_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int margin, int anchored, float pos[2], int origin[2]); -void BKE_track_unique_name(struct MovieTracking *tracking, struct MovieTrackingTrack *track); +void BKE_track_unique_name(struct ListBase *tracksbase, struct MovieTrackingTrack *track); -struct MovieTrackingTrack *BKE_tracking_named_track(struct MovieTracking *tracking, const char *name); -struct MovieTrackingTrack *BKE_tracking_indexed_track(struct MovieTracking *tracking, int tracknr); +struct MovieTrackingTrack *BKE_tracking_named_track(struct MovieTracking *tracking, struct MovieTrackingObject *object, const char *name); +struct MovieTrackingTrack *BKE_tracking_indexed_track(struct MovieTracking *tracking, int tracknr, struct ListBase **tracksbase_r); void BKE_tracking_camera_shift(struct MovieTracking *tracking, int winx, int winy, float *shiftx, float *shifty); void BKE_tracking_camera_to_blender(struct MovieTracking *tracking, struct Scene *scene, struct Camera *camera, int width, int height); void BKE_get_tracking_mat(struct Scene *scene, struct Object *ob, float mat[4][4]); -void BKE_tracking_projection_matrix(struct MovieTracking *tracking, int framenr, int winx, int winy, float mat[4][4]); +void BKE_tracking_projection_matrix(struct MovieTracking *tracking, struct MovieTrackingObject *object, + int framenr, int winx, int winy, float mat[4][4]); + +struct ListBase *BKE_tracking_get_tracks(struct MovieTracking *tracking); +struct MovieTrackingReconstruction *BKE_tracking_get_reconstruction(struct MovieTracking *tracking); + +struct MovieTrackingTrack *BKE_tracking_active_track(struct MovieTracking *tracking); +struct MovieTrackingObject *BKE_tracking_active_object(struct MovieTracking *tracking); +struct MovieTrackingObject *BKE_tracking_get_camera_object(struct MovieTracking *tracking); +struct ListBase *BKE_tracking_object_tracks(struct MovieTracking *tracking, struct MovieTrackingObject *object); +struct MovieTrackingReconstruction *BKE_tracking_object_reconstruction(struct MovieTracking *tracking, + struct MovieTrackingObject *object); + +void BKE_tracking_disable_imbuf_channels(struct ImBuf *ibuf, int disable_red, int disable_green, int disable_blue, int grayscale); + +/* clipboard */ +void BKE_tracking_free_clipboard(void); +void BKE_tracking_clipboard_copy_tracks(struct MovieTracking *tracking, struct MovieTrackingObject *object); +int BKE_tracking_clipboard_has_tracks(void); +void BKE_tracking_clipboard_paste_tracks(struct MovieTracking *tracking, struct MovieTrackingObject *object); /* 2D tracking */ struct MovieTrackingContext *BKE_tracking_context_new(struct MovieClip *clip, struct MovieClipUser *user, - short backwards, short disable_failed, short sequence); + short backwards, short sequence); void BKE_tracking_context_free(struct MovieTrackingContext *context); void BKE_tracking_sync(struct MovieTrackingContext *context); void BKE_tracking_sync_user(struct MovieClipUser *user, struct MovieTrackingContext *context); int BKE_tracking_next(struct MovieTrackingContext *context); /* Camera solving */ -int BKE_tracking_can_reconstruct(struct MovieTracking *tracking, char *error_msg, int error_size); +int BKE_tracking_can_reconstruct(struct MovieTracking *tracking, struct MovieTrackingObject *object, + char *error_msg, int error_size); struct MovieReconstructContext* BKE_tracking_reconstruction_context_new(struct MovieTracking *tracking, - int keyframe1, int keyframe2, int width, int height); + struct MovieTrackingObject *object, int keyframe1, int keyframe2, int width, int height); void BKE_tracking_reconstruction_context_free(struct MovieReconstructContext *context); void BKE_tracking_solve_reconstruction(struct MovieReconstructContext *context, short *stop, short *do_update, float *progress, char *stats_message, int message_size); int BKE_tracking_finish_reconstruction(struct MovieReconstructContext *context, struct MovieTracking *tracking); -struct MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(struct MovieTracking *tracking, int framenr); -void BKE_tracking_get_interpolated_camera(struct MovieTracking *tracking, int framenr, float mat[4][4]); +struct MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(struct MovieTracking *tracking, + struct MovieTrackingObject *object, int framenr); +void BKE_tracking_get_interpolated_camera(struct MovieTracking *tracking, + struct MovieTrackingObject *object, int framenr, float mat[4][4]); /* Feature detection */ -void BKE_tracking_detect_fast(struct MovieTracking *tracking, struct ImBuf *imbuf, +void BKE_tracking_detect_fast(struct MovieTracking *tracking, struct ListBase *tracksbase, struct ImBuf *imbuf, int framenr, int margin, int min_trackness, int min_distance, struct bGPDlayer *layer, int place_outside_layer); @@ -127,8 +153,14 @@ struct ImBuf *BKE_tracking_undistort(struct MovieTracking *tracking, struct ImBuf *ibuf, int width, int height, float overscan); struct ImBuf *BKE_tracking_distort(struct MovieTracking *tracking, struct ImBuf *ibuf, int width, int height, float overscan); +/* Object tracking */ +struct MovieTrackingObject *BKE_tracking_new_object(struct MovieTracking *tracking, const char *name); +void BKE_tracking_remove_object(struct MovieTracking *tracking, struct MovieTrackingObject *object); +void BKE_tracking_object_unique_name(struct MovieTracking *tracking, struct MovieTrackingObject *object); +struct MovieTrackingObject *BKE_tracking_named_object(struct MovieTracking *tracking, const char *name); + /* Select */ -void BKE_tracking_select_track(struct MovieTracking *tracking, struct MovieTrackingTrack *track, int area, int extend); +void BKE_tracking_select_track(struct ListBase *tracksbase, struct MovieTrackingTrack *track, int area, int extend); void BKE_tracking_deselect_track(struct MovieTrackingTrack *track, int area); #define TRACK_SELECTED(track) ((((track)->flag&TRACK_HIDDEN)==0) && ((track)->flag&SELECT || (track)->pat_flag&SELECT || (track)->search_flag&SELECT)) @@ -137,6 +169,10 @@ #define MARKER_VISIBLE(sc, marker) (((marker)->flag&MARKER_DISABLED)==0 || ((sc)->flag&SC_HIDE_DISABLED)==0) +#define TRACK_CLEAR_UPTO 0 +#define TRACK_CLEAR_REMAINED 1 +#define TRACK_CLEAR_ALL 2 + #define CLAMP_PAT_DIM 1 #define CLAMP_PAT_POS 2 #define CLAMP_SEARCH_DIM 3 diff -Nru blender-2.61/source/blender/blenkernel/BKE_utildefines.h blender-2.62/source/blender/blenkernel/BKE_utildefines.h --- blender-2.61/source/blender/blenkernel/BKE_utildefines.h 2011-12-13 19:49:19.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/BKE_utildefines.h 2012-02-15 19:34:08.000000000 +0000 @@ -43,9 +43,9 @@ /* these values need to be hardcoded in structs, dna does not recognize defines */ /* also defined in DNA_space_types.h */ #ifndef FILE_MAXDIR -#define FILE_MAXDIR 160 -#define FILE_MAXFILE 80 -#define FILE_MAX 240 +#define FILE_MAXDIR 768 +#define FILE_MAXFILE 256 +#define FILE_MAX 1024 #endif /* this weirdo pops up in two places ... */ diff -Nru blender-2.61/source/blender/blenkernel/BKE_writeavi.h blender-2.62/source/blender/blenkernel/BKE_writeavi.h --- blender-2.61/source/blender/blenkernel/BKE_writeavi.h 2011-12-13 19:49:19.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/BKE_writeavi.h 2012-02-15 19:34:08.000000000 +0000 @@ -44,7 +44,8 @@ typedef struct bMovieHandle { int (*start_movie)(struct Scene *scene, struct RenderData *rd, int rectx, int recty, struct ReportList *reports); - int (*append_movie)(struct RenderData *rd, int frame, int *pixels, int rectx, int recty, struct ReportList *reports); + int (*append_movie)(struct RenderData *rd, int start_frame, int frame, int *pixels, + int rectx, int recty, struct ReportList *reports); void (*end_movie)(void); int (*get_next_frame)(struct RenderData *rd, struct ReportList *reports); /* optional */ void (*get_movie_path)(char *string, struct RenderData *rd); /* optional */ diff -Nru blender-2.61/source/blender/blenkernel/BKE_writeffmpeg.h blender-2.62/source/blender/blenkernel/BKE_writeffmpeg.h --- blender-2.61/source/blender/blenkernel/BKE_writeffmpeg.h 2011-12-13 19:49:19.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/BKE_writeffmpeg.h 2012-02-15 19:34:08.000000000 +0000 @@ -68,11 +68,13 @@ extern int start_ffmpeg(struct Scene *scene, struct RenderData *rd, int rectx, int recty, struct ReportList *reports); extern void end_ffmpeg(void); -extern int append_ffmpeg(struct RenderData *rd, int frame, int *pixels, int rectx, int recty, struct ReportList *reports); +extern int append_ffmpeg(struct RenderData *rd, int start_frame, int frame, int *pixels, + int rectx, int recty, struct ReportList *reports); void filepath_ffmpeg(char* string, struct RenderData* rd); extern void ffmpeg_set_preset(struct RenderData *rd, int preset); -extern void ffmpeg_verify_image_type(struct RenderData *rd); +extern void ffmpeg_verify_image_type(struct RenderData *rd, struct ImageFormatData *imf); +extern void ffmpeg_verify_codec_settings(struct RenderData *rd); extern struct IDProperty *ffmpeg_property_add(struct RenderData *Rd, const char *type, int opt_index, int parent_index); extern int ffmpeg_property_add_string(struct RenderData *rd, const char *type, const char *str); diff -Nru blender-2.61/source/blender/blenkernel/BKE_writeframeserver.h blender-2.62/source/blender/blenkernel/BKE_writeframeserver.h --- blender-2.61/source/blender/blenkernel/BKE_writeframeserver.h 2011-12-13 19:49:19.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/BKE_writeframeserver.h 2012-02-15 19:34:08.000000000 +0000 @@ -42,7 +42,8 @@ extern int start_frameserver(struct Scene *scene, struct RenderData *rd, int rectx, int recty, struct ReportList *reports); extern void end_frameserver(void); -extern int append_frameserver(struct RenderData *rd, int frame, int *pixels, int rectx, int recty, struct ReportList *reports); +extern int append_frameserver(struct RenderData *rd, int start_frame, int frame, int *pixels, + int rectx, int recty, struct ReportList *reports); extern int frameserver_loop(struct RenderData *rd, struct ReportList *reports); #ifdef __cplusplus diff -Nru blender-2.61/source/blender/blenkernel/CMakeLists.txt blender-2.62/source/blender/blenkernel/CMakeLists.txt --- blender-2.61/source/blender/blenkernel/CMakeLists.txt 2011-12-13 19:49:19.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/CMakeLists.txt 2012-02-15 19:34:08.000000000 +0000 @@ -156,7 +156,6 @@ BKE_anim.h BKE_animsys.h BKE_armature.h - BKE_array_mallocn.h BKE_blender.h BKE_bmesh.h BKE_bmeshCustomData.h diff -Nru blender-2.61/source/blender/blenkernel/depsgraph_private.h blender-2.62/source/blender/blenkernel/depsgraph_private.h --- blender-2.61/source/blender/blenkernel/depsgraph_private.h 2011-12-13 19:49:19.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/depsgraph_private.h 2012-02-15 19:34:08.000000000 +0000 @@ -69,7 +69,7 @@ int ancestor_count; unsigned int lay; // accumulated layers of its relations + itself unsigned int scelay; // layers due to being in scene - unsigned int customdata_mask; // customdata mask + uint64_t customdata_mask; // customdata mask int lasttime; // if lasttime != DagForest->time, this node was not evaluated yet for flushing int BFS_dist; // BFS distance int DFS_dist; // DFS distance diff -Nru blender-2.61/source/blender/blenkernel/intern/anim.c blender-2.62/source/blender/blenkernel/intern/anim.c --- blender-2.61/source/blender/blenkernel/intern/anim.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/anim.c 2012-02-15 19:34:02.000000000 +0000 @@ -585,11 +585,14 @@ } -/* calculate the deformation implied by the curve path at a given parametric position, and returns whether this operation succeeded - * - *vec needs FOUR items! - * - ctime is normalized range <0-1> +/* calculate the deformation implied by the curve path at a given parametric position, + * and returns whether this operation succeeded. + * + * note: ctime is normalized range <0-1> + * + * returns OK: 1/0 */ -int where_on_path(Object *ob, float ctime, float *vec, float *dir, float *quat, float *radius, float *weight) /* returns OK */ +int where_on_path(Object *ob, float ctime, float vec[4], float dir[3], float quat[4], float *radius, float *weight) { Curve *cu; Nurb *nu; @@ -726,10 +729,10 @@ if(!is_zero_v3(group->dupli_ofs)) { copy_m4_m4(tmat, go->ob->obmat); sub_v3_v3v3(tmat[3], tmat[3], group->dupli_ofs); - mul_m4_m4m4(mat, tmat, ob->obmat); + mult_m4_m4m4(mat, ob->obmat, tmat); } else { - mul_m4_m4m4(mat, go->ob->obmat, ob->obmat); + mult_m4_m4m4(mat, ob->obmat, go->ob->obmat); } dob= new_dupli_object(lb, go->ob, mat, ob->lay, 0, OB_DUPLIGROUP, animated); @@ -955,7 +958,7 @@ when par_space_mat is NULL ob->obmat can be used instead of ob__obmat */ if(par_space_mat) - mul_m4_m4m4(vdd.obmat, ob->obmat, par_space_mat); + mult_m4_m4m4(vdd.obmat, par_space_mat, ob->obmat); else copy_m4_m4(vdd.obmat, ob->obmat); @@ -1084,7 +1087,7 @@ when par_space_mat is NULL ob->obmat can be used instead of ob__obmat */ if(par_space_mat) - mul_m4_m4m4(ob__obmat, ob->obmat, par_space_mat); + mult_m4_m4m4(ob__obmat, par_space_mat, ob->obmat); else copy_m4_m4(ob__obmat, ob->obmat); @@ -1143,21 +1146,17 @@ madd_v3_v3v3fl(dob->orco, dob->orco, orco[mv1], w); madd_v3_v3v3fl(dob->orco, dob->orco, orco[mv2], w); madd_v3_v3v3fl(dob->orco, dob->orco, orco[mv3], w); - if(mv4) + if (mv4) { madd_v3_v3v3fl(dob->orco, dob->orco, orco[mv4], w); + } } if(mtface) { - dob->uv[0] += w*mtface[a].uv[0][0]; - dob->uv[1] += w*mtface[a].uv[0][1]; - dob->uv[0] += w*mtface[a].uv[1][0]; - dob->uv[1] += w*mtface[a].uv[1][1]; - dob->uv[0] += w*mtface[a].uv[2][0]; - dob->uv[1] += w*mtface[a].uv[2][1]; - - if(mv4) { - dob->uv[0] += w*mtface[a].uv[3][0]; - dob->uv[1] += w*mtface[a].uv[3][1]; + madd_v2_v2v2fl(dob->uv, dob->uv, mtface[a].uv[0], w); + madd_v2_v2v2fl(dob->uv, dob->uv, mtface[a].uv[1], w); + madd_v2_v2v2fl(dob->uv, dob->uv, mtface[a].uv[2], w); + if (mv4) { + madd_v2_v2v2fl(dob->uv, dob->uv, mtface[a].uv[3], w); } } } @@ -1396,15 +1395,15 @@ if(!is_zero_v3(part->dup_group->dupli_ofs)) { copy_m4_m4(tmat, oblist[b]->obmat); sub_v3_v3v3(tmat[3], tmat[3], part->dup_group->dupli_ofs); - mul_m4_m4m4(tmat, tmat, pamat); + mult_m4_m4m4(tmat, pamat, tmat); } else { - mul_m4_m4m4(tmat, oblist[b]->obmat, pamat); + mult_m4_m4m4(tmat, pamat, oblist[b]->obmat); } mul_mat3_m4_fl(tmat, size*scale); if(par_space_mat) - mul_m4_m4m4(mat, tmat, par_space_mat); + mult_m4_m4m4(mat, par_space_mat, tmat); else copy_m4_m4(mat, tmat); @@ -1435,15 +1434,15 @@ * remove the real emitter's transformation before 2nd order duplication. */ if(par_space_mat && GS(id->name) != ID_GR) - mul_m4_m4m4(mat, pamat, psys->imat); + mult_m4_m4m4(mat, psys->imat, pamat); else copy_m4_m4(mat, pamat); - mul_m4_m4m4(tmat, obmat, mat); + mult_m4_m4m4(tmat, mat, obmat); mul_mat3_m4_fl(tmat, size*scale); if(par_space_mat) - mul_m4_m4m4(mat, tmat, par_space_mat); + mult_m4_m4m4(mat, par_space_mat, tmat); else copy_m4_m4(mat, tmat); diff -Nru blender-2.61/source/blender/blenkernel/intern/armature.c blender-2.62/source/blender/blenkernel/intern/armature.c --- blender-2.61/source/blender/blenkernel/intern/armature.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/armature.c 2012-02-15 19:34:02.000000000 +0000 @@ -505,9 +505,9 @@ if(prev->bone->segments==1) { /* find the previous roll to interpolate */ if(rest) - mul_m4_m4m4(difmat, prev->bone->arm_mat, imat); + mult_m4_m4m4(difmat, imat, prev->bone->arm_mat); else - mul_m4_m4m4(difmat, prev->pose_mat, imat); + mult_m4_m4m4(difmat, imat, prev->pose_mat); copy_m3_m4(result, difmat); // the desired rotation at beginning of next bone vec_roll_to_mat3(h1, 0.0f, mat3); // the result of vec_roll without roll @@ -538,9 +538,9 @@ /* find the next roll to interpolate as well */ if(rest) - mul_m4_m4m4(difmat, next->bone->arm_mat, imat); + mult_m4_m4m4(difmat, imat, next->bone->arm_mat); else - mul_m4_m4m4(difmat, next->pose_mat, imat); + mult_m4_m4m4(difmat, imat, next->pose_mat); copy_m3_m4(result, difmat); // the desired rotation at beginning of next bone vec_roll_to_mat3(h2, 0.0f, mat3); // the result of vec_roll without roll @@ -590,7 +590,7 @@ /* ************ Armature Deform ******************* */ typedef struct bPoseChanDeform { - Mat4 *b_bone_mats; + Mat4 *b_bone_mats; DualQuat *dual_quat; DualQuat *b_bone_dual_quats; } bPoseChanDeform; @@ -665,7 +665,7 @@ } /* using vec with dist to bone b1 - b2 */ -float distfactor_to_bone (float vec[3], float b1[3], float b2[3], float rad1, float rad2, float rdist) +float distfactor_to_bone(const float vec[3], const float b1[3], const float b2[3], float rad1, float rad2, float rdist) { float dist=0.0f; float bdelta[3]; @@ -677,18 +677,18 @@ sub_v3_v3v3(pdelta, vec, b1); - a = bdelta[0]*pdelta[0] + bdelta[1]*pdelta[1] + bdelta[2]*pdelta[2]; - hsqr = ((pdelta[0]*pdelta[0]) + (pdelta[1]*pdelta[1]) + (pdelta[2]*pdelta[2])); + a = dot_v3v3(bdelta, pdelta); + hsqr = dot_v3v3(pdelta, pdelta); - if (a < 0.0F){ + if (a < 0.0f) { /* If we're past the end of the bone, do a spherical field attenuation thing */ - dist= ((b1[0]-vec[0])*(b1[0]-vec[0]) +(b1[1]-vec[1])*(b1[1]-vec[1]) +(b1[2]-vec[2])*(b1[2]-vec[2])) ; + dist = len_squared_v3v3(b1, vec); rad= rad1; } - else if (a > l){ + else if (a > l) { /* If we're past the end of the bone, do a spherical field attenuation thing */ - dist= ((b2[0]-vec[0])*(b2[0]-vec[0]) +(b2[1]-vec[1])*(b2[1]-vec[1]) +(b2[2]-vec[2])*(b2[2]-vec[2])) ; - rad= rad2; + dist = len_squared_v3v3(b2, vec); + rad = rad2; } else { dist= (hsqr - (a*a)); @@ -709,7 +709,7 @@ if(rdist==0.0f || dist >= l) return 0.0f; else { - a= (float)sqrt(dist)-rad; + a = sqrtf(dist)-rad; return 1.0f-( a*a )/( rdist*rdist ); } } @@ -837,7 +837,7 @@ invert_m4_m4(obinv, target->obmat); copy_m4_m4(premat, target->obmat); - mul_m4_m4m4(postmat, armOb->obmat, obinv); + mult_m4_m4m4(postmat, obinv, armOb->obmat); invert_m4_m4(premat, postmat); /* bone defmats are already in the channels, chan_mat */ @@ -924,7 +924,6 @@ float contrib = 0.0f; float armature_weight = 1.0f; /* default to 1 if no overall def group */ float prevco_weight = 1.0f; /* weight for optional cached vertexcos */ - int j; if(use_quaternion) { memset(&sumdq, 0, sizeof(DualQuat)); @@ -971,12 +970,14 @@ mul_m4_v3(premat, co); if(use_dverts && dvert && dvert->totweight) { // use weight groups ? + MDeformWeight *dw= dvert->dw; int deformed = 0; + unsigned int j; - for(j = 0; j < dvert->totweight; j++){ - int index = dvert->dw[j].def_nr; + for (j= dvert->totweight; j != 0; j--, dw++) { + const int index = dw->def_nr; if(index < defbase_tot && (pchan= defnrToPC[index])) { - float weight = dvert->dw[j].weight; + float weight = dw->weight; Bone *bone= pchan->bone; pdef_info= pdef_info_array + defnrToPCIndex[index]; @@ -1102,7 +1103,7 @@ invert_m4_m4(obmat, ob->obmat); /* multiply given matrix by object's-inverse to find pose-space matrix */ - mul_m4_m4m4(outmat, obmat, inmat); + mult_m4_m4m4(outmat, inmat, obmat); } /* Convert Wolrd-Space Location to Pose-Space Location @@ -1122,66 +1123,183 @@ copy_v3_v3(outloc, nLocMat[3]); } -/* Convert Pose-Space Matrix to Bone-Space Matrix - * NOTE: this cannot be used to convert to pose-space transforms of the supplied - * pose-channel into its local space (i.e. 'visual'-keyframing) +/* Construct the matrices (rot/scale and loc) to apply the PoseChannels into the armature (object) space. + * I.e. (roughly) the "pose_mat(b-1) * yoffs(b-1) * d_root(b) * bone_mat(b)" in the + * pose_mat(b)= pose_mat(b-1) * yoffs(b-1) * d_root(b) * bone_mat(b) * chan_mat(b) + * ...function. + * + * This allows to get the transformations of a bone in its object space, *before* constraints (and IK) + * get applied (used by pose evaluation code). + * And reverse: to find pchan transformations needed to place a bone at a given loc/rot/scale + * in object space (used by interactive transform, and snapping code). + * + * Note that, with the HINGE/NO_SCALE/NO_LOCAL_LOCATION options, the location matrix + * will differ from the rotation/scale matrix... + * + * NOTE: This cannot be used to convert to pose-space transforms of the supplied + * pose-channel into its local space (i.e. 'visual'-keyframing). + * (note: I don't understand that, so I keep it :p --mont29). */ -void armature_mat_pose_to_bone(bPoseChannel *pchan, float inmat[][4], float outmat[][4]) +void pchan_to_pose_mat(bPoseChannel *pchan, float rotscale_mat[][4], float loc_mat[][4]) { - float pc_trans[4][4], inv_trans[4][4]; - float pc_posemat[4][4], inv_posemat[4][4]; - float pose_mat[4][4]; - - /* paranoia: prevent crashes with no pose-channel supplied */ - if (pchan==NULL) return; - - /* default flag */ - if((pchan->bone->flag & BONE_NO_LOCAL_LOCATION)==0) { - /* get the inverse matrix of the pchan's transforms */ - switch(pchan->rotmode) { - case ROT_MODE_QUAT: - loc_quat_size_to_mat4(pc_trans, pchan->loc, pchan->quat, pchan->size); - break; - case ROT_MODE_AXISANGLE: - loc_axisangle_size_to_mat4(pc_trans, pchan->loc, pchan->rotAxis, pchan->rotAngle, pchan->size); - break; - default: /* euler */ - loc_eul_size_to_mat4(pc_trans, pchan->loc, pchan->eul, pchan->size); + Bone *bone, *parbone; + bPoseChannel *parchan; + + /* set up variables for quicker access below */ + bone= pchan->bone; + parbone= bone->parent; + parchan= pchan->parent; + + if(parchan) { + float offs_bone[4][4]; /* yoffs(b-1) + root(b) + bonemat(b). */ + + /* Bone transform itself. */ + copy_m4_m3(offs_bone, bone->bone_mat); + + /* The bone's root offset (is in the parent's coordinate system). */ + copy_v3_v3(offs_bone[3], bone->head); + + /* Get the length translation of parent (length along y axis). */ + offs_bone[3][1]+= parbone->length; + + /* Compose the rotscale matrix for this bone. */ + if((bone->flag & BONE_HINGE) && (bone->flag & BONE_NO_SCALE)) { + /* Parent rest rotation and scale. */ + mult_m4_m4m4(rotscale_mat, parbone->arm_mat, offs_bone); + } + else if(bone->flag & BONE_HINGE) { + /* Parent rest rotation and pose scale. */ + float tmat[4][4], tscale[3]; + + /* Extract the scale of the parent pose matrix. */ + mat4_to_size(tscale, parchan->pose_mat); + size_to_mat4(tmat, tscale); + + /* Applies the parent pose scale to the rest matrix. */ + mult_m4_m4m4(tmat, tmat, parbone->arm_mat); + + mult_m4_m4m4(rotscale_mat, tmat, offs_bone); } + else if(bone->flag & BONE_NO_SCALE) { + /* Parent pose rotation and rest scale (i.e. no scaling). */ + float tmat[4][4]; + copy_m4_m4(tmat, parchan->pose_mat); + normalize_m4(tmat); + mult_m4_m4m4(rotscale_mat, tmat, offs_bone); + } + else + mult_m4_m4m4(rotscale_mat, parchan->pose_mat, offs_bone); - copy_m4_m4(pose_mat, pchan->pose_mat); - } - else { - /* local location, this is not default, different calculation - * note: only tested for location with pose bone snapping. - * If this is not useful in other cases the BONE_NO_LOCAL_LOCATION - * case may have to be split into its own function. */ - unit_m4(pc_trans); - copy_v3_v3(pc_trans[3], pchan->loc); +# if 1 + /* Compose the loc matrix for this bone. */ + /* NOTE: That version deos not modify bone's loc when HINGE/NO_SCALE options are set. */ + + /* In this case, use the object's space *orientation*. */ + if(bone->flag & BONE_NO_LOCAL_LOCATION) { + /* XXX I'm sure that code can be simplified! */ + float bone_loc[4][4], bone_rotscale[3][3], tmat4[4][4], tmat3[3][3]; + unit_m4(bone_loc); + unit_m4(loc_mat); + unit_m4(tmat4); + + mul_v3_m4v3(bone_loc[3], parchan->pose_mat, offs_bone[3]); + + unit_m3(bone_rotscale); + copy_m3_m4(tmat3, parchan->pose_mat); + mul_m3_m3m3(bone_rotscale, tmat3, bone_rotscale); + + copy_m4_m3(tmat4, bone_rotscale); + mult_m4_m4m4(loc_mat, bone_loc, tmat4); + } + /* Those flags do not affect position, use plain parent transform space! */ + else if(bone->flag & (BONE_HINGE|BONE_NO_SCALE)) { + mult_m4_m4m4(loc_mat, parchan->pose_mat, offs_bone); + } + /* Else (i.e. default, usual case), just use the same matrix for rotation/scaling, and location. */ + else + copy_m4_m4(loc_mat, rotscale_mat); +# endif +# if 0 + /* Compose the loc matrix for this bone. */ + /* NOTE: That version modifies bone's loc when HINGE/NO_SCALE options are set. */ - /* use parents rotation/scale space + own absolute position */ - if(pchan->parent) copy_m4_m4(pose_mat, pchan->parent->pose_mat); - else unit_m4(pose_mat); + /* In these cases we need to compute location separately */ + if(bone->flag & (BONE_HINGE|BONE_NO_SCALE|BONE_NO_LOCAL_LOCATION)) { + float bone_loc[4][4], bone_rotscale[3][3], tmat4[4][4], tmat3[3][3]; + unit_m4(bone_loc); + unit_m4(loc_mat); + unit_m4(tmat4); + + mul_v3_m4v3(bone_loc[3], parchan->pose_mat, offs_bone[3]); + + /* "No local location" is not transformed by bone matrix. */ + /* This only affects orientations (rotations), as scale is always 1.0 here. */ + if(bone->flag & BONE_NO_LOCAL_LOCATION) + unit_m3(bone_rotscale); + else + /* We could also use bone->bone_mat directly, here... */ + copy_m3_m4(bone_rotscale, offs_bone); + + if(bone->flag & BONE_HINGE) { + copy_m3_m4(tmat3, parbone->arm_mat); + /* for hinge-only, we use armature *rotation*, but pose mat *scale*! */ + if(!(bone->flag & BONE_NO_SCALE)) { + float size[3], tsmat[3][3]; + mat4_to_size(size, parchan->pose_mat); + size_to_mat3(tsmat, size); + mul_m3_m3m3(tmat3, tsmat, tmat3); + } + mul_m3_m3m3(bone_rotscale, tmat3, bone_rotscale); + } + else if(bone->flag & BONE_NO_SCALE) { + /* For no-scale only, normalized parent pose mat is enough! */ + copy_m3_m4(tmat3, parchan->pose_mat); + normalize_m3(tmat3); + mul_m3_m3m3(bone_rotscale, tmat3, bone_rotscale); + } + /* NO_LOCAL_LOCATION only. */ + else { + copy_m3_m4(tmat3, parchan->pose_mat); + mul_m3_m3m3(bone_rotscale, tmat3, bone_rotscale); + } - copy_v3_v3(pose_mat[3], pchan->pose_mat[3]); + copy_m4_m3(tmat4, bone_rotscale); + mult_m4_m4m4(loc_mat, bone_loc, tmat4); + } + /* Else, just use the same matrix for rotation/scaling, and location. */ + else + copy_m4_m4(loc_mat, rotscale_mat); +# endif + } + /* Root bones. */ + else { + /* Rotation/scaling. */ + copy_m4_m4(rotscale_mat, pchan->bone->arm_mat); + /* Translation. */ + if(pchan->bone->flag & BONE_NO_LOCAL_LOCATION) { + /* Translation of arm_mat, without the rotation. */ + unit_m4(loc_mat); + copy_v3_v3(loc_mat[3], pchan->bone->arm_mat[3]); + } + else + copy_m4_m4(loc_mat, rotscale_mat); } +} + +/* Convert Pose-Space Matrix to Bone-Space Matrix. + * NOTE: this cannot be used to convert to pose-space transforms of the supplied + * pose-channel into its local space (i.e. 'visual'-keyframing) + */ +void armature_mat_pose_to_bone(bPoseChannel *pchan, float inmat[][4], float outmat[][4]) +{ + float rotscale_mat[4][4], loc_mat[4][4]; + pchan_to_pose_mat(pchan, rotscale_mat, loc_mat); + invert_m4(rotscale_mat); + invert_m4(loc_mat); - invert_m4_m4(inv_trans, pc_trans); - - /* Remove the pchan's transforms from it's pose_mat. - * This should leave behind the effects of restpose + - * parenting + constraints - */ - mul_m4_m4m4(pc_posemat, inv_trans, pose_mat); - - /* get the inverse of the leftovers so that we can remove - * that component from the supplied matrix - */ - invert_m4_m4(inv_posemat, pc_posemat); - - /* get the new matrix */ - mul_m4_m4m4(outmat, inmat, inv_posemat); + mult_m4_m4m4(outmat, rotscale_mat, inmat); + mul_v3_m4v3(outmat[3], loc_mat, inmat[3]); } /* Convert Pose-Space Location to Bone-Space Location @@ -1201,6 +1319,23 @@ copy_v3_v3(outloc, nLocMat[3]); } +void armature_mat_pose_to_bone_ex(Object *ob, bPoseChannel *pchan, float inmat[][4], float outmat[][4]) +{ + bPoseChannel work_pchan = *pchan; + + /* recalculate pose matrix with only parent transformations, + * bone loc/sca/rot is ignored, scene and frame are not used. */ + where_is_pose_bone(NULL, ob, &work_pchan, 0.0f, FALSE); + + /* find the matrix, need to remove the bone transforms first so this is + * calculated as a matrix to set rather then a difference ontop of whats + * already there. */ + unit_m4(outmat); + pchan_apply_mat4(&work_pchan, outmat, FALSE); + + armature_mat_pose_to_bone(&work_pchan, inmat, outmat); +} + /* same as object_mat3_to_rot() */ void pchan_mat3_to_rot(bPoseChannel *pchan, float mat[][3], short use_compat) { @@ -1236,7 +1371,7 @@ float imat[4][4]; invert_m4_m4(imat, arm_mat); - mul_m4_m4m4(delta_mat, pose_mat, imat); + mult_m4_m4m4(delta_mat, imat, pose_mat); } /* **************** Rotation Mode Conversions ****************************** */ @@ -1409,7 +1544,7 @@ offs_bone[3][1]+= prevbone->length; /* Compose the matrix for this bone */ - mul_m4_m4m4(bone->arm_mat, offs_bone, prevbone->arm_mat); + mult_m4_m4m4(bone->arm_mat, prevbone->arm_mat, offs_bone); } else { copy_m4_m3(bone->arm_mat, bone->bone_mat); @@ -2262,98 +2397,30 @@ */ void where_is_pose_bone(Scene *scene, Object *ob, bPoseChannel *pchan, float ctime, int do_extra) { - Bone *bone, *parbone; - bPoseChannel *parchan; - float vec[3]; - - /* set up variables for quicker access below */ - bone= pchan->bone; - parbone= bone->parent; - parchan= pchan->parent; - - /* this gives a chan_mat with actions (ipos) results */ - if(do_extra) pchan_calc_mat(pchan); - else unit_m4(pchan->chan_mat); + /* This gives a chan_mat with actions (ipos) results. */ + if(do_extra) + pchan_calc_mat(pchan); + else + unit_m4(pchan->chan_mat); - /* construct the posemat based on PoseChannels, that we do before applying constraints */ + /* Construct the posemat based on PoseChannels, that we do before applying constraints. */ /* pose_mat(b)= pose_mat(b-1) * yoffs(b-1) * d_root(b) * bone_mat(b) * chan_mat(b) */ - - if(parchan) { - float offs_bone[4][4]; // yoffs(b-1) + root(b) + bonemat(b) - - /* bone transform itself */ - copy_m4_m3(offs_bone, bone->bone_mat); - - /* The bone's root offset (is in the parent's coordinate system) */ - copy_v3_v3(offs_bone[3], bone->head); - - /* Get the length translation of parent (length along y axis) */ - offs_bone[3][1]+= parbone->length; - - /* Compose the matrix for this bone */ - if((bone->flag & BONE_HINGE) && (bone->flag & BONE_NO_SCALE)) { // uses restposition rotation, but actual position - float tmat[4][4]; - /* the rotation of the parent restposition */ - copy_m4_m4(tmat, parbone->arm_mat); - mul_serie_m4(pchan->pose_mat, tmat, offs_bone, pchan->chan_mat, NULL, NULL, NULL, NULL, NULL); - } - else if(bone->flag & BONE_HINGE) { // same as above but apply parent scale - float tmat[4][4]; - - /* apply the parent matrix scale */ - float tsmat[4][4], tscale[3]; - - /* the rotation of the parent restposition */ - copy_m4_m4(tmat, parbone->arm_mat); - - /* extract the scale of the parent matrix */ - mat4_to_size(tscale, parchan->pose_mat); - size_to_mat4(tsmat, tscale); - mul_m4_m4m4(tmat, tmat, tsmat); - - mul_serie_m4(pchan->pose_mat, tmat, offs_bone, pchan->chan_mat, NULL, NULL, NULL, NULL, NULL); - } - else if(bone->flag & BONE_NO_SCALE) { - float orthmat[4][4]; - - /* do transform, with an ortho-parent matrix */ - copy_m4_m4(orthmat, parchan->pose_mat); - normalize_m4(orthmat); - mul_serie_m4(pchan->pose_mat, orthmat, offs_bone, pchan->chan_mat, NULL, NULL, NULL, NULL, NULL); - } - else - mul_serie_m4(pchan->pose_mat, parchan->pose_mat, offs_bone, pchan->chan_mat, NULL, NULL, NULL, NULL, NULL); - - /* in these cases we need to compute location separately */ - if(bone->flag & (BONE_HINGE|BONE_NO_SCALE|BONE_NO_LOCAL_LOCATION)) { - float bone_loc[3], chan_loc[3]; - - mul_v3_m4v3(bone_loc, parchan->pose_mat, offs_bone[3]); - copy_v3_v3(chan_loc, pchan->chan_mat[3]); - - /* no local location is not transformed by bone matrix */ - if(!(bone->flag & BONE_NO_LOCAL_LOCATION)) - mul_mat3_m4_v3(offs_bone, chan_loc); - - /* for hinge we use armature instead of pose mat */ - if(bone->flag & BONE_HINGE) mul_mat3_m4_v3(parbone->arm_mat, chan_loc); - else mul_mat3_m4_v3(parchan->pose_mat, chan_loc); - - add_v3_v3v3(pchan->pose_mat[3], bone_loc, chan_loc); - } + { + float rotscale_mat[4][4], loc_mat[4][4]; + pchan_to_pose_mat(pchan, rotscale_mat, loc_mat); + /* Rotation and scale. */ + mult_m4_m4m4(pchan->pose_mat, rotscale_mat, pchan->chan_mat); + /* Location. */ + mul_v3_m4v3(pchan->pose_mat[3], loc_mat, pchan->chan_mat[3]); } - else { - mul_m4_m4m4(pchan->pose_mat, pchan->chan_mat, bone->arm_mat); - /* optional location without arm_mat rotation */ - if(bone->flag & BONE_NO_LOCAL_LOCATION) - add_v3_v3v3(pchan->pose_mat[3], bone->arm_mat[3], pchan->chan_mat[3]); - - /* only rootbones get the cyclic offset (unless user doesn't want that) */ - if ((bone->flag & BONE_NO_CYCLICOFFSET) == 0) + /* Only rootbones get the cyclic offset (unless user doesn't want that). */ + /* XXX That could be a problem for snapping and other "reverse transform" features... */ + if(!pchan->parent) { + if((pchan->bone->flag & BONE_NO_CYCLICOFFSET) == 0) add_v3_v3(pchan->pose_mat[3], ob->pose->cyclic_offset); } - + if(do_extra) { #if 0 /* XXX OLD ANIMSYS, NLASTRIPS ARE NO LONGER USED */ @@ -2364,6 +2431,7 @@ /* Do constraints */ if (pchan->constraints.first) { bConstraintOb *cob; + float vec[3]; /* make a copy of location of PoseChannel for later */ copy_v3_v3(vec, pchan->pose_mat[3]); @@ -2387,7 +2455,7 @@ } } } - + /* calculate head */ copy_v3_v3(pchan->pose_head, pchan->pose_mat[3]); /* calculate tail */ @@ -2465,7 +2533,7 @@ for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { if(pchan->bone) { invert_m4_m4(imat, pchan->bone->arm_mat); - mul_m4_m4m4(pchan->chan_mat, imat, pchan->pose_mat); + mult_m4_m4m4(pchan->chan_mat, pchan->pose_mat, imat); } } } diff -Nru blender-2.61/source/blender/blenkernel/intern/boids.c blender-2.62/source/blender/blenkernel/intern/boids.c --- blender-2.61/source/blender/blenkernel/intern/boids.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/boids.c 2012-02-15 19:34:02.000000000 +0000 @@ -1503,7 +1503,7 @@ state->id = boids->last_state_id++; if(state->id) - sprintf(state->name, "State %i", state->id); + BLI_snprintf(state->name, sizeof(state->name), "State %i", state->id); else strcpy(state->name, "State"); @@ -1514,7 +1514,8 @@ return state; } -BoidState *boid_duplicate_state(BoidSettings *boids, BoidState *state) { +BoidState *boid_duplicate_state(BoidSettings *boids, BoidState *state) +{ BoidState *staten = MEM_dupallocN(state); BLI_duplicatelist(&staten->rules, &state->rules); diff -Nru blender-2.61/source/blender/blenkernel/intern/brush.c blender-2.62/source/blender/blenkernel/intern/brush.c --- blender-2.61/source/blender/blenkernel/intern/brush.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/brush.c 2012-02-15 19:34:02.000000000 +0000 @@ -487,14 +487,14 @@ } /* Brush Sampling */ -void brush_sample_tex(Brush *brush, float *xy, float *rgba, const int thread) +void brush_sample_tex(const Scene *scene, Brush *brush, const float xy[2], float rgba[4], const int thread) { MTex *mtex= &brush->mtex; if (mtex && mtex->tex) { float co[3], tin, tr, tg, tb, ta; int hasrgb; - const int radius= brush_size(brush); + const int radius= brush_size(scene, brush); co[0]= xy[0]/radius; co[1]= xy[1]/radius; @@ -515,19 +515,20 @@ rgba[3]= 1.0f; } } - else if (rgba) + else { rgba[0]= rgba[1]= rgba[2]= rgba[3]= 1.0f; + } } - -void brush_imbuf_new(Brush *brush, short flt, short texfall, int bufsize, ImBuf **outbuf, int use_color_correction) +/* TODO, use define for 'texfall' arg */ +void brush_imbuf_new(const Scene *scene, Brush *brush, short flt, short texfall, int bufsize, ImBuf **outbuf, int use_color_correction) { ImBuf *ibuf; - float xy[2], dist, rgba[4], *dstf; + float xy[2], rgba[4], *dstf; int x, y, rowbytes, xoff, yoff, imbflag; - const int radius= brush_size(brush); - char *dst, crgb[3]; - const float alpha= brush_alpha(brush); + const int radius= brush_size(scene, brush); + unsigned char *dst, crgb[3]; + const float alpha= brush_alpha(scene, brush); float brush_rgb[3]; imbflag= (flt)? IB_rectfloat: IB_rect; @@ -554,67 +555,60 @@ xy[1] = y + yoff; if (texfall == 0) { - dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]); - copy_v3_v3(dstf, brush_rgb); - dstf[3]= alpha*brush_curve_strength_clamp(brush, dist, radius); + dstf[3]= alpha*brush_curve_strength_clamp(brush, len_v2(xy), radius); } else if (texfall == 1) { - brush_sample_tex(brush, xy, dstf, 0); + brush_sample_tex(scene, brush, xy, dstf, 0); } else { - dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]); - - brush_sample_tex(brush, xy, rgba, 0); + brush_sample_tex(scene, brush, xy, rgba, 0); mul_v3_v3v3(dstf, rgba, brush_rgb); - dstf[3] = rgba[3]*alpha*brush_curve_strength_clamp(brush, dist, radius); + dstf[3] = rgba[3]*alpha*brush_curve_strength_clamp(brush, len_v2(xy), radius); } } } } else { - crgb[0]= FTOCHAR(brush->rgb[0]); - crgb[1]= FTOCHAR(brush->rgb[1]); - crgb[2]= FTOCHAR(brush->rgb[2]); + float alpha_f; /* final float alpha to convert to char */ + rgb_float_to_uchar(crgb, brush->rgb); for (y=0; y < ibuf->y; y++) { - dst = (char*)ibuf->rect + y*rowbytes; + dst = (unsigned char *)ibuf->rect + y*rowbytes; for (x=0; x < ibuf->x; x++, dst+=4) { xy[0] = x + xoff; xy[1] = y + yoff; if (texfall == 0) { - dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]); + alpha_f = alpha * brush_curve_strength(brush, len_v2(xy), radius); - dst[0]= crgb[0]; - dst[1]= crgb[1]; - dst[2]= crgb[2]; - dst[3]= FTOCHAR(alpha*brush_curve_strength(brush, dist, radius)); + dst[0] = crgb[0]; + dst[1] = crgb[1]; + dst[2] = crgb[2]; + dst[3] = FTOCHAR(alpha_f); } else if (texfall == 1) { - brush_sample_tex(brush, xy, rgba, 0); - dst[0]= FTOCHAR(rgba[0]); - dst[1]= FTOCHAR(rgba[1]); - dst[2]= FTOCHAR(rgba[2]); - dst[3]= FTOCHAR(rgba[3]); + brush_sample_tex(scene, brush, xy, rgba, 0); + rgba_float_to_uchar(dst, rgba); } else if (texfall == 2) { - dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]); + brush_sample_tex(scene, brush, xy, rgba, 0); + mul_v3_v3(rgba, brush->rgb); + alpha_f = rgba[3] * alpha * brush_curve_strength_clamp(brush, len_v2(xy), radius); + + rgb_float_to_uchar(dst, rgba); - brush_sample_tex(brush, xy, rgba, 0); - dst[0] = FTOCHAR(rgba[0]*brush->rgb[0]); - dst[1] = FTOCHAR(rgba[1]*brush->rgb[1]); - dst[2] = FTOCHAR(rgba[2]*brush->rgb[2]); - dst[3] = FTOCHAR(rgba[3]*alpha*brush_curve_strength_clamp(brush, dist, radius)); - } else { - dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]); - - brush_sample_tex(brush, xy, rgba, 0); - dst[0]= crgb[0]; - dst[1]= crgb[1]; - dst[2]= crgb[2]; - dst[3] = FTOCHAR(rgba[3]*alpha*brush_curve_strength_clamp(brush, dist, radius)); + dst[3] = FTOCHAR(alpha_f); + } + else { + brush_sample_tex(scene, brush, xy, rgba, 0); + alpha_f = rgba[3] * alpha * brush_curve_strength_clamp(brush, len_v2(xy), radius); + + dst[0] = crgb[0]; + dst[1] = crgb[1]; + dst[2] = crgb[2]; + dst[3] = FTOCHAR(alpha_f); } } } @@ -623,6 +617,125 @@ *outbuf= ibuf; } +/* Unified Size and Strength */ + +// XXX: be careful about setting size and unprojected radius +// because they depend on one another +// these functions do not set the other corresponding value +// this can lead to odd behavior if size and unprojected +// radius become inconsistent. +// the biggest problem is that it isn't possible to change +// unprojected radius because a view context is not +// available. my ussual solution to this is to use the +// ratio of change of the size to change the unprojected +// radius. Not completely convinced that is correct. +// In anycase, a better solution is needed to prevent +// inconsistency. + +void brush_set_size(Scene *scene, Brush *brush, int size) +{ + UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; + + if (ups->flag & UNIFIED_PAINT_SIZE) + ups->size= size; + else + brush->size= size; +} + +int brush_size(const Scene *scene, Brush *brush) +{ + UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; + + return (ups->flag & UNIFIED_PAINT_SIZE) ? ups->size : brush->size; +} + +int brush_use_locked_size(const Scene *scene, Brush *brush) +{ + const short us_flag = scene->toolsettings->unified_paint_settings.flag; + + return (us_flag & UNIFIED_PAINT_SIZE) ? + (us_flag & UNIFIED_PAINT_BRUSH_LOCK_SIZE) : + (brush->flag & BRUSH_LOCK_SIZE); +} + +int brush_use_size_pressure(const Scene *scene, Brush *brush) +{ + const short us_flag = scene->toolsettings->unified_paint_settings.flag; + + return (us_flag & UNIFIED_PAINT_SIZE) ? + (us_flag & UNIFIED_PAINT_BRUSH_SIZE_PRESSURE) : + (brush->flag & BRUSH_SIZE_PRESSURE); +} + +int brush_use_alpha_pressure(const Scene *scene, Brush *brush) +{ + const short us_flag = scene->toolsettings->unified_paint_settings.flag; + + return (us_flag & UNIFIED_PAINT_ALPHA) ? + (us_flag & UNIFIED_PAINT_BRUSH_ALPHA_PRESSURE) : + (brush->flag & BRUSH_ALPHA_PRESSURE); +} + +void brush_set_unprojected_radius(Scene *scene, Brush *brush, float unprojected_radius) +{ + UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; + + if (ups->flag & UNIFIED_PAINT_SIZE) + ups->unprojected_radius= unprojected_radius; + else + brush->unprojected_radius= unprojected_radius; +} + +float brush_unprojected_radius(const Scene *scene, Brush *brush) +{ + UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; + + return (ups->flag & UNIFIED_PAINT_SIZE) ? + ups->unprojected_radius : + brush->unprojected_radius; +} + +static void brush_set_alpha(Scene *scene, Brush *brush, float alpha) +{ + UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; + + if (ups->flag & UNIFIED_PAINT_ALPHA) + ups->alpha= alpha; + else + brush->alpha= alpha; +} + +float brush_alpha(const Scene *scene, Brush *brush) +{ + UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; + + return (ups->flag & UNIFIED_PAINT_ALPHA) ? ups->alpha : brush->alpha; +} + +/* scale unprojected radius to reflect a change in the brush's 2D size */ +void brush_scale_unprojected_radius(float *unprojected_radius, + int new_brush_size, + int old_brush_size) +{ + float scale = new_brush_size; + /* avoid division by zero */ + if(old_brush_size != 0) + scale /= (float)old_brush_size; + (*unprojected_radius) *= scale; +} + +/* scale brush size to reflect a change in the brush's unprojected radius */ +void brush_scale_size(int *brush_size, + float new_unprojected_radius, + float old_unprojected_radius) +{ + float scale = new_unprojected_radius; + /* avoid division by zero */ + if(old_unprojected_radius != 0) + scale /= new_unprojected_radius; + (*brush_size)= (int)((float)(*brush_size) * scale); +} + /* Brush Painting */ typedef struct BrushPainterCache { @@ -642,6 +755,7 @@ } BrushPainterCache; struct BrushPainter { + Scene *scene; Brush *brush; float lastmousepos[2]; /* mouse position of last paint call */ @@ -665,16 +779,17 @@ BrushPainterCache cache; }; -BrushPainter *brush_painter_new(Brush *brush) +BrushPainter *brush_painter_new(Scene *scene, Brush *brush) { BrushPainter *painter= MEM_callocN(sizeof(BrushPainter), "BrushPainter"); painter->brush= brush; + painter->scene= scene; painter->firsttouch= 1; painter->cache.lastsize= -1; /* force ibuf create in refresh */ - painter->startsize = brush_size(brush); - painter->startalpha = brush_alpha(brush); + painter->startsize = brush_size(scene, brush); + painter->startalpha = brush_alpha(scene, brush); painter->startjitter = brush->jitter; painter->startspacing = brush->spacing; @@ -707,8 +822,8 @@ { Brush *brush = painter->brush; - brush_set_size(brush, painter->startsize); - brush_set_alpha(brush, painter->startalpha); + brush_set_size(painter->scene, brush, painter->startsize); + brush_set_alpha(painter->scene, brush, painter->startalpha); brush->jitter = painter->startjitter; brush->spacing = painter->startspacing; @@ -720,12 +835,13 @@ static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf, int x, int y, int w, int h, int xt, int yt, float *pos) { + Scene *scene= painter->scene; Brush *brush= painter->brush; ImBuf *ibuf, *maskibuf, *texibuf; float *bf, *mf, *tf, *otf=NULL, xoff, yoff, xy[2], rgba[4]; - char *b, *m, *t, *ot= NULL; + unsigned char *b, *m, *t, *ot= NULL; int dotexold, origx= x, origy= y; - const int radius= brush_size(brush); + const int radius= brush_size(painter->scene, brush); xoff = -radius + 0.5f; yoff = -radius + 0.5f; @@ -763,7 +879,7 @@ xy[0] = x + xoff; xy[1] = y + yoff; - brush_sample_tex(brush, xy, tf, 0); + brush_sample_tex(scene, brush, xy, tf, 0); } bf[0] = tf[0]*mf[0]; @@ -775,12 +891,12 @@ } else { for (; y < h; y++) { - b = (char*)ibuf->rect + (y*ibuf->x + origx)*4; - t = (char*)texibuf->rect + (y*texibuf->x + origx)*4; - m = (char*)maskibuf->rect + (y*maskibuf->x + origx)*4; + b = (unsigned char *)ibuf->rect + (y*ibuf->x + origx)*4; + t = (unsigned char *)texibuf->rect + (y*texibuf->x + origx)*4; + m = (unsigned char *)maskibuf->rect + (y*maskibuf->x + origx)*4; if (dotexold) - ot = (char*)oldtexibuf->rect + ((y - origy + yt)*oldtexibuf->x + xt)*4; + ot = (unsigned char *)oldtexibuf->rect + ((y - origy + yt)*oldtexibuf->x + xt)*4; for (x=origx; x < w; x++, b+=4, m+=4, t+=4) { if (dotexold) { @@ -794,11 +910,8 @@ xy[0] = x + xoff; xy[1] = y + yoff; - brush_sample_tex(brush, xy, rgba, 0); - t[0]= FTOCHAR(rgba[0]); - t[1]= FTOCHAR(rgba[1]); - t[2]= FTOCHAR(rgba[2]); - t[3]= FTOCHAR(rgba[3]); + brush_sample_tex(scene, brush, xy, rgba, 0); + rgba_float_to_uchar(t, rgba); } b[0] = t[0]*m[0]/255; @@ -812,11 +925,12 @@ static void brush_painter_fixed_tex_partial_update(BrushPainter *painter, float *pos) { + const Scene *scene= painter->scene; Brush *brush= painter->brush; BrushPainterCache *cache= &painter->cache; ImBuf *oldtexibuf, *ibuf; int imbflag, destx, desty, srcx, srcy, w, h, x1, y1, x2, y2; - const int diameter= 2*brush_size(brush); + const int diameter= 2*brush_size(scene, brush); imbflag= (cache->flt)? IB_rectfloat: IB_rect; if (!cache->ibuf) @@ -866,13 +980,14 @@ static void brush_painter_refresh_cache(BrushPainter *painter, float *pos, int use_color_correction) { + const Scene *scene= painter->scene; Brush *brush= painter->brush; BrushPainterCache *cache= &painter->cache; MTex *mtex= &brush->mtex; int size; short flt; - const int diameter= 2*brush_size(brush); - const float alpha= brush_alpha(brush); + const int diameter= 2*brush_size(scene, brush); + const float alpha= brush_alpha(scene, brush); if (diameter != cache->lastsize || alpha != cache->lastalpha || @@ -891,11 +1006,11 @@ size= (cache->size)? cache->size: diameter; if (brush->flag & BRUSH_FIXED_TEX) { - brush_imbuf_new(brush, flt, 3, size, &cache->maskibuf, use_color_correction); + brush_imbuf_new(scene, brush, flt, 3, size, &cache->maskibuf, use_color_correction); brush_painter_fixed_tex_partial_update(painter, pos); } else - brush_imbuf_new(brush, flt, 2, size, &cache->ibuf, use_color_correction); + brush_imbuf_new(scene, brush, flt, 2, size, &cache->ibuf, use_color_correction); cache->lastsize= diameter; cache->lastalpha= alpha; @@ -917,17 +1032,17 @@ static void brush_apply_pressure(BrushPainter *painter, Brush *brush, float pressure) { - if (brush_use_alpha_pressure(brush)) - brush_set_alpha(brush, MAX2(0.0f, painter->startalpha*pressure)); - if (brush_use_size_pressure(brush)) - brush_set_size(brush, MAX2(1.0f, painter->startsize*pressure)); + if (brush_use_alpha_pressure(painter->scene, brush)) + brush_set_alpha(painter->scene, brush, MAX2(0.0f, painter->startalpha*pressure)); + if (brush_use_size_pressure(painter->scene, brush)) + brush_set_size(painter->scene, brush, MAX2(1.0f, painter->startsize*pressure)); if (brush->flag & BRUSH_JITTER_PRESSURE) brush->jitter = MAX2(0.0f, painter->startjitter*pressure); if (brush->flag & BRUSH_SPACING_PRESSURE) brush->spacing = MAX2(1.0f, painter->startspacing*(1.5f-pressure)); } -void brush_jitter_pos(Brush *brush, float pos[2], float jitterpos[2]) +void brush_jitter_pos(const Scene *scene, Brush *brush, float pos[2], float jitterpos[2]) { int use_jitter= brush->jitter != 0; @@ -937,7 +1052,7 @@ if(use_jitter){ float rand_pos[2]; - const int radius= brush_size(brush); + const int radius= brush_size(scene, brush); const int diameter= 2*radius; // find random position within a circle of diameter 1 @@ -956,6 +1071,7 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, double time, float pressure, void *user, int use_color_correction) { + Scene *scene= painter->scene; Brush *brush= painter->brush; int totpaintops= 0; @@ -1017,7 +1133,7 @@ else { float startdistance, spacing, step, paintpos[2], dmousepos[2], finalpos[2]; float t, len, press; - const int radius= brush_size(brush); + const int radius= brush_size(scene, brush); /* compute brush spacing adapted to brush radius, spacing may depend on pressure, so update it */ @@ -1042,7 +1158,7 @@ brush_apply_pressure(painter, brush, press); spacing= MAX2(1.0f, radius)*brush->spacing*0.01f; - brush_jitter_pos(brush, paintpos, finalpos); + brush_jitter_pos(scene, brush, paintpos, finalpos); if (painter->cache.enabled) brush_painter_refresh_cache(painter, finalpos, use_color_correction); @@ -1056,7 +1172,7 @@ startdistance -= spacing; } } else { - brush_jitter_pos(brush, pos, finalpos); + brush_jitter_pos(scene, brush, pos, finalpos); if (painter->cache.enabled) brush_painter_refresh_cache(painter, finalpos, use_color_correction); @@ -1084,7 +1200,7 @@ while (painter->accumtime >= (double)brush->rate) { brush_apply_pressure(painter, brush, pressure); - brush_jitter_pos(brush, pos, finalpos); + brush_jitter_pos(scene, brush, pos, finalpos); if (painter->cache.enabled) brush_painter_refresh_cache(painter, finalpos, use_color_correction); @@ -1102,8 +1218,8 @@ painter->lastmousepos[1]= pos[1]; painter->lastpressure= pressure; - brush_set_alpha(brush, painter->startalpha); - brush_set_size(brush, painter->startsize); + brush_set_alpha(scene, brush, painter->startalpha); + brush_set_size(scene, brush, painter->startsize); brush->jitter = painter->startjitter; brush->spacing = painter->startspacing; @@ -1213,261 +1329,3 @@ return im; } - -/* Unified Size and Strength */ - -static void set_unified_settings(Brush *brush, short flag, int value) -{ - Scene *sce; - for (sce= G.main->scene.first; sce; sce= sce->id.next) { - if (sce->toolsettings && - ELEM4(brush, - paint_brush(&(sce->toolsettings->imapaint.paint)), - paint_brush(&(sce->toolsettings->vpaint->paint)), - paint_brush(&(sce->toolsettings->wpaint->paint)), - paint_brush(&(sce->toolsettings->sculpt->paint)))) - { - if (value) - sce->toolsettings->sculpt_paint_settings |= flag; - else - sce->toolsettings->sculpt_paint_settings &= ~flag; - } - } -} - -static short unified_settings(Brush *brush) -{ - Scene *sce; - for (sce= G.main->scene.first; sce; sce= sce->id.next) { - if (sce->toolsettings && - ELEM4(brush, - paint_brush(&(sce->toolsettings->imapaint.paint)), - paint_brush(&(sce->toolsettings->vpaint->paint)), - paint_brush(&(sce->toolsettings->wpaint->paint)), - paint_brush(&(sce->toolsettings->sculpt->paint)))) - { - return sce->toolsettings->sculpt_paint_settings; - } - } - - return 0; -} - -// XXX: be careful about setting size and unprojected radius -// because they depend on one another -// these functions do not set the other corresponding value -// this can lead to odd behavior if size and unprojected -// radius become inconsistent. -// the biggest problem is that it isn't possible to change -// unprojected radius because a view context is not -// available. my ussual solution to this is to use the -// ratio of change of the size to change the unprojected -// radius. Not completely convinced that is correct. -// In anycase, a better solution is needed to prevent -// inconsistency. - -static void set_unified_size(Brush *brush, int value) -{ - Scene *sce; - for (sce= G.main->scene.first; sce; sce= sce->id.next) { - if (sce->toolsettings && - ELEM4(brush, - paint_brush(&(sce->toolsettings->imapaint.paint)), - paint_brush(&(sce->toolsettings->vpaint->paint)), - paint_brush(&(sce->toolsettings->wpaint->paint)), - paint_brush(&(sce->toolsettings->sculpt->paint)))) - { - sce->toolsettings->sculpt_paint_unified_size= value; - } - } -} - -static int unified_size(Brush *brush) -{ - Scene *sce; - for (sce= G.main->scene.first; sce; sce= sce->id.next) { - if (sce->toolsettings && - ELEM4(brush, - paint_brush(&(sce->toolsettings->imapaint.paint)), - paint_brush(&(sce->toolsettings->vpaint->paint)), - paint_brush(&(sce->toolsettings->wpaint->paint)), - paint_brush(&(sce->toolsettings->sculpt->paint)))) - { - return sce->toolsettings->sculpt_paint_unified_size; - } - } - - return 35; // XXX magic number -} - -static void set_unified_alpha(Brush *brush, float value) -{ - Scene *sce; - for (sce= G.main->scene.first; sce; sce= sce->id.next) { - if (sce->toolsettings && - ELEM4(brush, - paint_brush(&(sce->toolsettings->imapaint.paint)), - paint_brush(&(sce->toolsettings->vpaint->paint)), - paint_brush(&(sce->toolsettings->wpaint->paint)), - paint_brush(&(sce->toolsettings->sculpt->paint)))) - { - sce->toolsettings->sculpt_paint_unified_alpha= value; - } - } -} - -static float unified_alpha(Brush *brush) -{ - Scene *sce; - for (sce= G.main->scene.first; sce; sce= sce->id.next) { - if (sce->toolsettings && - ELEM4(brush, - paint_brush(&(sce->toolsettings->imapaint.paint)), - paint_brush(&(sce->toolsettings->vpaint->paint)), - paint_brush(&(sce->toolsettings->wpaint->paint)), - paint_brush(&(sce->toolsettings->sculpt->paint)))) - { - return sce->toolsettings->sculpt_paint_unified_alpha; - } - } - - return 0.5f; // XXX magic number -} - -static void set_unified_unprojected_radius(Brush *brush, float value) -{ - Scene *sce; - for (sce= G.main->scene.first; sce; sce= sce->id.next) { - if (sce->toolsettings && - ELEM4(brush, - paint_brush(&(sce->toolsettings->imapaint.paint)), - paint_brush(&(sce->toolsettings->vpaint->paint)), - paint_brush(&(sce->toolsettings->wpaint->paint)), - paint_brush(&(sce->toolsettings->sculpt->paint)))) - { - sce->toolsettings->sculpt_paint_unified_unprojected_radius= value; - } - } -} - -static float unified_unprojected_radius(Brush *brush) -{ - Scene *sce; - for (sce= G.main->scene.first; sce; sce= sce->id.next) { - if (sce->toolsettings && - ELEM4(brush, - paint_brush(&(sce->toolsettings->imapaint.paint)), - paint_brush(&(sce->toolsettings->vpaint->paint)), - paint_brush(&(sce->toolsettings->wpaint->paint)), - paint_brush(&(sce->toolsettings->sculpt->paint)))) - { - return sce->toolsettings->sculpt_paint_unified_unprojected_radius; - } - } - - return 0.125f; // XXX magic number -} -void brush_set_size(Brush *brush, int size) -{ - if (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_SIZE) - set_unified_size(brush, size); - else - brush->size= size; - - //WM_main_add_notifier(NC_BRUSH|NA_EDITED, brush); -} - -int brush_size(Brush *brush) -{ - return (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_SIZE) ? unified_size(brush) : brush->size; -} - -void brush_set_use_locked_size(Brush *brush, int value) -{ - if (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_SIZE) { - set_unified_settings(brush, SCULPT_PAINT_UNIFIED_LOCK_BRUSH_SIZE, value); - } - else { - if (value) - brush->flag |= BRUSH_LOCK_SIZE; - else - brush->flag &= ~BRUSH_LOCK_SIZE; - } - - //WM_main_add_notifier(NC_BRUSH|NA_EDITED, brush); -} - -int brush_use_locked_size(Brush *brush) -{ - return (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_SIZE) ? (unified_settings(brush) & SCULPT_PAINT_UNIFIED_LOCK_BRUSH_SIZE) : (brush->flag & BRUSH_LOCK_SIZE); -} - -void brush_set_use_size_pressure(Brush *brush, int value) -{ - if (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_SIZE) { - set_unified_settings(brush, SCULPT_PAINT_UNIFIED_SIZE_PRESSURE, value); - } - else { - if (value) - brush->flag |= BRUSH_SIZE_PRESSURE; - else - brush->flag &= ~BRUSH_SIZE_PRESSURE; - } - - //WM_main_add_notifier(NC_BRUSH|NA_EDITED, brush); -} - -int brush_use_size_pressure(Brush *brush) -{ - return (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_SIZE) ? (unified_settings(brush) & SCULPT_PAINT_UNIFIED_SIZE_PRESSURE) : (brush->flag & BRUSH_SIZE_PRESSURE); -} - -void brush_set_use_alpha_pressure(Brush *brush, int value) -{ - if (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_ALPHA) { - set_unified_settings(brush, SCULPT_PAINT_UNIFIED_ALPHA_PRESSURE, value); - } - else { - if (value) - brush->flag |= BRUSH_ALPHA_PRESSURE; - else - brush->flag &= ~BRUSH_ALPHA_PRESSURE; - } - - //WM_main_add_notifier(NC_BRUSH|NA_EDITED, brush); -} - -int brush_use_alpha_pressure(Brush *brush) -{ - return (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_ALPHA) ? (unified_settings(brush) & SCULPT_PAINT_UNIFIED_ALPHA_PRESSURE) : (brush->flag & BRUSH_ALPHA_PRESSURE); -} - -void brush_set_unprojected_radius(Brush *brush, float unprojected_radius) -{ - if (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_SIZE) - set_unified_unprojected_radius(brush, unprojected_radius); - else - brush->unprojected_radius= unprojected_radius; - - //WM_main_add_notifier(NC_BRUSH|NA_EDITED, brush); -} - -float brush_unprojected_radius(Brush *brush) -{ - return (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_SIZE) ? unified_unprojected_radius(brush) : brush->unprojected_radius; -} - -void brush_set_alpha(Brush *brush, float alpha) -{ - if (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_ALPHA) - set_unified_alpha(brush, alpha); - else - brush->alpha= alpha; - - //WM_main_add_notifier(NC_BRUSH|NA_EDITED, brush); -} - -float brush_alpha(Brush *brush) -{ - return (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_ALPHA) ? unified_alpha(brush) : brush->alpha; -} diff -Nru blender-2.61/source/blender/blenkernel/intern/bvhutils.c blender-2.62/source/blender/blenkernel/intern/bvhutils.c --- blender-2.61/source/blender/blenkernel/intern/bvhutils.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/bvhutils.c 2012-02-15 19:34:02.000000000 +0000 @@ -52,7 +52,7 @@ { float dist; - if(isect_ray_tri_v3(ray->origin, ray->direction, v0, v1, v2, &dist, NULL)) + if(isect_ray_tri_epsilon_v3(ray->origin, ray->direction, v0, v1, v2, &dist, NULL, FLT_EPSILON)) return dist; return FLT_MAX; diff -Nru blender-2.61/source/blender/blenkernel/intern/camera.c blender-2.62/source/blender/blenkernel/intern/camera.c --- blender-2.61/source/blender/blenkernel/intern/camera.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/camera.c 2012-02-15 19:34:02.000000000 +0000 @@ -159,7 +159,7 @@ copy_m4_m4(obmat, ob->obmat); normalize_m4(obmat); invert_m4_m4(imat, obmat); - mul_m4_m4m4(mat, cam->dof_ob->obmat, imat); + mult_m4_m4m4(mat, imat, cam->dof_ob->obmat); return fabsf(mat[3][2]); } return cam->YF_dofdist; diff -Nru blender-2.61/source/blender/blenkernel/intern/CCGSubSurf.c blender-2.62/source/blender/blenkernel/intern/CCGSubSurf.c --- blender-2.61/source/blender/blenkernel/intern/CCGSubSurf.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/CCGSubSurf.c 2012-02-15 19:34:02.000000000 +0000 @@ -218,7 +218,7 @@ /***/ -static int VertDataEqual(float *a, float *b) { +static int VertDataEqual(const float *a, const float *b) { return a[0]==b[0] && a[1]==b[1] && a[2]==b[2]; } #define VertDataZero(av) { float *_a = (float*) av; _a[0] = _a[1] = _a[2] = 0.0f; } @@ -238,7 +238,7 @@ #define NormAdd(av, bv) { float *_a = (float*) av, *_b = (float*) bv; _a[0]+=_b[0]; _a[1]+=_b[1]; _a[2]+=_b[2]; } -static int _edge_isBoundary(CCGEdge *e); +static int _edge_isBoundary(const CCGEdge *e); /***/ @@ -392,7 +392,7 @@ v->faces = CCGSUBSURF_realloc(ss, v->faces, (v->numFaces+1)*sizeof(*v->faces), v->numFaces*sizeof(*v->faces)); v->faces[v->numFaces++] = f; } -static CCGEdge *_vert_findEdgeTo(CCGVert *v, CCGVert *vQ) { +static CCGEdge *_vert_findEdgeTo(const CCGVert *v, const CCGVert *vQ) { int i; for (i=0; inumEdges; i++) { CCGEdge *e = v->edges[v->numEdges-1-i]; // XXX, note reverse @@ -402,7 +402,7 @@ } return NULL; } -static int _vert_isBoundary(CCGVert *v) { +static int _vert_isBoundary(const CCGVert *v) { int i; for (i=0; inumEdges; i++) if (_edge_isBoundary(v->edges[i])) @@ -423,7 +423,7 @@ CCGSUBSURF_free(ss, v); } -static int VERT_seam(CCGVert *v) { +static int VERT_seam(const CCGVert *v) { return ((v->flags & Vert_eSeam) != 0); } @@ -462,7 +462,7 @@ e->faces = CCGSUBSURF_realloc(ss, e->faces, (e->numFaces+1)*sizeof(*e->faces), e->numFaces*sizeof(*e->faces)); e->faces[e->numFaces++] = f; } -static int _edge_isBoundary(CCGEdge *e) { +static int _edge_isBoundary(const CCGEdge *e) { return e->numFaces<2; } @@ -900,7 +900,7 @@ return eCCGError_None; } -CCGError ccgSubSurf_syncVert(CCGSubSurf *ss, CCGVertHDL vHDL, void *vertData, int seam, CCGVert **v_r) { +CCGError ccgSubSurf_syncVert(CCGSubSurf *ss, CCGVertHDL vHDL, const void *vertData, int seam, CCGVert **v_r) { void **prevp; CCGVert *v = NULL; short seamflag = (seam)? Vert_eSeam: 0; @@ -2484,13 +2484,13 @@ /*** External API accessor functions ***/ -int ccgSubSurf_getNumVerts(CCGSubSurf *ss) { +int ccgSubSurf_getNumVerts(const CCGSubSurf *ss) { return ss->vMap->numEntries; } -int ccgSubSurf_getNumEdges(CCGSubSurf *ss) { +int ccgSubSurf_getNumEdges(const CCGSubSurf *ss) { return ss->eMap->numEntries; } -int ccgSubSurf_getNumFaces(CCGSubSurf *ss) { +int ccgSubSurf_getNumFaces(const CCGSubSurf *ss) { return ss->fMap->numEntries; } @@ -2504,23 +2504,23 @@ return (CCGFace*) _ehash_lookup(ss->fMap, f); } -int ccgSubSurf_getSubdivisionLevels(CCGSubSurf *ss) { +int ccgSubSurf_getSubdivisionLevels(const CCGSubSurf *ss) { return ss->subdivLevels; } -int ccgSubSurf_getEdgeSize(CCGSubSurf *ss) { +int ccgSubSurf_getEdgeSize(const CCGSubSurf *ss) { return ccgSubSurf_getEdgeLevelSize(ss, ss->subdivLevels); } -int ccgSubSurf_getEdgeLevelSize(CCGSubSurf *ss, int level) { +int ccgSubSurf_getEdgeLevelSize(const CCGSubSurf *ss, int level) { if (level<1 || level>ss->subdivLevels) { return -1; } else { return 1 + (1<subdivLevels); } -int ccgSubSurf_getGridLevelSize(CCGSubSurf *ss, int level) { +int ccgSubSurf_getGridLevelSize(const CCGSubSurf *ss, int level) { if (level<1 || level>ss->subdivLevels) { return -1; } else { @@ -2736,19 +2736,19 @@ /*** Extern API final vert/edge/face interface ***/ -int ccgSubSurf_getNumFinalVerts(CCGSubSurf *ss) { +int ccgSubSurf_getNumFinalVerts(const CCGSubSurf *ss) { int edgeSize = 1 + (1<subdivLevels); int gridSize = 1 + (1<<(ss->subdivLevels-1)); int numFinalVerts = ss->vMap->numEntries + ss->eMap->numEntries*(edgeSize-2) + ss->fMap->numEntries + ss->numGrids*((gridSize-2) + ((gridSize-2)*(gridSize-2))); return numFinalVerts; } -int ccgSubSurf_getNumFinalEdges(CCGSubSurf *ss) { +int ccgSubSurf_getNumFinalEdges(const CCGSubSurf *ss) { int edgeSize = 1 + (1<subdivLevels); int gridSize = 1 + (1<<(ss->subdivLevels-1)); int numFinalEdges = ss->eMap->numEntries*(edgeSize-1) + ss->numGrids*((gridSize-1) + 2*((gridSize-2)*(gridSize-1))); return numFinalEdges; } -int ccgSubSurf_getNumFinalFaces(CCGSubSurf *ss) { +int ccgSubSurf_getNumFinalFaces(const CCGSubSurf *ss) { int gridSize = 1 + (1<<(ss->subdivLevels-1)); int numFinalFaces = ss->numGrids*((gridSize-1)*(gridSize-1)); return numFinalFaces; diff -Nru blender-2.61/source/blender/blenkernel/intern/CCGSubSurf.h blender-2.62/source/blender/blenkernel/intern/CCGSubSurf.h --- blender-2.61/source/blender/blenkernel/intern/CCGSubSurf.h 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/CCGSubSurf.h 2012-02-15 19:34:02.000000000 +0000 @@ -56,7 +56,7 @@ CCGError ccgSubSurf_initFullSync (CCGSubSurf *ss); CCGError ccgSubSurf_initPartialSync (CCGSubSurf *ss); -CCGError ccgSubSurf_syncVert (CCGSubSurf *ss, CCGVertHDL vHDL, void *vertData, int seam, CCGVert **v_r); +CCGError ccgSubSurf_syncVert (CCGSubSurf *ss, CCGVertHDL vHDL, const void *vertData, int seam, CCGVert **v_r); CCGError ccgSubSurf_syncEdge (CCGSubSurf *ss, CCGEdgeHDL eHDL, CCGVertHDL e_vHDL0, CCGVertHDL e_vHDL1, float crease, CCGEdge **e_r); CCGError ccgSubSurf_syncFace (CCGSubSurf *ss, CCGFaceHDL fHDL, int numVerts, CCGVertHDL *vHDLs, CCGFace **f_r); @@ -84,15 +84,15 @@ /***/ -int ccgSubSurf_getNumVerts (CCGSubSurf *ss); -int ccgSubSurf_getNumEdges (CCGSubSurf *ss); -int ccgSubSurf_getNumFaces (CCGSubSurf *ss); - -int ccgSubSurf_getSubdivisionLevels (CCGSubSurf *ss); -int ccgSubSurf_getEdgeSize (CCGSubSurf *ss); -int ccgSubSurf_getEdgeLevelSize (CCGSubSurf *ss, int level); -int ccgSubSurf_getGridSize (CCGSubSurf *ss); -int ccgSubSurf_getGridLevelSize (CCGSubSurf *ss, int level); +int ccgSubSurf_getNumVerts (const CCGSubSurf *ss); +int ccgSubSurf_getNumEdges (const CCGSubSurf *ss); +int ccgSubSurf_getNumFaces (const CCGSubSurf *ss); + +int ccgSubSurf_getSubdivisionLevels (const CCGSubSurf *ss); +int ccgSubSurf_getEdgeSize (const CCGSubSurf *ss); +int ccgSubSurf_getEdgeLevelSize (const CCGSubSurf *ss, int level); +int ccgSubSurf_getGridSize (const CCGSubSurf *ss); +int ccgSubSurf_getGridLevelSize (const CCGSubSurf *ss, int level); CCGVert* ccgSubSurf_getVert (CCGSubSurf *ss, CCGVertHDL v); CCGVertHDL ccgSubSurf_getVertVertHandle (CCGVert *v); @@ -135,9 +135,9 @@ void* ccgSubSurf_getFaceGridDataArray (CCGSubSurf *ss, CCGFace *f, int gridIndex); void* ccgSubSurf_getFaceGridData (CCGSubSurf *ss, CCGFace *f, int gridIndex, int x, int y); -int ccgSubSurf_getNumFinalVerts (CCGSubSurf *ss); -int ccgSubSurf_getNumFinalEdges (CCGSubSurf *ss); -int ccgSubSurf_getNumFinalFaces (CCGSubSurf *ss); +int ccgSubSurf_getNumFinalVerts (const CCGSubSurf *ss); +int ccgSubSurf_getNumFinalEdges (const CCGSubSurf *ss); +int ccgSubSurf_getNumFinalFaces (const CCGSubSurf *ss); /***/ diff -Nru blender-2.61/source/blender/blenkernel/intern/cdderivedmesh.c blender-2.62/source/blender/blenkernel/intern/cdderivedmesh.c --- blender-2.61/source/blender/blenkernel/intern/cdderivedmesh.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/cdderivedmesh.c 2012-02-15 19:34:02.000000000 +0000 @@ -657,7 +657,7 @@ float *nors= dm->getFaceDataArray(dm, CD_NORMAL); MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE); int i, j, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX); - int startFace = 0, lastFlag = 0xdeadbeef; + int startFace = 0 /*, lastFlag = 0xdeadbeef */ /* UNUSED */; MCol *mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL); if(!mcol) mcol = dm->getFaceDataArray(dm, CD_MCOL); @@ -776,7 +776,7 @@ int next_actualFace= dm->drawObject->triangle_to_mface[0]; glShadeModel( GL_SMOOTH ); - lastFlag = 0; + /* lastFlag = 0; */ /* UNUSED */ for(i = 0; i < tottri; i++) { int actualFace = next_actualFace; int flag = 1; @@ -1870,7 +1870,7 @@ int i; /* this will just return the pointer if it wasn't a referenced layer */ - vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT); + vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData); cddm->mvert = vert; for(i = 0; i < dm->numVertData; ++i, ++vert) @@ -1884,7 +1884,7 @@ int i; /* this will just return the pointer if it wasn't a referenced layer */ - vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT); + vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData); cddm->mvert = vert; for(i = 0; i < dm->numVertData; ++i, ++vert) @@ -1899,7 +1899,7 @@ if(dm->numVertData == 0) return; /* we don't want to overwrite any referenced layers */ - cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT); + cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData); /* make a face normal layer if not present */ face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL); @@ -1950,7 +1950,7 @@ index = CustomData_get_layer(&edgeData, CD_ORIGINDEX); for(i = 0; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) { - BLI_edgehashIterator_getKey(ehi, (int*)&med->v1, (int*)&med->v2); + BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2); med->flag = ME_EDGEDRAW|ME_EDGERENDER; *index = ORIGINDEX_NONE; diff -Nru blender-2.61/source/blender/blenkernel/intern/cloth.c blender-2.62/source/blender/blenkernel/intern/cloth.c --- blender-2.61/source/blender/blenkernel/intern/cloth.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/cloth.c 2012-02-15 19:34:02.000000000 +0000 @@ -47,7 +47,6 @@ #include "BKE_modifier.h" #include "BKE_pointcache.h" - #ifdef _WIN32 void tstart ( void ) {} @@ -91,7 +90,7 @@ /* ********** cloth engine ******* */ /* Prototypes for internal functions. */ -static void cloth_to_object (Object *ob, ClothModifierData *clmd, DerivedMesh *dm); +static void cloth_to_object (Object *ob, ClothModifierData *clmd, float (*vertexCos)[3]); static void cloth_from_mesh ( ClothModifierData *clmd, DerivedMesh *dm ); static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr, int first); static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ); @@ -131,6 +130,7 @@ clmd->sim_parms->presets = 2; /* cotton as start setting */ clmd->sim_parms->timescale = 1.0f; /* speed factor, describes how fast cloth moves */ clmd->sim_parms->reset = 0; + clmd->sim_parms->vel_damping = 1.0f; /* 1.0 = no damping, 0.0 = fully dampened */ clmd->coll_parms->self_friction = 5.0; clmd->coll_parms->friction = 5.0; @@ -377,6 +377,8 @@ } implicit_set_positions(clmd); + + clmd->clothObject->last_frame= MINFRAME-1; } return 1; @@ -427,9 +429,8 @@ /************************************************ * clothModifier_do - main simulation function ************************************************/ -DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, DerivedMesh *dm) +void clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, DerivedMesh *dm, float (*vertexCos)[3]) { - DerivedMesh *result; PointCache *cache; PTCacheID pid; float timescale; @@ -439,20 +440,14 @@ clmd->scene= scene; /* nice to pass on later :) */ framenr= (int)scene->r.cfra; cache= clmd->point_cache; - result = CDDM_copy(dm); BKE_ptcache_id_from_cloth(&pid, ob, clmd); BKE_ptcache_id_time(&pid, scene, framenr, &startframe, &endframe, ×cale); clmd->sim_parms->timescale= timescale; - if(!result) { - BKE_ptcache_invalidate(cache); - return dm; - } - if(clmd->sim_parms->reset || (framenr == (startframe - clmd->sim_parms->preroll) && clmd->sim_parms->preroll != 0) - || (clmd->clothObject && result->getNumVerts(result) != clmd->clothObject->numverts)) + || (clmd->clothObject && dm->getNumVerts(dm) != clmd->clothObject->numverts)) { clmd->sim_parms->reset = 0; cache->flag |= PTCACHE_OUTDATED; @@ -460,7 +455,7 @@ BKE_ptcache_validate(cache, 0); cache->last_exact= 0; cache->flag &= ~PTCACHE_REDO_NEEDED; - return result; + return; } // unused in the moment, calculated separately in implicit.c @@ -472,18 +467,20 @@ /* do simulation */ if(!do_init_cloth(ob, clmd, dm, framenr)) - return result; + return; do_step_cloth(ob, clmd, dm, framenr); - cloth_to_object(ob, clmd, result); + cloth_to_object(ob, clmd, vertexCos); + + clmd->clothObject->last_frame= framenr; - return result; + return; } /* simulation is only active during a specific period */ if(framenr < startframe) { BKE_ptcache_invalidate(cache); - return result; + return; } else if(framenr > endframe) { framenr= endframe; @@ -491,14 +488,15 @@ /* initialize simulation data if it didn't exist already */ if(!do_init_cloth(ob, clmd, dm, framenr)) - return result; + return; if((framenr == startframe) && (clmd->sim_parms->preroll == 0)) { BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED); do_init_cloth(ob, clmd, dm, framenr); BKE_ptcache_validate(cache, framenr); cache->flag &= ~PTCACHE_REDO_NEEDED; - return result; + clmd->clothObject->last_frame= framenr; + return; } /* try to read from cache */ @@ -506,14 +504,16 @@ if(cache_result == PTCACHE_READ_EXACT || cache_result == PTCACHE_READ_INTERPOLATED) { implicit_set_positions(clmd); - cloth_to_object (ob, clmd, result); + cloth_to_object (ob, clmd, vertexCos); BKE_ptcache_validate(cache, framenr); if(cache_result == PTCACHE_READ_INTERPOLATED && cache->flag & PTCACHE_REDO_NEEDED) BKE_ptcache_write(&pid, framenr); - return result; + clmd->clothObject->last_frame= framenr; + + return; } else if(cache_result==PTCACHE_READ_OLD) { implicit_set_positions(clmd); @@ -521,9 +521,12 @@ else if( /*ob->id.lib ||*/ (cache->flag & PTCACHE_BAKED)) { /* 2.4x disabled lib, but this can be used in some cases, testing further - campbell */ /* if baked and nothing in cache, do nothing */ BKE_ptcache_invalidate(cache); - return result; + return; } + if(framenr!=clmd->clothObject->last_frame+1) + return; + /* if on second frame, write cache for first frame */ if(cache->simframe == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0)) BKE_ptcache_write(&pid, startframe); @@ -539,9 +542,8 @@ else BKE_ptcache_write(&pid, framenr); - cloth_to_object (ob, clmd, result); - - return result; + cloth_to_object (ob, clmd, vertexCos); + clmd->clothObject->last_frame= framenr; } /* frees all */ @@ -696,24 +698,19 @@ * cloth_to_object - copies the deformed vertices to the object. * **/ -static void cloth_to_object (Object *ob, ClothModifierData *clmd, DerivedMesh *dm) +static void cloth_to_object (Object *ob, ClothModifierData *clmd, float (*vertexCos)[3]) { unsigned int i = 0; - MVert *mvert = NULL; - unsigned int numverts; Cloth *cloth = clmd->clothObject; if (clmd->clothObject) { /* inverse matrix is not uptodate... */ invert_m4_m4(ob->imat, ob->obmat); - mvert = CDDM_get_verts(dm); - numverts = dm->getNumVerts(dm); - - for (i = 0; i < numverts; i++) + for (i = 0; i < cloth->numverts; i++) { - copy_v3_v3 (mvert[i].co, cloth->verts[i].x); - mul_m4_v3(ob->imat, mvert[i].co); /* cloth is in global coords */ + copy_v3_v3 (vertexCos[i], cloth->verts[i].x); + mul_m4_v3(ob->imat, vertexCos[i]); /* cloth is in global coords */ } } } @@ -1154,7 +1151,7 @@ spring->kl = MAX2(mface[i].v4, mface[i].v2); spring->restlen = len_v3v3(cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest); spring->type = CLOTH_SPRING_TYPE_SHEAR; - spring->stiffness = (cloth->verts[spring->kl].shear_stiff + cloth->verts[spring->ij].shear_stiff) / 2.0; + spring->stiffness = (cloth->verts[spring->kl].shear_stiff + cloth->verts[spring->ij].shear_stiff) / 2.0f; BLI_linklist_append ( &edgelist[spring->ij], spring ); BLI_linklist_append ( &edgelist[spring->kl], spring ); diff -Nru blender-2.61/source/blender/blenkernel/intern/colortools.c blender-2.62/source/blender/blenkernel/intern/colortools.c --- blender-2.61/source/blender/blenkernel/intern/colortools.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/colortools.c 2012-02-15 19:34:02.000000000 +0000 @@ -52,45 +52,6 @@ #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" - -void floatbuf_to_srgb_byte(float *rectf, unsigned char *rectc, int x1, int x2, int y1, int y2, int UNUSED(w)) -{ - int x, y; - float *rf= rectf; - float srgb[3]; - unsigned char *rc= rectc; - - for(y=y1; ymatrix, cob->pchan->pose_mat, ob->obmat); + mult_m4_m4m4(cob->matrix, ob->obmat, cob->pchan->pose_mat); } else unit_m4(cob->matrix); @@ -182,7 +184,7 @@ /* calculate delta of constraints evaluation */ invert_m4_m4(imat, cob->startmat); - mul_m4_m4m4(delta, imat, cob->matrix); + mult_m4_m4m4(delta, cob->matrix, imat); /* copy matrices back to source */ switch (cob->type) { @@ -203,7 +205,7 @@ /* cob->ob or cob->pchan might not exist */ if (cob->ob && cob->pchan) { /* copy new pose-matrix back to owner */ - mul_m4_m4m4(cob->pchan->pose_mat, cob->matrix, cob->ob->imat); + mult_m4_m4m4(cob->pchan->pose_mat, cob->ob->imat, cob->matrix); /* copy inverse of delta back to owner */ invert_m4_m4(cob->pchan->constinv, delta); @@ -218,6 +220,50 @@ /* -------------- Space-Conversion API -------------- */ +static void constraint_pchan_diff_mat(bPoseChannel *pchan, float diff_mat[4][4]) +{ + if (pchan->parent) { + float offs_bone[4][4]; + + /* construct offs_bone the same way it is done in armature.c */ + copy_m4_m3(offs_bone, pchan->bone->bone_mat); + copy_v3_v3(offs_bone[3], pchan->bone->head); + offs_bone[3][1] += pchan->bone->parent->length; + + if (pchan->bone->flag & BONE_HINGE) { + /* pose_mat = par_pose-space_location * chan_mat */ + float tmat[4][4]; + + /* the rotation of the parent restposition */ + copy_m4_m4(tmat, pchan->bone->parent->arm_mat); + + /* the location of actual parent transform */ + copy_v3_v3(tmat[3], offs_bone[3]); + zero_v3(offs_bone[3]); + mul_m4_v3(pchan->parent->pose_mat, tmat[3]); + + mult_m4_m4m4(diff_mat, tmat, offs_bone); + } + else { + /* pose_mat = par_pose_mat * bone_mat * chan_mat */ + if (pchan->bone->flag & BONE_NO_SCALE) { + float tmat[4][4]; + copy_m4_m4(tmat, pchan->parent->pose_mat); + normalize_m4(tmat); + mult_m4_m4m4(diff_mat, tmat, offs_bone); + } + else { + mult_m4_m4m4(diff_mat, pchan->parent->pose_mat, offs_bone); + } + } + } + else { + /* pose_mat = chan_mat * arm_mat */ + copy_m4_m4(diff_mat, pchan->bone->arm_mat); + } +} + + /* This function is responsible for the correct transformations/conversions * of a matrix from one space to another for constraint evaluation. * For now, this is only implemented for Objects and PoseChannels. @@ -242,7 +288,7 @@ /* world to pose */ invert_m4_m4(imat, ob->obmat); copy_m4_m4(tempmat, mat); - mul_m4_m4m4(mat, tempmat, imat); + mult_m4_m4m4(mat, imat, tempmat); /* use pose-space as stepping stone for other spaces... */ if (ELEM(to, CONSTRAINT_SPACE_LOCAL, CONSTRAINT_SPACE_PARLOCAL)) { @@ -256,47 +302,23 @@ /* pose to world */ if (to == CONSTRAINT_SPACE_WORLD) { copy_m4_m4(tempmat, mat); - mul_m4_m4m4(mat, tempmat, ob->obmat); + mult_m4_m4m4(mat, ob->obmat, tempmat); } /* pose to local */ else if (to == CONSTRAINT_SPACE_LOCAL) { if (pchan->bone) { - if (pchan->parent) { - float offs_bone[4][4]; - - /* construct offs_bone the same way it is done in armature.c */ - copy_m4_m3(offs_bone, pchan->bone->bone_mat); - copy_v3_v3(offs_bone[3], pchan->bone->head); - offs_bone[3][1]+= pchan->bone->parent->length; - - if (pchan->bone->flag & BONE_HINGE) { - /* pose_mat = par_pose-space_location * chan_mat */ - float tmat[4][4]; - - /* the rotation of the parent restposition */ - copy_m4_m4(tmat, pchan->bone->parent->arm_mat); - - /* the location of actual parent transform */ - copy_v3_v3(tmat[3], offs_bone[3]); - offs_bone[3][0]= offs_bone[3][1]= offs_bone[3][2]= 0.0f; - mul_m4_v3(pchan->parent->pose_mat, tmat[3]); - - mul_m4_m4m4(diff_mat, offs_bone, tmat); - invert_m4_m4(imat, diff_mat); - } - else { - /* pose_mat = par_pose_mat * bone_mat * chan_mat */ - mul_m4_m4m4(diff_mat, offs_bone, pchan->parent->pose_mat); - invert_m4_m4(imat, diff_mat); - } - } - else { - /* pose_mat = chan_mat * arm_mat */ - invert_m4_m4(imat, pchan->bone->arm_mat); - } - + constraint_pchan_diff_mat(pchan, diff_mat); + + invert_m4_m4(imat, diff_mat); + copy_m4_m4(tempmat, mat); - mul_m4_m4m4(mat, tempmat, imat); + mult_m4_m4m4(mat, imat, tempmat); + + /* override with local location */ + if ((pchan->parent) && (pchan->bone->flag & BONE_NO_LOCAL_LOCATION)) { + armature_mat_pose_to_bone_ex(ob, pchan, pchan->pose_mat, tempmat); + copy_v3_v3(mat[3], tempmat[3]); + } } } /* pose to local with parent */ @@ -304,7 +326,7 @@ if (pchan->bone) { invert_m4_m4(imat, pchan->bone->arm_mat); copy_m4_m4(tempmat, mat); - mul_m4_m4m4(mat, tempmat, imat); + mult_m4_m4m4(mat, imat, tempmat); } } } @@ -313,44 +335,11 @@ { /* local to pose - do inverse procedure that was done for pose to local */ if (pchan->bone) { - /* we need the posespace_matrix = local_matrix + (parent_posespace_matrix + restpos) */ - if (pchan->parent) { - float offs_bone[4][4]; - - /* construct offs_bone the same way it is done in armature.c */ - copy_m4_m3(offs_bone, pchan->bone->bone_mat); - copy_v3_v3(offs_bone[3], pchan->bone->head); - offs_bone[3][1]+= pchan->bone->parent->length; - - if (pchan->bone->flag & BONE_HINGE) { - /* pose_mat = par_pose-space_location * chan_mat */ - float tmat[4][4]; - - /* the rotation of the parent restposition */ - copy_m4_m4(tmat, pchan->bone->parent->arm_mat); - - /* the location of actual parent transform */ - copy_v3_v3(tmat[3], offs_bone[3]); - zero_v3(offs_bone[3]); - mul_m4_v3(pchan->parent->pose_mat, tmat[3]); - - mul_m4_m4m4(diff_mat, offs_bone, tmat); - copy_m4_m4(tempmat, mat); - mul_m4_m4m4(mat, tempmat, diff_mat); - } - else { - /* pose_mat = par_pose_mat * bone_mat * chan_mat */ - mul_m4_m4m4(diff_mat, offs_bone, pchan->parent->pose_mat); - copy_m4_m4(tempmat, mat); - mul_m4_m4m4(mat, tempmat, diff_mat); - } - } - else { - copy_m4_m4(diff_mat, pchan->bone->arm_mat); - - copy_m4_m4(tempmat, mat); - mul_m4_m4m4(mat, tempmat, diff_mat); - } + /* we need the posespace_matrix = local_matrix + (parent_posespace_matrix + restpos) */ + constraint_pchan_diff_mat(pchan, diff_mat); + + copy_m4_m4(tempmat, mat); + mult_m4_m4m4(mat, diff_mat, tempmat); } /* use pose-space as stepping stone for other spaces */ @@ -366,7 +355,7 @@ if (pchan->bone) { copy_m4_m4(diff_mat, pchan->bone->arm_mat); copy_m4_m4(tempmat, mat); - mul_m4_m4m4(mat, diff_mat, tempmat); + mult_m4_m4m4(mat, tempmat, diff_mat); } /* use pose-space as stepping stone for other spaces */ @@ -384,10 +373,10 @@ /* check if object has a parent */ if (ob->parent) { /* 'subtract' parent's effects from owner */ - mul_m4_m4m4(diff_mat, ob->parentinv, ob->parent->obmat); + mult_m4_m4m4(diff_mat, ob->parent->obmat, ob->parentinv); invert_m4_m4(imat, diff_mat); copy_m4_m4(tempmat, mat); - mul_m4_m4m4(mat, tempmat, imat); + mult_m4_m4m4(mat, imat, tempmat); } else { /* Local space in this case will have to be defined as local to the owner's @@ -399,7 +388,7 @@ invert_m4_m4(imat, diff_mat); copy_m4_m4(tempmat, mat); - mul_m4_m4m4(mat, tempmat, imat); + mult_m4_m4m4(mat, imat, tempmat); } } else if (from==CONSTRAINT_SPACE_LOCAL && to==CONSTRAINT_SPACE_WORLD) { @@ -407,8 +396,8 @@ if (ob->parent) { /* 'add' parent's effect back to owner */ copy_m4_m4(tempmat, mat); - mul_m4_m4m4(diff_mat, ob->parentinv, ob->parent->obmat); - mul_m4_m4m4(mat, tempmat, diff_mat); + mult_m4_m4m4(diff_mat, ob->parent->obmat, ob->parentinv); + mult_m4_m4m4(mat, diff_mat, tempmat); } else { /* Local space in this case will have to be defined as local to the owner's @@ -419,7 +408,7 @@ zero_v3(diff_mat[3]); copy_m4_m4(tempmat, mat); - mul_m4_m4m4(mat, tempmat, diff_mat); + mult_m4_m4m4(mat, diff_mat, tempmat); } } } @@ -436,16 +425,15 @@ float vec[3] = {0.0f, 0.0f, 0.0f}; float normal[3] = {0.0f, 0.0f, 0.0f}, plane[3]; float imat[3][3], tmat[3][3]; - int dgroup; + const int defgroup= defgroup_name_index(ob, substring); short freeDM = 0; /* initialize target matrix using target matrix */ copy_m4_m4(mat, ob->obmat); /* get index of vertex group */ - dgroup = defgroup_name_index(ob, substring); - if (dgroup < 0) return; - + if (defgroup == -1) return; + /* get DerivedMesh */ if (em) { /* target is in editmode, so get a special derived mesh */ @@ -463,28 +451,25 @@ if (dm) { MDeformVert *dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); int numVerts = dm->getNumVerts(dm); - int i, j, count = 0; + int i, count = 0; float co[3], nor[3]; /* check that dvert is a valid pointers (just in case) */ if (dvert) { + MDeformVert *dv= dvert; /* get the average of all verts with that are in the vertex-group */ - for (i = 0; i < numVerts; i++) { - for (j = 0; j < dvert[i].totweight; j++) { - /* does this vertex belong to nominated vertex group? */ - if (dvert[i].dw[j].def_nr == dgroup) { - dm->getVertCo(dm, i, co); - dm->getVertNo(dm, i, nor); - add_v3_v3(vec, co); - add_v3_v3(normal, nor); - count++; - break; - } + for (i = 0; i < numVerts; i++, dv++) { + MDeformWeight *dw= defvert_find_index(dv, defgroup); + if (dw && dw->weight != 0.0f) { + dm->getVertCo(dm, i, co); + dm->getVertNo(dm, i, nor); + add_v3_v3(vec, co); + add_v3_v3(normal, nor); + count++; } } - - + /* calculate averages of normal and coordinates */ if (count > 0) { mul_v3_fl(vec, 1.0f / count); @@ -506,13 +491,17 @@ normalize_v3(normal); copy_v3_v3(plane, tmat[1]); - copy_v3_v3(tmat[2], normal); - cross_v3_v3v3(tmat[0], normal, plane); - cross_v3_v3v3(tmat[1], tmat[2], tmat[0]); - - copy_m4_m3(mat, tmat); + cross_v3_v3v3(mat[0], normal, plane); + if(len_v3(mat[0]) < 1e-3f) { + copy_v3_v3(plane, tmat[0]); + cross_v3_v3v3(mat[0], normal, plane); + } + + copy_v3_v3(mat[2], normal); + cross_v3_v3v3(mat[1], mat[2], mat[0]); + normalize_m4(mat); - + /* apply the average coordinate as the new location */ mul_v3_m4v3(mat[3], ob->obmat, vec); @@ -535,43 +524,38 @@ float *co = dl?dl->verts:NULL; BPoint *bp = lt->def; - MDeformVert *dvert = lt->dvert; + MDeformVert *dv = lt->dvert; int tot_verts= lt->pntsu*lt->pntsv*lt->pntsw; float vec[3]= {0.0f, 0.0f, 0.0f}, tvec[3]; - int dgroup=0, grouped=0; + int grouped=0; int i, n; + const int defgroup= defgroup_name_index(ob, substring); /* initialize target matrix using target matrix */ copy_m4_m4(mat, ob->obmat); - + /* get index of vertex group */ - dgroup = defgroup_name_index(ob, substring); - if (dgroup < 0) return; - if (dvert == NULL) return; + if (defgroup == -1) return; + if (dv == NULL) return; /* 1. Loop through control-points checking if in nominated vertex-group. * 2. If it is, add it to vec to find the average point. */ - for (i=0; i < tot_verts; i++, dvert++) { - for (n= 0; n < dvert->totweight; n++) { - /* found match - vert is in vgroup */ - if (dvert->dw[n].def_nr == dgroup) { + for (i=0; i < tot_verts; i++, dv++) { + for (n= 0; n < dv->totweight; n++) { + MDeformWeight *dw= defvert_find_index(dv, defgroup); + if (dw && dw->weight > 0.0f) { /* copy coordinates of point to temporary vector, then add to find average */ - if (co) - memcpy(tvec, co, 3*sizeof(float)); - else - memcpy(tvec, bp->vec, 3*sizeof(float)); - + memcpy(tvec, co ? co : bp->vec, 3 * sizeof(float)); + add_v3_v3(vec, tvec); grouped++; - - break; } } /* advance pointer to coordinate data */ - if (co) co+= 3; - else bp++; + if (co) co += 3; + else bp++; } /* find average location, then multiply by ob->obmat to find world-space location */ @@ -621,7 +605,7 @@ */ if (headtail < 0.000001f) { /* skip length interpolation if set to head */ - mul_m4_m4m4(mat, pchan->pose_mat, ob->obmat); + mult_m4_m4m4(mat, ob->obmat, pchan->pose_mat); } else { float tempmat[4][4], loc[3]; @@ -633,7 +617,7 @@ copy_m4_m4(tempmat, pchan->pose_mat); copy_v3_v3(tempmat[3], loc); - mul_m4_m4m4(mat, tempmat, ob->obmat); + mult_m4_m4m4(mat, ob->obmat, tempmat); } } else @@ -834,7 +818,7 @@ { bChildOfConstraint *data= con->data; bConstraintTarget *ct= targets->first; - + /* only evaluate if there is a target */ if (VALID_CONS_TARGET(ct)) { float parmat[4][4]; @@ -845,12 +829,12 @@ /* multiply target (parent matrix) by offset (parent inverse) to get * the effect of the parent that will be exherted on the owner */ - mul_m4_m4m4(parmat, data->invmat, ct->matrix); + mult_m4_m4m4(parmat, ct->matrix, data->invmat); /* now multiply the parent matrix by the owner matrix to get the * the effect of this constraint (i.e. owner is 'parented' to parent) */ - mul_m4_m4m4(cob->matrix, cob->matrix, parmat); + mult_m4_m4m4(cob->matrix, parmat, cob->matrix); } else { float invmat[4][4], tempmat[4][4]; @@ -887,13 +871,13 @@ /* multiply target (parent matrix) by offset (parent inverse) to get * the effect of the parent that will be exherted on the owner */ - mul_m4_m4m4(parmat, invmat, ct->matrix); + mult_m4_m4m4(parmat, ct->matrix, invmat); /* now multiply the parent matrix by the owner matrix to get the * the effect of this constraint (i.e. owner is 'parented' to parent) */ copy_m4_m4(tempmat, cob->matrix); - mul_m4_m4m4(cob->matrix, tempmat, parmat); + mult_m4_m4m4(cob->matrix, parmat, tempmat); /* without this, changes to scale and rotation can change location * of a parentless bone or a disconnected bone. Even though its set @@ -1106,10 +1090,10 @@ { bKinematicConstraint *data= (bKinematicConstraint *)cdata; - data->weight= (float)1.0; - data->orientweight= (float)1.0; + data->weight= 1.0f; + data->orientweight= 1.0f; data->iterations = 500; - data->dist= (float)1.0; + data->dist= 1.0f; data->flag= CONSTRAINT_IK_TIP|CONSTRAINT_IK_STRETCH|CONSTRAINT_IK_POS; } @@ -1264,6 +1248,7 @@ float quat[4]; if ((data->followflag & FOLLOWPATH_STATIC) == 0) { /* animated position along curve depending on time */ + Nurb *nu = cu->nurb.first; curvetime= cu->ctime - data->offset; /* ctime is now a proper var setting of Curve which gets set by Animato like any other var that's animated, @@ -1273,7 +1258,18 @@ * factor, which then gets clamped to lie within 0.0 - 1.0 range */ curvetime /= cu->pathlen; - CLAMP(curvetime, 0.0f, 1.0f); + + if (nu && nu->flagu & CU_NURB_CYCLIC) { + /* If the curve is cyclic, enable looping around if the time is + * outside the bounds 0..1 */ + if ((curvetime < 0.0f) || (curvetime > 1.0f)) { + curvetime -= floorf(curvetime); + } + } + else { + /* The curve is not cyclic, so clamp to the begin/end points. */ + CLAMP(curvetime, 0.0f, 1.0f); + } } else { /* fixed position along curve */ @@ -1303,7 +1299,7 @@ if (data->followflag & FOLLOWPATH_RADIUS) { float tmat[4][4], rmat[4][4]; scale_m4_fl(tmat, radius); - mul_m4_m4m4(rmat, totmat, tmat); + mult_m4_m4m4(rmat, tmat, totmat); copy_m4_m4(totmat, rmat); } @@ -2246,7 +2242,7 @@ * function has already taken care of everything else. */ copy_m4_m4(temp, cob->matrix); - mul_m4_m4m4(cob->matrix, ct->matrix, temp); + mult_m4_m4m4(cob->matrix, temp, ct->matrix); } } @@ -2770,18 +2766,22 @@ /* store Z orientation before destroying obmat */ normalize_v3_v3(zz, cob->matrix[2]); - sub_v3_v3v3(vec, cob->matrix[3], ct->matrix[3]); - vec[0] /= size[0]; - vec[1] /= size[1]; - vec[2] /= size[2]; - - dist = normalize_v3(vec); - //dist = len_v3v3( ob->obmat[3], targetmat[3]); + /* XXX That makes the constraint buggy with asymmetrically scaled objects, see #29940. */ +/* sub_v3_v3v3(vec, cob->matrix[3], ct->matrix[3]);*/ +/* vec[0] /= size[0];*/ +/* vec[1] /= size[1];*/ +/* vec[2] /= size[2];*/ + +/* dist = normalize_v3(vec);*/ + + dist = len_v3v3(cob->matrix[3], ct->matrix[3]); + /* Only Y constrained object axis scale should be used, to keep same length when scaling it. */ + dist /= size[1]; /* data->orglength==0 occurs on first run, and after 'R' button is clicked */ - if (data->orglength == 0) + if (data->orglength == 0) data->orglength = dist; - if (data->bulge == 0) + if (data->bulge == 0) data->bulge = 1.0; scale[1] = dist/data->orglength; @@ -2937,7 +2937,7 @@ if (data->flag & MINMAX_USEROT) { /* take rotation of target into account by doing the transaction in target's localspace */ invert_m4_m4(imat, tarmat); - mul_m4_m4m4(tmat, obmat, imat); + mult_m4_m4m4(tmat, imat, obmat); copy_m4_m4(obmat, tmat); unit_m4(tarmat); } @@ -2990,7 +2990,7 @@ } if (data->flag & MINMAX_USEROT) { /* get out of localspace */ - mul_m4_m4m4(tmat, obmat, ct->matrix); + mult_m4_m4m4(tmat, ct->matrix, obmat); copy_m4_m4(cob->matrix, tmat); } else { @@ -3946,6 +3946,8 @@ bFollowTrackConstraint *data= con->data; func(con, (ID**)&data->clip, userdata); + func(con, (ID**)&data->camera, userdata); + func(con, (ID**)&data->depth_ob, userdata); } static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets)) @@ -3953,105 +3955,151 @@ Scene *scene= cob->scene; bFollowTrackConstraint *data= con->data; MovieClip *clip= data->clip; + MovieTracking *tracking; MovieTrackingTrack *track; - + MovieTrackingObject *tracking_object; + Object *camob= data->camera ? data->camera : scene->camera; + if (data->flag & FOLLOWTRACK_ACTIVECLIP) clip= scene->clip; - - if (!clip || !data->track[0]) + + if (!clip || !data->track[0] || !camob) return; - - track= BKE_tracking_named_track(&clip->tracking, data->track); - + + tracking= &clip->tracking; + + if(data->object[0]) + tracking_object= BKE_tracking_named_object(tracking, data->object); + else + tracking_object= BKE_tracking_get_camera_object(tracking); + + if(!tracking_object) + return; + + track= BKE_tracking_named_track(tracking, tracking_object, data->track); + if (!track) return; - + if (data->flag & FOLLOWTRACK_USE_3D_POSITION) { if (track->flag & TRACK_HAS_BUNDLE) { - float pos[3], mat[4][4], obmat[4][4]; - + float obmat[4][4], mat[4][4]; + copy_m4_m4(obmat, cob->matrix); - - BKE_get_tracking_mat(cob->scene, NULL, mat); - mul_v3_m4v3(pos, mat, track->bundle_pos); - - cob->matrix[3][0] += pos[0]; - cob->matrix[3][1] += pos[1]; - cob->matrix[3][2] += pos[2]; + + if((tracking_object->flag&TRACKING_OBJECT_CAMERA)==0) { + float imat[4][4]; + + copy_m4_m4(mat, camob->obmat); + + BKE_tracking_get_interpolated_camera(tracking, tracking_object, scene->r.cfra, imat); + invert_m4(imat); + + mul_serie_m4(cob->matrix, obmat, mat, imat, NULL, NULL, NULL, NULL, NULL); + translate_m4(cob->matrix, track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]); + } + else { + BKE_get_tracking_mat(cob->scene, camob, mat); + + mult_m4_m4m4(cob->matrix, obmat, mat); + translate_m4(cob->matrix, track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]); + } } - } + } else { - Object *camob= cob->scene->camera; - - if (camob) { - MovieClipUser user; - MovieTrackingMarker *marker; - float vec[3], disp[3], axis[3], mat[4][4]; - float aspect= (scene->r.xsch*scene->r.xasp) / (scene->r.ysch*scene->r.yasp); - float len, d; - - where_is_object_mat(scene, camob, mat); - - /* camera axis */ - vec[0]= 0.0f; - vec[1]= 0.0f; - vec[2]= 1.0f; - mul_v3_m4v3(axis, mat, vec); - - /* distance to projection plane */ - copy_v3_v3(vec, cob->matrix[3]); - sub_v3_v3(vec, mat[3]); - project_v3_v3v3(disp, vec, axis); - - len= len_v3(disp); - - if (len > FLT_EPSILON) { - CameraParams params; - float pos[2], rmat[4][4]; - - user.framenr= scene->r.cfra; - marker= BKE_tracking_get_marker(track, user.framenr); - - add_v2_v2v2(pos, marker->pos, track->offset); - - camera_params_init(¶ms); - camera_params_from_object(¶ms, camob); + MovieTrackingMarker *marker; + float vec[3], disp[3], axis[3], mat[4][4]; + float aspect= (scene->r.xsch*scene->r.xasp) / (scene->r.ysch*scene->r.yasp); + float len, d; - if (params.is_ortho) { - vec[0]= params.ortho_scale * (pos[0]-0.5f+params.shiftx); - vec[1]= params.ortho_scale * (pos[1]-0.5f+params.shifty); - vec[2]= -len; - - if (aspect > 1.0f) vec[1] /= aspect; - else vec[0] *= aspect; - - mul_v3_m4v3(disp, camob->obmat, vec); - - copy_m4_m4(rmat, camob->obmat); - zero_v3(rmat[3]); - mul_m4_m4m4(cob->matrix, rmat, cob->matrix); - - copy_v3_v3(cob->matrix[3], disp); - } - else { - d= (len*params.sensor_x) / (2.0f*params.lens); - - vec[0]= d*(2.0f*(pos[0]+params.shiftx)-1.0f); - vec[1]= d*(2.0f*(pos[1]+params.shifty)-1.0f); - vec[2]= -len; - - if (aspect > 1.0f) vec[1] /= aspect; - else vec[0] *= aspect; - - mul_v3_m4v3(disp, camob->obmat, vec); - - /* apply camera rotation so Z-axis would be co-linear */ - copy_m4_m4(rmat, camob->obmat); - zero_v3(rmat[3]); - mul_m4_m4m4(cob->matrix, rmat, cob->matrix); - - copy_v3_v3(cob->matrix[3], disp); + where_is_object_mat(scene, camob, mat); + + /* camera axis */ + vec[0]= 0.0f; + vec[1]= 0.0f; + vec[2]= 1.0f; + mul_v3_m4v3(axis, mat, vec); + + /* distance to projection plane */ + copy_v3_v3(vec, cob->matrix[3]); + sub_v3_v3(vec, mat[3]); + project_v3_v3v3(disp, vec, axis); + + len= len_v3(disp); + + if (len > FLT_EPSILON) { + CameraParams params; + float pos[2], rmat[4][4]; + + marker= BKE_tracking_get_marker(track, scene->r.cfra); + + add_v2_v2v2(pos, marker->pos, track->offset); + + camera_params_init(¶ms); + camera_params_from_object(¶ms, camob); + + if (params.is_ortho) { + vec[0]= params.ortho_scale * (pos[0]-0.5f+params.shiftx); + vec[1]= params.ortho_scale * (pos[1]-0.5f+params.shifty); + vec[2]= -len; + + if (aspect > 1.0f) vec[1] /= aspect; + else vec[0] *= aspect; + + mul_v3_m4v3(disp, camob->obmat, vec); + + copy_m4_m4(rmat, camob->obmat); + zero_v3(rmat[3]); + mult_m4_m4m4(cob->matrix, cob->matrix, rmat); + + copy_v3_v3(cob->matrix[3], disp); + } + else { + d= (len*params.sensor_x) / (2.0f*params.lens); + + vec[0]= d*(2.0f*(pos[0]+params.shiftx)-1.0f); + vec[1]= d*(2.0f*(pos[1]+params.shifty)-1.0f); + vec[2]= -len; + + if (aspect > 1.0f) vec[1] /= aspect; + else vec[0] *= aspect; + + mul_v3_m4v3(disp, camob->obmat, vec); + + /* apply camera rotation so Z-axis would be co-linear */ + copy_m4_m4(rmat, camob->obmat); + zero_v3(rmat[3]); + mult_m4_m4m4(cob->matrix, cob->matrix, rmat); + + copy_v3_v3(cob->matrix[3], disp); + } + + if(data->depth_ob && data->depth_ob->derivedFinal) { + Object *depth_ob= data->depth_ob; + BVHTreeFromMesh treeData= NULL_BVHTreeFromMesh; + BVHTreeRayHit hit; + float ray_start[3], ray_end[3], ray_nor[3], imat[4][4]; + int result; + + invert_m4_m4(imat, depth_ob->obmat); + + mul_v3_m4v3(ray_start, imat, camob->obmat[3]); + mul_v3_m4v3(ray_end, imat, cob->matrix[3]); + + sub_v3_v3v3(ray_nor, ray_end, ray_start); + + bvhtree_from_mesh_faces(&treeData, depth_ob->derivedFinal, 0.0f, 4, 6); + + hit.dist= FLT_MAX; + hit.index= -1; + + result= BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_nor, 0.0f, &hit, treeData.raycast_callback, &treeData); + + if(result != -1) { + mul_v3_m4v3(cob->matrix[3], depth_ob->obmat, hit.co); } + + free_bvhtree_from_mesh(&treeData); } } } @@ -4095,17 +4143,20 @@ Scene *scene= cob->scene; bCameraSolverConstraint *data= con->data; MovieClip *clip= data->clip; - + if (data->flag & CAMERASOLVER_ACTIVECLIP) clip= scene->clip; - + if (clip) { float mat[4][4], obmat[4][4]; - - BKE_tracking_get_interpolated_camera(&clip->tracking, scene->r.cfra, mat); - + MovieTracking *tracking= &clip->tracking; + MovieTrackingObject *object= BKE_tracking_get_camera_object(tracking); + + BKE_tracking_get_interpolated_camera(tracking, object, scene->r.cfra, mat); + copy_m4_m4(obmat, cob->matrix); - mul_m4_m4m4(cob->matrix, mat, obmat); + + mult_m4_m4m4(cob->matrix, obmat, mat); } } @@ -4125,6 +4176,80 @@ camerasolver_evaluate /* evaluate */ }; +/* ----------- Object Solver ------------- */ + +static void objectsolver_new_data (void *cdata) +{ + bObjectSolverConstraint *data= (bObjectSolverConstraint *)cdata; + + data->clip = NULL; + data->flag |= OBJECTSOLVER_ACTIVECLIP; + unit_m4(data->invmat); +} + +static void objectsolver_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata) +{ + bObjectSolverConstraint *data= con->data; + + func(con, (ID**)&data->clip, userdata); + func(con, (ID**)&data->camera, userdata); +} + +static void objectsolver_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets)) +{ + Scene *scene= cob->scene; + bObjectSolverConstraint *data= con->data; + MovieClip *clip= data->clip; + Object *camob= data->camera ? data->camera : scene->camera; + + if (data->flag & OBJECTSOLVER_ACTIVECLIP) + clip= scene->clip; + + if(!camob || !clip) + return; + + if (clip) { + MovieTracking *tracking= &clip->tracking; + MovieTrackingObject *object; + + object= BKE_tracking_named_object(tracking, data->object); + + if(object) { + float mat[4][4], obmat[4][4], imat[4][4], cammat[4][4], camimat[4][4], parmat[4][4]; + + where_is_object_mat(scene, camob, cammat); + + BKE_tracking_get_interpolated_camera(tracking, object, scene->r.cfra, mat); + + invert_m4_m4(camimat, cammat); + mult_m4_m4m4(parmat, cammat, data->invmat); + + copy_m4_m4(cammat, camob->obmat); + copy_m4_m4(obmat, cob->matrix); + + invert_m4_m4(imat, mat); + + mul_serie_m4(cob->matrix, cammat, imat, camimat, parmat, obmat, NULL, NULL, NULL); + } + } +} + +static bConstraintTypeInfo CTI_OBJECTSOLVER = { + CONSTRAINT_TYPE_OBJECTSOLVER, /* type */ + sizeof(bObjectSolverConstraint), /* size */ + "Object Solver", /* name */ + "bObjectSolverConstraint", /* struct name */ + NULL, /* free data */ + NULL, /* relink data */ + objectsolver_id_looper, /* id looper */ + NULL, /* copy data */ + objectsolver_new_data, /* new data */ + NULL, /* get constraint targets */ + NULL, /* flush constraint targets */ + NULL, /* get target matrix */ + objectsolver_evaluate /* evaluate */ +}; + /* ************************* Constraints Type-Info *************************** */ /* All of the constraints api functions use bConstraintTypeInfo structs to carry out * and operations that involve constraint specific code. @@ -4165,6 +4290,7 @@ constraintsTypeInfo[25]= &CTI_PIVOT; /* Pivot Constraint */ constraintsTypeInfo[26]= &CTI_FOLLOWTRACK; /* Follow Track Constraint */ constraintsTypeInfo[27]= &CTI_CAMERASOLVER; /* Camera Solver Constraint */ + constraintsTypeInfo[28]= &CTI_OBJECTSOLVER; /* Object Solver Constraint */ } /* This function should be used for getting the appropriate type-info when only diff -Nru blender-2.61/source/blender/blenkernel/intern/context.c blender-2.62/source/blender/blenkernel/intern/context.c --- blender-2.61/source/blender/blenkernel/intern/context.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/context.c 2012-02-15 19:34:02.000000000 +0000 @@ -381,7 +381,8 @@ { C->wm.window= win; C->wm.screen= (win)? win->screen: NULL; - C->data.scene= (C->wm.screen)? C->wm.screen->scene: NULL; + if(C->wm.screen) + C->data.scene= C->wm.screen->scene; C->wm.area= NULL; C->wm.region= NULL; } @@ -389,7 +390,8 @@ void CTX_wm_screen_set(bContext *C, bScreen *screen) { C->wm.screen= screen; - C->data.scene= (C->wm.screen)? C->wm.screen->scene: NULL; + if(C->wm.screen) + C->data.scene= C->wm.screen->scene; C->wm.area= NULL; C->wm.region= NULL; } diff -Nru blender-2.61/source/blender/blenkernel/intern/curve.c blender-2.62/source/blender/blenkernel/intern/curve.c --- blender-2.61/source/blender/blenkernel/intern/curve.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/curve.c 2012-02-15 19:34:02.000000000 +0000 @@ -368,9 +368,8 @@ dl= cu->disp.first; while(dl) { - if(dl->type==DL_INDEX3 || dl->type==DL_INDEX3) tot= dl->nr; - else tot= dl->nr*dl->parts; - + tot = ELEM(dl->type, DL_INDEX3, DL_INDEX4) ? dl->nr : dl->nr * dl->parts; + if(tot) doit= 1; fp= dl->verts; while(tot--) { diff -Nru blender-2.61/source/blender/blenkernel/intern/customdata.c blender-2.62/source/blender/blenkernel/intern/customdata.c --- blender-2.61/source/blender/blenkernel/intern/customdata.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/customdata.c 2012-02-15 19:34:02.000000000 +0000 @@ -99,6 +99,14 @@ default is assumed to be all zeros */ void (*set_default)(void *data, int count); + /* functions necassary for geometry collapse*/ + int (*equal)(void *data1, void *data2); + void (*multiply)(void *data, float fac); + void (*initminmax)(void *min, void *max); + void (*add)(void *data1, void *data2); + void (*dominmax)(void *data1, void *min, void *max); + void (*copyvalue)(void *source, void *dest); + /* a function to read data from a cdf file */ int (*read)(CDataFile *cdf, void *data, int count); @@ -226,13 +234,11 @@ w = weights ? weights[i] : 1.0f; mst = (MSticky*)sources[i]; - co[0] += w*mst->co[0]; - co[1] += w*mst->co[1]; + madd_v2_v2fl(co, mst->co, w); } mst = (MSticky*)dest; - mst->co[0] = co[0]; - mst->co[1] = co[1]; + copy_v2_v2(mst->co, co); } @@ -251,13 +257,11 @@ { MTFace *tf = dest; int i, j, k; - float uv[4][2]; + float uv[4][2] = {{0.0f}}; float *sub_weight; if(count <= 0) return; - memset(uv, 0, sizeof(uv)); - sub_weight = sub_weights; for(i = 0; i < count; ++i) { float weight = weights ? weights[i] : 1; @@ -266,24 +270,17 @@ for(j = 0; j < 4; ++j) { if(sub_weights) { for(k = 0; k < 4; ++k, ++sub_weight) { - float w = (*sub_weight) * weight; - float *tmp_uv = src->uv[k]; - - uv[j][0] += tmp_uv[0] * w; - uv[j][1] += tmp_uv[1] * w; + madd_v2_v2fl(uv[j], src->uv[k], (*sub_weight) * weight); } - } else { - uv[j][0] += src->uv[j][0] * weight; - uv[j][1] += src->uv[j][1] * weight; + } + else { + madd_v2_v2fl(uv[j], src->uv[j], weight); } } } - *tf = *(MTFace *)sources[0]; - for(j = 0; j < 4; ++j) { - tf->uv[j][0] = uv[j][0]; - tf->uv[j][1] = uv[j][1]; - } + *tf = *(MTFace *)(*sources); + memcpy(tf->uv, uv, sizeof(tf->uv)); } static void layerSwap_tface(void *data, const int *corner_indices) @@ -299,10 +296,9 @@ int j; for(j = 0; j < 4; ++j) { - int source_index = corner_indices[j]; + const int source_index = corner_indices[j]; - uv[j][0] = tf->uv[source_index][0]; - uv[j][1] = tf->uv[source_index][1]; + copy_v2_v2(uv[j], tf->uv[source_index]); // swap pinning flags around if(tf->unwrap & pin_flags[source_index]) { @@ -331,6 +327,24 @@ tf[i] = default_tf; } +static void layerCopy_propFloat(const void *source, void *dest, + int count) +{ + memcpy(dest, source, sizeof(MFloatProperty)*count); +} + +static void layerCopy_propInt(const void *source, void *dest, + int count) +{ + memcpy(dest, source, sizeof(MIntProperty)*count); +} + +static void layerCopy_propString(const void *source, void *dest, + int count) +{ + memcpy(dest, source, sizeof(MStringProperty)*count); +} + static void layerCopy_origspace_face(const void *source, void *dest, int count) { const OrigSpaceFace *source_tf = (const OrigSpaceFace*)source; @@ -346,13 +360,11 @@ { OrigSpaceFace *osf = dest; int i, j, k; - float uv[4][2]; + float uv[4][2] = {{0.0f}}; float *sub_weight; if(count <= 0) return; - memset(uv, 0, sizeof(uv)); - sub_weight = sub_weights; for(i = 0; i < count; ++i) { float weight = weights ? weights[i] : 1; @@ -361,24 +373,18 @@ for(j = 0; j < 4; ++j) { if(sub_weights) { for(k = 0; k < 4; ++k, ++sub_weight) { - float w = (*sub_weight) * weight; - float *tmp_uv = src->uv[k]; - - uv[j][0] += tmp_uv[0] * w; - uv[j][1] += tmp_uv[1] * w; + madd_v2_v2fl(uv[j], src->uv[k], (*sub_weight) * weight); } } else { - uv[j][0] += src->uv[j][0] * weight; - uv[j][1] += src->uv[j][1] * weight; + madd_v2_v2fl(uv[j], src->uv[j], weight); } } } - *osf = *(OrigSpaceFace *)sources[0]; - for(j = 0; j < 4; ++j) { - osf->uv[j][0] = uv[j][0]; - osf->uv[j][1] = uv[j][1]; - } +#if 0 /* no need, this ONLY contains UV's */ + *osf = *(OrigSpaceFace *)(*sources); +#endif + memcpy(osf->uv, uv, sizeof(osf->uv)); } static void layerSwap_origspace_face(void *data, const int *corner_indices) @@ -388,8 +394,7 @@ int j; for(j = 0; j < 4; ++j) { - uv[j][0] = osf->uv[corner_indices[j]][0]; - uv[j][1] = osf->uv[corner_indices[j]][1]; + copy_v2_v2(uv[j], osf->uv[corner_indices[j]]); } memcpy(osf->uv, uv, sizeof(osf->uv)); } @@ -640,10 +645,83 @@ } /* --------- */ +static void layerCopyValue_mloopcol(void *source, void *dest) +{ + MLoopCol *m1 = source, *m2 = dest; + + m2->r = m1->r; + m2->g = m1->g; + m2->b = m1->b; + m2->a = m1->a; +} + +static int layerEqual_mloopcol(void *data1, void *data2) +{ + MLoopCol *m1 = data1, *m2 = data2; + float r, g, b, a; + + r = m1->r - m2->r; + g = m1->g - m2->g; + b = m1->b - m2->b; + a = m1->a - m2->a; + + return r*r + g*g + b*b + a*a < 0.001; +} + +static void layerMultiply_mloopcol(void *data, float fac) +{ + MLoopCol *m = data; + + m->r = (float)m->r * fac; + m->g = (float)m->g * fac; + m->b = (float)m->b * fac; + m->a = (float)m->a * fac; +} + +static void layerAdd_mloopcol(void *data1, void *data2) +{ + MLoopCol *m = data1, *m2 = data2; + + m->r += m2->r; + m->g += m2->g; + m->b += m2->b; + m->a += m2->a; +} + +static void layerDoMinMax_mloopcol(void *data, void *vmin, void *vmax) +{ + MLoopCol *m = data; + MLoopCol *min = vmin, *max = vmax; + + if (m->r < min->r) min->r = m->r; + if (m->g < min->g) min->g = m->g; + if (m->b < min->b) min->b = m->b; + if (m->a < min->a) min->a = m->a; + + if (m->r > max->r) max->r = m->r; + if (m->g > max->g) max->g = m->g; + if (m->b > max->b) max->b = m->b; + if (m->a > max->a) max->a = m->a; +} + +static void layerInitMinMax_mloopcol(void *vmin, void *vmax) +{ + MLoopCol *min = vmin, *max = vmax; + + min->r = 255; + min->g = 255; + min->b = 255; + min->a = 255; + + max->r = 0; + max->g = 0; + max->b = 0; + max->a = 0; +} static void layerDefault_mloopcol(void *data, int count) { - static MLoopCol default_mloopcol = {255,255,255,255}; + MLoopCol default_mloopcol = {255,255,255,255}; MLoopCol *mlcol = (MLoopCol*)data; int i; for(i = 0; i < count; i++) @@ -674,7 +752,7 @@ col.r += src->r * (*sub_weight) * weight; col.g += src->g * (*sub_weight) * weight; col.b += src->b * (*sub_weight) * weight; - sub_weight++; + sub_weight++; } else { col.a += src->a * weight; col.r += src->r * weight; @@ -695,33 +773,74 @@ mc->g = (int)col.g; mc->b = (int)col.b; } + +static void layerCopyValue_mloopuv(void *source, void *dest) +{ + MLoopUV *luv1 = source, *luv2 = dest; + + copy_v2_v2(luv2->uv, luv1->uv); +} + +static int layerEqual_mloopuv(void *data1, void *data2) +{ + MLoopUV *luv1 = data1, *luv2 = data2; + + return len_squared_v2v2(luv1->uv, luv2->uv) < 0.00001f; +} + +static void layerMultiply_mloopuv(void *data, float fac) +{ + MLoopUV *luv = data; + + mul_v2_fl(luv->uv, fac); +} + +static void layerInitMinMax_mloopuv(void *vmin, void *vmax) +{ + MLoopUV *min = vmin, *max = vmax; + + INIT_MINMAX2(min->uv, max->uv); +} + +static void layerDoMinMax_mloopuv(void *data, void *vmin, void *vmax) +{ + MLoopUV *min = vmin, *max = vmax, *luv = data; + + DO_MINMAX2(luv->uv, min->uv, max->uv); +} + +static void layerAdd_mloopuv(void *data1, void *data2) +{ + MLoopUV *l1 = data1, *l2 = data2; + + add_v2_v2(l1->uv, l2->uv); +} + static void layerInterp_mloopuv(void **sources, float *weights, - float *sub_weights, int count, void *dest) + float *sub_weights, int count, void *dest) { MLoopUV *mluv = dest; + float *uv= mluv->uv; int i; - float *sub_weight; - struct { - float u; - float v; - }uv; - uv.u = uv.v = 0.0; - sub_weight = sub_weights; - for(i = 0; i < count; ++i){ - float weight = weights ? weights[i] : 1; - MLoopUV *src = sources[i]; - if(sub_weights){ - uv.u += src->uv[0] * (*sub_weight) * weight; - uv.v += src->uv[1] * (*sub_weight) * weight; - sub_weight++; - } else { - uv.u += src->uv[0] * weight; - uv.v += src->uv[1] * weight; + zero_v2(uv); + + if (sub_weights) { + const float *sub_weight = sub_weights; + for(i = 0; i < count; i++) { + float weight = weights ? weights[i] : 1.0f; + MLoopUV *src = sources[i]; + madd_v2_v2fl(uv, src->uv, (*sub_weight) * weight); + sub_weight++; + } + } + else { + for(i = 0; i < count; i++) { + float weight = weights ? weights[i] : 1; + MLoopUV *src = sources[i]; + madd_v2_v2fl(uv, src->uv, weight); } } - mluv->uv[0] = uv.u; - mluv->uv[1] = uv.v; } static void layerInterp_mcol(void **sources, float *weights, @@ -734,12 +853,11 @@ float r; float g; float b; - } col[4]; + } col[4] = {{0.0f}}; + float *sub_weight; if(count <= 0) return; - - memset(col, 0, sizeof(col)); sub_weight = sub_weights; for(i = 0; i < count; ++i) { @@ -749,10 +867,11 @@ if(sub_weights) { MCol *src = sources[i]; for(k = 0; k < 4; ++k, ++sub_weight, ++src) { - col[j].a += src->a * (*sub_weight) * weight; - col[j].r += src->r * (*sub_weight) * weight; - col[j].g += src->g * (*sub_weight) * weight; - col[j].b += src->b * (*sub_weight) * weight; + const float w= (*sub_weight) * weight; + col[j].a += src->a * w; + col[j].r += src->r * w; + col[j].g += src->g * w; + col[j].b += src->b * w; } } else { MCol *src = sources[i]; @@ -798,11 +917,56 @@ MCol *mcol = (MCol*)data; int i; - for(i = 0; i < 4*count; i++) + for(i = 0; i < 4*count; i++) { mcol[i] = default_mcol; + } +} + +static void layerInterp_bweight(void **sources, float *weights, + float *UNUSED(sub_weights), int count, void *dest) +{ + float *f = dest; + float **in = (float **)sources; + int i; + + if(count <= 0) return; + + *f = 0.0f; + + if (weights) { + for(i = 0; i < count; ++i) { + *f += *in[i] * weights[i]; + } + } + else { + for(i = 0; i < count; ++i) { + *f += *in[i]; + } + } } +static void layerInterp_shapekey(void **sources, float *weights, + float *UNUSED(sub_weights), int count, void *dest) +{ + float *co = dest; + float **in = (float **)sources; + int i; + + if(count <= 0) return; + + zero_v3(co); + if (weights) { + for(i = 0; i < count; ++i) { + madd_v3_v3fl(co, in[i], weights[i]); + } + } + else { + for(i = 0; i < count; ++i) { + add_v3_v3(co, in[i]); + } + } +} static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { /* 0: CD_MVERT */ @@ -829,14 +993,14 @@ /* 8: CD_NORMAL */ /* 3 floats per normal vector */ {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, - /* 9: CD_FLAGS */ - {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, + /* 9: CD_POLYINDEX */ + {sizeof(int), "MIntProperty", 1, NULL, NULL, NULL, NULL, NULL, NULL}, /* 10: CD_PROP_FLT */ - {sizeof(MFloatProperty), "MFloatProperty",1,"Float",NULL,NULL,NULL,NULL}, + {sizeof(MFloatProperty), "MFloatProperty",1,"Float", layerCopy_propFloat,NULL,NULL,NULL}, /* 11: CD_PROP_INT */ - {sizeof(MIntProperty), "MIntProperty",1,"Int",NULL,NULL,NULL,NULL}, + {sizeof(MIntProperty), "MIntProperty",1,"Int",layerCopy_propInt,NULL,NULL,NULL}, /* 12: CD_PROP_STR */ - {sizeof(MStringProperty), "MStringProperty",1,"String",NULL,NULL,NULL,NULL}, + {sizeof(MStringProperty), "MStringProperty",1,"String",layerCopy_propString,NULL,NULL,NULL}, /* 13: CD_ORIGSPACE */ {sizeof(OrigSpaceFace), "OrigSpaceFace", 1, "UVMap", layerCopy_origspace_face, NULL, layerInterp_origspace_face, layerSwap_origspace_face, layerDefault_origspace_face}, @@ -845,15 +1009,20 @@ /* 15: CD_MTEXPOLY */ {sizeof(MTexPoly), "MTexPoly", 1, "Face Texture", NULL, NULL, NULL, NULL, NULL}, /* 16: CD_MLOOPUV */ - {sizeof(MLoopUV), "MLoopUV", 1, "UV coord", NULL, NULL, layerInterp_mloopuv, NULL, NULL}, + {sizeof(MLoopUV), "MLoopUV", 1, "UV coord", NULL, NULL, layerInterp_mloopuv, NULL, NULL, + layerEqual_mloopuv, layerMultiply_mloopuv, layerInitMinMax_mloopuv, + layerAdd_mloopuv, layerDoMinMax_mloopuv, layerCopyValue_mloopuv}, /* 17: CD_MLOOPCOL */ - {sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, layerDefault_mloopcol}, + {sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, + layerDefault_mloopcol, layerEqual_mloopcol, layerMultiply_mloopcol, layerInitMinMax_mloopcol, + layerAdd_mloopcol, layerDoMinMax_mloopcol, layerCopyValue_mloopcol}, /* 18: CD_TANGENT */ {sizeof(float)*4*4, "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, /* 19: CD_MDISPS */ {sizeof(MDisps), "MDisps", 1, NULL, layerCopy_mdisps, - layerFree_mdisps, layerInterp_mdisps, layerSwap_mdisps, NULL, layerRead_mdisps, layerWrite_mdisps, - layerFilesize_mdisps, layerValidate_mdisps}, + layerFree_mdisps, layerInterp_mdisps, layerSwap_mdisps, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + layerRead_mdisps, layerWrite_mdisps, layerFilesize_mdisps, layerValidate_mdisps}, /* 20: CD_WEIGHT_MCOL */ {sizeof(MCol)*4, "MCol", 4, "WeightCol", NULL, NULL, layerInterp_mcol, layerSwap_mcol, layerDefault_mcol}, @@ -867,6 +1036,30 @@ {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, /* 24: CD_RECAST */ {sizeof(MRecast), "MRecast", 1,"Recast",NULL,NULL,NULL,NULL} + +#ifdef USE_BMESH_FORWARD_COMPAT + , +/* BMESH ONLY */ + /* 25: CD_MPOLY */ + {sizeof(MPoly), "MPoly", 1, "NGon Face", NULL, NULL, NULL, NULL, NULL}, + /* 26: CD_MLOOP */ + {sizeof(MLoop), "MLoop", 1, "NGon Face-Vertex", NULL, NULL, NULL, NULL, NULL}, + /* 27: CD_SHAPE_KEYINDEX */ + {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, + /* 28: CD_SHAPEKEY */ + {sizeof(float)*3, "", 0, "ShapeKey", NULL, NULL, layerInterp_shapekey}, + /* 29: CD_BWEIGHT */ + {sizeof(float), "", 0, "BevelWeight", NULL, NULL, layerInterp_bweight}, + /* 30: CD_CREASE */ + {sizeof(float), "", 0, "SubSurfCrease", NULL, NULL, layerInterp_bweight}, + /* 31: CD_WEIGHT_MLOOPCOL */ + {sizeof(MLoopCol), "MLoopCol", 1, "WeightLoopCol", NULL, NULL, layerInterp_mloopcol, NULL, + layerDefault_mloopcol, layerEqual_mloopcol, layerMultiply_mloopcol, layerInitMinMax_mloopcol, + layerAdd_mloopcol, layerDoMinMax_mloopcol, layerCopyValue_mloopcol}, +/* END BMESH ONLY */ + +#endif /* USE_BMESH_FORWARD_COMPAT */ + }; static const char *LAYERTYPENAMES[CD_NUMTYPES] = { @@ -875,6 +1068,13 @@ /* 10-14 */ "CDMFloatProperty", "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco", /* 15-19 */ "CDMTexPoly", "CDMLoopUV", "CDMloopCol", "CDTangent", "CDMDisps", /* 20-24 */"CDWeightMCol", "CDIDMCol", "CDTextureMCol", "CDClothOrco", "CDMRecast" + +#ifdef USE_BMESH_FORWARD_COMPAT + , + /* 25-29 */ "CDMPoly", "CDMLoop", "CDShapeKeyIndex", "CDShapeKey", "CDBevelWeight", + /* 30-31 */ "CDSubSurfCrease", "CDWeightLoopCol" + +#endif /* USE_BMESH_FORWARD_COMPAT */ }; const CustomDataMask CD_MASK_BAREMESH = @@ -896,7 +1096,6 @@ CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL; - static const LayerTypeInfo *layerType_getInfo(int type) { if(type < 0 || type >= CD_NUMTYPES) return NULL; @@ -917,6 +1116,25 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data, int type, int alloctype, void *layerdata, int totelem, const char *name); +void CustomData_update_typemap(CustomData *data) +{ + int i, lasttype = -1; + + /* since we cant do in a pre-processor do here as an assert */ + BLI_assert(sizeof(data->typemap) / sizeof(int) >= CD_NUMTYPES); + + for (i=0; itypemap[i] = -1; + } + + for (i=0; itotlayer; i++) { + if (data->layers[i].type != lasttype) { + data->typemap[data->layers[i].type] = i; + } + lasttype = data->layers[i].type; + } +} + void CustomData_merge(const struct CustomData *source, struct CustomData *dest, CustomDataMask mask, int alloctype, int totelem) { @@ -943,7 +1161,7 @@ number++; if(lastflag & CD_FLAG_NOCOPY) continue; - else if(!((int)mask & (int)(1 << (int)type))) continue; + else if(!(mask & CD_TYPE_AS_MASK(type))) continue; else if(number < CustomData_number_of_layers(dest, type)) continue; if((alloctype == CD_ASSIGN) && (lastflag & CD_FLAG_NOFREE)) @@ -961,6 +1179,8 @@ newlayer->flag |= lastflag & (CD_FLAG_EXTERNAL|CD_FLAG_IN_MEMORY); } } + + CustomData_update_typemap(dest); } void CustomData_copy(const struct CustomData *source, struct CustomData *dest, @@ -1025,6 +1245,7 @@ } data->totsize = offset; + CustomData_update_typemap(data); } int CustomData_get_layer_index(const CustomData *data, int type) @@ -1038,6 +1259,17 @@ return -1; } +int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n) +{ + int i = CustomData_get_layer_index(data, type); + + if (i != -1) { + i = (data->layers[i + n].type == type) ? (i + n) : (-1); + } + + return i; +} + int CustomData_get_named_layer_index(const CustomData *data, int type, const char *name) { int i; @@ -1051,11 +1283,12 @@ int CustomData_get_active_layer_index(const CustomData *data, int type) { - int i; + if (!data->totlayer) + return -1; - for(i=0; i < data->totlayer; ++i) - if(data->layers[i].type == type) - return i + data->layers[i].active; + if (data->typemap[type] != -1) { + return data->typemap[type] + data->layers[data->typemap[type]].active; + } return -1; } @@ -1284,8 +1517,9 @@ data->layers[index].type = type; data->layers[index].flag = flag; data->layers[index].data = newlayerdata; + if(name || (name=typeInfo->defaultname)) { - BLI_strncpy(data->layers[index].name, name, 32); + BLI_strncpy(data->layers[index].name, name, sizeof(data->layers[index].name)); CustomData_set_layer_unique_name(data, index); } else @@ -1316,6 +1550,7 @@ layer = customData_add_layer__internal(data, type, alloctype, layerdata, totelem, typeInfo->defaultname); + CustomData_update_typemap(data); if(layer) return layer->data; @@ -1331,6 +1566,7 @@ layer = customData_add_layer__internal(data, type, alloctype, layerdata, totelem, name); + CustomData_update_typemap(data); if(layer) return layer->data; @@ -1369,6 +1605,7 @@ customData_resize(data, -CUSTOMDATA_GROW); customData_update_offsets(data); + CustomData_update_typemap(data); return 1; } @@ -1404,7 +1641,7 @@ return number; } -void *CustomData_duplicate_referenced_layer(struct CustomData *data, int type) +void *CustomData_duplicate_referenced_layer(struct CustomData *data, const int type, const int totelem) { CustomDataLayer *layer; int layer_index; @@ -1416,7 +1653,20 @@ layer = &data->layers[layer_index]; if (layer->flag & CD_FLAG_NOFREE) { - layer->data = MEM_dupallocN(layer->data); + /* MEM_dupallocN won’t work in case of complex layers, like e.g. + * CD_MDEFORMVERT, which has pointers to allocated data... + * So in case a custom copy function is defined, use it! + */ + const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type); + + if(typeInfo->copy) { + char *dest_data = MEM_mallocN(typeInfo->size * totelem, "CD duplicate ref layer"); + typeInfo->copy(layer->data, dest_data, totelem); + layer->data = dest_data; + } + else + layer->data = MEM_dupallocN(layer->data); + layer->flag &= ~CD_FLAG_NOFREE; } @@ -1424,7 +1674,7 @@ } void *CustomData_duplicate_referenced_layer_named(struct CustomData *data, - int type, const char *name) + const int type, const char *name, const int totelem) { CustomDataLayer *layer; int layer_index; @@ -1436,13 +1686,40 @@ layer = &data->layers[layer_index]; if (layer->flag & CD_FLAG_NOFREE) { - layer->data = MEM_dupallocN(layer->data); + /* MEM_dupallocN won’t work in case of complex layers, like e.g. + * CD_MDEFORMVERT, which has pointers to allocated data... + * So in case a custom copy function is defined, use it! + */ + const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type); + + if(typeInfo->copy) { + char *dest_data = MEM_mallocN(typeInfo->size * totelem, "CD duplicate ref layer"); + typeInfo->copy(layer->data, dest_data, totelem); + layer->data = dest_data; + } + else + layer->data = MEM_dupallocN(layer->data); + layer->flag &= ~CD_FLAG_NOFREE; } return layer->data; } +int CustomData_is_referenced_layer(struct CustomData *data, int type) +{ + CustomDataLayer *layer; + int layer_index; + + /* get the layer index of the first layer of type */ + layer_index = CustomData_get_active_layer_index(data, type); + if(layer_index < 0) return 0; + + layer = &data->layers[layer_index]; + + return (layer->flag & CD_FLAG_NOFREE) != 0; +} + void CustomData_free_temporary(CustomData *data, int totelem) { CustomDataLayer *layer; @@ -1469,15 +1746,25 @@ } void CustomData_set_only_copy(const struct CustomData *data, - CustomDataMask mask) + CustomDataMask mask) { int i; for(i = 0; i < data->totlayer; ++i) - if(!((int)mask & (int)(1 << (int)data->layers[i].type))) + if(!(mask & CD_TYPE_AS_MASK(data->layers[i].type))) data->layers[i].flag |= CD_FLAG_NOCOPY; } +void CustomData_copy_elements(int type, void *source, void *dest, int count) +{ + const LayerTypeInfo *typeInfo = layerType_getInfo(type); + + if (typeInfo->copy) + typeInfo->copy(source, dest, count); + else + memcpy(dest, source, typeInfo->size*count); +} + void CustomData_copy_data(const CustomData *source, CustomData *dest, int source_index, int dest_index, int count) { @@ -1509,7 +1796,14 @@ src_offset = source_index * typeInfo->size; dest_offset = dest_index * typeInfo->size; - + + if (!src_data || !dest_data) { + printf("%s: warning null data for %s type (%p --> %p), skipping\n", + __func__, layerType_getName(source->layers[src_i].type), + (void *)src_data, (void *)dest_data); + continue; + } + if(typeInfo->copy) typeInfo->copy(src_data + src_offset, dest_data + dest_offset, @@ -1637,6 +1931,19 @@ return (char *)data->layers[layer_index].data + offset; } +void *CustomData_get_n(const CustomData *data, int type, int index, int n) +{ + int layer_index; + int offset; + + /* get the layer index of the first layer of type */ + layer_index = data->typemap[type]; + if(layer_index < 0) return NULL; + + offset = layerType_getInfo(type)->size * index; + return (char *)data->layers[layer_index+n].data + offset; +} + void *CustomData_get_layer(const CustomData *data, int type) { /* get the layer index of the active layer of type */ @@ -1649,10 +1956,10 @@ void *CustomData_get_layer_n(const CustomData *data, int type, int n) { /* get the layer index of the active layer of type */ - int layer_index = CustomData_get_layer_index(data, type); + int layer_index = CustomData_get_layer_index_n(data, type, n); if(layer_index < 0) return NULL; - return data->layers[layer_index+n].data; + return data->layers[layer_index].data; } void *CustomData_get_layer_named(const struct CustomData *data, int type, @@ -1664,6 +1971,20 @@ return data->layers[layer_index].data; } + +int CustomData_set_layer_name(const CustomData *data, int type, int n, const char *name) +{ + /* get the layer index of the first layer of type */ + int layer_index = CustomData_get_layer_index_n(data, type, n); + + if(layer_index < 0) return 0; + if (!name) return 0; + + strcpy(data->layers[layer_index].name, name); + + return 1; +} + void *CustomData_set_layer(const CustomData *data, int type, void *ptr) { /* get the layer index of the first layer of type */ @@ -1679,10 +2000,10 @@ void *CustomData_set_layer_n(const struct CustomData *data, int type, int n, void *ptr) { /* get the layer index of the first layer of type */ - int layer_index = CustomData_get_layer_index(data, type); + int layer_index = CustomData_get_layer_index_n(data, type, n); if(layer_index < 0) return NULL; - data->layers[layer_index+n].data = ptr; + data->layers[layer_index].data = ptr; return ptr; } @@ -1810,10 +2131,10 @@ int layer_index; /* get the layer index of the first layer of type */ - layer_index = CustomData_get_layer_index(data, type); + layer_index = CustomData_get_layer_index_n(data, type, n); if(layer_index < 0) return NULL; - return (char *)block + data->layers[layer_index+n].offset; + return (char *)block + data->layers[layer_index].offset; } void CustomData_em_set(CustomData *data, void *block, int type, void *source) @@ -1995,7 +2316,8 @@ CustomData_add_layer(ldata, CD_MLOOPCOL, CD_CALLOC, &(fdata->layers[i].name), 0); } } -void CustomData_from_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata, int total){ +void CustomData_from_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata, int total) +{ int i; for(i=0; i < pdata->totlayer; i++){ if(pdata->layers[i].type == CD_MTEXPOLY) @@ -2008,7 +2330,8 @@ } -void CustomData_bmesh_init_pool(CustomData *data, int allocsize){ +void CustomData_bmesh_init_pool(CustomData *data, int allocsize) +{ if(data->totlayer)data->pool = BLI_mempool_create(data->totsize, allocsize, allocsize, FALSE, FALSE); } @@ -2113,6 +2436,15 @@ return (char *)block + data->layers[layer_index+n].offset; } +/*gets from the layer at physical index n, note: doesn't check type.*/ +void *CustomData_bmesh_get_layer_n(const CustomData *data, void *block, int n) +{ + if(n < 0 || n >= data->totlayer) return NULL; + + return (char *)block + data->layers[n].offset; +} + + void CustomData_bmesh_set(const CustomData *data, void *block, int type, void *source) { void *dest = CustomData_bmesh_get(data, block, type); @@ -2139,6 +2471,19 @@ memcpy(dest, source, typeInfo->size); } +void CustomData_bmesh_set_layer_n(CustomData *data, void *block, int n, void *source) +{ + void *dest = CustomData_bmesh_get_layer_n(data, block, n); + const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[n].type); + + if(!dest) return; + + if(typeInfo->copy) + typeInfo->copy(source, dest, 1); + else + memcpy(dest, source, typeInfo->size); +} + void CustomData_bmesh_interp(CustomData *data, void **src_blocks, float *weights, float *sub_weights, int count, void *dest_block) { @@ -2184,6 +2529,7 @@ if(typeInfo->set_default) typeInfo->set_default((char*)*block + offset, 1); + else memset((char*)*block + offset, 0, typeInfo->size); } } @@ -2413,7 +2759,7 @@ layer = &data->layers[i]; typeInfo = layerType_getInfo(layer->type); - if(!(mask & (1<type))); + if(!(mask & CD_TYPE_AS_MASK(layer->type))); else if((layer->flag & CD_FLAG_EXTERNAL) && (layer->flag & CD_FLAG_IN_MEMORY)) { if(typeInfo->free) typeInfo->free(layer->data, totelem, typeInfo->size); @@ -2439,7 +2785,7 @@ layer = &data->layers[i]; typeInfo = layerType_getInfo(layer->type); - if(!(mask & (1<type))); + if(!(mask & CD_TYPE_AS_MASK(layer->type))); else if(layer->flag & CD_FLAG_IN_MEMORY); else if((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read) update= 1; @@ -2460,7 +2806,7 @@ layer = &data->layers[i]; typeInfo = layerType_getInfo(layer->type); - if(!(mask & (1<type))); + if(!(mask & CD_TYPE_AS_MASK(layer->type))); else if(layer->flag & CD_FLAG_IN_MEMORY); else if((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read) { blay= cdf_layer_find(cdf, layer->type, layer->name); @@ -2499,7 +2845,7 @@ layer = &data->layers[i]; typeInfo = layerType_getInfo(layer->type); - if(!(mask & (1<type))); + if(!(mask & CD_TYPE_AS_MASK(layer->type))); else if((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) update= 1; } @@ -2613,7 +2959,7 @@ if(layer->flag & CD_FLAG_EXTERNAL) { if(!(layer->flag & CD_FLAG_IN_MEMORY)) - CustomData_external_read(data, id, (1<type), totelem); + CustomData_external_read(data, id, CD_TYPE_AS_MASK(layer->type), totelem); layer->flag &= ~CD_FLAG_EXTERNAL; diff -Nru blender-2.61/source/blender/blenkernel/intern/deform.c blender-2.62/source/blender/blenkernel/intern/deform.c --- blender-2.61/source/blender/blenkernel/intern/deform.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/deform.c 2012-02-15 19:34:02.000000000 +0000 @@ -163,33 +163,85 @@ /* be sure all flip_map values are valid */ void defvert_remap(MDeformVert *dvert, int *map, const int map_len) { - MDeformWeight *dw; - int i; - for (i=0, dw=dvert->dw; itotweight; i++, dw++) { + MDeformWeight *dw= dvert->dw; + unsigned int i; + for (i= dvert->totweight; i != 0; i--, dw++) { if (dw->def_nr < map_len) { dw->def_nr= map[dw->def_nr]; + + /* just incase */ + BLI_assert(dw->def_nr >= 0); } } } void defvert_normalize(MDeformVert *dvert) { - if (dvert->totweight<=0) { + if (dvert->totweight <= 0) { + /* nothing */ + } + else if (dvert->totweight==1) { + dvert->dw[0].weight= 1.0f; + } + else { + MDeformWeight *dw; + unsigned int i; + float tot_weight= 0.0f; + + for (i= dvert->totweight, dw= dvert->dw; i != 0; i--, dw++) { + tot_weight += dw->weight; + } + + if (tot_weight > 0.0f) { + float scalar= 1.0f / tot_weight; + for (i= dvert->totweight, dw= dvert->dw; i != 0; i--, dw++) { + dw->weight *= scalar; + + /* incase of division errors with very low weights */ + CLAMP(dw->weight, 0.0f, 1.0f); + } + } + } +} + +void defvert_normalize_lock(MDeformVert *dvert, const int def_nr_lock) +{ + if (dvert->totweight <= 0) { /* nothing */ } else if (dvert->totweight==1) { dvert->dw[0].weight= 1.0f; } else { - int i; - float tot= 0.0f; + MDeformWeight *dw_lock = NULL; MDeformWeight *dw; - for (i=0, dw=dvert->dw; i < dvert->totweight; i++, dw++) - tot += dw->weight; + unsigned int i; + float tot_weight= 0.0f; + float lock_iweight= 1.0f; + + for (i= dvert->totweight, dw= dvert->dw; i != 0; i--, dw++) { + if(dw->def_nr != def_nr_lock) { + tot_weight += dw->weight; + } + else { + dw_lock= dw; + lock_iweight = (1.0f - dw_lock->weight); + CLAMP(lock_iweight, 0.0f, 1.0f); + } + } + + if (tot_weight > 0.0f) { + /* paranoid, should be 1.0 but incase of float error clamp anyway */ - if (tot > 0.0f) { - for (i=0, dw=dvert->dw; i < dvert->totweight; i++, dw++) - dw->weight /= tot; + float scalar= (1.0f / tot_weight) * lock_iweight; + for (i= dvert->totweight, dw= dvert->dw; i != 0; i--, dw++) { + if(dw != dw_lock) { + dw->weight *= scalar; + + /* incase of division errors with very low weights */ + CLAMP(dw->weight, 0.0f, 1.0f); + } + } } } } @@ -227,7 +279,7 @@ int defgroup_name_index(Object *ob, const char *name) { /* Return the location of the named deform group within the list of - * deform groups. This function is a combination of defgroup_find_index and + * deform groups. This function is a combination of BLI_findlink and * defgroup_find_name. The other two could be called instead, but that * require looping over the vertexgroups twice. */ @@ -244,46 +296,6 @@ return -1; } -int defgroup_find_index(Object *ob, bDeformGroup *dg) -{ - /* Fetch the location of this deform group - * within the linked list of deform groups. - * (this number is stored in the deform - * weights of the deform verts to link them - * to this deform group). - * - * note: this is zero based, ob->actdef starts at 1. - */ - - bDeformGroup *eg; - int def_nr; - - eg = ob->defbase.first; - def_nr = 0; - - /* loop through all deform groups */ - while (eg != NULL) { - - /* if the current deform group is - * the one we are after, return - * def_nr - */ - if (eg == dg) { - break; - } - ++def_nr; - eg = eg->next; - } - - /* if there was no deform group found then - * return -1 (should set up a nice symbolic - * constant for this) - */ - if (eg == NULL) return -1; - - return def_nr; -} - /* note, must be freed */ int *defgroup_flip_map(Object *ob, int *flip_map_len, int use_default) { @@ -464,22 +476,22 @@ switch(name[0]) { case 'l': strcpy(replace, "r"); - strcpy(suffix, name+1); + BLI_strncpy(suffix, name+1, sizeof(suffix)); prefix[0]= 0; break; case 'r': strcpy(replace, "l"); - strcpy(suffix, name+1); + BLI_strncpy(suffix, name+1, sizeof(suffix)); prefix[0]= 0; break; case 'L': strcpy(replace, "R"); - strcpy(suffix, name+1); + BLI_strncpy(suffix, name+1, sizeof(suffix)); prefix[0]= 0; break; case 'R': strcpy(replace, "L"); - strcpy(suffix, name+1); + BLI_strncpy(suffix, name+1, sizeof(suffix)); prefix[0]= 0; break; } @@ -489,29 +501,29 @@ index = BLI_strcasestr(prefix, "right"); if (index==prefix || index==prefix+len-5) { if (index[0]=='r') - strcpy (replace, "left"); + strcpy(replace, "left"); else { if (index[1]=='I') - strcpy (replace, "LEFT"); + strcpy(replace, "LEFT"); else - strcpy (replace, "Left"); + strcpy(replace, "Left"); } *index= 0; - strcpy (suffix, index+5); + BLI_strncpy(suffix, index+5, sizeof(suffix)); } else { index = BLI_strcasestr(prefix, "left"); if (index==prefix || index==prefix+len-4) { if (index[0]=='l') - strcpy (replace, "right"); + strcpy(replace, "right"); else { if (index[1]=='E') - strcpy (replace, "RIGHT"); + strcpy(replace, "RIGHT"); else - strcpy (replace, "Right"); + strcpy(replace, "Right"); } *index= 0; - strcpy (suffix, index+4); + BLI_strncpy(suffix, index + 4, sizeof(suffix)); } } } @@ -527,6 +539,12 @@ return dw ? dw->weight : 0.0f; } +/* take care with this the rationale is: + * - if the object has no vertex group. act like vertex group isnt set and return 1.0, + * - if the vertex group exists but the 'defgroup' isnt found on this vertex, _still_ return 0.0 + * + * This is a bit confusing, just saves some checks from the caller. + */ float defvert_array_find_weight_safe(const struct MDeformVert *dvert, const int index, const int defgroup) { if (defgroup == -1 || dvert == NULL) @@ -540,9 +558,9 @@ { if (dvert && defgroup >= 0) { MDeformWeight *dw = dvert->dw; - int i; + unsigned int i; - for (i=dvert->totweight; i>0; i--, dw++) { + for (i= dvert->totweight; i != 0; i--, dw++) { if (dw->def_nr == defgroup) { return dw; } @@ -626,9 +644,16 @@ */ if (dvert->totweight) { dw_new = MEM_mallocN(sizeof(MDeformWeight)*(dvert->totweight), __func__); - if (dvert->dw){ + if (dvert->dw) { +#if 1 /* since we dont care about order, swap this with the last, save a memcpy */ + if (i != dvert->totweight) { + dvert->dw[i]= dvert->dw[dvert->totweight]; + } + memcpy(dw_new, dvert->dw, sizeof(MDeformWeight) * dvert->totweight); +#else memcpy(dw_new, dvert->dw, sizeof(MDeformWeight)*i); memcpy(dw_new+i, dvert->dw+i+1, sizeof(MDeformWeight)*(dvert->totweight-i)); +#endif MEM_freeN(dvert->dw); } dvert->dw = dw_new; diff -Nru blender-2.61/source/blender/blenkernel/intern/depsgraph.c blender-2.62/source/blender/blenkernel/intern/depsgraph.c --- blender-2.61/source/blender/blenkernel/intern/depsgraph.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/depsgraph.c 2012-02-15 19:34:02.000000000 +0000 @@ -269,7 +269,8 @@ } } -void *pop_ob_queue(struct DagNodeQueue *queue) { +void *pop_ob_queue(struct DagNodeQueue *queue) +{ return(pop_queue(queue)->ob); } @@ -278,7 +279,8 @@ return queue->first->node; } -int queue_count(struct DagNodeQueue *queue){ +int queue_count(struct DagNodeQueue *queue) +{ return queue->count; } @@ -396,8 +398,11 @@ // fprintf(stderr,"armature %s target :%s \n", ob->id.name, target->id.name); node3 = dag_get_node(dag, ct->tar); - if (ct->subtarget[0]) + if (ct->subtarget[0]) { dag_add_relation(dag,node3,node, DAG_RL_OB_DATA|DAG_RL_DATA_DATA, cti->name); + if(ct->tar->type == OB_MESH) + node3->customdata_mask |= CD_MASK_MDEFORMVERT; + } else if(ELEM3(con->type, CONSTRAINT_TYPE_FOLLOWPATH, CONSTRAINT_TYPE_CLAMPTO, CONSTRAINT_TYPE_SPLINEIK)) dag_add_relation(dag,node3,node, DAG_RL_DATA_DATA|DAG_RL_OB_DATA, cti->name); else @@ -537,6 +542,7 @@ } break; case OB_CURVE: + case OB_FONT: { Curve *cu= ob->data; @@ -548,15 +554,11 @@ node2 = dag_get_node(dag, cu->taperobj); dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_DATA, "Curve Taper"); } - } - break; - case OB_FONT: - { - Curve *cu= ob->data; - - if(cu->textoncurve) { - node2 = dag_get_node(dag, cu->textoncurve); - dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_DATA, "Texture On Curve"); + if(ob->type == OB_FONT) { + if(cu->textoncurve) { + node2 = dag_get_node(dag, cu->textoncurve); + dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_DATA, "Texture On Curve"); + } } } break; @@ -647,17 +649,27 @@ continue; /* special case for camera tracking -- it doesn't use targets to define relations */ - if(ELEM(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER)) { + if(ELEM3(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER, CONSTRAINT_TYPE_OBJECTSOLVER)) { + int depends_on_camera= 0; + if(cti->type==CONSTRAINT_TYPE_FOLLOWTRACK) { bFollowTrackConstraint *data= (bFollowTrackConstraint *)con->data; - if((data->clip || data->flag&FOLLOWTRACK_ACTIVECLIP) && data->track[0]) { - if(scene->camera) { - node2 = dag_get_node(dag, scene->camera); - dag_add_relation(dag, node2, node, DAG_RL_DATA_OB|DAG_RL_OB_OB, cti->name); - } + if((data->clip || data->flag&FOLLOWTRACK_ACTIVECLIP) && data->track[0]) + depends_on_camera= 1; + + if(data->depth_ob) { + node2 = dag_get_node(dag, data->depth_ob); + dag_add_relation(dag, node2, node, DAG_RL_DATA_OB|DAG_RL_OB_OB, cti->name); } } + else if(cti->type==CONSTRAINT_TYPE_OBJECTSOLVER) + depends_on_camera= 1; + + if(depends_on_camera && scene->camera) { + node2 = dag_get_node(dag, scene->camera); + dag_add_relation(dag, node2, node, DAG_RL_DATA_OB|DAG_RL_OB_OB, cti->name); + } dag_add_relation(dag,scenenode,node,DAG_RL_SCENE, "Scene Relation"); addtoroot = 0; @@ -1155,7 +1167,8 @@ queue_delete(nqueue); } -int pre_and_post_BFS(DagForest *dag, short mask, graph_action_func pre_func, graph_action_func post_func, void **data) { +int pre_and_post_BFS(DagForest *dag, short mask, graph_action_func pre_func, graph_action_func post_func, void **data) +{ DagNode *node; node = dag->DagNode.first; @@ -1341,7 +1354,8 @@ } /* unused */ -int pre_and_post_DFS(DagForest *dag, short mask, graph_action_func pre_func, graph_action_func post_func, void **data) { +int pre_and_post_DFS(DagForest *dag, short mask, graph_action_func pre_func, graph_action_func post_func, void **data) +{ DagNode *node; node = dag->DagNode.first; @@ -1552,7 +1566,8 @@ } /* unused */ -short are_obs_related(struct DagForest *dag, void *ob1, void *ob2) { +short are_obs_related(struct DagForest *dag, void *ob1, void *ob2) +{ DagNode * node; DagAdjList *itA; @@ -1568,7 +1583,8 @@ return DAG_NO_RELATION; } -int is_acyclic( DagForest *dag) { +int is_acyclic( DagForest *dag) +{ return dag->is_acyclic; } @@ -1704,7 +1720,7 @@ /* sort the base list on dependency order */ void DAG_scene_sort(Main *bmain, Scene *sce) { - DagNode *node; + DagNode *node, *rootnode; DagNodeQueue *nqueue; DagAdjList *itA; int time; @@ -1726,11 +1742,10 @@ time = 1; - node = sce->theDag->DagNode.first; - - node->color = DAG_GRAY; + rootnode = sce->theDag->DagNode.first; + rootnode->color = DAG_GRAY; time++; - push_stack(nqueue,node); + push_stack(nqueue,rootnode); while(nqueue->count) { @@ -2160,7 +2175,7 @@ if (cti) { /* special case for camera tracking -- it doesn't use targets to define relations */ - if(ELEM(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER)) { + if(ELEM3(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER, CONSTRAINT_TYPE_OBJECTSOLVER)) { ob->recalc |= OB_RECALC_OB; } else if (cti->get_constraint_targets) { @@ -2554,7 +2569,9 @@ bConstraint *con; for (con = obt->constraints.first; con; con=con->next) { bConstraintTypeInfo *cti= constraint_get_typeinfo(con); - if(ELEM(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER)) { + if(ELEM3(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER, + CONSTRAINT_TYPE_OBJECTSOLVER)) + { obt->recalc |= OB_RECALC_OB; break; } @@ -2848,10 +2865,8 @@ for(node = dag->DagNode.first; node; node= node->next) node->color = DAG_WHITE; - node = dag->DagNode.first; - - node->color = DAG_GRAY; - push_stack(nqueue, node); + rootnode->color = DAG_GRAY; + push_stack(nqueue, rootnode); while(nqueue->count) { diff -Nru blender-2.61/source/blender/blenkernel/intern/DerivedMesh.c blender-2.62/source/blender/blenkernel/intern/DerivedMesh.c --- blender-2.61/source/blender/blenkernel/intern/DerivedMesh.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/DerivedMesh.c 2012-02-15 19:34:02.000000000 +0000 @@ -642,67 +642,71 @@ CALC_WP_AUTO_NORMALIZE= (1<<1) }; +static void weightpaint_color(unsigned char r_col[4], ColorBand *coba, const float input) +{ + float colf[4]; + + if(coba) do_colorband(coba, input, colf); + else weight_to_rgb(colf, input); + + r_col[3] = (unsigned char)(colf[0] * 255.0f); + r_col[2] = (unsigned char)(colf[1] * 255.0f); + r_col[1] = (unsigned char)(colf[2] * 255.0f); + r_col[0] = 255; +} + + static void calc_weightpaint_vert_color( - Object *ob, const int defbase_tot, ColorBand *coba, int vert, unsigned char *col, - const char *dg_flags, int selected, int UNUSED(unselected), const int draw_flag) + unsigned char r_col[4], + MDeformVert *dv, ColorBand *coba, + const int defbase_tot, const int defbase_act, + const char *dg_flags, + const int selected, const int draw_flag) { - Mesh *me = ob->data; float input = 0.0f; int make_black= FALSE; - if (me->dvert) { - MDeformVert *dvert= &me->dvert[vert]; - - if ((selected > 1) && (draw_flag & CALC_WP_MULTIPAINT)) { - int was_a_nonzero= FALSE; - int i; - - MDeformWeight *dw= dvert->dw; - for (i = dvert->totweight; i > 0; i--, dw++) { - /* in multipaint, get the average if auto normalize is inactive - * get the sum if it is active */ - if (dw->def_nr < defbase_tot) { - if (dg_flags[dw->def_nr]) { - if (dw->weight) { - input += dw->weight; - was_a_nonzero= TRUE; - } + if ((selected > 1) && (draw_flag & CALC_WP_MULTIPAINT)) { + int was_a_nonzero= FALSE; + unsigned int i; + + MDeformWeight *dw= dv->dw; + for (i = dv->totweight; i != 0; i--, dw++) { + /* in multipaint, get the average if auto normalize is inactive + * get the sum if it is active */ + if (dw->def_nr < defbase_tot) { + if (dg_flags[dw->def_nr]) { + if (dw->weight) { + input += dw->weight; + was_a_nonzero= TRUE; } } } + } - /* make it black if the selected groups have no weight on a vertex */ - if (was_a_nonzero == FALSE) { - make_black = TRUE; - } - else if ((draw_flag & CALC_WP_AUTO_NORMALIZE) == FALSE) { - input /= selected; /* get the average */ - } + /* make it black if the selected groups have no weight on a vertex */ + if (was_a_nonzero == FALSE) { + make_black = TRUE; } - else { - /* default, non tricky behavior */ - input= defvert_find_weight(dvert, ob->actdef-1); + else if ((draw_flag & CALC_WP_AUTO_NORMALIZE) == FALSE) { + input /= selected; /* get the average */ } } - - if (make_black) { - col[3] = 0; - col[2] = 0; - col[1] = 0; - col[0] = 255; + else { + /* default, non tricky behavior */ + input= defvert_find_weight(dv, defbase_act); + } + + if (make_black) { /* TODO, theme color */ + r_col[3] = 0; + r_col[2] = 0; + r_col[1] = 0; + r_col[0] = 255; } else { - float colf[4]; CLAMP(input, 0.0f, 1.0f); - - if(coba) do_colorband(coba, input, colf); - else weight_to_rgb(colf, input); - - col[3] = (unsigned char)(colf[0] * 255.0f); - col[2] = (unsigned char)(colf[1] * 255.0f); - col[1] = (unsigned char)(colf[2] * 255.0f); - col[0] = 255; + weightpaint_color(r_col, coba, input); } } @@ -713,33 +717,124 @@ stored_cb= coba; } -static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm, int const draw_flag) +/* return an array of vertex weight colors, caller must free. + * + * note that we could save some memory and allocate RGB only but then we'd need to + * re-arrange the colors when copying to the face since MCol has odd ordering, + * so leave this as is - campbell */ +static unsigned char *calc_weightpaint_vert_array(Object *ob, DerivedMesh *dm, int const draw_flag, ColorBand *coba) +{ + MDeformVert *dv = DM_get_vert_data_layer(dm, CD_MDEFORMVERT); + int numVerts = dm->getNumVerts(dm); + unsigned char *wtcol_v = MEM_mallocN (sizeof(unsigned char) * numVerts * 4, "weightmap_v"); + + if (dv) { + unsigned char *wc = wtcol_v; + unsigned int i; + + /* variables for multipaint */ + const int defbase_tot = BLI_countlist(&ob->defbase); + const int defbase_act = ob->actdef-1; + char *dg_flags = MEM_mallocN(defbase_tot * sizeof(char), __func__); + const int selected = get_selected_defgroups(ob, dg_flags, defbase_tot); + + for (i = numVerts; i != 0; i--, wc += 4, dv++) { + calc_weightpaint_vert_color(wc, dv, coba, defbase_tot, defbase_act, dg_flags, selected, draw_flag); + } + + MEM_freeN(dg_flags); + } + else { + int col_i; + weightpaint_color((unsigned char *)&col_i, coba, 0.0f); + fill_vn_i((int *)wtcol_v, numVerts, col_i); + } + + return wtcol_v; +} + +/* return an array of vertex weight colors from given weights, caller must free. + * + * note that we could save some memory and allocate RGB only but then we'd need to + * re-arrange the colors when copying to the face since MCol has odd ordering, + * so leave this as is - campbell */ +static unsigned char *calc_colors_from_weights_array(const int num, float *weights) +{ + unsigned char *wtcol_v = MEM_mallocN(sizeof(unsigned char) * num * 4, "weightmap_v"); + unsigned char *wc = wtcol_v; + int i; + + for (i = 0; i < num; i++, wc += 4, weights++) + weightpaint_color((unsigned char *) wc, NULL, *weights); + + return wtcol_v; +} + +void DM_update_weight_mcol(Object *ob, DerivedMesh *dm, int const draw_flag, + float *weights, int num, const int *indices) { - Mesh *me = ob->data; - MFace *mf = me->mface; ColorBand *coba= stored_cb; /* warning, not a local var */ - unsigned char *wtcol; + + MFace *mf = dm->getFaceArray(dm); + int numFaces = dm->getNumFaces(dm); + int numVerts = dm->getNumVerts(dm); + unsigned char *wtcol_v; + unsigned char *wtcol_f = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL); int i; - - int defbase_tot = BLI_countlist(&ob->defbase); - char *defbase_sel = MEM_mallocN(defbase_tot * sizeof(char), __func__); - int selected = get_selected_defgroups(ob, defbase_sel, defbase_tot); - int unselected = defbase_tot - selected; - wtcol = MEM_callocN (sizeof (unsigned char) * me->totface*4*4, "weightmap"); - - memset(wtcol, 0x55, sizeof (unsigned char) * me->totface*4*4); - for (i=0; itotface; i++, mf++) { - calc_weightpaint_vert_color(ob, defbase_tot, coba, mf->v1, &wtcol[(i*4 + 0)*4], defbase_sel, selected, unselected, draw_flag); - calc_weightpaint_vert_color(ob, defbase_tot, coba, mf->v2, &wtcol[(i*4 + 1)*4], defbase_sel, selected, unselected, draw_flag); - calc_weightpaint_vert_color(ob, defbase_tot, coba, mf->v3, &wtcol[(i*4 + 2)*4], defbase_sel, selected, unselected, draw_flag); - if (mf->v4) - calc_weightpaint_vert_color(ob, defbase_tot, coba, mf->v4, &wtcol[(i*4 + 3)*4], defbase_sel, selected, unselected, draw_flag); - } - - MEM_freeN(defbase_sel); + /* If no CD_WEIGHT_MCOL existed yet, add a new one! */ + if (!wtcol_f) + wtcol_f = CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_CALLOC, NULL, numFaces); + + if (wtcol_f) { + unsigned char *wtcol_f_step = wtcol_f; + + /* Weights are given by caller. */ + if (weights) { + float *w = weights; + /* If indices is not NULL, it means we do not have weights for all vertices, + * so we must create them (and set them to zero)... */ + if(indices) { + w = MEM_callocN(sizeof(float)*numVerts, "Temp weight array DM_update_weight_mcol"); + i = num; + while(i--) + w[indices[i]] = weights[i]; + } + + /* Convert float weights to colors. */ + wtcol_v = calc_colors_from_weights_array(numVerts, w); + + if(indices) + MEM_freeN(w); + } - CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_ASSIGN, wtcol, dm->numFaceData); + /* No weights given, take them from active vgroup(s). */ + else + wtcol_v = calc_weightpaint_vert_array(ob, dm, draw_flag, coba); + + /* Now copy colors in all face verts. */ + for (i = 0; i < numFaces; i++, mf++, wtcol_f_step += (4 * 4)) { +#if 0 + unsigned int fidx= mf->v4 ? 3:2; + +#else /* better zero out triangles 4th component. else valgrind complains when the buffer's copied */ + unsigned int fidx; + if (mf->v4) { + fidx = 3; + } + else { + fidx = 2; + *(int *)(&wtcol_f_step[3 * 4]) = 0; + } +#endif + + do { + copy_v4_v4_char((char *)&wtcol_f_step[fidx * 4], + (char *)&wtcol_v[4 * (*(&mf->v1 + fidx))]); + } while (fidx--); + } + MEM_freeN(wtcol_v); + } } /* new value for useDeform -1 (hack for the gameengine): @@ -753,7 +848,7 @@ int needMapping, CustomDataMask dataMask, int index, int useCache) { Mesh *me = ob->data; - ModifierData *firstmd, *md; + ModifierData *firstmd, *md, *previewmd = NULL; LinkNode *datamasks, *curr; CustomDataMask mask, nextmask, append_mask = 0; float (*deformedVerts)[3] = NULL; @@ -766,8 +861,17 @@ int has_multires = mmd != NULL, multires_applied = 0; int sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt; - int draw_flag= ((scene->toolsettings->multipaint ? CALC_WP_MULTIPAINT : 0) | - (scene->toolsettings->auto_normalize ? CALC_WP_AUTO_NORMALIZE : 0)); + const int draw_flag= ((scene->toolsettings->multipaint ? CALC_WP_MULTIPAINT : 0) | + (scene->toolsettings->auto_normalize ? CALC_WP_AUTO_NORMALIZE : 0)); + /* Generic preview only in object mode! */ + const int do_mod_mcol = (ob->mode == OB_MODE_OBJECT); +#if 0 /* XXX Will re-enable this when we have global mod stack options. */ + const int do_final_wmcol = (scene->toolsettings->weights_preview == WP_WPREVIEW_FINAL) && do_wmcol; +#endif + const int do_final_wmcol = FALSE; + int do_init_wmcol = ((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT) && !do_final_wmcol); + /* XXX Same as above... For now, only weights preview in WPaint mode. */ + const int do_mod_wmcol = do_init_wmcol; if(mmd && !mmd->sculptlvl) has_multires = 0; @@ -792,6 +896,14 @@ datamasks = modifiers_calcDataMasks(scene, ob, md, dataMask, required_mode); curr = datamasks; + if(do_mod_wmcol || do_mod_mcol) { + /* Find the last active modifier generating a preview, or NULL if none. */ + /* XXX Currently, DPaint modifier just ignores this. + * Needs a stupid hack... + * The whole "modifier preview" thing has to be (re?)designed, anyway! */ + previewmd = modifiers_getLastPreview(scene, md, required_mode); + } + if(deform_r) *deform_r = NULL; *final_r = NULL; @@ -947,8 +1059,8 @@ CDDM_calc_normals(dm); } - if((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT)) - add_weight_mcol_dm(ob, dm, draw_flag); + if(do_init_wmcol) + DM_update_weight_mcol(ob, dm, draw_flag, NULL, 0, NULL); /* Constructive modifiers need to have an origindex * otherwise they wont have anywhere to copy the data from. @@ -1035,8 +1147,14 @@ } /* in case of dynamic paint, make sure preview mask remains for following modifiers */ + /* XXX Temp and hackish solution! */ if (md->type == eModifierType_DynamicPaint) append_mask |= CD_MASK_WEIGHT_MCOL; + /* In case of active preview modifier, make sure preview mask remains for following modifiers. */ + else if ((md == previewmd) && (do_mod_wmcol)) { + DM_update_weight_mcol(ob, dm, draw_flag, NULL, 0, NULL); + append_mask |= CD_MASK_WEIGHT_MCOL; + } } isPrevDeform= (mti->type == eModifierTypeType_OnlyDeform); @@ -1064,10 +1182,19 @@ CDDM_apply_vert_coords(finaldm, deformedVerts); CDDM_calc_normals(finaldm); - if((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT)) - add_weight_mcol_dm(ob, finaldm, draw_flag); +#if 0 /* For later nice mod preview! */ + /* In case we need modified weights in CD_WEIGHT_MCOL, we have to re-compute it. */ + if(do_final_wmcol) + DM_update_weight_mcol(ob, finaldm, draw_flag, NULL, 0, NULL); +#endif } else if(dm) { finaldm = dm; + +#if 0 /* For later nice mod preview! */ + /* In case we need modified weights in CD_WEIGHT_MCOL, we have to re-compute it. */ + if(do_final_wmcol) + DM_update_weight_mcol(ob, finaldm, draw_flag, NULL, 0, NULL); +#endif } else { finaldm = CDDM_from_mesh(me, ob); @@ -1076,8 +1203,9 @@ CDDM_calc_normals(finaldm); } - if((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT)) - add_weight_mcol_dm(ob, finaldm, draw_flag); + /* In this case, we should never have weight-modifying modifiers in stack... */ + if(do_init_wmcol) + DM_update_weight_mcol(ob, finaldm, draw_flag, NULL, 0, NULL); } /* add an orco layer if needed */ @@ -2006,13 +2134,8 @@ tfdata = fdata; /* calc auto bump scale if necessary */ -#if 0 if(dm->auto_bump_scale<=0.0f) DM_calc_auto_bump_scale(dm); -#else - dm->auto_bump_scale = 1.0f; // will revert this after release -#endif - /* add a tangent layer if necessary */ for(b = 0; b < gattribs->totlayer; b++) @@ -2268,3 +2391,79 @@ #endif /* WITH_GAMEENGINE */ /* --- NAVMESH (end) --- */ + + +/* derivedmesh info printing function, + * to help track down differences DM output */ + +#ifndef NDEBUG +#include "BLI_dynstr.h" + +static void dm_debug_info_layers(DynStr *dynstr, DerivedMesh *dm, void *(*getElemDataArray)(DerivedMesh *, int)) +{ + int type; + + for (type = 0; type < CD_NUMTYPES; type++) { + /* note: doesnt account for multiple layers */ + void *pt = getElemDataArray(dm, type); + if (pt) { + const char *name = CustomData_layertype_name(type); + const int size = CustomData_sizeof(type); + const char *structname; + int structnum; + CustomData_file_write_info(type, &structname, &structnum); + BLI_dynstr_appendf(dynstr, + " dict(name='%s', struct='%s', type=%d, ptr='%p', elem=%d, length=%d),\n", + name, structname, type, (void *)pt, size, (int)(MEM_allocN_len(pt) / size)); + } + } +} + +char *DM_debug_info(DerivedMesh *dm) +{ + DynStr *dynstr= BLI_dynstr_new(); + char *ret; + const char *tstr; + + BLI_dynstr_appendf(dynstr, "{\n"); + BLI_dynstr_appendf(dynstr, " 'ptr': '%p',\n", (void *)dm); + switch (dm->type) { + case DM_TYPE_CDDM: tstr = "DM_TYPE_CDDM"; break; + case DM_TYPE_EDITMESH: tstr = "DM_TYPE_EDITMESH"; break; + case DM_TYPE_CCGDM: tstr = "DM_TYPE_CCGDM"; break; + default: tstr = "UNKNOWN"; break; + } + BLI_dynstr_appendf(dynstr, " 'type': '%s',\n", tstr); + BLI_dynstr_appendf(dynstr, " 'numVertData': %d,\n", dm->numVertData); + BLI_dynstr_appendf(dynstr, " 'numEdgeData': %d,\n", dm->numEdgeData); + BLI_dynstr_appendf(dynstr, " 'numFaceData': %d,\n", dm->numFaceData); + BLI_dynstr_appendf(dynstr, " 'deformedOnly': %d,\n", dm->deformedOnly); + + BLI_dynstr_appendf(dynstr, " 'vertexLayers': (\n"); + dm_debug_info_layers(dynstr, dm, dm->getVertDataArray); + BLI_dynstr_appendf(dynstr, " ),\n"); + + BLI_dynstr_appendf(dynstr, " 'edgeLayers': (\n"); + dm_debug_info_layers(dynstr, dm, dm->getEdgeDataArray); + BLI_dynstr_appendf(dynstr, " ),\n"); + + BLI_dynstr_appendf(dynstr, " 'faceLayers': (\n"); + dm_debug_info_layers(dynstr, dm, dm->getFaceDataArray); + BLI_dynstr_appendf(dynstr, " ),\n"); + + BLI_dynstr_appendf(dynstr, "}\n"); + + ret = BLI_dynstr_get_cstring(dynstr); + BLI_dynstr_free(dynstr); + return ret; +} + +void DM_debug_print(DerivedMesh *dm) +{ + char *str = DM_debug_info(dm); + printf("%s", str); + fflush(stdout); + MEM_freeN(str); +} + +#endif /* NDEBUG */ diff -Nru blender-2.61/source/blender/blenkernel/intern/displist.c blender-2.62/source/blender/blenkernel/intern/displist.c --- blender-2.61/source/blender/blenkernel/intern/displist.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/displist.c 2012-02-15 19:34:02.000000000 +0000 @@ -269,9 +269,9 @@ (*b)= 1; } - if( (dl->flag & DL_CYCL_V) && a==dl->parts-1) { \ - (*p3)-= dl->nr*dl->parts; \ - (*p4)-= dl->nr*dl->parts; \ + if( (dl->flag & DL_CYCL_V) && a==dl->parts-1) { + (*p3)-= dl->nr*dl->parts; + (*p4)-= dl->nr*dl->parts; } return 1; @@ -833,6 +833,7 @@ int editmode = (!forRender && cu->editnurb); DerivedMesh *dm= NULL, *ndm; float (*vertCos)[3] = NULL; + int useCache = !forRender; if(forRender) required_mode = eModifierMode_Render; else required_mode = eModifierMode_Realtime; @@ -911,7 +912,7 @@ vertCos= NULL; } - ndm = mti->applyModifier(md, ob, dm, forRender, editmode); + ndm = mti->applyModifier(md, ob, dm, forRender, useCache); if (ndm) { /* Modifier returned a new derived mesh */ @@ -1178,6 +1179,60 @@ forRender, originalVerts, deformedVerts); } +static void rotateBevelPiece(Curve *cu, BevPoint *bevp, DispList *dlb, float widfac, float fac, float **data_r) +{ + float *fp, *data = *data_r; + int b; + + fp = dlb->verts; + for (b = 0; bnr; b++,fp += 3,data += 3) { + if(cu->flag & CU_3D) { + float vec[3]; + + vec[0] = fp[1]+widfac; + vec[1] = fp[2]; + vec[2 ]= 0.0; + + mul_qt_v3(bevp->quat, vec); + + data[0] = bevp->vec[0] + fac*vec[0]; + data[1] = bevp->vec[1] + fac*vec[1]; + data[2] = bevp->vec[2] + fac*vec[2]; + } + else { + data[0] = bevp->vec[0] + fac*(widfac+fp[1])*bevp->sina; + data[1] = bevp->vec[1] + fac*(widfac+fp[1])*bevp->cosa; + data[2] = bevp->vec[2] + fac*fp[2]; + } + } + + *data_r = data; +} + +static void fillBevelCap(Curve *cu, Nurb *nu, BevPoint *bevp, DispList *dlb, float fac, float widfac, ListBase *dispbase) +{ + DispList *dl; + float *data; + + dl= MEM_callocN(sizeof(DispList), "makeDispListbev2"); + dl->verts= data= MEM_callocN(3*sizeof(float)*dlb->nr, "dlverts"); + + dl->type= DL_POLY; + + dl->parts= 1; + dl->nr= dlb->nr; + dl->col= nu->mat_nr; + dl->charidx= nu->charidx; + + /* dl->rt will be used as flag for render face and */ + /* CU_2D conflicts with R_NOPUNOFLIP */ + dl->rt= nu->flag & ~CU_2D; + + rotateBevelPiece(cu, bevp, dlb, widfac, fac, &data); + + BLI_addtail(dispbase, dl); +} + static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispbase, DerivedMesh **derivedFinal, int forRender, int forOrco) { @@ -1222,9 +1277,9 @@ for (; bl && nu; bl=bl->next,nu=nu->next) { DispList *dl; - float *fp1, *data; + float *data; BevPoint *bevp; - int a,b; + int a; if (bl->nr) { /* blank bevel lists can happen */ @@ -1261,9 +1316,10 @@ } else { DispList *dlb; + ListBase bottom_capbase = {NULL, NULL}; + ListBase top_capbase = {NULL, NULL}; for (dlb=dlbev.first; dlb; dlb=dlb->next) { - /* for each part of the bevel use a separate displblock */ dl= MEM_callocN(sizeof(DispList), "makeDispListbev1"); dl->verts= data= MEM_callocN(3*sizeof(float)*dlb->nr*bl->nr, "dlverts"); @@ -1301,33 +1357,27 @@ dl->bevelSplitFlag[a>>5] |= 1<<(a&0x1F); } - /* rotate bevel piece and write in data */ - fp1= dlb->verts; - for (b=0; bnr; b++,fp1+=3,data+=3) { - if(cu->flag & CU_3D) { - float vec[3]; - - vec[0]= fp1[1]+widfac; - vec[1]= fp1[2]; - vec[2]= 0.0; - - mul_qt_v3(bevp->quat, vec); - - data[0]= bevp->vec[0] + fac*vec[0]; - data[1]= bevp->vec[1] + fac*vec[1]; - data[2]= bevp->vec[2] + fac*vec[2]; - } - else { - data[0]= bevp->vec[0] + fac*(widfac+fp1[1])*bevp->sina; - data[1]= bevp->vec[1] + fac*(widfac+fp1[1])*bevp->cosa; - data[2]= bevp->vec[2] + fac*fp1[2]; - } + /* rotate bevel piece and write in data */ + rotateBevelPiece(cu, bevp, dlb, widfac, fac, &data); + + if (cu->bevobj && (cu->flag & CU_FILL_CAPS)) { + if (a == 0) + fillBevelCap(cu, nu, bevp, dlb, fac, widfac, &bottom_capbase); + else if (a == bl->nr - 1) + fillBevelCap(cu, nu, bevp, dlb, fac, widfac, &top_capbase); } } - + /* gl array drawing: using indices */ displist_surf_indices(dl); } + + if(bottom_capbase.first) { + filldisplist(&bottom_capbase, dispbase, 1); + filldisplist(&top_capbase, dispbase, 0); + freedisplist(&bottom_capbase); + freedisplist(&top_capbase); + } } } diff -Nru blender-2.61/source/blender/blenkernel/intern/dynamicpaint.c blender-2.62/source/blender/blenkernel/intern/dynamicpaint.c --- blender-2.61/source/blender/blenkernel/intern/dynamicpaint.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/dynamicpaint.c 2012-02-15 19:34:02.000000000 +0000 @@ -97,13 +97,18 @@ /* brush mesh raycast status */ #define HIT_VOLUME 1 #define HIT_PROXIMITY 2 +/* dynamicPaint_findNeighbourPixel() return codes */ +#define NOT_FOUND -1 +#define ON_MESH_EDGE -2 +#define OUT_OF_TEXTURE -3 /* paint effect default movement per frame in global units */ #define EFF_MOVEMENT_PER_FRAME 0.05f /* initial wave time factor */ #define WAVE_TIME_FAC (1.0f/24.f) -#define WAVE_INIT_SIZE 5.0f +#define CANVAS_REL_SIZE 5.0f /* drying limits */ #define MIN_WETNESS 0.001f +#define MAX_WETNESS 5.0f /* dissolve macro */ #define VALUE_DISSOLVE(VALUE, TIME, SCALE, LOG) (VALUE) = (LOG) ? (VALUE) * (pow(MIN_WETNESS,1.0f/(1.2f*((float)(TIME))/(SCALE)))) : (VALUE) - 1.0f/(TIME)*(SCALE) @@ -133,10 +138,10 @@ float v[3]; } Vec3f; -typedef struct BakeNeighPoint { +typedef struct BakeAdjPoint { float dir[3]; /* vector pointing towards this neighbour */ float dist; /* distance to */ -} BakeNeighPoint; +} BakeAdjPoint; /* Surface data used while processing a frame */ typedef struct PaintBakeNormal { @@ -155,7 +160,7 @@ Bounds3D mesh_bounds; /* adjacency info */ - BakeNeighPoint *bNeighs; /* current global neighbour distances and directions, if required */ + BakeAdjPoint *bNeighs; /* current global neighbour distances and directions, if required */ double average_dist; /* space partitioning */ VolumeGrid *grid; /* space partitioning grid to optimize brush checks */ @@ -187,12 +192,6 @@ Vec3f *barycentricWeights; /* b-weights for all pixel samples */ } ImgSeqFormatData; -typedef struct EffVelPoint { - float previous_pos[3]; - float previous_vel[3]; -} EffVelPoint; - - /* adjacency data flags */ #define ADJ_ON_MESH_EDGE (1<<0) @@ -361,8 +360,8 @@ surface->depth_clamp = 1.0f; } else { - sprintf(surface->output_name, "dp_"); - strcpy(surface->output_name2,surface->output_name); + strcpy(surface->output_name, "dp_"); + strcpy(surface->output_name2, surface->output_name); surface->flags &= ~MOD_DPAINT_ANTIALIAS; surface->depth_clamp = 0.0f; } @@ -422,15 +421,31 @@ result[3] = f_alpha; } -/* assumes source alpha > 0.0f or results NaN colors */ -static void mixColors(float *t_color, float t_alpha, float *s_color, float s_alpha) +/* Mix two alpha weighed colors by a defined ratio. output is saved at a_color */ +static float mixColors(float a_color[3], float a_weight, float b_color[3], float b_weight, float ratio) { - float factor = (s_alphacanvas) - return; + return 1; /* if object has parents, update them too */ if (flags & UPDATE_PARENTS) { - if (ob->parent) subframe_updateObject(scene, ob->parent, 0, frame); - if (ob->track) subframe_updateObject(scene, ob->track, 0, frame); + int is_canvas = 0; + if (ob->parent) is_canvas += subframe_updateObject(scene, ob->parent, 0, frame); + if (ob->track) is_canvas += subframe_updateObject(scene, ob->track, 0, frame); + + /* skip subframe if object is parented + * to vertex of a dynamic paint canvas */ + if (is_canvas && (ob->partype == PARVERT1 || ob->partype == PARVERT3)) + return 0; /* also update constraint targets */ for (con = ob->constraints.first; con; con=con->next) { @@ -501,6 +522,8 @@ } else where_is_object_time(scene, ob, frame); + + return 0; } static void scene_setSubframe(Scene *scene, float subframe) @@ -510,8 +533,6 @@ scene->r.subframe = subframe; } -#define BRUSH_USES_VELOCITY (1<<0) - static int surface_getBrushFlags(DynamicPaintSurface *surface, Scene *scene) { Base *base = NULL; @@ -619,6 +640,12 @@ } } +float getSurfaceDimension(PaintSurfaceData *sData) +{ + Bounds3D *mb = &sData->bData->mesh_bounds; + return MAX3((mb->max[0]-mb->min[0]), (mb->max[1]-mb->min[1]), (mb->max[2]-mb->min[2])); +} + static void freeGrid(PaintSurfaceData *data) { PaintBakeData *bData = data->bData; @@ -961,17 +988,21 @@ /* Set initial values */ surface->flags = MOD_DPAINT_ANTIALIAS | MOD_DPAINT_MULALPHA | MOD_DPAINT_DRY_LOG | MOD_DPAINT_DISSOLVE_LOG | - MOD_DPAINT_ACTIVE | MOD_DPAINT_PREVIEW | MOD_DPAINT_OUT1; + MOD_DPAINT_ACTIVE | MOD_DPAINT_PREVIEW | MOD_DPAINT_OUT1 | MOD_DPAINT_USE_DRYING; surface->effect = 0; surface->effect_ui = 1; surface->diss_speed = 250; surface->dry_speed = 500; + surface->color_dry_threshold = 1.0f; surface->depth_clamp = 0.0f; surface->disp_factor = 1.0f; surface->disp_type = MOD_DPAINT_DISP_DISPLACE; surface->image_fileformat = MOD_DPAINT_IMGFORMAT_PNG; + surface->influence_scale = 1.0f; + surface->radius_scale = 1.0f; + surface->init_color[0] = 1.0f; surface->init_color[1] = 1.0f; surface->init_color[2] = 1.0f; @@ -1196,7 +1227,7 @@ static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface, int force_init) { PaintSurfaceData *sData = surface->data; - PaintAdjData *ed; + PaintAdjData *ad; int *temp_data; int neigh_points = 0; @@ -1212,17 +1243,17 @@ if (!neigh_points) return; /* allocate memory */ - ed = sData->adj_data = MEM_callocN(sizeof(PaintAdjData), "Surface Adj Data"); - if (!ed) return; - ed->n_index = MEM_callocN(sizeof(int)*sData->total_points, "Surface Adj Index"); - ed->n_num = MEM_callocN(sizeof(int)*sData->total_points, "Surface Adj Counts"); + ad = sData->adj_data = MEM_callocN(sizeof(PaintAdjData), "Surface Adj Data"); + if (!ad) return; + ad->n_index = MEM_callocN(sizeof(int)*sData->total_points, "Surface Adj Index"); + ad->n_num = MEM_callocN(sizeof(int)*sData->total_points, "Surface Adj Counts"); temp_data = MEM_callocN(sizeof(int)*sData->total_points, "Temp Adj Data"); - ed->n_target = MEM_callocN(sizeof(int)*neigh_points, "Surface Adj Targets"); - ed->flags = MEM_callocN(sizeof(int)*sData->total_points, "Surface Adj Flags"); - ed->total_targets = neigh_points; + ad->n_target = MEM_callocN(sizeof(int)*neigh_points, "Surface Adj Targets"); + ad->flags = MEM_callocN(sizeof(int)*sData->total_points, "Surface Adj Flags"); + ad->total_targets = neigh_points; /* in case of allocation error, free memory */ - if (!ed->n_index || !ed->n_num || !ed->n_target || !temp_data) { + if (!ad->n_index || !ad->n_num || !ad->n_target || !temp_data) { dynamicPaint_freeAdjData(sData); if (temp_data) MEM_freeN(temp_data); setError(surface->canvas, "Not enough free memory."); @@ -1241,14 +1272,15 @@ /* count number of edges per vertex */ for (i=0; in_num[edge[i].v1]++; - ed->n_num[edge[i].v2]++; + ad->n_num[edge[i].v1]++; + ad->n_num[edge[i].v2]++; temp_data[edge[i].v1]++; temp_data[edge[i].v2]++; } - /* to locate points on "mesh edge" */ + /* also add number of vertices to temp_data + * to locate points on "mesh edge" */ for (i=0; itotal_points; i++) { if ((temp_data[i]%2) || temp_data[i] < 4) - ed->flags[i] |= ADJ_ON_MESH_EDGE; + ad->flags[i] |= ADJ_ON_MESH_EDGE; /* reset temp data */ temp_data[i] = 0; @@ -1271,22 +1303,22 @@ /* order n_index array */ n_pos = 0; for (i=0; itotal_points; i++) { - ed->n_index[i] = n_pos; - n_pos += ed->n_num[i]; + ad->n_index[i] = n_pos; + n_pos += ad->n_num[i]; } /* and now add neighbour data using that info */ for (i=0; in_index[index]+temp_data[index]; - ed->n_target[n_pos] = edge[i].v2; + n_pos = ad->n_index[index]+temp_data[index]; + ad->n_target[n_pos] = edge[i].v2; temp_data[index]++; /* second vertex */ index = edge[i].v2; - n_pos = ed->n_index[index]+temp_data[index]; - ed->n_target[n_pos] = edge[i].v1; + n_pos = ad->n_index[index]+temp_data[index]; + ad->n_target[n_pos] = edge[i].v1; temp_data[index]++; } } @@ -1325,7 +1357,7 @@ MTFace *tface; MFace *mface = dm->getFaceArray(dm); int numOfFaces = dm->getNumFaces(dm); - char uvname[40]; + char uvname[MAX_CUSTOMDATA_LAYER_NAME]; if (!tex) return; @@ -1474,10 +1506,11 @@ int dynamicPaint_resetSurface(DynamicPaintSurface *surface) { int numOfPoints = dynamicPaint_surfaceNumOfPoints(surface); - /* dont touch image sequence types. they get handled only on bake */ - if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) return 1; - + /* free existing data */ if (surface->data) dynamicPaint_freeSurfaceData(surface); + + /* dont reallocate for image sequence types. they get handled only on bake */ + if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) return 1; if (numOfPoints < 1) return 0; /* allocate memory */ @@ -1510,7 +1543,7 @@ /* apply displacing vertex surface to the derived mesh */ -static void dynamicPaint_applySurfaceDisplace(DynamicPaintSurface *surface, DerivedMesh *result, int update_normals) +static void dynamicPaint_applySurfaceDisplace(DynamicPaintSurface *surface, DerivedMesh *result) { PaintSurfaceData *sData = surface->data; @@ -1533,10 +1566,6 @@ mvert[i].co[2] -= normal[2]*val; } } - else return; - - if (update_normals) - CDDM_calc_normals(result); } /* @@ -1551,7 +1580,7 @@ if(pmd->canvas && !(pmd->canvas->flags & MOD_DPAINT_BAKING)) { DynamicPaintSurface *surface = pmd->canvas->surfaces.first; - pmd->canvas->flags &= ~MOD_DPAINT_PREVIEW_READY; + int update_normals = 0; /* loop through surfaces */ for (; surface; surface=surface->next) { @@ -1591,11 +1620,11 @@ if (col) { #pragma omp parallel for schedule(static) for (i=0; ipreview_id == MOD_DPAINT_SURFACE_PREV_PAINT) { float c[3]; @@ -1622,13 +1651,12 @@ } else { col[i*4+j].a = 255; - col[i*4+j].r = FTOCHAR(pPoint[index].wetness); - col[i*4+j].g = FTOCHAR(pPoint[index].wetness); + col[i*4+j].r = + col[i*4+j].g = col[i*4+j].b = FTOCHAR(pPoint[index].wetness); } } } - pmd->canvas->flags |= MOD_DPAINT_PREVIEW_READY; } } @@ -1644,9 +1672,9 @@ if (col) { #pragma omp parallel for schedule(static) for (i=0; iflags & MOD_DPAINT_PREVIEW) { /* Save preview results to weight layer, to be * able to share same drawing methods */ - MFace *mface = result->getFaceArray(result); - int numOfFaces = result->getNumFaces(result); - int i; - MCol *col = result->getFaceDataArray(result, CD_WEIGHT_MCOL); - if (!col) col = CustomData_add_layer(&result->faceData, CD_WEIGHT_MCOL, CD_CALLOC, NULL, numOfFaces); - - if (col) { - #pragma omp parallel for schedule(static) - for (i=0; icanvas->flags |= MOD_DPAINT_PREVIEW_READY; - } + DM_update_weight_mcol(ob, result, 0, weight, 0, NULL); } /* apply weights into a vertex group, if doesnt exists add a new layer */ @@ -1750,14 +1755,20 @@ normal_short_to_float_v3(normal, mvert[i].no); madd_v3_v3fl(mvert[i].co, normal, wPoint[i].height); } - CDDM_calc_normals(result); + update_normals = 1; } /* displace */ - dynamicPaint_applySurfaceDisplace(surface, result, 1); + if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) { + dynamicPaint_applySurfaceDisplace(surface, result); + update_normals = 1; + } } } } + + if (update_normals) + CDDM_calc_normals(result); } /* make a copy of dm to use as brush data */ if (pmd->brush) { @@ -1879,7 +1890,8 @@ * px,py : origin pixel x and y * n_index : lookup direction index (use neighX,neighY to get final index) */ -static int dynamicPaint_findNeighbourPixel(PaintUVPoint *tempPoints, DerivedMesh *dm, char *uvname, int w, int h, int px, int py, int n_index) +static int dynamicPaint_findNeighbourPixel(PaintUVPoint *tempPoints, DerivedMesh *dm, + const char *uvname, int w, int h, int px, int py, int n_index) { /* Note: Current method only uses polygon edges to detect neighbouring pixels. * -> It doesn't always lead to the optimum pixel but is accurate enough @@ -1894,8 +1906,8 @@ x = px + neighX[n_index]; y = py + neighY[n_index]; - if (x<0 || x>=w) return -1; - if (y<0 || y>=h) return -1; + if (x<0 || x>=w) return OUT_OF_TEXTURE; + if (y<0 || y>=h) return OUT_OF_TEXTURE; tPoint = &tempPoints[x+w*y]; /* UV neighbour */ cPoint = &tempPoints[px+w*py]; /* Origin point */ @@ -2008,8 +2020,8 @@ } } - /* If none found return -1 */ - if (target_face == -1) return -1; + /* If none found pixel is on mesh edge */ + if (target_face == -1) return ON_MESH_EDGE; /* * If target face is connected in UV space as well, just use original index @@ -2047,15 +2059,15 @@ final_pixel[1] = (int)floor(pixel[1]); /* If current pixel uv is outside of texture */ - if (final_pixel[0] < 0 || final_pixel[0] >= w) return -1; - if (final_pixel[1] < 0 || final_pixel[1] >= h) return -1; + if (final_pixel[0] < 0 || final_pixel[0] >= w) return OUT_OF_TEXTURE; + if (final_pixel[1] < 0 || final_pixel[1] >= h) return OUT_OF_TEXTURE; final_index = final_pixel[0] + w * final_pixel[1]; /* If we ended up to our origin point ( mesh has smaller than pixel sized faces) */ - if (final_index == (px+w*py)) return -1; + if (final_index == (px+w*py)) return NOT_FOUND; /* If found pixel still lies on wrong face ( mesh has smaller than pixel sized faces) */ - if (tempPoints[final_index].face_index != target_face) return -1; + if (tempPoints[final_index].face_index != target_face) return NOT_FOUND; /* * If final point is an "edge pixel", use it's "real" neighbour instead @@ -2081,7 +2093,7 @@ int ty; int w,h; int numOfFaces; - char uvname[32]; + char uvname[MAX_CUSTOMDATA_LAYER_NAME]; int active_points = 0; int error = 0; @@ -2291,7 +2303,7 @@ tPoint->quad = (isInside == 2) ? 1 : 0; /* quad or tri part*/ /* save vertex indexes */ - tPoint->v1 = mface[i].v1; /* (isInside == 2) ? mface[i].v1 : mface[i].v1; */ /* same! */ + tPoint->v1 = mface[i].v1; tPoint->v2 = (isInside == 2) ? mface[i].v3 : mface[i].v2; tPoint->v3 = (isInside == 2) ? mface[i].v4 : mface[i].v3; @@ -2371,7 +2383,7 @@ tPoint->quad = tempPoints[ind].quad; // quad or tri /* save vertex indexes */ - tPoint->v1 = (tPoint->quad) ? mface[i].v1 : mface[i].v1; + tPoint->v1 = mface[i].v1; tPoint->v2 = (tPoint->quad) ? mface[i].v3 : mface[i].v2; tPoint->v3 = (tPoint->quad) ? mface[i].v4 : mface[i].v3; @@ -2401,10 +2413,8 @@ } } - /* If any effect enabled, create surface effect / wet layer - * neighbour lists. Processes possibly moving data. */ - if (surface_usesAdjData(surface)) { - + /* Generate surface adjacency data. */ + { int i, cursor=0; /* Create a temporary array of final indexes (before unassigned @@ -2417,12 +2427,11 @@ } /* allocate memory */ sData->total_points = w*h; - dynamicPaint_initAdjacencyData(surface, 0); + dynamicPaint_initAdjacencyData(surface, 1); if (sData->adj_data) { PaintAdjData *ed = sData->adj_data; unsigned int n_pos = 0; - //#pragma omp parallel for schedule(static) for (ty = 0; ty < h; ty++) { int tx; @@ -2440,11 +2449,14 @@ * If not found, -1 is returned */ int n_target = dynamicPaint_findNeighbourPixel(tempPoints, dm, uvname, w, h, tx, ty, i); - if (n_target != -1) { + if (n_target >= 0) { ed->n_target[n_pos] = final_index[n_target]; ed->n_num[final_index[index]]++; n_pos++; } + else if (n_target == ON_MESH_EDGE || n_target == OUT_OF_TEXTURE) { + ed->flags[final_index[index]] |= ADJ_ON_MESH_EDGE; + } } } } @@ -2578,14 +2590,8 @@ if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) { PaintPoint *point = &((PaintPoint*)sData->type_data)[index]; - ibuf->rect_float[pos] = point->color[0]; - ibuf->rect_float[pos+1] = point->color[1]; - ibuf->rect_float[pos+2] = point->color[2]; - /* mix wet layer */ - if (point->e_alpha) mixColors(&ibuf->rect_float[pos], point->alpha, point->e_color, point->e_alpha); - - /* use highest alpha */ - ibuf->rect_float[pos+3] = (point->e_alpha > point->alpha) ? point->e_alpha : point->alpha; + /* blend wet and dry layers */ + blendColors(point->color, point->alpha, point->e_color, point->e_alpha, &ibuf->rect_float[pos]); /* Multiply color by alpha if enabled */ if (surface->flags & MOD_DPAINT_MULALPHA) { @@ -2916,7 +2922,13 @@ float paint[3], float influence, float depth, float vel_factor, float timescale) { PaintSurfaceData *sData = surface->data; - float strength = influence * brush->alpha; + float strength; + + /* apply influence scale */ + influence *= surface->influence_scale; + depth *= surface->influence_scale; + + strength = influence * brush->alpha; CLAMP(strength, 0.0f, 1.0f); /* Sample velocity colorband if required */ @@ -2995,12 +3007,12 @@ } /* checks whether surface and brush bounds intersect depending on brush type */ -static int meshBrush_boundsIntersect(Bounds3D *b1, Bounds3D *b2, DynamicPaintBrushSettings *brush) +static int meshBrush_boundsIntersect(Bounds3D *b1, Bounds3D *b2, DynamicPaintBrushSettings *brush, float brush_radius) { if (brush->collision == MOD_DPAINT_COL_VOLUME) return boundsIntersect(b1, b2); else if (brush->collision == MOD_DPAINT_COL_DIST || brush->collision == MOD_DPAINT_COL_VOLDIST) - return boundsIntersectDist(b1, b2, brush->paint_distance); + return boundsIntersectDist(b1, b2, brush_radius); else return 1; } @@ -3127,6 +3139,7 @@ { BVHTreeFromMesh treeData = {0}; float avg_brushNor[3] = {0.0f}; + float brush_radius = brush->paint_distance * surface->radius_scale; int numOfVerts; int ii; Bounds3D mesh_bb = {0}; @@ -3144,8 +3157,8 @@ mul_m4_v3(brushOb->obmat, mvert[ii].co); boundInsert(&mesh_bb, mvert[ii].co); - /* for project brush calculate average normal */ - if (brush->collision & MOD_DPAINT_COL_DIST && brush->flags & MOD_DPAINT_PROX_PROJECT) { + /* for proximity project calculate average normal */ + if (brush->flags & MOD_DPAINT_PROX_PROJECT && brush->collision != MOD_DPAINT_COL_VOLUME) { float nor[3]; normal_short_to_float_v3(nor, mvert[ii].no); mul_mat3_m4_v3(brushOb->obmat, nor); @@ -3155,7 +3168,7 @@ } } - if (brush->collision & MOD_DPAINT_COL_DIST && brush->flags & MOD_DPAINT_PROX_PROJECT) { + if (brush->flags & MOD_DPAINT_PROX_PROJECT && brush->collision != MOD_DPAINT_COL_VOLUME) { mul_v3_fl(avg_brushNor, 1.0f/(float)numOfVerts); /* instead of null vector use positive z */ if (!(MIN3(avg_brushNor[0],avg_brushNor[1],avg_brushNor[2]))) @@ -3165,7 +3178,7 @@ } /* check bounding box collision */ - if(grid && meshBrush_boundsIntersect(&grid->grid_bounds, &mesh_bb, brush)) + if(grid && meshBrush_boundsIntersect(&grid->grid_bounds, &mesh_bb, brush, brush_radius)) /* Build a bvh tree from transformed vertices */ if (bvhtree_from_mesh_faces(&treeData, dm, 0.0f, 4, 8)) { @@ -3177,7 +3190,7 @@ int id; /* check grid cell bounding box */ - if (!grid->s_num[c_index] || !meshBrush_boundsIntersect(&grid->bounds[c_index], &mesh_bb, brush)) + if (!grid->s_num[c_index] || !meshBrush_boundsIntersect(&grid->bounds[c_index], &mesh_bb, brush, brush_radius)) continue; /* loop through cell points and process brush */ @@ -3220,7 +3233,7 @@ /* hit data */ float hitCoord[3]; int hitFace = -1; - short hitQuad; + short hitQuad = 0; /* Supersampling factor */ if (samples > 1 && surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) @@ -3238,7 +3251,7 @@ hit.index = -1; hit.dist = 9999; nearest.index = -1; - nearest.dist = brush->paint_distance * brush->paint_distance; /* find_nearest uses squared distance */ + nearest.dist = brush_radius * brush_radius; /* find_nearest uses squared distance */ /* Check volume collision */ if (brush->collision == MOD_DPAINT_COL_VOLUME || brush->collision == MOD_DPAINT_COL_VOLDIST) @@ -3296,9 +3309,9 @@ if (inner_proximity && !hit_found) continue; /* If pure distance proximity, find the nearest point on the mesh */ - if (brush->collision != MOD_DPAINT_COL_DIST || !(brush->flags & MOD_DPAINT_PROX_PROJECT)) { + if (!(brush->flags & MOD_DPAINT_PROX_PROJECT)) { if (BLI_bvhtree_find_nearest(treeData.tree, ray_start, &nearest, mesh_faces_nearest_point_dp, &treeData) != -1) { - proxDist = sqrt(nearest.dist); + proxDist = sqrtf(nearest.dist); copy_v3_v3(hitCo, nearest.co); hQuad = (nearest.no[0] == 1.0f); face = nearest.index; @@ -3318,7 +3331,7 @@ proj_ray[2] = 1.0f; } hit.index = -1; - hit.dist = brush->paint_distance; + hit.dist = brush_radius; /* Do a face normal directional raycast, and use that distance */ if(BLI_bvhtree_ray_cast(treeData.tree, ray_start, proj_ray, 0.0f, &hit, mesh_faces_spherecast_dp, &treeData) != -1) @@ -3331,8 +3344,8 @@ } /* If a hit was found, calculate required values */ - if (proxDist >= 0.0f && proxDist <= brush->paint_distance) { - proximity_factor = proxDist / brush->paint_distance; + if (proxDist >= 0.0f && proxDist <= brush_radius) { + proximity_factor = proxDist / brush_radius; CLAMP(proximity_factor, 0.0f, 1.0f); if (!inner_proximity) proximity_factor = 1.0f - proximity_factor; @@ -3518,8 +3531,8 @@ int invalidParticles = 0; int p = 0; - float solidradius = (brush->flags & MOD_DPAINT_PART_RAD) ? psys->part->size : brush->particle_radius; - float smooth = brush->particle_smooth; + float solidradius = surface->radius_scale*((brush->flags & MOD_DPAINT_PART_RAD) ? psys->part->size : brush->particle_radius); + float smooth = brush->particle_smooth*surface->radius_scale; float range = solidradius + smooth; float particle_timestep = 0.04f * part->timetweak; @@ -3539,7 +3552,7 @@ /* Proceed only if particle is active */ if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0) continue; else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0) continue; - else if(pa->flag & PARS_NO_DISP || pa->flag & PARS_UNEXIST) continue; + else if(pa->flag & PARS_UNEXIST) continue; /* for debug purposes check if any NAN particle proceeds * For some reason they get past activity check, this should rule most of them out */ @@ -3748,6 +3761,7 @@ Object *brushOb, BrushMaterials *bMats, Scene *scene, float timescale) { int index; + float brush_radius = brush->paint_distance * surface->radius_scale; PaintSurfaceData *sData = surface->data; PaintBakeData *bData = sData->bData; Vec3f brushVel; @@ -3765,13 +3779,13 @@ float colorband[4] = {0.0f}; float strength; - if (distance>brush->paint_distance) continue; + if (distance > brush_radius) continue; /* Smooth range or color ramp */ if (brush->proximity_falloff == MOD_DPAINT_PRFALL_SMOOTH || brush->proximity_falloff == MOD_DPAINT_PRFALL_RAMP) { - strength = 1.0f - distance / brush->paint_distance; + strength = 1.0f - distance / brush_radius; CLAMP(strength, 0.0f, 1.0f); } else strength = 1.0f; @@ -3836,8 +3850,8 @@ else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE || surface->type == MOD_DPAINT_SURFACE_T_WAVE) { /* get displace depth */ - float disp_intersect = (1.0f - sqrtf((brush->paint_distance-distance) / brush->paint_distance)) * brush->paint_distance; - depth = (brush->paint_distance - disp_intersect) / bData->bNormal[index].normal_scale; + float disp_intersect = (1.0f - sqrtf((brush_radius-distance) / brush_radius)) * brush_radius; + depth = (brush_radius - disp_intersect) / bData->bNormal[index].normal_scale; if (depth<0.0f) depth = 0.0f; } dynamicPaint_updatePointData(surface, index, brush, paintColor, strength, depth, velocity_val, timescale); @@ -3851,14 +3865,13 @@ /***************************** Dynamic Paint Step / Baking ******************************/ /* -* Calculate current frame neighbouring point distances -* and direction vectors +* Calculate current frame distances and directions for adjacency data */ -static void dynamicPaint_prepareNeighbourData(DynamicPaintSurface *surface, int force_init) +static void dynamicPaint_prepareAdjacencyData(DynamicPaintSurface *surface, int force_init) { PaintSurfaceData *sData = surface->data; PaintBakeData *bData = sData->bData; - BakeNeighPoint *bNeighs; + BakeAdjPoint *bNeighs; PaintAdjData *adj_data = sData->adj_data; Vec3f *realCoord = bData->realCoord; int index; @@ -3866,7 +3879,7 @@ if ((!surface_usesAdjDistance(surface) && !force_init) || !sData->adj_data) return; if (bData->bNeighs) MEM_freeN(bData->bNeighs); - bNeighs = bData->bNeighs = MEM_mallocN(sData->adj_data->total_targets*sizeof(struct BakeNeighPoint),"PaintEffectBake"); + bNeighs = bData->bNeighs = MEM_mallocN(sData->adj_data->total_targets*sizeof(struct BakeAdjPoint),"PaintEffectBake"); if (!bNeighs) return; #pragma omp parallel for schedule(static) @@ -3905,7 +3918,7 @@ /* find two adjacency points (closest_id) and influence (closest_d) to move paint towards when affected by a force */ void surface_determineForceTargetPoints(PaintSurfaceData *sData, int index, float force[3], float closest_d[2], int closest_id[2]) { - BakeNeighPoint *bNeighs = sData->bData->bNeighs; + BakeAdjPoint *bNeighs = sData->bData->bNeighs; int numOfNeighs = sData->adj_data->n_num[index]; int i; @@ -3940,7 +3953,7 @@ if (closest_id[1] != -1) { float force_proj[3]; float tangent[3]; - float neigh_diff = acos(dot_v3v3(bNeighs[closest_id[0]].dir, bNeighs[closest_id[1]].dir)); + float neigh_diff = acosf(dot_v3v3(bNeighs[closest_id[0]].dir, bNeighs[closest_id[1]].dir)); float force_intersect; float temp; @@ -3974,7 +3987,7 @@ { PaintSurfaceData *sData = surface->data; PaintBakeData *bData = sData->bData; - BakeNeighPoint *bNeighs = sData->bData->bNeighs; + BakeAdjPoint *bNeighs = sData->bData->bNeighs; int index, steps, step; float eff_scale, max_velocity = 0.0f; @@ -4012,7 +4025,6 @@ if (n_index != -1 && closest_d[i]>0.0f) { float dir_dot = closest_d[i], dir_factor; float speed_scale = eff_scale*smudge_str/bNeighs[n_index].dist; - float mix; PaintPoint *ePoint = &((PaintPoint*)sData->type_data)[sData->adj_data->n_target[n_index]]; /* just skip if angle is too extreme */ @@ -4022,13 +4034,11 @@ if (dir_factor > brush->smudge_strength) dir_factor = brush->smudge_strength; /* mix new color and alpha */ - mix = dir_factor*pPoint->alpha; - if (mix) mixColors(ePoint->color, ePoint->alpha, pPoint->color, mix); + mixColors(ePoint->color, ePoint->alpha, pPoint->color, pPoint->alpha, dir_factor); ePoint->alpha = ePoint->alpha*(1.0f-dir_factor) + pPoint->alpha*dir_factor; /* smudge "wet layer" */ - mix = dir_factor*pPoint->e_alpha; - if (mix) mixColors(ePoint->e_color, ePoint->e_alpha, pPoint->e_color, mix); + mixColors(ePoint->e_color, ePoint->e_alpha, pPoint->e_color, pPoint->e_alpha, dir_factor); ePoint->e_alpha = ePoint->e_alpha*(1.0f-dir_factor) + pPoint->e_alpha*dir_factor; pPoint->wetness *= (1.0f-dir_factor); } @@ -4045,7 +4055,7 @@ { double average_force = 0.0f; float shrink_speed=0.0f, spread_speed=0.0f; - float fastest_effect; + float fastest_effect, avg_dist; int steps; PaintSurfaceData *sData = surface->data; PaintBakeData *bData = sData->bData; @@ -4122,9 +4132,10 @@ shrink_speed = surface->shrink_speed; fastest_effect = MAX3(spread_speed, shrink_speed, average_force); + avg_dist = bData->average_dist*CANVAS_REL_SIZE/getSurfaceDimension(sData); - steps = (int)ceil(1.5f*EFF_MOVEMENT_PER_FRAME*fastest_effect/bData->average_dist*timescale); - CLAMP(steps, 1, 14); + steps = (int)ceil(1.5f*EFF_MOVEMENT_PER_FRAME*fastest_effect/avg_dist*timescale); + CLAMP(steps, 1, 20); return steps; } @@ -4135,7 +4146,8 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, float *force, PaintPoint *prevPoint, float timescale, float steps) { PaintSurfaceData *sData = surface->data; - BakeNeighPoint *bNeighs = sData->bData->bNeighs; + BakeAdjPoint *bNeighs = sData->bData->bNeighs; + float distance_scale = getSurfaceDimension(sData)/CANVAS_REL_SIZE; int index; timescale /= steps; @@ -4145,7 +4157,7 @@ * Spread Effect */ if (surface->effect & MOD_DPAINT_EFFECT_DO_SPREAD) { - float eff_scale = EFF_MOVEMENT_PER_FRAME*surface->spread_speed*timescale; + float eff_scale = distance_scale*EFF_MOVEMENT_PER_FRAME*surface->spread_speed*timescale; /* Copy current surface to the previous points array to read unmodified values */ memcpy(prevPoint, sData->type_data, sData->total_points*sizeof(struct PaintPoint)); @@ -4155,7 +4167,6 @@ { int i; int numOfNeighs = sData->adj_data->n_num[index]; - float totalAlpha = 0.0f; PaintPoint *pPoint = &((PaintPoint*)sData->type_data)[index]; /* Only reads values from the surface copy (prevPoint[]), @@ -4164,39 +4175,23 @@ /* Loop through neighbouring points */ for (i=0; iadj_data->n_index[index]+i; - float w_factor, alphaAdd = 0.0f; + float w_factor; PaintPoint *ePoint = &prevPoint[sData->adj_data->n_target[n_index]]; float speed_scale = (bNeighs[n_index].distwetness, pPoint->wetness))*0.25f*surface->color_spread_speed; - - totalAlpha += ePoint->e_alpha; + float color_mix = (MIN3(ePoint->wetness, pPoint->wetness, 1.0f))*0.25f*surface->color_spread_speed; /* do color mixing */ - if (color_mix > MIN_WETNESS) mixColors(pPoint->e_color, pPoint->e_alpha, ePoint->e_color, color_mix); + if (color_mix) mixColors(pPoint->e_color, pPoint->e_alpha, ePoint->e_color, ePoint->e_alpha, color_mix); - /* Check if neighbouring point has higher wetness, - * if so, add it's wetness to this point as well*/ - if (ePoint->wetness <= pPoint->wetness) continue; - w_factor = ePoint->wetness/numOfNeighs * (ePoint->wetness - pPoint->wetness) * speed_scale; - if (w_factor <= MIN_WETNESS) continue; - - if (ePoint->e_alpha > pPoint->e_alpha) { - alphaAdd = ePoint->e_alpha/numOfNeighs * (ePoint->wetness*ePoint->e_alpha - pPoint->wetness*pPoint->e_alpha) * speed_scale; - } + /* Only continue if surrounding point has higher wetness */ + if (ePoint->wetnesswetness || ePoint->wetnesse_color, pPoint->e_alpha, ePoint->e_color, w_factor); + w_factor = 1.0f/numOfNeighs * MIN2(ePoint->wetness, 1.0f) * speed_scale; + CLAMP(w_factor, 0.0f, 1.0f); - pPoint->e_alpha += alphaAdd; - pPoint->wetness += w_factor; - - if (pPoint->e_alpha > 1.0f) pPoint->e_alpha = 1.0f; - } - - /* For antialiasing sake, don't let alpha go much higher than average alpha of neighbours */ - if (pPoint->e_alpha > (totalAlpha/numOfNeighs+0.25f)) { - pPoint->e_alpha = (totalAlpha/numOfNeighs+0.25f); - if (pPoint->e_alpha>1.0f) pPoint->e_alpha = 1.0f; + /* mix new wetness and color */ + pPoint->wetness = (1.0f-w_factor)*pPoint->wetness + w_factor*ePoint->wetness; + pPoint->e_alpha = mixColors(pPoint->e_color, pPoint->e_alpha, ePoint->e_color, ePoint->e_alpha, w_factor); } } } @@ -4205,7 +4200,7 @@ * Shrink Effect */ if (surface->effect & MOD_DPAINT_EFFECT_DO_SHRINK) { - float eff_scale = EFF_MOVEMENT_PER_FRAME*surface->shrink_speed*timescale; + float eff_scale = distance_scale*EFF_MOVEMENT_PER_FRAME*surface->shrink_speed*timescale; /* Copy current surface to the previous points array to read unmodified values */ memcpy(prevPoint, sData->type_data, sData->total_points*sizeof(struct PaintPoint)); @@ -4255,7 +4250,7 @@ */ if (surface->effect & MOD_DPAINT_EFFECT_DO_DRIP && force) { - float eff_scale = EFF_MOVEMENT_PER_FRAME*timescale/2.0f; + float eff_scale = distance_scale*EFF_MOVEMENT_PER_FRAME*timescale/2.0f; /* Copy current surface to the previous points array to read unmodified values */ memcpy(prevPoint, sData->type_data, sData->total_points*sizeof(struct PaintPoint)); @@ -4268,8 +4263,9 @@ float closest_d[2]; /* adjust drip speed depending on wetness */ - float w_factor = pPoint_prev->wetness*0.5f - 0.025f; + float w_factor = pPoint_prev->wetness - 0.025f; if (w_factor <= 0) continue; + CLAMP(w_factor, 0.0f, 1.0f); /* get force affect points */ surface_determineForceTargetPoints(sData, index, &force[index*4], closest_d, closest_id); @@ -4278,48 +4274,45 @@ for (i=0; i<2; i++) { int n_index = closest_id[i]; if (n_index != -1 && closest_d[i]>0.0f) { - float dir_dot = closest_d[i], dir_factor; + float dir_dot = closest_d[i], dir_factor, a_factor; float speed_scale = eff_scale*force[index*4+3]/bNeighs[n_index].dist; PaintPoint *ePoint = &((PaintPoint*)sData->type_data)[sData->adj_data->n_target[n_index]]; + float e_wet = ePoint->wetness; /* just skip if angle is too extreme */ if (dir_dot <= 0.0f) continue; - dir_factor = dir_dot * speed_scale * w_factor; - if (dir_factor > (0.5f/steps)) dir_factor = (0.5f/steps); + dir_factor = dir_dot * MIN2(speed_scale, 1.0f) * w_factor; + if (dir_factor > 0.5f) dir_factor = 0.5f; - /* mix new color */ - if (dir_factor) mixColors(ePoint->e_color, ePoint->e_alpha, pPoint->e_color, dir_factor); - - ePoint->e_alpha += dir_factor; + /* mix new wetness*/ ePoint->wetness += dir_factor; - if (ePoint->e_alpha > 1.0f) ePoint->e_alpha = 1.0f; + CLAMP(ePoint->wetness, 0.0f, MAX_WETNESS); + + /* mix new color */ + a_factor = dir_factor / pPoint_prev->wetness; + CLAMP(a_factor, 0.0f, 1.0f); + mixColors(ePoint->e_color, ePoint->e_alpha, pPoint_prev->e_color, pPoint_prev->e_alpha, a_factor); + /* dripping is supposed to preserve alpha level */ + if (pPoint_prev->e_alpha > ePoint->e_alpha) { + ePoint->e_alpha += a_factor * pPoint_prev->e_alpha; + if (ePoint->e_alpha > pPoint_prev->e_alpha) + ePoint->e_alpha = pPoint_prev->e_alpha; + } - /* and decrease paint wetness on current point */ - pPoint->wetness -= dir_factor; + /* decrease paint wetness on current point */ + pPoint->wetness -= (ePoint->wetness - e_wet); + CLAMP(pPoint->wetness, 0.0f, MAX_WETNESS); } } } - - /* Keep values within acceptable range */ - #pragma omp parallel for schedule(static) - for (index = 0; index < sData->total_points; index++) - { - PaintPoint *cPoint = &((PaintPoint*)sData->type_data)[index]; - - if (cPoint->e_alpha > 1.0f) cPoint->e_alpha=1.0f; - if (cPoint->wetness > 2.0f) cPoint->wetness=2.0f; - - if (cPoint->e_alpha < 0.0f) cPoint->e_alpha=0.0f; - if (cPoint->wetness < 0.0f) cPoint->wetness=0.0f; - } } } void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, float timescale) { PaintSurfaceData *sData = surface->data; - BakeNeighPoint *bNeighs = sData->bData->bNeighs; + BakeAdjPoint *bNeighs = sData->bData->bNeighs; int index; int steps, ss; float dt, min_dist, damp_factor; @@ -4327,7 +4320,7 @@ double average_dist = 0.0f; Bounds3D *mb = &sData->bData->mesh_bounds; float canvas_size = MAX3((mb->max[0]-mb->min[0]), (mb->max[1]-mb->min[1]), (mb->max[2]-mb->min[2])); - float wave_scale = WAVE_INIT_SIZE/canvas_size; + float wave_scale = CANVAS_REL_SIZE/canvas_size; /* allocate memory */ PaintWavePoint *prevPoint = MEM_mallocN(sData->total_points*sizeof(PaintWavePoint), "Temp previous points for wave simulation"); @@ -4440,48 +4433,53 @@ if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) { PaintPoint *pPoint = &((PaintPoint*)sData->type_data)[index]; /* drying */ - if (pPoint->wetness >= MIN_WETNESS) { - int i; - float dry_ratio, f_color[4]; - float p_wetness = pPoint->wetness; - VALUE_DISSOLVE(pPoint->wetness, surface->dry_speed, timescale, (surface->flags & MOD_DPAINT_DRY_LOG)); - if (pPoint->wetness<0.0f) pPoint->wetness=0.0f; - dry_ratio = pPoint->wetness/p_wetness; + if (surface->flags & MOD_DPAINT_USE_DRYING) { + if (pPoint->wetness >= MIN_WETNESS) { + int i; + float dry_ratio, f_color[4]; + float p_wetness = pPoint->wetness; + VALUE_DISSOLVE(pPoint->wetness, surface->dry_speed, timescale, (surface->flags & MOD_DPAINT_DRY_LOG)); + if (pPoint->wetness<0.0f) pPoint->wetness=0.0f; - /* - * Slowly "shift" paint from wet layer to dry layer as it drys: - */ - /* make sure alpha values are within proper range */ - CLAMP(pPoint->alpha, 0.0f, 1.0f); - CLAMP(pPoint->e_alpha, 0.0f, 1.0f); - - /* get current final blended color of these layers */ - blendColors(pPoint->color, pPoint->alpha, pPoint->e_color, pPoint->e_alpha, f_color); - /* reduce wet layer alpha by dry factor */ - pPoint->e_alpha *= dry_ratio; - - /* now calculate new alpha for dry layer that keeps final blended color unchanged */ - pPoint->alpha = (f_color[3] - pPoint->e_alpha)/(1.0f-pPoint->e_alpha); - /* for each rgb component, calculate a new dry layer color that keeps the final blend color - * with these new alpha values. (wet layer color doesnt change)*/ - if (pPoint->alpha) { - for (i=0; i<3; i++) { - pPoint->color[i] = (f_color[i]*f_color[3] - pPoint->e_color[i]*pPoint->e_alpha)/(pPoint->alpha*(1.0f-pPoint->e_alpha)); + if (pPoint->wetness < surface->color_dry_threshold) { + dry_ratio = pPoint->wetness/p_wetness; + + /* + * Slowly "shift" paint from wet layer to dry layer as it drys: + */ + /* make sure alpha values are within proper range */ + CLAMP(pPoint->alpha, 0.0f, 1.0f); + CLAMP(pPoint->e_alpha, 0.0f, 1.0f); + + /* get current final blended color of these layers */ + blendColors(pPoint->color, pPoint->alpha, pPoint->e_color, pPoint->e_alpha, f_color); + /* reduce wet layer alpha by dry factor */ + pPoint->e_alpha *= dry_ratio; + + /* now calculate new alpha for dry layer that keeps final blended color unchanged */ + pPoint->alpha = (f_color[3] - pPoint->e_alpha)/(1.0f-pPoint->e_alpha); + /* for each rgb component, calculate a new dry layer color that keeps the final blend color + * with these new alpha values. (wet layer color doesnt change)*/ + if (pPoint->alpha) { + for (i=0; i<3; i++) { + pPoint->color[i] = (f_color[i]*f_color[3] - pPoint->e_color[i]*pPoint->e_alpha)/(pPoint->alpha*(1.0f-pPoint->e_alpha)); + } + } } - } - pPoint->state = DPAINT_PAINT_WET; - } - /* in case of just dryed paint, just mix it to the dry layer and mark it empty */ - else if (pPoint->state > 0) { - float f_color[4]; - blendColors(pPoint->color, pPoint->alpha, pPoint->e_color, pPoint->e_alpha, f_color); - copy_v3_v3(pPoint->color, f_color); - pPoint->alpha = f_color[3]; - /* clear wet layer */ - pPoint->wetness = 0.0f; - pPoint->e_alpha = 0.0f; - pPoint->state = DPAINT_PAINT_DRY; + pPoint->state = DPAINT_PAINT_WET; + } + /* in case of just dryed paint, just mix it to the dry layer and mark it empty */ + else if (pPoint->state > 0) { + float f_color[4]; + blendColors(pPoint->color, pPoint->alpha, pPoint->e_color, pPoint->e_alpha, f_color); + copy_v3_v3(pPoint->color, f_color); + pPoint->alpha = f_color[3]; + /* clear wet layer */ + pPoint->wetness = 0.0f; + pPoint->e_alpha = 0.0f; + pPoint->state = DPAINT_PAINT_DRY; + } } if (surface->flags & MOD_DPAINT_DISSOLVE) { @@ -4647,7 +4645,7 @@ #pragma omp parallel for schedule(static) for (index=0; indextotal_points; index++) { - float prev_point[3]; + float prev_point[3] = {0.0f, 0.0f, 0.0f}; if (do_velocity_data && !new_bdata) { copy_v3_v3(prev_point, bData->realCoord[bData->s_pos[index]].v); } @@ -4747,8 +4745,8 @@ /* generate surface space partitioning grid */ surfaceGenerateGrid(surface); - /* calculate current frame neighbouring point distances and global dirs */ - dynamicPaint_prepareNeighbourData(surface, 0); + /* calculate current frame adjacency point distances and global dirs */ + dynamicPaint_prepareAdjacencyData(surface, 0); /* Copy current frame vertices to check against in next frame */ copy_m4_m4(bData->prev_obmat, ob->obmat); @@ -4831,7 +4829,7 @@ if (!sData->adj_data) dynamicPaint_initAdjacencyData(surface, 1); if (!bData->bNeighs) - dynamicPaint_prepareNeighbourData(surface, 1); + dynamicPaint_prepareAdjacencyData(surface, 1); } /* update object data on this subframe */ @@ -4929,7 +4927,7 @@ /* apply previous displace on derivedmesh if incremental surface */ if (surface->flags & MOD_DPAINT_DISP_INCREMENTAL) - dynamicPaint_applySurfaceDisplace(surface, surface->canvas->dm, 0); + dynamicPaint_applySurfaceDisplace(surface, surface->canvas->dm); /* update bake data */ dynamicPaint_generateBakeData(surface, scene, cObject); diff -Nru blender-2.61/source/blender/blenkernel/intern/fcurve.c blender-2.62/source/blender/blenkernel/intern/fcurve.c --- blender-2.61/source/blender/blenkernel/intern/fcurve.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/fcurve.c 2012-02-15 19:34:02.000000000 +0000 @@ -1283,7 +1283,7 @@ } else { /* worldspace matrix */ - mul_m4_m4m4(mat, pchan->pose_mat, ob->obmat); + mult_m4_m4m4(mat, ob->obmat, pchan->pose_mat); } } else { @@ -1414,10 +1414,7 @@ DRIVER_TARGETS_LOOPER_END /* remove the variable from the driver */ - if (driver) - BLI_freelinkN(&driver->variables, dvar); - else - MEM_freeN(dvar); + BLI_freelinkN(&driver->variables, dvar); #ifdef WITH_PYTHON /* since driver variables are cached, the expression needs re-compiling too */ @@ -1990,7 +1987,7 @@ for (a=0; prevbezt && bezt && (a < fcu->totvert-1); a++, prevbezt=bezt, bezt++) { /* use if the key is directly on the frame, rare cases this is needed else we get 0.0 instead. */ - if(fabs(bezt->vec[1][0] - evaltime) < SMALL_NUMBER) { + if(fabsf(bezt->vec[1][0] - evaltime) < SMALL_NUMBER) { cvalue= bezt->vec[1][1]; } /* evaltime occurs within the interval defined by these two keyframes */ diff -Nru blender-2.61/source/blender/blenkernel/intern/idcode.c blender-2.62/source/blender/blenkernel/intern/idcode.c --- blender-2.61/source/blender/blenkernel/intern/idcode.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/idcode.c 2012-02-15 19:34:02.000000000 +0000 @@ -58,7 +58,7 @@ { ID_ID, "ID", "ids", 0}, /* plural is fake */ { ID_IM, "Image", "images", IDTYPE_FLAGS_ISLINKABLE}, { ID_IP, "Ipo", "ipos", IDTYPE_FLAGS_ISLINKABLE}, /* deprecated */ - { ID_KE, "Key", "keys", 0}, + { ID_KE, "Key", "shape_keys", 0}, { ID_LA, "Lamp", "lamps", IDTYPE_FLAGS_ISLINKABLE}, { ID_LI, "Library", "libraries", 0}, { ID_LT, "Lattice", "lattices", IDTYPE_FLAGS_ISLINKABLE}, diff -Nru blender-2.61/source/blender/blenkernel/intern/idprop.c blender-2.62/source/blender/blenkernel/intern/idprop.c --- blender-2.61/source/blender/blenkernel/intern/idprop.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/idprop.c 2012-02-15 19:34:02.000000000 +0000 @@ -692,7 +692,11 @@ case IDP_ARRAY: { /*for now, we only support float and int and double arrays*/ - if (val->array.type == IDP_FLOAT || val->array.type == IDP_INT || val->array.type == IDP_DOUBLE || val->array.type == IDP_GROUP) { + if ( (val->array.type == IDP_FLOAT) || + (val->array.type == IDP_INT) || + (val->array.type == IDP_DOUBLE) || + (val->array.type == IDP_GROUP) ) + { prop = MEM_callocN(sizeof(IDProperty), "IDProperty array"); prop->subtype = val->array.type; if (val->array.len) diff -Nru blender-2.61/source/blender/blenkernel/intern/image.c blender-2.62/source/blender/blenkernel/intern/image.c --- blender-2.61/source/blender/blenkernel/intern/image.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/image.c 2012-02-15 19:34:02.000000000 +0000 @@ -285,6 +285,10 @@ break; ibuf->index= index; + if(ima->flag & IMA_CM_PREDIVIDE) + ibuf->flags |= IB_cm_predivide; + else + ibuf->flags &= ~IB_cm_predivide; /* this function accepts link==NULL */ BLI_insertlinkbefore(&ima->ibufs, link, ibuf); @@ -946,6 +950,7 @@ case R_IMF_IMTYPE_MULTILAYER: case R_IMF_IMTYPE_DDS: case R_IMF_IMTYPE_JP2: + case R_IMF_IMTYPE_QUICKTIME: chan_flag |= IMA_CHAN_FLAG_ALPHA; } @@ -1106,9 +1111,9 @@ if(BLI_testextensie_array(string, imb_ext_image) || (G.have_quicktime && BLI_testextensie_array(string, imb_ext_image_qt))) { return BLI_replace_extension(string, FILE_MAX, extension); - } else { + } + else { return BLI_ensure_extension(string, FILE_MAX, extension); - return TRUE; } } @@ -1164,7 +1169,7 @@ char *name = scene_find_last_marker_name(scene, CFRA); if (name) BLI_strncpy(text, name, sizeof(text)); - else strcpy(text, ""); + else BLI_strncpy(text, "", sizeof(text)); BLI_snprintf(stamp_data->marker, sizeof(stamp_data->marker), do_prefix ? "Marker %s":"%s", text); } else { @@ -1198,14 +1203,14 @@ } if (scene->r.stamp & R_STAMP_FRAME) { - char format[32]; + char fmtstr[32]; int digits= 1; if(scene->r.efra>9) digits= 1 + (int) log10(scene->r.efra); - BLI_snprintf(format, sizeof(format), do_prefix ? "Frame %%0%di":"%%0%di", digits); - BLI_snprintf (stamp_data->frame, sizeof(stamp_data->frame), format, scene->r.cfra); + BLI_snprintf(fmtstr, sizeof(fmtstr), do_prefix ? "Frame %%0%di":"%%0%di", digits); + BLI_snprintf (stamp_data->frame, sizeof(stamp_data->frame), fmtstr, scene->r.cfra); } else { stamp_data->frame[0] = '\0'; } @@ -1220,7 +1225,7 @@ if (camera && camera->type == OB_CAMERA) { BLI_snprintf(text, sizeof(text), "%.2f", ((Camera *)camera->data)->lens); } - else strcpy(text, ""); + else BLI_strncpy(text, "", sizeof(text)); BLI_snprintf(stamp_data->cameralens, sizeof(stamp_data->cameralens), do_prefix ? "Lens %s":"%s", text); } else { @@ -1237,7 +1242,7 @@ Sequence *seq= seq_foreground_frame_get(scene, scene->r.cfra); if (seq) BLI_strncpy(text, seq->name+2, sizeof(text)); - else strcpy(text, ""); + else BLI_strncpy(text, "", sizeof(text)); BLI_snprintf(stamp_data->strip, sizeof(stamp_data->strip), do_prefix ? "Strip %s":"%s", text); } else { @@ -1508,10 +1513,7 @@ int ok; - if(imtype == -1) { - /* use whatever existing image type is set by 'ibuf' */ - } - else if(imtype== R_IMF_IMTYPE_IRIS) { + if(imtype== R_IMF_IMTYPE_IRIS) { ibuf->ftype= IMAGIC; } #ifdef WITH_HDR @@ -1547,7 +1549,7 @@ ibuf->ftype= OPENEXR; if(imf->depth == R_IMF_CHAN_DEPTH_16) ibuf->ftype |= OPENEXR_HALF; - ibuf->ftype |= (quality & OPENEXR_COMPRESS); + ibuf->ftype |= (imf->exr_codec & OPENEXR_COMPRESS); if(!(imf->flag & R_IMF_FLAG_ZBUF)) ibuf->zbuf_float = NULL; /* signal for exr saving */ @@ -1606,7 +1608,7 @@ return(ok); } -/* same as BKE_write_ibuf_as but crappy workaround not to perminantly modify +/* same as BKE_write_ibuf() but crappy workaround not to perminantly modify * _some_, values in the imbuf */ int BKE_write_ibuf_as(ImBuf *ibuf, const char *name, ImageFormatData *imf, const short save_copy) @@ -2277,7 +2279,10 @@ ibuf->x= rres.rectx; ibuf->y= rres.recty; - if(ibuf->rect_float!=rectf || rect) /* ensure correct redraw */ + /* free rect buffer if float buffer changes, so it can be recreated with + the updated result, and also in case we got byte buffer from sequencer, + so we don't keep reference to freed buffer */ + if(ibuf->rect_float!=rectf || rect || !rectf) imb_freerectImBuf(ibuf); if(rect) @@ -2304,9 +2309,17 @@ /* since its possible to access the buffer from the image directly, set the profile [#25073] */ ibuf->profile= (iuser->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) ? IB_PROFILE_LINEAR_RGB : IB_PROFILE_NONE; - ibuf->dither= dither; + if(iuser->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE) { + ibuf->flags |= IB_cm_predivide; + ima->flag |= IMA_CM_PREDIVIDE; + } + else { + ibuf->flags &= ~IB_cm_predivide; + ima->flag &= ~IMA_CM_PREDIVIDE; + } + ima->ok= IMA_OK_LOADED; return ibuf; diff -Nru blender-2.61/source/blender/blenkernel/intern/image_gen.c blender-2.62/source/blender/blenkernel/intern/image_gen.c --- blender-2.61/source/blender/blenkernel/intern/image_gen.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/image_gen.c 2012-02-15 19:34:02.000000000 +0000 @@ -30,9 +30,10 @@ #include "BKE_image.h" #include "BLI_math_color.h" +#include "BLI_math_base.h" #include "BLF_api.h" -void BKE_image_buf_fill_color(unsigned char *rect, float *rect_float, int width, int height, float color[4]) +void BKE_image_buf_fill_color(unsigned char *rect, float *rect_float, int width, int height, const float color[4]) { int x, y; @@ -40,22 +41,17 @@ if(rect_float) { for(y= 0; yV, id->V, clmd->sim_parms->vel_damping, numverts); + // calculate forces cloth_calc_force(clmd, frame, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step, id->M); diff -Nru blender-2.61/source/blender/blenkernel/intern/ipo.c blender-2.62/source/blender/blenkernel/intern/ipo.c --- blender-2.61/source/blender/blenkernel/intern/ipo.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/ipo.c 2012-02-15 19:34:02.000000000 +0000 @@ -328,9 +328,9 @@ /* block will be attached to ID_KE block, and setting that we alter is the 'value' (which sets keyblock.curval) */ // XXX adrcode 0 was dummy 'speed' curve if (adrcode == 0) - sprintf(buf, "speed"); + strcpy(buf, "speed"); else - sprintf(buf, "key_blocks[%d].value", adrcode); + BLI_snprintf(buf, sizeof(buf), "key_blocks[%d].value", adrcode); return buf; } @@ -909,15 +909,18 @@ if (array_index) *array_index= dummy_index; } - + + /* 'buf' _must_ be initialized in this block */ /* append preceding bits to path */ + /* note, strings are not escapted and they should be! */ if ((actname && actname[0]) && (constname && constname[0])) { /* Constraint in Pose-Channel */ - sprintf(buf, "pose.bones[\"%s\"].constraints[\"%s\"]", actname, constname); + BLI_snprintf(buf, sizeof(buf), "pose.bones[\"%s\"].constraints[\"%s\"]", actname, constname); } else if (actname && actname[0]) { if ((blocktype == ID_OB) && strcmp(actname, "Object")==0) { /* Actionified "Object" IPO's... no extra path stuff needed */ + buf[0]= '\0'; /* empty string */ } else if ((blocktype == ID_KE) && strcmp(actname, "Shape")==0) { /* Actionified "Shape" IPO's - these are forced onto object level via the action container there... */ @@ -925,19 +928,21 @@ } else { /* Pose-Channel */ - sprintf(buf, "pose.bones[\"%s\"]", actname); + BLI_snprintf(buf, sizeof(buf), "pose.bones[\"%s\"]", actname); } } else if (constname && constname[0]) { /* Constraint in Object */ - sprintf(buf, "constraints[\"%s\"]", constname); + BLI_snprintf(buf, sizeof(buf), "constraints[\"%s\"]", constname); } else if (seq) { /* Sequence names in Scene */ - sprintf(buf, "sequence_editor.sequences_all[\"%s\"]", seq->name+2); + BLI_snprintf(buf, sizeof(buf), "sequence_editor.sequences_all[\"%s\"]", seq->name+2); } - else + else { buf[0]= '\0'; /* empty string */ + } + BLI_dynstr_append(path, buf); /* need to add dot before property if there was anything precceding this */ @@ -949,7 +954,7 @@ /* if there was no array index pointer provided, add it to the path */ if (array_index == NULL) { - sprintf(buf, "[\"%d\"]", dummy_index); + BLI_snprintf(buf, sizeof(buf), "[\"%d\"]", dummy_index); BLI_dynstr_append(path, buf); } diff -Nru blender-2.61/source/blender/blenkernel/intern/key.c blender-2.62/source/blender/blenkernel/intern/key.c --- blender-2.61/source/blender/blenkernel/intern/key.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/key.c 2012-02-15 19:34:02.000000000 +0000 @@ -377,7 +377,7 @@ if(k1->next==NULL) k[0]=k1; k1=k1->next; } - k1= k[1]; + /* k1= k[1]; */ /* UNUSED */ t[0]= k[0]->pos; t[1]+= dpos; t[2]= k[2]->pos + dpos; diff -Nru blender-2.61/source/blender/blenkernel/intern/lattice.c blender-2.62/source/blender/blenkernel/intern/lattice.c --- blender-2.61/source/blender/blenkernel/intern/lattice.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/lattice.c 2012-02-15 19:34:02.000000000 +0000 @@ -316,7 +316,7 @@ else { /* in deformspace, calc matrix */ invert_m4_m4(imat, oblatt->obmat); - mul_m4_m4m4(lt->latmat, ob->obmat, imat); + mult_m4_m4m4(lt->latmat, imat, ob->obmat); /* back: put in deform array */ invert_m4_m4(imat, lt->latmat); @@ -462,32 +462,25 @@ so we store in latmat transform from path coord inside object */ typedef struct { - float dmin[3], dmax[3], dscale, dloc[3]; + float dmin[3], dmax[3]; float curvespace[4][4], objectspace[4][4], objectspace3[3][3]; int no_rot_axis; } CurveDeform; -static void init_curve_deform(Object *par, Object *ob, CurveDeform *cd, int dloc) +static void init_curve_deform(Object *par, Object *ob, CurveDeform *cd) { invert_m4_m4(ob->imat, ob->obmat); - mul_m4_m4m4(cd->objectspace, par->obmat, ob->imat); + mult_m4_m4m4(cd->objectspace, ob->imat, par->obmat); invert_m4_m4(cd->curvespace, cd->objectspace); copy_m3_m4(cd->objectspace3, cd->objectspace); - - // offset vector for 'no smear' - if(dloc) { - invert_m4_m4(par->imat, par->obmat); - mul_v3_m4v3(cd->dloc, par->imat, ob->obmat[3]); - } - else { - cd->dloc[0]=cd->dloc[1]=cd->dloc[2]= 0.0f; - } - cd->no_rot_axis= 0; } -/* this makes sure we can extend for non-cyclic. *vec needs 4 items! */ -static int where_on_path_deform(Object *ob, float ctime, float *vec, float *dir, float *quat, float *radius) /* returns OK */ +/* this makes sure we can extend for non-cyclic. + * + * returns OK: 1/0 + */ +static int where_on_path_deform(Object *ob, float ctime, float vec[4], float dir[3], float quat[4], float *radius) { Curve *cu= ob->data; BevList *bl; @@ -532,20 +525,18 @@ return 0; } - /* for each point, rotate & translate to curve */ - /* use path, since it has constant distances */ - /* co: local coord, result local too */ - /* returns quaternion for rotation, using cd->no_rot_axis */ - /* axis is using another define!!! */ -static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, CurveDeform *cd, float *quatp) +/* for each point, rotate & translate to curve */ +/* use path, since it has constant distances */ +/* co: local coord, result local too */ +/* returns quaternion for rotation, using cd->no_rot_axis */ +/* axis is using another define!!! */ +static int calc_curve_deform(Scene *scene, Object *par, float co[3], + const short axis, CurveDeform *cd, float quat_r[4]) { Curve *cu= par->data; float fac, loc[4], dir[3], new_quat[4], radius; - short /*upflag, */ index; - - index= axis-1; - if(index>2) - index -= 3; /* negative */ + short index; + const int is_neg_axis = (axis > 2); /* to be sure, mostly after file load */ if(cu->path==NULL) { @@ -554,52 +545,24 @@ } /* options */ - if(ELEM3(axis, OB_NEGX+1, OB_NEGY+1, OB_NEGZ+1)) { /* OB_NEG# 0-5, MOD_CURVE_POS# 1-6 */ + if (is_neg_axis) { + index = axis - 3; if(cu->flag & CU_STRETCH) fac= (-co[index]-cd->dmax[index])/(cd->dmax[index] - cd->dmin[index]); else - fac= (cd->dloc[index])/(cu->path->totdist) - (co[index]-cd->dmax[index])/(cu->path->totdist); + fac= - (co[index]-cd->dmax[index])/(cu->path->totdist); } else { + index = axis; if(cu->flag & CU_STRETCH) fac= (co[index]-cd->dmin[index])/(cd->dmax[index] - cd->dmin[index]); else - fac= (cd->dloc[index])/(cu->path->totdist) + (co[index]-cd->dmin[index])/(cu->path->totdist); - } - -#if 0 // XXX old animation system - /* we want the ipo to work on the default 100 frame range, because there's no - actual time involved in path position */ - // huh? by WHY!!!!???? - Aligorith - if(cu->ipo) { - fac*= 100.0f; - if(calc_ipo_spec(cu->ipo, CU_SPEED, &fac)==0) - fac/= 100.0; + fac= + (co[index]-cd->dmin[index])/(cu->path->totdist); } -#endif // XXX old animation system if( where_on_path_deform(par, fac, loc, dir, new_quat, &radius)) { /* returns OK */ float quat[4], cent[3]; -#if 0 // XXX - 2.4x Z-Up, Now use bevel tilt. - if(cd->no_rot_axis) /* set by caller */ - dir[cd->no_rot_axis-1]= 0.0f; - - /* -1 for compatibility with old track defines */ - vec_to_quat( quat,dir, axis-1, upflag); - - /* the tilt */ - if(loc[3]!=0.0) { - normalize_v3(dir); - q[0]= (float)cos(0.5*loc[3]); - fac= (float)sin(0.5*loc[3]); - q[1]= -fac*dir[0]; - q[2]= -fac*dir[1]; - q[3]= -fac*dir[2]; - mul_qt_qtqt(quat, q, quat); - } -#endif - if(cd->no_rot_axis) { /* set by caller */ /* this is not exactly the same as 2.4x, since the axis is having rotation removed rather than @@ -634,9 +597,9 @@ /* zero the axis which is not used, * the big block of text above now applies to these 3 lines */ - quat_apply_track(quat, axis-1, (axis==1 || axis==3) ? 1:0); /* up flag is a dummy, set so no rotation is done */ - vec_apply_track(cent, axis-1); - cent[axis < 4 ? axis-1 : axis-4]= 0.0f; + quat_apply_track(quat, axis, (axis == 0 || axis == 2) ? 1:0); /* up flag is a dummy, set so no rotation is done */ + vec_apply_track(cent, axis); + cent[index]= 0.0f; /* scale if enabled */ @@ -650,8 +613,8 @@ /* translation */ add_v3_v3v3(co, cent, loc); - if(quatp) - copy_qt_qt(quatp, quat); + if(quat_r) + copy_qt_qt(quat_r, quat); return 1; } @@ -666,6 +629,7 @@ int a, flag; CurveDeform cd; int use_vgroups; + const int is_neg_axis = (defaxis > 2); if(cuOb->type != OB_CURVE) return; @@ -674,10 +638,10 @@ flag = cu->flag; cu->flag |= (CU_PATH|CU_FOLLOW); // needed for path & bevlist - init_curve_deform(cuOb, target, &cd, (cu->flag & CU_STRETCH)==0); + init_curve_deform(cuOb, target, &cd); /* dummy bounds, keep if CU_DEFORM_BOUNDS_OFF is set */ - if(defaxis < 3) { + if(is_neg_axis == FALSE) { cd.dmin[0]= cd.dmin[1]= cd.dmin[2]= 0.0f; cd.dmax[0]= cd.dmax[1]= cd.dmax[2]= 1.0f; } @@ -711,10 +675,6 @@ if(cu->flag & CU_DEFORM_BOUNDS_OFF) { - /* dummy bounds */ - cd.dmin[0]= cd.dmin[1]= cd.dmin[2]= 0.0f; - cd.dmax[0]= cd.dmax[1]= cd.dmax[2]= 1.0f; - dvert = me->dvert; for(a = 0; a < numVerts; a++, dvert++) { if(dm) dvert = dm->getVertData(dm, a, CD_MDEFORMVERT); @@ -749,6 +709,7 @@ weight= defvert_find_weight(dvert, index); if(weight > 0.0f) { + /* already in 'cd.curvespace', prev for loop */ copy_v3_v3(vec, vertexCos[a]); calc_curve_deform(scene, cuOb, vec, defaxis, &cd, NULL); interp_v3_v3v3(vertexCos[a], vertexCos[a], vec, weight); @@ -776,6 +737,7 @@ } for(a = 0; a < numVerts; a++) { + /* already in 'cd.curvespace', prev for loop */ calc_curve_deform(scene, cuOb, vertexCos[a], defaxis, &cd, NULL); mul_m4_v3(cd.objectspace, vertexCos[a]); } @@ -787,7 +749,8 @@ /* input vec and orco = local coord in armature space */ /* orco is original not-animated or deformed reference point */ /* result written in vec and mat */ -void curve_deform_vector(Scene *scene, Object *cuOb, Object *target, float *orco, float *vec, float mat[][3], int no_rot_axis) +void curve_deform_vector(Scene *scene, Object *cuOb, Object *target, + float orco[3], float vec[3], float mat[][3], int no_rot_axis) { CurveDeform cd; float quat[4]; @@ -797,7 +760,7 @@ return; } - init_curve_deform(cuOb, target, &cd, 0); /* 0 no dloc */ + init_curve_deform(cuOb, target, &cd); cd.no_rot_axis= no_rot_axis; /* option to only rotate for XY, for example */ copy_v3_v3(cd.dmin, orco); @@ -805,7 +768,7 @@ mul_m4_v3(cd.curvespace, vec); - if(calc_curve_deform(scene, cuOb, vec, target->trackflag+1, &cd, quat)) { + if(calc_curve_deform(scene, cuOb, vec, target->trackflag, &cd, quat)) { float qmat[3][3]; quat_to_mat3( qmat,quat); @@ -885,7 +848,7 @@ static BPoint *latt_bp(Lattice *lt, int u, int v, int w) { - return lt->def+ u + v*lt->pntsu + w*lt->pntsu*lt->pntsv; + return <->def[LT_INDEX(lt, u, v, w)]; } void outside_lattice(Lattice *lt) diff -Nru blender-2.61/source/blender/blenkernel/intern/library.c blender-2.62/source/blender/blenkernel/intern/library.c --- blender-2.61/source/blender/blenkernel/intern/library.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/library.c 2012-02-15 19:34:02.000000000 +0000 @@ -991,7 +991,7 @@ ID *id; for (i=0, id= lb->first; id; id= id->next, i++) { - char buf[32]; + char numstr[32]; if (nr && id==link) *nr= i+1; @@ -1002,12 +1002,12 @@ if ( ((Image *)id)->source==IMA_SRC_VIEWER ) continue; - get_flags_for_id(id, buf); + get_flags_for_id(id, numstr); - BLI_dynstr_append(pupds, buf); + BLI_dynstr_append(pupds, numstr); BLI_dynstr_append(pupds, id->name+2); - BLI_snprintf(buf, sizeof(buf), "%%x%d", i+1); - BLI_dynstr_append(pupds, buf); + BLI_snprintf(numstr, sizeof(numstr), "%%x%d", i+1); + BLI_dynstr_append(pupds, numstr); /* icon */ switch(GS(id->name)) @@ -1017,8 +1017,8 @@ case ID_IM: /* fall through */ case ID_WO: /* fall through */ case ID_LA: /* fall through */ - BLI_snprintf(buf, sizeof(buf), "%%i%d", BKE_icon_getid(id) ); - BLI_dynstr_append(pupds, buf); + BLI_snprintf(numstr, sizeof(numstr), "%%i%d", BKE_icon_getid(id) ); + BLI_dynstr_append(pupds, numstr); break; default: break; @@ -1136,10 +1136,12 @@ { ID *idtest; int nr= 0, nrtest, a, left_len; - char left[32], leftest[32], in_use[32]; + char in_use[64]; /* use as a boolean array, unrelated to name length */ + + char left[MAX_ID_NAME + 8], leftest[MAX_ID_NAME + 8]; /* make sure input name is terminated properly */ - /* if( strlen(name) > 21 ) name[21]= 0; */ + /* if( strlen(name) > MAX_ID_NAME-3 ) name[MAX_ID_NAME-3]= 0; */ /* removed since this is only ever called from one place - campbell */ while (1) { @@ -1151,20 +1153,20 @@ if( idtest == NULL ) return 0; /* we have a dup; need to make a new name */ - /* quick check so we can reuse one of first 32 ids if vacant */ + /* quick check so we can reuse one of first 64 ids if vacant */ memset(in_use, 0, sizeof(in_use)); /* get name portion, number portion ("name.number") */ left_len= BLI_split_name_num(left, &nr, name, '.'); /* if new name will be too long, truncate it */ - if(nr > 999 && left_len > 16) { - left[16]= 0; - left_len= 16; - } - else if(left_len > 17) { - left[17]= 0; - left_len= 17; + if(nr > 999 && left_len > (MAX_ID_NAME - 8)) { + left[MAX_ID_NAME - 8]= 0; + left_len= MAX_ID_NAME - 8; + } + else if(left_len > (MAX_ID_NAME - 7)) { + left[MAX_ID_NAME - 7]= 0; + left_len= MAX_ID_NAME - 7; } for(idtest= lb->first; idtest; idtest= idtest->next) { @@ -1206,11 +1208,11 @@ /* otherwise just continue and use a number suffix */ } - if(nr > 999 && left_len > 16) { + if(nr > 999 && left_len > (MAX_ID_NAME - 8)) { /* this would overflow name buffer */ - left[16] = 0; - /* left_len = 16; */ /* for now this isnt used again */ - memcpy(name, left, sizeof(char) * 17); + left[MAX_ID_NAME - 8] = 0; + /* left_len = MAX_ID_NAME - 8; */ /* for now this isnt used again */ + memcpy(name, left, sizeof(char) * (MAX_ID_NAME - 7)); continue; } /* this format specifier is from hell... */ @@ -1245,7 +1247,7 @@ strncpy(name, tname, sizeof(name)-1); - /* if result > 21, strncpy don't put the final '\0' to name. + /* if result > MAX_ID_NAME-3, strncpy don't put the final '\0' to name. * easier to assign each time then to check if its needed */ name[sizeof(name)-1]= 0; diff -Nru blender-2.61/source/blender/blenkernel/intern/material.c blender-2.62/source/blender/blenkernel/intern/material.c --- blender-2.61/source/blender/blenkernel/intern/material.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/material.c 2012-02-15 19:34:02.000000000 +0000 @@ -51,6 +51,7 @@ #include "BLI_listbase.h" #include "BLI_utildefines.h" #include "BLI_bpath.h" +#include "BLI_string.h" #include "BKE_animsys.h" #include "BKE_displist.h" @@ -903,7 +904,7 @@ /* always get derivatives for these textures */ if ELEM3(mtex->tex->type, TEX_IMAGE, TEX_PLUGIN, TEX_ENVMAP) ma->texco |= TEXCO_OSA; - else if(mtex->texflag & (MTEX_COMPAT_BUMP|MTEX_3TAP_BUMP|MTEX_5TAP_BUMP)) ma->texco |= TEXCO_OSA; + else if(mtex->texflag & (MTEX_COMPAT_BUMP|MTEX_3TAP_BUMP|MTEX_5TAP_BUMP|MTEX_BICUBIC_BUMP)) ma->texco |= TEXCO_OSA; if(ma->texco & (TEXCO_ORCO|TEXCO_REFL|TEXCO_NORM|TEXCO_STRAND|TEXCO_STRESS)) needuv= 1; else if(ma->texco & (TEXCO_GLOB|TEXCO_UV|TEXCO_OBJECT|TEXCO_SPEED)) needuv= 1; @@ -1614,7 +1615,7 @@ int digits = integer_getdigits(flag); /* clamp the old name, remove the MA prefix and add the .TF.flag suffix e.g. matname = "MALoooooooooooooongName"; newname = "Loooooooooooooon.TF.2" */ - sprintf(newname, "%.*s.TF.%0*d", MAX_ID_NAME-(digits+5), matname, digits, flag); + BLI_snprintf(newname, MAX_ID_NAME, "%.*s.TF.%0*d", MAX_ID_NAME-(digits+5), matname, digits, flag); } /* returns -1 if no match */ @@ -1661,8 +1662,8 @@ short mat_nr= -1; /* new material, the name uses the flag*/ - sprintf(idname, "MAMaterial.TF.%0*d", integer_getdigits(flag), flag); - + BLI_snprintf(idname, sizeof(idname), "MAMaterial.TF.%0*d", integer_getdigits(flag), flag); + if ((ma= BLI_findstring(&main->mat, idname+2, offsetof(ID, name)+2))) { mat_nr= mesh_getmaterialnumber(me, ma); /* assign the material to the mesh */ diff -Nru blender-2.61/source/blender/blenkernel/intern/mball.c blender-2.62/source/blender/blenkernel/intern/mball.c --- blender-2.61/source/blender/blenkernel/intern/mball.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/mball.c 2012-02-15 19:34:02.000000000 +0000 @@ -356,7 +356,7 @@ int is_mball_basis_for(Object *ob1, Object *ob2) { int basis1nr, basis2nr; - char basis1name[32], basis2name[32]; + char basis1name[MAX_ID_NAME], basis2name[MAX_ID_NAME]; BLI_split_name_num(basis1name, &basis1nr, ob1->id.name+2, '.'); BLI_split_name_num(basis2name, &basis2nr, ob2->id.name+2, '.'); @@ -378,7 +378,7 @@ Object *ob; MetaBall *active_mball = (MetaBall*)active_object->data; int basisnr, obnr; - char basisname[32], obname[32]; + char basisname[MAX_ID_NAME], obname[MAX_ID_NAME]; BLI_split_name_num(basisname, &basisnr, active_object->id.name+2, '.'); @@ -423,7 +423,7 @@ Object *ob,*bob= basis; MetaElem *ml=NULL; int basisnr, obnr; - char basisname[32], obname[32]; + char basisname[MAX_ID_NAME], obname[MAX_ID_NAME]; BLI_split_name_num(basisname, &basisnr, basis->id.name+2, '.'); totelem= 0; @@ -1596,7 +1596,7 @@ float size, totsize, obinv[4][4], obmat[4][4], vec[3]; //float max=0.0; int a, obnr, zero_size=0; - char obname[32]; + char obname[MAX_ID_NAME]; copy_m4_m4(obmat, ob->obmat); /* to cope with duplicators from next_object */ invert_m4_m4(obinv, ob->obmat); @@ -1619,7 +1619,7 @@ else ml= mb->elems.first; } else { - char name[32]; + char name[MAX_ID_NAME]; int nr; BLI_split_name_num(name, &nr, bob->id.name+2, '.'); @@ -1679,7 +1679,7 @@ temp2[3][1]= ml->y; temp2[3][2]= ml->z; - mul_m4_m4m4(temp1, temp3, temp2); + mult_m4_m4m4(temp1, temp2, temp3); /* make a copy because of duplicates */ mainb[a]= new_pgn_element(sizeof(MetaElem)); @@ -1691,9 +1691,9 @@ /* mat is the matrix to transform from mball into the basis-mball */ invert_m4_m4(obinv, obmat); - mul_m4_m4m4(temp2, bob->obmat, obinv); + mult_m4_m4m4(temp2, obinv, bob->obmat); /* MetaBall transformation */ - mul_m4_m4m4(mat, temp1, temp2); + mult_m4_m4m4(mat, temp2, temp1); invert_m4_m4(imat,mat); diff -Nru blender-2.61/source/blender/blenkernel/intern/mesh.c blender-2.62/source/blender/blenkernel/intern/mesh.c --- blender-2.61/source/blender/blenkernel/intern/mesh.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/mesh.c 2012-02-15 19:34:02.000000000 +0000 @@ -42,12 +42,12 @@ #include "DNA_meshdata_types.h" #include "DNA_ipo_types.h" +#include "BLI_utildefines.h" #include "BLI_blenlib.h" #include "BLI_bpath.h" #include "BLI_editVert.h" #include "BLI_math.h" #include "BLI_edgehash.h" -#include "BLI_utildefines.h" #include "BKE_animsys.h" #include "BKE_main.h" @@ -65,6 +65,10 @@ /* -- */ #include "BKE_object.h" +#ifdef USE_BMESH_FORWARD_COMPAT +#include "BLI_array.h" +#endif + EditMesh *BKE_mesh_get_editmesh(Mesh *me) { @@ -366,9 +370,9 @@ tex_space_mesh(me); } - if (loc_r) VECCOPY(loc_r, me->loc); - if (rot_r) VECCOPY(rot_r, me->rot); - if (size_r) VECCOPY(size_r, me->size); + if (loc_r) copy_v3_v3(loc_r, me->loc); + if (rot_r) copy_v3_v3(rot_r, me->rot); + if (size_r) copy_v3_v3(size_r, me->size); } float *get_mesh_orco_verts(Object *ob) @@ -466,8 +470,8 @@ if(mface->v3==0) { static int corner_indices[4] = {1, 2, 0, 3}; - SWAP(int, mface->v1, mface->v2); - SWAP(int, mface->v2, mface->v3); + SWAP(unsigned int, mface->v1, mface->v2); + SWAP(unsigned int, mface->v2, mface->v3); if(fdata) CustomData_swap(fdata, mfindex, corner_indices); @@ -477,8 +481,8 @@ if(mface->v3==0 || mface->v4==0) { static int corner_indices[4] = {2, 3, 0, 1}; - SWAP(int, mface->v1, mface->v3); - SWAP(int, mface->v2, mface->v4); + SWAP(unsigned int, mface->v1, mface->v3); + SWAP(unsigned int, mface->v2, mface->v4); if(fdata) CustomData_swap(fdata, mfindex, corner_indices); @@ -520,12 +524,14 @@ /* ************** make edges in a Mesh, for outside of editmode */ struct edgesort { - int v1, v2; + unsigned int v1, v2; short is_loose, is_draw; }; /* edges have to be added with lowest index first for sorting */ -static void to_edgesort(struct edgesort *ed, int v1, int v2, short is_loose, short is_draw) +static void to_edgesort(struct edgesort *ed, + unsigned int v1, unsigned int v2, + short is_loose, short is_draw) { if(v1v1= v1; ed->v2= v2; @@ -627,7 +633,7 @@ /* order is swapped so extruding this edge as a surface wont flip face normals * with cyclic curves */ if(ed->v1+1 != ed->v2) { - SWAP(int, medge->v1, medge->v2); + SWAP(unsigned int, medge->v1, medge->v2); } medge++; } @@ -724,7 +730,7 @@ nors= dl->nors; verts= dl->verts; while(a--) { - VECCOPY(mvert->co, verts); + copy_v3_v3(mvert->co, verts); normal_float_to_short_v3(mvert->no, nors); mvert++; nors+= 3; @@ -823,7 +829,7 @@ a= dl->parts*dl->nr; data= dl->verts; while(a--) { - VECCOPY(mvert->co, data); + copy_v3_v3(mvert->co, data); data+=3; vertcount++; mvert++; @@ -846,7 +852,7 @@ a= dl->parts*dl->nr; data= dl->verts; while(a--) { - VECCOPY(mvert->co, data); + copy_v3_v3(mvert->co, data); data+=3; vertcount++; mvert++; @@ -869,7 +875,7 @@ a= dl->nr; data= dl->verts; while(a--) { - VECCOPY(mvert->co, data); + copy_v3_v3(mvert->co, data); data+=3; vertcount++; mvert++; @@ -897,7 +903,7 @@ a= dl->parts*dl->nr; data= dl->verts; while(a--) { - VECCOPY(mvert->co, data); + copy_v3_v3(mvert->co, data); data+=3; vertcount++; mvert++; @@ -986,8 +992,8 @@ me->totedge= totedge; me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, allvert, me->totvert); - me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN, allface, me->totface); me->medge= CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, alledge, me->totedge); + me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN, allface, me->totface); mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL); } else { @@ -1029,17 +1035,17 @@ typedef struct VertLink { Link *next, *prev; - int index; + unsigned int index; } VertLink; -static void prependPolyLineVert(ListBase *lb, int index) +static void prependPolyLineVert(ListBase *lb, unsigned int index) { VertLink *vl= MEM_callocN(sizeof(VertLink), "VertLink"); vl->index = index; BLI_addhead(lb, vl); } -static void appendPolyLineVert(ListBase *lb, int index) +static void appendPolyLineVert(ListBase *lb, unsigned int index) { VertLink *vl= MEM_callocN(sizeof(VertLink), "VertLink"); vl->index = index; @@ -1111,8 +1117,8 @@ int closed = FALSE; int totpoly= 0; MEdge *med_current= ((EdgeLink *)edges.last)->edge; - int startVert= med_current->v1; - int endVert= med_current->v2; + unsigned int startVert= med_current->v1; + unsigned int endVert= med_current->v2; int ok= TRUE; appendPolyLineVert(&polyline, startVert); totpoly++; @@ -1242,8 +1248,6 @@ mf->flag &= ~ME_SMOOTH; } } - - mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL); } void mesh_calc_normals(MVert *mverts, int numVerts, MFace *mfaces, int numFaces, float (*faceNors_r)[3]) @@ -1288,11 +1292,11 @@ { int i, numVerts = me->totvert; float (*cos)[3] = MEM_mallocN(sizeof(*cos)*numVerts, "vertexcos1"); - + if (numVerts_r) *numVerts_r = numVerts; for (i=0; imvert[i].co); - + copy_v3_v3(cos[i], me->mvert[i].co); + return cos; } @@ -1311,7 +1315,7 @@ for(a=0; aflag & ME_HIDE) && (mf->flag & ME_FACE_SEL))) totuv += (mf->v4)? 4: 3; - + if(totuv==0) return NULL; @@ -1443,6 +1447,184 @@ } } +#ifdef USE_BMESH_FORWARD_COMPAT + +void mesh_loops_to_mface_corners(CustomData *fdata, CustomData *ldata, + CustomData *pdata, int lindex[4], int findex, + const int polyindex, + const int mf_len, /* 3 or 4 */ + + /* cache values to avoid lookups every time */ + const int numTex, /* CustomData_number_of_layers(pdata, CD_MTEXPOLY) */ + const int numCol, /* CustomData_number_of_layers(ldata, CD_MLOOPCOL) */ + const int hasWCol /* CustomData_has_layer(ldata, CD_WEIGHT_MLOOPCOL) */ + ) +{ + MTFace *texface; + MTexPoly *texpoly; + MCol *mcol; + MLoopCol *mloopcol; + MLoopUV *mloopuv; + int i, j; + + for(i=0; i < numTex; i++){ + texface = CustomData_get_n(fdata, CD_MTFACE, findex, i); + texpoly = CustomData_get_n(pdata, CD_MTEXPOLY, polyindex, i); + + texface->tpage = texpoly->tpage; + texface->flag = texpoly->flag; + texface->transp = texpoly->transp; + texface->mode = texpoly->mode; + texface->tile = texpoly->tile; + texface->unwrap = texpoly->unwrap; + + for (j=0; j < mf_len; j++) { + mloopuv = CustomData_get_n(ldata, CD_MLOOPUV, lindex[j], i); + texface->uv[j][0] = mloopuv->uv[0]; + texface->uv[j][1] = mloopuv->uv[1]; + } + } + + for(i=0; i < numCol; i++){ + mcol = CustomData_get_n(fdata, CD_MCOL, findex, i); + + for (j=0; j < mf_len; j++) { + mloopcol = CustomData_get_n(ldata, CD_MLOOPCOL, lindex[j], i); + mcol[j].r = mloopcol->r; + mcol[j].g = mloopcol->g; + mcol[j].b = mloopcol->b; + mcol[j].a = mloopcol->a; + } + } + + if (hasWCol) { + mcol = CustomData_get(fdata, findex, CD_WEIGHT_MCOL); + + for (j=0; j < mf_len; j++) { + mloopcol = CustomData_get(ldata, lindex[j], CD_WEIGHT_MLOOPCOL); + mcol[j].r = mloopcol->r; + mcol[j].g = mloopcol->g; + mcol[j].b = mloopcol->b; + mcol[j].a = mloopcol->a; + } + } +} + + +/* + * this function recreates a tesselation. + * returns number of tesselation faces. + */ +int mesh_mpoly_to_mface(struct CustomData *fdata, struct CustomData *ldata, + struct CustomData *pdata, int totface, int UNUSED(totloop), int totpoly) +{ + MLoop *mloop; + + int lindex[4]; + int i; + int k; + + MPoly *mp, *mpoly; + MFace *mface = NULL, *mf; + BLI_array_declare(mface); + + const int numTex = CustomData_number_of_layers(pdata, CD_MTEXPOLY); + const int numCol = CustomData_number_of_layers(ldata, CD_MLOOPCOL); + const int hasWCol = CustomData_has_layer(ldata, CD_WEIGHT_MLOOPCOL); + + mpoly = CustomData_get_layer(pdata, CD_MPOLY); + mloop = CustomData_get_layer(ldata, CD_MLOOP); + + mp = mpoly; + k = 0; + for (i = 0; itotloop, 3, 4)) { + BLI_array_growone(mface); + mf = &mface[k]; + + mf->mat_nr = mp->mat_nr; + mf->flag = mp->flag; + + mf->v1 = mp->loopstart + 0; + mf->v2 = mp->loopstart + 1; + mf->v3 = mp->loopstart + 2; + mf->v4 = (mp->totloop == 4) ? (mp->loopstart + 3) : 0; + + /* abuse edcode for temp storage and clear next loop */ + mf->edcode = (char)mp->totloop; /* only ever 3 or 4 */ + + k++; + } + } + + CustomData_free(fdata, totface); + memset(fdata, 0, sizeof(CustomData)); + + totface= k; + + CustomData_add_layer(fdata, CD_MFACE, CD_ASSIGN, mface, totface); + + CustomData_from_bmeshpoly(fdata, pdata, ldata, totface); + + mp = mpoly; + k = 0; + for (i = 0; itotloop, 3, 4)) { + mf = &mface[k]; + + if (mf->edcode == 3) { + /*sort loop indices to ensure winding is correct*/ + /* NO SORT - looks like we can skip this */ + + lindex[0] = mf->v1; + lindex[1] = mf->v2; + lindex[2] = mf->v3; + lindex[3] = 0; /* unused */ + + /*transform loop indices to vert indices*/ + mf->v1 = mloop[mf->v1].v; + mf->v2 = mloop[mf->v2].v; + mf->v3 = mloop[mf->v3].v; + + mesh_loops_to_mface_corners(fdata, ldata, pdata, + lindex, k, i, 3, + numTex, numCol, hasWCol); + test_index_face(mf, fdata, k, 3); + } + else { + /*sort loop indices to ensure winding is correct*/ + /* NO SORT - looks like we can skip this */ + + lindex[0] = mf->v1; + lindex[1] = mf->v2; + lindex[2] = mf->v3; + lindex[3] = mf->v4; + + /*transform loop indices to vert indices*/ + mf->v1 = mloop[mf->v1].v; + mf->v2 = mloop[mf->v2].v; + mf->v3 = mloop[mf->v3].v; + mf->v4 = mloop[mf->v4].v; + + mesh_loops_to_mface_corners(fdata, ldata, pdata, + lindex, k, i, 4, + numTex, numCol, hasWCol); + test_index_face(mf, fdata, k, 4); + } + + mf->edcode= 0; + + k++; + } + } + + return k; +} + +#endif /* USE_BMESH_FORWARD_COMPAT */ + + + /* basic vertex data functions */ int minmax_mesh(Mesh *me, float min[3], float max[3]) { diff -Nru blender-2.61/source/blender/blenkernel/intern/mesh_validate.c blender-2.62/source/blender/blenkernel/intern/mesh_validate.c --- blender-2.61/source/blender/blenkernel/intern/mesh_validate.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/mesh_validate.c 2012-02-15 19:34:02.000000000 +0000 @@ -395,7 +395,7 @@ while(itotlayer) { CustomDataLayer *layer= &data->layers[i]; - int mask= 1 << layer->type; + CustomDataMask mask= CD_TYPE_AS_MASK(layer->type); int ok= 1; if((mask&CD_MASK_MESH)==0) { @@ -509,7 +509,7 @@ if(update && (med_orig=BLI_edgehashIterator_getValue(ehi))) { *med= *med_orig; /* copy from the original */ } else { - BLI_edgehashIterator_getKey(ehi, (int*)&med->v1, (int*)&med->v2); + BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2); med->flag = ME_EDGEDRAW|ME_EDGERENDER|SELECT; /* select for newly created meshes which are selected [#25595] */ } } diff -Nru blender-2.61/source/blender/blenkernel/intern/modifier.c blender-2.62/source/blender/blenkernel/intern/modifier.c --- blender-2.61/source/blender/blenkernel/intern/modifier.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/modifier.c 2012-02-15 19:34:02.000000000 +0000 @@ -142,6 +142,19 @@ (mti->flags & eModifierTypeFlag_SupportsMapping)); } +int modifier_isPreview(ModifierData *md) +{ + ModifierTypeInfo *mti = modifierType_getInfo(md->type); + + if (!(mti->flags & eModifierTypeFlag_UsesPreview)) + return FALSE; + + if (md->mode & eModifierMode_Realtime) + return TRUE; + + return FALSE; +} + ModifierData *modifiers_findByType(Object *ob, ModifierType type) { ModifierData *md = ob->modifiers.first; @@ -239,7 +252,14 @@ int modifier_sameTopology(ModifierData *md) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); - return ( mti->type == eModifierTypeType_OnlyDeform || mti->type == eModifierTypeType_Nonconstructive); + return ELEM3(mti->type, eModifierTypeType_OnlyDeform, eModifierTypeType_Nonconstructive, + eModifierTypeType_NonGeometrical); +} + +int modifier_nonGeometrical(ModifierData *md) +{ + ModifierTypeInfo *mti = modifierType_getInfo(md->type); + return (mti->type == eModifierTypeType_NonGeometrical); } void modifier_setError(ModifierData *md, const char *format, ...) @@ -378,6 +398,21 @@ return dataMasks; } +ModifierData *modifiers_getLastPreview(struct Scene *scene, ModifierData *md, int required_mode) +{ + ModifierData *tmp_md = NULL; + + if (required_mode != eModifierMode_Realtime) + return tmp_md; + + /* Find the latest modifier in stack generating preview. */ + for(; md; md = md->next) { + if(modifier_isEnabled(scene, md, required_mode) && modifier_isPreview(md)) + tmp_md = md; + } + return tmp_md; +} + ModifierData *modifiers_getVirtualModifierList(Object *ob) { /* Kinda hacky, but should be fine since we are never @@ -538,6 +573,20 @@ return 0; } +/* Check whether the given object has a modifier in its stack that uses WEIGHT_MCOL CD layer + * to preview something... Used by DynamicPaint and WeightVG currently. */ +int modifiers_isPreview(Object *ob) +{ + ModifierData *md = ob->modifiers.first; + + for (; md; md = md->next) { + if (modifier_isPreview(md)) + return TRUE; + } + + return FALSE; +} + int modifiers_indexInObject(Object *ob, ModifierData *md_seek) { int i= 0; diff -Nru blender-2.61/source/blender/blenkernel/intern/movieclip.c blender-2.62/source/blender/blenkernel/intern/movieclip.c --- blender-2.61/source/blender/blenkernel/intern/movieclip.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/movieclip.c 2012-02-15 19:34:02.000000000 +0000 @@ -257,18 +257,30 @@ /* regular movie cache */ struct MovieCache *moviecache; - /* cache for stable shot */ - int stable_framenr; - float stable_loc[2], stable_scale, stable_angle; - ImBuf *stableibuf; - int proxy; - short render_flag; + /* cached postprocessed shot */ + struct { + ImBuf *ibuf; + int framenr; + int flag; + + /* cache for undistorted shot */ + float principal[2]; + float k1, k2, k3; + short undistoriton_used; + + int proxy; + short render_flag; + } postprocessed; - /* cache for undistorted shot */ - int undist_framenr; - float principal[2]; - float k1, k2, k3; - ImBuf *undistibuf; + /* cache for stable shot */ + struct { + ImBuf *ibuf; + int framenr; + + float loc[2], scale, angle; + int proxy; + short render_flag; + } stabilized; } MovieClipCache; typedef struct MovieClipImBufCacheKey { @@ -372,7 +384,10 @@ BKE_tracking_init_settings(&clip->tracking); clip->proxy.build_size_flag= IMB_PROXY_25; - clip->proxy.build_tc_flag= IMB_TC_RECORD_RUN|IMB_TC_FREE_RUN|IMB_TC_INTERPOLATED_REC_DATE_FREE_RUN; + clip->proxy.build_tc_flag= IMB_TC_RECORD_RUN | + IMB_TC_FREE_RUN | + IMB_TC_INTERPOLATED_REC_DATE_FREE_RUN | + IMB_TC_RECORD_RUN_NO_GAPS; clip->proxy.quality= 90; return clip; @@ -462,111 +477,180 @@ } } -static int need_undistorted_cache(MovieClipUser *user, int flag) +static ImBuf *get_undistorted_ibuf(MovieClip *clip, struct MovieDistortion *distortion, ImBuf *ibuf) +{ + ImBuf *undistibuf; + + /* XXX: because of #27997 do not use float buffers to undistort, + otherwise, undistorted proxy can be darker than it should */ + imb_freerectfloatImBuf(ibuf); + + if(distortion) + undistibuf= BKE_tracking_distortion_exec(distortion, &clip->tracking, ibuf, ibuf->x, ibuf->y, 0.0f, 1); + else + undistibuf= BKE_tracking_undistort(&clip->tracking, ibuf, ibuf->x, ibuf->y, 0.0f); + + if(undistibuf->userflags&IB_RECT_INVALID) { + ibuf->userflags&= ~IB_RECT_INVALID; + IMB_rect_from_float(undistibuf); + } + + IMB_scaleImBuf(undistibuf, ibuf->x, ibuf->y); + + return undistibuf; +} + +static int need_undistortion_postprocess(MovieClipUser *user, int flag) { + int result = 0; + /* only full undistorted render can be used as on-fly undistorting image */ - if(flag&MCLIP_USE_PROXY) { - if(user->render_size != MCLIP_PROXY_RENDER_SIZE_FULL || (user->render_flag&MCLIP_PROXY_RENDER_UNDISTORT)==0) - return 0; + if(flag & MCLIP_USE_PROXY) { + result |= (user->render_size == MCLIP_PROXY_RENDER_SIZE_FULL) && + (user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT) != 0; } - else return 0; - return 1; + return result; +} + +static int need_postprocessed_frame(MovieClipUser *user, int flag, int postprocess_flag) +{ + int result = postprocess_flag; + + result |= need_undistortion_postprocess(user, flag); + + return result; } -static ImBuf *get_undistorted_cache(MovieClip *clip, MovieClipUser *user) +static int check_undistortion_cache_flags(MovieClip *clip) { MovieClipCache *cache= clip->cache; MovieTrackingCamera *camera= &clip->tracking.camera; + + /* check for distortion model changes */ + if(!equals_v2v2(camera->principal, cache->postprocessed.principal)) + return 0; + + if(!equals_v3v3(&camera->k1, &cache->postprocessed.k1)) + return 0; + + return 1; +} + +static ImBuf *get_postprocessed_cached_frame(MovieClip *clip, MovieClipUser *user, int flag, int postprocess_flag) +{ + MovieClipCache *cache= clip->cache; int framenr= user->framenr; + short proxy= IMB_PROXY_NONE; + int render_flag= 0; + + if(flag&MCLIP_USE_PROXY) { + proxy= rendersize_to_proxy(user, flag); + render_flag= user->render_flag; + } - /* no cache or no cached undistorted image */ - if(!clip->cache || !clip->cache->undistibuf) + /* no cache or no cached postprocessed image */ + if(!clip->cache || !clip->cache->postprocessed.ibuf) return NULL; - /* undistortion happened for other frame */ - if(cache->undist_framenr!=framenr) + /* postprocessing happened for other frame */ + if(cache->postprocessed.framenr != framenr) return NULL; - /* check for distortion model changes */ - if(!equals_v2v2(camera->principal, cache->principal)) + /* cached ibuf used different proxy settings */ + if(cache->postprocessed.render_flag != render_flag || cache->postprocessed.proxy != proxy) + return NULL; + + if(cache->postprocessed.flag != postprocess_flag) return NULL; - if(!equals_v3v3(&camera->k1, &cache->k1)) + if(need_undistortion_postprocess(user, flag)) { + if(!check_undistortion_cache_flags(clip)) + return NULL; + } + else if(cache->postprocessed.undistoriton_used) return NULL; - IMB_refImBuf(cache->undistibuf); + IMB_refImBuf(cache->postprocessed.ibuf); - return cache->undistibuf; + return cache->postprocessed.ibuf; } -static ImBuf *get_undistorted_ibuf(MovieClip *clip, struct MovieDistortion *distortion, ImBuf *ibuf) +static ImBuf *put_postprocessed_frame_to_cache(MovieClip *clip, MovieClipUser *user, ImBuf *ibuf, int flag, int postprocess_flag) { - ImBuf *undistibuf; + MovieClipCache *cache= clip->cache; + MovieTrackingCamera *camera= &clip->tracking.camera; + ImBuf *postproc_ibuf = NULL; - /* XXX: because of #27997 do not use float buffers to undistort, - otherwise, undistorted proxy can be darker than it should */ - imb_freerectfloatImBuf(ibuf); + if(cache->postprocessed.ibuf) + IMB_freeImBuf(cache->postprocessed.ibuf); - if(distortion) - undistibuf= BKE_tracking_distortion_exec(distortion, &clip->tracking, ibuf, ibuf->x, ibuf->y, 0.0f, 1); - else - undistibuf= BKE_tracking_undistort(&clip->tracking, ibuf, ibuf->x, ibuf->y, 0.0f); + cache->postprocessed.framenr= user->framenr; + cache->postprocessed.flag = postprocess_flag; - if(undistibuf->userflags&IB_RECT_INVALID) { - ibuf->userflags&= ~IB_RECT_INVALID; - IMB_rect_from_float(undistibuf); + if(flag&MCLIP_USE_PROXY) { + cache->postprocessed.proxy= rendersize_to_proxy(user, flag); + cache->postprocessed.render_flag= user->render_flag; + } + else { + cache->postprocessed.proxy = IMB_PROXY_NONE; + cache->postprocessed.render_flag = 0; } - IMB_scaleImBuf(undistibuf, ibuf->x, ibuf->y); + if(need_undistortion_postprocess(user, flag)) { + copy_v2_v2(cache->postprocessed.principal, camera->principal); + copy_v3_v3(&cache->postprocessed.k1, &camera->k1); + cache->postprocessed.undistoriton_used = 1; + postproc_ibuf= get_undistorted_ibuf(clip, NULL, ibuf); + } + else cache->postprocessed.undistoriton_used = 0; - return undistibuf; -} + if(postprocess_flag) { + int disable_red = postprocess_flag & MOVIECLIP_DISABLE_RED, + disable_green = postprocess_flag & MOVIECLIP_DISABLE_GREEN, + disable_blue = postprocess_flag & MOVIECLIP_DISABLE_BLUE, + grayscale = postprocess_flag & MOVIECLIP_PREVIEW_GRAYSCALE; -static ImBuf *put_undistorted_cache(MovieClip *clip, MovieClipUser *user, ImBuf *ibuf) -{ - MovieClipCache *cache= clip->cache; - MovieTrackingCamera *camera= &clip->tracking.camera; + if(!postproc_ibuf) + postproc_ibuf = IMB_dupImBuf(ibuf); - copy_v2_v2(cache->principal, camera->principal); - copy_v3_v3(&cache->k1, &camera->k1); - cache->undist_framenr= user->framenr; + if(disable_red || disable_green || disable_blue || grayscale) + BKE_tracking_disable_imbuf_channels(postproc_ibuf, disable_red, disable_green, disable_blue, 1); + } - if(cache->undistibuf) - IMB_freeImBuf(cache->undistibuf); + IMB_refImBuf(postproc_ibuf); - cache->undistibuf= get_undistorted_ibuf(clip, NULL, ibuf); + cache->postprocessed.ibuf= postproc_ibuf; - if(cache->stableibuf) { + if(cache->stabilized.ibuf) { /* force stable buffer be re-calculated */ - IMB_freeImBuf(cache->stableibuf); - cache->stableibuf= NULL; + IMB_freeImBuf(cache->stabilized.ibuf); + cache->stabilized.ibuf= NULL; } - IMB_refImBuf(cache->undistibuf); - - return cache->undistibuf; + return postproc_ibuf; } -ImBuf *BKE_movieclip_get_ibuf(MovieClip *clip, MovieClipUser *user) +static ImBuf *movieclip_get_postprocessed_ibuf(MovieClip *clip, MovieClipUser *user, int flag, + int postprocess_flag, int cache_flag) { ImBuf *ibuf= NULL; - int framenr= user->framenr; - int cache_undistorted= 0; + int framenr= user->framenr, need_postprocess= 0; /* cache isn't threadsafe itself and also loading of movies can't happen from concurent threads that's why we use lock here */ BLI_lock_thread(LOCK_MOVIECLIP); - /* try to obtain cached undistorted image first */ - if(need_undistorted_cache(user, clip->flag)) { - ibuf= get_undistorted_cache(clip, user); + /* try to obtain cached postprocessed frame first */ + if(need_postprocessed_frame(user, flag, postprocess_flag)) { + ibuf= get_postprocessed_cached_frame(clip, user, flag, postprocess_flag); + if(!ibuf) - cache_undistorted= 1; + need_postprocess= 1; } if(!ibuf) - ibuf= get_imbuf_cache(clip, user, clip->flag); + ibuf= get_imbuf_cache(clip, user, flag); if(!ibuf) { int use_sequence= 0; @@ -576,23 +660,23 @@ (user->render_size!=MCLIP_PROXY_RENDER_SIZE_FULL); if(clip->source==MCLIP_SRC_SEQUENCE || use_sequence) - ibuf= movieclip_load_sequence_file(clip, user, framenr, clip->flag); + ibuf= movieclip_load_sequence_file(clip, user, framenr, flag); else { - ibuf= movieclip_load_movie_file(clip, user, framenr, clip->flag); + ibuf= movieclip_load_movie_file(clip, user, framenr, flag); } - if(ibuf) - put_imbuf_cache(clip, user, ibuf, clip->flag); + if(ibuf && (cache_flag & MOVIECLIP_CACHE_SKIP) == 0) + put_imbuf_cache(clip, user, ibuf, flag); } if(ibuf) { clip->lastframe= framenr; real_ibuf_size(clip, user, ibuf, &clip->lastsize[0], &clip->lastsize[1]); - /* put undistorted frame to cache */ - if(cache_undistorted) { + /* postprocess frame and put to cache */ + if(need_postprocess) { ImBuf *tmpibuf= ibuf; - ibuf= put_undistorted_cache(clip, user, tmpibuf); + ibuf= put_postprocessed_frame_to_cache(clip, user, tmpibuf, flag, postprocess_flag); IMB_freeImBuf(tmpibuf); } } @@ -602,105 +686,113 @@ return ibuf; } -ImBuf *BKE_movieclip_get_ibuf_flag(MovieClip *clip, MovieClipUser *user, int flag) +ImBuf *BKE_movieclip_get_ibuf(MovieClip *clip, MovieClipUser *user) { - ImBuf *ibuf= NULL; - int framenr= user->framenr; - int cache_undistorted= 0; + return BKE_movieclip_get_ibuf_flag(clip, user, clip->flag, 0); +} - /* cache isn't threadsafe itself and also loading of movies - can't happen from concurent threads that's why we use lock here */ - BLI_lock_thread(LOCK_MOVIECLIP); +ImBuf *BKE_movieclip_get_ibuf_flag(MovieClip *clip, MovieClipUser *user, int flag, int cache_flag) +{ + return movieclip_get_postprocessed_ibuf(clip, user, flag, 0, cache_flag); +} - /* try to obtain cached undistorted image first */ - if(need_undistorted_cache(user, flag)) { - ibuf= get_undistorted_cache(clip, user); - if(!ibuf) - cache_undistorted= 1; +ImBuf *BKE_movieclip_get_postprocessed_ibuf(MovieClip *clip, MovieClipUser *user, int postprocess_flag) +{ + return movieclip_get_postprocessed_ibuf(clip, user, clip->flag, postprocess_flag, 0); +} + +static ImBuf *get_stable_cached_frame(MovieClip *clip, MovieClipUser *user, int framenr) +{ + MovieClipCache *cache = clip->cache; + ImBuf *stableibuf; + float tloc[2], tscale, tangle; + short proxy = IMB_PROXY_NONE; + int render_flag = 0; + + if(clip->flag&MCLIP_USE_PROXY) { + proxy = rendersize_to_proxy(user, clip->flag); + render_flag = user->render_flag; } - ibuf= get_imbuf_cache(clip, user, flag); + /* there's no cached frame or it was calculated for another frame */ + if(!cache->stabilized.ibuf || cache->stabilized.framenr != framenr) + return NULL; - if(!ibuf) { - if(clip->source==MCLIP_SRC_SEQUENCE) { - ibuf= movieclip_load_sequence_file(clip, user, framenr, flag); - } else { - ibuf= movieclip_load_movie_file(clip, user, framenr, flag); - } + /* cached ibuf used different proxy settings */ + if(cache->stabilized.render_flag!=render_flag || cache->stabilized.proxy!=proxy) + return NULL; - if(ibuf) { - int bits= MCLIP_USE_PROXY|MCLIP_USE_PROXY_CUSTOM_DIR; + stableibuf = cache->stabilized.ibuf; - if((flag&bits)==(clip->flag&bits)) - put_imbuf_cache(clip, user, ibuf, clip->flag); - } + BKE_tracking_stabilization_data(&clip->tracking, framenr, stableibuf->x, stableibuf->y, tloc, &tscale, &tangle); + + /* check for stabilization parameters */ + if(tscale != cache->stabilized.scale || + tangle != cache->stabilized.angle || + !equals_v2v2(tloc, cache->stabilized.loc)) + { + return NULL; } - /* put undistorted frame to cache */ - if(ibuf && cache_undistorted) { - ImBuf *tmpibuf= ibuf; - ibuf= put_undistorted_cache(clip, user, tmpibuf); - IMB_freeImBuf(tmpibuf); + IMB_refImBuf(stableibuf); + + return stableibuf; +} + +static ImBuf *put_stabilized_frame_to_cache(MovieClip *clip, MovieClipUser *user, ImBuf *ibuf, int framenr) +{ + MovieClipCache *cache = clip->cache; + ImBuf *stableibuf; + float tloc[2], tscale, tangle; + + if(cache->stabilized.ibuf) + IMB_freeImBuf(cache->stabilized.ibuf); + + stableibuf = BKE_tracking_stabilize(&clip->tracking, framenr, ibuf, tloc, &tscale, &tangle); + + cache->stabilized.ibuf= stableibuf; + + copy_v2_v2(cache->stabilized.loc, tloc); + + cache->stabilized.scale = tscale; + cache->stabilized.angle = tangle; + cache->stabilized.framenr = framenr; + + if(clip->flag&MCLIP_USE_PROXY) { + cache->stabilized.proxy= rendersize_to_proxy(user, clip->flag); + cache->stabilized.render_flag= user->render_flag; + } + else { + cache->stabilized.proxy = IMB_PROXY_NONE; + cache->stabilized.render_flag = 0; } - BLI_unlock_thread(LOCK_MOVIECLIP); + IMB_refImBuf(stableibuf); - return ibuf; + return stableibuf; } -ImBuf *BKE_movieclip_get_stable_ibuf(MovieClip *clip, MovieClipUser *user, float loc[2], float *scale, float *angle) +ImBuf *BKE_movieclip_get_stable_ibuf(MovieClip *clip, MovieClipUser *user, float loc[2], float *scale, float *angle, int postprocess_flag) { ImBuf *ibuf, *stableibuf= NULL; int framenr= user->framenr; - ibuf= BKE_movieclip_get_ibuf(clip, user); + ibuf= BKE_movieclip_get_postprocessed_ibuf(clip, user, postprocess_flag); if(!ibuf) return NULL; if(clip->tracking.stabilization.flag&TRACKING_2D_STABILIZATION) { - float tloc[2], tscale, tangle; - short proxy= IMB_PROXY_NONE; - int render_flag= 0; - - if(clip->flag&MCLIP_USE_PROXY) { - proxy= rendersize_to_proxy(user, clip->flag); - render_flag= user->render_flag; - } - - if(clip->cache->stableibuf && clip->cache->stable_framenr==framenr) { /* there's cached ibuf */ - if(clip->cache->render_flag==render_flag && clip->cache->proxy==proxy) { /* cached ibuf used the same proxy settings */ - stableibuf= clip->cache->stableibuf; - - BKE_tracking_stabilization_data(&clip->tracking, framenr, stableibuf->x, stableibuf->y, tloc, &tscale, &tangle); - - /* check for stabilization parameters */ - if(!equals_v2v2(tloc, clip->cache->stable_loc) || tscale!=clip->cache->stable_scale || tangle!=clip->cache->stable_angle) { - stableibuf= NULL; - } - } - } + MovieClipCache *cache= clip->cache; - if(!stableibuf) { - if(clip->cache->stableibuf) - IMB_freeImBuf(clip->cache->stableibuf); - - stableibuf= BKE_tracking_stabilize(&clip->tracking, framenr, ibuf, tloc, &tscale, &tangle); - - copy_v2_v2(clip->cache->stable_loc, tloc); - clip->cache->stable_scale= tscale; - clip->cache->stable_angle= tangle; - clip->cache->stable_framenr= framenr; - clip->cache->stableibuf= stableibuf; - clip->cache->proxy= proxy; - clip->cache->render_flag= render_flag; - } + stableibuf= get_stable_cached_frame(clip, user, framenr); - IMB_refImBuf(stableibuf); + if(!stableibuf) + stableibuf= put_stabilized_frame_to_cache(clip, user, ibuf, framenr); - if(loc) copy_v2_v2(loc, tloc); - if(scale) *scale= tscale; - if(angle) *angle= tangle; + if(loc) copy_v2_v2(loc, cache->stabilized.loc); + if(scale) *scale= cache->stabilized.scale; + if(angle) *angle= cache->stabilized.angle; } else { if(loc) zero_v2(loc); if(scale) *scale= 1.0f; @@ -783,11 +875,11 @@ if(clip->cache) { IMB_moviecache_free(clip->cache->moviecache); - if(clip->cache->stableibuf) - IMB_freeImBuf(clip->cache->stableibuf); + if(clip->cache->postprocessed.ibuf) + IMB_freeImBuf(clip->cache->postprocessed.ibuf); - if(clip->cache->undistibuf) - IMB_freeImBuf(clip->cache->undistibuf); + if(clip->cache->stabilized.ibuf) + IMB_freeImBuf(clip->cache->stabilized.ibuf); MEM_freeN(clip->cache); clip->cache= NULL; @@ -813,7 +905,8 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClipScopes *scopes) { - if(scopes->ok) return; + if(scopes->ok) + return; if(scopes->track_preview) { IMB_freeImBuf(scopes->track_preview); @@ -824,8 +917,10 @@ scopes->track= NULL; if(clip) { - if(clip->tracking.act_track) { - MovieTrackingTrack *track= clip->tracking.act_track; + MovieTrackingTrack *act_track= BKE_tracking_active_track(&clip->tracking); + + if(act_track) { + MovieTrackingTrack *track= act_track; MovieTrackingMarker *marker= BKE_tracking_get_marker(track, user->framenr); if(marker->flag&MARKER_DISABLED) { @@ -854,7 +949,9 @@ undist_marker.pos[1]/= height*aspy; } - tmpibuf= BKE_tracking_get_pattern_imbuf(ibuf, track, &undist_marker, 1, 1, scopes->track_pos, NULL); + /* NOTE: margin should be kept in sync with value from ui_draw_but_TRACKPREVIEW */ + tmpibuf= BKE_tracking_get_pattern_imbuf(ibuf, track, &undist_marker, 3 /* margin */, + 1 /* anchor */, scopes->track_pos, NULL); if(tmpibuf->rect_float) IMB_rect_from_float(tmpibuf); @@ -885,7 +982,7 @@ { char name[FILE_MAX]; int quality, rectx, recty; - int size= size= rendersize_to_number(proxy_render_size); + int size= rendersize_to_number(proxy_render_size); ImBuf *scaleibuf; get_proxy_fname(clip, proxy_render_size, undistorted, cfra, name); @@ -915,15 +1012,17 @@ IMB_freeImBuf(scaleibuf); } -void BKE_movieclip_build_proxy_frame(MovieClip *clip, struct MovieDistortion *distortion, +void BKE_movieclip_build_proxy_frame(MovieClip *clip, int clip_flag, struct MovieDistortion *distortion, int cfra, int *build_sizes, int build_count, int undistorted) { ImBuf *ibuf; MovieClipUser user; user.framenr= cfra; + user.render_flag= 0; + user.render_size= MCLIP_PROXY_RENDER_SIZE_FULL; - ibuf= BKE_movieclip_get_ibuf_flag(clip, &user, 0); + ibuf= BKE_movieclip_get_ibuf_flag(clip, &user, clip_flag, MOVIECLIP_CACHE_SKIP); if(ibuf) { ImBuf *tmpibuf= ibuf; @@ -985,9 +1084,9 @@ } for(ob= bmain->object.first; ob; ob= ob->id.next) { - bConstraint *con= ob->constraints.first; + bConstraint *con; - for (con= ob->constraints.first; con; con= con->next) { + for(con= ob->constraints.first; con; con= con->next) { bConstraintTypeInfo *cti= constraint_get_typeinfo(con); if(cti->type==CONSTRAINT_TYPE_FOLLOWTRACK) { diff -Nru blender-2.61/source/blender/blenkernel/intern/multires.c blender-2.62/source/blender/blenkernel/intern/multires.c --- blender-2.61/source/blender/blenkernel/intern/multires.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/multires.c 2012-02-15 19:34:02.000000000 +0000 @@ -1616,7 +1616,7 @@ CustomData_external_read(&me->fdata, &me->id, CD_MASK_MDISPS, me->totface); mdisps= CustomData_get_layer(&me->fdata, CD_MDISPS); - if(!mdisps || !mmd) return; + if(!mdisps || !mmd || !mmd->totlvl) return; /* we need derived mesh created from highest resolution */ high_mmd= *mmd; diff -Nru blender-2.61/source/blender/blenkernel/intern/navmesh_conversion.c blender-2.62/source/blender/blenkernel/intern/navmesh_conversion.c --- blender-2.61/source/blender/blenkernel/intern/navmesh_conversion.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/navmesh_conversion.c 2012-02-15 19:34:02.000000000 +0000 @@ -344,7 +344,7 @@ int *vertsPerPoly_r, int **dtrisToPolysMap_r, int **dtrisToTrisMap_r) { - int *trisMapping = MEM_callocN(sizeof(int)*ntris, "buildNavMeshData trisMapping"); + int *trisMapping; int i; struct SortContext context; int validTriStart, prevPolyIdx, curPolyIdx, newPolyIdx, prevpolyidx; @@ -360,6 +360,8 @@ return 0; } + trisMapping = MEM_callocN(sizeof(int)*ntris, "buildNavMeshData trisMapping"); + //sort the triangles by polygon idx for (i=0; iextendmode != NLASTRIP_EXTEND_NOTHING) { + /* 1) First strip must be set to extend hold, otherwise, stuff before acts dodgy + * 2) Only overwrite extend mode if *not* changing it will most probably result in + * occlusion problems, which will occur iff + * - blendmode = REPLACE + * - all channels the same (this is fiddly to test, so is currently assumed) + * + * Should fix problems such as [#29869] + */ if (strip == fstrip) strip->extendmode= NLASTRIP_EXTEND_HOLD; - else + else if (strip->blendmode == NLASTRIP_MODE_REPLACE) strip->extendmode= NLASTRIP_EXTEND_HOLD_FORWARD; } } @@ -1542,6 +1550,34 @@ break; } } + + /* There are situations where we may have multiple strips selected and we want to enter tweakmode on all + * of those at once. Usually in those cases, it will usually just be a single strip per AnimData. + * In such cases, compromise and take the last selected track and/or last selected strip [#28468] + */ + if (activeTrack == NULL) { + /* try last selected track for active strip */ + for (nlt = adt->nla_tracks.last; nlt; nlt = nlt->prev) { + if (nlt->flag & NLATRACK_SELECTED) { + /* assume this is the active track */ + activeTrack= nlt; + + /* try to find active strip */ + activeStrip= BKE_nlastrip_find_active(nlt); + break; + } + } + } + if ((activeTrack) && (activeStrip == NULL)) { + /* no active strip in active or last selected track; compromise for first selected (assuming only single)... */ + for (strip = activeTrack->strips.first; strip; strip= strip->next) { + if (strip->flag & (NLASTRIP_FLAG_SELECT|NLASTRIP_FLAG_ACTIVE)) { + activeStrip = strip; + break; + } + } + } + if ELEM3(NULL, activeTrack, activeStrip, activeStrip->act) { if (G.f & G_DEBUG) { printf("NLA tweakmode enter - neither active requirement found \n"); diff -Nru blender-2.61/source/blender/blenkernel/intern/node.c blender-2.62/source/blender/blenkernel/intern/node.c --- blender-2.61/source/blender/blenkernel/intern/node.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/node.c 2012-02-15 19:34:02.000000000 +0000 @@ -159,7 +159,6 @@ static bNodeSocket *make_socket(bNodeTree *UNUSED(ntree), int in_out, const char *name, int type) { - bNodeSocketType *stype= ntreeGetSocketType(type); bNodeSocket *sock; sock= MEM_callocN(sizeof(bNodeSocket), "sock"); @@ -169,8 +168,8 @@ sock->type= type; sock->storage = NULL; - if (stype->value_structsize > 0) - sock->default_value = MEM_callocN(stype->value_structsize, "default socket value"); + sock->default_value = node_socket_make_default_value(type); + node_socket_init_default_value(type, sock->default_value); return sock; } @@ -216,8 +215,7 @@ BLI_remlink(&node->inputs, sock); BLI_remlink(&node->outputs, sock); - if (sock->default_value) - MEM_freeN(sock->default_value); + node_socket_free_default_value(sock->type, sock->default_value); MEM_freeN(sock); node->update |= NODE_UPDATE; @@ -236,13 +234,10 @@ } for (sock=node->inputs.first; sock; sock=sock->next) - if (sock->default_value) - MEM_freeN(sock->default_value); + node_socket_free_default_value(sock->type, sock->default_value); BLI_freelistN(&node->inputs); for (sock=node->outputs.first; sock; sock=sock->next) - if (sock->default_value) - MEM_freeN(sock->default_value); - + node_socket_free_default_value(sock->type, sock->default_value); BLI_freelistN(&node->outputs); node->update |= NODE_UPDATE; @@ -396,7 +391,8 @@ oldsock->new_sock= sock; sock->stack_index= 0; - sock->default_value = (oldsock->default_value ? MEM_dupallocN(oldsock->default_value) : NULL); + sock->default_value = node_socket_make_default_value(oldsock->type); + node_socket_copy_default_value(oldsock->type, sock->default_value, oldsock->default_value); /* XXX some compositor node (e.g. image, render layers) still store * some persistent buffer data here, need to clear this to avoid dangling pointers. @@ -410,7 +406,8 @@ oldsock->new_sock= sock; sock->stack_index= 0; - sock->default_value = (oldsock->default_value ? MEM_dupallocN(oldsock->default_value) : NULL); + sock->default_value = node_socket_make_default_value(oldsock->type); + node_socket_copy_default_value(oldsock->type, sock->default_value, oldsock->default_value); /* XXX some compositor node (e.g. image, render layers) still store * some persistent buffer data here, need to clear this to avoid dangling pointers. @@ -658,13 +655,15 @@ for(gsock= newtree->inputs.first, oldgsock= ntree->inputs.first; gsock; gsock=gsock->next, oldgsock=oldgsock->next) { oldgsock->new_sock= gsock; gsock->groupsock = (oldgsock->groupsock ? oldgsock->groupsock->new_sock : NULL); - gsock->default_value = (oldgsock->default_value ? MEM_dupallocN(oldgsock->default_value) : NULL); + gsock->default_value = node_socket_make_default_value(oldgsock->type); + node_socket_copy_default_value(oldgsock->type, gsock->default_value, oldgsock->default_value); } BLI_duplicatelist(&newtree->outputs, &ntree->outputs); for(gsock= newtree->outputs.first, oldgsock= ntree->outputs.first; gsock; gsock=gsock->next, oldgsock=oldgsock->next) { oldgsock->new_sock= gsock; gsock->groupsock = (oldgsock->groupsock ? oldgsock->groupsock->new_sock : NULL); - gsock->default_value = (oldgsock->default_value ? MEM_dupallocN(oldgsock->default_value) : NULL); + gsock->default_value = node_socket_make_default_value(oldgsock->type); + node_socket_copy_default_value(oldgsock->type, gsock->default_value, oldgsock->default_value); } /* copy links */ @@ -790,16 +789,11 @@ unsigned char *tar= preview->rect+ 4*((preview->xsize*y) + x); if(do_manage) { - tar[0]= FTOCHAR(linearrgb_to_srgb(col[0])); - tar[1]= FTOCHAR(linearrgb_to_srgb(col[1])); - tar[2]= FTOCHAR(linearrgb_to_srgb(col[2])); + linearrgb_to_srgb_uchar4(tar, col); } else { - tar[0]= FTOCHAR(col[0]); - tar[1]= FTOCHAR(col[1]); - tar[2]= FTOCHAR(col[2]); + rgba_float_to_uchar(tar, col); } - tar[3]= FTOCHAR(col[3]); } //else printf("prv out bound x y %d %d\n", x, y); } @@ -868,14 +862,12 @@ for (sock=node->inputs.first; sock; sock = nextsock) { nextsock = sock->next; - if (sock->default_value) - MEM_freeN(sock->default_value); + node_socket_free_default_value(sock->type, sock->default_value); MEM_freeN(sock); } for (sock=node->outputs.first; sock; sock = nextsock) { nextsock = sock->next; - if (sock->default_value) - MEM_freeN(sock->default_value); + node_socket_free_default_value(sock->type, sock->default_value); MEM_freeN(sock); } @@ -929,12 +921,10 @@ } for (sock=ntree->inputs.first; sock; sock=sock->next) - if (sock->default_value) - MEM_freeN(sock->default_value); + node_socket_free_default_value(sock->type, sock->default_value); BLI_freelistN(&ntree->inputs); for (sock=ntree->outputs.first; sock; sock=sock->next) - if (sock->default_value) - MEM_freeN(sock->default_value); + node_socket_free_default_value(sock->type, sock->default_value); BLI_freelistN(&ntree->outputs); } @@ -1325,30 +1315,9 @@ node->flag |= NODE_ACTIVE_TEXTURE; } -/* use flags are not persistent yet, groups might need different tagging, so we do it each time - when we need to get this info */ -void ntreeSocketUseFlags(bNodeTree *ntree) +int nodeSocketIsHidden(bNodeSocket *sock) { - bNode *node; - bNodeSocket *sock; - bNodeLink *link; - - /* clear flags */ - for(node= ntree->nodes.first; node; node= node->next) { - for(sock= node->inputs.first; sock; sock= sock->next) - sock->flag &= ~SOCK_IN_USE; - for(sock= node->outputs.first; sock; sock= sock->next) - sock->flag &= ~SOCK_IN_USE; - } - - /* tag all thats in use */ - for(link= ntree->links.first; link; link= link->next) { - - if(link->fromsock) // FIXME, see below - link->fromsock->flag |= SOCK_IN_USE; - if(link->tosock) // FIXME This can be NULL, when dragging a new link in the UI, should probably copy the node tree for preview render - campbell - link->tosock->flag |= SOCK_IN_USE; - } + return ((sock->flag & (SOCK_HIDDEN | SOCK_AUTO_HIDDEN | SOCK_UNAVAIL)) != 0); } /* ************** dependency stuff *********** */ @@ -1425,16 +1394,27 @@ /* first clear data */ for(node= ntree->nodes.first; node; node= node->next) { - for(sock= node->inputs.first; sock; sock= sock->next) + for(sock= node->inputs.first; sock; sock= sock->next) { sock->link= NULL; + sock->flag &= ~SOCK_IN_USE; + } + for(sock= node->outputs.first; sock; sock= sock->next) { + sock->flag &= ~SOCK_IN_USE; + } + } + for(sock= ntree->inputs.first; sock; sock= sock->next) { + sock->flag &= ~SOCK_IN_USE; } - /* clear socket links */ - for(sock= ntree->outputs.first; sock; sock= sock->next) + for(sock= ntree->outputs.first; sock; sock= sock->next) { sock->link= NULL; + sock->flag &= ~SOCK_IN_USE; + } for(link= ntree->links.first; link; link= link->next) { - if (link->tosock) - link->tosock->link= link; + link->tosock->link= link; + + link->fromsock->flag |= SOCK_IN_USE; + link->tosock->flag |= SOCK_IN_USE; } } @@ -1872,7 +1852,8 @@ register_node_type_cmp_channel_matte(ttype); register_node_type_cmp_color_spill(ttype); register_node_type_cmp_luma_matte(ttype); - + register_node_type_cmp_doubleedgemask(ttype); + register_node_type_cmp_translate(ttype); register_node_type_cmp_rotate(ttype); register_node_type_cmp_scale(ttype); @@ -1899,6 +1880,8 @@ register_node_type_sh_output(ttype); register_node_type_sh_material(ttype); register_node_type_sh_camera(ttype); + register_node_type_sh_gamma(ttype); + register_node_type_sh_brightcontrast(ttype); register_node_type_sh_value(ttype); register_node_type_sh_rgb(ttype); register_node_type_sh_mix_rgb(ttype); @@ -1954,6 +1937,7 @@ register_node_type_sh_tex_musgrave(ttype); register_node_type_sh_tex_gradient(ttype); register_node_type_sh_tex_magic(ttype); + register_node_type_sh_tex_checker(ttype); } static void registerTextureNodes(bNodeTreeType *ttype) diff -Nru blender-2.61/source/blender/blenkernel/intern/object.c blender-2.62/source/blender/blenkernel/intern/object.c --- blender-2.61/source/blender/blenkernel/intern/object.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/object.c 2012-02-15 19:34:02.000000000 +0000 @@ -430,7 +430,8 @@ if(pchan->custom==ob) pchan->custom= NULL; } - } else if(ELEM(OB_MBALL, ob->type, obt->type)) { + } + else if(ELEM(OB_MBALL, ob->type, obt->type)) { if(is_mball_basis_for(obt, ob)) obt->recalc|= OB_RECALC_DATA; } @@ -608,21 +609,6 @@ sce= sce->id.next; } -#if 0 // XXX old animation system - /* ipos */ - ipo= bmain->ipo.first; - while(ipo) { - if(ipo->id.lib==NULL) { - IpoCurve *icu; - for(icu= ipo->curve.first; icu; icu= icu->next) { - if(icu->driver && icu->driver->ob==ob) - icu->driver->ob= NULL; - } - } - ipo= ipo->id.next; - } -#endif // XXX old animation system - /* screens */ sc= bmain->screen.first; while(sc) { @@ -844,7 +830,7 @@ { Object *ob; Base *base; - char name[32]; + char name[MAX_ID_NAME]; BLI_strncpy(name, get_obdata_defname(type), sizeof(name)); ob = add_only_object(type, name); @@ -990,7 +976,7 @@ } else if (md->type==eModifierType_Smoke) { SmokeModifierData *smd = (SmokeModifierData*) md; - + if(smd->type==MOD_SMOKE_TYPE_FLOW) { if (smd->flow) { if (smd->flow->psys == psys) @@ -1026,22 +1012,6 @@ ListBase targets = {NULL, NULL}; bConstraintTarget *ct; -#if 0 // XXX old animation system - /* note that we can't change lib linked ipo blocks. for making - * proxies this still works correct however because the object - * is changed to object->proxy_from when evaluating the driver. */ - if(con->ipo && !con->ipo->id.lib) { - IpoCurve *icu; - - con->ipo= copy_ipo(con->ipo); - - for(icu= con->ipo->curve.first; icu; icu= icu->next) { - if(icu->driver && icu->driver->ob==ob) - icu->driver->ob= obn; - } - } -#endif // XXX old animation system - if (cti && cti->get_constraint_targets) { cti->get_constraint_targets(con, &targets); @@ -1071,8 +1041,7 @@ } } -//Object *object_pose_armature_get(Object *ob) -Object *object_pose_armature_get(struct Object *ob) +Object *object_pose_armature_get(Object *ob) { if(ob==NULL) return NULL; @@ -1178,13 +1147,8 @@ static void extern_local_object(Object *ob) { - //bActionStrip *strip; ParticleSystem *psys; -#if 0 // XXX old animation system - id_lib_extern((ID *)ob->action); - id_lib_extern((ID *)ob->ipo); -#endif // XXX old animation system id_lib_extern((ID *)ob->data); id_lib_extern((ID *)ob->dup_group); id_lib_extern((ID *)ob->poselib); @@ -1192,11 +1156,6 @@ extern_local_matarar(ob->mat, ob->totcol); -#if 0 // XXX old animation system - for (strip=ob->nlastrips.first; strip; strip=strip->next) { - id_lib_extern((ID *)strip->act); - } -#endif // XXX old animation system for(psys=ob->particlesystem.first; psys; psys=psys->next) id_lib_extern((ID *)psys->part); } @@ -1363,7 +1322,7 @@ * this is closer to making a copy of the object - in-place. */ if(gob) { ob->rotmode= target->rotmode; - mul_m4_m4m4(ob->obmat, target->obmat, gob->obmat); + mult_m4_m4m4(ob->obmat, gob->obmat, target->obmat); if(gob->dup_group) { /* should always be true */ float tvec[3]; copy_v3_v3(tvec, gob->dup_group->dupli_ofs); @@ -1589,9 +1548,9 @@ if(use_parent && ob->parent) { float rmat[4][4], diff_mat[4][4], imat[4][4]; - mul_m4_m4m4(diff_mat, ob->parentinv, ob->parent->obmat); + mult_m4_m4m4(diff_mat, ob->parent->obmat, ob->parentinv); invert_m4_m4(imat, diff_mat); - mul_m4_m4m4(rmat, mat, imat); /* get the parent relative matrix */ + mult_m4_m4m4(rmat, imat, mat); /* get the parent relative matrix */ object_apply_mat4(ob, rmat, use_compat, FALSE); /* same as below, use rmat rather than mat */ @@ -1715,7 +1674,7 @@ if(cu->flag & CU_PATH_RADIUS) { float tmat[4][4], rmat[4][4]; scale_m4_fl(tmat, radius); - mul_m4_m4m4(rmat, mat, tmat); + mult_m4_m4m4(rmat, tmat, mat); copy_m4_m4(mat, rmat); } @@ -2473,6 +2432,14 @@ copy_m4_m4(ob->imat, obtfm->imat); } +int BKE_object_parent_loop_check(const Object *par, const Object *ob) +{ + /* test if 'ob' is a parent somewhere in par's parents */ + if(par == NULL) return 0; + if(ob == par) return 1; + return BKE_object_parent_loop_check(par->parent, ob); +} + /* proxy rule: lib_object->proxy_from == the one we borrow from, only set temporal and cleared here */ /* local_object->proxy == pointer to library object, saved in files and read */ @@ -2512,7 +2479,7 @@ if(ob->proxy_from->proxy_group) {/* transform proxy into group space */ Object *obg= ob->proxy_from->proxy_group; invert_m4_m4(obg->imat, obg->obmat); - mul_m4_m4m4(ob->obmat, ob->proxy_from->obmat, obg->imat); + mult_m4_m4m4(ob->obmat, obg->imat, ob->proxy_from->obmat); if(obg->dup_group) { /* should always be true */ add_v3_v3(ob->obmat[3], obg->dup_group->dupli_ofs); } @@ -2555,7 +2522,7 @@ #else /* ensure CD_MASK_BAREMESH for now */ EditMesh *em = (ob == scene->obedit)? BKE_mesh_get_editmesh(ob->data): NULL; - unsigned int data_mask= scene->customdata_mask | ob->customdata_mask | CD_MASK_BAREMESH; + uint64_t data_mask= scene->customdata_mask | ob->customdata_mask | CD_MASK_BAREMESH; if(em) { makeDerivedMesh(scene, ob, em, data_mask); /* was CD_MASK_BAREMESH */ BKE_mesh_end_editmesh(ob->data, em); diff -Nru blender-2.61/source/blender/blenkernel/intern/ocean.c blender-2.62/source/blender/blenkernel/intern/ocean.c --- blender-2.61/source/blender/blenkernel/intern/ocean.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/ocean.c 2012-02-15 19:34:02.000000000 +0000 @@ -1343,7 +1343,8 @@ } Ocean; -float BKE_ocean_jminus_to_foam(float UNUSED(jminus), float UNUSED(coverage)) { +float BKE_ocean_jminus_to_foam(float UNUSED(jminus), float UNUSED(coverage)) +{ return 0.0f; } diff -Nru blender-2.61/source/blender/blenkernel/intern/packedFile.c blender-2.62/source/blender/blenkernel/intern/packedFile.c --- blender-2.61/source/blender/blenkernel/intern/packedFile.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/packedFile.c 2012-02-15 19:34:02.000000000 +0000 @@ -251,7 +251,7 @@ if (fop_exists(name)) { for (number = 1; number <= 999; number++) { - sprintf(tempname, "%s.%03d", name, number); + BLI_snprintf(tempname, sizeof(tempname), "%s.%03d", name, number); if (! fop_exists(tempname)) { break; } diff -Nru blender-2.61/source/blender/blenkernel/intern/paint.c blender-2.62/source/blender/blenkernel/intern/paint.c --- blender-2.61/source/blender/blenkernel/intern/paint.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/paint.c 2012-02-15 19:34:02.000000000 +0000 @@ -66,6 +66,11 @@ return &ts->wpaint->paint; case OB_MODE_TEXTURE_PAINT: return &ts->imapaint.paint; + case OB_MODE_EDIT: + if(ts->use_uv_sculpt) + return &ts->uvsculpt->paint; + else + return &ts->imapaint.paint; } } diff -Nru blender-2.61/source/blender/blenkernel/intern/particle.c blender-2.62/source/blender/blenkernel/intern/particle.c --- blender-2.61/source/blender/blenkernel/intern/particle.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/particle.c 2012-02-15 19:34:02.000000000 +0000 @@ -90,7 +90,8 @@ float *orco, float mat[4][4], ParticleKey *state, float t); /* few helpers for countall etc. */ -int count_particles(ParticleSystem *psys){ +int count_particles(ParticleSystem *psys) +{ ParticleSettings *part=psys->part; PARTICLE_P; int tot=0; @@ -102,7 +103,8 @@ } return tot; } -int count_particles_mod(ParticleSystem *psys, int totgr, int cur){ +int count_particles_mod(ParticleSystem *psys, int totgr, int cur) +{ ParticleSettings *part=psys->part; PARTICLE_P; int tot=0; @@ -709,8 +711,8 @@ psys->childcachebufs.first = psys->childcachebufs.last = NULL; copy_m4_m4(data->winmat, winmat); - mul_m4_m4m4(data->viewmat, ob->obmat, viewmat); - mul_m4_m4m4(data->mat, data->viewmat, winmat); + mult_m4_m4m4(data->viewmat, viewmat, ob->obmat); + mult_m4_m4m4(data->mat, winmat, data->viewmat); data->winx= winx; data->winy= winy; @@ -1123,7 +1125,8 @@ return ret == 2; } -float psys_get_dietime_from_cache(PointCache *cache, int index) { +float psys_get_dietime_from_cache(PointCache *cache, int index) +{ PTCacheMem *pm; int dietime = 10000000; /* some max value so that we can default to pa->time+lifetime */ @@ -1362,11 +1365,42 @@ if(pind->keyed || pind->cache || point_vel) mul_v3_fl(result->vel, 1.f/invdt); } + +static void interpolate_pathcache(ParticleCacheKey *first, float t, ParticleCacheKey *result) +{ + int i=0; + ParticleCacheKey *cur = first; + + /* scale the requested time to fit the entire path even if the path is cut early */ + t *= (first+first->steps)->time; + + while(isteps && cur->time < t) + cur++; + + if(cur->time == t) + *result = *cur; + else { + float dt = (t-(cur-1)->time)/(cur->time-(cur-1)->time); + interp_v3_v3v3(result->co, (cur-1)->co, cur->co, dt); + interp_v3_v3v3(result->vel, (cur-1)->vel, cur->vel, dt); + interp_qt_qtqt(result->rot, (cur-1)->rot, cur->rot, dt); + result->time = t; + } + + /* first is actual base rotation, others are incremental from first */ + if(cur==first || cur-1==first) + copy_qt_qt(result->rot, first->rot); + else + mul_qt_qtqt(result->rot, first->rot, result->rot); +} + /************************************************/ /* Particles on a dm */ /************************************************/ /* interpolate a location on a face based on face coordinates */ -void psys_interpolate_face(MVert *mvert, MFace *mface, MTFace *tface, float (*orcodata)[3], float *w, float *vec, float *nor, float *utan, float *vtan, float *orco,float *ornor){ +void psys_interpolate_face(MVert *mvert, MFace *mface, MTFace *tface, float (*orcodata)[3], + float *w, float *vec, float *nor, float *utan, float *vtan, float *orco,float *ornor) +{ float *v1=0, *v2=0, *v3=0, *v4=0; float e1[3],e2[3],s1,s2,t1,t2; float *uv1, *uv2, *uv3, *uv4; @@ -1828,7 +1862,8 @@ /************************************************/ /* Particles on emitter */ /************************************************/ -void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int index, int index_dmcache, float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor){ +void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int index, int index_dmcache, float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor) +{ if(psmd){ if(psmd->psys->part->distr==PART_DISTR_GRID && psmd->psys->part->from != PART_FROM_VERT){ if(vec) @@ -2642,6 +2677,8 @@ /* offset the child from the parent position */ offset_child(cpa, (ParticleKey*)(key[0]+k), par_rot, (ParticleKey*)child, part->childflat, part->childrad); } + + child->time = (float)k/(float)ctx->steps; } /* apply effectors */ @@ -3003,6 +3040,8 @@ if(k==1) copy_v3_v3((ca-1)->vel, ca->vel); + + ca->time = (float)k/(float)steps; } /* First rotation is based on emitting face orientation. * This is way better than having flipping rotations resulting @@ -3083,6 +3122,9 @@ if(edit->totcached && !(point->flag & PEP_EDIT_RECALC)) continue; + if(point->totkey == 0) + continue; + ekey = point->keys; pind.keyed = 0; @@ -3231,7 +3273,8 @@ /************************************************/ /* Particle Key handling */ /************************************************/ -void copy_particle_key(ParticleKey *to, ParticleKey *from, int time){ +void copy_particle_key(ParticleKey *to, ParticleKey *from, int time) +{ if(time){ memcpy(to,from,sizeof(ParticleKey)); } @@ -3241,7 +3284,8 @@ to->time=to_time; } } -void psys_get_from_key(ParticleKey *key, float *loc, float *vel, float *rot, float *time){ +void psys_get_from_key(ParticleKey *key, float *loc, float *vel, float *rot, float *time) +{ if(loc) copy_v3_v3(loc,key->co); if(vel) copy_v3_v3(vel,key->vel); if(rot) copy_qt_qt(rot,key->rot); @@ -3249,7 +3293,8 @@ } /*-------changing particle keys from space to another-------*/ #if 0 -static void key_from_object(Object *ob, ParticleKey *key){ +static void key_from_object(Object *ob, ParticleKey *key) +{ float q[4]; add_v3_v3(key->vel, key->co); @@ -3374,7 +3419,7 @@ psys_mat_hair_to_object(ob, dm, from, pa, facemat); - mul_m4_m4m4(hairmat, facemat, ob->obmat); + mult_m4_m4m4(hairmat, ob->obmat, facemat); } /************************************************/ @@ -3400,14 +3445,14 @@ psys->part = psys_new_settings("ParticleSettings", NULL); if(BLI_countlist(&ob->particlesystem)>1) - sprintf(psys->name, "ParticleSystem %i", BLI_countlist(&ob->particlesystem)); + BLI_snprintf(psys->name, sizeof(psys->name), "ParticleSystem %i", BLI_countlist(&ob->particlesystem)); else strcpy(psys->name, "ParticleSystem"); md= modifier_new(eModifierType_ParticleSystem); if(name) BLI_strncpy(md->name, name, sizeof(md->name)); - else sprintf(md->name, "ParticleSystem %i", BLI_countlist(&ob->particlesystem)); + else BLI_snprintf(md->name, sizeof(md->name), "ParticleSystem %i", BLI_countlist(&ob->particlesystem)); modifier_unique_name(&ob->modifiers, md); psmd= (ParticleSystemModifierData*) md; @@ -4004,84 +4049,105 @@ CLAMP(t, 0.0f, 1.0f); if(pparticles + p; - pind.keyed = keyed; - pind.cache = cached ? psys->pointcache : NULL; - pind.epoint = NULL; - pind.bspline = (psys->part->flag & PART_HAIR_BSPLINE); - /* pind.dm disabled in editmode means we dont get effectors taken into - * account when subdividing for instance */ - pind.dm = psys_in_edit_mode(sim->scene, psys) ? NULL : psys->hair_out_dm; - init_particle_interpolation(sim->ob, psys, pa, &pind); - do_particle_interpolation(psys, p, pa, t, &pind, state); - - if(pind.dm) { - mul_m4_v3(sim->ob->obmat, state->co); - mul_mat3_m4_v3(sim->ob->obmat, state->vel); - } - else if(!keyed && !cached && !(psys->flag & PSYS_GLOBAL_HAIR)) { - if((pa->flag & PARS_REKEY)==0) { - psys_mat_hair_to_global(sim->ob, sim->psmd->dm, part->from, pa, hairmat); - mul_m4_v3(hairmat, state->co); - mul_mat3_m4_v3(hairmat, state->vel); - - if(sim->psys->effectors && (part->flag & PART_CHILD_GUIDE)==0) { - do_guides(sim->psys->effectors, state, p, state->time); - /* TODO: proper velocity handling */ - } + /* interpolate pathcache directly if it exist */ + if(psys->pathcache) { + ParticleCacheKey result; + interpolate_pathcache(psys->pathcache[p], t, &result); + copy_v3_v3(state->co, result.co); + copy_v3_v3(state->vel, result.vel); + copy_qt_qt(state->rot, result.rot); + } + /* otherwise interpolate with other means */ + else { + pa = psys->particles + p; - if(psys->lattice && edit==0) - calc_latt_deform(psys->lattice, state->co,1.0f); + pind.keyed = keyed; + pind.cache = cached ? psys->pointcache : NULL; + pind.epoint = NULL; + pind.bspline = (psys->part->flag & PART_HAIR_BSPLINE); + /* pind.dm disabled in editmode means we dont get effectors taken into + * account when subdividing for instance */ + pind.dm = psys_in_edit_mode(sim->scene, psys) ? NULL : psys->hair_out_dm; + init_particle_interpolation(sim->ob, psys, pa, &pind); + do_particle_interpolation(psys, p, pa, t, &pind, state); + + if(pind.dm) { + mul_m4_v3(sim->ob->obmat, state->co); + mul_mat3_m4_v3(sim->ob->obmat, state->vel); + } + else if(!keyed && !cached && !(psys->flag & PSYS_GLOBAL_HAIR)) { + if((pa->flag & PARS_REKEY)==0) { + psys_mat_hair_to_global(sim->ob, sim->psmd->dm, part->from, pa, hairmat); + mul_m4_v3(hairmat, state->co); + mul_mat3_m4_v3(hairmat, state->vel); + + if(sim->psys->effectors && (part->flag & PART_CHILD_GUIDE)==0) { + do_guides(sim->psys->effectors, state, p, state->time); + /* TODO: proper velocity handling */ + } + + if(psys->lattice && edit==0) + calc_latt_deform(psys->lattice, state->co,1.0f); + } } } } else if(totchild){ //invert_m4_m4(imat,ob->obmat); - cpa=psys->child+p-totpart; + /* interpolate childcache directly if it exists */ + if(psys->childcache) { + ParticleCacheKey result; + interpolate_pathcache(psys->childcache[p-totpart], t, &result); + copy_v3_v3(state->co, result.co); + copy_v3_v3(state->vel, result.vel); + copy_qt_qt(state->rot, result.rot); + } + else { + cpa=psys->child+p-totpart; - if(state->time < 0.0f) - t = psys_get_child_time(psys, cpa, -state->time, NULL, NULL); + if(state->time < 0.0f) + t = psys_get_child_time(psys, cpa, -state->time, NULL, NULL); - if(totchild && part->childtype==PART_CHILD_FACES){ - /* part->parents could still be 0 so we can't test with totparent */ - between=1; - } - if(between){ - int w = 0; - float foffset; - - /* get parent states */ - while(w<4 && cpa->pa[w]>=0){ - keys[w].time = state->time; - psys_get_particle_on_path(sim, cpa->pa[w], keys+w, 1); - w++; - } + if(totchild && part->childtype==PART_CHILD_FACES){ + /* part->parents could still be 0 so we can't test with totparent */ + between=1; + } + if(between){ + int w = 0; + float foffset; + + /* get parent states */ + while(w<4 && cpa->pa[w]>=0){ + keys[w].time = state->time; + psys_get_particle_on_path(sim, cpa->pa[w], keys+w, 1); + w++; + } - /* get the original coordinates (orco) for texture usage */ - cpa_num=cpa->num; + /* get the original coordinates (orco) for texture usage */ + cpa_num=cpa->num; - foffset= cpa->foffset; - cpa_fuv = cpa->fuv; - cpa_from = PART_FROM_FACE; + foffset= cpa->foffset; + cpa_fuv = cpa->fuv; + cpa_from = PART_FROM_FACE; - psys_particle_on_emitter(psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa->fuv,foffset,co,0,0,0,orco,0); + psys_particle_on_emitter(psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa->fuv,foffset,co,0,0,0,orco,0); - /* we need to save the actual root position of the child for positioning it accurately to the surface of the emitter */ - //copy_v3_v3(cpa_1st,co); + /* we need to save the actual root position of the child for positioning it accurately to the surface of the emitter */ + //copy_v3_v3(cpa_1st,co); - //mul_m4_v3(ob->obmat,cpa_1st); + //mul_m4_v3(ob->obmat,cpa_1st); - pa = psys->particles + cpa->parent; + pa = psys->particles + cpa->parent; - if(part->type == PART_HAIR) - psys_mat_hair_to_global(sim->ob, sim->psmd->dm, psys->part->from, pa, hairmat); - else - unit_m4(hairmat); + if(part->type == PART_HAIR) + psys_mat_hair_to_global(sim->ob, sim->psmd->dm, psys->part->from, pa, hairmat); + else + unit_m4(hairmat); - pa=0; - } - else{ + pa=0; + } + else{ /* get the parent state */ keys->time = state->time; psys_get_particle_on_path(sim, cpa->parent, keys,1); @@ -4105,79 +4171,81 @@ } } - /* correct child ipo timing */ -#if 0 // XXX old animation system - if((part->flag&PART_ABS_TIME)==0 && part->ipo){ - calc_ipo(part->ipo, 100.0f*t); - execute_ipo((ID *)part, part->ipo); - } -#endif // XXX old animation system + /* correct child ipo timing */ + #if 0 // XXX old animation system + if((part->flag&PART_ABS_TIME)==0 && part->ipo){ + calc_ipo(part->ipo, 100.0f*t); + execute_ipo((ID *)part, part->ipo); + } + #endif // XXX old animation system - /* get different child parameters from textures & vgroups */ - memset(&ctx, 0, sizeof(ParticleThreadContext)); - ctx.sim = *sim; - ctx.dm = psmd->dm; - ctx.ma = ma; - /* TODO: assign vertex groups */ - get_child_modifier_parameters(part, &ctx, cpa, cpa_from, cpa_num, cpa_fuv, orco, &ptex); - - if(between){ - int w=0; + /* get different child parameters from textures & vgroups */ + memset(&ctx, 0, sizeof(ParticleThreadContext)); + ctx.sim = *sim; + ctx.dm = psmd->dm; + ctx.ma = ma; + /* TODO: assign vertex groups */ + get_child_modifier_parameters(part, &ctx, cpa, cpa_from, cpa_num, cpa_fuv, orco, &ptex); + + if(between){ + int w=0; + + state->co[0] = state->co[1] = state->co[2] = 0.0f; + state->vel[0] = state->vel[1] = state->vel[2] = 0.0f; + + /* child position is the weighted sum of parent positions */ + while(w<4 && cpa->pa[w]>=0){ + state->co[0] += cpa->w[w] * keys[w].co[0]; + state->co[1] += cpa->w[w] * keys[w].co[1]; + state->co[2] += cpa->w[w] * keys[w].co[2]; + + state->vel[0] += cpa->w[w] * keys[w].vel[0]; + state->vel[1] += cpa->w[w] * keys[w].vel[1]; + state->vel[2] += cpa->w[w] * keys[w].vel[2]; + w++; + } + /* apply offset for correct positioning */ + //add_v3_v3(state->co, cpa_1st); + } + else{ + /* offset the child from the parent position */ + offset_child(cpa, keys, keys->rot, state, part->childflat, part->childrad); + } - state->co[0] = state->co[1] = state->co[2] = 0.0f; - state->vel[0] = state->vel[1] = state->vel[2] = 0.0f; + par = keys; - /* child position is the weighted sum of parent positions */ - while(w<4 && cpa->pa[w]>=0){ - state->co[0] += cpa->w[w] * keys[w].co[0]; - state->co[1] += cpa->w[w] * keys[w].co[1]; - state->co[2] += cpa->w[w] * keys[w].co[2]; - - state->vel[0] += cpa->w[w] * keys[w].vel[0]; - state->vel[1] += cpa->w[w] * keys[w].vel[1]; - state->vel[2] += cpa->w[w] * keys[w].vel[2]; - w++; - } - /* apply offset for correct positioning */ - //add_v3_v3(state->co, cpa_1st); - } - else{ - /* offset the child from the parent position */ - offset_child(cpa, keys, keys->rot, state, part->childflat, part->childrad); - } + if(vel) + copy_particle_key(&tstate, state, 1); - par = keys; + /* apply different deformations to the child path */ + do_child_modifiers(sim, &ptex, par, par->rot, cpa, orco, hairmat, state, t); - if(vel) - copy_particle_key(&tstate, state, 1); + /* try to estimate correct velocity */ + if(vel){ + ParticleKey tstate; + float length = len_v3(state->vel); - /* apply different deformations to the child path */ - do_child_modifiers(sim, &ptex, par, par->rot, cpa, orco, hairmat, state, t); + if(t>=0.001f){ + tstate.time=t-0.001f; + psys_get_particle_on_path(sim,p,&tstate,0); + sub_v3_v3v3(state->vel,state->co,tstate.co); + normalize_v3(state->vel); + } + else{ + tstate.time=t+0.001f; + psys_get_particle_on_path(sim,p,&tstate,0); + sub_v3_v3v3(state->vel,tstate.co,state->co); + normalize_v3(state->vel); + } - /* try to estimate correct velocity */ - if(vel){ - ParticleKey tstate; - float length = len_v3(state->vel); - - if(t>=0.001f){ - tstate.time=t-0.001f; - psys_get_particle_on_path(sim,p,&tstate,0); - sub_v3_v3v3(state->vel,state->co,tstate.co); - normalize_v3(state->vel); - } - else{ - tstate.time=t+0.001f; - psys_get_particle_on_path(sim,p,&tstate,0); - sub_v3_v3v3(state->vel,tstate.co,state->co); - normalize_v3(state->vel); + mul_v3_fl(state->vel, length); } - - mul_v3_fl(state->vel, length); } } } /* gets particle's state at a time, returns 1 if particle exists and can be seen and 0 if not */ -int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *state, int always){ +int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *state, int always) +{ ParticleSystem *psys = sim->psys; ParticleSettings *part = psys->part; ParticleData *pa = NULL; @@ -4514,8 +4582,8 @@ madd_v3_v3fl(center, yvec, bb->offset[1]); } - -void psys_apply_hair_lattice(Scene *scene, Object *ob, ParticleSystem *psys) { +void psys_apply_hair_lattice(Scene *scene, Object *ob, ParticleSystem *psys) +{ ParticleSimulationData sim= {0}; sim.scene= scene; sim.ob= ob; diff -Nru blender-2.61/source/blender/blenkernel/intern/particle_system.c blender-2.62/source/blender/blenkernel/intern/particle_system.c --- blender-2.61/source/blender/blenkernel/intern/particle_system.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/particle_system.c 2012-02-15 19:34:02.000000000 +0000 @@ -39,6 +39,10 @@ #include #include +#ifdef _OPENMP +#include +#endif + #include "MEM_guardedalloc.h" #include "DNA_anim_types.h" @@ -107,7 +111,8 @@ /* Reacting to system events */ /************************************************/ -static int particles_are_dynamic(ParticleSystem *psys) { +static int particles_are_dynamic(ParticleSystem *psys) +{ if(psys->pointcache->flag & PTCACHE_BAKED) return 0; @@ -1121,6 +1126,9 @@ fprintf(stderr,"Particle distribution error: Nothing to emit from!\n"); if(dm != finaldm) dm->release(dm); + + BLI_kdtree_free(tree); + return 0; } @@ -2240,7 +2248,8 @@ psys->fluid_springs = (ParticleSpring*)MEM_reallocN(psys->fluid_springs, psys->alloc_fluidsprings * sizeof(ParticleSpring)); } } -static void sph_springs_modify(ParticleSystem *psys, float dtime){ +static void sph_springs_modify(ParticleSystem *psys, float dtime) +{ SPHFluidSettings *fluid = psys->part->fluid; ParticleData *pa1, *pa2; ParticleSpring *spring = psys->fluid_springs; @@ -2299,6 +2308,7 @@ return springhash; } +#define SPH_NEIGHBORS 512 typedef struct SPHNeighbor { ParticleSystem *psys; @@ -2306,7 +2316,7 @@ } SPHNeighbor; typedef struct SPHRangeData { - SPHNeighbor neighbors[128]; + SPHNeighbor neighbors[SPH_NEIGHBORS]; int tot_neighbors; float density, near_density; @@ -2317,10 +2327,6 @@ float massfac; int use_size; - - /* Same as SPHData::element_size */ - float element_size; - float flow[3]; } SPHRangeData; typedef struct SPHData { ParticleSystem *psys[10]; @@ -2330,9 +2336,15 @@ float *gravity; /* Average distance to neighbours (other particles in the support domain), for calculating the Courant number (adaptive time step). */ + int pass; float element_size; float flow[3]; + + /* Integrator callbacks. This allows different SPH implementations. */ + void (*force_cb) (void *sphdata_v, ParticleKey *state, float *force, float *impulse); + void (*density_cb) (void *rangedata_v, int index, float squared_dist); }SPHData; + static void sph_density_accum_cb(void *userdata, int index, float squared_dist) { SPHRangeData *pfr = (SPHRangeData *)userdata; @@ -2343,11 +2355,13 @@ if(npa == pfr->pa || squared_dist < FLT_EPSILON) return; - /* Ugh! One particle has over 128 neighbors! Really shouldn't happen, - * but even if it does it shouldn't do any terrible harm if all are - * not taken into account - jahka + /* Ugh! One particle has too many neighbors! If some aren't taken into + * account, the forces will be biased by the tree search order. This + * effectively adds enery to the system, and results in a churning motion. + * But, we have to stop somewhere, and it's not the end of the world. + * - jahka and z0r */ - if(pfr->tot_neighbors >= 128) + if(pfr->tot_neighbors >= SPH_NEIGHBORS) return; pfr->neighbors[pfr->tot_neighbors].index = index; @@ -2357,15 +2371,38 @@ dist = sqrtf(squared_dist); q = (1.f - dist/pfr->h) * pfr->massfac; - add_v3_v3(pfr->flow, npa->state.vel); - pfr->element_size += dist; - if(pfr->use_size) q *= npa->size; pfr->density += q*q; pfr->near_density += q*q*q; } +/* + * Find the Courant number for an SPH particle (used for adaptive time step). + */ +static void sph_particle_courant(SPHData *sphdata, SPHRangeData *pfr) { + ParticleData *pa, *npa; + int i; + float flow[3], offset[3], dist; + + flow[0] = flow[1] = flow[2] = 0.0f; + dist = 0.0f; + if (pfr->tot_neighbors > 0) { + pa = pfr->pa; + for (i=0; i < pfr->tot_neighbors; i++) { + npa = pfr->neighbors[i].psys->particles + pfr->neighbors[i].index; + sub_v3_v3v3(offset, pa->prev_state.co, npa->prev_state.co); + dist += len_v3(offset); + add_v3_v3(flow, npa->prev_state.vel); + } + dist += sphdata->psys[0]->part->fluid->radius; // TODO: remove this? - z0r + sphdata->element_size = dist / pfr->tot_neighbors; + mul_v3_v3fl(sphdata->flow, flow, 1.0f / pfr->tot_neighbors); + } else { + sphdata->element_size = MAXFLOAT; + VECCOPY(sphdata->flow, flow); + } +} static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, float *UNUSED(impulse)) { SPHData *sphdata = (SPHData *)sphdata_v; @@ -2406,24 +2443,14 @@ pfr.density = pfr.near_density = 0.f; pfr.h = h; pfr.pa = pa; - pfr.element_size = fluid->radius; - pfr.flow[0] = pfr.flow[1] = pfr.flow[2] = 0.0f; for(i=0; i<10 && psys[i]; i++) { pfr.npsys = psys[i]; pfr.massfac = psys[i]->part->mass*inv_mass; pfr.use_size = psys[i]->part->flag & PART_SIZEMASS; - BLI_bvhtree_range_query(psys[i]->bvhtree, state->co, h, sph_density_accum_cb, &pfr); + BLI_bvhtree_range_query(psys[i]->bvhtree, state->co, h, sphdata->density_cb, &pfr); } - if (pfr.tot_neighbors > 0) { - pfr.element_size /= pfr.tot_neighbors; - mul_v3_fl(pfr.flow, 1.0f / pfr.tot_neighbors); - } else { - pfr.element_size = MAXFLOAT; - } - sphdata->element_size = pfr.element_size; - copy_v3_v3(sphdata->flow, pfr.flow); pressure = stiffness * (pfr.density - rest_density); near_pressure = stiffness_near_fac * pfr.near_density; @@ -2462,6 +2489,7 @@ if(spring_constant > 0.f) { /* Viscoelastic spring force */ if (pfn->psys == psys[0] && fluid->flag & SPH_VISCOELASTIC_SPRINGS && springhash) { + /* BLI_edgehash_lookup appears to be thread-safe. - z0r */ spring_index = GET_INT_FROM_POINTER(BLI_edgehash_lookup(springhash, index, pfn->index)); if(spring_index) { @@ -2475,7 +2503,9 @@ temp_spring.particle_index[1] = pfn->index; temp_spring.rest_length = (fluid->flag & SPH_CURRENT_REST_LENGTH) ? rij : rest_length; temp_spring.delete_flag = 0; - + + /* sph_spring_add is not thread-safe. - z0r */ + #pragma omp critical sph_spring_add(psys[0], &temp_spring); } } @@ -2488,28 +2518,52 @@ /* Artificial buoyancy force in negative gravity direction */ if (fluid->buoyancy > 0.f && gravity) madd_v3_v3fl(force, gravity, fluid->buoyancy * (pfr.density-rest_density)); + + if (sphdata->pass == 0 && psys[0]->part->time_flag & PART_TIME_AUTOSF) + sph_particle_courant(sphdata, &pfr); + sphdata->pass++; } -static void sph_integrate(ParticleSimulationData *sim, ParticleData *pa, float dfra, float *gravity, EdgeHash *springhash, float *element_size, float flow[3]) { +static void sph_solver_init(ParticleSimulationData *sim, SPHData *sphdata) { ParticleTarget *pt; int i; + // Add other coupled particle systems. + sphdata->psys[0] = sim->psys; + for(i=1, pt=sim->psys->targets.first; i<10; i++, pt=(pt?pt->next:NULL)) + sphdata->psys[i] = pt ? psys_get_target_system(sim->ob, pt) : NULL; + + if (psys_uses_gravity(sim)) + sphdata->gravity = sim->scene->physics_settings.gravity; + else + sphdata->gravity = NULL; + sphdata->eh = sph_springhash_build(sim->psys); + + // These per-particle values should be overridden later, but just for + // completeness we give them default values now. + sphdata->pa = NULL; + sphdata->mass = 1.0f; + + sphdata->force_cb = sph_force_cb; + sphdata->density_cb = sph_density_accum_cb; +} +static void sph_solver_finalise(SPHData *sphdata) { + if (sphdata->eh) { + BLI_edgehash_free(sphdata->eh, NULL); + sphdata->eh = NULL; + } +} +static void sph_integrate(ParticleSimulationData *sim, ParticleData *pa, float dfra, SPHData *sphdata){ ParticleSettings *part = sim->psys->part; // float timestep = psys_get_timestep(sim); // UNUSED float pa_mass = part->mass * (part->flag & PART_SIZEMASS ? pa->size : 1.f); float dtime = dfra*psys_get_timestep(sim); // int steps = 1; // UNUSED float effector_acceleration[3]; - SPHData sphdata; - sphdata.psys[0] = sim->psys; - for(i=1, pt=sim->psys->targets.first; i<10; i++, pt=(pt?pt->next:NULL)) - sphdata.psys[i] = pt ? psys_get_target_system(sim->ob, pt) : NULL; - - sphdata.pa = pa; - sphdata.gravity = gravity; - sphdata.mass = pa_mass; - sphdata.eh = springhash; + sphdata->pa = pa; + sphdata->mass = pa_mass; + sphdata->pass = 0; //sphdata.element_size and sphdata.flow are set in the callback. /* restore previous state and treat gravity & effectors as external acceleration*/ @@ -2518,9 +2572,7 @@ copy_particle_key(&pa->state, &pa->prev_state, 0); - integrate_particle(part, pa, dtime, effector_acceleration, sph_force_cb, &sphdata); - *element_size = sphdata.element_size; - copy_v3_v3(flow, sphdata.flow); + integrate_particle(part, pa, dtime, effector_acceleration, sphdata->force_cb, sphdata); } /************************************************/ @@ -3293,7 +3345,8 @@ * -uses Newton-Rhapson iteration to find the collisions * -handles spherical particles and (nearly) point like particles */ -static void collision_check(ParticleSimulationData *sim, int p, float dfra, float cfra){ +static void collision_check(ParticleSimulationData *sim, int p, float dfra, float cfra) +{ ParticleSettings *part = sim->psys->part; ParticleData *pa = sim->psys->particles + p; ParticleCollision col; @@ -3354,6 +3407,7 @@ ParticleSystem *psys = sim->psys; ParticleSettings *part = psys->part; ParticleEditSettings *pset = &sim->scene->toolsettings->particle; + Base *base; int distr=0, alloc=0, skip=0; if((psys->part->childtype && psys->totchild != get_psys_tot_child(sim->scene, psys)) || psys->recalc&PSYS_RECALC_RESET) @@ -3396,6 +3450,19 @@ } } + + /* particle instance modifier with "path" option need cached paths even if particle system doesn't */ + for (base = sim->scene->base.first; base; base= base->next) { + ModifierData *md = modifiers_findByType(base->object, eModifierType_ParticleInstance); + if(md) { + ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md; + if(pimd->flag & eParticleInstanceFlag_Path && pimd->ob == sim->ob && pimd->psys == (psys - (ParticleSystem*)sim->ob->particlesystem.first)) { + skip = 0; + break; + } + } + } + if(!skip) { psys_cache_paths(sim, cfra); @@ -3427,6 +3494,7 @@ int totedge; int k; float hairmat[4][4]; + float (*deformedVerts)[3]; if(!psys->clmd) { psys->clmd = (ClothModifierData*)modifier_new(eModifierType_Cloth); @@ -3520,7 +3588,15 @@ psys->clmd->point_cache = psys->pointcache; psys->clmd->sim_parms->effector_weights = psys->part->effector_weights; - psys->hair_out_dm = clothModifier_do(psys->clmd, sim->scene, sim->ob, dm); + deformedVerts = MEM_callocN(sizeof(*deformedVerts)*dm->getNumVerts(dm), "do_hair_dynamics vertexCos"); + psys->hair_out_dm = CDDM_copy(dm); + psys->hair_out_dm->getVertCos(psys->hair_out_dm, deformedVerts); + + clothModifier_do(psys->clmd, sim->scene, sim->ob, dm, deformedVerts); + + CDDM_apply_vert_coords(psys->hair_out_dm, deformedVerts); + + MEM_freeN(deformedVerts); psys->clmd->sim_parms->effector_weights = NULL; } @@ -3561,7 +3637,8 @@ psys->flag |= PSYS_HAIR_UPDATED; } -static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra)){ +static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra)) +{ Object *ob = sim->ob; ParticleSystem *psys = sim->psys; HairKey *key, *root; @@ -3618,15 +3695,15 @@ step, after the velocity has been updated. element_size defines the scale of the simulation, and is typically the distance to neighbourning particles. */ void update_courant_num(ParticleSimulationData *sim, ParticleData *pa, - float dtime, float element_size, float flow[3]) + float dtime, SPHData *sphdata) { float relative_vel[3]; float speed; - sub_v3_v3v3(relative_vel, pa->state.vel, flow); + sub_v3_v3v3(relative_vel, pa->prev_state.vel, sphdata->flow); speed = len_v3(relative_vel); - if (sim->courant_num < speed * dtime / element_size) - sim->courant_num = speed * dtime / element_size; + if (sim->courant_num < speed * dtime / sphdata->element_size) + sim->courant_num = speed * dtime / sphdata->element_size; } /* Update time step size to suit current conditions. */ float update_timestep(ParticleSystem *psys, ParticleSimulationData *sim, @@ -3712,11 +3789,11 @@ case PART_PHYS_FLUID: { ParticleTarget *pt = psys->targets.first; - psys_update_particle_bvhtree(psys, psys->cfra); + psys_update_particle_bvhtree(psys, cfra); for(; pt; pt=pt->next) { /* Updating others systems particle tree for fluid-fluid interaction */ if(pt->ob) - psys_update_particle_bvhtree(BLI_findlink(&pt->ob->particlesystem, pt->psys-1), psys->cfra); + psys_update_particle_bvhtree(BLI_findlink(&pt->ob->particlesystem, pt->psys-1), cfra); } break; } @@ -3798,37 +3875,32 @@ } case PART_PHYS_FLUID: { - EdgeHash *springhash = sph_springhash_build(psys); - float *gravity = NULL; - float element_size, flow[3]; - - if(psys_uses_gravity(sim)) - gravity = sim->scene->physics_settings.gravity; + SPHData sphdata; + sph_solver_init(sim, &sphdata); + #pragma omp parallel for firstprivate (sphdata) private (pa) schedule(dynamic,5) LOOP_DYNAMIC_PARTICLES { /* do global forces & effectors */ basic_integrate(sim, p, pa->state.time, cfra); /* actual fluids calculations */ - sph_integrate(sim, pa, pa->state.time, gravity, springhash, - &element_size, flow); + sph_integrate(sim, pa, pa->state.time, &sphdata); if(sim->colliders) collision_check(sim, p, pa->state.time, cfra); - /* SPH particles are not physical particles, just interpolation particles, thus rotation has not a direct sense for them */ + /* SPH particles are not physical particles, just interpolation + * particles, thus rotation has not a direct sense for them */ basic_rotate(part, pa, pa->state.time, timestep); + #pragma omp critical if (part->time_flag & PART_TIME_AUTOSF) - update_courant_num(sim, pa, dtime, element_size, flow); + update_courant_num(sim, pa, dtime, &sphdata); } sph_springs_modify(psys, timestep); - if(springhash) { - BLI_edgehash_free(springhash, NULL); - springhash = NULL; - } + sph_solver_finalise(&sphdata); break; } } @@ -4241,7 +4313,8 @@ } } -static void fluid_default_settings(ParticleSettings *part){ +static void fluid_default_settings(ParticleSettings *part) +{ SPHFluidSettings *fluid = part->fluid; fluid->spring_k = 0.f; @@ -4355,6 +4428,7 @@ if(psys->totpart == 0 && part->totpart == 0) { psys_free_path_cache(psys, NULL); free_hair(ob, psys, 0); + psys->flag |= PSYS_HAIR_DONE; } /* (re-)create hair */ else if(hair_needs_recalc(psys)) { diff -Nru blender-2.61/source/blender/blenkernel/intern/pointcache.c blender-2.62/source/blender/blenkernel/intern/pointcache.c --- blender-2.61/source/blender/blenkernel/intern/pointcache.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/pointcache.c 2012-02-15 19:34:02.000000000 +0000 @@ -1491,7 +1491,7 @@ static void ptcache_find_frames_around(PTCacheID *pid, unsigned int frame, int *fra1, int *fra2) { if(pid->cache->flag & PTCACHE_DISK_CACHE) { - int cfra1=frame-1, cfra2=frame+1; + int cfra1=frame, cfra2=frame+1; while(cfra1 >= pid->cache->startframe && !BKE_ptcache_id_exist(pid, cfra1)) cfra1--; @@ -1518,7 +1518,7 @@ PTCacheMem *pm = pid->cache->mem_cache.first; PTCacheMem *pm2 = pid->cache->mem_cache.last; - while(pm->next && pm->next->frame < frame) + while(pm->next && pm->next->frame <= frame) pm= pm->next; if(pm2->frame < frame) { @@ -1841,7 +1841,7 @@ /* possible to get old or interpolated result */ int BKE_ptcache_read(PTCacheID *pid, float cfra) { - int cfrai = (int)cfra, cfra1=0, cfra2=0; + int cfrai = (int)floor(cfra), cfra1=0, cfra2=0; int ret = 0; /* nothing to read to */ @@ -3096,7 +3096,7 @@ } closedir(dir); - strcpy(pid->cache->name, old_name); + BLI_strncpy(pid->cache->name, old_name, sizeof(pid->cache->name)); } void BKE_ptcache_load_external(PTCacheID *pid) @@ -3217,11 +3217,11 @@ /* smoke doesn't use frame 0 as info frame so can't check based on totpoint */ if(pid->type == PTCACHE_TYPE_SMOKE_DOMAIN && totframes) - sprintf(cache->info, "%i frames found!", totframes); + BLI_snprintf(cache->info, sizeof(cache->info), "%i frames found!", totframes); else if(totframes && cache->totpoint) - sprintf(cache->info, "%i points found!", cache->totpoint); + BLI_snprintf(cache->info, sizeof(cache->info), "%i points found!", cache->totpoint); else - sprintf(cache->info, "No valid data to read!"); + BLI_snprintf(cache->info, sizeof(cache->info), "No valid data to read!"); return; } @@ -3231,9 +3231,9 @@ int totpoint = pid->totpoint(pid->calldata, 0); if(cache->totpoint > totpoint) - sprintf(mem_info, "%i cells + High Resolution cached", totpoint); + BLI_snprintf(mem_info, sizeof(mem_info), "%i cells + High Resolution cached", totpoint); else - sprintf(mem_info, "%i cells cached", totpoint); + BLI_snprintf(mem_info, sizeof(mem_info), "%i cells cached", totpoint); } else { int cfra = cache->startframe; @@ -3243,7 +3243,7 @@ totframes++; } - sprintf(mem_info, "%i frames on disk", totframes); + BLI_snprintf(mem_info, sizeof(mem_info), "%i frames on disk", totframes); } } else { @@ -3267,20 +3267,21 @@ mb = (bytes > 1024.0f * 1024.0f); - sprintf(mem_info, "%i frames in memory (%.1f %s)", + BLI_snprintf(mem_info, sizeof(mem_info), "%i frames in memory (%.1f %s)", totframes, bytes / (mb ? 1024.0f * 1024.0f : 1024.0f), mb ? "Mb" : "kb"); } if(cache->flag & PTCACHE_OUTDATED) { - sprintf(cache->info, "%s, cache is outdated!", mem_info); + BLI_snprintf(cache->info, sizeof(cache->info), "%s, cache is outdated!", mem_info); } else if(cache->flag & PTCACHE_FRAMES_SKIPPED) { - sprintf(cache->info, "%s, not exact since frame %i.", mem_info, cache->last_exact); + BLI_snprintf(cache->info, sizeof(cache->info), "%s, not exact since frame %i.", mem_info, cache->last_exact); + } + else { + BLI_snprintf(cache->info, sizeof(cache->info), "%s.", mem_info); } - else - sprintf(cache->info, "%s.", mem_info); } void BKE_ptcache_validate(PointCache *cache, int framenr) diff -Nru blender-2.61/source/blender/blenkernel/intern/property.c blender-2.62/source/blender/blenkernel/intern/property.c --- blender-2.61/source/blender/blenkernel/intern/property.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/property.c 2012-02-15 19:34:02.000000000 +0000 @@ -171,7 +171,7 @@ i= 0; do { /* ensure we have enough chars for the new number in the name */ - sprintf(num, "%d", i++); + BLI_snprintf(num, sizeof(num), "%d", i++); BLI_strncpy(new_name, base_name, sizeof(prop->name) - strlen(num)); strcat(new_name, num); } while(get_property__internal(first, prop, new_name)); diff -Nru blender-2.61/source/blender/blenkernel/intern/sca.c blender-2.62/source/blender/blenkernel/intern/sca.c --- blender-2.61/source/blender/blenkernel/intern/sca.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/sca.c 2012-02-15 19:34:02.000000000 +0000 @@ -428,7 +428,7 @@ case ACT_CAMERA: act->data= MEM_callocN(sizeof(bCameraActuator), "camact"); ca = act->data; - ca->axis = ACT_CAMERA_X; + ca->axis = OB_POSX; ca->damping = 1.0/32.0; break; case ACT_EDIT_OBJECT: diff -Nru blender-2.61/source/blender/blenkernel/intern/scene.c blender-2.62/source/blender/blenkernel/intern/scene.c --- blender-2.61/source/blender/blenkernel/intern/scene.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/scene.c 2012-02-15 19:34:02.000000000 +0000 @@ -78,8 +78,6 @@ //XXX #include "BIF_previewrender.h" //XXX #include "BIF_editseq.h" -//XXX #include "nla.h" - #ifdef WIN32 #else #include @@ -299,6 +297,10 @@ free_paint(&sce->toolsettings->sculpt->paint); MEM_freeN(sce->toolsettings->sculpt); } + if(sce->toolsettings->uvsculpt) { + free_paint(&sce->toolsettings->uvsculpt->paint); + MEM_freeN(sce->toolsettings->uvsculpt); + } free_paint(&sce->toolsettings->imapaint.paint); MEM_freeN(sce->toolsettings); @@ -529,6 +531,8 @@ sce->gm.recastData.detailsampledist = 6.0f; sce->gm.recastData.detailsamplemaxerror = 1.0f; + sce->gm.exitkey = 218; // Blender key code for ESC + sound_create_scene(sce); return sce; diff -Nru blender-2.61/source/blender/blenkernel/intern/seqeffects.c blender-2.62/source/blender/blenkernel/intern/seqeffects.c --- blender-2.61/source/blender/blenkernel/intern/seqeffects.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/seqeffects.c 2012-02-15 19:34:02.000000000 +0000 @@ -176,7 +176,7 @@ MEM_freeN(info); cp= BLI_dynlib_find_symbol(pis->handle, "seqname"); - if(cp) BLI_strncpy(cp, seqname, 21); + if(cp) BLI_strncpy(cp, seqname, SEQ_NAME_MAXSTR); } else { printf ("Plugin returned unrecognized version number\n"); return; @@ -303,7 +303,10 @@ cp = BLI_dynlib_find_symbol( seq->plugin->handle, "seqname"); - if(cp) strncpy(cp, seq->name+2, 22); + /* XXX: it's crappy to limit copying buffer by it's lemgth, + * but assuming plugin stuff is using correct buffer size + * it should be fine */ + if(cp) strncpy(cp, seq->name+2, sizeof(seq->name)-2); if (seq->plugin->current_private_data) { *seq->plugin->current_private_data @@ -1574,44 +1577,35 @@ int flip; int xo, yo; int width; - float invwidth; float pythangle; } WipeZone; static void precalc_wipe_zone(WipeZone *wipezone, WipeVars *wipe, int xo, int yo) { wipezone->flip = (wipe->angle < 0); - wipezone->angle = tan(DEG2RAD(fabsf(wipe->angle))); + wipezone->angle = tanf(DEG2RADF(fabsf(wipe->angle))); wipezone->xo = xo; wipezone->yo = yo; wipezone->width = (int)(wipe->edgeWidth*((xo+yo)/2.0f)); - wipezone->pythangle = 1.0f/sqrtf(wipe->angle*wipe->angle + 1.0f); - - if(wipe->wipetype == DO_SINGLE_WIPE) - wipezone->invwidth = 1.0f/wipezone->width; - else - wipezone->invwidth = 1.0f/(0.5f*wipezone->width); + wipezone->pythangle = 1.0f/sqrtf(wipezone->angle*wipezone->angle + 1.0f); } // This function calculates the blur band for the wipe effects -static float in_band(WipeZone *wipezone,float width,float dist,float perc,int side,int dir) +static float in_band(float width,float dist,int side,int dir) { - float t1,t2,alpha; + float alpha; if(width == 0) return (float)side; - + if(width < dist) - return side; - - t1 = dist * wipezone->invwidth; //percentange of width that is - t2 = wipezone->invwidth; //amount of alpha per % point - + return (float)side; + if(side == 1) - alpha = (t1*t2*100) + (1-perc); // add point's alpha contrib to current position in wipe + alpha = (dist+0.5f*width) / (width); else - alpha = (1-perc) - (t1*t2*100); - + alpha = (0.5f*width-dist) / (width); + if(dir == 0) alpha = 1-alpha; @@ -1648,7 +1642,6 @@ switch (wipe->wipetype) { case DO_SINGLE_WIPE: width = wipezone->width; - hwidth = width*0.5f; if(angle == 0.0f) { b1 = posy; @@ -1669,15 +1662,15 @@ if(wipe->forward) { if(b1 < b2) - output = in_band(wipezone,width,hyp,facf0,1,1); + output = in_band(width,hyp,1,1); else - output = in_band(wipezone,width,hyp,facf0,0,1); + output = in_band(width,hyp,0,1); } else { if(b1 < b2) - output = in_band(wipezone,width,hyp,facf0,0,1); + output = in_band(width,hyp,0,1); else - output = in_band(wipezone,width,hyp,facf0,1,1); + output = in_band(width,hyp,1,1); } break; @@ -1700,27 +1693,23 @@ b3 = (yo-posy*0.5f) - (-angle)*(xo-posx*0.5f); b2 = y - (-angle)*x; - hyp = abs(angle*x+y+(-posy*0.5f-angle*posx*0.5f))*wipezone->pythangle; - hyp2 = abs(angle*x+y+(-(yo-posy*0.5f)-angle*(xo-posx*0.5f)))*wipezone->pythangle; + hyp = fabsf(angle*x+y+(-posy*0.5f-angle*posx*0.5f))*wipezone->pythangle; + hyp2 = fabsf(angle*x+y+(-(yo-posy*0.5f)-angle*(xo-posx*0.5f)))*wipezone->pythangle; } - temp1 = xo*(1-facf0*0.5f)-xo*facf0*0.5f; - temp2 = yo*(1-facf0*0.5f)-yo*facf0*0.5f; - pointdist = sqrt(temp1*temp1 + temp2*temp2); + hwidth= MIN2(hwidth, fabsf(b3-b1)/2.0f); if(b2 < b1 && b2 < b3 ){ - if(hwidth < pointdist) - output = in_band(wipezone,hwidth,hyp,facf0,0,1); + output = in_band(hwidth,hyp,0,1); } else if(b2 > b1 && b2 > b3 ){ - if(hwidth < pointdist) - output = in_band(wipezone,hwidth,hyp2,facf0,0,1); + output = in_band(hwidth,hyp2,0,1); } else { if( hyp < hwidth && hyp2 > hwidth ) - output = in_band(wipezone,hwidth,hyp,facf0,1,1); + output = in_band(hwidth,hyp,1,1); else if( hyp > hwidth && hyp2 < hwidth ) - output = in_band(wipezone,hwidth,hyp2,facf0,1,1); + output = in_band(hwidth,hyp2,1,1); else - output = in_band(wipezone,hwidth,hyp2,facf0,1,1) * in_band(wipezone,hwidth,hyp,facf0,1,1); + output = in_band(hwidth,hyp2,1,1) * in_band(hwidth,hyp,1,1); } if(!wipe->forward)output = 1-output; break; @@ -1840,8 +1829,8 @@ pointdist = sqrt(temp1*temp1 + temp1*temp1); temp2 = sqrt((halfx-x)*(halfx-x) + (halfy-y)*(halfy-y)); - if(temp2 > pointdist) output = in_band(wipezone,hwidth,fabs(temp2-pointdist),facf0,0,1); - else output = in_band(wipezone,hwidth,fabs(temp2-pointdist),facf0,1,1); + if(temp2 > pointdist) output = in_band(hwidth,fabs(temp2-pointdist),0,1); + else output = in_band(hwidth,fabs(temp2-pointdist),1,1); if(!wipe->forward) output = 1-output; diff -Nru blender-2.61/source/blender/blenkernel/intern/sequencer.c blender-2.62/source/blender/blenkernel/intern/sequencer.c --- blender-2.61/source/blender/blenkernel/intern/sequencer.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/sequencer.c 2012-02-15 19:34:02.000000000 +0000 @@ -523,31 +523,12 @@ } -void calc_sequence_disp(Scene *scene, Sequence *seq) -{ - if(seq->startofs && seq->startstill) seq->startstill= 0; - if(seq->endofs && seq->endstill) seq->endstill= 0; - - seq->startdisp= seq->start + seq->startofs - seq->startstill; - seq->enddisp= seq->start+seq->len - seq->endofs + seq->endstill; - - seq->handsize= 10.0; /* 10 frames */ - if( seq->enddisp-seq->startdisp < 10 ) { - seq->handsize= (float)(0.5*(seq->enddisp-seq->startdisp)); - } - else if(seq->enddisp-seq->startdisp > 250) { - seq->handsize= (float)((seq->enddisp-seq->startdisp)/25); - } - - seq_update_sound_bounds(scene, seq); -} - static void seq_update_sound_bounds_recursive(Scene *scene, Sequence *metaseq) { Sequence *seq; /* for sound we go over full meta tree to update bounds of the sound strips, - since sound is played outside of evaluating the imbufs, */ + * since sound is played outside of evaluating the imbufs, */ for(seq=metaseq->seqbase.first; seq; seq=seq->next) { if(seq->type == SEQ_META) { seq_update_sound_bounds_recursive(scene, seq); @@ -567,6 +548,29 @@ } } +void calc_sequence_disp(Scene *scene, Sequence *seq) +{ + if(seq->startofs && seq->startstill) seq->startstill= 0; + if(seq->endofs && seq->endstill) seq->endstill= 0; + + seq->startdisp= seq->start + seq->startofs - seq->startstill; + seq->enddisp= seq->start+seq->len - seq->endofs + seq->endstill; + + seq->handsize= 10.0; /* 10 frames */ + if( seq->enddisp-seq->startdisp < 10 ) { + seq->handsize= (float)(0.5*(seq->enddisp-seq->startdisp)); + } + else if(seq->enddisp-seq->startdisp > 250) { + seq->handsize= (float)((seq->enddisp-seq->startdisp)/25); + } + + if(ELEM(seq->type, SEQ_SOUND, SEQ_SCENE)) { + seq_update_sound_bounds(scene, seq); + } + else if(seq->type == SEQ_META) + seq_update_sound_bounds_recursive(scene, seq); +} + void calc_sequence(Scene *scene, Sequence *seq) { Sequence *seqm; @@ -745,7 +749,7 @@ seq->scene = sce; } - seq->len= seq->scene->r.efra - seq->scene->r.sfra + 1; + seq->len= (seq->scene)? seq->scene->r.efra - seq->scene->r.sfra + 1: 0; seq->len -= seq->anim_startofs; seq->len -= seq->anim_endofs; if (seq->len < 0) { @@ -833,8 +837,8 @@ typedef struct SeqUniqueInfo { Sequence *seq; - char name_src[32]; - char name_dest[32]; + char name_src[SEQ_NAME_MAXSTR]; + char name_dest[SEQ_NAME_MAXSTR]; int count; int match; } SeqUniqueInfo; @@ -850,7 +854,8 @@ Sequence *seq; for(seq=seqbasep->first; seq; seq= seq->next) { if (sui->seq != seq && strcmp(sui->name_dest, seq->name+2)==0) { - sprintf(sui->name_dest, "%.17s.%03d", sui->name_src, sui->count++); /*24 - 2 for prefix, -1 for \0 */ + /* SEQ_NAME_MAXSTR - 2 for prefix, -1 for \0, -4 for the number */ + BLI_snprintf(sui->name_dest, sizeof(sui->name_dest), "%.59s.%03d", sui->name_src, sui->count++); sui->match= 1; /* be sure to re-scan */ } } @@ -1689,10 +1694,10 @@ if(rct) { float rgb[3]; for (i = ibuf->x * ibuf->y; i > 0; i--, rct+=4) { - rgb_byte_to_float(rct, rgb); + rgb_uchar_to_float(rgb, rct); rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); hsv_to_rgb(hsv[0], hsv[1] * sat, hsv[2], rgb, rgb+1, rgb+2); - rgb_float_to_byte(rgb, rct); + rgb_float_to_uchar(rct, rgb); } } @@ -2025,7 +2030,10 @@ } /* float buffers in the sequencer are not linear */ - ibuf->profile= IB_PROFILE_LINEAR_RGB; + if(scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) + ibuf->profile= IB_PROFILE_LINEAR_RGB; + else + ibuf->profile= IB_PROFILE_NONE; IMB_convert_profile(ibuf, IB_PROFILE_SRGB); } else if (rres.rect32) { @@ -2572,8 +2580,8 @@ seq_thread_shutdown = TRUE; - pthread_cond_broadcast(&wakeup_cond); - pthread_mutex_unlock(&wakeup_lock); + pthread_cond_broadcast(&wakeup_cond); + pthread_mutex_unlock(&wakeup_lock); for(tslot = running_threads.first; tslot; tslot= tslot->next) { pthread_join(tslot->pthread, NULL); @@ -3067,10 +3075,10 @@ } else { if(seq->sound) { - seq->scene_sound = sound_add_scene_sound(scene, seq, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); + seq->scene_sound = sound_add_scene_sound_defaults(scene, seq); } if(seq->scene) { - sound_scene_add_scene_sound(scene, seq, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); + sound_scene_add_scene_sound_defaults(scene, seq); } } } @@ -3224,10 +3232,8 @@ void seq_update_sound_bounds(Scene* scene, Sequence *seq) { - if(seq->scene_sound) { - sound_move_scene_sound(scene, seq->scene_sound, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); - /* mute is set in seq_update_muting_recursive */ - } + sound_move_scene_sound_defaults(scene, seq); + /* mute is set in seq_update_muting_recursive */ } static void seq_update_muting_recursive(ListBase *seqbasep, Sequence *metaseq, int mute) @@ -3387,13 +3393,13 @@ /* XXX - hackish function needed for transforming strips! TODO - have some better solution */ void seq_offset_animdata(Scene *scene, Sequence *seq, int ofs) { - char str[32]; + char str[SEQ_NAME_MAXSTR+3]; FCurve *fcu; if(scene->adt==NULL || ofs==0 || scene->adt->action==NULL) return; - sprintf(str, "[\"%s\"]", seq->name+2); + BLI_snprintf(str, sizeof(str), "[\"%s\"]", seq->name+2); for (fcu= scene->adt->action->curves.first; fcu; fcu= fcu->next) { if(strstr(fcu->rna_path, "sequence_editor.sequences_all[") && strstr(fcu->rna_path, str)) { @@ -3410,7 +3416,7 @@ void seq_dupe_animdata(Scene *scene, const char *name_src, const char *name_dst) { - char str_from[32]; + char str_from[SEQ_NAME_MAXSTR+3]; FCurve *fcu; FCurve *fcu_last; FCurve *fcu_cpy; @@ -3419,7 +3425,7 @@ if(scene->adt==NULL || scene->adt->action==NULL) return; - sprintf(str_from, "[\"%s\"]", name_src); + BLI_snprintf(str_from, sizeof(str_from), "[\"%s\"]", name_src); fcu_last= scene->adt->action->curves.last; @@ -3440,13 +3446,13 @@ /* XXX - hackish function needed to remove all fcurves belonging to a sequencer strip */ static void seq_free_animdata(Scene *scene, Sequence *seq) { - char str[32]; + char str[SEQ_NAME_MAXSTR+3]; FCurve *fcu; if(scene->adt==NULL || scene->adt->action==NULL) return; - sprintf(str, "[\"%s\"]", seq->name+2); + BLI_snprintf(str, sizeof(str), "[\"%s\"]", seq->name+2); fcu= scene->adt->action->curves.first; @@ -3769,7 +3775,7 @@ } else if(seq->type == SEQ_SCENE) { seqn->strip->stripdata = NULL; if(seq->scene_sound) - seqn->scene_sound = sound_scene_add_scene_sound(sce_audio, seqn, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); + seqn->scene_sound = sound_scene_add_scene_sound_defaults(sce_audio, seqn); } else if(seq->type == SEQ_MOVIE) { seqn->strip->stripdata = MEM_dupallocN(seq->strip->stripdata); @@ -3778,7 +3784,7 @@ seqn->strip->stripdata = MEM_dupallocN(seq->strip->stripdata); if(seq->scene_sound) - seqn->scene_sound = sound_add_scene_sound(sce_audio, seqn, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); + seqn->scene_sound = sound_add_scene_sound_defaults(sce_audio, seqn); seqn->sound->id.us++; } else if(seq->type == SEQ_IMAGE) { diff -Nru blender-2.61/source/blender/blenkernel/intern/smoke.c blender-2.62/source/blender/blenkernel/intern/smoke.c --- blender-2.61/source/blender/blenkernel/intern/smoke.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/smoke.c 2012-02-15 19:34:02.000000000 +0000 @@ -77,6 +77,9 @@ #include "BKE_smoke.h" +/* UNUSED so far, may be enabled later */ +/* #define USE_SMOKE_COLLISION_DM */ + #ifdef WITH_SMOKE #ifdef _WIN32 @@ -617,9 +620,11 @@ smd->coll->bvhtree = NULL; } +#ifdef USE_SMOKE_COLLISION_DM if(smd->coll->dm) smd->coll->dm->release(smd->coll->dm); smd->coll->dm = NULL; +#endif MEM_freeN(smd->coll); smd->coll = NULL; @@ -682,9 +687,11 @@ smd->coll->bvhtree = NULL; } +#ifdef USE_SMOKE_COLLISION_DM if(smd->coll->dm) smd->coll->dm->release(smd->coll->dm); smd->coll->dm = NULL; +#endif } } @@ -772,7 +779,10 @@ smd->coll->points = NULL; smd->coll->numpoints = 0; smd->coll->bvhtree = NULL; + +#ifdef USE_SMOKE_COLLISION_DM smd->coll->dm = NULL; +#endif } } } @@ -1339,11 +1349,13 @@ { // XXX TODO smd->time = scene->r.cfra; - + +#ifdef USE_SMOKE_COLLISION_DM if(smd->coll->dm) smd->coll->dm->release(smd->coll->dm); smd->coll->dm = CDDM_copy(dm); +#endif // rigid movement support copy_m4_m4(smd->coll->mat_old, smd->coll->mat); diff -Nru blender-2.61/source/blender/blenkernel/intern/softbody.c blender-2.62/source/blender/blenkernel/intern/softbody.c --- blender-2.61/source/blender/blenkernel/intern/softbody.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/softbody.c 2012-02-15 19:34:02.000000000 +0000 @@ -3468,7 +3468,7 @@ bs->len= globallen((bp-dw-dv-1)->vec, bp->vec,ob); bs++; } - if( (v < lt->pntsv-1) && (u) ) { + if( (v < lt->pntsv-1) && (u != 0) ) { bs->v1 = bpc; bs->v2 = bpc-dw+dv-1; bs->springtype=SB_BEND; @@ -3485,7 +3485,7 @@ bs->len= globallen((bp+dw-dv-1)->vec, bp->vec,ob); bs++; } - if( (v < lt->pntsv-1) && (u) ) { + if( (v < lt->pntsv-1) && (u != 0) ) { bs->v1 = bpc; bs->v2 = bpc+dw+dv-1; bs->springtype=SB_BEND; @@ -3728,6 +3728,8 @@ if(!sb->effector_weights) sb->effector_weights = BKE_add_effector_weights(NULL); + sb->last_frame= MINFRAME-1; + return sb; } @@ -4108,6 +4110,7 @@ softbody_update_positions(ob, sb, vertexCos, numVerts); softbody_step(scene, ob, sb, dtime); softbody_to_object(ob, vertexCos, numVerts, 0); + sb->last_frame = framenr; return; } @@ -4123,6 +4126,9 @@ BKE_ptcache_validate(cache, framenr); cache->flag &= ~PTCACHE_REDO_NEEDED; + + sb->last_frame = framenr; + return; } @@ -4137,6 +4143,8 @@ if(cache_result == PTCACHE_READ_INTERPOLATED && cache->flag & PTCACHE_REDO_NEEDED) BKE_ptcache_write(&pid, framenr); + sb->last_frame = framenr; + return; } else if(cache_result==PTCACHE_READ_OLD) { @@ -4148,6 +4156,9 @@ return; } + if(framenr!=sb->last_frame+1) + return; + /* if on second frame, write cache for first frame */ if(cache->simframe == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0)) BKE_ptcache_write(&pid, startframe); @@ -4164,5 +4175,7 @@ BKE_ptcache_validate(cache, framenr); BKE_ptcache_write(&pid, framenr); + + sb->last_frame = framenr; } diff -Nru blender-2.61/source/blender/blenkernel/intern/sound.c blender-2.62/source/blender/blenkernel/intern/sound.c --- blender-2.61/source/blender/blenkernel/intern/sound.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/sound.c 2012-02-15 19:34:02.000000000 +0000 @@ -233,7 +233,7 @@ { bSound* sound = NULL; - char name[25]; + char name[MAX_ID_NAME+5]; strcpy(name, "buf_"); strcpy(name + 4, source->id.name); @@ -257,7 +257,7 @@ { bSound* sound = NULL; - char name[25]; + char name[MAX_ID_NAME+5]; strcpy(name, "lim_"); strcpy(name + 4, source->id.name); @@ -449,6 +449,13 @@ return NULL; } +void* sound_scene_add_scene_sound_defaults(struct Scene *scene, struct Sequence* sequence) +{ + return sound_scene_add_scene_sound(scene, sequence, + sequence->startdisp, sequence->enddisp, + sequence->startofs + sequence->anim_startofs); +} + void* sound_add_scene_sound(struct Scene *scene, struct Sequence* sequence, int startframe, int endframe, int frameskip) { void* handle = AUD_addSequence(scene->sound_scene, sequence->sound->playback_handle, startframe / FPS, endframe / FPS, frameskip / FPS); @@ -459,6 +466,13 @@ return handle; } +void* sound_add_scene_sound_defaults(struct Scene *scene, struct Sequence* sequence) +{ + return sound_add_scene_sound(scene, sequence, + sequence->startdisp, sequence->enddisp, + sequence->startofs + sequence->anim_startofs); +} + void sound_remove_scene_sound(struct Scene *scene, void* handle) { AUD_removeSequence(scene->sound_scene, handle); @@ -474,6 +488,15 @@ AUD_moveSequence(handle, startframe / FPS, endframe / FPS, frameskip / FPS); } +void sound_move_scene_sound_defaults(struct Scene *scene, struct Sequence* sequence) +{ + if (sequence->scene_sound) { + sound_move_scene_sound(scene, sequence->scene_sound, + sequence->startdisp, sequence->enddisp, + sequence->startofs + sequence->anim_startofs); + } +} + void sound_update_scene_sound(void* handle, struct bSound* sound) { AUD_updateSequenceSound(handle, sound->playback_handle); @@ -781,11 +804,13 @@ void sound_destroy_scene(struct Scene *UNUSED(scene)) {} void sound_mute_scene(struct Scene *UNUSED(scene), int UNUSED(muted)) {} void* sound_scene_add_scene_sound(struct Scene *UNUSED(scene), struct Sequence* UNUSED(sequence), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) { return NULL; } +void* sound_scene_add_scene_sound_defaults(struct Scene *UNUSED(scene), struct Sequence* UNUSED(sequence)) { return NULL; } void* sound_add_scene_sound(struct Scene *UNUSED(scene), struct Sequence* UNUSED(sequence), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) { return NULL; } +void* sound_add_scene_sound_defaults(struct Scene *UNUSED(scene), struct Sequence* UNUSED(sequence)) { return NULL; } void sound_remove_scene_sound(struct Scene *UNUSED(scene), void* UNUSED(handle)) {} void sound_mute_scene_sound(void* UNUSED(handle), char UNUSED(mute)) {} void sound_move_scene_sound(struct Scene *UNUSED(scene), void* UNUSED(handle), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) {} -static void sound_start_play_scene(struct Scene *UNUSED(scene)) {} +void sound_move_scene_sound_defaults(struct Scene *UNUSED(scene), struct Sequence *UNUSED(sequence)) {} void sound_play_scene(struct Scene *UNUSED(scene)) {} void sound_stop_scene(struct Scene *UNUSED(scene)) {} void sound_seek_scene(struct Main *UNUSED(bmain), struct Scene *UNUSED(scene)) {} diff -Nru blender-2.61/source/blender/blenkernel/intern/subsurf_ccg.c blender-2.62/source/blender/blenkernel/intern/subsurf_ccg.c --- blender-2.61/source/blender/blenkernel/intern/subsurf_ccg.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/subsurf_ccg.c 2012-02-15 19:34:02.000000000 +0000 @@ -44,12 +44,12 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "BLI_utildefines.h" #include "BLI_blenlib.h" #include "BLI_edgehash.h" #include "BLI_math.h" #include "BLI_memarena.h" #include "BLI_pbvh.h" -#include "BLI_utildefines.h" #include "BKE_cdderivedmesh.h" #include "BKE_global.h" @@ -92,9 +92,17 @@ BLI_memarena_free(a); } -static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, int useAging, int useArena, int UNUSED(useFlatSubdiv)) { +typedef enum { + CCG_USE_AGING = 1, + CCG_USE_ARENA = 2, + CCG_CALC_NORMALS = 4, +} CCGFlags; + +static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, CCGFlags flags) { CCGMeshIFC ifc; CCGSubSurf *ccgSS; + int useAging = !!(flags & CCG_USE_AGING); + int useArena = flags & CCG_USE_ARENA; /* subdivLevels==0 is not allowed */ subdivLevels = MAX2(subdivLevels, 1); @@ -102,7 +110,6 @@ if (prevSS) { int oldUseAging; - useAging = !!useAging; ccgSubSurf_getUseAgeCounts(prevSS, &oldUseAging, NULL, NULL, NULL); if (oldUseAging!=useAging) { @@ -119,7 +126,7 @@ } else { ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 8; } - ifc.vertDataSize = sizeof(DMGridData); + ifc.vertDataSize = sizeof(float) * (flags & CCG_CALC_NORMALS ? 6 : 3); if (useArena) { CCGAllocatorIFC allocatorIFC; @@ -139,7 +146,10 @@ ccgSubSurf_setUseAgeCounts(ccgSS, 1, 8, 8, 8); } - ccgSubSurf_setCalcVertexNormals(ccgSS, 1, offsetof(DMGridData, no)); + if (flags & CCG_CALC_NORMALS) + ccgSubSurf_setCalcVertexNormals(ccgSS, 1, offsetof(DMGridData, no)); + else + ccgSubSurf_setCalcVertexNormals(ccgSS, 0, 0); return ccgSS; } @@ -225,6 +235,7 @@ CCGVertHDL fverts[4]; EdgeHash *ehash; float creaseFactor = (float)ccgSubSurf_getSubdivisionLevels(ss); + float uv[3]= {0.0f, 0.0f, 0.0f}; /* only first 2 values are written into */ limit[0]= limit[1]= STD_UV_CONNECT_LIMIT; vmap= make_uv_vert_map(mface, tface, totface, totvert, 0, limit); @@ -248,11 +259,8 @@ if (v->separate) { CCGVert *ssv; CCGVertHDL vhdl = SET_INT_IN_POINTER(v->f*4 + v->tfindex); - float uv[3]; - uv[0]= (tface+v->f)->uv[v->tfindex][0]; - uv[1]= (tface+v->f)->uv[v->tfindex][1]; - uv[2]= 0.0f; + copy_v2_v2(uv, (tface+v->f)->uv[v->tfindex]); ccgSubSurf_syncVert(ss, vhdl, uv, seam, &ssv); } @@ -324,7 +332,7 @@ return; /* create a CCGSubSurf from uv's */ - uvss = _getSubSurf(NULL, ccgSubSurf_getSubdivisionLevels(ss), 0, 1, 0); + uvss = _getSubSurf(NULL, ccgSubSurf_getSubdivisionLevels(ss), CCG_USE_ARENA); if(!ss_sync_from_uv(uvss, ss, dm, dmtface)) { ccgSubSurf_free(uvss); @@ -355,19 +363,14 @@ int numVerts = ccgSubSurf_getFaceNumVerts(f); for (S=0; Suv[0][0] = a[0]; tf->uv[0][1] = a[1]; - tf->uv[1][0] = d[0]; tf->uv[1][1] = d[1]; - tf->uv[2][0] = c[0]; tf->uv[2][1] = c[1]; - tf->uv[3][0] = b[0]; tf->uv[3][1] = b[1]; + copy_v2_v2(tf->uv[0], faceGridData[(y + 0)*gridSize + x + 0]); + copy_v2_v2(tf->uv[1], faceGridData[(y + 1)*gridSize + x + 0]); + copy_v2_v2(tf->uv[2], faceGridData[(y + 1)*gridSize + x + 1]); + copy_v2_v2(tf->uv[3], faceGridData[(y + 0)*gridSize + x + 1]); tf++; } @@ -2299,6 +2302,9 @@ break; } } + + if(numEdges == 0) + return -1; fIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, adjf)); @@ -2777,7 +2783,7 @@ int isFinalCalc, int forEditMode, int inEditMode) { int useSimple = smd->subdivType == ME_SIMPLE_SUBSURF; - int useAging = smd->flags & eSubsurfModifierFlag_DebugIncr; + CCGFlags useAging = smd->flags & eSubsurfModifierFlag_DebugIncr ? CCG_USE_AGING : 0; int useSubsurfUv = smd->flags & eSubsurfModifierFlag_SubsurfUv; int drawInteriorEdges = !(smd->flags & eSubsurfModifierFlag_ControlEdges); CCGDerivedMesh *result; @@ -2785,8 +2791,7 @@ if(forEditMode) { int levels= (smd->modifier.scene)? get_render_subsurf_level(&smd->modifier.scene->r, smd->levels): smd->levels; - smd->emCache = _getSubSurf(smd->emCache, levels, useAging, 0, - useSimple); + smd->emCache = _getSubSurf(smd->emCache, levels, useAging|CCG_CALC_NORMALS); ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple); result = getCCGDerivedMesh(smd->emCache, @@ -2800,7 +2805,7 @@ if(levels == 0) return dm; - ss = _getSubSurf(NULL, levels, 0, 1, useSimple); + ss = _getSubSurf(NULL, levels, CCG_USE_ARENA|CCG_CALC_NORMALS); ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple); @@ -2810,7 +2815,6 @@ result->freeSS = 1; } else { int useIncremental = (smd->flags & eSubsurfModifierFlag_Incremental); - int useAging = smd->flags & eSubsurfModifierFlag_DebugIncr; int levels= (smd->modifier.scene)? get_render_subsurf_level(&smd->modifier.scene->r, smd->levels): smd->levels; CCGSubSurf *ss; @@ -2831,8 +2835,7 @@ } if(useIncremental && isFinalCalc) { - smd->mCache = ss = _getSubSurf(smd->mCache, levels, - useAging, 0, useSimple); + smd->mCache = ss = _getSubSurf(smd->mCache, levels, useAging|CCG_CALC_NORMALS); ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple); @@ -2845,7 +2848,7 @@ smd->mCache = NULL; } - ss = _getSubSurf(NULL, levels, 0, 1, useSimple); + ss = _getSubSurf(NULL, levels, CCG_USE_ARENA|CCG_CALC_NORMALS); ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple); result = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm); @@ -2867,7 +2870,7 @@ * calculated vert positions is incorrect for the verts * on the boundary of the mesh. */ - CCGSubSurf *ss = _getSubSurf(NULL, 1, 0, 1, 0); + CCGSubSurf *ss = _getSubSurf(NULL, 1, CCG_USE_ARENA); float edge_sum[3], face_sum[3]; CCGVertIterator *vi; DerivedMesh *dm = CDDM_from_mesh(me, NULL); diff -Nru blender-2.61/source/blender/blenkernel/intern/suggestions.c blender-2.62/source/blender/blenkernel/intern/suggestions.c --- blender-2.61/source/blender/blenkernel/intern/suggestions.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/suggestions.c 2012-02-15 19:34:02.000000000 +0000 @@ -47,7 +47,8 @@ static char *documentation = NULL; //static int doc_lines = 0; -static int txttl_cmp(const char *first, const char *second, int len) { +static int txttl_cmp(const char *first, const char *second, int len) +{ int cmp, i; for (cmp=0, i=0; iprev; @@ -69,7 +71,8 @@ suggestions.top = 0; } -static void txttl_free_docs(void) { +static void txttl_free_docs(void) +{ if (documentation) { MEM_freeN(documentation); documentation = NULL; @@ -80,23 +83,27 @@ /* General tool functions */ /**************************/ -void free_texttools(void) { +void free_texttools(void) +{ txttl_free_suggest(); txttl_free_docs(); } -void texttool_text_set_active(Text *text) { +void texttool_text_set_active(Text *text) +{ if (activeToolText == text) return; texttool_text_clear(); activeToolText = text; } -void texttool_text_clear(void) { +void texttool_text_clear(void) +{ free_texttools(); activeToolText = NULL; } -short texttool_text_is_active(Text *text) { +short texttool_text_is_active(Text *text) +{ return activeToolText==text ? 1 : 0; } @@ -104,7 +111,8 @@ /* Suggestion list methods */ /***************************/ -void texttool_suggest_add(const char *name, char type) { +void texttool_suggest_add(const char *name, char type) +{ SuggItem *newitem, *item; int len, cmp; @@ -154,7 +162,8 @@ suggestions.top= 0; } -void texttool_suggest_prefix(const char *prefix) { +void texttool_suggest_prefix(const char *prefix) +{ SuggItem *match, *first, *last; int cmp, len = strlen(prefix), top = 0; @@ -194,27 +203,33 @@ } } -void texttool_suggest_clear(void) { +void texttool_suggest_clear(void) +{ txttl_free_suggest(); } -SuggItem *texttool_suggest_first(void) { +SuggItem *texttool_suggest_first(void) +{ return suggestions.firstmatch; } -SuggItem *texttool_suggest_last(void) { +SuggItem *texttool_suggest_last(void) +{ return suggestions.lastmatch; } -void texttool_suggest_select(SuggItem *sel) { +void texttool_suggest_select(SuggItem *sel) +{ suggestions.selected = sel; } -SuggItem *texttool_suggest_selected(void) { +SuggItem *texttool_suggest_selected(void) +{ return suggestions.selected; } -int *texttool_suggest_top(void) { +int *texttool_suggest_top(void) +{ return &suggestions.top; } @@ -222,7 +237,8 @@ /* Documentation methods */ /*************************/ -void texttool_docs_show(const char *docs) { +void texttool_docs_show(const char *docs) +{ int len; if (!docs) return; @@ -246,10 +262,12 @@ documentation[len] = '\0'; } -char *texttool_docs_get(void) { +char *texttool_docs_get(void) +{ return documentation; } -void texttool_docs_clear(void) { +void texttool_docs_clear(void) +{ txttl_free_docs(); } diff -Nru blender-2.61/source/blender/blenkernel/intern/text.c blender-2.62/source/blender/blenkernel/intern/text.c --- blender-2.61/source/blender/blenkernel/intern/text.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/text.c 2012-02-15 19:34:02.000000000 +0000 @@ -33,6 +33,8 @@ #include /* strstr */ #include #include +#include +#include #include "MEM_guardedalloc.h" @@ -215,8 +217,48 @@ return ta; } +/* this function replaces extended ascii characters */ +/* to a valid utf-8 sequences */ +int txt_extended_ascii_as_utf8(char **str) +{ + int bad_char, added= 0, i= 0; + int length = strlen(*str); + + while ((*str)[i]) { + if((bad_char= BLI_utf8_invalid_byte(*str+i, length-i)) == -1) + break; + + added++; + i+= bad_char + 1; + } + + if (added != 0) { + char *newstr = MEM_mallocN(length+added+1, "text_line"); + int mi = 0; + i= 0; + + while ((*str)[i]) { + if((bad_char= BLI_utf8_invalid_byte((*str)+i, length-i)) == -1) { + memcpy(newstr+mi, (*str)+i, length - i + 1); + break; + } + + memcpy(newstr+mi, (*str)+i, bad_char); + + BLI_str_utf8_from_unicode((*str)[i+bad_char], newstr+mi+bad_char); + i+= bad_char+1; + mi+= bad_char+2; + } + newstr[length+added] = '\0'; + MEM_freeN(*str); + *str = newstr; + } + + return added; +} + // this function removes any control characters from -// a textline +// a textline and fixes invalid utf-8 sequences static void cleanup_textline(TextLine * tl) { @@ -229,6 +271,7 @@ i--; } } + tl->len+= txt_extended_ascii_as_utf8(&tl->line); } int reopen_text(Text *text) @@ -689,16 +732,10 @@ } /* 0:whitespace, 1:punct, 2:alphanumeric */ -static short txt_char_type (char ch) +static short txt_char_type(unsigned int ch) { - if (ch <= ' ') return 0; /* 32 */ - if (ch <= '/') return 1; /* 47 */ - if (ch <= '9') return 2; /* 57 */ - if (ch <= '@') return 1; /* 64 */ - if (ch <= 'Z') return 2; /* 90 */ - if (ch == '_') return 2; /* 95, dont delimit '_' */ - if (ch <= '`') return 1; /* 96 */ - if (ch <= 'z') return 2; /* 122 */ + if (iswspace(ch)) return 0; + if (iswalpha(ch) || iswdigit(ch)) return 2; return 1; } @@ -731,29 +768,63 @@ } } -/****************************/ +/*****************************/ /* Cursor movement functions */ -/****************************/ +/*****************************/ + +int txt_utf8_offset_to_index(char *str, int offset) +{ + int index= 0, pos= 0; + while (pos != offset) { + pos += BLI_str_utf8_size(str + pos); + index++; + } + return index; +} + +int txt_utf8_index_to_offset(char *str, int index) +{ + int offset= 0, pos= 0; + while (pos != index) { + offset += BLI_str_utf8_size(str + offset); + pos++; + } + return offset; +} + +/* returns the real number of characters in string */ +/* not the same as BLI_strlen_utf8, which returns length for wide characters */ +static int txt_utf8_len(const char *src) +{ + int len; + + for (len=0; *src; len++) { + src += BLI_str_utf8_size(src); + } + + return len; +} void txt_move_up(Text *text, short sel) { TextLine **linep; - int *charp, old; + int *charp; + /* int old; */ /* UNUSED */ if (!text) return; if(sel) txt_curs_sel(text, &linep, &charp); else { txt_pop_first(text); txt_curs_cur(text, &linep, &charp); } if (!*linep) return; - old= *charp; + /* old= *charp; */ /* UNUSED */ if((*linep)->prev) { + int index = txt_utf8_offset_to_index((*linep)->line, *charp); *linep= (*linep)->prev; - if (*charp > (*linep)->len) { - *charp= (*linep)->len; - if(!undoing) txt_undo_add_toop(text, sel?UNDO_STO:UNDO_CTO, txt_get_span(text->lines.first, (*linep)->next), old, txt_get_span(text->lines.first, *linep), (unsigned short) *charp); - } else { - if(!undoing) txt_undo_add_op(text, sel?UNDO_SUP:UNDO_CUP); - } + if (index > txt_utf8_len((*linep)->line)) *charp= (*linep)->len; + else *charp= txt_utf8_index_to_offset((*linep)->line, index); + + if(!undoing) + txt_undo_add_op(text, sel?UNDO_SUP:UNDO_CUP); } else { txt_move_bol(text, sel); } @@ -764,21 +835,23 @@ void txt_move_down(Text *text, short sel) { TextLine **linep; - int *charp, old; + int *charp; + /* int old; */ /* UNUSED */ if (!text) return; if(sel) txt_curs_sel(text, &linep, &charp); else { txt_pop_last(text); txt_curs_cur(text, &linep, &charp); } if (!*linep) return; - old= *charp; + /* old= *charp; */ /* UNUSED */ if((*linep)->next) { + int index = txt_utf8_offset_to_index((*linep)->line, *charp); *linep= (*linep)->next; - if (*charp > (*linep)->len) { - *charp= (*linep)->len; - if(!undoing) txt_undo_add_toop(text, sel?UNDO_STO:UNDO_CTO, txt_get_span(text->lines.first, (*linep)->prev), old, txt_get_span(text->lines.first, *linep), (unsigned short)*charp); - } else - if(!undoing) txt_undo_add_op(text, sel?UNDO_SDOWN:UNDO_CDOWN); + if (index > txt_utf8_len((*linep)->line)) *charp= (*linep)->len; + else *charp= txt_utf8_index_to_offset((*linep)->line, index); + + if(!undoing) + txt_undo_add_op(text, sel?UNDO_SDOWN:UNDO_CDOWN); } else { txt_move_eol(text, sel); } @@ -790,7 +863,7 @@ { TextLine **linep; int *charp, oundoing= undoing; - int tabsize = 1, i=0; + int tabsize= 0, i= 0; if (!text) return; if(sel) txt_curs_sel(text, &linep, &charp); @@ -799,32 +872,36 @@ undoing= 1; - // do nice left only if there are only spaces - // TXT_TABSIZE hardcoded in DNA_text_types.h - if (text->flags & TXT_TABSTOSPACES) { - tabsize = TXT_TABSIZE; - - if (*charp < tabsize) - tabsize = *charp; - else { - for (i=0;i<(*charp);i++) + if (*charp== 0) { + if ((*linep)->prev) { + txt_move_up(text, sel); + *charp= (*linep)->len; + } + } + else { + // do nice left only if there are only spaces + // TXT_TABSIZE hardcoded in DNA_text_types.h + if (text->flags & TXT_TABSTOSPACES) { + tabsize= (*charp < TXT_TABSIZE) ? *charp : TXT_TABSIZE; + + for (i=0; i<(*charp); i++) if ((*linep)->line[i] != ' ') { - tabsize = 1; + tabsize= 0; break; } + // if in the middle of the space-tab - if ((*charp) % tabsize != 0) - tabsize = ((*charp) % tabsize); + if (tabsize && (*charp) % TXT_TABSIZE != 0) + tabsize= ((*charp) % TXT_TABSIZE); } - } - - if (*charp== 0) { - if ((*linep)->prev) { - txt_move_up(text, sel); - *charp= (*linep)->len; + + if (tabsize) + (*charp)-= tabsize; + else { + const char *prev= BLI_str_prev_char_utf8((*linep)->line + *charp); + *charp= prev - (*linep)->line; } } - else (*charp)-= tabsize; undoing= oundoing; if(!undoing) txt_undo_add_op(text, sel?UNDO_SLEFT:UNDO_CLEFT); @@ -835,8 +912,7 @@ void txt_move_right(Text *text, short sel) { TextLine **linep; - int *charp, oundoing= undoing; - int tabsize=1, i=0; + int *charp, oundoing= undoing, do_tab= 0, i; if (!text) return; if(sel) txt_curs_sel(text, &linep, &charp); @@ -845,32 +921,33 @@ undoing= 1; - // do nice right only if there are only spaces - // spaces hardcoded in DNA_text_types.h - if (text->flags & TXT_TABSTOSPACES) { - tabsize = TXT_TABSIZE; - - if ((*charp) + tabsize > (*linep)->len) - tabsize = 1; - else { - for (i=0;i<(*charp) + tabsize - ((*charp) % tabsize);i++) - if ((*linep)->line[i] != ' ') { - tabsize = 1; - break; - } - // if in the middle of the space-tab - tabsize -= (*charp) % tabsize; - } - } - if (*charp== (*linep)->len) { if ((*linep)->next) { txt_move_down(text, sel); *charp= 0; } - } else { - (*charp)+=tabsize; + } + else { + // do nice right only if there are only spaces + // spaces hardcoded in DNA_text_types.h + if (text->flags & TXT_TABSTOSPACES && (*linep)->line[*charp]== ' ') { + do_tab= 1; + for (i=0; i<*charp; i++) + if ((*linep)->line[i]!= ' ') { + do_tab= 0; + break; + } + } + + if (do_tab) { + int tabsize= (*charp) % TXT_TABSIZE + 1; + for (i=*charp+1; (*linep)->line[i]==' ' && tabsizeline + *charp); } + undoing= oundoing; if(!undoing) txt_undo_add_op(text, sel?UNDO_SRIGHT:UNDO_CRIGHT); @@ -896,9 +973,12 @@ count= 0; for (i=0; i<3; i++) { if (count < 2) { - while (*charp>0 && txt_char_type((*linep)->line[*charp-1])==i) { - txt_move_left(text, sel); - count++; + while (*charp>0) { + char *sym= BLI_str_prev_char_utf8((*linep)->line + *charp); + if (txt_char_type(BLI_str_utf8_as_unicode(sym))==i) { + txt_move_left(text, sel); + count++; + } else break; } } } @@ -927,9 +1007,12 @@ count= 0; for (i=0; i<3; i++) { if (count < 2) { - while (*charp<(*linep)->len && txt_char_type((*linep)->line[*charp])==i) { - txt_move_right(text, sel); - count++; + while (*charp<(*linep)->len) { + char *sym= (*linep)->line + *charp; + if (txt_char_type(BLI_str_utf8_as_unicode(sym))==i) { + txt_move_right(text, sel); + count++; + } else break; } } } @@ -1014,6 +1097,7 @@ txt_move_to(text, line, 0, sel); } +/* Moves to a certain byte in a line, not a certain utf8-character! */ void txt_move_to (Text *text, unsigned int line, unsigned int ch, short sel) { TextLine **linep, *oldl; @@ -1396,42 +1480,45 @@ void txt_insert_buf(Text *text, const char *in_buffer) { - int i=0, l=0, j, u, len, lineno= -1, count= 0; + int l=0, u, len, lineno= -1, count= 0; + size_t i=0, j; TextLine *add; + char *buffer; if (!text) return; if (!in_buffer) return; txt_delete_sel(text); - if(!undoing) txt_undo_add_block (text, UNDO_IBLOCK, in_buffer); + len= strlen(in_buffer); + buffer= BLI_strdupn(in_buffer, len); + len+= txt_extended_ascii_as_utf8(&buffer); + + if(!undoing) txt_undo_add_block(text, UNDO_IBLOCK, buffer); u= undoing; undoing= 1; /* Read the first line (or as close as possible */ - while (in_buffer[i] && in_buffer[i]!='\n') { - txt_add_raw_char(text, in_buffer[i]); - i++; - } + while (buffer[i] && buffer[i]!='\n') + txt_add_raw_char(text, BLI_str_utf8_as_unicode_step(buffer, &i)); - if (in_buffer[i]=='\n') txt_split_curline(text); - else { undoing = u; return; } + if (buffer[i]=='\n') txt_split_curline(text); + else { undoing = u; MEM_freeN(buffer); return; } i++; /* Read as many full lines as we can */ - len= strlen(in_buffer); lineno= txt_get_span(text->lines.first, text->curl); while (ilines, text->curl, add); i++; count++; @@ -1441,21 +1528,19 @@ count= 0; } - for (j= i-l; jundo_buf[i]); + if (op >= UNDO_INSERT_1 && op <= UNDO_DEL_4) { i++; + printf (" - Char is "); + switch (op) { + case UNDO_INSERT_1: case UNDO_BS_1: case UNDO_DEL_1: + printf ("%c", text->undo_buf[i]); + i++; + break; + case UNDO_INSERT_2: case UNDO_BS_2: case UNDO_DEL_2: + printf ("%c%c", text->undo_buf[i], text->undo_buf[i+1]); + i+=2; + break; + case UNDO_INSERT_3: case UNDO_BS_3: case UNDO_DEL_3: + printf ("%c%c%c", text->undo_buf[i], text->undo_buf[i+1], text->undo_buf[i+2]); + i+=3; + break; + case UNDO_INSERT_4: case UNDO_BS_4: case UNDO_DEL_4: { + unsigned int uc; + char c[BLI_UTF8_MAX+1]; + size_t c_len; + uc= text->undo_buf[i]; i++; + uc= uc+(text->undo_buf[i]<<8); i++; + uc= uc+(text->undo_buf[i]<<16); i++; + uc= uc+(text->undo_buf[i]<<24); i++; + c_len= BLI_str_utf8_from_unicode(uc, c); + c[c_len]= '\0'; + printf ("%s", c); + } + } } else if (op==UNDO_STO || op==UNDO_CTO) { i++; @@ -1635,40 +1763,43 @@ text->undo_buf[text->undo_pos+1]= 0; } +static void txt_undo_store_uint16(char *undo_buf, int *undo_pos, unsigned short value) +{ + undo_buf[*undo_pos]= (value)&0xff; + (*undo_pos)++; + undo_buf[*undo_pos]= (value>>8)&0xff; + (*undo_pos)++; +} + +static void txt_undo_store_uint32(char *undo_buf, int *undo_pos, unsigned int value) +{ + undo_buf[*undo_pos]= (value)&0xff; + (*undo_pos)++; + undo_buf[*undo_pos]= (value>>8)&0xff; + (*undo_pos)++; + undo_buf[*undo_pos]= (value>>16)&0xff; + (*undo_pos)++; + undo_buf[*undo_pos]= (value>>24)&0xff; + (*undo_pos)++; +} + static void txt_undo_add_block(Text *text, int op, const char *buf) { - int length; - - length= strlen(buf); + unsigned int length= strlen(buf); if(!max_undo_test(text, length+11)) return; text->undo_pos++; text->undo_buf[text->undo_pos]= op; - - text->undo_pos++; - text->undo_buf[text->undo_pos]= (length)&0xff; - text->undo_pos++; - text->undo_buf[text->undo_pos]= (length>>8)&0xff; - text->undo_pos++; - text->undo_buf[text->undo_pos]= (length>>16)&0xff; - text->undo_pos++; - text->undo_buf[text->undo_pos]= (length>>24)&0xff; - text->undo_pos++; + + txt_undo_store_uint32(text->undo_buf, &text->undo_pos, length); + strncpy(text->undo_buf+text->undo_pos, buf, length); text->undo_pos+=length; - text->undo_buf[text->undo_pos]= (length)&0xff; - text->undo_pos++; - text->undo_buf[text->undo_pos]= (length>>8)&0xff; - text->undo_pos++; - text->undo_buf[text->undo_pos]= (length>>16)&0xff; - text->undo_pos++; - text->undo_buf[text->undo_pos]= (length>>24)&0xff; - - text->undo_pos++; + txt_undo_store_uint32(text->undo_buf, &text->undo_pos, length); text->undo_buf[text->undo_pos]= op; text->undo_buf[text->undo_pos+1]= 0; @@ -1685,51 +1816,147 @@ text->undo_buf[text->undo_pos]= op; text->undo_pos++; - text->undo_buf[text->undo_pos]= (fromc)&0xff; - text->undo_pos++; - text->undo_buf[text->undo_pos]= (fromc>>8)&0xff; + + txt_undo_store_uint16(text->undo_buf, &text->undo_pos, fromc); + txt_undo_store_uint32(text->undo_buf, &text->undo_pos, froml); + txt_undo_store_uint16(text->undo_buf, &text->undo_pos, toc); + txt_undo_store_uint32(text->undo_buf, &text->undo_pos, tol); + + text->undo_buf[text->undo_pos]= op; - text->undo_pos++; - text->undo_buf[text->undo_pos]= (froml)&0xff; - text->undo_pos++; - text->undo_buf[text->undo_pos]= (froml>>8)&0xff; - text->undo_pos++; - text->undo_buf[text->undo_pos]= (froml>>16)&0xff; - text->undo_pos++; - text->undo_buf[text->undo_pos]= (froml>>24)&0xff; + text->undo_buf[text->undo_pos+1]= 0; +} +static void txt_undo_add_charop(Text *text, int op_start, unsigned int c) +{ + char utf8[BLI_UTF8_MAX]; + size_t i, utf8_size = BLI_str_utf8_from_unicode(c, utf8); + + if(!max_undo_test(text, 3 + utf8_size)) + return; + text->undo_pos++; - text->undo_buf[text->undo_pos]= (toc)&0xff; - text->undo_pos++; - text->undo_buf[text->undo_pos]= (toc>>8)&0xff; + + if (utf8_size < 4) { + text->undo_buf[text->undo_pos]= op_start + utf8_size - 1; + text->undo_pos++; + + for (i = 0; i < utf8_size; i++) { + text->undo_buf[text->undo_pos]= utf8[i]; + text->undo_pos++; + } + + text->undo_buf[text->undo_pos]= op_start + utf8_size - 1; + } else { + text->undo_buf[text->undo_pos]= op_start + 3; + text->undo_pos++; + txt_undo_store_uint32(text->undo_buf, &text->undo_pos, c); + text->undo_buf[text->undo_pos]= op_start + 3; + } + + text->undo_buf[text->undo_pos+1]= 0; +} - text->undo_pos++; - text->undo_buf[text->undo_pos]= (tol)&0xff; - text->undo_pos++; - text->undo_buf[text->undo_pos]= (tol>>8)&0xff; - text->undo_pos++; - text->undo_buf[text->undo_pos]= (tol>>16)&0xff; - text->undo_pos++; - text->undo_buf[text->undo_pos]= (tol>>24)&0xff; +static unsigned short txt_undo_read_uint16(const char *undo_buf, int *undo_pos) +{ + unsigned short val; + val= undo_buf[*undo_pos]; (*undo_pos)--; + val= (val<<8)+undo_buf[*undo_pos]; (*undo_pos)--; + return val; +} - text->undo_pos++; - text->undo_buf[text->undo_pos]= op; +static unsigned int txt_undo_read_uint32(const char *undo_buf, int *undo_pos) +{ + unsigned int val; + val= undo_buf[*undo_pos]; (*undo_pos)--; + val= (val<<8)+undo_buf[*undo_pos]; (*undo_pos)--; + val= (val<<8)+undo_buf[*undo_pos]; (*undo_pos)--; + val= (val<<8)+undo_buf[*undo_pos]; (*undo_pos)--; + return val; +} - text->undo_buf[text->undo_pos+1]= 0; +static unsigned int txt_undo_read_unicode(const char *undo_buf, int *undo_pos, short bytes) +{ + unsigned int unicode; + char utf8[BLI_UTF8_MAX+1]; + + switch (bytes) { + case 1: /* ascii */ + unicode = undo_buf[*undo_pos]; (*undo_pos)--; + break; + case 2: /* 2-byte symbol */ + utf8[2] = '\0'; + utf8[1] = undo_buf[*undo_pos]; (*undo_pos)--; + utf8[0] = undo_buf[*undo_pos]; (*undo_pos)--; + unicode= BLI_str_utf8_as_unicode(utf8); + break; + case 3: /* 3-byte symbol */ + utf8[3] = '\0'; + utf8[2] = undo_buf[*undo_pos]; (*undo_pos)--; + utf8[1] = undo_buf[*undo_pos]; (*undo_pos)--; + utf8[0] = undo_buf[*undo_pos]; (*undo_pos)--; + unicode= BLI_str_utf8_as_unicode(utf8); + break; + case 4: /* 32-bit unicode symbol */ + unicode= txt_undo_read_uint32(undo_buf, undo_pos); + default: + /* should never happen */ + BLI_assert(0); + unicode= 0; + } + + return unicode; } -static void txt_undo_add_charop(Text *text, int op, char c) +static unsigned short txt_redo_read_uint16(const char *undo_buf, int *undo_pos) { - if(!max_undo_test(text, 4)) - return; + unsigned short val; + val = undo_buf[*undo_pos]; (*undo_pos)++; + val = val+(undo_buf[*undo_pos]<<8); (*undo_pos)++; + return val; +} - text->undo_pos++; - text->undo_buf[text->undo_pos]= op; - text->undo_pos++; - text->undo_buf[text->undo_pos]= c; - text->undo_pos++; - text->undo_buf[text->undo_pos]= op; - text->undo_buf[text->undo_pos+1]= 0; +static unsigned int txt_redo_read_uint32(const char *undo_buf, int *undo_pos) +{ + unsigned int val; + val= undo_buf[*undo_pos]; (*undo_pos)++; + val= val+(undo_buf[*undo_pos]<<8); (*undo_pos)++; + val= val+(undo_buf[*undo_pos]<<16); (*undo_pos)++; + val= val+(undo_buf[*undo_pos]<<24); (*undo_pos)++; + return val; +} + +static unsigned int txt_redo_read_unicode(const char *undo_buf, int *undo_pos, short bytes) +{ + unsigned int unicode; + char utf8[BLI_UTF8_MAX+1]; + + switch (bytes) { + case 1: /* ascii */ + unicode = undo_buf[*undo_pos]; (*undo_pos)++; + break; + case 2: /* 2-byte symbol */ + utf8[0] = undo_buf[*undo_pos]; (*undo_pos)++; + utf8[1] = undo_buf[*undo_pos]; (*undo_pos)++; + utf8[2] = '\0'; + unicode= BLI_str_utf8_as_unicode(utf8); + break; + case 3: /* 3-byte symbol */ + utf8[0] = undo_buf[*undo_pos]; (*undo_pos)++; + utf8[1] = undo_buf[*undo_pos]; (*undo_pos)++; + utf8[2] = undo_buf[*undo_pos]; (*undo_pos)++; + utf8[3] = '\0'; + unicode= BLI_str_utf8_as_unicode(utf8); + break; + case 4: /* 32-bit unicode symbol */ + unicode= txt_undo_read_uint32(undo_buf, undo_pos); + default: + /* should never happen */ + BLI_assert(0); + unicode= 0; + } + + return unicode; } void txt_do_undo(Text *text) @@ -1792,13 +2019,8 @@ text->undo_pos--; text->undo_pos--; - linep= text->undo_buf[text->undo_pos]; text->undo_pos--; - linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--; - linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--; - linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--; - - charp= text->undo_buf[text->undo_pos]; text->undo_pos--; - charp= (charp<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--; + linep= txt_undo_read_uint32(text->undo_buf, &text->undo_pos); + charp= txt_undo_read_uint16(text->undo_buf, &text->undo_pos); if (op==UNDO_CTO) { txt_move_toline(text, linep, 0); @@ -1812,23 +2034,23 @@ text->undo_pos--; break; - case UNDO_INSERT: + case UNDO_INSERT_1: case UNDO_INSERT_2: case UNDO_INSERT_3: case UNDO_INSERT_4: txt_backspace_char(text); - text->undo_pos--; + text->undo_pos-= op - UNDO_INSERT_1 + 1; text->undo_pos--; break; - case UNDO_BS: - txt_add_char(text, text->undo_buf[text->undo_pos]); - text->undo_pos--; + case UNDO_BS_1: case UNDO_BS_2: case UNDO_BS_3: case UNDO_BS_4: + charp = op - UNDO_BS_1 + 1; + txt_add_char(text, txt_undo_read_unicode(text->undo_buf, &text->undo_pos, charp)); text->undo_pos--; - break; - - case UNDO_DEL: - txt_add_char(text, text->undo_buf[text->undo_pos]); + break; + + case UNDO_DEL_1: case UNDO_DEL_2: case UNDO_DEL_3: case UNDO_DEL_4: + charp = op - UNDO_DEL_1 + 1; + txt_add_char(text, txt_undo_read_unicode(text->undo_buf, &text->undo_pos, charp)); txt_move_left(text, 0); text->undo_pos--; - text->undo_pos--; break; case UNDO_SWAP: @@ -1836,10 +2058,7 @@ break; case UNDO_DBLOCK: - linep= text->undo_buf[text->undo_pos]; text->undo_pos--; - linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--; - linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--; - linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--; + linep= txt_undo_read_uint32(text->undo_buf, &text->undo_pos); buf= MEM_mallocN(linep+1, "dblock buffer"); for (i=0; i < linep; i++){ @@ -1863,25 +2082,31 @@ } text->curc= holdc; - linep= text->undo_buf[text->undo_pos]; text->undo_pos--; - linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--; - linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--; - linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--; + text->undo_pos--; + text->undo_pos--; + text->undo_pos--; + text->undo_pos--; text->undo_pos--; break; case UNDO_IBLOCK: - linep= text->undo_buf[text->undo_pos]; text->undo_pos--; - linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--; - linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--; - linep= (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--; - + linep= txt_undo_read_uint32(text->undo_buf, &text->undo_pos); txt_delete_sel(text); + + /* txt_backspace_char removes utf8-characters, not bytes */ + buf= MEM_mallocN(linep+1, "iblock buffer"); + for (i=0; i < linep; i++){ + buf[(linep-1)-i]= text->undo_buf[text->undo_pos]; + text->undo_pos--; + } + buf[i]= 0; + linep= txt_utf8_len(buf); + MEM_freeN(buf); + while (linep>0) { txt_backspace_char(text); - text->undo_pos--; linep--; } @@ -1897,30 +2122,23 @@ case UNDO_UNINDENT: case UNDO_COMMENT: case UNDO_UNCOMMENT: - linep= text->undo_buf[text->undo_pos]; text->undo_pos--; - linep = (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--; - linep = (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--; - linep = (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--; + linep= txt_undo_read_uint32(text->undo_buf, &text->undo_pos); //linep is now the end line of the selection - charp = text->undo_buf[text->undo_pos]; text->undo_pos--; - charp = (charp<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--; + charp = txt_undo_read_uint16(text->undo_buf, &text->undo_pos); //charp is the last char selected or text->line->len - //set the selcetion for this now + + //set the selection for this now text->selc = charp; text->sell = text->lines.first; for (i= 0; i < linep; i++) { text->sell = text->sell->next; } - linep= text->undo_buf[text->undo_pos]; text->undo_pos--; - linep = (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--; - linep = (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--; - linep = (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--; + linep= txt_undo_read_uint32(text->undo_buf, &text->undo_pos); //first line to be selected - charp = text->undo_buf[text->undo_pos]; text->undo_pos--; - charp = (charp<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--; + charp = txt_undo_read_uint16(text->undo_buf, &text->undo_pos); //first postion to be selected text->curc = charp; text->curl = text->lines.first; @@ -2014,22 +2232,22 @@ txt_move_down(text, 1); break; - case UNDO_INSERT: - text->undo_pos++; - txt_add_char(text, text->undo_buf[text->undo_pos]); + case UNDO_INSERT_1: case UNDO_INSERT_2: case UNDO_INSERT_3: case UNDO_INSERT_4: text->undo_pos++; + charp = op - UNDO_INSERT_1 + 1; + txt_add_char(text, txt_redo_read_unicode(text->undo_buf, &text->undo_pos, charp)); break; - case UNDO_BS: + case UNDO_BS_1: case UNDO_BS_2: case UNDO_BS_3: case UNDO_BS_4: text->undo_pos++; txt_backspace_char(text); - text->undo_pos++; + text->undo_pos+= op - UNDO_BS_1 + 1; break; - case UNDO_DEL: + case UNDO_DEL_1: case UNDO_DEL_2: case UNDO_DEL_3: case UNDO_DEL_4: text->undo_pos++; txt_delete_char(text); - text->undo_pos++; + text->undo_pos+= op - UNDO_DEL_1 + 1; break; case UNDO_SWAP: @@ -2049,15 +2267,8 @@ text->undo_pos++; - charp= text->undo_buf[text->undo_pos]; - text->undo_pos++; - charp= charp+(text->undo_buf[text->undo_pos]<<8); - - text->undo_pos++; - linep= text->undo_buf[text->undo_pos]; text->undo_pos++; - linep= linep+(text->undo_buf[text->undo_pos]<<8); text->undo_pos++; - linep= linep+(text->undo_buf[text->undo_pos]<<16); text->undo_pos++; - linep= linep+(text->undo_buf[text->undo_pos]<<24); text->undo_pos++; + charp= txt_redo_read_uint16(text->undo_buf, &text->undo_pos); + linep= txt_redo_read_uint32(text->undo_buf, &text->undo_pos); if (op==UNDO_CTO) { txt_move_toline(text, linep, 0); @@ -2072,12 +2283,9 @@ case UNDO_DBLOCK: text->undo_pos++; - linep= text->undo_buf[text->undo_pos]; text->undo_pos++; - linep= linep+(text->undo_buf[text->undo_pos]<<8); text->undo_pos++; - linep= linep+(text->undo_buf[text->undo_pos]<<16); text->undo_pos++; - linep= linep+(text->undo_buf[text->undo_pos]<<24); text->undo_pos++; - + linep= txt_redo_read_uint32(text->undo_buf, &text->undo_pos); txt_delete_sel(text); + text->undo_pos+=linep; text->undo_pos++; @@ -2089,10 +2297,7 @@ case UNDO_IBLOCK: text->undo_pos++; - linep= text->undo_buf[text->undo_pos]; text->undo_pos++; - linep= linep+(text->undo_buf[text->undo_pos]<<8); text->undo_pos++; - linep= linep+(text->undo_buf[text->undo_pos]<<16); text->undo_pos++; - linep= linep+(text->undo_buf[text->undo_pos]<<24); text->undo_pos++; + linep= txt_redo_read_uint32(text->undo_buf, &text->undo_pos); buf= MEM_mallocN(linep+1, "iblock buffer"); memcpy (buf, &text->undo_buf[text->undo_pos], linep); @@ -2102,26 +2307,21 @@ txt_insert_buf(text, buf); MEM_freeN(buf); - linep= text->undo_buf[text->undo_pos]; text->undo_pos++; - linep= linep+(text->undo_buf[text->undo_pos]<<8); text->undo_pos++; - linep= linep+(text->undo_buf[text->undo_pos]<<16); text->undo_pos++; - linep= linep+(text->undo_buf[text->undo_pos]<<24); text->undo_pos++; - (void)linep; - + text->undo_pos++; + text->undo_pos++; + text->undo_pos++; + text->undo_pos++; break; + case UNDO_INDENT: case UNDO_UNINDENT: case UNDO_COMMENT: case UNDO_UNCOMMENT: text->undo_pos++; - charp = text->undo_buf[text->undo_pos]; text->undo_pos++; - charp = charp+(text->undo_buf[text->undo_pos]<<8); text->undo_pos++; + charp = txt_redo_read_uint16(text->undo_buf, &text->undo_pos); //charp is the first char selected or 0 - linep= text->undo_buf[text->undo_pos]; text->undo_pos++; - linep = linep+(text->undo_buf[text->undo_pos]<<8); text->undo_pos++; - linep = linep+(text->undo_buf[text->undo_pos]<<16); text->undo_pos++; - linep = linep+(text->undo_buf[text->undo_pos]<<24); text->undo_pos++; + linep= txt_redo_read_uint32(text->undo_buf, &text->undo_pos); //linep is now the first line of the selection //set the selcetion for this now text->curc = charp; @@ -2130,13 +2330,10 @@ text->curl = text->curl->next; } - charp = text->undo_buf[text->undo_pos]; text->undo_pos++; - charp = charp+(text->undo_buf[text->undo_pos]<<8); text->undo_pos++; + charp = txt_redo_read_uint16(text->undo_buf, &text->undo_pos); //last postion to be selected - linep= text->undo_buf[text->undo_pos]; text->undo_pos++; - linep = linep+(text->undo_buf[text->undo_pos]<<8); text->undo_pos++; - linep = linep+(text->undo_buf[text->undo_pos]<<16); text->undo_pos++; - linep = linep+(text->undo_buf[text->undo_pos]<<24); text->undo_pos++; + + linep= txt_redo_read_uint32(text->undo_buf, &text->undo_pos); //Last line to be selected text->selc = charp; @@ -2203,8 +2400,7 @@ left[text->curc]=0; right= MEM_mallocN(text->curl->len - text->curc+1, "textline_string"); - if (text->curl->len - text->curc) memcpy(right, text->curl->line+text->curc, text->curl->len-text->curc); - right[text->curl->len - text->curc]=0; + memcpy(right, text->curl->line+text->curc, text->curl->len-text->curc+1); MEM_freeN(text->curl->line); if (text->curl->format) MEM_freeN(text->curl->format); @@ -2228,7 +2424,7 @@ txt_clean_text(text); txt_pop_sel(text); - if(!undoing) txt_undo_add_charop(text, UNDO_INSERT, '\n'); + if(!undoing) txt_undo_add_charop(text, UNDO_INSERT_1, '\n'); } static void txt_delete_line (Text *text, TextLine *line) @@ -2296,9 +2492,9 @@ txt_clean_text(text); } -void txt_delete_char (Text *text) +void txt_delete_char(Text *text) { - char c='\n'; + unsigned int c='\n'; if (!text) return; if (!text->curl) return; @@ -2314,12 +2510,14 @@ txt_pop_sel(text); } } else { /* Just deleting a char */ - int i= text->curc; + size_t c_len = 0; + TextMarker *mrk; + c= BLI_str_utf8_as_unicode_and_size(text->curl->line + text->curc, &c_len); - TextMarker *mrk= txt_find_marker_region(text, text->curl, i-1, text->curl->len, 0, 0); + mrk= txt_find_marker_region(text, text->curl, text->curc - c_len, text->curl->len, 0, 0); if (mrk) { int lineno= mrk->lineno; - if (mrk->end==i) { + if (mrk->end==text->curc) { if ((mrk->flags & TMARK_TEMP) && !(mrk->flags & TMARK_EDITALL)) { txt_clear_markers(text, mrk->group, TMARK_TEMP); } else { @@ -2328,18 +2526,15 @@ return; } do { - if (mrk->start>i) mrk->start--; - mrk->end--; + if (mrk->start>text->curc) mrk->start-= c_len; + mrk->end-= c_len; mrk= mrk->next; } while (mrk && mrk->lineno==lineno); } - c= text->curl->line[i]; - while(i< text->curl->len) { - text->curl->line[i]= text->curl->line[i+1]; - i++; - } - text->curl->len--; + memmove(text->curl->line+text->curc, text->curl->line+text->curc+c_len, text->curl->len-text->curc-c_len+1); + + text->curl->len-= c_len; txt_pop_sel(text); } @@ -2347,7 +2542,7 @@ txt_make_dirty(text); txt_clean_text(text); - if(!undoing) txt_undo_add_charop(text, UNDO_DEL, c); + if(!undoing) txt_undo_add_charop(text, UNDO_DEL_1, c); } void txt_delete_word (Text *text) @@ -2358,7 +2553,7 @@ void txt_backspace_char (Text *text) { - char c='\n'; + unsigned int c='\n'; if (!text) return; if (!text->curl) return; @@ -2378,12 +2573,15 @@ txt_pop_sel(text); } else { /* Just backspacing a char */ - int i= text->curc-1; + size_t c_len = 0; + TextMarker *mrk; + char *prev = BLI_str_prev_char_utf8(text->curl->line + text->curc); + c= BLI_str_utf8_as_unicode_and_size(prev, &c_len); - TextMarker *mrk= txt_find_marker_region(text, text->curl, i, text->curl->len, 0, 0); + mrk= txt_find_marker_region(text, text->curl, text->curc - c_len, text->curl->len, 0, 0); if (mrk) { int lineno= mrk->lineno; - if (mrk->start==i+1) { + if (mrk->start==text->curc) { if ((mrk->flags & TMARK_TEMP) && !(mrk->flags & TMARK_EDITALL)) { txt_clear_markers(text, mrk->group, TMARK_TEMP); } else { @@ -2392,19 +2590,16 @@ return; } do { - if (mrk->start>i) mrk->start--; - mrk->end--; + if (mrk->start>text->curc - c_len) mrk->start-= c_len; + mrk->end-= c_len; mrk= mrk->next; } while (mrk && mrk->lineno==lineno); } - c= text->curl->line[i]; - while(i< text->curl->len) { - text->curl->line[i]= text->curl->line[i+1]; - i++; - } - text->curl->len--; - text->curc--; + memcpy(text->curl->line + text->curc - c_len, text->curl->line + text->curc, text->curl->len-text->curc+1); + + text->curl->len-= c_len; + text->curc-= c_len; txt_pop_sel(text); } @@ -2412,7 +2607,7 @@ txt_make_dirty(text); txt_clean_text(text); - if(!undoing) txt_undo_add_charop(text, UNDO_BS, c); + if(!undoing) txt_undo_add_charop(text, UNDO_BS_1, c); } void txt_backspace_word (Text *text) @@ -2436,11 +2631,12 @@ txt_insert_buf(text, sb); } -static int txt_add_char_intern (Text *text, char add, int replace_tabs) +static int txt_add_char_intern (Text *text, unsigned int add, int replace_tabs) { - int len, lineno; - char *tmp; + int lineno; + char *tmp, ch[BLI_UTF8_MAX]; TextMarker *mrk; + size_t add_len; if (!text) return 0; if (!text->curl) return 0; @@ -2458,43 +2654,42 @@ txt_delete_sel(text); + add_len = BLI_str_utf8_from_unicode(add, ch); mrk= txt_find_marker_region(text, text->curl, text->curc-1, text->curl->len, 0, 0); if (mrk) { lineno= mrk->lineno; do { - if (mrk->start>text->curc) mrk->start++; - mrk->end++; + if (mrk->start>text->curc) mrk->start+= add_len; + mrk->end+= add_len; mrk= mrk->next; } while (mrk && mrk->lineno==lineno); } - tmp= MEM_mallocN(text->curl->len+2, "textline_string"); - - if(text->curc) memcpy(tmp, text->curl->line, text->curc); - tmp[text->curc]= add; + tmp= MEM_mallocN(text->curl->len+add_len+1, "textline_string"); - len= text->curl->len - text->curc; - if(len>0) memcpy(tmp+text->curc+1, text->curl->line+text->curc, len); - tmp[text->curl->len+1]=0; + memcpy(tmp, text->curl->line, text->curc); + memcpy(tmp+text->curc, ch, add_len); + memcpy(tmp+text->curc+add_len, text->curl->line+text->curc, text->curl->len-text->curc+1); + make_new_line(text->curl, tmp); - text->curc++; + text->curc+= add_len; txt_pop_sel(text); txt_make_dirty(text); txt_clean_text(text); - if(!undoing) txt_undo_add_charop(text, UNDO_INSERT, add); + if(!undoing) txt_undo_add_charop(text, UNDO_INSERT_1, add); return 1; } -int txt_add_char (Text *text, char add) +int txt_add_char (Text *text, unsigned int add) { return txt_add_char_intern(text, add, text->flags & TXT_TABSTOSPACES); } -int txt_add_raw_char (Text *text, char add) +int txt_add_raw_char (Text *text, unsigned int add) { return txt_add_char_intern(text, add, 0); } @@ -2505,34 +2700,48 @@ txt_make_dirty(text); } -int txt_replace_char (Text *text, char add) +int txt_replace_char (Text *text, unsigned int add) { - char del; + unsigned int del; + size_t del_size = 0, add_size; + char ch[BLI_UTF8_MAX]; if (!text) return 0; if (!text->curl) return 0; /* If text is selected or we're at the end of the line just use txt_add_char */ if (text->curc==text->curl->len || txt_has_sel(text) || add=='\n') { - TextMarker *mrk; int i= txt_add_char(text, add); - mrk= txt_find_marker(text, text->curl, text->curc, 0, 0); - if (mrk && mrk->end==text->curc) mrk->end--; + TextMarker *mrk= txt_find_marker(text, text->curl, text->curc, 0, 0); + if (mrk) BLI_freelinkN(&text->markers, mrk); return i; } - del= text->curl->line[text->curc]; - text->curl->line[text->curc]= (unsigned char) add; - text->curc++; - txt_pop_sel(text); + del= BLI_str_utf8_as_unicode_and_size(text->curl->line + text->curc, &del_size); + add_size= BLI_str_utf8_from_unicode(add, ch); + + if (add_size > del_size) { + char *tmp= MEM_mallocN(text->curl->len+add_size-del_size+1, "textline_string"); + memcpy(tmp, text->curl->line, text->curc); + memcpy(tmp+text->curc+add_size, text->curl->line+text->curc+del_size, text->curl->len-text->curc-del_size+1); + MEM_freeN(text->curl->line); + text->curl->line = tmp; + } else if (add_size < del_size) { + char *tmp= text->curl->line; + memmove(tmp+text->curc+add_size, tmp+text->curc+del_size, text->curl->len-text->curc-del_size+1); + } + + memcpy(text->curl->line + text->curc, ch, add_size); + text->curc+= add_size; + txt_pop_sel(text); txt_make_dirty(text); txt_clean_text(text); /* Should probably create a new op for this */ if(!undoing) { - txt_undo_add_charop(text, UNDO_DEL, del); - txt_undo_add_charop(text, UNDO_INSERT, add); + txt_undo_add_charop(text, UNDO_DEL_1, del); + txt_undo_add_charop(text, UNDO_INSERT_1, add); } return 1; } @@ -2548,15 +2757,19 @@ /* hardcoded: TXT_TABSIZE = 4 spaces: */ int spaceslen = TXT_TABSIZE; + if (ELEM3(NULL, text, text->curl, text->sell)) { + return; + } + + if (!text) return; + if (!text->curl) return; + if (!text->sell) return; + /* insert spaces rather than tabs */ if (text->flags & TXT_TABSTOSPACES){ add = tab_to_spaces; indentlen = spaceslen; } - - if (!text) return; - if (!text->curl) return; - if (!text->sell) return; num = 0; while (TRUE) @@ -2609,16 +2822,16 @@ /* hardcoded: TXT_TABSIZE = 4 spaces: */ int spaceslen = TXT_TABSIZE; + if (!text) return; + if (!text->curl) return; + if (!text->sell) return; + /* insert spaces rather than tabs */ if (text->flags & TXT_TABSTOSPACES){ remove = tab_to_spaces; indent = spaceslen; } - if (!text) return; - if (!text->curl) return; - if (!text->sell) return; - while(TRUE) { int i = 0; @@ -2851,7 +3064,8 @@ /* Returns the first matching marker on the specified line between two points. If the group or flags fields are non-zero the returned flag must be in the specified group and have at least the specified flags set. */ -TextMarker *txt_find_marker_region(Text *text, TextLine *line, int start, int end, int group, int flags) { +TextMarker *txt_find_marker_region(Text *text, TextLine *line, int start, int end, int group, int flags) +{ TextMarker *marker, *next; int lineno= txt_get_span(text->lines.first, line); @@ -2918,7 +3132,8 @@ /* Finds the marker at the specified line and cursor position with at least the specified flags set in the given group (if non-zero). */ -TextMarker *txt_find_marker(Text *text, TextLine *line, int curs, int group, int flags) { +TextMarker *txt_find_marker(Text *text, TextLine *line, int curs, int group, int flags) +{ TextMarker *marker; int lineno= txt_get_span(text->lines.first, line); @@ -2936,7 +3151,8 @@ /* Finds the previous marker in the same group. If no other is found, the same marker will be returned */ -TextMarker *txt_prev_marker(Text *text, TextMarker *marker) { +TextMarker *txt_prev_marker(Text *text, TextMarker *marker) +{ TextMarker *tmp= marker; while (tmp) { if (tmp->prev) tmp= tmp->prev; @@ -2949,7 +3165,8 @@ /* Finds the next marker in the same group. If no other is found, the same marker will be returned */ -TextMarker *txt_next_marker(Text *text, TextMarker *marker) { +TextMarker *txt_next_marker(Text *text, TextMarker *marker) +{ TextMarker *tmp= marker; while (tmp) { if (tmp->next) tmp= tmp->next; diff -Nru blender-2.61/source/blender/blenkernel/intern/texture.c blender-2.62/source/blender/blenkernel/intern/texture.c --- blender-2.61/source/blender/blenkernel/intern/texture.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/texture.c 2012-02-15 19:34:02.000000000 +0000 @@ -168,7 +168,7 @@ pit= MEM_callocN(sizeof(PluginTex), "plugintex"); - strcpy(pit->name, str); + BLI_strncpy(pit->name, str, sizeof(pit->name)); open_plugin_tex(pit); if(pit->doit==NULL) { @@ -349,9 +349,9 @@ /* ------------------------------------------------------------------------- */ -int do_colorband(ColorBand *coba, float in, float out[4]) +int do_colorband(const ColorBand *coba, float in, float out[4]) { - CBData *cbd1, *cbd2, *cbd0, *cbd3; + const CBData *cbd1, *cbd2, *cbd0, *cbd3; float fac, mfac, t[4]; int a; @@ -478,10 +478,28 @@ return 0; } -CBData *colorband_element_add(struct ColorBand *coba, float position) +void colorband_update_sort(ColorBand *coba) { int a; + + if(coba->tot<2) + return; + + for(a=0; atot; a++) + coba->data[a].cur= a; + + qsort(coba->data, coba->tot, sizeof(CBData), vergcband); + for(a=0; atot; a++) { + if(coba->data[a].cur==coba->cur) { + coba->cur= a; + break; + } + } +} + +CBData *colorband_element_add(struct ColorBand *coba, float position) +{ if(coba->tot==MAXCOLORBAND) { return NULL; } @@ -503,17 +521,7 @@ coba->tot++; coba->cur = coba->tot-1; - for(a = 0; a < coba->tot; a++) - coba->data[a].cur = a; - - qsort(coba->data, coba->tot, sizeof(CBData), vergcband); - - for(a = 0; a < coba->tot; a++) { - if(coba->data[a].cur == coba->cur) { - coba->cur = a; - break; - } - } + colorband_update_sort(coba); return coba->data + coba->cur; } diff -Nru blender-2.61/source/blender/blenkernel/intern/tracking.c blender-2.62/source/blender/blenkernel/intern/tracking.c --- blender-2.61/source/blender/blenkernel/intern/tracking.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/tracking.c 2012-02-15 19:34:02.000000000 +0000 @@ -55,6 +55,7 @@ #include "BKE_movieclip.h" #include "BKE_object.h" #include "BKE_scene.h" +#include "BKE_main.h" // XXX: ... #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" @@ -69,6 +70,10 @@ struct libmv_CameraIntrinsics *intrinsics; } MovieDistortion; +static struct { + ListBase tracks; +} tracking_clipboard; + /*********************** common functions *************************/ void BKE_tracking_init_settings(MovieTracking *tracking) @@ -85,11 +90,14 @@ tracking->settings.keyframe1= 1; tracking->settings.keyframe2= 30; tracking->settings.dist= 1; + tracking->settings.object_distance= 1; tracking->stabilization.scaleinf= 1.0f; tracking->stabilization.locinf= 1.0f; tracking->stabilization.rotinf= 1.0f; tracking->stabilization.maxscale= 2.0f; + + BKE_tracking_new_object(tracking, "Camera"); } void BKE_tracking_clamp_track(MovieTrackingTrack *track, int event) @@ -208,7 +216,7 @@ } } -MovieTrackingTrack *BKE_tracking_add_track(MovieTracking *tracking, float x, float y, +MovieTrackingTrack *BKE_tracking_add_track(MovieTracking *tracking, ListBase *tracksbase, float x, float y, int framenr, int width, int height) { MovieTrackingTrack *track; @@ -234,6 +242,7 @@ track->margin= settings->default_margin; track->pattern_match= settings->default_pattern_match; track->frames_limit= settings->default_frames_limit; + track->flag= settings->default_flag; memset(&marker, 0, sizeof(marker)); marker.pos[0]= x; @@ -251,13 +260,13 @@ if(track->tracker == TRACKER_KLT) BKE_tracking_clamp_track(track, CLAMP_PYRAMID_LEVELS); - BLI_addtail(&tracking->tracks, track); - BKE_track_unique_name(tracking, track); + BLI_addtail(tracksbase, track); + BKE_track_unique_name(tracksbase, track); return track; } -void BKE_tracking_insert_marker(MovieTrackingTrack *track, MovieTrackingMarker *marker) +MovieTrackingMarker *BKE_tracking_insert_marker(MovieTrackingTrack *track, MovieTrackingMarker *marker) { MovieTrackingMarker *old_marker= NULL; @@ -266,6 +275,8 @@ if(old_marker) { *old_marker= *marker; + + return old_marker; } else { int a= track->markersnr; @@ -283,6 +294,8 @@ track->markers[a+1]= *marker; track->last_marker= a+1; + + return &track->markers[a+1]; } } @@ -383,6 +396,13 @@ return BKE_tracking_exact_marker(track, framenr) != 0; } +int BKE_tracking_has_enabled_marker(MovieTrackingTrack *track, int framenr) +{ + MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, framenr); + + return marker && (marker->flag & MARKER_DISABLED) == 0; +} + void BKE_tracking_free_track(MovieTrackingTrack *track) { if(track->markers) MEM_freeN(track->markers); @@ -524,18 +544,44 @@ dst_track->markersnr= tot; } -void BKE_tracking_free(MovieTracking *tracking) +static void tracking_tracks_free(ListBase *tracks) { MovieTrackingTrack *track; - for(track= tracking->tracks.first; track; track= track->next) { + for(track= tracks->first; track; track= track->next) { BKE_tracking_free_track(track); } - BLI_freelistN(&tracking->tracks); + BLI_freelistN(tracks); +} - if(tracking->reconstruction.cameras) - MEM_freeN(tracking->reconstruction.cameras); +static void tracking_reconstruction_free(MovieTrackingReconstruction *reconstruction) +{ + if(reconstruction->cameras) + MEM_freeN(reconstruction->cameras); +} + +static void tracking_object_free(MovieTrackingObject *object) +{ + tracking_tracks_free(&object->tracks); + tracking_reconstruction_free(&object->reconstruction); +} + +static void tracking_objects_free(ListBase *objects) +{ + MovieTrackingObject *object; + + for(object= objects->first; object; object= object->next) + tracking_object_free(object); + + BLI_freelistN(objects); +} + +void BKE_tracking_free(MovieTracking *tracking) +{ + tracking_tracks_free(&tracking->tracks); + tracking_reconstruction_free(&tracking->reconstruction); + tracking_objects_free(&tracking->objects); if(tracking->stabilization.scaleibuf) IMB_freeImBuf(tracking->stabilization.scaleibuf); @@ -544,9 +590,78 @@ BKE_tracking_distortion_destroy(tracking->camera.intrinsics); } +static MovieTrackingTrack *duplicate_track(MovieTrackingTrack *track) +{ + MovieTrackingTrack *new_track; + + new_track = MEM_callocN(sizeof(MovieTrackingTrack), "tracksMapMerge new_track"); + + *new_track= *track; + new_track->next = new_track->prev = NULL; + + new_track->markers = MEM_dupallocN(new_track->markers); + + return new_track; +} + +/*********************** clipboard *************************/ + +void BKE_tracking_free_clipboard(void) +{ + MovieTrackingTrack *track = tracking_clipboard.tracks.first, *next_track; + + while (track) { + next_track = track->next; + + BKE_tracking_free_track(track); + MEM_freeN(track); + + track = next_track; + } +} + +void BKE_tracking_clipboard_copy_tracks(MovieTracking *tracking, MovieTrackingObject *object) +{ + ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object); + MovieTrackingTrack *track = tracksbase->first; + + while (track) { + if (TRACK_SELECTED(track)) { + MovieTrackingTrack *new_track = duplicate_track(track); + + BLI_addtail(&tracking_clipboard.tracks, new_track); + } + + track = track->next; + } +} + +int BKE_tracking_clipboard_has_tracks(void) +{ + return tracking_clipboard.tracks.first != NULL; +} + +void BKE_tracking_clipboard_paste_tracks(MovieTracking *tracking, MovieTrackingObject *object) +{ + ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object); + MovieTrackingTrack *track = tracking_clipboard.tracks.first; + + while (track) { + MovieTrackingTrack *new_track = duplicate_track(track); + + BLI_addtail(tracksbase, new_track); + BKE_track_unique_name(tracksbase, new_track); + + track = track->next; + } +} + /*********************** tracks map *************************/ typedef struct TracksMap { + char object_name[MAX_NAME]; + int is_camera; + int num_tracks; int customdata_size; @@ -558,10 +673,13 @@ int ptr; } TracksMap; -static TracksMap *tracks_map_new(int num_tracks, int customdata_size) +static TracksMap *tracks_map_new(const char *object_name, int is_camera, int num_tracks, int customdata_size) { TracksMap *map= MEM_callocN(sizeof(TracksMap), "TrackingsMap"); + BLI_strncpy(map->object_name, object_name, sizeof(map->object_name)); + map->is_camera= is_camera; + map->num_tracks= num_tracks; map->customdata_size= customdata_size; @@ -607,10 +725,24 @@ static void tracks_map_merge(TracksMap *map, MovieTracking *tracking) { MovieTrackingTrack *track; + MovieTrackingTrack *act_track= BKE_tracking_active_track(tracking); ListBase tracks= {NULL, NULL}, new_tracks= {NULL, NULL}; - ListBase *old_tracks= &tracking->tracks; + ListBase *old_tracks; int a; + if(map->is_camera) { + old_tracks= &tracking->tracks; + } else { + MovieTrackingObject *object= BKE_tracking_named_object(tracking, map->object_name); + + if(!object) { + /* object was deleted by user, create new one */ + object= BKE_tracking_new_object(tracking, map->object_name); + } + + old_tracks= &object->tracks; + } + /* duplicate currently operating tracks to temporary list. this is needed to keep names in unique state and it's faster to change names of currently operating tracks (if needed) */ @@ -634,7 +766,7 @@ /* original track was found, re-use flags and remove this track */ if(cur) { - if(cur==tracking->act_track) + if(act_track) replace_sel= 1; track->flag= cur->flag; @@ -646,9 +778,7 @@ } } - new_track= MEM_callocN(sizeof(MovieTrackingTrack), "tracksMapMerge new_track"); - *new_track= *track; - new_track->markers= MEM_dupallocN(new_track->markers); + new_track= duplicate_track(track); BLI_ghash_remove(map->hash, track, NULL, NULL); /* XXX: are we actually need this */ BLI_ghash_insert(map->hash, track, new_track); @@ -685,7 +815,7 @@ track= next; } - tracking->tracks= new_tracks; + *old_tracks= new_tracks; } static void tracks_map_free(TracksMap *map, void (*customdata_free) (void *customdata)) @@ -730,33 +860,35 @@ typedef struct MovieTrackingContext { MovieClipUser user; MovieClip *clip; + int clip_flag; int first_time, frames; MovieTrackingSettings settings; TracksMap *tracks_map; - short backwards, disable_failed, sequence; + short backwards, sequence; int sync_frame; } MovieTrackingContext; -MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *user, short backwards, short disable_failed, short sequence) +MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *user, short backwards, short sequence) { MovieTrackingContext *context= MEM_callocN(sizeof(MovieTrackingContext), "trackingContext"); MovieTracking *tracking= &clip->tracking; MovieTrackingSettings *settings= &tracking->settings; + ListBase *tracksbase= BKE_tracking_get_tracks(tracking); MovieTrackingTrack *track; + MovieTrackingObject *object= BKE_tracking_active_object(tracking); int num_tracks= 0; context->settings= *settings; context->backwards= backwards; - context->disable_failed= disable_failed; context->sync_frame= user->framenr; context->first_time= 1; context->sequence= sequence; /* count */ - track= tracking->tracks.first; + track= tracksbase->first; while(track) { if(TRACK_SELECTED(track) && (track->flag&TRACK_LOCKED)==0) { MovieTrackingMarker *marker= BKE_tracking_get_marker(track, user->framenr); @@ -771,12 +903,13 @@ if(num_tracks) { int width, height; - context->tracks_map= tracks_map_new(num_tracks, sizeof(TrackContext)); + context->tracks_map= tracks_map_new(object->name, object->flag & TRACKING_OBJECT_CAMERA, + num_tracks, sizeof(TrackContext)); BKE_movieclip_get_size(clip, user, &width, &height); /* create tracking data */ - track= tracking->tracks.first; + track= tracksbase->first; while(track) { if(TRACK_SELECTED(track) && (track->flag&TRACK_LOCKED)==0) { MovieTrackingMarker *marker= BKE_tracking_get_marker(track, user->framenr); @@ -830,7 +963,20 @@ } context->clip= clip; + + /* store needed clip flags passing to get_buffer functions + * - MCLIP_USE_PROXY is needed to because timecode affects on movie clip + * only in case Proxy/Timecode flag is set, so store this flag to use + * timecodes properly but reset render size to SIZE_FULL so correct resolution + * would be used for images + * - MCLIP_USE_PROXY_CUSTOM_DIR is needed because proxy/timecode files might + * be stored in a different location + * ignore all the rest pssible flags for now */ + context->clip_flag= clip->flag&MCLIP_TIMECODE_FLAGS; + context->user= *user; + context->user.render_size= MCLIP_PROXY_RENDER_SIZE_FULL; + context->user.render_flag= 0; if(!sequence) BLI_begin_threaded_malloc(); @@ -869,57 +1015,92 @@ MEM_freeN(context); } -static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track) +/* zap channels from the imbuf that are disabled by the user. this can lead to + * better tracks sometimes. however, instead of simply zeroing the channels + * out, do a partial grayscale conversion so the display is better. */ +void BKE_tracking_disable_imbuf_channels(ImBuf *ibuf, int disable_red, int disable_green, int disable_blue, int grayscale) { int x, y; + float scale; - if((track->flag&(TRACK_DISABLE_RED|TRACK_DISABLE_GREEN|TRACK_DISABLE_BLUE))==0) + if(!disable_red && !disable_green && !disable_blue && !grayscale) return; + /* If only some components are selected, it's important to rescale the result + * appropriately so that e.g. if only blue is selected, it's not zeroed out. */ + scale = (disable_red ? 0.0f : 0.2126f) + + (disable_green ? 0.0f : 0.7152f) + + (disable_blue ? 0.0f : 0.0722f); + for(y= 0; yy; y++) { for (x= 0; xx; x++) { int pixel= ibuf->x*y + x; if(ibuf->rect_float) { float *rrgbf= ibuf->rect_float + pixel*4; - - if(track->flag&TRACK_DISABLE_RED) rrgbf[0]= 0; - if(track->flag&TRACK_DISABLE_GREEN) rrgbf[1]= 0; - if(track->flag&TRACK_DISABLE_BLUE) rrgbf[2]= 0; + float r = disable_red ? 0.0f : rrgbf[0]; + float g = disable_green ? 0.0f : rrgbf[1]; + float b = disable_blue ? 0.0f : rrgbf[2]; + if (grayscale) { + float gray = (0.2126f*r + 0.7152f*g + 0.0722f*b) / scale; + rrgbf[0] = rrgbf[1] = rrgbf[2] = gray; + } else { + rrgbf[0] = r; + rrgbf[1] = g; + rrgbf[2] = b; + } } else { char *rrgb= (char*)ibuf->rect + pixel*4; - - if(track->flag&TRACK_DISABLE_RED) rrgb[0]= 0; - if(track->flag&TRACK_DISABLE_GREEN) rrgb[1]= 0; - if(track->flag&TRACK_DISABLE_BLUE) rrgb[2]= 0; + char r = disable_red ? 0 : rrgb[0]; + char g = disable_green ? 0 : rrgb[1]; + char b = disable_blue ? 0 : rrgb[2]; + if (grayscale) { + float gray = (0.2126f*r + 0.7152f*g + 0.0722f*b) / scale; + rrgb[0] = rrgb[1] = rrgb[2] = gray; + } else { + rrgb[0] = r; + rrgb[1] = g; + rrgb[2] = b; + } } } } } +static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track, int grayscale) +{ + BKE_tracking_disable_imbuf_channels(ibuf, track->flag&TRACK_DISABLE_RED, + track->flag&TRACK_DISABLE_GREEN, track->flag&TRACK_DISABLE_BLUE, grayscale); +} + static ImBuf *get_area_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, float min[2], float max[2], int margin, int anchored, float pos[2], int origin[2]) { ImBuf *tmpibuf; int x, y; - int x1, y1, x2, y2, w, h; + int x1, y1, w, h; float mpos[2]; copy_v2_v2(mpos, marker->pos); if(anchored) add_v2_v2(mpos, track->offset); + if(pos) + zero_v2(pos); + x= mpos[0]*ibuf->x; y= mpos[1]*ibuf->y; - x1= x-(int)(-min[0]*ibuf->x); - y1= y-(int)(-min[1]*ibuf->y); - x2= x+(int)(max[0]*ibuf->x); - y2= y+(int)(max[1]*ibuf->y); - /* dimensions should be odd */ - w= (x2-x1)|1; - h= (y2-y1)|1; + w= (max[0]-min[0])*ibuf->x; + h= (max[1]-min[1])*ibuf->y; + + w= w|1; + h= h|1; + + x1= x-(int)(w/2.0f); + y1= y-(int)(h/2.0f); + /* dimensions should be odd */ tmpibuf= IMB_allocImBuf(w+margin*2, h+margin*2, 32, IB_rect); IMB_rectcpy(tmpibuf, ibuf, 0, 0, x1-margin, y1-margin, w+margin*2, h+margin*2); @@ -933,7 +1114,13 @@ origin[1]= y1-margin; } - disable_imbuf_channels(tmpibuf, track); + if((track->flag & TRACK_PREVIEW_GRAYSCALE) || + (track->flag & TRACK_DISABLE_RED) || + (track->flag & TRACK_DISABLE_GREEN) || + (track->flag & TRACK_DISABLE_BLUE)) + { + disable_imbuf_channels(tmpibuf, track, 1 /* grayscale */); + } return tmpibuf; } @@ -962,7 +1149,7 @@ height= (track->search_max[1]-track->search_min[1])*ibuf->y; tmpibuf= BKE_tracking_get_search_imbuf(ibuf, track, marker, 0, 0, pos, origin); - disable_imbuf_channels(tmpibuf, track); + disable_imbuf_channels(tmpibuf, track, 0 /* don't grayscale */); *width_r= width; *height_r= height; @@ -974,14 +1161,11 @@ if(tmpibuf->rect_float) { float *rrgbf= tmpibuf->rect_float + pixel*4; - *fp= 0.2126*rrgbf[0] + 0.7152*rrgbf[1] + 0.0722*rrgbf[2]; } else { unsigned char *rrgb= (unsigned char*)tmpibuf->rect + pixel*4; - *fp= (0.2126*rrgb[0] + 0.7152*rrgb[1] + 0.0722*rrgb[2])/255.0f; } - fp++; } } @@ -1002,15 +1186,13 @@ int pixel= ibuf->x*y + x; if(ibuf->rect_float) { - float *rrgbf= ibuf->rect_float + pixel*4; - - *cp= FTOCHAR(0.2126f*rrgbf[0] + 0.7152f*rrgbf[1] + 0.0722f*rrgbf[2]); + const float *rrgbf= ibuf->rect_float + pixel*4; + const float grey_f= 0.2126f*rrgbf[0] + 0.7152f*rrgbf[1] + 0.0722f*rrgbf[2]; + *cp= FTOCHAR(grey_f); } else { - unsigned char *rrgb= (unsigned char*)ibuf->rect + pixel*4; - + const unsigned char *rrgb= (unsigned char*)ibuf->rect + pixel*4; *cp= 0.2126f*rrgb[0] + 0.7152f*rrgb[1] + 0.0722f*rrgb[2]; } - cp++; } } @@ -1025,7 +1207,7 @@ unsigned char *pixels; tmpibuf= BKE_tracking_get_search_imbuf(ibuf, track, marker, 0, 0, pos, origin); - disable_imbuf_channels(tmpibuf, track); + disable_imbuf_channels(tmpibuf, track, 0 /* don't grayscale */); *width_r= tmpibuf->x; *height_r= tmpibuf->y; @@ -1044,7 +1226,7 @@ user.framenr= framenr; - ibuf= BKE_movieclip_get_ibuf_flag(context->clip, &user, 0); + ibuf= BKE_movieclip_get_ibuf_flag(context->clip, &user, context->clip_flag, MOVIECLIP_CACHE_SKIP); return ibuf; } @@ -1148,13 +1330,13 @@ if(context->backwards) context->user.framenr--; else context->user.framenr++; - ibuf_new= BKE_movieclip_get_ibuf_flag(context->clip, &context->user, 0); + ibuf_new= BKE_movieclip_get_ibuf_flag(context->clip, &context->user, context->clip_flag, MOVIECLIP_CACHE_SKIP); if(!ibuf_new) return 0; #pragma omp parallel for private(a) shared(ibuf_new, ok) if(map_size>1) for(a= 0; apattern_match==TRACK_MATCH_KEYFRAME) need_readjust= context->first_time; @@ -1288,8 +1469,7 @@ MEM_freeN(image_new); } - coords_correct= !isnan(x2) && !isnan(y2) && finite(x2) && finite(y2); - if(coords_correct && !onbound && (tracked || !context->disable_failed)) { + if(tracked && !onbound && finite(x2) && finite(y2)) { if(context->first_time) { #pragma omp critical { @@ -1356,6 +1536,8 @@ struct libmv_Reconstruction *reconstruction; #endif + char object_name[MAX_NAME]; + int is_camera; float focal_length; float principal_point[2]; @@ -1377,13 +1559,13 @@ } ReconstructProgressData; #if WITH_LIBMV -static struct libmv_Tracks *create_libmv_tracks(MovieTracking *tracking, int width, int height) +static struct libmv_Tracks *create_libmv_tracks(ListBase *tracksbase, int width, int height) { int tracknr= 0; MovieTrackingTrack *track; struct libmv_Tracks *tracks= libmv_tracksNew(); - track= tracking->tracks.first; + track= tracksbase->first; while(track) { int a= 0; @@ -1427,16 +1609,28 @@ static int retrieve_libmv_reconstruct_tracks(MovieReconstructContext *context, MovieTracking *tracking) { struct libmv_Reconstruction *libmv_reconstruction= context->reconstruction; - MovieTrackingReconstruction *reconstruction= &tracking->reconstruction; + MovieTrackingReconstruction *reconstruction= NULL; MovieReconstructedCamera *reconstructed; MovieTrackingTrack *track; + ListBase *tracksbase= NULL; int ok= 1, tracknr= 0, a, origin_set= 0; int sfra= context->sfra, efra= context->efra; float imat[4][4]; + if(context->is_camera) { + tracksbase= &tracking->tracks; + reconstruction= &tracking->reconstruction; + } + else { + MovieTrackingObject *object= BKE_tracking_named_object(tracking, context->object_name); + + tracksbase= &object->tracks; + reconstruction= &object->reconstruction; + } + unit_m4(imat); - track= tracking->tracks.first; + track= tracksbase->first; while(track) { double pos[3]; @@ -1484,7 +1678,7 @@ } if(origin_set) - mul_m4_m4m4(mat, mat, imat); + mult_m4_m4m4(mat, imat, mat); copy_m4_m4(reconstructed[reconstruction->camnr].mat, mat); reconstructed[reconstruction->camnr].framenr= a; @@ -1502,7 +1696,7 @@ } if(origin_set) { - track= tracking->tracks.first; + track= tracksbase->first; while(track) { if(track->flag&TRACK_HAS_BUNDLE) mul_v3_m4v3(track->bundle_pos, imat, track->bundle_pos); @@ -1518,19 +1712,20 @@ static int retrieve_libmv_reconstruct(MovieReconstructContext *context, MovieTracking *tracking) { - tracks_map_merge(context->tracks_map, tracking); - /* take the intrinscis back from libmv */ retrieve_libmv_reconstruct_intrinscis(context, tracking); return retrieve_libmv_reconstruct_tracks(context, tracking); } -static int get_refine_intrinsics_flags(MovieTracking *tracking) +static int get_refine_intrinsics_flags(MovieTracking *tracking, MovieTrackingObject *object) { int refine= tracking->settings.refine_camera_intrinsics; int flags= 0; + if((object->flag&TRACKING_OBJECT_CAMERA)==0) + return 0; + if(refine&REFINE_FOCAL_LENGTH) flags|= LIBMV_REFINE_FOCAL_LENGTH; @@ -1546,16 +1741,16 @@ return flags; } -static int count_tracks_on_both_keyframes(MovieTracking *tracking) +static int count_tracks_on_both_keyframes(MovieTracking *tracking, ListBase *tracksbase) { int tot= 0; int frame1= tracking->settings.keyframe1, frame2= tracking->settings.keyframe2; MovieTrackingTrack *track; - track= tracking->tracks.first; + track= tracksbase->first; while(track) { - if(BKE_tracking_has_marker(track, frame1)) - if(BKE_tracking_has_marker(track, frame2)) + if(BKE_tracking_has_enabled_marker(track, frame1)) + if(BKE_tracking_has_enabled_marker(track, frame2)) tot++; track= track->next; @@ -1565,42 +1760,50 @@ } #endif -int BKE_tracking_can_reconstruct(MovieTracking *tracking, char *error_msg, int error_size) +int BKE_tracking_can_reconstruct(MovieTracking *tracking, MovieTrackingObject *object, char *error_msg, int error_size) { #if WITH_LIBMV - if(count_tracks_on_both_keyframes(tracking)<8) { - BLI_strncpy(error_msg, "At least 8 tracks on both of keyframes are needed for reconstruction", error_size); + ListBase *tracksbase= BKE_tracking_object_tracks(tracking, object); + + if(count_tracks_on_both_keyframes(tracking, tracksbase)<8) { + BLI_strncpy(error_msg, "At least 8 common tracks on both of keyframes are needed for reconstruction", error_size); return 0; } return 1; #else BLI_strncpy(error_msg, "Blender is compiled without motion tracking library", error_size); - (void) tracking; + (void)tracking; + (void)object; return 0; #endif } MovieReconstructContext* BKE_tracking_reconstruction_context_new(MovieTracking *tracking, - int keyframe1, int keyframe2, int width, int height) + MovieTrackingObject *object, int keyframe1, int keyframe2, int width, int height) { MovieReconstructContext *context= MEM_callocN(sizeof(MovieReconstructContext), "MovieReconstructContext data"); MovieTrackingCamera *camera= &tracking->camera; + ListBase *tracksbase= BKE_tracking_object_tracks(tracking, object); float aspy= 1.0f/tracking->camera.pixel_aspect; - int num_tracks= BLI_countlist(&tracking->tracks); + int num_tracks= BLI_countlist(tracksbase); int sfra= INT_MAX, efra= INT_MIN; MovieTrackingTrack *track; - context->tracks_map= tracks_map_new(num_tracks, 0); - track= tracking->tracks.first; + BLI_strncpy(context->object_name, object->name, sizeof(context->object_name)); + context->is_camera = object->flag&TRACKING_OBJECT_CAMERA; + + context->tracks_map= tracks_map_new(context->object_name, context->is_camera, num_tracks, 0); + + track= tracksbase->first; while(track) { - int first= 0, last= track->markersnr; + int first= 0, last= track->markersnr-1; MovieTrackingMarker *first_marker= &track->markers[0]; MovieTrackingMarker *last_marker= &track->markers[track->markersnr-1]; /* find first not-disabled marker */ - while(firstmarkersnr-1 && first_marker->flag&MARKER_DISABLED) { + while(first<=track->markersnr-1 && first_marker->flag&MARKER_DISABLED) { first++; first_marker++; } @@ -1626,10 +1829,10 @@ context->efra= efra; #ifdef WITH_LIBMV - context->tracks= create_libmv_tracks(tracking, width, height*aspy); + context->tracks= create_libmv_tracks(tracksbase, width, height*aspy); context->keyframe1= keyframe1; context->keyframe2= keyframe2; - context->refine_flags= get_refine_intrinsics_flags(tracking); + context->refine_flags= get_refine_intrinsics_flags(tracking, object); #else (void) width; (void) height; @@ -1643,7 +1846,7 @@ context->k1= camera->k1; context->k2= camera->k2; - context->k2= camera->k2; + context->k3= camera->k3; return context; } @@ -1726,8 +1929,22 @@ int BKE_tracking_finish_reconstruction(MovieReconstructContext *context, MovieTracking *tracking) { - tracking->reconstruction.error= context->reprojection_error; - tracking->reconstruction.flag|= TRACKING_RECONSTRUCTED; + MovieTrackingReconstruction *reconstruction; + + tracks_map_merge(context->tracks_map, tracking); + + if(context->is_camera) { + reconstruction= &tracking->reconstruction; + } + else { + MovieTrackingObject *object; + + object= BKE_tracking_named_object(tracking, context->object_name); + reconstruction= &object->reconstruction; + } + + reconstruction->error= context->reprojection_error; + reconstruction->flag|= TRACKING_RECONSTRUCTED; #ifdef WITH_LIBMV if(!retrieve_libmv_reconstruct(context, tracking)) @@ -1737,14 +1954,15 @@ return 1; } -void BKE_track_unique_name(MovieTracking *tracking, MovieTrackingTrack *track) +void BKE_track_unique_name(ListBase *tracksbase, MovieTrackingTrack *track) { - BLI_uniquename(&tracking->tracks, track, "Track", '.', offsetof(MovieTrackingTrack, name), sizeof(track->name)); + BLI_uniquename(tracksbase, track, "Track", '.', offsetof(MovieTrackingTrack, name), sizeof(track->name)); } -MovieTrackingTrack *BKE_tracking_named_track(MovieTracking *tracking, const char *name) +MovieTrackingTrack *BKE_tracking_named_track(MovieTracking *tracking, MovieTrackingObject *object, const char *name) { - MovieTrackingTrack *track= tracking->tracks.first; + ListBase *tracksbase= BKE_tracking_object_tracks(tracking, object); + MovieTrackingTrack *track= tracksbase->first; while(track) { if(!strcmp(track->name, name)) @@ -1756,9 +1974,8 @@ return NULL; } -static int reconstruction_camera_index(MovieTracking *tracking, int framenr, int nearest) +static int reconstruction_camera_index(MovieTrackingReconstruction *reconstruction, int framenr, int nearest) { - MovieTrackingReconstruction *reconstruction= &tracking->reconstruction; MovieReconstructedCamera *cameras= reconstruction->cameras; int a= 0, d= 1; @@ -1810,21 +2027,41 @@ return -1; } -MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(MovieTracking *tracking, int framenr) +static void scale_reconstructed_camera(MovieTrackingObject *object, float mat[4][4]) { - int a= reconstruction_camera_index(tracking, framenr, 0); + if((object->flag&TRACKING_OBJECT_CAMERA)==0) { + float smat[4][4]; + + scale_m4_fl(smat, 1.0f/object->scale); + mult_m4_m4m4(mat, mat, smat); + } +} + +MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(MovieTracking *tracking, + MovieTrackingObject *object, int framenr) +{ + MovieTrackingReconstruction *reconstruction; + int a; + + reconstruction= BKE_tracking_object_reconstruction(tracking, object); + a= reconstruction_camera_index(reconstruction, framenr, 0); if(a==-1) return NULL; - return &tracking->reconstruction.cameras[a]; + return &reconstruction->cameras[a]; } -void BKE_tracking_get_interpolated_camera(MovieTracking *tracking, int framenr, float mat[4][4]) +void BKE_tracking_get_interpolated_camera(MovieTracking *tracking, MovieTrackingObject *object, + int framenr, float mat[4][4]) { - MovieTrackingReconstruction *reconstruction= &tracking->reconstruction; - MovieReconstructedCamera *cameras= reconstruction->cameras; - int a= reconstruction_camera_index(tracking, framenr, 1); + MovieTrackingReconstruction *reconstruction; + MovieReconstructedCamera *cameras; + int a; + + reconstruction= BKE_tracking_object_reconstruction(tracking, object); + cameras= reconstruction->cameras; + a= reconstruction_camera_index(reconstruction, framenr, 1); if(a==-1) { unit_m4(mat); @@ -1838,6 +2075,8 @@ } else { copy_m4_m4(mat, cameras[a].mat); } + + scale_reconstructed_camera(object, mat); } void BKE_get_tracking_mat(Scene *scene, Object *ob, float mat[4][4]) @@ -1876,7 +2115,8 @@ BKE_tracking_camera_shift(tracking, width, height, &camera->shiftx, &camera->shifty); } -void BKE_tracking_projection_matrix(MovieTracking *tracking, int framenr, int winx, int winy, float mat[4][4]) +void BKE_tracking_projection_matrix(MovieTracking *tracking, MovieTrackingObject *object, + int framenr, int winx, int winy, float mat[4][4]) { MovieReconstructedCamera *camera; float lens= tracking->camera.focal*tracking->camera.sensor_width/(float)winx; @@ -1909,15 +2149,87 @@ perspective_m4(winmat, left, right, bottom, top, clipsta, clipend); - camera= BKE_tracking_get_reconstructed_camera(tracking, framenr); + camera= BKE_tracking_get_reconstructed_camera(tracking, object, framenr); + if(camera) { float imat[4][4]; invert_m4_m4(imat, camera->mat); - mul_m4_m4m4(mat, imat, winmat); + mult_m4_m4m4(mat, winmat, imat); } else copy_m4_m4(mat, winmat); } +ListBase *BKE_tracking_get_tracks(MovieTracking *tracking) +{ + MovieTrackingObject *object= BKE_tracking_active_object(tracking); + + if(object && (object->flag & TRACKING_OBJECT_CAMERA) == 0) { + return &object->tracks; + } + + return &tracking->tracks; +} + +MovieTrackingTrack *BKE_tracking_active_track(MovieTracking *tracking) +{ + ListBase *tracksbase; + + if(!tracking->act_track) + return NULL; + + tracksbase= BKE_tracking_get_tracks(tracking); + + /* check that active track is in current tracks list */ + if(BLI_findindex(tracksbase, tracking->act_track) >= 0) + return tracking->act_track; + + return NULL; +} + +MovieTrackingObject *BKE_tracking_active_object(MovieTracking *tracking) +{ + return BLI_findlink(&tracking->objects, tracking->objectnr); +} + +MovieTrackingObject *BKE_tracking_get_camera_object(MovieTracking *tracking) +{ + MovieTrackingObject *object= tracking->objects.first; + + while(object) { + if(object->flag & TRACKING_OBJECT_CAMERA) + return object; + + object= object->next; + } + + return NULL; +} + +ListBase *BKE_tracking_object_tracks(MovieTracking *tracking, MovieTrackingObject *object) +{ + if(object->flag & TRACKING_OBJECT_CAMERA) { + return &tracking->tracks; + } + + return &object->tracks; +} + +MovieTrackingReconstruction *BKE_tracking_object_reconstruction(MovieTracking *tracking, MovieTrackingObject *object) +{ + if(object->flag & TRACKING_OBJECT_CAMERA) { + return &tracking->reconstruction; + } + + return &object->reconstruction; +} + +MovieTrackingReconstruction *BKE_tracking_get_reconstruction(MovieTracking *tracking) +{ + MovieTrackingObject *object= BKE_tracking_active_object(tracking); + + return BKE_tracking_object_reconstruction(tracking, object); +} + void BKE_tracking_apply_intrinsics(MovieTracking *tracking, float co[2], float nco[2]) { MovieTrackingCamera *camera= &tracking->camera; @@ -2004,8 +2316,9 @@ return 0; } -static void retrieve_libmv_features(MovieTracking *tracking, struct libmv_Features *features, - int framenr, int width, int height, bGPDlayer *layer, int place_outside_layer) +static void retrieve_libmv_features(MovieTracking *tracking, ListBase *tracksbase, + struct libmv_Features *features, int framenr, int width, int height, + bGPDlayer *layer, int place_outside_layer) { int a; @@ -2025,7 +2338,7 @@ ok= point_in_layer(layer, xu, yu)!=place_outside_layer; if(ok) { - track= BKE_tracking_add_track(tracking, xu, yu, framenr, width, height); + track= BKE_tracking_add_track(tracking, tracksbase, xu, yu, framenr, width, height); track->flag|= SELECT; track->pat_flag|= SELECT; track->search_flag|= SELECT; @@ -2034,7 +2347,7 @@ } #endif -void BKE_tracking_detect_fast(MovieTracking *tracking, ImBuf *ibuf, +void BKE_tracking_detect_fast(MovieTracking *tracking, ListBase *tracksbase, ImBuf *ibuf, int framenr, int margin, int min_trackness, int min_distance, bGPDlayer *layer, int place_outside_layer) { @@ -2042,15 +2355,18 @@ struct libmv_Features *features; unsigned char *pixels= get_ucharbuf(ibuf); - features= libmv_detectFeaturesFAST(pixels, ibuf->x, ibuf->y, ibuf->x, margin, min_trackness, min_distance); + features= libmv_detectFeaturesFAST(pixels, ibuf->x, ibuf->y, ibuf->x, + margin, min_trackness, min_distance); MEM_freeN(pixels); - retrieve_libmv_features(tracking, features, framenr, ibuf->x, ibuf->y, layer, place_outside_layer); + retrieve_libmv_features(tracking, tracksbase, features, framenr, + ibuf->x, ibuf->y, layer, place_outside_layer); libmv_destroyFeatures(features); #else (void)tracking; + (void)tracksbase; (void)ibuf; (void)framenr; (void)margin; @@ -2061,22 +2377,34 @@ #endif } -MovieTrackingTrack *BKE_tracking_indexed_track(MovieTracking *tracking, int tracknr) +MovieTrackingTrack *BKE_tracking_indexed_track(MovieTracking *tracking, int tracknr, ListBase **tracksbase_r) { - MovieTrackingTrack *track= tracking->tracks.first; + MovieTrackingObject *object; int cur= 1; - while(track) { - if(track->flag&TRACK_HAS_BUNDLE) { - if(cur==tracknr) - return track; + object= tracking->objects.first; + while(object) { + ListBase *tracksbase= BKE_tracking_object_tracks(tracking, object); + MovieTrackingTrack *track= tracksbase->first; + + while(track) { + if(track->flag&TRACK_HAS_BUNDLE) { + if(cur==tracknr) { + *tracksbase_r= tracksbase; + return track; + } + + cur++; + } - cur++; + track= track->next; } - track= track->next; + object= object->next; } + *tracksbase_r= NULL; + return NULL; } @@ -2088,6 +2416,8 @@ INIT_MINMAX2(min, max); + (void) tracking; + track= tracking->tracks.first; while(track) { if(track->flag&TRACK_USE_2D_STAB) { @@ -2525,12 +2855,12 @@ } /* area - which part of marker should be selected. see TRACK_AREA_* constants */ -void BKE_tracking_select_track(MovieTracking *tracking, MovieTrackingTrack *track, int area, int extend) +void BKE_tracking_select_track(ListBase *tracksbase, MovieTrackingTrack *track, int area, int extend) { if(extend) { BKE_tracking_track_flag(track, area, SELECT, 0); } else { - MovieTrackingTrack *cur= tracking->tracks.first; + MovieTrackingTrack *cur= tracksbase->first; while(cur) { if(cur==track) { @@ -2550,3 +2880,78 @@ { BKE_tracking_track_flag(track, area, SELECT, 1); } + +MovieTrackingObject *BKE_tracking_new_object(MovieTracking *tracking, const char *name) +{ + MovieTrackingObject *object= MEM_callocN(sizeof(MovieTrackingObject), "tracking object"); + + if(tracking->tot_object==0) { + /* first object is always camera */ + BLI_strncpy(object->name, "Camera", sizeof(object->name)); + + object->flag|= TRACKING_OBJECT_CAMERA; + } + else { + BLI_strncpy(object->name, name, sizeof(object->name)); + } + + BLI_addtail(&tracking->objects, object); + + tracking->tot_object++; + tracking->objectnr= BLI_countlist(&tracking->objects) - 1; + + BKE_tracking_object_unique_name(tracking, object); + + return object; +} + +void BKE_tracking_remove_object(MovieTracking *tracking, MovieTrackingObject *object) +{ + MovieTrackingTrack *track; + int index= BLI_findindex(&tracking->objects, object); + + if(index<0) + return; + + if(object->flag & TRACKING_OBJECT_CAMERA) { + /* object used for camera solving can't be deleted */ + return; + } + + track= object->tracks.first; + while(track) { + if(track==tracking->act_track) + tracking->act_track= NULL; + + track= track->next; + } + + tracking_object_free(object); + BLI_freelinkN(&tracking->objects, object); + + tracking->tot_object--; + + if(index>0) + tracking->objectnr= index-1; + else + tracking->objectnr= 0; +} + +void BKE_tracking_object_unique_name(MovieTracking *tracking, MovieTrackingObject *object) +{ + BLI_uniquename(&tracking->objects, object, "Object", '.', offsetof(MovieTrackingObject, name), sizeof(object->name)); +} + +MovieTrackingObject *BKE_tracking_named_object(MovieTracking *tracking, const char *name) +{ + MovieTrackingObject *object= tracking->objects.first; + + while(object) { + if(!strcmp(object->name, name)) + return object; + + object= object->next; + } + + return NULL; +} diff -Nru blender-2.61/source/blender/blenkernel/intern/unit.c blender-2.62/source/blender/blenkernel/intern/unit.c --- blender-2.61/source/blender/blenkernel/intern/unit.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/unit.c 2012-02-15 19:34:02.000000000 +0000 @@ -299,7 +299,8 @@ if(suppress && (unit->flag & B_UNIT_DEF_SUPPRESS)) continue; - if (value_abs >= unit->scalar*(1.0-EPS)) /* scale down scalar so 1cm doesnt convert to 10mm because of float error */ + /* scale down scalar so 1cm doesnt convert to 10mm because of float error */ + if (value_abs >= unit->scalar*(1.0-EPS)) return unit; } @@ -481,11 +482,14 @@ } } -static int unit_scale_str(char *str, int len_max, char *str_tmp, double scale_pref, bUnitDef *unit, const char *replace_str) +static int unit_scale_str(char *str, int len_max, char *str_tmp, + double scale_pref, bUnitDef *unit, const char *replace_str) { char *str_found; - if((len_max>0) && (str_found= (char *)unit_find_str(str, replace_str))) { /* XXX - investigate, does not respect len_max properly */ + if((len_max>0) && (str_found= (char *)unit_find_str(str, replace_str))) { + /* XXX - investigate, does not respect len_max properly */ + int len, len_num, len_name, len_move, found_ofs; found_ofs = (int)(str_found-str); diff -Nru blender-2.61/source/blender/blenkernel/intern/writeavi.c blender-2.62/source/blender/blenkernel/intern/writeavi.c --- blender-2.61/source/blender/blenkernel/intern/writeavi.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/writeavi.c 2012-02-15 19:34:02.000000000 +0000 @@ -52,7 +52,8 @@ /* callbacks */ static int start_avi(Scene *scene, RenderData *rd, int rectx, int recty, ReportList *reports); static void end_avi(void); -static int append_avi(RenderData *rd, int frame, int *pixels, int rectx, int recty, ReportList *reports); +static int append_avi(RenderData *rd, int start_frame, int frame, int *pixels, + int rectx, int recty, ReportList *reports); static void filepath_avi(char *string, RenderData *rd); /* ********************** general blender movie support ***************************** */ @@ -121,7 +122,6 @@ static AviMovie *avi=NULL; -static int sframe; static void filepath_avi (char *string, RenderData *rd) { @@ -150,7 +150,6 @@ filepath_avi(name, rd); - sframe = (rd->sfra); x = rectx; y = recty; @@ -159,9 +158,6 @@ avi = MEM_mallocN (sizeof(AviMovie), "avimovie"); - /* RPW 11-21-2002 - if (rd->imtype != AVI_FORMAT_MJPEG) format = AVI_FORMAT_AVI_RGB; - */ if (rd->im_format.imtype != R_IMF_IMTYPE_AVIJPEG ) format = AVI_FORMAT_AVI_RGB; else format = AVI_FORMAT_MJPEG; @@ -186,7 +182,8 @@ return 1; } -static int append_avi(RenderData *UNUSED(rd), int frame, int *pixels, int rectx, int recty, ReportList *UNUSED(reports)) +static int append_avi(RenderData *UNUSED(rd), int start_frame, int frame, int *pixels, + int rectx, int recty, ReportList *UNUSED(reports)) { unsigned int *rt1, *rt2, *rectot; int x, y; @@ -215,8 +212,8 @@ } } - AVI_write_frame (avi, (frame-sframe), AVI_FORMAT_RGB32, rectot, rectx*recty*4); -// printf ("added frame %3d (frame %3d in avi): ", frame, frame-sframe); + AVI_write_frame (avi, (frame-start_frame), AVI_FORMAT_RGB32, rectot, rectx*recty*4); +// printf ("added frame %3d (frame %3d in avi): ", frame, frame-start_frame); return 1; } diff -Nru blender-2.61/source/blender/blenkernel/intern/writeffmpeg.c blender-2.62/source/blender/blenkernel/intern/writeffmpeg.c --- blender-2.61/source/blender/blenkernel/intern/writeffmpeg.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/writeffmpeg.c 2012-02-15 19:34:02.000000000 +0000 @@ -49,6 +49,8 @@ # include "AUD_C-API.h" #endif +#include "BLI_utildefines.h" + #include "BKE_global.h" #include "BKE_idprop.h" #include "BKE_main.h" @@ -236,13 +238,13 @@ } /* Write a frame to the output file */ -static int write_video_frame(RenderData *rd, AVFrame* frame, ReportList *reports) +static int write_video_frame(RenderData *rd, int cfra, AVFrame* frame, ReportList *reports) { int outsize = 0; int ret, success= 1; AVCodecContext* c = video_stream->codec; - frame->pts = rd->cfra - rd->sfra; + frame->pts = cfra; if (rd->mode & R_FIELDS) { frame->top_field_first = ((rd->mode & R_ODDFIELD) != 0); @@ -250,7 +252,8 @@ outsize = avcodec_encode_video(c, video_buffer, video_buffersize, frame); - if (outsize != 0) { + + if (outsize > 0) { AVPacket packet; av_init_packet(&packet); @@ -268,14 +271,13 @@ packet.data = video_buffer; packet.size = outsize; ret = av_interleaved_write_frame(outfile, &packet); - } else { - ret = 0; + success = (ret == 0); + } else if (outsize < 0) { + success = 0; } - if (ret != 0) { - success= 0; + if (!success) BKE_report(reports, RPT_ERROR, "Error writing frame."); - } return success; } @@ -483,7 +485,7 @@ if (!codec) return NULL; /* Be sure to use the correct pixel format(e.g. RGB, YUV) */ - + if (codec->pix_fmts) { c->pix_fmt = codec->pix_fmts[0]; } else { @@ -509,6 +511,12 @@ c->pix_fmt = PIX_FMT_RGB32; } + if ( codec_id == CODEC_ID_QTRLE ) { + if (rd->im_format.planes == R_IMF_PLANES_RGBA) { + c->pix_fmt = PIX_FMT_ARGB; + } + } + if ((of->oformat->flags & AVFMT_GLOBALHEADER) // || !strcmp(of->oformat->name, "mp4") // || !strcmp(of->oformat->name, "mov") @@ -538,7 +546,19 @@ return NULL; } - video_buffersize = avpicture_get_size(c->pix_fmt, c->width, c->height); + if ( codec_id == CODEC_ID_QTRLE ) { + // normally it should be enough to have buffer with actual image size, + // but some codecs like QTRLE might store extra information in this buffer, + // so it should be a way larger + + // maximum video buffer size is 6-bytes per pixel, plus DPX header size (1664) + // (from FFmpeg sources) + int size = c->width * c->height; + video_buffersize = 7*size + 10000; + } + else + video_buffersize = avpicture_get_size(c->pix_fmt, c->width, c->height); + video_buffer = (uint8_t*)MEM_mallocN(video_buffersize*sizeof(uint8_t), "FFMPEG video buffer"); @@ -918,7 +938,7 @@ } #endif -int append_ffmpeg(RenderData *rd, int frame, int *pixels, int rectx, int recty, ReportList *reports) +int append_ffmpeg(RenderData *rd, int start_frame, int frame, int *pixels, int rectx, int recty, ReportList *reports) { AVFrame* avframe; int success = 1; @@ -933,7 +953,7 @@ if(video_stream) { avframe= generate_video_frame((unsigned char*) pixels, reports); - success= (avframe && write_video_frame(rd, avframe, reports)); + success= (avframe && write_video_frame(rd, frame - start_frame, avframe, reports)); if (ffmpeg_autosplit) { if (avio_tell(outfile->pb) > FFMPEG_AUTOSPLIT_SIZE) { @@ -1077,9 +1097,9 @@ } if (parent_index) { - sprintf(name, "%s:%s", parent->name, o->name); + BLI_snprintf(name, sizeof(name), "%s:%s", parent->name, o->name); } else { - strcpy(name, o->name); + BLI_strncpy(name, o->name, sizeof(name)); } fprintf(stderr, "ffmpeg_property_add: %s %d %d %s\n", @@ -1200,6 +1220,64 @@ return 1; } +static void ffmpeg_set_expert_options(RenderData *rd) +{ + int codec_id = rd->ffcodecdata.codec; + + if(rd->ffcodecdata.properties) + IDP_FreeProperty(rd->ffcodecdata.properties); + + if(codec_id == CODEC_ID_H264) { + /* + * All options here are for x264, but must be set via ffmpeg. + * The names are therefore different - Search for "x264 to FFmpeg option mapping" + * to get a list. + */ + + /* + * Use CABAC coder. Using "coder:1", which should be equivalent, + * crashes Blender for some reason. Either way - this is no big deal. + */ + ffmpeg_property_add_string(rd, "video", "coder:vlc"); + + /* + * The other options were taken from the libx264-default.preset + * included in the ffmpeg distribution. + */ +// ffmpeg_property_add_string(rd, "video", "flags:loop"); // this breakes compatibility for QT + ffmpeg_property_add_string(rd, "video", "cmp:chroma"); + ffmpeg_property_add_string(rd, "video", "partitions:parti4x4"); + ffmpeg_property_add_string(rd, "video", "partitions:partp8x8"); + ffmpeg_property_add_string(rd, "video", "partitions:partb8x8"); + ffmpeg_property_add_string(rd, "video", "me:hex"); + ffmpeg_property_add_string(rd, "video", "subq:6"); + ffmpeg_property_add_string(rd, "video", "me_range:16"); + ffmpeg_property_add_string(rd, "video", "qdiff:4"); + ffmpeg_property_add_string(rd, "video", "keyint_min:25"); + ffmpeg_property_add_string(rd, "video", "sc_threshold:40"); + ffmpeg_property_add_string(rd, "video", "i_qfactor:0.71"); + ffmpeg_property_add_string(rd, "video", "b_strategy:1"); + ffmpeg_property_add_string(rd, "video", "bf:3"); + ffmpeg_property_add_string(rd, "video", "refs:2"); + ffmpeg_property_add_string(rd, "video", "qcomp:0.6"); + ffmpeg_property_add_string(rd, "video", "directpred:3"); + ffmpeg_property_add_string(rd, "video", "trellis:0"); + ffmpeg_property_add_string(rd, "video", "flags2:wpred"); + ffmpeg_property_add_string(rd, "video", "flags2:dct8x8"); + ffmpeg_property_add_string(rd, "video", "flags2:fastpskip"); + ffmpeg_property_add_string(rd, "video", "wpredp:2"); + + if(rd->ffcodecdata.flags & FFMPEG_LOSSLESS_OUTPUT) + ffmpeg_property_add_string(rd, "video", "cqp:0"); + } +#if 0 /* disabled for after release */ + else if(codec_id == CODEC_ID_DNXHD) { + if(rd->ffcodecdata.flags & FFMPEG_LOSSLESS_OUTPUT) + ffmpeg_property_add_string(rd, "video", "mbd:rd"); + } +#endif +} + void ffmpeg_set_preset(RenderData *rd, int preset) { int isntsc = (rd->frs_sec != 25); @@ -1267,47 +1345,6 @@ rd->ffcodecdata.mux_packet_size = 2048; rd->ffcodecdata.mux_rate = 10080000; - /* - * All options here are for x264, but must be set via ffmpeg. - * The names are therefore different - Search for "x264 to FFmpeg option mapping" - * to get a list. - */ - - /* - * Use CABAC coder. Using "coder:1", which should be equivalent, - * crashes Blender for some reason. Either way - this is no big deal. - */ - ffmpeg_property_add_string(rd, "video", "coder:vlc"); - - /* - * The other options were taken from the libx264-default.preset - * included in the ffmpeg distribution. - */ - ffmpeg_property_add_string(rd, "video", "flags:loop"); - ffmpeg_property_add_string(rd, "video", "cmp:chroma"); - ffmpeg_property_add_string(rd, "video", "partitions:parti4x4"); - ffmpeg_property_add_string(rd, "video", "partitions:partp8x8"); - ffmpeg_property_add_string(rd, "video", "partitions:partb8x8"); - ffmpeg_property_add_string(rd, "video", "me:hex"); - ffmpeg_property_add_string(rd, "video", "subq:6"); - ffmpeg_property_add_string(rd, "video", "me_range:16"); - ffmpeg_property_add_string(rd, "video", "qdiff:4"); - ffmpeg_property_add_string(rd, "video", "keyint_min:25"); - ffmpeg_property_add_string(rd, "video", "sc_threshold:40"); - ffmpeg_property_add_string(rd, "video", "i_qfactor:0.71"); - ffmpeg_property_add_string(rd, "video", "b_strategy:1"); - ffmpeg_property_add_string(rd, "video", "bf:3"); - ffmpeg_property_add_string(rd, "video", "refs:2"); - ffmpeg_property_add_string(rd, "video", "qcomp:0.6"); - ffmpeg_property_add_string(rd, "video", "directpred:3"); - ffmpeg_property_add_string(rd, "video", "trellis:0"); - ffmpeg_property_add_string(rd, "video", "flags2:wpred"); - ffmpeg_property_add_string(rd, "video", "flags2:dct8x8"); - ffmpeg_property_add_string(rd, "video", "flags2:fastpskip"); - ffmpeg_property_add_string(rd, "video", "wpredp:2"); - - // This makes x264 output lossless. Will be a separate option later. - //ffmpeg_property_add_string(rd, "video", "cqp:0"); break; case FFMPEG_PRESET_THEORA: @@ -1331,13 +1368,15 @@ break; } + + ffmpeg_set_expert_options(rd); } -void ffmpeg_verify_image_type(RenderData *rd) +void ffmpeg_verify_image_type(RenderData *rd, ImageFormatData *imf) { int audio= 0; - if(rd->imtype == R_IMF_IMTYPE_FFMPEG) { + if(imf->imtype == R_IMF_IMTYPE_FFMPEG) { if(rd->ffcodecdata.type <= 0 || rd->ffcodecdata.codec <= 0 || rd->ffcodecdata.audio_codec <= 0 || @@ -1353,19 +1392,19 @@ audio= 1; } - else if(rd->imtype == R_IMF_IMTYPE_H264) { + else if(imf->imtype == R_IMF_IMTYPE_H264) { if(rd->ffcodecdata.codec != CODEC_ID_H264) { ffmpeg_set_preset(rd, FFMPEG_PRESET_H264); audio= 1; } } - else if(rd->imtype == R_IMF_IMTYPE_XVID) { + else if(imf->imtype == R_IMF_IMTYPE_XVID) { if(rd->ffcodecdata.codec != CODEC_ID_MPEG4) { ffmpeg_set_preset(rd, FFMPEG_PRESET_XVID); audio= 1; } } - else if(rd->imtype == R_IMF_IMTYPE_THEORA) { + else if(imf->imtype == R_IMF_IMTYPE_THEORA) { if(rd->ffcodecdata.codec != CODEC_ID_THEORA) { ffmpeg_set_preset(rd, FFMPEG_PRESET_THEORA); audio= 1; @@ -1378,4 +1417,9 @@ } } +void ffmpeg_verify_codec_settings(RenderData *rd) +{ + ffmpeg_set_expert_options(rd); +} + #endif diff -Nru blender-2.61/source/blender/blenkernel/intern/writeframeserver.c blender-2.62/source/blender/blenkernel/intern/writeframeserver.c --- blender-2.61/source/blender/blenkernel/intern/writeframeserver.c 2011-12-13 19:49:12.000000000 +0000 +++ blender-2.62/source/blender/blenkernel/intern/writeframeserver.c 2012-02-15 19:34:02.000000000 +0000 @@ -310,7 +310,7 @@ } } - len = recv(connsock, buf, 4095, 0); + len = recv(connsock, buf, sizeof(buf) - 1, 0); if (len < 0) { return -1; @@ -362,7 +362,8 @@ connsock = -1; } -int append_frameserver(RenderData *UNUSED(rd), int frame, int *pixels, int rectx, int recty, ReportList *UNUSED(reports)) +int append_frameserver(RenderData *UNUSED(rd), int UNUSED(start_frame), int frame, int *pixels, + int rectx, int recty, ReportList *UNUSED(reports)) { fprintf(stderr, "Serving frame: %d\n", frame); if (write_ppm) { diff -Nru blender-2.61/source/blender/blenlib/BLI_array.h blender-2.62/source/blender/blenlib/BLI_array.h --- blender-2.61/source/blender/blenlib/BLI_array.h 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/source/blender/blenlib/BLI_array.h 2012-02-15 19:35:55.000000000 +0000 @@ -0,0 +1,189 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2008 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Joseph Eagar. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/* + * this library needs to be changed to not use macros quite so heavily, + * and to be more of a complete array API. The way arrays are + * exposed to client code as normal C arrays is very useful though, imho. + * it does require some use of macros, however. + * + * anyway, it's used a bit too heavily to simply rewrite as a + * more "correct" solution without macros entirely. I originally wrote this + * to be very easy to use, without the normal pain of most array libraries. + * This was especially helpful when it came to the massive refactors necessary + * for bmesh, and really helped to speed the process up. - joeedh + * + * little array macro library. example of usage: + * + * int *arr = NULL; + * BLI_array_declare(arr); + * int i; + * + * for (i=0; i<10; i++) { + * BLI_array_growone(arr); + * arr[i] = something; + * } + * BLI_array_free(arr); + * + * arrays are buffered, using double-buffering (so on each reallocation, + * the array size is doubled). supposedly this should give good Big Oh + * behaviour, though it may not be the best in practice. + */ + +#define BLI_array_declare(arr) \ + int _##arr##_count = 0; \ + void *_##arr##_tmp; \ + void *_##arr##_static = NULL + +/* this will use stack space, up to maxstatic array elements, before + * switching to dynamic heap allocation */ +#define BLI_array_staticdeclare(arr, maxstatic) \ + int _##arr##_count = 0; \ + void *_##arr##_tmp; \ + char _##arr##_static[maxstatic*sizeof(arr)] + + +/* this returns the entire size of the array, including any buffering. */ +#define BLI_array_totalsize_dyn(arr) ( \ + ((arr)==NULL) ? \ + 0 : \ + MEM_allocN_len(arr) / sizeof(*arr) \ +) + + +#define BLI_array_totalsize(arr) ( \ + (size_t) \ + (((void *)(arr) == (void *)_##arr##_static && (void *)(arr) != NULL) ? \ + (sizeof(_##arr##_static) / sizeof(*arr)) : \ + BLI_array_totalsize_dyn(arr)) \ +) + + +/* this returns the logical size of the array, not including buffering. */ +#define BLI_array_count(arr) _##arr##_count + +/* Grow the array by a fixed number of items. zeroes the new elements. + * + * Allow for a large 'num' value when the new size is more then double + * to allocate the exact sized array. */ +#define _bli_array_grow_items(arr, num) ( \ + (BLI_array_totalsize(arr) >= _##arr##_count + num) ? \ + (_##arr##_count += num) : \ + ( \ + (void) (_##arr##_tmp = MEM_callocN( \ + sizeof(*arr) * (num < _##arr##_count ? \ + (_##arr##_count * 2 + 2) : \ + (_##arr##_count + num)), \ + #arr " " __FILE__ ":" STRINGIFY(__LINE__) \ + ) \ + ), \ + (void) (arr && memcpy(_##arr##_tmp, \ + arr, \ + sizeof(*arr) * _##arr##_count) \ + ), \ + (void) (arr && ((void *)(arr) != (void*)_##arr##_static ? \ + (MEM_freeN(arr), arr) : \ + arr) \ + ), \ + (void) (arr = _##arr##_tmp \ + ), \ + (_##arr##_count += num) \ + ) \ +) + +/* grow an array by a specified number of items */ +#define BLI_array_growitems(arr, num) ( \ + ((void *)(arr)==NULL && (void *)(_##arr##_static) != NULL) ? \ + ((arr= (void*)_##arr##_static), (_##arr##_count += num)) : \ + _bli_array_grow_items(arr, num) \ +) + +/* returns length of array */ +#define BLI_array_growone(arr) BLI_array_growitems(arr, 1) + + +/* appends an item to the array. */ +#define BLI_array_append(arr, item) ( \ + (void) BLI_array_growone(arr), \ + (void) (arr[_##arr##_count - 1] = item) \ +) + +/* appends an item to the array and returns a pointer to the item in the array. + * item is not a pointer, but actual data value.*/ +#define BLI_array_append_r(arr, item) ( \ + (void) BLI_array_growone(arr), \ + (void) (arr[_##arr##_count - 1] = item), \ + (&arr[_##arr##_count - 1]) \ +) + +#define BLI_array_reserve(arr, num) \ + BLI_array_growitems(arr, num), (void)(_##arr##_count -= num) + + +#define BLI_array_free(arr) \ + if (arr && (char *)arr != _##arr##_static) { \ + BLI_array_fake_user(arr); \ + MEM_freeN(arr); \ + } + +#define BLI_array_pop(arr) ( \ + (arr&&_##arr##_count) ? \ + arr[--_##arr##_count] : \ + 0 \ +) + +/* resets the logical size of an array to zero, but doesn't + * free the memory. */ +#define BLI_array_empty(arr) \ + _##arr##_count=0 + +/* set the count of the array, doesn't actually increase the allocated array + * size. don't use this unless you know what you're doing. */ +#define BLI_array_set_length(arr, count) \ + _##arr##_count = (count) + +/* only to prevent unused warnings */ +#define BLI_array_fake_user(arr) \ + (void)_##arr##_count, \ + (void)_##arr##_tmp, \ + (void)_##arr##_static + + +/* not part of the 'API' but handy funcs, + * same purpose as BLI_array_staticdeclare() + * but use when the max size is known ahead of time */ +#define BLI_array_fixedstack_declare(arr, maxstatic, realsize, allocstr) \ + char _##arr##_static[maxstatic*sizeof(*arr)]; \ + const int _##arr##_is_static= ((void *)_##arr##_static) != ( \ + arr= (realsize <= maxstatic) ? \ + (void *)_##arr##_static : \ + MEM_mallocN(sizeof(*arr)*realsize, allocstr) \ + ) \ + +#define BLI_array_fixedstack_free(arr) \ + if (_##arr##_is_static) MEM_freeN(arr) \ + diff -Nru blender-2.61/source/blender/blenlib/BLI_callbacks.h blender-2.62/source/blender/blenlib/BLI_callbacks.h --- blender-2.61/source/blender/blenlib/BLI_callbacks.h 2011-12-13 19:51:08.000000000 +0000 +++ blender-2.62/source/blender/blenlib/BLI_callbacks.h 2012-02-15 19:35:55.000000000 +0000 @@ -29,7 +29,6 @@ * \ingroup bli */ - #ifndef BLI_CALLBACKS_H #define BLI_CALLBACKS_H @@ -64,12 +63,11 @@ void BLI_exec_cb(struct Main *main, struct ID *self, eCbEvent evt); void BLI_add_cb(bCallbackFuncStore *funcstore, eCbEvent evt); -#endif - - void BLI_cb_init(void); void BLI_cb_finalize(void); /* This is blenlib internal only, unrelated to above */ void callLocalErrorCallBack(const char* msg); + +#endif /* BLI_CALLBACKS_H */ diff -Nru blender-2.61/source/blender/blenlib/BLI_dynstr.h blender-2.62/source/blender/blenlib/BLI_dynstr.h --- blender-2.61/source/blender/blenlib/BLI_dynstr.h 2011-12-13 19:51:08.000000000 +0000 +++ blender-2.62/source/blender/blenlib/BLI_dynstr.h 2012-02-15 19:35:55.000000000 +0000 @@ -100,6 +100,17 @@ */ char* BLI_dynstr_get_cstring (DynStr *ds); +/** + * Get a DynStr's contents as a c-string. + * The str argument must be allocated to be at + * least the size of BLI_dynstr_get_len(ds) + 1. + * + * @param ds The DynStr of interest. + * @param str The string to fill. + * @return The contents of @a ds as a c-string. + */ +void BLI_dynstr_get_cstring_ex (DynStr *ds, char *str); + /** * Free the DynStr * diff -Nru blender-2.61/source/blender/blenlib/BLI_edgehash.h blender-2.62/source/blender/blenlib/BLI_edgehash.h --- blender-2.61/source/blender/blenlib/BLI_edgehash.h 2011-12-13 19:51:08.000000000 +0000 +++ blender-2.62/source/blender/blenlib/BLI_edgehash.h 2012-02-15 19:35:55.000000000 +0000 @@ -47,22 +47,22 @@ /* Insert edge (v0,v1) into hash with given value, does * not check for duplicates. */ -void BLI_edgehash_insert (EdgeHash *eh, int v0, int v1, void *val); +void BLI_edgehash_insert (EdgeHash *eh, unsigned int v0, unsigned int v1, void *val); /* Return value for given edge (v0,v1), or NULL if * if key does not exist in hash. (If need exists * to differentiate between key-value being NULL and * lack of key then see BLI_edgehash_lookup_p(). */ -void* BLI_edgehash_lookup (EdgeHash *eh, int v0, int v1); +void* BLI_edgehash_lookup (EdgeHash *eh, unsigned int v0, unsigned int v1); /* Return pointer to value for given edge (v0,v1), * or NULL if key does not exist in hash. */ -void** BLI_edgehash_lookup_p (EdgeHash *eh, int v0, int v1); +void** BLI_edgehash_lookup_p (EdgeHash *eh, unsigned int v0, unsigned int v1); /* Return boolean true/false if edge (v0,v1) in hash. */ -int BLI_edgehash_haskey (EdgeHash *eh, int v0, int v1); +int BLI_edgehash_haskey (EdgeHash *eh, unsigned int v0, unsigned int v1); /* Return number of keys in hash. */ int BLI_edgehash_size (EdgeHash *eh); @@ -83,7 +83,7 @@ void BLI_edgehashIterator_free (EdgeHashIterator *ehi); /* Retrieve the key from an iterator. */ -void BLI_edgehashIterator_getKey (EdgeHashIterator *ehi, int *v0_r, int *v1_r); +void BLI_edgehashIterator_getKey (EdgeHashIterator *ehi, unsigned int *v0_r, unsigned int *v1_r); /* Retrieve the value from an iterator. */ void* BLI_edgehashIterator_getValue (EdgeHashIterator *ehi); @@ -98,4 +98,3 @@ int BLI_edgehashIterator_isDone (EdgeHashIterator *ehi); #endif - diff -Nru blender-2.61/source/blender/blenlib/BLI_editVert.h blender-2.62/source/blender/blenlib/BLI_editVert.h --- blender-2.61/source/blender/blenlib/BLI_editVert.h 2011-12-13 19:51:08.000000000 +0000 +++ blender-2.62/source/blender/blenlib/BLI_editVert.h 2012-02-15 19:35:55.000000000 +0000 @@ -42,7 +42,6 @@ #include "BLO_sys_types.h" // for intptr_t support struct DerivedMesh; -struct RetopoPaintData; /* note; changing this also might affect the undo copy in editmesh.c */ typedef struct EditVert @@ -184,8 +183,6 @@ */ int lastDataMask; - struct RetopoPaintData *retopo_paint_data; - CustomData vdata, edata, fdata; } EditMesh; diff -Nru blender-2.61/source/blender/blenlib/BLI_fnmatch.h blender-2.62/source/blender/blenlib/BLI_fnmatch.h --- blender-2.61/source/blender/blenlib/BLI_fnmatch.h 2011-12-13 19:51:08.000000000 +0000 +++ blender-2.62/source/blender/blenlib/BLI_fnmatch.h 2012-02-15 19:35:55.000000000 +0000 @@ -51,7 +51,7 @@ #define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */ #define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */ -#if !defined (_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined (_GNU_SOURCE) +#if !defined (_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined (_GNU_SOURCE) || defined( __SUNPRO_C) #define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */ #define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */ #define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */ diff -Nru blender-2.61/source/blender/blenlib/BLI_ghash.h blender-2.62/source/blender/blenlib/BLI_ghash.h --- blender-2.61/source/blender/blenlib/BLI_ghash.h 2011-12-13 19:51:08.000000000 +0000 +++ blender-2.62/source/blender/blenlib/BLI_ghash.h 2012-02-15 19:35:55.000000000 +0000 @@ -142,6 +142,16 @@ unsigned int BLI_ghashutil_inthash (const void *ptr); int BLI_ghashutil_intcmp (const void *a, const void *b); +typedef struct GHashPair { + const void *first; + int second; +} GHashPair; + +GHashPair* BLI_ghashutil_pairalloc (const void *first, int second); +unsigned int BLI_ghashutil_pairhash (const void *ptr); +int BLI_ghashutil_paircmp (const void *a, const void *b); +void BLI_ghashutil_pairfree (void *ptr); + #ifdef __cplusplus } #endif diff -Nru blender-2.61/source/blender/blenlib/BLI_graph.h blender-2.62/source/blender/blenlib/BLI_graph.h --- blender-2.61/source/blender/blenlib/BLI_graph.h 2011-12-13 19:51:08.000000000 +0000 +++ blender-2.62/source/blender/blenlib/BLI_graph.h 2012-02-15 19:35:55.000000000 +0000 @@ -1,3 +1,27 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + * The Original Code is Copyright (C) 2008 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Joshua Leung + * + * ***** END GPL LICENSE BLOCK ***** + */ #ifndef BLI_GRAPH_H_ #define BLI_GRAPH_H_ diff -Nru blender-2.61/source/blender/blenlib/BLI_math_base.h blender-2.62/source/blender/blenlib/BLI_math_base.h --- blender-2.61/source/blender/blenlib/BLI_math_base.h 2011-12-13 19:51:08.000000000 +0000 +++ blender-2.62/source/blender/blenlib/BLI_math_base.h 2012-02-15 19:35:55.000000000 +0000 @@ -167,6 +167,11 @@ MINLINE float power_of_2(float f); +/* these dont really fit anywhere but were being copied about a lot */ +MINLINE int is_power_of_2_i(int n); +MINLINE int power_of_2_max_i(int n); +MINLINE int power_of_2_min_i(int n); + MINLINE float shell_angle_to_dist(float angle); #if (defined(WIN32) || defined(WIN64)) && !defined(FREE_WINDOWS) diff -Nru blender-2.61/source/blender/blenlib/BLI_math_color.h blender-2.62/source/blender/blenlib/BLI_math_color.h --- blender-2.61/source/blender/blenlib/BLI_math_color.h 2011-12-13 19:51:08.000000000 +0000 +++ blender-2.62/source/blender/blenlib/BLI_math_color.h 2012-02-15 19:35:55.000000000 +0000 @@ -34,6 +34,8 @@ extern "C" { #endif +#include "BLI_math_inline.h" + /* primaries */ #define BLI_XYZ_SMPTE 0 #define BLI_XYZ_REC709_SRGB 1 @@ -48,7 +50,7 @@ #define BLI_YCC_ITU_BT601 0 #define BLI_YCC_ITU_BT709 1 #define BLI_YCC_JFIF_0_255 2 - + /******************* Conversion to RGB ********************/ void hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b); @@ -67,25 +69,33 @@ unsigned int rgb_to_cpack(float r, float g, float b); unsigned int hsv_to_cpack(float h, float s, float v); -float rgb_to_grayscale(float rgb[3]); -unsigned char rgb_to_grayscale_byte(unsigned char rgb[3]); +float rgb_to_grayscale(const float rgb[3]); +unsigned char rgb_to_grayscale_byte(const unsigned char rgb[3]); +float rgb_to_luma(const float rgb[3]); +unsigned char rgb_to_luma_byte(const unsigned char rgb[3]); -/***************** Profile Transformations ********************/ +/**************** Profile Transformations *****************/ void gamma_correct(float *c, float gamma); float rec709_to_linearrgb(float c); float linearrgb_to_rec709(float c); float srgb_to_linearrgb(float c); float linearrgb_to_srgb(float c); -void srgb_to_linearrgb_v3_v3(float *col_to, float *col_from); -void linearrgb_to_srgb_v3_v3(float *col_to, float *col_from); -/* rgba buffer convenience functions */ -void srgb_to_linearrgb_rgba_buf(float *col, int tot); -void linearrgb_to_srgb_rgba_buf(float *col, int tot); -void srgb_to_linearrgb_rgba_rgba_buf(float *col_to, float *col_from, int tot); -void linearrgb_to_srgb_rgba_rgba_buf(float *col_to, float *col_from, int tot); - +MINLINE void srgb_to_linearrgb_v3_v3(float linear[3], const float srgb[3]); +MINLINE void linearrgb_to_srgb_v3_v3(float srgb[3], const float linear[3]); + +MINLINE void srgb_to_linearrgb_v4(float linear[4], const float srgb[4]); +MINLINE void linearrgb_to_srgb_v4(float srgb[4], const float linear[4]); + +MINLINE void srgb_to_linearrgb_predivide_v4(float linear[4], const float srgb[4]); +MINLINE void linearrgb_to_srgb_predivide_v4(float srgb[4], const float linear[4]); + +MINLINE void linearrgb_to_srgb_uchar3(unsigned char srgb[3], const float linear[3]); +MINLINE void linearrgb_to_srgb_uchar4(unsigned char srgb[4], const float linear[4]); + +void BLI_init_srgb_conversion(void); + /************************** Other *************************/ int constrain_rgb(float *r, float *g, float *b); @@ -94,12 +104,18 @@ void rgb_float_set_hue_float_offset(float * rgb, float hue_offset); void rgb_byte_set_hue_float_offset(unsigned char * rgb, float hue_offset); +void rgb_uchar_to_float(float col_r[3], const unsigned char col_ub[3]); +void rgba_uchar_to_float(float col_r[4], const unsigned char col_ub[4]); +void rgb_float_to_uchar(unsigned char col_r[3], const float col_f[3]); +void rgba_float_to_uchar(unsigned char col_r[4], const float col_f[4]); + /***************** lift/gamma/gain / ASC-CDL conversion *****************/ void lift_gamma_gain_to_asc_cdl(float *lift, float *gamma, float *gain, float *offset, float *slope, float *power); -void rgb_byte_to_float(const unsigned char *in, float *out); -void rgb_float_to_byte(const float *in, unsigned char *out); +#ifdef BLI_MATH_INLINE_H +#include "intern/math_color_inline.c" +#endif #ifdef __cplusplus } diff -Nru blender-2.61/source/blender/blenlib/BLI_math_geom.h blender-2.62/source/blender/blenlib/BLI_math_geom.h --- blender-2.61/source/blender/blenlib/BLI_math_geom.h 2011-12-13 19:51:08.000000000 +0000 +++ blender-2.62/source/blender/blenlib/BLI_math_geom.h 2012-02-15 19:35:55.000000000 +0000 @@ -54,6 +54,8 @@ float area_quad_v3(const float a[3], const float b[3], const float c[3], const float d[3]); float area_poly_v3(int nr, float verts[][3], const float normal[3]); +int is_quad_convex_v3(const float *v1, const float *v2, const float *v3, const float *v4); + /********************************* Distance **********************************/ float dist_to_line_v2(const float p[2], const float l1[2], const float l2[2]); @@ -65,7 +67,9 @@ float dist_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3]); float closest_to_line_v3(float r[3], const float p[3], const float l1[3], const float l2[3]); float closest_to_line_v2(float r[2], const float p[2], const float l1[2], const float l2[2]); -void closest_to_line_segment_v3(float r[3], const float p[3], const float l1[3], const float l2[3]); +void closest_to_line_segment_v3(float r[3], const float p[3], const float l1[3], const float l2[3]); +void closest_to_plane_v3(float r[3], const float plane_co[3], const float plane_no_unit[3], const float pt[3]); + float line_point_factor_v3(const float p[3], const float l1[3], const float l2[3]); float line_point_factor_v2(const float p[2], const float l1[2], const float l2[2]); @@ -219,6 +223,9 @@ float n4[3], const float f_no[3], const float co1[3], const float co2[3], const float co3[3], const float co4[3]); +void accumulate_vertex_normals_poly(float **vertnos, float polyno[3], + float **vertcos, float vdiffs[][3], int nverts); + /********************************* Tangents **********************************/ typedef struct VertexTangent { diff -Nru blender-2.61/source/blender/blenlib/BLI_math_matrix.h blender-2.62/source/blender/blenlib/BLI_math_matrix.h --- blender-2.61/source/blender/blenlib/BLI_math_matrix.h 2011-12-13 19:51:08.000000000 +0000 +++ blender-2.62/source/blender/blenlib/BLI_math_matrix.h 2012-02-15 19:35:55.000000000 +0000 @@ -68,10 +68,12 @@ void sub_m4_m4m4(float R[4][4], float A[4][4], float B[4][4]); void mul_m3_m3m3(float R[3][3], float A[3][3], float B[3][3]); -void mul_m4_m4m4(float R[4][4], float A[4][4], float B[4][4]); void mul_m4_m3m4(float R[4][4], float A[3][3], float B[4][4]); void mul_m4_m4m3(float R[4][4], float A[4][4], float B[3][3]); -void mul_m3_m3m4(float R[3][3], float A[3][3], float B[4][4]); +/* note: the A,B arguments are reversed compared to previous mul_m4_m4m4 + function, for consistency with above functions & math notation. */ +void mult_m4_m4m4(float R[4][4], float A[4][4], float B[4][4]); +void mult_m3_m3m4(float R[3][3], float A[4][4], float B[3][3]); void mul_serie_m3(float R[3][3], float M1[3][3], float M2[3][3], float M3[3][3], float M4[3][3], diff -Nru blender-2.61/source/blender/blenlib/BLI_math_vector.h blender-2.62/source/blender/blenlib/BLI_math_vector.h --- blender-2.61/source/blender/blenlib/BLI_math_vector.h 2011-12-13 19:51:08.000000000 +0000 +++ blender-2.62/source/blender/blenlib/BLI_math_vector.h 2012-02-15 19:35:55.000000000 +0000 @@ -116,9 +116,10 @@ /*********************************** Length **********************************/ +MINLINE float len_squared_v2(const float v[2]); MINLINE float len_v2(const float a[2]); MINLINE float len_v2v2(const float a[2], const float b[2]); -MINLINE float len_squared_v2v2(const float a[3], const float b[3]); +MINLINE float len_squared_v2v2(const float a[2], const float b[2]); MINLINE float len_v3(const float a[3]); MINLINE float len_v3v3(const float a[3], const float b[3]); MINLINE float len_squared_v3v3(const float a[3], const float b[3]); @@ -170,6 +171,7 @@ float angle_normalized_v3v3(const float v1[3], const float v2[3]); void angle_tri_v3(float angles[3], const float v1[3], const float v2[3], const float v3[3]); void angle_quad_v3(float angles[4], const float v1[3], const float v2[3], const float v3[3], const float v4[3]); +void angle_poly_v3(float* angles, const float* verts[3], int len); /********************************* Geometry **********************************/ @@ -198,6 +200,7 @@ float normalize_vn_vn(float *array_tar, const float *array_src, const int size); float normalize_vn(float *array_tar, const int size); void range_vn_i(int *array_tar, const int size, const int start); +void range_vn_fl(float *array_tar, const int size, const float start, const float step); void negate_vn(float *array_tar, const int size); void negate_vn_vn(float *array_tar, const float *array_src, const int size); void mul_vn_fl(float *array_tar, const int size, const float f); diff -Nru blender-2.61/source/blender/blenlib/BLI_md5.h blender-2.62/source/blender/blenlib/BLI_md5.h --- blender-2.61/source/blender/blenlib/BLI_md5.h 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/source/blender/blenlib/BLI_md5.h 2012-02-15 19:35:55.000000000 +0000 @@ -0,0 +1,45 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef BLI_MD5_H +#define BLI_MD5_H + +/** \file BLI_md5.h + * \ingroup bli + */ + +#include +#include + +/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The + result is always in little endian byte order, so that a byte-wise + output yields to the wanted ASCII representation of the message + digest. */ + +void *md5_buffer(const char *buffer, size_t len, void *resblock); + +/* Compute MD5 message digest for bytes read from STREAM. The + resulting message digest number will be written into the 16 bytes + beginning at RESBLOCK. */ + +int md5_stream(FILE *stream, void *resblock); + +#endif + diff -Nru blender-2.61/source/blender/blenlib/BLI_utildefines.h blender-2.62/source/blender/blenlib/BLI_utildefines.h --- blender-2.61/source/blender/blenlib/BLI_utildefines.h 2011-12-13 19:51:08.000000000 +0000 +++ blender-2.62/source/blender/blenlib/BLI_utildefines.h 2012-02-15 19:35:55.000000000 +0000 @@ -108,6 +108,7 @@ #define FTOCHAR(val) ((val)<=0.0f)? 0 : (((val)>(1.0f-0.5f/255.0f))? 255 : (char)((255.0f*(val))+0.5f)) #define FTOUSHORT(val) ((val >= 1.0f-0.5f/65535)? 65535: (val <= 0.0f)? 0: (unsigned short)(val*65535.0f + 0.5f)) +#define USHORTTOUCHAR(val) ((unsigned char)(((val) >= 65535-128)? 255: ((val)+128)>>8)) #define F3TOCHAR3(v2, v1) { \ (v1)[0]= FTOCHAR((v2[0])); \ (v1)[1]= FTOCHAR((v2[1])); \ @@ -279,27 +280,34 @@ # endif # if defined(__GNUC__) || defined(_MSC_VER) /* check __func__ is available */ # define BLI_assert(a) \ -do { \ - if (!(a)) { \ + (void)((!(a)) ? ( \ + ( \ fprintf(stderr, \ "BLI_assert failed: %s, %s(), %d at \'%s\'\n", \ - __FILE__, __func__, __LINE__, STRINGIFY(a)); \ - _dummy_abort(); \ - } \ -} while (0) + __FILE__, __func__, __LINE__, STRINGIFY(a)), \ + _dummy_abort(), \ + NULL)) : NULL) # else -# define BLI_assert(a) \ -do { \ - if (0 == (a)) { \ +# define BLI_assert(a) \ + (void)((!(a)) ? ( \ + ( \ fprintf(stderr, \ "BLI_assert failed: %s, %d at \'%s\'\n", \ - __FILE__, __LINE__, STRINGIFY(a)); \ - _dummy_abort(); \ - } \ -} while (0) + __FILE__, __LINE__, STRINGIFY(a)), \ + _dummy_abort(), \ + NULL)) : NULL) # endif #else # define BLI_assert(a) (void)0 #endif +/* hints for branch pradiction, only use in code that runs a _lot_ where */ +#ifdef __GNUC__ +# define LIKELY(x) __builtin_expect(!!(x), 1) +# define UNLIKELY(x) __builtin_expect(!!(x), 0) +#else +# define LIKELY(x) (x) +# define UNLIKELY(x) (x) +#endif + #endif // BLI_UTILDEFINES_H diff -Nru blender-2.61/source/blender/blenlib/CMakeLists.txt blender-2.62/source/blender/blenlib/CMakeLists.txt --- blender-2.61/source/blender/blenlib/CMakeLists.txt 2011-12-13 19:51:08.000000000 +0000 +++ blender-2.62/source/blender/blenlib/CMakeLists.txt 2012-02-15 19:35:55.000000000 +0000 @@ -65,12 +65,14 @@ intern/math_base.c intern/math_base_inline.c intern/math_color.c + intern/math_color_inline.c intern/math_geom.c intern/math_geom_inline.c intern/math_matrix.c intern/math_rotation.c intern/math_vector.c intern/math_vector_inline.c + intern/md5.c intern/noise.c intern/path_util.c intern/pbvh.c @@ -86,6 +88,7 @@ intern/voxel.c intern/winstuff.c + BLI_array.h BLI_args.h BLI_blenlib.h BLI_boxpack2d.h @@ -117,6 +120,7 @@ BLI_math_matrix.h BLI_math_rotation.h BLI_math_vector.h + BLI_md5.h BLI_memarena.h BLI_mempool.h BLI_noise.h diff -Nru blender-2.61/source/blender/blenlib/intern/BLI_dynstr.c blender-2.62/source/blender/blenlib/intern/BLI_dynstr.c --- blender-2.61/source/blender/blenlib/intern/BLI_dynstr.c 2011-12-13 19:51:07.000000000 +0000 +++ blender-2.62/source/blender/blenlib/intern/BLI_dynstr.c 2012-02-15 19:35:54.000000000 +0000 @@ -94,7 +94,8 @@ ds->curlen+= cstrlen; } -void BLI_dynstr_nappend(DynStr *ds, const char *cstr, int len) { +void BLI_dynstr_nappend(DynStr *ds, const char *cstr, int len) +{ DynStrElem *dse= malloc(sizeof(*dse)); int cstrlen= BLI_strnlen(cstr, len); @@ -225,10 +226,11 @@ return ds->curlen; } -char *BLI_dynstr_get_cstring(DynStr *ds) { - char *s, *rets= MEM_mallocN(ds->curlen+1, "dynstr_cstring"); +void BLI_dynstr_get_cstring_ex(DynStr *ds, char *rets) +{ + char *s; DynStrElem *dse; - + for (s= rets, dse= ds->elems; dse; dse= dse->next) { int slen= strlen(dse->str); @@ -237,11 +239,17 @@ s+= slen; } rets[ds->curlen]= '\0'; - +} + +char *BLI_dynstr_get_cstring(DynStr *ds) +{ + char *rets= MEM_mallocN(ds->curlen+1, "dynstr_cstring"); + BLI_dynstr_get_cstring_ex(ds, rets); return rets; } -void BLI_dynstr_free(DynStr *ds) { +void BLI_dynstr_free(DynStr *ds) +{ DynStrElem *dse; for (dse= ds->elems; dse; ) { diff -Nru blender-2.61/source/blender/blenlib/intern/BLI_ghash.c blender-2.62/source/blender/blenlib/intern/BLI_ghash.c --- blender-2.61/source/blender/blenlib/intern/BLI_ghash.c 2011-12-13 19:51:07.000000000 +0000 +++ blender-2.62/source/blender/blenlib/intern/BLI_ghash.c 2012-02-15 19:35:54.000000000 +0000 @@ -40,8 +40,8 @@ // #include "BLI_blenlib.h" -#include "BLI_mempool.h" #include "BLI_utildefines.h" +#include "BLI_mempool.h" #include "BLI_ghash.h" #include "BLO_sys_types.h" // for intptr_t support @@ -56,7 +56,8 @@ /***/ -GHash *BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info) { +GHash *BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info) +{ GHash *gh= MEM_mallocN(sizeof(*gh), info); gh->hashfp= hashfp; gh->cmpfp= cmpfp; @@ -72,11 +73,13 @@ return gh; } -int BLI_ghash_size(GHash *gh) { +int BLI_ghash_size(GHash *gh) +{ return gh->nentries; } -void BLI_ghash_insert(GHash *gh, void *key, void *val) { +void BLI_ghash_insert(GHash *gh, void *key, void *val) +{ unsigned int hash= gh->hashfp(key)%gh->nbuckets; Entry *e= (Entry*) BLI_mempool_alloc(gh->entrypool); @@ -109,7 +112,8 @@ } } -void *BLI_ghash_lookup(GHash *gh, const void *key) { +void *BLI_ghash_lookup(GHash *gh, const void *key) +{ if(gh) { unsigned int hash= gh->hashfp(key)%gh->nbuckets; Entry *e; @@ -151,7 +155,8 @@ return 0; } -int BLI_ghash_haskey(GHash *gh, void *key) { +int BLI_ghash_haskey(GHash *gh, void *key) +{ unsigned int hash= gh->hashfp(key)%gh->nbuckets; Entry *e; @@ -162,7 +167,8 @@ return 0; } -void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp) { +void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp) +{ int i; if (keyfreefp || valfreefp) { @@ -190,7 +196,8 @@ /***/ -GHashIterator *BLI_ghashIterator_new(GHash *gh) { +GHashIterator *BLI_ghashIterator_new(GHash *gh) +{ GHashIterator *ghi= MEM_mallocN(sizeof(*ghi), "ghash iterator"); ghi->gh= gh; ghi->curEntry= NULL; @@ -203,7 +210,8 @@ } return ghi; } -void BLI_ghashIterator_init(GHashIterator *ghi, GHash *gh) { +void BLI_ghashIterator_init(GHashIterator *ghi, GHash *gh) +{ ghi->gh= gh; ghi->curEntry= NULL; ghi->curBucket= -1; @@ -214,18 +222,22 @@ ghi->curEntry= ghi->gh->buckets[ghi->curBucket]; } } -void BLI_ghashIterator_free(GHashIterator *ghi) { +void BLI_ghashIterator_free(GHashIterator *ghi) +{ MEM_freeN(ghi); } -void *BLI_ghashIterator_getKey(GHashIterator *ghi) { +void *BLI_ghashIterator_getKey(GHashIterator *ghi) +{ return ghi->curEntry?ghi->curEntry->key:NULL; } -void *BLI_ghashIterator_getValue(GHashIterator *ghi) { +void *BLI_ghashIterator_getValue(GHashIterator *ghi) +{ return ghi->curEntry?ghi->curEntry->val:NULL; } -void BLI_ghashIterator_step(GHashIterator *ghi) { +void BLI_ghashIterator_step(GHashIterator *ghi) +{ if (ghi->curEntry) { ghi->curEntry= ghi->curEntry->next; while (!ghi->curEntry) { @@ -236,23 +248,27 @@ } } } -int BLI_ghashIterator_isDone(GHashIterator *ghi) { +int BLI_ghashIterator_isDone(GHashIterator *ghi) +{ return !ghi->curEntry; } /***/ -unsigned int BLI_ghashutil_ptrhash(const void *key) { +unsigned int BLI_ghashutil_ptrhash(const void *key) +{ return (unsigned int)(intptr_t)key; } -int BLI_ghashutil_ptrcmp(const void *a, const void *b) { +int BLI_ghashutil_ptrcmp(const void *a, const void *b) +{ if (a==b) return 0; else return (afirst = first; + pair->second = second; + return pair; +} + +unsigned int BLI_ghashutil_pairhash(const void *ptr) +{ + const GHashPair *pair = ptr; + unsigned int hash = BLI_ghashutil_ptrhash(pair->first); + return hash ^ BLI_ghashutil_inthash(SET_INT_IN_POINTER(pair->second)); +} + +int BLI_ghashutil_paircmp(const void *a, const void *b) +{ + const GHashPair *A = a; + const GHashPair *B = b; + + int cmp = BLI_ghashutil_ptrcmp(A->first, B->first); + if(cmp == 0) + return BLI_ghashutil_intcmp(SET_INT_IN_POINTER(A->second), SET_INT_IN_POINTER(B->second)); + return cmp; +} + +void BLI_ghashutil_pairfree(void *ptr) +{ + MEM_freeN((void*)ptr); +} + diff -Nru blender-2.61/source/blender/blenlib/intern/BLI_kdtree.c blender-2.62/source/blender/blenlib/intern/BLI_kdtree.c --- blender-2.61/source/blender/blenlib/intern/BLI_kdtree.c 2011-12-13 19:51:07.000000000 +0000 +++ blender-2.62/source/blender/blenlib/intern/BLI_kdtree.c 2012-02-15 19:35:54.000000000 +0000 @@ -132,19 +132,18 @@ tree->root= kdtree_balance(tree->nodes, tree->totnode, 0); } -static float squared_distance(float *v2, float *v1, float *n1, float *n2) +static float squared_distance(float *v2, float *v1, float *UNUSED(n1), float *n2) { float d[3], dist; - (void)n1; /* unused */ d[0]= v2[0]-v1[0]; d[1]= v2[1]-v1[1]; d[2]= v2[2]-v1[2]; - dist= d[0]*d[0] + d[1]*d[1] + d[2]*d[2]; + dist = dot_v3v3(d, d); - //if(n1 && n2 && n1[0]*n2[0] + n1[1]*n2[1] + n1[2]*n2[2] < 0.0f) - if(n2 && d[0]*n2[0] + d[1]*n2[1] + d[2]*n2[2] < 0.0f) + //if(n1 && n2 && (dot_v3v3(n1, n2) < 0.0f)) + if(n2 && (dot_v3v3(d, n2) < 0.0f)) dist *= 10.0f; return dist; diff -Nru blender-2.61/source/blender/blenlib/intern/BLI_linklist.c blender-2.62/source/blender/blenlib/intern/BLI_linklist.c --- blender-2.61/source/blender/blenlib/intern/BLI_linklist.c 2011-12-13 19:51:07.000000000 +0000 +++ blender-2.62/source/blender/blenlib/intern/BLI_linklist.c 2012-02-15 19:35:54.000000000 +0000 @@ -35,7 +35,8 @@ #include "BLI_linklist.h" #include "BLI_memarena.h" -int BLI_linklist_length(LinkNode *list) { +int BLI_linklist_length(LinkNode *list) +{ if (0) { return list?(1+BLI_linklist_length(list->next)):0; } else { @@ -70,7 +71,8 @@ return NULL; } -void BLI_linklist_reverse(LinkNode **listp) { +void BLI_linklist_reverse(LinkNode **listp) +{ LinkNode *rhead= NULL, *cur= *listp; while (cur) { @@ -85,7 +87,8 @@ *listp= rhead; } -void BLI_linklist_prepend(LinkNode **listp, void *ptr) { +void BLI_linklist_prepend(LinkNode **listp, void *ptr) +{ LinkNode *nlink= MEM_mallocN(sizeof(*nlink), "nlink"); nlink->link= ptr; @@ -93,7 +96,8 @@ *listp= nlink; } -void BLI_linklist_append(LinkNode **listp, void *ptr) { +void BLI_linklist_append(LinkNode **listp, void *ptr) +{ LinkNode *nlink= MEM_mallocN(sizeof(*nlink), "nlink"); LinkNode *node = *listp; @@ -110,7 +114,8 @@ } } -void BLI_linklist_prepend_arena(LinkNode **listp, void *ptr, MemArena *ma) { +void BLI_linklist_prepend_arena(LinkNode **listp, void *ptr, MemArena *ma) +{ LinkNode *nlink= BLI_memarena_alloc(ma, sizeof(*nlink)); nlink->link= ptr; @@ -118,7 +123,8 @@ *listp= nlink; } -void BLI_linklist_insert_after(LinkNode **listp, void *ptr) { +void BLI_linklist_insert_after(LinkNode **listp, void *ptr) +{ LinkNode *nlink= MEM_mallocN(sizeof(*nlink), "nlink"); LinkNode *node = *listp; @@ -134,7 +140,8 @@ } } -void BLI_linklist_free(LinkNode *list, LinkNodeFreeFP freefunc) { +void BLI_linklist_free(LinkNode *list, LinkNodeFreeFP freefunc) +{ while (list) { LinkNode *next= list->next; @@ -146,7 +153,8 @@ } } -void BLI_linklist_apply(LinkNode *list, LinkNodeApplyFP applyfunc, void *userdata) { +void BLI_linklist_apply(LinkNode *list, LinkNodeApplyFP applyfunc, void *userdata) +{ for (; list; list= list->next) applyfunc(list->link, userdata); } diff -Nru blender-2.61/source/blender/blenlib/intern/BLI_memarena.c blender-2.62/source/blender/blenlib/intern/BLI_memarena.c --- blender-2.61/source/blender/blenlib/intern/BLI_memarena.c 2011-12-13 19:51:07.000000000 +0000 +++ blender-2.62/source/blender/blenlib/intern/BLI_memarena.c 2012-02-15 19:35:54.000000000 +0000 @@ -48,7 +48,8 @@ LinkNode *bufs; }; -MemArena *BLI_memarena_new(int bufsize, const char *name) { +MemArena *BLI_memarena_new(int bufsize, const char *name) +{ MemArena *ma= MEM_callocN(sizeof(*ma), "memarena"); ma->bufsize= bufsize; ma->align = 8; @@ -57,20 +58,24 @@ return ma; } -void BLI_memarena_use_calloc(MemArena *ma) { +void BLI_memarena_use_calloc(MemArena *ma) +{ ma->use_calloc= 1; } -void BLI_memarena_use_malloc(MemArena *ma) { +void BLI_memarena_use_malloc(MemArena *ma) +{ ma->use_calloc= 0; } -void BLI_memarena_use_align(struct MemArena *ma, int align) { +void BLI_memarena_use_align(struct MemArena *ma, int align) +{ /* align should be a power of two */ ma->align = align; } -void BLI_memarena_free(MemArena *ma) { +void BLI_memarena_free(MemArena *ma) +{ BLI_linklist_free(ma->bufs, (void(*)(void*)) MEM_freeN); MEM_freeN(ma); } @@ -78,7 +83,8 @@ /* amt must be power of two */ #define PADUP(num, amt) ((num+(amt-1))&~(amt-1)) -void *BLI_memarena_alloc(MemArena *ma, int size) { +void *BLI_memarena_alloc(MemArena *ma, int size) +{ void *ptr; /* ensure proper alignment by rounding diff -Nru blender-2.61/source/blender/blenlib/intern/BLI_mempool.c blender-2.62/source/blender/blenlib/intern/BLI_mempool.c --- blender-2.61/source/blender/blenlib/intern/BLI_mempool.c 2011-12-13 19:51:07.000000000 +0000 +++ blender-2.62/source/blender/blenlib/intern/BLI_mempool.c 2012-02-15 19:35:54.000000000 +0000 @@ -274,6 +274,9 @@ iter->curindex = 0; } +#if 0 +/* unoptimized, more readable */ + static void *bli_mempool_iternext(BLI_mempool_iter *iter) { void *ret = NULL; @@ -303,6 +306,37 @@ return ret; } +#else + +/* optimized version of code above */ + +void *BLI_mempool_iterstep(BLI_mempool_iter *iter) +{ + BLI_freenode *ret; + + if (UNLIKELY(iter->pool->totused == 0)) { + return NULL; + } + + do { + if (LIKELY(iter->curchunk)) { + ret = (BLI_freenode *)(((char*)iter->curchunk->data) + iter->pool->esize*iter->curindex); + } + else { + return NULL; + } + + if (UNLIKELY(++iter->curindex >= iter->pool->pchunk)) { + iter->curindex = 0; + iter->curchunk = iter->curchunk->next; + } + } while (ret->freeword == FREEWORD); + + return ret; +} + +#endif + void BLI_mempool_destroy(BLI_mempool *pool) { BLI_mempool_chunk *mpchunk=NULL; diff -Nru blender-2.61/source/blender/blenlib/intern/boxpack2d.c blender-2.62/source/blender/blenlib/intern/boxpack2d.c --- blender-2.61/source/blender/blenlib/intern/boxpack2d.c 2011-12-13 19:51:07.000000000 +0000 +++ blender-2.62/source/blender/blenlib/intern/boxpack2d.c 2012-02-15 19:35:54.000000000 +0000 @@ -174,33 +174,33 @@ for (box=boxarray, box_index=0, i=0; box_index < len; box_index++, box++) { - vert->blb = vert->brb = vert->tlb =\ - vert->isect_cache[0] = vert->isect_cache[1] =\ - vert->isect_cache[2] = vert->isect_cache[3] = NULL; + vert->blb = vert->brb = vert->tlb = + vert->isect_cache[0] = vert->isect_cache[1] = + vert->isect_cache[2] = vert->isect_cache[3] = NULL; vert->free = CORNERFLAGS &~ TRF; vert->trb = box; vert->index = i; i++; box->v[BL] = vert; vert++; - vert->trb= vert->brb = vert->tlb =\ - vert->isect_cache[0] = vert->isect_cache[1] =\ - vert->isect_cache[2] = vert->isect_cache[3] = NULL; + vert->trb= vert->brb = vert->tlb = + vert->isect_cache[0] = vert->isect_cache[1] = + vert->isect_cache[2] = vert->isect_cache[3] = NULL; vert->free = CORNERFLAGS &~ BLF; vert->blb = box; vert->index = i; i++; box->v[TR] = vert; vert++; - vert->trb = vert->blb = vert->tlb =\ - vert->isect_cache[0] = vert->isect_cache[1] =\ - vert->isect_cache[2] = vert->isect_cache[3] = NULL; + vert->trb = vert->blb = vert->tlb = + vert->isect_cache[0] = vert->isect_cache[1] = + vert->isect_cache[2] = vert->isect_cache[3] = NULL; vert->free = CORNERFLAGS &~ BRF; vert->brb = box; vert->index = i; i++; box->v[TL] = vert; vert++; - vert->trb = vert->blb = vert->brb =\ - vert->isect_cache[0] = vert->isect_cache[1] =\ - vert->isect_cache[2] = vert->isect_cache[3] = NULL; + vert->trb = vert->blb = vert->brb = + vert->isect_cache[0] = vert->isect_cache[1] = + vert->isect_cache[2] = vert->isect_cache[3] = NULL; vert->free = CORNERFLAGS &~ TLF; vert->tlb = box; vert->index = i; i++; @@ -390,7 +390,7 @@ } else if ( vert->trb && vert->brb && (box == vert->trb || box == vert->brb) ) { if (vert->trb->w > vert->brb->w) { - vert->brb->v[TR]->free &= ~(TRF|TRF); + vert->brb->v[TR]->free &= ~(TLF|TRF); } else if (vert->trb->w < vert->brb->w) { vert->trb->v[BR]->free &= ~(BLF|BRF); } else { /*same*/ diff -Nru blender-2.61/source/blender/blenlib/intern/bpath.c blender-2.62/source/blender/blenlib/intern/bpath.c --- blender-2.61/source/blender/blenlib/intern/bpath.c 2011-12-13 19:51:07.000000000 +0000 +++ blender-2.62/source/blender/blenlib/intern/bpath.c 2012-02-15 19:35:54.000000000 +0000 @@ -194,12 +194,18 @@ /* find this file recursively, use the biggest file so thumbnails dont get used by mistake - - dir: subdir to search - - filename: set this filename - - filesize: filesize for the file -*/ + * - dir: subdir to search + * - filename: set this filename + * - filesize: filesize for the file + * + * return found: 1/0. + */ #define MAX_RECUR 16 -static int findFileRecursive(char *filename_new, const char *dirname, const char *filename, int *filesize, int *recur_depth) +static int findFileRecursive(char *filename_new, + const char *dirname, + const char *filename, + int *filesize, + int *recur_depth) { /* file searching stuff */ DIR *dir; @@ -207,11 +213,14 @@ struct stat status; char path[FILE_MAX]; int size; + int found = FALSE; + + filename_new[0] = '\0'; dir= opendir(dirname); if (dir==NULL) - return 0; + return found; if (*filesize == -1) *filesize= 0; /* dir opened fine */ @@ -233,19 +242,20 @@ if ((size > 0) && (size > *filesize)) { /* find the biggest file */ *filesize= size; BLI_strncpy(filename_new, path, FILE_MAX); + found = TRUE; } } } else if (S_ISDIR(status.st_mode)) { /* is subdir */ if (*recur_depth <= MAX_RECUR) { (*recur_depth)++; - findFileRecursive(filename_new, path, filename, filesize, recur_depth); + found |= findFileRecursive(filename_new, path, filename, filesize, recur_depth); (*recur_depth)--; } } } closedir(dir); - return 1; + return found; } typedef struct BPathFind_Data @@ -262,19 +272,26 @@ int filesize= -1; int recur_depth= 0; + int found; - findFileRecursive(filename_new, - data->searchdir, BLI_path_basename((char *)path_src), - &filesize, &recur_depth); + found = findFileRecursive(filename_new, + data->searchdir, BLI_path_basename((char *)path_src), + &filesize, &recur_depth); if (filesize == -1) { /* could not open dir */ BKE_reportf(data->reports, RPT_WARNING, + "Could open directory \"%s\"", + BLI_path_basename(data->searchdir)); + return FALSE; + } + else if (found == FALSE) { + BKE_reportf(data->reports, RPT_WARNING, "Could not find \"%s\" in \"%s\"", BLI_path_basename((char *)path_src), data->searchdir); return FALSE; } else { - strcpy(path_dst, filename_new); + BLI_strncpy(path_dst, filename_new, FILE_MAX); return TRUE; } } @@ -314,7 +331,11 @@ } } -static int rewrite_path_fixed_dirfile(char path_dir[FILE_MAXDIR], char path_file[FILE_MAXFILE], BPathVisitor visit_cb, const char *absbase, void *userdata) +static int rewrite_path_fixed_dirfile(char path_dir[FILE_MAXDIR], + char path_file[FILE_MAXFILE], + BPathVisitor visit_cb, + const char *absbase, + void *userdata) { char path_src[FILE_MAX]; char path_dst[FILE_MAX]; @@ -496,7 +517,8 @@ SEQ_BEGIN(scene->ed, seq) { if (SEQ_HAS_PATH(seq)) { if (ELEM(seq->type, SEQ_MOVIE, SEQ_SOUND)) { - rewrite_path_fixed_dirfile(seq->strip->dir, seq->strip->stripdata->name, visit_cb, absbase, bpath_user_data); + rewrite_path_fixed_dirfile(seq->strip->dir, seq->strip->stripdata->name, + visit_cb, absbase, bpath_user_data); } else if (seq->type == SEQ_IMAGE) { /* might want an option not to loop over all strips */ @@ -510,7 +532,8 @@ } for(i= 0; i < len; i++, se++) { - rewrite_path_fixed_dirfile(seq->strip->dir, se->name, visit_cb, absbase, bpath_user_data); + rewrite_path_fixed_dirfile(seq->strip->dir, se->name, + visit_cb, absbase, bpath_user_data); } } else { diff -Nru blender-2.61/source/blender/blenlib/intern/edgehash.c blender-2.62/source/blender/blenlib/intern/edgehash.c --- blender-2.61/source/blender/blenlib/intern/edgehash.c 2011-12-13 19:51:07.000000000 +0000 +++ blender-2.62/source/blender/blenlib/intern/edgehash.c 2012-02-15 19:35:54.000000000 +0000 @@ -20,7 +20,7 @@ * * The Original Code is: none of this file. * - * Contributor(s): Daniel Dunbar + * Contributor(s): Daniel Dunbar, Joseph Eagar * * ***** END GPL LICENSE BLOCK ***** * A general (pointer -> pointer) hash table ADT @@ -35,143 +35,159 @@ #include #include "MEM_guardedalloc.h" -#include "BLI_edgehash.h" -/***/ +#include "BLI_utildefines.h" +#include "BLI_edgehash.h" +#include "BLI_mempool.h" -static unsigned int hashsizes[]= { - 1, 3, 5, 11, 17, 37, 67, 131, 257, 521, 1031, 2053, 4099, 8209, - 16411, 32771, 65537, 131101, 262147, 524309, 1048583, 2097169, - 4194319, 8388617, 16777259, 33554467, 67108879, 134217757, +/**************inlined code************/ +static unsigned int _ehash_hashsizes[]= { + 1, 3, 5, 11, 17, 37, 67, 131, 257, 521, 1031, 2053, 4099, 8209, + 16411, 32771, 65537, 131101, 262147, 524309, 1048583, 2097169, + 4194319, 8388617, 16777259, 33554467, 67108879, 134217757, 268435459 }; -#define EDGEHASH(v0,v1) ((v0*39)^(v1*31)) +#define EDGE_HASH(v0, v1) ((v0 * 39)^(v1 * 31)) + +/* ensure v0 is smaller */ +#define EDGE_ORD(v0, v1) \ + if (v0 > v1) { \ + v0 ^= v1; \ + v1 ^= v0; \ + v0 ^= v1; \ + } /***/ -typedef struct Entry Entry; -struct Entry { - Entry *next; - int v0, v1; +typedef struct EdgeEntry EdgeEntry; +struct EdgeEntry { + EdgeEntry *next; + unsigned int v0, v1; void *val; }; struct EdgeHash { - Entry **buckets; + EdgeEntry **buckets; + BLI_mempool *epool; int nbuckets, nentries, cursize; }; /***/ -EdgeHash *BLI_edgehash_new(void) { - EdgeHash *eh= MEM_mallocN(sizeof(*eh), "EdgeHash"); - eh->cursize= 0; - eh->nentries= 0; - eh->nbuckets= hashsizes[eh->cursize]; - - eh->buckets= malloc(eh->nbuckets*sizeof(*eh->buckets)); - memset(eh->buckets, 0, eh->nbuckets*sizeof(*eh->buckets)); +EdgeHash *BLI_edgehash_new(void) +{ + EdgeHash *eh = MEM_callocN(sizeof(*eh), "EdgeHash"); + eh->cursize = 0; + eh->nentries = 0; + eh->nbuckets = _ehash_hashsizes[eh->cursize]; + eh->buckets = MEM_callocN(eh->nbuckets * sizeof(*eh->buckets), "eh buckets 2"); + eh->epool = BLI_mempool_create(sizeof(EdgeEntry), 512, 512, TRUE, FALSE); + return eh; } -void BLI_edgehash_insert(EdgeHash *eh, int v0, int v1, void *val) { + +void BLI_edgehash_insert(EdgeHash *eh, unsigned int v0, unsigned int v1, void *val) +{ unsigned int hash; - Entry *e= malloc(sizeof(*e)); + EdgeEntry *e = BLI_mempool_alloc(eh->epool); - if (v1nbuckets; + EDGE_ORD(v0, v1); /* ensure v0 is smaller */ + + hash = EDGE_HASH(v0, v1) % eh->nbuckets; e->v0 = v0; e->v1 = v1; e->val = val; - e->next= eh->buckets[hash]; + e->next = eh->buckets[hash]; eh->buckets[hash]= e; - - if (++eh->nentries>eh->nbuckets*3) { - Entry **old= eh->buckets; - int i, nold= eh->nbuckets; - - eh->nbuckets= hashsizes[++eh->cursize]; - eh->buckets= malloc(eh->nbuckets*sizeof(*eh->buckets)); - memset(eh->buckets, 0, eh->nbuckets*sizeof(*eh->buckets)); - - for (i=0; inext; - - hash= EDGEHASH(e->v0,e->v1)%eh->nbuckets; - e->next= eh->buckets[hash]; + + if (++eh->nentries>eh->nbuckets * 3) { + EdgeEntry *e, **old = eh->buckets; + int i, nold = eh->nbuckets; + + eh->nbuckets = _ehash_hashsizes[++eh->cursize]; + eh->buckets = MEM_mallocN(eh->nbuckets * sizeof(*eh->buckets), "eh buckets"); + memset(eh->buckets, 0, eh->nbuckets * sizeof(*eh->buckets)); + + for (i = 0; i < nold; i++) { + for (e = old[i]; e;) { + EdgeEntry *n = e->next; + + hash = EDGE_HASH(e->v0, e->v1) % eh->nbuckets; + e->next = eh->buckets[hash]; eh->buckets[hash]= e; - - e= n; + + e = n; } } - - free(old); + + MEM_freeN(old); } } -void** BLI_edgehash_lookup_p(EdgeHash *eh, int v0, int v1) { +void **BLI_edgehash_lookup_p(EdgeHash *eh, unsigned int v0, unsigned int v1) +{ unsigned int hash; - Entry *e; + EdgeEntry *e; - if (v1nbuckets; - for (e= eh->buckets[hash]; e; e= e->next) - if (v0==e->v0 && v1==e->v1) + EDGE_ORD(v0, v1); /* ensure v0 is smaller */ + + hash = EDGE_HASH(v0, v1) % eh->nbuckets; + for (e = eh->buckets[hash]; e; e = e->next) + if (v0 == e->v0 && v1 == e->v1) return &e->val; - + return NULL; } -void* BLI_edgehash_lookup(EdgeHash *eh, int v0, int v1) { - void **value_p = BLI_edgehash_lookup_p(eh,v0,v1); +void *BLI_edgehash_lookup(EdgeHash *eh, unsigned int v0, unsigned int v1) +{ + void **value_p = BLI_edgehash_lookup_p(eh, v0, v1); return value_p?*value_p:NULL; } -int BLI_edgehash_haskey(EdgeHash *eh, int v0, int v1) { - return BLI_edgehash_lookup_p(eh, v0, v1)!=NULL; +int BLI_edgehash_haskey(EdgeHash *eh, unsigned int v0, unsigned int v1) +{ + return BLI_edgehash_lookup_p(eh, v0, v1) != NULL; } -int BLI_edgehash_size(EdgeHash *eh) { +int BLI_edgehash_size(EdgeHash *eh) +{ return eh->nentries; } -void BLI_edgehash_clear(EdgeHash *eh, EdgeHashFreeFP valfreefp) { +void BLI_edgehash_clear(EdgeHash *eh, EdgeHashFreeFP valfreefp) +{ int i; - for (i=0; inbuckets; i++) { - Entry *e; + for (i = 0; inbuckets; i++) { + EdgeEntry *e; - for (e= eh->buckets[i]; e; ) { - Entry *n= e->next; + for (e = eh->buckets[i]; e; ) { + EdgeEntry *n = e->next; if (valfreefp) valfreefp(e->val); - free(e); + BLI_mempool_free(eh->epool, e); - e= n; + e = n; } - eh->buckets[i]= NULL; + eh->buckets[i] = NULL; } - eh->nentries= 0; + eh->nentries = 0; } -void BLI_edgehash_free(EdgeHash *eh, EdgeHashFreeFP valfreefp) { +void BLI_edgehash_free(EdgeHash *eh, EdgeHashFreeFP valfreefp) +{ BLI_edgehash_clear(eh, valfreefp); - - free(eh->buckets); + + BLI_mempool_destroy(eh->epool); + + MEM_freeN(eh->buckets); MEM_freeN(eh); } @@ -181,53 +197,63 @@ struct EdgeHashIterator { EdgeHash *eh; int curBucket; - Entry *curEntry; + EdgeEntry *curEntry; }; -EdgeHashIterator *BLI_edgehashIterator_new(EdgeHash *eh) { - EdgeHashIterator *ehi= malloc(sizeof(*ehi)); - ehi->eh= eh; - ehi->curEntry= NULL; - ehi->curBucket= -1; +EdgeHashIterator *BLI_edgehashIterator_new(EdgeHash *eh) +{ + EdgeHashIterator *ehi = MEM_mallocN(sizeof(*ehi), "eh iter"); + ehi->eh = eh; + ehi->curEntry = NULL; + ehi->curBucket = -1; while (!ehi->curEntry) { ehi->curBucket++; - if (ehi->curBucket==ehi->eh->nbuckets) + if (ehi->curBucket == ehi->eh->nbuckets) break; - ehi->curEntry= ehi->eh->buckets[ehi->curBucket]; + ehi->curEntry = ehi->eh->buckets[ehi->curBucket]; } return ehi; } -void BLI_edgehashIterator_free(EdgeHashIterator *ehi) { - free(ehi); +void BLI_edgehashIterator_free(EdgeHashIterator *ehi) +{ + MEM_freeN(ehi); } -void BLI_edgehashIterator_getKey(EdgeHashIterator *ehi, int *v0_r, int *v1_r) { +void BLI_edgehashIterator_getKey(EdgeHashIterator *ehi, unsigned int *v0_r, unsigned int *v1_r) +{ if (ehi->curEntry) { *v0_r = ehi->curEntry->v0; *v1_r = ehi->curEntry->v1; } } -void *BLI_edgehashIterator_getValue(EdgeHashIterator *ehi) { +void *BLI_edgehashIterator_getValue(EdgeHashIterator *ehi) +{ return ehi->curEntry?ehi->curEntry->val:NULL; } -void BLI_edgehashIterator_setValue(EdgeHashIterator *ehi, void *val) { - if(ehi->curEntry) - ehi->curEntry->val= val; +void BLI_edgehashIterator_setValue(EdgeHashIterator *ehi, void *val) +{ + if (ehi->curEntry) { + ehi->curEntry->val = val; + } } -void BLI_edgehashIterator_step(EdgeHashIterator *ehi) { +void BLI_edgehashIterator_step(EdgeHashIterator *ehi) +{ if (ehi->curEntry) { - ehi->curEntry= ehi->curEntry->next; + ehi->curEntry = ehi->curEntry->next; while (!ehi->curEntry) { ehi->curBucket++; - if (ehi->curBucket==ehi->eh->nbuckets) + if (ehi->curBucket == ehi->eh->nbuckets) { break; - ehi->curEntry= ehi->eh->buckets[ehi->curBucket]; + } + + ehi->curEntry = ehi->eh->buckets[ehi->curBucket]; } } } -int BLI_edgehashIterator_isDone(EdgeHashIterator *ehi) { +int BLI_edgehashIterator_isDone(EdgeHashIterator *ehi) +{ return !ehi->curEntry; } diff -Nru blender-2.61/source/blender/blenlib/intern/fileops.c blender-2.62/source/blender/blenlib/intern/fileops.c --- blender-2.61/source/blender/blenlib/intern/fileops.c 2011-12-13 19:51:07.000000000 +0000 +++ blender-2.62/source/blender/blenlib/intern/fileops.c 2012-02-15 19:35:54.000000000 +0000 @@ -82,7 +82,7 @@ return -2; while(1) { - readsize = read(file, buffer, 10240); + readsize = read(file, buffer, sizeof(buffer)); if(readsize < 0) { rval= -2; /* error happened in reading */ diff -Nru blender-2.61/source/blender/blenlib/intern/math_base_inline.c blender-2.62/source/blender/blenlib/intern/math_base_inline.c --- blender-2.61/source/blender/blenlib/intern/math_base_inline.c 2011-12-13 19:51:07.000000000 +0000 +++ blender-2.62/source/blender/blenlib/intern/math_base_inline.c 2012-02-15 19:35:54.000000000 +0000 @@ -115,6 +115,31 @@ return (float)pow(2.0, ceil(log((double)val) / M_LN2)); } +MINLINE int is_power_of_2_i(int n) +{ + return (n & (n - 1)) == 0; +} + +MINLINE int power_of_2_max_i(int n) +{ + if (is_power_of_2_i(n)) + return n; + + while(!is_power_of_2_i(n)) + n = n & (n - 1); + + return n * 2; +} + +MINLINE int power_of_2_min_i(int n) +{ + while (!is_power_of_2_i(n)) + n = n & (n - 1); + + return n; +} + + MINLINE float minf(float a, float b) { return (a < b)? a: b; @@ -130,5 +155,6 @@ return (f < 0.f)? -1.f: 1.f; } + #endif /* BLI_MATH_BASE_INLINE_H */ diff -Nru blender-2.61/source/blender/blenlib/intern/math_color.c blender-2.62/source/blender/blenlib/intern/math_color.c --- blender-2.61/source/blender/blenlib/intern/math_color.c 2011-12-13 19:51:07.000000000 +0000 +++ blender-2.62/source/blender/blenlib/intern/math_color.c 2012-02-15 19:35:54.000000000 +0000 @@ -30,7 +30,11 @@ #include +#include "MEM_guardedalloc.h" + #include "BLI_math.h" +#include "BLI_rand.h" +#include "BLI_utildefines.h" void hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b) { @@ -333,24 +337,29 @@ *b /= 255.0f; } -void rgb_byte_to_float(const unsigned char *in, float *out) +void rgb_uchar_to_float(float col_r[3], const unsigned char col_ub[3]) { - out[0]= ((float)in[0]) / 255.0f; - out[1]= ((float)in[1]) / 255.0f; - out[2]= ((float)in[2]) / 255.0f; + col_r[0]= ((float)col_ub[0]) / 255.0f; + col_r[1]= ((float)col_ub[1]) / 255.0f; + col_r[2]= ((float)col_ub[2]) / 255.0f; } -void rgb_float_to_byte(const float *in, unsigned char *out) +void rgba_uchar_to_float(float col_r[4], const unsigned char col_ub[4]) { - int r, g, b; - - r= (int)(in[0] * 255.0f); - g= (int)(in[1] * 255.0f); - b= (int)(in[2] * 255.0f); - - out[0]= (char)((r <= 0)? 0 : (r >= 255)? 255 : r); - out[1]= (char)((g <= 0)? 0 : (g >= 255)? 255 : g); - out[2]= (char)((b <= 0)? 0 : (b >= 255)? 255 : b); + col_r[0]= ((float)col_ub[0]) / 255.0f; + col_r[1]= ((float)col_ub[1]) / 255.0f; + col_r[2]= ((float)col_ub[2]) / 255.0f; + col_r[3]= ((float)col_ub[3]) / 255.0f; +} + +void rgb_float_to_uchar(unsigned char col_r[3], const float col_f[3]) +{ + F3TOCHAR3(col_f, col_r); +} + +void rgba_float_to_uchar(unsigned char col_r[4], const float col_f[4]) +{ + F4TOCHAR4(col_f, col_r); } /* ********************************* color transforms ********************************* */ @@ -393,57 +402,6 @@ return 1.055f * powf(c, 1.0f/2.4f) - 0.055f; } -void srgb_to_linearrgb_v3_v3(float *col_to, float *col_from) -{ - col_to[0] = srgb_to_linearrgb(col_from[0]); - col_to[1] = srgb_to_linearrgb(col_from[1]); - col_to[2] = srgb_to_linearrgb(col_from[2]); -} - -void linearrgb_to_srgb_v3_v3(float *col_to, float *col_from) -{ - col_to[0] = linearrgb_to_srgb(col_from[0]); - col_to[1] = linearrgb_to_srgb(col_from[1]); - col_to[2] = linearrgb_to_srgb(col_from[2]); -} - -/* todo, should these be moved elsewhere?, they dont belong in imbuf */ -void srgb_to_linearrgb_rgba_buf(float *col, int tot) -{ - while(tot--) { - srgb_to_linearrgb_v3_v3(col, col); - col += 4; - } -} - -void linearrgb_to_srgb_rgba_buf(float *col, int tot) -{ - while(tot--) { - linearrgb_to_srgb_v3_v3(col, col); - col += 4; - } -} - -void srgb_to_linearrgb_rgba_rgba_buf(float *col_to, float *col_from, int tot) -{ - while(tot--) { - srgb_to_linearrgb_v3_v3(col_to, col_from); - col_to[3]= col_from[3]; - col_to += 4; - col_from += 4; - } -} - -void linearrgb_to_srgb_rgba_rgba_buf(float *col_to, float *col_from, int tot) -{ - while(tot--) { - linearrgb_to_srgb_v3_v3(col_to, col_from); - col_to[3]= col_from[3]; - col_to += 4; - col_from += 4; - } -} - void minmax_rgb(short c[]) { if(c[0]>255) c[0]=255; @@ -481,16 +439,26 @@ return 0; /* Color within RGB gamut */ } -float rgb_to_grayscale(float rgb[3]) +float rgb_to_grayscale(const float rgb[3]) { return 0.3f*rgb[0] + 0.58f*rgb[1] + 0.12f*rgb[2]; } -unsigned char rgb_to_grayscale_byte(unsigned char rgb[3]) +unsigned char rgb_to_grayscale_byte(const unsigned char rgb[3]) { return (76*(unsigned short)rgb[0] + 148*(unsigned short)rgb[1] + 31*(unsigned short)rgb[2]) / 255; } +float rgb_to_luma(const float rgb[3]) +{ + return 0.299f*rgb[0] + 0.587f*rgb[1] + 0.114f*rgb[2]; +} + +unsigned char rgb_to_luma_byte(const unsigned char rgb[3]) +{ + return (76*(unsigned short)rgb[0] + 150*(unsigned short)rgb[1] + 29*(unsigned short)rgb[2]) / 255; +} + /* ********************************* lift/gamma/gain / ASC-CDL conversion ********************************* */ void lift_gamma_gain_to_asc_cdl(float *lift, float *gamma, float *gain, float *offset, float *slope, float *power) @@ -527,7 +495,83 @@ { float rgb_float[3]; - rgb_byte_to_float(rgb, rgb_float); + rgb_uchar_to_float(rgb_float, rgb); rgb_float_set_hue_float_offset(rgb_float, hue_offset); - rgb_float_to_byte(rgb_float, rgb); + rgb_float_to_uchar(rgb, rgb_float); +} + + +/* fast sRGB conversion + * LUT from linear float to 16-bit short + * based on http://mysite.verizon.net/spitzak/conversion/ + */ + +float BLI_color_from_srgb_table[256]; +unsigned short BLI_color_to_srgb_table[0x10000]; + +static unsigned short hipart(const float f) +{ + union { + float f; + unsigned short us[2]; + } tmp; + + tmp.f = f; + +#ifdef __BIG_ENDIAN__ + return tmp.us[0]; +#else + return tmp.us[1]; +#endif } + +static float index_to_float(const unsigned short i) +{ + union { + float f; + unsigned short us[2]; + } tmp; + + /* positive and negative zeros, and all gradual underflow, turn into zero: */ + if (i<0x80 || (i >= 0x8000 && i < 0x8080)) return 0; + /* All NaN's and infinity turn into the largest possible legal float: */ + if (i>=0x7f80 && i<0x8000) return FLT_MAX; + if (i>=0xff80) return -FLT_MAX; + +#ifdef __BIG_ENDIAN__ + tmp.us[0] = i; + tmp.us[1] = 0x8000; +#else + tmp.us[0] = 0x8000; + tmp.us[1] = i; +#endif + + return tmp.f; +} + +void BLI_init_srgb_conversion(void) +{ + static int initialized= 0; + int i, b; + + if (initialized) return; + initialized = 1; + + /* Fill in the lookup table to convert floats to bytes: */ + for (i = 0; i < 0x10000; i++) { + float f = linearrgb_to_srgb(index_to_float(i))*255.0f; + if (f <= 0) BLI_color_to_srgb_table[i] = 0; + else if (f < 255) BLI_color_to_srgb_table[i] = (unsigned short)(f*0x100+0.5f); + else BLI_color_to_srgb_table[i] = 0xff00; + } + + /* Fill in the lookup table to convert bytes to float: */ + for (b = 0; b <= 255; b++) { + float f = srgb_to_linearrgb(((float)b)*(1.0f/255.0f)); + BLI_color_from_srgb_table[b] = f; + i = hipart(f); + /* replace entries so byte->float->byte does not change the data: */ + BLI_color_to_srgb_table[i] = b*0x100; + } +} + diff -Nru blender-2.61/source/blender/blenlib/intern/math_color_inline.c blender-2.62/source/blender/blenlib/intern/math_color_inline.c --- blender-2.61/source/blender/blenlib/intern/math_color_inline.c 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/source/blender/blenlib/intern/math_color_inline.c 2012-02-15 19:35:54.000000000 +0000 @@ -0,0 +1,200 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: some of this file. + * + * ***** END GPL LICENSE BLOCK ***** + * */ + +/** \file blender/blenlib/intern/math_color_inline.c + * \ingroup bli + */ + + +#include "BLI_math_color.h" +#include "BLI_utildefines.h" + +#ifndef BLI_MATH_COLOR_INLINE_H +#define BLI_MATH_COLOR_INLINE_H + +/******************************** Color Space ********************************/ + +MINLINE void srgb_to_linearrgb_v3_v3(float linear[3], const float srgb[3]) +{ + linear[0] = srgb_to_linearrgb(srgb[0]); + linear[1] = srgb_to_linearrgb(srgb[1]); + linear[2] = srgb_to_linearrgb(srgb[2]); +} + +MINLINE void linearrgb_to_srgb_v3_v3(float srgb[3], const float linear[3]) +{ + srgb[0] = linearrgb_to_srgb(linear[0]); + srgb[1] = linearrgb_to_srgb(linear[1]); + srgb[2] = linearrgb_to_srgb(linear[2]); +} + +MINLINE void srgb_to_linearrgb_v4(float linear[4], const float srgb[4]) +{ + srgb_to_linearrgb_v3_v3(linear, srgb); + linear[3] = srgb[3]; +} + +MINLINE void linearrgb_to_srgb_v4(float srgb[4], const float linear[4]) +{ + linearrgb_to_srgb_v3_v3(srgb, linear); + srgb[3] = linear[3]; +} + +MINLINE void linearrgb_to_srgb_uchar3(unsigned char srgb[3], const float linear[3]) +{ + float srgb_f[3]; + + linearrgb_to_srgb_v3_v3(srgb_f, linear); + F3TOCHAR3(srgb_f, srgb); +} + +MINLINE void linearrgb_to_srgb_uchar4(unsigned char srgb[4], const float linear[4]) +{ + float srgb_f[4]; + + linearrgb_to_srgb_v4(srgb_f, linear); + F4TOCHAR4(srgb_f, srgb); +} + +/* predivide versions to work on associated/premultipled alpha. if this should + be done or not depends on the background the image will be composited over, + ideally you would never do color space conversion on an image with alpha + because it is ill defined */ + +MINLINE void srgb_to_linearrgb_predivide_v4(float linear[4], const float srgb[4]) +{ + float alpha, inv_alpha; + + if(srgb[3] == 1.0f || srgb[3] == 0.0f) { + alpha = 1.0f; + inv_alpha = 1.0f; + } + else { + alpha = srgb[3]; + inv_alpha = 1.0f/alpha; + } + + linear[0] = srgb_to_linearrgb(srgb[0] * inv_alpha) * alpha; + linear[1] = srgb_to_linearrgb(srgb[1] * inv_alpha) * alpha; + linear[2] = srgb_to_linearrgb(srgb[2] * inv_alpha) * alpha; + linear[3] = srgb[3]; +} + +MINLINE void linearrgb_to_srgb_predivide_v4(float srgb[4], const float linear[4]) +{ + float alpha, inv_alpha; + + if(linear[3] == 1.0f || linear[3] == 0.0f) { + alpha = 1.0f; + inv_alpha = 1.0f; + } + else { + alpha = linear[3]; + inv_alpha = 1.0f/alpha; + } + + srgb[0] = linearrgb_to_srgb(linear[0] * inv_alpha) * alpha; + srgb[1] = linearrgb_to_srgb(linear[1] * inv_alpha) * alpha; + srgb[2] = linearrgb_to_srgb(linear[2] * inv_alpha) * alpha; + srgb[3] = linear[3]; +} + +/* LUT accelerated conversions */ + +extern float BLI_color_from_srgb_table[256]; +extern unsigned short BLI_color_to_srgb_table[0x10000]; + +MINLINE unsigned short to_srgb_table_lookup(const float f) +{ + union { + float f; + unsigned short us[2]; + } tmp; + tmp.f = f; +#ifdef __BIG_ENDIAN__ + return BLI_color_to_srgb_table[tmp.us[0]]; +#else + return BLI_color_to_srgb_table[tmp.us[1]]; +#endif +} + +MINLINE void linearrgb_to_srgb_ushort4(unsigned short srgb[4], const float linear[4]) +{ + srgb[0] = to_srgb_table_lookup(linear[0]); + srgb[1] = to_srgb_table_lookup(linear[1]); + srgb[2] = to_srgb_table_lookup(linear[2]); + srgb[3] = FTOUSHORT(linear[3]); +} + +MINLINE void linearrgb_to_srgb_ushort4_predivide(unsigned short srgb[4], const float linear[4]) +{ + float alpha, inv_alpha, t; + int i; + + if(linear[3] == 1.0f || linear[3] == 0.0f) { + linearrgb_to_srgb_ushort4(srgb, linear); + return; + } + + alpha = linear[3]; + inv_alpha = 1.0f/alpha; + + for(i=0; i<3; ++i) { + t = linear[i] * inv_alpha; + srgb[i] = (t < 1.0f)? to_srgb_table_lookup(t) * alpha : FTOUSHORT(linearrgb_to_srgb(t) * alpha); + } + + srgb[3] = FTOUSHORT(linear[3]); +} + +MINLINE void srgb_to_linearrgb_uchar4(float linear[4], const unsigned char srgb[4]) +{ + linear[0] = BLI_color_from_srgb_table[srgb[0]]; + linear[1] = BLI_color_from_srgb_table[srgb[1]]; + linear[2] = BLI_color_from_srgb_table[srgb[2]]; + linear[3] = srgb[3] * (1.0f/255.0f); +} + +MINLINE void srgb_to_linearrgb_uchar4_predivide(float linear[4], const unsigned char srgb[4]) +{ + float alpha, inv_alpha; + int i; + + if(srgb[3] == 255 || srgb[3] == 0) { + srgb_to_linearrgb_uchar4(linear, srgb); + return; + } + + alpha = srgb[3] * (1.0f/255.0f); + inv_alpha = 1.0f/alpha; + + for(i=0; i<3; ++i) + linear[i] = linearrgb_to_srgb(srgb[i] * inv_alpha) * alpha; + + linear[3] = alpha; +} + +#endif /* BLI_MATH_COLOR_INLINE_H */ + diff -Nru blender-2.61/source/blender/blenlib/intern/math_geom.c blender-2.62/source/blender/blenlib/intern/math_geom.c --- blender-2.61/source/blender/blenlib/intern/math_geom.c 2011-12-13 19:51:07.000000000 +0000 +++ blender-2.62/source/blender/blenlib/intern/math_geom.c 2012-02-15 19:35:54.000000000 +0000 @@ -209,33 +209,54 @@ } /* point closest to v1 on line v2-v3 in 2D */ -void closest_to_line_segment_v2(float closest[2], const float p[2], const float l1[2], const float l2[2]) +void closest_to_line_segment_v2(float close_r[2], const float p[2], const float l1[2], const float l2[2]) { float lambda, cp[2]; lambda= closest_to_line_v2(cp,p, l1, l2); if(lambda <= 0.0f) - copy_v2_v2(closest, l1); + copy_v2_v2(close_r, l1); else if(lambda >= 1.0f) - copy_v2_v2(closest, l2); + copy_v2_v2(close_r, l2); else - copy_v2_v2(closest, cp); + copy_v2_v2(close_r, cp); } /* point closest to v1 on line v2-v3 in 3D */ -void closest_to_line_segment_v3(float closest[3], const float v1[3], const float v2[3], const float v3[3]) +void closest_to_line_segment_v3(float close_r[3], const float v1[3], const float v2[3], const float v3[3]) { float lambda, cp[3]; lambda= closest_to_line_v3(cp,v1, v2, v3); if(lambda <= 0.0f) - copy_v3_v3(closest, v2); + copy_v3_v3(close_r, v2); else if(lambda >= 1.0f) - copy_v3_v3(closest, v3); + copy_v3_v3(close_r, v3); else - copy_v3_v3(closest, cp); + copy_v3_v3(close_r, cp); +} + +/* find the closest point on a plane to another point and store it in close_r + * close_r: return coordinate + * plane_co: a point on the plane + * plane_no_unit: the plane's normal, and d is the last number in the plane equation 0 = ax + by + cz + d + * pt: the point that you want the nearest of + */ + +// const float norm[3], const float coord[3], const float point[3], float dst_r[3] +void closest_to_plane_v3(float close_r[3], const float plane_co[3], const float plane_no_unit[3], const float pt[3]) +{ + float temp[3]; + float dotprod; + + sub_v3_v3v3(temp, pt, plane_co); + dotprod= dot_v3v3(temp, plane_no_unit); + + close_r[0] = pt[0] - (plane_no_unit[0] * dotprod); + close_r[1] = pt[1] - (plane_no_unit[1] * dotprod); + close_r[2] = pt[2] - (plane_no_unit[2] * dotprod); } /* signed distance from the point to the plane in 3D */ @@ -2361,6 +2382,38 @@ } } +/* Add weighted face normal component into normals of the face vertices. + Caller must pass pre-allocated vdiffs of nverts length. */ +void accumulate_vertex_normals_poly(float **vertnos, float polyno[3], + float **vertcos, float vdiffs[][3], int nverts) +{ + int i; + + /* calculate normalized edge directions for each edge in the poly */ + for (i = 0; i < nverts; i++) { + sub_v3_v3v3(vdiffs[i], vertcos[(i+1) % nverts], vertcos[i]); + normalize_v3(vdiffs[i]); + } + + /* accumulate angle weighted face normal */ + { + const float *prev_edge = vdiffs[nverts-1]; + int i; + + for(i=0; i 0) ? 1 : 0; +} diff -Nru blender-2.61/source/blender/blenlib/intern/math_matrix.c blender-2.62/source/blender/blenlib/intern/math_matrix.c --- blender-2.61/source/blender/blenlib/intern/math_matrix.c 2011-12-13 19:51:07.000000000 +0000 +++ blender-2.62/source/blender/blenlib/intern/math_matrix.c 2012-02-15 19:35:54.000000000 +0000 @@ -142,7 +142,7 @@ /******************************** Arithmetic *********************************/ -void mul_m4_m4m4(float m1[][4], float m2_[][4], float m3_[][4]) +void mult_m4_m4m4(float m1[][4], float m3_[][4], float m2_[][4]) { float m2[4][4], m3[4][4]; @@ -195,8 +195,14 @@ m1[2][2]= m2[2][0]*m3[0][2] + m2[2][1]*m3[1][2] + m2[2][2]*m3[2][2]; } -void mul_m4_m4m3(float (*m1)[4], float (*m3)[4], float (*m2)[3]) +void mul_m4_m4m3(float (*m1)[4], float (*m3_)[4], float (*m2_)[3]) { + float m2[3][3], m3[4][4]; + + /* copy so it works when m1 is the same pointer as m2 or m3 */ + copy_m3_m3(m2, m2_); + copy_m4_m4(m3, m3_); + m1[0][0]= m2[0][0]*m3[0][0] + m2[0][1]*m3[1][0] + m2[0][2]*m3[2][0]; m1[0][1]= m2[0][0]*m3[0][1] + m2[0][1]*m3[1][1] + m2[0][2]*m3[2][1]; m1[0][2]= m2[0][0]*m3[0][2] + m2[0][1]*m3[1][2] + m2[0][2]*m3[2][2]; @@ -209,7 +215,7 @@ } /* m1 = m2 * m3, ignore the elements on the 4th row/column of m3*/ -void mul_m3_m3m4(float m1[][3], float m2[][3], float m3[][4]) +void mult_m3_m3m4(float m1[][3], float m3[][4], float m2[][3]) { /* m1[i][j] = m2[i][k] * m3[k][j] */ m1[0][0] = m2[0][0] * m3[0][0] + m2[0][1] * m3[1][0] +m2[0][2] * m3[2][0]; @@ -280,19 +286,19 @@ if(m1==NULL || m2==NULL) return; - mul_m4_m4m4(answ, m2, m1); + mult_m4_m4m4(answ, m1, m2); if(m3) { - mul_m4_m4m4(temp, m3, answ); + mult_m4_m4m4(temp, answ, m3); if(m4) { - mul_m4_m4m4(answ, m4, temp); + mult_m4_m4m4(answ, temp, m4); if(m5) { - mul_m4_m4m4(temp, m5, answ); + mult_m4_m4m4(temp, answ, m5); if(m6) { - mul_m4_m4m4(answ, m6, temp); + mult_m4_m4m4(answ, temp, m6); if(m7) { - mul_m4_m4m4(temp, m7, answ); + mult_m4_m4m4(temp, answ, m7); if(m8) { - mul_m4_m4m4(answ, m8, temp); + mult_m4_m4m4(answ, temp, m8); } else copy_m4_m4(answ, temp); } @@ -772,32 +778,38 @@ mul_v3_fl(mat[2], size[2]); } -int is_orthogonal_m3(float mat[][3]) +int is_orthogonal_m3(float m[][3]) { - if (fabsf(dot_v3v3(mat[0], mat[1])) > 1.5f * FLT_EPSILON) - return 0; + int i, j; - if (fabsf(dot_v3v3(mat[1], mat[2])) > 1.5f * FLT_EPSILON) - return 0; + for (i = 0; i < 3; i++) { + for (j = 0; j < i; j++) { + if (fabsf(dot_v3v3(m[i], m[j])) > 1.5f * FLT_EPSILON) + return 0; + } - if (fabsf(dot_v3v3(mat[0], mat[2])) > 1.5f * FLT_EPSILON) - return 0; - - return 1; + if (fabsf(dot_v3v3(m[i], m[i]) - 1) > 1.5f * FLT_EPSILON) + return 0; + } + + return 1; } -int is_orthogonal_m4(float mat[][4]) +int is_orthogonal_m4(float m[][4]) { - if (fabsf(dot_v3v3(mat[0], mat[1])) > 1.5f * FLT_EPSILON) - return 0; + int i, j; - if (fabsf(dot_v3v3(mat[1], mat[2])) > 1.5f * FLT_EPSILON) - return 0; + for (i = 0; i < 4; i++) { + for (j = 0; j < i; j++) { + if (fabsf(dot_vn_vn(m[i], m[j], 4)) > 1.5f * FLT_EPSILON) + return 0; + } - if (fabsf(dot_v3v3(mat[0], mat[2])) > 1.5f * FLT_EPSILON) - return 0; - - return 1; + if (fabsf(dot_vn_vn(m[i], m[i], 4) - 1) > 1.5f * FLT_EPSILON) + return 0; + } + + return 1; } void normalize_m3(float mat[][3]) diff -Nru blender-2.61/source/blender/blenlib/intern/math_rotation.c blender-2.62/source/blender/blenlib/intern/math_rotation.c --- blender-2.61/source/blender/blenlib/intern/math_rotation.c 2011-12-13 19:51:07.000000000 +0000 +++ blender-2.62/source/blender/blenlib/intern/math_rotation.c 2012-02-15 19:35:54.000000000 +0000 @@ -811,7 +811,7 @@ mat[2][2] = 1.0f; break; default: - assert("invalid axis"); + assert(0); } } @@ -1433,7 +1433,7 @@ /* split scaling and rotation, there is probably a faster way to do this, it's done like this now to correctly get negative scaling */ - mul_m4_m4m4(baseRS, basemat, mat); + mult_m4_m4m4(baseRS, mat, basemat); mat4_to_size(scale,baseRS); copy_v3_v3(dscale, scale); @@ -1452,10 +1452,10 @@ copy_v3_v3(baseR[3], baseRS[3]); invert_m4_m4(baseinv, basemat); - mul_m4_m4m4(R, baseinv, baseR); + mult_m4_m4m4(R, baseR, baseinv); invert_m4_m4(baseRinv, baseR); - mul_m4_m4m4(S, baseRS, baseRinv); + mult_m4_m4m4(S, baseRinv, baseRS); /* set scaling part */ mul_serie_m4(dq->scale, basemat, S, baseinv, NULL, NULL, NULL, NULL, NULL); diff -Nru blender-2.61/source/blender/blenlib/intern/math_vector.c blender-2.62/source/blender/blenlib/intern/math_vector.c --- blender-2.61/source/blender/blenlib/intern/math_vector.c 2011-12-13 19:51:07.000000000 +0000 +++ blender-2.62/source/blender/blenlib/intern/math_vector.c 2012-02-15 19:35:54.000000000 +0000 @@ -239,6 +239,20 @@ angles[3]= (float)M_PI - angle_normalized_v3v3(ed4, ed1); } +void angle_poly_v3(float *angles, const float *verts[3], int len) +{ + int i; + float vec[3][3]; + + sub_v3_v3v3(vec[2], verts[len-1], verts[0]); + normalize_v3(vec[2]); + for (i = 0; i < len; i++) { + sub_v3_v3v3(vec[i%3], verts[i%len], verts[(i+1)%len]); + normalize_v3(vec[i%3]); + angles[i] = (float)M_PI - angle_normalized_v3v3(vec[(i+2)%3], vec[i%3]); + } +} + /********************************* Geometry **********************************/ /* Project v1 on v2 */ @@ -416,6 +430,15 @@ while(i--) { *(array_pt--) = j--; } } +void range_vn_fl(float *array_tar, const int size, const float start, const float step) +{ + float *array_pt= array_tar + (size-1); + int i= size; + while(i--) { + *(array_pt--) = start + step * (float)(i); + } +} + void negate_vn(float *array_tar, const int size) { float *array_pt= array_tar + (size-1); diff -Nru blender-2.61/source/blender/blenlib/intern/math_vector_inline.c blender-2.62/source/blender/blenlib/intern/math_vector_inline.c --- blender-2.61/source/blender/blenlib/intern/math_vector_inline.c 2011-12-13 19:51:07.000000000 +0000 +++ blender-2.62/source/blender/blenlib/intern/math_vector_inline.c 2012-02-15 19:35:54.000000000 +0000 @@ -429,6 +429,11 @@ /*********************************** Length **********************************/ +MINLINE float len_squared_v2(const float v[2]) +{ + return v[0]*v[0] + v[1]*v[1]; +} + MINLINE float len_v2(const float v[2]) { return (float)sqrtf(v[0]*v[0] + v[1]*v[1]); @@ -448,7 +453,7 @@ return sqrtf(dot_v3v3(a, a)); } -MINLINE float len_squared_v2v2(const float a[3], const float b[3]) +MINLINE float len_squared_v2v2(const float a[2], const float b[2]) { float d[2]; @@ -510,6 +515,29 @@ return d; } +MINLINE double normalize_v3_d(double n[3]) +{ + double d= n[0]*n[0] + n[1]*n[1] + n[2]*n[2]; + + /* a larger value causes normalize errors in a + scaled down models with camera xtreme close */ + if(d > 1.0e-35) { + double mul; + + d= sqrt(d); + mul = 1.0 / d; + + n[0] *= mul; + n[1] *= mul; + n[2] *= mul; + } else { + n[0] = n[1] = n[2] = 0; + d= 0.0; + } + + return d; +} + MINLINE float normalize_v3(float n[3]) { return normalize_v3_v3(n, n); diff -Nru blender-2.61/source/blender/blenlib/intern/md5.c blender-2.62/source/blender/blenlib/intern/md5.c --- blender-2.61/source/blender/blenlib/intern/md5.c 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/source/blender/blenlib/intern/md5.c 2012-02-15 19:35:54.000000000 +0000 @@ -0,0 +1,414 @@ +/** \file blender/imbuf/intern/md5.c + * \ingroup imbuf + */ +/* md5.c - Functions to compute MD5 message digest of files or memory blocks + according to the definition of MD5 in RFC 1321 from April 1992. + Copyright (C) 1995 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Written by Ulrich Drepper . */ + +#include +#include +#include +#include + +#if defined HAVE_LIMITS_H || defined _LIBC +# include +#endif + +/* The following contortions are an attempt to use the C preprocessor + to determine an unsigned integral type that is 32 bits wide. An + alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but + doing that would require that the configure script compile and *run* + the resulting executable. Locally running cross-compiled executables + is usually not possible. */ + +#if defined __STDC__ && __STDC__ +# define UINT_MAX_32_BITS 4294967295U +#else +# define UINT_MAX_32_BITS 0xFFFFFFFF +#endif + +/* If UINT_MAX isn't defined, assume it's a 32-bit type. + This should be valid for all systems GNU cares about because + that doesn't include 16-bit systems, and only modern systems + (that certainly have ) have 64+-bit integral types. */ + +#ifndef UINT_MAX +# define UINT_MAX UINT_MAX_32_BITS +#endif + +#if UINT_MAX == UINT_MAX_32_BITS + typedef unsigned int md5_uint32; +#else +# if USHRT_MAX == UINT_MAX_32_BITS + typedef unsigned short md5_uint32; +# else +# if ULONG_MAX == UINT_MAX_32_BITS + typedef unsigned long md5_uint32; +# else + /* The following line is intended to evoke an error. + Using #error is not portable enough. */ + "Cannot determine unsigned 32-bit data type." +# endif +# endif +#endif + +/* Structure to save state of computation between the single steps. */ +struct md5_ctx +{ + md5_uint32 A; + md5_uint32 B; + md5_uint32 C; + md5_uint32 D; +}; + +/* + * The following three functions are build up the low level used in + * the functions `md5_stream' and `md5_buffer'. + */ + +/* Initialize structure containing state of computation. + (RFC 1321, 3.3: Step 3) */ +static void md5_init_ctx(struct md5_ctx *ctx); + +/* Starting with the result of former calls of this function (or the + initialzation function update the context for the next LEN bytes + starting at BUFFER. + It is necessary that LEN is a multiple of 64!!! */ +static void md5_process_block(const void *buffer, size_t len, struct md5_ctx *ctx); + +/* Put result from CTX in first 16 bytes following RESBUF. The result is + always in little endian byte order, so that a byte-wise output yields + to the wanted ASCII representation of the message digest. */ +static void *md5_read_ctx(const struct md5_ctx *ctx, void *resbuf); + + +#ifdef __BIG_ENDIAN__ +# define SWAP(n) \ + (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) +#else +# define SWAP(n) (n) +#endif + + +/* This array contains the bytes used to pad the buffer to the next + 64-byte boundary. (RFC 1321, 3.1: Step 1) */ +static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; + + +/* Initialize structure containing state of computation. + (RFC 1321, 3.3: Step 3) */ +static void md5_init_ctx(struct md5_ctx *ctx) +{ + ctx->A = 0x67452301; + ctx->B = 0xefcdab89; + ctx->C = 0x98badcfe; + ctx->D = 0x10325476; +} + +/* Put result from CTX in first 16 bytes following RESBUF. The result must + be in little endian byte order. */ +static void *md5_read_ctx(const struct md5_ctx *ctx, void *resbuf) +{ + ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A); + ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B); + ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C); + ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D); + + return resbuf; +} + +/* Compute MD5 message digest for bytes read from STREAM. The + resulting message digest number will be written into the 16 bytes + beginning at RESBLOCK. */ +int md5_stream(FILE *stream, void *resblock) +{ + /* Important: BLOCKSIZE must be a multiple of 64. */ +#define BLOCKSIZE 4096 + struct md5_ctx ctx; + md5_uint32 len[2]; + char buffer[BLOCKSIZE + 72]; + size_t pad, sum; + + /* Initialize the computation context. */ + md5_init_ctx (&ctx); + + len[0] = 0; + len[1] = 0; + + /* Iterate over full file contents. */ + while (1) + { + /* We read the file in blocks of BLOCKSIZE bytes. One call of the + computation function processes the whole buffer so that with the + next round of the loop another block can be read. */ + size_t n; + sum = 0; + + /* Read block. Take care for partial reads. */ + do + { + n = fread (buffer, 1, BLOCKSIZE - sum, stream); + + sum += n; + } + while (sum < BLOCKSIZE && n != 0); + if (n == 0 && ferror (stream)) + return 1; + + /* RFC 1321 specifies the possible length of the file up to 2^64 bits. + Here we only compute the number of bytes. Do a double word + increment. */ + len[0] += sum; + if (len[0] < sum) + ++len[1]; + + /* If end of file is reached, end the loop. */ + if (n == 0) + break; + + /* Process buffer with BLOCKSIZE bytes. Note that + BLOCKSIZE % 64 == 0 + */ + md5_process_block (buffer, BLOCKSIZE, &ctx); + } + + /* We can copy 64 byte because the buffer is always big enough. FILLBUF + contains the needed bits. */ + memcpy (&buffer[sum], fillbuf, 64); + + /* Compute amount of padding bytes needed. Alignment is done to + (N + PAD) % 64 == 56 + There is always at least one byte padded. I.e. even the alignment + is correctly aligned 64 padding bytes are added. */ + pad = sum & 63; + pad = pad >= 56 ? 64 + 56 - pad : 56 - pad; + + /* Put the 64-bit file length in *bits* at the end of the buffer. */ + *(md5_uint32 *) &buffer[sum + pad] = SWAP (len[0] << 3); + *(md5_uint32 *) &buffer[sum + pad + 4] = SWAP ((len[1] << 3) + | (len[0] >> 29)); + + /* Process last bytes. */ + md5_process_block (buffer, sum + pad + 8, &ctx); + + /* Construct result in desired memory. */ + md5_read_ctx (&ctx, resblock); + return 0; +} + +/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The + result is always in little endian byte order, so that a byte-wise + output yields to the wanted ASCII representation of the message + digest. */ +void *md5_buffer(const char *buffer, size_t len, void *resblock) +{ + struct md5_ctx ctx; + char restbuf[64 + 72]; + size_t blocks = len & ~63; + size_t pad, rest; + + /* Initialize the computation context. */ + md5_init_ctx (&ctx); + + /* Process whole buffer but last len % 64 bytes. */ + md5_process_block (buffer, blocks, &ctx); + + /* REST bytes are not processed yet. */ + rest = len - blocks; + /* Copy to own buffer. */ + memcpy (restbuf, &buffer[blocks], rest); + /* Append needed fill bytes at end of buffer. We can copy 64 byte + because the buffer is always big enough. */ + memcpy (&restbuf[rest], fillbuf, 64); + + /* PAD bytes are used for padding to correct alignment. Note that + always at least one byte is padded. */ + pad = rest >= 56 ? 64 + 56 - rest : 56 - rest; + + /* Put length of buffer in *bits* in last eight bytes. */ + *(md5_uint32 *) &restbuf[rest + pad] = (md5_uint32) SWAP (len << 3); + *(md5_uint32 *) &restbuf[rest + pad + 4] = (md5_uint32) SWAP (len >> 29); + + /* Process last bytes. */ + md5_process_block (restbuf, rest + pad + 8, &ctx); + + /* Put result in desired memory area. */ + return md5_read_ctx (&ctx, resblock); +} + + +/* These are the four functions used in the four steps of the MD5 algorithm + and defined in the RFC 1321. The first function is a little bit optimized + (as found in Colin Plumbs public domain implementation). */ +/* #define FF(b, c, d) ((b & c) | (~b & d)) */ +#define FF(b, c, d) (d ^ (b & (c ^ d))) +#define FG(b, c, d) FF (d, b, c) +#define FH(b, c, d) (b ^ c ^ d) +#define FI(b, c, d) (c ^ (b | ~d)) + +/* Process LEN bytes of BUFFER, accumulating context into CTX. + It is assumed that LEN % 64 == 0. */ + +void md5_process_block (const void *buffer, size_t len, struct md5_ctx *ctx) +{ + md5_uint32 correct_words[16]; + const md5_uint32 *words = buffer; + size_t nwords = len / sizeof (md5_uint32); + const md5_uint32 *endp = words + nwords; + md5_uint32 A = ctx->A; + md5_uint32 B = ctx->B; + md5_uint32 C = ctx->C; + md5_uint32 D = ctx->D; + + /* Process all bytes in the buffer with 64 bytes in each round of + the loop. */ + while (words < endp) + { + md5_uint32 *cwp = correct_words; + md5_uint32 A_save = A; + md5_uint32 B_save = B; + md5_uint32 C_save = C; + md5_uint32 D_save = D; + + /* First round: using the given function, the context and a constant + the next context is computed. Because the algorithms processing + unit is a 32-bit word and it is determined to work on words in + little endian byte order we perhaps have to change the byte order + before the computation. To reduce the work for the next steps + we store the swapped words in the array CORRECT_WORDS. */ + +#define OP(a, b, c, d, s, T) \ + do \ + { \ + a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \ + ++words; \ + CYCLIC (a, s); \ + a += b; \ + } \ + while (0) + + /* It is unfortunate that C does not provide an operator for + cyclic rotation. Hope the C compiler is smart enough. */ +#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s))) + + /* Before we start, one word to the strange constants. + They are defined in RFC 1321 as + + T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64 + */ + + /* Round 1. */ + OP (A, B, C, D, 7, 0xd76aa478); + OP (D, A, B, C, 12, 0xe8c7b756); + OP (C, D, A, B, 17, 0x242070db); + OP (B, C, D, A, 22, 0xc1bdceee); + OP (A, B, C, D, 7, 0xf57c0faf); + OP (D, A, B, C, 12, 0x4787c62a); + OP (C, D, A, B, 17, 0xa8304613); + OP (B, C, D, A, 22, 0xfd469501); + OP (A, B, C, D, 7, 0x698098d8); + OP (D, A, B, C, 12, 0x8b44f7af); + OP (C, D, A, B, 17, 0xffff5bb1); + OP (B, C, D, A, 22, 0x895cd7be); + OP (A, B, C, D, 7, 0x6b901122); + OP (D, A, B, C, 12, 0xfd987193); + OP (C, D, A, B, 17, 0xa679438e); + OP (B, C, D, A, 22, 0x49b40821); + + /* For the second to fourth round we have the possibly swapped words + in CORRECT_WORDS. Redefine the macro to take an additional first + argument specifying the function to use. */ +#undef OP +#define OP(f, a, b, c, d, k, s, T) \ + do \ + { \ + a += f (b, c, d) + correct_words[k] + T; \ + CYCLIC (a, s); \ + a += b; \ + } \ + while (0) + + /* Round 2. */ + OP (FG, A, B, C, D, 1, 5, 0xf61e2562); + OP (FG, D, A, B, C, 6, 9, 0xc040b340); + OP (FG, C, D, A, B, 11, 14, 0x265e5a51); + OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa); + OP (FG, A, B, C, D, 5, 5, 0xd62f105d); + OP (FG, D, A, B, C, 10, 9, 0x02441453); + OP (FG, C, D, A, B, 15, 14, 0xd8a1e681); + OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8); + OP (FG, A, B, C, D, 9, 5, 0x21e1cde6); + OP (FG, D, A, B, C, 14, 9, 0xc33707d6); + OP (FG, C, D, A, B, 3, 14, 0xf4d50d87); + OP (FG, B, C, D, A, 8, 20, 0x455a14ed); + OP (FG, A, B, C, D, 13, 5, 0xa9e3e905); + OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8); + OP (FG, C, D, A, B, 7, 14, 0x676f02d9); + OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a); + + /* Round 3. */ + OP (FH, A, B, C, D, 5, 4, 0xfffa3942); + OP (FH, D, A, B, C, 8, 11, 0x8771f681); + OP (FH, C, D, A, B, 11, 16, 0x6d9d6122); + OP (FH, B, C, D, A, 14, 23, 0xfde5380c); + OP (FH, A, B, C, D, 1, 4, 0xa4beea44); + OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9); + OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60); + OP (FH, B, C, D, A, 10, 23, 0xbebfbc70); + OP (FH, A, B, C, D, 13, 4, 0x289b7ec6); + OP (FH, D, A, B, C, 0, 11, 0xeaa127fa); + OP (FH, C, D, A, B, 3, 16, 0xd4ef3085); + OP (FH, B, C, D, A, 6, 23, 0x04881d05); + OP (FH, A, B, C, D, 9, 4, 0xd9d4d039); + OP (FH, D, A, B, C, 12, 11, 0xe6db99e5); + OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8); + OP (FH, B, C, D, A, 2, 23, 0xc4ac5665); + + /* Round 4. */ + OP (FI, A, B, C, D, 0, 6, 0xf4292244); + OP (FI, D, A, B, C, 7, 10, 0x432aff97); + OP (FI, C, D, A, B, 14, 15, 0xab9423a7); + OP (FI, B, C, D, A, 5, 21, 0xfc93a039); + OP (FI, A, B, C, D, 12, 6, 0x655b59c3); + OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92); + OP (FI, C, D, A, B, 10, 15, 0xffeff47d); + OP (FI, B, C, D, A, 1, 21, 0x85845dd1); + OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f); + OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0); + OP (FI, C, D, A, B, 6, 15, 0xa3014314); + OP (FI, B, C, D, A, 13, 21, 0x4e0811a1); + OP (FI, A, B, C, D, 4, 6, 0xf7537e82); + OP (FI, D, A, B, C, 11, 10, 0xbd3af235); + OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb); + OP (FI, B, C, D, A, 9, 21, 0xeb86d391); + + /* Add the starting values of the context. */ + A += A_save; + B += B_save; + C += C_save; + D += D_save; + } + + /* Put checksum in context given as argument. */ + ctx->A = A; + ctx->B = B; + ctx->C = C; + ctx->D = D; +} + diff -Nru blender-2.61/source/blender/blenlib/intern/noise.c blender-2.62/source/blender/blenlib/intern/noise.c --- blender-2.61/source/blender/blenlib/intern/noise.c 2011-12-13 19:51:07.000000000 +0000 +++ blender-2.62/source/blender/blenlib/intern/noise.c 2012-02-15 19:35:54.000000000 +0000 @@ -919,10 +919,6 @@ {-0.944031, -0.326599, -0.045624}, }; - - -#define DOT(a,b) (a[0] * b[0] + a[1] * b[1] + a[2] * b[2]) - #define setup(i,b0,b1,r0,r1) \ t = vec[i] + 10000.0f; \ b0 = ((int)t) & 255; \ diff -Nru blender-2.61/source/blender/blenlib/intern/path_util.c blender-2.62/source/blender/blenlib/intern/path_util.c --- blender-2.61/source/blender/blenlib/intern/path_util.c 2011-12-13 19:51:07.000000000 +0000 +++ blender-2.62/source/blender/blenlib/intern/path_util.c 2012-02-15 19:35:54.000000000 +0000 @@ -52,7 +52,7 @@ #include "GHOST_Path-api.h" -#if defined WIN32 && !defined _LIBC +#if defined WIN32 && !defined _LIBC || defined __sun # include "BLI_fnmatch.h" /* use fnmatch included in blenlib */ #else # ifndef _GNU_SOURCE @@ -317,7 +317,7 @@ void BLI_cleanup_path(const char *relabase, char *dir) { - short a; + ptrdiff_t a; char *start, *eind; if (relabase) { BLI_path_abs(dir, relabase); @@ -627,8 +627,10 @@ if (stringframe_chars(path, &ch_sta, &ch_end)) { /* warning, ch_end is the last # +1 */ char tmp[FILE_MAX]; - sprintf(tmp, "%.*s%.*d-%.*d%s", ch_sta, path, ch_end-ch_sta, sta, ch_end-ch_sta, end, path+ch_end); - strcpy(path, tmp); + BLI_snprintf(tmp, sizeof(tmp), + "%.*s%.*d-%.*d%s", + ch_sta, path, ch_end-ch_sta, sta, ch_end-ch_sta, end, path+ch_end); + BLI_strncpy(path, tmp, FILE_MAX); return 1; } return 0; @@ -1416,7 +1418,7 @@ { size_t path_len= strlen(path); size_t ext_len= strlen(ext); - size_t a; + ssize_t a; for(a= path_len - 1; a >= 0; a--) { if (ELEM3(path[a], '.', '/', '\\')) { @@ -1424,7 +1426,7 @@ } } - if (path[a] != '.') { + if ((a < 0) || (path[a] != '.')) { a= path_len; } @@ -1440,7 +1442,7 @@ { size_t path_len= strlen(path); size_t ext_len= strlen(ext); - size_t a; + ssize_t a; /* first check the extension is alread there */ if ( (ext_len <= path_len) && diff -Nru blender-2.61/source/blender/blenlib/intern/rand.c blender-2.62/source/blender/blenlib/intern/rand.c --- blender-2.61/source/blender/blenlib/intern/rand.c 2011-12-13 19:51:07.000000000 +0000 +++ blender-2.62/source/blender/blenlib/intern/rand.c 2012-02-15 19:35:54.000000000 +0000 @@ -78,11 +78,13 @@ MEM_freeN(rng); } -void rng_seed(RNG *rng, unsigned int seed) { +void rng_seed(RNG *rng, unsigned int seed) +{ rng->X= (((r_uint64) seed)<<16) | LOWSEED; } -void rng_srandom(RNG *rng, unsigned int seed) { +void rng_srandom(RNG *rng, unsigned int seed) +{ rng_seed(rng, seed + hash[seed & 255]); seed= rng_getInt(rng); rng_seed(rng, seed + hash[seed & 255]); @@ -90,16 +92,19 @@ rng_seed(rng, seed + hash[seed & 255]); } -int rng_getInt(RNG *rng) { +int rng_getInt(RNG *rng) +{ rng->X= (MULTIPLIER*rng->X + ADDEND)&MASK; return (int) (rng->X>>17); } -double rng_getDouble(RNG *rng) { +double rng_getDouble(RNG *rng) +{ return (double) rng_getInt(rng)/0x80000000; } -float rng_getFloat(RNG *rng) { +float rng_getFloat(RNG *rng) +{ return (float) rng_getInt(rng)/0x80000000; } @@ -135,28 +140,34 @@ static RNG theBLI_rng = {0}; /* note, this one creates periodical patterns */ -void BLI_srand(unsigned int seed) { +void BLI_srand(unsigned int seed) +{ rng_seed(&theBLI_rng, seed); } /* using hash table to create better seed */ -void BLI_srandom(unsigned int seed) { +void BLI_srandom(unsigned int seed) +{ rng_srandom(&theBLI_rng, seed); } -int BLI_rand(void) { +int BLI_rand(void) +{ return rng_getInt(&theBLI_rng); } -double BLI_drand(void) { +double BLI_drand(void) +{ return rng_getDouble(&theBLI_rng); } -float BLI_frand(void) { +float BLI_frand(void) +{ return rng_getFloat(&theBLI_rng); } -void BLI_fillrand(void *addr, int len) { +void BLI_fillrand(void *addr, int len) +{ RNG rng; unsigned char *p= addr; @@ -188,11 +199,13 @@ rng_seed(&rng_tab[thread], seed + hash[seed & 255]); } -int BLI_thread_rand(int thread) { +int BLI_thread_rand(int thread) +{ return rng_getInt(&rng_tab[thread]); } -float BLI_thread_frand(int thread) { +float BLI_thread_frand(int thread) +{ return rng_getFloat(&rng_tab[thread]); } diff -Nru blender-2.61/source/blender/blenlib/intern/storage.c blender-2.62/source/blender/blenlib/intern/storage.c --- blender-2.61/source/blender/blenlib/intern/storage.c 2011-12-13 19:51:07.000000000 +0000 +++ blender-2.62/source/blender/blenlib/intern/storage.c 2012-02-15 19:35:54.000000000 +0000 @@ -54,7 +54,7 @@ #include #endif -#if defined(linux) || defined(__CYGWIN32__) || defined(__hpux) +#if defined(linux) || defined(__CYGWIN32__) || defined(__hpux) || defined(__GNU__) || defined(__GLIBC__) #include #endif @@ -180,7 +180,7 @@ if (slash) slash[1] = 0; } else strcpy(name,"/"); -#if defined (__FreeBSD__) || defined (linux) || defined (__OpenBSD__) || defined (__APPLE__) +#if defined (__FreeBSD__) || defined (linux) || defined (__OpenBSD__) || defined (__APPLE__) || defined(__GNU__) || defined(__GLIBC__) if (statfs(name, &disk)) return(-1); #endif @@ -203,7 +203,7 @@ char buf[256]; DIR *dir; - strcpy(buf,relname); + BLI_strncpy(buf, relname, sizeof(buf)); rellen=strlen(relname); if (rellen){ @@ -220,7 +220,7 @@ while ((fname = (struct dirent*) readdir(dir)) != NULL) { dlink = (struct dirlink *)malloc(sizeof(struct dirlink)); if (dlink){ - strcpy(buf+rellen,fname->d_name); + BLI_strncpy(buf + rellen ,fname->d_name, sizeof(buf) - rellen); dlink->name = BLI_strdup(buf); BLI_addhead(dirbase,dlink); newnum++; @@ -343,8 +343,8 @@ tm= localtime(&file->s.st_mtime); // prevent impossible dates in windows if(tm==NULL) tm= localtime(&zero); - strftime(file->time, 8, "%H:%M", tm); - strftime(file->date, 16, "%d-%b-%y", tm); + strftime(file->time, sizeof(file->time), "%H:%M", tm); + strftime(file->date, sizeof(file->date), "%d-%b-%y", tm); /* * Seems st_size is signed 32-bit value in *nix and Windows. This @@ -354,38 +354,43 @@ st_size= file->s.st_size; if (st_size > 1024*1024*1024) { - sprintf(file->size, "%.2f GB", ((double)st_size)/(1024*1024*1024)); + BLI_snprintf(file->size, sizeof(file->size), "%.2f GB", ((double)st_size)/(1024*1024*1024)); } else if (st_size > 1024*1024) { - sprintf(file->size, "%.1f MB", ((double)st_size)/(1024*1024)); + BLI_snprintf(file->size, sizeof(file->size), "%.1f MB", ((double)st_size)/(1024*1024)); } else if (st_size > 1024) { - sprintf(file->size, "%d KB", (int)(st_size/1024)); + BLI_snprintf(file->size, sizeof(file->size), "%d KB", (int)(st_size/1024)); } else { - sprintf(file->size, "%d B", (int)st_size); + BLI_snprintf(file->size, sizeof(file->size), "%d B", (int)st_size); } - strftime(datum, 32, "%d-%b-%y %H:%M", tm); + strftime(datum, 32, "%d-%b-%y %H:%M", tm); /* XXX, is this used? - campbell */ if (st_size < 1000) { - sprintf(size, "%10d", (int) st_size); - } else if (st_size < 1000 * 1000) { - sprintf(size, "%6d %03d", (int) (st_size / 1000), (int) (st_size % 1000)); - } else if (st_size < 100 * 1000 * 1000) { - sprintf(size, "%2d %03d %03d", (int) (st_size / (1000 * 1000)), (int) ((st_size / 1000) % 1000), (int) ( st_size % 1000)); - } else { - sprintf(size, "> %4.1f M", (double) (st_size / (1024.0 * 1024.0))); - sprintf(size, "%10d", (int) st_size); + BLI_snprintf(size, sizeof(size), "%10d", + (int) st_size); + } + else if (st_size < 1000 * 1000) { + BLI_snprintf(size, sizeof(size), "%6d %03d", + (int) (st_size / 1000), (int) (st_size % 1000)); + } + else if (st_size < 100 * 1000 * 1000) { + BLI_snprintf(size, sizeof(size), "%2d %03d %03d", + (int) (st_size / (1000 * 1000)), (int) ((st_size / 1000) % 1000), (int) ( st_size % 1000)); + } + else { + /* XXX, whats going on here?. 2x calls - campbell */ + BLI_snprintf(size, sizeof(size), "> %4.1f M", (double) (st_size / (1024.0 * 1024.0))); + BLI_snprintf(size, sizeof(size), "%10d", (int) st_size); } - sprintf(buf,"%s %s %s %7s %s %s %10s %s", file->mode1, file->mode2, file->mode3, file->owner, file->date, file->time, size, - file->relname); + BLI_snprintf(buf, sizeof(buf), "%s %s %s %7s %s %s %10s %s", + file->mode1, file->mode2, file->mode3, file->owner, + file->date, file->time, size, file->relname); - file->string=MEM_mallocN(strlen(buf)+1, "filestring"); - if (file->string){ - strcpy(file->string,buf); - } + file->string = BLI_strdup(buf); } } diff -Nru blender-2.61/source/blender/blenlib/intern/winstuff.c blender-2.62/source/blender/blenlib/intern/winstuff.c --- blender-2.61/source/blender/blenlib/intern/winstuff.c 2011-12-13 19:51:07.000000000 +0000 +++ blender-2.62/source/blender/blenlib/intern/winstuff.c 2012-02-15 19:35:54.000000000 +0000 @@ -49,7 +49,8 @@ /* FILE_MAX */ -int BLI_getInstallationDir( char * str ) { +int BLI_getInstallationDir( char * str ) +{ char dir[FILE_MAXDIR]; int a; @@ -73,7 +74,8 @@ TerminateProcess(GetCurrentProcess(),1); } -void RegisterBlendExtension(void) { +void RegisterBlendExtension(void) +{ LONG lresult; HKEY hkey = 0; HKEY root = 0; @@ -167,7 +169,8 @@ TerminateProcess(GetCurrentProcess(),0); } -DIR *opendir (const char *path) { +DIR *opendir (const char *path) +{ if (GetFileAttributes(path) & FILE_ATTRIBUTE_DIRECTORY) { DIR *newd= MEM_mallocN(sizeof(DIR), "opendir"); @@ -185,7 +188,8 @@ } } -struct dirent *readdir(DIR *dp) { +struct dirent *readdir(DIR *dp) +{ if (dp->direntry.d_name) { MEM_freeN(dp->direntry.d_name); dp->direntry.d_name= NULL; @@ -208,7 +212,8 @@ } } -int closedir (DIR *dp) { +int closedir (DIR *dp) +{ if (dp->direntry.d_name) MEM_freeN(dp->direntry.d_name); if (dp->handle!=INVALID_HANDLE_VALUE) FindClose(dp->handle); @@ -217,7 +222,8 @@ return 0; } -void get_default_root(char* root) { +void get_default_root(char* root) +{ char str[MAX_PATH+1]; /* the default drive to resolve a directory without a specified drive diff -Nru blender-2.61/source/blender/blenloader/BLO_readfile.h blender-2.62/source/blender/blenloader/BLO_readfile.h --- blender-2.61/source/blender/blenloader/BLO_readfile.h 2011-12-13 19:50:53.000000000 +0000 +++ blender-2.62/source/blender/blenloader/BLO_readfile.h 2012-02-15 19:35:39.000000000 +0000 @@ -65,7 +65,7 @@ int fileflags; int displaymode; int globalf; - char filename[240]; /* 240 = FILE_MAX */ + char filename[1024]; /* 1024 = FILE_MAX */ struct bScreen* curscreen; struct Scene* curscene; diff -Nru blender-2.61/source/blender/blenloader/BLO_sys_types.h blender-2.62/source/blender/blenloader/BLO_sys_types.h --- blender-2.61/source/blender/blenloader/BLO_sys_types.h 2011-12-13 19:50:53.000000000 +0000 +++ blender-2.62/source/blender/blenloader/BLO_sys_types.h 2012-02-15 19:35:39.000000000 +0000 @@ -86,6 +86,15 @@ /* Linux-i386, Linux-Alpha, Linux-ppc */ #include +/* XXX */ +#ifndef UINT64_MAX +# define UINT64_MAX 18446744073709551615 +typedef uint8_t u_int8_t; +typedef uint16_t u_int16_t; +typedef uint32_t u_int32_t; +typedef uint64_t u_int64_t; +#endif + #elif defined (__APPLE__) #include diff -Nru blender-2.61/source/blender/blenloader/CMakeLists.txt blender-2.62/source/blender/blenloader/CMakeLists.txt --- blender-2.61/source/blender/blenloader/CMakeLists.txt 2011-12-13 19:50:53.000000000 +0000 +++ blender-2.62/source/blender/blenloader/CMakeLists.txt 2012-02-15 19:35:39.000000000 +0000 @@ -32,6 +32,7 @@ ../nodes ../render/extern/include ../../../intern/guardedalloc + ../imbuf ) set(INC_SYS diff -Nru blender-2.61/source/blender/blenloader/intern/readfile.c blender-2.62/source/blender/blenloader/intern/readfile.c --- blender-2.61/source/blender/blenloader/intern/readfile.c 2011-12-13 19:50:53.000000000 +0000 +++ blender-2.62/source/blender/blenloader/intern/readfile.c 2012-02-15 19:35:39.000000000 +0000 @@ -39,6 +39,7 @@ #include // for open #include // for strrchr strncmp strstr #include // for fabs +#include /* for va_start/end */ #ifndef WIN32 #include // for read close @@ -96,9 +97,9 @@ #include "MEM_guardedalloc.h" +#include "BLI_utildefines.h" #include "BLI_blenlib.h" #include "BLI_math.h" -#include "BLI_utildefines.h" #include "BKE_anim.h" #include "BKE_action.h" @@ -134,11 +135,14 @@ #include "BKE_scene.h" #include "BKE_screen.h" #include "BKE_sequencer.h" +#include "BKE_text.h" // for txt_extended_ascii_as_utf8 #include "BKE_texture.h" // for open_plugin_tex #include "BKE_tracking.h" #include "BKE_utildefines.h" // SWITCH_INT DATA ENDB DNA1 O_BINARY GLOB USER TEST REND #include "BKE_sound.h" +#include "IMB_imbuf.h" // for proxy / timecode versioning stuff + #include "NOD_socket.h" //XXX #include "BIF_butspace.h" // badlevel, for do_versions, patching event codes @@ -247,6 +251,31 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb); static void convert_tface_mt(FileData *fd, Main *main); +/* this function ensures that reports are printed, + * in the case of libraray linking errors this is important! + * + * bit kludge but better then doubling up on prints, + * we could alternatively have a versions of a report function which foces printing - campbell + */ +static void BKE_reportf_wrap(ReportList *reports, ReportType type, const char *format, ...) +{ + char fixed_buf[1024]; /* should be long enough */ + + va_list args; + + va_start(args, format); + vsnprintf(fixed_buf, sizeof(fixed_buf), format, args); + va_end(args); + + fixed_buf[sizeof(fixed_buf) - 1] = '\0'; + + BKE_report(reports, type, fixed_buf); + + if(G.background==0) { + printf("%s\n", fixed_buf); + } +} + static OldNewMap *oldnewmap_new(void) { OldNewMap *onm= MEM_callocN(sizeof(*onm), "OldNewMap"); @@ -3678,6 +3707,7 @@ } } +/*this isn't really a public api function, so prototyped here*/ static void direct_link_customdata(FileData *fd, CustomData *data, int count) { int i = 0; @@ -3698,6 +3728,8 @@ i++; } } + + CustomData_update_typemap(data); } static void direct_link_mesh(FileData *fd, Mesh *mesh) @@ -3726,6 +3758,36 @@ direct_link_customdata(fd, &mesh->edata, mesh->totedge); direct_link_customdata(fd, &mesh->fdata, mesh->totface); + +#ifdef USE_BMESH_FORWARD_COMPAT + /* NEVER ENABLE THIS CODE INTO BMESH! + * THIS IS FOR LOADING BMESH INTO OLDER FILES ONLY */ + mesh->mpoly= newdataadr(fd, mesh->mpoly); + mesh->mloop= newdataadr(fd, mesh->mloop); + + direct_link_customdata(fd, &mesh->pdata, mesh->totpoly); + direct_link_customdata(fd, &mesh->ldata, mesh->totloop); + + if (mesh->mpoly) { + /* be clever and load polygons as mfaces */ + + mesh->totface= mesh_mpoly_to_mface(&mesh->fdata, &mesh->ldata, &mesh->pdata, + mesh->totface, mesh->totloop, mesh->totpoly); + + CustomData_free(&mesh->pdata, mesh->totpoly); + memset(&mesh->pdata, 0, sizeof(CustomData)); + mesh->totpoly = 0; + + CustomData_free(&mesh->ldata, mesh->totloop); + memset(&mesh->ldata, 0, sizeof(CustomData)); + mesh->totloop = 0; + + mesh_update_customdata_pointers(mesh); + } + +#endif + + mesh->bb= NULL; mesh->mselect = NULL; mesh->edit_mesh= NULL; @@ -4080,8 +4142,9 @@ ob= ob->id.next; } - if(warn) + if(warn) { BKE_report(fd->reports, RPT_WARNING, "Warning in console"); + } } @@ -4652,7 +4715,7 @@ link_paint(fd, sce, &sce->toolsettings->vpaint->paint); link_paint(fd, sce, &sce->toolsettings->wpaint->paint); link_paint(fd, sce, &sce->toolsettings->imapaint.paint); - + link_paint(fd, sce, &sce->toolsettings->uvsculpt->paint); sce->toolsettings->skgen_template = newlibadr(fd, sce->id.lib, sce->toolsettings->skgen_template); for(base= sce->base.first; base; base= next) { @@ -4662,8 +4725,9 @@ base->object= newlibadr_us(fd, sce->id.lib, base->object); if(base->object==NULL) { - BKE_reportf(fd->reports, RPT_ERROR, "LIB ERROR: Object lost from scene:'%s\'\n", sce->id.name+2); - if(G.background==0) printf("LIB ERROR: base removed from scene:'%s\'\n", sce->id.name+2); + BKE_reportf_wrap(fd->reports, RPT_ERROR, + "LIB ERROR: Object lost from scene:'%s\'\n", + sce->id.name+2); BLI_remlink(&sce->base, base); if(base==sce->basact) sce->basact= NULL; MEM_freeN(base); @@ -4676,7 +4740,7 @@ if(seq->scene) { seq->scene= newlibadr(fd, sce->id.lib, seq->scene); if(seq->scene) { - seq->scene_sound = sound_scene_add_scene_sound(sce, seq, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); + seq->scene_sound = sound_scene_add_scene_sound_defaults(sce, seq); } } if(seq->scene_camera) seq->scene_camera= newlibadr(fd, sce->id.lib, seq->scene_camera); @@ -4688,7 +4752,7 @@ seq->sound= newlibadr(fd, sce->id.lib, seq->sound); if (seq->sound) { seq->sound->id.us++; - seq->scene_sound = sound_add_scene_sound(sce, seq, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); + seq->scene_sound = sound_add_scene_sound_defaults(sce, seq); } } seq->anim= NULL; @@ -4705,8 +4769,8 @@ (void)marker; #endif - if(sce->ed) - seq_update_muting(sce->ed); + seq_update_muting(sce->ed); + seq_update_sound_bounds_all(sce); if(sce->nodetree) { lib_link_ntree(fd, &sce->id, sce->nodetree); @@ -4781,6 +4845,7 @@ direct_link_paint(fd, (Paint**)&sce->toolsettings->sculpt); direct_link_paint(fd, (Paint**)&sce->toolsettings->vpaint); direct_link_paint(fd, (Paint**)&sce->toolsettings->wpaint); + direct_link_paint(fd, (Paint**)&sce->toolsettings->uvsculpt); sce->toolsettings->imapaint.paintcursor= NULL; sce->toolsettings->particle.paintcursor= NULL; @@ -5097,7 +5162,6 @@ } else if(sl->spacetype==SPACE_BUTS) { SpaceButs *sbuts= (SpaceButs *)sl; - sbuts->ri= NULL; sbuts->pinid= newlibadr(fd, sc->id.lib, sbuts->pinid); sbuts->mainbo= sbuts->mainb; sbuts->mainbuser= sbuts->mainb; @@ -5245,6 +5309,30 @@ return NULL; } +static int lib_link_seq_clipboard_cb(Sequence *seq, void *arg_pt) +{ + Main *newmain = (Main *)arg_pt; + + if(seq->sound) { + seq->sound = restore_pointer_by_name(newmain, (ID *)seq->sound, 0); + seq->sound->id.us++; + } + + if(seq->scene) + seq->scene = restore_pointer_by_name(newmain, (ID *)seq->scene, 1); + + if(seq->scene_camera) + seq->scene_camera = restore_pointer_by_name(newmain, (ID *)seq->scene_camera, 1); + + return 1; +} + +static void lib_link_clipboard_restore(Main *newmain) +{ + /* update IDs stored in sequencer clipboard */ + seqbase_recursive_apply(&seqbase_clipboard, lib_link_seq_clipboard_cb, newmain); +} + /* called from kernel/blender.c */ /* used to link a file (without UI) to the current UI */ /* note that it assumes the old pointers in UI are still valid, so old Main is not freed */ @@ -5452,6 +5540,9 @@ sa= sa->next; } } + + /* update IDs stored in all possible clipboards */ + lib_link_clipboard_restore(newmain); } static void direct_link_region(FileData *fd, ARegion *ar, int spacetype) @@ -5763,8 +5854,9 @@ for(newmain= fd->mainlist.first; newmain; newmain= newmain->next) { if(newmain->curlib) { if(BLI_path_cmp(newmain->curlib->filepath, lib->filepath) == 0) { - printf("Fixed error in file; multiple instances of lib:\n %s\n", lib->filepath); - BKE_reportf(fd->reports, RPT_WARNING, "Library '%s', '%s' had multiple instances, save and reload!", lib->name, lib->filepath); + BKE_reportf_wrap(fd->reports, RPT_WARNING, + "Library '%s', '%s' had multiple instances, save and reload!", + lib->name, lib->filepath); change_idid_adr(&fd->mainlist, fd, lib, newmain->curlib); // change_idid_adr_fd(fd, lib, newmain->curlib); @@ -5934,10 +6026,29 @@ /* ***************** READ MOVIECLIP *************** */ +static void direct_link_movieReconstruction(FileData *fd, MovieTrackingReconstruction *reconstruction) +{ + reconstruction->cameras= newdataadr(fd, reconstruction->cameras); +} + +static void direct_link_movieTracks(FileData *fd, ListBase *tracksbase) +{ + MovieTrackingTrack *track; + + link_list(fd, tracksbase); + + track= tracksbase->first; + while(track) { + track->markers= newdataadr(fd, track->markers); + + track= track->next; + } +} + static void direct_link_movieclip(FileData *fd, MovieClip *clip) { MovieTracking *tracking= &clip->tracking; - MovieTrackingTrack *track; + MovieTrackingObject *object; if(fd->movieclipmap) clip->cache= newmclipadr(fd, clip->cache); else clip->cache= NULL; @@ -5945,16 +6056,8 @@ if(fd->movieclipmap) clip->tracking.camera.intrinsics= newmclipadr(fd, clip->tracking.camera.intrinsics); else clip->tracking.camera.intrinsics= NULL; - tracking->reconstruction.cameras= newdataadr(fd, tracking->reconstruction.cameras); - - link_list(fd, &tracking->tracks); - - track= tracking->tracks.first; - while(track) { - track->markers= newdataadr(fd, track->markers); - - track= track->next; - } + direct_link_movieTracks(fd, &tracking->tracks); + direct_link_movieReconstruction(fd, &tracking->reconstruction); clip->tracking.act_track= newdataadr(fd, clip->tracking.act_track); @@ -5965,6 +6068,16 @@ clip->tracking.stabilization.ok= 0; clip->tracking.stabilization.scaleibuf= NULL; clip->tracking.stabilization.rot_track= newdataadr(fd, clip->tracking.stabilization.rot_track); + + link_list(fd, &tracking->objects); + + object= tracking->objects.first; + while(object) { + direct_link_movieTracks(fd, &object->tracks); + direct_link_movieReconstruction(fd, &object->reconstruction); + + object= object->next; + } } static void lib_link_movieclip(FileData *fd, Main *main) @@ -6475,14 +6588,14 @@ if (layer->type == CD_MTFACE) { if (layer->name[0] == 0) { if (mtfacen == 0) strcpy(layer->name, "UVMap"); - else sprintf(layer->name, "UVMap.%.3d", mtfacen); + else BLI_snprintf(layer->name, sizeof(layer->name), "UVMap.%.3d", mtfacen); } mtfacen++; } else if (layer->type == CD_MCOL) { if (layer->name[0] == 0) { if (mcoln == 0) strcpy(layer->name, "Col"); - else sprintf(layer->name, "Col.%.3d", mcoln); + else BLI_snprintf(layer->name, sizeof(layer->name), "Col.%.3d", mcoln); } mcoln++; } @@ -7438,6 +7551,56 @@ } +/* socket use flags were only temporary before */ +static void do_versions_nodetree_socket_use_flags_2_62(bNodeTree *ntree) +{ + bNode *node; + bNodeSocket *sock; + bNodeLink *link; + + for (node=ntree->nodes.first; node; node=node->next) { + for (sock=node->inputs.first; sock; sock=sock->next) + sock->flag &= ~SOCK_IN_USE; + for (sock=node->outputs.first; sock; sock=sock->next) + sock->flag &= ~SOCK_IN_USE; + } + for (sock=ntree->inputs.first; sock; sock=sock->next) + sock->flag &= ~SOCK_IN_USE; + for (sock=ntree->outputs.first; sock; sock=sock->next) + sock->flag &= ~SOCK_IN_USE; + + for (link=ntree->links.first; link; link=link->next) { + link->fromsock->flag |= SOCK_IN_USE; + link->tosock->flag |= SOCK_IN_USE; + } +} + +/* set the SOCK_AUTO_HIDDEN flag on collapsed nodes */ +static void do_versions_nodetree_socket_auto_hidden_flags_2_62(bNodeTree *ntree) +{ + bNode *node; + bNodeSocket *sock; + + for (node=ntree->nodes.first; node; node=node->next) { + if (node->flag & NODE_HIDDEN) { + for (sock=node->inputs.first; sock; sock=sock->next) { + if (sock->link==NULL) + sock->flag |= SOCK_AUTO_HIDDEN; + } + for(sock=node->outputs.first; sock; sock= sock->next) { + if(nodeCountSocketLinks(ntree, sock)==0) + sock->flag |= SOCK_AUTO_HIDDEN; + } + } + else { + for(sock=node->inputs.first; sock; sock= sock->next) + sock->flag &= ~SOCK_AUTO_HIDDEN; + for(sock=node->outputs.first; sock; sock= sock->next) + sock->flag &= ~SOCK_AUTO_HIDDEN; + } + } +} + static void do_versions(FileData *fd, Library *lib, Main *main) { /* WATCH IT!!!: pointers from libdata have not been converted */ @@ -8725,9 +8888,9 @@ } if(ob->soft && ob->soft->vertgroup==0) { bDeformGroup *locGroup = defgroup_find_name(ob, "SOFTGOAL"); - if(locGroup){ + if (locGroup) { /* retrieve index for that group */ - ob->soft->vertgroup = 1 + defgroup_find_index(ob, locGroup); + ob->soft->vertgroup = 1 + BLI_findindex(&ob->defbase, locGroup); } } } @@ -8927,8 +9090,9 @@ strcpy(kb->name, "Basis"); } else { - if(kb->name[0]==0) - sprintf(kb->name, "Key %d", index); + if (kb->name[0]==0) { + BLI_snprintf(kb->name, sizeof(kb->name), "Key %d", index); + } kb->adrcode= index++; } } @@ -9921,7 +10085,7 @@ BLI_addtail(&ob->particlesystem, psys); md= modifier_new(eModifierType_ParticleSystem); - sprintf(md->name, "ParticleSystem %i", BLI_countlist(&ob->particlesystem)); + BLI_snprintf(md->name, sizeof(md->name), "ParticleSystem %i", BLI_countlist(&ob->particlesystem)); psmd= (ParticleSystemModifierData*) md; psmd->psys=psys; BLI_addtail(&ob->modifiers, md); @@ -10665,8 +10829,11 @@ void *olddata = ob->data; ob->data = me; - if(me && me->id.lib==NULL && me->mr && me->mr->level_count > 1) /* XXX - library meshes crash on loading most yoFrankie levels, the multires pointer gets invalid - Campbell */ + /* XXX - library meshes crash on loading most yoFrankie levels, + * the multires pointer gets invalid - Campbell */ + if(me && me->id.lib==NULL && me->mr && me->mr->level_count > 1) { multires_load_old(ob, me); + } ob->data = olddata; } @@ -10765,7 +10932,7 @@ sce->gm.dome.warptext = sce->r.dometext; //Stand Alone - sce->gm.fullscreen = sce->r.fullscreen; + sce->gm.playerflag |= (sce->r.fullscreen?GAME_PLAYER_FULLSCREEN:0); sce->gm.xplay = sce->r.xplay; sce->gm.yplay = sce->r.yplay; sce->gm.freqplay = sce->r.freqplay; @@ -12564,10 +12731,12 @@ clip->aspy= 1.0f; } - /* XXX: a bit hacky, probably include imbuf and use real constants are nicer */ - clip->proxy.build_tc_flag= 7; + clip->proxy.build_tc_flag= IMB_TC_RECORD_RUN | + IMB_TC_FREE_RUN | + IMB_TC_INTERPOLATED_REC_DATE_FREE_RUN; + if(clip->proxy.build_size_flag==0) - clip->proxy.build_size_flag= 1; + clip->proxy.build_size_flag= IMB_PROXY_25; if(clip->proxy.quality==0) clip->proxy.quality= 90; @@ -12665,9 +12834,249 @@ } } - /* put compatibility code here until next subversion bump */ + if (main->versionfile < 261 || (main->versionfile == 261 && main->subversionfile < 1)) + { + { + /* update use flags for node sockets (was only temporary before) */ + Scene *sce; + Material *mat; + Tex *tex; + Lamp *lamp; + World *world; + bNodeTree *ntree; + + for (sce=main->scene.first; sce; sce=sce->id.next) + if (sce->nodetree) + do_versions_nodetree_socket_use_flags_2_62(sce->nodetree); + + for (mat=main->mat.first; mat; mat=mat->id.next) + if (mat->nodetree) + do_versions_nodetree_socket_use_flags_2_62(mat->nodetree); + + for (tex=main->tex.first; tex; tex=tex->id.next) + if (tex->nodetree) + do_versions_nodetree_socket_use_flags_2_62(tex->nodetree); + + for (lamp=main->lamp.first; lamp; lamp=lamp->id.next) + if (lamp->nodetree) + do_versions_nodetree_socket_use_flags_2_62(lamp->nodetree); + + for (world=main->world.first; world; world=world->id.next) + if (world->nodetree) + do_versions_nodetree_socket_use_flags_2_62(world->nodetree); + + for (ntree=main->nodetree.first; ntree; ntree=ntree->id.next) + do_versions_nodetree_socket_use_flags_2_62(ntree); + } + { + /* Initialize BGE exit key to esc key */ + Scene *scene; + for(scene= main->scene.first; scene; scene= scene->id.next) { + if (!scene->gm.exitkey) + scene->gm.exitkey = 218; // Blender key code for ESC + } + } + { + MovieClip *clip; + Object *ob; + + for (clip= main->movieclip.first; clip; clip= clip->id.next) { + MovieTracking *tracking= &clip->tracking; + MovieTrackingObject *tracking_object= tracking->objects.first; + + clip->proxy.build_tc_flag|= IMB_TC_RECORD_RUN_NO_GAPS; + + if(!tracking->settings.object_distance) + tracking->settings.object_distance= 1.0f; + + if(tracking->objects.first == NULL) + BKE_tracking_new_object(tracking, "Camera"); + + while(tracking_object) { + if(!tracking_object->scale) + tracking_object->scale= 1.0f; + + tracking_object= tracking_object->next; + } + } + + for (ob= main->object.first; ob; ob= ob->id.next) { + bConstraint *con; + for (con= ob->constraints.first; con; con=con->next) { + bConstraintTypeInfo *cti= constraint_get_typeinfo(con); + + if(!cti) + continue; + + if(cti->type==CONSTRAINT_TYPE_OBJECTSOLVER) { + bObjectSolverConstraint *data= (bObjectSolverConstraint *)con->data; + + if(data->invmat[3][3]==0.0f) + unit_m4(data->invmat); + } + } + } + } + { + /* Warn the user if he is using ["Text"] properties for Font objects */ + Object *ob; + bProperty *prop; + + for (ob= main->object.first; ob; ob= ob->id.next) { + if (ob->type == OB_FONT) { + prop = get_ob_property(ob, "Text"); + if (prop) { + BKE_reportf_wrap(fd->reports, RPT_WARNING, + "Game property name conflict in object: \"%s\".\nText objects reserve the " + "[\"Text\"] game property to change their content through Logic Bricks.\n", + ob->id.name+2); + } + } + } + } + { + /* set the SOCK_AUTO_HIDDEN flag on collapsed nodes */ + Scene *sce; + Material *mat; + Tex *tex; + Lamp *lamp; + World *world; + bNodeTree *ntree; + + for (sce=main->scene.first; sce; sce=sce->id.next) + if (sce->nodetree) + do_versions_nodetree_socket_auto_hidden_flags_2_62(sce->nodetree); + + for (mat=main->mat.first; mat; mat=mat->id.next) + if (mat->nodetree) + do_versions_nodetree_socket_auto_hidden_flags_2_62(mat->nodetree); + + for (tex=main->tex.first; tex; tex=tex->id.next) + if (tex->nodetree) + do_versions_nodetree_socket_auto_hidden_flags_2_62(tex->nodetree); + + for (lamp=main->lamp.first; lamp; lamp=lamp->id.next) + if (lamp->nodetree) + do_versions_nodetree_socket_auto_hidden_flags_2_62(lamp->nodetree); + + for (world=main->world.first; world; world=world->id.next) + if (world->nodetree) + do_versions_nodetree_socket_auto_hidden_flags_2_62(world->nodetree); + + for (ntree=main->nodetree.first; ntree; ntree=ntree->id.next) + do_versions_nodetree_socket_auto_hidden_flags_2_62(ntree); + } + } + + if (main->versionfile < 261 || (main->versionfile == 261 && main->subversionfile < 2)) + { + { + /* convert Camera Actuator values to defines */ + Object *ob; + bActuator *act; + for(ob = main->object.first; ob; ob= ob->id.next) { + for(act= ob->actuators.first; act; act= act->next) { + if (act->type == ACT_CAMERA) { + bCameraActuator *ba= act->data; + + if(ba->axis==(float) 'x') ba->axis=OB_POSX; + else if (ba->axis==(float)'y') ba->axis=OB_POSY; + /* don't do an if/else to avoid imediate subversion bump*/ +// ba->axis=((ba->axis == (float) 'x')?OB_POSX_X:OB_POSY); + } + } + } + } + + { + /* convert deprecated sculpt_paint_unified_* fields to + UnifiedPaintSettings */ + Scene *scene; + for(scene= main->scene.first; scene; scene= scene->id.next) { + ToolSettings *ts= scene->toolsettings; + UnifiedPaintSettings *ups= &ts->unified_paint_settings; + ups->size= ts->sculpt_paint_unified_size; + ups->unprojected_radius= ts->sculpt_paint_unified_unprojected_radius; + ups->alpha= ts->sculpt_paint_unified_alpha; + ups->flag= ts->sculpt_paint_settings; + } + } + } + + if (main->versionfile < 261 || (main->versionfile == 261 && main->subversionfile < 3)) + { + { + /* convert extended ascii to utf-8 for text editor */ + Text *text; + for (text= main->text.first; text; text= text->id.next) + if(!(text->flags & TXT_ISEXT)) { + TextLine *tl; + + for (tl= text->lines.first; tl; tl= tl->next) { + int added= txt_extended_ascii_as_utf8(&tl->line); + tl->len+= added; + + /* reset cursor position if line was changed */ + if (added && tl == text->curl) + text->curc = 0; + } + } + } + { + /* set new dynamic paint values */ + Object *ob; + for(ob = main->object.first; ob; ob = ob->id.next) { + ModifierData *md; + for(md= ob->modifiers.first; md; md= md->next) { + if (md->type == eModifierType_DynamicPaint) { + DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md; + if(pmd->canvas) + { + DynamicPaintSurface *surface = pmd->canvas->surfaces.first; + for (; surface; surface=surface->next) { + surface->color_dry_threshold = 1.0f; + surface->influence_scale = 1.0f; + surface->radius_scale = 1.0f; + surface->flags |= MOD_DPAINT_USE_DRYING; + } + } + } + } + } + } + } + + if (main->versionfile < 261 || (main->versionfile == 261 && main->subversionfile < 4)) + { + { + /* set fluidsim rate */ + Object *ob; + for (ob = main->object.first; ob; ob = ob->id.next) { + ModifierData *md; + for (md = ob->modifiers.first; md; md = md->next) { + if (md->type == eModifierType_Fluidsim) { + FluidsimSettings *fss = (FluidsimSettings *)md; + fss->animRate = 1.0f; + } + } + } + } + } + + if (main->versionfile < 262) { - /* nothing! */ + Object *ob; + for(ob=main->object.first; ob; ob= ob->id.next) { + ModifierData *md; + + for (md=ob->modifiers.first; md; md=md->next) { + if (md->type==eModifierType_Cloth) { + ClothModifierData *clmd = (ClothModifierData*) md; + if(clmd->sim_parms) + clmd->sim_parms->vel_damping = 1.0f; + } + } + } } /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ @@ -14120,15 +14529,16 @@ if(fd==NULL) { /* printf and reports for now... its important users know this */ - BKE_reportf(basefd->reports, RPT_INFO, "read library: '%s', '%s'\n", mainptr->curlib->filepath, mainptr->curlib->name); - if(!G.background && basefd->reports) printf("read library: '%s', '%s'\n", mainptr->curlib->filepath, mainptr->curlib->name); + BKE_reportf_wrap(basefd->reports, RPT_INFO, + "read library: '%s', '%s'\n", + mainptr->curlib->filepath, mainptr->curlib->name); fd= blo_openblenderfile(mainptr->curlib->filepath, basefd->reports); /* allow typing in a new lib path */ if(G.rt==-666) { while(fd==NULL) { - char newlib_path[240] = { 0 }; + char newlib_path[FILE_MAX] = { 0 }; printf("Missing library...'\n"); printf(" current file: %s\n", G.main->name); printf(" absolute lib: %s\n", mainptr->curlib->filepath); @@ -14166,8 +14576,9 @@ else mainptr->curlib->filedata= NULL; if (fd==NULL) { - BKE_reportf(basefd->reports, RPT_ERROR, "Can't find lib '%s'\n", mainptr->curlib->filepath); - if(!G.background && basefd->reports) printf("ERROR: can't find lib %s \n", mainptr->curlib->filepath); + BKE_reportf_wrap(basefd->reports, RPT_ERROR, + "Can't find lib '%s'\n", + mainptr->curlib->filepath); } } if(fd) { @@ -14184,8 +14595,10 @@ append_id_part(fd, mainptr, id, &realid); if (!realid) { - BKE_reportf(fd->reports, RPT_ERROR, "LIB ERROR: %s:'%s' missing from '%s'\n", BKE_idcode_to_name(GS(id->name)), id->name+2, mainptr->curlib->filepath); - if(!G.background && basefd->reports) printf("LIB ERROR: %s:'%s' missing from '%s'\n", BKE_idcode_to_name(GS(id->name)), id->name+2, mainptr->curlib->filepath); + BKE_reportf_wrap(fd->reports, RPT_ERROR, + "LIB ERROR: %s:'%s' missing from '%s'\n", + BKE_idcode_to_name(GS(id->name)), + id->name+2, mainptr->curlib->filepath); } change_idid_adr(mainlist, basefd, id, realid); @@ -14198,7 +14611,8 @@ expand_main(fd, mainptr); - /* dang FileData... now new libraries need to be appended to original filedata, it is not a good replacement for the old global (ton) */ + /* dang FileData... now new libraries need to be appended to original filedata, + * it is not a good replacement for the old global (ton) */ while( fd->mainlist.first ) { Main *mp= fd->mainlist.first; BLI_remlink(&fd->mainlist, mp); @@ -14220,8 +14634,9 @@ ID *idn= id->next; if(id->flag & LIB_READ) { BLI_remlink(lbarray[a], id); - BKE_reportf(basefd->reports, RPT_ERROR, "LIB ERROR: %s:'%s' unread libblock missing from '%s'\n", BKE_idcode_to_name(GS(id->name)), id->name+2, mainptr->curlib->filepath); - if(!G.background && basefd->reports)printf("LIB ERROR: %s:'%s' unread libblock missing from '%s'\n", BKE_idcode_to_name(GS(id->name)), id->name+2, mainptr->curlib->filepath); + BKE_reportf_wrap(basefd->reports, RPT_ERROR, + "LIB ERROR: %s:'%s' unread libblock missing from '%s'\n", + BKE_idcode_to_name(GS(id->name)), id->name+2, mainptr->curlib->filepath); change_idid_adr(mainlist, basefd, id, NULL); MEM_freeN(id); diff -Nru blender-2.61/source/blender/blenloader/intern/writefile.c blender-2.62/source/blender/blenloader/intern/writefile.c --- blender-2.61/source/blender/blenloader/intern/writefile.c 2011-12-13 19:50:53.000000000 +0000 +++ blender-2.62/source/blender/blenloader/intern/writefile.c 2012-02-15 19:35:39.000000000 +0000 @@ -89,6 +89,9 @@ #include "BLI_winstuff.h" #endif +/* allow writefile to use deprecated functionality (for forward compatibility code) */ +#define DNA_DEPRECATED_ALLOW + #include "DNA_anim_types.h" #include "DNA_armature_types.h" #include "DNA_actuator_types.h" @@ -174,6 +177,10 @@ MemFile *compare, *current; int tot, count, error, memsize; + +#ifdef USE_BMESH_SAVE_AS_COMPAT + char use_mesh_compat; /* option to save with older mesh format */ +#endif } WriteData; static WriteData *writedata_new(int file) @@ -649,7 +656,7 @@ /* forward compatibility code, so older blenders still open */ sock->stack_type = 1; - + if(sock->default_value) { bNodeSocketValueFloat *valfloat; bNodeSocketValueVector *valvector; @@ -1959,6 +1966,9 @@ if(tos->sculpt) { writestruct(wd, DATA, "Sculpt", 1, tos->sculpt); } + if(tos->uvsculpt) { + writestruct(wd, DATA, "UvSculpt", 1, tos->uvsculpt); + } // write_paint(wd, &tos->imapaint.paint); @@ -2522,6 +2532,27 @@ } } +static void write_movieTracks(WriteData *wd, ListBase *tracks) +{ + MovieTrackingTrack *track; + + track= tracks->first; + while(track) { + writestruct(wd, DATA, "MovieTrackingTrack", 1, track); + + if(track->markers) + writestruct(wd, DATA, "MovieTrackingMarker", track->markersnr, track->markers); + + track= track->next; + } +} + +static void write_movieReconstruction(WriteData *wd, MovieTrackingReconstruction *reconstruction) +{ + if(reconstruction->camnr) + writestruct(wd, DATA, "MovieReconstructedCamera", reconstruction->camnr, reconstruction->cameras); +} + static void write_movieclips(WriteData *wd, ListBase *idbase) { MovieClip *clip; @@ -2530,20 +2561,20 @@ while(clip) { if(clip->id.us>0 || wd->current) { MovieTracking *tracking= &clip->tracking; - MovieTrackingTrack *track; + MovieTrackingObject *object; writestruct(wd, ID_MC, "MovieClip", 1, clip); - if(tracking->reconstruction.camnr) - writestruct(wd, DATA, "MovieReconstructedCamera", tracking->reconstruction.camnr, tracking->reconstruction.cameras); + write_movieTracks(wd, &tracking->tracks); + write_movieReconstruction(wd, &tracking->reconstruction); - track= tracking->tracks.first; - while(track) { - writestruct(wd, DATA, "MovieTrackingTrack", 1, track); + object= tracking->objects.first; + while(object) { + writestruct(wd, DATA, "MovieTrackingObject", 1, object); - if(track->markers) - writestruct(wd, DATA, "MovieTrackingMarker", track->markersnr, track->markers); + write_movieTracks(wd, &object->tracks); + write_movieReconstruction(wd, &object->reconstruction); - track= track->next; + object= object->next; } } @@ -2574,7 +2605,10 @@ fg.curscene= screen->scene; fg.displaymode= G.displaymode; fg.winpos= G.winpos; - fg.fileflags= (fileflags & ~(G_FILE_NO_UI|G_FILE_RELATIVE_REMAP)); // prevent to save this, is not good convention, and feature with concerns... + + /* prevent to save this, is not good convention, and feature with concerns... */ + fg.fileflags= (fileflags & ~(G_FILE_NO_UI|G_FILE_RELATIVE_REMAP|G_FILE_MESH_COMPAT)); + fg.globalf= G.f; BLI_strncpy(fg.filename, mainvar->name, sizeof(fg.filename)); @@ -2617,7 +2651,11 @@ blo_split_main(&mainlist, mainvar); wd= bgnwrite(handle, compare, current); - + +#ifdef USE_BMESH_SAVE_AS_COMPAT + wd->use_mesh_compat = (write_flags & G_FILE_MESH_COMPAT) != 0; +#endif + sprintf(buf, "BLENDER%c%c%.3d", (sizeof(void*)==8)?'-':'_', (ENDIAN_ORDER==B_ENDIAN)?'V':'v', BLENDER_VERSION); mywrite(wd, buf, 12); diff -Nru blender-2.61/source/blender/blenloader/SConscript blender-2.62/source/blender/blenloader/SConscript --- blender-2.61/source/blender/blenloader/SConscript 2011-12-13 19:50:53.000000000 +0000 +++ blender-2.62/source/blender/blenloader/SConscript 2012-02-15 19:35:39.000000000 +0000 @@ -5,7 +5,7 @@ incs = '. #/intern/guardedalloc ../blenlib ../blenkernel' incs += ' ../makesdna ../editors/include' -incs += ' ../render/extern/include ../makesrna ../nodes' +incs += ' ../render/extern/include ../makesrna ../nodes ../imbuf' incs += ' ' + env['BF_ZLIB_INC'] diff -Nru blender-2.61/source/blender/blenpluginapi/iff.h blender-2.62/source/blender/blenpluginapi/iff.h --- blender-2.61/source/blender/blenpluginapi/iff.h 2011-12-13 19:49:46.000000000 +0000 +++ blender-2.62/source/blender/blenpluginapi/iff.h 2012-02-15 19:34:32.000000000 +0000 @@ -63,7 +63,7 @@ int channels; /**< amount of channels in rect_float (0 = 4 channel default) */ float dither; /**< random dither value, for conversion from float -> byte rect */ short profile; /** color space/profile preset that the byte rect buffer represents */ - char profile_filename[256]; /** to be implemented properly, specific filename for custom profiles */ + char profile_filename[1024]; /** to be implemented properly, specific filename for custom profiles */ /* mipmapping */ struct ImBuf *mipmap[IB_MIPMAP_LEVELS]; /**< MipMap levels, a series of halved images */ diff -Nru blender-2.61/source/blender/collada/AnimationExporter.cpp blender-2.62/source/blender/collada/AnimationExporter.cpp --- blender-2.61/source/blender/collada/AnimationExporter.cpp 2011-12-13 19:50:01.000000000 +0000 +++ blender-2.62/source/blender/collada/AnimationExporter.cpp 2012-02-15 19:34:46.000000000 +0000 @@ -767,12 +767,33 @@ // compute bone local mat if (bone->parent) { invert_m4_m4(ipar, parchan->pose_mat); - mul_m4_m4m4(mat, pchan->pose_mat, ipar); + mult_m4_m4m4(mat, ipar, pchan->pose_mat); } else copy_m4_m4(mat, pchan->pose_mat); UnitConverter converter; + // SECOND_LIFE_COMPATIBILITY + // AFAIK animation to second life is via BVH, but no + // reason to not have the collada-animation be correct + if(export_settings->second_life) + { + float temp[4][4]; + copy_m4_m4(temp, bone->arm_mat); + temp[3][0] = temp[3][1] = temp[3][2] = 0.0f; + invert_m4(temp); + + mult_m4_m4m4(mat, mat, temp); + + if(bone->parent) + { + copy_m4_m4(temp, bone->parent->arm_mat); + temp[3][0] = temp[3][1] = temp[3][2] = 0.0f; + + mult_m4_m4m4(mat, temp, mat); + } + } + float outmat[4][4]; converter.mat4_to_dae(outmat,mat); @@ -1274,7 +1295,7 @@ // compute bone local mat if (bone->parent) { invert_m4_m4(ipar, parchan->pose_mat); - mul_m4_m4m4(mat, pchan->pose_mat, ipar); + mult_m4_m4m4(mat, ipar, pchan->pose_mat); } else copy_m4_m4(mat, pchan->pose_mat); diff -Nru blender-2.61/source/blender/collada/AnimationExporter.h blender-2.62/source/blender/collada/AnimationExporter.h --- blender-2.61/source/blender/collada/AnimationExporter.h 2011-12-13 19:50:01.000000000 +0000 +++ blender-2.62/source/blender/collada/AnimationExporter.h 2012-02-15 19:34:46.000000000 +0000 @@ -83,7 +83,9 @@ public: - AnimationExporter(COLLADASW::StreamWriter *sw): COLLADASW::LibraryAnimations(sw) { this->sw = sw; } + AnimationExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings): + COLLADASW::LibraryAnimations(sw), export_settings(export_settings) + { this->sw = sw; } void exportAnimations(Scene *sce); @@ -92,6 +94,7 @@ void operator() (Object *ob); protected: + const ExportSettings *export_settings; void dae_animation(Object* ob, FCurve *fcu, char* transformName , bool is_param, Material *ma = NULL); diff -Nru blender-2.61/source/blender/collada/AnimationImporter.cpp blender-2.62/source/blender/collada/AnimationImporter.cpp --- blender-2.61/source/blender/collada/AnimationImporter.cpp 2011-12-13 19:50:01.000000000 +0000 +++ blender-2.62/source/blender/collada/AnimationImporter.cpp 2012-02-15 19:34:46.000000000 +0000 @@ -723,7 +723,7 @@ // calc M calc_joint_parent_mat_rest(par, NULL, root, node); - mul_m4_m4m4(temp, matfra, par); + mult_m4_m4m4(temp, par, matfra); // evaluate_joint_world_transform_at_frame(temp, NULL, , node, fra); @@ -1276,7 +1276,7 @@ // calc M calc_joint_parent_mat_rest(par, NULL, root, node); - mul_m4_m4m4(temp, matfra, par); + mult_m4_m4m4(temp, par, matfra); // evaluate_joint_world_transform_at_frame(temp, NULL, , node, fra); @@ -1434,7 +1434,7 @@ float temp[4][4]; copy_m4_m4(temp, mat); - mul_m4_m4m4(mat, m, temp); + mult_m4_m4m4(mat, temp, m); } } @@ -1597,7 +1597,7 @@ calc_joint_parent_mat_rest(par, NULL, root, node); get_node_mat(m, node, NULL, NULL); - mul_m4_m4m4(mat, m, par); + mult_m4_m4m4(mat, par, m); } } @@ -1616,7 +1616,7 @@ if (par) { float temp[4][4]; get_node_mat(temp, node, NULL, NULL); - mul_m4_m4m4(m, temp, par); + mult_m4_m4m4(m, par, temp); } else { get_node_mat(m, node, NULL, NULL); @@ -1656,7 +1656,7 @@ float temp[4][4], ipar[4][4]; invert_m4_m4(ipar, par_job->obmat); copy_m4_m4(temp, mat); - mul_m4_m4m4(mat, temp, ipar); + mult_m4_m4m4(mat, ipar, temp); } TransformBase::decompose(mat, job->loc, NULL, job->quat, job->size); @@ -1689,7 +1689,7 @@ if (par) { float temp[4][4]; evaluate_transform_at_frame(temp, node, node == end ? fra : 0.0f); - mul_m4_m4m4(m, temp, par); + mult_m4_m4m4(m, par, temp); } else { evaluate_transform_at_frame(m, node, node == end ? fra : 0.0f); diff -Nru blender-2.61/source/blender/collada/ArmatureExporter.cpp blender-2.62/source/blender/collada/ArmatureExporter.cpp --- blender-2.61/source/blender/collada/ArmatureExporter.cpp 2011-12-13 19:50:01.000000000 +0000 +++ blender-2.62/source/blender/collada/ArmatureExporter.cpp 2012-02-15 19:34:46.000000000 +0000 @@ -218,11 +218,34 @@ float invpar[4][4]; invert_m4_m4(invpar, parchan->pose_mat); - mul_m4_m4m4(mat, pchan->pose_mat, invpar); + mult_m4_m4m4(mat, invpar, pchan->pose_mat); } else { - // get world-space from armature-space - mul_m4_m4m4(mat, pchan->pose_mat, ob_arm->obmat); + copy_m4_m4(mat, pchan->pose_mat); + // Why? Joint's localspace is still it's parent node + //get world-space from armature-space + //mult_m4_m4m4(mat, ob_arm->obmat, pchan->pose_mat); + } + + // SECOND_LIFE_COMPATIBILITY + if(export_settings->second_life) + { + // Remove rotations vs armature from transform + // parent_rest_rot * mat * irest_rot + float temp[4][4]; + copy_m4_m4(temp, bone->arm_mat); + temp[3][0] = temp[3][1] = temp[3][2] = 0.0f; + invert_m4(temp); + + mult_m4_m4m4(mat, mat, temp); + + if(bone->parent) + { + copy_m4_m4(temp, bone->parent->arm_mat); + temp[3][0] = temp[3][1] = temp[3][2] = 0.0f; + + mult_m4_m4m4(mat, temp, mat); + } } TransformWriter::add_node_transform(node, mat,NULL ); @@ -341,10 +364,16 @@ { std::string source_id = controller_id + BIND_POSES_SOURCE_ID_SUFFIX; + int totjoint = 0; + for (bDeformGroup *def = (bDeformGroup*)defbase->first; def; def = def->next) { + if (is_bone_defgroup(ob_arm, def)) + totjoint++; + } + COLLADASW::FloatSourceF source(mSW); source.setId(source_id); source.setArrayId(source_id + ARRAY_ID_SUFFIX); - source.setAccessorCount(BLI_countlist(defbase)); + source.setAccessorCount(totjoint); //BLI_countlist(defbase)); source.setAccessorStride(16); source.setParameterTypeName(&COLLADASW::CSWC::CSW_VALUE_TYPE_FLOAT4x4); @@ -366,16 +395,27 @@ for (bDeformGroup *def = (bDeformGroup*)defbase->first; def; def = def->next) { if (is_bone_defgroup(ob_arm, def)) { - bPoseChannel *pchan = get_pose_channel(pose, def->name); float mat[4][4]; float world[4][4]; float inv_bind_mat[4][4]; - // make world-space matrix, arm_mat is armature-space - mul_m4_m4m4(world, pchan->bone->arm_mat, ob_arm->obmat); - + // SECOND_LIFE_COMPATIBILITY + if(export_settings->second_life) + { + // Only translations, no rotation vs armature + float temp[4][4]; + unit_m4(temp); + copy_v3_v3(temp[3], pchan->bone->arm_mat[3]); + mult_m4_m4m4(world, ob_arm->obmat, temp); + } + else + { + // make world-space matrix, arm_mat is armature-space + mult_m4_m4m4(world, ob_arm->obmat, pchan->bone->arm_mat); + } + invert_m4_m4(mat, world); converter.mat4_to_dae(inv_bind_mat, mat); diff -Nru blender-2.61/source/blender/collada/ArmatureImporter.cpp blender-2.62/source/blender/collada/ArmatureImporter.cpp --- blender-2.61/source/blender/collada/ArmatureImporter.cpp 2011-12-13 19:50:01.000000000 +0000 +++ blender-2.62/source/blender/collada/ArmatureImporter.cpp 2012-02-15 19:34:46.000000000 +0000 @@ -99,7 +99,7 @@ // get world-space if (parent){ - mul_m4_m4m4(mat, obmat, parent_mat); + mult_m4_m4m4(mat, parent_mat, obmat); } else { @@ -185,7 +185,7 @@ // get world-space if (parent) - mul_m4_m4m4(mat, obmat, parent_mat); + mult_m4_m4m4(mat, parent_mat, obmat); else copy_m4_m4(mat, obmat); @@ -584,17 +584,17 @@ // get world-space if (parentname){ - mul_m4_m4m4(mat, obmat, parent_mat); + mult_m4_m4m4(mat, parent_mat, obmat); bPoseChannel *parchan = get_pose_channel(ob_arm->pose, parentname); - mul_m4_m4m4(pchan->pose_mat, mat , parchan->pose_mat); + mult_m4_m4m4(pchan->pose_mat, parchan->pose_mat, mat ); } else { copy_m4_m4(mat, obmat); float invObmat[4][4]; invert_m4_m4(invObmat, ob_arm->obmat); - mul_m4_m4m4(pchan->pose_mat, mat, invObmat); + mult_m4_m4m4(pchan->pose_mat, invObmat, mat); } mat4_to_axis_angle(ax,&angle,mat); diff -Nru blender-2.61/source/blender/collada/collada.cpp blender-2.62/source/blender/collada/collada.cpp --- blender-2.61/source/blender/collada/collada.cpp 2011-12-13 19:50:01.000000000 +0000 +++ blender-2.62/source/blender/collada/collada.cpp 2012-02-15 19:34:46.000000000 +0000 @@ -49,11 +49,12 @@ return 0; } - int collada_export(Scene *sce, const char *filepath, int selected) + int collada_export(Scene *sce, const char *filepath, int selected, int second_life) { ExportSettings export_settings; export_settings.selected = selected != 0; + export_settings.second_life = second_life != 0; export_settings.filepath = (char *)filepath; /* annoying, collada crashes if file cant be created! [#27162] */ diff -Nru blender-2.61/source/blender/collada/collada.h blender-2.62/source/blender/collada/collada.h --- blender-2.61/source/blender/collada/collada.h 2011-12-13 19:50:01.000000000 +0000 +++ blender-2.62/source/blender/collada/collada.h 2012-02-15 19:34:46.000000000 +0000 @@ -37,7 +37,7 @@ * both return 1 on success, 0 on error */ int collada_import(bContext *C, const char *filepath); - int collada_export(Scene *sce, const char *filepath, int selected); + int collada_export(Scene *sce, const char *filepath, int selected, int second_life); #ifdef __cplusplus } #endif diff -Nru blender-2.61/source/blender/collada/collada_utils.cpp blender-2.62/source/blender/collada/collada_utils.cpp --- blender-2.61/source/blender/collada/collada_utils.cpp 2011-12-13 19:50:01.000000000 +0000 +++ blender-2.62/source/blender/collada/collada_utils.cpp 2012-02-15 19:34:46.000000000 +0000 @@ -89,7 +89,7 @@ where_is_object(sce, par); // move child obmat into world space - mul_m4_m4m4(mat, ob->obmat, par->obmat); + mult_m4_m4m4(mat, par->obmat, ob->obmat); copy_m4_m4(ob->obmat, mat); } diff -Nru blender-2.61/source/blender/collada/DocumentExporter.cpp blender-2.62/source/blender/collada/DocumentExporter.cpp --- blender-2.61/source/blender/collada/DocumentExporter.cpp 2011-12-13 19:50:01.000000000 +0000 +++ blender-2.62/source/blender/collada/DocumentExporter.cpp 2012-02-15 19:34:46.000000000 +0000 @@ -257,7 +257,7 @@ } // - AnimationExporter ae(&sw); + AnimationExporter ae(&sw, this->export_settings); ae.exportAnimations(sce); // diff -Nru blender-2.61/source/blender/collada/DocumentImporter.cpp blender-2.62/source/blender/collada/DocumentImporter.cpp --- blender-2.61/source/blender/collada/DocumentImporter.cpp 2011-12-13 19:50:01.000000000 +0000 +++ blender-2.62/source/blender/collada/DocumentImporter.cpp 2012-02-15 19:34:46.000000000 +0000 @@ -335,7 +335,7 @@ } } // calc new matrix and apply - mul_m4_m4m4(obn->obmat, mat, obn->obmat); + mult_m4_m4m4(obn->obmat, obn->obmat, mat); object_apply_mat4(obn, obn->obmat, 0, 0); } } diff -Nru blender-2.61/source/blender/collada/ExportSettings.h blender-2.62/source/blender/collada/ExportSettings.h --- blender-2.61/source/blender/collada/ExportSettings.h 2011-12-13 19:50:01.000000000 +0000 +++ blender-2.62/source/blender/collada/ExportSettings.h 2012-02-15 19:34:46.000000000 +0000 @@ -31,6 +31,7 @@ { public: bool selected; + bool second_life; char *filepath; }; diff -Nru blender-2.61/source/blender/collada/GeometryExporter.cpp blender-2.62/source/blender/collada/GeometryExporter.cpp --- blender-2.61/source/blender/collada/GeometryExporter.cpp 2011-12-13 19:50:01.000000000 +0000 +++ blender-2.62/source/blender/collada/GeometryExporter.cpp 2012-02-15 19:34:46.000000000 +0000 @@ -65,6 +65,7 @@ #endif Mesh *me = (Mesh*)ob->data; std::string geom_id = get_geometry_id(ob); + std::string geom_name = id_name(ob->data); std::vector nor; std::vector norind; @@ -78,7 +79,7 @@ create_normals(nor, norind, me); // openMesh(geoId, geoName, meshId) - openMesh(geom_id); + openMesh(geom_id, geom_name); // writes for vertex coords createVertsSource(geom_id, me); diff -Nru blender-2.61/source/blender/collada/MeshImporter.cpp blender-2.62/source/blender/collada/MeshImporter.cpp --- blender-2.61/source/blender/collada/MeshImporter.cpp 2011-12-13 19:50:01.000000000 +0000 +++ blender-2.62/source/blender/collada/MeshImporter.cpp 2012-02-15 19:34:46.000000000 +0000 @@ -187,7 +187,8 @@ // not used anymore, test_index_face from blenkernel is better #if 0 // change face indices order so that v4 is not 0 -void MeshImporter::rotate_face_indices(MFace *mface) { +void MeshImporter::rotate_face_indices(MFace *mface) +{ mface->v4 = mface->v1; mface->v1 = mface->v2; mface->v2 = mface->v3; diff -Nru blender-2.61/source/blender/collada/TransformReader.cpp blender-2.62/source/blender/collada/TransformReader.cpp --- blender-2.61/source/blender/collada/TransformReader.cpp 2011-12-13 19:50:01.000000000 +0000 +++ blender-2.62/source/blender/collada/TransformReader.cpp 2012-02-15 19:34:46.000000000 +0000 @@ -63,7 +63,7 @@ } copy_m4_m4(copy, mat); - mul_m4_m4m4(mat, cur, copy); + mult_m4_m4m4(mat, copy, cur); if (animation_map) { // AnimationList that drives this Transformation diff -Nru blender-2.61/source/blender/collada/TransformWriter.cpp blender-2.62/source/blender/collada/TransformWriter.cpp --- blender-2.61/source/blender/collada/TransformWriter.cpp 2011-12-13 19:50:01.000000000 +0000 +++ blender-2.62/source/blender/collada/TransformWriter.cpp 2012-02-15 19:34:46.000000000 +0000 @@ -40,7 +40,7 @@ if (parent_mat) { float invpar[4][4]; invert_m4_m4(invpar, parent_mat); - mul_m4_m4m4(local, mat, invpar); + mult_m4_m4m4(local, invpar, mat); } else { copy_m4_m4(local, mat); @@ -59,6 +59,7 @@ void TransformWriter::add_node_transform_ob(COLLADASW::Node& node, Object *ob) { + /* float rot[3], loc[3], scale[3]; if (ob->parent) { @@ -77,7 +78,7 @@ // calculate local mat invert_m4_m4(imat, ob->parent->obmat); - mul_m4_m4m4(mat, tmat, imat); + mult_m4_m4m4(mat, imat, tmat); // done @@ -91,6 +92,26 @@ } add_transform(node, loc, rot, scale); + */ + + /* Using parentinv should allow use of existing curves */ + // If parentinv is identity don't add it. + bool add_parinv = false; + for(int i = 0; i < 16; ++i) + { + float f = (i%4 == i/4) ? 1.0f : 0.0f ; + if(ob->parentinv[i%4][i/4] != f) add_parinv = true; + } + + if(add_parinv && ob->parent) + { + double dmat[4][4]; + UnitConverter converter; + converter.mat4_to_dae_double(dmat, ob->parentinv); + node.addMatrix("parentinverse", dmat); + } + + add_transform(node, ob->loc, ob->rot, ob->size); } void TransformWriter::add_node_transform_identity(COLLADASW::Node& node) diff -Nru blender-2.61/source/blender/editors/animation/anim_channels_defines.c blender-2.62/source/blender/editors/animation/anim_channels_defines.c --- blender-2.61/source/blender/editors/animation/anim_channels_defines.c 2011-12-13 19:51:31.000000000 +0000 +++ blender-2.62/source/blender/editors/animation/anim_channels_defines.c 2012-02-15 19:36:17.000000000 +0000 @@ -186,7 +186,7 @@ } /* copy the colors over, transforming from bytes to floats */ - rgb_byte_to_float(cp, color); + rgb_uchar_to_float(color, cp); } else { // FIXME: what happens when the indention is 1 greater than what it should be (due to grouping)? diff -Nru blender-2.61/source/blender/editors/animation/anim_channels_edit.c blender-2.62/source/blender/editors/animation/anim_channels_edit.c --- blender-2.61/source/blender/editors/animation/anim_channels_edit.c 2011-12-13 19:51:31.000000000 +0000 +++ blender-2.62/source/blender/editors/animation/anim_channels_edit.c 2012-02-15 19:36:17.000000000 +0000 @@ -496,7 +496,7 @@ break; /* store this level as the 'old' level now */ - prevLevel= level; // XXX: prevLevel is unused + // prevLevel= level; // XXX: prevLevel is unused } } } @@ -1529,7 +1529,7 @@ return OPERATOR_FINISHED; } - +/* duplicate of 'ANIM_OT_channels_setting_toggle' for menu title only, weak! */ static void ANIM_OT_channels_setting_enable (wmOperatorType *ot) { /* identifiers */ @@ -1551,7 +1551,7 @@ /* setting to set */ ot->prop= RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, 0, "Type", ""); } - +/* duplicate of 'ANIM_OT_channels_setting_toggle' for menu title only, weak! */ static void ANIM_OT_channels_setting_disable (wmOperatorType *ot) { /* identifiers */ @@ -1574,28 +1574,6 @@ ot->prop= RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, 0, "Type", ""); } -static void ANIM_OT_channels_setting_invert (wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Invert Channel Setting"; - ot->idname= "ANIM_OT_channels_setting_toggle"; - ot->description= "Invert specified setting on all selected animation channels"; - - /* api callbacks */ - ot->invoke= WM_menu_invoke; - ot->exec= animchannels_setflag_exec; - ot->poll= animedit_poll_channels_active; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - /* props */ - /* flag-setting mode */ - RNA_def_enum(ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_INVERT, "Mode", ""); - /* setting to set */ - ot->prop= RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, 0, "Type", ""); -} - static void ANIM_OT_channels_setting_toggle (wmOperatorType *ot) { /* identifiers */ @@ -2401,7 +2379,6 @@ WM_operatortype_append(ANIM_OT_channels_setting_enable); WM_operatortype_append(ANIM_OT_channels_setting_disable); - WM_operatortype_append(ANIM_OT_channels_setting_invert); WM_operatortype_append(ANIM_OT_channels_setting_toggle); WM_operatortype_append(ANIM_OT_channels_delete); @@ -2424,20 +2401,21 @@ void ED_keymap_animchannels(wmKeyConfig *keyconf) { wmKeyMap *keymap = WM_keymap_find(keyconf, "Animation Channels", 0, 0); - + wmKeyMapItem *kmi; + /* selection */ /* click-select */ // XXX for now, only leftmouse.... WM_keymap_add_item(keymap, "ANIM_OT_channels_click", LEFTMOUSE, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_click", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", 1); - RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_click", LEFTMOUSE, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "children_only", 1); + RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_click", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", TRUE); + RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_click", LEFTMOUSE, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "children_only", TRUE); /* rename */ WM_keymap_add_item(keymap, "ANIM_OT_channels_rename", LEFTMOUSE, KM_PRESS, KM_CTRL, 0); /* deselect all */ WM_keymap_add_item(keymap, "ANIM_OT_channels_select_all_toggle", AKEY, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_select_all_toggle", IKEY, KM_PRESS, KM_CTRL, 0)->ptr, "invert", 1); + RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_select_all_toggle", IKEY, KM_PRESS, KM_CTRL, 0)->ptr, "invert", TRUE); /* borderselect */ WM_keymap_add_item(keymap, "ANIM_OT_channels_select_border", BKEY, KM_PRESS, 0, 0); @@ -2459,9 +2437,11 @@ WM_keymap_add_item(keymap, "ANIM_OT_channels_expand", PADPLUSKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "ANIM_OT_channels_collapse", PADMINUS, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_expand", PADPLUSKEY, KM_PRESS, KM_CTRL, 0)->ptr, "all", 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_collapse", PADMINUS, KM_PRESS, KM_CTRL, 0)->ptr, "all", 0); - + kmi = WM_keymap_add_item(keymap, "ANIM_OT_channels_expand", PADPLUSKEY, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "all", FALSE); + kmi = WM_keymap_add_item(keymap, "ANIM_OT_channels_collapse", PADMINUS, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "all", FALSE); + /* rearranging */ RNA_enum_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_move", PAGEUPKEY, KM_PRESS, 0, 0)->ptr, "direction", REARRANGE_ANIMCHAN_UP); RNA_enum_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_move", PAGEDOWNKEY, KM_PRESS, 0, 0)->ptr, "direction", REARRANGE_ANIMCHAN_DOWN); diff -Nru blender-2.61/source/blender/editors/animation/anim_deps.c blender-2.62/source/blender/editors/animation/anim_deps.c --- blender-2.61/source/blender/editors/animation/anim_deps.c 2011-12-13 19:51:31.000000000 +0000 +++ blender-2.62/source/blender/editors/animation/anim_deps.c 2012-02-15 19:36:17.000000000 +0000 @@ -148,7 +148,7 @@ /* if one matches, sync the selection status */ if (pchan) { - if (pchan->bone->flag & BONE_SELECTED) + if (pchan->bone && pchan->bone->flag & BONE_SELECTED) agrp->flag |= AGRP_SELECTED; else agrp->flag &= ~AGRP_SELECTED; diff -Nru blender-2.61/source/blender/editors/animation/anim_draw.c blender-2.62/source/blender/editors/animation/anim_draw.c --- blender-2.61/source/blender/editors/animation/anim_draw.c 2011-12-13 19:51:31.000000000 +0000 +++ blender-2.62/source/blender/editors/animation/anim_draw.c 2012-02-15 19:36:17.000000000 +0000 @@ -180,7 +180,7 @@ static void draw_cfra_number (Scene *scene, View2D *v2d, float cfra, short time) { float xscale, yscale, x, y; - char str[32] = " t"; /* t is the character to start replacing from */ + char numstr[32] = " t"; /* t is the character to start replacing from */ short slen; /* because the frame number text is subject to the same scaling as the contents of the view */ @@ -193,10 +193,10 @@ * but power = 1 is required for frames (to get integer frames) */ if (time) - ANIM_timecode_string_from_frame(&str[4], scene, 0, time, FRA2TIME(cfra)); + ANIM_timecode_string_from_frame(&numstr[4], scene, 0, time, FRA2TIME(cfra)); else - ANIM_timecode_string_from_frame(&str[4], scene, 1, time, cfra); - slen= (short)UI_GetStringWidth(str) - 1; + ANIM_timecode_string_from_frame(&numstr[4], scene, 1, time, cfra); + slen= (short)UI_GetStringWidth(numstr) - 1; /* get starting coordinates for drawing */ x= cfra * xscale; @@ -208,7 +208,7 @@ /* draw current frame number - black text */ UI_ThemeColor(TH_TEXT); - UI_DrawString(x-5, y+3, str); + UI_DrawString(x-5, y+3, numstr); /* restore view transform */ glScalef(xscale, 1.0, 1.0); diff -Nru blender-2.61/source/blender/editors/animation/anim_filter.c blender-2.62/source/blender/editors/animation/anim_filter.c --- blender-2.61/source/blender/editors/animation/anim_filter.c 2011-12-13 19:51:31.000000000 +0000 +++ blender-2.62/source/blender/editors/animation/anim_filter.c 2012-02-15 19:36:17.000000000 +0000 @@ -1852,6 +1852,10 @@ /* textures for world */ if (!(ads->filterflag & ADS_FILTER_NOTEX)) items += animdata_filter_ds_textures(ac, &tmp_data, ads, (ID *)wo, filter_mode); + + /* nodes */ + if ((wo->nodetree) && !(ads->filterflag & ADS_FILTER_NONTREE)) + tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)wo, wo->nodetree, filter_mode); } END_ANIMFILTER_SUBCHANNELS; @@ -1947,12 +1951,12 @@ } /* world */ - if ((wo && wo->adt) && !(ads->filterflag & ADS_FILTER_NOWOR)) { + if ((wo) && !(ads->filterflag & ADS_FILTER_NOWOR)) { tmp_items += animdata_filter_ds_world(ac, &tmp_data, ads, sce, wo, filter_mode); } /* nodetree */ - if ((ntree && ntree->adt) && !(ads->filterflag & ADS_FILTER_NONTREE)) { + if ((ntree) && !(ads->filterflag & ADS_FILTER_NONTREE)) { tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)sce, ntree, filter_mode); } @@ -2205,12 +2209,12 @@ /* only filter data if there's somewhere to put it */ if (data && anim_data) { - Object *obact= (ac) ? ac->obact : NULL; /* firstly filter the data */ switch (datatype) { case ANIMCONT_ACTION: /* 'Action Editor' */ { + Object *obact= ac->obact; SpaceAction *saction = (SpaceAction *)ac->sl; bDopeSheet *ads = (saction)? &saction->ads : NULL; diff -Nru blender-2.61/source/blender/editors/animation/anim_ipo_utils.c blender-2.62/source/blender/editors/animation/anim_ipo_utils.c --- blender-2.61/source/blender/editors/animation/anim_ipo_utils.c 2011-12-13 19:51:31.000000000 +0000 +++ blender-2.62/source/blender/editors/animation/anim_ipo_utils.c 2012-02-15 19:36:17.000000000 +0000 @@ -134,8 +134,8 @@ char c= RNA_property_array_item_char(prop, fcu->array_index); /* we need to write the index to a temp buffer (in py syntax) */ - if (c) sprintf(arrayindbuf, "%c ", c); - else sprintf(arrayindbuf, "[%d]", fcu->array_index); + if (c) BLI_snprintf(arrayindbuf, sizeof(arrayindbuf), "%c ", c); + else BLI_snprintf(arrayindbuf, sizeof(arrayindbuf), "[%d]", fcu->array_index); arrayname= &arrayindbuf[0]; } @@ -161,6 +161,11 @@ * use the struct's icon if it is set */ icon= RNA_struct_ui_icon(ptr.type); + + /* valid path - remove the invalid tag since we now know how to use it saving + * users manual effort to reenable using "Revive Disabled FCurves" [#29629] + */ + fcu->flag &= ~FCURVE_DISABLED; } else { /* invalid path */ diff -Nru blender-2.61/source/blender/editors/animation/anim_markers.c blender-2.62/source/blender/editors/animation/anim_markers.c --- blender-2.61/source/blender/editors/animation/anim_markers.c 2011-12-13 19:51:31.000000000 +0000 +++ blender-2.62/source/blender/editors/animation/anim_markers.c 2012-02-15 19:36:17.000000000 +0000 @@ -439,22 +439,28 @@ void draw_markers_time(const bContext *C, int flag) { ListBase *markers= ED_context_get_markers(C); - View2D *v2d= UI_view2d_fromcontext(C); + View2D *v2d; TimeMarker *marker; - + Scene *scene; + if (markers == NULL) return; - + + scene = CTX_data_scene(C); + v2d = UI_view2d_fromcontext(C); + /* unselected markers are drawn at the first time */ for (marker= markers->first; marker; marker= marker->next) { - if ((marker->flag & SELECT) == 0) - draw_marker(v2d, marker, CTX_data_scene(C)->r.cfra, flag); + if ((marker->flag & SELECT) == 0) { + draw_marker(v2d, marker, scene->r.cfra, flag); + } } /* selected markers are drawn later */ for (marker= markers->first; marker; marker= marker->next) { - if (marker->flag & SELECT) - draw_marker(v2d, marker, CTX_data_scene(C)->r.cfra, flag); + if (marker->flag & SELECT) { + draw_marker(v2d, marker, scene->r.cfra, flag); + } } } @@ -550,7 +556,8 @@ if (markers == NULL) return OPERATOR_CANCELLED; - /* two markers can't be at the same place */ + /* prefer not having 2 markers at the same place, + * though the user can move them to overlap once added */ for (marker= markers->first; marker; marker= marker->next) { if (marker->frame == frame) return OPERATOR_CANCELLED; @@ -1490,15 +1497,17 @@ WM_keymap_verify_item(keymap, "MARKER_OT_move", EVT_TWEAK_S, KM_ANY, 0, 0); WM_keymap_verify_item(keymap, "MARKER_OT_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_verify_item(keymap, "MARKER_OT_select", SELECTMOUSE, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "MARKER_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", 1); + kmi = WM_keymap_add_item(keymap, "MARKER_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "extend", TRUE); #ifdef DURIAN_CAMERA_SWITCH kmi= WM_keymap_add_item(keymap, "MARKER_OT_select", SELECTMOUSE, KM_PRESS, KM_CTRL, 0); - RNA_boolean_set(kmi->ptr, "camera", 1); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + RNA_boolean_set(kmi->ptr, "camera", TRUE); kmi= WM_keymap_add_item(keymap, "MARKER_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_CTRL, 0); - RNA_boolean_set(kmi->ptr, "extend", 1); - RNA_boolean_set(kmi->ptr, "camera", 1); + RNA_boolean_set(kmi->ptr, "extend", TRUE); + RNA_boolean_set(kmi->ptr, "camera", TRUE); #else (void)kmi; #endif diff -Nru blender-2.61/source/blender/editors/animation/anim_ops.c blender-2.62/source/blender/editors/animation/anim_ops.c --- blender-2.61/source/blender/editors/animation/anim_ops.c 2011-12-13 19:51:31.000000000 +0000 +++ blender-2.62/source/blender/editors/animation/anim_ops.c 2012-02-15 19:36:17.000000000 +0000 @@ -277,78 +277,12 @@ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } -/* ****************** time display toggle operator ****************************/ - -static int toggle_time_exec(bContext *C, wmOperator *UNUSED(op)) -{ - ScrArea *curarea= CTX_wm_area(C); - - if (curarea == NULL) - return OPERATOR_CANCELLED; - - /* simply toggle draw frames flag in applicable spaces */ - // XXX or should relevant spaces define their own version of this? - switch (curarea->spacetype) { - case SPACE_TIME: /* TimeLine */ - { - SpaceTime *stime= CTX_wm_space_time(C); - stime->flag ^= TIME_DRAWFRAMES; - } - break; - case SPACE_ACTION: /* Action Editor */ - { - SpaceAction *saction= CTX_wm_space_action(C); - saction->flag ^= SACTION_DRAWTIME; - } - break; - case SPACE_IPO: /* Graph Editor */ - { - SpaceIpo *sipo= CTX_wm_space_graph(C); - sipo->flag ^= SIPO_DRAWTIME; - } - break; - case SPACE_NLA: /* NLA Editor */ - { - SpaceNla *snla= CTX_wm_space_nla(C); - snla->flag ^= SNLA_DRAWTIME; - } - break; - case SPACE_SEQ: /* Sequencer */ - { - SpaceSeq *sseq= CTX_wm_space_seq(C); - sseq->flag ^= SEQ_DRAWFRAMES; - } - break; - - default: /* editor doesn't show frames */ - return OPERATOR_CANCELLED; // XXX or should we pass through instead? - } - - ED_area_tag_redraw(curarea); - - return OPERATOR_FINISHED; -} - -static void ANIM_OT_time_toggle(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Toggle Frames/Seconds"; - ot->idname= "ANIM_OT_time_toggle"; - ot->description= "Toggle whether timing is displayed in frames or seconds for active timeline view"; - - /* api callbacks */ - ot->exec= toggle_time_exec; - - ot->poll= ED_operator_animview_active; -} - /* ************************** registration **********************************/ void ED_operatortypes_anim(void) { /* Animation Editors only -------------------------- */ WM_operatortype_append(ANIM_OT_change_frame); - WM_operatortype_append(ANIM_OT_time_toggle); WM_operatortype_append(ANIM_OT_previewrange_set); WM_operatortype_append(ANIM_OT_previewrange_clear); @@ -382,11 +316,14 @@ void ED_keymap_anim(wmKeyConfig *keyconf) { wmKeyMap *keymap= WM_keymap_find(keyconf, "Animation", 0, 0); + wmKeyMapItem *kmi; /* frame management */ /* NOTE: 'ACTIONMOUSE' not 'LEFTMOUSE', as user may have swapped mouse-buttons */ WM_keymap_add_item(keymap, "ANIM_OT_change_frame", ACTIONMOUSE, KM_PRESS, 0, 0); - WM_keymap_verify_item(keymap, "ANIM_OT_time_toggle", TKEY, KM_PRESS, KM_CTRL, 0); + + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", TKEY, KM_PRESS, KM_CTRL, 0); + RNA_string_set(kmi->ptr, "data_path", "space_data.show_seconds"); /* preview range */ WM_keymap_verify_item(keymap, "ANIM_OT_previewrange_set", PKEY, KM_PRESS, 0, 0); diff -Nru blender-2.61/source/blender/editors/animation/keyframing.c blender-2.62/source/blender/editors/animation/keyframing.c --- blender-2.61/source/blender/editors/animation/keyframing.c 2011-12-13 19:51:31.000000000 +0000 +++ blender-2.62/source/blender/editors/animation/keyframing.c 2012-02-15 19:36:17.000000000 +0000 @@ -1200,7 +1200,7 @@ else { /* just call the exec() on the active keyingset */ RNA_enum_set(op->ptr, "type", 0); - RNA_boolean_set(op->ptr, "confirm_success", 1); + RNA_boolean_set(op->ptr, "confirm_success", TRUE); return op->type->exec(C, op); } diff -Nru blender-2.61/source/blender/editors/animation/keyingsets.c blender-2.62/source/blender/editors/animation/keyingsets.c --- blender-2.61/source/blender/editors/animation/keyingsets.c 2011-12-13 19:51:31.000000000 +0000 +++ blender-2.62/source/blender/editors/animation/keyingsets.c 2012-02-15 19:36:17.000000000 +0000 @@ -776,7 +776,7 @@ * - only include entry if it exists */ if (scene->active_keyingset) { - uiItemIntO(layout, "Active Keying Set", ICON_NONE, op_name, "type", i++); + uiItemEnumO(layout, op_name, "Active Keying Set", ICON_NONE, "type", i++); uiItemS(layout); } else @@ -788,7 +788,7 @@ if (scene->keyingsets.first) { for (ks= scene->keyingsets.first; ks; ks=ks->next, i++) { if (ANIM_keyingset_context_ok_poll(C, ks)) - uiItemIntO(layout, ks->name, ICON_NONE, op_name, "type", i); + uiItemEnumO(layout, op_name, ks->name, ICON_NONE, "type", i); } uiItemS(layout); } @@ -798,7 +798,7 @@ for (ks= builtin_keyingsets.first; ks; ks=ks->next, i--) { /* only show KeyingSet if context is suitable */ if (ANIM_keyingset_context_ok_poll(C, ks)) - uiItemIntO(layout, ks->name, ICON_NONE, op_name, "type", i); + uiItemEnumO(layout, op_name, ks->name, ICON_NONE, "type", i); } uiPupMenuEnd(C, pup); diff -Nru blender-2.61/source/blender/editors/armature/armature_intern.h blender-2.62/source/blender/editors/armature/armature_intern.h --- blender-2.61/source/blender/editors/armature/armature_intern.h 2011-12-13 19:52:38.000000000 +0000 +++ blender-2.62/source/blender/editors/armature/armature_intern.h 2012-02-15 19:37:12.000000000 +0000 @@ -99,7 +99,6 @@ void POSE_OT_paste(struct wmOperatorType *ot); void POSE_OT_select_all(struct wmOperatorType *ot); -void POSE_OT_select_inverse(struct wmOperatorType *ot); void POSE_OT_select_parent(struct wmOperatorType *ot); void POSE_OT_select_hierarchy(struct wmOperatorType *ot); void POSE_OT_select_linked(struct wmOperatorType *ot); diff -Nru blender-2.61/source/blender/editors/armature/armature_ops.c blender-2.62/source/blender/editors/armature/armature_ops.c --- blender-2.61/source/blender/editors/armature/armature_ops.c 2011-12-13 19:52:38.000000000 +0000 +++ blender-2.62/source/blender/editors/armature/armature_ops.c 2012-02-15 19:37:12.000000000 +0000 @@ -114,7 +114,6 @@ WM_operatortype_append(POSE_OT_paste); WM_operatortype_append(POSE_OT_select_all); - WM_operatortype_append(POSE_OT_select_inverse); WM_operatortype_append(POSE_OT_select_parent); WM_operatortype_append(POSE_OT_select_hierarchy); @@ -183,7 +182,7 @@ if(ot) { ot->description= "Create new bones from the selected joints and move them"; otmacro=WM_operatortype_macro_define(ot, "ARMATURE_OT_extrude"); - RNA_boolean_set(otmacro->ptr, "forked", 0); + RNA_boolean_set(otmacro->ptr, "forked", FALSE); otmacro= WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); RNA_enum_set(otmacro->ptr, "proportional", 0); } @@ -194,7 +193,7 @@ if(ot) { ot->description= "Create new bones from the selected joints and move them"; otmacro=WM_operatortype_macro_define(ot, "ARMATURE_OT_extrude"); - RNA_boolean_set(otmacro->ptr, "forked", 1); + RNA_boolean_set(otmacro->ptr, "forked", TRUE); otmacro= WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); RNA_enum_set(otmacro->ptr, "proportional", 0); } @@ -221,15 +220,17 @@ WM_keymap_add_item(keymap, "SKETCH_OT_gesture", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "SKETCH_OT_draw_stroke", LEFTMOUSE, KM_PRESS, 0, 0); kmi = WM_keymap_add_item(keymap, "SKETCH_OT_draw_stroke", LEFTMOUSE, KM_PRESS, KM_CTRL, 0); - RNA_boolean_set(kmi->ptr, "snap", 1); + RNA_boolean_set(kmi->ptr, "snap", TRUE); WM_keymap_add_item(keymap, "SKETCH_OT_draw_preview", MOUSEMOVE, KM_ANY, 0, 0); kmi = WM_keymap_add_item(keymap, "SKETCH_OT_draw_preview", MOUSEMOVE, KM_ANY, KM_CTRL, 0); - RNA_boolean_set(kmi->ptr, "snap", 1); + RNA_boolean_set(kmi->ptr, "snap", TRUE); /* only set in editmode armature, by space_view3d listener */ - WM_keymap_add_item(keymap, "ARMATURE_OT_hide", HKEY, KM_PRESS, 0, 0); + kmi = WM_keymap_add_item(keymap, "ARMATURE_OT_hide", HKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "unselected", FALSE); kmi= WM_keymap_add_item(keymap, "ARMATURE_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0); - RNA_boolean_set(kmi->ptr, "unselected", 1); + RNA_boolean_set(kmi->ptr, "unselected", TRUE); + WM_keymap_add_item(keymap, "ARMATURE_OT_reveal", HKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "ARMATURE_OT_align", AKEY, KM_PRESS, KM_CTRL|KM_ALT, 0); WM_keymap_add_item(keymap, "ARMATURE_OT_calculate_roll", NKEY, KM_PRESS, KM_CTRL, 0); @@ -241,20 +242,24 @@ WM_keymap_add_item(keymap, "ARMATURE_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "ARMATURE_OT_parent_clear", PKEY, KM_PRESS, KM_ALT, 0); - WM_keymap_add_item(keymap, "ARMATURE_OT_select_all", AKEY, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "ARMATURE_OT_select_inverse", IKEY, KM_PRESS, KM_CTRL, 0); + kmi = WM_keymap_add_item(keymap, "ARMATURE_OT_select_all", AKEY, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE); + kmi = WM_keymap_add_item(keymap, "ARMATURE_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0); + RNA_enum_set(kmi->ptr, "action", SEL_INVERT); kmi= WM_keymap_add_item(keymap, "ARMATURE_OT_select_hierarchy", LEFTBRACKETKEY, KM_PRESS, 0, 0); RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_PARENT); + RNA_boolean_set(kmi->ptr, "extend", FALSE); kmi= WM_keymap_add_item(keymap, "ARMATURE_OT_select_hierarchy", LEFTBRACKETKEY, KM_PRESS, KM_SHIFT, 0); RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_PARENT); - RNA_boolean_set(kmi->ptr, "extend", 1); + RNA_boolean_set(kmi->ptr, "extend", TRUE); kmi= WM_keymap_add_item(keymap, "ARMATURE_OT_select_hierarchy", RIGHTBRACKETKEY, KM_PRESS, 0, 0); RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_CHILD); + RNA_boolean_set(kmi->ptr, "extend", FALSE); kmi= WM_keymap_add_item(keymap, "ARMATURE_OT_select_hierarchy", RIGHTBRACKETKEY, KM_PRESS, KM_SHIFT, 0); RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_CHILD); - RNA_boolean_set(kmi->ptr, "extend", 1); + RNA_boolean_set(kmi->ptr, "extend", TRUE); WM_keymap_add_item(keymap, "ARMATURE_OT_select_linked", LKEY, KM_PRESS, 0, 0); @@ -300,9 +305,11 @@ WM_keymap_add_item(keymap, "OBJECT_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_menu(keymap, "INFO_MT_add", AKEY, KM_PRESS, KM_SHIFT, 0); - WM_keymap_add_item(keymap, "POSE_OT_hide", HKEY, KM_PRESS, 0, 0); - kmi= WM_keymap_add_item(keymap, "POSE_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0); - RNA_boolean_set(kmi->ptr, "unselected", 1); + kmi = WM_keymap_add_item(keymap, "POSE_OT_hide", HKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "unselected", FALSE); + kmi = WM_keymap_add_item(keymap, "POSE_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "unselected", TRUE); + WM_keymap_add_item(keymap, "POSE_OT_reveal", HKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_menu(keymap, "VIEW3D_MT_pose_apply", AKEY, KM_PRESS, KM_CTRL, 0); @@ -317,26 +324,32 @@ WM_keymap_add_item(keymap, "POSE_OT_rotation_mode_set", RKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "POSE_OT_copy", CKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "POSE_OT_paste", VKEY, KM_PRESS, KM_CTRL, 0); + kmi = WM_keymap_add_item(keymap, "POSE_OT_paste", VKEY, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "flipped", FALSE); + kmi= WM_keymap_add_item(keymap, "POSE_OT_paste", VKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0); - RNA_boolean_set(kmi->ptr, "flipped", 1); + RNA_boolean_set(kmi->ptr, "flipped", TRUE); - WM_keymap_add_item(keymap, "POSE_OT_select_all", AKEY, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "POSE_OT_select_inverse", IKEY, KM_PRESS, KM_CTRL, 0); + kmi = WM_keymap_add_item(keymap, "POSE_OT_select_all", AKEY, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE); + kmi = WM_keymap_add_item(keymap, "POSE_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0); + RNA_enum_set(kmi->ptr, "action", SEL_INVERT); WM_keymap_add_item(keymap, "POSE_OT_select_parent", PKEY, KM_PRESS, KM_SHIFT, 0); kmi= WM_keymap_add_item(keymap, "POSE_OT_select_hierarchy", LEFTBRACKETKEY, KM_PRESS, 0, 0); RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_PARENT); + RNA_boolean_set(kmi->ptr, "extend", FALSE); kmi= WM_keymap_add_item(keymap, "POSE_OT_select_hierarchy", LEFTBRACKETKEY, KM_PRESS, KM_SHIFT, 0); RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_PARENT); - RNA_boolean_set(kmi->ptr, "extend", 1); + RNA_boolean_set(kmi->ptr, "extend", TRUE); kmi= WM_keymap_add_item(keymap, "POSE_OT_select_hierarchy", RIGHTBRACKETKEY, KM_PRESS, 0, 0); RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_CHILD); + RNA_boolean_set(kmi->ptr, "extend", FALSE); kmi= WM_keymap_add_item(keymap, "POSE_OT_select_hierarchy", RIGHTBRACKETKEY, KM_PRESS, KM_SHIFT, 0); RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_CHILD); - RNA_boolean_set(kmi->ptr, "extend", 1); + RNA_boolean_set(kmi->ptr, "extend", TRUE); WM_keymap_add_item(keymap, "POSE_OT_select_linked", LKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "POSE_OT_select_grouped", GKEY, KM_PRESS, KM_SHIFT, 0); diff -Nru blender-2.61/source/blender/editors/armature/editarmature.c blender-2.62/source/blender/editors/armature/editarmature.c --- blender-2.61/source/blender/editors/armature/editarmature.c 2011-12-13 19:52:38.000000000 +0000 +++ blender-2.62/source/blender/editors/armature/editarmature.c 2012-02-15 19:37:13.000000000 +0000 @@ -936,7 +936,7 @@ /* Find the difference matrix */ invert_m4_m4(oimat, ob->obmat); - mul_m4_m4m4(mat, base->object->obmat, oimat); + mult_m4_m4m4(mat, oimat, base->object->obmat); /* Copy bones and posechannels from the object to the edit armature */ for (pchan=opose->chanbase.first; pchan; pchan=pchann) { @@ -972,7 +972,7 @@ /* Find the roll */ invert_m4_m4(imat, premat); - mul_m4_m4m4(difmat, postmat, imat); + mult_m4_m4m4(difmat, imat, postmat); curbone->roll -= (float)atan2(difmat[2][0], difmat[2][2]); } @@ -3457,7 +3457,7 @@ Object *obedit = CTX_data_edit_object(C); EditBone *bone; float obmat[3][3], curs[3], viewmat[3][3], totmat[3][3], imat[3][3]; - char name[32]; + char name[MAXBONENAME]; RNA_string_get(op->ptr, "name", name); @@ -3507,7 +3507,7 @@ /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - RNA_def_string(ot->srna, "name", "Bone", 32, "Name", "Name of the newly created bone"); + RNA_def_string(ot->srna, "name", "Bone", MAXBONENAME, "Name", "Name of the newly created bone"); } @@ -5031,43 +5031,10 @@ /* ***************** selections ********************** */ -static int pose_select_inverse_exec(bContext *C, wmOperator *UNUSED(op)) -{ - - /* Set the flags */ - CTX_DATA_BEGIN(C, bPoseChannel *, pchan, visible_pose_bones) - { - if ((pchan->bone->flag & BONE_UNSELECTABLE) == 0) { - pchan->bone->flag ^= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); - } - } - CTX_DATA_END; - - WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, NULL); - - return OPERATOR_FINISHED; -} - -void POSE_OT_select_inverse(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Select Inverse"; - ot->idname= "POSE_OT_select_inverse"; - ot->description= "Flip the selection status of bones (selected -> unselected, unselected -> selected)"; - - /* api callbacks */ - ot->exec= pose_select_inverse_exec; - ot->poll= ED_operator_posemode; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - -} static int pose_de_select_all_exec(bContext *C, wmOperator *op) { int action = RNA_enum_get(op->ptr, "action"); - Object *ob = NULL; Scene *scene= CTX_data_scene(C); int multipaint = scene->toolsettings->multipaint; @@ -5100,8 +5067,8 @@ WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, NULL); - if(multipaint) { - ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + if (multipaint) { + Object *ob = ED_object_context(C); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); } @@ -5389,7 +5356,7 @@ } } } - + /* See if an object is parented to this armature */ if (ob->parent && (ob->parent->data == arm)) { if (ob->partype==PARBONE) { @@ -5418,17 +5385,15 @@ } } } - - /* Fix animation data attached to this object */ - // TODO: should we be using the database wide version instead (since drivers may break) - if (ob->adt) { - /* posechannels only... */ - BKE_animdata_fix_paths_rename(&ob->id, ob->adt, "pose.bones", oldname, newname, 0, 0, 1); - } } - + + /* Fix all animdata that may refer to this bone - we can't just do the ones attached to objects, since + * other ID-blocks may have drivers referring to this bone [#29822] + */ + BKE_all_animdata_fix_paths_rename("pose.bones", oldname, newname); + + /* correct view locking */ { - /* correct view locking */ bScreen *screen; for(screen= G.main->screen.first; screen; screen= screen->id.next) { ScrArea *sa; @@ -5500,7 +5465,7 @@ { Object *ob= CTX_data_edit_object(C); bArmature *arm; - char newname[32]; + char newname[MAXBONENAME]; short axis= RNA_enum_get(op->ptr, "type"); /* paranoia checks */ diff -Nru blender-2.61/source/blender/editors/armature/editarmature_retarget.c blender-2.62/source/blender/editors/armature/editarmature_retarget.c --- blender-2.61/source/blender/editors/armature/editarmature_retarget.c 2011-12-13 19:52:38.000000000 +0000 +++ blender-2.62/source/blender/editors/armature/editarmature_retarget.c 2012-02-15 19:37:12.000000000 +0000 @@ -450,7 +450,7 @@ { int i, j; - for (i = 0, j = 0; template_name[i] != '\0' && i < 31 && j < 31; i++) + for (i = 0, j = 0; i < (MAXBONENAME-1) && j < (MAXBONENAME-1) && template_name[i] != '\0'; i++) { if (template_name[i] == '&') { @@ -485,7 +485,7 @@ static RigControl *cloneControl(RigGraph *rg, RigGraph *src_rg, RigControl *src_ctrl, GHash *ptr_hash, char *side_string, char *num_string) { RigControl *ctrl; - char name[32]; + char name[MAXBONENAME]; ctrl = newRigControl(rg); @@ -541,7 +541,7 @@ if (src_edge->bone != NULL) { - char name[32]; + char name[MAXBONENAME]; renameTemplateBone(name, src_edge->bone->name, rg->editbones, side_string, num_string); edge->bone = duplicateEditBoneObjects(src_edge->bone, name, rg->editbones, src_rg->ob, rg->ob); edge->bone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL); @@ -1453,7 +1453,7 @@ printf("%sBone: %s\n", indent, ctrl->bone->name); printf("%sLink: %s\n", indent, ctrl->link ? ctrl->link->name : "!NONE!"); - sprintf(text, "%soffset", indent); + BLI_snprintf(text, sizeof(text), "%soffset", indent); print_v3(text, ctrl->offset); printf("%sFlag: %i\n", indent, ctrl->flag); diff -Nru blender-2.61/source/blender/editors/armature/meshlaplacian.c blender-2.62/source/blender/editors/armature/meshlaplacian.c --- blender-2.61/source/blender/editors/armature/meshlaplacian.c 2011-12-13 19:52:38.000000000 +0000 +++ blender-2.62/source/blender/editors/armature/meshlaplacian.c 2012-02-15 19:37:12.000000000 +0000 @@ -45,6 +45,7 @@ #include "BLI_edgehash.h" #include "BLI_memarena.h" #include "BLI_utildefines.h" +#include "BLI_string.h" #include "BKE_DerivedMesh.h" #include "BKE_modifier.h" @@ -681,8 +682,8 @@ mask[mface->v4]= (mvert[mface->v4].flag & SELECT) != 0; } } - else { - if(use_face_sel) { + else if (use_face_sel) { + if (mface->flag & ME_FACE_SEL) { mask[mface->v1]= 1; mask[mface->v2]= 1; mask[mface->v3]= 1; @@ -1613,7 +1614,7 @@ NLContext *context; float vec[3], gridvec[3]; int a, b, x, y, z, totvar; - char message[1024]; + char message[256]; /* setup variable indices */ mdb->varidx= MEM_callocN(sizeof(int)*mdb->size3, "MeshDeformDSvaridx"); @@ -1715,7 +1716,7 @@ break; } - sprintf(message, "Mesh deform solve %d / %d |||", a+1, mdb->totcagevert); + BLI_snprintf(message, sizeof(message), "Mesh deform solve %d / %d |||", a+1, mdb->totcagevert); progress_bar((float)(a+1)/(float)(mdb->totcagevert), message); } diff -Nru blender-2.61/source/blender/editors/armature/poselib.c blender-2.62/source/blender/editors/armature/poselib.c --- blender-2.61/source/blender/editors/armature/poselib.c 2011-12-13 19:52:38.000000000 +0000 +++ blender-2.62/source/blender/editors/armature/poselib.c 2012-02-15 19:37:13.000000000 +0000 @@ -77,6 +77,7 @@ #include "ED_keyframing.h" #include "ED_keyframes_edit.h" #include "ED_screen.h" +#include "ED_object.h" #include "armature_intern.h" @@ -171,7 +172,7 @@ sa = CTX_wm_area(C); if (sa && (sa->spacetype == SPACE_BUTS)) - return CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + return ED_object_context(C); else return object_pose_armature_get(CTX_data_active_object(C)); } @@ -375,6 +376,10 @@ bAction *act= ob->poselib; /* never NULL */ TimeMarker *marker; + wmOperatorType *ot = WM_operatortype_find("POSELIB_OT_pose_add", 1); + + BLI_assert(ot != NULL); + /* set the operator execution context correctly */ uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); @@ -382,9 +387,9 @@ for (marker= act->markers.first; marker; marker= marker->next) { PointerRNA props_ptr; - props_ptr = uiItemFullO(layout, "POSELIB_OT_pose_add", - marker->name, ICON_ARMATURE_DATA, NULL, - WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + props_ptr = uiItemFullO_ptr(layout, ot, + marker->name, ICON_ARMATURE_DATA, NULL, + WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); RNA_int_set(&props_ptr, "frame", marker->frame); RNA_string_set(&props_ptr, "name", marker->name); @@ -976,7 +981,9 @@ /* do header print - if interactively previewing */ if (pld->state == PL_PREVIEW_RUNNING) { if (pld->flag & PL_PREVIEW_SHOWORIGINAL) { - sprintf(pld->headerstr, "PoseLib Previewing Pose: [Showing Original Pose] | Use Tab to start previewing poses again"); + BLI_strncpy(pld->headerstr, + "PoseLib Previewing Pose: [Showing Original Pose] | Use Tab to start previewing poses again", + sizeof(pld->headerstr)); ED_area_headerprint(pld->sa, pld->headerstr); } else if (pld->searchstr[0]) { @@ -987,10 +994,10 @@ /* get search-string */ index= pld->search_cursor; - if (index >= 0 && index <= 64) { + if (index >= 0 && index <= sizeof(tempstr) - 1) { memcpy(&tempstr[0], &pld->searchstr[0], index); tempstr[index]= '|'; - memcpy(&tempstr[index+1], &pld->searchstr[index], 64-index); + memcpy(&tempstr[index+1], &pld->searchstr[index], (sizeof(tempstr) - 1) - index); } else { BLI_strncpy(tempstr, pld->searchstr, sizeof(tempstr)); @@ -999,11 +1006,18 @@ /* get marker name */ BLI_strncpy(markern, pld->marker ? pld->marker->name : "No Matches", sizeof(markern)); - sprintf(pld->headerstr, "PoseLib Previewing Pose: Filter - [%s] | Current Pose - \"%s\" | Use ScrollWheel or PageUp/Down to change", tempstr, markern); + BLI_snprintf(pld->headerstr, sizeof(pld->headerstr), + "PoseLib Previewing Pose: Filter - [%s] | " + "Current Pose - \"%s\" | " + "Use ScrollWheel or PageUp/Down to change", + tempstr, markern); ED_area_headerprint(pld->sa, pld->headerstr); } else { - sprintf(pld->headerstr, "PoseLib Previewing Pose: \"%s\" | Use ScrollWheel or PageUp/Down to change", pld->marker->name); + BLI_snprintf(pld->headerstr, sizeof(pld->headerstr), + "PoseLib Previewing Pose: \"%s\" | " + "Use ScrollWheel or PageUp/Down to change", + pld->marker->name); ED_area_headerprint(pld->sa, pld->headerstr); } } diff -Nru blender-2.61/source/blender/editors/armature/poseobject.c blender-2.62/source/blender/editors/armature/poseobject.c --- blender-2.61/source/blender/editors/armature/poseobject.c 2011-12-13 19:52:38.000000000 +0000 +++ blender-2.62/source/blender/editors/armature/poseobject.c 2012-02-15 19:37:13.000000000 +0000 @@ -73,6 +73,7 @@ #include "ED_keyframing.h" #include "ED_mesh.h" #include "ED_screen.h" +#include "ED_object.h" #include "UI_interface.h" #include "UI_resources.h" @@ -207,7 +208,7 @@ /* since this call may also be used from the buttons window, we need to check for where to get the object */ if (sa->spacetype == SPACE_BUTS) - ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + ob= ED_object_context(C); else ob= object_pose_armature_get(CTX_data_active_object(C)); @@ -283,7 +284,7 @@ /* since this call may also be used from the buttons window, we need to check for where to get the object */ if (sa->spacetype == SPACE_BUTS) - ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + ob= ED_object_context(C); else ob= object_pose_armature_get(CTX_data_active_object(C)); @@ -1221,7 +1222,7 @@ /* since this call may also be used from the buttons window, we need to check for where to get the object */ if (sa->spacetype == SPACE_BUTS) - ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + ob= ED_object_context(C); else ob= object_pose_armature_get(CTX_data_active_object(C)); @@ -1261,7 +1262,7 @@ /* since this call may also be used from the buttons window, we need to check for where to get the object */ if (sa->spacetype == SPACE_BUTS) - ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + ob= ED_object_context(C); else ob= object_pose_armature_get(CTX_data_active_object(C)); @@ -1309,7 +1310,7 @@ /* since this call may also be used from the buttons window, we need to check for where to get the object */ if (sa->spacetype == SPACE_BUTS) - ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + ob= ED_object_context(C); else ob= object_pose_armature_get(CTX_data_active_object(C)); @@ -1358,7 +1359,7 @@ /* since this call may also be used from the buttons window, we need to check for where to get the object */ if (sa->spacetype == SPACE_BUTS) - ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + ob= ED_object_context(C); else ob= object_pose_armature_get(CTX_data_active_object(C)); @@ -1421,7 +1422,7 @@ /* since this call may also be used from the buttons window, we need to check for where to get the object */ if (sa->spacetype == SPACE_BUTS) - ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + ob= ED_object_context(C); else ob= object_pose_armature_get(CTX_data_active_object(C)); @@ -1466,7 +1467,7 @@ static int group_move_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob = ED_object_context(C); bPose *pose= (ob) ? ob->pose : NULL; bPoseChannel *pchan; bActionGroup *grp; @@ -1564,7 +1565,7 @@ static int group_sort_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob = ED_object_context(C); bPose *pose= (ob) ? ob->pose : NULL; bPoseChannel *pchan; tSortActionGroup *agrp_array; @@ -1656,7 +1657,7 @@ /* since this call may also be used from the buttons window, we need to check for where to get the object */ if (sa->spacetype == SPACE_BUTS) - ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + ob= ED_object_context(C); else ob= object_pose_armature_get(CTX_data_active_object(C)); @@ -1694,7 +1695,7 @@ /* since this call may also be used from the buttons window, we need to check for where to get the object */ if (sa->spacetype == SPACE_BUTS) - ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + ob= ED_object_context(C); else ob= object_pose_armature_get(CTX_data_active_object(C)); @@ -1776,7 +1777,7 @@ { Object *ob= object_pose_armature_get(CTX_data_active_object(C)); bArmature *arm; - char newname[32]; + char newname[MAXBONENAME]; short axis= RNA_enum_get(op->ptr, "axis"); /* paranoia checks */ diff -Nru blender-2.61/source/blender/editors/armature/poseSlide.c blender-2.62/source/blender/editors/armature/poseSlide.c --- blender-2.61/source/blender/editors/armature/poseSlide.c 2011-12-13 19:52:38.000000000 +0000 +++ blender-2.62/source/blender/editors/armature/poseSlide.c 2012-02-15 19:37:13.000000000 +0000 @@ -523,28 +523,28 @@ /* draw percentage indicator in header */ static void pose_slide_draw_status (tPoseSlideOp *pso) { - char statusStr[32]; - char mode[32]; + char status_str[32]; + char mode_str[32]; switch (pso->mode) { case POSESLIDE_PUSH: - strcpy(mode, "Push Pose"); + strcpy(mode_str, "Push Pose"); break; case POSESLIDE_RELAX: - strcpy(mode, "Relax Pose"); + strcpy(mode_str, "Relax Pose"); break; case POSESLIDE_BREAKDOWN: - strcpy(mode, "Breakdown"); + strcpy(mode_str, "Breakdown"); break; default: // unknown - strcpy(mode, "Sliding-Tool"); + strcpy(mode_str, "Sliding-Tool"); break; } - sprintf(statusStr, "%s: %d %%", mode, (int)(pso->percentage*100.0f)); - ED_area_headerprint(pso->sa, statusStr); + BLI_snprintf(status_str, sizeof(status_str), "%s: %d %%", mode_str, (int)(pso->percentage*100.0f)); + ED_area_headerprint(pso->sa, status_str); } /* common code for invoke() methods */ diff -Nru blender-2.61/source/blender/editors/armature/reeb.c blender-2.62/source/blender/editors/armature/reeb.c --- blender-2.61/source/blender/editors/armature/reeb.c 2011-12-13 19:52:38.000000000 +0000 +++ blender-2.62/source/blender/editors/armature/reeb.c 2012-02-15 19:37:12.000000000 +0000 @@ -1174,7 +1174,7 @@ fac2 = 0.5f; break; case SKGEN_SHARPEN: - fac1 = fac2 = -0.25f; + fac1 = fac3 = -0.25f; fac2 = 1.5f; break; default: @@ -2035,10 +2035,9 @@ if (count == -1) { - sprintf(filename, "test.txt"); + strcpy(filename, "test.txt"); } - else - { + else { sprintf(filename, "test%05i.txt", count); } f = fopen(filename, "w"); diff -Nru blender-2.61/source/blender/editors/curve/curve_intern.h blender-2.62/source/blender/editors/curve/curve_intern.h --- blender-2.61/source/blender/editors/curve/curve_intern.h 2011-12-13 19:51:44.000000000 +0000 +++ blender-2.62/source/blender/editors/curve/curve_intern.h 2012-02-15 19:36:27.000000000 +0000 @@ -57,7 +57,6 @@ void FONT_OT_text_cut(struct wmOperatorType *ot); void FONT_OT_text_paste(struct wmOperatorType *ot); void FONT_OT_file_paste(struct wmOperatorType *ot); -void FONT_OT_buffer_paste(struct wmOperatorType *ot); void FONT_OT_move(struct wmOperatorType *ot); void FONT_OT_move_select(struct wmOperatorType *ot); @@ -107,7 +106,6 @@ void CURVE_OT_de_select_first(struct wmOperatorType *ot); void CURVE_OT_de_select_last(struct wmOperatorType *ot); void CURVE_OT_select_all(struct wmOperatorType *ot); -void CURVE_OT_select_inverse(struct wmOperatorType *ot); void CURVE_OT_select_linked(struct wmOperatorType *ot); void CURVE_OT_select_linked_pick(struct wmOperatorType *ot); void CURVE_OT_select_row(struct wmOperatorType *ot); diff -Nru blender-2.61/source/blender/editors/curve/curve_ops.c blender-2.62/source/blender/editors/curve/curve_ops.c --- blender-2.61/source/blender/editors/curve/curve_ops.c 2011-12-13 19:51:44.000000000 +0000 +++ blender-2.62/source/blender/editors/curve/curve_ops.c 2012-02-15 19:36:27.000000000 +0000 @@ -68,7 +68,6 @@ WM_operatortype_append(FONT_OT_text_cut); WM_operatortype_append(FONT_OT_text_paste); WM_operatortype_append(FONT_OT_file_paste); - WM_operatortype_append(FONT_OT_buffer_paste); WM_operatortype_append(FONT_OT_move); WM_operatortype_append(FONT_OT_move_select); @@ -117,7 +116,6 @@ WM_operatortype_append(CURVE_OT_de_select_first); WM_operatortype_append(CURVE_OT_de_select_last); WM_operatortype_append(CURVE_OT_select_all); - WM_operatortype_append(CURVE_OT_select_inverse); WM_operatortype_append(CURVE_OT_select_linked); WM_operatortype_append(CURVE_OT_select_linked_pick); WM_operatortype_append(CURVE_OT_select_row); @@ -137,10 +135,30 @@ WM_operatortype_append(CURVE_OT_cyclic_toggle); } +void ED_operatormacros_curve(void) +{ + wmOperatorType *ot; + wmOperatorTypeMacro *otmacro; + + ot= WM_operatortype_append_macro("CURVE_OT_duplicate_move", "Add Duplicate", OPTYPE_UNDO|OPTYPE_REGISTER); + ot->description = "Duplicate curve and move"; + WM_operatortype_macro_define(ot, "CURVE_OT_duplicate"); + otmacro= WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); + RNA_enum_set(otmacro->ptr, "proportional", 0); + RNA_boolean_set(otmacro->ptr, "mirror", FALSE); + + ot= WM_operatortype_append_macro("CURVE_OT_extrude_move", "Extrude Curve and Move", OPTYPE_UNDO|OPTYPE_REGISTER); + ot->description = "Extrude curve and move result"; + WM_operatortype_macro_define(ot, "CURVE_OT_extrude"); + otmacro= WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); + RNA_enum_set(otmacro->ptr, "proportional", 0); + RNA_boolean_set(otmacro->ptr, "mirror", FALSE); +} + void ED_keymap_curve(wmKeyConfig *keyconf) { wmKeyMap *keymap; -// wmKeyMapItem *kmi; + wmKeyMapItem *kmi; keymap= WM_keymap_find(keyconf, "Font", 0, 0); keymap->poll= ED_operator_editfont; @@ -192,7 +210,8 @@ WM_keymap_add_item(keymap, "FONT_OT_line_break", RETKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "FONT_OT_text_insert", KM_TEXTINPUT, KM_ANY, KM_ANY, 0); // last! - RNA_boolean_set(WM_keymap_add_item(keymap, "FONT_OT_text_insert", BACKSPACEKEY, KM_PRESS, KM_ALT, 0)->ptr, "accent", 1); // accented characters + kmi = WM_keymap_add_item(keymap, "FONT_OT_text_insert", BACKSPACEKEY, KM_PRESS, KM_ALT, 0); + RNA_boolean_set(kmi->ptr, "accent", TRUE); /* accented characters */ /* only set in editmode curve, by space_view3d listener */ keymap= WM_keymap_find(keyconf, "Curve", 0, 0); @@ -204,18 +223,24 @@ WM_keymap_add_item(keymap, "CURVE_OT_vertex_add", LEFTMOUSE, KM_CLICK, KM_CTRL, 0); - WM_keymap_add_item(keymap, "CURVE_OT_select_all", AKEY, KM_PRESS, 0, 0); + kmi = WM_keymap_add_item(keymap, "CURVE_OT_select_all", AKEY, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE); + kmi = WM_keymap_add_item(keymap, "CURVE_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0); + RNA_enum_set(kmi->ptr, "action", SEL_INVERT); + WM_keymap_add_item(keymap, "CURVE_OT_select_row", RKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "CURVE_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "CURVE_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "CURVE_OT_select_inverse", IKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "CURVE_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "CURVE_OT_select_linked_pick", LKEY, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "CURVE_OT_select_linked_pick", LKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "deselect", 1); + + kmi = WM_keymap_add_item(keymap, "CURVE_OT_select_linked_pick", LKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "deselect", FALSE); + kmi = WM_keymap_add_item(keymap, "CURVE_OT_select_linked_pick", LKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "deselect", TRUE); WM_keymap_add_item(keymap, "CURVE_OT_separate", PKEY, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "CURVE_OT_extrude", EKEY, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "CURVE_OT_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0); + WM_keymap_add_item(keymap, "CURVE_OT_extrude_move", EKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "CURVE_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "CURVE_OT_make_segment", FKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "CURVE_OT_cyclic_toggle", CKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "CURVE_OT_delete", XKEY, KM_PRESS, 0, 0); @@ -227,8 +252,10 @@ RNA_enum_set(WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", SKEY, KM_PRESS, KM_ALT, 0)->ptr, "mode", TFM_CURVE_SHRINKFATTEN); WM_keymap_add_item(keymap, "CURVE_OT_reveal", HKEY, KM_PRESS, KM_ALT, 0); - WM_keymap_add_item(keymap, "CURVE_OT_hide", HKEY, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "CURVE_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "unselected", 1); + kmi = WM_keymap_add_item(keymap, "CURVE_OT_hide", HKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "unselected", FALSE); + kmi = WM_keymap_add_item(keymap, "CURVE_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "unselected", TRUE); WM_keymap_add_item(keymap, "OBJECT_OT_vertex_parent_set", PKEY, KM_PRESS, KM_CTRL, 0); diff -Nru blender-2.61/source/blender/editors/curve/editcurve.c blender-2.62/source/blender/editors/curve/editcurve.c --- blender-2.61/source/blender/editors/curve/editcurve.c 2011-12-13 19:51:44.000000000 +0000 +++ blender-2.62/source/blender/editors/curve/editcurve.c 2012-02-15 19:36:27.000000000 +0000 @@ -1069,17 +1069,17 @@ while (a--) { keyIndex= getCVKeyIndex(editnurb, bezt); if(keyIndex) { - sprintf(rna_path, "splines[%d].bezier_points[%d]", nu_index, pt_index); - sprintf(orig_rna_path, "splines[%d].bezier_points[%d]", keyIndex->nu_index, keyIndex->pt_index); + BLI_snprintf(rna_path, sizeof(rna_path), "splines[%d].bezier_points[%d]", nu_index, pt_index); + BLI_snprintf(orig_rna_path, sizeof(orig_rna_path), "splines[%d].bezier_points[%d]", keyIndex->nu_index, keyIndex->pt_index); if(keyIndex->switched) { char handle_path[64], orig_handle_path[64]; - sprintf(orig_handle_path, "%s.handle_left", orig_rna_path); - sprintf(handle_path, "%s.handle_right", rna_path); + BLI_snprintf(orig_handle_path, sizeof(orig_rna_path), "%s.handle_left", orig_rna_path); + BLI_snprintf(handle_path, sizeof(rna_path), "%s.handle_right", rna_path); fcurve_path_rename(ad, orig_handle_path, handle_path, orig_curves, &curves); - sprintf(orig_handle_path, "%s.handle_right", orig_rna_path); - sprintf(handle_path, "%s.handle_left", rna_path); + BLI_snprintf(orig_handle_path, sizeof(orig_rna_path), "%s.handle_right", orig_rna_path); + BLI_snprintf(handle_path, sizeof(rna_path), "%s.handle_left", rna_path); fcurve_path_rename(ad, orig_handle_path, handle_path, orig_curves, &curves); } @@ -1100,8 +1100,8 @@ while (a--) { keyIndex= getCVKeyIndex(editnurb, bp); if(keyIndex) { - sprintf(rna_path, "splines[%d].points[%d]", nu_index, pt_index); - sprintf(orig_rna_path, "splines[%d].points[%d]", keyIndex->nu_index, keyIndex->pt_index); + BLI_snprintf(rna_path, sizeof(rna_path), "splines[%d].points[%d]", nu_index, pt_index); + BLI_snprintf(orig_rna_path, sizeof(orig_rna_path), "splines[%d].points[%d]", keyIndex->nu_index, keyIndex->pt_index); fcurve_path_rename(ad, orig_rna_path, rna_path, orig_curves, &curves); keyIndex->nu_index= nu_index; @@ -1140,8 +1140,8 @@ } if(keyIndex) { - sprintf(rna_path, "splines[%d]", nu_index); - sprintf(orig_rna_path, "splines[%d]", keyIndex->nu_index); + BLI_snprintf(rna_path, sizeof(rna_path), "splines[%d]", nu_index); + BLI_snprintf(orig_rna_path, sizeof(orig_rna_path), "splines[%d]", keyIndex->nu_index); fcurve_path_rename(ad, orig_rna_path, rna_path, orig_curves, &curves); } @@ -2749,64 +2749,6 @@ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } -/********************** select invert operator *********************/ - -static int select_inverse_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Object *obedit= CTX_data_edit_object(C); - Curve *cu= obedit->data; - ListBase *editnurb= object_editcurve_get(obedit); - Nurb *nu; - BPoint *bp; - BezTriple *bezt; - int a; - - cu->lastsel= NULL; - - for(nu= editnurb->first; nu; nu= nu->next) { - if(nu->type == CU_BEZIER) { - bezt= nu->bezt; - a= nu->pntsu; - while(a--) { - if(bezt->hide==0) { - bezt->f2 ^= SELECT; /* always do the center point */ - if((cu->drawflag & CU_HIDE_HANDLES)==0) { - bezt->f1 ^= SELECT; - bezt->f3 ^= SELECT; - } - } - bezt++; - } - } - else { - bp= nu->bp; - a= nu->pntsu*nu->pntsv; - while(a--) { - swap_selection_bpoint(bp); - bp++; - } - } - } - - WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); - - return OPERATOR_FINISHED; -} - -void CURVE_OT_select_inverse(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Select Inverse"; - ot->idname= "CURVE_OT_select_inverse"; - - /* api callbacks */ - ot->exec= select_inverse_exec; - ot->poll= ED_operator_editsurfcurve; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - /********************** subdivide operator *********************/ /** Divide the line segments associated with the currently selected @@ -3447,8 +3389,12 @@ nu->orderu= 4; nu->orderv= 1; nu->type = type; + +#if 0 /* UNUSED */ if(nu->flagu & CU_NURB_CYCLIC) c= nu->orderu-1; else c= 0; +#endif + if(type== CU_NURBS) { nu->flagu &= CU_NURB_CYCLIC; /* disable all flags except for cyclic */ nu->flagu |= CU_NURB_BEZIER; @@ -4607,8 +4553,6 @@ } } - // XXX retopo_do_all(); - if(ok) { test2DNurb(nu); @@ -4636,7 +4580,7 @@ { RegionView3D *rv3d= CTX_wm_region_view3d(C); - if(rv3d && !RNA_property_is_set(op->ptr, "location")) { + if(rv3d && !RNA_struct_property_is_set(op->ptr, "location")) { Curve *cu; ViewContext vc; float location[3]; @@ -4716,18 +4660,6 @@ return OPERATOR_FINISHED; } -static int extrude_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) -{ - if(extrude_exec(C, op) == OPERATOR_FINISHED) { - RNA_enum_set(op->ptr, "mode", TFM_TRANSLATION); - WM_operator_name_call(C, "TRANSFORM_OT_transform", WM_OP_INVOKE_REGION_WIN, op->ptr); - - return OPERATOR_FINISHED; - } - - return OPERATOR_CANCELLED; -} - void CURVE_OT_extrude(wmOperatorType *ot) { /* identifiers */ @@ -4737,7 +4669,6 @@ /* api callbacks */ ot->exec= extrude_exec; - ot->invoke= extrude_invoke; ot->poll= ED_operator_editsurfcurve; /* flags */ @@ -5599,16 +5530,6 @@ return OPERATOR_FINISHED; } -static int duplicate_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) -{ - duplicate_exec(C, op); - - RNA_enum_set(op->ptr, "mode", TFM_TRANSLATION); - WM_operator_name_call(C, "TRANSFORM_OT_transform", WM_OP_INVOKE_REGION_WIN, op->ptr); - - return OPERATOR_FINISHED; -} - void CURVE_OT_duplicate(wmOperatorType *ot) { /* identifiers */ @@ -5618,14 +5539,10 @@ /* api callbacks */ ot->exec= duplicate_exec; - ot->invoke= duplicate_invoke; ot->poll= ED_operator_editsurfcurve; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - /* to give to transform */ - RNA_def_enum(ot->srna, "mode", transform_mode_types, TFM_TRANSLATION, "Mode", ""); } /********************** delete operator *********************/ @@ -5963,8 +5880,8 @@ if(obedit->type==OB_SURF) { pup= uiPupMenuBegin(C, "Delete", ICON_NONE); layout= uiPupMenuLayout(pup); - uiItemEnumO(layout, op->type->idname, NULL, 0, "type", 0); - uiItemEnumO(layout, op->type->idname, NULL, 0, "type", 2); + uiItemEnumO_ptr(layout, op->type, NULL, 0, "type", 0); + uiItemEnumO_ptr(layout, op->type, NULL, 0, "type", 2); uiPupMenuEnd(C, pup); } else { @@ -6083,7 +6000,7 @@ if(cu->nurb.first) { /* watch it: switch order here really goes wrong */ - mul_m4_m4m4(cmat, base->object->obmat, imat); + mult_m4_m4m4(cmat, imat, base->object->obmat); nu= cu->nurb.first; while(nu) { diff -Nru blender-2.61/source/blender/editors/curve/editfont.c blender-2.62/source/blender/editors/curve/editfont.c --- blender-2.61/source/blender/editors/curve/editfont.c 2011-12-13 19:51:44.000000000 +0000 +++ blender-2.62/source/blender/editors/curve/editfont.c 2012-02-15 19:36:27.000000000 +0000 @@ -398,7 +398,7 @@ static int paste_file_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { - if(RNA_property_is_set(op->ptr, "filepath")) + if(RNA_struct_property_is_set(op->ptr, "filepath")) return paste_file_exec(C, op); WM_event_add_fileselect(C, op); @@ -422,52 +422,7 @@ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - WM_operator_properties_filesel(ot, FOLDERFILE|TEXTFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH); -} - -/******************* paste buffer operator ********************/ - -static int paste_buffer_exec(bContext *C, wmOperator *UNUSED(op)) -{ - const char *filename; - -#ifdef WIN32 - filename= "C:\\windows\\temp\\cutbuf.txt"; - -// The following is more likely to work on all Win32 installations. -// suggested by Douglas Toltzman. Needs windows include files... -/* - char tempFileName[MAX_PATH]; - DWORD pathlen; - static const char cutbufname[]="cutbuf.txt"; - - if((pathlen=GetTempPath(sizeof(tempFileName),tempFileName)) > 0 && - pathlen + sizeof(cutbufname) <= sizeof(tempFileName)) - { - strcat(tempFileName,cutbufname); - filename= tempFilename; - } -*/ -#else - filename= "/tmp/.cutbuffer"; -#endif - - return paste_file(C, NULL, filename); -} - -void FONT_OT_buffer_paste(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Paste Buffer"; - ot->description= "Paste text from OS buffer"; - ot->idname= "FONT_OT_buffer_paste"; - - /* api callbacks */ - ot->exec= paste_buffer_exec; - ot->poll= ED_operator_editfont; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + WM_operator_properties_filesel(ot, FOLDERFILE|TEXTFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); } /******************* text to object operator ********************/ @@ -1235,7 +1190,7 @@ wchar_t *inserted_text; int a, len; - if(!RNA_property_is_set(op->ptr, "text")) + if(!RNA_struct_property_is_set(op->ptr, "text")) return OPERATOR_CANCELLED; inserted_utf8= RNA_string_get_alloc(op->ptr, "text", NULL, 0); @@ -1268,10 +1223,10 @@ int event= evt->type, val= evt->val; wchar_t inserted_text[2]= {0}; - if(RNA_property_is_set(op->ptr, "text")) + if(RNA_struct_property_is_set(op->ptr, "text")) return insert_text_exec(C, op); - if(RNA_property_is_set(op->ptr, "accent")) { + if(RNA_struct_property_is_set(op->ptr, "accent")) { if(cu->len!=0 && cu->pos>0) accentcode= 1; return OPERATOR_FINISHED; @@ -1718,7 +1673,7 @@ path = (font && strcmp(font->name, FO_BUILTIN_NAME) != 0)? font->name: U.fontdir; - if(RNA_property_is_set(op->ptr, "filepath")) + if(RNA_struct_property_is_set(op->ptr, "filepath")) return font_open_exec(C, op); RNA_string_set(op->ptr, "filepath", path); @@ -1742,7 +1697,7 @@ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - WM_operator_properties_filesel(ot, FOLDERFILE|FTFONTFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH); + WM_operator_properties_filesel(ot, FOLDERFILE|FTFONTFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); } /******************* delete operator *********************/ diff -Nru blender-2.61/source/blender/editors/datafiles/Bfont.c blender-2.62/source/blender/editors/datafiles/Bfont.c --- blender-2.61/source/blender/editors/datafiles/Bfont.c 2011-12-13 19:54:09.000000000 +0000 +++ blender-2.62/source/blender/editors/datafiles/Bfont.c 2012-02-15 19:38:23.000000000 +0000 @@ -34,4 +34,1579 @@ int datatoc_Bfont_size= 25181; -char datatoc_Bfont[25181]= {128, 1, 228, 1, 0, 0, 37, 33, 80, 83, 45, 65, 100, 111, 98, 101, 70, 111, 110, 116, 45, 49, 46, 48, 58, 32, 66, 102, 111, 110, 116, 32, 48, 48, 49, 46, 48, 48, 49, 10, 49, 49, 32, 100, 105, 99, 116, 32, 98, 101, 103, 105, 110, 10, 47, 70, 111, 110, 116, 73, 110, 102, 111, 32, 49, 48, 32, 100, 105, 99, 116, 32, 100, 117, 112, 32, 98, 101, 103, 105, 110, 10, 47, 118, 101, 114, 115, 105, 111, 110, 32, 40, 48, 48, 49, 46, 48, 48, 49, 41, 32, 114, 101, 97, 100, 111, 110, 108, 121, 32, 100, 101, 102, 10, 47, 70, 117, 108, 108, 78, 97, 109, 101, 32, 40, 66, 102, 111, 110, 116, 41, 32, 114, 101, 97, 100, 111, 110, 108, 121, 32, 100, 101, 102, 10, 47, 70, 97, 109, 105, 108, 121, 78, 97, 109, 101, 32, 40, 66, 102, 111, 110, 116, 41, 32, 114, 101, 97, 100, 111, 110, 108, 121, 32, 100, 101, 102, 10, 47, 87, 101, 105, 103, 104, 116, 32, 40, 82, 101, 103, 117, 108, 97, 114, 41, 32, 114, 101, 97, 100, 111, 110, 108, 121, 32, 100, 101, 102, 10, 47, 73, 116, 97, 108, 105, 99, 65, 110, 103, 108, 101, 32, 48, 32, 100, 101, 102, 10, 47, 105, 115, 70, 105, 120, 101, 100, 80, 105, 116, 99, 104, 32, 102, 97, 108, 115, 101, 32, 100, 101, 102, 10, 47, 85, 110, 100, 101, 114, 108, 105, 110, 101, 80, 111, 115, 105, 116, 105, 111, 110, 32, 45, 49, 48, 48, 32, 100, 101, 102, 10, 47, 85, 110, 100, 101, 114, 108, 105, 110, 101, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 53, 48, 32, 100, 101, 102, 10, 101, 110, 100, 32, 114, 101, 97, 100, 111, 110, 108, 121, 32, 100, 101, 102, 10, 47, 70, 111, 110, 116, 78, 97, 109, 101, 32, 47, 66, 102, 111, 110, 116, 32, 100, 101, 102, 10, 47, 69, 110, 99, 111, 100, 105, 110, 103, 32, 83, 116, 97, 110, 100, 97, 114, 100, 69, 110, 99, 111, 100, 105, 110, 103, 32, 100, 101, 102, 10, 47, 80, 97, 105, 110, 116, 84, 121, 112, 101, 32, 48, 32, 100, 101, 102, 10, 47, 70, 111, 110, 116, 84, 121, 112, 101, 32, 49, 32, 100, 101, 102, 10, 47, 70, 111, 110, 116, 77, 97, 116, 114, 105, 120, 32, 91, 48, 46, 48, 48, 49, 32, 48, 32, 48, 32, 48, 46, 48, 48, 49, 32, 48, 32, 48, 93, 32, 114, 101, 97, 100, 111, 110, 108, 121, 32, 100, 101, 102, 10, 99, 117, 114, 114, 101, 110, 116, 100, 105, 99, 116, 32, 101, 110, 100, 10, 99, 117, 114, 114, 101, 110, 116, 102, 105, 108, 101, 32, 101, 101, 120, 101, 99, 10, 128, 2, 146, 94, 0, 0, 217, 214, 111, 99, 59, 132, 106, 152, 155, 153, 116, 176, 23, 159, 198, 204, 68, 91, 194, 192, 49, 3, 198, 133, 112, 167, 179, 84, 164, 162, 128, 174, 111, 191, 127, 152, 247, 90, 132, 186, 206, 45, 3, 106, 107, 81, 184, 72, 73, 49, 89, 29, 146, 229, 6, 158, 98, 38, 213, 173, 204, 93, 228, 248, 16, 122, 166, 154, 53, 181, 95, 106, 155, 75, 79, 147, 197, 108, 35, 188, 198, 29, 215, 191, 143, 50, 242, 29, 88, 228, 26, 95, 121, 12, 238, 47, 2, 175, 73, 134, 149, 233, 12, 29, 11, 210, 89, 231, 91, 2, 25, 48, 11, 15, 105, 44, 51, 119, 156, 42, 166, 122, 232, 81, 122, 190, 18, 48, 8, 69, 34, 74, 246, 173, 93, 169, 219, 154, 26, 58, 64, 251, 6, 179, 106, 156, 205, 105, 18, 85, 7, 252, 45, 233, 208, 65, 132, 199, 96, 66, 240, 63, 207, 209, 83, 132, 0, 35, 151, 42, 129, 42, 185, 179, 203, 86, 112, 193, 206, 39, 89, 113, 28, 117, 41, 66, 98, 214, 242, 145, 175, 155, 124, 118, 7, 30, 218, 126, 122, 208, 38, 33, 98, 50, 34, 185, 54, 8, 122, 178, 127, 254, 95, 7, 134, 71, 6, 101, 146, 24, 61, 195, 71, 174, 146, 230, 191, 86, 177, 123, 237, 206, 19, 104, 70, 246, 162, 163, 118, 171, 140, 11, 192, 255, 78, 52, 125, 32, 253, 14, 199, 126, 250, 177, 240, 99, 49, 0, 20, 141, 42, 125, 47, 210, 31, 18, 90, 170, 205, 143, 219, 153, 121, 131, 43, 103, 13, 138, 170, 118, 210, 18, 186, 181, 97, 70, 25, 144, 150, 12, 53, 110, 184, 216, 233, 243, 198, 93, 157, 254, 127, 140, 44, 138, 123, 43, 233, 158, 99, 255, 108, 134, 136, 60, 29, 229, 7, 141, 163, 185, 30, 3, 228, 132, 13, 221, 109, 48, 227, 60, 227, 135, 117, 220, 128, 67, 195, 147, 32, 118, 71, 190, 131, 11, 245, 200, 93, 30, 226, 32, 114, 26, 39, 232, 138, 33, 109, 232, 1, 11, 233, 212, 78, 221, 88, 158, 135, 95, 159, 14, 38, 31, 12, 106, 255, 51, 147, 42, 139, 254, 210, 119, 6, 96, 221, 226, 140, 183, 213, 222, 5, 205, 13, 140, 253, 214, 125, 103, 227, 52, 60, 102, 31, 250, 163, 147, 228, 167, 58, 207, 156, 68, 166, 150, 167, 169, 116, 83, 194, 150, 104, 152, 31, 7, 157, 38, 76, 29, 10, 247, 63, 57, 194, 106, 230, 183, 120, 135, 187, 201, 211, 82, 234, 168, 182, 167, 90, 56, 37, 109, 160, 144, 13, 48, 204, 190, 14, 169, 103, 127, 136, 102, 24, 81, 61, 32, 233, 228, 158, 18, 235, 189, 28, 0, 222, 67, 17, 110, 143, 71, 223, 181, 33, 17, 66, 81, 210, 7, 23, 186, 245, 229, 198, 143, 62, 113, 33, 80, 236, 87, 148, 65, 42, 27, 111, 128, 223, 196, 140, 45, 32, 91, 123, 158, 136, 153, 166, 144, 126, 115, 133, 220, 254, 234, 192, 123, 14, 239, 75, 199, 116, 28, 241, 25, 30, 66, 226, 248, 159, 142, 46, 41, 10, 237, 111, 205, 31, 230, 72, 196, 49, 200, 50, 29, 115, 153, 141, 198, 225, 218, 157, 86, 56, 67, 249, 99, 50, 25, 151, 14, 200, 35, 186, 250, 204, 151, 187, 209, 51, 129, 161, 68, 118, 130, 31, 25, 134, 255, 75, 170, 240, 225, 113, 144, 5, 178, 133, 45, 85, 242, 66, 10, 10, 65, 138, 93, 147, 72, 210, 250, 209, 123, 148, 135, 12, 156, 94, 13, 250, 31, 211, 157, 82, 128, 132, 143, 11, 155, 47, 211, 151, 232, 142, 253, 82, 104, 234, 231, 190, 169, 78, 32, 90, 2, 41, 201, 122, 142, 205, 144, 234, 204, 198, 227, 56, 57, 6, 63, 8, 237, 89, 199, 30, 226, 169, 48, 198, 191, 38, 114, 87, 135, 189, 98, 251, 224, 210, 154, 58, 87, 26, 56, 41, 219, 119, 124, 109, 83, 182, 169, 166, 123, 255, 190, 35, 121, 177, 37, 92, 128, 242, 247, 132, 218, 149, 140, 116, 184, 163, 13, 248, 138, 68, 124, 229, 211, 89, 210, 101, 172, 149, 221, 182, 113, 36, 182, 46, 5, 141, 127, 147, 54, 118, 67, 107, 105, 187, 40, 53, 208, 170, 25, 45, 113, 216, 110, 135, 56, 7, 26, 14, 225, 61, 79, 228, 72, 30, 39, 220, 195, 227, 229, 153, 196, 28, 6, 107, 240, 54, 67, 6, 94, 143, 0, 34, 180, 49, 14, 41, 111, 9, 41, 94, 203, 184, 139, 142, 34, 140, 138, 90, 25, 216, 89, 252, 45, 46, 132, 169, 154, 230, 131, 15, 20, 100, 99, 235, 106, 73, 185, 89, 6, 66, 230, 171, 202, 22, 213, 227, 183, 32, 138, 116, 253, 208, 230, 121, 16, 63, 238, 132, 69, 28, 135, 88, 115, 18, 21, 11, 102, 172, 200, 37, 222, 255, 100, 221, 80, 173, 218, 53, 210, 250, 148, 211, 241, 97, 150, 185, 43, 250, 138, 14, 122, 133, 30, 191, 54, 158, 118, 22, 12, 232, 25, 228, 60, 101, 206, 119, 29, 57, 12, 99, 36, 167, 182, 153, 86, 195, 21, 70, 154, 102, 106, 45, 236, 70, 151, 143, 185, 207, 252, 106, 46, 168, 80, 216, 206, 157, 171, 118, 77, 82, 153, 24, 54, 165, 128, 160, 27, 195, 117, 241, 141, 93, 151, 233, 239, 244, 73, 123, 133, 42, 138, 123, 68, 159, 225, 209, 171, 242, 70, 212, 6, 168, 19, 116, 228, 0, 14, 148, 191, 132, 10, 254, 83, 125, 20, 17, 71, 126, 142, 56, 80, 55, 48, 125, 184, 172, 156, 163, 161, 72, 249, 105, 204, 207, 179, 217, 115, 177, 2, 82, 220, 142, 14, 180, 138, 254, 83, 139, 36, 70, 203, 91, 81, 82, 229, 20, 253, 78, 132, 213, 64, 154, 163, 59, 93, 245, 168, 38, 148, 48, 228, 13, 186, 204, 95, 140, 184, 118, 22, 130, 111, 27, 38, 139, 127, 106, 172, 161, 254, 136, 187, 166, 48, 162, 152, 124, 69, 27, 186, 50, 126, 7, 144, 43, 75, 176, 145, 159, 202, 244, 7, 78, 203, 250, 32, 42, 195, 71, 186, 90, 92, 162, 126, 98, 44, 195, 163, 47, 88, 124, 43, 177, 122, 251, 254, 29, 161, 70, 98, 235, 133, 52, 12, 28, 184, 67, 145, 73, 88, 99, 69, 60, 227, 142, 15, 218, 82, 167, 57, 225, 230, 218, 131, 251, 171, 11, 63, 191, 65, 236, 178, 63, 159, 213, 211, 114, 64, 200, 85, 73, 40, 94, 123, 108, 171, 89, 169, 206, 99, 196, 31, 15, 152, 138, 77, 137, 210, 197, 228, 255, 73, 126, 120, 249, 214, 170, 212, 168, 73, 54, 125, 113, 78, 226, 37, 137, 249, 188, 239, 33, 231, 244, 125, 116, 137, 126, 187, 31, 193, 194, 118, 121, 19, 80, 250, 87, 48, 80, 62, 246, 29, 121, 247, 135, 198, 193, 253, 148, 211, 17, 210, 17, 247, 44, 205, 91, 1, 190, 195, 236, 66, 95, 144, 58, 235, 2, 42, 79, 25, 82, 164, 167, 244, 114, 188, 192, 101, 23, 55, 69, 141, 168, 28, 89, 60, 116, 91, 162, 121, 28, 123, 96, 252, 165, 180, 69, 56, 232, 54, 122, 138, 223, 158, 131, 94, 171, 82, 4, 112, 13, 160, 117, 170, 146, 28, 241, 154, 211, 119, 16, 233, 141, 96, 94, 167, 13, 37, 118, 105, 73, 211, 97, 109, 148, 131, 190, 119, 45, 124, 208, 225, 39, 94, 48, 62, 33, 188, 248, 154, 233, 46, 158, 7, 144, 1, 121, 0, 235, 71, 25, 52, 13, 46, 1, 25, 171, 27, 179, 170, 164, 231, 2, 25, 182, 226, 250, 96, 192, 23, 185, 218, 218, 16, 140, 36, 180, 216, 59, 95, 49, 165, 162, 134, 252, 47, 168, 65, 242, 178, 211, 62, 10, 239, 153, 65, 219, 247, 72, 17, 105, 49, 254, 85, 136, 211, 117, 240, 218, 77, 221, 166, 41, 145, 198, 4, 104, 136, 241, 48, 0, 158, 210, 236, 207, 26, 145, 140, 95, 164, 117, 198, 0, 183, 104, 161, 59, 9, 189, 8, 32, 44, 26, 255, 157, 119, 245, 250, 49, 176, 156, 227, 102, 228, 105, 83, 24, 153, 85, 196, 129, 133, 128, 208, 129, 202, 62, 204, 173, 137, 91, 223, 112, 208, 243, 87, 180, 109, 82, 141, 56, 239, 210, 40, 86, 200, 173, 31, 32, 230, 140, 202, 61, 220, 176, 92, 108, 207, 177, 213, 169, 238, 172, 158, 254, 38, 242, 141, 6, 115, 217, 193, 134, 166, 227, 36, 208, 119, 86, 44, 34, 195, 71, 119, 94, 234, 241, 122, 79, 169, 173, 36, 221, 120, 68, 23, 3, 44, 125, 38, 78, 72, 230, 25, 62, 18, 205, 206, 66, 140, 79, 125, 229, 223, 0, 92, 25, 118, 253, 161, 219, 51, 228, 229, 212, 13, 155, 26, 50, 54, 105, 54, 38, 85, 152, 49, 150, 233, 88, 191, 111, 0, 122, 147, 95, 215, 50, 33, 176, 209, 77, 136, 198, 6, 71, 97, 100, 152, 0, 159, 94, 91, 202, 7, 148, 125, 254, 58, 38, 107, 49, 101, 14, 194, 163, 12, 79, 253, 153, 150, 54, 30, 37, 140, 189, 241, 141, 47, 57, 139, 145, 74, 88, 15, 178, 179, 63, 241, 91, 129, 30, 79, 19, 104, 72, 56, 215, 37, 124, 242, 77, 81, 109, 155, 0, 233, 122, 186, 107, 91, 145, 92, 162, 90, 4, 113, 170, 84, 211, 132, 142, 64, 27, 93, 152, 248, 107, 94, 93, 160, 109, 249, 241, 251, 102, 130, 66, 96, 51, 112, 140, 245, 151, 65, 45, 189, 157, 117, 188, 91, 97, 49, 138, 107, 106, 135, 204, 203, 38, 119, 33, 149, 87, 122, 158, 198, 8, 142, 218, 3, 56, 249, 80, 86, 253, 82, 246, 203, 231, 57, 160, 50, 52, 187, 24, 108, 130, 253, 193, 24, 51, 201, 50, 3, 67, 176, 187, 124, 165, 172, 142, 252, 156, 155, 220, 252, 51, 237, 105, 94, 48, 44, 233, 187, 188, 123, 100, 218, 223, 36, 114, 54, 219, 223, 39, 156, 112, 206, 46, 19, 10, 213, 139, 69, 12, 138, 134, 44, 130, 94, 136, 4, 111, 77, 21, 115, 225, 162, 15, 38, 159, 218, 138, 102, 171, 2, 142, 48, 158, 57, 94, 59, 182, 17, 127, 190, 223, 196, 66, 238, 107, 50, 154, 2, 142, 167, 152, 18, 25, 226, 1, 253, 251, 17, 102, 20, 111, 28, 97, 136, 15, 60, 65, 230, 39, 49, 25, 166, 31, 18, 54, 4, 24, 89, 211, 226, 250, 74, 226, 185, 67, 138, 29, 18, 85, 156, 124, 145, 84, 17, 175, 167, 51, 13, 54, 82, 97, 64, 206, 201, 111, 199, 214, 210, 235, 148, 55, 181, 241, 136, 86, 254, 219, 122, 64, 103, 179, 79, 113, 163, 126, 75, 107, 79, 102, 244, 21, 147, 198, 210, 251, 35, 136, 73, 15, 32, 45, 150, 134, 253, 113, 83, 111, 161, 110, 212, 242, 33, 12, 12, 16, 143, 194, 199, 37, 228, 251, 110, 7, 213, 198, 55, 80, 32, 209, 140, 34, 47, 102, 249, 217, 166, 118, 31, 106, 2, 18, 106, 46, 146, 148, 125, 0, 208, 89, 209, 247, 55, 143, 177, 19, 183, 127, 71, 118, 20, 136, 3, 233, 109, 119, 181, 115, 223, 110, 139, 182, 171, 109, 104, 72, 62, 152, 143, 14, 157, 82, 154, 253, 142, 215, 59, 1, 11, 98, 107, 140, 12, 240, 144, 56, 38, 14, 220, 237, 154, 174, 151, 179, 207, 104, 234, 222, 84, 126, 157, 90, 52, 118, 126, 96, 23, 203, 135, 134, 41, 16, 196, 210, 44, 125, 68, 145, 232, 236, 52, 222, 102, 131, 80, 101, 237, 218, 244, 215, 205, 95, 58, 96, 18, 66, 213, 91, 247, 58, 44, 57, 150, 193, 139, 135, 36, 143, 236, 94, 209, 236, 213, 227, 42, 176, 173, 206, 87, 151, 240, 145, 185, 45, 209, 177, 201, 123, 32, 196, 44, 158, 83, 203, 202, 6, 106, 54, 93, 43, 209, 12, 114, 76, 100, 242, 104, 165, 138, 15, 143, 5, 33, 228, 195, 243, 111, 81, 249, 174, 15, 167, 40, 165, 51, 97, 185, 215, 150, 118, 253, 22, 103, 9, 21, 185, 238, 189, 94, 49, 104, 100, 98, 165, 196, 31, 148, 112, 125, 199, 46, 103, 252, 79, 100, 165, 112, 104, 82, 249, 219, 205, 34, 198, 31, 198, 191, 181, 72, 212, 182, 62, 87, 13, 53, 171, 84, 222, 156, 131, 201, 162, 173, 47, 44, 187, 105, 119, 132, 47, 228, 184, 36, 85, 218, 11, 251, 242, 124, 205, 168, 252, 24, 245, 49, 84, 161, 107, 211, 21, 63, 219, 89, 15, 116, 192, 18, 208, 86, 95, 75, 71, 239, 247, 105, 124, 85, 174, 144, 220, 24, 188, 94, 40, 209, 132, 234, 225, 53, 69, 240, 42, 47, 92, 18, 240, 120, 210, 140, 168, 218, 105, 60, 246, 247, 238, 188, 247, 10, 162, 24, 136, 226, 91, 107, 157, 168, 51, 186, 15, 79, 68, 154, 225, 52, 41, 228, 127, 35, 41, 224, 97, 225, 44, 85, 16, 225, 99, 198, 48, 182, 98, 235, 255, 178, 24, 210, 58, 14, 200, 84, 18, 132, 137, 35, 171, 63, 195, 238, 195, 167, 167, 8, 207, 232, 214, 100, 91, 195, 90, 233, 86, 98, 207, 185, 229, 196, 140, 253, 236, 219, 150, 62, 62, 2, 15, 51, 232, 157, 44, 234, 107, 188, 220, 214, 209, 42, 165, 18, 94, 143, 235, 241, 192, 254, 106, 155, 48, 246, 239, 123, 17, 140, 12, 101, 251, 102, 156, 126, 130, 2, 38, 62, 255, 27, 134, 182, 120, 23, 158, 103, 4, 48, 154, 78, 236, 14, 254, 222, 239, 42, 228, 224, 138, 87, 211, 236, 78, 212, 1, 107, 139, 81, 5, 238, 185, 84, 205, 51, 83, 67, 52, 42, 135, 255, 244, 123, 157, 185, 116, 114, 160, 116, 246, 30, 147, 127, 129, 156, 51, 229, 39, 122, 2, 122, 145, 229, 25, 122, 2, 151, 7, 125, 246, 76, 129, 209, 110, 138, 246, 211, 33, 183, 60, 192, 108, 167, 161, 157, 173, 188, 134, 192, 179, 203, 195, 136, 84, 41, 110, 193, 122, 131, 11, 75, 124, 83, 139, 80, 12, 71, 93, 214, 179, 43, 70, 139, 91, 53, 228, 97, 105, 67, 230, 118, 92, 183, 131, 114, 231, 74, 140, 48, 135, 180, 10, 184, 148, 46, 75, 182, 205, 83, 47, 151, 206, 84, 243, 232, 233, 126, 142, 30, 11, 113, 219, 252, 153, 18, 16, 215, 238, 121, 155, 255, 21, 214, 89, 6, 196, 3, 201, 131, 48, 187, 159, 235, 14, 27, 155, 245, 77, 229, 130, 112, 168, 164, 253, 69, 23, 253, 242, 175, 19, 232, 155, 161, 27, 158, 95, 160, 90, 79, 109, 133, 203, 42, 70, 181, 120, 247, 244, 85, 191, 167, 255, 36, 251, 115, 54, 191, 78, 211, 182, 252, 5, 12, 100, 32, 48, 200, 26, 234, 123, 25, 161, 253, 134, 168, 60, 15, 187, 62, 24, 239, 177, 98, 92, 109, 195, 112, 78, 242, 161, 250, 224, 210, 94, 111, 34, 100, 196, 71, 103, 74, 123, 216, 217, 180, 160, 33, 64, 105, 123, 183, 125, 84, 77, 80, 99, 109, 247, 173, 168, 239, 122, 88, 233, 117, 237, 148, 43, 144, 195, 255, 222, 124, 214, 133, 156, 117, 244, 7, 73, 13, 100, 164, 68, 175, 191, 93, 225, 252, 128, 96, 77, 231, 196, 150, 223, 120, 56, 23, 101, 94, 23, 50, 76, 38, 27, 89, 184, 93, 140, 37, 79, 249, 66, 199, 27, 220, 230, 114, 176, 179, 228, 201, 12, 56, 113, 1, 25, 207, 104, 177, 191, 79, 237, 143, 226, 104, 92, 21, 249, 98, 205, 22, 105, 215, 184, 142, 178, 107, 8, 194, 13, 32, 156, 84, 109, 146, 152, 57, 241, 72, 62, 74, 122, 212, 88, 179, 57, 23, 186, 74, 73, 82, 37, 80, 182, 165, 40, 89, 30, 244, 209, 110, 163, 24, 182, 201, 139, 145, 225, 148, 219, 184, 1, 109, 99, 156, 37, 247, 177, 111, 50, 209, 221, 208, 78, 0, 72, 6, 236, 76, 79, 63, 132, 26, 227, 72, 142, 229, 248, 120, 160, 148, 155, 91, 51, 61, 40, 22, 192, 96, 139, 193, 192, 41, 116, 79, 140, 116, 158, 248, 64, 168, 227, 174, 56, 114, 92, 160, 31, 200, 94, 82, 99, 139, 67, 95, 47, 76, 180, 152, 43, 131, 149, 177, 4, 212, 56, 209, 190, 209, 102, 122, 224, 72, 234, 244, 111, 175, 138, 120, 23, 203, 9, 146, 234, 239, 94, 241, 28, 21, 170, 51, 2, 176, 125, 179, 217, 99, 83, 17, 16, 113, 123, 111, 68, 94, 156, 200, 90, 117, 30, 174, 131, 42, 161, 91, 76, 85, 199, 44, 75, 199, 0, 159, 111, 158, 236, 63, 252, 73, 67, 220, 113, 169, 158, 74, 7, 81, 214, 149, 155, 222, 129, 91, 63, 169, 196, 168, 208, 230, 83, 168, 4, 19, 27, 176, 157, 146, 56, 42, 254, 143, 171, 119, 60, 127, 57, 37, 107, 84, 255, 246, 76, 159, 38, 176, 233, 13, 97, 107, 64, 55, 206, 201, 204, 218, 3, 139, 123, 150, 151, 110, 28, 198, 99, 247, 167, 155, 37, 184, 253, 214, 21, 253, 250, 179, 26, 233, 98, 205, 117, 109, 94, 222, 15, 151, 184, 119, 219, 159, 26, 52, 234, 55, 66, 100, 108, 175, 174, 17, 111, 135, 189, 244, 238, 173, 23, 17, 241, 136, 78, 124, 75, 203, 114, 135, 228, 221, 79, 244, 180, 84, 215, 120, 58, 193, 234, 17, 21, 132, 110, 10, 93, 93, 0, 183, 245, 134, 61, 95, 68, 191, 141, 237, 95, 126, 87, 58, 149, 134, 213, 110, 116, 216, 192, 10, 112, 38, 232, 50, 35, 120, 57, 45, 172, 232, 37, 77, 226, 153, 110, 131, 253, 210, 168, 180, 83, 56, 51, 56, 189, 222, 97, 193, 136, 138, 42, 148, 50, 111, 24, 19, 254, 177, 109, 42, 4, 65, 172, 96, 251, 160, 54, 58, 165, 202, 64, 75, 38, 58, 75, 176, 216, 98, 146, 125, 118, 248, 14, 106, 228, 226, 81, 241, 251, 127, 27, 23, 92, 157, 140, 12, 59, 86, 252, 122, 13, 128, 14, 184, 55, 155, 44, 253, 29, 47, 123, 191, 185, 154, 163, 114, 250, 216, 48, 218, 24, 41, 137, 186, 200, 209, 147, 86, 234, 11, 251, 42, 56, 181, 243, 238, 166, 135, 92, 151, 86, 174, 89, 79, 71, 14, 24, 5, 179, 87, 131, 135, 102, 59, 186, 66, 1, 6, 72, 5, 28, 79, 49, 186, 194, 62, 179, 53, 186, 31, 143, 15, 105, 32, 251, 188, 138, 11, 244, 36, 100, 101, 80, 187, 253, 53, 90, 154, 212, 181, 126, 209, 58, 10, 55, 168, 27, 236, 115, 101, 224, 193, 103, 231, 231, 76, 130, 169, 64, 247, 143, 160, 6, 12, 187, 62, 115, 85, 133, 97, 131, 157, 164, 5, 18, 51, 69, 53, 226, 170, 32, 248, 133, 194, 58, 114, 243, 156, 53, 219, 228, 37, 51, 150, 240, 227, 74, 100, 66, 140, 115, 100, 103, 47, 160, 145, 39, 160, 75, 222, 218, 28, 108, 232, 107, 91, 0, 57, 250, 136, 6, 33, 118, 115, 103, 179, 221, 108, 40, 142, 175, 185, 2, 12, 192, 66, 213, 152, 41, 233, 223, 41, 212, 85, 17, 52, 58, 211, 181, 46, 211, 206, 189, 26, 8, 90, 115, 224, 151, 195, 224, 213, 34, 162, 189, 222, 218, 155, 78, 201, 101, 242, 9, 56, 215, 152, 239, 247, 121, 3, 16, 221, 56, 45, 35, 243, 146, 128, 44, 114, 215, 132, 101, 220, 233, 180, 2, 29, 87, 203, 185, 144, 16, 37, 113, 60, 244, 214, 140, 191, 24, 192, 37, 255, 161, 147, 216, 30, 40, 155, 88, 60, 186, 135, 11, 23, 228, 43, 157, 203, 102, 196, 197, 1, 1, 87, 218, 126, 80, 76, 30, 182, 207, 153, 135, 248, 6, 181, 215, 77, 128, 200, 10, 19, 107, 138, 202, 84, 120, 191, 140, 117, 50, 32, 27, 105, 174, 224, 170, 123, 53, 76, 48, 210, 6, 227, 195, 114, 235, 87, 145, 150, 26, 21, 17, 214, 198, 245, 125, 109, 156, 170, 204, 143, 228, 62, 196, 128, 21, 243, 153, 91, 71, 164, 113, 164, 255, 48, 36, 238, 105, 220, 163, 93, 3, 33, 47, 150, 241, 211, 190, 111, 157, 234, 189, 25, 58, 247, 75, 118, 247, 167, 171, 118, 223, 1, 180, 98, 83, 0, 2, 109, 17, 255, 116, 244, 107, 101, 220, 100, 70, 21, 133, 179, 90, 210, 116, 32, 197, 24, 82, 114, 120, 218, 14, 147, 80, 194, 80, 69, 78, 223, 157, 183, 130, 49, 139, 162, 34, 12, 176, 45, 242, 103, 232, 128, 68, 88, 225, 181, 149, 3, 210, 20, 38, 155, 6, 206, 136, 22, 170, 92, 156, 165, 116, 142, 250, 72, 203, 235, 193, 116, 244, 4, 209, 55, 186, 29, 8, 33, 193, 221, 73, 27, 212, 204, 22, 197, 179, 8, 122, 134, 8, 255, 96, 51, 2, 169, 193, 96, 128, 178, 109, 143, 131, 50, 219, 208, 58, 159, 103, 233, 100, 26, 2, 177, 129, 122, 168, 120, 71, 39, 115, 228, 108, 114, 161, 243, 24, 10, 221, 105, 0, 32, 230, 75, 208, 233, 4, 70, 249, 98, 37, 46, 87, 158, 145, 60, 85, 229, 199, 236, 126, 80, 183, 181, 12, 68, 3, 15, 23, 36, 92, 146, 109, 61, 24, 128, 78, 239, 88, 230, 215, 204, 90, 147, 118, 171, 51, 168, 95, 93, 23, 90, 244, 164, 172, 201, 222, 112, 143, 193, 209, 130, 201, 207, 118, 175, 51, 3, 83, 144, 53, 7, 2, 223, 146, 50, 101, 168, 159, 133, 28, 66, 29, 64, 233, 76, 182, 133, 172, 68, 223, 114, 254, 236, 111, 30, 73, 137, 130, 164, 131, 196, 189, 111, 155, 147, 217, 64, 194, 115, 143, 201, 77, 22, 153, 228, 83, 191, 53, 210, 87, 234, 21, 34, 187, 184, 28, 63, 179, 214, 83, 14, 112, 32, 169, 159, 133, 207, 19, 169, 188, 147, 111, 186, 114, 43, 118, 152, 25, 71, 184, 247, 239, 62, 39, 125, 8, 176, 91, 46, 127, 37, 169, 247, 186, 170, 231, 106, 124, 93, 82, 203, 135, 50, 177, 85, 74, 115, 219, 76, 96, 173, 44, 242, 38, 163, 171, 14, 0, 95, 76, 99, 75, 14, 39, 213, 116, 182, 72, 2, 234, 176, 65, 98, 150, 36, 70, 86, 137, 151, 218, 245, 141, 17, 24, 233, 41, 185, 58, 178, 56, 54, 122, 148, 231, 151, 41, 214, 96, 4, 243, 46, 63, 200, 233, 128, 161, 95, 138, 244, 183, 141, 145, 14, 25, 91, 197, 70, 3, 227, 187, 203, 223, 48, 120, 113, 7, 0, 130, 193, 160, 67, 108, 185, 71, 237, 171, 101, 159, 96, 98, 34, 4, 142, 114, 155, 160, 147, 193, 170, 48, 115, 253, 172, 245, 59, 145, 176, 55, 203, 245, 60, 24, 247, 235, 79, 12, 117, 74, 18, 151, 14, 208, 7, 227, 230, 138, 182, 107, 33, 172, 211, 232, 244, 91, 86, 80, 237, 55, 154, 175, 32, 221, 17, 151, 79, 104, 238, 25, 226, 76, 155, 72, 39, 90, 209, 93, 119, 54, 17, 9, 222, 62, 18, 136, 25, 15, 59, 194, 203, 57, 150, 0, 52, 122, 104, 84, 199, 104, 180, 154, 180, 177, 141, 173, 169, 154, 113, 35, 75, 198, 157, 150, 80, 44, 212, 248, 174, 232, 251, 140, 74, 214, 189, 41, 120, 113, 156, 65, 16, 15, 201, 18, 45, 16, 210, 104, 247, 38, 33, 40, 249, 61, 119, 153, 179, 72, 88, 122, 109, 208, 91, 186, 231, 246, 201, 154, 26, 36, 115, 126, 217, 44, 194, 140, 103, 229, 15, 250, 227, 140, 106, 204, 118, 169, 157, 84, 150, 31, 128, 194, 254, 144, 221, 84, 79, 211, 148, 33, 60, 107, 211, 170, 159, 248, 105, 63, 114, 0, 23, 234, 92, 230, 240, 118, 6, 250, 181, 184, 227, 64, 186, 40, 94, 67, 225, 133, 89, 15, 16, 174, 144, 165, 59, 6, 73, 13, 18, 29, 10, 46, 237, 23, 51, 33, 27, 193, 212, 63, 194, 5, 79, 66, 177, 81, 200, 84, 254, 225, 36, 110, 208, 225, 202, 213, 89, 214, 140, 142, 227, 223, 60, 214, 19, 145, 92, 92, 164, 207, 222, 158, 250, 12, 146, 150, 67, 204, 120, 211, 109, 95, 186, 40, 167, 178, 90, 34, 46, 234, 28, 109, 171, 182, 83, 197, 36, 51, 69, 152, 168, 121, 48, 71, 179, 22, 218, 168, 182, 160, 147, 195, 177, 176, 201, 234, 213, 209, 135, 222, 9, 1, 157, 170, 240, 175, 246, 218, 255, 92, 53, 102, 171, 22, 235, 180, 248, 118, 10, 85, 14, 24, 218, 184, 132, 191, 225, 112, 66, 3, 231, 36, 235, 34, 214, 181, 57, 104, 151, 76, 69, 101, 83, 20, 39, 170, 108, 161, 239, 236, 126, 9, 144, 27, 117, 209, 174, 173, 92, 16, 185, 25, 8, 65, 29, 134, 67, 1, 248, 62, 221, 239, 134, 12, 15, 252, 203, 140, 179, 52, 247, 3, 230, 34, 184, 102, 82, 118, 76, 218, 254, 242, 24, 115, 22, 119, 90, 4, 149, 236, 176, 116, 68, 77, 123, 201, 192, 255, 188, 107, 195, 3, 217, 184, 106, 219, 116, 81, 207, 193, 227, 101, 41, 29, 232, 72, 85, 236, 151, 74, 93, 150, 166, 171, 155, 81, 131, 81, 109, 171, 184, 37, 190, 114, 106, 113, 144, 234, 76, 143, 92, 98, 190, 112, 151, 198, 151, 181, 99, 7, 182, 50, 190, 157, 141, 17, 199, 148, 230, 14, 240, 95, 238, 139, 161, 96, 85, 137, 154, 79, 67, 168, 101, 253, 126, 23, 165, 143, 47, 33, 157, 100, 6, 130, 253, 188, 66, 21, 205, 243, 116, 62, 241, 161, 177, 199, 234, 61, 135, 55, 113, 25, 153, 27, 129, 149, 189, 140, 112, 211, 49, 176, 38, 44, 110, 29, 135, 178, 122, 233, 3, 166, 97, 175, 61, 159, 98, 61, 54, 46, 62, 246, 137, 17, 150, 249, 165, 99, 211, 172, 76, 7, 104, 39, 106, 119, 221, 159, 210, 96, 33, 236, 87, 164, 112, 47, 226, 247, 236, 140, 185, 182, 20, 201, 51, 88, 97, 52, 198, 70, 49, 248, 96, 51, 82, 115, 169, 78, 73, 112, 123, 106, 120, 113, 184, 93, 194, 224, 68, 211, 200, 237, 209, 41, 160, 127, 89, 163, 55, 9, 27, 252, 78, 93, 147, 141, 12, 156, 44, 226, 106, 126, 159, 181, 106, 84, 25, 39, 220, 41, 134, 184, 173, 69, 141, 128, 221, 57, 194, 56, 41, 148, 107, 242, 241, 174, 129, 152, 123, 81, 101, 1, 204, 9, 109, 154, 97, 169, 63, 167, 52, 96, 239, 63, 116, 163, 122, 158, 94, 221, 35, 90, 184, 69, 186, 220, 155, 205, 65, 191, 31, 209, 62, 120, 156, 77, 154, 212, 58, 165, 208, 254, 65, 204, 148, 200, 121, 78, 129, 79, 121, 39, 34, 3, 169, 118, 120, 52, 35, 119, 142, 29, 15, 144, 156, 90, 134, 101, 105, 11, 112, 32, 74, 0, 219, 159, 132, 100, 7, 106, 88, 142, 42, 159, 159, 133, 11, 175, 92, 88, 144, 12, 55, 185, 47, 142, 31, 43, 39, 16, 83, 122, 54, 7, 150, 158, 215, 14, 143, 136, 147, 141, 231, 157, 67, 152, 119, 164, 114, 159, 71, 210, 144, 98, 127, 44, 132, 218, 170, 183, 6, 185, 210, 94, 95, 99, 240, 116, 30, 126, 76, 115, 212, 246, 102, 92, 96, 159, 252, 177, 173, 238, 87, 145, 120, 239, 83, 103, 148, 111, 193, 200, 157, 199, 84, 245, 167, 68, 43, 9, 69, 55, 83, 164, 109, 90, 46, 101, 215, 36, 23, 74, 170, 73, 31, 151, 63, 13, 233, 151, 107, 248, 28, 92, 35, 70, 5, 235, 85, 219, 20, 213, 153, 157, 249, 176, 37, 255, 191, 49, 221, 195, 243, 205, 150, 238, 234, 168, 137, 153, 201, 222, 205, 199, 162, 119, 146, 41, 89, 105, 114, 144, 27, 194, 167, 15, 17, 102, 155, 81, 20, 64, 25, 235, 217, 63, 154, 242, 225, 13, 33, 182, 38, 116, 47, 107, 50, 207, 110, 29, 136, 55, 33, 139, 136, 214, 63, 92, 125, 90, 118, 202, 7, 13, 45, 43, 162, 106, 53, 143, 13, 190, 171, 226, 196, 144, 17, 49, 136, 120, 246, 99, 28, 219, 184, 171, 145, 232, 242, 225, 86, 216, 29, 251, 249, 41, 244, 144, 111, 2, 13, 67, 69, 97, 59, 202, 92, 254, 71, 189, 6, 119, 180, 186, 203, 34, 18, 85, 115, 103, 178, 15, 139, 42, 154, 39, 24, 0, 19, 22, 240, 255, 252, 93, 217, 151, 118, 89, 76, 228, 117, 200, 137, 13, 190, 247, 255, 24, 253, 162, 24, 184, 20, 70, 173, 242, 65, 255, 14, 85, 235, 99, 103, 131, 181, 84, 80, 63, 156, 184, 204, 191, 61, 156, 252, 59, 37, 109, 229, 102, 139, 94, 178, 178, 164, 231, 49, 155, 35, 56, 196, 15, 169, 144, 251, 215, 89, 129, 230, 72, 219, 139, 197, 78, 109, 102, 25, 48, 44, 123, 211, 216, 106, 185, 237, 124, 133, 39, 37, 162, 20, 211, 134, 155, 168, 11, 222, 152, 143, 211, 112, 133, 136, 21, 169, 89, 187, 92, 61, 144, 126, 142, 165, 91, 64, 45, 41, 56, 164, 108, 49, 241, 137, 99, 44, 191, 100, 11, 225, 166, 244, 183, 14, 69, 141, 184, 193, 220, 72, 211, 67, 223, 16, 43, 227, 34, 87, 91, 32, 229, 84, 162, 113, 251, 125, 218, 118, 31, 254, 16, 33, 170, 201, 209, 49, 30, 113, 104, 193, 212, 82, 64, 80, 214, 32, 149, 217, 244, 237, 193, 223, 104, 77, 128, 228, 140, 55, 252, 204, 229, 187, 36, 99, 153, 241, 138, 135, 171, 169, 62, 250, 184, 63, 167, 139, 183, 57, 170, 36, 217, 201, 129, 169, 222, 78, 153, 65, 153, 195, 211, 229, 159, 191, 0, 145, 12, 209, 25, 247, 122, 19, 108, 173, 163, 187, 235, 254, 87, 80, 25, 110, 179, 158, 48, 232, 20, 138, 81, 198, 78, 18, 44, 75, 181, 18, 238, 96, 61, 247, 229, 254, 2, 55, 169, 32, 180, 136, 177, 161, 213, 132, 128, 108, 93, 159, 201, 212, 238, 223, 233, 186, 243, 4, 248, 5, 33, 214, 193, 214, 95, 51, 141, 60, 72, 63, 142, 184, 37, 122, 118, 136, 97, 93, 142, 245, 8, 147, 224, 126, 67, 93, 170, 105, 121, 231, 171, 85, 105, 191, 126, 88, 57, 42, 253, 179, 85, 251, 193, 163, 112, 71, 28, 137, 104, 199, 121, 13, 122, 58, 231, 160, 176, 50, 200, 80, 65, 99, 25, 67, 129, 91, 97, 178, 131, 195, 111, 148, 134, 71, 57, 145, 113, 209, 177, 51, 154, 29, 28, 180, 74, 13, 69, 147, 96, 210, 108, 176, 89, 248, 238, 64, 140, 85, 196, 169, 20, 251, 238, 194, 41, 56, 39, 59, 226, 189, 130, 178, 90, 176, 226, 46, 108, 156, 204, 174, 85, 118, 165, 137, 184, 160, 133, 89, 170, 184, 37, 48, 65, 241, 224, 117, 164, 248, 213, 112, 143, 128, 23, 130, 133, 216, 66, 190, 63, 238, 179, 84, 71, 27, 50, 83, 199, 91, 126, 164, 192, 76, 107, 100, 229, 6, 25, 164, 89, 235, 117, 247, 61, 109, 205, 76, 128, 230, 41, 243, 85, 58, 189, 128, 216, 21, 53, 68, 80, 1, 25, 171, 203, 71, 176, 46, 6, 84, 35, 150, 95, 144, 144, 253, 210, 78, 10, 31, 218, 179, 248, 95, 81, 244, 79, 215, 63, 196, 100, 165, 120, 54, 14, 180, 125, 152, 106, 173, 125, 14, 108, 211, 161, 131, 229, 114, 56, 252, 16, 221, 16, 242, 74, 87, 168, 121, 127, 247, 212, 200, 71, 204, 116, 246, 255, 154, 24, 137, 127, 45, 177, 212, 17, 212, 102, 236, 29, 88, 177, 166, 135, 107, 210, 230, 219, 124, 71, 98, 50, 230, 107, 222, 79, 222, 190, 37, 241, 242, 167, 27, 117, 253, 201, 76, 251, 186, 18, 135, 96, 191, 207, 15, 107, 67, 146, 251, 105, 102, 25, 200, 71, 209, 165, 125, 192, 18, 228, 162, 238, 214, 221, 138, 49, 40, 100, 122, 249, 20, 121, 57, 199, 11, 0, 243, 76, 57, 23, 211, 110, 212, 250, 218, 95, 154, 145, 179, 173, 45, 233, 155, 246, 67, 35, 203, 93, 5, 2, 91, 121, 116, 93, 64, 69, 31, 182, 179, 74, 59, 198, 41, 19, 102, 51, 76, 126, 224, 153, 65, 254, 186, 90, 16, 91, 220, 154, 130, 20, 187, 103, 141, 248, 188, 245, 250, 139, 191, 48, 138, 40, 199, 201, 155, 147, 83, 62, 254, 80, 3, 107, 104, 36, 103, 186, 94, 186, 225, 107, 167, 118, 230, 199, 85, 241, 219, 139, 20, 28, 233, 5, 131, 144, 101, 21, 228, 236, 249, 115, 82, 62, 147, 175, 251, 174, 128, 176, 255, 248, 142, 239, 113, 165, 254, 238, 22, 99, 162, 202, 108, 79, 235, 246, 32, 220, 11, 51, 239, 109, 4, 204, 179, 212, 86, 38, 5, 232, 170, 76, 151, 131, 165, 206, 122, 105, 124, 107, 28, 137, 196, 99, 194, 6, 122, 29, 75, 178, 26, 232, 70, 33, 231, 24, 73, 33, 187, 181, 240, 75, 22, 114, 163, 98, 114, 6, 93, 2, 32, 16, 79, 93, 119, 219, 153, 15, 182, 129, 123, 242, 162, 182, 152, 200, 24, 14, 95, 48, 35, 60, 237, 71, 183, 152, 92, 134, 31, 82, 174, 53, 155, 170, 96, 221, 93, 137, 90, 31, 128, 20, 131, 15, 86, 154, 93, 190, 178, 124, 214, 130, 43, 64, 134, 249, 0, 48, 215, 92, 236, 202, 24, 47, 60, 232, 190, 124, 3, 71, 145, 183, 215, 240, 1, 100, 235, 203, 185, 205, 122, 222, 41, 199, 127, 4, 74, 57, 92, 80, 227, 109, 81, 197, 32, 38, 35, 53, 94, 245, 9, 141, 245, 223, 223, 95, 42, 175, 157, 209, 215, 90, 64, 0, 248, 244, 246, 25, 60, 7, 169, 138, 246, 184, 96, 155, 68, 94, 155, 22, 15, 241, 169, 20, 49, 215, 209, 111, 239, 200, 144, 5, 33, 153, 142, 239, 148, 110, 117, 109, 248, 67, 98, 109, 157, 187, 172, 160, 169, 85, 54, 0, 153, 129, 217, 150, 67, 124, 151, 101, 106, 131, 207, 134, 5, 255, 139, 146, 192, 0, 115, 91, 6, 129, 58, 60, 103, 106, 223, 52, 211, 102, 252, 153, 7, 36, 34, 32, 136, 111, 24, 231, 218, 101, 114, 49, 128, 185, 58, 235, 26, 108, 148, 216, 2, 109, 127, 76, 170, 230, 167, 77, 230, 144, 120, 234, 183, 78, 246, 204, 228, 134, 249, 88, 100, 196, 198, 168, 113, 216, 42, 35, 193, 234, 34, 195, 152, 125, 79, 79, 24, 161, 173, 16, 174, 46, 67, 170, 131, 156, 232, 86, 89, 173, 30, 39, 209, 177, 50, 137, 84, 109, 203, 25, 179, 105, 42, 151, 141, 56, 47, 146, 109, 175, 225, 243, 210, 206, 81, 196, 237, 159, 201, 165, 55, 181, 153, 69, 153, 117, 118, 217, 130, 65, 139, 68, 118, 59, 201, 202, 82, 129, 162, 23, 102, 61, 155, 109, 206, 125, 41, 111, 139, 83, 174, 133, 242, 44, 2, 235, 186, 58, 247, 99, 136, 173, 106, 250, 248, 34, 152, 133, 3, 208, 170, 129, 23, 60, 73, 212, 46, 191, 190, 88, 207, 221, 164, 178, 45, 215, 131, 204, 225, 117, 173, 138, 180, 3, 0, 15, 14, 221, 73, 184, 22, 167, 83, 216, 31, 137, 254, 108, 90, 21, 235, 5, 68, 143, 236, 218, 177, 170, 239, 180, 8, 168, 140, 226, 189, 16, 145, 62, 163, 225, 93, 205, 37, 120, 98, 129, 249, 129, 253, 213, 174, 200, 19, 143, 140, 9, 177, 50, 105, 134, 69, 113, 244, 133, 6, 120, 25, 155, 132, 254, 226, 207, 43, 56, 168, 69, 169, 95, 83, 166, 34, 69, 213, 187, 98, 243, 119, 143, 121, 249, 119, 129, 165, 103, 146, 140, 13, 136, 238, 160, 170, 253, 171, 212, 98, 239, 172, 195, 249, 68, 207, 60, 24, 130, 128, 167, 163, 178, 130, 220, 6, 139, 198, 201, 110, 26, 91, 155, 144, 143, 212, 85, 106, 50, 198, 74, 210, 168, 146, 232, 172, 30, 152, 206, 69, 44, 47, 88, 165, 180, 221, 45, 252, 248, 47, 26, 33, 142, 189, 77, 77, 20, 185, 247, 249, 88, 67, 117, 249, 151, 118, 57, 18, 137, 128, 189, 134, 148, 85, 7, 47, 60, 142, 110, 105, 252, 45, 165, 187, 134, 50, 255, 180, 56, 130, 137, 76, 189, 218, 152, 46, 148, 44, 1, 239, 47, 72, 192, 70, 14, 74, 90, 136, 245, 35, 40, 171, 29, 17, 97, 77, 184, 32, 38, 38, 252, 12, 0, 226, 11, 222, 132, 183, 121, 209, 83, 3, 164, 243, 32, 111, 109, 145, 203, 57, 241, 192, 5, 107, 164, 128, 3, 218, 69, 178, 200, 222, 45, 65, 105, 110, 115, 184, 75, 243, 221, 49, 226, 170, 189, 49, 246, 129, 33, 150, 38, 203, 3, 214, 111, 206, 150, 168, 137, 162, 228, 3, 96, 105, 184, 27, 106, 81, 32, 147, 230, 60, 219, 199, 176, 74, 100, 18, 80, 140, 70, 128, 115, 119, 111, 82, 172, 8, 6, 168, 188, 56, 197, 112, 159, 169, 216, 200, 90, 251, 104, 112, 19, 179, 71, 59, 181, 138, 224, 158, 252, 148, 50, 65, 55, 33, 120, 142, 137, 108, 20, 142, 236, 144, 89, 197, 190, 188, 19, 102, 227, 240, 38, 170, 129, 123, 69, 123, 193, 13, 37, 133, 44, 167, 210, 141, 172, 154, 208, 42, 156, 35, 126, 176, 1, 98, 193, 135, 102, 235, 229, 22, 34, 187, 18, 111, 64, 83, 107, 17, 157, 241, 117, 59, 8, 211, 60, 200, 87, 184, 89, 132, 249, 60, 18, 81, 237, 225, 53, 221, 131, 255, 218, 64, 239, 194, 7, 181, 40, 3, 46, 108, 220, 52, 108, 62, 254, 140, 37, 116, 15, 40, 169, 90, 47, 136, 102, 253, 7, 223, 132, 207, 60, 234, 21, 134, 155, 63, 112, 37, 72, 222, 55, 59, 20, 34, 167, 71, 222, 221, 164, 161, 92, 131, 244, 235, 243, 237, 184, 129, 77, 165, 160, 139, 171, 234, 234, 69, 113, 128, 93, 215, 9, 84, 41, 213, 35, 164, 24, 120, 204, 180, 178, 153, 47, 245, 57, 22, 175, 206, 12, 175, 203, 129, 39, 93, 127, 18, 12, 55, 43, 36, 252, 1, 104, 116, 59, 135, 193, 145, 183, 41, 62, 78, 165, 189, 232, 128, 224, 11, 142, 255, 2, 223, 95, 80, 219, 87, 249, 121, 31, 181, 50, 241, 31, 127, 174, 99, 238, 176, 116, 65, 220, 160, 189, 25, 204, 103, 20, 231, 42, 195, 34, 180, 105, 121, 110, 99, 149, 139, 1, 221, 124, 67, 172, 47, 189, 207, 14, 229, 79, 158, 187, 203, 126, 236, 14, 53, 121, 243, 132, 78, 39, 72, 7, 165, 22, 78, 41, 101, 128, 20, 168, 136, 198, 109, 226, 32, 135, 168, 104, 155, 115, 57, 50, 66, 17, 72, 245, 124, 70, 188, 194, 144, 89, 140, 85, 8, 10, 129, 227, 167, 15, 15, 201, 54, 239, 194, 154, 204, 129, 27, 190, 245, 102, 166, 178, 201, 7, 197, 78, 149, 69, 245, 4, 143, 4, 84, 13, 217, 59, 242, 223, 226, 199, 231, 118, 188, 55, 115, 56, 15, 217, 3, 0, 181, 190, 3, 162, 127, 120, 206, 181, 8, 225, 155, 148, 202, 117, 70, 96, 81, 246, 165, 253, 115, 148, 217, 138, 44, 203, 36, 44, 221, 59, 122, 68, 170, 248, 235, 88, 242, 209, 42, 71, 31, 117, 5, 149, 221, 216, 154, 116, 41, 231, 138, 123, 85, 128, 71, 109, 111, 17, 72, 163, 225, 109, 7, 40, 133, 74, 76, 155, 107, 34, 193, 114, 240, 61, 31, 24, 46, 215, 197, 96, 114, 213, 18, 214, 57, 119, 50, 18, 5, 175, 254, 21, 246, 64, 145, 171, 217, 243, 159, 250, 231, 228, 64, 164, 97, 61, 150, 9, 230, 11, 138, 132, 95, 209, 138, 97, 87, 139, 190, 171, 135, 158, 170, 99, 198, 18, 127, 44, 102, 1, 236, 90, 73, 214, 135, 116, 107, 247, 175, 46, 238, 51, 79, 163, 249, 5, 137, 145, 92, 138, 23, 207, 158, 50, 109, 131, 84, 61, 184, 252, 232, 20, 67, 107, 189, 61, 198, 27, 6, 189, 119, 34, 236, 94, 105, 65, 140, 181, 248, 32, 12, 119, 126, 0, 14, 226, 78, 7, 121, 111, 47, 30, 49, 206, 187, 125, 247, 235, 6, 229, 34, 161, 174, 72, 154, 37, 94, 8, 88, 125, 54, 182, 100, 46, 84, 144, 213, 251, 62, 71, 177, 120, 255, 194, 14, 105, 206, 151, 179, 144, 140, 191, 167, 248, 44, 70, 227, 154, 142, 32, 174, 159, 199, 154, 78, 165, 68, 96, 73, 8, 13, 246, 162, 155, 48, 7, 121, 90, 173, 40, 226, 166, 189, 35, 87, 225, 45, 209, 220, 70, 22, 156, 216, 39, 126, 84, 142, 207, 100, 219, 155, 166, 43, 253, 161, 255, 143, 148, 93, 17, 7, 109, 176, 112, 14, 87, 147, 186, 123, 32, 159, 252, 83, 111, 182, 250, 28, 239, 207, 92, 64, 17, 26, 216, 0, 41, 24, 142, 246, 19, 172, 32, 137, 234, 69, 147, 251, 234, 207, 95, 6, 113, 209, 107, 69, 122, 198, 148, 13, 18, 28, 238, 191, 168, 205, 144, 234, 181, 247, 192, 151, 176, 95, 157, 60, 224, 26, 120, 24, 16, 66, 102, 51, 185, 111, 39, 6, 205, 187, 16, 1, 141, 45, 234, 48, 144, 26, 92, 155, 213, 218, 88, 151, 0, 111, 109, 28, 44, 172, 24, 215, 205, 186, 42, 119, 124, 48, 41, 199, 85, 81, 244, 24, 170, 71, 156, 141, 249, 234, 193, 174, 77, 184, 47, 107, 112, 235, 124, 254, 7, 163, 156, 71, 59, 122, 224, 196, 215, 71, 81, 145, 207, 178, 97, 118, 45, 154, 109, 190, 143, 63, 83, 135, 110, 166, 174, 47, 195, 33, 0, 234, 212, 223, 11, 248, 210, 158, 17, 139, 239, 15, 57, 133, 185, 152, 71, 56, 2, 62, 10, 103, 243, 247, 182, 81, 10, 38, 49, 7, 131, 10, 202, 184, 79, 149, 84, 213, 122, 133, 208, 24, 141, 132, 12, 244, 251, 160, 41, 56, 219, 123, 120, 23, 240, 40, 29, 32, 213, 222, 36, 49, 173, 176, 11, 209, 145, 104, 154, 154, 182, 183, 5, 60, 131, 70, 224, 47, 125, 110, 47, 246, 180, 222, 125, 243, 251, 55, 25, 147, 77, 164, 116, 218, 152, 191, 244, 47, 199, 68, 208, 209, 49, 90, 197, 176, 2, 191, 127, 198, 48, 16, 168, 243, 41, 195, 50, 175, 33, 172, 92, 185, 254, 96, 221, 65, 24, 36, 187, 10, 104, 242, 101, 185, 176, 206, 215, 166, 82, 189, 245, 208, 62, 38, 207, 97, 192, 45, 46, 98, 66, 201, 69, 95, 206, 211, 204, 225, 137, 204, 100, 110, 58, 84, 29, 112, 144, 51, 15, 1, 170, 79, 41, 239, 77, 1, 208, 209, 80, 208, 214, 27, 168, 153, 229, 188, 40, 250, 13, 240, 23, 96, 54, 235, 23, 202, 165, 215, 109, 143, 163, 161, 136, 101, 109, 98, 102, 54, 231, 141, 157, 22, 5, 201, 89, 10, 241, 113, 225, 185, 234, 128, 212, 206, 186, 59, 114, 79, 69, 43, 171, 208, 219, 63, 219, 112, 54, 77, 156, 116, 150, 140, 113, 186, 79, 131, 109, 231, 205, 170, 253, 131, 97, 141, 107, 242, 5, 238, 167, 32, 135, 194, 143, 151, 71, 22, 81, 254, 84, 120, 103, 131, 61, 86, 126, 66, 51, 201, 0, 170, 70, 18, 38, 152, 225, 3, 117, 98, 100, 141, 114, 39, 161, 189, 146, 148, 43, 55, 189, 18, 157, 181, 185, 7, 117, 77, 56, 229, 91, 80, 233, 79, 165, 140, 24, 98, 197, 130, 50, 70, 44, 111, 230, 241, 92, 204, 246, 78, 19, 18, 231, 219, 201, 207, 84, 205, 137, 138, 113, 45, 4, 72, 145, 204, 3, 86, 230, 200, 208, 166, 218, 183, 217, 21, 89, 23, 40, 107, 161, 68, 230, 96, 236, 91, 106, 15, 38, 255, 132, 13, 248, 98, 106, 177, 223, 54, 247, 114, 82, 147, 161, 42, 43, 10, 192, 12, 94, 200, 248, 200, 85, 231, 247, 246, 201, 221, 180, 217, 113, 12, 222, 88, 53, 21, 6, 26, 214, 220, 152, 253, 92, 56, 158, 17, 233, 218, 95, 234, 91, 97, 71, 148, 11, 3, 226, 199, 250, 201, 132, 92, 244, 18, 210, 248, 212, 89, 182, 96, 73, 121, 250, 222, 59, 121, 118, 19, 28, 221, 126, 48, 119, 190, 217, 72, 194, 91, 4, 213, 17, 137, 34, 246, 7, 6, 143, 245, 97, 192, 252, 55, 145, 82, 10, 77, 111, 31, 80, 74, 156, 14, 68, 111, 82, 76, 168, 203, 9, 220, 54, 233, 175, 186, 169, 104, 243, 2, 143, 109, 213, 247, 163, 196, 181, 37, 16, 50, 218, 28, 129, 118, 162, 187, 98, 202, 226, 244, 39, 27, 90, 255, 235, 125, 98, 206, 155, 179, 211, 58, 135, 80, 97, 220, 32, 136, 18, 226, 60, 251, 51, 170, 165, 47, 4, 63, 160, 41, 105, 85, 23, 122, 32, 145, 69, 85, 159, 147, 73, 209, 201, 169, 25, 225, 164, 6, 151, 92, 9, 223, 55, 137, 202, 67, 221, 100, 161, 248, 10, 209, 195, 27, 146, 4, 219, 227, 190, 203, 134, 228, 10, 160, 34, 221, 250, 110, 203, 33, 186, 60, 136, 185, 235, 72, 45, 105, 176, 161, 36, 169, 185, 174, 168, 146, 23, 57, 128, 198, 162, 194, 197, 62, 254, 102, 200, 154, 140, 98, 40, 208, 128, 95, 151, 77, 40, 190, 88, 75, 156, 47, 207, 220, 11, 125, 159, 24, 89, 142, 60, 2, 156, 25, 44, 203, 39, 222, 166, 122, 93, 215, 91, 87, 57, 199, 69, 211, 244, 140, 241, 106, 43, 193, 10, 150, 65, 226, 163, 202, 165, 155, 93, 219, 207, 28, 174, 157, 201, 199, 169, 174, 28, 36, 117, 106, 155, 87, 209, 223, 171, 104, 72, 76, 180, 101, 196, 248, 163, 252, 150, 33, 224, 118, 128, 130, 145, 211, 28, 80, 17, 174, 33, 156, 108, 139, 120, 225, 111, 9, 46, 228, 79, 112, 121, 35, 181, 170, 12, 131, 173, 169, 4, 40, 8, 101, 34, 154, 227, 200, 57, 50, 118, 220, 128, 21, 208, 62, 131, 68, 193, 52, 163, 35, 96, 45, 225, 26, 219, 50, 194, 44, 22, 181, 83, 21, 82, 35, 100, 10, 241, 218, 12, 104, 240, 254, 190, 54, 48, 213, 87, 65, 183, 27, 232, 23, 246, 169, 179, 164, 55, 66, 70, 219, 7, 214, 128, 58, 244, 120, 52, 255, 213, 170, 81, 235, 16, 46, 18, 229, 186, 139, 118, 127, 12, 74, 173, 106, 171, 161, 3, 108, 3, 113, 211, 2, 88, 90, 227, 202, 196, 195, 69, 88, 168, 40, 87, 247, 210, 5, 26, 117, 159, 42, 3, 73, 148, 247, 236, 110, 16, 236, 169, 179, 22, 198, 32, 79, 138, 96, 70, 6, 161, 27, 71, 155, 241, 112, 60, 188, 51, 134, 154, 0, 207, 203, 43, 102, 88, 180, 139, 239, 72, 26, 46, 174, 76, 65, 14, 135, 202, 211, 124, 201, 4, 227, 40, 119, 46, 102, 23, 71, 143, 167, 164, 77, 192, 135, 16, 27, 148, 127, 123, 191, 209, 160, 49, 93, 138, 94, 161, 181, 205, 80, 80, 33, 73, 203, 45, 36, 194, 173, 86, 7, 234, 200, 138, 20, 62, 20, 110, 84, 16, 238, 207, 123, 175, 233, 40, 135, 51, 85, 136, 64, 204, 198, 207, 151, 162, 133, 207, 58, 246, 187, 201, 91, 185, 76, 46, 209, 173, 153, 71, 158, 241, 109, 66, 129, 109, 19, 70, 30, 186, 76, 249, 125, 197, 243, 223, 219, 16, 93, 134, 232, 59, 188, 42, 4, 155, 129, 236, 145, 166, 244, 222, 103, 3, 166, 145, 150, 57, 129, 19, 253, 157, 242, 66, 97, 165, 107, 87, 180, 245, 247, 47, 19, 34, 135, 219, 94, 76, 118, 156, 247, 148, 44, 142, 164, 20, 184, 96, 179, 138, 54, 39, 212, 235, 96, 215, 39, 45, 51, 215, 39, 47, 119, 120, 22, 197, 166, 158, 26, 115, 21, 16, 110, 23, 166, 132, 209, 232, 103, 248, 200, 133, 238, 224, 13, 50, 110, 33, 211, 154, 5, 239, 137, 226, 87, 131, 152, 225, 59, 208, 49, 204, 237, 81, 149, 34, 167, 46, 181, 121, 110, 31, 108, 226, 10, 80, 6, 47, 84, 180, 176, 86, 70, 171, 221, 85, 143, 172, 227, 120, 229, 75, 140, 133, 195, 176, 173, 92, 82, 179, 97, 115, 116, 236, 224, 70, 44, 166, 206, 23, 99, 0, 213, 47, 203, 153, 221, 178, 246, 196, 30, 74, 208, 100, 245, 85, 136, 132, 6, 213, 73, 199, 248, 61, 206, 141, 74, 61, 100, 181, 157, 51, 131, 95, 116, 217, 218, 162, 32, 136, 10, 115, 221, 65, 16, 223, 19, 163, 172, 73, 140, 97, 69, 67, 199, 116, 137, 251, 188, 106, 68, 78, 25, 225, 202, 40, 117, 161, 114, 10, 208, 29, 48, 217, 82, 234, 75, 134, 156, 9, 253, 241, 144, 22, 186, 139, 101, 111, 37, 72, 95, 33, 177, 20, 246, 210, 132, 1, 255, 84, 153, 171, 140, 222, 57, 86, 34, 181, 228, 39, 13, 158, 35, 57, 113, 16, 61, 97, 111, 39, 48, 192, 88, 102, 201, 83, 73, 113, 227, 116, 20, 73, 169, 135, 107, 8, 96, 250, 23, 25, 242, 51, 166, 29, 160, 169, 43, 239, 90, 254, 198, 209, 54, 249, 31, 217, 23, 118, 57, 192, 20, 69, 77, 50, 24, 34, 190, 166, 28, 181, 49, 126, 222, 133, 171, 0, 85, 212, 226, 94, 35, 11, 186, 253, 42, 162, 231, 111, 41, 53, 21, 0, 196, 211, 17, 73, 180, 211, 43, 10, 11, 169, 42, 217, 100, 220, 106, 211, 8, 68, 44, 65, 124, 214, 103, 198, 30, 191, 25, 71, 54, 175, 38, 179, 199, 70, 138, 97, 108, 255, 138, 125, 40, 227, 161, 76, 237, 137, 181, 151, 130, 199, 147, 50, 202, 63, 204, 201, 210, 176, 96, 34, 56, 67, 123, 183, 1, 76, 154, 235, 179, 216, 12, 117, 188, 46, 156, 252, 113, 160, 233, 197, 85, 136, 30, 248, 140, 12, 94, 134, 65, 86, 195, 234, 246, 91, 169, 22, 246, 179, 50, 9, 114, 221, 181, 117, 75, 248, 250, 178, 13, 27, 17, 253, 242, 46, 217, 38, 173, 41, 199, 29, 74, 40, 35, 68, 210, 208, 58, 180, 133, 244, 138, 113, 207, 34, 225, 122, 92, 111, 221, 183, 24, 150, 49, 7, 21, 66, 56, 58, 165, 114, 83, 27, 31, 48, 14, 6, 160, 66, 45, 64, 87, 184, 7, 29, 123, 248, 231, 76, 1, 133, 82, 122, 54, 198, 43, 143, 135, 5, 173, 90, 234, 193, 11, 13, 158, 200, 210, 235, 34, 16, 147, 34, 12, 162, 125, 17, 42, 120, 178, 254, 70, 247, 98, 239, 253, 121, 6, 228, 136, 142, 224, 84, 181, 244, 122, 130, 165, 247, 26, 40, 7, 194, 75, 69, 109, 154, 8, 69, 73, 19, 187, 93, 141, 133, 163, 142, 102, 230, 167, 64, 60, 82, 140, 73, 205, 221, 44, 139, 106, 67, 75, 232, 192, 201, 199, 198, 3, 138, 228, 140, 161, 212, 57, 55, 51, 94, 38, 89, 225, 92, 37, 239, 56, 35, 50, 203, 123, 145, 140, 62, 37, 78, 17, 223, 236, 211, 3, 152, 48, 200, 73, 18, 202, 203, 100, 185, 171, 51, 254, 143, 39, 141, 125, 28, 236, 179, 45, 234, 126, 20, 65, 174, 97, 241, 242, 45, 63, 49, 10, 137, 234, 137, 186, 225, 132, 36, 54, 195, 173, 21, 185, 163, 118, 125, 244, 66, 172, 145, 124, 242, 5, 21, 230, 51, 165, 24, 71, 157, 116, 172, 183, 147, 176, 148, 136, 88, 84, 10, 83, 22, 173, 67, 228, 17, 37, 136, 248, 234, 77, 233, 145, 111, 253, 31, 77, 212, 111, 222, 215, 46, 77, 29, 10, 192, 121, 17, 173, 70, 252, 53, 136, 16, 177, 162, 28, 113, 124, 181, 146, 235, 248, 80, 80, 242, 94, 21, 192, 162, 236, 21, 163, 244, 217, 15, 167, 84, 195, 43, 216, 220, 177, 69, 99, 35, 58, 217, 252, 195, 102, 13, 196, 105, 6, 217, 48, 209, 199, 143, 139, 51, 227, 180, 80, 148, 206, 183, 153, 31, 245, 60, 182, 205, 199, 153, 244, 232, 251, 209, 169, 42, 163, 67, 217, 181, 27, 57, 115, 107, 78, 192, 254, 236, 183, 230, 114, 42, 155, 19, 142, 83, 207, 172, 53, 20, 250, 2, 150, 37, 214, 186, 35, 8, 179, 170, 90, 214, 160, 218, 251, 130, 197, 24, 191, 23, 236, 227, 157, 3, 96, 32, 168, 173, 248, 215, 41, 14, 14, 80, 134, 34, 65, 108, 106, 46, 195, 150, 150, 123, 103, 56, 121, 202, 213, 107, 245, 191, 129, 192, 40, 90, 5, 30, 100, 119, 156, 208, 22, 206, 119, 48, 69, 54, 22, 230, 217, 97, 167, 114, 105, 155, 188, 78, 3, 170, 226, 209, 167, 147, 154, 90, 126, 193, 12, 253, 228, 165, 3, 31, 102, 106, 2, 235, 18, 39, 152, 173, 182, 194, 126, 183, 114, 202, 209, 32, 68, 98, 99, 185, 55, 21, 116, 89, 224, 79, 160, 166, 171, 39, 179, 173, 146, 79, 167, 36, 75, 195, 22, 248, 177, 97, 122, 14, 86, 234, 99, 20, 138, 252, 2, 31, 47, 191, 187, 136, 224, 233, 172, 28, 59, 77, 231, 124, 86, 67, 25, 9, 222, 119, 157, 29, 30, 166, 111, 107, 138, 153, 254, 26, 105, 243, 91, 208, 2, 249, 188, 40, 34, 138, 91, 32, 171, 246, 64, 57, 7, 145, 243, 155, 93, 228, 228, 158, 94, 185, 149, 63, 236, 176, 186, 35, 145, 171, 209, 213, 214, 1, 158, 143, 185, 33, 248, 84, 1, 91, 201, 0, 174, 112, 52, 165, 202, 24, 20, 234, 125, 255, 142, 35, 138, 21, 87, 157, 40, 87, 150, 222, 226, 114, 119, 127, 190, 123, 25, 10, 175, 20, 66, 35, 8, 253, 203, 17, 79, 239, 79, 49, 92, 111, 62, 64, 94, 150, 95, 50, 246, 19, 78, 89, 247, 4, 25, 146, 142, 201, 101, 137, 36, 179, 93, 80, 158, 144, 34, 248, 173, 20, 245, 180, 30, 132, 241, 10, 120, 205, 10, 200, 119, 195, 193, 48, 205, 143, 48, 53, 155, 242, 50, 99, 181, 154, 182, 44, 243, 5, 18, 121, 140, 60, 56, 141, 213, 156, 158, 122, 28, 125, 42, 152, 83, 47, 132, 16, 54, 246, 164, 123, 68, 237, 151, 20, 161, 128, 24, 251, 153, 36, 9, 100, 227, 235, 15, 204, 33, 69, 90, 175, 71, 200, 215, 24, 28, 136, 123, 224, 112, 205, 183, 171, 130, 119, 157, 87, 155, 55, 89, 50, 121, 143, 12, 118, 51, 131, 109, 111, 39, 194, 206, 119, 150, 89, 9, 199, 86, 88, 207, 32, 241, 141, 106, 11, 19, 241, 140, 74, 19, 241, 116, 186, 224, 216, 139, 83, 35, 186, 189, 122, 64, 168, 121, 63, 182, 101, 232, 152, 96, 4, 162, 191, 152, 73, 12, 240, 55, 51, 112, 218, 216, 129, 30, 39, 49, 209, 132, 24, 140, 22, 17, 216, 218, 120, 221, 248, 40, 169, 24, 78, 198, 219, 99, 86, 225, 233, 255, 239, 118, 13, 44, 190, 145, 152, 207, 101, 102, 168, 204, 212, 179, 109, 54, 101, 48, 155, 91, 170, 10, 87, 131, 49, 95, 165, 199, 62, 162, 187, 239, 186, 7, 225, 128, 178, 201, 39, 223, 213, 194, 202, 65, 216, 188, 204, 161, 53, 103, 200, 108, 56, 119, 205, 152, 227, 105, 8, 55, 99, 100, 226, 227, 206, 104, 172, 249, 126, 39, 185, 1, 243, 134, 226, 104, 36, 176, 242, 51, 27, 83, 252, 250, 219, 2, 201, 197, 64, 156, 102, 171, 172, 59, 35, 60, 154, 112, 32, 14, 252, 78, 91, 162, 54, 139, 223, 154, 97, 157, 236, 49, 33, 253, 67, 60, 100, 127, 204, 83, 235, 7, 217, 215, 136, 85, 76, 172, 161, 180, 54, 61, 43, 187, 207, 125, 50, 157, 246, 96, 159, 203, 17, 61, 26, 184, 206, 206, 232, 73, 32, 222, 252, 64, 156, 78, 140, 41, 121, 73, 222, 133, 72, 98, 45, 161, 172, 42, 230, 164, 248, 139, 255, 140, 84, 5, 244, 131, 158, 185, 177, 5, 27, 201, 68, 69, 37, 32, 11, 79, 15, 218, 201, 41, 61, 220, 82, 102, 143, 137, 93, 161, 93, 184, 133, 140, 9, 118, 220, 217, 184, 157, 227, 184, 1, 219, 35, 183, 183, 154, 195, 123, 59, 124, 166, 251, 151, 248, 83, 199, 158, 163, 206, 4, 131, 32, 69, 137, 93, 52, 213, 84, 219, 225, 85, 146, 26, 21, 122, 138, 108, 189, 93, 29, 36, 19, 127, 185, 251, 186, 134, 1, 139, 130, 148, 24, 147, 113, 153, 18, 156, 113, 220, 136, 99, 207, 16, 224, 118, 5, 125, 247, 223, 187, 255, 176, 45, 225, 100, 65, 230, 94, 247, 106, 236, 139, 48, 170, 135, 188, 110, 72, 245, 77, 229, 119, 121, 221, 117, 80, 161, 11, 83, 111, 104, 7, 16, 215, 200, 76, 70, 30, 235, 109, 255, 108, 51, 22, 39, 118, 166, 185, 10, 201, 25, 135, 139, 123, 47, 231, 94, 237, 44, 205, 224, 101, 159, 219, 52, 75, 219, 117, 127, 94, 37, 98, 166, 26, 218, 182, 135, 79, 97, 128, 47, 80, 11, 129, 232, 199, 73, 238, 20, 96, 73, 8, 13, 246, 150, 113, 16, 93, 29, 63, 99, 184, 127, 48, 184, 15, 201, 41, 8, 73, 20, 254, 186, 190, 85, 57, 106, 219, 50, 222, 245, 19, 1, 224, 126, 204, 176, 212, 46, 202, 253, 246, 139, 139, 157, 165, 224, 100, 16, 48, 50, 146, 146, 189, 215, 105, 250, 219, 7, 105, 27, 195, 58, 185, 223, 24, 132, 199, 121, 183, 28, 15, 242, 170, 196, 120, 116, 16, 197, 209, 226, 57, 221, 6, 20, 154, 98, 50, 100, 209, 68, 35, 57, 77, 168, 139, 101, 179, 73, 182, 158, 237, 54, 140, 39, 181, 108, 154, 139, 112, 185, 112, 88, 51, 125, 93, 26, 202, 77, 157, 48, 88, 66, 74, 64, 55, 153, 78, 123, 156, 171, 59, 43, 11, 142, 249, 137, 25, 136, 219, 244, 210, 117, 44, 156, 136, 80, 224, 236, 213, 190, 71, 252, 135, 37, 95, 7, 5, 28, 172, 241, 27, 217, 140, 19, 42, 138, 107, 71, 12, 75, 179, 112, 29, 129, 191, 9, 141, 179, 255, 1, 162, 7, 118, 105, 47, 49, 105, 44, 20, 86, 185, 2, 125, 146, 241, 159, 105, 176, 221, 115, 213, 14, 66, 202, 95, 250, 213, 43, 248, 176, 4, 46, 39, 84, 19, 186, 80, 242, 53, 182, 156, 3, 43, 8, 79, 88, 156, 127, 11, 247, 179, 199, 208, 251, 37, 217, 22, 207, 191, 128, 53, 160, 16, 159, 197, 19, 214, 240, 29, 193, 212, 73, 191, 244, 27, 189, 229, 99, 251, 254, 50, 42, 191, 199, 15, 149, 141, 81, 60, 25, 135, 120, 231, 40, 84, 127, 59, 150, 127, 45, 154, 135, 124, 109, 252, 186, 204, 98, 148, 162, 133, 10, 234, 232, 152, 88, 216, 54, 242, 206, 78, 160, 12, 78, 10, 228, 2, 238, 50, 9, 230, 116, 204, 206, 160, 9, 199, 12, 12, 224, 13, 153, 81, 51, 253, 140, 197, 148, 47, 192, 14, 187, 255, 216, 110, 141, 198, 35, 212, 244, 67, 77, 48, 87, 46, 46, 113, 205, 220, 81, 105, 109, 9, 248, 194, 100, 71, 187, 160, 9, 221, 178, 176, 119, 196, 36, 136, 12, 68, 34, 113, 221, 250, 250, 4, 251, 20, 137, 70, 241, 172, 178, 185, 214, 23, 55, 196, 31, 160, 76, 214, 230, 139, 192, 144, 120, 188, 225, 215, 132, 33, 105, 178, 83, 69, 92, 192, 112, 123, 221, 34, 7, 73, 145, 233, 56, 12, 67, 106, 152, 77, 143, 77, 217, 102, 6, 199, 53, 14, 162, 12, 134, 91, 59, 169, 181, 18, 47, 11, 206, 69, 65, 66, 27, 160, 98, 149, 22, 24, 53, 196, 119, 231, 84, 211, 246, 231, 218, 99, 120, 197, 151, 30, 153, 192, 120, 253, 70, 234, 253, 239, 34, 74, 6, 233, 149, 155, 214, 12, 127, 57, 92, 225, 201, 233, 116, 48, 226, 94, 159, 212, 78, 222, 99, 116, 29, 187, 3, 59, 167, 68, 108, 162, 146, 125, 6, 178, 230, 60, 158, 60, 85, 94, 113, 93, 2, 75, 195, 234, 66, 200, 148, 128, 50, 56, 58, 205, 79, 226, 11, 189, 189, 88, 32, 67, 83, 84, 188, 31, 180, 79, 252, 9, 177, 199, 53, 163, 66, 54, 110, 245, 174, 113, 225, 204, 180, 149, 6, 141, 18, 250, 150, 168, 229, 99, 107, 110, 108, 63, 70, 43, 146, 216, 64, 42, 3, 227, 146, 223, 233, 6, 140, 108, 238, 21, 245, 70, 14, 152, 92, 109, 138, 104, 200, 195, 248, 125, 230, 8, 4, 138, 125, 228, 221, 225, 98, 146, 230, 91, 225, 247, 207, 29, 112, 185, 202, 157, 218, 18, 193, 45, 54, 47, 215, 162, 29, 92, 95, 13, 88, 40, 129, 1, 150, 106, 203, 117, 76, 176, 157, 169, 61, 45, 201, 67, 35, 238, 149, 21, 174, 50, 162, 150, 120, 22, 144, 195, 187, 214, 239, 178, 231, 165, 200, 167, 170, 107, 98, 242, 205, 72, 113, 166, 163, 6, 197, 57, 210, 106, 231, 192, 17, 112, 77, 83, 171, 216, 127, 73, 143, 182, 224, 111, 104, 137, 123, 119, 52, 153, 42, 205, 161, 145, 174, 167, 38, 117, 130, 82, 31, 228, 102, 234, 30, 199, 194, 207, 73, 109, 64, 231, 55, 221, 65, 225, 203, 28, 113, 2, 120, 201, 22, 125, 211, 76, 82, 58, 75, 181, 33, 121, 189, 138, 70, 122, 155, 252, 133, 51, 35, 241, 193, 121, 148, 48, 44, 155, 123, 240, 9, 169, 145, 15, 79, 213, 180, 160, 30, 198, 225, 209, 186, 124, 186, 53, 240, 246, 13, 188, 52, 211, 221, 181, 212, 140, 143, 187, 178, 11, 181, 202, 78, 50, 55, 119, 228, 113, 120, 231, 184, 165, 122, 121, 94, 181, 222, 248, 225, 204, 245, 174, 205, 63, 219, 192, 246, 82, 101, 109, 115, 160, 153, 82, 131, 38, 219, 229, 58, 114, 205, 138, 141, 137, 237, 89, 94, 245, 84, 177, 166, 0, 38, 16, 173, 56, 248, 67, 55, 114, 252, 89, 251, 146, 93, 24, 104, 113, 181, 37, 164, 37, 158, 96, 137, 191, 214, 21, 51, 215, 58, 123, 111, 161, 116, 157, 112, 211, 188, 210, 52, 105, 219, 91, 213, 191, 133, 171, 47, 102, 174, 51, 170, 180, 10, 30, 181, 17, 43, 76, 13, 242, 136, 41, 45, 155, 24, 45, 79, 146, 218, 6, 107, 47, 142, 32, 141, 94, 165, 12, 149, 84, 170, 122, 202, 67, 130, 126, 39, 129, 244, 187, 19, 227, 22, 108, 234, 94, 98, 61, 155, 251, 228, 212, 43, 37, 254, 81, 222, 41, 67, 5, 225, 124, 53, 203, 111, 24, 212, 64, 17, 85, 194, 255, 56, 190, 115, 192, 203, 55, 170, 152, 187, 166, 116, 85, 66, 167, 213, 247, 129, 15, 118, 86, 104, 224, 195, 108, 109, 6, 200, 191, 34, 138, 117, 74, 182, 209, 18, 204, 182, 139, 184, 27, 107, 175, 14, 145, 155, 197, 251, 53, 141, 209, 98, 130, 230, 2, 91, 91, 90, 254, 131, 252, 91, 85, 39, 212, 73, 90, 57, 184, 144, 26, 163, 6, 32, 243, 234, 162, 234, 236, 167, 234, 73, 113, 50, 77, 165, 129, 122, 211, 6, 34, 194, 184, 29, 135, 226, 91, 114, 14, 96, 246, 243, 22, 200, 242, 220, 174, 227, 244, 168, 199, 197, 55, 114, 62, 215, 172, 58, 60, 82, 41, 205, 8, 107, 253, 62, 108, 122, 249, 78, 137, 39, 167, 14, 35, 153, 136, 62, 193, 211, 120, 49, 237, 232, 22, 215, 190, 132, 161, 250, 249, 174, 253, 90, 93, 210, 35, 222, 35, 62, 60, 204, 107, 63, 198, 121, 147, 68, 213, 75, 49, 50, 3, 5, 74, 30, 92, 119, 11, 223, 133, 222, 29, 233, 248, 93, 87, 194, 139, 84, 52, 214, 44, 146, 19, 241, 82, 204, 163, 154, 253, 130, 159, 88, 148, 116, 207, 29, 114, 117, 150, 154, 24, 81, 78, 95, 1, 208, 84, 197, 172, 141, 3, 107, 18, 192, 120, 196, 91, 30, 82, 90, 232, 163, 10, 142, 96, 198, 62, 126, 212, 153, 100, 207, 146, 122, 233, 92, 188, 147, 27, 9, 102, 204, 119, 209, 242, 71, 222, 108, 114, 249, 173, 59, 14, 67, 26, 104, 240, 136, 199, 70, 131, 39, 134, 18, 1, 152, 79, 224, 130, 104, 195, 179, 215, 90, 186, 244, 238, 12, 90, 181, 145, 75, 238, 84, 158, 111, 63, 187, 121, 152, 132, 167, 150, 138, 62, 203, 40, 70, 138, 154, 210, 37, 50, 226, 69, 253, 143, 26, 0, 243, 131, 5, 139, 79, 48, 48, 115, 122, 61, 71, 41, 1, 232, 239, 4, 96, 74, 209, 253, 128, 224, 222, 158, 97, 150, 16, 30, 132, 240, 199, 197, 118, 13, 71, 56, 160, 190, 35, 215, 110, 165, 254, 26, 69, 43, 195, 163, 30, 245, 138, 48, 80, 140, 245, 89, 83, 165, 65, 39, 20, 83, 115, 119, 111, 90, 202, 101, 172, 91, 178, 35, 17, 120, 45, 118, 91, 60, 189, 180, 133, 34, 19, 137, 152, 143, 16, 186, 214, 4, 46, 242, 23, 179, 229, 204, 55, 218, 22, 188, 5, 222, 140, 69, 195, 43, 31, 34, 159, 131, 53, 28, 83, 208, 158, 112, 163, 16, 61, 175, 3, 69, 113, 134, 174, 21, 125, 162, 91, 182, 251, 120, 17, 94, 100, 252, 199, 118, 35, 248, 64, 206, 179, 38, 121, 176, 84, 197, 9, 2, 45, 111, 244, 161, 250, 199, 130, 208, 167, 250, 0, 155, 57, 0, 95, 39, 206, 237, 5, 23, 58, 142, 137, 77, 164, 152, 219, 94, 57, 237, 16, 219, 119, 57, 58, 101, 189, 104, 205, 228, 28, 237, 119, 143, 99, 241, 5, 160, 115, 91, 215, 246, 198, 153, 60, 186, 64, 248, 126, 67, 56, 155, 179, 55, 102, 3, 47, 68, 145, 41, 209, 45, 148, 106, 11, 71, 191, 171, 245, 33, 6, 133, 216, 1, 109, 128, 56, 120, 247, 17, 169, 150, 173, 61, 111, 0, 65, 2, 95, 229, 63, 59, 185, 148, 213, 149, 140, 190, 57, 151, 163, 73, 9, 231, 250, 76, 126, 211, 12, 175, 14, 38, 146, 30, 102, 22, 124, 58, 137, 239, 181, 99, 176, 2, 184, 48, 196, 132, 248, 140, 90, 194, 95, 6, 90, 242, 171, 254, 189, 235, 8, 68, 244, 115, 89, 217, 10, 61, 172, 252, 75, 186, 117, 212, 216, 62, 253, 98, 156, 233, 96, 139, 55, 91, 251, 168, 221, 67, 231, 18, 140, 250, 38, 232, 143, 65, 220, 234, 129, 106, 184, 63, 171, 119, 96, 32, 9, 45, 151, 74, 71, 81, 162, 109, 58, 194, 125, 191, 169, 244, 9, 190, 37, 38, 98, 36, 238, 176, 38, 150, 30, 227, 0, 191, 60, 189, 0, 4, 178, 196, 238, 182, 233, 8, 126, 14, 236, 73, 100, 16, 150, 49, 26, 104, 152, 197, 132, 53, 229, 100, 196, 206, 7, 74, 91, 143, 23, 206, 120, 252, 52, 73, 161, 148, 41, 160, 137, 29, 207, 222, 13, 128, 144, 191, 162, 60, 24, 226, 187, 250, 73, 76, 246, 240, 31, 254, 109, 144, 102, 248, 207, 215, 44, 182, 29, 202, 54, 141, 107, 124, 239, 205, 243, 54, 158, 0, 148, 202, 98, 65, 233, 201, 60, 169, 34, 64, 81, 62, 205, 225, 228, 233, 250, 23, 146, 53, 104, 120, 68, 71, 179, 26, 156, 230, 25, 225, 235, 138, 20, 196, 223, 72, 176, 237, 67, 107, 202, 211, 32, 31, 184, 26, 178, 64, 134, 225, 115, 8, 227, 9, 200, 33, 31, 31, 58, 82, 251, 249, 54, 46, 60, 12, 233, 66, 222, 144, 243, 111, 110, 25, 117, 77, 108, 223, 211, 209, 23, 78, 162, 154, 77, 84, 251, 166, 89, 207, 45, 78, 51, 85, 18, 51, 14, 56, 9, 131, 186, 111, 229, 230, 11, 197, 196, 201, 184, 134, 147, 52, 14, 185, 145, 14, 9, 164, 157, 82, 3, 252, 42, 244, 140, 207, 189, 77, 13, 232, 248, 139, 10, 137, 30, 189, 91, 92, 202, 63, 249, 97, 212, 139, 39, 155, 251, 253, 10, 249, 13, 115, 238, 203, 112, 147, 186, 185, 46, 239, 51, 143, 148, 251, 163, 208, 254, 121, 240, 243, 22, 162, 47, 196, 44, 249, 0, 59, 127, 144, 82, 11, 69, 124, 76, 131, 231, 236, 169, 97, 172, 168, 157, 24, 17, 61, 108, 229, 182, 153, 0, 196, 23, 118, 40, 70, 167, 178, 79, 47, 113, 75, 93, 46, 135, 148, 121, 57, 20, 150, 28, 66, 210, 141, 142, 91, 131, 112, 239, 188, 35, 5, 181, 128, 2, 59, 120, 6, 228, 206, 130, 132, 104, 30, 219, 147, 82, 12, 48, 9, 98, 51, 34, 196, 135, 236, 115, 178, 10, 25, 8, 205, 28, 231, 140, 199, 224, 224, 162, 123, 88, 194, 202, 218, 116, 49, 233, 137, 112, 72, 235, 157, 125, 137, 74, 132, 49, 69, 232, 249, 247, 241, 47, 8, 112, 5, 72, 138, 149, 121, 2, 148, 204, 93, 231, 44, 129, 140, 149, 206, 104, 37, 208, 181, 86, 67, 122, 167, 114, 166, 200, 134, 180, 179, 139, 120, 16, 106, 171, 93, 58, 179, 175, 179, 244, 148, 36, 83, 171, 157, 182, 146, 111, 22, 0, 144, 110, 105, 47, 90, 236, 177, 47, 44, 35, 250, 237, 111, 141, 89, 6, 186, 22, 196, 32, 166, 23, 143, 17, 96, 127, 58, 139, 137, 29, 250, 164, 52, 141, 1, 13, 117, 82, 93, 241, 254, 120, 139, 165, 1, 114, 105, 7, 135, 180, 57, 252, 202, 233, 69, 253, 38, 11, 88, 223, 17, 203, 64, 162, 170, 127, 59, 163, 90, 8, 58, 149, 20, 214, 159, 26, 160, 120, 244, 123, 91, 203, 31, 86, 237, 20, 242, 66, 14, 182, 206, 127, 54, 119, 36, 182, 41, 129, 128, 193, 81, 19, 182, 120, 85, 23, 210, 220, 177, 202, 204, 102, 143, 81, 243, 233, 15, 67, 183, 157, 96, 122, 120, 130, 79, 154, 118, 36, 78, 152, 24, 123, 90, 86, 169, 200, 20, 29, 57, 210, 133, 16, 52, 24, 202, 20, 173, 101, 230, 61, 47, 105, 94, 244, 47, 217, 207, 87, 87, 93, 204, 138, 110, 8, 150, 200, 248, 129, 139, 134, 225, 34, 34, 150, 247, 70, 194, 144, 167, 21, 98, 161, 7, 38, 78, 3, 36, 42, 134, 161, 157, 203, 87, 34, 171, 28, 199, 64, 186, 130, 223, 103, 121, 88, 130, 50, 174, 10, 50, 79, 13, 92, 162, 99, 1, 85, 168, 122, 61, 132, 80, 85, 112, 238, 6, 179, 207, 162, 53, 16, 198, 250, 218, 206, 202, 242, 248, 31, 74, 86, 197, 133, 193, 36, 99, 133, 160, 223, 55, 36, 153, 101, 165, 188, 184, 179, 189, 36, 198, 254, 51, 199, 13, 116, 24, 10, 135, 101, 208, 166, 54, 107, 1, 166, 97, 38, 201, 45, 86, 218, 44, 163, 60, 173, 129, 69, 17, 204, 55, 85, 141, 80, 100, 88, 127, 108, 205, 65, 73, 159, 204, 216, 250, 240, 17, 121, 196, 196, 121, 46, 64, 25, 215, 88, 102, 221, 244, 35, 248, 96, 114, 66, 125, 134, 7, 83, 97, 0, 80, 166, 224, 216, 22, 213, 18, 42, 242, 126, 182, 81, 224, 10, 37, 193, 43, 174, 74, 159, 147, 58, 65, 217, 147, 110, 214, 95, 122, 174, 125, 121, 74, 66, 144, 74, 99, 52, 132, 104, 105, 139, 225, 128, 62, 1, 188, 7, 43, 185, 222, 134, 6, 216, 52, 211, 213, 83, 109, 176, 166, 152, 161, 48, 211, 124, 198, 241, 52, 237, 139, 155, 20, 233, 140, 55, 147, 68, 77, 166, 106, 81, 213, 250, 74, 125, 165, 213, 65, 147, 92, 31, 208, 242, 169, 90, 30, 239, 165, 143, 196, 85, 247, 121, 147, 38, 181, 170, 75, 30, 224, 105, 121, 27, 197, 246, 172, 39, 109, 6, 209, 42, 208, 13, 148, 153, 97, 247, 38, 168, 185, 76, 42, 102, 145, 166, 27, 242, 37, 136, 45, 245, 32, 200, 177, 225, 248, 154, 117, 172, 184, 37, 156, 208, 100, 151, 64, 16, 193, 254, 213, 205, 140, 207, 153, 64, 155, 57, 47, 237, 59, 231, 10, 130, 204, 72, 30, 17, 60, 76, 115, 161, 237, 104, 5, 38, 254, 90, 152, 208, 49, 194, 160, 243, 106, 78, 41, 251, 143, 104, 130, 180, 241, 98, 211, 238, 194, 224, 36, 242, 39, 109, 180, 67, 130, 210, 44, 8, 162, 150, 16, 76, 83, 40, 86, 97, 87, 187, 42, 50, 63, 35, 98, 192, 23, 138, 236, 90, 3, 157, 19, 5, 252, 228, 211, 239, 1, 85, 190, 54, 144, 218, 221, 184, 19, 89, 75, 138, 53, 115, 206, 31, 100, 99, 187, 80, 162, 222, 134, 167, 238, 117, 84, 36, 62, 178, 224, 147, 119, 160, 65, 244, 245, 157, 188, 184, 222, 42, 53, 188, 84, 51, 5, 22, 214, 229, 92, 249, 17, 78, 6, 79, 145, 92, 201, 53, 58, 45, 87, 90, 19, 194, 253, 18, 68, 87, 58, 48, 206, 85, 241, 173, 40, 0, 38, 75, 210, 227, 254, 150, 117, 168, 88, 41, 180, 31, 77, 239, 136, 37, 106, 222, 33, 63, 239, 217, 245, 29, 11, 255, 94, 181, 132, 91, 80, 152, 15, 224, 253, 187, 104, 191, 95, 180, 55, 108, 24, 65, 32, 27, 147, 201, 102, 102, 64, 245, 14, 196, 154, 169, 133, 191, 117, 49, 108, 75, 133, 72, 95, 48, 126, 1, 166, 187, 129, 223, 94, 96, 39, 225, 222, 196, 210, 129, 35, 24, 186, 145, 6, 173, 82, 67, 130, 97, 167, 138, 167, 57, 181, 228, 249, 247, 44, 29, 9, 140, 245, 49, 164, 210, 119, 91, 176, 15, 31, 206, 88, 229, 155, 23, 72, 114, 224, 237, 190, 194, 147, 133, 233, 170, 22, 64, 241, 162, 204, 52, 208, 138, 159, 29, 94, 25, 117, 103, 132, 232, 65, 198, 90, 183, 113, 6, 76, 52, 141, 199, 166, 170, 128, 199, 251, 60, 137, 86, 78, 52, 16, 72, 64, 112, 174, 67, 54, 73, 63, 55, 183, 30, 11, 48, 131, 7, 94, 151, 17, 166, 115, 62, 5, 221, 71, 30, 137, 35, 181, 250, 187, 68, 26, 187, 51, 202, 249, 76, 162, 63, 10, 144, 123, 119, 217, 155, 15, 214, 212, 52, 39, 208, 109, 210, 206, 230, 242, 186, 254, 170, 138, 52, 40, 130, 7, 102, 67, 28, 38, 106, 152, 122, 172, 184, 166, 81, 30, 236, 149, 213, 236, 174, 130, 140, 44, 143, 199, 9, 118, 58, 11, 30, 126, 139, 39, 128, 92, 83, 242, 207, 200, 157, 245, 147, 84, 207, 140, 120, 59, 56, 228, 145, 177, 130, 48, 139, 78, 101, 124, 42, 228, 129, 172, 14, 248, 144, 142, 189, 38, 158, 58, 85, 84, 75, 136, 180, 175, 13, 184, 0, 26, 128, 234, 151, 167, 40, 6, 163, 8, 23, 57, 69, 42, 89, 174, 50, 0, 216, 186, 166, 7, 143, 123, 95, 23, 26, 134, 127, 125, 199, 117, 26, 215, 129, 212, 119, 83, 2, 66, 96, 247, 126, 241, 49, 171, 186, 222, 146, 234, 115, 199, 123, 112, 79, 147, 53, 210, 95, 192, 166, 49, 137, 245, 80, 120, 14, 184, 242, 237, 131, 27, 141, 100, 178, 185, 54, 245, 152, 55, 243, 88, 45, 122, 48, 229, 214, 55, 118, 105, 222, 26, 189, 68, 42, 21, 34, 57, 165, 246, 109, 35, 84, 45, 76, 196, 116, 127, 88, 180, 10, 179, 103, 226, 208, 33, 91, 111, 12, 231, 221, 166, 64, 199, 93, 87, 58, 164, 108, 23, 126, 169, 216, 119, 68, 104, 24, 51, 156, 71, 175, 181, 93, 184, 124, 171, 34, 72, 115, 95, 148, 72, 166, 241, 178, 223, 36, 10, 12, 219, 50, 172, 139, 152, 26, 232, 185, 249, 95, 249, 8, 244, 20, 78, 136, 141, 145, 169, 168, 2, 208, 9, 30, 37, 50, 149, 47, 50, 17, 64, 214, 168, 32, 23, 228, 232, 31, 78, 219, 77, 8, 80, 253, 41, 79, 8, 123, 65, 234, 36, 78, 151, 23, 68, 18, 70, 10, 9, 9, 33, 142, 129, 115, 143, 191, 127, 209, 141, 202, 189, 55, 120, 16, 148, 184, 122, 178, 77, 10, 149, 18, 30, 6, 101, 53, 90, 155, 239, 253, 82, 57, 11, 125, 84, 7, 175, 116, 62, 210, 232, 112, 130, 253, 105, 153, 203, 31, 120, 251, 241, 45, 41, 127, 96, 146, 11, 187, 180, 115, 21, 63, 182, 213, 196, 175, 255, 162, 31, 233, 65, 197, 110, 42, 136, 54, 118, 234, 176, 3, 252, 83, 4, 107, 133, 19, 226, 34, 163, 232, 31, 39, 171, 178, 242, 36, 69, 64, 33, 167, 139, 81, 184, 160, 207, 119, 37, 137, 40, 165, 50, 167, 243, 188, 82, 142, 91, 2, 0, 209, 16, 166, 152, 134, 113, 185, 236, 253, 161, 120, 90, 94, 189, 81, 201, 224, 60, 66, 82, 23, 12, 199, 197, 86, 198, 16, 54, 174, 237, 121, 186, 244, 141, 50, 26, 152, 120, 78, 52, 71, 115, 40, 94, 156, 22, 162, 241, 219, 90, 212, 236, 21, 153, 170, 142, 20, 200, 251, 49, 98, 192, 173, 14, 167, 199, 167, 176, 235, 111, 61, 243, 30, 215, 35, 113, 127, 122, 250, 79, 162, 40, 130, 81, 31, 51, 177, 240, 9, 31, 192, 210, 151, 171, 78, 201, 50, 102, 227, 75, 196, 239, 232, 175, 240, 119, 205, 191, 180, 209, 68, 123, 86, 244, 114, 244, 209, 7, 35, 17, 16, 89, 133, 89, 42, 9, 18, 124, 21, 252, 101, 244, 88, 79, 214, 234, 145, 140, 52, 118, 47, 44, 121, 43, 14, 6, 157, 26, 16, 172, 252, 85, 94, 84, 59, 134, 19, 119, 10, 70, 91, 157, 246, 8, 74, 32, 15, 23, 230, 2, 205, 188, 103, 237, 92, 19, 88, 21, 147, 135, 117, 124, 107, 140, 39, 152, 51, 56, 246, 122, 153, 174, 106, 145, 140, 146, 78, 180, 243, 212, 62, 46, 3, 131, 137, 78, 56, 79, 160, 252, 117, 84, 126, 199, 194, 240, 227, 23, 188, 40, 206, 72, 68, 40, 58, 91, 183, 80, 40, 31, 65, 9, 70, 23, 34, 64, 199, 213, 138, 80, 140, 58, 202, 215, 115, 223, 92, 181, 218, 116, 252, 210, 190, 210, 54, 166, 241, 66, 132, 62, 98, 109, 158, 51, 52, 89, 69, 24, 171, 176, 235, 116, 175, 18, 111, 80, 167, 209, 170, 150, 194, 152, 23, 96, 162, 41, 244, 232, 80, 85, 76, 226, 126, 240, 196, 214, 81, 40, 183, 225, 102, 10, 166, 57, 231, 230, 232, 149, 164, 116, 112, 122, 0, 182, 53, 199, 252, 55, 50, 111, 243, 200, 64, 191, 29, 240, 86, 187, 126, 133, 121, 249, 249, 37, 58, 174, 209, 39, 152, 103, 151, 131, 127, 207, 154, 14, 188, 239, 28, 107, 33, 10, 57, 82, 158, 116, 63, 225, 29, 103, 80, 134, 84, 245, 37, 13, 1, 70, 95, 180, 82, 191, 0, 67, 243, 67, 218, 148, 30, 248, 160, 133, 92, 83, 190, 197, 251, 150, 117, 28, 178, 121, 17, 16, 209, 4, 188, 155, 55, 82, 134, 128, 3, 104, 142, 132, 144, 32, 101, 0, 223, 166, 79, 49, 108, 64, 231, 162, 6, 27, 94, 116, 68, 235, 168, 36, 115, 39, 191, 151, 28, 202, 228, 35, 90, 53, 172, 170, 173, 151, 236, 174, 197, 19, 85, 216, 192, 158, 128, 35, 6, 88, 21, 25, 158, 92, 18, 213, 22, 136, 119, 149, 124, 213, 103, 197, 6, 206, 174, 36, 196, 199, 208, 68, 57, 84, 28, 218, 251, 214, 75, 157, 254, 46, 61, 228, 188, 87, 93, 125, 155, 38, 175, 4, 36, 160, 31, 177, 70, 222, 245, 85, 246, 69, 109, 45, 77, 151, 175, 202, 23, 17, 139, 66, 77, 166, 155, 251, 82, 156, 11, 77, 102, 222, 20, 170, 255, 232, 162, 41, 73, 26, 89, 118, 58, 126, 212, 207, 108, 55, 5, 136, 150, 240, 223, 185, 103, 231, 115, 182, 189, 39, 164, 162, 182, 112, 113, 11, 93, 250, 108, 247, 231, 143, 172, 67, 223, 221, 224, 24, 116, 128, 119, 232, 143, 90, 27, 149, 49, 226, 195, 238, 66, 233, 15, 97, 137, 170, 155, 236, 124, 185, 95, 192, 121, 36, 82, 76, 249, 31, 46, 102, 185, 14, 243, 30, 244, 217, 184, 156, 156, 207, 35, 38, 89, 107, 212, 139, 75, 161, 16, 78, 232, 76, 209, 7, 92, 94, 80, 159, 58, 162, 138, 216, 206, 231, 93, 85, 198, 140, 90, 200, 170, 79, 118, 26, 52, 168, 111, 165, 224, 91, 45, 85, 42, 162, 142, 55, 0, 19, 167, 142, 86, 74, 235, 43, 230, 3, 162, 93, 33, 239, 43, 181, 253, 155, 106, 28, 48, 150, 43, 234, 102, 187, 247, 187, 40, 43, 158, 33, 48, 242, 214, 95, 182, 126, 3, 25, 218, 47, 163, 140, 217, 6, 221, 199, 57, 76, 182, 244, 110, 49, 168, 240, 129, 31, 226, 185, 35, 18, 185, 189, 2, 17, 190, 134, 137, 29, 76, 118, 48, 216, 33, 188, 103, 160, 66, 143, 23, 230, 255, 24, 238, 6, 111, 18, 214, 163, 244, 30, 36, 4, 216, 31, 162, 60, 127, 235, 203, 67, 34, 69, 20, 227, 220, 56, 107, 78, 81, 10, 160, 169, 19, 255, 211, 126, 46, 77, 46, 152, 46, 114, 135, 139, 23, 3, 172, 52, 80, 86, 11, 5, 190, 51, 86, 190, 67, 0, 75, 17, 160, 229, 12, 254, 152, 221, 3, 213, 220, 213, 244, 51, 157, 73, 251, 206, 213, 43, 113, 247, 245, 189, 52, 226, 250, 109, 212, 4, 168, 132, 24, 137, 160, 175, 219, 204, 156, 32, 253, 121, 8, 209, 200, 96, 88, 93, 66, 243, 84, 76, 148, 142, 229, 86, 31, 106, 10, 23, 136, 200, 132, 152, 150, 51, 125, 202, 13, 202, 63, 110, 38, 125, 12, 113, 17, 162, 92, 217, 24, 108, 235, 209, 81, 65, 202, 179, 60, 176, 11, 91, 62, 45, 126, 96, 9, 66, 153, 134, 11, 40, 231, 205, 66, 5, 249, 92, 99, 119, 206, 105, 108, 207, 79, 44, 61, 10, 179, 18, 7, 33, 15, 68, 204, 40, 214, 171, 223, 177, 98, 94, 176, 243, 165, 152, 231, 154, 1, 67, 226, 236, 109, 137, 202, 72, 234, 243, 23, 156, 41, 105, 118, 40, 72, 112, 147, 53, 76, 126, 158, 255, 145, 213, 214, 43, 241, 194, 125, 227, 104, 241, 196, 244, 237, 140, 214, 62, 210, 249, 207, 143, 58, 106, 182, 10, 75, 247, 114, 19, 127, 210, 217, 102, 190, 200, 149, 36, 59, 137, 204, 222, 223, 123, 63, 215, 84, 249, 49, 149, 83, 137, 205, 224, 192, 44, 166, 101, 109, 181, 98, 219, 17, 169, 186, 35, 11, 108, 131, 75, 185, 220, 58, 214, 129, 67, 15, 106, 220, 67, 76, 7, 247, 154, 201, 146, 25, 224, 51, 169, 180, 61, 73, 169, 216, 163, 64, 179, 144, 61, 184, 163, 163, 8, 113, 40, 42, 53, 46, 80, 50, 199, 156, 6, 138, 44, 86, 130, 12, 195, 251, 191, 99, 122, 127, 116, 155, 248, 205, 86, 172, 49, 197, 132, 101, 124, 32, 23, 225, 78, 252, 23, 182, 27, 10, 93, 135, 220, 98, 246, 62, 157, 134, 102, 1, 113, 244, 65, 39, 3, 106, 168, 22, 142, 16, 64, 140, 15, 80, 99, 35, 22, 179, 165, 166, 85, 100, 233, 90, 229, 18, 78, 92, 204, 255, 218, 224, 121, 218, 149, 146, 101, 90, 237, 209, 141, 172, 71, 193, 90, 175, 189, 165, 169, 88, 27, 15, 197, 225, 132, 32, 122, 215, 89, 92, 130, 175, 160, 186, 201, 20, 61, 64, 162, 133, 3, 43, 242, 1, 253, 252, 181, 136, 253, 218, 163, 130, 111, 36, 14, 133, 7, 219, 204, 145, 34, 32, 170, 193, 236, 151, 74, 74, 147, 76, 138, 107, 121, 122, 117, 158, 28, 246, 50, 255, 135, 138, 164, 17, 38, 164, 210, 75, 174, 116, 208, 146, 145, 163, 54, 161, 142, 104, 242, 253, 76, 97, 186, 92, 131, 69, 189, 217, 241, 225, 157, 78, 37, 78, 96, 220, 194, 3, 246, 214, 121, 178, 93, 26, 46, 165, 137, 4, 223, 97, 14, 94, 50, 52, 234, 50, 86, 69, 141, 165, 121, 202, 152, 37, 85, 22, 135, 212, 233, 30, 106, 208, 152, 10, 196, 23, 144, 2, 199, 18, 43, 47, 236, 83, 30, 54, 249, 7, 145, 116, 239, 36, 191, 115, 171, 101, 77, 39, 102, 167, 249, 152, 234, 193, 141, 24, 143, 254, 132, 241, 49, 221, 223, 189, 103, 12, 245, 20, 240, 213, 121, 152, 82, 69, 179, 192, 186, 6, 66, 56, 22, 22, 144, 240, 125, 87, 13, 248, 93, 108, 229, 245, 148, 14, 62, 131, 45, 100, 201, 63, 68, 118, 249, 66, 98, 132, 141, 74, 140, 20, 220, 81, 134, 141, 172, 190, 199, 149, 205, 93, 57, 45, 113, 240, 15, 161, 4, 122, 228, 28, 150, 220, 183, 88, 226, 51, 117, 6, 107, 122, 39, 165, 25, 15, 197, 199, 149, 157, 131, 214, 44, 253, 240, 247, 241, 139, 229, 232, 212, 218, 113, 23, 188, 132, 147, 250, 252, 14, 145, 7, 246, 101, 27, 190, 155, 27, 224, 20, 37, 63, 2, 54, 38, 5, 34, 186, 2, 107, 221, 161, 66, 248, 217, 63, 79, 202, 83, 53, 253, 127, 87, 252, 108, 133, 175, 14, 82, 140, 132, 150, 94, 234, 120, 120, 214, 32, 234, 53, 81, 60, 107, 255, 166, 188, 89, 153, 9, 173, 234, 85, 244, 11, 76, 217, 190, 22, 16, 147, 80, 23, 113, 126, 241, 84, 57, 134, 84, 152, 42, 97, 158, 176, 247, 138, 249, 54, 110, 103, 112, 170, 52, 238, 109, 27, 131, 137, 84, 37, 53, 162, 45, 12, 135, 228, 179, 197, 44, 163, 143, 33, 0, 125, 198, 45, 122, 93, 252, 148, 208, 163, 242, 99, 126, 195, 122, 247, 103, 141, 22, 208, 148, 113, 236, 210, 223, 57, 241, 128, 9, 40, 105, 207, 109, 69, 229, 204, 238, 98, 124, 100, 227, 17, 185, 226, 18, 119, 192, 50, 24, 98, 196, 187, 230, 224, 60, 191, 157, 41, 179, 95, 76, 153, 6, 217, 232, 93, 2, 110, 41, 148, 140, 203, 9, 156, 225, 174, 26, 16, 1, 182, 20, 242, 221, 114, 72, 21, 141, 226, 213, 200, 17, 198, 16, 100, 176, 216, 73, 240, 76, 6, 237, 78, 200, 119, 77, 39, 240, 158, 31, 148, 131, 187, 63, 232, 210, 64, 179, 250, 232, 53, 78, 40, 18, 89, 33, 39, 140, 209, 56, 112, 249, 146, 222, 7, 127, 161, 65, 146, 33, 146, 127, 56, 114, 32, 84, 80, 24, 112, 229, 230, 213, 94, 91, 148, 244, 109, 13, 157, 111, 51, 201, 173, 173, 66, 136, 150, 6, 111, 111, 154, 11, 17, 116, 13, 27, 209, 242, 59, 99, 21, 169, 222, 68, 72, 222, 164, 61, 217, 201, 53, 205, 33, 15, 141, 10, 80, 10, 215, 82, 125, 43, 165, 54, 184, 26, 151, 71, 203, 206, 50, 58, 57, 161, 52, 168, 22, 242, 179, 125, 111, 43, 91, 87, 3, 7, 126, 177, 54, 163, 148, 93, 255, 55, 124, 43, 141, 72, 166, 34, 147, 163, 135, 0, 50, 126, 152, 165, 1, 244, 118, 95, 96, 80, 4, 187, 206, 110, 239, 214, 183, 209, 125, 252, 40, 182, 126, 134, 2, 45, 182, 138, 179, 2, 102, 138, 101, 19, 92, 134, 39, 69, 120, 57, 190, 57, 130, 245, 73, 221, 23, 174, 183, 93, 28, 157, 42, 231, 217, 206, 139, 115, 38, 188, 129, 124, 12, 110, 89, 108, 132, 51, 142, 244, 135, 245, 251, 68, 128, 56, 218, 26, 248, 129, 34, 157, 167, 84, 138, 245, 95, 64, 172, 74, 9, 252, 17, 188, 73, 110, 229, 78, 230, 153, 231, 44, 191, 46, 126, 39, 241, 123, 223, 46, 47, 39, 69, 139, 118, 7, 184, 183, 166, 171, 61, 112, 200, 111, 196, 61, 123, 217, 188, 193, 102, 212, 105, 92, 0, 159, 27, 176, 74, 50, 250, 107, 68, 26, 196, 203, 239, 0, 42, 184, 35, 143, 14, 106, 172, 76, 147, 112, 100, 25, 215, 41, 170, 126, 95, 108, 218, 82, 36, 9, 116, 177, 182, 123, 254, 190, 56, 53, 125, 239, 66, 243, 145, 10, 61, 102, 57, 109, 197, 80, 159, 97, 253, 120, 48, 249, 97, 177, 2, 185, 153, 14, 201, 121, 165, 107, 133, 118, 248, 220, 68, 206, 96, 137, 154, 121, 215, 217, 189, 74, 76, 204, 222, 35, 222, 227, 83, 52, 77, 180, 122, 123, 184, 249, 212, 240, 22, 200, 136, 194, 206, 111, 120, 162, 253, 186, 155, 213, 149, 39, 97, 252, 132, 95, 70, 241, 47, 54, 19, 143, 188, 149, 148, 238, 161, 194, 121, 17, 93, 111, 133, 242, 201, 212, 183, 138, 152, 178, 37, 230, 140, 107, 137, 122, 163, 75, 5, 135, 225, 186, 32, 50, 131, 104, 197, 16, 87, 163, 180, 251, 170, 27, 181, 241, 85, 179, 126, 116, 219, 206, 79, 242, 5, 101, 41, 165, 80, 223, 66, 32, 68, 71, 88, 53, 117, 216, 209, 172, 112, 212, 129, 152, 49, 109, 61, 236, 79, 222, 156, 11, 239, 31, 202, 61, 123, 205, 58, 128, 7, 95, 27, 139, 135, 91, 119, 192, 187, 13, 99, 165, 103, 254, 140, 195, 234, 100, 79, 231, 154, 176, 233, 82, 214, 191, 60, 193, 53, 143, 213, 250, 131, 91, 40, 145, 225, 212, 106, 77, 201, 106, 185, 120, 141, 225, 195, 5, 110, 132, 235, 189, 95, 42, 90, 55, 194, 116, 222, 147, 91, 172, 175, 220, 232, 23, 95, 201, 4, 150, 102, 250, 23, 196, 86, 120, 28, 42, 188, 48, 46, 144, 66, 85, 124, 42, 187, 137, 212, 196, 230, 245, 111, 147, 204, 161, 63, 35, 100, 22, 144, 232, 208, 88, 101, 151, 10, 31, 210, 90, 1, 4, 202, 135, 120, 102, 81, 121, 189, 201, 44, 222, 209, 48, 188, 152, 108, 250, 65, 173, 13, 240, 1, 123, 109, 36, 163, 137, 172, 69, 250, 162, 10, 75, 89, 57, 102, 147, 77, 18, 93, 4, 104, 216, 225, 207, 229, 24, 57, 187, 228, 99, 218, 204, 58, 115, 44, 120, 209, 99, 200, 214, 156, 221, 139, 17, 131, 159, 164, 233, 160, 6, 2, 27, 15, 60, 204, 219, 18, 190, 164, 210, 203, 188, 34, 116, 36, 134, 101, 193, 75, 88, 189, 222, 245, 174, 203, 0, 199, 161, 57, 22, 4, 219, 77, 24, 36, 141, 70, 215, 219, 31, 92, 105, 10, 70, 102, 169, 244, 215, 230, 169, 88, 240, 157, 190, 5, 130, 186, 232, 76, 117, 45, 230, 181, 115, 67, 35, 172, 15, 165, 30, 125, 180, 57, 245, 25, 97, 244, 170, 182, 180, 107, 24, 231, 195, 140, 97, 50, 220, 220, 193, 196, 144, 49, 32, 90, 62, 206, 109, 85, 35, 135, 220, 249, 255, 78, 103, 207, 98, 156, 228, 213, 254, 22, 231, 247, 191, 152, 250, 37, 8, 172, 204, 136, 181, 30, 75, 9, 174, 226, 175, 172, 238, 237, 107, 27, 230, 46, 197, 240, 140, 162, 225, 65, 165, 249, 209, 49, 152, 19, 102, 96, 96, 206, 145, 40, 39, 155, 68, 8, 228, 176, 0, 112, 6, 27, 164, 12, 220, 185, 140, 95, 71, 202, 125, 234, 15, 246, 52, 206, 5, 103, 198, 6, 65, 12, 209, 87, 223, 121, 239, 124, 120, 128, 156, 194, 250, 239, 133, 247, 227, 76, 107, 73, 38, 228, 241, 33, 19, 61, 138, 70, 37, 45, 58, 239, 13, 176, 27, 17, 41, 202, 233, 62, 223, 175, 157, 36, 234, 192, 23, 180, 64, 61, 231, 103, 173, 83, 169, 241, 51, 201, 81, 67, 217, 79, 246, 203, 247, 233, 117, 253, 153, 252, 50, 54, 251, 120, 254, 215, 105, 168, 47, 128, 61, 139, 243, 91, 142, 166, 179, 26, 97, 65, 171, 167, 244, 114, 188, 192, 101, 23, 55, 115, 205, 222, 209, 59, 111, 83, 147, 188, 26, 163, 123, 244, 252, 98, 148, 104, 110, 81, 27, 167, 67, 200, 85, 251, 80, 163, 117, 36, 78, 137, 95, 34, 59, 163, 172, 164, 89, 247, 72, 64, 181, 41, 86, 255, 184, 158, 238, 185, 226, 70, 112, 123, 179, 3, 73, 1, 111, 110, 161, 49, 29, 112, 124, 244, 110, 238, 247, 14, 14, 76, 199, 159, 197, 179, 250, 244, 247, 85, 172, 56, 98, 70, 232, 99, 204, 226, 75, 121, 73, 239, 205, 191, 210, 74, 92, 4, 0, 234, 193, 196, 194, 173, 68, 44, 15, 40, 155, 166, 205, 197, 52, 207, 169, 123, 143, 5, 179, 234, 31, 202, 86, 56, 24, 233, 62, 121, 211, 133, 19, 209, 88, 32, 158, 85, 70, 85, 248, 249, 48, 225, 47, 86, 13, 128, 6, 140, 36, 31, 128, 58, 215, 176, 81, 129, 125, 172, 224, 209, 207, 246, 173, 207, 193, 22, 97, 60, 173, 183, 77, 253, 155, 18, 178, 36, 113, 186, 216, 70, 53, 47, 176, 176, 110, 88, 134, 81, 218, 164, 230, 45, 241, 27, 80, 100, 97, 7, 241, 118, 72, 200, 165, 187, 155, 190, 94, 40, 30, 205, 153, 71, 104, 141, 15, 220, 15, 153, 177, 200, 155, 239, 120, 101, 136, 17, 153, 255, 88, 163, 185, 221, 199, 216, 98, 69, 95, 59, 175, 164, 233, 253, 133, 225, 2, 156, 121, 93, 233, 11, 172, 164, 252, 66, 25, 59, 141, 195, 114, 131, 224, 50, 139, 227, 135, 240, 4, 171, 14, 206, 140, 207, 55, 211, 159, 135, 8, 193, 239, 233, 207, 53, 244, 238, 84, 19, 73, 1, 94, 104, 42, 148, 26, 3, 101, 198, 153, 239, 239, 34, 230, 253, 108, 6, 54, 59, 54, 252, 49, 86, 67, 90, 174, 196, 140, 239, 181, 64, 85, 11, 44, 9, 229, 249, 136, 72, 125, 199, 191, 242, 156, 145, 81, 70, 193, 44, 181, 133, 36, 211, 242, 30, 144, 244, 7, 89, 97, 98, 244, 61, 184, 3, 174, 101, 173, 221, 239, 145, 166, 225, 182, 82, 202, 76, 76, 150, 198, 93, 120, 100, 254, 47, 21, 168, 61, 38, 165, 48, 31, 76, 59, 37, 89, 106, 87, 203, 179, 248, 156, 162, 64, 50, 76, 5, 123, 113, 9, 215, 226, 23, 205, 44, 245, 117, 179, 251, 160, 106, 205, 130, 187, 253, 151, 224, 24, 32, 107, 210, 221, 62, 9, 133, 192, 119, 143, 232, 69, 204, 98, 5, 86, 121, 17, 245, 180, 249, 233, 48, 185, 56, 62, 20, 215, 140, 6, 220, 139, 44, 46, 180, 236, 215, 250, 81, 195, 254, 101, 135, 40, 135, 235, 141, 22, 183, 1, 31, 3, 89, 252, 87, 207, 58, 24, 161, 225, 28, 217, 174, 122, 71, 46, 100, 25, 85, 189, 177, 45, 185, 53, 210, 109, 222, 240, 244, 82, 75, 188, 17, 191, 45, 184, 220, 132, 105, 75, 151, 12, 5, 236, 148, 150, 10, 22, 199, 26, 143, 142, 159, 137, 87, 142, 70, 241, 67, 5, 15, 235, 87, 20, 224, 207, 210, 38, 60, 245, 34, 238, 108, 193, 204, 194, 179, 7, 131, 158, 63, 245, 255, 95, 34, 247, 63, 100, 39, 85, 51, 182, 220, 69, 125, 88, 223, 39, 160, 176, 115, 100, 232, 150, 20, 40, 205, 132, 231, 201, 97, 40, 66, 207, 53, 195, 39, 59, 4, 191, 140, 210, 66, 46, 104, 196, 64, 35, 22, 151, 210, 88, 220, 108, 96, 95, 175, 97, 70, 25, 90, 111, 112, 123, 106, 204, 22, 59, 106, 248, 232, 178, 149, 32, 36, 16, 254, 191, 202, 95, 177, 177, 116, 95, 213, 205, 170, 254, 96, 184, 233, 166, 10, 156, 95, 254, 105, 205, 55, 158, 61, 129, 215, 98, 230, 107, 3, 63, 157, 155, 207, 247, 157, 79, 254, 138, 189, 94, 248, 244, 152, 167, 111, 16, 202, 234, 81, 38, 253, 1, 180, 210, 24, 89, 184, 252, 85, 6, 35, 223, 9, 34, 83, 254, 224, 69, 138, 199, 37, 90, 24, 21, 136, 15, 51, 50, 30, 54, 216, 227, 156, 117, 242, 100, 52, 163, 89, 33, 164, 98, 17, 89, 176, 21, 155, 15, 146, 216, 86, 117, 168, 3, 121, 75, 252, 116, 80, 199, 162, 215, 74, 4, 31, 118, 186, 206, 249, 116, 221, 99, 65, 54, 33, 13, 78, 210, 35, 210, 53, 122, 190, 198, 221, 183, 134, 204, 79, 8, 25, 210, 188, 253, 85, 201, 46, 250, 3, 232, 208, 37, 12, 223, 72, 151, 148, 238, 168, 204, 252, 31, 1, 28, 118, 248, 170, 149, 73, 59, 32, 202, 101, 151, 15, 8, 189, 163, 217, 141, 150, 116, 65, 129, 166, 147, 54, 1, 66, 214, 228, 77, 76, 12, 105, 1, 82, 129, 123, 28, 50, 106, 239, 115, 189, 81, 165, 89, 64, 162, 72, 173, 162, 12, 143, 161, 42, 195, 52, 49, 79, 130, 231, 207, 125, 113, 21, 43, 184, 120, 97, 79, 162, 36, 125, 204, 253, 23, 235, 22, 87, 250, 129, 46, 51, 140, 184, 122, 5, 176, 91, 77, 121, 99, 94, 246, 217, 247, 181, 100, 190, 81, 43, 71, 97, 216, 82, 144, 50, 215, 72, 88, 136, 202, 167, 146, 20, 108, 111, 48, 8, 128, 77, 59, 179, 227, 116, 102, 106, 170, 123, 183, 150, 15, 20, 226, 177, 244, 199, 210, 225, 96, 11, 232, 230, 107, 230, 92, 88, 7, 200, 250, 162, 143, 245, 215, 194, 174, 126, 31, 145, 211, 158, 210, 125, 222, 86, 80, 105, 207, 96, 197, 240, 16, 121, 229, 16, 43, 32, 18, 97, 116, 249, 105, 53, 10, 109, 163, 226, 90, 43, 205, 27, 190, 20, 75, 5, 119, 97, 81, 100, 236, 30, 13, 42, 30, 148, 237, 225, 149, 35, 17, 17, 5, 142, 35, 250, 215, 197, 155, 17, 111, 145, 129, 53, 57, 0, 200, 249, 89, 176, 189, 1, 116, 36, 15, 140, 182, 95, 214, 143, 116, 235, 82, 165, 53, 192, 181, 183, 131, 106, 5, 142, 35, 31, 235, 177, 90, 203, 121, 167, 216, 165, 33, 47, 225, 21, 227, 222, 235, 82, 74, 195, 197, 215, 79, 205, 108, 145, 185, 88, 224, 207, 185, 43, 148, 199, 55, 206, 55, 53, 36, 83, 228, 15, 155, 240, 52, 139, 36, 169, 202, 140, 11, 148, 201, 100, 116, 5, 4, 93, 209, 255, 14, 104, 27, 30, 138, 224, 182, 136, 68, 27, 18, 127, 61, 231, 13, 79, 211, 129, 170, 83, 133, 121, 42, 201, 91, 161, 157, 93, 92, 228, 230, 85, 42, 72, 252, 142, 85, 49, 49, 90, 248, 105, 64, 101, 17, 183, 104, 71, 66, 88, 231, 243, 185, 127, 109, 96, 16, 144, 67, 137, 142, 51, 15, 176, 229, 195, 244, 121, 225, 235, 1, 47, 26, 187, 199, 29, 84, 42, 209, 192, 23, 24, 66, 139, 105, 59, 42, 98, 42, 59, 121, 42, 19, 252, 216, 83, 170, 15, 153, 227, 209, 242, 192, 84, 127, 225, 7, 106, 52, 122, 11, 197, 13, 114, 196, 194, 67, 217, 106, 201, 9, 33, 188, 44, 80, 156, 138, 13, 234, 189, 29, 240, 190, 247, 231, 194, 113, 145, 182, 63, 184, 81, 203, 88, 173, 43, 148, 126, 63, 55, 30, 179, 169, 8, 4, 211, 7, 73, 48, 152, 169, 65, 139, 239, 39, 42, 66, 67, 209, 4, 20, 102, 193, 58, 22, 155, 229, 248, 233, 99, 238, 62, 173, 71, 56, 43, 153, 129, 253, 161, 69, 87, 94, 50, 53, 1, 18, 167, 179, 253, 232, 5, 244, 180, 73, 202, 206, 199, 177, 156, 168, 144, 156, 112, 247, 187, 93, 121, 233, 149, 16, 80, 145, 67, 175, 57, 252, 185, 218, 56, 13, 0, 164, 160, 84, 19, 68, 168, 14, 89, 77, 225, 2, 14, 83, 124, 56, 55, 162, 229, 39, 196, 249, 27, 240, 90, 133, 241, 237, 79, 169, 233, 173, 143, 255, 36, 249, 166, 116, 116, 177, 216, 149, 224, 26, 64, 44, 177, 25, 5, 253, 13, 50, 65, 237, 15, 138, 43, 95, 108, 20, 129, 184, 138, 121, 110, 240, 91, 12, 102, 187, 183, 232, 196, 253, 140, 90, 174, 171, 9, 150, 159, 88, 97, 56, 227, 158, 92, 227, 209, 227, 137, 248, 248, 182, 167, 229, 110, 188, 85, 30, 74, 7, 72, 99, 106, 178, 181, 90, 248, 101, 59, 184, 64, 26, 188, 1, 76, 145, 191, 118, 78, 161, 90, 157, 108, 121, 235, 154, 90, 112, 236, 204, 226, 67, 193, 204, 136, 84, 224, 47, 165, 0, 44, 46, 226, 144, 113, 146, 133, 73, 73, 101, 61, 49, 183, 45, 136, 209, 10, 185, 207, 24, 241, 253, 134, 113, 248, 233, 113, 75, 161, 177, 2, 66, 216, 62, 176, 59, 4, 163, 90, 175, 96, 238, 243, 195, 62, 32, 61, 225, 75, 178, 126, 96, 109, 122, 231, 239, 180, 196, 203, 20, 193, 0, 203, 49, 146, 34, 127, 250, 192, 204, 89, 255, 86, 9, 155, 120, 161, 237, 64, 148, 50, 54, 120, 95, 190, 121, 93, 65, 125, 191, 202, 190, 16, 112, 191, 77, 28, 125, 90, 84, 128, 7, 218, 251, 177, 71, 144, 162, 60, 43, 217, 255, 49, 53, 101, 131, 42, 192, 64, 123, 188, 33, 217, 147, 248, 63, 75, 61, 69, 149, 248, 90, 112, 148, 132, 15, 114, 114, 66, 235, 198, 222, 166, 108, 140, 172, 248, 14, 252, 63, 158, 153, 145, 61, 115, 160, 194, 30, 202, 34, 18, 158, 139, 132, 175, 73, 77, 36, 10, 85, 156, 180, 44, 92, 245, 67, 124, 21, 55, 3, 181, 208, 16, 78, 144, 45, 150, 153, 171, 99, 203, 120, 102, 144, 205, 149, 16, 168, 245, 60, 67, 171, 105, 163, 74, 101, 197, 243, 77, 206, 187, 79, 125, 54, 232, 50, 99, 60, 209, 21, 224, 203, 240, 54, 5, 64, 190, 113, 52, 43, 114, 153, 57, 24, 246, 249, 67, 5, 116, 108, 167, 24, 152, 157, 145, 145, 184, 135, 9, 21, 19, 40, 208, 87, 254, 48, 249, 255, 162, 39, 75, 119, 20, 188, 245, 166, 23, 134, 69, 64, 7, 242, 184, 89, 17, 166, 36, 158, 76, 105, 235, 212, 75, 14, 179, 168, 51, 204, 42, 50, 187, 5, 118, 76, 173, 58, 155, 172, 195, 168, 44, 28, 129, 9, 188, 8, 114, 79, 57, 233, 150, 175, 36, 213, 59, 176, 207, 25, 10, 148, 80, 3, 116, 14, 120, 161, 233, 250, 36, 212, 116, 26, 203, 37, 129, 42, 24, 65, 190, 157, 65, 193, 132, 195, 181, 27, 125, 161, 237, 17, 53, 203, 32, 29, 134, 120, 218, 120, 84, 139, 39, 121, 244, 190, 167, 179, 165, 113, 169, 219, 31, 137, 86, 15, 43, 237, 99, 71, 43, 151, 167, 221, 182, 112, 157, 111, 40, 91, 133, 17, 87, 222, 83, 221, 39, 188, 149, 51, 45, 135, 104, 27, 148, 246, 248, 28, 160, 219, 125, 198, 41, 151, 206, 26, 167, 167, 94, 41, 105, 251, 4, 35, 251, 166, 1, 111, 156, 209, 126, 39, 93, 105, 234, 197, 64, 185, 177, 48, 182, 153, 99, 34, 27, 109, 126, 192, 183, 20, 117, 131, 209, 93, 37, 71, 96, 87, 4, 183, 52, 16, 4, 125, 12, 53, 9, 76, 104, 151, 170, 9, 186, 74, 152, 140, 173, 231, 52, 113, 11, 115, 6, 75, 62, 208, 192, 102, 71, 112, 204, 74, 206, 20, 82, 5, 153, 16, 194, 186, 179, 190, 170, 219, 251, 109, 24, 88, 223, 137, 185, 190, 217, 168, 80, 101, 210, 105, 223, 115, 124, 71, 91, 192, 48, 42, 206, 220, 14, 48, 3, 232, 99, 51, 247, 39, 146, 151, 148, 230, 92, 113, 123, 184, 124, 169, 55, 5, 249, 226, 156, 86, 81, 167, 144, 164, 169, 73, 241, 61, 56, 20, 247, 116, 172, 147, 170, 3, 6, 80, 189, 3, 220, 11, 62, 56, 129, 179, 145, 205, 91, 46, 65, 29, 114, 184, 208, 118, 239, 103, 33, 224, 177, 109, 150, 19, 19, 100, 136, 166, 97, 101, 168, 9, 7, 29, 143, 169, 93, 186, 76, 23, 3, 227, 93, 240, 235, 94, 195, 2, 46, 188, 75, 37, 252, 60, 62, 186, 250, 143, 133, 96, 127, 208, 127, 55, 176, 247, 232, 99, 196, 99, 197, 107, 162, 234, 47, 109, 27, 121, 66, 73, 160, 1, 52, 29, 72, 89, 252, 231, 65, 236, 250, 198, 186, 129, 21, 102, 98, 57, 20, 184, 221, 174, 48, 37, 11, 185, 123, 187, 102, 78, 92, 3, 69, 161, 222, 33, 150, 250, 117, 85, 118, 111, 4, 145, 242, 62, 255, 27, 48, 72, 87, 253, 32, 157, 130, 68, 63, 224, 223, 227, 29, 217, 177, 173, 61, 206, 34, 14, 205, 70, 161, 224, 28, 131, 197, 203, 105, 33, 178, 131, 144, 186, 147, 119, 167, 172, 7, 116, 52, 214, 52, 191, 16, 20, 138, 241, 150, 60, 17, 30, 90, 22, 144, 187, 227, 163, 134, 176, 66, 121, 14, 1, 232, 99, 93, 57, 25, 113, 177, 243, 126, 46, 49, 0, 67, 207, 198, 255, 38, 164, 52, 221, 52, 220, 90, 196, 191, 73, 33, 136, 99, 74, 195, 31, 231, 194, 199, 182, 140, 82, 157, 188, 8, 12, 81, 84, 107, 2, 2, 35, 89, 168, 58, 130, 16, 60, 88, 163, 212, 87, 132, 194, 194, 63, 187, 98, 243, 115, 64, 245, 175, 9, 218, 0, 32, 210, 197, 40, 166, 44, 15, 234, 238, 33, 153, 224, 250, 120, 51, 0, 227, 120, 219, 44, 30, 86, 64, 104, 234, 171, 137, 78, 125, 204, 253, 60, 134, 211, 218, 47, 15, 145, 50, 231, 108, 143, 126, 99, 80, 109, 242, 211, 146, 142, 83, 22, 234, 150, 48, 123, 227, 52, 208, 213, 137, 83, 217, 82, 43, 155, 212, 230, 162, 139, 107, 243, 220, 45, 253, 220, 250, 97, 103, 239, 54, 14, 22, 131, 74, 171, 99, 219, 98, 40, 216, 176, 158, 82, 250, 106, 254, 2, 99, 49, 56, 168, 119, 184, 140, 182, 116, 186, 29, 103, 223, 20, 9, 95, 6, 36, 28, 134, 90, 8, 57, 65, 158, 33, 238, 155, 61, 210, 236, 126, 109, 144, 252, 222, 44, 104, 106, 212, 140, 195, 31, 222, 141, 131, 55, 1, 160, 236, 52, 155, 170, 173, 154, 85, 238, 6, 154, 93, 244, 172, 20, 207, 3, 249, 143, 52, 22, 77, 100, 14, 227, 254, 35, 66, 27, 37, 222, 98, 7, 22, 145, 202, 214, 116, 214, 33, 222, 138, 32, 154, 51, 86, 104, 119, 28, 107, 68, 13, 217, 155, 196, 223, 205, 180, 94, 22, 149, 156, 167, 202, 45, 125, 37, 105, 207, 145, 26, 162, 155, 167, 7, 155, 51, 201, 3, 72, 182, 154, 209, 14, 197, 215, 140, 114, 186, 121, 172, 94, 77, 16, 142, 0, 103, 184, 23, 29, 55, 101, 211, 60, 229, 54, 78, 121, 246, 79, 212, 96, 239, 52, 182, 132, 42, 214, 208, 28, 48, 252, 79, 113, 145, 90, 110, 46, 145, 190, 80, 63, 166, 210, 77, 34, 111, 125, 51, 102, 10, 3, 194, 209, 9, 160, 15, 155, 36, 235, 142, 252, 125, 174, 44, 186, 78, 171, 54, 62, 14, 227, 191, 192, 234, 43, 84, 99, 96, 201, 1, 12, 101, 98, 237, 12, 249, 186, 148, 221, 17, 209, 11, 181, 148, 166, 177, 44, 162, 16, 85, 35, 214, 85, 114, 100, 249, 76, 82, 74, 70, 30, 146, 99, 230, 15, 157, 117, 154, 219, 131, 163, 193, 175, 216, 30, 147, 176, 224, 116, 82, 144, 224, 131, 249, 50, 247, 196, 237, 65, 178, 102, 105, 252, 20, 31, 166, 17, 217, 207, 140, 216, 254, 123, 59, 77, 17, 111, 98, 168, 210, 237, 76, 110, 107, 16, 100, 40, 46, 208, 81, 201, 160, 52, 137, 25, 180, 136, 37, 214, 173, 172, 95, 113, 210, 195, 95, 222, 172, 118, 119, 189, 98, 253, 123, 107, 18, 98, 111, 201, 224, 197, 109, 136, 150, 149, 5, 87, 124, 188, 37, 201, 73, 198, 26, 6, 62, 134, 188, 136, 206, 126, 101, 46, 234, 17, 202, 47, 135, 223, 57, 59, 53, 114, 38, 89, 31, 1, 76, 76, 238, 143, 11, 190, 30, 76, 230, 46, 162, 51, 0, 186, 207, 126, 107, 219, 156, 18, 104, 247, 158, 244, 145, 20, 84, 31, 68, 141, 55, 190, 221, 105, 102, 56, 81, 154, 125, 71, 123, 126, 236, 179, 81, 231, 220, 167, 119, 206, 115, 106, 59, 166, 166, 3, 137, 43, 56, 32, 5, 45, 215, 145, 162, 47, 148, 234, 114, 18, 3, 166, 248, 209, 117, 192, 103, 35, 83, 79, 19, 212, 230, 12, 128, 214, 142, 148, 173, 234, 212, 62, 78, 144, 8, 141, 63, 252, 255, 188, 27, 191, 132, 53, 215, 220, 19, 191, 75, 253, 145, 230, 122, 156, 115, 250, 73, 171, 210, 22, 233, 244, 91, 58, 47, 75, 68, 116, 182, 98, 182, 75, 66, 36, 159, 64, 205, 176, 102, 50, 237, 38, 107, 148, 58, 61, 64, 1, 249, 68, 75, 235, 104, 25, 228, 147, 233, 46, 25, 190, 118, 196, 34, 39, 1, 60, 201, 67, 77, 64, 9, 43, 0, 150, 41, 73, 57, 254, 211, 96, 93, 129, 231, 63, 12, 177, 106, 238, 70, 73, 87, 251, 7, 254, 51, 212, 34, 34, 137, 127, 209, 207, 70, 60, 68, 71, 74, 208, 119, 211, 153, 100, 173, 21, 178, 95, 113, 6, 103, 244, 204, 200, 141, 58, 156, 13, 21, 109, 169, 215, 206, 184, 10, 248, 214, 219, 2, 22, 108, 37, 247, 157, 102, 167, 253, 142, 139, 177, 62, 243, 59, 147, 69, 231, 150, 123, 177, 231, 224, 33, 29, 75, 184, 115, 143, 218, 4, 10, 125, 35, 50, 201, 143, 44, 175, 108, 206, 247, 152, 81, 249, 135, 221, 23, 132, 80, 104, 24, 6, 10, 208, 155, 97, 45, 9, 52, 29, 232, 152, 176, 75, 242, 241, 111, 128, 127, 144, 96, 159, 171, 73, 250, 52, 163, 43, 158, 232, 89, 227, 65, 219, 151, 153, 227, 61, 46, 232, 177, 170, 203, 237, 9, 253, 225, 222, 224, 200, 86, 146, 180, 104, 8, 15, 189, 184, 94, 177, 36, 57, 170, 206, 62, 47, 152, 67, 77, 106, 10, 26, 180, 44, 124, 175, 5, 81, 96, 215, 143, 142, 152, 61, 2, 81, 216, 66, 142, 216, 71, 8, 175, 245, 51, 144, 186, 166, 28, 230, 64, 159, 150, 90, 249, 65, 151, 10, 136, 91, 38, 146, 1, 243, 23, 141, 224, 125, 108, 4, 166, 186, 241, 55, 10, 202, 251, 230, 96, 252, 248, 197, 48, 29, 239, 129, 204, 184, 15, 10, 89, 130, 175, 144, 59, 155, 33, 171, 121, 32, 19, 252, 109, 220, 191, 115, 237, 37, 243, 233, 121, 122, 90, 250, 66, 142, 44, 35, 203, 218, 145, 243, 140, 28, 161, 213, 153, 231, 76, 138, 76, 251, 151, 7, 11, 64, 193, 73, 230, 191, 196, 153, 83, 5, 94, 107, 104, 1, 65, 203, 149, 153, 209, 76, 82, 60, 0, 21, 153, 63, 172, 119, 106, 223, 51, 212, 244, 144, 25, 25, 126, 216, 9, 93, 42, 46, 188, 134, 154, 195, 84, 46, 126, 128, 136, 111, 21, 90, 103, 219, 198, 39, 161, 53, 255, 151, 213, 105, 135, 115, 226, 94, 28, 48, 252, 80, 33, 60, 213, 206, 247, 191, 175, 195, 227, 118, 54, 185, 205, 195, 248, 11, 238, 202, 13, 236, 38, 182, 1, 1, 51, 111, 190, 234, 249, 87, 189, 234, 35, 148, 226, 72, 131, 77, 249, 214, 48, 36, 116, 58, 228, 77, 168, 222, 190, 115, 193, 157, 174, 213, 105, 120, 23, 98, 134, 22, 205, 150, 192, 202, 128, 65, 128, 85, 254, 99, 135, 227, 170, 80, 96, 234, 225, 173, 172, 156, 179, 234, 81, 185, 34, 227, 155, 41, 242, 244, 138, 148, 58, 255, 232, 63, 146, 184, 233, 157, 105, 206, 181, 53, 42, 165, 59, 77, 71, 206, 219, 169, 168, 246, 61, 114, 171, 147, 22, 101, 218, 92, 93, 58, 103, 80, 240, 152, 80, 137, 179, 181, 175, 203, 245, 111, 231, 4, 41, 158, 94, 224, 189, 172, 122, 97, 92, 93, 126, 47, 229, 239, 52, 225, 102, 38, 25, 61, 196, 121, 227, 94, 27, 148, 133, 61, 98, 247, 7, 82, 187, 159, 106, 74, 51, 245, 171, 42, 69, 188, 227, 34, 178, 136, 210, 137, 62, 86, 101, 8, 204, 106, 6, 234, 105, 133, 51, 69, 50, 164, 84, 182, 73, 94, 107, 10, 134, 19, 165, 111, 191, 145, 238, 0, 8, 188, 57, 123, 185, 132, 9, 169, 43, 215, 92, 74, 108, 176, 219, 88, 26, 227, 255, 172, 198, 175, 40, 106, 120, 227, 148, 24, 151, 195, 121, 182, 70, 177, 251, 105, 27, 168, 16, 142, 207, 176, 74, 47, 217, 161, 139, 28, 60, 228, 196, 246, 233, 249, 184, 212, 36, 196, 96, 125, 79, 197, 37, 17, 133, 251, 89, 226, 187, 232, 38, 238, 158, 183, 92, 96, 35, 3, 28, 247, 68, 111, 103, 174, 110, 81, 164, 146, 165, 195, 219, 114, 27, 207, 83, 255, 253, 126, 88, 242, 198, 111, 102, 218, 249, 114, 9, 153, 221, 223, 176, 188, 88, 17, 208, 46, 178, 238, 36, 253, 109, 224, 222, 79, 154, 125, 18, 200, 101, 116, 57, 1, 129, 97, 201, 151, 111, 183, 222, 140, 135, 114, 156, 95, 84, 178, 241, 159, 177, 112, 62, 25, 125, 115, 232, 102, 251, 62, 203, 14, 5, 150, 92, 99, 241, 219, 53, 250, 69, 48, 65, 141, 243, 130, 124, 225, 30, 176, 59, 17, 175, 145, 254, 49, 241, 235, 137, 226, 136, 42, 0, 251, 160, 205, 156, 192, 10, 9, 85, 55, 14, 59, 38, 172, 192, 24, 221, 66, 54, 237, 238, 147, 90, 228, 189, 22, 9, 220, 164, 100, 218, 76, 176, 128, 184, 136, 152, 252, 67, 162, 227, 119, 133, 5, 15, 108, 130, 165, 211, 24, 19, 34, 74, 234, 209, 206, 203, 5, 232, 5, 133, 92, 251, 111, 242, 81, 57, 100, 12, 116, 139, 189, 113, 167, 141, 181, 174, 47, 10, 105, 237, 10, 170, 195, 140, 245, 184, 206, 44, 7, 175, 182, 148, 159, 209, 239, 141, 192, 194, 7, 189, 225, 93, 37, 161, 90, 81, 167, 97, 32, 161, 12, 147, 110, 81, 128, 14, 78, 146, 252, 19, 252, 221, 57, 196, 233, 98, 192, 166, 49, 199, 150, 96, 30, 247, 169, 183, 252, 210, 201, 226, 23, 114, 193, 229, 123, 251, 93, 187, 191, 44, 195, 214, 222, 243, 9, 180, 215, 34, 89, 67, 220, 162, 195, 200, 67, 126, 247, 59, 142, 35, 82, 238, 128, 25, 51, 135, 152, 238, 100, 52, 59, 118, 152, 147, 111, 133, 138, 41, 196, 210, 24, 241, 10, 35, 73, 163, 94, 97, 181, 32, 144, 24, 172, 191, 205, 12, 25, 230, 108, 130, 138, 248, 164, 98, 141, 92, 99, 56, 180, 192, 55, 63, 70, 173, 164, 57, 26, 95, 135, 243, 255, 159, 211, 163, 47, 128, 71, 155, 98, 187, 81, 159, 191, 1, 55, 225, 241, 16, 174, 240, 168, 122, 37, 40, 97, 207, 157, 157, 176, 7, 252, 81, 133, 214, 128, 83, 249, 33, 72, 143, 4, 87, 8, 197, 231, 21, 222, 74, 138, 132, 149, 108, 102, 24, 221, 154, 83, 187, 80, 31, 7, 63, 116, 180, 169, 84, 202, 18, 188, 14, 118, 98, 166, 75, 244, 10, 1, 219, 79, 105, 163, 0, 249, 253, 96, 86, 201, 39, 97, 83, 83, 174, 48, 249, 73, 39, 191, 208, 168, 34, 67, 151, 254, 16, 18, 135, 92, 157, 224, 225, 41, 254, 45, 203, 41, 197, 216, 141, 15, 210, 33, 219, 67, 189, 220, 69, 50, 19, 79, 43, 75, 122, 1, 93, 44, 65, 197, 15, 29, 234, 39, 175, 233, 136, 5, 65, 123, 116, 109, 136, 63, 92, 59, 31, 158, 1, 40, 219, 158, 94, 39, 236, 207, 198, 124, 247, 209, 150, 168, 146, 27, 164, 80, 109, 251, 220, 101, 150, 29, 142, 44, 199, 71, 232, 27, 36, 118, 69, 230, 84, 26, 172, 252, 227, 46, 19, 35, 168, 239, 5, 15, 220, 128, 95, 212, 106, 205, 242, 56, 128, 9, 20, 28, 24, 33, 11, 177, 244, 110, 237, 131, 233, 183, 223, 121, 115, 90, 225, 223, 160, 83, 66, 136, 70, 58, 153, 13, 104, 136, 207, 39, 234, 129, 140, 247, 219, 176, 72, 120, 211, 185, 133, 118, 131, 212, 59, 186, 178, 199, 228, 54, 231, 97, 187, 224, 97, 237, 206, 215, 9, 22, 12, 12, 147, 21, 38, 165, 78, 149, 245, 145, 118, 103, 245, 129, 120, 5, 142, 49, 0, 211, 224, 239, 77, 114, 48, 172, 158, 171, 19, 224, 201, 82, 218, 78, 168, 91, 134, 15, 40, 187, 114, 42, 26, 8, 142, 211, 61, 233, 8, 155, 177, 147, 149, 232, 160, 1, 177, 135, 245, 144, 69, 22, 157, 156, 200, 109, 133, 201, 157, 212, 254, 134, 213, 191, 255, 101, 255, 20, 235, 105, 62, 221, 210, 159, 64, 246, 136, 181, 60, 41, 149, 129, 224, 46, 79, 173, 136, 105, 125, 192, 244, 16, 236, 172, 194, 247, 136, 160, 191, 219, 24, 101, 151, 204, 189, 254, 69, 160, 79, 84, 149, 43, 108, 90, 65, 16, 75, 49, 182, 29, 211, 188, 135, 145, 131, 108, 143, 97, 95, 38, 38, 244, 117, 92, 157, 91, 38, 118, 118, 134, 108, 123, 83, 215, 239, 228, 186, 45, 112, 202, 166, 127, 199, 80, 183, 251, 112, 113, 237, 49, 148, 92, 31, 54, 242, 208, 12, 47, 101, 74, 79, 19, 78, 122, 60, 125, 85, 133, 3, 52, 123, 236, 60, 62, 178, 101, 111, 91, 89, 228, 63, 62, 116, 53, 148, 71, 46, 153, 133, 244, 59, 87, 117, 171, 67, 182, 119, 3, 204, 215, 205, 128, 248, 11, 59, 34, 15, 115, 249, 177, 240, 198, 58, 52, 23, 101, 132, 118, 39, 181, 199, 49, 39, 98, 196, 23, 179, 199, 62, 65, 165, 246, 218, 161, 150, 163, 253, 94, 124, 215, 10, 245, 71, 135, 168, 59, 251, 229, 157, 39, 75, 179, 211, 83, 33, 172, 81, 2, 30, 222, 174, 66, 80, 11, 196, 187, 123, 255, 127, 187, 208, 236, 106, 88, 54, 93, 253, 37, 33, 155, 82, 26, 156, 57, 87, 148, 130, 44, 84, 207, 171, 200, 131, 82, 28, 61, 122, 155, 114, 160, 253, 29, 177, 50, 168, 100, 73, 18, 132, 92, 136, 67, 24, 156, 149, 164, 120, 109, 130, 170, 156, 164, 248, 104, 83, 152, 231, 211, 100, 78, 59, 170, 147, 101, 86, 254, 127, 143, 124, 178, 232, 35, 35, 243, 3, 220, 198, 182, 146, 71, 250, 50, 61, 152, 253, 101, 219, 219, 159, 58, 34, 239, 111, 144, 29, 8, 99, 24, 212, 123, 176, 171, 0, 132, 253, 35, 140, 166, 157, 68, 215, 217, 105, 78, 224, 18, 118, 216, 79, 227, 101, 59, 153, 27, 217, 243, 250, 193, 213, 100, 184, 69, 78, 229, 7, 144, 107, 5, 214, 223, 139, 123, 44, 140, 165, 131, 215, 65, 77, 181, 143, 101, 218, 198, 87, 47, 191, 10, 102, 231, 0, 239, 23, 128, 83, 11, 218, 62, 104, 185, 73, 211, 216, 40, 70, 231, 92, 187, 172, 255, 66, 159, 93, 156, 35, 172, 123, 2, 230, 123, 236, 241, 154, 88, 136, 179, 147, 174, 89, 50, 5, 158, 169, 128, 127, 215, 231, 82, 83, 159, 66, 241, 205, 103, 143, 20, 248, 239, 143, 31, 210, 249, 39, 25, 8, 8, 242, 111, 111, 188, 35, 190, 251, 17, 114, 164, 49, 24, 113, 159, 50, 115, 56, 190, 180, 91, 125, 237, 99, 116, 211, 36, 208, 115, 12, 73, 61, 99, 110, 81, 64, 83, 163, 131, 154, 211, 9, 165, 11, 30, 177, 177, 43, 241, 7, 108, 203, 224, 75, 25, 246, 160, 33, 148, 32, 131, 183, 190, 0, 219, 28, 208, 242, 134, 174, 91, 92, 51, 36, 240, 43, 139, 147, 101, 183, 51, 216, 249, 42, 166, 52, 133, 115, 249, 6, 240, 23, 27, 23, 77, 180, 40, 175, 240, 173, 104, 70, 137, 83, 82, 171, 155, 215, 136, 131, 4, 172, 19, 100, 255, 146, 160, 199, 128, 177, 130, 163, 56, 104, 107, 102, 44, 178, 196, 187, 0, 38, 53, 230, 191, 148, 218, 207, 105, 66, 106, 103, 52, 241, 119, 233, 63, 63, 182, 45, 101, 61, 210, 89, 175, 101, 98, 89, 172, 252, 236, 36, 54, 143, 131, 55, 35, 189, 128, 57, 73, 34, 229, 250, 206, 253, 43, 37, 53, 136, 172, 73, 221, 27, 205, 207, 21, 120, 92, 6, 220, 166, 66, 95, 45, 241, 209, 112, 72, 22, 31, 221, 232, 220, 157, 248, 78, 105, 214, 230, 41, 193, 211, 46, 249, 26, 11, 242, 42, 225, 116, 207, 166, 141, 116, 185, 223, 86, 218, 190, 255, 185, 250, 199, 181, 56, 188, 132, 37, 27, 85, 248, 112, 161, 182, 164, 153, 129, 40, 37, 13, 8, 67, 236, 36, 182, 151, 130, 96, 131, 65, 26, 103, 239, 65, 243, 234, 162, 7, 90, 237, 24, 99, 145, 47, 181, 99, 65, 38, 36, 112, 157, 239, 225, 127, 161, 168, 6, 66, 231, 252, 142, 154, 225, 138, 189, 243, 66, 142, 71, 61, 239, 55, 230, 59, 40, 224, 134, 104, 100, 189, 166, 249, 66, 91, 146, 154, 28, 67, 78, 138, 40, 114, 71, 172, 3, 168, 233, 9, 106, 228, 143, 56, 193, 227, 243, 144, 51, 222, 94, 224, 43, 79, 149, 212, 245, 52, 68, 200, 17, 235, 45, 164, 147, 62, 118, 52, 216, 195, 78, 13, 66, 190, 188, 241, 142, 234, 182, 85, 48, 148, 214, 123, 57, 223, 188, 229, 119, 169, 180, 193, 70, 250, 215, 249, 29, 88, 123, 88, 226, 210, 171, 170, 32, 80, 85, 3, 26, 219, 109, 97, 134, 11, 96, 118, 71, 130, 86, 182, 77, 116, 137, 214, 28, 140, 242, 227, 178, 167, 200, 214, 175, 107, 96, 132, 33, 40, 64, 93, 206, 90, 129, 132, 221, 170, 242, 113, 235, 251, 172, 193, 35, 58, 85, 70, 9, 75, 104, 71, 161, 99, 214, 6, 33, 204, 250, 172, 199, 33, 183, 246, 250, 109, 251, 50, 106, 114, 16, 134, 150, 19, 219, 21, 60, 63, 251, 204, 157, 45, 106, 233, 133, 154, 145, 135, 201, 77, 59, 178, 176, 217, 109, 236, 19, 19, 200, 5, 165, 235, 81, 14, 42, 153, 40, 189, 86, 92, 90, 239, 77, 53, 136, 65, 112, 94, 130, 104, 71, 55, 79, 22, 250, 34, 178, 14, 91, 24, 145, 250, 4, 197, 96, 72, 118, 142, 31, 83, 137, 14, 57, 115, 36, 202, 144, 10, 19, 123, 176, 23, 93, 35, 90, 145, 73, 163, 124, 66, 156, 8, 82, 243, 22, 204, 59, 77, 49, 222, 1, 246, 7, 75, 15, 234, 110, 9, 232, 29, 156, 239, 250, 88, 24, 244, 123, 15, 169, 66, 180, 254, 210, 233, 134, 27, 100, 162, 103, 158, 223, 149, 226, 167, 140, 53, 34, 57, 105, 221, 112, 116, 72, 207, 169, 98, 200, 189, 33, 72, 181, 162, 166, 4, 29, 98, 157, 184, 244, 188, 127, 186, 35, 186, 202, 24, 21, 185, 160, 63, 17, 112, 78, 96, 49, 87, 60, 154, 215, 49, 196, 179, 122, 60, 253, 154, 86, 177, 227, 70, 1, 80, 205, 58, 66, 103, 146, 170, 108, 34, 134, 149, 134, 160, 225, 152, 63, 18, 199, 101, 158, 199, 235, 124, 98, 105, 8, 62, 100, 92, 248, 81, 59, 108, 190, 156, 216, 106, 103, 90, 69, 199, 160, 21, 66, 203, 125, 157, 189, 8, 115, 15, 158, 77, 105, 124, 171, 180, 227, 134, 50, 208, 245, 254, 35, 231, 215, 231, 193, 218, 216, 68, 204, 229, 233, 95, 120, 177, 105, 108, 92, 9, 181, 119, 196, 19, 97, 5, 145, 254, 112, 156, 70, 9, 68, 39, 84, 33, 80, 2, 21, 228, 184, 145, 218, 19, 202, 231, 144, 3, 29, 22, 14, 146, 193, 90, 216, 63, 95, 197, 70, 198, 68, 235, 132, 16, 31, 100, 179, 19, 105, 19, 178, 210, 222, 118, 148, 37, 202, 50, 222, 84, 246, 89, 36, 25, 183, 80, 175, 79, 154, 38, 119, 89, 125, 133, 56, 21, 61, 187, 123, 80, 224, 187, 15, 84, 46, 19, 1, 24, 246, 250, 32, 226, 193, 49, 118, 252, 1, 47, 172, 161, 175, 60, 113, 56, 248, 198, 100, 117, 78, 138, 154, 40, 231, 118, 120, 23, 223, 8, 239, 145, 51, 43, 82, 146, 83, 129, 43, 146, 75, 171, 20, 186, 157, 174, 137, 205, 187, 198, 37, 10, 108, 65, 154, 212, 207, 63, 178, 11, 51, 5, 62, 172, 122, 219, 147, 16, 223, 243, 134, 146, 161, 173, 118, 113, 185, 212, 199, 29, 83, 5, 241, 42, 54, 160, 57, 100, 116, 111, 218, 193, 39, 66, 67, 141, 161, 179, 141, 54, 87, 16, 43, 15, 93, 41, 240, 62, 66, 231, 59, 42, 48, 46, 207, 141, 27, 160, 156, 247, 138, 129, 130, 68, 34, 66, 69, 177, 45, 108, 26, 36, 50, 109, 46, 238, 82, 187, 219, 166, 225, 115, 204, 121, 228, 122, 92, 65, 67, 69, 162, 104, 10, 117, 17, 33, 113, 110, 10, 9, 2, 41, 24, 227, 173, 49, 10, 2, 147, 115, 197, 93, 133, 139, 86, 38, 138, 102, 92, 17, 94, 115, 74, 101, 5, 12, 222, 186, 229, 16, 126, 16, 234, 105, 191, 184, 182, 27, 59, 152, 118, 179, 114, 78, 65, 15, 21, 43, 215, 7, 215, 110, 207, 152, 128, 14, 106, 188, 73, 230, 183, 23, 101, 92, 95, 250, 115, 245, 40, 58, 167, 157, 201, 1, 229, 233, 39, 243, 103, 253, 104, 135, 248, 219, 74, 127, 91, 135, 224, 240, 42, 6, 70, 70, 48, 23, 52, 78, 12, 212, 203, 55, 134, 108, 107, 185, 237, 129, 120, 234, 54, 243, 252, 231, 19, 190, 190, 46, 48, 115, 200, 145, 119, 195, 140, 122, 21, 85, 120, 189, 33, 208, 59, 39, 181, 57, 55, 128, 144, 149, 120, 65, 77, 113, 75, 203, 194, 251, 217, 77, 110, 56, 54, 93, 240, 101, 219, 52, 174, 163, 153, 193, 24, 16, 112, 103, 178, 252, 57, 2, 7, 55, 184, 80, 176, 248, 128, 236, 73, 250, 66, 218, 63, 16, 230, 149, 32, 149, 237, 199, 168, 81, 147, 63, 211, 251, 112, 223, 62, 92, 60, 114, 156, 203, 12, 225, 232, 250, 166, 123, 194, 227, 56, 82, 4, 104, 168, 170, 38, 93, 122, 232, 207, 228, 68, 58, 247, 162, 96, 128, 20, 249, 114, 93, 37, 199, 229, 152, 134, 168, 14, 212, 153, 137, 31, 241, 189, 163, 223, 247, 196, 22, 67, 27, 105, 10, 235, 28, 24, 177, 249, 230, 19, 247, 145, 228, 151, 195, 17, 201, 93, 226, 167, 76, 227, 85, 207, 200, 139, 37, 148, 40, 243, 214, 60, 55, 241, 183, 126, 160, 97, 6, 129, 104, 182, 207, 250, 77, 123, 235, 211, 158, 171, 52, 171, 186, 53, 121, 24, 137, 105, 164, 247, 172, 132, 201, 31, 135, 123, 0, 164, 164, 235, 167, 103, 63, 40, 54, 102, 46, 197, 185, 194, 14, 195, 159, 182, 120, 4, 36, 14, 194, 219, 155, 23, 233, 148, 169, 113, 158, 92, 103, 68, 247, 133, 214, 252, 9, 220, 50, 198, 251, 75, 34, 10, 115, 209, 172, 147, 168, 185, 81, 70, 174, 155, 80, 111, 246, 78, 199, 155, 192, 2, 241, 162, 123, 123, 77, 228, 101, 22, 241, 89, 245, 63, 3, 235, 76, 162, 20, 12, 81, 228, 254, 50, 146, 76, 149, 112, 226, 88, 231, 167, 229, 27, 250, 21, 98, 84, 235, 251, 213, 238, 209, 111, 34, 144, 181, 190, 22, 60, 112, 244, 98, 241, 19, 51, 163, 4, 198, 8, 50, 194, 200, 241, 155, 192, 97, 95, 173, 49, 94, 169, 112, 21, 87, 23, 229, 226, 75, 60, 134, 126, 21, 10, 86, 84, 238, 113, 19, 77, 205, 3, 158, 105, 241, 98, 86, 237, 233, 190, 97, 136, 202, 234, 147, 121, 253, 156, 176, 238, 222, 71, 35, 185, 127, 212, 211, 0, 86, 129, 131, 93, 111, 167, 121, 138, 69, 251, 4, 90, 229, 43, 48, 144, 138, 0, 48, 249, 202, 203, 46, 117, 175, 27, 96, 230, 119, 93, 156, 129, 186, 122, 133, 114, 160, 196, 50, 81, 97, 63, 13, 188, 146, 63, 4, 220, 222, 165, 9, 236, 124, 117, 145, 91, 244, 186, 233, 35, 78, 241, 45, 38, 127, 179, 165, 20, 253, 131, 171, 41, 230, 158, 162, 83, 50, 19, 23, 83, 128, 121, 67, 248, 17, 145, 98, 112, 190, 250, 237, 243, 248, 64, 146, 41, 16, 44, 154, 33, 60, 162, 161, 156, 229, 176, 172, 49, 42, 240, 235, 85, 90, 162, 151, 170, 183, 27, 21, 183, 40, 134, 187, 193, 75, 183, 76, 63, 235, 27, 90, 133, 26, 138, 83, 150, 77, 206, 233, 166, 204, 90, 125, 211, 133, 229, 10, 166, 12, 146, 184, 152, 107, 242, 245, 52, 145, 154, 34, 249, 13, 102, 253, 209, 20, 3, 225, 88, 156, 137, 30, 182, 206, 211, 255, 149, 39, 64, 133, 16, 125, 5, 115, 220, 51, 122, 242, 121, 222, 212, 239, 237, 208, 31, 72, 98, 36, 131, 185, 9, 124, 14, 55, 236, 196, 38, 68, 82, 17, 197, 255, 168, 199, 158, 94, 52, 58, 126, 100, 57, 118, 184, 214, 42, 65, 249, 156, 128, 82, 139, 234, 63, 119, 55, 89, 108, 207, 209, 226, 34, 198, 134, 54, 131, 154, 87, 96, 31, 11, 241, 1, 11, 97, 61, 167, 20, 223, 188, 163, 31, 250, 189, 13, 29, 196, 209, 218, 119, 102, 13, 172, 149, 149, 219, 251, 64, 238, 211, 212, 136, 82, 237, 150, 140, 188, 201, 123, 191, 83, 133, 193, 253, 25, 27, 246, 72, 60, 212, 227, 241, 209, 206, 142, 29, 11, 11, 146, 182, 203, 214, 25, 192, 236, 197, 176, 6, 216, 105, 145, 191, 115, 161, 107, 170, 194, 121, 148, 205, 65, 116, 157, 96, 173, 217, 30, 96, 174, 239, 178, 151, 121, 46, 3, 86, 65, 32, 120, 195, 66, 86, 144, 206, 91, 36, 148, 42, 216, 208, 164, 203, 149, 69, 230, 49, 78, 224, 177, 23, 175, 103, 191, 111, 181, 130, 255, 215, 189, 173, 134, 189, 64, 36, 226, 134, 89, 116, 138, 92, 81, 246, 202, 10, 243, 21, 81, 165, 210, 235, 49, 99, 217, 19, 184, 54, 71, 102, 132, 49, 135, 228, 156, 67, 170, 38, 173, 200, 239, 244, 255, 65, 211, 100, 161, 118, 111, 218, 219, 87, 23, 57, 9, 246, 102, 252, 157, 205, 98, 12, 97, 198, 183, 141, 223, 154, 23, 180, 123, 80, 156, 144, 231, 95, 42, 135, 31, 244, 164, 121, 138, 116, 154, 207, 222, 138, 32, 84, 185, 56, 114, 9, 244, 11, 213, 237, 166, 91, 31, 217, 20, 179, 168, 121, 139, 237, 181, 221, 90, 174, 2, 176, 34, 210, 130, 241, 130, 240, 178, 89, 176, 130, 185, 243, 52, 101, 116, 112, 6, 60, 84, 6, 110, 29, 246, 66, 10, 164, 130, 46, 75, 163, 179, 45, 250, 32, 57, 48, 74, 169, 133, 44, 167, 241, 103, 31, 119, 243, 74, 208, 4, 162, 17, 11, 72, 126, 10, 81, 117, 188, 103, 222, 163, 78, 206, 72, 216, 73, 2, 221, 230, 122, 107, 141, 126, 1, 236, 63, 51, 169, 160, 14, 165, 208, 174, 9, 91, 74, 252, 146, 198, 79, 238, 175, 39, 102, 75, 150, 40, 109, 143, 117, 77, 153, 234, 82, 38, 162, 23, 242, 107, 124, 217, 13, 51, 55, 92, 1, 28, 138, 62, 209, 69, 222, 63, 62, 150, 221, 74, 232, 220, 181, 21, 36, 203, 182, 193, 183, 173, 113, 157, 241, 208, 131, 172, 0, 176, 55, 229, 63, 54, 84, 197, 105, 196, 154, 60, 52, 50, 191, 230, 202, 129, 85, 235, 75, 245, 172, 58, 230, 0, 251, 250, 104, 123, 247, 224, 120, 118, 30, 50, 223, 144, 233, 243, 213, 58, 228, 124, 24, 168, 194, 24, 192, 4, 63, 107, 39, 55, 202, 196, 254, 149, 141, 189, 136, 218, 108, 203, 100, 198, 121, 240, 252, 208, 200, 230, 178, 117, 199, 2, 55, 165, 214, 210, 246, 142, 178, 63, 86, 249, 156, 100, 172, 202, 197, 148, 222, 76, 185, 221, 248, 71, 7, 231, 224, 158, 236, 27, 44, 53, 58, 181, 65, 176, 146, 223, 254, 5, 249, 207, 218, 160, 212, 245, 14, 114, 246, 153, 139, 55, 230, 89, 143, 125, 133, 103, 249, 123, 91, 229, 195, 214, 65, 251, 219, 11, 48, 167, 72, 9, 131, 110, 207, 244, 197, 159, 23, 51, 161, 135, 251, 220, 52, 242, 122, 199, 21, 231, 34, 185, 84, 140, 112, 3, 164, 231, 64, 162, 192, 103, 182, 162, 112, 2, 142, 22, 148, 62, 71, 79, 232, 85, 38, 15, 87, 230, 232, 112, 203, 94, 230, 172, 233, 219, 158, 246, 87, 61, 155, 22, 14, 157, 23, 61, 99, 196, 97, 70, 216, 173, 236, 211, 120, 197, 28, 231, 47, 215, 66, 71, 46, 66, 28, 29, 223, 77, 173, 144, 82, 220, 222, 99, 229, 74, 53, 88, 116, 123, 162, 240, 168, 216, 142, 205, 144, 183, 127, 135, 4, 162, 91, 176, 78, 26, 178, 249, 104, 195, 76, 105, 206, 143, 20, 158, 220, 22, 67, 201, 237, 78, 241, 56, 111, 63, 160, 240, 168, 131, 253, 62, 8, 51, 88, 43, 174, 217, 235, 243, 71, 50, 210, 7, 235, 56, 63, 128, 111, 32, 244, 187, 217, 170, 77, 152, 65, 7, 200, 30, 47, 83, 126, 139, 170, 142, 219, 184, 156, 54, 102, 249, 94, 32, 2, 204, 206, 77, 230, 60, 184, 143, 167, 110, 241, 203, 60, 44, 174, 128, 150, 186, 215, 218, 189, 87, 107, 216, 84, 76, 166, 171, 91, 23, 16, 208, 211, 181, 234, 61, 203, 224, 172, 128, 129, 66, 7, 249, 0, 75, 157, 235, 49, 244, 154, 157, 107, 205, 70, 146, 38, 188, 6, 218, 133, 231, 204, 168, 234, 133, 17, 245, 85, 253, 163, 242, 168, 56, 9, 99, 142, 236, 237, 67, 20, 226, 60, 4, 86, 83, 208, 243, 19, 127, 168, 6, 156, 67, 179, 66, 170, 242, 211, 170, 199, 188, 71, 231, 191, 67, 42, 109, 37, 117, 154, 231, 116, 63, 232, 206, 107, 141, 17, 127, 143, 79, 247, 160, 62, 151, 234, 116, 126, 14, 223, 8, 5, 52, 82, 8, 99, 17, 9, 7, 4, 208, 106, 11, 208, 156, 157, 85, 51, 236, 128, 41, 66, 99, 243, 220, 153, 131, 111, 78, 189, 95, 219, 51, 100, 41, 150, 188, 218, 35, 37, 176, 31, 122, 252, 207, 222, 214, 142, 95, 19, 136, 159, 195, 209, 39, 182, 19, 97, 185, 72, 83, 165, 208, 249, 83, 4, 244, 230, 30, 7, 13, 161, 90, 200, 121, 138, 67, 151, 252, 197, 165, 44, 215, 9, 81, 118, 179, 159, 15, 3, 156, 105, 151, 104, 109, 161, 202, 143, 199, 41, 187, 172, 154, 64, 105, 69, 67, 173, 226, 34, 234, 111, 69, 244, 45, 230, 49, 11, 18, 158, 56, 184, 55, 124, 46, 252, 215, 109, 236, 124, 156, 172, 148, 159, 44, 147, 129, 50, 49, 230, 128, 213, 137, 161, 125, 140, 222, 36, 90, 117, 223, 146, 237, 122, 39, 118, 188, 93, 11, 40, 49, 114, 230, 80, 31, 221, 58, 199, 174, 192, 112, 31, 236, 98, 56, 76, 27, 199, 78, 28, 48, 62, 246, 207, 30, 85, 50, 31, 4, 143, 58, 241, 131, 83, 203, 70, 241, 124, 150, 160, 88, 30, 227, 177, 213, 75, 139, 122, 83, 83, 41, 97, 140, 78, 157, 188, 172, 85, 52, 202, 76, 47, 145, 76, 126, 144, 228, 49, 239, 103, 196, 149, 203, 133, 159, 201, 215, 241, 71, 245, 114, 49, 125, 228, 22, 192, 235, 230, 246, 247, 100, 110, 76, 74, 214, 226, 221, 120, 140, 250, 108, 9, 203, 40, 92, 19, 184, 136, 86, 76, 250, 177, 64, 76, 214, 79, 190, 86, 8, 131, 178, 0, 200, 171, 245, 144, 94, 2, 236, 11, 187, 119, 165, 83, 130, 252, 49, 126, 254, 131, 38, 43, 245, 170, 53, 7, 183, 205, 84, 71, 16, 127, 86, 249, 31, 169, 65, 33, 207, 146, 111, 155, 43, 145, 85, 250, 216, 38, 95, 18, 129, 186, 14, 3, 158, 43, 183, 44, 205, 90, 37, 141, 27, 130, 115, 4, 121, 67, 113, 43, 109, 251, 71, 103, 32, 129, 163, 73, 116, 252, 32, 149, 17, 150, 117, 168, 218, 56, 163, 173, 125, 84, 103, 136, 195, 89, 46, 27, 45, 153, 6, 184, 81, 93, 131, 28, 42, 171, 87, 177, 135, 109, 24, 78, 80, 103, 110, 168, 3, 251, 165, 139, 171, 25, 77, 166, 250, 193, 166, 168, 195, 160, 12, 25, 110, 36, 0, 132, 247, 199, 195, 30, 177, 14, 176, 197, 58, 142, 93, 43, 151, 126, 28, 184, 231, 179, 113, 227, 26, 165, 98, 180, 183, 218, 182, 150, 125, 231, 102, 231, 206, 39, 57, 121, 193, 43, 11, 254, 173, 29, 251, 45, 171, 106, 87, 114, 38, 58, 153, 72, 84, 193, 36, 2, 142, 215, 121, 147, 160, 11, 37, 243, 213, 217, 181, 152, 112, 191, 155, 217, 136, 117, 175, 182, 125, 134, 218, 58, 212, 239, 39, 250, 119, 220, 113, 214, 143, 204, 124, 11, 153, 200, 158, 215, 253, 40, 35, 17, 232, 45, 217, 47, 191, 159, 199, 82, 41, 106, 158, 244, 222, 254, 133, 109, 151, 43, 187, 203, 165, 61, 163, 205, 7, 217, 12, 252, 123, 90, 255, 255, 88, 221, 122, 76, 173, 185, 85, 185, 33, 228, 226, 161, 72, 217, 34, 197, 140, 190, 18, 7, 142, 177, 203, 49, 93, 91, 12, 12, 29, 35, 100, 136, 58, 22, 174, 49, 71, 209, 218, 199, 125, 51, 110, 117, 45, 205, 141, 81, 192, 148, 211, 238, 218, 84, 227, 191, 160, 49, 110, 207, 190, 8, 156, 184, 167, 148, 228, 69, 19, 39, 3, 210, 204, 196, 230, 123, 64, 123, 133, 115, 33, 85, 15, 45, 144, 218, 31, 192, 34, 60, 208, 166, 113, 151, 122, 249, 171, 207, 8, 164, 207, 138, 246, 217, 251, 34, 27, 145, 144, 57, 60, 165, 203, 117, 199, 80, 141, 218, 36, 65, 24, 115, 33, 152, 139, 152, 34, 72, 99, 192, 219, 49, 65, 187, 217, 14, 208, 56, 62, 143, 12, 51, 225, 187, 38, 19, 114, 83, 118, 117, 17, 249, 224, 185, 225, 237, 71, 79, 67, 75, 51, 0, 92, 123, 155, 122, 154, 105, 101, 235, 17, 160, 35, 152, 108, 45, 151, 154, 92, 149, 63, 255, 77, 153, 104, 98, 208, 251, 112, 189, 38, 102, 205, 117, 255, 232, 150, 109, 51, 70, 5, 11, 224, 41, 141, 200, 227, 170, 1, 220, 34, 103, 112, 185, 169, 207, 141, 183, 172, 61, 129, 113, 126, 200, 59, 197, 93, 245, 240, 58, 232, 40, 90, 125, 37, 134, 210, 82, 118, 234, 200, 115, 169, 124, 188, 1, 172, 236, 31, 79, 211, 213, 146, 195, 206, 105, 57, 241, 59, 237, 145, 32, 6, 24, 253, 23, 60, 211, 2, 94, 42, 190, 180, 213, 177, 23, 167, 104, 3, 226, 171, 208, 95, 96, 57, 53, 141, 115, 88, 174, 10, 206, 234, 150, 182, 157, 242, 93, 97, 80, 9, 154, 152, 166, 94, 141, 238, 212, 68, 231, 244, 0, 36, 167, 2, 9, 169, 16, 151, 170, 33, 51, 1, 105, 210, 194, 224, 146, 221, 227, 137, 63, 144, 14, 5, 140, 30, 193, 203, 47, 90, 20, 233, 169, 66, 192, 91, 252, 161, 140, 67, 202, 12, 24, 190, 242, 46, 208, 121, 8, 194, 164, 164, 125, 216, 194, 242, 125, 131, 35, 5, 45, 18, 152, 157, 240, 35, 56, 246, 144, 175, 2, 7, 123, 13, 158, 168, 115, 221, 195, 54, 236, 35, 132, 246, 7, 100, 108, 120, 17, 23, 210, 61, 238, 38, 73, 149, 28, 249, 29, 5, 232, 28, 131, 84, 79, 155, 26, 82, 96, 150, 219, 122, 167, 231, 56, 233, 176, 154, 213, 126, 14, 155, 13, 68, 157, 25, 236, 244, 64, 125, 74, 247, 241, 123, 177, 102, 43, 244, 122, 173, 75, 132, 244, 248, 236, 246, 161, 138, 68, 86, 2, 52, 121, 232, 96, 100, 207, 238, 219, 64, 197, 162, 8, 97, 144, 89, 121, 66, 146, 166, 233, 7, 145, 217, 223, 51, 254, 128, 1, 211, 1, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 10, 99, 108, 101, 97, 114, 116, 111, 109, 97, 114, 107, 10, 128, 3}; +char datatoc_Bfont[25181]= { +128, 1, 228, 1, 0, 0, 37, 33, 80, 83, 45, 65, 100, 111, 98, 101, +70, 111, 110, 116, 45, 49, 46, 48, 58, 32, 66, 102, 111, 110, 116, 32, +48, 48, 49, 46, 48, 48, 49, 10, 49, 49, 32, 100, 105, 99, 116, 32, +98, 101, 103, 105, 110, 10, 47, 70, 111, 110, 116, 73, 110, 102, 111, 32, +49, 48, 32, 100, 105, 99, 116, 32, 100, 117, 112, 32, 98, 101, 103, 105, +110, 10, 47, 118, 101, 114, 115, 105, 111, 110, 32, 40, 48, 48, 49, 46, +48, 48, 49, 41, 32, 114, 101, 97, 100, 111, 110, 108, 121, 32, 100, 101, +102, 10, 47, 70, 117, 108, 108, 78, 97, 109, 101, 32, 40, 66, 102, 111, +110, 116, 41, 32, 114, 101, 97, 100, 111, 110, 108, 121, 32, 100, 101, 102, +10, 47, 70, 97, 109, 105, 108, 121, 78, 97, 109, 101, 32, 40, 66, 102, +111, 110, 116, 41, 32, 114, 101, 97, 100, 111, 110, 108, 121, 32, 100, 101, +102, 10, 47, 87, 101, 105, 103, 104, 116, 32, 40, 82, 101, 103, 117, 108, +97, 114, 41, 32, 114, 101, 97, 100, 111, 110, 108, 121, 32, 100, 101, 102, +10, 47, 73, 116, 97, 108, 105, 99, 65, 110, 103, 108, 101, 32, 48, 32, +100, 101, 102, 10, 47, 105, 115, 70, 105, 120, 101, 100, 80, 105, 116, 99, +104, 32, 102, 97, 108, 115, 101, 32, 100, 101, 102, 10, 47, 85, 110, 100, +101, 114, 108, 105, 110, 101, 80, 111, 115, 105, 116, 105, 111, 110, 32, 45, +49, 48, 48, 32, 100, 101, 102, 10, 47, 85, 110, 100, 101, 114, 108, 105, +110, 101, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 53, 48, 32, 100, +101, 102, 10, 101, 110, 100, 32, 114, 101, 97, 100, 111, 110, 108, 121, 32, +100, 101, 102, 10, 47, 70, 111, 110, 116, 78, 97, 109, 101, 32, 47, 66, +102, 111, 110, 116, 32, 100, 101, 102, 10, 47, 69, 110, 99, 111, 100, 105, +110, 103, 32, 83, 116, 97, 110, 100, 97, 114, 100, 69, 110, 99, 111, 100, +105, 110, 103, 32, 100, 101, 102, 10, 47, 80, 97, 105, 110, 116, 84, 121, +112, 101, 32, 48, 32, 100, 101, 102, 10, 47, 70, 111, 110, 116, 84, 121, +112, 101, 32, 49, 32, 100, 101, 102, 10, 47, 70, 111, 110, 116, 77, 97, +116, 114, 105, 120, 32, 91, 48, 46, 48, 48, 49, 32, 48, 32, 48, 32, +48, 46, 48, 48, 49, 32, 48, 32, 48, 93, 32, 114, 101, 97, 100, 111, +110, 108, 121, 32, 100, 101, 102, 10, 99, 117, 114, 114, 101, 110, 116, 100, +105, 99, 116, 32, 101, 110, 100, 10, 99, 117, 114, 114, 101, 110, 116, 102, +105, 108, 101, 32, 101, 101, 120, 101, 99, 10, 128, 2, 146, 94, 0, 0, +217, 214, 111, 99, 59, 132, 106, 152, 155, 153, 116, 176, 23, 159, 198, 204, +68, 91, 194, 192, 49, 3, 198, 133, 112, 167, 179, 84, 164, 162, 128, 174, +111, 191, 127, 152, 247, 90, 132, 186, 206, 45, 3, 106, 107, 81, 184, 72, +73, 49, 89, 29, 146, 229, 6, 158, 98, 38, 213, 173, 204, 93, 228, 248, +16, 122, 166, 154, 53, 181, 95, 106, 155, 75, 79, 147, 197, 108, 35, 188, +198, 29, 215, 191, 143, 50, 242, 29, 88, 228, 26, 95, 121, 12, 238, 47, +2, 175, 73, 134, 149, 233, 12, 29, 11, 210, 89, 231, 91, 2, 25, 48, +11, 15, 105, 44, 51, 119, 156, 42, 166, 122, 232, 81, 122, 190, 18, 48, +8, 69, 34, 74, 246, 173, 93, 169, 219, 154, 26, 58, 64, 251, 6, 179, +106, 156, 205, 105, 18, 85, 7, 252, 45, 233, 208, 65, 132, 199, 96, 66, +240, 63, 207, 209, 83, 132, 0, 35, 151, 42, 129, 42, 185, 179, 203, 86, +112, 193, 206, 39, 89, 113, 28, 117, 41, 66, 98, 214, 242, 145, 175, 155, +124, 118, 7, 30, 218, 126, 122, 208, 38, 33, 98, 50, 34, 185, 54, 8, +122, 178, 127, 254, 95, 7, 134, 71, 6, 101, 146, 24, 61, 195, 71, 174, +146, 230, 191, 86, 177, 123, 237, 206, 19, 104, 70, 246, 162, 163, 118, 171, +140, 11, 192, 255, 78, 52, 125, 32, 253, 14, 199, 126, 250, 177, 240, 99, +49, 0, 20, 141, 42, 125, 47, 210, 31, 18, 90, 170, 205, 143, 219, 153, +121, 131, 43, 103, 13, 138, 170, 118, 210, 18, 186, 181, 97, 70, 25, 144, +150, 12, 53, 110, 184, 216, 233, 243, 198, 93, 157, 254, 127, 140, 44, 138, +123, 43, 233, 158, 99, 255, 108, 134, 136, 60, 29, 229, 7, 141, 163, 185, +30, 3, 228, 132, 13, 221, 109, 48, 227, 60, 227, 135, 117, 220, 128, 67, +195, 147, 32, 118, 71, 190, 131, 11, 245, 200, 93, 30, 226, 32, 114, 26, +39, 232, 138, 33, 109, 232, 1, 11, 233, 212, 78, 221, 88, 158, 135, 95, +159, 14, 38, 31, 12, 106, 255, 51, 147, 42, 139, 254, 210, 119, 6, 96, +221, 226, 140, 183, 213, 222, 5, 205, 13, 140, 253, 214, 125, 103, 227, 52, +60, 102, 31, 250, 163, 147, 228, 167, 58, 207, 156, 68, 166, 150, 167, 169, +116, 83, 194, 150, 104, 152, 31, 7, 157, 38, 76, 29, 10, 247, 63, 57, +194, 106, 230, 183, 120, 135, 187, 201, 211, 82, 234, 168, 182, 167, 90, 56, +37, 109, 160, 144, 13, 48, 204, 190, 14, 169, 103, 127, 136, 102, 24, 81, +61, 32, 233, 228, 158, 18, 235, 189, 28, 0, 222, 67, 17, 110, 143, 71, +223, 181, 33, 17, 66, 81, 210, 7, 23, 186, 245, 229, 198, 143, 62, 113, +33, 80, 236, 87, 148, 65, 42, 27, 111, 128, 223, 196, 140, 45, 32, 91, +123, 158, 136, 153, 166, 144, 126, 115, 133, 220, 254, 234, 192, 123, 14, 239, +75, 199, 116, 28, 241, 25, 30, 66, 226, 248, 159, 142, 46, 41, 10, 237, +111, 205, 31, 230, 72, 196, 49, 200, 50, 29, 115, 153, 141, 198, 225, 218, +157, 86, 56, 67, 249, 99, 50, 25, 151, 14, 200, 35, 186, 250, 204, 151, +187, 209, 51, 129, 161, 68, 118, 130, 31, 25, 134, 255, 75, 170, 240, 225, +113, 144, 5, 178, 133, 45, 85, 242, 66, 10, 10, 65, 138, 93, 147, 72, +210, 250, 209, 123, 148, 135, 12, 156, 94, 13, 250, 31, 211, 157, 82, 128, +132, 143, 11, 155, 47, 211, 151, 232, 142, 253, 82, 104, 234, 231, 190, 169, +78, 32, 90, 2, 41, 201, 122, 142, 205, 144, 234, 204, 198, 227, 56, 57, +6, 63, 8, 237, 89, 199, 30, 226, 169, 48, 198, 191, 38, 114, 87, 135, +189, 98, 251, 224, 210, 154, 58, 87, 26, 56, 41, 219, 119, 124, 109, 83, +182, 169, 166, 123, 255, 190, 35, 121, 177, 37, 92, 128, 242, 247, 132, 218, +149, 140, 116, 184, 163, 13, 248, 138, 68, 124, 229, 211, 89, 210, 101, 172, +149, 221, 182, 113, 36, 182, 46, 5, 141, 127, 147, 54, 118, 67, 107, 105, +187, 40, 53, 208, 170, 25, 45, 113, 216, 110, 135, 56, 7, 26, 14, 225, +61, 79, 228, 72, 30, 39, 220, 195, 227, 229, 153, 196, 28, 6, 107, 240, +54, 67, 6, 94, 143, 0, 34, 180, 49, 14, 41, 111, 9, 41, 94, 203, +184, 139, 142, 34, 140, 138, 90, 25, 216, 89, 252, 45, 46, 132, 169, 154, +230, 131, 15, 20, 100, 99, 235, 106, 73, 185, 89, 6, 66, 230, 171, 202, +22, 213, 227, 183, 32, 138, 116, 253, 208, 230, 121, 16, 63, 238, 132, 69, +28, 135, 88, 115, 18, 21, 11, 102, 172, 200, 37, 222, 255, 100, 221, 80, +173, 218, 53, 210, 250, 148, 211, 241, 97, 150, 185, 43, 250, 138, 14, 122, +133, 30, 191, 54, 158, 118, 22, 12, 232, 25, 228, 60, 101, 206, 119, 29, +57, 12, 99, 36, 167, 182, 153, 86, 195, 21, 70, 154, 102, 106, 45, 236, +70, 151, 143, 185, 207, 252, 106, 46, 168, 80, 216, 206, 157, 171, 118, 77, +82, 153, 24, 54, 165, 128, 160, 27, 195, 117, 241, 141, 93, 151, 233, 239, +244, 73, 123, 133, 42, 138, 123, 68, 159, 225, 209, 171, 242, 70, 212, 6, +168, 19, 116, 228, 0, 14, 148, 191, 132, 10, 254, 83, 125, 20, 17, 71, +126, 142, 56, 80, 55, 48, 125, 184, 172, 156, 163, 161, 72, 249, 105, 204, +207, 179, 217, 115, 177, 2, 82, 220, 142, 14, 180, 138, 254, 83, 139, 36, +70, 203, 91, 81, 82, 229, 20, 253, 78, 132, 213, 64, 154, 163, 59, 93, +245, 168, 38, 148, 48, 228, 13, 186, 204, 95, 140, 184, 118, 22, 130, 111, +27, 38, 139, 127, 106, 172, 161, 254, 136, 187, 166, 48, 162, 152, 124, 69, +27, 186, 50, 126, 7, 144, 43, 75, 176, 145, 159, 202, 244, 7, 78, 203, +250, 32, 42, 195, 71, 186, 90, 92, 162, 126, 98, 44, 195, 163, 47, 88, +124, 43, 177, 122, 251, 254, 29, 161, 70, 98, 235, 133, 52, 12, 28, 184, +67, 145, 73, 88, 99, 69, 60, 227, 142, 15, 218, 82, 167, 57, 225, 230, +218, 131, 251, 171, 11, 63, 191, 65, 236, 178, 63, 159, 213, 211, 114, 64, +200, 85, 73, 40, 94, 123, 108, 171, 89, 169, 206, 99, 196, 31, 15, 152, +138, 77, 137, 210, 197, 228, 255, 73, 126, 120, 249, 214, 170, 212, 168, 73, +54, 125, 113, 78, 226, 37, 137, 249, 188, 239, 33, 231, 244, 125, 116, 137, +126, 187, 31, 193, 194, 118, 121, 19, 80, 250, 87, 48, 80, 62, 246, 29, +121, 247, 135, 198, 193, 253, 148, 211, 17, 210, 17, 247, 44, 205, 91, 1, +190, 195, 236, 66, 95, 144, 58, 235, 2, 42, 79, 25, 82, 164, 167, 244, +114, 188, 192, 101, 23, 55, 69, 141, 168, 28, 89, 60, 116, 91, 162, 121, +28, 123, 96, 252, 165, 180, 69, 56, 232, 54, 122, 138, 223, 158, 131, 94, +171, 82, 4, 112, 13, 160, 117, 170, 146, 28, 241, 154, 211, 119, 16, 233, +141, 96, 94, 167, 13, 37, 118, 105, 73, 211, 97, 109, 148, 131, 190, 119, +45, 124, 208, 225, 39, 94, 48, 62, 33, 188, 248, 154, 233, 46, 158, 7, +144, 1, 121, 0, 235, 71, 25, 52, 13, 46, 1, 25, 171, 27, 179, 170, +164, 231, 2, 25, 182, 226, 250, 96, 192, 23, 185, 218, 218, 16, 140, 36, +180, 216, 59, 95, 49, 165, 162, 134, 252, 47, 168, 65, 242, 178, 211, 62, +10, 239, 153, 65, 219, 247, 72, 17, 105, 49, 254, 85, 136, 211, 117, 240, +218, 77, 221, 166, 41, 145, 198, 4, 104, 136, 241, 48, 0, 158, 210, 236, +207, 26, 145, 140, 95, 164, 117, 198, 0, 183, 104, 161, 59, 9, 189, 8, +32, 44, 26, 255, 157, 119, 245, 250, 49, 176, 156, 227, 102, 228, 105, 83, +24, 153, 85, 196, 129, 133, 128, 208, 129, 202, 62, 204, 173, 137, 91, 223, +112, 208, 243, 87, 180, 109, 82, 141, 56, 239, 210, 40, 86, 200, 173, 31, +32, 230, 140, 202, 61, 220, 176, 92, 108, 207, 177, 213, 169, 238, 172, 158, +254, 38, 242, 141, 6, 115, 217, 193, 134, 166, 227, 36, 208, 119, 86, 44, +34, 195, 71, 119, 94, 234, 241, 122, 79, 169, 173, 36, 221, 120, 68, 23, +3, 44, 125, 38, 78, 72, 230, 25, 62, 18, 205, 206, 66, 140, 79, 125, +229, 223, 0, 92, 25, 118, 253, 161, 219, 51, 228, 229, 212, 13, 155, 26, +50, 54, 105, 54, 38, 85, 152, 49, 150, 233, 88, 191, 111, 0, 122, 147, +95, 215, 50, 33, 176, 209, 77, 136, 198, 6, 71, 97, 100, 152, 0, 159, +94, 91, 202, 7, 148, 125, 254, 58, 38, 107, 49, 101, 14, 194, 163, 12, +79, 253, 153, 150, 54, 30, 37, 140, 189, 241, 141, 47, 57, 139, 145, 74, +88, 15, 178, 179, 63, 241, 91, 129, 30, 79, 19, 104, 72, 56, 215, 37, +124, 242, 77, 81, 109, 155, 0, 233, 122, 186, 107, 91, 145, 92, 162, 90, +4, 113, 170, 84, 211, 132, 142, 64, 27, 93, 152, 248, 107, 94, 93, 160, +109, 249, 241, 251, 102, 130, 66, 96, 51, 112, 140, 245, 151, 65, 45, 189, +157, 117, 188, 91, 97, 49, 138, 107, 106, 135, 204, 203, 38, 119, 33, 149, +87, 122, 158, 198, 8, 142, 218, 3, 56, 249, 80, 86, 253, 82, 246, 203, +231, 57, 160, 50, 52, 187, 24, 108, 130, 253, 193, 24, 51, 201, 50, 3, +67, 176, 187, 124, 165, 172, 142, 252, 156, 155, 220, 252, 51, 237, 105, 94, +48, 44, 233, 187, 188, 123, 100, 218, 223, 36, 114, 54, 219, 223, 39, 156, +112, 206, 46, 19, 10, 213, 139, 69, 12, 138, 134, 44, 130, 94, 136, 4, +111, 77, 21, 115, 225, 162, 15, 38, 159, 218, 138, 102, 171, 2, 142, 48, +158, 57, 94, 59, 182, 17, 127, 190, 223, 196, 66, 238, 107, 50, 154, 2, +142, 167, 152, 18, 25, 226, 1, 253, 251, 17, 102, 20, 111, 28, 97, 136, +15, 60, 65, 230, 39, 49, 25, 166, 31, 18, 54, 4, 24, 89, 211, 226, +250, 74, 226, 185, 67, 138, 29, 18, 85, 156, 124, 145, 84, 17, 175, 167, +51, 13, 54, 82, 97, 64, 206, 201, 111, 199, 214, 210, 235, 148, 55, 181, +241, 136, 86, 254, 219, 122, 64, 103, 179, 79, 113, 163, 126, 75, 107, 79, +102, 244, 21, 147, 198, 210, 251, 35, 136, 73, 15, 32, 45, 150, 134, 253, +113, 83, 111, 161, 110, 212, 242, 33, 12, 12, 16, 143, 194, 199, 37, 228, +251, 110, 7, 213, 198, 55, 80, 32, 209, 140, 34, 47, 102, 249, 217, 166, +118, 31, 106, 2, 18, 106, 46, 146, 148, 125, 0, 208, 89, 209, 247, 55, +143, 177, 19, 183, 127, 71, 118, 20, 136, 3, 233, 109, 119, 181, 115, 223, +110, 139, 182, 171, 109, 104, 72, 62, 152, 143, 14, 157, 82, 154, 253, 142, +215, 59, 1, 11, 98, 107, 140, 12, 240, 144, 56, 38, 14, 220, 237, 154, +174, 151, 179, 207, 104, 234, 222, 84, 126, 157, 90, 52, 118, 126, 96, 23, +203, 135, 134, 41, 16, 196, 210, 44, 125, 68, 145, 232, 236, 52, 222, 102, +131, 80, 101, 237, 218, 244, 215, 205, 95, 58, 96, 18, 66, 213, 91, 247, +58, 44, 57, 150, 193, 139, 135, 36, 143, 236, 94, 209, 236, 213, 227, 42, +176, 173, 206, 87, 151, 240, 145, 185, 45, 209, 177, 201, 123, 32, 196, 44, +158, 83, 203, 202, 6, 106, 54, 93, 43, 209, 12, 114, 76, 100, 242, 104, +165, 138, 15, 143, 5, 33, 228, 195, 243, 111, 81, 249, 174, 15, 167, 40, +165, 51, 97, 185, 215, 150, 118, 253, 22, 103, 9, 21, 185, 238, 189, 94, +49, 104, 100, 98, 165, 196, 31, 148, 112, 125, 199, 46, 103, 252, 79, 100, +165, 112, 104, 82, 249, 219, 205, 34, 198, 31, 198, 191, 181, 72, 212, 182, +62, 87, 13, 53, 171, 84, 222, 156, 131, 201, 162, 173, 47, 44, 187, 105, +119, 132, 47, 228, 184, 36, 85, 218, 11, 251, 242, 124, 205, 168, 252, 24, +245, 49, 84, 161, 107, 211, 21, 63, 219, 89, 15, 116, 192, 18, 208, 86, +95, 75, 71, 239, 247, 105, 124, 85, 174, 144, 220, 24, 188, 94, 40, 209, +132, 234, 225, 53, 69, 240, 42, 47, 92, 18, 240, 120, 210, 140, 168, 218, +105, 60, 246, 247, 238, 188, 247, 10, 162, 24, 136, 226, 91, 107, 157, 168, +51, 186, 15, 79, 68, 154, 225, 52, 41, 228, 127, 35, 41, 224, 97, 225, +44, 85, 16, 225, 99, 198, 48, 182, 98, 235, 255, 178, 24, 210, 58, 14, +200, 84, 18, 132, 137, 35, 171, 63, 195, 238, 195, 167, 167, 8, 207, 232, +214, 100, 91, 195, 90, 233, 86, 98, 207, 185, 229, 196, 140, 253, 236, 219, +150, 62, 62, 2, 15, 51, 232, 157, 44, 234, 107, 188, 220, 214, 209, 42, +165, 18, 94, 143, 235, 241, 192, 254, 106, 155, 48, 246, 239, 123, 17, 140, +12, 101, 251, 102, 156, 126, 130, 2, 38, 62, 255, 27, 134, 182, 120, 23, +158, 103, 4, 48, 154, 78, 236, 14, 254, 222, 239, 42, 228, 224, 138, 87, +211, 236, 78, 212, 1, 107, 139, 81, 5, 238, 185, 84, 205, 51, 83, 67, +52, 42, 135, 255, 244, 123, 157, 185, 116, 114, 160, 116, 246, 30, 147, 127, +129, 156, 51, 229, 39, 122, 2, 122, 145, 229, 25, 122, 2, 151, 7, 125, +246, 76, 129, 209, 110, 138, 246, 211, 33, 183, 60, 192, 108, 167, 161, 157, +173, 188, 134, 192, 179, 203, 195, 136, 84, 41, 110, 193, 122, 131, 11, 75, +124, 83, 139, 80, 12, 71, 93, 214, 179, 43, 70, 139, 91, 53, 228, 97, +105, 67, 230, 118, 92, 183, 131, 114, 231, 74, 140, 48, 135, 180, 10, 184, +148, 46, 75, 182, 205, 83, 47, 151, 206, 84, 243, 232, 233, 126, 142, 30, +11, 113, 219, 252, 153, 18, 16, 215, 238, 121, 155, 255, 21, 214, 89, 6, +196, 3, 201, 131, 48, 187, 159, 235, 14, 27, 155, 245, 77, 229, 130, 112, +168, 164, 253, 69, 23, 253, 242, 175, 19, 232, 155, 161, 27, 158, 95, 160, +90, 79, 109, 133, 203, 42, 70, 181, 120, 247, 244, 85, 191, 167, 255, 36, +251, 115, 54, 191, 78, 211, 182, 252, 5, 12, 100, 32, 48, 200, 26, 234, +123, 25, 161, 253, 134, 168, 60, 15, 187, 62, 24, 239, 177, 98, 92, 109, +195, 112, 78, 242, 161, 250, 224, 210, 94, 111, 34, 100, 196, 71, 103, 74, +123, 216, 217, 180, 160, 33, 64, 105, 123, 183, 125, 84, 77, 80, 99, 109, +247, 173, 168, 239, 122, 88, 233, 117, 237, 148, 43, 144, 195, 255, 222, 124, +214, 133, 156, 117, 244, 7, 73, 13, 100, 164, 68, 175, 191, 93, 225, 252, +128, 96, 77, 231, 196, 150, 223, 120, 56, 23, 101, 94, 23, 50, 76, 38, +27, 89, 184, 93, 140, 37, 79, 249, 66, 199, 27, 220, 230, 114, 176, 179, +228, 201, 12, 56, 113, 1, 25, 207, 104, 177, 191, 79, 237, 143, 226, 104, +92, 21, 249, 98, 205, 22, 105, 215, 184, 142, 178, 107, 8, 194, 13, 32, +156, 84, 109, 146, 152, 57, 241, 72, 62, 74, 122, 212, 88, 179, 57, 23, +186, 74, 73, 82, 37, 80, 182, 165, 40, 89, 30, 244, 209, 110, 163, 24, +182, 201, 139, 145, 225, 148, 219, 184, 1, 109, 99, 156, 37, 247, 177, 111, +50, 209, 221, 208, 78, 0, 72, 6, 236, 76, 79, 63, 132, 26, 227, 72, +142, 229, 248, 120, 160, 148, 155, 91, 51, 61, 40, 22, 192, 96, 139, 193, +192, 41, 116, 79, 140, 116, 158, 248, 64, 168, 227, 174, 56, 114, 92, 160, +31, 200, 94, 82, 99, 139, 67, 95, 47, 76, 180, 152, 43, 131, 149, 177, +4, 212, 56, 209, 190, 209, 102, 122, 224, 72, 234, 244, 111, 175, 138, 120, +23, 203, 9, 146, 234, 239, 94, 241, 28, 21, 170, 51, 2, 176, 125, 179, +217, 99, 83, 17, 16, 113, 123, 111, 68, 94, 156, 200, 90, 117, 30, 174, +131, 42, 161, 91, 76, 85, 199, 44, 75, 199, 0, 159, 111, 158, 236, 63, +252, 73, 67, 220, 113, 169, 158, 74, 7, 81, 214, 149, 155, 222, 129, 91, +63, 169, 196, 168, 208, 230, 83, 168, 4, 19, 27, 176, 157, 146, 56, 42, +254, 143, 171, 119, 60, 127, 57, 37, 107, 84, 255, 246, 76, 159, 38, 176, +233, 13, 97, 107, 64, 55, 206, 201, 204, 218, 3, 139, 123, 150, 151, 110, +28, 198, 99, 247, 167, 155, 37, 184, 253, 214, 21, 253, 250, 179, 26, 233, +98, 205, 117, 109, 94, 222, 15, 151, 184, 119, 219, 159, 26, 52, 234, 55, +66, 100, 108, 175, 174, 17, 111, 135, 189, 244, 238, 173, 23, 17, 241, 136, +78, 124, 75, 203, 114, 135, 228, 221, 79, 244, 180, 84, 215, 120, 58, 193, +234, 17, 21, 132, 110, 10, 93, 93, 0, 183, 245, 134, 61, 95, 68, 191, +141, 237, 95, 126, 87, 58, 149, 134, 213, 110, 116, 216, 192, 10, 112, 38, +232, 50, 35, 120, 57, 45, 172, 232, 37, 77, 226, 153, 110, 131, 253, 210, +168, 180, 83, 56, 51, 56, 189, 222, 97, 193, 136, 138, 42, 148, 50, 111, +24, 19, 254, 177, 109, 42, 4, 65, 172, 96, 251, 160, 54, 58, 165, 202, +64, 75, 38, 58, 75, 176, 216, 98, 146, 125, 118, 248, 14, 106, 228, 226, +81, 241, 251, 127, 27, 23, 92, 157, 140, 12, 59, 86, 252, 122, 13, 128, +14, 184, 55, 155, 44, 253, 29, 47, 123, 191, 185, 154, 163, 114, 250, 216, +48, 218, 24, 41, 137, 186, 200, 209, 147, 86, 234, 11, 251, 42, 56, 181, +243, 238, 166, 135, 92, 151, 86, 174, 89, 79, 71, 14, 24, 5, 179, 87, +131, 135, 102, 59, 186, 66, 1, 6, 72, 5, 28, 79, 49, 186, 194, 62, +179, 53, 186, 31, 143, 15, 105, 32, 251, 188, 138, 11, 244, 36, 100, 101, +80, 187, 253, 53, 90, 154, 212, 181, 126, 209, 58, 10, 55, 168, 27, 236, +115, 101, 224, 193, 103, 231, 231, 76, 130, 169, 64, 247, 143, 160, 6, 12, +187, 62, 115, 85, 133, 97, 131, 157, 164, 5, 18, 51, 69, 53, 226, 170, +32, 248, 133, 194, 58, 114, 243, 156, 53, 219, 228, 37, 51, 150, 240, 227, +74, 100, 66, 140, 115, 100, 103, 47, 160, 145, 39, 160, 75, 222, 218, 28, +108, 232, 107, 91, 0, 57, 250, 136, 6, 33, 118, 115, 103, 179, 221, 108, +40, 142, 175, 185, 2, 12, 192, 66, 213, 152, 41, 233, 223, 41, 212, 85, +17, 52, 58, 211, 181, 46, 211, 206, 189, 26, 8, 90, 115, 224, 151, 195, +224, 213, 34, 162, 189, 222, 218, 155, 78, 201, 101, 242, 9, 56, 215, 152, +239, 247, 121, 3, 16, 221, 56, 45, 35, 243, 146, 128, 44, 114, 215, 132, +101, 220, 233, 180, 2, 29, 87, 203, 185, 144, 16, 37, 113, 60, 244, 214, +140, 191, 24, 192, 37, 255, 161, 147, 216, 30, 40, 155, 88, 60, 186, 135, +11, 23, 228, 43, 157, 203, 102, 196, 197, 1, 1, 87, 218, 126, 80, 76, +30, 182, 207, 153, 135, 248, 6, 181, 215, 77, 128, 200, 10, 19, 107, 138, +202, 84, 120, 191, 140, 117, 50, 32, 27, 105, 174, 224, 170, 123, 53, 76, +48, 210, 6, 227, 195, 114, 235, 87, 145, 150, 26, 21, 17, 214, 198, 245, +125, 109, 156, 170, 204, 143, 228, 62, 196, 128, 21, 243, 153, 91, 71, 164, +113, 164, 255, 48, 36, 238, 105, 220, 163, 93, 3, 33, 47, 150, 241, 211, +190, 111, 157, 234, 189, 25, 58, 247, 75, 118, 247, 167, 171, 118, 223, 1, +180, 98, 83, 0, 2, 109, 17, 255, 116, 244, 107, 101, 220, 100, 70, 21, +133, 179, 90, 210, 116, 32, 197, 24, 82, 114, 120, 218, 14, 147, 80, 194, +80, 69, 78, 223, 157, 183, 130, 49, 139, 162, 34, 12, 176, 45, 242, 103, +232, 128, 68, 88, 225, 181, 149, 3, 210, 20, 38, 155, 6, 206, 136, 22, +170, 92, 156, 165, 116, 142, 250, 72, 203, 235, 193, 116, 244, 4, 209, 55, +186, 29, 8, 33, 193, 221, 73, 27, 212, 204, 22, 197, 179, 8, 122, 134, +8, 255, 96, 51, 2, 169, 193, 96, 128, 178, 109, 143, 131, 50, 219, 208, +58, 159, 103, 233, 100, 26, 2, 177, 129, 122, 168, 120, 71, 39, 115, 228, +108, 114, 161, 243, 24, 10, 221, 105, 0, 32, 230, 75, 208, 233, 4, 70, +249, 98, 37, 46, 87, 158, 145, 60, 85, 229, 199, 236, 126, 80, 183, 181, +12, 68, 3, 15, 23, 36, 92, 146, 109, 61, 24, 128, 78, 239, 88, 230, +215, 204, 90, 147, 118, 171, 51, 168, 95, 93, 23, 90, 244, 164, 172, 201, +222, 112, 143, 193, 209, 130, 201, 207, 118, 175, 51, 3, 83, 144, 53, 7, +2, 223, 146, 50, 101, 168, 159, 133, 28, 66, 29, 64, 233, 76, 182, 133, +172, 68, 223, 114, 254, 236, 111, 30, 73, 137, 130, 164, 131, 196, 189, 111, +155, 147, 217, 64, 194, 115, 143, 201, 77, 22, 153, 228, 83, 191, 53, 210, +87, 234, 21, 34, 187, 184, 28, 63, 179, 214, 83, 14, 112, 32, 169, 159, +133, 207, 19, 169, 188, 147, 111, 186, 114, 43, 118, 152, 25, 71, 184, 247, +239, 62, 39, 125, 8, 176, 91, 46, 127, 37, 169, 247, 186, 170, 231, 106, +124, 93, 82, 203, 135, 50, 177, 85, 74, 115, 219, 76, 96, 173, 44, 242, +38, 163, 171, 14, 0, 95, 76, 99, 75, 14, 39, 213, 116, 182, 72, 2, +234, 176, 65, 98, 150, 36, 70, 86, 137, 151, 218, 245, 141, 17, 24, 233, +41, 185, 58, 178, 56, 54, 122, 148, 231, 151, 41, 214, 96, 4, 243, 46, +63, 200, 233, 128, 161, 95, 138, 244, 183, 141, 145, 14, 25, 91, 197, 70, +3, 227, 187, 203, 223, 48, 120, 113, 7, 0, 130, 193, 160, 67, 108, 185, +71, 237, 171, 101, 159, 96, 98, 34, 4, 142, 114, 155, 160, 147, 193, 170, +48, 115, 253, 172, 245, 59, 145, 176, 55, 203, 245, 60, 24, 247, 235, 79, +12, 117, 74, 18, 151, 14, 208, 7, 227, 230, 138, 182, 107, 33, 172, 211, +232, 244, 91, 86, 80, 237, 55, 154, 175, 32, 221, 17, 151, 79, 104, 238, +25, 226, 76, 155, 72, 39, 90, 209, 93, 119, 54, 17, 9, 222, 62, 18, +136, 25, 15, 59, 194, 203, 57, 150, 0, 52, 122, 104, 84, 199, 104, 180, +154, 180, 177, 141, 173, 169, 154, 113, 35, 75, 198, 157, 150, 80, 44, 212, +248, 174, 232, 251, 140, 74, 214, 189, 41, 120, 113, 156, 65, 16, 15, 201, +18, 45, 16, 210, 104, 247, 38, 33, 40, 249, 61, 119, 153, 179, 72, 88, +122, 109, 208, 91, 186, 231, 246, 201, 154, 26, 36, 115, 126, 217, 44, 194, +140, 103, 229, 15, 250, 227, 140, 106, 204, 118, 169, 157, 84, 150, 31, 128, +194, 254, 144, 221, 84, 79, 211, 148, 33, 60, 107, 211, 170, 159, 248, 105, +63, 114, 0, 23, 234, 92, 230, 240, 118, 6, 250, 181, 184, 227, 64, 186, +40, 94, 67, 225, 133, 89, 15, 16, 174, 144, 165, 59, 6, 73, 13, 18, +29, 10, 46, 237, 23, 51, 33, 27, 193, 212, 63, 194, 5, 79, 66, 177, +81, 200, 84, 254, 225, 36, 110, 208, 225, 202, 213, 89, 214, 140, 142, 227, +223, 60, 214, 19, 145, 92, 92, 164, 207, 222, 158, 250, 12, 146, 150, 67, +204, 120, 211, 109, 95, 186, 40, 167, 178, 90, 34, 46, 234, 28, 109, 171, +182, 83, 197, 36, 51, 69, 152, 168, 121, 48, 71, 179, 22, 218, 168, 182, +160, 147, 195, 177, 176, 201, 234, 213, 209, 135, 222, 9, 1, 157, 170, 240, +175, 246, 218, 255, 92, 53, 102, 171, 22, 235, 180, 248, 118, 10, 85, 14, +24, 218, 184, 132, 191, 225, 112, 66, 3, 231, 36, 235, 34, 214, 181, 57, +104, 151, 76, 69, 101, 83, 20, 39, 170, 108, 161, 239, 236, 126, 9, 144, +27, 117, 209, 174, 173, 92, 16, 185, 25, 8, 65, 29, 134, 67, 1, 248, +62, 221, 239, 134, 12, 15, 252, 203, 140, 179, 52, 247, 3, 230, 34, 184, +102, 82, 118, 76, 218, 254, 242, 24, 115, 22, 119, 90, 4, 149, 236, 176, +116, 68, 77, 123, 201, 192, 255, 188, 107, 195, 3, 217, 184, 106, 219, 116, +81, 207, 193, 227, 101, 41, 29, 232, 72, 85, 236, 151, 74, 93, 150, 166, +171, 155, 81, 131, 81, 109, 171, 184, 37, 190, 114, 106, 113, 144, 234, 76, +143, 92, 98, 190, 112, 151, 198, 151, 181, 99, 7, 182, 50, 190, 157, 141, +17, 199, 148, 230, 14, 240, 95, 238, 139, 161, 96, 85, 137, 154, 79, 67, +168, 101, 253, 126, 23, 165, 143, 47, 33, 157, 100, 6, 130, 253, 188, 66, +21, 205, 243, 116, 62, 241, 161, 177, 199, 234, 61, 135, 55, 113, 25, 153, +27, 129, 149, 189, 140, 112, 211, 49, 176, 38, 44, 110, 29, 135, 178, 122, +233, 3, 166, 97, 175, 61, 159, 98, 61, 54, 46, 62, 246, 137, 17, 150, +249, 165, 99, 211, 172, 76, 7, 104, 39, 106, 119, 221, 159, 210, 96, 33, +236, 87, 164, 112, 47, 226, 247, 236, 140, 185, 182, 20, 201, 51, 88, 97, +52, 198, 70, 49, 248, 96, 51, 82, 115, 169, 78, 73, 112, 123, 106, 120, +113, 184, 93, 194, 224, 68, 211, 200, 237, 209, 41, 160, 127, 89, 163, 55, +9, 27, 252, 78, 93, 147, 141, 12, 156, 44, 226, 106, 126, 159, 181, 106, +84, 25, 39, 220, 41, 134, 184, 173, 69, 141, 128, 221, 57, 194, 56, 41, +148, 107, 242, 241, 174, 129, 152, 123, 81, 101, 1, 204, 9, 109, 154, 97, +169, 63, 167, 52, 96, 239, 63, 116, 163, 122, 158, 94, 221, 35, 90, 184, +69, 186, 220, 155, 205, 65, 191, 31, 209, 62, 120, 156, 77, 154, 212, 58, +165, 208, 254, 65, 204, 148, 200, 121, 78, 129, 79, 121, 39, 34, 3, 169, +118, 120, 52, 35, 119, 142, 29, 15, 144, 156, 90, 134, 101, 105, 11, 112, +32, 74, 0, 219, 159, 132, 100, 7, 106, 88, 142, 42, 159, 159, 133, 11, +175, 92, 88, 144, 12, 55, 185, 47, 142, 31, 43, 39, 16, 83, 122, 54, +7, 150, 158, 215, 14, 143, 136, 147, 141, 231, 157, 67, 152, 119, 164, 114, +159, 71, 210, 144, 98, 127, 44, 132, 218, 170, 183, 6, 185, 210, 94, 95, +99, 240, 116, 30, 126, 76, 115, 212, 246, 102, 92, 96, 159, 252, 177, 173, +238, 87, 145, 120, 239, 83, 103, 148, 111, 193, 200, 157, 199, 84, 245, 167, +68, 43, 9, 69, 55, 83, 164, 109, 90, 46, 101, 215, 36, 23, 74, 170, +73, 31, 151, 63, 13, 233, 151, 107, 248, 28, 92, 35, 70, 5, 235, 85, +219, 20, 213, 153, 157, 249, 176, 37, 255, 191, 49, 221, 195, 243, 205, 150, +238, 234, 168, 137, 153, 201, 222, 205, 199, 162, 119, 146, 41, 89, 105, 114, +144, 27, 194, 167, 15, 17, 102, 155, 81, 20, 64, 25, 235, 217, 63, 154, +242, 225, 13, 33, 182, 38, 116, 47, 107, 50, 207, 110, 29, 136, 55, 33, +139, 136, 214, 63, 92, 125, 90, 118, 202, 7, 13, 45, 43, 162, 106, 53, +143, 13, 190, 171, 226, 196, 144, 17, 49, 136, 120, 246, 99, 28, 219, 184, +171, 145, 232, 242, 225, 86, 216, 29, 251, 249, 41, 244, 144, 111, 2, 13, +67, 69, 97, 59, 202, 92, 254, 71, 189, 6, 119, 180, 186, 203, 34, 18, +85, 115, 103, 178, 15, 139, 42, 154, 39, 24, 0, 19, 22, 240, 255, 252, +93, 217, 151, 118, 89, 76, 228, 117, 200, 137, 13, 190, 247, 255, 24, 253, +162, 24, 184, 20, 70, 173, 242, 65, 255, 14, 85, 235, 99, 103, 131, 181, +84, 80, 63, 156, 184, 204, 191, 61, 156, 252, 59, 37, 109, 229, 102, 139, +94, 178, 178, 164, 231, 49, 155, 35, 56, 196, 15, 169, 144, 251, 215, 89, +129, 230, 72, 219, 139, 197, 78, 109, 102, 25, 48, 44, 123, 211, 216, 106, +185, 237, 124, 133, 39, 37, 162, 20, 211, 134, 155, 168, 11, 222, 152, 143, +211, 112, 133, 136, 21, 169, 89, 187, 92, 61, 144, 126, 142, 165, 91, 64, +45, 41, 56, 164, 108, 49, 241, 137, 99, 44, 191, 100, 11, 225, 166, 244, +183, 14, 69, 141, 184, 193, 220, 72, 211, 67, 223, 16, 43, 227, 34, 87, +91, 32, 229, 84, 162, 113, 251, 125, 218, 118, 31, 254, 16, 33, 170, 201, +209, 49, 30, 113, 104, 193, 212, 82, 64, 80, 214, 32, 149, 217, 244, 237, +193, 223, 104, 77, 128, 228, 140, 55, 252, 204, 229, 187, 36, 99, 153, 241, +138, 135, 171, 169, 62, 250, 184, 63, 167, 139, 183, 57, 170, 36, 217, 201, +129, 169, 222, 78, 153, 65, 153, 195, 211, 229, 159, 191, 0, 145, 12, 209, +25, 247, 122, 19, 108, 173, 163, 187, 235, 254, 87, 80, 25, 110, 179, 158, +48, 232, 20, 138, 81, 198, 78, 18, 44, 75, 181, 18, 238, 96, 61, 247, +229, 254, 2, 55, 169, 32, 180, 136, 177, 161, 213, 132, 128, 108, 93, 159, +201, 212, 238, 223, 233, 186, 243, 4, 248, 5, 33, 214, 193, 214, 95, 51, +141, 60, 72, 63, 142, 184, 37, 122, 118, 136, 97, 93, 142, 245, 8, 147, +224, 126, 67, 93, 170, 105, 121, 231, 171, 85, 105, 191, 126, 88, 57, 42, +253, 179, 85, 251, 193, 163, 112, 71, 28, 137, 104, 199, 121, 13, 122, 58, +231, 160, 176, 50, 200, 80, 65, 99, 25, 67, 129, 91, 97, 178, 131, 195, +111, 148, 134, 71, 57, 145, 113, 209, 177, 51, 154, 29, 28, 180, 74, 13, +69, 147, 96, 210, 108, 176, 89, 248, 238, 64, 140, 85, 196, 169, 20, 251, +238, 194, 41, 56, 39, 59, 226, 189, 130, 178, 90, 176, 226, 46, 108, 156, +204, 174, 85, 118, 165, 137, 184, 160, 133, 89, 170, 184, 37, 48, 65, 241, +224, 117, 164, 248, 213, 112, 143, 128, 23, 130, 133, 216, 66, 190, 63, 238, +179, 84, 71, 27, 50, 83, 199, 91, 126, 164, 192, 76, 107, 100, 229, 6, +25, 164, 89, 235, 117, 247, 61, 109, 205, 76, 128, 230, 41, 243, 85, 58, +189, 128, 216, 21, 53, 68, 80, 1, 25, 171, 203, 71, 176, 46, 6, 84, +35, 150, 95, 144, 144, 253, 210, 78, 10, 31, 218, 179, 248, 95, 81, 244, +79, 215, 63, 196, 100, 165, 120, 54, 14, 180, 125, 152, 106, 173, 125, 14, +108, 211, 161, 131, 229, 114, 56, 252, 16, 221, 16, 242, 74, 87, 168, 121, +127, 247, 212, 200, 71, 204, 116, 246, 255, 154, 24, 137, 127, 45, 177, 212, +17, 212, 102, 236, 29, 88, 177, 166, 135, 107, 210, 230, 219, 124, 71, 98, +50, 230, 107, 222, 79, 222, 190, 37, 241, 242, 167, 27, 117, 253, 201, 76, +251, 186, 18, 135, 96, 191, 207, 15, 107, 67, 146, 251, 105, 102, 25, 200, +71, 209, 165, 125, 192, 18, 228, 162, 238, 214, 221, 138, 49, 40, 100, 122, +249, 20, 121, 57, 199, 11, 0, 243, 76, 57, 23, 211, 110, 212, 250, 218, +95, 154, 145, 179, 173, 45, 233, 155, 246, 67, 35, 203, 93, 5, 2, 91, +121, 116, 93, 64, 69, 31, 182, 179, 74, 59, 198, 41, 19, 102, 51, 76, +126, 224, 153, 65, 254, 186, 90, 16, 91, 220, 154, 130, 20, 187, 103, 141, +248, 188, 245, 250, 139, 191, 48, 138, 40, 199, 201, 155, 147, 83, 62, 254, +80, 3, 107, 104, 36, 103, 186, 94, 186, 225, 107, 167, 118, 230, 199, 85, +241, 219, 139, 20, 28, 233, 5, 131, 144, 101, 21, 228, 236, 249, 115, 82, +62, 147, 175, 251, 174, 128, 176, 255, 248, 142, 239, 113, 165, 254, 238, 22, +99, 162, 202, 108, 79, 235, 246, 32, 220, 11, 51, 239, 109, 4, 204, 179, +212, 86, 38, 5, 232, 170, 76, 151, 131, 165, 206, 122, 105, 124, 107, 28, +137, 196, 99, 194, 6, 122, 29, 75, 178, 26, 232, 70, 33, 231, 24, 73, +33, 187, 181, 240, 75, 22, 114, 163, 98, 114, 6, 93, 2, 32, 16, 79, +93, 119, 219, 153, 15, 182, 129, 123, 242, 162, 182, 152, 200, 24, 14, 95, +48, 35, 60, 237, 71, 183, 152, 92, 134, 31, 82, 174, 53, 155, 170, 96, +221, 93, 137, 90, 31, 128, 20, 131, 15, 86, 154, 93, 190, 178, 124, 214, +130, 43, 64, 134, 249, 0, 48, 215, 92, 236, 202, 24, 47, 60, 232, 190, +124, 3, 71, 145, 183, 215, 240, 1, 100, 235, 203, 185, 205, 122, 222, 41, +199, 127, 4, 74, 57, 92, 80, 227, 109, 81, 197, 32, 38, 35, 53, 94, +245, 9, 141, 245, 223, 223, 95, 42, 175, 157, 209, 215, 90, 64, 0, 248, +244, 246, 25, 60, 7, 169, 138, 246, 184, 96, 155, 68, 94, 155, 22, 15, +241, 169, 20, 49, 215, 209, 111, 239, 200, 144, 5, 33, 153, 142, 239, 148, +110, 117, 109, 248, 67, 98, 109, 157, 187, 172, 160, 169, 85, 54, 0, 153, +129, 217, 150, 67, 124, 151, 101, 106, 131, 207, 134, 5, 255, 139, 146, 192, +0, 115, 91, 6, 129, 58, 60, 103, 106, 223, 52, 211, 102, 252, 153, 7, +36, 34, 32, 136, 111, 24, 231, 218, 101, 114, 49, 128, 185, 58, 235, 26, +108, 148, 216, 2, 109, 127, 76, 170, 230, 167, 77, 230, 144, 120, 234, 183, +78, 246, 204, 228, 134, 249, 88, 100, 196, 198, 168, 113, 216, 42, 35, 193, +234, 34, 195, 152, 125, 79, 79, 24, 161, 173, 16, 174, 46, 67, 170, 131, +156, 232, 86, 89, 173, 30, 39, 209, 177, 50, 137, 84, 109, 203, 25, 179, +105, 42, 151, 141, 56, 47, 146, 109, 175, 225, 243, 210, 206, 81, 196, 237, +159, 201, 165, 55, 181, 153, 69, 153, 117, 118, 217, 130, 65, 139, 68, 118, +59, 201, 202, 82, 129, 162, 23, 102, 61, 155, 109, 206, 125, 41, 111, 139, +83, 174, 133, 242, 44, 2, 235, 186, 58, 247, 99, 136, 173, 106, 250, 248, +34, 152, 133, 3, 208, 170, 129, 23, 60, 73, 212, 46, 191, 190, 88, 207, +221, 164, 178, 45, 215, 131, 204, 225, 117, 173, 138, 180, 3, 0, 15, 14, +221, 73, 184, 22, 167, 83, 216, 31, 137, 254, 108, 90, 21, 235, 5, 68, +143, 236, 218, 177, 170, 239, 180, 8, 168, 140, 226, 189, 16, 145, 62, 163, +225, 93, 205, 37, 120, 98, 129, 249, 129, 253, 213, 174, 200, 19, 143, 140, +9, 177, 50, 105, 134, 69, 113, 244, 133, 6, 120, 25, 155, 132, 254, 226, +207, 43, 56, 168, 69, 169, 95, 83, 166, 34, 69, 213, 187, 98, 243, 119, +143, 121, 249, 119, 129, 165, 103, 146, 140, 13, 136, 238, 160, 170, 253, 171, +212, 98, 239, 172, 195, 249, 68, 207, 60, 24, 130, 128, 167, 163, 178, 130, +220, 6, 139, 198, 201, 110, 26, 91, 155, 144, 143, 212, 85, 106, 50, 198, +74, 210, 168, 146, 232, 172, 30, 152, 206, 69, 44, 47, 88, 165, 180, 221, +45, 252, 248, 47, 26, 33, 142, 189, 77, 77, 20, 185, 247, 249, 88, 67, +117, 249, 151, 118, 57, 18, 137, 128, 189, 134, 148, 85, 7, 47, 60, 142, +110, 105, 252, 45, 165, 187, 134, 50, 255, 180, 56, 130, 137, 76, 189, 218, +152, 46, 148, 44, 1, 239, 47, 72, 192, 70, 14, 74, 90, 136, 245, 35, +40, 171, 29, 17, 97, 77, 184, 32, 38, 38, 252, 12, 0, 226, 11, 222, +132, 183, 121, 209, 83, 3, 164, 243, 32, 111, 109, 145, 203, 57, 241, 192, +5, 107, 164, 128, 3, 218, 69, 178, 200, 222, 45, 65, 105, 110, 115, 184, +75, 243, 221, 49, 226, 170, 189, 49, 246, 129, 33, 150, 38, 203, 3, 214, +111, 206, 150, 168, 137, 162, 228, 3, 96, 105, 184, 27, 106, 81, 32, 147, +230, 60, 219, 199, 176, 74, 100, 18, 80, 140, 70, 128, 115, 119, 111, 82, +172, 8, 6, 168, 188, 56, 197, 112, 159, 169, 216, 200, 90, 251, 104, 112, +19, 179, 71, 59, 181, 138, 224, 158, 252, 148, 50, 65, 55, 33, 120, 142, +137, 108, 20, 142, 236, 144, 89, 197, 190, 188, 19, 102, 227, 240, 38, 170, +129, 123, 69, 123, 193, 13, 37, 133, 44, 167, 210, 141, 172, 154, 208, 42, +156, 35, 126, 176, 1, 98, 193, 135, 102, 235, 229, 22, 34, 187, 18, 111, +64, 83, 107, 17, 157, 241, 117, 59, 8, 211, 60, 200, 87, 184, 89, 132, +249, 60, 18, 81, 237, 225, 53, 221, 131, 255, 218, 64, 239, 194, 7, 181, +40, 3, 46, 108, 220, 52, 108, 62, 254, 140, 37, 116, 15, 40, 169, 90, +47, 136, 102, 253, 7, 223, 132, 207, 60, 234, 21, 134, 155, 63, 112, 37, +72, 222, 55, 59, 20, 34, 167, 71, 222, 221, 164, 161, 92, 131, 244, 235, +243, 237, 184, 129, 77, 165, 160, 139, 171, 234, 234, 69, 113, 128, 93, 215, +9, 84, 41, 213, 35, 164, 24, 120, 204, 180, 178, 153, 47, 245, 57, 22, +175, 206, 12, 175, 203, 129, 39, 93, 127, 18, 12, 55, 43, 36, 252, 1, +104, 116, 59, 135, 193, 145, 183, 41, 62, 78, 165, 189, 232, 128, 224, 11, +142, 255, 2, 223, 95, 80, 219, 87, 249, 121, 31, 181, 50, 241, 31, 127, +174, 99, 238, 176, 116, 65, 220, 160, 189, 25, 204, 103, 20, 231, 42, 195, +34, 180, 105, 121, 110, 99, 149, 139, 1, 221, 124, 67, 172, 47, 189, 207, +14, 229, 79, 158, 187, 203, 126, 236, 14, 53, 121, 243, 132, 78, 39, 72, +7, 165, 22, 78, 41, 101, 128, 20, 168, 136, 198, 109, 226, 32, 135, 168, +104, 155, 115, 57, 50, 66, 17, 72, 245, 124, 70, 188, 194, 144, 89, 140, +85, 8, 10, 129, 227, 167, 15, 15, 201, 54, 239, 194, 154, 204, 129, 27, +190, 245, 102, 166, 178, 201, 7, 197, 78, 149, 69, 245, 4, 143, 4, 84, +13, 217, 59, 242, 223, 226, 199, 231, 118, 188, 55, 115, 56, 15, 217, 3, +0, 181, 190, 3, 162, 127, 120, 206, 181, 8, 225, 155, 148, 202, 117, 70, +96, 81, 246, 165, 253, 115, 148, 217, 138, 44, 203, 36, 44, 221, 59, 122, +68, 170, 248, 235, 88, 242, 209, 42, 71, 31, 117, 5, 149, 221, 216, 154, +116, 41, 231, 138, 123, 85, 128, 71, 109, 111, 17, 72, 163, 225, 109, 7, +40, 133, 74, 76, 155, 107, 34, 193, 114, 240, 61, 31, 24, 46, 215, 197, +96, 114, 213, 18, 214, 57, 119, 50, 18, 5, 175, 254, 21, 246, 64, 145, +171, 217, 243, 159, 250, 231, 228, 64, 164, 97, 61, 150, 9, 230, 11, 138, +132, 95, 209, 138, 97, 87, 139, 190, 171, 135, 158, 170, 99, 198, 18, 127, +44, 102, 1, 236, 90, 73, 214, 135, 116, 107, 247, 175, 46, 238, 51, 79, +163, 249, 5, 137, 145, 92, 138, 23, 207, 158, 50, 109, 131, 84, 61, 184, +252, 232, 20, 67, 107, 189, 61, 198, 27, 6, 189, 119, 34, 236, 94, 105, +65, 140, 181, 248, 32, 12, 119, 126, 0, 14, 226, 78, 7, 121, 111, 47, +30, 49, 206, 187, 125, 247, 235, 6, 229, 34, 161, 174, 72, 154, 37, 94, +8, 88, 125, 54, 182, 100, 46, 84, 144, 213, 251, 62, 71, 177, 120, 255, +194, 14, 105, 206, 151, 179, 144, 140, 191, 167, 248, 44, 70, 227, 154, 142, +32, 174, 159, 199, 154, 78, 165, 68, 96, 73, 8, 13, 246, 162, 155, 48, +7, 121, 90, 173, 40, 226, 166, 189, 35, 87, 225, 45, 209, 220, 70, 22, +156, 216, 39, 126, 84, 142, 207, 100, 219, 155, 166, 43, 253, 161, 255, 143, +148, 93, 17, 7, 109, 176, 112, 14, 87, 147, 186, 123, 32, 159, 252, 83, +111, 182, 250, 28, 239, 207, 92, 64, 17, 26, 216, 0, 41, 24, 142, 246, +19, 172, 32, 137, 234, 69, 147, 251, 234, 207, 95, 6, 113, 209, 107, 69, +122, 198, 148, 13, 18, 28, 238, 191, 168, 205, 144, 234, 181, 247, 192, 151, +176, 95, 157, 60, 224, 26, 120, 24, 16, 66, 102, 51, 185, 111, 39, 6, +205, 187, 16, 1, 141, 45, 234, 48, 144, 26, 92, 155, 213, 218, 88, 151, +0, 111, 109, 28, 44, 172, 24, 215, 205, 186, 42, 119, 124, 48, 41, 199, +85, 81, 244, 24, 170, 71, 156, 141, 249, 234, 193, 174, 77, 184, 47, 107, +112, 235, 124, 254, 7, 163, 156, 71, 59, 122, 224, 196, 215, 71, 81, 145, +207, 178, 97, 118, 45, 154, 109, 190, 143, 63, 83, 135, 110, 166, 174, 47, +195, 33, 0, 234, 212, 223, 11, 248, 210, 158, 17, 139, 239, 15, 57, 133, +185, 152, 71, 56, 2, 62, 10, 103, 243, 247, 182, 81, 10, 38, 49, 7, +131, 10, 202, 184, 79, 149, 84, 213, 122, 133, 208, 24, 141, 132, 12, 244, +251, 160, 41, 56, 219, 123, 120, 23, 240, 40, 29, 32, 213, 222, 36, 49, +173, 176, 11, 209, 145, 104, 154, 154, 182, 183, 5, 60, 131, 70, 224, 47, +125, 110, 47, 246, 180, 222, 125, 243, 251, 55, 25, 147, 77, 164, 116, 218, +152, 191, 244, 47, 199, 68, 208, 209, 49, 90, 197, 176, 2, 191, 127, 198, +48, 16, 168, 243, 41, 195, 50, 175, 33, 172, 92, 185, 254, 96, 221, 65, +24, 36, 187, 10, 104, 242, 101, 185, 176, 206, 215, 166, 82, 189, 245, 208, +62, 38, 207, 97, 192, 45, 46, 98, 66, 201, 69, 95, 206, 211, 204, 225, +137, 204, 100, 110, 58, 84, 29, 112, 144, 51, 15, 1, 170, 79, 41, 239, +77, 1, 208, 209, 80, 208, 214, 27, 168, 153, 229, 188, 40, 250, 13, 240, +23, 96, 54, 235, 23, 202, 165, 215, 109, 143, 163, 161, 136, 101, 109, 98, +102, 54, 231, 141, 157, 22, 5, 201, 89, 10, 241, 113, 225, 185, 234, 128, +212, 206, 186, 59, 114, 79, 69, 43, 171, 208, 219, 63, 219, 112, 54, 77, +156, 116, 150, 140, 113, 186, 79, 131, 109, 231, 205, 170, 253, 131, 97, 141, +107, 242, 5, 238, 167, 32, 135, 194, 143, 151, 71, 22, 81, 254, 84, 120, +103, 131, 61, 86, 126, 66, 51, 201, 0, 170, 70, 18, 38, 152, 225, 3, +117, 98, 100, 141, 114, 39, 161, 189, 146, 148, 43, 55, 189, 18, 157, 181, +185, 7, 117, 77, 56, 229, 91, 80, 233, 79, 165, 140, 24, 98, 197, 130, +50, 70, 44, 111, 230, 241, 92, 204, 246, 78, 19, 18, 231, 219, 201, 207, +84, 205, 137, 138, 113, 45, 4, 72, 145, 204, 3, 86, 230, 200, 208, 166, +218, 183, 217, 21, 89, 23, 40, 107, 161, 68, 230, 96, 236, 91, 106, 15, +38, 255, 132, 13, 248, 98, 106, 177, 223, 54, 247, 114, 82, 147, 161, 42, +43, 10, 192, 12, 94, 200, 248, 200, 85, 231, 247, 246, 201, 221, 180, 217, +113, 12, 222, 88, 53, 21, 6, 26, 214, 220, 152, 253, 92, 56, 158, 17, +233, 218, 95, 234, 91, 97, 71, 148, 11, 3, 226, 199, 250, 201, 132, 92, +244, 18, 210, 248, 212, 89, 182, 96, 73, 121, 250, 222, 59, 121, 118, 19, +28, 221, 126, 48, 119, 190, 217, 72, 194, 91, 4, 213, 17, 137, 34, 246, +7, 6, 143, 245, 97, 192, 252, 55, 145, 82, 10, 77, 111, 31, 80, 74, +156, 14, 68, 111, 82, 76, 168, 203, 9, 220, 54, 233, 175, 186, 169, 104, +243, 2, 143, 109, 213, 247, 163, 196, 181, 37, 16, 50, 218, 28, 129, 118, +162, 187, 98, 202, 226, 244, 39, 27, 90, 255, 235, 125, 98, 206, 155, 179, +211, 58, 135, 80, 97, 220, 32, 136, 18, 226, 60, 251, 51, 170, 165, 47, +4, 63, 160, 41, 105, 85, 23, 122, 32, 145, 69, 85, 159, 147, 73, 209, +201, 169, 25, 225, 164, 6, 151, 92, 9, 223, 55, 137, 202, 67, 221, 100, +161, 248, 10, 209, 195, 27, 146, 4, 219, 227, 190, 203, 134, 228, 10, 160, +34, 221, 250, 110, 203, 33, 186, 60, 136, 185, 235, 72, 45, 105, 176, 161, +36, 169, 185, 174, 168, 146, 23, 57, 128, 198, 162, 194, 197, 62, 254, 102, +200, 154, 140, 98, 40, 208, 128, 95, 151, 77, 40, 190, 88, 75, 156, 47, +207, 220, 11, 125, 159, 24, 89, 142, 60, 2, 156, 25, 44, 203, 39, 222, +166, 122, 93, 215, 91, 87, 57, 199, 69, 211, 244, 140, 241, 106, 43, 193, +10, 150, 65, 226, 163, 202, 165, 155, 93, 219, 207, 28, 174, 157, 201, 199, +169, 174, 28, 36, 117, 106, 155, 87, 209, 223, 171, 104, 72, 76, 180, 101, +196, 248, 163, 252, 150, 33, 224, 118, 128, 130, 145, 211, 28, 80, 17, 174, +33, 156, 108, 139, 120, 225, 111, 9, 46, 228, 79, 112, 121, 35, 181, 170, +12, 131, 173, 169, 4, 40, 8, 101, 34, 154, 227, 200, 57, 50, 118, 220, +128, 21, 208, 62, 131, 68, 193, 52, 163, 35, 96, 45, 225, 26, 219, 50, +194, 44, 22, 181, 83, 21, 82, 35, 100, 10, 241, 218, 12, 104, 240, 254, +190, 54, 48, 213, 87, 65, 183, 27, 232, 23, 246, 169, 179, 164, 55, 66, +70, 219, 7, 214, 128, 58, 244, 120, 52, 255, 213, 170, 81, 235, 16, 46, +18, 229, 186, 139, 118, 127, 12, 74, 173, 106, 171, 161, 3, 108, 3, 113, +211, 2, 88, 90, 227, 202, 196, 195, 69, 88, 168, 40, 87, 247, 210, 5, +26, 117, 159, 42, 3, 73, 148, 247, 236, 110, 16, 236, 169, 179, 22, 198, +32, 79, 138, 96, 70, 6, 161, 27, 71, 155, 241, 112, 60, 188, 51, 134, +154, 0, 207, 203, 43, 102, 88, 180, 139, 239, 72, 26, 46, 174, 76, 65, +14, 135, 202, 211, 124, 201, 4, 227, 40, 119, 46, 102, 23, 71, 143, 167, +164, 77, 192, 135, 16, 27, 148, 127, 123, 191, 209, 160, 49, 93, 138, 94, +161, 181, 205, 80, 80, 33, 73, 203, 45, 36, 194, 173, 86, 7, 234, 200, +138, 20, 62, 20, 110, 84, 16, 238, 207, 123, 175, 233, 40, 135, 51, 85, +136, 64, 204, 198, 207, 151, 162, 133, 207, 58, 246, 187, 201, 91, 185, 76, +46, 209, 173, 153, 71, 158, 241, 109, 66, 129, 109, 19, 70, 30, 186, 76, +249, 125, 197, 243, 223, 219, 16, 93, 134, 232, 59, 188, 42, 4, 155, 129, +236, 145, 166, 244, 222, 103, 3, 166, 145, 150, 57, 129, 19, 253, 157, 242, +66, 97, 165, 107, 87, 180, 245, 247, 47, 19, 34, 135, 219, 94, 76, 118, +156, 247, 148, 44, 142, 164, 20, 184, 96, 179, 138, 54, 39, 212, 235, 96, +215, 39, 45, 51, 215, 39, 47, 119, 120, 22, 197, 166, 158, 26, 115, 21, +16, 110, 23, 166, 132, 209, 232, 103, 248, 200, 133, 238, 224, 13, 50, 110, +33, 211, 154, 5, 239, 137, 226, 87, 131, 152, 225, 59, 208, 49, 204, 237, +81, 149, 34, 167, 46, 181, 121, 110, 31, 108, 226, 10, 80, 6, 47, 84, +180, 176, 86, 70, 171, 221, 85, 143, 172, 227, 120, 229, 75, 140, 133, 195, +176, 173, 92, 82, 179, 97, 115, 116, 236, 224, 70, 44, 166, 206, 23, 99, +0, 213, 47, 203, 153, 221, 178, 246, 196, 30, 74, 208, 100, 245, 85, 136, +132, 6, 213, 73, 199, 248, 61, 206, 141, 74, 61, 100, 181, 157, 51, 131, +95, 116, 217, 218, 162, 32, 136, 10, 115, 221, 65, 16, 223, 19, 163, 172, +73, 140, 97, 69, 67, 199, 116, 137, 251, 188, 106, 68, 78, 25, 225, 202, +40, 117, 161, 114, 10, 208, 29, 48, 217, 82, 234, 75, 134, 156, 9, 253, +241, 144, 22, 186, 139, 101, 111, 37, 72, 95, 33, 177, 20, 246, 210, 132, +1, 255, 84, 153, 171, 140, 222, 57, 86, 34, 181, 228, 39, 13, 158, 35, +57, 113, 16, 61, 97, 111, 39, 48, 192, 88, 102, 201, 83, 73, 113, 227, +116, 20, 73, 169, 135, 107, 8, 96, 250, 23, 25, 242, 51, 166, 29, 160, +169, 43, 239, 90, 254, 198, 209, 54, 249, 31, 217, 23, 118, 57, 192, 20, +69, 77, 50, 24, 34, 190, 166, 28, 181, 49, 126, 222, 133, 171, 0, 85, +212, 226, 94, 35, 11, 186, 253, 42, 162, 231, 111, 41, 53, 21, 0, 196, +211, 17, 73, 180, 211, 43, 10, 11, 169, 42, 217, 100, 220, 106, 211, 8, +68, 44, 65, 124, 214, 103, 198, 30, 191, 25, 71, 54, 175, 38, 179, 199, +70, 138, 97, 108, 255, 138, 125, 40, 227, 161, 76, 237, 137, 181, 151, 130, +199, 147, 50, 202, 63, 204, 201, 210, 176, 96, 34, 56, 67, 123, 183, 1, +76, 154, 235, 179, 216, 12, 117, 188, 46, 156, 252, 113, 160, 233, 197, 85, +136, 30, 248, 140, 12, 94, 134, 65, 86, 195, 234, 246, 91, 169, 22, 246, +179, 50, 9, 114, 221, 181, 117, 75, 248, 250, 178, 13, 27, 17, 253, 242, +46, 217, 38, 173, 41, 199, 29, 74, 40, 35, 68, 210, 208, 58, 180, 133, +244, 138, 113, 207, 34, 225, 122, 92, 111, 221, 183, 24, 150, 49, 7, 21, +66, 56, 58, 165, 114, 83, 27, 31, 48, 14, 6, 160, 66, 45, 64, 87, +184, 7, 29, 123, 248, 231, 76, 1, 133, 82, 122, 54, 198, 43, 143, 135, +5, 173, 90, 234, 193, 11, 13, 158, 200, 210, 235, 34, 16, 147, 34, 12, +162, 125, 17, 42, 120, 178, 254, 70, 247, 98, 239, 253, 121, 6, 228, 136, +142, 224, 84, 181, 244, 122, 130, 165, 247, 26, 40, 7, 194, 75, 69, 109, +154, 8, 69, 73, 19, 187, 93, 141, 133, 163, 142, 102, 230, 167, 64, 60, +82, 140, 73, 205, 221, 44, 139, 106, 67, 75, 232, 192, 201, 199, 198, 3, +138, 228, 140, 161, 212, 57, 55, 51, 94, 38, 89, 225, 92, 37, 239, 56, +35, 50, 203, 123, 145, 140, 62, 37, 78, 17, 223, 236, 211, 3, 152, 48, +200, 73, 18, 202, 203, 100, 185, 171, 51, 254, 143, 39, 141, 125, 28, 236, +179, 45, 234, 126, 20, 65, 174, 97, 241, 242, 45, 63, 49, 10, 137, 234, +137, 186, 225, 132, 36, 54, 195, 173, 21, 185, 163, 118, 125, 244, 66, 172, +145, 124, 242, 5, 21, 230, 51, 165, 24, 71, 157, 116, 172, 183, 147, 176, +148, 136, 88, 84, 10, 83, 22, 173, 67, 228, 17, 37, 136, 248, 234, 77, +233, 145, 111, 253, 31, 77, 212, 111, 222, 215, 46, 77, 29, 10, 192, 121, +17, 173, 70, 252, 53, 136, 16, 177, 162, 28, 113, 124, 181, 146, 235, 248, +80, 80, 242, 94, 21, 192, 162, 236, 21, 163, 244, 217, 15, 167, 84, 195, +43, 216, 220, 177, 69, 99, 35, 58, 217, 252, 195, 102, 13, 196, 105, 6, +217, 48, 209, 199, 143, 139, 51, 227, 180, 80, 148, 206, 183, 153, 31, 245, +60, 182, 205, 199, 153, 244, 232, 251, 209, 169, 42, 163, 67, 217, 181, 27, +57, 115, 107, 78, 192, 254, 236, 183, 230, 114, 42, 155, 19, 142, 83, 207, +172, 53, 20, 250, 2, 150, 37, 214, 186, 35, 8, 179, 170, 90, 214, 160, +218, 251, 130, 197, 24, 191, 23, 236, 227, 157, 3, 96, 32, 168, 173, 248, +215, 41, 14, 14, 80, 134, 34, 65, 108, 106, 46, 195, 150, 150, 123, 103, +56, 121, 202, 213, 107, 245, 191, 129, 192, 40, 90, 5, 30, 100, 119, 156, +208, 22, 206, 119, 48, 69, 54, 22, 230, 217, 97, 167, 114, 105, 155, 188, +78, 3, 170, 226, 209, 167, 147, 154, 90, 126, 193, 12, 253, 228, 165, 3, +31, 102, 106, 2, 235, 18, 39, 152, 173, 182, 194, 126, 183, 114, 202, 209, +32, 68, 98, 99, 185, 55, 21, 116, 89, 224, 79, 160, 166, 171, 39, 179, +173, 146, 79, 167, 36, 75, 195, 22, 248, 177, 97, 122, 14, 86, 234, 99, +20, 138, 252, 2, 31, 47, 191, 187, 136, 224, 233, 172, 28, 59, 77, 231, +124, 86, 67, 25, 9, 222, 119, 157, 29, 30, 166, 111, 107, 138, 153, 254, +26, 105, 243, 91, 208, 2, 249, 188, 40, 34, 138, 91, 32, 171, 246, 64, +57, 7, 145, 243, 155, 93, 228, 228, 158, 94, 185, 149, 63, 236, 176, 186, +35, 145, 171, 209, 213, 214, 1, 158, 143, 185, 33, 248, 84, 1, 91, 201, +0, 174, 112, 52, 165, 202, 24, 20, 234, 125, 255, 142, 35, 138, 21, 87, +157, 40, 87, 150, 222, 226, 114, 119, 127, 190, 123, 25, 10, 175, 20, 66, +35, 8, 253, 203, 17, 79, 239, 79, 49, 92, 111, 62, 64, 94, 150, 95, +50, 246, 19, 78, 89, 247, 4, 25, 146, 142, 201, 101, 137, 36, 179, 93, +80, 158, 144, 34, 248, 173, 20, 245, 180, 30, 132, 241, 10, 120, 205, 10, +200, 119, 195, 193, 48, 205, 143, 48, 53, 155, 242, 50, 99, 181, 154, 182, +44, 243, 5, 18, 121, 140, 60, 56, 141, 213, 156, 158, 122, 28, 125, 42, +152, 83, 47, 132, 16, 54, 246, 164, 123, 68, 237, 151, 20, 161, 128, 24, +251, 153, 36, 9, 100, 227, 235, 15, 204, 33, 69, 90, 175, 71, 200, 215, +24, 28, 136, 123, 224, 112, 205, 183, 171, 130, 119, 157, 87, 155, 55, 89, +50, 121, 143, 12, 118, 51, 131, 109, 111, 39, 194, 206, 119, 150, 89, 9, +199, 86, 88, 207, 32, 241, 141, 106, 11, 19, 241, 140, 74, 19, 241, 116, +186, 224, 216, 139, 83, 35, 186, 189, 122, 64, 168, 121, 63, 182, 101, 232, +152, 96, 4, 162, 191, 152, 73, 12, 240, 55, 51, 112, 218, 216, 129, 30, +39, 49, 209, 132, 24, 140, 22, 17, 216, 218, 120, 221, 248, 40, 169, 24, +78, 198, 219, 99, 86, 225, 233, 255, 239, 118, 13, 44, 190, 145, 152, 207, +101, 102, 168, 204, 212, 179, 109, 54, 101, 48, 155, 91, 170, 10, 87, 131, +49, 95, 165, 199, 62, 162, 187, 239, 186, 7, 225, 128, 178, 201, 39, 223, +213, 194, 202, 65, 216, 188, 204, 161, 53, 103, 200, 108, 56, 119, 205, 152, +227, 105, 8, 55, 99, 100, 226, 227, 206, 104, 172, 249, 126, 39, 185, 1, +243, 134, 226, 104, 36, 176, 242, 51, 27, 83, 252, 250, 219, 2, 201, 197, +64, 156, 102, 171, 172, 59, 35, 60, 154, 112, 32, 14, 252, 78, 91, 162, +54, 139, 223, 154, 97, 157, 236, 49, 33, 253, 67, 60, 100, 127, 204, 83, +235, 7, 217, 215, 136, 85, 76, 172, 161, 180, 54, 61, 43, 187, 207, 125, +50, 157, 246, 96, 159, 203, 17, 61, 26, 184, 206, 206, 232, 73, 32, 222, +252, 64, 156, 78, 140, 41, 121, 73, 222, 133, 72, 98, 45, 161, 172, 42, +230, 164, 248, 139, 255, 140, 84, 5, 244, 131, 158, 185, 177, 5, 27, 201, +68, 69, 37, 32, 11, 79, 15, 218, 201, 41, 61, 220, 82, 102, 143, 137, +93, 161, 93, 184, 133, 140, 9, 118, 220, 217, 184, 157, 227, 184, 1, 219, +35, 183, 183, 154, 195, 123, 59, 124, 166, 251, 151, 248, 83, 199, 158, 163, +206, 4, 131, 32, 69, 137, 93, 52, 213, 84, 219, 225, 85, 146, 26, 21, +122, 138, 108, 189, 93, 29, 36, 19, 127, 185, 251, 186, 134, 1, 139, 130, +148, 24, 147, 113, 153, 18, 156, 113, 220, 136, 99, 207, 16, 224, 118, 5, +125, 247, 223, 187, 255, 176, 45, 225, 100, 65, 230, 94, 247, 106, 236, 139, +48, 170, 135, 188, 110, 72, 245, 77, 229, 119, 121, 221, 117, 80, 161, 11, +83, 111, 104, 7, 16, 215, 200, 76, 70, 30, 235, 109, 255, 108, 51, 22, +39, 118, 166, 185, 10, 201, 25, 135, 139, 123, 47, 231, 94, 237, 44, 205, +224, 101, 159, 219, 52, 75, 219, 117, 127, 94, 37, 98, 166, 26, 218, 182, +135, 79, 97, 128, 47, 80, 11, 129, 232, 199, 73, 238, 20, 96, 73, 8, +13, 246, 150, 113, 16, 93, 29, 63, 99, 184, 127, 48, 184, 15, 201, 41, +8, 73, 20, 254, 186, 190, 85, 57, 106, 219, 50, 222, 245, 19, 1, 224, +126, 204, 176, 212, 46, 202, 253, 246, 139, 139, 157, 165, 224, 100, 16, 48, +50, 146, 146, 189, 215, 105, 250, 219, 7, 105, 27, 195, 58, 185, 223, 24, +132, 199, 121, 183, 28, 15, 242, 170, 196, 120, 116, 16, 197, 209, 226, 57, +221, 6, 20, 154, 98, 50, 100, 209, 68, 35, 57, 77, 168, 139, 101, 179, +73, 182, 158, 237, 54, 140, 39, 181, 108, 154, 139, 112, 185, 112, 88, 51, +125, 93, 26, 202, 77, 157, 48, 88, 66, 74, 64, 55, 153, 78, 123, 156, +171, 59, 43, 11, 142, 249, 137, 25, 136, 219, 244, 210, 117, 44, 156, 136, +80, 224, 236, 213, 190, 71, 252, 135, 37, 95, 7, 5, 28, 172, 241, 27, +217, 140, 19, 42, 138, 107, 71, 12, 75, 179, 112, 29, 129, 191, 9, 141, +179, 255, 1, 162, 7, 118, 105, 47, 49, 105, 44, 20, 86, 185, 2, 125, +146, 241, 159, 105, 176, 221, 115, 213, 14, 66, 202, 95, 250, 213, 43, 248, +176, 4, 46, 39, 84, 19, 186, 80, 242, 53, 182, 156, 3, 43, 8, 79, +88, 156, 127, 11, 247, 179, 199, 208, 251, 37, 217, 22, 207, 191, 128, 53, +160, 16, 159, 197, 19, 214, 240, 29, 193, 212, 73, 191, 244, 27, 189, 229, +99, 251, 254, 50, 42, 191, 199, 15, 149, 141, 81, 60, 25, 135, 120, 231, +40, 84, 127, 59, 150, 127, 45, 154, 135, 124, 109, 252, 186, 204, 98, 148, +162, 133, 10, 234, 232, 152, 88, 216, 54, 242, 206, 78, 160, 12, 78, 10, +228, 2, 238, 50, 9, 230, 116, 204, 206, 160, 9, 199, 12, 12, 224, 13, +153, 81, 51, 253, 140, 197, 148, 47, 192, 14, 187, 255, 216, 110, 141, 198, +35, 212, 244, 67, 77, 48, 87, 46, 46, 113, 205, 220, 81, 105, 109, 9, +248, 194, 100, 71, 187, 160, 9, 221, 178, 176, 119, 196, 36, 136, 12, 68, +34, 113, 221, 250, 250, 4, 251, 20, 137, 70, 241, 172, 178, 185, 214, 23, +55, 196, 31, 160, 76, 214, 230, 139, 192, 144, 120, 188, 225, 215, 132, 33, +105, 178, 83, 69, 92, 192, 112, 123, 221, 34, 7, 73, 145, 233, 56, 12, +67, 106, 152, 77, 143, 77, 217, 102, 6, 199, 53, 14, 162, 12, 134, 91, +59, 169, 181, 18, 47, 11, 206, 69, 65, 66, 27, 160, 98, 149, 22, 24, +53, 196, 119, 231, 84, 211, 246, 231, 218, 99, 120, 197, 151, 30, 153, 192, +120, 253, 70, 234, 253, 239, 34, 74, 6, 233, 149, 155, 214, 12, 127, 57, +92, 225, 201, 233, 116, 48, 226, 94, 159, 212, 78, 222, 99, 116, 29, 187, +3, 59, 167, 68, 108, 162, 146, 125, 6, 178, 230, 60, 158, 60, 85, 94, +113, 93, 2, 75, 195, 234, 66, 200, 148, 128, 50, 56, 58, 205, 79, 226, +11, 189, 189, 88, 32, 67, 83, 84, 188, 31, 180, 79, 252, 9, 177, 199, +53, 163, 66, 54, 110, 245, 174, 113, 225, 204, 180, 149, 6, 141, 18, 250, +150, 168, 229, 99, 107, 110, 108, 63, 70, 43, 146, 216, 64, 42, 3, 227, +146, 223, 233, 6, 140, 108, 238, 21, 245, 70, 14, 152, 92, 109, 138, 104, +200, 195, 248, 125, 230, 8, 4, 138, 125, 228, 221, 225, 98, 146, 230, 91, +225, 247, 207, 29, 112, 185, 202, 157, 218, 18, 193, 45, 54, 47, 215, 162, +29, 92, 95, 13, 88, 40, 129, 1, 150, 106, 203, 117, 76, 176, 157, 169, +61, 45, 201, 67, 35, 238, 149, 21, 174, 50, 162, 150, 120, 22, 144, 195, +187, 214, 239, 178, 231, 165, 200, 167, 170, 107, 98, 242, 205, 72, 113, 166, +163, 6, 197, 57, 210, 106, 231, 192, 17, 112, 77, 83, 171, 216, 127, 73, +143, 182, 224, 111, 104, 137, 123, 119, 52, 153, 42, 205, 161, 145, 174, 167, +38, 117, 130, 82, 31, 228, 102, 234, 30, 199, 194, 207, 73, 109, 64, 231, +55, 221, 65, 225, 203, 28, 113, 2, 120, 201, 22, 125, 211, 76, 82, 58, +75, 181, 33, 121, 189, 138, 70, 122, 155, 252, 133, 51, 35, 241, 193, 121, +148, 48, 44, 155, 123, 240, 9, 169, 145, 15, 79, 213, 180, 160, 30, 198, +225, 209, 186, 124, 186, 53, 240, 246, 13, 188, 52, 211, 221, 181, 212, 140, +143, 187, 178, 11, 181, 202, 78, 50, 55, 119, 228, 113, 120, 231, 184, 165, +122, 121, 94, 181, 222, 248, 225, 204, 245, 174, 205, 63, 219, 192, 246, 82, +101, 109, 115, 160, 153, 82, 131, 38, 219, 229, 58, 114, 205, 138, 141, 137, +237, 89, 94, 245, 84, 177, 166, 0, 38, 16, 173, 56, 248, 67, 55, 114, +252, 89, 251, 146, 93, 24, 104, 113, 181, 37, 164, 37, 158, 96, 137, 191, +214, 21, 51, 215, 58, 123, 111, 161, 116, 157, 112, 211, 188, 210, 52, 105, +219, 91, 213, 191, 133, 171, 47, 102, 174, 51, 170, 180, 10, 30, 181, 17, +43, 76, 13, 242, 136, 41, 45, 155, 24, 45, 79, 146, 218, 6, 107, 47, +142, 32, 141, 94, 165, 12, 149, 84, 170, 122, 202, 67, 130, 126, 39, 129, +244, 187, 19, 227, 22, 108, 234, 94, 98, 61, 155, 251, 228, 212, 43, 37, +254, 81, 222, 41, 67, 5, 225, 124, 53, 203, 111, 24, 212, 64, 17, 85, +194, 255, 56, 190, 115, 192, 203, 55, 170, 152, 187, 166, 116, 85, 66, 167, +213, 247, 129, 15, 118, 86, 104, 224, 195, 108, 109, 6, 200, 191, 34, 138, +117, 74, 182, 209, 18, 204, 182, 139, 184, 27, 107, 175, 14, 145, 155, 197, +251, 53, 141, 209, 98, 130, 230, 2, 91, 91, 90, 254, 131, 252, 91, 85, +39, 212, 73, 90, 57, 184, 144, 26, 163, 6, 32, 243, 234, 162, 234, 236, +167, 234, 73, 113, 50, 77, 165, 129, 122, 211, 6, 34, 194, 184, 29, 135, +226, 91, 114, 14, 96, 246, 243, 22, 200, 242, 220, 174, 227, 244, 168, 199, +197, 55, 114, 62, 215, 172, 58, 60, 82, 41, 205, 8, 107, 253, 62, 108, +122, 249, 78, 137, 39, 167, 14, 35, 153, 136, 62, 193, 211, 120, 49, 237, +232, 22, 215, 190, 132, 161, 250, 249, 174, 253, 90, 93, 210, 35, 222, 35, +62, 60, 204, 107, 63, 198, 121, 147, 68, 213, 75, 49, 50, 3, 5, 74, +30, 92, 119, 11, 223, 133, 222, 29, 233, 248, 93, 87, 194, 139, 84, 52, +214, 44, 146, 19, 241, 82, 204, 163, 154, 253, 130, 159, 88, 148, 116, 207, +29, 114, 117, 150, 154, 24, 81, 78, 95, 1, 208, 84, 197, 172, 141, 3, +107, 18, 192, 120, 196, 91, 30, 82, 90, 232, 163, 10, 142, 96, 198, 62, +126, 212, 153, 100, 207, 146, 122, 233, 92, 188, 147, 27, 9, 102, 204, 119, +209, 242, 71, 222, 108, 114, 249, 173, 59, 14, 67, 26, 104, 240, 136, 199, +70, 131, 39, 134, 18, 1, 152, 79, 224, 130, 104, 195, 179, 215, 90, 186, +244, 238, 12, 90, 181, 145, 75, 238, 84, 158, 111, 63, 187, 121, 152, 132, +167, 150, 138, 62, 203, 40, 70, 138, 154, 210, 37, 50, 226, 69, 253, 143, +26, 0, 243, 131, 5, 139, 79, 48, 48, 115, 122, 61, 71, 41, 1, 232, +239, 4, 96, 74, 209, 253, 128, 224, 222, 158, 97, 150, 16, 30, 132, 240, +199, 197, 118, 13, 71, 56, 160, 190, 35, 215, 110, 165, 254, 26, 69, 43, +195, 163, 30, 245, 138, 48, 80, 140, 245, 89, 83, 165, 65, 39, 20, 83, +115, 119, 111, 90, 202, 101, 172, 91, 178, 35, 17, 120, 45, 118, 91, 60, +189, 180, 133, 34, 19, 137, 152, 143, 16, 186, 214, 4, 46, 242, 23, 179, +229, 204, 55, 218, 22, 188, 5, 222, 140, 69, 195, 43, 31, 34, 159, 131, +53, 28, 83, 208, 158, 112, 163, 16, 61, 175, 3, 69, 113, 134, 174, 21, +125, 162, 91, 182, 251, 120, 17, 94, 100, 252, 199, 118, 35, 248, 64, 206, +179, 38, 121, 176, 84, 197, 9, 2, 45, 111, 244, 161, 250, 199, 130, 208, +167, 250, 0, 155, 57, 0, 95, 39, 206, 237, 5, 23, 58, 142, 137, 77, +164, 152, 219, 94, 57, 237, 16, 219, 119, 57, 58, 101, 189, 104, 205, 228, +28, 237, 119, 143, 99, 241, 5, 160, 115, 91, 215, 246, 198, 153, 60, 186, +64, 248, 126, 67, 56, 155, 179, 55, 102, 3, 47, 68, 145, 41, 209, 45, +148, 106, 11, 71, 191, 171, 245, 33, 6, 133, 216, 1, 109, 128, 56, 120, +247, 17, 169, 150, 173, 61, 111, 0, 65, 2, 95, 229, 63, 59, 185, 148, +213, 149, 140, 190, 57, 151, 163, 73, 9, 231, 250, 76, 126, 211, 12, 175, +14, 38, 146, 30, 102, 22, 124, 58, 137, 239, 181, 99, 176, 2, 184, 48, +196, 132, 248, 140, 90, 194, 95, 6, 90, 242, 171, 254, 189, 235, 8, 68, +244, 115, 89, 217, 10, 61, 172, 252, 75, 186, 117, 212, 216, 62, 253, 98, +156, 233, 96, 139, 55, 91, 251, 168, 221, 67, 231, 18, 140, 250, 38, 232, +143, 65, 220, 234, 129, 106, 184, 63, 171, 119, 96, 32, 9, 45, 151, 74, +71, 81, 162, 109, 58, 194, 125, 191, 169, 244, 9, 190, 37, 38, 98, 36, +238, 176, 38, 150, 30, 227, 0, 191, 60, 189, 0, 4, 178, 196, 238, 182, +233, 8, 126, 14, 236, 73, 100, 16, 150, 49, 26, 104, 152, 197, 132, 53, +229, 100, 196, 206, 7, 74, 91, 143, 23, 206, 120, 252, 52, 73, 161, 148, +41, 160, 137, 29, 207, 222, 13, 128, 144, 191, 162, 60, 24, 226, 187, 250, +73, 76, 246, 240, 31, 254, 109, 144, 102, 248, 207, 215, 44, 182, 29, 202, +54, 141, 107, 124, 239, 205, 243, 54, 158, 0, 148, 202, 98, 65, 233, 201, +60, 169, 34, 64, 81, 62, 205, 225, 228, 233, 250, 23, 146, 53, 104, 120, +68, 71, 179, 26, 156, 230, 25, 225, 235, 138, 20, 196, 223, 72, 176, 237, +67, 107, 202, 211, 32, 31, 184, 26, 178, 64, 134, 225, 115, 8, 227, 9, +200, 33, 31, 31, 58, 82, 251, 249, 54, 46, 60, 12, 233, 66, 222, 144, +243, 111, 110, 25, 117, 77, 108, 223, 211, 209, 23, 78, 162, 154, 77, 84, +251, 166, 89, 207, 45, 78, 51, 85, 18, 51, 14, 56, 9, 131, 186, 111, +229, 230, 11, 197, 196, 201, 184, 134, 147, 52, 14, 185, 145, 14, 9, 164, +157, 82, 3, 252, 42, 244, 140, 207, 189, 77, 13, 232, 248, 139, 10, 137, +30, 189, 91, 92, 202, 63, 249, 97, 212, 139, 39, 155, 251, 253, 10, 249, +13, 115, 238, 203, 112, 147, 186, 185, 46, 239, 51, 143, 148, 251, 163, 208, +254, 121, 240, 243, 22, 162, 47, 196, 44, 249, 0, 59, 127, 144, 82, 11, +69, 124, 76, 131, 231, 236, 169, 97, 172, 168, 157, 24, 17, 61, 108, 229, +182, 153, 0, 196, 23, 118, 40, 70, 167, 178, 79, 47, 113, 75, 93, 46, +135, 148, 121, 57, 20, 150, 28, 66, 210, 141, 142, 91, 131, 112, 239, 188, +35, 5, 181, 128, 2, 59, 120, 6, 228, 206, 130, 132, 104, 30, 219, 147, +82, 12, 48, 9, 98, 51, 34, 196, 135, 236, 115, 178, 10, 25, 8, 205, +28, 231, 140, 199, 224, 224, 162, 123, 88, 194, 202, 218, 116, 49, 233, 137, +112, 72, 235, 157, 125, 137, 74, 132, 49, 69, 232, 249, 247, 241, 47, 8, +112, 5, 72, 138, 149, 121, 2, 148, 204, 93, 231, 44, 129, 140, 149, 206, +104, 37, 208, 181, 86, 67, 122, 167, 114, 166, 200, 134, 180, 179, 139, 120, +16, 106, 171, 93, 58, 179, 175, 179, 244, 148, 36, 83, 171, 157, 182, 146, +111, 22, 0, 144, 110, 105, 47, 90, 236, 177, 47, 44, 35, 250, 237, 111, +141, 89, 6, 186, 22, 196, 32, 166, 23, 143, 17, 96, 127, 58, 139, 137, +29, 250, 164, 52, 141, 1, 13, 117, 82, 93, 241, 254, 120, 139, 165, 1, +114, 105, 7, 135, 180, 57, 252, 202, 233, 69, 253, 38, 11, 88, 223, 17, +203, 64, 162, 170, 127, 59, 163, 90, 8, 58, 149, 20, 214, 159, 26, 160, +120, 244, 123, 91, 203, 31, 86, 237, 20, 242, 66, 14, 182, 206, 127, 54, +119, 36, 182, 41, 129, 128, 193, 81, 19, 182, 120, 85, 23, 210, 220, 177, +202, 204, 102, 143, 81, 243, 233, 15, 67, 183, 157, 96, 122, 120, 130, 79, +154, 118, 36, 78, 152, 24, 123, 90, 86, 169, 200, 20, 29, 57, 210, 133, +16, 52, 24, 202, 20, 173, 101, 230, 61, 47, 105, 94, 244, 47, 217, 207, +87, 87, 93, 204, 138, 110, 8, 150, 200, 248, 129, 139, 134, 225, 34, 34, +150, 247, 70, 194, 144, 167, 21, 98, 161, 7, 38, 78, 3, 36, 42, 134, +161, 157, 203, 87, 34, 171, 28, 199, 64, 186, 130, 223, 103, 121, 88, 130, +50, 174, 10, 50, 79, 13, 92, 162, 99, 1, 85, 168, 122, 61, 132, 80, +85, 112, 238, 6, 179, 207, 162, 53, 16, 198, 250, 218, 206, 202, 242, 248, +31, 74, 86, 197, 133, 193, 36, 99, 133, 160, 223, 55, 36, 153, 101, 165, +188, 184, 179, 189, 36, 198, 254, 51, 199, 13, 116, 24, 10, 135, 101, 208, +166, 54, 107, 1, 166, 97, 38, 201, 45, 86, 218, 44, 163, 60, 173, 129, +69, 17, 204, 55, 85, 141, 80, 100, 88, 127, 108, 205, 65, 73, 159, 204, +216, 250, 240, 17, 121, 196, 196, 121, 46, 64, 25, 215, 88, 102, 221, 244, +35, 248, 96, 114, 66, 125, 134, 7, 83, 97, 0, 80, 166, 224, 216, 22, +213, 18, 42, 242, 126, 182, 81, 224, 10, 37, 193, 43, 174, 74, 159, 147, +58, 65, 217, 147, 110, 214, 95, 122, 174, 125, 121, 74, 66, 144, 74, 99, +52, 132, 104, 105, 139, 225, 128, 62, 1, 188, 7, 43, 185, 222, 134, 6, +216, 52, 211, 213, 83, 109, 176, 166, 152, 161, 48, 211, 124, 198, 241, 52, +237, 139, 155, 20, 233, 140, 55, 147, 68, 77, 166, 106, 81, 213, 250, 74, +125, 165, 213, 65, 147, 92, 31, 208, 242, 169, 90, 30, 239, 165, 143, 196, +85, 247, 121, 147, 38, 181, 170, 75, 30, 224, 105, 121, 27, 197, 246, 172, +39, 109, 6, 209, 42, 208, 13, 148, 153, 97, 247, 38, 168, 185, 76, 42, +102, 145, 166, 27, 242, 37, 136, 45, 245, 32, 200, 177, 225, 248, 154, 117, +172, 184, 37, 156, 208, 100, 151, 64, 16, 193, 254, 213, 205, 140, 207, 153, +64, 155, 57, 47, 237, 59, 231, 10, 130, 204, 72, 30, 17, 60, 76, 115, +161, 237, 104, 5, 38, 254, 90, 152, 208, 49, 194, 160, 243, 106, 78, 41, +251, 143, 104, 130, 180, 241, 98, 211, 238, 194, 224, 36, 242, 39, 109, 180, +67, 130, 210, 44, 8, 162, 150, 16, 76, 83, 40, 86, 97, 87, 187, 42, +50, 63, 35, 98, 192, 23, 138, 236, 90, 3, 157, 19, 5, 252, 228, 211, +239, 1, 85, 190, 54, 144, 218, 221, 184, 19, 89, 75, 138, 53, 115, 206, +31, 100, 99, 187, 80, 162, 222, 134, 167, 238, 117, 84, 36, 62, 178, 224, +147, 119, 160, 65, 244, 245, 157, 188, 184, 222, 42, 53, 188, 84, 51, 5, +22, 214, 229, 92, 249, 17, 78, 6, 79, 145, 92, 201, 53, 58, 45, 87, +90, 19, 194, 253, 18, 68, 87, 58, 48, 206, 85, 241, 173, 40, 0, 38, +75, 210, 227, 254, 150, 117, 168, 88, 41, 180, 31, 77, 239, 136, 37, 106, +222, 33, 63, 239, 217, 245, 29, 11, 255, 94, 181, 132, 91, 80, 152, 15, +224, 253, 187, 104, 191, 95, 180, 55, 108, 24, 65, 32, 27, 147, 201, 102, +102, 64, 245, 14, 196, 154, 169, 133, 191, 117, 49, 108, 75, 133, 72, 95, +48, 126, 1, 166, 187, 129, 223, 94, 96, 39, 225, 222, 196, 210, 129, 35, +24, 186, 145, 6, 173, 82, 67, 130, 97, 167, 138, 167, 57, 181, 228, 249, +247, 44, 29, 9, 140, 245, 49, 164, 210, 119, 91, 176, 15, 31, 206, 88, +229, 155, 23, 72, 114, 224, 237, 190, 194, 147, 133, 233, 170, 22, 64, 241, +162, 204, 52, 208, 138, 159, 29, 94, 25, 117, 103, 132, 232, 65, 198, 90, +183, 113, 6, 76, 52, 141, 199, 166, 170, 128, 199, 251, 60, 137, 86, 78, +52, 16, 72, 64, 112, 174, 67, 54, 73, 63, 55, 183, 30, 11, 48, 131, +7, 94, 151, 17, 166, 115, 62, 5, 221, 71, 30, 137, 35, 181, 250, 187, +68, 26, 187, 51, 202, 249, 76, 162, 63, 10, 144, 123, 119, 217, 155, 15, +214, 212, 52, 39, 208, 109, 210, 206, 230, 242, 186, 254, 170, 138, 52, 40, +130, 7, 102, 67, 28, 38, 106, 152, 122, 172, 184, 166, 81, 30, 236, 149, +213, 236, 174, 130, 140, 44, 143, 199, 9, 118, 58, 11, 30, 126, 139, 39, +128, 92, 83, 242, 207, 200, 157, 245, 147, 84, 207, 140, 120, 59, 56, 228, +145, 177, 130, 48, 139, 78, 101, 124, 42, 228, 129, 172, 14, 248, 144, 142, +189, 38, 158, 58, 85, 84, 75, 136, 180, 175, 13, 184, 0, 26, 128, 234, +151, 167, 40, 6, 163, 8, 23, 57, 69, 42, 89, 174, 50, 0, 216, 186, +166, 7, 143, 123, 95, 23, 26, 134, 127, 125, 199, 117, 26, 215, 129, 212, +119, 83, 2, 66, 96, 247, 126, 241, 49, 171, 186, 222, 146, 234, 115, 199, +123, 112, 79, 147, 53, 210, 95, 192, 166, 49, 137, 245, 80, 120, 14, 184, +242, 237, 131, 27, 141, 100, 178, 185, 54, 245, 152, 55, 243, 88, 45, 122, +48, 229, 214, 55, 118, 105, 222, 26, 189, 68, 42, 21, 34, 57, 165, 246, +109, 35, 84, 45, 76, 196, 116, 127, 88, 180, 10, 179, 103, 226, 208, 33, +91, 111, 12, 231, 221, 166, 64, 199, 93, 87, 58, 164, 108, 23, 126, 169, +216, 119, 68, 104, 24, 51, 156, 71, 175, 181, 93, 184, 124, 171, 34, 72, +115, 95, 148, 72, 166, 241, 178, 223, 36, 10, 12, 219, 50, 172, 139, 152, +26, 232, 185, 249, 95, 249, 8, 244, 20, 78, 136, 141, 145, 169, 168, 2, +208, 9, 30, 37, 50, 149, 47, 50, 17, 64, 214, 168, 32, 23, 228, 232, +31, 78, 219, 77, 8, 80, 253, 41, 79, 8, 123, 65, 234, 36, 78, 151, +23, 68, 18, 70, 10, 9, 9, 33, 142, 129, 115, 143, 191, 127, 209, 141, +202, 189, 55, 120, 16, 148, 184, 122, 178, 77, 10, 149, 18, 30, 6, 101, +53, 90, 155, 239, 253, 82, 57, 11, 125, 84, 7, 175, 116, 62, 210, 232, +112, 130, 253, 105, 153, 203, 31, 120, 251, 241, 45, 41, 127, 96, 146, 11, +187, 180, 115, 21, 63, 182, 213, 196, 175, 255, 162, 31, 233, 65, 197, 110, +42, 136, 54, 118, 234, 176, 3, 252, 83, 4, 107, 133, 19, 226, 34, 163, +232, 31, 39, 171, 178, 242, 36, 69, 64, 33, 167, 139, 81, 184, 160, 207, +119, 37, 137, 40, 165, 50, 167, 243, 188, 82, 142, 91, 2, 0, 209, 16, +166, 152, 134, 113, 185, 236, 253, 161, 120, 90, 94, 189, 81, 201, 224, 60, +66, 82, 23, 12, 199, 197, 86, 198, 16, 54, 174, 237, 121, 186, 244, 141, +50, 26, 152, 120, 78, 52, 71, 115, 40, 94, 156, 22, 162, 241, 219, 90, +212, 236, 21, 153, 170, 142, 20, 200, 251, 49, 98, 192, 173, 14, 167, 199, +167, 176, 235, 111, 61, 243, 30, 215, 35, 113, 127, 122, 250, 79, 162, 40, +130, 81, 31, 51, 177, 240, 9, 31, 192, 210, 151, 171, 78, 201, 50, 102, +227, 75, 196, 239, 232, 175, 240, 119, 205, 191, 180, 209, 68, 123, 86, 244, +114, 244, 209, 7, 35, 17, 16, 89, 133, 89, 42, 9, 18, 124, 21, 252, +101, 244, 88, 79, 214, 234, 145, 140, 52, 118, 47, 44, 121, 43, 14, 6, +157, 26, 16, 172, 252, 85, 94, 84, 59, 134, 19, 119, 10, 70, 91, 157, +246, 8, 74, 32, 15, 23, 230, 2, 205, 188, 103, 237, 92, 19, 88, 21, +147, 135, 117, 124, 107, 140, 39, 152, 51, 56, 246, 122, 153, 174, 106, 145, +140, 146, 78, 180, 243, 212, 62, 46, 3, 131, 137, 78, 56, 79, 160, 252, +117, 84, 126, 199, 194, 240, 227, 23, 188, 40, 206, 72, 68, 40, 58, 91, +183, 80, 40, 31, 65, 9, 70, 23, 34, 64, 199, 213, 138, 80, 140, 58, +202, 215, 115, 223, 92, 181, 218, 116, 252, 210, 190, 210, 54, 166, 241, 66, +132, 62, 98, 109, 158, 51, 52, 89, 69, 24, 171, 176, 235, 116, 175, 18, +111, 80, 167, 209, 170, 150, 194, 152, 23, 96, 162, 41, 244, 232, 80, 85, +76, 226, 126, 240, 196, 214, 81, 40, 183, 225, 102, 10, 166, 57, 231, 230, +232, 149, 164, 116, 112, 122, 0, 182, 53, 199, 252, 55, 50, 111, 243, 200, +64, 191, 29, 240, 86, 187, 126, 133, 121, 249, 249, 37, 58, 174, 209, 39, +152, 103, 151, 131, 127, 207, 154, 14, 188, 239, 28, 107, 33, 10, 57, 82, +158, 116, 63, 225, 29, 103, 80, 134, 84, 245, 37, 13, 1, 70, 95, 180, +82, 191, 0, 67, 243, 67, 218, 148, 30, 248, 160, 133, 92, 83, 190, 197, +251, 150, 117, 28, 178, 121, 17, 16, 209, 4, 188, 155, 55, 82, 134, 128, +3, 104, 142, 132, 144, 32, 101, 0, 223, 166, 79, 49, 108, 64, 231, 162, +6, 27, 94, 116, 68, 235, 168, 36, 115, 39, 191, 151, 28, 202, 228, 35, +90, 53, 172, 170, 173, 151, 236, 174, 197, 19, 85, 216, 192, 158, 128, 35, +6, 88, 21, 25, 158, 92, 18, 213, 22, 136, 119, 149, 124, 213, 103, 197, +6, 206, 174, 36, 196, 199, 208, 68, 57, 84, 28, 218, 251, 214, 75, 157, +254, 46, 61, 228, 188, 87, 93, 125, 155, 38, 175, 4, 36, 160, 31, 177, +70, 222, 245, 85, 246, 69, 109, 45, 77, 151, 175, 202, 23, 17, 139, 66, +77, 166, 155, 251, 82, 156, 11, 77, 102, 222, 20, 170, 255, 232, 162, 41, +73, 26, 89, 118, 58, 126, 212, 207, 108, 55, 5, 136, 150, 240, 223, 185, +103, 231, 115, 182, 189, 39, 164, 162, 182, 112, 113, 11, 93, 250, 108, 247, +231, 143, 172, 67, 223, 221, 224, 24, 116, 128, 119, 232, 143, 90, 27, 149, +49, 226, 195, 238, 66, 233, 15, 97, 137, 170, 155, 236, 124, 185, 95, 192, +121, 36, 82, 76, 249, 31, 46, 102, 185, 14, 243, 30, 244, 217, 184, 156, +156, 207, 35, 38, 89, 107, 212, 139, 75, 161, 16, 78, 232, 76, 209, 7, +92, 94, 80, 159, 58, 162, 138, 216, 206, 231, 93, 85, 198, 140, 90, 200, +170, 79, 118, 26, 52, 168, 111, 165, 224, 91, 45, 85, 42, 162, 142, 55, +0, 19, 167, 142, 86, 74, 235, 43, 230, 3, 162, 93, 33, 239, 43, 181, +253, 155, 106, 28, 48, 150, 43, 234, 102, 187, 247, 187, 40, 43, 158, 33, +48, 242, 214, 95, 182, 126, 3, 25, 218, 47, 163, 140, 217, 6, 221, 199, +57, 76, 182, 244, 110, 49, 168, 240, 129, 31, 226, 185, 35, 18, 185, 189, +2, 17, 190, 134, 137, 29, 76, 118, 48, 216, 33, 188, 103, 160, 66, 143, +23, 230, 255, 24, 238, 6, 111, 18, 214, 163, 244, 30, 36, 4, 216, 31, +162, 60, 127, 235, 203, 67, 34, 69, 20, 227, 220, 56, 107, 78, 81, 10, +160, 169, 19, 255, 211, 126, 46, 77, 46, 152, 46, 114, 135, 139, 23, 3, +172, 52, 80, 86, 11, 5, 190, 51, 86, 190, 67, 0, 75, 17, 160, 229, +12, 254, 152, 221, 3, 213, 220, 213, 244, 51, 157, 73, 251, 206, 213, 43, +113, 247, 245, 189, 52, 226, 250, 109, 212, 4, 168, 132, 24, 137, 160, 175, +219, 204, 156, 32, 253, 121, 8, 209, 200, 96, 88, 93, 66, 243, 84, 76, +148, 142, 229, 86, 31, 106, 10, 23, 136, 200, 132, 152, 150, 51, 125, 202, +13, 202, 63, 110, 38, 125, 12, 113, 17, 162, 92, 217, 24, 108, 235, 209, +81, 65, 202, 179, 60, 176, 11, 91, 62, 45, 126, 96, 9, 66, 153, 134, +11, 40, 231, 205, 66, 5, 249, 92, 99, 119, 206, 105, 108, 207, 79, 44, +61, 10, 179, 18, 7, 33, 15, 68, 204, 40, 214, 171, 223, 177, 98, 94, +176, 243, 165, 152, 231, 154, 1, 67, 226, 236, 109, 137, 202, 72, 234, 243, +23, 156, 41, 105, 118, 40, 72, 112, 147, 53, 76, 126, 158, 255, 145, 213, +214, 43, 241, 194, 125, 227, 104, 241, 196, 244, 237, 140, 214, 62, 210, 249, +207, 143, 58, 106, 182, 10, 75, 247, 114, 19, 127, 210, 217, 102, 190, 200, +149, 36, 59, 137, 204, 222, 223, 123, 63, 215, 84, 249, 49, 149, 83, 137, +205, 224, 192, 44, 166, 101, 109, 181, 98, 219, 17, 169, 186, 35, 11, 108, +131, 75, 185, 220, 58, 214, 129, 67, 15, 106, 220, 67, 76, 7, 247, 154, +201, 146, 25, 224, 51, 169, 180, 61, 73, 169, 216, 163, 64, 179, 144, 61, +184, 163, 163, 8, 113, 40, 42, 53, 46, 80, 50, 199, 156, 6, 138, 44, +86, 130, 12, 195, 251, 191, 99, 122, 127, 116, 155, 248, 205, 86, 172, 49, +197, 132, 101, 124, 32, 23, 225, 78, 252, 23, 182, 27, 10, 93, 135, 220, +98, 246, 62, 157, 134, 102, 1, 113, 244, 65, 39, 3, 106, 168, 22, 142, +16, 64, 140, 15, 80, 99, 35, 22, 179, 165, 166, 85, 100, 233, 90, 229, +18, 78, 92, 204, 255, 218, 224, 121, 218, 149, 146, 101, 90, 237, 209, 141, +172, 71, 193, 90, 175, 189, 165, 169, 88, 27, 15, 197, 225, 132, 32, 122, +215, 89, 92, 130, 175, 160, 186, 201, 20, 61, 64, 162, 133, 3, 43, 242, +1, 253, 252, 181, 136, 253, 218, 163, 130, 111, 36, 14, 133, 7, 219, 204, +145, 34, 32, 170, 193, 236, 151, 74, 74, 147, 76, 138, 107, 121, 122, 117, +158, 28, 246, 50, 255, 135, 138, 164, 17, 38, 164, 210, 75, 174, 116, 208, +146, 145, 163, 54, 161, 142, 104, 242, 253, 76, 97, 186, 92, 131, 69, 189, +217, 241, 225, 157, 78, 37, 78, 96, 220, 194, 3, 246, 214, 121, 178, 93, +26, 46, 165, 137, 4, 223, 97, 14, 94, 50, 52, 234, 50, 86, 69, 141, +165, 121, 202, 152, 37, 85, 22, 135, 212, 233, 30, 106, 208, 152, 10, 196, +23, 144, 2, 199, 18, 43, 47, 236, 83, 30, 54, 249, 7, 145, 116, 239, +36, 191, 115, 171, 101, 77, 39, 102, 167, 249, 152, 234, 193, 141, 24, 143, +254, 132, 241, 49, 221, 223, 189, 103, 12, 245, 20, 240, 213, 121, 152, 82, +69, 179, 192, 186, 6, 66, 56, 22, 22, 144, 240, 125, 87, 13, 248, 93, +108, 229, 245, 148, 14, 62, 131, 45, 100, 201, 63, 68, 118, 249, 66, 98, +132, 141, 74, 140, 20, 220, 81, 134, 141, 172, 190, 199, 149, 205, 93, 57, +45, 113, 240, 15, 161, 4, 122, 228, 28, 150, 220, 183, 88, 226, 51, 117, +6, 107, 122, 39, 165, 25, 15, 197, 199, 149, 157, 131, 214, 44, 253, 240, +247, 241, 139, 229, 232, 212, 218, 113, 23, 188, 132, 147, 250, 252, 14, 145, +7, 246, 101, 27, 190, 155, 27, 224, 20, 37, 63, 2, 54, 38, 5, 34, +186, 2, 107, 221, 161, 66, 248, 217, 63, 79, 202, 83, 53, 253, 127, 87, +252, 108, 133, 175, 14, 82, 140, 132, 150, 94, 234, 120, 120, 214, 32, 234, +53, 81, 60, 107, 255, 166, 188, 89, 153, 9, 173, 234, 85, 244, 11, 76, +217, 190, 22, 16, 147, 80, 23, 113, 126, 241, 84, 57, 134, 84, 152, 42, +97, 158, 176, 247, 138, 249, 54, 110, 103, 112, 170, 52, 238, 109, 27, 131, +137, 84, 37, 53, 162, 45, 12, 135, 228, 179, 197, 44, 163, 143, 33, 0, +125, 198, 45, 122, 93, 252, 148, 208, 163, 242, 99, 126, 195, 122, 247, 103, +141, 22, 208, 148, 113, 236, 210, 223, 57, 241, 128, 9, 40, 105, 207, 109, +69, 229, 204, 238, 98, 124, 100, 227, 17, 185, 226, 18, 119, 192, 50, 24, +98, 196, 187, 230, 224, 60, 191, 157, 41, 179, 95, 76, 153, 6, 217, 232, +93, 2, 110, 41, 148, 140, 203, 9, 156, 225, 174, 26, 16, 1, 182, 20, +242, 221, 114, 72, 21, 141, 226, 213, 200, 17, 198, 16, 100, 176, 216, 73, +240, 76, 6, 237, 78, 200, 119, 77, 39, 240, 158, 31, 148, 131, 187, 63, +232, 210, 64, 179, 250, 232, 53, 78, 40, 18, 89, 33, 39, 140, 209, 56, +112, 249, 146, 222, 7, 127, 161, 65, 146, 33, 146, 127, 56, 114, 32, 84, +80, 24, 112, 229, 230, 213, 94, 91, 148, 244, 109, 13, 157, 111, 51, 201, +173, 173, 66, 136, 150, 6, 111, 111, 154, 11, 17, 116, 13, 27, 209, 242, +59, 99, 21, 169, 222, 68, 72, 222, 164, 61, 217, 201, 53, 205, 33, 15, +141, 10, 80, 10, 215, 82, 125, 43, 165, 54, 184, 26, 151, 71, 203, 206, +50, 58, 57, 161, 52, 168, 22, 242, 179, 125, 111, 43, 91, 87, 3, 7, +126, 177, 54, 163, 148, 93, 255, 55, 124, 43, 141, 72, 166, 34, 147, 163, +135, 0, 50, 126, 152, 165, 1, 244, 118, 95, 96, 80, 4, 187, 206, 110, +239, 214, 183, 209, 125, 252, 40, 182, 126, 134, 2, 45, 182, 138, 179, 2, +102, 138, 101, 19, 92, 134, 39, 69, 120, 57, 190, 57, 130, 245, 73, 221, +23, 174, 183, 93, 28, 157, 42, 231, 217, 206, 139, 115, 38, 188, 129, 124, +12, 110, 89, 108, 132, 51, 142, 244, 135, 245, 251, 68, 128, 56, 218, 26, +248, 129, 34, 157, 167, 84, 138, 245, 95, 64, 172, 74, 9, 252, 17, 188, +73, 110, 229, 78, 230, 153, 231, 44, 191, 46, 126, 39, 241, 123, 223, 46, +47, 39, 69, 139, 118, 7, 184, 183, 166, 171, 61, 112, 200, 111, 196, 61, +123, 217, 188, 193, 102, 212, 105, 92, 0, 159, 27, 176, 74, 50, 250, 107, +68, 26, 196, 203, 239, 0, 42, 184, 35, 143, 14, 106, 172, 76, 147, 112, +100, 25, 215, 41, 170, 126, 95, 108, 218, 82, 36, 9, 116, 177, 182, 123, +254, 190, 56, 53, 125, 239, 66, 243, 145, 10, 61, 102, 57, 109, 197, 80, +159, 97, 253, 120, 48, 249, 97, 177, 2, 185, 153, 14, 201, 121, 165, 107, +133, 118, 248, 220, 68, 206, 96, 137, 154, 121, 215, 217, 189, 74, 76, 204, +222, 35, 222, 227, 83, 52, 77, 180, 122, 123, 184, 249, 212, 240, 22, 200, +136, 194, 206, 111, 120, 162, 253, 186, 155, 213, 149, 39, 97, 252, 132, 95, +70, 241, 47, 54, 19, 143, 188, 149, 148, 238, 161, 194, 121, 17, 93, 111, +133, 242, 201, 212, 183, 138, 152, 178, 37, 230, 140, 107, 137, 122, 163, 75, +5, 135, 225, 186, 32, 50, 131, 104, 197, 16, 87, 163, 180, 251, 170, 27, +181, 241, 85, 179, 126, 116, 219, 206, 79, 242, 5, 101, 41, 165, 80, 223, +66, 32, 68, 71, 88, 53, 117, 216, 209, 172, 112, 212, 129, 152, 49, 109, +61, 236, 79, 222, 156, 11, 239, 31, 202, 61, 123, 205, 58, 128, 7, 95, +27, 139, 135, 91, 119, 192, 187, 13, 99, 165, 103, 254, 140, 195, 234, 100, +79, 231, 154, 176, 233, 82, 214, 191, 60, 193, 53, 143, 213, 250, 131, 91, +40, 145, 225, 212, 106, 77, 201, 106, 185, 120, 141, 225, 195, 5, 110, 132, +235, 189, 95, 42, 90, 55, 194, 116, 222, 147, 91, 172, 175, 220, 232, 23, +95, 201, 4, 150, 102, 250, 23, 196, 86, 120, 28, 42, 188, 48, 46, 144, +66, 85, 124, 42, 187, 137, 212, 196, 230, 245, 111, 147, 204, 161, 63, 35, +100, 22, 144, 232, 208, 88, 101, 151, 10, 31, 210, 90, 1, 4, 202, 135, +120, 102, 81, 121, 189, 201, 44, 222, 209, 48, 188, 152, 108, 250, 65, 173, +13, 240, 1, 123, 109, 36, 163, 137, 172, 69, 250, 162, 10, 75, 89, 57, +102, 147, 77, 18, 93, 4, 104, 216, 225, 207, 229, 24, 57, 187, 228, 99, +218, 204, 58, 115, 44, 120, 209, 99, 200, 214, 156, 221, 139, 17, 131, 159, +164, 233, 160, 6, 2, 27, 15, 60, 204, 219, 18, 190, 164, 210, 203, 188, +34, 116, 36, 134, 101, 193, 75, 88, 189, 222, 245, 174, 203, 0, 199, 161, +57, 22, 4, 219, 77, 24, 36, 141, 70, 215, 219, 31, 92, 105, 10, 70, +102, 169, 244, 215, 230, 169, 88, 240, 157, 190, 5, 130, 186, 232, 76, 117, +45, 230, 181, 115, 67, 35, 172, 15, 165, 30, 125, 180, 57, 245, 25, 97, +244, 170, 182, 180, 107, 24, 231, 195, 140, 97, 50, 220, 220, 193, 196, 144, +49, 32, 90, 62, 206, 109, 85, 35, 135, 220, 249, 255, 78, 103, 207, 98, +156, 228, 213, 254, 22, 231, 247, 191, 152, 250, 37, 8, 172, 204, 136, 181, +30, 75, 9, 174, 226, 175, 172, 238, 237, 107, 27, 230, 46, 197, 240, 140, +162, 225, 65, 165, 249, 209, 49, 152, 19, 102, 96, 96, 206, 145, 40, 39, +155, 68, 8, 228, 176, 0, 112, 6, 27, 164, 12, 220, 185, 140, 95, 71, +202, 125, 234, 15, 246, 52, 206, 5, 103, 198, 6, 65, 12, 209, 87, 223, +121, 239, 124, 120, 128, 156, 194, 250, 239, 133, 247, 227, 76, 107, 73, 38, +228, 241, 33, 19, 61, 138, 70, 37, 45, 58, 239, 13, 176, 27, 17, 41, +202, 233, 62, 223, 175, 157, 36, 234, 192, 23, 180, 64, 61, 231, 103, 173, +83, 169, 241, 51, 201, 81, 67, 217, 79, 246, 203, 247, 233, 117, 253, 153, +252, 50, 54, 251, 120, 254, 215, 105, 168, 47, 128, 61, 139, 243, 91, 142, +166, 179, 26, 97, 65, 171, 167, 244, 114, 188, 192, 101, 23, 55, 115, 205, +222, 209, 59, 111, 83, 147, 188, 26, 163, 123, 244, 252, 98, 148, 104, 110, +81, 27, 167, 67, 200, 85, 251, 80, 163, 117, 36, 78, 137, 95, 34, 59, +163, 172, 164, 89, 247, 72, 64, 181, 41, 86, 255, 184, 158, 238, 185, 226, +70, 112, 123, 179, 3, 73, 1, 111, 110, 161, 49, 29, 112, 124, 244, 110, +238, 247, 14, 14, 76, 199, 159, 197, 179, 250, 244, 247, 85, 172, 56, 98, +70, 232, 99, 204, 226, 75, 121, 73, 239, 205, 191, 210, 74, 92, 4, 0, +234, 193, 196, 194, 173, 68, 44, 15, 40, 155, 166, 205, 197, 52, 207, 169, +123, 143, 5, 179, 234, 31, 202, 86, 56, 24, 233, 62, 121, 211, 133, 19, +209, 88, 32, 158, 85, 70, 85, 248, 249, 48, 225, 47, 86, 13, 128, 6, +140, 36, 31, 128, 58, 215, 176, 81, 129, 125, 172, 224, 209, 207, 246, 173, +207, 193, 22, 97, 60, 173, 183, 77, 253, 155, 18, 178, 36, 113, 186, 216, +70, 53, 47, 176, 176, 110, 88, 134, 81, 218, 164, 230, 45, 241, 27, 80, +100, 97, 7, 241, 118, 72, 200, 165, 187, 155, 190, 94, 40, 30, 205, 153, +71, 104, 141, 15, 220, 15, 153, 177, 200, 155, 239, 120, 101, 136, 17, 153, +255, 88, 163, 185, 221, 199, 216, 98, 69, 95, 59, 175, 164, 233, 253, 133, +225, 2, 156, 121, 93, 233, 11, 172, 164, 252, 66, 25, 59, 141, 195, 114, +131, 224, 50, 139, 227, 135, 240, 4, 171, 14, 206, 140, 207, 55, 211, 159, +135, 8, 193, 239, 233, 207, 53, 244, 238, 84, 19, 73, 1, 94, 104, 42, +148, 26, 3, 101, 198, 153, 239, 239, 34, 230, 253, 108, 6, 54, 59, 54, +252, 49, 86, 67, 90, 174, 196, 140, 239, 181, 64, 85, 11, 44, 9, 229, +249, 136, 72, 125, 199, 191, 242, 156, 145, 81, 70, 193, 44, 181, 133, 36, +211, 242, 30, 144, 244, 7, 89, 97, 98, 244, 61, 184, 3, 174, 101, 173, +221, 239, 145, 166, 225, 182, 82, 202, 76, 76, 150, 198, 93, 120, 100, 254, +47, 21, 168, 61, 38, 165, 48, 31, 76, 59, 37, 89, 106, 87, 203, 179, +248, 156, 162, 64, 50, 76, 5, 123, 113, 9, 215, 226, 23, 205, 44, 245, +117, 179, 251, 160, 106, 205, 130, 187, 253, 151, 224, 24, 32, 107, 210, 221, +62, 9, 133, 192, 119, 143, 232, 69, 204, 98, 5, 86, 121, 17, 245, 180, +249, 233, 48, 185, 56, 62, 20, 215, 140, 6, 220, 139, 44, 46, 180, 236, +215, 250, 81, 195, 254, 101, 135, 40, 135, 235, 141, 22, 183, 1, 31, 3, +89, 252, 87, 207, 58, 24, 161, 225, 28, 217, 174, 122, 71, 46, 100, 25, +85, 189, 177, 45, 185, 53, 210, 109, 222, 240, 244, 82, 75, 188, 17, 191, +45, 184, 220, 132, 105, 75, 151, 12, 5, 236, 148, 150, 10, 22, 199, 26, +143, 142, 159, 137, 87, 142, 70, 241, 67, 5, 15, 235, 87, 20, 224, 207, +210, 38, 60, 245, 34, 238, 108, 193, 204, 194, 179, 7, 131, 158, 63, 245, +255, 95, 34, 247, 63, 100, 39, 85, 51, 182, 220, 69, 125, 88, 223, 39, +160, 176, 115, 100, 232, 150, 20, 40, 205, 132, 231, 201, 97, 40, 66, 207, +53, 195, 39, 59, 4, 191, 140, 210, 66, 46, 104, 196, 64, 35, 22, 151, +210, 88, 220, 108, 96, 95, 175, 97, 70, 25, 90, 111, 112, 123, 106, 204, +22, 59, 106, 248, 232, 178, 149, 32, 36, 16, 254, 191, 202, 95, 177, 177, +116, 95, 213, 205, 170, 254, 96, 184, 233, 166, 10, 156, 95, 254, 105, 205, +55, 158, 61, 129, 215, 98, 230, 107, 3, 63, 157, 155, 207, 247, 157, 79, +254, 138, 189, 94, 248, 244, 152, 167, 111, 16, 202, 234, 81, 38, 253, 1, +180, 210, 24, 89, 184, 252, 85, 6, 35, 223, 9, 34, 83, 254, 224, 69, +138, 199, 37, 90, 24, 21, 136, 15, 51, 50, 30, 54, 216, 227, 156, 117, +242, 100, 52, 163, 89, 33, 164, 98, 17, 89, 176, 21, 155, 15, 146, 216, +86, 117, 168, 3, 121, 75, 252, 116, 80, 199, 162, 215, 74, 4, 31, 118, +186, 206, 249, 116, 221, 99, 65, 54, 33, 13, 78, 210, 35, 210, 53, 122, +190, 198, 221, 183, 134, 204, 79, 8, 25, 210, 188, 253, 85, 201, 46, 250, +3, 232, 208, 37, 12, 223, 72, 151, 148, 238, 168, 204, 252, 31, 1, 28, +118, 248, 170, 149, 73, 59, 32, 202, 101, 151, 15, 8, 189, 163, 217, 141, +150, 116, 65, 129, 166, 147, 54, 1, 66, 214, 228, 77, 76, 12, 105, 1, +82, 129, 123, 28, 50, 106, 239, 115, 189, 81, 165, 89, 64, 162, 72, 173, +162, 12, 143, 161, 42, 195, 52, 49, 79, 130, 231, 207, 125, 113, 21, 43, +184, 120, 97, 79, 162, 36, 125, 204, 253, 23, 235, 22, 87, 250, 129, 46, +51, 140, 184, 122, 5, 176, 91, 77, 121, 99, 94, 246, 217, 247, 181, 100, +190, 81, 43, 71, 97, 216, 82, 144, 50, 215, 72, 88, 136, 202, 167, 146, +20, 108, 111, 48, 8, 128, 77, 59, 179, 227, 116, 102, 106, 170, 123, 183, +150, 15, 20, 226, 177, 244, 199, 210, 225, 96, 11, 232, 230, 107, 230, 92, +88, 7, 200, 250, 162, 143, 245, 215, 194, 174, 126, 31, 145, 211, 158, 210, +125, 222, 86, 80, 105, 207, 96, 197, 240, 16, 121, 229, 16, 43, 32, 18, +97, 116, 249, 105, 53, 10, 109, 163, 226, 90, 43, 205, 27, 190, 20, 75, +5, 119, 97, 81, 100, 236, 30, 13, 42, 30, 148, 237, 225, 149, 35, 17, +17, 5, 142, 35, 250, 215, 197, 155, 17, 111, 145, 129, 53, 57, 0, 200, +249, 89, 176, 189, 1, 116, 36, 15, 140, 182, 95, 214, 143, 116, 235, 82, +165, 53, 192, 181, 183, 131, 106, 5, 142, 35, 31, 235, 177, 90, 203, 121, +167, 216, 165, 33, 47, 225, 21, 227, 222, 235, 82, 74, 195, 197, 215, 79, +205, 108, 145, 185, 88, 224, 207, 185, 43, 148, 199, 55, 206, 55, 53, 36, +83, 228, 15, 155, 240, 52, 139, 36, 169, 202, 140, 11, 148, 201, 100, 116, +5, 4, 93, 209, 255, 14, 104, 27, 30, 138, 224, 182, 136, 68, 27, 18, +127, 61, 231, 13, 79, 211, 129, 170, 83, 133, 121, 42, 201, 91, 161, 157, +93, 92, 228, 230, 85, 42, 72, 252, 142, 85, 49, 49, 90, 248, 105, 64, +101, 17, 183, 104, 71, 66, 88, 231, 243, 185, 127, 109, 96, 16, 144, 67, +137, 142, 51, 15, 176, 229, 195, 244, 121, 225, 235, 1, 47, 26, 187, 199, +29, 84, 42, 209, 192, 23, 24, 66, 139, 105, 59, 42, 98, 42, 59, 121, +42, 19, 252, 216, 83, 170, 15, 153, 227, 209, 242, 192, 84, 127, 225, 7, +106, 52, 122, 11, 197, 13, 114, 196, 194, 67, 217, 106, 201, 9, 33, 188, +44, 80, 156, 138, 13, 234, 189, 29, 240, 190, 247, 231, 194, 113, 145, 182, +63, 184, 81, 203, 88, 173, 43, 148, 126, 63, 55, 30, 179, 169, 8, 4, +211, 7, 73, 48, 152, 169, 65, 139, 239, 39, 42, 66, 67, 209, 4, 20, +102, 193, 58, 22, 155, 229, 248, 233, 99, 238, 62, 173, 71, 56, 43, 153, +129, 253, 161, 69, 87, 94, 50, 53, 1, 18, 167, 179, 253, 232, 5, 244, +180, 73, 202, 206, 199, 177, 156, 168, 144, 156, 112, 247, 187, 93, 121, 233, +149, 16, 80, 145, 67, 175, 57, 252, 185, 218, 56, 13, 0, 164, 160, 84, +19, 68, 168, 14, 89, 77, 225, 2, 14, 83, 124, 56, 55, 162, 229, 39, +196, 249, 27, 240, 90, 133, 241, 237, 79, 169, 233, 173, 143, 255, 36, 249, +166, 116, 116, 177, 216, 149, 224, 26, 64, 44, 177, 25, 5, 253, 13, 50, +65, 237, 15, 138, 43, 95, 108, 20, 129, 184, 138, 121, 110, 240, 91, 12, +102, 187, 183, 232, 196, 253, 140, 90, 174, 171, 9, 150, 159, 88, 97, 56, +227, 158, 92, 227, 209, 227, 137, 248, 248, 182, 167, 229, 110, 188, 85, 30, +74, 7, 72, 99, 106, 178, 181, 90, 248, 101, 59, 184, 64, 26, 188, 1, +76, 145, 191, 118, 78, 161, 90, 157, 108, 121, 235, 154, 90, 112, 236, 204, +226, 67, 193, 204, 136, 84, 224, 47, 165, 0, 44, 46, 226, 144, 113, 146, +133, 73, 73, 101, 61, 49, 183, 45, 136, 209, 10, 185, 207, 24, 241, 253, +134, 113, 248, 233, 113, 75, 161, 177, 2, 66, 216, 62, 176, 59, 4, 163, +90, 175, 96, 238, 243, 195, 62, 32, 61, 225, 75, 178, 126, 96, 109, 122, +231, 239, 180, 196, 203, 20, 193, 0, 203, 49, 146, 34, 127, 250, 192, 204, +89, 255, 86, 9, 155, 120, 161, 237, 64, 148, 50, 54, 120, 95, 190, 121, +93, 65, 125, 191, 202, 190, 16, 112, 191, 77, 28, 125, 90, 84, 128, 7, +218, 251, 177, 71, 144, 162, 60, 43, 217, 255, 49, 53, 101, 131, 42, 192, +64, 123, 188, 33, 217, 147, 248, 63, 75, 61, 69, 149, 248, 90, 112, 148, +132, 15, 114, 114, 66, 235, 198, 222, 166, 108, 140, 172, 248, 14, 252, 63, +158, 153, 145, 61, 115, 160, 194, 30, 202, 34, 18, 158, 139, 132, 175, 73, +77, 36, 10, 85, 156, 180, 44, 92, 245, 67, 124, 21, 55, 3, 181, 208, +16, 78, 144, 45, 150, 153, 171, 99, 203, 120, 102, 144, 205, 149, 16, 168, +245, 60, 67, 171, 105, 163, 74, 101, 197, 243, 77, 206, 187, 79, 125, 54, +232, 50, 99, 60, 209, 21, 224, 203, 240, 54, 5, 64, 190, 113, 52, 43, +114, 153, 57, 24, 246, 249, 67, 5, 116, 108, 167, 24, 152, 157, 145, 145, +184, 135, 9, 21, 19, 40, 208, 87, 254, 48, 249, 255, 162, 39, 75, 119, +20, 188, 245, 166, 23, 134, 69, 64, 7, 242, 184, 89, 17, 166, 36, 158, +76, 105, 235, 212, 75, 14, 179, 168, 51, 204, 42, 50, 187, 5, 118, 76, +173, 58, 155, 172, 195, 168, 44, 28, 129, 9, 188, 8, 114, 79, 57, 233, +150, 175, 36, 213, 59, 176, 207, 25, 10, 148, 80, 3, 116, 14, 120, 161, +233, 250, 36, 212, 116, 26, 203, 37, 129, 42, 24, 65, 190, 157, 65, 193, +132, 195, 181, 27, 125, 161, 237, 17, 53, 203, 32, 29, 134, 120, 218, 120, +84, 139, 39, 121, 244, 190, 167, 179, 165, 113, 169, 219, 31, 137, 86, 15, +43, 237, 99, 71, 43, 151, 167, 221, 182, 112, 157, 111, 40, 91, 133, 17, +87, 222, 83, 221, 39, 188, 149, 51, 45, 135, 104, 27, 148, 246, 248, 28, +160, 219, 125, 198, 41, 151, 206, 26, 167, 167, 94, 41, 105, 251, 4, 35, +251, 166, 1, 111, 156, 209, 126, 39, 93, 105, 234, 197, 64, 185, 177, 48, +182, 153, 99, 34, 27, 109, 126, 192, 183, 20, 117, 131, 209, 93, 37, 71, +96, 87, 4, 183, 52, 16, 4, 125, 12, 53, 9, 76, 104, 151, 170, 9, +186, 74, 152, 140, 173, 231, 52, 113, 11, 115, 6, 75, 62, 208, 192, 102, +71, 112, 204, 74, 206, 20, 82, 5, 153, 16, 194, 186, 179, 190, 170, 219, +251, 109, 24, 88, 223, 137, 185, 190, 217, 168, 80, 101, 210, 105, 223, 115, +124, 71, 91, 192, 48, 42, 206, 220, 14, 48, 3, 232, 99, 51, 247, 39, +146, 151, 148, 230, 92, 113, 123, 184, 124, 169, 55, 5, 249, 226, 156, 86, +81, 167, 144, 164, 169, 73, 241, 61, 56, 20, 247, 116, 172, 147, 170, 3, +6, 80, 189, 3, 220, 11, 62, 56, 129, 179, 145, 205, 91, 46, 65, 29, +114, 184, 208, 118, 239, 103, 33, 224, 177, 109, 150, 19, 19, 100, 136, 166, +97, 101, 168, 9, 7, 29, 143, 169, 93, 186, 76, 23, 3, 227, 93, 240, +235, 94, 195, 2, 46, 188, 75, 37, 252, 60, 62, 186, 250, 143, 133, 96, +127, 208, 127, 55, 176, 247, 232, 99, 196, 99, 197, 107, 162, 234, 47, 109, +27, 121, 66, 73, 160, 1, 52, 29, 72, 89, 252, 231, 65, 236, 250, 198, +186, 129, 21, 102, 98, 57, 20, 184, 221, 174, 48, 37, 11, 185, 123, 187, +102, 78, 92, 3, 69, 161, 222, 33, 150, 250, 117, 85, 118, 111, 4, 145, +242, 62, 255, 27, 48, 72, 87, 253, 32, 157, 130, 68, 63, 224, 223, 227, +29, 217, 177, 173, 61, 206, 34, 14, 205, 70, 161, 224, 28, 131, 197, 203, +105, 33, 178, 131, 144, 186, 147, 119, 167, 172, 7, 116, 52, 214, 52, 191, +16, 20, 138, 241, 150, 60, 17, 30, 90, 22, 144, 187, 227, 163, 134, 176, +66, 121, 14, 1, 232, 99, 93, 57, 25, 113, 177, 243, 126, 46, 49, 0, +67, 207, 198, 255, 38, 164, 52, 221, 52, 220, 90, 196, 191, 73, 33, 136, +99, 74, 195, 31, 231, 194, 199, 182, 140, 82, 157, 188, 8, 12, 81, 84, +107, 2, 2, 35, 89, 168, 58, 130, 16, 60, 88, 163, 212, 87, 132, 194, +194, 63, 187, 98, 243, 115, 64, 245, 175, 9, 218, 0, 32, 210, 197, 40, +166, 44, 15, 234, 238, 33, 153, 224, 250, 120, 51, 0, 227, 120, 219, 44, +30, 86, 64, 104, 234, 171, 137, 78, 125, 204, 253, 60, 134, 211, 218, 47, +15, 145, 50, 231, 108, 143, 126, 99, 80, 109, 242, 211, 146, 142, 83, 22, +234, 150, 48, 123, 227, 52, 208, 213, 137, 83, 217, 82, 43, 155, 212, 230, +162, 139, 107, 243, 220, 45, 253, 220, 250, 97, 103, 239, 54, 14, 22, 131, +74, 171, 99, 219, 98, 40, 216, 176, 158, 82, 250, 106, 254, 2, 99, 49, +56, 168, 119, 184, 140, 182, 116, 186, 29, 103, 223, 20, 9, 95, 6, 36, +28, 134, 90, 8, 57, 65, 158, 33, 238, 155, 61, 210, 236, 126, 109, 144, +252, 222, 44, 104, 106, 212, 140, 195, 31, 222, 141, 131, 55, 1, 160, 236, +52, 155, 170, 173, 154, 85, 238, 6, 154, 93, 244, 172, 20, 207, 3, 249, +143, 52, 22, 77, 100, 14, 227, 254, 35, 66, 27, 37, 222, 98, 7, 22, +145, 202, 214, 116, 214, 33, 222, 138, 32, 154, 51, 86, 104, 119, 28, 107, +68, 13, 217, 155, 196, 223, 205, 180, 94, 22, 149, 156, 167, 202, 45, 125, +37, 105, 207, 145, 26, 162, 155, 167, 7, 155, 51, 201, 3, 72, 182, 154, +209, 14, 197, 215, 140, 114, 186, 121, 172, 94, 77, 16, 142, 0, 103, 184, +23, 29, 55, 101, 211, 60, 229, 54, 78, 121, 246, 79, 212, 96, 239, 52, +182, 132, 42, 214, 208, 28, 48, 252, 79, 113, 145, 90, 110, 46, 145, 190, +80, 63, 166, 210, 77, 34, 111, 125, 51, 102, 10, 3, 194, 209, 9, 160, +15, 155, 36, 235, 142, 252, 125, 174, 44, 186, 78, 171, 54, 62, 14, 227, +191, 192, 234, 43, 84, 99, 96, 201, 1, 12, 101, 98, 237, 12, 249, 186, +148, 221, 17, 209, 11, 181, 148, 166, 177, 44, 162, 16, 85, 35, 214, 85, +114, 100, 249, 76, 82, 74, 70, 30, 146, 99, 230, 15, 157, 117, 154, 219, +131, 163, 193, 175, 216, 30, 147, 176, 224, 116, 82, 144, 224, 131, 249, 50, +247, 196, 237, 65, 178, 102, 105, 252, 20, 31, 166, 17, 217, 207, 140, 216, +254, 123, 59, 77, 17, 111, 98, 168, 210, 237, 76, 110, 107, 16, 100, 40, +46, 208, 81, 201, 160, 52, 137, 25, 180, 136, 37, 214, 173, 172, 95, 113, +210, 195, 95, 222, 172, 118, 119, 189, 98, 253, 123, 107, 18, 98, 111, 201, +224, 197, 109, 136, 150, 149, 5, 87, 124, 188, 37, 201, 73, 198, 26, 6, +62, 134, 188, 136, 206, 126, 101, 46, 234, 17, 202, 47, 135, 223, 57, 59, +53, 114, 38, 89, 31, 1, 76, 76, 238, 143, 11, 190, 30, 76, 230, 46, +162, 51, 0, 186, 207, 126, 107, 219, 156, 18, 104, 247, 158, 244, 145, 20, +84, 31, 68, 141, 55, 190, 221, 105, 102, 56, 81, 154, 125, 71, 123, 126, +236, 179, 81, 231, 220, 167, 119, 206, 115, 106, 59, 166, 166, 3, 137, 43, +56, 32, 5, 45, 215, 145, 162, 47, 148, 234, 114, 18, 3, 166, 248, 209, +117, 192, 103, 35, 83, 79, 19, 212, 230, 12, 128, 214, 142, 148, 173, 234, +212, 62, 78, 144, 8, 141, 63, 252, 255, 188, 27, 191, 132, 53, 215, 220, +19, 191, 75, 253, 145, 230, 122, 156, 115, 250, 73, 171, 210, 22, 233, 244, +91, 58, 47, 75, 68, 116, 182, 98, 182, 75, 66, 36, 159, 64, 205, 176, +102, 50, 237, 38, 107, 148, 58, 61, 64, 1, 249, 68, 75, 235, 104, 25, +228, 147, 233, 46, 25, 190, 118, 196, 34, 39, 1, 60, 201, 67, 77, 64, +9, 43, 0, 150, 41, 73, 57, 254, 211, 96, 93, 129, 231, 63, 12, 177, +106, 238, 70, 73, 87, 251, 7, 254, 51, 212, 34, 34, 137, 127, 209, 207, +70, 60, 68, 71, 74, 208, 119, 211, 153, 100, 173, 21, 178, 95, 113, 6, +103, 244, 204, 200, 141, 58, 156, 13, 21, 109, 169, 215, 206, 184, 10, 248, +214, 219, 2, 22, 108, 37, 247, 157, 102, 167, 253, 142, 139, 177, 62, 243, +59, 147, 69, 231, 150, 123, 177, 231, 224, 33, 29, 75, 184, 115, 143, 218, +4, 10, 125, 35, 50, 201, 143, 44, 175, 108, 206, 247, 152, 81, 249, 135, +221, 23, 132, 80, 104, 24, 6, 10, 208, 155, 97, 45, 9, 52, 29, 232, +152, 176, 75, 242, 241, 111, 128, 127, 144, 96, 159, 171, 73, 250, 52, 163, +43, 158, 232, 89, 227, 65, 219, 151, 153, 227, 61, 46, 232, 177, 170, 203, +237, 9, 253, 225, 222, 224, 200, 86, 146, 180, 104, 8, 15, 189, 184, 94, +177, 36, 57, 170, 206, 62, 47, 152, 67, 77, 106, 10, 26, 180, 44, 124, +175, 5, 81, 96, 215, 143, 142, 152, 61, 2, 81, 216, 66, 142, 216, 71, +8, 175, 245, 51, 144, 186, 166, 28, 230, 64, 159, 150, 90, 249, 65, 151, +10, 136, 91, 38, 146, 1, 243, 23, 141, 224, 125, 108, 4, 166, 186, 241, +55, 10, 202, 251, 230, 96, 252, 248, 197, 48, 29, 239, 129, 204, 184, 15, +10, 89, 130, 175, 144, 59, 155, 33, 171, 121, 32, 19, 252, 109, 220, 191, +115, 237, 37, 243, 233, 121, 122, 90, 250, 66, 142, 44, 35, 203, 218, 145, +243, 140, 28, 161, 213, 153, 231, 76, 138, 76, 251, 151, 7, 11, 64, 193, +73, 230, 191, 196, 153, 83, 5, 94, 107, 104, 1, 65, 203, 149, 153, 209, +76, 82, 60, 0, 21, 153, 63, 172, 119, 106, 223, 51, 212, 244, 144, 25, +25, 126, 216, 9, 93, 42, 46, 188, 134, 154, 195, 84, 46, 126, 128, 136, +111, 21, 90, 103, 219, 198, 39, 161, 53, 255, 151, 213, 105, 135, 115, 226, +94, 28, 48, 252, 80, 33, 60, 213, 206, 247, 191, 175, 195, 227, 118, 54, +185, 205, 195, 248, 11, 238, 202, 13, 236, 38, 182, 1, 1, 51, 111, 190, +234, 249, 87, 189, 234, 35, 148, 226, 72, 131, 77, 249, 214, 48, 36, 116, +58, 228, 77, 168, 222, 190, 115, 193, 157, 174, 213, 105, 120, 23, 98, 134, +22, 205, 150, 192, 202, 128, 65, 128, 85, 254, 99, 135, 227, 170, 80, 96, +234, 225, 173, 172, 156, 179, 234, 81, 185, 34, 227, 155, 41, 242, 244, 138, +148, 58, 255, 232, 63, 146, 184, 233, 157, 105, 206, 181, 53, 42, 165, 59, +77, 71, 206, 219, 169, 168, 246, 61, 114, 171, 147, 22, 101, 218, 92, 93, +58, 103, 80, 240, 152, 80, 137, 179, 181, 175, 203, 245, 111, 231, 4, 41, +158, 94, 224, 189, 172, 122, 97, 92, 93, 126, 47, 229, 239, 52, 225, 102, +38, 25, 61, 196, 121, 227, 94, 27, 148, 133, 61, 98, 247, 7, 82, 187, +159, 106, 74, 51, 245, 171, 42, 69, 188, 227, 34, 178, 136, 210, 137, 62, +86, 101, 8, 204, 106, 6, 234, 105, 133, 51, 69, 50, 164, 84, 182, 73, +94, 107, 10, 134, 19, 165, 111, 191, 145, 238, 0, 8, 188, 57, 123, 185, +132, 9, 169, 43, 215, 92, 74, 108, 176, 219, 88, 26, 227, 255, 172, 198, +175, 40, 106, 120, 227, 148, 24, 151, 195, 121, 182, 70, 177, 251, 105, 27, +168, 16, 142, 207, 176, 74, 47, 217, 161, 139, 28, 60, 228, 196, 246, 233, +249, 184, 212, 36, 196, 96, 125, 79, 197, 37, 17, 133, 251, 89, 226, 187, +232, 38, 238, 158, 183, 92, 96, 35, 3, 28, 247, 68, 111, 103, 174, 110, +81, 164, 146, 165, 195, 219, 114, 27, 207, 83, 255, 253, 126, 88, 242, 198, +111, 102, 218, 249, 114, 9, 153, 221, 223, 176, 188, 88, 17, 208, 46, 178, +238, 36, 253, 109, 224, 222, 79, 154, 125, 18, 200, 101, 116, 57, 1, 129, +97, 201, 151, 111, 183, 222, 140, 135, 114, 156, 95, 84, 178, 241, 159, 177, +112, 62, 25, 125, 115, 232, 102, 251, 62, 203, 14, 5, 150, 92, 99, 241, +219, 53, 250, 69, 48, 65, 141, 243, 130, 124, 225, 30, 176, 59, 17, 175, +145, 254, 49, 241, 235, 137, 226, 136, 42, 0, 251, 160, 205, 156, 192, 10, +9, 85, 55, 14, 59, 38, 172, 192, 24, 221, 66, 54, 237, 238, 147, 90, +228, 189, 22, 9, 220, 164, 100, 218, 76, 176, 128, 184, 136, 152, 252, 67, +162, 227, 119, 133, 5, 15, 108, 130, 165, 211, 24, 19, 34, 74, 234, 209, +206, 203, 5, 232, 5, 133, 92, 251, 111, 242, 81, 57, 100, 12, 116, 139, +189, 113, 167, 141, 181, 174, 47, 10, 105, 237, 10, 170, 195, 140, 245, 184, +206, 44, 7, 175, 182, 148, 159, 209, 239, 141, 192, 194, 7, 189, 225, 93, +37, 161, 90, 81, 167, 97, 32, 161, 12, 147, 110, 81, 128, 14, 78, 146, +252, 19, 252, 221, 57, 196, 233, 98, 192, 166, 49, 199, 150, 96, 30, 247, +169, 183, 252, 210, 201, 226, 23, 114, 193, 229, 123, 251, 93, 187, 191, 44, +195, 214, 222, 243, 9, 180, 215, 34, 89, 67, 220, 162, 195, 200, 67, 126, +247, 59, 142, 35, 82, 238, 128, 25, 51, 135, 152, 238, 100, 52, 59, 118, +152, 147, 111, 133, 138, 41, 196, 210, 24, 241, 10, 35, 73, 163, 94, 97, +181, 32, 144, 24, 172, 191, 205, 12, 25, 230, 108, 130, 138, 248, 164, 98, +141, 92, 99, 56, 180, 192, 55, 63, 70, 173, 164, 57, 26, 95, 135, 243, +255, 159, 211, 163, 47, 128, 71, 155, 98, 187, 81, 159, 191, 1, 55, 225, +241, 16, 174, 240, 168, 122, 37, 40, 97, 207, 157, 157, 176, 7, 252, 81, +133, 214, 128, 83, 249, 33, 72, 143, 4, 87, 8, 197, 231, 21, 222, 74, +138, 132, 149, 108, 102, 24, 221, 154, 83, 187, 80, 31, 7, 63, 116, 180, +169, 84, 202, 18, 188, 14, 118, 98, 166, 75, 244, 10, 1, 219, 79, 105, +163, 0, 249, 253, 96, 86, 201, 39, 97, 83, 83, 174, 48, 249, 73, 39, +191, 208, 168, 34, 67, 151, 254, 16, 18, 135, 92, 157, 224, 225, 41, 254, +45, 203, 41, 197, 216, 141, 15, 210, 33, 219, 67, 189, 220, 69, 50, 19, +79, 43, 75, 122, 1, 93, 44, 65, 197, 15, 29, 234, 39, 175, 233, 136, +5, 65, 123, 116, 109, 136, 63, 92, 59, 31, 158, 1, 40, 219, 158, 94, +39, 236, 207, 198, 124, 247, 209, 150, 168, 146, 27, 164, 80, 109, 251, 220, +101, 150, 29, 142, 44, 199, 71, 232, 27, 36, 118, 69, 230, 84, 26, 172, +252, 227, 46, 19, 35, 168, 239, 5, 15, 220, 128, 95, 212, 106, 205, 242, +56, 128, 9, 20, 28, 24, 33, 11, 177, 244, 110, 237, 131, 233, 183, 223, +121, 115, 90, 225, 223, 160, 83, 66, 136, 70, 58, 153, 13, 104, 136, 207, +39, 234, 129, 140, 247, 219, 176, 72, 120, 211, 185, 133, 118, 131, 212, 59, +186, 178, 199, 228, 54, 231, 97, 187, 224, 97, 237, 206, 215, 9, 22, 12, +12, 147, 21, 38, 165, 78, 149, 245, 145, 118, 103, 245, 129, 120, 5, 142, +49, 0, 211, 224, 239, 77, 114, 48, 172, 158, 171, 19, 224, 201, 82, 218, +78, 168, 91, 134, 15, 40, 187, 114, 42, 26, 8, 142, 211, 61, 233, 8, +155, 177, 147, 149, 232, 160, 1, 177, 135, 245, 144, 69, 22, 157, 156, 200, +109, 133, 201, 157, 212, 254, 134, 213, 191, 255, 101, 255, 20, 235, 105, 62, +221, 210, 159, 64, 246, 136, 181, 60, 41, 149, 129, 224, 46, 79, 173, 136, +105, 125, 192, 244, 16, 236, 172, 194, 247, 136, 160, 191, 219, 24, 101, 151, +204, 189, 254, 69, 160, 79, 84, 149, 43, 108, 90, 65, 16, 75, 49, 182, +29, 211, 188, 135, 145, 131, 108, 143, 97, 95, 38, 38, 244, 117, 92, 157, +91, 38, 118, 118, 134, 108, 123, 83, 215, 239, 228, 186, 45, 112, 202, 166, +127, 199, 80, 183, 251, 112, 113, 237, 49, 148, 92, 31, 54, 242, 208, 12, +47, 101, 74, 79, 19, 78, 122, 60, 125, 85, 133, 3, 52, 123, 236, 60, +62, 178, 101, 111, 91, 89, 228, 63, 62, 116, 53, 148, 71, 46, 153, 133, +244, 59, 87, 117, 171, 67, 182, 119, 3, 204, 215, 205, 128, 248, 11, 59, +34, 15, 115, 249, 177, 240, 198, 58, 52, 23, 101, 132, 118, 39, 181, 199, +49, 39, 98, 196, 23, 179, 199, 62, 65, 165, 246, 218, 161, 150, 163, 253, +94, 124, 215, 10, 245, 71, 135, 168, 59, 251, 229, 157, 39, 75, 179, 211, +83, 33, 172, 81, 2, 30, 222, 174, 66, 80, 11, 196, 187, 123, 255, 127, +187, 208, 236, 106, 88, 54, 93, 253, 37, 33, 155, 82, 26, 156, 57, 87, +148, 130, 44, 84, 207, 171, 200, 131, 82, 28, 61, 122, 155, 114, 160, 253, +29, 177, 50, 168, 100, 73, 18, 132, 92, 136, 67, 24, 156, 149, 164, 120, +109, 130, 170, 156, 164, 248, 104, 83, 152, 231, 211, 100, 78, 59, 170, 147, +101, 86, 254, 127, 143, 124, 178, 232, 35, 35, 243, 3, 220, 198, 182, 146, +71, 250, 50, 61, 152, 253, 101, 219, 219, 159, 58, 34, 239, 111, 144, 29, +8, 99, 24, 212, 123, 176, 171, 0, 132, 253, 35, 140, 166, 157, 68, 215, +217, 105, 78, 224, 18, 118, 216, 79, 227, 101, 59, 153, 27, 217, 243, 250, +193, 213, 100, 184, 69, 78, 229, 7, 144, 107, 5, 214, 223, 139, 123, 44, +140, 165, 131, 215, 65, 77, 181, 143, 101, 218, 198, 87, 47, 191, 10, 102, +231, 0, 239, 23, 128, 83, 11, 218, 62, 104, 185, 73, 211, 216, 40, 70, +231, 92, 187, 172, 255, 66, 159, 93, 156, 35, 172, 123, 2, 230, 123, 236, +241, 154, 88, 136, 179, 147, 174, 89, 50, 5, 158, 169, 128, 127, 215, 231, +82, 83, 159, 66, 241, 205, 103, 143, 20, 248, 239, 143, 31, 210, 249, 39, +25, 8, 8, 242, 111, 111, 188, 35, 190, 251, 17, 114, 164, 49, 24, 113, +159, 50, 115, 56, 190, 180, 91, 125, 237, 99, 116, 211, 36, 208, 115, 12, +73, 61, 99, 110, 81, 64, 83, 163, 131, 154, 211, 9, 165, 11, 30, 177, +177, 43, 241, 7, 108, 203, 224, 75, 25, 246, 160, 33, 148, 32, 131, 183, +190, 0, 219, 28, 208, 242, 134, 174, 91, 92, 51, 36, 240, 43, 139, 147, +101, 183, 51, 216, 249, 42, 166, 52, 133, 115, 249, 6, 240, 23, 27, 23, +77, 180, 40, 175, 240, 173, 104, 70, 137, 83, 82, 171, 155, 215, 136, 131, +4, 172, 19, 100, 255, 146, 160, 199, 128, 177, 130, 163, 56, 104, 107, 102, +44, 178, 196, 187, 0, 38, 53, 230, 191, 148, 218, 207, 105, 66, 106, 103, +52, 241, 119, 233, 63, 63, 182, 45, 101, 61, 210, 89, 175, 101, 98, 89, +172, 252, 236, 36, 54, 143, 131, 55, 35, 189, 128, 57, 73, 34, 229, 250, +206, 253, 43, 37, 53, 136, 172, 73, 221, 27, 205, 207, 21, 120, 92, 6, +220, 166, 66, 95, 45, 241, 209, 112, 72, 22, 31, 221, 232, 220, 157, 248, +78, 105, 214, 230, 41, 193, 211, 46, 249, 26, 11, 242, 42, 225, 116, 207, +166, 141, 116, 185, 223, 86, 218, 190, 255, 185, 250, 199, 181, 56, 188, 132, +37, 27, 85, 248, 112, 161, 182, 164, 153, 129, 40, 37, 13, 8, 67, 236, +36, 182, 151, 130, 96, 131, 65, 26, 103, 239, 65, 243, 234, 162, 7, 90, +237, 24, 99, 145, 47, 181, 99, 65, 38, 36, 112, 157, 239, 225, 127, 161, +168, 6, 66, 231, 252, 142, 154, 225, 138, 189, 243, 66, 142, 71, 61, 239, +55, 230, 59, 40, 224, 134, 104, 100, 189, 166, 249, 66, 91, 146, 154, 28, +67, 78, 138, 40, 114, 71, 172, 3, 168, 233, 9, 106, 228, 143, 56, 193, +227, 243, 144, 51, 222, 94, 224, 43, 79, 149, 212, 245, 52, 68, 200, 17, +235, 45, 164, 147, 62, 118, 52, 216, 195, 78, 13, 66, 190, 188, 241, 142, +234, 182, 85, 48, 148, 214, 123, 57, 223, 188, 229, 119, 169, 180, 193, 70, +250, 215, 249, 29, 88, 123, 88, 226, 210, 171, 170, 32, 80, 85, 3, 26, +219, 109, 97, 134, 11, 96, 118, 71, 130, 86, 182, 77, 116, 137, 214, 28, +140, 242, 227, 178, 167, 200, 214, 175, 107, 96, 132, 33, 40, 64, 93, 206, +90, 129, 132, 221, 170, 242, 113, 235, 251, 172, 193, 35, 58, 85, 70, 9, +75, 104, 71, 161, 99, 214, 6, 33, 204, 250, 172, 199, 33, 183, 246, 250, +109, 251, 50, 106, 114, 16, 134, 150, 19, 219, 21, 60, 63, 251, 204, 157, +45, 106, 233, 133, 154, 145, 135, 201, 77, 59, 178, 176, 217, 109, 236, 19, +19, 200, 5, 165, 235, 81, 14, 42, 153, 40, 189, 86, 92, 90, 239, 77, +53, 136, 65, 112, 94, 130, 104, 71, 55, 79, 22, 250, 34, 178, 14, 91, +24, 145, 250, 4, 197, 96, 72, 118, 142, 31, 83, 137, 14, 57, 115, 36, +202, 144, 10, 19, 123, 176, 23, 93, 35, 90, 145, 73, 163, 124, 66, 156, +8, 82, 243, 22, 204, 59, 77, 49, 222, 1, 246, 7, 75, 15, 234, 110, +9, 232, 29, 156, 239, 250, 88, 24, 244, 123, 15, 169, 66, 180, 254, 210, +233, 134, 27, 100, 162, 103, 158, 223, 149, 226, 167, 140, 53, 34, 57, 105, +221, 112, 116, 72, 207, 169, 98, 200, 189, 33, 72, 181, 162, 166, 4, 29, +98, 157, 184, 244, 188, 127, 186, 35, 186, 202, 24, 21, 185, 160, 63, 17, +112, 78, 96, 49, 87, 60, 154, 215, 49, 196, 179, 122, 60, 253, 154, 86, +177, 227, 70, 1, 80, 205, 58, 66, 103, 146, 170, 108, 34, 134, 149, 134, +160, 225, 152, 63, 18, 199, 101, 158, 199, 235, 124, 98, 105, 8, 62, 100, +92, 248, 81, 59, 108, 190, 156, 216, 106, 103, 90, 69, 199, 160, 21, 66, +203, 125, 157, 189, 8, 115, 15, 158, 77, 105, 124, 171, 180, 227, 134, 50, +208, 245, 254, 35, 231, 215, 231, 193, 218, 216, 68, 204, 229, 233, 95, 120, +177, 105, 108, 92, 9, 181, 119, 196, 19, 97, 5, 145, 254, 112, 156, 70, +9, 68, 39, 84, 33, 80, 2, 21, 228, 184, 145, 218, 19, 202, 231, 144, +3, 29, 22, 14, 146, 193, 90, 216, 63, 95, 197, 70, 198, 68, 235, 132, +16, 31, 100, 179, 19, 105, 19, 178, 210, 222, 118, 148, 37, 202, 50, 222, +84, 246, 89, 36, 25, 183, 80, 175, 79, 154, 38, 119, 89, 125, 133, 56, +21, 61, 187, 123, 80, 224, 187, 15, 84, 46, 19, 1, 24, 246, 250, 32, +226, 193, 49, 118, 252, 1, 47, 172, 161, 175, 60, 113, 56, 248, 198, 100, +117, 78, 138, 154, 40, 231, 118, 120, 23, 223, 8, 239, 145, 51, 43, 82, +146, 83, 129, 43, 146, 75, 171, 20, 186, 157, 174, 137, 205, 187, 198, 37, +10, 108, 65, 154, 212, 207, 63, 178, 11, 51, 5, 62, 172, 122, 219, 147, +16, 223, 243, 134, 146, 161, 173, 118, 113, 185, 212, 199, 29, 83, 5, 241, +42, 54, 160, 57, 100, 116, 111, 218, 193, 39, 66, 67, 141, 161, 179, 141, +54, 87, 16, 43, 15, 93, 41, 240, 62, 66, 231, 59, 42, 48, 46, 207, +141, 27, 160, 156, 247, 138, 129, 130, 68, 34, 66, 69, 177, 45, 108, 26, +36, 50, 109, 46, 238, 82, 187, 219, 166, 225, 115, 204, 121, 228, 122, 92, +65, 67, 69, 162, 104, 10, 117, 17, 33, 113, 110, 10, 9, 2, 41, 24, +227, 173, 49, 10, 2, 147, 115, 197, 93, 133, 139, 86, 38, 138, 102, 92, +17, 94, 115, 74, 101, 5, 12, 222, 186, 229, 16, 126, 16, 234, 105, 191, +184, 182, 27, 59, 152, 118, 179, 114, 78, 65, 15, 21, 43, 215, 7, 215, +110, 207, 152, 128, 14, 106, 188, 73, 230, 183, 23, 101, 92, 95, 250, 115, +245, 40, 58, 167, 157, 201, 1, 229, 233, 39, 243, 103, 253, 104, 135, 248, +219, 74, 127, 91, 135, 224, 240, 42, 6, 70, 70, 48, 23, 52, 78, 12, +212, 203, 55, 134, 108, 107, 185, 237, 129, 120, 234, 54, 243, 252, 231, 19, +190, 190, 46, 48, 115, 200, 145, 119, 195, 140, 122, 21, 85, 120, 189, 33, +208, 59, 39, 181, 57, 55, 128, 144, 149, 120, 65, 77, 113, 75, 203, 194, +251, 217, 77, 110, 56, 54, 93, 240, 101, 219, 52, 174, 163, 153, 193, 24, +16, 112, 103, 178, 252, 57, 2, 7, 55, 184, 80, 176, 248, 128, 236, 73, +250, 66, 218, 63, 16, 230, 149, 32, 149, 237, 199, 168, 81, 147, 63, 211, +251, 112, 223, 62, 92, 60, 114, 156, 203, 12, 225, 232, 250, 166, 123, 194, +227, 56, 82, 4, 104, 168, 170, 38, 93, 122, 232, 207, 228, 68, 58, 247, +162, 96, 128, 20, 249, 114, 93, 37, 199, 229, 152, 134, 168, 14, 212, 153, +137, 31, 241, 189, 163, 223, 247, 196, 22, 67, 27, 105, 10, 235, 28, 24, +177, 249, 230, 19, 247, 145, 228, 151, 195, 17, 201, 93, 226, 167, 76, 227, +85, 207, 200, 139, 37, 148, 40, 243, 214, 60, 55, 241, 183, 126, 160, 97, +6, 129, 104, 182, 207, 250, 77, 123, 235, 211, 158, 171, 52, 171, 186, 53, +121, 24, 137, 105, 164, 247, 172, 132, 201, 31, 135, 123, 0, 164, 164, 235, +167, 103, 63, 40, 54, 102, 46, 197, 185, 194, 14, 195, 159, 182, 120, 4, +36, 14, 194, 219, 155, 23, 233, 148, 169, 113, 158, 92, 103, 68, 247, 133, +214, 252, 9, 220, 50, 198, 251, 75, 34, 10, 115, 209, 172, 147, 168, 185, +81, 70, 174, 155, 80, 111, 246, 78, 199, 155, 192, 2, 241, 162, 123, 123, +77, 228, 101, 22, 241, 89, 245, 63, 3, 235, 76, 162, 20, 12, 81, 228, +254, 50, 146, 76, 149, 112, 226, 88, 231, 167, 229, 27, 250, 21, 98, 84, +235, 251, 213, 238, 209, 111, 34, 144, 181, 190, 22, 60, 112, 244, 98, 241, +19, 51, 163, 4, 198, 8, 50, 194, 200, 241, 155, 192, 97, 95, 173, 49, +94, 169, 112, 21, 87, 23, 229, 226, 75, 60, 134, 126, 21, 10, 86, 84, +238, 113, 19, 77, 205, 3, 158, 105, 241, 98, 86, 237, 233, 190, 97, 136, +202, 234, 147, 121, 253, 156, 176, 238, 222, 71, 35, 185, 127, 212, 211, 0, +86, 129, 131, 93, 111, 167, 121, 138, 69, 251, 4, 90, 229, 43, 48, 144, +138, 0, 48, 249, 202, 203, 46, 117, 175, 27, 96, 230, 119, 93, 156, 129, +186, 122, 133, 114, 160, 196, 50, 81, 97, 63, 13, 188, 146, 63, 4, 220, +222, 165, 9, 236, 124, 117, 145, 91, 244, 186, 233, 35, 78, 241, 45, 38, +127, 179, 165, 20, 253, 131, 171, 41, 230, 158, 162, 83, 50, 19, 23, 83, +128, 121, 67, 248, 17, 145, 98, 112, 190, 250, 237, 243, 248, 64, 146, 41, +16, 44, 154, 33, 60, 162, 161, 156, 229, 176, 172, 49, 42, 240, 235, 85, +90, 162, 151, 170, 183, 27, 21, 183, 40, 134, 187, 193, 75, 183, 76, 63, +235, 27, 90, 133, 26, 138, 83, 150, 77, 206, 233, 166, 204, 90, 125, 211, +133, 229, 10, 166, 12, 146, 184, 152, 107, 242, 245, 52, 145, 154, 34, 249, +13, 102, 253, 209, 20, 3, 225, 88, 156, 137, 30, 182, 206, 211, 255, 149, +39, 64, 133, 16, 125, 5, 115, 220, 51, 122, 242, 121, 222, 212, 239, 237, +208, 31, 72, 98, 36, 131, 185, 9, 124, 14, 55, 236, 196, 38, 68, 82, +17, 197, 255, 168, 199, 158, 94, 52, 58, 126, 100, 57, 118, 184, 214, 42, +65, 249, 156, 128, 82, 139, 234, 63, 119, 55, 89, 108, 207, 209, 226, 34, +198, 134, 54, 131, 154, 87, 96, 31, 11, 241, 1, 11, 97, 61, 167, 20, +223, 188, 163, 31, 250, 189, 13, 29, 196, 209, 218, 119, 102, 13, 172, 149, +149, 219, 251, 64, 238, 211, 212, 136, 82, 237, 150, 140, 188, 201, 123, 191, +83, 133, 193, 253, 25, 27, 246, 72, 60, 212, 227, 241, 209, 206, 142, 29, +11, 11, 146, 182, 203, 214, 25, 192, 236, 197, 176, 6, 216, 105, 145, 191, +115, 161, 107, 170, 194, 121, 148, 205, 65, 116, 157, 96, 173, 217, 30, 96, +174, 239, 178, 151, 121, 46, 3, 86, 65, 32, 120, 195, 66, 86, 144, 206, +91, 36, 148, 42, 216, 208, 164, 203, 149, 69, 230, 49, 78, 224, 177, 23, +175, 103, 191, 111, 181, 130, 255, 215, 189, 173, 134, 189, 64, 36, 226, 134, +89, 116, 138, 92, 81, 246, 202, 10, 243, 21, 81, 165, 210, 235, 49, 99, +217, 19, 184, 54, 71, 102, 132, 49, 135, 228, 156, 67, 170, 38, 173, 200, +239, 244, 255, 65, 211, 100, 161, 118, 111, 218, 219, 87, 23, 57, 9, 246, +102, 252, 157, 205, 98, 12, 97, 198, 183, 141, 223, 154, 23, 180, 123, 80, +156, 144, 231, 95, 42, 135, 31, 244, 164, 121, 138, 116, 154, 207, 222, 138, +32, 84, 185, 56, 114, 9, 244, 11, 213, 237, 166, 91, 31, 217, 20, 179, +168, 121, 139, 237, 181, 221, 90, 174, 2, 176, 34, 210, 130, 241, 130, 240, +178, 89, 176, 130, 185, 243, 52, 101, 116, 112, 6, 60, 84, 6, 110, 29, +246, 66, 10, 164, 130, 46, 75, 163, 179, 45, 250, 32, 57, 48, 74, 169, +133, 44, 167, 241, 103, 31, 119, 243, 74, 208, 4, 162, 17, 11, 72, 126, +10, 81, 117, 188, 103, 222, 163, 78, 206, 72, 216, 73, 2, 221, 230, 122, +107, 141, 126, 1, 236, 63, 51, 169, 160, 14, 165, 208, 174, 9, 91, 74, +252, 146, 198, 79, 238, 175, 39, 102, 75, 150, 40, 109, 143, 117, 77, 153, +234, 82, 38, 162, 23, 242, 107, 124, 217, 13, 51, 55, 92, 1, 28, 138, +62, 209, 69, 222, 63, 62, 150, 221, 74, 232, 220, 181, 21, 36, 203, 182, +193, 183, 173, 113, 157, 241, 208, 131, 172, 0, 176, 55, 229, 63, 54, 84, +197, 105, 196, 154, 60, 52, 50, 191, 230, 202, 129, 85, 235, 75, 245, 172, +58, 230, 0, 251, 250, 104, 123, 247, 224, 120, 118, 30, 50, 223, 144, 233, +243, 213, 58, 228, 124, 24, 168, 194, 24, 192, 4, 63, 107, 39, 55, 202, +196, 254, 149, 141, 189, 136, 218, 108, 203, 100, 198, 121, 240, 252, 208, 200, +230, 178, 117, 199, 2, 55, 165, 214, 210, 246, 142, 178, 63, 86, 249, 156, +100, 172, 202, 197, 148, 222, 76, 185, 221, 248, 71, 7, 231, 224, 158, 236, +27, 44, 53, 58, 181, 65, 176, 146, 223, 254, 5, 249, 207, 218, 160, 212, +245, 14, 114, 246, 153, 139, 55, 230, 89, 143, 125, 133, 103, 249, 123, 91, +229, 195, 214, 65, 251, 219, 11, 48, 167, 72, 9, 131, 110, 207, 244, 197, +159, 23, 51, 161, 135, 251, 220, 52, 242, 122, 199, 21, 231, 34, 185, 84, +140, 112, 3, 164, 231, 64, 162, 192, 103, 182, 162, 112, 2, 142, 22, 148, +62, 71, 79, 232, 85, 38, 15, 87, 230, 232, 112, 203, 94, 230, 172, 233, +219, 158, 246, 87, 61, 155, 22, 14, 157, 23, 61, 99, 196, 97, 70, 216, +173, 236, 211, 120, 197, 28, 231, 47, 215, 66, 71, 46, 66, 28, 29, 223, +77, 173, 144, 82, 220, 222, 99, 229, 74, 53, 88, 116, 123, 162, 240, 168, +216, 142, 205, 144, 183, 127, 135, 4, 162, 91, 176, 78, 26, 178, 249, 104, +195, 76, 105, 206, 143, 20, 158, 220, 22, 67, 201, 237, 78, 241, 56, 111, +63, 160, 240, 168, 131, 253, 62, 8, 51, 88, 43, 174, 217, 235, 243, 71, +50, 210, 7, 235, 56, 63, 128, 111, 32, 244, 187, 217, 170, 77, 152, 65, +7, 200, 30, 47, 83, 126, 139, 170, 142, 219, 184, 156, 54, 102, 249, 94, +32, 2, 204, 206, 77, 230, 60, 184, 143, 167, 110, 241, 203, 60, 44, 174, +128, 150, 186, 215, 218, 189, 87, 107, 216, 84, 76, 166, 171, 91, 23, 16, +208, 211, 181, 234, 61, 203, 224, 172, 128, 129, 66, 7, 249, 0, 75, 157, +235, 49, 244, 154, 157, 107, 205, 70, 146, 38, 188, 6, 218, 133, 231, 204, +168, 234, 133, 17, 245, 85, 253, 163, 242, 168, 56, 9, 99, 142, 236, 237, +67, 20, 226, 60, 4, 86, 83, 208, 243, 19, 127, 168, 6, 156, 67, 179, +66, 170, 242, 211, 170, 199, 188, 71, 231, 191, 67, 42, 109, 37, 117, 154, +231, 116, 63, 232, 206, 107, 141, 17, 127, 143, 79, 247, 160, 62, 151, 234, +116, 126, 14, 223, 8, 5, 52, 82, 8, 99, 17, 9, 7, 4, 208, 106, +11, 208, 156, 157, 85, 51, 236, 128, 41, 66, 99, 243, 220, 153, 131, 111, +78, 189, 95, 219, 51, 100, 41, 150, 188, 218, 35, 37, 176, 31, 122, 252, +207, 222, 214, 142, 95, 19, 136, 159, 195, 209, 39, 182, 19, 97, 185, 72, +83, 165, 208, 249, 83, 4, 244, 230, 30, 7, 13, 161, 90, 200, 121, 138, +67, 151, 252, 197, 165, 44, 215, 9, 81, 118, 179, 159, 15, 3, 156, 105, +151, 104, 109, 161, 202, 143, 199, 41, 187, 172, 154, 64, 105, 69, 67, 173, +226, 34, 234, 111, 69, 244, 45, 230, 49, 11, 18, 158, 56, 184, 55, 124, +46, 252, 215, 109, 236, 124, 156, 172, 148, 159, 44, 147, 129, 50, 49, 230, +128, 213, 137, 161, 125, 140, 222, 36, 90, 117, 223, 146, 237, 122, 39, 118, +188, 93, 11, 40, 49, 114, 230, 80, 31, 221, 58, 199, 174, 192, 112, 31, +236, 98, 56, 76, 27, 199, 78, 28, 48, 62, 246, 207, 30, 85, 50, 31, +4, 143, 58, 241, 131, 83, 203, 70, 241, 124, 150, 160, 88, 30, 227, 177, +213, 75, 139, 122, 83, 83, 41, 97, 140, 78, 157, 188, 172, 85, 52, 202, +76, 47, 145, 76, 126, 144, 228, 49, 239, 103, 196, 149, 203, 133, 159, 201, +215, 241, 71, 245, 114, 49, 125, 228, 22, 192, 235, 230, 246, 247, 100, 110, +76, 74, 214, 226, 221, 120, 140, 250, 108, 9, 203, 40, 92, 19, 184, 136, +86, 76, 250, 177, 64, 76, 214, 79, 190, 86, 8, 131, 178, 0, 200, 171, +245, 144, 94, 2, 236, 11, 187, 119, 165, 83, 130, 252, 49, 126, 254, 131, +38, 43, 245, 170, 53, 7, 183, 205, 84, 71, 16, 127, 86, 249, 31, 169, +65, 33, 207, 146, 111, 155, 43, 145, 85, 250, 216, 38, 95, 18, 129, 186, +14, 3, 158, 43, 183, 44, 205, 90, 37, 141, 27, 130, 115, 4, 121, 67, +113, 43, 109, 251, 71, 103, 32, 129, 163, 73, 116, 252, 32, 149, 17, 150, +117, 168, 218, 56, 163, 173, 125, 84, 103, 136, 195, 89, 46, 27, 45, 153, +6, 184, 81, 93, 131, 28, 42, 171, 87, 177, 135, 109, 24, 78, 80, 103, +110, 168, 3, 251, 165, 139, 171, 25, 77, 166, 250, 193, 166, 168, 195, 160, +12, 25, 110, 36, 0, 132, 247, 199, 195, 30, 177, 14, 176, 197, 58, 142, +93, 43, 151, 126, 28, 184, 231, 179, 113, 227, 26, 165, 98, 180, 183, 218, +182, 150, 125, 231, 102, 231, 206, 39, 57, 121, 193, 43, 11, 254, 173, 29, +251, 45, 171, 106, 87, 114, 38, 58, 153, 72, 84, 193, 36, 2, 142, 215, +121, 147, 160, 11, 37, 243, 213, 217, 181, 152, 112, 191, 155, 217, 136, 117, +175, 182, 125, 134, 218, 58, 212, 239, 39, 250, 119, 220, 113, 214, 143, 204, +124, 11, 153, 200, 158, 215, 253, 40, 35, 17, 232, 45, 217, 47, 191, 159, +199, 82, 41, 106, 158, 244, 222, 254, 133, 109, 151, 43, 187, 203, 165, 61, +163, 205, 7, 217, 12, 252, 123, 90, 255, 255, 88, 221, 122, 76, 173, 185, +85, 185, 33, 228, 226, 161, 72, 217, 34, 197, 140, 190, 18, 7, 142, 177, +203, 49, 93, 91, 12, 12, 29, 35, 100, 136, 58, 22, 174, 49, 71, 209, +218, 199, 125, 51, 110, 117, 45, 205, 141, 81, 192, 148, 211, 238, 218, 84, +227, 191, 160, 49, 110, 207, 190, 8, 156, 184, 167, 148, 228, 69, 19, 39, +3, 210, 204, 196, 230, 123, 64, 123, 133, 115, 33, 85, 15, 45, 144, 218, +31, 192, 34, 60, 208, 166, 113, 151, 122, 249, 171, 207, 8, 164, 207, 138, +246, 217, 251, 34, 27, 145, 144, 57, 60, 165, 203, 117, 199, 80, 141, 218, +36, 65, 24, 115, 33, 152, 139, 152, 34, 72, 99, 192, 219, 49, 65, 187, +217, 14, 208, 56, 62, 143, 12, 51, 225, 187, 38, 19, 114, 83, 118, 117, +17, 249, 224, 185, 225, 237, 71, 79, 67, 75, 51, 0, 92, 123, 155, 122, +154, 105, 101, 235, 17, 160, 35, 152, 108, 45, 151, 154, 92, 149, 63, 255, +77, 153, 104, 98, 208, 251, 112, 189, 38, 102, 205, 117, 255, 232, 150, 109, +51, 70, 5, 11, 224, 41, 141, 200, 227, 170, 1, 220, 34, 103, 112, 185, +169, 207, 141, 183, 172, 61, 129, 113, 126, 200, 59, 197, 93, 245, 240, 58, +232, 40, 90, 125, 37, 134, 210, 82, 118, 234, 200, 115, 169, 124, 188, 1, +172, 236, 31, 79, 211, 213, 146, 195, 206, 105, 57, 241, 59, 237, 145, 32, +6, 24, 253, 23, 60, 211, 2, 94, 42, 190, 180, 213, 177, 23, 167, 104, +3, 226, 171, 208, 95, 96, 57, 53, 141, 115, 88, 174, 10, 206, 234, 150, +182, 157, 242, 93, 97, 80, 9, 154, 152, 166, 94, 141, 238, 212, 68, 231, +244, 0, 36, 167, 2, 9, 169, 16, 151, 170, 33, 51, 1, 105, 210, 194, +224, 146, 221, 227, 137, 63, 144, 14, 5, 140, 30, 193, 203, 47, 90, 20, +233, 169, 66, 192, 91, 252, 161, 140, 67, 202, 12, 24, 190, 242, 46, 208, +121, 8, 194, 164, 164, 125, 216, 194, 242, 125, 131, 35, 5, 45, 18, 152, +157, 240, 35, 56, 246, 144, 175, 2, 7, 123, 13, 158, 168, 115, 221, 195, +54, 236, 35, 132, 246, 7, 100, 108, 120, 17, 23, 210, 61, 238, 38, 73, +149, 28, 249, 29, 5, 232, 28, 131, 84, 79, 155, 26, 82, 96, 150, 219, +122, 167, 231, 56, 233, 176, 154, 213, 126, 14, 155, 13, 68, 157, 25, 236, +244, 64, 125, 74, 247, 241, 123, 177, 102, 43, 244, 122, 173, 75, 132, 244, +248, 236, 246, 161, 138, 68, 86, 2, 52, 121, 232, 96, 100, 207, 238, 219, +64, 197, 162, 8, 97, 144, 89, 121, 66, 146, 166, 233, 7, 145, 217, 223, +51, 254, 128, 1, 211, 1, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 10, 48, 48, 48, 48, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 10, 48, 48, 48, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 10, 48, 48, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 10, 48, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 10, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 10, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 10, 99, +108, 101, 97, 114, 116, 111, 109, 97, 114, 107, 10, 128, 3 +}; diff -Nru blender-2.61/source/blender/editors/datafiles/blender_icons.png.c blender-2.62/source/blender/editors/datafiles/blender_icons.png.c --- blender-2.61/source/blender/editors/datafiles/blender_icons.png.c 2011-12-13 19:54:09.000000000 +0000 +++ blender-2.62/source/blender/editors/datafiles/blender_icons.png.c 2012-02-15 19:38:23.000000000 +0000 @@ -1,6289 +1,6865 @@ /* DataToC output of file */ -int datatoc_blender_icons_png_size= 201043; +int datatoc_blender_icons_png_size= 219467; char datatoc_blender_icons_png[]= { -137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 2, - 90, 0, 0, 2,128, 8, 6, 0, 0, 0, 68,254,214,163, 0, 0, 0, 4,103, 65, 77, 65, 0, 0,177,142,124,251, 81,147, 0, 0, - 0, 32, 99, 72, 82, 77, 0, 0,135, 15, 0, 0,140, 15, 0, 0,253, 82, 0, 0,129, 64, 0, 0,125,121, 0, 0,233,139, 0, 0, - 60,229, 0, 0, 25,204,115, 60,133,119, 0, 0, 10, 57,105, 67, 67, 80, 80,104,111,116,111,115,104,111,112, 32, 73, 67, 67, 32, -112,114,111,102,105,108,101, 0, 0, 72,199,157,150,119, 84, 84,215, 22,135,207,189,119,122,161,205, 48, 2, 82,134,222,187,192, - 0,210,123,147, 94, 69, 97,152, 25, 96, 40, 3, 14, 51, 52,177, 33,162, 2, 17, 69, 68,154, 34, 72, 80,196,128,209, 80, 36, 86, - 68,177, 16, 20, 84,176, 7, 36, 8, 40, 49, 24, 69, 84, 44,111, 70,214,139,174,172,188,247,242,242,251,227,172,111,237,179,247, -185,251,236,189,207, 90, 23, 0,146,167, 47,151,151, 6, 75, 1,144,202, 19,240,131, 60,156,233, 17,145, 81,116,236, 0,128, 1, - 30, 96,128, 41, 0, 76, 86, 70,186, 95,176,123, 8, 16,201,203,205,133,158, 33,114, 2, 95, 4, 1,240,122, 88,188, 2,112,211, -208, 51,128, 78, 7,255,159,164, 89,233,124,129,232,152, 0, 17,155,179, 57, 25, 44, 17, 23,136, 56, 37, 75,144, 46,182,207,138, -152, 26,151, 44,102, 24, 37,102,190, 40, 65, 17,203,137, 57, 97,145, 13, 62,251, 44,178,163,152,217,169, 60,182,136,197, 57,167, -179, 83,217, 98,238, 21,241,182, 76, 33, 71,196,136,175,136, 11, 51,185,156, 44, 17,223, 18,177, 70,138, 48,149, 43,226, 55,226, -216, 84, 14, 51, 3, 0, 20, 73,108, 23,112, 88,137, 34, 54, 17, 49,137, 31, 18,228, 34,226,229, 0,224, 72, 9, 95,113,220, 87, - 44,224,100, 11,196,151,114, 73, 75,207,225,115, 19, 18, 5,116, 29,150, 46,221,212,218,154, 65,247,228,100,165,112, 4, 2,195, - 0, 38, 43,153,201,103,211, 93,210, 82,211,153,188, 28, 0, 22,239,252, 89, 50,226,218,210, 69, 69,182, 52,181,182,180, 52, 52, - 51, 50,253,170, 80,255,117,243,111, 74,220,219, 69,122, 25,248,185,103, 16,173,255,139,237,175,252,210, 26, 0, 96,204,137,106, -179,243,139, 45,174, 10,128,206, 45, 0,200,221,251, 98,211, 56, 0,128,164,168,111, 29,215,191,186, 15, 77, 60, 47,137, 2, 65, -186,141,177,113, 86, 86,150, 17,151,195, 50, 18, 23,244, 15,253, 79,135,191,161,175,190,103, 36, 62,238,143,242,208, 93, 57,241, - 76, 97,138,128, 46,174, 27, 43, 45, 37, 77,200,167,103,164, 51, 89, 28,186,225,159,135,248, 31, 7,254,117, 30, 6, 65,156,120, - 14,159,195, 19, 69,132,137,166,140,203, 75, 16,181,155,199,230, 10,184,105, 60, 58,151,247,159,154,248, 15,195,254,164,197,185, - 22,137,210,248, 17, 80, 99,140,128,212,117, 42, 64,126,237, 7, 40, 10, 17, 32,209,251,197, 93,255,163,111,190,248, 48, 32,126, -121,225, 42,147,139,115,255,239, 55,253,103,193,165,226, 37,131,155,240, 57,206, 37, 40,132,206, 18,242, 51, 23,247,196,207, 18, -160, 1, 1, 72, 2, 42,144, 7,202, 64, 29,232, 0, 67, 96, 6,172,128, 45,112, 4,110,192, 27,248,131, 16, 16, 9, 86, 3, 22, - 72, 4,169,128, 15,178, 64, 30,216, 4, 10, 65, 49,216, 9,246,128,106, 80, 7, 26, 65, 51,104, 5,199, 65, 39, 56, 5,206,131, - 75,224, 26,184, 1,110,131,251, 96, 20, 76,128,103, 96, 22,188, 6, 11, 16, 4, 97, 33, 50, 68,129,228, 33, 21, 72, 19,210,135, -204, 32, 6,100, 15,185, 65,190, 80, 16, 20, 9,197, 66, 9, 16, 15, 18, 66,121,208,102,168, 24, 42,131,170,161,122,168, 25,250, - 30, 58, 9,157,135,174, 64,131,208, 93,104, 12,154,134,126,135,222,193, 8, 76,130,169,176, 18,172, 5, 27,195, 12,216, 9,246, -129, 67,224, 85,112, 2,188, 6,206,133, 11,224, 29,112, 37,220, 0, 31,133, 59,224,243,240, 53,248, 54, 60, 10, 63,131,231, 16, -128, 16, 17, 26,162,138, 24, 34, 12,196, 5,241, 71,162,144,120,132,143,172, 71,138,144, 10,164, 1,105, 69,186,145, 62,228, 38, - 50,138,204, 32,111, 81, 24, 20, 5, 69, 71, 25,162,108, 81,158,168, 80, 20, 11,181, 6,181, 30, 85,130,170, 70, 29, 70,117,160, -122, 81, 55, 81, 99,168, 89,212, 71, 52, 25,173,136,214, 71,219,160,189,208, 17,232, 4,116, 22,186, 16, 93,129,110, 66,183,163, - 47,162,111,163, 39,208,175, 49, 24, 12, 13,163,141,177,194,120, 98, 34, 49, 73,152,181,152, 18,204, 62, 76, 27,230, 28,102, 16, - 51,142,153,195, 98,177,242, 88,125,172, 29,214, 31,203,196, 10,176,133,216, 42,236, 81,236, 89,236, 16,118, 2,251, 6, 71,196, -169,224,204,112,238,184, 40, 28, 15,151,143,171,192, 29,193,157,193, 13,225, 38,113, 11,120, 41,188, 38,222, 6,239,143,103,227, -115,240,165,248, 70,124, 55,254, 58,126, 2,191, 64,144, 38,104, 19,236, 8, 33,132, 36,194, 38, 66, 37,161,149,112,145,240,128, -240,146, 72, 36,170, 17,173,137,129, 68, 46,113, 35,177,146,120,140,120,153, 56, 70,124, 75,146, 33,233,145, 92, 72,209, 36, 33, -105, 7,233, 16,233, 28,233, 46,233, 37,153, 76,214, 34, 59,146,163,200, 2,242, 14,114, 51,249, 2,249, 17,249,141, 4, 69,194, - 72,194, 75,130, 45,177, 65,162, 70,162, 67, 98, 72,226,185, 36, 94, 82, 83,210, 73,114,181,100,174,100,133,228, 9,201,235,146, - 51, 82,120, 41, 45, 41, 23, 41,166,212,122,169, 26,169,147, 82, 35, 82,115,210, 20,105, 83,105,127,233, 84,233, 18,233, 35,210, - 87,164,167,100,176, 50, 90, 50,110, 50,108,153, 2,153,131, 50, 23,100,198, 41, 8, 69,157,226, 66, 97, 81, 54, 83, 26, 41, 23, - 41, 19, 84, 12, 85,155,234, 69, 77,162, 22, 83,191,163, 14, 80,103,101,101,100,151,201,134,201,102,203,214,200,158,150, 29,165, - 33, 52, 45,154, 23, 45,133, 86, 74, 59, 78, 27,166,189, 91,162,180,196,105, 9,103,201,246, 37,173, 75,134,150,204,203, 45,149, -115,148,227,200, 21,201,181,201,221,150,123, 39, 79,151,119,147, 79,150,223, 37,223, 41,255, 80, 1,165,160,167, 16,168,144,165, -176, 95,225,162,194,204, 82,234, 82,219,165,172,165, 69, 75,143, 47,189,167, 8, 43,234, 41, 6, 41,174, 85, 60,168,216,175, 56, -167,164,172,228,161,148,174, 84,165,116, 65,105, 70,153,166,236,168,156,164, 92,174,124, 70,121, 90,133,162, 98,175,194, 85, 41, - 87, 57,171,242,148, 46, 75,119,162,167,208, 43,233,189,244, 89, 85, 69, 85, 79, 85,161,106,189,234,128,234,130,154,182, 90,168, - 90,190, 90,155,218, 67,117,130, 58, 67, 61, 94,189, 92,189, 71,125, 86, 67, 69,195, 79, 35, 79,163, 69,227,158, 38, 94,147,161, -153,168,185, 87,179, 79,115, 94, 75, 91, 43, 92,107,171, 86,167,214,148,182,156,182,151,118,174,118,139,246, 3, 29,178,142,131, -206, 26,157, 6,157, 91,186, 24, 93,134,110,178,238, 62,221, 27,122,176,158,133, 94,162, 94,141,222,117,125, 88,223, 82,159,171, -191, 79,127,208, 0,109, 96,109,192, 51,104, 48, 24, 49, 36, 25, 58, 25,102, 26,182, 24,142, 25,209,140,124,141,242,141, 58,141, -158, 27,107, 24, 71, 25,239, 50,238, 51,254,104, 98, 97,146, 98,210,104,114,223, 84,198,212,219, 52,223,180,219,244,119, 51, 61, - 51,150, 89,141,217, 45,115,178,185,187,249, 6,243, 46,243, 23,203,244,151,113,150,237, 95,118,199,130, 98,225,103,177,213,162, -199,226,131,165,149, 37,223,178,213,114,218, 74,195, 42,214,170,214,106,132, 65,101, 4, 48, 74, 24,151,173,209,214,206,214, 27, -172, 79, 89,191,181,177,180, 17,216, 28,183,249,205,214,208, 54,217,246,136,237,212,114,237,229,156,229,141,203,199,237,212,236, -152,118,245,118,163,246,116,251, 88,251, 3,246,163, 14,170, 14, 76,135, 6,135,199,142,234,142,108,199, 38,199, 73, 39, 93,167, - 36,167,163, 78,207,157, 77,156,249,206,237,206,243, 46, 54, 46,235, 92,206,185, 34,174, 30,174, 69,174, 3,110, 50,110,161,110, -213,110,143,220,213,220, 19,220, 91,220,103, 61, 44, 60,214,122,156,243, 68,123,250,120,238,242, 28,241, 82,242, 98,121, 53,123, -205,122, 91,121,175,243,238,245, 33,249, 4,251, 84,251, 60,246,213,243,229,251,118,251,193,126,222,126,187,253, 30,172,208, 92, -193, 91,209,233, 15,252,189,252,119,251, 63, 12,208, 14, 88, 19,240, 99, 32, 38, 48, 32,176, 38,240, 73,144,105, 80, 94, 80, 95, - 48, 37, 56, 38,248, 72,240,235, 16,231,144,210,144,251,161, 58,161,194,208,158, 48,201,176,232,176,230,176,249,112,215,240,178, -240,209, 8,227,136,117, 17,215, 34, 21, 34,185,145, 93, 81,216,168,176,168,166,168,185,149,110, 43,247,172,156,136,182,136, 46, -140, 30, 94,165,189, 42,123,213,149,213, 10,171, 83, 86,159,142,145,140, 97,198,156,136, 69,199,134,199, 30,137,125,207,244,103, - 54, 48,231,226,188,226,106,227,102, 89, 46,172,189,172,103,108, 71,118, 57,123,154, 99,199, 41,227, 76,198,219,197,151,197, 79, - 37,216, 37,236, 78,152, 78,116, 72,172, 72,156,225,186,112,171,185, 47,146, 60,147,234,146,230,147,253,147, 15, 37,127, 74, 9, - 79,105, 75,197,165,198,166,158,228,201,240,146,121,189,105,202,105,217,105,131,233,250,233,133,233,163,107,108,214,236, 89, 51, -203,247,225, 55,101, 64, 25,171, 50,186, 4, 84,209,207, 84,191, 80, 71,184, 69, 56,150,105,159, 89,147,249, 38, 43, 44,235, 68, -182,116, 54, 47,187, 63, 71, 47,103,123,206,100,174,123,238,183,107, 81,107, 89,107,123,242, 84,243, 54,229,141,173,115, 90, 87, -191, 30, 90, 31,183,190,103,131,250,134,130, 13, 19, 27, 61, 54, 30,222, 68,216,148,188,233,167,124,147,252,178,252, 87,155,195, - 55,119, 23, 40, 21,108, 44, 24,223,226,177,165,165, 80,162,144, 95, 56,178,213,118,107,221, 54,212, 54,238,182,129,237,230,219, -171,182,127, 44, 98, 23, 93, 45, 54, 41,174, 40,126, 95,194, 42,185,250,141,233, 55,149,223,124,218, 17,191, 99,160,212,178,116, -255, 78,204, 78,222,206,225, 93, 14,187, 14,151, 73,151,229,150,141,239,246,219,221, 81, 78, 47, 47, 42,127,181, 39,102,207,149, -138,101, 21,117,123, 9,123,133,123, 71, 43,125, 43,187,170, 52,170,118, 86,189,175, 78,172,190, 93,227, 92,211, 86,171, 88,187, -189,118,126, 31,123,223,208,126,199,253,173,117, 74,117,197,117,239, 14,112, 15,220,169,247,168,239,104,208,106,168, 56,136, 57, -152,121,240, 73, 99, 88, 99,223,183,140,111,155,155, 20,154,138,155, 62, 28,226, 29, 26, 61, 28,116,184,183,217,170,185,249,136, -226,145,210, 22,184, 69,216, 50,125, 52,250,232,141,239, 92,191,235,106, 53,108,173,111,163,181, 21, 31, 3,199,132,199,158,126, - 31,251,253,240,113,159,227, 61, 39, 24, 39, 90,127,208,252,161,182,157,210, 94,212, 1,117,228,116,204,118, 38,118,142,118, 69, -118, 13,158,244, 62,217,211,109,219,221,254,163,209,143,135, 78,169,158,170, 57, 45,123,186,244, 12,225, 76,193,153, 79,103,115, -207,206,157, 75, 63, 55,115, 62,225,252,120, 79, 76,207,253, 11, 17, 23,110,245, 6,246, 14, 92,244,185,120,249,146,251,165, 11, -125, 78,125,103, 47,219, 93, 62,117,197,230,202,201,171,140,171,157,215, 44,175,117,244, 91,244,183,255,100,241, 83,251,128,229, - 64,199,117,171,235, 93, 55,172,111,116, 15, 46, 31, 60, 51,228, 48,116,254,166,235,205, 75,183,188,110, 93,187,189,226,246,224, -112,232,240,157,145,232,145,209, 59,236, 59, 83,119, 83,238,190,184,151,121,111,225,254,198, 7,232, 7, 69, 15,165, 30, 86, 60, - 82,124,212,240,179,238,207,109,163,150,163,167,199, 92,199,250, 31, 7, 63,190, 63,206, 26,127,246, 75,198, 47,239, 39, 10,158, -144,159, 84, 76,170, 76, 54, 79,153, 77,157,154,118,159,190,241,116,229,211,137,103,233,207, 22,102, 10,127,149,254,181,246,185, -206,243, 31,126,115,252,173,127, 54, 98,118,226, 5,255,197,167,223, 75, 94,202,191, 60,244,106,217,171,158,185,128,185, 71,175, - 83, 95, 47,204, 23,189,145,127,115,248, 45,227,109,223,187,240,119,147, 11, 89,239,177,239, 43, 63,232,126,232,254,232,243,241, -193,167,212, 79,159,254, 5, 3,152,243,252,186,196,232,211, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 13,213, 0, 0, 13,213, 1, - 61,214, 88,241, 0, 0, 0, 7,116, 73, 77, 69, 7,219, 2, 27, 16, 38, 47, 61,220,216,191, 0, 0, 0, 26,116, 69, 88,116, 83, -111,102,116,119, 97,114,101, 0, 80, 97,105,110,116, 46, 78, 69, 84, 32,118, 51, 46, 53, 46, 49, 48, 48,244,114,161, 0, 0,245, - 8, 73, 68, 65, 84,120, 94,236, 93, 7,152,213, 68, 23, 93, 64,164, 75, 7, 1,233,189,247,142, 52,233, 69, 81,233, 69, 16,169, -138, 32, 85, 64,113,233, 8,210, 59, 72, 21, 88, 64,164,174,128,130, 72,239, 75,149,222, 59, 75,175, 75,103,231, 63, 39,188,121, -127, 54,155,188, 36,187,111,129,133,228,251,230,203,123,201,204,205,204,157,118,230,222, 59,119,124,124,156,203,225,128,195, 1, -135, 3, 14, 7, 28, 14, 56, 28,112, 56,224,112,192,225,128,195, 1,135, 3, 14, 7, 28, 14, 56, 28,112, 56,224,112,192,225,192, - 27,205, 1,127,127,127, 97,163,128, 21,173,196, 37, 77, 87, 40,107, 33,254, 43,165,105, 33,127, 50,138,221,124, 90,225,171, 85, -154,101, 93,252,236,109, 33,191, 86,105,202, 58,138,136,124,122,179,222,101,217,189, 66, 83,182,119,220,173,210, 53,229,167,186, - 15, 89,236, 79,150,105,218,232, 75,175,156,166,133,182,201, 40, 97,201,167, 89, 27,181, 67,211,106, 95,178, 67,211,106, 95,178, - 67,211,235,237,211, 91,109, 94,219, 38, 45,210,245, 88,118,189,118,110,161, 47,217,162,105,177, 47,189, 22, 52, 45,244,165,176, -230,211, 83, 95,178,212, 62,213,115,187,170,238,173,204, 77, 22,138,245, 6, 70,145, 13,207, 70,209, 76, 43, 66, 77,203, 66, 71, -177, 52,240, 70, 20, 77,213,164,107, 54,144, 91,206,167,197, 50,219, 6,111,145,161,142, 80,246,117,204,167,188,155,228,217, 82, - 91,242,102, 29,169,219,187, 13,186,150, 6, 52, 87,185,149, 9,215, 66, 93, 89,166, 41,105, 89,160,251, 74,105, 70, 20, 63, 45, -240,210,180,111,234,213,187, 5,186,175,154,159, 86,251,146,229,124,122,171,142,180,109,210, 34, 93,219,253, 61,188,109,222,168, -239,152,208,181,149, 79,139,253,211, 22,205,136,226,103,120,219,188,222, 60,108,161,142, 44,124,246, 45,136, 98,147, 81,150, 26, -140,106,210, 41,107,129,133,182,104, 90,160,103, 58,240,170, 59,135, 13,176,105, 41,159, 22, 87, 77,182,129,150,122, 21,225, 13, - 0, 19, 17,117,100,113,101,107,183,236,114,101, 31,110, 0, 35,203,172,119,247,192, 83,211,122, 87,247, 33,139,253,201, 54, 77, -242, 54,188,245, 30,145,249, 84,181,123,179,122,178, 92,118, 27,125,233,149,210,180,209,151,236,228, 51, 34, 37, 90, 94,169, 35, -217, 38, 93,245,212, 59,188, 0, 70, 59,198, 89,232, 75,150,248,169,238, 59, 22,198,209, 48,209,244, 70,223,212,240,211,108,209, -102, 43,159, 22,251,146, 41, 77,109, 91,183, 72,215,226,180,253, 6, 71,179,208,152,213,165,183, 92, 17, 54, 88,102,137,166,197, -149,131,173, 73, 60,178,208,180,184,194,177, 93,118, 27,117,111,169,142, 34, 42,159,106, 96,228,141, 1, 45, 50, 1, 45,111,214, -145,150,150, 5,218,166,245, 30,217,104,218,104,163,182,202,110,129,151,150, 22,128,218,252, 89,160,107, 43,159, 22,251,146,169, -148, 76,221, 15, 45,242,212, 22,205,136,204,103,120,198, 16,163,250, 8, 15,200,140, 44, 52,245,234,196, 98,221,219,128, 3,111, -104, 84, 11, 29, 57, 76, 64, 75, 34, 93, 11,108, 51, 29, 40, 84, 40,154, 40,223,108,101,111,105, 64,211, 27, 40,194,211, 1,213, -160,205,194,170,201, 22, 40, 98,153,189, 77,211,226, 64,246,202,243,137,114, 43, 43,101,111,213,187,106, 96,176,202, 83,211,246, -169,238, 67, 22,251,147,101,154,170, 21,163, 87,164, 16, 54,251,146,229,124,218, 88,180, 88,166,105, 99,181,108,135,102,100,169, -119,175,231,211, 70, 95, 50, 5, 69,234,241,221,226,248,100,139,166,197,241,201, 22, 77,139,125, 41,172, 52, 61,205, 75,182,104, - 90,236, 75,182,104, 90,236, 75,150,250, 81, 24,234,222, 2, 12,112,162,216, 6, 90, 54, 89,102, 90,185, 54,233,217, 6, 90, 22, -233, 59,249,180,200, 40,139,209, 28,126, 90,100,148,197,104, 14, 63, 45, 50,202, 98, 52,135,159, 22, 25,101, 49,154,195, 79,139, -140,178, 24, 45,178,240,211, 98,113,156,104, 14,208,122,193,129,200,210,176,157,124,122,183,207, 58,252,116,248,233, 45, 14, 56, -109,201, 91,156,116,198,228,200,210,150,188, 91,227, 14, 53,135, 3, 14, 7, 28, 14, 56, 28,112, 56,224,112,192,225,128,195,129, -183,148, 3,169, 82,165,242,207,146, 37,203, 17,163,144, 50,101,202,127,223, 82,214,188, 54,197,118,234,232,181,169, 10, 39, 35, -230, 28,136,138, 40,239,184, 2,127, 71, 49, 79,226,196,112, 56,224,112,192,225,192, 27,204,129,140, 25, 51, 30,122,246,236,153, -120,242,228,137,120,248,240,161,184,119,239,158,184,125,251,182,184,126,253,186,184,120,241,162,200,148, 41,211, 9,187,197,127, -255,253,247,215, 3, 28,156,179, 19,144,102,163,201,119, 54,227,125, 96,148, 40, 81,220, 33,106,212,168,129, 12,209,162, 69, 83, -194, 59,239,188,163,132,232,209,163,203,176,203,140,166, 30, 61, 61,154, 42,186, 30,105, 38, 72,144, 96,103,146, 36, 73, 2,147, - 38, 77,234, 14,201,146, 37, 11,148, 33,121,242,228,129, 50,160,204,129, 12,120,199,178, 25, 94, 17, 81, 71,118,235,244, 77,138, -207,246,249,193, 7, 31,156,179, 19, 82,164, 72,225,177,125, 98, 65,178, 27,244,174,216, 8,215,145,102,147, 9, 16, 81,218,188, -167,160,109,191,232, 7, 59,205,218,188, 17, 61, 73, 75,246, 43, 85, 63, 48,163, 41, 63, 25, 21,253,100, 8,250,253, 61,244,131, -171, 8, 87, 18, 39, 78, 28,200,160,238, 19, 9, 19, 38,220,255, 38,181, 39,167, 44, 14, 7, 28, 14, 56, 28,240,200,129,244,233, -211, 31,185,127,255,190,216,181,107,151, 8, 8, 8, 8, 21, 0,180,142,218,101, 33,193,195,229,195, 7, 69,208,205, 27,226, 78, -224,101,241,252,249,115, 65, 48,199,112, 97,223, 30,113, 38, 96,187, 56,177,121,131,120,250,244,169, 18, 30, 63,126, 76, 64,119, -209,228, 59,231, 6, 15, 30, 44, 38, 76,152, 32,134, 15, 31, 46, 6, 12, 24, 32,122,245,234, 37,186,116,233, 34,190,253,246, 91, -209,170, 85, 43,209,172, 89, 51,209,176, 97, 67, 81,183,110, 93,241,241,199, 31,139, 88,177, 98,153,210, 28, 56,112,160, 24, 55, -110,156, 24, 58,116,168,232,223,191,191,248,241,199, 31, 67,208,108,218,180,169,104,208,160,129,168, 93,187,182,168, 94,189,186, -136, 25, 51,166, 71,154,156, 80, 88, 30, 94,193,193,193, 74,153, 89, 70, 2, 89, 62,127,244,232, 81,168,192, 9,223, 83,217, 35, -162,142,236,214,233,155, 20,159,237,115,230,134,189, 98,105,192, 17,177,112,199, 33,165,110,100, 56, 60,126,182, 56, 52,122,166, - 56, 48,124,106,136,231,102,237, 19, 64,236,166, 29,154,151, 46, 93, 10,138, 31, 63,254,124,240,149, 82, 31,163,235,220,131, 7, - 15, 4, 67, 80, 80,144, 59,200,103,108, 75,204, 55,219, 24,219,218,138, 21, 43, 4, 23, 28,102,253,168, 99,199,142,162, 93,187, -118,162,101,203,150,162, 73,147, 38,162,126,253,250, 74,251,174, 85,171,150,168, 81,163,134,168, 90,181,170,168, 84,169,146,248, -232,163,143, 68,169, 82,165, 4, 23, 25, 22,234,159,229,248,165, 90,181,106, 55,152,151,133, 11, 23,138,221,187,119,139, 3, 7, - 14,136,195,135, 15,139, 99,199,142,137, 19, 39, 78,136, 51,103,206, 8,240,255,138, 5,122, 78, 20,135, 3, 14, 7, 28, 14,188, - 25, 28,192, 4,177, 2,106,195,195, 12,105,210,164,185,135,251, 99,117,200,156, 57,243,125, 61,181,162, 39,149, 34, 39, 50,130, -172,246,113,125,148, 64,233, 24,195,141, 27,255,127,198,231,148,156, 49,112,178,192,119, 46,153, 77, 16, 4, 68, 39, 79,158, 20, - 23, 46, 92, 16,200,183, 64,126, 5,164, 61, 34, 91,182,108, 34,119,238,220,162, 64,129, 2,162,104,209,162,226,195, 15, 63, 20, -229,203,151, 55, 5, 90, 88,193,159, 27, 51,102,140,128, 68, 73, 9, 40,147,200,146, 49,131, 24,243, 69, 61, 49,229,139,186,162, - 72,254,124, 34,111,222,188,162, 96,193,130, 10,221,146, 37, 75,154, 2, 45, 74,178, 8,178,246,237,219, 39, 14, 30, 60, 40,142, - 28, 57,162, 76, 48,167, 79,159, 22,231,206,157, 19,152, 96, 21,176, 72,126,200,178, 3,104,157,247, 84,118,117, 29,165, 77,155, -246, 14,234,227, 26,194, 69, 87,184, 6,222,221,181, 91, 71,111, 70,235, 13, 91, 41,216, 62, 9,178, 18,124, 53, 80, 9,119,239, -222, 85, 2,165,185,211,125, 50,184, 3, 23, 32, 4, 56,108,159,228,181, 73, 29,221,180, 74,243,236,217,179, 65, 37, 74,148,248, - 43,117,234,212, 95,154, 1, 45,126,159, 64,229,248,241,227, 10, 72,161,148,249,234,213,171,226,214,173, 91,130,249, 35,120, 39, -176,225, 66,161,117,235,214,150,128, 86,155, 54,109, 24,143,110, 33, 8,162,216, 79,196,123,239,189, 39, 18, 37, 74, 36, 32,109, - 21,144, 72,137,116,233,210,177, 79,138,236,217,179, 91, 1, 90, 4, 89, 3, 43, 87,174, 28,200,188,240, 42, 87,174,156,192,127, - 49,122,244,104,225,231,231, 39,184, 96, 33,176, 99, 57, 28,160, 21,182,118,235,164,114, 56,240, 54,112, 0,195, 71,116,132, 34, - 8, 53, 16,170, 34,148,116,253,230,127, 6,190,147,239,149,255,122,124, 81,197, 81,222,171,254, 87,148,116, 52,207,139,225,121, -121,215,187, 10,184,199,210,124, 71,166,115,231, 67,183, 62,204,252,154, 80, 69, 37, 7, 74, 14,150, 92, 41,115,213,204, 1,253, -206,157, 59, 10, 80,186,114,229,138,192, 68,193,137,231,184, 81,165,115, 34,163, 36, 75, 13,180,152,246,230,205,155,238,103, 18, -104,145,174,107, 34,243, 8,180, 8,138, 70,140, 24, 33, 10, 21, 42,164, 4, 35,144,197, 21, 56, 65, 22, 7,249,216,177, 99,123, -156, 28, 73,147, 19, 20, 1, 86,249, 98,249,196,218,222,205,197, 3,223, 38,226,106,167, 47,196,165,230,159,137,235,165,115,138, - 13,109,191, 16,141,170, 85, 81, 64, 86,153, 50,101, 76,193, 27,129, 22, 37,120, 70, 32,139,252,203,147, 39,143, 2,178, 56,177, - 83,218,101, 6,180,212,124,206,144, 33,195,159,168,163,109,168,158,117, 12,168,163,109,168,163,195,168,163,107,118,234,232,109, -232,176,158,218, 39, 37, 89,106,160,197,186,208, 2, 45,130, 28, 74,143,216, 62,179,102,205,106, 10,180,172,208, 36,200, 66,253, -255, 83,164, 72,145, 6,133, 11, 23, 46,109, 6,180,216,247,164, 36, 72, 15,100,177,159,178, 13,179, 63, 80,162,107, 65,250,116, -206, 21, 79, 76,154, 52, 41, 84, 64, 91, 20,144,160, 42, 32, 43, 71,142, 28,202, 66,131,170,120, 15,237,133, 54, 88,239, 0,156, -221, 86,143, 29,148, 42, 55,106,212, 72,172, 91,183, 78,145,108,181,109,219, 86,145, 58, 19, 44, 98,225,224, 72,180,222,230, 14, -232,148,253,173,231,128, 39, 44,130, 33,173, 66,247,238,221,123, 16, 27, 97, 65,234, 71,224,195,223, 50, 72,208,165,249, 31, 2, -108,185,192,154,146,206,149,158, 63,212,255,149,231, 8, 10,120,146,241,228,119,121,199,243,106,242,191,138, 78,136,124, 24, 1, - 45,197,185,161,145,243, 68,170,168, 56,177, 24,169, 17,213,170, 69, 12,196,134,182, 91, 4, 90, 4, 27, 82,146, 37, 1, 23,239, - 92,137, 19,100, 16, 20,244,207,156, 76,140,204,159, 65, 28,241, 95, 72,224,230, 17,104,193, 94,228,220,207, 63,255, 44, 32, 5, -240, 8,178,228, 74,154, 42, 16, 51,160, 69,154, 84, 65,102,206,148, 81, 60,159,255,133, 56, 61,174,173,232,214,232, 19,247, 4, -211,189, 97, 3,177,161, 67, 59,113,248,235,150,162, 74,133, 10,138, 42,197, 76, 29, 73,160, 69,128,122,244,232, 81,183, 36,235, -252,249,243,138, 36,139, 32,139,128, 51, 95,190,124, 10,120,165, 77, 28,227,218, 1, 90,144, 52,140, 7, 0,152,129,201,107, 60, -234,131, 97,198,206,157, 59,151,225,190, 29,225,162,213, 58,122,155,123, 58,219, 39,193,147,148,100,173,242, 41, 34,100,144, 82, - 44,130,172, 54, 67,125,149,240,251,218,149,150, 36, 90,102, 52, 9,178,210,100,206,176, 28,160,164, 14, 58,112, 65,128,173, 15, -173, 0, 45, 46,108,180, 32,139,223, 82,131, 44, 0,112, 69,197,109, 5,104, 49, 30,165, 88,122, 64,139,116,208, 23, 69,206,156, - 57,149,118,202, 69,141, 21,160, 5, 53,232,149, 69,139, 22, 41,146,172, 58,117,234,136, 41, 83,166, 40,170,204,175,191,254, 90, - 1, 89, 92,120, 80,170, 75,105, 28, 22, 54, 14,208,122,155, 59,160, 83,246,183,158, 3,158, 60,199,171,129,143, 26, 84,201,223, -218,247,106, 48, 37, 25,171, 6,107, 70, 64, 75, 11,158,244,128,152,140, 99,144, 15, 93, 73,154, 2,176, 60,121,102, 87,171,168, -164, 58,209,232,110,166, 58, 36,128, 48, 82, 23, 18,100, 49,140, 42,144, 81, 76, 45,151, 79, 28,251,211, 26,208,234,215,175,159, -178,218,166,186,144, 42,196,203,151, 47,187,213,133,148,100,113,144,167,109, 9, 65,214,167,159,126, 42,226,196,137,227, 81, 10, - 65,160,229,235,235, 43,114,229,200, 38,196,191,221, 68,233, 98,133,220, 32, 75,170, 11, 43, 66, 58,182,226,199,129,162, 54,108, -190,172, 72,201,104,244,206, 73, 80,170, 11, 37,200,226, 4,195,252, 21, 47, 94, 92,228,207,159, 95, 1, 89,140, 71, 41, 0,128, -214, 5,163,158, 7,155,175,157,210,104,222,117,191,131, 59,195,109, 87,184,131,111, 94,128,196,101, 20,194, 31,168,175,237,178, -206,156, 29,163,250, 92, 85, 3, 45, 74,177,212, 64, 75,218, 66,113,193, 33,129,214,188, 53,203,109, 1, 45, 61,154, 82,146, 69, -144,133, 78,251, 1, 66,102,171, 64,139, 32, 93,170, 11,165, 42,147, 32,107,216,176, 97,238, 69, 7,234, 94,124,246,217,103,150, -128, 22,129, 80,188,120,241,220, 64,171,115,231,206, 66, 6,210,201,149, 43,151, 2,178, 32,113,227,138, 82,196,136, 17,195,204, - 70, 43, 42,128,214,101,170,203,217,255,104, 39,185,124,249,114,177,117,235, 86, 65, 53, 37, 37, 89,167, 78,157, 82, 22, 26, 92, -100, 57, 64,235,173,159,103, 29, 6,188,229, 28,240,132, 69, 48,180,149,215, 72,150,220, 18, 45, 61,192,163, 5, 90,136,163,168, - 21, 85, 32, 73,170, 14, 67, 73,180,212, 96, 75, 79,114,166,150,116,169,223, 75,240, 22, 38,137,150,183,234,158, 19, 25,129,150, -158,186, 80,130, 44, 74, 19,166,125, 84, 64,204,251,164,180, 56,185,114,177,169,106, 6, 54, 37,231,104,252,206,213, 54,109,178, - 56,160,195,240, 86,177,157, 82,131, 44, 26,172, 19,100,113, 50, 49, 3, 90,164,217,163, 71, 15,168,242,114,138,139,135, 39,138, -146, 37,138,133,178,201,170, 92,169,178, 24, 63,110,177,168,247,121,109, 5,192,153, 73,201, 8,180,104, 55, 67, 21,137, 4, 89, -156, 0,201, 11, 74,196, 56,113,209,150,140, 42, 67,130, 70, 94,158,128, 22,121, 73,245, 45,105,202, 32, 13,234, 9,214, 40,129, - 97, 28,111,213,221,219, 64, 71, 2, 45,169, 46,212, 2, 45,105,108, 46,129,214,156, 85,254,166,237,147,198,240, 4,206,122, 52, - 9,178,208, 78,151, 67,189, 87, 7, 96, 61, 47,170, 60, 13, 66, 86, 43, 64,139,192,138, 32,139, 0,197, 19,200, 34, 56,170, 89, -179,166,153,244,201,135,234,114, 26,189, 99, 39, 96, 8,160,165, 52, 68,205,197,182, 74,117,185, 5,160, 21, 5, 59, 9, 47,209, -150,140,106,204,213,171, 87, 43,146, 44,130,172,255,254,251, 79, 89, 20,181,111,223, 94,121, 70,254, 0,108, 58, 18,173,183,161, -163, 57,101,116, 56, 96,192, 1, 19,137, 86, 9, 45,160,242, 36, 89,210,188,115,131, 44,151,250,175,130, 74,202,165,167, 58, 84, -236,173,244, 0,151, 5, 9,151,177, 68,203,147,234,208, 91,173,130, 19,217,249,189,187,221,246, 88,106,117,225,207,217, 83,138, -177, 69,178,136, 25, 21, 10, 42, 32,129,193,138, 13, 12, 65, 17, 24,167,168, 52,212,134,239, 90,144,197, 73,132, 32,139,171,234, -184,113,227,122,148,104,145, 38, 87,242,249, 10,231, 21, 35,239, 15, 20, 37,202,125, 24,194,240,157,147, 76,181,106, 53, 68,247, -249,251, 68,131,250, 13,149, 93, 89,102,224,141, 64,139, 64, 72, 45,201,226,142, 46, 78,130, 21,160,126,100,126,169,142, 97, 57, -168,166,113, 1, 45,195,124,146,151, 4, 88,218,141, 5,242, 63,193,150, 3,180,236,181, 92,242,235,236,230,241, 98,101, 71, 31, - 37,168,213,133, 61, 51, 23, 21, 50,144,183,172, 75,130, 98, 43, 54, 90,122, 52, 9,178,222,143,243,222, 63, 4, 89, 46, 73, 86, -154,122,245,234,229, 29, 52,104,144, 37,213, 33, 65,159, 30,200,194,166, 8, 69,178,171,150, 64, 85,169, 82,197, 18,208, 98, 91, - 4, 15, 76,129, 86,217,178,101,149, 54,139,157,182,166, 64, 30,134,244,151,168, 46,255,245,215, 95,197,182,109,219,220, 54, 89, -148,236, 6, 6, 6, 42, 32,139,146, 45,242,211, 1, 90,246,218,171, 19,219,225,192,155,198, 1, 43,170, 67,130, 31, 23, 88,178, - 98,163,165,150, 96,169,127, 71,247, 4,180,248,206, 19,160, 10,147,141,150,182,178, 92,170, 66, 67,103,165,218,157,108, 86, 85, - 81,156,200,206,236,220,230, 6, 7,210, 38,139, 82,172,113, 69,179,138,233, 0, 89,191,127, 86,214, 61,193, 89,153,200, 36, 40, -162,113,174,220, 93, 72,208,194,213, 50, 87,252,148,100,169, 65, 22,119, 57, 89, 1, 90,116, 13, 81,160,100,126, 81,245,217, 71, -226,195, 42,229,220,187, 11, 9,178, 40,129,170,249,201,167,162,233,138,107,162, 81,147,166,202, 22,120, 51,160, 69, 31, 89,156, - 88,168,214,108,209,162,133, 34,201, 34,240,163,187, 9, 74,225, 74,151, 46,173,168,100, 40,129, 8, 47,208,250, 46, 94, 20,197, - 88,155, 42, 68,216,204,117, 65,125,141, 69, 88,142,122, 90,243,166,117, 76,111,150, 71,105,159, 27, 70,185,129,150, 90, 93,168, - 6, 90, 82,114,104,165,125, 82,162,165,165,105, 32,201, 74,215,188,121,243,188,163, 70,141,178, 4,180,152, 7,173, 36, 75,130, - 44, 74,118,217,142,168,138,102,155,226, 38, 16, 51,233, 19,213,229, 4,100, 52,158,151, 59, 11,105,244,174,119, 85,172, 88, 81, -145, 26, 91, 5, 90,220, 81, 72, 3,120, 74,178,168, 70,228,127, 41,201, 98, 63, 32,112,229,229, 0, 45,111,182,102,135,150,195, -129, 55,139, 3, 82,245,231,146,106, 81, 66, 85, 84, 74,184, 84,207,220,187, 14,117, 36, 90,242,157,214, 64, 94, 62, 55,218,117, - 40,159,203, 59,119, 33,170,191,109,109,215,161,182, 58,104,252,206,129,143,134,235,148, 42,201, 65, 93, 58, 45,229, 46,193,107, -215,174, 41,182, 21,116, 77, 96,213,121, 41, 39, 50,250,201,162,212,165, 83,130,104,138, 61,150, 52, 60,158, 81,177,144, 88, 80, -187,188, 88,254,229, 39,202, 4, 66,160,224,154,200, 60, 26,195,195, 32,247, 92,135, 14, 29, 20,105,144, 90, 93,216,184,113, 99, -101,183, 21,237, 88, 24, 40,201, 34,200, 34,200,129, 29,138, 71,137, 22,105,210, 80,183, 64,177, 2, 34,215,211,180,226,139,195, - 93, 68,189, 31, 58, 40,234, 18,130,172,134, 63, 14, 19,245,253,207,137,218,235, 30,137,250, 13, 27, 41,254,134,204,192, 27,129, - 22, 13,127,137,216,185,221,158,121,129, 4, 67, 1,129,156,224, 72, 27, 42, 35,101,130,164, 68,226,239,191,255,166,234,208,176, -236, 82,162,165,221, 88, 32,213,178,228, 31, 0,219, 93,240,114, 60,234,237,111,212,213, 41,171,245,244,102,117, 79,235,165, 33, - 79, 79,175, 27, 22, 2,104, 73,117,161, 22,104, 81,154,104,165,125, 18,104,169,105, 74,155, 44,151, 36, 43, 53,186, 89, 90,180, -213,188,104, 19, 84, 29,102, 66,200,137,157,172, 30,141,225,169,230,147,254,189,216, 79,105,147,101, 4,178,168,230, 35,136,183, - 2,180,104,107, 40,141,222,229,206, 66, 61,160,197,197,203, 39,159,124, 66,195,121, 83,137, 22, 84,145,151,184,232, 97,127,148, -110, 28,216, 31,165, 36,139,252,149,151, 3,180,172,183, 85, 39,166,195, 1,135, 3,198, 28, 80,129, 50,125, 53,222,235,192, 60, - 76,244, 71,184,202,212,115, 84, 26, 30,231,165,210, 6, 70, 74,178,126,201,149, 90, 76, 40,153, 67,252, 86,185, 72, 8, 53,205, -214, 31,218,138, 61,131,186,137,171,155,215, 80, 5,226, 17,104,189,251,238,187,231, 56,104,211,152, 92, 79, 93,200,119,116,194, - 72,149, 29, 47,238,210,130,111, 32, 83,160,245,213, 87, 95, 41,210,128, 74, 13,170,138,182,127,247, 23,223, 30,221, 40,218,174, -191, 41,106,174,186, 43,210, 46,125, 46,190,248,125,159,104,218,174,179, 2,178, 56,137, 88, 1, 90, 92,205, 83, 37,201, 60, 65, -122,161,236, 6, 35,208,226, 4,199,188, 83, 34, 71,149, 15,119, 80, 82, 10,129,137,199, 35,208, 34, 0, 86, 3,173,239,222,139, -170,184,202, 96, 32, 88, 5, 96, 14,194, 78,209, 63, 80,103,188,110,134,197,201,236,235,208, 30, 95, 86, 30, 36,120,149,146, 44, -191, 31,235, 11, 25,164,186,144, 60, 31, 56, 37,167, 18, 22,175,233,100,218, 62, 9,180, 8,202, 72,147, 32, 43, 71,198, 15, 86, -160, 94,234,192,174,143,192, 42, 45, 66,122,130,172,239,190,251, 46, 31,126,103, 65,200,101, 5,104,209,214, 81, 13,178, 80,183, -138,141,162, 90,146, 37, 65, 22, 23, 7,102,210, 39, 74,134, 25,143, 52,212, 59, 11,245,128,150,148, 16, 91, 5, 90,220, 85,184, -118,237, 90,101,199, 45, 37,197, 92,196,112,161, 70,158,112,145,196,254, 64,208,234, 0,173,151,213,210,157,239, 56, 28,112, 56, -240,202, 57, 0, 21,211, 74,163, 51, 14, 1, 2,232,168, 84,215,121,169,142, 10, 49,196,137,225, 18,104, 73, 73,214,164,146, 57, -197,111, 85,138,138,133,117, 42,184,165, 88, 92,225,238, 29,220, 93, 28, 25, 63, 64, 92,223,185, 65,111, 34, 11, 65,147, 64,139, - 18, 34,174,218,229,238, 66, 61,117, 97,183,110,221,220, 94,227,117,128, 86, 40,154,148, 56, 21, 43, 86,204,237, 39,171, 82,149, -170,226,155, 17,191,137,214, 99,255, 16,159,215,123,225, 17, 94,130, 44, 74,206,116,128, 86,168,178,115,146,102,217, 57,193, 72, - 27, 31,189,137, 76,181,194,215, 2, 45, 55, 77,105, 12, 47,109,178,164, 36,235,199,148,241, 68,223,244,137,149,111, 96,146,127, -128,186,250, 29, 97, 3,235, 19,245,243,183, 78,227,138, 44,167,186, 71,120, 62,213, 64,139,237, 80, 13,180,212, 27, 15, 36,208, - 90,248, 79, 7, 2, 19,195, 58, 34,175, 37,208,146,146, 44,130, 44,212,175,158, 36, 43, 75,223,190,125,243,255,246,219,111,133, -116,128, 86,136,178, 83,205,199, 54,194,147, 16, 40,201,146, 32,139, 54,138, 84, 23, 82, 50,170, 6, 89, 4,242, 58, 64, 43, 4, - 77, 2, 45,218, 94, 73, 26,114,103,161,148,226, 82,234, 42,119,237, 74, 91, 71,108, 0,209, 74,180, 66,213, 17,118,199, 94,162, -212,155,198,239,116, 40, 44,253,102,209,254,141,151,148,108, 81, 66,103, 0,180, 34,188,222,189, 52,224, 58,249,244, 18, 35, 93, -100, 28,126,190,157,252,244,110,169, 35, 43, 53, 74, 69, 56, 64,114, 69, 45, 87,234, 84,255, 81,141,168,163,154,210, 5, 27,242, -200,153, 19,127,251,139,147,171,253,197,233,213,127, 42,170, 66, 25, 46,111,254, 71, 92,221,182, 14, 97, 45,237, 69,180,210,167, - 16, 52,161, 18, 57,199,227, 66, 40, 1,162,173,147, 30,200,162,186,144, 3, 60,237, 66, 40, 81,194, 89,107, 30,105, 18,188,209, -177, 34,165, 76,114,162,225,100, 37,105,107, 65,150,129, 58, 82,183,236,156, 80,184,122,167, 90,214,236, 2, 48,186,172,105, 39, - 33,128, 22,165, 44, 4, 90, 82,146,197,205, 5, 4, 89, 3,179,190,111,103,215,161, 51,160,185,152, 44,193,171,180,193,218,189, -114,150, 8, 88, 62, 67,236, 92, 54, 85,177, 35,146, 97,201,191, 93,196,162, 53, 29,197,188,191, 90,153,182, 79, 0,173, 91, 0, - 24,202,238, 66, 56, 36,253, 28,199,220,228, 68,189, 39, 69, 72,130, 54,153, 21,109, 50, 51,126, 39, 68, 72, 0,169, 86, 58, 24, -134,167,129,100, 83,171, 58, 12, 5,180,168,130,166,212,149,109,159,109,149, 82, 38,182, 79,182, 83,246, 5, 45, 64,210,145, 62, -133,160, 73,117, 57,219,187, 4,106,210, 17, 47,141,222,121,244, 14, 13,229,185, 75, 86, 58, 28,229, 66,196, 42,208,162, 20,153, - 18,101,218, 76,114, 65, 64, 19, 4,121,201, 99,168,248,223, 1, 90,161,102, 5,167,111,122,119,162,116,248,249,250,243,211,187, - 57,140,172,212, 8,166,140,212,138, 58,170,169, 16, 13, 91,199,247, 83,160,198, 23, 84,168,255,112,244,169, 61,172, 89, 59, 65, -108,166,253, 9, 3, 87,237, 12,156, 84, 24, 56, 17, 48,192, 80, 93, 9,144, 58, 41, 1,191, 45,211, 84,211, 85,211,214,210,199, -119, 60,210, 68, 57,118, 98,210, 13,148, 1, 32, 42,208, 44, 48,141, 39,160, 37,109,217,180,231,222, 81, 90,192,201,204,226,174, - 67,103,240,113, 49,153,252, 54,107,143,218,247,102,237, 19,182,121,219,209,230, 22, 66, 18,220, 28, 82,162, 50, 86, 2,128, 86, - 49,100,137,158,213,229,165,149, 62,109,246,112, 96,186,210, 23,180,253, 1,109,215,176, 45,241, 35,112,104,186, 89, 30,186, 46, -211,235,245, 41,117,187,199,111,143, 52, 73, 23, 54, 90, 91,104,159, 40,249,198,246,111,212,238,193, 75,189, 67,165,157,246,233, -221,201,194,225,167,195, 79,111,113, 32, 34,218,146,183,242, 22,185,233, 80, 61,104,164, 86,212, 81, 77, 69, 68, 69, 56, 52,209, -132,172,128, 86,198,177,208,218, 28,126, 90, 96,146,141, 40, 14, 63,109, 48,203, 66, 84,135,159, 22,152,100, 35,138,195, 79, 27, -204,178, 16,213,225,167, 5, 38, 57, 81, 34,150, 3, 78, 35,244, 46,127, 29,126, 58,252,244, 22, 7,156,182,228, 45, 78,190,160, -227,240,211,225,167,183, 56,240, 54,183, 37,111,241,240,173,162,243, 54, 55, 24,167,236,222,109,234, 14, 63, 29,126,122,139, 3, - 78, 91,242, 22, 39, 29,144,233,180, 37,239,182,165, 55,150, 26, 27,138, 94,176, 83, 96, 35, 26,158,158,155,209,119,104,234,215, - 75, 88,235,203,225,167,195, 79,171,109,192,233,155,198, 28,176,202, 67,117, 60,135,159, 14, 63,245, 56,240, 54,183, 37,201,143, -176,206,103,102,125,234,173,122,239,160,125,239, 86,183,195, 79,135,159,222,226,128,211,150,188,197, 73, 71,170,227,180, 37,167, - 45,121,151, 3, 14, 53, 91, 28,112, 58,160, 45,118,153, 70,118,248,105,202, 34, 91, 17, 28,126,218, 98,151,105,100,135,159,166, - 44,178, 21,193,225,167, 45,118,153, 70,118,248,105,202, 34, 91, 17, 34,130,159,182, 50,224, 68,118, 86,121,102,141, 48, 90, 24, - 26,137, 33, 77,184, 33, 74,132,144,194, 32, 36,242,240, 45, 79, 52,163,128, 94, 12,132,120, 46,250,252, 6,127,243,153,218,253, -128,150,188,155,166, 16,189,163, 94,184, 48, 58,239,249,179, 19, 90,158, 59, 55,241,235, 51,103, 38, 22, 23, 98, 69, 12,153, 32, -238,251, 57,114,166,200, 84,232,187,132,105,114,143, 78,145,177, 80,235,152,201,179,166, 55,200,171, 25, 63,195,192, 78,199,128, - 57, 44, 76, 11, 75, 91, 10,199,119,156,122, 15, 7,243,116,146,154,241,243, 99,164,217,131,176, 23,161,158,197, 79,155,209,180, - 72, 38, 68, 52,135,102, 88,184,102,156, 38,178,240,211,187,165,126,221,169,225, 60,192,157,241,227,199, 15,132,115, 79,119, 72, -148, 40, 81, 32, 3,124,227, 40, 1,238, 3,220, 1, 62,112,248,206,212,175,142,170,220,239,224,119, 67,124,103, 10,210, 29, 97, -224,111, 62, 67,224, 59,163,203,172,193,196, 71,194, 86, 8,235, 93,129,191,249,204,211,229,137,102, 94,240,224, 56,202,119, 12, - 4, 18, 51,160,220,199,192,155,227,248,157, 55, 12,249,140, 10,127, 69, 35,225,201,158,131,217,183, 54,219,129, 39, 80,148, 18, -103,224, 61,214, 11, 0, 69, 41,237,230, 19,105,222, 69, 72, 54,122,244,232, 28,240,253,212, 24,126,144,134, 48,240, 55,159,241, - 29,227, 24,208,117,231,147, 32,107,215,206, 14, 19,151,255, 89,225, 22,195,238,221,157, 38,158, 63, 63,185,140, 16, 1,209, 99, - 39,201,154,178,192,135,213,199, 28, 61,118,106,210,147,103,207, 38,173, 92,191,125, 98,166,124, 31,141, 53, 0, 91,102,245,110, -147,149, 74,116,135, 38,152,128,147, 18,118,202,126,110,212,199,217,191, 25,146, 37, 75,230, 14, 24, 3, 12,251, 59,105,154,141, - 23, 90,122,244,183,133,103,155, 53, 21,233,174, 35,244,185, 45, 70, 99,143, 30, 45,233,191, 75,199,205,137,154,166,146, 79, 45, - 93, 89, 94, 53, 93,210,147, 52,193, 7, 79,249,220, 25, 17,249, 12, 11, 77, 79,249,116,241, 57, 42,238, 99, 92, 60,202,138,223, -219,120,122, 5,125,241,193,143,218, 62,252, 47,128,182,177,155,113, 16, 24, 87,239,114,250, 81, 88, 70, 31,227, 52,111, 51, 63, -189,203,201,215,157, 26, 65,150,218,131,115,112,112,176,226,209,156, 94,179,233, 32, 83, 58,197,100,167,228,217,133, 60,115,143, -131,176,209, 32,169,121,158, 7,244,143,254,252,243,207,143, 78,157, 58,165, 28, 92,205,192, 51,209,126,249,229,151, 71,124,135, -248,121,108,116,106, 14, 0,149, 16,252,224,236,241,241,159,127,254,169,120,241,102, 30,231,207,159,207,243,223, 30,243,157, 43, -142,222, 96, 97,212,176, 63,132,131,197,243, 39, 78,156,120,190,106,213,170, 39, 24,112, 86, 51, 32,159,207,241, 44, 24,131,240, -121,208,164, 23,111, 59,131, 79, 29,120,167, 15,100, 89,113,228, 9,193,150,188, 40, 33,242, 36, 37, 98,188, 80,249, 84, 73,178, - 8,166,132, 94, 32,208,114, 73,186,244, 36, 91,122, 52,227,226, 32,224, 52, 0, 86, 63, 19,184,105,105,242, 25,223, 49, 14,232, -198,213, 41,188,155, 38, 37, 89, 4, 88,247,111, 30, 22, 12,211,166,151,187,211,250,219,198,126, 41, 51, 21,252, 53, 97,234,220, - 99, 14, 30, 62, 54, 9, 52, 38,253,187,227,232, 36,223,241, 43, 38,125,246,237,200,137, 73,210, 21,104,237,137,166, 23,251,206, -219, 60,160,185,203,158, 48, 97,194,203,242, 72, 28,189,131,228,121,242,131,236,231,242,156, 82,222, 9, 58,140,250, 59,193,139, - 60, 48, 90,142, 29,242, 68, 8, 62,151,231, 73,242,187, 50,112,188,129,119,248,115, 70, 52,145,207, 75, 50,159,164,201,211, 41, - 56,110, 72,186,106,239,253,234,179, 41,113,186,132,229,124, 90,161, 73,218,112, 64,123,209, 40,159, 4, 68,140,195, 75,230,147, - 99,167,204, 39,199, 80,117, 94,229,127,140, 53,134, 39, 65,232,209, 52, 43, 59,191,225,137,159,174,252,143, 57,114,228,136, 50, -166,227, 16,251,235, 56,245,226, 41,219, 0,199, 80,140,165,193, 56,214,236, 9,207,165,252,242,203, 47, 57,182, 16,108,217, 25, -235,194,211, 85,157,190, 25, 30,238,133, 78, 27, 89,248,233,221, 82,191,238,212,184,194,229, 64, 49,119,238, 92,241,199, 31,127, -136, 37, 75,150,136,229,203,151, 11, 0, 14,241,239,191,255,138,141, 27, 55,138,109,219,182, 41, 7, 79,243,176,100, 14,188, 22, -129, 86,225, 12, 25, 50, 4,241, 88, 14,245, 37,207, 1,100,135,231,225,179, 24, 28,131,192,163,194, 22, 38,220,207,241,221,203, - 99,198,140, 81, 14,170,213,187, 56,112, 28, 60,120, 80,240,188, 67, 72,205,120, 54,221,231, 70,131,164,124, 14, 79,239,181, 50, -103,206, 28,136,203, 77,114,224,192,129,103, 23, 46, 92,120,141,131, 49,207,111,219,180,105,147, 72,147, 38, 77, 32,142,236,169, -101, 33,159,140, 18, 3, 43,199, 61,199,143, 31,127,190,119,239,222,167,240, 24, 62,207,149, 14,139,199, 24, 67, 48,168,173,195, -255, 22, 30,218,134, 30, 40,114, 75,178,144,209,219, 8, 65,154,112, 91, 74,185, 12, 36, 91, 33,104, 82, 45,184,123,247,238,180, -240, 36, 30, 64,128,133, 99, 98,206,224,104,159,171,152, 48, 30, 35, 60,193,239, 64, 28, 21,115,150,239, 24,135,113,153,198,136, -159, 84, 23, 74,160,117,104,255,122,241, 69,139, 50,143, 78,156,220,187,241,206,221,187,179, 86,111, 57, 48,233,232,217, 43,147, -150,174,219, 63,105,210, 31,155, 39, 21,110, 60,100,210,199,223, 77,156,148, 50, 91,209,177, 9, 62,200, 85, 22, 52, 13,189,163, -123,169,255, 68,150,193, 39, 66,243, 9, 80,116,153,141,124,233,210,165, 98,197,138, 21, 98,245,234,213, 98,221,186,117, 98,243, -230,205, 98,251,246,237, 2,117,172,156, 85,200, 9, 25,224,154,135, 99, 11,130, 47,157,147, 7,220,249, 36,208, 34,205,191,255, -254, 91, 25, 47, 54,108,216, 32,182,108,217, 34,118,238,220, 41,246,236,217,227,166,135, 5,139, 66,143,227, 1,193, 23,128, 1, - 23, 47,234, 75, 77,243, 18,251, 50,199, 30,230,109,199,142, 29,238,188, 29, 62,124, 88,168,105,241,184, 31, 30,174, 78, 48,130, -241,230,170, 17, 77, 2, 24,230,147,229,101,127,102,121,113, 16,187,216,191,127,191, 32, 77,244, 85,113,230,204, 25,229,156, 70, - 30, 51,198, 35,132, 72, 19, 64,203, 16,188, 73,154,158,202, 76,154, 44,179,154,166,167, 35,183, 36, 77,150,125,235,214,173,110, - 62, 30, 56,112, 64,169, 23,150, 93, 75,147,192, 14,224,201,144,159,228, 9,234, 41,128,124,231,161,223,172, 31,130, 93,150,155, - 99,253, 95,127,253,165,148,155,188,152, 62,125,186,192, 2,152,146, 45,189, 43, 66,219,167,151,250, 58,201, 56,249,244, 34, 51, - 35,136,159,134, 57, 68, 55,141,142, 80, 4,161, 6, 66, 85,132,146,174,223, 21, 93,247, 98,184,151,119,253,174,128,123, 81,215, -111,198,231,111,190,231,111, 25,138,168, 63,166,162,205,111,200,239,200,184,242, 27,218,255,242,185,246,125, 8,218,202,119,120, -110,154, 43,112,114, 83, 46, 9,180,172,128,172, 67,135, 14, 41, 64, 75,103,133,171,101, 90, 76,128,139,179, 28, 92,212, 23, 87, - 94,124,198,193,130,131, 58,239, 28, 68,161,126,224,132, 30,211,164,109,156, 35,240, 33, 80, 51,187,152, 71, 14,250,160,167, 93, - 53,135,250, 4, 85, 6, 92,197,147, 54, 7, 50, 78, 62, 28,184,152, 87, 74,225, 56, 8, 77,153, 50, 69, 25,160,200, 43,139,237, -247,187, 1, 3, 6, 60,226, 96,141, 51,237,174, 35,141,148,134, 13,152, 52,105, 82, 32,191,131,243,230,214,226,185, 22,184,132, - 34,143,178, 74,155, 44,183, 36, 11,207, 30, 32, 4,104,194, 3, 36, 86, 36, 93,184,164,100, 43,161, 94,126,241,158, 54, 89,201, - 81,246, 81,140,143, 65,253, 24,254, 63, 65, 56,131,112,192, 21,248,251,209,154, 53,107, 14, 51, 14,227, 50, 13,211,234,209,164, - 77, 22,213,133, 4, 91, 93,186,127, 24,180,255,191,127, 14, 61,125,122,199,127,199,129,211, 51, 70,204,250,119,210,194,127,246, - 42, 18, 45,134,253,199, 46, 76,106,213,119,238,164, 1, 19,151, 77, 42, 80,174,246,216,120,169,114,213,176,200, 87, 39, 90, 56, - 56,128, 73,252, 50, 1, 12, 65, 22,235, 20,192, 92, 64,189, 45,112,196, 14, 23, 38, 2,146, 36, 46,162,148,126,137, 5,144,192, - 2, 68, 64, 26,237,241,136, 39, 2, 3,210, 68, 59, 81,104,105,105, 98,130, 23, 28, 55,212,224,128,139, 44, 29,160,229, 46, 25, -210, 92, 98,127, 36,208, 80, 3, 64, 9,178,212,180, 8,178, 8, 6, 41, 73,202,152, 49,163, 22,104,185,105,202,124,106, 65, 22, -243, 70,144, 69,201,179, 26,100, 73,154, 58, 64,203, 77,147, 38, 21,148,100, 25, 1, 75, 45, 32,146, 52,117,128, 86, 8,154,228, -167, 4, 89, 88,220, 9, 79, 32,139, 99, 23,203,174, 3,180,180, 45, 37, 39, 37, 89,139, 23, 47, 22, 12,203,150, 45,115,131, 44, -142,121, 12,148,110,225,240,114, 74,182, 11,132,163,153, 57, 73, 29, 14,152,114, 64, 15,139,200, 68,152, 35, 42,116,239,222,189, - 7,199,168, 18, 37, 74,248, 17, 48,185,230, 53,247, 93,190,231, 93,190,103, 28,237,127, 85, 58,133, 60,226, 18,196,185,233,168, -211,170,191,161,154, 75, 67,125, 91,190,211,210,118, 23,154,133,227, 31,121,231,111,130, 7, 14, 22, 92,229, 74, 73, 22, 65,133, -148,100,113,213, 71, 73,150, 28,144,216,177,205,128, 22,206, 83,235, 2,251,158,199,158, 64,214,250,245,235, 21,208,199, 21, 52, - 14,224,125,204, 52, 38,181,163,172, 72,185,194, 93,180,104,145,178,226,214, 94, 28, 48, 71,142, 28, 41,124,125,125, 21,218,160, -103, 8,140,242,229,203,215,187, 97,195,134, 91, 27, 55,110,124,129, 3, 21, 87,224,228, 67,239,222,189,197,177, 99,199,148, 85, - 40, 39, 36,222, 81,121,202,192,132, 67,124, 47, 20, 44, 88,112, 3, 38,161,222, 30,242,250, 46, 6,180, 91, 84,177, 98,133,248, - 28, 3,229, 98, 87,220,118, 63,252,240,195,101,174,234,145,255, 91,120, 62,200,180, 53,190,168, 73, 61, 73,214, 29, 53,200, 66, -190, 3, 80,134,155,152,192,110, 97,226,185, 74,201, 86,212,168, 81,239, 34, 78, 10,189,111,224,121,108, 28, 22, 92, 18,239,158, - 65,106, 69, 70, 18,100,237, 83,211, 4,189, 0,208,218, 7,192,121, 7,124,162,221,218, 51,166, 97, 90,125,154, 43, 98,208, 38, -107,195,186, 1, 93,211,102, 72,127, 41,123,246,108,247,227,196,137,251, 44,109,186, 12,183, 51,231, 46,118,112,207,254,195, 51, - 8,178, 46, 92,185, 61,105,214,138,157,147,190, 25,244,251,164,134, 61,127,155,212,113,200,239,147,226,165,204, 59,216, 10, 47, -156, 56,225,227, 0,192,198, 37, 74,105, 40,173,102, 31,151,160,131,139, 30, 41,217,145,210,162, 75,151, 46, 41,146, 99, 74, 65, - 60,157,165, 73, 0,195,254,195,254, 76,192,161, 39,125,210, 74,138,184, 88,242, 4, 12,100, 62, 37, 45,173,212,169,107,215,174, - 74,191,148, 32,139,139, 34,130, 19, 0,173,107, 70, 28, 34, 40, 98, 62, 41,157,151,146, 44, 53,200,194, 96, 33, 40,213,230,226, -136,128,136, 96,144, 52,205,128,150, 28, 59,176,160, 82,198, 28,179, 59,105,162,236,148,182,235, 94, 50,159, 28,143, 8,178, 56, - 4, 72, 73,150, 17,125, 23, 77,173, 68, 75, 77, 95, 49,124,255,228,147, 79,158,114,252,230, 88, 6,218, 15,241,108, 47, 67,141, - 26, 53, 30, 17,104, 46, 88,176, 64, 96,124, 11,118, 61,183,106, 32, 31,190, 70,233,164,126, 43, 57,160,135, 69, 36, 35,180, 64, - 72, 15,104,189,152, 26, 67, 3, 48,237,115,198, 65,112, 75,157,212, 32, 78,190,211, 3, 94,174,119,138, 84, 75,143,166,124,166, -166,237,174, 72, 61, 20, 73,209, 63, 7, 11, 43, 32,139,157,209, 64,149, 16,162,177, 96,176, 88,203,213,161,188, 56,104, 81,146, - 69, 32,196, 65,142,226,123,230,101,206,156, 57, 74,231,246,243,243, 19, 76, 99,210,226, 20,160,197, 21, 46, 3, 7, 76,174,204, -168,158,224,128,220,183,111, 95,209,169, 83, 39,241,253,247,223,139, 94,189,122, 9,168,254, 60, 2, 45,128,135, 29, 28,160, 32, - 42,191, 65,128,245,219,111,191, 9,128, 14,209,161, 67, 7, 69,106,199,129,124,218,180,105,162, 75,151, 46,202,115, 78, 76, 45, - 91,182,188, 70, 62, 21, 41, 82,100,171,135,188,150, 99,124,242,180, 81,163, 70,207, 16,143,149, 92, 18, 54, 17,215, 56,144, 99, -165,250, 8, 19,201, 95,120, 38,237,168,162,123, 42, 55,129, 22, 43,213, 85,177,161, 36, 89,152, 56, 3, 0,234, 2, 80, 55, 1, -152,144, 2, 46, 95,190, 76, 9, 26, 37, 11, 4,186, 70, 64, 43, 1, 38,165,110,140, 7, 21,194, 37,196, 59,167, 6, 89,152, 8, - 3, 48,201, 42, 52, 33,213, 59, 6, 30, 31, 98, 92,166, 65,188, 4, 70,249,141, 31, 63, 78, 37, 72, 39,111, 67, 13,253, 28,170, - 71, 69, 74,200,201,112,246,156, 57,207,177,179,224,209,164, 41,211,150,206,251,123,215,164,214, 3,230, 77,170,222,110,226,164, - 10,173,199, 76,234, 53,118, 25,128, 86,110, 75,160,243,173, 28,145,188, 88,104,244,177, 75, 4, 37,108,203, 82,138, 69,137, 19, -165, 88,148, 22, 73, 41, 86,142, 28, 57, 4, 22, 34, 2, 27, 34,148, 69, 11, 15,136, 54,202, 6,129, 1,129, 19, 23, 64, 80, 57, - 81, 58, 45, 72, 19,139, 49, 74,173,148, 69, 11,199, 2, 9, 98, 56,209, 27,168,186,220,159, 32,208, 34, 77, 9, 0, 37, 32,146, -128,141, 11, 31,142, 39, 18, 16,177,175,241,130,234,208, 35,208,226,119,181, 11, 71, 41,201, 34,208, 34,200, 98,254, 56, 94, 73, -154,102, 64,139,192, 85,171, 34,213,147,100,145, 38,227,114,172, 49, 3, 90,204, 39,105, 50,175,236,119,122,234, 66,153, 79, 21, - 77, 79, 64,107, 27,121,197, 75,170, 11, 93, 6,240, 10,207, 1, 14,143, 83,106,198, 49,112,242,228,201,130,230, 25,104, 31,122, - 7,127,123,177, 53, 58,164,222,102, 14,152, 72,180,202, 27, 73,172,212,160, 71, 53, 47, 26, 74,157, 92, 64, 73, 97, 53, 65,145, - 6, 84, 41, 0, 76, 15,104,201,239,224,157,162, 42, 52,250,175, 91,135,122, 40,146, 64,139,131,154,122,149,171,183,234,147,131, - 28,117,251,158, 86,184,252,112,156, 56,113,110,203,129, 74, 15,100,113, 69, 69,144, 53, 97,194, 4, 69, 2,197,255, 76, 99,210, -240, 66, 0, 45, 9,184,120, 7, 0, 18,223,124,243, 13, 37, 99,110,160, 69,240, 6,122,134, 19, 68,158, 60,121,230, 97, 69,255, -156, 18, 53,168, 77,175,208, 22,139,246, 30, 52,194,229,157,229,229,160, 68, 94, 16, 12, 98, 21,125,117,232,208,161, 4,113,207, - 49,248,206,245,144,215, 65, 20,193, 19,100,208, 38,134,241, 96,227,180, 28,246,104,207, 33,205,122,158, 41, 83, 38,110, 0,200, -134, 16, 23,131,221,232,202,149, 43, 7, 64,250,244,157, 17, 61, 79, 64, 11,188, 13,192,132, 19, 0, 0, 27,128, 65, 57, 0, 82, - 5,254,190,194, 70, 97, 2,180,146, 66,146, 57,219,213,120, 8,200,168, 46, 84, 84,145,144, 96, 16,172, 5, 96,130, 84,104, 66, - 74,177, 15,121, 63,201,184, 76,131, 56, 73, 13,242,154, 12,117,120,199,200,126,142,252, 76,144, 48,225,163,161,211,252,103,244, -157,180,114,210,144, 25,255, 76, 26, 48,117,229,164,178,117, 59, 76,136,251,126,182,178,111,243,160,243,178,202, 14,245,239, 37, - 74,168, 40,201, 82,247,113,173, 74,142,237,159, 64,153,125,129, 19,185, 25,208, 98, 31,151, 42, 62,181,244, 73,130, 24,130, 44, - 74,120, 9, 14,248,125,151,170,235,130, 81,185, 9,180, 8, 8,217, 55, 9,178,216,175,185, 0, 98, 27, 34,173,158, 61,123, 42, -160, 72, 13,136,172, 0, 45,142,115, 82, 58,239, 83,231,128, 96, 56,127,254,188, 66,147, 64, 75, 13, 94,228, 34, 17,160,136,253, - 73,247,162,217, 1,105, 50,159,102,146, 44,249,158,116, 49,126, 24, 74,180, 36, 77,169, 46,100,191,147,192,205, 72,162, 69,154, -200,167, 33, 63, 65, 99, 27,235,147,233, 41,165,167, 61,157, 4, 90, 63,254,248, 99,235,126,253,250,221, 27, 63,126,188,178, 64, - 37,175, 91,180,104, 65,233,125, 80,133, 10, 21,246,228,204,153,115,209,203,106,159,206,119,222, 30, 14,152, 72,180, 74, 16,220, -168, 1,142, 4, 58,118,239, 46, 58, 33, 0,149, 75,189, 88, 65,114, 91, 15,104,201,239,235,229, 65,243, 44,116,165,169, 80,100, -111,249,150,162,127, 14, 88, 82,149,224, 9,100,113, 21,105,166, 74,112, 1,139,251, 4, 26,164,203, 65,140,171, 90,174,206,248, - 13, 53,200, 26, 60,120,176, 64, 39, 87, 12, 48, 1, 70,238,155, 52, 51, 67,160,197,129, 65, 11,180, 72, 19,244, 60,217, 84,197, -202,146, 37,203, 48, 72,167,214, 96, 37,239, 7, 99,247, 43, 92,121, 83, 2,195, 21, 37, 3, 85,148, 28,148, 8, 44, 49, 0,206, -135, 68,103, 13, 38,157, 97,160, 27,203, 40,175,176, 83,217,205,213, 35,249,136, 56, 51, 17, 10, 32,127,193,156, 56, 48,168,209, -142,170, 45, 66, 66,216,176, 65, 32,183,248, 14, 7,122,236, 74,164, 65,186, 46, 77, 35,160, 5,192, 27, 0,169, 91, 0, 38,201, - 0,168, 25, 2,254,249,231,159, 0,228,151,224,136,187,164, 76,129, 22,164, 15,243, 17, 47, 24,244,105,244,118,128,234, 71, 76, - 52, 1,224,129,155, 38,236,110, 2, 86,174, 92,185, 23, 18,195, 19,140,203, 52, 70, 64, 11,229,153,132,239,191, 16, 45,168, 46, -182, 3,242,149, 3,253,176, 97,195,130,227, 39, 76,254, 95,162, 52,121, 39, 37, 73,151,143, 42,195,159, 95,128,172,222, 70,219, -201,223,158,145,231, 37,148,148, 64,139, 11, 37,182, 77, 41,113,210, 74,177, 8,178, 74,150, 44, 41,176, 97, 67, 96, 17, 32,160, -238, 22,176, 41,242, 40,209,226,152, 64,233, 19, 38,123, 37,164, 79,159, 94,217,232, 34, 65, 12, 65, 22,165,196,140,199,126,229, -146,234, 24, 2, 3, 74,222, 24,151, 0,144, 99, 7, 1, 27,105, 81, 90,205, 49, 8,253, 72,201, 23,129,129, 92,208,153, 1, 45, - 2, 24,246, 65, 2, 55, 53, 77,130, 45,230,143, 64,203, 29, 84,237,215, 12,104,145,166, 26,168,170,237,188,180, 82, 39, 73, 86, -103, 39,163,187,246,101, 62,165,186,144,124, 84, 27,211, 27,209, 52, 1, 90,138,234, 16,146,202, 39, 28,207, 48, 86,136,234,213, -171, 63,198,184,116, 6,147,206,125,109,159, 85,255, 71, 26,186,183,113, 46,135, 3, 94,229,128, 30, 22,209, 2, 31,206, 99,106, -155, 43, 51,224,165,141,207,255, 12,174,116, 90,201,149, 91,147,164, 7,180, 52,105, 37, 13,229,110, 10,180,244, 56, 69,160,197, -149,171,167,157, 56,178,163, 19,132,112, 5,231,105,133,203,111,128,230,102,166,225,228,170, 6, 89,180, 3,155, 61,123,182,224, -234,137, 32,139, 3, 38, 85, 19,216,229, 39,152,198,155, 64, 11, 70,231,102, 64, 75,251,185,138,121,243,230,189,200,129,156, 18, - 41,230, 13,118,102, 52, 8, 38,112,161, 75, 9, 75, 87,246,236,217,159,177, 54, 40,253, 66,130, 47, 17,198, 83, 13, 64,240,133, - 50,210, 88, 55, 29,140,142, 55,195,248,244, 17,165, 63,144,188,221, 6,200,252,217,136,184, 6,104,221,131,186, 51, 0,124, 13, -128,116, 44, 0, 59, 44, 41,113, 10,192,224, 25, 0,169, 91, 0, 84,157, 4, 92,220, 0, 96, 6,180, 18,192,232,245, 7,198,195, -132,118, 5, 52,207,161,110,221, 52,161,222, 84,104, 66,253, 26,128, 58, 59, 56,107,214, 44,250, 42,163,161,236, 15,200, 79, 2, -189,188, 66,218,117, 82,170, 39,228, 64,205, 73,149, 54,105,156,216,185, 51,139,118, 60,144,242, 81, 13,233, 92,175,128, 3, 80, - 17, 94,228, 68,173, 85,159, 73,137,137,220,193, 71, 48,198,126, 78,213, 58, 47, 79, 64,139,192,128,241, 41,201,210,130, 24, 72, - 70, 21, 16, 67,144,197, 49,134,237, 65,210, 4, 48,208,186, 77,112,115, 68, 2, 45,105,164, 78,155, 44,170,240,185,155,152,146, -172,159,126,250, 73, 89,196, 17,176,113,161, 38,193, 22, 0,158,161,234,144,249,100, 26,142, 71,220,228, 34, 37, 90,188,147, 39, - 4, 89, 82, 13,167, 0, 46,215,133,124, 26, 26,216,115,247, 53,105, 74,213,158, 21,144, 69,178,158,128,150,150,166, 21,144, 69, -154,158,248,233, 98,108, 78, 72,168,110,177,174,184, 81,136, 0,142,210, 61,142, 83,188,228,196,162,190,243, 57, 22,160,134,245, -244, 10,154,176,243,201,183,128, 3,104,118,234,157,128,252, 45,119, 21,106,119,254,233,237, 4, 84,199, 15,177,235, 80, 69, 55, - 44,187, 16,229,183,212, 59, 21, 67,239, 56, 52,170, 31,218, 88,176,243, 25,109,119, 86,131, 44,198, 51, 83, 37,240, 59, 0, 14, -125,176, 83,239, 41, 7, 33, 41,201,210,130, 44,174, 72,169, 14, 24, 52,104,144,128,189,212, 83,166, 49, 3, 90,148,142,168, 85, -134,242,183,158, 68,139,118, 6,160,103,117,151,160,242,105, 74,174, 56, 88,114, 48,134, 91, 6,101,231, 15,249, 99,163,109,191, - 75,187, 22, 94, 44, 31,210, 81,183,251, 47,249, 64,160,129,223, 19, 16,218,112,163, 0, 39, 30,240,232, 62, 36, 96, 83,201, 50, - 43, 64, 11,147,212,117, 76, 86, 55, 49, 49, 4, 34,127, 1,216,176, 16, 0,155,177,128,121,243,230, 5,192,238,237, 52,164, 79, -103, 0,100, 21, 53,159,137,234, 48, 14, 12, 99, 41, 58,229,138,225, 63,186,115,192,100, 11,146, 47,104,130, 78, 0,252,146, 5, -204,152, 49, 99, 55,232,159,196,206, 15, 58,172, 20, 76,131,162,197,209,203, 43, 54, 51, 40,126,121,228, 37,119,109,210,118,135, -246,114,148, 48,146, 7, 80, 89, 80,170,231, 92,175,128, 3,144, 98, 93, 36,232, 81,111,110, 81, 27,170,115, 33,165, 5, 89, 86, -128, 22, 1, 54, 65, 22,119, 41, 66,213,228,182,239, 82, 75,198, 24, 71,221, 62, 76,236,148, 20,137, 22, 37, 89, 4, 89,148,102, - 17,176,177, 79, 17, 20,113,195, 10,199, 33, 94,106,160,133,133, 0,237, 19,117, 47, 2, 24,210,148, 32, 75,130, 64, 2, 45, 62, - 39,184, 34,112,115,161, 14, 53,208, 50, 4,111, 18, 20,145,135,118, 84,135,158,192,139,154,166, 4, 61,191,254,250,171, 82,110, - 19,213,161,161, 58,146, 12,201,157, 59,247, 94,246, 73, 26,217,211,182, 21, 99,134, 64,255, 86,198, 96, 79, 23, 22,135, 55, 95, - 65, 83,117, 62,233,112,224,205,226, 0,129, 4, 59,177,118,231,145,167, 85,174,167, 21,174,139, 59, 9, 96,175,115,157,210, 12, -174, 74,169, 46, 84, 75,178, 56, 96,182,111,223,222, 45,254,103, 92,164, 75, 96,194,217,243, 28, 40,152, 47, 14, 22,106,192,165, - 6, 90, 61,122,244, 80,192, 27,165,100,160,231,201, 64, 52,212,231,184,155,146, 3, 49,125,113,241, 27,148,192, 80,226,103,163, -198, 19, 82,229,194,139, 3, 24,210,149,133, 65,176,178, 43,128,131, 26,254,183, 71, 88, 8,158, 4,163, 28,193, 0, 67, 43,241, -223,147,119,124, 46,173, 19, 35, 31,233, 25, 0, 82, 30, 51, 64,242,112, 5,106,216, 0,240, 53, 0,124, 13,128,132, 48, 0,131, -240, 41,128,157,199,209,162, 69,123,204,184, 0,137,233,144, 86,247, 72, 30, 60,143,138,240, 62, 84,129,115, 56,152, 3, 12,237, -199, 4,123, 23,118, 33,199, 33,201,218, 7, 21,224, 94,216,173, 29, 2,253,211,168,167, 85,140,195,184, 76,195,180,122,252,128, - 68,235,148,148,104,113,226,226, 42,159, 59, 87,105,223, 70,201,224,168, 81,163, 20,176, 5,137, 22,221, 69, 56,215, 43,224, 0, -129, 22,165,204,122, 46, 13, 36,200, 98, 31,227,130, 70,125,153, 73,180, 88,239, 82, 82, 68, 91, 71,130, 24, 74,107,165,157,151, - 90, 58, 38,233,122, 2, 90, 84,113,114, 33, 66,128, 69, 90,236,211, 52,128,167,109, 22,219, 22, 55,190, 80, 18,206,160, 86, 29, - 90, 1, 90,146,166, 90,162, 69, 73,155, 7,213,161, 41,208,178, 42,201,146,101,183, 2,180,212,146, 44,246, 63,181, 49,189, 30, - 48,242,196, 79, 54, 53,140, 11, 99, 57,230, 18,180,145, 79,216,236,240, 4,227, 70,240, 23, 95,124,225,194,150,161,157, 32,243, - 5, 22,192,220,157,232, 92, 14, 7, 28, 14,132,135, 3,210,143,148,122,123,183, 17,200,146, 3,176,206,192,171,231, 32,174,114, -214,172, 89,131, 40, 25,226,192, 78, 63, 93,156,108, 57, 72,246,233,211, 71,241,207, 67,155, 11,172,224,232,176,180,178, 78, 25, -180, 52,191,128,231,247, 7,244,107, 69, 21, 7,237, 34,184,219,144,128,139, 64,171, 93,187,118,202, 74,119,200,144, 33,226,243, -207, 63,167,113, 61,233,126,161,161,235,209,145, 29,129, 22, 69,234, 84,245, 81, 18, 67, 91, 6,110, 22, 48,225,175,154,102,106, -108,149, 86, 6, 46,230, 9,233, 74, 22, 47, 94, 92, 17,243,208,158, 4,255,107,194,206,235, 22,255, 99,135, 15,183, 81,119, 48, -160,173,117, 46, 74,191, 87,238,221,135,152,212,206, 3, 20,157, 7,152, 58,139, 60,158,134,196,232,228,196,137, 19,233,130, 65, -234,164,233, 71, 75,235,239, 74, 75, 51, 22, 86,181, 89, 32, 81, 59,205,116, 95,127,253,245, 62,148,251, 63,128, 76,210, 61, 54, -115,230,204,109,200,251, 54,190, 99, 28,198, 5, 77,173, 29,153,155, 38,108,180, 38, 35, 31, 79, 41,105, 32, 15, 9, 82,233,173, -159,155, 29, 56, 73,114, 71, 83,155, 54,109,158, 33,222,104, 27,252, 12, 79,211, 86,167,117, 28, 24,130, 27, 80,249, 95,144,234, -124,181,223, 40,181,155, 4, 45,200, 98, 91,245,212,223, 41,129,225, 66,141, 11,148, 66,133, 10,209,239, 13,109, 14, 69,165, 74, -149, 4,251, 2, 65,150, 30, 77, 44, 64,180, 18, 24,119, 29, 73,163,125, 9,216,244, 84,143,122, 96, 3, 0,226,134, 81,127,151, - 18, 45,181, 58, 83,109, 51,166, 71,143,207,144, 79, 45,208,114,231,147,227,133,220,236, 99, 83,162,165,181, 79,211,165, 73, 53, - 41, 36, 81, 10,184,100,191,242, 36,209,242,196, 79, 23, 79,148, 35,120,176, 96,162,116, 90, 57,130, 7,167,115,136,143, 63,254, -216,168,232,106, 0, 38,217,234,244, 35,111,141, 72, 47,232,188,205,252,244, 46, 39, 95,119,106, 4, 90,236,208,242,200, 13, 14, -154, 92,161,114, 69,201, 65,132, 3,165,219,118,193,213, 37, 45, 2, 45, 22,189, 10, 38,214,235, 88,137, 62, 33,208,162,100,139, -187, 1,251,247,239, 79,215, 7, 79, 93,146,172, 42, 86,192,134, 43, 78, 50,220,199, 2, 0, 60, 35,224, 34, 32, 36,144,163,237, - 6, 12,173, 21,112,131,242,208,165,194, 88, 4,198,213, 94,102, 64,235, 50,119, 16,101,203,150, 77,192, 80, 94,217,161, 67, 39, -143, 54,128, 65,114, 76, 48,138,254, 1,106, 54,130,158,124,248,175, 0,173,122,245,234,241,127,238,138, 21, 43, 42,255,155, 52, -105,194,255, 70,142, 1, 67,229, 19, 73,220,146, 45, 72,174, 4, 3, 86,169,238,128,157,139, 4, 55,138,228,139,113,173,148, 29, -241,226, 79,157, 58, 53,171,148,108, 33, 77, 40, 91, 13,190, 99, 28,198, 53,161,153, 12,117,125,135,254,205, 40,213,160, 27,140, -113,227,198, 41,192,151,171,104, 14,234,240,194, 79, 53,132,167,131,175,223,246,193, 39, 66, 7, 94,244, 91, 5,104,233, 57,231, -212,147,100,201, 25,216, 10,208, 98,157,211,247,150,220,177, 40, 85,144,122, 32,203, 5, 96, 12,129, 22, 64,145,162, 58, 84, 75, -197,212,246, 93, 70,200, 0,146, 34, 67,160, 37, 65, 17,105,170,129,155, 91, 93,104, 64,212, 12,104,145,111,210, 45,132, 4, 68, -102, 52,145, 79,143, 64, 75,210, 84,247, 71, 51,154, 22,128,150,182,251, 74, 3,121,229, 12, 33,245,183,212,172,112, 61,119,128, -214,219, 13,138, 34, 98, 92,122,221,161,145,119,243,199, 3,162,229, 1,178,234,195, 84,105,175,196, 64,195,119, 6, 14,182, 50, - 0,204,216, 57, 84, 58, 62,196,207, 63, 65, 69,185, 17,190, 89,238, 50,240, 55,159,161, 36,122,147,183,149, 78,157, 9,145,230, -127,244,209, 71,193, 4, 67,180,227,128,219, 4, 74,136,184,147,142,239,140, 46,143, 13, 6, 59,108, 86,211, 23, 23, 37,112,180, - 99,105,222,188, 57,119, 80,173,182, 1,180, 40,162,159,134, 85, 61,193,222, 52,166,131, 99,192,105,240, 2,255, 28, 64,232, 55, -254,231,251, 98,197,138,241,191, 39, 23, 17,186,249,164,148, 74, 45,217,210, 2, 35,190,211,145,100,121,228, 39,165, 84, 8,239, -215,173, 91,183, 28,118,160,117, 7,176,154,203,192,223,124,198,119,140, 99,192, 3,109, 62,203, 3,108,221,130, 20,235, 41, 61, -133,211,219, 52,253,242,124,251,237,183, 4,213, 4, 89, 70,231, 69,170,201, 71, 68,167,118,104,130,195, 84, 99, 83,122, 69,160, -161, 94, 76,153,129, 24, 51,160, 69,122, 4, 86,218,197,153,218, 38, 75,139, 99, 60, 29, 67, 35,129,150, 92,228, 81, 61,104, 6, - 52, 72, 31,234, 51,143,210, 39, 2, 33, 73,147, 0,208, 10, 77,240,204,240, 88, 31, 9,222,200, 63, 46, 70,173,210,132,228,205, - 16,104,113,204,229, 2,151, 52, 89,110,171, 52, 61,241,211,211,248, 5,187, 58,158, 10, 97,120, 57, 64,203,205, 61,103, 12,241, - 46,244,112,168,133,129, 3,175,170, 17, 22, 70, 94,151,185, 2,127,155, 93,102,249,140,137,157,135,191, 97,176, 59,142, 65,244, - 56, 84,159, 4, 71,102, 71, 3,233,209,212, 2,147,120,154,140,105,255,107,243,109,152, 79,140,136, 60,146,135,128, 74, 47,120, -146, 22,121,162, 73,155,173, 56, 8, 9, 16,146,186, 2,127,243,153, 39,215, 11,122, 52,147,226, 56,151, 95, 97,179,117,154, 6, -242,220,141, 72,215, 15, 40, 96, 18,179,202,113,189, 55,171, 35,139,100, 66, 68,115,104,178, 2,146, 36,217,166, 93, 76,233, 45, -164,212,139, 42,254,246,180,176,130,196,119, 39,105,202,133,153,209,226,204, 14, 77,124,111,139,167,133,158,150,150,252,143,242, -237,211, 52, 14,119,189,227,221,206,176,208,244, 84,118, 73, 83,242, 80,187, 32, 53,202, 39,242, 65,149,188,238,226, 34,172, 52, -109, 46,126,221,223, 6,144,220,134,180,119,209, 71, 31,162,191,114,129, 24, 66,186, 5, 41,180,218,143,152,211,143,194, 50,250, - 24,167,121,155,249,233, 93, 78,190, 37,212,222,230, 6,227,148,221,187,141,220,225,167,195, 79,111,113,192,105, 75,222,226,228, - 11, 58, 14, 63, 29,126,122,151, 3, 14, 53, 91, 28,112, 58,160, 45,118,153, 70,118,248,105,202, 34, 91, 17, 28,126,218, 98,151, -105,100,135,159,166, 44,178, 21,193,225,167, 45,118,153, 70,118,248,105,202, 34, 91, 17, 34,130,159,182, 50, 16,153, 34,147, 89, -122,193, 78, 25,140,104,120,122,110, 70,223,161,169, 95, 47, 97,173, 47,135,159, 14, 63,173,182, 1,167,111, 26,115,192, 42, 15, -213,241, 28,126, 58,252,212,227,192,219,220,150, 36, 63,194, 58,159,153,245,169,183,234,125, 68, 32, 94,135,166,119,155,144,195, - 79,135,159,222,226,128,211,150,188,197,201, 23,116, 28,126, 58,252,244, 22, 7, 34, 75, 91,242, 86,121,223, 42, 58,145,165,114, -157,124,122,183, 89, 58,252,116,248,233, 45, 14, 56,109,201, 91,156,116,192,155,211,150, 94,255,182,228,221, 28,190, 37,212,156, -134,237,221,138,118,248,233,240,211, 91, 28,112,218,146,183, 56,233, 0, 24,167, 45, 57,109,201,187, 28,112,168,217,226,128,211, - 1,109,177,203, 52,178,195, 79, 83, 22,217,138,224,240,211, 22,187, 76, 35, 27,241, 51, 27,156,113, 30,132,195, 95,250,137,106, -102, 74, 37,100, 4,187,117,212, 8,142,139,175,195, 31,223,223, 32,147,205,224, 91,118,105, 90,201,178, 67,211, 10,151,172,199, -113,248,105,157, 87, 86, 98, 70, 22,126, 90, 41,139, 19, 71,195,129,200, 82,185, 78, 62,189,219,116, 29,126, 58,252,148, 28,200, - 6, 31,116,215,228, 25,133,112, 30,170,117,244,105,198, 41, 91,109, 9,135,183, 95,160, 67, 79,156,249, 41,224,191,138,190,158, -244,192,150, 25,205,108,112, 30, 74, 96,200, 51, 81, 27,153,101,208,245,222,140,166, 36,211, 12,142,139,111,224,108,210,191, 60, - 0, 65, 25,215, 42, 77,139, 89, 84,162, 57, 52,237,112,203, 60,174,195, 79,207, 60,202,131,215,121,205,217,232,196, 8, 15, 7, -156, 70, 24, 30,238,133, 78,235,240,211,225,167,183, 56,240, 50,218,146, 27,100,241,136, 27, 28, 76, 46,112, 34, 2, 1,134,157, -203, 86, 62,225, 20,119,255,186,117,235,148,195,203,255,253,247, 95,145, 33, 67, 6, 2, 59, 45,216,242, 68, 51, 4, 48,164,211, - 85,139,153,181,148,207,162, 69,139, 94,164, 87,119,230, 17,158,238,141,128,160, 3,180, 28, 64,104,177,217, 89,142,102,169,125, - 90,166,246, 34,162, 17, 77, 58,243,254, 34, 74,148, 40,219,243,228,201,163,156,203,137,223, 91,240,172, 46,194, 59, 54,191,241, -102, 69,199,193,164,235, 24,222,172, 82, 57,165,113, 56,224,112,224, 21,113, 0,227,107,110, 8,178,238, 43,231, 28,142, 29, 59, -150,231,131, 62, 65, 94,254, 65, 88,162, 19,122,226,153,167,163,183,212,197, 96, 60,198,215,163,243, 15,191,195,239,241,124, 77, - 28,178,206, 51, 74, 31,232,128, 45, 61,182,184, 65, 22,243,204,115, 57,225, 21,221, 46, 48,244,200,110, 28, 99,245, 31, 15, 86, - 39, 16, 36,240,132, 55,120, 51,176,245,138,170,207,249,172,195, 1,219, 28, 72,143, 20,131,177,216,185,193, 67,201,113, 22,174, - 88,186,116,169, 88,184,112,161, 24, 49, 98,132, 40, 95,190,188,128, 36,151,230, 3,221, 16, 18, 26, 81,127, 99,177, 8, 79,127, - 71, 40,203, 96,155,181, 78, 2,135, 3, 14, 7, 28, 14,132,230,192,102,158, 33, 72,192, 66, 80,193, 51,255,140,174,192,192, 64, -193,195,229,161,234,251, 15,100,204, 14, 23, 79, 84,176, 96,193,195, 60,228, 94,125,241,252, 68, 30,186,204,179, 26,175, 95,191, - 46, 46, 92,184,160,124,247,252,249,243,202,225,206,160,171, 61,134, 71,155,227, 16, 32,107,229,202,149, 2,199,222, 68, 4, 8, -202, 6, 41,217, 21,130, 44,230,143,103,127,226,252, 80, 61,169,155,211,166, 28, 14, 68, 38, 14,116,255,252,243,207,159,127,243, -205, 55, 98,210,164, 73,196, 19, 98,193,130, 5, 98,230,204,153, 98,198,140, 25, 98,246,236,217, 98,214,172, 89, 98,204,152, 49, -162,118,237,218, 2,103, 41, 63, 68,225,198, 35,100, 85, 23,242,141,198, 34, 44, 92,100,170, 81, 39,175, 14, 7, 28, 14,188,246, - 28,216,199, 67,165, 9,162, 8, 40,172, 4,130, 15, 23,216, 50,146,108,197, 39,200,162,148,140,170, 72, 43, 52, 9,180, 8,188, -192,173,205, 30, 56,150, 30, 42,142,235, 82,250,246,215, 95,127, 81,250,246, 24,241,141,164,111, 75,240,110, 42, 66, 58, 3,154, -124, 62, 2,129,241,244,194, 63, 80, 27, 62,102,121, 41,117,219,191,127, 63,165,110,215, 17, 55,195,107, 95,171, 78, 6, 29, 14, -232,115,224,200,161, 67,135,196,127,255,253,167,168,236, 87,172, 88, 17, 2,104, 17,100,253,246,219,111, 98,218,180,105, 74,152, - 50,101,138,104,211,166,141,200,152, 49, 99, 48,200,245,146, 36,223,104, 44,242, 70, 23,206,233, 22, 14, 7, 28, 14,188, 10, 14, -100,195,225,235, 15, 8, 36, 8,118, 60,169, 14,161, 62, 59, 41, 37, 60,148,108, 33,179, 84, 11,234, 93, 61, 41,201,146,246, 94, - 76,167, 3,100,254,129, 93,214,147,197,139, 23, 43,223,165,234, 48,123,246,236,247, 17, 47,183, 7, 38, 12,163,212, 75, 74,223, - 30, 63,126,108, 40,125,147, 47, 40,173, 3, 88,210, 5,111,144,132,173,225,123,179,139,223,145, 82,183,227,199,143,179,220,211, - 94, 69, 69, 57,223,116, 56,224, 5, 14, 28,217,179,103,143,232,214,173,155,152, 63,127,190,210,239,182,110,221, 42,150, 45, 91, - 38,126,255,253,119, 69,154, 37, 65,150,250, 78,149, 34,190,125,228,109, 1, 90,189,223, 88,189,168, 23, 90,144, 67,194,225,128, -195,129, 48,113, 32, 27,141,209,119,237,218, 37, 78,159, 62,173,216, 36,197,137, 19,103,191, 14,165, 68, 4, 77, 84, 47, 18,120, -184,192,147,222, 7,151, 16,188, 48,142, 11,100,133, 82, 51,114, 55, 31,193,216,163, 71,143,196,134, 13, 27,140,140,225,181,180, -167, 93,186,116, 73, 92,185,114,197,146,148, 76,170,252, 8,168,244, 50, 73, 0, 38,237,176, 60, 73,221, 78,157, 58, 37,206,157, - 59,167, 0, 66, 23,208, 26, 22, 38, 46, 59,137, 28, 14,188,122, 14,252,183,109,219, 54, 69,138, 53,120,240, 96,209,181,107, 87, - 49,111,222, 60,183,132, 75, 11,180, 90,183,110, 45, 10, 21, 42, 36, 58,119,238,172, 5, 90,111, 54, 22,113,108,180, 94,125, 75, -117,114,224,112,224, 13,228, 64,182, 84,169, 82, 93,161, 45,210,225,195,135,169, 26, 60,107, 80, 70, 55,136,178, 2,180,140,226, -208,222,137,146, 41,170, 47, 60,184,119,208,102, 33, 67,142, 28, 57,174, 19,240, 92,188,120, 81, 88, 84, 29, 82, 53,152,206,160, - 44,124, 78,213,226, 18,131,240, 15,164,125,143,105, 79,118,239,222, 61,181,234,144,198,196,206,229,112, 32, 50,114,224, 83,244, -243, 91, 3, 7, 14, 84, 92,171, 80, 77,200,223, 93,186,116, 17,126,126,126, 10,224,162,148, 89, 2,172, 82,165, 74,137, 6, 13, - 26,136, 86,194,135, 64,139,182,153,238,203,193, 34,145,177,250,157, 60, 59, 28,112, 56,240,170, 57,144,141,110, 29,224, 67,139, -198,229,122,126,169, 18,213,169, 83,231, 34, 13,218,195, 43,209, 2,253,102, 0, 88,231, 92,146, 51, 35,135,165,122,252,200,150, - 37, 75,150,171, 4,131,148, 50, 69,164, 49, 60, 84,153,215, 8,178,104,188, 79,201,151, 99, 12,255,170,155,167,243,125, 47,113, -224, 61,208,233, 7,187,171,135, 67,135, 14, 85, 22, 44,191,254,250,171, 24, 48, 96,128, 34,185,130,255, 56, 37,212,173, 91, 87, -116,234,212, 73, 84,173, 90, 85, 96,135,226,109,164,249,204, 75,223,119,200, 56, 28,112, 56,224,112,192,225,128,139, 3,233,112, -119, 27,139, 19,100, 81,213,199,157,130,102, 54, 90,151, 47, 95, 22, 12, 46,215, 8,106, 27, 45, 79,198,233, 86, 25,159, 45,125, -250,244, 87,119,238,220,169,168, 58,233,222,193, 64,213,105,149, 94,168,120,177, 99,199,254,155,170, 77,130, 44, 74,249, 28,247, - 14, 97,102,165,147,240,245,229, 64,114,100,109, 76,174, 92,185,158,142, 28, 57, 82, 44, 89,178, 68,177,209,252,244,211, 79, 21, - 27,174,250,245,235,211,190,241, 17,226,252,140,144,224,245, 45, 70,228,201,217,203,116,146, 22, 30,174, 56,249, 12, 15,247, 66, -167,117,248,233,240,211, 19, 7,254,162,177,172,188, 40,201, 34,200, 50,216,117,168,110, 75,241,115,230,204,121,136, 82,167,179, -103,207,134,112, 25,193, 29, 79,248,224, 58,139,108,247,232,176,148,146, 55,170, 63, 92,170,206,115, 94,160,233, 38, 1, 32,119, -133,170, 77,130, 44,199, 97,169, 71,206, 58, 99,136,197,134,103, 49,218,171,224, 39, 85,225,179, 96,139,245,124,244,232,209,202, - 46, 67, 72,111,159,227, 25, 23, 69, 31, 88,204,183, 19,205, 2, 7, 94, 69,229, 90,200, 86,168, 40, 78, 62,195,194, 53,227, 52, - 14, 63, 29,126,122,226,192, 58,170, 20,212,134,226, 30,252,104,105,219, 82, 34, 24,216, 31,248,243,207, 63, 67,164, 31, 55,110, - 28,129,150, 85,231,162,102,237, 51, 27,140,234,255,134,205, 9,253, 91, 53,179, 88,149,102, 52, 37,153, 70,180, 83,179,168,218, -180, 74,211, 98, 22,149,104, 14, 77, 59,220, 50,143,235,240,211,156, 71,220,241, 59, 15, 97, 46, 66, 78,243,232, 78, 12,187, 28, -112, 26,161, 93,142,121,142,239,240,211,225,167,183, 56,240, 42,219, 82, 58, 20, 66,107, 44,110,228, 25, 94, 47,159,122,158,225, - 61, 25,167,107,121,246, 42,203,110,167,254,156,124,218,225,150,121, 92,135,159,230, 60,178, 19, 35, 34,248,105,231,251, 78, 92, - 23, 7, 34,162, 34, 28,154,222,109, 94, 14, 63, 29,126,122,139, 3, 78, 91,242, 22, 39, 95,208,113,248,233,240,211, 91, 28,136, - 44,109,201, 91,229,125,171,232, 68,150,202,117,242,233,221,102,233,240,211,225,167,183, 56,224,180, 37,111,113,210, 1,111, 78, - 91,122,253,219,146,119,115,248,150, 80,115, 26,182,119, 43,218,225,167,195, 79,111,113,192,105, 75,222,226,164, 3, 96,156,182, -228,180, 37,239,114,224, 13,164,198, 78,162, 23,236, 20,213,136,134,167,231,102,244, 29,154,250,245, 18,214,250,114,248,233,240, -211,106, 27,112,250,166, 49, 7,172,242, 80, 29,207,225,167,195, 79, 61, 14,188,205,109, 73,242, 35,172,243,153, 89,159,122,171, -222, 59, 43, 29,239, 86,183,195, 79,135,159,222,226,128,211,150,188,197, 73, 71,162,165,215,150,162,128, 45, 12, 81, 93, 65,254, -183,202,245, 87,209, 62,153, 71,187,215,203, 42,123, 68,240,243,117,164,105,151,255, 78,124,151,164, 76,143, 17,172,224,104,174, -142,104,151, 81,175,162, 3,218,205, 35,227, 71,246,124,106, 7, 73, 59, 60,136,236,101,183, 83, 86,109, 92,167,236,225,225, 94, -232,180, 14, 63, 35, 31, 63,229,216, 17, 29, 89,143,129, 16, 19,129,191, 9,186,172,130,153,151, 89,239,204,215, 59,174, 60,218, -157,151,180,249,140,136,178,191, 77, 52,189,219,218, 35, 1,181,252,113,227,198, 93,146, 56,113,226,255,112,120,234,222,152, 49, - 99,206, 68,158, 75,216,204,183, 94,103,153, 10,111,200,207,223,121,231,157,167, 56,150,227, 41,232, 62,141, 21, 43,214, 83,248, -149,121,154, 32, 65,130, 59, 22,232,235,118,192,100,121, 62,237,146, 50,239,103,231,146,231,249,228, 7, 53, 13,163,231,154,239, -188,204, 78,109,161,136,134, 81, 94, 86, 62,163,160,110,106,195,223, 79,203,104,209,162,181,136, 30, 61,186, 18, 80, 87, 45,224, -217,186, 5,234,169,153, 73, 33, 66,228, 51, 81,162, 68,219, 51,103,206,124, 44, 91,182,108,199,112,166,220, 49, 56,157, 60,150, - 60,121,242,237,146, 6,234,127, 83,210,164, 73,143,224,123, 71,224, 44,242, 72,218,180,105,143,160,205,109,114,234,200,205,129, -151, 85,239,225,105,155, 33, 22, 23,191,255,254,123,180,187, 91,226,101,123,176, 57, 90,253, 71, 91,163,182,225,157,255,249,220, - 74, 80,101, 36,210,149, 61,188, 76,124, 21,101,135,223,176,145,232,119,247,209, 87,175, 96,204, 15, 68,255, 11, 68,159, 84, 2, - 28,171, 42, 1,125, 86, 9,120,183,211, 67,223,148,160, 0, 36, 99,140,131,131,202,251,160,113,133,206, 89,153, 22, 99,127, 32, -250,185, 18, 82,166, 76,233, 14,136,227,137,102,136,207,129,214, 36,208, 13,114,209,189,140,255,238,128,103,151, 84, 97,131,201, - 24,162,228, 21,249, 28,163, 42,251, 21,111,149,157, 52,193, 75,210,187,162,199, 71,242,130,193,164,236, 33,248, 25, 81,249,116, -213,187, 87,203, 30, 70,154, 94,236, 62,145,128, 84,129, 2, 5,142, 60,121,242,196,237,189,249,193,131, 7,202,169,220,200,250, - 32, 27,217,215, 14,146, 51, 75,151, 46,173, 16,229, 1,147, 60,192,245,210,165, 75,202,233,245,103,206,156, 17,239,189,247,222, - 83, 11,180,117, 7,222, 44, 37, 26, 95,191,119,255, 65, 80,166,226,141,120,158,154,251, 50,122,238,161, 3,230,199,187,133, 8, -123,109,134, 85,136, 95,208,104,144, 68,163,219,204, 14,108, 39, 48,141,167,129, 34, 34,104,226,123, 4, 89,117, 42, 84,168,208, - 18,213,212, 10, 30,184, 91, 93,187,118,173,213,149, 43, 87, 90,161,174,148,255, 56,159,170,133, 29,160,133,179,175,142, 76,157, - 58, 85, 57, 58,101,204,152, 49,130, 71,144,228,201,147,231,136,164, 65,144, 5,250,226,217,179,103,202, 59,122,253,198,161,187, -238,247,174,120,145,110,194, 45, 86, 32,117,255,226,133,210, 76,144,161, 88,190, 84,253, 45,180,111,189, 40, 33,202,142,193,123, - 23,156,105, 94, 52, 11, 0,173, 23,101, 96, 26,147, 73,135,175,233,201,185, 3,192,245, 56, 76, 62,255, 34,156,198,239,135, 12, - 0,195,167,177,240,226,179,113,140,227,138,171,205,171, 59,159, 4, 85,247, 54, 68,237, 21,184,202,103,219,189, 83, 63,223, 86, -238,248,111, 21,108, 25,245,163, 48,242,207, 48,159, 6,244,120, 70,226, 62, 4,246, 63, 58, 91,180,114,121,106,159,244,130,253, - 13,194, 24,244,173,229,184,207, 64,104,135,144,213, 69, 56, 29,192, 2,199,135, 53,248,159, 78,175,236,104, 67, 59, 75, 22, 73, - 23, 88,178,240,139, 80,188, 80,106, 45, 48,177,146, 71,198, 9,149,207,168, 81,163,142,170, 93,187,246, 93,142,203, 60,126,136, - 99, 61,143, 68,122,252,248,177,114, 84, 16,255,171, 3,193,129,135,182, 68,233,208,187,160, 57,161,113,227,198,119, 72,147,199, - 25,113, 46, 97,255,230, 41, 0,193,193,193,238,121, 69,254, 32,232,242, 64,211,253, 10,237,120,106,147, 38, 77,148, 57,132, 71, -187,108,222,188, 89, 28, 61,122, 84,249,134, 54,160,127, 92, 48,161, 25, 13,249, 28, 91,175, 94, 61, 37,159, 91,183,110, 21, 65, - 65, 65, 94, 41, 59,142,153, 81,104,238,221,187,215,205, 79,242,128, 60, 85,135,167, 79,159,242,240,115, 75,252,196, 25,129, 10, -205,128,128, 0, 37,159,172, 27,214, 83,120,234,232, 53,164,105,181, 29,191, 25,241, 0,180, 78,223,191,127, 95,172, 90,181, 74, -252,243,207, 63, 98,207,158, 61,130,147,225, 71, 31,125, 68,176,101, 85,178,165,238,212, 83, 37,200, 98, 99,105, 28,199, 71, 12, - 77,224,163, 52, 58, 94,199,143, 31, 23, 9, 19, 38,124, 98,129,123, 33, 6, 10, 72, 89,154, 98,240, 63,145, 42, 77,150,251, 87, -174,222, 9,226, 29, 82,151,211, 50,164, 74,235,122,142, 59,158,157, 0, 72,104,170,243, 13, 55, 77, 28, 44,123, 80,230, 41,212, -104,224,225, 1,121,133, 65,224,152,222, 32,201,103, 88,205,157, 99,135,224, 32,195,193,134, 29,140, 29, 79,118, 20,118, 28,210, -184,119,239,158, 2, 54, 0,110, 4,211,120, 26, 40, 60,209, 36, 45,126, 71, 94,252,142, 5,154,138, 36, 75,130, 44, 2,173, 65, -131, 6,181,154, 49, 99, 70, 43, 28,178,219,106,227,198,141,173,118,237,218,213, 42,126,252,248,182,128, 22,120,122,132,160,154, - 39,183,223,186,117, 75,180,106,213, 74,228,205,155,215, 13,164, 48,200, 30,225, 32,140, 83,219,197,134, 13, 27,148, 67,125,113, - 78, 86,164, 7, 90, 4, 88,224,161,159, 12, 85,202,103,255,181, 88,193,180,227, 95,132,212,227, 75, 20, 78,205,251, 56, 6, 76, -156, 99, 11,231, 77,213,215,160,253,135,104,243,148, 46,168, 23, 65,102,237,148,109,141,105, 76, 38,157,234,185,115,231,126, 52, - 97,194,132, 96, 30, 15,131,186, 86, 38, 30, 78,188, 12,219,183,111, 23,219,182,109, 19, 91,182,108, 17,139, 22, 45, 10, 46, 87, -174,220, 99,208,171,110, 68,147, 18, 44,130,171,223,127,246, 81,178,199, 59,255,243,249,107, 46,209,202, 6, 62, 60, 96,127,100, - 91,133, 20,246, 62,202,104,229,112,106, 61,160,149, 8,105,167,247,232,209,227, 25, 23,147,236,147,172,139, 27, 55,110, 40,188, -196,145, 36,193, 4, 95, 8, 51,249,189,127,255,253,151, 99, 43, 29,175,202,203, 77,179,100,145,244,129,234,122,254,184,114,158, -155, 37, 10,167, 13,100, 40, 94, 72, 27,210, 4, 22,205,255,129, 17, 16,211,230,115,200,231,159,127,126, 93,210,110,222,188,185, -114,198, 35,243,247,223,127,255, 41, 32,230,212,169, 83,202, 17, 73, 28,255,201, 19, 15, 64,139,210, 23,170, 8, 71, 54,108,216, -208, 77,179,111,223,190, 10, 45, 46,180, 88, 78,246,117,237,101, 5,104, 17,100,213,170, 86,205,157, 52,103,186,116,162, 43,206, -205,235,251, 85,115, 49,236,219,182, 74, 24,218,174,173, 24,211,161,189,114,106,128, 9,208, 34, 32, 28,129,115, 54,175, 73,130, - 92, 4, 18,188,177,236,251,247,239, 15, 81,118,142, 95, 86,203, 14,154,238,178,119,236,216, 81, 57, 90, 10,227,166, 50,199,177, - 29, 72, 62,146, 23,108, 15, 30,202,238,230, 39,128,176,155,102,187,118,237,196,210,165, 75,149, 62,186,111,223, 62,113,228,200, -145, 48,213,209,107, 74,211, 2, 4,120,179,162, 80, 58, 67, 41,205, 94, 0,153,179, 95,126,249,165, 82,177, 60, 58,131, 3,131, -197,162,202, 78, 29,133,234, 66,117,231,170, 19, 59, 36,208, 98, 3, 68, 71, 10, 11,208, 58,177,191,125,251,160,134, 85,191, 12, - 90,226,191, 45, 40, 83,154,108, 65, 23,198,143, 15, 58,254,221,119, 65, 71,218,182, 13,106, 88,177,209,139,231,169, 50, 7, 29, -255,241,251, 32,172,202, 79,120, 2, 90,144,164,156, 36,208, 97, 71,179, 19,120, 36, 8,128,226,126, 35,160,133,242,159, 35,240, -225, 10,135,160,213, 44,184, 58,181, 71,160,229,137, 38, 0,146, 2,228,120,166,156,252,150, 5,154, 81,169, 46, 36,192,146, 1, -167,176,183,194,196,216, 10, 96,187, 53, 38,222, 54,200,127, 27, 72,210, 90,161,156,158,108, 45, 66, 12,230,152,172,142, 80, 26, -122,251,246,109, 5,100,241, 82, 3,173, 52,105,210, 28,225,228,195,213, 41,207,151, 35, 32, 84, 75,188, 92, 60,141,124, 18,173, -130, 33,129,214,161,125,171,253, 14,237, 89,229,119, 0, 97,255,238,191,252,246, 7,252,229,183, 47, 96,165,223,158,157,203,253, - 86, 46, 30,233, 87, 36,111,170, 9, 86,129, 22,121,200, 73,144,225,216,177, 99,202, 32,206, 1, 87, 30,107,115,242,228, 73,101, -240,101,224, 69,181,141, 39,160, 5,128, 29,192,180,189,123,247, 22,101,202,148, 17,101,203,150, 21, 85,170, 84, 17, 24,140, 69, -203,150, 45, 5,192,130, 24, 54,108,152,152, 57,115,166, 2, 8, 40, 61, 0,224, 14, 48,162, 73,117, 33, 37, 89,234, 62,127,227, - 72,255,199,124,254, 26, 3,173,108,104,151,215, 8,136,120, 30, 97, 96, 96,160, 32, 31,113,228, 15,143,226, 49, 3, 91,161,218, - 39,206, 53,220, 72,137, 61,129,197,245,235,215, 21, 9, 62, 37,247, 28,235, 72,251,238,221,187,226,175,191,254, 98,221, 60, 32, -159,200,127,124,103,137,222, 24, 82, 2, 82, 44, 53, 47,207, 30,223, 36,206, 28,219, 36, 78, 31,219, 40, 78, 29,217, 32, 78, 30, - 89, 47, 78, 28, 90, 39,142, 31, 90, 43,182,173,157, 38,138,229, 79,173,173,239, 80,224,141, 15,208,247, 20, 73,150,188,122,245, -234, 37, 86,175, 94, 45,118,239,222, 29, 10,100,221,188,121, 83, 1,139, 30, 36, 48, 4, 47, 49,160,222, 10, 65, 19,224, 93,233, -215,228, 1, 23,177, 92,108,174, 95,191, 94, 84, 41, 95, 66, 52,172, 95, 71,121,110, 6,180,168, 46,252,226,139, 47, 94,172,202, - 93, 87,195, 10, 21,196,250,177, 35,197,145,249,211,197,141,213, 11,149,112,253,239, 69,226,159,145, 67,205,128, 22,199,174,119, -180,101, 31, 63,126,188, 88,177, 98,133, 2,138, 56,246,147, 7, 92,100,112,113,193,179, 47,195, 82,246, 1, 3, 6, 40,105, 57, - 14,179,238, 89,239, 28,135, 9,178,228, 98,201, 67,217, 21,126,106,243,233,235,235, 43,176,240, 85, 22, 63, 60,227,147,109,244, -231,113,189, 67, 4,179, 58,178, 66, 83,130,107,171,245,174,165, 89,189,122,117, 81,180,104, 81,241,225,135, 31, 10, 44,204, 20, - 33, 77,197,138, 21, 69,165, 74,149, 4, 1,189, 1, 63, 13,161, 5,170,189, 8, 66, 13, 85,168,232,250, 45,239, 69,152, 88, 39, -158,124, 30, 93,245,174, 42,126,151, 52,160,103, 68,167,168,134,182,252,174,204,147,146,206,240,162, 36,193, 21,202,170, 34,101, -128,180,104, 10,109,180, 24,208,208,149, 21, 46, 43, 23,170,132,219,242,185,250,238,178,227,122, 95,231, 67,209, 96,227,243,148, -200,158,146, 44,130, 44, 2, 1, 54,190,165, 73,125,196,159, 8,156, 92, 81, 81,193,210,118, 11,224,206,146,237, 22, 85, 26,199, - 59,117, 10, 26, 19, 55,105, 80, 70,132,134,239,127, 16,180,183, 92,153,160, 13,209,125,130, 54,197,136, 18, 52, 41,113,178,160, -204,239, 37, 13,106,154, 58,117,208,185, 46,223, 4, 65, 61,121,198, 4, 36,186, 1, 38,226,237,181, 17,168,110,164,218, 81,247, - 66,195, 63,199, 1,151,237, 32, 74,148, 40, 2,252, 16,200,187,128,132,141, 0,141, 18, 7, 14, 54,228, 1, 7,118,185,122,242, -120,160,173,154, 38,233, 2, 68,114,181,169,240, 85, 2, 45,254,199,132,104,149,102, 84,218,100,161,131, 41,146, 44,130, 44, 74, -179,176,194,109,141, 65,238, 76,139, 22, 45,158, 55,106,212, 72,177,167, 67,253, 60, 66,254, 31,225,247, 35,208,191,238,137,167, -176,201, 58, 66, 73, 29, 37, 90,188,180, 18, 45, 76, 72, 71,216,169, 9, 24, 56,232,114, 32, 86, 3, 49,147,250,122,109, 95, 99, -178,155,176, 31, 64,202,111,106, 39,191,217,147,191,243,155, 57,177,131,223,140, 9,237,252,166,141,105,231,247,117,205,130,187, -106,229,120,255,202, 39, 57,146, 95,249, 36,219,139, 80,250,253,216, 23,203, 38,137,177, 14,225, 59, 79,133,162,116,138,124,228, - 0,203,186,238,215,175,159,104,208,160, 1, 85,239, 2,253,135, 19,161,128, 45,156, 50,152,113, 66, 51, 0, 90, 33, 62,129,246, -248, 45, 0,148, 34,205,234,208,161,131, 64,125, 43, 32,235,211, 79, 63, 21, 92,100,113, 2,230, 68,180, 96,193, 2,101,112, 71, - 8, 70, 27,248,214, 40,159,122, 18,173, 61,115, 99,222,252,165, 83,130, 29, 37, 11,167, 93,132,176, 16,146, 24, 37,148, 44,148, -246,143, 34,224,149, 26,128,189,130, 74, 13, 1,178, 36, 96, 37, 40,226,196, 11,233, 8, 77, 18,204,192, 86,136,108,163, 13,159, -167,244,130, 19, 54,219, 60,251, 53,164,234, 55, 96,175,248,156,255,201, 71, 2, 58, 78,238, 6, 64,203, 77,143, 82,171, 83, 0, - 83,107,150,245, 23,171,151,244, 19,127, 47,234, 35, 86,254,225, 43,150,255,254,147,240,159,247,163, 88,234,215, 83, 44,158,221, - 67, 44,252,237,123,177, 96, 70, 87, 81,212, 24,104,133,200, 35,237,104, 88,190,182,109,219, 42, 32,123,250,244,233, 10,176, 32, - 48, 34, 72,151, 18, 24, 57,217, 18, 40,233, 0, 3, 73, 83, 1, 6,180,157, 98, 90,130,140, 73,147, 38, 41, 96,146, 82,106,142, - 1, 82,202,142,177, 68,220,220, 48, 78,236,154,212, 74,124, 88,172,128, 39,154, 10,109,140, 17, 65,106,144,197,223,157,234,214, - 21,155, 39,141, 22,199, 23,205,112,191,186,241,207, 66,241,207,104, 67,160, 37,243,169, 72,138, 96,107,122,133,115, 26, 15, 60, - 30, 57,114,164, 34, 37, 98,251,102,221, 19, 20,179,110,102,207,158,173, 0,130,137, 19, 39, 42, 32,209,172,236,228, 39, 23,211, - 93,187,118, 21, 63,255,252,179,152, 53,107,150,216,177, 99,135,178, 16,162, 68,143, 32,139,244,168, 97, 72,157, 58,181, 50,254, - 91,161, 73,192,247,221,119,223, 9, 74, 7,167, 76,153,162,244,107,126,135,121,101, 29, 37,204,233, 19, 34,120,131, 38,219,174, -157,122,103,217,205,242,105, 70,211, 0,139, 40,245, 70, 80,196,155, 12,242,191,230,110, 20,143,207, 43,116,239,222,189, 7,211, -151, 40, 81,130,154, 6, 79,244,116,233,200,244, 47,178,163,155,222,120,232, 98,225,248, 86,222,241, 51, 3, 78,220,190, 78,201, -142,250, 34, 34,167,116,132,192,128, 43, 91,118, 30,181, 10,131, 43,106,164, 29,173,243,165, 40, 4, 78,108, 96, 84, 23, 50,112, -130, 32,125,127, 23,208,226,187, 33, 67,134,132, 80,119,113,194,229,115, 79,182, 91, 84, 17, 18,104,173,139,234, 19,180,239,163, - 50, 65,255, 85, 40, 19,180, 45, 97,204,160,109,113,163, 4,237,136, 31, 53, 40, 32, 81,212,160,227,181,202, 5,157, 64, 56,254, - 81,126, 2,173,211,175, 96, 16,247, 33, 40,162,152,152, 29,142,128,194, 44, 80,250, 3,144,116,222, 83, 94, 61,209,100, 39,231, -247, 56, 25,203,111, 89,160, 25,133, 70,239,136,167, 0, 44, 74,178, 8,178, 96,107,113,254,167,159,126,122,206,250, 98,157,115, -194,101,135,225,192, 65,123, 42,240,244,145,167,124, 82, 13,200,182, 37, 65, 22,239,106, 32,133,137, 71, 81, 45, 50,127,242,122, - 19,128, 22,193, 67,192,182,101,126,191,142,108,227, 55,121, 68,107,191,137,195, 90,250,141, 27,210,220,175, 85,213,252,187, 62, -122, 63,246,147, 7,107, 23, 9,134, 27, 63, 53, 14, 17,202, 38,137, 30, 88, 54, 81,244, 98, 70, 60,165,116,138,124, 34,239,209, - 79, 21,213, 62, 37, 76, 4, 90, 28,136, 41, 69, 97, 96,253,112, 5,205, 75, 71,221,163, 37, 31, 3,246, 92, 7, 48,241, 60,151, -105, 57, 41,176,127,179, 29, 81,250,194,137,135, 99, 0, 86,211,207, 17,247, 32, 39, 85,163, 60, 74, 27,173,221,115,222,185,113, -239,228,144,167,151,215,165,191, 19,184,163,206,169,147,123, 38,111, 63,180,127,245,186, 67,251, 86,173, 59,184,103,213,186,255, -118,175, 90,183,115,203,162,117, 69, 11,164, 94,252, 10,129,150, 27,100,113,193, 71, 96,192,114,115, 18,227,111,242,150, 0, 20, -124,183, 11,182, 26, 99,194,187,129,201,148, 38, 5,180,209, 74,232,226, 23, 15,214,253, 23,139,170,103,180, 93,164, 4, 73, 5, -180,252,245,120, 90,188, 96,154,192,163,255,173,209, 5, 85,243,167,117, 17,115,167,116, 18,115, 38,127, 39,102, 77,108, 47,102, -142,255, 86, 20,201,151,202, 72,162, 21,130, 60, 13,223,105,127, 69, 9, 9,219, 17,129, 7,199,102, 45,200, 34, 72,146,210, 40, - 15,147,184, 2, 96,104,248,206,184, 4, 2, 4,147,108,167,178, 45, 73,251, 44,218,232, 54,174,144, 75, 60, 88,214, 65, 28, 28, -223,192, 20,104,113,113,193, 58,200,159, 41,147,104, 14,245,225,247, 88, 88,140,106,223, 78,236,153, 57, 73,156,245,159,243,127, -160,181,230, 15, 43, 64,139, 60,136, 70, 67,117, 74,150,152, 23, 74,107, 71,140, 24, 33, 70,141, 26,165,244, 25, 2, 12,182,121, -140,123,162, 91,183,110,162,125,251,246,202, 2,208,172,236,164, 73,126,178,221, 80,146, 69,144,197,121,145, 96,136, 82,123,206, -103,108, 91, 92, 80,150, 47, 95, 94,249,134, 21,154,204, 39,213,154, 4,229, 4, 89, 4,239, 28,215, 57, 30,115, 44, 38,208,178, - 83, 71,178,236,146,102, 7,223, 9,162, 88, 93, 95,145,239,147, 94, 34,125,133,238, 33, 66,201, 6,131, 44,151, 93,230,147,210, - 44,128, 25, 1,115, 33,165,156, 48, 71, 81, 36, 89,148,146, 87,173, 90, 85, 89,116,235,241, 83, 7,139,184,219,171, 26, 80,241, -183, 25,208,146,113,112, 47,164, 6,106,170,231, 10,208,210,251,111, 49,190, 34,209, 82,209, 80,190, 99,120,105, 11, 71, 73, 22, - 27, 0, 43,145, 8,149, 43, 30,118, 26, 6,234,218, 33,197, 80, 86,184, 84,151,241, 61,159,177, 67, 17,132,225, 35, 90, 3,110, -229,187,220, 89,200,134,192, 70,198, 64, 73, 22, 65,150,188, 40,237,161, 20,102,254,252,249, 74, 99,218,180,105,147,162,127,230, - 32,135,149,135,161,145, 60,129,214, 31,181,106, 6,141,133,244,106,124,172, 40, 65, 19,226, 64,138, 5,144, 53, 57,126,148,160, - 41, 9,163, 4, 77, 75, 28, 53,104, 70,178,168, 65, 51,147, 71, 13, 90,152, 51,137, 93,160,101,102, 24,175, 53,128, 55,228, 49, - 58,211, 57,150,155,188,163,132, 9, 13, 93,145, 62, 97,194, 18,216, 65, 35, 0, 54, 68,246,236,217, 5,236, 67, 4,236,227, 20, - 16,106, 6,180, 36, 77, 86,180,107,101, 68, 35,114,133,103, 18,104, 97, 37,168, 72,201,172,210, 36,208,194, 32,163,216,100, 81, - 93, 72, 73, 22, 68,213, 10,200,226, 32,193, 65,233,235,175,191, 86, 6,102,170,146,217, 54, 80, 63, 30,129, 22,164, 1,255, 2, -108, 29, 84, 7, 62,147,204,194, 32,186,137, 96,140,224, 74, 6,148, 77,187,235,208, 99, 27,126, 29, 95, 22,130, 42,112,219,134, - 69,126, 35, 7, 53,245,235,215,163,182, 95,239,110,159,250,253,216,169,166,223, 39,121, 82,156, 90,245,203, 15,162,111,206,248, - 74, 8, 90, 61, 75, 92,174,157,210, 29,110, 14,250, 66,148, 77,242,238, 18,163, 50, 73,160,197, 9, 17,210, 66, 5,252,204,153, - 51, 71, 89,233,177, 63, 18, 96, 17, 20,113, 48,103,176, 8,180,248,185, 4, 48,200, 62,134, 85,120, 48, 7,114,218,203,177,158, -185,202, 7,240, 22, 99,199,142,165, 26, 49, 24,109,152,192, 33,129, 39,158,203, 93,135, 67, 32,193,186,184,163,249,209,237,139, - 42, 30, 92, 62,187,201,118,191,201, 29,215,205,154,212,126,221,111,227,219,175,155, 62,190,221,186,105,163,191, 94,247,235,232, -182,235,138,228,251,224,149, 1, 45,140, 33,171, 57,222, 17,100,177,188,224,193, 35, 9,124,248,155,207, 8,186, 40,145,135,212, - 88,109, 30, 16,166,102, 71,163,119, 78, 72,234,139, 96,214,165, 58,164, 65,124,168,171, 88,254, 52,129, 7,118,255, 37, 8,170, - 38, 13,111, 37, 70,255,252,165, 24, 49,224, 11, 49,180,111, 99, 49,216,183,190, 24,248, 99, 93,129, 54, 38,124,187,125, 42,126, -236,252,177,248,176, 72,218, 7, 5,243,164,184, 87, 32,247,251,247, 10,229, 73, 97, 40, 25,231,230, 28, 2, 3,182, 27,105,239, -195,197,153, 84,111, 18,112,168, 39,112,230,217, 4, 24, 68,101,251,228, 88, 39, 85, 79, 4, 49, 77, 62,173, 40, 90,212,174, 32, -190,172, 85, 70, 52,169, 94, 92, 52,172, 84, 64, 52,173,156, 87, 44,243,173, 41, 30,205,111,100, 10,180, 64,243, 50,213,121,189, - 32,105,221, 1,233,210, 78,132,189,144,236,156,156, 63, 91, 81, 23, 82,146,197,160,168, 14, 71,153, 74,180,200,223, 40,178,236, - 4,151, 61,123,246, 84, 0, 22,109,170,216, 22,164, 81, 60,165,186,148,194, 81,237,101,165,236,164, 73, 91, 92, 26,172,115, 94, -164,100,176, 86,173, 90,162,112,225,194,138,105,132,218, 38,153,115, 40,193,146, 25, 63, 73,147,249,225,120, 75,141, 18,231, 97, -166, 35,128,149,160,144, 64, 75, 2, 97,171,249,212,210, 76,247, 81, 55,145,254,163,239,221, 52,101,189,143,156,249, 98, 33,224, -141,124,154,181, 37, 43, 64, 75, 13,142,228,111,213, 61,132, 36,202, 5,132,148,254,132,223,229,165, 68,138,119, 9,146, 12,232, -133,162,163, 1,118,146,166, 27,104,153, 14, 6,218,194, 81, 29, 72,198,178,177,112,160, 1,129,189,152,128, 31, 82,226, 64,155, - 16,252,191,203,103, 8,199,138, 23, 47,174, 52, 74, 54,168, 78,157, 58,241, 93,103,189, 15, 82,221,164,150,144, 81, 93,200,160, -190,106,214,172, 41,180,129,104, 29, 34, 73,143, 64, 11, 52,130,144,215, 32, 52,192, 32, 52,238, 32,128,190, 32, 52,196, 32, 12, - 24, 65,104,140, 65,232,240, 65,152,124,130,144,127, 91, 64,203,204, 48, 94,199, 0,222,144,215, 18, 20,113,240,177, 18,216,217, - 33,177,242, 40,209,242, 68,147, 54, 81, 4,175,156,116,229,247,172,208,164, 11, 7,238, 50,196,170, 73,177,201,162,186, 80,130, - 44, 14, 32, 4,193, 20, 97,115,181,198,193,153,147, 61, 36,156, 30,129,150,105, 3,124, 67, 35, 16,104,109, 88, 51,223,111,224, -143,245,253,186,182,171,230,247,224,222,149, 80,161, 89,201,188, 87,236, 2, 45, 74,167,216,111, 8, 12, 24, 8,166, 62,249,228, - 19, 2, 94, 5,192, 83, 69, 53,121,242,100, 69, 66, 40,251,156, 5,137,150,172,133,100,160,113,102,218,180,105,138,132,131, 43, - 94,130, 56,170,128,168, 82, 68, 63, 62,131,136,201,204,170, 76, 74,167,138, 22, 76,189,120,207,142,229, 10,168, 26,216,171,254, -186,190, 61,234,172, 3,224, 92,215,179,211,199,235,186,127, 87, 99, 93,215,118, 85,214,117,108, 83,113, 93,169, 34,105,255,197, -102,128, 53, 5,243,166, 92, 83, 56,127,170, 21,102,244,189,249, 30,160, 63,144, 32,135, 70,224, 24,239, 46,129,182, 50,179,184, -128,207,106, 62,227, 59,142,113,232,147,103, 45,124, 59, 30,226,124,143,192,197,196, 18, 85,152,138,223,202, 14, 67, 74, 37,164, -122, 82,222, 41,221,194,251, 1,122,244,169, 10,220,179,253, 79, 49,125,220, 55,162, 95,207,218,226,242,185,189, 74,184,164,132, - 61,226,210,217,255,135,139,103,119,139,139,103, 94,132,189,219,230,139,252,185,146, 27,142,159,156,196, 57,142, 17,196, 80,242, -162, 7,178,168,230, 82,239, 20,244, 48,225, 50,235, 81, 8,180, 8, 28,217,246, 8,226, 42,127, 88, 80, 60,221,241,171,120,186, -117,156,120,178,225, 23,241,228,159,222,226,201,138,206,226,209,226, 54,226,241,242, 78,226,241,146, 54,166, 64, 11,237,247, 18, - 23,144, 67,218,180, 17,103,177, 24, 63, 51,111,158,184,128, 5,192,149, 37,139,197,213, 63, 23,139,107, 43, 94, 4,254, 94, 53, -220, 18,208,242,145,101, 39,192,164,234,253,179,207, 62, 19, 53,106,212, 80, 64, 85,169, 82,165, 68,193,130, 5,149,197, 47, 23, -194, 80,135,154,129, 13,165,236,116,227,192,249, 80,238,132, 36,200,162, 10,149,252,165, 52,231,155,111,190, 81,198, 76, 2,187, -185,115,231, 42,194, 9, 51,126, 50,159, 4, 40, 4, 88, 7, 15, 30, 84,180, 34, 20,130, 72,144,197,119, 4, 90,118,234, 72,143, -166,148,100, 73,112,109,183,222,213, 52,177,235, 82, 87,146, 69, 73, 23,231,120,170,170,245,192,155, 21,160, 69,192,131, 80, 72, - 3,124, 72,206,109,191,133,186, 80,255,151, 54, 87, 37,100, 28,249, 94, 19,207, 80,194,165, 77,231,250,175,216,140,169,104,121, - 30, 26,180,122, 81, 9,180,216, 0, 49,176, 60,226,127, 72, 68, 20, 67, 68, 54,118, 12, 20,244,119,149, 13,131,238, 60,105,224, -183,112,225, 66,218,135,108,197,115, 58,126, 11,117, 65,226,242,148,226, 99, 45,192, 82,255,167,161, 61,197,195,156,192,217,233, -169,194, 96, 35,194,247, 13, 7, 10,228,225, 52,129, 22,242, 26,132, 70, 24,132,116, 65, 44, 56, 65, 22, 86,101,202,111,130, 44, -136,109,131, 64,203, 22,208, 50, 51,140,215, 49,128, 55,100, 52, 6,115, 69,117, 40,237,176,224,242, 64,145, 62, 65,146, 35,242, -229,203,167,172,120,164,168,149, 29,221,101, 40,168,221,158, 28,130,190,164, 73, 9, 25, 37, 99,180,203, 41, 86,172,152, 34, 74, -150, 64,139,180, 97, 88,174, 12, 30, 86,104,210, 79, 22,129, 22,234,160, 53, 13,223,105,147,197,213, 45, 37, 89, 82,210, 72,195, -104,174,172, 56, 96,112,146,112,129,113, 11,243,207,219, 21, 5, 18,133, 9,171,255,154, 13, 41,214,199,126,109,154,126,168,128, -172,125,155,199,133, 8, 13, 11,166, 11, 51,208, 34,144, 98,224,228, 8,213,188, 98,164,206,254,194,192,186,230,128, 47, 37, 39, - 58,198,177,158, 42, 35, 53,250,220, 5, 26, 49, 3, 48, 41,118, 59,156, 24,208,135,217, 30, 83, 91,169, 69, 55,208,130, 74,112, -199,230,165,235,198,255,210, 98, 93,183,246,213,214, 61,184,119,213, 99, 56,127, 98,253,186,252, 57,147,235, 74,117,172,124, 55, -140,113, 26,130, 63,167, 49,150,236, 70,250, 76, 4, 70, 42,160,181,132,207, 48,182,249, 83,170,130,223,141, 44,124, 99, 0,199, - 73,237,197,133, 10,104, 80,226,159, 14,129,160,139,180,101, 32, 40, 35, 56, 35, 72, 11,117, 81, 21,184, 99,211, 18, 49,238,151, -175, 68,183,111,171, 9,240, 81, 28,219,247,187,105, 56,180,115,134,200,151, 35,169,225,248, 73, 96,192, 5, 24, 65, 36,219,145, -156,192,169,230, 98, 59,210, 78,182,122,147,163, 54,179, 4,245, 28,235, 88, 94, 46,246,168,142,171, 88, 40,163,168, 85, 60,163, - 56, 52,185,169,120,188, 0, 1, 0, 43,248,230,255,121,100, 2, 54,124, 36,208,226,120, 94, 15,134,213, 12, 93,234,213, 19, 87, - 48, 46, 49, 44,134,157, 34,159,241,190,106,168, 53,160,165, 46, 59, 85,240,148, 8,113, 92, 86,187,160,224,247,120,201,187, 89, - 62,169,226,100,159,163,180,137,243, 23,141,193, 37,136, 37, 48,154, 7,128, 72,213, 25,165,196, 92, 32, 17,112,155,209,148,249, -164,214,136,227,173, 94, 29, 17,104,169,175,176,208,148, 64, 43,172,245,110, 37,159, 90,215, 30,218,124, 90,177,209,114,129, 27, -183,196, 73,130, 29,214,145,171,158,244,108,175, 66, 72,168,180, 18, 45, 15,233, 66,216,132,105,109,180,108, 1, 45,157,126, 61, -153, 6,145,108, 32,106,187, 25, 54, 12, 54,160,117,235,214,113,101,123,142, 3, 49,117,249, 68,218, 80, 81, 81,202,197, 1, 68, -247, 2, 24, 80, 36, 90,158,128,150,158, 68,139,141, 30, 21,104, 10,180, 48, 80, 40, 82, 44,228, 39, 8, 18, 48, 69,178,133,134, -173,252, 70,227, 84, 64, 22, 58,126, 16, 86,253, 92,145, 26,218,150,104, 50,111,102, 24,239,209, 0, 94, 77, 75,130, 34,174, 22, -172, 4,174, 4, 49,184, 92,244, 52,168,123,162, 73,160, 69,222,177,254,228,247,172,208, 36,208,162,207, 44,128,214, 86,224,103, -235,166, 77,155, 62,101,122,170,145,104,111, 32,141,175,217, 54,216,233, 41, 45, 67,253,120,148,104,153, 57, 36,197,251,237,160, -113, 12,147,221, 49, 0,198, 99,104, 75,199, 48,209,187, 29,154, 90,152,216, 94,203, 40,249,243,188, 63, 97,229,178, 25,126,157, -218, 84,244,107,244,105, 65,175, 3, 45, 2,106,246, 41, 26,195, 19, 72,115, 98,147,190,117,164,175, 30,105, 67,105, 19,104,145, -159,153,177, 91,244, 6,193, 53, 37, 45, 72,127,139,207,172, 50, 90, 2, 45,170, 4, 55,175, 93,176,238,151,190,141,215,125,253, -101, 89, 5,100,237,223, 50,222, 99,120, 5, 64, 75, 91, 44, 45,208,178, 90,108, 25,111, 13, 39, 61,105, 43, 39,239, 28, 83, 93, -190,178,180,244,232,141,220,227, 85, 56,111,202,192, 77,107, 23,136, 95,250, 52, 18,109,155,149, 81,128, 22, 64,187,165, 96, 6, -180, 36, 88, 87, 79,224, 4, 95, 4, 89,106, 23, 49,114, 34, 55,155,196, 9,180, 8,176,164, 27, 7,210,104,142, 13, 21,126, 63, -126, 38, 30,251,127, 43, 30,205,254, 20, 32,235,148,216,117,228,138,104,208,235, 79, 37, 88,160,169, 72,180,228,100,106,118, 55, -112,239, 16,130,199, 4, 6,178,236,220, 72,132,141, 64,110, 64, 37,203,170,254,142, 21,144, 73,160,197, 69, 14, 53, 9, 4,171, -172,243,202,149, 43, 43,255,169,122,166,164,139,207, 9,154, 40, 49,230, 98,221,172,236,234,124,202, 58, 90,183,249, 31,241,195, -144, 78,162,209,183,181, 68,217,218, 5, 20,137,150, 93,160,165,173,119, 9,180,100,189, 47,248, 59, 32,204, 52,225,235, 44,132, - 77, 22, 37, 89,148, 22,202, 57,222, 72,162,229,169, 19, 32, 51,220,245,167, 72,179, 24, 79,245, 95,187,251, 79,251, 95, 27,159, - 52, 10, 35, 20,115,209,147,146, 48, 51, 58,252,190, 58, 13,165,106, 33,242,100,214,143,181,239, 51,208,160,145,232,155, 98, 74, - 54,112,138, 44,201, 36, 78,184,156, 92, 33, 78, 13,230,123, 78,190,240,195,194, 6, 90,223,211, 71,160, 94, 82,108,180,216,129, -141,252, 84, 81,106, 34,237,178, 8,234,228, 36,129,188,120, 4, 90,136, 23, 4, 41, 76, 16,164,107,138, 20,235,171,175,190,122, - 4,117,135, 34,197,130,234,235,209, 31,127,252, 17,132,198, 19,132, 85, 86, 16,242, 74, 27,139,158, 54,192,150, 93,222,233,198, - 7,128, 80,118, 29, 74,137,131,217,157,141,221, 12,104,121,162,201,141, 5,228,181,244,205, 37, 87, 41,102, 52,233,140,148,142, - 73, 49, 80,209, 57,105,107,216,228, 60,101,135,148, 62,117,216, 22,176, 27,209, 13,178, 88, 79, 88,165,123, 4, 90,102, 14, 73, - 49,249, 28,145,245,205, 58,167, 97, 60, 93, 66,120,133,241,175,144, 72,254, 92,239, 79, 88,186,104,170, 95,203, 47, 74,249,125, - 92, 57,155,215,128, 22, 65, 19, 71, 64, 26,190,195,217,162,248,248,227,143,149,129,155, 82, 4,233, 20, 82,235, 24,210,108, 48, -215, 99, 19,164,216,138,143, 33, 78, 22, 0,191,116,113, 96,249,146, 64,171, 80,222,148,139,215,174,158,187,174,111,247,207,214, - 53,169, 83,232,109, 1, 90,202,206, 15, 2, 44, 26,186,115, 50, 45, 82,164,200, 51, 48,111, 53, 66, 70, 23, 19,185, 67,175, 9, -220,104,156,193, 4, 68, 13, 65, 51, 79,204,133,157, 85, 32,248, 40,250,124,255,153,104, 92,187,160,215,128, 22,129, 1,251, 55, - 39,112, 9, 14, 60,129, 44, 43, 96,131,237, 83, 74, 46,216, 14,191,194,238,215,185, 4, 89, 80, 17,222,152, 84, 9, 54, 89,141, -149, 9,156, 0, 43, 87,195, 25, 74, 48,107,159, 28,183, 56,246, 84, 45, 91, 75,244,248,122, 64,168,176, 98,209, 63,130,129,239, -190,172,243,181,145,123,135, 16, 44, 86,151,253,197,188,253,127,201,149, 26,104,169,159,155,229,147,106, 83, 74,180, 8,166, 36, - 31,105, 72,239,231,231,167,128, 44, 41,177,225, 78, 71,204, 83,202,174, 94, 51,154,218, 58,154, 48,115,164, 24, 48,166,151,232, - 59,178,135,168,210,184,164, 72, 87, 44,129,200, 94, 38,133, 45, 80,164, 87,239, 90, 35,248, 82, 13,127, 14, 55,205,240,182, 37, -203, 3, 78, 36,142,152, 1,121,159,140,176,215, 21,214,225,222, 22, 42,138,191, 97, 92,253,148, 58, 88, 2, 35,238,212,192,243, -233,102,229, 68, 71,185,131, 9,245, 41,165, 83, 4, 78,248,255, 20, 29,242, 41, 38,212, 96,110,171,213,147,102,241, 25, 47,198, - 53,162, 79,213, 33, 12,127, 21, 73, 22, 36, 47,138, 20,139,192,170, 79,159, 62,138, 20, 11, 13, 59, 8, 70,246, 65,232,240,180, - 62,101,156, 91, 16,221,210, 59,243,122,179, 60,107,222, 75,195,120,203, 6,240,234,244, 4, 69, 28,116, 8,160,172, 4, 78,154, -102,160, 40, 34,104, 66,146,212, 12, 82,192, 22, 12,168,175, 22,220,241,201,173,205,224,167, 24, 56,112,160, 2,178,248,159, 96, -155,224,200,165,142,244, 8,180, 48,144,120,116, 72,138,114, 42,187, 14,105,239, 71,245, 41, 13,177,233, 18,194,102,253,188,118, -209,243,231, 72, 54,241,223,213, 75,253,122,247,104,225,247, 67,215, 70,126,247,239, 92,242,138,234, 80, 2, 45,233,189, 91,110, - 48, 49,186, 91,153, 28,245,152,151, 63,127,126, 5,104,209,136, 55,172, 64, 11, 54, 87,139, 87,173,152,181,174, 59,212,134,159, - 86,205, 25,233,128,150,107,167,225, 18,240, 71, 29, 20, 91, 43, 15, 13, 78,145,136, 17,104, 81, 26,200,182,205,190, 66,187, 57, -172,236, 31,102,202,148,233, 40, 0,242, 67,170,122, 57, 38, 80,165,132,190,236,209,246,171, 96,238, 20,129,224,163,248,190,125, - 53, 81,171, 74,118,175, 3, 45, 53,200,162, 84, 84, 79,146, 37,103, 93, 51, 96, 32,219, 39,227,255,240, 67, 79, 49,239,199, 79, -197,227,133, 95,138,201, 95,229, 18, 65,227,138,136, 71,191,125,108, 27,104,225,155, 10,208,106,220,168,147,152, 60,225,223, 80, -225,223, 53, 7, 5, 3,223,253,208, 99,162, 45,160,197,178, 19,104,153, 5, 43,253, 72, 2, 45, 53,192,160,244,159,234, 66,130, - 47, 2,173, 46, 93,186, 40,139, 35, 74,180, 40,149, 54,227,167, 4, 69,178,142, 8,174,138,127,146, 83,148,172,149, 91,100, 43, -155, 66, 36,207,247,174, 24, 63,115,120,152, 64,145,186,222, 37,208,146,132,236, 74,180,212,249,164,107, 25,150, 89, 45,201,146, - 82, 44,117, 70,205,202,254,218, 13,234, 47, 49, 67,223,115, 7, 18,141, 67,169, 86,224,142, 54, 76,206,199,105,199,197, 35, 58, -144, 15,195, 99,104,244,242, 8, 9,202, 19,118,108,173, 93,150,166, 50,212, 64, 43,132, 99, 64,164, 63,141, 1, 45, 8,187, 67, - 20,213, 33,164,101,138,244,138,119, 74,186,176,194, 87, 0,150, 54,192,151,149, 90, 53,101,234, 12, 83, 26,198,219, 48,128, 15, - 65, 19, 62, 83,206,113,149, 71,255, 57, 28,116,121,247, 20, 24,151,118, 9, 26,158, 69, 56, 77,109, 29,209, 79, 22,119,176,113, - 99,132,180,201, 82,131, 44, 74, 80,208, 89,180, 64, 43, 68, 62,205, 28,146, 66, 5,122,132, 3, 59,237,243, 40,209,228,247,116, -220, 59,152,214, 81, 24,250, 64,132,210,204,147, 61, 73,139,170, 31,229,153, 25,120,233,180,223,237, 27,167,253, 86, 45, 27,237, -183, 96, 70,143, 16,225,179,220,169,220, 54, 90,220,109,200,221,135, 58,187, 14, 67,228,147,131, 19,251, 7,219, 15, 39,115,179, -182,100, 48, 65,152,150, 93, 13,180, 32,193,182, 34,209,114,211,148, 18, 45, 0,132, 37,155, 55, 44, 95,215,167,103,203,117,189, -186, 53, 94,119,255,238, 37,187,170, 67,211,124, 70, 64,189,247,164,119,112,170,159,244, 60,240, 83, 98, 65,131,118, 15,125,211, - 13,180,208,127, 30,114, 55, 53,109, 89,217,239,229,174, 43,130,100, 78,198,124, 78,191, 72,112, 24,187, 82,167, 28,238,178, 67, - 58,122,101,211,250, 63, 69,239,158, 45,196,143,221, 26, 9,128,118, 75,106, 67,170, 23, 53,170,195, 16,252, 36, 48,160,250,153, -121, 99,126,204, 64,150,149,182, 36,219, 39,227, 86, 44,154, 67, 60,158, 87, 95, 76,250, 50,187,200,153, 35,187,216,209, 37,173, -120, 48, 36,157,120,126,229,160,153,234, 80,219,230, 47,208, 76,197, 8,104, 45,247,223, 35, 24, 76,128,150, 97,217, 9,178,212, -146, 43, 27, 18,173, 16, 52,169, 54,101,221,178,141,112, 28,163, 20,171,115,231,206,138,173, 35,165,206,148,100, 81,128,192,121, -196, 3,112,245, 88, 71,171,215,175, 16, 69,107,102, 19,197,106,230, 16,159,182,172, 40,182,239,217, 28, 2,100, 89,169, 35,189, -122,215, 2, 45, 45, 81, 29, 80, 20, 17,109, 41, 12,221,249, 13, 76, 2,137,212, 94, 14, 14, 52,158, 36, 66, 87,175,124, 56, 40, - 97, 0, 82,123, 94, 55, 29, 36, 97, 51,245,132,131, 15, 85,147, 20, 95, 83,140, 45,105, 74,137, 22, 38, 98,143, 64,139, 32, 10, - 59, 30,131,170, 85,171, 22, 4, 49,124, 16, 86, 11, 65,216,237, 17, 4,177,108, 16,118,146, 40, 32, 12,103, 58, 5, 53,107,214, - 44, 8, 82,154, 19, 46,144,165,246, 87, 99,154, 79,105, 24,111,195, 0, 94,219, 8, 55,129,103,161,207,158, 8,213, 69, 94, 60, -128, 29, 28,165,126, 90,169, 91,132,211,212, 54, 89,128,231, 71, 92,117, 25,129, 44,230, 21,171,113,143, 64,203,204, 33, 41, 15, -145,102,253,151, 44, 89, 82,217,237,195, 21,254,155, 0,180,200,203,124, 57,147,117,131,157,210, 28,248,212,154,147, 47, 71,178, - 80,225,195,247, 99, 41, 64,203, 5,174,148,187, 25,208,130,196, 96, 35,140,104,159, 26, 52,157, 80,143, 25,151,105, 60,129,118, -189,161, 10, 27, 41, 20,137, 22,119,152,162, 95,135, 9,104, 21,200,245,126,215, 26,149,243,175,190,121,237,210,186, 91,215, 79, -175, 3,216, 92,247,251,204,158,186, 97,169,223, 79,235,106, 86,206,249, 79,209,124, 41,167,169,242, 99,218, 55,195, 48,204,154, -209,140, 15,126,253, 7,201,120,168,157,129, 4, 95,148, 68,233,216, 90,169,105,142,160, 61, 36,205, 42,144,183,223, 16,166,176, - 93, 83,250, 79,251, 86,110,205,231,157,155,127,240,156,199,240,204, 71, 72,226, 9,104,229,203,153,124, 82,141, 74,249, 30,221, -184,134,163, 96,174,159, 22,224,163,248,125, 70, 15,143, 97,137,223, 79,162,102,165,156,143,139,228, 75,185,215,136,159,156,112, -165, 73,135, 52, 94, 55,107, 87,102, 19,174, 26,104,209, 37, 72,245,226, 89,176, 99,181,189, 34,205,105, 93, 44,150, 8,234, 19, - 95, 60, 28,147, 79, 60, 15,220,111, 25,108,128,166, 2,180,190,108,218, 93,145, 88,105,195,224, 65, 51, 5,131,124,110,225, 8, - 30, 30,139,230, 46,187, 90,154,165, 46,191,246,185, 89,217, 9,180, 56, 15,114,211, 19,125, 72,113, 19, 9,213,134, 4,178,148, - 96, 81,210, 35,253,166,217, 1, 90,222,174, 35,189,122,247, 6,208,178,146, 79, 74,182,194, 98,163, 21,134,126, 30,121,147, 96, -229, 53,131, 13, 94,138, 28,185, 26,146,129,210, 8, 12, 64, 60,140, 85, 94,102, 3,154, 15, 84, 84, 79,216, 8, 41, 22, 38,112, -211, 91, 65, 66, 26,100, 8,180,120,164, 14,210, 7, 45, 91,182, 44, 8, 91,209,131,160,206, 12,194, 89,108, 65,216, 5,169,168, - 16,177,187,195, 29,104,183, 5, 85,152,199, 35,120, 60,212,140, 52,140,183,106, 0,175, 45,123, 92, 76, 86, 91,216, 81,173, 4, -116, 88,238,224,140, 99, 50, 57, 70, 4,205, 16,159,164, 51, 82,214,181, 52,124,151,234, 66,245,121,101,168, 31,143, 64,203,204, - 33, 41, 15,157,230, 38, 11,174, 0,229,245,166, 0, 45,179,158, 78, 79,240, 4, 90,240,155,117,134,113,121, 55, 3, 90,136, 22, - 27, 64, 96, 29,165,164, 86, 2,227, 50,141, 93,160,197,227,104,176, 10,127,142,250,161,243,203,210,102,101,193,251, 80, 18, 45, - 74,182, 0, 54, 7, 23,205,159,118,109,209,130,105,215, 2, 48, 24,133,127,105, 4, 95, 24, 32,139,105,236,140, 33, 22,242,165, -141, 98, 58, 46, 33, 65,124, 4,218,114, 46,209, 9, 60,143, 48,157, 7,126,166, 35, 16, 83,237, 48,100, 84,154, 30,116, 39, 45, - 24, 93,239,192,125, 17,194, 96,215,115,163, 34,132,200, 39, 36, 83, 43,138,228, 75, 29, 92, 36,127,154,231,121,115, 36,243, 24, -192,243,103,148,100,105, 64, 22,191, 19, 74, 2, 35, 15, 40,214, 59,131, 80, 15,116,153,129, 13, 53,208, 82,167,167,148,158,134, -225, 51, 62,143, 45,130,250, 37, 22, 65,125,227,139, 7,163,242, 40,193,140, 38,207, 45,228,188,163,117,137,225,233,191,217,161, -210, 4, 69,178,236,224,139, 87, 36, 90, 84,155, 82, 80,192,147, 63, 40, 33, 36,168,166, 11, 7,238, 46,164, 6,136,238, 30,184, -112, 85, 95,102,101, 87,231,211, 91,117,164, 71, 51,188, 64,203, 75,249, 12, 67,119,126, 51,147,164, 69,177,230, 96,167,216, 62, -128,174,125,104, 80,251,112, 2,250, 94, 72,137,246,226,185, 22,132,152, 14,104, 24,140,238,208,125,131,214,118, 11,141,239, 41, - 36, 37, 79, 9,178,224,203,132,198,162,242, 10, 65, 19,187, 25,191,130,250,240, 4, 61,190,171, 3,158,159,150, 1, 82,179,211, - 12, 4, 89, 0,118, 95,233, 84,139,105, 62,195, 80,149,111, 4, 77,212,205,117,250,201,162, 11, 7,238, 46,164,225, 59, 93,126, - 80, 93, 72, 73, 22, 65, 22,164,125,218, 35,120, 66,148,221,204, 33, 41,104,254,139, 58, 54,116,104,234,226,253, 27,193, 79,109, - 59, 42,155,244,221, 25, 18,100,201,119,252, 95, 54,113,244,145, 70,109, 62, 12,109, 81, 47,137, 41, 63,177,136,185,128, 62,195, -115, 77,181,128,223, 20, 24, 88, 57,207,208, 83,156, 87, 93,246, 48,240,216,148,159,175, 35, 77,244,235,157, 4, 7, 12, 86, 22, -128,140,131,113, 64,123, 96,117,136,178,243,189, 85, 90, 50,158, 25, 77,140,219,251, 48,145, 95,177, 19, 80,182, 93, 26,158,135, -200,103,100, 41,123, 68,228,243, 53,166, 25,134,110,226, 36,137,148,131,143,151,170,205, 41,187,151, 24,249, 38, 3, 45,139, 44, -122, 85,109,201,212,237,128,167,137,204, 98,217,204,162,189,170,178,155,229, 75,251,222,201,167, 93,142,121,142,239,240,243,237, -228,167,119, 75,253,150, 80,115, 58,139,119, 43,218,225,167,195, 79,111,113,192,105, 75,222,226,228, 11, 58, 14, 63, 29,126,122, -139, 3,111,115, 91,242, 22, 15, 95, 59, 58,172, 84,189, 96, 39,163, 70, 52, 60, 61, 55,163,239,208,212,175,151,176,214,151,195, - 79,135,159, 86,219,128,211, 55,141, 57, 96,149,135,234,120, 14, 63, 29,126,234,113,224,109,110, 75,146, 31, 97,157,207,204,250, -212, 91,245,254,109, 70,230, 78,217,189,219,212, 29,126, 58,252,244, 22, 7,156,182,228, 45, 78, 58,210, 60,167, 45,121,183, 45, - 57,212,194,192, 1,167, 17,134,129,105, 30,146, 56,252,116,248,233, 45, 14, 56,109,201, 91,156,116,192,134,211,150,156,182,228, - 93, 14, 56,212,108,113,192,233,128,182,216,101, 26,217,225,167, 41,139,108, 69,112,248,105,139, 93,166,145, 29,126,154,178,200, - 86, 4,135,159,182,216,101, 26,217,225,167, 41,139,108, 69,136, 8,126,218,202,128, 19,217, 89,229, 69, 68, 35,116,104,122,183, -103, 57,252,116,248,233, 45, 14, 56,109,201, 91,156,116,230,142,183,185, 45,121,183, 21,189, 37,212,222,230, 6,227,148,221,187, -141,220,225,167,195, 79,111,113,192,105, 75,222,226,164, 3,138,156,182,228,221,182,228, 80, 11, 3, 7,156, 70, 24, 6,166,121, - 72,226,240,211,225,167,183, 56,224,180, 37,111,113,210, 1, 27, 78, 91,114,218,146,119, 57,224, 80,115, 56,224,112,192,225,128, -195, 1,135, 3, 14, 7, 28, 14, 56, 28,112, 56, 96,153, 3, 60,236, 83, 6,203,137,156,136, 14, 7, 28, 14, 56, 28,112, 56,224, -112,192,225,128,195, 1, 47,113,224,141,198, 34, 44,156,151,248,228,144,113, 56,224,112,192,225,128,195, 1,135, 3, 14, 7, 28, - 14,216,230,192, 27,141, 69, 28,105,150,237,246,224, 36,112, 56,224,112,192,225,128,195, 1,135, 3, 14, 7,188,200,129, 55, 26, -139,188,209, 40,210,139,141,192, 33,229,112,192,225,128,195, 1,135, 3, 14, 7, 28, 14, 68, 12, 7,222,104, 44,242, 70,235, 69, - 35,166, 61, 56, 84, 29, 14, 56, 28,112, 56,224,112,192,225,128,195, 1, 47,114, 32,146, 99, 17,154, 96,169,205,176, 28,147, 44, - 47,182, 13,135,148,195, 1,135, 3, 14, 7, 28, 14, 56, 28,112, 56,240,118,114, 64, 2, 42,163,251,219,201, 21,167,212, 14, 7, - 28, 14, 56, 28,112, 56,224,112,192,225,128,195, 1, 47,114, 64, 43,205,122,105, 18, 45,199,145,157, 23,107, 17,164, 28,126, 58, -252,244, 22, 7,156,182,228, 45, 78,190,160,227,240,211,225,167,183, 56,240, 54,183, 37,111,241,240,173,162,243, 54, 55, 24,167, -236,222,109,234, 14, 63, 29,126,122,139, 3, 78, 91,242, 22, 39, 29,144,233,180, 37,239,182,165,200, 78, 77,218,105,189, 52,105, -150,179,202,243,126,147,113, 58,181,119,121,234,240,211,225,167,183, 56,224,180, 37,111,113,210, 1,111,111,115, 91,242,110, 43, -122,185,212,180,224,234,165,129,173,183,185,193, 56,101,247,110, 35,119,248,233,240,211, 91, 28,112,218,146,183, 56,233,128, 34, -167, 45,121,183, 45, 69,102,106, 14,208, 50,169, 61,167,179,120,183,121, 59,252,116,248,233, 45, 14, 56,109,201, 91,156,116, 64, -145,211,150, 94,255,182,228,221, 28,190,124,106,142,234,208, 3,207,157, 14,232,221, 6,233,240,211,225,167,183, 56,224,180, 37, -111,113,210, 1, 90, 78, 91,122,253,219,146,119,115,248, 26, 81, 99,227,211, 11,118,178,104, 68,195,211,115, 51,250, 14, 77,253, -122, 9,107,125, 57,252,116,248,105,181, 13, 56,125,211,152, 3, 86,121,168,142,231,240,211,225,167, 30, 7,222,230,182, 36,249, - 17,214,249,204,172, 79,189,138,247,101,241, 81, 74,180,228,221,177,209,210,212,130,179,210,241,110,179,116,248,233,240,211, 91, - 28,112,218,146,183, 56,233, 72,180,156,182,244,250,183, 37,239,230,240,229, 82,211, 58, 44,125,105, 95,119, 26,182,119, 89,253, - 42,248,249, 14,138,192, 96,116,233,189,127, 21,249, 12, 11,167,157,124,134,133,107,158,165, 19,222,165,232,248,167,114,248,233, - 61, 14, 56,253,221,123,188, 36,165,136,224,167,119,115,248,114,169,169,237,179,180,199,241,232,230, 36, 11,158,206, 64, 88,162, - 10, 61,116, 98,206,209,196,153,141,255, 76, 43, 47,195,138, 16, 66,188,139,144, 12, 33, 13, 66, 22,132, 76, 8,169, 16, 18, 35, - 68,247,192,159,136,168, 92,135,166, 62,195, 75,224,241, 32, 87,224,111,237,101,244,254,141,228,103,202,148, 41, 99,231,202,149, -235,211,199,143, 31,215,223,189,123,119,253,145, 35, 71,214,227,127, 62,183,210,230,195,209,231,223, 72,126, 90,228,199,203, 46, -123, 21,228,107,157, 43,240,183,213,203, 40,159, 81,226,196,137,211, 33,121,242,228,171,210,166, 77,123, 48, 85,170, 84,135, 18, - 36, 72,176,250,157,119,222,233, 10,194, 81, 77,136, 27,209,172,149, 56,113, 98,255, 82,165, 74, 29, 5,189, 53,160,209, 28, 33, - 46,239,252,207,231,124,143,255,181,116,232,191,204,124, 90,229,157, 94,188,151, 93,239, 97,205,171,147,207,176,114,206, 73,231, - 51, 27, 96, 39,196, 5,158, 44,209,242,229,163,143, 62,186,255,236,217, 51,241,228,201, 19,241,232,209, 35,241,224,193, 3,162, -184, 25,102,147, 14, 8, 39,217,180,105, 83,161, 60,121,242, 12,196,128,176, 58,122,244,232,119, 25, 48, 0,173,202,154, 53,107, -255,191,254,250, 43, 39,226,188,103, 80, 15,158, 26,246, 59,160,211, 18,131,218, 18,208, 61,159, 40, 81,162,243,252,141,103,109, - 64, 43,172,224, 45, 6, 6,197, 78,113,227,198, 93, 21, 51,102,204, 43, 12,252,205,103,160, 25,195, 67, 91,241,148,207, 88, 49, - 98,196,232,146, 44, 89,178, 85,241,227,199,191,194,192,223,124, 6,122,177,194, 72, 51,172,205,214, 40,159,148, 84, 13, 66, 61, - 12,101,136, 26, 53,234,144,226,197,139, 55, 44, 81,162, 68,253,146, 37, 75,214,227,157,207,228,123,198, 69,144,146,175, 72, 55, -248, 36, 77,154,148,109,113,166,167,144, 49, 99,198, 67, 0, 89,226,183,223,126,123,134,201,236,218,180,105,211, 30,141, 31, 63, -254, 89,142, 28, 57, 70,233,181,249, 36, 73,146, 12, 71,189,206,178, 18, 24,247, 85,214,123,211,166, 15,133, 58, 32, 47,153, 76, -218,183,233,228, 24, 33, 52, 31, 54, 21, 77, 17,152, 63,222,229,111,155,121,245,212, 62,215,141, 95,125, 87,140, 91,117,151,223, -216, 96,163, 83,233,210,252,224,131, 15,126,251,225,135, 31,158,254,254,251,239, 98,254,252,249, 98,246,236,217, 98,202,148, 41, -162,121,243,230,207,222,123,239,189,223, 77,232,235,209,108,249,253,247,223, 95,193,152, 27,204, 1,154,247, 89,179,102,221,142, - 29, 59,246,126,222,213,207,187,119,239,126, 5,244, 59,107,190,241,178,242,105,131,117,186, 81, 35,221, 24, 18,222, 2,155,205, -155,225,164, 31, 89,248, 25,206, 98,190,210,228,101,241,117,181,141, 86,111,179,220, 44, 97, 39, 70,164,203, 8, 75, 92,193, 76, -162,117,249,254,253,251, 76,195,248,242, 10, 85,185, 32,155,190,113,227,198,141, 0, 42,206,126,241,197, 23,219, 48,121,223, 26, - 58,116,232,133, 97,195,134, 93, 46, 82,164,200,245,134, 13, 27,110,122,247,221,119,207, 86,173, 90,181, 54, 37, 94, 58, 25, 53, -106, 48,185, 48, 73, 30,157, 58,117,234,227,139, 23, 47, 42,224,143,147,226,169, 83,167,196,232,209,163, 31,227,221,113,208,202, -101, 80,112, 35,154, 69, 48,128,157,253,229,151, 95,158, 30, 56,112, 64,220,184,113, 67, 92,184,112, 65,252,253,247,223,162, 99, -199,142,143,249, 14,244,138,216,164, 89, 20,128,242,252,226, 65,131,158, 6, 6, 6,138,167, 79,159, 42,121, 37,221,185, 3, 7, - 62,229, 59,208, 43,106,147,166, 89,125,122,122,111, 9,104,197,138, 21,107,232,137, 19, 39,126, 57,127,254,188, 18,248,155,207, -222, 20,160, 69, 48,132,197,130,127,112,112,176,110, 64, 61,249, 3, 92, 62, 98,191,200,155, 55,239, 67, 72,177, 82,231,207,159, -255,234,225,195,135, 69,206,156, 57, 47,233,181,121,210, 68, 27,244, 71,146, 80, 1, 11, 20,127, 44, 76,252,239,222,189,235,127, -237,218, 53,127,198,245, 80, 73, 47, 99,144,252, 0,223, 31, 46,193, 17,126, 47, 69, 32,216,138, 98,163,113,105,243,233,109,154, - 81, 84,224,106,153,234,183,221,188,122,226,231, 25, 2,173,106, 67,174,112, 44, 59, 24,142,178, 43, 73,179,101,203, 22,112,240, -224, 65,177,118,237, 90,129,197,165,248,247,223,127,197,156, 57,115,196,136, 17, 35, 4,198,185,253, 38,244, 67,229, 51,115,230, -204, 91,217, 6,255,252,243,207,199,245,234,213,187,139,241,238, 33,255,159, 59,119,238, 57,239,252,207,231,124,207,255,144,184, -174,215,124, 67,183,236,222,206,167, 13,190, 25, 69,125, 25,109,222, 11,217,140, 16,245,217,219, 92,118,111,212,201,171,162, 97, -251, 80,105, 9,180,150,200, 28, 67, 42, 84, 32,117,234,212, 51, 83,164, 72,177,138,129,191,249, 76, 85,162, 37,152, 52, 60, 2, - 45, 74,178, 8,178, 32,105,186,188,107,215,174,195, 0, 44,103,191,254,250,235, 75,120,190,145,129,191, 33,205, 58,179,101,203, -150, 77,241,226,197,187, 88,174, 92,185,207,240,156, 34,113,245,165,215, 8,115,229,206,157,251,206,205,155, 55,181,130, 56,247, -255,179,103,207, 10, 12, 82,183, 65, 40,143, 78, 45,232,209, 44,154, 37, 75,150,187, 0, 21, 34, 40, 40, 72, 1, 66, 4, 91,219, -183,111, 23,219,182,109, 83,194,210, 69, 11, 69,234, 15, 62,184, 3,122,122, 96, 75,151,102,169, 92,185,238,158,243,247, 23, 39, -199,142, 21,228, 23,243,204,192,223, 39,230,205, 19,199,151, 45, 19, 69,178,101,187, 11,154,122, 96,235,101,116,192,152,248, 54, - 3,175, 18,148, 90, 17, 80, 53,104,208, 96,232,132, 9, 19,134, 14, 31, 62,124, 36, 3,127,243, 25,223, 49, 14,227,170,248,250, - 50,242,233,141,206,228,206, 39,129, 14, 1,209,177, 99,199, 66,132,128,128, 0,255, 21, 43, 86,248, 67,138,229, 95,160, 64,129, - 71,172, 43,180,181, 71,153, 50,101,138, 1,192,117,245,232,209,163, 4, 90, 92,144,200, 43, 20, 77,128, 49,127,117,248,239,191, -255,252,183,110,221,234,143,201,215, 31,125,192,127,193,130, 5,107, 64,239, 40,232,156, 71, 24,243,254,251,239,167,179,208,230, -195, 91,126,109, 29,197, 80,129, 44, 46, 74,254, 66, 8, 47,208,242, 54, 77,130, 62, 69,146,133,251,110,121, 15, 67, 94, 61,181, -207,245, 85, 7, 95, 17, 8,143, 64,151,234, 55,171,151, 17,128,217, 65,160,213,167, 79, 31,209,182,109, 91, 81,187,118,109, 81, -186,116,105,209,168, 81, 35,129,241,115,175, 9,113, 61,154, 77,208,254,182, 33, 93,111,132, 36, 8, 93,134, 12, 25,114,157, 3, - 29,239,252,239,122,254, 35, 36,173, 91,241,187,161,149,182, 4,160,229,237,124, 90,229,155, 81,188, 72, 55,134,132,183,192,145, -121,252,244, 98,217, 13, 73,161,137, 23, 65,168,225, 10, 69,113, 47,166,249,175,104,152, 84,241, 42,186,222,107,239,146,134,124, -174,204,223,170,116, 70,194, 19,179, 98,122,182,209,242,199,196, 47,131,139, 82, 8,160, 5,245, 91,251, 42, 85,170,252,123,229, -202,149, 0,100, 70, 9,252,205,103,124, 39,211,220,185,115, 71, 11,180,220, 25, 67,154,119,169, 46,196,196,124,158, 32, 11,255, -247,118,235,214,237,228,210,165, 75,247,224,247, 90, 6,254,230, 51,252,222,189,113,227,198,173, 24,136,206, 64,228, 78,219,173, -104, 30, 74, 24, 61, 97,194,132,199, 41,109, 50,187,142, 28, 57, 34, 16,247, 20,104,189,107,194, 49,100, 51,214,121,130, 43,150, -137, 82, 49,148, 87, 64,242,160, 72,179, 22, 47, 90, 36,230,205,156, 41,252,231,250,137, 63,102, 78, 23, 46,201,150, 39, 53, 34, - 63, 23,139,210,170,115, 0, 82,187,219,183, 23,127,188,255,190,184,126,253,122,136, 48, 35, 81, 34,177, 25,239, 14,248,249, 9, -151,100,203,147, 26,209,172,210,195,242,254,107, 36, 10,114, 5,254,246, 1,152,168,139,242, 43, 32, 11,192,247,159,104,209,162, - 61, 97,224,111, 62,227, 59,198, 9,203,199, 94,167, 52, 18,104,105, 65,209,142, 29, 59,220, 64,171,102,205,154,103,127,253,245, - 87,209,191,127,255, 39, 0, 68, 55, 6, 13, 26,116, 23,106,160, 96,252,158,172, 87, 22, 79, 52,215,172, 89,131, 46,231,239, 15, -213,227,154,194,133, 11, 63,129, 74, 41,248,210,165, 75,148,118, 60,131, 74,253,134, 14,216,138,104,118, 69, 81, 1, 45, 74,114, - 42, 35, 72,192, 29,214,111, 71, 4,205,152, 82,146,229, 2, 90,127,123, 41,175,178,140,243, 0,178, 30, 35, 16,180,140, 9,107, -193,153, 14,166, 21,121,208,102,206,253, 52,239,178,232, 48,232,119,209,186, 67, 79,241, 89,195,150,162,228,103, 93, 68,145,230, -115, 4,192,117, 32, 22,148,122,182,143,118, 63,251, 45, 18, 80,114,213,193,110,194,151,156,207,176,100,207, 73,243, 22,113, 64, - 7,139,184, 75, 79,208,132, 63, 10,152,129, 90,188,135,206,255,242,140, 44,159, 27,221, 37, 13,245,123, 9,216, 94, 36, 87,190, -227,253,139,133,211, 80,165,154,112, 9, 66, 15, 74,173, 8,168, 36,192, 82,223,239,221,187, 23,128,193,228, 95,151,100,203,157, - 70, 47,135, 72,151,156, 54, 89,173, 91,183, 62,128,223, 4, 90,107,171, 85,171, 22,120,245,234,213,141, 80,203,172, 99,224,111, - 62,131, 42,109, 29, 84, 46,255, 65,125,184, 22, 54, 14,125, 16, 87, 43,213, 82,127,162,233,228,201,147, 21,149,142,209, 5,117, -144, 2,152,110,223,190, 45, 96, 47,241, 16,249,109,235,137,139,176,191,234, 2,117,227, 19, 74,178, 78,159, 62,173,168,247, 32, -154, 23, 0,127, 98,201,194, 63,196,239, 51,166,139, 89,163, 71,138,169,253,122,139, 53,126,179, 68,235, 6,245, 30,187,108,182, - 12,201,210,254,106, 33, 84,131,199, 71,141, 18, 11, 0,178,230, 39, 73, 18, 10,104, 77,137, 27, 87,140,143, 21, 75,236, 28, 60, - 88, 76,236,210,229,169,203,102,203,251, 21,174, 79,145,147,106,144,228, 97,148, 40, 81,158, 66, 85, 54, 27,170,221,117, 45, 91, -182, 60, 80,171, 86,173,131,144, 92, 41,234, 9, 94, 4, 91,148,108, 1, 28, 12, 45, 88,176, 96,157,151,149,201,136,250,142, 17, - 40,218,179,103,143,255, 63,255,252,227,255,199, 31,127,248, 67, 98,176,166,104,209,162, 79,102, 2,100, 83,101, 8, 41, 87,112, -190,124,249,110, 64,186,155, 81, 47, 95,122, 52,247,237,219,231,191, 97,195, 6, 5,100, 97, 17,225,255,249,231,159,159, 6,189, - 96, 0,184,167,133, 10, 21,186, 62, 99,198,140,251, 0, 93,207, 40,217,138,168,178,234,209,213,128, 44,130,151,204, 8,118,212, -134,161,200, 70, 4, 77, 87,158,212,246, 89,187,241, 44,103,120,243,170,202,252,108,130, 44,132, 51,120,246,139,234, 57,251, 71, - 94, 4,203,224, 19, 18,208,173, 24,211, 68,239, 37,143, 68,129,222, 65,226,189,111,159,138, 56, 95, 63, 22,153, 58, 5,138,154, -190, 59, 68,175, 94,189, 4,236, 61,153,255, 87,122,189,132,124,166, 67, 57,127,135, 77,218, 70,222, 81,216,116,225, 45,112,165, -204, 62, 21, 63,201, 17,245,124,165, 76, 62, 66,185,227,127,120,105, 58,233, 95, 61, 7,116,176,136, 59, 83,152,118,220, 18, 45, - 60,148,128, 72,123, 55, 5, 90, 18, 84,153, 0,178,176, 48,195,154, 68, 75,143, 50, 85,132,106, 73,150, 4, 90,176,131, 10, 56, -116,232, 80, 0,212, 31, 1,140, 99,150, 43,164, 75, 3,131,227,191, 49,201,156, 4,136,218,249,240,225,195,245, 48,170,190, 78, - 80, 37,129, 22,127, 99,114,191, 1,245,204, 70, 72,143,118,206,157, 59,119, 11,118,236,172, 64,218,248, 70,244, 49,153,205,161, - 77,150,209, 69,251, 39,170,123, 8,148, 96, 87, 36,160,154, 20, 52,144,247,148, 95, 26,187, 83,250,197, 52,183,110,221, 18,199, -143, 31, 87, 36, 89, 75,255, 0,200,154, 62, 85,204, 30, 61, 66, 76,239,223, 91, 76,233,242,157,152,223,187,167,152, 1,192,197, - 52,158,104,210,216,157, 18, 11,170, 8,165, 36,235,183,100,201, 4,172,175,197,244, 4, 9, 4, 65, 22, 37,104, 4,118, 84,115, - 98, 87,155, 96, 26, 51,190,122,241,125, 8,160, 5,137,158, 56,121,242,100, 48,242, 20, 76,245, 41,121,199,103,111, 27,208, 66, - 27,247,223,188,121,179, 34,213,130,138,207, 31, 0,124, 45, 84,202,167,160,106,185,138,133,195, 76,216,106,101,245,208, 54, 21, -117,164, 90, 74, 70, 85,228,234,213,171, 21,224, 6, 80,229, 15,105,224, 35, 2,120,170, 35, 51,100,200, 16, 31,147,222, 85, 74, - 78,241, 95,109,247,229,197,106,214, 39,165, 99,184, 78,240, 98, 38,165,245,152,175,136,160,233,250, 96, 12,151, 52,235, 0,254, -135, 69,197,105,148,111,150,247,207, 54, 83,111,156,249,118,198,141,255,240,123,146, 11, 20,116,198,194,227, 15,216, 59,253,203, - 59,158,209,192, 60,165, 89,165, 0,132,111,163, 29,230,229,203,151, 5, 1, 23,199, 41,170, 17,151, 47, 95, 46, 6, 99, 49,245, -233,167,159,134, 9,104, 97, 67,206, 87, 24, 75,127, 79,147, 38,205, 78,180,191, 93,144,138, 45,196, 34,136, 27,126,194, 4,140, - 35, 42,159,146, 63, 4, 87, 3, 7, 14,188, 4,233,237,165, 22, 45, 90, 92,114,129, 45, 51,246,121,124, 79,112,117,114,213,120, -241,120,223, 92,177,125,116, 3, 5,108,133,139,160,147,248,181,224,128, 70,179, 22, 42, 79,106,112,100, 0,148, 76,129,150, 4, -105, 17, 0,180,152, 95, 99, 39,165,158, 80, 36,237,177, 36,184,226, 29,210,161, 0, 76,190, 1,176, 81, 10, 88,182,108, 89, 0, -212,129, 1,220,186,108, 86, 75, 72,155, 5, 18,154,219,152,184, 46,130,198, 70, 24,206,175,175, 84,169,210, 85, 60, 95,203, 64, -176, 5, 99,228,117, 21, 42, 84,184, 10, 64,178, 9, 3,211, 22, 12, 72,255, 65,114,114, 11,239, 19, 27,209,199,128,115,130, 70, -239,122, 23,192,156, 50,192, 81,245, 7, 73,130, 98, 95,181,119,239, 94,193, 29,137,158,242,203,157,133, 4,103,176,165, 81, 64, - 17, 13, 88,151,253,177, 64, 44,152, 54, 85,248,141, 30, 46,102,246,253, 73, 76,237,220, 65, 76,110,221, 76,204,254,182,165,248, -103,236, 8,193, 52,158,104,114,103,161, 4,125, 18,104, 17,100, 77,139, 31, 95, 76,142, 19, 71,140,143, 25, 83,201, 39, 1, 30, -120, 36, 8,110,152,198,140,175, 94,126,255, 53, 37, 89, 4, 84,157, 58,117, 82, 36,120,234,192,103,124, 71,201,150, 84, 29,130, -159, 67, 33,125,209,218,129,120, 57, 91, 17, 79,206, 72,162, 69,144, 4,155, 65,127,180,117,127, 0,127, 37, 64,253,236,103, 37, - 71,122, 52,105,155, 69,208, 6,169, 21,213,134,254, 0,107,143, 70, 65,202,137,141, 32,207, 97, 83,115, 14,255,131, 40,121, 5, - 0, 11,180,242, 13, 47,198,161, 61, 22,141,202, 41, 97, 89,134,192, 93,144, 52,102, 87, 95,118, 38,114,197,158,202, 2, 77,219, - 69, 80, 25,193, 19,100,121, 67,197,201, 60,148,203,158, 48,198,158, 37,213,210,156, 57,123,237,241,129,235,119,159,109,253,166, -119,254, 85,177,227, 68,223,214,166, 77,155, 67, 24, 71, 30,112,140,129, 13,223,131, 38, 77,154,144, 71,180,133,242,120,161,157, -116,195,238,194,227, 11, 23, 46, 12, 38,184,146, 70,240,216, 53, 40,234,212,169, 19,156, 62,125,250, 99,144,132,119, 55,163,163, -126, 15, 96, 53,165, 75,151, 46, 79,230,193,158,147, 1, 82, 85,129,118, 36,234,214,173,251, 12, 0,198, 82,187,212,126, 15, 54, -179,157,190,250,234,171, 3,200,231,115,111,229, 83,253, 13, 72,178, 54,140, 25, 51,230, 18,128,229, 37,240,227, 18,255,219, 41, -179, 94, 92, 74,178, 30,253,247,187,184, 61,161,152,184, 59,175,190,224,255,240,210,116,210,191,122, 14,120, 73,162, 85,158,170, - 69,148, 38,132,138, 81, 11,210,240,191,170, 58,158, 42,126,133,112,114, 66,191, 45, 90, 5, 90,207,159, 63, 15,128,180, 37, 0, - 19, 79, 0,212, 30, 1,232,224, 1,216,221, 18,128, 9,101,181, 89,198, 80,168,204, 0, 35, 55,225,123,232, 33,212, 36, 71, 1, -124,182, 17, 84, 73,144,133, 29, 88,235,161,138, 92,143, 9,252, 26,232,239,192,138,239,120,211,166, 77,239, 1,104,209,208, 51, -161, 17,125, 2, 45,186,150,208, 94,148, 28, 81,130,132,129, 81,145, 14, 65,146,166, 72,165,120,183, 2,180,152,150,192,108, 21, - 36, 96,254, 11,126, 23,127, 76,155, 34,252, 70, 14, 19, 51,251,244, 18,211, 58,125, 43,166,180,106, 42,102,126,213, 80, 44,104, -221, 84,172,249,165,191, 37,160,197,124, 18,192, 73,160, 37, 65,214,216, 24, 49,196,200,119,222, 81,212, 81,251,247,239, 87,192, - 32, 37, 91,175, 0,104,249, 96, 39,221, 84,126, 91, 11,178,228,127,190,171, 94,189,250,127,180,207,130,106,151,134,240, 67, 81, - 55, 84,177, 84, 51,107, 3,175,243,123, 79,170, 67, 26,173, 83,154, 5,119, 14,254, 19, 39, 78, 36,208,154,107,165, 44,164,201, - 93,140,106,137, 22,165, 99, 4,109,148,102, 65,245,234, 15,119, 38,143,203,148, 41,173,184, 71, 9, 8,216, 41, 96,175,165,212, - 61, 36, 90, 47, 27,104, 81,154, 67, 96, 68, 73, 86, 14, 4,170, 67, 21,137,150,218,141,130,234,183,251,189, 7, 94, 24,210,180, -194, 63,163, 56,216,177, 71,155,192, 41, 8,148, 46,217, 53,216,215,146,173, 22, 35,106,148, 11, 93,243, 39,185, 17,248,101,182, -179,183, 90,102, 63,176,117, 64,231,173,115,102,247, 93,221,111, 90, 41,255,172,185,147,157,191,121,243,198,115, 44, 40,131, 90, -181,106,117, 0,139,174,107,232,159,143,177,224, 32, 24, 53, 28,151,240, 46, 86,179,102,205, 62,236,209,163,199,196,138, 21, 43, -110, 66, 61, 31,130,196,242, 28, 76, 33,206,192,254,242, 95,236, 56,228, 68, 80,200, 46, 31,184, 59,144,155,114,216, 31, 1,218, -197,250,245,235, 5, 93, 71, 64,210, 42,176,144, 53,219,197,232,233,115,249, 81,166,238,176, 13,252, 35, 93,186,116,155, 17, 54, - 0,128,253, 30,214,124,170, 63, 4,173,196,239, 24,203, 47,129, 31,151, 96,106,114,137,255,237,150, 91, 27, 31, 18,172,179,219, -199, 54, 18,247,230, 55, 20, 43,218,167,167, 68,139, 59,192,157, 43,146,115,192, 4,104,153,217,104, 41, 0, 9, 88, 32,134, 39, -201, 23,163,188,136,246,194,176, 94,254, 86, 61,139, 30, 14, 54,134, 13,240, 75,213, 33,164, 49, 1,152, 0, 2,208,193, 3,176, -146, 10,128, 59,134,128,177, 99,199, 42,193,162,234,240, 3,116, 92,170, 14,207, 78,159, 62,253, 52,118,223, 92,194,128,243, 24, -234,195, 27, 24,136,174, 18,116, 81,149,200,103,159,125,246,217, 37, 0,173,211, 0,114,235, 0,206,168, 58, 52,180,209,162,234, -144,146, 32,121,209,158,138,234, 62, 74,132, 8, 92, 96,204,252, 66, 34, 5, 35,116, 6,124,219,146,234,144,105,182,111,221, 34, -252,127,159, 47, 22, 78,157, 44,230,141, 24, 42,102,245,249, 81, 76,235,216, 78, 76,107,217, 68,204,250,178,129,152,247, 69,109, -177,188,221, 87, 98,102,251,214,150, 84,135,103,206,156, 81,108,197, 36,208,154, 4, 73, 22, 65,214, 8,128,172,159, 81,241,148, -186,237,220,185, 83, 1, 90, 28, 64, 95,178,234, 80,105, 91,176,183,154, 76,144,105, 4,180,248, 14,171,223,125,148,100, 17,100, -129,239, 74, 64, 82,130,173,120,225,104,160,175, 52, 41, 65, 17, 93, 56,104,141,225, 9,140,120,193,142,202, 31,146, 39,127, 95, - 95,223,149,112, 10,185, 7, 64,104, 43, 84,136, 29,169,238, 51,202,184,116, 25, 33,105, 82, 13, 9,190,250, 99,211,135, 63,182, -225,251,163,141,251,131,142,178, 61,255,151,225,131,185, 21, 63, 24, 54,132, 2,139, 17,238,100,220,249, 10, 24, 66, 41,148, 58, - 48, 11, 70, 46, 21,150,224,157, 21,144,163, 71, 83, 22, 77,190, 51,250,111,196, 2,250,216, 43,139,160,167,222,180, 75,243,240, -131,249, 3,111, 60,152,211,239,236, 77,128,172, 49,165, 83,110, 75, 26, 43,218,232,247, 18,188,219,239,163, 90,105,150, 85,251, -164, 52,119, 69,139, 70, 77,234,112, 34, 95, 92,185,114,229,205, 84,163, 99, 65, 66,169, 76,110,163, 12, 2, 76,228, 69, 93, 79, - 69, 93,207,130, 20,138,198,234,197, 16,180,227, 24, 7,249, 25, 8, 4,238,107, 17,168, 25,232,229,169,222,195,185, 59,208, 19, -233,242,144,166,238, 65,190,213, 62,225,220,241, 1,184,250,162,173,238,192,131,234, 97,104,151,233,176, 97,104, 1, 84,156, 91, -120, 71,250,116, 97,160, 17, 34, 9,109,178,106,229,140,118,134,146, 44,229,238,216,104,133,151,165,175,125,122,116, 67,245,174, - 67,254,230,206, 67,185,131,144,255,221, 0, 73, 21,151,207,101, 58,185,203, 80,157, 70,251, 46,172, 59, 14,201, 63,219,158,225, - 67, 24,195, 99,112,249, 23,224, 32, 0,147,107, 0, 86,246, 1,152,112,148, 0, 7,121, 1, 48,150,222, 96,209, 24, 62, 49,157, -145,194,176,122, 63, 10,126, 8, 43,125,197, 24, 30,224, 99, 51, 85,133, 0, 70,155, 97, 11,181,165,124,249,242, 87, 33, 53,219, - 12,245,228, 94, 0,175,245,112,228,232,139,248,158, 12, 80,155, 2,244, 41,147, 21,165, 2,180,111,161, 68,128,106, 63,174,248, - 96, 15, 35, 22, 97,151, 32, 69,236, 68,203, 0, 9,143,172, 24,195,119,237,220,233,241,190,157, 59,196,162, 41, 0, 89,195,127, - 17,179,125,127, 20, 51, 58,126, 35,166,183,104, 44,102,127, 89, 95, 44,106, 93, 87,108,237,223, 68,108,236,249,157,104, 91,161, -204, 19, 43,198,240,179,250,244,121,122, 12,134,212,148,100, 77,140, 29,219,109, 55, 70, 85, 33,193, 85, 31, 84,212, 79, 81,162, -136,197,173, 91,139,193, 95,125,245,178,141,225,149,142,102, 5,104, 33,206, 42, 0,129,250,136,254,203,155, 4,180,232,215, 74, - 13,180, 8,140,104,184,190,120,241, 98,127, 72, 97,253,123,246,236,185, 10,147,209, 99,170,246, 40, 25,197,238,195, 71,217,179, -103,191, 10,143,223, 41,244, 70, 41, 2, 45,168,200, 67,208,212, 1, 90, 79,216,118, 11, 21, 42, 40,176,104,225,102, 13, 1,131, -123, 1,186, 47,213, 70,139,249,167, 77, 21,110,169, 17,212,182, 89,122, 46, 21,118, 33,206, 74, 4, 83,160,101, 64,211,231, 97, -211,166,130,193, 69, 35,134,234,191,169,164, 76,229,164, 84,237,145, 63,172, 52,119, 18,100, 81,146, 85, 34,101,236, 45,200, 79, - 85, 4, 69, 69,138, 5,228,222, 79, 63,173,245,148,245,243,121,237,207,158, 0, 88,223,130, 52,247, 1,129, 22, 92, 52, 60,192, -216,180,209, 96,118,138, 86,191,126,253, 54,144,166,239,129, 68,107, 26,226,148,213,139,135, 93,135,219,164,131, 81,185, 80, 68, - 60, 67, 51,140,178,101,203,102,195,198,164, 83, 67, 22, 93, 20,157, 6,249,137, 54,237, 58,138,218,245,155,136,146,159,180, 23, - 37,191,156, 36, 0,250, 47, 96,161,154, 63, 12, 51,102,121, 44,110,207, 64,163,240, 28,125,155,106,209, 80, 30,235,161,214,222, -206,247, 40, 23,205, 46,106,134,225, 27, 78, 18,135, 3, 14, 7, 52, 28, 88,194,157,122,120,182,132,207,233,194, 1, 34,223,181, -216,125,165, 24,191,211, 54, 11,162,106, 5,100,169,221, 59,208,216, 83,166,209,114,148,104, 19,170,187, 92, 16,111,159,135,212, -230, 40, 6,152,221,157, 59,119, 62, 9,187,133,253, 0, 71, 27, 97,112,191, 17,246, 47,251, 32,158, 63, 11, 35,244, 93, 80,173, -252, 3,137,201, 25,172,250, 63, 64, 90, 79, 71, 85, 40,238, 29, 56,248,113, 2,228, 29, 59,197, 20,137,204,202,149, 43, 21,177, - 58, 84, 62, 2,180, 5,118, 39,210,109,130,101,247, 14, 43,255,248, 93,172,153, 59, 27, 32,171,167,152,217,161,141,152,241, 85, - 35,225,215,180,174, 88,210,170,142, 8, 24,218, 76,236, 29,209, 78, 44,248,230, 43, 17, 59, 86, 44,174,118,205, 12,135, 21,247, - 14,135,144,143,127, 91,182, 20,163, 33,201,162,145,189, 4, 89,148,188, 17,100, 77,173, 88, 81, 44,133, 13, 7,212,134, 28,208, - 94,182,123, 7, 75,170, 67,170, 23, 93,245, 75,117, 33, 37, 89,111,132,234, 16,210, 70,127,216,206,248, 99, 19,128,114,103,248, -248,227,143,253, 97, 75,232, 95,166, 76, 25,218, 83,157,160, 68, 18, 82,138, 96,168, 77,175, 66,178,251, 20,106,172,167, 0, 69, -244, 35, 22,234, 34,208,130,116,213, 31, 91,252,253,209, 55,148,187, 54,192, 16,249,209,185,115,103, 33,193,202, 17,140,137,156, -126,180,130,232,163, 13,210, 3,181,111,174,151, 49, 64, 41,174, 24,240, 33,218,102, 17,236,168,237,177,194,234, 82,193, 19,205, -212, 18, 92,169, 64, 22,109,196,198, 33, 16,236, 25, 93,138,132,205, 32,159, 97,161, 89, 9,180, 86,184,198,173,114,234,143, 66, -194,120,204, 45, 42,199, 15,142,137,180,179, 4,224, 80, 22, 73, 48, 70, 63,102,148, 73, 72,226,155, 97,193,120, 30,109,137,142, -152, 57,142,114,241, 74,213, 6,157, 38,115,247, 34,191, 59, 5,253,252, 48, 54,232,220,179, 2,180,176, 81, 98, 51,141,235,191, - 95,240, 72,100,253,225,145,136,245,245, 51, 17,179,237, 83,145,170,195, 13, 81,233,199,221,226,199, 31,127, 20,144, 26, 5,216, -108, 44, 13, 97, 59,117,142, 32, 10,142, 78, 47,184,120, 65,231,185,218,240, 39,226,157, 87,197,171,109,243, 59, 78,116,135, 3, -111, 58, 7,202,162,128, 90,169,150,199, 50, 47,225,209, 58,174,193, 71,137, 40, 29,150,210, 30,139,198,239,122, 14, 75,169,174, - 83,167,193,239, 16, 91,110, 49,152,196,167,199,119, 12, 46,151, 33, 17,216, 11,251,174,147,208,221, 99, 83,206,229,173,152,136, -182,192,153,233, 37, 24, 9, 31,135,154,102, 61, 0,217, 69, 76, 96,213,145, 70,235,243, 74,215, 97, 41,157,145, 82,245,198, 1, -144,234, 55,238, 46,196,206, 46,229,216, 11, 74,180, 96, 91, 35,160,242,185,141, 60, 89,118, 88,154, 30,206, 72,151, 65,109,184, -113,230, 20,177,184,123, 71,177,160, 85, 19,177,164,121,125,177,123,120, 27,113, 96, 92, 39,177,232,219, 22, 34,109,226,132,182, - 28,150, 22,134, 19,212, 93,240,197,180, 9, 91,187,169,242,164,228, 13,126,197, 20,112,184,160, 89, 51,177,180, 91, 55,145, 59, -109,218,123,200,231,171,112, 88,106,201, 24,158, 6,243,200,159,226,103, 11, 23,213,133, 90,149, 97, 68,108,181,142, 80,154,176, -219, 27, 5,155,188,101,144,176, 42, 14, 75, 41,205,162,107, 7, 6,212,143, 18,138, 21, 43,166, 72, 78, 1, 52, 31,194,214, 38, - 55,119, 8,114, 23, 25, 38,100, 78, 80,242,114,231, 19, 18,143,161,235,214,173, 91, 74,144,133, 73,215, 31,192, 58,148,106, 18, -139,149, 71, 92, 28, 0,196, 61,164, 26, 18,192,235, 42,255,131,166,174,183,121, 47,142, 84, 90,126, 74, 80, 68,251, 25,170,228, -212,139, 27,183, 84, 75,229, 36, 84,207,165,130, 29,154, 92,152,148, 85,129, 44,238, 32,164, 91, 9, 14, 86,234, 69, 75,104,154, - 47,128,150, 58,159, 18, 20,134,149,166, 46, 91,181, 64, 75,186,123,225,162,136,139, 36, 24,179,211,177,107,168,122,119, 61, 40, - 64,160,142,197,223, 35,140,165,193,240,155,118,151, 71,226, 64, 34,116, 17, 46, 61, 46,124,251,237,183,129, 88, 4,222, 1, 77, -152,190, 62, 23,144,150,210, 94,149,229,154, 99, 68, 19,237,109, 27,253,249,113,131, 15,253, 6, 94,186,116, 25,187, 24, 15, 41, -182,167,144,234, 11,208,181,178,139, 81,205, 79, 58, 60, 61, 8, 77,128,114,156,143,213,203, 53, 55, 28, 66, 90, 9,136, 35,180, -111, 70, 96,155,247, 6,105,167,236,222,224,226,155, 65, 67,235, 25,222,180, 84, 75,104,235,132, 88,102, 71,240, 72, 21,227, 18, -198,165, 91, 2,220,249,219,104,240,161, 5, 90, 50,216, 99,125,198, 99,118,176,186,223, 10, 81,245,213,174, 93,187, 94,192,145, - 54,167, 48,201, 4, 66,109,178,154,146, 44, 23,200,138,163,147, 83,163,134,173, 28,193, 3, 81,253, 35,218, 98, 81,162, 5, 9, -156,152, 52,105,146,192,174,161, 71,148,122,129,150,221, 35,120,138,210,113,105,135,134,245, 30,205,237,231, 43,214,143,254, 69, -172,255,185,143,152, 3,233, 86,187, 74,229, 30, 99,213, 26,150,227,114,148, 35,120, 70,183,107,247,148, 71,114, 16,108,209, 96, -159,192,112,224, 23, 95, 60,117, 73,178, 94,197, 17, 60,161,220, 59, 80, 5, 75,155, 44, 6,254, 86,187,119, 0, 47,233,216,212, - 72,165, 27, 25, 7,159,120,104, 63, 99,177,136,152, 99, 20,208, 38, 31, 82,162, 5,105,211,125,148,253, 29,128,163,171,172, 59, - 72,161,212,134,235,234,178,199, 36,216,242,116,214, 33, 22, 8, 71,208, 70,131,177, 43,235, 49, 38,210,235,176, 75,188,143,255, - 90, 63, 90, 47,131,159, 81, 96, 55,166,156, 29,104, 96,240,174, 72,181, 80,110, 79, 46, 21, 66,129, 34,210, 84, 75,174,144,222, -173, 26,212,145,104,125,133,247, 90,155,183,151, 65,211, 18,208,226, 17, 99,236, 7, 4, 90, 92, 24,105, 36, 90,122,117, 84, 30, - 70,229,219,113,132,215,117, 44, 38, 21, 21,164,250, 34,200,130,164,253, 14,212,144,148,136,175, 3,192,126,140, 59, 85,141,186, -227, 39,218,231,143, 29, 58,116, 56,178,106,213, 42,193, 32,119, 49, 98,204, 19, 56,165,129, 39, 95,156,198,184,234,107, 50,186, -107,243, 89, 47,140, 18,173, 6,158,198,121,211, 25,198, 60,194,203,104,243,230,185, 48,143,225,228,211,156, 71,111, 75,140,178, - 40,168, 45,137,214, 12,186, 76,160,123, 4,174,226, 40, 42,215, 0, 40,201,184, 37, 84, 23, 82,146, 69,144,197, 65, 8, 47,102, -155,117, 64, 12, 54,113, 49, 72,100,166, 51, 82, 24, 95,254,133,157,133,119, 24, 0, 92, 86,210, 38,203,165, 46, 52,242,222,238, -169, 97, 71,196,161,210,177,232,192, 84,231, 80,233,240, 28, 0,253, 58, 30, 42, 29,202, 97, 41, 36, 55, 19, 1,132,199, 51, 0, - 4, 79,166, 36, 75,165,226,120,211,128,150,233, 96, 0,128, 53,139, 78, 74,161,162,185, 3,123,195, 27,188,243, 63,159,155,181, -121, 35,226,244, 0,143,244, 55, 96, 3,246,140,174, 61,120,231,127,141,103,248,151, 49,152, 75,119, 12, 52, 86,166, 10,143, 18, - 35,233,226, 65,109, 16,239,201,165, 66, 40, 80, 4, 26,180,227,210,210,116,171,248,240,142, 82,172,131, 42,201, 22, 7, 43,143, - 18,173, 8,160,169, 91, 61, 90,137, 22,199, 68, 74,147, 88, 79,180,209,131, 84, 95,173, 58, 52,170, 35, 74,141, 90, 35, 44,131, -171,156, 67,240, 19,120, 22, 7,146,159, 5, 0, 59, 9, 45, 1,109,194,122, 35,208,168,158,129, 42,120,181, 95, 54, 61,154, 37, -176,104, 28,136,111, 47,133,170,121, 19,164,106, 91, 0,192,252,177, 8,194,126, 26,159,146,166,141, 88,163,101,112,197,119,219, -104,193,105, 46, 37, 85,161, 46,216,104,109,244, 96,163,245, 50,218,167,133,162,153, 70,113,242,105,202, 34, 91, 17, 34,130,159, -182, 50, 16,217, 35,103, 65, 1, 8,152,150,168,130,222,161,210,106,137, 22,227,206, 64, 96, 90,121, 25, 86, 4, 38,236,104, 4, - 92, 8, 9, 16, 18, 35, 36, 68,136,135, 16,211,196, 38, 43, 34, 42,215,161,249,162,198, 66, 29,193,163,105,200,102,239, 77,235, - 61, 28, 29,227,149,215, 17, 22, 6,137, 96,111,211, 14,170,232, 46,144, 62,116,225,157,255,249,220, 74,155, 55, 42, 59, 65, 21, - 61,193, 99, 50,123,149,103, 29, 50,123,210, 29, 3,221, 59,168, 93, 60, 16,132, 81, 77, 52, 14,129, 0,204,200, 8, 94,175,142, -140,104, 74,122, 4,117, 85, 92, 65,207, 70,235,101,209, 12, 85, 61, 80,229,174,128, 63,179, 99, 88,100, 28, 71, 56, 70,224, 5, -169,230, 49, 24,177, 31,163, 52, 11,174,101,104,219,101,183,205,211, 39, 32,157,157,154, 29, 3, 70,186, 47,179,205,151,227, 78, - 90,158, 93,170,215, 78,177,216,236, 11, 30,236,195, 59,189,227, 73, 94,102, 62,195, 49,132,188, 84,126, 58,249, 12, 15, 7,156, -180,182, 56,224,116, 64, 91,236, 50,141,252, 50,248,169, 62, 84, 90, 47, 67,102,239, 95,246, 4, 97,202, 52, 15, 17, 94, 6, 63, -195,147, 63,187,147,184,157,111, 25,149,221,200, 29, 3, 1, 19,213,126, 4, 89, 70, 27, 63,236,208, 84,211,147,109,138,180,181, -187, 14, 95, 38, 77, 59,252,211,198,117,218, 82,120,184, 23, 58,173,195,207,183,147,159,222, 45,245, 91, 66,205,233, 44,222,173, -104,135,159, 14, 63,189,197, 1,167, 45,121,139,147, 47,232, 56,252,116,248,233, 45, 14,188,205,109,201, 91, 60,124, 21,116,180, -246, 89,101,213,153, 96,165,234, 5, 59, 25, 53,162,225,233,185, 25,125,135,166,126,189,132,181,190, 28,126, 58,252,180,218, 6, -156,190,105,204, 1,171, 60, 84,199,115,248,233,240, 83,143, 3,111,115, 91,146,252, 24,129, 31,122,161, 21,158,171,131, 89, 31, -122, 29,223,135,205, 75,124, 24, 74,242, 54, 35,115,167,236, 97,104, 48, 30,146, 56,252,116,248,233, 45, 14, 56,109,201, 91,156, -116,164,121, 78, 91,242,110, 91,210,163, 70,192, 21,217, 46,130,172, 16, 18,173,136, 44,128,211, 8,189,203, 93,135,159, 14, 63, -189,197, 1,167, 45,121,139,147, 14,216,112,218,146,211,150,188,203,129,144,212, 34, 35,208, 50,231, 7, 28,233, 69,147, 1,110, - 23, 90, 34, 5,119,155, 40,129,255,213,239,245,126,171,190,224,238,128,102,105,204,190,163, 71, 51, 87,214,248,109,203, 22, 77, -121, 36,111,214,248,109,224,126, 33, 7,104,212,145,129,255,205,190, 25,150,124,234,125, 39,119,246,132,223, 48, 31,185,179,196, - 83, 55, 8,103,240, 49,111,106,118, 98,152,241, 51, 41,136, 53,127, 47,214,187, 75, 75,164,140,123, 45,238,187,209,150,240, 63, -130,122, 71,160,246,123,102, 52,237,228, 79,198,125,105, 52,225, 46, 32, 59,206,190, 27,136,176, 12,219,253,183,243,206,255,124, -110, 33,227,238,124,150, 77,239,115, 6, 65,184,194, 25,117, 90, 79,239,116,190, 17,162,236,149, 51,249, 60,228, 89,116,149, 51, -251,208, 63,148,251,170,146, 89,255, 57,227, 41,241,145, 78,175,111, 90, 40,147,213, 40, 47,173,142, 92, 25,162,111,176, 58, 8, -125, 17, 62, 67,208,243, 15,168,151,247,151,157, 79,171,252,123,163,250, 81, 88, 11,237, 74,231,212, 81, 56, 25,104, 33,121,100, - 1, 90, 90, 85,161,103,213, 33,192, 68,249, 68, 9,226, 29, 76,152, 32,238,165,104,209,162, 62,225, 25,130,188,120,231,255,132, -239,197,189,132,119, 7, 25, 47, 60, 64,203,206,119,244, 6,222,210, 69, 82,220, 16, 87, 70,137,210,133, 83,222,134, 79,154, 86, -240,249,213, 6, 94,150,219,240,206,255,137, 19, 36,248, 34,105,210,248,245,224, 17,254,131,240,228,147,233,147, 38, 77, 84, 47, -113,226, 4, 95,232,125,231,195, 66,239,223,103, 62,202, 20, 73,161, 62, 54,197,233,128, 22,122,144,141, 40,158,248, 25, 35, 93, -162,184, 7,151,124, 83, 83, 92,157,208, 89, 4,126, 83, 72,156,110,145, 71, 76,171,156, 94,164,142,247, 46, 29,108,218,221, 37, -103, 35, 91,161,162,190,140,122,143,150, 49, 99,198,246,240, 42,191,101,255,254,253, 1,104,239, 1, 56, 30, 38, 0, 14, 53,149, -243, 72,249,156,239,145,179,104, 30, 10,162, 6, 90, 66,172,239,165,132,146,105, 20,135,123,244, 17,215,150,129,224, 75,190,227, -111, 60,235, 42,223,185,238,159, 24,129, 34,128,166,224,199, 91,134,138, 42,153,124,158,171,211, 84,207,234,243, 80,236, 28, 21, -234, 57,227, 49, 62,211, 25,209,172,146, 37,202, 83,130, 49,163,192,247, 72,219, 76, 39,208,133,132,188,212,117,196,231,134,241, -107,100,143, 22,104,244, 45,190,211,163,217,180,128,207,211,134,121,125, 4, 67,179,130, 62,207,224,160,120, 53,156,150,174,133, -255,173,181, 93,186,116, 89,251,222,123,239,209, 23, 25,121,156,217,164,161,189,140,182, 20,158,182,174,199, 79,111,208, 35, 13, -167,236,222,226,228, 11, 58,145,133,159,122,165,142,108, 64,203,154,135,248, 4,241,227, 30,219,248,207, 2,177, 96,206,120, 17, - 59,118, 44,229,172,192,161, 67,135, 42,247,216,177, 98,138,153,147, 6,139, 37,243,198,137,248,239,197, 57, 22, 30, 0, 99,231, - 59,122, 3, 26,129, 13, 1, 78,249, 98, 31, 4, 1,180,181,129, 23,234, 54,200,167,114,143, 27, 55,118,155,223, 38, 14,110,179, -116,238,248, 54, 73, 18,190,215, 32, 60,249, 76,146,228,189, 6, 27, 86,253,209,230,143,217,227, 41, 57, 11,245,157,143, 74,164, -185,163, 0,190, 34, 41,110, 26, 77, 16, 94,234, 51,145,165,179,188,236,124,246,253,219,247,107,113,121,216,215,226,194,215, 69, -197,149,111,139,138,171, 93,202,138, 11,109,242,139,153, 85,210,179,209,227,188,110,221,235,101,231, 51,172,205, 32, 68, 62, 9, -162,224, 13,124, 11, 22, 21, 1, 88,255, 40, 1,206, 36, 3,112, 60, 75, 0, 15,127,199,130, 40, 0, 19,186, 4, 91, 70,223, 52, - 4, 90, 56, 22,106,220,221,187,119,135, 50,104,129,150,250, 29,223,131, 56, 1,153,238,132, 43,129, 86,227,194,113,131,212,233, -154, 20,121,239, 62,129,150,222,115, 51,160, 69,208, 35, 86,182, 53, 12, 45, 74,190,247, 16, 96,115, 48,248,225,171, 14, 46, 48, -165,151,207,102,218,184,252, 47,227,123,250, 30,223,233,149,157, 0, 75, 28,152,163,132,161, 85,124, 4, 78,217, 88,139, 58,114, - 7, 28, 94,190, 22, 62,216,214,214,170, 85,107, 45,210,171,129,170,182,174, 34,101,251, 12,107, 35,215,164,115,202,238, 37, 70, -186,200, 68, 22,126, 70,118,160,101,221, 51, 60,164, 89,129,251,119,252, 37,222, 79,150, 72,224,172,182, 16,199, 70,240,127,178, - 36, 9,196,154, 63,167, 19,104,241,188, 46,183,154, 81,254,214, 27,124,244,226,217,249,142, 30, 77,170,234,170,148,203,116, 37, - 99,218,248,139,113,216,181, 34,205,146,129,255, 83, 36, 75,210,102,141,255,244, 54,137, 19,196,107, 26,158,124, 38, 77,156,160, -233,222,237,127,181, 73,149, 34, 73, 27,189,239,100, 78,155, 96,118,229, 50, 25,174,100,201, 16,175,187, 3,180, 94,254,234, 41, -115,138, 36,219, 3,231,143, 17,135,234,102, 19,115, 42,166, 21,141,114, 36, 19,255,126,247,177,184,246, 67, 53, 69,178,149, 34, -110,244, 77,111, 10,208,162, 90,144, 18, 43, 53,200,194,177, 64, 1, 23, 46, 92, 8,192,185,139, 1, 91,183,110, 13,192,153,141, - 1,240, 96, 30, 0, 47,223, 91, 60,168, 17, 67,168, 14, 41,201, 82, 66,250,232,119,113, 36,203, 48, 28, 91,213, 31,135,190,247, -171,144, 53,230, 29,169, 86, 44,159,249,221, 59, 95,125,245,213,112, 95, 95,223,126,184,134, 88, 5, 90,181,115,191,115, 95, 77, -179,110,222,119, 21,160,197,231, 56,223,116, 56, 64, 97,127,210,172,151, 47,198,125,171, 64,107,239,184,186,226,200,175, 13,196, -153,153,141,197,149,121, 95,138,135,219, 39, 40,224,171, 89,209,216, 15, 27, 54,108,216, 15,121,239,254,211, 79, 63,125, 63, 96, -192,128, 94,106,224,164, 51,233, 40, 64, 11,231, 18,254,132, 3,237,187,227, 40,176,159,244,128,214, 63,131,106,138, 45,195, 63, - 19,251,198,215, 21, 15,255,234,172,124,203, 42,208,130,180, 49, 4,208,226,255,107,215,174,173,197,241, 77, 4, 90, 35, 61,204, -167,145,101,114,116,242,249,118,130,162,136,168,247,200, 12,180, 60,183, 2,127,127,255,178, 8,130,129, 49, 9,128,254,219,177, - 82, 12,235,211, 74,100, 76,151, 66,164, 75,157, 92,164,253, 32,153, 18,210,165, 73, 46,122,119,109, 36, 86, 47,155, 98, 5,104, -185, 63,108, 4,180,172,126, 71,175, 4,180,209, 34,208,170, 82, 38,251,162,204, 25, 82,181,201,144, 46, 69,155, 12,169, 93, 1, -191,123,119,107,210,102,213,210,169, 86,128,150,199,124, 18,104,253,183,125,121,155,225,125, 91,183,209,251, 78,245, 10, 57,253, - 42,151,206,112, 37,107,186, 56,221,188,219,223, 28,106, 86, 56,240,105,209, 60, 55,206, 79, 31, 44,118,213,204, 40, 42,125, 16, - 55, 8,105,226, 54, 41,153,251,193,205,145,173,196,185,150,121, 69,241,148,113,175, 90,161, 19, 25,226,208, 6,139,234, 66, 41, -201,146, 32, 43, 32, 32, 96, 55, 22, 1,187,113,192,112,192,130, 5, 11, 2,182,108,217, 18,128, 67,213,119, 50, 62,202,101,197, -201,108, 87, 74,157, 62,254,248,227, 17, 99,199,142,109,191, 98,197,138,230,160,213, 28,135, 21,247,229,243,122,245,234,141,192, -113, 67,237,113,116, 86,123, 28,218,222, 28, 82,227,190, 58, 64, 43, 4, 11,165, 68,139,128, 74, 77, 19,128,234, 30,129, 86,157, - 60,209,239,147,230,182,109,219,154,147,102,253,252, 49,239,233, 0, 45, 45, 77, 5,228, 28,156, 84,255,255, 82,173,191,190, 22, -226,191,217,110,160, 53, 99,198,140, 86, 0,155, 13, 64,179,193,148, 41, 83,186,233, 0, 45, 53, 77, 5,104,225,112,251, 30, 88, - 68, 54,152, 48, 97, 66,136,248, 82,162,181,110,200, 39,255,255,222, 1, 63, 61,160,229,166, 73,213,225, 15,101,124, 20,105,214, -216,186, 73, 31,222,186,117,107, 45,193, 21, 3,164,141,107, 81, 55, 4, 88, 2, 99,162, 25,208,138, 12, 77,210,201,163,195, 1, -175,113, 64,139, 69, 92,132, 35,147,234, 80, 45,229, 14,105,163, 37, 1,150,228, 22,129,214,222,173,254, 98,241,140,159,196, 31, - 83,127, 16,243, 39,247, 16,126, 19,186,137,223,198,118, 17,211, 71,117, 20, 83,134,183, 23, 43,254, 24,239, 21,160,101,245, 59, -122, 53, 41,109,180,202,151,248,224, 46,242,217,102,254,228, 31,218,204,157,216,173,205,111, 99,186,181, 65, 62,219, 76, 29,222, -190,205,242, 63,198,123, 5,104,237,222,234,223,102,209,244,222,109,244,190, 83,190, 88, 42,197, 70, 11,249,185,226,181, 22,231, - 16,178,204,129,134, 31, 22,185,115,110,214,104,177,165, 82, 90, 81, 44,105,108, 69,125, 91,187, 72,206,219, 55,166,252,160, 0, -173, 15, 63,136,167, 86,233, 90,166,251, 58, 70,164,193, 59,109,178, 8,180, 36,200,250,238,187,239,206,226, 48,225,231, 12,144, -230,156,133,138, 63,128, 1, 7,149, 7,224, 28,188,253, 40, 7,193, 39, 3,143, 80, 50,186,218, 18, 56,181,104,209,162,191, 4, - 89,171, 87,175,110, 62,106,212, 40, 5, 80,181,111,223,190, 63, 1,209,238,221,187,155, 67, 53,215,124,250,244,233,150,129, 22, - 1, 21, 0, 76,123, 2, 55,210, 84, 3, 45, 2, 55, 73,211, 14,208, 58, 54,181,161, 74,125, 24, 18,104,205,154, 53,171, 21, 65, - 22,232, 54, 0, 31, 44, 1, 45, 72,240,186, 19,104,225, 64,111, 93,160,181,113,104,173,255,127,239,200, 66,143, 64,203,197, 96, - 69,138, 5, 0,172, 4,128, 99, 69,138,245,237,183,223,174,109,217,178,165, 2,180, 92, 97,228,235,216,206,156, 60, 57, 28,120, - 21, 28,208, 98,145, 72, 8,180,152,101,125, 27, 45, 89, 56,162, 73,198, 34,208,218,181,105,177, 33,200,154, 48,248,107,177,116, -238, 72, 17, 63, 94,108, 51,213,161,187,174,140, 36, 90,158,190, 51,233,151,118,238,239,232, 85,186,180,209, 42, 91, 44,213, 3, - 61,144, 53,113,104, 59,216,104,141,242, 10,208, 10,216,180, 72, 23,100, 17,204,125, 84, 60,245, 11, 27,173,194, 41,110,189,138, -198,249,182,127,179,115,227,186,247, 78,110,248, 83,252, 92, 62,153,168,157, 61, 17, 1,133,207,247, 95,212,185,183,122, 84, 55, -225, 91,248, 29,241, 89,246,196,247,223, 20, 30,113,119, 33, 13,223,105,147, 69,117, 33, 37, 89, 4, 88, 82,191, 31, 45,218, 59, -193, 21,234,119,187, 90,174,110,183,171,159,182,236,127, 53, 74,148,104,193, 22, 15, 2, 87,128,214,215, 95,127,221, 95, 2,162, -245,235,215, 55, 31, 51,102,140, 2,168,186,117,235,214,159, 82, 39,130, 44, 72,184,154,207,156, 57,211, 22,208, 2,128,105, 79, -144, 69,154,106,160, 53,119,238,220,246,146,166, 29,160, 69,149, 97, 8, 91, 45,218, 68,185, 84,135, 4, 90, 4, 89,251,246,237, -107, 0,137,153, 37,160,213,161, 67,135,238,144, 52,133,146,128, 73,137,214,214, 17,159,253,255,123,199,255,180, 13,180, 8,182, - 78,157, 58,181, 22,170, 82, 55,208, 98,189,168, 6,229, 55,165,137, 58,229,112, 56, 16,102, 14,104,177, 72, 36, 5, 90, 18,108, -233, 75,180,212,170,195,237,107,231,235, 74,178, 42,149, 45, 32,178,102,205, 34,202,150, 42, 40,222,139, 23,251,138,137,237, 83, - 8,160, 21, 53,106,212, 89, 56,128,247,132, 12, 41, 83,166,124, 86, 48,127, 94,145, 55,119,118,241, 97,209,156, 33, 36,102, 4, - 89,227,127,110, 43,254,152, 57,152,223, 81,239,238,113,211, 84,108,180,202,100,188, 82,171,114,222,197, 90, 73, 86,166,188, 37, -214, 36, 74, 87,224, 88,146, 12, 69,142, 69, 73,152,245,176, 79,194, 28,235,101,136,154, 56,215, 40,230, 91,175, 53,232,149, 39, - 73,146, 68, 45,210,231, 46,179, 59, 93,254, 26,143,115, 22, 44,189, 74, 45, 49, 35,152,171, 91, 35,223,236, 74,165,211,107,109, -180,194,220,216,156,132,246, 56,208,167, 93,235,160, 39, 15,131,196,154,165,243, 69,197, 28,233, 20, 80,245, 75,247,142, 65,207, -159, 61, 21,219,182,108, 18,149,114,166,191,107,143,226,235, 27,155, 18, 45,105,248, 78,155,172, 53,107,214,132, 0, 90, 49, 98, -198, 18,191,175, 59, 39, 22,111,185,162,220,249,223, 12,104,169, 93, 56,124,148, 37,198, 29,170, 11, 41,201, 34,200,170,152, 45, -182,219, 70,171, 82,246, 56,183, 41,201, 34,200, 2,112,210,179,209, 10,193, 56,169, 58,164, 68,235,135, 31,126,248, 69,210,164, - 45, 22, 85,135,180,213,130, 13,213, 80, 73, 19, 64, 75,207, 70, 75, 75, 83, 1, 57, 87,255,128, 20,107,219, 80,168, 12,103,189, - 8, 46,160,245,101,177, 56, 15,251,246,237,219,135,146, 44,130,172, 95,127,253, 85,207, 70, 75, 77, 83, 81, 29,210, 54,139,106, -195,113,227,198,133,136, 47,129,214, 61,255,111,133,216, 59, 69,136,195,127, 8, 97, 17,104, 81, 85, 40, 37, 90, 70, 64,203, 1, - 91,175,111, 95,115,114,246,242, 57,160, 2, 90,106,144, 18, 89, 84,135,158, 25, 22,218, 70, 43,110,224,230, 85,179, 93,234,194, -206,110,117, 33,193, 79,206, 28,217,149,113,123,196,136, 17,226,157,104,209, 30,231,201,147, 39, 14,193, 9, 64,212, 40,124,101, -189,235, 30,234,131, 46, 96,179, 62, 48, 48, 80,200,112,254,252,121, 1,245,135, 66, 47, 91,230, 15, 66,124,135, 32,107,204,128, - 86,194,239,215,126,134, 64, 75,177,209, 2,208,250,180, 82,238, 69,191,141,233,236, 86, 23, 18,252, 16,100,109, 60, 46,132, 94, - 32,224, 50, 2, 90, 4, 97,124, 47,193, 88,158, 74,149,226, 68, 77,152,109,255,183,125,127, 83,104,165,206, 83,245,201,228,161, - 29,190,166, 36,139,223, 25, 63,184,109,155, 79,171,229,243,171,244, 97,122,199, 70,235,229,247, 75,229,139,141, 27, 53,186,205, - 54,180, 99,199, 14,145, 38,117,234, 39,240,165,182,189,117,235, 86, 79,229,179,148, 41,222,191,241,138,178,230,245,207,210,230, - 10,210, 26,101,119, 33,237,176,104,147, 69,117, 33, 37, 89, 4, 85,181,191,236,250,124,212,220,173,143,198,204,223,241,104,244, -188,173,143, 62,253,162,211, 99, 62,143, 18, 37, 42,221, 30,232,170, 14, 61,237, 44,180,185,235, 80, 23,104,133,115,215,161, 46, -208, 82,164, 89,180,205,250,235,155,255, 7, 60,179,184,235, 48, 20,208, 50,218,165,104, 99,215,161,155,166,218, 70,107, 76,157, - 36, 15, 37,216,210,147,104,169, 64,240, 75, 59,174,195,235,141,210, 33,232,112,192, 75, 28,136,228, 54, 90,101,193, 6,233, 17, -222, 92, 90,157, 40,126,220,192,117, 43,166, 65,194, 20, 18,100, 17,252,228,203,153, 94, 1, 89, 18,108, 69,137, 18,229,111,130, - 45,130, 44,215,234,108,189, 30,207, 93, 96,172, 55,128,216,124,164, 89,132,201,240,250,196,137, 19, 5,193, 22,175,172, 25, 83, - 41,182, 95, 82,146, 69,144, 53,178,111, 11, 49, 99,220,143,226,189,184,250, 18, 45,183,141, 86,241, 15,238, 74,155, 44, 9,126, - 18,165,201,175, 0,173,197,155,206,139, 54, 61,199, 8,159,132, 57,111,248, 36,202,177, 81, 13,162,116,219, 6, 64, 22,211, 49, - 30, 65, 86,148, 68,185,254,150, 32,139,247,180, 57,138,109, 85,131,172, 49,253, 91,183, 41,231,216,104,121,169,155,133,137, 76, -226,164, 73,147,222,129, 74,230, 57, 12,185,159,103,202,148,233, 17, 85,107,216,153,247, 8,234,160,231,117,235,214,125, 30, 39, - 78,156, 59,160,156, 56, 76,212, 95,179, 68,220, 69, 88,180,104,209, 45,116,225, 0,155,169, 0,244,171, 0, 24,124, 7, 80, 93, - 72, 9,214,136, 57, 91, 30,207, 88,186,243,182,223,202,189,183, 71,204,248,251,230,168,249,187, 46,240,121,202,146,109,199, 26, - 21, 69, 11,166,212, 59, 1,181,239, 96,171, 53,124,200,144, 33,253, 70,143, 30,109, 75,162, 5,154,195,212,187, 11,165, 49, 60, -119, 49,246,238,221,187, 63,105, 90,145,104,209, 79, 22,193, 20,119, 23,202, 64, 41, 22, 3,159, 55, 45, 30,255, 42,104,246, 3, -205,238,240, 93,245, 61,164,114,150, 36, 90, 48,134,255, 9, 82,173,238,189,122,245, 10,235,174, 67, 55,123,181,238, 29,184,187, - 80, 74,180,154, 52,105,178, 22, 59, 44, 21, 27, 45,237,229, 26,164, 95,179, 22,231,100,199,225,192, 43,231, 64,100,145,104, 89, -243,159, 37,217, 9,255, 86,199,231, 97, 23,215,202, 63,198, 10,255,121, 35,197,226,217, 67,197,130, 25,131,196,220, 95,251,138, -105,163,123,138, 92,217, 51,132, 2, 91, 72,187,209, 12,104, 17,108, 65,109,152,232,157,119,222,217, 49,123, 54,118, 9,225,194, -224,171,220,115,229,200, 20,226, 59,179, 38,252, 36,166,143,233, 41,126,241,109, 43,226,197,141,117, 92,175,170,165,141, 86,185, - 98, 31, 60,240,135, 45,214,162,217, 67,219,252, 49,125, 80,155,185,147,251,182, 73,156,190,176, 2,180, 8,178,120, 39, 72, 34, -104, 34,120,210,113, 67,241,127,242, 18,104, 1,148,105, 65, 86,138,204,197, 15,250, 77,253,249, 91,245,119,126,155,216,187,141, -219,143,150, 99,163,245,178,123,100,226,152, 49, 99,254, 11, 73,214, 78,186, 59,160,113, 56, 37, 61,244, 39,117,249,242,229,128, - 75,151, 46, 41, 62,165, 22, 46, 92,184,131,241,222, 20,176, 69, 63, 90,157, 58,117,218, 74, 23, 14,148,106,209,240,189, 66,131, -239,175, 80, 93, 56,106,238,182,199,115, 86,236,185, 61,126,238,250,155,147, 23,238, 56, 48,246,143,189,167,249,252,131,210, 29, - 40,113,214,189,212,170, 67,186,112,144, 59, 1,105,164, 78,117,161,116,239, 80, 41,123,236, 27,203,151, 47,111,127,230,204,153, -230,216,217,104,106,163, 5, 15,239, 79,170,101,137,250,188, 78,190, 56,129,106,154, 95, 20, 79,124,145, 82,174,186,249,227, 6, - 46, 89,178,164,253,201,147, 39,155,147,102,211, 18, 73, 46, 50, 62,211,121,104, 72,205,232, 39, 11,238, 24,250,115,119, 33,237, -177, 96, 80,223,170,127,255,254,125,248, 28,128,169,255,226,197,139, 91,129,102,131,211,167, 79, 55, 64, 62, 45,217,104,181,109, -219,182,199,129, 3, 7, 26,248,249,249,133,123,215,161, 30,208, 66, 93,173,133, 36,127, 45,212,164,107,199,143, 31,175, 11,180, - 28, 53,226,203, 30, 62,156,239, 69, 18, 14, 68, 38,160,101,221,143, 86,156, 56, 49, 42,199,127, 47,246,113,250,201,114, 7,216, - 73,209, 86, 74, 9,113, 99, 95,129,135,248, 32,181,100, 11, 21,118,195, 12,104,105, 65, 86,247,238,221,161,210,136,242,140,233, - 64,239,177,242,173,144,223, 9, 36,200,138, 19, 35, 70,101,189, 6, 65, 27,173, 15, 11,167,184,156, 62,245,123,191,211, 87,150, - 12, 9,240,155,118, 89, 46,201,212, 61,181, 68, 74, 13,182, 60, 75,180,114,222, 80,167,139,154, 48,235,190, 68,137,226,183,208, -126,135,223,202,152, 38,222,116,230, 67,227, 71, 43,146,180,225,200,155,205, 24, 49, 98,140,223,188,121,243,142,199,143, 31, 43, -224,138,192,138, 1,147,182,226, 33,125,195,134, 13, 1,171, 86,173, 10, 56,123,246,108,192,228,201,147,119, 48,126,228, 45,109, -136,156, 43,158,225, 11, 20, 40,176, 5,139,134,157, 43, 87,174, 12,168,221,118,160, 34,209,162,218,144,146, 44,130,172,197,155, - 47, 47, 39,208, 50,147,104,185, 40,119,161, 27, 7, 0,149,225,234,157,128,180,159,226,115,248,152, 26, 14,177,126,123,124,171, -253,185,115,231,154, 3,188,154, 2, 45,208,109,107,133, 38, 65,150,164,201,248, 72, 71,239,243, 70,151, 98, 83, 69,227,117,186, -112,144, 70,239, 0, 93, 10, 64,250,254,251,239,187, 67,130,164,128, 44,208,108,128,124, 90, 2, 90,244,187, 69,160, 53,127,254, -252,112,239, 58,212,122,134, 71, 65,230, 80,146,181,103,207,158,181,165, 74,149, 34,200,250, 3, 33,132, 64,171, 76,153, 50, 28, -160,123,243,249, 27,210, 70,157, 98, 56, 28,240, 22, 7, 34, 11,208,178, 87, 94,179, 51, 2,249,158,234, 66,170, 13, 37,216,130, - 81,171, 50,112,224, 75,106,213,161,219,161,153, 30,200,130, 26,113, 14,226,111,144,233, 60,125, 87, 85, 2, 55, 77,218,104,149, - 41,154,242, 88, 54, 56, 10,213,166,165,234, 79, 1, 90, 58,146, 41, 9,182,244,104,202,116,158, 36, 97,218,111,241,172, 67,230, - 67,227, 71, 43, 34,156,185, 57, 52,255, 95,105,229,155, 55,111,174, 56,238, 84,131, 44, 76,176,110,144, 5, 96, 16, 0,201,169, - 34,241,193,228, 27, 0,149, 27, 29,151,150,215,173,119,123, 93,196, 83,236,151, 86, 71,242,172, 67,186,112,128, 13,150, 98,163, - 85, 11, 54, 89, 35,231, 7,156, 27,243,199,222,147,163, 23,236, 57,245,105,179, 46,119, 13,108,180,180,249, 84,118, 29,114,119, -161,116,183,160,222, 93,216,167, 79,159,254, 18, 16, 93,188,120,177,249,210,165, 75,245,128,214,203,160,169, 0,173,174, 93,187, -118,167, 11, 7,238, 44, 36, 64,146,187, 11, 97, 8,223, 93,130, 44,228,179, 1,242,169, 7,180,212,249, 84,232,193,211,126,247, -195,135, 15,135,146,128,217,216,117,232,169,222,185,241,134, 71,253,244, 66,168,142,240,142, 4, 90,242,238, 2, 90,218,118,245, -210,218, 82, 56,155,191,147,207,112, 50, 80,147,252,109,230,167, 30, 39, 35, 11,208, 42,235, 90, 40, 73,169, 22,255, 27, 95,102, - 64, 75, 26,190,131,194, 70,132, 27, 4, 89, 88, 61,122, 4, 90,176,201, 90, 44,213,133,148,100, 17,100, 65,252,255, 46,129, 25, -141,227,121,183, 11,180,164,141, 22, 84,136,161,220, 76,184,129,150,129,173, 21,192,214, 66, 3,160,181,193,204,182, 75,155, 79, -117, 62,222,148, 73, 60,156,227, 70,132, 15, 20,112,105,208,143,224,137,234, 66, 41,201,146, 32, 11, 46, 4, 2, 36,200,194, 46, -178,128,129, 3, 7, 42,182, 76,216, 85, 22,192,116,111, 88, 29,209, 25,105,144, 20,143,216,216,117,168, 11,138,122,246,236, 57, -132,206, 72,229, 78, 64,236,218, 83,108,177,208,199,135, 80, 93, 72, 73, 22, 65,214,188,121,243, 76, 61,195, 35, 95, 10,120,243, - 50, 77, 9,140,126,162, 51, 82, 74,178,212,187, 11, 81,215, 63, 81, 93, 72, 73, 22, 65, 22, 36, 84,150, 60,195,195,166,235, 39, -170, 13,161,138, 12,235,174, 67,187,109, 94,109, 44, 43,199, 78,173, 52,203, 46, 77, 43,221,214,161,105,133, 75,214,227, 56,252, -180,206,171,176,198,140, 44, 64, 75,219,127, 61, 75,167,205,128, 22, 65, 81, 40, 75, 78,215, 3,190,211,153,200,222, 73,159, 62, -253, 3, 72, 31,132, 26,100,169, 13,228, 1,188,122,219, 5, 90,210, 70,139, 64, 71,155, 86,111,247,160,218,230, 42,117,190,234, -138,191, 37,215,245,255,206,226,146,132,121,218,173,168,253,150, 58, 31,111,216, 36, 30,214,142, 17,225,131, 15,212,128, 67,224, -184,115, 26,108,178,166,193, 30,107, 26, 64,214, 52,168, 11,167, 65, 93, 56, 13, 32,107, 26, 38,204,105,240, 70, 62, 13, 19,239, - 52, 76,162,202,111, 62, 71,186,193,111, 88, 29,133, 0, 90, 81,162, 70,123,154,161, 92,251, 41,153, 43,118,153,152,241,163,246, -147,248, 95,181,179,141,109,158,241,121,233, 2, 45,121,198,161,213, 59,193,148, 7,126, 42, 64,203,110, 48,161,169,123, 54,161, -222,121,133,175,234,172,195, 48,116, 26, 7,104,133,102, 90,132,143, 33, 97,168, 39,189, 36, 78, 62,189,196, 72, 15,100, 34, 19, -208,178,110,163,101, 6,180, 84, 18, 45,130, 42, 25, 54,240,183,198,189,131,187, 17,226,249,247, 56,181,254, 20,238,227, 40,201, - 50,251, 70, 40, 85,160, 14, 40,162,141, 86,217,162, 41,143, 80,117,103,133,158,226,170, 33,113,174,153,169,114, 87,125, 16, 53, - 81,174, 95,244, 38, 8, 9,208,212,126,183,180,254,183,180,223,202,155, 53,126, 27,230,131,170,204, 55,108, 18, 15,107, 23,138, -240,193, 7, 27, 42, 62,194,236, 84, 1,106,195, 10, 48,124,174, 0,117, 87, 5, 28, 65, 83, 1,198,213, 21,224,231,169, 2, 12, -142, 43, 12, 26, 52,168, 2, 64,150, 18,248,123,227,198,141, 21,152,238, 13,172, 35,186,109, 32,136, 98,208,186,112, 48,122,167, -173,163, 79, 92, 0,135,109,216, 78, 96, 58,121,189, 12,154, 84,193, 53, 11, 67, 96, 58,189,124, 26,209, 83,226,215,200, 30, 45, -144,234, 67,189,192,119, 94,108, 75,210, 70, 75,221,231, 34,188, 31,133,181,131,107,210, 57,249,244, 18, 35, 93,100,222,102,126, -234,113, 50,178, 0, 45,239,182, 2, 27,212,222,230, 6,227,148,221, 70, 67,177, 16,213,225,167,103, 38,121, 58,207, 80,239,157, -195, 79, 11,141,206, 70, 20,135,159, 54,152,101, 33,170,195, 79, 11, 76,178, 17, 37,178,240, 51, 50, 3, 45,173, 52,235,165,109, -108,137, 44,149,235,228,211, 70,143,181, 16,213,225,167, 5, 38,217,136,226,240,211, 6,179, 44, 68,117,248,105,129, 73, 54,162, - 56,252,180,193, 44, 11, 81,223,102,126, 70,102,160, 37,243,174, 11,176, 88,169,122,193, 66,123,112, 71, 49,162,225,233,185, 25, -125,135,166,126,189,132,181,190, 28,126, 58,252,180,218, 6,156,190,105,204, 1,171, 60, 84,199,115,248,233,240, 83,143, 3,111, -115, 91,146,252,176, 50,159, 69, 38,213,225, 75,147, 98,169, 27,212,219,140,204,157,178,155, 77, 47,246,222, 59,252,180,199, 47, -179,216, 14, 63,205, 56,100,239,189,195, 79,123,252, 50,139,237,240,211,140, 67,246,222, 71, 22,126, 70,102,137,150,163, 58, 52, -105,147,145,165, 17, 58,249,180, 55,184,152,197,118,248,105,198, 33,123,239, 29,126,218,227,151, 89,108,135,159,102, 28,178,247, -222,225,167, 61,126,153,197,142, 8,126, 70,102,160,101,198,175, 8,123, 31, 17, 21,241,106,104,166,173,245,163, 79,234, 90, 15, -148,144,166, 86,111, 11, 28,123, 53,249,180,144, 49, 77, 20,119, 62,177, 27, 52,154,157, 80,176, 96,171,232, 62, 5,123,143,142, - 95,102,224,153,168, 5,251,124,171,162,107, 84,246, 40, 73, 51, 22,108,154, 46, 87,233,237, 41, 50, 23,189,150,165, 96,197, 3, -137,211,230,109,135,116, 81, 84, 33, 1,206,240,203,129,255,241, 85,207, 72, 58,210,241,211,126, 85, 24,166,112,202,238, 69,102, - 58,109,201,197,204,132, 57,211,248, 36,202,213,219, 39, 81,206, 97,238,144, 32,199,151,161, 88,205,103,234, 56,137,114,246,195, -217,177,105, 60,244,119,217,159, 19, 29, 63,126,188, 0,226, 37,210,244,113,190,215,123,167,254,180,211,230,223,206, 54, 31,153, -129, 86, 89,100,222,186,123, 7, 91,245,155,229,243, 12, 62, 25,234,244,241, 73, 95,231, 36,238, 60, 90, 34,108,157, 37,211,103, - 31,248,100,168,251, 57,194, 64,208,249, 59,110,174, 47,174, 69,205, 92,255,128, 79,166,122,236,168,246,105,102,168,211, 22,116, - 2, 13,130,218, 13,131,181, 73, 60,245, 39, 15,119,156,122, 38,142, 95,121, 46, 20,176,101,126, 89, 25, 40, 98,112,208,135,203, -139,142,241,226,197,251, 5,247,174,248, 95,207, 53, 48,233,125,193, 10,205,168, 72,216, 50, 94,220,184,139,114,167, 76,124,246, -189,232,209, 54,227,255, 32, 43, 52,237,131, 44,223,233,223, 13,251, 75, 60,121,250, 92,196, 41, 53,240,188,135,129,151,175,162, -164,206, 86,114,105,215, 62,163,238,158,185,124, 71, 60,123, 30, 44,206, 5,222, 21, 61, 6,140,123,244, 65,182, 18,127,195, 5, - 67, 84, 6, 56,182,253, 18, 14, 72,251,226,222,140,255,225,194, 65, 14,218,122,101, 79, 9,186,234, 1, 63, 46,254, 23, 71,104, -236,186,243,191,167,203, 10, 63, 35, 5, 77,156,188,144, 42,101,202,148,190, 56,150,103, 39,239,252,239,133,178,155,183,114, 15, -125, 19,117, 55, 9,175,233, 35,202,206, 93,251, 77,143,117, 20, 43, 86, 44,186, 88, 80, 6, 55,215,111, 43,121,182, 82,239,161, -232,152,124, 43, 76, 52, 95,105, 29, 1, 48,253,125, 80, 4,168,131, 2,168,180, 23,158,133,142, 7,128,246,255, 75, 93,246, 40, -236,179,236,187,184, 58,179,238, 57,190,201,254, 45,239,218,119,170,126, 46,169, 70, 62,126, 90,105,121,214,226,188,205,101,215, -227, 80,100,177,209,178,119,168,180,105, 91,200, 89, 39,174, 79,134,218, 95, 2,196,172, 47,219,120, 80,240,220, 85, 7,133,223, -154, 83, 2,255,143,106,210,154, 55,152,116,205, 98,250,100,172, 59, 52,111,173,159,158, 15,152,182, 81,172,218,121, 65, 28, 56, -123, 95, 28, 56,255, 88,124, 59,241, 8,105,110,179, 77,147, 9, 0,178, 78, 4, 62, 21, 27, 14, 63, 18, 27,143, 60, 18,155,142, - 62, 18, 91,142, 61, 18,127,239,123, 64,154,106,255, 55,140,109,158,207,212,181, 30, 19,100,213, 24,113,159, 64,235,177, 41,143, -204,105,166, 79,150, 44, 89, 95,120,220, 30,190,108,217,178,233,171, 87,175,246,195,125,214,176, 97,195,126,137, 29, 59,118,127, -208, 47,162,243, 13,179,124,166,205,156, 58,213,182,191,134,255, 36, 2,151, 78, 19, 55,126, 31, 37,174,253, 54, 64,108,234,213, - 84,228, 74, 28,235,186, 65, 57, 77, 37, 90,101,203,150,125,135, 65, 2,177, 23,146,172, 23, 32,139, 23,239,248, 79, 48,103, 56, - 72, 38, 78,159,255,139, 14, 61,127,185,251,228, 89,176, 56, 21,248, 72,236, 60,126, 95,185, 63,122, 18, 44, 58,246, 26,121, 47, - 89,134,130,109,232,159, 12, 4,102, 3,104,177, 29,205,150,131, 50,126, 19,108,105,203,222, 23,207,158, 33, 60, 71,248, 13,192, -172,113,197,138, 21,127,130, 39,112, 95,248,213,242,229,253,147, 79, 62,249,137,207,241, 62, 55, 66,116, 27,252,100,220,220,175, - 59, 77, 0,170,216, 56,126,167,109,190,124,249,246,124,243,205, 55,193,127,255,253,183,192,185,142,226,175,191,254, 18,237,219, -183, 15,230,115,190,103, 60, 27,101,183,208,180, 13,163,104,235,136, 3, 15,193,176,213, 32,227,171, 63, 96,214,230,221,190,147, -145,200,170, 33,170, 25, 77,163, 2,122,250,150,150,230, 65, 28, 81, 22,200, 0, 80,161, 4,180, 39, 37,192,151,155, 18,162, 71, -143,174, 4, 56,209,229,243, 19, 22,234, 40, 27,226, 80,218,107, 53,100,247, 72,211, 5,160, 32,157,250,219,178, 68, 11,113, 9, -186, 52,128, 44, 4,208,114, 45,144,184,224, 83, 28, 91,243,174,227, 23,209,253, 14, 81,148, 69,150,171,159, 27,142, 33,225,105, -152,174,180, 97,173,119, 79,159,118,104,122,161, 98, 76, 72, 68, 22,160, 85,214, 53, 6,169,165, 90,182,185, 19,197, 39, 83,237, -178, 62,233,107,207, 72, 87,166, 93,208,240, 89, 27,197,234, 93,129, 98,217,174, 32, 49,234,175,187,162,210,183,243, 8, 96,250, -104,168,122,110,132, 25,234, 21,126, 39, 75,189, 67,195,253,118,138,128,147,143,196,180,245,247,196,128,197,183, 69,207,249,183, - 68,175, 5,183,196,215,227, 15, 11, 72,202,120, 8,171,157,129,247, 69, 92,128,169,181,135, 30,138,190,139,110,139,254,160, 57, -104,233,109, 49,216,255,142, 24,186,252, 78,216,128, 86,170,170,251,191,248,121,135, 40,250,221, 54,225,131,223, 22,184,231,169, -236,185,178,102,205, 58, 24, 96, 96,242,200,145, 35,253,126,250,233, 39, 63,120, 48,247,155, 56,113,162,223,220,185,115,121,159, -130,163, 98, 8, 36,146,218, 40,123,142,234,133,243,222,186,184,118,153, 56, 51,168,141, 56, 92, 63,135, 56,214, 48,187, 56,211, -170,136,184,244, 93, 89,113,174,101, 30, 81,244,253,184,119, 65,239, 3, 35,154,106,137, 86,206,156, 57,223,197,193,197, 77, 33, - 33,153,136, 51, 2,151,148,173, 90,127, 81,137, 6,195, 38,103,106,184,228,251,120,213,230,172,232, 52, 98,141, 26,100, 77, 87, -192,215,255,175, 80,101, 79,147,171,244,230,147, 23,110,137,147,151, 31,137, 47,199,158, 23, 62,117, 14,136,166, 99,206,137,189, - 39,239,138,128,195,129, 34, 85,246,146,123, 52, 64,235, 7,254, 87, 13,192,106,154, 84, 69,224, 44,233,199,193,204, 68,204,152, - 49, 5, 0,234, 20,120,136,247,213,134,163, 71,143,250,226,232, 29,223, 18, 37, 74,252,128, 52,181, 60,241, 51, 86,172,216,103, -217, 81, 98,197,142,125, 31, 71,187,244,129,183,249, 80,244, 72,223, 14, 77,126, 47, 65,130, 4,191,162,190,167,120,147, 38, 78, - 90,248,187,126,253,250, 79,113, 84,142,128,122, 70, 60,120,240, 32, 84, 56,114,228,136,192, 97,218,226,243,207, 63,127,202,248, - 54,218,146,133,230,173, 27, 37, 68,189,187, 36, 89, 4, 89,150, 46,131,248,102, 19,217,107, 9,180, 0,176,206,145,247,168,115, -129, 35,130, 4,142, 53, 82,234, 2, 71, 66,137,209,163, 71, 11,158, 17, 59,116,232, 80, 49,100,200, 16, 1,103,186, 34,110,220, -184, 23,117,152,164, 45,123, 54, 20, 54, 13, 66, 90,215, 61, 53,238, 31, 32,164, 68, 72,129,144, 28, 33, 25, 66, 18,132,196, 24, - 67, 8,204,180,215,255,105, 74,160,133, 59,192,248, 95, 89,178,100, 57,226, 41, 48, 14, 1,150, 9,208, 74, 68, 9, 22, 62, 74, - 71,214,203, 93, 64,235,182,235,191,218,193,245,109,215,187,229,124, 71, 9, 23,238,236,215,242, 50,171,119, 75,109,234,101,183, -249,176,100,202, 66,189,123,131,108,100,225,167, 94, 89, 21,160,133,246, 82, 4,161,134, 42, 84, 84,253, 46,138,223,197, 92,255, -213,207, 25, 95,254,151,119,210,145,180,152, 78, 77, 87, 79,192,225, 13,254,251,248,224,104, 18,101, 37, 40,239,186, 84, 51,212, - 89,241,213, 79,179,197,226, 13,167,197,210,157,119,196,144, 63,239,136, 62, 0, 49, 3,150, 0,196, 44,185, 37,222,203,223, 42, -216,135,106, 68,171, 87,250,218,157,243,126,210,231,217,206,163,183,197,140, 13,247,197, 55,211,111,136,150,227,207,136, 79,122, -173, 23,197,154,207, 20,105, 42,254, 36,162,102,105,180,215, 39,125,221,210, 86, 73,134,136, 7,160,245,239,193,135,194,247,143, -219,161,192,150,142, 68,203,252, 19, 73, 63,156,215,103,201,195, 23, 18, 45,252, 54, 79, 96, 24, 35, 15, 6,179,159, 49,248, 78, -249,241,199, 31,253, 58,118,236, 56, 13,147,112, 87, 12,138,253,211,165, 75,215,113,240,224,193, 19,112, 38,164, 95,131, 6, 13, -120, 84,140, 85, 36,159,251,147,226, 5,238, 93,223,185, 94, 28,233, 90, 91,236,171,149, 73, 12, 44,242,190,168,150, 38, 94,240, -183,121,146,138,163, 95,228, 20,151, 90,229, 21,171,106,103, 21,209, 95, 28,228,173,123, 73,160,133, 1, 53,117,230,204,153, 23, -248,250,250,110,198, 17, 55,187,174,220,126,190,111,236,138, 43,103,227,212, 88,252,204,167,194,239,162,225,192, 45,226,194,181, - 32,209,113,196, 63,148,100, 41, 32,139,105, 61,241, 36, 69,150, 98,151,159, 60, 13, 22,219,143,129,127, 0, 89,255,236,189,165, -220,151,109,185, 36, 78, 92,188, 39,146,103, 44,242, 16,233,103, 35,240,236,194, 89,188,243, 63, 85,137,184, 39,208,208, 14, 5, -180,224, 9, 94, 23,104, 93,187,118,205, 23,135, 5,251,226,252, 67, 95,208, 96, 48,188,240,173,167,193,128,110,113,227,198, 11, -254,243,207, 63,199,220,184,113, 67, 23,104,217,161,201,143, 1,176,222,106,221,186,245,189, 74,149, 42,157, 34,168, 6, 0,234, -167, 5,132, 56, 0,217,119,205,154, 53,190, 43, 87,174, 52,205, 39,105, 22, 47, 94, 92, 60,125,250, 84, 60,123,246, 76, 0,112, -234, 2,173, 71,143, 30, 9,156, 5, 41, 64, 91, 48,126, 56,218,108, 88,147,134,146, 80,153,168,223,244, 36, 90, 30,191, 29, 70, -213,161, 33, 77, 23,216, 35, 6, 8,165,238, 36,160, 71, 66, 75,106, 74, 2, 45,156,197, 40,160,194, 21,169, 83,167, 22, 25, 50, -100, 16,217,178,101, 19,185,115,231, 22, 5, 11, 22, 20,197,138, 21, 19,165, 75,151, 22, 31,125,244,145,232,223,191,191, 17,208, -210,230, 83, 2, 45, 74,120,163, 97,204,232, 9,233, 55, 79,219,120, 26, 39, 78,156, 51,200, 95,111, 60, 87, 22, 60,200,127, 66, -220,244,128,214,255,105,170, 64, 19, 1,150, 27,177,234,252,120,248,240,161, 96, 28, 3,160,229,166, 73,155, 44,242, 78, 69, 98, -157, 7,186,234,119,147, 92,246, 92, 97,109,107, 78,186, 55,128, 3, 6, 88, 68, 2,173, 26,178,255,189,104,226,194,253, 31, 71, -251,245,144,255,213,207,213,241,212,239,213,191,153, 86,210,117, 61,143, 24, 78, 90, 4, 90,155,107,118, 93, 34, 58,206,186, 41, -186,250,221, 20, 61,230,189,144, 58,245, 89,120, 91,124, 57,116, 7,165, 68,234, 51, 14, 61,103, 52, 67,157, 82,249, 63,239,247, -252, 16,212,131, 93,230,220, 20, 95, 77,186, 38,138,183,254, 93, 68,203,210,224, 18,108,180,198,249,100,172,211,204, 39, 99,189, - 92, 62, 62,158, 39,111,143, 31,201, 88,251,250,154, 3, 15,197,143,191,223, 10, 5,182, 94, 33,208,202,151, 61,123,246,159,113, -120,237,212,206,157, 59,251,125,245,213, 87, 19, 49, 56,246, 66, 57,106, 35,208, 22,168, 48, 64, 78,119, 2, 45,172,114,103, 97, - 0,165, 84,203,236,202,215,181, 89,163, 7, 71,119,239, 20,235,191,111, 38,182, 85, 75, 39, 42,164,140, 67,149,218,247, 8,180, - 1,251,168, 94,230,132,207, 47,181,204, 43,142, 55,207, 45,114, 36,142,117,201,136, 32,193, 18, 37, 89, 4, 89, 48, 72,223, 25, - 28, 28,188,139, 97,221,161, 39, 71, 9,178, 54,254,119,237, 57, 91,119,224,205,135,162, 94,191, 45, 34, 94,213, 57, 43, 36,200, - 50, 3, 90, 89, 11, 85,218, 39, 37, 90, 95,140, 62,171,128,172, 58, 67, 78,136, 85, 1,151,133,255,198, 99,162, 84,229,122,143, -168, 50, 36,200,114,221,249,155,161,175,203, 56, 94,155,109,242, 38, 24, 19, 90, 48, 36,110,187, 54,109,218, 52, 2,128,195,247, -214,173, 91, 10, 56, 34, 72, 58,127,254,188,239,214,173, 91,125, 33, 61,240,197,177, 60,166, 0, 70, 13,180, 32, 89, 28, 3, 32, -227, 27, 94,154,204, 52, 0,180,178,122,223,191,127,191,232,213,171,215,131,170, 85,171,158,235,210,165,203,194,128,128,128, 65, -204, 35,250,159, 47, 58,187,111,171, 86,173,124, 33,161, 50,205, 39,105, 66,210,168,204, 95, 56,239, 81,240, 12, 81, 6, 2, 46, - 78,136, 4, 88,124, 14, 64, 40, 40,213, 58,117,234,148, 96,124,179,134,228,237,247, 46,176,162,149,104,185,231, 93,215,224,230, -254,172, 65,124,111,103,203,140,158,161,186, 19,109,139, 11, 0, 75, 18, 58,244,221,115,148, 54, 18, 96, 1,104,139,230,205,155, -139,205,155, 55, 43,117,243,223,127,255, 9, 28,180, 45, 42, 84,168, 32,208, 22, 20,160, 5, 27, 77, 61,137,150, 54,175, 10,208, -162, 26, 31, 0,115, 59, 36,154, 15, 72,235,254,253,251, 98,251,246,237,226,211, 79, 63,125, 8,201,216, 94, 36,138,142,120,220, - 76,226, 25,104, 73, 35,119,220, 9,162,216,118,208, 38, 13,131, 2,180, 84,105, 12, 24, 73,137, 22,165, 83,156, 15, 66, 72,173, - 92,207,164, 84, 43,132,180,203, 37, 5, 83, 75,180,204,234,201,121,255, 6,114,192, 10,208,114, 73,173, 20,201, 22,199, 16,189, -187, 17,168,114,141, 57,134,105,240,162, 68, 56,216, 90, 86,210,119,221,249,255,255, 23, 11, 39,131,225, 71,210,213,121, 31, 32, -232,116,133, 14,161,193, 86,238,218, 35, 0,180, 96,179,101,229, 74, 89, 51,118,212,204, 13, 78,108,135, 36,171,195,111, 55,197, -167,131, 14,139,100,165,190, 71,250,186,211, 0,128, 56, 56,132,255, 74,255,121,158,228, 69,219, 62,255,115,247, 3, 69, 13,169, - 5, 91,175, 8,104, 21,196,138,118, 16, 6,235,169, 0, 15,126,109,219,182,253, 21, 43, 82, 78,170,165, 84, 5,142, 10,219,141, - 95, 8,180,160, 98,240,195,123, 74,181,184,122, 53,186, 10,118,109,209,244, 65, 48,164, 26, 71, 0,180, 62,203,144, 84,148, 75, - 30,155, 32,171,166, 58, 65,166, 4, 49,206, 94,132,234,240, 76,139, 60,162, 66,218,247, 56,145,196,210, 35, 72,176,132, 73,161, - 25, 37, 89, 18,100,241,190, 96, 91,208, 73, 74,178,120, 21, 44, 87, 71,185,243, 63,213,136,106,117,163,167,138, 75,152, 58, 87, -219,118,223,255,252, 40,232,209,115,168, 11,239, 8,255,173,151,196, 63,187, 46,139,157, 71,174,139, 90, 95,116,125, 18, 43,254, -251,180,197,163,122,143, 18, 45,218,104, 73,137, 86, 51,252, 54,106, 23,147, 41, 25,132, 90,102, 4, 38,181, 17,180,205, 2,192, -240, 69,246,124, 15, 30, 60,232, 59,106,212, 40,223, 54,109,218, 40, 0,134,234, 67,208,177, 44,209, 26,131,107,231,206,157,190, -201,146, 37,191,205, 78,147, 40,113,146,123, 97,161, 73,158,164, 73,147,230,142, 27, 93,224, 7,192,149,128, 4,238,113,173, 90, -181,142,125,247,221,119, 74,254,100,176,146, 79,210, 4, 32, 86, 72, 66,226, 40, 0, 42, 5, 14, 80, 86,164, 91,188,110,223,190, -173, 0,172, 29, 59,118, 40,129,170, 69,198, 15,127,199,178, 77, 65, 79, 66,101, 8,180,200,103, 4, 75, 64,198,118, 78, 44, 38, - 48, 1,123,150,243, 7,208,126,238,215, 95,127, 85,164, 88,205,154, 53, 83,128, 47,206,226, 20, 0,240, 98,203,150, 45,226,216, -177, 99, 2, 18,109, 1, 59, 66,187, 64,235, 3,140, 11, 63,212,171, 87,239, 1,129, 53,212,216, 2,237, 84,161,119,225,194, 5, - 81,173, 90,181, 32, 44,222,250,161, 28,239,161,200,158,129,150,138, 39, 70,170,195, 50,101,202, 4, 74, 0,166, 0, 45,243, 75, - 49,132,119,153, 1,132,176,195,146,118, 90,200, 91, 40,251, 45, 29, 27, 45,243, 47, 57, 49,222, 56, 14, 24, 96, 17, 74,180, 90, - 73,240,196,113, 66,130, 45,249, 91,123,247, 4,180,180,116,100, 90,151, 84,172,124, 24,153, 90,214, 53,126,169,147,115,188,224, -243, 23,151, 37,137, 22,118,255,165, 40,254,245,221,127,246, 92, 23, 29,102,222,124, 33,217,130, 52,170,227,140,139, 80,241, 53, -184,239, 67, 3,121, 43, 87,134,218, 99, 7,206,216, 46, 38,254,115, 87,212, 30, 25, 40, 18, 22,253, 46, 88,217,109,232,173, 43, -125,189,188,200,231,205, 53,123,175,139,159, 32,113,251,126,238,173, 23, 54, 95, 42,201,214, 43, 0, 90, 41, 96,248, 62,156, 32, - 11,131,150, 31, 6,220,217, 48, 82, 38,136,210,162,231,210, 80,241, 12, 90,186,116,169, 31, 84,136, 51,240,190,183, 7,182,164, - 46, 87, 48,223,125,130, 44, 14,226,219, 54,109, 20,117,138,228, 10, 5,178,144,190,100,171,162, 25,159, 95,106, 95, 74,156, 6, -208,202,152, 32,230, 5, 35,154, 46,137,214, 28,170, 11,213, 64,235,255, 18,173,171,138, 68,107,253,254,171,207, 99, 85, 91,248, -140, 54, 91, 86,129, 22,190, 25, 37, 85,182,146,203,218,116, 29,116,119,243,190,243,226,240,185,219, 98,241,218,195,162, 86,211, -174, 79,146,101, 42,170,236, 58,212, 26,195,107,108,180,244,178,237, 11, 73,142, 47, 86,243, 33, 2,165, 89,106,240,194,223, 4, - 93, 32, 96, 11,104,145, 46,128,175, 82,102,118, 34, 0,163, 17,106,186, 86,104, 50,211,169, 82,165,186,171, 6, 90,242, 55,140, -247,175, 65, 10, 49, 60, 44, 52, 51,101,202, 36, 80, 71, 10,208, 82, 7, 74, 76, 36,192,146,119,130, 46,198,247, 86, 23,179, 74, - 71, 13, 90,212, 42, 62,169,130,211,238, 18, 52, 1, 57, 86, 63,235, 19, 78,117,162, 33,152,178,147, 63, 2, 45,216, 90,138, 60, -121,242, 8, 28,102, 46,254,253,247, 95,197, 70, 11,109, 90,172, 90,181, 74,236,217,179, 71,108,216,176, 65,212,173, 91, 87, 1, - 90,239,189,247,158, 85,137, 86, 42, 72,173, 14,239,219,183, 79, 64, 37, 46, 32,201, 21,187,118,237, 18,135, 14, 29, 82, 54, 66, - 96, 83,141,128, 77,224,105,228, 53, 30, 24,102, 25,104, 25, 49, 87,170, 20, 41,233, 10, 15,208, 98, 95, 38,192, 98,208,130, 48, - 11,253,220,114,221, 59, 17, 35, 55, 7, 94,134, 68,203, 12,164,133,145,131,114,124, 45,235, 74, 47,239,255, 31,119, 77,129, 22, - 64,214,251,197,190,190,189,106, 55, 65,214, 13,241, 89,191, 93,162, 84,219,133, 10,216,170,212,233, 79, 24,172,215,157,105, 41, -115,233,235,100,205, 81,163,119,240,150, 99, 15, 69,173, 97, 87, 69,246, 6, 51,152,118,180,165,180, 86, 34,165,171,147, 15,249, -188,185, 26,249,236, 60,251,166,168, 51,112,183,136,158,173, 9,128, 92,157, 27, 26, 55, 15, 90,247, 14,166,212, 99, 39, 46,178, -184,203,244,211,162, 98,159, 19, 34, 86,242, 2, 75, 77, 19,104, 34, 0,104,213,130,125,206, 88,216,224,204, 78,148, 40,209, 47, -120, 77, 55, 4,234, 75, 49,144,199,128, 54,115,209,162, 69,126, 80, 43,112, 23, 95, 19, 79,223,129,184,125,200,170,105, 19,196, -166,245,235, 68,157,146, 5,159, 34,110, 53, 77,252, 28, 21,243,102,189,121,117,193,104, 17,216,189,170, 88,252,177, 50,217,206, - 48,162, 73,149, 4,212, 92,155, 1, 94,220, 64,139,191,143,157,187,185,175,207,172, 67,103, 9,174, 40,201,138, 89,245,143,103, -223, 79, 10, 56, 75, 3,121,245,110, 68, 19,158, 40, 43,221,164, 25, 11, 55, 3,224,218,145, 52, 93,129, 71,165,171, 54,124, 8, - 73,214, 86,185,187, 48, 12, 64,107, 40,164, 3,195,181, 64,139,234, 56, 45,208, 2,112,245, 58,208,178, 66,147, 60,121,255,253, -247,239,233, 1,173,114,229,202, 93,215, 2, 45,171, 52,105,251, 67,117,161, 22,104, 17,116,107,129, 22, 39, 97,198,183,219,102, -189, 16, 95, 13, 90,220, 44,240, 96,235,100, 89, 98,100,146, 55, 79, 82, 51,143, 73,189, 37,209,194,110,194,115,144, 90,138, 66, -133, 10, 41,170, 61, 74,178, 22, 46, 92, 40,254,249,231, 31, 69, 2, 69, 73, 20, 37,155, 77,154, 52, 81,128, 22,192,145, 85,160, -149, 18,224,255, 1,165,150,172,103, 9,178,176,113, 67, 92,185,114, 69, 4, 6, 6, 10,188,127,138,114,196, 65, 65, 29,160,229, -133, 70,236,144,120,121, 28,176, 2,180,144, 27,101,225,171,150, 76,105,109,180,204, 36, 90,234,247, 94,178,209,146,227,171,209, -221,132,137, 46,144,181, 50,224,154,104, 51,229,186,168,238,187,147,224,229, 14,213,136, 37, 90,207, 19,201, 75, 67,237,151,177, -110, 57, 75, 85,145,177,246, 23, 61, 39,108, 16,189, 97,215, 85,238,199, 3, 34, 74,166,250,167,124,146, 55,225,128, 16,254,203, - 5,178,254,222,117, 77,124, 59,227,134,248,164,239, 46,228,243,139,219, 62,216,217, 24, 94,226,141,223,125,183, 86,243,252,201, -159, 29, 57,185, 73, 28, 60,181, 94,228,175, 27,243,105,202, 15, 67,237, 96, 51,253, 12,236, 48, 62,197,106,123, 20, 34, 22,213, - 68,206, 3,137,195, 32, 24,108, 79, 33,200,130,129,252,100,128,168,129,136, 99, 69,149, 58,172, 96,250, 15,158, 32,110, 85, 13, -205,220, 53, 11,229,186,115,117,245,239,226,162,111, 29,113, 4, 6,241,217, 18,197,184,141, 56, 41,172, 2, 45,168, 38,118, 97, -240,222, 5,149,217,174, 21,107,182,239, 27, 60, 99,211,209,142,195, 87,159,236, 54,116,201,209,153,243,150,239, 43, 92,184,240, - 82,187, 64, 75,170, 15,144, 7,233,198, 65,217, 93,168, 90,213,186,221, 59,152,172,116,105,163,245,156, 54, 90,144, 2,110, 81, -131, 45,168,202, 66, 1,173,126,253,250,121, 29,104, 89,161, 73, 94, 3,100, 7,233, 1,173, 82,165, 74,221,208, 2, 45,171, 52, -147, 38, 77,170,168, 10,181, 64,235,238,221,187,161,128, 22,237,120, 24,223,180,129,122, 57,130, 6,180,132, 0, 63,242,143,107, -208, 84,190,108, 71, 98,100,146,213, 48, 3, 45, 87,126,116,213,151,118,242, 7,245,222, 57,104,159, 5,118,187, 42, 18, 45,218, -103, 81,117, 72, 96, 68, 85, 46, 1, 17,213,125,180,221,130,139, 23, 59, 64,235,125,140, 35,135, 41,201, 98,122, 74,181,206,156, - 57,163,128, 44,214, 61, 65,156, 75,162, 69,151, 30,150,129,150, 39,213, 33,153, 25, 94,137,150,148,100, 73,201, 22,242, 22,194, -245,131,163, 58,244,114,231,123,179,200, 89,217,117,200,157,131,220, 65, 72,219, 45,245,174, 66,245,111,189, 93,135,220,169, 40, -211, 41,105,195,200, 58,181, 68, 75,173, 50,180, 48,238, 2,100,193,214,233,246,159,219,175,138,102, 19,175,137, 10, 61,119,136, -119,178, 54,185,165, 56, 17, 85,108,182,234,108,132,225,250, 95,200,152, 39, 59,162,255,231, 59,125,237, 81, 11, 55,156, 19,141, -199, 93, 19, 57,155, 46, 36, 64,163, 33,120,248,175, 76,159,231, 79, 94,244,235, 91, 43,119, 94, 21,173, 1, 6,171,253,180, 19, -249, 36,200,250,188, 80,120,136,127,133,237,198,173,226,198,154,183,170,102, 41,113,172, 99, 3,113,228,196, 90,241,223,249,127, - 69,255,128,212,162,241,164, 68, 34, 77,165,168,243, 62, 40, 30, 98, 75,178,149,207,105,221, 43,228,131, 72,126, 16, 86,186, 83, -105,155, 5,144, 53, 5, 59,137,250,129, 80,126, 43,196, 92,113,180,254,114,242,117,109,222,232,193,222,141,107,197,182,159,154, -139, 99,141,115,136, 26,233,226, 83,173,168,149,120,133,248,132, 90,117, 8, 21,212, 46,216,124,236,130,138, 98, 23, 0,224, 46, - 0,192, 93,176,133,218,133,237,232,187, 96, 92,174,220,233,250,193,134,234, 48, 49,192, 99,119, 2, 44, 87, 8,177,187, 80,245, -124,146,198, 70,203,210,174, 67, 12,212, 83, 36,216,162, 45,149, 90,162, 5,159, 82,190, 48, 62,182, 5,180,176, 99,108,140, 39, -213,161, 85,154,100, 48,212,196, 15,244,128, 22, 0,226, 77, 53,208,178, 73, 83, 1, 90,148,108,168,193,150,148,116, 72,169, 22, - 39,118,170,153,144, 7, 11, 29,222, 70,139,179, 22,213, 45,161, 82,171,243, 94, 96,170, 23,151, 26,104,121, 2, 57,234,207,153, -169, 6,205,222,123,202,186,183, 36, 90, 4, 90, 80, 45, 11, 44, 68, 4, 54, 62, 8,180, 73,101, 51, 4,236, 8,197,213,171, 87, -149, 93,162,116,245, 0, 27, 66,197,189,131, 13,137, 86,114, 72, 4,127,168, 94,189,122, 16, 37, 98,231,206,157,115,131, 44,238, - 66,229,115,142, 31, 40, 7,237, 48,109, 25,195,235,181, 81,249,204, 13,180,172, 25,195, 75,247, 14,118,140,225,181,238, 29,172, -181, 48, 39,214,219,192, 1,171,187,239, 95, 37, 47,202,106,198, 50,230, 37,164,141,150,110,238, 0, 94,146, 21,105,115,123,217, -182, 43,162,193,152,107,162,116,215,109,216, 21,216,248, 5,200, 10,235,149,161,206,166,109, 71,239,137,170,131,175,136, 15,170, - 13,167, 1,188,199,137,223,210,103,148,124,182,189,181,124,199, 85,241,229,164,235,162,162, 4,131, 25,235, 20,180,148,222, 32, - 18,165, 88,131,179,166,190,113, 14, 0,235,110,167, 58,226,230,103,121,197,144, 82,201, 68,221, 33, 9,196,232,115,233,196,152, - 11,233, 68,159,157,169, 68,145, 86, 49,175,135, 69,186,229,250,108, 65,236, 74, 26, 4,155,162, 41,216, 33,230,247,195, 15, 63, - 76,197, 32, 57, 0,239,212, 6,242,118,139, 81,176,123,171,102, 15,130,159, 63, 19,251,183,111,129,129,124, 18, 81, 37,117, 60, -130,172,207,204, 8,169,141,225,159, 60,121,162,128, 44, 0,192, 93, 88,133,238,154, 52,105,210, 46,248,250,218,213,163, 71,143, - 93,240, 3,180,171,114,229,202, 91,232,103,203, 42,208,194,138,190, 48, 0,212,111,170, 29,133,218,221,133,114,151,161,118,231, -161,222,174,195, 80,238, 29,134, 15, 31, 62, 5,118, 47,138,173, 22,192,133, 2,180, 8, 92,160,174,245,253,250,235,175,125,193, -103, 2, 45, 30,247, 99,120, 73, 63, 90,177,227,196,121, 48,103,206,156, 81, 84, 65,106,109,180,236,210,228,199, 0,114,142, 98, -119,217, 3, 74, 27,212, 23,212, 74,183, 8,180,194, 66, 19,234,231,251,116, 13,192, 9,156,234,194,155, 55,111, 42,128,139,119, -130, 44, 78,140,156,216,225,166, 66,113, 37,192,248,102,245,239,237,247, 70,160,197, 8, 8,217,144, 24,133, 71, 98, 21,170,152, - 90,251, 49,215,238, 66,126, 67,207,163,189, 37, 99,125, 56, 33, 61, 71, 95, 89,112,233,161,236, 44,236,214,173,155,192,130, 69, - 49, 88,167,205, 28,165, 93,216, 16, 35, 58,116,232, 32,126,254,249,103,145, 48, 97, 66,171,170,195,164,148, 34, 67,170,181,253, -195, 15, 63, 12,130, 61,167,160,218,144,180,209, 30, 30,196,143, 31,127, 47, 10,200, 93,135,220,113,108,203,189,131,165, 93,135, -250,126,180,220, 60,117,220, 59,120,187, 23, 57,244,192,129,200, 0,180, 88, 81,101, 93,224, 74, 46, 32,249,223,228, 2, 40, 34, -200,170, 59,234,154, 40,214,113, 75, 88, 65, 86, 8, 39,105,177,114,125,121,151,222,217, 9,180,226, 21,254, 14,246, 89, 13,146, -155,101, 67,231,125, 72,199,107,200,167, 63,242,217, 8, 82,178,178,223,111,123, 33,113,179, 15,178,220, 52, 1,176,122,125, 25, - 43,198,227,121, 21,139,139,139,112,151,112,167, 89, 25,113,244,163, 76,162,207,251,239, 93, 39,248, 34,168, 34,184, 34,200, 34, -216,234,183,251, 3, 81,173,119, 60,145,170,124,148,199, 41, 75,133, 48, 94, 55,115, 16,151, 2, 6,176,195, 8,178,176,186,245, -195, 64, 57, 59, 73,146, 36,122, 6,242,106, 22,152,209, 76, 93, 36,107,166,123,193, 88,217,210,127,210,150, 13,235, 68,195, 18, -121, 8,178,106,121,224,179,155,166,218,189, 3,140,119,119,210, 40, 30,119, 69,146,245,203, 47,191, 40, 64,139,210, 44,248,132, -218, 73, 23, 16,116, 5, 97, 0,180,244,242, 73,137, 22,253,149, 80,162, 21,106,119,161,235,185,244,163,197, 93,135,156,228,232, - 71,171, 25,238, 84,161,106,105, 74,207,240,116,241,176, 13,182, 46, 35,232, 47,139,206, 68, 9,180,160,142,241,237,211,167,143, -111,145, 34, 69,124, 93,219,205, 9,188,185,219,201,140,159,140, 83, 16, 0,171, 51, 38,199, 16, 64, 11,229, 30, 17, 70,154,239, -128,102, 23,216,106, 93,134, 75,143,135,148,106,240,202,159, 63,255, 29, 72, 52,134,135,149, 38,164, 32, 35, 1,160,158, 54,106, -212, 72, 49,132,102,157, 19,104, 29, 56,112, 64, 81, 85,125,252,241,199,156,192,159, 50, 30,190,207, 60,152,149, 61, 12,221,209, - 35, 77,187, 54, 87,122,241,245,218, 82,120,129,150,150,166,150,158,153, 39,123, 61, 62,133,160, 73,160, 5, 39,186,162, 70,141, - 26,202,206, 66,244, 19,209,176, 97, 67,209,180,105, 83,209,178,101, 75, 1,240,175,128,172,174, 93,187, 10,216,229, 17, 8, 91, -117, 88, 74,103,164,138, 31, 45, 72,182,122, 2, 88,157,162, 91, 18,220,207, 96,145,214, 27,207,165, 31,173,119,241,251, 85, 57, - 44,149,238, 29,236, 56, 44,165, 20,204,113, 88,250,162,101,153,141,243, 97,233,167,145,133,166, 94,217, 34, 11,208,178, 89, 47, -112, 64, 25, 61,251,151,247,186,204,186, 26, 30,144, 21,170,193, 68,201, 88,119, 87,133,222, 71,197,135,221,247,138, 40,153,235, - 31,182,153, 43, 25,253,255, 13, 70,149,207, 18,157,183,134, 21, 12,134,200,103,147,119,223,125,240, 8,222,213, 31,239,217, 44, -182,151,201, 34, 22,229, 73, 41, 90,196,137, 57,143,106, 68,153, 1,170, 11,169, 54,164,250,176,227,242,228,226, 72,208, 66,113, -246,209,122,241,126, 41, 31,245, 25,136,166, 13, 59,121,242,228,159,208, 64, 30, 82, 35, 35, 3,121, 45,139, 76,105, 34,193,144, -101, 99,126, 6,200, 90, 47, 26,150, 41,162,183, 11,209,144,166,214, 97, 41, 38,131, 45, 56,214, 69,145,106, 65,194,179, 11,128, - 96, 87,149, 42, 85,182, 16,100,209,169,169,246,108, 68, 21, 97,189,124, 42,198,240, 70,187, 11,117,108,183,204,142,224,225,231, -228, 89,135,156, 92,202, 96,149,223,131, 18, 44, 74,181, 48,193,249, 66,125, 67, 96, 87, 70, 78, 62, 58,237,205, 19, 63, 21,154, -152,196,220,187, 14, 75,150, 44, 57, 34,156, 52,227,208,101, 7,220, 61, 92,131, 63,173, 39,185,114,229,186, 3,169,196,240,240, -208,132,237, 85, 92, 0,169, 63, 0,210,159, 67,237,172, 72, 55, 0, 8,169, 42,124,142,231, 11,249,222,160,159, 89,105, 75,118, -187,104, 8,154, 6, 18, 33, 35, 73,145,124,174,149, 24,133,202,103,120, 84,131,174, 2,153, 1, 45,187,229, 14, 53,214, 1, 4, - 41, 64,139, 1,139, 20, 37,208, 11, 60, 65,149, 12,252,207,231,140, 99, 3,104, 37, 6,163, 18, 33, 36, 64,136,143, 16, 15, 33, - 46, 66,108,170, 11, 17, 98, 34,188,139,192,246,107, 13,104, 57, 71,240,132,165,190, 67,207, 71,225,161, 18, 50,109,132,247, 77, - 47,101, 53, 34,242,249, 22, 1, 45, 22, 53, 99,237,111,163,103,111,118, 61, 74,166, 6, 39,124,160,158, 11, 99,197,132,172,136, -244,117, 42, 70,201,220,224, 8,104,110,193, 81, 62, 31,122,133,166,151,243, 73,160, 69,144,117,237,211, 60,162,107,162, 56,193, -148, 98, 25,229,147,210,173, 92,245,163, 7, 19,100,141,187,152,214, 54,208, 34, 93, 26,200,195,171,179,158,129,188,222,103,173, - 54,236, 97, 69,179,164,163,129,188, 21,213,108, 8,137,150, 4, 79,174, 35,120,154,225, 62, 39,109,218,180,155,185, 27,145,191, -233,103, 75, 43,201,146,105,204,128, 22, 87,226,170,195,163,155,185, 14,143,254, 82,125,224, 44, 37, 88,234,231,174,213,187,222, - 89,135,122,252,225,198, 10,150,153, 18, 51,222,205, 54, 90,152,242, 19,234,196,115,160, 35,222,141, 17,243,158,183,104,130, 78, -114,212,249, 20, 0,109, 30,229,228,149,124, 2, 88,165,194,100,189, 25, 82,210, 96,222,249,223,164,127,153,150, 61, 12,253, 83, -143,166,153,116, 72,239,189,250,211, 17,158, 79, 47, 0,183, 80, 64, 11,187, 14, 15,146,174, 12,144, 54, 5, 50,160,222, 3,225, -158,193, 29,208,255, 3, 81,103,129, 0,102,175,224,172,195, 92,189,195,126,168,116, 78,218,145,234,129, 13,245,161,210, 29, 9, -182, 41, 81,214, 57, 84, 58,196, 59, 85, 63,215,163, 25,134,166,168,155, 36,194,219,146,151, 50,250, 54,231, 83,143,133,111,168, - 68, 43, 68, 81,149,195, 62,195,122,189,196, 6,227,157,124, 54,122,247,221, 62, 4, 91, 8, 15, 1,178, 6,152, 21, 60, 69, 73, -159, 1,148,100, 49,164, 40,229,243,163, 9,216, 48, 34,167, 53,144, 55,138,103,135,159,122, 7,202,234,209,213, 5, 90,106,105, -149,246, 80,105,173, 36,203, 34,208,226,183, 9,152,100,136,239,242,248,158,192,194,243, 80, 19,153, 73,189,120, 60, 14, 40,140, -117, 20, 41,104, 98,247, 42,109,115,172, 92,118,218,146, 21,122,118,235,200,161,105,206,129,136,173,163,132, 57,211,224, 72,157, -126,238, 3,165, 97,127,165,120,126,215, 94,210, 0,158,239,149,144,171, 55, 14,162, 78,227,161, 31,201, 62,158,200,117,172, 14, -181, 1,234,190,207,223,122,239,212, 95,142,216,178,155,243,222,106, 12, 39,159, 86, 57, 21,246,120,111, 3,208, 10, 59,119,144, -210,105,132,225, 98, 95,168,196, 14, 63, 29,126,122,139, 3, 78, 91,242, 22, 39, 95,208,113,248,233,240,211, 91, 28,120,155,219, -146, 30, 15, 29,160,101,210,178,222,230, 6,227,148,221, 91,195,142, 51,145, 57,109,201,105, 75,222,226,128,211,150,188,197, 73, -103, 92,138,136,182,244,198, 2, 45, 50, 75, 47,216,105,142, 70, 52, 60, 61, 55,163,239,208,212,175,151,176,214,151,195, 79,135, -159, 86,219,128,211, 55,141, 57, 96,149,135,234,120, 14, 63, 29,126,234,113,224,109,110, 75,146, 31, 86,230,179,200, 42,209,122, -105,249,142, 8,196,235,208, 52, 27,182,237,189,119,248,105,143, 95,102,177, 29,126,154,113,200,222,123,135,159,246,248,101, 22, -219,225,167, 25,135,236,189,119,248,105,143, 95, 97,137,253,210, 0, 75, 88, 50,247, 58,164,113, 26,161,119,107,193,225,167,195, - 79,111,113,192,105, 75,222,226,164,163, 66,114,218,210, 75,110, 75, 21,179,250,164,172,154,201,199,234, 38, 42,230,206, 99, 29, -145,150, 77,122,166, 52,189,200,146,200, 2,180,184,131,154,121,149,193,146,115, 99,111,240,201,233,128,222,224,226,255,105,168, -249,153, 5,143,103, 32, 44, 81, 5,250,141,210, 94,115, 52,113,232, 20,148,105,229,101,169,142,176, 69,123, 16, 14, 65,190, 3, - 71,158, 63, 89, 40,146, 30,205,116,240,189, 53, 63, 85,170, 84, 39, 17,206,225,144,227,127, 65,203,210,183, 93,223,211,139,155, - 49, 69,138, 20, 11, 16, 36,205, 53,160,105,237,220, 77,227,201,241, 61, 56, 22,173, 6,215, 11, 95, 33,180, 66, 62,233, 81,223, - 78,135, 9,145,207, 58,189, 15,190, 91,169,203,190, 56, 12,252,205,207, 90,125,102,183,142, 44,212,139, 58,138, 29,222, 91, 37, -237,208,180,202, 41,107,241, 28,126, 90,227,147,213, 88,145,142,159,240,224, 27, 77, 27, 42,103,242,249,185, 82, 70,159,103, 8, -207, 43,103,240, 25,161, 23, 71, 62,211, 27, 67, 60,208,123, 70,218,158,232,241,157, 21,154,146, 6,188, 78, 71, 55,163,167,161, -169, 87,151,145, 5,104,105,243,105, 45,223,245,129,154,235,228,244, 81,111,227,125, 15, 92,160, 3,200,150,174, 59,255,123,186, -172, 52,236,200, 66,211,106,103,182, 5, 96,108, 18, 85,243,115,118,136,243, 92,240, 7,180,150,104,233,225, 88,142,251, 60, 19, - 15, 71,234, 8,156, 95,168,156,177,134, 56, 51,108, 78,226,201,233,213,154,105,107,214,172, 73,255, 92,241,236,212, 59,252, 58, -213,129,255,173, 64,120,153, 15,126,248,240,145, 8, 14, 22,202,129,184, 0,110,215, 1,102,166, 88,228, 65,136,182, 4, 63, 81, -141,225,202,224,234,154, 53,107,148,178,241,156,183,173, 91,183,138,162, 69,139,222, 4, 80, 26, 23, 22,154,112,250,153, 21, 52, -219,254,245,215, 95,157,239,223,191,223,249,249,243,231,157,113,148, 77,103, 28,149,243, 13,104,150,181, 75,147,128, 42, 75,141, - 65,245, 50, 84,242, 61,203,192,223,197,135,111,137,101,229,153, 4,101,174,111, 90,233, 71, 22,179,231,142,230,208,180,203,177, -240,143,117,118,191,232,212,145, 93,142,189, 97,117,164, 5, 41,141, 82,249,124, 64,128, 37,214,247, 18, 12,252,205,103, 70, 96, -198, 12, 20,233,208,123,246,197, 7, 62,169,194, 11,222, 8,176, 98,225,116,141,178,165, 74,253, 28,221,199,231, 43, 51,176,101, - 82,205,214, 0,139,119,219, 74, 88,168,169,165, 89,242,183,103, 58,181,115,250,244, 69,120,134,240,188,106,102,229, 40,148, 86, - 56,183,235,151,249,243,231, 15, 61,113,226,196,208,121,243,230, 13,197,209, 18,191,240, 57, 40,241,252, 67,240, 51,212,101, 52, - 80, 48,110,129, 72, 64, 51, 44,204,150,105, 34,122,144, 92, 66,160,133,143, 93, 70, 88,226, 10,102, 18,173,203, 0, 16, 90, 64, -102, 37,159,197,120,132, 8, 15, 40,230,113, 34,248, 86, 94, 27, 64, 43, 53,174,107, 87,174,223, 18, 87,111, 63, 22, 23,111,190, - 8,103, 47,223, 21, 39,207, 92, 32,189,219,112,216,248,133, 5, 70,171,243,153, 1, 78, 84,175,177, 44,188, 0,136, 4,206,167, - 19,103,206,156, 81,206,247,171, 80,161,194,109, 56,138,172,109,147,230,123, 4, 89, 0,147,157, 65, 82, 9, 0,166,157,175, 92, -185,210, 25,199,250,116,198,217,142,223,224, 88,149,140,118,104, 82,138, 69,128,181,241,184, 16, 12,252, 93,182,247,193,184, 86, -158, 49,173,222, 32,105,225,251, 86,163, 88,169,119,171,180, 94, 86,155,183,155, 31,163,248, 78,217,141, 57, 89, 8,167, 9,156, -198,235,233, 8,222,242, 29,151, 21,253,177, 30,250,207,119,184,127, 7,135,173,245, 64, 59,171,141, 49, 36, 84,212, 36,153,202, -125,156, 36, 87,141,197, 73,114, 86, 59,147, 12, 33,121,110,252,206, 90,238,227,112,211,204, 89,125, 9,104,158, 5,205,211,164, -153, 52,123, 57, 51,167,207, 17,218,150,180, 0, 37, 67, 28,159, 10,149, 50, 69, 9,246, 22,208,210,161, 23, 10,104,213,207,232, -147,186, 97,122,159,180,118,164,100, 16,221,215,234,218,185,243,208, 51, 39, 79, 14, 43,247,225,135,131,215,226, 8, 48,139,224, - 77,175, 10, 35, 11,208,178, 55, 62, 65,138,149, 8, 0,235,241,211,127,123, 42, 21,218, 32,223, 59, 98,198,196,145,126,240,216, - 61, 84, 27, 48, 9, 13,197, 41,244, 67, 75,148, 40,241, 51,190, 82, 95,243,165, 16,141,176, 74, 38,159, 7,149, 50,249,136, 26, -217,223,185,231,231,231, 55,244,212,169, 83,161,232,145,190, 29,154,252, 94,165,204, 81, 79, 86, 47,150,121,225,156, 57,179,134, -121,139,166, 61,142,233,198,142,208, 14, 72, 96,229, 2, 90, 4, 89,242, 74,132,227, 93, 74, 65, 69, 87,145,129,191,241, 66,125, -126,216,146,187,119,239,218, 1, 90,116, 86,219, 7, 96,232, 57, 15,173,229,161,197,148, 32, 85,171, 86,237, 41,158, 19,212,209, -241,160,222,229, 46, 59, 36, 86,191,250,251,251, 7,223,184,247, 84,164,251,250,168,120,183,193, 65, 37, 36,254,242,160,216,180, -227,128, 66, 15,121,165,247,117,179, 75, 77,115,246,170, 85,171, 32, 23, 19,144,142, 5,139,219,183,111, 43,103,253,253,247,223, -127,202, 25,127,139, 23, 47, 22, 84, 39,154, 17,196,123, 55, 77,170, 11, 41,201, 34,192, 2,143,122,160,172, 61,209,150,122,130, -102, 15, 74,181,112, 56,115,103,228,179,133, 29,154, 14,208,178,192, 45,243, 40,158,250, 17,129, 64, 29,120, 97,159,151, 35, 71, -142,147, 80, 27, 47,112,141, 65,122,139, 62,245,151,172,244,205, 10, 80,113,111, 71,162, 38,230, 89, 84, 98, 88,161,105,145,148, - 59,218, 75,167,137,126,112,150,103,113,118,238,220,153,227,132,149,197,138,167,178,227,116,169,119, 27, 98,129,222, 29, 71,120, -249,162,175,251, 46, 95,190,220, 23, 7,106,251,150, 42, 85,234,123,120,201,111,136,196,138, 58, 93,231,210, 45,123,146,172, 37, -227, 1, 8,253,249,113,171,129,119,230,172, 58, 34,214,236, 14, 20,254, 91, 47,138, 97,115,119,138, 10,141,127,188,149, 50,119, -245, 63, 25, 39, 44, 52,235,126, 59,252,206,175, 75,247,139, 5, 27,206,137, 95, 87,156, 16,223,143, 91, 39, 10,127,210,233, 70, -138,220,213, 23, 37,207, 83,201,232,148,137, 8,173, 35, 53, 56,249,214,199, 39, 70,178, 36, 73,186,124,223,180,242,118,130,173, -138, 25,125,130,245, 84,135,140,103, 5, 20,105,233, 41,170, 72,141,234, 80, 79, 77,169,226,173,187,236,234,124, 86,194,137, 28, -201, 19, 39,254,249,228,209,163,195,246,239,222, 61, 44, 65,220,184, 63,105, 65,214,240, 15,124, 98,125,146,198, 39,135, 78, 62, -245,170, 46,178, 0, 45,123,170, 67, 61,160,181, 96,214,175,186, 64, 11, 43,254,161, 56,204,119, 40, 38,226,161,224, 16,131,225, - 5,144, 21,252,248,159, 30,162,113,225,184, 65,152, 16, 39,227, 64,101, 93,160,101,135, 38, 63, 70,240, 54,176, 94,166,135, 29, - 42,167,190, 49,169, 95,187,191,143, 29, 57, 56, 74, 15, 20,162,163, 15, 93,177, 98,133,105, 62,237,142,134,175, 40,126, 8,160, - 5, 96,145,189,116,233,210,149,142,159, 58, 85, 19, 96, 65, 9,135,143, 31,175, 9, 0, 92,137,239, 92,121, 92,194,131,135,241, -123,137,197, 60, 15, 0,136,118,107, 40, 9,106,228,197,243,217, 64,163,151, 25, 29,124,251, 8,191,121,227,238, 19, 17,163,225, - 65,177,251, 76,176, 56,120, 17, 7,177,213, 63, 32,150,174,218, 44,252,253,255, 20, 56, 59,241, 26,232,152,169,161,221,159, 2, -120, 59, 45,165, 89,164,125,254,252,121,128, 44, 30,164,188, 69,252,245,215,223, 98,222,188,249, 34,125,250,244,164, 25,203, 44, -127,242, 61,109,178,168, 46, 36,208, 34,200,146, 64,107,195,134, 13, 61,113,214, 99,231,133, 11, 23,118,134, 20,237,107,196,215, - 30,206,108,248, 9, 47,170, 14,173, 22,195,155,241,146,193, 46,111, 26,164,124, 7,113,159, 9,194, 41,194, 73,188, 8,210, 15, -196, 49, 52,171, 1,138,206, 97,146, 93,131,255, 92,156,149, 8, 35,221, 24,160,177, 14, 7,157, 43, 0, 27,253, 93, 28, 60,120, - 80, 57, 79, 16,199,218,108, 5, 77,179,227,151, 60,126, 54, 67,134, 12,103,217,174,112,190,229, 99, 68,140, 25,198, 60,106,147, - 17, 24, 82,250,111,180, 64,241,210,103,194, 76, 38, 85,245,234,213, 21, 94, 98,209,193,254,109, 85, 5,175,251, 65,130,172,190, -125,251,254,180,113,227, 70, 95,156,233,232,219,179,103, 79, 95,158, 69,138,131,233,125, 9,188,112,150,106, 47, 72,179, 9,182, - 44, 95, 4, 89,253,126, 93,253,124,227,129,107,162,235,175,251, 69,227,193,219, 69,243, 97, 59, 69,183, 41,251,197,232, 37,199, - 69,243, 94,179,158,165,202, 91,253, 79,203, 4, 17,145, 52,135,254,182,254,249, 63,123,174,136, 14, 19,246,186,104, 6,136,206, -147,247,137,222,179, 14,137,106,109,199, 62, 73,149,167, 58, 65,252, 75,191,212, 0, 5,141,176,236,128,126,253,134,220,184,118, -109,216,151, 13, 63, 31,153, 55,161, 79, 41,245,123, 24,222, 38, 73, 20, 55,110,157, 10,101,203,182,195,192, 87,204,200,246, 73, -166, 9, 65,175,254,167,163,180,244, 74, 39,246,201,174,167,166,212, 99,130, 58, 31, 88,229, 52, 31,216,191,255, 48,230,179,245, - 87, 95, 13,195,119, 62, 84,191,255, 40,141, 79,141,170, 89,223,185,222,169, 74,106, 81, 46, 93,148,205, 70,249, 84,125, 39,178, - 1, 45,153,223,208,249,134,212,129, 29,203,125, 81,117,248,121, 14,159,224,218,185,162, 4,119,109, 80,106, 63,236, 95, 38,195, - 22,102, 40, 84, 52, 67, 47, 95,190, 60,148, 32,233,194,133, 11, 67,241,124,232,240,225,195,135,206,152, 49,195, 20,192,168,129, - 22, 0,143, 66, 47,188, 52,153, 97, 2, 45,177,178,173, 56, 62,233,115, 49,166, 89,206,199,223,148,127,255,238,136, 46, 13, 54, -254, 23,176,117,220,185,115,231,134,162,108, 67,187,119,239, 62,180, 85,171, 86, 67,167, 77,155,102,154,207,151,222,155,194,246, - 65, 74,148,150, 32,240,158,136, 32,235,193, 99, 81,255,202,237,231,173, 79, 93,126,210,238,196,197, 71,237,206, 93, 10,106,115, -238,226,181,250,197,139, 23,175,204, 56,174,184, 50,141,167,175, 18,160, 20,128,186, 80, 57, 80,153,246, 84,101,202,148, 9,194, -121,108,103, 97,243, 21, 4, 73,143,130,183, 96,175,197, 67,171,115, 34, 24, 2, 26,172,144, 79, 61,124,248,208, 13,180,182,157, -124,166,128, 45, 2,173,223, 22,172, 16, 51,103,254, 38,112,118,226, 77,208,200,100,149, 13, 80,109, 92,124,252,248,177,160,116, - 14,109, 80,108,218,121, 64,204,249,115,187, 24, 63,119,173, 24, 58,117,185, 24, 48,102,158,200,148,171,240, 45,208, 75,111,149, - 38, 13,223,105,147, 5, 91,175,206,148,100, 49,236,219,183,175, 39, 36, 89, 61, 9,178,166, 78,157,218, 25,147,239,247,160,151, -216, 42, 77,198, 83, 27,190, 39,120, 63, 93, 58, 60,138,166, 99, 12, 31, 43, 73,234,252, 41,181, 70,243,118,190,227,229,184, 49, -147, 37, 75,118, 96,221,186,117,202,164,187,105,211, 38, 74, 29,143,226, 27, 97, 1, 47,113, 0,212,198,126,249,229,151,193,171, - 87,175, 22,232,143, 10, 77,222, 41,205, 68,159, 20, 48, 33,152, 12,218,102,118,127,234, 34, 70,133, 26,106,241,236,217,179, 5, -204, 24, 4, 14,232, 22,144,154, 60,255,241,199, 31,149,182,138, 3,202, 5,218,234, 42, 36, 48,147,108, 25,177, 45, 93,227,198, -141,149,124,118,235,214,141,227, 98, 73, 47,240, 55, 30, 84,232,187,190,248,226, 11, 74, 91, 3,108,150,151,159,175, 5, 9,219, - 49,244,149,235, 86, 3, 54,114,156,101, 19,180,145,247,218,190,190,190, 98,203,150, 45,138,132, 24, 64,105, 15,210,182, 70,224, -152,193,126,110,231,202, 10,201,119,119,130,172,246,237,219,251,182,107,215,142,192, 74,185, 19,112, 97, 1,231, 59,107,214, 44, -223, 34, 69,138,116, 3, 81, 51, 53,162,242, 93,170, 11, 63,105, 51,228,206,134,255,174,137, 90,190,155, 69,205, 94, 27, 68,173, -159,254, 21,181,125,255, 17,205,126,222, 36,126,250,237,160, 24,252,251, 17, 81,188, 86,231,235, 73,178, 86, 52, 83, 35,186,105, - 54,233, 52,242,238,202,157,129,162,230, 79,155, 69,169,230,147,159,165, 43,214,232,114,134,146, 77, 46,215,236, 48,227, 89, 23, -128,185, 31,103, 30, 20,121, 43,183,190,145, 40,115,153,136,144, 94,121,228,169, 4, 40,189, 33,249,203,252, 65,210,209,251,183, -111,154,248,223,222,189, 67, 99, 71,143,222, 92,190,163, 90, 46,182,143, 79,161,226, 69,139,118, 89,191,118,237,207,199, 33, 73, - 42, 86,176, 96, 27,218, 73,233, 17,103, 58,210, 75,157, 34,197, 0,130, 33, 45, 61,190, 7,189, 2, 37,242,229,240,213, 83, 83, - 26,209,100,186,154, 62, 62,177, 65, 87, 1, 89, 7,246,238, 29, 22,243,221,119,123,203,124, 82,138, 85, 38,173,207,212,111, 62, - 74, 17,124,118,110, 27,197,198,172,117,217,228,162, 92,202,144,245,175,197, 34,248, 94,100, 2, 90, 90, 59,173,144,236,210, 41, -156,207,123,239,250,204, 94,185,120,174,223,204,153, 51, 39,255,246,219,111,147,105,155, 5, 27,150,161,152, 99,135, 98, 21, 57, -116,228,200,145, 67,219,180,105,163, 0,152, 9, 19, 38,152, 2, 24, 53,208, 34,205, 29, 59,118, 40,246, 94,225,161,201, 82, 72, -160, 69,176,197,112,121, 86, 67,241, 91,187, 2, 79,191,173,152,234, 86,135, 14, 29,148,252,201, 96, 37,159,118, 70,147,215, 33, - 46, 85,132, 16,247,215,184, 25, 36, 90, 37,168,183,241,238, 59, 31,175, 11,102,224,239, 19,103,175,181,132, 68,166,134, 75,141, -104,154, 93, 12,174, 3, 48, 64, 62,169, 90,181,170, 50,193,242, 2, 80,187,141,132,201, 93,137, 83,193,136, 93, 49,142,130,113, -187, 96, 60, 0,174, 96,188, 67,223, 13,125,113,167, 33,233,156,190,112, 93,100,109,127, 24,106,195, 3, 74, 72,241,213,126, 49, - 96,200,104,209,168, 81, 35,218, 84, 5, 87,172, 88,241,113,182,108,217,238,193,126,131, 82, 35,143, 23, 38,156, 63,169, 34,188, -120,241,162,128, 52, 85,204, 93,190, 29,170,200, 3,226,157,122, 47, 66,172,122, 59, 68,201,106, 77,158,231,201,147,231, 42, 0, -212,133, 4, 9, 18,132, 62,191, 77,243, 5,238, 46,220,189,123,119,103, 44, 32, 58, 67, 50,210,131,146, 44, 44, 6,122, 66,197, -253, 3, 54, 2,108,194,121,143, 79,144,207,167, 0,156,143, 33,129,187,101,209, 6, 76,126, 37, 26,212, 90, 35, 49,209, 92, 6, -240, 92,134,135,234,243, 67, 19,228,206,157,123, 91,147, 38, 77,206,227,121, 87,179,178,191,164,247,109,209,183, 21, 73,209,199, - 31,127, 44,246,236,217, 35, 38, 78,156, 72,192,209,209,230,247, 99, 3, 84, 28, 36,240, 33,104,249,245,215, 95, 5, 0,151,192, -162,224,105,179,102,205, 20,154,172,195, 69,139, 22, 9,130, 8,208,182, 10,182, 90, 80,146, 69, 48,128,182,248, 16,233, 56,169, -242,140,199,106, 80, 73, 5,209, 86, 15,139, 63,230, 23,218,145, 48, 93, 29,153, 87,230,217, 53, 46,170, 15, 80, 14, 11,193, 24, -216,104,177,158,253,133, 52, 9, 56,177, 65,100,189, 43,207,150,232,161,125, 30,133, 10, 91,105,239, 86, 3,235, 13,146, 93, 43, - 42,116,153,135, 97, 44,239, 55,223,124, 35, 78,159, 62,205,141, 37,226,187,239,190, 83,190,151, 43, 87,174,251,136, 20,215, 82, -102, 17,137, 54, 89, 4, 82,148,100, 17,104, 77,154, 52,201,119,231,206,157,190, 11, 22, 44,240, 5,120,245,133, 68,220, 23, 11, - 24,223,193,131, 7,251, 98,225, 68,155, 45,211, 43, 25,108,178,166, 47, 63,168, 72,154,106,246, 90, 47,250,254,182, 87,172, 10, -184, 44, 70, 45, 62, 34,154,244, 95, 45,126,248,117,135,152,184,252,148,232, 60,114,149, 72, 87,168,214, 98, 83,130,136, 64, 59, -175, 37, 27, 78,136, 54,163,118,137, 82, 95,253, 26,156, 44,103,149,191, 19,102, 40,149,134,225,253,156,149, 87,180,234,247,251, -179, 95, 87,158, 22,223, 13, 91, 33, 82, 23,252,216,207, 10, 77,111,198,145, 32,165,108, 26,159,233, 84, 21, 86,201, 20,245,121, -205, 34,105,183,188,239,227,147, 78,190, 67,195,175,254, 83,207,158,253,207,157, 57, 51,236,204,169, 83,195,250,247,238,253, 19, -164, 72,101, 60, 73,180,146, 96,231,249, 55,109,219, 14,123,250,228,201,176, 38, 13, 26, 12,213,208,171,252,125,215,174,253, 72, -175,103,243,106,219, 43,103,138,242, 92,173,166,212, 43,159, 90, 74, 38,233, 54,110,216,112,152,148,172,241,125,185,116, 62, 91, -103,118, 44, 45,158,173,253, 65, 60, 95,251,163,152,211,165, 44, 37, 90,123,181,249,140,196, 64,203,188,234,245,128, 22, 82, 13, -197, 10,127, 40, 14,255, 13, 17, 40,205, 82,131, 23,254, 38,232, 98,124, 79, 95,210, 2, 45, 53,221,176,210,228,247,180, 64, 75, - 2,174,150,165,226, 63,106,208,160,193, 56,117, 94,173,228,211,156, 91,175, 87, 12,218, 99, 1,247,212,184, 29, 36, 90,251,212, -248, 87, 92,187, 39,148,192,223, 7,143, 93,104,189,125,251,246, 26,144, 80, 88, 89,141, 69,175, 85,171,214, 19,238, 78, 4,232, - 80, 36, 70,148, 28,161,180,255,169, 75, 12, 9,197, 81,105,128,190,119,239, 94,101,215, 31,128, 18, 39, 60,189, 3,200, 11,112, - 5,126,224,208, 81,177,110,203, 46,177,116,197,191, 98,246,252,165,162,243,247, 63,138, 78,157, 58,139,160,160, 32,101, 23, 34, - 3, 36,165,162,126,253,250,207, 48,169,248,155,112,184,120,190,124,249,110,114, 2, 64,217,196,212, 5,235,132, 79,157, 3,138, - 74,146,129,191,247,158, 2, 3,112, 81,197, 8, 41,194, 45,240,104,170, 9,205,148, 80,179,126, 13, 73, 86,103, 2,174,181,107, -215,118,254,227,143, 63,186, 2, 68, 94,199, 68, 17,172,206, 39,165, 49, 80,177, 60, 3,104,154, 97,161, 37, 64, 96, 19,109,204, -220,185,115,239, 48, 63,224,239, 41,164,193,130,209,125,229,128, 61,204, 21,190,131,218,235, 58,158,246,180, 64, 51, 66,163, 96, -226, 59, 68,176,130, 69,148, 2,174, 8,142, 88,102,186,230,192,127, 59,106,175,113,216, 52, 35, 14, 28, 56,192,246,241, 8,105, - 59, 33, 80,202, 72, 26,233, 16,218, 3,192, 62,128,228, 80, 1, 91,104, 87,102,117,164,148, 27,124, 63,200,252,125,251,237,183, -204, 95,117, 13, 51, 62,162,148,140,249,133, 4,233, 68, 24, 24, 21,143, 18, 86, 74, 74,153,119, 2, 35,180,139, 32,208, 73, 26, - 6, 90, 76, 18, 21,170,204,197, 28, 95, 9, 94, 0,182,149, 59,237, 8,177,168, 32, 24,208,235, 51,161, 62, 5,160,115,137,237, - 29,192, 55,216,138, 68, 11, 11,160, 96,198, 47, 88,176,224, 13,139,249,142, 13,112,180,141,224,181, 64,129, 2, 2,192, 72, 1, -153,252, 79,251,204, 1, 3, 6,144,215,166, 11, 22,249, 45,208,106,255,247,223,127,251, 66,202,168, 0, 45,104, 62, 20,176, 69, - 73, 22,109,180,186,116,233,226, 11,186,190, 75,151, 46,245,197, 14,226,246, 86,242,152, 44, 87,245,147,127,110,187, 40, 26,255, -188, 93,124,218,107,141, 88,177,253,162,232, 62,237, 63,209,105,210, 62,209,101, 98,128,104,222,255, 79,241,231,118, 0,175, 69, - 71, 69,218,130, 31, 91, 2,152,169,242,126,124,254,175,157,151, 68,157,126, 91, 69,186, 98, 13,175, 38,200, 86,150,237, 82,185, - 18,101, 44,157, 58,127,165, 22,129, 84, 41, 14, 95,112, 64,164, 41, 80,195, 18, 77, 43,101,177, 26,135, 32,164, 78, 90,159,244, - 53,178,189,163,216, 75, 63, 93,251, 67,112,197, 12, 62,207,190,124,223, 39, 41,223,161, 81,102, 6, 80, 26,120,231,198,141, 97, - 59,182,109,251,165,100,145, 34, 61, 1,110,138, 83,202,229, 9,104, 1,156,213, 88,186,120,241,176,231, 0, 90, 73, 18, 37,114, - 75,157,176,154, 78, 95,247,179,207, 20,122,187, 2, 2,126,129, 33,123,207,212,241,124,106,213, 79,247,127, 96,167,151,119, 9, -180, 32, 66,235,160,162, 59, 84, 5, 20, 59,252,220, 56,183, 34,197, 58, 55,175,173,104, 87, 33,165,248, 48,181,207,202, 79, 83, -249, 36,126,131,128,150,185,228,205, 8,104, 81,181,167, 5, 90, 84,199,105,129, 22, 86, 38,225, 2, 90, 97,165,201, 74,183, 3, -180,172,228,211,106, 39,120, 93,226, 73,160,117,237,246, 19, 5,104, 93,184,249, 92, 9,252,189,107,255,137,214, 0, 13, 86,129, -150, 15, 84, 46,191,114,162,162,234, 4, 43, 80, 5,172, 64, 50,196,193, 90, 74, 27, 18, 64,220,127,155,207,169, 98,128, 36,134, -113,131, 97,123, 51,214,136, 31,152, 24,123,195,214,229, 38, 39, 83,128, 23, 65,251, 46,174,154, 31, 60,126, 22, 98, 39,226,149, - 91, 79,196,237,123, 15, 5,118,248, 61, 3, 56,129, 20,218,248, 2,205,193,152,164,111, 46, 89,178, 68,140,153,185, 66, 1, 87, - 84, 73, 50,168,129, 22,243,121,243,230, 77, 74, 62,110, 64,170, 84,222, 19, 77, 0,188,178,248,118, 59, 72,178, 58, 99, 34,236, -140,178,109, 36,200, 98, 62,175,220,194,110,201, 27, 47, 2,127,223,131,158, 22,223,127, 10,154,158,108,140, 66,128, 44, 23,144, -234,172,201, 67, 20, 68, 26, 45,129,216,107, 0,182,202, 19,192, 80, 61, 12,169,203, 94,230, 53,126,252,248,219,169,146,195,228, -200,201,214,108, 23,150, 44, 94, 17, 74, 43, 9, 84, 32, 9,164,157, 83, 46, 3,222,103,133,132,235, 33, 37, 91,205,155, 83, 27, -226, 83,218,164, 95,149,236,212,169,147,146, 63, 72,137,168,218, 10,117, 37, 76,152,112,203,241,227,199, 69,143, 30, 61, 72,239, - 35, 27,253,244, 93,180,255,149,108,167, 24,243,168, 58,123, 72,245, 38, 54, 94, 8, 72, 69,119,168,250,128,101,146,160, 55,133, - 42, 78, 2,191, 42, 85,170, 16,108,126, 11, 16,244,136,246, 95,144,234, 11,168, 64, 45,185, 55,145, 64,203, 42,112,178, 17, 63, - 14,128,224, 22, 72, 85,159, 66,130,245,156,134,240, 40,247,113,128,203,231, 4, 89, 93,187,118,229,162, 66,217,205,139,118,186, -194,106,193, 1, 34,219, 99, 78,241, 29, 52,104,144, 47,234, 75, 81, 19, 66,155,224, 59,125,250,116, 5,112, 17,104, 97, 23,179, - 47,164,123,148,104, 89,146, 60, 38,207, 93,253,196,156, 53,103,196,151,176,201,170,227,187, 90, 12,157,127, 80, 1, 89, 63, 76, - 63, 32,122, 76,217, 37,154,247, 91, 38, 54, 31,188, 46, 38, 47, 63, 33,210, 23,250,228,184,149,188,126,144,239,227,243,243,214, -158, 81,236,178, 50,151,254,242, 90,162, 76, 31,230,144,233, 96, 84,159,181,100,173,111,174,236, 59,117, 71, 76, 88,122,232,245, - 1, 90, 25,125,158, 18,104, 53,131,237, 96,250,180,105,127,188,114,233,210, 48, 74,159,210,124,240, 65,119, 56,252, 75, 45,193, -141, 39,160, 69,215, 11,119,111,221, 26,182,125,235,214, 97,216,141,208,144,113,105, 28,159, 38, 85,170, 30,151,206,157, 27,118, -249,194,133, 97,160,221, 19,244,210,168,233,121,162,201,119, 80, 21,254, 44,233,194,152,181, 39,159,209,133, 68,253, 66,241, 30, -222, 91,217, 85,220, 89,209, 69,212,207, 31,247,121,241,148, 62,223, 24,229, 51, 18, 75,180,204,221, 59, 24, 1, 45, 72, 55, 66, - 1, 45, 12, 98,161,128, 86,159, 62,125,194, 5,180,194, 74,147,157,194, 8,104,181, 40,249, 94, 40,137,150,149,124, 90,233,160, -175, 83, 28,170, 5,177,122,173,113,233,218,221,150, 73, 26,110,188, 17,189,214,186,231, 12,137, 27,108,184,177,117,207,225,150, - 24,232, 45,171, 14, 93,229, 74,139,123,117,168,119, 20,235,119, 74, 28,176,138, 14,196,179, 0, 12,200,215,105,116,204, 11,210, - 39,170, 12,177,201,196,220, 80,154,206, 73,105, 24,159, 46, 93,186,171,152, 4,130, 9,126,180, 59, 17,147,126,117, 88, 28, 58, -113, 73, 64,165, 32, 0,122, 14,152,241, 24,147, 84,117,208, 60,154,189, 72,245, 91,113,235,110,118,239,104,228,238,198,253,103, - 94, 72,180,248,157, 35, 71,142, 8,168, 44, 72,243,111, 11, 52, 51,114,119, 33, 12,223,191, 65,153, 31, 75, 67,254, 20,173,254, -191, 99,146,191, 47, 92,185,163,128, 70,196,221,104, 68, 19, 18,154, 97, 26, 0,181, 26,113,199,235,132, 9,152,196, 54,202,184, - 88, 12, 80,178, 69,219,152,151,126, 1, 84,237,160, 4,138,170, 57,124, 28, 99,185,114,213,167,237, 14,118, 3, 11, 72, 70,247, -227,191, 21,169, 86,111,216,183,137, 41, 83,166,144, 14,237,112, 60, 93,237,185,233, 2, 42,110,198, 29,100, 18,183, 15,129, 15, -164, 34,140,107,180, 11,180,241,208,161, 67, 21, 73, 12,226, 12,182,200,196, 28, 0, 83,219, 9,126, 8, 54,138, 21, 43,246, 0, -233,202, 64,186,115,135,237, 7,146, 23, 1, 53,244, 65, 60, 43,110,145,158, 15,234,127, 32,203, 69, 16, 89,175, 94, 61,238,212, -165,173, 36,175, 42,144,180, 63, 35, 8,101, 57, 24,207,140,166, 13,224,164,144,178, 17,127, 56,192,143, 2,136,161, 46, 23, 4, -133, 72,206, 77, 46,165,209,191,168,222,236, 12,208,180,159, 18,196,194,133, 11, 19, 48, 91,178,211, 67,154,186,163, 70,141, 82, -192, 85,191,126,253, 20, 96, 69, 73, 22, 65, 22, 85,135, 4, 94, 80, 77, 43,119, 0,173,186,102,229,231,251,247,243,212, 92,216, -123,202,102,209,229,215,125,226,203, 33,155, 68,195,222,127,137,239,198,237, 16,221, 39, 7,136,166,125,150,137, 81,191,239, 17, - 91, 14,221, 16,131,103,110, 20, 25, 10,215, 90,104,133,102,138,188, 53, 22, 15,158,189, 93,124, 55, 97,159,168,253,253, 60,145, - 50, 79,245, 93,241, 51,150, 42,152, 56,203,135, 69, 82,229,173,182,103,218,146,157,193,123, 78,220, 22, 3,167,254, 43, 50, 20, -122,117,170,195, 50,153,226, 5,208, 94,170,114,198, 40,207, 75,166,246, 97,167,162, 29, 85,225, 41,147, 39, 15,123,254,244,233, -176,250,117,235,254,130,255, 5,173,130,162, 92, 57,114,252, 2,191, 56,195,134,253,242,139, 91,189,135,244,249,199,142, 26,165, -208,107,250,197, 23,191, 64, 50, 86, 84, 75,207, 12,104,229,204,145, 99,152,164, 11, 0, 87,159,241,203,165,241, 25,178,162, 95, -117, 69,154, 53,160, 65, 78, 81,226, 3, 31, 54,178, 16,142, 88,213,117, 21,201,129,150,149,102, 23, 42,142, 98, 63, 69,123, 44, -181, 84,139,255,213, 18, 45,218, 65, 65, 68,108, 11,104,193, 31,215,100,111,208,100,142,173, 2, 45,171,249, 12, 19,167, 94,126, -162, 16,198,240,220, 93,120,238,226,213,122, 71, 79, 93,106,185,255,240,217, 86, 59,247, 30,107,181, 97,235,254,150,255,172,221, - 84, 15, 18, 40,187,198,240,178, 52, 99, 81, 79, 10, 96,145,106, 56,249, 27, 54,123, 28,144, 61,170,138, 13, 88, 18,255,195, 15, - 63,124, 76, 58,218,157,136,116,251,176, 97,231, 33,177,110,221,122, 2, 59, 78,116,150,174,172, 85,186,228, 41, 88,174,206,173, -253,167,239, 9,134,131,103,239,139,235,119,158, 8,168,163, 21,144,197, 9,132,160,136,246, 90,150, 8,190,136,148, 10,134,255, - 74, 62,175, 99,199,164, 86, 53,121,240,248,121,197,175, 24,236,202,238, 24,208,140, 10, 0,124,196,205, 60, 27, 63,168,150, 5, -205,197, 54,242,234,141,168,220, 17,247, 13,165, 86, 4, 26, 0,144, 84,187,201, 29,150, 81,169, 78, 36,208,234,223,191, 63,243, - 70,169,156, 71, 31, 75,144,138,252, 73, 21,153, 75, 74,101,182,209, 33, 5, 29,226, 82,234, 3,149, 19,119, 35,122,186,102,177, - 78,169,130, 67, 36,238,224,211,187,114,124,245,213, 87,138,138, 46, 74,148, 40, 86,118,139,213,130, 36,243, 41,213,229, 52,174, -135,164,146,146, 39,121,194, 64, 65, 56,172,189,199,111, 82, 21, 71,233, 45,128, 81,127, 11, 12,111, 78, 94, 17,192,180,110,221, -154, 11, 18, 45,152,104, 8,169,110, 48,223, 3,136,176, 44,109, 61,209,196, 2,229, 16, 1,112,214,172, 89, 47, 89,248,182,143, -213,248,168,215, 35,204, 3,235,137, 82,194,186,117,235, 50,175,249, 52,223,232, 3, 91, 69,241,195, 15, 63, 48,159,150,236,169, - 16, 47, 43,198,157,239,177,120,112, 75,179,104, 4,143, 77, 73,202,142, 67,240,210, 23, 54,100,190,176,121,236, 6, 64,103,205, - 24, 30,126,178, 74,212,234,116,235,231,249, 71,197, 79, 51, 15,136, 31,166,236, 20, 95,245, 95, 46,154,247, 89, 42,198,252,177, - 79,236, 59,117, 91, 44,221,114, 73,148,171,253,221, 13,203,198,240,160, 89,161,209, 15,183,250,206, 57, 44,126,156,113, 80,116, - 27,245,183, 40, 87,183,203,141,106, 77,122,220,244, 91,185, 87,156,187,250, 64, 44,219,122, 89,148,170,213,238,149, 25,195,247, -134,225,122,145, 66,133,134, 29, 63,176,107,114,231,118,173, 38, 37, 4,142, 38, 80,137, 30, 45, 90, 83, 74,158,104,151, 5,149, - 93, 71,171,160, 72,210, 35, 32,234,245,195, 15,195, 36, 61, 74,182,232,247,234, 50, 36,100,239, 68,141,218,117,173,129,239, 43, -189,246,199,111,211, 16,158,249,148,116,161,158,172,202,231,229, 51,248, 28,188,177,180,163,184,178,168,189,248, 40, 67,148,187, -141, 18,249,188,103, 5, 16,170,190, 99,174,146,179,210, 41, 94,227, 56,223,211,216,157,210, 38,170,246, 96,143,163, 0, 46, 12, - 72, 10,208,130,138, 97,104,239,222,189,135, 98,192, 24, 10,207,223,156,116,185, 43,203,240,162, 31,173, 42,153,125,158,215,206, - 23,231, 42,196,243,147,189, 65,147, 31,171,146, 37,234,195,207,115,199,120,190,226,199,210,138, 49,188, 12, 82,162,101, 55,159, -175,113,125,168,179,182,132,238, 22,240, 96, 9, 31,210,133, 3,119, 23,194, 46,162, 6, 84,122, 53,104, 0, 79, 73, 22, 65,150, -218,189, 3, 87,215, 50,141,133,114,210,199,205,248, 22, 45, 90, 4,115, 18,162,189, 19,213,137, 77,155, 54,229, 96, 60, 2,193, -178,171, 3,213,183,162, 65,253,241, 72, 13,180,228, 78, 68, 2, 45,255,127,182,138, 57,115,252, 4,220, 10, 24, 1, 24,189,108, -191, 75, 73,153, 26,203, 16,100,113, 98,148, 32,107,236,216,177, 4, 90,150,212, 9,174, 15,196,133,186, 83,201,167, 4, 90,106, -213,228,150,128, 3,130, 18, 27, 24,198, 95, 53,226, 35, 38,228,145,225,144,104, 89,241,217,101,161, 10, 45, 69,249, 52,111,222, -188,119,168,106,163, 74,139,234, 34,164,210,250, 80,170, 1, 53,170, 34,157,193, 22,125,218,254,208, 56,186,177, 17,117, 72, 15, -247,145, 22,232,222,182,146, 3, 0,136,203,140,143,113,132, 59,229, 12, 47,216,243,108, 35, 48,160,145, 62, 34, 37, 48,136, 24, - 11,106, 58, 5,196, 48, 31,102,223,135,138,116,139, 84,229,161, 29,209,167,155, 86,125,153, 31,192,243, 48, 36, 52, 74,249,173, -168,239, 64,103, 7,191,239, 82, 95, 26, 73, 39,219, 81, 82,200,120,216,209,186,217, 36,159, 53, 1,138,118, 34,206,167,102,229, -113,189,183, 18,191, 60,108, 16,159, 19, 92, 2,144, 30,135, 84,149,126,195,190,211,161,159,239,243,207, 63, 87, 22, 45,249,243, -231,231, 2,200,146, 75, 6,184,223,104,128,177,163, 23, 22,107,190, 43, 87,174, 84,236,180, 40,197,130, 68,220, 23, 82,114,218, -111,245,130,154,183,129,197,242, 40,209,222,207, 83,205,191, 78,199,201, 79,250,206, 62, 36, 38,175, 56, 37,150,195, 38,139, 82, -172,173, 8, 75,183, 94, 18,237,251,205,120,146,182, 64, 13, 51, 27,207, 16,159, 76, 9,119, 16,117, 58, 77,126,218, 7, 52,103, -172, 58, 35,214,236,189, 42, 40,197,218,117,252, 22, 64,214, 37,209,174,247,212, 39,233, 11,126,108, 5,176,219, 41,138,165,184, - 4, 36,101,177, 9,225,163, 82,133, 39,157, 58,180,103,242,119,237,219, 15,163, 33, 59,159, 23,204,155,119, 16, 65,205,216,209, -163,135, 1,212, 84,178, 10,180, 20,122,229,202, 41,128, 72, 77, 47,103,246,236,253,248,140, 82, 50,208,171,166, 71,207,147, 68, - 11,171,169,164,106,186,116, 31,209, 54,141, 79, 66,236, 44, 84,236,203,150,254, 84, 69, 64, 26,183,218,106, 62, 85, 12,138, 44, - 64,203, 92,117,104, 80,235, 52,212, 44, 14,181, 15,197,189, 67,209, 65, 20,103,162, 4, 90, 88,133, 41, 32, 11,122,253,161,152, - 80,124, 25, 15, 65,107,216,169,103,128,237,117,154,216,191,252,110,185,244, 62,243,171,100,137,242,172, 81,161, 56,207,119, 14, -135,152, 18,128,139, 64,171, 99,199,142,227,194,152, 79, 75, 29,193, 67, 36, 43,198,231,118,191,161,166,185,132, 71,235,128,192, - 18, 21, 17,197, 97, 41, 13,223, 25,244, 28,150,114, 66,209,164,177,146,207,202,181,107,215, 86, 12,207, 93, 19, 28, 29,161,122, -186, 60,210,196, 78,168,203,180,129,185, 9, 39,166, 57, 58, 30, 83,252,107,113, 39, 98,202, 22,255,137, 57, 11,254, 84,156, 37, - 34,255, 90, 53,159, 71,154,116, 63, 16, 24, 24,168, 96, 45, 58, 86, 37,200,162,234,136, 42, 67, 26,246, 66,101, 28, 12,187, 46, -173,177,181, 71,154, 0,123, 55,168, 38,165,138, 51, 83,187, 99,226, 93, 87, 62,211,182, 57, 36,254, 90,179, 89, 96,133, 46, 48, -249,205,215, 48, 66, 77, 83,207, 70, 43,212,206, 66,244,175, 17, 38, 54, 90, 86,234, 40,204,109, 9,182, 78,155,216, 46, 40,201, - 34,200, 66,166,117,237,134,232,166,129,187,208, 56, 49, 19,112,128,231,187, 61,148,189, 38,128,173, 45, 96,128,248,156,232, 63, -247, 64,211, 7, 42,221, 3,204, 43, 84, 99, 30,141,188,179,100,201,114,142,241, 0,224,244,164,152, 90,126,214, 64,219,160,203, -133, 1, 8, 70,174, 74,184,168,232,136, 69,203, 38,220,191,209, 97,182,150,102, 45, 72, 59,119, 33,158,153,253, 81, 43,128,172, - 61,136, 87,195, 2, 77,187,117,172, 23,223,157, 79,212,243, 95,108,223, 46,219, 59,143,170,106,212,253, 12,248,191, 18,180,125, -131,221, 25, 85,138,234,203,168,125,190, 11, 63, 89, 13, 32, 17,236, 70,181, 33,237,177,104, 0, 79, 41, 23, 37, 89, 46,144,197, -197,156,199,124,170, 95,210, 25,105, 74,128,173, 66,213,218,221,232, 58,230, 31, 49,102,201, 81,241, 43,108,178,134, 64, 93, 72, - 73, 22, 65, 86, 88, 28,150,166,202, 87,253,207, 98,181,190,187,241,253,232,213, 98,130,255,113, 49,253,239,147,226,151,153,235, - 69,249, 58, 29,175,167, 43,248,241, 43,117, 88,250, 81, 6,159,145,240,103, 21, 76,213, 97,173, 34,105, 2,224,208, 46, 45,252, -141,196,171, 82,185,178, 2,150,190,253,230, 27, 55,248,242, 32, 41,114,215, 81, 54,184,168,249,184, 70, 13, 37,109, 75,248,185, - 34,189,102,176,247, 42, 87,166,140,242,172, 75,167, 78,195,224, 11, 40,167, 5,160,229,166,201,184, 52,164, 87,211,165,106,179, - 78, 6,159,220, 61, 63,201,168,168, 13,199,182, 44, 36, 10,189,239,227,251, 6, 3, 45,217, 84,195, 12, 12,217, 25, 42,194,104, -114, 0, 86,179,138, 84, 11, 43,161,161,232,112, 28,152,200,108, 91,157,197,149, 27,175,211, 44,130, 29, 12,229, 51, 69, 89, 95, - 57,115,148,224, 54,165, 19, 61,111, 86, 44,238, 99,168,127,198,133, 51,159, 97, 29,220, 34,116,114, 68,166,150,240,124, 63,220, -205,142,224,145, 42,198, 37,140, 75, 3, 87,166, 85, 21,202, 74, 62,147,210, 30,139,187, 16, 97,107,226, 73,146, 32,201,122,164, -137,250, 40,143,129,246,105,224, 85, 72,157, 78, 94, 16, 91, 33, 29, 34,112,153,187,240, 79, 49,102,220, 36,129, 29,133,180, 5, - 73,103,113, 48, 87,162, 1,172,124, 84,190,124,249,235, 4, 91,135, 14, 29, 10, 1,178, 96, 39, 34, 0, 58,105, 99,134, 93,204, -150, 38, 8, 37, 18, 12,252,107,209, 11,254,173, 59, 65,226, 20,220, 83,236, 59,116, 74,108,218,190, 79,172, 92,179, 73,204,246, -251,157,147, 61,119, 90,154,209,212,238, 58,164, 27, 7,245,100,158,209,194,174, 67, 43,117,100,183,157,170,105, 86,133,228,231, - 48,213,125, 32, 98,118, 28, 82, 3,240,122, 25, 0, 7,141,195,121,224,182,250,138,232,124,242, 91, 4,112,116, 72,250,137, 73, -129,101, 60, 61, 9,208,203,200,167,221,250,208,139, 31,209,249,252, 8,117, 73,208,244,131,133,204,114,188,238,135,198,188, 28, -247, 10, 54,235, 61, 43, 93, 56, 64,114,248, 29, 3,234,143,199,241,152,169, 11, 61,150,157,170,193,180, 5, 63, 89,156, 38,127, -141, 51,105, 11,212, 60,147, 1,238, 28, 44,168, 11, 77,105,194, 45,196, 18,208, 59,155,182,192,199,167, 51, 22,169,133, 35,120, - 42,154,109,254,136,208, 58,226,185,131, 60, 64, 90, 30,185, 67, 55, 11, 37, 18,250,228, 42, 10, 7,207, 85, 42, 86, 84,128,209, -231,159,126, 58, 44, 11, 60, 85,152, 0, 24,119, 62, 11, 98,127,139, 59,109,173, 90,195, 40,137,130,161,109,156,178,165, 75, 15, - 37,189,198, 13, 26, 12, 75, 11, 37,137, 93,160,245, 1,204, 45,212,116,147, 98, 71, 36,129, 86,143,143, 51, 40, 64,171, 79,221, -108, 4, 90, 95,188,193, 64, 43,204, 18, 45,109,255,163, 31, 21, 14,174, 52, 88,229,221,204,175,138,149, 70,232,117,154,216,209, -144,173, 98,230, 40,135,170,103,127,135,171,222, 58, 94,202,167,133,177,232,165, 78, 58, 51,232,122,129,206, 64,233,122,224,222, -189,123, 70, 42,193, 37,148, 62,112,117, 79,144, 69,187, 21,228,114,182, 42,167, 86,234,136, 59,207,166,192,126,227, 57,142, 59, - 25, 99,129, 17,166, 52,161, 2, 26, 4,131,227, 39, 84,199,112,171, 59,253, 22,193,153, 33,119, 56, 62,194, 74, 87, 79, 53, 97, - 74, 19,147,255,143,217,179,103,191, 14,231,162,138, 81, 47,125, 65,193,174,228, 57,182,249, 95,198,202,186,138, 78,190, 77,105, - 98, 82,152, 12,155,178, 39,147, 39, 79, 86,118,159,193,190, 68,145,184,193,187,249, 35, 24,252,234, 29, 81,162, 71,147,126,180, -134, 65, 13,127,153, 62,192, 52,249,136, 3,192,182, 3,182, 63, 23,241,220, 72,245,110,154, 79, 11,117,162,141,226,208, 12, 3, -211, 60, 36,113,248,233,240,211, 91, 28,112,183, 37, 61,160, 37, 15,145,142,243,238,187, 13, 8,142,128,128, 27,216, 5, 69,177, -162, 69,171, 83,170, 88, 49,166, 85,118, 28, 50,240, 25,233,193,246,171,137, 17, 61,141,234, 48,132, 68,139,239,222,125,231,157, -239, 75,149, 40, 49, 76,238, 56,228,179,143, 50, 70, 57,216,185,106, 26, 81, 58, 93,148, 99, 77,146,251,196,121,131,129,150,183, -234,223, 77,199,170,109,142,157,193, 39,178,208,180,202, 76, 59,101, 15, 11, 77, 44, 98, 20,192,180, 68, 21, 40,189,210, 94,106, -137, 22,227,206, 64, 96, 90,121,217,201,167,218,255,147,167, 60, 91,165,153, 23, 43,221, 21, 80,243, 92,133, 58,241, 34, 86,187, -126, 32,154,218,128,176, 85,154,185, 1,184,126,131, 42,232, 40, 84, 91,123, 65,127, 4,232, 37, 11, 15, 77,128,203, 98,160,183, - 22, 42,158, 91,176,189, 9, 4,205,185,160,167,149,100, 89,225, 39,118, 75,235, 26,145, 83, 90,192,119, 70,151,213,178, 91,109, - 71,140,231,208,180,195, 45,243,184, 14, 63,205,121,100, 39,134,195, 79,112,139,160, 68,239,188, 65, 9, 86,104,128, 30, 86, 80, -212, 12,234, 66,109, 90, 51,122,102, 64,139,239,169,214,212,210,173,158,250,133, 1,191, 5, 64,168,215, 70,194,172,138,179,211, -224,188, 16, 87,230,147, 99,185,148,110,121,129,172, 57, 9,167,179,152,243,200, 78, 12,135,159,118,184,101, 30,215,225,167, 57, -143,236,196,112,248,105,135, 91,230,113, 29,126,154,243,200, 78,140, 72,203,207,138, 89,125, 82, 86,205,228, 3,237, 92,152,175, -200, 82,246, 55, 1,104,201, 50,188, 52,128, 24, 89, 42,215,201,103,152,251,175,110, 66,135,159, 14, 63,189,197, 1,167, 45,121, -139,147, 47,232, 56,252,116,248,233, 45, 14, 68, 68, 91,138,204, 64, 75, 45,201, 34,200, 10,161,165, 32,179,244,130,157,202, 48, -162,225,233,185, 25,125,135,166,126,189,132,181,190, 28,126, 58,252,180,218, 6,156,190,105,204, 1,171, 60, 84,199,115,248,233, -240, 83,143, 3,111,115, 91,146,252,160,105,135, 94,208, 26,150,155,245,161,183,250,125, 68, 32, 94,135,166,119,155,148,195, 79, -135,159,222,226,128,211,150,188,197, 73, 71,250,228,180,165,183,179, 45,121,183,212, 47,151,154,215,118, 29,218,205,182,211, 89, -236,114,204,115,124,135,159, 14, 63,189,197, 1,167, 45,121,139,147, 14, 40,114,218,146,211,150,188,203, 1,135,154, 45, 14, 56, - 29,208, 22,187, 76, 35, 59,252, 52,101,145,173, 8, 14, 63,109,177,203, 52,178,195, 79, 83, 22,217,138,224,240,211, 22,187, 76, - 35, 59,252, 52,101,145,173, 8, 17,193, 79, 91, 25,120,205, 34, 75, 27,173,240,237, 58,252,249,231,159,163, 98, 43,126, 60, 56, -155,203, 3,239,208, 81,113,222,152,217,225,178,166, 21, 49,116,196,152,168,216, 50, 31, 15, 12,203,115,253,230,221,168,205, 91, -116, 13, 55,205, 48, 48,223, 52,159, 14, 77, 91, 28,112,248,105,139, 93,166,145, 29,126,154,178,200, 86, 4,135,159,182,216,101, - 26,217,225,167, 41,139,108, 69,120,155,249,105,139, 81,175, 89,100,185,203, 48,124,187, 13,225,160, 49, 42, 64, 86, 10,132,129, - 56,252, 85,241,110,141,115,172, 60, 1, 35,211, 6, 3,111,212, 60,146, 7,167, 0,248, 12,132,215, 97,133,230,239,203, 54,134, -139,166, 30,243,225,251, 8, 71, 68, 25, 94,134,249, 52, 73,231,169,158, 77,203, 30,134, 70,226,208, 12, 3,211,194, 82,239,225, -248,140, 83, 71,225, 96,158, 78, 82,135,159, 14, 63,189,197, 1,167, 45,121,139,147, 47,232, 68, 4, 63,189,155,195,151, 75,205, - 59, 54, 90, 9, 18, 36,136, 14, 15,219, 31, 2, 99,237,133,115,201, 50, 22,202, 96, 90, 17, 56,230, 36,122,140,152, 49, 63, 4, -200,218, 27, 39, 78, 92,175,208,132, 23,238, 10, 0,133,231,112,168, 41,207, 90,139,141, 60,239,130,103,243, 64,220, 55, 27,228, - 89, 55,159,140,239, 74,199, 51,203, 98,147, 30,233,146,190, 55,202,110,129,134, 54,138, 41, 63, 29,154,182, 56,224,240,211, 22, -187, 76, 35, 59,252, 52,101,145,173, 8, 14, 63,109,177,203, 52,178,195, 79, 83, 22,217,138, 16, 17,252,180,149,129, 72, 25,217, -223,223,159,199,179,232, 94,144, 98, 69,205,157, 59,247,135, 80,243,109,202,153, 51,231, 99, 28,107,178, 0,192,195,236, 8, 30, - 51, 62, 68,205,146, 45,199,135,169, 82,190,191,169, 64,166,148,143,113,220,201, 2,120,225, 14, 15,205,104, 0, 71, 35, 43, 87, -174,124,123,211,166, 77,130, 32, 9, 25, 72,136, 3,138, 47,242,176, 97,120, 12, 15, 54,203,144,250, 61,227, 51, 29,211,147, 14, -233,145, 46,233,243, 59,120, 22,205, 14, 61, 39,174,195, 1,135, 3, 14, 7, 28, 14, 56, 28,112, 56,224,153, 3,158,176,200,107, -204, 59, 41,209,242,116,202,135,143,143, 9,208, 42, 8, 53,218,254,142, 29, 59, 62,231,185,111, 0, 92,219, 1,140, 74,224, 89, -136,163,115,190,252,242, 75, 51, 27, 43, 53,159, 10,190, 23, 63,193,254, 25, 29,170, 62,127, 48,173,150,248, 32,101,242,237, 56, -231,174, 4, 0, 77, 8,154,141,155,183,182, 66, 51, 21, 36,110,123, 97, 71,246,240,214,173, 91,196, 71, 2,255, 9,180, 18,225, -248,148,139, 39, 79,158, 20,200, 43,129, 36, 85,149, 86,174,168,140,207,116, 76, 79, 58,164, 71,186,164,207,239,240,123,120,158, -202, 10, 49, 39,142,195, 1,135, 3, 14, 7, 28, 14, 56, 28,112, 56, 96,206,129, 72, 10,180,100,193,212, 42,196,208,133,213, 22, -174, 72,145, 34, 49, 1, 50, 74, 64,122,243,105,146, 36, 73,182,181,104,209, 66, 80,162, 51,122,244,232,103, 53,107,214,188, 80, -188,120,241,185, 89,179,102,109, 14, 85, 98, 62, 72,188,154, 0, 32,165, 52, 59,149, 61,111,254,194, 49, 19, 38, 76, 84, 34, 70, -140,152,159,198,139,247,222,182,110, 45, 62, 23,193,103,167,138,103, 19,242, 62,107, 90,173,200,133, 50,133,115,206,205,150, 62, - 85,243,119,162, 69,205, 23, 37, 74,148, 38,160, 77,116,104,118,210,123, 38, 28,214, 27,184, 98,197,138,224, 51,103,206,136,205, -155, 55, 43, 64, 43, 94,188,120,183,144, 54, 30,222,225, 92,229,139,148,112,241,144,105, 43,160,141,204,137,194,248, 76,247, 63, -246,174, 2,172,138,166, 11, 95, 27, 21, 37, 20, 68, 64, 64, 64, 4, 65,236, 86,236,238,238,252,236,238, 14,236,238,238,238,238, -238, 86,236,238, 86,196, 64, 64, 12,234,252,231, 93,185,252,151,235,141,189,120, 13,116,150,103,158,229,238,206,158,157,121,231, -236,206,187,231,156,153,193,245,144, 3,121,144, 11,249,184, 15,238,135,251,242, 57, 94, 0, 93,108, 2, 1,129,128, 64, 64, 32, - 32, 16, 16, 8,252, 40, 2,241,148,104,233,182,104, 41, 43,165, 90, 57, 38, 76,179,152, 96, 93,229,197,126, 63,177,155, 48,164, -119,239,222,225, 87,175, 94,165, 3, 7, 14, 68,142, 28, 57,146,124,125,125, 35, 42, 84,168, 16,148, 39, 79,158, 23,188,120,239, - 93, 38, 68,129,124,205, 89, 78,121,117,128, 60,203,196, 36,217, 85,123, 91,219, 79, 54,214, 86, 33, 35,250,117, 11,143,250,176, -143,200,127, 84,228, 87, 95, 59,122, 58,216, 43,162, 91, 73,199,160,242,217,108, 94,216,167, 73,121,151,227,182, 2,153,108,157, -101,121, 90,101,178,213, 41, 55,147, 29,186,114,229, 10,241, 72, 72,186,124,249, 50,249,249,249, 73, 68,139,175, 67,178,176,183, -183,127,241,246,237, 91,229,111,217, 68, 11,215,227, 58, 92, 15, 57,248,141, 13,242,113, 31,220, 15,247,197,253, 81,142, 31, 85, - 46,113,189, 64, 64, 32, 32, 16, 16, 8, 8, 4,254, 85, 4, 52,113,145,191, 6, 11,174, 92, 49, 84, 16,123,101,165,152, 48,229, -115,117,117,221,156, 35, 71,142,200,217,179,103,211,134, 13, 27,104,225,194,133,145, 83,167, 78,165,113,227,198, 73,105,226,196, -137, 81, 99,199,142,141,240,241,241,137,228,120,166, 87,108,245,170,164, 7,148,124, 89,211,155,109,206,231,153, 49,242,245,146, -250, 68,167, 26, 19,173, 41, 20, 25, 53,223,149, 34, 7,219,210,231,113, 89, 40,106,168, 83,212,139,169, 5, 35,170,231,119,141, - 76,147, 38,205, 43, 38,123, 58,101, 50,193,177, 1,209,185,121,243, 38, 61,121,242,132, 30, 61,122, 36, 17, 32, 21,162,101,238, -224,224,240,226,227,199,143,113, 34, 90,184, 14,215,115,189,204,149, 68, 11,242,113, 31,220, 15,247,141, 38, 90, 54,127,141, 66, -136,138, 8, 4, 4, 2, 2, 1,129,128, 64,224, 23, 35,160,137,139,252,226, 34,252,200,237, 84,231,209,146, 39,135, 93,134,112, -157,217, 50,209,242,229,224,239, 7, 53,106,212, 8, 5,201,154, 52,105, 18, 8,150, 68,186, 14, 29, 58, 20,206,238,196,207,236, - 62,188, 59,115,230, 76, 79, 72,174, 88,177,162,214, 24, 40, 11,203, 52, 9, 82, 37, 75,108,235,229,153,205,183, 97,113,239, 7, -131,170,187,135,134, 45,201, 69, 81,131, 29, 40,114,186, 51, 69,174, 43, 21, 73,183,199,135,143,106, 85,234,115, 70,167,140,119, -103, 47, 92, 35,201, 44, 93, 86,187, 76,156,103,178,149,151,173,110,254,123,247,238,141,122,255,254,189,100,133,138,142,209,130, -235,208,156,227,201, 94, 68, 68, 68, 16,143,148,132,235, 80,246,134,252,184, 14,215, 67, 14,111,146,235, 16,242,113, 31,220, 15, -247,197,253,101, 11, 21, 25, 5, 2, 2, 1,129,128, 64, 64, 32, 32, 16,248,219, 16, 48,124, 30,173,194,133, 11,131,104, 37,204, -150, 45, 27, 98,156, 10,112, 58, 51,121,242,100, 16,173,136, 57,115,230,208,178,101,203, 34,154, 53,107, 22,196,211, 29,236, 96, -235,151, 37, 16,115,118,118,214,233,150,203, 91,160, 96,130, 20,201, 77, 18,122,120,120,165,178, 74,155,182,128,117,218, 52,103, -194, 38,121, 19, 13,181,143,160, 5, 57,137,214,149,143, 24, 95, 55, 95, 80,146, 36, 73,119,176, 56, 73,102, 6, 59, 91,185,174, - 62, 59, 14,206,191, 60,116,232,208,143, 97, 97, 97, 18,209, 98, 43,155, 52,234, 16, 68, 9,191,153, 20, 61, 5, 47,147,217,186, - 86,200,143,235,162,137,150, 5,228,225, 55,228,227, 62,184, 31,203, 18,193,240, 50, 1, 21,217, 4, 2, 2, 1,129,128, 64, 64, - 32,240,151, 34, 16,247,121,180,216,125,135,121,168,202, 85,169, 82,229, 46, 7,193,211,170, 85,171,104,254,252,249,145,179,102, -205,162, 94,189,122,221,228, 81,130,245, 0, 90,245,234,213,229, 18, 34,133,169,105,234, 20, 41,146, 37, 41,215,179,148,219,221, -168,113,238, 20,185,163, 30,125, 88, 85, 63, 50,114, 73, 62,218,217,173,232, 77,158, 54, 66,146, 89,163,114, 37,217, 50,163, 27, - 46, 17,147,159, 41, 28,164,255, 14, 46, 63,142, 29, 3,209, 74,171, 70,180,220,100, 54,178,155, 26,209, 74, 11,121,144, 11,249, -184, 15,203, 17,211, 59,200, 4, 83,100, 19, 8, 8, 4, 4, 2, 2, 1,129,128, 64, 64, 3, 2, 38, 38, 38,246, 28,123, 53,145, - 3,224,195, 71,141, 26, 21,153, 37, 75,150, 39, 94, 94, 94, 75,186,118,237, 26,198,191,195, 96,233,170, 87,175,158,100, 37,226, - 88, 45,117, 98,164,113, 66,179,132, 9, 19,216, 91,166, 74, 49,241,249,192,220,225,143, 71, 20,140,116,119,205,248, 36,187,171, -195,146,245, 61, 10,133, 61, 31,145, 39,204,193,210,148,101,214,149,100, 22, 44, 88, 64,150, 76,213,162, 99, 66, 81, 38, 66, 79, -217,165,135, 9, 75, 21, 60, 15,214, 5,144, 36, 62,134, 9, 75,157, 52, 84, 83, 83, 57,157,144, 31,215,225,122, 92, 3,121,144, - 43, 38, 44,213,251,168,252,140,137,236,132, 76,189,176, 27,148, 65,224,105, 16, 92,122, 51, 11, 60,245, 66,100, 80, 6,129,167, - 65,112,233,205, 28, 95,240,212, 91,145, 63, 60,131,238,169, 29,180, 21,158,227,146, 26,230,202,149,235, 28,147,169, 47, 28, 20, -254,134,173, 67,125, 59,116,232,224,194,214,158,219,217,179,103, 15,100,235,206, 99, 38, 98,117,181, 92,175,177,113, 77, 83, 36, -107, 88, 42,139,237,185,193, 21,115,125,177,183, 78,243, 38,125,122,187,190, 29, 58,117,113, 73,111,157,246,118,110, 79,231,192, -106, 94,118,143,121,234, 7,131,100,234, 3,159, 73,146, 39, 39,115, 67,202,137,252,184, 78,159,108, 67,100,198, 81,150,242,178, -248,242,176,136,114,254, 96, 67,171, 93, 46,240, 20,120, 26, 11, 1,161, 75,198, 66,242,155, 28,129,167,113,241,140,207,210,212, -215, 56,148,183,230, 33,199, 94,217,179,235,112, 52, 91,116,214,241, 28, 82,231,107,213,170,149, 7, 40,240, 98,210, 9,221,221, -221,125, 56, 88,252, 12, 91,180,238,240, 50, 58,135, 13, 32, 27,246,166,166,169, 70,155,153,153,175, 99,249,231, 43, 86,107, 40, -201,108,219,177,115, 66,167,140, 46, 62, 28,243,117, 38,157, 85,154, 59,108, 53, 50, 68,230,143, 54,142,120, 88,126, 20,193,216, -215, 11, 60, 5,158,198, 66, 64,232,146,177,144, 20,196, 64,232,210,159,175, 75,198, 45,225,175,149, 22,103,162,101,205, 22, 45, - 75,142,153,114,229, 17,118, 38,170,101,254,239,191,255, 18, 20, 45, 90,212,148,173, 89,117, 92, 92, 92,210,112,210, 20, 79,165, - 73,177,173,153,152, 89,242, 82, 59,174, 71,143, 95,137, 37,179,126,235, 46, 9,242, 20, 46, 97,154, 42,181, 89, 29,182,152,165, -177, 77,159, 81,174,204, 31,133, 83, 60,128, 63,138,160, 32, 90,194,234, 40,190,238,141,251, 20, 9, 60, 5,158,198, 67, 32,190, -244,113,198,171,241,239,145, 20, 55,215,225, 15,150, 53,190, 52,174, 40,231, 15, 54,180,218,229, 2, 79,129,167,177, 16, 16,186, -100, 44, 36,133, 69, 75,232,210,159,175, 75,198, 45,225, 63, 34, 77, 40,182,113, 27, 90,224, 41,240, 52, 22, 2, 66,151,140,133, -164, 32, 48, 66,151,132, 46, 25, 23,129,248, 41, 77,167,235, 16, 15,137,166,100, 72, 85,181,201,208,117, 92,159,124, 33, 83,115, -187,196,181,189, 4,158, 2, 79,185, 58, 32,158, 77,237, 8,200,197, 80, 53,159,192, 83,224,169, 9,129,127, 89,151, 84, 67, 45, -126,148,127,232,123,190,126,213,249,184,197,104, 25,161,116,226, 75,199, 8, 32,170,136, 16,120, 10, 60,141,133,128,208, 37, 99, - 33, 41, 44, 90, 66,151,132, 46, 25, 23,129,248, 41, 77,185, 4,143,238,197,165,127, 66,221,196, 3,104, 92, 80, 5,158, 2,207, -239, 16,160,117,138, 68, 52,199, 35, 19,205,118, 47, 70,243,178,185,145,175, 66,235, 50, 88,114, 73,187, 36,115,154,151, 11, 45, -200, 92,136,230,100,207,100, 12,153,113,108, 58,161,243,113, 4, 78,203,101, 2, 79,129,167,177, 16,144,116, 41,125,161,246, 53, -108,139,116,122,109, 87,184,195,107, 11,215,226, 65,233,108,157, 34,140,117, 3, 33, 71, 30, 2,226,161,150,135,147,220, 92, 2, - 79,185, 72,201,203,247, 87,224, 73, 51,178,120,210,156, 44,219,104,174,135, 31,167,213, 52,203,203, 91, 70,245,117,214, 61, 90, -230,102, 73,230,236, 44, 43,104,182,135,215,143,202,148,113,189,166, 44,127, 69, 27,253,201,117,239,212,177, 29,149,240,201, 65, - 46,142,214, 84,182, 84,118,234,210,185, 3, 25, 88, 94,209, 70, 6, 2,166, 39,123,188,194, 51,125,193, 14,111,155,142, 63, 75, -237,102,221,146, 82,155,105, 87,137,167,103,218,199,117,108,200, 41,133,113,161, 17,210,100,189, 36,121, 90, 7, 44,139, 19,149, - 60,121,242,141,188,135,169,205,208, 45, 94, 41,161,161,149,251,155, 30,192, 63,160,238,182,209,122, 22, 21,173,119,234, 69,210, -165, 75,169,248,101, 49,152,167, 54, 57,196,171, 35,188, 70,226, 57,222, 14,225, 24, 11, 73,165,163,110,191, 84, 63,105,153,119, - 74,154,149,185,215,151,233,238, 23,119,181,183,121,246,113,170,219, 37,154,227,222,143, 22,102,214, 85, 70, 20, 95,107, 57, 37, -153,115, 60,187,127,154,230,126,113,121, 11,135,231, 33, 83, 88,230, 44,143, 62, 63, 34, 83, 5, 47,139,164, 73,147,238,230,223, - 86, 50,245,227,151,226, 41,179, 76,178,222,117, 63, 32, 75,121,233, 47,169,123,229,242,133,232,115,208, 33, 90,189,180, 23,189, -124, 56,135,202,148,204,249, 67, 68,139,103,120,206,147, 39,113,226,158, 89, 20,138,146, 92, 17, 67,151, 81,251,165,117,143, 47, -109,244, 39,151, 51,150, 69,203,165,104, 84,186,244,142,132, 37,250,154, 54,109, 74,142,142,142, 31,185,236,117,140, 80,126, 33, -194,192, 78,135,222,188,121, 67,235,214,173,139,224, 57,186, 66,185,227,234,199,215, 39, 53, 0,197, 95,242,242, 49,160, 60,218, -178,106, 44, 39, 79,252,122,146, 23,235,246,231,186,251,243, 94, 90,218, 7,155,182,227,106,194,227,117,221, 85,234,226,206,147, -224, 62,230,201,112,111,171,214,207, 58,123,141, 66,110,133,155, 12, 73,235, 85,173,152, 6, 80, 13,169,123, 82,232, 21,244, 11, -122,246,252,249,115,116, 28,154, 58, 15,109, 50,139,242,100,188, 79,253,252,252,194, 63,125,250, 20, 21,112,105, 37, 5, 94, 94, - 74,111,207,207,165, 75,123,103,135, 91, 88,152, 63, 97,121, 69,181, 52,188, 33,229,148,171,102,218, 73,209, 92,118,239,205,201, -178,251,124,191, 12,119, 22, 52, 76, 19,126,164,171,221, 3, 38, 73,251,152,124,101,214, 35, 92,187, 76,184, 12,231,100,217,121, -178,151,195,221,182, 85,115, 71,236,236,232,240,144,101,238,165, 25,238,250,214, 9,213, 91,247,132, 9, 19,246,231,182,137,100, -178, 53, 82,102,229,245,202,148, 41, 71, 53,155,144,169,130, 70,237,234,197,233,243,135,131,180, 99,227, 96, 38, 90,179,169, 92, -169, 31, 35, 90, 57, 19, 38,236, 22, 86,179,230,151,165,217,179,111, 97,178, 85, 85, 11,217, 2, 1,235,204, 75,186,237,226,125, -253, 31,124,222, 85, 47, 31,235,225,225,241,156, 15,116,137,131, 76,141,239,165,220,185,115, 23, 42, 81,162,196,144,156, 57,115, -198,229,189,164, 81,102, 92,159,205, 56,232,186,242,146, 95,165,243, 29,115,228,200, 17,217,163, 71, 15, 90,191,126, 61,109,223, -190,157,178,102,205,250,149, 11, 97,247, 3,101,143, 47,151,230,138, 46,168, 50, 86,203,112, 67, 82,109,103, 69,225, 6, 46,138, - 35,117,157, 21,193,245, 92, 20, 33,141, 93, 20,199,107, 57, 75, 95, 44,186, 54, 77,141, 75,216, 94,191,126, 77, 88,160,185, 79, -159, 62, 95,216,234,128, 7,163,156, 76, 52, 99,201,228,201, 79,207,179,213, 1,235, 15,198, 42, 11, 31, 59,207, 22,136,239,214, - 37,228, 5,178, 37,162,195,251, 24,146,195,247,141,145,137, 25,240,113, 30,123,213,242, 96,125, 67, 62,246,140,175, 83, 63, 94, -146,143, 61, 85, 63,174, 42, 83, 85, 14, 58,240,160,160, 32, 10, 9, 9, 33, 38, 27, 47,148,231,112,252,195,135, 15, 20, 28, 28, - 28,235,184, 26, 38, 58, 31, 22, 96,128, 58,163,238,106,101,151,142,171,215, 41, 58,207,119, 50, 85,176,211,134,105, 92,218, 93, - 89, 36,247,178,101,203,190,137,136,136, 32, 87, 87,215,215,170,229,244, 40,246,223,240, 51,119, 66,130, 90,246,153,189,214,218, -179,122, 54, 67,234,174,146,183, 28,244, 9,122, 5,253, 2,201,122,249,242,165, 33, 68,171,116,181,106,213, 2,195,194,194,162, - 34, 35, 35,163,184, 61,162, 14,250,186, 80,216, 18, 11, 10, 93,155,131,222, 29, 31,202,132,107, 78, 84,217,226,121, 2,181,180, -241,175,122,161, 41,104,157,103, 82,154,151,165, 69,228,108,143, 11, 75, 26,167, 13,244, 95,215,142, 38,213,176, 8, 9,155,233, -126,129,102,101,105, 75,139,157, 98, 77, 8, 44, 7, 79, 73,230,172,204,205, 33,115,104, 45,151, 15,235, 86, 45,165,238, 21,157, - 63,126,147,233,222, 58, 46, 50, 85,238,203,134,197, 36,111,167, 78,157, 74, 76,180,130,248,120, 50, 25,207,252, 47,195, 83, 70, - 89, 12,125,215,197,202,159,207, 78, 97, 95, 50, 83,162,179,185,108, 21,133,101,222, 75, 78,221,179, 70, 63,239,238,113,149,169, - 36, 90,213, 42,229,166,242,165,115,252,176,235,144, 45, 90,229, 64,178,162,106,215,142,212, 66,182, 64,178,250,142, 25, 51,198, -143,159, 49, 63,158,236,250, 8,255, 86,143, 43,148, 83,119,245, 42, 79, 97,153,132,119,139,179,179,243, 7, 3,101,106,125, 47, -149, 41, 83,102,248,195,135, 15,131, 6, 15, 30,188,150, 73,151, 33,239, 37,173, 50,245,180, 85, 92,234,174,175,249,127,165, 76, -123, 46, 76, 31,238, 19, 63,128,104,117,235,214, 13,239,223,218,250, 10,168,239, 60,211,134,100,156, 74,112,170,196,169, 20,167, -124,209,255,231,229, 61, 18,142,151, 86,219,231,133, 92,149,243,249,181,200,192,181,170,215,171,202,196,113,213,223,177,254, 87, - 41,183,114,212,161,250,254, 91, 22,128,161,186, 87,175,112, 61,103,133,111,167, 66,246,161, 55,182,173,164,144,167, 15,232,253, -205,139,116,113,222, 40,234,148,215, 58,180,161,139, 98,172, 62,128,212,206, 75, 68,235,196,137, 19,116,237,218, 53,137,112,220, -185,115,135,242,231,207,255,137, 95, 24, 7, 56,175,179, 33,242,184, 49,253, 15, 28, 56, 64,220,121,127, 96, 34, 49, 65,249,112, -129, 44,225, 30, 56,206,121,166,240,241, 68,144,203,203, 8,189,198,253, 85, 73,142,234,253,184,147,125,143,243,176, 56, 69, 31, - 79,132,235,121,125,199,144,115,231,206, 17, 19, 34,229,241,132,124,143, 9, 29, 59,118, 12, 97,203,135,234,113,157,197,103, 43, -206, 83,126,185,208,182,109,219,136, 23,168,142, 69,180,112,124,203,150, 45,186,136,150, 54,217, 9,185,238,227, 27, 55,110, 28, -252,232,209, 35,226,217,250, 99,202, 8, 76,216,132, 27,252,228,201, 19,226,117, 27,149,199,117,150, 17,215,159, 60,121,146,106, -214,172, 25,164,138, 41,142,159, 58,117, 74,121,124,188,134, 23,217,119,114,121,137,166, 54,168, 39,146,133,133,197, 72, 94,164, -251, 85, 64, 64,128,164, 3, 74,162,165,180,100,165,203, 90,181,219,156,117,167,206, 28,189,250, 54, 32,123,153,118,227,205,179, - 87, 51, 55, 64, 23,156,161, 63,197,138, 21,251,244,244,233, 83,137,196, 95,190,124, 89,210,179,187,119,239,106, 35, 90,234,226, - 83,115,125,159,127,249,242, 37, 10,137,203, 25,201, 31, 4,145, 55, 39,216, 18, 45, 74, 18,147, 2,183, 84,161, 87, 71, 71, 71, -153,165, 74,249,140, 5,164, 54,160,140, 70,205, 74, 51,189, 50, 32, 38,235,250, 96,199,155, 71,199,148, 15,167, 71, 7,105,101, -115,235,240, 35,221,236,239,113, 92,213, 6,154,235,233, 96,232, 13, 37,153,179, 61, 87, 94, 30,224,120,107,250,208,206,225,143, - 31, 63,166,158, 77,203, 71,236,237,100,127,159,173, 92,235,226, 34, 83,165, 12, 13,106,212,168, 17, 2, 93,228,133,233, 63, 38, - 74,148,232, 63, 67,203, 23, 95,243,131,100,149,118, 79,246,252,242,138,158, 81, 85,178,166,124,107, 0,217,210, 85,229,172,252, - 92,189, 89,178,100, 9,241, 59, 10, 31, 45,114,201, 86, 44,153, 32, 90,159, 62, 28,160,234,149,243,233,116, 25,214,173, 91,151, -216,178, 67,157, 58,117,210,231, 90, 76, 0, 75,150, 22,178, 37,145,172,113,227,198,249,133,135,135,251, 45, 94,188,216,175,106, -213,170,126,124,172,231, 15,182,237,212,177, 99,199, 18,203, 36,150, 73, 44, 19,101,156,166, 77,166,156,247,146,210,146,197,107, -253,118,219,188,121,243,153, 91,183,110, 5, 84,174, 92,121, 60,175,241,171,241,189, 36, 71,230, 15,214,241,167, 92,206,239, 60, -183,108,217,178, 45,231,103,242, 9, 91,163,190,122,122,122,126,230, 37,246, 30,177, 37,106, 9,135, 76, 24,212, 31,171, 20,176, - 64,225,194,133, 35,143, 28, 57, 66,252,204,163, 45,148,214, 30,157,117,208,197, 69, 64,172,250,246,237, 11, 15, 24, 97, 15, 98, -132,255,163, 9, 82,204,255,202, 99, 42,231, 36,242,165,252,173, 73, 6,206,105,184, 78,186, 70,211, 61, 84,229,169, 84, 72,221, -146, 21,123,186, 7, 84,142, 83, 49, 78, 71,212, 81,168,227,162, 40,196, 36,235,211,167,128,151,116,117, 84, 87, 58, 84, 34, 3, -157, 40,158,158,110,119,175, 65, 47, 87, 76,161,246, 57, 45, 67,107,187, 40, 74, 24,160, 1, 82, 39, 11,114,130,116,225,194, 5, -226,175, 5,130, 53,103,205,154, 53,145,220,153,127,226,198, 29,195,242,100, 5,209,129, 80, 65, 30,119,140, 52,114,228,200,207, -209,150, 42, 27, 16, 37, 28, 15, 12, 12, 36,254,202,249,204,191, 47,179, 76, 59, 38, 27, 79, 31, 60,120, 64, 54, 54, 54, 49, 36, - 71,181,236, 32, 82,252, 64, 41,137,147, 61,255,190,186,117,235,214, 48,200,122,246,236, 25, 49, 81, 2, 89,177,225,114, 94,100, -188,164,227, 47, 94,188, 80, 30,215, 11, 3,136, 22,187,163,136,151, 52,138, 85, 6,229,241, 93,187,118,197, 34, 96,122, 5,114, - 89,184,110,126,140,221, 87, 16,181,171, 87,175, 42, 73,162, 13, 19,155, 11,236, 58,147,142,223,188,121, 83, 54, 25,204,152, 49, -163, 68, 70,241,101, 56,103,206,156, 47, 74, 76,149,199,191,126,253, 10, 31,252, 23,198, 30, 47, 72, 27, 93,101,100,188, 95, 32, - 63,218,129,201,116, 8,136, 15, 44,122,216, 32, 15,215, 42, 45, 89, 45,122,207, 92,235,156,175,225,168, 61,103,159, 63, 91,176, -249,188,159, 85,214,106,229,101,212, 63, 5,244,133, 9,220,231, 99,199,142, 69,178, 37,138,208,145, 67,175,148, 58,118,229,202, - 21, 89, 68, 11,241, 87,103,206,156, 9,131, 37,139,221,219, 18,201,226, 20,161, 78,180, 64,186,222,236,106, 69, 59,230,117,249, -202,150, 25,196,108,253,242, 77, 26, 21, 56,215,163, 26,130,213,151, 52,182,122, 19,124, 97, 21,209,190, 46,116,127,184, 11, 13, - 46,159, 58, 56, 74, 10,140,207, 82,155,124,139, 37,150, 91, 56, 73,230, 60,207, 42,144, 57,182,142,211,219,139,126,231, 8, 47, -202, 89, 83,198, 81,167,210,246, 31, 37,153,179, 61,107, 26, 34, 83,245,222,220, 78,119,142, 31, 63, 78, 71,143, 30,165,161, 67, -135, 18, 19, 99,184, 96,127,104,147, 44,112,179,221,157,104, 62,143,184, 92,152,217,150, 14,203,175,239, 15,221,216,128,139, 65, -178,202,184, 39,123,246,230,226,102,162,119,119,233,213, 4, 47, 42,239,145,228, 71,201, 22, 72, 86, 0, 62,172, 94,189,122, 69, -147, 38, 77, 34,126, 30,227, 68,182, 36,162, 21,184, 95, 39,209,226, 15, 80,154, 60,121,178, 68,100, 10, 20, 40,160,143,104, 1, -157,239,200,150,135, 66, 81,141,143,247, 27, 63,126,124, 12,201,154, 57,115,166, 31, 63,159,126, 28,203,179,211, 0, 72,213,179, - 78, 99,153, 49, 36,139,101, 18,158,121, 39, 39,167,167,218,100,202,121, 47, 41, 45, 89, 3, 7, 14, 92,203,203,205,141,186,120, -241,226,179, 29, 59,118,248, 49,241,210,248, 94,146, 35,243, 7,234, 40, 93,202,175,205,196,156, 96,217, 65,226,175, 63, 2,113, - 69,194,115,158,132,147,100, 80,144,179,241,135,121,202, 66,133, 10,249, 53,106,212, 40, 20,100, 29,186,132,143, 83, 96, 57,100, -200, 16, 90,180,104, 17, 62,170, 63,242,123,251, 76,237,218,181,147,203,145, 25,157,199, 11, 22, 69, 24, 13, 86,174, 92, 9,235, -245, 14,185,215,234,226, 34,106,228, 70, 34, 88,128,228, 27, 44,255, 39, 82,170,191,181,253,175,141,164,105,146,163,126, 76,195, -253, 80, 61,253, 11, 72, 71, 87, 78,227,195,211,192, 89,113,240,218,166,197,116,125, 92, 79,218,231,157,152,142,230, 72, 66,103, -115, 37,161,203,121,146,210,147, 54,197,233, 76,199, 74,212,212, 53,193, 41,185, 64, 70, 23, 82,178,102,169,166, 27, 55,110, 72, -132, 5,157,100,151, 46, 93, 62,179, 75,240, 13,231,173,174, 79,174,146, 80, 29, 60,120,144, 96, 41, 97, 82, 20,197,214,170, 87, -204,210, 3,129, 62, 44, 51,248, 42,103, 2, 19,197, 95, 28,136,139,122,135,251,240,255, 26,137, 22,136, 20,136, 31, 95,255, 33, -115,230,204,111, 81,158,168,168, 40, 73, 9,209,233, 48,233, 8,100,182,255, 26,199,177, 97,143,123,168, 88,145,116, 22,153,243, - 61, 5,233, 64,103,195,228, 32,166, 12, 56,254,254,253,123, 66, 61,180,145, 64,117,193,112, 21,114,140,195,107,148, 13, 68,243, -244,233,211,180,115,231, 78,148, 61,144,191, 74, 94,163,222, 32, 57, 32, 29,135, 14, 29,146, 93, 70, 54,229, 75, 68,235,252,249, -243,146,101, 8,245,227,178,250,243,250,147, 31,112, 28,150, 61,148, 21,247,115,112,112,240, 87,119,219,170,150, 19, 86, 52,148, - 1,109,131, 47, 77,101,155,131,252,241,181, 18,209,178,242,174, 90,107,246,186,147,167,143, 92,126,243,218, 38, 71,205,193,131, -167,109,222,131,255,173,189,171,182,215,211,254,213,217, 37,250,102,198,140, 25,124,139,175,244,246,237, 91,137, 80,170,235, 22, -126, 71, 63,144, 58,197,113,199,127,152,235, 27,133,164, 36, 89, 32, 92,154,136,214,199,149,238,244,104, 91,135, 40,214, 63,109, -139,159,235, 83,221, 31, 58, 79,243,189,210,241, 72,192, 89,143,134, 59, 95, 95,211, 57,231, 87,122,117,145,104,126,118, 98,139, - 19, 13,173,104, 17,126,166,183,195,109, 38, 76,243,105,177,167, 78, 34,172, 90, 8, 73,230, 28,143, 25,247,135, 57, 95, 31,209, -174,202, 87,184,247, 55,108,216, 64,220,185, 80,203, 74, 57,195,143,247,200,112,135,173, 90,115, 13,145,169, 34,223,135,191,154, -131, 85,101,178, 62,133,240,249, 50,113, 5, 2,110, 76,154,239, 89, 66,178,222,205,241, 56,202,113,100, 75,153, 92,230,163,185, -185,208,225,252, 17,155,146,100,189,189,244,141,100,209,210,194, 68, 11,115,211,203,105,249,169,124, 22,147,184,146,173,172,252, -142,144, 72,150,191,191,191,212, 62,251,246,237,163,133, 11, 23,226, 99,202, 96,178,245,141,104,237,163,106, 85, 52, 91,180, 84, - 73, 22, 58,223, 74,149, 42, 17,119,206, 6,147,173,145,238,238, 55,218,214,175,127,159,159, 85, 63,254, 40,150, 44, 89, 32, 89, -249,242,229, 59,205,141, 21,215,128,233, 25, 19, 38, 76, 32,124, 96,177, 76,201,146, 5,146,197, 50, 17, 23,212, 65,155, 18,200, -121, 47,113, 76, 86,173, 77,155, 54,157,230,119,202,235,188,121,243, 14,158, 61,123,246, 30,252,207, 68, 75,227,123, 73,142,204, -184, 42, 37, 8, 21,167,228,156,204, 56, 89,114, 74,195,201,156,137,140, 5,183,143, 57,203, 53,139, 78, 24, 4,163, 43,100, 64, - 42, 2, 91,175, 50,112,157, 2, 55,110,220, 40,245, 99,136,167, 98, 34, 73,236,185,193,136, 65,242,245,245,149,244, 9, 31,197, -115,231,206, 37,182,226,189, 99,226, 42,231, 93, 98,194,253,207,205,213,171, 87, 19, 99, 71,246,246,246, 1,124, 59,167,232,122, - 15,228,143,127,180,117, 53,109, 56,232,226, 34,170,196, 10,239,115, 25, 4, 72, 39, 1, 83,202,208, 70,186, 52,157, 87,189,175, -202,255,168,142,210,154,165,189,137,117,177,200,250,206,138,119,111, 47,159,161, 19,165, 28,232, 68,206, 36,116, 62,119, 82,186, -150, 55, 41,221, 45,144,140,158,149,180,164,151,189,170, 19,199,110,225,133, 41,119,147, 26, 22,238, 28, 77, 9, 36, 7, 47, 15, -124,249,114,224,108,164, 62,161, 32, 70,144, 7,130,194, 22, 13,186,127,255, 62,177, 85,130,250,245,235,247, 21,199, 97,213, 0, - 75,199,113, 60,128,108,178, 14, 67,135,204, 10,160,145,104,129, 48, 33,174,135,191, 98,194, 96,101,131, 85, 7,229, 84, 90,223, - 6, 13, 26,244, 85,121, 28,101,133, 76, 88,145,228,186,229, 96, 81, 67,253, 64, 82, 84,201,158,242, 56, 44, 62,170, 4, 76, 87, -253, 81, 86, 88,199, 64,220, 80,103, 96, 6, 82,212,191,127,255,175,159, 63,127,150, 30,146, 75,151, 46,197,148, 93,110, 25,225, -210, 3,118,103,207,158,149, 72, 21, 98,156,238,221,187,135, 23,153,132, 41,238,133, 4,156,240,178, 87,113,179,126, 87, 92,180, - 15,242,160,125, 6, 12, 24, 32,237, 65,250, 80,102,174,167, 68,180,156,156,138,153, 20,169,217,103,214,185,187,161, 31, 75,213, -239,191,176,106,203,225, 75,241,127,222,202,157,217,244,239,171,117, 78, 40,232, 7,218, 50, 52, 52, 84, 34,211,218,116, 74,174, -235, 48, 89,178,100, 1, 32,128, 76, 34, 37, 75, 22, 18,199,104, 69,150,205, 97, 70,158,246, 73, 98,165,202,121, 44,232,225,230, -214, 24, 61,139, 23,201, 47,221,184,135, 75, 64, 11, 50,249, 48,233, 57,187,170,169,245,171,151,251, 39,176, 47,126,164, 68,178, -104,126, 54, 58, 54,192,155,250,150,181,252,192,228,227, 60, 91,160, 56,166, 65,255,200, 47, 73,230,124,183, 34,144, 57,179,161, -131,255,145,253,187, 37,130, 14, 23, 55, 92,243,179, 39,143,162,118, 37,108,130,153,200,156,227,251, 20,151, 35, 83, 21, 20,254, -112,218,207, 47,222, 40, 85,153,120,153,179,238,156,140, 11,120, 18,201,154, 46,145,172,173, 87, 7, 56, 94, 24, 81,201,252,237, -221,161, 25,207,113,157,215,210, 92,111, 99,144,173,226,108,129,123,192,101, 43, 18,151,242,225, 26,137,100,121, 36,123,250, 46, - 22,201,202, 69,180,204,135,104, 77,121,122, 57,191, 2,149,247, 76, 97, 40,217, 2,201,146, 62,174, 84, 73, 22,158,125,188,163, -208, 97,242, 51,103, 16,217, 2,209, 10, 13,220, 75,213, 52,184, 14,171, 87,175, 46, 89,178, 64,100, 22, 44, 88, 64, 76, 54,164, -119, 30,187,133,228, 16, 45,192,144, 0,150, 44,144,172,200,218,181,105,111,171, 86,129, 45,107,215,190,207,199,135,112,234,192, -100, 27, 35, 80,227, 66,178, 96,197,153, 57,113,226, 68,169,108, 35, 70,140, 64,121, 22,114, 26,197, 50,241,110,215, 74,178, 80, - 40, 57,239, 37, 38, 23, 38, 13, 26, 52,152,197,239,150,143, 28,126,177,176, 93,187,118, 75,241, 63,187,194,166,113,136,194,119, -239, 37, 57, 50,227,162, 75,108,185, 44,197, 33, 27, 89,163, 73, 86, 58,222,103,224,228,200,237,144,145, 61, 11,206,108,153,202, -200,239,210, 12, 44, 27,157,125, 58, 46, 95,122, 38, 75, 58,245,150, 45,136, 23,241,108, 43, 55, 16,104,196, 78,242,135, 43,158, -201, 88, 68, 11,122, 6, 43, 97,250,244,233, 79,200, 40,127,155,158, 61,123,210,225,195,135, 9, 46, 72,206,175,156,106,198,188, -116,233,210,146, 87, 40,154, 4,231,214, 36, 43, 46, 22, 45, 16, 37,117,210,165, 78,158,244,157,231,178, 72,164, 76, 83, 62, 25, -199,100,192,194, 89,116,249, 69, 65,180, 94, 30,220, 66,126,165,236,232, 34, 91,177,110,230, 75, 70, 15,152,100, 61, 47,108, 66, -239, 74,154, 83, 64,171,130,212,208,213,112,162, 5, 75,144,174,196, 62,113, 89, 68, 11,100, 67, 73,168, 64, 42, 64,122, 64, 86, -134, 13, 27, 38,145, 2, 16, 44,188,148,112, 47, 88, 59,166, 79,159, 30, 6, 43, 13, 91, 83, 52, 18, 45,182,134,249,195,250,194, -238,198, 48,228,199,245,183,111,223,150,226,200,144,248,129,254, 10,235, 27,228,193, 5,137, 4,194,197, 15,131,172,248, 39, 16, - 42, 88,212,240,245,160, 78,180,160,132,176, 34,105,179,182,169,183, 38, 8, 14,242,131, 72,226,229, 7,203,205,245,235,215,165, -186,227, 55,202, 13,146, 1,146,132,114,162,110,114, 52,194,205,205, 77, 34, 90,112,161, 66, 30, 18,238,193,238, 9, 9, 83,213, -227, 32, 92, 42,113,107,223,137, 71, 25,209, 30,248,194,225, 23, 2,220,195, 82, 66,185,208, 97,224,130, 31, 33, 90,168,151, 62, - 93,194,121, 60, 72,250,234,206,129,218, 1, 32,128,108, 21,140, 98,119, 76, 4,227, 23,118,255,206,157,176,173,214,214,116,111, -193,130, 40,198,247, 19,227, 26,202,199, 67, 57, 14, 44,148,243,132,253, 22,162, 53, 43,171, 5, 19,140,145, 1,227, 51, 93,153, - 82,223,254,115,148,255, 21,182,148, 20,146, 72, 22,173, 40, 78,225,107,171, 83,189, 60,102, 17, 55,125,157,175,179,149,103, 28, -143, 22, 76,163,175,238, 4,153,115, 60,135,191, 30,151,233, 74,207,218,185, 63, 99,100, 48,172,163,176,148,160,253,252, 88,207, -202,120, 91, 69, 94, 27,228,116,131,243,141,145, 35, 83,229,158,174,252,124,132,170,203,132,238,242, 23, 46,134,127,115, 72,143, -252,141,166,185, 38,147,200, 30,147,172,107,131, 28,253,134, 85,182, 14,189,186,176, 37,117, 40,156, 34,244,250,144,140,231,153, -108,173,163, 57, 89, 11,252,128,101,171, 24, 91,174, 63,206,159, 63,159,184,125,241, 17,233, 35,191,116,255,207, 89, 42, 83,162, - 29,199,103, 52,143,138,177,100, 45,200,193,237, 84,132,104,117, 57,162, 13, 53,137,182, 53,165, 11, 83,170,145,143, 75,146, 88, -131, 66,116,221,139, 9,235, 53, 88, 33, 52,145, 44,188,151,240, 46, 66,135,201,157,190,234, 96, 31,173, 34, 39,140, 31, 71,165, -138,231,160,208,247,123,169,184, 79, 22,226,223,239,149,153, 17, 91,163, 36, 89,112,245,130,116,225, 61,192, 29, 37, 97, 84,153, - 30, 76,202,242,179,191,156, 59,215, 51,140,229,206, 14,141, 26,221, 7,201, 2,217, 26,145, 57,243,205,104, 55,162,161, 83, 63, -212, 71,184, 66,169, 82,165,194, 48, 0, 9,238, 82, 88,178,163, 73,214, 60, 46,143,108,121,114,222, 75,134, 18, 45, 57, 50,227, -162, 71,220,199,185,117,237,218,181, 37,215,213,139, 95,191,246,156, 50,241,199,160, 55,127,176,102,155, 50,101,138,119,195,134, - 13,179, 50,169,193, 51,148,169, 73,147, 38,118,252,254, 46,197,255,103,212,117, 47,118,231,241,224, 76, 15,238,234,190,197,203, -226, 3, 8, 31, 62,170, 9,253, 41,140, 10,104,115, 14,243,120,197,242, 92,101,148,127, 2,158, 27,232, 32,231,221,198, 9,243, -239, 73,113,172,172,147, 23,113, 31,244,169,209,134, 14, 43,117,121,122, 98,180,116,197, 97,105, 61,135,123,196,133,104, 41,175, -249,118,121,108, 18,166, 38, 79, 89, 13,253,238, 67,109, 0, 54,114, 81, 28, 60, 61,166, 27, 61,234, 86,149,110,231, 79, 70,143, - 11,154,208,171, 34, 38, 20, 88, 52, 57,125,174,225, 68,167,203,218, 82,243, 56,184, 14,241,162,208,148,208,184, 21, 43, 86, 12, -149,235, 58, 4,121, 80, 37, 84,171, 86,173,138,226,151,250, 43, 86,250, 64, 28,135,197, 3,110, 46,142,137,138,226, 47, 29,127, - 38, 5,239, 96,165, 98, 51,168, 70,162, 5,194, 4,229,226,235, 63,240,255,175,153,240, 69,193,114, 3,114, 4,203, 14,228, 66, - 62,127, 57,194,189, 36,185,196,208,129, 48,105,144, 69, 98,248, 90,238,163,159, 18, 94,138,170, 86, 53, 28, 7, 33, 0, 81,212, -102,109, 83,111, 35,184,236, 80, 22,212, 25,215, 66, 46,202,170, 94, 70,148, 15, 56,200, 45, 35,187, 76, 37,162,133, 58,131,252, - 49, 49,146, 48,101,204, 36,215,161,242,248,218,181,107,165,227,186, 92,135, 24,172, 0,255, 63,204,207,245,235,215,151,220,135, - 76,118, 37, 43, 9,147, 78,169,131,177,246,170, 90, 61,174,174, 67,232, 9,244, 5,122,163, 77,167,112, 28, 15,139,190,151, 4, -127,205, 29,225,193, 25, 81,156, 34,249,203, 53,156, 73, 70, 40, 91, 30, 63,129,100,109, 74,149,138, 30, 44, 90, 20,197, 29,217, - 39, 38,238,161,220,246,159,217,138,240,133, 95, 30, 71,244,201, 53,246,121, 38, 58, 89,152, 76, 28,219,208,210,230,233,205,213, - 61,163,232,210, 60, 38, 89,222, 68,203,217,208,132, 14,124,103, 43, 90,214,163, 56,245, 46,155,230, 29,187, 23, 79,210,188,236, -217,245,149,129,221,134, 30,112,191, 45,111, 97,255,108,235,186,165, 81, 32,233,123,246,236,145,172,196,176,148,128, 92,143, 27, -210,131,186,149,177,121,207, 86,175, 19, 52,211, 83,175, 76,229, 61,217, 82, 56,143,221,187,225,248, 80,217,189,123,119,140, 76, -124,200,176,229, 57,130, 59,207, 85,250,202,167, 60,255, 45, 38,203,171, 24, 91,214,182,222, 28,156,209,111, 68, 21,171,208,208, - 27,219,137, 46,205,167,171,131, 50, 82,163, 92, 41,190, 92,236,239,120, 65, 10,220,159,233, 85, 48, 14,100,203, 7, 36, 11,101, -197,243,142, 47,121,214, 49,144,193,162,114,203,168,204,151,223, 70,225, 84,218, 45,209,203, 75, 3,157,191,185,117, 65,134, 87, -149,229, 54,170, 65,180,181, 49,249,175,108, 76, 21,179,166, 10, 44,224, 16,123,196,180,158,251,228,100,114,250, 6,229, 2, 9, - 86, 90,178,148, 36, 11,207, 21,191, 19,223,178,140,172,250,202, 59,105,226, 4,191, 38, 13,202,209,211,251,219,153,104,237,161, -235,126,211,169, 70,229, 28, 84,188, 88, 81,116,172,132,224,114, 16, 25, 30,109, 71,245,234,213,163,214,173, 91, 75,241, 89, 60, -162, 87,223,179, 84,150, 7, 9,249,241,115,228,199,175, 11, 63, 14,107,144, 18, 44, 89, 32, 89, 58, 70, 35,234, 42,114,125,184, -181, 48, 42, 27, 27, 66, 37, 84, 72,214, 28,190, 80, 54,201,194, 77,228,188,151,216, 69, 88,221, 16,215,161, 28,153,250,218, 68, -203,249, 4,252,174, 44,204,248, 55,229,119, 60, 43, 16, 21,224,247, 83, 65,142,129,202,199,109,148,159, 7, 39, 20,229,143,216, -162,124, 62, 39,187, 4,203,240,199, 65, 62, 57,120,240,187, 59, 31,187, 71,223,191,123,247,142, 96,201,199,199, 63,222,211, 32, - 74, 32, 87,240,138,128, 20,113,120,202, 91, 14,171, 80, 31,109,169,173, 42,109,248, 67, 95,122,103, 96, 95,167, 78, 29,242,241, -241, 33,111,111,239, 80, 38,174, 95,152, 8, 74,109,135, 65, 85,108, 49,198,164,166,178, 55,174,183,214,145,133,186,206,225, 6, - 50,175,213, 54,178,208,144, 81,135,202,229,119,148,123,121,245, 67, 48,124,219,156, 22,159, 94, 78,233, 69,254,205,243,211,155, -146, 22, 20, 84,202,140,190, 86,207, 64,129,213, 28,232,191, 76, 9, 62,198, 37, 24, 30,150, 3,213, 4,210,194,238,186,112, 86, - 18,131,130,225, 65,140,240,224,129,240,240, 48,210,143,172,144,248,146,179, 97, 51,167,116, 28,102,101,254, 26,251,200,249, 46, -243,113, 59, 38, 91, 79,113, 92, 27,209, 2, 25,129, 59, 46,154,148, 56, 49, 49,187,206,174,184, 16,229,212, 11,209,199,109,112, - 31, 54,145,178,113,236,163,164,144,184,159, 28, 68,249,122,137, 80, 65,129,163, 77,220,210,101, 56, 14,247, 23, 94,240,114,137, - 86,244,253, 80, 22,191,238,221,187, 75,101,196, 40, 78,213, 50,246,238,221,251, 35, 20, 27,228, 82,110, 25, 17,131, 6,140,224, -122,228, 47,215, 24, 76,213,142,135,224,190, 40,186,174,122,243, 3,250, 2, 95, 55,240,247,195,148,140,224, 72,116, 18,152,208, - 46, 58,158, 68,225, 81,180,197, 32, 76,235,240, 35,193,240,208, 27,232, 15,244, 72, 93,183,240, 27,207,154,190,246, 97,194,232, -203,113,120, 95, 25,171, 40,126, 17,124,102, 55,103, 40, 91,115, 66, 97,201, 2,201,130,101,235, 93, 64, 64, 24, 19,205, 80,110, -247, 47,172, 23, 65,252,178,240,213, 39,215,216,231, 57, 96, 61, 15, 2,214, 71, 86, 54,255,240,104,109, 87,182,144,148,103,146, - 85,236, 91, 7,206, 36,139, 14,245,161, 67,147,155, 80,209, 76, 38,225,223,102,118,247, 44,171,175, 12, 74,153,189, 42,216, 7, -237,218,186, 94, 50,253, 35, 38, 17,174, 99, 88, 52, 97, 21,222,176,114, 17,249,184,165,252, 38,115,142,167,220,233, 88, 20, 76, -180, 94,193,138, 9,153, 72, 74,153,176,190, 64, 31,152,200,196, 88, 81,244,150,115, 50, 7,190,207,206,178,254,150,111,198,243, - 35, 42, 71,147,172,171,203,136,230,177,103,133,227,159, 46,140, 41,204,238,184,228, 97,103,251, 56, 94,148, 98,182,102,187, 25, - 50,127, 79, 17,144, 44,144, 76, 4,152, 43, 73,230,138, 21, 43, 16,184, 15,178, 85, 92, 95,249,212,207,199,144,173,161,108,140, - 88,197,131,159,214, 87,103,146,213,136, 94,175,108, 68,149,188, 83,191, 55,144,100, 41,197, 75,100, 11,229, 66,135,166, 36, 89, -112,201,203, 37, 89, 16, 84,185, 98, 41,122,254,112,141,148,253,180, 0, 0,255,244, 73, 68, 65, 84, 55,109, 88, 61,138,138, 22, -114,167,165, 11, 58,147,223,137, 97, 84,163,106,121,201, 50, 6, 75, 56,220,253, 32, 89,134,212, 27,150, 44,144, 44,126,126,252, - 42, 84,168,224,199, 31,185,126,252,204,248, 49,134, 59, 97,201,210, 51,245,131,198, 91,193,146, 5,146,133,208, 3,150, 41, 13, - 38,194, 7, 31,166,246,225, 11, 12, 34, 89,184,129,156,247, 18, 7,195, 15,194,180, 14,114,131,225,245,200,188,107, 8,134, 26, -242,162,142,110,153, 50,101,170,193,100,165, 42, 91,178,170,240,179, 83,131,223,173, 85,153, 96,149, 97,194, 84,130,117,162, 34, -231,145, 99,117,138, 17,207,239,205,188,220, 15, 93,103,121, 8,105,137,148, 88, 44,111,252,145, 17, 49,122,244,232,199,236,146, -188,194,150,254, 28, 6,148, 61, 41,191, 19,143,115,127, 36,145, 53,188, 55,208, 78,248,208, 71,251,161, 47, 66,204, 51, 54,142, -167,139, 66, 83, 24, 32,251, 79,207, 26,119,139, 22,106,214,200, 85,225,219,214, 59,117,232,201,198, 5,232, 85,235, 34,228, 95, -207,147,142, 23, 75, 35,145,172,166,113,156,222, 1,100, 70,153, 96, 10,103, 18,240,145, 95,114, 6, 79,239, 0,242, 0, 66,192, -129,125,239,248, 37, 19, 51,189, 3,130,183, 65,130,248, 11,236, 29,147,172, 41, 92, 13,105, 52,134, 62,162, 5,121,106,164, 36, - 9, 91, 45,102,243,200,139,119,176,140, 64,110,116,107, 39,196,253,216,140,174,126, 92,167, 50,176,252,167,176, 18, 33,169,186, - 47,113, 28, 68, 11, 73,149,128,201,212, 44,148,101,188,134,178,196,169,140,236,191,151,200, 38,143, 72,137,133, 41,142,131, 84, - 70, 31,151, 53,189, 3,119,162,109,248, 97,126,129,196, 15,224, 72,140, 52,100, 75, 24,241,131,173, 28,146, 14,139, 86, 65,183, - 66,205,250, 91,123, 85,235,241, 35,211, 59, 64,127,160, 71,208, 39, 85,253,194,255,140,163,156,206, 34, 53,151,247, 25,172, 90, -220,214,225, 32, 89,236,222, 10,101, 43, 99, 40, 44, 89,111, 95,191, 14,227,227,159,152,208,126, 97, 11,218, 23,126,177,254,150, -233, 29,104,158,187, 27,220,102,247, 56,104,189, 75,209,148,159,175,140, 96,151,148, 68,178, 90,114,176, 98,111, 58, 59,183, 53, - 21,114, 54,137, 60,209,147, 3,226,231,120,108,146, 51, 37,131,180, 70,226,236, 44, 59,239, 12,117,190,222,212,199,238,243,130, - 89, 83,164, 56, 60, 88, 88,241, 81,176,115,243, 90, 42,228,154,242,155, 76,190,183, 28,153, 42,186, 91,152,219, 62, 4,174, 30, -196, 38, 42,101,242,192, 21,116,148,161,156, 79,214,168,101, 41,142,108,182, 87,245,136, 89, 30,199, 6,148, 73, 21,252,118,123, -111,162, 43, 75,190,145,172,197, 60, 61,206, 90,254,240,220,214,140, 78, 79,169, 77,133,157,147,134, 75, 1,242,115,189,100, 7, -219,115,135, 18, 4,221, 65,199,128,193, 42,112,109,194,234,134, 15, 35, 4,156,243,121,196,156,200, 30,197,169,172,191, 68,182, - 50, 39,125,121,137, 73, 32,109,105, 64, 1, 76,178, 42,123,167,126, 23, 71,146, 21, 67,182,216,165,244, 6,229, 2, 41, 2, 41, -198, 84, 15,124, 82,175, 37, 75, 41,160,114, 5,142, 21,251,122,137, 74, 20,245,230, 96,103,111, 42, 86, 56, 51, 61,191, 55,141, -242,229,206, 40,197, 98,225,125, 7,203,150,204,119, 80, 76, 54,184, 11, 97,201, 98, 75, 51, 62,196,118,243,111, 63,118,241, 43, -131,222,117, 77,253,160,245, 86,112, 23,162,115,102,153, 40,207, 11,196,251, 32,108, 32, 58,222,199,208, 34, 42,228,188,151,216, -162, 85,176,100,201,146,253,121,223, 67,206,244, 14,122,100,202,114,229,202,168, 8,250, 49,124, 60,192, 37,151, 39, 58,241,212, -101,210, 49,217, 35, 14,213,238,131,235,154,177,126, 47,224,190,238, 16,127, 0, 31,228,169, 87,224,138,109,204, 73,206,186,169, -234,197,198, 53,109, 56,237,229,126,233, 46, 91,178, 62,149, 43, 87, 78, 34,200,176, 74,130,104,161, 15,128,197, 43, 83,218,180, - 17, 83, 20,138, 55,108,146,108, 46,163,238,127,127, 22, 76, 88,202, 46,194, 35, 60,111, 86, 48,130,223, 91,100, 74,240, 67, 19, -150, 2,108,124, 57,242,188, 44, 31,217,101, 19,231, 9, 75,217,170,114, 30,110, 55,117,247,149,202,113,248,171, 99, 54,206,123, - 18,100,137, 21, 64,227,132,165,184, 14,231,177, 87,189,142, 21,175, 34, 31,123,174,126, 60,218,125,247, 84,253, 56, 95,171,113, -130, 56, 16, 42,188,200, 97,129, 99,226, 18,227,190, 84, 18, 48,124, 73,107,139, 31,211, 38, 83, 89, 78,109,101,209, 81, 70, 92, -250, 93, 57,101, 96,250, 67, 19,150,178,197,238, 53,130, 88,121,116, 74,236, 9, 75,163, 45, 91, 63, 58, 97, 41,244, 9,122, 5, -253,130,158, 33,113, 61, 53,117, 24,154,218,168,124,158, 60,121,222, 98,180, 33,127,129, 69,176,169,254, 11,191,208, 63,113, 28, - 72, 24,183,217,103, 38, 97, 95,249, 75,237, 11,235, 8,130,224, 53, 13,243,254,233, 19, 3, 74,238,179,185,158,133,217, 98,179, -227,230, 16,167, 27,205,242,155,126,241,155, 88, 81, 34, 89,167,103,183,164,130,206,201,190, 17,162,185, 89,118,209, 34,247,162, -136,105,210,240,134,138, 85, 78, 73, 38, 2,236,249,154,235,131,157,110,212,200,109,253,117,213,146,185, 82, 44,221,214,245, 43, -169,128, 75, 52,201,194, 12,241, 8,176,151, 33, 83,237,158, 18,217,130,101, 19, 50, 49, 34, 73, 38,201,138, 41,167, 42,209,234, - 87, 58, 85, 96,203,252,201,191, 52,200,153,236,107,181,172, 73,195,202,186, 37,141, 40,228,148, 56, 50,135,109,194, 40, 79,107, - 5,149,245, 72,241, 37,122, 36,162, 38,203,155,198, 54, 98,203, 27,166,155, 80,234,202,119,123, 46, 63,218, 92, 27,209,210,217, -238, 18,217,114, 55,121,121, 96, 88, 73,170,146, 61,245, 91,153, 36, 75,159, 46,229,228,103,245, 13,220,241, 24,133,200,101,147, - 67,178, 98,100, 86,173, 92,150, 30,223,219, 73,155,214,142,102,178,229, 73,203, 23,118,161, 51, 71,135, 80,165, 10, 37, 8, 68, - 6, 33, 7, 76, 52,228, 16,173, 88,229, 84, 90,180,216,245,236, 7,146,181,124,249,114, 63,118,113,194,162,181, 60, 90, 39,190, - 35, 91,152,228, 84, 77, 95, 98,201, 84, 90,180,224,206, 70,217, 88,166,228, 54,101,153, 32,115,114, 55, 93,120,186,107,123, 47, - 41, 45, 91,113,153,176, 84, 69,166, 33, 22, 45,125,237, 46,183,190,170,249,126,183, 76,124,196,250, 33,196, 3,161, 60,222, 54, - 54, 52, 42, 81, 34,122,150, 52, 41,189,224, 52, 91,161,120, 23,151, 74,253, 97,215,168,187, 13,127,204,194,101, 64,229, 52, 53, -174,228,106, 99,183,219, 87,182,114,132,114, 80,222, 63,181, 4, 15,191, 24, 79,194,181,135,164, 74,246, 84,143, 71,187, 63, 53, -193,252,187, 31, 22,185, 77,175,175,156,238,220,238,143,249, 11, 42,246, 18, 60,108,217,202, 84,184,233, 64,155,172, 85, 43,232, - 35, 6,122, 10,194,226,147,246,131,126, 65,207,224, 78, 53,128,104, 65,116, 25,126,129, 63, 95,186,116,233, 39,118,229,134,115, - 12, 67, 4, 91,119,194,217,194,241,149,131, 69,131,113, 14,121,180,148, 65, 95,221,229, 98,168,243, 37, 25, 29, 16, 46,145,173, - 43, 3,157,110, 86,241, 78, 25, 54,175,123, 89, 42,152, 81,141,100,105,159, 29,254,187,114, 74, 50,163,201,214,197, 1,142, 55, - 75,184,167,138, 24, 61,176, 27,147,172, 20,209,214,177,104,146,101,128, 76,117,178,197,216, 5, 99,142, 30,153, 36,235,187, 15, - 1, 90,224,225,200,100,112,249, 55, 18,165, 39,205,230,233, 45,102,120, 56,254,160, 46,201,109, 47,189,237, 14,178, 85,202,221, -228,154, 76,146,245, 93,221,181, 20, 36, 39, 91, 32,110,200, 36, 89,177,100,206,152, 49,157, 26,213, 43, 67,247,110,108,164,144, -183, 59,233,194,169, 73, 84,179,106, 46,246, 2,240,160, 77,142,213, 65, 92, 30,123, 10, 12, 38, 90,124,147,178,109,219,182,149, -172, 88,108, 13,149, 72, 22, 7,210,131, 16,169,186,176, 99,200, 22,150,235,193,178, 61,186,136, 22,159,171,207, 50, 37, 43, 22, - 44,172, 32, 89, 8,206,199,113,185, 13,196,249,244,181,145,198,247, 18, 44, 91,252,225, 54,144, 39, 48,141,203,123, 73,163, 76, - 61,101,214, 87, 78, 3,170, 28,147,245,119,203, 52,229,193, 21, 88,109, 3,150,173,200,169, 10, 69,224,188, 4, 9,252,145,230, - 42, 20, 1,194,162, 21,151, 38,253,255, 53,223, 53, 46,119,126,210,162,210,108,205, 16,139, 74, 27,142,237,239,126, 88,228,150, -248, 79, 41,167,109,180,158, 97, 26, 6, 77, 49,116,186,202,105,193, 22,140, 97, 28,247,112,130, 73,219, 91, 36,238,208, 78,240, - 87,217, 48, 6,193, 66, 7, 16,191,172,238,170,100,235,124, 63,199, 91, 53,114,152,126,142,101,201,138,203, 18, 60, 42,100,235, - 76, 95,199, 91,213,115, 90,124,147,169,180,100,197, 65,166, 58,217, 98,139, 35,166, 77,144,229, 46, 84,239, 28, 37,203,219, 34, - 55,103,105,178,214, 57, 30,117,181,166,217,238,149,224,222, 36, 95, 79, 77,235,168,254,178, 54,146,251,192,252, 46,210, 62,107, -214, 76,170, 94,141,167,153, 40,157,143,178,121,187,243,100,149,227,164, 56, 40,184,119, 17,155,133, 64,120, 25,117,208,132,103, - 89,126,246,150, 99,142,172,104, 75,150,166, 56, 65,144,173,146, 88,128, 26, 11, 81,235, 33, 90, 56, 93,159,101,194, 5,249, 53, -218,146,101, 8,201,146, 75, 92,101, 84, 55, 86, 22,161, 75, 50, 17,227,233,120, 38,243, 68,166,136,169,107, 32,243, 18,145, 77, - 38, 2, 66, 9,101, 2, 37, 51,155,192, 83, 38, 80, 50,179,201,197, 83, 57,251,178, 28,177,114,101,202,145,165,204,163, 85,230, -255,201, 22,230,143, 66,144,122,150,205,146,187, 80, 55, 33,210,217,233,196, 88,182,164,248, 46,200,244,216, 46,185, 11,127, 64, -166, 33,149,149,209,225,194,191,151,128,124, 21, 9,181, 38,221, 1,210,191,180,141,140, 93,247, 31,144,167,179,221,121,142, 64, - 98,171, 13,241, 44,232,196,238,115,194,111,153,247, 18,120,202, 4, 74,102,182,127, 25, 79,153, 16,137,108,170, 8,252,203, 10, - 35,234,110,220,103, 65,224,169, 5, 79,201,202, 35,173, 81,200,211, 30, 96, 57, 26,205,241, 83,234, 87,235,196, 51, 70,230, 28, -175,210,180,216, 56, 50,227,168, 14,162,221,227, 8,156,150,203, 4,158, 2, 79, 99, 33,240, 51,116,201, 88,101,251, 29,114,212, - 99,178,126,107,140,214,143, 2,240, 51, 26, 87,200,252,209, 86,137,125,189,192, 83,224,105, 44, 4,132, 46, 25, 11,201,111,114, - 4,158, 2, 79, 99, 33,240, 51,116,201, 88,101,251, 29,114,148,196, 74,125, 31,243,224, 1, 48,245,100, 72, 65, 53, 93,175,239, -152, 62,249,250,174,143, 75,153,255, 6,153, 24,157, 83,143, 83, 59, 78, 88,241,190, 79,116,210,135, 39, 2, 57, 13,173,191, 62, -153,134,202,147,243, 96, 10,153,134,181,147,104, 35,237, 8, 8, 93, 18,186, 36, 87, 7,196,115,244,107,159, 35,229,221,180,181, -143,190,246,248, 19,207,255, 81,163, 14,127, 20, 32, 57,157,181,161,247,136, 47, 50,101, 79, 18,105, 0, 0,191,167,238,164,200, -193,129, 54, 83,162,147,156, 9,241,126, 79, 57, 13, 0, 50, 58,171, 40,167,225,152,233,186, 66,224, 41,240, 52, 22, 2, 66,151, -140,133,228, 55, 57, 63, 3, 79,227,150,240, 31,145,246, 51, 26,226, 95,150, 89,253, 39,232,205,175,193,147,200,150,215, 65,200, - 31,157, 82, 40, 62, 41, 26, 50,201,250,246, 23,164,104,204,139, 20,167,224,196,179, 78, 74, 9,139,163,170,111,191,166,156, 63, - 14,176, 40,231,143, 99,168, 42, 65,224, 41,240, 52, 22, 2, 66,151,140,133,164, 32, 90,154,144,204, 21,125, 16,253, 23,172, 91, -154,250, 49,227,182,128,156,175,251, 20,105, 51,219,166,176,241,168,144,210,218,189, 39, 18,254,199, 49, 61, 37,145,245,176,164, -178,115, 79, 99,106,151,237, 32,246, 50,106,166, 87,166,183,187, 89,205, 50, 69, 50,108,206,234,145,170,154, 12,121,177,216,190, -185,185,147,121,122,151,156,173, 44, 50,100,157,110,227,146,171,167,165,165,171,180,200,102, 28,182,150,186,174,225, 53, 65, 19, -228,106,237,151,176, 64,183, 83,137, 43,251,250, 37, 41,230,123, 56, 49,126,215,174,189, 78,215, 18, 21, 26,235,142,118, 72,105, -157,185, 97, 58,215, 60,147, 29,179, 22, 59,149,165, 80,141,119,238, 5,107,188,179,114,206,235,151, 58, 67,206,201, 56,167,163, -173,190,151, 73,212, 23, 11, 78, 73,169, 68,137,125,138,174,138,179, 49, 68,171,155,226, 84,137, 18,138,253,209,103,145,163,175, -129, 68, 11,211, 45,192, 42,150,145,215,212,178, 54, 0, 87,189,237,110,128, 44,101, 86, 33, 51, 14,160,233,184, 68,224, 41,240, - 52, 22, 2, 66,151,140,133,164, 32, 90,154,144,212, 25,163,165, 17,122, 39,175, 34,231, 60,242,148,125,139,148, 57,119,153,183, -153,114,149,121,155,222, 53,207, 30,101,102,171,140,185,246,216,102, 41,241,214,198,163,196, 91,107,247,226,111,211,184, 21,127, -107,230,148,255,156,154, 48,173,138,109,106,237, 94,163,106,195,142, 43, 23,172,217,115,241,252,205, 87, 33, 72,248, 31,199,112, -238, 71, 95,188,166,118, 57,102, 21,175,246, 95,152,169, 93,246,153, 50,116, 75,239, 3, 88,162,176,253, 17,122, 61,149, 74, 22, -206,176, 95,134,188, 88, 68, 11, 36,171, 93,183, 1,179, 31, 62,122, 54,183, 68,205,118,179, 76,211,185,207, 73,101,155,117,180, -169,141,123, 49,133,194,215,144, 37, 14,212, 39,245,147,138, 2,130,229,218,105, 87, 34,115,199, 2, 86, 73, 77,211,118, 74,146, -194,226,100,210,148,150, 39,147, 91,102,232,234,152,183, 65,250, 82,125,252, 52,205, 12,174,149, 24,152,217,122,149,118,203, 93, - 62,120,240,172,125,225, 99, 87, 93,165,177,107,111,115,186, 67,157,199,108, 34,207,108,121,104,254,150, 75,212,212,119,115,184, -157, 87,169,224,148,156, 87, 22, 41,122,244,104,108, 12,209,122,240, 32, 31,147, 44, 19, 78, 54,209,201,228,249,115, 5, 47,232, -249, 45,199,195,135,138,113,178,100,114,166,114, 21,235,150,241,240,204,126, 38,181,153, 69, 95,243, 52, 86,189,237, 29,156,253, -211,166, 77,119,143, 79,101,136,209, 85, 43, 43, 83,254, 95,204,167, 20, 27, 84,189, 58, 47, 83,207, 85,179, 9,153,113, 0,237, - 71,223,117, 6,222, 82,180,145,129,128,233,201, 46,240, 52, 46,158,241, 89,154,186, 37, 75,255,168, 67, 16,172, 15, 31,195,104, -209,238,251, 82,122, 22, 16, 74,141, 59,143,193,188, 42,183,144,170,182,244,165, 43, 15,222,211,172, 45,183,104,230,230,155,116, -250, 70, 0, 89,100, 42,134, 85,227,245,190,120,147,219,120,230,109,222,105,200,198, 27, 79,130, 35, 54,239,247,187,215,109,224, -196,157, 72,248, 31,199,112, 14,121,180, 32,174, 87,177,147,219,185,218,231, 41, 81, 43,248,245,251, 79, 17, 89,242, 86, 8,196, -111,185, 15, 11,207,202,222,133,151, 87, 25,130,196,179,183,199,164,194,121,237,238,128,104, 21, 45, 96,119,214,210,206, 35,216, - 42, 99,206,192, 12, 30,249,143,155,217,123,106,179, 50,197,148,211,194, 33,235,180, 59,119,239,207,221,176,255,210,220,150,190, -171,231, 94,189,251,124,238,229, 91,143,230, 50, 17,156,249,141,108,201,222,122,171,231,180,183, 47,144, 40, 81, 50,211,242,137, - 77, 76,215,186,150,232, 28,182,234,240,115,186,247, 34,132,174, 61, 14,162,177, 27, 30,144, 83,161,102,225, 38,169,109, 48, 57, - 44,102, 50,215, 68,234,190,195,211,217,187,232,235,153, 91,190,145, 43,101, 82,146,172, 83,151, 31,209,204,109, 15,164,227,125, -231, 95, 36, 11,199,220, 47,180,147, 34,226, 5, 78,169,153, 66,113,163,135,162, 76,179, 11, 10,127,255, 17, 76,165,250, 42,222, -188,193, 66,212, 78,156, 48,137, 33,146,211,155, 55, 10, 27, 88,178,252,253, 21, 35,154,149, 81,248, 93,228, 32,127, 86,182,102, -156,148,139,164,106,108,247,114, 21,106, 94,152,187,124,127,248,230, 83,175,105,232,194, 11, 84,174,122, 11,202,153,191,196, 87, -158, 28,239,144,147,123,174,131, 94,249,203,127,176,115,116,251, 96,102, 97,117,193,220,220, 18,228, 75,117, 9, 21,189,186, 36, -187,101,254,159, 81,200,140, 3,104,130,108,104, 68, 64,232,146,208, 37, 99, 33, 16, 95,116,201, 88,245,141, 31,114, 64,180, 34, -121,141,184, 94, 51,142, 75,105,243,209,251,116,238,198, 43, 42, 95,191, 59,149,168,221,149,182, 30,127, 64,139,182, 95,167, 78, -147, 14, 81,199,137, 7,233,160,223, 19,217, 68,203,212,198,163,195,241,203, 79,222, 77,156,183,254,100, 10,107,247, 54, 41,211, -185,103, 69,194,255, 99,102,174,242, 59,228,119, 63,196,212, 38,139,111, 92,137, 86, 42,251,156,155,143,156,187,243,213,239,206, -187,144,185,235,142,189, 51,181,207,177, 65, 46,209, 2,193,226,101, 2, 38,176,105, 37, 86, 26, 51,162,207,188,210,133, 51,108, -115,176, 77,225,123,238,188, 31,125,250,252,133,238,220,123, 68,255,117,236,243,145, 45,125, 39, 83, 90,121,130, 60,168,110, 49, -138, 13,139, 86,131,150, 61,102,215,235, 53, 87, 34, 89, 44,123,238, 51,255,247,115,125,231,108,155, 11,203,150, 1, 26,129, 17, -134,170, 91,109, 43, 91,231, 81, 99,215, 92, 63,119,247, 89, 32,221,127, 17, 76,151,238,189,163,147, 55,222,208,177,107,111,232, -244,173,119,116,245, 97, 16, 29,190,250,150, 74, 14,190, 72,201,205,237, 94,241,197, 53,181,149, 83,121,220,217,219, 39, 98,219, -233, 87, 58, 73, 22,136,214,224, 69,231,201,210, 49,215, 87, 29, 68,139, 73, 22,211, 39, 41,249, 73,179, 1, 51,121,173,157, 45, -123,142,231,117, 27, 54,127,209, 99,208,132,144,214, 61, 70,133, 20, 44, 83,247, 69, 58, 71,143,231,201, 77, 45,107, 35,207, 13, -133,162, 78,244, 69,184,144,101, 72,155,198, 23, 69, 70, 23,247, 3, 97, 17,145,116,230, 86, 32,141,231, 50,245,154,176,157, 90, -245,158, 21, 53, 96,238,241, 79,221,198,111,167,145,203,175, 81,131,182,131,168, 84,249,186, 84,168, 68,213,243, 85,154,143, 77, -197,178,148,214,173,248,242,242, 17,229, 52,224, 33,145,145, 85,224, 41, 3, 36, 3,178, 8, 60, 13, 0, 75, 70,214,127, 25, 79, - 25,240,252,177, 89,116,143, 58,220,190,125,251,119, 51, 0,131,104,133,133, 71, 82,165,238,107,165,212,119,246, 41, 58,113,253, - 45,221,121, 22, 66,151,238, 7,210,162,189,143,168, 82,223, 93, 84,186,227, 74, 42,213, 97, 5,173,217,119, 93, 19,209,138,133, -200,132,209, 41,114, 77,158,108, 54,190,102,221, 60, 27,110, 62, 13,161,214,157, 42,239, 29, 51,198,124, 26,142,155,155,103, 55, -183,118,201,189, 44,103,209,170, 95,112, 46,125,166,252,159, 82,218,231, 88,136,227,134,192,154, 34, 93,150,170,141,218, 14, 8, -190,243, 44,232,115,238,118,123,207,158,190,241,214, 63, 87,137,122,254, 41,210,101,174, 42, 71, 14,172, 88, 32, 89,188,184,243, -132,231,207,159, 79,224,117,181, 38,240,154, 95, 19,218,183,174, 51,172,100, 33,251,221,118,182, 38,195,158,191,120, 77, 97,225, - 68,225, 17, 68, 97, 17, 81,180,112,197,230,136,180, 25,115,158, 97,249, 26, 99,161, 16,163,101,102,231, 53, 32,181, 93,246, 89, - 32, 90,254,239,130,231, 46,217,118,102,110,229,142, 51, 12, 37, 90,234, 85,232,253, 53, 44,162,207,200, 81, 99, 46, 52,106,210, -226,201,226, 53,187, 30, 30,190,240,146,118,159,123,193,233, 37, 29,190, 28, 64, 23,238, 5,210, 35,255, 80, 10,254, 20, 65,251, - 46,190,161, 4, 9, 18, 96, 9, 4,157,155,173, 91,129,175,129, 65, 33,244,236,205,103,218,126,234, 5,213,104,218,147,230,173, - 63, 65, 83, 55,222,162,225, 75,252,104,196,194, 19, 52,122,193, 1,106, 55,112, 14,165,182,207,254, 69,187, 48, 88,179,148, 68, -139,164, 17,147, 78, 78, 78, 23, 31, 60,245,167, 27,108,113, 59,112,233, 53,173, 56,248,132, 38,108,184, 67, 29,167,240, 2,177, - 22,182,108,200,146, 86,245, 45,167,129,104,169,223,198,132, 15, 96,202,138,221, 33,161, 97,145,135,175,188,165, 61,103, 94, 83, -173,255, 6,209,176,149, 55, 67,199,174,129, 53,142,173,114,107,110,211,232,213, 55,169, 90,221,246, 84,189,126, 39,106,216,117, -170, 15, 95,163,203,149,170, 15, 30,113, 94, 32, 32, 16, 16, 8, 8, 4,126, 2, 2,154,184,200, 79,184,205,239, 17,169,141,104, -221,120, 16, 64, 46, 85,167,144,239,130,147,180,112,207, 99,154,184,225, 46, 13, 90,114,131, 58,206,184, 68, 13,199,156,165, 10, - 3, 79,144, 87,227,149,148,161,194, 4, 26, 58,239, 48, 89,184,126,231, 58,140, 85, 33,144, 44, 38, 49, 52,108,184,219,139,153, -115,154, 73,123,252,198,113,182,162,236,154, 52,123,101, 84,177, 10, 13,232,210,221,183, 84,164, 92, 61,234, 55,102, 81,148,133, -115,254, 93,114, 81, 73,109,239,105,105,153, 49,247,155,199,254, 65, 97,109,167,158,187,237,222, 98,239,193,158,243,175,159, 88, -181,239,230, 13, 38, 4, 47,113, 94,159, 44, 37,209,122,250,244,169, 68,178,110,220,184, 49,225,202,149, 43, 19,170,148,243,188, - 2,215,161, 79,126,187,115,111,223, 7,211, 87, 38, 90,111,131,195,233, 22,147, 66, 16,153,114,181, 90,133,166,178,213,234, 70, - 84,164,178,205, 54,246,232,185, 27,115, 7,204,216, 54,119,220,146, 3,115,171,117,157, 53,215,218,171, 66, 44,215, 97, 42, 91, - 55,119,206,247, 56,149, 93,118,255,152,100,239,125, 94, 71,153,123, 71, 68, 70,245, 62,125,238,194,152,227,103, 47, 47,153, 49, -111,217,233,134,205,218, 60, 91,186,249,196,245,195,151, 95,133,159,187,253,142,142, 92,125, 67, 67, 86,220,165,178,131,206,211, -164,205, 15, 65,168, 53,173,249, 23,235, 22, 54,110, 5, 58,148,173,213, 54,226,225,139, 32,201, 74,246,249,107, 4,189,126, 23, - 74,215,239,191,166,189, 39,111,211,228,165, 7,168, 65,247,233,100,158, 49,127,184,169,109,206, 14, 58,136,150, 29,211, 38, 38, - 88, 82, 74,139,124,105,210,164, 41, 89,171, 94,195,215, 23,153,172,239, 58,247, 74, 34,236,163, 86,223, 34,247,124,149, 94,155, -152,152,149,140, 38, 90,105,163,201, 22, 8, 23,203,208,184,205,107,217,190,207,132, 5, 43,246, 71, 46,217,245,152, 86, 31,124, - 73,189,134,204,160,206, 67,151,210, 24, 38, 87,146,203,115,221, 55,215,231,168, 85, 55,168,117,159,153, 84,174,110, 7, 74,102, - 98, 42,214,217,210,247, 16,136,243, 2, 1,129,128, 64,224, 55, 32, 16,207,137,150,170, 69,235,251, 65,125,154, 42,167, 12,134, - 47, 82,169,217,215,203, 15, 62,208,130, 61,143,168,207,180,125, 84,189,253, 4, 42,211,124, 52, 85,234,177,142,137,214,113,170, - 60,228, 36,101,200, 93,251,107, 26,142,207,210, 16, 12, 31,211, 84, 85,171,218,102,104,215,202,110,226,184,177, 14,167, 26, 52, - 48, 13, 3,193,194, 30,191,113, 60,107,190, 34, 65,129,159,136,166,204, 89, 65,101,170, 55,163,137, 51,151, 18,126,219,122,248, - 4,202,109,111, 83,251,236,171,198, 47,216, 25,124,230,214,187,144, 28,237, 14, 94,206,213,249,248,233,252, 61, 79,239, 95,122, -240,229,197,250, 93,166,156, 79,149,222,107,169, 62, 89, 74,162,117,239,222, 61,137,100, 93,190,124,121,194,185,115,231, 64,180, - 46,130,104, 21, 43,104,119, 26, 68,235,197,187, 47,116,241,254, 7,218,117,222,159,182,157,121, 73,243, 55,156, 96, 55, 90,238, -227,218,228,195, 69,120,224,212,229,185,238, 85,134,204,101,183,232,108,245, 96,120,144, 44,183, 92,165, 95,247, 24,181,156,250, - 79,222, 36,165,142,195, 87, 17, 8,151, 46,162, 5,239,238,201,211,103,251, 28, 62,118,102,224,158,131,167, 70, 28, 58,117,109, -226,208,145,227,239,183,106,223,237,125,243, 73,151,168,112,167,157, 84,180,251, 65, 42,209,247, 20,141, 90,251, 64, 22,209,194, -253,152,108,117, 44, 94,181, 85,196,182, 19,143,168, 74,159, 29, 84,182,243, 90, 42,218,114, 33,101,175, 53,158, 10,214, 27, 69, -169, 50,228, 3,201,234,168, 15, 79, 77,231,211,219,218,207,159,181,116,107,228,230,147, 47,104,246,142, 7,212,172,223,226, 72, - 83,243,116,243, 13,144,149,130,131,223,215,157,186,241, 54,242,214,163, 47,180,246, 24,187, 57,153, 92,117, 31,187,133, 70, 51, -169,194,255, 18,209,194,158,211,193, 75,111,232,194,173,183, 52,101,205,133, 8,190,199, 18, 78, 41, 13,184,151,200, 42, 16, 16, - 8, 8, 4, 4, 2,191, 0,129,120, 78,180, 84, 17, 82,146,174,255, 31,211, 85, 57,119,118, 33, 62,120,249,145,150,236,123, 76, - 77,123,205,100, 23, 84, 56, 33, 72,190, 80,253,145, 84,126,192,113,170, 59,242, 12, 89,101, 46,174, 30, 4,255, 93,147, 84,171, -102,245, 95, 84,212,215,205,109,219,100,184, 1,146,165,220,240, 27,199,243, 22,202, 26,244, 62, 36,130, 30,248,127, 33,255,160, - 8, 58,125, 59,136,230,239,126, 76,169, 29,243,233,181,192,224,102, 41,172,178,228,200,152,189, 76, 96,120, 4, 83, 15,222,234, -141,189,112,173, 96,143, 51,199,139,244,185,176,167,230,232,155,219, 87, 29,123,125,198,218,181,192,115,228,211,165, 47, 74,162, -117,237,218, 53,137,100,157, 57,115,102,194,241,227,199, 39, 52,111, 92,101,120,233, 34, 25,182,186,101, 76,213,234, 26, 91,118, - 78,223,122, 79,155, 79,189,164, 57, 59, 31,210,104,118, 81, 45,217,125,147, 82,219,102, 13,214, 38,219, 52,189,151, 7,200, 21, -167,177, 32, 85,170,249,148, 36,171,203,240, 37,148,187,198, 96, 74,157, 33,247, 59,185, 22, 45,174,106,207, 51,103,206,246, 58, -121,234,108,159, 99, 39,206,244, 63,112,228,212,144, 57, 11,150,206, 45, 94,162,196,171,252,173,215, 83,161,142,219, 99,136,214, -192,101,119,101, 19, 45, 37,217, 42, 89,167,203,215,193, 11,206,145, 79,187, 53,148,187,233, 66,106, 63,122, 59,165,207, 86,229, -179,169,189,193, 36,203,194,193,193,193,215, 37, 83,166,227, 89,179,231,122,178, 97,255,101, 90,123,244, 41, 77,221,124,151, 99, -252,246, 83,218, 12, 89,158,164,176,204,112, 60,169,169,181, 47,223, 27,211, 53,104,221,246,157,190, 94,185, 70,189,230,244,248, -245, 23,138,226,230, 30,187,248, 70,196,136,229,215,162,148,129,251,107,142,248,211,192,137,171,169, 82,227,190, 52, 96,246, 81, - 30,180, 17, 74, 15,159, 5, 71, 13, 24, 54,245,181, 77,122,251,171,250,228,255,130,247,137,184,133, 64, 64, 32, 32, 16, 16, 8, -168, 33,240, 23, 16, 45, 37,193,210,108,209, 66, 5, 53, 85, 18, 68,235,232,197, 39,180,227,244,115,234, 53,101, 55, 85,105, 53, - 70, 34, 90,249,235,248, 82,185,254,199,169,230,176, 83,178,136,150,100,209,106, 99, 55,113,236, 88,135,147, 13, 27,164, 8, 5, - 25,194, 30,191,113,220, 61,103,193, 55, 1, 31,190,210,210,253, 79,168,199,220, 43, 84,186,239, 49,170,193,178,229, 18,173, 84, -246,217,231,173,223,115, 65,146,123,245, 81,112,112,161, 94,103, 79, 21,233,123,225, 96,185, 97,215,119, 87, 26,117,119,253,200, -141,254, 59, 26,244,154,119,200,212,198,115,134, 46,237,182,182,182,150, 98,180, 46, 94,188, 24, 67,178, 14, 30, 60, 56,161, 89, -163,202,195, 48,143,150,171,115,138, 22,187, 78, 63,102,146,240,156, 73,194,125,234,191,232, 58,181,155,118,145,198,172,188, 72, - 76,162, 52, 18, 45, 16, 41,123,247, 2,143, 29, 61, 11,251, 59,100, 41,236,159,222, 53,255, 99, 37,217, 82, 37, 89,121,235,140, - 36, 51,167, 2,175, 82,166,243, 40, 37,243, 9,236, 13,162,117,246,236,217,158,103,206,158,237, 5,194,117,252,228,169,190, 11, - 23, 45,153, 86,188,120,241, 23,249, 91,175,139, 69,180,186,205,191,101, 16,209, 66, 25, 80,102,118, 79,210, 99,118,143,142, 97, - 66,137,196, 46, 67, 89,228, 87,181, 14,105,211,166,237, 58, 99,198, 12,122,230, 31, 72,215, 30,125,160,253, 23,252,105,249,129, -199, 52,110, 29, 91,162,230, 94,166, 6, 99,206, 80,177,238,123,201,182, 80, 7, 74,146,220,188,171,174,250, 47, 91,182,215,186, - 92,229,218,116,229, 81,168, 68,180, 48,104,163,255,244, 61,212,123,218, 1,201,130,117,232,210,123,186,255, 60,136, 22,110, 60, - 67,221,135, 47,162,202, 77,122, 81,171, 46, 35, 46,123,122,231, 9,173, 88,163,129,250,128, 2,153, 80,139,108, 2, 1,129,128, - 64, 64, 32,240, 51, 17, 80,242,144,191,136,112,201,131, 43,115,238,178,111,231,109,242,163,253,231,159,210,180,173,247,169,114, -171,209, 49, 68,171, 44, 19,173,170,236, 58,148, 99,209,194,221, 38, 78,252, 22,163, 5,114, 5, 75, 22,246,248,141,227, 46,222, - 69,253, 95, 7,126,161,197,251,158, 80,183, 57, 87,168,100,159,163, 84,125,232, 73, 3,136, 86,206, 43,247,159,127,248,226,187, -226,246,227,194,189,206,157, 45, 62,224,210,209, 6, 19,111, 31,106, 59,239,209,190, 14, 11,158,111, 27,180, 38, 96,195,176,101, - 23,118,155,218,122,157,214, 85,115, 38, 4, 18,209, 58,125,250,244,132,163, 71,143, 78, 56,112,224,192,132, 93,187,118, 77,168, - 84,198, 93,138,209, 42, 86,208,254,216,188,173, 55,153, 32,220,145, 8, 33, 98,213,154,140, 59, 71,245,251,175, 99,119, 90,174, - 19,154,100,131,100, 29,243,187, 71,213,234, 52,163, 10, 53, 26,211,206, 19,119,201,218, 37,159, 68,182,188, 10, 87,253,248,254, -253,123, 2,201,178,206, 90,237,101, 74,155, 44, 19,229,181,140,148, 43,134,104,129,108,157, 58,125,186,247,150,237,187, 71,206, -156,183,100, 62, 19,173,231,234, 68,171,221,204, 27,113, 34, 90,129, 33, 97, 52,109,203,125, 42, 84,119, 8, 85,108, 53, 62, 78, - 68,203,213,213,117,254,181,107,215,233,249,219, 79,228,119,247, 61,237, 56,251,146, 22,236,126, 72, 35, 86,221,228,152,191,139, - 84,107,248, 41, 42,212,237, 16,101,170, 61,159,146,153,217,234,115, 35, 38,242,202,150,123,109,165,234, 13,104,217,198, 3,116, -247,229, 87,170,206, 65,240,237,134,174,166,225,203,175, 68,141,216,120, 63,236,203,215,240, 40, 16,196,189,231,222,210,140, 77, -119,168,211,176,229,148, 35,119,161,203, 94, 94,217,179, 25,128,175,200, 42, 16, 16, 8, 8, 4, 4, 2, 2, 1, 57, 8,232,142, -209,210, 37, 1, 68,107,223,249,231, 52,124,225, 49,218,118,250, 5, 53,238, 57,147, 78, 93,122, 64,133,234,125,115, 29, 86, 24, -112, 66, 54,209,194,232, 66,144, 42, 88,176,224, 46,196, 30,191,113, 28, 68,203,255,253, 23, 14,142,126, 76, 93,102, 95,166,226, -189,143, 82, 21, 38,113,114, 45, 90,166,182, 89, 3, 63,126, 14, 15,175,232,235,231,231,211,231,194,209,218,227,111, 31,238,188, -240,241,145, 97,235, 95, 29, 30,179, 37, 96,207,136,205,111, 55, 44, 61, 28,184,137,137,140, 78,107,140,146,104, 29, 62,124, 88, - 34, 89, 59,118,236,152,176,117,235,214, 9,149,203,102,145, 98,180,124,242,219, 94, 28,184,208, 79, 26, 16, 80,107,248,105, 42, -209,235, 40,181,155,122,129, 92,243,213,254,200, 51,219, 99,161,231,239, 54,199,172, 69, 63,188,226,186,157,187,243,158,142, 92, -121, 67,115,217,221,104,239, 89,244,171,119,225,154,159,199,175, 58, 79,141,152,172,205,157, 59,151, 82,218,120,242,132,175,185, -146,200,105,209,232, 60,189, 35, 34, 34,122, 30, 62,114,172,255,234,245, 91, 38,204, 89,184, 98,254,178, 85, 27,166,174,223,184, -101,148, 38,162,213,108,210,213, 56, 17, 45,140,172,124,252, 58, 84, 10, 46, 31,178,236, 70, 92,137,214,161, 55,239,131,232,225, -171,143,116,234,230, 91,218,116,226, 57,205,218,126,159, 6, 45,189, 78,173,166,248, 81,229,193, 39, 40, 79,167, 3,148,165,197, - 86, 38, 90,118,135,100, 98,224,105,157,206,246,202,146,237, 55,137,219, 94, 26, 93, 8, 2,172,140,209, 90,181,239,126,212,220, -157, 79,104,252,250,187,212,188,203, 68,106,208, 97,100, 36,203, 93,205, 9, 35, 22,197, 38, 16, 16, 8, 8, 4, 4, 2, 2,129, -223,143, 0,136,214,233,155,239,104,216,146,243,212,115,250, 17, 26,181,228, 36,181,246, 93, 69,205, 71, 31,162,178,253, 14, 83, -153,126, 71,201,138,103,133, 55,164,164,112, 35, 34,102, 11,123,229,117, 32, 90, 32, 35, 11,118, 63,162,206,179, 46, 83,177,158, - 71,168, 18,119,190,178,137,150, 93,142, 75, 87, 31,188,253,208,105,238,109,191,226, 3,175,238,109, 62,253,225,126,223,181,175, - 14,205,217,255,254,196,162,195,193,135,231, 31, 10,217, 50,122,229,197, 53, 28,136, 46,203,162,181,111,223, 62,137,100,109,222, -188,121,194,218,181,107, 39,212,171, 85,106,120,201,130,246,123, 50,164, 79, 49,188,213,184,163, 84,123,196, 25,118,155,158,150, - 72, 86,161,122, 67, 35,120,185,159, 11, 92, 23,141,211, 59,100,240, 44, 26,242, 36,224,147, 68,176,198,112,144,118,159, 5,215, -168, 94,167,137, 52, 99,219,125,170, 51,226, 52,213,242, 61, 70, 46,185, 43, 7,153,164,115,115, 54, 4, 71,190, 93,223, 19,103, - 47, 77, 95,187,105,215,252, 13,155,119,140, 59,118,252, 68, 95, 88,182,184,236, 3, 84,137, 22,176,172, 50,236, 2, 85, 30,122, - 1, 68,235,153, 33,247,128,235, 16, 46,221,169,209, 22,173,210,205,199,146, 89, 28, 92,135, 89,178,100,185, 4,151,243,237,167, -193,116,248, 74, 0,173, 62,252,148, 38,111,186,203, 88, 92,165,166,227,207,177, 46, 29,163,108,109,247,145, 87,235,189,148,204, -194,241,146,220, 50,154,153,155,207, 26, 60,110, 97, 68, 80,104, 4,189,124,251,133, 74,213,104, 71,205,250,204,161, 77, 39, 3, -152,212,125,161,241, 27,165, 81,135, 65,253,167,239,163,126,156, 88,174, 47,167, 2,114,229,139,124, 2, 1,129,128, 64, 64, 32, - 32, 16,144,129,128,234,204,240,223, 7,195,235, 18, 0,162,133,249,179,102,239,120, 72,131, 22, 95,162,150, 99, 14, 83,189,161, - 7,169,234,192,131, 84,170,247, 97, 42,222,235, 8, 97,249, 29, 45, 50,100, 79,188,230,226,237,227,255,226,221,103,154,183,235, - 17,117,156,121,137,124,122, 28,145, 70, 53,106, 32, 90, 26,101,166,178,245, 30, 55,124,250,250,199, 7,174,188,127, 88,114,200, -141,205,109,230, 60,222, 62, 98,115,192,158, 69,135, 63, 28, 94,113,252,227,158,237, 23,190,108, 47, 83,183,215,230,148,233,179, -140,210, 80,214, 24,153,176,104,125,250,244,233,187, 9, 75,125, 7,118,153,135, 96,120,123, 91,147,161, 3,166,110,167,254,243, -206, 82,221,126,107, 41, 83,254, 58, 31, 57, 62,236,124,242, 52,110,234,211, 16,196,200,204,144,197, 39,232, 34,187,203,166,108, -190, 71,189,153,100,181,154,114, 65,178,134,193, 61, 90,105,208, 9,202, 93,169, 83, 40, 7,191, 55,147,209,144,234,241, 69, 13, -221, 61,189, 7,237,222,189,167, 87, 64, 64, 64, 79,158,239,171, 39,143,144,140, 33, 90, 5,218,172,167, 82, 3,206, 81,141,145, - 23,201,171,234,112, 74,154,210, 34,148,239,209, 68,237, 62, 58,219, 8, 68,235, 43,207,167,134, 24, 45, 88,180,122,206,187,194, -113,100,122, 99,180,190,147,153, 39, 79,158, 59,112, 13, 95,121,248,129,246,250,249,115, 44,222, 99,105,158,171,174,115, 46, 83, -189, 81, 28,159,197,122, 4,146,133,148,220, 42,243, 29, 13, 88, 96,102,123, 77, 91,133,138,213,234,145,255,135,112,186,120,239, - 3, 21,244, 41,133,185,194,246, 55,104,215, 45, 50,244, 75, 36,193,125,184,231,220, 27, 46,251,183, 17,136,229, 27,244,228,249, - 80, 21, 46,209,130,100,235,167,140,182, 81,102, 17, 50, 13, 0, 75, 70, 86,129,167, 12,144, 12,200, 34,240, 52, 0, 44, 25, 89, - 5,158, 50, 64,250, 71,178,168,175,117, 40,191,218, 88,231, 16, 46,189,128, 15, 95,232, 9, 47,195,115,251, 89, 48,199,216, 4, -242,144,249,215,146,251,103,194,250, 59, 70, 33, 90,206, 89,125,252,159,243, 4,153,243,153,104,117, 96,183,156, 15, 91, 97,202, -246, 63, 70,169,190, 31,117,168, 81,177,211,166,205,156,202, 60, 67,142, 39,187, 79, 61,184,181,245,124,224,133,161,107,253,183, -141,220,242,118,211,146, 99, 31,183,239,190,242,101,207,196,213,103, 22,178, 53,235, 62,242,233, 34, 90,230,230,230, 93, 44, 45, - 45,135, 32,241,255, 49,169, 80, 30,219,251,210, 18, 60,249,237, 78,167,176,206,252,209, 52,125,214, 96,196,100,177,187,176, 61, -203,211,100,201,138, 41,167, 99,246,178,167,102,173, 57, 38,145,139,246,211, 47, 81,253,209,103, 37,183,104,109,182,102,229,175, - 61,228,171,165,115,254, 69, 50, 91, 68, 83, 32, 55,172,130,221, 10, 20, 40,216,115,247,238,221, 61, 31, 63,126,220,243,200,145, - 35, 3, 74,150, 44,249,188,238,152,203,148,167,217, 34, 74,153, 54, 35,166, 53,192, 32, 0, 77, 11, 46,235, 37, 90,136,171,154, -181,253, 33, 21,169, 55,148,138, 53, 30, 19, 23,162,149,176,104,209,162, 79,159,189,249, 68,231,217,125,138,233, 48,230,237,122, -136,137, 69, 25,143,139,210,160,135,130, 93, 15,197, 16,173,148,182,222,152, 84, 85,125,185, 32,109,229, 76,192,145,110,215,203, - 85,170, 69,117, 26,181,162,145, 83, 22,192, 53,108, 98,146, 34,197,156, 50,229,106, 6, 30,191,244, 66, 26,134,122,254, 86, 48, -237, 59,255,129,188, 11,150,199, 76,246, 74,203,161,120, 73,202, 84, 60,153,217, 4,158, 50,129,146,153, 77,224, 41, 19, 40,153, -217, 4,158, 50,129,146,153,237,103,224, 41,243,214,127,100, 54,221, 51,195,235, 42,178,131,103,145,115, 88, 80,218, 37, 71,233, -183, 78,217, 75,191,117,200, 90,234,173,189, 87,201,183,170, 11, 74,243, 40, 52,245,197,164, 13,254,186,119,242, 44,180,181,239, -200, 25, 17,235, 15, 92,167,217, 28,187,211,200,119, 23,185,148,234, 25,158, 42, 67,222, 77,106,229,211,218,184, 41,108,220,242, -164,182,203,246,168,211,160,217,167, 54, 28,190,115,232,248,205,224, 93,171,246,221, 90, 95,187,213,128, 77, 60,153,232,125,156, -215, 82, 87,189, 10,131,197,164, 65,180,176,184,180,204, 38,142,145,153, 34,173, 71,122,123,207, 18, 95,250, 76,217, 78,147, 54, -220,150,220,101,181,135,236, 37,207,210,237, 62,155,101,200,181, 82, 11, 81,211,116,155,198, 58,238,157,149,207,245, 98,130,213, -147, 93,157, 3, 74,148, 40,249, 60,141,115,129, 40, 62,182,150,147,114,189, 64, 77,151,235,172,123, 6,143, 2,103, 86,110, 59, - 17,254, 54,232, 43,173,227,145,150,101,219,205, 13, 51,115,204,139, 89,240,117,109,234, 50,109, 27, 53,105,246,242, 62, 79, 19, -114,226,250, 27,218,112,252, 25,205,216,122,143, 6, 46,185, 70, 45, 39,157,103,171,222,113,202,213, 97,127, 12,209,178,200, 92, -230, 37, 11, 87, 31, 30,171,171,156,137, 56,127, 43, 78, 85, 84, 11,149, 40,113,226,190,182,118, 14, 55,219,245,153, 26, 62,107, -205,105, 42, 94,174, 14,185,231, 40,178, 74, 37,143,222,118,151,217,214,170,217,132,204, 56,128,166,227, 18,129,167,192,211, 88, - 8, 8, 93, 50, 22,146,223,228,252, 12, 60,141, 91,194,127, 68,154,236,134,176,180,116, 77,109,147, 41,239, 52, 91,247, 66, 23, - 45, 50,230, 14, 48,207, 88,208,143, 45, 70, 19, 20,182,185, 82,168, 97,165, 83, 38, 44, 86, 28, 84, 62, 38,165,109,214, 51, 8, -124, 71, 76, 22,220,133, 90, 44, 89, 74,209,122,203,233,157,217,172, 22, 92,135,222,238,102,234,107, 5,106,107,202, 88, 50, 77, -211,185, 88,155, 59,229, 93,106,233, 92,192,223,204, 49,223, 59, 94,143,145, 45, 99, 30,213,248, 98,141,113, 93, 90,132, 98,201, - 25,125, 27,150,152,233, 21,157,180, 17, 75,217,196,192,202,202,211,148,151,228, 57, 99,227, 86,208,159,231, 33,243,183,204,152, -239, 12,142,233, 41,132, 58,158,249,125,135,141, 12,186,249, 36,136, 14, 93,126, 77, 43, 15, 61,161,137, 28, 59,213,107,254, 21, -106, 60,238, 44, 79,229,113,148,178,182,249,230, 54, 68, 74,151,239,191, 32,150,159,223,144,118,215, 81, 30, 39, 62,135,245, 36, - 65, 56,213, 39, 88,213,219,238,250,192,214,112, 94,200,140, 3,104, 58, 46, 17,120, 10, 60,141,133,128,208, 37, 99, 33,249, 77, -206,207,192,211,184, 37,252,181,210,148,174, 67,229, 93,213,127,255,180,210,252,140,134, 16, 50,141,219, 92,191, 2, 79,215, 76, -110,238,167, 51,123,100,245,115,243,204,126,197, 53, 75,174, 91, 78, 30,185,239,219,103,206,243, 36,157,115,174, 39,102,246,222, -247,147,219,100,185,149,220,202,237, 74,242, 52, 46,126, 38, 22, 25, 48, 96, 65,221, 10,247, 43,202,105, 12,100, 69, 57,141,129, -226,255,101, 8, 60, 5,158,198, 66, 64,232,146,177,144, 20, 68, 75, 19,146,234, 49, 90,130,104, 25,201, 90,162, 75,109,197, 67, -253,231, 63,212,162,141, 68, 27, 25, 11, 1,161, 75,198, 66,242,231,117,226,162,141,254,252, 54, 50,110, 9,127,173, 52,157, 49, - 90, 80, 62, 77,201,144, 34,106,147,161,235,184, 62,249, 66,166,230,118, 81,197, 5,174,196,234,156,212, 71, 18,106,194,150, 23, -118,214,216,206,127, 90, 27, 33,224,223,208,182, 23,186,164, 29, 1, 67,177,148,211, 25, 9,153,134,233,168,208, 79,161,159,154, - 16,248,151,159, 35, 37, 30,198,224, 31,250,158,175,191,254,188,156,151,182,161, 32, 8,153,134, 34,166, 59,191,192, 83,224,105, - 44, 4,132, 46, 25, 11, 73, 97,213, 17,186,244,111,234,146,113,107,253,107,165,197,125,212,225, 15,150, 83, 60, 44, 63, 8,160, -218,229, 2, 79,129,167,177, 16, 16,186,100, 44, 36, 5, 41,138,151,186,132, 1, 82,122, 6, 73,197,210,144,148, 86,158, 54, 72, -226,157, 28,131,192,207,104,119,227, 62,149,191, 71,154,209, 98,179,146, 36, 76,156,172, 87,202,212,105,111,152,154,167,125,174, -163, 46, 63,163, 33,254, 52,153, 9,220, 51,154,118, 42, 83,212,121,179,135, 75,138,106, 42, 88,232, 45,103, 74,107,247,197,233, - 51,229,127, 98,154,206,189,147,134,209,149,218, 76,205, 26,225,198,168,198, 84, 14,121, 78,164,182,207, 42,103,100,162,170, 12, -189,229,228,204, 38, 94, 94, 94, 5,145,240,191, 12,221,213, 43, 51,101, 58,247, 6, 25,220, 10, 28, 77,231,154,147, 23,250,206, - 92,219, 24, 50, 85,101,240, 58,146,105, 83, 57,228,222,192, 19,193,190, 79,101,155, 61, 40, 85,134,220, 71, 82, 91,121,234, 13, -176,119,168, 58, 42,203,208, 85, 87, 87, 97,175,169, 76,150,229,167,165, 30,178,250,206,200,180, 85,198,106,154,143, 13,151,232, -173,187,140,186,170,103,249,171,100, 58, 20,110, 96, 97, 91,172, 71, 90,153, 56,196,212,157,215, 12,189,150, 49,171,207,107,187, -204,249,175,202,188, 86,145,193,163,224, 5, 39,175,194,254, 25,220, 11,158, 55,228,217,148, 43,255,111,148,153,220,218,165, 96, -114, 75,199, 29, 38,150,142, 59, 77,210,184,148,144,129,133, 78,253,180,181,181, 77,193, 43, 67,148, 47, 80,160, 64,155, 82,165, - 74,117,205,153, 51,103,107, 39, 39,167,178, 44, 55,241,239,234, 59,248,253,211,207, 52,189,251, 23, 36,252,175,175,142,166,233, - 60, 70,240,123, 58,242, 91,242, 24,241,167,180,187,137,141,187, 19,151,127, 82,234,244, 94,103, 83,164,203, 28,107,122, 27, 57, -132,144,231,139, 44,107,109,109, 93, 93,153,240, 91, 31, 22, 63,185,238, 6,220,254,143,203,106, 84,139, 86,162, 36, 38, 41,207, - 52,107,223,251,147,127,192,123,234, 59,122, 33,153,152, 90, 92,215, 82,229,223,222, 65, 88,185,228, 59,111,147,169,160,191,106, -194, 49, 57, 74, 40,167, 25, 61, 50,166,104,185, 98,118,187, 71, 81,239, 55, 81,201, 66, 25,182, 24,162,132,252,128, 92, 62,118, -229, 37, 13,159,178,130,156,178,250, 4,242,116, 15,131,204, 28,178, 90, 24,250,242, 49,179,118,117, 73,227, 82,224,121,181, 30, - 43, 34,237,189,203, 5,240, 87, 87,118, 57,101,143,206,163,171,141,172, 51,101,202, 84,201,221,221,189, 25,175,197,216, 26, 9, -255,227, 24, 95,171,105,242, 83,229,109,117,182,123, 74,107,143,198, 11,150,173,227, 37,115, 66,121, 34,209,215, 84,187,213, 96, -146, 65,182,100,235,146,133,133,179,153,133, 83,238, 23,190,179,118, 69,156,189,245,150, 14, 92,244,167, 30,147,119, 69,165,115, -205,255, 78,141,108,125, 39,211,190, 84,239, 85,115,183, 95, 9,196, 94, 19,134,222,117, 38,214,156,185,245,230, 69,236,229,232, -188, 69,198,194,123,172, 61, 74,221,182,241, 44,115,219,214,171,204,109,123,239,178,183, 29,179,149,187,157, 49,123,185,219,246, - 89,124,246,200,108, 39,217,117,151, 41, 15,217, 98,201,228, 21, 24, 94,165,118, 46, 20,110,238, 82, 56, 60,141,107,145,112,171, - 76, 69,194,173, 51,251,132,219,184,251,132,167,207, 92, 68,238, 18, 91,250,202,105,238,237,102, 81,164,125,139, 42,247,178, 20, -109,246,202,161,104,215,249,142, 62,221,115,232, 41,115,140,204, 76, 57, 74,188,184,245,236, 35, 57,121, 21,249,154, 46,107,181, - 35,114,146,107,246,146, 95,191, 93, 83, 88,117,141, 83, 61,250,233, 94,134,167,134,121,205, 83,195,188,199, 51,153, 42,173,187, - 27,151, 81,223, 52, 44,223,201, 76,145,206,227, 63,238,152,231,200, 77,200,255, 35,239,165,196, 38,102,165,146,167,182,218,225, -149,183,212, 43,115, 43,135,109,137, 77,204,139,105,192, 86, 95, 27, 41,146, 91, 56,110, 62,113,237, 77,212,153,219, 31,200,194, -222, 93,142,142,234,148,201,196,170,225,201,147, 39,135,240,188,193, 82, 10, 15, 15, 31,178,114,229,202, 33,252, 46,209, 53, 85, -142,190,114,218, 51, 57, 40,148, 33, 67,134,186, 72,248,159,235,106, 47, 71,151, 76,109, 92,173,184, 77,194, 47,222,125, 77, 72, -166, 54,238,145,142, 69, 58,142,119, 46,217,111,168,166,148,161,112,135,137, 76,174,162,174, 61,122, 79, 72,124,109,132,138,101, - 75, 95, 57, 13,120, 36, 99,178,234,149,153, 60,157, 71,254,148,233, 60,214,149,170,211, 57,114,193,230,243,116,246,102, 0,153, -219,103, 61,105,104,223, 1,130,245,232,209,163,222, 79,158, 60,233,247,224,193,131,174,248,109, 64,129,191, 43,167,157,123,193, -147,246,238,133,159, 89,187,230, 25,204,114,212, 39,157,134,232, 68,230, 14,185, 6,155,103,204,247, 44,181, 99, 30, 93,229, 53, -160, 24,127, 97, 86,182,100,245,104,218,174,215,167, 43, 15, 62, 80,221,254, 27, 41,165,153, 85,128,161,141,251,131,176,232, 85, - 66, 85,249, 32, 88,151, 31, 6,211,189, 23,161, 82,186,120, 63,136,112, 76,223, 11,141, 21,225, 48,207,216,238,159, 38, 58,153, - 59,228, 12, 74,235, 82,192,223, 10,137,231,147,194,156, 82,158, 69, 27,172, 4,185, 2,201, 90, 58,179,237, 83, 87,135,228, 93, - 85,228,234, 45, 39,136,214,113, 94,222,232,192,165, 55,116,134, 23, 90,158,186,104, 43,121,230, 45,247, 41,165,141,251, 68, 13, - 75,250,124,215, 57,226, 64,138,244,153,115, 91,187, 21,126,211,110,226, 97,106, 54,249, 42,205,219,126,135, 26,182, 27,252,161, -104,197, 70,239, 29, 61,125, 94, 56,120, 21,221,107,154, 62,147,135, 1,109,148, 40, 85,170, 84,153,249, 43,180, 94,133, 10, 21, -154, 31, 58,116,168, 53,191, 28, 99, 37, 28,195, 57,228, 65, 94, 60, 60,250,240, 84, 61,239,154,173,232,217, 15, 31,191, 80,174, -178,255, 81,246,210, 45,105,214,230, 27,148,202,206,243,160,156,151,164, 28,221, 49,181,207, 49,173,219,232, 53,225, 88,234,167, - 34, 47,227, 84,155,151, 59, 90,184,231, 17,245,157,186, 35,202,202, 37,239, 17, 77,109, 4, 11, 22,200, 85,133,250, 93,200,255, -221, 71,194, 30,191, 85, 45, 91,174,229, 59,165,206, 91,179,207,203, 45,199,238, 68, 98,143,223,250, 58, 50,144,172, 3, 23,249, -133,126, 63,144,174,242,242, 67, 55,120, 46,177, 59,207, 67,232, 50, 63, 63,110,185,203,223,150, 83, 31,206,163, 79,151, 18,225, -107,214, 52, 93,230,205, 72,209, 95,182,234,109,162,126,171, 88, 50,205,156,139,132, 31,187,246,134,238, 60, 11, 33, 76, 44,251, -200,255, 35, 61,229,149, 32,142, 94,125, 67,174,121, 42, 97,101, 1, 57,155,182,114, 90, 87, 40,156,174,210,225, 25,197,102,124, - 57, 86,243,196,146, 49,181,222, 44,223,176,135, 38, 45, 63, 30,158,167,230,208,143, 14, 62,221, 14,100, 40,210, 69,219,151,116, -140, 76, 88,167, 28,189,124, 62, 58,101, 47, 79, 87, 31,125, 32,204,203,134, 37,157, 46,220, 11,148, 22,108, 63,115,251, 29,157, -149,210,123, 58,207,171, 87,156,227,125,182, 34,213, 9,215, 24, 98,209, 2,201, 58,118,237, 61,237,187,248,150,202,240,218,158, - 5,171,247,160,116,153, 11, 63,100, 92,171, 26,240, 28, 41, 64,176,222,135,132,209,244, 85, 71, 25,199,183, 60,135,220, 27,218, -127, 49,128,158,243, 10, 9, 99, 23, 31,164,237,103, 94,209,150, 83, 47,121,133,141, 23,116,147,215, 0, 69,126, 67,158, 35,213, -188,137, 77, 82, 15, 46, 85,171, 35, 77, 93,119,145,214, 28,121, 78,235, 14, 63,162, 86, 61, 70, 80,226,228,102, 61, 13,149,153, -220,220,126,187,146,104,153,219,186, 29,144,209,240, 58,245,179,114,229,202,221, 64,174,148, 68,235,243,231,207, 67, 78,159, 62, - 61,196,212,212,116,160, 33,120, 70,231, 77,201,239,157,186,252,209,215,249,249,243,231, 61, 34, 35, 35,165,132,255,231,207,159, -223, 25,231, 56, 95, 74, 45,114,165,114,226,221,202,239,222, 40, 16,112,164,148, 54, 30, 52,125,237,185,253,235,143,191,216,174, - 41,205,220,232,183, 15,121, 98,242,243,181,152,132, 58,250, 30,223,213,157,173, 66,165,211,165, 75, 87, 85, 83,178,176,117, 27, - 99,238,152,247, 45,247, 45,111, 44, 93, 56, 57,230,186,161,239, 29,162,122,158,203,157,213,220,193,251, 68,203,222, 83,104,239, -217,199, 76,252, 62,208,164,101, 71, 40, 71,137, 70, 97,166,214,134, 19, 87, 16,171,167, 79,159,246, 63,127,254,124,125, 38, 90, -221,127,148,104, 57,100, 41,228,143,245,108,167, 47,218,252,201,201,187,248, 43,219,204, 69,158,218,184, 21,126,154,142,147,149, -107,161,167,142,222, 37, 95,181, 26, 48,239, 19, 38,171,150,187,142,177, 12,253,251, 83,178, 24,205,101,168,224, 47,166,115,247, - 31, 61,165,166,195,119,127, 71,178, 76,205, 44,176,176,178,234,166,175,131,136,201,155,202,218,189, 32,155, 63,151,154,217,103, -219,104,238,144,125, 71,106, 59,239, 89, 41,210,102, 86,159, 29, 28,249,101,203, 68,102,144, 42,144,171,209,235, 30,198, 36, 57, - 68,203,194, 41,223,139,157,103, 95,210, 5, 94,163, 16,179,153,179,165,136, 95,148, 1,116,253,113, 16, 47, 35,243,142,234,180, -238, 31, 84,190,180,247, 1,247,140, 41,151,148, 44,236,180,199,209, 54,249, 56,190,157,242,225,147, 85, 78, 16,173,253,220, 9, -111, 56,254,130,182,158,126, 69,123,206,191,162, 93, 39,238,209,236, 21,123, 40, 95,201, 90,225,252,197,178, 48,185,173,167,131, - 10,160,177,234,158, 50,189,119, 57, 91,207, 18,239, 59, 78, 59, 77,165, 7,156,231,117, 13,253,168,215,162,123,180,237,236, 91, -126,113,127,162,167,111,190,210,225,243, 15, 40, 87,177, 26,111, 97,245,210,245,242, 81,158,203,152, 49, 99,157,206,157, 59, 55, -231, 47, 28,137, 92, 45, 90,177,118, 84,145,178,181,175, 59,103, 45, 18,156,209,171,112,112,129,146, 53,175,227, 24,206, 33, 79, -135, 14, 29,154,166, 79,159, 94,253,203, 84,103, 27,101,244,246, 57,251,138,173, 89,217, 75,181,160,172, 37, 90,144,239,226, 11, -134, 18,173, 4,246,246,246,201,185,204,170, 86, 6,252, 47, 37,158, 12,246,238,206,211,143,165,165,125,176,102,102,221,145,103, -104,192,146,235,180,145,103,164, 79,227,148, 19,147,161, 42,183,152,114,194, 93, 8, 75, 22, 72, 22, 54,236,241, 27,199,225, 38, -132, 5,171, 96,173, 30, 47, 7,140, 93, 64, 33,159,190, 82,255, 49, 11,168, 16,255,198,113,184, 19,181,181, 81,122,182,100, 93, - 98,146,213,145,151,149,234,179,240, 26, 13, 95,117,139, 23,211,190, 71,243,121,241,116,247,188, 21,126,136,104, 65, 55,248,107, -124,168,153,157,215,243,182,221,135,209,241,243,183,163,142, 95,188, 27,213,169,255, 4,178,112,200,246, 2,231,212,244, 71,235, -179,105,206, 86,172, 59,188,188, 22,150,134,106, 60,246,156,180, 12, 86,255,197,215,121,169,173, 0,202,156, 47,206, 68,203,178, -109, 53,215,198,151,151,149, 94,252,245,104,141, 83,103, 22,148,152,215,176,140, 67, 45,219, 60,205, 78, 96,249,174, 89,219, 31, -208,246,211, 47,105,214,134,243, 81,197,154,140, 39,219,188, 45,110, 90,103,175, 83, 77,215, 59,196,190, 64,237,228,214, 94,213, -238, 46,221,117, 77,194,177,197, 68, 63,105, 17,250, 1, 92,214,209,188,150,229,244,173,247,105,241,190, 39,210, 51, 53,117,213, -113,178,207, 81,235,152,162, 88, 49,117, 23,149,110,139, 22, 19,173,189, 23,222, 72,239,139, 54,227,246,211,208, 21, 55,169,255, -130, 75, 84,162,254, 0,210,178, 86,170,198,231, 29,196, 9, 36,139,159,243,243, 74,171, 22,254, 7,201, 82, 63, 54,100,206,190, - 56, 19, 45, 38, 89, 3,203, 54,232, 75, 35,151,156,163,225,179,119, 81,157,255,250,208,162, 45,231,233,232,141, 16,234, 61, 98, - 46,177,165,171,164, 38,253, 76,149, 62, 75,145,194,101,107, 63,169,215,162, 43,213,105,214,149,106, 53,237, 66, 53,155,116,161, - 50,213,154, 82,193,146,213, 40,127,137,170, 84,188,114, 99,170, 80,175, 35,149,175,219,129,202,214,110, 79, 57,139,215, 14,129, - 53,197,144,247, 60,187, 11, 59,190,120,241, 98,200,246,237,219,135,140, 31, 63,126, 72,147, 38, 77,134,240,135,218, 16,126,134, -187,232,232, 33, 53,181,145, 89,246,236,217,219,191,123,247,174, 7, 63,162, 49,233,203,151, 47, 61,130,131,131,123,240, 26,181, - 61,152, 52,244,240,246,246,198,178,104,102, 26,100,199,200, 76,109,227, 49, 43,157,107,110, 66,178,202, 92,242,190, 91,185,129, -147,116, 37, 43,247, 82,119, 45, 29,178,147,101,134,108,220, 78,153, 39,107,123,222,113, 28,100,229,225,195,135,189, 96, 37, 82, - 38,182, 26,245,235, 53,104,244,242,108, 69,235,125,218,125,238, 57,157,226, 15,235, 45,167, 94, 80, 90,231,124,129,186,202,169, -122,142,151,123,171, 88,166,102,219,240, 51,215, 95,208, 13,238,135, 38,173,185, 64,110, 5,106,127, 98,111,192,176,148,214, 94, -233,116, 96,169,181, 63, 82, 35, 90,221,140, 65,180,240,254,124,201,235, 22,135, 71, 68,209,199,207,225,132,165,215,238,189, 8, -145,150,239, 59,115,235, 29, 45,224,143,222,173,252,220, 27, 74,180, 88,108, 94, 78,149,176, 71,133, 84,127,171,252, 47,157, 87, -251,157,143,127,231,143,190,182,116,244, 30,249,144,148,191,181, 29, 71, 30, 92,159, 82, 69,102,121,254,223, 82, 3,222,218, 93, -135,172,252,164,122,129,250,111,117, 97, 22,105,109, 95,248,243,226,192, 77,134,237, 38, 83,115,235, 24,107, 86,186,244,246,111, -151,175,222, 64,102, 22,105, 30,235,105,240, 88,167,209, 17,164,178,243,222, 80,185,110,155,144, 93, 71,175,132, 60,122,241,254, -235,253,167,111,190,108,218,119, 38,164, 74,221,214,159,204, 50,120, 99, 17,104, 77, 38, 72, 89,183,145,233, 58,252, 78, 22,207, -128,254,226,212,205,119,188, 0,180, 31,181,156,236, 71, 25,188,203, 74, 86, 9,188,208,235,117, 24,250, 97,249,236, 14,207, 97, -201, 42, 86,192,254, 0,127,185,180, 98, 1, 88,115,208,160, 13, 68,107, 27,127,213,174, 56,248,148, 86, 31,126, 66,141,186, 77, -167,149, 59,206,127,251, 90,127, 26, 66, 75, 55, 29,199, 11,121,191, 38,161,201,109,220,242,218,120,148, 12,234, 52,227, 2,249, -244, 57, 75, 37,250,159,167, 86,211,111,210,152, 13, 79,104,253,201,119,180,211,239,131,148,118,156,127, 79, 75,118, 92, 35,254, -170,224, 78,221, 51,169,190, 2,242,131,214,152,191,110, 90,223,191,127,191, 89,131,255, 58,175, 46, 94,161,222,231,107,183, 31, - 82, 64,224, 39,122,244, 50,152,214,239,245,163,172,133, 42,127,174,214,176,237,170,203,151, 47,215,217,177, 99, 71,235, 52,105, -210,232, 90, 26,232,187, 91,194,117, 56,114,202, 18, 58,124,217,159,102,109,185, 73,185,202,119,144,227, 58,140, 37,167, 95,191, -126,105,216,245,224,150, 50,101, 74,188, 96, 98, 72, 22,255,159,200,204, 33,215,195,133, 59,110, 80, 27, 94,188, 27, 11, 86,119, -157,115,133,166,109,185, 79,219, 78, 61, 35,171,140,185,222,107,194, 64,151, 69, 11, 49, 89,112, 23,110, 57,118, 59, 18, 36, 11, - 27,246, 91,249, 55,142,227,188, 54, 92,237,178,150,189,125,237, 81,144, 68, 90,114,148,108,234,159, 41, 87,249,219,110,121, 42, -220, 6,201,202,232, 93, 92,142, 91, 70,163,104,214,139,190, 69,202,215,139, 92,181,121, 63, 61,125, 29, 28,133,117, 66, 47,177, -149,236,226,253, 15,244,224,213, 71,186,253, 52, 40,106,223,233,187, 84,181, 81,247, 72, 83,235, 44,190,250,218,221, 50,147, 79, - 56, 94,134, 13,199,156,149,214,159,236,203,164, 16,196,101, 7,235,167,123,254, 74,100,225,152,235,131,165, 83,174, 15,105,156, - 52,126,129,107, 20,159,198, 49,235, 69,231,172,133,190,212,169,152,235, 80,238,236, 54,136, 29, 76,131,140, 14, 69,187,109, 95, -115,228,153,180, 72,249, 84, 94,104,125,226,170,115,180,108,205,122, 58,177,125, 2, 85,168, 94, 63, 56,186, 61,181, 22, 57,173, -119,141,156,217,203,117,140, 56,112,225, 21,245, 95,116, 93, 42,235, 8, 38,176, 83, 55,223,103,203,229, 99, 90,203, 75, 69, 45, -219,125,131,220,138, 52,121,105,147,163,182,149,190,186,171,159,103,253, 44,205, 86,173,183,236, 58, 12,225,248,190,155,238, 5, -171,127,234, 56,102, 43,141, 98, 60,138,214,238, 25,197, 31, 64,165,228,200, 4,185,130, 37, 75,213, 82,133,255, 97,201, 82, 63, -182,242,208, 51, 77, 68, 75,235,109,146, 36, 79,221, 49,157,189,235,171, 98,229,235, 68,185,231,171, 66,181, 59,207,164,255,250, -205,161,228,230,214,203,146, 37, 51,115,177, 76,231,180,102,217,142,139,180,143, 9, 99, 90, 91,103,141, 86, 41, 46,195,220,251, -207, 2,121, 13,219,207,108,197, 12,149, 44, 54, 87, 31, 5, 75, 22,194,125,103, 30,208, 78,254,232, 59,196,107,218,238,187, 16, - 64, 59,207,249, 75,214,183, 53,135,159,178,139,202,123,153,182,130,217,103, 41,182,199, 57, 39,187,198, 57, 57,177,123,220, 49, - 91,217,219,206,158, 69,238,194,154, 5,178,181,127,255,254, 33,211,167, 79, 31, 50,117,234,212, 33,214, 25,115,223,179, 98,139, -175,149,123,201,219,105, 51,151,188, 13, 55,187, 46, 92,249,131,174,177, 58,201, 2,185,122,253,250,117,143,245,155,183, 15, 47, - 91,189,137, 95,166, 28,197, 63,184,240,186,185,169,211,185,110,211,215, 70, 25, 10,180,154, 51,101,197,137, 67,206,165,250, 96, -229, 8,157, 27,242,204, 92,127,254, 64,134,194,109,103,234,203,171, 36, 47,126,126,126, 13,148,169,105,155,238,147,189,124,234, -124, 60,112,225, 37,141, 89,123, 91, 90,239,118, 15, 91,220,217, 75,162,137,104,125,119, 11,184, 59,179, 21,169,242,225,222,115, -126,167,159,125, 69,141,134,238,163,244, 57,106, 28, 85,112,252,155,190,242,232, 58,175, 70,180, 12,117, 29,126, 39, 26, 22, 45, -188, 31,209,167,205,222,241,144, 38,111,188, 75,227,120, 61,100,124,232,182,156,124, 65, 90,223,183, 92,255,227,180,250,200, 83, -141, 68, 75, 23, 31, 1, 49,226, 27, 66,124, 12, 65, 82,249, 45,157,211,244,187,111,223,190,253, 84,175, 85,230, 83,230, 85,221, -171,202, 80,254, 31,125,125, 69,236,113,172, 96,193,130,171, 88, 30,194, 9,212, 55,237, 22, 45, 84, 76, 89, 57,213,255,181, 52, -142,107, 74,179,180,239, 62,127,141,148,190,242, 58,141,219, 65,169, 45,211,189, 78,151,222,238,237,133, 75, 87,105,239,153, 71, -100,145,198, 90, 91,188,214,119, 34, 83, 89,103, 46,196, 22,134,192, 37, 27, 15, 7,126, 13,143,140,188,251,242,203,135,205,167, -223, 63, 89,126,228,205,131,125,151, 63, 60,191,250,224,125, 80,131, 54,253,130, 82,217,120,245,210,166, 44,230, 25,243,156, 87, -186,247,164, 61,187,246, 44, 51,230, 85,143,193, 50, 88, 23, 65,180,246, 94,240,167,182,211, 46, 74, 29,143, 67,182,178,116,156, - 93, 43,131,151,221,240, 47, 91, 34,203,129,104,119,225,243,162,133,178,110,226,206,190,171,193, 55,224, 11, 64,180,208, 41,128, -225,119, 25,189,158,230,175, 59, 76,143, 95,135,242,215, 74,176,228,250, 56,126,237, 45,136,214,101, 77,178, 83,217,185,167, 73, -231,230,227,223,113,250, 57, 26,191,241, 17, 45, 59,244,146, 14, 92,102,235, 27, 47,158,124,248, 90,176, 68,178, 54, 48,225, 26, -191,233, 25, 13, 90,241,128,202,182,158, 22,238, 85,172,113, 84, 26,199, 60, 27,245, 60,120,141,207,156, 57,211,122,224,208,209, -163,138,150,171,243,249,227,231, 48,122,232, 31,202,110,148, 0, 90,206, 15,207,242, 3, 79,105,195,209, 39,228,146,179,236,231, -174,189, 7,142,138, 11,209,194,253,189, 11, 86, 12,189,250, 32,136,218,245, 29,143, 47, 68,213,224, 82, 57, 80, 38, 92,183,110, -157, 25,127, 37,218,180,106,213, 42, 15,191, 44, 10,240, 69,201, 56, 37,180,176,176,200, 90,160, 84,205,141,117, 58,140, 15, 91, -118,224, 9,141, 92,125,139,102,110,227, 78,227,172, 63, 13, 24,191, 36,204,222, 61,255, 6, 93, 55, 80,198,104,101, 40,221,119, -211,208,213,183, 70, 21,108,187,201, 26, 22, 43, 88,174,242,213,234, 19,203,162, 5, 11, 23,142,235, 8,140, 87,176,222,220,190, -197,166,244, 49,107,239, 80, 38,249,174, 66,189, 24,176, 94,220,250,244,133,191, 22, 3, 62,209,201, 27,239,104,221,177,231,252, -242,122,198, 86,209,215,116,142,117,103, 47,147,172,198,237, 7, 82,122,183,252,100,154,222, 75,215,128, 21,233, 94,105,221,124, -194, 31, 50, 65,107, 59,245, 34,245, 94,112,141,113,131,117,232, 1,109, 62,249,130,170, 55,233, 70,199,206,223, 37,212, 35,109, -198,220, 31,244, 22, 46, 58, 67,198, 92,149,233,236,213,199, 52,102,246, 70,178,206, 92,252, 35,127, 80,141, 74,109,239,105,201, -174,194,117, 75,246, 61,166,126,115, 79,147,239,180,181,180,123,211,116, 58,183,119, 10,173, 93,183,138,236,243,183,138,245,225, -167,237, 94, 86, 89,171,247,109, 51,100,133, 84, 62,188,139, 38,109,188,199, 11,149, 63,162, 85,135,159,209,166, 99, 79, 40, 95, -149, 78, 97,105,179, 86,203, 37,183,172,186,242, 97,160,137,153,109,214,221, 61,167,236,166, 49,171,175, 51,233,204,121, 72,142, - 92,144, 41,184, 11,213, 73, 21, 8,139,250, 49, 60, 87, 26, 92,135, 26,111,195, 94,133,169,125, 70,206,165, 67, 87, 3, 37,171, - 21,158,251,182,125,167, 82,178, 84,105,225,134,138,254, 40,181, 76, 93,177,110,171, 40,156, 47, 81,177,254, 71, 77,130, 82,216, -122,228, 44, 88,166, 78, 80,141, 38,157,169, 90,163,206, 84,165, 97, 39,170,220,160, 35,245, 26, 62,135,142, 48, 65,236, 62,108, - 30,149, 97, 43, 86,169, 90,237,169,100,205,118, 84,188,122, 91,202, 94,180,214, 75,126, 94,181, 6,200,187,240,135, 4,220,205, - 8,137,128, 53,116,215,121,127,202,156,167,252,151, 54, 93,250, 29,216,182,107,239,228,189,123,247,250,118,239,217,111,106,254, -226, 85,142,164,117, 43,254,181,207,194,171,212,121,230, 37,106, 50,238, 28,165, 97,178,165, 13, 87, 14,206, 47, 88,176,114,251, - 35,181,219,143, 62,211,184,211,216, 99,227,102,174, 94,124,238,226,245,161, 32, 89, 29,186, 13, 90,231, 93,160, 66,232,200, 25, - 27,163, 86,241,242, 94,124,255, 40,182,192, 63, 77,153,198, 65,231,252,130, 32, 79,155, 79, 5,108, 87, 18,173, 20, 54,238, 27, -241,190, 85, 77, 56,134, 50,169,231,213,243, 14,141,113,199,193, 37,215,184,117,183, 73, 32, 89,251,163, 73, 86, 29,182,176, 55, - 25,127,142,182,177, 85,135,195, 80,100, 17, 45,118, 91, 15, 92,183,235,148,228, 26,239, 49,247, 10,101,171,212, 55,202,210,181, -188, 61, 62, 90,241, 49,206,233, 49,246,108,221,170,165, 80,124,103,193,213, 90, 92, 85,162,117,239,222, 61,137,104,193,251, 97, -106,235,213,217, 34, 99,254, 53,150,206,249,110,164,201,152,239, 85, 26,153,125,106, 6, 21,162, 53,126,193, 46,178,114,206, 77, -171, 14, 61,165, 46,179, 47, 83,207, 9,155,249,253,145, 75,250,128, 67, 40,135, 38,139,150, 46, 62,162, 36, 75, 92, 25,137,108, - 97,175,250,191,210, 82,165,126, 76,219,111,109,249,245,201,137, 62,111, 39,231, 29, 16,147, 71,149,100,225,160, 14,139,150,187, -181,173,211,187, 83,103, 47,208,139,183,159,105, 28,127,141, 78,216,112,151, 38,173, 60, 77,183,239,222,151, 30,172,166,237,250, -190, 53, 49, 49,209,229,119,143,185, 47,204,207,233, 92,243,124, 56,113,249,217, 7,255,192,176, 79, 11, 15, 6,220,107, 63,239, -177,159, 50, 53, 28,113,228,218,160,233, 59,253, 55,238, 61, 31, 98,237,154,239,133,182, 74,129, 92,193, 13,129, 56,152,131,252, -245,133, 23, 47, 98,169, 12, 2, 65, 67,102, 75,167, 60,254,246, 89,203, 74,150, 44,144, 44, 51, 59,111, 42, 82,161,246,167,255, -187, 11, 51,238,207,157,205,121,219,132, 9, 19,250,178, 69, 71,206,132,161,223,221, 5, 15,244, 82,118,115,204, 96, 34, 80,241, -191, 81,244,248,101,144,132,237,109,142,147,193, 87, 37,190, 38,181, 17, 45, 8, 75,149,222,187,136,153, 83,222,219, 89,242, 87, -126,155,175, 84,221, 55,165,170, 54,125,219,173,223,168,224,117,219,142,126,245,187,199,166,229, 45,207,168,227,156, 59, 84,126, -208, 89,170, 58,248, 4,141, 92,123,159,220, 11, 84,131, 69, 71,171,133, 16, 22, 45, 16,173,188,197,170, 92,191,122,235,129, 20, -175,179,141,221,154,115,119, 62,164, 33,203,111, 82,107,182, 18,245,152,119,149, 90, 12,221, 72,174, 57,202, 92,143, 43,209, 98, -171,192,218,173, 71,111,209,220,245,199,152, 8,100, 57,134, 0,118, 3,218, 44, 1,187, 7,172,119,237,218,101,207,110, 3,183, - 69,139, 22, 21, 69, 60, 4, 95,111,195,129,183,117,130,130, 66,218,187,100, 47,249,172, 78,187,145, 95,103,172,229,248, 44,118, -163,116, 30, 56,229, 43,187, 9, 94, 96, 52,162,174,251, 40, 71, 29,230,106, 62,163,223,164, 77,215, 15,251,180, 95, 24,211,182, -136,201, 42,192,228, 10,150,173,124,181,122,107,139,209,138, 37, 30, 65,239,247, 95,124,148,220,100,153,217,146, 37,181,155, 93, -246,187,169,236,115,124, 64, 74,157, 33,199, 7,179, 12, 57, 63,112, 12,224, 7, 11, 78,150,142, 57, 53,197,108,104,208, 29,143, -155, 48,203,195,218,176,145, 99,124, 64, 42, 15, 95,121, 75,107,247, 94,162, 42,141,187,144,157,123, 1,106,209,125, 12,109, 58, -122,159,210, 56,230,188,167, 15, 91,107,247,162,225, 32,249,189,230, 95,165,225, 43,111, 73, 22,192, 37,251,159,240,243,244,146, -138,213,232, 72,157, 39, 29,144,220,114,252,226,252,160, 79,150,242,124,182, 98,245,104,239,137,155, 52,110,225,126, 10, 10,249, - 68,171,183, 30, 34,151,220,149,195, 45, 92,139,223,239, 63,126, 25, 45, 91, 50,141, 78,238,156, 64,115, 22,204,167, 97,243, 14, -210,250, 35, 79,200,193,167,171, 44,162,165, 80,248, 38, 76,151,173,218,201, 5, 91, 47,211, 82, 46, 39,190,158,241, 33, 0, 18, - 83,181,229, 72, 98,247,162, 65, 86, 86,125,117, 50, 73,231,230, 92,186, 94, 15, 94,240,254, 33,121, 22,170, 46,171,115, 4,113, - 58,192, 31, 40,234,164, 10, 49, 89,234,199,150,240,123, 64, 14,209, 74,154,210,162, 95,255,177,139, 36,130, 53,102,246,102,170, -211,126,156, 20,163,179,237,108, 0, 53,104, 55,152, 18,167, 76,141,137,137, 21,112, 39, 14,155,182,134, 14, 95,253, 64,118, 25, - 61, 47,233,171,159,242,124, 10,171, 44, 57, 26,180, 31,194,214,150,215, 28, 30, 49,136, 64,198,228, 94,139,124, 32, 90,136,145, - 27,198, 58, 52,112,201, 13,137,180,183,238, 53, 57,168, 83,159,209, 97,249, 74,215, 13,205,144,165,200,103,143, 2, 53, 66, 11, -215,238, 23,238, 93,190, 71, 72,153,126,199,168, 88,207, 35,146,215, 64, 23,209,114,204, 90,250,200,166,163,247,222,108, 61,253, -226,205,242,253, 15,158,143, 93,114,244, 94,203,158,211, 46, 22,168,240, 95, 64,157,230, 61,190,238, 62,251, 76,138, 77,155,202, -122, 59,157,211,160, 25,219, 35,211,187, 23,220,167,171,236,234,228, 9,239,218,195,151, 3,194, 56,238, 47,252,196,141,183, 95, - 89,151, 62, 41,223,191,113, 37, 90, 49, 36,203,239,155, 37, 11, 97, 12, 77,199,159,167,214, 83, 47,208,122,254, 56,226, 88, 95, - 57,186,148,208,197,187,216,243, 23,111, 66,105,225,222,199, 18,166,153,124, 90,115,191,152,231, 99,217,186, 93,105,192,164,181, - 82,223, 55,123,245, 17,201,205,107,110,239,245,146,227,181,106,200,105, 55, 85,162,117,241,242,229, 30, 22, 25,178,109,243,224, - 62, 98,224,180,173, 81, 11,182, 94,160,237,167,240, 14,120, 65,136, 77,150, 35, 15, 68, 43, 50,138,164, 15,242, 52,142,217,208, -127,113, 12,242,107,201,189,111,233,240,237,247,178, 3,143,249,253,114, 79,167, 69, 75,157,151,224,222,234, 86, 41, 77,191,229, -228,129,168,111,226, 36,203, 88,140,149, 76,211,113, 28, 83,183,104, 69,255,214,246,177,161,234, 62,252, 63,100,178, 92,135, 73, -147,122, 88,217, 58, 5, 94,186,122,139, 6, 47,189, 65,165,251, 28,147,204,244,120,233, 44, 99, 64, 87,239,185, 74, 13, 91,245, -120,159,210,212,244, 50, 75,134,101, 65,231,150,194,198, 45, 79, 58,151, 60, 31,246,156,126,240,254,206,243,207, 31, 6,175,121, -126, 85,149,100,149,104, 49,245, 92, 42, 91,207,119,204,170, 87, 88,185,228, 57,151,154,215,194,211, 38, 16, 68,107,195,241,231, -212,128, 77,177,141,249,171,168,217,132,243, 70, 33, 90,105, 92,242,191, 56,124,229, 91, 76,150, 31,147,158, 82,213,154,132,170, -186, 11,203,149, 43,215,183, 75,151, 46,125, 16, 24,206,202, 42,135,104, 37,102, 50, 48,130,205,223, 15,121,104,243, 91,236, 45, -211, 57,190,158,185,245, 46,141, 95,127,151,138,213, 27,196, 36,235,147,228,219,126,192,228,230,248, 85,127,218,126,242,137, 78, -162,165, 17, 19, 87,215,100,214, 46,121,123,119,232, 63, 41,120,244,250, 71, 84, 97, 48, 72,214,113, 38, 89, 15,168,100,179,241, - 81, 28,104,223, 84, 87,227, 40,137,150, 99,150, 66,193,254,239, 66, 37,151, 1, 72,194, 32,110,247,150,147,252,168,194,192, 19, - 84,184,251, 97,234, 56,237, 12,241, 87, 78,112, 92,137, 22,143,226,169,219,174,223,100,201, 12,222,127,210,122, 74,151, 41,223, - 35,254, 26, 43,174, 79,119, 84,206, 39,202,154, 53,171, 59,147,194, 44, 97, 97, 97,121, 46, 92,184, 80,142,135,144,215,190,126, -253,122,211,136,136,136,102,193,193, 31,155,214,105,218,113, 51, 91,206, 30,243,180, 0, 79,108, 92,114,207,150, 77,230, 60,125, -147,150,105, 55,107,247,210,189, 55,223, 98,175,224,223,202,251,202, 24,117, 24,171, 10,232,120, 16, 0, 15, 83,186, 71,190, 74, -223,136,150,173,247, 71,232, 44,130,207, 79,179,123,250, 60, 7,114,227, 67, 97, 53, 91, 99,224,158,147,131, 1,191,176,174,127, -248, 24, 38, 17, 11, 60,131, 32, 90, 91,143,221, 34,103,239,226,212,113,224,116,218,198,186, 3,162,212,111,209, 53, 74,101,155, - 85,235,243,163,188,151,141, 71,241,112,148, 19, 86, 43,238,100,216, 50,230, 47,197, 81,128, 40,148,174,211,153,250,207, 62, 34, -221,131, 93,175,159,248, 26,233,101,146, 36, 73, 18,157,100,198,187,104, 93,186,247,244, 61,109, 62,124,155,220, 43, 14,163, 78, - 35,215,209,167,207, 95,105,215,161,115,228,150,171, 52,205,156, 51,157,186,142,223, 74,195,151, 93,145,226,173, 96,141,114,240, -233,242, 89, 78,253,145, 39,189, 71, 13,199,220,149, 58,127,218,117,238, 37, 47, 84,254, 84, 34,156,157,134, 45, 37, 43,175,106, - 83,228,202,144,155, 15, 49,164,181,218, 12, 35, 16, 34,215, 60,229,101,117, 58, 32, 78,123,153,176,168,199, 99,173, 63,246,226, -187, 99,112,121,234, 35, 90, 28,216,222,183,187,239,116,137,100,245, 31,179,136, 92,115,149,137,104, 50,112, 45,199, 77,213,165, - 46,163, 86,209,108,118,195,155,167,115,218,135, 0,248,246,125,198,127,203,199,164, 44,145, 73,234, 70,178,235,105,235,185,120, -225,150, 11, 18,193,158,177,238, 28,165,178,241, 92, 44,247, 90,228,131,190, 99, 96,130, 42,209,106,217,107,234,187, 71,108, 21, - 63,115,235, 61, 33, 84, 98,230,182,251,252,177,118,133, 92,138,119, 14,150, 75,180,120, 84,246,167,119, 65, 95,194,107, 14,216, -249,160,219,156, 75, 55,122, 79,217,253,168,112,213,206, 95, 22,174, 63, 22,121, 4, 31, 24,236, 25,192,199,193, 64,118, 81,193, -122,130,247,106, 90,215, 66, 26, 45,121,202,250,104, 34, 90,120,223,183, 99, 47, 70, 95,126,110,224,226,141, 43,209,122,252,248, -113,127,117, 75, 22,194, 24, 64,178,218, 48,201, 66, 25,241,188,167,203,164,159,104,165, 72,231, 94,121,210,188,117,244,240, 85, - 40,141,101,203, 56,194, 16, 10,215,236, 75, 13,187, 76,166,175,225, 17, 82,106,210,125, 26, 29,187, 30, 40,165,173,199, 30,160, -220, 79,228,180, 27,136, 22,202,234, 59, 98, 92,223, 2,165,235, 6, 14,156,186, 41, 2, 1,246, 75,247, 63,150, 44, 79,125, 24, -135,110,108, 65,195,224, 47, 57,242, 64,180,216, 59, 37,189, 43,182,159,126, 74, 7, 47,190,148,234,217,137,173,150,179,182,222, -166, 21,251, 31, 72, 70, 26,144, 78,109, 22, 45,213,251,168,242, 19, 53,215,225,119, 36, 73,159, 37,138,229,198, 88,194,162,243, - 74, 49, 95, 26,142,107,149,173,150, 95, 29, 18,237,139, 74,235, 35, 90, 73,147,154,102,177,178,205, 24,116,241,202, 77,238,108, -175, 83,161,174, 71,104,202,166, 7, 52, 98,193, 33,142,199,178,122,107,110,145,246,133,101,218,116,215, 83,164, 48, 29,202,119, -213, 27, 3,148, 34,189,123, 46,107,231, 60, 31, 54, 28,188,249,246,194,195,143,111, 7,174,122,126, 69,149,100,181,153,125,239, - 2, 72, 22, 98,144,228, 52, 44,155, 55,223,231,106, 48,131,114, 53,152, 78, 57,234, 77,165,236,117, 38, 83,122,175, 50, 31, 49, - 50, 16,137, 71,119, 4, 65, 73,164,196,129,241, 72, 60,242, 76,175,107, 49, 45, 19, 45, 4, 49,227,171,140,211, 43, 85,119, 97, -190,156,153, 54,118,234,212,169, 15, 15, 81,110, 13,235,143, 12,162,149,200,198,198,230,194,140, 25, 51, 62,179, 5, 70,138,241, -225, 81, 56, 52, 99,230,204,200,108,121,139,210,176,229,215,169, 76,211,145,116,239,217, 7,122,204,163,189,206,223,124, 69,219, -142,223,167, 21,123,110, 25, 78,180,162, 65,179,117, 47,114,166,197,232, 67, 84,221, 23,150, 44, 38, 89,205, 39, 68,105, 24, 62, -254, 29,196, 74,162,229,224, 81, 48, 24,241, 0,112,199,224,193,110, 62,241,188,228, 91,207,214,118, 31,101,111,183,159,254, 27, -127,226,135,136, 22,223, 56,129,169,173,231,170,230, 61, 38, 75,157,215,216, 21,126,228, 85,184, 86,132,134, 64, 91, 93,106,144, -204,195,195, 35,255,165, 75,151, 10, 49,158, 62, 12,107, 77, 78,141, 57,213,229,212, 60, 36, 36,164, 13,147, 47,140, 66, 66,108, -144,190,225,249,210,125,156,138, 53, 51,201, 82,176,114,231, 86,189,198,208,201,171, 79, 8,251, 44,249,171, 78,181, 46,217, 69, - 10, 54,133,155, 16, 49, 89,106, 1,240, 90,203,232,224, 89,108, 15,226,177, 60,153,100,185, 68,199,100,177, 11,237, 35,220,208, - 37,251, 28,165,106,190,167, 36,183, 9,130,207,215,112,220, 2,199, 64,125,144,163,247,252, 34,189,246, 38,232, 11, 19,140,103, - 52, 39, 58, 22, 98, 55,187, 13, 15, 94,121, 67,139, 24,207, 22,108, 33, 40,208,229, 16,127,120,156, 99,139,161,247, 3,125, 50, -121,228,106,160, 75,158,202,145,110,249,170, 68,122, 20,168, 74,181, 57,160,186, 68,157,110, 84,174, 65, 15,170,216,180, 47,141, - 90,124,130,182, 50,169,227, 57,172, 62,177,187, 70, 26, 8,193, 50,117,142,178,201, 90,164, 14,189,230,120, 78,196, 27, 58,151, - 25, 44,165,224, 79,145, 20, 17, 73,148, 57,127, 13,234, 48,229, 20, 19,193,235,146,235, 15,241, 90,139,249,107,157,221,138, 26, - 99,232, 80,126, 7, 7,135,146,220,158, 85, 29, 29, 29, 99, 8, 57, 91,174, 26,117, 26,190,156, 45,123,175,105,244,194, 3,100, -147,157,227, 86, 84,130,223,153,140, 23, 40, 81,162, 68, 25,182,128,230,211,135,129,142,243, 9, 56, 94,107,221,164, 21,199, 49, - 58, 13,174,238,249,114,100,129, 56, 61,103, 11,245,152, 69, 7, 37,236, 54, 49,121,225, 81,109, 76,102, 67,104,240,172,125,146, - 5, 14,186, 15,146,133, 32, 97, 93, 68,139, 45, 85,101, 91,116, 25, 42,145,167,193,147, 86,144, 73,170, 52,203,210,102,240,184, -208,109,210, 94,106,214,127, 17,229, 96,178,213,119,198, 97,114,246, 44,240,185, 99,191, 9, 82,190,209,179, 55, 81, 74, 11,155, -165,114,117, 31, 46, 82,159,202, 45,194, 80,198, 69, 59,111, 75,157,101,254,114,205,195,112, 92, 78,125,145, 71, 19,209,106,209, -115,202,187, 91, 79, 63,210, 46,254,104,131,245, 30,174,175,234, 67, 79, 81,198,162,157,131,100, 19,173, 44,133, 63,135,133, 69, - 80,235,222,147, 35, 74,212,236, 30,222,162,219,184,136, 83, 87,159, 73, 46,206,117, 76,178, 96,109, 29,200, 31,131,176,184,215, - 31,125, 70,122,167, 90,102, 44, 16,170,171,220,154,136, 22, 62,126, 48,104, 5,174,126,124,196,196,149,104,245, 25, 50,102, 57, -220,133,251,216,146, 53,118,221,109, 41, 86, 20, 70, 0,184,230, 65,178,112,143, 21, 7,159, 48,209, 42,168,215,162,101,102,151, -117,255,195, 23,129, 92,215, 55,146, 23, 9,198,142,255,134,109,166,190, 19, 54, 82,145,154, 61,165, 52,126,209, 1,137,100, 45, -222,247,140,177, 61,141,114,203, 34, 70, 32, 90,215,111,222, 28,100,235,238, 19,112,226,202, 11, 30, 21,251,154, 58, 50, 41,194, -251, 30, 33, 51,221,185,173, 16,151,204,229,148, 37, 15, 68, 43,244, 75,132,100,101, 70, 91, 43,137, 33,100,130,100, 34, 70,171, -116,223, 99, 28,130,115,253,135,136, 22,218, 85,157,120,225,208,183,195,255,183, 84,225,183,166, 24,173,232,107,191,179,146,169, -202, 80,202, 82,221,171,200,211, 20,167,169,157,104,233, 82,196,164,166,150,158,214,182,206,193, 23, 46,131,108,252,159,100,141, - 95,113,134, 99,177,108,158,242,181,234, 19, 64,234,124, 30, 49,191, 83, 90,238, 72, 22,111,187, 24,112,252, 70,176,127,255,149, -207, 98,145, 44, 16,174,150,147,175, 93, 66, 16,170,220, 7, 27, 49, 89,240,117, 99, 4, 7, 72,214,174,115,175,216,141,249,230, -219, 87, 57, 7, 27,122, 84, 30, 33, 29, 67,220, 0, 30, 34, 12,249,151,163, 52, 32, 90,232, 12,235,182, 29, 16,172,238, 46,236, -216,177, 99, 95,144,172,221,187,119,183,190,122,245,106,107, 38, 81, 58, 45, 90,124,222,119,246,236,217,159, 36,134,165,182, 77, -157, 54,131,202,214,239, 78,141,250,175,164, 9, 11,119,115,124,214, 59, 58,116,254, 33, 49, 70,180,112,219,149, 56, 19, 45,126, -105,143, 44,223,122, 50,141, 92,243,128, 74,201, 36, 89,192, 92, 73,180,178, 23,174,116,125,245,206,243, 52,127,215, 67, 41,158, - 0, 15,135, 87,235,189,148,169,249,110, 42,205,230,254,210,237, 23, 27,228, 58,228,249,136,170,177, 53,109, 15, 91,173,234,168, -182, 45, 15,155,238,157,187,116,227,240,161, 75,206, 83,143,169,135,120,168,117, 22,189, 65,172, 42,215,131, 60,153,178,187,176, - 44, 19,216, 82, 76,182,202,177, 53,171, 10, 67, 92,159,127,183,201,147, 39, 15, 72, 22, 58, 9,101,176,188, 86,181, 42,210,124, -157,149, 79,187, 5, 77, 75,183,153,181, 23,228,106,245,246, 99, 82, 75, 97,143,223,165,219,206,220, 87,184,237,130, 22,249, 90, -174, 74,151,174,204,248,148,125, 22, 93, 30,104, 91,217, 55, 78,129,168,169,236,178,125,132, 37, 11,157, 13,176,197, 75, 8, 65, -221,203,185, 99,227, 24,134, 15,114,116,159, 95,164, 87, 95,190,251, 36,141, 94,156,200, 1,167,190,236,214,237,201, 47,197,134, - 60, 98,176,194,128, 19, 84,172,215, 81,202,223,229, 32, 91,122,207, 16,187,152, 31,202,145,169,204,131,192,247,227,126,247,168, -203,228, 67, 52, 96,206, 49, 26,179,244, 20,205,217,112,129, 93,147,111, 36,162,197,241,113,173, 97,201,229,252, 58,137,150,103, -161, 90, 52,131, 71,221,129, 96,221,121,142,233, 34, 62, 75,255, 15,227,145,113,153,242, 85,163, 50,109,230,190,234,196, 49,134, - 8,148,133,187, 18,238, 63,118, 29,106,141, 39, 99,139, 48, 8,116, 57,158,199,173,129,157,157, 93,109, 38, 94,181,144,236,179, - 20,249,232,145,183, 28,101,240, 42, 22,225,226,158,189,169,155,155, 91, 53,164,204,153, 51, 87, 45, 92,184,112,109, 92,195, 68, -171,178, 33, 24,168,228, 77,200, 22,133,233, 93,135,206,147, 44, 28,141, 59,141, 36,158,104, 88,214,164,142, 32, 78, 32, 89,234, - 22, 45,144, 44,245, 99, 61,167,236,210, 73,180, 82,167,177,219,191,147,173,191, 19, 22,237,161,228,102,233, 48,199, 91,194, 68, -201, 83,215,107,210,115, 22, 13, 93,114,145,154,246,156, 66, 57,138, 84,148, 44, 93, 74,146,149,202, 34,221,114,228,147, 91,239, - 20,214,238,131,125,103,110,231, 78,242, 17,199, 98,213, 97,143,197, 61,234, 54,126, 51,225,184, 92, 25, 32, 90,120,207,158,224, - 80, 18,140,210,222,205,150,209,182,253,166, 7, 33,208, 94,157,104,101, 42,209, 37, 4, 3, 25, 58,207, 66, 39,172, 59, 70,203, - 53,123,241,135,175, 3,222, 17,115, 45,122, 31, 18,206,225, 21, 31,233, 40,199,176,194,253,134, 14, 29, 22,119, 88,138,240,225, -130,206,188,193,144, 29,148,214,173,200, 99, 93,229,214, 68,180,164,233, 54,216, 85, 6, 82,140,129, 32,113, 33, 90, 22,182,153, -198,178, 53,247,211, 62,191, 23, 18,201, 66,224,187, 68,178,216, 82,214, 53,154,100, 33, 12, 3,100, 36,189,155,110,162,133,120, -169,206,253,198,210,187,224,175,146,213,118, 10, 15, 30,193,135, 73,143,185, 23,248,185, 60, 65,107, 15,220,149,166, 13, 89,188, -255, 25,213, 28,118,154, 92,234, 44,165,140,149, 38, 24, 68,180, 90,119, 25,116,106,240,244,173,225, 24, 9,137, 17,199,173, 56, -104,189,221,148, 51, 84,172,193,160, 79,153,242, 84, 9,176,113, 43,248, 58,157,235,119,115, 79,106,132, 54, 67,150,194,175,130, - 66,195,165,186,217,230,172, 45,245,187,248,152,194,168,107, 16, 45,155,236,181, 36,107, 22, 44,154,152,187, 79,174, 94, 33, 31, - 63,199,113, 29,117,136,235, 48,114, 80,117,148,161,250,200, 69,125,163, 17, 85,207, 67, 94, 18, 45,101,215,236, 58,212, 86,209, -148, 22,214,222, 76,178, 66,252, 46, 95,143, 69,178,198, 45, 63, 19,101,102, 97, 13,179,164,187, 33, 32,165,180,206,236,157,134, - 59,145, 41, 43, 79,248,239,190, 24,248,188,239,242,103,151, 85, 45, 89,255,255,255,145,159,141,123,177, 0,115,199,156,147,172, -172, 60, 77,245,221, 3,241, 88, 32, 89,255,177, 91, 43, 91,237,137,236,234,122, 37,117, 92,248,106, 0, 27,119,171, 56, 84, 34, - 90,120,153, 15, 89,118, 67, 82, 82, 57, 68,203,202, 53,255,139, 6, 29, 99,143, 46,132,187, 16,150,172,229,203,151,183,134,203, - 12,214, 44, 14,200,110,205, 47,125,157, 68, 11,110, 66, 88,176,212, 55,127,127,127,186,121,243, 38,185,186,103,227,145, 83, 87, -164, 57,123, 70,205,217,201, 83, 60,220,161, 35, 23, 30,211,178,157, 87,227, 68,180, 76,109, 60, 58,148,108,208,159, 70, 73,238, -194,113,176,100,181,212,135,163,242,188,146,104, 33, 24, 62, 75,254,138,159, 87, 29,124,196, 15,201, 69,202,213, 97, 63,121,183, -217, 39,145,172,250, 35, 79,144,141,123,241, 79,134, 4,195,187,231, 46, 29,178,243,244, 35, 42, 81,181, 89, 24, 2,249, 85,203, -195,195,150, 43, 84,111, 53,130,221, 13, 55,201, 37, 87,149, 47,114,203, 26,157, 47, 65,234,212,169, 93,123,246,236, 89,153, 73, -150,114,200,110,243, 49, 99,198, 52,226,227,153,228,144, 44,200, 65,224, 59, 98,178,224, 46,132, 37, 75,117,195,111, 28,199,121, -228,179, 46,214,187,218,220,237,215,158, 88,151,236, 87,205,192,178, 74,217, 83, 51,209,130,187, 16, 47, 30,152,212, 97, 49,196, - 23,244, 82,184,230,100,198, 64,113, 7,112,229,201,235,143,210,151, 60, 72, 74,239, 5, 87,165, 23,121, 53,126,217,150,235,127, -130,124, 56,238,165, 64,215, 67, 84,107,248, 41, 16,173, 71,134,148, 19,238, 75,140,124,133,108, 88, 53,208,249,128,100, 97, 68, -163, 61, 19, 45,144,172, 27, 55,110,232, 37, 90, 89, 10,214,164,137, 75, 14, 74,228, 10,163,217, 48,178, 13,255, 15,152,186,141, - 92,243, 86, 37,158,176,180,113,166, 82,189, 55, 86,236,176,224,109,159,249, 23, 56,160,253, 14,136,214, 93,109,101,229,121,151, -106,241,188,109, 77,217,245,222, 28,228, 73,153, 48,210, 12, 29,121,150,188,101, 2, 85,143,135,134,134,150,207,145, 35, 71, 19, - 76,104,105,101,101, 37,197, 46, 25,176, 37, 64,156, 11,143,162,186, 53,144,227,201,208,153, 13,156,176,130,221,176,158, 75,228, -202, 0,209,194,180, 45,223, 5,190,179, 37, 75,253,216, 76,118,207,235,178,104, 21, 44, 89, 61,100,199,185, 55, 84,170,122,243, - 40,133,133,133, 50,158, 49, 65,210,148,105,238, 54,235, 49,129, 7, 67,188,100,107,230, 7,137,100,249, 78, 94, 73,169,204,211, -109,231,114,202, 38, 89, 10, 79,207,164,110,121,202,191,195,212, 24,157,134, 45,199,123,231,106,235, 65, 75, 37, 11,138, 83,142, -114,239,112, 94, 78,189, 53,141, 58,172,223,162,235, 91, 16,163, 24,162,197,157, 44, 62, 50,108,115,215,123, 39,119,212, 97, 90, - 7,207,177,107, 54,237,140,252, 18, 22, 37,145,246, 99, 32, 89,108,121,195, 64, 23, 30,160, 36, 89,138, 32,179, 96,183, 67,212, -156, 73, 77,254,186,190,145, 76,136, 39,232, 42,179, 58,209, 98,252, 79,243,136,202,107, 72,108, 69,186,150, 42,189,215, 53, 28, -131, 12, 67, 98,180,204, 29,115, 7,238, 57,199, 36, 43,122,116, 33,172, 67,112, 71, 98,244, 51,136, 37, 62,138,240,188,195,154, -105,171,135,104,165, 76,151,121,237,229,219, 79,165,184, 93,196, 61,129, 84, 98,160, 74, 31,142,211,106,199, 22,167,246,211, 47, - 81,237,161, 39, 40,103,179, 21,148,177,236, 16,114, 41, 63,148,242,182, 92, 43,155,104,165,177,202,208,161, 97,219,129,161,112, - 23,250,114,223, 8, 28,155, 13,223, 69,118,158, 37, 94,167,113,200,213, 89,203,124,142, 90, 97,117,244, 44,114,229,169,127, 48, -173,229,120,185, 19, 87, 95, 51,217,170,245, 45,229,248,150, 38,173,191, 37, 61,231,205,198, 28, 39, 51,167,252, 87,228,232,212, - 95,157, 39,185,153,213,243, 75, 87,174, 75,126,111,196,100,193, 93, 56,110,249,233,200,212,230,210,244, 13, 6,145, 44, 0, 5, -203, 69,135,225,171,143,239,184,240, 97,127,175, 37,207,230,182,156,241,112,154,182, 84, 99,208,129,197, 25,114, 84,189,195, 47, -181, 47, 28,167, 21,202, 95, 84, 67,180,129,109,233, 92, 32, 48, 71,221,201, 18,201,242,174, 57,158,188,106,140,165, 44,213, 70, - 75,150, 44,183, 74,195, 40, 19, 43,158,115,217,193,228, 80,122, 0,217,151,232, 75,182, 69,251, 16, 95,163,215, 98,230, 85,180, -254,180,114, 42,163, 11,149,238, 66, 85,146,197, 83, 32,180,126,255,254,125,107,254,170,214, 73,180,248,252, 27,117,146,197, 4, -141,184,195, 34,142, 45, 34, 23,183, 44,212,141, 31,194,158,243, 46, 83,221, 94,203,168,120,195,225, 84,172,190, 47, 85,106, 61, -209, 96,162,197, 36,171,125,137,250,253, 36,146, 85,172, 78,111, 38, 89,238,152,122, 66,246,134,192,254,227,199,143, 75, 36,178, -124,173,230,155, 50,230, 40,251,185,209,224, 77,212,105,198, 57,106, 57,241, 52,149,237,184, 76, 34, 89,197, 42, 54,220, 4,178, -185,121,243,230,214,230,230,230,122, 99,212, 28,179, 22,125,136, 0,219,249,107,246,243, 84, 14, 30,135, 77,173, 51,183,131,155, - 48,133,117,230,182, 24, 45, 51,116,230,102,137,208,219,184, 23,125, 41,187,176,223, 50, 74,214, 42, 44, 29,113,237,218,181, 26, -112, 27,222,189,123,183,121,116,199,138,142, 70,175, 53, 11, 66, 48,186, 80,213,162,181,106,219, 55,139,214, 42, 21,139, 86,254, -150,115,219,217,150, 26,220,188,100,205, 54, 17,152,103, 11,123,235,226,125,107, 90, 21,243,213,251, 65,160, 90, 39,158, 43,238, - 35,130, 87,149,243, 63,193,188,142, 56, 56,196,113, 89,203, 36, 90,220, 1,108, 90,190,249,136, 52,209,237,204,237,247,165, 47, - 70,184, 32,171,240, 23,125, 25,118,241,214, 96,194,133,169, 26, 10,183, 89,197, 86, 66,119,125,147,193,198,130,220,210, 41, 39, -230, 12,250,104,233,144,227, 99, 26,199,236, 95, 56,190,237, 75, 58,151, 92,188,207,245,133, 71,115,189, 6,201,130,251,144, 47, -210,105,209, 2,153, 66,128, 61,166, 73, 81,186, 14, 31,190,250, 68, 31, 62,134,147,115,238, 42, 82,208,187, 75,193,182,214, 25, - 10,119,105,239,144,191,249,201,182, 29, 59,124,206, 87,162, 26,222, 47,186,182,100,172,163,213,124,124,124, 26, 6, 4, 4, 84, - 0,177,242,202, 87,246,174, 91,142,226,239, 61,243,149,189,167, 36, 90,172,195,149,217,205,216,144,173,201, 69, 89,152,182,175, -207,152,251,124,155,210,193,227, 13,207,147,245,209,198, 37,207,245,130,165,235, 7,118, 29, 60,149,142, 94,121,197, 35,189, 2, -105,248,212, 85,148,218,206,107, 13, 95, 32,155,188,128, 56,193, 50,242, 93,224, 59,127,237,171, 31, 3,169,213, 69,180, 50,184, -102,187,188,150, 71,149,118, 31,181,140,146,166, 48, 31,164, 80, 88,153, 38, 50, 49,155, 83,177,201, 64, 42, 82,111, 8, 21, 46, -223,136,170,212,111, 75, 94,185,125, 66,147, 36, 55, 3,193,144, 93, 78,233,253,204, 75, 98, 53,235, 57, 77,178, 42,194, 26,131, - 14,214,171, 72,157, 79, 32,241, 85,218, 72, 22,146,250, 6, 62,151, 49,217, 29,220,243, 62,156,177,100,115,196,134, 35,247, 37, - 98,212,137,227, 59, 11, 53,158, 18,110,102,111,136,165,213, 51, 41, 47,191, 20,242,240, 89,128, 68, 58, 48, 79, 26,158,153, 33, -203,152, 28, 48,137,193,156,121,136, 29,173,202,243,192,213, 29,180,147, 44, 50,230,227,248, 44,221,228,208,161, 72,135,105,243, - 54, 95,221, 39,119,122, 7,228,197, 53,250,112,224, 17,235,129,167,249,185, 68,220, 48,230,121, 3, 33,194,251, 29,241,146, 74, -146, 5,203, 20,136,150, 93,102,221, 22, 45, 38, 90, 1, 55,159,240,200, 82, 30,193,185,130, 63,122,166,109,190, 67, 67, 57,166, -177,221,196, 99, 84,185,251, 90,202, 83,127, 42,101,174,232, 75, 57,235, 77,163,170,253,118, 81,227,145,135,201,171, 84, 91,182, - 66,102,214, 59, 13, 5,234,145,218,218,121,198,212,165,251, 34, 97, 45,195, 7, 95,183, 89, 23,200,214,195,231, 77, 42,219,204, -152,136,218,224,141,103,134,159,176,237,192,249, 40, 60,243, 51,120,212,242, 65,158,130,101,215,217, 23,180,249,196, 51,158, 68, -247,177,244,142, 7, 38,197, 91,206,137, 74,149, 33,143, 78, 34,108,240,205,227,227, 5, 41, 82, 91, 73,243, 97, 88,103,173,198, - 74,253,138,198, 44, 57, 21,153, 42,181, 5, 92, 16,134,144,172, 88,147,206, 53,159,249,160,126,171,121, 15, 26, 54,156,126,191, -174,156, 84,125,228,217, 38, 85, 6, 29,106,161,112,114, 82, 93, 95, 47,150, 76, 88,180, 52,185, 11, 97,182,198, 80, 88, 4,102, - 30,225,160,118,144, 44, 30, 81, 34,153,179,217, 20,170,107,102,248,152,181, 11,191, 77, 70,154,113,127,193,188, 30,219, 71,140, - 24,209,151,135, 38,183, 6, 9, 97,114,132,121,166, 36,146,197, 16,105, 35, 90, 49,229,132, 69, 75, 25,155,197,179, 24, 19, 15, -163, 37,150, 69,107,215,174,165, 53,107,214, 16, 79,143, 17, 94,176,214, 0,106, 59,233,148,100,133,195,215,202, 64, 86,122, 60, -148,106,163, 14,117, 78,180, 40,145,172,122, 28, 79, 35,145,172, 62, 32, 89,114,102,170,141, 37, 19,211, 35,176, 85,171,209,160, - 65,131, 90, 40,167,121,112,203, 93,238, 58, 79,172, 23,140,224,119,140, 52,132, 37,107,219,182,109,173,187,118,237,218, 18,121, -113,141,154,142,127, 87, 78,144,229,158,163, 87, 73, 35, 24,215,236,185, 68, 3,216, 58, 80,167,205, 32,234, 57,122, 41,205, 90, -119, 70, 26, 16, 80,174,195, 2,212, 87,219,156, 54,186,234, 46,185, 16, 61, 61, 61,107,114,155,212,199,200, 67,252,230,164,143, -100,125, 39, 19, 49, 90, 30, 5,171,246, 81,141,209,242,204, 95,109, 22, 98,180,250, 46,190, 60, 8,150,172,216,147,154, 94,123, -130,227, 42,245,215, 59,161, 46,136,214,218,163,252,226,225,132, 23, 28, 98,117, 86,240, 30,216,164,115,209, 56,170,239, 59,153, -230,230,217,205,217, 74, 60,182, 64,153,250, 95,103,174, 62, 74,139,120,184,116, 27,238,112,154,176,149,172,219,220,171, 84,119, -200, 30,178,207, 85, 35,156,117, 96,154,150,145,150,122,203, 25, 93,167,214,111,222,188,105, 13,119,225,209,163, 71, 37, 75, 22, -126, 67,239, 53, 16,173, 88, 50,205, 29,114, 31,255,175,231, 36, 58,195, 83, 60, 96,250,146,108,213, 71, 73,115, 53,189, 9, 10, - 35,167,156,149,148,163, 11, 51,116,169,231,250,223,157,245,149,118, 93, 90, 85,243,102,165, 10,197,102,171,145, 4, 77,229, 76, -192, 68,218,135, 45,201, 77,121, 46, 55, 88, 49, 99,172, 91,248,191,123,247,238,181,121,244,115,179,100,201,146,105, 11,109,248, - 78, 38,147,172, 0,148,237, 10,175, 34,129, 73, 70, 17, 71,117,131, 59,184,197,235, 15, 82,161,114,245,165, 73, 33,245, 12,155, -255, 78, 38,136, 19,172, 46,234,164,106, 17,199,162,169, 31, 67,199,171,129,104,197,200, 68, 64, 59,176,156,187,227, 62, 53,239, - 61,141,156,178,228,143,172,213,118, 36, 13, 89,228, 71, 21, 91,142,165,164,169,210,140, 97,220,226,188, 14, 41,123, 27, 78, 79, - 88,115,149,227,188, 14,226, 67, 8,109,160,192,190,237,152,221,212,109, 6,135,138, 56,230,146, 44, 59, 90, 54,157,186, 84,216, -167, 88,223,242, 53,155, 93,241,202, 91, 54,192,201,203, 39,152,173, 30,175, 51,231, 44,126,217,222,193,169,175, 33, 50, 83, 90, -102, 44,147,187,104,141,176, 83, 87,158, 72,174, 73,144,211,174,115, 46, 75,238,241, 90,188,250, 67, 11,182, 28, 65,239,211,185, - 23, 11, 75,145, 86, 90, 38, 76,125,139, 41,103,244,218,133, 81,169,108, 60,162,210,186,151,189,161,109,249, 29,229,113,228, 65, - 94,110, 35, 78,186,215, 58, 76,195,147,144,110, 63,243,146,167,148,121, 37,141,216,195,115,142,129, 30,203, 57, 38,107, 25,147, -108,140, 52,199, 64, 21,184,215,236, 50, 23,210, 57, 97, 41, 98,173, 6,207,220, 77,255, 13, 90, 69,245,123, 47,165,234, 93, 22, - 82,197,246,243,168,114,167,133,212,100,200, 38,234, 57,227, 4,141, 88,121,141, 58, 78,216, 67, 57,203,181, 35,246, 14, 28,215, - 50,207,155,198, 54,226, 80,158,131,235, 15, 92,147,230,179,195, 92,116,229,154, 14,251,106,229,156,183,143, 76,206,242,253,123, -158, 39, 25,119,206, 94,236,229,209,139,143,165,153, 8, 86,241,188,107,248,144,132, 71, 9, 9,211,121, 52,240,221,205, 68, 56, -255, 11, 45, 19,146,203,188,245, 95,146, 45,169,137,233,221,245,187,206, 68, 96,126,154, 81,139,142,135,165, 72,101,134,128, 90, - 67, 72, 22,144,144,251, 50, 55, 4,181,239,136,214,119,238, 66,182,100, 97, 72,169,170,187,208,182, 88,111,137,100,141,231,201, -211,116, 17, 45,213,181, 11,139, 22,176,223,203, 95,207, 77,147, 39, 79,222,133,173, 54,141,145, 48, 57, 39,220,107,152, 60,143, - 95,244, 82, 98,107, 74,172,184,163,232,202,196,148, 19, 49, 90, 60, 73,223,103,184, 15,121,153, 3,226,105, 9,136, 99,188,104, -211,166, 77,196,243, 64,133,113,236,201, 40,184,247,120,125,190,167, 5,107, 15,160,118,147, 79,177,117,139, 95,122,252, 5, 36, -151,104,225,139,179,120,189,190, 81, 32, 89,197,235,246,141, 98, 98,211, 70, 38,168,154,218, 40, 41,215, 57, 63,215,177,225,196, -137, 19, 37,194,133, 4, 11, 22,210,208,161, 67, 91, 69,215, 27,139, 76,107,114, 41,104,144,153, 43, 9,155,228,121,126,171, 9, -212,127,238,113, 41,214, 96, 6,143, 62, 26,198,230,234,166, 35,246, 83,161,250, 35,200,220, 46,219, 14, 5,143,154, 52,244,101, -206,238, 33,199, 92,185,114, 21,231,184,156,142,188, 4,199, 66,222,183,231, 99, 69, 57, 70,203, 57,154,108, 25,212, 65,128,108, - 33, 86, 11,238, 66,236,241, 27, 2, 16,155, 5,183,161,210,162, 85, 10, 22, 45,118, 31,170,197,106,233,213,121,243, 12, 57,238, - 34,232, 29, 9, 49, 89,112, 23,194,146, 5,146,101,227,154,231,134,174, 14, 66,253, 92,114, 91,175, 12,236, 34, 89, 82,168, 82, -203,200,254,179, 14, 80,239, 57,103,201,187,108,123,158, 84, 51,243, 26, 29,171, 1, 24,242,108,182,230,229, 77,190, 35, 89,114, -136, 22,136, 9, 91,165, 91,154, 57, 23,122,211,172,219,120, 58,113,241, 1,181, 24,184,156, 58,143, 90, 79,142,217, 43, 80,221, - 18, 14,181,111,172, 42,183, 60,228, 80,245,195,139, 7,230,246, 77,153, 50, 41, 8,187,186,245, 73, 43,158,236, 70,116,231, 4, -235,101, 11,190,174, 53, 63, 71, 45, 56, 46,171, 97,138, 20,210,226,238,186,172,140, 26,137, 22, 72,214,230, 83,175,217, 82,217, -137, 90,116, 30,132,213, 25,130,208,169,170,187,186,229,234, 39,136, 19, 70,195,169,199, 99, 33,174, 78,253, 24,226,236,116, 17, - 45,232,113,146,148,150,139,235,117, 24, 69, 99, 87, 93,165, 97, 75, 47,210,192, 5,231,169, 90,219,113, 28,179,101,131, 85, 41, -228,110, 26,241,244,246,169,243, 30,239,198, 34, 53,187,113, 12, 90,102,111, 8,195, 62, 79,197,142,212,137,135,230,187,230,173, - 5,151,190,182, 1, 37, 58,117,158, 7, 35,116,100,125, 25,194,239, 62,105,118,120,126,167, 12,233,223,191,255, 16, 30,212,208, - 81, 71,161, 53,202, 52,229, 69,174,109,221, 11,127,236, 50,116, 94,228,180, 53,103,121,218, 25, 38, 8, 43,175, 83,195, 33,219, -169, 96,189,225,145,220,129,127,100, 66,166,173, 60,210,113,172, 83,200, 88,243,232,186,111,107, 23,242, 12,249, 81,179, 55, 94, -220,167,109, 9, 30,156, 67, 30,185,107, 29, 90, 56,230,190,151,222,221,231,157,125,150,162,239,236, 61,125,222,101,240, 44,250, - 45,121,125,219,243,178,104,156,124,222, 57,242,222, 54, 83, 62, 77, 83,175,196,148, 31, 68,235, 17,143, 54,196,100,194,151,238, -189,163, 35,151, 94,208, 22,158,178, 5, 31,167,173,250,207,161,220,101,154, 18, 79,234,125, 31, 22, 44, 94, 9,162,152,161,120, -242, 7,244,227,195,151, 48,245,196, 29,142,245,188,199,171, 64, 84, 14, 50,192, 93,168, 17,103, 46,115,214,244,110, 5,158, 55, -234, 60,230,227,180,181, 23,248, 35, 16, 19,151,222,166,182,227, 15, 82,238,170, 61, 67,204, 29,242, 60, 71, 30,185, 10, 27,143, -243,201, 49,116, 40,220,147, 36, 53,185, 97,146,220,244,126,210,100, 38,152,132,212, 80,146,101,200,203,220, 16, 44, 99, 53,110, - 26,231,188,231,149, 35, 12,149,163, 11,121,164, 97, 48, 70, 23, 34, 22, 75,153,224, 46, 4,193, 66,210, 16,216, 23, 35, 83,117, -237, 66,199,244, 38,195,185, 96, 6,207,248, 30, 93, 25,213,114, 74,163, 14, 57,110,232,243,217,179,103,137, 23, 88,165,101,203, -150, 81,155, 54,109,194,248,248, 69,206, 31,189, 68, 72,174, 36, 74,194, 85,168,246, 64,106, 63, 69, 26, 61,114, 89, 5, 28,173, - 47, 52, 76,162, 56, 98,245, 61, 2,217,130, 59,206, 0, 64,117,189, 36, 83,176,101,160, 24,199,196,212,227,185,170,154, 79,158, - 60,185,181,171,171,107, 99, 51, 51, 51,140,184,208, 21, 8,174, 85, 38, 38, 59,100, 18, 48,198,222,171,228, 37,175, 18,205, 62, -218,121,149,186,194,110,155,113,112,221,232, 41,179,198,243,108,189,114,101,146, 53,144,211, 58,254,255, 50,239,111,243,254, 52, -239,231,113,106,239,229,229,165,171,253,180,222, 19,110, 68,105, 30, 45,222,171,151, 43, 93,241, 62, 85, 97,217,194, 94, 67,153, -245,213,195,128,166,137,201,170, 87, 38, 94, 92, 60, 31,217,134, 84, 54, 89,182, 98,250, 20, 25, 55,209, 43, 19, 50,162,167,112, - 80, 13,240,140,249,159,117, 67,125,122, 7, 45, 50,255, 79,184,170,180,158, 64, 29,134,175,165,226,101, 43,210,231,195, 53,142, -111,159, 80,120,130,171, 93,114, 76, 56,139, 37,149, 52,109,250,202,137,193, 14,176,176, 33, 6, 11, 83, 78,100,231,189,190, 17, -166,223, 19,173,111,174,195, 0,198,240,125, 74, 43,247,190,209, 75, 23,233,147,163, 90,222,239,100,130, 56,193,205, 53,112,230, - 94,201,122, 1, 75, 22, 72, 22,214,100,236, 62,105,167,100,145,193, 7, 7, 72, 22,172,242,122,136, 22,238,149, 32,137,137,121, -179, 76, 57, 75,221, 45, 88,169, 85,120,198,108,197, 47, 39, 74,110,166,107, 97,102,217,120,178,245,106, 80,230,124,213,130, 82, -217,101,157,168,122, 17, 38,202,116,202, 89,245,131,169,157,103, 92,214, 37,148, 68,229,205,155,183, 58,135, 92, 12,226,112,137, - 33, 60,129,231,144,133, 11, 23, 14,169, 88,177,226, 32,142,157,171,166, 67, 79,117,180,187,107, 50,115, 91,239,169, 60, 82,246, - 62,191,235, 63, 51,185,250,108,149,169,240,131,212,182, 89,103, 40,236, 11,104,211, 35,220, 74,146,137,117, 10,249,121,249,255, - 90,135, 60,183, 19,143,128,156,171,109, 9, 30,156,195,252, 79,114,215, 58,148,241,236,233,203, 18, 83,119,132, 88,240, 7,234, - 51,190,255, 93,196,101,114, 58,195,233, 48,127, 72,175, 71, 44,174,158,143, 41,157,250,137,147,188,114, 74, 32, 12, 16,112,195, - 98,186, 38,219,204, 5, 63,232, 43,156,202,121, 29,109, 84, 44,177,165, 99,142,255,210,187, 23,217,203,125,241, 61, 43, 87, 41, -237,229,169,109,120,225,116,249, 19,170, 26, 80,150, 63, 49, 43,150, 16,148, 69,182,126,180,240,250, 94,146,113,145,255, 83,101, -122,184,164,168, 86,166,168,243,102, 87,135,148, 48,107,171,174, 93,104,104, 89,213,203, 9,178,229,203, 86,162, 7, 76, 92, 2, -224, 78,196,111, 22,170, 97,241,223, 24,194,133,217,126, 87,202, 81,108,140,132, 74,235,156,251, 16,199,227, 52, 51,176,160,114, -240, 52,231, 78,181,100,116,220,147,185, 12,249,114,100,202, 16, 19, 43,139, 86,153, 74,139, 22,239,235,115,106,199,169, 38, 39, -159,184, 90,180,112, 87,140, 66, 84,206, 12,175, 94, 80,251,218,147,146,247, 91,162,117,212,225, 47,173,187,161, 32,202,209,165, -159, 39, 51,154,112,101, 44,228, 95,179, 66,206, 7, 62,217,172,203,240,189, 52, 45,204,173,183,131, 80,205,144, 52,105, 82,204, - 19,213, 58,122, 47,167,248,191,164,141, 48,157, 10,200,147,220,164, 97,250,149, 95, 82, 78, 57,128,233,201,163,175,156,137,178, -101,203, 86,156,159,199,102,252, 17,212,129, 93,252,205,120, 77, 85, 31,205,239,190,152, 59,233,147, 25,151, 98,255,159,192,240, -122,133,188,110, 97, 20,146,218,218,133, 26,229, 34,143,150,252, 63,181,156,113,169,164,150,107, 52,150,211,202, 57,207,157,244, - 60,197, 4, 70, 63, 50,201, 10,180,113,201,123,199,128,123,254,140,186, 27,112,123,145, 85,137,192,207,104, 8, 33,211,184,250, - 37,240, 20,120, 26, 11, 1, 67,116, 73,110,176,182, 33, 50,229,214, 67,200,148,139,148,188,124,241, 18, 79, 88, 45,117, 44,186, -254, 93,205,181,228,143,151,117,151,215,172,122,115,253,140,186,235,189,233, 31,156, 65,147,229,255,151, 20,247,103, 52,132,144, -105,220,166, 19,120, 10, 60,141,133,128,208, 37, 99, 33,249, 77,142,192, 83,224,105, 44, 4,226,139, 46, 25,171,190,127,156, 28, - 52,128,166,100, 72, 65,181,201,208,117, 92,159,124, 33, 83,115,187,196,181,189, 4,158, 2, 79,185, 58, 32,158, 77,237, 8,200, -197, 80, 53,159,192, 83,224,169, 9,129,127, 89,151,148,120,196,181, 63,211,247, 76,253,142,243,234, 22, 45,196,104,253,146, 45, -190,176,104, 81, 78,227,170,131,192, 83,224,105, 44, 4,132, 46, 25, 11, 73, 97, 37, 19,186,244,231,235,146,113, 75,248,123,165, -253,146, 64,120, 97,250, 54,126, 35,139, 23,133,113, 49, 21,120, 10, 60,141,133,128,208, 37, 99, 33, 41, 8,225,191,172, 75,198, -213,162,223, 43, 77, 16, 45, 53,252,255,101,197, 22,117, 55,238,195, 40,240, 20,120, 26, 11, 1,161, 75,198, 66, 82,144,183,248, -162, 75,198,109,241, 95, 43, 77,184, 14,245,224, 29, 95,148, 80,148,211,184, 15,142,192, 83,224,105, 44, 4,132, 46, 25, 11, 73, - 65,138,254,101, 93, 50,174, 22,253, 35,210,254,101,133, 17,117, 55,174,146, 11, 60, 5,158,198, 66, 64,232,146,177,144, 20,164, - 72,232,146,113,117, 41, 62, 75, 83,186, 10,149, 19,149, 10,215,161,112, 29,198, 32, 32, 94, 20,198,125,180, 5,158, 2, 79, 99, - 33, 32,116,201, 88, 72, 10, 66, 24, 95,116,201,184, 45,254,107,165,169, 19,171,216,191,121,253, 41,229, 2,175, 10,213,255,127, -109, 25,197,221, 4, 2, 2, 1,129,128, 64, 64, 32, 32, 16,248, 87, 17,136,231, 92, 68,213,146, 5,146, 21,123,122, 7, 84, 78, - 89, 65, 65,180,254, 85, 21, 23,245, 22, 8, 8, 4, 4, 2, 2, 1,129,192,239, 67,224,175,230, 34,170, 36, 75, 16,173,223,167, -100,226,206, 2, 1,129,128, 64, 64, 32, 32, 16,248, 87, 17,248,171,185, 72, 60, 55,215,253,171, 58, 41,234, 45, 16, 16, 8, 8, - 4, 4, 2, 2,129,191, 6,129,191,154,139,252,213,149,251,107, 84, 80, 84, 68, 32, 32, 16, 16, 8, 8, 4, 4, 2,127, 47, 2, -241,156,139,232,142,209,250,123,155, 77,212, 76, 32, 32, 16, 16, 8, 8, 4, 4, 2, 2, 1,129,192, 79, 71, 64,247,168,195,159, -126,123,113, 3,129,128, 64, 64, 32, 32, 16, 16, 8, 8, 4, 4, 2,127, 47, 2,234, 51,195,255,178,121,180,254, 94, 72, 69,205, - 4, 2, 2, 1,129,128, 64, 64, 32, 32, 16, 16, 8,252,102, 4,226,203, 36,105,162,156,198, 85, 20,129,167,192,211, 88, 8, 8, - 93, 50, 22,146,223,228, 8, 60, 5,158,198, 66,224,103,232,146,177,202,246, 59,228, 40, 99,180,112,239,239,231,209,250,137, 37, -250, 25, 13, 33,100, 26,183,193, 4,158, 2, 79, 99, 33, 32,116,201, 88, 72, 10, 82, 36,116,233,223,212, 37,227,214,250,215, 74, - 83,186, 10,213,247, 63,189, 20,226, 97, 49, 46,196, 2, 79,129,167,177, 16, 16,186,100, 44, 36, 5, 41, 18,186, 36,116,201,184, - 8,196, 79,105,191, 45, 24, 94, 60,128,198, 85, 24,129,167,192,211, 88, 8, 8, 93, 50, 22,146,130,104, 9, 93, 18,186,100, 92, - 4,132, 52,131, 16, 16, 15,160, 65,112,233,205, 44,240,212, 11,145, 65, 25, 4,158, 6,193,165, 55,179,192, 83, 47, 68, 6,101, - 16,120, 26, 4,151,222,204, 2, 79,189, 16, 25,148,225,103,224,105, 80, 1, 68,102,241,149,247, 51,148, 80,200, 52,238,147, 37, -240, 20,120, 26, 11, 1,161, 75,198, 66, 82,244, 29,255,178, 46, 25, 87,139,254, 32,105,104, 84, 77,201,144, 34,106,147,161,235, -184, 62,249, 66,166,230,118,137,107,123, 9, 60, 5,158,114,117, 64, 60,155,218, 17,144,139,161,106, 62,129,167,192, 83, 19, 2, -255,178, 46, 41,241,136,107,127,166,239,153,250, 29,231,149,163, 14, 85,103,136,255, 37,229,248,151,153,185,168,187,113, 85, 76, -224, 41,240, 52, 22, 2, 66,151,140,133,164,176, 62, 9, 93, 50,174, 46,197,103,105,191,124,180,161, 42, 91, 53, 54,112, 66,177, -141,139,168,192, 83,224,105, 44, 4,132, 46, 25, 11, 73, 65, 96,132, 46,253,155,186,100,220, 90,255, 90,105,191,109,102,120,241, -176, 24,183,161, 5,158, 2, 79, 99, 33, 32,116,201, 88, 72, 10, 82, 36,116, 73,232,146,113, 17, 16,210, 12, 66, 64, 60,128, 6, -193,165, 55,179,192, 83, 47, 68, 6,101, 16,120, 26, 4,151,222,204, 2, 79,189, 16, 25,148, 65,224,105, 16, 92,122, 51, 11, 60, -245, 66,100, 80,134,159,129,167, 65, 5,248,195, 50,139,121,180,244, 52,200,207, 80, 24, 33,211,184, 79,129,192, 83,224,105, 44, - 4,132, 46, 25, 11, 73, 97,205, 19,186,100, 92, 93,138,207,210,196,204,240,130,104,105, 69, 64,188, 40,140,251,104, 11, 60, 5, -158,198, 66, 64,232,146,177,144, 20,132, 48,190,232,146,113, 91,252,215, 74,211, 31,163,181,125,251,118,250,181,101, 18,119, 19, - 8, 8, 4, 4, 2, 2, 1,129,128, 64, 64, 32,240,127, 4,254, 90, 46,162,172,216, 95, 91, 65,161,197, 2, 1,129,128, 64, 64, - 32, 32, 16, 16, 8,252,209, 8,196,115, 46,162, 58,127, 22,172, 91,248,253, 61,131, 20, 68,235,143,214, 65, 81, 56,129,128, 64, - 64, 32, 32, 16, 16, 8,252,181, 8,196,115,162,165, 59, 24, 62,158, 87,238,175, 85, 58, 81, 49,129,128, 64, 64, 32, 32, 16, 16, - 8,252, 43, 8,196,115, 46, 34, 98,180,254, 21, 69, 21,245, 20, 8, 8, 4, 4, 2, 2, 1,129, 64,124, 69, 64,120,214,226,107, -203,137,114, 11, 4, 4, 2, 2, 1,129,128, 64, 64, 32, 32, 16,248,121, 8,232,183,104,253,188,123, 11,201, 2, 1,129,128, 64, - 64, 32, 32, 16, 16, 8, 8, 4,254, 9, 4,212, 99,181,254,137, 74,139, 74, 10, 4, 4, 2, 2, 1,129,128, 64, 64, 32, 32, 16, -248,217, 8,252, 22,146, 21, 95, 38, 73, 19,229, 52,174,250, 9, 60, 5,158,198, 66, 64,232,146,177,144,252, 38, 71,224, 41,240, - 52, 22, 2, 63, 67,151,140, 85,182,223, 33,231,183,185, 14,127, 70, 67, 8,153,198, 85, 33,129,167,192,211, 88, 8, 8, 93, 50, - 22,146,130, 20, 9, 93,250, 55,117,201,184,181,254, 71,164,137,135,197,184, 13, 45,240, 20,120, 26, 11, 1,161, 75,198, 66, 82, -144, 34,161, 75, 66,151,140,139, 64,252,148, 38, 22,149,214,211,110,226, 69, 97, 92,197, 22,120, 10, 60,141,133,128,208, 37, 99, - 33, 41, 8,161,208,165, 63, 95,151,140, 91,194, 95, 43, 77, 44, 42, 45,136,150, 86, 4,196,203,199,184, 15,163,192, 83,224,105, - 44, 4,132, 46, 25, 11, 73, 65, 50,227,139, 46, 25,183,197,127,173, 52, 17,163, 37,136,150, 32, 90, 26, 16,136, 47, 47, 31, 81, - 78,227,190, 48, 5,158, 2, 79, 99, 33, 32,116,201, 88, 72,254,229,114,160, 40,154,146, 33,213,214, 38, 67,215,113,125,242,133, - 76,205,237, 18,215,246, 18,120, 10, 60,229,234,128,120, 54,181, 35, 32, 23, 67,213,124, 2, 79,129,167, 38, 4,254,101, 93, 82, -226, 17,215,254, 76,223, 51,245, 39,156,255,101, 83, 61, 8,182,111,220,230, 22,120, 10, 60,141,133,128,208, 37, 99, 33, 41,220, - 82, 66,151,132, 46, 25, 23,129,191, 67,154, 32, 90,106,237, 40, 94, 20,198, 85,108,129,167,192,211, 88, 8, 8, 93, 50, 22,146, -130, 16, 10, 93,250,243,117,201,184, 37,252,181,210, 68,140,150, 30,188,197, 3,104, 92,133, 20,120, 10, 60,141,133,128,208, 37, - 99, 33, 41,136,150,208,165, 63, 95,151,140, 91,194,127, 68,154, 80,108,227, 54,180,192, 83,224,105, 44, 4,132, 46, 25, 11, 73, - 65, 96,132, 46, 9, 93, 50, 46, 2,241, 83,154, 45, 23, 27, 86, 45,229, 62,215,175,170,134,120, 0,141,139,180,192, 83,224,105, - 44, 4,132, 46, 25, 11, 73, 65,180,132, 46, 9, 93, 50, 46, 2,241, 83,154,152, 71, 75,184, 14,181, 34, 32, 94,146,198,125,168, - 5,158, 2, 79, 99, 33, 32,116,201, 88, 72, 10, 50, 28, 95,116,201,184, 45,254,107,165,233,142,209,218,190,125, 59, 69,167, 98, -191,182, 92,226,110, 2, 1,129,128, 64, 64, 32, 32, 16, 16, 8, 8, 4, 20,138,191,154,139,160,114,104,100,229, 94, 52,184, 64, - 64, 32, 32, 16, 16, 8, 8, 4, 4, 2, 2,129, 95,137,192, 95,205, 69,254,106, 22,249, 43,181, 68,220, 75, 32, 32, 16, 16, 8, - 8, 4, 4, 2, 2,129, 56, 33,240, 87,115, 17, 97,201,138,147, 78,136,139, 4, 2, 2, 1,129,128, 64, 64, 32, 32, 16, 48, 18, - 2,241,156,139,168,143, 58,140, 61, 97,105, 60,175,156,145,154, 88,136, 17, 8, 8, 4, 4, 2, 2, 1,129,128, 64,224,119, 33, - 16,207,185,136,250,168,195,223, 5,163,184,175, 64, 64, 32, 32, 16, 16, 8, 8, 4, 4, 2, 2,129,191, 14,129,223, 54, 51,252, - 95,135,164,168,144, 64, 64, 32, 32, 16, 16, 8, 8, 4, 4, 2, 2, 1,129,128, 64, 64, 32, 32, 16, 16, 8, 8, 4, 4, 2, 2, - 1,129,192,175, 67, 64,213,170,245,203,238, 26, 95, 38, 73, 19,229, 52,174, 74, 8, 60, 5,158,198, 66, 64,232,146,177,144,252, - 38, 71,224, 41,240, 52, 22, 2, 63, 67,151,140, 85,182,223, 33, 39,118,240,251,183,229,120,126,201,246, 51, 26, 66,200, 52,110, -211, 9, 60, 5,158,198, 66, 64,232,146,177,144, 20,164, 72,232,210,191,169, 75,198,173,245,175,149, 38,136,150, 30,188,197, 67, -109, 92,133, 20,120, 10, 60,141,133,128,208, 37, 99, 33, 41,200,155,208,165, 63, 95,151,140, 91,194, 95, 47, 77,184, 14,117, 96, - 46, 30, 64,227, 42,164,192, 83,224,105, 44, 4,132, 46, 25, 11, 73, 65,180,132, 46,253,249,186,100,220, 18,254, 35,210,132, 98, - 27,183,161, 5,158, 2, 79, 99, 33, 32,116,201, 88, 72, 10, 2, 35,116, 73,232,146,113, 17,136,159,210,126, 89, 76,150, 58, 60, -226, 1, 52,174,194, 8, 60, 5,158,198, 66, 64,232,146,177,144, 20, 68, 75,232,146,208, 37,227, 34, 16, 63,165,233,156,176, 20, - 15,137,166,100, 72, 85,181,201,208,117, 92,159,124, 33, 83,115,187,196,181,189, 4,158, 2, 79,185, 58, 32,158, 77,237, 8,200, -197, 80, 53,159,192, 83,224,169, 9,129,127, 89,151,148,120,196,181, 63,211,247, 76,253,142,243,191,109,194, 82,241,165, 99,220, -230, 22,120, 10, 60,141,133,128,208, 37, 99, 33, 41, 44, 90, 66,151,132, 46, 25, 23, 1, 33,205, 32, 4,196, 3,104, 16, 92,122, - 51, 11, 60,245, 66,100, 80, 6,129,167, 65,112,233,205, 44,240,212, 11,145, 65, 25, 4,158, 6,193,165, 55,179,192, 83, 47, 68, - 6,101,248, 25,120, 26, 84,128,191, 49,179,117,226,196,137,251,167, 72,145, 98, 22,167,185,252,255, 4,174,164,165,158,138,126, -215, 16,166,166,166,157,211,167, 79,127,147,211, 51, 71, 71,199,157,169, 83,167,236,234,106,162, 40,202,114,146,200, 4, 77, 87, -227, 38,100, 25, 30,156,186,114, 25,111, 36, 79,158,252, 17,255,191, 28,191, 57, 89,233,144,175, 87, 97,134,219, 41,106, 93,237, - 82,109, 51,246,106,114, 42,217,216,216, 28,227, 99,101,213,142,235,149,169,173, 60,245, 83, 42, 74,215, 54, 85, 60, 65,194,255, - 42,249, 12,146,153, 58,117,234,198,182,182,182,167,210,166, 77,251,156,247, 39, 24,143,218, 26,238,169, 75,102, 58,174,219,120, - 7, 7,135,219,118,118,118, 83,248, 90,172, 78, 46,103, 51,168,156,114, 4,114, 30,189, 50,125, 76, 20, 62, 5, 76, 20, 1, 5, -147, 41,130, 11, 39, 83,204,226,125,153, 50, 10, 69,202, 56,182,123, 17,190,110,189,153,153,217, 69,214,245,237,252,127, 77, 78, -208,175,154,248,141,227, 56,207, 9,249, 84, 55,189,229,140,150, 51,158,247,207, 57,141,138,254,221,137,113, 14,206,158, 61,251, - 35, 78,139,221,220,220,154,200,109,247,148, 41, 83,150,225,107, 55,240,243,244,168, 96,193,130,239,236,237,237,111,101,200,144, - 97,137,137,137, 73,241, 56,214, 93,102,147,124,151, 77, 78,221, 13,149, 45,100, 26,138,152,238,252, 2, 79,129,167,177, 16,248, - 25,186,100,172,178,197, 59, 57, 85,184,196,163, 57, 77,191,124,249,178, 31, 17, 73, 9,255,243,177, 89,156,198,232,232, 4, 99, - 53, 4,119,248, 67, 71,140, 24,241,249,229,203,151, 20, 16, 16, 64,183,111,223,166,201, 3,251, 68,149, 75,147,152, 92,173, 45, - 67,153, 12,220,115,202,144, 97,117,214, 84, 9,251,176,204, 76, 90,144,210,214,184,150, 76,174,206, 12, 28, 56, 48,228,216,177, - 99, 33, 95,191,126, 13,137,138,138, 10,121,241,226, 69,200,254,253,251, 67, 10, 23, 46, 28,194,242,186,113, 74,164, 65,174, 94, -133, 25,102,167, 56, 66, 11, 7, 17,246,170,215,103,201,146,229, 58,223,135,106,213,170,245,133,143,219,203,237, 28, 53,213,141, - 47, 78,158,213, 76, 97, 81, 59,149,194, 63, 98,201,112,162,153, 61, 9,100, 43, 46, 50,211,165, 75,183,165,115,231,206, 65,207, -159, 63,167, 47, 95,190,208,147, 39, 79,168, 77,155, 54, 31,248,248, 10,181,123,107,171,123,218,108,217,178,249,159, 58,117, 42, - 42, 48, 48,144, 14, 31, 62, 28,229,237,237,237,207,215,202, 33, 91,177,100,242, 61,231, 49, 81,219,105, 72,226,107, 22,200, 44, -103, 76,182,252, 38,138, 39, 97,126,135,136,206,237,165,173,181, 10,210,228, 60, 25,168,102,154,100,129, 69,146, 41, 58, 21, 83, - 40, 18, 27,208,238,117,138, 21, 43,246,241,202,149, 43,145,111,223,190,165,235,215,175, 71,181,106,213,234, 51, 95,127, 13,123, -252,198,113,156, 71, 62, 62,222,210,128, 54, 2, 89, 91,228,235,235,203,143, 17, 17, 63, 15,196,196,138, 74,150, 44, 73, 33, 33, - 33, 56,244,136,211,226,136,136,136,102,114,100,154,155,155, 55,230,118, 14, 9, 13, 13,149,228, 97,131, 62,162,205,166, 79,159, -254,145, 63,104,118,178, 28, 77, 31, 25,122,117, 62, 14,111, 42, 33, 51, 14,160,233,184, 68,224, 41,240, 52, 22, 2,241, 69,151, -140, 85,223,223, 33, 7,125,163,106,156,150,156,190, 82, 42,103,131, 62,125,250, 40, 73,213,174, 34, 69,138,156,109,214,172,153, - 31, 18,255,127,152,207,239, 57,127,254,188, 95,239,222,189, 65,186, 26,232,233,200, 44, 11, 21, 42, 20,248,234,213, 43,202,156, - 57, 51,101,204,152,145,240, 63,182,115,117,114,211, 1, 79, 5, 61, 61,186,139,246,110, 90, 79,173,108, 19,147,143,173,121,184, -109,250,244,111,173,172,172, 70,178,220, 4,122, 58,157, 26,158,158,158,193,215,174, 93, 11,185,115,231, 78,200,208,161, 67, 67, -184,227, 10, 97,162, 16, 82,179,102,205,144,105,211,166,133,132,133,133,133, 44, 88,176, 32,132, 45, 17,215, 88,150, 58,217,210, -171,132,218,136, 22, 91, 55,166, 50,233,164,123,247,238, 17,203,133,149, 66,185,169,203, 52,183,176,176, 40,111,105,105,217, 13, -123,206,100,142,140,153, 21,138, 84, 57,204, 21,142,157,114,184,102,217,222,160,116,166,233,165,243,230,174,157, 58, 97, 96,248, -140,158, 68,181, 28,227, 68,180,208,249,118,237,218, 53, 24, 4, 11, 29, 48, 58,112,236,131,131,131,169, 65,131, 6, 65,108,217, -170,161,175, 19,103,220,135, 31, 61,122, 52, 2,109,196,123,218,185,115, 39,205,156, 57, 51,138, 9,208, 36, 25, 26, 28,171,238, -220,217,239,219,187,119,175,223,133, 11, 23,252,206,156, 57,227, 23, 30, 30,238,199,237, 33,165,237,219,183,251,109,220,184,209, -111,205,154, 53,126, 76,142,165,196,229,246,115,113,113,217,173,118, 31,189,109,148,207, 68,241,244,235,177,173, 68,147, 58,208, -135,177,237, 40,176,123, 69,122,221,166, 40,205,202,155,129,138,166, 80,108, 83,211, 35,136,215, 40, 51, 73,146, 36, 71, 30, 61, -122, 20,213,175, 95,191,175, 94, 94, 94, 31, 90,180,104,241, 25, 88, 98,195, 30,191,113, 28,231, 31, 62,124, 24,197, 58,176, 95, - 31,158, 42,231,199, 40, 73,214,145, 35, 71, 98,200, 17,254, 65, 59,177,222, 74, 22, 45,103,103,231,134,250,100,166, 74,149,170, - 90,223,190,125, 37,118,166,190, 49,198, 82,123,163,124,252,172,189, 96, 89,105, 13,197, 83, 70, 59,171,103,209,219, 70, 66,166, - 65, 8, 8, 60, 13,130, 75,111,102,129,167, 94,136, 12,202,240, 51,240, 52,168, 0,127, 88,230, 56,205, 12, 95, 26, 4, 10,214, -171, 1, 3, 6,128, 72,193,178,149,148, 83,170,232, 4, 11, 65,125,126,209, 75,121, 64,200,162,243,168,214, 93,181, 33,170,172, - 91,183, 46,108,202,148, 41,196,238, 40,226,206,151,166, 78,157, 42,125,125,191,218,190, 66, 34, 90, 55,250, 55,149,250,139,219, - 35, 59, 74,191,239,207, 30, 70,141, 26, 53, 10,101,215,136, 42,137, 83,111,220, 52,185,115,231, 14,254,244,233, 83,200,146, 37, - 75, 66, 56,239, 57, 46,128, 23,167, 36,209, 29, 43,202,219,132, 59,198,160,171, 87,175,134,172, 90,181, 10,150,173,161, 50, 59, - 29, 88,213, 74,176,187,179,102, 95,251, 36,119, 96,209,234,107,163,184,194,199,188, 57, 89, 71,203,176,227,186, 75,229,102,247, -205, 81, 45,157,163, 57,147,190, 62, 76, 2,135,112, 7, 56,132, 9,199, 16,119,119,247,126, 85, 93,108, 11,110,110, 80, 38,215, -135, 97,237,114,209,196,238,217, 38, 84,200, 87,122,117,189,226, 13,154, 59, 91, 29,107,145, 46,121,104, 93,243, 68,193,113,113, - 29,178,235,232, 12, 44, 88, 74,114,133, 14, 23,150,173, 7, 15, 30, 16, 91,251,136, 45,135, 7,244,117,226,220, 62,215, 33, 99, -246,228,201, 84,203, 59, 11, 21,181, 72, 77,197, 44, 83, 83,158, 84,201, 63,122, 42, 20,121,244, 40,248,119, 68,235,226,197,139, -208, 15, 41,177, 53, 72, 74,239,223,191,143, 57,134,227, 31, 62,124,144, 18,200,150,171,171,171,193, 68,171,112,114, 69,225,252, -201, 21,239, 10,154, 40, 62, 85,177,183,122,209,206,197, 42,242,116,131,130,244,190, 67, 73,154,146,203,158, 96,217,146,217,238, - 85,146, 37, 75,134, 15,137,158,156, 64,202,155,150, 47, 95, 94, 50, 25, 97,143,223,209,199,187, 70,147, 44, 16,103,229,166,235, -229,147,144, 93,130, 31, 33, 7,150, 44,190,224, 36,126,195,162,133, 4,215, 97,180,108,117,120, 53,202,204,148, 41,211,109,214, -251, 24, 2, 8, 43, 22, 91,112,233,254,253,251,196, 31, 29,116,238,220, 57, 98,194, 72,107,215,174,141,100,114,191, 67,102,221, -245, 52,173,206,211, 63,227,197, 43,100,254, 72,139,124,127,173,192, 83,224,105, 44, 4,126,134, 46, 25,171,108,191, 67,142,254, - 81,135,108, 89,192,139, 95,117, 27, 11,107, 21,136, 20, 31,212, 53, 17, 87,107, 16,177,104, 87, 34, 92,140, 26, 55,238,252, 23, -192, 85,216,180,105, 83,242,240,240,144, 18, 91,198,136, 59, 86, 10,185,123, 85, 34, 86,231,234,230,145, 58,141,224, 27, 23,164, -223,126,141, 10,209,165, 75,151,136,227, 77,246,234, 64,109,219,137, 19, 39, 2, 86,172, 88,241,138,243, 32, 30, 11, 4,171, 0, -167,169,236, 74, 92,196,123,184, 11, 51,114,178,100, 75,218, 59, 38, 31, 33,236,230, 3,217,114,212, 33,179, 24,151,239, 30, 91, -192,232,245,235,215,244,238,221, 59, 26, 87,216,157, 64,180, 70,228,201, 24, 53,123,246,236, 47, 61,123,246,252,152, 38, 77, 26, -196,238,216,177,188, 8,148,187,104,209,162,112,173,125,183,193,130, 5,146,245,249,243,231, 33,220, 25, 14, 97,121, 67,182,110, -222, 60,164,156,183,123, 83,144, 44,144,173, 10,246,150, 53, 39,149,205,219,246,121,191,150,181, 6, 20,242,186,241,121, 76,151, - 67,117, 92,108, 84, 45,100,178, 21,199,218,218,250, 37, 44, 47,124,193,119, 9,150, 55,118,225,170,186, 35, 53,202,229,186, 13, -232, 90,191, 94,100,141,140,246,116,111,202, 64, 10,223,183,138,194,119, 46,161,187, 99,187, 83,213,244, 86, 65, 5,146, 38,236, - 43,183, 64,176,104,193,146,197,249, 99,136, 22, 72,150, 38,162, 21, 20, 20, 36, 17, 45, 38, 32,234, 68, 75,238,237, 98,242, 21, - 72,166,112, 45,150, 34,209,185, 11, 77,125, 40,160, 93, 73, 42,111,158, 4, 49,123,113,221,234,243,133, 32, 95,141, 12, 20, 0, - 87,225, 24, 37,161, 26, 59,118,172,164,227,248,205,199,113, 46,174,155, 57,187,173, 31,180,108,217, 50,130,173,185,175,217, 53, - 30,120,246,236, 89,130,149, 12,214,199,245,235,215, 19,127, 88, 72, 4, 27,207, 93,165, 74,149, 2,249, 70,197,226,122, 51,113, -157, 64, 64, 32, 32, 16,248, 21, 8,104,224, 34,191,226,182, 63,255, 30,202,138,169, 84,208,156,239, 58,141,211, 46, 78,232, 96, -176, 37,200,150, 72, 81,167,100,138,196,151,144,240, 63,142, 69,159,171,202,123,184,102,166,114, 74,175,169,196, 28,159,115, 23, -113, 45, 28,211, 66, 5, 10, 20,144, 82,241,226,197,165, 88,146,192, 59, 87,105,119, 22, 5, 29,171,158, 77,178,194,188,190,230, - 71,219, 60, 20,116,176,170, 55,249,251,251, 19,187,171, 30,104, 65, 33, 71,221,186,117,111,178,203,229, 58, 91,105,208,137, 39, -227,180,252,191,255,254, 11, 57,121,242,228,145,200,200,200,241,252,101,223,150, 99,139,218,243,113, 54,196, 40, 42,140, 25, 51, - 38,132,235, 9,162, 5,171,132,166,205,155, 59,165, 80,184, 94, 64, 86,216,165, 69,176, 88,245,202,156, 38, 10, 68,107, 96,214, -244,145, 51,102,204, 8,222,188,121,243,251,229,203,151, 7, 48,185,122,166,180,104, 49,153, 68, 80,252,119, 27,220,133, 76, 30, - 36,146, 5,194,197,241, 78, 82,178, 73,147,166, 15,220,134, 30,201, 21,249,151,215, 44,222,154,173, 90,205,218,231,116, 25,176, -186, 78,169,119, 31,134,181,191,229,157, 92, 10,226, 55,120,227,114,156,126,246,236, 25,241, 61, 9, 22, 15, 38, 47, 4,236,223, -188,121, 35,117,196,106, 22, 45,141,242,157, 21,138,194,149, 51,216, 68,133,239, 93, 73, 52,161, 29, 81,235,124, 68,173,242, 18, - 13,107, 68,254, 51, 7, 82, 78, 91,155, 47,102,169, 83,191,103, 18, 57,143, 5,184,233, 42, 36,136, 22,220,133, 74, 75, 22,231, -141, 33, 93,140,137,100,197, 2,193,226,118,246, 99,151,153,223,252,249,243,141, 66,180, 80,166,194, 41, 20,185, 70,231,117,161, - 15,189,170, 82, 71,103, 75,202,155, 74,145, 70, 71, 89, 75,178,219,112, 29,147, 76, 16,251, 14,156, 76,177,199,111, 28,231,255, - 75, 26,220, 24, 76,178,148,174, 66,165,123, 15,191, 89, 14, 98, 27,149, 91,123, 38,191,219, 19, 38, 76, 56,159, 15, 84,228, 84, -158,219,168,148,158,123, 53, 95,180,104,209,245, 57,115,230, 92,231,124, 5, 57,185,194, 53,207, 86, 93,154, 56,113, 34,177,254, - 75, 31, 49,183,110,221, 34,142,179,163,133, 11, 23, 18,187,205,209, 86, 98, 19, 8, 8, 4, 4, 2,127, 36, 2, 26,184,200, 31, - 89, 78, 45,133,210,237, 58, 84,175, 28,187,223,166,248,241,198,238,140,125, 44, 80,250,234, 6,177,242,245,201,249, 49,120,197, - 68,250, 48,207,151,250,228,202,252, 49,154,108,225,116,194, 60,121,242,156,192, 53, 60,210, 9,163,168,190,219,152,104,221, 65, -103, 95,163, 70, 13,184, 95,168, 66,133, 10,196,241, 83,146,181,232,233,197,179,180, 62,179,130,118,148,115,151, 92, 31,247,206, - 28,167, 85,110, 10,218, 82,214, 93,114,131,112, 7,124, 95, 75,197,186,115,160,251,145, 81,163, 70, 29,228,243,181, 57,229, 97, -139, 25, 2,131, 67,134, 13, 27,182,187,156,155,243,226,122, 22, 73,222, 52, 72,107,242,218, 35,137, 98, 10,159, 79,201,247, 14, - 97, 75, 74, 72,130, 4, 9, 52, 90, 76,216, 10,118, 2,177, 50,236,234,130, 37,237,106,180, 92,151,161,182,138,163,146,235, 48, -189,226, 50, 31,235,194,238,202,219,220,161, 61,231,125, 24, 58,178,199,143, 31,163,243,212,104,209,131, 69,139,243, 12,102, 55, -206, 16,182, 54, 12,153, 48, 97,194, 88,182, 64,236,226, 56,168,211,105,205, 83,251,142, 41,157,167, 11, 77,232,209, 26,100,203, - 43,185, 98,194,253, 62,205,232, 80,203,106, 95, 61, 82, 72,157,174,193, 27,143, 54,172,215,186,117,235, 96,224,205,196, 78,114, - 23, 34,206, 10,174, 36,198, 61,152,221, 98,112, 3,235,220,138, 36, 79,188,249,246,228, 1, 68, 19,219, 19, 53,244,136, 73,159, -235,185,211,232, 14,255,209,105,174, 51, 72, 50,199, 94, 69,241,104, 55,184,188, 56,220, 76,243, 6,162,133,120, 44,109,238, 66, -118,109, 30, 98,162,181,157,227,178, 54,177,206,109, 98, 82,176,157,221, 98, 24,209,247,195,155, 79, 82, 69,214,209, 5,220,232, -195,192,250,212, 57,179,181, 46,162, 85,167, 94,189,122, 1, 28,147, 22,204,245, 66, 92,223,123,142,101,187,143, 61,126,227, 56, -206,115,129, 84, 71, 3,234, 45,159,210, 85, 8, 75, 22,220,131,209,150, 44,232, 34, 92,239,157,248,247,241,142, 29, 59,250,241, - 71,129, 31,235,190, 31,147,248,109,236, 82, 31,194,164,172,178, 30,225,139, 56,255,245, 42, 85,170,128,104, 57, 33, 47, 91,108, -223,140, 28, 57,146,118,239,222, 77, 28, 76, 79, 32,219,104,115, 88,184, 14, 30, 60, 72, 28,211,133,188, 98, 19, 8, 8, 4, 4, - 2,127, 36, 2,127, 9,209,210, 60, 67,188,122,229,248,235,122, 25,226,174,152, 8,193,242,128,184, 44, 5,172, 88, 65,203,198, - 19,117, 45, 69, 65,109, 10,211,165,110,181, 8,199,162, 91, 43,105,237,218,181,165, 88, 45, 92,171,169, 5,153,104,205, 65,220, - 8, 58, 2, 14,200,150, 18, 19, 36, 41, 32,254,234,145,253,180,216, 85, 65,107, 75,186,209,141, 27, 55,232,204,182,245, 52,223, - 69, 65, 27,106, 23, 38, 38, 82,176,192,104,115, 29, 78, 96,130,179,174, 78,157, 58,171,249,158,136,153, 90,200,191, 67, 58,117, -234, 4,139, 85,147,154,166,138,151,116,122, 39,209,140,238, 84,205, 52,193,107, 62,150,132,221, 44, 8, 30, 14,225, 78,231,161, -166,114, 50, 17,147,162,158,121, 36, 87, 20,159, 79,173,204,163, 33, 24,222,156, 73,217,126, 14,136,150, 12, 21,236,194, 1,209, -130,101, 65,211,102,206, 49, 71,125,152, 64, 12, 25,207, 27, 91, 30, 30,178,101,233, 25, 19,194, 75,167, 78,158, 60,231,153,217, -237, 4,200,150,123, 74, 69,214,226, 54,166,123,162, 38,244,160,241,165,114,147, 91,170,239, 2,152,191,147,157, 63, 73,162,150, -197,147, 39,190,224, 99,146,240, 37,239,253,242, 38, 73,244, 31, 50, 49, 57, 93,215,164, 73,147, 96,144, 44, 4,235,115,192, 57, - 85,171, 86, 45,152,143,195,157,170,119, 43,152, 44,209,179, 79, 91,230, 17,181, 45, 24, 67,178,190,214,119,167, 35,213,189,233, -250,181,171,146,181, 4,214, 70,180, 31, 91, 81,162, 56, 0, 95,125,148, 96,204, 61,148, 68, 75,131,187,240, 12, 8, 22,167,101, -236,226,154,149, 53,107,214, 73,121,243,230,157, 52,110,220,184, 89,140,215,116,189,133,212,159, 33, 97, 17, 19,197,146, 99,109, - 42,209,135, 17,255, 81,149, 52,201, 49,157,130,198,141,201,233, 94, 38,253, 33, 28, 59,245,174, 97,195,134,111, 48,106, 21,122, -130, 61,126,227, 56,206,179,222,108,213,127,219,255,231, 80,139,201, 82,181, 98,245, 96,203, 86,204, 40, 94, 12, 6,224,248, 69, - 63,198, 97, 27,223,119,200,224,193,131,117, 17,173,148, 76,218,174,112,217,174,163,220,209,119, 99,206,159,251, 43,158, 31,108, -248, 88, 64, 76, 30, 8, 22,187,213, 37, 75, 38,199,128,105,116,109, 27, 82, 31,145, 87, 32, 32, 16, 16, 8,252, 44, 4,254, 2, -162,165, 30,167, 21, 27, 42, 85,191,168,146,104,129, 60,113,174, 24,162,245,126, 74, 79,122,223,178, 0, 93,168,229, 77,155,106, - 23,140, 69,180, 64,202,116, 17, 45,150, 83, 97,238,220,185,225,123,246,236,161,246,237,219, 75,137,173, 33,146,197,106,247,228, -225, 52,221, 89, 65,235,219,214, 38,196,153,236, 26,221,143,214,212, 44, 72, 71,150,206, 33,254, 98,255,156, 52,105,210,234,154, - 26,150, 45, 51, 83,217, 18, 48, 35, 87,174, 92, 83,248,124, 34,238,236,159,163,143,225,192,119, 16,173,132, 53, 76, 21,175,105, - 70, 15,105,244, 94,213,148, 10,116, 50,150, 21, 43, 86, 12, 97,130,128,243, 11, 53,201,100,247,202, 21,182,190, 72, 29, 20,255, - 15,171, 23, 2,191,147,246, 79,175, 56,126,113, 72, 43,234,109,163, 56,203,191,203,176, 59,112, 23,130,249,249,254,180,101,203, - 22, 88,191,190,242,113,213,145, 98,234,226,165, 81,135,236,134,218,202,193,240,119, 63,126,252,120, 9,110, 51,144,143,181,107, -214,156,131,101,139, 47, 72,208, 53,151, 91, 8, 77,236, 65, 77,221, 51,232,141, 39, 42,154, 44,209,246, 41, 37,115, 5,135,204, - 31, 74,116,100, 35,133, 76,235, 69, 19, 10,103, 9, 42,150, 60,209, 22,220,156,203, 95,155,203,117,132, 99,182,158,113, 39,123, -136, 73,130, 94, 75, 22,174, 75,148, 40, 81,165,156, 25,157, 66, 95, 44, 28, 77,212,166,128, 68,180, 62,212,201, 76,247,170,184, -208,172,166, 85, 99, 72, 22, 98,128,208,134, 72, 44, 27,214, 30,141, 27,136, 22, 70, 23,242, 73, 41,169,184, 11,183, 51,137,158, -207,238,194,209, 60, 56,160, 47,231,233,194, 3, 38,186,108,218,180,169, 47,143,148, 27,240, 35, 15,115,190,148,138,116, 69, 83, - 36,216,184,170,126,201,224,144,233,189,163,118, 52, 46, 77,133, 77, 20,195,117,200,172,204,109, 3,203,104, 23, 78,165,153,188, - 7, 64,151,176,199,111, 78,237,184,253, 14,241,222, 80, 43,227, 24, 4,190,171,196,101, 73, 69,128, 37, 11,207, 11,147, 74, 63, -214,215,115,236, 54, 28,194,135,235,243,126, 44, 99, 2, 87,183, 86, 11, 33,159, 43,198, 4,255,236,129, 3, 7, 46,243,255,192, -169,107,187,118,237,174, 47, 93,186, 52,128,201,234,103,190,254, 37, 91, 4,223,193,138,137,196,238, 69,105,207,207,135,222,216, -188, 31,193, 92, 92, 43, 16, 16, 8, 8, 4,126, 20,129,191, 54, 70, 75, 9,140,178,130,236, 50, 25,199,150, 33, 63,142,163, 58, -195,231, 98, 92,135, 61,188, 50,134,156,106, 85,150, 54, 84,205, 77, 13,211,167,138,229, 58,204,151, 47,223, 33,118,141,249,177, -149,103,166, 22,160,205,120,228, 93, 16, 92,133,236, 30,145, 70, 28,226,127,196,146,172,108, 85,147, 22, 87,202, 77,187,215, 44, -163, 5, 51,167, 83,187, 98,185,169,108,174,172,225, 14, 25, 50,188,225,206, 13,157,142,198,141, 71, 3, 14,102,162, 51, 40,103, -206,156,253, 57, 67, 34,118, 7,238,100, 55, 84, 72,169, 82,165, 64,164, 82,151, 73,174,168, 91, 43, 85,130,215,176,108,213,254, - 54,241,231,112,142,171, 82,198,104,181,213, 34,182, 8,187, 31,195,209, 49, 34,166,137, 99,186, 16,192, 31, 53,160, 82,177,240, -169, 61,219,211,188, 62,157,137,131,225,165, 32, 99,140,152,156, 55,111, 30,113, 80,114,216,232,209,163,175,178,181, 8, 49,106, - 58, 55, 38,177, 59,224, 70, 3,193,186,123,247,174, 31,199,106,249,113,135,233,199,157,224,126,107, 11,139, 85,206,182, 54,212, -179, 84, 65,202,156, 50,209, 26, 93,130, 10, 36, 73,212,100, 90,153, 60,193,116,116, 19, 15, 97,107, 44, 5,189,211,194,225, 20, -190, 96, 8, 13,207,237,250, 33,119,162, 68,141,245,149, 69,203,249,242, 62, 62, 62, 33,199,143, 31,167,166,149,203,209,219, 62, -181,201,191,102, 38,186, 90,209,153, 14,150,116,160,209,133, 51,209,137, 19,199,165, 0,107, 16,204,213,171, 87, 19,207, 93,166, -215,162,197,228, 41,134,104, 33, 38, 11,238, 66, 78,203, 64,178,216,229,213,133,201, 70,163,201,147, 39, 87, 99, 43,103, 53,198, -188, 17, 19, 67, 57, 43,161,103, 96,247,235,100, 78, 79, 57, 77,231, 0, 61,215,130, 73, 20,121, 10, 38, 87,244,110,224,148,246, -200,205,209,221,110,132, 46, 27,243,228,202,128,255,222, 85,178, 74,126, 59,151, 66,145,194, 0, 76, 16,155, 8,226,165,139, 60, -203, 17,151, 24, 46, 67,108,216, 43, 47,224,255,165, 15, 19,236,149,207,152, 28, 97,209,121, 90,178, 5,108, 37,147,171, 13,252, -123, 22,239, 47,115, 12,220,117,182,188,193, 53,232, 18,157,199,149, 7,116,188,227, 1, 45, 52,107,214, 44,226,152, 66,226,231, - 26, 68, 81,108, 2, 1,129,128, 64,224,143, 70, 32,158,146, 45,238, 98,164, 77, 57,159,150,222,121,180, 28, 56, 51, 2,103,247, -112, 66,160, 59, 54, 93,193,240,232,148, 96,253, 65, 48,175,141,182, 22,100,146,209, 11, 36, 6,177, 35,112, 57, 97,100, 84,183, -255,154, 70,150,201,100, 23,149,201,206,230, 35, 91, 94,110,219, 90,165, 89,156, 51,165, 52, 82, 48,131, 12, 77,104,202,193,190, -173, 89, 38,220,101,184,239,127,220,241,135,236,219,183, 47,132,173, 50, 24, 17,136,169, 29,176, 33, 30,166, 9, 91,199, 66, 56, -192, 61, 4, 29, 16,255,214,213,233,214,230, 64,253,247,187,118,237,146, 44, 86,234, 27, 38, 91,133, 21, 7, 35,189, 88, 78, 99, - 38,118,135,121,228,227, 97,158, 91, 12, 29,159,206,141, 9, 65, 63, 30, 73,121, 30,164,116,199,142, 29,126, 43, 87,174,244,107, -219,182,237, 21,238,112, 63,113, 60, 85, 20, 98,107, 46,113,124,152,135,187, 59, 70,165, 57,105, 19,198,110,219,179, 65, 11,134, -211,231, 17,205,232,115,117, 7,137,104, 5, 79,234, 69,254, 29, 75,211,237, 14, 21,168, 68,242, 68,167,244,149, 69,211,121,182, -234, 96,110, 52,105, 14, 38, 88,172,154, 48,217, 58,213,178, 52,113,192, 27, 45, 43,230, 76,147,202,102,167,114,197,124,164,206, - 27,238, 72,182,172, 68,113,157,244,198,104,241, 20, 3, 18,209,226,118,145, 2,223, 89,254,182,167, 79,159,206,228,182,232,195, - 86,152,134, 76, 86, 75,150,112,118,234, 83, 42,181,201,237,210,102,201,239,185,167, 74,137,249,186, 84,231, 79,139, 85, 92,115, -198, 38,147,171,107, 48,187,196,162, 48,104,129, 93,164, 81,158,238,153, 63, 79,172, 91,126,195,195, 5, 99, 54,124,222,181,116, - 79,232,150,121, 39,214, 53,175,124,185,120,202,132, 75, 11,154,198, 76,199, 17, 23, 88,112, 13,116,124, 51, 39,229,168, 67, 12, -166,216,162,242, 91,147, 92,105,114, 82, 13, 22,173,132,106, 68,203,160, 50,113, 12,101,247,173, 91,183,250,114,108,220, 56,142, - 27, 91,192, 22,194, 29, 76,178, 46,179, 16, 76,156, 10,204,176, 58, 66, 21,182,102, 6,176,245, 20,147,205, 98, 66,221, 96,182, - 12, 27, 58, 98,210,160,114,137,204, 2, 1,129,128, 64,224, 31, 70, 64, 61, 54, 75,142,177, 64, 49, 18, 83, 54, 68,207,161,213, - 78, 7,120,173, 49, 5, 4,166,130,224, 60,170, 49, 40, 26, 47,225,121,135, 54,193,109,200,115,105,133,176, 5,104, 83,146, 68, -137, 90, 58,240,200, 48,206, 28,151,161,238, 62,108,161,170,198, 22,178, 74,124,125,126, 78, 73,120,196,221, 11, 38,113, 33, 76, -124,164,217,224,153, 4,188,198,196,165, 28,184, 30,194, 95,253, 33,221,187,119,135,181, 75,142, 11, 45, 57,231,235,192,238,201, - 77, 28,215,117,121, 96,213,146,225,227, 58,183,164,166,110,214,184,126, 6, 39, 88,218, 44,112, 79,118,177, 30,224,216,152, 61, -124,159,185, 50,148,204,142,137,197, 65, 38,132,231, 49, 81,103,175, 94,189,206, 51, 1,125, 6,146,197,211, 63, 16, 91,186,164, - 32,115, 38, 97,145, 76,122,180,198, 41,249,152, 36,122, 73,123, 87,104,156,194,225,233,128, 70, 84, 56, 89, 66,173,241, 72,186, -202,200, 86,194,119, 8,162, 7, 17,134, 91,119,195,134, 13, 84,190, 80, 62, 90,211,182, 38,173,248,175, 26,141, 47,159,143,242, -167, 78,254, 49,125,234, 84,231, 57, 62,232,181,220, 81,135,152,132, 84, 57,186,144, 9,128, 31, 19,172,141,140,215, 36, 38, 12, - 93, 96,201, 2,201, 26, 85,174,208,167,208,253,235, 40,120,237, 12,234,155, 59,243,103,149,193, 22,223, 21,217, 62,109,154,229, - 71,120,182,122, 37, 9, 6, 65,221,188,105, 19,213,173, 80,230,242,135,221,171,230, 31, 27,210,113,117,247,220,153, 55,243,220, - 90, 32, 72, 90, 9,155, 82,112, 46,142,135, 43,106,150,112,102, 69,199, 52, 47,125,204, 19,206, 40,144, 58,214,242, 82,117,217, -234,118,159,239,245,146, 9, 33, 6,102,172,192, 94,229,119,115, 45,152,198,140, 56, 84, 25,105, 8, 61, 31,204,177,138,146, 69, - 11, 46, 68, 92,155,195, 84, 97, 85,204, 60,225,252,170,174, 54,111,177,199,111, 77, 50,157,146, 42,220,125,172, 83, 30,171,230, -102, 27, 92,220,222,252,232,138,197, 11,199,177, 59, 28,241,113,208,149,225,172, 75,199,234,215,175,127,125,217,178,101,215, 89, -231,195, 48, 24,130, 39, 88,253,200,131, 84,116,185, 77,101,168,173,200, 34, 16, 16, 8, 8, 4, 4, 2, 58, 16, 80,183,100,201, - 34, 90, 85, 48, 9, 41, 58,131,232,185,180, 52,185,162,170,130,136, 33, 79,244,236,240,234, 19,152,105,154,208,204,151,103, 24, - 39,126,241,195,250, 21,151, 77, 85,102,250,234,213,171, 23, 96, 11, 73, 94, 38,110,121, 89, 24, 44, 87, 14, 76,174,238,179,165, - 40, 4,147,152, 34,206,134, 59,225, 16, 38,130, 33,108,165, 2, 73, 82,126,245,171,222, 91,239,196,107,136,209, 58, 55,240, 63, -194, 94,173,208,141,120,152,253, 46, 14, 60,222,198, 49, 81,189, 85,206,233,146,233,192,214,187,193,176, 30,113, 89,251,243,254, - 37,226,194, 64,178,224,146,131, 5, 2, 35, 25,249,248, 51,181,123,197,200, 44,149, 34,241,233,247,227, 58, 80,212,162,145,244, -117, 90, 63,137,112, 5, 78,238, 75,111,102, 13,165,115,173,202, 81,241,228,137, 78,202, 4, 55, 86, 57, 65,156,216,205, 23,197, -110, 77,130,249,150, 9, 31, 6, 6,144,187,157,237,151, 2,201, 18,250,251,152, 36,222, 19,151, 9, 75, 65,180, 96,201,226, 32, -109, 63, 38,174,126,236,106,222,200,174,233, 73,136,201,130,187, 16,150, 44,144, 44,234, 85,129,168, 67, 17,186,215,178,184,106, - 12, 32,170, 18,123, 18, 84, 27,155,103,202,217,218, 57,222, 77,138, 65, 66, 92, 93,122, 43,171,160,162, 41, 18,181,230,120,172, - 98,133,121, 57, 35, 61, 24,196,200, 44, 97,158,112,241,233, 89,163, 35, 63,237, 90, 70,171,154, 86,136, 40,110,145, 80,213, 5, -190, 6,164,138,173, 66, 15,177,103,242,249, 20,123,142, 75,148,126,243, 61, 48, 24, 67,185,197,200, 84, 11,132,199, 32, 4,144, -172, 14,202, 32,120,236,249,183, 52,137, 42,147,171, 37,103,230,142,143,250,178, 99, 9,173,107, 81, 41, 18,191, 53,201, 44, 97, -145,120,219,133, 69,147,233,235,158, 21,180,169,115,195,200, 34,233,205,142, 48, 9, 28,223,165, 75,151,141,172, 51, 87,216, 2, -123,157, 9,242,117, 94,126,231, 58,175,123,120,156,137,215,101,254, 88,208,228,126,215,171,243, 50,245,199,160,231, 72,200, 52, - 8, 1,209, 70, 6,193,165, 55,179,192, 83, 47, 68, 6,101,248, 25,120, 26, 84,128,191, 37,115, 3, 16,168,104,107,213, 14,182, -196,236,226, 81,121,126, 72, 60, 55, 21,102, 65,223, 6,171,215,160, 65,131,208, 97,232, 91,130, 71,137,137, 49,137, 22,100,230, -229, 14,214,145,201, 14, 92,141,152,177, 29, 27, 8, 87, 23,182,158,157,224,209,107, 33, 28, 55,134,121,184, 48, 27,188, 54,159, -169, 94,133,209,178, 4, 79, 5, 30, 29,182,131, 9,196, 22,238, 52,225, 54, 84, 13, 96,214, 43, 83, 9, 8, 44, 87, 60, 8, 32, - 18, 83, 68,128,216,192,138,196,228, 67,147, 69, 43, 70,102,190,164,137,234,141,204,155,233,195,231,105,221,233,109,219, 98,148, - 52, 81, 34, 10,152, 49,132,174, 52, 46, 64,109, 29,204, 62,228, 73,148,168,174, 76, 37, 84, 47,167, 27, 91, 5, 67,121, 90,131, -168,109,219,182, 17,147,108, 76,175,129,117,254,138,201,148,135,108,177, 73, 17, 7,195, 51,233,149,150,214, 65, 98, 43, 36, 92, -166,219, 38, 77,154, 52,147,221,199,125, 56,190,173, 33,220,133, 31,230, 12,166,200,214,249,233, 69,173,204,116,176,176,181, 78, -162,197, 68,117, 2,187, 13, 35,225,226,228, 24, 55,226, 25,255,137,219, 32,202, 58,109,218, 57,113, 41,103,101, 23,235, 15, 95, -214, 76, 38,170,237, 68, 47,170, 56,147,143, 89, 66,140, 82, 85,110,188, 54,181, 98, 19,167,121,106,150, 44,204, 53,135,227,170, - 11,138,199,212, 29, 11, 68, 51, 17,195,146, 58, 24,216,160, 92,246,105, 49, 31,219,198,101,199,188,115,112,207, 75,150,220,202, -206,214,129,159,215, 78,149,238,255,188,178, 19, 21, 78,157,224,189,202,253, 99,100, 86,117,183, 15, 13, 91,135,124, 25,233,121, -231, 10, 84,202, 42,249,123,142,215, 26,202,115,143,173,100, 66,124,142, 73,215, 5,190, 14,107,144,214,139,126, 14,180,193, 33, - 91, 63,227,130,167, 1,215,232,203, 42,202,169, 15, 33,195,206, 11, 60, 13,195, 75, 95,110,129,167, 62,132,254,157,243,234, 35, - 14,245,198,104,169, 66, 3, 69,130, 75,112, 54,199, 67,197, 12, 71,199,255,124, 12,157, 26,230,142,210,230,138,211,164,132, 3, -163, 45, 90,114,220,108,154,154, 72, 93,102,114, 30,117,152,130, 93,119, 24, 29,169,169, 98,122,221, 70,124,157,222,135, 69, 19, -209,226, 78,109, 10,187, 35, 55,242,168,174,117, 28,123,164, 30, 52,173, 87,166, 74,229,156,216,250,241,158,201, 71, 20,172, 72, - 28, 92, 30,201, 35,199,208,209, 58,169, 1, 16, 75, 38,143, 58, 92,223, 51,139,125,208,249,198,108, 1,234, 82,149,142, 53, 42, - 78,173,237, 83, 5, 21, 77,158,104,173, 1,186,173,169,156,110, 28,156,191,136, 9,106, 16, 91,233, 48,151, 90, 33, 3,228, 33, -107, 44,153, 24,197,138,145,135,170,137, 45,144, 27,153, 44,205, 96,139,222, 64,182,162,181,113, 77,158,108,114, 23,119,187,207, -151,171,123,210,126, 38, 89,141,172,146,169,187, 14,213,203,105,203, 36,250, 45,147, 54,137, 16, 34, 86,140, 71, 42, 6,105,192, - 76, 87,209,255,111,209,178, 72,180,118,125,205, 2, 81,254,149,236,105, 76,150,212, 81, 37, 44, 19, 45,214,114, 33,226,156,182, -112,210, 54,225,109,140, 76, 30,249, 55,135, 73,213, 98,142,209,130, 44,229,135, 72, 25, 94,139,115, 8, 31, 31,130, 61, 31, 47, -135,251, 20, 53, 79,184,124, 69,181, 60,145, 47, 42,218,209,232, 44,169, 34,241, 91,229,254, 49, 50, 75,165, 73,188,121, 75,203, - 74, 81, 47, 91, 22,166,193,110,166,145, 5,210,152, 28, 96,139, 21, 70, 74,194,226,156,143, 19, 38,237,149,179, 25,162,159,114, -228,125,215,238,114, 47,210,147, 79,148,211, 72, 64, 70,139, 17,120, 10, 60,141,133,192,207,208, 37, 99,149,237, 79,144, 35,203, -117,168, 94,208,244,108,121, 89,196,147, 74,174,115,114,114, 90,199,195,249, 17,172,140,160,121, 89, 29,153, 74, 38, 87,142, 79, - 9,226,142, 60, 71, 28,145,208,212,184,233, 88,150, 61, 39,245,133,115,229,222, 66,175,194, 12,179, 85,116,188,211,187,238, 37, -236, 85,132,230, 99, 11, 7,136,166,166, 33,255,122,101,170, 21,206, 9,150, 45,184, 11,163, 99,179,156, 52, 20,254, 59,153,108, -185,106,200,129,239, 39, 11, 37, 75,248,170, 68,242,196, 39,242, 38, 74,164,201,178,104,104, 27,201,197, 77, 91, 62, 67,235, 14, - 57,186, 6, 91,104,235,196,165, 81,135,140,215, 11,140, 58,228, 76,154, 48,147, 85,247, 28, 41, 20,182, 37, 45, 18,109, 46,148, - 58,193,199,146,230,137, 54,228, 73,169,125, 80,135, 1, 58,159,139,173,108,205,152, 84, 53,227,121,228,106, 71, 95, 7,226,159, - 13,243,100,241,241,202,202, 25,224, 49, 29, 69,113,139, 68, 43, 11,155, 37, 8,196, 30,191, 85,238, 19,131, 39,202, 89,130, 73, - 33,242,113, 76,217, 74, 71, 19,105,121,169,184,108,113,105, 35,125,247, 17, 50,245, 33,100,216,121,129,167, 97,120,233,203, 45, -240,212,135,144, 97,231,127, 6,158,134,149,224,207,206, 29, 39,162, 21,151, 42,253,140,134, 16, 50,227,210, 18,218,175, 17,120, - 10, 60,141,133,128,208, 37, 99, 33,249, 77,142,192, 83,224,105, 44, 4,226,139, 46, 25,171,190,191, 67,206, 15,185, 14,127,164, -192,241,165,113, 69, 57,127,164,149,191,191, 86,224, 41,240, 52, 22, 2, 66,151,140,133,164, 32,111, 66,151,254,124, 93, 50,110, - 9,255, 32,105, 80, 62, 77,201,144, 34,106,147,161,235,184, 62,249, 66,166,230,118,137,107,123, 9, 60, 5,158,114,117, 64, 60, -155,186, 45,192,114,113, 84,230, 19,120, 10, 60, 53, 33, 96,168, 30,201, 33,138,241, 69,166, 18,143,184,246,103,250,158,169,127, -234,188, 28,197, 48, 20, 16, 33,211, 80,196,116,231, 23,120, 10, 60,141,133,128,208, 37, 99, 33, 41,172, 79, 66,151,254, 77, 93, - 50,110,173,255, 17,105,226, 97, 49,110, 67, 11, 60, 5,158,198, 66, 64,232,146,177,144, 20,164, 72,232,146,208, 37,227, 34, 16, - 63,165, 25,182, 4, 79,226,124, 35,252, 21,185,124, 9, 9,255,243,108,152, 9,117, 37,158,180, 10,243, 12, 97,193,218, 39,209, -255,171,154, 5,165,255, 89,206, 62,150,231,135,132,255,245,202, 84,203,175,130,123,204, 67,205, 50, 18,105, 40,107, 34, 28,151, -147, 52,201,252, 25,229,140, 47, 50,141,168,219,241,238,197,155, 36,255,255,117, 30,255,235,211, 31,245,252,154,116, 73, 53, 79, -202, 34, 99,222,100,175,191,168,159,174,100,234, 51,246,141,242,185,147,174,253,255, 22,131,167,161,207,102, 6, 91,219, 50, 60, -178,241, 9, 18,254,255, 85, 58,111,128, 46,229,225,188, 91, 57, 29, 81, 73, 83, 52,149,211, 0,153,250,178,198, 59,253,212, 87, - 33, 3,206,139,186, 27, 0,150,140,172, 2, 79, 25, 32,253, 35, 89, 12, 92,130,135, 9,150,223, 19,162, 35,119,136,137,214,112, -114,169, 62,119,181,122,114, 44, 55,122, 83,106,187,108, 15, 44,172,157, 2,249, 37, 30,179, 20, 74, 52,225,250,142,104,129, 96, -177, 76,191,163,119, 73, 34, 91, 60, 47,132,133, 73,210,164, 35, 44, 45, 45, 79,241, 44,241, 33, 72,210,255,124, 12,231,212,243, -107, 35, 90,232,152,148,101, 77,148,119, 56,121, 84,159,219,205,173,234,236,190, 41,210,103,219,157, 32,177,201,126,158, 92,171, -154,175, 66,145, 84, 83,199,169,241,101,174, 90,206,236,125, 47, 50,113, 44,157, 50,121,242,222,246,118,118, 59,184,158,143,120, -254,167,199, 86,188, 48,116,210,196,137,123,227,156,130,243,168,214, 75,175, 76,150, 95,155,203,195,179, 87, 54, 52, 75,149,106, - 33,215,249, 54, 18,254,199, 49,156,147, 83,119,245, 60,250,136,171, 44,153,198,123, 26,226,223,203,135,245,232,193, 27,162, 27, - 47,137, 76, 10,142,162,108, 13,151,174, 65,114, 47,213,245,136, 93,134,140, 95,144, 50,151,232,124, 68,121, 60,121,161,209, 49, -249, 37,114,164,129, 20,225,184, 82,102,222,150,107,104,195,185,240,161, 72,173,122, 79, 94,235,236,226, 22,130,132,255,149,199, -145, 71,153, 95,151, 76,253,207,230,216,141,102, 25, 11, 95, 51,177,116,126,206,243,179,197, 44,214, 9,178, 37, 71, 63,121,158, - 20, 75,158, 69,117, 80,226, 68,137,246,243, 82, 73,239,177, 54,104,146,196,137,247,225, 24,206, 25, 89,151,150,171,175, 37, 26, - 77,184,190,127,135,252,203,250, 41,234,110, 12, 4,226,223,123,201, 24,181,254, 38, 35,190,212,221,120, 53,254,245,146, 12, 92, -130,135, 59, 8,144, 44,223,237, 68,165,186,110,167,117,231,163,118,168,166,218, 45,135, 92,243,246,206, 22,137, 25,185,177, 46, - 30,207,106, 30,243,174,212, 69,180, 64,178, 88,166,159,194,185,246, 93, 94, 83,239,237,236,217,179,195,121,233, 26,194, 82, 42, - 95,191,126, 37,204,140,206, 51, 92,135,227, 28,242,196,228,135, 37, 76, 67, 71, 6,242,132, 14, 73, 89,214,236, 77, 86,196,116, -102,110,238, 94,111,121,109, 61,194, 2,201, 37, 74,148,120,195,157,196, 48,158,152, 40,163, 42,225,210,214,233,224,190,255, 77, - 56,125,195,220,218,225,107,199,142, 29,131,148,179,164,243,108,222,116,252,248,113,226,245,249,104,248,240,225, 81,149, 42, 85, - 10, 78,102,154,230,235,236,117,167,111, 72,245,210, 82, 78, 28,143,169,139, 71,171, 27,188, 70,224,157,102,205,154,125,218,189, -123,183,180,158, 32, 18,254,231, 53,233, 62,225,156,130,243,232,171,123, 44,153, 44,223, 68,161, 40,146, 62, 93,186,185, 60,171, -251, 41, 38,131, 79,145,240, 63,142,225,156,122,126,141,117, 55,158, 98,198,151,135,250,255,229,100, 61, 2,201, 90,199, 83,242, - 86,238,187, 55, 70,231, 51,186,184,125,229, 73,105, 9,203,252,216,103,112,140, 88,119, 54, 66,122, 22,144, 71,153, 95, 23, 41, - 82,230, 73, 90, 96, 36,121, 86, 30, 55,212,220, 33,207,190, 84,169,205, 34,148, 15, 76,106, 51,179, 8, 28,195, 57,182, 98,201, -146,169,235,217,108,222, 99,234,197, 82,165,203,134, 97, 9, 37, 60, 83,231,206,157,139,121, 54,117, 17,173, 24,125,115,169,123, -151,243,189,228,245, 39,233, 34, 47,110,126,239,222, 61,226, 5,208,165, 61,175,190, 64,188, 78,229, 75, 5,231,209,171,159,242, -117, 41, 59,103,125,209,188,117,103,218,176,235,184, 84, 86, 65,180, 98,192,139,127,207,145,252,118,215,151, 83,212, 93, 31, 66, -134,157,143, 47,120, 26, 86,171, 63, 39,183,225,115,102,193, 61,145, 52,255, 72,137,100,165, 46, 58, 62, 80,213,154,101,238, 90, -234, 18,147, 4,105,225, 99, 44, 60, 12,210,129, 5,115,121,145,100, 98,146,240, 89,175,235,208,165,254,157,204, 30, 94, 17, 79, -159, 62, 37, 44,120,139,151,247,132, 9, 19,136,215,102,163, 45, 91,182, 16,142, 35,185,185,123, 70, 40, 56,175,210,213,168,141, -104,161,172,176,186,129,100,165, 44, 50, 54,208,189,250,156,158,176,104, 37, 76,106,250, 18,242,158, 61,123, 70, 88,112,248,245, -235,215,196,147, 68, 70, 37, 78,150,118,178,146,108,105,146,169,116,243,165,181,207, 18,122,225,194, 5, 90,178,100, 9,229,207, -159,159,120, 22,114,226, 53,250,136, 23,170, 38, 94, 68,154,120,217, 33,105, 61,194,185,115,231, 82, 82, 51,251, 80, 93,229,140, -113, 29,186, 53,187,101,149, 46,125,196,177, 99,199, 98, 44,128,234, 95,243,135, 14, 29,138, 66, 30, 5,231,149, 37, 51,115,139, -155,105,237,221,131,120, 33,225,247,232, 92,121, 45,193, 24,145,104, 35,116,150, 76, 8,223, 33,143,130,243,234,146,105, 68,157, -141, 47, 15,117, 76, 57, 85,221,124,169,139,142,123,167,180, 92,217,218, 59,126, 5,201,194, 7, 5, 47,139, 68,102, 25,114,221, -197,185, 84, 69,199,190,213,231,230, 83,149,153,216,189,201,123, 37,129,193,179,162,220,240,252, 40, 9, 12,242,232,147,169,235, -217,180,244,168,124, 22,171, 46, 96,221, 76, 44, 80,142, 53, 51,241,108,214,171, 87, 47,138,159,205,247,122, 93,135, 76,160,138, - 20,241,137,130, 94, 67,111,248,121, 33, 94,223,145,234,212,169, 35,213, 29,207, 18, 82,249,242, 21,162, 64,182,140,160, 75, 88, -126,104, 81,191, 33, 99,233,214,179,143, 4,178, 37,136, 86,172,167, 48,222, 61, 71,255,242, 59, 68,212,221,136, 8,196, 63, 81, - 74,107,150,246,146, 99,217,151,232, 84, 12,185,224,134, 2,185,194,151, 59,246, 74,183,148, 25, 91,132,114,230,204, 25,142, 14, - 28, 86,172,246,237,219,127,156, 58,117,234, 33, 94,159,111,125, 68, 88,216, 2, 59, 91,219, 9,200,171,233, 78, 56,238,164, 80, -152,167, 76,153, 50,224,201,147, 39,180,115,231, 78,169, 19, 88,177, 98, 5,237,218,181,139,246,239,223, 47,237,209, 9,241,250, -137,210,226,202,108,217, 10,192, 53, 58,100, 74,177, 88, 32, 87,112,191,192,109,136,223,150, 10, 69, 22, 46,103, 36,175,163, 71, -188, 68, 11, 45, 93,186, 84,146,249,230,205, 27, 74,108, 98, 26,160,129,104,197, 20, 89, 89, 87,182, 6, 5,160,158, 14, 14, 14, -196, 75,156, 16, 91,136,200,221,221,157,120, 33,100,170, 80,161, 2, 53,108,216, 80, 34, 91,200,147, 60,121,242,152, 56, 54,109, -117,231, 40,185, 20, 92,159, 39,126,126, 88,197, 72,243,198,235, 1, 74,101,220,179,103, 15,234,254, 4,215,232,194, 51,133, 66, -145, 59, 91,182,108, 1,184, 6,157, 43,112,189,122,245, 42,221,188,121, 83,250, 31,242,148, 27,240,100,178, 24,128,107,180,201, -140,127,186,109,188, 18,107,139,201,114,180,177,169,192, 75, 7,125,194,250,147,207,159, 63,151,136, 55, 43,248, 72,245,252, 90, -218, 93,210, 79, 94, 19,167,108,145, 34, 69, 34,149, 4, 6,235, 71,150, 43, 87,142, 9, 75,121, 26, 50,100, 72, 12,129, 97,189, -138, 68, 94,125,250,169,233,217, 52, 87, 40, 28, 43, 87,174,252, 9,122, 0, 11, 41,175, 75,250,140, 93,209,141, 76, 21, 10, 47, -126,168, 77,148,122,173, 77, 63,225, 18, 4, 17, 68, 25, 55,110,220, 72,188,250, 67, 0, 95,223,156,159,121, 23, 36,252,207,171, - 66, 4,224, 60, 72,167,163,163,227, 75, 92,243, 3,186, 20,139,100,129,108,113,217, 56, 96, 65,178,104, 97,217, 39,177, 9, 4, - 4, 2,255, 24, 2,234, 92,228,175,170, 62, 42,135, 10, 41,247,218,136, 86,146, 68,137, 86,195, 93,248,242,229, 75,106,221,186, -117,208,145, 67,135, 22, 93,185,116,105,222,205,235,215,231, 69, 70, 68,204,211, 71,180, 82,152,152, 12,225, 47,238,112, 88, 94, - 64,178, 64,182,120, 65,104,201, 29,119,230,204, 25,130, 5, 9,132,104,239,222,189,210, 61,134, 13, 27, 22,134,107,244, 17, 45, - 88,176, 64,180,176, 79,162, 80,180,203,155, 55,111, 40,172, 89,248,162, 7,121,219,180,105,147,180,232, 48, 58, 74, 51,203,116, -239,245,117,100,184, 31, 19,172,183,176,132,193,101,210,171, 87, 47,170, 89,179,166, 68,178,202,150, 45, 75,125,250,244,161,101, -203,150, 73,150, 55,184, 38,121, 77,192,215,250, 58,178,100,137, 19,247,234,214,173,219, 23, 93, 36,235,197,139, 23,196,107, 54, - 74,169,121,243,230, 95,112,141,182,186,167, 81, 40,236,120,173,197, 23,112,187,194,122,177,112,225, 66,154, 50,101, 10,141, 29, - 59,150,198,143, 31, 79, 51,102,204,144,234, 12, 75,158,114, 3,190,188, 64,244, 43, 92,251, 87, 41,176, 17, 42,163,141,104,225, - 56, 71,144,167, 52, 73,150,236, 40,175,239, 41, 89, 71,199,140, 25, 67,108,185,237,169,122,141, 54,162,229,174, 80,164, 81, 39, - 48,172,163, 45,172, 20, 10, 87, 36,252,175, 78, 96,112, 13,100,107, 35, 69,154,136, 22,179,150,137,112,195,243, 2,231,228,236, -236,124,207, 83,161, 48, 85,234,164,234, 94,155, 76,196, 95, 65,127, 96,201, 2,201,226,178,217,168, 95,143, 99, 32,235,176,240, -225,153,194, 53, 6, 18, 45,213,192,247, 87, 74,119, 97, 52,201, 90,196,101,195, 90,141, 88,227, 81,185, 56,188, 17, 90, 86,136, - 16, 8, 8, 4,226, 11, 2,234, 92, 36,190,148, 59,186,156,186,221,135,114, 45, 90,220, 73,223, 15, 8, 8, 32, 88,138,152, 48, -237, 3,201,226,206,103, 30,127, 65,207, 99,139,150, 94,162,197,139, 11, 31, 7,201,130,133, 9,150, 44, 16,161, 19, 39, 78, 72, -214, 49,188,224,175, 93,187, 38,185, 19,177, 71,167,134,175,103, 92, 35,135,104, 77, 88,126, 97,146,185,181,211,253, 37, 75, 22, -115, 76,201, 67,186,116,233,146, 68,220, 16,163, 2, 34,119,250,244,105, 66, 71,148, 44,149,245, 35, 57, 68,139,215,166,139, 97, - 40,136,209, 9, 14, 14,150, 98,201,144, 64, 94, 96, 33, 98, 75,158,228,242,148, 99,209,226, 0,250, 35, 32,147,154, 54, 16, 37, - 16, 75, 16, 44,224, 1,235, 30,199,170, 17,174,209, 86,119, 14,208,239,194,184, 73,177, 62,161,161,161,132,152, 26, 38,114, 84, -189,122,245, 79, 5, 11, 22, 12,102,139,201,199,182,109,219,126,226, 14, 81,114, 83, 34, 94, 13, 24,183,108,217, 50, 60,121,178, -100,221,227,153, 2,255,244,226,234, 34, 90, 56,199,214, 69, 51,179,212,169,253,208,238,104, 47,118,199, 69, 70, 91, 7, 37,171, -149, 54,162,197,132,108,176, 42,129,113, 84, 40,210,171,223, 11,199, 84, 9, 12,174, 49,148,104,241,218,161,199, 81, 46, 88,163, -184, 48, 53, 52,145, 44, 29,207, 81, 66, 14,124,223,135,103, 6, 22, 54, 88,175,180, 93,143,115,208,121,232, 28, 2,228, 13, 36, - 90,223, 5,190,131,108, 49,118, 32, 89, 26, 45,225, 63,189,225,197, 13, 4, 2, 2,129, 63, 6,129,120,110,209, 82, 95,130, 39, - 54,241,146,107,209,242,246,246,254,130,151, 57, 58,142, 35,135, 15, 47,191,195, 36,235, 33,147,172, 23,207,158,201, 34, 90, 76, - 72,130,241,130,102,119,163,100,181, 58,121,242,164, 68,132,240,130, 7,201, 0,201, 66,224, 45,220, 94,248, 31, 22, 30, 92,163, -143,104,217,229,107, 55, 57,119,158,188, 95,224, 50, 3, 33,194, 87,253,187,119,111, 37, 11,214,245,235,215, 37,121,236,238,136, - 98, 87, 39, 89,186,150, 89, 35,135,104,177, 21,194, 95,149, 20,193, 69,136, 96,125,148, 21,101, 71, 92, 13, 91,220,136, 23,200, - 38, 30, 49,169,215,117,200, 86,175, 32, 77,110, 67, 85,146, 5, 60,208, 22, 43, 87,174,164,254,253,251, 67,174,214,186,115, 80, -242, 49, 92,171,220,142, 30, 61, 10,203, 90, 56,119,132, 85,184,117,147, 32,225,255, 68,137, 18,133,131,176, 2, 3,184, 81, 33, -151, 59,229,179,127,204,147,245,135, 20, 68, 31,209,194,121, 87,133,194,138, 23,176,190,143,216, 68,196, 42, 49,241,186,232, 27, - 61,162, 85, 43,209, 82, 33, 48,176, 94,105,187, 15,206,169, 17, 24,131, 44, 90,236,134, 12,194,179,133,184, 42, 94, 89,221,214, - 80,162,133,145,133,112, 57, 34,254,208,140, 93,133,218,174,199, 57,196,104, 98,203,158, 61, 59,172,195,134, 16,164,236,140,147, -122,224,251, 43, 65,178,254,144,135, 64, 20, 67, 32,240,155, 17,248,235, 45, 90,192, 87,159,235,144,227, 62, 36,162,133,128, 91, -182, 16, 45,127,252,240,161, 68,178, 56, 70, 72, 54,209, 66,220,208,188,121,243, 8, 35,248,224,118,187,114,229,138, 68,178,224, -162, 3,145, 1,185, 66, 71, 6,146,132, 36,135,104, 37,183,112,186, 48,103,206, 28,122,248,240, 33,199, 56, 5, 72,214, 27,116, - 58, 72,176, 64, 33,110, 41,179,187,215,167, 74,245,187,110,131,123, 49, 46, 68, 11,113, 80, 32,109,112,117,194, 37, 7, 11, 18, - 98,109, 16, 36, 44,135,104,113,158,143,112,183,128, 68, 65, 22, 54,148, 13,117, 69,253, 65,178, 96, 33, 3,137, 69,252, 14, 91, - 76, 32,247,163,182,142, 76,157,104, 65, 30,151, 45,170, 84,169, 82, 1,112,253, 32,225,127,150, 25, 5, 23, 39,240,238,220,185, - 51,177,149,139,204,204,204,206,253,230,231,233,143,187,189, 28,162,133, 60, 60,130,211,135,221,186, 81,208, 49,232, 49, 19,164, -102,186, 44, 90,170, 4, 6,174, 66,109,247,193, 57, 53, 2, 99, 16,209, 98,157, 9,194, 64,136, 1, 3, 6,196,137,104,101,201, -146,229, 61,200, 56, 2,223, 13, 32, 90,129, 6, 16, 45, 57,129,239,127,156, 94,136, 2, 9, 4, 4, 2,191, 14,129,120, 78,180, - 12, 3, 10, 47, 79, 77,113, 32, 86, 86, 86,247, 65, 18, 16, 91,181,110,221,186,125,236,238,154,247,142, 73, 86, 72,112,176,172, - 24, 45,184, 1, 65,168, 16, 55,133, 88, 47,144, 44,184, 8,241, 37,141,151, 60,220,103, 8,180, 69,130, 85, 10,174, 69, 57,174, -195,164, 41, 82,191,135,181, 8,174, 66, 36, 16,174,192,192,247,146,139,167, 71,143, 30,145,252,134,159,150,177,228,208, 97,202, - 56, 46, 99, 18,173,209,163, 71,203, 34, 90,108, 9, 57,137, 50,162,174, 32,133,136,243,106,213,170, 21, 53,104,208,128,106,212, -168, 33,197,126, 21, 43, 86, 76, 10,144,238,217,179, 39,166,143, 32, 92,163,173, 35,131,235,144, 93,145, 49,211, 4,104,114, 73, - 34,150, 6, 22, 66,184,122, 57,166,142,218,180,105,131,123, 68, 36, 75,146,164,155, 97, 26,241,247,231,150, 75,180,144,143,245, -105, 1,220,221,176,160,242,255,235,116, 17, 45, 85, 2, 99, 0,209, 2,129, 49,136,104,241,168,194,227, 32,127,176, 90,198,197, -117,200,110,192,253,112,173, 67,159, 13,112, 29,238,151, 73,180, 68,224,251,223,255, 8,137, 26, 10, 4,254,117, 4,116,187, 14, -213,209,209, 70,180, 56, 24,126, 13, 70,196, 33, 70,137, 93,102, 65, 47,158, 63, 95, 4,146, 21,246,229,203, 60,138,140,212, 27, -163,133,192,118,204,157,229,239,239, 79,155, 55,111,150, 44, 57,120,185,195,226,130, 99,239,222,189,147, 8, 22, 58, 12, 4, 29, -119,234,212,233,171,156, 96,248,196,201, 76,223, 32,254, 8, 73, 73,182, 96, 13,195,168, 64,158,176,180, 30, 58, 45,213,128,249, -223, 65,180,184, 30,195,134, 14, 29, 26, 6, 66,132,249,141, 80, 95,116,212, 60,213,131,228, 46, 68,204, 26,207,215, 69,156,135, -198,141, 27, 7, 2,134,129, 0,195,180,117,100,202, 96,120,144, 41, 88,198, 96,205, 0,118,112,113,162,125, 16,151, 54,107,214, - 44,226,121,192,136,167,126,160, 38, 77,154, 32,192, 30, 83,112, 4,136, 96,248,239,223, 7,134, 16, 45, 30, 25, 88, 30, 83,146, - 0,103,182, 44, 74,163, 88,181,185, 14, 85, 9,140, 1,174, 67, 16, 24,131,136, 22,130,225,161,251,208,123, 46, 83,156,130,225, - 49,162, 18, 22,101, 4,231,107, 11,134,207,148, 41,147,220, 96,120,213,192,247, 39, 34,240,253, 95,239,131, 68,253, 5, 2, 2, -129, 88, 8,104, 35, 90,236, 82,200,232,229,229, 21, 6,171, 22,130,130,217,133, 24,194,177, 65,135,158, 61,121, 98,240,244, 14, -184, 30, 36, 3,193,241, 74, 75,214,251,247,239, 37,194, 16, 25, 25, 41, 5,200, 99, 42, 8, 39, 25,211, 59, 36, 72,156,252, 0, - 2,193,217, 66, 22, 5,242, 2,194, 5, 34,195, 83, 36,248,207,229, 88, 37,116, 90,152,250, 1, 22, 45, 76, 5, 33,147,104,189, - 82,181, 18,105,114, 29, 34,112, 56, 58, 70,235,149, 50,166, 69, 75,135,155, 16, 67,225,185, 62,111,225,126, 4,161,132, 37, 15, -238, 66, 88, 7, 65,178, 16,159, 3,146,133,184, 47,196,217, 32,175,174,225,243,184, 31,130,177,121,110,175, 55, 32,172,136, 25, - 2,158,108,105,148, 8,219,192,129, 3,169,107,215,174,146,171, 16,163, 38, 27, 55,110,140,216,172, 64, 49,189,131,230,135, 93, -149,104, 57,165, 79, 95,150, 7,126, 60,103, 11,238, 75,252,175, 78,194, 48,241, 45, 15, 42,144, 72, 73,241,226,197, 35,125, 49, -155,191,134, 13,215, 33,176, 93,149,192, 56,106, 9,134, 87, 37, 48,113, 10,134,231,233, 29,120, 98,222, 80, 12, 86,129, 94,241, -140,240, 79, 13,157,222, 1,147,145,226, 89,196,192, 17,148, 71,125,122, 7, 28, 3,153,195,135,144,140,233, 29, 68,224,187,232, - 87, 4, 2, 2, 1,129,128, 54, 4,148,147,128,126,155,176,116,220,119, 19,150, 98,170, 3,124,205,131, 24, 97, 58, 6, 16, 5, - 88,101,228, 78, 88,154, 41,179, 71, 4, 92,104,112, 17, 42,131,223,209, 65, 32,166, 10, 27, 2,228,173,109,108,101, 77, 88,138, -206,140,199,132,167,230,206,105, 40,143, 20, 12,101,139,153, 36, 19,157, 32, 38, 45,133, 37, 11,228, 10,147,153, 98, 82, 83, 76, -110, 26,189,126,163,170,197, 32,102, 98, 64,229,228,162,142, 94,197, 62,160, 83, 81,110,168, 43, 72, 28,220,153,136,181,194,244, - 14, 72, 8, 30, 78, 97,237,249, 65,214,228,162, 60,201,163, 29,207, 46,142,120, 41,200,226,201, 73,105,205,154, 53,132, 50, 79, -156, 56, 81,178,100,193,165,152,214,218,134,235,174,123, 66,200,152, 73, 80,121, 18,210, 52,182,110,193,101,202,148, 9, 90,187, -118,173, 52, 7, 23, 92,179,104, 19,144, 64,158,109, 30, 22,138, 16, 83, 75,251, 16, 49, 97,233,119, 26, 31,211,238,170,100, 10, - 3, 33,148,147,126,178,251, 54,156,173, 69,195,147, 43, 20,133,153, 96, 57,131,100,241,239,133, 32,179,176,196,242,252,106, 79, -212,172, 79,177,100, 98,170, 6,117, 2,163, 62,189,131, 58,129,209, 48,189,131,170,126, 74, 19,244,106,122, 54, 49, 97, 41, 98, -180,160,251,112,197, 67, 63, 49, 0, 4,243,190,201,157,176,180, 66,133,138, 81,208,117, 88, 74, 65,254, 17, 55,134,132,255,113, - 12, 36,171, 82,165,202,114, 38, 44,197, 20, 13,152, 15,235, 8, 39,105, 66, 55,222, 63,231,100, 72,240, 60, 26, 76, 76,218,105, -220,174, 74,224, 41,240, 52, 22, 2, 63, 67,151,140, 85,182,120, 32, 71,101,253, 64,109, 75,240,184,101,118,143,196,228,162,136, -135,130, 37, 5, 36, 9,110, 43,174,157,254,245,212,120,198,119, 76, 70, 58, 98,196,136, 48, 4,196,131,180, 33, 65, 78,151, 46, - 93,190,194,146,133, 89,225,245,173, 33,168,110,105, 96, 11,144, 29,191,197,231,229,206,157, 59, 18,129,229,102, 22,214,111,148, -235,200,129,100, 97, 73, 33, 44, 95,130,217,183,181,117,142,202,117,220, 54,158,120,113,217,198,209,227, 19,207, 73, 21,130, 14, - 21,110, 57,116, 52,176,148, 97, 10, 6, 30, 57, 25, 85,178,100,201,160,228, 22,118,159,246,156,123,113, 89,185,134,163, 74,235, -170, 46,239,242,255,117, 30,121,105, 33, 88,171,184, 3, 12, 91,188,120,177, 52, 65, 43,246,176,142,177,139, 15,117,151,150, 31, -210, 87,119,245,245,230,162,151,224,153,199,150,152,243, 22, 22, 22,175,184, 99,245,103, 11,214, 69,222, 47, 86, 46,193,163, 87, -166,241, 84,243,103, 60,128, 63, 85,166,170, 46, 49,134,239,149,163, 65, 65,182, 65,134, 65,128, 27, 53,106, 68,117,235,214,149, - 98,222,160,247,209,147,151, 78,215, 69,180,112, 14,147,144, 86,172, 88, 49, 82, 31,129,225, 9, 71,181, 77, 88,170,170, 75, 49, -107,123,106,122, 54,177, 4, 79,222,252, 5,195, 64,182,225,150,199,210, 78,202,103, 83,214, 90,135, 76,240, 97,173,194,199,132, -242,195, 71, 57,133, 8,142,225, 28, 62, 2, 12,212,165, 35,209, 68, 11,164,203,208,237,167,182,187,161,133,209,145, 95,148,211, -136, 96, 10,130,109, 92, 48,227, 17,158, 70,175,248, 47, 20,200,179, 0, 73,155,250,154,135, 90,138,160,178,126, 32,150,226,209, -184,168,116,153,255, 47, 42,109,157, 46, 93, 20, 72, 22,130,189,117, 17, 45,213,245,209,156,216, 37,136,248, 43, 4,187, 99,100, - 33, 18,254,199, 49,156,147,179, 54,159,182,184, 26, 11,158, 13,155, 23,148,222,149, 34,157,215,126, 88,180,224, 54,196,130,211, - 32, 89, 88,144, 87, 31,209,250,127, 57, 7, 95, 96,146, 82,140, 23,124,238, 99,111,107,187,219,218,218,250, 33,151,241, 97, 90, - 75,203,221,201,147, 38,237,131,115,138, 92,131, 47,232, 93,247, 77,117,173,195,232, 5,181,181,213, 93,185,160,182,161, 50,149, -174, 75,109,123, 57,120, 26, 81, 33,227, 93,167,163,170, 75,118, 86, 86,181, 88, 31, 63, 49,241,145,220,176, 32, 85,112,205,194, - 74,132,145,177, 24,197,138,160,113, 38,180,183, 49,229,131, 62,162,165, 36, 91,250, 8,140,234,172,240, 58, 62, 4, 98,214,246, -212,250,108,150,251,255,162,210,246, 25, 28, 34,149,207,166,172,181, 14, 89, 63,149,139, 74, 35,190,140,167,112, 8,196, 52, 14, -234,139, 74,235,213,207,216,202,180, 53,154,104,197,101,198,247,120,167, 75,255,242,115, 36,234,110, 20, 4,254,101,157, 55, 10, -128,191, 73,136,114,222, 44,245,189,230,226,192,181,166, 92,115, 45,218,205,150, 80, 87, 71, 30,189,190, 33, 44, 89, 79,244,174, -117,200, 47,114,184,189,244, 17,131, 24,215, 88,116,126,149,146,106,116,247,104, 35, 93,202,227, 26,234,164,211,117,168,116, 5, - 26,163,156,234,117,249, 83,101, 26, 81, 57,227,221,139, 66,147,254,192, 66,202,250,220,157, 73,198, 41, 38, 73,111, 96, 41,229, - 56, 40, 76, 57,114,159,221,127,157,225,178, 86, 94, 39, 71, 63,225, 18, 68,252,149, 58,129,193, 49,165,187, 80,181, 28,154,100, - 26,250,108, 98,125, 67, 16, 44, 36,189,107, 29, 26,241,217, 84,211, 37, 4,198,199,117,198,247,120,167, 75,255,242,115, 36,234, -110, 20, 4,254,101,157, 55, 10,128,191, 73,136,186, 37,203,240,133,166,227, 88,240,127, 89, 97, 68,221,227,168, 52, 90, 46,251, - 19,240, 4, 57, 55,211, 83,173, 63,161,156,114,144, 23,229,148,131,146,252, 60, 2, 79,249, 88,201,201, 41,240,148,131,146,252, - 60,241, 5, 79,249, 53, 18, 57, 99, 16,136, 47,141, 43,202,105, 92,165, 21,120, 10, 60,141,133,128,208, 37, 99, 33,249, 77,142, -192, 83,224,105, 44, 4,126,134, 46, 25,171,108,191, 67,142,210,162,165, 58,159, 86, 44, 50, 4,192,212,147, 33, 5,213,116,189, -190, 99,250,228,235,187, 62, 46,101, 22, 50,191,111,103, 93,152,136, 54,210,142,128,208, 37,161, 75,114,117,224, 79,124,142,170, -197,225,157, 47,183,190,170,249,254,196,186,139,190, 35,246,179,251, 59,218, 72,121, 79,109, 58,165,175, 76,127,226,121,121,177, - 89, 63,161,228, 63,131,241, 10,153,198,109, 40,129,167,192,211, 88, 8, 8, 93, 50, 22,146,194,250, 36,116,233,223,212, 37,227, -214,250,215, 74,211,105,209,250,153, 69, 17, 15,139,113,209, 21,120, 10, 60,141,133,128,208, 37, 53, 36,125,125, 21, 9,121, 76, -114, 2, 34, 95,222,175, 75, 68, 84,155,147, 34,129, 76,192, 53,226, 89,187,182,230, 25,254, 59, 53,180, 76, 45, 67,174,104, 35, - 25, 32, 25,144, 69,224,105, 0, 88, 50,178,254, 12, 60,101,220, 86,100, 81, 71,224,103, 52,196,223, 36,211, 49,125,250,244,123, - 56,237,101,224,120,210,112,189,219,223, 84,119,189,149, 85,203,240,219,234,206,147,150,150,226,133,184, 75,201, 44,240,111, 43, -167,204,242, 41,179,197,148,211, 43,147,162,134,103,102,197,160,152,228,166,104,162, 77,150, 39,159, 83,205,139,107, 85,242,202, -169,123,194, 10,165, 29,102, 35,241,117,114, 38, 47,149, 35, 83,189,184,238, 60, 21,203, 99, 30,105,249,156,231, 68,171,172,161, - 46, 49, 50,121,194,225, 68, 72, 13,106,165, 25,216,165, 77,150,143, 93,218,120,126,109,217,212,193,191, 81,109,203,219, 77, 27, - 88,237,106,211, 52,125,191, 54, 45,236,178, 41,243,169,239,117,213, 61,171,155,162, 66,221, 26, 94,115,114,121, 39,239,121,248, -112,177,196,244,172,118,242,251, 39, 93,172, 91, 53, 78,179,185,103,231, 92,145, 77,234,166,217,210,162, 69,218, 84, 58,218, 45, - 46,117,215,167, 6,191, 84,230, 40,110,227,161, 73,146,120, 14, 75,148,168,234,176,196,137, 27, 12,231, 52, 44, 97,194,122,188, -207, 51, 65,161,136, 83,221, 89,102, 26, 95,133,162,196, 72, 19,147,102, 44,179, 47,203,234, 51,202,196,164,233, 80,133,162,248, -104,133,130,103,247,209,186,105,173,123,124,147,137,250,162,222,127,106,221,245, 41,161, 56, 31,141, 64,170, 84,169,206,115,231, -130, 73, 47, 99,146,165,165,165, 63, 18,119, 60, 82,226, 57,165, 98, 18, 47, 87,130,115,231, 13,236, 28, 49,130, 11,126,205,163, -209, 9,255,255,200,168, 46,179,164, 73,147, 14,231,114,156, 50, 49, 49, 9, 65,194,255, 56,166, 71,174,174,151, 15,143,190, 87, - 52, 96, 60, 22, 48, 30, 15,121, 2,208, 71,252,255, 66, 28,227,132,115,218, 54, 93, 50, 83,112, 7, 48,153, 23, 28,126,205,139, - 0,223,224, 73, 37,163,220,221,221, 95, 51,134,147, 89, 24,175,146, 19, 39,153,113,213, 93, 93,229,204,196, 36,240,156,131,131, -195,133,104,252,204,240, 63,151,253, 28,255,206, 20,135,114,154,242, 53,165, 25,191,254,220, 9,238,141, 94,230,230, 57,235,210, - 94,110,163,254, 56,199, 9,121, 52,109,191,180,131, 80, 41, 64,106, 46,231, 43,214,245, 87,124,236,175,180, 66,128, 56, 81,216, -205, 85,202,132,223,218,218, 86, 79, 94,189,109, 84,178,152,109,181,185, 51, 90,206, 69,194,255, 50,148, 86,175, 76, 53, 25,238, -188,114,197,187, 79,159, 62, 73, 43, 87,212,170, 85, 43,152,159, 91,238,127, 99,109,223, 17,173,118,205, 51,189, 11,251,244,140, -194, 63,191,144,210,215,208,167,244,224,206, 65,218,186,126, 24,141, 24, 92,142, 26,215,178, 60,213,176,118,186,172,114,137,150, -167,171,162,242,128,254, 53,230, 70, 70, 92,157, 91,183,150,215,204,105,211,242,165,190,119, 49,135,213,153,253,217, 10,247,235, - 81, 48, 10,247, 56,180,119, 6, 53,175,103,117, 78, 7,217, 50,180,238, 50,224,252,101,193,240, 9,134, 36, 75,230, 52, 52,113, -226,118,195,147, 36,169, 58,218,194,194,115,116,186,116, 78, 72, 99,211,166,117, 25,150, 36, 73, 57,233, 92,226,196, 57, 13,120, -222, 19,140, 72,156,184,224,172, 44, 89,250,189,191,115,167, 95,248,231,207,131,120,126,182, 33, 72,248, 31,199,102,185,187,247, -243, 85, 40,242, 11,153,223, 33,160, 73,151,126, 6,158,114,116, 80,228, 81, 34, 0,146,133,117, 7,149, 91, 84, 84, 20,133,135, -135, 75, 11, 24,227, 37,134, 89,210,149, 11, 25, 99, 89, 14, 44,167,195, 95,145,254,218, 94,104, 42,199,241, 21,139, 70, 95,201, -235,196,133, 97,230,109, 44, 32, 13,185,123,247,238,165, 92,185,114,133,241,185, 85,156,202,112,210,244,197,171,237,229, 83,142, -103,155,127,139, 69,171, 49, 35, 54,228, 97,241,102, 76, 48, 57,127,254,252,112,156, 99,121,229, 12,120, 0,145,213,155,137,213, - 29, 94,130,228, 19,102, 1,199,132,172, 88,131, 17, 75,230,240,210, 54,159,112, 14,121, 12,144,153,128, 73, 70, 51,123,123,251, - 23,243,230,205,251, 2, 28,207,156, 57,115, 11,216, 97, 45,197, 25, 51,102,124,193, 57,228, 97,153,154, 92, 22,223,213,157,203, -112, 94, 73,134,245, 17, 97, 3,201,112, 78,103,103,231,123,188, 72,113, 36, 47, 80, 29,198, 68, 99, 43,210,189,123,247, 34,120, -249,160, 72, 44, 92,204,101, 52,228, 37,153,157, 9,213, 99, 94, 40, 60,132, 39, 1,141,194,204,253, 88,138, 8,139, 95, 99,249, - 38, 94, 46, 40,138, 39, 8,253,200,228, 24,243,177,101,215,128,169,174, 78,167, 16,147,161, 57,140,221, 41, 94, 18,231, 41, 18, -254,199, 49,150, 83, 72,199, 83,173,183, 35, 99, 89, 75, 23, 46, 92, 24, 49,106,212,168,112,198,122,169,140, 55,132, 94,153, 50, -100,168,103,249,169, 50,149,228,105,197, 18,223, 85, 93,218,151, 91,197,191,241, 97,162, 73,255, 18,224, 28,242, 32, 47,136,153, - 26, 41,251,174,156, 21, 75,101, 24, 95,173,162,203,226,178, 37,108, 91,230,203,103,153,186,106, 69,151,213, 33,239,182,250, 34, -225,127, 28,195, 57,228, 65, 94, 3,219,221,157,219,249,177,183,183,247, 27, 94,126,235,106,146, 36, 73,218,129,100,225,189,116, -237,218, 53,105, 29, 81,232, 87,190,124,249,130,147, 37, 75,166,106,217,250,142,104, 53,172,105, 57,152,173, 76, 17, 32, 85, 83, -198,214,165, 69,115,219,211,177, 67,243, 41,224,229,101,137,120,221,184,188,141,122,117,201, 29, 86,191,166,249,208,214,173,115, - 37, 81, 18, 46,149,242,254,223, 66,232,174, 40,166, 36, 89,216,103,203,146,112,116,222,156,137, 7,148, 41,110, 50,106,202,200, -156,147,122,117,204,248, 0, 36, 75,149,108,105,113, 37,254,212,118,143,131, 30,106,187, 68,189,156, 9,152, 72,101, 99, 43, 86, -221, 89, 25, 50, 88, 76,180,179, 51, 31,147, 50,165,247,168,164, 73, 11, 34,141, 76,153, 50,215, 36, 75,203,244,107,243,231, 79, -206,100,171, 28,147, 45, 31, 25,237, 14,153,205,252,102,204,232,195,139,225, 14, 9,190,119,175,223,173,201,147,187, 31,174, 86, -173,203,241,122,245, 58, 63, 89,186,180,203,231,103,207,250,242,185,193,199, 71,142,236, 51, 50,105,210, 70, 66,102, 44, 4, 52, -181,145,177,241, 52,162, 74,197, 75, 81,202, 96,120,213, 88, 45,221, 21, 65,231, 13,146,133, 37, 98, 54,108,216, 64, 91,182,108, -145, 94, 92,251,246,237,147,214,232,195, 11,140, 73,130, 68, 62,120, 49,103,105, 13, 52, 25, 68,171, 38, 91, 72, 94, 97, 41, 15, -144, 12, 77, 27, 8, 29,102,225,230,165,111, 48,243, 54,172, 8, 53,213, 74,170,233,229, 83,194,195,195, 35, 20, 75,229,220,185, -115,135, 22, 45, 90, 68, 19, 38, 76,144,214,103, 67,185,113, 28,137,173, 70,161, 44,171,132,140, 7, 16, 89,242,112, 71, 29,202, -139,102, 71, 5, 7, 7, 75,245, 84,110, 32,132, 88,138,135,113,136, 66, 30,228,149, 33, 51, 55,215,253, 70,135, 14, 29, 62, 96, - 57, 31,108, 60,227,248, 11,158,109, 60, 10, 68, 11, 9,139, 77,163,156, 29, 59,118, 12, 98,185, 55, 88,102,110,125,117, 71, 59, -129,244, 98,123,245,234,149, 84,111, 44, 31,131,181,250,128, 35,126,131,112,130,204,202, 37,195,188, 12, 80,233, 28, 57,114, 60, -133, 69, 64,185,241,146, 67,143,184,253, 95, 67, 14,202,136,245, 40, 51,103,206,252,148,137,145, 38,151,218,119,109,196,132,229, - 34, 48,196,114, 67,220,241,145,171,171, 43,241,130,216, 84,184,112, 97,105,189, 72, 44,130,141,197,144,153, 20, 19,119,138, 23, -101,224,137, 44, 57, 96, 93,227,165,139,222, 99,113,114,213, 15, 3,204,134,142,197,197, 43, 85,170,244, 46,218, 2,151, 67,166, - 76,213,108, 57, 75,149, 42,197, 48,188, 39, 44, 6,206, 58,246,158, 79,106, 35,151,202,235,226, 93,231,168, 36, 90, 32, 80, 55, -174,239,158, 59,110, 76,235,177, 37,139, 37,170,245,254,189,167, 3,125,241,116, 69,194,255, 56,134,115,200,131,188,114,136, 22, - 8, 84,104,224, 86,223,221,219, 6, 78,235,214,169,212,198, 19, 7,166,111,248, 26,114,108, 5, 18,254,199, 49,156, 67, 30,228, - 53,160,141,248,113,118,127,133,101,130,176, 8, 61,214, 74,229, 37,189, 62,243,243,250,245,210,165, 75,180,114,229, 74, 26, 62, -124, 56,245,232,209,131, 6, 13, 26, 68,137, 18, 37,194, 58,139,223,181,145,170,133,106,242,228,106,230,203,231, 54,202,185,112, - 86,229,242, 11,103, 20,233, 53,176,187,235,202,118,205,109,111, 15, 29, 80,138,158,220, 63, 78,159, 67, 30,211,194, 57,237, 8, -100, 75, 39,209,202,172, 24, 16, 26,122,126,238,251,247,231,230,222, 98,172,110, 95,223, 61,255,214,245, 45, 75,111, 94, 89,189, -241,210,233,153,135, 30, 92,104, 63,165,123, 59,231,167, 50,200, 86,188,211, 37, 0, 60, 44,105, 82, 23,118,233,213, 92, 91,171, - 86, 82, 38, 85, 30, 35,146, 36,241, 25,109,106,154,113, 70,250,244,214, 83, 44, 44,172,198,167, 76,105, 55,194,196, 36, 15, 8, -215,161,129, 3, 19, 51,217, 42, 53, 60, 81,162,188,186,222,117, 44,175,192,165,185,115,123,115, 91, 15,185, 56,120,112,143,189, - 69,139,182,123, 52,110, 92,221,224, 61,123,170, 34, 61,159, 53,171,246,165, 22, 45,154,189, 88,186,180,125,228,215,175, 3,143, - 12, 30,220,107,152, 66,193,115, 10,107, 39, 27,218,100, 62, 92,189,186, 86,163, 50,101,198,101, 72,147,230,188, 67,234,212, 23, -219,148, 43,183, 32,240,205, 27,223, 31,145,105,204,114,110,247,241,233,176,164, 69,139, 14,215,150, 46,149,234,111,204,186,255, - 72, 57,227, 37, 53, 50,110,161,213, 39, 40,141,253,155, 45, 10,197, 96, 85,224,228,171,188,175,146,104,201, 33, 89, 88, 32, 25, - 68,139, 59, 52,117,139,150,122, 53,158,130, 72,225,197,168,111, 3, 89,192,130,213, 44,224,169, 30, 44, 82, 99,109, 68, 44,143, - 2, 34,232,235,235, 43, 45,168,140,181,222,246,239,223, 47,237, 65, 22, 33,235,246,237,219,132, 53, 22, 89,158, 62, 23,144, 9, -231,123,162, 36, 87, 32,148, 47, 95,190,140, 41, 50, 44,102,176,112,193, 10,133, 69,156,145,151,101,242,138, 60,218, 55,182,230, -188,228, 50,156,101, 33, 71,152, 16, 28, 99,203,208,233, 5, 11, 22, 28,159, 52,105,210,229,193,131, 7,223, 96, 75,207,221, 38, - 77,154, 60,172, 81,163,198, 51,118,119,188,230,133,128,223,179, 59, 45, 72,159, 30, 40,219, 9,132, 18,139,105,131, 88, 97, 3, - 17, 6, 38, 32,172,216,208, 70, 40,175,140, 54, 82,240, 34,199,119, 65,132, 65,170,128, 25,112, 4, 89, 3,145, 65,221, 81,103, - 46,187,180, 54, 37, 91, 20,238,234, 43, 35,206,115,190, 0,144, 31,158, 97, 29, 68, 10,139, 49,131,248, 82,129, 2, 5,164, 69, -143, 27, 52,104, 64,140,131,164, 71, 60,243,186, 62, 61,130,200,156,217,178,101, 11, 64,157, 64, 42, 81, 87, 44,141,131,122,226, -127, 85, 34,143, 58, 48,177, 67,187,235, 35, 73,170, 85, 73,200,101,188, 13, 66, 13, 2, 11, 29, 0, 73,228,178,221,230, 76,114, - 98,139,228,192,242, 71,228, 81,137,187, 26, 14, 34,117,255,246,210, 97, 91,215,215, 26,190,119,173,231,240, 55,183, 10,246, 64, -194,255, 56,134,115,200,227,233,174,152,196,215,169, 91,180,190,171, 15,172, 85, 32, 82, 95, 2, 15,204, 8,120,182,101,253,208, -254, 69, 31, 53,174,147,246, 19, 18,254,199, 49,156, 67, 30,228,149, 9,136, 43,147,252, 0,180, 43,116, 10, 27,116, 19, 31, 42, - 76,180, 62,181,107,215, 46,168,111,223,190,212,180,105, 83,170, 82,165, 10, 85,173, 90, 21,239,145,199,154,100,171, 18,173,195, -139,125, 77,222, 60, 93,109, 27, 20,176,220, 53, 60,112,128, 79,248,135,190,101, 34, 2, 71, 54,217,182,186,230,164,182,205,237, - 95,239,219, 49,153,190,124,124, 66,189,187,230, 13, 83,186, 17, 53,201,204,226,166, 40,169,180,104, 13,234, 95,115,110,118,207, -132, 99,139,228, 75, 60,180, 82,185,228, 83,199, 15, 45, 61, 38,242,237,204,246, 31, 30,245, 31,163,137,108,233,137,217,146, 9, -207,239,203, 54, 68,161, 72, 10,151,224, 2, 55,183, 84, 32, 89, 83,108,108,188,217,188, 88, 58,226,242,101,179, 26,165, 74,197, -178,146, 14, 74,152,208,206, 55, 73,146,188,171,171, 87,151,174, 25,171, 80, 88,107, 42, 57,119, 74,150, 83, 93, 93,251,193,146, -117,113,208,160,238,236,107,109,198, 50, 43,106, 74, 79, 39, 78,172,251,122,205,154,214,236, 74,236, 55, 33, 93,186,190,218, 98, -182, 52,201, 28,217,165, 75, 55,175, 76,153,118,122,102,201, 18,186,116,233, 82,201,245,140,119, 42,222,161,174, 46, 46,159,125, -138, 20, 57, 83,223,204,108,166, 33, 50, 81, 70,174,123, 37,174,251,180, 76,206,206, 55, 76, 83,166,252,132,228,230,224,112,187, - 97,137, 18,203,191,134,134,246, 55,164,156,237,254,199,222, 85,192, 71,113,124,225,195,221, 37,184,134,224,238, 78,161, 88,139, - 83, 92,139, 22, 45,110,109,113, 47,110, 45,238,238, 4, 9, 26, 92,131,187, 59, 4, 8, 26, 2,201, 1,121,255,239,219,102,243, -191, 92,238,110,247,146, 64, 75,187,251,251,205,239,246,118,103,223,206,188,153,157,249,230,189, 55,239, 21, 42, 52, 54,105,146, - 36, 47,178,186,185,249, 67,235,244,209, 5, 90,164, 90,229,203, 79,121,180,123,119,109,214,253,217,170, 85, 97,170, 59,203,233, -115,232, 80,205,198, 85,171,254, 94, 34,127,254, 53,185,179,103, 63,151, 38,117,234,103, 41,147, 39,127,158, 45, 99,198,171,223, -127,247,221,254,111,226,196, 89,129, 15,212,229,115,246, 46, 91, 88,228,115,190, 47,130,105, 91,239, 58,228,255,255, 31, 4, 89, -214, 47,228, 4, 78, 80,180,113,227,198, 96, 73,150,167,167,103,176, 36,139, 42, 63, 74,178, 56,177, 1, 52, 40, 65,151,117, 76, -226,138,148,140,210, 16,198,143, 35,152,178, 62, 24, 92,122,237,218,181, 50,116,232, 80, 69,165,132,114, 57,156,116, 33, 81, 25, - 56,125,250,244, 15,148,104, 16,100, 17,108,237,222,189, 59, 68, 57, 9,178, 40,133, 34, 88, 2, 93, 51,159,113,196,224,168, 81, -163,246,234,222,189,187,191, 90,182, 85,171, 86, 41,160, 67, 61, 56,168,119,237,218, 85, 46, 94,188,168,164, 31,127,252,209,159, -207, 56,162, 9,155, 36,165,238,234, 1,192,114, 25,193,137,159, 67,133, 22, 64, 80,100,157,160,154,124,129,114, 82,221,233,240, -160,186,144,245, 34, 63,185,146, 39,208, 98,249,200, 71,242,132,131, 4,249,204,246, 33, 96,112,212, 70,136,105, 55, 24,128,231, - 72,187,118,237,238, 81, 77,204,128,223,236, 3,228, 43,105, 61,124,248, 80, 1,174,252,229, 68,182,105,211, 38,169, 90,181,234, - 61,168,123,247,103,200,144, 1, 99,151,253, 3,182, 93, 62,228, 33, 7, 46, 74, 24,154, 52,105, 34,229,202,149, 83, 38, 66,210, - 39,160,103,249,168,154,141, 29, 59,246, 19,141,106,167,196, 68,251,144,234, 97,214, 13,170, 61,153, 52,105,146,140, 25, 51, 70, -169, 47, 84,176,178,108,217, 50,133, 7,234,193,254, 74, 91, 43,208, 77,169,197, 83,222, 7, 95,187, 67, 69,172,136, 93,201, 91, -130, 75, 6,104, 6, 40,124, 11, 21, 85,119, 61, 52,190,194, 60,145, 40,181, 34,160,186,119,161,197,194,137,163, 42,120,254,216, - 52,151, 15, 19,207,121,141,247,152, 7,117,211,181, 27,143,170, 65, 74,173, 8,168,122,117,118,125,127,251,210,104,121,247, 98, -145,220, 58, 93, 91,102,142, 75, 27,216,188,126, 50, 63,222, 99, 30,230,213,195,179,108,217,210,111, 59,186,167,149, 28, 63, 48, - 76, 54,173, 27, 43,187,118,121, 40, 38, 2, 28,143, 56,182,224, 91,242,133,164,244, 45, 2,121, 83,162,201,254,196, 49, 4, 81, -142, 66, 31,150, 64,107,235,214, 41, 49,188,111, 44, 74,254,234,201,210, 76,230, 87, 99, 10,125,120,222,167,226,169,125,173,154, - 7,248, 76,239,243,242,246,144,159, 9,182,238,222,216, 47,144, 80, 73,211, 31, 18, 31,226,179,246,202, 27,108,163,245,233,220, -204, 70,245,115,205,246,220,154, 58,205,129, 61, 89,138, 62,191, 53,164,226,244,177,117, 39,236,220,208,123,253,131,139,125,103, - 88,131,173,230, 13,147,236,214,203, 91, 61,188,250,210,121, 0,152,242,194, 38,235,123,170, 11, 41,201,194, 4, 94,200, 99,214, -172, 72,163, 97,123, 11, 73, 87,118,166, 17,136, 15,170,150,107, 80,244,232, 57,134, 71,138,148, 17,134,237, 69, 6, 71,142,108, - 83,130,135,129,165,252,139,203,151,251,191,185,117,107,192, 78, 72,178, 8, 10,210,166, 78,125, 45,121,178,100, 47, 1, 52,148, -148,210,197,229,101,170,148, 41,149,148,218,197,229, 85,250,116,233,222,164, 75,157,250, 77,202,196,137,185, 48, 10,117, 88,211, -204,147, 37,139, 59,199,143, 27, 55,110, 40, 99,158,245,193,177,139,125,171,119,239,222,146,196,100, 90,171,135, 38,203,137,186, - 55,203,144, 38,205,149,218,181,107,191, 63,114,228,136,162, 85, 96,226,121,173,154, 53,253,179,186,186,222, 89, 59,106, 20, 54, -188,154,108,169, 79, 77,150,229,220, 2, 73, 22, 65, 22,251,185,122,112,254,109,223,190,253,251, 36,137, 19,191,152,254,203, 47, - 29,239, 13, 31,222,200,124,247,110,215,171,171, 86,245,208, 67, 83,229, 39,203,154, 59,107, 86,207, 78, 29, 58, 60,195,252, 27, - 72, 33, 3,181, 67, 84,193,115,236,195,184, 26, 88,166, 84,169,151,137,163, 68, 9, 75,188, 82,221,221,208, 22, 22,209,253,240, - 63, 61,163, 5,138, 44,167,150,149, 19, 56, 39, 91, 85, 93,232, 8,100,113,242,164,122, 13, 18, 0, 45, 73,132, 2, 54, 56,153, -170, 73, 85,249,176,131,207,156, 57, 83,122,244,232, 33,125,251,246, 85, 38, 99, 2, 46,148,199, 33, 77, 6,162, 38, 13,174, 64, - 40,201, 98, 57, 15, 30, 60,168,208,167,234,136, 29, 69,237, 48,151, 47, 95,150,195,135, 15, 11,159,113,212, 38,184,239, 73, 9, -134,122,112, 34, 87, 15, 78,236, 4, 54, 4, 10,124, 15,165, 61, 84,119,241, 25, 71, 52, 45,129, 22, 84,125,111, 80, 14,111, 2, - 1,124,220,151,172, 65, 22,192,224, 59,168,195,124,131, 38, 8,135,221,135,237, 52,118,236, 88, 5, 96, 48,253,252,243,207,193, -231,252,223,166, 77, 27, 5,128,140, 30, 61, 90, 9,132,236,168,141, 0,178,142, 83,218, 8,201,205,115, 14, 54,139, 22, 45,146, -110,221,186, 41, 52, 41,105, 34,192,162, 90,182, 87,175, 94,202,117,242,186,109,219,182,207,216, 71,138, 20, 41,114,196, 81, 65, - 97, 67, 19,140,122,216,175,216, 95, 8,148,152,200, 7, 74, 39,104,183, 69,117,175,150, 68, 11,247,187,162,125, 21,228, 75,213, -209,196,137, 19, 5,192, 88, 48,152,189, 43, 81,162,196,155, 42, 85,170,188,253,233,167,159,222, 65, 69,173,140,152, 44, 59,129, - 22,120,241, 1,210, 52, 61, 32, 41, 57,212,154,207, 84,112, 77,160, 69,144,197,186,179, 47, 96, 37, 73,233,152,205,213,247, 63, -253, 91,215, 42, 31, 85,132,148, 94, 17, 88,253,220,177,220,135,139,103,183, 11, 19,207,121,141,247,152, 71,139, 14,238, 71,166, -177, 59,237,176,168, 34,164,244,138, 32, 75, 2,209,108, 72,102,223,237,114,243, 68, 41,153, 48,212, 37,144,247,152,135,121,131, - 12,228, 29, 74, 12,203,150,202,118,254,252,225,250,242,242,233,122,241,125,177, 83,246,237,158, 34,227,198, 14, 84,218,104,253, -250,245,130, 5,140,224,155,120, 91,160, 64,129,119,142, 64, 22,235, 96, 9,180,102,206,108, 23,237,246,233,249, 9, 95, 60, 90, -149,206,231,206,196,236,109,154,102, 28,251,231,180,159, 60,239, 92,223,120,240,221,227,169,125, 40,217, 26,212,175,156, 98, 91, - 53,229,247, 70,194,221,136,142,248,128, 93,135, 85,105, 8, 95,180, 96,156,126,143, 79,185, 38,219,191,219,181, 64,211,250,105, -126,159, 53,163,251,158, 59,215, 55, 31,218,190,190,215, 6,107,201,214,128,158, 37, 62,181,108,233, 88, 58,174,131,247,127, 91, - 22,216,101,213, 29,157, 56,113, 86,216,100,229, 27, 29, 47, 94,122, 72,115,170, 14,137, 20, 41, 49, 1, 22,164, 93,241,149, 20, - 35,134,235,244,156, 57,211,226,211, 76, 58, 41,115,230,248,195, 98,198, 44, 55, 36,114,228,132, 0,105, 63,217, 42, 56,119,216, -209,216,253,234, 31,127,244,188, 13,169, 13, 65, 1, 65,150,106, 50,193,177,138, 18,119, 74,177,173,237,134, 83, 37, 75,246, 74, - 15,205,184,177, 99,223,231, 88,193,177,157, 18,114,235,131, 11, 85,154,204,112, 97, 13,213,197, 35, 61, 52, 41,201, 34,200,194, -130,237,147, 45,240,198,113, 16, 11,196, 79, 89, 51,103,190, 51, 52,102, 76, 91, 54,101, 38,203,186, 47,104,211,166, 19, 37, 89, -161, 10,135, 11, 0,129,129, 24,219,223,183,174, 90,117,244,155,125,251, 90, 61, 63,119,174,251,168,152, 49,155,232, 41,167, 42, - 25, 4, 56,125,206,186, 83, 83,193,177, 56, 72,203,165,156, 67, 82,172,152,203,196,209,161,101, 9, 79,231,179,133, 69,194, 67, -239, 11, 63,107,233, 17, 94, 61, 15, 93, 4, 75, 52,201, 9,156,147, 32,109,178, 84,240, 66,240,193, 9, 75, 85,209, 80,146,197, -149, 36, 12,166,149, 14, 30, 22,160,165, 2, 46, 76,216, 2,251, 37,101,194, 84,129, 22,165, 18, 90, 64, 11,147,238, 27, 78,182, -176, 33, 82,164, 86,180,243,225,202,131,210, 29,126, 20, 4, 89, 4,130, 84, 39,241,156, 96,129,207, 56,106, 0, 12,206,175, 89, - 55, 30,252, 64, 32, 49, 83,206, 85,144, 69,186, 80,239, 41, 18, 29,218,130,140, 31, 63, 94, 32,125,114, 72, 83, 5, 90, 4, 50, - 0, 89, 39,169,242, 32,216,152, 49, 99,198, 61, 78, 16, 42,216,162, 10, 48,115,230,204, 79,135, 12, 25,162,174,196, 29,246, 21, -238,254, 84, 37,131, 28,120, 8,174, 56,232,240,224,224, 64,144,197, 15,154, 7,219,211, 81, 27,193,168,120, 5,192,227, 39,130, - 83, 72,152,158,240,195,162,237, 11,233,242,151,109, 77,176,202,126, 64, 73, 39, 86,119, 79, 41, 65, 3, 40,166,113,252,114,189, - 64,147,101, 97,253, 73,143,237,196,118, 35,136, 97,157, 97, 20, 79, 94, 58, 4,215,120,215,126, 75,105, 40, 7, 1,180,217, 7, -188,159, 6,207,148, 50, 48, 85,135, 93,206, 7, 2,107,182, 61,118,119,202,128, 1, 3, 4,146,218, 99, 90, 31, 31,108,233,182, - 64,226, 24,188,172, 85, 37, 90, 4,129, 76,144, 54,126,130, 4,115,139, 22,157,175,241, 62,237,177,168, 42,164, 20,139, 0, 75, - 61,120,206,107,188,199, 60, 90,117,163,251, 6,238, 44,164,209, 59,237,177,168, 42,164, 36, 43, 24,104,249, 29,149,215,119,190, -151, 77,139,210, 9,239, 49, 15,243,242,153, 32,215, 15,118, 95, 1,201,228,240,163,123, 90, 4,222,185, 52, 72, 1, 90, 76, 87, -206,175,148,158, 61, 90, 40,223, 42,191, 71, 46,218,160, 90, 14,192,198, 18,120, 17,176,127, 88,239, 34, 60,124,120, 66,172,123, - 87,230,166,170, 94, 41,245, 47, 83, 39,117,220,122,253,242,250,221, 51,167,119,220,115,241,104,155,166, 84, 35,210,102,139, 82, - 45,207, 29, 51,164, 93,115,151,126, 90,126,182, 92, 93, 77, 49,188,188,218, 69,187,233, 85, 48, 65,165,242, 81,127,157, 50,161, -245,246,171, 23, 54,236, 34,216, 90, 56,163,233, 8,241,249,163,195,205,147,157, 39, 13,232,158,229,114,239,159, 11,126,106,219, - 50,201, 6, 45,222,254,147,239, 83, 5, 56, 35, 93,186, 68,176,127, 42,127,105,196,136,140, 84, 23,194,136, 61, 55, 0,150,178, -155, 26,253, 41,210,167, 15, 31, 70,157, 90,176, 96, 44,174, 41,128,122, 68,148, 40, 21, 49, 43, 69,195, 51, 61,113, 45,212, 78, -110,186, 48,192,115,131, 14,212,171,247, 51,109,136, 8, 12, 40,197, 98,223, 36,176,166,148,157, 90, 12, 46,124, 57,246, 83,226, -195,133, 27, 23, 88,169,147, 39,183, 57, 46, 91,211, 84,129, 22, 37, 57,156,227,104, 34,193, 57,141,139,120,154, 12,112, 78, 82, -237, 72, 81, 17, 46,180, 66, 29,214, 52,169, 46,132, 84,245,189, 45,144,197, 49,154,160,142, 99, 96,165, 74,149, 2,138, 71,141, -186, 90,139, 38,109,178,168, 46,180, 5,180,248, 14, 10, 43,178,184,186, 6,180,173, 84,105,130,191,183,119, 55,236,208,180,169, -101,177,197, 79,242, 52, 99,134, 12, 47, 57, 87,176, 76,228, 1, 55, 43, 49,241,156,115, 40,109,126, 99, 69,139,246,238, 75,244, -191,175, 92,178,101, 59,152,180,138, 92,137, 38, 85, 38,114, 2,231, 10, 65, 15,200,162, 68,130, 96, 39, 60, 64,139,146, 23,107, -160,197, 14,174, 7,104,177,156,216,197,167,116, 10,170,187,248,161, 17, 12,169, 64,144,224,138,106, 41, 2, 66, 38, 45,160,133, -137,254, 45, 59, 23, 87,198,180, 1,162, 52,136, 32,133, 52, 72,151, 96,142,106, 9,170,171,168,154,160, 20,142,207,232, 1, 26, - 0,123,199, 9, 96, 8,178,152, 56, 32, 64, 13,247,128, 64,139, 43,137, 92,185,114, 61,109,218,180, 41, 13,123,117, 3, 45,174, - 66, 56,200, 16, 12, 81,186,197,131, 34,101,218,172, 80,138,197,131,109, 68,112,162,209, 70,177,220,220,220,198, 67, 58,181, 27, - 59, 14, 23,195,253,196, 93,214,159,182, 10, 28, 24,152,184,145,129,125, 34, 99,198,140,119, 48,225, 45, 5, 40,220, 13, 96, 50, - 30,117,143,165,167,254,234, 32, 65,186, 52, 48,231, 0, 73, 64, 77,169, 20,213,145,216,221,231, 52,208, 34, 77,208, 9,132,225, -250, 83,168, 48,149,196,115,172,196, 2,105,184,207,126, 65, 85, 47,164, 92,148, 70,209, 53,133,221, 3, 0,170, 60, 6,213, 55, -148,102,177,190,228, 25,121, 73, 80, 77, 48,207,182,230, 68, 14,155,175,151, 32, 98,107, 99,197,151, 24,135, 62,219, 59, 62, 39, -208,162,186,144,146, 44, 51, 64, 86,192,179,190,138, 68, 43, 44, 64,139,125,173, 76,201,204,143,207, 30,106, 36, 7,118, 13, 18, -159,167,103,148,110,117,225,244, 82,105,210,184,182, 2,168, 97,243,168, 44,218, 32,105,230, 6, 6,187,135, 53,208, 26, 60,184, - 94,244,226,133,227,252, 60,113,124,199, 13, 87, 46,110,217, 52,117, 98,199,173,109, 91,100, 26, 67, 53,226,135,231,253, 42,209, - 64,222, 99,211, 56,241,126,112, 82, 90, 52, 78,186,149,206, 77,181, 26, 3,170,241,200,133,242, 70,235, 60,225,247, 54,107, 47, -157, 91,189,121,242,132, 86,219,155,254,144,230,247, 39, 80, 35,142,252,173,220, 40,175,195,211,118, 79, 26,147,127,220,158,141, - 57, 75,210,207,150, 22,189,127,242,125, 0,173, 46,115,178,102,141, 7,208,244,237,227,165, 75, 21,117, 24, 84,136,249, 38,155, - 76, 49,208, 68,217,145,202, 16,108, 13,138, 26,181,208,170,191, 22, 68,166, 33, 81,162, 84,224,125, 60,219, 25,219, 78,227, 88, -215, 79, 5, 6, 71,154, 55,239,242,102,231, 78, 5,104, 81, 85, 72,112, 97, 9,178,212,177,159, 99,170,170,101, 73,227,226,226, - 16,104,169, 52, 45,129, 22,193,150,154, 40, 0, 96, 95,162, 20,159, 64,139, 26, 12, 45,160,165,210,164, 77, 22, 23,122,214, 7, -199, 21,206, 73,156,167, 56,110,115,158,203,144, 48,225,109, 71, 64, 75,165,153, 58,101,202, 7, 92, 8, 91, 30,228, 3, 23,174, - 4,110, 20, 92, 64,218,231,191,114,238,220, 17, 90, 64,203,146,159, 42,208,226,184,199, 49,143,115, 19,129, 38,233,170,227, 31, -235, 31, 55,122,116,135, 2,133,240,246, 77, 91, 88, 36,188, 52,191,240,243,182, 65,150,189, 66, 16,104, 81,146,161,170,225, 84, - 73, 22, 37, 26,150, 0,134, 19, 56, 39, 98, 2, 17, 76,184, 78,171, 14, 85,137,150, 45,160,197, 85,169, 22,208,162, 26,144,229, -225, 7,183,107,215, 46,165,243,178,140, 68,247,148,100,176,243,169,122,113, 74,120, 8, 18,180, 84,135,168,251, 33,126,104,156, -164,255,252,243, 79,174, 56,168, 34, 83, 12,182, 97,172, 46, 80, 77, 9, 84, 97,180, 79, 82, 86, 58,220,221,196,103,180,128, 6, - 58,238, 67, 72, 71,124, 85,144,165,254,162,238,247, 40,150,134,241,238,171,138, 21, 43,190,131,141,148, 2, 56,244,168, 14,233, -203,140, 43, 13,214,149,171, 47, 2, 45,214,147, 32,139,192,144,116,248,225, 48, 17,144,234,104, 35,203,106, 20,129, 11,142, 27, -108, 99,138,143,249,161,193, 53,131, 20, 42, 84,232, 6, 50, 89,239, 18,114,216,159,173,109,212,236, 1, 45, 2, 67, 45,137, 22, - 85,135,144,170,217, 92,217,169, 3, 16,251, 46, 37, 81, 4,203,228, 39,236, 24,104, 19,246, 17,246, 85,221, 28, 20, 52, 58, 64, -218, 61, 85,173,201, 65,135,131, 24, 87,120, 28, 96,233,214,131, 54, 26,216, 21,170, 12,188, 65,174, 40,162,127,225, 15,249,179, -190,238,115,170, 14,105,147, 69,112, 69, 73, 22,127,119,173,113, 13,147,234, 48,136, 1,197,154, 55,200,233,191,123,251, 68,121, -247,246,153, 2,182, 40,217, 90,189,124, 8,190,203, 74, 2,213,187, 2,180,176, 19,154,238, 98,116, 1, 45,244,143,168,185,178, - 70,238, 48,118, 84,251, 21,151, 47,108, 93, 67,176, 69,201,150,207,157,233,217, 21,155, 45, 24,200,115, 55,226,212,113,141, 21, -245, 97,135,150,153,110,208,131,188, 45,226,193, 27, 12,224,224, 53,119, 54, 83,251,223, 71,183, 91,126,233,252,150,149, 4, 91, -149,202, 69,253,229,144,103,150,124,135,247,187, 21,169, 86, 57,214,164,203,231, 86,174,174, 80, 54,250,136, 7,151,179, 37,161, - 83,211,207,218,192,159,153, 56,236,179,154,195,103, 86,154, 81,177, 98,149,160, 19, 80,190,110, 80,172, 88,105,160, 30, 76,171, -190,154, 54, 90, 84, 31,242,127,175,244,233,163,143,136, 22,173, 18, 37, 89,148,104,217, 42,158,170, 62,123,176,108, 89,183,199, -179,103,255,160, 2, 45, 2, 22, 85,146, 69,144, 69, 77,139, 10,178, 56,238,115, 12, 0,208,122,165,135,166, 94,160, 69,141,131, -150,234, 80, 45, 39,141,222, 57,247, 88, 30, 92, 20,171, 32,139,101,167,109, 42,199,168,216, 49, 99,190,215, 83,206, 86,181,107, -143,248,161,110,221,191, 84, 22, 56, 84,144,165,218, 40,210, 92, 6,192, 45,208, 5, 11,140, 33, 49, 99, 54,211, 67, 83, 85, 29, - 82,162,165,210,165,100,139,243, 42,231, 84,110,124,226,216,207,185, 4,170, 67,155,252,252,204,221,234,107, 33,175, 79,117,104, - 89, 27, 78,224, 68,180, 4, 66, 90, 32,139,249,216,129,116, 76,226,222,156,188, 44,109,180, 28, 1, 45,170,105,180,128, 22, 13, -219,233, 59,139, 82, 34,138,145, 41,113,162,216,151, 32,137,215, 8, 56, 8, 60, 40, 70,230,187,177, 58, 9,208, 50,134,199,125, -104,177,134, 40,138,122,126,204,156, 88,185,138,160,196,137,136,155, 43,144,210,165, 75, 43,170, 46, 2, 27, 0, 48, 26,216,195, - 49,177,253,131,110, 45, 0,254,174, 88,131, 44,254,135,234,204, 12, 85,228, 91, 72,144,158, 17, 20, 48, 17,112,232, 5, 90, 44, - 3, 85,132, 76, 48,204, 87,158,229, 71, 65, 53, 28,236,150, 20, 32,200,178, 14, 26, 52, 72, 79, 27,133,168, 4, 36,108, 87, 40, - 5, 36,136,227,166, 2, 26,113, 66,218,101,211,192,212, 81,253, 35, 18,104,225, 61,138, 49, 60, 7, 82, 2,124,213, 46,131,171, - 47,130, 66, 74, 7,161,146, 85,218,141, 19, 46,118,115, 42,124,129, 31, 44,138,252,237, 26,195, 99, 82, 30, 10,192,251,193,122, - 87, 44,251, 18,129, 48,109,241,126,249,229, 23,101, 55, 27,109, 8, 33,205,244, 71,187, 99, 23,249,191,230,248,172,198,240, 52, -124,167, 77, 22,165, 88, 76, 60,119,198, 24,222, 26,188, 12, 29,210,233,230,131,187, 94, 66,176,117,252,224,136, 96, 53, 98,135, -118, 53,165, 86,173, 90,210,160, 65, 3,182,185,195, 13, 37, 57,179, 68,105,153,195, 45,242, 32,254, 18,100,141, 25, 73, 64,180, -117, 57,193, 22, 37, 91, 84, 35,190,120,180, 40, 29, 13,228, 95, 63,157,227, 74,215, 15, 35, 7,127,167, 0,173,174, 63,101,123, -106, 23,104, 5, 57,129,133,235,140, 25,160,181,236,210,185,109,203, 8,182, 10,229,139,214,137,106,196,235,176,217,218,183, 33, - 85,218, 82,197,162, 14,190,116,126,195,194, 34,249,162, 14,240,114,175, 30,219, 30,189,175,165,135,193, 70,171,204,200,216,177, -203,140,140, 31, 63, 3, 0, 84, 46,181,220,195, 98,196,200, 72, 41,214,160,104,209, 10,192, 0,222, 77, 85, 27, 98, 7, 95,134, -193, 9, 18,228, 86, 12,229,163, 68,169, 97,171,158,131,105, 12, 15,103,164,239, 31, 61,234,119,182, 93,187, 22, 4, 6, 52,122, -231,194,145,130, 0, 21,100,169,102, 34, 4, 89, 28,247,185,184, 76,147, 50,165, 77,137,166, 53, 77,189, 64,139,210,119,172,172, -184,203, 60,212, 17,138,166, 21,208, 34,120, 97,217, 40, 12, 32,200, 90,185,114,165,178,144,103, 2,208,162,155, 32, 77,154,180, -251, 74,157, 34,197, 35,186, 22,226,252,196,121,141,139,108,210, 84,231, 39,154,251, 84, 40, 95, 62, 0,187, 63,108,206, 73,182, -248,169, 74,180, 28, 1, 45,106,118, 98, 71,143,238, 80, 66,252,181,244,211,127, 76, 57, 9,180, 8, 80,136,144,185, 82, 80,165, - 68, 68,206, 68,228, 84, 83, 81,146,197, 73,142,147, 29, 39, 39, 78,166, 26, 21,184,207,206, 79, 26,252, 56, 44, 1,151,165, 68, -171,127,255,254,193, 96, 1,244,238,107,208, 12,118,239,192,213, 12, 59, 27, 65,129, 42,201, 82,203,200,242,241,125,116, 5, 1, -122, 90,187,155, 18, 34,159, 15, 85, 91,252, 96,233,118,128, 54, 62, 52,250,166,193,125,159, 62,125, 20,213, 33,119, 70, 18,188, - 48, 47,104, 38,116, 84, 78, 12,248,143, 96, 72,125, 14,171,151,211,176, 35, 57,135,103, 47,193,160,252, 26, 0,192,109,128,161, - 7,152,176, 3,160,214,123, 2, 85,220,147,242,229,203,251, 84,168, 80,225, 37,164, 47, 54,109, 1, 44,223, 67, 39,164,170, 77, - 22,121, 75,144,101,105,147,197, 50,170, 54, 2,252,213,209, 70, 33,170, 1,163,240, 43,148, 12, 17,192,178,205,104, 15,245, 57, -129, 22,193,162,150, 68, 43,168,128, 5,104,176,206,114, 81,162,199,118,231,238, 80, 74,220,184,250,162, 1, 63, 85,133,148, 64, - 53,107,214,140,182, 89, 84,245, 57,116,239, 0, 48,124,215,114,119,169, 58,232,176,191,179,222,116,233, 65,192, 74,233, 24,236, -180, 4,174, 57,216,246, 54, 7,221,127,204,135,172,163, 32, 97,114,239, 0,199,165, 74, 40, 30, 7,225,122,248,234,136,116,239, -160,250,251, 82,193,203,229, 11,219, 87, 13, 29,210,241,102,195, 31,178,250,159, 62,208, 64,238, 92, 26, 44, 79,239,207,147,121, -127,182,151, 98,197,138,209,141, 8,141,150,109,238, 54, 84,217, 66,144,245,201,124, 97,121,174,172,166, 63, 85,144,197, 95,130, - 46,170, 17,105,179,117,243,230,204, 4,222, 55,254, 72, 78,215, 15,139,231, 53, 40, 48,168,255, 55, 10,208,234,217, 37, 63, 36, - 11,182,119, 95,170,101,157, 58,190,169, 2,178, 8,182, 40,217, 90,133,157,138, 80, 55, 70,165,129,124,163,250,185,255,164,235, - 7,250,217,202,157, 53,242,104, 24,206, 43,225,122, 80, 54, 93, 59, 58,117, 52,237, 23,207, 2, 23, 13,241,104,167, 53,191,108, -217,152,195, 99,197, 42,170, 74,181, 88, 16,170, 10,103,194, 22, 75, 45, 20,236, 13, 98, 65, 45, 88, 2,190,181, 98, 2,100,213, - 1,216,202, 98, 7,108,252,229,222, 65,100,224,227,197,139, 59, 60,152, 60,185,126,234, 84,169, 94,114,238,177, 4, 89,156, 87, - 84,144,197, 69, 24,199, 65,228,179, 57,134, 2,108,132,160, 25, 47,102,204,135,252,222, 57,215,217, 83, 29,114, 44,229, 98, 11, -141, 67,103,205,182, 64, 81, 8,154,116,225,192,133, 41, 15,150,133, 26, 6,210,231,162,141, 32,139,246,132,180,113,229,152,146, - 52,113,226,163,122,104,178,238,139, 71,141,106,147,194,197,229, 29, 23,255,164,105, 9,178, 56, 63,113,195, 14, 23,218, 9, 17, -201, 68, 47,205,143, 65, 54, 90,142,128, 22,237,127, 99,198,136,161, 57, 39,125,241, 78,247,207,122,161,165, 84, 75,187,100,156, -192, 9,180,244,128, 44,117,114,178, 49,137, 91,111,215,109, 14, 9,201, 59,110, 23, 37, 80, 35,120,163,241, 34, 1, 16,129, 22, - 37, 16,220,234, 79, 9, 13, 60, 60,115, 18, 35,202,183,142,187,102,211, 97, 41, 36, 28,126, 84, 23, 82, 84,171, 26,191,243, 29, -180, 29,227,193,247,192,166,136,118, 84,122, 29,150, 86,134,122,240, 45, 39, 88,138, 79,105,155,179, 98,197, 10, 69,125, 68, 67, -120,170, 12,153,192, 39,150,177,178, 13,142, 90,151,179, 16, 28,176, 94, 4,168,122, 77, 67,114,242, 64,221,217, 1,209,108, 32, - 12,119, 95,193, 3,189, 98, 15, 0,135,158,175, 49, 73,232,114, 88,202,118,226, 71, 76, 94,178,189,248,129,241, 96,221, 9,188, -200, 79, 30, 78,180, 81,136,170,192, 73,231, 21,174, 20,105,180, 78,219, 52,242, 2,246, 89, 90, 18,173, 80,109,132,190,241,216, - 82,132,110, 75,117, 72,208, 26,100,163, 69, 55, 12,214,135,173,118,207,143,250,159,132,106,247, 53, 7, 46,242,148, 42,100, 14, - 54,180,113, 35, 24, 2,112,245,133,159,179, 51, 32,166,233,176, 20,237,237,105,203,145, 46, 37,163,172, 59, 55, 62, 16,200,114, -199, 37,193, 55, 7, 73,208,182,222,109,250,213, 57,153,252, 90, 28,150,218, 3, 47,104,219, 98, 5,243,166,120,236,177,174,102, - 32,119, 35, 46,158, 85, 89, 96, 4, 79, 96,109, 15,100, 5,183,145, 10,180,166,142,107,170, 72,178, 84,144, 69, 53, 34,237,183, - 6, 15, 46, 23,149,187, 17, 87,173, 26, 28,157,238, 31, 70,143,254, 54, 65,183,142,185,253, 25,162,167, 91,199, 60, 31, 25,136, - 58,168,163,134,104,119,181,172,167,143,205, 93, 70,176, 69,112,168,130, 82, 6,154, 38,168,250, 4,215, 15,244,179, 69,167,166, -170,223,173,250,216,165, 72, 3,122, 91, 52,181, 71,109, 93, 57, 62,123,255,132, 10,176, 12,220, 53,148,153, 92,185,114, 12, 24, -194,151, 36,128,162, 13,150, 90, 58, 74,179,144,210, 16,100, 17,108,241, 62,129, 22, 22,150,150,246,110, 33,202, 73,231,162, 39, -166, 78,237, 3,196,242,235,179,149, 43,219,210,133,131, 58, 63,113,124, 34,200, 34,232,224,194, 88, 5, 89, 28,111,172,230, 36, -187, 52,179,167, 77,123,140,106, 65,106,102,248,189,115,188, 35,224,162,201, 8,199,126,106, 87, 40, 37,175, 92,185, 50,181, 44, -140, 92,162, 30,118,105, 54, 42, 87,110, 9, 93, 56,112,145, 79, 73, 59,129, 17, 65, 22, 23,132, 4, 89,212, 52,112,174, 43, 82, -184,176, 63,163, 26,232,161,201,186, 63,132,163,214, 30,245,235,255, 6,159,132, 1, 92, 96,178,172,156, 75, 56, 62,145, 46,199, - 80,150, 23,115,200, 71,208, 84,109,222, 28,242,147, 52, 51,166, 79,239, 80,117, 72,219, 84,208,180, 20,166,124,142,190,164,171, - 19,255, 67, 51, 57,118, 88,106,171,208,156,192,217,105, 41,154,100,135,102,162,154,139,157,152,147, 17,165, 88,236,148,150, 59, - 42,116, 0, 45,190,138,198,158,211,224,168,242, 35,119,219,241, 3,161, 74,138, 82, 34, 54, 36, 1, 23,222,205, 14, 50, 45, 40, -175,158, 9,151,121,202,211, 25, 41, 38, 88, 51, 87, 57,236,216, 76,236,136,144,110, 4, 4, 73,178,236, 25, 47,219,235, 48, 85, - 40,173,234,216,177,163,153, 82, 12,118, 96, 78,176,116,128,216,176, 97, 67,210,116, 54,172, 79, 36, 60,211, 18,245,123, 8,195, -239, 0,130, 22,130, 3,168,162,188, 9, 10, 32, 37, 11, 64, 29, 30, 98,183, 92, 75,212, 71, 87, 8, 30,122,227, 87,109,208, 88, - 95, 2, 12,213,191, 20,219,137, 42,174, 48,180, 81, 48,207,225,188,244, 58, 7, 8, 58, 23,133,161,188, 2,100,130,194,239, 56, -234,235,161,248, 9,181,232, 38,170,160,213,131,146, 70, 26, 89,210,102,142, 6,246, 4, 71,148, 26,214,175, 95,159,147,228, 38, - 27,196, 29,125,212, 12,193, 51, 19,233, 4,163, 9, 64,122,200,248,156,167, 96,248, 62, 15,116,116,135,224,129, 33,252,183,120, -255, 27, 85, 34,168,150,149,252,101,217,217, 94,148,106,114, 80,163,235, 17,128,208, 87,160,111,237, 25,255,115, 12, 62,159,149, -230,215, 18,130,199, 17,120, 65, 59,196,130,131,223,225,185,178, 39, 59,159, 44, 89,156,109,248,239,104,103,100, 40,160,117,230, -232,156,229, 4, 91,148,108, 81,141,104, 47,136,116, 80, 0,234, 1,157, 90,185,249, 52,169,155,228, 23,123,147,163,117, 76, 72, -107, 47,250, 12, 56,173,130, 43,122,144,103, 76, 68,254,167, 75, 8,123, 52, 35,104,114,249,172,125, 41,168,140,145,232,230, 1, -182, 85, 69,118, 15, 24, 16,149,170, 66, 26,188, 35,125,195,112, 59,240, 2, 95, 5,106,197, 60, 4, 95, 84, 41,194,174,171, 81, - 16, 16,179, 28,243,172,203,169,132,224,217, 59,120,112,159, 79,239,223, 15,160,159, 44,206, 77,150, 32,139, 99,138, 37,200,210, - 2, 90, 28, 99, 85,154,190,207,159,255,214,184,118,237,181,121,243,228,241,163, 20,138, 99, 39, 77, 80,184, 73,135, 54, 84, 4, - 92,137,226,199,247,197, 51, 93,145,130,165,114, 56,183, 91,206, 15,126,126,191,184,102,202,116, 31, 0, 77,217,148, 67,186, 28, -235,184,113,139,115, 29,165,247, 48, 19, 9,196,120,197, 88,178,186,235, 78, 63, 89,111,247,239,111,217,239,135, 31,134,194,240, -253, 29, 84,143,129,180, 33, 85, 37, 89, 20, 0,112,129, 13,173, 20,119, 8,166, 15,106, 19,135,252, 36,205,236,110,110,207, 84, -223,131, 92,152, 83,112, 65, 96, 72, 0, 71,233, 61,105,226, 27,179,148,230,125,142,190, 20, 65,221,252,111, 33,227, 60,208, 98, -128,104, 78,226, 76,116,114,201,196, 29,107,106,162, 61, 22, 19,193,149,154, 0, 32,156, 9, 42,205,129,112, 21, 84,100,129,156, -188,169,226,193, 78,174, 64, 92, 91,169,119,144,180,193,202,248,180,191,162,177, 59,119, 22, 50,241, 60,200, 38,203,145,186,208, - 81,135, 73, 16, 68,243, 32, 58,217, 59, 38,208, 60, 24, 68,211, 81, 0,108, 71, 52, 99, 3, 8, 76, 4,136,121,138,143, 46, 16, - 62,185, 30,128,175, 79,177, 90,112, 58,168, 52,140,240,149,118,250, 76,109,100,130, 19, 83,119,130, 75,170, 99,169,166,163,212, - 17,128,203, 93,163, 27,219,170,123, 50, 0,180, 11,176, 27,123, 75, 85, 36, 7, 73, 14,138, 92, 61, 18, 12, 99, 64, 11, 44, 91, -182,236,107, 0,209, 11,160,157,204, 73,160, 21,214,175, 42, 84, 57, 1,182,202, 65, 53,250, 24,126,217,252,184, 66, 38,232, 82, -253,244, 80, 82, 74,105, 36, 60,143,251, 6, 5,153, 46,247,119,149, 51,172, 21,182, 53,137,127, 45, 65,165,181,192,139, 19, 60, - 9, 5,180,168, 62, 84, 19,165, 92,142,128,150,229, 61,187, 64, 11, 42, 85, 69,181,106,153,172,212,172,170, 83, 83,134,235, 33, -200,226,127,171, 58,124,142,137,236, 75,209,140, 4, 96,245, 45, 64, 84,171,225,113,227,230,164,177, 59,165, 87,248, 85,130,198, -171, 82,172,161,145, 35,215,239, 21, 37, 10, 55, 0,164,214, 81,119, 37, 8,242,196,116,233,250,167, 79,147,230, 13,129, 21, 5, - 0, 84, 33, 82,115,193, 5,166,181,234,223,145, 68, 75, 5,133, 42,205, 27, 27, 55,246, 60,187,123,247, 47,223, 85,170,180, 19, - 54,184, 31,184, 8, 36, 24, 74,159, 54,237, 7, 72, 7,230, 35,191,173, 57,196, 22, 63,131,203,185,126,252,248,161, 89, 50,103, -190,143,141, 83,102, 53,156, 29, 77, 16,168,134, 44, 89,162, 4,189,187,123, 57, 91,119,150,243,249,197,139, 61,253,159, 61,235, -177,121,229,202,161,216,137,248,180, 84,201,146,102, 46,178, 41,201,162, 42,146,118,164, 88,176, 82,250,164,110,214,112, 88, 78, -210, 28,220,187,247,226,194,144,174,209,221, 14,199, 62,106, 68, 8,188, 8,226, 96,155,250, 30,115,205, 99, 8, 1,106,218,235, -243, 78,124,127,255,230,172,206,169, 14, 35,136, 19,122, 62,234,194,120, 23, 37, 24, 76, 60,215, 58,244,208,212,162, 97,125,255, -239,162,153, 30,157,119, 59,140,222, 61, 80, 32,117,229,225,168,236,127, 71, 57,163,226,227,155, 5,207,238, 23, 1,148, 46,230, -206,157,123, 22, 10, 24,202,215,141,142, 65,146, 89,248,209,151,193, 0,208, 7,106,186,173,168,251, 93, 72,160,238, 2,212,111, - 5,128,237,195,123, 22, 3,195,223,217, 70, 44,103, 85,148,113, 45, 22, 19,231, 49, 88, 63, 0,144,125,128,114,158, 7, 64,166, - 87,104, 74, 29,236,121, 5,255, 59,218,200,217,254,206,252,193,229,204,149,197, 84,199, 17, 32,176, 36,110, 97,207,165,128, 8, - 62,235,228,192, 27,153,126,178,130,124,101,105,186, 70,176, 44,167,245,187,245,216,136,217, 97, 76,112,221, 85, 99,120,130, 43, - 53,105, 73,180,244, 0, 45,189, 13,146, 11, 1,168, 33, 69,251,133, 97,123,108, 60,243,213,245, 37,235, 58, 0, 88,165,128, 51, -210,154, 80,253,245,162, 67, 82, 72,144,218,224,188,175,149, 77,150, 46,233,189, 74,155,118, 95,169,224,241, 61, 77,242,228,175, -145,124,211,186,184,248,166, 75,145,226, 53, 13,223,105,147,229, 96,241,111,151,159,164, 57, 24, 90, 17,168, 60, 91,162,124,253, - 58, 68,141, 58, 34, 93,164, 72,219,177,226, 91, 3,195,206,236, 14,218, 83,147, 38,118, 92,254, 88, 44, 70,140,141,153, 48,222, -197,137, 21,235, 61,210,187, 20, 16, 74, 64, 16,208, 25,116,157,174, 59,203,201,157,152,116,123,193,196, 50,231, 54,153, 6,194, - 38,235, 6,213,133, 88, 4,190, 39,200,162,132, 94,207,183,105, 89,247, 22, 81,163,142,203, 28, 61,250,241,180,137, 19,223,114, - 73,146,228, 41,104, 62, 64, 57, 15,131,206, 31, 72, 89,116,142,243,122,187,191,145, 47,130, 56,240,213, 15, 20,225,224,131, 81, -247,112, 48,239,223, 56,233,132,131, 29, 70, 95, 10, 7,243,140,190, 20,130, 3,127, 91, 95, 98, 24, 30, 75,227,120,141, 38,253, -219,202,233,100, 87,251,167,149,147, 54, 89, 92,180, 91, 47, 4,255,105,229,116,146,205, 95,101,118,231,124,106,133,163,138, 95, - 75,227, 26,229, 12, 71, 35, 27, 19,217, 63, 99, 34,115,178, 9,141, 62,239, 36,195, 12, 96, 96,151, 3, 70, 95, 50,250, 82,196, -114,224,223, 65, 45, 4,208,226, 71, 98, 43, 57, 83, 85,123, 52, 28, 93,215,162,111,208,180,221, 46, 97,109, 47,131,159, 6, 63, -245,246, 1,227,219,180,207, 1,189, 60,180,204,103,240,211,224,167, 45, 14,252,151,251,146,202,143,176,206,103, 90,223,212,223, -113,223,121,135,165, 17, 84, 74, 99,165, 19, 65,140, 12, 34, 99,240,211,224,103, 68,113,192,232, 75, 17,197,201,191,232, 24,252, - 52,248, 25, 81, 28,248, 47,247,165,136,226,225,127,138,206,215,220, 97, 82,160,165,152,244, 28,182,242,126,205,117,215, 83,103, - 71,121,254,109,117,119,166, 47,124,137,186,167, 1,243,153,244, 30,204,155,202, 42,243,151, 40,167,222,242,253,151,250,146, 51, - 60, 49,218,200, 25,110,105,231, 53,248,169,205, 35,103,114,124, 14,126, 58,243,126, 35,111, 16, 7,108, 53,132,222, 73,203, 94, - 62, 61,141,171,247, 29,106, 67, 89,211, 28, 21, 41,146,233, 19, 19, 50, 32, 74,132,195,195, 94, 94, 61,229,180, 38,156, 26, 46, - 50,186,194,169,235, 18,184,123,224,142, 20, 23, 39, 39,199,172,112,143, 48,153, 78, 52,153,120,142,231,179,106,148, 95,111, 57, -185, 59,166, 61,220, 90,236,225, 46, 60,236,110,217,131,255, 63, 33, 57,181,107,198,162, 44,220,201,195,240, 53,195,144,242,233, -248, 98,130,203,233,146,187,214,202,228,185,107,157, 65, 58,151, 52, 79,141,172,252,229,127, 94,215, 65,199, 50,139,158,186, 59, -211, 23, 72, 91, 15, 77, 39,139, 25,130,166,179,229,153,128, 6, 10,180,209,151, 63,119, 57,157,173,163,189,252, 70, 57, 35,138, -147,127,209, 49,248,105,240, 51,162, 56,240, 57,250, 82, 68,149,237,235,165,131,237,238, 63, 96,146,221,137,180,131,231, 58,106, - 18, 86, 0,227,104, 50,209,106, 92,203,103,199,233, 40,163,245,224,147,130,147,146,234,172, 18,231,129,216,218, 63, 5,117, 30, -101,157,120,157,247, 45,242, 18,152,169, 82, 48,173,114, 90, 23, 45, 5, 66,197,172,130,111, 24,119,132,212,113,135, 35, 62,119, - 4,116, 94,129, 76,150,146, 8,187, 52,177, 5,183,113,209, 98, 37,189,246, 30, 56,122,245,202,181,219, 15, 47, 92,190,121,123, -211,182, 93,199,243,228,205,119,140,247, 28,240,193,154,166, 2,168,176, 53,120, 15,182, 8,223,231, 47,254,119,128,255,148,141, -136,117,117, 27,206, 75,189, 17, 95,236,229,222,189,123, 31,180,110,221,250, 90,164, 72,145,232,150,195,122,155,190, 53, 77, 91, - 18,152,129,112, 86,187, 13, 33, 51, 60,224,222, 98,132, 85,249,108,229, 15,166, 73, 80,245,228,149, 89,152,112,174,252, 6,157, -159,209,217,222,106, 54,173, 54, 10,213, 23, 0, 52, 45,221,112,124,105, 73,102,168,242,160, 34,106,236,198,194, 56,159, 26,148, -120,206, 35,101,172,152, 49, 35,170,127,234, 97,173, 22, 63,245,208,176,206, 99,208, 12, 11,215,236, 63, 99,240,211,224,103, 68, -113,224,115,244,165,136, 42,219,223, 65,167, 96,208, 75, 57,103,211, 94,203, 90,139,160,175, 76, 12, 81, 2,231,112, 94, 76, 56, -231, 4,172,117, 88, 54, 68,168, 73, 2,206, 74,119, 84,175, 94,221,221, 50,241,154, 3,240,194,247, 57,106, 92,229, 29,102,179, -191,130,125, 72, 7,161,109,214, 2, 32,117, 77,147, 38, 77, 98, 7,133,181, 91,206,200,145, 35, 5,110,218,180,105, 7,194, 49, -184, 91, 39, 94,231,125,103,128, 86, 75,147, 41,102,195,152, 49,203, 53, 7,248,105, 18, 45, 90, 39,166, 22,177, 98, 53,202,158, - 48,225,132,251,119,239,110, 65, 96,100,119,196,214,115, 71, 88, 5,119,208,223, 4, 9, 87, 39,139,114,219,171,123,182,226, 37, - 74,157,120,253,198,247,253,189,219,119, 95,252,214,117,192,142,158, 61, 6,175,159, 62,111,213,150,131,199,206, 30,201,145, 35, -247, 17,208,208, 12, 71,130, 60, 4, 76, 27, 16, 98,230, 38,130,158, 62, 64,144,238,231,240, 10,124, 27,206,246, 30,194,105,233, - 27, 4, 43, 13, 24, 48, 96,128,153,158,242,225,180,211, 12,239,198, 1,240,144,127, 22,207,208, 91,178,229, 97, 89,206, 96,224, - 27, 57,114,228,241,136, 79, 24,151, 9, 0,110,184, 10,180, 32,121, 27,171, 94,103, 30, 59,210,196,208, 18,173, 60,181,222, 41, - 0, 11,191,150, 18, 45,244,205,161,244,129,101, 39, 89, 6,129,214, 26, 40, 66,244, 89,244, 83,169, 81,163,198,113,244,167, 62, - 0,158,127,106,149,211, 78,127,203, 6, 7,179,119,224, 67, 44, 68, 24,163,228,249,234,148,204, 81,166,249,160,164,185,106,149, -179,241,156, 90,206, 16,229, 65,223, 99, 20,133,254, 65,249,103,194,161,172, 23, 19,254, 35,164, 28,246,210, 39, 72, 80, 15, 64, - 43,216, 27,127,144, 84, 43,172, 11, 1,173,111, 93,235,219,212,243,188,173, 60, 90,109, 20, 22,186, 6,205,176,112,205,254, 51, - 6, 63, 13,126, 70, 44, 7,190, 78,106,234, 46, 67,235, 95,231,106,131,137,235, 48, 65, 22, 66,144, 16,104,209,137,153,214, 97, - 13, 96,130, 65,137, 61, 0,163, 1, 94,180, 6,115, 78, 68,129, 42,208, 82,223, 1, 47,223,238,101,202,148,225,196, 91,220, 78, -129,109, 73,222, 2,249, 60,164, 45,151, 44, 36, 89, 43, 8,182,240,127,133,122,141,247,153,143,239, 5,109, 75, 53, 99,168,193, -167, 30,194,130, 52,141, 17,163,189,231,236,217,173,125,159, 60,105,143, 25,176, 51,211,173,139, 23,187,252,212,178,229,113,120, - 37, 62,123,245,236,217,221,136,171,231,142,112, 10,238, 0, 57,238, 80, 33,210, 35,177,122,216, 28,208,160, 38,156,177,123,239, -161,203,247,110,223,123,126,245,204,249, 71,131, 59,246,222, 52,164,223,136, 53,191,141,152,186,112,209,138,173,171, 22, 46, 95, -187,145,121,116,212,189, 43,226,122, 93, 71,220,192, 0,132,134, 48, 35, 28,141,185,113,227,198,102,120, 5, 54,187,187,187,191, - 71,104, 7,243,204,153, 51,205,136,249,104,238,212,169,147,185, 78,157, 58,102,120,122,191,129, 56, 93,246, 34, 2, 88, 3,131, - 64, 56,123,244, 68, 32,109, 15,196,178,244,168, 88,177,162,199,183,223,126,235, 81,171, 86, 45, 15, 72,243, 60, 16, 7,210,211, - 25,224,170, 74,182,248,107, 89, 55, 2, 44,132,139,122, 4, 32,247, 8,222,220, 31,193, 19,253, 35,132,147, 80, 18,239,105,241, -211,138, 79,163,170, 87,175, 22, 72,144,133,128,213, 47,224, 37,222, 11,193,198,207,186,185,101, 9, 11,128,201,134, 88,105,207, -232,189, 26, 81, 16,158, 88,190, 39,239,183,173,135,189,124,237,251,186,215,208, 63, 86, 38,207, 89, 59,175, 85, 25,172,129, 43, -251, 38, 99, 57, 62, 70,120, 41, 47,244,197, 90,200, 63,247,250,245,235, 94, 76, 56,159, 3,105,107,114,120,218,223,131, 54,242, -142, 28, 41,146,178,232,208,234,159, 90, 31,179,142,251,198,132,171,131, 73, 78,100, 49,248,233, 4,179,116,100, 53,248,169,131, - 73, 78,100,249, 28,252,116,226,245,255,184,172,214,146,172,144,126,180, 48,137,138,154, 28, 21, 29, 3,250, 58,132, 75,241,194, - 68,204,193,125,157,179,213,132,180, 98, 26, 7,124, 78,166, 8,237,114,189,124,249,242,238,182, 18,239,169,224,133,207, 56,249, -158,209,124, 7, 19,202,120,237,167,159,126,114,135,116,198, 29,129,171,169,138, 91,139, 64,156,170,170,197, 33, 89,170, 5, 9, -250, 8,168,212,140, 60, 15, 2, 90, 33,174, 49, 31,243, 59, 34, 88, 23, 94,117,123,230,200,241,147,223,179,103,237,223,223,191, -223,230,222,234,213, 13,111, 78,157, 90,215,227,183,223,154, 55,172, 82,101,245, 5,136,176, 16, 83,226,236,198,249,243,207,205, -153, 54,109, 23, 2, 22,187,247,234,213,107, 19,188,252,182,209,170, 63, 64,212,129, 11,151,110,220,251,165, 75,255,109, 99,122, -252,186,229,143, 81,147,221,231,204, 90,178, 97,222, 82,247, 21, 75,215,120, 44, 58,122,242, 2,129,214, 1, 45, 58,240,206,126, - 2,225, 23, 30, 1, 8,153, 17, 18,199,140, 80, 17,102, 76,230,102,134,143,128, 4, 43, 0,113, 40,205,136,241,103, 46, 82,164, -136, 25,128,201, 12,126,154, 1,200, 94,131,246, 27, 59,180, 21,224,171, 34, 18,182, 41,226, 80,122, 66, 98,231,113,247,238, 93, -143, 83,167, 78,121, 32,216,183, 7, 2, 98, 43, 9, 18, 51, 71, 64, 43,212, 43, 28, 1, 45,132,230,120,132,246,186, 98, 67,170, -101, 41,209,210, 98,137, 9,146,208, 60, 8,242,125, 22,146,188,179,136,245,229, 5,201,158, 23,226,149,157,173, 81,163,186, 61, -160, 21, 76, 19,239,110,143,126,241,144, 9, 30,240, 71, 48,176, 54,131,125,243, 80,129,150, 42,201,114,201, 93,179,251,230,157, -135,143, 62,122,226,243,180,112,213, 14,191, 39,204, 87, 43,161,189,194,193, 62,206, 21, 65,212, 55,157, 61,123,214,235,193,131, - 7, 94,136,195,233, 5, 73,155, 23, 64,171,146, 16, 51,211, 11,224,213, 11,223,180, 34,225, 2,224, 58, 6,169, 97, 30,205,202, - 26, 25, 12, 14, 24, 28, 48, 56,240, 55,114, 64, 47, 22,249, 27,139, 24,190, 87,179,130, 90, 20, 48, 81,204,130,132, 0, 88,195, -139, 64,139,161, 88,156, 62, 0, 28,126,131,202,105, 7,130,243,186,103,204,152,209,218, 54,199,196,107,188,199, 60,204,235,244, - 11,254,122, 64,181,157,137,130, 16, 42, 5, 17,252,119, 46,130, 55,187,175, 89,179,134,210,168,222,122,104,218, 3, 85,182,128, -150,245, 53,107,250, 8, 96, 22,155,146, 44,130,172, 23,199,143, 55, 29,215,160, 65,199, 44, 25, 50, 92,206,128,104,233, 69,139, - 20,121,217,187, 71,143,123, 55,207,157, 59,121,253,226,197,147, 71, 15, 30, 60, 51, 17,147,250,208, 33, 67,182, 98,146,103,148, -248, 36, 90,229,133, 45,213,230,115, 23,175, 95, 31, 61,246,207, 77,183,174,223,186,179, 98,241,154,173, 91,119,236,219,242,196, -231,229, 29,207,131,167,214, 28, 61,113,110, 53,243,104,209,129, 74,203, 23, 82, 52, 95, 74,170,240,107, 70,232, 29, 51, 38,112, - 51,164,129,230, 82,165, 74,249, 55,106,212,200,220,181,107, 87, 51,164, 81,102, 76,222,230, 98,197,138,153,161, 58,188, 6, 53, -224, 25,123,180,161, 98,155,171,130,107,196,118,188,213,178,101, 75,143,230,205,155,123, 32,134,152, 7,164, 47, 30,176,251,242, - 64,172, 71, 15, 72,206, 60, 64,223, 3,113, 6,111, 5, 1,101,205,141, 8,142,128, 22, 84,176,214,210, 43,173,234, 91,223,143, - 12,160,212, 28, 11,129,163,115,230,204,241, 66,192,107,175, 63,254,248,195, 11, 0,216, 11,177,196,188, 16,200,245, 5, 37, 93, -142, 54, 76, 48,120, 56,236,237, 4,101, 17,240,202, 23,182,109, 74,108, 54, 30,232,231,138, 68, 75,149,100,245, 28, 60,125,165, -107,241, 38, 35,111,220,121,112,127,251,190, 19, 94,201,114,215,178, 12, 46, 28,170,236,148, 88, 81,205, 78, 9, 22, 2,214,122, - 65,122,231,197,111,147,255,175, 92,185,226, 5,224,170,128,172, 97,195,134,241, 91,173,225,108,229,141,252, 6, 7, 12, 14, 24, - 28,248, 59, 56,160, 7,139,252, 29,229,210,241, 78, 85,162,101, 63,222,161,158,202, 69, 4,208,226, 4, 81,169, 82,165,245, 4, - 39,136,136,238, 78,137,129, 90, 1,158,243, 26,239, 49, 15,243,234,168,156,102, 22,128,173,236, 42,221,130, 5, 11, 46,212,124, - 0, 25, 34, 18,104, 53,141, 25,179,180,231,159,127,182, 54, 63,122,212,118,116,253,250,157,146, 37, 77,234,135,168,232, 1, 8, -130,106, 70,224, 78,243,209, 35, 71, 2,218,181,105,243,220,115,203, 22,175, 25,147, 39,123,149, 45, 80,224, 72,214,228,201, 23, -163, 24, 25,245,148, 21, 6,218, 3, 86,175,219,124,250,240,241,115,167,230, 45,217,176,206,247,237,251,215,254,254, 1,111,206, - 93,190,177,251,234,205,251,187,254,156, 61,111, 19,243,104,209,130, 26,244, 44,212,172, 15,160,194, 51, 83,122, 5,201, 8, 1, -150, 25, 18, 29, 51,164,140,175, 9,186,160,238, 83,174, 21, 42, 84,200,140,137,222, 12, 16,187, 31,116, 17,210,204,254,129,119, -103, 0,208,203,170,218, 97,161,157,115, 67,229,165, 72,177,186,116,233,226,193,255,234, 61,254, 50, 63,168,105,186, 47,112, 4, -180,176,169, 32,204, 64, 11,253, 37,125,230,204,153, 23,206,154, 53,211, 11, 18, 56, 47, 0,127, 69, 58, 4,155, 53,175, 37, 75, -150, 40,231,160, 79, 0,195,141, 0,118, 93,128, 0,104,121, 19,104, 81,138, 53,127,254,124,193, 70, 2, 37,125,250,244, 73, 16, - 59, 82, 1, 90,201,242,212,252,193,125,231,161, 35, 15,189,159, 61, 73,145,191,238,192,105,243,215,123,240, 60,121,158,154, 29, -181,218, 11, 64,208, 13, 64,112, 37,108,230,188, 32,113,244,154, 52,105,146, 2,176,176, 72,241, 66,127,247, 2,112, 61,150, 33, - 67,134,159,181,232, 24,247, 13, 14, 24, 28, 48, 56,240, 79,225,128, 30, 44,242, 79, 41,171, 85, 57,180,109,179,244, 84, 46, 34, -128, 22, 11,134,137,181, 29, 36, 2,238,187,118,237,114,135, 10,101,130, 90, 88,158,243, 26,239, 49, 79, 68, 49, 19,147, 77, 6, - 72, 81, 20, 0, 7,144,176, 74, 15, 93, 11,160, 21,108,143, 69,219, 44,107, 27, 45,139,107,118,221, 64, 52,143, 27,183,193,139, -187,119,219,123,111,222,220, 48,115,186,116,215,183,123,120, 4,124,248,240,193,252,206,207,207, 12,155, 55,179,207,179,103,230, - 85,176,139,106,222,168,209,237, 38,213,171, 47, 56,176,114,101,171,102,113,227,194,164, 75,247, 17, 55,153, 75, 10,207,243,151, -174, 93, 63,126,234,226,190, 85,107,183,236,217,179,239,208,177, 71,143,159, 29, 59,119,241,202, 97, 24, 94,239, 5,165,120, 58, -168, 13,106,218,180,233, 25,128, 32, 69, 45, 88,162, 68, 9, 5,100,209, 70, 11,170, 51, 26,194,251, 67,117,230,255,195, 15, 63, -248, 3,116,221,133,250,234, 48,118, 29, 30, 7,221, 24, 58,104, 7,103, 65,112,234,158,136, 8,239, 1,208,225,177,117,235, 86, - 15,254,119,230,121, 53,175, 35,160,245,252,249,115,107,213,161, 46,149, 33,193,126,185,114,229, 14, 31, 61,122,212, 11, 42, 78, - 69, 53,119,243,230, 13,175,115,231,206,122, 65, 5,173, 72,140, 0,158, 20,169, 22,218,190,161,163,114,131,239,222,144, 50, 9, -158, 19,240, 80,249, 5,192, 86, 36, 92,120, 86, 1, 90, 25, 50,148,139, 89,185,113,223, 25,175,223,248,189,173,213,114,192,220, -166,157,135, 45,228,121,233, 90, 93,161,138, 30,172, 39,232,178, 9,224, 52, 58,232,149,132,180, 80,145, 98, 65, 58,232,133,122, -100,193,247, 20, 31,215, 99, 3, 56,182,163, 36, 23, 18,226,176,237,130, 9, 75,227, 24,207, 24, 28, 48, 56, 96,112, 32, 12, 28, -208,131, 69,194, 64,246, 75, 60, 18,126,137, 22, 37, 13,144,120,248,163,180, 84, 49, 10,207, 57,144,135,165,244,176, 87, 73, 0, -192,179, 22,246, 57,238,152,212, 9,170,138, 50,241,156,215,120,143,121,194, 66,219,214, 51, 88,249,183,152, 54,109,154, 59,236, -143,220,113,254,171, 30,186, 42,208,178,181,219,208,214, 53, 75, 91, 46,107,250,141,163, 69,235, 0, 49, 70,167,251,243,231,215, - 65, 52,116, 63, 74,178, 8,178,252, 33,205,186,119,247,174,249,192,254,253,102,216, 39,153, 11, 21, 40,224,115,102,197,138, 58, -175,175, 93,107,196,103,244,148,211, 34, 79,134,114,229, 43,158,122,248,248,217,229,237,158,135, 55, 29, 61,113,118,235,139,151, -175, 79,127, 83,190, 34,141,163,179,232,164, 21, 3,192,233,232,119,223,125,119, 28,147,246, 93,252,154,139, 23, 47,254, 30,118, -110,102,203,148, 56,113, 98, 51, 84,130, 55, 65,147,224, 50,150, 78,218, 74, 54, 96,222,132,176,239,218, 12,251, 34,143, 3, 7, - 14, 40, 54, 90, 53,107,214,220,204,235,206,208, 97, 94, 45,160, 5,163,245, 71, 0,115,143,206,157, 59,167, 91,186, 5, 80, 50, -137,234, 65,216,244, 1, 84, 93, 83,128,214,147, 39, 79,188,158, 61,123,230,101, 54,155, 21,245, 28, 64,232, 33,244,215, 38, 40, -130, 45, 31, 98,193,213, 72,152, 48, 33, 93, 97,200,242,229,203, 5, 0, 86,176,137, 64, 73,215,174, 93, 19,108,114,136, 48,160, -133, 62, 93, 31, 60, 69,145,143,121,209,110,107,213,170, 85, 94,248,134, 54,161, 79, 54,134,250,119, 43, 85,158,171, 87,175,246, -130, 20,205,161,228,209, 89,254, 27,249, 13, 14, 24, 28, 48, 56, 16,209, 28,248,138,129, 86,248, 88,129,201,167, 12,156,104,238, - 32,192, 82, 15,158, 67,226, 65,231,149, 97,218,121, 0,154,205,160,234,112,135,113,189, 59,212, 79, 51,152,120,206,107,188, 23, -190, 18,255,255,105, 76,136,223, 97,146,219, 68, 0,247,219,111,191,113, 23,223, 55,122,104, 71,164, 68, 43, 24,104, 45, 90, 84, - 39, 81,194,132,126,111,223,190, 53, 51,193, 32,220, 12,233,150,121,217,178,101,230,121,115,231,154,179,101,205,250,196,255,248, -241, 42,222,231,207, 55,128,219, 7, 58, 3,117,234,128, 81,250,250,107,215,111, 31, 62,121,246,234,138, 43, 55,238,174,184,121, -231,238, 46, 94,115,138, 8,220, 79, 32,255, 72, 2, 41, 0, 5, 74,178,204,144, 62,153,247,237,219,103, 6, 80, 85,118, 28,130, -230, 3, 11,154,241, 96,104,189, 48,126,252,248,195,245,188, 7,109,219,100,209,162, 69, 10,192,194, 14, 60,143,195,135, 15,123, - 64,130,233,193,235,122,158,183,204,227, 8,104, 1, 24,133, 73,162, 5, 48,178, 7,155, 27, 20,245, 32, 19,193, 11,193, 22,212, -125, 94, 99,199,142, 61, 65,215, 17, 80, 9,234,138, 24, 0,158,120, 99, 67,129, 96,167,166, 64,141,167,168, 15,167, 78,157, 42, -144,218,210, 45,131, 2,180,146,231,170, 89, 59,172,170, 67, 62, 79,201, 47,164,101, 10,192, 2,168,243,194, 38, 6, 69,221, 9, -190,122,141, 26, 53, 74,145,194,113, 3, 75,144, 4,238, 71,103,121,108,228, 55, 56, 96,112,192,224,128,193,129,207,200, 1, 76, - 58,137, 48,177,140,228,174, 38, 24,147, 83, 50, 18, 2,104,113,117,255,251,239,191,123, 65,245, 51,193, 89,123, 42,228,143,131, -213,246, 10, 2, 32,184, 10,216,193,196,115, 94,227,189, 48, 84, 43,132,243, 72,148, 59, 31,118, 24, 14,131,237,138, 34, 37,163, -187, 4, 24, 32,143,135, 90, 40,170, 30,218, 17,105,163, 69, 53,224,139, 7, 15,218,189,218,183,175, 1, 85,135,144,112, 4,248, -248,248,152, 33,209, 49, 47, 7,200, 66,217,204,224,177,127,174,172, 89,143,125,188,113,163,234,209, 69,139, 26, 66,221,168,199, - 33,108,136,170,228,112, 75,119,169, 65,221,202,239,107,124, 95,198,183, 76,201, 60, 47,203,151, 43,248, 54,123,150,180,151,244, -212,215, 50, 15,128,211, 78,164,187, 0, 10, 47, 97,239, 99,198,238, 71, 69,125,248,235,175,191,154, 33, 25, 49, 3, 36, 60,229, -125, 38, 0, 36,111, 0, 19,127,228, 37, 16,119,120,192, 62, 46, 90,201,146, 37, 87, 17,100, 1, 80, 19, 92,253, 9,233,145,135, -167,167,167, 7,140,197, 87,241,190, 22, 13,189, 64, 11,118, 81,186,165, 88,150, 52,209,111,118, 17, 96,169,118, 89, 60, 71, 91, -121,193,181, 3, 85,133, 53,157, 41, 31,248,243,112,242,228,201,130,246, 21, 72,132,223, 99,131,129, 76,159, 62, 93,102,204,152, - 33,144, 10, 42, 64, 43,247, 55,173,126,163, 91, 7,103,141,225,249, 44, 85,134, 80,225, 30, 34,200,194,110, 80, 47,216,205,109, -163,138, 16, 0,246,216,134, 13, 27,188,208,191, 20,187, 50,228, 57, 74,245, 33, 30,137,226, 76,249,141,188, 6, 7, 12, 14, 24, - 28, 48, 56,240, 25, 57, 0,144, 85, 31,170,193, 99,152, 92,189, 48, 65,120, 97,101,238, 5, 7,136,102,130, 45, 38,168,246,204, - 84,169,208,175, 22, 86,232, 94, 5, 10, 20, 56, 78, 21,157, 51, 69,194,224, 95, 23,147,131,226,202,129,137,231,188,230, 12,141, -160,188,170, 83,204, 64,120, 65, 63, 12,195,237, 37, 52,126,135,253,143, 98,151, 69,155, 47,128,172,113,180, 87,209, 75, 59, 34, -129, 86,163,168, 81, 75,109,159, 58,181,181,249,197,139,118, 83, 58,118,108,159, 56, 81, 34,191,137, 19, 38, 4,120,108,219,102, -158, 51,123,182,185, 77,235,214, 1, 80, 41,250,174,159, 50,165,209, 71,111,239, 26, 19,106,212,104,209, 32, 90,180, 98,122,203, -202,124,144,108,148,107,223,182,169,248,250,190,144,167, 79,238,202,166,117,211,101,193,156, 65, 82,188, 72, 46,225, 61,103,104, - 65, 98,117, 31, 18, 17, 51,252,121,153,193, 63,101,231, 33, 29,148,246,235,215, 79, 1,133,144,148, 40, 70,252, 76, 0, 77,102, - 24, 96,155,245, 0, 45, 72, 19,203,193, 69,130, 34,197, 2, 24,216, 8, 30, 39,229, 47,237,181,250,244,233,227,161, 87,218,168, -214,197,145, 68, 11,125, 51, 76, 64, 11,101,154,209,185,115,103,130,148, 19,180,211,218,182,109,155, 34,205,130, 61,218, 94,103, -129, 10,212,235,237,209, 31, 31, 50,193,192,127, 4,119, 26,194, 53,138, 0,100, 10,248,165, 74,180, 74,228, 40,221,114, 64,242, - 92,181,122,234,117,239,160,214, 31,101,138, 7, 73,153,215,153, 51,103,188,176,251,211, 11, 54, 88,138,235, 18, 44, 84, 50, 97, -135,231, 12,180,155, 7,126,255,228,127,103,218,223,200,107,112,192,224,128,193, 1,131, 3, 78,115, 64,181, 43,215,239, 25,158, -158,223,225,224,209, 11,246, 36, 94,144,104,208, 23,207, 9, 76, 66,125, 8, 86, 0,192, 98,224,183, 43,189,100,159, 60,121, 82, -177, 93,129,221,145, 45,111,241, 14,213,138,152,128,210, 90,121,129, 39, 80, 74,171, 81, 61,107,154,161,156, 98,170,158,220,231, -205,155,231,142, 50,110, 4,120,251, 25, 54, 64, 84,137,217, 59, 66,149, 51, 2,128, 86, 48,205,150, 80,199,209,189,195,243,251, -247,219,190,187,121,179,209,159,189,122,181,118,205,144,225,106,146,196,137,223,194, 96,218, 55,107,230,204,231, 87, 77,158,220, -216,255,238,221,106,167, 87,172,168,135, 93,138,109,186,216, 54, 48,119,200, 79, 55,215,116, 50,117,194,175, 50,126,116, 47,233, -217,249, 7, 37,185,102, 74,163,229,182, 35, 20, 77,128,130,243, 52,214, 70,242,165,147, 82, 26,196,247,236,217, 83, 1, 90, 19, - 38, 76, 48, 67, 42,101,222,184,113,163,146,134, 14, 29,106,134,219, 12,107,160,101,179,156,232, 55, 19, 1,202, 61,160, 42,245, - 0,109, 84, 81,217,221,217, 5,224,205, 3, 52, 60,120,223,153, 54,114, 4,180,188,189,189,245, 0,173, 80,229,164,221, 33,250, - 75,183,252,249,243, 31,225, 2,131,139, 9, 2, 45, 92,219,162,243,179,115,212, 70,217, 0,122,159, 64, 74, 40,216,133, 25,194, - 97,169, 42,217,210,225,176, 52,184, 24, 4, 90, 4, 88, 84, 21,194,185, 44,193,160,158, 13, 15,234,243, 97, 82,249, 59,249,109, -234,100,153,195,108, 70, 57, 35,130,139,255,167, 97,240,211,224,103, 68,113,224,115,244,165,136, 42,219,223, 65,199,121,207,240, -152, 0,119, 16,100,193,190,196, 11, 43,241, 99, 0, 94,214,222,170, 57, 73,102,227, 61,130,172, 32,223, 90, 59,173,106,167,213, - 16, 33, 28, 90, 6,121,175,214,178,127,209, 4, 90,240, 3,181, 3, 70,220,244, 4,255,147, 78,149,166, 35,160, 21,214, 93,135, - 33,104, 34,216, 96,166,206, 25, 50,252,244,244,218,181, 31, 63,190,120,209,196,255,226,197, 26,126,167, 78, 85,245,191,112,161, -178,220,185, 83,149,146, 44,130,172,150,137, 18,253, 84,199,100,178,140,167,103,201, 82,187,252, 12,150,104,189,121, 46, 79,188, -239,200,198,181,211,100,254,236,129,122, 36, 90,118,105, 2,244,222, 37,208,130,186,203, 12,219, 34, 51,124, 95,153, 33,145, 50, - 3,180, 62,133,234,235, 49, 19, 36,159,207,186,119,239,174, 11,104, 85,169, 82,101, 21,108,189, 20, 47,240, 80,235, 42,174, 43, -248,219,160, 65, 3, 15,168,186, 60,160,214,117,199, 37,123, 6,230,193,229, 12, 14, 42,173, 29,130, 71,107,167,161,221,186,115, -135, 30,250,207,112,248, 12, 59, 1, 99,122, 2, 45, 15,157, 95,174, 86,159,207, 6,199,176,119,224, 77, 63,100, 8,158, 92, 53, - 75,100, 47,211,226,215, 20,185,107,126,103,227, 61, 54,105,170, 64,235,200,145, 35, 94, 48,134, 55,128,150,206, 6, 66, 54,173, - 54,210, 79,201, 0, 48,228,128,193,207,176,244, 24,251,207,252,151,249, 25,177,156,252,178,212,172,253,103,105,123, 78, 8, 10, - 32,189, 3, 96,106, 55,206,237,186, 26,208, 8, 52,173,167,195, 56, 10, 32,109,139, 77,182,104, 6,171, 14, 97,196, 61, 63,200, -251,187, 51,246, 40,118,129, 86, 56,118, 29,134,162, 9, 95, 0, 25,154,197,140,217,118, 89,247,238, 63, 94,218,177,163, 25,118, - 23, 54,126,118,225, 66,195, 99,139, 23, 55,162,186,144,146, 44, 7, 32, 75,115, 64,115,205,156,198,163, 74,197, 98,210,185,125, - 93, 37,241,156,215,194, 33,133,200, 15, 53,226, 61, 0,170, 71, 80, 21, 63,130,113,252, 35,168,188, 30, 81,226,101, 65, 51, 53, -108,145,246, 67, 66, 99,233,192,214,102,187, 3, 12, 54,134,100,116, 45,192, 89,136, 14,136, 62,214,168,116,233,210,107, 96,235, -231,200, 93, 66, 48,205, 47, 24, 84,218, 68, 31,108, 72, 19,144,122,232,252,102,245,244,121,157,164,130,179,217,164, 73, 41, 45, -237,175,104, 4,143,157,155, 39, 52,164,182,214,239,252, 98,229,116,182,178, 78, 46,214,194, 66,254,191, 92,247, 74, 97, 97, 88, - 56,198,144,176,190,238,191,220, 70,255,229,186, 59,236, 47, 48, 18, 47,130, 84, 45, 40,241, 92,253,111,121, 94,209, 34, 15,243, -170,255,139,144,184,197, 51,193,215,109, 92, 83,223, 97, 73,171, 40,242, 57,229,202, 40,172,157,223,217,231,244,118,152, 16,134, -236, 97,252,168,157,161,161, 57,233, 0, 20,180,165,250, 80,111, 98,126, 61, 19, 4, 85,130,176,217, 42,222, 44, 86,172,122,220, -141,200,221,133, 52,124,167, 77,150, 29,117,161, 37, 89, 93,252,116,115,115, 83,236,232,116, 54,150, 46,154, 58,105,169,217, 62, - 43,205, 96,137, 86,238, 90,231,146,230,169,145, 21,192,235,156,101, 80,105, 39,202,250, 89,203,233, 68, 57,180,178,218, 45, 39, - 36,202,157, 16,135,241, 40, 22, 60,221,180,136,232,233,159, 78,210,208,252,142,194, 73,143,143,127,245,109, 20, 14, 30,124,142, -186, 27, 64, 43, 28, 13, 98,227,209,207,209, 70,255,101,154,118, 91, 71, 5, 67, 65,115, 27, 55,230, 41, 96,232, 47,236, 20,242, - 92,205,163,222,179,248,101,230,224,103,244, 62,203,124, 48,157,233,143,103,203, 59,209,125,180, 37, 90, 78, 16,115,148,245,191, -220, 97,140,186, 71, 80, 39, 10, 34, 99,240,211, 14, 63,245,238,164, 53,128, 86, 48, 7,140,190,100,124,155, 17,197, 1,163, 47, - 69, 20, 39, 53,232, 56, 2, 85,142, 64,151, 21,176, 10, 5,180,108,128,177, 96,224,102, 11,148,125,161,234, 58,245, 26,163, 19, - 58,197, 46,205,204, 6, 63, 53, 89,228, 84, 6,131,159, 78,177, 75, 51,179,193, 79, 77, 22, 57,149,193,224,167, 83,236,210,204, -108,240, 83,147, 69, 78,101,248, 28,252,180, 91,128,207, 5,180, 84,186,150,128,203, 90,210,101, 33,209,114, 84,103,235,221,134, - 33, 36, 90,124,208, 86,114,134,227,246,104, 56,186,174, 69,223,160,105,187, 93,194,218, 94, 6, 63, 13,126,234,237, 3,198,183, -105,159, 3,122,121,104,153,207,224,167,193, 79, 91, 28,248, 47,247, 37,149, 31,186,231,179,136, 0, 90,182, 84,140,142,174, 57, - 41,209,114,126,215,161,214,200,160,243,254,231, 64,188, 6, 77,157,204,215,153,205,224,167, 78, 70,233,204,102,240, 83, 39,163, -116,102, 51,248,169,147, 81, 58,179, 25,252,212,201, 40,157,217, 12,126,234,100, 84,120,179,217,177,209,170, 74,219, 41, 74,156, - 44,164, 78,223,218, 2,101,106,158,176,216,104, 89,171, 31,237,212,197, 82,130,165,238, 64, 12,111,181,117, 61,111,116, 66, 93, -108,210,157,201,224,167,110, 86,233,202,104,240, 83, 23,155,116,103, 50,248,169,155, 85,186, 50, 26,252,212,197, 38,221,153, 12, -126,234,102,149,174,140,159,131,159, 14, 95,108, 99,215, 97, 12, 92,227,110, 64,203,157,136,209,236,236, 70,180,222, 73,232,204, -174,195, 16, 59, 23,117,113,231, 11,102,250, 28, 13,241, 69,104,230, 79, 25,121, 88,173, 34, 41, 61,152,106, 22, 78,225, 81,163, - 96,114, 37, 85, 43,144, 76, 73,223,231, 79,186, 77, 73,121, 19,111,251, 46, 79,162,109,121, 93, 76,195,172,248,234, 84, 57,179, -165, 54, 37, 41,235, 26,107,113,233,204, 49,239, 4,165, 5,185, 19,152, 18, 57, 67, 51, 71, 10, 83,206,130,169, 76, 11,242,167, - 52,157, 97,226, 57,175,105,180,183,222,114, 70,202,157,220,212,190, 80,134, 56,158,223,230, 79,251,176, 64,250,152,123,114, 37, - 55, 49, 30,163, 45,191, 87,154, 52, 93, 19,155,138,103, 74,100,114, 71,218,146, 53,137, 73,207, 78, 14, 77,154, 97,232,215, 6, -205, 48, 48,205,193, 35, 6, 63, 13,126, 70, 20, 7, 62,107, 95,194, 68, 28, 37, 60,201,162,146,193,229, 4,189, 72,225, 73,182, -104, 70, 20, 51, 65,231,179,242, 51, 2,203,105,144,194,196,218, 33,151,139,233, 9,146, 55,207,117,112, 36, 68,227,230, 74,101, -170, 88, 56,109,148,187, 72, 15, 64,163, 65,206,100,166, 20,182, 18,239, 49, 15,210, 61, 62,227, 12,216,200,157,198, 84, 53,127, -170,200, 62,121, 83, 70,122, 13, 58, 83, 80,206,138,197,211,152, 98, 57, 11, 54, 8,176,184,245, 96,247,140,174,226,119,120,170, -188, 61, 48, 81,222,238, 27,203, 75,178,115, 66, 51,241,221,254,171,188,217,214, 87,222,108,233,169, 92,171,154, 59,193, 86,103, -202,105,153,151, 32,171, 74, 62,151,135,247, 79,184, 7, 6,190,188, 45, 31,159, 93,149,243,155,167,124,172,144, 35,225,125, 43, -176,101,247, 99,201,151,202,212,166,102,201,236, 87,247,238,220,118,227,218,165,139,222, 87,206,158,124,224,185,126,209,249,218, -197, 51, 92,230, 61, 39, 38,199, 72, 4, 80,249,210,197,216, 83, 34,107,146, 7,121,211, 68, 83, 0, 85,158,212, 81, 55,110, 95, - 62,237,190,249,249,237, 87,239,111, 31,126,243,230,230,225,167,179, 71,116,185,149, 39, 85, 20, 58, 25,141,236,108,221, 1,176, -214,155,221,219, 5,202,182, 14,146, 35,101, 84, 45, 95, 95, 36,111,179,238, 57, 93, 76,141, 81,190, 63,181, 18,243,217,224,129, -174,193, 39,135,139,105,110,206,228,166, 67,160,209, 13,239,113,113,182, 47,233,248, 78,180,178,232, 42,167, 22, 17,103,219,200, - 73,122,118,219, 40, 12,116, 44, 31, 49,234, 30, 78, 6, 26,237, 30,204, 1, 75, 80, 20, 10,104, 69,138, 20,105,159, 94,240,165, - 23,104, 33, 95, 9,189,224,203, 0, 90, 17,219,209,191, 90,106, 0, 46,207,229,205, 61,145,151, 55, 4,231, 62, 58, 42, 18, 98, -144, 4,112,122, 36,239,158,137,188,121, 40,179,250,214,148,169, 61,106,202,196, 46, 85,101, 92,135,111,101, 76,219,178, 50,226, -199,226, 50,180,105, 33, 25,210, 32,151,136,223, 83,145, 23, 55,164, 80,154, 40,143,156, 25, 40, 10,164,142,236, 19,120,115,167, -200,165,213,178,180, 75, 1, 25,213, 32,139,148,207, 26,251, 41,202,219,218, 6, 32, 80, 73,135, 26,204, 9,180,118,255,209, 85, -126,252, 54,211, 61, 85,146,213,226,155,244,119, 9,178,154,149, 73,125,151,146, 44,166, 38, 37, 83,222,217, 49,162, 90,184,128, - 22, 37, 89,119, 15,175, 10,252,116,123,183,152, 55,183,151,119, 27,219,200,235,179, 27,100,215,140,206,159,202,101,137,185, 64, -235, 3,204,238, 98,202, 85,187, 84,206,203,111, 94,189,242,127,116,247,234,235,249, 35,235,122,205, 31, 88,247,136,199,172,129, - 94, 23,246,174,187, 84,179,104,218, 75,204, 99,167,189, 44,235, 30, 25, 96, 98,147,251,252,113,247,222, 61,185,250,242,237,141, - 3,111,158,157,217,250,104,100,215, 58,222, 27,230,141,241,125,127,113, 99,192,253, 63, 42,155,175,142, 41,100, 62,255,123,105, -243,173, 77, 67, 3, 38,247,109,122, 21,188,237,234, 76, 27, 49,111,250,132, 38,119, 21,104,101,115,137,106, 29, 81,192, 86, 81, -109, 78,184, 4, 88,230,155,123,228,253,254,209,242,206,115,152,188,219,245,155,248,109,239, 39,126, 91,123,136,159,123, 23,121, -187,177,189,188, 93,215, 74,152, 47,172, 64, 11,207, 62,120,124,245,120,224,233,189, 27, 62, 52,175, 86,228, 9, 64,215,252,156, -127, 73,225,172, 1,166, 30,176,145, 45,115,210, 40,119,210, 37,138, 18,194, 51,124,133,108, 49, 75, 54, 43, 28,107, 80,153, 44, -177,203,133,181,156, 58,190, 71, 3,192,252,197, 1, 3,188, 57,217, 89, 52,178,127,117,252,180, 5,168, 8,180, 80, 79,174,155, - 53,165, 93,206, 0, 45,228,165,202, 74, 83,218,165, 49,206,247,198,253,171, 65,137,231,206, 30,182,218,136,225,238,232,196,147, - 73, 43,244,157,238, 49,217,217,130,253,139,242, 91,251,205, 10,155, 31, 45, 76,168,239,228,245, 29,145, 89,185, 9,180,222,233, - 96, 80,136,198, 45,148, 54,202, 75,121,255, 66,228,249, 85,121,186,111,186,200,149,117, 34,231, 23,139,156,252, 83,228,232, 4, -145, 3, 67, 69,246,244,147,167, 75, 26, 2,204,221, 18, 57, 62, 69,242,165,142,252,194,234, 61, 14, 63,106, 5,104, 93, 92, 45, -178,182,158, 60, 89, 80, 91,100, 67, 99,121,183,188,182, 76,106,158,157,101, 94, 97,167,204,161,104, 82, 93,232,119,120,154, 16, -100,169,207, 80, 85,232,187,227, 55, 33,192, 82,175, 81,146,245,122, 93, 59,169,156, 59,126,152, 37, 90, 80, 21,222,253,248,248, -140,152,183,116, 16,255,165,223,201,227, 25,229,228,248,196, 58,114,106,245, 72,161, 26, 81,227, 3, 52, 65, 69,184,196,115,219, -230, 27,143,239, 94,121,253,224,250,254, 23, 91,198,124,115,122,251,136,178, 39,183, 15, 44,115,232,200,159, 93,142,237,157,251, -203, 33,230,209,170, 59, 1,211,246, 37,147,238,250, 93,221, 17,112,115,122, 21,243,153, 97,249,204, 94, 35, 75,154, 47,173,232, -107,126,124,122,139,255,237,105,229,205,143, 60, 70,153,159,122,173, 54,159,154, 92,203,188,187,127, 94,243,169, 85, 67,239,230, - 75, 27,253,132,189, 54,114, 75,102, 42,221,245,135,162, 15,167,244,172, 35,147,123,212,146,137,221,106,202,132,174,213,100, 72, -219,202,210,179,105,121,233,214,168,172,252,218,226, 27, 25,221,174,188,140,108, 83, 78, 70,180, 46, 35,237,191,203,241, 22,170, - 69,235,160,218,118, 37, 90, 0, 62, 23, 63,220, 59, 34,239,118,244, 23,158, 91, 74,183,248,223,255,212,252,240, 0,173, 72, 0, -159,119, 15, 79,170, 19,248,240,180, 71,224,123,132, 56,122,124,227,108,224,212,129,237,223, 66,210,229, 44,120,203,214,173,108, -140,103,242,209, 95,138,103,136, 26, 34,214, 97,187, 18,177,135, 5,190,188,245,250, 96,247,228, 43,203,102,137,101, 29,238,234, -171,155,200,116,140, 13,122,179, 24,117,215,203, 41,125,249, 12,126,254,133,166,236, 73,180, 20,163,106, 45,176,229, 12,208,186, -115,231, 78,126, 61, 96,203,222, 56, 15,103,216,101,131,202,164,104, 79,120, 14, 71,197,190,106, 66, 36, 20, 95,139,116, 63, 40, -191,117,111, 8,209,238,213,170, 85, 75,141, 12,101, 65, 78, 73, 60,183,151, 16, 21,164, 84, 80,126,135, 52,245,117,191,127,117, -174,136,217,117,136,137,216,235,206,236,154,114,101,112, 6,130, 22, 47,103, 89,150, 51,133,169,239,252,190,213,196,235,207, 22, -178,103, 92, 67,233,219,160,168,244,250,161,128,116,175,149, 71,186,124,159, 77, 58, 86,118,149,246, 21,210,203,250, 94,133,228, -233,236, 74,242,107,141,180,146, 43,133,201, 41,244, 14, 85, 99,165,124,169, 34,191,204,147, 34,210,187, 34,144,160, 53, 47,233, -242,233,236,196, 42, 34,235,234,203,200,134, 89, 4,147,102, 91, 61,229, 86,128,214,193, 73,161,128,214, 27,143,254,161,128,214, -171,213,173,108, 1, 45, 61,175, 49, 65,210, 84,108,104,155, 74,175, 62,220,222, 43,126, 11, 42,202,227,233,229,228,192,144,146, -178,170,223, 55,178,105, 82,103,107,160,101,147, 38,236,177, 46,220, 56,127,234,241,234, 49, 53, 79,123,142, 43,119,222,107, 92, -169,139,231,127, 47,118,241,204,176,162,103, 78,143,250,230,232,181,141,163,142, 51,143, 86,129,138,100,138,239,229,255,236,198, -235,171,147,202,155,239,123,140, 53, 63, 62,186,194,124,104, 76, 21,243,150,158, 57,204,251,199,215, 15, 56, 59, 60,191,249,137, -215, 26,115,161,108, 81,205,158,131, 75,152,215,119,204,104,222, 59,169,217,235,162,153,226,191,177, 71, 59, 75, 98,211,204, 15, - 55,119,137,220,217, 35,114,107,135,200,141,173, 34,215, 54,137, 92, 94, 43,126,167,151,138,159,215, 66, 9, 60, 51, 95,228,244, -108, 0,238, 63, 68, 78, 76,145,143,135,199, 73,174,148, 81, 22,105,149, 87,189, 79, 96,245,225,206,126,241,219,242,115, 40, 64, -165,170, 22,237,168, 14, 53, 95,145, 39,169,169, 70,235,226,241,158,159, 27,146, 45,240,232,128, 44,129,123, 7,228, 9,188,178, -117, 74,224,243, 59,231, 37,119,138, 72,148,182,218,139,205,104,202,145, 34, 74,251, 44,201,162, 60,100, 74,157, 48,242,136,236, - 46, 81, 30,127,122,116, 82, 25, 44, 85,160,165, 74,178,190,113,139,217,221,127,109,227,163,159, 30, 28,123,218,181,108,236,223, -203,185,197, 76,168, 89, 56, 35,131,193,129,127, 56, 7, 18, 36, 72,144, 57, 95,190,124, 11,115,230,204,121, 7,129,218,253,241, -235,159, 61,123,246,219,188,198,123,127, 87,241, 29, 1,173, 51,103,206,104,130, 45, 91,229,182, 37,181, 66,190, 18, 15, 31, 62, -204,127,249,242,101, 55, 45,176,101,143, 23, 0, 84,247, 14, 28, 56, 32, 43, 86,172, 80,210,149, 43, 87,148, 49,196,214,113,243, -230, 77, 65,136,179,123, 90,124, 69,184,179, 50,155, 54,109, 42,187,106,213, 42, 37,161,124,193,160, 75, 5, 95,234,239,254,253, -251,203, 50,191, 22, 77,227,190,201, 50,214, 97,232, 93,135,238,238,238,193,225, 90, 44,207,173, 25, 71,137,144,172,173, 47, 50, - 5, 0,200,190,116,200, 33,191,243,165,140,186,215,231,224, 76,241, 59, 62, 91, 74,103,141,127, 55,107, 82, 83, 42,213, 78,139, -231,197, 51,198,184,243, 98, 81, 45,185, 49,189,178,228,118,137,180, 55,188,141,151, 59,137, 41, 27,128,215,233,203, 83,190,151, -247, 43,234, 73,145,180, 81, 47,233,161, 73, 73,214,219,253,227,132,134,239,106,126, 74,178,222,108,237, 45, 52,126, 87,175, 81, -146,245,106,101,115,169,148, 51,158,181, 68,203,225,107,202,153, 76, 81,243,184,152,106,148,202, 20,227,222,147, 19,171,229,221, -177,153,114,111,230,247,114,112, 88, 41, 89,213,183,156,204,253,165,161, 76,104, 87,250, 99, 89,215,152,150, 49, 4,109,210, 44, -144,202,116,232,250,233, 67, 15,119, 79,106,122,246,249,165,237, 47,111,141, 47,120,243,225,248,188,119,222, 94,116,127,125,123, -242, 55,103,174, 47,237,126,144,121,180,234, 93,169, 64,122,223,151,151,119,190, 59, 54, 48,183,249,233,217,109,230,130, 0, 84, -155,123,229, 51, 47,107,147,206, 60,191,101, 26,255, 67, 3,114,154,143, 77,168,101, 94,223, 35,175,121,245, 79, 25,204,139, 91, -103, 48,111, 24, 94,239, 86,158,212,209,206,218,163,237,154,212, 84,160, 83,237, 2,190,191,119,170, 34, 99, 59, 86,150, 49, 63, - 85, 84,164, 87,219, 39,183, 19, 57, 51, 79,182, 79,108, 37,195, 90,150,144, 33,205,139,201,224,102, 69,101, 80,147,194,210,234, -219,204,143, 51,235, 51,144, 87, 94,171, 0, 45,168, 15,223,110,104,103, 79,114,165, 85,245, 80,247,209, 54,113, 0,206, 70,183, - 41, 17,255,217,141, 81,121, 62,120, 79,204, 27,120,123,108,174,192, 75,195,178, 7, 30, 31,224, 22,232,115,121,159, 20,203, 24, -251,113, 65,147, 41,154,221, 1, 50, 73,148,135,129, 1,111, 36,208,231,170, 52, 42, 16,221,215,188,189,187, 64,106,165,140,143, -133,210,254, 37,209, 82, 37, 89,251,127, 78,186,178,110,190, 88, 35, 63, 94,115,191, 31,176,249, 39, 47, 0,175,170, 78, 23,218, -120,192,224,192, 63,132, 3, 8,114, 30, 11,241, 75,143, 54,105,210,228,237,194,133, 11,229,246,237,219,114,254,252,121, 25, 55, -110,156, 32, 48,189,204,155, 55, 79, 16, 76,254,109,177, 98,197,142, 50,175, 51,197,198,231, 19, 21,137,187,205,152,184,195,140, -139, 29,166,168, 72,252, 30, 53,227,220, 58, 2, 90, 0, 29, 2, 41,148, 67,176,101,171,188, 90, 64,235,193,131, 7, 14,193,150, - 61, 30, 32,192,189, 55,249,119,245,234, 85,185,116,233,146, 32,254,174,172, 91,183, 78,225,225,156, 57,115,100,217,178,101,146, -163,224, 55, 74,121,143, 30, 61, 42,136, 71,235,173,131,159,101,239,223,191, 95,246,250,245,235, 10,200, 58,117,234, 84,217, 29, - 59,118,148, 37,248, 2,109,229, 55, 91,225,111, 20, 41, 23,239,241, 87, 7,205,112,103,209,139, 69,194,253,162,191,131,128,222, -202, 69, 4,208,194,206,181,226, 35,219,150, 83,212,133, 43, 7,215, 21,128,172, 22,106,157,121, 62,163,117,110, 69,237,247,115, -229,212,194,188, 17,193, 15, 72,197,202,141,104,156, 83,100, 83,115,105, 92, 52,201, 39, 87, 87,147,102, 96, 72, 5,104,237, 29, - 45,205,203,166,189,171,238, 46,108, 90, 58,213,221, 55,238,221,133,118, 89, 84, 25, 50, 53, 44,150,244,206,171,229,141,117, 3, -173,194,233,162,181, 43,231, 22,203,171, 90,161, 84,207, 22, 12,109,233,247,236,140,187,248, 95, 92, 47, 15,230,214,145,243,243, -126, 18,207, 25,157,100,209,192,134, 50,184, 73,193,143,165, 50,197,188, 3,240, 25, 79,139, 7,249, 82,154, 70,122,174,153,115, -253,206,222, 69,247,175,140, 41,116,229,195,211, 43,230, 79, 79, 47,125,124, 57, 33,219,131,103, 75, 91, 92,219, 60,164,198, 1, -230,209,162, 83, 52, 83,130,115, 79, 47,236,244,241,252, 37,191,249,208,196,250,230,213, 61, 10,154, 23,253,152,198, 60,179, 73, - 10,243,152,218, 73,223,120,116,207, 98,222,208, 41,147,121,121,219,116,230, 5, 45,211,152,151,118, 47,102,238,240,157,219, 49, - 0,157, 65, 90,180, 45,239,187, 38, 51,229,159,221, 27,102, 11, 39,166,201,204, 30,149,133, 96,204,153,231,173,243, 42,118, 90, -215,119,200,219,213, 77,131,129, 86,120, 36, 89, 80, 9, 22, 45,148, 33,250,241, 61,147,127,124,231,191,189, 87,224,187, 57, 37, - 2,223,207, 42, 20,248,246,143,130,129, 79, 39,231, 11,124,180,240,135,192,167,103,220, 3, 33,209, 34,104,183, 43,209,202,152, - 36,138, 55,129, 22,165, 88, 15, 38, 21,148, 15, 39,166, 43, 73, 62,125,144,188,169,255, 2, 90, 0, 84, 63, 64,146,117,228,211, -253,195, 79, 42,102,143, 57,240,238,132, 2, 30, 60,199,245,142,225,225,137,241,172,193,129,191,139, 3,144, 88,165, 44, 94,188, -184,207,218,181,107,149, 69, 5,127, 41, 37,234,214,173,155, 2, 6, 8,180,102,206,156, 41,175, 95,191,150,185,115,231, 74,193, -130, 5,125,160,250, 74,169, 85,222, 32, 32, 19, 11,191,241,145, 18, 35, 37, 65, 74,180,121,243,230, 68,223,127,255, 61,119,104, - 39, 64, 74,136,196, 49, 51,166, 35,122,142,128,214,173, 91,183,228,241,227,199,242,234,213, 43,187, 96,203, 22,109,123, 64,235, -233,211,167,249, 9,178,158, 61,123,230,246,230,205, 27,187, 96,203, 94,121, 19, 38, 76,248, 12, 82, 37, 1,248, 17,127,240,111, -212,168, 81,114,236,216, 49,121,251,246,173,248,250,250, 42,160,235,231,159,127,150,161, 67,135, 42,252,140, 29, 59,182, 30,251, -233,178,199,143, 31, 87, 0,213, 7,128,168, 25, 51,102, 40,128,234,253,251,247,101, 65, 83,185,254,219,111,191,149, 29, 57,114, -100, 89, 0, 57, 3,104,105,117,206,191,238, 59,182,209,250,146, 64,139,165, 1,160,218,116,123,109, 95,121,191,123,144,124,155, - 45,193,131,156, 57, 77,209,153,202,102,142,121,255,237,210,218,114,126, 66, 5, 2,176, 77,250,234,166,157, 43, 71, 50, 83,189, -153, 29, 16,220,123, 75, 91,169,149, 63, 81,128, 35, 41,132, 74,141,146, 44, 14, 18, 59,199, 55,197, 14,195, 1,242,102,107, 31, -121,179,185,187, 50,112,236, 24,254,189,188, 90,219, 70, 94,173,106, 33, 4, 89, 60, 42,229,136,163, 41,209,130,244,106,199,154, -201,125,252,222,221, 59, 41,159,158,223, 20,243, 45, 79,241, 59, 52, 73, 30,204,171, 45, 87, 86,244,147, 29,163,127,144,214,229, -210,188, 44, 5,187,172, 50, 89, 98,206,132,157, 82,124,237,218,153, 76, 4, 99,165,179, 38, 56,247,232,212,182, 39,222,107,187, - 63,184, 52, 48,243,211,155, 67,211,191,241, 93, 82,247,209,131,117,189,174,150,200, 24,227,156, 30, 90, 4, 76, 75,199,247,184, -124, 98, 94, 87,243,202,159, 50,153,231,183, 72,101,254,163,113, 42,243,193,201,141,204,251, 38, 52, 12,216, 63,169,145,255,145, -169, 77, 3, 54, 12,250, 46, 96,197,128,202,119, 59, 86,205,114, 36, 87,138, 72,199,245, 0, 87,203,122,100, 75, 30,101,254,147, -173, 3, 69, 14,143, 21,239,141,125,132,255,245,212,211, 94, 30, 5,104, 93,221, 42,190,203, 0,220,131,108,180,248,251, 30,188, -181, 99, 4,111,247,117,185,147,153,190,107, 88, 34,245,147,199,123,166,124,252,112,125,187,124,188,186, 89, 62,156, 91, 34, 31, - 14,140, 10,244, 95, 86, 61,208,188,127, 68,224,251,155,251, 2, 39,255, 92,253, 53,222,241,155,163,114,195,224,221,251, 35,212, -164, 1, 27, 90,202,222,206, 9,148,223,128,141,173, 20, 9, 23,212,136, 10,208, 42,158, 33, 70,204, 49,213,227,206, 8,124,117, -247,237,212,186,113,231, 46,111, 22,111, 33,207, 7, 84,140, 51, 37, 89,220,184,182,140,237,195,195, 42,227, 89,131, 3,159,157, - 3, 25, 50,100, 56, 76, 80,160, 30, 11, 22, 44, 16, 76,228, 18, 55,110, 92, 37, 89, 2, 45,111,111,111, 69, 42,131,160,232,135, - 29, 21,172,100,201,146, 53, 78,158, 60, 89, 16, 52, 19, 32,185, 32,165, 69, 74,127,246,236,217,140,160,157,169, 89,179,102, 25, - 65, 35, 13,104, 48, 12,138, 75,171, 86,173, 82,225, 93,229,236,209,116, 4,180,160,234,147, 23, 47, 94, 8, 64,135, 82, 5,208, -224, 79, 8,155, 46,103,128,214,203,151, 47,243,171, 32,203,223,223,223, 13,180,108,130, 45,123,101,141, 23, 47,222,203,190,125, -251, 74,249,242,229,165, 64,129, 2,178,120,241, 98,185,113,227,134,112,222, 38,159, 33,137,146,166, 77,155, 74,242,228,201,165, - 81,163, 70, 18, 61,122,116,187,166, 28, 22,239, 40,219,187,119,239,178,223,124,243, 77,217,194,133, 11, 43, 96,138,210, 45, 2, - 44, 38, 74,183,192,211,178, 41, 82,164, 40, 11,154, 6,208,210,247,213,132, 31,104,161,199, 70,205,157,194,180, 47, 96, 89, 53, -241,159,144,134,182, 83, 7, 8,142,244,189, 63,100,174,220, 46,166,220,221,107,228, 8,164,225,251,170,126,229,169,134,252,153, -105, 81,167,124,138, 52,171, 77, 25,151, 64,230, 9, 11,109,235,103, 88, 70,208,222,115,123, 97, 11,121,176,164, 57, 39, 98, 77, - 64, 68, 26, 4, 90, 4, 89,234, 14, 67,170, 11,149, 29,134,195,171, 73,163,226, 46,119,168, 50,164,186,176, 65,145,196,119, 60, -126, 45,169, 9,180, 40,201, 90, 55,125,192,187,192,119, 47,196,236,245, 39, 12,244,107,201,219,133,149,228,225,236,106,144,100, -181,149,173, 99, 26, 9,128,216,221,176, 74,241, 0, 76, 93, 59,215,204,127,203,247,252,134,103,183,198,228,187,117,119,108,174, - 59,239, 14, 77,125,240, 83,197,140,215,114,165, 52,101,215,195, 75, 2,166, 60,169,162,158,152,218,167,193,153,157, 19, 91, 61, - 88,214,171,172,255,140,182,249,238,118,168,146,197,108,153,190,205,153,200, 12,117,225, 77, 72,141, 70,233,112,157, 17,226,213, -153, 93, 76,201,123,255,144,207, 44, 7,135, 99,119, 32,130,161,123,254, 34,221,106,100, 51,243,186,158, 50,218,202,163, 0,173, -203, 27,229,205,194,170,242,102, 94, 5,121, 61,187,140,188,254,179,184,188,158, 94,208,105,160, 5, 90, 59, 15,246,207,230, 31, -176,173, 91,224,135,211,243, 0,180,220,229,227,221,131,242,241,222, 97,249,244,226,150,220, 59,190,241, 67,205, 98,105, 31,163, - 79, 13, 47,151,193,241,170, 57,101,130,200,222, 84, 23,250,252, 89, 82,166,212,142, 37,207,103,150, 82,210,199, 11,203,196, 45, -185, 1,180,194,218,222,198,115,255,120, 14,184,194, 22,235, 49, 36, 57, 10, 80, 57,125,250,180, 2,174, 44,211,137, 19, 39, 20, -137,209,197,139, 23, 37, 75,150, 44,180,117,116,117, 84, 43,168,195, 92, 33,181,105, 29, 16, 16, 0,149,135,164, 65,202, 2, 48, -148,103,207,158, 61,121,199,143, 31,159, 23, 42,202,220,120,103, 14,208,200,210,176, 97,195,180, 89,179,102,229,174,224, 76, 97, - 1, 90, 62, 62, 62,226,231,231, 39,201,146, 37, 59,203,157,136,106,178, 4, 91,206, 2, 45, 74,178, 8,178, 0,154, 74,225,217, - 18,106,178,148,130,233, 1, 90,121,242,228, 81,108,180,166,205, 93, 41, 85, 27,117,149, 18,101, 42, 42,192,235,247,223,127, 23, -168, 24,195, 12,180,168, 62,156, 50, 99, 94,217,122, 63,118, 41, 91,184,120,233,178,139, 22, 45, 42, 59,118,236,216,178,160,105, - 0, 45,253,159,155, 26,235, 80,181,207,226,255,255, 31, 64,198,229,136,142,131, 18, 48, 85,200, 3, 18,161,252, 21,221, 98, 92, - 88,211, 45, 23, 86,227, 39, 68, 94, 95,148, 75, 91,198, 73,237,146, 25,110,192,150,197,122,119,152,174, 98, 97, 66, 91,114,106, -234, 15,202, 42,191, 98,246, 56, 62, 76, 1, 43,235,202,209,145,101, 57, 57,218,219, 33,167,139,182,154, 73,177,179, 73,110,218, -184,101,120, 45,101, 55,227,236,206, 37, 9,234,232,230, 65,243, 80,118, 24,194, 87, 86,168, 29,134,107,219,134, 48,124,167, 36, -235,197,194,234,168, 67,236, 45,142,136, 98, 39,217, 73,127,239,203, 98,198, 14, 56,243,234,186,242,126,113, 21, 24,252,127, 43, - 39, 70,150,145,189, 51, 58, 74,239,154,217,252, 0,136,106,107, 22,204, 65, 6, 24,188,123, 62, 58,178,236,234,147,249,245,206, -248, 44,172,123,234,201,238, 41,167,120,205, 25,154, 4, 78, 4, 80,249,210,198,184, 85, 48, 93,140,128,239,242, 38,121,127,111, -247, 12,243,171, 19,139,205, 47, 14,206, 48,191,240, 24,108, 46,151, 57,250, 3,149, 38,165,105,101, 50, 71, 91, 88, 62, 75,244, -225,122,222, 3,201,218,192,179,115, 90,201,167,221,253,164,117,249, 12,242,113,123, 55, 57, 57,165,174,240,186,158,231,109,229, - 33,208, 10,184,176, 86, 94,207, 41, 27, 66,162,245,206,115,184, 83, 64,139,146,206,124,169, 34, 61,122,251,103, 33, 69, 85,200, -100,246, 0,224,186,188, 94, 62,190,122, 16, 56,105, 64,155, 55, 0,180,171, 29,184,202, 8, 81,188,228,241, 34,123, 63,156, 92, - 72,110,141,205, 45,227,107,196, 82,212,135, 87,134,103,149,128,245,205, 4,106, 69, 69,162, 85, 54, 75,204,218,134,234, 48,172, - 45,111, 60,247, 79,229, 0,212, 93,249, 32, 41,241,121,254,252,185,124,250,244, 73, 1, 91,179,102,205, 82, 18,207, 41, 45,162, -221, 17,128,195,211, 56,113,226, 88,239,178,181, 85,173, 72,169, 82,165, 42,213,186,117,235, 22,120, 14,187,155,164, 56, 36, 79, - 37,160,150, 44, 54,102,204,152, 98, 93,186,116, 81, 36, 48,237,218,181, 43,144, 43, 87,174, 74,177, 98,197,226,188,100, 87,173, -239, 72,162, 85,170, 84, 41,165,204, 4, 90,182,242,241,154,173, 2, 90,130, 38,245, 28,249, 74, 0,180,229,207,156, 57,115,121, - 74,178, 8,180,108,229,227, 53,123,109, 73,137, 86,159, 62,125, 20,137, 22,129,214,242,229,203,229,135,142, 99,165,122,157, 54, -242, 77,182, 28,210,177,118, 13,241,240,240, 16,240, 60,204, 64,139, 18,173,111,106,183, 45, 91,189, 81,135,178,113, 19, 38, 44, - 91,189,122,245,178, 91,183,110, 45, 11,154, 95, 26,104, 57,196, 34,255,212,254, 30,174,114, 81,194, 1, 96, 50,178,199,119,105, - 62, 30, 27,245,141, 28,236,231, 38, 31,159, 28, 83,128,214,115, 24,179,191,189,117, 88,102,141,236, 26,152, 47,117,212, 73, 4, - 53,206,188, 12,147, 99,230,166, 37, 93, 62,200,186,134,178,174,103, 97, 37, 81,154,213,168,104,226, 15,188,231, 12, 45,235,188, - 4, 11,148,144, 85,204,153,208,103,207,196,166, 66,233,137,231,184,250,138,113,189, 30,181, 33,233, 17,104,209, 33,169,165,225, - 59,109,178, 94,173,254, 49, 52,208,154,255,157, 38,208,130,189,213,163,192,183, 79,196,127,109, 51,197,133,195,139,217,229,197, -107, 84, 89, 89,139,122,111,156,220, 77,202,101,141,243,172,220, 95,198,156, 97, 61, 34,149,118,141,117,173, 77,181,130,239,155, -148,119,243,173,150, 47,209,203, 58, 69, 83,189,133, 26,242,154,179, 4,203,102,138,182, 19,233,110,165,156, 81, 95, 28, 92,216, -211,124,120,114, 13,179,207,212,130,230,231, 83, 10,152,223,239, 30,104,174,145, 59,214,211,210, 25,163,221,101,170,154, 59,161, -247,185,117,195,253,203,103,137,182, 67,235, 61,112, 81, 31,189,110,145,148, 47,100, 87, 47,217, 59,166,134,184, 38, 49,157,219, - 61,188,178,136,123, 43,169,150, 55,209,115,222,215,162, 97, 23,104,157, 95, 41,175,255, 40, 18, 46, 27,173,122, 48,162,133, 36, -245,145,223,236,162,129,239,231, 20, 15, 6, 91, 31,142, 77, 11, 92, 52,184,185, 47,250,165, 83, 59, 96, 19,197,142,252,240,210, -208, 44,114,111, 66,126,249,214, 45,218,251,167, 51,138,203,181,145,217,229,250,168, 28,146, 38,225, 95, 64,171, 85,177,216,191, -209,173,131, 97, 12, 31,150,150, 55,158,249, 39,115, 0,182, 66,133,176, 91,237, 2,164, 45,247, 96,243,244, 73, 85, 37,242, 28, -118, 70,247, 0,156,206, 69,139, 22, 13, 67,178,238,131, 96,196, 13, 18,176,186, 80,149,213,154, 52,105, 82, 13, 72, 94,234, 76, -158, 60,185, 38, 0, 86, 37, 0,187, 10,112, 69, 80,141,121, 28,129, 44,190,205, 30,208,226,173,200,145, 35, 15,249, 43,139,109, -181,161,179, 64, 11,180,212, 50,209,159,150,211, 54, 90,150, 64,139,170,195,233,211,167, 75,213,218,205,164, 78,161, 34,210,189, - 80, 46,153,219,186,137, 28, 57,114, 68, 81,203,134, 85,117, 72, 27,173,111, 42, 86, 45,155, 48,105,138,178,160,163,128,214,195, -135, 15, 43,231, 95, 82,117,168,187, 39,252, 51, 51, 58,222,117,104,103,242,234, 80, 36,173, 41, 96,110,235, 44,226, 57,180,188, -236,235, 24, 79, 38, 85, 51, 73,217, 76,166,243,229,115,196, 63,190,114,116,115,249,136,109,251,215,247, 45,145, 93, 11, 6,202, -183,121,146,125, 32,184,113,166,254, 57,146,155,254,216, 61,176,164,156, 24,152, 83,142,253,154, 67,120,206,107,206,208, 96, 94, -122,143,199,206,194,231,240, 6,255,174,108,150,120,222,157,170,231,248,180, 97, 84, 19, 9, 56, 50, 9,190,184, 38,201,254,169, - 45, 36, 95,170, 40,135, 33,141,136,171,151,182,178,195,112, 75, 47, 27, 59, 12,155,134, 48,124,167, 36,235,197,220, 74,242,109, -214,152,154, 18, 45,223, 11, 48,124,223, 55, 92, 94,204, 41, 47, 39,199,148,147, 53,221,242,203,220, 94,223,201,244,222, 63, 8, - 13,228,245,150,205, 86, 62,172,190, 82,180,172, 85, 90,252, 95,123,203,155, 71, 87,228,244,210,126,168, 55,119, 67, 38, 16,248, - 85, 41,231, 12,109, 72,172,238,127,188,180,198,252,241,226, 26,179, 92,219,108,118,239,150,198,124,121,184,155,217,103, 98, 46, -179,159,251, 79,230, 45,115,219,154,229,254, 62, 37,221,222, 49,209, 44,135, 70,152,245, 0,173, 44, 73, 77,141,168, 42,150,109, - 29,229,199,114,105,222,185, 37, 49,165,110, 81, 58,213, 59,130,237,197,157,243, 11,238,219,242,222,174, 89,116, 74,180,252,207, - 44,149, 87, 83,114, 57, 37,193,178, 69, 24,210,219,125,115, 91,102,120,243,102,217, 15,159,252, 87,213, 11,124, 63,183,120,160, -249,252,202,192,226, 25, 99, 62, 42,152, 72, 49,182,213,125, 36,136, 29,185,125,252, 88,145, 31, 50,197,139, 25,121, 4,119, 26, -190,152, 85, 90, 46, 14,113, 21, 72,187, 84,137, 86,137,166,133, 99, 15,128,100,171,167,225,222, 65, 55,107,141,140, 95, 15, 7, - 40,253,105, 6, 64, 53, 7, 32,200,147,137,231,188,134,164,185, 59,208, 78, 53,249, 28,253, 64,209, 9,115,225,160,196,115, 94, -211, 69,211,129, 68, 75,177,197, 2,157, 8, 3, 90, 22,210,173, 48, 1, 45,184,193,240,161,141, 86,133, 10, 21,164, 68,137, 18, -220,173, 41,243, 97,244,222,171,118, 53, 89,212,170,145, 92, 61,184, 95,134, 12, 25, 34,200, 39,141, 27, 55, 22, 72,243,172,125, - 79,218, 98, 99,176,141, 22, 54, 46, 40, 96, 10,187, 24,203, 86,173, 90, 85, 57, 63,119,238, 92, 89, 24,215,127,113,137,214,215, -211,173, 29,150, 84,191,163, 82,128,166,103,175,118,143,148, 87, 59,134,200,162,198,241,164, 94, 46,147, 63, 38,180,158, 92,245, -227, 21, 12,211,210,161,245,247,249,222, 30, 90,252,155,200,189, 3, 34,119,247,218,242, 22,239,208, 57, 30,221, 57, 52, 40,156, - 40, 80, 32,233,145, 23,215,133,231,188,166,193,236, 80, 52, 75,185,198,123, 46, 79,207,139, 60, 56, 44,183, 54, 13, 19,185,184, - 66,228,220, 34,185,186,230, 23,233, 92, 61,251, 39,168, 15, 23,104, 24,131,135,162,169, 0, 45,247,110,210,184, 68, 10,101,135, - 33,109,178,184,195,240,229,242, 70, 66,187, 44,170, 12, 9,178,234, 22, 76,112,251,249,172,111,108, 1,173,144, 94,241, 97,163, - 53,173, 71, 77,120, 87,223, 36, 87,151,116,146, 77, 3, 74,203,252,190,213,229,207,161,157,164, 91,173, 92,126,180,225,210,209, -201, 28,241, 51, 82,174, 20,145,101,193,152,159,101,246,208,246, 50,188,237,183, 74, 66,221, 5,182, 11,142, 36, 69,161,104,150, - 72, 31,245,124,205, 2,137,159, 52, 42,151,216,119,235,212, 22,230, 9, 77,147,154, 31,253,158, 67, 1, 90,111,151,213, 49,143, -109,152,204,252,110,114, 22, 37,237,236,153,213, 44, 75,202, 91, 3, 45,155,229, 44,152, 54,250,145,183,107,154,203,141, 63,107, - 9,220, 55, 40,128,154,191,215,166, 86, 22,223,165,181,164, 64,154,104, 71, 28,240,192,161,195, 82,255, 83, 11,229,229,248, 76, -138,234,208, 9,159, 89,161,104,230, 73,109, 74, 3,176,255,103,229, 28,113,188,119,143,168,250,222,127,239,240, 64,243,233, 69, -129,116, 90,170,163,125,152,197, 81, 27,101,131,127,176, 39,231, 6,102,148,164,113,255, 2, 90,234,161, 74,182,254,114, 88, 26, -211,112, 88,250,127,214, 24, 14, 54,117,118, 60,157,217, 12,126,254,133,162,244,120,127,183, 11,182, 44,120, 29,204, 79,123, 42, - 65, 43, 59, 44,187, 96,203, 22, 77, 94,131, 68,235,236,154, 53,107,228,208,161, 67,194,221,135,179,103,207,150, 65,131, 6,201, -246,237,219, 5, 59, 7, 21,117, 44,236,210, 4,182,106, 50,122,244,104, 2, 45, 91,238,118, 66,180,123,212,168, 81,139,227, 57, - 69,106, 69, 63, 89, 4, 89, 4, 86, 52,130,231,110, 68,254, 39,224,154, 48, 97, 66,217,254,253,251,151,101,126, 27,253,235,115, -244, 37,157,221,248, 31,155, 77,207, 60,254,255,194, 51,158, 33, 65,214,157, 94, 38, 41,152,198, 20, 0,149, 74, 40,195,194,188, -144, 72, 96,242,244, 39,200,146,227,147, 9,180, 66, 76, 30, 26,147,142,242, 50,132,229,121, 69,144,197,231,113,254, 90, 7,251, - 66, 53,110,201, 76,177, 95,200,131,163, 10,141,197, 61, 43,200,220,254,117,224, 93, 60,219, 71,218,122,193,225,100,214,176,208, -164,202,144, 95,217,142,225,223,201,171, 53,173,132,190,178, 8,178,120,120,252, 82, 66, 94,204,255, 94, 94,204,173, 44,207,161, - 2,228, 97, 67,162, 21, 26, 16, 98,215,225,200, 31, 75,250, 30, 95,216, 91,246, 47, 29, 37,115, 7,181,144,238,181,243,248,113, - 55,162,142, 50, 58,156,196, 41,181,234,214,180,162,248,191,130, 68,235,225, 21, 57,181,164,143,236,155,220,140,210, 55, 45,137, -150,221,143,165, 20, 84,131, 7,167, 54, 48,251,172,108,101,126,187,170,145,249,205,162,239,204,126,179, 75,155,219,150,138,255, -244,187,236, 49, 30, 51,213,203, 31,243,217,145, 30, 46,186,128, 22,164, 87, 47,100,125, 35, 25, 88, 39,179,100, 76,100,202,195, - 10,241,247,215, 90,153, 20,181, 49,156,203, 98,247,178, 93,187, 10,155,229,164, 52,235,221,158, 33,242,114,108, 58,121, 57, 58, -133,188, 24,145,196, 25,169,150,221,186,231, 72,101,202, 15,218,235,126, 44,155,246,217,133,197, 93,204, 0,112, 15,195,219, 70, - 65,207,103,139, 29, 61,210,157,152,209, 34,133, 8,193, 3,112, 5,201, 86,172, 95,225,214,225,187, 47, 52,160,125,142, 65,210, -160,169,179,147,232,204,102,240, 83, 39,163,116,102,179, 4, 69, 95, 13,208, 66,221,138, 17,108, 37, 78,156,248, 49,146, 55,236, -166,188,177, 57,192, 7,170,217,215, 49, 98,196,240, 5,176,122, 5, 21,159, 15,242, 60,198, 53,130, 44, 91,118,211,214,125, 41, -105, 16,120,114,232, 21, 30,180, 84,144,149,244, 11,141, 75, 58,155,242, 31,153, 45,108,170, 67, 37,120, 52,131, 72, 59, 8, 32, -205,123, 65,249,108, 5,154,214, 28, 40,130, 2, 77,251, 0,100,249, 48, 32,180, 14,246,133,162, 73, 26, 8, 36, 77,213,225,107, -120,159, 31,207,157,123,122,220, 25,216, 91, 65,240,122, 94, 23,211, 48,213, 87,150,186,195,144,187, 12, 41,201, 82,165, 89, 4, - 87,106, 98,126,171,178,219,172, 59, 37, 87, 52,140,167,205, 22,127,117, 74,178, 84,210, 14,249, 9, 48,224, 81, 46,163,137,210, - 71, 37,241,156,215, 52,120,106, 31,108, 96, 19, 68,153,204, 49,238, 85,204, 22,251, 81,197,172,177, 30,125,235, 22,243, 81,133, - 44, 49, 30, 81,226,165,210, 36,216, 46,149, 49,234,254,178,174,209, 44, 29,171,218,164, 9,105,229,111, 13,138, 38,125,157, 35, -121,228,241,150,101,202,146,196,244, 43,174,191,202,238, 18,249, 87, 7,101,181, 43,209,178, 14, 40, 29, 30,137,150,245,251, 65, -187, 18,210,118,244,241,121, 58,250,166, 67, 48,172,243,121, 91,217, 52,191,163, 48,208, 54,104,134,129,105,206,246,207,112,190, -194,104,163,112, 50,208,222,152,172, 71,162,165,170, 16,105,179,101,157,223,214,220,161, 71,162, 21,100,244,174,216,108, 89,231, -119, 52, 31, 69, 0, 27,190,150,190, 20, 1, 85,253,239,145,248, 90, 26,247, 95, 85, 78, 55, 55, 55,197,247,139,206,238,246,175, -170,187,206, 58,235, 2,174, 78,210, 50,104, 26,193,154,195,216,101,236, 62,102,124,155, 17,203, 81,167, 36, 90,142,192, 88,120, -128,150,142, 93,135,255,229,118,143,216, 22,255,178,212, 28,251,209,250,140,101,249, 47,119, 24,163,238, 17,219,177, 12,126, 26, -252,140, 40, 14, 24,125, 41,162, 56,249, 23, 29,131,159, 6, 63, 35,150, 3, 95, 39,181,136, 9, 42, 29,134,186, 27, 31, 96, 24, -152,230,224, 17,131,159, 6, 63, 35,138, 3, 70, 95,138, 40, 78, 26, 96,195,232, 75, 70, 95,138, 88, 14,124,157,212, 28,218,104, -241, 35,177,149,156,169,170, 61, 26,142,174,107,209, 55,104,218,110,151,176,182,151,193, 79,131,159,122,251,128,241,109,218,231, -128, 94, 30, 90,230, 51,248,105,240,211, 22, 7,254,203,125, 73,229, 71, 88,231, 51,173,111,234, 63,117,223, 88,233, 68,108,115, - 27,252, 52,248, 25, 81, 28, 48,250, 82, 68,113,210,144,104, 25,125,201,232, 75, 17,203,129,175,147,154, 97,163,165,209,110,198, - 64, 17,177, 29,219,224,167,193,207,136,226,128,209,151, 34,138,147, 6, 32, 52,250,210, 63,191, 47, 69,108, 9,191, 44, 53, 3, -104, 25, 64,203, 46, 7,140,193, 39, 98, 63, 70,131,159, 6, 63, 35,138, 3, 70, 95,138, 40, 78, 26, 32,243,107,233, 75, 17,219, -226, 95,150,154,227,160,210,159,177, 44, 95, 75,227, 26,229,140,216, 78, 96,240,211,224,103, 68,113,192,232, 75, 17,197, 73, 3, -108, 24,125,233,159,223,151, 34,182,132,255, 17,106, 70,199,142,216,134, 54,248,105,240, 51,162, 56, 96,244,165,136,226,164, 1, - 96,140,190,100,244,165,136,229,192,215, 73,205,121,207,240, 17, 84, 79,227, 3,140, 32, 70, 6,145, 49,248,105,240, 51,162, 56, - 96,244,165,136,226,164, 1,180,140,190,100,244,165,136,229,128, 65,205,224,128,193, 1,131, 3, 6, 7, 12, 14, 24, 28, 48, 56, - 96,112,192,224,128, 3, 14,132, 52,142,119,119,119, 87,194,181,168,191, 6,235, 12, 14, 24, 28, 48, 56, 96,112,192,224,128,193, - 1,131, 3, 95,146, 3,255, 50, 44, 98, 0,173, 47,217,121,140,119, 25, 28, 48, 56, 96,112,192,224,128,193, 1,131, 3,142, 57, -240,149, 3, 45,199, 54, 90, 95,121,229,140,190,107,112,192,224,128,193, 1,131, 3, 6, 7, 12, 14,124,229, 28,248, 87, 99, 17, - 84,174, 28, 43,200,223,175,188,157,140,226, 27, 28, 48, 56, 96,112,192,224,128,193, 1,131, 3, 95, 33, 7,254,245, 88,196,176, -207,250, 10,123,165, 81,100,131, 3, 6, 7, 12, 14, 24, 28, 48, 56,240, 47,226,128,129, 69,254, 69,141,105, 84,197,224,128,193, - 1,131, 3, 6, 7, 12, 14, 24, 28, 48, 56, 16, 65, 28,248,219, 66,240, 68, 80,249, 13, 50, 6, 7, 12, 14, 24, 28, 48, 56, 96, -112,192,224,128,193,129,127, 44, 7, 84,160,101,253,251,217, 11,108, 56,178,139, 88, 22, 27,252, 52,248, 25, 81, 28, 48,250, 82, - 68,113,242, 47, 58, 6, 63, 13,126, 70, 20, 7,254,203,125, 41,162,120,248,119,208, 49, 60,195,107,112,253,191,220,177,141,186, - 71,236, 39,105,240,211,224,103, 68,113,192,232, 75, 17,197, 73, 3, 12,127, 45,125, 41, 98, 91,252, 63, 66,237,107,105, 92,163, -156, 17,219, 33, 13,126, 26,252,140, 40, 14, 24,125, 41,162, 56,105,128, 13,163, 47,253,243,251, 82,196,150,240,203, 82,163, 68, -171,122,208, 43,249,107,109,179,245,217, 74, 99,116,236,136,101,173,193, 79,131,159, 17,197, 1,163, 47, 69, 20, 39, 13, 0, 99, -244, 37,163, 47, 69, 44, 7,190, 94,106,169,130, 0, 22,127,191,216, 97,124,128, 17,203,106,131,159, 6, 63, 35,138, 3, 70, 95, -138, 40, 78, 26, 64,203,232, 75, 70, 95,138, 88, 14,124,157,212, 12, 27, 45,141,118, 51, 6,138,136,237,216, 6, 63, 13,126, 70, - 20, 7,140,190, 20, 81,156, 52, 0,161,209,151,254,249,125, 41, 98, 75,248, 15,162,198,206,103, 43, 57, 83, 68,123, 52, 28, 93, -215,162,111,208,180,221, 46, 97,109, 47,131,159, 6, 63,245,246, 1,227,219,180,207, 1,189, 60,180,204,103,240,211,224,167, 45, - 14,252,151,251,146,202,143,176,206,103, 90,223,212,223,113,223,144,104, 25, 18, 45,187, 28, 48, 86,121, 17,251, 73, 26,252, 52, -248, 25, 81, 28, 48,250, 82, 68,113,210,144,230,125, 45,125, 41, 98, 91,252,223, 74,173,160,201, 20,219,162,110, 95, 75,227, 26, -229,212,238,144, 41,144,133, 73,207, 97,240, 83, 15,151,244,231, 49,248,169,159, 87,122,114, 26,252,212,195, 37,253,121, 12,126, -234,231,149,158,156,255,101,126,234,225,207,215,146,231,243,236, 58,204,105, 50,181,153,152, 39,249,199, 60, 38, 83,156, 32, 78, -216,237, 48,201,147, 39,159,153, 49, 99, 70, 63,252, 62,113,113,113,121,172, 38,252,127,140,244,200, 34,237,183,226,170, 77,154, - 49, 98,196,152,148, 62,125,250,183,137, 19, 39,126,146, 36, 73, 18,239,164, 73,147,122, 39, 75,150, 76, 73,160,165, 36,188, 67, - 73,184,119, 66, 15,205,112,182,230,231,253, 88, 68,162, 36,115,113,241, 74,149, 42,149,183,179,201, 37, 69,138,195, 78,130,225, - 81,145, 34,153, 62, 49,225,185, 81, 58,248,242,121,235,174,163, 0, 58,179, 4,151, 83, 76,166, 40,122, 82,110,147, 41, 81, 52, -147,169, 67,228,200,145, 47,197,136, 28,185,147,250,140,147,252, 12, 81, 60,255,163,166, 44, 1, 71, 76,245,205, 71, 77,237,248, -203,255,127, 99,255,172, 27, 45, 90,180,197,248, 70, 54,160, 12,221,144, 92,248,203,255,188,142,243,186, 14,120,235,176,221,203, -228, 55,245,173, 88, 52,218,213, 82,249, 77,173, 72,163, 92, 65, 83, 82,156,207,169, 88, 52,234,181,210,249, 76,109,236,208,117, - 68, 51, 18,158,137, 28,148,120,174,247, 8,166,185, 10,237,174, 55, 53, 74,156, 56,231,143,217, 50, 62,110,151,215,245, 80, 61, - 23,151,140,124, 46, 60,237,174,163,176, 95,252, 59,194,120,217, 18, 99,228, 67,140,151, 15, 49,142,182,212, 81, 70,102,209, 83, -206, 95,144,111, 92, 80,226,185,214,161, 69,243, 14, 8,224,243, 83, 18,207,245, 28, 90, 52,245,208,176,206,243,111,160,249,199, -186,117,235,228,213,171, 87, 50,104,208, 32, 65,219,223, 66, 37, 9, 18, 98,104, 48,196,186,238, 97,165, 19, 22,190,127, 13,207, - 68, 60,208,202,101, 50,125,255,123,149, 98,159, 62,204, 31, 22,168, 53,248,224, 99,158,219,188,121,115,179,224,184,124,249,178, - 4, 4, 4,200,135, 15, 31,228,227,199,143, 74,226,185,154,210,164, 73,243,192,138,163,161, 58, 54, 38,189,201, 63,252,240,195, - 27,210, 59,113,226,132,188,123,247, 78,252,253,253, 21,186,239,223,191, 87,254, 91,166, 20, 41, 82,120, 59,162,153, 32, 65,130, - 19, 0,108,222, 76, 4,109, 42,112, 35,120,179, 4,112,150, 32, 14,121,244,130,183, 42,120,247, 94, 29,137,249,236,127,212, 0, - 90, 4, 88,172,179,179, 71,218,180,105,239,105,181,145,197,253, 20, 4, 88,234, 59,112, 30, 24, 51,102,204,244,150,247,113,110, - 45,233,210, 28,124, 82,167, 78,253, 3,202,191, 19,105, 7,207,117,124, 53, 33,104,198,143, 31,255, 4,249,159, 50,101,202, 39, -106, 2,173, 39,150, 9,116,159,168,137,109,142,246,180,219, 70,142, 64,150,167,201, 20, 53,166,201, 84, 33,106,148, 40,238,160, -243,250,236,217,179, 10, 63,208,239, 30,132, 23,104, 17, 84,249, 29, 48,253,242,108, 79,204,163,190,183, 70,191,226, 47,255, 91, -129, 45, 77,126,234,224,159,158, 9,162, 5,142,211,222,222,222, 15, 94,190,124,249,232,207, 63,255,188, 18, 43, 86,172, 3,252, -229,127, 94,231,125, 16,234,104,231,125,118,203, 89, 34,191,169,120,235,186,169,252, 78,175,111,230, 87,161, 72,212, 83,165,242, -152,170, 87, 42, 17,253,193,180,126, 57,253,246,205, 46,237, 87,190, 80,228,115, 78,210,140, 20, 53,106,212,146, 88, 92,181,194, -196,208, 60, 40, 53,195,175,146,208, 39,148,132, 54,175,239,232, 59,210, 11,178,210,197,138, 85,178,126,230,244,126,119,134, 14, -150,179,221,186, 72, 43,215,116,175, 9,182,156,248,142,194,208, 68,186, 0,140,179,116, 29,246, 37,130, 44,142,189,102,179, 89, - 48,214, 61,212, 73, 92, 79,255, 28,135, 79, 70, 73,160,201,164,117,104,209, 12, 30,246, 64,136, 96, 75,207,225,136,102,172,168, -145, 35,247,140, 19, 35,198,142,152, 81,163, 62, 97,226, 57,174,245, 2,225, 88, 14,136,107,149, 83, 79,185,244,124,155, 97,161, - 99,249,140,163,114,198,195, 55,115,115,210,164, 73,226,231,231,167, 36,158,243, 26, 8,196,115,162,238, 97,165, 19,222,186,253, - 83,158,255,188, 54, 90,144,100, 21,254, 57,191,219,123,243,138, 73,159, 2,234,102,176,236,244,161, 26,151, 32,171,230,119,223, - 5,127, 36, 5,179,102,149, 1,205,155,203,232, 78, 29,101, 98,143,174, 74,154,212,253,103,153,209,167,183, 60,126,252, 88,116, - 0,173,177,117,235,214,245, 81, 9,182,106,213, 74,182,108,217, 34, 71,143, 30,149,243,231,207,203,213,171, 87,229,214,173, 91, -242,224,193, 3,121,242,228,137, 96,194, 16, 45,160, 69,128, 69, 96,166, 30,129,129,129, 10, 0,228,224, 67, 0,199,123,236,140, -111,223,190, 85, 18, 87, 2,148,148, 89,181,182,189,142,189,151,249, 89,158,251,247,239,203,189,123,247,228,238,221,187,114,231, -206, 29,185,125,251,182, 82,214,155, 55,111,146,135,123, 29, 77, 16, 38, 11,160, 53,124,216, 80, 25, 58,168,143,140, 28,214, 71, -249, 29,208,191,159,244,235, 23, 58, 77,157, 58, 85, 62,125,250, 68,158,134, 25,104, 85,175, 94, 93,106,212,168,113, 28,128,166, - 79,148, 40, 81,254,180, 35,233,210, 28,124, 0,128, 60,125,125,125,189,152,112,190, 71,199,151, 18,130, 38,219,232,225,195,135, -242,252,249,115,121,241,226,133,146,216,182, 76,228, 47,211,235,215,175,149,196,123, 0, 9,130,247,216, 5,237,182,128, 22, 68, - 57,153, 48,208,142, 42, 82,164,200,243, 81,163, 70,189,171, 85,171,150,212,169, 83, 71, 78,158, 60, 41, 99,199,142,253, 16, 41, - 82, 36, 63,244,253,196,124,214,193,132, 59, 0,247,174, 33, 93, 69,234,109, 93, 79, 74,176, 8,174,142,108,108,164,116, 55,254, -242, 63,175, 59,160,169,131, 93,154, 89, 66,181, 17, 22, 24,235,193,171,135,168,219,165, 31,127,252,241, 12, 22, 42,143, 80,164, - 71,252,229,127, 94,231,253,184,113,227,174,181, 67,221,110,187,151, 41, 96,218,181,107,241,143,126,135, 87,181,246,131,100,235, - 65,253,111,227,191, 58,180,184,166,223,193, 69, 85,252,218,213, 73,234, 7,137, 86, 55, 39,104, 82,122, 85,178, 81,163, 70, 45, - 80,190,118, 23, 47, 94,108,199, 95,244,237,118,248, 70,219,225,219, 84, 18,250, 86, 59,130, 45, 71,223,145, 30,160, 21,215,100, -202,153, 49, 99, 26,191, 73, 93, 59,136,249,247,209,226,219,188,129, 28,202,145, 73,218,102, 74,126,232, 75,183,145,102,171,106, -103,112,248,109, 82,146,197,126,200, 49, 41,103,206,156, 47,241,157, 61, 66,210, 90,153,107,126,239, 40,214, 63, 25,104, 21,141, - 17, 53,234,253,149,139,166,127,188,123,243,140, 4,188,127, 44,103,207, 28,149,139,103, 15,201,210,217,147, 63,240, 30,202, 95, -212,137,254,169,221, 10,142,115,232,225,167,179,239,176, 73, 51,101,201,142,117, 82,149,238,242, 36,117,169, 78, 79, 18,185,126, -243,218, 37, 85,134,143,148,106,113,252,164,148, 11, 47,249, 67, 15,208, 74, 89,172, 99,157,148, 37, 59, 63, 73, 89,162,211,147, - 4,153,191,121,157,220, 57, 58,206,214,229,191,151, 31, 19,141,107,195,116, 46, 47,222, 45,159,248, 49,160,121, 94,121, 81, 54, -150, 93,160, 69,117, 33, 86,196, 1,150, 18,152, 46,245,234,137,215,194,217,114,127,203,106,121,177,111,147,188,216,139,180,199, - 93,118, 79,159, 44,143, 30, 61,210, 4, 90,233,210,165, 83, 36, 89,234,241,219,111,191,201,206,157, 59,229,212,169, 83,161, 64, - 22, 39, 92, 2, 35, 12,190, 14, 65, 17, 39,113,210,219,177, 99,135,236,217,179, 71,246,237,219, 39,135, 14, 29,146, 99,199,142, - 41,147,236,153, 51,103,228,194,133, 11,114,229,202, 21,185,126,253,186, 96, 64,119, 6,104, 81, 82,245,234,205,155, 55,202, 96, -198,115,164,189, 22,233,213,211,167, 79,157, 2, 90, 4, 87,190,247, 22,138,255,245,159,228,245,157,249,242,248,193,117, 89,179, -110,131,180,104,215, 77, 42,124,223, 64, 6, 15, 31,163, 0, 56, 72, 38, 20,176,232, 36,208, 98,167, 30, 85,189,122,181, 64,130, -172, 41, 83,166,188, 0,240,244, 66,253,207,186,185,101, 9,230,123,144, 90, 81,149,108,105, 14, 20, 0, 61,135, 9,178, 54,111, -222, 76,160,101,169,202,180,247, 17,133, 2, 90, 4, 89,238,238,238, 2, 26, 10,184,222,182,109,155,108,223,190, 93,118,237,218, - 37, 93,103,156,149, 86, 19,207, 75,131,190, 75,229,224,193,131, 10,104,135, 36, 79, 19,104,149, 51,153,226, 70, 51,153,154, 71, -143, 22,237,116,134, 12, 25, 94,127,251,237,183, 31,213, 74, 66,122, 18, 8,245,217,115, 72,178,110, 71,143, 28,185, 15,196, 25, - 46,142, 36, 90,232,155,165,144, 55,196,202, 27,234,114, 95, 53,129,158,111,255,182, 73,252,189, 47, 12, 11,180,236,195,175,174, -143,244,165, 26,241,111,152,196, 27, 64,138,177, 9,239,237,139,212,160,105,211,166,167, 9,180,248,203,255, 72, 61, 32,185,117, -199,175, 45, 41, 17,139,107,179,221, 1,162,190,239,209, 42,143,223,245,125,131,252,102,143,172,226,247,109,177,104,126,123,151, - 52,241, 59,183,177,133, 95,243,234, 73,124,203,228, 51,181,208, 51,152, 7,229, 33,200, 42, 86,175, 94,189,102, 4, 87, 76, 75, -151, 46,109,135, 54,111,119,238,220,185,118, 55,110,220,104,135,239,170, 29, 22, 50,237,176,176, 10, 55,208, 34,200, 74,147, 46, -169,239,153, 51, 94, 88, 24,221,148, 9,245,170,137, 79,153, 66,114,169, 88, 94,105,153, 54,249,227,191,161,141,194, 59,201, 56, -250, 54,179, 65, 51,240,130,139, 74,128, 87,225, 56,196,241, 50, 81,162, 68, 90,146,173, 16, 52, 33, 5,229,248,170,168,245,130, -206, 89,230,223, 96,222, 49,150,137,231, 65,149,112,164, 78,180,164,121, 71,165,135, 95,158,243,176,117, 77,139, 55,182,234, 94, -164,104,145,124,111, 30,220,189, 40, 23,206,239,146, 55, 47,183,203,135,247,123,165, 83,199,122,210,187, 87, 27,121,235,123, 75, - 30,222,185, 32,185,115,102,123, 3,226,182,192,150,230, 88,167, 85, 40, 27,247,191, 24, 77, 0, 35,159, 22,191, 31,147, 14, 51, - 46, 43,169,253,148,115,146, 62,247, 55, 50,100,200, 16,101, 72,202,157, 59, 55,205, 69,146,216,169, 67,112, 57, 83, 20,239,232, - 83,121,192, 1,169, 49,236,140,146,170, 13, 62, 33, 46, 89,203,254, 69,199,236, 45,141,106,100,254,116,106,177,169,198,135, 35, -166,114, 76,230,195,166, 34,114, 84, 49, 75, 8, 62, 48,150,151,115,244, 63, 12,124,252,210,143,168,206, 74, 45, 37, 91,127,149, -129, 19,149, 85,229,244,138, 97, 77,249, 77,166,100, 21, 18,198,185,253,114,222,200, 15,230,174, 21,228, 21, 64,214,249, 34,209, -237, 62, 79,155, 44,203, 9,133,231,227,186,116,150,115,203, 23,136,247,206, 53,193,183, 8,184,246,204,152,100, 15,104,133, 96, - 30,109,178, 8,126, 58,116,232, 32,131, 7, 15,150,249,243,231,203,225,195,135, 21,149, 36,193, 5,165, 70,148,100,169, 32,139, -234, 68,170,220, 28,181, 0, 85,133, 44, 12, 65,214,222,189,123,229,151, 95,126,145,190,125,251,138,151,151, 87, 40,144, 69, 41, - 20, 7, 35, 27, 18, 45, 71,175,216, 75, 73, 11,203,135, 76,123,173, 50,170,170, 69, 91,170,195,255,103,181,144,104,141, 24,218, - 91,222, 93,109,247,151,164,237, 74, 91,185,131, 85, 89,199,238,191, 6,243, 51, 99,246,194,114,233,210, 37,153, 49, 99,134, 34, -145,179, 2, 90,154,157, 17,249,243, 20, 45, 90,244,236,128, 1, 3,206,130,199, 94, 3, 7, 14,244,194,106,231,108,141, 26,213, -237, 1, 45, 77,154,104,131,117, 7, 14, 28,240, 90,181,106, 21,237,204,214,105, 62, 96,149,129, 96,152,109, 90,191,126,125, 33, - 0,180, 78, 45,198,159,151,243,119,124,165, 80,245, 94,148,192, 41, 18, 68, 27, 18,173, 96,170,216,193, 81, 48, 82, 66,183,131, - 49,147,100,122, 59,126,252,248,143,207,158, 61,147,106,213,170,113,160, 17, 72, 73,223,129, 7, 47,163, 68,142, 60,159,249,108, - 73,191,108,149,223,205,205,237, 22,193,250,138, 21, 43,148, 68, 96,110,125,124,242, 89, 41, 47,189, 74, 43,146, 44, 30,252, 61, -184, 32,158,191,149, 68,203, 89,246, 68, 84,254, 31, 65,136,192,171,117,120, 8,150,206,111, 90,115,108,203, 32,191,219, 71,198, -251,117,111,153,211,111,120,143, 98,126, 87,118,246,240, 91, 49,169, 58,165, 91,215,203,230, 55,121, 86, 41, 25,227, 49,206,245, -188, 39, 50, 0,115, 75, 21,100,241, 23,188,109,135,197, 80, 59,124,243,237,240, 61, 6,131, 44,180, 97, 59,180,185, 45,137, 86, -112,117, 28, 73,180, 8,178, 82,165,141,231, 59,223,205, 18, 81,186, 0, 0,255,244, 73, 68, 65, 84,189,150,252,185,176,155,120, -238,219, 41, 11, 22,204,148, 49,141,234, 72,171, 92,110,239,104,179, 21, 30,190,252,195,158,205, 6,205,192,115,142,143, 28,151, - 56, 86,120,120,120,200,218,181,107, 37, 97,194,132, 90, 64,203,186, 42, 33, 22, 23, 65, 55,105, 75, 23, 53, 40,241,156,135, 94, - 41,151, 45,122, 17,193,190, 24,177,162, 71,191,243,232,254,101,217,177,253, 79,241,121,122, 22,239,249, 36,159, 62, 62,144, 6, - 13,170, 72,197,111, 75, 72,191,190, 63,193,252,228,190,220,186,122, 94,130, 36, 91,142,212,136, 17, 81,166, 47, 74,195, 90,162, -149, 60, 69,186,143, 61,122,244, 80,132, 20, 27, 54,108,224,252, 52, 77, 79,129,172, 37, 90,201, 82,166,251,216,171, 87, 47,185, -125,237,168, 28,222,214, 95, 22, 12, 54,157,126,178,195,180, 64, 77,207,119,155,198,249, 29, 54,213,178, 4, 91, 42, 22, 81, 1, -151, 53, 54,209, 83,142,191, 57,143,186, 56, 14, 45, 1,182,168,156, 2,144,244, 86, 46, 43,116,183, 5, 98, 68,191,121,127, 98, - 31,179,121, 80, 35,121, 83, 46,150, 92, 44, 26, 35,176, 83,178,200, 31,173,118, 30, 6,215,157,134,239,215,174, 93,147, 18,185, -114, 73,239,198,141,101, 98,215,174,178,105,236, 24,185,177,126,185,188,220,183, 49,248, 99,122,233, 4,208, 34, 40, 34,192,160, - 52,131,146,140, 35, 71,142, 40,210, 38,107,144, 69,169, 19, 7, 17,170, 1,245, 0, 45,230,163, 36,139,234,182, 38, 77,154, 72, -231,206,157, 21,189,181,165, 36,139, 32,139, 64,142, 64,203,134, 58,210, 81,155, 43,234, 67,172,190,237, 73,174,180,251,139, 5, -208,162, 68,235,201,149, 63,228,205,197, 86,242,248,210,116,185,114,209, 75, 90,117,232, 37,115,246, 7, 72,219,185,207, 37,117, -230, 60,138,132,111,250,244,233, 10, 24,115, 2,104, 69,198, 68,213,188,124,249,242, 71,231,204,153,227,181,120,241, 98,175, 63, -254,248,195,107,220,184,113, 94, 88,169,120, 65, 66,246,130,146, 46, 39,140,228,131,235,133, 54,152, 5,254, 1,187,122, 17,104, -205,210,174,112,200, 28, 4, 90, 84, 19,218, 59, 8,180, 46,223,127,171, 0, 45,170, 24,169,162,197,123,236, 78, 24, 80, 3,190, - 28, 50,195, 93, 98,187,213,150,185, 11,150,202,234,213,171, 63, 66, 53,250, 2,118, 89,135,163,155, 76, 63,212,131,157,134, 35, - 59, 46, 91,229,167, 61, 31,219,152,160,159, 18, 2,170,178, 79,159, 62, 45, 91,183,110,149, 69,139, 22, 41, 18,198,213, 75, 70, -201, 25,143,198,114, 96,113, 74,121,120,118,176,220,221,147, 87,134,118,136,238,107,195, 32,222, 89, 22,253, 99,242, 67,162,117, -244,206,169,185,126,247, 78,254,233, 87,191,170,139,223,254, 53, 61, 20,233,214, 72, 0,174,159,155,185,250, 29, 95,211,210,239, -228,218,166,126, 21, 10, 71, 62,169,163,208,145, 49,241, 55,163,186,144,146, 44, 38, 72, 52,219, 97,177,165, 72,179, 84, 73, 22, - 65, 22,190,177, 48, 3, 45, 21,100, 45,216, 92, 91, 22,109,175, 40, 99,230,229,148, 38,109, 74,201,184,241, 99, 4,106,196,119, -180,217,178, 50,134,215, 81,244,127, 86, 22, 72,246,219, 99,129,200,141, 71, 23, 85,144, 69,179,133,149, 43, 87,210, 62,235, 9, - 37, 89,224,245, 35,168,148,181, 84,135,122,128,150,173,202, 71, 4,208,138, 22, 39,150,169, 71,134, 20,145,246,187,166, 74,248, - 32, 67,156, 40,251,227, 68,141,220, 3, 47,131, 96,218,241, 1,105,115,167,205,235,230,126,248, 16,112, 81, 62, 4, 92,135,134, -225,162,244,232,222, 84,154, 55,171, 33,111,223,156, 70,186,132, 5,250, 85, 41, 82,172,168, 84,175, 89, 87,186,116,232,248, 49, -200,102, 75,139,244,215,118,159,182, 85,119,126,253,245, 87,153, 55,111,158, 44, 95,190, 92, 17, 90,184, 37, 77,250,113,146,201, -244,244, 79,147,169,142,206, 10, 41,116,176, 16, 87,250,208,198,141, 27,101,206,228,246, 50,181, 95,236,215,183,221, 77,199,110, -109, 52, 41, 38, 62,252,189,191,213,116,152, 96,139,146, 45,149,118, 88,177,136,206,178,125,137,108,218, 18, 45,235, 74,106,149, -202, 45, 90,140, 91, 39,251,182, 12,252, 48,177,171,188, 45, 31, 7,162,244, 24, 31,155, 39,140, 36, 88,226,117,179,247, 44,192, -200, 99,130,157,223,126,252, 81, 78, 67,242,116,126,241, 98,185,177,106,165, 60,245,112, 87,212,133, 58, 85,135, 33,200,115, 50, - 35,120,160, 17, 60,140,148, 21,169, 1, 7, 11, 2, 32,218,229, 80,234, 97, 9,178,216,208, 90, 64,139, 52, 41, 62,167,186,176, -117,235,214,202,132,200,201, 17,106,207, 96,117,161, 10,178,168,146,162,189,150,179, 64,139, 32,129,171, 6, 84,102,111, 80,133, -244, 73,178,212,218, 91, 0,173,254,253,250,202,133,179,176, 41, 56,119, 72,206,158, 58, 36,167, 78,122, 73,227,150,157,100,246, -190, 0,105, 51,231,185, 36, 79,155, 85,169,203,180,105,211, 20, 94, 0, 60, 89,218,104,217,108, 46, 12,194,233, 51,103,206,188, -112,214,172,153, 94,224,173, 23, 84,115, 94,232, 35, 94,235,215,175,247, 90,178,100,137,114, 14,222, 18, 36, 81,226,161,215,237, - 67,132, 1, 45, 2,108,242,144,171,110,170, 11,169, 46,222,189,123,183,120,122,122, 42, 0,185,110,207, 37, 82,172,118, 95, 41, - 89,187,151,162, 86,100,123,161,141, 28, 1,173,215, 7, 46,190,148, 74,173,127,255, 16, 41,121, 17, 95,168, 6,127, 73, 99, 50, -165,214,179, 19,209,202, 70, 43,184,142, 44, 35,129, 63,120, 38,200, 35, 0, 5, 50,124,248,112,101,165, 72, 9, 27,141,142,185, -240, 88, 60,103,144,204, 30, 91, 89, 54,204,169, 38, 59, 87,181,151,252,217, 99, 63,211,250,254, 62,243,253, 90,160,191, 30, 19, -236, 57, 24,156,123,224,156,187, 4,129, 61, 76,173,248,159,215,121, 31,137,249, 52,143,202,197, 99,221,240,190,188,198,239,209, -249, 37,126,141,171,167,246,187,115,124,154, 34,221,234,213, 58,143,223,233, 45, 61,252,230,140,168,236, 87,183, 66,252,215, 26, - 42, 68,245, 61,145,192,215,166,180,199,130,196,185, 29,164,162, 10,200, 2, 31,219, 65,157,168,168, 11, 85,144, 69, 59,173,176, - 72,180, 8,178, 82,167,143,247,198, 18,100,117, 31,146, 79,186,247,251, 65,210,101, 76,233,203,251,170, 36, 76,179,242,255,224, - 12,148,194,179, 15,242,224, 47,199, 77, 74, 94, 49,254, 81, 37,154, 45,172, 69,183,165, 58,180,163, 78,212,187, 19,241, 14,202, -162,168, 34,145,120,174, 30,174,153,210,198,191,181,123,205,160, 79,190, 15,118, 72,160,247,177,231,175,247,111,144,205,195,186, -125,202,144, 56, 30, 13,185, 93, 29,213, 33,118,140, 24, 91,158, 63,189, 42, 31,252,247,129, 3,129, 80, 23,214,151,122,245, 42, - 75,133,242,197,197,236, 79,147,144, 91,242,204,231,182,116,239,221, 91, 18, 38, 79, 43, 3,126, 25, 44, 52,144, 15, 43, 95,254, -193,207, 77, 35, 48,130,234, 93, 40,205,202,151, 52,169, 76,136, 26, 85, 30, 69,143, 46,119,163, 69,147, 25, 38,147,143,206,178, - 43,116,168, 61,161, 52, 11,253,235, 78,207, 38,166,113, 15,182,153, 22, 19, 92,173, 26, 13,203, 98, 28,252,229,127, 74,183,168, - 70, 84,105, 19,131, 80,154,101,249,171,243,189,255,252,108,214, 21,179,214,147,218,170, 65,236,228, 89,127, 90,219,236,187,192, - 15,152, 32,222, 85, 76, 40,151,138,196,240,175, 19,207, 49,200, 34, 29, 76,202,143, 8, 96,126,239,212, 73, 30, 98,178,241, 6, - 99,159, 97, 18,124,182,117,139,248,108,223, 34,207,119,110, 86, 18,207,119, 77,177,107,163, 21,162, 72, 4, 69,148, 40,177,147, -216, 3, 89, 84,151, 81, 66,165, 30,122,128, 22,109,153, 40, 37,251,230,155,111, 20,219, 44, 74,178, 8,180, 56,145,171, 32,139, -147, 40, 39, 78,174, 0, 96,207,243,196,137,214,222, 75, 0, 72, 73, 7,158,121,133,180,151,191,180, 73, 11, 58,215, 38,101, 1, -180,250,244,233,163,148,113,255,254,253, 50,123,246,108,101, 53, 82,172,116, 69,153,180,229,169,180, 6,208, 74,150,198, 77, 1, - 33,148,206, 81,101,169, 5,180,168, 42, 44, 87,174,220, 97,108, 40,240,130, 52,200, 11,160,192,235,230,205, 27, 94,231,206,157, -245, 2, 29, 47,216,165,121, 1, 48, 43, 82, 45,240,178,161,118, 97, 67,231, 8,175, 68, 75, 5, 90, 84,205,169, 32, 75,181,167, -195,228, 43,251,246, 31,144,117,235, 55,202,198, 77,238, 10, 72,230, 36,162, 33,209,122, 79,160, 53,106, 21,212,185,169,202,113, - 71,225, 39, 72,180, 52, 19,242,249, 59, 2, 90, 28,120,104, 84, 10, 21, 41,237,219, 20,208,231,227,227,163,168,183,185,226, 35, - 0, 38, 80,236,223,191,191,252,252,243,207,202,246,106, 24,155, 59, 84,109,135,133,223, 78, 60,211,182, 98,197,138,247, 33,125, - 51,179,156, 24, 52, 63,116,234,212,137,125,251, 44,127,249,159,215,121,159,249,112,189,167, 22,237,186, 21, 93, 94, 62,187,233, -225,247,228,202, 6,191, 78,205,114,251, 61, 56,187, 64,145,110,117,255, 49,143,223,173, 67,163,253,126,172,147,214,207, 37,169, -137,253, 72, 85, 41, 57, 36, 73,160, 69,149, 33,109,178,168, 46, 84,237,178, 8,180,152, 40,201, 34,200,194,119,239, 52,208, 82, - 65,214, 66, 11, 73, 86,183,193,121, 1,178,234, 74,102,183, 84, 47, 44, 65,214,215, 46,209,226,174, 93,142,115,148,186,114,145, -202,241,129,146, 44, 48, 63, 4,200,194,132,217, 22,106,240,135, 88,124,253,172,213,214, 14,238, 71,180,250, 47, 90,186, 84,177, -110,188,188,189, 41, 80,110,193, 14,232, 96, 6,145,185,137,246, 74,219,108, 34,179,123,201,227, 21,147, 2,211, 37,136,117, 3, -229,177, 43,217,194,206, 66,111, 26,190,127,240,223, 47, 39,142,239, 14, 6, 89,121,243,102,151, 55,111,110,201,211,103,183,229, -238,195,187,178,121,199, 30,137, 22, 47,133, 52,111,211, 69,184, 27, 49, 28, 60,248, 39, 62,154, 36, 79,158, 60,138, 29, 42,237, -169,224,190,198,127, 70,164, 72, 79,102, 69,138,228,205, 4,105,214, 19,157, 18,173, 16,116, 80, 81,110,152,137, 78, 32, 69, 64, -101, 75,243, 96, 13,180,200, 28,103, 5, 62,255, 68,134,218, 45,147, 51,149,139,159, 34,251,247,195,126,159,250,250,254,249,179, -114,183,146,139,156, 42, 18,227, 67,149,216,218, 32,203, 18,104,225, 92, 26, 86,168,160, 36,170, 16, 21,176,133,180, 97,244,104, -229, 26,127,119, 77,214, 7,180, 56, 88,208,176,156,160,133,147, 41, 85, 68,148,100,209, 80,154,210, 27,107,144,165, 87,162, 69, -187, 46,236,180, 82,118,239,169,234,194,137, 19, 39, 42, 82, 33, 74,203, 40,145, 32,192,225,238, 70, 72,120,164,113,227,198,239, -156,104,244,189, 44, 31,213, 73,164, 77,149, 18,129, 34, 7,187,176, 2, 45, 74,113,160,214, 83,212,100,116,105, 49,103,206, 92, -105,208,101,130,180,154,237, 3,137,150,155, 50,193,115,162,167, 20, 72, 11,104, 97, 64,157, 68,245, 32,192, 27, 64,213, 53, 5, -104,129, 31, 94,144, 20,120, 97, 96,246,162,202, 15, 0,244, 16, 0, 89, 19,148,215, 25,255, 69, 10,139,176,155, 41,110,236,216, -177,253,217, 15,152,120,238,234,234, 26,223, 9,254,153, 8,180,168,126,165,186,152, 32,210, 18,100, 17,188, 16, 4,179,109,142, - 31, 63,174,216,214,113,211, 2, 36, 90,143,236,189, 3,128,201,123,249,190,199, 10,208, 74, 95,188,133, 98,100,207,163, 43,212, -219,180,255, 83, 15,236,116, 19,168, 89,130,255, 19,140, 57, 2, 90, 92,217, 1,180, 74,201,146, 37,185,139, 75,217, 0,177, 6, -118, 47,117,155,118,144, 2,197, 43,192,254,171,181, 2,182, 40,110,135,154, 70,177, 53,251, 59,129, 22,140,253,247, 97, 7,236, - 39,128,117,159,188,121,243,222,249,233,167,159,188,249, 13,241,224, 47,255,243, 58,239,163, 31,124,130,132,107,187, 29,158, 82, - 2, 70,223, 88,251,190, 41,154,208,247,218,233,117,126, 87, 78, 44,247,171, 82, 42,142,223,133,131, 51,253,206,237,155,226, 87, -231,219, 36,126,103,119,141,240,171, 94, 54,129, 95,229,202,149,159, 69,143, 30,253, 60,242, 87,215,234, 7, 4, 90, 4, 89, 51, -103,206,108,135,239, 83, 1, 87,214,137, 32,139, 82, 47,103, 36, 90,182, 65, 86, 30, 5,100,185,102, 77, 29, 10,100,125,237, 64, - 11,160,170, 61,210, 35, 76,180, 47, 41,153,231,166, 18,244,193, 80,210,238,134, 13, 27,222, 13,218,240,115, 93,171,109,190, 20, -208,138, 28,217,212,113,197,198,238,175, 63, 61,154,122, 95, 60,227,139,146, 8,180, 26,167, 20,166,103, 51,102,220, 24,219,114, -240,139,200,166,200,246, 92,145,152, 8,180, 46,156, 63,166, 72,178,110, 92,219, 10, 85,225, 89,121,243, 10,155, 0,158, 93,145, - 68, 73, 93, 36, 86,252,100, 18, 59, 97, 74, 41, 89,161,134, 28,240,186, 38, 71, 79, 93,251, 55, 2, 45, 54,217, 20, 43, 63, 90, -183,113, 77,143, 31, 45,235,230,182,166,115,203, 25,137, 86, 16,208,218,107,249, 27,142,254,246,117, 62, 90, 48,107,230, 97, 21, - 74, 20,126, 88,177, 74,109,115,128,249, 99,224,197,187,190, 50,164,125,143, 55,101, 98, 69, 13,204, 18, 45,214, 20, 61,181, 82, - 37, 90,234, 4,171,245,107,103,215, 97,136, 87, 17,104,113,194,181, 6, 89, 4, 95,156, 24,232,206,192,250,208,146,104, 97, 55, - 88, 0, 38, 19,233,217,179,167, 50, 73,171,187, 11, 9,102, 48,209, 40, 59,216, 8, 92,104,179,197,247, 48, 97, 2,118, 10,104, - 81, 42, 64,112,133,202,188, 10, 2, 87,175, 8,224,194, 10,180, 40, 21, 25, 54,108,152, 82,103, 30, 4,112,177, 98,199,149,116, -174,185,228,219, 42, 53, 21,157, 57,203,203,247,106, 1, 45,236,150,219,179,105,211, 38, 69, 61,200, 68,192, 69,176, 5, 94,122, - 97,139,255, 9, 60, 63, 20,124,119, 90, 93,200,134, 3,136, 43,147, 43, 87, 46,138,223, 67,172,112, 75,148, 40,177, 7,237,162, -123,183, 13,129, 22,165,115,148, 86, 81,242,216,105,218, 57,161, 93, 86,173,110,243, 21,169, 35, 55, 49, 80,178, 69, 16, 67,176, - 69, 21,157, 35,160, 5, 27,173, 27,148,100,165, 43,214, 76, 76, 73,242, 9,252,188, 41,210, 76,238, 26,100,226,185,245,127,170, -149,113,239,163, 94,160,149, 61,123,118, 69,138, 85,167, 89, 23,233,252,235, 52, 41, 84,184,172,228,117, 73, 38,195,250,245,161, - 77,152,196,137, 19, 71, 49,192,255, 59,129, 22,218,165, 25,118,134,113,176, 27,140,148, 20,169, 23, 54, 19, 60, 96, 99,241,151, -255,131,174,255, 10,144,197,124,141,109,125,251, 0,160,171,123,247,238,237, 3,181,243,243,179, 39, 15,251, 76, 29,213,254,213, -196, 97,173, 94,239,222,186,252,133,122,190,108,238,136,151, 35,251,215,127,189,121,237,172, 23,248,214,159, 65, 13,236, 3,160, -119, 86,107, 44,129, 29,136, 2,180, 32,189,181, 9,180, 0, 12,218, 49, 81,234,165, 23,104,193, 89, 80,214,212, 25,226,189, 89, -184,165, 78,176, 77, 86,183,193,142, 65,214,215, 14,180, 84, 62,211,222,145, 64,106,217,178,101, 2,181,176, 53,208,138,133,126, -251,148,146, 47,124, 19, 47,240,253, 94, 1, 79, 59, 56,106,163, 47,161, 58, 76,154,194,180,237,206,203, 37,114, 65,220,228,230, -211,104, 39, 3,247,199,191, 65,160,245,178, 78,254, 27,155, 11,140, 57,185,165,194, 60,241, 28,177, 89, 18, 69,141,191,205, 94, - 89,169, 58, 60,184,207, 67,154, 54,173, 41,243,231,141, 22,255,119, 55,224,214,224,166,120, 63,185, 45, 81, 99, 38,144,168,113, -146, 74,244,248, 41,101,250,188,181,178,255,228, 45,217,178,245,192,191, 85,117, 24, 7,223,212, 13, 27,126,180, 40, 17, 84,157, -143,107,125,150,188, 31,138,206,242, 57, 61,100, 90,255,216, 47,239,108, 54, 29,213,178,209,210,243,130,127,120, 30,107, 91, 70, -231,108, 27,221, 50,167,169,218,174, 81,237,215,119,207,123,201,214, 63,127,151,238,191, 77, 10,252,115,211,165,215,169,178,151, -125, 26, 47,153, 91, 41,189,149,167,234,134,170,195,170, 21,234, 74,255,159,199,134, 74, 91, 55,122, 10, 19,239,253,216,168,171, -174, 93,135,244,248, 78,160, 69, 73, 22, 1, 16, 37, 69,142, 64,150, 30,137, 22,193, 27, 39,113, 91,134,239,148,110,208,230,134, -210, 44, 26, 54,211, 62,140,246, 13, 54, 92, 70, 56, 98,203, 94,238,106,163,155, 8, 11, 96, 21,102, 27, 45, 76,104, 74,153, 8, - 12,105,255, 67, 29, 57, 36,108, 2, 41,145,178, 11,115,238,220,185, 50,107,214, 44,193,110, 58,101,203,182, 22,208,194,253, 93, - 4, 88,170, 93, 22,207, 1,208,188, 32, 17,163,170,176,166,222,246,182,204, 7,240,150, 8,116, 71,182,111,223,222, 11, 19,170, -151, 53,208,162,148,236,247,223,127,247,194,142,178, 9, 80, 85, 36,215,122,135, 10,180,176, 29, 93,152, 44,141,223, 9, 86,212, -235,252,109,208,160,129, 98, 15, 71,195, 95,123,116, 9,150, 48,201,123, 79,134, 36, 21,128,140,237, 73, 62,113,227,128,160,236, - 2,240, 13, 35,232,140,146, 41, 83, 38,133,175, 89,178,100, 17, 72, 97,184,125,157,190, 56, 44,253,104, 5,191,130,101,180,150, -104,209, 6,166, 80,153,106, 82,184, 88, 69,249,198,205, 77, 26,184,101,144,238,223, 87, 82, 36,110,144,232,252, 19,128,150, 45, - 22,117,193,197,125, 72,186, 85, 71,165, 74,149,186, 9,233, 41, 62,163,215,175,161,218,127,141,254,243,156, 96,202, 86, 2, 40, -126,134,190,251, 12,125,195, 7, 96,243,178, 86,219, 19,104,225,219,105, 7,195,221,118,216, 17, 28, 66,154,101, 9,178,156, 1, - 90, 25, 51,164,221,241,196,231,230, 75,143, 35,189,253,104,248,254,243,160,220, 14, 37, 89,255, 6, 27, 45,149,207, 48,122,111, - 79,163,119, 56, 1,126, 24, 47, 94,188, 22, 22,252,143,137,126,127, 2, 99,107, 32,199, 57,142,179,212, 28,128,255,119, 53,218, - 72,175,154, 48,216, 24, 30,224,126,130, 3,154,161,232, 37, 74,102,186,253,242,211, 22, 57, 37,177,196, 75, 76,226, 21, 24,201, -103,228,138,118,171, 22, 22,152,233,179, 54,239, 52, 89, 95,232, 15, 57, 59,233,144, 36,136, 18,143,210, 25,155, 7,141,225,167, -140, 31,241,241,151, 1,189,165, 86,237,170,242,242,213, 45,121,236,125, 71,110,221,191, 43,209, 20,144,149, 74, 10,151,169, 46, -158, 39,110,202, 62, 0,173,193,131, 70,127,248,183, 25,195,167, 42,213,165, 81,234,210, 93,158, 58,240,163,165, 75,136,226, 82, -188, 75,163,148, 37,187, 60,181,246,163,245,218,231,154, 28,220,210, 87, 22, 14, 49,157,210,218,117,168,245,221,127, 5,247,173, -119, 29,234, 7, 90,156, 32, 11,231,204,250,248,236, 46,119,217,183,104,138,204,237, 92, 87, 10,231,206,233,147, 50,123,233,171, -206,128, 44, 50, 9, 19,215, 67,174,140,154, 53,237, 37,179,103,237, 11,149, 60,247, 92, 22, 38,222,251,245,151, 89, 78, 1, 45, - 75,144, 69,213,153, 45, 73,150, 94, 27, 45, 2, 45,218,125,169,146, 44, 75,195,119,130, 35,216,170, 40,118, 89, 28,124,244,238, -100,180,234, 36,123,169,154,164, 91, 10, 11,160,229, 92, 63,178,176,209, 34,208, 90,184,112,161, 98, 99,241, 29,156,193, 18, 32, - 80,122, 66,159, 98, 4, 14, 19, 38, 76, 16,168, 2, 5, 64, 70, 1,163, 0, 75, 14,141,225,113,127, 6,118, 89,122, 65, 34,116, -130,118, 90,144, 24, 41,210,172,172, 89,179,238, 69, 33,109,130, 10, 71,133, 71, 31,170, 15,112,114, 12,187, 90,188, 96, 16,238, -181, 96,193, 2, 47,172,156,205, 4, 91, 76, 24,232,205, 84, 77,210,175, 22, 84,129, 94, 5, 10, 20, 56,142, 58, 88, 14,248,161, -200,211, 54,143,128, 90,141, 32,208,124,220, 89, 57,115,227,165,178,203,144,160, 91,141, 50,160,254,114,130, 96,152, 39, 45,160, -197, 93, 55,101,203,150,149, 10, 80, 97, 87,170, 84, 73,225, 39,221, 67,208, 81, 41, 87,124,220,129,218,172, 89,179, 96,181, 50, -128,129,183, 30,160, 5,137,157, 80, 74, 10, 23, 25,210,162,229,143,146, 47,117, 42,169,239,150, 94, 70,127, 83, 76,150,142, 25, -169,168, 42, 1,244,254, 46,160, 69,245, 47, 85, 44, 52,112,111, 31,212,198,150,255,117,217, 78, 89,242,182, 88,177, 98, 55,128, -177,222, 64, 45,238,131, 29,192,207,109, 1, 46, 21, 96,193, 69,199, 51, 44, 96,158,195,133,202,115,240,192,210, 9,168,205,230, - 34,208,162,106,208,218,240,221, 26,100,233, 5, 90,112,217,145, 31,253,242,250,235, 23,119,228,254,141, 61, 50,125,110,221,119, -142,212,133,150, 46, 33,156,251,104,191,142,220, 24,255,126,196, 98,227, 6,192,151,162, 30,166,148, 28,106, 90, 51,119,141, 99, - 1,114, 25,223,145,214, 4,242,217,129, 86,194,164, 38,247,107,207, 39,201,121,113,253,180,232, 93,230,253,137,175,204,246, 49, -173,221,183, 55, 82,139,151, 62,117,171, 28,220,191,249,219,249,159,182,247, 89, 35,241,163,196,161,223, 55,123, 71, 12, 72,181, -238,220,187,121, 1, 70,239, 55,165,126,195,134, 18, 59, 65,114,137,147, 40,181, 28, 57,115, 67,246, 30,191, 42,171,183, 29, 19, -151, 44,197,165, 80,217, 26, 18, 51,122,116,110,166,249,151,185,119,232,244,252,199,113, 94,255,247,163, 53,237,130,100,202, 95, - 57,216,143, 22,237,183, 80,103,123,126,180,130,249,154,162, 68,167,231, 85,126, 57, 20,236, 71,171,250,144,147,146, 50,103, 69, -167,252,104,125, 29, 95,135,195, 82, 58,239, 25, 30,198,221, 49,115,101,201,208, 53,127, 54,215, 7, 11, 70,246,251,180,227,143, -145, 10,200, 98,202,151, 53,163, 93,201,128, 85, 49, 66,168,130,232,199,136, 32,200, 30,208,218,186,229,156, 48,105, 0,173, 16, - 52,185,115,134,210, 39,170,196, 56,241,106,129, 44, 59, 18,173, 16, 52, 41, 37, 35,208,162,148,193, 18,100, 81, 26, 68, 35,118, -190, 71, 5, 89, 42,160,179,161,142,180,167, 6, 83, 28,150, 18,104,113,167, 36,207,145, 28,251,204,250, 63, 83,255, 79,211, 2, -104, 17, 64, 81, 90,197,196,115,235, 52,102,204, 24, 97, 82,109,184,172,128, 86,168,114,210, 94, 10, 3,106,183,252,249,243, 31, - 33, 48, 34, 8, 34,208,194,181, 45, 58, 63, 6,235,118,223, 3,131, 91, 47,168,239,188, 32,225,241, 2,144, 57, 65,207,242, 72, -177,241,174, 24,248,237, 74,111,243,112, 65,161,216,128, 97, 96,183,229, 45, 62, 4, 77, 21,104,169,234,193,198,253,151, 73,137, - 31,250, 75,185, 6,253,148,157,136,148, 54, 18, 20, 83, 61, 75,201,164, 29,160, 21, 76, 83,149,104,193,141,133,192,157,133, 2, -178,170, 86,173,170,216, 76, 17,164,210, 62,143, 54,110, 4,179,244, 49,212,166, 77, 27, 33,192,181, 1,180,130,105, 66,162,245, -120, 52,236, 13,169,114, 36,208, 42, 92,184,176, 0,128, 40,198,251, 3,123,246,144,206, 85, 42,200, 66,128, 44, 74, 55,225, 24, - 85, 16,218, 72,217,112, 1,213,161, 53, 32,212,173, 82,213,217, 62,204,102, 73,179, 53,236,199,142,225,219,160,189,206, 49,220, - 91,201, 95,139,255,122, 37, 89,193, 52, 33, 45, 24, 53, 98,196,136,151,176, 25,124, 3,149,248, 75,216, 31,250, 32, 61,199, 55, -244, 10, 82,215,103,176,127,124, 6, 73,227, 51,244,135,231,216,233,244, 2,234,100, 31,168,111, 55,227,221, 8,149, 26,226, 8, - 85,119, 2, 45, 26,187,227, 91, 12, 54,124,167, 71,120, 72,113, 21,117,161,101,178,163, 58, 12,166, 73,208,148, 51, 71,182,109, - 79, 30,156, 10,184,113,126,157,236,223, 54, 70,166,140,239,240,202,158, 77,150,181,223, 45,139,146,126,238, 54,114,162,105, 29, -102,213, 44, 39,128,214,125,142,169, 28,163, 40,197,194, 66, 45, 0,215,232,122, 3,152,212,230, 17,130,102, 4,169, 14, 45,105, -222,193, 91,173,119, 29,182, 31, 51,183,241,147, 25, 47,247, 62, 49, 93, 88, 37, 74, 2,208, 50,181,124, 37, 76,205,255,240,189, -223,178, 90, 15, 2, 35, 46, 28,212,195, 86,221,139, 20,202,151,231,205,245,203,176,149,197, 98, 44, 85,134,236, 18, 61, 65, 26, - 57,116,250,182,236,129, 36,203,173, 64, 37,201, 87,162,154,100,113,205,250, 22, 68,254,117, 14, 75, 85,137, 86,218, 50, 93,188, - 19,185,125,251, 42,105,138,244, 31,186,119,239,174,140,151,107,214,172, 33,207, 29,249,209, 10,230,167, 42,209, 74, 85,178,139, -119,194, 44,164,147,241, 3, 53, 44, 52,217,160, 47, 54, 13, 58, 17,213,183,191, 62, 58,121, 92, 51, 92,235, 84,251,219,119, 43, -135,119,151,181,195,186, 42, 0,107,108,203,239,228,219,130, 57, 94, 20,112,203, 60, 66,103,141, 66, 1, 45, 2,152, 86, 63, 14, - 80, 36, 86,214,105,236,152,197,194,164, 94,215,227, 25,158, 64,139,246, 5, 42,200,162, 4, 67,235,208, 2, 69, 4, 90, 28,104, - 72, 87, 13,179, 67, 23, 14,106, 12, 69, 74,229, 40, 73,209,216,201,104,111, 64,219, 75,131,104,218, 13,113,167, 32, 13,182,193, -203,189, 78,243,211, 2,104,177, 28, 44, 15,165,107, 44, 35,203,204,242,211,240,157,170, 84, 2, 68,110, 16,160,161, 60,237,192, -180,128,150, 90, 22,128,153, 84,152,168,134,195,248,251, 4, 0, 11,129, 22,183,250,235, 57, 66,212, 29,239,219, 65,144,133, 85, -177, 23,212,111,199, 64, 51,175, 53, 17,228,201,198,123, 4, 89, 65,190,181,118, 58,154,112, 9,180, 88, 39,214,141,253,132,245, -226,230, 2,110, 40,160,207, 48,130,100,170, 11, 41,149,100, 10, 82, 29,218, 5, 48, 4, 90, 80, 95,120,163,140,130,221,116, 10, -200,162, 10,146, 97,119, 84,245, 35, 55, 66,112,131, 4,109,179,160,230, 82,182, 48, 59, 2, 90, 80,195, 28,133,244, 78,177, 21, -163,221, 24, 13,247,105, 7,195,231, 56,248,176, 76, 52,226, 87,164, 92, 0, 88,148, 60,210, 57, 46, 0,215, 81, 71,117,215,211, - 0, 58,242, 88,182,209, 90,130, 42, 0,149,211,252,133,125,222, 53,254,194,238, 80,249, 15, 90,192, 23,186, 14,235, 62, 95, 6, -252,217,138, 29,149, 47, 80,215,215,144,108,189, 68,219,248, 64,130,229, 3,105,235, 11,216, 20,190,196, 38,129,231,176,245, 34, -128, 47, 99,231, 13, 54,129, 22, 37, 90,234,238, 66,130, 44, 26,190, 91,131, 44, 7, 18,173, 96,154,169, 92, 98,182,202,150, 43, -241,219,223, 6,212,251,176,108, 78,143,128, 42,229,115, 94,143, 29, 51,234, 54,218,108,233, 9,207,163, 49,137,235, 98,154,131, - 76,154,160, 40, 12, 47,208,164, 9,105,214, 56,168,204,159, 99,145,240,158,139, 21,168, 20,185,211,206, 30,200, 98, 17, 52,105, - 34,143, 94, 41,151, 90, 37, 45,154, 81, 35, 39,138,119,185,151,215,206, 15,109, 30,158,144,244, 87, 55, 75,188,141, 7,247,167, -233,254, 70,106, 78,246,147, 90, 67, 79, 7, 68,142,153,152,106,104, 58, 73,213,162, 89, 20,210,170,251,147,199, 77, 52,207,248, - 99,190,148,255,174,158, 28, 60,113, 85, 70,254, 62, 83, 10, 22,171, 16, 24, 51,122, 12,126, 3,255,202, 16, 60, 65,140,137,133, - 69,225, 21, 2, 35, 74,244,105,207, 59,116,232, 80,201,242,151, 31,173,103,216,117, 72,199,197,182, 14,235, 54, 34,157,203, 92, -128,210, 68,130, 82,122,238,202,215, 65, 39, 12,221,248, 31,249,136,234, 71,203,210,159,150,227,130,230,113,203,232, 85, 32,135, -235,147,130, 76,217, 50,123,231,207,154,233, 78,193,236,153,246,103,205,156, 70,175,244, 37,212, 7,200,184,133, 4, 68,156, 24, -245, 38,173, 88,135,244, 95, 69, 16, 68, 73,150, 30,144,165, 71,162,197, 0,209, 4,112,106,226, 59,212, 68, 91, 44, 53, 17,176, -169, 9, 43,190,240, 4,149,214,203,211,255,119,236, 32,160,229, 44,200, 98, 76, 69,148,223,153, 88,135, 52, 96,207,142, 52, 1, -137,142, 0,245, 28,214, 0,155, 1,164,119, 32,237, 6,200,170,103,143, 0,238, 57, 10, 52, 29,130, 38, 12,120, 15,161,125,238, -169, 9,237,115,207, 50,177,142,150,137,224, 18,109,116,200,234,221,193, 52, 85,160, 69, 9, 20, 29,247, 17,252,112,199, 41, 35, - 2,208, 30,143,131, 7, 1,146,101,226,192, 68,195,117, 43,213,161,101, 57,243, 18,108,161,172,143,105,112, 12, 85,140,146,112, -237, 25, 64,221, 91, 0,140,247, 72,254,176,205,122, 11, 64,242,140,146,172, 32,144,101, 13, 68,181, 38, 29, 61,109, 98,157,199, -146, 38,195,235,172, 65, 90, 96, 37,201, 98,156, 51,110,211,214,235,176,208, 94, 57,203, 64, 85,188, 13,124,124, 1, 73,227, 43, - 72, 86, 95,125,255,253,247,207,177,219,116, 43,104,219, 3, 88,118, 39, 71,180,121, 53, 74,181,152,208,198, 14, 19,242,212,182, -193,156,224,114,230, 41,154,240,221,216, 5,185,197, 53, 91,252, 55, 9,226,197,216, 70, 53,162, 30,128,101,195, 70,235,115,183, - 81, 88,218, 88,207,228,104,143,110, 44,240,249, 5, 55,217, 96, 81,163,229,119, 79, 79,221, 35, 26,104,177,220,153, 34, 39, 78, -120,174,252,248,223,222,182, 61,189, 67,134,157,187,126,171,225,184,107, 82,160,193, 4,223, 72,177,146,208,215, 91, 38,123,223, -187,141, 74, 91, 6,149,126,250, 31, 11, 42, 61,158, 0,139, 11,127,142,111,121, 96,163, 58, 50, 74, 20,185, 15,155,209,135, 72, - 24, 4,158,235, 4, 90,227,185,176,228, 66,151,227,102, 94,253,116,116,245,109,116,160, 34, 72,213,130, 82, 81,252, 98,171,169, -148, 15,250,255, 45,126,121, 77,189,207,223, 98, 86,247,163,233,122, 81,216, 51,217,247, 12, 31,118,154,186,158,180,158, 28,207, - 98, 96,164,158, 95,119,194, 71,110,237, 45, 58, 4, 77,220, 63, 97, 11,248, 88,130, 32,235,115, 39, 64,145,174, 74,234,236,132, -225,161, 21,122,210, 1,208,114, 73,145,226, 8,119,210, 49,209,208,219, 58, 97,146,161,215,231, 16, 9,117,127,148, 52, 89,178, -189, 22,133,209, 51, 72, 58, 91,246,175,142, 38,193, 18, 86,181, 94, 0, 58,222,106,162, 10, 68, 77, 0, 5,222,106,162, 20, 43, - 56,197,142, 13, 91, 92,135, 65,165,157,229, 93,120, 38, 71,103,222,101,171,141,104,139, 69, 85, 11,109,181,104,163,229,172,109, -150, 86,187,151, 1,208, 92, 7,208,197,144, 75, 90, 0,203, 46,208,114,166,146, 90,223,102,234,244,177,220,243, 21, 75,248,142, -146, 45,103, 0,214,127, 0,104,153, 48,118,140, 71, 58,140, 49, 86,203, 38, 75,171,221, 77,118, 28,150, 58,106, 74, 77,154, 65, - 15,211,102,180,173, 41, 81,252,141,166,248,137,175,153, 98, 36,221,168,252,183,109, 75,170,151,166, 51, 93,236,107,167, 73,255, - 87,202,214,124, 46, 48,115,153, 76, 1,211, 45,252,104,205,252,203, 51,188, 30,137, 86,120,232,232,226, 55, 65, 20, 50, 42, 42, -100, 44,130,251,227,127, 85,254, 90,252, 15,190,207,107,204,111,117, 63,216, 11,189,174, 23, 58,159,201,121, 27, 45,231,223, 97, -243,137,175,189, 19,134,135, 13, 70,221,195,195,189,208,207, 26,252, 52,248, 25, 81, 28, 48,250, 82, 68,113,242, 47, 58, 6, 63, - 13,126, 70, 44, 7,108, 80, 83,129,150,163, 95,203,123,118,242,125,246,114,254, 29, 47, 48, 62,192,136,229,186,193, 79,131,159, - 17,197, 1,163, 47, 69, 20, 39, 13,176, 97,244, 37,163, 47, 69, 44, 7,156, 0, 90,170,148, 75, 85, 27,170,210, 44, 75, 9,152, -122,237, 51, 23,210,126,172,195,160,213, 8, 63, 20,235,228, 76,153,108, 61,175,117, 77,139,190,214,243, 97, 41,179, 65, 51,116, - 59, 59,226,137,209, 70,246, 57, 96,244, 37,163, 47,233,237, 3,198,119,100,124, 71,182, 56,160,183,255, 88,230,251,183,244, 37, -181, 30,246,120, 16,170,158, 95,129, 68,235,159, 97,163,165,213, 67,116,222, 55, 86, 79, 58, 25,165, 51,155,193, 79,157,140,210, -153,205,224,167, 78, 70,233,204,102,240, 83, 39,163,116,102, 51,248,169,147, 81, 58,179, 25,252,212,201,168,240,102,179, 97,163, -165,216,100,217, 83, 23,254, 13,170, 67,135, 18, 45,155,245, 71,140,237, 40,247,239,175, 74,252,244,233,150, 20, 76, 60,231, 53, - 39,153,101,116, 66, 39, 25,166,145,253,107,229, 39,195,245,232, 13,217, 99, 47,239,215, 90,247,136,232, 1, 70,221, 35,130,139, -255,167, 97,240,211,224,103, 68,113,192,232, 75, 17,197, 73, 13, 58, 86,187, 14,185, 3, 81,221,101, 88, 49, 72,109,200,107,234, -206, 68,203,243,224,251, 95,168,168,250, 94, 67, 64, 69,112,245,248,241,226,114,143, 31, 47,236,248, 87, 90, 92,142,215,156, 4, - 91,193,157, 48,153,139, 11,195,183, 4,187, 67,112,184, 43, 16,121,129, 83,163,132, 72,255,142, 65, 82, 47,224, 8, 15,216,208, -251, 14, 75,209,173,190,142, 17,148,139,113, 14,115,231,206,221, 30, 97, 86, 22,194,209,101, 71, 27,113, 15, 45, 7,159, 81,145, - 34,153, 62, 49,225,241, 81, 26, 47,114,148, 87,107, 64,203,138,157,128,147,225, 34,193,147,137,231,120, 87,214,127, 41,112,213, -106, 47,250, 60,106, 2,215, 17, 59,176, 35,247, 53,206,187,219,120, 64,139,159,234, 35,244, 67,212, 23,222,251, 79, 35,252,144, - 47,118, 12,158,198,255,126, 72,209,244,208, 28,220, 53, 85,137,125, 91,155,108,229,175,173, 66, 15,238,153, 42,233,145,237,245, - 39,143,236,148,218,158,247,105, 71,229,228,174, 72,150,143,137,231,122, 3,156,235,173, 59,139,204,122,214, 69,162,227, 70,254, -218,170, 55,243,233,161, 89, 28,249,232,169,124, 11, 82,121,173, 70,212, 73, 83, 7,153, 16, 89,244,148, 83,125, 32, 46,118, 52, - 79, 71,186, 15, 55, 59,140, 25,152,214,206,203,156,161,169,183,188,246,104,178,173,217,151,126, 10,250,181,244,147,165, 69,219, - 97, 57,177,187,178, 58,234,186, 13, 59, 45,183,241, 92,139, 88,208,253, 47, 89,247,224, 34,193, 61,204, 36, 56, 21,127, 75,111, -253,116, 67,100,233,126,200,198,174,122,189,253, 83,103,149,131,179,125,142,186, 59, 91,134,127, 82,126,231,118, 29, 82,122, 69, - 96,117,230, 84,175, 63,183,108,254,246, 37, 19,207,121,141,247, 82,102,175,147, 62, 93,161,250, 91, 50, 22,109,242, 56, 69,190, -186, 31,211, 22,106,248,216, 37, 95,221, 45,188,110, 85,235,224,134, 32,176, 10,120,115, 69,252,124, 14,137,217,239, 78,176, 79, - 21, 91, 39,138, 67,209, 48, 0,173,196,137, 93,227,199, 77,149,123, 96,162,244,249, 14, 38, 72,151,235, 77,252, 52,185,222, 36, - 76,155,255, 96,220, 84,185, 6,243,158,131, 22,209,236, 48,217,147,154, 82,102, 75,106,234,145, 45,153,201,131,191,252,175,209, -194,214, 52,245, 2,142,240,128, 13,203,103,199,233,236,129,154,117,183,164,131, 1, 55, 49,194,165,172,128, 39,254, 77,112,144, -234, 14, 71,164,155,106,215,174,189, 18,215, 83, 91,228, 83,105,166, 32,192, 82,219, 24,231,129, 24, 20,166,160,125, 71, 89, 39, - 94,231,125,139,188, 4,102,150, 82, 48,187,229,196,214,241,198, 69,139,149,244,218,123,224,232,213, 43,215,110, 63,188,112,249, -230,237, 77,219,118, 29,207,147, 55,223, 49,222, 11, 99,187, 71, 66, 96,228, 70, 0,108,203,144,206, 6,165,101,188, 6,122,142, - 38,244, 16,229,196, 0,184,143,177, 37,157, 73,120,230,128,189,239, 72, 71,155,214, 71,124,186,183,116,128, 74, 15,246,140,115, - 9, 94, 51, 24,180,245, 97,205, 79, 5, 80,161,158,167,209, 22,190,112,101,113, 10,255, 7, 96, 64,247,252,243,207, 63,111,194, -187,254, 51, 56, 92,125, 11,199,171,143,225,107,231, 82, 80, 64,105,235, 73, 46, 84, 27,117,171,154,114,235,177, 93, 35,223,242, -215, 86,217,127,237,152,185,231,225, 93,189,110,241,215,201, 73, 60, 50,194,245, 76, 69,120,167,183,152, 88,158, 33, 61, 13,154, -116, 56,241, 60, 1, 15,149, 4,128,104, 43,118,162,158, 62,159, 29,229, 25,135,231,159,143, 28, 57, 82,137, 50, 64, 31, 67, 0, -154,244, 41,196,111,139,247, 45, 15, 61, 52,215, 35, 4, 86, 32,163, 88,128,191,122,156,255, 90,210,204,134,151, 45, 70, 98,220, - 73, 85,179, 64,176, 70, 58, 76,193,192, 13, 94,249,103, 96, 1,244, 16,215,126,213,209,238,118,187, 20, 64,250,210,117,235,214, -125,164,175, 62, 58, 7,198,255,253, 78,182,145, 61,218,173,224, 66,229, 60,163, 36,128,159,108,159, 54, 54,190, 41,107,126, 18, -228,181, 66,123, 44, 67,164, 6,119, 56,192,117,135, 31, 59,119, 56, 83, 93,198,235, 72,246, 64,160,238, 54, 34,200,130,227,103, - 37, 58, 5,128,150,221, 96,212, 97,104,119,187, 60, 14, 11, 63,209,190,147,225, 92,248, 13,199, 74, 56, 1, 22, 58,208,102,132, - 18,213,129,182, 13,135,220,124,141,158,254, 25,161,229,116,150,216,191, 40,191,150, 59,148,191,170,250,151, 52,107, 97, 71, 2, -172,183,111, 47,195,211,248,101,225, 57,175,241, 94,198, 98, 77,188,122,141, 92, 16,120,236,252, 29,121,244,252,189,240,183,221, -128, 63, 3, 83, 22,168,207, 96,193, 54, 59, 54, 27,159, 32, 75, 30, 13,150, 75,235, 19,203,179, 87,239,101,208,210,107, 82,177, -151,135,148,104,179, 88,154,252,182, 22,180,222, 42,243,108, 88,128, 86, 92,151,172,229,227,167,206,251,180,125,239,113,230,173, -135,183,201,165,219,103,228,226,173, 43,178,118,251, 9,105,221, 99,140, 57, 65,154,188, 79,153,199,153,142, 93, 48,149, 41,118, -214,164,166, 38, 57, 93, 34,109,111, 95, 45,247,167,125,127,116,146,231,251, 39,203,190,233,237,164,123,157, 60,159,120,157,247, -153, 79, 99, 64, 11, 5, 56,224,125,252, 16,194,187,120, 90, 38, 94, 11, 43,216,192,251,149,119,152,205,254, 10, 15, 73, 7,177, -245,182,129,151,189, 49,201, 59,138, 85,101,243, 3,196,104, 30, 3, 34,145,146,205,226,198,173,215, 56, 90,180, 14, 76, 77,226, -198,109, 80, 60, 93,186,145, 15,238,223,223, 2,175,243,238,240, 52,239, 14, 7,148,238, 91,183,110,221,132, 16, 42, 93, 45,120, - 96, 19,104, 69,142, 28, 41, 16, 94,199,119,192,243,187,187,117,226,117,222, 15, 3,208,202, 86,188, 68,169, 19,175,223,248,190, -191,119,251,238,139,223,186, 14,216,209,175,239,136, 77,179, 23,173,219,118,240,216,217, 35, 57,114,228, 62,130,114,113,146,178, -117,216, 27,124,210, 99, 34,244, 2, 80, 49,211,171, 60, 61,236,171, 33, 41, 0, 50,223,243, 30,136, 89, 47, 42, 84,250,214, 64, -203,251,242,238,237,114,255,204, 73,185,115,226,168,226,193,159, 3, 35,211,133,109,238,114,102,227, 90, 57,181,102,133,226,213, -159,137,113,229, 50,103,206,204, 73, 82,247, 4, 97,145, 49, 53, 36,141, 1,244,200,188,122,245,106, 37,200, 56,194, 40, 17,176, -118,214,232,159, 81, 17,254,102,247,224,193,131,175,237,222,189,219, 27, 94,157,125, 17,122,233, 62, 60,226, 63, 0,200,240, 69, -251,154,225,108,212,140,186,155,219,182,109,107, 70, 56, 39,115,243,230,205, 41,217,234,107,175,156,148, 96,117, 7,184,106,240, - 93,105,121,243,234,161,240,151,255, 45, 37, 91, 85, 17,234,169, 75,141,188, 79,207,159, 88,252,137,191,252,175, 81, 78,245, 54, -230,154,200, 83, 17,219,240, 5,251, 11, 67, 44,241,224,100, 99, 25, 29,129,206,145,233,179, 79, 39, 77,203,108,163,127,250,233, - 39,197,155, 63,219,158,116,212,196,112, 73, 12, 77,194,216,151,120, 96,180,141, 62,111,167,171, 41,151,221, 45,128,150,117,228, - 3,173,254,185,242,230,205,155, 50,118,236, 88,203,112, 38,158, 4,109, 76,120,216, 51,136, 64, 43, 58,215,101, 68, 8, 0,153, - 0, 92,179, 94, 20,232,157,112,163, 0,188,190,226,228, 77,158, 50,218, 4,192,135,189, 88,161,122,105,178, 44, 51, 24, 85,129, - 33,178, 24, 33, 3,161,185, 4, 17, 2, 88,254,121, 86,101,181,164,217, 2,125,207,253,240,225,195,238,248,126,220,209,212,193, - 9,206,170,221, 1, 6,221, 17,193,129,146, 66,135,241, 81,113,223, 97, 57, 41,201, 2,109, 47,148,203, 11, 64,213, 19, 78,134, - 61,224,188, 90,203, 89,175,222,186, 59,234, 23,214,247, 28,209, 28,139,126,239,163,142,147,224,139, 18,230,134,253, 83, 61, 12, -160,229, 12,171, 35, 52,175,115, 18, 45, 45,160,149, 60,119, 45,121,254, 54, 80, 94,190,147,224,196,255,188,110,111,224,101,227, - 83,146, 69,144,117,235,228, 80,185,255,204, 87, 42,245, 98,191,254,235,200, 90,117,128,220,122,252, 90, 57,199,224,248, 33, 70, -172, 88,227, 77,209,163,215, 54,165, 79,159, 82,145,110,253,255, 8,213, 9, 9,160, 50,229, 43,235,183, 3,225,108,188,159,191, -150,123, 79,124,228,240,185, 51,114, 4, 0,240,248,197, 71,114,232,236,121, 89,188,105,137,184, 22, 44,253, 46, 78,178,172,182, -188,176,135,162, 9,201,213,130,118, 85,178,190,223, 59,173,141,188, 4,184,242, 59, 62, 59, 84,122,178,123,188,108, 26,213, 72, -154,149,203,240,158,249,237,213, 29,215, 9,130,130, 65, 4, 1,197,230,205,155, 15, 1,108,120, 90, 38, 94,179, 2, 27,129,124, - 86,231, 96,174,188, 67, 5, 90,234, 59, 22, 45, 90,228, 89,166, 76, 25, 15,240,180,180,157, 46, 21,170,238,205, 76,166,140,205, - 98,198,108,187,107,250,244,214, 47, 30, 60,104,135, 25,172, 19, 16, 92,231,123,151, 46,117,234,254,211, 79, 71,206,238,222,125, -246,202,153, 51,123, 56,240,193,163,176, 59, 2,108,187,231,203,151,111,137,157,114, 82,202, 22,200,242, 0,160, 92,178,144,100, -173, 32,216,194,255, 21,234, 53,222,103, 62,230, 7, 45,107, 53,163,205,193, 7,106,194, 25,187,247, 30,186,124,239,246,189,231, - 55,206, 95,244,158,250,219,168,157,211,198, 78,223, 50,110,202,130,149, 43,214,239, 92,191,116,213,250, 77,204,163,183,238,200, -151, 30,224,196,155, 43, 69, 14, 94,156, 12, 24,206,135, 30,143,233, 61,153, 97,116,150, 44, 92, 32,233,210,164, 33, 24,178, 5, -182, 66, 1,173,251,103, 78, 73,215,120, 38, 37,169, 19, 35, 39, 66,245, 26,127, 25, 83,142,137,147, 90,150, 44, 89,194, 10,180, -234, 49, 78, 25,129, 22, 86,250,175, 80, 62, 2,161, 52, 58,234,222, 23, 33,113,174, 46, 94,188,216,220,170, 85, 43,115,189,122, -245,148, 4,239,206,102, 76, 98,239, 49,113,155, 33, 25, 51, 3,188,153, 17,108,220, 92,179,102, 77, 51, 66,107,220,132, 71,123, - 74,189, 44,143,224,186, 83, 93, 72, 73, 22, 65, 22, 15,254,242, 63,175, 83, 77, 72, 9, 86,187,239,243, 63,155, 48,172,187, 4, -248,191,145,241, 67,187, 73,155,239, 11, 60,227,117,170, 19, 29,244,121,170, 8,199,163,124, 79,212,177, 3,160, 80,105, 23,198, -181,100, 91, 49,250,193,131, 7, 15, 84, 41, 76, 88,128,150, 55, 1, 6,193, 48, 35, 78,168, 33,190,248,203, 16, 87, 4, 91,236, - 31, 40,135,183,157,114,150, 6,200,185,139, 9, 81, 44, 19, 67, 58,149, 43, 87, 78, 73, 12, 86,206,208, 78, 4,108, 12,243, 84, -164, 72,145, 55,160, 85,204, 30, 63, 1, 44,231,239,219,183, 79,169, 50, 65, 32,242,245, 66, 58,202, 50, 49,225,252, 48, 82, 54, - 0,109, 95, 70,221, 96,104, 47,244,123, 91, 18, 40,221,192, 0, 33,177,142,179, 63, 50,242, 6, 67, 93,181,107,215,238, 21, 35, - 28, 0,128,237,193,187,104,248,171, 30,122,104, 50, 24,243, 12,150,157,188,155, 53,107,150,194, 3,140, 29, 74,249, 25,176, 29, -247, 41,217,178, 69,115, 49,193, 21, 34,127,184,163, 93, 66, 0, 45,254, 71,123, 80,178, 78,160, 69,137,159,163,195, 81, 57, 51, - 32,212,216, 30,198,116, 69, 40, 47, 47,212,215, 11,224,210, 11, 18, 52, 45,201,150,158,186,107, 20, 43,212,109,187, 52,161, 46, -252, 63,162, 2, 83, 24,226,230,222,189,123,202,184, 97, 0, 45,103,217,252, 55,231,215, 82, 29, 18, 80, 61,125,243, 73,110, 61, - 49,139,247,235,143,114,228,202, 11,153,181,249,170, 45,160, 21, 92, 19, 2, 45,118,132, 91,143, 94,203,205,135,175,228, 6, 82, -153, 54,243,100,164,251, 91,105, 50,227,153,100, 40,253,147, 92,190,171, 44, 80, 5,158,106, 17,179,238,116, 32, 68,196,239,176, -178, 8,136,159, 32,129,181,119,248, 96,186, 84, 9, 38, 76,151,231,217,246,163,187,100,251,137, 37,178,247,212, 46,121, 4, 16, -119,253,254, 11,217,127,234,158,252,190,104,182,252,248, 75, 13, 25, 62,189,171, 76, 91, 56, 82, 82,100,205,249, 42, 81,162, 76, - 9,180, 88, 12,224,164,148,229,131,207,117,241,191,178,213, 38,208,122,119,126,141, 60, 58,182, 82,142, 46, 29, 40,204,239,136, - 38, 6, 74, 56,220,253, 11,112, 20, 40, 80,224, 46, 2, 13,123,218, 74,188,167,130, 13, 60,227, 40,160,167,173,215,141,230, 59, -152,192,239, 59, 24,212, 60, 17, 75,207, 19,113, 21,249, 46, 15, 43,245,158,205,226, 98,249,150,190,107,150, 44, 63,249, 62,121, -210,222, 31, 32,235,225,218,181, 13,110, 78,157, 90,247,224,136, 17,141,187, 54,105,178,244,220,233,211,167, 94, 61,127,126,214, -125,193,130,115,115,167, 77,219, 77, 49, 62,226,243, 81,162, 69,149,134,205,131,106, 65, 74,172, 8,168,212, 12, 60, 15, 2, 90, - 33,174, 49, 31,243,107,181,143,122, 31,147,201,129, 11,151,110,220, 27,221,111,248,238,217, 35, 39,120,174,156,181,104,247,186, -213,238,219, 87,109,218,189,126,197,166,221, 75,143,158,188,176,145,121,116,210,139, 68,105, 21, 7, 46, 72, 30, 20,105, 6, 39, - 90,198, 80,100, 80,233, 33, 67,134,200, 47,189,122,202,220, 41,147,101,254,180,169,140,115, 72,201,150, 67,187, 32,218, 78, 80, -146,101, 9,180, 8,178, 24,156,220, 26,104, 49, 62, 37, 7, 76, 55, 55, 55,107,160,165,179,248,166,130,156,184,247,238,221, 43, -176,159,163, 36,139, 54, 65,154, 7,212,171,167, 16,106,229, 49,164, 84,102, 4,205, 54,171,128,171, 74,149, 42,102, 0,183, 0, - 4,208, 54,175, 90,181,202, 92,176, 96, 65, 51,232,155,209,151,204,136,247,248, 26,245, 39, 56,176,121, 80,114, 69,117,161,165, - 68,139,255,121,157, 54, 89, 84, 23,158, 59,190,228, 19, 65, 22, 15,254,158,197,127, 94,231,125, 59,100,201,235,168, 80, 23,254, -181, 34, 11, 58, 24, 87,141, 32,132, 82, 71, 6,129, 87, 65, 22, 65, 45,250,153, 45,160,165,197, 19,101,172, 82,165,153, 12,237, -165, 74, 28, 25, 94,100,250,244,233,194,208, 52, 32, 98, 9,180, 44,105,206, 36,120,176, 62, 8,222, 24,168,153, 49, 71, 9,170, -217, 15,216,207,216,223, 24,247, 18,170,208, 69, 14, 10,150, 8,125,233, 58, 65, 36, 1, 32, 99,110,162,125,164,114,229,202, 74, -108, 78, 6, 37,175, 80,161,130, 18, 59,147, 64,171,120,241,226,102,208,202,161, 85, 81, 7,247,115, 1,204,190,216,178,101,139, - 2,132, 88, 70, 46, 60, 88, 7, 44, 58, 2, 33,253,209,163,250,100,123,141,195, 34,207, 15,170, 46,101, 92,167, 52,107,208,160, - 65,228, 29, 85,126, 25,145, 22, 32,200,184, 34, 49, 3,168,185, 96,167, 60, 10,208,162,186,144,146,116,130, 43, 38, 72,127, 21, - 41, 23, 36,177,238,232,159,122,128,150,189,234, 42, 32, 11,109,236,133,254, 67, 73,182, 23, 2,211,123, 33, 30,169, 23, 67, 71, -133,131,135, 17,254, 40,213,227,236, 3,148,100, 81, 18,136,111, 85, 1,254,170,148,156,253,212,142, 68, 75,179, 44,229,202,153, -162,230,116, 77,252, 67,201,194,174,158, 37, 10,101, 62,144,195, 53, 81, 83, 87, 87, 83, 12,205, 7,141, 12, 42, 7, 10, 6,157, - 88,198, 60,252, 63,119,184, 2,230, 63,245, 87,203, 24,158, 64,235,193,139,143,178,216,243,137,244,156,121, 70,190,237,185, 77, -106,253,226,161, 11,104, 93,186,243, 92, 46, 34, 93,184,237, 35,133, 27,140, 13, 6, 90,169, 10,212,151,211,215,159, 42, 99, 83, - 86,183,204,178,111,231, 98,185,119,235, 28, 86, 83,190,212,227,223,183,215,150,180,201,234, 55,177,255, 71,175,171,251,100,208, -220, 38,226,113,100,173,188,244,245,151,115,160,181,255,244, 61,105, 51,176,158,252,216,191,169,212,239, 82, 83, 38,204,234, 47, - 45,187,214,255, 20, 63,101,238, 97, 90,125, 67, 5, 90,239, 79, 47,145, 79,239, 94,200, 39,223, 39,226,127,107,175,188, 59,185, - 64,222, 93,221, 46, 62,215, 14,203,149,189,203,100,221,208, 58,178,110, 72, 29, 77,160,197,247, 97, 37, 56, 28, 43,183, 67, 80, -197,120, 98,101, 50,193,186, 12,188,198,123,204,195,188, 90,101,180,115, 95, 53,134,143, 2,192, 82, 52, 91,182,108,203, 49,104, -120, 66, 50,225, 9, 21,226,111,142,104, 82, 93,216, 60,102,204, 54, 88, 18,183,127,233,229,213, 98, 70,139, 22,237,114,186,186, -158,203,146, 41,211,243, 18,197,139,191,232,221,189,251,189,155,103,207,158,188,113,241,226,201, 99, 7, 15,158,153, 60,112,224, -217,223, 71,143,222, 10, 9,208,114,216, 5,217,181, 89,179, 7,170,108, 1, 45,235,107, 90, 60, 64,220,192,205,231, 46, 94,191, - 49,115,246,242, 93, 80, 29, 62,220,181,117,247,190, 67, 71, 78,237,245,121,254,234,158,231,129, 83,171,143, 28, 63,187,130,121, -180,232,240, 62,237,175,176,210,254,160, 6,228,102, 95,228,196,200,201, 21,131,185,244,239,209, 77,122,180,106, 41, 93,127,168, - 45,171,166, 79,145, 31,127,168,243, 62,200,102,203, 46,121, 2, 45,170, 11, 85, 73,150, 37,184, 34,144,227,132,203,247, 13,112, - 77, 33,131,243,103,145,195,139,231,134, 7,104, 65, 8, 28,125, 51, 37, 60,156,188, 96,188,254, 10, 5, 67, 84, 13,199, 7, 6, -111,223, 37, 75,150,248,194,214, 78, 1, 89, 4, 84,136, 69,104, 46, 93,186,180, 25, 65,159,253, 33,149, 81,212,134,144,188,152, - 33, 29, 53, 67, 90, 99, 70,192,233, 43,176,211,178,150,104,133,122, 17,213,133,148,100,245,252, 62,213,158,227,187, 27, 77, 90, - 56, 33,111,106, 74,172, 40,185,234, 84, 61,239,211, 96,137, 22, 36, 91,144,104, 61,229,117, 7,134,241, 10,208,162, 84,133,224, - 23,101, 22,214,149, 96, 0,253, 70, 81, 67, 89,130, 44,242, 54, 12, 64,139, 18, 51, 5,104,145, 38, 19, 37,101, 4, 47, 12,180, -203,126,192,180,109,219, 54, 71, 64,171, 0,128,206,107,107,137, 22,131,134, 83, 58,132,197,137,128,215, 2,201,160,192,116, 64, - 9, 94, 14,158, 19, 92,107, 25,200,187, 98, 33,246,138,160, 68, 85,147,146, 30,251, 15, 65,155, 10,226,184, 32, 0, 45,107,181, -174, 86, 55,176,188,159, 3,210,182,231,156,180, 25,172,157, 18, 40, 6,107,191,116,233,146,156, 63,127, 94,137,137,135, 54,184, -171, 65, 48, 50,190,141,141,180, 19,100,255,231, 65,181,248,239,191,255, 46, 88, 64, 82, 5, 25, 61,232,249,212,148,232,241, 40, - 95,190,188,189,197,170, 2,180, 84,115, 3,148,197, 29, 18, 39,247,174, 93,187,186, 3,184, 41, 9, 96, 91, 5, 90,212,126,204, -193,184,247, 20,191,125,236,149, 17,224,175, 14,190, 77, 15,140,179,171, 84,144, 5,213,172, 23, 2, 42,123, 65, 93,184,131,146, - 44,204, 59, 30, 0,191,211, 48,142,122, 97,124,187, 4,213, 41, 23,108, 85,157, 97,100, 68,231, 69, 89,158, 18,168,179, 95,210, -110,144,106, 67,130, 96, 53,118, 48,239,161,207, 63,115,230,189,110,110,241,146,230,112, 75,210,191, 78,141,178, 79,102, 76, 29, - 39, 27,214, 97,225,178,123,131,204,152, 50, 92,234,214, 40,243, 50,103,182,100,163,178,103, 76,104,207, 84,194,153, 87,105,230, -181,198, 34,154, 15,252,179, 50, 88,251,209, 10,105,171,101,171,114,142,220, 59, 16,104,221,241,126, 47, 11,119, 63,150,238,127, -156,150,242,221,183, 74,141,254,250,128,214, 41, 0,160, 21,155,118, 73,199, 78, 93,228,187,106,181,165,251,164, 93,138, 68, 43, - 73,182, 74,114,248,194, 3,229,131,203,226,154, 65, 38,141,106, 33,155, 86, 79,130, 26,224,166, 36, 72,148, 8,161,197,108, 31, -105,242,228, 57,225,126, 96,165, 44,219, 49, 85,182, 28,218, 32, 55, 30,188,144,211, 87,159,200, 30,175,187,178,102,247, 21,153, -177,230,164, 12,158,117, 64,186, 79,220, 33,173,122, 53,149, 95,199, 12,144, 4,105, 11,208,110,199,225,161, 2,173,151,139,107, -203,203,165, 63,136,223,161, 73,242,241,197,109,145,192, 79,114,231,212, 78, 89, 63,188,158, 76,105,144, 66, 38,215, 75, 38,171, -127,171,166, 11,104, 97, 66,115,193, 10,116, 39,213,133,176,117,241,196, 7,145, 95, 45, 4,207,121,141,247,152,135,121,181,202, -168,231, 62, 62,204, 92, 42, 93, 12,210, 12, 28,108,247,104, 16, 45, 90,177,109, 19, 38,180,246,127,242,164,221,172,150, 45,219, -186, 96, 2, 6,240, 11, 8,240,247, 55,251,191,127,111, 62,124,232, 80, 64,187,182,109,159,239,219,178,197,107,225,188,121, 94, -181, 43, 84, 56, 92,212,205,141,170, 63,123, 54, 80,202,187, 62, 39,208,130, 81,237,128,245,238, 30,103, 78,157,191,122,110,253, -230, 61, 30,239,223,251,251, 6, 4,152,253,206, 92,188,182,227,226,213,155, 91, 39, 78,249, 99, 3,243,232,225, 21, 13,223,105, - 7, 67,169, 8, 87,136,156,184, 78,158, 60,169,168, 97,250,118,235, 42,221, 91, 54,151,206,181,171, 75,135,138,229,100, 84,139, - 38, 50,181, 95,111, 74,181,184, 50,183,123, 16,104,145, 22,129,150, 45,117, 33, 39, 73,166, 33, 5,220,100,116,217,130,114,100, -233,124,103,129, 86, 45, 76, 10,236,207,170,225,115, 6, 72, 46,159, 2, 88, 43,106, 25,128,204, 75,184, 23,211, 81, 25, 41,209, -130,148,226, 30,129, 22,140,232,205, 80,233, 16, 96,153,161,206, 50, 67, 21,245, 26, 96,192, 12,137,137, 25, 82, 50,115,225,194, -133,149,115, 87, 87,215, 67,160,169, 57,153,171,187, 14, 71,245,113,155,125,112,123,167, 51, 99,127,201, 61, 80, 45, 11,109,178, -218, 66, 93, 72,201, 86,167,234,249,236,217,104, 89, 23, 61, 50, 38,194,199, 4, 26,180,161,218,191,127,191,210, 70,156,112, 32, -129, 81,212,133,228, 53, 65, 22, 1,137, 78,160, 21, 11, 82,207,137, 80,183, 62, 70, 44,198, 79,224,217, 39, 6,197, 61,116,232, - 80, 48,216, 34,176,163, 49,188, 10,180, 8,238, 80, 48,123, 18, 45, 91,236, 46,223,165, 75, 23,165, 15, 4,169,254,202,233,233, -147, 54,242, 20,199,194,230, 26,190,105,129,164, 81, 32,129, 84,234, 75, 16,215,172, 89, 51, 2,183, 79,216,192, 48, 7,207, 57, -235,138, 71,149,204,102, 87, 65, 22, 39,109, 74,218,200, 95,242,131,243, 4,191, 5,168,143, 63,160,207, 77,117, 80,126,218,208, -205,155, 61,123,182, 50,158, 79,155, 54, 77,208,159, 20,251, 50,130, 2,218,144,225,217,182, 72,124,231, 44,128, 27, 69, 90,134, - 54,112, 40,209,178,180,235,164,116, 11,245, 13, 6, 90, 52, 95, 0, 45,154, 47, 44,165,244,153, 7,108, 29,253,240, 63,154,173, -114, 98, 92,220, 65,195,119,226,105,254, 18,100, 1,172, 17,100,109, 71,254, 12, 65,207,252, 2,201,173, 34,209, 38, 31,152,176, - 0,249,136,123,159, 67, 93,232,176, 59,100,203,150, 40,119,222,156, 41,231,164, 77,155, 38,144, 96,151,109, 66,240,203,115, 46, - 4,120,174,166, 12, 25,210, 75,145, 2,233, 55,231,202,154, 40,143, 35,162, 57,179, 36,204, 87, 36,127,134, 5, 61,126,110,253, -113,187,199,102,217,226,190, 94,186,116,250, 81, 10,230,203, 36,189,187,124, 39, 51,167,246,151,189,187,214,138,199,150,149,210, -227,231,150,129, 37,138,100,218,162, 69, 51,140,125, 58,248,177,175, 28,104, 89, 75,178, 66, 27,197,171, 21,180,195,168,100, 88, -193, 44, 3,194,247,102, 74,154, 38,155,108,118,247,148, 9, 11, 15, 74,135,241,251,164, 92,183, 45, 82,173,239, 54, 93, 18,173, -195,231,239, 75,135,142,157, 21, 81, 60, 63,228, 76,174,110,146, 44,219,183, 82,160, 82,107,217,125,252,170,242,129,184,102,206, - 32, 99, 7, 55,150,163, 7, 54,200,218,181,107,204,166,104,209, 24,224,214,230,145,169,104,182,119,231,174,159,133, 45,214,125, - 57,127,227,169,120, 93,122, 44, 59,142,221,150, 21, 59, 46, 73,181,182,185,229,219,198,153,165, 92,221,180, 82,170, 90, 10,169, -211,169,179,140, 91,184, 91,226,165,202,245, 86,171, 67,132, 0, 90, 4, 91, 65, 41,224,166,167, 2,174, 44,211,170, 95,191,211, - 5,180,248, 78, 12,252, 93, 32, 53,241,132, 77,137, 39, 6, 2, 4, 70,255,235,224, 57,175,241, 30,243,104,149, 79,239,125,168, - 89, 50, 97, 64, 82, 0, 28, 36, 20, 91, 28, 61,215, 60,110,220, 31,158,223,189,219,214,123,235,214, 6,217, 93, 93, 47, 65,141, - 23,240, 1, 40, 1,118, 41,230,183,190,190,102, 12,232,230,181,107,214, 4,180,110,222,252, 78,187, 70,141,150, 31, 94,191,190, - 53,141,229,181,202, 98, 1,180,130,237,177,104,155,101,109,163,101,113, 77,203, 13,132,229, 43,227,186,164, 72,233,121,249,234, -141,155,167,206, 93, 59,178,126,163,199,254,109, 59, 61, 15, 94,191,249, 96,247,177,147,103,247, 96, 66,216,139,204,241,180,202, -200,251,220, 89,200, 1,159, 3, 42, 13,172,185,106, 60,114,228,136, 28,218,181, 83,186, 53,111, 38, 29,106,124, 39, 29, 1,178, -186,151, 47, 45, 3,191,171, 32, 43,134, 13, 36,208, 58,235,136,182, 10,180,108,169, 11, 85,144,197,119,142,253,166,176, 76,170, - 94, 94,142,173, 90, 34, 89,179,102,213,171, 58, 44, 84,180,104,209, 0, 74, 29,168, 62, 66, 57, 18, 6,149, 37, 15, 84,238,239, - 9, 68, 8, 14,112,141,129,162, 29, 29,125, 49,185,158,131,154,208, 12,169,130,153,106, 39,208, 53, 3, 84,132, 72, 13, 26, 52, -120, 85,163, 70,141,171,144,188, 30, 7, 49, 26, 95,235,218, 90,223,189, 94,154, 88, 99,186, 22, 59,115,242,192,184, 55,252,229, -127,181, 48, 58,118, 29, 90,151, 59, 18, 36, 11,143,168,194,226, 36, 67,117, 33, 37, 89,156,192,235,215,175,175, 36, 21,100, 81, -130, 2, 41,174,150,234, 48, 22, 0,214, 13, 76,206, 1,180,191,226,193,182,154, 60,121,178, 64, 42, 18, 12,182,172,129, 86,208, -120,169, 27,104, 65,186,179, 9, 42,124, 69,242, 64, 53, 39,254,111,208,211, 39,237,228, 33, 64, 97, 91,183,160,212,140,234, 71, -180, 11,219,185, 28, 18, 37,218,220, 84, 48, 22,105, 33,146,195, 69, 16,238,211,133,195, 34, 44,236, 94, 67,253,191, 23,253,224, - 5,199,102,242,147,117,230,228,205,141, 21,144,252, 60, 4, 8,185, 4, 32,250, 20,115, 1, 13,215,227, 58, 40,219, 60,242,143, - 7,129, 41,232, 6, 82,213, 10,224,206, 96,192,138, 52, 16, 96,150,160,106,198,248,241,227,149,124, 65, 82,184,214,118,104, 46, -166,170,208, 17,208,130, 45, 42,165,214,183, 85,144,197, 50,163,191,146, 39, 4,157,161, 14,212,103, 7,119, 23,162,239,120,161, -142, 94, 0,131,138, 36, 11, 25, 51, 4,101,254,153,234, 57,170,143,161, 82,231,198,162,199, 84,213,113,206,194, 55,175, 75, 66, - 30,142,246, 13,241,104,118,183, 36,163, 91, 52,173, 45,253,251,245,149,180,105,211, 42,166, 1, 76,252,190,169, 42,102,194, 38, - 22, 89,191,126,189,178,211, 56, 95,222,220,178,111,207, 70,129, 26,240,156,189, 50,228,112, 77, 60,110,208,111,189, 80,191,139, -178,114,249, 66,105,210,176,186,228,206,158, 90,114,101, 75,165,164,238, 63,125, 27,156,198, 12,105, 35,219, 55, 47, 20,175, 99, - 59, 36,187,107,226, 19, 17, 85, 47,123,116, 52,176,200,231,126,253,231,163,175,129, 34, 9,178,188,119,236,216,241, 81, 53, 12, - 93,133, 78,156, 62, 77, 90, 25,216,127,186,180,238,191, 92, 74,117, 88, 43,223,245,217,170, 11,104,237, 58,118, 69,126,234,136, -221,123, 24,204,160, 87,151,140,153, 50,201,182,253,103,101,235,190,211,178,121,239,169, 32,160,149, 94,134, 13,248, 65, 30,220, -187,202, 78,254,206, 20, 59,182,170,251, 12,197,132, 36,153,115,250,158,188,124, 70,214,237, 57, 40, 19,151,204,144,249,155,182, -200,226,109, 23,100,226,178, 99, 82,171,125, 37, 41, 91,251, 47,144,197, 84,185, 69, 77, 25, 58,123, 79,184,128, 22, 85,135,214, - 64,107,229,128, 42,186,129, 22, 6,170,132, 0, 60, 30, 39, 78,156,240,252,249,231,159, 9,170, 74, 50,241,156,215,120,143,121, - 34,170,181, 33, 34,111,139, 65,196, 19,237, 71,213,161, 67,117,100,147,104,209,126, 50,251,251,119,186, 63,127,126,157, 36,137, - 19,191,133, 90, 66, 1, 89,148,102, 97, 50, 55, 31,216,191,223,188,103,247,110,115,145,194,133,159, 31, 91,180,168,222,235,155, - 55, 27,113, 55,162, 86, 89, 85,160,101,107,183,161,173,107,150,182, 92, 90,180,131,238,103,168, 80,177,202,169, 71,222, 62,151, -183,238,220,191,222,115,255,177,213,222, 79,159, 31, 46, 86,188, 36, 1, 65, 22,157, 52, 20,160, 69,251, 7, 72,241,148,129, 12, - 18, 60, 57,184,115,135,236, 91,191, 86,218,127, 95, 57, 24,100, 13,175, 94, 81, 22,181,109, 38, 71,102, 42,118, 90,154, 64,139, -187, 11, 85,149,161,165,186,240,215,108,105,100, 88,161,236, 50,182,124, 17, 69,250,194, 68,233,151, 78,160,149, 12,146,171,135, - 4, 25, 92,221, 98,146, 80,213,120,156,100,169, 46,220,196,201,142, 82, 5,156,107,185,250, 80,118, 29, 66, 45,120,170,101,203, -150,215,170, 86,173,234, 15,160,245, 14,198,207,102,203,132,110,233, 15, 73, 5,237, 37,237,249,209, 10,197,106,130,170, 34,153, -210,244,237,211,177,145,220,184,178, 75,248, 91,204, 53, 93, 95, 21,108, 81, 77, 72,155, 44, 43, 3,120,135, 77, 70,160, 69,144, - 5,183, 19,202,196, 77, 73,150, 10,178,212, 95,130, 44,218, 86,105, 1, 45, 74,178, 32, 13,250,191, 37, 49, 70, 32, 2, 53, 74, -204, 56,249,131, 31, 10,224,182, 6, 90, 88,132, 56, 35,209,202, 92,169, 82,165, 64,170, 53, 41,125,160,244, 13, 6,241,220,240, -145, 73,111,223,180,202, 71,160, 53, 0, 54, 90,129, 92, 20, 16, 20,109,220,184,145,253,134,160,178, 63,212, 92,143,105, 71, 6, - 27, 35,129,122,119,173,163,119,160,223, 76,197,179,168,238, 39,197, 30, 17, 27,114, 20,112, 65,128,197,126, 69,251, 55,240,155, -192, 95,239,119,212, 26, 54,155,202, 56, 62,122,244,104,101, 55, 33,250,141, 23,237,136,248, 93, 97, 1,160,180, 27, 12,237, 3, - 41,225,226,193,126,202,124, 72,246,236, 29, 29, 2, 45, 72,247, 54,231,200,145,227,161, 37,200, 98,221,149, 69,187,171, 43, 85, -136,161,231, 13,236, 38, 68,221, 61, 32,177,245, 4, 80,245, 66,189,105,143,165, 46, 68,167,130,135,129,180,123,195,243, 44, 27, - 1,171,169,108,217,178, 28, 19, 9, 58, 15,134,177,221,194,244, 88,174,108, 73,189, 31,222, 58, 44,235, 87,195,172, 32, 75,102, - 69, 50, 8, 96,169,204,159,148, 6, 46, 92,184, 80, 81,201,142, 28, 49, 76,182,108, 90, 38,103, 79,108,145, 29,155,231, 75, 78, -183, 36,118, 23, 2,188,119,231,250, 97, 89, 52,111,188, 20, 47,236, 22, 12,176,172,129, 86,191,159,171,203,250,149, 19,229,226, -105, 15,217,182,105,142,228,112, 75,124, 39, 76,149,208,249,208, 87, 46,209, 82,107,105,219,189,131,163,202, 65, 34,176, 20,171, - 17,140, 89, 31,149, 1,136, 70,188, 20,207,143, 31, 55, 94,202,230, 47, 33,237, 58, 76,149,210,173, 22, 96, 7,225,102, 93, 64, -203,221,243,164, 76,155,187, 76, 42,124, 91, 17,157, 56,139,116,248,185,143,172,219,126, 88,214,108, 59, 40,171,183, 30,248, 75, -228,155, 41,189,252,218,179, 6,164, 94,239, 5, 34,222, 0, 83,151, 46,118, 13,242, 18,166, 45,112, 96,233,166, 35, 50,109,197, -100,249,161,107, 65,169,209, 46,183,252, 54,125,149,244,157,186, 71,218, 15, 95, 35,223,183,106, 18, 12,180,234,247,156, 44,109, -127,157,239,188,234,208, 66,162,245,118,223,216, 80, 64,107, 69,255,202,186,129, 22, 91, 2, 64,162, 53,236,176, 60,161,246,240, -196,170,121, 1, 19,207,121,141,247,116,246, 73,205,108,160, 85,179, 73,147, 38,123,104, 12,143, 93,101,164, 93,201,209, 67, 42, -208,122,180,100, 73,237,100, 73,147, 66,136,229,171, 72,178, 48,144,155,119,238,220,105, 94,190,108,153,121,209,194,133,230, 28, -217,178, 61,123,123,252,120, 21,223,235,215,235, 59, 3,180, 44,119, 24, 70,160, 68, 75,169, 18, 38,204,245, 87,174,223, 62,116, -212,235,194,194,211,231,175,207,187,116,245,198, 86, 94,211,100,146, 69, 6,170, 1, 57,129,254,241,199, 31,202, 4,222,171,115, - 71,233,219,166,181,244,111,218, 80, 86,143, 28, 34, 91, 70, 14,150, 61, 35, 7,202,129,225,253,229,232,168,129,178, 99,220, 72, - 93,170,195,179,155,214, 5, 3, 45,213, 38,139, 82,172, 97, 69,114, 40, 32,107,114,205,111, 21,144,197, 65,156, 64, 75,143, 49, - 60,212,161, 59, 96, 8,172,216,189, 96, 49, 34,216,245,233, 15, 99, 99, 63,128, 37, 5,116,208,158,136, 0,129,191,168,162,150, - 68,139, 92, 80,252,104, 17, 72, 65,194, 19,128,201,210, 12,213,153, 25,147,173, 25,125,211, 12,155, 47, 51,248,105,105, 43,153, - 20,252,226,142,206, 73,182,120, 76, 91, 44,170, 9, 41,193, 34,184,218,190,105,158,242,109,111,223, 52, 87, 1, 91,188,206,251, -179,199,228, 73, 51,184, 91,194,132,187, 55,212,253,189,111,187, 68,154,155, 84,248, 46, 76,116,143, 8, 4, 8, 34,251,247,239, - 31, 10,100, 81,146,193,196, 67, 11,104, 81, 93, 72,190, 91, 30, 4, 66,148,104,210, 54, 15,128, 32, 4,208, 34,128,161, 90, 54, - 8, 28,216, 83,117, 89,179,100, 50, 1, 11,233, 82,170,195,178,207,156, 57,147,237, 98,147,119, 90,125, 22,109, 52,142,253,147, -192,141,180,168, 54, 36, 56,162,203, 4,238, 66, 99,191,160, 29,213,175,191,254,202,119, 56, 92, 92, 97, 33,118,143, 32,139,234, -114, 74,107,168, 46,103,191,161,212,141,246,111, 4,181,160,225,166, 85, 38,245, 62,108, 4,207,147,198,178,101,203,248,238,249, - 72,180,121,107, 72,105, 11, 15,238, 54,164, 17, 63,119,241,242,160, 90, 17,247, 9,178,152,207,222, 49, 29, 96,200, 29, 18, 96, -197, 32,158,139,179, 81,163, 70, 29, 7, 80,242,129,164,233, 3,250,160,191, 10,178,248, 75, 21, 42, 15, 72,103, 63,128, 96,127, - 71,101,135, 16, 97, 7,198, 57, 47,148,215, 11,125,129, 64,171, 23,121,171, 30,228, 49, 0, 23, 65,241,124, 2,111,218,155,225, -125,122, 54, 2,232,101,153,102,190, 28, 89, 18, 3,104, 29,148,179,199, 86,201,173,203,158,178,106,217,108,233,211,187,151, 96, - 76,151,129, 3, 7, 66,106,221, 83,150, 47,158, 41,183,175,236,151,131,123,150, 73,175, 46,181,101,212,208, 46,194,231,236, 17, -231,189, 71,183, 15,200,201,195,203, 20,154,147,199,253, 34, 5,243,102, 12, 6, 92,189, 59, 87,149,229,243,135,200,141, 11,123, -196, 99,227, 76,233,222,169,230, 95, 52, 13,160,165,217, 94,200,160,207,143,150, 37, 37,170, 10, 41, 82,231, 74,156, 98,111,174, -114,232, 71,134, 91,221, 83, 39,135, 1,111,175,241, 82,189,253,100,201, 84,161,231, 71,151,124,245, 40, 65,176,121,168,187, 14, - 67,140,104,118,254,100,202,148, 78, 70, 15,109, 13,219,149,151,146, 56, 73,146,243, 86,238, 29, 66,208,167, 49,124,179,206,195, -205,158, 39,206, 75,245,182,185,164, 74,243, 28,210,115,210, 14,105, 63,106,155, 52, 25,184, 81,170,247, 88, 42,165,170,167,134, -100, 43, 51, 36, 94,219,164,116,237, 46, 1,206, 24,195,251,238, 28, 20,172, 54,164,250,240,205,150,158, 33,128,214,172,214,217, -100,121,191,138, 78, 1, 45,128,199, 56,133, 10, 21,218, 76, 0,212,177, 99,199, 67, 76, 60,231, 53,222,211,211,146, 86,121, 66, -120,131,199,224, 89, 16, 43,178,113, 16,125, 43, 59, 14,209, 86, 52,190,255, 3,171,104,135,170, 30, 85,117,232,123,248,112,189, -172,153, 50, 93, 93,185, 98, 69, 0,128,181,249,192,129, 3,102,216, 64,152,231, 97,139, 63,236, 51, 2,242,230,204,121,202,239, -234,213,239, 78,172, 88,209,208, 73,213,161,230,174, 67,103,141,225, 85, 62,228,112, 75,119,161, 65,221,202,239,107,124, 95,198, -183,108,169,188, 47, 43,124, 83,232,109,246, 44,105,245, 78,132, 10, 25, 26,182,195,142,230, 61,193,214,207,237,219, 74,167, 6, -245,164, 77,229, 10,138, 36,107,207,196, 49,178,111,204, 16,217, 55,180,191,220, 94,219, 79, 46,205, 25, 35,163,219,180, 52,235, - 49,134, 63,181,118,165, 2,180,186, 37,140,162,216, 99,169, 62,153,198, 86, 40, 42, 83,106, 87,146, 89,205,235, 42, 32,139,223, - 89, 16,208,226,228,230,232,136, 3, 67,106,197, 93, 8, 85,104, 4, 91,164, 73, 91, 29, 78,150,156, 52,105, 40,219,163, 71, 15, - 1, 32,163, 1,175,106,120,236,144, 40,118, 92, 30, 1,120,122,128,201,231, 5,128,132, 25,188, 80,252,103, 97,226, 81,118, 29, -210,222,137, 96,139, 9,170,110,111, 72,253, 2, 48, 57, 81,221, 18,234,160,225, 59,109,178,168, 46,164, 36,203,242,224,127, 94, -231,125,230,235, 90, 51,113,155, 35,187,134,248,116,194,175,158,190, 79,160,197,250,209, 25,235,128, 1, 3, 66, 0, 45, 75,144, -165, 3,104, 69,166, 77,150,101,217, 40,121,161, 52,147,128,138, 42, 25,212, 79, 89, 88,210,205, 7, 37, 8, 4, 8,144, 58, 19, - 28,144,175, 5,116,148, 55, 54, 36, 77,175,233,118, 34,200,133,193,125,248, 33, 83,192, 16, 54, 43,208,107,191, 45, 31,124,142, -200,198,133,100, 37,128, 0,128, 18, 34,152, 6,208,240,121, 38, 36,144,159,248,159, 32,137,253, 23,101,164, 45, 17,253,124, 57, -108,123, 26,132,179,191,208,208,157,207,210, 6,139,106, 40,250, 96, 3,159,105,180,174, 21, 93, 33, 68, 89, 81, 14,101, 23, 28, -141,252,113, 67,117, 98, 28, 29, 18,211,251, 4,129, 4,117, 60,168,158,164,196, 11,215,105, 91,229, 8,100,145,126,102,164, 49, -176,109, 83,220, 56,160,111, 30,231,238, 90,182, 9, 15,190,143, 7, 65, 22,242,173, 70,154,129,254,249, 2,191,189,181,218,135, -126,178,104,244,142,118,222,134,111,121, 26, 65, 22,203,216,173, 91, 55,101, 23, 39, 54, 41, 8,118,217, 10,190, 3,229, 58, 36, -156, 4, 93, 53,180,232, 70,228,125,130,162, 7, 55,247,201,225,109,191,202,169,125, 19,228,198,197,109, 0, 64,187,100,218,228, -209, 74,186,114,110, 39, 0,211, 90, 25,212,175,169, 52,170, 83, 88,154, 53, 40, 33, 35, 6,119,212, 4, 90, 42,205,147,123,199, -201,165, 83, 27,228, 58,104, 14,232,221, 70,250,116,107, 46,215,206,109,151,163,251, 86,200,111,189, 27,135,164,249,153,129, 86, - 68,242,237,111,164, 21, 54,160,165,238,106,161,141, 1, 7, 32,126,132, 68,210,137, 18, 39,251,228,146,183,214,135, 20,249,234, -223, 74,158,183,222,162,100, 57,235, 89,250,124, 10, 81, 79,171, 16, 60,254,208,219, 67,162,149, 73, 50,100, 72, 43, 25,131, 83, - 58,172, 32,211, 73,214, 44,233,100,209,220,145,114,254,220,217,192, 88,177, 99, 79,113, 4,180,232,222, 33, 94,170, 60, 79,255, - 92,177, 79,254, 88,185, 86, 42, 54,204, 33, 63, 14, 89, 45, 13,127,217, 32,213,122,172,146,111, 58, 44,149,234, 45, 43,200,176, -137, 61,165,215,152,197, 18, 47,117,110, 31,157,238, 29,174, 76, 25,240,163,188,125,120, 73, 2,174,239,148,215, 27, 58, 40,128, -235,213,202,102, 10,208,154,213, 42,171,172,197,110,195, 57,189,191,147,218,133,146, 19,104, 93,113,166, 97, 49,105, 53,196,234, - 86,113,229,192,196,115, 94,115,134, 70, 80, 94,213, 27, 60,253, 84, 29,135,100, 99, 61,141,223, 97, 7,161,216,101,209,230, 11, -171,242,233,160,173, 57,160,211, 24,126,251,164, 73,173,205, 47, 94,180,155,211,173, 91, 27, 74,181,254,152, 49, 35,128,234, 66, - 74,178,126,238,218, 53, 32, 81,194,132,111,151,143, 25,211,236,227,195,135, 53,166, 53,108,216,172, 81,212,168,165,180,202,252, - 57,141,225,249,110,168,208,202,181,111,219, 20,219,208, 95,200,211, 39,119,101,211,186,233,178, 96,206, 32, 41, 94, 36,151,240, -158, 86,249, 44,238, 71,162,203,134,165,152, 76,167, 66, 12, 79,144,213,137, 54, 89,223,148, 82, 64,214,129, 17,253,228,238,134, -190,114,111,211, 8,217, 53,108,128,196,211,233,222,129, 64, 72,149,100, 13,204,153, 94, 70, 20,207, 37,191, 87, 44, 30, 44,197, - 34,200, 90,209,183, 43, 54, 88,252, 34, 23,118,121, 80,162,165, 5,180, 76,176,113, 57, 70,176, 65,160,213,169, 83, 39,197, 39, - 17, 37, 5,104,255,119,176,183,185,134, 58,209,168,151,146, 44,173, 73, 44,184,250, 4, 80,232, 51,102, 53,209, 8, 30,147,155, - 2,180, 32, 61, 50, 99, 69,111,198,124,166, 36,140, 5,102, 72,125,204,246,128, 22, 37, 85,182, 37, 90,243,130, 37, 90, 99, 6, -228, 24,217,171, 97,178,190,181, 43, 20,255, 72, 63, 91,252,237, 82, 51, 81,251, 81, 29, 18, 36,114,212,102, 4, 90, 84,115,169, -134,239, 28,159,200, 67,218, 43,169,146, 44, 21, 60,233,145,104,169,182, 89,170,253,212,156, 57,115,148, 73,155,187, 3,193, 19, -115,211,166, 77, 21, 9, 17, 39, 92,148,139, 0,235, 91, 39,250, 84, 91,142,149,148,144,225, 27,167,132, 37, 31, 38,239, 15,180, -175, 97,187,225, 63,141,194,157, 57, 82,208, 30,139, 59, 1, 97,152,205,231,115, 6, 61,156, 31,125,226, 8,140,206,159,227,151, - 62,181,242,233, 36,154, 10, 82,171,131, 0,215, 15,104,131, 71,160, 78,159,100, 4,133, 84,173,233,164, 17,156, 13,192,245,130, - 42,101, 3,112,161, 95, 43,122,208,223,132,197,164, 98,188,143,254,169, 0, 24,140, 9, 4,153, 92,120,233, 13,155,196,119,176, - 78, 99, 40,201, 34,200,162,107, 3, 72,180, 20, 21, 41,193, 22, 36,125, 84, 19,234,178, 27,180, 85, 47, 44,116, 21,167,111, 48, -128, 39,152,154,200, 93,173,234,193, 5, 16, 36,101,188,222,220, 89,158,132, 55, 63,128,214,253, 91,151,119,200,197,227,243,229, -232,246,193, 10,224, 58,123,104, 58,192,214,118,184, 68,217, 36, 99,135,182,151,198,117,139, 72,211,122,197, 32,121,170, 43, 67, -127,251, 73,154, 53,172, 64,160,181,203,222,187,255,162,185, 83, 46, 28,155, 43, 71,182, 15, 82,104,158, 57, 56, 85,174,159,223, - 42,103,142,109,144, 81,131,219, 42, 0,139, 52,123,116,254, 63,205,156, 89, 18,127, 81,251,180,240,242,238,171,121,158, 70,240, - 16,123,127,160,237, 10, 59, 30,108,137,148,196,157, 39,188,167, 81,145,255,239,206,176, 8,169,131,129,224,241,235, 87, 47,229, -246,205,203,178,110,213, 44, 72,175, 58, 73,187,230,229,164,101,195,162,210,186,113,113,105,219,172,164, 28,216,235, 78,195,190, -247,216,175,222, 64,143,195,210, 52, 57, 74,250,141,159,191, 83,102,175,221, 39,157,134, 79,151, 31,250,174,147,239,187,175,146, -198,191,109,132, 1,252,118,233, 54,114,177,184,100, 41,246, 86,175,195,210,114,248, 96, 17,106,167,125,238, 52,209, 31, 47, 26, -211, 69,222,220, 56, 36,239,142,205,148,215,235,218,202,230,223, 91,200,150,169,221,164, 99,181,220,146,195, 37,210, 99,230, 99, -126, 43, 94, 56,220,153,130,157, 94,233,172,188,192, 7,242,154,110,126,254,149, 49,132,199,121, 75, 71,168,148, 98, 97, 64,222, -141, 1,173, 15,192, 70,176,241,177, 13,250,193,229, 84,221, 59,188,186,127,191,237, 59,216, 95,205,233,215,175, 85,214,204,153, -175, 65,125,236,151, 48, 65, 2, 63,183, 76,153,174,204, 25, 51,166,197,199, 59,119,190, 63,189, 98, 69,189, 70, 49, 98,180,111, -105,123, 71, 91,136,186, 71, 16,208,114,200, 79, 55,215,116, 50,117,194,175, 50,126,116, 47,233,217,249, 7, 37,185,102, 74, 99, -111,187,184,202, 6, 91, 52,211,103, 76,151,238,209,220,137, 19,100,241,239,163,101,120,227,250, 50,176,114, 57,217, 63,252, 55, - 57, 58,226, 87,185, 56,115,148,236, 25, 50, 64, 10,186,102,166, 88,222,214,150,231, 80, 14, 75, 9,180, 84, 73,214,200, 18,185, -101, 92,165, 18, 50,181,110,149, 96, 41, 22, 39,250,141, 35,127, 19,143, 41, 99,229,202, 1, 79,218,218, 88, 3, 45, 91,229, 76, - 11,199,166,207,169,202,167,202, 40,200, 91,189,163, 48, 83,214, 77, 31,138,102,144, 68,235, 33,192,197, 27, 2, 44, 26,196,195, -152, 94, 1, 90, 80, 79, 41,255, 41,217, 98,130,218, 66,249,181, 2, 90,161,104,210, 22,139, 54, 89, 33,108,180,178,254,101,163, -181,107, 99,157,113,148,100, 89, 58, 53,229,127, 94,183, 40,108, 40,154, 0,146,143,200, 51,218,121,170, 32,139, 18, 18,168,201, - 67,201,200,237, 0,173, 96,154, 40,255, 36, 72, 72,240,120,128, 34,209,161,218,152,246, 46, 84,105, 97,247, 47,213, 82, 19, 81, -150,202, 72,147,144, 28, 1, 44,155,253, 19,207,159,165,244,138,210, 48, 60,191, 60,168, 94,203,169, 58,164,125, 13,120,238,200, -198,207, 22,205, 20,116, 7, 65,219, 44,130,107,142, 1, 78, 78, 38,118,191, 35, 0, 24, 69,141, 72, 59, 45,170,250, 48, 78,191, -210, 73,219,146,102, 43, 2, 42,214,153,161,139, 8,132, 40,117,228,127, 94, 7, 61,189, 27, 93,236,150, 19,118, 94, 74, 8, 17, -210, 6,189,145,252,229,129,235,118,253,186, 5,213,195,225, 24, 2, 0,248,150,128, 10,243, 26,129, 42,143,101, 0, 95, 10,192, -166, 90, 30,255,107, 57, 26, 63,117,242, 74, 79,182, 16,229,132, 49,124,243,242,165,178,189, 91,190, 96, 24,192,213, 38, 5,100, - 29,241,248, 77, 1, 71, 4, 67,141,235, 22,149,110, 29,106, 41,170,189,246,173,106, 72,225,252,105,253,105, 64,159, 47, 67, 8, - 91, 95,251, 52,207,111,148,179, 7,167,201, 97,187, 52,171,147,230,187,156, 89, 18, 13,119,117, 77,108, 57,198,124,241,221,151, -122,152,247, 55,230,113,206, 51,188, 85, 65,147, 81,125,136,143,230, 35,237, 61,152,224, 61,250, 3, 62, 66, 78, 52,201, 52, 42, -101, 19,104, 37, 74,156,120, 27, 68,214, 1, 24,204,253,182,109,219,250,225,225,131,251,208,125,155,229,217,211, 71, 0, 88,155, -101,214,180,193,144, 76, 60,160,142,253,189,201,197, 37,163, 22,208, 98, 25,212, 16, 60,223, 53,233, 19,208,115,244,114, 25, 57, -103,143, 12,254, 99,135,180, 30, 48, 87, 74,213,234, 28, 16, 63,117, 30,167, 67,240,144,110, 30, 23, 83, 28, 0,169,129, 69, 51, -197,243, 93, 55,169,187,248,156, 92, 45, 35, 58,124, 39,249,211,196,240,229,117,222,183,195, 3,173, 78, 24,194, 91,124,144, 55, -116,173, 65,211,154,102, 40,160, 5,145,250,161, 18, 37, 74,208, 19,252,207, 54,130, 61,219, 42,106, 8,154,116, 88,218, 57, 67, -134,159,188,175, 92,105,245,241,197,139, 38,254, 23, 47,214,240, 63,121,178,138,255,133, 11,149, 1,176,170,126,244,246,174,113, -122,245,234,122, 45, 19, 37,250, 9, 65, 4,237, 25,243,218, 3, 90,225,217,117,104,151,159,193, 18,173, 55,240, 37,228,125, 71, - 54,174,157, 38,243,103, 15,212, 35,209,178, 71, 51,125, 28, 56, 46,109, 93,167,198,251,201, 61,126,150,229,191,246,149,211,115, -103,200,206, 81,131,229,247,214,205,205, 65,146, 44, 91, 32,139,252, 13, 5,180, 8, 10, 40,129, 97, 58,190,114,137,156, 88,179, - 92, 78,172, 91,169, 0, 45, 38,218,103,157,135, 36,235,194,222, 93,114,113,255,110,129,218,247,161, 85, 67,217, 43,231, 55,152, -108, 21, 67,102,180, 59, 87,219,246,118,130,105,182,187,101, 6, 0,254, 91,176,125, 50, 3, 12,152, 1, 56,148,144, 59,144,202, -132, 80, 29, 2,236, 60,133, 68,198, 90,117,104,179,156,246,118, 29,210, 54,139,234,194, 96,137, 86,249,226, 31,169, 70,180,178, -213,178, 9,180,200, 75, 75,144,165,170,164,172,145,150, 22,208, 66,189,149, 93,135,112,162, 25, 64,181, 25,221, 69, 80,181, 71, -144,133, 49,238, 38,239,235, 28,184,109,214, 29, 19,181, 47, 53, 1,244,155, 5, 58, 37,131,104,149,164,163, 81,238,140, 3, 56, -160, 99, 89,123,238, 55,108, 2, 45, 74,178, 40, 33,163, 4, 19,207,106,141, 25,214,197,183,251, 29, 65,178,181, 7,128, 58,144, -110, 65, 32,189,249, 0,233,148, 35, 7,170,150,116,173,105,206, 98,172, 77,186,199, 32,192, 34, 79,185,131, 15, 15,232, 5, 89, -161,190, 35,203,151, 65, 82,182,215, 82,162, 69,201, 22,255,243,186,238,249,200, 70, 70,180,213, 83,170,120, 1,100, 63, 64, 37, -123,142, 27, 33, 14, 30, 60,200,255,252,182,190, 11,227, 56,175,179,251,132,200, 22,170,141,242,100,118, 73,158,221, 53,209,180, - 26, 85, 10,126,220,184,114,172, 92, 61,179, 74, 78,238, 29, 47, 93,218, 87,151,177, 35,186, 73,175,174, 77,164, 76,241,204, 31, -177, 43,112,150,155, 91, 18,203,184,179, 42, 97,167,104,142, 25, 14,159,129, 93, 26, 73,169,162,153, 62,230,204,146,100, 70,206, - 12,201,108,245, 51,173, 57, 46, 44,117,255, 55, 60,227,188,234, 48,168,214, 33,220, 59, 4, 73,178,180, 64, 86,200,143,197, 58, - 72,116,189,122,177, 76,177, 98, 21, 55, 69,141,218, 3,192,107, 43, 62,106, 31,172, 28, 2,176, 35,229,253,197,139,231,177, 67, -231,158,224,218,171,224,224,210,255,103,191,221,198, 85,131, 74,211, 64, 30, 46, 28,222, 48, 69, 84, 80,233,204, 46,166,228, 89, -147,153,166,103, 79, 30,233, 29,127,249, 63, 60, 31,117,208,179,122, 3, 77,219,253, 88, 56,120, 49,198, 33,129, 26, 6,154, 5, -216,254, 75, 95, 30,206,248,208, 9,197, 79, 53, 4,207,170,126,253, 90,222,242,244,108,138,221,133,141, 95,221,184,209,224, 20, -108,178,168, 46,108, 28, 51,102,187,122, 38,147,171,131,250,219, 4, 90,225,220,117,232,240,163,118,205,156,198,163, 74,197, 98, -210,185,125, 93, 37,241,156,215,194,209, 70,193, 65,165,227, 98,103, 33, 19,141,229,157, 13, 42,141,201,235, 4, 93, 60, 56,147, - 0,144,173, 35, 33, 56,170,123, 99,216,250,220,131,218,132,146, 23,103, 14, 71, 52,179, 66,210,114, 67,181,199, 82,127, 41,241, -178,120,129, 45, 99,120,187, 52,169, 70,180,246,163,165,210,234, 82, 59,113, 43, 74,178,248,107,163, 2,161,104,194,142,209, 19, -233, 17, 19,248,234, 48,129,151,182,182,163, 91,211, 36,216,154,132,228,141,186,210,143, 22,127,201, 79,189, 32,203, 46, 48, 64, -187,140,134,153, 4, 29,219,206,181,170,219, 56, 72, 36,223, 99, 87,224,239,122,191,163,160,124, 9,176,225,225, 19,165,152, 12, -229,131,107,137,157,105,116,228,117,212,238, 41, 49,182,111,197,194,250, 46,120, 65, 63, 89,122,129,187, 53, 77,170, 3, 27, 97, - 1,116, 10, 82, 34, 63,252, 30,194,255, 90, 17, 88,206,106, 0,174,129,170,141, 22,127,249, 31,244,171,133,227,123,231,163,191, - 16, 16, 18, 28, 50, 17, 40, 6,129, 44, 71,234,194,207, 1, 54,236,210,204,153, 57,153, 43, 12,210, 87, 54,249,161,116,224,246, - 13, 19,101,208,128,159,164, 82,185,220,146, 61, 75,226,181, 89,179, 38,117,100, 79,167,155,230,192, 1,237,165, 98,217, 92,129, -112, 15,177,130,239,115,178,127, 58,217,204,255,186,236, 97, 6, 89,225,225,196,255, 27,215, 26,104,217,250,159, 42, 85, 58,168, - 10,235,195, 46,107, 42,192,215,197, 36,201,146, 77,117, 6,104,133,163,160,186, 63, 22, 39, 66, 18,232,165, 25,194,144, 61,140, - 3,133, 51, 52,172, 95, 97,179,156,246,130, 74,211, 38,139,247,156, 41, 39, 6,218,182, 84, 31,234, 77,204,175,103,194,181, 85, - 6,216, 55,113,242,209, 82, 25,170,143,234,109, 35,103,186,150, 65,211, 6,183,184, 11,145,134,239,180,221,178,190, 61,184, 75, -226,248,220,117,200,223,176,182,187, 51, 13,164, 1, 54,116,219,180, 89,189,211, 81,187,219,163,169,101,159,100,147, 38,188,149, -255,201, 16, 75, 0,111,179,156,172, 55,179,255, 91,250,103, 53, 74,176,168, 46, 12,146,100,105,129, 44,189,117, 31,128,133,203, - 3,236, 4,247,129, 52,148,182,142, 13,156, 25,235,194,208, 30,182, 30,209,108, 35,184,103, 40,156, 35, 75,146, 77, 65,169,168, -142,247,234,167,233,154,104,125,182,204, 73,237,186, 84,178,120,151, 38, 77, 29,229,250, 55,101, 9,151,234, 48, 60,140,248, 28, - 13, 97,208, 12, 79,139,132,126,214,224,167,193,207,136,226,128,209,151, 34,138,147,127,209,113,196, 79,205,205, 45,118,138, 98, -180,209,151,107,163,176,190,233,191,220, 70, 97,229,217,127,250,185,255,114,135, 49,234, 30,177, 93,223,224,167,193,207,136,226, -128,209,151, 34,138,147,218,128, 48,172,111, 50,218, 40,172,156,179,253,220,215,194,207,136,173,245,151,167,102, 41,213, 10,241, -118, 54,128,173,228, 76, 17,237,209,112,116, 93,139,190, 65,211,118,187,132,181,189, 12,126, 26,252,212,219, 7,140,111,211, 62, - 7,244,242,208, 50,159,193, 79,131,159,182, 56,240, 95,238, 75, 90,223,196,215,120,223,218, 62,235,139,217,107,125, 45, 40,218, - 40,103,196,118,107,131,159, 6, 63, 35,138, 3, 70, 95,138, 40, 78, 26,210, 39,163, 47,253,243,251, 82,196,150,240,203, 82, 51, -128,150, 6,191,141, 15, 48, 98, 59,100, 8,126, 78,169, 99, 74,195,164,247, 21,118,242, 27,109,164,151,129,250,242, 25,252,212, -199, 39,189,185, 12,126,234,229,148,190,124, 6, 63,245,241, 73,111,174,175,133,159,122,235,243, 79,205,103, 87,117,248, 57, 11, -172,167,113,233,243,227, 7, 36,198,164,170,133,164,181, 93, 89,139,102, 50,208,232,140,208, 14,251,153,120,142,196,107,142,142, - 96,154,240, 33, 68,255, 96,202,206,181,160,115,238, 12, 82, 19,119, 15,209,117,130,101,226, 53, 91,187,135,130,105, 98, 23,139, - 55,118,220,209, 27,178, 86,122, 9,255, 87, 12,254, 60, 9,187, 94,170,219, 40,176,195,186,195,239, 88,203,138, 21, 43, 62,100, -226,185,206,134,213,226,167, 61, 50,197,210,165, 78,121, 57, 69,114,132, 72, 10,189,117, 59,152,230,244,234,166, 81, 51,106,152, - 62, 50,241, 92,171, 76, 14,242, 59, 91,206,194,216,157,181, 16,238, 46, 24,162,100, 43, 18, 3, 45, 91, 31,161,104,194,127, 78, -115,180,215, 14,248,178,186,197, 95,254,215, 42,179,213,125,103,203,169,135,188, 65, 83, 15,151,244,231, 49,248,169,159, 87,122, -114, 26,252,212,195, 37,253,121,254,203,252,212,207,165,127,107,206,236, 73, 77, 41,225,164,179, 7,194,205,120,240,151,255, 53, -234, 26,162,195,124,159,221,244,161, 82, 22,147, 48, 85,203,106,250, 8, 31, 51, 51,224,167,196, 29, 65,171,221,225,180,209, 29, -129,139,221, 27, 53,106,180, 9,215,135,130,110, 57, 36, 91,110, 4,108,117, 66,250,123,105,138,180, 13, 14, 28, 63,210,199, 12, -131, 96, 51,254, 27,163,218, 99, 43, 52,227,126,109, 11,202, 99,203, 55,140, 37,205, 96,159,135,200, 47,245,234,213, 59,142,116, - 66, 77, 8, 83,113, 2,161, 62,188,240, 59, 5,191, 13,112, 93,241,230,142, 56, 19,197, 38,101,138,110, 25,116, 55,152, 38, 1, -214,177, 37, 11,228,228,154, 21,114,104,222,204, 16, 62, 21,183,255,214, 75,118,252,210, 77,118,255,242,243,115,220,216,141, 52, - 1,113,204,154, 35,106,188, 26, 90,195,146,197, 14, 63, 64, 2, 44,214,155,129, 79,225,191,230,161,206,126, 24,150,143, 58,102, -241,194,249,223, 61,187,123, 89,110,157,130, 39,243,116, 46,111,241, 46,130,101,245, 80,104, 78,255,206,148,130, 0, 75, 46, 44, - 21,166,233, 53, 76,159, 38, 86, 14,238, 51,229,145,133,126,174,152,120,174,228, 7,208, 10, 84,243, 43,224, 12,215,130,136, 58, - 83,206,142,112, 54,136, 40, 65, 74, 68, 13,185,127,255,190,192, 55,208, 45,208,177,222,169, 21,130, 38, 66, 21,173,104,209,230, -231, 19,155,118, 28,189,116,244,244,181, 91,107,183, 28, 58, 86,175, 73,171, 67,188,174,147,151,204,230, 76, 57,245,146, 53,104, -234,229,148,190,124, 6, 63,245,241, 73,111, 46,131,159,122, 57,165, 47,223,127,153,159,250, 56,244,207,204, 21,118,247, 14, 5, - 83,153, 98,103, 77,106,106,146,211, 37,210,246,246,213,114,127,218,247, 71, 39,121,190,127,178,236,155,222, 78,186,215,201,243, -137,215,121,159,249,108,212, 61, 68,135, 33,192, 82, 39,209, 14, 69, 76,114,226,196, 9, 70,155,117,183, 78, 8, 96,237,142,176, - 63,238,136,154,190, 22, 52,173,253,163, 88,119,194,206,116,252,135,216,126,138,231,109,123, 7,131,176, 34,164, 15, 98, 43,102, -240, 7, 77, 74,185, 44, 15,187, 64,235,220,185,115, 98, 35,109, 61,127,254,124, 23, 0,186, 44, 36,146, 13,209,237, 39,125, 95, -242,141,121, 84, 43, 58,205, 83,143, 16, 64,235,228,234,229,210, 53,174, 73, 73,150,199, 31, 37,114,200,146,170,197,158,173,111, - 80,105, 39,174,143, 67,106, 10, 96,144,155, 68,114,152, 76,249, 91, 39,142,124,198, 22, 77, 91,253,140, 64,139,180,233,192,175, -110,221,186, 47,225,208,240, 17,156,192,106, 25,228,133,229,163, 46,183,125,213,236,143, 87,247, 46,151,189, 51,186,200,204, 94, - 63, 72,172, 24,209, 46, 91,151,211, 26,104,205,168, 25, 89, 82,198, 53, 77, 14,202,231,201, 32,200, 76,248,239,201,107,174,137, - 77,173,167,215,136, 20,220, 71,194, 0,180,162,195,167,206,236,133, 11, 23, 42, 44,102,176, 92,122,165, 38,240, 70,152, 21,129, -115, 72,245,221,161,218,136,146, 43,130,172, 87,175,222,188,191,119,243,222,203, 95,122,252,190,125,198,130,205, 59,247, 28,185, -120,172,102,189,198,251,156,144,108,133,133,159, 90,195,134, 65, 83,139, 67,206,221, 55,248,233, 28,191,180,114, 27,252,212,226, -144,115,247,255,203,252,116,142, 83,255,134,220,144, 92, 45,104, 87, 37,235,251,189,211,218,200, 75,128, 43,191,227,179, 67,165, - 39,187,199,203,166, 81,141,164, 89,185, 12,239,153,223, 1,128, 49, 89, 3,173,139, 23, 47, 42, 64,107,120, 77,151,119,253,202, -152,132,137,231, 8,148,235, 14, 96,228, 14,207,188,140,236,190,222, 17, 77,220,123, 68, 41,142,158,131,129, 71, 25,204,149,207, -216,163,105,169, 58, 68,236,175,143, 8,109,114, 28, 94,135,143,213,170, 85,139,233,104,205,154, 53, 39,224,127, 61,252,166, 37, - 13,232,163, 92,122, 23,202,238,109, 94, 49,233, 83, 64,221, 12,150,142, 50, 67, 0,173,131,115,254,180, 9,180, 22, 85, 46,242, -100, 93,189,111,183,111,107, 85,115, 44,234,208,152, 33,187,130,232,166,109,157, 61,211,211,128, 89,191, 17, 24,134, 2, 6,214, -253, 11,129,106,179,245,238,221,251, 5,121, 1,190,202,211,167, 79,149,208, 46,240, 34, 29, 66,178, 5,226,121, 7,165,142, 50, - 93, 15, 77, 27,125, 56, 81,153, 18,133, 95, 77, 29, 61, 72, 94,220,191, 42, 71, 22,254, 42,107,135,181,144, 49,173, 43, 75,140, -104, 81,238,218,162, 73, 85, 32,165, 84, 4, 89, 71, 22,246, 19,132, 93, 34,143,218, 32, 29,244,245,245, 69, 32,104, 95, 53, 80, -111,106,196, 19,123,177,115,122,103, 97, 94, 62, 99,165,106,212, 26,124, 92,224,205,250, 8, 14, 97, 56, 22,122,118,102,104, 14, -120,249,246, 71,172,190,192,203,151, 47, 75,159, 62,125, 8,132, 45,131, 96, 7,211,164,154,112,253,182, 35,231,238,223,190,255, -226,250,197, 27,143, 39,140,154,179,109,194,180,213,235, 86,110, 57,188,105,249, 6,207,213,188,111,235,155, 14, 39, 63,245, 14, - 19, 90,117,215, 75,199, 50,159, 65, 51, 44, 92,179,255,140,193, 79,131,159, 17,197,129,255,114, 95,178,203, 67,204,141, 69,144, -170,241,151,153, 44,255, 91,156, 43,247,173,254, 23,197,255, 98, 65,207,242, 62, 19,175,169,244,170,226, 92,203,100, 73, 79,219, - 58, 22,106,184,187,187, 43, 0, 65,253, 85, 41, 2, 56, 41,248,229,131,207,117,241,191,178,213, 38,208,122,119,126,141, 60, 58, -182, 82,142, 46, 29, 40,204,239,168, 52, 84, 29, 54,201,103, 18, 74,179,126,254, 38,209,251, 99,199,142,237, 34,168, 34,192, 82, - 37, 93,221, 75,152, 24, 3,108,219,168, 81,163,220, 23, 45, 90, 68,160,197,228,232,240,126,115,252,144, 28,117, 9, 41, 41,178, - 4, 94,156,100, 17,218, 71, 16,191, 77,230,206,157,203, 50,210, 14,203,238,129, 24, 98,158,148, 98, 33, 94,215, 41,100,178,235, - 24, 16,147,108,220,166, 25, 83, 94,242, 95, 49,201, 28,208, 60,175,188, 40, 27,203,102,253,169, 58,180, 60, 70,103, 77, 41,211, -138,102,149, 5,149, 10, 61,198,245,109, 72,163,145, 26, 34, 49,210,189, 9, 46,121, 19,212, 74,149,244,218,251,149,147,223, 5, -180, 43,174,233,229,156, 32, 11,193,127,159, 51, 48,238,173, 91,183,132, 1,107,119,236,216,161, 4,134, 45, 93,186,116, 48,208, - 66,121, 83,180,202,158,193, 59, 96,206, 16, 75,240,166,167, 3, 41,121,162, 69,137, 50,237,248,142,213,114,109,255, 42, 57,182, -124,148, 44,249,181,177,116,169, 85,204,156, 32,118,204,247,184, 93,193, 30,161, 78,165, 76,110,217, 51, 38,191,194,192,228, 12, -218,250,227,143, 63, 42,113,218, 24,239, 13, 82, 56,129,228,146,170, 78,217,189,123,183, 80,221, 87,177, 76,161,183,213,115,154, - 10,235, 46, 24, 66, 82, 66, 82,249,152,117, 39,253, 93,187,118, 41, 32,139,191, 0, 89,228,223, 2,132,214,120,199, 0,204,120, - 47,213,187,161,108,234,240,252,197,115, 87,238,221,155, 56,114,246,238,133,211,150,237, 94,187,122,199,238, 13, 30,199, 54,175, -247, 56,190,242,232,233, 27,235,121,223,186, 60,225,229,167, 19,245, 51,178, 26, 28, 48, 56, 96,112,224, 95,207, 1,123, 88,132, - 21, 39, 64,250,235, 71, 1, 74, 21,173,254, 43,247, 44,238, 7,255,199, 28,208, 95,205,107,153,135,215,249, 31,177,129,151,225, -190, 91, 4, 48,215,177,234, 80, 11,104,189, 63,189, 68, 62,189,123, 33,159,124,159,136,255,173,189,242,238,228, 2,121,119,117, -187,248, 92, 59, 44, 87,246, 46,147,117, 67,235,200,186, 33,117, 52,129, 86, 80, 69,118, 81,146, 5, 48,165, 36, 4, 71, 13, 5, -180,186,118,237,186, 13, 76,112,135, 10, 72, 23,208,122,125, 96,119, 8,160,117,186, 96,122,185,209,165,133, 80,186, 49,108,216, - 48,233,220,185,179,244,232,209, 67, 1, 90, 4, 33, 40,135, 67,160, 5, 59,175,125, 4, 90,205,155, 55, 39,208,178, 25,239,172, -156,201, 20,181, 74,146,120,123,222, 44, 24,237,111,238, 90, 65, 94, 1,100,157, 47, 18, 93, 23,208,154, 82, 40,139,204,175, 80, -224,225,170, 90,101,183,160,129, 71, 34,213, 71, 82,226, 84, 1,100, 69, 43, 27, 47,214,190,151,243, 70,250,154,251, 84,151, 87, -229,108,131, 55, 0,148,246, 72,143, 0, 82, 46,170, 32,235,230,205,155,138, 77, 26, 12,225,159, 80,146,133,244, 8,246,105, 10, -202, 46,142,122,124,151, 60,209,153,119,203, 39,190, 11,104, 91, 84, 19,188,217,234,116,201,242,212,174,146, 46,101, 82,217, 48, -186,149, 44, 25,208, 80,170,162, 30,200, 87, 21, 73, 79, 76,180, 52, 0,132, 79, 41,101,163,196,137,160,144, 1,149, 25, 24,248, -249,115, 4,131,126,242, 68, 1, 89, 67,134, 12, 33, 77, 91, 49,239,236,125, 7,169, 33,109,122, 66, 9, 30,233,109,222,188, 57, -132, 36,235,202,149, 43,210,190,125,251, 0, 60, 92, 29, 32,235, 42,226,245, 29,194,121, 84,107, 98,153, 51,103,222,112,234,194, -141,107, 43, 55,238,219,199, 47,249,205,179,211, 10, 54, 62,116,234,218,198,109,187,143, 46,231,125,203,103, 34,130,159, 17,240, - 97, 27, 36, 12, 14, 24, 28, 48, 56,240,175,225,128, 30,160,165,130, 41, 75,208,100, 13,176, 44, 65,152,101,126, 75,169,150,229, - 51,184,110, 43, 16,183,179,124,213,148,104,149, 99, 5,145,128, 31,254,127,168, 18,173,151,139,107,203,203,165, 63,136,223,161, - 73,242,241,197,109,145,192, 79,114,231,212, 78, 89, 63,188,158, 76,105,144, 66, 38,215, 75, 38,171,127,171,166, 23,104, 41, 54, - 89,150, 1,134, 7,126,151,248, 29, 37, 89, 76, 63,151,137,245, 94, 5, 90, 11, 22, 44,208, 5,180, 84,105, 17,165, 90,150,146, - 45, 70, 95,111,215,174,157, 2,180,122,246,236,169, 0,173,233,211,167,107, 2,173,239,191,255,126, 63,129, 86,211,166, 77, 25, -220, 55,166, 13,110, 71, 42, 28, 51,218,202,199, 83,250,251,153, 7, 53,146, 55, 0, 67, 23,139,198, 8, 28,145, 46,202, 38, 91, - 45, 99, 45,209,154, 91, 46,223,253,149, 53, 74,111,222,220,236,251,225, 40,123, 61, 36,197,214,139, 71,129,104,209,150,223,155, -208,251,245,135,145,173, 20,186,151,138,198, 32, 72, 8,117, 0,100,121,211,232,157, 7,213,133, 4, 89, 27, 54,108, 16,216,100, - 61,166,132,203,234,129,200, 69, 98,199,216,228,243,231, 96, 95,115,223,154, 10, 93,103,123, 16, 65, 86,155,159,135,126, 60,225, -229, 37,105, 92,146,200, 47, 13,203, 6,102, 77,153,216, 15,116,156, 9, 96,157, 15,101,187,208,182,109, 91,105,211,166,141, 76, -157, 58, 85,177,209,154, 48, 97,130, 52,107,214, 76,106,212,168, 17, 16, 35, 70,140, 49, 78,148, 45, 14,130,224,158,163, 45, 22, - 65,214,186,117,235,100,201,146, 37,138,100,204, 90,146, 5,126, 81,181,201, 29,162,161, 64, 22,223,135,248,138,223,245,236,243, -235,141, 91,247,158,220,220,117,248,252,206,205,219,247,157,184,112,245,238,174,235,119, 30,123,214,107,208,228, 12,238, 91,198, - 19,179,224,103,141, 48,241,211,137, 58, 26, 89, 13, 14, 24, 28, 48, 56,240,159,224, 0, 49,136, 45, 44,194,202, 59, 2, 79,127, -221, 86, 36, 93,193, 82, 47,245,154,229,175, 69,190,242,170, 68, 43, 72,226,165,108,200,250,236,135,181,218,144, 47, 12, 1,180, - 8,182,130, 82,192, 77, 79, 5, 92, 89,166, 85,191,126, 23,102,160, 69,208,117,240,224,193,109,152,124,183, 17,100,169, 64, 11, -106,190, 8, 7, 90, 52,138, 70,213, 28, 74,180,176, 19,242, 0,129, 86,147, 38, 77, 8,180,162, 89, 51, 63, 83,204,120,251, 78, -247,111,109,254, 48,177,171,188, 45, 31, 71, 46, 21,139,241,225,199, 68,145, 94, 65,149,100,105,255, 19,252, 24,129,214,186,159, -219,201,164,252, 25,101,118,153, 60,119,209, 25, 54, 33, 13, 69,170,139,148, 89,205,152, 49,102,252, 93,199,251,182, 8,248, 48, -173, 55,232,198,149,203,197, 98,188,239,154, 60,178,165, 61, 85, 48, 77, 72,178,188,169, 38,187,113,227,134,156, 61,123, 86, 49, -244,167, 36,203, 6,200, 50,177,188,231, 7,119, 8,248, 48,182,189,188,253, 38,182, 66, 87, 79,135, 74,150,183,118,169,212,249, -235,248,165, 41, 88, 79, 90,118,254, 77, 32,125,148,214,221, 71,124, 32,232,138, 23, 51,250,124,208,208,218,117,106,239, 53, 4, -175,223, 97,135,169, 60,126,252,152, 0,139,109, 66,209, 45, 37, 99, 76,220,117,202,128,185,142, 34,199, 71,142, 30, 61,250,166, -147, 39, 79, 42,234,194, 45, 91,182, 40, 32,139, 54, 89, 0,212,129,148,100,193, 30, 76, 83,146,101, 89, 64,184,116, 24,177,105, -203,206,203, 23,111, 60, 56,190,209,227,224,230,219, 15,158,238, 89,184,100,197, 33, 92,167, 77, 89,240, 17, 86,126,234,225,185, -145,199,224,128,193, 1,131, 3,255,101, 14,216,194, 34,228,135,181,170,208, 22,168,210, 2, 90, 22, 18,173,202, 54,128, 89,120, -217,110,173, 58, 76, 21,138,160, 51, 64,139,170, 67,107,160,181,114, 64, 21,221, 64,139,118, 89,150, 18, 45,158, 95,186,116,201, - 29, 0,203,157, 42, 67, 53,205,158, 61, 91, 23,208,242, 89,187, 52,132, 36, 75,149,108,217,146,104,141, 31, 63, 94, 19,104, 85, -175, 94,253, 32,129, 22,128,192, 20, 48, 42,132,196, 38,142, 75,182,198,155,218,214,253,244, 97,206, 32,121, 87, 49,161, 92, 46, - 26,227, 93,189,248,145,158,219, 3, 89,100, 52,129,214,250, 78, 63,202,204,210, 57,111, 47,253,190,196, 6, 52,240, 96,164,218, - 72, 25,213,134,136,155, 34,235, 15,107, 91,213,250,244, 97,193,112,121, 95, 37,177, 92, 41, 26,227, 77,205,184,145,124, 64,215, - 38,210,134, 77, 83,123, 72,175, 30,193,189,196, 75,130,149,173, 91,183,210,240,253,158,117,195,178,188,238, 63,213,255,244, 97, -230, 47,242,238,219,248,148,144,189,109,159,196, 54,120,179,124,150, 32, 43, 71,217,230,111,247, 31, 58, 42, 4, 51, 0,194,210, -180,227, 32, 33,200, 10,111,111,196,243,157,193,227, 15,215,175, 95,151,123,247,238, 41,234,206,236,217,179,223,198,245,110, 0, - 53, 15, 40,117,164,116, 10,126,176, 22, 56,120,215,239, 80, 61, 11,250,146,236,217,179, 71, 1, 89,252,165,212, 18,207, 44,232, -216,177,163, 98,147,165, 37,201,178,164, 15,169, 85,172,239,191,205, 18, 48,228,183, 86, 31,154, 52, 40,241,126,202,132, 1, 1, -181,170,230,218, 1,240, 26, 12,182, 21,126,118,104,224, 52, 63, 35,128,103, 6, 9,131, 3, 6, 7, 12, 14,252,235, 57,160, 7, -104,217, 2, 94,196, 98,127,225,177,255, 75,182,248,223,158,141,150,154, 63,232,254,183,159,129,177, 90, 59,254,255,122,165, 61, -137,214,219,125, 99, 67, 1,173, 21,253, 43,107, 2, 45, 26,195,183,135, 33, 60,141,223,169, 46,180, 4, 91,214, 64,107,248,240, -225,238, 48, 96,215, 5,180,158, 46,157,227, 16,104,117,233,210, 37, 88,117, 56,102,204, 24, 77,160,133, 29,133,135, 1,180,182, -210, 79, 22,216, 16,108, 56,157, 48, 69,182,114,163, 38,252,241,244,229,189, 59,114,191,114, 42, 57, 87, 44,230,251, 42,113,162, -188,117, 4,178,130,129,214, 79, 77,111,194,141,195,186,117, 13, 42, 14, 68, 71,168,137,148, 94,109,216, 88, 46, 89,138, 14, 25, - 61,229,233,171,123,119, 2, 31,126,159, 86,206, 23,141,249,190,114,236, 40,190,246, 64,150,101,135,128, 11, 7,111,238,220, 91, -185,114, 37, 13,223, 67, 0,173, 16,229,173,148, 66,206,160,188,149, 98,107,151,151, 32, 43,103,185, 22,111, 15, 28, 58, 38,112, -179,161,128, 30,248, 56,147,228,185,107, 57,173,114,180,238,188,240,145, 54,120,192,128, 1,138, 61, 22, 37,113, 4,190,148, 62, -209, 5, 3,218, 92,217, 45,136, 77, 18,242,235,175,191,242, 93, 52, 86,180,117,212,161, 74,152,199,209,163, 71, 67, 72,178,174, - 94,189,234,180, 36, 75,125, 1,128, 86,185, 46, 29, 26, 66, 66,246, 82,222,188,188, 34, 55,206,207,247,172, 81, 37,207, 96, 24, -194, 39,100,158,176,242,243, 51,124,192, 6, 73,131, 3, 6, 7, 12, 14,252,167, 56,128,225, 62,172,187, 14,249, 28,119, 25,170, - 59, 14,131,141,233,131,174,241,126, 40,205, 85, 4, 48,215, 57,160,229,187,115, 80,176,218,144,234,195, 55, 91,122,134, 0, 90, -179, 90,103,147,229,253, 42,106, 2, 45,107,247, 14, 30, 30, 30,187, 32, 45, 81,164, 91, 42,208,130,241,186,251,188,121,243,220, -199,141, 27,231, 94,160, 64, 1, 2,173,129, 26, 21,126, 64,195,106, 30,199,210, 68,183,105,163, 69,160, 5,131,113, 25, 52,104, -144, 12, 30, 60,152, 19,248, 3, 71, 52,233,194,129,126,178, 0,180, 20, 23, 14, 5,179,102, 30, 86,170, 96,222, 7, 21,171, 84, - 15,120,239,255, 33,240,226, 93, 95,153, 50,124,234,139,210,241, 98,127, 72, 31, 59,161,166,225, 54, 36, 90,215, 81,188, 53, 72, -191, 34, 85, 71, 82,232, 22,200,154,249,151,146, 5,114,221, 41, 95,177,122, 64,128,249, 99,224,229,123,111,101,218,208,169,175, -202,197,141,245, 33,109,236, 68,157,244, 52, 52,128, 86,123, 26,189,115,119, 97,201,146, 37, 91, 88,151,151,116, 89,222,201,195, -166, 62, 47, 29, 87,187,188, 4, 89,185,191,105,249,246,208,145, 19,220,253,169,216,125, 81, 82,180, 96,217, 58, 73,157,191, 46, -109,178,194,115,196, 68,121,223,211,167, 25, 37,112,144, 94,113, 71,228,148,194,133, 11,127,224, 42, 6,253, 64, 54,109,218, 68, -192,104,198,245,193, 72, 54,237,169,224, 15,107, 43,140,231, 3, 73,103,233,210,165, 74,249, 8,222,144, 95,145,100,193, 15,155, - 83,146, 44,203, 10,185,185,166,147, 93, 27, 6,137,199,234,190,158,203,255,104, 56,216,213, 53, 77, 57,203,246,119,150,159,225, - 97,150,241,172,193, 1,131, 3, 6, 7, 12, 14,124, 53, 28,208, 86, 29,218,170, 10, 36, 90, 87,166, 12,248, 81,222, 62,188, 36, - 1,215,119,202,235, 13, 29, 20,192,245,106,101, 51, 5,104,205,106,149, 85,214, 98,183,225,156,222,223, 73,237, 66,201, 9,180, -174, 56, 98,137, 53,208, 90,181,106,213, 46, 24, 67,187, 15,169,150, 52,216,143,214, 47,149, 18,188,131, 90,201, 29,146, 15,122, -227,174,105,111,178,181,120, 79, 27, 55, 55, 55,127, 78,212,183,250,252, 36,103, 75,231, 80, 64, 23, 15,170, 14,233,183,169,111, -223,190, 10,200, 2,128,146,184,113,227,210,181, 65, 8,155, 27,235, 50,195, 95, 86,125,213, 25,169, 91,230, 52, 85,219, 55,170, -251,250,238,185, 19,178,101,218,112,233, 53,112,226,167, 89,238,151, 95,164,202, 81,254, 78,236, 84,217, 11,232,233, 2, 0, 90, -171, 80,156, 1, 72,223, 35, 41,187, 27,114,100, 74, 87,161, 77,189, 90,175, 72,119,243,180, 17,210,119,248,180,192,121, 91,174, -190, 76,151,167,194,157, 88, 46, 57, 44, 13,175,245,188, 34, 56,143,117,121,187,255, 58,254,211,204, 77,151,124, 82,102, 47,171, - 89,222,228, 57,235,148, 44, 88,177,205,219,195,199,188,100,237,218,181,220, 28, 33,123,247,238,149,133,203,214, 75,250, 34, 13, -124, 9,194,156, 42, 76,232,204, 9,105,143, 69, 55, 12,216,112, 64, 96,164, 74,245,114,196,137, 19,103, 23,182,217, 62,130,141, -149, 39,217,227,232, 61,201,146, 37,123,197,246,133,159, 53,197, 38, 11, 32, 43, 48, 60,146, 44,245, 93,148,104,117,254,169,129, -248,191,243,246,124,253,252,242,224,211, 7,250,149, 11, 15, 63,195,201, 43,227,113,131, 3, 6, 7, 12, 14, 24, 28,248,183,115, -160, 28, 36, 10, 8,181,211, 62,119,154,232,143, 23,141,233, 34,111,110, 28,146,119,199,102,202,235,117,109,101,243,239, 45,100, -203,212,110,210,161, 90,110,201,225, 18,233, 49,243, 49,191, 21, 79, 66, 56, 94, 11, 17,130, 39,155,233, 3,242, 14,128,253,203, -250,206, 69,255,239, 71,139,231,184,254, 19, 82, 60, 59,252,181,229,204,141, 70,103,179, 10, 21, 42,244,145,210,141,203,245, 43, -202,201, 28,201,164, 83,167, 78, 50,112,224, 64, 26,181, 75,242,228,201, 25,134,135, 6,214,161, 13,212,172,194,166,168,206, 72, -225, 13, 60, 81,225,156,110,143,207,236,218, 36,251, 22, 77,145,185,157,235, 74,177,188, 57,159,165,204, 81,246,180, 14,144, 21, - 92, 78,196, 47,164, 31, 15, 58, 69, 83,222,157, 53,107,210,120, 5,115,184, 61, 60,189,115,147,236, 95, 60, 77,161, 91, 60, 95, - 46,159,180, 57,203, 95,210, 0, 89, 14, 29,217,217, 44,111,158, 28,207, 82,184,149, 60,229,160,188,193, 52, 51, 23,109,176,225, -254, 67,111, 69, 29, 71,227,114,122, 85, 95,180, 98, 3, 64, 86,125,103, 65,150,189,114, 38,196, 70, 3, 33, 40,130, 11, 13,182, -115, 66, 39,190, 33, 75,154,235, 9,214,104, 71,103, 41,201,122,245,234,149,179,146,172, 80,229,116,205,148,102,116,157, 26,101, - 6,119,254,233,135,114,225,229,167, 19,117,211,202,250, 95,118, 96,104,212, 93,171,119, 56,119,223,224,167,115,252,210,202,109, -240, 83,139, 67,255,157,251,156,223, 41,213, 82,127,225,173,201,137, 35,143,139, 41, 14,128,212,192,162,153,226,249,174,155,212, - 93,124, 78,174,150, 17, 29,190,147,252,105, 98,248,242, 58,239, 59, 1,138,172,179,198,177,148,116,241, 92,163,104,142, 58, 54, -125, 81,173,105, 91,170,168,156,109,219, 80,113,237, 0,251, 26,210, 91, 67,124,227,128,110, 8,154,120, 38,102,174, 44, 25,126, -206,159,205,245,193,130,145,253, 62,237,248, 99,164, 2,134,152,242,101,205,104,237, 85,222, 30,217,255, 3,152,204,153,191,129, - 20, 38, 69,206,156, 57,163,103,203,156,174, 93,190,172,153,239,207, 25,214,231,227,206,153,163,131,233,230,215, 71,215,102,221, -195, 89,222, 96,154, 41,242,214, 42,210,166,215,216,247,222, 79,158, 9,157,188, 46, 94,185, 49, 44, 32,139,252,176, 11,180, 40, -201,226,238, 69, 58, 44, 13, 7,208,114, 67,236,194, 43,211,166, 77,147,107,215,174,133,217, 38,203, 94, 57,161,222,204,133,246, -239, 26,198,246, 55, 6, 94, 39,198, 22, 29, 89, 13,126,234, 96,146, 19, 89, 12,126, 58,193, 44, 29, 89, 13,126,234, 96,210,127, - 36,139,106,147,101,253,235, 92,245, 51,187,152,146,103, 77,102,154,158, 61,121,164,119,252,229,255,112,128,162,224, 71, 45, 37, - 93, 60,143, 0,154,116,209, 79,159, 86, 76,138,187,126,103,104,230,113,205,112,173, 83,237,111,223,173, 28,222, 93,214, 12,235, -170,128,161,177, 45,191,147,111, 11,230,120, 81,192, 45,243, 8, 45, 98, 65,247, 67,125,128,185,179,100,184,216,161,102,133,183, - 43,134,117,147,181,195,127,150,121, 93,126,144,241,173,170, 73,165,194,185, 94,230,207,150,105,188, 14,186, 54, 63,234,112,150, - 55, 4, 77,170, 7,219,246,254,253,253,237,187, 15, 37, 83,209,134,206, 74,178,212, 42,216, 27,124,162,229,205,155,247, 25,141, -221,115,231,206, 77, 21,174, 51, 6,136,214, 52, 99,192, 86,107, 12,195,235,208,233,169, 51,187, 11, 45,248,252,217,249,169,163, - 77,245,100, 49, 6,115, 61, 92,210,159,199,224,167,126, 94,233,201,105,240, 83, 15,151,244,231,249, 47,243, 83, 63,151,254,121, - 57,195, 30, 84,218, 86, 93, 92, 93, 77, 49,116,214,241,171,236, 48,121,220, 50,122, 21,200,225,250,164, 32, 83,182,204,222,249, -179,102,186, 83, 48,123,166,253, 89, 51,167,113,198,181, 65,104,160,229,150,241, 92,193,236,174, 79, 11,229,200,242, 12,116,159, -130,238,253, 2,217, 50, 29,207,157, 57, 67,173,240,240, 51,156,229, 13, 85,206, 20, 57,235, 20,206, 94,186,217,114,218,108,233, - 44,151,117, 54, 71,237, 94, 25,129,159, 87,226,129,111,156,164,109,143,102,145,170, 85,171,222,182,231,241,221, 25,128,173,230, -141,104,126, 58, 89, 79, 91,217,191,202,239, 40, 2,234, 77, 18, 70,221, 35,136,145,246, 22,128, 17, 64,222,104,163, 8, 96,162, -214, 2, 48,156,175,248, 90,218, 40,156,213,252,111, 62,254,181, 52,174, 81,206,136,237,159, 95,154,159,116,193, 97,115,135, 98, - 88,128, 86, 56, 89,241,165,235, 30,214,226, 26,229, 12, 43,231,108, 63,103,240,211,224,103, 68,113,224,191,220,151, 34,138,135, -127, 7,157,136,149,104, 57, 81,131,255,114,135, 49,234,238, 68, 71,209,145,213,224,167, 14, 38, 57,145,197,224,167, 19,204,210, -145,213,224,167, 14, 38, 57,145,197,224,167, 19,204,210,145,245,107,225,167,142,170,124,157, 89,216, 0,182,146, 51,181,177, 71, -195,209,117, 45,250, 6, 77,219,237, 18,214,246, 50,248,105,240, 83,111, 31, 48,190, 77,251, 28,208,203, 67,203,124, 6, 63, 13, -126,218,226,192,127,185, 47,105,125, 19, 95,227,125,235, 93,135,250, 28,150, 70, 64, 77,191, 22, 20,109,148, 51, 2, 26,219,130, -132,193, 79,131,159, 17,197, 1,163, 47, 69, 20, 39,255,162, 99,240,211,224,103, 68,113,224,115,244,165,136, 42,219,223, 65, 39, -124,187, 13,195, 81,226,207,209, 16, 6,205,112, 52,136,141, 71, 13,126, 26,252,140, 40, 14, 24,125, 41,162, 56,105,128, 34,173, -190,196,192,244, 76,246, 14, 91,247,181,104,134,165,245, 12,154, 97,225,218,191,243,153, 8,181,209,114, 3,143,152,244, 28, 97, -237,132,157,225, 77,253, 28,156, 90,126,130,151,118, 41, 95,190,252, 96,139,151, 5,211, 44,147, 43,234,137,111,242, 68,245,254, -127,138,230,253, 77,222,152,222,223,228,143,237, 93, 38, 95,236, 19,122, 10, 24,148, 39,172,229,116,244, 10,131,166,118, 3,100, -136,157, 32,249,217, 56,137, 82, 94,137, 25, 47,201,149,104, 49,227, 33,197, 13, 78, 81,162,199,244,176,213,238,234,181,148,249, -235,164, 79,150,167,214,138,100,121,106,150, 70,176,235,229,252, 77,158,167,238,178,191,126,235, 44, 77,158,191,118, 94,254,166, - 42, 88, 47,157,157,162,124,117,109,132,104, 10, 81,194,147,236,241, 51,117,234,212,238,136,176,112,197, 94,194,247,184, 71,187, - 57,191,122,105, 73, 89,212,241, 28,146, 18,156,214, 34, 93,196,185, 86,208, 89, 93,125,169, 28, 54,109, 52, 52,153, 58, 53, 55, -153,238, 50,241,156,215,254, 73,253, 19,206,157,247,161,189,189,227,199,143,127,131,229,226, 47,255,243,186, 86, 57,193,180, 40, -122, 82,110,147, 41, 81, 52,147,169, 3, 34,128, 92,138, 17, 57,114, 39,245, 25, 71,223,187,197,189,142, 56,247, 11, 74, 60,183, - 62,236,221,215,213, 70, 58,250,185,101, 22,131,166,147, 12, 51,178,219,230, 64, 54, 92,166,167,118,134,196,121, 92,164, 72, 17, -201,145, 35, 7, 7,161,199, 65,215,120,143,121,108, 29, 78,119, 66,124,120,227, 38, 79,158, 44,129,129,129,193,161,116, 16, 14, -103,176,173, 15,144, 0, 75,238,120,202,177,141,127,136,188,243, 65,122, 46,242,254,165,200,179,139,242, 77,254,184,222, 78, 52, -168,101, 57,227, 39, 78,156,120, 98,146, 36, 73, 30,194,201,168,183, 86, 98, 62,230,231,120,100,245, 62,205,186,199,141, 19,243, - 67,204,152,209, 2,109, 37,222,179, 81,254, 96,154,120,239, 33,150, 13,131, 95,136,228,226,226,226,173,166, 20, 41, 82,120, 91, - 38,120,168,247,102,194,115,150, 32,212, 81, 57, 99, 69,142, 26,189, 95,148,104,113,247, 68,137, 17,251, 81,148, 24,113, 30, 69, -141, 17,111, 15,175,161,108,177, 28,240, 87,179,238,120, 54, 67,170,116,174,247,126,159,185, 70,154,117, 29, 42,151,175,221,148, -150, 93,126,147,171, 55,110, 75,199, 62, 35,148, 95,130, 46, 71, 3,175, 75,254,134, 75, 39,205, 89,247,220, 37,127,131,135,147, -230,172, 85,126, 39,207, 93,239,131,235, 15,248,155, 34,127,195,123,147,231,172,243,113, 41,208,104,113, 88,251,103,227,172,169, -223, 54,201,236,242,209, 86,226, 61, 71,109,228, 68,255,211,202, 26,204, 79, 21,100,193,157, 5,189, 14, 75,147, 74, 5, 71,141, -239, 90,179,147,173,212,191, 94,193, 81,245,114,153,164,113,129,216, 5,213,231,236,241, 51,115,230,204,151, 62,126,252,136,128, -218,102,121,255,254,189, 48, 80, 57, 61,237, 35, 68,150, 18, 0,220,213,213, 85,153,116, 53, 14, 61,237, 94, 3, 52, 78, 35,157, - 65, 98,208,118,173,195, 17,205,120,240,165, 54, 16,225,155,246,196,136, 17,227, 9, 19, 66,108,237,225, 53, 16,181, 23, 89,130, -239,179, 71,243, 52,226,103, 42,126,217,158, 61,123, 38,143, 31, 63, 86,210,211,167, 79, 37, 86,172, 88, 87, 35,160,238, 38, 2, -171,169,165, 75,127,124,131, 24,162,222,221,187, 75,255, 4, 9, 62,240,154,158,254,137,250,121,160, 28, 87,156, 73,124,198,217, -113,137,160,138,131, 47,127,249,172,245,127, 71,125,222, 17,200, 66,108,173,168, 16, 51, 85,136, 26, 37,138, 59,198,165,215, 8, - 42,255,137,239,193,152,255,192, 9,160, 69, 73,149,159, 58, 57, 68,138, 20,233, 3, 66,119, 45, 65,156,215, 5, 72,243,139, 23, - 47,190,144,215,212,251,204,139,164, 74,190,244,244, 79,173,254,104,125,223,160,233, 44,199,254,189,249,195,100,147,181,133,157, -148,192,106,226,196,137, 2,176, 35,239,222,189, 11, 6, 63, 28,136,182,111,223,174,132, 64,201,149, 43, 23,129, 23, 59,180,221, -143,250,219,234,165,187, 84,111, 92, 81,152,138,150,206,255, 16, 31,111, 95,228,143,108,197,115,215, 22, 45, 90, 40, 8,139,193, -133, 17,212, 89, 28, 73,180, 20,160,117,113,133,108,235,154, 94,100,119,111,145,121,133, 69, 86, 34, 48,247,150, 54, 97, 6, 90, - 4, 77, 67,134, 12, 81, 98,253,173, 89,179, 70,150, 47, 95, 46,139, 22, 45, 18, 4,186,150,153, 51,103,202,168, 81,163,132, 65, -172,153,252,253,253, 21,158, 32,223,199, 32,176,101, 89,157,224, 15,176,120,161,116, 39, 74, 22,206,224, 93, 34, 40, 21, 47,144, - 86, 1, 58, 4, 88,193, 12,181, 58,225, 61, 71, 3, 26, 6,170,123, 62,112,252,249,226,204, 25,121,126,242,164, 60, 63,113, 66, -248,223,231,216, 17,164, 67, 72, 7,196,231,232, 62,121,118,216, 83,158, 30,216, 45, 79,246,236,144,199, 59, 60,228, 62, 6,120, -117, 0, 13,162,111,111,160, 40, 25, 45, 70,236,187, 63,118,254,205, 60,115,233, 86,217,113,224,172,108,221,123, 90, 38,207,219, - 36,205, 58,244, 55,199,136, 29,255, 46,158,183,231,103, 75,115,240,137, 17, 39,193,213,117, 91, 60,165,223,176,201,146, 50, 87, - 5, 73,145,179,124,136,212,185,223, 40, 45,160,149,216, 37,247,247, 23,192, 54,191, 20,249,234,189,225,111, 74,245, 55,111,200, -255, 41,114,127,127, 30,101, 77,236,136,159,246,218,136, 0, 75,109,154, 39,127,252, 33, 15, 16,148, 92, 61,120,207, 17, 77,203, -123, 4,183,228,187, 86,178, 2,193, 42,137, 16, 64, 11, 32,171, 16,110, 8,128, 17,251,136,108,253,115,192, 58,185,180,122,150, -101, 58,189,108,192, 58,130,172, 64,255, 55,129,252,109, 86, 36,118, 33,130, 45,139, 50,133,104,163,140, 25, 51, 94,121,251,246, -173, 32,200,187, 18,220,219, 58, 1,104,105, 1, 13,146,254, 95,123, 87, 1, 38,197,209, 68, 47,184,123,112, 75, 32,193,221, 37, -184, 75,112,130, 91,144, 16,220, 37,200, 5,119, 9,238,238,238,238,206, 29,238,122,232,113, 56, 28,183,248, 93,253,239, 13, 59, -251,207, 45,187, 59, 51,199, 65, 66,178,243,125,253,205,238, 76, 79, 77, 79,181,189,174,170,174,114, 84,239,236,227,227,226,197, -139,199, 54,207,232, 12,135, 9,100,248, 46,128,128, 83,248,159, 61, 86,172, 88,199,153,199,193,120,224,140, 38,175, 23, 70,116, -128,155, 59,118,236,120, 1, 64,104,185,114,229,138, 37, 48, 48,208, 2, 80,100, 65, 48,116,127, 72, 97,216, 62, 41,161,114,116, - 56,107,159,175, 17,144, 92,145,162, 35,222,170, 45, 17,104, 85,201, 19, 62,168, 69,153,168,150, 6, 69,163,112,236,170,136,104, - 12,177,236, 8,235,182,121,230,167, 20,139, 32, 11,131,170, 72,145, 34, 2, 81,153,240,154,145,114, 18, 96, 45, 91,181, 88,214, -110, 92, 37, 43,215, 46,147,197,203, 23,200,252,197,115,100,214,188,233, 50,117,230, 36,153, 48,229, 47, 25, 61,110,132, 12, 27, - 53, 88, 6, 15, 31, 32,253, 6,246, 37, 64,180,143, 63,171, 91, 78, 21, 88,253,240,195, 15, 47,248,155,103, 45,240,114,213,230, - 29, 1,173, 4, 30, 30,223,135, 11, 19,102, 48,230,146,199, 24, 63, 95,146,191, 85,171, 86, 85,218,218,176, 97,195,222, 1, 24, - 89, 50,160,127,242, 89,103,237, 83,115, 61, 24,208,194,247, 9,234, 62,232,214,173, 91, 74,226,111, 94,115, 3,173,143,106, 73, -183,222,157,180, 65, 87,151, 63, 7,205, 16, 20,227, 31,243, 72,136, 84,135,194, 1,241,201,147, 39, 28,208,157,225, 1, 5,108, -156, 57,115, 70, 1, 36,248, 92,123,112, 96,171,136, 89,187,135,181,217,113,111,174, 48,109,190, 53, 91,122, 77,108, 43,144,174, -216,123, 67, 31,124,240,224, 65,101, 53, 25, 41, 82,164,221,160, 23,211, 85,167, 86, 85,135,133, 51,133,247, 47,149, 59,214,139, -194,153, 34,248,127,170,234,144, 18,170,233,211,167, 75,245,234,213,131, 13,182,234,192, 91,175, 94,189, 96,147, 16, 1, 40, 87, -252,124,206,217,192, 75,128,165,101, 96,133,146, 25,159,228,203,153,194, 47,121,210,184,202,138,142, 96,149,169, 71,143, 30, 74, -162, 84, 65, 15,104,129,119,183,158, 28, 63, 46, 23,199,140,177,165,203,227,255,146,171, 83,199,201,181, 89,227,196,103,222, 56, -185,177, 16,105, 1,126,207,197,181,153,227,228,202,148,113,114,103,221, 26, 35, 64, 43, 79,210, 20,105,158,204, 93,177, 67,166, - 46,222, 46, 69,107,117, 71, 40,158, 26,242,125,222, 95,164, 84,253, 62, 50,114,230, 38, 25, 59,107,157, 36, 73,241,227, 99,124, -179,163, 0,216,186, 29, 48, 98,228, 24,183,206, 32, 20, 79,185,170,245, 37, 75,161,202, 50,112,244, 52, 25, 61,121,158, 2,182, -166,207, 95, 41,251, 14, 31,119, 9,180, 48, 57,143, 47, 86,189,125,192,132,217,235, 44,197,235,244,181, 76,152,179,206, 82,162, -158,122,246, 84,254,151,172,255,167,114, 46, 83,167,115, 0,234,103,188,171,182,244, 81, 29,149,250, 80, 71,141,210, 36, 83,234, -136,199, 97, 76,138, 76, 33, 1, 90,234,228,229,180, 35, 89,111,216,129, 96,181,200, 54,126,170,146, 44,246, 73,182, 59, 0, 3, - 5,108,109,154,210,115,133, 10,180,142, 47,232,185,130,224, 42,240, 21, 0,205,174, 65,242,230,218,238, 64, 85,178,229,108, 34, - 67,123,218, 8,181,225, 5, 38,196,120,124,129,243, 27,109,194,100, 27,224, 72,173,104,167, 82,116, 84,239,227,216,167,253,253, -253, 5, 65,187, 31,161, 95,189, 3, 32,146,245,235,215, 75,246,236,217,131,138, 22, 45,250,150,253,189, 73,147, 38, 28, 63, 8, -182,236, 15, 71, 52, 75,194,156,224,145, 5,199,187,119,239, 44, 24,167, 44, 43, 87,174,180,128,142,242,155,215, 32,137,178,164, - 77,155,246, 33,136, 57,124,222,201,208,252,218,215,215,247,253,209,163, 71,229,220,185,115,114,227,198, 13, 69,162,199, 49,174, - 65,145,240, 34,155,210, 75,155, 42,137,100,248,148,181,231, 50,101,201, 62,142,177, 48, 13, 0,131, 96,175, 34,168,162, 36,139, - 32, 11, 31,108, 26,104,109,219,182, 77, 16, 31,214,101,202,147, 39,143,252,244,211, 79,130,168, 9,186, 64, 11,253, 98, 5, 36, -224, 7,180, 9, 82,242,231,221,186,117,123,207,122,226,193, 51,255,243, 58,243, 97, 49,176,194,217, 88,167, 2,173, 34, 30, 30, -209,194, 3, 87, 70, 8, 31,254, 4, 64,233,243, 18, 37, 74,216, 38,145, 20, 41, 82, 4,133, 15, 31,254, 49, 36, 89, 62, 17,194, -132,233,250,157,135, 71, 2, 19, 18, 45,190,250,119, 74,173, 8,168,160, 93,241,193,130,124, 1,210, 66,166, 95,126,249,101, 49, -175,241, 30,243, 48,175,217, 58, 50, 57,109,235,142,117, 38,233, 49,251,127,153,166, 83,118,161, 41,230, 68,130, 36,197,150, 74, -106,126,231,197,239, 60,214,255,218,235,204,207,235,218,103,237,255,243,217,104, 72,144,212, 40,180, 25,151, 56,110, 8,234,205, -181, 68,107,221,186,117,162, 38, 13,113,165,147, 49, 92, 10, 7,158,139, 23, 47, 42, 98,116,170, 21,252,252,252,100,251,246,237, -242,215, 95,127, 73, 7, 12, 26, 29, 59,118,148,137, 19, 39,170, 54, 13, 14,203,167, 74,180,126,174, 91, 82,254,156,217, 69,150, -159,155, 46,149, 26,150,123,143,129, 90,141, 65, 24, 46,115,230,204, 15,248,206,145, 35, 71,146, 22, 85, 12,134, 14,208,232,188, -227,148,165, 47,207,134, 30,112,145,137,128,137, 82, 43,174,184,180,171, 90,103, 64,139,171, 50, 2, 77, 7, 64,203,246, 22, 78, -216,218, 9,246,202,249,221,114,236,224, 98,169, 92,169,188, 2,170, 30, 63,126,172,128,203,251,247,239, 43, 60,230,217, 9,208, -178,209, 36,208,162, 20, 43, 24,208,154, 8,160, 53,125,156, 92,159, 3,128,181,104,156,237,149, 4, 92,188,118,117, 26,128,214, -154, 85,246, 64,203,158, 27,145,195, 70,136,226, 51,125,241, 22,105,215,127,182,164, 40,220, 70, 18,101,173, 98,163,149, 42,127, -109,201, 93,227, 79,105, 59,112,161, 12,159,186, 90, 32,217,242, 1, 1, 87,106, 68,135,220,142, 16, 41,234,173,154, 53,107, 10, - 84, 53,210,182, 99, 87,233,218,119,152, 12, 27, 63, 75, 1, 90,147,103, 47,147,221, 7,188,236,129, 86, 48, 58,144,102, 92,131, -148, 13, 32,171,143,165,231,160,201,150,162,181,122, 89,250, 12,155,174,252,239, 55,106,182,165,100, 61, 79,203,144,241, 11, 44, -229, 26, 15,180,108,222,115,220, 2,137,227, 53, 87,109,195,190,142,174,162,142,142, 31, 90, 44,127, 86, 40, 43,126,136,169,168, - 5, 88,252,125, 60, 89, 50,113, 34,209,114,248, 26, 21,104, 49,206,163, 35,137, 17,175,243,112, 2,180,180, 52, 21, 73, 22,249, - 70, 58,236,151,103,206,156,166,100, 77, 84,160,245, 65,146,245, 92, 94,236,232, 47,247,251,199,151,167, 11,106,202,211, 21, 45, -222,240,186,145,254, 65, 53,162, 86,117, 79, 80, 71,176, 65, 41, 20, 23, 95,108,175,108,163, 55,111,222, 20,128,175, 43,174,104, -130,239,222,124,102,215,174, 93, 2, 48,164,168, 35, 25, 71,147, 65,203, 55,111,222,172,212,255,249,243,231, 5,210, 54, 65,157, - 82,178,165,119,196,128,122,240, 54,202, 98,193, 88,100, 65, 89, 20,128, 69, 73, 22,127,239,219,183,207, 82,168, 80, 33,229, 26, -222, 99,129, 90,241, 54, 8,218,171,245,157,189,227,213,181,107,215,222, 49, 88, 57,206,202, 55, 2,203, 41,245, 2,137,150, 52, - 43, 21,229,213,111,149, 82, 88, 54,123, 61,125, 59,106,198,230, 11,168,171,202,122,133,181,191, 79, 53, 97,143, 88,177, 2, 41, -201, 98,234,240,205, 55,129, 46, 84,135,193, 30,167,116,138,146,172,106,191, 84, 86,202,196,179,125,250,165,110,117,169,215,168, -142, 52,105,214, 80,145,106, 57,144,104, 5,163,137,113,228, 0,192,250, 37,240,243, 18,212,197,151, 80, 63,151,192,203, 75,136, - 19,251, 20, 17, 23, 20,164,197,115,221,186,117,159,249,248,248, 92,130,196,232, 18,159,113,246,221, 81, 60, 60,114,124, 19,235, -199,253,145,226,126, 31,128,113,252, 61,199, 53, 6,146, 71,200, 45,130,233,151, 0,219, 79,195,134, 9, 51,139,249, 28, 73,191, -140,242, 51, 91,182,108, 51, 80, 30, 1,176, 90,138,126,144, 86,155,120,141,247,152,199, 40, 61,119,190,127, 6, 7,156, 96, 17, -165,112, 4, 65, 60,169, 73,251, 31,139,138, 30,234,127, 71,249,180,215,172, 96,202, 70,203,250,108,121,158, 73, 27,170,232,133, -200, 99,212, 14,221, 60,227,248,145,154,167,108, 64,139, 96, 75,155, 26, 55,110, 44,205,154, 53,147,223,127,255, 93,218,182,109, -171, 0, 45,130, 46, 43, 3, 92,190, 24,171,177,240, 41,190, 75,177,109,194,182,145, 50, 96,126,111,129, 17,110, 47,235, 3, 63, - 19, 96,241, 32,224,194, 53,195,158,190, 67, 19,104, 81, 5,216,168, 81, 35,105,221,186,181,180,108,217, 82,249, 78,254,199, 64, -195, 78,173,168, 51,185,218, 37,184, 58, 9,181,221,161, 67,135,152,231,157, 3,213,161,141, 15,121,115, 36,247,187,112,122,187, -172, 94,208, 83, 86,206,235, 46,203,230,116,149, 37, 51, 59, 75,197, 10,101,148,137,171, 77,155, 54,202,251, 90,181,106,165, 36, - 78,186, 70,128,214, 67,188,251, 35,160, 5, 48,165, 0, 45,128, 43,245, 80,128,214,236, 15, 64,235,246,202,229, 46, 39,243, 48, - 97, 34,116,171,213,180,235,155,169, 75,118, 72,202, 34,109, 37,117,137,142,146, 44, 71,117, 27,173,180, 63,213,151,130,117, 7, - 75,209,134,195,101,232,140,205, 82,179,105,151,215,225, 34, 68,166, 26,216,212, 65,160,229, 57,104,140, 84,131,228,144, 82,211, -150,109,218, 75, 55,128, 45, 2,173,241, 51, 22,203,246,189,135, 93, 2,173,216,177, 99,251,160, 80,150,141, 27, 55, 90,160,194, -182, 64,133,100,217,189,123,183,101,255,254,253, 22,212,137, 5,139, 3,203,241,227,199, 45,176, 3, 81, 38,100,172,198, 9, 8, -157, 30, 31,234,104,155,173,142,150,163,142,150,206,234, 34,158, 0, 90,183, 32,109,180, 7, 90, 71,194,134,149, 58,223, 59, 84, - 29, 58,124, 7, 1, 20,193, 11,164, 13, 79, 84, 91, 57,237,153,215, 9,102,120,205, 85, 57, 85,137, 22, 64, 69, 32, 1,203,249, -243,231, 2,217,239, 28, 73,180, 94,159, 95, 23,244,116,126, 53,121,182,180,193, 59, 7, 18, 45,167,175,161, 26,145, 42,113,103, -106, 68, 45, 80,132,164, 75,207,118, 43, 3, 37, 89,171, 86,173, 18, 38,154, 4,168, 32,139,210, 25,212,153,236,221,187,151,193, -223,223,160, 64,217,245, 26, 17,237,175, 0,208, 94, 80,106, 69, 96, 5,137, 83, 48,144, 85,169, 82, 37,203,140, 25, 51, 44, 40, -163, 34,213,234,211,167,207,179, 8, 17, 34,208,102,203,200,113, 8,160,239, 61, 65, 22, 36, 91, 74,223, 84,165, 58,224, 59,213, -156, 30, 80,129, 38,234, 51,124,238,209, 45,199,158,191,203,156, 53,231, 48, 35, 68,181,121, 96, 88, 23, 62,119,244,232,247,246, -173, 92, 25, 52,184, 94,189,247,121, 99,196,240, 41, 98,112,172, 35,104,162, 73,131, 42,209, 98,167,212, 74,183, 96,159, 4, 65, - 89, 17, 41, 85,170,148, 2,110, 32,133, 50, 2,180,246,227, 59, 47,129,167,151, 80, 47,151, 0,134, 47, 65, 59,113, 9,227,249, - 85,168,139, 21, 41, 20,234,248,125,191,126,253,124,120,157,135, 43,160, 5, 41,210,211, 63, 39,174,147, 40, 63, 86,145, 25,179, - 23, 8,212,184,239, 17,114,235, 9,236,178, 14, 70,240,240,168, 94, 3,139, 50, 87,118, 92,142,248, 9, 51,137, 61,152, 39,110, -105, 83,178,100,201, 2, 32, 17,101,187,177, 64, 66,118,143, 9,237,214,139,128,139, 64,139,245, 7,222, 76, 53, 91, 63,238,252, -255, 12, 14,216, 97, 17,165, 80, 90, 32,165, 5, 75,246, 0,203,254,158,253,115, 31, 72,125, 0,109,206,158,197,245,164, 33,224, -132,190,141,150,131, 15, 51, 5,180, 70,141, 26,101, 8,104,177,240,232, 48, 53,219, 14,109, 45,227,182,140,145, 31,210,164,218, -135, 75, 49,169, 42,228,234,135,106, 6,252, 31,108,230, 35, 29, 1, 45,128,181,205,176, 9,184,232, 40,241,158, 11,250,161,101, - 12,111,123, 69,158,108,201,252, 78,123,111,146,249, 83,219,203,220,201,109,101,246,196,214, 50,115,220,239, 82,174,108, 73, 69, -253,115,224,192, 1,193, 74, 92,246,236,217,163,172,252, 1, 26,116,129, 22,190,249, 22, 7,210,108,223,125, 39,189, 32,125, 75, -151, 36,137,172,233,209, 21,234,193,191, 20, 53, 33,213,133, 84, 27,122, 79, 28, 36, 29,170,150,147, 6, 37, 10,203,214,126,189, -229,230,210,197, 46,129, 86,216,136,209,118,140,158,177, 90,106,180, 29, 43, 63,148,236, 40,105, 74,182,151,164,153,203, 74,226, -244, 69, 36, 89,198, 98,146,169, 68, 83, 41,214,104,132,148,110, 54, 70,154,245,157, 39,127,254,181, 76, 34, 71,143,179,195, 76, -125, 49, 47,129,214,204,133,107,165,119,255,145,138,228,144,210,146, 72,209,227,217,236,180,126,109,239,233, 18,104, 1,216, 42, - 64,107,235,214,173,150,157, 59,119, 90,192, 59, 11,248,104, 57,124,248,176, 50,201, 66,165,107,129,100,194,130,137,147, 26, 38, - 93,160,197, 58, 58,229,189, 49,120, 29,141,111, 37,158,229,203,216, 64,166,170, 58,100, 89,105,183, 99, 6,104, 17, 64, 81, 26, -236, 12, 72,113,211, 2, 39,118,158, 93,241,146,118, 86,170,141,214,201, 19, 39,222,114,176,112,101,163,245,112,126,237,247, 78, -108,180,156,190, 70,171, 70, 84,213,137,206,206, 58,187, 17, 21,195,119,128,159,119,252, 54,130, 44,128,158, 87,184,118,146, 9, - 96,224, 53,175,179,253,163,159, 82, 5,202,235, 46, 13,228, 33,161,218, 5, 96,110,129,244, 69, 1, 89,148, 92,169,146,172,242, -229,203, 91, 22, 44, 88, 96, 1, 64,180,120,121,121, 89, 46, 95,190,172,128,111,168,153, 97,135,109,232, 96, 0,250,189, 72, 79, -145,158,105, 18, 37, 56,249, 85, 10, 21,170, 53,152,177,253,164, 69, 42,213,108, 50, 95,143, 42, 84,109, 61,192,207,147, 56,159, -193, 24,183, 1, 64,228, 10,165, 59, 60, 56,230,162,190,105,159,165, 85, 65, 58, 37, 73,160, 69,155, 44,173, 20,139,116,170,215, -170, 34,117, 26,252, 34, 13,154,212,147,166, 45, 26, 99,209,210, 66,218,117,108, 45, 67, 70, 12, 50, 4,180,192, 71, 5,104,173, - 89,179,230,210,146, 37, 75, 46,205,153, 51,231,210,136, 17, 35,174, 34, 0,188, 2,180,178,102,205,250, 30,128,213, 7,182,170, -151,176,112,185,132, 58,223,239,172,144,248,190,231,251,206, 61,149, 82,191, 14,127,247, 77,252,220, 47,160, 26,252, 3, 51, 86, - 18, 35, 59, 17,237,108,180,108,175, 96,159,216, 63, 99,178, 28, 95,190, 88,188, 22,205, 83,164,171,236, 75, 76,187,198,141,148, - 93, 99,135,203,202, 14, 45,185,104,127,228, 6, 90,122, 45,242,159,127,223, 17,200, 98,169, 85, 80,244,225,231, 7,245,161,250, -219,254,236, 12, 92,217, 63,195,231,236, 37, 90,214,255,197, 66,192, 41,215, 54, 90, 78, 62,204, 20,208, 26, 62,124,184, 75,160, - 5,155,138, 54, 52,130,116,148, 40, 37,226, 32,204,131,198,240,248,192,212,102, 62,146, 64,107,202,146,195, 35,112,238,195,223, - 76,185,114,229,186, 79,122,148,196,105, 15, 26,177, 19,124,153,161,255,169,121,115,103, 77,226,231,125,112,141, 76, 25,221, 92, -254, 26,210, 72, 70,245,111, 32,195,250,214,145, 62, 93,171,201,224,190,245,197,179,251, 47,210,171,115,117,233,222,190,178,116, -106, 85, 65,218,181, 40, 35, 63,124, 23, 55, 40, 71,230,132,239,114,101, 77,244,220,209,251, 9,180,218,183,111, 79, 59, 4,155, - 40,149,141, 70, 47,113,227,130, 43,245, 20,118, 22,222, 90,190,249,136,228,255,197, 83, 50,148,239, 46, 89,138,214,193,202,158, -182,230, 31,142,140,133,235, 74,153,230, 99,165, 98,171, 9, 82,187,203, 12,153,184,120,143, 68,137, 22,251,150, 51, 30, 69,141, -147,104,115,204,132,223, 95,140,241,109,202,139,209,227, 37,191, 24, 45, 78,146,139,116,231, 16, 35,126,138,199, 81, 99,198, 3, - 72,139, 45, 69, 74,148, 17,136,157, 8,172,164,109,143, 33, 82,175,101, 79,233,246,231,104, 67, 64,139, 19,169,171,111,230,100, -203, 3, 19,157, 75,137, 22,235,200, 11,117, 52,121, 84,115, 25, 51,232, 67,253, 12,232, 89, 83,122,183,253, 89,250,253,129,186, -234, 82, 83, 58,213,206, 47,109,170,231,150, 86, 77, 75, 73,179,250, 69,165, 64,166, 68, 65, 89, 51,124,251, 46,123,134,248, 14, -235, 72,203, 19, 78, 22, 80,209, 56, 5, 82,188, 79,240,102, 4,104, 89,193,150,178,235,240,151,146,217, 70, 12,254,189, 98, 7, - 71,169, 75,245,108, 35, 92,236, 58,252,212,102,109,228,249,195,180,205,226,161,170, 11,173, 6,240,202,179, 80, 79, 93,161,106, - 14,224, 88, 0,140,148, 13, 55, 0, 19,138,228,200,217,129,231, 31, 64,149,105, 33,216, 82, 85,134, 4, 93,216,113,102,153, 60, -121,178, 13,100, 81,146, 9,187, 71, 11,164,104, 22,208,164,132, 60,212,142,114, 85,234,205, 36,208,250,185,122, 99,103,187, 89, -109,239,130, 73,193, 37,136,254, 5,198, 68,130, 50, 74,187,118,237, 20, 73,185, 10,180, 10, 22, 44, 40, 0,206,175,241,192,116, - 36,151, 18, 61, 2,173, 89,179,102, 5,147,104,113,179, 18,105, 96,124,165,138, 79, 0,106,165, 70,141, 26,138, 4,158,246,158, - 6, 84,135,251, 33,249, 83,128, 22,120,117, 9, 64,245,210,184,113,227,174, 0, 4, 63,175, 93,187,182,162, 58,172, 83,167, 78, - 32,254,251, 15, 29, 58,244, 26,164,197,122, 64,235, 21,129,214,224,165,215,197, 35,113, 17,238, 40, 12,132, 68, 75, 55, 33,223, -107, 87, 64,139, 32,171,109, 52, 15, 37,209,110,142,137, 42,236,174,241, 34,202, 31,137,162,201,174,145,131,130, 1, 45,183,234, - 48,212,154,251, 23, 37,228, 12,100,177, 16,246,224, 41, 52,128,150, 14, 77,179,223,254,105, 54, 90, 70, 84,135,131, 6, 13,114, - 9,180,160,102,107, 19, 12,241,216,253,161, 90,133,110, 29,232,222,193,236,215, 17, 88,249, 62,126,183,133, 96,139,182, 90, 76, -133,139, 22,127,200, 45,234, 84, 71, 66,218,109,179, 65, 99, 69,234, 0,173, 24, 88, 1,143,134,196,196,144,123, 7,230, 99,126, -148,217,169, 29, 72,174, 44, 73,252, 14,238, 89, 33, 35, 7,212,151, 65,189,107,202,203, 23, 15, 12,165,103,143,174, 74,214, 12, -241, 29,185,121,160, 84,240,214,162, 89,107,164,117,195,222,210,170, 65,175, 96,169,109,163, 94,210,190, 73, 47,153, 59,101,137, -146,248,155,215,152,207,179,203, 40, 73,150, 36,137, 83,169, 9,128,214,237,197, 27, 14, 73,161,186, 3, 37, 91,229,222,146, 58, -223, 47,146, 52,125, 97, 91,109,101, 45,222, 80, 42,181,158, 40,213,218, 79,149,134, 61,231,202,248, 69,123, 37, 74,244,216,180, -131,113,120,196, 78,148,234, 34, 31,158,178,246,164, 66, 99,233,214, 19,202,121,199,161, 51,202,249,244,197,235,202,121,252,140, - 37, 18, 46, 98,180,231, 46,252,104, 5,163,143, 9,204, 7,143,217, 84,133,148, 96,168,170, 66,168,118, 45,176, 93,178, 92,189, -122,213,130, 1,215, 66,123, 30, 61,160,149, 43, 75, 98,191, 3,187,151,203,136,254,245,164, 95,207,234,134,234,135,245,168,212, - 81,250,111, 29,214,145, 61,208,162,109, 35, 93,111, 56, 98, 20,175, 99,215,148,211,251,234, 51,159,226, 67,203,110,215,161,217, -110, 22,146,252,135, 9, 46,217,231,160,226, 85,118, 41,219, 3, 45,170, 40,169,138, 36,200,162,109,148, 30,208,130, 17,245, 3, -214, 43, 1, 20,248,169,212,243, 53,128,233,149,209,162, 89, 46, 79,153, 98,129, 74, 95, 81, 23,243, 58,108,200, 44, 48,104, 15, -125,160, 85,185,238, 44, 2,173,138,213, 26,204,213, 97,202, 72, 74,107, 47, 52,104, 32, 75, 49, 79,120, 98,199, 42, 19, 22,129, - 54,160,197,223,189,122,245, 82, 22,160,232,211, 28, 67,237, 55, 8,217, 94, 65,208,196,221,133,170,141, 86,205, 58,213, 96,143, - 85, 59,216, 72,218,161,115, 91,233,218,163,179,252,209,183,135,140, 24, 61,204, 8,208,218,135,118,119,105,211,166, 77,138,218, -112,234,212,169, 87,202,148, 41,243, 26, 26,138, 32,173, 49,252,152, 49, 99,130,224,215,240, 53,128,216,117, 87, 18, 45,140,223, -126,139,246,220, 83,128, 86,138,124, 13,149,186,231, 65, 19, 19, 21, 96,242, 63, 64,156, 84,171, 86,205, 86,118,130, 49, 87, 64, -235,232,194,185,193,128, 22, 65, 22, 77, 14, 8,178,254, 76, 25, 71,118,193, 30, 13, 42,234,215, 84, 27,194, 24,254,134, 19, 99, -248,144,180, 97,247, 51, 95,144, 3,161,101,163,101, 7,160,114,171,255, 63,224, 53,231,210, 48,222,183, 74,180,244,252,230,133, - 26, 87,148, 78,192, 65, 80, 15,104,117,238,220, 89,160,195, 15,177, 68, 11, 43,177, 32,116, 94, 58, 10,108, 29,146,210, 59,146, -104,101,200,144,225, 60, 0,213,117,179,170, 67,130, 38,184,107,192, 24, 99,219,108,102, 27, 12,120, 13,182, 33,138,107, 7,138, -173,185, 26,167,113, 47,220, 62, 4, 90,193,150,195,226,231,204,156,216,111,247,182,197,210,175,123, 53, 72,173,202, 43,147,248, -169, 3, 19, 12, 37,103,147, 56,129,214,250,213, 94, 50,180,223, 10, 25,242,231,114,135,105,254,172,221,194,164,189, 63,113,244, - 6,151, 18,173,112,145,162,239, 26, 60,113,185,212,235, 60, 89,242,212,236, 39, 5,235, 12,146,244,133,254, 63,152,231, 44,221, - 68,170,119,152, 38,181,187,206,146,246, 67, 87, 74,159, 49,203, 36, 90,204,120, 78, 85, 51, 4, 90,253,231,123, 75,249,174,203, -164,100,155,153, 82,184,233, 95,146,175,238, 32,201, 81,173,135,100, 42,215, 70,210, 20,109, 36,223,229,173, 46,139, 86,109,113, - 41,193,178,103,172, 10,180,168, 42,100,231,112,150, 96,108,173, 0, 45, 72,138, 92, 74,180,114,102, 78,228,183,107,235, 34,241, -236, 86, 85,186,182, 45, 23, 42,117,164, 45, 51,129, 20,141,199,157, 1, 45,250, 67,131,161,177,240,236,170, 15, 56, 3, 90,170, - 58,145,103, 87, 96,204, 17,109,171,170,208,169,179, 82,251,221,134, 58,234, 66,237, 43, 20,213, 33, 38,190,183, 4, 89,220, 64, - 3,245,222,155,166, 77,155,222, 96,130,228,228, 29,129, 22, 65, 22,236,139, 12,169, 14, 97, 8,191,155, 42, 67,238, 46, 36,144, -162,234, 24,230, 6, 10,200, 90, 22, 54,172,229,234,180,105,150,235,215,175, 43, 0,155, 64,140,246,123,104, 43,187, 93,240, 52, - 47,238, 81, 93,168,236,222,180, 38,254,230, 53,222,251,232,168, 80,181,254, 28, 2, 45, 72,182,230,232,140, 87,126, 52, 7,160, - 57, 4,141,253,185, 24, 37,208, 34,232, 32,192, 98,226,111, 21,128,209, 62, 19,244,156,214, 63,129, 22, 23,163,180,203,162, 61, - 86,225,194,133,165,100,201,146,228,169, 84,169, 82, 69,177, 31,173, 95,191,190,128,183,138,253, 44, 1,156,158, 68, 11,117,185, - 23, 54,105, 54,160, 53,105,210,164,171,144, 94, 41, 42, 67, 0,161, 32,254,230,153,255,127,254,249,231,247, 24,235,124,116, 84, -135, 87, 41,201, 74,158,183,190,120,196,205, 42, 13, 0, 50,177,179,148, 11,104, 37,241,183,253,255, 95,127,253,149,247,222,187, - 2, 90, 84, 23,170,146,172,246, 49,194, 72, 23, 72,178,122, 37,142,206, 93,183,202, 24,204,241, 24, 99,190, 80,146,229,194,189, - 67, 72,166, 23,247, 51,255, 16, 14,160, 9, 42,128, 73,147,180,187, 11,121, 79,221,117,200,223,106, 94,154, 3, 16, 93,105,159, -213,222, 87,105,216,211,194,166, 89,211,135, 26,235, 80,171, 66,212, 37,114,145,182, 19, 4, 21, 80,191,124,100, 12, 15,177,191, -210,153,233,150, 96,192,128, 1,138,216, 26, 20, 13,171,228,208, 89,243,215,235, 80, 87,198,109, 29, 43,121,139,230,121,130,103, -181, 62,181,190, 1,144,104,144,242,251, 20, 27, 75, 84, 46,244,178,196,207, 5, 61, 93,149, 54,148,141,225,239, 18, 80, 97, 85, - 44,233,210,165,115,184, 67, 76, 53, 6,230,125, 26,196, 83,229, 67,201,150,179, 50,230,200,148,200,111,235,134,121,210,181, 77, - 89,105,221,180, 88,168, 76,226, 4, 90, 35,134, 77,149, 12,233,114, 75,186, 52, 57, 29,166, 34,133,202, 10,147,246,126,195,186, - 29, 93, 27,195,135,139,208,163,122,227, 46,111, 70,207,222, 34,133,234, 13,150,130,181,250,202,119, 89, 75,216,192,102,186,220, -229,164, 90,155,191,164, 97,175, 5, 50,116,230, 78,169,209,180,219,107,216, 91,113,183,134,195,131, 64,235,185,229,141, 60,246, -127, 37,143,159, 91, 20,160,245,232,233, 11,121,248,196, 95, 30, 60,126,174, 0,173,107, 55,239,202,165,107, 55, 67, 4,180,104, -143, 67, 9, 6, 54, 16, 40,187,204,232, 79,137, 19, 45, 86,233, 22,216,191, 41,147, 45, 38,115, 93,160,197, 58,218,178, 97,174, -116,105, 93, 70,126,111, 82, 56, 84,234,200,202,144,248, 0,121, 43, 0, 54,158,179, 31, 57, 0, 82,184, 20, 95,185,207, 77, 16, - 33, 1, 90,246,126,181, 92,129, 45, 71,149, 68,227,119, 86, 48,219, 61,119,193,114, 82,227, 34, 66,117, 90, 74,201,129,186, 43, -150, 82, 55,131,206, 75,213, 87,101,192,214,254,167,180, 69,164,225, 59,109,178, 8,174, 84, 27, 27,238,236,163, 36,235,251,239, -191, 55,106, 12,239,137,133,144, 63,202,169,108,122,224, 38, 8,110,128,160, 36,139, 32,139,146,173, 39,176,219, 98,221, 19,140, - 97, 87,244, 83,216, 70, 57, 29, 63,192,171,211,148, 52,170, 78, 74, 89, 30,126, 43, 39,112,124,192, 81,123,126,161,126, 18,244, - 30, 50,235,232, 22,239,231,239,179,102,207, 51, 92, 15,104,209,120, 29,230, 16, 2,181,230, 71,128, 75, 5, 88, 84,247, 65, 26, -163, 0, 16, 61,160, 69, 63, 89,181,234,213,128, 61, 86, 93,249,181, 69, 35,105,217,186,185,180,237,208, 74, 58,117,109, 47,221, -255,232, 42,189,255,252, 67,250, 15,250, 83,134, 12, 27, 36, 99,199,143, 54, 2,180,246, 64,250,167,168, 14, 87,175, 94,125, 9, -229,188,138,221,192, 10,208,226, 25, 82, 40,238, 14, 86,254, 3,200,189,199,238,114, 31,140, 61, 78,109,180, 8,150, 32,117,244, - 35, 32, 68,187,167, 77,162, 34,169,227,247,193, 29,134,192,104, 93,208,222, 88,223,108, 71, 52,180,151,210,165, 75,179,156, 15, - 92, 1, 45,182, 23, 85, 93,168,130,172,126,223,197, 85, 64, 22,235,142,247, 49, 15,188,132, 61,217, 84, 23, 14, 75,117, 39, 61, -119, 6, 55, 7, 62,129, 3, 33,138,117,152, 10, 47,220, 6,253,188, 2, 36,232,118,128,187,144, 40,221,226,174, 67,238,148,163, - 93, 22,125,181, 96, 7, 8, 7,136,237, 72,124,198,232,241, 77,238,194, 57, 31,206, 60, 56, 81,154,245,106,196, 78,162, 58,191, - 36,200,154,217,101,100,115,217,116, 99,134,226,119,107,214,158,161, 95, 12,104,209,219, 58,213,152, 4, 81, 70,128, 22,243,112, -112,230,115,206, 62, 60, 91,198,132,126,235, 87,205,148, 86, 77,138, 72,195, 90,121, 67,101, 18, 39,208, 82, 39, 43, 78,142,174, -124,157, 5,211, 45,224,143,142, 11,129,200,240,113,229, 51,120,242, 42,233, 52,116,137, 20,168,222, 77, 14, 30,246,178,145, 56, -116,196, 91, 42,183, 24, 42,189,199,111,146,254, 19,215, 74,212,152,113, 40, 41,114,234,222,129, 64,235, 89,128,107,160,229,115, -203, 87, 46,126,236, 9,222,101, 59, 2,191,125, 80, 40,197,224, 29, 25,157, 74,180,104, 40,205, 93,135,122, 18, 45,214,209,186, -149, 51,228,183, 70,133,164, 65,141, 92,161, 82, 71, 40, 87, 54,248, 51,122,200,190,195, 54,117,251,246,109,251,118,146, 13,246, - 53, 15,185, 67,138,247,233,183, 9,187,218, 76, 73,180, 52, 32, 75,217, 41, 7, 80,164,236, 66,116, 6,182, 28, 49, 21,238, 28, - 46,178, 45, 57,114, 59,241, 9,206, 75,149, 87, 65,210,235, 69,224, 66, 23, 14,220,240, 65,233, 14,199, 16,173,186,144,187,120, -185, 9, 4, 59, 73, 13,185,119,192,164,124,155,245, 74, 64, 77,144, 69,181, 49,219, 1, 36, 51,150, 71,247,239, 43,224, 26, 64, -201,130,247,232,185,119,136, 8,227,250, 55, 4,146,246,174, 92,120,173, 82,174,176,210,172,100,196, 23,141, 75,198,122, 88,182, - 82,157, 57,144,100,205,237, 61,108,246,209, 13, 71, 30,189, 30, 51,115, 11,221, 59, 84,210, 25,236,110, 47, 92,184, 80, 96,219, -164,248, 9,163,170,140,110,112,200, 3,158, 85,128,197,241, 19, 0, 65,177,181, 2, 61,167,106,120, 74,167,134, 12, 25,162, 0, - 50,168,247,148, 50,211,223, 31,199,104,142,201, 92,252,114, 92,238,212,169,147, 98,159, 69, 32,103, 64,162,181,135, 42, 67,140, -227,151,186,118,237,122, 9, 59,168,175, 66,173,247, 26,146,177,247,176,245,122, 7, 16,116,139,103,128,197,247,240, 33,248, 26, - 11,107, 67, 64,139, 14,158, 41,113, 43, 94,188,184,178, 11, 18,106, 71, 74,196, 20,183, 57, 80, 67, 42, 54,100,148,190,177,220, -156, 67, 80, 15,126,122, 64, 75, 85, 23, 82,146, 69,144, 53, 40, 77, 66, 5,100,169, 64, 75, 99,223,168, 23,162,199,232, 28,229, -206,231,230,128, 25, 14,132, 72,162,165,190,160, 46, 58,235,253,105,211,166, 41,254,179, 56, 96,210,115, 58,255,179,227, 64,183, - 78, 67,211,250, 78, 74,227,210,241, 26, 6,170, 9, 19,183, 12,149, 41,219,135,203,247, 63,124,191, 23,171,159,116, 88,249, 76, -233,133, 93,121, 4, 88, 19,214,123, 74,189, 54, 85,196, 78,162,245, 17, 77, 39,170,195, 11, 38, 84,135, 54,154,148, 76,113,210, - 49, 42,209,162,218,131, 19,164, 3,137,150,141,102,214,244, 9,238,111, 94,191, 80, 6,121,254, 46,158, 61, 27, 72,192,115, 95, - 67,106, 67,170, 23,237, 84,135, 54,154,224,211, 45, 74, 27,207, 98, 82,229, 68,166,213,109,187,250, 77,196,100, 7,180, 28,213, - 81,129,132,201, 82, 61, 25, 48, 97,133,244, 25,189, 68, 74,212,104, 45,133, 42,181,148, 34, 85, 91, 73,185, 58, 29,164,207,216, - 21,242,231,120,248,227, 74,158,154,146, 72, 71,222,225,109, 52, 9,180,158,250,191,118, 46,209, 42,210, 72,174,222,184, 35,227, -224,210,193, 46,228,142,125,147, 10, 86, 78, 2, 45, 26, 69,115, 87, 33, 13,222, 57,201, 82,149, 68, 85, 33,183,245,211, 80, 90, -221,157, 6, 62, 89,208,182, 28,169, 14, 53,117, 20,223, 86, 71,125,187,215, 15,149, 58,130,154,112, 33,235,134, 0,139, 96, 2, -246, 45,148, 88,217,118,104,242, 62, 23, 49,108, 63,148,140,206,158, 61,155, 64,203,209, 14, 78, 91, 57,237,213,130, 4, 85,244, -171, 69,144, 69,240, 66,163,115,208,226,206, 62,170,171, 62,138,139,168, 97,170,141, 38,218,195, 38,103, 49, 14,185,141,222,153, -243, 82, 7, 42, 68,135, 14, 75, 9, 50,176,205,159, 91,241, 31, 97, 75,254, 91, 0,160, 32,246, 27, 24,135,191,135, 84,227, 41, - 65, 22, 85,104, 40,155, 81,135,165,101,225,140,244, 1,213,131,172,103,218,108, 81,146,217,187,119,111, 11, 22, 61,138, 36,139, - 32, 11, 19, 47,199,166,178, 14,198, 38,181,156,145,160,138,124, 77, 73, 9,125, 5,114,108,163,196,142, 19, 58,251, 86,253,194, -225, 20, 39,165,109,171, 38, 22,170, 10,153, 40,201, 34,200,130, 52,107,130,157,119,120, 71,223,222, 0,237,212, 66, 48,193,239, - 35,176, 34, 40,162,211, 99,128, 91, 69,202, 67,128, 69, 67,118,124, 15,119,100,114,209, 0,159,166,182, 35, 24, 77,130,166,209, -216,101,215,172,229,175,210,170,237,111,210,190, 83, 91,233,210,163,147,244,236,221, 93, 60,177,163,120,224,144,254, 50,108,228, - 16, 25,253,215, 72, 25, 63,105,156, 76,157, 62, 89,215, 97, 41,234,112, 15,190,247, 18,218,143,146,208,127, 46, 1,188, 94,135, -154,215, 7,106,217, 96,137,215,192,231, 43,104, 19,220, 41,174, 61,108,229, 84, 37, 90,116,250,204,239, 34,200,162,182,131,160, - 16, 59, 25,149, 40, 35,116, 5, 4,181,177, 2, 54,169,230,236,210,165,139, 35,160,101,163, 73, 0,181,115,236,136,143,212,133, - 4, 88,127,229, 76, 45,147, 10,164,151,189, 67,251,216,111, 36,161, 7,121, 53,244,142, 90,214,255,178, 35,208,175,229,219,205, - 0,155,127, 93, 94,110, 63,158, 2, 7,112, 65, 20,255,211,161, 39, 36, 42,180, 99,160, 67, 56, 71,161, 77, 12, 53,108, 76,126, - 57,107, 52,255, 57,104,253,245, 89, 50,126, 67, 63,105,216,161,186,140, 90,254,135, 2,178,134,204,239, 42, 73,147, 39,157,139, - 60, 41,156,117,106,245, 58, 6,139,214,215,239, 62,255,200, 24,158,160,194,224,174, 67, 91, 35,164,173, 21,252,240, 4, 82, 36, -205, 29, 83, 60,115,117,203,193,152,147,162,234, 84,148,170, 16, 78,160,244,185,211,183,111, 95, 71, 54, 90, 54,154, 89,210,199, -159, 82,182, 68,230,215,126,190,215,229,233, 35, 31,217,186,246, 47, 89, 58,187,135,203,180,122, 97, 31,169, 88, 42,195,155,220, - 89, 19,159,116, 52,240, 98,194,222, 15,191, 55,111, 29,217,146,217, 75,176,180,255,177,125,251, 45, 6, 46,120, 42,112, 60,152, -255,255,114,184,130,145,162,196,188, 85,189,113,231,183,125,199, 44,129,209,251, 30,153,176,120,175, 98,147, 85,243,215,174,111, -163,197,140,115,203, 35, 92,184,130, 78, 90,122, 48,160, 85,165,207, 38,216,104, 45,213,216,104, 13,148, 28, 85, 97,163, 85,182, -181,164, 1,208, 74, 95,164,174,180,198,110,195, 8,145,163,187, 10,243, 18,108,160,160, 3, 82,168,184, 20, 21,161, 86, 85,200, -137,150, 54, 60, 12,203, 66,176, 65,105, 22,243,129, 95,142, 28,150,126,214, 58, 2,104, 58,197,141, 24,148, 4, 99, 98, 9,178, -174,184,109,158,244,241, 13,167, 8,140, 56,201, 99, 2, 10,178,218,111,185,244,180,111, 15,158, 84,137, 22, 37, 89,164, 5,201, -142,226,242,193,128, 68,203,208,192,203,208, 59,108, 63,148,152, 18,124, 80,165,200,126,193,126,224, 64,133,232,136,166, 18,130, - 7,206, 72,169,134, 83, 66,240,176, 79,210, 15,157,213,240, 61, 3,248,192,240, 60,102, 67,240,148,194, 55,222,129, 84,253, 57, - 37, 90, 0, 9, 22, 44, 48, 20, 55, 31,152,184,159, 65, 66,114, 7, 52, 75,233,180,207,136, 0, 90,111,184,128,228,194,202,222, - 73, 41, 37, 90,191,150,136, 96,105, 88, 34,214,195,114, 48,128, 47, 91,185,238,108,170, 11, 49, 38, 85,195,152, 19,207,217,184, - 4,190, 68,196,248,152, 15,121, 26,227, 60, 16,210,155,187,180,191, 35,224, 66,200, 25, 5, 88,192,117,130, 34,229,201,153, 51, - 39, 65, 6, 29,206, 50,114, 65,124, 87, 99, 29,129, 22,220, 44, 40,246,176,170,218,145,103,140, 63, 74,226,111,222,235,223,191, -191, 80,242, 69,151, 59,122, 33,120, 80, 62,186,213,185,132, 5,219, 37,180,157, 75,176,193,162,250,208,105, 34, 24,211, 3, 90, -216,240,224,199,112,101,180, 31, 35,200,162, 79, 47, 26,251, 83,250, 70, 95,132,227,225, 0,152,188,160,109, 86,139, 22, 45,132, - 54,190, 14, 36, 90,193,129,214,152, 97,210, 43,105, 12,233,151, 42,158, 77, 93,200,118, 56,185, 64, 6,153, 81, 44,155,236,251, - 24,104, 57,170,122, 67,109,222,228,236,237,166,105,146, 97,238,236,250, 28,200, 15,253, 55,195,174,248, 35, 21,210,207,174, 31, - 74, 0,131, 81,183, 54,253, 27,217,212,132, 91,111,207,146, 63,167,183, 23,216,103, 45, 4,125,251, 88,136,124,229, 71, 13, 27, - 19, 88,122,208,105,171,186,118, 80,221, 59,152,216,117,168,165, 25, 90,187, 14,131,149, 19,146,169,141,185,179, 38, 13,202,157, - 45,121, 32,128,151,211,132, 93,134,239, 41,197, 98,178, 3, 89,246,223, 30, 13,224,225, 32,165, 83,102,146, 21,100, 69,211, 7, - 90, 74,142,200, 17, 34, 69,239, 25, 53, 70,156,189,145,163,197,188, 23, 5, 41,122,172,111,247, 2,128,245,228, 61, 23,245, 31, - 12,104, 93,189,251, 92, 1, 90,151,111, 61,146,210,191, 79,144, 43, 55,239, 75,245,182,163,229,250,109, 63,249,181,203, 8,185, -121,199, 79,114, 23, 46, 27, 24, 62, 74, 76,110,113,119,118,216, 75,180,198,195, 14,228, 5, 93, 55, 16, 76, 49,209, 22, 75, 5, - 86,148, 98,209,169, 37,207,204, 7, 94,185, 12,193,195,151,254,191,142,146,133, 74, 29,193, 86, 37, 7, 12,177,207, 32, 93, 1, -152,216,128, 87, 36,211,126, 28,239,227,250, 25,168,204, 28,222,119, 84, 71,142,164, 84, 54,191, 90, 86, 73,150, 65, 27, 45, 67, - 19, 4,193,148, 51,181,162,131,248,135, 70,104,134,102, 80,233,216,176,191,234, 7,254,237,135, 52,232, 17, 19,248,185, 31,223, -223, 15,188,115,229,155,202, 86, 78, 58, 34,165,119,122,170,119, 41,125,228,228,173,170,225, 65,227, 35, 27, 45, 35,237, 19,224, - 58, 45,104,121, 2,240,159, 35, 77, 0,184, 87,144,100,237,135,179,213,245,144, 14, 6,209,193, 51,165, 61, 0,226, 92,172, 98, - 67,162, 83,119, 54,193,248,249, 57,130, 74, 67,226,182, 8,146,212,115, 0,206,151,232,230, 65,155, 84, 41,151,246, 12,155,184, - 75,120,102,139, 29, 31,130, 73,180, 8,180, 8,244,104,140, 79, 27, 94,170, 6,233,243, 15,170, 73, 5,100, 18, 88,105, 19, 85, -157, 0,188,246,170,195, 96, 64,107,163,103,119,184,112, 24,136,221,133,253,109,246,125,108,151,251,134,246, 85, 64,214,222,126, - 93,117, 93,163, 56,154, 59, 12,204, 97,122, 89,140,180,121, 61, 26,246,247,255,203, 52,205,242,202,157,223,104,195, 6, 80,168, -149,234,199,239,247, 21,255,185,224,139,180,233,127, 56,132,255,212,177,107, 3,140,106,153,105,168, 17,154,116, 88,106,136,166, -201, 26,117,211, 4,195,254,239, 71, 43, 5,252,104, 37,181,249,209,138, 28, 51,254, 69, 56, 40,189, 24, 49, 90,156,139, 17, 34, -199,188, 20,209, 53,200, 34,235,237,249, 25, 7, 3,254,120, 76, 86,215,232,186,129, 54, 88,106,162,154, 80, 77,148,100, 89, 65, -150,203,160,210, 38,235,214, 85,246,207, 90,239,161,184,235,208, 80, 57,169, 30,116,166, 86,196, 61,167, 19,238,223,192,207,111, -240, 78, 38, 35,135,246,219, 77,239, 58,116,242, 2, 27, 77,168, 20, 35,209,230, 20,169, 9, 36, 70,157,144, 26,161,173, 38,180, - 62,151, 11,231,181,214,196,223,127, 91, 91,178,190, 56, 10,202,182,216, 62,222,161,179,255, 88, 52,236,196,115,193, 22, 12,218, -190, 73,213, 97,164, 8, 17,188, 1,128,253,212, 4,169,154,159,154, 0,108,253,212, 68, 41,150, 45, 69,137,226,109,103,163,101, -227, 39, 3,146, 83, 26,172,151,172,129,203,255,110,126, 26,105,127,122,121, 12,245, 77, 61, 34,118,247,191, 22,154, 38, 63,235, - 31,149,221,222,143,150,190,167,248, 80, 42,254,215, 82,185,238,114,134, 82,133, 91,201,184,249,233,230,103,104,113,192,221,150, - 66,139,147, 31,232,184,249,233,230,103,104,113,224,115,180,165,208, 42,219,223, 65,199, 13,180,254, 1, 43,199,208,168,248,207, -209,176,221, 52, 67,163,102,254, 79,195,205, 79, 55, 63, 67,139, 3,238,182, 20, 90,156,116,131,204,175,165, 45,133,110,141,127, - 89,106,246,187, 14,249,223,118,176, 2, 28, 37, 51, 69,116, 70,195,213,117, 61,250,110,154,142,235, 37,164,245,229,230,167,155, -159, 70,219,128,187,111, 58,231,128, 81, 30,106,243,185,249,233,230,167, 35, 14,252,151,219,146, 94,159,112,223, 55,193,129,175, - 5, 69,187,203,105,162, 82, 13,100,117,243,211, 0,147, 76,100,113,243,211, 4,179, 12,100,117,243,211, 0,147, 76,100,113,243, -211, 4,179, 12,100,253, 47,243,211, 0,123,254,177, 89,220,170, 67,157,170,249, 47, 55,108,247,183,135,110,191,117,243,211,205, -207,208,226,128,187, 45,133, 22, 39, 63,208,113,243,243,159,207,207,208, 45,225,151,165,246,233, 64, 43, 90,194,244, 25,190, 77, -153,117,118,156,100, 89, 78, 50,241, 55,175,253, 71, 1, 76, 20,124,119, 93,108,215,222,138,221,109,207,241,187,131, 3, 62,252, - 27, 58,117, 76,124, 87, 13, 36,110,151,175,138, 20,213, 96,187, 53,244,237, 69, 60, 60,194,213,242,240,104, 5, 15,141, 55,153, -248,155,215,156,188,195, 16, 77,131,229, 83,179,125, 17,154,158,109, 19,231,223,179,177,238, 70,158, 29,149,207,179, 83,226,120, -135,182,212, 28, 59,168, 85,146,184,161,244,237, 49,176,107,108, 42,119, 97,226,124, 3,105, 38,232,198,178,163,253, 69,190,221, -100,125, 56,202,238, 46,103, 40, 48, 81, 67,194,205, 79, 55, 63, 67,139, 3,159,163, 45,133, 86,217,254, 14, 58, 46,109,180, 60, -224,232,175,136,213,155, 56,230,185,143,143, 56, 41, 50, 55,205, 83,172,218,165,109,123,143, 93, 62,123,233,214,221,147,231,111, -248,172,220,176,215, 59, 83,190,114,231,121,207,197, 23,185,170,136,111,224, 85,190, 54,182,247, 46, 68, 58,101, 77, 11,121, 13, -244, 92,109,211, 14, 70, 19,147,201, 30,134,163, 49,147,240,140, 83,207,198, 6,106,167, 38,226,117, 5, 48,126, 25, 61, 27,195, -185, 41, 61,173,211, 57,162,253,225,244,219,227,196, 73, 29, 35, 90,226, 76,125, 98,125,151,115,127,204,164,153,252, 99, 36,205, -232, 31, 35,121,206,253,209, 18,103,244,228, 61, 19,252,164, 63,171,203, 72,116,244,217,197, 64,217, 93, 78,100, 13,179,123,188, -171,147,197, 67,152, 26,229,240,120, 15,231,173,219,224, 16,114, 23, 98,161,237,130,223,155, 93, 49, 98,196,216, 12, 2,157,145, -126,208,121,151,161, 14, 72, 96, 53,238,167,159,222,251,175, 94, 45,126, 29, 58, 72,143,152, 49,223,241, 90, 8,192,198, 55, 17, - 34,120,212, 76,146, 36,252,188,196,137,195,159, 79,146, 56,252,133,164,137,195, 47,136, 16, 33,108, 29,208,114,228,139, 77,125, -133,145,114,214, 69,102,198,240,100,226,111,189,227, 35,154,237,203, 38,218,120,100,251,160, 0,158, 29, 61,220,235,247, 84,157, - 14,110,239,124,157,231, 16,124,187,253, 35, 81,225,206,226, 58,226, 0,190, 99, 88, 31, 38, 56, 8,125,143,107, 55,145,145,192, -217,204,183,235,125,171,225, 54,143,140,145,195,133, 9,211, 57,106,196,136, 91, 35,133, 11,119,159,137,191,121,141,247, 76,180, -121,179,101,114,217,230, 67,131,152,149,134,145,182,100,246,117,110,154,102, 57,230, 58,191,155,159,255,112,126,234, 97,145,208, - 45,254, 23,166, 70,144,197, 87,170,103,237,235,163, 37, 72,151, 49, 95,137,234, 23,158,249, 91, 94,249,248,220,121,210,177,213, -192,173,205,219,141, 88, 53,114,218,186, 13,187, 15,159, 59,148, 33, 79,233,179,204, 99,114,130, 72, 1, 95, 42,222, 0, 42,111, - 49,137, 43, 1, 92,233,213, 26,193, 98, 5, 65, 76, 95,241, 30,232,217,123,132,119, 56, 65,208,183,202,133, 29, 91,228,246,201, - 99,114,195,235,176,192, 73,165, 18, 24,151,233,236,166,117,114,114,205, 10, 57,190,124,177,226,213,154,137, 1,115, 17,254,226, -174, 93,121,141,118,192, 36,153, 50,101,122, 67, 62, 49,164, 8, 29,237,193, 91, 62, 99,203,181,118,240,253, 14,105, 70, 75,144, -166, 88,140,164, 89, 31, 52,237, 62,225,237,250, 3,155,229,204,181,227, 72,151,100,233,182,115,210,168,243, 95,111, 99, 36,205, -246,128,121,244,248, 9,199,140,249,224, 60,214,230,244, 29,249, 25,172,245,133, 54, 1, 16,190,208, 38, 4,117,125,129, 96,174, - 87,224,111, 38,135,163, 9,151, 0, 75,206, 46, 80,210, 31,133, 61,232,189,251, 16, 94,176, 75, 77,112, 8,186, 11,113,209,118, -193,203,243, 46, 60,239, 42,206,155, 33,126, 82,138, 69,144, 5,183,232, 34, 69,138,200, 57,124, 3,175,233,125,187,221,253, 84, -137, 18,133, 63, 62, 98,120,243, 55,171, 87,207,146,141, 27,215,203,134, 13,235,100,213,202,153, 50,102,116, 43,120,193, 15,127, - 26,249,127, 52, 65,147, 18,181,129, 72,163,144, 40,185,188,168,198,250,228,111,235,181, 81, 0, 46, 35,241,219,145,244,205,246, -237,148, 96,117, 0,184,250,165,220, 79,226,255,236,174,240,204,255, 90,201, 86,217,212,169, 99,180,249, 57,203,131, 51, 94,243, - 2,121,230,127,163,109,201, 46,159,226, 71, 10, 11,142,137,112, 42,169, 4, 1, 86, 15,246,137, 57,115,230, 4,162,205,204,114, - 84,239, 78,120,147, 22,223,120, 3,126,147,130, 5,138,143,159,181,106,129,244,133, 26,244,141,151,177,114, 17, 19,229,204, 19, - 57, 66,132,219, 91,151, 76, 10,124,116,243,148,188,121,233, 39,207, 46, 31,147,219,231, 14,201,156, 41,163,222, 69, 12, 23,142, -241,253, 28,121,196,231, 43, 12,181, 37, 39,223,224,236,178,155,166, 73,134,233,100,119,243,211,205,207, 80,225,128, 43, 44, 18, - 42, 47,248, 59,137,104, 99,227,217,151, 35, 94,138,172,243, 55,239,242,186,232,115,253,206,227,243, 39,206,251,182,105,210,107, -205,111,191, 13, 88,216,160,221,152,201,163,103,109,156, 63,125,225,134,181,204, 99, 98, 34, 75, 1,112,226,135,176, 41, 74, 48, - 80,196,167, 19,134,167, 96,156,183, 89,179,102, 9,226,105,201, 28,156,147, 37, 77, 74, 48,228, 8,108,217, 75,180,252,110,159, - 60, 46,109,163,123, 40,137,161,114,212, 40,239,234, 53,158, 25, 74,135,137, 96, 11, 17,227, 67, 10,180,106,116,128,228,133,252, -130,116,231, 25,202,215, 13, 41,169,209,111, 39,128,250, 46, 91, 49,203,230, 35,199,228,222,147, 0,185,121,255,153,236, 57,121, - 78, 14,156,123, 32,135, 46,242,247, 69,153,181,106,129,164,206, 94,248,101,212,111,211,148,113, 53,145, 1, 44, 94, 70, 44, 50, - 89,188,120,177,146, 8, 88,141, 28, 12, 53, 2,135,138,148,130,169,135,141,159,246, 64, 11,177,223,130, 1, 45, 72, 71,118,193, -211,245, 46,196, 22, 36,208, 26,227,162,205, 26, 26,120, 9,170, 40,201, 34,200, 2,210, 15, 9,208, 74,149, 51,103,202, 7,247, -253,246, 65,178, 56, 89, 16,192,153,222,161,149,196, 0,189,147, 38,254,133, 80, 49, 71,165, 80,161, 31, 30,162,172,105, 13, 2, -131,129,140,227, 9,176,194,248,149,119, 16, 24, 55,144,109,134,241,217, 32,185,124, 15,224,113,135,193,145,225, 56,148,239, 33, -216,178, 63,108,223, 78,117, 33, 37, 89, 4, 89, 60,120,230,127, 94,167,154,144, 18,172,230,229,179, 61, 28,213,191,131,188,121, -237, 47, 35,251,181,151,166,229,179, 63,228,117,170, 19, 29,213,145, 71,141,165, 97, 51,151,242, 68,168, 22, 79, 85, 82, 71,128, -197,223, 74, 74,152, 56,201, 93,109,128,113,246, 51,198,240, 99, 28, 68, 72,141,181, 32,214, 85, 29,165, 69, 48,225,135,164, 3, -239,239,247,181, 31,152,165,196,175,253,159, 62,127,241,188,115,191, 73, 75,226,103,168,146,197,238,227, 29,209,204, 83, 48, 95, - 78,127,127,223, 11,242,226,210, 22,121,235,191, 93,222, 6,236, 16,239, 63,235,200,177, 17,109,228,141,197, 71,110, 95, 59, 37, -233,210,252,192,104, 19,185, 13,214,209,167, 14,151,134,218,167,201,151,184,105,154,100,152, 78,118, 55, 63,255,131,252,116,133, - 69, 66,151, 29,127, 3, 53, 87, 40, 50, 78,242,204,103, 79,158,247,185,213,238,247, 1,155, 58, 54,237,189,186, 71,167, 17, 75, -250,244,159, 54,191,239,216,101,211,134, 78, 94, 51,105,251,190, 83,203,152,199, 96,177,191,161,180,138,129, 91, 25,242,130,146, - 44,134, 81, 96,192, 93, 6, 27,101,176,234,158, 8,207, 48,125,220, 95, 50, 99,252, 56, 78, 12,148,108,185,244,246, 76,137, 22, - 37, 89, 90,160,165, 70,121,183, 7, 90, 4,118,156, 52,225,233,218, 30,104, 25, 44,190, 71, 14, 70,159,103,188, 71, 76,228,148, -100,229, 51,250, 32, 85,130,177, 82,100,126,184,233,240, 46, 89,187,127,150,108, 59,186, 85,238, 60,122, 45,151,238, 4,200,206, - 83,143,101,224,204, 57,242, 75,219, 82,210,107, 88, 51, 25, 51,173,159, 36,252, 49,211,179,216,177,191,215,170,122,130,189, 10, - 82,169,123,140,205,198, 88,122,148, 6,146,135,140, 31,199,224,196,199,143, 31, 23,196,127, 83,226, 60, 30, 60,120, 80, 16, 36, - 86,154,182,255, 83, 26, 33,190, 24, 3,248, 34,220,197, 61, 71,229,166,234,176, 67,126, 15, 69,154,213,175,124,220,215,120,254, - 16,193, 21, 19, 36,129,187, 64,139, 0,139, 32, 67, 15,104, 25, 98, 11,213,132, 61, 98,197, 10,164, 36,139,169,195, 55,223, 4, -186, 80, 29,218,211,252, 38, 65,130,240, 39, 30, 62,216, 43, 79, 30, 77,145,213, 43,190, 67, 80,222,111, 40,153, 85, 82,184,112, -223,200,146, 69,153,228,233,147,217,136, 85,121, 68, 18, 37,138,192, 54,234, 74,141,168,210, 31, 85,165, 74, 21,217,185,115,167, - 48, 80, 51, 99,250, 33,126,158, 48, 72,238,194,133, 11,109, 49,241, 24, 90, 4, 15, 80,234,229,244,160,228,138,234, 66,173, 68, -139,255,121,157, 54, 89, 84, 23,158, 62, 58, 63,144, 32,139, 7,207,167,240,159,215,121,223, 25,225,177, 11,246,151, 43,223,108, -212,239,137,115, 52,207,110,253, 38, 70, 81, 64, 74, 29, 49, 81,210,239, 44, 4, 72, 84, 25, 18,124,179,111,111,218,180, 73, 86, -172, 88, 33, 8,141,226, 80, 90, 8, 41, 88, 11,216,113,221,101, 66, 56,155,129, 0,148,247, 40,197,227,161, 2, 45, 85,146,149, - 32, 83,165, 14,235,183, 29, 60,236,123,255,209,131, 92,101, 91, 14,143,149,181,114, 44, 23, 44,136, 28, 37, 98,196,219, 47,238, - 93,148, 39,251, 39,200,219,167,231, 65, 49, 80,222,191,189, 41,123,218,253, 44,235,234, 21,145, 3, 35, 58, 97, 12,184, 35, 87, -206,159,148, 72,225,195,223, 0,173,136,134, 26,143, 59,147,155, 3,110, 14,252,235, 56,224, 10,139, 96,240,200,137, 84,193,154, -242,226,156,199,250,155,103,245, 94, 73, 77, 30,230,181,255,175,205,203,251,218,255,218,223,164,159,203, 74,171, 44,206,206,236, -103,181,117,160,218,104,105,109,181,254,127,223,213,199,197, 77,145,245,192,177, 51,215,174,118,241,156,182,242,226, 5,159,107, - 99,255, 90,186,108,250,162, 45,139,239,248, 61,186,178, 98,203,145, 57, 59, 14,156, 94,200, 60, 70,106,156,246, 87, 83,167, 78, -125, 71,192, 67,144,197,131, 19, 25,129, 1,131,162,118,235,208, 94, 58,252,218, 88, 90,213,172, 38,139, 38,142,151,134,213,171, -190,178,218,108, 57, 37, 79,160, 69,213,136, 42,201,210,130, 43,190,131, 82, 44,190,175,103,234,132,226,153,237, 7, 57, 56,111, -198,167, 0, 45, 15,196, 83,219,176, 96,193, 2, 89, 13,149, 23,212,112,207, 80, 48,103,106,211, 96,101,166, 77, 86,215,209,127, - 4, 30, 57,183, 83, 58,141,174, 44,107,247, 46,149,167, 47,222,201,201,107,254,178,235,244, 99,169,211,225,103,169,213,174,182, - 84,104, 82, 94,134,141,239, 44, 13,219,214, 10,140,145, 40, 83,127,103, 31, 14,160,229, 71, 48,181,126,253,122, 89,181,106,149, - 34, 97,161, 84, 8, 42, 34,153, 48, 97,130,192,182, 74, 6, 12, 24,160,128, 87, 6,153, 77,158, 42,131, 2, 64, 40,173, 97, 92, - 49, 23,245,117, 8,192,237, 16,212,184, 74, 66,160, 89, 69,138,213,166, 77,155, 93,205,154, 53, 83,128,150, 53,141, 49, 82,231, -174,242, 64,127, 25, 62,119,244,232,247,246,173, 92, 25, 52,184, 94,189,247,121, 99,196,240, 41,226,220, 24, 62, 24, 41,218,100, -205,157,211,246,245,171,151,199,229,242,133,116, 72,105,164, 71,183,111,109, 64,171, 99,135,228,226,115,181,152,220,184, 86, 94, - 44, 1, 7,160,234,237,242, 38,106,212,176,141, 12,148, 57, 74,152, 48, 97,110, 33, 62, 91, 16,121, 72, 73,150, 10,178,200,103, - 74, 17,113, 14, 66,156,194, 91,160, 69,213,162,238, 65,117, 33, 37, 89,157, 42, 38,222, 7, 0, 53, 97,146,103,170,140,148, 88, - 81,114,213,170, 98,150, 7, 54,137, 22, 36, 91,144,104, 61,224,117,103,134,241, 69,138,120,134, 91,182,227, 66,169,181, 7,110, -253,209,180,247,162, 41,137,242,180,232,239,241,125, 14, 2,242,240,145,126,252,165,105,209,114,181,159,108,217,178, 69, 81,145, -159, 56,113, 66, 1, 90, 44, 51,212,189,129,232, 75, 90,213,161,173,220, 8,193,114,151, 11, 16,246,151,188,121,243,190, 32, 48, -103,159,225, 1, 85,180, 34,209, 82, 37, 89,157, 60, 39, 44, 73,157,175,238,160,171, 55,238,220,222,178,199,203,251,219, 76,149, -203, 58, 99, 0,237,175,182,111, 88,240,254,253,155, 51, 18,248,246,170, 4,220, 58, 45,167,134, 54,145,131, 61,107,203,171, 23, - 39,144,206,203,179, 39, 23,101, 76,201,124, 50,161,118,117, 25,220,178,197, 59,240,190,189, 46, 67,221, 25,220, 28,112,115,224, - 95,201, 1, 29,160, 85, 65,157,127, 48, 62,247, 32, 8,226,127, 21, 88,169,191, 53,115,148,114,207,254,191,246,154,253,179, 90, -154,124, 7,159,205,159, 63,255, 66, 92,119,102,126,162,173, 7,117,215,161,249,208, 59,177,147,101, 30,180,104,245,246, 83,219, - 15,156,241, 26, 62,105,245, 34,255, 23, 47,159, 6, 88, 94, 63,219,123,228,226,234,211,151,110,109, 28, 51,121,222, 6,230, 49, - 82,235, 52,124,167, 20,198,199,199, 71,177,161, 34,200, 58,118,236,152, 28, 62,124, 88,186,182,107, 43,237, 26, 55,148,223,170, - 86,146,102,165,138, 74,191,198,245,101,116,143,174,148,106, 49,184,180,211,131, 64,139,180,156,169, 11, 57, 97, 48,253,153,253, - 71, 25, 82, 56,135, 28, 90, 48,203, 44,208,170,140, 85,254, 33, 20,160,151,181, 16, 41,147, 38, 77,250, 0,182, 74,178,104,209, - 34,137, 30, 61,250,121, 92,143,164,247,253,137,179,102,245, 90,189,103,137,204, 90, 55, 74, 86,239, 94, 37,151,239, 90,228,216, -149,231,178,237,196, 35, 89,188,231,158,140, 89,125, 83,122,204,190, 44,191,143, 63, 45, 13, 59, 55,150,158,195,250, 74,140,100, -185,248, 94,135, 7,129, 22,165, 20, 90,160, 69,137, 11, 13,244, 57,177,222,189,123, 87,177, 87,163, 90,118,230,204,153, 74,112, - 87,130,217,126,253,250,233, 1,173, 93,104, 84,187,160,106,178, 37,168,159,118,213,171, 87,207, 6,180,216,122,173,141, 87,239, -179,131,221,135,196,164, 7,118,105,158,196,249, 12,226,160,109,128,141,217, 21,216,188, 41, 19, 58, 59, 24,234,242, 6, 30,112, - 21, 12,216, 70, 47, 73,162,240,115,239,220,217, 44,190,119, 90, 43, 32,139,233,202,197, 12,178,111,119, 38,217,191, 55, 23, 64, - 86,113,185,113,189,188,220,244,169, 42, 15,252,250,201,237, 91,171, 36,105,210,112, 43,116, 10,172, 24,190, 23, 42, 84, 40,144, -129,134,199,141, 27,199,239,124,195,107, 76,173, 90,181,122, 15,181,169,210,102,161,186,125,111,189,174,107, 32,175,238, 58, 28, -208,249,199,217,251,183,180, 58, 57,236,143, 12,127,170,229,160, 77, 86, 51,168, 11, 41,217,106, 85, 49,171, 51, 27, 45, 77,177, - 61,195,212,106, 63,169,200,162, 45, 23,250,110,240,186, 63,202,115,234,174,101,113,179, 52, 90,235,145,180,116,238,116, 37, 59, -239,222,125,242,161, 95,178,239,211,189, 25, 63, 97, 98, 16, 37,113,243,231,207,151, 10, 21, 42, 16,192,216, 27,195,219,104, 2, -104,249, 17,104, 81,138, 69,245, 61, 37,163, 76,129,129,129, 2,187, 62, 5,104,125,155,185, 82,245,117,219, 14, 28,186,235,247, -240,126,194,108,213,250,140,159,181,106, 51,127,199,207, 92,137,113, 73, 29, 30, 52,118,127,254,248,154,188,123,189, 23, 18,182, -119,114,162,127,125,217,219,190,146,108,250,181,148,188,125,125, 69, 94,188,184, 46, 15, 31,249,200,156, 46,237,165, 77,170,239, -100, 30,218, 39, 36, 96,220,112,225, 62,220, 28,112,115,192,205,129, 96, 28,208,130, 32,206, 63,206,128,150,221,117, 69,162,165, -230,215, 3,103,142,222, 97, 5, 99,206, 76,132,180,101, 36,192,178, 79,198,106, 49, 94,188, 52,209,147,164,201,123,234,248,185, -107, 87,246, 30,189,176,123,238,210,141, 91, 55,108,221,119,224,246,189,199, 7, 79,157,189,114, 56,241,143,121, 78,235,236,148, -179,189,136, 59, 11,253,253,253, 21,117,215,217,179,103, 21,187, 17,236,142,146,253,176,203,106,219,160,190, 52,175, 84, 81, 1, - 89,173,138, 23,146,238,229, 75,201,188, 1,125, 9,180, 78,185, 42,169, 10,180, 28,169, 11, 85,144,197,119, 14, 43,154, 75,198, - 84, 44, 38, 71,150,206,151, 52,105,210, 24, 85, 29,230,204,147, 39,207,155,219,183,111, 75,201,146, 37, 57,233,198,178,150, 37, -115,134, 12, 25, 94, 81, 13,199, 40,244,184,214, 66,143,155,223,231, 73,247,242,228,229,211,114,232,194, 99, 57,117,221, 95,142, - 92,122, 38,155,188, 31,201,252,157,190, 82,180,250,119, 82,176, 2,236,138,172,233,231,118, 61,101,240,130, 19, 18, 61,113,230, - 0,103,116, 9,180, 90,180,104, 33,185,115,231,150,236,217,179, 75,150, 44, 89, 36, 93,186,116, 10,160,242,243,243, 83, 84,134, -107,214,172, 81,212, 94, 4, 49,197,139, 23,167, 93,153,242, 29, 58, 18, 45, 69, 85,168, 7,180, 66, 2,182, 96,223,116, 73,126, -255, 93, 36,125,122, 41, 80,160,128,180,107,215,142,155, 31,108, 64,139,118, 85, 80, 45,191,198, 55, 79, 71,162, 90,204,233, 1, - 3,248,115,111,223,250, 42, 82,171, 15, 32, 43,163, 92,189,148, 19,234,195, 48, 10, 8,188,116,161,172,220,242,169, 38,183,111, -214, 5, 24,107, 11,169,214, 81,193,174,196, 43, 58,245,164, 24,190, 19,116,236,221,187, 87,145,100, 33,255, 69, 79, 79,207,214, - 35, 71,142, 92, 14,160,250, 6,103,233,213,171,151,180,111, 15,123,170,166, 77, 9, 68, 94,232,213, 61,239, 55, 47, 17, 59,230, -208,118,121, 79, 31,219, 55,194,127, 88,187,188,167,126, 47,242,109, 52,245, 57, 3,187, 14,131,189, 34,117,217, 54, 17, 43,180, - 24,213,110,230,186, 11,227,214, 29,121, 52,103,234,154,115,155,191, 43,212,102,247,226,237, 87, 47,205,223, 19,112,225,215, 49, - 62, 39,138, 86,104,248, 60,249,247, 63,190,139, 24, 37,214,203, 48, 97, 35, 44,209,180,221,143,138,139,122,241,227,226,135,118, -105,127,252,241,135,114,166,234,148, 18, 46,168, 17, 21,160,149, 50,101,145, 72,165,235,116,155,248,220,223, 18, 80,185, 81,207, - 25,245, 90,247,159,195,223, 63, 85,110,251,151,198, 94, 44, 24,109,238, 44,124,251,250, 30,128,214, 62,121,124,114,187,236,237, - 80, 89, 54, 52, 44, 38, 75, 42,231, 19,127,255,235,242,224,225, 13,185,121, 23,106,196, 13,155,164, 81,130,132, 50,177, 85, 59, -225, 51, 70,248,233,206,227,230,128,155, 3,255, 45, 14,104, 37, 81,174, 36, 90,118, 96,137,136,204, 16,208,178,151,116,169, 18, - 45,235,187,156,109, 80, 51, 94, 9,122, 91, 42, 99,124,155, 33,117,225,242,117, 47,223,245,123,114, 97,235, 94,239,205,199,207, - 94,218,251,204, 63,224, 66,169,159, 27, 93,136,150,232,135,116, 70,223, 68,208,116,227,198, 13,236, 12,219,168,216, 57, 29, 60, -112, 64,246,109,219, 38,187,215,172,146,166, 21,202, 74,115, 43,200,234,243,115, 25,153,217,178,177,236,159, 62,217, 16,208,226, -238, 66, 85,101,168, 85, 23,246, 74,155, 84,250,231, 76, 39,195,138,229,150,128,128, 0, 37, 81,250,101, 16,104,125, 11,201,213, -221,171, 87,175, 42, 18, 12, 76, 70,199,173,223,201, 93, 97, 84, 23,174, 29, 59,118,172,162,138,195,239, 17,122, 60,136,251,125, -134, 23, 94,231, 79,201,146, 29,222, 50,120,246, 20,153,186,122,187,204,218,118, 71,134, 44,189, 46,101, 27,148, 8, 6,180, 74, - 54,170, 35,189,103,157, 54, 4,180, 8,176, 0,250,248, 77, 52,114, 23,242,119, 57, 36, 93,213,234,181,148,172,121,138, 74,237, -218,117, 20, 27, 29, 2, 48, 72,145, 92, 2, 45,218,104,209, 62,107, 68, 25, 15, 25, 87, 35,222, 43, 21,108, 57,146,104, 41,232, -200,156,100,107,100,197,138, 21,229, 66,131, 6,178, 20, 64, 8,224, 69, 73,185,114, 81, 13,254, 65,162,197,223, 4, 49, 80,115, - 1, 20, 37, 33, 95, 29, 25,155, 43,172, 78,148, 48,252,185,149, 43,151, 11,118,198,217,212,133,139, 23,102,178, 1,173, 77,235, -139,219,174, 67, 34, 9, 73,205,116, 67, 64,139,182,131,148,100,209,109, 7, 37,132, 4, 90, 80,193, 46, 86,191,215,254,140,141, - 21,148,120,185, 60, 58,212, 72, 26, 57,103,234, 36, 61,187,254, 94, 91,174, 94,220, 46, 60,231, 73,157,188, 7,175,243, 65,170, - 9,105,147,101,103, 0,239,146,102,172,148,141, 98,229,168,210,119,248,172,141,151, 23, 45,217,251,104,249,142,211, 1, 71,119, -157,123,121,177,253,236,103, 7,199,172,127,113, 97,221,145,103,119,146,228,111,179,211, 35,121,165,244, 32,228,210, 54, 13,110, - 60,252,168, 46,164,132, 22,146, 75,219, 6, 11, 74,239,176,144, 9, 49,208,138, 28, 62,252,253,103,151, 14,203,201,193, 13,229, -249,157,237,242, 58,224,180, 88,252,207,203,195,123,103,196, 51,211,247,210, 54, 89, 66,105,158, 36,145,252, 89,169,186, 28,240, -190, 44,135,188, 46,184,129,150, 94, 99,114,223,119,115,224, 95,204, 1, 87, 88, 36, 36, 18, 45,178,202, 12,208,178,207,107, 15, -218,116, 88,239,218, 97,169,145, 45,149,113, 83,100,217,117,233,250,173,163, 80, 23,174,190,118,235,193,198, 27,183,125, 15,240, -154,153, 58,167, 26,112,237,218,181, 50,105,210, 36,233,222,173,155,116,110,211, 74,186, 54,107, 42, 93,234,213,150, 37, 67, 7, -200, 90,164,109,195, 7,202,158,161,125, 97, 36, 59, 72, 54,141, 30,106, 72,117,120,106,237, 74, 27,208, 82,109,178, 40,197,234, -159, 59,189, 2,178,198, 86, 42,161,128, 44,139,197,162, 0, 45, 35,198,240, 0, 37, 91, 41, 21,162,173, 75, 3,128,131,172, 89, -179,190,206,156, 57,179, 5,106, 37,169, 89,179,166,162,130,163, 68,142,103,240, 64, 87,162, 5, 63, 89,251,230,110, 56, 37, 35, -231,142,149,178, 13,211, 74,177, 26, 41,165,203,132, 77,210,110,202, 69,105, 56,252,128,148,110,246,155, 13,108, 85,238,177, 88, - 26,121,174,209, 85, 29, 54,111,222, 92,145,100, 17,104,225,155, 20,160, 69, 59,162,170,245,219, 72,235, 94,227, 37,103,174,194, -146, 37,193,183,242, 7,212,178,176,141, 19,216, 21,185, 4, 90,246,187, 14, 97,235,115,136, 96,139, 64,171,126,253,250,187, 32, -209, 81,108,180,236, 15, 94, 51,208, 14,252, 40, 93, 35, 79,105, 79, 54,104,208, 32, 5,104,181,109,219, 86, 1, 88, 76,252,173, - 2, 48,168,233, 72,211,169, 45, 25, 84,135,243,150, 46,157, 76,253,185, 13, 80,149, 45,147, 64,206,156, 42, 35,103, 79, 85,146, -230,205,210,217,174,163,238,100,208,192,238,134, 85,135,220, 93, 72,208, 65, 59, 60, 72,220,222,117,235,214,237, 13,191,121,240, -224,193, 54,154, 84,195,242, 72,150, 44,217, 19,103,223, 62,103, 84,150, 36,195,254,200,212,103,104,219,188, 39, 9,174,182,172, -157,169, 60,179,101,237, 12, 5,108,241, 58,239, 79, 27,154, 57,169,103,251, 88,177,118,172,174, 54,188, 91,243,216, 78, 55, 64, -216,189, 39, 76,148, 52,181, 18,103,255,185,215,146,213,135, 30,110,152,185,253,241,230,126, 75, 31,237,232,189,248,217,209, 13, -222, 1,119,190, 47,214,105,143, 71,138,178,217,172, 32,203, 37,208,130,164,211,143,187,126,167, 76,153, 2, 96, 94, 91, 81, 31, - 18,108,114, 7, 48,212,138, 10,208,138,159,177, 82,149,144,168, 14,239,122,237,144, 3, 93,107,202,149,181,227,228,245,203,171, -176,153,188, 38,119,110, 67, 69,158, 40,158, 52,249, 54,158, 52, 76,144, 72, 86, 46, 92, 43,123,143, 93,151,213,107,118,186, 85, -135, 6, 58,146, 59,139,155, 3,255, 86, 14, 24,181,209,178,218, 77, 85, 80,165, 78,156,131,172,146,167, 18, 58, 18,173,220,246, -146, 43,103, 64,204, 58,175,217,232, 26,224,185,189,141, 86,112,224,101, 96, 75,229, 55,217,178,164,188,220,180,126,161, 87, 77, -106,231,127, 81,190,196,247, 79, 43,149, 73, 31,192,107, 6, 94,110,203, 66,195,118, 24, 85,191,226,251,218,255,214, 92, 90,214, -170, 41, 77,202,148,148, 22,144,100,109, 31, 55, 74,118,142, 28, 36,187, 6,245,149,107,171,123,203,217,185, 99,100, 96,243, 38, -111,141, 24,195, 31, 95,177, 68, 1, 90,237, 99,133, 85,236,177, 8,178, 20,117, 97,241, 60,242, 87,149, 82, 50,181, 65, 53, 5, -100,193, 15,148, 10,180,124,117,202, 29,181, 82,165, 74, 65,156, 20,185,123,139, 96,139,244,104, 7, 70,219, 39,170, 89,184,187, -175, 99,199,142,148, 18,209,249,105, 4, 61, 62,208, 24,190, 78,187, 81,111,183,123, 93, 1,200, 74, 33,133,126, 78, 42,173, 38, -158,149,134, 35,207, 72,213, 1, 39,165, 68,143, 3, 82,176, 98, 82, 41, 92,229, 7, 25,182,196, 75,242, 87,239,254, 70,207, 24, - 94, 5, 90,233,161,138, 83,129, 22, 93, 61,228, 44, 84, 65,114,229, 45, 41, 69, 1,190,126,249, 49,165,180,135, 26,150, 82, 57, -240,210, 52,208,130, 42,109, 23, 84,145,187, 48,249,238,130,253,151, 67,160,101, 80,178,165,216,148,209,209,235,228,201,147, 63, - 2, 92, 42,192, 2,223, 1,136,146, 74,209,162, 69, 93, 2, 45, 24,195,215, 26, 57,162,249,155, 97,195,134, 9,253,137,177, 83, -180,111,247, 35,212,133,213,161, 46,172, 39, 99,199, 20,177,129, 34,186,228,232,214,181,250,187, 40, 81,194, 54,209,171, 39,220, -143, 66, 23, 14,220,113, 72, 96, 72,169, 14,193,180,179, 3,121,157, 2,173,163, 59,106,143,161, 77, 22,213,133,148,100,105, 15, -254,231,117,222,103,190, 86,149,226, 52, 61,180,253,207, 71,109,113, 54, 80, 70,102, 81,220, 58,196,205, 88,191,106,195,238,115, -182, 44, 61,240,108,103,239, 69,143,182, 46, 59,100,185,210,176,231,146, 99, 17,190,175, 78, 79,254,220,141, 72,144,229,114,231, - 46, 22, 64,119, 41,157,165, 20,143, 42,113,110,246,224,134, 10,218,251,193,197,133, 2,180, 50, 21,109,210,155,110, 29,204, 26, -195,111,156, 50,226,189,247,216, 94,178,169, 67, 29,121,250,236,186,220,243,187, 33,151,175, 94, 81, 64, 86,131,132,137,165,123, -185,170,178,203,235,154,236, 1,208,234,217,189,223, 91,183, 49,188,193,218,119,103,115,115,224, 95,200, 1, 87, 88, 4,227,167, - 2,146,172, 41, 31,206, 9,145,212,157,135,188,206,251,225, 53,249, 20,119, 49, 46,254,171,207,168,116,121, 86,127,107,119, 43, - 42,116, 13,176,219,181,141,150,158, 68, 11,171,218,132, 77,155,212, 32,236, 0,240, 8,148,115, 94, 67,101,223,250,134, 82, 36, -255, 15,156, 20,139, 24, 40,128,154,229, 27,186,108, 88, 48,103,182,252, 53,176,191, 52, 46, 93, 66, 1, 89,109, 96,147, 69,144, -181, 23, 6,224, 62,235,123,201,205, 13, 67,101,203, 96, 79,137,110,208,189, 3,129,144, 42,201,234,147, 33,133, 12,204,151, 81, -134, 99, 39,147, 42,197, 34,200, 90,220,173,173,172, 26,240,135,156,221,190,153,160, 68, 15,104,121,192,200,253, 8,193, 20,129, - 22,165, 43,229,202,149,147, 50,101,202, 80,178,245, 18,234, 42, 2,204, 45, 72,148,100, 25,113, 25,224, 65, 59,182,232, 73,178, - 60, 24,191,252,184,252,181,104,131, 20,173,154, 70,234, 12, 58, 32,149,250,157,144,226, 61,188, 36, 79,135,195, 82,174,113,121, -233, 55,246, 15,105, 55,114,189, 68, 79,146,245,145,142,123, 7, 63,123,160,133, 29, 98,210,165, 75, 23,169, 5,117, 97,214, 36, -137,165,230,143, 41,100, 72,209,188, 50,111,112,127, 69, 29,164, 7,180,236, 61,195,227,219, 22, 80,146,133,221,107,187, 96, 63, - 69,144,181,252, 67,187,253,255, 1, 63, 83, 4, 52,158,188,174,211, 14,110, 83, 21, 55,116,232, 80,105,210,164,137, 84,171, 86, - 77,153,200, 41,225,226, 89, 5, 88,144, 16,145,199,138, 31, 44,208,163, 35, 75,103, 71,152,248,241,195,157, 94,176, 96,170,160, -140, 18, 57,114, 56, 57,125,178,146, 2,178,238,220,106, 10, 67,248,150, 80,247, 70,145,242,229,203, 67,122,214, 85,190,141, 23, -142, 6,237,206,194,251,104,223, 49,138,146, 74,110,218,128, 68, 43,136, 59, 98, 41,105,227,225, 72,162, 5,160,253,202, 89, 1, - 41,169,114, 44,209,154,105,147,104, 13,237,153,126, 80,231, 90,223,118,171, 82, 60,223,123,250,217,226,185, 77,165,216, 45, 6, -183,140,105,100, 83, 0,219, 94,216,232, 25,234,207,153,186,246,210,161,101, 7, 95, 28,159,178,246,250,229, 40,233, 27,114,119, - 33,191, 85,245,175,229,178,106, 96, 23,215, 34,114,228,200,119,153,240, 61, 3,185,211,112,201,146, 37, 50,102,204, 24,218,245, -169, 18,173,252,233,127,106,212, 51,126,198,202,157,204,184,119,136, 30, 37,242,109,223,155,231,229,241,195,107, 50,171,121,125, -105,155, 34,137,180, 68, 59, 61,122,242,170,236, 61,122, 73,214,108, 56, 32,127,100, 46, 35, 67, 74,213,145, 88,225, 35,112, 39, -167,219,189,131,137, 1,213,157,213,205,129,127, 19, 7,244,176,200, 87,253,173, 6, 62,238,155, 31, 82, 37,147,157,107,251,201, -206, 53,127,202,226,201,181,148,148,250,251,164, 92, 1,187,146,230, 56,114, 58,151,226,187,228,201,125,167,141, 30, 37,179,135, - 15, 17,207,122,181,164,123,217,226, 80, 23, 14,144, 3,195, 7,200,233,153, 35,101,203,192, 62,146,245,135, 84, 84, 27,165,112, -192,216,143, 28,150, 18,104,169,146,172, 65,249, 51,201,136, 82,249,101, 92,181, 50, 54, 41, 22, 37, 89,107, 6,245,150,205,127, - 13,147,139,251,118,209,158,201, 30,104, 57, 42,103, 50,216,223, 60,126,242,228,137,178, 77,222,234,173,222, 85,120, 28,251,162, -126, 68,147, 14, 75,147,164, 47,100, 25, 58,239,136, 76, 90,115, 66,154, 15, 89, 36,229,251, 30,147, 98, 0, 90, 85, 7,156,144, - 65, 11,143, 75,171, 97, 27, 37,193, 15,249, 2,244, 28,150, 66,146,114,175, 79,159, 62,138,234, 80,149,104,193,221,132, 2, 82, -184, 35,178, 59,212,178,173,203, 20,151, 89,131,250, 11,220, 51,192, 39,104, 17, 69,117, 88,167, 78, 29,123, 63, 90,174, 28, 3, - 82, 34, 66,199,169,189,145,202, 91, 39,111, 5,116,168,128,203, 10,180,116,191, 29, 25, 26, 0,176, 91, 8,178, 8, 92, 8,172, - 88, 22,218, 4, 97, 7,159, 34,197, 98,217,139, 21, 43, 38,105,211,166,133,173, 85, 4, 11,159,209, 16,118, 84,206, 31,243,228, -249,254,225,210,165,211, 96, 95, 52, 89, 30,222, 31, 38,126,119,187,136,223,189,158,242,232,225, 56,120,135, 31, 7,201, 76, 31, -201,147, 59,197, 35,208,113,228,134,195, 17,205,129,227,199,143, 87, 0, 43, 93, 56,192,143,212,123,170,142,157, 29,228,131,221, -199,127, 68,147,182, 88,185,211,166,168,163,181,209,202,155, 38,121, 55, 94,223,190,166,234, 8, 74,178,180, 78, 77,249,159,215, -117,190,157,183, 63, 56, 43,141, 87, 50,113,202, 66,173,183, 46,218,253,224,100,234,226,157,118,241,191, 6,100, 57,147,102,185, -116, 88,138,250,184, 79,195,127, 44, 56,130, 25,167,171,146, 45, 51, 14, 75,243,228,204,241,226,234,165,115,114,233,252, 57,105, -141,186,109,156,252, 59, 57,112,194, 71,118, 66,146,213, 47, 95, 53, 25, 88,180,166,100, 74,253, 35, 55,126,184, 29,150, 6,111, - 76,110,167,157,161, 59,179,186,249,249, 15,231,167, 1, 44, 18,186, 95, 16,186,212, 92,199, 58,212,123, 23,165, 86, 93, 58, 54, -177, 73,180,206, 30, 29, 44,123,215, 55,144, 34, 5, 82,235, 73,180,156, 53,108, 37, 4, 79,163, 42, 63,191, 26,213,169,189,204, -233,221, 93,142,205,158, 38,155, 97,159, 53,164, 89,227,183, 86, 73,150, 35,144,197,162,126, 4,180, 8,164,232,248,148,233,232, -146,249,226,181,124,145,120,173, 92,162, 0, 45, 38, 74,182,206, 64,146,117,118,247,118, 57,183,119,135, 32, 44,141, 81,207,240, - 69, 33,201,194, 46,247, 64,129,163,210, 32,188,219,182, 83, 76,143,103,246,229, 84,243,171, 33,120, 74, 55,252,243, 77,219, 17, - 27,197,115,246, 73,233, 57,237,184, 52,236,187, 74,242, 85,235,254, 6,146, 44, 67, 33,120, 48, 1, 30,230,214,125,238,218,164, -167,114,238,128,164, 77, 13,109,139,184, 19,114,222,188,121,138,127,178,205,155, 55, 75,239,222,189, 21,149,221,168, 81,163,148, - 93,101,144, 90, 28, 54, 48,137, 59,251, 68, 85, 37,199,251, 54,208,229, 12,108, 0,168, 68,132, 97,123, 62,216, 61, 53,198,121, - 96,221,186,117,239,210,229, 68, 99, 56, 79,165,218,143,128,134, 96,145, 18,195,156, 57,115,210, 38,143,110, 19,198, 35,193,251, -121,176,195, 89, 91, 74,141, 48, 59,167,230,204,110,253,250,214,205, 21,216, 93,120, 72, 2, 94,236,147,235,215,230, 34,194, 64, -243, 55, 9, 19,132,167,163,210, 52, 78, 62,198, 17,205,143, 66,240, 16, 20, 58,147,104, 25, 1, 90,234,187,135,181,207,239, 69, -117, 33,109,179, 84, 67,120,218,102, 81,109,104,147,104, 21,203,247,158,234, 67, 59, 91, 45,167, 19, 4,162, 44,164,192,174, 83, - 0,248,226, 3, 35,167,174,114, 53, 81,250,210, 3,113,173,112,142, 28, 57, 82, 89,129,152,179,122,212,155,116,210, 2,236,222, - 0,216, 12, 30,130, 39, 99,165,252,233, 10, 53,236,149, 48, 83,165,114, 14, 8, 59,163,153, 39, 74,164, 72,183,199,141, 26,243, -110,197,164,105, 50,176, 70, 29,197,248,125,230,240, 41,210,183,104,133,192, 88, 17, 34,176, 63,186, 67,240,124,204, 80,189, 58, - 50, 48, 12,125,148,197, 77, 51, 36, 92,115,254,140,155,159,161,203,207,175,153,154,107, 99,120, 35, 95,150, 58, 85,210,205, 21, - 17,171,173,117,139,106, 74, 42, 83, 50,175,240,154,206,179,174, 26,161, 45,168,116, 52,236, 70,100,162,177,188,217,160,210,112, -115,224, 69, 23, 15,102, 18, 36, 43,199, 12, 78,226,204, 86, 7,146,162, 91,176, 29, 25,109,132, 79, 70, 0,140, 26, 84,154, 6, -242,209, 19,103,242,103, 10, 65, 80,233, 44, 4, 91,176,161,185,135,228,199,196,221, 99, 76,184,254, 16, 94,192, 3,194,133, 11, -247, 10,233, 53, 38,204, 0,240,246, 33, 61,194, 91, 65, 86, 22, 35,229, 52,240,189,186, 64, 11,174, 60,210, 66,162,230, 9,251, -182,115,148,172, 65, 37,247, 10,146,172,253, 40,215, 6,168,112,131,104,231, 70, 41, 22,234,145, 64,150,110, 8, 82,155, 0, 69, -106,214, 48,145, 34,133,173, 11,247, 13,139, 16, 84,250, 98,226, 68,225, 47,225,247, 82, 56, 40,109,136, 12,148,202,133, 20,108, -240,185,186, 80,165,189,253, 20,137,150, 13,104,253,145,169,215, 7, 63, 90,153,250,216, 23,168, 77,149, 56, 77, 40,201,226,217, - 40,128, 1,192, 74, 13, 64,213, 11,105, 41,126,159,204,150, 45,199, 37,156, 15,225,255, 84,164,223, 51,102,204,152,236, 19,191, -221, 64, 19, 8,150,197, 85,127,183, 5,149,142, 26, 46,220, 3,119, 80,105, 67,172,117, 79,226,134,216,100, 56,147,155,159,134, - 89,101, 40,227,231,224,167,161, 23,255, 67, 51,133,220,143,150,253, 7,209,232, 26,215,244,236,113,212,199, 62, 71, 69,184,105, -134,110, 43,251, 84,126,170, 54, 90,218, 82,217,104, 98, 39,100, 36, 72,179, 10, 32, 53,129, 68,171, 19, 82, 35,218,252, 89, 51, -231,194,121,173, 53,241,183,171,227, 83,203,233,136,182, 33,154, 40,251, 49,168,106,253, 33,133,125,163, 26,222, 91,251, 0, 85, -202,246,126,159,156,210,164,205, 22, 13,223,121,182, 47,140,103,155, 56, 49,184,235,144,103,163, 64,139,249, 40,209, 2,168, 42, -138,115,109,164,150, 72,213,144, 10, 97, 23,231,247,184,237,202, 8,222,208,183,155,108,106,110,154, 38, 25,246, 79,109,243, 38, - 63,195, 93,239, 38, 25,230,174,247,208,101,216,127,157,154,187, 3,134,110, 11,112,243,211,205,207,208,226,128,187, 45,133, 22, - 39, 63,208,113,243,211,205,207,208,226,192,127,185, 45,133, 22, 15,255, 14, 58,161, 39,209, 50, 89,250,255,114,131,113,127,187, -201,198,226, 94,229, 57,229,128,187, 45,185,219, 82,104,113,192,221,150, 66,139,147,110,128,253, 57,218, 82,232,214,206,223, 67, -205, 97,172, 67, 50,203, 81, 50, 83, 68,103, 52, 92, 93,215,163,239,166,233,184, 94, 66, 90, 95,110,126,186,249,105,180, 13,184, -251,166,115, 14, 24,229,161, 54,159,155,159,110,126, 58,226,192,127,185, 45,233,245,137,175,245,190,249,128,210,161,240,165,159, - 3,241,186,105,134, 66,197,104, 72,184,249,233,230,103,104,113,192,221,150, 66,139,147,110,105,137,187, 45,253, 55,219, 82,232, -126,245,151,165,230, 86, 29,186,213, 82,110,181,148, 3, 14,184, 7,243,208, 29,136,190, 58,126, 34, 28, 84, 88, 35, 41,108,202, - 82,149, 99,101,170,117, 44,108,242, 50, 53,180,249,221, 11, 22,133, 3, 95, 93,189,135, 98,179,119,127,123, 40, 50,243, 63, 71, - 42, 85,170,100, 25,127, 72,153,228,183,212, 41,146,181, 74,245, 93,210,230,169,227,124,188, 27, 42,121,242,228,177, 83,165, 76, -222,144,121,152,151,207,216, 49, 74,175, 17, 70,132, 91,130, 78,112,205,176, 25,129,127,207, 97,103,215,102,184, 33,232, 4, 26, -174,188, 67,235,209, 12, 73, 93,185,164, 9, 7,154,117, 16,108,184, 21,124, 66,253,138,120,135, 13,121,134, 47,168, 86,112,104, - 90,199,197,203, 92,210,196,238,187,226, 8,246,220, 28,110, 3,154,147, 14,124, 93, 53,226,127, 94, 15, 1,205,140,216, 13,119, - 28, 46, 40, 78,225, 89,173,235, 6, 35,188, 48,195, 79,188, 34, 76, 75,184,224,216,134,179,143,245,220, 18, 47,177,247,142,111, -148,102,117, 60, 59, 11,180, 78, 51,241, 55, 18,175, 57, 58,254,118,154, 12,138,206, 20,154,229, 68,189,157, 98,250, 4,154,141, -177,243,241, 32, 19,104, 52, 54, 82,225,214, 60, 54,126,202,228,244,146, 61,145,135,146,248,219,236,127, 51, 96,195, 25,253, 16, -180,121,237, 35,229,225,248,150, 60,172,108,240,251,109,223,110, 4,100, 49, 79,210,124, 77,239, 44, 57, 26, 36,137,114, 55,190, -102, 4,104, 97, 32, 44,149, 35,108,216, 9, 56,255,130, 50,113,247,103,120,140,111, 13,177,131,117, 38,199,185, 4, 9, 18,204, -132, 43, 22,186, 31, 9,255,137,223,174, 60, 46,231, 60,226,188, 57,234,145,225,237, 97,143, 28,106,226,127, 94,183,163,111,180, - 31, 25,100,165,146,205, 8, 77,142, 17, 29,144, 90, 35, 41,193,212,117,142,143,104, 50, 60, 19, 34, 71,236, 69,180,130, 77,152, - 47, 54, 34,109,194,252,177,137,252,100,194,110,230, 45, 56,207, 53,194,207,104, 41, 60,210,197,205,240,141, 87,172, 31,191,217, - 19, 45,185, 7, 3,175,123, 68, 79,238, 81, 0,191,167, 68, 77,238,177, 45,250,119, 97, 78, 69, 77,225,177, 9,169,115,244, 36, - 30, 63, 26,161,169,247, 65, 38,238, 27,225,167, 74, 46, 37,126,208,245,208,106,107,218,128, 51,221, 23,205,224, 39,105,222,105, -134,166,209,162,126, 14,154, 70,223,253, 79,204,103, 47,209,162, 3,211,255, 31,154,248, 66, 69,120,149,128,169,123,231,246,107, -111, 92,185,180,238,246,245, 43,235, 54,172, 89,185, 41, 86,204,152, 43,208,168,143,192,211,104, 64,138,168, 81,253,225,247,104, -127,204,152, 49, 22,111,217,176,118, 35,243, 48, 47,159,177, 3, 91,174, 42, 34,109,162, 68,137,142, 34,198,218,237, 27, 55,110, -248,190,121,243,198,247,226,197,139,190, 8,214,123, 19,239, 57,138, 98,164,117,194, 73,189,202, 45,148, 40,110,152,129,105,146, -133, 61,146, 38,166,199,145, 68, 81, 60, 6,130, 78, 33,179,157, 90,155, 31,157,251,208,213,171, 87,233,201, 60,136, 78, 81,127, -249,229,151, 32,254, 7, 40, 34, 48,112,118,184, 44, 39,188,211, 95,164,111, 38,184,203,184, 2, 2, 56,253,120,133, 52,121, 61, - 4, 52,189, 30, 63,126, 44,183,111,223,166,171, 5,111,147, 45, 80,143,159, 42, 57,250, 61, 91, 13,103,175,171, 16,158,165, 21, - 98, 0,246,135,179,212,190, 8,149,179, 18,215,215, 33,147, 22,108,233,209,140, 3,112,177, 12,245,191,123,206,156, 57, 83,207, -159, 63, 63, 23,129,171,151, 0,104, 46, 77,151, 46,221, 1,222, 3, 61,179, 19,132, 66, 19,206,117,119,207,157, 59,119,214,185, -115,231,230, 3, 12, 47, 93,191,126,253, 50, 68, 47,216, 31, 82,154, 24,220,151, 34,128,233,118, 4,216, 30,123,235,214,173,137, -136,117, 57,227,240,225,195,179, 16,142,105, 55,239,133,180,156, 88, 92,236, 64,204,199,191, 78,159, 62, 61, 25,237,126, 38,130, -129,207, 70,221,239, 54, 83, 78, 76, 42,197,208, 15,223,225, 16, 38, 76, 52,129, 88, 4, 4,192,239,155, 45,193, 7, 88, 0, 19, -248,226,203,252,142, 6, 94,130,159,191,254,250,171, 98, 72, 18,159, 53, 50,152,171, 64,110,196,136, 17,149,237, 19, 66,253,252, -204,251, 38,251,123,229,226,197,139,159,196, 51, 45, 16, 23,243, 58,186, 18, 3,190, 95,194,255,182, 8,140,125, 28,188,168, 97, -164, 31, 25, 5, 90,169, 10,183,126,180,212, 91, 68, 57,107,164, 96,206,190, 61, 91,152, 48,227, 94, 87,171,246,118, 92,250,244, -135, 49, 75,247, 4,192, 90, 59,100,200,144,163,104,147,222, 24,235,188,207,156, 57,227,221,181,107,215, 35, 0, 11,107, 64, 35, -165,201,111, 15,150,157, 96,234,197,126,143,162, 15,119,120,116,126,176,221, 99,160,154,248,159,215,237,192,150, 94,223, 52, 57, -124, 40,217,141,208,244,100,176,242, 30, 61,122,176,158, 9,182,244, 14,123,154, 29,225, 52,122, 39,234,217, 27,227,143, 55,226, -205,122, 35, 34,136,146,224,176,218, 27,142,169,189,225,152,218, 27, 0,150,161,209,156, 29, 54,154, 81,147,121,108,156,119,227, - 87,233,114, 44,145, 68, 73,233,177, 38, 74, 50,143, 21,101,218,166,145, 9,199,235,200,130, 59,205,100,229,243,150, 50,227, 90, - 29,233,188,180,160,100,175, 22, 63, 16,192,140,243,136, 35,159,124, 70,190, 93,239, 91,237,239, 27,166,137,254,191,131, 81, 81, -232, 84, 91,155,224,191,144,124, 30,105,164,111,218,189, 60, 37, 66,204, 29, 32, 93,107,187, 76, 9, 96,187, 31,237,247, 60,254, - 87,182,203,107,184,156, 70, 25, 96,143, 69,140, 62,247, 15,205,247,113, 80,105, 22, 84,117,127, 79,233, 20,129, 83,222, 92,217, -167,198,137, 29,115, 50, 24,239,143, 73, 53,240,197,139, 23,242,112,240, 96,185,135, 32,189,152,116, 24,132,246,109,204,152, 49, -159,197,139, 19,107, 52,243,242, 25, 62,107,160,114, 35, 18,100, 17, 88, 97,130,240, 69,224, 98, 5,100, 33,198,156, 47, 38, 93, -223,109,219,182,249, 98,181, 71,176,229, 72,178,229,172,114, 19,254,152, 44,156,215,200, 62,191,188,184,112, 96,156,188,184,189, - 89,252,143,174,146,179, 11, 6,202,224,166, 21, 94,252, 24,235, 27, 47,208, 83,253, 55,153,106,216,112,242,249, 19, 36, 89,247, -219,183,111,175,248,173,164,147, 77, 76,222, 12, 17,148,210, 72,167,118,148, 7, 82, 50, 5,104,241,140,251, 63,242, 76,160,101, -253,175, 59, 80,216,101,240, 83, 29,106,226, 58,203,101,230,176,231,103, 24, 12,254, 19, 1,168, 30,162, 14, 8,122,111, 96,130, -246,129,179,211,251,144, 96,110, 14,176,188, 58,243,232,241,211,115,221,123, 15,107,142,122,234,130, 65,110,101,217,178,101,215, - 82,210,101,160,222,149, 44, 4, 19,136,117, 56, 27,177, 36,231, 46, 93,190,106,227,178,149,107,129,177,182,108, 64,253,111, 69, -240,238, 35,127,254,249,231,122, 43,224,208,126,135,203, 78,205,252, 0,194, 11,224, 13,127,225,130,197,203, 54, 46, 92,186,106, -195,186,117,235,215, 0, 20,173, 7,205,189, 33,161, 73, 32,133,136,240,211, 48,168, 79,246,242, 62,177,244,228,153,115, 75,208, - 78,231,223,188,121,115, 49, 6,248,205,104,255,203,173, 96,203,112, 57,145,113,105,229,202,149, 9,214,166,206,153,191,112,217, -188,133, 75,151,173, 92,185,106, 33, 98, 62, 46,193,128,185, 21,146,205, 21, 70,191, 29,117,116, 27,116,100,217,178,101, 74,162, -199,125,251,195,242,242, 67,196, 4,246, 87,128, 45,109,236, 72, 27, 63, 9,114, 8,178,240,108, 14,179,201, 14, 32, 57,172,163, -192, 73,233,133,224,138,128, 10, 19, 98, 46,251, 4,103,182,185, 93,128, 45,135, 52, 17,195,210,139,224, 10,160,218, 82,186,116, -233, 39,252,205, 51, 34, 35, 88, 16,159,212, 82,163, 70, 13, 74, 72,117,251,145, 81,160,149,178, 80, 75, 95, 2,173, 12,101, 58, - 7, 32, 0,122, 56,245, 57,103,109, 62, 3,194, 71, 17,100, 5, 86,175, 30,228,153, 54,237,147, 65, 29, 59,222,124,251,246,173, - 55,156,246,122,163, 13,121, 35,200,187, 55,198, 58,111, 52,124,111, 76,100,244, 37,231, 40,148,153, 35,169,206, 8,244, 67,127, - 60,115, 23,253,244, 14,210,221,130, 57, 98,220,255,163, 89,148,231,203,134,135,127,189,102,212, 55, 65,108, 3,155,199,121,188, -184,181,209, 99, 35,193, 22, 37, 91, 70,251,166,171,129, 35,102, 50,143, 84,209,190,247, 88,244,125,225, 40, 15, 0, 60,180, 96, -201, 81, 29, 85,199,152,177, 0,244, 42, 91,105, 46, 70, 61,139,117,142, 89,108,189, 86, 28,253,103, 38,126,231,119,240, 94, 45, -205,182,232, 51,155, 9,178,152,170, 87,175,238,141,168, 24,222,104,251,222,232,239,222, 88, 84,121, 99,225,231,141, 5,187, 25, -160,117,114,203,203,238, 50,236, 89,114, 73,154, 35,218,187,113, 71,234,201, 90, 75, 43,153,230, 95, 72,254,122,158, 73, 70, 61, -251, 65,198, 63,207, 38, 51,252,139,201,162,231,181,165,246,208, 12, 2, 73,215, 86,140,248,145,236,202, 26,234, 96, 3,244, 13, -211, 36, 40,218,179,103,143,112,238,176, 79,160,163, 93,116, 27,165, 57, 3,227,165,236,220,185,147, 64,109, 6,162,118,248, 62, -125,250, 84, 25, 91, 32,112, 96, 44, 82, 51, 99,157,153,121, 72,201,251,149,135,224,177,255,222,143,129,150, 21, 73, 22, 97, 78, -170, 2, 41,165,250, 54,118,236, 9,213,171, 85,195, 56,253, 74, 25,191, 25, 83,208,167, 68, 9,185, 94,160,128,144,249, 76, 12, -188,156, 42, 69,138, 23,241,227,196, 26,193,103,248,172, 94,167,166,186,112,220,184,113,183, 65,210, 23,180,125,253,252,252, 20, -160,133,142,227,139,144, 49,202, 25,241,240,110, 90,213,136,246,133,119,212, 96,190, 75,155, 58,193,221,187,167,103,128,226, 92, -145,147,152, 51, 14,164, 17,233,146, 72,100, 88, 65,145, 13, 3,196,103, 65,159,160, 31,146,196,189, 11, 98,223,233,116,106,103, -141,163, 34, 98,241, 5,146, 15, 56,211,139,121, 37,157, 86,228,178, 97, 67,130,117,145,113, 20,237, 37, 90,188,238,130,174, 51, -154,161, 5,180,194, 0, 56, 79, 5, 96,121,202,137, 11,147,191, 5,224,218, 2, 0, 96, 65,120,156,199, 11, 22, 44,104,253,240, -241,243,243,247, 30, 60, 57,222,185,231,192, 90,115, 70,141,170,114,231,250,245, 63,160, 86, 93, 76, 53,162, 94,189, 91,239, 87, -135, 36,112, 23, 64,213,236, 83,231,174, 92, 58,115,225,250,181,149,235,182, 31,218,178,125,247,129,189,123,247,109, 66, 92,201, -101,152,144,206,195,195, 57, 85, 97, 90, 53,162, 43,126, 86,167, 36, 11,131,238,130,211,231,175, 94, 60,119,233,250,149, 21,107, -183,237,219,184,121, 39, 3, 97, 91,112,125, 17,164, 8,199,243,228,201, 99,138,102,222,188,121,183,195,147,253, 36,191,251,143, - 79, 63,121,250,226, 28,105, 49, 65,170, 53, 31,192,101, 50, 22, 9, 7, 49, 1,236, 53, 83, 78,172,184,183,163,125, 79,241,245, -123,116,235,254,131,199,119,150,172,222,188,109,237,134,109,155,182,109,219,177,144,224, 11,229,164,103,119, 67, 52,177,234,244, - 99,240,107,174, 94, 47, 32, 30,167,151,151,151, 44, 95,190, 92,102,206,156, 41,211,166, 77, 19,212,151,164,207, 81, 72,137,113, -201, 80, 77,136, 24,160, 5,225, 95, 4,104, 17,100,105, 1,150, 51, 32,167,130, 45, 59, 9, 25,155,140,125,189,171,146,172,133, - 4, 89,168, 91,203,232,209,163, 45,108,175, 24,195, 20,144, 69,176,133,231, 22, 66, 66,184, 31,231,202,174,250,187, 10,152,176, -152,226,216,119, 0,233, 20, 38,255, 25, 0, 48,201,181, 32, 44, 66,170, 10,107,230, 29,120, 45,245,254, 88, 42, 97,147,149,105, -164, 7,180, 64,231,155, 76,144,182, 13, 76,147,230, 58,192,150, 44,172, 92, 57, 96,234,160, 65, 55,209, 87, 20,160, 69,144,128, -177,206,251,200,145, 35,222,191,255,254,251, 33,188,191,169,129,113,105, 52,164, 58,143, 57, 6, 49,232, 55, 22, 0, 10,136,126, -253,228,160, 60,187,216, 85,182, 77,142, 38, 19,187,127, 8,139,197, 51,193, 22,165, 91, 84, 37, 26,236,155,142,135,158,196, 30, - 81, 32,241, 25,151,179, 78,236,119,158, 94,217,101,170,255, 79,146, 60, 95, 36,142,165,234, 97, 95, 71, 89, 17, 94, 43,136,147, -245, 79, 63,253,196,144, 90, 81,144,236,129, 86,100, 56,213,125,198, 5, 2, 36,145,129,184,159,217,238,229, 54,154,152,224,119, -171, 32,139,231,150, 45, 91,122,175, 88,177,226, 35,144,229,235,235,235,141, 5,188, 81,137,150, 13,104,205,185,220, 92, 22, 6, - 84,151, 1,183, 83, 74,137, 94, 49, 36,105,129,112,129,241, 50,132,125,149,182, 82, 68,169, 57, 45,142,140,121,158, 78,230,191, -168, 44,205,166,102, 19, 72,194,180, 49, 72, 29,181, 79,157,105,193,208,109,163,160,136,196, 82, 34, 45, 65, 91,127,181,120,241, - 98,193,152,173,204,211, 4, 93,184, 78, 77,131,179, 58,114, 86,144,213,148,140, 89,181, 43,175,158, 61,123, 38, 16,132, 8, 36, -250,140, 63,187,202, 89, 29, 25,250, 42, 3,153,190,114,137,150,190,234,144, 60, 80,209, 36,237,174,214,173, 94,177, 25,234, 13, -127, 86, 26, 25,207, 78,141,201, 81, 16, 56, 78, 73, 23, 46, 92, 80, 86,201, 0, 73, 74,140, 61, 76,208, 79,182,110, 92,183,145, -246, 92,122,252,132, 24,114, 51, 58,133,175, 51,160,133, 78,228,139,138,245,197,170, 77, 47,196, 15, 95,245, 77,146,248,223,156, -185,115,114,170,200,165, 14, 34,187,227,137,236, 77, 44,178, 63,133, 72,135, 56, 34,109,163,139,180, 12, 15,187,147,234,114,109, -102,199,160,164, 81,195,157,225, 51,122,101,180,187,159, 26,129,155,149, 32,187, 60, 58,117,234,196, 64,206,244, 8,238, 44, 92, -140, 46,121,170, 29,217,152, 33,193,120, 10, 27,173,155, 60, 27, 80, 71, 58,163,171, 5, 90,239, 17,122,229, 81,228,200,145, 23, - 34,179,253,234,203,101,185, 40,201, 82, 65, 22, 39,174,129, 3, 7, 90, 48, 89, 91,246,239,223,111, 97, 88, 31, 76, 16,253,254, - 24, 58,173,237, 31,127,142,174,127, 96,227,198, 78,183, 14,236,233,245,252,148,119, 91,228,189, 67,155, 45,221,143,254,144, 97, -214,244,233,211,199,205, 89,180,124,245,153, 75, 55,174, 93,186,122,235,238,142,189,135,125,188,142,122,223, 58,119,204,251,204, -133, 83, 39, 55, 3,192,239,192,187, 56, 73,186, 82,205,106, 95, 7,173,196,172, 25,243, 22,175,220,120,230,226,141,171,151,175, -221,190,185,117,215, 65,198, 56, 84,128,209,217,227,199, 86, 96,176,216, 8, 9,194,110, 51, 52, 33,109, 24,117,212,251,228,146, - 71, 79,252, 47,248,191,120,121, 77,165,247,252,233,211,173,143, 31, 60,152, 5, 16,186, 20,210, 45,182, 81,195,229,132,186,112, -204,172,121, 75,150, 3,188,221,125,240,240,169,223,230,157,251, 79, 28, 60,112,240,216,169,195,135,182,157,241,246,154,131,114, - 46,195, 10,221, 16, 77,244,143, 39, 7, 14, 28, 80,130,136, 91, 0,166, 80, 95, 10,216, 82,227,123, 66, 29, 41,109,218,180, 17, - 6, 31, 7, 40, 17,132,101,122,230,168,142, 84,213,161, 61, 8, 66, 63,101,115,119, 45,229, 10,174, 58, 12, 70,158,210, 46, 21, -100, 57,162, 99, 79,159,146, 46, 7, 64, 43, 24, 77,173, 36, 11, 55, 54, 67,202,108, 1,104,177,156, 61,123,214, 2,190, 89, 0, - 50, 89,231,155, 33,161, 83, 22, 9, 8, 88, 78,201,184,211,131,128, 9,109,183, 45,212,195,129, 0, 65, 66, 21, 60,249,246,235, -175,191,190, 67,152,168,210, 42,160, 10,155,188,116,205, 95,186,206,151,197, 71, 3, 37, 99,185,174,175,163,164,174,152,157,247, -116,218,252, 55,169, 17, 38,107,110,249,242, 1,129, 53,106,200,130,159,127, 14,248,171, 79,159,155, 24, 59,109, 64,139,128,129, -128, 11,117,233,202,182,136,175, 25, 86,165, 74, 21,142,153,202, 1,169,142, 48,214, 41, 37,154, 23,142, 45, 16,159, 67,205,212, - 91,193,206, 14,128,150,193,110,250, 33, 91,148, 20, 30,137,226,165, 11,119,188,245,202,116, 10,192, 26,121, 61,143, 20,106, 25, - 95, 34, 39,240, 24,227,132,208, 55,224,229, 25, 72,151, 4,253, 71,114,231,206,205,250,224,241, 17,208,194,247,188,161,164,132, - 11, 2,204, 31,236,155, 14, 15,140, 75,155, 97, 2,224, 93,191,126,125,111, 44,192,189, 1,172,189, 17,219,245,131,250,181,123, -239,155, 57, 10, 22, 11,136,151, 44, 69, 96,156,196, 41,222, 71,141,157,244,105,248, 40,113,154,129,144,203, 49, 30,128,201, 6, -180,198, 63,207, 46,221, 79, 39,150, 4,217,195, 6, 70, 79, 26,214,127,236,196,209,103, 32,121, 60, 58,119,193,156, 83, 53, 26, - 87,124,144,163,113, 20, 25,241,228, 7,153,247,188,138,100,174, 20, 39, 80,181,233, 50,197,200,207,151, 57, 37,165, 78, 4, 68, -108,191, 11, 23, 46, 84,230,107, 43,208, 90, 29,130,215,218,128, 22,129, 27,105, 18,100, 1, 11, 80, 26,158, 50, 4,244, 76, 61, -242, 47,147,104, 5,255,118, 13,138,244,228, 29, 26,185,211, 38, 11,131,182, 34,193,225,170,153, 3,122,155, 86,173,222, 99, 69, -254, 28,210,131,103,221,187,118, 13, 98, 39, 97, 69, 16, 51, 53,109,218,244,117,140,232,209,103, 57, 50,154,183,231, 52, 64,198, -105,130, 44, 38,216, 83,124, 36,209,130,141,137, 34,213, 66,231,163,129,171,222,241,203,208, 73, 85,159,189,124,177,236, 94,208, -238, 56,143,100, 95, 50,145,131,105, 69, 14,103, 22,233,249,189, 72,215, 36, 34,237, 99,201,171,166,177, 31,249,204,216,122,173, - 93,217, 22, 79, 65,144, 6,170,134, 15,148,119, 14,191, 19,101, 13, 98,131,230,121,245,234,213,180,209,154, 99,152,200,199, 25, -191,135,154,240,158, 86,220,203,255,200,198,208, 41,102, 15, 27,208,194,170, 67, 25,104, 9, 10, 65,228, 76,166, 76,153, 30,161, -190,168, 54,213,237, 36, 84, 23, 18, 96,169,169,127,255,254, 22,172,156, 45, 88,117, 91, 80,182, 59,104, 3,125,183,236,216,213, -125,193,216,177,181,110,236,220,222,219,114,226,232, 20,185,113,117, 33, 6,165,245,118, 18, 45,167,229,167,225, 55, 6,200,201, - 51, 23,174, 89, 89, 48,119,170,215, 37,127, 74,253,190, 90,169, 76, 65,245, 42,102, 15,106, 88, 49,107, 96,157,210, 25,223, 62, -127,252,120, 61,164, 90,215,172, 6,242,186,188, 96, 62, 76,180,115,230, 44, 94,183,113,241,234, 93,251,183,238, 62, 68, 48,173, -128, 44,251,132,247,223,209, 37,136, 12, 48, 46, 63,133,201,226, 47,239, 19,231,104,135,229,144,150,197,223,127, 42,164, 90, 39, -152,215, 8, 77,126, 59, 36,118,227,103,204, 91,181,220, 25,205,135,190,190,211, 33,213, 58, 97, 53,144,119, 73, 22,117,253, 10, -210, 16,129,244, 79, 0,214, 5,246,110,202,226,103,235,214,173,178, 99,199, 14,161, 74,161,102,205,154, 12, 19, 36,144,188, 9, -104, 82, 18,251,209,225, 10,104,233,130, 45, 29,160, 69,149,161, 51,176, 70,218,246,244, 93,216,106,169,229,110,171, 74,178, 8, -178,112,113, 51,193, 21, 0,111, 48,144,133,246, 99, 33,216,194,253, 22,174,152,136,182,211,191,121,243,230,130,252, 54,128,130, -252,106,152, 49, 74,109, 88,183, 74,250, 38, 78,250,253, 61,167,122,201,164,205, 15, 36,108,202, 50,192, 89,186, 64,203, 3,223, -183,117,230,176, 97, 55, 41,209,162,100,107,110,133, 10, 1, 67,187,116,185, 9, 9,163, 2,176, 32,193, 86, 64, 23,128,214, 86, - 87,229,132, 84,231,153, 22, 65,253,246,219,111,138,186,152,129,227,175,158, 94, 42,183,142,254, 38, 91, 39, 69, 53, 34,209, 50, -210, 84,149, 60, 81,147,122,100, 78,154, 39,226,189, 62, 71,178, 41, 32,171,225,148,212, 18, 55,125,216, 91, 17,227, 40, 70,237, -206,226,104,230, 34, 80,197,152, 33, 80,215,147,143, 61,172, 47,252, 72,117, 8,222,247, 99,249, 9, 22, 25,244, 30,249,114, 59, - 42, 28, 52, 32,155,239,223,191,239,141,239,245,198,184,171,128,172,205, 91,182,157, 74,151, 53,159,165,108,141, 22,129, 91,240, -252,169, 43,222,114,238,154,143,172,220,113, 78, 10, 87,168,253, 50, 66,140,196,135, 61,162,196, 11,110,140,172, 33,174, 5, 90, - 67,159, 36,151,165,143,154,202,154, 39, 29,100,246,149, 38,146,189,204,247,175,208, 7,189,218,181,107, 71,251, 47,175,198,109, -234,248, 85,155, 16, 91, 38,251,231,149,142,171,115, 73,148,228, 30,125, 13, 51,241, 51,103,196,130,122, 53, 53, 75,170,212, 9, -182,137, 47, 63, 17,104,173, 83,159,167,116,140,192,141, 52,241, 25,140, 67,155,242, 51,127,142, 34,236,177, 38,207,207,253,174, -127, 4,125, 26,190,195,184, 80, 17, 67,194,158, 64, 58,182,111,255,158,149,138,194, 37, 71, 74, 13,253,251,246,241,227,198, 5, -209, 16,143,186,119, 2, 15,128, 48,173,168,210,233,119, 96,226, 63,163, 5, 90, 48, 44,182,169, 14, 49, 97,248, 18,104,237,219, -183,143,118, 90,174,236, 44, 20,250,209, 99,121,204, 61,117,103,176, 92,148, 66,114,250, 93,116,255, 23,231, 51, 28,148, 35,185, -222,137, 23, 84,134,253,179, 73, 96,239,140,239,206, 55,108,115,112, 77,222,201,254,219,170, 44,148,245, 93, 23, 73,212,176,145, -245, 86,143,193,202, 78,117, 30,121, 1, 67,227,135, 40,223,101,156, 31, 16, 32,233,168,249,140,212,227,143, 88, 41,252,133,193, -248, 2,207,120,192,213,238, 22,123,122,180,137,162, 42,104, 28,207, 28,132, 89, 87, 80, 65, 8,212, 39, 2,245, 22, 69,189,202, -111,216, 82,113, 16, 35,136,163, 65, 99, 62,103, 5,163, 77, 22,165, 3,148,100, 17,100, 77,156, 56,209,130,201,192,114,234,212, - 41, 11,140, 88,159, 67, 13,176, 15, 82,135,229,190, 80, 23, 62,221,191,183, 67,224,213, 11,139,228,205,235,187,176,183,226, 46, - 68,173,141,150,211,111, 39,128, 0,239,102, 45, 94,186, 98,193, 79, 57,146,188, 61,177,109, 69,208,229, 61,235,228,246,161, 77, -242,240,192,242,160,230, 63,103,123,247,234,209,131,205,152,248,174,155, 1, 90,176,209, 88,180,106,245,186, 85,107, 55,237,221, -117, 96,207, 33,182,155, 79, 6, 90,216, 92, 48, 5, 82, 18,182, 21,135,180,222, 6, 4, 76,199,160,116,206, 12,208,130, 52, 99, -234,178,101, 43,231, 59,163,105,185,127,111, 22, 85,167,206,128,150,118,103,160, 22,104, 65,114,163, 72,157, 39,206, 90, 33, 69, -171,252, 38, 25,179,229, 21,174, 72, 1,116, 4,253,214, 37,208,114,102,163,101, 5, 65, 31,129, 33, 45,112,114, 6,140,180, 42, - 67, 87, 64,139,237, 86,121,143,117,231,163, 78,167,169, 76,131,119,218, 98, 65, 82,166, 72,178, 8,178,212,133, 1,234,203,194, -235,148,100, 17,140, 21, 46, 92,248, 49, 13,229, 65,179,188, 11,186,167,236, 69, 65, 4, 93,152, 96,133, 99, 27, 37, 92,148,218, - 99,162,151,158, 61,255,120,144,163,106, 31,161,173, 86,226,220,141,175, 26, 1, 90, 0, 72,219,208, 7,189, 9,182,134,102,207, -174,128,173, 89,101,203, 6,120,182,110,125, 19, 27, 63,188, 49,214,121, 99,172,243,198,162,210, 37,208,130, 84,199, 23, 82, 29, -129, 84, 71, 32,213,145, 81,163, 70, 41,118, 52, 88,180,200,245,243,235,229,238,201,158,114,123,127, 49, 5,108,241,112, 97,163, -101,100, 92,242,136,148,194,227,187,148, 5, 35, 63, 25,126, 37,143, 2,178,170, 12, 74, 46,145, 19,121,172,240, 8,231, 81, 0, - 4,236, 55,170,104,105,254,142, 13, 30,202,152, 3,105,214, 11,220, 80,109,207, 28,217,104, 69,197, 2,253, 21, 54,194,200,208, -161, 67, 57, 70,105,237,123,109, 52, 9,180,104,236, 78,112, 74,219, 54,208,247, 78,159, 45,191,101,204, 92, 44, 44,238,223, 22, -223,199,175,229,220,205, 23,178,231,204, 19,217,125,250,145,108,220,185, 74, 58,252,217, 37, 40, 74,220, 68, 92, 96, 58,148,108, - 65, 42, 53,245,207,131, 5, 20, 27, 45,166, 17,207,190,151,145,207, 82,137,231,213,228,146,163,252,119,168,254,151, 94, 88,156, -208,200,222,107,199,174,237, 71, 83,149,140,168,168, 16,199, 92, 42, 65,245, 33, 77, 18,254, 17, 7,237,166, 40,240,208, 72,157, -102,176,221,114,145,133, 2,114,231,161,217,195, 91, 5, 90,170, 54,139,255,105,183, 69,123, 48,179,196,220,249,117, 56,144, 56, -122,116,255, 71, 24,164,111,148, 46,173,168, 10, 33,189,161, 36, 40,149,230,177,140,176, 37,121,118,187,118,109,185,154, 37,139, -146, 39, 41, 12, 51,141, 48, 86, 11,180, 28,217,104, 65,138,226,139, 85,139, 33,160, 21, 59,190,135,207,131,119, 75,228,148, 36, -144, 19, 18, 83, 78, 75, 74,241,121,153,239,206,187, 11,213, 47, 62, 28,216,254,226,158,250,139,239,108, 42, 59, 71,214, 22,152, - 42,107, 11, 78,147,227, 35,247, 72,204,176,209,141,170,185,148,207,161,129, 58,129,150, 73,195,117, 35,172, 8,113, 30, 72,144, -252, 40,158,135,202,145, 29, 74, 49,128,101, 7,163,244,130,224,138,131, 23,127,179,147, 80,157, 68, 59,157,163, 71,143, 10,192, -203,113,103, 47,165,225, 59, 6, 24, 69, 93, 72, 73, 22, 58,175,101,211,134,117,150,170,197,243, 89, 42,149, 42,170,216,192, 0, - 20, 31, 2,136, 91,132,119,220,194, 42,106, 3,140,142, 55,113, 55, 34,104,218,187,120,112,246,154, 89, 27, 54,108,152, 11,233, -216,226,130, 89, 98,189,190,178,103, 69,208,157,177, 37,130, 30,206,172, 31, 20, 48,183, 81, 96,235, 74, 57,222,137, 37,224, 48, -164,168, 84,249, 24, 86,201, 65, 77,177, 4, 3,241,186,237, 59,118,175, 61,129,165,152,207, 49, 47, 74, 33, 20,128,244,234,216, -145,245,242, 50, 96, 39,120, 98,138, 38,232, 77, 7,120, 89,120,227,214,237,133, 80, 23,110, 87,233,189,245,127,182,243,253, 3, -191,197, 0,153,235, 49, 1,211,158,202,112, 57,215,174, 93, 59, 19,223,190,104,211,150,237,139, 78,236,223,191,243,154,215,225, - 99,119,189,143, 28,127,118,226,232,174,151, 94,135,151, 74,128,255, 70,124,251, 62,103, 52, 9,108, 6, 15, 30, 92,133, 9,160, -250,141, 42,209,194,132,173,168,188, 42, 52,233, 39, 21, 43, 55,150, 98,105,211, 74,227,210,197, 21,201, 22, 84,134,159, 4,180, -108, 96,200,129, 26,209, 21,208,114, 37,205, 34,176, 82,129,156, 74, 95,175, 51,208,133,131, 86,226, 74,117, 33, 37, 89,188, 6, - 3,117, 5,120,169,137, 82,216,247,239,223, 43,247,172,174, 31,156,145,183, 1,173, 41, 83,166, 40,187, 55,121, 32,179, 54, 93, -198,255, 16, 73,180, 8,180, 64,206,155, 96,107, 82,255,254, 55, 85, 53,226,140, 82,165, 2,186, 52,110,124,147, 70,221,148,208, -232, 1, 45,244, 77, 95,130, 61, 74,177,184,168,197, 51, 10,200,162,125,222,205,235, 39,228,254,181,101,242,240,188,167, 60, 62, -215, 73,134,119,140, 26, 64,149,161,147, 93,135, 90, 62,124, 3,163,246,170, 48,242,166, 75, 25, 27, 32,137,149,210, 35,214,183, -153,195, 95, 30,112, 42,135, 2,178, 42, 15, 72, 70,144,197,157,192,105,244,250, 57,218,228, 20,238,126, 38, 40,196,194,251,144, -230,101,142,128,150, 71,190,124,249,206, 80, 35,194, 29,137,200, 59,220, 81, 37, 97, 51,206, 22,128,103, 5,100, 81, 93,216, 5, -234,194,122,237, 27, 4,157,247, 57, 38,253,167,253, 38,143,159,191,149,203,119, 2,100,231, 73, 63,169,208, 40,151,148,173,149, - 86,102, 45, 26, 37,229,106, 21,121,111, 85, 35,126, 68, 54,242,247, 30,201,241,237,203,226,101, 12,115, 57, 94,250,176, 15,211, - 21, 78,252, 42, 75,201,148,175,138, 87,207,251,108,197,218, 37,231, 9,176,126,254,249,103, 5,104,237,221,187,247,192, 15,121, - 18, 91,122, 93, 76, 42, 35,175,229,151,168, 73,195,220,208,107,171, 95,240,126,101,238, 8,132,224,131,166, 22, 41,153,184, 99, -208, 10,138,248,223,217,193,123,163,145, 86, 91,211, 6,156,233, 22,226,140, 34, 37,181, 51,174, 39,168,183,238, 68,252,130,159, -246,213,189, 74,181,133,164, 36,149, 38, 84, 31,185,119, 40,162, 53,134,231,231, 37,140, 22,237,153, 31,182,226,250, 20, 46,172, -128,168,148, 41, 83, 62,193,101,173,193, 98,158, 18, 37, 74, 60,247,235,218, 85,174,229,201,243, 1,140,197,142,109,191, 43,193, - 33,167,140, 0, 45,168, 63, 12, 1,173,152,113, 61,110, 61,120, 63, 79, 78, 74,124, 27,208, 58, 35,249,239,120, 62,154,124,177, -246,136,199, 23, 23, 55,221,242,127,160, 5,176,117,124,232,110,137, 22, 54,170,161,114,170,133, 7,192,186,192, 85, 45, 37, 89, - 90,137, 22, 12, 16, 47,252,141, 77, 97, 63, 7, 52, 14,190, 40,131, 50, 57, 80,124, 76,176,197,213, 56,109,232, 84,155, 19,216, - 88, 9,108,158,148,213, 57, 0,151,211, 93,137,220, 93,136,129,197,130, 21,182, 5,160,204,178,125,235,102, 75,181,194, 57, 44, -199,214,206,177, 44,110, 89,216, 82,165,116, 81, 11, 86,158,254,152,184,111,106,252,104,113, 21,106,198,230,173, 58,118,112,238, -195, 10,105, 87,197, 66,201, 95,220, 62,188, 58,232,225,136,188,129, 47, 38,150, 13,124, 61,169,124,224,176, 54,213,184,243,226, -105,129, 2, 5, 56, 72, 59,243,169,101,207,246,234,176,153,219,135,111,223,199, 93,135,231,189,142,172,186,123,236,232,246,103, - 39,143, 42,224, 40,232,246,141,101,100, 15, 36,114,246,198,240,174,170,175, 58,218,247, 46,176, 99, 19, 13,223,159,220,191,111, -147,108,189,127,112,127,105,224,211,199, 51, 65,243, 62, 84,115, 4, 69,134,203, 73, 23, 14, 40,231,102, 26,190,159, 57,114,104, -254,237, 35, 7,215, 61,241, 62,180,193,114,120,255, 10,185,121,109, 22,105,226,219, 57,104, 58,164, 73,128, 66,144, 69, 41,145, - 22,104, 81,117, 8,219, 55, 41, 94,182,186, 84,203,153, 71, 58,229,202, 36,147,234,215, 80, 84,254,148,108, 86,170, 84, 73, 1, -228,142, 62, 88,199, 70,203, 38,240,113,168, 70,116,162, 58, 36, 0,115, 10,180,172,207,104,129,150, 65,176, 85,158, 18, 42, 74, -180, 8,250, 85,155, 44, 74,178, 8,176, 0,140, 21,195,120,254,158, 52,105,146, 5,121,159, 88, 93, 62, 84,118, 81,209, 54,160, - 69,144,197,190,195,213, 59,251, 10,199,196,108,217,178, 5, 97, 83, 78,166, 16,218,104,121,168, 64,139, 96,139,110, 8,104,163, - 69,137, 22,109,182,166, 22, 47, 30,208,174, 94,189,155, 88,208, 24, 2, 90,180,189,227,166, 6,106, 24, 84,144, 69, 41, 38,165, -215,143,238, 95, 22,255, 7,135, 21,195,248,178,133,227, 62,162, 1,188, 19, 63, 90, 54, 86, 0, 96, 13, 42,221, 45,177, 48,193, - 95, 20,119,255,113,177, 20, 38,102,234,111,118,116,221,158, 73, 1, 89,141,166,167, 38,200, 90,137,235,220,185,168,219,207, 49, - 46,140,225, 2,112,227,198,141, 92,156,159,208,240,189, 53, 55,104,208, 94, 16,215, 60,213,235,216,189,125,146, 99, 24,165,175, -184, 54,217, 81, 61, 17,104,193,100, 67,145,100,113, 35, 65,206,194,133, 44, 27,246, 47,147,105, 43, 7,203, 46,239,189,114, 9, - 32,107,239,217, 39,178,226,128,159,244,152,184, 70,186,205, 56, 47,237, 6,120, 74,175, 33,109, 37, 82,236,228,236, 75, 46, 15, -216,159,206,129,250,205, 11,239, 56,138, 49,244, 40,198,250,163, 4, 88,197,138, 21,243,230,111,140,135,251, 39, 78, 31,127, 42, -121,254, 40,239, 83,228,139, 18, 24, 51, 94, 84,237,198, 31, 61,242,159,122,223,140,187, 5,195,239,210,113, 11, 65,211, 11,130, - 46,130,175,213,214, 68, 80,150,210,240, 11, 66,152, 17,125,238, 35, 44, 18, 66, 82,127,199, 99,170,125,186,253,249, 67, 89, 28, - 25,160,161, 34,246,221,185,115, 71,104,147,196, 85,211,159,125,251, 6, 98,192,217,141,236, 57,145, 10,162,113,122,115, 2,167, -196,132, 34, 70,210, 0,138,166,237,137,238, 97, 15,180, 32,105,240, 5,130, 86,236,178,214,172, 89,227, 11,137,135, 47, 36, 20, - 4, 90,186,182, 47,209, 98,122, 44, 62,126,167,135, 92,144, 60,114, 76, 98,248, 15,125,214,240, 80,166, 43, 27,223,229,184,182, - 77,114,120,190,144,244, 61,253,223,149,109,121,253,208,194,130, 51,253,183, 84,152, 39,171,126,159, 43,145,195, 70, 86,183, 23, -235,150,149, 25, 96,187,164,248,209,194,164,170,216,104, 65,138, 19,200,255,176,101,155,109,136,128,243, 76,249, 49, 24, 45, 5, - 63,174,243,140,108,142,182, 57, 59,123,186, 49,141, 72,169,182,197,106, 94, 1, 88,172, 47,218,211, 17,100,113, 55, 40, 37, 88, -172, 35, 74, 53,104,152,202, 1, 89, 15,104, 81,237,130, 1,205,178,103,247, 14, 5,100,157,220,180,192,178, 99,100, 27,203,240, -159,211, 88,154,252, 82,209, 2, 9,164, 5, 59,123, 76, 73, 4, 53, 31,192,129, 60, 65,133, 10, 21,158,247,234,213,235,225,225, -125, 27,223,248,123,207, 11,124, 49,181,232,187,183,243,171,188,151,189, 3, 2, 31,221,191, 27, 56,102,212,136, 67, 14, 92, 28, - 56,227,131, 66, 19, 42,149,135,152,120, 3,208, 22, 79,192,102,108,211,227,123,190,203, 94, 62,184,191, 66, 94,191,218, 65,240, -130,137,119,187, 89,154, 80, 29, 60,128,250,244, 46, 84, 73, 7,193,151,101,150,103,207,102,190,183, 4,204,130,216, 99, 29,196, -134,126, 48,100,222,224,192,189,131,203,114, 98,149,252, 0,254,147,238,130,143,135, 80,119,203, 31,223,189, 51,235,213,253,123, -115,228,149,101, 3,105,142, 31, 63,126,147,171,114,106,129, 22,250,163,165,117,235,214,130,221,148,220, 9, 43, 80,225,202,202, - 21, 43,165, 67,229,242, 50,189,225, 47,114,229,208, 1,233, 0, 87, 44,200, 39,216,173, 38,144, 60,190,118, 84, 56,103, 14, 74, -237,129,144,189,154, 79, 85, 99, 58,162,233, 10,104,169, 82, 48,103,244,117,250, 84, 11,213,133, 3,220,107, 40, 54, 90,170, 26, -145, 32,139,255, 7, 12, 24,160, 72,178,120,198,255,182, 58,244, 20,160, 69,144, 69,137, 22, 65,150, 86,162, 5,158, 53,167,138, -208,192,174, 67,135,175,209, 2, 45,250,124, 66,255,244, 30,214,181,235, 77, 74,180, 8,182,166, 0,108,117,251,245,215,155,122, - 18, 45,128,141,123, 44,155, 10,178,184,112,162,212,154,125,158, 11, 44,142, 75, 4,137,144,226, 9,250, 39,205, 4,116,143, 88, - 63,132,241, 35,152, 98,170, 59,225,123, 5,108, 65,202,211,170,206,184,239,149,107, 84, 27,194, 38,203, 7, 46, 85,115,129,152, - 81,137,117, 83,117,204,129, 81,252, 43, 60, 23,195, 90, 16, 58, 41,165, 75, 8,218,119,169,180,162, 99,179,134, 50,150, 90,237, -185,126,117, 84,104, 2, 45, 0, 33, 5,100,209,127,214,119, 89,147, 5, 94,240,185, 44,222,151,158,200,169,235,254,178,227,212, - 99, 89,180,231,158,148,173,151, 79, 74,214,202, 37,197,106,230,148, 74,173, 90,200,160, 57,187, 37,124,244,248,254,122,140,192, -130,101, 59, 36, 54,222,144, 54,123, 17, 88, 1,184, 31,185,231,235,123, 52,102,248,240,222,215, 23, 47,246,194,120,120, 0,192, -118, 63,242, 28, 0,255, 15, 67, 21,191, 83,143,102, 40,222, 55,227,110,193,240,107, 77,184,133, 48, 76, 51, 52, 50,126,229,198, -240,246,146, 44,167,238, 29,184,170,240,160, 65, 59,156,145, 46,132,253,195, 27,118,110,118,102,136,232,101,238,156, 57, 65,117, -242,231,127,222,188, 84, 41,255,163, 48,118,100,167,102,162, 77, 67,221,186,117,177, 51, 45,218,100, 26,210,235, 49, 28,131,207, - 89, 12,102,138, 49, 60, 6, 7, 95, 24, 8,251,210,105, 41,129, 22, 12,122,125,209,152,125,193,112, 67, 64, 11,239,250,117,216, -180,146,143,207,191,159,115, 35,225,165, 25,143, 98, 95, 88, 45, 73, 47,173,147, 84,151, 55, 74,170,174,254,146,180,131,191,196, -110,245, 92, 34,252,250,236,209,196,177, 87,206,183, 43,210,226, 33,159,209, 43,163,246, 62, 58, 98, 49, 24, 28, 63, 84,253,104, -113,242,194,206,190, 7,200, 19, 18,195,117,133, 52,128,108,109,172,152, 30,113, 80, 87,197,180,252,207,235, 6,203, 22, 5, 0, - 16,243,255, 11, 69, 63, 79,233, 22, 65, 22,118,214, 41, 32,139,198,168, 88,137, 41, 32,139,171, 75,170, 27, 56, 48,187, 2, 90, - 48,122,244, 33,208,194,128,102,169, 83,174,160, 13,100,141,172,156,198, 82, 46, 87, 90,203,245,171,151, 45, 0,214, 22, 76,144, -166,129,214,143,241,163,102,201,146, 36,198,133, 14, 77,106,189, 63, 0,240, 87,174, 92,185,103,185,178,167,121,125,106,237,152, -192,183,119,143, 5,189,189,227, 29,116,124,227,212,192,188, 57,210, 5,198,138,234, 65,227, 75, 87,118, 32, 10,139, 50,128,102, -230, 36, 49,206,119,110, 94,231, 5,118,196, 90, 8,182, 80, 79, 28, 20,247,192,152,245, 28,218,229, 21,170, 11,161,158, 56,232, -196, 17,232, 71,172,182,167, 9, 96,116,159, 46, 28,184,187, 16,244, 78,226,251,207, 99, 5,190, 15,187,190,246, 58,113, 88,170, - 75,179, 98,197,138,247, 33, 41,217,139,114,110, 69, 57, 79,130,238, 5,212,221,126,216,180,236,211, 43,167,170, 58,164, 68, 11, - 19,234, 37, 74, 2, 40,181,162, 77, 6, 37, 90, 4,221,172,115, 26, 24,211, 62, 11,139, 2,197,158, 7, 54,119,180,213,210, 74, - 24,116,155,153, 35, 32,100, 80,242,228,161,250,206, 98, 57,181, 73,171,106, 12, 9,125,250,199,210,184,112,176,237, 46, 84, 85, -134, 86,112,165,128, 45, 94,131, 20, 90, 79,162,113,138, 99, 24,221, 36,176, 47,209,229, 10, 37, 44, 4, 50, 83,167, 78,165,170, -189, 29,129,150, 1, 63, 90, 14,249,137,241,112, 59,165, 89,170, 68, 11,125, 83, 1, 11,180,209,154, 80,164,136, 13,108, 37,139, - 20,137,246,147, 78, 37, 70, 24, 23,238, 17, 76,209,254,201, 21,200, 98,253, 24, 5, 90, 81, 18,123,204, 32,192,210,130,173, 31, - 75, 69, 13,154,252,180,160,114, 45, 79,195,184, 65,225, 99, 42,155, 9,140,120,114, 87,191, 63, 35,219, 29,213, 79, 0,192,228, -223, 4,103, 13,141,106, 70,154, 53, 48, 97, 7, 34,231,158, 20,142,242,210,227, 59,234, 69, 1,169,152,139,188,227, 37, 75, 30, -120,246,218, 77, 25,179,112,129, 12,155, 53, 67,166,109,184, 32,131,151, 94,151,178,141,202, 74,193, 10, 9,149, 84,166, 78, 78, -233, 54, 5, 38, 19, 6,128, 22, 54, 34, 44,132, 4, 83, 1, 89,208, 2, 28, 37,160,130,245,193,193, 75, 19, 38,120,173,138, 25, -211,251,198,210,165, 94,120,247, 1,140, 1, 7, 48,190, 30,132, 26,151,139,226, 47,117,152,113,183, 96,166, 76, 41,145,217,136, - 91, 8, 51, 52, 63, 57,175,198, 24, 94,193, 34,255,170,195, 30, 69,210, 69, 3, 93, 53, 64,162,244, 24, 32, 72, 32, 33, 80, 36, - 39, 28,136,238, 52,110, 44,247,123,245, 82, 36, 89, 28,160,184, 18,220, 0,125, 60, 26,223,253, 61,219,183,174,167,107, 8, 29, -230,132,131,154,131,206, 58, 21,160, 69, 73, 22, 36, 48,244,246,160, 0, 45,236, 20,242, 5,104, 80,128,150,193, 93,135,225,195, -198,141,118,165,211,153,221, 65,149,111, 66, 77,114,110,185,196, 56,191, 74,226, 2,112,197,109,253, 92, 98,180, 4,200,106,250, - 76, 10, 12,124, 33,149, 6, 95, 8, 10, 19, 41, 30, 61,177,135, 15, 65, 5, 86, 85,253,104, 97,146,164,223,151, 26, 33,160, 97, -123, 4, 32,233, 4, 7,197, 46, 93,186, 60,134,106,242, 26,207, 4, 92,188,110,130,238,120, 72,113, 20,127,102,124,150, 32,139, -219,248, 9,178, 32, 25, 81,220,110, 12, 26, 52, 72,177,221,161,127, 37,230,197, 10,221,169, 29, 29, 86, 57, 62,244,153,117, 96, -223, 94, 75,157,220,201, 44, 27,250,214,181,216,131, 44, 74, 10,204, 2,173,180, 9,162,102, 42,150, 41,133,223,209,149, 51,100, - 73,235,146,210,177, 73,173, 64,140,220, 73, 99,197,240,232, 31, 59,154,199,133, 40, 17, 61, 94, 33, 5,149, 44,156, 59,176,127, - 73,143,183,197, 51,122,208,149,130,203,131, 52,139,103, 76,113,239,248,186, 57,150, 37,191, 23,181,116,105, 86, 39,128, 52,241, -144,153,176, 62,193,222,161, 71,211, 96, 8, 30, 83, 52, 13,134,224,177,209,212, 2, 45, 0,255,250,152, 84,207,161,222, 30,170, - 9, 70,211, 79, 96,175,225, 15,251, 60, 11,128,213, 83,148,249, 62,164,207,190,248, 77,195, 96, 74,163, 13, 31,246, 64,136, 18, - 51, 92,243,228,117, 61, 34, 42,208, 82, 92, 54,104,193,150, 70,213, 24, 18,250,244,248, 78,207,239,120,255, 66,238, 42,228,238, - 66, 26,190,171,234, 66,141, 36,107, 33, 60,226,211, 38,175,178, 78, 89, 79,169, 32,139, 18, 45, 74,135,120,192,181, 3, 23, 37, - 59,176, 35, 49, 60,129,150, 1,207,240,142, 94, 19, 6, 64,207,230, 3,138, 64,129,174, 29, 32, 89, 86, 12,187,127,173, 84,233, -230, 28,171,235,135, 94, 63,252,240,140,126,183, 64,196, 33,216, 34,208, 98, 63,215, 3, 89, 44, 59, 54,214,248,234,213,143,245, -126,130, 40, 73, 60, 54,106,193,214,216,187,249, 20,144,213,106, 89, 58,137,156,216,131,128,226, 7,131,180,108,217, 32,129, 90, - 77, 87, 64, 52,136,111,209,162, 5,249, 56, 13, 55,233, 75, 75, 61, 98, 1,128,253,197, 93,178, 92,252,205,158, 61,155,243, 7, - 61,145, 59, 60,208,182, 21,160, 69,144,197,221,135, 57, 10,148, 10, 88,182,253,172,244, 24,214, 82, 1, 85, 77,122, 15,145,214, - 19,207, 75,189, 97,199,165,120,163,134,202,181,186,221,255,148, 58,221, 23, 26, 85, 29,246, 0, 0, 62, 10, 59, 92, 74,175, 14, - 1,104,237,167,186, 16, 11,161,131, 87, 38, 77,242, 90, 27, 47,158,247,227,135, 15, 15, 99, 14, 60, 8, 41, 54,129,214,151,220, -117,248,185,220, 45,132,182, 91, 8,179,205,196, 97,254,175, 92,162,229, 58,168,180,253,199,169, 14, 75,233,132, 52,101,178,100, - 1,148,152,112,149,167,120,136, 77,159, 94,174,229,200,161, 72,177, 8,178,182,163, 51,197,141, 29,219, 63,193,183,113, 7, 26, -113, 88, 10,123,145, 58,127,252,241,199, 85, 21,104,161, 81, 43,192, 10, 43, 10, 95, 44, 34,124,177,250, 86, 64, 23,119, 29, 98, -146,112,228, 3,199,145, 51,183,172,177, 82, 36,189,211,234,236,174,160, 54,190,199, 37,243,213, 45, 18,239,226, 26, 5,104,165, -233,238, 47, 53, 38, 88,164,242,208,171, 65, 81,227, 38,163, 47,144,172, 14,106, 88,207, 65, 92, 90,128, 44, 63, 74, 6,120, 64, -245, 67, 85, 13,109,157,156,133, 9,226, 43, 92,210,164,221, 23,105,193,102,135,134,182, 63,242,108,245, 12,239,202,238,203,158, -102,102,110,139,102, 93,112, 0, 38, 40,230, 42, 28,198,155,138, 52, 3, 42, 88,197, 38,130,206, 13, 41,241,176,238,236,153, 98, -247,253, 54,154, 42,208,162,205, 75,221, 10,197, 44, 53,179, 37,180,252, 92, 32,147, 77,146,197, 73,204, 32,208,178,209,252, 33, - 81,180,116, 69, 1,136,142,173,155, 27,180,121, 72, 75, 25, 81, 41,109, 80,250, 68,209,104,215, 20,236, 40,154,193,195, 71, 46, -174,120, 47, 3, 60, 44,197, 51,121, 92,117, 85, 71, 25, 65,179, 68,166, 20,119, 85,181,230,232, 42,105, 45,160, 73,163,116,179, -135,173,156, 95, 11, 77,173,234,208, 94, 90,244,209,127, 23,174, 23,244,218, 39, 25,105,183,235, 80, 81, 77,234, 48, 56, 88,251, -204, 6, 59, 45,244,153, 74,122, 64, 75,125,143, 19,250, 14,251, 17,253, 99, 81,250, 74,176, 69,103,186, 4, 90, 60, 27,148,100, -217,104, 98,194,239, 4, 59,174, 32, 26,111, 19,100, 81,189, 78,233, 61,141,179, 1,130, 87,170,126,180, 24,227,144,177, 14, 25, -243,208, 72, 8, 30,242, 9,182,140, 21,186,117,235,182, 79,149,104,209,232,157, 96, 1, 19,182, 55,198, 58,111,244, 81,239, 49, -189,122,221,156, 86,178,100,192,123,236, 70,164, 39,121,122,148,215,240,216, 86, 78, 0,204,123,148,182, 81,106,173,218,102,114, - 60,166,221,150,106,192,175, 12, 78,250, 64,203,158,159, 73, 62, 2, 91,119,242, 73,162, 28, 17,239, 99,135, 33,243, 58,242, 88, -111,223, 12,236,105, 38,131,196,247, 21,213,156, 4, 91,112, 94, 74,199,165,111,105, 28,143,157,218,167,106,213,170,245,146, 18, - 47,126, 7, 77, 26,224,130,134,246,191,137, 92,140, 75,138,234,144, 32,139,231,254,131,135,223, 44, 86,169, 73,224,142,163,103, -165,116,205, 52, 82,191,223, 66,120,110, 63, 37,229,250, 28,147,130,191, 77,146,226, 85, 83,202,188,181, 43,229,187,172,165, 2, -236,140,225,157,141,201, 63, 96, 60,223,134,113, 20,194, 53,175,131, 4, 89, 56, 19,104,237,135,166,229,192, 99, 63,191,195,104, - 27, 7, 49, 71, 29,132,173, 50,119,135,106,119,135,235,205, 29,102,199, 36,251,185, 35,180,220, 45, 4, 43,103, 40,185,133, 8, -245,111,255,202,129,150,185,186,214,134,224, 73, 16, 55,238,144, 88,177, 98, 62,132,106,240, 37,108, 35,108, 14, 75, 41, 33,193, -202, 50, 0,232,254,110,226,248,241,250, 25, 13,193,131,149,217, 17, 12, 14,116,235,239, 11,189,252, 29, 74,174,248, 27,157,200, - 23, 78, 2,111, 66,220,172,248,213,226,117, 26, 41,154, 0, 69, 25,191,137, 31,231, 82,158,126,157, 31,215,217,191, 74,218,221, -242,146,223,103, 63,147, 74,253, 78, 72,166, 42, 67, 30,123, 68, 78,200, 56,104,246, 65,175, 85,242, 46, 27, 12,236,167, 22, 17, -104,210, 70,139,118, 16,140,117,104, 53,246, 92,228,130,179,122, 64, 75,241, 12,111,114, 39,163, 35,154,171, 96,215,166, 12,184, - 20,193,195,227,190, 50,184, 97,194, 81, 28, 89, 18, 20, 98, 21, 38,187,119,239, 22, 72, 40, 57,160, 57,141, 33,168, 2, 45,240, -223,130, 65,197,114,245,202, 69, 75, 0, 38, 51,170, 11, 85,144,101, 22,104,101, 76, 18, 99,201,209, 85, 51, 20,144, 53,236,231, - 31, 3,115, 38,143,225, 75, 53,162, 67,160,117,244,175,119, 4, 90, 37, 51,121, 80,234,232,116, 48,207,152, 36,230,146, 99,144, -100,209,118,140, 18,183,156,201,162,251, 82,229,103,174,149, 43,185,255, 15,180,190, 18,154, 95, 26,104,169,210, 43, 45,232, 50, -218,230,237,237,180,236,119, 40,170,126,180,236, 65,157,179, 9,215,238,122,101,171,231,247,182, 80,227,159, 39,208,194,153, 0, -189,133, 1, 73,150,173,222, 9,154, 32, 1, 76, 15,192,197,177,230,255, 62,179, 0,178, 32, 25,250,246,255, 14, 75,203,212,136, -149,169,214,177,176, 41, 75, 85, 54, 10,180, 48,214,173,229,110, 57, 38,198, 57,196,194, 71, 1, 10, 12,195, 3,239,230,135, 17, -231,213,155,158,226,187, 98,220,243,252,225, 7, 63,198, 70,100,140, 68, 71, 64, 11,125, 83, 1, 90,122, 32, 43, 4, 64,139,175, -179,129,173,137,143, 10, 72,209,182, 9, 4,190,178, 58,227,122, 74,131,125,202,209,184, 84, 24,113, 80,159,210,167, 27,119, 72, -194, 77,140,162,226,198, 78, 81, 69,250, 78,137, 23, 35, 24, 64, 93, 78,187,193, 34,174,250, 59, 3, 69, 51,134, 33, 19,234,100, - 51,164,184,155,163,196, 78,252,188,121,207,169, 65,139,119,156,146, 86,131, 39, 74,229,254, 39,164, 88, 15, 47,105, 48,252,168, -204, 90,179, 74,170,255,230,249, 62, 66, 76,248,210, 10, 46, 33,116, 58, 38, 67, 2,220, 18, 59,184,119, 67,170,117, 20,170,221, - 67,144, 60, 30,232,215,175,223, 97,240,251, 0, 37, 89, 80,219, 30,196,162,118, 59,180, 44,246,110,108, 66, 29,108,104,199, 37, -252, 14, 45,119, 11,193,202, 25, 74,110, 33, 62,199,183, 27,108,114,255,130,108,246, 65,165,119,110,221,180, 1,246, 87, 83,176, -170, 90,158, 36, 86,172,219, 72, 55, 49,136, 44,138, 17, 45,202,120,170, 11,205, 4,149,198, 42,111, 7, 86, 49, 87,176,130,184, - 10,144,246, 39,118,139, 93,162,125, 22, 92, 69, 92, 5,202, 30,130,109,234, 23, 33,190,245,197, 32, 74,255, 55,185, 92,117, 64, - 7,247,194,225, 90, 67,143,104, 81, 23,120,196,138,113,211, 35, 82,220,155, 30, 17, 98, 44, 80,174,121, 96,125,230,252,112,217, - 96, 24,232,217,234, 71,235, 17,118,204,221,133,234,243,225, 39, 4,128, 86, 74,193, 29,139, 86, 95, 92,156, 28,210, 96,165,135, -191,138,111, 46,218,106, 56, 59, 28,149,147,222,223, 55, 83,106, 69,176,165, 58,175,227,128, 76,122, 84, 23,114,101, 9, 91, 35, - 74, 35, 26,185,226, 39, 6, 50, 31, 2, 44, 12,232,138, 47, 34, 24,239,126, 4,178,204, 2,173,188, 41, 99, 29,155,211,164, 64, - 16, 65, 86,142,100, 49,238, 82, 61,231,232,227,114,167,245, 56, 67,169, 22, 83,190,116, 30,142, 92, 80,216,190, 61,239,247, 49, -143, 45,104, 81, 80, 1, 89,185,146, 69,191,227,140,166,129,174,248,213,209,212,170, 14,245, 36, 90, 58,206, 63, 77, 13,146, 33, - 1, 90,228, 63, 85,136, 70,124,100,185,160,111,164,156,149, 49,110,112, 82,117,229, 47, 75,219, 28,130, 1, 45,163,241, 14, 29, -229,211, 16,253,168,156,144,222, 47, 1,200,216,135,177,109, 63,198,206,158, 24, 59,246, 80,109,136,208, 78,251, 49,177, 3, 91, -253,176,139,241, 14,177,243,238, 64, 74, 15,143,238, 57,194,134,157,128,149, 96, 41, 71, 52, 9,180,216,183, 85,205,130, 35, 73, - 86, 8, 37, 90,234,235,146, 96,119,225,124,236, 68,188, 31, 57,190,199, 4, 92,228,198, 28, 61,207,247,234,179,206,234, 40, 9, -198,148,253,240,149,165,216,107,209,132, 1, 27, 24,184,107,150,139, 85,218, 12,134, 60,160,118,228,184, 73, 0,164,142,101,253, -169,138,165,237,208, 53,210,103,230, 49,233, 54,249,168,212,238,190, 64, 82,102, 46, 26,224,196, 97,169,171,182, 20, 22,182, 90, -109, 49, 47,109,133, 49,255, 97, 72, 30, 15, 19, 28, 99, 28, 61,132,249,234, 32,234,106, 43, 22,170,220, 88, 97,207, 19, 35,237, -211,192, 80, 20, 44,139,150,230, 72,110, 70, 11, 5,119, 11,246,229, 12,169, 91, 8,135,253,200,236, 7,186,243, 91, 57, 64,176, - 69,201, 22,213,136,180,187,114,100,228, 78,163,121,218,115, 49, 15,243,242, 25, 59, 6, 58,106,132,169,177, 42,216,136,129, 53, - 59,243,162,241, 86,134, 93,201, 25,158,249, 31, 82,172,202, 72,231, 32, 78,110,230,164, 50, 62,119,195,254,232,181,144, 58,213, - 1,240,248,157,103,222,228, 25, 78,226,108,255, 67, 82, 78,240,179, 4, 36, 80,181,161, 62,168, 14,112, 85, 25,182, 84,213, 49, - 16,213,198, 74,195, 17,184,212, 27,208, 8,182,230,211,208, 29, 64,246, 62,207,106,130,173,137, 31,125,110,225, 62, 85,134,142, -236, 63,108,252,228, 78, 83,172, 24,125,152,184,179,144,137,246, 88,246, 9,147,198, 71,170, 63,103,245,158, 62, 81,244,159,242, -166,136,177, 63, 75,226,232,251, 50, 36,140,150,254, 19, 58,152,173,156,164,153, 39, 69, 44,208,140,177,247,191, 70, 83,235,176, -148,191,245,254,187,224,183,233,126,100,149, 64,121,134, 38, 77, 45, 45, 39,244, 77,151,211, 64, 27,251, 82, 52, 83, 99,242, 94, - 4,187, 75,117,172,251, 25, 99,223, 78,140,111, 63, 91,199,186,159, 33, 77,219,141,177,174,145,222, 24, 2,169,142, 23, 64,203, - 61,107,242,165, 29, 22, 19,254,223,101, 2, 16,187,163, 38,140,167, 90,255, 85,246,164, 93,125,123, 2,100,166, 67, 99,142, 65, - 49, 13,240, 81,111, 92, 82,239,211,255, 34,237,207, 56, 6, 13, 65,226,216,158, 85,135,190,145, 58,250, 38,124,148,184, 45,233, -194,129, 70,239, 76,145, 98, 37,219,239, 34, 4,143, 17,154,233,192,235,129,168,167, 85,168,187,189, 72,171, 49,222, 13, 66, 89, -211,233,213,145, 9,126,233,101,213,150, 51, 58, 50,211,241,232,167,186, 91, 48,242,237,122,229, 50,211,150,204,210,250, 55,228, -215, 13, 63,248,185, 62,242,107,169, 92,119, 57, 67,183, 5,184,249,233,230,103,104,113,192,221,150, 66,139,147, 31,232,184,249, -105,156,159, 70, 92, 90,184,249,105,156,159,255,246,156,174,141,225, 63,227,215,187, 27, 97,232, 50,215,205, 79, 55, 63, 67,139, - 3,238,182, 20, 90,156,116, 3, 24,119, 91,114,183,165,208,229,192,215, 73,205,165, 68,139,157,196, 81, 50,243,169,206,104,184, -186,174, 71,223, 77,211,113,189,132,180,190,220,252,116,243,211,104, 27,112,247, 77,231, 28, 48,202, 67,109, 62, 55, 63,221,252, -116,196,129,255,114, 91,210,235, 19,238,251, 38, 56,224, 94,233,152, 96,150,129,172,110,126, 26, 96,146,137, 44,110,126,154, 96, -150,129,172,110,126, 26, 96,146,137, 44,110,126,154, 96,150,129,172,110,126, 26, 96,146,137, 44,159,131,159, 38, 94,255,143,203, -234, 86, 29,234, 84,201,231,104, 48,110,154,161,219, 15,220,252,116,243, 51,180, 56,224,110, 75,161,197,201, 15,116,220,252,116, -243, 51,116, 57,240,117, 83,251,226, 70,241,255,198, 14, 72, 3, 73,198,236,218,131, 68, 15,204, 60,243,191,189,225,164,209,111, -231,238,158,193, 72,220,201, 71,122, 60, 15, 68,226,110, 19,251,195, 40, 77, 51,205,244,171,164,201,237,242,216,165, 54,156, 9, -187,175,148,132, 93, 87,195,177,115, 82, 73,112, 29, 50, 28, 59,135,122,126, 70,128,237,108,235,251, 71,252, 84,203,170, 45,167, -182,172,159,185,156,206, 88,240, 85,214,187,153,134,237, 34,239, 63,225,219,211, 98,119,155, 55,202, 24, 98,167,199, 33,228,197, - 63,225,219,141, 20,221, 93, 78, 35, 92, 50,158,231,139,242, 19,227,219,111,240, 36,192,157,176,246,126,199,140,151,248,235,204, -233, 26,100,193, 65,232,110, 38,245,219,176, 69,248, 0, 6, 2, 63, 51,137,207,216,241, 38, 88,229,242, 62, 38, 65, 63,251,132, -137,230,165,179,247,224, 30, 67,135,104,143, 47,218, 96,236,222, 77,247, 8, 27, 48,137, 47,159, 48, 97,194, 47,240,129,211, 5, -206, 65, 59, 32, 36,207, 50, 92,223,140,164, 5, 91, 70,202,153, 31,222,167, 47,195,207,206, 16,120,184,110,141, 32,208,157,224, - 8,245,207,198,141, 27,207,128, 3, 69, 58, 88,205,245, 15,250,118, 51,205,222,200,183,155,161,199,188,193,104, 18, 96,193,145, -234, 20, 38,132,130,154, 2,175,206, 83, 16, 74,101, 10, 98,115, 78,129, 47,176, 41,240,238, 61,133, 96, 43,180,129, 22, 92, 94, -228,192,187, 15,193, 15,218,123,156, 15, 34,101,211,171, 35,251,178,194, 63,153,173,172, 8,130,240, 89,202,105,128,185,159,189, -142, 12,148,193, 72, 22, 71,229,108, 10, 55, 38, 43,224,151,234, 14, 92,163,156,134,251, 18,134,120,177,247, 44,238,138,182,222, -183,199,194,195,163, 16,139,239, 32, 92, 47,220,129, 63,172,131,252,143,196,235,206, 14, 61,154,218,231,210, 22, 41, 82,132, 65, -208, 5, 94,233, 25,123,213, 25,216, 50, 67,211, 8, 47, 63,234, 71, 70, 31, 10,237,126,100,224,189,238,111, 55,192, 36, 19, 89, -156,242,147,174,155, 48, 86,174, 64,186, 1, 87, 33,111,224,253,254, 13,252, 91,222, 64,220,216,149,112, 58,235, 42,118,177, 83, -154,152,207,233,136,156, 14,185, 95,160, 15, 61,192, 34,243, 38,232,211, 77,133,174,219, 16,123, 44, 98,226, 27,255,238,172,250, - 33,120,240,113, 69,152,212,146, 98, 21,126,139, 78,241, 16,192,213, 22,211, 16, 1,112,149,224,171,188,206,184,135,136,139,167, - 68,141,167,199, 98,120, 56, 22, 62,227,106,210, 1,186,189,141, 73, 70,245,171,167,156,249, 31,192, 43,144,116,237, 15, 94, 99, -140, 47,189,137, 44, 20,184,107,180, 83,183, 66, 3, 90, 16, 16, 96, 57,255,240,209,211, 75,149,107,255, 86,109,249,202,149,205, -224, 45,126, 9, 6,206,213, 40, 7, 37, 91,234,161, 71, 51, 22, 64,214, 21,132,232,168,231,217,111, 80,251, 74,191, 52,111,154, -227,167, 82,149,155, 53,251,173, 10, 66, 63, 12, 64, 56,157,169, 86,176,165,149,108,233,209,244, 64, 99,222,132,137,253, 34, 19, -126,111, 49,192, 27, 93,154, 6,104,216,103,209,163,233,200,121,172, 43,135,178, 31, 77, 16, 42,120,129, 3,199, 41,240,228, 60, - 5,147, 22, 3,212, 78, 65,168,161, 41,112, 48, 56, 5,142, 6,167, 0,216,135, 54,208, 10,135, 65,233,246,130, 5, 11,100,196, -240,225,140,251,199,100,239,179,232,163,111, 87,203, 74, 80, 5,199,131, 83,224,144,119, 10, 60,153, 79, 65,248,169, 41,240,194, -239, 6, 90,174, 27,152, 61, 63,187, 35,162,132,226,192,145,142, 28, 25,118,138,206,122,225, 80,242, 49,200,164, 54,216, 86, 93, -181,207,248, 0,209,143, 38, 77,154,164, 4, 70,102,128,118, 70, 85,128,151,112,198, 33,125, 4,250,241,157,188, 67,175,205,219, - 30,163, 36, 11,126,248, 4,237, 65,113, 48,140,133, 22, 3,212, 59, 2, 91, 70,105,134,193, 56,217, 30,105, 29,250,252, 86,164, -126,160,231, 44,116,142, 43,154,137,225,227,235, 32, 22,183,126, 76,144, 72, 40, 9,244, 2,213,133, 48, 23,201, 24,231, 5,255, -181,139,106,163,229, 52, 88, 61, 74, 54, 55, 77, 51,220,210,207,235,144,159,168,207,166, 88, 72,188,129,191, 48, 1,192, 18, 56, -207,149, 44, 89,178,176, 77, 74,129, 2, 5,164, 68,137, 18,111,138, 21, 43,214, 84,175,205,231,207,158,176,113,254,156,137,110, -255,148, 43,137, 47, 83,225,252,105, 24, 77, 68,224,228, 87, 9, 17,199,132, 96,247,239,225, 39,242, 38,104, 57, 5, 91,214,160, -210,193,176,136,254,167,125, 37, 57,212,248, 66,218,226, 2,217,222, 98,208,104,134, 77, 64,236, 39,221,196,192,211,122, 64, 11, -168, 86, 1, 90, 28,192,212,164, 2, 45, 2, 58,251,247, 48,112, 53, 99,124,125, 73,160, 85, 35,163,135, 48,209,155, 53,147,246, -127,161, 31,162, 48,196,205, 47,247, 31, 62,189,130,116,162,112,233,154, 69,187,214,173,155,247,250,249,243,173,224, 73,120, 46, -202, 73, 53,162, 81,160, 53, 36, 87,174, 92,131,123,254, 57,184,131,207, 45,191,147,183,125, 31, 28, 45, 90,177, 65,165,210,229, -171,149,200,151, 47, 95, 54,196,214, 26, 51,124,248,240,149, 32, 54,208, 4, 77, 15,132, 11,186, 8,169,142, 50,128,227, 55,165, - 98,122,199,151, 30,208,232,188,145, 94,234, 21,231,175,214,131,191,121, 77,113,236,168,215,169,121, 95, 5, 47,224,251,148,203, -151, 47, 79,193,132, 56, 5,241,227,166, 32,144,246,148,181,107,215, 78, 65,176,218, 80, 7, 90, 73,147, 38,205,140, 56,157,175, -255,130,151,107, 53,124, 12,206,239, 81, 28,173, 26,241, 35,126, 82,101, 72,201, 27, 1, 33, 60, 79,191,196, 10,239, 45,194,197, - 40, 9, 65,135, 95, 0, 80,115,162, 61,105, 77,140,165,102,127, 56,170,163, 84,112,118,185, 18,233, 38,158, 15,100,194, 96,121, - 19,255, 71,227, 97,109, 0, 95, 67,252,212,100, 74,142,223,244,176, 94,193, 73, 42, 15,207,222,206, 0,141,179,182, 20, 90, 52, -191, 3, 47,131, 16, 30, 69,241, 52, 94,178,100,201,183,149, 42, 85, 10,162,199,113,254, 71,121,219,233, 53,118,235,125, 87,109, -190,241,226,197,139, 5,139, 29, 37, 78, 40, 34, 42, 88, 16,240, 93, 24,114,139, 1,218,241,124, 35, 35,237, 83,167, 28,149, 81, -238,231, 92,176, 2,116, 11, 2, 76, 19,196, 57,138,157,234,170,156,116, 82,220, 21,105, 51, 36,122, 47, 59,119,238,236, 15, 41, -238, 43, 44, 48,252, 59,118,236,120, 18, 64,233, 50, 38, 81,163,230, 7,148,196, 15, 64, 8, 52, 95,132, 47,122,205,152,143, 28, -143, 25, 67,145,139,107,134, 29, 99,100, 12, 46,174,153, 56,182, 64,178,171, 93, 84, 87, 50,200,119, 51,217,190,200,184,132,126, -243, 22,133, 98,189,146,159, 30,122,255, 13,246, 77, 51,223,233, 40,239, 23,249,118,128,229,150, 88,236, 43, 99, 25,164, 87, 10, -184,178, 79, 0, 90,130,240,123, 82,185,114,101, 71, 42, 64, 91, 57, 11,228, 74,228,243,232,234,116,145, 39, 75,149, 52,122, 80, -147, 0, 2, 45,132,233,147,209,163, 71, 11, 3,136,115, 81,132, 0,226,239,172,146, 45,135, 60,114,132, 69, 62,149,153, 95,240, -121,123,181, 97,240,255,206,128, 22, 59,218,145, 35, 71, 4,171,111,221, 68,160, 69,112,230,234,163,112,255, 14,165, 96, 20,153, -171,137,255, 41,209, 34,226,181,127, 15,175, 65, 10,102, 52, 18,189,250,234, 70,152,108,198,226,143,209,213,109,176, 34, 19, 92, -161, 49,212,118,148, 48,160, 61,198, 0,220,233,151,223,254,172, 91,177,122,243, 82, 91,230,207,111,114, 99,199,230,214,143, 14, -236,170,135, 54,197,201,210, 76, 89, 15,141, 31, 63,190,101,197,186,157,126,247,123,248,228,252,163, 39,207,207,245,233, 53,232, -215,233, 35,134, 54, 92, 58, 98,104,117,239,131,251,106, 32,198,214, 46,208,212,243,194, 30,172,252, 4, 90, 28, 36,217,176, 1, - 12, 28,197, 12,252,130,237,238,163, 87, 41, 32,139,135,117,112,227,127, 71,215,248,160, 75, 9, 23,193, 11, 85,134,170, 52,139, - 0, 70, 5, 47, 42,128,193, 32,162, 5, 48, 39, 65,211, 17,136,209,229, 7, 6,162, 45, 28,140,176, 26,147,206, 29, 59,190,230, - 89, 3,180, 92,121,225, 86,104,171,101, 37, 32, 36,200, 98,187,118,116,176,222,144,157,229,212, 59,210, 35,224,250, 83, 72,196, -130, 56,241,145, 30, 39, 67,246,159, 42, 85,170,188, 68,251, 39,192, 14,175, 71,196,201,253,242, 8, 74, 94, 24,210,150,130,142, - 18, 64, 78, 17,148,221,217, 10,215,217, 43, 67,139, 38,219, 68, 37,240,127, 19, 34, 30,140,180,182,145,236, 12,241,194,224,196, - 8,107,195,144, 46,159,116, 96,140, 90,195,240, 85,144, 52,179, 46, 74, 88,137,149,104,222,188,185, 18,164, 29, 82,210, 79,125, - 71,218,194,133, 11, 63, 60,117,234,148, 34,137,163,196,108,203,150, 45, 2,211, 1,210,230,162,210,149,205,150,250,109, 25,161, -214,244, 70, 44,211, 75, 0,106,129, 12, 40,207, 69, 49,195,243, 32,156,153,162,117,232,213,171,215,113, 72,167, 86, 24, 96, 6, - 65,214,160, 41, 83,166, 60, 97,155,172, 87,175,222,123,126, 63,227,218, 82, 26, 65, 16,171,198, 43, 68,104, 26,129,121,131, 2, -182,236,128,150,171,215, 60,195, 77,242, 50,150,129,178, 24,201, 66,122,140,143,168, 36, 68,192,120,141, 5,198,107,212,219,107, -128,213,215,232, 7, 93,240, 25,122,210,113,219,123, 48,166,191,179,150,143, 30,241,195,232,253, 55, 82,192, 47,144, 39, 25,198, -182, 21, 72, 79,145,158,163,204,107, 48,198,164, 52,243, 94,140, 95,241, 32,201,122,139,249,194, 6,174,176,240,231,248, 33, 21, - 42, 84, 16, 4,104,183, 93,199,162, 64,126,255,253,247,183,232, 3,241,156,189,163, 64,142, 68,191, 21,200,153,208,183, 80,158, - 36,126, 76, 69, 11,164, 85, 36, 90, 61,123,246, 84,226, 90, 82,136,194,152,151, 12, 7, 7,128,247, 30,229, 94, 14, 90,197,237, -233,253, 75,128,150, 10,176, 62, 2, 90,158,246,122, 81, 84,220, 45, 14,224, 68,161, 90, 9,148,179,223, 0, 5, 4, 69,183, 93, - 85, 54, 58,131, 47,243, 81,108,174, 38,254,135,212, 74, 81, 29,218,211,230,181, 16, 0,173, 78, 24, 36, 71, 3, 53,143, 64, 89, - 76,131, 45, 21,104,161,141,112, 66, 9,150, 64,243, 36, 36, 38, 29,151,173, 94,219,226,207,230,205,139, 94,223,184,166,245, 75, -175,131,163,228,218,165, 89, 0,154,171,241, 62,173, 68, 75,175,221, 63,198,196,216, 41, 87,209,154, 53, 43,214,235, 82,187,159, -231,208,223, 86, 78,153,214,229,208,146, 5,189,206, 46, 91,216,254,218,222,157,213,240,126, 2, 55, 51,224,205, 3,224, 74, 1, - 90, 12,250, 13, 53, 23,227, 40,254, 83, 14, 14,126, 10,190, 96,157,175, 95,191, 94, 5, 91,202, 53,170,160,169, 74,177, 14,122, -186,101, 38,120,161, 93, 22,212, 71, 83,208, 70, 21, 0,195,213,183,179,131,210, 81, 16, 61,169, 75,216, 65, 6, 12, 74, 5, 1, -222, 94,183,109,219,150, 82, 66,130,172, 23, 72,254, 72,119,105,179,165, 71,147,101,165, 93, 22,213,155, 44, 39,203,200, 9, 17, -113,239,132, 11, 20, 46, 54, 8,148,172, 0, 84,183,140,152,100,103,162,191, 6, 81, 34, 2, 41,134, 0,108, 42,103, 72,247, 20, - 21, 62,236, 42, 44,200,211, 87,175, 92, 78,238, 87,112, 6,178,212,235, 40,167,217, 93, 53, 14,105,222,186,117,235, 39,180,209, -181,136,121,119, 51, 4, 52,213,226,127,147, 63,127,126, 11, 3,169,163,142,238,135,240,155,109,143, 17, 4, 65,157, 43, 56,191, -194, 69,117,194, 14,135,224,199,175, 8,136,160, 86,161, 77,149,209, 35, 45,108, 93,110, 21, 45, 90,244, 17, 76, 11,148,132,192, -244,207,217,214, 25, 92,121,222,188,121, 82,166, 76, 25,129,189,167, 2,108,250,247,239, 47, 0, 71, 52,144,119,117, 68,134,125, -218,113,240,206, 66,112,197, 9,140,192,135,245,206,241, 19,170,115, 69, 66,134, 54,113, 23,192, 83,143, 31,193, 64, 22,193, 22, -218,205,115,106, 25, 56,126, 16,100,177,159, 2,208, 11, 65, 22, 23,221,124, 7,223,135,182,239,114, 81,173,249,128,103,214, 62, - 45, 0, 69, 12,108, 31,203, 40,243,156,228, 35,192, 82,198, 9,210,163,202, 11,115, 4, 37,130,180, 7,162, 41,202,191, 29,104, - 37, 37,184, 66, 27,120,131,249,136, 66, 10, 46,168,223,160, 93,190, 40, 85,170,212,119, 70,121, 11, 80,191,145,188, 83, 37, 89, -117,234,212,145, 97,195,134, 81,138, 27,136,113, 46,176,126,253,250,242,211, 79, 63, 41, 96,139, 0,172, 93,187,118,210,186,117, -235,141, 70,233, 99, 78,247,211, 2, 45,130, 45,246, 43,158, 33, 53, 85, 22, 22, 80, 77, 6,129, 94,125, 45, 77,140,107, 31, 97, - 17,163,239,252, 7,228,211,119,239, 96,111,163, 69,160,197,137,139, 3, 2,197,232,122,201, 8,208, 98,108, 46,174,186, 40,154, - 86, 19,255,163,163, 4,114,210,176,127, 7,197,213, 4,103, 38, 25,216,201,211,211,115, 10, 84, 60,220,121,102, 26,108, 81, 85, - 72,105,150, 35,160, 5,195,213, 9, 24,112,247,162, 92, 11,111,156, 61,219,234,209,150,245, 13,229,242,133, 89,242,246,245,195, -242,229,203,111, 67, 57,181, 54, 90,122,197, 62,132,149, 98,239, 58, 13, 26, 87,170,215,168,117,229, 57, 67, 70,182, 56,188, 96, - 78,239,155,219, 54, 77,185,183,126, 85,191,151,103, 79,118, 3,208, 60, 7, 34, 46, 37, 90,140,102,207, 64,220,106,194, 74,196, -143,160,130, 43,124, 4,175,189,143, 70,125, 81, 77,204,171, 87, 40,222, 71, 39,220, 12, 0,113,145,210, 49, 2, 55, 12, 98, 10, -141, 84,169, 82, 93,132,241,241, 69, 12,104, 23,161,203,191,136,137,141,215, 13,209,180,190, 87,145, 94,113,240,102,123,161, 58, -134, 7, 85, 17,156, 32,172, 3,168, 86,165,232,180,184, 4, 47, 52,126, 71,251,156,130, 85,246, 20, 74,177, 72, 11, 27, 20, 20, -251, 29, 2, 15, 2, 55, 2, 25, 78,108, 38,164, 69, 31,189, 19,224, 72,153, 4, 1, 10,130, 84, 73, 22,120,147, 5, 60,112,102, - 7, 19,140,134, 90, 86, 21, 16,178,156, 4, 69,236, 3,252,118,182,125, 85,202,133, 7, 79,234,213, 17,164, 89,190,156, 88, 9, -212, 8,178, 48,233, 42,223,202,190, 68,190, 82, 90,130, 9,243, 29, 82, 0, 6,211,187, 0, 50,236, 7,174,140, 90,181,175,252, - 98, 64, 11, 54, 33, 84,141,211, 54,100,205, 39, 0, 45, 15, 76, 4, 79, 8,180, 48,217, 60,209,227,157,222,125,128,161, 39,156, - 16, 0, 86,131,209,194,132,243,196, 10,180, 12,191, 3,147,141, 55,235,135,135, 42,117,100, 29,173, 94,189, 90,168,158,156, 53, -107,150, 50,129, 97,133,255,146, 54, 96,104, 83,142,212,135,246, 69,238, 14,213,248,101,130, 44,154, 8,144, 6, 23,164,180, 87, -131, 36, 82,233, 83,228, 5, 36,101, 47, 49, 25, 63,213,249,222,190,170, 36,139,103,228,221,133,103, 94, 52,107,214, 76, 1,128, -229,202,149, 83,164, 27,107,214,172,177,129, 44,142,209, 28,151,209, 15, 92, 46,170, 53,239,125,198, 58,134, 4,146, 32,210, 6, -138, 80,231,138,170, 46, 4, 71, 68, 60, 67, 73, 86, 48,122,176,171, 99, 63,239, 1, 86, 27,150,102,241,221, 26, 85,161, 34,209, -210,251, 31,130,242,134,234, 35,148, 4, 17,100,105, 36,234,138,116, 29,237,245, 13,192,209, 6,163, 47,163,237, 29, 1, 15,129, - 20,230, 52,129,153,138,180,105,211,102, 5,104, 68, 5, 96,139,138,250, 95,129,197,134, 77,170, 69,224,133, 57,149,237,211,225, -161, 39,209,162, 96,133,237, 20,230, 29, 20,172, 4,181,106,213, 74,230,207,159, 79,201, 25, 77, 47, 24, 11,211,118,216, 99, 17, -163,223,244, 85,230,163,104,152, 43, 27,138,165,141, 36,236,244, 18,218, 96,185,250, 88, 12, 40, 47, 8,170, 28, 36, 69, 5, 98, -255, 30, 94, 3,205,187, 38, 25,168, 0,173,144,130, 45, 71, 64,107,205,178, 5,181,242,167, 75,118,190, 98,137,194,239, 40,218, -132,113,224, 65,136,215,231,161, 83,223,219,190,105,174, 84,172, 88,145, 13,156,201, 72,108, 44,245,115,134,161, 97, 79, 4,194, -239, 93,174, 72,129,156,171, 7,255,249,203,185,133,179, 59, 61, 88,183,172,255,171,117, 75,187, 99,100,222,143, 85, 37,193, 27, - 93, 63, 56, 61, 8,126,236, 55, 18,176,222, 56,232,114, 2, 87, 15,254,102, 94, 35,188, 36,200,162,148,133, 7, 7, 85, 78,222, -234,196,174,130, 23, 14,242, 4, 47,152,220, 12,209,212,188, 87,177,199,226,132, 64, 21, 5,219, 13, 87,229,188,134,228,202, 70, - 43, 88,209, 9, 94,208, 62, 20,105, 22,236, 8,109, 64, 11,234, 57,241, 4, 45,130, 16, 21,200,240,127, 72,129, 22,118,182, 41, - 18, 39, 78,140,168, 47,170, 15,149, 65,206, 8, 31,213, 60,116,229,192,178,106, 1, 33, 39,115,110, 34, 97, 27,231,130,134,229, - 51, 42,209,194, 64, 27,192,103,249,141,170, 20,139,223, 74, 94, 18, 84,178,206, 88,223,172, 43,108, 16, 16,136,254,105,236,186, -208, 96,153, 63, 27,208,234,221,187,119, 61, 74,177, 40, 25, 67,187, 97,128, 97, 78, 18,219, 96, 79, 87, 40, 36, 64, 11, 3,182, - 23,218,170, 31,192,127, 0,192,193, 91, 76, 28, 1,224,181, 31, 19, 87,212,234,238,102, 7, 59,151, 29,178,130,244, 0,158, 3, - 48,161,188,197, 98, 34, 0,109,204, 15, 11, 61,133, 30, 22, 50, 1,176, 97,122, 11,128, 16,128, 73,202,126, 39,180, 51,214,166, -197,226,236, 1, 65, 22, 23, 63,108,155,156,104,184,168, 0, 45, 5,188,227,251,105, 96, 95,217, 42,201, 50,162, 54,220,132,186, -126,203, 5, 4,193, 22,108, 70,149,190,206,246, 64,201,211,230,205,155, 21,169, 1,212, 60, 15, 1,180, 93,246, 77, 72,188, 78, - 58, 21, 1,107,110,192,102, 84, 81,249, 16,100,113,140,102,219, 50, 3,180,160,218, 18,168,179, 57,193,114,177, 34, 4, 69, 80, -245, 11,233,154,149, 64,145,209, 0,109,175, 85,208,166,165, 23, 18, 90,214,138,227,184, 67,201,180, 58,126,235,253, 55,216,149, - 66, 63, 27,128,214, 35, 44,132,181,166, 11,202,111,236,124,167,186,251,133,209, 55,162,111,188,167,225, 59,129, 22,164,172, 4, - 81,239,209,102,108,230, 6,184, 30, 30,117,244, 30, 11, 88, 37, 15, 85,138,144, 66, 17, 20, 57, 60,156,217,104,193, 60, 70,105, - 73,156,163,174, 93,187, 70, 59,199,183, 16,128,204, 2,160,157,193, 77, 45, 67,134, 12,225, 88, 74,187,210,127,195,161,235,218, -129, 86,254,162,221,117,168, 2, 45, 50,199, 72, 98, 71,167, 13,150, 43,110, 81,220, 76,187, 47,237,193,255, 4, 94,156,184,237, -223,195,107, 84,207,152,172, 1, 27,208, 34,216, 2, 82, 31,130, 65, 18,115,173,177,195, 94,117, 72,144, 85, 54,103,154, 71,199, -214,206,145,197, 45,139, 72,165,146,133,223, 3,233,255, 69, 53, 34, 86, 85, 15,191,141,173, 0,132, 86, 72,116,253, 96,244, 96, -135, 78,139,149, 68, 0, 6,198,205,152,116,199, 28,219,191,191,230,181, 13,171,106,191,185,114,190,155,188,122,121, 4,147,251, - 9, 12, 40,151,145,207,229,118, 88, 74,152, 56,161,114, 32,180, 79, 28,112,181,137,121,141, 20,144,146, 44,214,231,178,101,203, - 20, 64,196,129,156, 42, 3, 78, 20,124,151, 10,178, 88,143, 33, 0, 90, 54,155, 44, 2, 56, 78, 66,156,124, 80, 46, 83, 64,139, -224,133,174, 28,212,221,123,248, 54,101,219, 42, 38,109, 5,192,105,129, 12, 42, 63, 68, 64,139,187,111, 8, 90, 56,121, 77,159, - 62, 93, 41, 35,213,136,180,217, 50,194, 71, 53, 15,203, 10,126, 42,128, 16,147,204, 43,130, 33, 74, 32, 40,121, 83,203, 75,208, - 68, 48,139,103, 78,234,209, 70,187,120,203, 58, 96, 93,240, 59, 57,233,178,190,120,141,147, 32,129, 54,251,149, 10,222, 72, 23, - 82, 45,163,131,240,103, 1, 90,237,219,183,111, 66,254, 97, 98,220, 0,187,141, 6,152, 48,222, 2,176,156,132,205,151, 98, 15, - 22, 18,160,133,122, 80,212, 19,218,131,128,134,192,149,124, 32,159,201, 87,238,152,211,227, 41,239, 59,163,167, 74,163,200, 95, -242,210, 40, 61,235, 59,105,147,245,152,101, 34, 29,130,161,185,115,231,202,208,161, 67, 5, 0,144,117, 98, 4, 92,105,139,127, -154, 0,139, 99, 37,203,194,205, 74, 52, 86,230,248, 77, 41, 46,141,235, 23, 46, 92, 40,176,191, 9, 4,184, 41,172,243,221,158, -142, 36, 90,180,121,163, 36, 11, 27, 1,104, 4,173, 72,200, 72,151,155, 16,248, 94, 78,154, 70,129, 22, 38,212,103,144,192, 42, - 42, 46,218, 54,162,159, 42,187,218, 32,109, 23,168, 84, 67, 4,180,240, 77, 17,209,167, 94,107, 65, 86, 72,164, 89, 70,218,196, - 63, 45, 15,250,254, 35,204,205, 31, 1, 45,242, 19, 27, 66,140,246,113,154,152, 4,170,187, 11,171, 86,173, 42,144, 48,189,193, -124,169, 21, 20,132,193,194,229, 13, 54,235, 40, 64,139,121,102,204,152, 17,232,140, 31,206,118, 29,142, 26, 53, 74,153,131, 56, -198, 19,100, 1, 36,250, 88,231,180,184, 0,218,239,169,158, 6,110, 56,171,210,181, 74,179,130, 97,145,127, 90, 29,184, 40,143, -190,123, 7, 62,172, 53, 68, 35, 40,226,128, 77,181,132,145,196, 65, 13, 12,115, 9,138, 72,147,131, 4, 7, 63, 53,241, 63,158, - 83,128,150,253,123, 62, 21,104, 1, 77,143, 4, 64,152,216,181,107,215,188, 70, 43, 75, 11,180, 84,144,117,114,211, 66,217, 49, -162,141, 12,255,249, 71, 41,152,249,187,195, 24,216,255,111,187, 5,227,121,163,180,153, 47,253,183, 81,178,101, 73, 18,195,167, - 75,243,186,129,108,128, 0, 91, 22,216,104, 44, 6,176,218,143,137,241, 17,120,126, 25,146,172, 45, 88, 5,210,144, 61,191, 30, -109,116,152,205,152,188, 47,170, 9, 43,232,123, 28,212,185,242, 44, 94,188,248,125,237, 61,230,213,163,199,251, 88,121,110,118, -165, 46,132,148,231, 34, 1, 22,147, 73,213,161, 34,205,226, 65,112, 64, 0,199, 14,200,195,172, 84,139,224,133,174, 29,232, 30, -129, 6,241,148, 12,144,142, 39,232, 51, 17,196,109,233,209,195,246,223,168,180, 72,229, 15, 87,220,156, 80,104, 96, 78, 85, 15, -203,109,132,119, 14,242,164,198,192,120, 22,131,202, 83, 38,128,216,215, 84, 65,241,219,249,205, 52,136,230, 68, 73, 49, 61,212, - 86, 2, 0, 79, 55, 5,223,187,122, 23, 13,118,105, 68, 93,171, 86, 45,101, 53,202,118, 68,201, 24,237,188, 88,247, 4,113, 20, -245,211,238,130,191,121, 96,128,230,106,212,136, 90,229,179, 0, 45,171, 61, 22,165,190,130,242, 91, 48, 1,191, 30, 56,112, 96, -173, 79,176,251, 82,128,209,227,167,207,101,255,145, 83,178,251,192, 49,217,190,231,136,108,222,113, 64,214,111,217, 35,171, 55, -236,144,229,107,192,231,131,222,134,129,145, 74,239,160,215, 25,217,123,232,132,236,220,231, 37,219,118, 31,146, 77,219,247,201, -186,205,187,100,213,250,237,178,239,208,113,195,244,172,117,152, 12, 54,100, 55, 97, 90, 16,196,246, 68, 9,228,180,105,211,132, - 19, 16,213, 55, 33,104, 83, 27,209,238,223,208,198,143,146, 49,142,153,148,106,113,162,133,196, 90,177, 85,194,152, 18, 8, 32, -123,212, 0,237,143,108,180, 0,200, 21, 27, 50,108,197, 87,218, 40,237,189, 84,144,197,133, 1,223,199,121, 1,188,114,185,168, - 86,223, 13,144,245, 12,192,148,118, 68,116,193, 33,148, 16,231,201,147, 71, 5, 88,157,209, 52, 9,178,205,104, 2, 20,210, 0, - 89,175, 41, 25, 83, 65,219, 39, 72,179, 12,176,201, 92, 22,189,157,139,246,247,205, 80,199,119, 47,135,148,233, 35,213, 33,118, -157,190,129,212,221,176,234, 48, 93,186,116, 15, 85,251, 44,170, 14, 27, 52,104, 32,165, 75,151, 30,138,178, 80, 96,240, 13,132, - 19, 67,177, 16, 80, 36,101, 4, 90, 84,245, 77,156, 56,209,176,125,162,234, 71,139,182,172,148, 46,211, 71,151,189, 31, 45, 72, -135, 31,209,140, 4,210,227,103, 42, 15, 84, 12,242,149, 26,197,235, 74,180,148, 21,145,246,227, 48, 33, 40, 54, 90, 92, 49, 27, - 73, 4, 69,122, 64, 75,165, 73, 59, 5, 53,241, 29, 4, 90,156, 40,236,223,195,107,232,160,134, 58,180,166,177, 42, 18, 45, 21, -100, 65, 36,106, 24,100,145,134, 86,117, 88, 46,111,218,155, 42,200, 26, 89, 57,141, 20, 72, 29,255, 1,193, 87, 72,129, 86,134, -111,163,102, 45,158, 41,197,179,227,235,230,200,146,223,139, 74,151,102,117,130, 96,228,147, 17,175, 29,134,196,221,107,156,100, -121, 30,130, 20,203, 76, 7, 84,243, 82,106,197,137,149, 82, 29, 12, 68,255, 72, 99,120,170,185,184,178,231,164,203, 68,192,193, -131,128,193,122, 45,151,222,183, 99,101,212, 83,235, 5,158, 46, 18, 72,131, 82, 30, 79,208,228,100,193, 51, 37, 59, 60,155, 1, - 90, 28, 92, 40,125, 32, 72,161, 17,176,181, 76,122, 69,114,116, 63, 51,140,161,239, 83,242, 64,201, 24,219, 55,109, 21,232,159, -134,147, 35,237, 34,104,104,202, 50,171,247, 57,153, 97,224,225,238,179, 31,157,189,144, 3, 53,212, 90,138,132,145, 18, 6, 74, - 11, 84, 94,242,236,226,158, 17,187,152,207, 2,180, 8,168,168, 34,164, 68,139,101,132,109,198, 95, 90,163,251, 79,145,104, 81, -122, 69,181, 41, 23,111,164,205,177,136,210, 93, 74,123,200, 31,163, 18, 40, 85,162,197, 49,137,234, 98,142, 81,164,199,186, 33, -216,160, 26,150, 0,199, 40, 61, 60,155, 28,182, 46, 87, 81, 54,203,200,145, 35, 95, 1, 12, 5,145, 6,119,243, 13, 24, 48, 32, -164, 64,171, 43, 22, 98,231, 89, 62,238,130,164,116,108,196,136, 17,202, 68,200,173,248,116, 73,209,161, 67, 7,250,184,162,235, - 7, 35, 71, 48,176, 69,208, 79, 59, 71,150,147, 96,158,187,195,181, 27, 55,216,175,120, 24, 85,159,131, 87,207,180, 32, 11,146, -215,158,120,156, 0,203, 8,232,119, 89,126,128,172,215, 4,152,255, 36,144,197, 2,235,237, 92,180,191,111,164,146,212, 60, 0, -169, 73, 33,109,124, 78,115, 0, 2, 86, 44,172,185,179,239, 13, 22,131, 47,176, 89,193,176, 49, 60,198,184,221,228,157,186,187, -144, 11, 61,210, 2, 16,126, 13, 0,196,157,156,138, 4,146, 32,139,121,168, 2,196,226, 96,183,209,178, 26,240, 12, 31, 17,101, -120,199, 29,173, 0,117,182, 5,135,138, 67,190, 82,160,229,154, 61,142, 80, 36, 65, 17, 39, 27, 14, 96, 70, 18, 7, 35, 61,123, - 42,210,228,106,136,106, 14, 53,241, 63,158, 11,228,243,246,239,225,181,144, 0, 45,136, 80,199, 82,146,101, 22,100,145, 75, 42, -208, 90, 58,127,110,157, 58,185,147,201,134,190,117,197, 41,200,130,100,139,249,141, 52,190, 52,241,163,102, 6,200,122,170, 2, -183,209, 85,210, 74,250, 68, 81,141,172, 58,141,144,183,229,193, 74, 69, 1, 90,228, 47, 38,249,127,164,123, 7,205,238, 66,155, -123, 7, 13,200, 50,108,167,101,199, 24,197,222,132,147, 35,129, 21,219,206,246, 94,189, 66, 34,209, 82,236,105, 8, 6, 9,180, - 62, 1,100,121, 64,146, 53,151, 32, 11,146,155,103, 0,192, 87, 33,134,191, 89,163, 70,141, 32,168,209, 20,128,197,196, 73, 18, - 91,234,149,149, 57, 1, 88,247,238,221,223, 99,101, 26,132, 62,241,151,171,138,135, 36,113, 59,129, 22, 12,163, 9,180,246,107, -243,186,186,103,160, 49,149,131, 52,180,168,179,157,135,144, 20, 22, 3,155,205,186,119,176,209,164,100, 11, 6,224,191,170,182, - 90,124, 79, 8,105, 58,148,104,193, 94, 82,252, 30, 60, 82, 36, 90, 43,214,110,145,109,187, 14, 26, 6, 70,142, 36, 90,164,119, -255,225, 99,155, 68,107,199,158, 67, 70,233,209,168,248, 60, 54, 59, 88, 0,136, 44,216,209,101,193,226,224, 42, 38,175,135,220, -113,101, 85, 29,134, 68,162, 21, 9,106, 65, 47,216,251, 61,162,218,153,106, 66,250,249,106,209,162,133,192,191, 25, 39,195, 27, - 48,105,160, 13,153, 17, 80,173, 54, 7,130, 45, 79,216,141,221,197,164,247,154,125, 8,186, 28,197,173, 3,221, 90,216, 39, 43, -208, 50,180, 73, 9, 99,254, 51,170,159, 66, 19, 96,169,133,134, 36,230, 53,165,192,255, 37,160,197,111,135,171,133,100, 61,122, -244, 88, 1,240,254, 20,110,124,158, 99,254, 94, 3, 91,213,148, 6,250,182, 45, 11,120,247, 29,128,249,123,242, 79,235, 59, 11, -115, 6,129,143, 98, 67,167, 94, 39,136, 95,177, 98,197,123,216, 20, 26, 6,114, 6,202,210,150, 54,175, 28,191, 32,125,101,100, - 21,229,248, 23, 72,180,236,213,135,255,103,133,163,143, 3,192, 81,236,169,216,225,232,226,193, 81,135,211, 94,163, 88,220,193, - 14,193, 96,142,215, 72,147,192, 74,251,156, 10,180,168,246,176,127, 7,175, 97, 96,178,151,104,233, 57,115,107, 4,144, 53,201, - 36,200,178,209,212,170, 14, 11,101, 76,121,170,102,182,132, 82, 48, 77,130,187, 31, 73,178,172,234, 67, 23, 64,203, 70, 51,125, -194,104, 25, 74,100, 74,241, 68, 43, 29,203,153, 44,198, 83,170, 17, 13, 52, 72,109, 22,189,111,247,192, 14, 57,197,189, 3, 87, -229,248,253,181, 56, 44, 85,157,152, 26,118, 88,234,128,111, 10,208, 34, 88,167, 36,148,237,138,128, 73,123,224,153,147,118,207, - 57,226,167, 34,205, 34, 80, 13, 33,200,178,209,196,196,125,157, 18, 42,168, 76,148,173,240, 24,192,218, 19, 0,218, 31,188,134, - 13, 22, 10,176, 3, 72,122,197, 51,158,189,160, 41,171, 67,135,165,144, 14,109,135, 88,126, 55,242,165,177,251,174, 84, 46,238, -169, 89, 29,182, 37, 72, 91, 82, 19, 72, 81,194,228, 36,241, 94,122, 39,237,246,139,209,228,251, 85, 9,148, 86,162,165, 70,173, -160, 77, 33,213,210,220,129,233, 64, 2,229,176,156,142, 36, 90,170,179, 78, 85,162, 69, 9,143, 19,137, 86, 48,154, 0,191, 83, - 0,178, 95, 64,170,102,153, 60,121,178, 5,160,155, 59,136, 57, 25,166,133, 10,229, 30, 39, 25, 24,116,223,208,233,255,206,250, -123, 70,128,169,227, 0,107, 71, 48,118,251, 97, 87,224, 27,216,207,220,198,132,184, 7, 42,226,227,160, 73, 41,185,179,195,213, - 24,146,128, 97,210,160, 46,127,207,246,207, 29,177,148,156,177,125,170,106,105,206, 9, 84, 89, 98, 33,160,117,101,211,205,217, -203,208, 86, 58,132, 80,130,165, 59,214,105,104, 23, 50, 56,142,234,210, 52, 72,199,229,152,172,183,115,209,254,190,131,119,126, -145,114, 2,104,245,165,249, 65,217,178,101, 29, 58, 43,165, 36,171,101,203,150,138,166, 11,210,119, 71,238, 98,204,150,147, 82, - 76,218, 36, 14,194,187,223, 81, 53,253,203, 47,191,112,156, 45,163,242,224, 43, 7, 90,234,103, 24,119,127, 3,209,223,126,236, - 50,129, 9,213,123, 91, 8, 30,118, 50, 53,169,110,245,213, 51,252, 75,189,179,235,124,124,105,176,138, 32, 77,172,238, 20,135, -141,106,226, 68,132, 65,233, 29, 85, 42, 4, 7,218, 4, 35,228,119, 24,160, 40, 6,119,217,176, 67,208, 57,236, 31,113, 8,180, -208,145,139,108, 90,191,178,198,179, 71,143, 74,240,183,195,228,220, 70,203, 70, 51, 67,210, 24,171,143, 65, 93, 72, 59, 47, 74, -199,114, 37,139,241,132,106,196, 16,148, 91,183, 97, 67,236,187, 73, 99, 63,101,196,104, 91,151,230,103, 40,167, 35,181,129,158, -186, 80,175,156, 39, 9,172,212,164, 26,130,155, 4, 90,170,138, 49,164, 32, 43, 88,155,167, 68, 11, 78, 37,109, 18, 45,216,208, -220,196,192,242,134, 18, 45,172, 22,223, 34,189,235,212,169, 19,109,169,130, 32,241,122, 8,149,225, 53, 24,140, 62,119, 32,209, -210,251,246, 16, 84,209,215, 31,226,132,192,232,209,147,103,114,248,216, 89, 57,232,117, 90,246, 29, 70,184, 28,216,106,237,216, -123, 68,182,236,252, 96,171,181,110,211, 14, 83, 64,139, 54, 95,135,143,157, 3,189, 51,176,253, 58, 41,123, 14, 30,135,173,214, - 81,217,186,235,144,108,220,182, 79, 54,108,217,173, 11,180, 0,118,126,130,170,229, 14, 36, 67, 22, 72, 44, 31, 99,220, 59,129, - 10, 74,161,169,164,180, 6,119, 25,186,170,119,213, 51,252, 58,208, 61,141,196, 51,213,133,122,146, 44,189,182, 20, 13, 64,242, -160,186,123,147,187, 46,169,113,224, 14, 76,238,240,100,162,106, 26,239,137,170,249, 30,167, 64, 43, 36, 13,211,250,140, 94, 57, - 67, 66,250, 75,210,212,219,185,104,127,255,139,205,113,218, 23, 97,179, 67,127,128,169, 64, 2, 42,130, 30,213,165, 7, 93,124, - 80,242,138, 13, 81,129,216, 25,216,223, 9,179,131,241, 19,187, 24, 83, 99, 28, 43,139,113,172, 13,210, 88,152,174,108,192,249, - 18,210, 35, 38,168, 58,223, 17,216,141, 29, 59, 86,113, 23,194, 29,135, 0,157, 51, 67, 82,145, 95,250,153,179,217, 63,104,174, -206,228,244, 40,194,223, 60, 59, 41,131,113,144,101, 37, 16, 13,157,237,160,218,185,244,206,232,124,180, 45,210,118,190, 96,147, -142, 51,154,120,199, 13,220, 43,199,179,253, 59,208,201, 15,227, 94, 52,187, 15,250,172,157,197,149, 31,173,144, 2,173,188,223, -199, 58,183,160, 69, 65, 21,100, 61,166, 26, 49,132, 13,229,179,126,123, 8,203,228,232,177,191,163,156,244,250,126, 82, 39,217, -123,134,119, 40,209,250, 68, 62,104,105, 42, 54, 90, 52,166,231,130,130,137, 11, 10,216, 65, 80,101, 68, 27,172,143,238, 59,177, -209,250, 59,248, 25, 18, 54,124,209,114,170,238, 29,172,147,191,205, 21,131, 1,247, 14, 14,203, 73,122, 4,111, 42, 61,173,123, - 7, 26,244,170, 46, 35,156,184,119,176,209,132,251,141,213, 80,133,223,131, 74,248, 26,164, 87,116, 99, 97, 63, 46, 26,229,237, - 23,229,167,209, 66, 57,200,215,249, 19,158,117,246,232,215,242,237, 95,125, 57, 1,176, 82, 65, 29,121, 16, 90,160,167,176, 29, - 13,130,116, 52, 8, 27,180,158, 65, 13,125, 8,234,194, 96, 62,174, 92,205,197,176,235, 75,131, 84, 9, 32,170, 43,206, 51,144, -246,163, 31, 60, 84,119,190,211,110,146,155, 43,168,238,166,218, 18,180,232,186,200,144, 47, 66,190, 23,243,111,110,164, 10,214, -179,250,187,164,122,237, 51,180, 65, 27, 73, 21,104,217,159,237,222,169,239,176,244, 51, 21,242,171,107,132,206,226, 28,218,199, - 61,212,254,119,194, 59,219,183,167, 77, 24,173, 72,158, 20, 49,189,177,219,240,104,186, 4,209, 92,137,245,245,170,225,171,227, -167,222, 7,153,184,255,181,126,123,106,216,169,204,225, 38, 5, 38,252,158,133,111,214,238, 42,212,187, 79, 22,125,173,223,110, -162,122,157,102,253, 26,191, 61, 5,193, 22, 37, 91,159,200,128,175,229,219,233,222, 38,180,143,175,229,219,255, 85,229,132, 13, -105, 88, 38,131,149,249,145, 68, 11, 11,203,178, 72,109,144,198, 34,109, 64,186,132,244,136, 9,230, 12,151,177, 17, 96, 21,104, - 15, 64, 50,235,214,132, 64,139,241, 87,169,117, 32,216,178,253, 86,175, 25, 44,115,136,178, 17, 96,169,137, 4, 84,192, 21, 34, - 98,159,225,161,127, 85, 35, 52,201, 31,247,183,155,100,152, 78,118, 55, 63,221,252, 12, 45, 14,184,219, 82,104,113,242, 3,157, -186,161, 75, 78,161,230,174,163,208,101,234,215,194, 79,167, 95,253,119, 2, 45, 19, 85,161,149,106,153,120,236,211,178,126, 45, -149,235, 46,231,167,213,179,253,211,110,126,186,249, 25, 90, 28,112,183,165,208,226,228, 7, 58,159,131,159,229, 66,183,136,159, -173,156,159,227,219,221, 52, 63, 67,229, 59, 34,249,119, 2, 45,213, 54, 75,149,106, 57,177,209,178,183,207, 10,246,159, 13,197, - 81, 50,195, 62,103, 52, 92, 93,215,163,239,166,233,184, 94, 66, 90, 95,110,126,186,249,105,180, 13,184,251,166,115, 14, 24,229, -161, 54,223, 63,157,159, 53, 81, 64, 35, 6,237,204,163, 77, 13,241,159, 32,203, 61,206,135,108, 14,253, 55,182, 37,245,155,244, -218,188,233,251,127, 39,208,178, 25,195,103,247,240,100,193,157,168, 14, 93, 2, 45,211, 31,108,226, 1, 55,218, 55,193, 44, 3, - 89,221,252, 52,192, 36, 19, 89,220,252, 52,193, 44, 3, 89,221,252, 52,192, 36, 19, 89,220,252, 52,193, 44, 3, 89,221,252, 52, -192, 36, 19, 89, 62, 7, 63,157,190, 30, 64,171, 24,252, 12,246, 64, 6,101, 87, 56,127,219,217,106,153, 40,186,185,172, 6, 37, - 90, 36,234, 86, 29,186, 96,237,231,104, 48,110,154,230,218,178, 94,110, 55, 63,245, 56,100,238,190,155,159,230,248,165,151,219, -205, 79, 61, 14,153,187,239,230,167, 57,126,233,229,254, 90,248,233, 10,104, 69, 4,176,202,163, 26,195, 91,119, 31,170,255,115, -235, 49,224,223,124,223, 85,229, 38, 9, 19, 46, 66,247,136, 81, 98,108,141, 24, 57,218, 61, 37, 69,141,185, 53, 28,174,129, 33, - 73, 62, 5, 20,193,155, 98,134,202,177,163, 92, 45, 19, 35,226, 45,252,206, 99,128,193, 14,203, 89,195,195,163, 96,253,136, 17, - 45,205,224, 55,198, 81,226, 61,230,113, 66,255,107,105,216,238,114, 26,104, 32, 38,178,184,249,105,130, 89, 6,178,186,249,105, -128, 73, 38,178,184,249,105,130, 89, 6,178,126,173,252,140, 6,215, 35,135,225,195,210, 79, 77,170, 11, 19,158, 85, 63,106,234, - 25,190,213,232, 8,247, 91, 59,126,216,127,123,104,208, 52,192,242,191, 63, 75,136, 84,135,154,248, 66, 69, 66,249, 19, 28, 54, -194,176,225, 35, 53,139,253,109,162, 7,191,119, 29, 18, 52,118,230, 26, 89,181,253,152,172,218,118, 76,198,204, 88, 45,173,186, - 13, 13,138,151, 48,201,131,240,145, 34, 53, 11, 9,128,201, 0,191, 91,229,162, 71,122,242,112,104, 51,121, 58,180,177,148,141, - 30,225, 9,175,233,124,215, 71,229, 36,128,106, 30, 47, 94,192, 99,120,197,183, 63,232, 12,147,142, 92, 31, 33, 54, 95,243,184, -113, 3,156,128,173,175,181, 3,134, 70, 19,248,183,124,123, 34, 4, 86, 29,138,129,232, 40, 98,127, 61,192, 0,228,141,193,105, - 4, 24,148,244, 83, 22, 2, 33, 96,240,191,133,159, 33,248,244,207, 98,188,109,136,159,233, 18, 69, 43, 84,245,167,140,183,243, -164,142,183, 58,109,146,232,113,205,142, 33, 33,249, 88,157,137, 44, 20, 72,126,113,126,186,138,105,232,234,158,161, 58, 50,201, -144, 96, 52,225, 52,214, 11,253,219,143,137, 1,190,153,208,191,149, 68,239,255, 76,246, 32, 4,215, 14,232,212, 81,106,228,217, -202, 24,143,120,214,101, 98, 30,230, 5,189,212, 46,104,198, 64,121, 70, 35,223, 93, 45, 16,114,246,155,249,152, 31,244, 98,184, - 42, 39,242, 28, 66,236,213,160,143, 38, 55, 7, 23,232,164, 28,254,253,130, 64,251,252,231,166,249, 25,177,136,201,166, 18,162, -236,174,109,180, 62,163,219,251,143, 58, 75,132,200,209,215, 20, 41, 83,227,197,146,141,135,165,219,144, 89, 82,174,126, 55, 41, - 80,165,157, 20,170,214, 65, 42, 53,238, 37,221,134,206,145,121,107, 15, 73,177,114, 53,253, 35, 71,139,181,198,193,231,186,236, -128,121,162,134, 27,188,187, 97,225,183, 50,189,137,200,212, 6,178,163, 86,158,183,188,102,102,144,180,129, 44, 4, 85, 61,191, -121,179,180, 75,156, 88, 58,197,143, 47,189, 32,217, 26,152, 40,145,140, 74,146, 68,166, 34,126,215,109,132,162,184, 15, 15,183, - 78,192,214,103, 31, 40, 66,212, 20, 62,126,200, 93, 78, 7,140,196, 32,220, 24,222,140, 31, 50,168, 52,227, 21, 50,172, 15,131, -235, 34, 90, 65, 16,226, 73, 62,196,224,220, 34, 36, 11,129, 16,214,153,187,142, 66,200,184, 79,169,163, 52, 9,162, 77,123,182, -119,162,156,159,219, 94,126, 74, 27,255, 98,186,120, 81, 18,185, 1,182, 67, 14, 56,107,159,174, 66,107,233,133,221,114, 72, 51, -114,228,200,116,246, 27, 44,136,186,253,127,248, 48,115, 22, 67, 50, 24, 77, 2, 44,246,107, 46,156, 9, 38, 24,149,132,161,228, -212,176, 75,188,167, 38, 6, 42,103, 72, 34, 56,179, 85,194,105,105,142, 96, 52,177, 32,219,194, 69,184,246, 32,125,103, 9, 49, - 63,133,207, 56,163, 73,208,228,233,233, 41,140, 48,193, 4, 79,237,178,100,201, 18,197,233,231,252,249,243,101,244,232,209, 74, -148, 21, 53,162, 10,203,143,144, 76,129, 86,176,229,180,156, 0,129,247, 88, 70,189,208,122,140, 75,203, 60,214, 80,121, 12,118, -255, 89,105,126, 70, 44,242, 73, 35,136, 65,207,240,137,241, 18,173,141, 22,255,255,255,248,140, 31, 23,172, 17, 66,146,213,164, - 96,137,170,254,203, 54,123, 73,149, 22, 67, 36, 93,193, 90, 31,225,231,156,165, 26, 73,131,206,227,100,222,186,163, 82,188, 98, - 29,255,240,145,162, 52,113, 85,185,218,123,144, 92, 37,252, 37,110,212,128, 55, 19, 91,203,237,133, 37,228,253,230,159,229,237, -136,250, 82, 35, 86,164, 0,222, 51, 50, 72,218,131,172,142,113,227,202, 10, 68, 50,223, 31, 59,182, 28,138, 19, 71,142, 34,121, -227,218, 62, 94, 79,158, 92,238,236,222, 45,119, 15, 28,112, 4,182, 92, 78,142,209,162, 69, 59,110,141,117,102,198,129,233,223, - 61,225,102,100,153, 89,118, 51,192,245,147, 90,248,255, 31,118,245,237,108,208,142, 86,199,244, 58,156,192, 72,189,107,243, 68, -130, 52,181, 73,147, 38, 1, 28,112, 25,184,151,158,141, 25, 50,130,241,238,124,124,124,228,206,157, 59, 12,155,243, 2, 3,100, - 59, 7,180, 93,149, 51, 28, 98,212,205,164,199,113, 4,109, 13,192,160,125, 31,239,154, 7, 26,159, 18, 54, 37, 12,104, 54,128, - 51,212, 85, 69,139, 22, 61,132,184,138,107, 65,243, 87,208,100,160, 96, 87,135, 94, 91, 34, 79,185,163,172,129, 53,149, 64, 28, - 70, 87,188,228,187,204,210, 44, 30, 66,154,148, 80,111, 64, 58,169,147,152,199,145, 52, 91,175,156, 10,223,210,197,143, 82,185, -115,213,236, 65, 47,215,182,147, 43, 83,234, 74,241, 12,241,125, 50, 36,142,156,220, 9, 83, 13,209, 52,217, 23,190,102,154, 10, -144,226,193, 51,146, 54,142,169,171,123, 42,139, 28,126, 59, 2, 16, 7, 17, 88, 56, 59, 8,140,152,199, 72, 29, 17,104, 49,100, -215,130, 5, 11, 4, 49, 62,101,213,170, 85, 2,175,232, 74, 48,237, 93,187,118, 9, 23, 89, 8,222,173,196,250, 61,123,246,172, - 2,186,244,128, 86,212,168, 81,159,177,108, 42, 48, 67,192,116, 37,208, 61, 2,181,203,133, 11, 23,148,241,131,209, 31,248,159, -113, 51, 57,166,240, 25,187,242,218,190,157, 18,170,105,211,166, 73,245,234,213,133, 1,206,237, 19, 3,210,171,158,215,121,102, - 89,249, 62, 62,231,140, 38,175, 67, 34,230,203,114,170,207,176, 28,252, 70,150,145,193,234,175, 93,187,166, 44, 44,111,223,190, - 45, 4, 91, 4,112,248,118,151, 64, 43, 52,104,126, 70, 44, 98,178,235, 5,207,110,208, 51,188,235,119,124,161,143, 75, 18, 35, -118,130, 7, 11,215, 29,148,134, 61,166, 75,246,178, 45,157,118,150, 18,181,187, 73,251,161, 43,100,214,170,131, 18, 47, 65,146, - 7, 40,189, 43,155, 45,219,199, 21,136, 17, 97,222,137,223,203, 4, 62, 26, 91, 69,206,109, 70,120,194,171, 53, 68, 38, 85, 17, -175,250,121,223,231,143, 17, 97,174, 17, 78,211,238,138,234, 66, 74,178, 8,178, 86, 70,141, 42, 27,144,118, 3,108,169, 32,235, - 64,204,152,178, 37, 90, 52, 57, 4,240,181,235,187,239, 20,176,117, 11,210, 45, 62,107,228, 29,204, 67,241,244,206,157, 59, 5, -113, 9, 31,226,111, 78,163,207,253,141,249,114,102,203,150,237, 17, 7, 35,150, 61, 52,202,129,213,105,117,128,182, 7, 60,135, -144, 30,193,196,128, 95,127,253,213, 23, 0,131, 65,110,181,225, 28,194,241, 26,238,113,192,241, 68,210, 3, 30,106, 17,146, 34, - 38,225, 3,130, 44, 14, 90, 12,124,202,176, 17,184,166,252,231,224,200, 65,136, 3, 16,130, 68,179,109,166, 52, 88,246, 8, 80, - 77, 92,195, 74,244, 5,104, 91, 16,252,218,242,240,225, 67, 11, 98,226,189,192,234,242, 6,104,232,129, 45, 71,175, 9,131,144, - 49,179, 17, 63,244, 48, 86,156,222, 8, 4,236,141,129,221,123,246,236,217,135,112,125, 62, 30, 48,234,225,217,158,118,118, 12, -254, 13,186,116,233, 82, 6, 65,145,139, 49, 97,229, 92,162, 97,195,134,213,250,245,235,151,195,224,247,218,103,203, 9, 96, 90, -159, 52,193,211,226, 8, 92, 92, 20,113, 0, 75, 54,109,218,180,250,192,129, 3,179,154,164,185,129,193,154, 33, 13,120,129,122, -240, 71,122,206, 4, 0,252, 12,147,194, 83, 72, 32,159, 96,178,121,178,123,247,110,127,208,117, 36, 21,255,232,117,233, 18, 70, -251,189, 67,157,146,150, 63,154,148,151, 30, 13, 74, 73,215, 58, 69,164, 83,141,124,210,173,102,110,217, 57,168,178,188, 94, 82, - 87,110, 77,172, 32,101,179,124,251, 44, 83,220,232,166,189, 90,155,252,190,175, 61, 59, 23, 61,202,248, 78,160,177,126,253,122, - 45,216,178,129,172,103,207,158, 41,147, 56,243, 34,185, 82, 35,218,248,129, 62,180,117,226,196,137, 65,236,159,148, 48, 65,253, - 37, 55,111,222, 84,192, 1,250,147, 2,140, 48,166,216,135,218,114,200, 79,170, 10, 9,218, 84,144,197,120,127, 44,203,162, 69, -139, 20,144,197,197, 21,131,147, 19,128, 48,208, 59,129, 22,250,149,189, 68, 43, 24,109,188, 91, 1, 90, 44,155,250,237,136, 39, - 40, 45, 90,180,144, 94,189,122, 41,241, 3, 73,151,227, 8, 3,158,147, 62,159,113, 86,225, 4, 76,136,127, 42, 85,171, 86, 53, - 4,180, 72,143,101,117, 0,180,130,189, 66, 5, 69, 28,211, 8,178, 88, 30,130, 63, 71, 32,139,192,205, 9,208, 10,117,154, 95, - 8,139,152,238, 95,161,226, 25,254, 75,232, 69, 97,248,222,173,105,135,129, 65, 67,167,111,146,226,141, 71, 72,174,242,173,108, - 64, 43,123,137,134,146,187,116, 99,219,255, 82,245,122, 74,163,222, 11,100,212,220,221,210,178,219,240,192,112, 17, 34,235,250, -120, 65,240,192, 52,191, 37,137,107,121, 55,177,133,156,156,249,147,132, 13,243, 65,188, 44,123,127,150,192,129,149,164,105,252, -232, 1,204,163,199, 97, 26,189,243,160,186,112, 37,192,213,250, 40, 81,228, 29,196,198, 94, 77,154,200, 62,252, 63,128,196,223, -188,182, 61,122,116, 57,151, 32,129,156,201,158, 93, 89, 69,252, 10,245,162, 30,125,245, 62,245,255,124,207,131, 7, 15, 24, 96, -248, 17,194,117, 20, 54,250,172,125, 62,198, 94,211, 26, 53, 58,251,237, 36, 70,155,238,107, 89,182,130, 5, 11, 62,230, 55, 18, - 96,176,236,186, 15,233,100,128,120,191,108,237,218,181, 49,214, 62,227,106,237, 25,255,155,164, 73,224, 52,104,202,148, 41, 79, -200, 71, 43,160,210, 74, 92, 18, 19,128,241, 30,243, 48, 47,146, 46,216,130,196,110, 32, 87,179, 28,188, 85,144,197, 85, 95,132, - 8, 17,148, 1,140,177, 10,185, 42,229, 0,143, 1,154,118, 11, 99,140,148, 27, 82,166,217, 4, 89, 4, 88, 24,184, 45,231,207, -159,183,128,142, 5, 3,178,101,216,176, 97,254, 24,108, 23, 27,161,163,205, 67, 73, 22, 38,177,195,207,159, 63,247,198, 0,235, -141,119,120, 99,240,246, 14, 8, 8,240,198,128,126, 16,255, 77, 7, 56, 5,253,196, 0, 89,141, 48, 25, 20, 3, 96, 41,170, 77, -248,246, 34, 80, 75,212, 3,200,209, 6, 72, 54, 82,236,164, 4,110,251,246,237, 43, 81,178,100,201, 33, 0, 92, 23,153,240,123, - 40, 0, 87, 41, 0,197,250,123,246,236, 73,102,132,144, 53,207, 73,240,206,223,209, 10, 95,123, 13,125,139,245,126, 18,201, 85, -188, 54,133,100,213,124, 63,220,125,119,116,154,188, 59, 52, 65,222,238, 29, 46,111,183,123,202,219,141,157,228,245,170,223,228, -205,134,142,242,102,245,111,242,122,102, 25,241,159, 92, 72, 90, 22, 74, 28,152,254,219, 24,102,219,171,137,207,251, 87,100, 85, - 0, 21, 65,150, 29,216, 82,198, 87, 2, 17,212,185, 35,105,151,222,199,103,135,129,118,128, 42, 49, 82,129, 22,165, 68, 84,217, -229,206,157,251, 37, 8,104,165,103, 78,233, 17,104, 17, 64, 80, 37, 71, 0,196, 62, 78, 80, 67,176,162,130,172, 51,103,206, 40, - 0,132,146,109,244, 43, 2,173,219,174, 10,168, 2, 45,130, 62,180,107,249,165,102, 77,241,246,242,146,203, 24, 59,152,206,130, - 30,191,155,224,134,239, 65, 60, 64,151, 64,139, 42,192, 70,141, 26, 73,187,118,237,164, 77,155, 54,130,152,132,242,219,111,191, - 9,131, 62, 99,124, 83, 18,199, 37, 74,162, 88, 86, 2, 77,220,127,231, 64,117, 24,172,216,224,161, 50, 54,178, 28,197,138, 21, -147,252,249,243,219, 18,223,193, 52,124,248,112,217,190,125,187, 82,127,228, 19,194,135,249,186,250,118, 45,205, 54,209, 61,228, -215,104,255, 79, 88, 84, 9, 19,213,158,124,167, 51,154, 95, 2,139,232, 53,176,175,250,126,196, 40, 49,183, 12,153,180, 66,126, -239, 55, 95, 74, 55, 27, 35, 69,235,122, 74,254,202,176,125,168,214, 81, 10,215,232, 44, 69,170,254,110, 3, 90,101, 27,244,150, -166,158, 75,228,143,241, 27,101,216,212, 53, 18, 45,102, 92,123, 29,246, 71,188,248, 41, 86,248, 29,215, 58,253, 28,116,239,175, -114,114,121, 71, 41,155, 14, 95,174, 65,170, 53,165,180, 92,104,152, 51,136,121,244,152,168, 2,173,142, 0, 77, 7, 40,177, 2, -152, 34,176, 10, 66, 39,230, 89,251,251, 4,212,136,215, 96,179,117, 53, 83, 38,197,142,167,201,183,223, 26, 6, 90, 4, 67,170, -232,150, 19,119,174, 92,185, 30,135, 0,108, 40,159, 19, 59,118,236, 27, 28,104, 92, 29,188,207,124,122,223,111,127,159,101, 66, - 68,247,167, 92, 65,178, 19, 19,128,176,236,102,233,104,243, 3, 0, 20,198,132,248,148,171, 73,170,225, 32,137, 17, 0,185, 39, -188,110,144,110, 48,144,101, 5, 82,158, 14,158, 29,160, 2, 49,163, 96, 11, 43,189,131, 4,147, 39, 97,159, 71, 73, 22, 65, 22, - 87,180, 28,132,239,222,189, 43, 22,139, 69,177,231,224,234,150,146, 45, 12,188,199,140,148, 25,131,208, 93, 72,157, 44,219,182, -109,179,204,157, 59,215,130, 1,197, 2,137,139, 5,245, 98,193,247, 91,168, 70, 52, 66, 71,155, 7, 82,182,149,148,100, 97,176, -246,198, 0,230,141,123,202, 25, 34,127,111, 0, 88,239,164, 73,147,174, 55, 75, 19,249,203,116,232,208,161,140, 61,200, 82,255, - 99, 80, 47, 11,176, 88,205, 36,221,114,221,186,117, 43,141,118,212,159,147,175, 54, 17,108, 1,116,150,199,192, 91,197, 4,205, -147,152,248,158, 1,184,250,172, 88,177,194,103,237,218,181, 62, 91,182,108,241, 1, 63,125, 80,103, 62,152,192,124, 80,103, 62, -160,249, 24, 52, 79, 34, 49,128,183,203, 3,246, 88,109, 27, 22, 73,243,182, 85,217,244,114,121,106,109,121,179,172,161, 2,176, -130,158,248,216,186, 85,208,163,171,242,122, 65, 53,121, 57, 38,131,212,203, 25,251,117,234, 56,113,236, 13,142,245, 94,243, 57, -238,115, 91,251,126, 36,142,109,121, 63,199, 11, 62,129,102, 48,176,181,113,227, 70,133,151,236,239, 33, 4, 89, 74, 81, 48,142, -237, 67,127, 14,210, 74,180,184, 96,101,159,197, 66,105,159,209,242, 82, 50,207,254,204,201, 29,113,248,148,118,137,152,124, 2, -201, 61, 23,191,146, 51,103, 78,142,203, 12,128, 44,104,163, 74,223, 55, 10,180, 8, 0, 17, 51, 48, 24,200, 82,193, 22,207,228, - 1,199, 83,142, 49,174, 36, 90, 40, 83,104, 25,195, 7, 99,139, 10,138, 40,201, 34,200,162, 29,152,154, 8,130,212, 68, 16, 71, - 62,211, 70, 11,227,137,189,234,208, 41, 77,130,172,245,223,254, 63,105,231, 38,214,149, 81,154, 70,235,242, 75,231,115,178,235, - 80,149,246,171,182, 90,193,109,180,190, 68, 33, 97, 4,127,123,193,186,195,242, 75,199,169, 82,254,183,113,242,115,171, 9, 82, -165,237,100,169,244,251, 88, 41, 92,173,157,173, 30, 38,207, 90, 34,229, 27,245,149,223, 6, 44,151, 78, 35,215,201,220,117,222, - 18, 37,122,108,151,171, 8,216, 95, 21,232,147, 54,177,229,221,184,134,114,124,193, 79,242,242,108,149,224, 64,203,171,146, 4, -245, 41, 42,221,146,197,164,173, 86, 1, 87,223,171, 2,173,158,144,108, 41, 54, 89,180,199,178, 74,177, 8,182, 84,192,117, 12, - 32,140, 32,235, 6, 36, 95,119, 50,103, 86, 0, 67, 72,128,214,142, 29, 59,132, 81,205,185,106,194,106,236, 73, 8,213,104, 25, - 97,247,115, 31,134,218,138, 56,218, 62,241, 58,239,227,187,205,216,131,121,176, 44,148, 58,177,147,113, 21,194,178, 82,111,255, -137, 64, 43, 39,108,137, 30,211,120,147,160,141,101, 37, 8, 36,216,196, 32,103, 84,141,218,215, 14, 64,237,194,183, 77, 66,154, -104,151,120,109,151, 93,222,174,174,234, 31,131,184, 47, 7, 1, 2,172, 52,105,210, 56, 52,186,133, 93,145,208,182,131, 96, 11, -171,188, 59, 70,250, 79,198,140, 25,253, 33,121,178, 96, 64,167,122,217,150,240,188, 5,134,178, 22, 12,224, 1, 70,232,104,243, - 20, 40, 80,224, 32,213,133,168, 39, 5,100,169, 9,146, 46, 69,141,136,114, 30, 49, 75, 19,249,235,163,158, 63,146,102,169, 64, - 11, 19, 72,113,116,214,206, 38,233, 54,160,250, 17,188, 61,205,201, 76,155, 40,217,130,164, 20,122,126,233,100,130, 38,129,214, - 19,130, 44, 72, 76,124, 96, 83, 19, 12,100, 97,242,240,129, 10,196, 7, 60, 96,123, 58,137,164, 11,180,144, 39, 76,134,132,209, -103,173,237, 95, 93,222,172,105, 41,175,231, 87, 1,200,186, 46,199, 46,222,151,218,189,215, 43,137,191, 3, 31, 92,144,151, 67, -147,139,119,219,120,130, 0,241, 4,142,127,247, 65,149,185,202,211, 19,127,119, 97, 28,188, 95, 1, 91, 4, 89, 92,192, 0,164, - 11, 36,155, 33,145,100,105, 73,231, 71,127,121, 65,125, 24,145,170, 0, 0, 17, 55, 73, 68, 65, 84, 48, 64, 64, 67,131,114, 74, -155, 32,153, 97,191,202,111,148, 7, 4, 90,236,195,155, 54,109,146,100,201,146, 41,101, 34,192,162,241, 55, 85,125,148, 28, 81, -157,216,160, 65, 3, 69,165, 70,169, 14,222,235,178,191,171, 18, 45, 74,152,218,181,109,171, 72,177, 72, 87, 5, 89,234,111, 46, - 92, 41,205, 34, 47,116,128,150,209,207, 49,149,143, 11, 63, 78,186,156,119, 92, 1, 45,242,149,210, 67,142,215, 0, 90,122, 18, - 45, 27, 77, 87, 64,139,239, 53, 74,211,212, 71,253,253,153, 85, 13,130,253,249, 67,201,128,232,139, 88, 69,118, 69, 62, 87, 89, -225, 39,235, 14,119, 19,214,237, 50, 29, 32,107,162, 84,109, 55, 69,106,116,156, 38,197,106,117,147, 19,167, 47, 40, 64,107,242, -172,165, 82,161,241, 7,144,213,106,240, 42,233, 58,102,163,204, 93,127, 76,162, 68,139,237,178,113, 23,141, 21,225,220,189, 63, -170,201,237,241, 37,197,103,119, 25,161, 20, 75, 29,124, 20,137, 22,211,172,226,114,171, 65, 70, 97, 94, 87,223,168, 2,173,254, - 0, 80, 4, 89,199,226,197,179,169, 11,181, 64,139,210, 44,130,172,219,216,129,120, 27, 18, 45,118,118, 51, 64,139,219,115,249, -205, 92,209, 48,113, 53, 70,113, 53,221, 8,132,176, 14,114,162, 35, 60, 56,120,240,160,162,222, 82, 19,255,243, 58,104,154,182, - 3, 99, 89,168,218,227,160,161,150,147,224,136,101, 15, 97, 25, 51,230,201,147,231, 17,129, 27,213,144,218,114,146,127, 4,115, - 41, 82,164,208, 5,132, 81,162, 68, 57,233, 82,124,231,226, 38,158,229,234,223,233,129, 1,232, 48,129, 31, 87,176,148,100,241, -123, 57,160, 67,178,167, 12,230, 60,184,131,136, 3, 15,237, 75,192,219,147, 70,120,193,129, 77, 85, 27, 82,146,165, 38,170, 15, -121,221, 10,132,141,144,178,229, 73,153, 50,229, 74,128, 66,111, 12,150,222,152, 44, 20,160, 5, 27, 58,111,128,126, 5,104, 97, - 82, 88,103,138,224,135,204,117, 80,182, 96, 42, 67,173,116,203, 10,138,168,134, 53,115,212,165, 77,150, 11,160, 85, 18,108, 29, -104,130,224, 73,212,209, 35, 21,100, 65, 58, 98,147,100, 17,100,225,158, 15,218,147, 15,128, 45,219, 61,235, 71, 15,104,125, 0, - 89,127, 86,129,138,176,165, 60,157, 86, 26, 54, 89,245,148,186, 38,192,202, 88,103,182,146,248,155,199,203,113,217,196,210, 39, -178, 20,251, 33,186,203,177,196,196,247,124, 74,214, 83,234, 88,135,179,215,167, 16,250, 76,207,218,108,178,216,143, 40,197,230, -152,100, 45,179, 33, 21,159,163,114,209, 12, 98,250,244,233, 10,208,226, 88,194,133, 17,198, 43, 83,223, 79,160,133, 54,162,168, -199,102,206,156,169, 72,173,203,151, 47,175, 72,170,217,239, 41,193, 38,109, 74, 96, 88,118,142, 91,102,128, 22,213,144,174,128, - 22,199, 84,244, 53, 61,160, 21, 3,223, 58, 26,101, 53,228,222,129,249,152, 31, 60,115, 41,109, 77,144, 32,193, 29,182,101,142, -193,122, 64,139,160,144,245,134, 69,162, 75,160,165,165,169, 7,180,156,209,252, 18, 88, 36, 36,237, 92,245, 12,175,198, 56,116, - 34,209,178,151,100, 5, 55,221,248, 18, 6,104,145,162,198,220, 54,104,226,114,105, 55,120,137, 21,100, 77,151, 90, 93,102, 74, -201, 58,244,162,255,225,168,208,216, 83, 90, 2,100,181, 6,200,106, 55,108,173,244,159,186, 83,134, 77, 91, 39, 49, 98,197,221, -230,140, 57,153,195,122, 84, 27,159, 55,245,203, 55,163,107,201,241,165,133,228,205,197,106,142,129,214,153, 42, 34,221,115,200, -208,212, 49, 45,124,198, 25, 61, 2, 45, 78,164, 35,146, 38, 85, 64,214,161, 88,177, 28,170, 14,189,161, 70, 60,139,251, 42,208, -162, 68,198, 12,208,162, 35, 56,126,179, 42,125,162, 61, 16,140,183, 31,133, 80,162,165,124, 14, 85,111, 80, 39, 61,164, 56,152, -131, 4,207,252,111, 66, 37, 23,140, 45, 44, 11,203,196,178,169,229,228,170,148,101, 15, 73, 99,133, 61,211, 13,130, 23,130, 55, -150,207, 62,113,208,132,228,131, 54, 96, 55,116,232,123,126,130, 68,171,163, 43,218,216,137, 52, 4,170,168, 32, 14,180, 4,152, - 28,136,168, 50, 32,208,226,138,150,101, 39,224, 34,208, 66, 62,193,224, 50,206, 8, 47, 80, 7,115, 70,142, 28,137, 5,244, 11, - 5, 88,241, 12, 26, 22, 52, 1, 75,251,246,237, 67,106,163,213,100,242,228,201,135, 48,104,121,195, 38, 68,177,209, 66, 59,244, - 6, 77,239,206,157, 59, 31, 0,168,108,105,164,108,118,121, 10,192, 94,165,132, 51,213, 33,202,141, 14, 38,109, 77,210,253,137, - 52,157,169, 14, 81,126,172,132,164,149, 9,154, 4, 90, 15, 41,201, 34,200, 2,136,243,129, 81,175, 15,192,177, 15, 38, 73, 5, -100, 97,130,244, 65,189,177,157,234, 1, 45, 5,100,173,243,172, 36,111, 86,254, 42, 75, 91, 3, 68, 77,200, 45,175,231,254,236, - 28,104,141,201, 40, 47, 7,124, 43,117,114,197,161,177,253,223,125, 20,181,126,227, 21,156,139,253,221,133,177,123,191, 13,100, -209,102,137,227, 8, 65, 22,143, 80,144,106, 21,195,196,255,130, 38, 27, 4, 75,165, 75,151,166, 52,203,212,247,211,214,148,253, -153,106, 76,130, 30,168,183, 21, 0, 72,219, 42, 46,182, 56, 6,112, 49, 69,144,197,119, 16,108, 0,104,217,239,230, 11,246,201, -170, 68,139, 96,141,224,237, 28,198, 59,173,202,144,191,175,227, 30,199, 16,130, 44,130, 60, 87, 18, 45,130,166,229,203,151, 67, -128, 30,248,209,242,145,215,180,110, 41, 56, 78,241,123, 48, 54, 6, 90,193,150,211,230,160,130, 34,218,158,209, 30, 75,171, 46, -212,170, 17,137, 13, 56,214,241, 93, 70,129, 22,105,210, 30, 75,123,104,213,136,167, 59, 53,119, 74,243, 75, 96,145,144,244,145, - 80,219,117,168, 26,161,133,164, 16, 70,158,161,199,247, 95, 59, 12, 12, 28, 49,107,155,212,236, 56, 93,106,119,153, 37,245,186, -207,149,210,245,254,144,236, 69,170, 75,142,162, 53,164, 82,211,126,210,122,200,106,105, 55,124,173,116, 26,181, 65,198, 47, 57, - 36,191,119, 31, 25, 24, 33, 66,100,122,139,255,232, 40,130,157, 42,165,163, 71,188,247,212,179,186, 92,159, 88, 84,238,236, 47, -247, 65,122,229, 44, 45, 44, 42, 15,234,165,146, 82,209, 34,220,227,179,142,104, 18,104,209,168,114, 10,252,100,237, 7,144,218, -138,221,133,170, 49, 60,213,133,148,100, 17,100,241, 26,119, 34, 42, 64, 11,122,124,118, 44, 51, 64, 11, 13, 93, 1, 90,156,200, - 57,248, 64,205,243, 48,164, 54, 90,218,239,192,228, 90, 22, 42,184, 71, 4, 9, 60,243,191,145,250,113,150,135,101, 98,217, 84, - 73, 25, 7, 54,150, 61, 36, 52,161,114,244,162,107, 3,189,196,124, 58,244, 29,217,104, 13,112,240,140, 61, 32, 51, 98, 16,159, -130,187, 14,169, 10,166,154,148,131, 45, 7,179, 76,144, 90,114,160, 85, 65, 22, 87,183, 0,161,148,152,216, 59, 27,116, 86,244, - 72, 0,113, 55, 6, 12, 24,192, 93,114, 22,238, 60, 4,109, 5,100,225,250, 77, 60, 20,162, 93,135, 0,189,243, 96,180,122,144, -146, 45,117,231, 33, 65, 22, 86,182, 52,174, 55,180,147, 75, 91, 96,172,110,227,119,236,216,177, 26, 38,154,143,164, 90, 24,140, -139,161,201, 14, 69,130, 6,222,248, 1,117, 76,162, 78,157, 58, 85,133,237, 84,113,123, 99,120, 72,227, 32,130, 22,142,202,122, - 82, 39,237, 11, 79,162,191,221,199,196,237, 3, 41,176, 15,164,193, 54,144,133,122,243,129, 4,130,210, 44, 31, 76, 16,180, 41, - 57,137,228,148,118,250, 68, 81, 7,173,235, 83, 65,177,201, 90,242,123,102,201,144, 48,234,249, 83,221,191,147,151,195, 82, 74, -224,253,115, 31,171, 14,253, 78, 67,154, 21, 73, 2, 70,252, 40,121,191,143,125,193, 56, 23,254,115, 57,131,129, 44,238,176, 6, - 7,148, 68,144, 21, 26, 96, 11,253,230, 12,253, 73,113,135, 32,108,179,206,152,229, 48,129, 22,205, 4, 56,182, 81,141,199,197, - 36,129, 15,199,100,246,125,130, 44, 2, 68,130, 23, 74, 96, 8, 54,140, 2, 45,218, 54, 81,202, 70,179,144, 43, 80, 59,170, 96, - 75, 5, 89,220,237,199,119,193,182, 80,207, 24,254, 46,223,203,178,193,127, 95, 48, 87, 14, 90,183, 14,252,205,251,212,140, 80, - 2, 71,201,150, 43,126,192, 38,244, 54,235,128,227,155, 30,208, 82,253,130, 65,219,224, 82,162,165,165,169, 7,180,156,209,212, - 24,195, 27,182,119, 54, 91,239, 33,201,175,149, 96,169, 59, 16, 29,208,209,250,208, 82,127,255, 63,219, 23, 66,145, 73,226,124, -155,248,254,244,101,123,225,186, 97,185,212,239, 49, 87, 26,245, 90, 32,229, 26,246,177, 1,223,170,205, 7, 72,251,225,235, 20, -144,213,111,218, 78,153,185,234,168,196, 79,148,156,147,186, 67,247, 14,217,195,135,105,189,172, 76,166, 87, 47, 71, 84,146, 19, -171,138,200,251,203,213,109, 32, 75,237,212,193, 64, 23,165, 93, 61,178,200,156,108,113, 95,242, 89, 71, 12,167,139,134,135,232, -116,183,176,218, 88, 6, 3, 73,186,112,216, 6,131,248,227, 0, 88,215,173, 54, 89,231, 97,244,190, 27, 46, 30, 46,194, 96,254, - 54, 26,183, 15,108,160,206, 1,249,155,113,239,160, 2, 45,118,112,216, 7, 60, 8,169,212,201,209, 55, 96,133, 84, 29,106,154, - 7, 60,135,164, 81,217, 63,195,178,177,140, 44, 43, 87, 62, 33, 5, 90,161, 81, 22, 13, 13,251, 93,135, 28, 4,180,198,135, 9, -184, 19,145,141,203,168, 33,188, 74, 27,124,107, 83,179,102, 77, 2, 34, 69,117, 64, 59, 14, 14,118,170, 83, 64, 14,186,176, 93, -243, 7,143, 93,218,123, 57,248,222, 8,244,155, 69, 27, 55,240, 48,128,103, 72, 13, 9,136, 66, 2,178, 84,242, 97, 64,179, 49, - 38,128,181, 80, 99, 30, 1,136,197, 70,217, 40,236,228,166, 65,150, 74,112,194,132, 9, 89, 49,249,212,193,247,151,195, 36, 83, - 28, 60, 40, 5, 30, 80,234, 52, 4,169, 82, 72,234,113,210,164, 73,217, 72, 19, 0,169, 28,218, 80, 9, 72,245, 74,130,230, 47, -224,235, 48, 10,179, 77,210,228,174,195,123, 48, 38, 86, 64, 22, 22, 21, 62, 88, 69,251, 64, 66, 74, 3,120, 5,100, 1,116,250, - 0, 32,115,178,113, 9,180, 42,102,137,127,239,245,252,202,178,228,183,244, 4, 89,179,210, 38,136, 82,161, 79,201,152, 98,249, - 51,166,188, 26,151, 85, 2, 1,172,212,131,191, 95,253,149, 5, 54, 90,201,100, 83,251, 12,146, 54, 97,212,225, 38,203,253, 95, -201,110,115,239,192, 73, 95, 3,178, 8,190, 20, 0,166,130, 45, 2, 4,235, 88, 29,146,246, 90, 50, 76,152, 48,239,153, 64,195, -180,207, 49,246, 63, 26,165,115, 92, 35, 64,161, 6, 64, 5, 89,148,182,171, 32,139,146, 34,213,119,151, 81,160, 69,211, 3,154, - 66,168, 70,244, 28, 51, 72,135, 11, 53, 21,100,209,118,150,210, 51, 87, 18, 45,154,105, 80,195, 66, 16,101, 4,104, 49, 15,199, - 44, 61,243, 14, 21, 20,113, 65,201,221,133,174, 36, 90,106,251, 7,208, 50, 4,222, 72,147,187, 11, 93, 73,180,156,209,252, 66, - 88,228,239,233,135, 95,234,227,224,124,180,217, 79,165,107,248,207, 94,125, 88, 58,141, 88, 45,191,246, 93, 44, 21,155,120,218, -234,163,250,111,131,164,243,232,141,210,127,218, 46,153,179,254,132,148,170, 84,255,121,164, 40,209,155, 57,227, 74,149,184,145, -206, 60,237, 83, 85,222, 47, 44, 37,175,175, 79, 18,185,183, 88, 63,109,104, 44, 15,235,164,146,202,113, 34, 58, 92, 1, 41, 14, - 75, 17, 86,199,239,240, 97,185,133, 85,216, 78, 24, 62,159,135, 11, 7,130,172,155,170, 77, 22,165, 88, 76, 42,200,194, 22,230, -102,177, 99, 59, 11,197,227,176,248,148,234,176, 35,195, 24,154, 54, 73,166,237,167,254,134,150,146,147,101,229,224,193,178,255, - 13,239,119,244, 74,130, 45, 79, 2, 42,171, 31, 45,237, 96, 29,193,234, 71,139, 0,140,210, 46, 93,215, 14,218, 23, 64,244,222, - 6,126,178, 30,114,192,160, 40,156,131, 36,165,121,236, 43,144,120, 61,194, 32,109,198,120,251, 31,194, 46,227,197,192,132,147, - 20,192, 18, 43, 23,161,110,159, 82,172,246, 38,165, 78, 31,189,204, 74,147,128,141, 52, 9,176,218,134,144,230, 6,184,214,120, - 12,169,195,125, 76,136,208, 56,251,249, 1,184,221, 3,192,242, 69, 61,249,162,220,119,153, 96, 44,207, 93,135,220,141,231, 84, -162, 5,255, 89,173,106,100,143,119, 7,146,173,177,214, 54,242, 13, 0,212,230,149,117, 99,136,165,127, 92,177,244,139, 41, 47, -199,102, 86,146,101, 64, 60,236, 56,204, 40,151, 6,231,147, 60,223,197,242, 77,157, 48,218,183,198, 57,250,159,203,169, 0, 42, -141,159,172,143, 28,150,106, 64, 86,136,109,181, 62,133,171, 4, 90, 52,206,167, 75, 16,150, 83,207, 93, 8, 39, 42, 0, 45,151, - 82, 29,213, 97, 41,199, 73, 2, 42,126, 35, 84,219,138,253, 45, 37,103,116, 29,131,157,199,140, 48,161,128, 44,184, 75,113,228, -176,212,246, 89,148, 76,209,100,193,168, 68,139,239,164, 52, 78, 79,162,197,221,147,252, 30,142,105,148,172, 81, 2, 71, 16,200, -164,149, 42,161, 15,217,230,103, 61,160,165,165,201,239, 39,200, 86, 15,170, 11,213,116,188, 69, 29,167, 52,191, 20, 22,249,148, -118,227,226, 89,215, 18,173,207,244, 82,135,100, 97,171,181,233,167, 82,213, 95, 76, 91,182, 95, 70,205,219, 35,109,250,205,145, - 95, 90, 13,150,218,173,135, 74,167, 33, 11,101,220,226, 67, 50, 99,213, 17, 41, 82,182,230,139,232, 49,226,108,114, 85,182, 10, -177, 34, 28,184,210,180, 88,144, 12,169, 44, 50,160,188,200,159,165, 68,122, 23, 21,249,163,160, 72, 55, 4,245,238,148, 29,211, - 67, 38, 12,231,233,131,165, 51,197, 18, 5,241, 89,103,180, 85,176,229, 11,123,161, 59,232, 24, 39,177,221,247, 10, 84, 71,220, - 93, 72,195,119, 37, 65, 93,168, 72,178, 66, 0,178,248, 94,172, 56,188,160,246,185,129,159,166,118, 2,126,201,186,114,240,174, -140, 44, 51,203,254, 55,151,195,254,245,244,159,165,117, 86,170,222, 39,240,250,148, 45,182,223,225,123,167, 2, 88,158,165, 20, - 15,171, 64, 96,238, 4,211, 65,243,135,127,216,247,255,215,138,163,122,134,167,234,206, 85,218,141,251, 89,144,190, 51,195,160, -172, 64,217,105, 19, 68,221,217,173, 4, 54,195,116, 75, 37,207,198,192,110,107, 98,126,185, 60, 56,183, 76,168,151, 70,178, 37, -137,113, 51, 77,252,168,112,203,231, 62,116, 56,160,128, 45, 36, 71, 64,202,213,189, 47,194, 88,168, 14, 15, 67,154, 21, 72,169, - 22, 85,136,180,195,226,110, 56,130, 13, 74,160, 40,193,166,217,128,122,192,166,234, 29,198, 2,238,242,116,122, 48,156, 14,237, -117, 9,120, 40, 41, 35,200,162,221, 41,237,192, 40,217, 83, 65, 22,253,139, 17,100,209, 43,189,131, 16, 60, 54,250,180,181,130, -183,250, 64,170, 47, 89, 54,158, 89, 94, 74,160, 8,100, 40,189, 34, 88,162, 4,142, 18,120,154,176,244,237,219, 87,215, 70,139, -142, 87,249, 93,164, 65,176, 73,186,148,220,171,223,109, 31, 70,136,121,177,249,198,165, 68,235,115,208,252, 34, 13, 33,244, 95, - 18, 18,255,133,161, 95,138,240, 81,162,180,138,155, 32,233,131,230,157,134, 4, 13,158,180, 74,102,173,241,146,217,107,142,201, -144,201,107,228,183, 46,195,130,226, 39, 74,241, 32, 74,148,104,186,198,177, 48, 20, 73, 93, 49,102,132,227,213,163, 69,120, 89, - 61,106,248, 15, 41, 74, 56, 91,170, 22, 57,236, 75,251, 84, 21,215, 42,196, 8,127,140,207,186,250, 50, 21,108,209,227, 59, 27, - 51, 87, 60, 20,137, 82,167,205,142,196, 6, 77,117,161, 89, 73, 86,232,115,211, 77,209,205,129,255, 44, 7,232,136,148,210, 42, - 87,137, 32, 43, 36,106,169,111,224,190,161, 86,218, 4,209, 86,166, 79, 16,229,106,198,132, 81,111, 3,124,109, 75, 27, 63,106, -231, 28,137, 61,162,252,103, 57,110,254,195, 67, 26, 84,218,252,155,204, 63, 17,141, 96,139,155,123,152,184,152,210,218,143, 98, - 97,197,197,149, 31, 0,132,146,112,239, 16, 94, 17, 85,231, 53,169, 9,156, 40,217,162, 74,208, 85, 98, 30, 43,200,114, 53, 23, -125,150, 93,135,144,230, 93,209,238,162,166,105,132,154,168,170,180, 63, 40,241, 2, 47,124, 92,125,251,231,160,105,190, 74,191, -204, 19, 78,118, 29,254,115, 36, 90, 26, 54, 36,137, 16, 41,122,207,232,113,226,239,136, 26, 61,142,111,212, 24,113,124, 99,198, - 77,176, 3,170,194,158,200, 99, 40,228,206,231,102, 41,193, 22,237,174,232,241,157,134,238,246,137,247,152,231,115,151,195, 77, -223,205, 1, 55, 7,220, 28,112,115,192,205,129, 80,228, 64, 90,238,238, 86,129,165, 10, 42,181,192, 82, 5,152, 60, 3,136, 18, -100,233,133,158,250, 28, 52, 67,241,147,191, 34, 82,170, 14,213, 96,145, 13, 25, 40,154,116,187,255,183,210, 52,248,221,204,102, -182,156, 70,118, 89, 24,165,169,250, 69,243, 52, 80, 94,163, 52,109,186,251, 80,164,105,198,127,155,209,114,134, 42, 77,141,205, -128, 81,186,186,229,212,246, 33,131,253,201, 48, 77, 19,125,233,111,167,105,160, 29, 25,234, 71, 90,187, 14,131,187,167,205,124, -187,209,190,100,134,166,209,190,100,134,102,168,183, 79, 19, 62,141, 92,150,211,190, 77, 26,164,107,138, 38, 27,138,129,190,100, -138,166,193,190,244,143,160,105,160, 47,133,180,156,174,230, 37, 67,237, 83,235,163, 83, 83,247, 70,230, 38, 3,159,245,101,179, -168, 59, 14, 85,127, 90,118,111, 15, 29,149,161,193, 65, 76,251,110,221,138,208,102, 54,208, 81, 12, 13,188,159,139,166, 73, 67, - 61, 67,223,110,240,155,213, 79,250,219,104,170, 5, 48, 88, 94,163,229,220,109, 29, 32,149,179,206, 97,148,166, 50, 48,132, 70, - 57,181,237,221, 68,221, 27, 26,208,212, 50,134,118, 57, 77,212,147,225,114,126, 14,154,159,139,159,122,141,200,122,223,240,183, - 27,172, 31,221,113,201,209,216,105,128,182,153,114, 26,237, 75,102,104, 26,237, 75, 33,234,155, 58,223,111,154,230,167,242,211, - 89, 59, 15,205,114, 26,236, 75,166,191,221,192,152, 23, 34,154,161, 49, 38,107,203,102,160,142, 12,118,225,191, 55,219,103, 87, - 29,154,100,148,161,202,213, 76, 58, 69, 12,176,207, 20, 77, 3,244,116, 7, 73,109,231, 48, 1, 54, 13,149,211,224,170,201, 52, -208,210,174, 34, 66,179,179,112, 69, 98,128,167, 70,191,221,232, 42,220, 76, 29,169, 52, 67, 69, 66,104, 15, 8, 12,180,127,221, -111,215,210, 48, 64,207,208,183,219,211, 52, 80, 79,127,107, 57, 53,237, 94,175,158, 12,151,211, 68, 95,250, 91,105,154, 24,239, -204,148,211,104, 95, 10, 9,205, 80,169, 35,181, 77, 90,235,201,243, 83, 1,140,253, 24,103,160, 47, 25,250,118,109,223, 49, 48, -142,134,136,230,167,142,201,218,114, 25,236, 75,166,202,105,176, 47,233,210,180,111,235, 6,233, 26,152, 98,254,158, 44, 95, 68, -162,101, 0, 53,219,127,189,225,138, 48,193, 54, 67, 52, 13,174, 28, 76, 1,152,175,133,166, 9,105,129,161, 73,220,228,119, 27, -166,249,185,202,105,162,157,234,182,165,175, 13,104, 25,152,108, 12,183,121,123, 90, 6,104, 27,230,167,137, 54,245,183,210, 52, -209, 70, 77,149,211, 0, 47, 13,245,163,207,221, 62, 13,246, 37, 93, 41,153,118,124, 55,200, 83, 83, 52, 63,103, 57, 63, 5, 20, - 57,171,231, 79, 1,153, 95, 11, 77, 71,117, 98,176,238, 77,192,129,127,105, 86,131, 3,132,225,193, 92,131,120, 21,187, 5, 3, -108,211, 29,208,236,104, 22, 9, 45,154, 38, 38, 7, 67,131,228,231, 42, 39, 87,100, 6, 86, 98,166,234,200,224, 64,102,138,230, -231, 40, 39,104, 42, 43,101,237,170,212, 69,253,235,182, 37,205,192, 96,148,167,134,105,154,224,169, 97,154, 6, 87,183,134,218, -167,118, 80, 52,200, 83,195,229, 52,209,151, 12,211, 52,177, 90, 54, 67,243,107,169,247, 80, 47,167,137,190,164, 11,138,212,186, -177,182,121, 35,101, 53, 69,211, 96, 95, 50, 69,211, 96, 95, 10, 41, 77, 87,243,146, 41,154, 6,251,146, 41,154, 6,251,146,161, -126, 20,130,186, 55, 48,101,127, 93, 89,254, 7, 92, 51,104,174,242,165, 70,254, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130, +137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, + 13, 73, 72, 68, 82, 0, 0, 2, 90, 0, 0, 2,128, 8, 6, 0, 0, 0, 68,254,214,163, 0, 0, 10, 79,105, 67, 67, 80, 80,104, +111,116,111,115,104,111,112, 32, 73, 67, 67, 32,112,114,111,102,105,108,101, 0, 0,120,218,157, 83,103, 84, 83,233, 22, 61,247, +222,244, 66, 75,136,128,148, 75,111, 82, 21, 8, 32, 82, 66,139,128, 20,145, 38, 42, 33, 9, 16, 74,136, 33,161,217, 21, 81,193, + 17, 69, 69, 4, 27,200,160,136, 3,142,142,128,140, 21, 81, 44, 12,138, 10,216, 7,228, 33,162,142,131,163,136,138,202,251,225, +123,163,107,214,188,247,230,205,254,181,215, 62,231,172,243,157,179,207, 7,192, 8, 12,150, 72, 51, 81, 53,128, 12,169, 66, 30, + 17,224,131,199,196,198,225,228, 46, 64,129, 10, 36,112, 0, 16, 8,179,100, 33,115,253, 35, 1, 0,248,126, 60, 60, 43, 34,192, + 7,190, 0, 1,120,211, 11, 8, 0,192, 77,155,192, 48, 28,135,255, 15,234, 66,153, 92, 1,128,132, 1,192,116,145, 56, 75, 8, +128, 20, 0, 64,122,142, 66,166, 0, 64, 70, 1,128,157,152, 38, 83, 0,160, 4, 0, 96,203, 99, 98,227, 0, 80, 45, 0, 96, 39, +127,230,211, 0,128,157,248,153,123, 1, 0, 91,148, 33, 21, 1,160,145, 0, 32, 19,101,136, 68, 0,104, 59, 0,172,207, 86,138, + 69, 0, 88, 48, 0, 20,102, 75,196, 57, 0,216, 45, 0, 48, 73, 87,102, 72, 0,176,183, 0,192,206, 16, 11,178, 0, 8, 12, 0, + 48, 81,136,133, 41, 0, 4,123, 0, 96,200, 35, 35,120, 0,132,153, 0, 20, 70,242, 87, 60,241, 43,174, 16,231, 42, 0, 0,120, +153,178, 60,185, 36, 57, 69,129, 91, 8, 45,113, 7, 87, 87, 46, 30, 40,206, 73, 23, 43, 20, 54, 97, 2, 97,154, 64, 46,194,121, +153, 25, 50,129, 52, 15,224,243,204, 0, 0,160,145, 21, 17,224,131,243,253,120,206, 14,174,206,206, 54,142,182, 14, 95, 45,234, +191, 6,255, 34, 98, 98,227,254,229,207,171,112, 64, 0, 0,225,116,126,209,254, 44, 47,179, 26,128, 59, 6,128,109,254,162, 37, +238, 4,104, 94, 11,160,117,247,139,102,178, 15, 64,181, 0,160,233,218, 87,243,112,248,126, 60, 60, 69,161,144,185,217,217,229, +228,228,216, 74,196, 66, 91, 97,202, 87,125,254,103,194, 95,192, 87,253,108,249,126, 60,252,247,245,224,190,226, 36,129, 50, 93, +129, 71, 4,248,224,194,204,244, 76,165, 28,207,146, 9,132, 98,220,230,143, 71,252,183, 11,255,252, 29,211, 34,196, 73, 98,185, + 88, 42, 20,227, 81, 18,113,142, 68,154,140,243, 50,165, 34,137, 66,146, 41,197, 37,210,255,100,226,223, 44,251, 3, 62,223, 53, + 0,176,106, 62, 1,123,145, 45,168, 93, 99, 3,246, 75, 39, 16, 88,116,192,226,247, 0, 0,242,187,111,193,212, 40, 8, 3,128, +104,131,225,207,119,255,239, 63,253, 71,160, 37, 0,128,102, 73,146,113, 0, 0, 94, 68, 36, 46, 84,202,179, 63,199, 8, 0, 0, + 68,160,129, 42,176, 65, 27,244,193, 24, 44,192, 6, 28,193, 5,220,193, 11,252, 96, 54,132, 66, 36,196,194, 66, 16, 66, 10,100, +128, 28,114, 96, 41,172,130, 66, 40,134,205,176, 29, 42, 96, 47,212, 64, 29, 52,192, 81,104,134,147,112, 14, 46,194, 85,184, 14, + 61,112, 15,250, 97, 8,158,193, 40,188,129, 9, 4, 65,200, 8, 19, 97, 33,218,136, 1, 98,138, 88, 35,142, 8, 23,153,133,248, + 33,193, 72, 4, 18,139, 36, 32,201,136, 20, 81, 34, 75,145, 53, 72, 49, 82,138, 84, 32, 85, 72, 29,242, 61,114, 2, 57,135, 92, + 70,186,145, 59,200, 0, 50,130,252,134,188, 71, 49,148,129,178, 81, 61,212, 12,181, 67,185,168, 55, 26,132, 70,162, 11,208,100, +116, 49,154,143, 22,160,155,208,114,180, 26, 61,140, 54,161,231,208,171,104, 15,218,143, 62, 67,199, 48,192,232, 24, 7, 51,196, +108, 48, 46,198,195, 66,177, 56, 44, 9,147, 99,203,177, 34,172, 12,171,198, 26,176, 86,172, 3,187,137,245, 99,207,177,119, 4, + 18,129, 69,192, 9, 54, 4,119, 66, 32, 97, 30, 65, 72, 88, 76, 88, 78,216, 72,168, 32, 28, 36, 52, 17,218, 9, 55, 9, 3,132, + 81,194, 39, 34,147,168, 75,180, 38,186, 17,249,196, 24, 98, 50, 49,135, 88, 72, 44, 35,214, 18,143, 19, 47, 16,123,136, 67,196, + 55, 36, 18,137, 67, 50, 39,185,144, 2, 73,177,164, 84,210, 18,210, 70,210,110, 82, 35,233, 44,169,155, 52, 72, 26, 35,147,201, +218,100,107,178, 7, 57,148, 44, 32, 43,200,133,228,157,228,195,228, 51,228, 27,228, 33,242, 91, 10,157, 98, 64,113,164,248, 83, +226, 40, 82,202,106, 74, 25,229, 16,229, 52,229, 6,101,152, 50, 65, 85,163,154, 82,221,168,161, 84, 17, 53,143, 90, 66,173,161, +182, 82,175, 81,135,168, 19, 52,117,154, 57,205,131, 22, 73, 75,165,173,162,149,211, 26,104, 23,104,247,105,175,232,116,186, 17, +221,149, 30, 78,151,208, 87,210,203,233, 71,232,151,232, 3,244,119, 12, 13,134, 21,131,199,136,103, 40, 25,155, 24, 7, 24,103, + 25,119, 24,175,152, 76,166, 25,211,139, 25,199, 84, 48, 55, 49,235,152,231,153, 15,153,111, 85, 88, 42,182, 42,124, 21,145,202, + 10,149, 74,149, 38,149, 27, 42, 47, 84,169,170,166,170,222,170, 11, 85,243, 85,203, 84,143,169, 94, 83,125,174, 70, 85, 51, 83, +227,169, 9,212,150,171, 85,170,157, 80,235, 83, 27, 83,103,169, 59,168,135,170,103,168,111, 84, 63,164,126, 89,253,137, 6, 89, +195, 76,195, 79, 67,164, 81,160,177, 95,227,188,198, 32, 11, 99, 25,179,120, 44, 33,107, 13,171,134,117,129, 53,196, 38,177,205, +217,124,118, 42,187,152,253, 29,187,139, 61,170,169,161, 57, 67, 51, 74, 51, 87,179, 82,243,148,102, 63, 7,227,152,113,248,156, +116, 78, 9,231, 40,167,151,243,126,138,222, 20,239, 41,226, 41, 27,166, 52, 76,185, 49,101, 92,107,170,150,151,150, 88,171, 72, +171, 81,171, 71,235,189, 54,174,237,167,157,166,189, 69,187, 89,251,129, 14, 65,199, 74, 39, 92, 39, 71,103,143,206, 5,157,231, + 83,217, 83,221,167, 10,167, 22, 77, 61, 58,245,174, 46,170,107,165, 27,161,187, 68,119,191,110,167,238,152,158,190, 94,128,158, + 76,111,167,222,121,189,231,250, 28,125, 47,253, 84,253,109,250,167,245, 71, 12, 88, 6,179, 12, 36, 6,219, 12,206, 24, 60,197, + 53,113,111, 60, 29, 47,199,219,241, 81, 67, 93,195, 64, 67,165, 97,149, 97,151,225,132,145,185,209, 60,163,213, 70,141, 70, 15, +140,105,198, 92,227, 36,227,109,198,109,198,163, 38, 6, 38, 33, 38, 75, 77,234, 77,238,154, 82, 77,185,166, 41,166, 59, 76, 59, + 76,199,205,204,205,162,205,214,153, 53,155, 61, 49,215, 50,231,155,231,155,215,155,223,183, 96, 90,120, 90, 44,182,168,182,184, +101, 73,178,228, 90,166, 89,238,182,188,110,133, 90, 57, 89,165, 88, 85, 90, 93,179, 70,173,157,173, 37,214,187,173,187,167, 17, +167,185, 78,147, 78,171,158,214,103,195,176,241,182,201,182,169,183, 25,176,229,216, 6,219,174,182,109,182,125, 97,103, 98, 23, +103,183,197,174,195,238,147,189,147,125,186,125,141,253, 61, 7, 13,135,217, 14,171, 29, 90, 29,126,115,180,114, 20, 58, 86, 58, +222,154,206,156,238, 63,125,197,244,150,233, 47,103, 88,207, 16,207,216, 51,227,182, 19,203, 41,196,105,157, 83,155,211, 71,103, + 23,103,185,115,131,243,136,139,137, 75,130,203, 46,151, 62, 46,155, 27,198,221,200,189,228, 74,116,245,113, 93,225,122,210,245, +157,155,179,155,194,237,168,219,175,238, 54,238,105,238,135,220,159,204, 52,159, 41,158, 89, 51,115,208,195,200, 67,224, 81,229, +209, 63, 11,159,149, 48,107,223,172,126, 79, 67, 79,129,103,181,231, 35, 47, 99, 47,145, 87,173,215,176,183,165,119,170,247, 97, +239, 23, 62,246, 62,114,159,227, 62,227, 60, 55,222, 50,222, 89, 95,204, 55,192,183,200,183,203, 79,195,111,158, 95,133,223, 67, +127, 35,255,100,255,122,255,209, 0,167,128, 37, 1,103, 3,137,129, 65,129, 91, 2,251,248,122,124, 33,191,142, 63, 58,219,101, +246,178,217,237, 65,140,160,185, 65, 21, 65,143,130,173,130,229,193,173, 33,104,200,236,144,173, 33,247,231,152,206,145,206,105, + 14,133, 80,126,232,214,208, 7, 97,230, 97,139,195,126, 12, 39,133,135,133, 87,134, 63,142,112,136, 88, 26,209, 49,151, 53,119, +209,220, 67,115,223, 68,250, 68,150, 68,222,155,103, 49, 79, 57,175, 45, 74, 53, 42, 62,170, 46,106, 60,218, 55,186, 52,186, 63, +198, 46,102, 89,204,213, 88,157, 88, 73,108, 75, 28, 57, 46, 42,174, 54,110,108,190,223,252,237,243,135,226,157,226, 11,227,123, + 23,152, 47,200, 93,112,121,161,206,194,244,133,167, 22,169, 46, 18, 44, 58,150, 64, 76,136, 78, 56,148,240, 65, 16, 42,168, 22, +140, 37,242, 19,119, 37,142, 10,121,194, 29,194,103, 34, 47,209, 54,209,136,216, 67, 92, 42, 30, 78,242, 72, 42, 77,122,146,236, +145,188, 53,121, 36,197, 51,165, 44,229,185,132, 39,169,144,188, 76, 13, 76,221,155, 58,158, 22,154,118, 32,109, 50, 61, 58,189, + 49,131,146,145,144,113, 66,170, 33, 77,147,182,103,234,103,230,102,118,203,172,101,133,178,254,197,110,139,183, 47, 30,149, 7, +201,107,179,144,172, 5, 89, 45, 10,182, 66,166,232, 84, 90, 40,215, 42, 7,178,103,101, 87,102,191,205,137,202, 57,150,171,158, + 43,205,237,204,179,202,219,144, 55,156,239,159,255,237, 18,194, 18,225,146,182,165,134, 75, 87, 45, 29, 88,230,189,172,106, 57, +178, 60,113,121,219, 10,227, 21, 5, 43,134, 86, 6,172, 60,184,138,182, 42,109,213, 79,171,237, 87,151,174,126,189, 38,122, 77, +107,129, 94,193,202,130,193,181, 1,107,235, 11, 85, 10,229,133,125,235,220,215,237, 93, 79, 88, 47, 89,223,181, 97,250,134,157, + 27, 62, 21,137,138,174, 20,219, 23,151, 21,127,216, 40,220,120,229, 27,135,111,202,191,153,220,148,180,169,171,196,185,100,207, +102,210,102,233,230,222, 45,158, 91, 14,150,170,151,230,151, 14,110, 13,217,218,180, 13,223, 86,180,237,245,246, 69,219, 47,151, +205, 40,219,187,131,182, 67,185,163,191, 60,184,188,101,167,201,206,205, 59, 63, 84,164, 84,244, 84,250, 84, 54,238,210,221,181, + 97,215,248,110,209,238, 27,123,188,246, 52,236,213,219, 91,188,247,253, 62,201,190,219, 85, 1, 85, 77,213,102,213,101,251, 73, +251,179,247, 63,174,137,170,233,248,150,251,109, 93,173, 78,109,113,237,199, 3,210, 3,253, 7, 35, 14,182,215,185,212,213, 29, +210, 61, 84, 82,143,214, 43,235, 71, 14,199, 31,190,254,157,239,119, 45, 13, 54, 13, 85,141,156,198,226, 35,112, 68,121,228,233, +247, 9,223,247, 30, 13, 58,218,118,140,123,172,225, 7,211, 31,118, 29,103, 29, 47,106, 66,154,242,154, 70,155, 83,154,251, 91, + 98, 91,186, 79,204, 62,209,214,234,222,122,252, 71,219, 31, 15,156, 52, 60, 89,121, 74,243, 84,201,105,218,233,130,211,147,103, +242,207,140,157,149,157,125,126, 46,249,220, 96,219,162,182,123,231, 99,206,223,106, 15,111,239,186, 16,116,225,210, 69,255,139, +231, 59,188, 59,206, 92,242,184,116,242,178,219,229, 19, 87,184, 87,154,175, 58, 95,109,234,116,234, 60,254,147,211, 79,199,187, +156,187,154,174,185, 92,107,185,238,122,189,181,123,102,247,233, 27,158, 55,206,221,244,189,121,241, 22,255,214,213,158, 57, 61, +221,189,243,122,111,247,197,247,245,223, 22,221,126,114, 39,253,206,203,187,217,119, 39,238,173,188, 79,188, 95,244, 64,237, 65, +217, 67,221,135,213, 63, 91,254,220,216,239,220,127,106,192,119,160,243,209,220, 71,247, 6,133,131,207,254,145,245,143, 15, 67, + 5,143,153,143,203,134, 13,134,235,158, 56, 62, 57, 57,226, 63,114,253,233,252,167, 67,207,100,207, 38,158, 23,254,162,254,203, +174, 23, 22, 47,126,248,213,235,215,206,209,152,209,161,151,242,151,147,191,109,124,165,253,234,192,235, 25,175,219,198,194,198, + 30,190,201,120, 51, 49, 94,244, 86,251,237,193,119,220,119, 29,239,163,223, 15, 79,228,124, 32,127, 40,255,104,249,177,245, 83, +208,167,251,147, 25,147,147,255, 4, 3,152,243,252, 99, 51, 45,219, 0, 0, 0, 6, 98, 75, 71, 68, 0,255, 0,255, 0,255,160, +189,167,147, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 13,213, 0, 0, 13,213, 1, 61,214, 88,241, 0, 0, 0, 7,116, 73, 77, 69, + 7,220, 2, 12, 19, 45, 40,146,193,117, 16, 0, 0, 32, 0, 73, 68, 65, 84,120,218,236, 93,119,120, 20,213,226, 61, 51, 59,179, +187,217,146, 77, 35, 61,144, 66, 9, 96, 0, 67, 81,130, 84, 65, 80,140,138, 10, 86,132,167,207,103,197,134, 5, 84, 68, 68, 32, + 54, 64,240, 39,242,208,167,128,160,128, 5, 4,164, 68, 74,232, 29,233, 9,144, 4, 18, 66, 58,201, 38,219,203,220,223, 31,217, + 89, 55,203,182, 64, 98,129,123,190,111,190,221,157,157, 57,115,239,157,123,239,156, 57,183, 1, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,215, 52, 86,175, 94, 77,154,112,248,144, 64, 57, 29,219,128,191, 59,103, 11,198,157, 52, + 35,231, 0, 7,231,187,255,144,112, 14,248,187,114,138,241,109, 2,239,144,166,228,163,230, 74, 79,151,112,146,230, 14,103, 75, +113, 54, 87, 57,242, 16, 78,210, 2,247,253,221,127, 72, 56, 7,252,221, 56,221,243, 79,128,188, 77,226, 12, 48, 79, 53, 53,156, +164,185,195,217, 82,156, 87, 91,142,124,132,147, 92,109, 94,242,114,239,223,197,117, 4,174, 5, 69, 86,192,200,204,204,100, 92, +248,153,191, 43,167,107, 58,136,252,205, 25,214,102,196,150,230,230,116, 75,207,230,194,187,153,153,153,204,234,213,171,183, 2, + 24,208,156,113,111,142,251,238, 22,215,102,225,189, 2,145,213, 36,206,230,202,247, 45,205,217, 92,101,201,157,179, 57,242,189, +167,251,222,130,247,168,185,194,217, 44,101,169, 37,242,188,135,252,115,213,188,238,156,205, 81,150,220, 57,155, 35,223,255, 25, +156,205, 81,150, 60,113, 54, 71,190,247,118,239,175, 55,131,138,253,139, 5,129,123, 1, 31,248,119, 22, 68, 45, 37, 54,155,224, +192,252,229,156,205,124,143,222,117,112, 54,231,219,205,192,230,186, 71, 45,145,223, 93, 57,155,139,223,157,167, 57,238,147, 39, +206,171, 13,175,151,112, 54,123,220,175, 54,223,255, 89,156,205,124,143,154,165, 44,185,113, 14,108,230,151,129,129, 46,191,223, +109, 78,206,230, 42, 75, 30,194,121,213,247,201, 19,231,213,134,215, 75, 56,155, 61,238,205,241, 12,105, 41,222,107, 26, 45,213, +124,214,220,156, 77,228,190,166, 56,155,216, 60, 51,164, 5,238,253, 95, 26,206,230,228,116, 15, 99,115, 54,247,180,100, 56,155, +147,179, 9, 97,189,230, 56,255,105,247,253,239,152,158,222,248,174,166, 89,202,155, 59,218, 18,225,108, 78,206, 0,185,175, 9, +206,171,184,247,215, 28,184,191, 75, 64,196,132,111,230, 55, 19, 52,179, 3,211,146,194,181, 57,195, 57,176, 37, 28,194, 22, 64, +179,135,211,241,166, 60,185, 5,226,254, 79, 73, 83, 90,150,104, 89,250,219,149, 37,183, 60, 57,176, 25,157,162,102,117,158,221, + 57,155,227, 26,174, 28,205,149, 71, 91, 58,238,205, 89,150, 90,226,222, 83, 92,133, 11, 65, 57, 41, 39,229,164,156,148,147,114, + 82,206,235,150,243,154, 4, 75,147,128,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,226, 31, 5,175,237,187, +113,113,113,171,149, 74,101, 59,111,255,235,116,186,139, 23, 47, 94, 28, 68,147,240,175, 3,189, 71, 20,255, 32,176,248,195, 65, + 23, 0, 16,199, 70, 65, 65, 65,113, 77,195,107,103,120,185, 92,158,114,242,228,201, 14,130, 32,192,110,183,195,102,179, 57, 63, +205,102, 51,250,247,239,223,228,142,244,209,209,209, 57, 18,137, 36,169, 41,231,216,237,246,243,101,101,101,125,125, 28,178, 19, + 64, 10,195,252,161, 25,197,239,222, 62, 1,148, 88,173,214,238,190, 56, 25,134, 73,113,231,243,194, 37,126,247,201, 25, 18, 18, +178,159,227,184, 4, 79, 92,222,190, 11,130,144, 95, 81, 81,209,231,207,188, 71,215, 51,162,163,163,115, 56,142,107,114,254, 44, + 45, 45,245,154, 63, 99, 99, 99, 15,177, 44, 27,215, 4, 74,137, 32, 8,185, 23, 47, 94,236,235, 67,136,236, 4,144,226,243, 13, +202, 45, 63, 49, 12, 83,108,183,219,123,250, 43, 71,190,184, 60,228, 81,127,156, 78,145,197,113, 92, 86, 84, 84,212, 51,122,189, +222, 8,128, 72, 36, 18,226, 18, 54, 0,128,205,102,171,168,169,169,233, 66,115, 34, 5, 5,197,117, 33,180, 4, 65, 96, 77, 38, + 19,242,242,242, 64,136,199,250,222,126, 5,215,235,112,224,183,141, 81,193, 81,209,176, 89, 44, 80,181,138,116,114,151,157, 56, + 6,155,213, 2,155,217,140, 54,189,122,139, 97, 64,231,206,157, 37,126, 56, 19, 62,248,224,131,168,224,224, 96, 24,141, 70, 24, +141, 70,152, 76, 38, 24,141, 70,152,205,102,152,205,102, 88, 44, 22, 88, 44, 22,216,108, 54,152, 76, 38,100,103,103,219,173, 86, +171, 79,206,105,211,166, 69,105, 52, 26, 39,159,184,137,156, 34,175,213,106,133,209,104,196,166, 77,155,124,114,114, 28,151, 80, + 82, 82, 18, 37,149, 74, 65, 8,129, 32, 8, 32,132, 52,218,220,209,182,109, 91,139,175, 64,182,208, 61,186,158,209, 97,218,210, + 53, 81, 33, 10, 57,108,130,128,204,110,109,157,127,228,127,185, 28,196,102,135, 96,179,161,253,243,163,157,251, 59,117,234,228, + 51,127, 18, 66, 18,167, 45, 93, 19, 26, 40,103, 85, 85,149,161, 99,199,142, 37,104,112,155,189, 9,173, 4,131,193, 16,229,224, +191, 76, 16,177, 44,219,104, 91,191,126, 61, 50, 51, 51,253,197, 61,225,229,151, 95,142,178, 90,173, 48,155,205, 48,153, 76,176, + 90,173,176,217,108,206,205,110,183, 59, 55,179,217,140, 61,123,246, 4,234,100,125,112,219,109,183, 61,190,102,205, 26,213,207, + 63,255,172, 74, 74, 74,130, 84, 42,133, 68, 34,129, 68, 34, 1,203,178,224, 56, 14, 55,223,124, 51, 67,179, 32, 5, 5,197,117, + 35,180, 76, 38, 83, 65,122,122, 58,113,124,143,151,203,229, 82,183,183,220,184,246,237,219,231,186,159,231,175,185, 42, 56, 42, + 26, 19, 91,135, 3, 0,222, 57, 87,229,124, 64,124,216,231, 70,231, 49,239, 93,168, 5, 0, 40, 20, 10, 48,174,175,209, 94,160, + 82,169,112,219,109,183, 65, 38,147,161,103,207,158,224,121,222,227, 38,149, 74,193,243,188,223, 68, 97, 24, 6,106,181, 26, 83, +166, 76, 17, 69, 18, 84, 65,114,140,235,211, 19, 65, 32,248,239,177,211, 48, 11, 4, 28,199, 57,183, 64, 56,165, 82, 41,142, 30, + 61, 10,142,227, 32,145, 72,156,159,226,247, 85,171, 86, 97,228,200,145,224, 56, 14, 10,133, 2,240, 51,115,176,235, 61, 50,155, +205,177, 50,153,204, 2, 64, 20,103, 82,134, 97, 98,174,228, 30, 93,207, 8, 81,200, 49,102,222, 79, 0,128,162, 89,207, 59,239, +221,158,103,223,113, 30,147,248,159, 7,192, 48, 12,120,158, 7,203,178,205,198, 89, 93, 93,109,120,232,161,135,182, 7, 7, 7, +175,215,106,181,240, 35,224, 80, 84, 84, 4,142,227,188,230,119,150,101, 49,115,230, 76,156, 57,115, 38,160,184, 27,141, 70, 44, + 88,176, 0,118,187,189, 17,175,248,221,125, 95,128, 34,235,253,161, 67,135,142, 94,179,102, 77, 24,195, 48,248,236,179,207, 32, +149, 74, 49,124,248,112, 68, 68, 68, 96,195,134, 13,144, 74,165,120,253,245,215,105,230,163,160,160,240, 85,231,241, 0,110, 4, + 16,233, 48, 17,234, 0,132,186, 28, 82,225,248,140, 20,127, 51, 12,179,207, 3, 79, 47,199, 49, 21, 12,195,236,115,249,109, 6, + 32,243,176,191, 10,128,194,177,153,208,224,254,167,185, 92, 71, 60, 15,222,174,203, 1, 13,235, 15, 1,216, 2, 96, 96,102,102, +230, 86, 0, 40, 45, 45,189,163,180,180, 20, 0,144,146,146,114, 50, 55, 55,183,163,168,121, 28,205, 83, 82,155,205,214, 65,108, +170, 18,221,162, 33, 67,134,248,124,195,183, 89, 44,151, 9, 16, 79, 90,202, 83,115,133, 55, 1, 99,177, 88,240,192, 3, 15, 0, +128,215,135,142,235, 22,128,118,131,217,108, 6,199,113, 72,109, 29,137, 73,195,210,113, 19,177, 66, 87,207,192, 86,171,195, 61, +106, 43, 78,118,238,142,249,231, 43,112, 78, 91, 15,142,227, 2,226, 20, 4,193,171,200,146, 72, 36,152, 55,111, 30, 30,122,232, + 33, 72, 36,146,128,248, 92,239, 81,114,114,242,154,220,220,220, 8,134, 97, 76,142,123, 36,183,217,108, 26,155,205, 22, 97,183, +219, 35,154,114,143,174,103,216, 4,193, 99, 62,244,150,103, 3,185, 79,129,112, 86, 87, 87, 27, 50, 51, 51,119,203,229,242,133, +209,209,209, 37,197,197,197,126,133,150,187,248,113,127,169,248,228,147, 79, 48,103,206, 28, 12, 26, 52, 40,160,112,154, 76, 38, + 48, 12,131,249,243,231, 95,246,223,212,169, 83, 47,187,158, 31, 78, 6, 0, 27, 23, 23,247,236,186,117,235, 52,226,177,173, 90, +181, 2,207,243,232,210,165, 11,130,131,131,177,125,251,118,216,237,246,128,203, 37, 5, 5,197,181, 11, 79, 90,196, 5,253, 39, + 78,156,216, 51, 43, 43,107,122, 70, 70,198,119, 59,119,238, 92,202, 48,204,106,151, 58, 49,211, 81,191,174, 22,127, 19, 66,122, +185,138, 30,135, 88,139,100, 24,102,181,120,188,235,111,241,147, 16, 50, 4,128, 76,252, 61,113,226,196,180,172,172,172,233, 19, + 38, 76,120,115,198,140, 25,210,137, 19, 39,118,205,202,202,154, 46, 94,199, 83, 56, 60, 57, 90, 62,215,158, 18,155,168, 78,157, + 58,229,173,137,202,245, 1,224,179,182, 84,181,138,116, 58, 89,239, 37, 70, 56,247, 79, 41,174,113, 62,192,230,246,104, 7,149, + 74,133, 97,239,125, 20,144, 83,100, 54,155, 81, 94, 94,238,116, 25,252,109,129,114, 42, 21, 65,200,126,185, 11,138,170,100,120, +119, 87, 53,214, 28, 62, 3,158,231,113,123,231, 46,184, 67, 26,140,183, 19,101,120,249,116, 33,172, 36,176, 62,189,132, 16,143, + 2, 75,252, 46, 54,161, 4, 42,180,220,238, 81,145,209,104,172,202,203,203, 51, 8, 13, 15,118, 5, 33, 36,140, 97,152, 58,135, +203, 21, 27,232, 61,186,158,145,217,173,173,211,117,218, 19, 60,216,185,127,164,238,168,243,158,140,159,247, 33, 0, 96, 80,247, +155,253,150,135, 64, 56,171,170,170, 12,125, 7, 15,220,106, 55,152,191, 25, 61,122,116,193,230,205,155, 21,129,132,213,147,208, + 18, 93, 91, 81,100,113, 28, 7,179,217, 28, 80,220,205,102,179,215,242, 33,149, 74,175,196,209,130, 78,167, 51,175, 92,185, 18, +115,231,206, 69, 68, 68, 4,134, 14, 29,138,216,216, 88, 44, 95,190, 28,132, 16, 60,255,252,243, 80, 40, 20,162,123, 77, 51, 32, + 5,197,245, 13, 95, 90, 68,158,149,149, 53,221, 93,200,184,254,118, 21, 80,110, 98,202, 85,172,165,249,121,254,175,118, 23, 79, +226,117, 25,134, 89, 61, 99,198,140, 76, 63,225,168,240, 38,180,124, 78,137,111, 50,153, 10,186,117,235, 22,144,154,208,235,245, +165,254,196,134,167,183,122, 87,151, 64,173, 86, 67,165, 81,131, 13,176,222,181, 90,173, 78,161,178,113,227, 70, 40, 20, 10, 12, + 31, 62,252,170, 28, 45,139,197, 2,153,148, 7,219, 42, 26, 99,102,109, 70, 85,157,193,249,128,217,146, 95,128,131,101,229,120, + 57, 99, 48, 84,138,114,212,155,205, 1, 57,111,130, 32, 92, 38,178, 56,142,195, 3, 15, 60,224,116, 19, 92,251,173,192, 71,211, + 97, 68, 68,196,126,142,227, 18, 92,238, 81, 80, 74, 74, 10,240, 71,191, 30, 70, 16,132,250,208,208,208, 31, 1,196, 17, 66, 18, + 0, 4, 7,114,143, 40, 60,231, 79,247,253,130,155, 83,117, 37,156, 85, 85, 85,134,204,204,204,221,118,131,249,155, 11, 23, 46, +236, 6, 16,116,211, 77, 55, 53, 89,104,137, 2,139,231,121,204,156, 57, 19,115,230,204,113,254, 31,168,208,178,217,108,141, 4, +212,233,211,167, 27, 93,203, 93,216,249,105, 54, 37,104, 24, 93, 40,164,164,164, 56,207,137,137,137, 65,104,104, 40, 4, 65,128, + 32, 8, 8, 10, 10,130, 66,161,128, 84, 42,165,153,142,130,130,194,151, 22, 49, 76,152, 48,225, 77,134, 97, 86, 59,156,165, 99, + 62, 4,149, 39,237,209,203, 77,172, 85,120, 57, 46,211,147,216,114,253, 46, 98,226,196,137,105,238,225,240,212, 92,233,172, 85, +221,166,221,111, 4,215, 38,170,230,122,136,249,122,144,169, 67, 53, 80,168, 84,144, 72, 88, 48, 12, 67,252,113, 89, 44, 22,103, +197,255,204, 51,207,248,236,183, 18,104,127, 42,139,197, 2,150,147,224, 98, 76, 50,236,236, 54,231,185,226,198,114, 60,206,197, +116,132,228,212, 33,240, 1, 62,112,221, 29,173,231,159,127, 30, 11, 22, 44, 0,203,178,206, 52,225, 56, 14,237,219,183, 71, 65, + 65,129, 79, 46,142,227, 18,206,157, 59, 23,229,154,142,162,136, 37,132,192,110,183,163,109,219,182,198,188,188,188, 23,105,209, +189, 58,145,229,109,191,221, 46, 4,236,194,120, 58,174,170,170,202, 48,106,212,168,173,181,181,181,223,220,112,195, 13,167,209, +120, 10, 4,191,124, 28,199, 53, 18, 88,162,200,250,244,211, 79, 27,137, 34,171,213, 26,208,139,128,213,106,189, 76,240,124,252, +241,199,141, 62, 1,160, 79,159, 62, 1, 57,195, 0, 8,203,178, 68, 42,149,226,182,219,110, 67,215,174, 93,241,243,207, 63, 67, + 16, 4, 60,247,220,115, 80, 40, 20,152, 61,123, 54,108, 54, 27, 62,248,224, 3,234,104, 81, 80, 80,248,210, 34,166, 25, 51,102, + 28,155, 49, 99,134,211, 89,114,119,180,188, 60,119,239,116,136,170, 72, 81,164, 1, 48,121, 18, 68,158, 92, 50,119, 1,230,186, + 47, 43, 43,107,186,123, 56,220,155, 43, 27, 9,173, 63, 11,165,199,143,226,163, 91,210, 1, 52,110, 46,156,119,115, 71,168,212, + 42,168,130,213, 24,181,106, 27, 0, 56, 42,253, 9, 1, 57, 90,162,208,170,170,170,242, 41,178,154,226,104,177, 50, 14, 43, 18, + 46,129,200,120,112,102,107, 35,161, 37,225,120, 20, 69, 36,131,229,165,224,236,182,128, 56, 9, 33,151, 53, 21,142, 29, 59, 22, + 12,195, 56, 71,136,117,235,214,205,149,139,241,247,112,124, 45,188,161, 15,158,123,115,236, 7,149, 70, 90, 98,175, 36,127,238, +255, 18, 39,127,120, 22, 0,208, 87,167,115,222,139,105,221,254, 24, 59, 48,235,232, 86,167,251,248, 30, 94,189, 34,206,170,170, + 42,195, 77,157,210,118, 75,195, 67,190, 57,127,254,252,110, 0,236,131, 15, 62, 24,218,173, 91,183,128,202,164, 56,184,194, 93, +100,185, 58, 89,226,167,159, 17,182, 46,194,209, 30,144,128, 18,155, 17, 3,200,243, 68,204,219, 26,141, 6,106,181,218, 57,226, + 54, 40, 40, 8, 74,165,210,217,191, 51, 64,225, 70, 65, 65,113,253, 34, 76, 20, 58, 14,177,212,200,105,114,244,173,202,116,253, +237,201,241,114, 56, 80, 57,126,234,215, 53, 14,129,230, 17,162,179,230,118,206,106,111, 34,141, 19, 21,164,235,103, 76, 76,204, +175,106,181, 58, 57,208,216, 55,101, 20,155,221,106,185,204,217, 98, 24, 6,234, 96, 53, 20,106, 21, 20,193,106,175,174,151, 47, +161, 37, 58, 69,226, 67,103,225,194,133, 80,171,213,248,215,191,254,213,228, 62, 90, 78,161, 37,101,177, 65,190, 9, 18, 25,215, + 72,100,113, 28, 7, 9,207,163, 84, 29, 11,150,231,193,217, 2,115,201,106,107,107,193,113, 28, 38, 77,154,228,124,131,119, 21, + 89, 77,137,179, 47,176, 12, 35,186, 91,242,118,237,218,189,202, 48, 76, 34,128, 36,157, 78, 39,191,120,241,226,173,180,188,250, + 80, 6,118,235,101, 46,148, 55,247,245, 74, 57, 69, 39, 75, 26, 30,242, 77,199,142, 29,157, 78,150, 82,169, 20, 71,155,250,191, +199, 44,235, 81,100,185,143, 16,228, 56,174, 33, 47,251, 25, 29,233,234,104,205,152, 49,195,201,235,234,100,137,104, 74, 57, 18, +195,186,117,235, 86, 28, 60,120, 16,207, 60,243, 12, 20, 10, 5,230,204,153, 3,155,205,134,169, 83,167, 66,161, 80, 64, 38,147, +209,204, 71, 65, 65,221,172, 70, 90,196, 13, 21,110,253,160, 24, 55, 81, 83,225, 73, 96,185, 54, 19,138,223, 25,134,177,122,224, + 53,187, 53, 41,186,239, 23, 63,171,102,204,152,177, 89,116,178, 92,246, 55, 10,135, 95, 71, 75, 46,151, 39,231,229,229, 57, 39, +194,244,245,105, 54,155, 49,104,208,160,128,157, 49,113,212, 33,199, 73, 26, 9, 11,101,176, 26, 74, 77, 48, 20,106,181,187,224, + 96,252, 85,226,226, 27,177,171,208,154, 60,121, 50, 56,142,195,130, 5, 11, 0, 0,175,190,250,106,192,125,180, 68, 78,216, 25, + 20,147,179, 72,159, 53, 18,230,111,173, 40,219,241, 59, 56,142, 67, 84,239, 59, 32,220, 52, 18,122,133, 26,156,221, 22,240,168, +195,234,234,106, 20, 20, 20, 64, 34,145,224,149, 87, 94,105, 52,215,145,251, 72,182,141, 27, 55,250,141,187, 39, 39,107,242,249, +106, 39,143, 66,161, 96,127,255,253,247,100, 65, 16, 82, 12, 6, 67,187, 62,125,250, 8,180, 40,251, 17, 69,130, 45, 32, 81, 21, +104,254,116,231, 20,251,100,213,214,214,126,115,254,252,249, 61, 0,216,209,163, 71,135, 42,149, 74,124,245,213, 87,122, 0,178, +229,203,151, 43,252,137, 34, 49,223,248, 19, 89, 60,207, 55,228,229, 64,226, 78, 26, 79, 89,226,175, 99,124, 32,121, 94, 12, 43, +195, 48,176,219,237, 80, 40, 20,141,156,172,160,160, 32,200,229,114,154,241, 40, 40, 40,252,213, 37,251, 2,174,199, 9,233,229, + 34,170,246, 93, 9,111, 83,174,231, 15,156, 55,161, 97, 50,153,112,226,196,137, 64,121, 2,158, 24,179,117,207,155,241,222,133, + 90, 48, 12,131,255,246,185, 1, 42,141, 26, 74,149, 10,247,255,188,213, 89,113, 31,157,254, 42,228, 42, 53,226,250, 13, 13,168, + 34, 23,155, 14, 93,133, 86, 77, 77, 13,120,158,199,251,239,191, 15,150,101,241,193, 7, 31, 32, 62, 62, 30, 23, 47, 94,196,242, +229,203, 3,114,180, 36,118, 9, 98, 31,235, 4,229,216, 16,104, 30,235,143,176,219, 38,227,130,153,195, 78,163, 18,253,141,199, + 33,219,240, 41,204,130, 61,224, 17, 88, 54,155, 13, 91,183,110,117,239,240,238,236, 83,101,179,217, 96,181, 90, 97,177, 88,240, +193, 7, 31, 4, 50,194,243,178,251, 38,166,161, 99, 18, 84, 73,110,110,110, 36, 33, 36, 28, 64, 8,128, 74, 90, 92,125, 35,182, +247,243,136,236,249, 52, 0, 96,213,140, 39,156,251, 39, 29,253, 35,127,206,252,182, 97, 1,128,142, 73, 67,155,196, 89, 85, 85, +101,184,125, 80,159, 28,163,192,127,221,165, 75,151, 70, 78, 86, 80, 80, 16,227,248, 29,144, 93,198,178, 44, 36, 18,201,101,205, +133,222,196, 86, 32,125,180,108, 54,155,115, 34, 81, 95,253, 25,175,196,209,122,226,137, 39, 16, 27, 27,235,116,178,222,123,239, + 61, 40, 20, 10, 76,156, 56, 17, 86,171, 21,159,126,250, 41,205,124, 20, 20, 20,127,186, 40,251, 51,224,177, 38, 53, 26,141,133, + 93,187,118,133,151,255,226,131,130,130,120,183, 72,197,181,111,223, 62,215, 67, 19,226, 16, 0,217,158, 42,117,134, 97, 16,172, + 9, 70,144, 90, 5,165,155,139, 21, 20,172,129, 92,173, 6, 43,245, 88,153, 95,198, 41,246, 45,113, 21, 90,226, 86, 91, 91, 11, +158,231, 49,119,238, 92,104, 52, 26,152, 76, 38,191,156,226, 67, 71, 34,145, 64, 95, 84,135,147,211,179, 33, 11,218,137,118, 67, + 31, 66, 44,175,128,116,251,143, 48,216,173,254, 38, 44,189,140,179, 67,135, 14,120,231,157,119, 46,155,214,193, 27,226,227,227, +253,198,221,221,201,154,121, 67, 27, 72,101, 82,140, 63, 94, 4,147,201,196, 60,244,208, 67, 2, 0, 3,128, 10,131,193,112, 62, +144,244,108, 6,252,227, 57,125,141,138, 21, 33, 16,187, 39, 1,227,145, 83,116,178,140, 2,255,117, 65, 65,129,232,100,133, 40, +149, 74,124,241,197, 23,122, 0,236,212,169, 83,149,137,137,137,146, 64,242,146, 68, 34,193,172, 89,179, 60,246,201,242, 36,186, +154, 82,142, 92,207, 29, 48, 96,128,199, 9, 75,189,136,183,203, 56,197,176, 70, 68, 68, 56,157, 44,187,221,238, 28,109, 40,206, + 62,239,227,165,130,230, 79,202, 73, 57,175, 31,206,107, 18, 30,107,224,139, 23, 47,222,238,237,132,182,109,219,230,229,229,229, +181, 23,151,226,112, 84,156, 82,163,209,216,161, 79,159, 62,126,173, 29, 65, 16, 32,151,203, 65, 8,193,173,239,100,129, 97, 1, + 22,141, 31, 98, 81,183, 12,134, 68,194, 65,104, 88,234,195,239,168, 67,131,193,208,232,225,224,105,171,175,175,135,201,100, 10, +120, 54,111,163,209,216,104, 10, 6,134, 8, 56,247,219,178,203, 70, 31,138, 91,160,253,118,130,130,130, 26, 53,253,248,113,172, +152, 64, 28, 45,215,166, 71,169, 76, 10, 78,202,139,142, 86,221,233,211,167, 71,209,108, 30, 56,196, 1, 11, 0,144,218,103, 56, + 4,193, 14, 98,183, 55, 90, 38,169, 83,242,237, 16,136, 29, 22,171, 30, 38,147,201,223,180, 39, 76,101,101,165, 97,212,168, 81, + 91, 1,252,239,158,123,238,201, 69,195,236,194, 68,173, 86,203,121,158, 23, 0, 84, 3, 32,151, 46, 93, 10,185,112,225,130, 96, + 52, 26,219,248, 11,231,154, 53,107,112,226,196, 9,244,235,215,175,209,114, 80,162, 43,234, 58,187,123, 32,249, 83,108, 46,247, + 52, 35,188, 55, 33, 23, 40, 36, 18, 9, 66, 66, 66, 32,149, 74,241,254,251,239, 67, 42,149, 66,169, 84, 2, 0, 62,253,244, 83, +231,228,171, 20, 20, 20, 20,215,141,208,242, 87,111,250,104, 86,244,217,132,104,179,217,138, 19, 19, 19,155,116, 49,187,221, 94, +230, 71,184, 21, 47, 95,190, 92,234,234, 66,248,251, 36,132,148,249,121,216, 22,175, 90,181, 74,234,201,221,240,182,192,180, 63, + 78,187,221, 94,156,148,148,228,213, 49,241, 4,171,213,122,193,159,104,205,170, 48, 52, 18, 9,227,143, 23,121, 93, 59,145,194, +111, 94,243,145, 63,223,186,210,252,121, 58, 53, 53,245, 66,104,104,232,218,232,232,232,170, 29, 59,118, 68,244,234,213, 43,194, +245,152, 94,189,122,197,186,157,102,134,247,117, 14,193, 48, 76,241, 61,247,220,227, 49,207,139,162,201, 67,254, 44,246,151,231, +247,238,221, 43,117, 61,223, 27,191, 75, 57, 42, 14, 64,184,158, 75, 79, 79,103, 93,121,188,229,125,171,213, 90, 65,115, 33, 5, + 5,197,117, 47,180, 12, 6, 67, 81,215,174, 93,109, 94,254, 59,239,235,220,170,170,170,158,205, 29, 1,171,213,218,231,159,192, + 89, 89, 89,217,172,113,183,217,108,197,142, 9, 74,125, 30, 67,179,248, 95,119,143, 0,160,188,188,252, 38, 0,208,233,116,240, +183,172, 78, 19, 4, 97,179,231, 79,155,205,214,167, 37,210,180,186,186, 58,131,230, 44, 10, 10, 10, 42,180,154, 0,186, 24,241, +223, 3, 45, 33, 90, 41, 40, 40, 40, 40, 40, 40,154, 23, 44, 77, 2, 10, 10, 10, 10, 10, 10, 10,138,150, 1,131,134,145, 3,158, +208,148,209, 4, 67,174,224,218,217,148,147,114, 82, 78,202, 73, 57, 41, 39,229,188,238, 56,253,113,211,209,140, 45, 44,192, 40, + 39,229,164,156,148,147,114, 82, 78,202,121,253,113, 94,147,160, 77,135, 20, 20, 20, 20, 20, 20, 20, 20, 45, 4,142, 38,193, 95, + 6, 9,154, 48,163,190, 63, 16, 66,194, 0,120, 91, 48,206,204, 48,204,165, 43,224,100, 0, 72, 29,155, 56,209,145, 21,128, 5, +128,133, 97, 24,226,159,227, 93,182,164, 36, 44,141,216,249, 94,132, 97,120, 65,192,225, 54,109, 90, 31, 98,152, 59,204, 0,160, +138,238,212, 89,173, 82, 12, 49, 89,204,201,114, 94,118,162, 70, 87,191,209, 84,158, 87, 72,179, 7, 5,197, 95,130,187, 0, 76, + 65, 67,183,146, 25, 0,150,209, 36,161,160,104, 33,161,165, 86,171,247,179, 44,155,224,111,126, 30, 17,142,181,204,138, 47, 93, +186,212,179, 9,215, 30,165, 86,171, 7,241, 60,127, 11, 0, 88,173,214, 29,245,245,245,155, 1, 44, 7, 96,187,194, 56,105, 0, + 60, 0,224, 17,199,239, 37,142,202, 66,123,133,124, 93, 67, 66, 66,126,224,121,158, 84, 86, 86,246, 6,128,136,136,136,221, 86, +171,149,209,106,181,247, 3, 56,210, 68, 62,150,231,249,153,189,123,247,238,191,109,219,182,255, 1,152,219, 76,247, 82,206,178, +172, 71,129, 34, 8, 66,210, 21,136, 44, 41,128,144,185,115,231, 70, 44, 94,188, 56,189,184,184,184, 11, 0, 36, 36, 36, 28, 29, + 61,122,244,161,113,227,198, 85, 17, 66,106, 25,134,177,248,226, 41, 41, 9, 75, 43, 47,205,127,166,172,252,196, 3, 0, 16, 19, +219,101,153, 68,194, 74, 9, 57,176, 75,217,234,145, 86,237,219, 37, 61,253,221, 87,115,165, 73,201,173,177,105,231,193, 27,199, +189,248,102,218, 5,224, 19, 42,182,254, 60, 4, 7, 7,239,103, 89, 54,193, 87, 25,247, 84,230,237,118,123,113,117,117,117, 79, +111,156, 28,199, 37,248,170, 47, 60,237, 19, 4, 33,191,178,178,210,227, 84, 19, 26,141,102, 23,199,113,201,129,114,137,159, 54, +155,173,216,219, 40, 93,141, 70,179, 95, 34,145, 36,248,138,167,167,255, 4, 65,200,175,168,168,240, 22,206,203,226,222, 28,225, +188, 18, 78, 95,225, 20,235, 35, 0,159, 70, 68, 68,220, 92, 85, 85,245, 40,128, 55,181, 90,109, 55,137, 68,130,240,240,240, 55, +205,102,243,153,144,144,144, 47,107,107,107,119, 2,120, 17, 0, 93, 47,149,130,162,185,160,209,104,202,234,235,235,137, 8, 65, + 16,136,213,106, 37, 38,147,137, 24, 12, 6,162,211,233, 72,125,125, 61,209,106,181,164,182,182,150, 84, 85, 85,145,200,200, 72, +247,201, 27,189,181,225,118,209,104, 52,121, 89, 89, 89,166,130,130, 2, 98,177, 88,136,197, 98, 33,133,133,133,228,163,143, 62, + 50,105, 52,154, 60, 0, 93,188,156, 59,196, 75,101,113, 27,128,165,233,233,233,230, 53,107,214, 16,163,209, 72,116, 58, 29, 89, +182,108, 25,185,225,134, 27,204, 0,150, 58,142, 97, 3,228, 4,128,190, 49, 49, 49,197,103,207,158,181,111,220,184,209, 18, 18, + 18,146, 29, 18, 18,146, 93, 88, 88,104, 63,123,246,172,208,170, 85,171, 98, 0,125,155, 16, 78, 0, 24, 57,126,252,248,178,194, +194, 66, 50, 96,192,128,195, 46,251, 25,248, 95,231,110,136, 39, 39,139, 16, 18, 67, 8,137, 69,195, 36,151,151,109,132,144, 88, +199, 49, 97, 1,114,170,242,243,243, 91, 71, 71, 71,103, 49, 12, 99,118,231, 99, 24,198, 28, 29, 29,157,149,159,159,223,154, 16, +162,242,197, 89,124,126,222,147,107,215, 12,174,209, 93, 58, 69,116,151, 78,145,255,125, 61, 80,251,212,184, 71,151,198,182,237, +190, 32, 52, 33,109,238,137, 83,167,231, 19, 66,230,111,222,151, 55,127,242,231,191,206,191,119,220,236, 47, 34, 18,211,159,106, + 66,122, 94, 13, 40, 39,128,208,208,208, 82,157, 78, 71, 8, 33,196,110,183, 19,139,197, 66, 76, 38, 19,209,235,245,164,190,190, +158,212,213,213, 57,203,121,109,109,173,243,123, 84, 84,148,215,242, 30, 22, 22, 86,102, 48, 24, 26,213, 29,102,179,217, 89,127, +232,245,122,162,215,235,137, 78,167,115,110,245,245,245, 36, 46, 46,174,200, 71, 56, 47,138,225, 20, 4,129,216,108, 54, 98,177, + 88,156,188, 70,163,177,209,102, 50,153,136,201,100, 34,137,137,137, 1,135, 51, 16, 78,163,209, 72, 18, 18, 18, 74,188,113,134, +135,135,151, 25,141,198, 70,156,174,241,119,231, 21,127,199,196,196,148, 54,133, 51,144,112,250, 74, 79, 7,230,230,230,230, 18, +131,193, 64,226,227,227,171,238,191,255,126,171,221,110, 39,107,214,172, 33,233,233,233,194,192,129, 3, 45,149,149,149,228, 95, +255,250, 23,241,241, 82, 72,203, 17,229,164,184, 18, 71,139, 97, 24,168, 84, 42,124,255,253,247, 94,151,227,112,253,222,166, 77, +155, 64,175,217, 51, 57, 57,121,235,246,237,219, 21,177,177,127, 76,136,109, 54,155, 17, 22, 22,134,231,158,123, 78,118,215, 93, +119,181, 31, 58,116,232,238,115,231,206, 13, 0,176,223, 15,223,125,145,145,145,159, 77,154, 52, 41,250,193, 7, 31, 68, 68, 68, +163, 73,183, 49,106,212, 40,220,127,255,253,210,220,220,220,135, 22, 46, 92,248,208,188,121,243, 74,235,235,235,199, 1,248,209, + 23,169, 66,161,184, 39, 46, 46,238,139,237,219,183, 71, 69, 69, 69, 33, 37, 37,133,125,253,245,215,219,119,232,208, 65,145,144, +144,192, 94,188,120, 17, 63,255,252,115,252,195, 15, 63,188,162,172,172,236,105,139,197,178, 50,128,184,203, 34, 34, 34,222,124, +250,233,167, 91,105,181, 90,219,129, 3, 7,242,196,253, 50,153,108,106, 70, 70, 70,175, 45, 91,182,124, 11,224,203, 43,113,178, + 8, 33, 90,252,209,196, 39,194, 42,254, 31,136,179, 69, 8,145, 29, 62,124, 56, 60, 35, 35,227, 71,147,201,212,253,153,103,158, + 57, 63,125,250,116,133, 70,163,209, 0, 96,180, 90,237,165, 41, 83,166,152,103,207,158,253, 70,231,206,157, 7,239,218,181,235, + 62, 66,136,213, 33,200, 46,231, 99, 24,103,120,138, 46, 84, 96,235, 78, 65,246,206,196, 87, 19, 62,156,150,124,110,223,241, 34, +129, 83,104,240, 75,206, 49,148, 85,213,227,215, 93,199, 17, 19, 17,204, 72,229,124, 90, 72,252, 13, 3,106, 47, 28,207,129,143, + 25,210, 41,154, 7, 12,195, 64,169, 84,226,151, 95,126,185,108,233, 42, 79,203, 90,113, 28,135,208,208, 80,191,171, 27, 4, 5, + 5, 97,227,198,141, 30,215, 94,244,180,164, 79, 72, 72, 8,124,189,108, 48, 12,131,160,160, 32,236,216,177, 3, 44,203,122, 92, + 26,200,125,159, 74,165, 2,235, 99,173, 43,145, 51, 39, 39,199, 47,151,248,169, 86,171,129,134,166,127,239,133, 82, 46,199,246, +237,219,189,198,217,253,187,218,177,222,171, 63,206, 29, 59,118, 52, 90,250,203,125, 73, 48,215,223, 42,149, 10,140, 31,210,176, +176,176,222, 9, 9, 9,216,187,119, 47,150, 47, 95, 30,158,150,150,134,211,167, 79,131, 97, 24, 76,159, 62,157,185,225,134, 27, +248,210,210, 82,244,235,215, 15, 63,253,244, 83, 31,173, 86, 75, 11, 12,197, 95, 2, 66, 8, 15,224, 70, 0,145,104,232,118, 83, + 7, 32, 20, 13, 43,105,200, 0, 84, 1, 80, 56, 54, 19,128,122, 0,173, 28,167, 87, 58,234, 22, 87,129, 80,225,186,248, 52, 33, +164,151,131, 91, 92,161, 34,210,229, 88,241, 26,238,191,221, 63, 61,114,115, 0,176,122,245,106,241, 97, 54, 48, 51, 51,115,171, +107,228, 2, 17, 89,226, 58,101, 30,202,180,251, 16, 77,185, 74,165,250, 97,247,238,221,138,200,200, 63,226, 96, 50,153, 80, 87, + 87,135,250,250,122,212,213,213, 33, 56, 56, 24,203,151, 47, 87, 12, 30, 60,248,135,186,186,186, 14,142, 68,243,198, 57,235,226, +197,139,209, 54,155, 13, 50,153,231, 46, 74, 44,203,162, 83,167, 78,120,243,205, 55, 49,108,216,176,152, 65,131, 6,205,114, 19, + 90,151, 13, 37, 85, 42,149, 95, 28, 56,112, 32, 74,169, 84, 34, 47, 47, 15,197,197,197, 24, 63,126,124,107, 65, 16, 80, 84, 84, +132,211,167, 79,227,194,133, 11, 88,184,112, 97,212,136, 17, 35,190,240, 32,180, 60, 13, 79,125,230,229,151, 95,238, 24, 22, 22, +198,126,244,209, 71, 53, 58,157,238,255, 28,251,223,153, 51,103,206, 99,253,251,247,143,250,247,191,255, 77,118,236,216,177,216, +113,227,188,166,167,107,159, 44, 71, 51, 31, 28,153,239,164,219, 57,157, 92,254, 7, 33, 36, 6,128,137, 97,152, 26, 15,156, 12, +128,144,161, 67,135,190, 98, 50,153,186,111,223,190,253,204, 45,183,220,146, 8,224,162,152,249, 66, 66, 66, 84,179,102,205,138, +206,204,204,204,189,245,214, 91,187, 15, 29, 58,244,149,138,138,138,233,132,144, 10,151, 62, 91, 78, 78, 65,192,225,152,216, 46, +203,114,118,141,123, 96,203, 14,179,244,213, 23, 39,159,111,211, 58,169,246,112, 94,181,253,120,126, 5,234, 12, 54,220,123,107, +195, 2,230,189,187,180,193,103,223,111,199,115, 47,189,197,255,184,108,209,253,103, 8, 84,245, 37,199,215,248, 72,207,171, 5, +229,132,179,137, 9, 60,207,227,142, 59,238, 0,195, 48,151,173,229,201,243, 60,118,237,218,133, 91,111,189, 21, 60,207,227,137, + 39,158, 8,136,147,227, 56, 12, 29, 58,212,185,142,162, 43,159,187,104,240,162, 9,178,221, 42, 91,112, 28, 7,150,101,189, 46, +164,237,206,233,175, 94, 18,195,233,139,203,245, 63,127,225,116, 44,121, 20,176,200, 10,148, 83, 12, 39,199,113,232,211,167, 15, + 14, 29, 58,228, 83,116,121,209,151,141,226,126,233,210,165, 49, 29, 58,116,200,153, 59,119,110, 56, 0, 84, 85, 85, 57, 23,188, +151, 72, 36, 56,117,234, 20,204,102, 51,222,125,247, 93,139, 86,171,253, 55, 45, 71,148,179, 37, 57,125,105, 17, 0,253, 39, 78, +156,216, 51, 43, 43,107,122, 70, 70,198,119, 59,119,238, 92,202, 48,204,106, 66, 72,166,248, 57,113,226,196,180,172,172,172,233, + 19, 38, 76,120,115,198,140, 25,199, 24,134, 89, 13, 0,238,191, 29,117, 73,166,155,136,139, 20,121, 28,101,174,209,177,158,126, +187,127,122,226,110,228,104,101,102,102, 50,142, 72, 50,174,149, 90,160, 66, 43,144,181,251, 56,142,123,126,250,244,233,209,190, + 68, 86,125,125, 61, 74, 74, 74,144,152,152,136, 39,158,120, 34,122,238,220,185,207,219,108,182,143,125,208, 74, 37, 18, 9,246, +238,221,139,242,242,114,116,237,218, 21,201,201,201,141, 14, 56,123,246, 44,214,174, 93,139,154,154, 26,244,232,209, 3,104,232, +220,237, 17,221,186,117,123,183, 83,167, 78, 67, 89,150,181, 41, 20, 10, 28, 62,124, 24,221,187,119,199,247,223,127,143, 54,109, +218, 64,169, 84, 34, 55, 55, 23, 93,187,118,197,214,173, 91, 17, 25, 25,137,244,244,116,155, 86,171,221, 86, 93, 93,189,249,220, +185,115,239,122, 11,103,124,124,252,228,167,158,122, 74, 86, 82, 82, 34,124,243,205, 55,219, 1,108, 7,240,252, 91,111,189,245, +248,176, 97,195,162, 14, 30, 60, 88,187,111,223,190, 61, 94, 68, 86, 32, 78,150,205,253,161,100,183,219, 77, 6,131,193,108, 50, +153,172, 44,203, 22, 50, 12, 99,182,219,237, 29,188,153, 16, 99,199,142,109, 91, 89, 89,249,220, 75, 47,189, 84,224, 16, 89,167, +208,208, 1, 30, 0, 96,179,217, 76,245,245,245,218,140,140,140,196,135, 31,126,248,204,210,165, 75,159, 27, 59,118,236,242,111, +190,249,166, 30,128,193,157,176, 77,155,214,135, 36, 18, 86,170,171, 11,207, 95,177,252,203,151,215,174,122,190,117, 81,209,133, +246, 17,173, 34,117, 82,117,100,201,242, 37, 95,239, 7, 96, 46,169,208,226,200,217, 82,240,188, 4, 39,138,106,209,255,246, 81, +252,153,188,105,125, 1,172,161,239,114, 45,255,178, 40, 46, 66,189,101,203, 22,159,142,214,174, 93,187,192,243, 60, 20, 10, 5, +102,207,158,237,147, 84, 20, 6,162, 91,228, 79,204,136,139,163,251,114,159, 4, 65,112, 46,244,238,190,253,223,255,253, 31, 94, +122,233,165, 70,215,112,136, 13,198, 31,167,183,240, 37, 38, 37,161,188,172,172,209,190, 64, 22,165,183,219,237,224,121, 30, 11, + 22, 44, 64,102,102, 38, 86,175, 94,237,243,243,142, 59,238, 0,203,178, 36,144,244,236,211,167, 15, 44, 22,139, 51,204,167, 78, +157,242,200, 59,111,222, 60,127,193,188, 11,192,148,238,221,187,107, 6, 13, 26,132,156,156, 28,220,127,255,253, 38,139,197,146, + 7, 0,119,222,121,103,234,220,185,115,101, 7, 14, 28, 64, 68, 68, 4,127,254,252,249,255,129,118,144,167,104, 97,120,210, 34, +226, 51, 47, 43, 43,107,186,187,136,113,133,248, 63,195, 48,171,103,204,152,145,233, 42,138, 92,127,139,174,147,155,136, 75,115, +117,164, 92, 69,148, 55, 1,229,246,188,117, 61,190,194,163,208,114, 68,108,160,171, 11, 36, 86,190,254, 68,150,143, 55,199, 70, + 8, 9, 9, 25,126,239,189,247, 58, 69,142,209,104,116, 10, 44, 81,100,137,191,115,115,115,209,179,103, 79,105, 72, 72,200,240, +170,170,170,143, 3, 16,113,136,139,139, 67,101,101, 37,142, 30, 61,138,196,196, 68, 88,173, 86,172, 95,191, 30,181,181,181,224, +121, 30, 82,169, 20, 22,139,207,190,219,232,212,169,211, 29,139, 23, 47,238,185,104,209,162, 75,226, 27,221,146, 37, 75, 64, 8, + 65,100,100, 36,244,122, 61,202,202,202,176,121,243,102,216,108, 54,168,213,106,164,164,164,200,238,185,231,158,190, 83,166, 76, +225,125, 8,173, 62,247,223,127,127,136, 70,163,193,139, 47,190, 72, 44, 22,203, 12,199,190,201,227,198,141,139, 40, 44, 44, 52, + 63,249,228,147,123, 45, 22,203, 71,162,153,232, 42,112,188,220, 88,175, 78,150,213,106, 21,211,180,160,190,190, 30,173, 90,181, + 74,116,117,182,188,137,193, 29, 59,118,244, 1, 32,153, 58,117,106, 16,128, 50,215, 48,152,205,102,212,215,215, 67,167,211, 89, +107,107,107,203, 95,123,237, 53,219,210,165, 75, 37,142,115, 78,120, 18, 90, 12,115,135, 89,163, 81,202, 8,145,188, 53,127,254, +124,245,176, 97,195, 88,181, 90,141,186,186, 58,205,175,235,214,169, 7, 15,234,155, 50, 61,235,195, 13,154,132,174,101, 59, 14, +231,227, 66,105, 45,204, 86, 43, 82, 98, 67, 26,252, 48,138, 22,135, 99, 32,139,211,209,114, 21, 21, 57, 57, 57,184,253,246,219, +157,101, 93, 42,149, 54,114,190,252,113,114, 28,135,219,111,191,253, 50,135,103,203,150, 45, 30,221, 39,127,112, 21, 69,238,226, +200,147, 0, 99, 89,214,239, 2,235,162,155,231, 73,108,185,186,250,110,226,205, 95, 51, 7, 56,142,195,184,113,227,192,243, 60, + 94,127,253,117,112, 28,135,244,244,116,112, 28,135,140,140, 12,240, 60,143, 91,111,189,181,201,113,223,189,123, 55,186,119,239, +238, 12, 83,122,122, 58,122,245,234, 5,142,227,208,175, 95, 63,240, 60,143,161, 67,135, 6,194,249,102, 93, 93, 93, 55,181, 90, +141,220,220, 92, 72, 36, 18, 48, 12,115, 26, 64, 55, 0,136,141,141, 61,163, 6,111,130,189, 0, 0, 32, 0, 73, 68, 65, 84,215, +235,219, 26,141, 70, 60,245,212, 83,140,217,108,238,250,250,235,175,191,101, 52, 26,169,208,162,104, 49,184,107, 17, 23, 24, 38, + 76,152,240, 38,195, 48,171, 69,135,202,221,121,242,244,219, 67,221, 36, 58, 80,251, 28,101,181,151,155,136,171, 96, 24,102, 31, + 33,228, 78,111,231, 2, 48,187, 9,171, 70, 77,135,174,205,134,126, 29, 45,177,242, 13, 84,104,249,131,209,104,188, 49, 42, 42, +202,171,200,114,253, 52,155,205, 72, 78, 78,134,209,104,188,177,169, 15,141,216,216, 88, 88, 44, 22,124,249,229,151,144, 74,165, +144, 74,255,208, 23,102,179,111,179,232,248,241,227, 5,187,119,239,238,222,163, 71,143,176,159,126,250,169, 98,192,128, 1,145, +195,134, 13,131, 66,161,128,193, 96,128,213,106, 69,239,222,189,209,169, 83, 39, 20, 23, 23,227,215, 95,127,173,236,208,161, 67, +171, 61,123,246, 8,165,165,165,231,124, 80,223, 54,120,240, 96, 48, 12,131,117,235,214, 85, 2,216, 39,151,203,215, 78,155, 54, + 45,204,108, 54, 11,163, 71,143, 62, 95, 93, 93,253, 18, 0,139, 76, 38,155, 51, 96,192,128,140,236,236,236,111, 5, 65,152,221, +212,140,234,158,182, 58,157, 14, 65, 65, 65,129, 76, 37,193, 87, 87, 87,119, 1, 0,149, 74, 21, 14,224,140, 51,135, 27, 12,141, +196,176,217,108, 54,134,135,135,171, 0,192,113, 14,239,133, 51,210,102,195,138,115,231,242,131, 93,251,207,133,134,134,226,145, +135, 31,102,111,233,211, 71,214,237,198, 27,135,190,253,201,162,239,227, 34, 52,230,148,184, 8, 88,237, 86,100,111, 88, 47, 16, +193,186,129, 86, 59,127,142,208, 18,197,134,187,163,197,243, 60,182,110,221,122,217, 62,169, 84,138,255,254,247,191, 1, 9, 3, + 81, 84,121,107, 58,115,107,234, 98,252, 9, 24,158,231, 33,145, 72,176, 96,193, 2, 8,130,128,151, 95,126,185, 81,115,162, 43, +127, 64,118,158,139, 8,236, 52, 89, 0, 96, 70,241, 76,185,243,124,247,240, 58,206, 9,200, 37,155, 59,119,110, 64,142,214,157, +119,222,233, 87,184,186,182, 48,184,134,235,208,161, 67, 30,121,231,207,159,239, 55, 61,237,118, 59,214,172, 89,227, 20,169, 34, +222,126,251,237,167,100, 50, 89,244,182,109,219, 80, 90, 90, 10,157, 78,135,250,250,122,244,238,221, 59,133,101,217,195,165,165, +165,133, 39, 78,156,184,151,150, 30,138, 63,209,209, 50,205,152, 49,227,216,140, 25, 51, 60, 58, 86,238,206,146, 47,231, 73, 20, + 88, 14, 65, 20, 41,138, 55, 52,116,171,217,231,239, 92, 0, 50,247,166, 67,159, 70,144,155,138,156,226,169,242, 13,164,249, 48, + 64, 59,157, 99, 24, 6, 70,163,209,163,192,114, 21, 7, 22,139, 5,213,213,213,176,219,237, 87, 60,215,151,167, 55, 89,127, 66, +235,232,209,163,255,122,252,241,199, 75, 66, 66, 66,186, 85, 84, 84,148, 11,130,112,235,174, 93,187, 34, 57,142,131, 70,163,129, + 70,163,193,218,181,107,161, 84, 42, 49,110,220,184,114,187,221,158, 19, 28, 28, 28, 97, 48, 24,126, 47, 45, 45,125,219,171,130, +225,249,161,253,250,245,195,129, 3, 7,112,233,210,165,141, 0,210, 31,125,244,209,219, 91,183,110,205, 76,155, 54,205,120,246, +236,217,217, 0,202, 85, 42,213,226,197,139, 23, 15,234,209,163, 71,240,232,209,163,177,117,235,214,249, 0,140,129,198, 89,167, +211, 53, 18, 88, 90,173, 22,117,117,117, 80,169, 84,182, 0,211,140,199, 31, 35, 12, 65, 8,113,222, 27,135,155, 37,222, 31,194, +113,156, 56,170,209,155,200,130, 74,165,154,186,104,209, 34,133,251, 32, 5,187,221,142,178,178, 50,104, 52, 26, 76,122,251,109, +233,123,227,255,221, 93,162,142,222,197,178, 12,204, 22, 82, 67, 4,243,122, 93,217,131,219,128,119,105,205,243, 39, 64, 20, 6, +119,223,125,247,101,205,133, 82,169, 20, 27, 55,110,196,136, 17, 35,156, 47, 46, 61,122,244,240,251,114, 37, 10,131,187,238,186, +203,233, 12,173, 95,191,222, 99,179,159,232, 72, 5, 34, 8,197, 99, 95,120,225, 5,112, 28,135,207, 62,251, 12,175,188,242, 10, + 88,150,197,204,153, 51,193,178, 44,222,121,231,157,128, 69,166,171,128, 41,252,176,225, 51,225, 21, 45,170,230, 69, 3, 0,130, + 53, 26, 49, 66, 77,170,123, 56,142,115, 58, 89, 55,222,120, 35,120,158, 71, 70, 70, 6, 56,142,115, 58, 89,195,135, 15,119, 77, + 71, 18, 8, 39,199,113,200,203,203,115,134, 57, 35, 35,163,145,147,197,113, 28,238,188,243,206, 64,130, 57, 61, 52, 52,116, 74, +167, 78,157, 58,207,154, 53,139,151, 72, 36, 24, 60,120,112,106, 76, 76,204, 57,155,205, 22, 49,117,234, 84,165,135,115, 20, 0, +186,117,238,220, 89, 69, 75, 13, 69, 11, 58, 90, 83, 60,252, 21,230,218,231,170, 9, 47,146,171, 93,143, 23, 57,220,197,145,195, + 33,203,241,199,229,233, 92,127,224, 68, 5,233,203, 82, 15, 68,104, 57,108,103,159, 23, 83, 42,149, 71,202,203,203, 51, 20, 10, + 69, 35,145,229, 73,112, 73, 36, 18,148,150,150, 66,169, 84, 30, 49,153, 76,205,118, 19,253, 53, 29, 2, 48,158, 62,125,122,188, +203,239, 33,195,135, 15,255,102,227,198,141,177,217,217,217,216,179,103, 15, 34, 35, 35, 49,119,238,220,139,101,101,101,255, 2, +176,177,178,178,210,239,117,219,182,109,219, 69,173, 86, 99,199,142, 29, 0,176, 21,192,191,159,123,238, 57,198,106,181, 98,222, +188,121, 58, 0,235, 66, 67, 67,215, 44, 95,190,188,123,183,110,221,100,217,217,217,218, 61,123,246,252, 22,160,200,178, 11,130, +112,153,192,114, 77,211,224,224,224, 64, 28, 45,107, 72, 72,200, 81,173, 86, 59,202, 96, 48,104,229,114,121,176, 86,171, 53,185, + 10, 44,145,159,227, 56, 62, 47, 47,175, 4, 64, 74, 72, 72,200, 81,120,105,230,228, 56,110,240,224,193,131, 57,247,123, 80, 86, + 86,134,210,210, 82, 88, 44, 22,244,232,209,131,145, 48, 86,201,165,162, 35,110,211, 58, 80,145,245, 39, 57, 90, 68, 44,235,226, + 40, 65, 79, 35, 13,215,175, 95,239,252,205,178, 44,190,254,250,235,128, 68,209,198,141, 27,125,118, 88,119,107, 58,244,107,141, +139,199,127,254,249,231, 32,132, 56,157, 44,150,101, 49, 97,194, 4,200,229,114, 76,155, 54, 13, 19, 38, 76, 0,199,113,126,155, + 14, 93, 5, 76,210,235,122,215,151,163,134, 66,225,232, 15,197, 48,140,171,216, 98, 2, 21,111,190,220,188, 64, 90, 2, 92, 57, +197,243,130,130,130,188,118,132,119,227,244,117,129, 95, 0,228,199,198,198,238,200,200,200, 8,217,191,127, 63,102,206,156, 41, + 53,153, 76,109,178,179,179,157,215,245,148, 94, 58,157, 78, 65, 75, 14, 69, 75,184, 89, 62,254,174,112,235, 95,197,184, 54,227, +249,248,116, 63, 30, 46,251, 92,121, 43, 24,134,177,122,184, 94,133, 7,113,229,126, 13,215, 99, 42,188, 58, 90,254, 42, 11,127, +130, 43, 16, 71, 75,175,215,255,182,110,221,186, 94, 15, 63,252, 48,231,171,217, 80,167,211, 33, 58, 58, 26,199,142, 29,179,233, +245,250,223, 2,112,202,154, 83,104,185, 35,187,188,188, 92, 98,181, 90,209,190,125,123,196,199,199,195,104, 52,162,166,166, 70, + 2, 96, 99,128, 28, 82,149, 74, 37, 1,128,154,154, 26,160, 97,168,105,106,135, 14, 29,112,224,192, 1, 84, 87, 87,255, 8, 96, +216,148, 41, 83,122,244,238,221, 91,250,253,247,223,235,159,121,230,153, 31,173, 86,107, 64, 74, 67, 16, 4,179,205,102, 75,102, + 89,214, 82, 83, 83,115,193, 53, 61,163,163,163,195, 85, 42, 21, 83, 86, 86,102, 13, 68,104,117,235,214,109,239,249,243,231, 49, +117,234,212,138,233,211,167,119,168,171,171,187, 84, 91, 91,107,115, 21, 91, 70,163,145,109,213,170,149,124,222,188,121, 10, 0, +232,214,173,219, 94,111, 66, 75,167,211,181, 86, 42,255,120, 49, 54,153, 76, 40, 45, 45, 69,105,105, 41,202,202,202, 80, 87, 87, +135,148,148, 20,232,245,250, 68, 90,205,252,101, 66,171, 81,243,153,107,249,118,125,144, 55,165,172,187, 10,152,187,239,190,219, +217,183, 75,116,200,196,109,197,138, 21,238, 29,204, 3, 18, 90,159,127,254, 57, 94,120,225, 5, 4, 5, 5, 97,214,172, 89,141, +154, 14,221,197,129, 32, 8, 76, 32,113, 79,126,195,128,210, 57,225,224,121, 30, 17,207,148, 53,106,162,243, 32, 56, 2, 10,231, +244,233,211,155,165,233,208,149, 51, 49,177,161,168, 44, 88,176, 0,163, 70,141,194,182,109,219,174,184,233, 48, 45, 45,109,201, +234,213,171, 67,142, 31, 63, 14,173, 86,139,138,138, 10,152, 76, 38, 20, 23, 23,123,109, 21,112,212,229, 65,180,228, 80,252,201, +245,212,190, 63,147,183, 57,175,199,249,121,128, 7, 44,180, 2,113,180, 76, 38,211,172, 23, 95,124,241,185, 33, 67,134,132, 7, + 7, 7,163,164,164,228, 50,145, 85, 95, 95, 15,181, 90, 13,131,193,128, 85,171, 86,105, 77, 38,211, 44,127,226,192,106,181, 34, + 42, 42, 10,149,149,149, 16,188,244,159,102, 89, 22, 10,133, 2,245,245,245,128,159, 78,230,158, 30, 24, 22,139, 5, 86,171, 21, + 86,171, 21, 22,139,197,239, 91,178,187,153,167, 82,169, 68,225, 1, 0,186,184,184,184,246, 65, 65, 65, 40, 40, 40, 0, 26, 70, +246, 13,185,253,246,219,249,170,170, 42,242,228,147, 79,110, 39,132, 60, 5,223,179,227,155,115,114,114,146, 1, 64,161, 80,228, + 2, 64,113,113,177,181,166,166,166,145, 83,168, 84, 42,201,136, 17, 35, 98, 9, 33,200,201,201, 73,150, 74,165, 4,222, 71, 53, + 26, 87,174, 92,121, 60, 36, 36,100,105, 86, 86,214,195,153,153,153,199,186,116,233,146,172,211,233,202, 13, 6,131,193,104, 52, + 18,137, 68, 34, 13, 11, 11, 11,218,176, 97,195,153, 93,187,118, 13,209,104, 52, 75, 87,174, 92,121,220,155,243,166, 82,169,138, +245,122,125,146,120, 79, 93, 69, 86,105,105, 41, 8, 33,200,207,207,135, 82,169, 60,239,175, 89,151,162,229, 32,190, 84,185, 59, + 47,238,251, 2, 21, 89,174,194, 96,195,134, 13, 62,231,208, 10,148,211, 85, 20,189,242,202, 43,152, 51,103,206,101,142,214,180, +105,211, 0, 0,111,191,253,118,192,125,180, 68,247,170,116, 78, 56, 98, 94,168,110, 20,118, 0, 96,196,240, 53,173,204,131,227, + 56, 76,157, 58,245,178, 78,234,174, 77,123, 1, 54,241, 53, 10,103,121,121, 57, 56,142, 67,120,120, 56, 30,121,228, 17, 12, 29, + 58,212,217, 4,217, 84,222,147, 39, 79,238,120,227,141, 55,186,166,165,165,225,253,247,223,175, 14, 13, 13, 13,254,207,127,254, +195,213,212,212, 48,190, 28, 45, 42,180, 40, 40,154, 65,104,137, 5, 44,208, 81,135, 94, 42,203, 33,104, 60,215, 70,173, 94,175, +127,228,182,219,110,251,105,217,178,101,138,182,109,219,226,228,201,147,168,174,174,134,217,108,134, 84, 42, 69,108,108, 44,106, +106,106,240,245,215, 95, 27,244,122,253, 35, 0,106,253,112,190,213,179,103,207, 47, 62,254,248,227,160,244,244,116, 84, 87, 87, +163,190,190,222, 41,132, 24,134,129, 70,163,129, 66,161,192,222,189,123,177,126,253,122, 3,128,183,252,112,122, 82,115,176, 88, + 44, 78,193, 21,128,208,114,229, 84,137,174,142, 94,175, 7, 0,107,235,214,173, 99, 0, 32, 63, 63, 31, 0, 10, 83, 82, 82,166, +180,109,219,150, 89,188,120, 49, 33,132,172,247, 34,178,156,156, 12,195, 84, 19, 66, 46, 1,136, 49,155,205, 82, 0,168,173,173, +181,180,106,213, 42, 74, 46,151, 11, 10,133, 66, 8, 10, 10, 18, 74, 74, 74,108, 54,155, 77, 10, 0,253,250,245, 51, 3, 40,117, + 91,163,208,149, 83, 32,132,104,231,207,159, 63,101,244,232,209, 25,125,250,244, 73,123,246,217,103,143, 62,249,228,147,108,124, +124,124, 88, 93, 93,157,241,244,233,211,151, 62,249,228,147,186,221,187,119, 15,225,121,254,220,252,249,243,167, 0,208, 50, 12, + 35,120,226,180,217,108,191,101,103,103,255, 43, 51, 51,147,187,112,225, 2,202,202,202,156, 34,171,172,172, 12,157, 58,117,194, +174, 93,187,236, 22,139, 37,187, 9,233,217, 92,160,156, 13, 47, 33, 68, 44,235,222, 4,150,248, 50, 21, 40,167,171, 40, 26, 53, +106, 84, 35, 23, 75, 42,149,226,135, 31,126,240, 88,111,120, 40, 87,141,226,238, 58,199,215, 27,111,188,209, 72,180, 77,154, 52, +201,107,117,230, 47, 61, 69,158,218, 5,241,141, 71, 29,122, 41,231,190,194, 41,214,157, 60,207, 99,210,164, 73, 1, 59, 90,184, +188,143,214,101,156, 98,220, 7, 12, 24, 0,189, 94,239, 20,178,222, 28, 45,127,233,105,183,219, 95,152, 51,103, 14,209,104, 52, + 55,107,181,218, 71,207,159, 63,191, 80,175,215,223, 84, 91, 91,235,211,209, 50,153, 76,114, 90,142, 40, 39, 90,102,126,174,235, + 71,104, 57, 30,146,104,221,186,117,163,181,179, 88,150,109,180, 53,165,159,129, 3, 27,242,242,242,238,187,229,150, 91,190,125, +225,133, 23,130,211,211,211,249,164,164, 36,232,116, 58, 20, 20, 20,224,216,177, 99,182,149, 43, 87,106,245,122,253,163, 0, 2, + 25,117,182,232,248,241,227,235,135, 13, 27,246, 78,239,222,189,159,158, 60,121,178, 36, 53, 53, 21,181,181,181, 8, 11, 11, 67, + 84, 84, 20, 78,157, 58,133, 85,171, 86,217, 43, 43, 43,191, 0,240, 30, 60,180,161,250,123,225,183, 88, 44,120,232,161,135, 32, + 8, 2,102,207,158,141, 64, 22, 84,118,129,197, 98,177, 16, 0,140,163, 63,151,222, 49,187, 52, 78,159, 62, 13, 0,231,146,147, +147,131, 1, 32, 59, 59,155, 65,195,252, 90,129,188,225, 19, 66,136,211,217,234,212,169, 83,129,123,229, 40, 58, 89,162, 11,230, + 47,220, 12,195, 24, 9, 33,229,122,189,126,216, 43,175,188,242,206,231,159,127,254,240,231,159,127,126,217,113, 26,141,102,233, +204,153, 51,223,123,224,129, 7,202, 25,134,241,218,143, 76,167,211,189, 61,102,204,152, 7,142, 28, 57, 18, 28, 20, 20, 4,157, + 78,135,170,170, 42, 88, 44, 22,164,164,164,160,188,188, 28,139, 22, 45,170, 51, 24, 12,239,210,226,248,215,192, 85, 24,120,115, +181, 2, 16, 89, 94, 93,157, 95,126,249,197,227, 28, 85, 77,229,116, 23, 27,129,206,109,229,235,165, 72,156,150,198,211,148, 17, + 77,172,215, 46,227,229, 56, 14, 31,125,244,145,115,210, 86, 79, 78, 86, 83, 28, 45,145, 51, 60, 60,188,193, 38, 87, 42, 33, 8, + 2,238,188,243,206,171,225, 21, 0,140,115,153,241,125,250,107,175,189, 54,165, 83,167, 78,169, 0,228,174,105,208, 68, 23,159, +130,130,194,159,208,178,219,237,197, 29, 59,118,108, 84,193,249, 91,204,212,106,181, 22, 7,120,221,245, 58,157, 46,101,230,204, +153, 47,170, 84,170, 33,122,189,190,171,163,226, 56,162,211,233,178, 77, 38,211,167,104,218, 34,208, 21, 0,158,223,189,123,247, +236, 97,195,134, 77,187,245,214, 91, 71,142, 31, 63,158, 33,132, 96,222,188,121,228,236,217,179, 43, 28, 46,214,217, 43, 73,164, +240,240,240,227, 95,127,253,117,244, 79, 63,253, 4,171,213,138, 79, 63,253, 20,193,193,193,199,171,171,171, 3,165, 40,223,180, +105,211, 55,125,250,244,121,108,215,174, 93,139, 0,252,190,117,235,214,133,125,251,246, 29,179,107,215,174, 37, 0,142,109,222, +188,121, 97,239,222,189,199,236,219,183,111, 57,128, 67, 77,168,124,157,206,150,205,230,185,165,209,139,147,229,139, 83, 75, 8, +177, 60,254,248,227,227, 31,120,224,129, 47,247,237,219,119, 83, 77, 77, 77, 87, 0, 8, 13, 13, 61,210,171, 87,175,189,203,150, + 45, 59,229,112,178,252,117,214,175,208,233,116, 35,186,118,237,250,227,251,239,191,175, 74, 75, 75,227,218,183,111,143,194,194, + 66, 28, 61,122,212,246,191,255,253,175,222, 96, 48,220, 13,224, 18, 45,142,127,157,208, 34,132, 32, 52, 52,180,209, 75,148, 56, +228,191,169,205,133,174, 15,102,113,169, 30,119, 94,111,156,190,166, 77, 16,161, 86,171,157,147,155, 6,210,101, 65, 16,124,207, +199, 70, 8,113,114,138, 91, 0, 34,203,239, 8, 65,199, 18, 56, 1,115, 6, 50,189,131, 74,165,130,213,106,117,242, 6, 48,242, +179,169,106,241, 23, 0,191, 88,173,214,211, 0,218, 81,113, 69, 65,209,130, 66,235,210,165, 75, 61, 91,248,218, 90,147,201,244, +158,201,100,122, 79,220, 97, 52, 26,175,150,243, 44,128, 7, 54,109,218,244,241,166, 77,155,196,118,132,169,240,191, 94,162, 79, +156, 60,121, 50,147,231,249,255, 46, 93,186,180, 55, 33, 4, 33, 33, 33,187, 11, 11, 11,255,211, 20, 14,187,221,254,248,174, 93, +187,158,131,163, 47,147,197, 98,121,124,199,142, 29, 47,162, 97, 61, 38,216,237,246,199,247,236,217,227,252,221,196, 7, 37, 33, +132,152, 8, 33,113, 94, 14, 49, 53,209,129, 19,157, 45,243,178,101,203,234, 1, 28,198, 31,243,100, 89, 29,155,209,173,185,208, + 23, 54,235,116,186,246,147, 38, 77,154, 46,145, 72, 6,235,116,186,120,149, 74, 85,100,179,217,126,211,235,245,111,161, 97,141, + 42,138,191, 8,102,179,249, 66,199,142, 29, 57, 79, 47, 80,190, 30,228,190, 94,172,236,118,123,113,135, 14, 29,252,190,156,121, +224,188,224, 67, 52,156, 75, 73, 73, 97, 3,229, 18, 97,177, 88,202,125,133, 51, 37, 37, 5, 77,229,244, 23,247,228,228,100,143, +113,247, 35, 8,189,198,221,102,179, 93, 17,167,175,244,244, 5,131,193,112, 41, 50, 50,178,222,104, 52,242, 38,147,137,183,217, +108,141,236, 71,133, 66, 81, 97, 48, 24,104,225,161,160,184, 26,161,245, 15,199,126, 52, 44, 47,209, 92, 48, 29, 57,114,228, 49, +167, 61, 85, 94,126,165, 60,238, 74,178,222,207,239,166, 8,163,102,119,132, 28, 66, 74,223, 76,116,149,245,245,245, 79,138, 63, +196, 62, 32, 20,127, 61,170,170,170,110,110,110,206,234,234,234,102,127, 81,171,172,172,204,104,129,184,247,188, 94, 57,125,161, +164,164,228,102, 63, 66,140, 22, 28, 10,138, 0,193,210, 36,160,160,160,160,160,160,160,160,104, 25, 48,104, 24, 57,224, 9, 77, + 25, 77, 48,228, 10,174,157, 77, 57, 41, 39,229,164,156,148,147,114, 82,206,235,142,211, 31, 55, 29,205,216,194, 2,140,114, 82, + 78,202, 73, 57, 41, 39,229,164,156,215, 31,231, 53, 9,218,116, 72, 65, 65, 65, 65, 65, 65, 65, 65,133, 22, 5, 5, 5, 5, 5, + 5, 5, 5, 21, 90, 20, 20, 20, 20,174, 72,109,221,186,245,137,212,212,212, 11, 0,198,182,240,181, 30,233,221,187,119,149, 92, + 46,223, 0, 32,149, 38, 61, 5, 5, 5, 21, 90, 20, 20, 20,215,180,200,234,218,181,235,246,147, 39, 79,118,202,206,206,142,139, +143,143,255,176, 37, 47,214,179,103,207, 15,182,109,219, 22,190,110,221,186,219, 98, 98, 98,114,174, 80,108,165,182,105,211,230, + 68,106,106,106, 49,128, 71,154, 57,136, 99, 51, 50, 50,170,101, 50,217,122, 42, 4, 41,174, 3,116, 1,208,149, 10, 45, 10, 10, + 10,138, 22, 20, 89, 59,119,238,140, 48, 26,141, 56,121,242, 36, 42, 42, 42, 14,181,228, 5,115,115,115, 47,237,220,185, 19, 9, + 9, 9, 88,178,100, 73,100,114,114,242,182, 38, 10,154,212,174, 93,187,110, 63,113,226, 68,167,236,236,236,248,168,168,168, 79, +154, 51,124, 55,221,116,211,180,109,219,182,133,109,216,176, 97,104,100,100,228,149, 10, 65, 10,138,191, 51,228, 0, 30, 99, 24, +102,111,151, 46, 93,142,164,165,165,253,206, 48,204, 46, 0,163,112,237,206,221, 25, 24, 86,175, 94,189,117,245,234,213, 91,105, + 30,161,160,160,104, 6,164,165,165,165,233,116, 58, 29,169,168,168, 32,159,125,246, 25, 9, 15, 15,183, 0,248, 13,192, 74, 15, +219,155, 0, 52, 1,114,107, 28,199,123,226,249, 45, 60, 60,220,242,217,103,159,145,252,252,124,114,252,248,113,146,154,154,106, + 8, 80,208,164,118,237,218,181, 82, 12,243,218,181,107, 9,199,113,235,155, 51, 81, 52, 26,205,177,156,156, 28,114,246,236, 89, +178, 97,195, 6, 18, 29, 29, 93, 78,197, 22,197, 53,130, 36, 0, 31,168,213,234,234,187,238,186,139,124,245,213, 87,100,213,170, + 85,228,199, 31,127, 36,179,102,205, 34,131, 6, 13, 34, 50,153,236, 2,128,215, 1,132, 94, 79, 90,132,113, 68,140, 0, 24, 8, + 0,153,153,153, 84,108, 81, 80, 80, 92, 45,118,234,245,250, 12,189, 94,143,186,186, 58,180,110,221, 26, 60,207,123, 60,176,188, +188, 28, 59,118,236,192,184,113,227,142,151,150,150,246,135,239,117, 47,195,186,119,239,190,115,243,230,205,169,193,193,193,206, +157,130, 32,192, 98,177,192,106,181,194, 98,177,192,100, 50,193,100, 50, 65, 38,147, 65,161, 80, 32, 60, 60,252, 40,124, 55, 97, + 56,221, 55,131,193,128,131, 7, 15, 98,244,232,209, 21, 85, 85, 85,253, 1,228, 54, 99,186,164, 70, 69, 69,229, 44, 90,180, 40, + 50, 37, 37, 5,231,207,159,199, 19, 79, 60, 81,121,238,220,185,126,205,124, 29, 10,138, 63, 19, 19,238,187,239,190,105,209,209, +209,108,151, 46, 93, 16, 27, 27, 11,147,201, 4,131,193, 0, 66, 8, 56,142, 3, 33, 4,181,181,181,200,201,201,193,230,205,155, + 77,151, 46, 93,250, 26,192,167, 0,242, 92, 68,214, 53,169, 69,156, 66, 43, 51, 51,147,161,121,133,130,130,162,153,112,164,182, +182,182,139,201,100,130, 78,167, 11,232,132,252,252,124,140, 29, 59,246,120,105,105,233, 45,240,188,168,188,166,123,247,238,123, +114,114,114, 82,141, 70, 35,180, 90,255,235,206,203,100, 50, 4, 5, 5, 33, 34, 34, 98, 23,128, 62,222,222,196,187,116,233,178, +127,215,174, 93,225, 6,131, 1,135, 14, 29,194, 35,143, 60, 98,169,174,174,222, 14,192, 91,224,171,209,176,142,234, 57, 15,255, + 37, 2,120,209,241,134,239, 9,170,200,200,200,190,139, 23, 47,150,182,109,219, 22,122,189, 30,163, 70,141,170,206,205,205,237, + 5,160,128,102, 29,138,127, 32,114, 79,158, 60,217,193,110,183,163,178,178, 18, 38,147, 9,122,189,222, 41,180, 36, 18, 9, 8, + 33,176,217,108,206, 23,163, 3, 7, 14, 32, 59, 59,155,228,231,231, 79,118,148,165,107, 86,139, 80,161, 69, 65, 65,209, 18, 72, +237,208,161,195,161, 95,127,253, 53, 72, 42,149, 98,213,170, 85,152, 60,121,178,181,186,186,122,155,187,120,137,142,142, 78, 91, +184,112, 97,114, 74, 74, 10,126,255,253,119,220,127,255,253,111, 1,152,238,129,243, 77,173, 86, 59,205, 98,177,224,208,161, 67, + 24, 51,102, 76, 65, 89, 89,217, 49,119, 17,147,156,156,220,239,147, 79, 62,225,123,244,232, 1,173, 86,139,145, 35, 71,234, 79, +157, 58,213, 27,192, 49, 47, 97,253,164,186,186,250, 21,187,221,142,186,186, 58, 36, 36, 36, 64, 42,149,250,140,156,193, 96, 64, + 82, 82,210,174,138,138,138,203,196, 91, 68, 68,196,166,243,231,207, 15, 82, 40, 20, 62, 57, 44, 22, 11,138,139,139, 33,147,201, + 96, 50,153,208,174, 93,187,175, 1, 60, 78,179, 14,197, 63, 81,104, 29, 62,124,184,195,119,223,125,135,238,221,187,163,115,231, +206,168,175,175,119,138, 46,179,217, 12,171,213,122,217, 73, 90,173, 22, 47,191,252,114, 30, 28,205,231,215,170, 22, 17, 59,166, + 77, 17,219, 68, 51, 51, 51, 7,208, 60, 67, 65, 65,113,181, 21,111, 94, 94, 94,250,144, 33, 67,182,173, 88,177,162,213,240,225, +195,209,174, 93, 59,254,222,123,239,141,212,235,245,131, 93, 15, 44, 43, 43, 11, 27, 51,102,204,254,162,162,162,100,199,174, 94, + 94, 56,123, 5, 7, 7, 35, 63, 63, 95, 20, 89, 61,225,214,204, 40,147,201,214, 31, 62,124,152,151,201,100,216,183,111, 31,198, +142, 29, 91, 89, 80, 80,224,175, 89, 46,212,108, 54, 67, 34,145, 0, 0,138,139,139,253, 70,238,252,249,243, 16, 4,193,228,233, + 63,150,101,229, 7, 14, 28, 64, 92, 92,156, 79, 14,150,101,221, 5, 93, 13,205, 54, 20,255, 80, 88,205,102, 51,122,246,236,137, +130,130, 2, 28, 56,112,192, 41,184, 42, 43, 43, 81, 82, 82,210,232,224,189,123,247,226,224,193,131,232,223,191,191, 59,207, 53, +169, 69,156,202,113,245,234,213, 3, 28,145,219, 74,243, 12, 5, 5, 69, 51, 33, 53, 46, 46, 46,103,209,162, 69,145,177,177,177, + 24, 52,104, 80, 81,105,105,105, 27, 15,199,173, 36,132,220,157,159,159,143,182,109,219,174, 2,112,207,149, 28,147,152,152, 88, +177,111,223,190, 86,199,143, 31,199, 35,143, 60, 82,225,232,243,229,175,239, 83,114,167, 78,157,246,109,216,176, 33,156,101, 89, + 28, 59,118, 44,144,166,195, 66, 52,244, 47, 57,231,225,191, 68, 0,147, 0,132,123, 57, 87,213,161, 67,135,190,251,247,239,151, + 50, 12,131,194,194, 66,177,233,176,167,131,151,130,226,159,134, 17,113,113,113,255,123,238,185,231, 66,122,247,238,141,226,226, + 98, 92,184,112, 1,151, 46, 93, 66,122,122, 58,210,210,210,112,246,236, 89,172, 95,191, 30, 7, 15, 30,132, 92, 46, 71, 66, 66, + 2,212, 75,191,195,127, 25, 28, 7,144, 70,181, 8, 5, 5, 5,197, 85,136, 45,169, 84,186, 62, 62, 62,190, 28,158,231,165, 10, + 27, 57,114,100,137,221,110, 39,103,207,158, 37,104, 24, 61, 8, 47, 66,139,156, 61,123,150, 68, 71, 71,231, 3, 8,243,112,204, +216,152,152,152, 34,165, 82,121, 20, 77,156,214,161,125,251,246, 21,167, 78,157, 34, 69, 69, 69,100,221,186,117, 36, 34, 34,162, + 37, 70, 4,166,118,236,216,177,178,174,174,142, 24,141, 70,146,147,147, 67, 18, 19, 19, 43, 64, 71, 30, 82,252,243, 17, 12, 96, +106, 74, 74,138,241,227,143, 63, 38,235,215,175, 39, 11, 22, 44, 32,211,166, 77, 35,227,199,143, 39, 25, 25, 25, 36, 35, 35,131, +140, 26, 53,138,188,242,202, 43,228,246,219,111, 39,106,181,186, 22,192,189, 52,233, 40, 40, 40, 40,154, 23,137, 0,102, 57, 4, +213,202,145, 35, 71,150,152, 76, 38,114,225,194, 5,242,195, 15, 63, 16, 52, 76,221,224, 9,111,150,150,150,146,210,210, 82,113, +106,132,124,252, 49,173,195, 87, 14,222,171, 18, 65, 73, 73, 73, 21,251,247,239, 39,133,133,133,100,237,218,181,196, 33,216,154, + 13, 10,133, 98,131, 86,171, 37, 70,163,145,108,218,180,137, 78,239, 64,113, 45, 34, 10,192,220, 27,110,184,193, 58,123,246,108, +178,114,229, 74,242,217,103,159,145, 17, 35, 70,144,215, 95,127,157, 60,248,224,131, 36, 50, 50,210, 4, 32, 11, 64, 8, 77,174, +171, 7, 93,217,156,114, 82, 78,202,233,142,245,199,143, 31, 39, 34,236,118, 59,185,112,225, 2,217,176, 97, 3,137,137,137, 57, +134,198,243,105,185,114,106, 58,119,238,124,242,212,169, 83,228,252,249,243,196, 98,177, 56, 57, 78,158, 60, 73, 0,108,109,134, +112,166,198,199,199,151,111,217,178,133,156, 58,117,138,196,196,196, 20, 53,103,220,147,146,146,202, 43, 42, 42,200,166, 77,155, + 72,100,100,164, 63,145, 69,243, 18,229,252, 39,115, 38, 1, 88,220,163, 71, 15,251,156, 57,115,200,211, 79, 63, 77, 18, 19, 19, +237,142,151,162,248,235, 73, 8, 93,223,179,180, 82, 80, 80,252, 21,144,239,222,189, 27,114,185,220,185,227,247,223,127,119,157, + 71,203,219,188, 13,218, 19, 39, 78,220, 50,124,248,240,109,115,230,204,233,236, 58,138,105,203,150, 45, 0, 96,106,134,176,229, + 94,184,112,161,255,176, 97,195, 62,141,136,136,184,177,180,180,244,157,230,140,120, 97, 97,225, 43, 93,187,118,157, 94, 87, 87, +167,213,235,245,163, 64,231,206,162,184,118, 81, 8, 96,244,129, 3, 7, 62, 60,112,224,192, 91, 0, 8,128,247, 1,156,184,222, + 18,130, 10, 45, 10, 10,138, 63, 27, 99,159,124,242, 73,247,206,226,251, 0,252,159, 15,145, 37,226, 82, 65, 65, 65,159, 59,239, +188,243, 57, 52, 30,157, 40,118, 78,111, 14,228,154,205,230,161,238, 35,165,154, 9, 75, 74, 75, 75,151,208, 44, 64,113, 29,225, + 24,128, 7,175,231, 4,160, 66,139,130,130,226,207,198, 57, 0, 79, 92,197,249, 90,120,158,103,139,130,130,130,226,111, 7,186, +168, 52, 5, 5, 5, 5, 5, 5, 5, 5, 21, 90, 20, 20, 20, 20, 20, 20, 20, 20,255, 44, 48,240, 62,114, 32,187, 9, 60, 87, 50, +162, 33,155,114, 82, 78,202, 73, 57, 41, 39,229,164,156,215, 29,167, 63,238,108, 80,180,168, 0,163,156,148,147,114, 82, 78,202, +249,207,230,100, 28, 27,235,216,196,223,127,231,184, 51,127,227,184, 95, 47,156,215, 36,254,170,206,240,226,141, 16,208, 48,228, +147,226,239, 7,215, 2, 66,232,125,162,160,160,104, 98,221, 33,113,121,216,218, 29, 27,254,134,117,137,171, 40, 16,174,242,185, +212, 18,113,191,158, 57,175,121,161,117,163, 74,165,154, 44,147,201, 82, 24,134,177,235,116,186, 35, 38,147,105, 62,128, 93, 87, +121,205,175,162,163,163,199, 86, 85, 85, 9, 44,203,130,101, 89, 48, 12, 3,150,101,193,243,188,161,182,182, 86,115, 37,164,145, + 93, 70,188,202, 49,204, 11,118, 98,159, 95,126,116,213, 52,127,251, 41,124, 23, 24,169, 84,122, 95,120,120,120,104, 69, 69, 5, + 97,217,134,174,124, 18,137, 68, 92, 8,215, 86, 91, 91,251, 77,160,100, 97, 97, 97,123,195,195,195, 67,197,243, 25,134, 65, 85, + 85, 85, 77,121,121,249, 77, 0, 16, 20, 20,180, 67,165, 82, 69,112, 28, 7,137, 68, 2,137, 68, 2,189, 94, 95, 85, 85, 85,117, + 11,189, 21,255, 76, 44, 95,190, 92, 50, 44,254,137,118, 28, 49,116, 99, 89, 18, 34, 8, 76,173,141, 81,252,190,254,194, 87,103, + 2, 57,127,212,168, 81,118,154,138,127, 30,100, 50,217,236,232,232,232,127,215,215,215,235, 25,134, 33, 12,195,128, 97, 26,222, +179,220, 63,237,118,123,113, 85, 85, 85, 79, 63, 15, 91, 94, 38,147,205,140,137,137, 25,163,215,235,245, 14, 62,143,188, 0, 96, +181, 90,139, 43, 43, 43,123, 6, 84,215, 71, 70,206, 87, 40, 20,143,234,245,122, 29,195, 48,130,235,127,132, 16,215,135,249,217, +202,202,202,126,254,132,129, 76, 38,251, 52, 58, 58,250, 95,142,184, 59,195,121,181,113,143,142,142, 30,163,211,233, 2,226,244, + 17,247,203, 56, 91, 34,156,127, 83,206,107, 95,104,165,167,167,127,183,103,207,158, 14, 60,207, 3, 0,140, 70, 99,215,185,115, +231, 62,246,198, 27,111,100, 1,152,120,133,215, 91,216,175, 95,191,135,114,114,114,216,149, 43, 87,178,189,122,245, 2,195, 48, +176,219,237,176,219,237,232,210,165,139,226, 74, 35, 18,162, 82, 78, 56,184,241,191, 65, 55, 14,121,242,133,114, 96,154,191,253, +190, 4, 38,128,183, 1,164, 52, 49, 8, 21,142,116, 57,232, 69,108,236,100, 89,182, 73,156,130, 32,228, 95,186,116,169,143, 15, + 1,211,236,156, 14,145,117,127,191,126,253, 66,178,179,179,153,162,162, 34, 70,161, 80, 64, 16, 4,216,237,118, 88,173, 86,220, +112,195, 13, 77,114, 66, 67, 67, 67, 53, 19, 38, 76,104,119,199, 29,119,224,135, 31,126,192, 99,143, 61,134,190,125,251,230,149, +151,151, 3, 0, 84, 42, 85,196,241,227,199, 59,132,135,135, 67,175,215,163,182,182, 22,183,221,118, 27,170,170,170,254,209,133, +235,230,244,132,247, 25,150,113,206, 21, 69,108,246,234, 61,191,151,188,125,181,188,225,225,225, 7,229,114,121,180, 95,181,236, +242, 32, 51, 26,141,101,213,213,213,221,253,156,146, 4,224, 46,137, 68,210,158,227,184,142, 0,146,108, 54, 91, 52, 0, 72,165, +210, 50,137, 68, 82,104,181, 90, 79,153,205,230,211, 0,126,129,143, 5,144,135,197, 63,209,142,177,233, 71,214,153,132,225,202, +182, 89,169,250,179, 19,114,149,114,253,218, 97,241, 79,172, 8, 84,108,253,133, 72, 5,176, 12, 13, 11, 74, 63,141,134,121,128, +174, 6,241, 0,238, 70,195,154,143,201, 22,139,165, 18,192, 1, 52,244, 67,201, 3,144, 24, 25, 25,185, 68, 16, 4, 83, 85, 85, +213, 19,240,176, 80,117,239, 30,173,247,179, 44,155, 32,122, 2, 2,177, 23,239, 62, 80,220, 44, 15, 40,150,101, 63,205,204,204, +252,215,138, 21, 43,148, 7, 14, 28, 80,118,238,220,217,249, 66, 36, 8, 2, 26,107, 23, 32, 57, 57,217,159,171,193,177, 44, 59, +123,228,200,145, 15, 47, 94,188, 88,121,238,220, 57,101, 92, 92,156,147,211, 85,108,137,136,139,139, 11, 52,239,127, 53,116,232, +208,209,139, 22, 45,226, 87,173, 90,165,104,213,170, 21, 34, 34, 34, 32,149, 74, 47, 59,246,150, 91,110, 17,252, 71,157,253,244, +158,123,238, 25,253,253,247,223, 43,247,236,217,163,236,210,165, 11, 36, 18,201, 85,199,125,196,136, 17, 15,127,247,221,119,202, + 35, 71,142, 40,219,183,111, 15,209, 84,112,231, 99, 89, 22,173, 91,183, 14,136,243,238,187,239,126,120,217,178,101,202,131, 7, + 15, 42, 59,118,236,232, 76, 79, 66,200, 21,135,243,111,206,121, 93, 56, 90, 50,139,197,130,173, 91,183,130,101, 89,132,135,135, + 99,236,216,177,216,184,113,227,132, 77,155, 54,173,190, 2,103,235, 43,135,200,226, 1,224,199, 71, 71, 32,159, 7,198,149,155, + 33,149, 74,113,246,236, 89, 72, 36,146, 38, 91,139,114,185,124, 12, 33,100,146,254,194, 62,185,193, 96,133,177,100,191, 82,161, + 80, 56, 31, 0,250, 18,199,254,139,251,149, 10,133,226,172, 68, 34,153, 90, 95, 95,191,208, 27, 95,251,246,237,191, 61,118,236, + 88, 39, 79, 5,215, 23,244,122, 61,218,180,105,147, 88, 93, 93,221,222,211,255, 60,207, 39,156, 59,119, 46, 74, 38,147,129, 16, +226, 44,196,238,159,226,119,139,197,130, 27,110,184,193,226,235,154,190, 56,109, 54, 27,130,130,130, 32,186, 81,102,179, 25,245, +245,245,254, 56, 25,169, 84,122,159, 40,178, 0, 96,233,210,165,136,137,137, 65, 84, 84, 20, 84, 42, 21, 20, 10,133,147, 51, 80, + 72, 36, 18, 12, 27, 54, 12,239,190,251, 46,178,178,178,240,218,107,175, 53,170,104,121,158, 71,120,120, 56,214,173, 91, 7,141, + 70,131,196,196, 68,136, 2,255, 31,109, 11,178, 76,248,174,253,231,157, 14,237,237,183,118,226,110,238,206,125,238,120, 84,130, +101, 1, 65,104,120,116, 50, 12,136,205, 42, 92,218,127,164,228,157, 0,210, 51,174,176,176, 48, 42,208, 52,178,217,108,136,139, +139,147,248, 57,108,120, 90, 90,218,143,207, 62,251,172,180,125,251,246,140, 84, 42, 5,199,113,224, 56, 78, 20,232,137,132,144, + 68, 65, 16, 6,150,149,149,145,185,115,231,126,184,101,203,150,123, 1,172,245, 88,177, 16, 67,183, 58,147, 48,124,219, 33,220, + 52,114,200, 27, 88,183,124,194, 77,253,210, 5, 4, 43, 13,103, 0,252,157,133, 86,106, 90, 90,218,161, 61,123,246, 4, 89, 44, + 22,244,238,221,123,119,110,110,110, 15, 92,217, 12,238, 97, 0, 62,153, 56,113,226,232,103,159,125, 86, 18, 26, 26, 10,153, 76, +134,186,186, 58,156, 57,115,102,204, 55,223,124, 67,190,248,226,139,255, 3, 16, 92, 88, 88,152,177,119,239, 94, 12, 26, 52,232, + 69, 0, 47, 95,174, 8, 36, 9, 59,246, 22, 68,137,191,239, 30,214, 85,154,209,147, 45,107,112,113,220,143, 38, 16,236, 66,241, +222,195, 23, 2, 17, 98, 31,142, 24, 49,226,145, 21, 43, 86,168, 1, 96,222,188,121,184,239,190,251, 16, 30, 30, 14,165, 82, 9, +169, 84, 10,158,231, 27,125,250,121,216, 74, 0,124,248,224,131, 15,142, 92,188,120,113, 48, 0, 44, 94,188, 24, 35, 70,140, 64, + 68, 68, 4,130,131,131, 33,147,201, 32,145, 72,154,156,152,225,225,225, 95,245,189,233,166,199, 23, 45, 90, 4, 0,120,235,165, +151,112,199,205, 55, 67,173, 84, 64,169,144, 65, 76, 11,153,132,199,237,227, 94,240,171, 47, 1,124,124,223,125,247, 61,240,253, +247,223, 7, 3,192,129, 3, 7, 80, 94, 94,142,232,232,104, 40, 20, 10,200,100, 50,103,156, 25,134,129, 66,161, 8, 40,238,247, +221,119,223,200,239,190,251, 46, 24, 0, 22, 46, 92,136, 97,195,134, 57,227, 46,151,203, 33,149, 74, 27,109,238,162,211, 19,231, +189,247,222, 59,114,217,178,101,193, 0,240,205, 55,223, 96,200,144, 33, 8, 11, 11,115,166,167,200,213,148,123,244, 55,231,188, + 62,132,214,161, 67,135,238, 87,169, 84, 51, 0, 68,202,100,178,208,135, 31,126,184,245,227,143, 63,142, 7, 31,124, 16,155, 54, +109,122,170,137, 66,139,137,142,142, 30,155,147,147,227,124, 66,155,201,101,130,169,201, 15,112, 7, 38,237,127,234,169,152,172, + 51,245,216,189,247, 20,130,192, 50,123, 63,254, 56,210,120,250, 52,236,102, 51,222, 59, 91,215,176,223, 70,152,173,175,140,139, +185,113,246,255, 77, 2,176,208,135, 11, 32, 55,153, 76,200,203,203,107, 82, 32,138,138,138, 32, 8,130,201,151,187, 32,149, 74, +113,244,232,209,203, 84,189, 39, 36, 38, 38,250, 42,128,126, 57,215,175, 95,143,241,227,199,227,212,169, 83, 16,151, 42, 9,128, +147, 9, 15, 15, 15, 21, 69,150, 40,130, 20, 10, 5,120,158,103, 56,142, 99,196,166, 61, 71,225, 10, 72, 24,179, 44,139,111,191, +253, 22, 31,124,240, 1, 94,127,253,117,204,159, 63, 31,221,186,117,251, 35, 19,114, 28,180, 90, 45,194,194,194, 16, 22, 22,214, + 72, 32,254,147,225,126,155,103,206,154,163,132, 64, 26, 58,129, 16, 1, 16, 0, 2, 2,129, 8, 40,187,112, 6,147,223,253, 40, +224,167, 15,207,243, 56,125,250,180, 51, 31,136,206,176, 40,140, 92, 93,131,164,164, 36,191,121, 73, 42,149, 78,249,249,231,159, +101,223,126,251, 45,190,255,254,123, 48, 12, 3,185, 92, 14,149, 74,133,208,208, 80, 68, 68, 68, 56,183,132,132, 4,230,127, 61, +184,254,121, 0, 0, 32, 0, 73, 68, 65, 84,255,251,159,180, 91,183,110, 83,180, 90,237, 90,207,247,156,132, 40,219,102,165,142, + 28,242, 6, 0, 96,228, 27, 4,151,242,166,221,200,214,188,243,119, 94, 68, 54,181,107,215,174,219,119,238,220, 25,164,215,235, + 33, 8, 2,214,174, 93,171, 28, 50,100,200,182,130,130,130,126, 77, 21, 91, 73, 73, 73,171,118,238,220,121, 75,100,100, 36,106, +107,107,161,213,106, 97,181, 90, 33,145, 72,144,152,152,136, 15, 63,252,144,185,231,158,123,158, 31, 51,102,140, 81,161, 80,136, +206, 70,146,231,188,212, 56, 51,205,253,236,243, 80, 66, 26,242, 15, 17, 72,163,207,234,242, 66,188,244,202,228,128,194,216,186, +117,235,167,127,248,225, 7,181,171,179,228, 42, 2, 92, 69,150,184,249, 17, 6,108,155, 54,109, 30, 95,178,100,137,147,179, 85, +171, 86,224, 56, 14, 60,207,131,227, 56,176, 44,139,109,219,182, 97,198,148,137, 8,139,140,195,156,207,230,249, 13,103,100,100, +228,252, 97,195,134, 61,186,112,225, 31, 85,119,215,182,109,113,231, 45, 55, 35,170,149, 6,173,194,130, 27,210, 73, 96,240,251, +169, 2,191,207, 35, 0,108,235,214,173,159, 88,190,124,185,218,245,133, 80,140,171,248,242, 44,186,248,102,179, 25, 61,123,246, + 12, 40,238,174,156,162,219, 38,138, 54, 49, 61,197,235,136,229,213, 79, 56, 31, 23,133,176, 67,112, 54,226,224,121, 30,203,215, + 45,242,234,102, 95, 41,103, 83,239,187, 59,103, 97, 97, 33,166, 79,159, 14,241,165,205,181,171, 80,124,124, 60,230,204,153,227, +183, 94,114, 43, 3,189, 0, 68,186,236, 50, 3,144,185,124, 86, 48, 12,179,207,195,113,226,126,222,209, 98, 21,137,134,126, 99, +117, 0, 66, 61,240,121,227,169,116, 60,243, 34,221,142,111,116, 29,175, 66,107,245,234,213, 98, 41, 30,152,153,153,185,213,241, +189, 70, 46,151, 23, 41,149,202, 24, 0,117,107,215,174,197,127,254,243, 31, 56,172,213,187, 67, 66, 66,142,121,112,117, 14,153, + 76,166, 55, 0,148, 57,118,137, 67, 52,217,234,234,106, 97,227,198,141,236,226,123,135,194, 76,128,244, 73, 51, 48, 44, 51, 19, +235,227,101,144, 0,184,233,100, 37,148, 74, 37,167,213,106,173,174,253,182, 60,244,221,202,118,203, 80,146, 32,142, 67,239,237, +107, 48,126,251, 26,220,164,146,161,106,197, 50,212,237,200, 1,203, 50,232,175,106,133,215, 30,217,136, 62, 26, 57,100, 38, 29, + 88,150,245,148,179,157,156,121,121,121,163, 52, 26,205, 12,183, 4, 14, 4,249,104, 88,199, 9, 94,194, 9, 66, 8,186,117,235, + 6,134, 97,156,110,129,184,137,133, 78,220, 14, 30,244,216, 2,233,149,211,209, 4, 7,149, 74,133,223,126,251,205,121,204,224, +193,131, 97, 52, 26, 17, 30, 30, 30, 16,103, 69, 69, 5, 41, 41, 41, 97, 22, 47, 94, 12,158,231, 17, 17, 17, 1,165, 82,201, 44, + 90,180,104,162, 84, 42, 77, 48, 26,141,130,217,108,134, 76, 38,155, 35,222, 31,142,227,116, 90,173, 54,194, 27,167, 68, 34,193, +179,207, 62,139, 87, 95,125, 21,243,231,207,199, 83, 79, 61,117,153,227,101, 52, 26,209,170, 85, 43,167,216,242, 80, 0, 91, 98, +184,111,203,114, 10, 4,199, 14,174,199,241, 35,217, 16,236, 2,236, 2, 1, 33,118, 8, 54,224,192,198,221, 29, 46,230,151,196, + 19,144,134,174,183, 0,228,181,245,182, 1, 17,178,142, 0, 86,110,173, 50,207,246, 23, 78,142,227, 96, 52, 26,241,243,207, 63, +227,228,201,147, 88,187,118, 45, 12, 6, 3, 90,181,106,133,208,208, 80,220,124,243,205, 24, 51,102, 12,146,146,146,252,198,157, + 16,178,176,168,168, 40,189,111,223,190, 76, 77, 77, 13,106,106,106, 96, 48, 24, 96,183,219, 97,179,217,192,113, 28,130,130,130, +160, 80, 40, 16, 29, 29, 13,163,209, 72, 76, 38,211, 66,111,156,130,192,212,234,207, 78,200, 93,183,124,194, 77, 35,223, 32, 88, +241, 1,131,118,109,228,250,223,246, 7, 63,190,114,251,107,183, 1, 32, 2,113, 90, 11,196,106, 23, 42, 95,157,248,201,243,127, +250, 61,186, 92,100, 69, 24, 12, 6,212,213,213, 53,216,250, 50, 25, 86,172, 88,209,234,174,187,238,202, 41, 41, 41,233,239, 67, +108, 93,198, 25, 28, 28,156, 40,145, 72,112,244,232, 81,124,241,197, 23,248,237,183,223, 80, 86, 86,118, 41, 46, 46, 46,100,224, +192,129,236, 75, 47,189,132,244,244,116,124,253,245,215, 65,254, 56, 9, 33, 40,204,219,134,194,211,219, 33, 8, 13,174,117,195, +230,249, 59, 9, 48,238, 58,157,206,120,232,208, 33,245,151, 95,126,137,168,168, 40, 36, 39, 39, 67,169, 84, 34, 40, 40,168,209, + 67,214,245,193,235,175,108, 26, 12, 6, 99, 97, 97,161,250,187,239,190, 67, 68, 68, 4,146,146,146,160, 84, 42, 33,147,201,192, +113, 28, 24,134,193,226,197,139,177,244,221, 71, 80,120,234, 8, 70,220,121,155,223,112, 42,149,202, 71, 23, 46, 92,216,200, 2, +137, 14, 11, 3,199,179,144,240, 12,194, 6,223, 11, 0,184,180,233, 39, 95,179, 67,186,114, 50,117,117,117,198, 61,123,246,168, +247,239,223, 15, 65, 16,144,148,148, 4,189, 94, 15,141, 70,227,140,255,198,141, 27,113,207, 61,247,224,219,111,191, 69, 70, 70, +134,223,184,215,215,215, 27,143, 28, 57,162, 94,178,100, 9,194,195,195,209,186,117,107,103,220,197,141,231,121, 72, 36, 18,164, +164,164,160,182,182, 22,106,181,218,239, 61, 58,112,224,128,122,201,146, 37, 8, 11, 11, 67, 66, 66,130,211,113, 19,197,209, 7, +159,191,219,136, 32,136,137,189,106,206,166,222,119,119,206, 17, 35, 70,160, 93,187,118,208,104, 52, 80,169, 84, 78,110, 95,156, + 94,180,136, 83,111, 51, 12,179,218,165, 76,100, 50, 12,179,218,245,211,219,113,142,175,253, 39, 78,156,216, 51, 43, 43,107,122, + 70, 70,198,119, 59,119,238, 92,234,141,207, 27,207,196,137, 19,211,178,178,178,166,187, 30,239,225, 58,222, 29,173,204,204, 76, +198, 17, 73, 6, 64,114,143, 30, 61,246,109,218,180, 41, 60, 56, 56,216,121,240,249,243,231, 81, 83, 83,131,224,224, 96,205,204, +153, 51, 53, 3, 7, 14, 68,116,116,180,243, 13, 32, 47, 47,239,134,212,212, 84, 45, 0,119,223, 86, 96, 89, 22,125,250,244,193, + 49, 71,107,199,176,204, 76, 36, 36, 36, 56, 59,121, 4, 5, 5,225,249,231,159,103,198,143, 31,207,137,110, 6, 33, 4, 6,131, + 1,177,177,177, 10, 95,174, 14, 0,164, 25, 42,241,211,192,254, 96, 25, 64,127,112, 47,164, 50, 6,172,132, 65,119, 82,133, 95, + 7,245, 7, 3,192,124,120, 23, 2,112, 97, 14, 2,184,173,101, 28, 14,130, 51,103,206, 4,228,104, 57,226,197, 92, 41,167,232, +104,236,220,185, 19,118,187, 61, 80, 78,194,178, 44, 84, 42, 21, 98, 98, 98,160, 80, 40,160, 84, 42,153,239,190,251,238,237,228, +228,228,216,241,227,199,179, 90,173,150,237,211,167, 15,238,187,239, 62, 78,108,226, 76, 75, 75,243, 27,151,173, 91,183,226,139, + 47,190,192, 83, 79, 61,229,209,209, 98, 24, 6,145,145,145,208,104, 52,184, 86, 32, 0,176,216,172,208,215, 27,156, 77,186,118, +187, 29, 71,182, 28,238,144,127, 56, 47,109,245,119,223,242, 0, 96,220,242,147,235,105,177,247,125,190, 44,117, 64, 24,191,103, +235, 37,235, 30, 95,121,158,227, 56,140, 29, 59, 22, 89, 89, 89,120,244,209, 71,177,118,237, 90,188,243,206, 59,248,247,191,255, +125,153,171,229,239,205,209,106,181,254,247,177,199, 30,123,106,197,138, 21, 29,223,120,227, 13, 86,116,180,148, 74, 37, 24,134, +129,209,104,132,201,100,130,193, 96,192,169, 83,167,132, 39,159,124, 50,215,108, 54,255,215,107,115, 37,163,248, 93, 41,215,175, +109,155,192,182,211, 21,124, 20,220,247,230, 36, 3,163,232, 81,123,111,234, 16, 50,124,108, 82, 24, 8, 1, 17, 0,129, 0, 38, +147, 14,207, 63,255,162,228, 47,188, 85, 78,145,101, 52, 26,113,232,208, 33, 12, 26, 52, 8, 69, 69, 69, 56,113,226, 4, 58,116, +232,128, 69,139, 22, 69, 62,252,240,195, 57,229,229,229,253, 3,117,182,142, 28, 57, 50,241,198, 27,111,252,180,190,190,190,186, +190,190,254, 83, 0, 75, 1,212,156, 57,115,166,243,153, 51,103,230,174, 95,191,190,223,228,201,147, 37,110,125,116, 36,222,236, + 81,171,213, 6,131,193,228, 83, 96,137,191, 9, 17, 2,138, 56,195, 48,164, 99,199,142,184,235,174,187,192,243, 60,148, 74, 37, +212,106,117,163,102, 51,119,193,229,171,254, 0, 32, 48, 12,131,184,184, 56, 12, 31, 62, 28, 82,169,180, 17,167,152, 15,135, 15, + 31,142, 23,222,155,132,255,190,112, 43,190,120,172, 3,134,188, 95,230, 51,156,122,189,190,126,243,230,205,138, 87,159,122, 10, + 55,182,111,143, 86, 26, 13,218, 68, 71, 66, 33,151, 65,234, 26, 38, 38, 32,147,157, 0, 16, 36, 18, 9,186,116,233,130,178,178, + 50, 20, 20, 20,160,160,160, 0, 44,203,162,111,223,190, 78, 23,230,244,233,211,120,239,189,247, 96, 50,153, 2,142,123,251,246, +237,113,235,173,183, 66, 38,147, 65,169, 84, 54,106, 50, 20,211,180,174,174, 14,237,218,181,195,202,149, 43,145,154,154,234,151, +179, 83,167, 78, 24, 48, 96, 64,163,244, 84, 40, 20, 78, 81, 4, 0, 69,123,234,157,215,136,143,143,111, 18,231,134,189,231,241, +229,198,205, 48,153, 5,104,245,214, 70, 39,196,182,210, 96,251,146, 55, 2,138,187,200,185, 96,193, 2,212,212,212, 56,141, 3, +241,165, 92, 52, 81, 90,183,110,141,121,243, 60, 59,153,110, 90,196,211, 51, 47, 51,192,231,173,120,156,152,185,228, 89, 89, 89, +211,221,207,247,199,231,250,191,219,249,102, 55,113, 86,214,164,166, 67,185, 92,254,230,230,205,155,195,107,107,107,113,250,244, +105,176, 44,235,108, 83,231, 56, 14, 22,139, 5,103,207,158, 69,120,120, 56,202,203,203, 33,151,203, 33,145, 72, 96, 54,155, 1, +160,187,183, 7, 56, 33, 4, 47, 84, 52,116, 17, 90, 23, 39, 69, 33,128, 59, 43, 26, 10,134,216, 33,254,135, 31,126,128, 90,173, + 70,112,112,176,243,211, 95, 51,210,145,130, 51, 40,227, 25,176,187,182,129, 97, 1,150, 1, 24, 9,192,178, 4, 44,195,128,221, +149, 3,134, 1, 84, 17, 97, 77,173,128,253,117,140,247,217, 1,222,155,251,228,201,197,114,255,190,101,203, 22, 4,202,217,174, + 93, 59,168,213,106,231,182,126,253,250, 70,142,150,221,110, 71, 68, 68, 68, 32,156,164,193,141, 16, 16, 21, 21, 5,158,231,153, + 69,139, 22, 77, 76,249,127,246,174, 59, 60,138,106,125,191, 51,219,119,147,108, 54, 61, 33, 33,148, 0, 82, 34, 77,225,194,165, +151, 0, 66,104, 34, 69, 46, 4, 17, 81,138,168, 40, 17,129, 31, 42, 32,161, 73,147, 42,200, 37, 32, 72,151, 46, 69,164,131, 5, + 20, 36,129, 64, 8, 9,164,111,234,246, 50,237,247, 71,118,227,102,179, 73, 54, 33,194, 5,231,125,158,121,118,167,189,115,206, +156, 51,103,222,243,157,239,124,211,176, 97,200,244,233,211, 73,129, 64,128,235,215,175, 35, 33, 33, 1,245,235,215,119,219,103, +171,168,168, 40,235,147, 79, 62, 97, 62,249,164,100, 14, 69,100,100, 36,138,138,138,114,237,251, 53, 26, 77,126,159, 62,125,202, +248,109,228,229,229, 61,219,158,240,182,251, 72, 91,105, 24, 76, 38,232,180,134, 82,235, 80,110,102,142,234,227, 15, 63, 16, 45, +155,250, 6, 0,224,195,149,107,160,221,248, 87, 67,118,224,195, 81,129, 67,191,220, 53, 19,192,224,202,248,117, 58, 29, 76, 38, + 19, 34, 34, 34,112,249,242,101,104,181, 90,244,235,215, 15, 4, 65,148,206, 16,173, 6, 44, 25, 25, 25,157,162,163,163,127, 93, +177, 98, 69, 68,243,230,205, 9,189, 94, 15,131,193, 0,199,223,155, 55,111,114, 59,119,238, 76, 49, 24, 12,255,182,153,206, 93, +226, 68,198, 55,201,125, 67,223,220,251,227,117, 65,116, 96,163, 36,101, 70, 97, 4,157,159, 33,213,107,140,119, 76, 12,151, 0, +142, 1, 24,176,224,104, 22,140,109,216,235,105, 65, 46,151,127,117,241,226, 69, 63,147,201,132,107,215,174, 97,204,152, 49,150, +188,188, 60, 9, 0,252,231, 63,255,177,108,223,190, 93,210,168, 81, 35,108,219,182, 45,224,213, 87, 95,221,163,215,235, 95,116, +147,250,219,172,172,172,111,157, 55,250,249,249,173,126,248,240, 97,119, 71,159, 31,154,166, 75,147,227,242,193,100, 1,138,162, + 96, 52,154, 81, 92,172,133,197, 74,217,218, 76, 22, 12, 67,219,126, 89,208,182,118, 84, 34, 22,122,181,125, 49, 88,199,113, 28, + 72,130, 40,186,246,103,118,221,202, 68,187,171, 33, 46, 55,173, 89,206, 96,236,179,204,252,252,252, 32, 18,137,240,237,183,223, +226,198,165, 19,144, 8, 56, 48, 52, 5,154,178,130,161, 44, 16, 9, 4,248,241,250, 3, 68, 53,243,114, 75, 16,250,251,251, 99, + 64,199,142,136,238,216,177,100,122,155, 80, 8, 79,169, 20, 10,177,172,196,146, 5,128, 99, 72,119,131, 8,176,246,116, 6, 5, + 5,225,183,223,126,195,180,105,211,176,120,241, 98,200,229,242,210,217,207,183,111,223,198,238,221,187, 17, 21, 21, 85,237,188, +219, 45,120, 51,103,206, 68,102,102, 38, 86,174, 92,137,151, 94,122, 9, 34,145, 8, 69, 69, 69,248,247,191,255,141,156,156, 28, +183, 56, 29,135,247, 36, 18, 73, 25,235,147, 93, 0, 86,183,140, 28, 57,223, 24, 18,130, 67,151,118,130, 0,129,171, 59, 62, 40, + 35, 10,215,239,186, 80,109,206,185,115,231,150, 73,167, 59,214, 44,119,225,100,117,170,242, 56,130, 32,174,217,141,173, 51,103, +206,156, 69, 16,196,145,153, 51,103,206,138,139,139,187,229, 14,159,171,253, 4, 65, 28,181,137,176, 1, 14,219,174, 85, 75,104, + 41, 20,138,246,158,158,158,184,119,239, 30,250,245,235,103,201,207,207, 79, 18,137, 68, 77,242,242,242,164,185,185,185, 48, 24, + 12,186,249,243,231, 63, 0, 32,239,208,161, 67,163, 31,127,252, 17,143, 30, 61,194,246,237,219, 1,224,128,107,159, 13, 18, 44, +203,150, 86, 10,231,110,155, 64, 32,192,149, 43, 87,112,229, 74, 89,215,175,205,155, 55, 87,249,194,120,245,251,195,184,126,253, + 58, 28,195, 3,216,255, 59,110,147,201,100, 64,229, 51, 60,202,160, 42,199,248,170, 28,224, 93,193, 93,223, 47, 87, 51,115, 42, + 66, 70, 70, 70,133,231, 95,185,114,165,140, 69,171, 42, 78,129, 64, 0,134, 97, 32,151,203, 9,177, 88, 76,136,197,226, 48,187, +200, 18, 8, 4,165, 15,140, 84, 42,133, 84, 42, 45,211, 75,173, 8,153,153,153, 61, 50, 51, 51, 43,220,175, 86,171, 59,169,213, +106, 60,143,176, 82, 20,140, 6, 11,180, 58, 35, 62,143,251,111,201,198,207,241, 51,128,159, 59,189, 51, 13,147,251, 70,245,172, +238, 48,181,253,126, 7, 6, 6,226,220,185,115, 32, 8, 2,123,246,236,129,183,183, 55,250,246,237, 11,165, 82,137,153, 51,103, + 98,248,240,225,213,109,204,138,243,243,243, 59,189,255,254,251,191, 46, 93,186, 52,188,110,221,186,176, 88, 44,176, 90,173,176, + 88, 44, 72, 78, 78,198,206,157, 59, 31, 25, 12,134, 78, 0,138,171, 34, 59,145,241, 77,242,254,243, 31,102,246, 30,249,170,241, +118,206, 15,200,206,206, 7, 77,103,128,101,104, 88,105,166,196,194, 71,211,160,105, 6, 98,177, 64,185,244,139, 15, 78,177,224, + 64,146,132, 5,192, 43, 79,170,140, 84, 42, 85,164, 90,173,198,221,187,119, 17, 19, 19,147,157,159,159,159, 8,160, 23, 0,228, +231,231, 95, 28, 51,102, 76,243,248,248,248,224, 6, 13, 26,192,211,211, 83,169,215,235,171,162,244, 4, 48, 25, 64, 31,148,248, +129,216, 81, 0, 96, 62, 73,146,210,107,215,174,149,155,105,119,254,252,121, 0,248,217,117, 15,200,102,209, 50,153,160,206, 47, +196,132,119,230,252,213, 51, 2, 87, 70, 92,112,224, 48,233, 93,200, 0, 32, 47, 39, 25,111, 76,152, 38,173,170, 67,224,234, 69, + 88, 13, 31,157, 50, 29, 53,123, 29,245,244,244, 44, 25,126, 59,184, 19, 71,191,124, 7, 96,172,224, 40, 35, 96, 53, 0, 86, 29, + 88,139, 1,132, 88, 14, 80, 70,183,132,150,167,167, 39, 60,229,114, 4,170, 84,224, 56, 14, 66,129, 0, 34,145, 16, 44, 5, 16, + 12, 81, 42, 72, 89,247, 2,131,148,118, 42,229,114, 57, 82, 83, 83, 49,121,242,100, 88,173, 86, 12, 25, 50, 4, 22,139, 5, 38, +147, 9, 70,163, 17, 13, 27, 54,132,193, 96,112,139,207, 62, 91,209,211,211, 19, 98,177, 24, 31,124,240, 1, 94,126,249,101,204, +155, 55, 15,177,177,177,104,216,176, 33, 38, 77,154,132,157, 59,119, 34, 50, 50,178, 42, 94,206,177,140,236,247,211, 46,182, 28, +135,248, 0, 84,187,140,156, 57, 9,130, 44, 35,216,236,203,123, 99,123, 85,155,115,209,162, 69, 80,171,213,229, 44, 89,246,255, +161,161,161, 88,183,110, 93, 77, 71,134,236,214,163, 32, 23,251, 6, 56, 91,162, 56,142,107,103,243,157, 50,199,197,197,221,138, +139,139,139, 38, 8,226, 72, 92, 92, 92,116, 69, 22, 45, 87, 60, 46,246,187,253,210, 18, 58,141,141,118,119,220,105,191,209,190, +190,190,130,240,240,112, 82,169, 84,162,168,168, 8, 1, 1, 1,156, 90,173, 30,169, 80, 40, 62,251,238,187,239, 26,233,116, 58, +220,190,125, 27,171, 87,175,254, 25,192,170,202,132,214,177, 0,155,233,216,102,201,114, 92, 31, 56,112, 32, 26, 52,104, 80,198, +154, 37,151,203, 43,173, 60,246,125,118,139,144, 64, 32,192, 11, 47,188, 32, 79, 73, 73, 49,138,197, 98,132,133,133,201,179,179, +179,141, 98,177,184,218, 51, 93,170,114,140,175,202, 1,222,149,240,105,215,174, 93, 25, 11,150,227,175,227,255, 67,135, 14, 85, + 57,116,104,231,108,222,188,121,233,253,242,242,242,178,159, 11, 0,232,215,175, 31, 88,150,133,191,191,191, 91,156,118, 81,107, +115,128,135,201,100, 98,181, 90, 45,121,237,218, 53, 72, 36, 18,120,121,121,149,250,234,200,100,178, 82,107, 38, 15, 87, 13, 2, + 11, 11, 69,193,104, 52, 66,167,211, 1, 0,146,255,220, 87, 86,136,153, 53, 53,230,183, 55,176, 5, 5, 5, 56,113,226, 4,126, +248,225, 7,188,252,242,203, 46, 69,117, 53, 4,151,186,160,160,160,243,140, 25, 51,174, 46, 88,176,160,142,175,175, 47,172, 86, + 43, 30, 62,124,136, 45, 91,182,100, 26, 12,134,206,213,105, 96,192, 1, 20, 69,195,100, 48,163, 88,163,197,103, 95,108,173,176, +234, 1, 64, 65,238, 29, 12, 28, 52, 92,242, 36,203, 41, 51, 51,115,122,231,206,157,191,208,106,181, 69, 6,131, 97, 56,128,101, +142,253,169,252,252,252, 46,131, 6, 13, 90,225,235,235,251, 82,110,110,238, 44, 55, 40,103,166,166,166,206,170, 87,175, 94,153, +141,102,179, 25,245,234,213,123, 33, 55, 55,119,116,215,174, 93,255, 15,128,175,195,110, 47, 0, 39, 1,172,171,168, 46,217,135, + 14,117, 58, 35,148,170, 16,100, 60, 56, 87,101, 66,196, 2, 19, 56,150,173,180, 13,177,119,128, 43, 90,170,152, 25, 87, 46,169, +246, 99,237, 47,236, 87,134,141,197, 43,147, 23, 65, 33, 2, 22,190,209, 9, 13, 85, 0,228,190, 16,119,253, 24,132,202,118,143, + 38, 31,118,139, 60,118,195, 6, 92,183,181,199, 97, 1, 1,152, 49,114, 36, 56, 10,184,156,144,128, 93, 63,253,132,145, 61,122, + 64, 33,147,185,221, 97, 97, 89, 22, 98,177, 24,201,201,201,184,124,249, 50,154, 53,107,134,123,247,238,149, 9, 67,193,113,156, +187,249, 47,205,187, 84, 42,133, 72, 36, 66,118,118, 54,162,163,163, 33, 22,139,177,117,235, 86,156, 59,119, 14, 51,102,204,192, +248,241,227,209,189,123,119, 36, 38, 38,186,197,201,113, 92,185,217,138,206,195,185,213, 45, 35,103, 78,231,247,126, 77,202,221, +206,185, 96,193, 2,151, 19, 42,220,225,116,165, 69, 92,148,221, 53, 71, 49,100,183, 60, 57, 10, 35,231,117, 0, 62,246,109, 51, +103,206,156,229,238,121,142,235,118,139, 88,117,134, 48, 75,133, 86,116,116,116,153,156, 23, 20, 20, 92,189,122,245,106, 11, 15, + 15, 15,220,185,115, 71,162, 84, 42, 91,216, 27,116,146, 36,177,103,207, 30,175,254,253,251,159, 90,182,108, 89, 24,203,178,200, +201,201,193, 71, 31,125,164,163,105,122, 20, 0,186,162, 23,120, 85,150,169,195,135,203, 63,108, 7, 15, 30,116,107, 8,196, 46, +164,132, 66, 33,124,124,124,140, 70,163, 17, 10,133, 2, 62, 62, 62, 70,131,193, 0, 15, 15, 15,251, 88, 49,137,191,102, 42, 84, +101,125,170,202, 49,222,217, 1,190, 74, 36, 36, 36,184,117,156,109,168,213,173, 90,158,154,154, 90, 97, 67,114,238,220, 57,176, +182,134,214, 93, 78, 91, 47,143,179, 11, 63,133, 66, 1, 95, 95, 95, 72,165, 82,200,229,242, 50, 34, 75, 42,149, 86,249,224, 84, + 21,144, 84, 38,147,253,226,225,225,161,178,239, 23,137, 68,208,106,181, 69, 5, 5, 5,237,159,233,161, 67,112,160,173, 52,140, + 70, 19,116, 90, 99,173,243, 91, 44, 22, 72,165, 82,236,220,185, 19,157, 58,117, 66,135, 14, 29,202,137,172, 26,154,231,211, 11, + 10, 10,186,175, 90,181,234,231,229,203,151,251,232,116, 58,252,247,191,255, 45,214,233,116,221, 1,164, 87, 75,108,178, 28, 40, +171, 21, 6,147, 25,122, 93,201, 61,184,127,107,223,255, 90, 81,237,204,206,206,222, 89,201,254,251, 52, 77, 71,219,227,190,185, +129,127,213,171, 87, 15,217,217,217,101, 54,166,165,165,129, 97, 24, 51, 74,226,100,189,233,104, 72,198, 95,209,179, 43,234,197, +151, 88, 71,141,102,232,116, 37, 86, 16,147, 62,175,118,234,169, 77,108, 84,228,147, 85,147, 58, 68, 16, 68,169,211,247,212,169, + 83,113,243,198, 13,244,170,163, 65,195, 96, 47,112,154, 12,136,123,126,138, 63,212,114, 44, 91,113,172,218,220,187, 29, 92, 32, +150,237,222,237,114,223,253,193,131,171,149,247,164,164, 36,200,229,114, 48, 12, 83,238,125, 83,221,252, 59, 10,152, 21, 43, 86, + 96,198,140, 25,216,186,117, 43,110,222,188,137,214,173, 91,163,119,239,222,200,205,205,197,141, 27, 55, 96, 54,155,221, 78,167, +163,223, 92, 82, 74, 2, 78, 95, 62,142,180,244, 7,200,204,126, 84,227,114,119,228,116, 22, 90,251, 79,255,142, 97, 81,109,107, +196,249,217,103,159, 33, 55, 55,183,140, 37,203,177, 93,170,200,162,229,172, 69,156,144,231,228, 11,101, 95,183, 56,137, 30,231, +117,231,227, 1, 32, 23,128,160,138,243,156,215,243,226,226,226,206,218, 45, 97, 54, 94, 65, 85,254, 89,101, 44, 90, 78, 88, 52, +120,240,224, 65,171, 87,175, 14,144,201,100,165, 51,144,102,206,156,137, 25, 51,102, 32, 34, 34, 2,254,254,254,161, 42,149, 10, +249,249,249, 88,188,120, 49, 82, 83, 83, 39,194, 69,160, 61,103,161,213, 37, 69, 11,137,228,175, 14,171,221,178, 5, 0,227,199, +143, 47,103,209,178, 23, 80,101,160, 40, 10,126,126,126, 48, 24, 12, 16, 8, 4, 24, 50,100,136,224,207, 63,255,100,250,246,237, +139,161, 67,135, 10,110,220,184,193, 12, 24, 48, 0, 2,129, 0, 61,123,246,212,236,223,191,255, 67, 0, 95,186, 33,182,106,205, + 49,222, 94,201,220,141,125,228,142,184,172,140,147, 32, 8, 24, 12, 6, 8,133,194, 82, 71,121,119, 56,237, 67,135,142, 15, 32, + 73,146, 80,169, 84,165,141,135,221,162,101, 23, 90, 85,241, 86, 21,144, 84,161, 80, 40,239,220,185,211,200, 62,241, 34, 47, 47, + 15, 61,123,246,188, 91, 80, 80,240,108,155,180, 88,192, 74, 51,208, 25, 77,208, 25, 13,181, 70,107,127, 30, 54,110,220,136,196, +196, 68,152, 76, 38,124,245,213, 87,165,147, 10, 28, 69,214, 99, 8,174,100,185, 92,206,246,235,215, 15, 87,175, 94,133, 84, 42, +165, 80,131,248, 87, 44,199,194, 74,211, 48, 25,141,208, 85, 61,228,246,188,160, 84, 85, 39, 38, 38,194, 98,177, 96,222,188,121, +204,175,191,254,122, 22, 37, 1, 80,237, 22,188,209,221,186,117,155,239,225,225,161, 58,122,244,232,123, 0,182, 86,246,242,166, +104,155,104,175,197,251,232, 56, 34,224,202, 39,171, 38, 97, 86, 28, 95,172, 44,203, 98,226, 91,111,161,119, 29, 13,134,190, 20, + 0,125,214, 93, 40,188, 3, 64,168,234, 99,217,138, 99,184,149,226,182, 43, 38, 7, 0,253,186, 13, 70,171,102,229,195,131,117, +238, 85,210, 39,187,248,227, 47,200,201,203,172,118,222,245,122,125,133,150,171,106, 88,180, 74,159, 57,251,253,107,211,166, 13, +154, 52,105,130,179,103,207,162,109,219,182,184,119,239, 30,238,221,187,135,212,212, 84,220,188,121, 19,133,133,133,213, 46,163, +239, 79,238, 66,161,182, 0, 18,177, 4, 5, 69,121, 72,203,120,128, 32,191,224,199, 46,119, 59,154, 14,248, 12, 0, 80, 39,192, +187, 90, 66,203,145,115,201,146, 37,229,196,251,227,134,236, 33, 8,226,151,202,214,171,123,254,147, 68, 69, 66,235,129, 90,173, +238, 48,114,228,200,153, 0,218,217,182, 21, 3,216,125,234,212,169,193,129,129,129, 61, 58,118,236, 40,148, 72, 36,184,124,249, + 50,246,239,223,191, 21,192,174,202, 46, 36,145, 72,140,245,235,215,151,219, 43,162,253, 65, 84, 42,149,130,197,139, 23, 19,155, + 55,111,174,208,202, 85, 85, 1, 21, 23, 23, 67,175,215,195,219,219, 27, 86,171, 21,253,250,245, 99, 18, 19, 19, 33, 22,139, 49, +104,208, 32, 38, 33, 33,161,180,160, 55,109,218, 20,102, 52, 26,255,253,195, 15, 63,244, 1,208,181, 26,247,202,238, 24,239, 9, + 55, 29,224, 43,234,229,185, 3,119,135,227, 42,226,156, 54,109, 90,141, 56,197, 98, 49,109,143,252, 78,146, 36,172, 86, 43,218, +182,109,139,220,220,220,210,135,198,195,195,163, 84,100,185, 35,180,170, 10, 72, 42, 20, 10, 97,177, 88,208,181,107, 87, 16, 4, +129, 53,107,214, 60, 31,195,145, 44, 75,120,122,250,161, 78,157, 23, 16, 16,104, 2,203,214,238, 87,101, 98, 99, 99,203,136, 41, + 87,145,151,237,247,191, 38,176,115,185, 51, 75,182,178,183,163,125,200, 75,175, 55, 61,115, 69, 24, 24, 24,216, 33, 55, 55,247, +160,211,230, 2, 0,243, 43,233, 88,150, 22,244,163, 71,143,208,183,111, 95, 28, 63,126, 92,112,224,192,129, 94,135, 14, 29, 74, +184,123,247,238,163,182,109,219,214,125,251,237,183,165, 93,187,118, 69, 94, 94, 30, 94,122,233,165,207, 51, 50, 50, 42, 17, 90, +182,251,104, 50, 67,175,175,125,235,168, 43,107,214,227,188, 24,237,117,114,238,220,255, 67,239,144, 34, 12,105,237,141,248, 35, +151, 48,186,141, 28,176, 72,171,205,103, 79,139,111,157, 6,168, 31,217,161,220,126,169,178, 36,150,107,253,200, 14, 32, 31,221, +171,118,222, 29,211,236, 44,170,106, 98,209,115,188,159, 19, 38, 76,192,199, 31,127,140, 62,125,250,224,222,189,123, 56,127,254, + 60,238,221,187,135,105,211,166, 33, 50, 50, 18,173, 91,183,174, 22,231,161,211,123,161,209, 21,131, 36, 72, 20, 20,231,195,100, + 54, 34,118,210,220,199, 46,247,210,151,255,233, 56, 0,192,190, 83,215,107,204, 57,123,246,108,100,103,103,151,177,100, 61,142, + 95,214,179,142,202,162,165, 61, 0, 48,209,121,163,197, 98,241,154, 55,111, 94,148,191,191, 63, 8,130,192,138, 21, 43,224,235, +235,219, 9,192, 45,139,197,146,167,215,235,103, 56,136,144,222,176,197,218,200,201,201,113, 57,111, 95,175,215, 91,163,162,162, + 68, 33, 33, 33,101,102, 27,122,120,120, 84,100,221, 41,229,180,239,163,105, 26,177,177,177, 88,184,112, 33,194,195,195, 49, 96, +192, 0, 68, 71, 71,131, 32, 8,244,235,215, 15, 3, 6,252, 53,148,171, 82,169,196,199,143, 31,239, 70,146,100,130,195, 11,164, + 12,167, 43,216, 29,227, 41,138,114,215, 1,190, 12,167,189,178, 77,155, 54, 13, 11, 23, 46,196,172, 89,149,187,122,108,216,176, + 1, 40,239, 79,245,183,115, 22, 20, 20,148,105,236, 21, 10,197,154,161, 67,135, 10, 31, 61,122, 84, 70, 92, 57, 46, 46, 26,162, + 50,156, 85, 5, 36, 21, 8, 4, 8, 10, 10,194,130, 5, 11,224,231,231,135,224,224, 96, 87,129,252,170, 44,163, 26,224,111,229, +100, 56,246,218,210, 69,255,215,249,191,219, 15,137,164, 18,224,202,249,125,208, 20,150, 29, 78, 50, 91,255,154, 74, 45,105,219, + 11,150,235, 63,186, 85,151,236, 98,250,179,207, 62,195,103,159,125, 86,105,130, 54,110,220,248,216,121,119, 83,108,149,231,100, + 57, 66,225,225, 3,153, 71, 29,180,136,244, 1,203,209,255, 83,101, 84, 1,126,253,229,151, 95, 6,249,249,249, 33, 61, 61, 61, + 64, 36, 18, 13, 42, 99,174, 50, 26, 81,191,126,253, 23,212,106,245,191,171,226,156, 54,109,154,121,206,156, 57,210, 81,163, 70, + 97,232,208,161, 24, 53,106,148, 84, 44, 22, 55,230, 56, 14, 86,171, 21,233,233,233,248,241,199, 31,161, 86,171,111, 87,150, 78, +150,227, 8,185, 66, 5,153, 71, 8, 90,188,168, 2,203,210,181,146,119, 71,171,184,163, 53,171,154, 34,203,101,253, 4,128, 95, +127, 60,136,185, 31,188,136,173, 71,127,198,234, 95,128, 86,170, 92,180, 8, 80,131, 85,223,198, 71,163, 95,198,178, 29,191, 1, + 0,206,159,171,178,140,184,202,234,160,201,104,125,172,188, 59, 90,174, 28,175,227,134,143, 86, 57, 78,123, 39, 81,171,213,162, +168,168, 8,241,241,241,120,227,141, 55,144,155,155,139,212,212, 84,220,189,123, 23,223,125,247, 29, 20, 10, 69,141,202,232,195, +183,102, 99,206,178,233,224,192,161,105,163, 22,152, 57,249, 51,180,107,213,241,177,203,221, 25,110, 88,179, 42,228, 92,185,114, +101, 77,235,210, 63, 78,104,185,132,191,191,255,168,110,221,186,193,100, 50, 33, 32, 32, 0,169,169,169, 32, 73, 50, 2, 40, 25, +194, 11, 13, 13,221,173, 86,171, 35,220,229, 19, 8, 4,160,105,186,212,247,199,190, 0,192,192,129, 3,113,248,240,225, 42,123, + 20,193,193,193,168, 91,183, 46,222,127,255,253,114,179, 28, 28,103, 58,200,229,114, 28, 61,122, 52,187,160,160,160,128,227,184, +106, 77,115,179, 59,198, 95,188,120,209,109, 7,120, 71, 88,173,214, 71,119,239,222, 13,217,184,113,163,160,146,151, 95, 41,206, +159, 63, 79,163,138,161,154,191,131,211, 85,207,148,227,184, 10, 69,150, 59, 97, 4,170, 10, 72, 42, 20, 10,145,148,148,132,185, +115,231,130, 32, 8,236,219,183,239,185,120,184,254,188,147,191,153, 36, 73,159,129,175,116,110, 9,130,128,213, 82,126,164,218, +179, 80, 87, 42,178,134,126,185, 11, 7, 62, 28,233,142,232, 73,190,112,225,130,239,198,141, 27,133,238,148,251,133, 11, 23,104, +142,227,170, 61,236,103,127,225, 88,173, 86, 24,141, 53,179,162,112, 28,119, 57,238,139, 57, 81,219,190, 61, 38, 34, 8, 11,174, +156,219,135,226, 34,215,238, 12, 18,145, 16,155,227,247,211, 98,145,224,209, 83, 46,186,181, 67,134, 12, 25,245,213, 87, 95,181, +112,181,211,141, 73, 48,169, 38,147, 9, 25, 25, 25, 48, 24, 12,123, 63,249,228, 19,235,177, 99,199,222,124,245,213, 87,209,186, +117,107,132,132,132, 32, 43, 43, 11,201,201,201,136,143,143,231, 46, 93,186,180, 23,192,148, 42,238,227,193, 69, 95,204,137,137, +223,113, 76, 66, 18, 86, 92, 57,191, 15,197, 78,162,189,188,117, 90,132,111,182,238,183,138,197,162, 59, 85, 89,139, 28,173, 89, +181,249, 98, 28, 52,102, 50,134,174, 90,141,136,118,125,177,104,113,111,124,243,197,112, 44,239, 39,134,117,207,104,180,122,109, + 27,118,206,235, 15, 0,168,243,141,155,214, 18,161, 24, 15, 93, 88,172,138,138,101, 54,113, 83, 61,171,169, 61,239,149, 89,174, +170,107,209, 34, 73, 18, 13, 26, 52, 64, 68, 68, 4, 58,117,234,132,182,109,219,162, 71,143, 30,184,113,227, 6,110,220,184,129, +105,211,166, 85, 38,178,170, 44,163,238,255,142,194,207, 93,238, 60,118,217, 56,151,123,109,192,157,186, 52,121,242,100, 0,248, + 71, 89,183,170, 45,180, 52, 26,205, 13,150,101, 91,122,123,123,219, 45, 82,165,251,210,210,210,192,178,172,161,186, 5, 99,177, + 88,236,193, 49,203,196,101,178, 59,199, 87,246,224,115, 28,199, 20, 20, 20,160, 91,183,110,232,210,165, 75,233,240,137,227,226, + 32, 76,112,224,192, 1,112, 28, 87,109, 39,107, 7,199,120, 29,170,233, 0, 15, 0,185,185,185,125,187,118,237,122, 74, 40, 20, +186,245, 21, 77,150,101, 83,115,114,114, 94,121,210,156,174,202,135,101,217, 10, 69,150, 59, 13, 81, 85, 1, 73,133, 66, 33, 60, + 60, 60,240,253,247,223,195,223,223,255,185,122,192,110, 36,170,151, 84,182,191,155,159,228, 28,128,128,161, 95,238,122,120, 46, +223, 90,111,232,151,187,210, 14,124, 56, 50,188,178,115,178,179,179,251,140, 28, 57,242,184,187,229, 78,211,244,131,236,236,236, +106,135, 75,224, 56, 14,119,238,220, 97, 39, 76,152,144,167, 86,171,135,215, 36,255, 51,231,174, 94,190,240,243,169,126,253,162, + 58,180, 3, 9, 88, 42,118,254,229, 8,128, 19,138, 4,143,102,204, 90,249,214,240,225,195,159,102,177,105,178,179,179, 59, 13, + 27, 54,108, 10,254,114,157, 40, 35,164, 80,193,236,106, 27, 86,213,173, 91,247, 69,129, 64, 32, 5, 48, 23, 64,218,165, 75,151, +214, 94,186,116,169, 15,128,127, 9, 4,130, 16,134, 97, 50,108,157,158, 93, 0,254,168,186, 30,229,190, 13,142, 13,235,215,251, + 95,125, 65, 16,156,197, 98,174,162,131, 4, 14, 28,199,137,197,162, 59,191,222,200,106, 85, 89, 71,202,225, 11, 28,181, 62,100, + 63,101,202, 20, 76,153, 50,165,180, 62,173, 89,211, 5,123,255,188,136,215, 90,165,195,252,117,103, 16,202,112,183, 59,124, 0, + 48,251,255, 38,212, 90,218, 28,243,238,104,209,114,245, 28, 84,199, 71, 75, 32, 16, 32, 47, 47, 15, 73, 73, 73,200,201,201,129, +193, 96, 64, 98, 98, 34,172, 86, 43, 10, 11, 11,241,226,139, 47,214, 56,157,181, 85, 70, 79,147,243,159, 56,124, 88,109,161,101, +181, 90, 63,109,208,160,129, 72, 38,147,181, 96, 24, 6, 28,199,129, 97, 24,206, 38,106,170, 61, 11, 79, 36, 18,153,154, 52,105, + 66,184,154,157, 96,255,239,225,225, 97,172,196, 90, 18, 87,191,126,253, 79, 8,130, 16, 84,212, 11,177,255,103, 89,150, 17, 10, +133,113, 53,188, 87,143,235, 24,175, 87,171,213, 29,107,185,252,254, 14, 78,231,242,209, 55,107,214,172,244,139,246,206, 49, 81, +108, 31, 91,213, 87, 33,206, 43, 13, 72,170,215,235,179,250,246,237,203, 56,238,119, 12,104,250, 92,131,224,210,250,143,122,179, +222,185,124,107, 61, 0,176,139, 45,112, 92, 90, 37,103, 25,179,179,179,187,253,221, 73, 75, 73, 73,177,252,235, 95,255,250, 86, +171,213, 78, 6, 80, 99,111,254, 89,159,174,153,245, 12,150,140, 6,192,194, 26,158,155,150,159,159,223,211,105,219, 31,118, 65, +101,143,107, 87,109,209,126, 59,175,214, 99,139,209, 52,157, 30, 17, 17, 81, 45,203, 13, 69, 81,233, 85,237,119,142, 17,230,136, + 91,240,198,172,171, 64,201,228,239,124,183, 56, 77, 38, 83, 65,199,142, 29, 69,213,204, 91,174,187,121, 15, 9, 9, 65,157, 58, +117, 74,127,237,112,222, 94, 85, 58,105,154, 78, 15, 11, 11,131,191,191,127,133, 17,223,157,125,178,220,225,172,237, 50,170,140, +179, 78,157,109,181,206, 89,211,116,242,112, 15,189,121, 78,158,147,231,124,102, 57, 5,252,253,228, 57,121, 78,158,243, 9,114, + 62,151,224,189,212,120,240,224, 81, 17, 24,254, 22,240,224,193,131,199,227,129,168, 68,149, 86,103,166, 79, 77,148,237,105,158, +147,231,228, 57,121, 78,158,147,231,228, 57,255,113,156, 85,113,215,246, 76,227,231, 26,188, 89,149,231,228, 57,121, 78,158,147, +231,228, 57,121,206,127, 44,248,161, 67, 30, 60,120,240,224,193,131, 7, 15, 94,104,241,224,193,131, 7, 15, 30, 60,120,240, 66, +139, 7, 15, 30, 60,120,240,224,193,131, 7, 47,180,120,240,224,193,131, 7, 15, 30, 60,120,161,197,131, 7, 15, 30, 60,120,240, +224,193,131, 7, 15, 30, 60,120,240,224,193,131, 71, 9, 8, 0, 56,114,228, 72,233, 7, 1,163,163,163, 9,254,182,240,224,193, +131, 7, 15, 30, 60,158, 36,158,107, 45,226,152, 57, 30, 60,120,240,224,193,131, 7, 15, 94,139,212, 14, 72, 94,108,241,224,193, +131, 7, 15, 30, 60,120,177,197,103,140, 7, 15, 30, 60,120,240,224,193,139,172,103, 10,101, 44, 90,188,224,226,193,131, 7, 15, + 30, 60,120, 60, 77,177,245,140,106, 17,206,182, 56,174,243,224,193,131, 7, 15, 30, 60,120,240,120, 76,129, 85,217, 47, 15, 30, + 60,120,240,224,193,131, 7,143, 90, 18, 92,246,255, 79, 76,104,241, 95, 54,231, 57,121, 78,158,147,231,228, 57,121, 78,158,243, + 31, 11, 33,127, 11,120,240,224,193,131, 7, 15, 30, 60, 30, 27,142, 86, 44,130, 23, 90, 60,120,240,224,193,131, 7, 15, 30,181, + 39,178, 8, 87,235,252,183, 14,121,240,224,193,131, 7, 15, 30, 60,254, 38,240, 22, 45, 30, 60,120,240,224,193,131, 7,143,199, + 3, 1,126,232,144, 7, 15, 30, 60,120,240,224,193,227,111, 21, 91, 46, 55, 86, 52,115,224,116, 53,200,107, 50,251,224, 52,207, +201,115,242,156, 60, 39,207,201,115,242,156,255, 56,206,170,184, 79,227,217, 67, 55, 0,103, 1,116,183,253, 86, 40,188,106, 27, +252,212, 87,158,147,231,228, 57,121, 78,158,147,231,228, 57,159,119, 84, 24,168,148,119,134,231, 81, 21,132,168,124,136,185,170, +253, 60,120,240,224,193,131,199, 63, 77,108, 17,225, 72,218, 0, 0, 32, 0, 73, 68, 65, 84,113,142, 47, 73, 87,104, 12, 96, 22, + 0,111,135,109,191, 0,136,115, 58,110, 7, 0,133,195,186, 30,192, 60, 0,247,170, 76, 13,199,137,109,252, 82,219,194, 2, 48, + 1, 48, 3,208, 18, 4, 65,241,101,246,212,209, 17, 64,180,237,255, 17, 0, 87,170,185,255,185, 66, 72, 72,136,220,199,199,167, +207,245,235,215, 37,137,137,137,184,112,225, 2,183,121,243,102,107, 97, 97,225,201,172,172, 44, 35, 95, 93,158, 11,244, 5, 48, +211,246,127, 17,128, 19,143,201, 71, 40, 20,138,105, 30, 30, 30,253,165, 82,105, 29,154,166, 9,131,193,144,169,215,235, 79,209, + 52,253,165,173,221,171, 46, 6,251,250,250,190,217,180,105,211,198,169,169,169, 25,153,153,153, 59, 0,236, 1, 48,188, 78,157, + 58,163,235,215,175, 31,122,231,206,157,123, 5, 5, 5,223, 0, 56,248, 20,211,201,131,199, 63, 9, 68,101,214, 8, 87,152,203, +113,220,232, 50, 12, 68,121,142,158, 61,123, 14, 58,121,242,164,130,101, 89,216, 23,185, 92, 78, 3, 24, 87,133,200,242,187,124, +249,114,189,201,147, 39, 15,205,204,204,124, 89,171,213,182, 7, 0,133, 66,241,115, 96, 96,224,175,171, 86,173,250,142,227,184, +116,130, 32,180,213,204,168, 80, 36, 18,189,225,227,227,211,159,166,233,182, 28,199, 65, 36, 18, 93, 47, 44, 44, 60, 65, 81,212, + 55, 0,106, 34,222, 36, 66,161,112,138, 84, 42,237, 75,211,116, 75, 0, 16, 10,133, 55,205,102,243, 9,154,166,215, 2,176,212, +128, 83, 38,145, 72,166, 40,149,202, 40,139,197,210, 18, 0, 36, 18,201, 77,141, 70,115,202, 98,177,172,181, 9,206,167, 13, 33, +128,104,142,227, 68, 0, 32, 16, 8, 6,183,111,223,190, 30, 65, 16, 44, 65, 16, 28,199,113,196,207, 63,255,220,134, 97, 24,210, + 86, 63,162, 1,252, 10,128,126, 22,159, 16,127,127,255,133, 44,203,214,169,180,208,100,178,151,175, 95,191,222,116,247,238,221, +204,215, 95,127, 93, 52,126,252,120,207,201,147, 39, 11,215,172, 89,179, 54, 43, 43,235, 61,231,227,253,252,252,150,147, 36,233, +239,206,245, 89,150,205,203,207,207,159,254,180,242, 31, 19, 99, 42, 99,238,142,143,151, 53, 2,144, 94,195,250,253,247,113,154, + 98, 56, 0,136,151,197, 55,138, 49,197, 36,219,255, 63, 46,175, 3,102,174, 59,173,237,202,113,192,148, 40, 47,242,113,133, 86, +104,104,104,124, 76, 76,204,168,150, 45, 91, 10, 57,142, 3, 69, 81, 48,155,205, 77,175, 92,185,210,125,223,190,125, 47,107,181, +218,225,213,164,124,235,227,143, 63, 94, 48,127,254,124,127,145, 72, 68, 80, 20,213,104,247,238,221,109,223,126,251,237,247, 55, +110,220, 88,119,196,136, 17, 94,246,237,115,231,206,109,183,104,209,162,134, 0,190,124, 10,233,228,193,227,159,134,110, 40,235, +163,245, 57,128,207, 42, 19, 90, 30,182,151,103,142,205,146, 5,135,223, 82,156, 57,115,230,144, 80, 40,180, 91,180,218,235,245, +250, 32, 39, 43,152, 43,145, 85,127,204,152, 49, 29,247,238,221,187,112,196,136, 17,217, 10,133,162,201,171,175,190,170, 37, 8, + 66,176,123,247,238, 54, 17, 17, 17,242,129, 3, 7,142,233,217,179,231,135, 28,199, 93, 32, 8, 66,237,102, 38, 91,248,250,250, +238, 95,178,100, 73,189,190,125,251,138,253,253,253,193,113, 28, 50, 51, 51, 67,143, 30, 61,218,239,243,207, 63,255,176,160,160, + 96, 8,128,132,106,220,184,118,114,185,124,239,231,159,127, 30,210,175, 95, 63, 97,112,112, 48, 76, 38, 19, 18, 19, 19,123,159, + 56,113,162,235,198,141, 27,223, 51, 26,141,175,217, 4,134,187,104,239,237,237,189,239,191, 31,127, 28,212,225,141, 55,132,190, +190,190,224, 56, 14,106,181,186,247,197,109,219,186, 79, 90,178,228,189,226,226,226, 97,174,238,247,211,132, 68, 34, 33,183,111, +223,222, 90, 34,145, 0, 0, 44, 22, 11, 34, 35, 35,137,231,229, 9, 33, 8, 34, 44, 51, 51,211, 91, 44, 22,187,220,207, 48, 12, +186,118,237,218, 64, 44, 22,227,203, 47,191,164,242,242,242,218,124,245,213, 87,215,119,238,220,233,191,118,237,218,215, 0,148, + 19, 90, 36, 73,250,167,167,167,187,228,100, 24, 6, 86,171, 21, 52, 77,195, 98,177,160,121,243,230, 79, 53,255,241,241,178, 48, + 0,211, 99, 98, 76, 31,216, 54,125, 9,224, 67, 0, 41,168,225, 55,187,254, 6, 78,199,250,182,220,225,255, 99,167,213, 1,245, + 0,224,216, 13, 19, 0,248, 62,238,125,245,240,240,104,246,250,235,175, 11,213,106, 53, 68, 34, 17,172, 86, 43,178,179,179, 17, + 25, 25, 41,248,246,219,111, 95,168, 46, 95,163, 70,141,198, 47, 90,180, 40,224,216,177, 99,214,237,219,183, 91,162,162,162, 68, +227,199,143, 87,118,237,218,181,121, 88, 88, 24,185,101,203, 22,243,169, 83,167,168, 49, 99,198, 72,226,226,226, 2,142, 30, 61, + 58, 48, 33, 33,225,203, 39,157, 78, 30, 60,254,129, 56,139,191, 66, 60,216,127, 43, 21, 90,112, 16, 87,131, 1, 64, 36, 18,181, + 9, 10, 10,138,167,105, 58,216,102,213,201,206,201,201,249,146,162,168,223,109,199, 30,100, 89,118, 80, 85,150,172, 49, 99,198, +116, 60,126,252,248,178, 43, 87,174, 20,231,231,231, 7, 31, 58,116,200,244,225,135, 31,166, 2, 64, 74, 74, 74,195,129, 3, 7, +134, 78,157, 58, 53,189, 79,159, 62,171,122,244,232,241, 46,199,113,167, 8,130,208, 87, 37,178, 34, 35, 35, 47,159, 63,127,222, + 75,165, 82,149,217, 81,191,126,125,188,251,238,187,226, 65,131, 6, 69,244,234,213,235, 82,114,114,114, 23, 0,127,186, 35,136, + 26, 55,110,124,250,204,153, 51,158, 62, 62, 62, 40, 42, 42, 66,118,118, 54, 12, 6, 3,148, 74, 37, 70,140, 24, 33,238,214,185, + 83,221,169,211,222, 59,157,158,145,209,219, 77,177,213,190, 83,139, 22,167,119,198,197,121, 82, 15, 31, 66, 46,151, 67,167,211, + 1, 0,188,188,188,240,114,131, 6,194,223,182,109, 11, 29, 29, 27,123,250,215,164,164,222, 79, 73,108, 73,109,191,102, 0, 71, + 4, 2,193, 96,137, 68, 66, 14, 30, 60, 24,167, 79,159, 38, 76, 38,147,208,102,221,161, 7, 15, 30, 12,185, 92, 14,139,197,194, +162,100,232,144,126,150,159, 18,137, 68,130,228,228,228, 50,219,180, 90, 45,212,106, 53,242,243,243, 97, 54,155, 81, 84, 84, 4, +150,101, 9,185, 92,174,102, 89, 22, 36, 73, 58, 11,128, 50, 16,139,197, 72, 74, 74, 42,179,141,166,105,232,245,122,152,205,102, + 88,173, 86,104,181, 90,185,151,151, 87, 99,127,127,255,116, 0, 7, 11, 10, 10,190,204,201,201, 73,123,194,217,207,179, 11,162, +248,120,217,125, 0,146,255, 69, 78, 7, 75, 86,168,109,253,143, 90, 74,171, 29, 15,143,252,110, 10,183, 89,199, 30,212, 2, 31, + 11, 0, 23, 46, 92, 64, 78, 78, 14,242,242,242,160, 86,171, 17, 22, 22, 6,142,227,170, 61, 28,151,156,156,188,238,197, 23, 95, + 36,110,221,186,117, 2,192,154,221,187,119,143, 43, 40, 40,152, 57, 99,198, 12,223,165, 75,151, 22,196,198,198, 46, 2,176,117, +247,238,221,239, 52,107,214,172,255,237,219,183, 55, 62,141,116,242,224, 81,219,224, 56,174, 29,128, 0,123,219, 98,107,119,253, + 28,214,111, 16, 4, 97,113, 56,206, 98,107, 27,156,127,237,176,175,171, 9,130,248,213,225, 60, 53, 65, 16,191,214, 52,153, 78, +191, 37,157,110, 0, 56,114,228, 8,103, 95, 92,157, 25, 24, 24, 56,173,103,207,158,203,174, 93,187,214, 60, 43, 43,203, 39, 43, + 43,203,231,218,181,107,205,123,246,236,185, 44, 48, 48,112,154,195,141,112, 62,245,180,195, 62,241,229,203,151,235,237,223,191, +127,209,233,211,167,139,219,180,105, 99, 57,115,230, 12,221,167, 79,159, 92,219, 11,154,238,211,167, 79,238, 79, 63,253,196,116, +232,208, 65,126,252,248,241, 71,151, 46, 93, 90,190,119,239,222, 32,142,227, 4,174, 56,109, 16,169, 84,170,239,207,157, 59, 87, + 78,100, 57,162,110,221,186, 56,114,228,136, 82,165, 82, 29, 4, 32,174, 40,157, 54,200,100, 50,217,190,159,126,250,201,211,203, +203, 11,185,185,185, 16,137, 68, 8, 12, 12, 68,113,113, 49,178,179,178,144,118,247, 46, 72,139, 5, 43,190,152,239, 37,151,203, +247,186,104,236,203,113,122,123,123,239,219,185,112,161,103,254,233,211,248, 99,193, 2, 88,173,214,210, 33, 87,171,213,138, 75, +147, 39, 67,253,227,143,216, 50,119,174,167,183,183,247, 62, 0,178, 42, 56,107, 3,142,156,147, 1, 20,216,150,201, 0,174, 68, + 70, 70, 94, 75, 76, 76, 68,151, 46, 93,176,103,207,158, 86, 51,102,204,152, 60, 99,198,140,201,123,246,236,105,213,165, 75, 23, + 36, 38, 38, 34, 50, 50,242, 26,202,250,103,253,221,233,252,219, 56, 25,134, 41,179,176,236, 95,239,152, 58,117,234,228,238,223, +191, 31, 35, 70,140, 32, 37, 18, 73,214,200,145, 35,165, 23, 47, 94,228,108, 34,211,237,116,154, 76, 38, 24,141, 70,232,245,122, +164,164,164,200,151, 44, 89,210,249,179,207, 62,107,116,250,244,233,208, 89,179,102, 77, 10, 8, 8,184, 30, 20, 20, 84,239, 9, +231,221,234,244,127, 5,128,140,106, 90,136,254,110, 78,206,118, 62, 98, 76, 49,173, 29, 26,216,234,242, 86,118, 63,179,109,105, +213, 3, 72,123,156,186,212,179,103,207, 23, 27, 53,106, 20,180,251,150, 15, 10,197, 77,193,138, 85, 96,197, 42, 48,126,237,144, + 44,121, 5,225,225,225, 65,158,158,158, 29,171,153,206,237,183,110,221,250,151,173,167,156, 15, 96, 89,108,108,236,231, 4, 65, + 92,136,141,141,157, 15, 96,153,109,251,130,219,183,111,119, 0,176,243, 41,165,243,153,120,222,121,206,255, 45,206, 42,180, 72, + 0, 65, 16, 71, 8,130, 56,242,201, 39,159,244, 0,224,231,180,254,111,199,227, 0, 72, 92,253,218, 23,135,237, 1, 28,199, 13, +112, 56, 47,160,134,201, 39, 92, 44,127, 9, 45, 0,136,142,142, 38,162,163,163,237, 59,126, 33, 8,226, 16,128, 95, 68, 34, 81, +155,214,173, 91, 15,254,225,135, 31,188, 2, 2,254,186,126, 64, 64, 0,246,238,221,235,213,162, 69,139,193, 34,145,168, 13,128, + 95,148, 74,229,161, 74,172, 48,170,201,147, 39, 15, 29, 59,118,172,166, 77,155, 54, 0, 80,148,144,144,160,232,208,161,131,158, +166,105,130,166,105,162, 67,135, 14,250,132,132, 4, 5, 69, 81,218,118,237,218,121,244,234,213, 43,117,250,244,233, 99, 92, 8, + 14, 71,188,190,120,241,226, 48, 31, 31,159,202,148, 48,180, 90, 45,130,130,130, 48,121,242,228, 96,145, 72,244,102,101,119, 75, + 40, 20, 78, 89,188,120,113,160, 74,165, 66, 97, 97, 33,194,194,194, 96,177, 88,144,148,148, 4,147, 94, 7, 74,171, 1,165, 41, +130,250,254, 61,168, 68, 66,140, 25, 20, 29, 36, 20, 10,167, 84, 97, 45,153,242, 77,108,108,144, 37, 53, 21, 41,123,246,128,161, +203, 27,127,104,171, 21, 55, 55,109,130, 41, 61, 29,139, 38, 76, 8,146, 72, 36, 83,158,176, 37,107, 41,199,113,114,142,227,228, + 4, 65,172,234,216,177,227,183,114,185,124,114, 92, 92, 92,223,147, 39, 79,246, 59,127,254,124,119,154,166, 69, 52, 77,139, 46, + 92,184,208,197,100, 50, 9,165, 82, 41,132, 66, 33,135,231, 20, 34,145, 8, 98,177, 24,114,185, 28,157, 59,119,190,191,121,243, +102, 42, 44, 44, 76,180,111,223, 62,159, 58,117,234,120,172, 89,179,166, 72,171,213, 46,118,151,207,106,181,194,108, 54,195,104, + 52,194,100, 50,225,204,153, 51, 13,166, 78,157, 42, 52,153, 76,204,192,129, 3, 11, 40,138, 50,199,198,198, 42,125,125,125, 63, +124,146,249,140,137, 49,177, 54,203,211,109,155,104,121,128,199,244,121,250, 59, 56, 1, 88,108, 62, 89,118,248,219,184, 45,181, +116, 43,104, 0, 58,155,208, 50, 59, 61, 31, 45, 29, 44,190, 85,162,168,168,104,227, 55,223,124, 19, 70, 74, 85,184,104,233,143, +239,216,207,113,210,123, 13,114,235,125,132,192,176, 70, 24, 53,106, 84, 32,199,113,107,106, 33,205, 95, 1,232, 10, 96, 85, 77, + 78,126, 2,233,172,231,225,225,177,199,203,203,235,162,135,135,199, 30,216,134,103, 31, 7, 81,141,208,123, 80, 51, 50, 61, 42, + 2,220,160,102,100,122, 84, 35, 62,212,192,243, 2, 39, 45,226, 8, 53,199,113,209, 28,199, 69, 47, 90,180,104,161,195,251,221, +190, 46,119,211, 50, 22,205,113, 92,116, 25,133, 84, 34,176, 30,219,232,230, 98, 41,209, 20,142, 74,210, 33,115,165,179, 11,131, +130,130,226,227,227,227,189,156, 25,179,178,178,160,209,104, 48,103,206, 28,175,177, 99,199,190,151,158,158, 30, 83, 69, 34, 36, +217,217,217,109, 71,143, 30, 45,179, 90,173,133, 44,203,146, 26,141, 70,232,237,237,205,216, 15,240,246,246,102,138,139,139, 69, +122,189, 94,192, 48,140,121,236,216,177,146, 9, 19, 38,188, 12, 64, 80, 17,105, 64, 64, 64, 84,255,254,253, 43, 28, 58,160, 40, + 10,122,189, 30,122,189, 30, 86,171, 21,157, 59,119,150,110,222,188,185, 79,110,110,238,250, 10, 21,135, 84, 26, 21, 21, 21, 37, + 42, 40, 40,128,183,183, 55,210,210,210,240,224,193, 3,152,117, 58, 88,117, 26, 88,117, 90,208, 90, 13, 56, 77, 49,242,239,221, + 65,135,102, 77,197, 59,164,210,190,122,189,126,121, 69,156, 74,165, 50,170,195,184,113, 66, 15, 15, 15,116, 31, 93, 50,207,224, +120,179,102,224, 24, 6, 44,195,128,161,105,244, 77, 74, 2, 69, 81, 32, 73, 18,237, 10, 10,132,202,109,219,162,212,106,245,178, +167, 81,217,165, 82,169,112,251,246,237,175, 75, 36, 18,112, 28, 71, 88, 44, 22,156, 60,121,242, 31,247,208, 75, 36, 18,200,100, + 50, 88,173, 86,212,175, 95,223, 56,122,244,232,203, 95,124,241, 69, 56, 73,146, 30, 98,177,248,135,252,252,252,133, 89, 89, 89, + 41,238,242, 81, 20, 5,139,197, 2,139,197, 2,163,209,136,251,247,239, 7, 55,104,208,128,152, 60,121, 50, 99, 48, 24, 26,174, + 94,189, 58,249,228,201,147,138,197,139, 23,191, 10,224,221, 39,157,223,152, 24, 83, 51, 0,205,226,227,101, 98,155,229,215,242, + 63,198,201,161,196,241, 29,241,178,248, 68, 0,234, 90, 20, 89, 18, 0,222,225,126, 66,189, 72, 0, 29, 0, 47,155, 40,120,149, + 32,136, 14,205,155, 55,247, 73, 76, 76, 44,228, 56,238, 42,128,239, 0,100, 85, 70,198,178, 44,193,178, 44,222,110, 95,132,201, + 29, 5,160,168, 98, 20, 23, 23, 35, 45, 45, 13, 9, 9, 9,248,249,231,132,154, 62,155,111,122,122,122,246,145,201,100,245,105, +154, 38,117, 58, 93,154,193, 96, 56,205,178,236, 70,212,192, 71,237,239, 74,167, 29, 30, 30, 30, 75,102,205,154,213,201,219,219, + 27,191,255,254,123,195, 93,187,118, 45,209,235,245,143,229, 92, 47, 19,145, 91,150,175, 92, 19, 26, 26,168,194,141,243,135, 67, + 23,110,216,189, 5, 96,195,120,153,242,236,195, 73,139, 56,138,161, 95, 57,142, 27, 64, 16,196, 17,103,161, 84, 45,179,211, 99, +158, 95,133, 69,203,249,195,210,101,133, 86, 5, 10, 18, 52, 77, 7, 59, 90,178, 56,142, 67, 86, 86, 22, 50, 50, 50,160, 86,171, +225,227,227, 3,171,213, 26,236, 78,251,160,213,106,219,251,249,249, 25, 68, 34,145,217,104, 52, 66,161, 80,176, 34,145,136,179, + 93,135,176,205, 90,100,204,102, 51, 33, 20, 10, 41, 47, 47, 47, 79,179,217,220, 20,149,248,146,113, 28,215,222,207,207,207,229, + 62,179,217, 12,157, 78, 7,189, 94, 15,157, 78, 7,179,217,140,160,160, 32,208, 52,221,182,210, 46, 45, 77,183, 12, 8, 8, 64, +102,102, 38,228,114, 57,210,211,211, 97,209,105, 97,213,106, 65,235, 53, 96,138,139,193,106, 52, 96,245, 26, 80, 22, 3, 66,155, + 52,131,125, 70, 98,133,221,112,139,165,165,159,159, 31,244,250,191,220,205, 56,155,192,162,105, 26,180,205, 57,218, 62,156,232, +239,239, 15,251,140,196, 39, 4, 51,128, 25, 36, 73,174,146, 74,165,194, 73,147, 38, 33, 43, 43,171, 76,157,152, 52,105, 82,169, + 79, 86,215,174, 93, 47,200,100, 50, 90,173, 86,195,108, 54,139,158,215,135,158, 32, 8, 16, 4, 81, 82, 70, 52, 13,127,127,127, +125, 94, 94,222,207, 69, 69, 69,175,215,132,143,162, 40,251,140, 46, 24,141, 70,112, 28,135,223,127,255, 29, 50,153, 76,196, 48, +204, 45,154,166, 21, 34,145, 8,164,205,249,235, 73,193, 54, 35,240, 75, 0, 97, 54, 11,209,155, 40,113, 56,207,112,209,144,184, +117,235,220,228,172,190,112, 51,197,216, 45, 77, 25,168,217,112,164, 43,116,111,170,146, 44,143,235, 16,168,106, 61,208, 67,175, +144, 8,244,108, 90,235,250,255, 93,154,176,107,236,152, 55,189,230,205,155, 87,207,223,223, 95,150,156,156,108,154, 63,127,126, +131,237,219,183, 19, 40, 25,166,171, 16, 15, 31, 62, 60, 48,107,214, 44,223,254,253,251, 55,148, 74,165, 68,113,113, 49,212,106, + 53,114,114,114,240,224,193, 3,238,198,141, 27,247,205,102,243,158,234, 36, 50, 36, 36,100,243,235,175,191, 62,246,165,151, 94, + 18,217, 45,164,122,189,190,205,185,115,231, 6, 29, 63,126,188,139, 94,175,175,118,189,124,244,232,209,158,217,179,103,123,188, +242,202, 43, 77,165, 82, 41, 89, 27,233,116, 4, 73,146, 65,158,158,158, 56,125,250, 52, 84, 42, 21, 72,146, 12,122,220,250,106, +178,178,161,117,130,253, 96,186,180, 28, 77, 3,234,193,100,101, 67,121,137,242,252, 88,180, 42,120,215,183,179, 91,164,170, 16, + 75,198,153, 51,103,206, 34, 8,226,200,204,153, 51,103,185,178,104,217,254, 50,142,199, 57, 28,111,174,109,177, 85,173, 64,147, + 44,203, 34, 35, 35, 3,153,153,153,200,200,200, 64,126,126, 62, 72,146, 4,199,113,238,204, 62,227, 8,130, 96, 79,157, 58,229, +115,249,242,101,125,187,118,237,138,236,254, 47, 52, 77, 19, 20, 69, 17, 54,191, 24, 34, 45, 45, 77,124,241,226, 69,213,237,219, +183,131,108,189, 85,182, 10, 83, 96,185,109,118,129,229,184,152, 76, 38,200,100, 50,247, 84,135,237, 69,248,251,181,107, 37, 34, + 75,167,181, 13, 25, 22,131,209, 20,131,211,107, 33, 97, 40, 72,192,129, 48, 25,220,190,127,142,176,139, 44,171, 77,104, 89, 44, + 22, 80, 20, 5,150,101, 65,211, 79,197,175,124, 93,171, 86,173,218, 30, 56,112, 96,124, 70, 70,249,119,225,144, 33, 67,240,238, +187,239, 98,234,212,169,183, 7, 12, 24,112,227,240,225,195,152, 50,101, 10, 88,150,109, 13,160, 24,192,241,231,237,161, 55,155, +205,165, 22, 40,147,201, 4,171,213, 10, 84,227,179, 10,206,117,211, 94,182, 52, 77,219,185,137, 3, 7,246,227,194,133, 11,100, + 66,194,173,176, 73,147, 38,219, 29,238,159,116, 86,211, 81, 50,115, 79, 98,107, 40, 44, 40,241,127,170, 40,164, 66, 4, 42, 31, +178,227, 42,227,124, 28,180,218,208,106,196, 7, 31,124, 16,133,146, 25,206, 41,143,105,209,122, 69, 66, 18, 95, 79,107,233, 43, +251,176,149,159, 94, 34, 36,116, 73, 95,207,210, 61, 8, 87,234,131,234, 42, 44, 97, 13, 84,117, 22, 46,252, 34,228,246,237, 59, +230, 57,115,230, 36,142, 28, 57, 50,240,195, 15, 63,108,190,111,223,190, 46, 38,147,233, 27, 0, 69, 21, 25, 93, 6, 13, 26,116, + 53, 48, 48,176,193,134, 13, 27,114, 31, 61,122,228, 67, 81,148,135,213,106,101,245,122,253, 3,163,209,120,218,106,181,158, 6, +112,173, 58,137,245,242,242,106, 53,110,220, 56, 81, 81, 81, 17,132, 66, 33,172, 86, 43,114,115,115,209,169, 83, 39,193,161, 67, +135, 90,212,228, 6, 20, 22, 22, 46,255,230,155,111,206,238,220,185,179,143, 82,169,124, 73, 42,149, 6, 3, 96,180, 90,109,142, + 94,175,255,163, 38,233, 44,211,206, 49, 76,206,181,107,215, 34,148, 74, 37, 30, 62,124, 8,134, 97,114, 30,183, 14,200,196,228, +163,155,231, 15,213,109,230,223, 0, 23, 47, 95,133, 76, 76, 62,226, 67,125, 61,247,176,251, 80,193, 81, 64,185, 16, 72,151,227, +226,226,228,139, 22, 45, 66, 92, 92,220, 45, 87, 22, 45,187,224,138,139,139,187,101, 63,206,225,248,243,143,145,198,138, 45, 90, + 21, 41, 72,160,100,118,161, 90,173,246, 81,169, 84,165, 2, 43, 51, 51, 19,153,153,153,144, 72, 36, 72, 75, 75,131, 68, 34,201, +114,167, 19, 34,151,203,127,107,211,166,205, 11, 41, 41, 41,226,249,243,231,215,189,118,237,154,178, 83,167, 78, 47,202,229,114, +134,227, 56,152, 76, 38, 50, 49, 49,209,115,217,178,101,161,237,219,183,183,180,111,223,254,250,238,221,187,141,168, 36,254, 21, + 65, 16,191,100,101,101, 53,172, 95,191,190, 93,180,149, 17, 87,142,130, 11, 40, 25,242, 20, 10,133,215, 43, 75,168, 80, 40,188, +153,148,148,212, 91, 33,147,194,162,213,192,170,211,128,214,106,193,104,139,193, 20, 23, 3,122, 13, 36, 52, 13, 17, 67, 65, 46, +147, 33, 35, 61, 29, 66,161,240,102,101,156, 18,137,228,102, 78, 78, 78,111,149, 74, 85,250, 18,165,104,186,100, 97, 24, 88,104, +186,212,162, 37, 18,137,240,232,209, 35, 72, 36,146,155, 79,186, 38,147, 36,201,216, 67, 56, 84,144, 15, 4, 5, 5,177, 29, 58, +116,192,148, 41, 83,192, 48,140,173, 24,136,238, 0, 46,162,196,191,229,153,132, 43,113,107,119, 90, 55, 26,141,208,233,116, 40, + 44, 44, 20,202,229,242, 23, 66, 67, 67,175, 90, 44,150, 61, 52, 77,111,121,240,224,129,166, 34, 78,155, 48, 43, 21, 93, 44,203, +130,227, 56, 48, 12, 3,138,162, 32, 22,139,217,115,231,206, 99,217,138, 37,136,223,178,157, 27, 52,104, 16,113,232,208, 33,176, + 44,155,254,132,179,111,177,137,150,202, 26, 13,231,144, 10, 31,161,242,144, 10, 21,113, 58,246,254, 28,183, 17, 46,142, 41,135, + 15, 62,248,224, 4, 74,134, 12,243,108, 98,238,113, 56,191, 44,250,238, 11, 25,104, 70,111, 62,183, 83,247,237, 93,141,126,222, +183, 43,127,179, 72, 4,154,151,187, 5,181,108,216,224, 5,129, 74,229, 67,174,223,184, 42,127,199,246,189,201, 15, 31, 62,212, +172, 93,187,182,227, 11, 47,188,224,253,199, 31,127,132, 86, 36,180, 20, 10, 69,227, 55,223,124,115, 92, 97, 97,161, 56, 62, 62, +126,119, 86, 86,214,111, 40, 9, 45,227, 56,131,122, 0,128,173, 54, 33, 26,100,107,231, 46, 2,152, 95, 89,127,141, 32, 8,252, +244,211, 79,229,102, 7,178,143,167,206, 85,141, 26, 53, 26,145,146,146,114, 33, 39, 39,103,152,243, 78,177, 88, 60,175, 73,147, + 38,125,111,221,186,245, 57,128, 99,213, 33, 54, 24, 12,177,123,247,238, 93, 42, 16, 8,234, 48, 12,147,105, 52, 26, 99, 31,219, +162, 69,177, 19,226,214,239,218,100,180, 48,225,114,137,224,161,137, 98,223,226,117,200,243,107,205,178, 65,237, 96,141, 82, 3, + 32,156,214,255,176,189,140, 44, 28,199,217,143, 85, 59, 88,177, 44, 78, 86, 48, 87,251,212,143, 17, 44,157,171,168,141,171,200, +162,245, 9,128,246, 0,126,201,201,201, 89, 53,118,236,216,101, 59,118,236,240,210,104, 52,200,201,201, 65,110,110, 46,132, 66, + 33,148, 74, 37,214,173, 91,103,204,201,201, 89,229,120, 14,202, 71,144, 7, 0,147,191,191,255,111,219,183,111, 15,254,250,235, +175,133, 49, 49, 49,105, 3, 6, 12,104,186,110,221,186, 20,177, 88,204, 49, 12, 67,152,205,102,226,237,183,223,142, 88,177, 98, + 69,170, 64, 32, 80,140, 24, 49,130,240,240,240,248, 5,149,132, 13, 80,171,213,167,190,255,254,251,161,211,167, 79,151, 90, 44, + 22,151,150, 44,251, 54,149, 74,133, 75,151, 46, 89, 10, 11, 11, 79, 86, 97,197, 56,245,195,177,163, 93,255, 51,114,164,152,210, +106, 64,105, 53,160, 53, 26, 48,218, 34, 16, 58, 13, 68, 12, 13,185,152, 69,112,152, 12,180,209, 19, 71,127,253,131, 50,155,205, +149, 6, 54,212,104, 52,167, 46,198,199,119,111, 95,175,158,240,210,180,105,176, 82, 20, 94, 73, 74, 42, 21, 87, 86,171, 21, 7, + 91,182, 4, 67, 16,104, 61,113, 34,238,209, 52,173,209,104, 78,253, 47, 62, 12, 55,110,220,200, 29, 61,122,244, 53,150,101,219, +226, 9,125, 52,243, 73,128,162,168,114,214, 40,134, 97, 74,172,142, 37,150, 3,201,209,163, 71,187, 38, 38, 38,138,255,252,243, + 79, 92,184,112,161,245,142, 29, 59, 62, 9, 15, 15,111,249,240,225,195,236,170,196,155,171,160,191,176,249, 31,238,222,185, 7, +239,188,243, 14,145,157,157,141,239,190,251, 14, 85, 5, 79,253, 59, 16, 19, 99, 98,227,227,101,117,225,228,247,228, 34,164,194, +239,112, 51,164, 66, 69,156,166,152, 18, 43,153, 44,190, 36,216,168, 41,166,100, 56, 80, 22, 95,165,165, 12, 49,166, 24,141,205, + 33, 62,171, 22, 56,245,160, 25,185,229,220, 78,221,128, 99, 15,181, 87,178,140,243, 1,156,128,137,225,238, 93,231,110,188,244, +146,143, 63, 0,152, 77, 76,112,227,198,141,187, 9,133, 66, 9, 0,120,122,122,190,228,231,231,183, 46, 63, 63,191,179,171, 50, +141,142,142,238, 16, 24, 24,216,230,248,241,227,127,100,101,101,221, 2,240,179,243, 65, 17, 17, 17,115,110,223,190,221, 78, 36, + 18, 17, 85,212, 17, 0, 64,183,110,221, 94,144, 74,165,126,199,238,122, 67, 35,110, 4, 78, 80, 12, 8,101, 96, 84,173,144, 38, +110,142,176,176,171,126,133,133,133,173,139,139,139,255,168,102,209,247, 24, 58,116,232,150,248,248,248,176,110,221,186,113,215, +175, 95, 39,157, 71, 17, 34, 34, 34,250, 92,185,114,165,237, 91,111,189,181, 97,215,174, 93,147, 81,118,166,109, 85, 72,179,197, + 27,172, 53,156, 74,198,105,128,169,103,179,153,241, 10,229, 31,128,234,132, 92,120,140,240, 12,143,149,196, 10, 13, 24, 21,108, +111,111,139,137,213,158,162,168,223,111,220,184,113,112,196,136, 17,186,252,252,124,248,249,249,161,126,253,250, 32, 8, 2,235, +214,173, 51, 62,120,240, 96,159, 45,150, 86,251,204,204,204, 65, 54,177,229, 10,218,213,171, 87,239,218,182,109,155,234,218,181, +107, 2,154,166,149, 77,155, 54, 53, 92,190,124,217, 83, 36, 18,113, 98,177,152,189,118,237,154, 34, 34, 34,194, 68, 16,132,244, +199, 31,127,204,191,122,245,106,248,140, 25, 51,190, 65,217,105,226,206,216,185, 96,193,130,140,148,148, 20,152,205,102,104, 52, + 26, 20, 23, 23,151, 46, 69, 69, 69, 40, 46, 46,134, 72, 36, 66,118,118, 54,246,239,223,159,101,139, 18, 95,153,101, 99,237,154, +117,235,213, 89, 15,211,160, 84,200, 65,107,138,192, 20,231, 3,218, 98, 72, 40, 43, 60, 68, 12,234, 54,146, 67,166, 80, 34, 71, +163, 67,252,229, 95,179,109, 81,226, 43, 54, 23, 88, 44,107,223, 93,177, 34,135, 22,139, 81,111,248,112, 88,109, 67,133,142, 66, +139, 33, 8,132,247,234, 5,210,219, 27, 11,247,237,203,177, 69,137,127,162, 96, 89, 86, 96,177, 88, 42,203, 7, 88,150, 77, 79, + 76, 76,220, 5,224, 44, 65, 16, 28, 65, 16, 28, 74,130,181,233,158,229, 7,153,162, 40,204,157, 59, 23, 98,177, 24,115,231,206, +197,167,159,126,138,101,203,150, 97,253,250,245,248,246,219,111,113,244,232,209, 6, 23, 47, 94, 20,159, 63,127,158,139,139,139, +203,139,136,136, 16, 76,156, 56, 81, 37,151,203, 63,168,140, 51, 54, 54, 22, 94, 94, 94,136,141,141,197,146, 37, 75,176,121,243, +102, 28, 60,120, 16,151, 46, 93,130, 64, 32, 96,211,211, 31,193,100, 50,113,171, 87,175,206, 56,120,240,160,113,213,170, 85, 16, + 10,133,196, 83,106, 36, 62,176, 9, 42, 71, 75,144,115, 72,133,124, 0, 43, 81,181,111, 84, 69,156,144,197,199,215,181,137,163, +100, 7, 65,116, 24,192,116, 84, 62,189,218,206, 49, 25, 64,112, 45,112,206,150,143,254,191, 68,213,166, 59,247,175,100, 25,103, + 3,248,193,158, 39,165, 82, 41, 63,112,224,123, 33, 0,236,219,187, 95,148,148,148,228,253,253,247,223,203, 2, 3, 3,241,237, +183,223,202,228,114,121, 96, 5,156,204,193,131, 7,205, 18,137,196,111,194,132, 9,253,218,181,107,247,190,173, 35,218, 11, 64, + 11,148,204, 94,140,186,127,255,126,130,191,191,255,221,147, 39, 79,234,221, 41, 32,173, 86,251,205,214,173, 91,235, 23, 48,190, + 56,166, 31,138,120,118, 41,142,170,182, 32,173,222,167, 80,212,121, 25,175,191,254,122, 29,134, 97, 54, 85,179,220, 95, 31, 50, +100,200,214,248,248,248,176, 9, 19, 38,100, 95,191,126, 61, 7, 64, 60,128,237,142,203,237,219,183,243,198,142, 29,155,181,105, +211,166,144, 17, 35, 70,172, 7, 48,140,127,245,243,224, 81,182, 47,132,170,102, 29,186,120,225,150,254,207,205,205, 93, 93, 88, + 88,120,233,222,189,123,239, 89, 44,150, 16,130, 32, 56,177, 88,156,157,147,147,179,202, 33, 96,169, 43,191,146,222,176,197,218, + 32, 8,130,226, 56, 46,189, 71,143, 30, 31,244,234,213,235,171, 35, 71,142,152,186,119,239,142,189,123,247,250,247,232,209,195, +192,178, 44,119,236,216, 49,255,190,125,251, 26,206,158, 61,171,127,251,237,183,155, 54,105,210,100, 98,108,108,172,154, 32, 8, +214, 21,167,253, 93, 86, 84, 84, 52,164, 95,191,126,151,246,237,219,167, 84,169, 84,160,105, 26, 6,131, 1, 6,131, 1, 28,199, +193,219,219, 27,106,181, 26,243,231,207,215, 20, 23, 23, 15,118, 33,220,156, 57, 77, 38,147,105,216,228,247,167,159, 90,245,249, + 92,175,240, 6, 13,144,127,199, 4,218,100,128,136, 35, 81,247, 5,111,136, 37,114,220, 75,210,226,163, 93, 7,180, 70,147,233, + 53, 23,189,229,114,156,197,197,197,195, 98, 62,253,244,244,134, 25, 51, 60,219, 4, 5, 65, 32, 16,192,108, 54,131, 97, 24,136, + 68, 34, 68,198,196, 64, 28, 16,128, 57,187,118,233, 53, 26,205, 48,148,255, 20,143, 51,103,109,192,145,115,242,141, 27, 55,198, + 54,107,214, 12,147, 38, 77,194,144, 33, 67,202, 28,248,253,247,223, 99,253,250,245, 48,155,205, 99, 1, 92, 7,176, 14, 37, 67, + 29,112, 18, 89,127,119, 58,107,157,147, 97,152,194,164,164, 36,229,210,165, 75, 9,171,213,138,207, 63,255, 28,118,193,105,175, +215, 83,166, 76,169,227,229,229,133,207, 62,251,204,146,151,151,215,115,201,146, 37,103,182,111,223,238,255,205, 55,223,188, 14, + 32,214,153,147,101,217,220,155, 55,111,122,109,216,176,129,164,105, 26,203,151, 47, 47, 55, 60, 57,126,252,120, 88,173, 20, 4, + 2,161,197,100, 50,183,144,203,229,201,126,126,126,114,174,172,115,215,147,188,159,161, 40, 9, 97,224,232,248,110,113,244,207, + 66,197, 33, 21,170,195,169,150,197,199,119, 55,197,196,156,181, 9,162, 68,219, 49,123,237, 38,253,106,112,218, 5, 97, 77, 56, + 79,217,150, 42, 97, 50,153,160, 86,171,145,151,151, 7,149, 74, 5,129, 64, 64, 84,148, 78,179,217,252,231, 71, 31,125,116, 99, +211,166, 77,189,175, 92,185, 50,240,252,249,243, 61, 78,159, 62,109, 74, 75, 75,163, 41,138,226, 66, 66, 66,132,157, 59,119,150, +245,239,223,223, 67, 42,149,146,179,103,207,206,251,226,139, 47,252, 81,214,135,205, 57,239, 2,130, 32,240, 97, 87, 45, 98,123, + 8, 96,177, 88, 81, 84, 84,132,140,140,116, 36, 36, 36,224,202,149, 59,224, 56,142,172, 70,185,251, 1,152,253,221,119,223,133, + 74, 36, 18, 98,215,174, 93,117,118,237,218, 85,165, 37,117,199,142, 29,117,118,239,222, 61,207, 54,122,145,254, 44, 62,239, 60, +231,255, 44,231,179, 12,231,200,240,168, 82,104,217,218,249,246,176,125,148,148,162,168, 95, 92,132,112,248, 4,192, 92, 7, 43, + 88, 85,230, 60, 13,199,113, 23,122,247,238, 61,165, 87,175, 94, 43,250,244,233,147,149,149,149,213,112,249,242,229, 97, 52, 77, + 91, 19, 18, 18,200,228,228,228,180,223,126,251,173, 81,147, 38, 77, 38,222,190,125,251, 28, 65, 16, 86, 55, 50,152,144,156,156, +220,169, 71,143, 30,251, 39, 78,156, 24,222,161, 67, 7,137, 74,165,130, 80, 40, 68, 74, 74, 10,254,248,227, 15,203,238,221,187, +211,139,138,138,170,243, 9,158, 95, 82, 51, 50,162, 70, 76,125,111,223,196, 33, 3,253,255,213,244, 5, 73, 72, 72, 8, 96, 52, +226,206,195,108, 92,189,243,135,117,243,133,171,106,179,217, 60, 12,238,127,130,231,151,223,238,221,235,221,115,198,140,125,243, +254,243,159, 32,100,101, 9, 67, 66, 66, 32,145, 72,240,224,193, 3, 36,179, 44,189,120,227,198, 28,155,200,122,210, 81,225,165, + 0,150,178, 44, 43, 4, 0,185, 92,142,119,223,125, 23,142,159,220, 89,191,126, 61,140, 70, 35, 0, 8, 9,130, 88, 10, 96,203, +179,110,197,178,163,160,160, 96,206, 43,175,188, 18, 39, 20, 10, 43,140,122,235,227,227, 3,173, 86, 11,154,166,153,140,140,140, + 59, 62, 62, 62, 16,137, 68,224, 56,206,229,115,148,159,159, 63,103,216,176, 97, 11, 72,146,172,200,242, 1,165, 82,153,118,230, +204,153,198,111,189,245, 22,249,223,255,254, 55,101,194,132, 9,210, 51,103,206, 48, 28,199,237,127,210,247,160, 75,151,157,192, +134,152,215, 0,188, 6,148,115,120,207,176,109,171, 86, 72,133, 46, 93,118, 98, 3,254,226,116, 28,198,179, 11, 34,155, 21,170, +185, 44, 62,126, 5, 74,252, 44, 42,229,238,178,179, 11, 54,196,160, 86, 57,221,129,163,246,213,235,245, 96, 24,166, 50,107,222, +239,123,247,238, 93,241,219,111,191, 5, 76,153, 50,165,225,127,254,243, 31,101,143, 30, 61, 60, 29, 15, 48, 26,141,236,225,195, +135,245,235,215,175, 47,190,112,225, 66,234,248,241,227, 59, 84,150,206,135, 15, 31, 30, 93,184,112,161,119,255,254,253,155, 0, + 40,245,207, 82,171,213, 72, 75, 75,195,159,127,254,153,102,181, 90, 15, 85, 35, 75,249, 0,230,141, 26, 53,106,233,182,109,219, +234, 76,152, 48, 33,123,247,238,221,127,162, 36, 96,177, 51, 84, 67,134, 12,105,185,109,219,182,144, 9, 19, 38,100,163,196,143, + 44, 29, 60,120,240,176,163, 59,202,251,105, 85, 58, 50,177,213, 98,177,112, 38,147,137, 51, 24, 12,156, 78,167,227,224,250, 43, +240, 7, 51, 51, 51,185,244,244,116,238,225,195,135, 92,106,106, 42, 7,224, 91, 39,197,235,170,193,242,216,177, 99, 71,163,208, +208,208,207, 21, 10,197, 9,129, 64,160, 17, 8, 4, 26,169, 84,250,131,159,159,223,167,139, 23, 47, 14,229, 56, 78, 92,137,138, +174, 8, 66,145, 72,244, 86, 96, 96,224, 65, 95, 95,223,116, 31, 31,159,244,192,192,192,131, 34,145,232, 29, 0,162, 42,148,121, + 69,144, 9,133,194,143, 60, 60, 60, 78, 73,165,210, 92,169, 84,154,235,225,225,113, 74, 40, 20,126,132,202, 3,169, 86,202, 41, +145, 72, 62, 10, 8, 8, 56,165, 84, 42,115,149, 74,101,110, 64, 64,192, 41,137, 68,242, 56,156,143,211, 43,177, 11, 45, 3,103, + 3, 65, 16, 84,235,214,173, 55,180,109,219,118, 93,219,182,109,215,181,106,213,234,107,155, 85,146,179, 89, 91, 12,168, 56,120, +227,223,153,206,167,198, 25, 25, 25,185,125,219,182,109,236,156, 57,115, 52, 77,154, 52, 41,152, 51,103,142,102,219,182,109,108, +100,100,228,246,154,114, 6, 5, 5,213,139,140,140, 44,216,180,105, 19,157,148,148,196,109,218,180,137,142,140,140, 44,112,138, + 12,255, 36,242, 78, 0,136,176, 89,127, 14, 1,216,131, 18,231,247, 80, 0, 68,140, 41,134,179,205, 62, 60, 1,160, 79, 5,101, +239, 46,103,152, 41, 38,134,179,249, 84,157, 4,144,232,176,222, 13,101,253,191,158, 4,167, 75,180,104,209,226, 30,231, 0,139, +197,194,169,213,106, 46, 41, 41,137,187,112,225, 2, 23, 22, 22,118,207, 13, 78, 63, 0,111, 3, 56, 28, 28, 28,124,187, 99,199, +142, 15, 59,117,234,244,176, 94,189,122, 41, 34,145,232, 10, 74, 34,188, 71,218,150,165, 0,154, 84,193,217, 81,165, 82, 45, 12, + 11, 11, 59,212,184,113,227, 75,245,235,215,191,226,235,235,123, 68, 38,147, 45,194, 95,145,177,171, 91,231,123, 12, 29, 58, 52, + 77,167,211, 49, 47,189,244,210,109, 87, 39, 53,107,214,236,162, 78,167, 99, 70,142, 28,153, 14, 32,250,159,240,188,243,156, 79, +133,243, 31,133,198, 54,193,116,208, 97,249,196,197,113,159, 56, 29,179,213,118,110,149, 5,193,113,156,128,227, 56, 15,142,227, +188, 57,142,243,229, 56, 78,197,113,156, 39,199,113,210, 42,204,223,124,197,254,251, 56, 39,219, 4,148,193,246,223, 25, 85,237, +127,174,239,103,104,104,168, 79,187,118,237,166, 30, 56,112,224,163,251,247,239,127,116,224,192,129,143,218,181,107, 55, 53, 52, + 52,212,231,113,210, 25, 20, 20, 84,175,121,243,230, 95, 53,107,214, 44,189,121,243,230, 95, 57,137,172, 39,153,119,137, 77,196, + 52,179, 45, 13,109,219, 8,148,196,194, 90,107, 19, 54, 17, 21,244,212,170,195,105,231, 59, 4,160,175,109, 57,100,219, 22,246, + 20, 56,203,161, 65,131, 6,199, 91,182,108,121,175, 85,171, 86,201,173, 90,181,186,215,162, 69,139,123, 77,155, 54,189, 23, 17, + 17,113,175,110,221,186,247,252,253,253,143,215,160,140,124, 1,132,160,252,103,192,158,118,157,239, 30, 25, 25,121, 85, 38,147, +185,140, 13, 38, 20, 10,231,181,106,213,234, 38, 74,102, 74,242,237, 39,207,201, 11,173,255, 33,240,149,240,217,227,148,162,242, +207,140, 84,181,159,191,159,207, 54,167,203,111,117,217,132, 76, 67,155,192,145,212, 2,167, 35,159,189, 78, 69, 56,136,166,167, +193,201,215, 37,158,147,231,228,133, 86,173, 67,200,223, 2, 30, 78, 48, 63,230,126, 30,207,197,104, 60,126, 0, 0, 32, 0, 73, + 68, 65, 84, 54,170, 19, 19,235,113, 56, 93,241,221,127,202,156, 60,120,240,224, 81, 91,109,103,119, 0,231,236,189,194,138, 84, +105,117,102, 19,212, 68,217,158,230, 57,121, 78,158,147,231,228, 57,121, 78,158,243, 31,199,105,199,138, 10,182,223,113, 90,255, +250, 25, 21, 94, 79, 36, 76, 15,111, 86,229, 57,121, 78,158,147,231,228, 57,121, 78,158,179,166,152,248,140,138,172,110,246, 21, +126,232,144, 7, 15, 30, 60,120,240,224,193,163,246, 80,117, 28,173, 61,123,246, 8,236,255, 71,141, 26, 53,158, 97,152,169,246, +117,129, 64,176,230,187,239,190,219, 82,217, 21,134, 15, 31,206, 84,198,233, 10, 85, 93,199, 21,103,139, 38,202, 73,126,222,138, +247,138,138, 13, 43, 83, 50,153, 11, 38,147,169,185,125,159, 76, 38, 75,220,178,101,203,221,218, 78,231,248,241,227,155, 56, 95, +167,126,152,168,187,175,151,236,221,130, 34,221,242, 91,247,116, 95,243,117,236,169,192, 31, 64,180,151, 76, 60,168,133, 74,220, +241,207,124,211,101,189,149, 57,140,146,217,176,133,207, 99,134,131,131,131,155, 42,149,202, 49, 0, 90, 24, 12,134, 64,133, 66, +145, 11, 32, 65,163,209,108,207,206,206,190,227, 46, 79,183,250, 72, 3, 16,110, 91,125,120, 46, 21,245,220,217, 87, 21,250, 68, +192,196, 1, 82,130,128,245,100,242, 95,206,232,125, 27,193,196,114,229,183,247,105, 4, 11,199, 65, 76, 0,230,147,247, 33,123, +142,138, 74, 9, 32, 10, 37, 33, 28,110,160, 36,252,132,129,127,100,121,240,120,174,224, 60, 84, 88,186, 46,172, 64, 76,116, 21, + 11,137,175, 56,112, 42,128,243, 51,155,205, 34,137, 68, 2,139,197, 2,133, 66,190,246,237, 9,227, 63, 7,137, 34,138,198,187, + 91,182,108,169,241,151,174,171,115, 29, 0, 63, 57,159,239,163,148, 47, 56,123,248, 99,159,174, 3, 22, 47,178, 60,200,139,213, +106,181,164, 84, 42,133,217,108,134,183,183,119,167, 73, 19, 39,190, 68,138, 56,139, 88,236,113,121,197,138, 21,217, 53, 77,231, + 7, 31,124, 16,108,181,154,254,205,178,172,196, 98,177, 72,157,175,227,173,240, 88,124,246,240,199,138,110,209,139, 62, 7,120, +161,245, 20, 32,169,231,227,113,110,229,168,238,205, 58,182,104, 12, 54,225, 60, 76, 22,235,160,179,233,186, 65,159, 94,201,156, +158,174,179,182, 69, 45, 4,172,252, 31,130,160, 97,195,134, 83, 2, 2, 2, 70,110,220,184, 81,220,176, 97, 67,200,100, 50, 24, +141,198,144,251,247,239,135, 76,154, 52,169,155, 92, 46,223,149,146,146,178, 22,238,125, 8, 46,252,236,214,255, 3, 0,116, 26, + 51, 63, 28, 37, 31,139, 54, 56,239,235, 62,110,126, 56,128, 25, 40,251, 97,228, 44,148,132, 80,112,213,234, 72,142,108, 91,134, + 65, 99, 63, 18, 2,152, 84,154,120, 18,248,225,219, 85,232, 55,234,189, 50,219, 9, 14,194,195,219,150, 33,122,236, 71, 21,126, + 71,177,111, 99,130, 98, 89,174, 66, 75, 60, 73, 18,244,137,123,156,171, 15, 12,231,160, 36, 6, 88, 57, 74,148,124,208,217,229, +241, 3,154, 10,114,172, 20,227, 50,224,172, 88, 36,200, 61,122,135, 41,119,110, 76, 27, 80, 20, 83,210,182,138,133, 96, 14,166, +120,159,157, 61,123,182, 48, 58, 58, 26,155, 55,111,238,252,245,215, 95, 79,212,106,181, 63,218,238, 91, 50,255,248,242,224,241, + 92, 11, 46,215, 66, 75, 40,192,134, 67,251,182, 52,202,201,205, 67,204, 91, 31, 98,231,206,157, 40, 44, 44,132,143,143, 15, 36, + 98,177,104,229,210,255, 11, 86, 42, 61,130, 99, 38,198,110, 0,208,180,166,169,169,230,117, 26, 59,159, 79,216, 62,165, 35, 20, +144, 34,137, 68, 66,238,218,181, 11, 69, 69, 69, 80,169, 84,144, 72, 68,228,138, 69,159,200,149, 74, 79,249,155,147,103,118, 70, + 73,252,159, 26,193, 98,209,117, 62,176,115,139, 82,173, 86, 99,220, 59,177,112,190,142, 88, 44,102,236, 47, 22,190,142, 61, 21, +204,222,248,238,216,102, 47,122, 1,214, 91,151, 32, 18, 8,160,240,246, 65,148, 80, 0, 1,129,230, 49, 39, 82,103, 1,248,244, +121,201,108,195,134, 13,167, 12, 31, 62,124,228,130, 5, 11,196, 36, 89, 18,114, 78,175,215,195,104, 52, 34, 52, 52, 20,103,207, +158, 21,207,153, 51,103,228,247,223,127,143,148,148,148,213,213,229,191,117,235, 86,253,240,240,112, 19, 0, 12,108,233,229,188, +175,158,125, 31, 0,120,121,121, 85,201,231,167,242, 48,223,186,117,181,133,253,188, 41,189, 66,153, 10,182,155, 0, 40, 42,227, + 98, 89, 78,120,242,171, 73, 21,238,127,107,193, 14,250,198,158, 11, 77, 27, 54,108,104,116,220,238,233,233, 89,209, 41, 65, 58, +157, 46,220,121,163,253,120, 43,197, 4, 86,116,189, 62,239,174,119, 41,192, 40, 6,194, 29, 59,118, 0, 0,190,252,104,180, 96, +211,207,121, 66,161,176,164,169, 93,186,116, 41,230,205,155, 39, 57,113,226, 68,255,109,219,182,245, 63,120,240,224,202,138,132, + 42, 15, 30, 60,158, 73,145,229,248, 91,177,208, 34, 9,194, 75,233,229,137,215, 94,127, 27,199,143,255,128,174, 93,187,150,238, +107,208,160, 1,134, 15, 27,140,239,182,174, 0, 0,175,199, 73,209,227, 94,167,176, 88,255,105,191,145, 95,205,127,152,173,187, +114,228,200, 17,116,233,210,165,204,249,175,143,120, 13,223,126,179, 20,149, 68,153,119, 11, 4, 71,138,189,148, 30, 24, 21,243, + 14, 92, 93,103,226,184, 33, 71,250, 14, 95,213, 59, 39, 95,191,130,175,103, 79, 30,141,130,253,250,180,108,214, 20,133,251,215, +226,143, 34, 19,142,103,154,240,102,212,191, 16,233, 43, 71, 23,154, 65,176,135,168,103,182,158,122, 46,132, 86,112,112,112,211, +128,128,128, 50, 34, 75,171,213, 66,167,211, 65,163,209, 64,171,213,130, 36, 73,196,198,198,138,207,157, 59, 55, 50, 56, 56,248, +180, 27,195,136, 15,109,150, 44, 64, 32,210,205,157, 59,215, 28, 24, 24,104, 86, 40, 20,156, 80, 44,213,118, 31, 55,223, 11, 0, + 72,161, 88,187,114,229, 74, 75,104,104,168, 73, 40, 20, 74,222,123,239, 61,210,157, 52,155,205,102,206,145,211, 98, 49,151,110, + 95,188,120,177, 37, 40, 40,200,172, 80, 40, 56,171,213,125,163,227,205, 7, 5,144,138, 5,144,138, 5,144, 73, 68,240,170,223, + 14,210,194, 63, 65,211, 52,150, 44, 89, 98, 13, 14, 14,182, 40, 20, 10, 78, 34,145,136,167, 77,155, 86,101, 58,199,143, 31,207, +169, 84, 42,171, 66,161, 16,207,155, 55,175,220, 76,161, 51, 55, 50, 32,151,136,160,144, 10,209,184, 65, 24,164,156,209,237,180, + 10, 4,101,189, 17,164, 82, 41, 58,119,238,140, 22, 45, 90,224,224,193,131,221,121,161,197,131,199,115,129, 10,103, 24, 10, 1, +224,200,145, 35,221, 80,242, 65, 68, 68, 71, 71, 19, 37,103,112,152, 49,101, 24,222, 28, 55, 10, 12,195,150,126,231,139, 32, 9, + 76,126,163, 63, 88,214,157, 17,137,170,167,120,214,224, 58,165,156, 28, 65, 10, 0,160, 81,189, 16,110,226,155,255, 1,195,178, +127, 13,148, 8,128,183,199,245, 43,217, 86, 11,233, 20,128,193,135,147, 94,133,171,235, 52,109, 84,135,164,173, 38, 16,101, 63, +246,248,119,124,108,147,231,116,129, 22,117, 67, 34, 40,163, 17, 38, 19,133,248, 59, 5,198, 83, 25,250, 64, 82,149,170, 94,245, + 90, 7,153, 64,157,137,122, 94,146,198,217,122,234,185,200,187, 82,169, 28,179,113,227,198,114, 34, 43, 39, 39,135,212,233,116, +176, 90,173,172, 86,171, 5,195, 48,152, 57,115,166,104,206,156, 57, 99,178,179,179,231,217, 53,143, 43, 78,155,223,213,140, 91, +183,110,213,155, 61,123,182,181,103,207,158, 15, 27, 52,104,160, 23, 8, 4, 8, 9, 9, 89, 21, 21, 21,229,187, 96,193, 2,107, +255,254,253, 83, 5, 2, 1, 26, 55,110,172,255,243,207, 63,235, 1,144,187,155,119, 71,206, 45,103,214,112, 0, 64, 16, 4,162, +162,162,210, 26, 55,110,172, 23, 8, 4,184,123,120, 49,231,238,253, 20, 9, 73, 52, 9,245,182, 53, 34, 4, 32,247, 44,245,196, +139,138,138, 74,111,218,180,169,142, 36, 73,220,188,121, 51, 12,229, 63,107, 85,142, 83, 46,151, 83,175,191,254,250,195, 59,119, +238,184, 58, 30, 66, 1,137, 14, 77,109, 6,172,208,182, 64,250,197, 10,211, 41, 18,128,158, 51,101,180, 80, 37, 3,164, 94,254, +102,141, 70, 3,165, 82, 89, 98, 33,179, 90,241,251,239,191,163, 99,199,142,221,246,236,217,115,142,127,222,121, 78,158,243, 47, +184,210, 34,207,160, 53,203,241, 67,247,101,124,180,206, 58,103,138, 97,104, 52, 8, 15,194,226,255, 27, 15,134, 97,193, 48, 12, +104,219, 47,195, 48,160,172,214, 90, 73,217,227, 92,199, 71, 41, 95,240,195,174,119,125,122, 14, 89,218, 43,110,246,184, 83, 12, + 3,176, 44, 5,138, 2, 24,150, 2,203, 48,160,168,218,113,205,161, 88, 22,245,194,130, 17, 55,123, 28,156,175,179,253,187, 61, + 3,207, 28,138, 85,116,141, 94,244,225,221, 52,195, 18, 94,216, 63, 89,200,196, 82, 33, 39,148,193, 98,161,161,181,176, 22, 0, +122, 19,197, 90, 57, 15,127, 25, 0, 8, 73,226,121,154, 93,219,162, 97,195,134,101, 68,214,178,101,203,252,215,173, 91, 23, 10, + 0,195,134, 13,203,232,213,171, 87, 94, 82, 82, 18, 66, 66, 66,136,188,188,188, 1, 0,222,179,157, 59, 3,192,186, 10,120,245, +225,225,225,166,128,128, 0,179, 93, 16,145, 36, 9,161, 80,136,240,240,112, 83, 96, 96,160,185,113,227,198,122,177, 88, 12,146, + 36, 97, 23,122,110,117,243, 8, 2, 2,129, 0,118, 78,103,107,143,157,179, 58, 16, 9,201,242,205,155, 3, 39, 73,146, 46,175, + 87, 97, 29,146,201, 56, 0, 21, 30, 47, 32, 29,154, 71, 97,229, 30, 2,241,191, 67, 4,224, 44,199,113,184,126,253, 58, 82, 82, + 82, 32, 22,139, 17, 28, 28,140,121,243,230,193,108, 46,209,187,195,135, 15,239, 6,224, 38,255, 4,243,224, 81,138,179,207,160, +192,114,182,106, 85,238,163,117,228,200,145,110,209,209,209,231,236, 2,168, 68,236,184, 16, 63, 20, 13,138,178, 2, 28, 87, 43, + 66,171,162,235, 48, 12, 91,233,117,236, 62, 90, 44,203, 9, 93,138, 44,150, 5, 77, 81,181,114,247, 88,134, 2,203, 82,112,117, + 29,130, 32, 25, 91,131, 47,230,159,147, 39,143,224,240,122, 36, 21,222, 0, 23,104, 19, 66,253,164, 18,228, 25,209,240,133,102, +130,223, 13, 20, 46,221, 72,132,191,167,242,185, 41, 23,131,193, 16, 40,147,201,160,215,235, 75, 45, 89,235,214,173, 11,181, 88, + 44, 36, 0, 8,133,162, 48, 53, 27, 42, 99, 88,192, 91,153,133,194,194, 98, 63,142,227, 8,155,224, 89, 10, 96, 11, 42,137,238, + 47, 22,139, 75, 5,138,163, 0,146, 74,165, 53, 18, 48,118,216,197,153, 88, 44,118,185,221,121,120,173, 42,136, 29,133, 22,184, + 18,171,150,147,216, 18, 8, 4,176,251, 70, 85, 5,137, 68, 82,154,119, 87, 16, 10, 28,174, 39,168,190, 43,166,213,106,133, 78, +167, 67, 81, 81, 17,100,178, 18,131, 25,199,113, 32, 8,226, 61, 0,239,243, 79, 49, 15, 30,174,181,200, 51, 44,182, 92, 11, 45, +148,152,236, 8, 0,160, 41,171, 75,241,179,231,240, 37, 60,204,214, 35,216,255, 23,112,213,140,122, 58,114,228,200,173, 33, 33, + 33, 29,236,235, 82,185,167,223,196,119, 63, 3, 77, 91,225, 37, 39,241,214,152,126,101, 68, 86,137, 69,203, 82,225, 55, 65, 10, +139,245,159,246, 27,190,122,190,183,210,239,138,179,248,137,139,191,246, 90,161,198, 28, 70,146,191,162,144, 8, 97,134,191,253, +217,120,135,198,253,198,174,245,115,167,187,109, 15, 36, 72,209,107,147, 86, 77,228,132,158,205, 21,164,246,252,199,227,254,117, +192, 81,204,249,250,250, 30,233,243,218,202,222, 57, 5,188,143,214,211,128,151,183,138, 12,123,185, 59, 94,126,239, 43,156,249, +228, 99, 14, 40,132, 95, 72, 40,217, 99,202, 23,240,124,121, 32,174,190, 53,134, 5, 10,158,139,188, 42, 20,138, 92,131,193, 16, + 98, 52, 26,161,209,104,160,209,104,202, 10, 2,145,136,152,248,206, 84,127,145, 88, 2,202,106,193,241,237, 95, 84,201,105, 15, +225, 48,176,165, 23, 4, 34,137, 54,161, 97,195, 85, 66,161, 16, 36, 73,226,240,218,143,223,219,191,252, 93, 47, 0,184,113,100, +173,102, 84,236,154,213, 36, 73,194,108, 54, 75,171,147,238, 71,143, 30,133,153,205,102,147, 77,160,217,133, 31, 30, 60,120, 80, +215,108, 54, 27, 29,183,187, 3,185,194, 11, 80, 53, 0, 20,129,229,172,103,169,169,169,117, 40,138, 50, 8,133, 66, 88, 44, 22, +183, 84, 17, 73,146,226,155, 55,111,134,177, 44,235,242,248, 22, 17,117,128,224,150,128,196,219,237, 60,115,110,116, 68,109, 98, +235,137, 69,144,230,193,227, 89,177,108, 61,131,207, 4, 81,193,255, 82,161,213,253,200,145, 35,156, 99, 15,145,166, 40,155,200, +250, 75,244, 48, 12,139, 76,181, 9, 73, 73,119,177,114,229, 74, 92,186,250,145,247,130, 5, 11,164,115,230,204, 49,143, 28, 57, +114, 57,203,178,173, 72,146,188,129,191,134, 42,202, 90,133, 88,182,238,181,107,215, 26,218,215, 41,138,130,151,151, 23,188,188, +188,208,180,113, 88, 57,145,197, 48, 12,172,149, 12, 29,218,125,180, 8,142,229, 40,138, 1,195,178,165,226,167, 80, 99, 14, 59, +116,250,122, 35,135,195, 95,176,255,233,220,174,121,197, 98,112,210,188,210,124,236, 90, 63,119,250,130,205,155,165,133, 76,192, +180, 81,175,189, 25, 57,124,212, 24,188,254,234, 43,221,204, 22,203, 65, 1,201,177, 84,233,245, 64,130,131,179,143, 22,143, 39, +132,228, 34, 61, 37,146,202,225, 25, 92, 31,119,117,140, 88, 32, 16,252,114,191,200, 32, 38, 5, 66,144, 66, 49, 18, 10, 77,212, +115,148,221,132,228,228,228,144,186,117,235, 66,163,209,128,166,105,118,216,176, 97, 25, 66,161, 40, 76, 40, 18, 17,209,163,166, +178,217,217,153, 20, 73, 10,192,113, 12, 94, 25, 62,137,144,202,228, 98,171,197, 66,163,100,232,208,149, 53,203, 49,132,131, 87, + 84, 84,148,175,125, 38,224,254,229,239,122, 57,236, 83,190,244,210, 75,190,142,179, 14,221,180, 22, 17, 35, 71,142,148,135,135, +135, 19, 0,240,235,246,217,118,235, 25, 49,112,224, 64, 89,120,120,137, 31,254,143,107,223,117,155,211, 95,193, 1,197, 15,128, +226,212,114,150,172,129, 3, 7, 74, 27, 54,108, 88,173,103,209,230, 0, 95, 97,236, 46, 15, 33, 13,100, 95,119,139, 43,166, 13, +168, 80, 79, 8,151,191, 66, 66,226,233,103,238,240,241,137,159,121,177,197,131,135, 91,112,210, 34,207, 20,186,217, 4, 98,119, +219,111,169,224, 18, 2,128,205, 68, 71, 56,232, 44, 80,180,181,156,200, 98, 24, 6, 34,194,140,149, 43, 87,226,253,247,223, 7, + 0,241,244,233,211, 15, 44, 88,176, 96, 40,203,178,173, 56,142,235, 66, 16, 68,101,189,198,179, 33, 33, 33, 57, 28,199,137, 72, +146,236,178,118,237, 90,223,254,253,251,195,203,203, 11, 28,203,149, 19, 89, 12,195,194,106,181, 84,248,153, 91, 31,165,124,193, + 15,123,166,249,244, 28,188,180, 23,195,178,167,236, 34,139,101, 24,128, 45, 57, 41, 63, 55, 3, 39,143, 31,196,134,245, 27, 10, + 65,112,183,193,129,181,137, 65, 84, 32, 6, 91, 93,252, 53,177, 75,231,118,205,177, 96,243,102,233,173,107, 89, 7,166,126, 48, + 43,114,248,168, 49,216,243,221,118,144,116,209,117, 71,145,197, 80, 44,138, 11,243, 6,254,196,251,104, 61, 45,248,158, 60,117, +138, 24, 51,102, 12,171,213,106, 33,150, 72, 88,138,162, 4,255,254,247,191,153,247,223,127,159,204,206,206,134, 70,171, 19, 2, +240,197,115, 96,214,210,104, 52,219, 39, 77,154,212,237,252,249,243, 98,146, 36,161,209,104,208,163, 71,143, 60, 53, 27, 42,155, +248,206, 84,255,204,204, 12, 90, 41, 23,154,197, 98, 17,114,115,115,217,110,253, 71, 27, 71,141,127,191,206,251,179,227, 54,102, + 93, 94,191,206,157,107, 56,206, 4,116,222,183,105,211, 38, 75,104,104,168, 73, 42,149, 74,198,141, 27,231,214,248,161,197, 98, +225, 22, 47, 94,108,118,158, 93,104,177, 88,184,149, 43, 87, 90,194,194,194,204,114,185,156,163,168,170,253, 62, 73,146,160,223, + 90,176,131,166,105,186,140, 21,203, 46,178, 40,150,208,125,245,213, 87,214,176,176, 48,139, 66,161,224,164, 82,169,216,157,116, + 78,157, 58,149,243,241,241,177,122,120,120,136, 99, 99, 99, 31,107,214, 33,197, 64,184, 96,109,105,120, 7,169,151,151, 23,180, + 90,109,105, 90, 67, 66, 66,120,177,197,131,135, 11,148,211, 34,207,166, 21,206,189, 56, 90, 44,160,203,201,205, 11,244, 15,170, + 15,154,166,109, 11, 5,154,162, 48,237,237, 81, 88,190,254, 43, 0,176,139,173,168,233,211,167, 31, 0, 80,101, 99,182,107,215, +174,249,211,167, 79, 87,230,228,228,156,216,186,117,171,239,232,209,163, 49, 99,198, 12, 44, 93,186, 20, 34,137, 12,190, 1,117, + 75,175, 99,191,110,158,186, 0, 28, 56, 93, 5,118, 58,107, 73, 35, 5,161, 95, 64, 61, 80, 12, 5,150,162, 64, 81, 20, 8, 65, + 73,214, 78, 30, 63,136,209,111, 76,133, 72,170,244, 89,179,114,137, 49,242,229,144,161,115, 38, 76, 48,187, 97, 4, 36,111, 93, +203, 58, 48,245,253,216, 40,187,200,218,183,125,253,237, 47,103, 14,222, 41,149, 8, 75,175, 67,177, 44, 72, 82,192,251,104, 61, + 37,145, 37,149, 74,247, 30, 59,118,236, 94,219,182,109, 9,189, 94, 15,138,162,144,151,151,135, 3, 7, 14, 36,112, 28, 7, 31, + 31, 31, 28, 59,118,140, 29, 61,122,244, 94,179,217,252,218,179, 46,182,178,179,179,239,200,229,242, 93,179,102,205, 26, 53,115, +230, 76, 17,203,178, 72, 74, 74, 2, 8,130, 19,137, 37, 32, 73, 18, 34,145, 16,197,197, 26, 86,225,169,202,178,114, 2,133, 72, + 44, 1, 41, 16, 87, 54, 77,248,161, 45, 24, 41, 72,161, 88,107,159, 9, 40, 22,139,113,117,207, 50, 77,247,113,243,149, 0, 32, +150,202, 11,251,244,233,147,214,188,121,115,253,111,191,253, 86, 15,229,103, 29, 58, 63,159,244,144,113,177, 2,133, 92,166,143, +138,138,122,104,231, 76, 61,181, 70, 51,102,242,108,130, 16, 72,244,209,209,209,105,145,145,145,122,129, 64,128,196,131, 75, 52, + 67,198,197,202,136, 74,130,172,158,184,199,189,117, 99,207,133,166, 95,124,241, 5,213,191,127,255, 71,118,127,177,212,212,212, + 58, 3, 6, 12,144,174, 88,177,130, 26, 48, 96, 64,250,139,255,207,222,117,199, 53,113,254,225,231, 46,155,189, 71, 16, 68, 69, + 81, 20,112,139, 11,197, 58,107, 29,173,226,194,189, 71,157,173,179, 14,220, 74,221,168,117,214, 90,220, 84,171,162,214, 81, 23, + 42, 46, 16, 7, 67, 69, 1, 25, 97, 67,128,144,157,187,223, 31, 36, 52, 32, 35, 65, 91,107,127,121, 62,159,124,146,220,189,247, +220,123,251,185,239,251, 29, 94, 94,197, 36, 73, 34, 50, 50,210,185, 58, 75,149, 6, 70, 70, 70,138, 9, 19, 38,188,123,254,252, +121,109,163, 14,171,133,139,139, 11, 40,138, 66,183,110,221, 32,145, 72, 12,150, 45, 3, 12,248,111,162, 98, 30,173,170, 51,195, + 43,148,138,111,167,204, 94,185, 19, 32, 76,181,238, 2,127, 25,150,104, 16,223,127,255,157, 9, 0, 35,141,216,154, 59,119,110, +141,101, 78,180, 68, 86,155,128,128, 0, 44, 94,188, 24,155, 55,111, 86,253,248,227,143,140,248, 87,137,242,177,211, 87, 20, 84, + 88, 15,104,208,197,148,130,250,182, 50,190,124,161,104,133,239, 87, 27, 86,166,101,150,220, 25, 59,109,105,217,221, 75, 5,160, +144,224,171, 0, 96,207, 79, 63,137, 88, 92,115,147, 33,195, 71, 1, 64,207,157,219,130,206,172,193,129,154,197, 22, 77,120,124, + 59,119,129,149, 70,100,237,218,186,246,185, 5,145, 25, 60,243,187, 24,133,246,122, 0,192,218, 12,103,124,191,218,208, 59, 43, + 79,180,221,112,158,253,115,224,112, 56,171,175, 95,191,110,226,237,237, 77,228,230,230, 66,165, 42, 61, 34,114,185, 28, 66,161, + 16, 69, 69, 69,144, 74,165,104,221,186, 53,185, 99,199, 14,147,153, 51,103,174,150,201,100,211, 63,247,237,126,251,246,237,174, +115,231,206,225,214,173, 91,195, 22, 45, 90,196,114,116,116, 36, 44, 44, 50, 9,133, 92, 6,128,166,179,179,179, 41, 99, 83, 75, +129,173,131,243,187,244,140, 44, 15,133, 92, 6, 74, 37,175,210,219, 92,157,222,225,251, 23, 47, 94,212,219,180,105,147, 76, 59, + 18,112,248,130,157, 59, 90,183,110,109, 29, 28, 28, 44,235,215,175, 95,178,198,121, 93, 23,103,248, 43,111, 48,251,197,139,103, +205, 42,114,250, 77,222,116, 80,195,169, 29,141,216,255,187,189, 7, 27, 53,106,100,237,233,233,153, 92, 29,111,131, 6, 13,196, +124, 62, 95,214,164, 73,147, 98, 22,139, 85,106,201, 82, 40, 74, 26, 52,104, 64, 57, 56, 56,200,154, 54,109, 90,172,175,211,190, +145,145, 17,173,177,138, 85, 6,125,162, 14, 89, 12, 40, 3, 2, 2,202, 50,195,127,223,168,145, 96,212,168, 81,252,121,243,230, +225,224,193,131,184,123,247,238,123, 98,191,107,215,174,184,125,251,246, 74,252,135, 18,235, 26, 96,192,255, 25,170,207,163, 85, + 17,135, 14,133,252, 9, 45,159,166,202,176,102,205, 26,174,218,146,213,115,206,156, 57, 16,139,197, 86,149, 52,235, 1,117,174, +141,202, 68, 86, 80, 80,208, 49,154,166,157, 1,116, 86,169,168, 7,251, 15, 28,234, 86,213,250,134, 12, 25,242, 30, 39, 77,144, + 12,146, 36,138, 57, 44,250,201, 79,251, 14, 30, 41,215,190,212,249,189, 49, 8, 60,221,185, 45, 72, 12,160,103, 69,177,133,191, +202,140,148,113,106, 48,117,218,212, 50,145,181,115, 91,208, 85,207, 54,117,191, 89, 58,113,117,165,226,108,245,138, 41, 38, 36, + 73,116,172,224,163,245, 30,231, 71,128,129,243, 47,116, 11, 8, 8,104,238,227,227, 67,106,139, 44,153, 76, 86,150,184, 83,227, + 44,158,150,150,134,174, 93,187,146,205,155, 55,247,122,248,240, 97, 55,252, 85,206,233,115,221,118,213,219,183,111,119, 56, 58, + 58, 94, 91,190,124,249,168,156,156,156,175,242,243, 11,108,194, 14,173, 70,159, 33,211,136,174,125, 71,136,100, 52,147,151, 42, +200,108,114,243,226, 81,235, 75, 39,118, 65, 46,147, 77, 1, 16,135,191,210, 59, 84,228, 44,209,164,113,104,210,164,137, 72, 91, +168,212,173, 91, 87,226,228,228, 36,245,244,244, 44,155, 94, 69, 52,223,123,219,174, 47,167,218,255, 75, 84,211,254,212,136,182, +138,105, 35,140,141,141,161, 17, 95,250,244, 83, 59,218,178,210, 27,101,205, 81,135,101,156,234,244, 14,229,116, 90, 72, 72, 72, +143,144,144,144, 54, 0,158,160,180,214,161, 2, 40, 29, 74,212,114,154, 15, 84,127, 12,215,187,129,243,255,149,243,115, 70, 87, +252,229,155, 5,148,250,106,221,170, 82,104,213, 4,141,227, 59, 0,114,238,220,185,249, 98,177,216,106,212,168, 81,213, 46,147, +145,145,113,240,240,225,195,229, 68,214,160, 65,131,198,133,134,134, 94,203,202,202,170,213, 86, 89,153, 27,173,185,117,126,161, + 85,215,126, 27,230, 0,248,177, 10, 67, 30,229,217,134,255,205,206,109, 65,103, 42,136,173, 95, 1, 12,170, 74,149,246,250,114, + 32,142, 30,218,169,241,237, 50,122,254, 56,237,210,176,168, 85,149, 70, 43, 90,154,114, 87,169,251, 49,207,224,163,245,207,128, +205,102,251, 45, 90,180,136, 45, 18,137,222, 19, 89, 21,133, 86, 97, 97, 33,158, 62,125,138,177, 99,199,114,163,163,163,253,228, +114,249,141,255,194, 62,200,200,200,136, 87, 39, 35,157,173, 73,225,192,229, 25,177, 71,140,159,227, 92, 22,117,120, 98, 23,164, + 18, 49, 0, 48,117, 73,239,192,100, 50,217,209,209,209,174, 26,171,149, 92, 46,231,106,166, 63,126,252,216, 85,147, 91, 75, 34, +145,232, 28,117,248,119,113, 62,123,246,204, 89, 19, 29,169,137, 46,100, 50,153,236,200,200, 72,103, 13,167, 84, 42,213, 41,234, +144,195,225,176,163,163,163,157, 85, 42,213, 71,139, 58,212, 22,198, 40,173,179, 88,174,214,162,218,183,140, 32, 8,130, 54, 12, + 27, 26, 96,192,103,143,138,145,146,213, 23,149,174, 9, 26,199,119, 61, 22, 97,186,184,184,244, 26, 62,124,120, 57,145,229,239, +239,175, 58,125,250,244, 77, 62,159,159, 73,146,100,188,190,253, 40,243,209,194,123,111,144, 32, 73,242,105,231,182, 77, 65,146, +228,211,165, 19, 39, 74,215,224, 64, 57,177,117,246,204,201,222,169,249, 49,149, 75, 51, 0, 54,246,117, 16, 48,238, 91, 4,140, +251,214, 10, 64, 39,160,234,104,197,234,250, 97,192,223, 3,130, 32, 56, 78, 78, 78,207, 37, 18, 9, 8,130,128, 84, 42, 45, 19, + 88, 69, 69, 69, 16, 10,133,101,255,229,114, 57,178,179,179, 81,183,110, 93, 16, 4,241,159,246,163,147,203,229,202, 69, 43, 55, + 29,102, 48,217, 74,138,146, 19,114,185,124,188, 62,215,249,162, 69,139, 72, 84,226,123, 53,115,230,204, 74,167,127, 42,206, 37, + 75,150, 84, 26, 37, 56,115,230,204,106,163, 7,171,194,119,223,125,247,209,162, 14,117,191,125, 25, 96,128, 1,255, 49, 84, 26, +186, 87, 43,161, 69,146,228,211, 74,162, 11, 9, 0, 52, 73,146, 79, 43,201,114,160,124,247,238,221, 74, 75, 75,203, 41, 34,145, +232,143, 65,131, 6,205,245,247,247, 87, 1,165, 14,242,181,221,162,124,161,104,133, 95,255,141,243, 10,138,165,193, 21,231, 85, +180, 60,105,196,214,174,237, 65,187,207,132, 30,247,207, 72, 79,221, 93,213,182, 85, 37,168,170,138, 86, 20, 22,138, 87,250,245, +223, 56, 39,191, 80,108,240,209,250,135,160, 82,169,174, 24, 25, 25, 17,154, 98,202,218,214,171,194,194, 66,148,148,148, 64, 93, +146, 6, 0, 80, 92, 92, 12, 11, 11, 11,168, 84, 42,250, 63,182, 43,164, 0,230,171,173, 85, 0, 48, 63,241,230, 14,237,115,251, +153,246,188,106,172, 89, 2, 93, 10, 68, 87,182, 92,117,243,254, 6,206,204,106, 10, 68, 87,135, 76, 61,249, 50, 1,128,205, 98, +100, 85, 85, 60,154,205, 98,100, 85,227,183,175,231,123, 3, 65, 3, 88,105,184,178, 13, 48,224,243,125,255,255, 84, 43,238, 97, +224, 52,112, 26, 56,255, 17, 78,174,250,163,235, 60,195,254, 52,112, 26, 56, 13,156,255, 54,206,202, 48,249, 51, 17, 90,116, 37, + 31, 0,181,180,104, 25, 96,128, 1,255, 58, 72,107, 57,207, 0, 3, 12, 48,192,128, 15,199,123,197,164,181,103, 84,165, 74,245, +137, 38,168,141,178,189,102,224, 52,112, 26, 56, 13,156, 6, 78, 3,167,129,243,255,142,179, 38,110,237,229, 39, 3,216,247,153, +136,173, 79, 18,208, 98, 48,171, 26, 56, 13,156, 6, 78, 3,167,129,211,192,105,224,172, 45, 12, 67,135, 6, 24, 96,128, 1, 6, + 24, 96,128, 1,255,231,208, 47, 97,169, 1,149,160,238,192,165,160,176, 68,189, 59,131,144,114, 54,240,191,182,137,254,254,254, + 12,125,218, 39, 38, 90,146, 81,224,111, 54, 55, 97,247, 47, 22, 41, 54, 83, 81, 43,130,107, 58, 17,109, 27,180, 26,109,204, 51, +158, 46,147,201,234,155,154,153,101,229,229,102,239,201,123,247,108,151, 86, 27,243, 7, 15, 30,240,125,124,124,210, 1, 20,105, +189, 41, 24, 96,128, 1, 31, 19,150, 77, 93, 64, 16,227, 1,250,175,176, 75,138,142,129, 48,238, 80,185,118, 22, 30,227, 64, 18, +205,180,166,136, 65, 99, 63, 10, 98, 83,106,120,224, 88, 38, 36, 36,184, 54,108,216, 48, 25, 64, 65,197,181, 87, 50,207,112,157, + 27,240, 57,163, 43,202, 39, 44, 45,187, 22, 62, 92,104, 53, 26, 84, 31, 74,114, 12,104,140, 4,129,104, 36,134, 14,174, 21,143, +219, 55,117, 64, 49,219, 1,104, 5,208,173, 76,140,120, 45,197, 50,121, 22, 69,211,163,241,230,228, 19,189,249,234,251, 79, 67, +213,229, 44, 86, 34, 49,244, 39,189,248, 40,250,135, 71,183, 79,115, 45,141, 9, 52,108, 61,104, 1,202,103,112,174, 45, 56, 0, +124, 73,146,108,102,108,108,204, 47, 41, 41,201,166, 40, 42, 5,165,227,211,249,181,228, 36, 1, 76, 48, 53, 49,233,227,106,198, +105,245, 46, 71,152, 86,164, 80,133,163, 52,161,107,254,199, 58,163, 74, 69,150,227,190, 57, 35,124,198, 6,205,234, 1, 75,191, +141, 11, 74,128,234,132, 22,225,220,184,227,217, 97,195,135,248,205,152, 60,214,180,142,157, 41, 4, 57, 34,155,159, 14,134,108, + 10, 9, 57,218,111,226,176,158,125, 0, 96,245,234,213, 95,187,184,184,212, 99, 48, 24,137,203,150, 45,251,117,197,138, 21, 52, + 81,117,165,114,190,250, 28,214,220,240, 77, 0,120, 2,104, 0,224, 45,128, 23, 40,159,101,188, 54,248, 44, 56,235,212,169,227, + 68, 81,212, 68, 7, 7,135,175, 50, 51, 51, 47,144, 36,121, 32, 45, 45, 45,253, 83,222,117,104,154,222, 75, 16,196,100,154,166, +247,233,241, 61, 69,159,117,240,120,188, 76,137, 68, 98,175,254,157, 37,145, 72, 28,254,174,237,249, 39,215,245, 15,189,127, 79, +186,114,231, 69, 31,237, 73,189, 58, 55,171,228,142, 66, 52,187,114, 39,166, 75,249,118,158,170, 42,238,129, 4, 77,211, 88,185, +114, 37,177,106,213,170,113,110,110,110,141, 72,146,124,185,124,249,242,114,169,111, 42,206,211,186,206, 13, 98,203,128,207, 21, +250, 21,149,174, 17, 77,253, 77, 32,161,253, 1, 98,108,215,182, 45, 59, 79, 25,221,159,160, 25, 60,140,152,180, 80,169, 55,151, +235, 88, 46, 24,226, 53,222,205, 26,207, 29,210,191, 7,217,198,179, 30,248,118, 22, 0,201,194,222,139, 73, 54,193, 65,203,118, + 3,240,169, 69, 47, 87,188,137, 56,102, 47, 40, 80,129, 32, 0,130, 0, 72, 2, 40,150, 80,232,245,245,152, 21, 0,126,210,243, +174, 68, 90, 26, 19,152,123, 76, 2, 0,140,143,112, 80,234,217,217,217,141,155, 61,123,182,137,167,167,167, 37,143,199,227, 72, + 36, 18,135,132,132, 4,187,101,203,150,121,138,197,226,243, 0, 30,233,201, 89,183,161,179,211,201,224,185, 19,218, 53,111,224, + 10,150,172, 24,148, 84,228,242, 42,225,117,135,169,187, 79, 77,138,201,147, 12, 71, 45, 74, 38,228,228,228, 16, 0, 96,107,107, + 75,151, 23, 89,237,199,110,157,215, 11,115,183, 92, 65,137, 68,118,164, 58, 14,235,122, 45, 70,125,243,205, 64,191,181, 63,204, + 52, 77,203,149, 35, 58, 81, 12,107, 83, 54, 86,204,159,198,145, 74, 21, 29,118,255, 26, 50,121,231,134,133,251, 85, 42,213, 23, + 0,218,168, 84,170,199, 0,126, 93,185,114,101, 85, 55,223, 85, 0,150,168, 79,232,163, 12, 6,227,106,183,110,221,234, 79,156, + 56,145,104,221,186, 53, 34, 35, 35, 27, 28, 59,118,172,199,133, 11, 23, 18, 85, 42,213, 51, 0, 47,161, 46,123,162, 3, 88, 0, + 26, 51, 24, 12,239,127, 51, 39,159,207, 55,146,201,100, 99,156,157,157, 39,119,236,216,209,187,127,255,254, 68,227,198,141, 17, + 31, 31,223,250,210,165, 75, 43,194,195,195,159,165,166,166,238,227,112, 56,135, 5, 2,129,248, 31,127,142, 19,196,100, 0, 78, +106,157,188, 82,135,239,116,148,230,146, 18,232,186, 14,137, 68, 98,175, 41, 97, 67, 16,132,253,223,185, 61,122,174, 43,150, 32, + 8,107,117, 91, 84,247, 77,146, 36,148, 74,165, 72,165, 82,185,213,192,217, 88,253, 34,165,179,214, 5, 80, 93, 34,104, 35, 0, +232,213,169, 89, 30, 8,196,148, 89,180,222,127,201,140, 41, 19, 96, 52,154, 93,185, 27, 99, 93,206, 10, 86,241, 45,118,229, 74, + 98,197,138, 21, 8, 12, 12,236, 15,192,151,162,168,112, 15, 15,143, 29,229, 40, 41,170,108,222,138, 21, 43,182, 87,115,157, 27, + 96,192,231, 2, 63,232, 83, 84,186,202,247, 31,183,193, 93,160,194, 88, 87, 27,123,255, 89, 19,135, 26,121,122, 52,132, 4,166, + 72,202, 81,225, 98,216, 37, 0, 56,161,159,213,105,104, 27, 38, 83,114, 56, 40,112,126, 19,223,118,158,120,158,166,192,227, 52, + 21, 74, 18, 21, 96,144, 10,168, 40, 26,160, 33,169,237, 86,167,230, 43,113,231,165, 12, 36, 1, 48, 72,128, 36, 9, 48,200, 90, +146, 81,178, 87,171, 15, 69,121,230,100, 82, 0, 37,123,245,129, 7,164,153,187,187,251,168, 85,171, 86, 89,102,100,100,152, 68, + 70, 70,130,203,229,194,202,202,138,193,231,243,157,182,108,217, 34,158, 53,107,214, 87,114,185, 60, 9, 64,142,142,156, 30,125, +219,120,223,219, 23,180,218, 66,241,224, 18, 10,142,255, 6, 6, 73,131,109, 98,138,250, 70, 70,184,244, 77, 67,107,255,176,196, +211, 15, 51, 69, 30, 0,210,106, 34,139,139,139, 99, 72,165,210,225,230,230,230,237, 89, 44,150, 3,207,170, 30,149,206,108,147, +155, 77, 52,120,155,101, 95,210,101, 94, 15,135, 62,155,231,116,195,220, 45, 87,176,237,216,253, 95, 90, 33, 99,121,117,121,179, +141,141, 77,167,204,154, 62,209, 52, 53, 71,142, 53,167,115,112,232,118, 33,198,248,154, 97,238,151, 22, 8, 24, 49,204,228,212, +111,161, 83, 0,236,215, 90, 36,222,195,195,131,136,139,139,171,236,230,107, 5, 96,161, 76, 38, 35,217,108, 54,193,227,241, 70, +173, 93,187, 86, 62, 98,196,136, 84, 77, 3, 95, 95, 95,248,250,250, 18, 69, 69, 69, 13,110,220,184,209, 32, 36, 36, 68, 25, 17, + 17, 17, 11,224,108,213, 22, 11,163,119, 18,137,216,133,103,100, 84,242,211,238,221,155,187,116,233, 66,113,185,127,165,159,170, + 13, 39, 0, 88, 88, 88,236,183,183,183, 39, 22, 47, 94,156,254,177, 56,235,213,171,119,165, 93,187,118,221,122,245,234,197,236, +212,169, 19,156,156,156,202,230,217,218,218,194,215,215,151, 72, 73, 73,105, 30, 30, 30,190,251,202,149, 43, 59,158, 60,121,114, + 35, 41, 41,169,215, 63,108,209,218,167, 22, 19, 2, 61,219,127,246, 32, 8,194,116,239,222,189,246,154,154,140, 10,133, 2, 42, +149,170,236, 91,243,161, 40, 10, 42,149, 10,107,215,174, 85,137, 68, 34, 93,246,145, 72,235,173, 89,243,161, 42,251,230,112, 56, +182,154,132,189, 53,220,217, 99,248,220,130,166, 38, 38, 38,174, 0,250,194,174,209,194,242, 13, 74,223,159, 69, 34, 81,178, 64, +106, 25, 3,160, 75, 53,108,150,171, 86,173, 26, 19, 24, 24, 56, 80,203, 74,235, 61,100,200,144,138,101,175,188,213,223, 34,130, + 32,110,146, 36,121, 30,192, 33,124, 68,171,187, 1,255, 45,208, 52,221, 22,128,157,214, 36, 25, 74, 71,133,160,126, 78, 18, 0, +108, 42, 76,215,110,167,249,206, 86, 79,183, 83, 47, 71,107,241,102, 19, 4,241,168,150, 93,188,133, 42,252,180,152, 0, 16, 22, + 22, 70,247,235,215,143,208,124, 87, 46,138,252, 47, 78, 24, 49,160,207, 87,221, 59,130,228, 89,225, 85, 22, 16,241,142, 6,147, + 84,128, 4,141, 7,119,111,208, 96, 82,135, 43, 44, 85,181,245,164,222,224,239,188, 61, 61, 54, 30, 8,154,205,136,205, 98,226, + 80,120, 9,228,146, 98,100,103,188, 67, 86,122, 50, 4,169,111,145,246,238,237, 51,128, 88,161, 51,231,123, 7, 6, 80, 81,234, +119, 64, 10,168, 38,242,178,102, 78,185, 40,174, 65, 99, 79,207,124,142, 10,144,139,226,116, 88,125, 85,156, 94,141, 26, 53, 26, +241,195, 15, 63, 88,191,120,241,194,168,164,164, 68,122,233,210,165,248,164,164, 36,115, 62,159,159, 55,109,218,180, 70, 78, 78, + 78,230,131, 6, 13,226, 28, 63,126,252,107,148, 15,107,173,138,211,115, 64,251,150, 17, 7,119,108, 53,201, 61, 21, 12, 89,194, + 83, 92, 20,136,112, 55,179,132,110, 96,193, 37,190,109,110, 7, 83, 46, 19,171, 59, 57,153,246, 61,147,176, 81, 65, 81, 1,213, +113,222,187,119,143,111,108,108,188,101,228,200,145,252,153, 51,103,114, 85, 76, 75,102,104, 68,174,197,194,221, 17, 78, 37, 82, + 57, 99, 68,183,122,152, 55,210, 27,243,182, 93,215,136,172,201,245,235, 23, 80, 81, 81, 85,115, 42,228,242,250,206,246,230,136, + 78, 18,227,208,237, 66,252,249,131, 19,186,175, 77,199,160, 86, 76,120,212, 53,133, 82,174,104, 60,100,200,144,195,234,183,246, + 71, 0,190, 30, 50,100, 72, 19, 6,131,113, 29,192,239, 53, 29, 35, 30,175,242,234, 41, 86, 86, 86,232,218,181, 43, 60, 60, 60, +152, 93,186,116,241,174, 32, 96,202,113,202,229, 50, 62, 69,209, 48, 51, 51, 51,178,177,177,177, 50, 51, 51,203,173,236, 65,165, + 15, 39, 0, 88, 91, 91, 15,238,218,181, 43,243,216,177, 99, 57,137,137,137, 15, 70,140, 24,241,214,220,220,188,156,245,215,196, +196, 4,141, 26, 53,194,178,101,203,152,125,250,244,169,145,211,193,193,161,103, 72, 72, 8, 8,130, 40,123,104,191,103, 44,118, +117,133,163,163, 35,250,246,237,203, 28, 60,120,112,207,164,164,164, 90, 93, 71,122,224, 90, 37, 22,173,149, 21,142, 83,149,195, +111,149,181,215,225,184,103,105,172, 75,106, 62,124,192,181, 89,237,112, 39,143,199, 43,179, 66, 85,178,174,247, 56, 73,146,196, +210,165, 75, 65, 16, 4, 88, 44, 22,216,108,118,165,223,126,126,126,250,246, 51,133, 32, 8,146,205,102, 47,100, 50,153, 19,165, + 82,169, 51,143,199, 75, 87,169, 84,191, 72,165,210,181, 0, 20, 52, 77, 91, 86, 33,178, 42,229, 52, 49, 49,113,125,245,234,149, +123, 85, 29,145, 74,165,240,246,246, 6,164,136,173,142, 51, 33, 33,193,213,205,205,173, 49, 0, 77,137,182,219, 52, 77,119,209, +250,175,141,219, 52, 77,127,169,254,253,242,205,155, 55,174, 13, 27, 54,204,255,167,206, 79, 3,231,191,143,179, 6, 45, 98, 71, + 16, 68,152,113, 48, 25,151, 0, 0, 32, 0, 73, 68, 65, 84,214,181,218, 79,243,127,209,162, 69, 75,214,175, 95,255,130, 32,136, + 48,237,233,218,237,180,191,213,247,155, 48,154,166,251, 45, 94,188,216,115,195,134, 13,235, 52,109,255, 14,145,168,143, 69,203, + 60, 91, 98,130,240,119,230, 96, 50, 84, 96,146, 4,152, 12, 0, 52,129,228,164, 4, 20, 21, 22,220, 65,226,233, 68,221, 44, 89, +254,157, 90,180,240, 10, 58,186,109, 1,249,115,120, 9, 10, 68, 18,196, 61,185,137, 71, 55,127,207, 80, 41, 85,191,131,160, 31, + 3,100, 36,222, 82,241, 64,104,237,106, 92, 16, 52,179, 84,104,169,197, 85, 57,177,245,201,208,188, 73,147, 38,195,150, 45, 91, +102, 27, 21, 21,197, 19, 10,133, 69, 71,143, 30, 77,151, 74,165, 73, 0, 46, 39, 39, 39, 55,217,190,125, 59, 39, 40, 40,200,203, +203,203,139,127,242,228, 73, 89, 37,229,140,222,227,156, 63, 54, 32, 98,226,172, 57,188,216,147,187,192,137,141,196,210,167, 57, +170, 63, 5, 37, 63, 0,216,134,148,226, 78,217, 18,229,213,173, 93, 93,200,122,102,108, 52,180,228,248,197,229, 73,170,181,100, + 25, 27, 27,111, 9, 9, 9,113,109,219,182, 45, 9, 0,225, 47,149,220,133,187, 35,156, 46,175,239, 68,116,106,102,131,172, 2, + 41,102,239,138,198,165,136,172, 63, 52, 34,171,166, 78,154,153,153,101,167,102, 21, 58,216,152,242, 48,186,179, 41,186,175, 77, +135,127, 27, 46,184,108, 2,241,137, 25,104,232, 86,143,136,190,115,182,141, 90,100,181, 21, 8, 4, 0,208, 6, 64, 98, 74, 74, + 10,223,199,199, 71,168, 69,151, 15, 96, 35,135,195, 89, 74, 16, 4,221,182,109,219,104, 47, 47,175, 98, 43, 43, 43,136,197, 98, + 72,165, 82,176,217,108,136,197, 98, 36, 39, 39,227,193,131, 7,176,178,178,210,235, 64, 21, 23, 23,195,204,204, 12, 20, 69,125, + 48,167, 74,165, 34,246,236,217, 99,242,226,197, 11,147,208,208, 80,135,185,115,231,230, 54,109,218,244,241,176, 97,195, 94,219, +219,219, 75,159, 62,125,138,123,247,238, 33, 63, 63, 31,237,219,183,215,137, 83, 38,147,129,201,100, 66, 44, 22,131,203,229,130, +201,100, 66,169, 84,130,162,168, 50,241, 85, 92, 92,140,188,188, 60,176,217,108,200,100,178, 79,241, 6,250,158,133,170,186,225, +183,218, 88,180,180,133,154,142, 34,171, 38, 75, 84,149,195,157, 5, 5, 5, 70,150,150,150, 11, 1, 8,106, 90, 23, 65, 16, 96, + 48, 24, 96,179,217, 32, 8, 2, 93,186,116,193,132, 9, 19,208,170, 85, 43, 36, 36, 36,224,248,241,227,120,244,232, 17, 88, 44, + 86, 89,123,157,199, 39,252,252, 24, 60, 30,239,222,128, 1, 3, 60,127,248,225, 7, 94,189,122,245, 16, 27, 27, 91,119,195,134, + 13, 11,175, 93,187, 54, 80, 36, 18,181,209,220,237,170,183,210,171,135, 4, 75,135, 11,251, 74,165, 82,196,198,198,234,179,204, +123,104,216,176, 97, 50, 73,146,175, 41,138, 10, 7,224, 77,211,116, 23,130, 32, 46,161,212, 47, 81, 27, 34,154,166,191, 36, 8, +162, 16,192, 51,146, 36, 95, 82, 20,149,108,176,219, 24,160,195,125,165, 95,197,255, 4, 65,132,173, 95,191,190, 95,101,226,170, +146,107,179,220,244, 13, 27, 54,172,211,250,255, 33, 22,213,174, 40,239, 12,239,167,182,114,253, 37,180,194,194,194,170, 87, 32, + 20, 6,133,157, 62,118,191,187, 28,174,158,173,125,181,172, 67, 52, 34, 31,220, 3, 64,255,162, 83, 87,248,253,140, 72, 6,243, +151, 61,235,102,146,123,111,150, 32, 37, 61, 11,247, 46,254,130,108, 65,210, 33,128,158,139,196,208,194, 15, 62, 18,245, 6,121, +217,219,216, 90, 74,228, 52, 40, 26,192,123, 98,235,147,160, 85,227,198,141, 7, 71, 68, 68,216, 74, 36, 18,222,157, 59,119, 74, + 66, 66, 66, 50,228,114,249, 77, 0,119,213,109,162,178,179,179,135,168,133, 9,131,201,100,114,228,114,121,117,190, 11,173,230, + 79, 28,115,103,227,158,131,188,215,207,163,177, 61,244, 34, 10, 74, 74, 84, 55,179,196, 95, 3,208, 40,250,235, 81, 57,226, 52, + 26,180, 11,139, 36,192, 55, 97, 57,198,229, 73,120, 64,229, 67,178, 82,169,116,196,200,145, 35,249, 26,145, 5, 0, 57, 69, 10, +102,137, 84,193,232,212,204, 6,173,187, 13, 65,228,141, 83, 56,121, 59, 13,110,118,198,183,235,155, 20,232,180, 71,179,179, 4, +123,182, 6,239,221,186,113,229,124,206,188,190, 22,240,111,195, 2,143, 77,192,220,152,133,181, 59,246, 43,162, 30,220,126,202, +231,243,195, 0,124, 45, 16, 8,192,231,243,139, 1,188,100, 48, 24,137, 42,149,170, 50,167,238,229, 0, 28, 14, 31, 62, 76, 42, + 20,138,226,132,132, 4, 56, 58, 58,194,193,193, 1, 22, 22, 22,136,139,139,195,159,127,254,137,248,248,120, 80, 20,133, 22, 45, + 90,232,117,176,114,115,115,241,244,233, 83,244,237,251,213,220,236,236, 44,115, 43,107, 27,209,157,240,219,155,106,195, 73, 81, + 20, 1, 0,158,158,158,240,244,244,228,165,165,165, 57,135,133,133,217,175, 89,179,230,157,171,171,235, 81,177, 88, 92,206,114, +160,171,208,210,136, 11,141, 8,228,241,120, 96,179,217, 40, 44, 44, 68,102,102, 38,138,138, 74,131, 54, 45, 45, 45, 63,137,208, +170,194, 66,245,209,218,255,205,226,240,189,225, 78, 75, 75,203,145, 0, 22,234,184, 45, 80, 42,149, 96,179,217,240,241,241, 65, +112,112, 48, 30, 61,122,132,223,127,255, 29,117,235,214,197,216,177, 99, 65,146, 36, 94,188,120,161,111, 23,169,136,136,136,133, + 95,127,253,181,231,225,195,135,121,201,201,201,136,143,143,135,165,165, 37,130,131,131,185,147, 39, 79,110,120,227,198,141,229, + 40, 13,126,169, 30, 90,209,133, 34, 35,254, 80,111,111,239,247,154, 56, 58, 58, 90, 92,190,124,217,190, 76,128, 85,140, 72,124, + 31, 5,203,151, 47,223,234,225,225,177, 77, 61, 92,232, 11,192,132,166,105,191,208,208, 80, 2, 0,252,253,253,105,130, 32, 52, + 15,164,103,167, 78,157,234, 22, 23, 23, 71, 7, 6, 6, 26,124,180, 12,168, 74,139, 76,214, 92,147, 85, 9, 40,125,132,154,182, +197, 75,131,197,139, 23,123,174, 95,191,254,225, 7,138, 44,237, 55, 38, 90, 35,182,202, 30,166, 85, 14, 25,150,217,190, 72,190, +163,189,141,245,162,177,157, 64, 81,128, 82, 5, 40, 85, 52, 68, 37, 98,196, 62,127, 84, 2, 30, 17,170, 83,119,184,156,160, 53, + 63,204,105, 16,157, 74, 34, 61, 95,142, 91,103,247,210,217,130,164,193, 72, 60, 53,254,227,136,172,161,222,142, 14,246,183,142, +237, 93, 77, 62,122, 43,131,138, 42,213, 89, 20, 69,151,253,254, 4,112,180,179,179, 11,184,127,255,190, 29,151,203,229,189,122, +245,138, 58,117,234, 84,190, 92, 46,191,166, 37,178, 0,160, 83,155, 54,109,148,166,166,166, 16,137, 68,114,185, 92, 46,169, 70, +100, 57,251,181,106,126,123,227,158,131, 60,137, 76, 6,161, 88, 10,134,141,125, 69,145, 5, 0, 29,187,185,215,169, 67,240,204, + 64, 3, 72, 42,148,167, 87, 37,178, 0,128,203,229,246,152, 57,115,102,185,186,120,182,102, 44,165, 49,151,165,186, 27,147, 67, + 69,222, 56,133,240, 23, 57, 20,143,205, 80,217,209,111, 27,232,186, 3, 10, 82, 99,246,252,126, 46,236,234,119,203,130,138, 75, + 68, 69,112,115, 50, 66,113,145, 16,107,215,111, 84, 68, 68,132,223, 92, 56,119,106,135, 83,167, 78,109, 64,169, 51, 56, 0,188, + 60,117,234,212,152,101,203,150,253,138,191,210, 60, 84, 68,122, 64, 64, 64,106,179,102,205,132, 30, 30, 30,194,220,220, 92,196, +196,196, 32, 63, 63, 31,219,183,111, 71,108,108, 44, 52, 22, 65,157,124, 85,222, 23, 72,200,207,207, 51,165,105, 26,249,121,185, + 38, 63,252,240,131, 69,109, 56, 85, 42, 85,185,107,171, 78,157, 58,152, 54,109, 26,187,164,164,196,242,221,187,119,230,218,243, +116,229,148,201,100,208, 88,134,104,154,134, 76, 38,131, 80, 40,132, 76, 38,195,235,215,175,203, 68,150,122,253,159,204,162,165, +249,205,227,241, 50, 53,231,178,102, 8,142,199,227,101, 85,213,254, 67,160,181, 46, 90,253, 91, 95,113, 88,227,246,232,120,220, +193,102,179, 49, 97,194, 4, 60,124,248, 16, 9, 9, 9, 96, 48, 24, 16,137, 68, 40, 41, 41, 65,207,158, 61,193,225,112,244,181, +104,209,108, 54,123,228,146, 37, 75,120,137,137,137,200,201,201,209, 56,211, 67,165, 82, 97,238,220,185, 70, 92, 46,119,164,190, +166,123,129, 64,208,251,245,235,215,141, 43,126, 50, 50, 50,132,218, 62,133,181, 69,104,104, 40,225,239,239, 79,251,251,251,211, + 26,193,101,128, 1,149,161, 10, 45,178,175, 42,139,214,199,176,138,105, 44, 91, 80, 7,136,212, 2, 26,145,213, 85, 75,120, 17, + 26, 11,151,110, 67,135,110, 67, 91, 58,216, 88,223, 56,188,107,149,105,216,115, 2,169, 41, 73,200, 22, 36,163, 77, 7, 63,196, + 62,143, 6,165, 80,157,198,235,208,154, 61, 57,235,249,187,123,120, 52,157,222,181,131, 23,130,194,138,241, 42,242, 50, 10,178, + 5, 59,145,116,234,244, 71, 57, 66,174,254,205, 29,236,173,111,252,186,107,149,229,165, 24, 18, 41, 41, 73, 56,251,235, 86, 90, + 33,151, 22,160,124, 36,151,222,111,205, 70,148,140, 83, 92,144, 9, 89,145, 10, 60,178,132,167,231, 32, 69, 6,128,240,173, 91, +183,118,111,223,190, 61, 39, 32, 32, 32, 35, 63, 63,255, 44,128,251, 90,109,154,185,187,187,247, 13, 14, 14,118, 72, 73, 73,193, +181,107,215, 50, 80, 26,250, 95, 21, 82,111, 71, 63,223,253,231,175,251,231, 27, 53,104,130,237, 75,190, 83,134, 62,138, 25, 0, +224,146, 86, 27,143, 30,222,238, 97,107,190,159, 65, 82, 81,127,224,105,114, 38,222, 10,165,127, 86, 69,152,147,147, 67,148,148, +148,184, 90, 90, 90,106,159,144,224,155,136,164, 11,134,186,167,247, 92,120,199, 73, 34, 87,129,203, 34,233,217, 3, 93,211, 31, +158, 13,181,201,145,228, 16,154,104,196,154, 48,105, 88,143,129,187, 66,206,140, 14, 11,187, 48, 93, 46,149,120, 53,105,210,152, +126, 28,113,227,233,194,185, 83,251,212,242,136,155, 62,124,248,144,100, 48, 24,229, 4,186,182,133, 72, 95, 75,145, 62,208,149, +179,162,208,210, 64,169, 84, 18,181,229,148, 74,165,101, 66,171,226,195,189, 50,193,248,119,108,191, 62, 22, 42,237, 33, 67,141, + 63,157, 68, 34,177, 87,251,108, 57,124, 76,139,214,135, 68, 34, 86, 55,124,169, 79,255, 72,146, 4, 69, 81, 96,179,217,104,209, +162, 5,194,194,194, 96,109,109, 13,115,115,115,152,155,155,195,200,200, 8, 54, 54, 54,101, 66,139, 36,117,142,210,161,165, 82, +105,221,186,117,235,226,245,235,215,224,241,120,101, 31, 46,151, 11, 79, 79, 79,136, 68,162, 58,248,148,182,123, 3, 12,248,123, +239, 43, 97,218, 98,137, 32,136,176, 69,139, 22, 45,169, 45,223,162, 69,139,150, 84,102,225,250, 64,193, 85,206,186,197,212, 86, +144,149, 42, 73,181,200, 58,180,115,165,249,153, 39, 64,106,106, 34,174,158,220, 81,164,144,203,242, 41, 74,225,250, 54, 62, 26, + 32,241,139, 78, 93, 32,233,118, 3,251,118, 35,174,190,144,161,176, 32, 27, 47, 31, 95, 78,130,152,179,248,163,137, 44, 7,219, + 27,135,119,173,180, 60,255,156, 64, 74, 74, 18, 46, 29,219, 94,168,144,203,123, 32, 49,244,241,135, 80,143,100,179, 7,178, 93, +222,245,155,232,155, 14, 21,161,194,200,216,184, 47,179, 50, 48, 80,112,167,250,200, 48,109,100,103,103,159,221,186,117, 43,241, +227,143, 63,118,149, 72, 36,191, 1,208, 54, 81,122,185,185,185, 13,223,183,111,159,117, 74, 74, 10,235,206,157, 59,162, 27, 55, +110,208, 0,206,215, 96,113, 89,208,115,252, 52, 70,171,122,117,102, 70, 37,165, 13, 0,240,135,214,108,207,126,173,155,221, 61, +184,126,185,153,226,110, 40,138, 5, 41, 88,124, 55,181, 16,128,206,251, 91,161, 80, 64, 40, 20, 66, 81,156,171,108,195, 23, 9, + 3,135,216, 75, 51,243, 37, 76, 22, 85,162,244, 48,207,146,222,200,125,203, 48, 54, 54,214,107, 95,238, 90, 63, 63, 4, 64,200, +144, 33, 67, 14, 63,139,184,208,134,207,231, 95,240,240,240, 32, 0,160,138, 8,195,170,176, 10,192,220,142, 29, 59, 18, 62, 62, + 62, 15,182,109,219,118,165, 58,177, 82, 27,139, 86, 77,208,149,147,162, 40,178,138,253, 75,212,150, 83,219,162, 85,147,208,250, +148, 22,173,202, 68,139,182, 72,212, 22, 66,255,134,168,195,234,196,148, 62,253,211,248,201,177,217,108, 68, 71, 71,195,197,197, + 5,114,185, 28,102,102,102, 48, 51, 51,131,169,169, 41,138,138,138,192, 98,177,160,231, 54, 83, 60, 30,239, 93, 76, 76, 76, 99, + 59, 59, 59,168, 84,170,114, 98,235,213,171, 87, 48, 49, 49, 73,211,215,162,197,231,243, 47,171,163, 14,203,193,209,209,209,226, + 99,236, 87,109, 75,150,191,191,191, 97,136,208,128,106,173, 89, 85, 88,181,178, 43, 88,162,100, 90,255,179, 81,154,195,173,159, +250, 55, 42,249, 45,171,100, 90,238,250,245,235,111,104,249,119,101,127,224, 38,104, 82, 60,148,139,112, 97,214,100,201,178,183, +182,186,113, 96,123,160,249,201, 72, 32, 45, 37, 17,183, 78, 7, 11,149, 42,249, 23,160,104, 65,196,181,211,161, 32, 80,130,183, +161,183,116,187, 69,160, 85,171,166,174,248,253,133, 2,217,169,175, 64,211,212, 33,100,133,148,124,240,209,113, 27,212,194,222, +218,246,198,161,224, 64,139, 51,209, 4, 82, 83, 18,113,245,100,112,161, 82, 81,210, 29,137,167, 35,107, 75, 59, 1,176, 98,152, +240,118, 15,246,107, 53,212,213,205, 25, 20,173, 0,197,166, 49,104,129, 45,243,101, 84,201,239,225, 60,225, 73,170,152,154,158, +118, 95, 55, 7,186,226,226,226,223, 1, 60, 70,249,244, 10,205, 27, 53,106, 52,116,247,238,221,118,169,169,169,188,168,168, 40, +241,222,189,123,179, 40,138, 58, 3, 64,151,161,212,239,162,146,210, 14,160,124,190,156,230,243,199, 7, 68, 4,140,155,200, 75, +188, 22, 2,171,196, 88,124,127, 55, 93,245, 50, 95, 54, 66,109, 93,171, 20,182,182,182,116, 78, 78, 78,114, 65, 65, 65, 99, 19, + 19, 19,228,230,230, 34, 47, 47, 15, 66,161, 16,210,194, 60,165,141,170, 64, 68, 40,243,192, 98,177,144,149,162,128, 74,165,202, +208,213,154, 5,192,106,213,170, 85,147, 40,138,210,100, 68, 44, 23, 93,168,213, 78,115, 62, 52, 30, 50,100,200, 97,173,168, 67, +109,103,120, 77,122, 7, 66,157,222,161,253, 31,127,252, 17,215,167, 79,159,212,202,196, 10,151,203,213,219, 81,186,170, 40,198, +218,112, 86,101,209,170, 56, 93, 31, 78,205,240,165,198, 9,190,226,116, 13, 24, 12, 6, 40,138,130, 14, 65, 21,127,171,104,209, +142, 14,172,141,200,169,112,108,170, 77, 28, 90,203, 72,196,143,106,209,210, 28, 11, 54,155,141,115,231,206, 97,220,184,113, 80, +169, 84, 48, 54, 54,134,169,169, 41, 76, 76, 76,112,250,244,105,104,210, 63,232,163, 95, 21, 10,197,145,245,235,215, 47,217,179, +103,143, 17, 77,211,224,112, 56,101, 66, 43, 48, 48, 80, 44,151,203,143,232, 36,180, 52, 25,223, 41, 58,198,196, 68, 89,109,212, + 97,101,203, 84,225,175,101,185,106,213,170, 49, 20, 69, 13, 68,133, 20, 14, 21,218,149, 75,253, 96, 72,239, 96,128, 14,247,147, + 71,255,226,238,105, 4, 22,161,101,201, 42, 19, 92,100,117,226,197,206,202,242,198,254,237,129,230, 71, 31, 17, 72,124,251, 22, + 55,127,219, 81, 42,178,222,156,124,130,228,208, 76, 36,134,118,198,219,208,222, 58,191, 61, 17, 68, 43, 39,123, 75,228,137, 40, + 20,230,188, 3,104, 68,125, 12,145,101,103,101,119,227,231,224, 64,139, 83, 79, 72, 36, 38, 38,226,234,201, 29, 66,165, 82,242, +197,135,136,172,145,108,246,192, 70,238,206, 9, 75, 39, 13, 28,234,211,208, 17, 54,239,226,112,126,236, 80,172, 62,254, 13,204, +236, 24,104,215,215, 12, 19,214, 58, 14,229,123,114, 95,243, 59, 99,160, 30,212,218, 34,171, 85,253,250,245,135,222,191,127,223, +214,219,219,155, 23, 31, 31, 47,217,187,119,111,150, 88, 44,190, 2, 32, 90, 15, 78,109,145,213,106,209,228,177, 17, 27,247, 31, +230,145,108, 14,130,142,156,199,172,219,169,170, 11,201,133, 67, 80,126, 88,177, 82, 72,165,210,107,193,193,193, 82,146, 36,145, +151,151,135,156,156, 28,100,101,101,149,125, 23, 20, 20,128,193, 96,224,250,245,235,178,194,194,194,251,186,118,240,222,189,123, +245,211,210,210, 60, 4, 2, 65, 27,245, 39, 30,165,209,133,166, 90,211,218, 8, 4,130,174, 0, 30,105,166,167,166,166,214,123, +240,224, 1,191, 38,126, 51, 51, 51,176,217,236,114, 22, 45, 46,151, 11, 7, 7, 7, 40,149, 74,156, 56,113, 2, 0,242,170,227, + 96,179, 57, 2,146, 36, 64,209,148,148,199,227, 81,124, 62,191, 82,129,165, 15,167, 26,169, 95,126,249,165, 36, 50, 50,178, 82, +139, 86,109, 56,105,154, 46,233,213,171, 23,210,211,211,193,227,241,202, 30,214, 26, 65, 69,146, 36,184, 92, 46, 50, 50, 50, 48, +101,202, 20,208, 52, 93,242, 79,223,121,180,125,154,212, 98,136, 0, 64,168,133,208,123,126, 90,186,250, 64,105,134, 6,105,154, +134, 70,112, 85,152, 95,182, 46, 93,178,183, 87,240,233,154, 92, 80, 80,176,177,180, 59,244,222, 10,223,251,244,120, 40,148, 9, +173,216,216, 88, 28, 62,124, 24, 5, 5, 5,224,112, 56,200,207,207,199,193,131, 7, 17, 19, 19, 3, 14,135, 3,205,190,208, 85, +191,249,248,248,108, 12, 15, 15,143, 25, 49, 98,132, 56, 58, 58, 26, 98,177, 24,209,209,209,232,221,187,183,228,238,221,187, 9, + 98,177,120, 21,116, 25, 58,212,100,124, 87,151,215,145, 74,165,136,138,138,170,244, 83,213, 50, 21,145,144,144,224,170, 82,169, + 26,211, 52,237, 75,211,180, 57,212, 41, 28,212,255,181, 63, 95,170,231,153,211, 52,237,171, 82,169, 26, 37, 36, 36,184, 26,228, +132, 1,159, 41,110,105,137, 45, 90, 75,100,221,170,222,162, 69,145,193, 7,118,172, 52, 63,242,144, 68, 74,114, 2, 30, 95,220, + 45, 84, 81,138, 47,244, 44,135,211, 3, 90,185, 54,120, 70, 38, 94, 20, 81, 26,206, 92,152,147, 2,208,140,218, 8,173,114,156, +160,200,224,131, 59, 2, 45,142, 61, 38,144,158,242, 6,119,207,238, 18, 42,149,210,238,120, 27, 26, 85, 27,206,145,108,246, 50, + 22,131, 88,218,171, 83, 75,118,231,150,238, 48,201, 74, 66, 70,106, 58, 78,196,102,231, 37,228, 75, 39,222, 37,228, 72,126, 35, + 61,208,119,146,181,181,149, 35, 11,253,166,218, 88,223, 63, 95,248, 59,193, 18,201,105, 57,189, 94,112,183,172, 44, 69,249,126, +190, 15, 71, 51, 51,179, 17,143, 31, 63, 54,231,241,120, 70,143, 31, 63,166,246,238,221,155, 43, 22,139, 47, 2,136,208,105,219, +223,135,115, 91,119,183, 91,235,118,237,231, 21,139, 74, 32,146,201,193,117,224,171,206, 68, 60, 31,140,170, 19, 96,150,227,228, +114,185,199,142, 29, 59,214,183, 75,151, 46,174, 94, 94, 94,100, 94, 94, 30,138,139,139,203,156,171,237,236,236, 16, 27, 27, 75, + 37, 38, 38,166,115,185,220,227,186,246,179, 99,199,142,137, 36, 73,198,171,135,209,226, 81, 33,186, 80,171,105, 99,129, 64,208, +150,207,231,223, 2, 96,172, 21,117,168,205,169, 73,239,176, 4, 0, 73, 16,196,163,232,232,232,226, 62,125,250,192,200,200, 8, + 34,145, 8,117,235,214,133, 82,169,196,197,139, 23, 17, 25, 25, 41,162, 40,234, 86, 37,226,181, 92, 63, 37, 18,113, 93, 0,164, +184,164,164,197,152, 49, 99,186,206,155, 55,175, 92, 72,186,189,189, 61,172,173,173,245,226, 4,128,188,188,188,166,127,252,241, +199,156,232,232,232,239,250,246,237,107,177,100,201, 18,110,253,250,245,161, 82,169,200,218,114,230,231,231, 91, 68, 69, 69,109, +234,220,185,243,140, 62,125,250, 48,215,173, 91, 7, 11, 11, 11,168, 84, 42, 24, 25, 25,161,176,176, 16,171, 86,173,194,157, 59, +119,148, 52, 77,239, 18, 10,133,223,235,121, 46,225, 67,175,205,170, 44, 64, 85,165,100,168,162,253,223,222,207, 10, 62, 93, 80, +167,112, 88, 88, 69, 6,123,232,122,206,107,132, 22,131,193, 64, 82, 82, 18,246,238,221,251, 94, 30, 45, 77,250,135, 42,184, 43, +219,118,250,230,205,155, 42,130, 32, 58, 60,126,252,120,225,232,209,163, 39,138, 68, 34,103, 19, 19,147,116,133, 66,241,139, 88, + 44, 94,139, 82,127, 84,182, 62,247, 16,145, 72,148, 92, 89,212, 97,197, 54,128,101,181,156, 21,210, 59,148, 75,225, 80, 97,153, +114,169, 31, 42, 73,239,240,183, 31,119, 3,231,191,146,243,115, 23, 91, 85, 39, 44,125, 15,173, 38,179, 88, 98,133,119,120, 2, +241, 33, 34,235,125,107,137,164, 36, 97,249,177,119, 45,101, 82, 9, 68,194,204,151, 72, 58,145,245, 65,155,165,238,231,237, 4, + 2, 73,137,111,240, 48,108, 87,105, 63,223,134,214,186,159, 4,176,248,167, 75,161,108,194,194, 26, 79,231,140, 67,122,129, 8, +151,222,230,159,164, 75,164,211,143, 0,249,184, 3,144, 74,105,248,193, 31, 50,118,251, 14,178, 24,106, 91,135,133, 45,243,127, + 1,111,145, 13,187, 93,247, 46,250,212, 64,204,224,241,120,225,219,183,111,239,225,235,235,203, 29, 50,100, 72,101, 14,242,250, + 34,245,209,171, 55, 63, 93,216,179,121,190,141,119,123,236, 92,182, 64,117, 44,226,121,197, 40,196,106,225,225,225,161,186,119, +239,222,188, 41, 83,166,108,233,209,163,135,211,128, 1, 3, 56,117,235,214, 5,151,203,197,155, 55,111, 16, 30, 30, 46,123,251, +246,109,122, 73, 73,201,188,230,205,155,235,147,227, 44,127,249,242,229, 27,213,235, 32,212,195,133,109,160,142, 46,212, 52, 82, + 39, 45,109, 3,192, 56, 48, 48,112, 52, 0, 84, 17,246,189, 28,192, 30, 0, 76,154,166, 51, 66, 66, 66, 58,156, 61,123,182,195, +220,185,115,217,125,251,246,197,253,251,247,113,245,234, 85,185, 92, 46,143, 80, 11, 87, 93, 75,229, 80, 0,162,148, 74,229,243, +160,160,160, 14, 12, 6, 99,185,102, 70, 76, 76, 12, 14, 29, 58, 84, 27, 78, 37,128, 77,153,153,153, 63,133,132,132, 44,191,118, +237,218,248, 49, 99,198,152, 43, 20, 10,196,198,198,226,231,159,127,174, 21,167, 80, 40,156, 99,107,107,187,244,226,197,139,191, + 92,185,114,229,235, 81,163, 70,145,179,102,205, 66,112,112, 48,126,251,237, 55, 74,165, 82,157,101,177, 88, 99,114,114,114, 68, +159,226,174,163, 30,134, 75,215,179,214, 97,141,188, 31, 50, 52,168, 35, 4, 31, 74,160,217, 14, 63, 63,191, 50, 43,163,198, 10, +167,221,134, 32, 8,189,135, 14, 1, 88,210, 52, 77, 1,216,133,210,250,162,218, 89,225, 25,248, 43,115,188,174,140,205, 4, 82, +203, 24, 72, 17, 91,125, 81,105, 75,128, 70,179, 26,216, 10,150, 47, 95,190,117,197,138, 21, 91, 43,166,112,208,110, 84, 49,245, +195,202,149, 43, 97, 72,239, 96,192,127, 21,149, 11,173,168,125, 10, 69,131,193, 75,182,175, 91,176, 66,169,144, 9,105,200,253, +241,230,116,244,135,174,140,166,232, 69,215,143, 6, 6,131, 70, 62,173, 82, 46,252,224,222,255, 77,253, 36, 44,172, 81,180,106, + 26,126,123,145, 78,103,136, 20,223, 28,145,203,203, 89,131, 74,125,178,168, 97, 55, 36,249, 39,172,156, 88,103,230,124, 97, 67, + 92,200, 27,173,247,122,178,178,178,206,109,221,186,149,220,188,121,115,215,146,146,146,138, 14,242,181,197,130,254, 51, 23, 49, +218, 53,114,157,249,240,117,242, 64,232, 48, 92, 88, 17, 29, 59,118, 20,196,197,197, 5, 92,185,114,101,196,237,219,183,123,136, + 68, 34, 87,130, 32, 96,108,108,156, 44,149, 74,175,113,185,220, 99,122,138, 44, 0,192,138, 21, 43,232,149, 43, 87, 18,113,113, +113, 52,131,193,248, 19, 64, 34,131,193, 72,210,118,130,215,158,174, 89, 38, 48, 48, 80,151, 7,226,237,226,226,226,200, 85,171, + 86,117, 89,181,106, 85, 11,181, 85,232, 54,254,242,249,210, 23, 10, 0,183,217,108, 78, 58, 65, 16,206,108, 14, 87,116,239,222, +189,107, 31,200, 89, 34,151,203, 23,166,164,164,108,217,178,101,203, 90, 19, 19,147,182, 49, 49, 49,127,126, 8,167, 90, 68, 13, +182,182,182,118, 58,124,248,240,169,131, 7, 15,182,103, 50,153,247, 9,130, 24, 34, 20, 10, 63,105, 81,105,117,129,232,149,122, +212, 58,212,137,247, 99, 39, 41,253, 59,132,155, 74,165, 42, 94,186,116,105, 86, 69,225, 85,209,122,165,249,175, 78,229,162,203, + 62,213, 39,138,178, 6,225, 66, 20, 3, 64,105,237,194,210,178, 58,186, 22,149, 6, 32,174,233, 58, 39, 73,242, 44,128,151, 36, + 73,190,174, 24,232,162, 61,111,229,202,149, 53, 93,231, 6, 24,240, 89, 67,135, 59, 91, 32, 9, 4,214,214,147,246, 31, 52, 87, +126,156,126, 6,176,217, 43, 73, 96, 62, 0,130, 6,182, 28,145,203,127,168,110, 65,199,142, 88, 75, 19,152,171,222,153,235, 50, +238, 98, 77, 45,182,189, 14,116,168, 63,168, 39,103, 19, 84, 95, 80,246, 61, 78,127,127,127, 70, 21, 15,243,114, 69,165,171, 66, +104,104, 89, 22,255,170,250,169,125,190,153, 61,120,240,192,201,199,199, 71,128,242, 78,255,149, 77,167,245,220,118, 6, 0,213, + 71,222,159,159, 5,167,155,155, 27,231,205,155, 55,178,127,215,181,105,224,252, 87,114, 90, 54,117, 1,129, 73,208,206, 29, 84, +173, 69, 75, 75,160,209,244,207, 40,136, 77,169,162,159,154,235,220, 50, 33, 33,193,181, 97,195,134,201, 0, 10, 42,244,163,178, +121,180,225, 24,253,223,115, 86,134,201, 40, 95,138,206,128, 74, 14,132,129,211,192,105,224, 52,112, 26, 56, 13,156, 6, 78, 3, +103,109,133,214,103, 13, 18, 6, 24, 96,128, 1, 6, 24, 96,128, 1, 6,252, 45, 32,170, 81,165,250,152, 4,107,163,108,175, 25, + 56, 13,156, 6, 78, 3,167,129,211,192,105,224,252,191,227,172,137, 91,123,249,207,117,232,240, 31,235,183,193,172,106,224, 52, +112, 26, 56, 13,156, 6, 78, 3,167,129,243, 67, 4,203,103, 13, 38, 12, 48,192, 0, 3, 12, 48,192,128,207, 6, 61,220,193,103, +170, 64,254,241, 70,167, 32,170, 26,209,199, 13,117, 0,224, 99,241,253,159,130, 15,224, 43,173,255, 23,160,142,140, 55, 8,173, +207, 23,141, 0, 44, 1,160, 93,139,236, 33,128,245, 21,218, 29, 5,160, 93,144, 80,132,210, 58,129,175,245, 89, 25, 73,146,235, +187,116,233, 50,253,206,157, 59,155,149, 74,229,170, 90,244,215,149,207,231,111, 36, 8,162, 53, 0, 22, 65, 16,111, 50, 51, 51, +215, 43,149,202, 15,137, 90,105,224,232,232,184, 1, 64, 75,146, 36, 89, 4, 65, 36,100,102,102,174, 81, 42,149, 55, 63,128,211, +204,193,193,161, 19, 77,211,142, 0, 24, 44, 22, 43, 55, 45, 45,237, 1,106,153, 91,201, 63, 48,150, 93, 40, 82,178, 0,192,220, +132,169, 8, 13,108, 42,215,117,154,225, 20, 55,192,128,255,111,208,165,145,201,229,208,219, 13,107,105, 37,190, 87, 1, 68,175, +250,216,113, 57, 17,223, 87,181, 60, 81, 73, 84,115, 69,206,222,110, 88,171,162, 75, 57,122,185, 97,211,229, 55,168, 54,210, 94, + 23, 78, 13,246, 1,228,100, 29,170, 20, 16,186, 69, 95,255,219,241, 21,202, 15, 21,150, 13, 29, 86, 43,180,134,185,131,175, 98, +130, 25, 26, 11, 77, 24,175, 25,128, 22,234,135,252,107,148,230, 42, 42,250,192,206,125, 46,156,255, 54, 44,167,105, 58,160,220, +201, 90, 73, 30,162, 47,190,248, 98,192,149, 43, 87,140, 53,245,238, 40,138,130,145,145,145, 18,192, 88, 61,214,101, 63,108,216, +176, 69, 7, 14, 28,192,208,161, 67,151,134,133,133,109, 5, 80,172,235,194, 86, 86, 86,254,150,150,150,193,251,247,239,183,107, +223,190, 3,193,225,112,240,230, 77,130,243,148, 41, 83,188,226,226,226,206,102,101,101, 77,212,119,227,173,173,173, 71, 90, 90, + 90,110,217,187,119,175,109,231,206,157, 65, 16, 4, 34, 35, 35,157,231,204,153,211,226,221,187,119,199, 51, 51, 51,103,232,203, +105, 99, 99,227,110, 97, 97,209,109,231,206,157, 70,157, 58,117, 2,143,199, 67,116,116,180,233,212,169, 83, 29,211,210,210, 98, + 51, 51, 51,111,233, 43,178,158, 69,158,255, 90, 41,151, 6, 1, 0,147,205, 93,208,126, 75,196,249,103, 55,206,247,175,105,154, +127, 96,236,239, 6,177,101,128, 1, 6,104, 99,164, 19, 28,105, 26,243,175,252,188,140, 4,128, 94,227, 87,207, 26,233,132,205, + 71,210,171,174, 97,171, 39,223,247, 99,234, 32,248,112, 26, 50, 63,164,159,251, 0,114, 14,147, 57,171,157,143,143,237,183,119, +239, 38,200,129, 95,254, 79, 14, 81,165,195,156, 85, 10,173,193, 77,177, 74, 89,106, 49, 33,250, 52,196,241,171,137,140,240, 47, +190,248,162,225,132, 9, 19,136, 86,173, 90, 33, 50, 50,210,253,248,241,227, 95, 93,184,112, 33, 65,165, 82, 69, 2,120, 1,221, +179, 90,179, 0,120, 50, 24,140,214,255,114,206,127, 51, 76,212,226, 42, 19,127, 37, 58,125, 47,225,233,245,235,215,207, 49,153, + 76,141, 69,171,157, 72, 36,114,168, 96, 5,211, 5,245, 20, 10, 5,226,227,227, 65,146, 36, 11, 64,125,188, 95, 82,163, 42, 56, + 27, 27, 27,239,142,120, 24,105, 67, 48,141,144, 47, 1, 32,145,131, 99,234,128, 3,135, 66,172,231,205,158, 49,248,230,205,155, +225, 69, 69, 69,191,234,209,159,250, 38, 38, 38, 91,159, 62,125,106, 99,108,108, 12,138,162, 80, 84, 84, 4, 71, 71, 71,236,223, +191,223,114,222,188,121, 1,133,133,133, 55, 37, 18,201,111,250,136,115, 11, 11,139,110,207,159, 63, 55,210, 20,148,150,201,100, +112,118,118,198,209,163, 71,185,179,102,205,106, 90, 80, 80,144, 42,147,201,222,234, 74, 88, 40, 82,178,148,114,105,208,225, 93, +129, 46, 0, 48,102, 70, 96, 16,167,200,252,162, 46,211, 10, 69,202, 11, 0, 12, 66,203,128,127, 26,173,109,109,109, 67,115,114, +114,110, 1,152,136,143, 99,105,112,231,241,120,205, 41,138,114, 36, 73, 18, 12, 6, 35, 67, 36, 18, 61, 5,240,170,182,132, 54, +110,126,253,193, 53, 30, 7,154,106, 65, 2, 32, 72, 50, 90, 37, 47, 57,148,251,234,230,249, 15,226,228, 24,141, 7,232, 22, 36, + 64, 17, 36,249,148, 82,150,236,207,137,191,121,233,223,114,112,238, 11,209,216,205, 81,247,194,152, 31,131,111,120, 3,240, 73, + 10,228,209, 36,221,135, 21,103, 2,125,103,207,158,237, 56, 99,250,116, 98,220,216,177,141,110,221,185, 67,116,213,167, 90,193, +231,137, 42, 29,223, 43, 21, 90,254, 77, 97, 69, 3, 11,143, 7, 47, 33,153, 12, 6, 49, 98,246,250,128,131,187, 54,145, 61,251, + 15, 41, 27, 62,241,245,245,133,175,175, 47, 17, 20, 20,212,232,207, 63,255,108,116,244,232, 81,101, 68, 68,196, 83, 0, 39,170, + 90, 89,111, 55,136, 41,128,199,102, 49, 69, 35,150,253,186,215,199,199, 7, 92, 46, 23, 31,194, 9, 0, 61, 27,146,111, 89,214, + 13,158,142,152,185, 60,185,125,251,142,244,199,224,252,140,240, 16, 40, 43,106,109,229,226,226,210, 73,169, 84,242, 0,128,201, +100, 74, 82, 82, 82,102,162,180, 54, 32, 0,156,165, 40,106,128, 30,220, 36,128, 21, 3, 6, 12, 88,250,237,183,223,162,110,221, +186,152, 53,107, 22, 20, 10, 69,228,165, 75,151,150, 3,216,128, 26, 46, 30,123,123,251,229,187,119,239,182,102,114, 76,208,106, + 97, 34, 4, 5, 74, 0,128, 41, 23, 56, 55,141,198,172, 89,179,204, 31, 63,126,188, 70, 31,161,101,111,111,191,106,255,254,253, +214,198,198,198,160,105,186,172, 22, 99,113,113, 49,138,139,139, 49, 99,198, 12,243,216,216,216,141,250, 8, 45, 7, 7,135, 78, + 59,119,238, 52,226,241,120, 40, 46, 46,102,203,229,114,162,168,168, 8, 37, 37, 37,180, 76, 38,147,207,156, 57,147,251,226,197, + 11, 63,129, 64,240, 22, 6,252, 91,192, 0,240, 13,139,197, 26,212,176, 97,195, 54,175, 95,191,126,162, 84, 42, 79, 3, 56,253, + 17, 94,166,186, 59, 57, 57,173, 77, 79, 79,223, 9, 32,228,255,101,135, 58, 56, 56,156,190,119,239,158,203,238,221,187,199,110, +222,188,249, 34,128,223, 62,128,142,205,102,179, 7,119,237,218,213,101,204,152, 49, 28, 7, 7, 7, 72,165, 82, 36, 38, 38,154, +159, 60,121,210, 53, 58, 58, 58, 85, 93, 17, 67,231, 23, 10, 27,247,142,166, 96,154, 31,239,208,177, 83,231,161,131,191, 49,115, +176,177,128, 88,166,194,235,100, 65,221, 63, 46,158,235, 26,199, 54,186, 39,151, 11,135,231,190,186, 87,172, 47,103,183,110,221, + 59,247,232,222,221,204,194,210, 2, 66,145, 28,111,146,210, 92,111, 92, 61,239,203,100, 26,221,166, 8,197,168,172,231, 87, 75, + 62,229,177,153, 5, 48, 69, 60,155,230, 45, 58,182,122,220,107,194,154, 54, 52, 77,131,164,177,163,162, 53,107, 22,192,220, 81, + 90,246, 75, 47, 62,208, 52, 77, 16,216,164,109,205,234,237,134,181, 52,141,239, 65,130,232, 93,195, 48,165, 6,189, 0,174,165, +181,181,207,212,201,147,137,162,194, 66, 68, 71, 71,151, 84, 20, 89, 91,235,128,125,155, 68,189,179, 41,181, 23,219,255, 82,107, + 86,165, 67,135, 58,231,209, 50, 54, 54,174,116,186,133,133, 5,186,117,235,134,245,235,215, 51, 1,180,174, 48,187,124,145, 85, +128, 27,182,103, 49, 44, 76,184,100,221,186,117,205,204,205,205, 63,152, 19, 0, 64, 83,245, 59,214,165,191,124,244,235,146,177, +215,142,110,241, 20, 21, 21,176, 42, 54, 49, 53, 53, 69,227,198,141,177,116,233, 82,221, 56, 63, 28,255, 40,167,163,163, 99, 19, + 95, 95,223,214,215,111,221,178, 76, 79, 79,231,166,167,167,115,175, 92,191,110,217,161, 67,135,214,142,142,142, 77,202,118, 21, + 77,235,211,207,213,187,118,237, 90,126,246,236, 89,210,215,215, 23, 86, 86, 86,232,214,173, 27, 46, 94,188,200,220,188,121,243, + 58, 0, 75,107,234, 39, 73,146,157,125,125,125, 9,208, 52, 50,132, 74, 60, 88,223, 4,209,155, 60, 80, 36,161,145, 39, 44,132, + 88, 44,129,177,177, 49, 15,165,195,189,186,110,123,199, 14, 29, 58, 16, 0,202,196, 85, 81, 81,233,167,184, 88, 4,153, 76, 14, + 46,151,107, 6,128,167, 43, 39, 77,211,142,157, 58,117, 2, 0,200,229,242,178, 55,188,130,130, 2, 66, 40, 20, 66, 38,147,129, +197, 98,177, 81,179, 95, 99, 25,167,185, 9, 83,193,100,115, 23,140,153, 17,152, 50,102, 70, 96, 10,147,205, 93, 32, 51, 43, 84, +233, 50,205,220,132,169,248,196,231,167, 29, 73,146, 63,187,185,185,197,146, 36,121, 24,128,227, 7,114,182, 5,176,206,200,200, +232,154,135,135, 71,138,177,177,241,117,181, 80,239, 80, 75, 78,142,177,177,241,245,117,235,214,157,122,242,228,201,208, 63,255, +252,179,254,179,103,207, 6, 7, 5, 5, 29, 55, 53, 53, 13, 71,121,191, 68,189,175,205,250,245,235, 31,124,240,224, 65,219,142, + 29, 59, 30, 0,192,253, 72,215, 59, 3, 64, 75,232, 84,145,227,147, 28,119,167, 86,173, 90,185,240,120, 60,244,232,209, 3, 0, +252, 62,132,147,205,102, 15, 94,186,116,169,219,178,101,203, 56, 2,129, 0,215,175, 95,199,195,135, 15,161, 84, 42, 49,109,218, + 52,238,152, 49, 99, 26,152,153,153, 13,214,171,159, 76,243,227,179,231,204,237, 51,127,214, 36,179,167,239,228, 56,116,237, 29, +126,143, 16, 32,171,132,131,254,131,199, 88,244, 30, 56,172, 55,135,107,113, 92, 95,206, 69, 11, 23,246,153, 60, 62,192, 44, 70, + 64,225,220,253, 12,220,143, 23, 66,201,178, 68,223,193, 19,173, 90,116,234,243, 21, 19,172, 95, 62,245, 49,218, 15,180,159, 61, +123,182,221,130, 77, 71,238, 58,181,253,102, 71,118, 62,124,181,133,143, 59, 96,105,109, 98,242, 77,124,215,174,147,140, 74,235, +197, 86,203, 89,142,175,245,192,224,172,124,116,209,246,207,234, 98,141, 70,234, 97, 69,198,149,159,151,145, 52,129, 89, 35,157, +202,221, 7, 42,237,231, 77, 96,232,236,185,115, 89, 22, 86, 86,216,181,107, 23,164, 34, 81, 57,159,217,238, 46,232,115,205,152, +153,218,192,195, 57,182,155, 43, 17,254, 31,124, 95,153, 92,165, 69, 43, 44, 44,140,238,215,175, 31, 1, 0,161,177,200, 31,220, + 20, 27,135,125,187,110, 41, 65, 18,116, 61,207,142, 49,117,220,154,137,108,108,108, 80, 82, 82, 2,169, 84, 10, 54,155, 13,137, + 68,130,119,239,222,225,254,253,251,176,178,178,210,171, 39,133,133,133, 48, 53, 53,133,169,169,233, 71,225, 92, 60,182, 7,247, + 77, 74, 54,247,242,253,155, 93,183, 79,255,173,189, 91, 75,191,103,221,135,205,122,110,110,231, 36,121,246,236, 25,238,221,187, +135,252,252,124,248,248,248,252, 87, 14,230, 67,181, 79,214, 67, 0, 86, 13, 27, 54,116,190,124,237,182, 85,177,132, 50, 79,202, + 84,176, 40,138,130,177, 49, 95,121, 34,244,156,112,232,224,254, 68, 70, 70, 70, 22,128,135,106,113, 91, 83, 77, 69, 30,128, 38, +254,254,254,139,166, 79,159,142,132,132, 4, 76,154, 52, 73,252,240,225,195,220,142, 29, 59,218,236,223,191,223,104,222,188,121, +184,117,235,214,138,176,176,176, 51, 0, 18, 1, 84, 90,171,141,166,105, 54,155,205,134, 82, 45, 27,228, 42,170, 76,223, 23, 22, + 22,130, 22,231,131,205,102, 51, 0,216, 65, 71, 63, 58,138,162,216, 44, 22,171, 76,100,189,203, 44,196,187,172, 18, 20, 22,203, + 32, 22, 43, 33, 19,211, 96, 24,219, 48,129, 36, 7, 0, 73, 80,170, 87, 0, 0, 0, 32, 0, 73, 68, 65, 84,186, 90, 71,120, 60, + 30,148, 74, 37,138,138, 74,187,161,177,148,201,100, 50, 8,133, 66, 48, 24, 12, 83, 0,230, 0,242,116, 33, 84, 59,185,255,174, + 30, 6,196,163, 35, 3,108, 95, 95, 88, 92,110,154,185, 9, 83, 17, 58,175, 41,195,198,185,197,157,150, 67,127,241, 40,155,246, +105,253,179,184,118,118,118, 55, 78,157, 58,213,180, 81,163, 70, 72, 76, 76,244, 24, 50,100,136,143, 64, 32,104, 9,253,107, 50, + 26,147, 36,185,113,204,152, 49,211, 71,140, 24, 65,184,187,187,131,201,100, 66,169, 84, 58, 39, 36, 36,116, 59,121,242,228,194, +131, 7, 15,238, 87,169, 84,223, 65,119,191, 63,146,195,225,156,216,187,119,111, 23, 31, 31, 31, 28, 62,124, 24, 15, 31, 62,164, +218,182,109, 75,142, 30, 61, 26,174,174,174, 62,163, 71,143,254, 93, 42,149,246,173,165,101,203,181, 67,135, 14, 46, 12, 6, 3, + 29, 59,118,100,223,187,119,175, 21,128,123, 31,184, 79, 77,157,157,157,111,249,249,249,181,188,118,237, 90, 84, 70, 70,134,159, + 30,219, 11, 0, 3,157,156,156,130, 44, 44, 44,172,244,184,199,150,164,165,165,125, 15, 32, 84,199, 69,218,183,110,221, 26,201, +201,201,104,210,164, 9,216,108,118, 7,185, 92, 62, 5, 64, 31, 0, 63, 0,136,213,163,191,238,221,187,119,119,241,243,243, 35, + 66, 67, 67,203,252, 67, 73,146,132, 82,169, 4,155,205, 70,251,246,237,201,200,200,200, 58,143, 30, 61,114,135, 14,195,136, 54, +110,126,253, 59,118,238,218,185,139, 79,115,114,115,232,107,168, 40, 21, 24,132, 18, 76,130, 2,165,224,130,203,102,192,221,179, + 13, 35,254,197, 83, 31,153, 84,222, 63,247,213,181,243,186,112,246,233,213,211,183,105, 19,119,114,251,239,111, 80,144, 22,171, + 74,139,187,157, 67, 50, 72, 52,109,253,133,173,123,179,150,140,150, 62,126,172,244,196, 23,221, 36,146, 46, 61,242, 19,110, 95, +251, 20, 23,228, 74,128,225, 92,199,246,155,126, 61,253,216,130,244,116,209,201,208,243,207, 75, 20,184, 15, 0,183, 0,162, 47, +208,220,187, 93,187,174,251, 55,108,176,225,243,249,172, 81, 35, 70, 40,247, 69, 69, 69,161,138,161,223,149, 0,195,214,209,177, +199,212,169, 83, 25,130,244,116,250,228,233, 11,207, 52,124, 40,125, 75,241,110,238,236,209, 15,162,120,189,134, 41,251, 3, 28, + 7, 71,199,166, 83,166, 76, 65, 70,122, 58, 14,135,132, 20, 75,128, 8,141, 21,235, 28, 3, 59,155,185, 57,142, 91, 48,113, 0, +225,194,183,197,212, 21,251, 58,116,147,103,185, 65,240,215,241,215,214, 34,159,177,200,154, 92,169,208,170,136,223, 98,177,220, +140,141,250, 39, 79, 30, 35,179,139,228,162,132,132, 4,216,218,218,130,207,231,195,194,194, 2, 49, 49, 49,184,126,253, 58, 94, +190,124, 9,138,162,208,162, 69, 11,189,122,147,147,147,131,167, 79,159,194,202,202,234,163,113,186,185,216,225, 91, 23, 59,118, +102,110, 33,251,218,195,151, 62,251, 22, 15,110, 70,122, 12, 62,168, 93, 36, 86, 38,147,225, 63,130,178,232, 66, 23, 23,151, 78, +135, 14, 29, 98, 75,149, 48,115,159, 18,241,163, 72,162, 50, 1, 0, 19, 30, 67, 20, 25,212,248,187,213,171, 87,139,198,143, 31, +239,145,146,146,178, 94, 7, 91,255,218,238,221,187,207,167,105,154, 53,123,246,108, 0,192,152, 49, 99, 10,239,223,191,239, 14, + 32,235,250,245,235, 78, 19, 38, 76,120,117,227,198, 13,227,185,115,231, 50,148, 74,101, 12,147,201,164,195,194,194, 86, 1, 8, +124,239,137, 72,146,143,163,162,162,234, 57,185, 54,134,171, 13, 9,223,165, 47, 75,111,112,198, 20, 82,147,222, 32,238,217, 67, + 56, 58, 58, 90,240,249,252,216,212,212, 84,121, 90, 90,218, 66,145, 72,180,187,134, 62, 70, 71, 70, 70,242, 93, 93, 93, 81, 92, + 92,140,212,236, 18,204, 58,109,140, 66,113,169, 17,131, 5, 49, 90,186, 52, 54, 51, 34,101, 15,179,178,178,228, 50,153,108,153, + 80, 40, 60, 84, 29, 39,139,197,202,125,246,236,153,105,221,186,117, 33,145, 72,232,188,188, 60, 66, 36, 18,161,168,168,136,184, +112,225,194,215, 2,129,160,109,253,250,245, 9,103,103,231, 85, 2,129, 64,156,150,150, 54, 73,151,161, 73,181, 96, 82, 49,153, +204,205,147, 39, 79, 30,122,230,204,153,199,161,129, 77, 7,106, 13,151, 88,120,122,122, 94,110,222,188,153, 83,200, 38,239, 29, + 0,126,252, 23,156, 91,227,150, 44, 89,210,212,218,218, 26, 83,167, 78,197,202,149, 43,177,124,249,242, 70, 83,167, 78,157, 12, + 96,171, 30, 60, 70,142,142,142,143,182,111,223,238,209,169, 83, 39, 92,188,120, 17,199,142, 29,195,219,183,111,149,245,235,215, +103,250,248,248, 96,197,138, 21,232,221,187,247,164,153, 51,103,118, 77, 79, 79,111,165,163,248, 24,191, 98,197,138,129,157, 59, +119,198,216,177, 99,165, 55,111,222, 28, 10,224,202,213,171, 87,191,184,117,235, 86,232,145, 35, 71,140,214,173, 91,215, 99,222, +188,121, 83, 1, 4,215, 98,251,191,238,210,165,180,134,114,231,206,157, 17, 20, 20,212,251, 3,133, 22,199,198,198,230,194,225, +195,135, 91, 54,110,220, 24,163, 70,141,106, 53,116,232,208, 11,249,249,249, 61, 1,232,116, 67,170, 83,167,206,198,179,103,207, + 54,172,106,100,161, 50, 72,165, 82,235,111,190,249,102, 67, 82, 82,146, 94, 66,235,232,209,163,248,254,251,239,209,162, 69,139, +230,237,219,183,223, 51,101,202, 20,248,251,251,119,143,137,137,113, 64,105,212,114,141,224,241,120,205,135, 15, 31,206,121,240, +224, 1, 0,192,211,211, 19, 45, 91,182, 68,114,114, 50, 30, 63,126, 12,169, 84, 10, 7, 7, 7, 12, 26, 52,136,151,148,148,212, + 60, 39, 39,167, 70,161, 69,114,141,199, 13,236,215,215,236,220,125, 1, 84,148, 18,109, 26,154,195,199,195, 30,241,169,133,136, +140, 77,133, 74,198,134,185,181, 13, 58,116,237,101,157,145,246,118, 92, 46, 80,179,191, 22,215,120,220,160,129, 95,153,158,139, + 72, 71, 65,122, 28,253,250,225,153,235, 10,137,104, 18, 0, 60,254,243,248, 30, 71, 27,163,158,238,173,219, 48,252,122, 14,176, + 58,125, 44, 99, 92,254, 63, 83,219,239, 61,220,114,193, 94, 87, 86,206,152, 5, 1,190, 52,203,202,249,161,153, 66,177, 83, 51, +175, 55,208,107,225,146, 37,237, 39, 78,158,204,163, 40, 10, 71,126,253,181,240,105, 84, 84,252,100,128,154, 82, 5,223, 78,192, +117,232,192,129, 92, 51,115,115,204,153, 53, 11,102, 10,197,141,178, 93, 2,116,159, 51,127,126,167, 25, 51,102, 24,237, 89, 53, +253,113,239, 9,107, 90, 83, 52, 77,104,134, 41,143, 86,111,138,107, 59, 97,224, 64,152,153,155, 99,246,236,217, 32,228,242,203, +101, 2,138,137, 27,227,191,246,245, 9,232,223, 25, 4, 8, 28, 11,187,131,215,201,217,207,110, 8,240,230,115, 85, 85, 21, 80, +165,143, 86,181, 67,135, 69,114,100,118,255,106,176,192,221,221,189,168, 81,163, 70, 69,185,185,185,120,254,252, 57,242,243,243, + 17, 28, 28,140,184,184, 56, 80, 20, 85,107, 1, 67, 81, 20, 62, 54, 39, 0, 56,216,152, 99, 84,223,118, 76,169, 68,196,203,206, +206, 46, 55,124,244, 31, 18, 90,101, 80, 42,149,188,250,245,235,131, 4, 8, 97,137,194, 52,227,104, 23, 34,227,104, 23, 66, 88, +162, 48,149,201,100,164,169,169, 41,164, 82, 41, 79, 7, 42,214,151, 95,126, 57,255,204,153, 51,172,181,107,215,194,203,203, 11, +114,185, 28,247,239,223, 79, 5,144,165,110,147,126,251,246,237,116,141, 16, 94,191,126, 61, 78,159, 62, 77,244,232,209, 99, 97, +101,231,147, 64, 32,216, 56,101,202,148,188,146,162, 60,236, 29, 38, 70,232,168,108,252, 60,240, 45, 70,216,156, 66, 94,230, 59, +236,219,183, 15, 87,175, 94, 35,174, 92,185,202,190,121,243,166,201, 87, 95,125,181,163, 78,157, 58, 97,213,117, 50, 61, 61,125, +237,140, 25, 51, 10,138,138,138, 80, 84, 84, 4,177, 88,130, 60, 17,240,108, 75, 83, 60,219,210, 20, 18,202, 8,187,118,238, 38, +159, 61,123,102,251,246,237, 91,167,254,253,251,111,225,243,249, 7,171,227, 76, 75, 75,123,240,237,183,223, 74, 10, 11, 11, 33, +147,201,228, 42,149, 74, 38, 22,139, 21,199,143, 31,159,107, 99, 99,211,225,226,197,139,172,171, 87,175, 49,111,222,188,197,190, +126,253,186, 69,183,110,221, 78, 56, 56, 56,252,162,139,165,140,193, 96,108, 11, 9, 9, 25,183,107,215, 46, 7, 31, 31,159,102, + 21,134,162,248, 61,123,246,172,247,235,175,191,214, 9, 10, 10, 90,136,210, 0,148, 79, 10, 91, 91,219,153, 3, 7, 14,196,174, + 93,187,112,254,252,249,121, 59,118,236,192,151, 95,126, 9, 39, 39,167,111,161,251,176, 23, 0,252,184,117,235, 86, 15, 15, 15, + 15,140, 25, 51, 70, 54,105,210,164,239, 14, 29, 58, 84, 63, 60, 60,156,253,203, 47,191,212,155, 58,117,234,236,128,128, 0, 73, +131, 6, 13, 16, 28, 28,220,144, 36,201,109, 58, 93,223, 14, 14,115, 71,140, 24,129, 77,155, 54,225,230,205,155,131, 81,250, 64, +149, 1,184,116,247,238,221,254,235,214,173,195,224,193,131,225,236,236, 60,187, 54,150,167,166, 77,155, 46,235,211,167, 15,194, +195,195,209,170, 85, 43,116,232,208, 97, 30, 0,219, 90,238, 78,210,212,212,244,196,161, 67,135,124,235,213,171,135, 53,107,214, +192,205,205, 13, 7, 15, 30,244, 53, 49, 49, 57, 1, 29,221, 55, 44, 44, 44, 76,141,141,141,177,112,225, 66,122,240,224,193,121, + 53,125,230,205,155, 71,115,185, 92, 88, 89, 89,233, 26,248, 98,196,227,241, 58,122,121,121,225,254,253,251,184,122,245, 42,150, + 46, 93,138,185,115,231, 34, 59, 59, 27,195,135, 15, 55, 6,224,175,199,118,219,219,217,217,161,176,176,180, 46,188,151,151, 23, +158, 60,121,130,236,236,108, 56, 59, 59, 35, 35, 35, 3, 54, 54, 54,104,220,184, 49, 40,138,178,215,141,146,246,178,181,182, 64, + 86,190, 20, 76, 40,209,218,221, 22, 55,158,231,226, 93,182, 12,246, 54,150,200,200,202, 70, 29, 27, 30, 92, 92,234,130,166, 41, + 47,157, 20, 48,131,108,205,229, 25, 33,175, 72,142,180,216,155,185,114,149,116, 74, 65,226,221,148,130,196,187, 41,114,169,100, +202,227, 59, 87,115,235, 57, 24,193,197,197, 5, 4, 77,181,251, 20,215,227,144,186,112, 49, 49, 98,142,185,250,243, 50, 34,108, +255, 98, 66,154,251,174,109, 31,135, 82,203,178, 29, 80,127,200,240,225, 29,191,251,238, 59, 94,102,102, 38, 21, 48,108, 88,222, +218,192,192,107,127,212,240, 98, 80, 12, 52,234,217,179, 39, 72, 0,127, 92,185, 34,202, 0, 82, 1,192, 1,112, 25,240,205, 55, + 93,150, 44, 90,100,148,147,155, 75,221, 79, 40, 62, 23,151, 69, 15,178, 86,161,190, 46,254, 89, 42,192, 91,195,123,249,242,101, + 90, 12, 60, 6, 0, 63, 23,124,219,171,147,167,207,232,129, 93, 32,200,202,199,236,181, 63, 99,207,201, 91,151, 45, 20,244, 23, +255,161, 71,241,228, 90, 9, 45,245,208,207,123,211, 74, 74,222, 31, 61,248, 80, 1,243,119,112, 86,134,255,162,208,210, 64,161, + 40, 29, 37,145, 41, 40,200, 20,148,230,173, 22, 98,177, 88,103,138,203,151, 47, 31,158, 53,107, 22,182,108,217,130, 87,175, 94, +129,205,102,195,203,203,139, 15,192, 84,115,207,111,221,186,181, 61, 73,146,136,143,143,199,230,205,155, 49,126,252,120,250,222, +189,123, 7, 81,121,190,148, 39,121,121,121, 59,167, 76, 26, 95,144,159,249, 14, 10,113, 62,178,210,222, 64, 42, 42,192,154,245, + 27, 81,162, 96, 34, 67, 40, 71,134, 80, 14,146,107,141, 61,251, 15, 49,154, 54,109,218,135,193, 96,244,171,166,159,247, 51, 51, + 51,247, 79,155, 54,173, 32, 35, 35,163,108,251,100, 10, 26, 50, 69,249,243,213,216,216, 24,219,182,109,179,112,119,119, 31,200, +100, 50,187, 85,195, 41, 72, 73, 73,137,155, 54,109,154, 44, 51, 51, 19, 66,161, 16,231,206,157,235, 95,175, 94, 61,171, 13, 63, +110, 33, 68,114, 38, 50, 10,228,200, 40,144,131, 99,106,143, 19,161,103, 24,141, 27, 55, 14, 96, 50,153, 29,106, 18, 89, 71,142, + 28, 25, 61,108,216, 48,179, 31,127,252, 49,239,236,217,179,187, 0,104, 31,144,248,109,219,182,157, 60,113,226, 68,209,252,249, +243,173,131,130,130,230,125, 98,177,213,109,216,176, 97, 77, 40,138,194,169, 83,167,158, 1,216,122,230,204,153, 71, 82,169, 20, +195,135, 15,175,175, 30, 70,210, 5,109, 3, 2, 2,166,251,250,250, 98,206,156, 57,242,107,215,174,181, 6,176, 5,165, 67,185, + 52,128,100, 0, 59,110,221,186,213, 98,230,204,153,210,118,237,218, 97,236,216,177,227, 1,248,214,192,219,113,196,136, 17, 30, + 20, 69,225,248,241,227, 79, 1, 92,172, 48,255,122,104,104,232,125,153, 76,134,145, 35, 71, 54, 0,160,207,141,156,205,229,114, + 79,173, 94,189,218, 50, 45, 45, 13,163, 71,143,150,198,199,199, 35, 48, 48,208,200,194,194,226,162,214, 53,160, 51,184, 92,238, +190,159,126,250,105,160,183,183, 55,166, 77,155, 38,219,189,123,247,172,233,211,167,203, 90,183,110,141, 93,187,118, 13,228,112, + 56,122,149,232, 72, 79, 79, 47,136,141,141,181,169,233,147,154,154,170,107,120,190,177,169,169,105,132,167,167,103,161,151,151, + 87, 27,165, 82,137,152,152,152, 55,135, 15, 31,166,188,188,188,176,115,231, 78, 4, 5, 5,161, 95,191,126, 96, 48, 24, 58, 11, + 45, 6,131, 1,185, 92, 14, 99, 99, 99, 48,153, 76,188,121,243, 70,147, 90, 6,108, 54, 27, 0, 96, 98, 98, 2, 35, 35, 35,144, + 36,169, 83, 52, 26, 65,128, 46, 44, 81,128,197, 34,193, 36, 41,196, 37, 11, 33, 87, 80,224,177, 25, 96, 49, 9,128,166, 96,105, +194, 2,143,195, 0, 73, 16,148,142,156, 16,138,228,224,176, 73,176,216, 28,130, 84,170,140,202, 30,142, 76,149,145,145, 17,135, +176, 53,231,130,199,254, 23,149, 5, 38, 74, 29,203,199, 1, 44,147,186,117,135,110,218,188,153, 83, 88, 92,140,193,131, 7,231, + 37, 61,122, 20, 34, 6, 30,117,173, 33, 72,137,100, 50,221,253,186,118, 69,100, 84, 20,138,242,243, 95, 3,165,206,241, 28, 39, +167, 97,219,182,109,227,136, 37, 18, 12, 30, 52,168,224,213,157, 59, 71, 82,138, 17,118, 60,185, 84,136,213,120,220,217,108, 71, + 13,175, 48, 63, 63, 31, 40, 77, 33,225, 96,103,186, 97, 70, 64,111, 20,149, 72,176, 96, 99, 8, 21, 21, 39,248, 54, 60, 21, 95, +157, 73,135,240, 63,246, 24,158, 92,225, 3, 64,135,132,165, 26,235, 82, 77, 98, 69, 42,149,126,116, 1,244,161,156,149,137,196, + 15,229,252, 55,130,201,100, 74, 94,190,124,201, 49,183,113,162,108,204, 88,249,245,198,223,177, 0, 0,107, 83,166, 80,174, 82, + 80,233,233,233,224,114,185, 18, 29,135, 27, 38,237,219,183,111, 13,128,102, 76, 38, 51,236,208,161, 67, 68, 72, 72,136,213,136, + 17, 35, 18, 98, 99, 99,211, 60, 61, 61, 93, 15, 29, 58,100, 14, 0, 59,118,236,160, 79,156, 56,209, 27,165, 41, 51,170,204,227, +146,153,153, 25,152,155,155,123,111,198,140, 25,193, 28, 14,199,202,196,196,196, 38, 60, 60,156,144,200,105,180, 93,146, 92, 22, +137,104,110, 68,226,246, 98,115, 76,158, 60,153, 17, 27, 27,187, 62, 45, 45, 45,172, 26,206,133, 5, 5, 5,225,175, 94,189,218, + 98,225,220,210,206,196,117,137,133,207,226,120, 0,128,171, 45, 11,164,250,190, 88, 80, 80,128,236,236,108, 76,159, 62,221, 42, + 33, 33, 97, 97, 90, 90,218,141,106,172, 90,183,114,114,114, 82, 95,188,120,225,199, 98,177, 56, 38, 38, 38,109, 35, 34, 34, 8, +137,140, 66,243,133,201,200, 43, 46,237,167,181, 41, 19,143, 87, 59,224,219,111,191,101,190,126,253,122,163, 64, 32,232, 92,233, +205,140, 36,131,180, 69,214,130, 5, 11,162, 1, 52, 0, 80,110,104, 84,165, 82, 17, 35, 71,142,124, 14,192,107,254,252,249,214, + 52, 77,207, 91,184,112, 97, 30,128,189,255,244,185,100,110,110,190, 97,202,148, 41, 56,113,226, 4,242,243,243,183, 1, 64, 97, + 97,225,214,163, 71,143, 30,159, 52,105, 18,126,253,245,215, 13,217,217,217,127,160,230, 80,237, 47,135, 15, 31,142, 75,151, 46, +225,207, 63,255, 92, 6, 32,166,138,118,175,194,195,195, 23,158, 61,123,118,251,136, 17, 35,240,243,207, 63,247, 1, 80,157,131, +108,207,222,189,123,227,226,197,139,200,205,205,221, 85, 89,131,130,130,130,221,231,206,157,107,223,187,119,111,172, 95,191,190, + 39,128,235, 58,108,186,135,133,133,197,161,237,219,183,183,245,246,246, 70, 64, 64,128, 68, 46,151,247,153, 63,127,254,249, 99, +199,142,153, 29, 62,124,184,205,228,201,147, 31,168,115,190,221,215,201,148, 69,146,235, 54,111,222, 60,193,207,207, 15,243,230, +205, 83, 94,190,124,121, 0,128, 43,127,252,241, 71,194,130, 5, 11, 46,108,222,188,153,177,105,211,166, 9,179,103,207,206,166, + 40,234, 83,137,235,213, 59,118,236,104,223,171, 87, 47,188,121,243, 6,247,239,223,135, 92, 46,255, 53, 34, 34,226,118,163, 70, +141, 86,203,100,178,243, 38, 38, 38, 99,204,204,204, 60, 91,182,108,249,197,227,199,143,141,161,155,159, 94,102, 98, 98,162,165, +133,133, 5,148, 74, 37,158, 61,123,134,186,117,235, 66, 46,151,227,237,219,183,240,246,246, 6,155,205, 70,102,102, 38,180,172, +229, 53,136, 34,242, 89, 66, 82,122, 3,107, 51, 19, 64,197,195,147,248, 84,216,217, 90, 65, 69,144,200,200, 16,160,101, 19,103, + 16, 4,129,130,220, 12, 16, 4,241, 92, 23, 78, 21, 77, 69,190, 75,207,170, 99, 99,198,133,119,251, 94, 54, 17,127,100,135,152, + 55,232, 52,153,201, 32, 24, 28,174,233,222, 9, 99,199,218, 82, 20,141,130,220, 76, 48, 73,242,225,167, 56, 64,167,222, 33,165, +171, 27,239, 73,175, 9,107, 90, 18, 52,104,177, 28,135,127,206, 68,190, 49,208,114,199, 15, 63, 88,218,216,218, 34, 32, 32,128, +202, 77, 75,187, 86,162, 99, 98,229, 6,141, 26, 57,152,154,153,225,238,221,187, 96,148,250,216,226, 32,224, 17,180, 96,129,141, +189,163, 35,198, 79,152, 64,101,190,123,119, 93, 12,164,235,211,215, 6,110,110, 44, 13, 47,169,230, 21, 48, 48,107,254, 0, 95, +174,137, 17, 23,235,246,156, 65, 74,142,232,120,132, 0,123,254,163,246,142,125,213, 90,180,170,114, 62, 43,117,170, 54,174, 86, +172,240,120,188, 50,107,138, 30,111,122, 31,157,179, 38,252, 29,156,159, 16,139, 1,156, 5,176, 56, 37, 37, 37,110,194,132, 9, +114,165, 92, 90,116,111, 77,131, 69, 81,235,235, 77,139, 8,228, 79,251,125,150,197,162, 18, 97, 94,209,142, 29, 59, 20, 41, 41, + 41,113,218,203,212,192,253, 14,192,197, 95,126,249,101,247,169, 83,167,224,229,229,133,152,152, 24,123,145, 72,212,234,249,243, +231,214, 30, 30, 30, 8, 9, 9,193,137, 19, 39,182, 0,184, 90,157,200,210, 64,169, 84, 94,203,200,200,104,156,156,156,220,208, +210,210, 82, 97,105,105,137,138,145,136,133, 98, 10,185, 5, 66, 88, 91,219,192,220,220,188,190, 14,226,252, 98, 70, 70,134, 59, +101,213,164,139,123,206, 54, 97,228, 58, 23, 68,174,115,193,197,133, 78,224, 91,114,144,159,159,143,236,236,108,100,103,103,131, + 32, 8, 40, 20,138,166, 58,112,190, 21, 8, 4, 7,222,189,123,119,214,193,193, 1,102,102,102,160, 1,100, 20, 40, 16,189,201, + 3,209,155, 60,144, 81,160, 64, 97, 81, 17,234,213,171, 7, 51, 51,179,170,134, 40,200, 58,117,234,244, 29, 54,108,152, 25, 0, +168, 5, 84,119,154,166,167, 85,242,153,170, 84, 42, 59,105,218,126,255,253,247,214, 0,122,255,195,231, 19, 3,192,140, 73,147, + 38,181,225,241,120,216,185,115,231, 91, 0, 71, 52,247,250,221,187,119,199, 3,192,172, 89,179, 60, 1,204, 67, 21,153,160,203, + 76, 67,108,118,235,166, 77,155, 34, 34, 34, 2, 0,206,212,176,238,208,123,247,238,161, 81,163, 70,224,241,120,109,107,104, 91, +223,197,197, 5,241,241,241, 0,240,164,138, 54, 79,226,227,227, 75,135,123, 8,162,190, 14,219, 62,176, 87,175, 94,207,110,220, +184,209,182, 99,199,142,152, 48, 97,130,236,193,131, 7,125, 1,220,126,242,228, 73,183,145, 35, 71,138,220,221,221,113,235,214, + 45,143,145, 35, 71,222, 35, 73,114,141, 14,156,227, 87,173, 90,181,248,235,175,191,198,170, 85,171,232,147, 39, 79, 6, 0,184, +162,158,119,249,248,241,227,163,215,174, 93, 75, 15, 26, 52, 8, 43, 87,174, 92, 12, 96, 90,117,100, 34,145, 72,168, 82,169, 32, + 18,137,116, 50,201,235,218,222,214,214,246,203, 94,189,122, 97,233,210,165,168, 83,167, 14,206,159, 63, 79, 3, 8, 3, 16, 46, +147,201,186, 0,216, 44, 18,137,126,143,136,136, 64,207,158, 61,217, 40, 95, 98,164,186,245, 63, 59,122,244,168,212,194,194, 2, +174,174,174,104,208,160, 1, 50, 50, 50,144,148,148, 4,111,111,111,180,110,221, 26, 74,165, 18, 7, 14, 28,144, 20, 21, 21,233, +148,147, 79, 41, 19, 29,190,122,225,180,208,198,140, 11,103,123, 11,212,171, 99,141,226,130, 28,100,103,164,163,117,211,186,232, +218,186, 30,114,132, 50, 92, 14, 59,157, 95, 84, 84,114, 88, 39, 19,190,180,228,208,181, 63,206, 11,173,204,216,104,220,196, 19, + 35, 39,204,106,217,178,149,207,213,118,237, 58, 93,254,113,195,186,230,221, 59, 52, 37, 82,115, 36,184, 20,118, 38, 95, 88, 88, +120,232, 83,220,232, 87, 2, 12,137,133,251,237, 93,103, 35, 15, 52,235, 51,233, 64, 92, 42,182, 1,128,130,193,240,232,251,229, +151, 72, 77, 77,197,233, 83,167, 4, 37,192, 83, 93,249,140,140,140, 72, 0, 16, 10,133,224,170,253,238,148, 64,147,175,190,250, + 10,217, 57, 57, 56,122,228, 72,246, 37, 32, 74,159,126,246, 7, 56,198, 70,165, 6, 65,161, 80, 8, 2, 40, 4, 0,130,137,190, +237,188, 26, 33, 59,175, 16, 55, 30,198, 21,215, 19, 99,122,117, 60,159,177, 35,124,237,124,180, 0,228,204,155, 55, 15, 92, 46, + 23,124, 62,191, 76, 28,105,196, 10,135,195, 1,159,207,135, 82,169,196,241,227,199, 1, 32,167,218, 55, 60, 64, 58, 96,218,122, + 74,170,160, 75, 88, 44,214, 71,225, 84,191, 57, 74, 7, 47,248,153,250,227, 94,229, 65, 49,181,225,252, 12,208, 78,157, 19,171, + 29,128,252,164,164,164,212,161,131, 7, 8,147, 19, 94,100,136, 10,210, 5,133,185, 41,130,148,183,207, 51,150, 44,156, 39, 76, + 77, 77, 77, 65,105, 46,173,118,233,233,233,154,101,116,193,188,161, 67,135,254, 52,105,210, 36, 58, 58, 58, 26, 0, 16, 25, 25, +137,177, 99,199,210,163, 71,143,222, 6, 96, 81, 45,250, 45, 18,139,197,229,172, 33,114, 21, 85, 54,228, 87, 88, 88,136,244,244, +116,200,100, 50,157, 21,241,171,203,155, 94,230, 37, 61, 86,120,186,154,192,211,213, 4, 30, 46,198, 32,148,197,101, 34, 43, 59, + 59, 91,243,230, 44,209,163,159,133, 82,169,180, 92, 63,181,135, 38, 11, 11, 11,145,145,145, 1,149, 74, 85,213,131,140, 74, 75, + 75,187,124,226,196,137, 34, 0,248,241,199, 31,243, 8,130,248,147, 32,136,159, 42,249,236, 97, 50,153,119, 53,109, 55,109,218, +148,135,247,135,196,254, 78,124,237,237,237,157,191,120,241,226,157,179,103,207,198,158, 61,123, 32, 16, 8, 22,225,175, 92, 60, + 84, 78, 78,206,130, 93,187,118, 97,220,184,113, 88,190,124,249,166, 86,173, 90, 21, 2, 24, 89, 21,161,157,157,157, 51,147,201, + 68, 84, 84, 84, 33,128, 55, 53,172, 63, 35, 42, 42, 42,147, 32, 8,240,249,124,183,234, 26, 90, 91, 91, 55, 52, 51, 51, 67, 90, + 90, 26,160,126, 99,174, 4, 73,233,233,233, 52,135,195,129,147,147, 83,163,154, 54,222,202,202,106,193,129, 3, 7,152, 47, 94, +188, 64,247,238,221, 83,111,221,186,213, 19,128, 38, 36, 61, 42, 50, 50,210,183, 91,183,110, 47,175, 94,189,138,141, 27, 55, 18, + 45, 90,180,152, 86, 19,167,171,171,235,212,241,227,199, 35, 56, 56, 24,123,247,238,157, 6,224, 84,133, 38,199,118,237,218, 53, +107,239,222,189,152, 48, 97, 2,234,215,175, 63,178, 58,190,228,228,228,133,126,126,126,145,175, 94,189,210,169,226,129,142,237, +187,249,248,248, 52, 20,139,197, 56,116,232,208,155,134, 13, 27, 62, 58,117,234,212, 60,188,255,192,254,253,244,233,211, 24, 53, +106, 20, 90,180,104,113, 8,192, 8, 93, 46,203,216,216,216,148,235,215,175, 83,108, 54, 27,174,174,174,232,215,175, 31, 2, 2, + 2,208,188,121,115,200,229,114,156, 62,125,154,122,254,252,121,170, 76, 38,211, 41,151, 82,238,171,155,231, 19, 19,255,199,222, +121,135, 55, 85,253,127,252,125,179,119,210,180,105,210, 69, 75,129,210, 77,161, 64,217,163, 80,138, 64,153,162,136, 40, 34, 10, +200, 16, 21, 21, 84,134, 32, 75,217, 32,171,130,130, 8, 10,136,128,148,165,226, 23,100,211, 2,165,133,178,186,103,210,189,146, +102,159,223, 31,180,252, 74,237, 72, 90,220,247,245, 60,247, 73,114,110,238, 59,231,174,115,223,249,156,117,239,194,245, 43,231, + 76, 44, 38, 3,158,174,142, 24, 29,209, 9,175,141,237,133,206,254,238, 72,215,232,112,230,204, 79,166,212,212,228, 75,182,244, + 56,172,209, 76,186, 29,127, 49,241,250,121, 51,155, 69,193,223,175, 61,230,127,248,190,124,217,162,185, 14,237,219,122, 34, 62, +165, 20, 63,157, 62, 97,202,201,202,252,245,175,234,113,120, 22,224,136,121,148,136,201, 96,192,194,224, 85, 50,171, 59,210, 4, + 7, 6,250,170, 92, 92, 16, 19, 19, 3,134, 29, 61, 66,207, 2, 28,177,248, 81, 45,120, 69, 69, 5,106,244,218,249,249,249,121, +122,121,225,120, 76, 12,152, 86,235,157,126,118, 14, 48,122,247, 81, 53,244, 99, 93, 10,168,154,222, 10,146,118,173,148,126,114, +153, 8, 87,226, 31, 64,111, 34, 87,191, 41,198, 95, 58, 30,217, 31,200, 20, 52,179,234,112,213,182,109,219,194,118,236,216, 49, +232,157,119,222, 17, 79,156, 56, 17,124, 62, 31, 90,173, 22, 30, 30, 30,176, 88, 44, 56,121,242, 36, 98, 99, 99, 43,172, 86,235, + 79,248,253,176, 1, 17,168,213, 75,227, 84, 50, 4,143,252,150, 54,236,200,115,207, 61, 21, 77, 0, 16, 63,176, 74, 11, 91, 27, +246,108, 60,112,126,204,222, 83,215,169,183,198,247, 99,116,246,107, 5, 0, 80,169, 84,144, 74,165,118,107, 62, 5,254,112,205, +218,213,186,121,121,121,119,243,242,242, 52,175,191,254,186,127, 77,195,119, 30,143, 87, 85, 29,201, 42,174,111, 27, 27,242,105, + 4, 48,125,199,142, 29, 71, 75, 75, 75, 79,189,247,222,123, 88,182,108, 25,126,252,241,199, 62, 0, 46, 52,115,223, 45,197,197, +197, 37, 87,175, 94, 85,249, 4,132,162,141,146,141,190, 11,238,131, 16, 2, 39, 33, 65,121, 73, 17,110,220,184,142,242,242,242, + 43,246,228,211,104, 52,150,104, 52, 26,133, 82,169, 68, 81, 81, 17, 10, 10, 10, 30,155,172,226,226, 98, 20, 21, 21, 17,138,250, +221,152, 45,141,105, 86,106, 52, 26,109, 82, 82, 18, 87,213,202, 7,109,149, 28,116,251,240, 46, 64, 8, 60, 29, 25, 40, 47, 43, +193,165, 75,151, 80, 90, 90,250,191,134, 52,173, 86,235,156, 9, 19, 38, 48, 1,188,252,222,123,239, 57, 2,232,248,254,251,239, +255,132, 58, 61, 11, 89, 44,214,186, 61,123,246, 4,215, 84, 49,206,157, 59,119, 45,128, 29,127,214,181,228,228,228, 52, 39, 38, + 38, 70, 98, 52, 26,177,113,227, 70,172, 93,187,118, 39,126, 63, 80,101,204,231,159,127,190,153,193, 96,204,152, 57,115, 38,166, + 78,157, 42,236,210,165,203, 59,185,185,185,223,212,167,153,157,157, 61,191,115,231,206, 11, 53, 26,205,114,155,204,242,253,251, + 83, 58,119,238, 60, 95,163,209,124,214,216, 57, 18,137, 68, 34,139,197,130,212,212,212, 98,160,193,246, 29, 85,169,169,169,217, + 22,139,197, 67, 40, 20, 58, 54,117,125, 22, 23, 23, 47,239,210,165,203,199,106,181,250, 52,128,165,245, 24,242,155,185,185,185, + 65,179,103,207,158,181,114,229,202, 49,121,121,121,223, 54,165,153,158,158,190, 60, 60, 60,124,193,189,123,247,118,161,225, 42, +224,207, 23, 47, 94,108,220,179,103,207, 27,169,169,169, 43,154,208, 60, 86, 80, 80,112,204,142,243,219,208,247, 31,107, 50,153, +204,247, 87,174, 92,201,216,182,109, 27, 8, 33,171, 45, 22, 75, 67,249,140, 63,124,248,240,238, 94,189,122, 77, 60,112,224, 0, + 63, 40, 40,104,170, 94,175,223,215,212,245,169,213,106, 15, 29, 56,112, 96, 76,124,124,188,199,196,137, 19,249,190,190,190, 48, + 26,141,200,205,205,197,182,109,219,170, 18, 18, 18,178, 74, 74, 74, 14,217, 83,134,152, 13,101,227, 47,158, 57,178, 47,237,126, + 66,143,254,207,140,148, 27,140, 30,224, 21, 50, 81, 82,152,135,147,199, 14, 21,167,166, 38, 95,210,106, 75,198,219,163,105,212, +151,190,112,233,215,163,223,102,165, 38,117,239, 27, 62, 84, 94,101,240, 2,143,195, 64,161, 58, 27, 39, 99,142, 20,165,166,166, +252, 86,101,210,191,242, 87,149,243, 76,111, 44,101,230,197,190, 62,109,120, 39, 8,228, 30, 55,216,192,198, 94,128, 64,161, 82, +113,170,239, 29,136, 31,181,121,180, 73, 83, 13,112,125,170,107,169,180, 90, 45,216,128, 97, 18,192,118,118,118, 22, 0,192,189, +123,247, 32,124, 84,171, 97, 87, 62, 43, 0,145,176,150, 46, 3,208, 22,178,224,222, 78, 42,162, 0, 32, 43,175, 16, 6, 83,163, +207,141,127, 58,209,181, 12, 87,116,115, 4, 56, 0, 34,196, 98,241,178,133, 11, 23,174,190,114,229,202,234,168,168,168,213, 60, + 30,111, 89,245,193,230, 52,114, 34,254, 52,205,174,110,112, 12,111, 75,157,139,108, 71, 89,167,245,145, 91, 94,233, 38, 50, 12, + 24, 48, 96,115, 11,243,217,146,155,229,143,212, 60, 98, 50,153, 8, 30, 85,219, 29, 65,195, 85,130, 31,212, 90,159,151,145,145, + 65,170,223,219,147, 79,197,184,113,227,172,229,229,229,228,249,231,159, 39,104,122, 10,159, 70, 53,121, 60, 94,120,223,190,125, + 77,234,252, 34,114, 55, 37,155, 92,142,187, 77, 78,157,185, 72,190, 61, 20, 67, 54,109,222, 78, 66, 66, 66, 12, 0,188,236,209, +100,177, 88, 3,194,195,195, 11,213,106, 53, 73, 74, 74, 34,231,206,157, 35, 7, 15, 30, 36,219,183,111, 39, 91,183,110, 37,173, + 90,181, 82, 3, 80,217,163, 41, 16, 8, 70, 14, 25, 50,196, 84, 82,166, 37,169,217,133,228, 86, 82, 42,185,112,245, 22, 57,121, +230, 2,249,102,223, 1, 18, 24, 24, 88,101,131, 38,147,201,100,110,250,246,219,111,203, 8, 33,100,228,200,145, 89,120,114, 32, +213, 54,115,230,204,209, 16, 66,200,103,159,125, 86,136,250, 27,194,255,209,215,210, 51,238,238,238,119, 57, 28, 78, 12,128,151, +155,216,238, 5, 22,139,245,163,139,139,203, 53, 0,163,255,130,251, 40, 74,169, 84, 94, 6,208,212, 12, 7, 53,223, 27,245, 47, +185,223,255, 8,205, 1, 44, 22,235, 28,208,248, 36,194,181,202,235, 79,152, 76,230,113, 0, 3,237,204,103,123,133, 66,241,188, + 92, 46,127, 75, 46,151,191,165, 84, 42,159,231,114,185,237, 91,178,239, 78,237, 35,134,123,134,142, 56,220,170,227,176,116,207, + 78, 81,233,222,157, 71, 30,118,106, 31, 49,188,165,154, 94,157, 71, 30,241,236, 20,149,225,217,105,120, 90,155,174, 35, 15, 43, +252, 34,134,252,149,231,232,101,119,184, 13,106, 3, 51, 57,183,128,144,115, 11, 72, 68, 27, 88,123, 56, 32, 48, 12,144, 12,142, +136, 88, 67, 44,150, 53, 99, 70,141, 90,227, 3, 56, 17,128, 89,119,169, 79, 51, 20,144, 62,222,118,228,200, 53,109, 1,197, 32, + 64,216,175, 79,159,213,196, 98, 89, 51,225,133, 23,214,120, 2, 46,245,233, 53,164, 73, 0,166, 59,224, 86, 91, 87, 1,180, 27, +235,141,160, 15,134,123, 19,114,110, 1, 89,252,156, 47,233,172,194,203, 77,104, 54, 20, 41,250, 71, 71,180,236, 69, 84, 93,184, +174,168,126, 21, 61,133,139,240,169,107,118,119,133,111, 68, 59, 42,105,168, 31,171, 8,143,186, 36,139,254,133,133,228, 46,131, +193, 64,170,170,170,136, 86,171, 37, 21, 21, 21,117, 13,212, 99, 67,150,147,147, 67,178,178,178, 72, 70, 70, 6, 73, 75, 75, 35, +248,255,182, 55, 54,231, 83, 42,149,238,120,238,185,231, 44,108, 54,123,211,211,216,119, 71, 71,199, 21,221,186,117, 51,110,216, +176,129, 28, 62,124,152,124,241,197, 23,100,230,204,153, 36, 56, 56, 88,239,224,224, 48,190, 57,154, 46, 46, 46,243,253,252,252, + 10,119,238,220, 73,190,249,230, 27,178,126,253,122,242,209, 71, 31, 89, 60, 60, 60,242, 36, 18,201,224,230,104, 42,149,202,232, +222,189,123, 27,163,163,163,201, 79, 63,253, 68,246,238,221, 75,230,204,153, 67,252,253,253,245, 34,145,232, 89, 27, 53,153, 44, + 22,107,205,180,105,211,242,220,220,220, 98,234,172, 19, 6, 6, 6, 94,155, 48, 97, 66, 14,128,185,255,162,235,147,214,164, 53, +105,205, 63,192,104,189,232, 6,119, 2, 48,133, 28,206, 11,253,250,244, 89,205, 1, 94,176,215, 20,241,153,204,177,189,186,117, + 91,205, 1,198,215,124,151,207,100,142,237,215,167,207,106, 54,147,249, 82, 67,122,141,105, 18,128,201, 97,177,230,246,234,209, + 99, 13, 11,248,176, 38,109, 64, 27,234,206,156,103, 90,145, 62, 94,212,131,151,148, 16,254,139,141,214, 83,135,245, 7, 92,132, +255, 20,205,191,203, 77,237, 83,109,152,142,216, 17,209, 58,130, 71,179,168,251, 52, 51,159,130,167,188,239, 29, 20, 10,197, 9, + 31, 31,159,252,214,173, 91,231,200,229,242,125, 0, 60, 90,168, 25,228,226,226,242,181, 74,165,186,239,234,234, 26,175, 80, 40, +214,225,209,168,243,205,214,100,179,217,221, 84, 42,213,255,188,189,189, 75,188,188,188,212, 10,133,226,219,122, 34, 89,182,104, +186,162,254, 66,133, 83,189,142,126,232,208,154,180, 38,173,249,132,129,137,108,139,149,131,218,192, 60,168, 13, 44,145,222, 88, + 87,219,160, 68, 1,130,230,154,162, 87, 0, 94,221,239, 55,165,215,148, 38, 1,152, 61, 1,113,221,109,134,122, 32,208, 70,205, +127,122, 68,171,166,156,183,111,120,135, 6, 48,255, 1,153,252,167,104,254, 93,120,128, 70, 26, 35,215, 98,197, 83,252, 77,221, + 83,222,135, 91, 5, 5, 5, 67, 10, 10,158,106,223,132,196,188,188,188,151,159,166,160,201,100,186,162, 86,171,251, 63, 5,169, +134,186, 94, 27, 97, 99,183,108, 26, 26,154,255, 14, 20, 96, 65, 50,230, 69,180,199, 70,150, 5,140,147, 41,200,174,211, 37, 79, + 71, 53, 71,243, 17,150, 93,245,148,241, 84,115,243,249,255, 84,252, 78, 35, 11,183,169,255,206,105,203,197,163, 54, 90, 45, 54, + 90, 52, 52, 52, 52, 52, 52, 52,127, 2, 63,223,167,255,136,253, 3,136,193,147,209,183,152, 90, 70,180,193,208,167, 61, 61, 41, +154, 19, 62,253,153,214,164, 53,105, 77, 90,147,214,164, 53,105,205,255,156,102, 13, 13,205,157,122,183,206,231,102,245,226,251, +175, 64,215,179,211,154,180, 38,173, 73,107,210,154,180, 38,173,249,111,167,217,227,104,209,208,208,208,208,208,208,208,208, 52, + 78,131, 81, 55,218,104,209,208,208,208,208,208,208,208,180, 12, 87, 60,154,162, 42, 6,255, 63, 85, 85, 52,208,244, 20, 60, 79, +176,114,229, 74,134,143,143,143,152,203,229, 6, 39, 39, 39, 51,166, 79,159,222,226,142, 4,171,215,109, 98,120,121,121,137, 1, + 4, 23, 22,151, 51, 94,125,237, 61,138, 62, 95, 52, 52, 52, 52, 52, 52, 52,255, 32,134, 85, 27,171,154,215,199, 17, 46,187,140, +214,210,165, 75,145,145,145, 33, 2, 48, 46, 40, 40,136,187,101,203, 22,178,127,255,254, 22, 25,163, 15,231,206, 65,122,122,186, + 8,192, 56,165,194,129,251,229,142, 85,228,192,143,231,159,186,217, 82, 40, 20, 78,127,230,118, 52, 52, 52, 52, 52, 52, 52,255, + 41,166,212,122,157,210, 44,163,197, 98,177,152, 92, 46,183, 45,131,193, 24,194,231,243,187, 2, 64,245,148, 44,205,134,197, 98, + 49,185, 60, 94, 91, 38,147, 57,132,199,123,164,249,220,240,222, 45,213, 28, 40, 18,137, 50,133, 66, 97, 44, 0,129, 68, 34,185, +110, 52, 26,111, 75, 36,146,139,246,232, 72, 36,146,139,213,219, 93, 7, 32, 16, 10,133,177, 34,145, 40,147,197, 98, 13,164,175, + 39, 26, 26, 26, 26, 26, 26,154,106,162,235, 89,126,207,177, 99,199, 26, 52, 56, 92, 46,151, 17, 20, 20,212,219,203,203,235, 66, + 64, 64,128,193,195,195,227,160, 80, 40, 20,181, 48, 99, 12, 31, 95,255,222,110,174,170, 11,157,218,186, 26,148, 74,229, 65, 54, +155,221, 18, 77,166, 68, 34, 89, 31, 25, 25, 89,122,225,194, 5, 34,149, 74,213, 0, 28,156,157,157,115, 8, 33,196,197,197,197, +106,143,152,139,139,139,149, 16, 66,156,157,157,115, 0, 56, 72,165, 82,245,133, 11, 23, 72,100,100,100,169, 68, 34, 89,143,166, + 71,180,165,161,161,161,161,161,161,177,131,198,188,200,223,152,154, 40,150,107,179,119,142,203,229,134, 42, 20,138,132,183,223, +126,219, 18, 29, 29, 77,188,188,188,174, 42,149,202, 30, 10,133,226,137, 6,245,147, 38, 77,178,167,218, 47, 84, 34,149, 37,236, +154,253,140, 69,247,229, 72,226,238,170,188,234,224,224,208, 67, 42,149, 62,161, 57,225,213,169,182,104,186,156, 17,217,210, 0, + 0, 32, 0, 73, 68, 65, 84,201,100,178,248,149, 43, 87, 86,149,148,148, 16, 66, 8,145,201,100,106, 0,114,149, 74,149,147,146, +146, 66, 20, 10, 5,129,237, 81, 60,134, 66,161, 32, 41, 41, 41, 68,165, 82,229, 0,144,203,100, 50, 53, 33,132,148,148,148,144, +149, 43, 87, 86,201,100,178,120, 0,110,244,109, 65, 67, 67, 67, 67, 67,243,159, 54, 90,117, 13,151,109, 85,135, 93,187,118,229, +169, 84,170, 30, 18,137,100,148, 88, 44,222, 60, 98,196,136,160, 49, 99,198, 48,244,122,189, 37, 40, 40,200,205,219,219,123,150, + 92, 46,127,153,207,231,135,112,185,220,151,164, 82,169,235,190,125,251,124, 26,211,236,208,177, 11,207,193, 65,222,131,203,229, +141, 18,139, 37,155,167,141, 29, 16,244,242, 59,207, 50, 56,134, 52,203,128, 16, 79,183,224,182,174,179, 92,228,162,151, 89, 76, + 70, 8, 69, 81, 47,241,249,124,215,111,190,220,238,211,196,142,181,117,115,115,187,190,111,223,190,224,113,227,198,241,146,146, +146, 0, 0, 22,139,133, 11,192,196,100, 50,193,227,241, 96, 52, 26,139, 1,216,122, 2,137,209,104, 44,230,241,120, 96, 50,153, + 0, 96,170,214, 67, 82, 82, 18,198,141, 27,199,219,183,111, 95,176,155,155,219,117, 0,109,233, 91,131,134,134,134,134,134,230, + 63, 75,141,185,138, 65,157,170, 67, 86,141,123,140,138,138,122, 34,106,196,229,114,183,220,187,119,175,151,163,163, 99, 91, 54, +155,109,121,225,133, 23,120, 19, 38, 76, 64,126,126,190,181,162,162,130, 25, 26, 26,170,186,118,237,218, 16,179,217,220,199,193, +193, 65, 91, 82, 82,162,208,235,245, 15, 0,204,106, 36, 35, 91,238,223, 77,232,229, 36,119,108,203,101, 51, 45, 51, 39, 79,224, +125, 56,247, 25, 80,250, 56,171, 69, 83,200,252,164,179,131,106,221,197,202, 33,247,140,150, 62,149, 50,190, 54,175, 84,223,164, +166, 66,161,232,204,225,112, 98, 79,156, 56, 1,161, 80,136,210,210, 82,112,185, 92, 0, 64, 69, 69,133, 12, 0,139,162, 40,112, +185, 92,148,149,149,201,237, 57,106,101,101,101,114, 46,151, 11,138,162, 0,128, 85,173, 7, 46,151,139,210,210, 82,248,248,248, + 80, 39, 78,156, 80, 14, 25, 50,228,161,209,104,236, 82, 80, 80, 16, 71, 95,107, 52, 52, 52, 52, 52, 52,246, 83,159, 23,249, 7, +209,228, 56, 90,253,171, 67,117,181, 39,206,221,237,236,236,236, 34, 22,139, 3,166, 76,153,194, 80, 40, 20,136,141,141,181, 86, + 86, 86, 50,216,108, 54,216,108, 54,115,192,128, 1, 98,179,217, 44, 60,126,252, 56,245,240,225,195,124,147,201,244, 73, 97, 97, +225,181, 70, 50,178,187,157, 3,207, 69,224,192, 13,248,241,189,190, 12,103,159, 66,224,212, 98, 43,169,208, 48, 88, 86, 2,133, +200,202, 92,211,135, 18,231,201,188,133, 51,191,205,167,126,123, 88,146,111, 50,153, 62, 41, 47, 47,111, 76, 51, 27, 0,170,243, + 4,169, 84, 10,139,165,246,252,150, 32, 12, 6, 3, 60, 30,175, 89, 71,142,199,227,129,193, 96, 0,181, 34, 97, 50,153, 12, 76, + 38, 19, 12, 6, 3,108, 54,251,137,124,208,208,208,208,208,208,208, 52,139,250,188,200, 63,133,218,227,104,217, 54, 55,165, 74, +165,162,164, 82,169,107,199,142, 29, 63,142,140,140, 76, 25, 61,122,180,118,195,134, 13,100,237,218,181,100,205,154, 53,100,231, +206,157,150, 95,127,253,213,244,218,107,175, 85,181,111,223,254,193,230,205,155, 3, 0, 96,232,208,161, 13, 86, 71, 58,200, 29, + 41, 49,151,229, 26, 24,208,225,227, 23,251, 7,167, 44, 24,229,171, 53,238, 10, 37,214,133,173,136,101,147, 55,177, 28, 24,104, + 33,247, 86,153,150,191, 62,176,170,181, 87,235, 7, 91,119,126, 23, 0, 0, 17,145, 67, 27,173,226, 84, 40, 20, 93, 61, 60, 60, +212,167, 79,159,182, 22, 23, 23,147,194,194,194,154, 54, 90, 37, 0,100, 94, 94, 94, 57,102,179,153,200,229,242, 34,123,142,154, + 92, 46, 47, 50,155,205,196,203,203, 43,231,145,191,146,149, 16, 66, 72, 97, 97, 33, 41, 46, 46, 38,167, 79,159,182,122,120,120, +168, 21, 10, 69, 87,250,254,160,161,161,161,161,161,249,207, 50,165,206,107,211,244,234,213,139,146, 74,165,140, 14, 29, 58,136, +221,220,220,186,187,185,185, 93, 89,183,110, 29, 89,187,118,173,121,219,182,109,228,235,175,191, 54,191,242,202, 43,101, 34,145, + 40,134,203,229,202, 1,192,219,219,187,209,144, 95,215,238, 61, 40, 1,159,199,240,243, 11, 20, 43,156,156,186, 59, 59, 57, 94, + 49,174, 13, 38,100,177,187,153,236,232, 68,200,129,103,204,171,158, 15, 43, 99,179, 57, 49, 0,228, 0,224,225,230,106,107, 24, +209, 77,169, 84,198, 47, 94,188,184,210,104, 52,146,234, 94,134,106, 0, 14, 94, 94, 94, 57,132, 16,226,225,225,145, 9, 64, 97, +163,158,194,195,195, 35,147, 16, 82, 99,180, 28, 92, 92, 92,212,132, 16, 98, 52, 26,201,226,197,139, 43,149, 74, 37,221, 24,158, +134,134,134,134,134,134,166,193,185, 14, 27,140, 20, 93,184,112,129,148,149,149, 89,179,179,179, 45, 21, 21, 21,210,208,208, 80, + 57,147,201,132, 74,165, 98, 50,153, 76,107,101,101, 37, 83,161, 80,228,176,217,236,111, 12, 6, 67,241,168, 81,163,168,212,212, +212, 70, 27,154, 95,187,124,137,232,170,244,214,172,172, 76,139,182,162, 76,250,114,136,163,156,101, 54,194, 26,218,139, 89, 38, +104,111,181,234,138,153,254,174,188, 28, 14,135,253, 13,128,226,209, 81,195,168,172,156, 92, 91, 27,175,231,104, 52,154,208, 45, + 91,182,236,232,219,183,111,177, 86,171,173,105, 91, 85,119, 8, 6, 7, 27,245,234,126,143, 73, 81, 20,180, 90, 45,250,246,237, + 91,188,101,203,150, 29, 26,141, 38, 20, 64, 14,125,125,209,208,208,208,208,208,252,167,105,112, 28,173, 38,135, 58,208,106,181, +114, 14,135, 19, 17, 22, 22,214,186,178,178,210,186,116,233,210,204, 13, 27, 54,236,121,240,224,129,201,193,193,161,173, 64, 32, +120,107,220,184,113,138,195,135, 15,147, 62,125,250,212,141, 62,213, 59,187,183, 78, 87, 33,231,113,216, 17,111,117,147,180,206, + 52,202,173, 1,111, 93,205,236,183,240,226,158, 31, 18, 89,166, 14,142,186,182,142, 92,234,173,113,227,158, 87,252,112, 44,134, +244,232,209,221, 38,205,106, 44, 26,141,230,173,216,216,216,231,219,180,105,147,101, 50,153,178, 0, 20,234,116, 58,181,155,155, +155,198,104, 52,102, 1, 48,214,179, 93,125,154, 70,163,209,152,229,230,230,166,209,233,116,106, 0,133, 38,147, 41,171, 77,155, + 54, 89,177,177,177,207,107, 52,154,183, 0, 88, 26,201, 11, 61,171, 59,173, 73,107,210,154,180, 38,173, 73,107,254,119,248, 93, + 52, 11,176, 97, 82,105, 30,143,215,215,211,211,179,119, 98, 98,162,229,210,165, 75,165, 12, 6, 99,235,208,161, 67, 15, 30, 58, +116,168,155,163,163,163,178, 85,171, 86,170, 95,126,249, 37, 28,192,254,223,126,251,205,166,232,147,128,199,233,219,201, 67,214, + 59,250, 38,177,124, 25,123,191,212,194,228,109, 29,240,236,179, 7,223,220,179,183,155,155, 66,162,236,228, 42, 85, 29, 63,126, + 50, 28,192,254, 75,151, 46,219, 61,158,134,217,108,254, 69,163,209,180,170,249,156,159,159, 31,170, 80, 40, 2,240, 40,250, 84, +106,163, 76,186,213,106, 29,106,181, 90,221, 10, 10, 10,238, 0, 64, 65, 65, 65, 23,250, 58,162,161,161,161,161,161,161,169,199, +100, 69,215,247,185,209,136, 22,151,203,117,103, 50,153,129, 89, 89, 89,233,199,143, 31, 79,236,218,181,235,144,244,244,244,149, +132,144, 52,161, 80, 56, 37, 51, 51,243,126,102,102,166, 65,167,211, 77,179, 35, 51,238, 96,112, 2, 99,115,116,233,159,254,114, + 59,177, 67,143,193, 67,242,242,114, 86, 90, 8, 73,227, 10,165, 83,238,101,228,223,191,172,209, 27,170,170,236,210,108,146,130, +130,130, 59, 5, 5, 5,165,118,110, 83, 90, 99,178,104,104,104,104,104,104,104,104,236,165,169,136,150,209, 98,177,172,210,235, +245,242, 31,126,248, 33, 59, 50, 50, 82, 15, 0, 91,182,108,177, 78,158, 60,249,124,114,114,242,192, 59,119,238, 12,113,113,113, + 57, 3,128, 74, 73, 73,177, 37,250,100,180, 90, 45,171, 12, 6,189,252,151, 95,227,178,251,246,238,160, 7,128,109,159,111,180, +190, 48,101,246,249,228,164,196,129,247, 18,174, 15,113,113,113, 57, 99, 49,179,168,220,188, 52, 66,159, 38, 26, 26, 26, 26, 26, + 26,154,191, 49,209,120,178,202, 48,218, 38,163,101, 48, 24,242, 13, 6, 3, 0, 20, 71, 70, 70, 62,177,110,231,206,157, 4, 64, + 37,128, 3,133,133,133,246,100, 38, 95,167,211, 1, 64,113,223,222, 29,158, 88,241,109,244,134,199,154, 21,229,101,244,105,163, +161,161,161,161,161,161,249, 39,153,173,223,193,160,143, 11, 13, 13, 13, 13, 13, 13, 13, 77,139,152,210,208,103, 10, 13,247, 28, +248,217,142, 31,104, 78,239,131,159,105, 77, 90,147,214,164, 53,105, 77, 90,147,214,252,207,105, 54,165,253, 51,254,121, 52,216, + 24,254,143,134,238,250, 74,107,210,154,180, 38,173, 73,107,210,154,180,230,191, 29, 87, 60, 57,188,131,107,205, 10, 22,125,108, +104,104,254,217,144, 3, 96,162,216,207, 27,132,184,129,201,205, 69,238,173,100,234, 99, 88, 91,172,169, 14,244,130,192,164,130, +153,159, 15,117,124, 74, 75, 53,105,104,104,254,125,184,244,156, 62,154, 98, 48,183, 82,196, 10,157, 58,137,199,209,165, 9, 53, +185,233,255, 69,111,145,139, 6, 34, 88,180,209,162,161,249,167,147,239,239, 11, 22, 86,128, 1, 87, 16,227, 67, 56, 7,174, 0, +110, 39,180, 88,147, 99, 93, 10, 11,195, 3,196,120, 15, 74,191,149,192,221,219,244,193,254,247, 49,107,230, 27,228, 78,194, 21, +100,100,228,160,109, 59, 87,248,250,247,196,134,141,155, 41,250,200,208,216,246,175,140,138,142, 24, 62,193, 81, 32,148, 0, 0, +172,102, 19,118,190,211,233, 39,179,217,188, 27,192, 97, 0,186,255,250, 33,250,211, 27,195,179,217,108, 53, 0, 43,159,207, 63, +132, 90,161, 53, 26,154, 63, 0,215,234,235,204, 90,125,221,217,131,152,197, 98, 45, 20, 10,133,191,242,120, 60, 13,143,199,211, +136, 68,162, 95, 89, 44,214, 66, 0,226,191, 77, 25,247,117,176, 16, 12,203, 16,131,201,234,126,242, 86,137, 82,171,183,248,130, + 97, 30, 74,118,182, 23,183, 72,147, 69, 69, 86, 25,173,158,223, 92,213,170, 42, 13,230, 0, 16,180, 72,179, 22, 14, 28, 14,231, + 36,108,159,115,148,230, 15, 38, 61, 37, 1,199,143,173,193,210, 37, 19,241, 85,244, 52,220,189,115,185, 69,122, 1, 64,151, 46, + 44,214,187,254,192, 0, 60,106, 7, 76,243,111,134, 34, 83,126,254,241,155,252, 31,247,125,158,255,221,154,105,228,200,138, 40, +108,220,184, 49, 98,226,196,137,223,120,122,122,230, 3,120,142, 54, 90,127, 50, 38,147, 73, 89, 80, 80, 64,237,222,189,123,132, + 76, 38,123,200, 98,177, 62, 0,192,249,175, 28,112,177, 88,124, 81, 42,149,170,101, 50,153, 90, 42,149, 94,111, 42,253, 95,138, +175,179,179,115,186,163,163,227,189,218,137,206, 33,163,123,250,244,122,121,145, 83,224,200,126, 45,212,231,176, 88,172, 15,100, + 50,217,195,221,187,119,143,200,206,206,166, 76, 38,147,210,142,237,251,202,229,242, 59, 87,174, 92, 89, 80, 80, 80,208, 47,243, +242, 78,231,188, 43,219,157,211,255,183,166,127,236,241, 77, 11, 28, 28,100,183, 1,244,253, 91, 28,201, 42,171, 10, 12,102,120, + 98,174, 86,152, 91,102, 82,197,165,105, 37, 0,179, 63, 12, 45,248, 19, 83,106, 85, 1,100,192,205, 44,157,232, 98,145,179,234, +183,100,189, 20, 12, 70, 56,170, 40,151, 22, 23, 56, 12,198, 27, 86,171,117, 16,135,195,121,139,126, 66,253, 61,224,241, 56, 0, + 33, 16,139,248, 0, 8, 24, 45,180, 70, 92, 6,163,215,197, 17, 35,150,206, 13, 9,153,229, 15, 12,111,192,108, 81, 0,222,244, +247,247, 63, 1,224,133,167,184, 59,159,250,249,249,101, 3,152,253,180,202,165,206,157, 59,247, 12, 15, 15, 95,212,169, 83,167, +126, 79, 75,243,223, 68,222,197, 45, 63,228,158,223,164,204,185,176, 89, 89,146,114,238, 77, 87,149,220,154,146,146,130, 97,195, +134,225,243,207, 63, 23, 6, 5, 5,237, 1,224,246, 31,184,149, 66,107,254,224,163, 78, 27, 45,155,141,214, 88,111,244, 26,223, + 6,103,159,247, 70,249,184, 54,168,120,169, 13,206, 63,235,141, 1,205,201,141,147,147, 19,250,246,237,203,204,206,206, 22,204, +153, 51,103, 17,159,207, 79, 5, 48,184, 57, 90, 2,129, 32, 86, 40, 20,102,178, 88,172, 39,242, 34, 20, 10, 99, 69, 34, 81, 38, +139,197, 26, 88, 59, 93, 34,145, 92,148, 74,165,106,137, 68,114,189, 1, 35, 20, 43,149, 74,213, 98,177, 56,182,118, 58,139,197, + 26, 40, 22,139,179, 36, 18, 73,221,244, 1, 18,137, 36,179,110,122, 67,176,217,108,143,204,204, 76,101, 86, 86,150,146,203,229, +170,106,167,103,100,100, 40, 51, 51, 51,159, 72,183, 7, 22,139, 53, 64, 36, 18,101, 10,133,194,216,250,210,235,238, 83, 67,212, + 58,118, 3,108, 73,183,183,224,137,140,140, 60,159,155,155,235,233,224,224,240,196,196,221,142, 50,135,193, 95,239,220,252,206, +200,161,145,111, 56, 7,140,234,208, 76,253,193,124, 62, 63,117,206,156, 57,139,178,179,179, 5, 61,122,244, 96, 50, 24,118,253, +159,136, 24, 57,114,228, 17,181, 90,237,222,177, 99, 71,166,217,108, 70,226,209,133, 16,198,191, 5,126,234, 54,180, 18,228,179, + 30,254,180,210, 35,178,127,151, 35,248,139, 27,131,146, 3, 1, 28, 80,214,190, 86, 66,156,239,100, 87, 57, 15, 27,241, 28,235, + 70,166,206,217,100,177, 56, 2,204,254,228, 43, 47, 94,179, 52, 89,166, 62, 86, 66, 84,191,164,177,157,195,159,159,197, 60,147, +198,114, 54, 89, 44, 78, 96,160, 95,115, 52,107, 95,254, 76, 38,243,157, 53,107,214, 48, 0,204, 4,192,253, 47, 25,154, 48, 55, +184, 15,104,199,188, 26,234,138, 94, 79, 81, 54,168,250,126,247,109,169,208,142,175, 78, 96,242,212,104,180,247,239,222, 34, 29, +131,213,122,247,219,148,148, 83, 47,181,107, 23, 53, 55, 36,100, 82, 61,102,139, 2, 48,119,229,202,149, 47, 39, 38, 38, 58,183, +105,211,102,234, 83,250,211,191,126,229,202,149,239, 39, 38, 38,186,121,123,123, 47,182, 83,179,193,114, 73, 46,151, 15,222,177, + 99,199, 59,195,134, 13,123,163,115,231,206, 29,158,134,230,191,152,207,111,222,188,233,185,102,205,154,121,147, 39, 79, 46, 3, +128,129, 3, 7,114, 0,244,104,113,121, 71, 8,151, 16, 18, 78, 8, 25, 70, 8, 25, 72, 8, 9,171,126,223,181,122, 25, 70, 8, +137,168,243,218,181,122,219,154,245,221, 26,208, 24, 86,119,187, 90,219,212,253,252,196,251,122,140,214, 48, 60,106,171, 53,236, +137, 29, 56,118,236, 24,169,253, 90,151,113,222,248,120, 86, 79,119,237,157, 31,247,146,138,204, 20, 82,156,116,131,220,136, 94, + 78,102,117,117,214,190,216, 6,159,218,127,188, 8,185,112,225, 2, 73, 76, 76, 36, 21, 21, 21,228,254,253,251,164, 91,183,110, + 58,161, 80,248, 11, 0,111,123,196, 36, 18,137,250,151, 95,126, 33,145,145,145,165, 98,177,120,117,205,205, 37,149, 74,213, 23, + 46, 92, 32,145,145,145,165, 18,137,100, 61, 0, 38, 0, 60,251,236,179, 26, 66, 8,113,118,118,206,169, 79,111,228,200,145,197, +132, 16, 34,147,201,106,170,154,152, 18,137,100,253,140, 25, 51, 42,174, 93,187, 70,228,114,121, 77, 58, 67, 42,149,174,158, 57, +115,102, 69, 92, 92, 92,237,244, 70,113,116,116,204,180, 88, 44,228,199, 31,127, 36, 74,165, 50,167,214,205,156,105,177, 88,200, +145, 35, 71, 26,204, 91, 99,129, 2,177, 88,188,234,165,151, 94, 42, 79, 75, 75, 35, 78, 78, 78,234, 90,233,171, 39, 78,156, 88, +158,145,145, 65, 20, 10,133, 77,121,116,114,114, 82, 95,188,120,145,140, 25, 51,166,172,246, 49,117,114,114, 82, 95,186,116,169, + 38,125,149, 45, 5,153,155,155,219, 84,165, 82,153,163, 84, 42,115, 28, 28, 28,150,185,186,186,230,229,231,231, 19, 66, 8,105, +219,182,173,166,118, 36, 75, 25, 52,226,237,109, 7, 46, 93, 57,151, 80,152, 31, 50,232,141, 85,178,144,145, 50, 59,142,129,183, + 80, 40,252,165, 95,191,126,186,204,204, 76, 82, 89, 89, 73,226,227,227,201,133, 11, 23,200,131, 7, 15, 8, 0, 91,102, 24,144, +136,197,226,108,189, 94,111,213,235,245,214,252,252,124,139, 70,163,177, 36,173,118, 37,228, 75,246,227,165,228,200,112,146,119, +110,133, 85, 42, 22,102, 1,144,252,101, 70,107,115,160, 7,217,238,247,237,237,133,158, 73,231, 86, 62, 99, 34,105,103,200,222, + 73,206,166,179,111,187, 63, 36, 91,253,191, 39,219, 3, 90, 53, 75,115,107,192,222,248,143, 60,239,110, 90,252,166, 41, 61, 61, +157,188, 59,241, 25,243,233, 89,238,201,100,155,255,129,230,104,214, 98,252,232,209,163, 43, 50, 50, 50, 72, 96, 96, 96, 37,147, +201,156,252, 95, 50, 89, 17,190,220,236,248,111,222,181, 14, 15, 18, 22, 62, 37,179, 21,164, 84, 42, 11,118,237,218, 69, 36, 18, +137,166,185,102,107,236,168,254, 68, 87,250, 11, 25, 21, 21,214,232, 61,242,252,243,207,147,240,240,112, 50,107,214,172,166,238, + 37,202, 31, 24,177, 59, 36,228,136,117,236, 88,203,238,144,144, 35,254,192,136,106,131, 69, 1,152,247,217,103,159,197,153, 76, +166,184,175,190,250, 42,110,196,136, 17,113, 0,222,109,225,177,216,240,233,167,159, 18,147,201, 68,190,250,234, 43, 50, 98,196, + 8, 2, 96, 99, 75,202,165,154, 72, 86,104,104,232,219,135, 15, 31,190,114,247,238,221,252,168,168,168, 85, 33, 33, 33,178,230, +106,254, 29, 17,139,197, 62, 29, 58,116,216, 19, 24, 24,152,209,177, 99, 71, 67, 64, 64, 64,149,175,175,111, 90, 80, 80,208, 46, + 30,143,231,221, 76,217,238,189,122,245,178,156, 61,123,150,140, 30, 61,154,212, 50, 33,141,210,152, 23, 33,132,132,205,155, 55, +239, 3, 0,100,222,188,121, 31, 16, 66,134, 85,251,137, 97,181,223,215,125,173, 49, 79, 53,159,235,211,168, 89,234,211,172,239, + 55,234,252, 14, 26,136,100, 77,249,221,206, 29, 59,118,172,223,177, 99,199,206,214,221,185,231,218,160,231,172,158,238, 58, 93, +126, 46, 73, 88,254, 22,249, 53,220,131, 92,232,239, 66,238,189, 51,154,228,126,179,158, 76,239, 36,215,142,109,131,112,123,141, + 86, 92, 92, 28,137,139,139, 35,215,175, 95, 39,169,169,169,164,180,180,148,124,247,221,119, 22, 39, 39, 39, 29,143,199, 91, 9, + 64, 96,139,152, 84, 42, 85, 19, 66,136, 94,175, 39,203,150, 45,171,170,142, 84,169,100, 50,153,154, 16, 66, 74, 74, 74,200,202, +149, 43,171,100, 50, 89, 60, 0, 55,133, 66,145,153,146,146, 66, 84, 42, 85,189,102, 70, 46,151,171,239,222,189, 91, 99,156,220, +229,114,121,194,209,163, 71,141,132, 16,146,149,149, 69, 28, 29, 29,213, 0, 84, 78, 78, 78, 55,142, 29, 59,102, 36,132,144,156, +156,156,154,116,155,140,150, 78,167, 35,167, 79,159,126, 34, 15, 53,233, 39, 78,156,120,194,128,217,128, 74, 38,147,197,125,247, +221,119, 6,139,197, 66, 18, 18, 18,106, 76,162,202,193,193,225,250,129, 3, 7, 12, 22,139,133, 36, 37, 37,217,108, 6, 91,183, +110,173, 33,132, 16,179,217, 76,182,109,219,166,175, 57,166, 53,233, 6,131,129,108,217,178, 69, 47,149, 74,227, 0, 52, 26,125, + 83, 40, 20, 57, 6,131,129,148,148,148,144,110,221,186, 85, 92,184,112,129,148,149,149, 17, 66, 8,105,221,186,181, 6, 0,252, +250, 77,254,228,202,253,138,178, 87,223,223,188,223, 59,236,197,229,167,174,102,103,237, 56, 28, 27,167, 8, 26,249,140, 45, 65, + 77, 30,143,183,210,213,213,181,234,183,223,126,179, 24,141, 70,146,145,145, 65,174, 95,191,254,248, 26,187,117,235,150, 77, 70, +139,197, 98, 45,188,114,229,138,209, 98,177, 88, 11, 10, 10, 44, 26,141,198,162,209,104,204,117,141, 22,249,146, 77, 10, 78,188, + 78, 98,162,103, 27, 56, 28,206,194,191, 38,154, 5, 38,217,238, 55,146,108,247,139,219,245,146,162,160,252,250, 62, 66,126,154, + 77,146, 63,105, 67, 22, 62, 35, 41,183,110,247,139, 35,219,253,199,146,143,251,177,236,210,140, 14, 24, 78,182,251,197,125,250, +156, 87,225,141,184,107,228,236,217,179,100,203,250,207,200,172, 8,247, 74,235,118,191, 56,178, 53, 96,140, 61,154,181,225,241, +120,247,207,159, 63, 79,206,157, 59, 71, 22, 47, 94, 76,132, 66, 97,198,211,136,234,145,173,190, 94,228, 11,223,126,100,103,123, + 87,242,191,126,127,187, 14, 62, 97,110,112, 31,228,203,205, 42,184,113,152,144,162, 7, 36,111,117, 32,121,198,143,221, 82,179, + 21,164, 84, 42,243,211,210,210, 72, 94, 94, 30, 89,187,118, 45,145, 74,165,205, 50, 91, 99, 71,245, 39,186,146,159, 27, 53, 90, + 35, 71,142, 36,235,214,173, 35, 38,147,137,116,239,222,221,150, 63, 45,191, 51, 91,126,192, 72, 0, 31,172, 90,181,234,177,201, +218,188,121,115,220,173, 91,183,226, 60, 61, 61,143,183,224, 88,108, 92,181,106,213, 99,147,181,121,243,102,114,235,214, 45,226, +229,229,149,217,146,114,105,208,160, 65,159,164,166,166,150,205,159, 63,127,127,223,190,125,151,223,184,113, 35, 43, 38, 38, 38, + 46, 52, 52,244,153,230,106, 62,133,168, 14,171, 58,178,195, 37,132,176, 9, 33, 53,230,149, 5,128, 93, 19, 80,176,133,151, 94, +122, 73,216,179,103,207,184, 9, 19, 38,104,119,237,218, 69,210,210,210, 72,124,124, 60, 89,181,106, 21, 89,180,104, 17,249,242, +203, 47,201,152, 49, 99, 42,187,117,235,118,101,236,216,177,124, 59,178, 25,232,237,237, 93,122,228,200, 17,178,119,239, 94,194, +225,112, 98,108,221,176, 49, 47,210,144,153,106,200, 96,213, 93,215,136, 17,107,212,176,217,240,123,191, 55, 85,117, 35, 33,181, +222,255, 47, 42, 42,170,223,239, 30, 62, 4, 75,166,204,249,132,159,186,107, 45,212,223,125, 14,102,137, 26,236,242, 66,232,207, +199,192,116,254, 40, 94,238,209, 67, 32,160,168,165,246, 94, 48, 92, 46, 23, 92, 46, 23, 28, 14, 7, 90,173, 22, 57, 57, 57,232, +221,187, 55,227,250,245,235,252,169, 83,167,206, 22, 8, 4, 25, 0, 70, 53,121, 55, 83,143, 34,210, 23, 47, 94,196,235,175,191, +206,219,179,103, 79, 71,103,103,231,155, 22,139,133, 11, 0, 73, 73, 73, 24, 55,110, 28,111,223,190,125,193,110,110,110,215,141, + 70,163,144,199,227,129,201,100, 54,168,199,229,114, 97, 50,153,120,237,219,183,143,191,121,243,102, 80, 84, 84, 20, 59, 61, 61, + 29, 41, 41, 41, 48,153, 76, 92, 95, 95,223, 91,215,175, 95,239, 56,108,216, 48,118,102,102, 38,210,211,211, 31,231,195,150,252, + 26, 12, 6,240,120, 60,212,174,210,162, 40, 10,122,189, 30, 92, 46,215,102, 45, 22,139, 53,192,223,223,255,214,205,155, 55, 67, + 71,142, 28,201,185,118,237, 26,178,178,178, 96,177, 88,184, 1, 1, 1,183,110,222,188,217,105,196,136, 17,156,248,248,120,168, +213,106,216, 90,133, 86,243,189,155, 55,111, 98,194,132, 9,220,147, 39, 79,118,114,117,117,141, 55,155,205, 92, 0,184,117,235, + 22,198,141, 27,199, 61,117,234, 84,104,171, 86,173,226,155,168, 74,100, 2,128,201,100,194,212,169, 83, 69, 82,169, 20,153,153, +153,176, 90,173,176, 88, 44, 0,128,194,226,194, 91, 55,111, 37, 36,189, 60,254,185,126, 58,163, 94,127,233,106,236,157,182,173, +189, 60, 40,138,180,110, 34,171,163, 68, 34, 81,198,234,213,171,223, 78, 75, 75,227,249,251,251, 51,146,147,147, 81, 94, 94, 14, + 14,135,243,248, 26,179,117,191,185, 92,110,255,192,192, 64, 86, 85, 85, 21,172, 86, 43, 0, 16, 6,163,254, 22, 43,252,146,243, + 8, 80,153,217, 2,129,160,255, 95,242,244, 46, 11,116,130, 21,131,210,243, 13, 60,158,131,135, 68,236,234, 11,100,156, 67, 27, +103, 30,152, 12, 38,255, 90,138, 86, 4,144, 65,240, 44,112,178, 79,211, 58, 40, 69, 99,224,153, 28,131,197,110, 30,158, 40, 44, + 44, 68,171,182,254,168,226, 58,115, 47, 62,168, 20,131,178, 83,243,255,233,211,190,125,123, 23, 31, 31, 31, 20, 20, 20, 32, 52, + 52, 20,114,185, 92, 14, 96, 80,179, 31, 58, 95,121,241, 80,134, 94, 0, 99, 53, 44,212, 98,152, 88, 43,240, 32, 63,148,108, 15, +101,255,157, 76,150, 84,204,189,188,239,219,239,220,157, 60, 3,128,152, 87,161,114,224, 97,231, 27,161,142,206, 50,222,145,102, +154,173, 32,149, 74,117,230,202,149, 43, 10, 62,159,143,235,215,175, 35, 48, 48, 16,107,215,174,117,150,203,229,231,154, 23,217, + 34, 32, 84,195, 38,171,111,223,190,152, 57,115, 38,246,236,217, 3, 71, 71, 71, 76,152, 48,161, 41,179, 69,146,128, 31, 63,141, +143,255,106,207,195,135,199, 94,106,215, 46,106,130,175,239,178,105, 47,188, 48,249,205, 55,223,196,103,159,125,134, 35, 71,142, +160, 87,175, 94,152, 50,101,138, 41, 35, 35, 99,119,115,171,170, 86,175, 94, 61,107,246,236,217,117, 53,141,233,233,233,159,182, +168, 92, 42, 44,188, 21, 31, 31,159, 52,126,252,248,126, 85, 85, 85,250,171, 87,175,222,241,246,246,246, 0,208,186,185,154, 45, + 48, 88, 20, 33,132, 15, 64, 88,189,136, 0, 8,247,237,219, 39, 27, 57,114,164,180, 58, 77, 80,189, 52, 89,189, 31, 24, 24,232, +113,255,254,253,236,119,222,121, 39,116,207,158, 61, 2,161, 80,136,146,146, 18,124,241,197, 23,248,224,131, 15, 64, 81, 20, 8, + 33,248,242,203, 47,133,147, 38, 77, 10,123,248,240, 97,182,151,151,151, 45, 77, 90,120, 98,177,248,192,178,101,203,164, 86,171, + 21,115,231,206, 45, 48, 26,141, 51,171,215,205,119,112,112,184,140, 71,134,187, 49,234,245, 34,181,158,149,199,234, 28,155,168, +186,105,117,215, 17, 66,162, 26,211,176,243, 92,212,247,123, 49,141,153,173,218, 79,160,254,245,186, 72, 32,196,197,219, 15,165, + 63, 29,128,128, 69, 65,192,172, 94, 88, 20, 24,201,183,208,138,207,134,137,144,160,230, 26,173,154,133,205,102, 67,171,213,194, + 98,177,224,131, 15, 62,224,157, 62,125,218,137,193, 96,124,223,148, 78,109,195,116,239,222, 61, 4, 4, 4, 80, 63,254,248,163, +106,230,204,153,130,154,223, 41, 45, 45,133,143,143, 15,117,226,196, 9,229, 71, 31,125, 36,110,204,204, 80, 20, 5, 14,135,131, +217,179,103, 11,174, 94,189,234,232,230,230,134,228,228,100, 20, 21, 21, 65, 44, 22, 99,246,236,217,130, 43, 87,174, 56,187,185, +185, 33, 45, 45, 13,165,165,165, 16,139,197,118, 27, 45, 14,135,243,196, 54, 20, 69,193,104, 52,218,101, 12,100, 50,217,222,184, +184, 56,103,153, 76,134,248,248,120,152,205,102,200,100, 50,204,154, 53, 75, 16, 23, 23,231,236,224,224,128,164,164, 36, 16, 66, + 32,149, 74,237,202, 35, 0, 88,173, 86, 36, 37, 37,161,117,235,214, 56,119,238,156,114,218,180,105,252,154,244, 7, 15, 30,192, +195,195, 3,231,206,157, 83,138, 68,162,189, 13,105, 89,173, 86,228,230,230, 34, 49, 49, 17,201,201,201,200,207,207, 71, 65, 65, + 1,202,203,203, 97, 54,155, 1, 0,194,242,178,152,125,251,127,188, 41, 16, 8,132,129,190,237, 61,111, 37,220,214, 8, 4, 2, +161,151,167,167, 47,240, 49,163, 17, 67,248,125,122,122,186,211,164, 73,147, 56,121,121,121, 40, 46, 46, 6,139,197,250,221,181, +197,229,218,214, 20,200,108, 54, 7,240,249,124,202,104, 52, 62,142,128,113,185, 92,188,189, 87,139,192,133,120, 98,121, 97,189, + 6,196, 98,130,193, 96, 8,248,211,163, 89, 0, 5,202,208, 30, 20, 21,122, 57,185,210,177, 79,212,120, 14, 82, 78, 2, 86, 19, +192, 96,161,127,136, 7,235,200,173, 74, 21, 8, 66,160,135, 63, 33, 77,247,252, 34, 0, 5, 24,125, 0,170,203,233,251,102,167, + 94,163,223,224,100,103,103,131,195,225,128,199,227, 33,116,192,179,172,125, 55, 77, 46,160,208, 17, 70,248,217,162,249, 68,216, + 81, 32, 88,176,104,209, 34, 81,109,205,201,147, 39,139,100, 50,217,162,102,155,172, 74, 97, 15,152,201,236,196,108,109,235,101, + 49,121, 1, 15, 53, 58, 63, 16,242, 14, 96,234,244, 20,204, 86,127, 30,143,151, 2,160,119,139, 76,150,132,123,233,219,111,191, +115,119,108,245,200,100,193, 92, 5,176, 5,112,113,118,192,206,183,195, 29,157, 29, 4,246,154,173, 32,149, 74,245,203,229,203, +151, 21,124, 62, 31,113,113,113,224,112, 56,224,243,249,232,208,161, 3,182,111,223,238,236,232,232,104,183,217, 34, 32,245,198, +124, 71,141, 26, 69,250,246,237,139, 25, 51,102, 96,247,238,221, 48, 24, 12, 88,182,108, 25,210,211,211,109,146, 77, 2,126, 92, + 25, 31,191,107, 69, 98,226,189,121, 65, 65,254,163, 68, 34,199, 25, 19, 38,200, 62,250,232,163, 99, 71,143, 30,253,106,216,176, + 97, 5, 87,175, 94, 93, 7,224,128,157,135,151, 2,176,121,205,154, 53, 51,106,140,219, 71, 31,125,244,229,209,163, 71, 87, 12, + 27, 54, 44,247,234,213,171,239, 0,216,220,146,114,201,106,181,198,124,255,253,247, 55, 5, 2,129,208,207,207,207, 51, 33, 33, + 65, 35, 16, 8,132,158,158,158,190,253,250,245, 99, 52, 71,179, 57, 40,149,202,129,151, 47, 95, 14,196,163, 78, 99,188, 26,163, +149,144,144,224, 80, 86, 86,230, 32, 22,139, 29, 92, 93, 93, 37, 53,102,107,244,232,209, 14, 44, 22,171,209,235,182,162,162,226, +232,252,249,243,101,163, 71,143,174,249,140,243,231,207, 99,247,238,221, 16,137, 68, 79,124,119,196,136, 17,120,253,245,215,229, + 6,131,225,123, 27,178, 59,113,234,212,169,126, 42,149, 10, 11, 22, 44,208,103,103,103, 15, 4,144, 14, 64, 22, 17, 17,241, 73, + 66, 66, 66,183,176,176,176,253, 0, 58, 55,118,239,213,231, 69,106, 27, 29, 91,210,154,251,125, 91,205, 86,157,164, 6,199,208, +122,194,104, 69, 69, 69,157, 69, 3, 61,169,140, 69,106,240, 96,129,128, 73, 65,200,172,101,182, 96, 5,171, 84, 3,170, 25,189, + 84,234,123, 24,114,185, 92, 48,153, 76, 24, 12, 6,216, 58, 81,117,141, 41,144, 74,165, 16,139,197,208,233,116, 48,155,205,224, +243,249, 53,102, 4, 82,169, 20,108, 54, 27,108, 54, 27,124, 62,255,119,209,164,186,209, 28, 14,135, 3,145, 72,132,220,220, 92, +164,167,167,195,106,181, 66, 44, 22, 67, 36, 18,129,203,229, 34, 39, 39, 7, 57, 57, 57, 32,132, 64, 36, 18, 65, 36, 18,193,158, + 6,215, 22,139,165,222,135,191,201,100,178, 43,162,101, 54,155,113,231,206, 29,100,100,100,128,207,231, 63,222, 87, 30,143,135, + 7, 15, 30, 32, 47, 47, 15, 66,161, 16, 82,169, 20, 50,153,204,102,221,154,125,145, 72, 36, 16, 8, 4, 40, 46, 46,134, 86,171, +125,124, 76,165, 82, 41, 68, 34, 17, 74, 75, 75,161,209,104, 26,221,119,139,197,130,156,156, 28,228,231,231, 35, 51, 51, 19, 5, + 5, 5,143, 11,160,234,168, 81,203, 2, 59,101,101, 40, 44, 44,124, 28,137,108,104,177, 5,171,213,138,242,242,114, 92,190,124, +153,178, 90,173, 40, 41, 41,177,230,231,229, 89,166,231,112,113,228,227,173,228,187,147, 55,170,246, 29,143,211, 29,250, 37, 81, +183,249,208, 45, 29,191,219, 98, 51,254, 10,182, 4,201, 96, 98, 71, 22, 84,152,120,249, 70,142, 76, 21, 20, 1,164,156, 0, 24, + 44,128, 47, 71,247,224, 54, 72, 47,182,136,238,170, 13,124, 80, 24,140,205,190,114,155, 52, 45,236, 65,249,229, 38, 94,154,209, + 89, 26, 16,210, 25,106,181, 26, 60, 30, 15, 60, 30, 15, 93,122, 69, 32,165,208, 34,188,157,173, 19,130, 32,210, 38,205,255,167, +173, 88, 44,238,209,187,119,111,170,182,230,208,161, 67, 65, 81, 84, 7, 0,254,118, 21,114, 27,219,114, 97, 20,118, 7,139,204, +190,157,171,117, 59,146, 80,229, 59,124,212,179,142, 27,126,214, 4,220,201,211,123,131,152,230,128, 24, 59,183,192,108,245,147, + 72, 36,199, 54,109,218,228,205,231,243, 79, 0,232,211, 28, 17,177,128,185,109,193,140,241,238,242, 26,147,101,210, 2, 44, 1, +192, 22, 0, 44, 1, 92,148, 10, 44,125,125,144,163,144,207, 62,100,135, 97,221,183,121,243,102,231,186, 38,171,102, 9, 13, 13, +197,194,133, 11,157, 29, 29, 29,247,218,162,183,122,213,103,164,164,180, 20, 32, 64, 89, 89, 5, 86,175,250,172,184,102,221,232, +209,163, 73,159, 62,125, 48, 99,198, 12,172, 88,177, 2,199,143, 31, 71,247,238,221, 49,101,202, 20,132,133,133, 53, 37, 29, 41, +147,201,246, 68, 68, 68, 92,206,145, 72, 94,207,237,220,153,251,139, 76, 86, 58,176,180, 84,230,149,144, 96,244, 3,110, 1,216, +146,149,149,245,140, 29, 38,235, 5,169, 84, 26, 55,112,224, 64,163, 68, 34,201, 88,187,118,237,244,153, 51,103,226,179,207, 62, +195,252,249,243,191, 0,240, 26,128, 15,179,178,178,220, 26, 51, 89,127, 84,185,244, 71,149,117, 22,139, 37,243,192,129, 3, 97, + 70,163,209,163,186,122,144, 87, 82, 82, 34, 45, 42, 42,146, 24,141, 70,145,213,106, 21, 57, 56, 56,136, 1, 8, 95,126,249,101, +214,237,219,183, 3,204,102,115,118, 99,154,121,121,121, 47,206,157, 59,183,160,160,160, 0, 0,208,161, 67, 7,148,148,148,224, +221,119,223,197, 91,111, 61,234, 16,220,169, 83, 39, 16, 66,160, 86,171,177,122,245,106,117, 94, 94,222, 43, 54,100,183, 93,251, +246,237,145,144,144,128, 59,119,238,252, 12,192,138, 71,237, 88, 75,111,220,184,113, 51, 63, 63, 31,123,247,238,229,184,187,187, + 31, 69, 3, 67,188, 52,230, 69,154, 3, 69, 81, 49,205,217,174, 38,114, 85, 95, 68,172, 1, 26,143,104, 69, 69, 69, 81,181, 95, +159,136, 24, 81,136,207,136, 61, 7,199,160,206, 79, 68,179,132, 76, 10, 2,169, 12, 41,153,233,224,128, 74,124, 90, 70,171,184, +184, 24,211,167, 79,215,189,248,226,139,133, 86,171,245, 89, 91, 77,129, 76, 38,131, 76, 38,195,237,219,183,201,152, 49, 99,212, +107,215,174,213,213, 54, 90,247,238,221, 35,145,145,145,154, 69,139, 22, 85, 52,102,180,106, 34, 90, 43, 87,174,212,245,239,223, + 63, 63, 49, 49,145,212,152, 41,177, 88,140,213,171, 87,235,194,195,195,213,215,174, 93, 35, 53,105,246, 68,180, 24, 12,198, 99, +163, 85,123, 27, 6,131, 1,171,213,106,151,209,170,172,172,124,113,216,176, 97,234,164,164, 36, 82,179,159, 50,153, 12,107,215, +174,213, 13, 26, 52, 72,157,152,152, 72,106,210,164, 82,169,205,102,176,230,247, 37, 18, 9,164, 82, 41,110,223,190, 77, 34, 35, + 35,213, 27, 55,110,172,170,157,126,231,206, 29, 50, 98,196, 8,117,121,121,249,139,141,153,151,154,234, 60,179,217,140,170,170, + 42, 20, 20, 20, 32, 51, 51,243,113, 56, 93, 39,146, 62, 51,254,249,225, 29,117, 58,157,246,246,189,251, 25, 29,130, 3,149, 58, +157, 78,155,158,145,113, 15,248,216,218,136,246,179, 65, 65, 65,133,211,167, 79,215, 21, 23, 23,183,216,104,113,185,220, 36, 22, +139, 69,250,244,233, 67, 12, 6, 3,201,204,204, 52, 21, 20, 23,155,253,151, 47, 39,137,111,191, 77, 9, 98, 99,121, 98,177,152, +170,214,100, 36, 39, 39, 91, 5, 2, 65,210,159,110,180, 24, 86, 23, 80,164,247,111,247, 43, 28, 6, 13, 31,199,165,242,174, 2, +198, 10,128, 39, 7,120,114,176, 68, 78, 24,210,167, 19,115,215,229, 50, 23, 16,107, 79,112,120, 30, 77,106,178,137, 10,176,246, +249,233, 94,149,188,247,216, 89,220,162,162, 34, 48,153,204,199,166, 72, 40, 18, 97,224,168,151, 25, 95, 94,213,187, 0,164, 23, + 40,166,135, 29,247,250,251, 11, 22, 44,224, 20, 23, 23,131,193, 96,252,191,166, 80,136,105,211,166,241,164, 82,233,124,155, 11, +191, 3, 1, 28,176,121,221, 1,242,214,221,188, 42,183,163,183,116,126,115, 86,238, 20, 4,117, 10,195,212,254, 74,193,202, 24, + 77,208,205, 76, 93, 27,192,242, 54,204,134, 46,205, 48, 91,125, 36, 18, 73, 76,108,108,172,112,232,208,161, 88,189,122,181, 72, + 32, 16,156,104, 78,193, 95, 89, 97,153,185,100,227,215,234,248,117,131, 1, 99,229, 35,131, 85,107,209, 84, 88,177,112,231,153, + 82,147,137,140,183, 85, 83,167,211, 77,124,237,181,215, 10, 15, 29, 58,244, 59,147,197,231,243,145,154,154,138,101,203,150, 21, + 21, 21, 21, 53,249, 80, 92,187,102,117, 92,194,205, 95,241,229, 23, 75, 0, 16,108, 90,251, 6, 46,253,246,173, 67,255,126,125, + 73,235,214,173, 73, 88, 88, 24,166, 79,159,142,165, 75,151,226,238,221,187, 80, 40, 20,120,227,141, 55,208,175, 95, 63,172, 89, +179,166,177, 66, 42,114,230,204,153,203,178,178,178,252,126,250,233, 39, 86,126,126,190,114,205,142, 29,165, 7, 75, 75,139, 86, + 36, 36,220,253, 48, 56,184,253,188,144,144, 87, 26, 25,250,161, 94,147, 53, 99,198,140,125, 89, 89, 89,161, 63,255,252, 51, 59, + 63, 63,223, 99,198,140, 25, 88,181,106, 21,230,207,159,191, 29,192, 84,216,214,225,197,230,114,137,201,100, 62,243,236,179,207, +118,212,233,116,218,187,119,239,102, 4, 7, 7, 43,117, 58,157, 54, 35, 35,227,222,217,179,103,173,205,209,108, 14,133,133,133, + 15,247,238,221,123,111,214,106, 89,229, 44, 0, 0, 32, 0, 73, 68, 65, 84,172, 89,161, 89, 89, 89, 1, 0,156,202,203,203, 69, +229,229,229, 60,131,193, 32,144,203,229,242, 78,157, 58, 41,166, 76,153, 34,190,113,227, 70, 64, 86, 86, 86, 69,117, 20,169, 65, +140, 70,227,221,226,226,226,168,193,131, 7,151, 20, 23, 23, 35, 36, 36, 4,195,135, 15,135,139,139, 11,220,220,220, 48,114,228, + 72,248,250,250,162,176,176, 16,227,199,143, 47,202,207,207, 31, 12, 32,217,134,236, 62,204,203,203, 67,207,158, 61,177,100,201, +146,168,231,158,123, 46,177, 79,159, 62,101,193,193,193, 90, 15, 15, 15,255, 13, 27, 54,192,221,221, 29, 7, 14, 28,112,229,241, +120,123,235, 49, 89, 13,122, 17, 0,249,213,134,199, 80,231, 53,191,137,117,182,110, 91,239,123, 27,190, 87,215,108,213, 94,126, + 87,117, 88,255, 9, 1, 22,238, 62,176,171,138,235,233, 3,153, 95, 71, 8,249,124, 8,184, 92, 8,228, 78,208, 91,173,216,145, +154,167,173, 36,100,190,189, 23, 79,221, 7, 33, 69, 81,248,252,243,207,205, 61,122,244,168, 58,115,230,204, 38,157, 78,231,137, + 71,163,202,218,108, 10, 54,110,220,168,157, 61,123,246, 77,141, 70,211,145,207,231, 27,106,210, 55,109,218,164,125,249,229,151, + 19,178,178,178, 66,133, 66,161,182,161,246, 89,181,141, 22,143,199,211,107, 52,154,176,201,147, 39, 39,109,217,178,165, 82, 40, + 20, 66, 36, 18,129,199,227, 25, 52, 26, 77,199,233,211,167,223, 92,181,106,149, 86, 32, 16, 64, 36, 18,217, 85, 45, 71, 8,249, +157,161,170,157,110, 43,102,179,249,140, 70,163,233, 56,123,246,236, 27, 27, 54,108,168,172, 49, 64,181,243,184,102,205, 26,173, + 88, 44,182, 43,162, 85,243, 61,145, 72,132,245,235,215,107,103,205,154,117, 83,163,209,116,228,241,120,134, 90,233,149, 51,103, +206,188,161,209,104, 58,154,205,230, 51,141,252, 27,179,148,149,149,129,197, 98, 33, 33, 33, 65,207,225,112,192, 96, 48,240,224, +193,131,199,133,143,163,163, 99, 96,199, 14,193,254, 95,239, 59,112, 86,192,225,241,122,132,117, 9, 72, 78, 75,207, 34,132, 74, +107, 34,171,135,117, 58,157,231,153, 51,103, 54,245,232,209,163,234,243,207, 63, 55, 55, 20,217,178, 5,189, 94,127,246,250,245, +235, 38, 62,159, 79,229,230,230,154,153, 76, 38, 44, 22, 11,209,135,133,233, 59,108,216, 64,110,207,155, 71, 73, 69, 34, 22,135, +195,129, 80, 40,164, 78,158, 60,105,208,106,181,103,255,124,163, 5, 33, 40, 8,238,107,244, 18, 62,195, 76,225,222,225, 71, 38, +139,239, 0,240,229, 0, 95, 14,119,119, 15, 92, 77,213, 74,192, 0, 23, 22, 27,198, 16, 35, 68, 4, 10,194, 4, 53, 36,108,174, +128,202,203,203,123,108,136,106, 22,111,159, 0, 92, 79,175, 16,131, 34, 60, 48, 97,207, 16, 36, 81, 78, 78, 78,172,220,220,220, +223,105, 6, 6, 6, 50, 77, 38,147,237, 67,187,228, 88, 92, 1,235,140,123,121, 85,174, 63,220,172,244,123,123,197,151, 2,129, +165, 4,136,221,136,160,182,110,120,123,108, 39,238, 71, 71,243,131,174,165,105,219,130, 73,166,194, 90,225,108, 71, 62,123, 75, + 36,146, 19,215,174, 93, 19, 74, 36, 18, 36, 39, 39, 35, 44, 44, 12,209,209,209, 66,161, 80,120, 28,128, 93,237,241,174,168,145, + 94, 81,110,233,241,254,129,140,188,248, 92,243, 19, 38, 43,191,146,224,181, 79,143,150, 20,151, 85, 61,123, 57,179,225,251,167, + 30,110,148,148,148, 68,206,159, 63,191, 48, 63, 63,255, 9,147,149,158,158, 94,243, 80,236, 15,160,201, 63,191,255,251,245, 84, +232,242,165,179,113, 45, 54, 17, 67,162,222,194,245,248,135,248,112,238, 40, 56, 72, 5, 56,115,230, 12, 70,143, 30,141, 37, 75, +150,224,193,131, 7,248,238,187,239,168,232,232,104,234,242,229,203,212,167,159,126, 74, 53,209,164, 97,194,138, 21, 43,112,237, +218, 53, 12, 29, 58, 20,231,206,157, 67, 81, 81, 17,190, 61,113,226,254,222,251,247, 63,172,105,179,213,192,208, 15,245, 34,149, + 74,231,172, 88,177, 2,177,177,177,143, 53, 11, 11, 11,177, 98,197,138, 44, 0,111,216, 99,178,236, 41,151, 66, 66, 66,252,247, +237,219,119,150,207,231,243,194,194,194, 2, 82, 83, 83,179, 0,164, 53, 67,179,172, 37, 53, 85, 5, 5, 5, 23,163,163,163, 47, + 15, 24, 48, 64, 56,113,226, 68,231, 35, 71,142, 56,105,181, 90, 55, 30,143,167, 52, 24, 12,220, 59,119,238, 48, 15, 30, 60,232, +114,251,246,237,212,170,170,170,171,182, 28, 15,141, 70,115,245,238,221,187,131, 67, 66, 66,238,108,218,180, 41,203,213,213,213, + 58,101,202, 20,188,246,218,107,112,118,118,182,172, 95,191, 62,163, 79,159, 62, 9, 15, 31, 62,140,208,106,181,183,108,204,235, + 87,203,151, 47,191,176,111,223, 62, 12, 31, 62, 28,159,126,250, 41,190,253,246, 91,252,250,235,175,130,223,126,251,141, 27, 29, + 29, 13, 14,135,131,238,221,187, 35, 50, 50,114, 96,117,117,167,173,207,165,107, 20, 69,197, 80, 20,245,115,157,215,107,141,173, +179, 99,219,134,222, 55,250,189, 58,217,140,174,179,216,206,132,182,248,120, 90,176, 68,123,241,165,238, 36,111, 74,111,162, 30, + 23, 64,206,247,115, 36,147,219, 81,149, 19,155, 57,188,131, 78,167,123,188, 28, 58,116,136,184,184,184, 84, 74, 36, 18,187,135, +119,112,113,113, 81,151,149,149,145,174, 93,187, 22, 57, 59, 59, 63, 30,138,192,213,213, 85, 93, 89, 89, 73,186,119,239, 94,164, + 84, 42, 31, 15,239,224,225,225,145, 73, 8, 33, 94, 94, 94, 57, 13,233,153,205,102,226,226,226, 82,211, 67,143,237,232,232,184, +181, 91,183,110, 69,106,181,154,184,186,186, 62, 30, 58,193,217,217,121,117, 88, 88, 88,221,244,166,242,155,153,149,149, 69,178, +178,178, 72,171, 86,173,114,106,167,167,167,167,147,244,244,116,226,225,225, 97,247,240, 14,206,206,206,171,234,201, 75,179,242, +232,233,233,169,214,233,116,164,103,207,158, 79, 28, 83, 79, 79, 79,117, 85, 85, 85, 77,186, 77,195, 59, 8, 4,130,169,124, 62, + 63,135,207,231,231,240,120,188,101,173, 91,183,214,236,223,191,159,172, 95,191,190,166, 75, 58,156, 3, 71,244,240,233,249,202, +135,206,129, 35,231,180,100,120, 7,137, 68,242,139,139,139, 75,229,161, 67,135,158,184,190,116, 58,157,205,195, 59, 8, 4,130, +172,138,138, 10,171, 90,173, 54, 93,184,112, 65, 27, 27, 27,171, 77, 72, 72,208,166,166,166,234, 10, 53, 26,163, 90,173,214,149, +150,150,234,111,222,188,169, 23, 10,255,154,225, 29, 72,180,175, 15,217,234,127,244,225, 18,239,219,179,251, 10,171,110, 45,237, + 72,200,247,163, 9, 57,254, 26, 33,103,222, 39, 87,183, 79, 33, 61,189,121,150, 11,239,182,186, 71,182,249,253, 96,203,144, 12, + 36,186,131, 15,217,234,127,252,254, 98,239,219, 19,251,184, 85,237,216,178,158, 92,185,114,133, 36, 36, 36,144,228,228,100,114, +252,240,126,210,179,173,240,145,230, 86,255,163,118, 14,243,208,139,199,227, 85,172, 93,187,150, 92,190,124,249,177,230,209,163, + 71,137, 80, 40,212, 2,182,245, 90, 38, 0, 69,182, 6,142, 50,111,241,251,237,163, 65,226,242,194, 99,239, 19,114,107, 23, 33, +209, 65,132,124,213,141,144,253,195, 8,249,241, 21,114,121,253, 88,210,203,155, 99, 34,219,252,206,145,237,129, 54, 55,182,103, +179,217,101,135, 14, 29, 34, 57, 57, 57,228,220,185,115, 36, 54, 54,150, 36, 37, 37,145,140,140, 12, 18, 19, 19, 67,216,108,118, + 21,154, 49,109, 89, 55, 21,188, 34,218,115,114,111,174,236, 69,200,145,241, 36,127,239, 4, 18, 21, 44, 41,234,222,170, 69,227, +209,117,114,114,114, 42,136,137,137, 33,169,169,169,228,236,217,179, 68,169, 84, 22, 0,176,185,189,108,212,144, 62,132, 24,110, +146,240,190,193, 36, 36, 36,152,244,235,213,158,100, 63,220, 72,194, 58,183, 38, 91,183,110, 37,106,181,154,180,110,221,154,216, +155,177,136,136,136, 43,132,144,184,161, 67,135,198, 1, 56, 25, 17, 17, 17,151,146,146, 18, 23, 22, 22,118, 25,141, 15,253,208, + 32, 3, 7, 14, 52, 18, 66,200,208,161, 67, 9,128,156,136,136, 8,146,146,146, 66,194,194,194, 12,205, 57,120,182,148, 75,161, +161,161, 61, 6, 12, 24,240, 97,104,104,232, 28, 91,134,119,104, 66,243,105, 13, 66,205,196,163,193, 63, 3, 1,116,169, 94, 2, +170,211,152, 45,208,124,133,205,102,239,112,116,116,252, 85, 46,151,159, 97, 50,153,209, 0, 94, 66,243,198, 55, 99, 84, 71, 24, + 79, 59, 59, 59, 63, 8, 9, 9,209, 13, 30, 60,152, 12, 25, 50,132,204,152, 49,131, 88,173, 86,178,127,255,126,178,100,201, 18, +210,206,201,201,188, 30, 40,216, 6, 76, 2,205,163, 1, 75, 39,181,165,206,190,216, 6,229,227,219,160,226,213,118,148, 45, 3, +150, 70, 52,100,180,172, 86, 43,185,119,239, 30, 9, 15, 15,175, 20,137, 68,217,176,125,192,210, 39, 52, 21, 10, 69,172, 82,169, +252,221, 32,154,181,210,159, 24,176, 84,169, 84, 94,116,117,117, 85, 59, 59, 59, 95,175, 79, 83,161, 80,196,186,186,186,170, 21, + 10,197, 19,131,123, 50,153,204,161, 10,133, 34,187,110, 58,139,197, 26,160, 84, 42, 51,235,166, 55,176,239,112,113,113,201,204, +201,201, 33,249,249,249,196,211,211, 51,167,174, 1,203,203,203,123,194,128,217,162,217, 84, 94, 26,201, 99,189,154, 54, 28,211, +230,156,247, 26,124,221,221,221, 53,107,214,172, 33, 98,177,248,137, 46,207,126,125, 95, 93,112,229,126, 69,217,107,115,183,238, +175,103,192, 82, 91, 7, 7, 29, 44, 18,137,178,195,195,195, 43,239,221,187, 71,172, 86, 43,177, 90,173, 13, 25,173,250, 52,159, +233,210,165, 75, 97, 65, 65,129,165,188,188,220,156,153,153,169, 79, 73, 73,209, 45, 93,186,212,152,159,159, 95, 85, 81, 81, 97, +136,143,143,215,187,186,186,230, 3,120,198,222,115,212, 76, 34,234, 86,159,145,237, 1,189,200,182,128,152,164, 69, 94,119, 94, +233, 38,210,199,173, 25, 74,200,153,247,201,229,173,175,145, 30,222,220, 71,134,104,187,255, 9,242,165,111, 95,178,177, 45,215, + 38,205, 29,237,250,144,237,254, 39,110, 47,244,186, 51,186,179,179, 97,223,174,237,228,193,131, 7,228,232,193,189,164,123,155, +106,147,181, 45,224, 52,217, 26, 16,110,139,102,125,102,107,231,206,157,228,193,131, 7,228,135, 31,126,176,213,100, 69,212,103, +180, 62,136, 16,151,188,214,141,175, 31,223,137,107, 24, 25,196, 49, 70,250,112,204, 61,189, 88,150,142,174, 12,107,128, 51, 72, +164,159, 64, 79,182,249,157, 35,219, 2, 6,219,154, 79, 46,151,155,129, 90, 99,234,212, 93,120, 60, 94,126, 35, 70, 43,162, 73, +179,229,203,203,253,101,201, 0, 50, 60, 68, 82,104,163,201,106,234, 90,234,164, 80, 40, 10,190,250,234, 43,162, 82,169,242,109, + 52, 89,143, 53, 71, 68, 69,146,244,135,199,201, 15,251, 87,144,240,190, 1,100,207,206,217,228,202,185, 69,100,216,144,112, 18, + 17, 17, 65, 10, 10, 10,200,128, 1, 3,136,189,249,148,201,100,123, 42, 42, 42,226, 78,157, 58, 21, 23, 17, 17, 17,183,103,207, +158,184,243,231,207,199, 9,133,194, 61, 53,193,137,186,102, 43,224,247,229,127, 68,157,136, 86, 92,121,121, 57, 57,117,234, 20, +137,136,136, 32,123,246,236, 33,231,207,159, 39, 66,161, 48,174,185,247,145,173,229,210,160, 65,131, 22,164,166,166,150, 45, 92, +184,112,127, 61, 3,150,218,170,249,224, 41,229,243,169,148, 33,127,129,166, 68, 32, 16,196,221,188,121,147, 20, 23, 23,147, 96, +149,138, 44,103, 50, 73, 22,135, 67,114, 56, 28,178, 21, 40,250, 23,216,164, 41, 13, 85, 29,254,209,212,107,180,170,170,170,200, +187,239,190,107,224,243,249, 90, 14,135, 99,239, 20, 60,255,232,139, 80,161, 80, 92, 84,169, 84,106,149, 74,245,132,217,171,157, +174, 80, 40,174,255,203,111, 64, 95, 14,135,147,206,102,179,159,156,130, 39,112, 68,143,118,189, 38,206, 87, 5,141, 24,210,194, +124,114, 56, 28,206, 7,124, 62, 95,251,238,187,239, 26, 42, 42, 42,236, 49, 90, 0, 48, 72, 40, 20,102,239,222,189, 91,119,255, +254,125, 83, 81, 81,145,249,202,149, 43,166,216,216, 88,195,199, 31,127, 92, 46, 20, 10,179,209,240,176, 4,127,202,241, 36, 27, +219,114,107,204,214,173,249, 94, 73,195,131,133,198,232,119, 34, 73,143,214,117, 76, 86,195, 35,185,215,175, 89,109,182,110,124, +228,153, 20,238, 43, 54,175,152,255, 54,233,222, 70,240,164,201,178, 67,179,174,217, 18, 10,133,229,139, 22, 45,178, 39,146,245, +164, 33,220,225,231, 73,182,251,239,121,100,162,154, 88,182,250,125, 65, 62,247,243,252,187,220, 71,221, 84,240, 26,232,203, 75, +180, 35,146,101, 75, 62, 59,201,229,242, 59,118, 68,178, 30,107,126,254,249, 38, 50, 97,220, 32,242,240,206, 33, 82, 81,120,156, + 92,191,180,150,140, 25, 17, 74,186,119, 15, 35,219,183,111, 39,119,239,222, 37, 93,187,118, 37,205,200,103,228,180,105,211,226, + 82, 82, 82,226,146,147,147,227,206,159, 63, 31, 55,106,212,168, 56, 0,145,181,107,130,106,204,150,113,204, 24,125, 39, 6,227, +237, 38, 52, 95,152, 54,109, 26, 73, 73, 73, 33,201,201,201,228,252,249,243,100,212,168, 81, 4,246, 77,223,211,172,114, 41, 52, + 52,180, 71,120,120,248,252,206,157, 59, 15,121, 90,154,255, 65,163, 37, 26, 61,122,180,213, 98,177,144, 33, 67,134, 88, 54, 0, + 37,209, 20,165,142,166, 40,245,118, 32,255,223, 30,209,250,163, 39,252,140, 0,240,115,237, 4, 62,159,175,174,170,170,114, 22, +139,197,135, 43, 42, 42,102,225, 81,183,200, 22,105,254, 17,249,164, 53,255, 21,154,174, 98,177,120, 83, 69, 69,197, 40, 62,159, +159, 95, 85, 85,165,178, 67,211,129,199,227,189,205,231,243,195,181, 90,173, 47, 0,136, 68,162,123,122,189,254, 87,157, 78,183, + 14, 64,201, 95,189,239,100, 99, 91, 46,184,220, 46, 32,152, 23,151, 81,217,102,197,169, 34,175,119, 6,200, 51,122,182, 19,165, +130,109,253, 20,148,254, 42, 53, 41, 93,111,183,166,128, 10,131,133, 61,239,106,154,182,245,167, 63,149,123,205, 9, 23,103,244, +108, 43,206, 0,193,167,224,105, 47,217,171, 89,215,108,137, 68,162,221,149,149,149,175, 3,248,213,222,125, 39, 7, 2, 56,168, + 52,185,195,196, 12, 6,105,100, 10, 31, 66,180, 96, 48, 19,144, 7, 53,245,241, 29, 35,125, 31,213,175,185,101,203,102,242,243, + 79,199,161,215, 22, 33, 87, 83,134, 9, 47,189,138, 78,157, 66,161, 80, 40,176,124,249,114,248,248,248, 96,201,146, 37, 84, 51, +242, 25, 41, 22,139, 39,248,251,251,183,189,125,251,118,178, 86,171,253, 6,192,233,186,207, 31,127, 32, 92,200, 98,117,212,153, +205,231,238, 0,177, 77,104,190, 32, 22,139,231,248,251,251, 7,221,190,125, 59, 81,171,213,174, 1,240, 45, 93,214,253, 51, 52, + 25, 12,198, 58, 47, 47,175, 49,169,169,169,243, 0,236,195,127,136, 63,221,104,209,154,180,230, 63, 80,179,230, 62, 33,127,183, +124,254,191,217,178,206, 2,133, 54, 32, 84, 22, 56,214,245, 77,152,172,166, 53, 5, 84, 24,204,172,183, 64,161, 21, 8,242, 64, + 24,235,154, 48, 89,127,174,201, 4, 40,124,220, 72,249,245, 49, 8,213,240,249,162,175,249,122, 88,176, 96, 1, 57,121,242, 36, +132, 66, 33,116, 58, 29, 6, 15, 30,140, 79, 62,249,132,162,203, 16, 90,243, 79,212,252, 87,194,162, 15, 1, 13, 77,147,144,191, +107,198,168, 55,147, 13,228, 64,192, 53, 20, 48,223, 5, 3,109, 0,115, 58, 42,205,121,212,155,233,134, 22,106, 94, 65, 1, 53, + 27, 76,248,130,107,126,136, 10, 67, 30,245, 70,243, 53,255,128,127,136, 4, 31,255,125,207,203, 63,145,186,166, 42, 54, 54,150, + 62, 40, 52, 52,182, 51, 5, 79,246, 52,124,252,153, 54, 90, 52, 52,255,112,168,231,238, 24, 1,100, 85, 47,127, 91, 77, 26, 26, + 26,154,255,160,225, 2,133,134, 27,180,217, 19, 18,108, 78, 67,187,159,105,205,102,105, 50, 1,200, 0, 56,224,209, 24, 36, 53, + 93,122,155, 26,102, 99, 8, 0, 19,125, 60,105, 77, 90,147,214,164, 53,105,205,191, 88,179, 41,237,127, 98,149,100,125,189, 12, +163,255,140, 31,142,160, 53,159, 42,131,255, 53,251, 78,208, 17, 4,235,171,151,142,244,121,167, 53,105, 77, 90,147,214,252,207, +107,254, 43,161,171, 14,255, 89,240,255,177, 57, 39,196, 21, 64,205, 32,151, 9,168,162,252,193,199,108, 0, 64, 57,174, 19,130, +251, 0,130,171,215,103, 82,148,221,189, 81,105,104,104,104,104,104,254, 42, 66, 1, 92, 7,224, 10, 96, 24,128, 24, 84,143,170, +240,151, 26, 45,129, 83,123, 87,176, 24, 33,148,149,248, 3, 0, 97, 80, 73, 48, 91,227,117,133,247, 91,252,144, 21,187,249, 58, + 18,112, 15, 80, 48, 60, 87,145,115,175,197,131,161, 5,251, 74,199,168, 20,146, 9,121,133,165,187, 19,239, 86, 28,177,103, 91, +153,204, 75,198,119,148,143,213, 27, 77,193, 92, 14, 39,195, 88, 82, 22, 93, 92,156, 92,222,140,108, 56, 54,182,242,227,143, 9, +117, 44,247, 58,197, 17, 26, 25, 78, 82, 14, 85,129, 10, 82,145, 43,182,122,151,164,146,131, 7,159, 35,246,158, 27,138,129,254, + 34,137,164, 51,143, 47, 12, 19, 74,228,237,173, 4, 40, 82,103,167, 25, 76,230,243, 22,131, 54,142, 88,241, 63, 59,206,213,203, + 0, 86, 0, 0, 6, 12,248, 25,193,144, 98, 93, 77,198,241,198,128, 91,120,249,204, 25,212, 12, 46,251, 1,128,149,118,100,215, + 1,128, 23,128,210,224,224, 96,109, 66, 66, 66,254,211,186, 70, 91,114,222, 27,131,199,227, 11, 76, 38,163,209, 98,177,180,120, + 98,106,158, 80,186,232,119,211, 43, 81, 12, 84, 85, 20, 47,166,203, 62, 26, 26, 26,154, 63,213,104, 13,195,163, 42,195,166, 27, +195,123, 5,246,190,198,231, 11,188, 1,192, 74, 8,172, 4,168, 44, 43,137,203, 75,142, 29, 12, 0,138,214,161,167,216,124,105, +103, 43,121,180,222, 98, 5,204,198,170,212,178,244, 43, 93,109,201,145,200,217,119,244,128,136,129, 99,162,162,134,249,117, 8, +238,208, 14, 0,110, 37,220,122,120,236, 88,204,221, 51, 63, 83,135, 42,243,239,253,208,162, 0, 10,248,159,116,233,210,169,119, +108,236,245, 37, 0,102,180,244, 8, 58, 57,137,103,157,254,254,221,190, 3,199,172, 22, 1,246, 61,112,249,142,242,177, 35,135, + 63,211,233,189, 55,167, 49, 94,123,119,185,247,181, 11,255,251, 76,236, 26, 84, 66,172,166,211,149,234,113,191, 53, 54,113,114, + 93,255,216,144,193,250,166,232, 36, 99,253, 87, 61,228,186,162,135,227,136,213, 50,142,162, 40, 48,185,194,131,206,109,123,239, +119,232,255, 78, 49, 0,155,123,140, 73, 93, 3, 35,148,174, 30,135,198,189,250, 54, 95, 40, 83,177,192,228, 0,160,144,147,118, + 7,103,190, 93, 33,127,107,241,206,208, 11,241,233,230, 95,190,223, 92, 69,113,216, 99,180,185,183,155,174, 79, 79, 79,119,128, +151,215,163,247, 95,124,177, 0,222,109,110,225, 81, 91, 51, 96, 45, 74,191,206, 65, 48,240,200,104,165,165, 65,110,107, 94, 7, + 15,125,126, 80, 70,250,253, 37, 57,217, 25, 71, 24, 44,150,181,184,180,242, 29, 39, 39,101, 69, 97,161, 38, 28,213, 13,185, 21, + 10,133,168,160,160,192, 8,192,248,103,158,247,177,147, 62,249,226,224, 87, 11, 94,175,111,221,244,183, 62, 89,231,229,225, 32, +122,115,198,228,122, 39,228,238,247,204,228,247,206,158,220,185,170, 73, 67, 44,146, 44,122,246,245,249, 31,247, 31, 16,249, 68, +250,149, 75,231,177,247,243, 5,168, 44,167,205, 22, 13, 13, 13,205,159, 64, 76,181,185,138,169,187,162, 65,163,197,231, 11,188, + 47,255,239,152,227, 15,231, 51, 1, 0, 17,161, 46,248,112,233,166,200, 61, 27, 99,239, 2, 64,143, 1, 81,190, 75, 62,120, 19, + 23, 19, 53, 32,132,160,147,143, 19,134,140,124,206, 54,227,161, 10,232, 58,118,236,179, 47,190,251,238,156, 17, 15, 30, 60, 72, +219,183,111,223,111, 0,208,167,111, 95,159,229,203,151, 63,191, 90,238,200,251,238,224,247,217, 85,234, 59,215,154,179,183,124, +183,182,238,126,237,219, 76,248,238,203, 77,140,254,131,159, 29,159,134,202, 21, 85, 57,201,217,182,108,171, 80, 40,102,179,217, +108, 25,240,104, 54,246, 26,140, 70,226, 2, 0,102,139, 85, 34,119,243, 43,103,114,248, 22, 30,143,115,187,188,162, 98,119, 89, +246,157, 29,141,105,234, 77,166,160,183,222,152,196,184,145, 92, 8,239,160, 62,204,245, 43, 62,130,213, 98,146,191,253,193,210, +177,177, 87,190, 67,165, 26,103,109,220, 53,118,221, 4,119,247,238,204, 79, 86,136, 7, 81, 20, 94,241,234,241,234,168, 37,187, + 14,178,187,248, 72,161, 55, 89,113, 34,174,176,199,214,117,159,172,186,176,117,216,143, 0,182, 3,248, 5, 64,147,166,206,209, +201,241,155,217,243,215,137, 43, 13,255, 31, 37,169, 54, 89,248, 98,247, 1,220,204,180,194,223,207,159,229, 50,251, 51,241,246, +165, 83,118,105, 31,205,179, 85,159,221,109, 11,160, 23,144,228,136,169,139, 7,226,235,149,203,160, 84, 86, 66, 34,201, 0, 5, + 21,128,246,213, 95,188,207, 45, 64, 38,128, 15, 52, 26,136,150, 76,195,224, 27,192,220,142,128, 6,192, 5,170,177, 89,227,137, +121,197, 91,243, 86, 5, 59,183, 9, 14, 75,184,155,141,203, 49,155,145,159,151,238, 80, 92, 92,176,187,149, 79, 71, 34,146, 57, +135,150,228,165, 64,234,128, 20,138, 88, 70,150,150, 22,231, 1,176, 41,138,228,226,226,178,200,221,179, 91,223,154,243,238,232, +213,169,184,102, 29,131,201,250,166, 32,229,218,155,141,109,239,229, 63,124,242,138,205,125,194,147,110,158, 58,144,145, 28,119, +222,108, 50,234,219,251,133,116,153,244,202,248,231,147,178, 21, 29,243, 75,244,184,121, 43,177,211,202,149,159,174, 76, 76,184, +117, 75, 34,113,144,183,241,237,216,205, 63,100,232,248, 34,131, 99, 91, 91,140,150,217,108,129,147, 75, 91,176,249, 18,120,168, +100, 40, 41,215,163, 82,111,134,194,165, 13,204,102, 51, 93,244,209,208,208,208,252, 57,228,226,201,198,239,209, 77, 26, 45, 0, + 16, 11, 88,184,155,146, 7, 0,112, 16, 0,179,166, 78, 68, 97, 65,190,175,193,108,197,171, 19, 95,194,245,164, 92,220, 77,205, + 7, 33, 4,190, 30, 54, 79,194, 13, 38,172, 93, 94,157,252,106,191, 83,167, 79, 95, 93, 48,127,193,215, 20,133, 75, 0,176, 61, +250,139, 30, 11, 23, 45,124,253,165,137, 47, 13, 58,120,240, 96, 34,128,102, 25, 45, 22, 37,217,180,106,229, 50,110, 86, 65, 85, +213,236,119,231, 89,231,188, 51,123, 61,128,103,109,114, 50,108,182, 44, 43, 43, 75,204, 96, 60, 57,151,230,167,203,230,157, 27, + 52,102,245,253,180,140,146, 27,167,142, 30,237, 26, 24, 24,136,172,236,188, 94,159,109,216,214,241,196, 41,193,164,242, 50,221, + 24,109,193,157,122, 39,109,230,177,217,137,139, 63,219,218,201,234,224,195,248,240,245,161, 8,106,231,134,108, 77, 9,250, 14, + 30,193,138,187,118, 45, 18,176,217,104,213, 29, 60,112,172,193,170,233,184,124,247,149,129,163,122,186,117, 97, 48,152,168,208, +153,144, 95,170,135,197, 10,244, 9,144,225,153, 61, 27, 88, 69,149,166,209, 75,191,207, 28,125,105, 99,148,186,170, 52,103, 38, +128, 67, 77,196, 3, 29, 61,148, 82,220,205, 44,175,215,100, 85, 86, 61,122,128,115,152, 22, 80, 32, 78,141, 8,245, 2,240, 21, +224, 15,252, 52,243, 69,168, 84,251, 84, 42,213, 88,165,202, 37,206,247,197, 73,148,187,119,128,164, 66,103,196,237,196, 91,229, +129,157, 19, 72,121,145,230,237,170,202,226,131,119,128, 4,127, 96,127,181,198, 36, 52, 98,180,238,223,191, 83, 50,233,133,112, +214,141,135,229, 72, 22,137, 16,212,115, 20, 74,243,179,216,207, 76, 90,220, 77, 87, 94,202,119, 82,121,225,206,197, 3,200,207, +120,208,169,202,160,255,193,209,179, 71,248,143, 95,205, 53, 52, 21,221,114,113,113, 89, 52,117,234,212,143,243,115,147, 62, 25, + 52,102,117, 72, 90, 70,201,141, 23, 23,255,218,117,250,104, 31,156,136, 47,195,178,201,225, 19, 0, 52,106,180,152, 44, 98,225, +139, 93,188,199,188, 48,115,158,155, 51,127,158, 80,192,128,131,136,139,211, 87, 52,248,238,116, 38, 76,102,130,238, 33,237,125, +103,189,183,110,151,171, 19, 23,185, 5, 6,100,231, 87, 65, 93, 80,133,138, 66,173,222,166, 11,130,162,160,201, 47, 68,204,143, + 49,160,216,124, 80, 12, 10, 38,163, 17, 44, 6, 3, 20,131,162,139, 62, 26, 26, 26,154, 63,135, 6,123, 29,178, 0,224,216,177, + 99, 36, 42, 42,234,119,165,178,197, 66,112, 55,245, 81, 19, 28, 38,147,137, 97,189,125,176,254,179,197,208, 25,204,184,153, 82, +138, 31, 46,102,194, 80, 89, 2, 66, 8, 10,130,148,245,253,240, 19, 85, 74,171, 87, 8, 66,153, 60,246,184, 11, 87, 68,173, 29, +229,114,249,253,196,175, 43, 23,190,163, 14, 96, 17, 99,220,210, 79,125, 82, 56,142,172,158, 7, 14,236, 15, 28, 30, 21,197, 21, +139, 37,239, 19, 86, 71, 15,118, 37,153, 83, 90, 26, 95,218,144,102, 93, 4, 74,255, 17, 35,134, 61, 51,192,197, 69,101,125,113, +249,149,164, 77, 51, 67, 61,219,251,180,239,117,215,164, 27,161,211,220, 63,218,192,102,143, 53,173, 86, 43, 24, 12, 6,212,106, + 53, 44, 22, 11,244,122, 61, 76, 38, 19, 50, 51,211,212, 86, 66, 60, 44,176, 50, 92, 93, 61,192, 98,113,225,221,218, 11, 91,215, +175, 16,238,249,238,104,216,220, 5,159, 28,209, 22,160, 59,254,127,112,203,199,154, 85, 69,197, 7,143,159, 60,237, 76,112,198, +237,195,215,135, 50, 53,197, 21, 56,115,237, 1,174,223,206,180,247, 68,214, 29,194,161,117,118,250,131,178,213,171, 87, 51,151, +156,120,144, 57, 96,200,179, 22,175,118, 33,173,245, 22, 2,128, 2,143,195, 2,135,197,128,151, 51, 31,135,231, 5,227,202,200, +120, 85,100,168,243, 58, 66,200,161,198,142,167, 94,111,178,244,246, 23, 49, 59,182,149, 33,254, 97, 49,174,158,184,132,217,243, +215, 33, 54, 69,143,242, 10, 45, 40,139, 30, 76,162, 71, 65,122, 50,204, 22, 11,105,234,188, 63, 34,180, 24, 0,120, 60,222, 7, + 63,252,120,210, 77,111,229, 35,175, 68, 15,117,177, 30, 62,221,199,136,210,179,243,241,213,226,231, 63, 0,112,208, 31, 40,183, + 65,147, 7, 32, 60, 45,229,158,201, 96,176, 88,171,140, 22, 70,144,167, 12, 59,126,186,134,224,240, 23,170,184, 76,166, 64, 34, + 83, 0, 4, 8,234,251, 2,174, 30,249, 28, 98, 6,179,179, 64,202,235, 8,224,106, 99,215, 82,141,201, 90,180,104, 17,102, 76, +125, 30, 86, 66,216, 22, 88, 25, 0,176,229,135, 7,240,242, 86, 54,118,142,254,127,186, 24, 11,131, 50, 26, 9,202, 43, 76,200, + 47, 49, 64,194,103,225, 94, 70, 37, 30,164, 87,224,249,193,238, 24, 51,208, 21, 22, 43,193, 75,239, 95,199,179,145,174,120, 49, +202, 3,160, 40, 20, 20, 27,160, 55, 88, 26,220,119, 6,131,209,134,201,100,134, 90, 44,150,235,143, 62, 51, 97, 1, 80, 86, 92, + 0,189, 94, 15, 38,147, 9,185,163, 51, 0,234,137,239, 90,173,214, 20, 91,239,163,102, 66,107,210,154,180, 38,173,217,108, 26, +242, 34,255, 16, 26, 28,202,129,209,216, 86, 15, 51,139,112, 55, 37, 15,157,253,221,209,174,181, 43,174,222, 43,198, 55,103, 50, +177,243, 84, 58,206,220,204,135,149, 37, 65, 94, 25,112, 63, 77,141,251,233, 5, 77,142,159,205,228,177,199,189,245, 86,233,187, + 29, 2,203,186,255,239,196, 44,184, 59,223, 15,156, 59,183,100, 22,147,199, 30, 39,111, 37,217, 55,239,221,183, 39, 72,132, 66, +174, 65,111, 64,219, 54, 94,252, 55,103,206,154, 68,201,121, 54,207,137, 36,113, 15,144,243, 4,130, 29, 75, 63,126,159,183,238, +135,251, 25,149, 6, 84, 30,186,164, 78,158, 51,111, 97, 17,139,205,223, 42,113, 15,176,185,237,143,201,100,130, 94,175,135,193, + 96,128,209,104, 68,118,230,157, 17,191,252,240,222,224, 54,173, 28, 7,243,248,124, 16, 0,101, 58, 51, 82,114,181, 8, 31, 56, +136,217, 57, 52, 52, 72,236, 26, 48,185, 62,173,210,210,244, 82, 43, 97, 74,142, 29,222,203,220,255,211, 13,124,125,236, 26,142, +252,122, 3, 87,207,158, 48, 19,171,233,241,252, 95, 98, 87, 31, 95,177,107,135,116,177, 91,136,250,241,226, 30,220,232,240,204, + 76, 38,131,132, 15,140,248,121,234,140, 55,255,167, 45, 47,212,236,216,180, 56, 59, 63, 39,237, 14,143, 67,153,133, 60, 38, 42, +170,204,216,245, 75, 14,198,174,184,137,219, 25, 21, 32,132, 52, 57,129,183, 21,120,103,220,228,247, 44, 38,163, 17,126,158, 98, +236,141, 94,137, 17,225, 29, 49,160,131, 28, 93,219,137, 32,100,233,145,152,116, 23,223,238,221,101,182, 90, 25,115,154,184, 17, +159,169, 94,226, 0,160,162,162,226,189,185,239,207,201, 55,152,173, 48,154,172, 48, 86,191,254,242,237,167,249,150, 42,237,123, +213,219,197,213,218,174,161,155,121,227,107,211,231,134,239,248,230,231,255, 99,239,187,195,163,170,214,238,215, 41,211, 75,122, + 38, 9, 33, 9, 36, 64, 66,239, 16, 80, 64,122, 64,186, 32, 69, 64, 65,154, 10,138,162,130,162,130,212, 75,175, 42, 40,136,244, +222, 59,132,170, 32, 29, 18, 32,129,144,222, 39,109,122, 59,237,247,199, 36, 16, 32,101, 2,222,251,221,223,247,101, 61,207, 60, +147, 57,156,243,178,219,217,123,237,245,190,123,239,238,251, 46,102,145, 57,249, 14, 68,159,216,131,128,160, 48,136, 41, 82, 14, + 2, 0, 65, 0, 4, 1, 65, 16,224, 27,210, 0, 86,158,199,222, 95,190, 13, 68, 5,241,106, 37, 36,107,252,248,241,120,240,224, +193,115,245,158,240, 56, 9, 9,143,147,112,230,228, 85, 0,128, 87, 72,243, 66,175,144,230,133, 62,161,173,215,149,101,203,206, + 49,188,133,229,144, 93,100,133, 66, 70, 34, 56, 80,129,129, 93, 2,176,250,155,166, 24,209, 59, 16,233, 57,102,140,159,115, 7, +126,126, 34, 28,184,152,133, 85,219, 19, 80, 47, 68,137, 1, 93,106,224,253,190, 53,203, 86,107,105,186,151, 72, 36, 26, 62, 96, +192,192,217, 82,153,114,193, 39,115,182,206,146, 75,233, 18, 53, 22, 20, 69,129, 97, 24,144, 36,129,161,159,174,158, 37, 85,168, + 23, 12, 24, 48,112,182, 72, 36, 26, 78,211,116,175,234, 73,103, 53,170, 81,141,106,252,219, 20,173,146, 79,192,115,253,118,121, + 79, 88,173,150,164,119,134,142, 68,128,198, 95,213,255,173,247,197, 55, 19,138,160,205, 74,193,227,248, 24,152,173, 12,196,158, +161,128,204, 31,181,106,135,224,110,220, 65,199,170,197, 71,141, 60,107, 75, 42,207, 94,191,126, 1, 53, 31, 63, 36,200,197,139, +130,175,198,199, 21,182,220, 54,243,119,140, 24,161,242, 89,188, 40,248,106,242, 19, 37,169,144, 9,237, 63, 24, 61,156, 32, 9, + 1, 95,127, 61, 13,253,251, 68, 97,204, 7,163,136, 63,254,216, 20, 89,228, 98, 46,121,136,214,204,248,118,182, 36,167,136,181, + 95,139, 55,218, 20, 74,185,252,207, 71, 70, 83,163,218,193,242,222,131,222,207, 60,186,251,183,229, 0, 70,187, 98,171,132, 96, + 49, 12, 3,135,195, 1, 0,156, 83, 61,112,126,231, 27,236,200, 45,178, 33,167,200, 6,150,227, 49,104,232,104,249,245, 27,119, + 70, 3, 40, 39, 94,139,231, 25,150,193,190,211,183,144,113,125, 15, 79,144,148,174, 84, 48, 60, 84, 1,117,195,253,253,131, 47, +246, 25, 52,202, 87, 34,115,186, 97, 13, 38, 27,254,248,101, 81,133,233, 36, 9, 66,224, 57,182,136,101, 24, 83, 88,104, 88, 70, +253,134,205,100,151,207,159,236,247,231,153,125, 70, 54,108,148, 71, 66,114, 22, 40,145, 20,148, 88, 6,155,195,181,133,135, 57, +143,175,174, 5, 64,140,253,104,218,138,169, 95,126, 67,125,190,234, 18,236, 86, 51,108, 22, 19,244,186, 66,200,105, 6,177,127, + 29, 98, 5,142,153,106,202,186,189,182,124, 75, 68, 38,128,204,210, 87, 10, 10, 10,162,255,186,116,241,240,223,127, 93, 26,227, + 31,214,146,180, 51, 60, 30,199,252,205,103, 60,186,113,216,102,211, 71, 3, 0, 1,228, 3, 56, 89,145,112,169,118,243,112, 31, +243,241,151, 99, 61,228, 74, 50, 38,189, 8, 41, 89,122,112,242, 64,248,215,172,243,204,191,202, 59,243,219, 38,194, 23, 61,154, +189,139,203,247, 82,185,147,187,214,118, 7,112, 8,128,185, 34,146,117,243,230, 77,136,197,226,231,234,189, 78,221,218, 40,113, + 29, 22, 21, 76,246,216,180,248,125, 0, 64,151, 55, 59,142, 7, 48,225,165,137, 74,182, 30,222,118, 22,109, 27,120, 33, 34, 84, +133,140,124, 59, 4,130,198,238,179,121,120,148,110,194,233,107, 90, 4,120, 73,192,219, 73, 80, 82, 96,223,229, 12, 92,142,205, +195,200, 94, 65,120,152, 88, 80, 14,177,166, 90,124,254,197,180, 31, 87,174, 92,117,238,157,143, 22, 15,238,208, 34, 12,122,131, + 17, 25, 5, 12,140, 38, 3, 76, 70, 19,228, 10, 5,164, 18, 9, 40,154, 70,175, 15,230, 13, 62,246,251,183,231, 63,255, 98,218, +143,203,150, 46,249,158,101,217,227,213,253, 97, 53,170, 81,141,106,252, 91, 21,173,241,165,175,149, 75,180, 82,238, 95,110, 13, + 0,225,173,122,228,171,100,180, 23, 77, 18,200, 73, 79,192, 31, 75, 62, 5,207, 11,232, 61,110, 49,212,181,253, 33, 23, 83,176, + 25,243,141, 5, 9, 23, 42,138,213, 1, 65, 48,221,215,174,203,168,253,209,164, 48,183,109,219,140, 34, 0,216,182,205, 40,154, + 52, 49,200,237,167,117, 73,181,219,190,217, 18, 2,199,161, 79,255,119, 48,116,216, 80, 36,103,155,177,247, 98, 42, 76, 22,187, + 75,171,229,228, 62,245,155,249,120,251, 70,125,246,126,148,146,166, 8,162, 94,136, 59,149,166,101, 88,138, 18,113,135,175,235, + 50, 7, 13, 26,230, 19,125,108, 87, 23,206,167,126, 51, 75,222,195, 59,149,217,179,217,108,207,185, 14,189,124, 66,143,117,127, +103, 73,122, 86,182,225,104,118,161,181,173,137, 97,145, 83,100, 67,110,145, 13, 69, 38, 7,252,213,158, 96, 25,123,147,242,236, + 9,130,176,121,192, 59, 35, 71, 1, 32, 9,146,253,221,152,245, 48,222,249, 47,207, 72, 86, 84,255, 17,190, 23,111, 38,224,241, +141,227,133, 2,207, 58,119,113, 39,248,244,138,203, 21, 2, 69,128, 23,211, 4, 67,145, 36,239,112, 24, 25,141,198, 55,250, 66, +244,137,190, 86,246, 9, 40,177,244,233,189,150,231,221, 81,149,145,173, 53, 0,176,114,213,138,165,237,187,143, 16, 95,184,149, + 4, 11, 3,180,107, 17,142, 3, 59,127,181, 9, 2,243,165, 41,235,246,154, 42, 52, 66,143,160,160,160, 79, 69, 18, 73, 23,185, + 66, 29,228, 27, 16, 76, 58, 88, 14, 14,134,131,210, 59,144,148,170,188,186,243,164,248, 50,235,176, 71, 59, 76,218,149, 0,202, +229,215,167,175,222,239,242,203,202,165,131, 3,188,149, 8,242, 17,227,240,133, 66,142,161,121, 82, 19, 18, 65, 0, 64,176,198, + 13,247,111,157,199,221,187,247,208,164, 93, 20,188,213, 53,161, 18,115, 66,222,227, 63, 11,252,252, 3,155,231,100,103,136, 95, + 36, 90,254,254,254, 63,140, 28, 57,114, 86, 64, 64, 0, 86,172, 88,241,244,122,233,122,111, 12,180, 45,237, 58,252,105,255,227, + 10, 51,252, 65,159, 90,120,179,153, 6, 60, 15, 76, 89,126, 23, 49, 9,122,172,159,209, 2,131, 58, 7, 98,221,193, 36, 52,173, +167,132,209,194,195, 97,231, 32,150,144,104, 16,170,130, 84, 76,225,220,173, 60, 24, 76,166, 10,109, 19,148, 20,221, 59,183, 67, + 94,145, 25,190,238, 18,132, 6,249, 66,165, 8,133,193,194, 34, 37, 91, 7,157,137, 65, 94,161, 9,111,180,107,131, 83, 91, 36, +213, 93, 96, 53,170, 81,141,106,252,103, 84, 45,160,212, 30, 90,207, 17,173, 35, 71,142, 8, 0, 80,150,127, 52, 35,167, 0,222, + 42, 26,190, 53,106,227,189, 79,151, 98,243,242,207,193,113, 12, 4, 1, 96, 57,215,118, 38, 16, 4,209,233,143, 39,213,174, 95, +171, 54,229,251,222, 8,133,101,235, 54,179,252,189, 17, 10, 75,227, 38,222,186,143, 39,213, 78, 50, 88,131,223, 96, 57, 14,127, +198,230, 34, 38, 73,135,152,100, 61, 84,114,215,183,249,162, 36,226, 73,139, 22, 46, 16,211, 20, 65,196,166, 24,141,233,249,172, +145, 18,137, 28, 10,185, 68,176, 11,180, 45, 57, 79,200,239, 58,224, 3,203,225, 45, 43,199, 2,248,164, 92, 85,172,120,165, 97, +137,146, 85,242, 45, 8,130, 64, 0, 60, 79,112, 92,122,158, 21, 70, 7,131,156,194,103, 68,139, 96,203,247,156,170, 2,234,134, +187,169, 85, 39, 40,138,146, 10, 2,192, 56,216,119, 17, 80,183,167, 49,235,113,124,105,146,117, 53, 54, 19, 9,183,207,228,112, + 14,243, 72,115,110,220, 89, 87,243, 78, 16, 16, 40, 10, 60, 69, 18, 60, 65,128, 23,145,130, 29,130,192,191,152, 34,115, 21,136, + 86, 9,217,146,136,168,153,167,118, 44,215,140,121,187, 1,118, 94,116,114, 62,171, 65,171, 55,101, 84,137,100,193,219,219,123, +244, 87, 95,125,245, 67,191,119, 70, 64,103, 37,144, 83,232, 84, 3,237, 12, 15,177,210, 7,221, 63,222, 24,148,165,213, 7, 61, +190,118,248,141,188,219,219,116,140, 85,183,162,220,116, 37,100, 94,179,152,139,252,161,230, 0, 0, 32, 0, 73, 68, 65, 84, 77, +208, 91,156,249,153, 54, 58,130,250,110,237,105,176, 2, 13, 47,223, 64,248,186,137,241,254,187,189,112, 49,164, 22, 30, 60,124, +136,153,179,143,194,207,195, 45,230,202,249, 67,117, 90, 68,118, 88,118,108,255,246,151, 72, 92,118,118,246,236, 45, 91,182,160, + 89,179,102,179, 90,182,108,137,236,236,236, 18,130,252,180,222, 19, 30, 59, 5,219, 18,162,117,235,214, 93,180,104,209,180,220, + 60, 55,169,227,134, 61,231, 50,177,241, 72, 50,228, 82, 10,181, 3,101,152,180,232, 54, 58, 55,247,193,228, 33,161, 80,201, 67, + 80,100, 96, 96,103,120, 88,108, 44,242,245, 14,100,228, 91,145,150, 99,129,131,169, 56, 22, 94,128,128,152,248,116,216,108, 86, +120,122,122, 66,165,176, 66,230, 17, 12,128, 66, 97,142,206,185,250,208,108,133, 66, 46,173,238,250,170, 81,141,106,252,127,131, +138,184,200,255, 71,170,214,203,138, 86, 69, 25, 18, 4,224, 81, 74, 30,106,213,244, 69,205, 90,117, 16,255,224,110,169,206, 30, + 96, 57,215,220, 81,135, 14,101,165, 47, 93,234,198,127,254,185,174,221,162, 69,193, 87, 38, 77, 12,114,111,220,196, 91,247,213, + 87,169,237,150, 45,115,191,114,250,170,136, 19,138,247,235, 42,217,155, 75, 16,170,178,199, 38,217,166, 89,195, 80,106,246,182, + 71,169,103,239, 25,114,197, 98, 49,227,239, 41, 35,212, 42, 9, 69,145, 34,137,141, 33,109,225,141, 90, 80,135, 73,162, 69, 69, + 86, 74,136,214,139,174,195,124,109, 66,191, 83,123,167, 53,126,107,192, 98,175, 12,173, 5, 58, 59,245,212,117, 72,145, 4,238, + 61, 72, 1, 40,113, 76, 89, 54,221,212, 94, 39,183,111,221, 28,188,108,209, 60, 56, 88, 14, 31,127,254, 29, 62, 24, 61,242, 36, + 2,234,246, 12,174, 29,113,243,210,225,223, 21, 61, 39,254,140,148,184, 27,217,172, 77,191,163, 42, 36,235, 41,217, 2, 4, 78, +224,201,130, 66,189,202,198, 66,134, 50,120,159,205,193,191, 82,203, 49, 90, 88, 28,254, 59, 27, 71,246,239,128,187, 90,249, 74, + 54,220,221,221, 27,116,236,216, 9, 4, 45,129,157,177,193,206,242,176,151,138,209,114, 48, 60, 24, 65, 4, 69, 64, 83, 20,220, + 63,208, 0, 86, 93,185,182, 70,141,234, 81,208,176, 73,203,221,223,126, 62,110,200,144,247,198,160,109,228,155,136,187,251, 23, +252,130,234, 67,229,225, 35, 92, 73, 42,100,219,213, 15,166, 71,247,111, 77, 68,215, 12, 67,237, 6,237,241,232,254,245, 38, 98, +177,248, 94,234,227,135,229,186, 36,179,179,179, 75,246,156,154,213,178,101, 75,164,166,166,162,160, 84,189,215,169, 91, 27, 0, + 16,255,208,185,136,161,132,100,241,124,217,237,116,252,130,219,208, 91, 56,248,120, 74, 64, 17, 36, 32, 8,168, 21, 32,199,141, + 71, 5, 24, 57,187, 16,145, 13,189, 16, 28,160, 0, 4, 1, 70, 43, 3,187,157,135,131, 7,236, 86, 22, 20, 89,238,146, 65,142, +227, 56,142, 20, 24,234, 86, 76, 60, 36, 98, 17,220,139, 76,144,203,229, 16,139,243, 64,144, 36, 88,150,135,131, 97, 96, 49, 91, +176,251,198, 85, 8,156,131,226, 56,142, 67,177, 27,180, 26,213,168, 70, 53,254, 27,241,255,113, 32,124,105,114, 85,190,162, 85, + 17, 66,106,250,225,239,152, 36, 52,169, 31, 10,119, 55, 53, 30, 38,164,131, 34, 69, 32, 9,128, 97, 93, 39, 67,130,131,217,185, +108,153, 59, 82,146,148,228, 79, 63, 39,213,254,120, 82,237,164,101,203,220,175, 8, 14,102, 39,128,145,130, 0, 56,201,150,147, +112,113, 85,224, 5, 2,207, 4,249,121, 41,168, 27, 79, 76,249, 36, 73,217,188,221,101,188,183,187,148,244, 86, 75, 68, 98, 17, +197,179, 2,233,168,169,169,109, 21,120,222,149,115,245,158,115, 29,114, 28, 7,130, 32,185, 98, 34,166, 76,203,183, 64,103,165, +144, 83,100, 67,161,193,129,122,129, 74,156,137,222, 99,230, 24,203,182, 50,213, 54,145,216,189, 78,237,154,248,102,206, 50, 88, +108, 28, 30,101, 24, 33,150, 74,253,253,252, 27,221, 25,249,209,116,233,148,245, 9, 24,219,197, 27,159, 95, 74,200, 48,231,200, +166, 87,165,102, 57,142,131,197,106, 23,231,228, 21,122,234, 13, 38, 55,185, 76,106,241,245,114,207, 43,235, 94,171,253,213,198, + 89,133,140, 70,223, 72,127, 88, 29,195, 97,177,177,248,235,236,190, 87, 49, 19,234, 87,163, 38,140,246, 82,228,170,152,108,149, + 38, 93, 34,149, 47, 0, 34,180,178,108,223,191,119,243,221,251,247,110,254,120,253,202,133,237,139,126, 59,219,120,203,154,239, +177,250, 96, 2, 40,138, 34, 4,134, 21,173, 60,152,132,154, 30,148, 96,100, 68,132,149, 35, 96, 42,208, 34,162, 77,175, 70,219, +215,126, 59, 29,206, 45, 35,108,174,144,173,194,156, 27, 79,235,253,196,241,167,235, 22, 80,120,103, 83, 81,194,185,213, 78,138, + 79,209,123,202,102,237, 14,187,198, 93, 34,112,172,131, 47,189,163,149,187,156,128,192, 3,215, 99,115,112, 43,158,132,183,155, + 24, 42,185, 8, 12,203,195,108,103, 97,177,114, 36,207, 58,108,229,212,247,173,149, 43,150,127, 63,124,248,240, 73, 59,118,205, + 58,212, 44,234,179,126,250,162,124,136, 36,114,136,105, 49, 72,138, 4,203,113,176, 91, 77, 40, 44, 42, 64,210,159,127, 28, 26, + 58,100, 96,139,149, 43,150,127, 95,178, 74,177, 26,213,168, 70, 53,170,241,111, 83,179, 94,130, 75, 68, 75,165,144, 65,160,100, +184,116, 51, 1, 17, 13,155, 98,211,161,107,168,219, 36, 18, 89, 6, 22, 2,200, 74, 87, 27,150, 96,218, 12,203, 45, 0,183,250, +245, 83,212, 28, 56, 48,176,187, 32,136, 78,255,188, 78,159, 14, 0,161,141,157,102,120, 94,128, 32, 0, 2,239, 36, 92,174, 75, + 58,116, 74, 82,150,190, 86,109,127, 37,238,167, 59,108, 74,169,152,244, 84, 74, 40, 95,119,137, 88, 76,211,224, 4,194,150,149, +149, 96, 35,128,100, 87,204,189,232, 58, 84,168, 2,142,117, 29,176, 88,155,156,170,187, 81,175,192,220, 76,231,144, 64, 16,128, +122,129, 74,196, 92, 61,202,229,100, 60,126,100,201,137,251,165,108,149, 12,148,131,229,113,231,137, 14, 69, 38, 6, 69, 70, 7, +222,232,220, 87,252, 70,183,126,184, 20,147, 7,158,101,176,232,215,163, 6, 78, 96,134, 2, 15,152, 42,100,154,252,251, 86,108, + 77,109,161, 73, 42,162,233,162,250,117, 67, 18, 37, 98, 17,171,215,235, 37,207,223, 69, 65, 41,151,160,192,200, 0, 0, 83,213, +214,163, 51, 49, 56,116, 53, 27,135,247,109,135, 92, 46,135,240, 10, 45, 80, 44, 22,123,136,196, 50, 56, 76, 78,119, 97,201,199, +241,194,135,164,165, 0, 73,123,184,104,246,129,221,110,249, 43, 41,238,106, 3,174,115, 93,106,116,183,218, 24, 53,126, 42, 2, +235, 52, 65,223,190, 3,209,180,182,154,216,119, 37, 21, 12,195, 26,252,195, 26,169, 5,231, 42,219, 71, 0,154, 1,184,234,138, +178,165, 46, 85,239, 13,222, 8,107,246,140,104, 1, 5, 41,183, 43, 92,197,202,217,243, 51,204,118,146, 20, 4,190,204, 41,131, + 8,128, 96, 7,114,178, 4,100, 3,160, 73,128,166, 72,128, 32, 40,142,227,202,172, 39,150,101, 79,241, 60,159,179,117,235,214, + 28,142,227,110,221, 60,186,244, 78,157,183, 38,206, 2, 91, 0,134,113,134, 51, 74,164, 10,240, 4,137,132,139, 27,103,113, 14, +203,193,173, 91,183,150,108,239,112,175,186, 47,172, 70, 53,170, 81,141,127, 11, 74,159,113,248,118,105,242,229, 18,209,226,120, + 1, 62,222, 94, 96, 4, 26, 73, 57, 58,152, 8, 13,172,102, 1, 28, 71,128, 19,132,138,182, 26,239,134, 50,150,231, 31, 58,148, +149, 14, 96,195, 11,154,212, 83, 37,235,233,119,217, 46,153, 50,109, 18, 2,119,230,208,241,243, 67,250,117,232,226,249, 48, 43, + 59, 93, 44, 34,105, 90, 76,137,196, 52, 73,136,105,210,238, 38,167,169, 61,235,118, 72, 4, 2,231, 43,179,105,181, 90,209,173, +219,243, 7,147,199,197, 94,209, 20,228, 62,178, 11, 4,207,251, 74, 12,240,113,247, 69, 98,114, 42,206, 30,223,103,206,201,120, + 28,199,217,172,253,241, 60,229,124,102, 83, 16,248, 2,157, 13, 86, 7,135, 66,163, 3, 69, 38, 7, 88,223,118, 56,240, 87, 38, +100, 98, 10, 57,119,246, 88,180,217,233,159,218,114, 31, 39, 85, 82, 21, 95,227,185,189,180,132,244, 15,199,140, 22, 45, 95,178, +200,214,162, 69, 75,161,160,160, 0, 70,163,241, 89,153, 16, 4,100,110, 26,168,229, 52, 30, 95, 63,134,199,103,151, 89, 0,124, +235, 74,121,150,134,155,130, 70,191,182,254,176, 57,134, 35, 79,103,195,245,243, 7, 42,107, 50, 47,217, 84, 40, 20,242, 18,245, +170,244,182, 14,246, 82,170, 22, 87, 92,223, 36, 45,149,151, 97,179, 59,128,211, 47, 94,212,235,116, 71,111, 93, 57, 51,201, 58, +126, 20,114,138,108,176,228, 39,224,143, 3,191,156,117, 24, 30,117,238,177,124, 9, 57,181,127, 29,156,189, 85,160,190, 71, 83, + 0, 15, 68, 13,159, 54,248,196,246, 37, 91, 42,203,123, 9,217,234,212,161,245, 44,146, 34, 14, 11,196, 51,178,148,153,153,233, + 82,222,117, 57,143,139, 21,164, 42,249,192, 65, 16, 36, 37,240,207,157,129,248, 92, 58,121,158,191, 87, 66,154,104,130,232,175, + 86, 40,144,167,213,161,100,147, 93,171,197, 0, 47,159, 26, 32, 9, 2, 76,169,123,171, 90,239,175,128,106,155,213, 54,171,109, + 86,219,252,191,138,151,206, 56,172,130,162, 37, 32, 44, 64,137,186,129, 74, 88, 29, 26, 88,237, 28, 76, 86, 14,122,179, 3,122, + 51,131,164,108, 51, 98, 14,189,126, 10,157, 42,150,115,235,115,193,185,223, 38, 56, 94,112, 89, 61,145, 56,236,115,150, 46,154, +255,238,142, 22,205,237, 83,222, 14, 8,186,155,100,207, 36, 8,210, 66, 82, 52,227,165,166, 69, 15, 31,222,213, 94,185,120,172, +163,140,229, 70,153, 43,176,195,178,172, 46, 48, 48,176,100, 64,123,122,189, 65, 29,121,255, 63,143,126, 29,218,169,223, 34,223, +229,243,166,153, 73, 74,204, 19,180, 56,134, 99, 44,219, 45, 57,113, 63,163, 2, 93,143, 20,203, 30,252,125,251,126,164,135, 87, + 16, 30,103,152, 96,178,178,112,176, 60, 60, 85, 98,164,223, 59,233, 72,122,120, 99,151, 49,243,238,166, 87, 40,182,109,241, 15, + 98,106, 70, 69,245,124, 39, 50,178, 29,245,253,247,223, 33, 34, 34, 2, 22,139, 5, 36, 73, 34,168, 86, 29, 36,197,223,198,213, +163,115, 56,115,126,242, 47, 0,126, 4, 80,229, 3,151,243,244,118, 28,191,145,139,163,251,119,130, 18,189,210, 10, 54, 82, 46, +151,203,202, 34, 87,165, 73,215,211,155, 69, 18, 25,156,234, 19,255, 92, 67, 44, 27, 39, 18,226,239, 63,120,255,189, 97, 13,212, +238, 30,232, 61,112,104,238,149, 75,103,251,236,255, 99,221,138,252,228,180,119,191, 91,176,202,173,123,171, 0,194, 75, 37, 65, +145,137,199,182,148, 7, 97,112, 81,131,205,206,206,158,157,150,116, 99,228,159, 71,191,238,219,169,223, 34,223, 27,123,103, 62, + 13,162, 39, 41,122,107,101,207, 23,164,221, 60, 91, 85,146, 85, 66,181, 4, 65,112,201,113, 46, 0, 16,137, 37,208,104, 2, 64, + 16, 0,195,242,176, 51, 44,104, 81,245, 74,195,106, 84,163, 26,213,248, 15, 99,252, 11,223,174, 41, 90, 86,171, 53,233,205,110, +125,193,243, 2, 56, 1,224,185, 98,229,137,127,166, 62,113,140, 53,233,117, 83,199,243,220,181, 53,235, 55,244,110,209,166, 19, +213, 48, 88, 5,125,126, 54,174,254,121,142, 5, 47, 92,113,229,249,252,252, 71, 70,185, 95,221,119,222, 29, 60,112,247,232, 49, + 19,139, 58,118,238,172,212,104,252,109,233, 25,233,230,141, 91,182, 50, 39,143, 29,236,200,131, 29,150,159,255,216, 88,145, 29, +157, 78,183,178,172,235, 82,137,234, 13, 0,161, 20, 77,216, 45,218, 71, 85,138, 8,207,203, 72, 27, 52,127,206,172,228, 17,227, +166, 74,194, 2,235, 32, 87, 71, 33, 41, 61, 27, 15, 47, 30,180,101,196, 95,223,175, 79,191, 53,214, 69, 83, 89,101, 92, 75, 7, +176,252,234,213, 43,141,162,162,162,122,118,233,210, 69, 24, 63,126, 60, 4, 1, 56,187,126,146, 80,144,116,117, 79,177,138,245, +228, 21,235, 37,229,226,149,219, 94, 67, 58,182,162,189,213, 99,177, 97,231, 49, 6, 2,159, 82, 69, 51,126, 53,131,107,209, 78, +119,161,115, 75,135, 23, 63,118,230, 89,252,152, 88,229, 71,155, 17,227, 87, 78,126, 95,226, 26,143,227,239, 55,121, 28,127,127, + 12,128,220,221, 91,127, 61, 12, 0, 54,139,101, 98,244,217, 67, 41,247, 99,111,140,234,247,222, 23,117, 26, 53,107, 77,239,217, +180, 28, 14,171,105, 31, 0,151,219,171, 84, 66, 37,151,212,123,101,174,194,151,234, 61,249,234, 49,130,164,104, 87, 73, 83, 41, + 37,146, 20,120,222,165,128, 58,129,231,144,241,228, 30,188,252,131,161, 86,187,131, 23, 28,128,221, 6,109, 90, 28, 56,174,250, +172,195,106, 84,163, 26,213,248, 15,225,213, 99,180,210, 30, 56,247,211,250,119,195,144,157, 59,114,211,166,205,115, 55,111,217, +241,134,213,110, 15, 20, 32, 78,227, 88,251, 5, 35,135,239, 93,181, 97,201,121,124,195,219,187, 94,227,141,191,174,249,118,227, +134,159, 58,129,231,234, 19, 64,178, 64,224,188,140,225, 70, 87, 70,178, 42, 28, 52,243, 12,235,186,191,179,196,146,159,111,220, + 92,213,103, 45,249,113,217, 36,229, 8, 90,183, 98,206, 98,146,164,122,112, 28, 47,226, 57,230, 49,231,176,254,203,162,141, 59, + 4,151,163,220, 80, 80,193,191,197, 2,136,141,142,142,238, 16, 29, 29,221, 6,192, 74, 56,207, 80,188,241, 58,245, 98,203, 55, +116,253,114,218,151,103,191, 0, 17,194,243, 2, 88,142, 79, 17, 91,204, 93,171,104, 38, 40, 44,172,142,194,193,112, 47, 5,192, +151, 14,132,127, 74,180,220,107, 42, 0, 4,185, 72,180, 0,231,106,186, 95, 95,186,200,178, 11,179, 50,211,118,254,252,175, 79, + 39, 0,168, 13,224, 50,128, 53,255,169,122,119, 88,245,121,255,238,247,134,117,216,102,167,223, 61,132,204, 88,113, 0, 65, 59, +183,114, 16, 56, 59,120,214,158,197, 50,142,217,213,125, 95, 53,170, 81,141,106,252,199,212,172,245,101,253,166,255, 91, 82, 88, + 88,248,196,128,194,138, 15,233,117, 5,249,249,143,140, 0, 94, 90,185,103,126, 77,187, 49,143,244,123,241, 72,191,247, 85,159, + 55,229, 38,106,129,196,209,175,153, 12, 87, 2,217, 47, 21,127,254, 17,228,229, 61, 48, 33, 15,109, 95,183, 90,182,109,221,242, +112,199,142,157, 34,129,164, 68,188, 64,137, 89,129, 16,177, 60, 33, 98, 24, 30, 54, 7,195, 56, 88,150, 1,199, 58,192,115,140, +192, 59, 24, 56,119,135,255, 39,144, 2, 96,198,255, 84,189,255, 39,192, 50,142,217, 96, 28, 0, 76,213, 93, 93, 53,170, 81,141, +106,252,119, 17,174,255, 30,162, 85,141,255,213,120,146,240, 56, 62,178,186, 24,170, 81,141,106, 84,163, 26,255,203, 73, 86,233, +111, 0,206,216,243,110,229, 60, 80,149,213, 4,221, 94, 33, 65,103,170,109,190,182, 77, 17, 0, 9, 0, 21,128,202, 92, 91, 61, + 81,245, 13, 43,255, 39,242,254, 53,128,219,213,245, 94,109,179,218,102,181,205,106,155,255,107,109, 86,102,187,122, 53,227,191, +153,128, 85,219,172,182, 89,109,179,218,102,181,205,106,155,213, 54,255,239,217,252,255, 25,227,203,248, 0,168,118, 29, 86,163, + 26,213,168, 70, 53,254, 15,194,219,187,158, 10,120, 26,215, 91, 41, 20, 62, 13,252, 0,192,156,247, 32,167,186,244,170, 81, 6, + 74,159,115,248, 92,140, 22,249,138, 6, 69, 36, 45,249, 82,161,246,126,160,116,247,206,248, 63, 94,184, 68,120, 45,229,228,238, + 29,107, 31,136, 8,149,247,175,202,131, 10,223,240,223,253,235,180, 77, 85,106,194, 39, 35,160,133,252,117, 18,161,212,132,250, +170,130, 90,253,169, 14,108,212,235,223,144, 71,105,195,134, 13,219, 53,108,216,176, 29,128,127,228,148, 98,133, 38,124,120,205, +186,145, 23, 53, 97,205,207, 41,253,234, 13,254,167, 19,172, 10,168,235,173, 10,106,185, 87, 85,163,105,161, 42,160,169, 94, 85, +179,229, 5,181, 79,131,176,202,158, 11,234, 55,191,254,236,237, 49,219,131,250,205,175, 95,214,191,123, 70,173, 82,255,176,227, +209, 60,239,190,255, 82, 85,247, 43,175,134,160, 55,134,123, 4,116,250,194,187,170,207, 5,134, 71,198,214,106,212, 33,183, 70, +189,182, 49,174, 62, 83, 51,162,221,173,144,134,111,228,212, 12,111,119,163,186,228, 93,131,204, 55,180,157,204, 51,248,168,212, + 51,248,152,212, 43,180,243,235,218, 11, 8, 8,144,215,175, 95, 63, 42, 50, 50,114, 66,215,174, 93, 63,107,222,188,249,248,144, +144,144, 30,255,147, 19,125,133, 38,124,134, 77, 68,228,217, 68, 68,158, 66, 19, 94,233, 98, 25,165, 38, 98, 46, 65,114,153, 4, +201,101, 42, 53, 17,115,255, 91,234, 74,234, 23, 30,162,208,132, 47, 83,251, 55,188, 38,215,212,235, 91,213,231, 61, 61, 61,123, +248,250,250, 14, 40,249,120,122,122,246,168,126, 3, 94, 25,165, 85,172,215, 86,180, 40,145, 84,113,121,196,152,143, 27, 47,156, + 53, 93,182, 98,195, 1,172,152, 55,237,190,205, 84,212,240,191, 49,231, 62,161,109,110, 80, 36, 85,179,244, 53,142,231,210,243, + 18,175,181,250, 39,236, 71,212,146,143,253,246,171,145,159, 15,127,183, 91, 72,183, 62,159, 18,113,137,150,131,174, 83, 52, 52, +219,181,119,127,208,197,243,231, 86,109,216,176,254, 71, 45, 27,177, 76, 36,165,215,232,211, 98,139,170,146, 6, 55,223,176, 80, + 90,233,115,241,205,254, 31,251,223, 60,179,117, 19,103,231,187,155,243, 74,157,254,253,234,240,173, 83,167, 78,107,138,162,188, + 39, 79,158, 44, 6,128,229,203,151,215,229, 56, 46, 63, 33, 33,225, 58, 94, 97,243, 83, 39,193,140, 24,185,114,241,236,205,189, +122,245, 70,102,158, 9,139,150,173,125,235,196,145, 93, 67, 76, 57,143,246,252, 19,117,226,225, 81,219, 13, 98,245,189, 79,191, +250, 81, 19,245, 86,107,202,104,101,113,226,226,237, 14, 91,215,254,120, 13,104,208,198,144,247,160,220, 61,197,120,179,110,166, +159, 74,136,226,205, 58, 0, 24,254,210, 96,175, 98,186,249,202,185,168, 0, 41,125, 59, 31,168,244,208, 71,143, 90,111,156, 20, + 73,165, 33, 36, 73,130, 36, 0,146, 36, 64, 17,132,243,156, 80,135, 37, 37,227,225,165,158,255, 13,239,137, 58,184, 77, 54, 40, +218,155, 36,158,165,143, 32,139,191, 5, 65,159,253,232,178,247, 63,240,223,184, 55,174,235,209,232,141,186,166,141, 23, 18, 11, +148,116,199,207,142, 18, 2,249, 83,234,165,101,119, 92, 34, 0, 50,153,231,225,195,135,125,163,162,162,220, 53,141,250, 95,112, +229, 25, 9,101,108,120,228,200, 33,113, 84, 84,207, 42,180,207,240,238, 32,201, 45, 4, 32,226,121, 97, 57,197, 11,187,140,249, +241, 9, 64,213, 78,159,146,107, 34,198,146, 16, 92,238,103,120, 16, 55, 44,185,113, 27, 94,181,112,105,169, 91, 87,145, 88,252, + 89,104,120,147, 22, 25,201,143,111,152,140,134,101,172, 77,119,161,202,134, 24,246,203, 51,151,110,246,162, 69, 34, 34,170,107, + 91,202, 6,156,123,157, 74,247,243,243, 27,176,122,245,234,176,118,237,218, 1, 0, 88,150,117,219,189,123,183,255,156, 57,115, +148,241,241,241,251, 94,209,108,160,175,175,111,176, 68, 34, 9, 4, 0,187,221,158,161,213,106, 83, 1, 84, 58,241, 87,250,133, +249, 64,192,143,151, 46, 94,164, 1,160, 67,135,142,115,131,223,252,196,147, 18,171, 44,101, 22,135,221,160, 44, 74, 56, 55,245, +234,223, 87, 8, 0,136,108,219,110,186,194,167,193,154,255, 73,101, 75,166,137,104, 75, 2,159, 71,118,232, 54,104,232,176,145, +100,163,122,193,232,209,189,203,215, 22,224,112,149,218, 12, 77,203,175, 93,187, 86,135, 36, 73,138,101, 89,107,100,100,100,234, +235,164,171, 70,120,187,191, 8,144, 65, 14,214,254,171,246,201,141,185,192, 75, 7,199, 80,238, 65, 45,190, 5, 69,143,227,121, + 62,205,144,122,163,253,255, 66, 69,235,229,114,174,170, 37,146,150,124, 54,252,131,143, 26, 79,253,226, 27,217,167, 43,162,113, +116,237,244,188,255, 86,146, 5, 0, 20, 73,213, 60,121,234,164, 70, 33,161, 0, 0, 70, 43,139, 94, 81, 81,149,143, 8,181,218, +156, 39, 9, 34,162,228, 40,113,142,117,200,104,145,196, 74, 56, 9, 18, 8, 0, 62, 53,106, 69,251,177,151, 21,195,223,237, 22, +178,101,199,233,244,212,244,252, 42,119,106, 4, 37, 70,100,199, 30,232,214,189,167,251,181,191,255,250,113,253, 47, 63,207, 96, + 29,204,207, 60,195, 47,179, 22, 60,206,172,180, 51,247,175,215, 82,162,242, 57, 49,104,194, 28,111, 43,233,133,239,231,173,244, +185,120,124,219,133,140,180,102,124, 74, 74,154, 85, 32,136,251,133, 5, 89,159,153,178, 19,226, 92, 45, 50,149, 74, 21,166, 82, +169,154, 53,109,218, 84, 54,109,218, 52,209, 91,111,189,245,140,178,143, 31, 47, 62,127,254,124,192,146, 37, 75,122,223,189,123, +215,106, 52, 26,239, 24,141,198, 39,168, 66,160,189,191,191,239, 39,239, 12,236,139, 46,131, 62, 6,199, 19, 24,255,209, 84,156, + 60,190,111, 34,128,127,132,104, 49, 10,183, 57,227, 38, 76,243,141,108,221,156,250,113, 91, 28,228, 18, 26, 61, 91, 69, 16, 31, + 76,158,233,177, 97,213,143,191, 33, 15,157,202, 82,178,120,179,110,102, 99, 31,251,176,126,237, 66,113,104,187,125, 24,186,126, + 5, 82,225, 62, 55,237,208, 55, 15, 1, 32, 44,106,178, 90,202,105, 87,215,240,160, 52, 82, 78,187, 58, 44,106,242,153, 39, 39, + 86, 27, 42, 74,139, 72, 42, 13,217,190,109, 91, 61, 79,181, 24, 52, 73,128,162, 8,208, 20, 9,171,157,195,144,119,135,253, 99, +205, 92,174,169,215,155,116, 30,150, 13, 30,248,221,146,251,232, 88, 85,234,132,160,196,222, 71, 14,237,167, 53,238, 82, 80, 20, + 1,138, 4, 40,146, 64,114,142, 5, 99,199,126,224,254,186,132,189,215, 27,154,214, 95, 14,141,232, 25,217,216,171,233,206, 43, +132,123,100,175,161,222,121, 86,197,251, 59, 14,158, 27, 38,116,152,250,183, 32,240,139,211, 47,175, 60, 85,145, 17,155,205,150, +211, 51,170,151, 27, 65, 43, 21,103, 14,108,234, 72,147, 4, 24, 78, 0,203, 9,224,138,207, 70, 37,138,103, 48, 36, 73, 64,224, + 5,140, 27, 55, 22, 61,163,122,153,121,150, 79,119,189,147, 35,183,156, 56,243,167,175,141,225,177,100,245,134, 31, 77, 58,237, +143,137, 15,189,147,141,186,188,169,150,220, 71, 46,159,131, 65, 66,104,149,246, 36,102,194,182, 35, 87,209,184, 97, 3,112,188, + 51,157, 17, 53,149,216,118,244, 42,234, 71,212,119,166,155, 23, 16, 30,164, 66,235, 86,173,129,151,142, 38,115,149,100,169,191, +239,244,246,200,217,125,134,140,129,198,215, 23,164,192,244, 57,115,116, 91,159,223,127, 90,252, 37,107,213, 47,169,146, 49,129, +123, 58, 46, 8, 60,255,218,170, 83,141, 26, 53,124, 91,183,126,182, 29, 35,203,178,168, 93,187, 54, 50, 50, 50, 34, 94,101,158, + 22, 16, 16,240,246, 15, 63,252,160,233,221,187,183,200,223,223, 31, 0,144,157,157, 29,120,226,196,137, 22, 63,252,240, 67,110, + 86, 86,214, 81, 84,176,163, 15,199,144, 98,146, 6, 37,147, 41,156,121, 4, 65, 78,251,100, 84, 83,191,128, 26,101, 30,228,174, +213,102, 75,190,250,248, 28, 65,211,226,226,251, 65, 10, 2, 79, 84,160, 18,117, 19,137, 68,101,122, 40, 28,148, 91,164, 32,114, +255,144,164, 72,103, 99,101, 25,109, 97,234,173, 6, 85, 80,226, 26,137, 36,226,159,223, 25, 58,166,253,224, 65,253, 17,224,235, +142, 51,151,239, 98,226, 39,159, 51,172,131, 89,246, 74,157, 7, 69,209,185,185,185,201,158,158,158,254,175, 63,222, 18,161,167, + 79, 30,215,156, 57, 27, 61,125,233,138, 85,147, 28,118,150,225, 5,225,233, 57,198,114,185, 84,212,189,207,187,110,154, 58,145, +178, 85, 63,124, 40,250, 95,168,104,173,255, 71,136,150, 68,174,126,247,187,175, 38,203,230,108,189,138,163,107, 39,230,153,245, +121,190, 79,103, 10,110, 30,183, 76,250,162, 22,175,146, 66,149,111,120, 59,130,162, 39, 16, 20,165, 36, 72, 66,194,115,124, 26, +107,183,207,181,228, 63,202,122,221,220,243,188,128,189,127,229, 86,141, 0, 9,168,187,101,231,126,141,159,135, 20, 86, 7,135, +161,195, 71, 98,243,230,205,106, 95,119, 9,172,118, 22,139,151, 46, 53, 24,147,143,106,146,211, 10, 51,186,245,253,252,212,147, +164,220,152,212, 44,235,174,170,166,205,230,224,160, 55,179, 48,219, 72,212,107,212, 26,139,151,213,151,165,166, 36,126,190,233, +247,223,166,220,191, 79,109,230, 41,114,182, 53,235, 65, 90,153, 47,157,127,227,158,110,158,222,219, 7, 78,152,231,241, 40,151, +134, 0, 7, 18,220,100,120,247,253, 41,110, 97,254,114, 40,101,148, 71, 98, 74, 70,192,180, 47,191,188,252,132, 19,218,232,181, + 79, 18, 43, 75, 79,173, 90,181, 6,245,233,211, 71,241,197, 23, 95,136,130,130,130,240,251,182,221, 33, 29,122, 14,233,155,153, +149, 19, 36, 8, 2,252, 52,154,180,113, 31, 12, 57,124,236,216,177,148,180,180, 52,209,162, 69,139,218,238,223,191,191, 97,118, +118,182,203, 51, 83, 78, 16, 96,181,113,224,138, 7, 72,173,206, 86,101,126, 26, 24, 24, 40,205,200,200,176,149, 82, 25,136,103, + 66, 33,209,179,107,167,182,244,186,227, 73, 48, 90, 57, 40,101, 34, 36,229,152,209,170,121, 19,226, 87,142,109, 86,150,193,177, +239,190, 61,211, 79, 37, 68,245,107, 23, 10,141,167, 2, 27,215,204,195,161, 43,137, 81, 57, 70, 2,171, 5,106, 66,128,148,238, +174,228,179, 86,191,213,170,142,127,151,150, 33,184,222,170,142,255,197,155,113,241,242, 33, 75, 39,103, 24, 69,103, 10, 79, 76, + 49,148,221,241,144,240, 82,139,177,225,100, 10, 20, 50, 26, 74, 25, 13,165,212,249, 77,146,196,235,205,106, 3, 26, 4, 81, 60, + 55,150,162,232,177,195,222, 29, 82, 99,196,176, 33, 2, 40, 18,187,247, 30,238,191,117,235,150, 44,198, 97,255,141, 35,169, 13, +229,181,159,231, 10,148, 4, 52,238, 18,124,249, 91, 12,220,228, 34,168, 21, 34,184, 41, 68,232,210,212, 23, 20,249,202, 73,244, +156,216, 63,172,247,196,129,181, 58, 71, 4,171,234,221, 73,208,221, 31, 59,247,198,138,243, 69,157, 63, 91,179,188,161,183,177, +200, 78,127, 63,109, 28,157,158,153,217,121,247,225, 11, 93, 56,251,152, 56,214, 97,250, 70,123,119,119,153,170,112,122,220,149, + 22,129,145,131,101, 14, 35,115,239, 78, 92,122,157, 66,155, 20,177,201,122, 40,101, 52, 84, 37,101, 43,163,161,148,137,160,146, +209,200, 76, 79, 66,129,137,186,156,225, 77,118,198,133, 43, 85,218, 38,223,234,224,112, 59,209,136, 90, 17,205, 17, 16, 80, 3, +246,222,239,213,250, 59,122,239,193,107, 23, 14, 44, 48,103, 63,252,198, 85, 59,219,142, 92,197,244,169, 19,110, 18,192,173,226, + 65,186,197,247, 11,215,182,252,113,250,199,207, 93,155, 54,123, 85,203, 87, 87,178,212, 51,187, 12,252,104,118,135,238, 3, 97, + 40,200,193, 95,167,118,161,103,159,119,240,222,152, 79,225,225,225,179,120,217,220,175,238,176, 54,125,244, 75,125,174,127,253, + 55,155, 52,110,176, 53,176, 70,141, 32,158,119,158,242, 33, 8,128,209,160,195, 87,159,141, 3, 47, 8,104,214,162, 77, 23, 89, +135,238,130, 80,124, 26, 72, 94,126,158, 41,238,225,253,110,214,220,184,191, 93, 46, 75,171,149,209,106,181,184,125,251, 54,226, +227,227, 17, 27, 27,139,252,252,124,184,187,187, 27, 77,166, 42,237,253,230,214,180,105,211, 17,209,209,209, 50, 79,207,103,135, + 52,216,237,118,168,213,106,140, 24, 49, 66,212,163, 71,143,192,183,223,126,123,116, 76, 76,204, 54, 0,250, 50,211, 83,240, 56, + 83,237, 23,241, 75,167,183, 58, 77, 2, 0,185, 91, 64,226,234,223, 15,199, 86, 56,161,117,175, 17,210,190,253, 27,117, 32, 8, + 32, 32,172, 52,231,199,103, 87,160, 18, 41,175, 94,189, 26, 70, 81, 20,253,108, 12,226,241,211,198,157,245, 79, 95,186, 55,104, +225,226, 37, 50, 55,165, 20, 90,157, 29, 31,190, 55,208,229, 49, 88,238, 23,209,187,125,251,142, 7,127,156,253, 29,173, 82, 42, +113,234,239, 39,152,252,217,151,214,172,228,152, 37, 2, 47, 90,107,214,198,231,190,230, 80, 41,224, 31, 64,189,154, 42,168,251, +245,148, 77, 28,213, 79,102,103, 56, 20,153, 24,216, 28, 28, 56, 94,128,206,196,224,126,170, 1, 62,110, 85, 63, 34, 76, 16,132, +214, 0,124, 1,104, 9,130,184, 94,250,119,201,132,174,132, 27,191,240, 59,175,120,124,240, 6, 96,135,115,165,254,211,230, 83, +252,187,188,235, 37,207,223, 7,208,160,216, 38, 7,224, 26, 65, 16,133,229,144,173,151, 84, 46,250,200,145, 35, 66,159, 62,125, +158,246,248, 47,254,126, 17, 82,177,168,134,210,221, 23,130,240, 0, 4,241,236, 54,141,127, 96,254,146,101, 43,188, 62,249,104, + 66,138,190,168, 32,164,248,242, 25, 87, 6, 11,154,160,150,117,122, 35,178,199,164,143, 62, 66, 68, 88, 77, 49,199,113, 66, 76, +124, 34,179,105,195,198,247, 47, 94,145,172,208,167,199,204, 44, 37, 65, 86,105,217, 39,199,115,233, 47, 42, 88, 28,207,189, 56, +187,125,249,144,106, 2,240, 80, 73,240,203,241, 36, 8, 2, 64, 64,128,187, 82,132, 29,231,211,145,120,115,159,190, 79, 51,189, +105,196,194, 89, 93, 58,247,158, 18,125, 63,193,186, 43, 55,215,122, 18, 64,118, 69, 54,203,238,208,121,216, 28, 28, 24,150,197, +158,195,135, 17,213,165, 45,218,183,111,139,142, 29,218,211, 55,110,222, 29,243,209,164,113, 65,120,182,186,227,169, 77,153, 95, +221,214, 42,119,159, 93,131, 38, 45, 82,223, 75,103, 65, 83, 64,168,191, 28, 94,106, 49,236, 44,129,100,173,163,248,205,241,192, +228,105,179,189,166,127, 62,233,152, 94, 43,105, 12, 60,112, 84,148,119,179,217, 44, 25, 57,114,164,136, 97, 24,199,136, 15, 63, +237,145,157,173,237,255,211,202,127, 73, 53, 26, 63,152,173, 44,110,198, 62,110,240,227,143,179, 67, 15,159, 56,127, 96,214,151, + 19, 15, 70, 69, 69,185,239,220,185,147,175,172, 60,159,155, 33,230,228,173,217,184,117,207,230,229, 75,230, 35, 46,165, 16, 27, +214,173,133,192,177,191, 84, 82, 84,165,109, 10, 35, 71,142,148, 31, 56,112,160,102,122,122,186,222,108, 54,107,159,211, 35, 72, +130,206, 41, 48,195, 71, 45,129,152, 38,225,231, 41,131,198, 93, 10, 17, 5,144, 4,193,149,101,115,195,174,163,115,121,179, 14, +135,182,219,135,109, 92, 51, 15, 99, 62,249, 22, 49,121,146, 19,164,194,125,238,199,195, 6, 77,247,149,115, 81, 53, 60, 72, 77, +151,150,181,160,148,137, 49, 99,202, 72,180,185,153,172,201, 40,226,191,213, 90,168,230,179, 79, 60, 61,172,251,204,243,226,136, + 83,193, 82, 43, 68, 56,177,117,113,174, 73,167,213,149,184,228,236, 54,107,138,139,205,248, 76, 25, 51,219,233,205,155, 52,154, + 55,105,252, 88,242,141,118,109, 4,146, 20, 33,207, 96, 39, 4, 1,248,108,242, 68,124, 60,113,156,127, 90,102,238,247,107,215, +254, 50, 51,250,180, 48,199,164,125, 56,171, 34,155, 36,225, 84,129, 84, 50, 26, 42,185,147,184,168,100, 52,172,118, 14, 4, 1, +202, 35,184,133,142,112, 42,185,153, 5, 41,229,206,192,159,179,233, 21,220,232,236,233, 68,117,253,194, 93,133, 87,146, 50, 99, +231,222,188,155,115, 13, 64, 65, 80, 71,143,209, 14, 86,128,209,202, 34, 41,199, 12,214, 33, 16, 99,122,133,160,246, 96, 34, 98, +254,198, 91,155,143,223,133, 91,169, 78,255, 57,155, 25, 87,247, 88,189, 27, 15, 28,186,124,213,186,235, 75,230,125, 75,229,233, +236,224, 5, 1, 50, 9, 5,185,132, 46,254, 80,176,152,116, 88,251,243,175,217, 44,136, 65,184,112,129,173, 74,251, 4, 47,188, + 55,176,119,199, 29, 4, 32, 33, 72,113,122,141,144, 90, 33, 93,251,190, 47,235,218,111, 36, 56,214, 62,253,230, 37,225,156, 57, + 55,238,172, 43, 54, 27, 55,108, 0, 2,184,101,202,141,159, 8, 0, 74, 77,248, 47,245, 35,234,183,124,241, 90,221,186, 17, 45, + 93,169,247,167, 74,169, 76,253,137,167,151,239,183, 17,141,154,107,114, 10,109,132,218,187, 38,146, 30,221,198,246,159,191,223, +194, 91,237,179,207, 30,221, 53,111,197,134,253,239,118,141, 26,136,141, 63,253,107, 70,126,214, 83,162,117,166,148, 90,245,222, +166,223,214, 7,137, 36, 82, 48, 44, 15,134, 19,156,223, 44,135,130,130, 66, 48, 44, 15,153, 66, 13,150, 39,192,112, 60, 24,150, +135,205,206, 42, 39,142,124,251, 35, 43,240,119, 89,233, 12,172,223,233,164, 88, 42, 13, 17,224, 60,187, 86, 16, 4, 36,101, 91, +200,128,128,128,109, 0, 32,149, 74, 33,149, 74,193,243, 60,110,198,105, 63,241,137, 8,159,132, 98,130,199, 57,236, 41, 69,201, +127,246, 44, 47,239,254,254,254,125, 95, 36, 89, 86,171, 21, 70,163, 17,151,174, 92,119,255,109,243,158,168,164,148,244, 48, 94, +112,183,169, 53, 97, 61, 13,185, 79,250,150, 87,158,134,156,184,143,220, 34,199,145, 95,124, 60,186,238,170, 77, 71,174, 61, 62, + 57,183,194, 56,173,218, 93,191,182,127, 49,225,157, 86, 11, 87,110,120, 84,248,231, 47, 83, 43,171, 35,154,166, 69, 90,173,246, +233,251,189,250,215,237,173,110,197,101, 12, 88,177,124,133,236,230, 19, 3,238, 37,101, 98,116,183, 96,231, 12,199,133,122, 87, +250,133,249,132,214,169,179,109,237,202,133,244,163, 76, 43,214,236,187,134,232,131,191, 92,202,206,253, 59, 10, 57, 89,150, 87, +233, 67,254, 1,162, 85,174,205,115,119,243, 96,180,178,176,217, 89, 48,188, 0,189,153, 65,110,145, 29,122,179, 3, 70, 11,139, +209,221,131,203,124,174, 18, 62,226, 75, 16,196, 17, 65, 16,250, 8,130,208, 13,128,164,228,183,115,204, 38,142, 20, 19,178,231, +126, 79,159, 62,253,155, 5, 11, 22,196,150,220, 91,114,189,228,222,138,174,151,122,222,123,198,140, 25,141, 23, 46, 92, 56,191, + 93,187,118, 59,254,250,235,175, 68, 0,133,174,186, 15,233,210,153, 57,114,228, 72,101, 5, 29,230, 96, 28, 82, 55,185, 8,161, +181,131,241,193, 55, 27,125,254, 88, 56, 54, 87, 38,161,169,227,199,143,123,229,219, 85, 32, 73,202,229, 41,138,202,183, 94,123, +177, 88,114,116,233,210,165, 24,214,183,131, 60, 53,143, 49,222, 77,181,228,152,236, 96, 53,190,225,146,185,243, 23,170, 22, 46, + 90,252,241,145, 67,124,145, 49,231,254,226,178, 93,124,173,110, 80, 68,169, 24, 44,130,128,192,115,233,133,201,215, 91, 1,192, +235,196, 98, 25,173, 12,168,226,216, 26,130, 0,204, 86, 22, 20, 69,228, 22,197,237,186, 63, 98,206,220, 46, 91,118,156,206, 20, + 72, 15,131,201,148,164,128,243,204,193, 42,195,106,231, 96, 99, 56,196,222,185,137,142,145, 13,209,190, 85,125,152,173, 28,204, + 54, 22,181,235, 68, 0,128, 79,153, 21, 71,145,137, 2,199, 88, 5,129, 83,247,105,237, 11,141,135, 4, 1,158, 82, 72, 37, 52, + 24, 22,176,216,121, 88,237, 28,146,115, 45, 48, 88,228,104,210,105, 72,168,119,192, 13, 91,118,178,252, 64, 65,234,141, 65, 21, +146, 83,142,195,166,109,123,234,102,102,230,244, 63,118, 96,171, 84,171,103,112, 55,217,132,220, 34, 27, 64,249,226,135,249,107, +164, 95, 79, 29, 63, 96,211,246,189, 41, 93, 59,180, 77,169,106,158,205,218,184, 45,187,118,239,249,165, 79,159, 1,242,216,191, +143,225,209,237,179,243, 76,185, 85,138,207, 34,155, 53,107,198,142, 31, 63,222, 48,127,254,252,160, 67,135, 14,213,214,106,181, +183, 1, 48, 30, 30, 30,245,195,235,134,220, 57,117,226,120,224,219, 3,134,136,210,243, 44,112, 87,136, 17,162, 81,224,202,165, +147,140, 68, 34, 42, 51,222,164,216, 61, 56, 28, 93,191,194,161, 43,137, 81,177,249,178,243,227,198,142, 78, 57,117, 49, 46,127, +245,230, 83,255, 10, 84, 49,183,101,188,118,245,141, 86,117,252,167, 79, 30,137, 5,171,182,224,194,205,184, 92, 19, 25, 48, 47, +203,198,158, 46, 95, 74, 7,104,138,128, 90, 46,130, 73,175,213, 37,220, 58, 17,254, 15,201,212,163, 79, 29,216, 66, 22, 24, 24, +164,229, 89,137,204, 2, 3, 56, 94,128,135, 66, 12,150, 23, 80, 84,144, 71,108,221,178, 25,215,175, 95, 33, 65,145, 31, 2,152, + 85, 97,129, 18, 78, 87,161, 74, 38,114, 42, 66,114,231, 55,195,241,136,168, 91, 7,235, 87, 47,115,243,209,248,225,205,142,174, +199, 70,171,189, 67,154,237,248,125, 53,206,255,117,235,173, 11, 43,214,180, 86,213,240, 93, 69, 16,220, 18, 8,176,218, 28, 28, +116, 69,133,144,216,211,208, 38, 80, 11, 47, 5,135,100,125, 0, 98,178, 31,169, 42,235,240,243, 99,246,223, 38,132, 1, 51,247, + 28,142, 94,208,179,251, 91,136, 73,214, 67, 46,161, 33,147, 80,144, 73, 40,136, 8, 14,203,126,254,133, 41,212, 25,250,228,199, + 30,204,123,133,246,121,166,120,246,235, 36,119,156,209,119,203,170,153,127,140,251,106, 81,207,168,129,239, 19, 49,215,207,125, + 99, 6,206,186, 54,209, 19, 92,186,198,243,174,143,113, 50,181,207,202, 41, 95,207,157,210,163,207, 16, 80, 20, 13,134, 97,255, +137,233,136, 0, 0, 32, 0, 73, 68, 65, 84,176,119,231, 22,252,190,230,135,135,118, 99,254,251, 0,120,123, 46, 53,126,215,150, +159,135,124,245,253, 50,162,113,179, 54,109,207,101,189,124,188, 39, 79, 17,235, 70,141,157, 48,212,207,207, 79,253, 76,209, 18, + 16, 30,209, 16,189,251,189,131,147, 7,247,227,126,236, 93,240,130,147, 48,241,188,128,162,194,252,108,150,177,111, 42,215,227, + 33,147,133,108,252,125,115, 61,146, 36,158, 30, 32, 63,245,163, 15,236, 19, 63,251,230,205,222, 61, 58,197, 74, 40,232,147, 83, +179, 60,174,220,122,208,132, 23,169,130,198, 78, 91, 38,182,218, 56,232,204, 12,142,109, 40,159,235,200, 60,131,219,213,106,217, +123,236,196,239,214, 75,165, 20,233,104, 20, 30,148,216, 41,178, 81, 90,112, 13, 31,195,143, 11,215,180,185,252,247,173,222,239, +142, 24, 43, 27, 93,191, 37, 81,195, 91,174,254, 96,196,192,166, 28,235, 24,101, 46, 72, 43,119,127, 65,145,194,179, 40,184,118, + 93,243, 51,197, 40,124, 31, 33, 32,244, 57,230, 65, 32,209,146, 19, 63, 8, 0, 2,106, 4, 91, 69, 82, 55, 67, 21, 20, 24, 1, + 0, 86,253,186,189,213,157,248,204,113,203,151,175, 80,220,124, 98,192,237, 39, 58, 72,197, 36, 28, 12, 15,194, 69, 81,155, 23, +168, 9,223,206,152,238, 86,104,226,112,254,174, 22,177, 55,206, 9,118,163,117,132,130,117, 27, 4,141,122, 20,128, 58, 0, 18, + 8, 66, 88,103,202,241, 63, 8, 92,168,242, 65,167, 60,239,156, 47,187,249,134,133,114,180,180,183, 72,162,108, 71, 16, 66, 35, + 66,128, 39, 32,100, 20, 20,143,169,174, 50, 53, 83, 78, 60, 22,205,255, 30, 43,127,219,143,204,124, 43,220,185, 52, 28,220, 48, + 23, 95, 44,216, 6,139,173,252,168,134,202,248, 72, 89,196,232, 69,194, 85,242,119,201,125, 11, 22, 44,232,243, 66,221,244, 41, +167,206, 94,186,175,228,249,133, 11, 23,206, 47,245,239,102, 87, 73,214, 83,162, 85,146,169, 74,200, 86,184,111, 64,200, 95, 7, + 15,236,243, 44, 52, 58, 32, 19, 83, 8,174, 93, 23,179, 86, 31,244,237,213,202, 7,121, 14,119,108, 95,191,164,192,106, 54,236, +116,169,179,208, 68,180,149,171,148,199,246,237,221,143,176, 96,141,120,235,165,130,164, 91,137,150,167, 82,175, 94,155, 34,169, +237,102,166, 7, 13, 28,168, 56, 27,125,238, 51, 35, 80, 38,209,162, 8,170,230,175,155,247,106,212,114, 17, 8, 2, 48, 88, 88, +140, 27,245,206,235, 15, 99, 2, 79,141,125,127, 52,136, 98,146,165,207,207,198, 55, 95,127,100, 85, 50,143,238,167, 38,167,102, +116,235,251,197, 89,189,145,176, 14, 29,249,209,245,251,241, 11, 10,205,230, 87, 59,228,199,102,231, 96,115,240,120,242, 36, 1, + 83, 71,119,135,136, 34, 65, 81,188, 51, 88,154, 45,191, 49, 26, 51,227, 11,224, 47, 30,188,101,233, 39,191,214,240,211,120,171, +148,114, 65,165,144, 18,141,234,215, 19, 71, 70,182,151,212,142,104, 42,190,244,192,130, 84,173, 5,137,153, 58, 72,253,154,211, +195,186,244,194,150, 21,211,222, 42, 72,189, 65,226,229, 32,197,231,112,250,252,213,190,191,253,188, 92,154, 83,228,192,195, 84, + 35,178, 11,173,200, 42,180, 33,187,192, 10,149, 92,132,142,253,198, 75,143, 30, 92,215,183,107,135,182,171, 94, 37,223,137,137, + 73, 71,147, 51,178,134, 52,109,209, 6, 91,254,248,189,131,135, 71,109,183,162,162, 36,189,171,181, 51,119,238, 92,201,194,133, + 11,233,213,171, 87,235, 35, 35, 35,253,103,204,152,209, 51, 55, 55,247, 90,173, 90,181, 34, 78,238,219, 20,221,188, 99,255,214, +224, 29,190, 29, 58,117, 22, 75,121, 26,167,142, 28,113,236,218,185, 53,223, 98, 49, 76,172,144,112, 40,220,231,230, 24, 9,248, + 6, 6,198,170, 36, 92,119,154, 44,138, 47, 60, 49,101,115, 33,176, 47, 44,106,242,153,115, 55,226,226, 91,221, 76,214, 68,223, +124,156, 91, 96,118,132, 63, 57,241, 69,133, 29, 47, 69, 16, 16, 81, 36,212,114, 26,100,113,175,170,170,209,244, 49, 8,194,183, + 68, 57, 37, 64, 20,127, 3, 4,129,204,194,212,219, 46,196,108, 16, 2, 47, 0,113,233, 38, 24,173, 78,105,190,166,143, 2,218, +156,116,252,180,106, 19,110,221,184,142, 30,189,250, 97,237,175, 91, 49,110,212, 16,107,101,179, 31,146, 44, 86,180, 74,169, 89, + 42, 57, 13,128, 64,145,137,193,222,203,105,168, 19, 74,186, 60, 48, 0,128, 90,165,128,206, 96, 1, 41, 86, 35,225,230, 49,197, +241,115,127,207,152, 57,103,249,151,133, 89,119, 83, 31,223,187,132, 8, 31, 29, 66, 3, 29,136,205,118,195,141,252,218,136,168, + 27, 6, 82,124,221, 37,219,121,177, 77, 22, 29, 36,247,246,105,213,188, 97,187, 16,141, 7, 44,118,174, 88,213,162,240,251,198, +205, 72, 78, 74, 31,155,127,255,224,173,127,130,209,154,114, 19,181, 82, 77,221,143,239,253,125, 54,113,224,136,143, 17, 16, 24, +220,172, 40,245,182,139,131,151,107,164,138,115,145,104,137, 21, 30, 51,166,126,251,175, 41, 61,222, 30,140,171,151,206,226,118, +108, 2,218,182,109,141, 94, 3,134,193,160, 47,168,191,123,243,138,238,172,217,112,146,150,178, 83,218,180,239, 66,240, 28,135, + 71, 15, 99, 18,202,178,101,201,138,187,125, 37, 43,206,237, 57,247,148, 79,253,102, 42,119,175,219, 54, 7,135,140,140,116,252, +249,215,249, 22,150,172,184, 42,109, 32, 44, 21, 83, 56,117, 43, 23,142,226, 51, 76, 59,118,234,110, 23,147,182, 14,243,150,111, +140,204,202,204, 34,149,110, 62,188, 87, 96, 3,113,128,212, 97,187,243, 68, 39,118, 48, 60,194,106, 40, 43,180,233, 91,163,238, +252,105,211,166, 54,160,196,114, 24, 76, 54,123, 86,102,134,255,250,237,231,140, 15, 30,222, 11,172,169,113,119,251,215,138,117, + 98,189,149, 64,174,206,134, 2,131,158, 24, 49,225,171, 26,191,173, 89,240, 94, 69, 68,171,140,112,145,208,163,167, 46,213,247, + 84,139, 9,163,149,229,243,245, 14,110,196,128,215, 91,116, 89, 76,178,198, 47, 95,182, 66,113,235,137, 1,119,158,232, 32, 19, + 83,144,136, 73,216, 25, 30, 46,190, 78,164,191,198,127, 98,251, 86, 77,112,242,118, 30, 40,138,132,197, 80,104,166,145, 31,223, +234,173, 30,138,150,109, 34,209,249,173, 78,120, 28, 31, 23,124,228,208,222,174, 87,254,188,144,205, 58,194, 63, 49,105,227,247, + 87, 73, 88, 48,155, 41, 70,226,255, 65, 64, 96,173, 55, 6, 13,251,192, 61, 36, 56,144,208,248,120,131, 21,104,140, 31,245,142, +203,111,190,147,152, 3, 11,231,204,128,205,102,135,175,135, 4,130, 0,108, 92, 53, 11,118,187, 29, 53,188,165,208,153,202, 63, + 77,174, 50, 62, 82,158, 10, 85,165,216,147, 82,100,172,162,235, 4, 65, 28,153, 62,125,250, 55, 0,132,233,211,167,127, 83,242, +123,193,130, 5, 22, 0,153,149,184, 14,215, 63, 71,180, 74, 50, 87,254,219, 45,142,240,241, 14,184,114,234,228, 9,247, 3,119, +120, 92,221,127, 3,111,183, 13,128,152, 38,161,112,175,129, 59, 73, 58, 28,221,247,115,209,193, 29,235, 50,108, 54,219,226,202, +125,205,117, 91,169, 20,202,147,127,108,217,201,251,120,123,147, 63,157,210, 62,201, 55,176, 79, 93, 90,241,127, 31,226,111,156, + 92, 31, 32,128, 56, 33,147,201,234,218,237,118,207,202, 42,118,227,169,148,226, 32, 94,226,159,232, 91, 65, 80, 20,183,101,235, + 22,248,184, 73, 96, 99,120, 76,255,242, 83,203,232, 30,170,162, 17,239, 14,235,210,185,247,148,104,145,178,222,217,246, 45,234, + 9,205,155, 55, 47,162, 40,202,165, 80, 10,141, 70, 51,139, 36,201,225, 18,137, 68,109,183,219, 13,118,222,170, 48, 89,237,176, + 58, 0,179,217, 10,145,216, 73, 22, 69, 20, 1,139,213, 14,179,197, 94,241,139,145, 29,115, 25, 64,184,190,148,166,116,246, 65, +152,100,219,238,131,159, 14,126,119,232,204,192,102, 3, 84, 73, 89, 58,136, 9, 7, 90, 55, 8,192,185, 19,251,133,244,228,248, +169,149,145, 44, 0,200,213, 22, 4,249,250,250,225, 86,162, 17, 25,249, 22,100, 23,147,172,172, 66, 27, 12, 22, 3,154,134,212, + 64,145, 78, 23,244,202,229, 11,236, 63,121,242,228,144,222,253,135, 98,202,151,179,223,220,240,243,146,187, 74,137,104,140, 41, +231,209,121, 87,136, 86, 76, 76, 76,193,215, 95,127, 93,231,215, 95,127, 37,223,123,239, 61, 75,147, 38, 77,100, 35, 71,142,124, +115,243,230,205, 50,133, 66,102,185,115,233,208,204, 15, 39, 79,239,191,126,229,220,102,133,133,133, 4,203, 48,199, 29,133,133, +211,141,149,144,185,180, 67,223, 60,252,225,137,227,253,238, 29,124, 15,121, 41,200, 70, 82,193, 62, 12, 13,102,237,196,131, 89, +142, 39, 39, 86, 27,228, 67,150, 78,206, 44,226,191,181,146,154,121,149,145, 44, 0, 32, 41, 2,118,150,131, 90, 46, 2, 73,146, + 37, 36, 62,224,247,157,199, 21,190,238, 18,136, 40, 18, 52, 69, 64,111,102,144,167,119,224,227, 15, 92,221, 33, 68,224, 89, 78, +128,197,206,194, 92, 60, 59, 52,232,243, 48,227,203,207,209,171,239, 64,124, 56,241,115, 20, 90,128, 27,137, 6, 56, 24,166,210, +151,130, 36, 72,152,109, 44,198,244, 8, 65,129,209, 1,147,133,133,157,229,161,144,208, 16,209, 36,148, 50, 26,110, 10, 17, 32, + 8,226,146,206, 68, 36, 18, 89, 25,134,217, 82,193,140, 30,181,131,252, 96, 97, 72,180, 25,186, 4,221,218,133, 35,246,242, 94, +250,194,213,123,161,159,125,249, 45, 62, 29,215, 23,123, 30,214,129,151, 38, 4, 42,165, 28,140, 64, 2, 16, 92, 12,216,155,197, +147,142,129,195,127,249,117, 99,220,143,223, 79,151, 21,153, 8, 72,197, 20,162,207,158,193,149,191,111,172,204,187,127,112, 11, +254, 65,136, 4,210,207,205,205, 13, 50, 9, 5,187,195,102,119, 61,116, 65,128, 0,180, 80,106,194,127, 41,158,241,183,224,120, +148,113,173,114,162, 69,203,220,166,127,242,229,143,243,123,188, 61, 24,167,142,236,193,238, 61, 59,185,118, 81, 99,169,173,191, +255,140, 55,187,245,195,155, 61,134,226,248,254,205,159,155,120,162,225,248, 41, 51,231,116,236,210, 27,167,142,238, 65, 78,118, +250, 82, 87,211, 75,137,136, 41, 93,186,247,133,213,206,161, 67,215, 62, 56,113,120,255,100, 20, 47,178,112,125, 16,123,161,127, + 6,201,126, 62,117,138, 40,183,200, 46,210,234,237, 72,215,154,145,148, 99,198,193, 29, 27, 4,215,251, 11,123,235,142, 77,107, +138,198, 47,138, 78, 11,170, 25, 96, 19,217, 44,242,248,132, 39,245, 63,252, 96,180, 40,180,110,125, 50, 87,103,131, 86,103, 67, +158,206, 6,163,149, 69,221,154,245, 72,134, 37,218, 85,181,158,125,220, 37,162,181,135, 19,225,166, 20,161,125,253, 87, 95,104, +203,243,252, 51,146,181,220, 73,178,238, 38,234, 32, 21, 83,144,138, 73, 72,197, 20, 88, 78,112,105,226, 34,215,132,247,254,248, +147,143,106,216, 89, 32, 95,103, 7, 77, 17,208,248,120, 42, 91, 55, 27,142,141, 75, 38, 3, 0,198,125,253, 19, 62, 28, 51, 18, + 13, 26, 53, 65, 81, 97,161,255,240,193,189,151, 3,216,239,106, 90,143,157, 58, 31,124,234,226,173,175, 63,158,246,131,234,221, +190,157,169,219, 79,116,200, 42,176, 33, 33,222, 80, 37,229, 13, 0, 88,142,135, 0, 1,155,118, 30,129, 92, 66, 67,171,115, 64, + 16, 4,204, 93,189, 11,106,185, 8, 89,133, 78,119,127, 69,168,144,143, 84,160, 72, 85, 65,109,236, 3,103, 44,151,175,171,138, +214,130, 5, 11, 98, 23, 44, 88, 80,166, 66, 86,138,100,189,218,161,210, 98,177,178,190,155,183,207,213, 83, 39,142,169,247,223, +225,112,238, 78, 62, 6,119,168, 9, 99, 65, 42, 22,127,249,110, 1, 1,193, 78, 82, 84,145,205, 98,222,103,177,152,230, 1,112, + 84,216,104,252,195, 91, 40,101,170, 51,107,215,255,193,250,104, 52,216,114,169, 32,189,208,196, 50,207,220, 86, 12,113,227,228, +250, 80,150,103,162,172, 57,143,175, 87, 54, 19,231, 5,136, 23,252,124, 16,128, 0,158,231, 33,240, 60, 68, 50,149,210, 39, 44, + 50,167,184,163,147,209, 36, 97, 45,221, 3, 8, 60,155,158,151, 88,177, 12, 74, 0,112, 87,136,176,243, 66, 6, 0,228, 80,134, +155, 15, 70,188,235,116, 23, 90,237, 50,125,163, 58,117,132,214,173, 91, 23,201,229, 46,109,127, 69,249,249,249, 93,155, 57,115, +102,253, 15, 63,252, 80, 42,145, 72,192,178,172,215,186,245,235,249,245,243,198, 97,208,228,181, 16, 75,164,176, 88, 29, 16,137, +104, 20,234,140, 40,210,155, 97, 48, 51, 85,111, 65, 79,158,216,181,192,162, 3,251, 37, 3,123,170,154,182,145,144, 98,180,140, + 8,192,185,147, 7,132,171, 39, 54,142,179,228,198,255,225, 98, 67,132,209,202, 32, 51,223,138,140,124, 43,178, 11,173,200, 46, +176, 33,187,208, 10,130, 32, 96,181,179,175, 53,112,153,114,227,118,111,249,227,183,126, 54, 7,134,117,236, 49, 16,159,255,176, + 54,100,203, 47, 11,207, 36, 10,228, 27, 46, 6,218,114,177,177,177,201, 31,124,240, 65,179,237,219,183, 83,141, 27, 55,182, 60, +120,240, 64, 81, 76, 34, 29, 42,149, 66,190, 97,205,130,147,109,218,180,217,153, 17,255,240,108,177, 63,189,210,142, 61,164,211, +251, 82,185,227,214,248, 96,101,251,158, 97,254, 10, 4, 43, 13, 61,235,171,238, 44,206,239,242,233,124,109,244,202,220, 44, 27, +123, 90,107,161,154,103, 24, 69, 46,197,224, 49, 54,107,202,160,193,195, 64, 17, 36, 28, 86,115, 74, 73,227,210,184, 75, 48,107, +235, 67,168,100, 34,168,229, 52, 84,114, 17,222,108,232,133, 42,244,103, 2,195,241, 48,219, 56, 88,108, 44,172,118, 22, 62, 65, +158,248,117,203,110,164,230, 90,112,240,122, 30,226, 82, 12,168, 87, 83, 9, 65,168,188,155,228, 57,198,212,247,157,247,212, 20, + 73,128, 34, 9,178, 97,253,112, 20, 24, 29, 16,211, 36,196, 50, 57,148, 82, 26,110,114, 17,196, 98, 17,114,115,115, 97,179,217, + 16, 28, 28, 44,171,152, 10, 10, 80,171,228,168, 23, 90, 3, 14,134,197,177,139,247, 49,111,234, 32,116,239,216, 10,132, 72,133, +135,182, 22, 80,123,169,193,147, 36, 28, 44, 15,187,131, 3, 64, 90,203,179, 23, 20, 20,212, 69,169, 84, 42,205,102,179, 33, 53, + 53,245,124,118,220,254, 84,142,234, 63,254,196,169,232, 45,125,122,117,199,173,187,177,216,179,255,208,165, 60,111,221,180,146, +103, 26, 53,106, 20,233,227,227,163,202,207,207,215,199,196,196, 92,123,213,121,129, 64,146,159,181,123,243, 45, 24,139,114,145, +147,150,228,242, 44,186, 65,136, 26,223, 45, 88,219, 50, 34, 60,162, 37, 39, 56,137, 87,195, 96, 53,190,248, 97, 85,203, 58,245, +194, 91,150, 44, 8,105, 16, 92,241,182,108,180, 66,221, 99,212,135,159, 47,232, 55,248,125, 68,159, 58,132,101,243,190,220,162, +116,247,109,224,229,233,222,188,113,100, 15, 92, 58,115, 8, 50,181, 63, 60,189,253,223,124,111,204, 39,221, 6,191, 55, 1, 87, + 46,157,193,202,133,223,108,230,108,134,109,174,164, 85,169, 9,245,109,214,162,205, 8,181,151, 31,138,116, 6,168, 61, 53,104, +208,180,245,136,251,119,108, 95,155,114, 19,181,175, 76, 58, 4, 1, 54,135,128, 66,163, 3,105, 90, 11,146,179,157, 68,139,231, +171, 16, 19,196,241,132, 74, 70,211, 94,204,227,224,123,103,162,133,144, 32, 63, 98,209,156, 47, 41, 7,100,208, 22, 57, 73,150, + 86,111,135, 86,103,135,209,202,192, 75, 73,131,231,248, 42,207,186, 11,141, 14,168, 21, 34,184, 43,196, 46,171,140,101,225,231, +223,119, 70,220,137,207, 28,176,108,217, 10,197,237,196, 82, 36, 75,228, 84,179,164, 98, 10, 28,207, 3, 46,188,241, 34, 90, 52, +165,127,239,110, 72,203,179, 56, 87, 45,147, 4,234, 53,105, 3, 31, 57,143,174, 67,167, 3, 0,250,246,118,134,182, 37,102,153, +112,248,170, 22,120, 62,176,187,226,190,216, 98,161,214,111, 61,250,217,238, 93, 59,220,173, 28,141,117,199,147, 97,182,177,144, +137, 41, 72,197, 20,228, 98,234,185,120,236,202,137,150, 51,230, 46, 53,143,129,217,106,133,222,194, 64, 0,112,237,177, 17, 22, + 59, 11,157,137, 65,100,125,207,215, 19, 66, 8,226,168, 32, 8,111,191, 72,136, 94, 36, 75,165, 20,169,178,108, 92, 47,109,163, +228,254,242,136, 92,233,152, 45, 0, 85, 90,193, 69,191,200, 28, 75,255, 22, 43, 61, 27,184,171,221,175,158, 56,126, 68,181,255, + 14,143,243,119,157, 36,139,177,228, 97,233,215,195,211,245, 69,121,157, 1, 60,113,245, 63, 83,248, 52,104, 42,147, 72,163,255, +181, 98,157, 67,227, 23,200,239,187, 90,148,171, 51,115,207,177, 9,206,102, 35, 5, 94, 16, 91,115, 30,187,228, 67, 32, 73,194, +241,195,228,129,224, 5, 1,179, 86,236,198,252,105, 67,161,146,191,167, 32, 8, 66, 97,178,178,152, 58,251, 55, 44,253,110,172, + 90, 33,165, 65, 16,206,152,168, 81,195, 6,186,214, 0,173, 44, 18,254,222,110, 52, 36, 30,121, 80,218, 93,216,246,205, 94, 55, +218,182,109, 91,228,233,233, 9,185, 92,254, 76,169, 40, 7,126,126,126,223,253,240,195, 15, 17, 19, 39, 78,124,186,217, 39, 77, +211,248,248,163,143, 72,142, 19,112,252,248, 70,248,214,106,129, 67,167,175, 34,170, 75,107, 24,205, 86, 20, 20, 25,192,131,122, +229,134,104, 40,202,139,206, 78,190,215,230,141,206,125,113,254,228, 1,225,234,241, 13,227,170,178, 71,143,167,151,103,218,205, +123, 9, 13, 8,194,203,169,104, 21,147, 44, 59,195, 35,196, 79,129,180,228, 4,120,184,187,167,185,106, 79,238, 27,209,159, 32, +133,137, 4,132,141,166,156, 71,187, 1, 8,166,172, 7,195,119,111, 91,127, 55, 54,230,246,188, 62, 35,166,208, 61, 6,127, 68, +253,178,224,147,111, 0,184,186,241,158, 35, 46, 46,238,254,216,177, 99,219, 95,185,114,133, 3, 96, 38, 8,130,161, 40, 74, 97, +183,219,197,157, 59,119,214, 61,124,248,240, 60,202, 14, 90,124, 14,111,126,176,219,135,144, 26,122, 73,120,199,240, 16,181,161, +123,231, 14,237,208,174, 81, 16,210, 58,180, 3,128, 41, 41, 70, 85,132,181,206,111, 59, 25, 86,126,236,151,223, 15,207, 31, 55, +180,219,212, 45,244,172,101, 89, 71,102, 85, 24,136,154,246,224, 66,207,178,104, 60, 77,145, 80,203, 69, 80,201,105,168,229, 34, +168,101, 34, 48,172, 80,149,153,163,192,176,188, 83,209,178,179, 48, 90, 88, 68,223,206, 65,182,206,142, 34,131, 3, 22, 7, 7, + 1,130,115, 54,234, 66,111,174,125,252,167, 71,201, 72,234, 17,220, 66,183,126,245, 18,183,189,151,211,159,174,232,115, 87, 72, +160, 86, 56, 87, 99, 95,188,120, 17,222,222,149,207,246,121,158,199,158, 19,215,176,108, 83, 52, 78,108,252, 10, 50, 49,133,166, +253,103,227,253, 1,109,193, 11, 60, 18,226, 98,115,234, 53,108,230, 71,146,114,144, 4, 1, 27,195, 3, 16,202, 45, 79,187,221, +238,157,154,154,170,175, 91,183,174,127,141, 26, 53, 6, 83, 20, 37,192,112,219,118, 96, 71,129,249,236,145,109, 10,147,197,198, + 41, 88,221,198,186, 89,150,183, 81,183, 46, 8,130, 16,220,220,220,196,209,209,209,198, 38, 77,154,248,190,226,171, 68,202, 53, +225, 43, 63,156,244,217,224, 58, 97, 97,216,189,109, 35, 4,129,216,235,234,195, 91, 15, 95,193,156, 25,207,175, 48,252,226,135, + 85, 45,151,206,158,242,220,181, 73, 51,150, 85,184,234, 80, 46, 85, 77, 27, 52,124, 60,110, 92,251, 11,139,103,127,177,195,102, + 44,120,159, 97,153, 33, 5, 89,137, 59, 66, 27,182,133,224, 48,224,212,174, 37, 24, 58,114,156,180, 71,159,193,184,114,233, 12, +230,127, 51,105,171,185, 40,247, 3,184, 24,228,204, 11,162,137,157,123, 14, 16, 89,108, 14,172, 90,244, 61, 38, 76,155,135,200, + 46,125, 69, 49,183,175, 78, 4,240,163,203,225, 16, 14, 14,157,155,248, 56,201, 51,195,227, 80, 34, 69,151,213, 2,105,138, 32, +155,135,121,192, 98,103,161,175,100, 82, 73,139, 69,217, 69, 58,125,173, 53,243, 63,163, 76, 86, 22, 90,157, 29,185, 58, 27,242, +138,158, 17,172, 60,157, 13, 90,157, 29, 34,154, 64,252,147, 20,144, 34,186,202,241,121,133, 70, 6,109,194, 61,157,239,232, 43, +122, 71, 24,218,173,237,137, 11,119, 6, 45, 91,182, 92,118, 39,201,128,187,137,250, 98, 37,139,130, 84, 68, 66, 82,252, 55,199, + 59, 99, 35, 43,130,155,111, 88,232,232, 81,239,117,117, 83,201,145,249, 40, 23, 52,229,220, 34,198, 93, 19, 4,119,169, 21,159, + 76, 26, 15, 31,111, 15,164,230,217,176,114,127, 60,238,222,127, 12,222, 82,181,108,175, 90,183, 35,234,195,143,191,240, 32, 69, + 18,108, 62,153,228, 76, 39,197,225,225,213,195,214,204,132,123, 38,163, 62, 95,128,192,185, 24,131, 76, 8, 44,231,108,110,243, +103, 77,199,142, 77, 63,225,228,205,220,167, 45,240,242,222,165,248,108,198, 92,228,233,237, 40,171, 93, 86,196, 71, 0,104, 75, + 41, 81, 47,253, 46, 69,142,202,250, 77, 20,255,182,151, 99,195,254, 2,185,178,191,112,221,254,130,189,178,246,254, 91, 95,169, +235,240, 37, 82,228,225,219, 88, 33, 83,254,117,252,248, 97,229,129,187,194, 83,146,229, 48,231, 9,243,166,244, 77,215, 23,105, +123, 84,137,100,249,214,107, 44, 85, 72, 47,204,156,187,210,230, 23, 88,139, 61,118, 91,159,111,176,114,236,203, 49, 8, 74, 78, +233,238,107,165, 37,210,101, 34,139,253,251,188,188, 7,166,202,148, 39, 94, 16,112,228,239,108, 8,130,115,138,180,235, 98, 6, +138,103,230,224,120,167, 91,229,244,237, 92,208,197,113, 40,174,202,223, 63,175,251, 73,255,118, 19,157,105,196,252, 89, 79,221, +133,145,205,156, 74,150,155,155, 27, 60, 60, 60,160, 82,169, 80,153,235,144, 32,136, 81, 31,126,248,225, 75,179,255,220,220, 92, +116,235,218, 25,171,127,250, 21,205,186,142,198,233, 63, 79,194,193,240,104,218, 48, 12,181,106,120, 34, 45,199,240, 74, 47,186, +210, 47,226,227, 54,157, 7,124,243,102,151,190,136, 62,177, 79,184,122,226,247,241, 85,221, 8,241,237,110,237, 15,207,153, 51, + 43,116,230,188, 53, 82,181,140,198, 3,163, 29, 36, 65, 32,196, 79, 1,111, 37,137,243, 7, 54, 91,135,246,109,239,242,230,120, + 65, 65,129, 91,150,174, 94,175, 92,186,112,118,231, 27, 55,137,104, 99,102,124, 1, 0,152,115,226, 22, 61, 4,238,215,252,235, +212,177,102,157, 6,194,175, 70, 88,247,196,156,135, 46,147, 13, 0,230, 39, 79,158, 36,206,156, 57, 51, 98,225,194,133, 2, 69, + 81, 60, 0,233,138, 21, 43,204,143, 30, 61,186, 13,231,210, 92, 84, 54,216,116,237,222,104,170, 74,194, 69,122, 41,200, 70, 97, +254, 10,180,107,228,244,138, 14,125,251, 77, 4, 5, 7,227, 73,182,185,121,129,153, 23, 25,237, 84,216,218,117,119,175,215,246, +161,198,177, 22,251,125, 0, 7,171, 90, 63, 4,158, 5,200,151,168, 89,106,185, 8,188,179,173, 84,137,104,217, 28, 28, 44, 54, + 14, 22, 59, 11,147,157,131,217,206,129, 23,156,239, 4, 65, 16,112,176, 60, 92,154, 54,191,208,246,221,188,124, 16, 86,155,128, +155,194,153, 54,183,226,237, 30, 8, 0,222,222,222,208,104, 52, 46,169,162,118,135,243, 21,183, 51,252, 83,183,190,221,193, 66, + 16, 4,196,199,199,125,149,156,152,216,191,110,189,186, 29, 27, 54,109,230,165,144,146, 0, 80, 46,209, 50,155,205,156, 90,173, +214,120,121,121,145, 25, 25, 25, 79,201,115,221,230,157,217,253,251,246, 98,208,160,129,198, 7,215,238, 60, 93,226,110,177, 88, +136, 55,222,120,195, 45, 40, 40,136,180,217,108,250,170, 86,147,210, 55,124,128,167,183,215,188, 81, 31, 76, 8,239,220, 45, 10, +231,206,158,194,193,125,219,255, 48,107,227, 79,185,106, 36, 34,162,254, 75,171, 14,235,212, 11,127,105,213, 97,173,208,122, 21, + 18,173,134, 77, 91,183, 21, 8, 26, 39,143,236, 18,172,164, 99, 18, 0,158,179, 26,118,237,252,249,187, 31,135, 79,156, 81,167, +119,191,225, 24, 53,242,125,208, 52,133,243,167, 15, 99,233,236,207,143, 26,117,185,163, 93, 9, 19,112, 74,111, 13,196,129,242, +160, 79,131,235, 52,198,205,171,151,144, 16, 31, 19,123,231,250,149, 70,117,155, 68,194,183, 70,200,167, 41, 62,212, 66, 60,120, +224,168,204,140,221,106, 77,121,127,244, 72,148, 94,117,216,174, 69,132, 55,241,226, 11, 0,192,108,200,117,108, 88, 50,245, 81, +201,170, 67,222, 97, 79, 41,207,174,174, 80,187,231,252,159,127, 79,235,255,118, 20,153,167,183, 59, 21, 44,157,189,248, 99, 67, + 94,201,223,122, 27,234,213, 80, 33, 46,246, 38,111,213,229,237,173,226,123,105,125,127, 72,207,251, 37,109,151,231, 5, 16,128, +181,202,110, 41,145,219,248, 69,139,151,201,238, 36, 26,113, 55, 73,239,116, 21,138, 40, 39,193, 18,145, 79, 73,151,115, 53,123, + 37,234, 16, 65,205, 31, 51,122, 24,242,244, 14,240, 60, 64, 83,100,241, 71,140, 84, 3,129, 52,131, 25,121,133, 90, 36, 38,167, +160, 40, 59, 1, 36, 73,194,167, 70,184,203, 59, 73,115,130, 36,192,108, 23,154, 12,126,187, 35,189,239,175, 44, 40,164, 52,108, +134, 28, 28,223,185, 68,107, 51,234,231, 89,204,198,125,174,236,231,248, 44, 4,129,208,234,141, 86, 63,169,136,194,238, 77,107, + 48,228,253, 73,207,245,190, 95,125, 59, 7, 32, 9, 20, 20, 26, 64, 16,132,182,106,253, 18,113,189,162,223,175,168,140,189,182, +141, 50,200,214,203, 19,133,242,103,163,194,241, 83, 39, 14, 43, 47, 39, 75,113, 45, 46,171,152,100,105,249,185,147,223, 78, 55, +232, 10,122, 2,136,175,218,188,144,236, 57,116,204,180,216,176,240,134,182,115, 49,198,164, 34, 19, 83,110,156, 67,187,193, 51, + 99,111, 28, 93,221, 91,199, 60,249, 72, 25,208,144,227, 89,118,145, 69, 27, 63,187, 28,215,161,100,246,202,221, 79,221,134, 95, + 47,220,236,252,155,227,192, 9, 60, 4, 30,248,228,187,159,193,242, 28,120,142, 3,207, 9, 96, 56, 65, 81, 89,114, 53, 53,106, +237, 43,124,184,171,254,136, 31, 95,118, 23,122,120,120,192,219,219, 27,222,222,222,112,115,115,171,148,104,137, 68, 34, 21, 77, + 63, 95,212, 41, 41, 41, 72, 78, 78,134,155,155, 27, 4,158,129,157, 1, 26, 71,246,192,189,132, 24,156,185,124, 27, 2,207, 65, +169,170,250, 41, 47, 74,191,136,143, 90,191,213,127, 77,151,126, 99,113,122,223, 58,225,250,197,195, 19, 44,185,241,191,185,172, +208,115, 28,193, 48, 12,222,238,241, 86,202,173,216,199, 39,190,157, 54, 49,170,125,159, 9,210,118, 17,129,176,218, 57,164, 39, + 39,224,252,129,223,173,225,161, 1, 39,187,118,104,155,194, 48, 12, 56,142,171,116, 32,183,218, 29,121,148, 72,174, 28, 54,108, +132,232,250,181,107,123,149,190,245,118,115, 4,121,135, 16,248,166,132, 32, 12,106,218,180, 1, 28, 12, 15,179, 89, 95, 88,213, + 60, 27, 12,134,196,141, 27, 55,134,142, 30, 61, 90,209,176, 97, 67, 81, 66, 66, 2,150, 46, 93,154,111, 48, 24, 18, 93,181,113, +234, 98,220, 10,154, 40,124, 84,162,104,165,190,217, 14,195,250,188,137, 29, 71, 47,227,252,165, 43, 72, 49,170,110, 27, 89,250, + 64, 90, 74,166,173,145,151,126,111,191,118,181,168,221,155, 10,247,198,190, 53,253, 93, 65,144,158,202,187, 48,203,228,250,203, + 13, 24, 44, 12,220, 20,206,253,158, 74,148, 45,138, 32, 92,102, 68, 4,144,120,233,202,205,198,173,234, 53,196,173, 68, 29,114, +139,108,176,216, 88,240,188, 0, 30, 2,188,213, 18,200,196, 36, 82,147, 19,193, 11,142,164, 42, 14, 21,218, 78, 29, 59,209, 0, + 1,130, 16,104, 17, 77, 67,128,115,127, 69,185, 92,110,212,104, 52, 46, 41, 90, 14,150,197,160,168,182,136,108,221, 20,253, 39, + 56,247,204, 60,251,199,116,120,170, 68,216,177,229, 55,164, 93, 92,177, 37,180,221,196, 83, 49,247, 98,223,137,189,245,215,136, + 94, 45,229,205,253,233, 76,113,121, 50,169,201,100,218, 11, 64, 34, 22,139,163, 58,118,236,232,181,119,239,222, 34, 31, 31, 31, + 94, 34, 22,107,251,245,237,195,139,196,226,130,146,123,255,252,243, 79,209,132, 9, 19,212,133,133,133,169, 57, 57, 57, 87, 0, + 48, 21, 79, 4, 35,186,129,196,118, 16,132, 76, 37, 87,164,212,174, 29, 86,163,117,100, 91,247, 1,131,134, 64, 42,145,226,244, +169, 19, 88,181,124,225, 46, 99,214,131, 49, 85, 41,201,127,106,213, 97,122,106, 82,162,217, 98,107,210,184,213, 91,196,165, 83, + 7,166, 56,224,179,156,146, 58,150,116, 27, 52,169, 78, 98,166, 17,171, 22,124, 5, 79,119, 37,146, 18, 30, 90, 30, 61,184,247, + 51, 99,213,127,229, 50,201, 2,160,200,231,222,105, 55, 50,202,211,230,224,112, 49,250,168,149,103,249,168, 43, 23,142, 37,212, + 12,111, 45,107,220,186,171,103,222,193,223, 6,153,129, 29,149,217,201,120,248,178,130, 43,216,139,146,206, 70,159,113,247, 11, +105, 68, 17, 32,224,176, 89,161,125,114,157, 53,231, 60,212,235, 51, 98, 92, 90,133,155,159,134,239,102,252,240,175,143, 90,183, +106,165, 20, 32,123, 78,193, 42, 33, 88,121,122, 59,124,212, 18, 88,244, 90, 60,186,126,194,106,214, 82, 21,238,119,198,218, 77, +138,188,220, 28,201,179,112,134,248,200,138,238,207,203,205,145,176,118,147,162,242,161,142,130,155, 82,130,123, 73, 25, 79, 3, +223,165, 34,103,108,150, 68, 68, 61,141,211, 42,233, 11, 42,193, 91, 98,153, 7, 50,242,173, 32, 32,128,231, 88,176,140, 29, 6, +189, 30, 25,153,217,200,201,206,129,193, 80, 4,133,202, 19,141,155,183,129, 90, 41,195,157,243,187, 32, 8,130, 75,251, 26, 50, +132, 40,162,117,100, 7,105, 76,178, 51, 22, 75, 38, 18,112,120,251,194,124,163, 62,183,131, 49,235,209,163,170,246,197, 44,199, +157,185,123,255, 81,163,154, 1,181,137,219, 9, 58,108,249,117, 53,236,197,202, 38,195,112,136, 73, 53, 33,171,192,140,212, 39, + 15, 4,158,227,206,224,255, 8,232,242, 5, 64,208, 77, 27, 55, 64,143,247, 6,224,167,159,126,198,147,196,100,126,222,148,222, +169, 70, 67, 81,175, 42,144,172,110, 40,222,107,195,156, 19,183,200,226,217, 58,253,208,173, 2,210, 98, 23, 42, 12,240,145,249, +134,160,195,152,165, 39, 45,134, 2, 9,103, 51,211,135,183,140,217, 94,150, 77, 39,131,134,125,222, 23, 67,161,146,211, 32, 8, + 2, 37,238,194,181,115,198, 67, 33,117,250,150, 45, 54, 22,239, 77, 93,134, 45,203, 62,135, 0, 96,248,144,203,230,242,210, 9, +231,217,133,159, 4,224, 90,205,148,228,220,140,110,125,191, 56,107,117, 72,109,125, 6,142,190,209,170, 85,171, 34,185, 92, 14, +185, 92, 14, 55, 55, 55,120,122,122,194,195,195,163,210,188, 51, 12, 99,180,219,237,222, 18,137, 4, 60,207, 35, 41, 41, 9, 73, + 73, 73,208,233,116,208,106,181, 48, 25,245,236,181,179,187,233,198,237,122,163, 70, 88, 19,132,212,107, 6, 17, 69,128,166, 73, +156, 63,244,107,121,233, 44,155,100,117,234,183,182,107,255, 15,113,122,223,122,225,250,197,195, 19, 45,185,241,191,186, 90, 71, +197,238,158, 59,131, 6, 13,106, 50, 97,194, 4,241, 15,211, 38,156, 60,122,234,124,252,238, 35,235,251, 22, 22, 22, 5, 9,130, + 0, 15,119,247,180,161,125,219, 31,238,252, 70,235,148,179,103,207,242,219,183,255, 63,246,238, 59,174,234,234,255, 3,248,235, + 14,184,131, 11, 92,246, 30, 38, 67, 92,160,104,166,162, 56, 83, 75, 83, 83, 83,115,102,206,242,167, 13,115,164,137,166, 86,106, +238,180, 52,247,200,189,194,109,185, 35,149,139,226, 6, 4, 1,145, 61, 46,151,187,231,249,253,193,200,148,233,248,182,222,207, +199,227, 62,224,194,189, 47, 62,235, 94,222,247,124,206,231,156,159,116, 28, 14,231, 70,117,153,165,111, 82,185, 91,126, 57,253, +235,156,246, 29, 58, 98,253,230,159, 58,220,186,125,167,195,253,251,137,240,245, 15,192, 43,245,131,161,230, 56,226,215,115, 23, +160,148,231,110,169,205,114, 62,209,170,197, 41, 42, 42,250,109,208,160, 65,221, 46, 94,188,200, 29, 52,104,144, 58, 63, 63,255, +210, 99,173, 88,172,166,204,152, 31,222,206, 3,176,197,191,195,200,221,143, 12,242,201, 0,190,241,243,247,195,217, 11, 49,136, +185,120,249,251,124, 27,191,185,163,134,190, 55,182, 94,111,222,232,222,109,234,241,220, 28,109,176, 99,221, 18,222,225,152,212, +165,169, 5,230,245,223,156,155, 51,175, 54,251,168,226, 31, 71,137, 1, 17,141,156, 96, 52, 51, 88, 88,233, 27,174,157,200,170, +170, 55,222,167, 50,249,122,225,168,241,227,198,221,111, 26,214,252,163,161,239,141,183,110, 30,224,139, 43, 73,114,128,195,129, +147,135, 4, 89, 89, 89, 56,191,119,157,169,232,209,221,239,121, 60,203,151,117,216,158, 40, 74,187, 22,244,216,221,177,249,249, +249, 56,123,246, 44,202, 11, 44, 87, 87,215,170, 10,173, 63,101, 22,228,100, 94,154,183,120,109,196,152,225,111,163, 87,199, 38, + 56,119,245, 62,244,101,227, 53,149, 95, 74,158, 18,243,131, 96,242,160, 0,253, 7,253, 26, 40, 52, 70, 65,234, 23, 15,138,207, +163,116, 14, 86, 75, 21,203,169, 47, 44, 44, 60,124,239,222,189,118,205,154, 53,171,119,244,232,209,194, 91,151, 79, 76,122,124, + 33, 62,253,244, 83,219, 53,107,214,216, 48,198, 46,233,245,250,228, 90,173, 59, 23, 59,100,177,177,206, 6,163, 5, 23, 46, 95, +111,212, 37,162, 57, 44, 12,184,122,245, 42,214,111, 88,175,189, 17,127,237, 91, 85,142,199,151,213, 20, 47,149,110, 79,243,243, + 93,117, 88,145,153,245, 40,245,219, 83, 71,246,110,123,181,195, 91, 24, 50,241,203, 47,207, 30,249,105, 78,139,246,189,184,141, + 94,237, 6, 89,204,175, 56,125,244,248, 66,131,178,112, 14,106,238, 59, 82,233,114, 10,197, 54,255,215,184, 69, 7,164,167,165, +226, 65,226,205, 45,218,194,164,204,180,251,188, 45,153, 25,105,227,235, 55,137,192,197, 19, 59, 39, 85, 83,104, 85,123,204,251, +186,138,215, 29,141, 62, 60, 56, 35,227, 7, 15,149, 70, 43,100,140,105,133, 2,126,182, 45,183,100,151,162,214,203,121,199,144, +151, 89,175,223, 59, 67,199, 31, 89,185,114,153,149,187,131, 13,178,139,180, 80,104, 12, 40, 81, 27,192,229,112, 16,228, 37,129, +186,164, 16,231,246, 46, 54,234,149, 69,131,128,251,134,170, 50, 37,110, 33,243,139,146,126,157,248,233,132, 51, 16, 72,125,189, + 94,233, 60,163,218,214,186,146, 71,215,222,250,116,194,207, 33,140,177, 46, 18,183,144, 18, 85,238,189, 89, 85,173, 59,135, 83, +250,250, 30,210,201, 23, 6, 83,233,248, 99, 38, 11, 96,182, 88,202, 90,249, 0, 86,113, 62,159, 83,195,186,115, 44,187,142, 92, + 66,102,142, 28, 26,189, 17, 58,189, 9, 6,163, 25, 92, 30, 15, 14,142, 14, 8,126, 37, 28, 82, 7,123,228,100,103, 34,230,151, +195, 72,136, 63,119,137,195, 48, 87,147,151,248, 75,109,246,145,181,216, 33,196,211,203,131,155,165,208, 67, 44,224,225,218,185, +163, 6,163, 94,247,109, 45,139,172,167, 50,229, 5,133, 75, 63,154,242,217,187,155, 54,110,246, 8,173,111,143,140,124, 13, 50, +242,180, 40,209, 26,203, 10, 49, 11,116,202,124,196,255,186, 57,219,172, 45, 89,138,255,136, 42, 11, 45,147, 65, 91,178,239,248, + 21,231,233,115, 22,243,146,238, 39, 27,231, 79,238,153,161, 81, 42,222,172,115, 75,214, 99, 54,125, 88,127,231,203, 88,137,167, + 78, 23, 50, 11, 44,140,225,231,203,217, 21,167, 11, 45,101, 61, 47,227,238, 87, 63,141,224,227,115, 23,118,124,115,210,169,248, +123, 37,219, 53,154, 28,233,221,164,111,139, 0,128,199,227, 85,220,202,251,102,105,181, 90,125, 13,167, 80,182,254,248,227,143, +211,198,143, 31, 47,124,248,240, 33,238,223,191, 15,185, 92, 14,145, 72,132,227,199,143, 27, 97, 49,125, 27,127,241,192,131,123, +178,147,179, 67, 90,118,243, 9,109,243, 38,108,108, 36,224,179,218,119,198,180,113,107, 48,184,101,135,222,223,117,233, 59, 6, +167, 15,252,200,174,158, 59, 60, 65,147,151,176,174,174,219, 82, 46,151,223, 2,144,248,237,183,223, 54, 95,191,126,125,253, 41, + 83,166, 36,111,253,110,206, 74, 0, 40, 40, 40, 0, 0,196,197,197,177, 9, 19, 38,232,180, 90,109, 74, 81, 81,145, 12, 53, 92, + 0, 1, 0,154, 60,155,175,214,175,254,166,233,195, 71, 89,111, 7, 52,109, 5,215,250,173,224, 17,244, 26,138, 74, 12,184,146, +148,137,228, 59,191,224,206,133,189, 71,213,182,166, 57,168,227,248,198,205,154, 53,243,229,114,185,175, 40,149, 74,143,198,141, + 27, 55,147, 72, 36,113,205,154, 53, 11,231,243,249, 25,177,177,177,169,117,201, 74, 59,183, 89,231,223, 97,228,138,180, 18,187, + 78,201,217,234,240,180, 18,187, 56,181, 80,250, 73,222,175, 43,116,155,120,222, 75,153, 33,255,214,158,205,138,125, 59,214, 45, +225, 13, 29,251,169,249,102,177,227,100,190, 88,112,170,110,205,213,220,172, 15, 70,244,249, 99,120,135,178,150,172,178,239,107, +213, 76, 95, 92, 28, 95, 12, 96, 90,252,109,171,239,110, 78, 30, 55, 47,236,213,136, 97,145,111, 12,226,154,172,109,113,226,192, + 15, 44, 37,254,215, 61,124,102,158,169,169, 69,170, 17, 16, 0, 0, 32, 0, 73, 68, 65, 84,197,108, 0, 53,158, 14,210,235,107, + 83,100, 61,189,140, 15, 37, 29,247,252,180, 97,228,190, 3,251,191,238,219,187,143,243,234, 47, 6, 98,241,218,131,144,136,133, + 96, 22, 11, 6,118,242, 29, 48,123,116,195,183,124,221, 69,222,251,206,100,156,159,184,236,230, 52,181,218,144, 80,139,150, 24, +150,159,159,127,193,214,214, 54,175, 93,187,118,173,133, 66, 33, 39, 63, 63,159,239,230,230,102,146, 74,165,250,140,140, 12,181, + 78,167,219, 7,160, 78,195,142, 27,140, 22, 60,200,209,226,208,254,125,184,126,249, 23,220,185,115,175,228,206,237, 59,171, 56, +124,182, 76,149,147, 88, 8,212,249, 3, 62, 44,149, 94,117,200,234,124,213,161, 89, 87,178, 99,235,247,243, 59,171,181,186,145, +205,218,246, 68,189, 70, 17, 92,131,209,140, 27, 87,207,224,204,222,101,139, 13,202,194,233,207,179,143,189,124,234, 7, 51,158, + 0,191,157, 61, 2,102,177,124, 15, 0,204, 98,249, 62,238,226,209,241,175,189, 57, 26, 78,110,245,154,201,211,227, 56,120,134, +209,195,173,249, 92,213,177,125,155, 14, 60,120,240, 0,119,239,222, 69, 82, 82, 18, 10, 11, 11,177, 99,199,131, 58,237, 31,117, + 81,234,169,132,219,220,238,253, 7, 14,249,121,192,224,225,162,250,193,161,220, 16, 31, 71, 56,219,242,113, 47, 41, 21, 9,177, +241,150,123, 87,142,106, 13,138,220,190,154,162,212, 42, 11, 63, 27,151, 70,238,128,121,122,249,220,133,109,218, 68,132,124,182, +224,235,214,206,174,110,149,190,143, 23,228,229, 10,166, 78, 60, 28, 18,243,251,111,181,154,235,208, 98, 54, 23,140, 29, 57,200, +194, 43,157, 40, 20, 21,237,212,101, 91,175,244,195, 84,233,207,153,197, 84, 99, 11,254,123,111,183,135,201, 98,129, 74, 99,128, + 66,165, 67,113,137, 22, 89,185, 5,184, 30, 31,143,115, 63, 31,198,253,123,215, 83,140,122,253, 73, 46,151,179, 87,147,147,112, +174,110,103,154,248,245,157,157,156,144, 82,168,132, 72,192, 71,106, 66,172, 78,165, 40,222,254,172,199,145,166, 32, 49, 43,151, +199,233, 54,104,208,224,227,157,187,247,150,190,218,182,171,141,139,189, 3,172,249, 12,137, 15, 50, 33,187,116, 92,149,124,253, +188,194,168, 87,246,120, 17,179,190,252,205,213,124,213,161, 65,167,122,235,221, 62, 29,246,243,120,124,129,197, 98,210, 25,244, +186,254,207, 83,100,189, 44,140,153, 51, 70,190,251,246,159, 62, 27,152, 44, 76,252,238, 59, 39, 52,143,127, 86, 48,154,153,205, +187,239, 92, 82,151,190,129, 84,221,177,207,211,211,169,103,249,220,133,105,105, 5, 87, 11, 11,117,103, 0,100,104,181,218,103, + 94,198,156,156,156,121, 11, 22, 44,232,165, 86,171, 27,118,236,216, 81,104,111,111,143,130,130, 2,156, 60,121,210, 24, 29, 29, +125, 59, 55, 55,119, 54,144,107,210, 32,124, 75,188,246,192,136,123,177, 39,103, 55,108,217,221, 39,180,237,155,181,127, 51, 19, +138,199,116,238,253, 62,231,244,193, 31,217,149,179, 7, 63,208,228, 37,174,125,142,205,106,208,106,181,151,181, 90,237,205,153, + 51,103,190,234,238,238,238, 62,123,246,108,145, 66,161,176, 90,189,122,181, 54, 63, 63, 63, 91,161, 80,196,160,154,254, 52, 79, +139, 51, 22, 63, 66,191, 99,251,126,236,196,246,253,248,186,131,139,119, 55,169,171, 79,160, 60,239, 81, 74,113, 94,230, 73, 0, +167,203, 6,138,172,147,230,205,155, 7,112, 56,156, 65, 0,154, 74, 36,146, 32, 91, 91, 91, 33, 99,172, 33,135,195,185,101,177, + 88,226, 27, 55,110, 28,125,251,246,237, 58, 13, 38,155,118,110,179,206, 55, 36,226,167, 66,181,197, 90,207,181,254, 41,237,220, +102, 29, 0,228,158,250, 76, 13,224,208,237,142,211,250, 29,142, 73, 93,121,171, 72, 58, 41,239,236,215,135,235,186,204,197, 25, +215,131, 94,212,241,175,205,186,157, 1, 96,100,124, 44,150,220,136,139,137,226, 48, 88,153, 97,154,175,201, 77,138,125, 17,249, + 86, 86, 86, 90,111,111,239, 74,175, 46, 20, 10,133, 90,157,174,186, 6,148,115, 38,101, 22,214, 3, 29, 54,239,223,189,121,228, +193,195,135,190,142,236,210,215, 89,228,227,131, 87,220, 56,216, 60,189,197,164, 95,226,242,174,244,254,236,252,154,228, 76,109, + 60,234,216, 31, 70,169, 84, 38, 0, 40, 82, 42,149,125, 24, 99, 15, 57, 28,142,111, 81, 81,209, 53,163,209,120,163,206, 5,129, + 5, 67,218,180,105,181,131,195,225,240,153,201,178, 40,198,138,247,147, 54,235, 78, 6,158,115, 90,146,208, 87,236,241,241,236, + 21, 45, 2,131, 26,180, 40,159,235,176, 73, 61, 59,140,155,182,164, 69,189,250,193, 45,254,152,255,176,198,110, 2,204,168, 46, + 26,181,127,195,162,243,113,191,159,249,220,197,179, 94,189,236,140,228, 59, 15,147,174,205, 51,107, 21,251,159,119, 63, 63, 72, +186,181,108,253,183,211,166,100, 61, 74, 89,175,206, 75,188, 9, 0,234,188,196,155,119,100,248, 34, 63, 59, 99, 74, 65,110,242, +183,207,186, 45, 84, 42, 85,230,246,237,219, 29, 34, 34, 34,184,238,238,238,200,203,203,195,153, 51,103, 44, 22,139,229, 81,157, +179, 10, 83,206,168, 10, 57, 78, 91,214,126,183,200, 90, 98,247,166,201,100,242, 98, 12,224,243,249, 89,122,181,226,120, 9, 87, +242, 25,138, 82,181,213,255,207,176,112, 0,112,203,231, 46,180, 88, 44,156, 69, 43, 55,167, 90,137,236, 42, 29, 12,209,168, 45, +177,177, 88, 44,181,158,235, 80,158, 46, 11,124, 81,175,111, 14, 99,115,155,181,108,253,185,209,104,208,150,189, 62,180, 0,180, +140,161,128,203,229,156,227, 89,140, 39, 20,207,241, 97,138,195,129, 61,227,240, 97, 39,230,131, 3, 14,148,197,133,172, 46,125, +178, 42, 45,136,115, 19,110,169,115, 59,248, 31,211,239, 30,241,235,169,163,239,152,205,230, 87,202,218, 12, 30,232, 52,170, 61, +202, 44,199, 45, 64,172, 9,255,126, 71,202,139, 45,206, 75,254, 67,181, 58,141,242,119,202, 12,169, 47,238,227,227,237, 62,226, + 65,106,238,149,228,135,234, 45,248,243,180, 58,207,179,156, 60,119,119,247, 47, 56, 28,206, 48,129, 64, 96,171,215,235, 85,140, +177,173, 57, 57, 57,243,240,212,228,191,225, 86, 98, 55,205, 8,129,200,102,150, 65,171,250, 77,157,155, 48,164,166,117,183,113, +109,208, 77, 36,145, 76,211,106, 84, 91,213, 57, 9,155, 95,240,246,148, 10,133,194,112, 91, 91, 91,171,252,252,252,203, 0,138, +255, 78,251,189, 89,179,102,126, 92, 46,247, 21,139,197,226, 14, 64,138,210,171, 66,242,249,124,254,163,178, 22, 45, 86,215,204, +118,239,237,113,233,242,122,147,143, 79,158,191,183,188,236,180, 98, 5,239, 1, 75, 69,195,222,236,244,233,150,253,135, 42,187, +234,240, 31,119,204,255,239, 50, 59,240,109, 61,243, 71,114, 5,210,249, 93, 66,180,234,252,204, 71, 19, 46,220,200,187, 12,160, +228,121,150,211,218,218,122,168,193, 96, 16, 91, 91, 91,107, 12, 6,195,246,191,203,186,139,221, 66,222,231,130,213,122,102, 10, + 11, 56,177, 79, 92,180,242,111, 57,150,120,161,161,161,237,173,173,173,253,204,102,179,141, 94,175, 87,107, 52,154, 7,169,169, +169,191,161,234,137,207, 95,234,114, 74,220,130,151, 89, 91, 11, 39, 3,128,193,160, 91,161,202, 77,252,184,186, 39, 86,243,248, +127,244, 62,114,121,165,101, 34,159,103,229,138,178,129,185, 45, 38, 83, 94, 78,202,213,224,191,112, 57,201, 51,238, 92,202,164, + 76,202,164,204, 39,113,105,123, 82,230, 95,153, 41,242,108,228, 43,242,108, 84,235, 65,151,171,120, 60,109, 79, 82,110,108, 37, + 55, 0,181, 24,176,148, 16, 66, 94, 2, 11,109, 2,242, 87,210,102,221,121,248, 50, 31, 79,254,115,170,236, 19,205,169,166, 42, +173, 75,147,224,179, 84,182,167, 41,147, 50, 41,147, 50, 41,147, 50, 41,243, 63,151, 89, 83,246, 63,241,148,228,216, 39,238, 31, + 1,240, 63,233,240, 79,205,170,148, 73,153,148, 73,153,148, 73,153,148,249, 95, 83, 81,120,113,105, 91, 16, 66, 8, 33,132,188, + 28,212, 71,139, 16, 66, 8, 33,228,249, 84,118,234,144, 10, 45, 66, 8, 33,132,144, 23,160,202,206,240,116,234,144, 16, 66, 8, + 33,228,249,148,183,104,121,226,137,225, 29,168,208, 34,132, 16, 66, 8,121, 49,178, 80, 89,235, 86,116,116, 52,171,236,123, 66, + 8, 33,132,144,255,133,127,120, 45,242,120, 75,214,216,178,251, 0, 30,107,209,162, 2,139, 16, 66, 8, 33,127,151, 98,235, 31, +166,188, 37,171,252,150,245, 84,161,213,171, 87, 47, 14, 21, 91,132, 16, 66, 8,249,171,252, 27,107, 17,238,147, 43, 72,187,153, + 16, 66, 8, 33,127,101,177,245,111, 90, 31, 26,222,129, 16, 66, 8, 33,228,249,120, 2,232,249,216,253,255,217, 20, 60,132, 16, + 66, 8, 33,255,118, 99,171,186, 79, 45, 90,132, 16, 66, 8, 33, 47,190,216, 34,132, 16, 66, 8, 33,255,100, 52,179, 57,101, 82, + 38,101, 82, 38,101, 82, 38,101,254,219,149,143,163, 5, 84, 53,142, 22, 33,132, 16, 66, 8,121, 38, 61, 81, 58,126,214,216,178, +175, 61,169,208, 34,132, 16, 66, 8,121,177,158,154,126,135, 10, 45, 66, 8, 33,132,144, 23, 91, 96,173,163, 66,139, 16, 66, 8, + 33,228, 37,163, 66,139, 16, 66, 8, 33,228, 37,225,160,234, 43, 7, 78,215, 33,231, 89,174, 62, 56, 77,153,148, 73,153,148, 73, +153,148, 73,153,255,185,204,154,178, 79,227,159,167,124,100,248, 35,248,163, 35,252,186,255,197, 31,166, 75, 95, 41,147, 50, 41, +147, 50, 41,147, 50, 41,243,223,110,236, 19, 95, 43,208,169, 67, 66, 8, 33,132,144, 23, 91,108,209, 20, 60,132, 16, 66, 8, 33, + 47, 72,149,167, 9,169, 69,139, 16, 66, 8, 33,228,249, 84, 57,169, 52, 21, 90,132, 16, 66, 8, 33, 47,167,224,162, 66,139, 16, + 66, 8, 33,228, 5, 22, 89, 99, 43,253,109,116,116, 52,163,109, 68, 8, 33,132,144,191,202,191,182, 22, 41, 95, 49, 42,182, 8, + 33,132, 16, 66,181, 72,157,121,226,143,171, 13,199,150,221, 7, 64, 87, 29, 18, 66, 8, 33,132, 60,175,158,248,243,149,135, 99, +203,239, 83,161, 69, 8, 33,132, 16,242,252,198, 86,251, 91, 58,109, 72, 8, 33,132,144,191,210,191,177, 22,225,208,110, 37,132, + 16, 66, 8,121, 46,149,181,102,173,163,205, 66, 8, 33,132, 16,242,114, 11, 46, 66, 8, 33,132, 16,242, 50,138,172,151, 61, 96, + 41,205,108, 78,153,148, 73,153,148, 73,153,148, 73,153,255,149, 34,235,241, 33, 30, 0,208, 85,135,132, 16, 66, 8, 33,207,139, + 38,149, 38,132, 16, 66, 8,121, 73,104, 82,105, 66, 8, 33,132,144,255,113,193, 69,133, 22, 33,132, 16, 66,200, 11, 44,178,254, + 84,108, 81, 31, 45, 66, 8, 33,132,144,231, 83,101, 31, 45, 14,170,190,114,224,116, 29,254,192,179, 92,125,112,154, 50, 41,147, + 50, 41,147, 50, 41,147, 50,255,115,153, 53,101,159,198, 63,223, 88,252,143, 6, 44,165, 75, 95, 41,147, 50, 41,147, 50, 41,147, + 50, 41,243,191,134,134,119, 32,132, 16, 66, 8,121,209,133,213,147,168,208, 34,132, 16, 66, 8,121, 62, 52,142, 22, 33,132, 16, + 66,200, 75,226,137,210, 86,173,242,175,225, 84,104, 17, 66, 8, 33,132,188, 24, 61, 81,218,170, 85,254,149, 10, 45, 66, 8, 33, +132,144, 23,168,210,113,180, 56, 0, 16, 29, 29,205,202,238,119,236,213,171,215, 57,218, 86,132, 16, 66, 8,249, 95,250,183,214, + 34, 21, 45, 90,189,122,245,226, 0, 56, 75,187,154, 16, 66, 8, 33,127,133,127, 99, 45,194,125,162,146,236, 72,187,153, 16, 66, + 8, 33,127,133,127, 99, 45,194,127,162,138, 36,132, 16, 66, 8,249, 75,252,131,107, 17, 79,148,118,132, 63, 82,246, 21, 40, 27, +242,129,198,209, 34,132, 16, 66, 8,121, 62,229, 87, 27, 62, 53,245, 14,181, 98, 17, 66, 8, 33,132, 60,159,202, 70,134, 95, 71, +155,133, 16, 66, 8, 33,228, 37,162, 22, 45, 66, 8, 33,132,144,231,247,120,171,214,255,172, 53,139,102, 54,167, 76,202,164, 76, +202,164, 76,202,164,204,255, 82,145,245,167,251, 52, 50, 60, 33,132, 16, 66,200, 75, 66, 87, 29, 18, 66, 8, 33,132, 60,159,242, + 43, 14, 31,191, 79,133, 22, 33,132, 16, 66,200, 11, 44,182,158, 66,167, 14, 9, 33,132, 16, 66,158,207,216,170,126, 65,133, 22, + 33,132, 16, 66,200, 75, 42,184, 56,168,250,202,129,211,117, 8,126,150,171, 15, 78, 83, 38,101, 82, 38,101, 82, 38,101, 82,230, +127, 46,179,166,236,211,248,231,249,203, 6, 44,165, 75, 95, 41,147, 50, 41,147, 50, 41,147, 50, 41,243, 63,139, 78, 29, 18, 66, + 8, 33,132,252, 13, 10, 45, 87, 62,159,255,185, 88, 44, 94, 35, 22,139,215,242,249,252,111, 1, 56,214,245, 15, 74, 36,146, 73, + 30, 30, 30,119, 61, 60, 60, 50,252,252,252,142,218,217,217,124, 20, 32, 68, 36, 0,171, 23,180, 62, 33, 0, 62, 18,139,197,119, + 68, 34, 81, 42,128,109, 0, 62, 2,224,242, 60,193,243,188,208,255,230,228, 62, 7,231,121,161,255, 19,191,234,233,238,238,126, + 1, 64,183, 23,181, 83, 6,219,160,235, 0, 9,210, 7, 72,144, 62,216,230,217, 63, 53,216,217,217, 13,243,244,244,140,113,118, +118,126,228,233,233,121, 73, 36, 18, 13,168, 99,132,155,187,187,251, 98, 95, 95,223, 4, 47, 47,175,229, 40,157,157,252,111,171, +189, 16,237, 91, 11,145,215, 70,128,146, 8, 1,214,180, 17,224,245,215, 1,155,103,140,107, 7, 96,175,189,189,253, 53, 62,159, + 31, 13,160, 95,217,241,213,143,207,231, 71,219,219,219, 95, 3,176,183,236,113,207,114,156, 46, 6,240, 8,192, 87,101,247,255, +207,215,215,183, 36, 44, 44, 44, 53, 44, 44,108, 83, 80, 80,208,240,218,134,217,216,216,188,238,235,235,187,207,207,207, 47,181, + 77,155, 54,133,222,222,222,247,124,124,124, 54, 11,133,194,142,244, 22, 71, 8, 33,127,127,111, 1,248, 26,192,170,248,248,120, + 25, 99, 76,198, 24,147,197,199,199,203, 0,172, 1,240, 13,170,110, 66,252,211,207,157,157,157,231,206,159, 63, 95,155,149,149, +197,242,242,242, 88, 66, 66, 2, 91, 54,107,154,165,187, 19,159, 5,184, 58,170, 61, 61, 61,239,251,251,248,236,108, 98,203,157, + 6, 32,176, 54,153,143,113, 20,139,197,151,103,205,154,165,188,112,225,130, 82,175,215, 43, 45, 22,139, 50, 51, 51, 83,121,250, +244,105,101, 68, 68,132, 18,192,199, 0,120,117,200,172,240,165, 23,206,177, 13, 95,176, 47,189,112,238,241,159, 55,108,216,240, +182,197, 98, 97,253,251,247,215, 1,240,174, 75,230,147,188, 1, 81, 19,123, 56, 12,176, 69,142,105,243, 60,198, 86, 79, 97, 3, + 36, 72,127,150, 76, 55, 55,183, 67,147, 38, 77, 82, 60,122,244,136,233,116, 58,150,158,158,206,198,141, 27, 87,236,230,230,182, +189,150,235,238, 28, 26, 26,154, 19, 19, 19, 99,145,203,229,236,236,217,179,150,166, 77,155,230,212,178,216,234,250,196,178,172, +243,242,242, 58, 90,151,155,155,155,219,250,186,238,163,215,132, 72, 55,200,206, 48,118,245, 36, 59,220,191, 13, 91,214,210,135, +245,115, 18,200,219, 9,240,127, 29, 42, 31,202,164,170,204,119, 58,116,232,160,186,113,227,134,185,160,160,128,221,190,125,219, + 50,102,204, 24, 45,128, 91, 99,198,140,209,222,190,125,219, 82, 80, 80,192,110,220,184, 97,238,208,161,131, 10,192,232, 58, 44, + 39, 23,192,198, 57,115,230, 48,198, 24,155, 63,127, 62, 11, 11, 11, 99,157, 59,119,102, 74,165,146, 49,198, 82, 25, 99,155, 76, + 38,211,200,218,100, 74,165,210, 97,147, 38, 77, 82,170,213,106, 86,206, 98,177, 48,185, 92,206, 86,173, 90,165,242,240,240, 56, + 90,197,135, 12, 58,229, 65,153,148, 73,153,127,183,204,127, 50, 79,148,246,211, 42,191,213,186, 97,226,221,105,211,166,149, 23, + 85,199,218,181,107,119,101,228,200,145,178,145, 35, 71,202,218,181,107,119, 22,192,137,216,216, 88,217,212,169, 83,101, 0,222, +173, 97, 71, 56,182,109,219, 86,158,157,157,205,130,131,131, 89,189,122,245, 88,118,118, 54, 99,140,177,171,239,180, 96,191, 52, + 2,123,120,254, 24, 59,121, 96, 47, 27,227,201,103,237, 61,165, 70, 79, 15,143, 2, 23, 23,151, 5,248,243,156,140,149,237,220, +183, 27, 53,106, 84,114,235,214, 45,101, 98, 98,162,114,238,220,185,202,206,157, 59, 43, 67, 67, 67,149,253,250,245, 83,174, 92, +185, 82,105, 48, 24,148,235,215,175, 87,218,219,219,223,170,164,216,122,230, 66,139,207,231,175,136,143,143,103,247,239,223,103, +101,173, 20, 85,101, 74, 29, 28, 28,122, 56, 58, 58,126,236,224,224,208, 3,128, 20, 0,130, 1,219,102, 82,248,253, 95,179,128, +134,209,239,118, 13, 92,213,245,213, 22, 3,236,184,114,227,119, 83, 24,235,239,247, 76,133,150, 84, 42, 29,246,209, 71, 31,149, +232,116, 58,166, 86,171,153, 82,169,100,106,181,154,149,148,148,176,119,223,125, 87, 33, 18,137,222,174, 41,211,197,197,101,222, +249,243,231, 77,217,217,217,236,252,249,243,236,232,209,163,108,245,234,213, 22, 55, 55,183,165,117,125, 1,122,120,120,156, 58, +121,242,164, 44, 46, 46, 78,118,249,242,101,153,209,104,148, 25, 12, 6,153,193, 96,144, 69, 71, 71,203,246,239,223, 47,219,181, +107,151, 76,175,215,203,244,122,189, 76,167,211,201,234,215,175,127,188,174,251,168,149, 16, 15,245, 23, 14, 51,182,244, 67, 86, +188,112, 2,147,127,242, 38,203, 29, 23,201,214,188,234,195, 34,197,248, 25, 79,207,237, 89,105,166,149,149,213,185,212,212, 84, +203,140, 25, 51,244,141, 27, 55, 46, 30, 53,106,148, 86,167,211, 49,198, 24,211,233,116,108,212,168, 81,218,198,141, 27, 23,207, +152, 49, 67,255,224,193, 3, 11,159,207, 63, 93,135,229,252,166,188,200, 58,119,238, 28,123,156, 82,169,100,157, 59,119, 78, 13, + 11, 11,219,244,202, 43,175, 12,169, 41,211,214,214,182,207,244,233,211,149,172, 18, 70,163,145,149,148,148,176, 7, 15, 30, 88, +234,213,171,151, 9,192,153,222,204, 41,147, 50, 41,147, 10,173,151,102,108, 13,247, 43,223,136, 83,167, 78,149, 49,198,100, 51, +103,206,148,149,181,108, 89, 3,176, 45,187,241, 1, 12,158, 62,125,186,140, 49, 38,155, 54,109, 90,249, 99,170,218, 17,111,237, +217,179,199,176,124,249,114,230,238,238,206, 60, 60, 60,216,138, 21, 43,152,197, 98, 97,217,209,219,217, 47,141,192,238,124, 62, +130, 49,198, 88,194,130,137,236,151, 70, 96,201,223,127,201,134, 14, 29,170,182,177,177,121,183,154,157,235,212,162, 69,139, 18, +141, 70,163,220,188,121,179,210,198,198,230, 42,128,198, 40, 61, 21,201, 41, 91,214,225,141, 27, 55, 86,220,188,121, 83,249,211, + 79, 63, 41, 1,204,173,229, 1, 19, 8,160,147, 68, 34,233, 55,221,219, 42,145,109,248,130, 77,119,199, 13, 0, 77, 1,184,150, + 61,198,107,218,180,105,140, 49,198,124,125,125,207, 87,145, 41, 13, 13, 13,157,150,152,152, 24,101, 52, 26,163,226,226,226,162, + 26, 52,104, 48,163,119,125,207, 54, 7,223,125, 61,188,248,203, 9,225,108,201, 39,161,223,190,209,170,235,206, 65, 29,223,125, +239, 21,151, 11,163,220, 68,234,129, 82, 94,201, 19,167, 14,107,117, 96,123,123,123, 95, 78, 79, 79,175, 40,174, 74, 74, 74,216, +163, 71,143, 88, 74, 74, 10,187,112,225, 2,243,244,244,252,165,166, 76, 15, 15,143,219,233,233,233,236,251,101,203, 88,255,166, + 13, 89,164,131, 29,235,224,104,199, 90,218,138, 84,141,128,150,117, 45,180,174, 93,187, 38, 3, 32, 3, 32, 43, 40, 40,144, 21, + 20, 20,200,138,138,138, 42,126, 6, 64, 86, 92, 92, 44, 43, 46, 46,150,233,245,122, 89, 64, 64, 64,157, 11,173, 8, 17, 34, 94, + 19,161,176,141, 16,154,183,188, 93, 50, 39,212,119, 49,255,254,110, 27, 86,244, 97,103,182, 60,220,155,181, 19,224,255,106,153, +249,150, 64, 32, 56, 11, 96, 74, 89, 81, 62,162, 71,143, 30,106,198, 24,235,209,163,135, 26,192,136,178,159,127, 84, 86,100,245, +168,229,114,114,131,130,130, 84,229, 45, 89, 0,126, 11, 10, 10, 82,133,133,133,177,176,176, 48,230,235,235, 91, 82,150, 93,171, + 55,180,192,192,192, 4,141, 70, 83, 81, 0,202,229,114,150,153,153,201,146,147,147,217,173, 91,183,216,213,171, 87, 89,106,106, + 42,219,189,123,183,217,193,193,225, 8,189,153, 83, 38,101, 82, 38, 21, 90, 47,181,208,122,242,246,103,209,209,209,236,137, 31, + 45,140,141,141,149, 77,159, 62, 93, 86, 67,101, 54,118,230,204,153,229,173, 94, 95, 87,243,207,127,125, 66, 66, 2, 27, 49, 98, + 4, 11, 9, 9, 97, 33, 33, 33,108,228,200,145,172,184,184,152, 41,147,110,178, 95, 26,129, 93, 29,216,146, 49,198, 88,201,157, + 56,246, 75, 35, 48,217,208,182,236,250,245,235,204,199,199,231,100, 53,127,255,231, 75,151, 46,229,109,223,190, 61, 27,165,253, +177,172, 0,180, 6,176, 66, 44, 22,111, 68,233,233,194,122, 0, 28,131,131,131, 11,213,106,181,178,127,255,254, 74, 0,126,213, +100,118, 8, 9, 9,185,191,126,253,122,150,155,155,203, 10, 11, 11,217,162,136, 6,140,109,248,130,205,111, 89,207,242,253,247, +223,235,166, 76,153,162,114,114,114,138, 6,224,213,191,127,127, 19, 99,140, 69, 70, 70,230, 84, 22,230,224,224,208, 35, 49, 49, + 49, 74,171,213, 70,201,229,242,168,194,194,194,168,195, 7, 15, 70,117,111,218, 96, 68,241,151, 19,194, 15,190,251,122,248, 27, +222,142,253,150,118,123,117,252,163, 25,163,251,207,108,219,248,142,246,155,201,103,222,169,239,190,248, 89,246,182,171,171,107, +150, 78,167, 99, 0,158,186,221,191,127,159, 57, 59, 59,167,215,148,225,228,228, 52,243,163,193,131,204,111,215,243,102,247,151, +207, 98,198, 83, 63, 49,227,209,205, 44,105,225, 39,172,183,135,139,162,181, 53,119,122,109,151,199,195,195,227,212,229,203,151, +255, 84,104, 21, 21, 21, 85, 90,104, 41, 20, 10,153, 94,175,151, 5, 5, 5, 29,127,222,163,190,181, 0, 1, 29,196,188,171,113, + 35,218,179,188, 9,157, 89, 15,169, 85,234,115,196, 13, 6,112, 22,192,208, 58, 62,143, 11,224,155,242,130,106,225,194,133,140, + 49,198,130,130,130, 84,120,190,139, 81,164, 13, 27, 54, 76, 25, 61,122,180,169, 81,163, 70,185, 17, 17, 17,242, 43, 87,174,176, +115,231,206,177,163, 71,143,178,189,123,247,178,155, 55,111,178, 71,143, 30,177,132,132, 4,214,179,103, 79, 57,128, 14,244, 94, + 72, 8,249, 59,171,164, 22,249,199,227,150,175, 88,175, 94,189, 56,143,173,160, 20,128,168,101,203,150,121,223,124,243,205, 18, +148,142, 5,193, 9,229,225,157,206, 98,254,245,206, 98,254,245, 80, 30,222, 41,107, 49, 90,183, 96,193,130,121, 97, 97, 97, 89, + 0,196, 0, 60, 42,251, 67,140,177,246,206,206,206, 72, 79, 79,135, 84, 42,133, 84, 42, 69,122,122, 58, 24, 99, 48, 49,192,200, + 0,157,193, 0,141, 70, 3,173,133, 65, 99, 1, 20, 74, 37, 60, 60, 60, 96, 48, 24, 2,170, 88,254,102, 3, 7, 14, 12, 8, 13, + 13,205,155, 58,117,106, 38, 74,251,202,108,124,255,253,247, 79,253,246,219,111,161, 74,165,178,240,214,173, 91,218,166, 77,155, +246, 0,224,145,152,152, 56,108,213,170, 85, 24, 49, 98, 4,170,249,167,211,180,103,207,158, 71,111,222,188, 25, 48,116,232, 80, +156, 61,123, 22,139, 22, 45, 66,126,126, 62, 3, 0,157, 78,199,204,102,179,161,109,219,182,134,229,203,151,183,138,140,140,188, + 92,191,126,125, 30, 0,164,164,164, 36, 85, 22,200,225,112, 26,248,251,251, 67,167,211, 33, 47, 47, 15, 55,111,222,132,157, 84, +138,248,204,124,247,142, 75,191, 47,248,252,224, 41,171,193,173, 66,157, 62,126, 61, 66,247,213,201,179,193,141,189,220,221,245, + 6,163, 71, 66, 86, 78,230,179,236, 84,107,107,235,244,252,252,124,232,245,122,104, 52, 26, 40, 20, 10, 20, 20, 20, 32, 63, 63, + 31,153,153,153,176,182,182,190, 95, 83,134,125, 97,225,249,148, 75,231, 56,187,127, 88,136, 0, 83, 33,248,251, 86,128,127,104, + 13, 2,245,121, 88, 59,107,156,157,222,217,117,142,189,157, 93,145,131,131,195, 58, 0, 65, 53,229,133,135,135,163,160,160, 0, + 5, 5, 5,112,118,118,134,163,163, 35, 28, 29, 29, 33,151,203, 81, 92, 92, 12,133, 66,129,224,224, 96, 52,107,214, 12, 91,183, +110,125, 33, 7,247,239,122, 36,155, 96,158,112,234, 94, 38,172, 37, 18,212,119,180,245,127,213, 22, 78,213, 60,165,179,149,149, +213, 30, 39, 39,167,147, 0, 62, 4, 32, 1,240,161,147,147,211, 73, 43, 43,171,190, 0,230, 3,216, 94,199,197,248,106,206,156, + 57,211, 18, 19, 19,109,174, 95,191,142,169, 83,167, 98,238,220,185, 72, 74, 74,250, 14,128,165,236, 49, 31, 56, 59, 59, 71,115, +185,220, 31, 1,188, 9,160,135,167,167,103,151, 26,114,251, 78,153, 50, 69,219,162, 69,139,132, 59,119,238,244,189,116,233, 82, +203, 79, 62,249,164, 56, 45, 45, 13, 9, 9, 9,240,244,244,132,175,175, 47,148, 74, 37,138,138,138,208,183,111, 95,169,189,189, +253,187,244, 54, 78, 8,249, 59, 23, 89, 79,212, 34,255,180, 22,173, 74,239, 87,250,137,218,198,198,102,142, 76, 38,107, 19, 22, + 22,198, 7,176, 27, 0, 66,121, 24,208,183,109,243,141, 7,215, 45, 12,219,191,124, 86, 88,247,176,224,141,161, 60,148, 95,197, + 22,221,178,101, 75, 71,153, 76,214, 86, 40, 20,254, 95, 21, 11,193, 0,192,209,209, 17, 82,169, 20, 14, 14, 14,112,116,116,132, +197, 98,129, 82,173,133,202, 12,148,104,245, 40, 46, 46, 70, 73,217,125,165,206, 0,149, 74, 85,241,220, 74,116, 28, 61,122,116, +222,170, 85,171,114,179,178,178, 22, 2,104, 58, 98,196,136, 62, 43, 87,174,196,175,191,254,170,125, 51, 36,208,121, 65,251,230, +243, 26,103, 37, 69,133, 88, 97, 12,128,243,231,207,159, 71,219,182,109,193,225,112, 6, 85, 22, 40, 22,139,215,236,220,185, 83, +124,235,214, 45, 4, 6, 6,222, 26, 52,104,208, 59, 11, 23, 46, 12,144, 40, 11, 47, 2,128,169, 32,251,214,196,137, 19,191, 88, +176, 96, 65, 94, 94, 94,158, 65,173, 86,187,245,238,221, 27,233,233,233,120,244,232,209,111, 85, 20,153, 9,113,113,113,172,184, +184, 24,201,201,201,136,139,139, 19,127,241,197, 23,173,204, 92,110,159, 12,216,189, 55, 34,162,101,171,161,173,155, 99,123,204, +117,235, 11,247, 82, 28, 90,214,243,118,188,246, 48,235, 21, 35, 7,247,159,101,111,151,148,148,172,152, 55,111,158, 82,169, 84, + 34, 35, 35, 3, 55,110,220,192,157, 59,119,144,154,154,138, 69,139, 22, 41, 11, 11, 11, 87,214,148,225, 37,226,127,186,248,147, +247, 57,252,219,191, 1,215,207, 1,234, 18, 64,163,132,238,174, 12,155,238,102, 99,245,190, 3,130,180,244,116,135, 93,187,118, +141,246,243,243,147, 1, 8,174, 46,143,177,210, 93,200,229,114,159, 44, 66,193,229,114, 75, 0,100, 75, 36,146,135,118,118,118, + 15,185, 92,110, 54, 99, 76,245, 66, 62, 73,152, 96, 0,143, 7, 8,196,224, 90, 85, 59,181,231, 59,131, 6, 13,218,249,240,225, +195,238,201,201,201,109, 86,174, 92, 57, 79, 36, 18,197,175, 92,185,114, 94,114,114,114,155,135, 15, 31,118, 31, 52,104,208, 78, + 0,195,235,242,247,131,130,130, 38, 70, 69, 69, 97,209,162, 69,104,214,172, 25,130,131,131,213,115,230,204, 89, 1, 96, 22,128, +255, 11, 10, 10,186, 56,113,226,196, 81,185,185,185, 30, 25, 25, 25,205,190,251,238,187,113, 43, 86,172,120, 53, 51, 51, 83, 84, + 67,116,187,110,221,186,225,216,177, 99, 0,144, 5, 32,185,160,160,192,148,153,153,137,134, 13, 27,162, 85,171, 86, 80, 42,149, + 80, 42,149,144,203,229,240,247,247,135,197, 98,105, 67,111,229,132, 16,242, 63, 45,184, 42, 47,180, 68, 34,145, 99,120,120, 56, +234,215,175,239,136,178,171,181,156, 5,252, 25, 31,143, 30,108, 99, 43, 59, 14, 78,220, 47, 24,212,190,137,141,179,128, 63,163, +236, 41,124,127,127,127, 97,120,120, 56, 36, 18,137,119, 21,127,252,108,118,118, 54,194,195,195,225,224,224, 0,169, 84,138,240, +240,112, 24, 12, 6, 20,151,148, 64,101, 6,212, 70, 11,138,139,139, 81,152,151, 3,181, 25, 48,217, 57, 35, 53, 53, 21, 60, 30, + 47,165,138, 76,207,192,192,192,188,248,248,248, 60, 0,231, 1,140,159, 59,119, 46,166, 79,159,142,217,179,103,239,180,201,122, +208,109,231,177, 67,206, 59,230,124,224, 26, 44,224, 12, 6, 96,120,248,240, 33, 28, 28, 28, 32,145, 72, 42, 45, 12, 34, 35, 35, + 91, 72, 36, 18,108,222,188,153,101,100,100, 68,160,244, 18,254, 20, 14,167,180,216, 19,115, 81, 12, 96,133, 76, 38,123,237,139, + 47,190,184,215,181,107, 87,171,214,173, 91, 99,254,252,249, 0, 16, 93, 89,166, 92, 46,255,125,248,240,225,250, 51,103,206,224, +238,221,187,146,131, 7, 15, 14,152, 63,127,126,147,180,180, 52,225,207, 71,143,191,177,237,161, 98,192,194,147, 23, 68, 11, 78, +156,253,221,197, 94,210,248, 21, 23, 39,196,165, 61,178, 54,243,112,165,166, 61,250,154, 21,111,116, 71, 17, 63,174,189,144,155, +213, 81,196,151,189,106,197,123,191,164,164,100,215,225,195,135, 79,124,242,201, 39,202,220,220, 92,216,217,217,161,160,160, 0, + 95,125,245,149, 50, 46, 46,110,159, 94,175,255,185,166, 92,179,133,181,240,173,231, 7,220,143,175,248,153,193,194,112, 69,111, +141, 94,227, 39, 35,164, 97, 67,232,245,122, 52,109,218,148, 51,119,238, 92,137, 84, 42,253,172,198,162,135,251,212,225,102,226, +112, 56,217,140,177, 71, 74,165, 50, 67, 44, 22,167, 89, 91, 91,167, 21, 22, 22,102, 48,198,114, 94, 68,157,197,184,248,180,109, +211, 32, 64, 40, 70, 90,129, 50,243,170, 18,133,149, 61,208,206,206,238,253,213,171, 87,139, 54,108,216, 96,156, 56,113,162,110, +220,184,113, 86, 26,141,198,109,220,184,113, 86, 19, 39, 78,212,109,216,176,193,184,122,245,106,145,173,173,109,191,103, 89, 16, +163,209,136,248,248,248,133, 73, 73, 73, 18,148, 14, 55, 50,121,206,156, 57, 35, 18, 19, 19, 69,171, 86,173,194,222,189,123,177, +119,239, 94,244,233,211, 7,147, 38, 77, 66, 84, 84, 84,117,113, 54, 97, 97, 97,225,206,206,206, 56,119,238, 92, 38,128, 52, 0, + 45,108,109,109,237,250,244,233,131,238,221,187, 67,171,213,194, 96, 48, 84, 20, 90, 60, 30, 15, 14, 14, 14,206,244, 30, 72, 8, + 33, 47,189,200,250, 83,177,197, 7,128,242,166,186, 94,189,122,113,170,251,199,104, 46,202,133, 92,165, 70,106,177, 26,233, 69, +150, 63,253,206, 98,177, 84,251,215, 51, 51, 51,127,142,137,137,121, 63, 60, 60,156,159,153, 89,122, 70, 44, 60, 60, 28,106,181, + 26,153,215, 47, 67,101, 1, 36,129,161, 80,169, 84, 40,186,115, 13,182, 97,109,224,220,115, 40,150,174, 90,165, 43, 40, 40,248, +161,178, 76,129, 64, 96,229,227,227,147,151,146,146, 98, 2, 80, 40,149, 74,187,249,249,249,225,236,217,179, 0,176,157, 1,139, + 17,119, 6, 56,183, 31,172,180, 73,197,214,223,223, 31,185,185,185, 80, 42,149,103, 43,203,140,137,137, 73, 52, 26,141, 77,123, +247,238,205,217,178,101,203,110,133, 66, 49, 27,192, 13,157, 5,188,235, 15,115,160, 50, 67, 4,224,117, 71, 71,199,143,162,162, +162,186, 76,156, 56, 17,135, 15, 31,198,201,147, 39, 13, 40,237, 11, 22, 83, 73,108,113,114,114,242,218, 41, 83,166,180,230,114, +185,227, 79,157, 58,101, 10, 14, 14, 86, 24, 12, 6,115,131,144, 16,238,236,185, 95, 90,127, 56,126,172, 67,129, 26,183,187, 55, +240,108,203,225, 0,183, 31,229,166, 37, 41, 81, 80,221, 54,141, 20,240,162,251, 70,132, 69,190, 63,232, 45, 91, 73, 96, 99,168, +110, 94,246, 88,187,231,232, 82,113, 92, 98,175,115,185,185,125, 14, 31, 62, 60,224,236,217,179, 31,234,245,250,250, 66,161,240, +190, 92, 46, 95,174, 84, 42,107, 44,178,120, 60, 94, 79,157,167,143,163,188,176, 16,162,178,150, 40,133,209,130,124,157, 9,119, + 29,130,241,174,143,111,197,105,208,236,236,108,120,120,120,112,204,102,243, 91,213,101,158, 60,121, 18,189,122,245, 42, 47, 60, +193,225,112,192,225,112,242, 67, 66, 66,114,132, 66, 97,129,181,181,181, 98,241,226,197, 90,173, 86, 11, 62,159, 47, 50,155,205, +188,231, 57,218, 91,217,192, 77,200, 56,107,198,245,238,212,181, 89,227,134,236,252,213,235,156, 34,181,118, 83, 53,173,128,223, + 5, 5, 5,241, 11, 11, 11,127, 6,112,215,104, 52,238,216,189,123,183,104,216,176, 97,218, 61,123,246, 12, 1, 16,176,100,201, +146, 1, 74,165,178, 78, 83, 42, 36, 37, 37,125,183, 96,193,130,105, 51,103,206,196,214,173, 91, 39, 38, 37, 37, 77, 47,107,233, +234, 19, 21, 21,133,197,139, 23, 99,235,214,173,150,187,119,239, 30,181, 88, 44, 73,159,124,242, 73,152,187,187,123,126, 86, 86, + 86, 82, 53,177, 45,123,244,232,161,187,120,241,162,160,164,164,228, 2,128,143, 38, 76,152, 48,250,181,215, 94, 83, 12, 26, 52, +200,182,176,176, 80,110, 99, 99, 35, 88,191,126,189, 35,159,207,135, 74,165, 2,135,195, 65, 73, 73,137,158,222, 7, 9, 33,127, + 87, 85,213, 34,255, 16, 85,254,111,224, 87,182,130,106,181, 58, 39, 61, 61,189,225,163, 71,143, 76, 0, 76, 0, 80,160, 55,125, +189, 96,253,254, 13,253, 90, 7, 73,178,140, 70, 28,188,122, 75, 93,160, 55,149,119,126, 55, 61,122,244,168, 36, 45, 45,205, 78, +163,209, 40,171,248, 91,191,173, 89,179, 70,115,230,204, 25,187,228,228,100,152,205,102,180,104,209, 2, 9, 9, 9, 40,186, 27, + 15, 73,195, 22,144,116,232,133, 91,178,171,136, 59,121, 26, 15,148,122,211,189, 89, 11,138,149, 42, 85,148,193, 96, 56, 88, 89, +160,149,149, 85, 33, 0,198, 24, 51, 3,128, 66,161,184,161, 84, 42,219,187,187,187,227,246,237,219, 18,149, 25,147, 6,204, 88, +186,146, 49,102,182, 46,189,154,235,227, 65,131, 6, 33, 54, 54, 22, 0, 98, 43,203, 84, 40, 20, 19,199,140, 25,115,102,243,230, +205,252,228,228,228,238, 27, 54,108,232,126,239,222, 61,198, 41, 76, 55, 95, 84, 91, 33, 96,196,164, 87,191,247, 15, 57,217,171, + 87, 47,120,122,122, 98,253,250,245, 88,190,124,185,241,131, 15, 62, 72, 92,190,124,249,171,185,185,185, 59,170, 88,255, 98,185, + 92,126,220,217,217,249,195, 38, 77,154,148,168, 84, 42, 20, 20, 20, 32, 51, 51, 19, 78,206,206, 92, 19,184,109, 93, 29, 28,118, +252,156, 93, 34,225, 31,255, 29,151, 51,178,170,109,205,106,109,197, 27,222, 47,178,121,228,255,205,156, 97,139,139, 7,193, 25, + 19, 5,182, 97, 30, 38,143, 28, 96,167,213,237,232,160,186,158, 58, 76,166, 80,108, 83, 40, 20,123,235,120,176,244,104,219,182, +237,206, 5, 11, 22,136, 63, 95,180, 0, 75, 26,122,195, 84, 80,128, 60,157, 25,249, 58, 19, 20, 69,119,113,251,246, 45, 56, 59, +187,224,193,131, 7,208,106,181,184,115,231, 14,227,241,120, 63,215,212,162, 83,238,177,211,133,114,161, 80, 88, 96,101,101,149, +195,231,243, 11,147,147,147, 85, 90,173, 22, 92, 46, 87, 98, 54,155,197,181, 88, 86, 31, 23, 23,151, 79, 80, 58,152,232,225,146, +252,252, 21,225, 86,112, 0, 31, 29,253, 93,156,223,152, 53,110,152,139,159,151,155, 60, 57,241,190,241,135, 19,151,242,181,186, +170, 47,214, 0, 16, 93, 88, 88, 88,209, 34,185,103,207,158,201,123,246,236, 25, 13, 96, 35, 74,231,221, 58, 45,151,203,191,127, +134, 23,223,172,125,251,246, 77,155, 57,115, 38,196, 98,113,197,224,169, 98,177, 88, 4, 0, 63,253,244, 19,110,223,190,253, 26, +202,250,107, 89, 44,150,157, 89, 89, 89, 53,101, 6,132,134,134, 38,239,223,191, 95, 0,192,107,194,132, 9,109, 86,174, 92,137, +145, 35, 71,230,221,186,117,171, 53,128, 20, 0, 1,227,199,143,191,178,117,235, 86, 71,139,197,130,162,162, 34,232,245,250, 20, +122, 43, 39,132, 80,177,245, 82,132, 3,136, 67,233,248, 89, 61, 1, 28, 65,105,183,142, 42,249,150, 85,103, 39, 0,244, 46,255, +255, 88, 69,103,120,160,244,138,172,227, 0,126, 4,224, 94, 85,168,179,179,243,103, 35, 70,140, 48,102,100,100,176,236,236,108, +182,119,239, 94,246,241,251, 35,204,175, 7,122, 89, 2,189,220, 85,174,174,174, 9,158, 46, 78,155,154,219,224, 99, 0, 62,181, + 88,177, 17,247,238,221, 27, 59, 98,196,136,247,203,254,238,251, 59,119,238, 84,158, 58,117, 74,201,227,241,162, 81, 58,180, 67, +121, 65, 57,252,173,183,222, 82,234,116, 58,101, 72, 72, 72, 33, 74, 59,238, 87,101, 64,199,142, 29,139,142, 29, 59,198,204,102, +243, 83, 99, 20,229,229,229,177,147, 39, 79,178,136,136, 8, 57,128, 97, 93,186,116, 57,123,233,210,165,179,237,218,181,219, 87, +211, 2,187,184,184,204,184,126,253,122,108,106,106,170,236,200,145, 35,178, 29, 59,118,200,198,143, 31,127, 35, 44, 44, 76,147, +152,152,104, 49,153, 76,236,250,181,107, 44,164, 65, 3, 21, 0,255,170,114, 58,139,249, 87, 20,235,231, 49,237,252,145, 76,219, +215,151, 1, 96, 37, 75, 63, 99, 57, 19,187,178,132, 15,223, 96,157, 68,188,152,103, 57, 82,125,108,111,173, 0, 0, 32, 0, 73, + 68, 65, 84,156,156,156, 78,196,198,198,178,146,146, 18,118,243,230, 77, 54,188, 87,119, 22, 51,186, 43, 59,222, 61,136,109,237, +240, 10, 91,218, 45,140,117,239,208,158,173, 89,179,134,237,223,191,159,205,152, 49,195,226,226,226, 82,130,106,250,104,121,120, +120,156,218,189,123,183, 12,128,140,199,227,201, 20, 10,133,172,164,164,228,231,135, 15, 31,174, 14, 9, 9,153,214,164, 73,147, + 33, 13, 27, 54,236,220,233, 21,255,105, 93,236,132, 9, 93,237, 69,247, 27,216,218, 44,197,211,227, 94, 85,144, 2,254,129, 1, + 1, 37,231,206,157,179,232,116, 58,118,225,194, 5, 75,163, 6,193,218, 37, 3,123,236,123,176,254,155,125,218, 99, 91, 78,168, + 15,173,187,180,231,189, 94,241, 29,109,184, 91,218, 72, 42,134,227,120, 86,131, 1, 28,196, 31, 87, 29,142, 0,112, 8,213, 95, +133,200, 5,176,113,254,252,249,143, 95,105, 8, 0,220,176,176, 48, 25, 99, 76, 22, 22, 22, 38,171,235,130,216,216,216,124,114, +248,240,225, 57,126,126,126,139, 6, 13, 26,180, 94, 46,151, 31, 25, 50,100, 72, 60, 74, 47, 6,225,160,116,118,132,183,124,124, +124,242,226,226,226,216,217,179,103, 89,255,254,253, 75,172,173,173,135,210,219, 56, 33,132,188, 20, 99,171,248, 90,173, 5,241, +241,241,229, 99,104, 77,168, 46,124,250,244,233,178,216,216, 88, 25, 74, 71,137,175, 22,159,207, 63,240,193, 7, 31, 48,119,119, +119,165,155,155,219, 1, 43, 30,111,180,175, 24,225,120,182, 75,221,219,111,219,182,173,207,119,223,125,215, 19,192,107, 0,172, +188,189,189, 51,179,179,179,149,151, 46, 93, 82, 70, 68, 68, 40, 93, 92, 92,114, 67, 67, 67,149, 75,150, 44, 81, 26,141, 70,229, + 39,159,124,162,196,211,227,125, 85, 70, 4,224, 67,129, 64,112,160, 81,163, 70,241,179,122,119, 54, 46,154, 52,154,141, 8,114, + 85, 2,248, 14,192, 7, 0, 28, 0, 88, 13, 24, 48,224,151, 59,119,238,156, 8, 13, 13, 93, 91,139, 92,175, 38, 77,154,252,186, +115,231,206,216,253,251,247,203, 62,251,236,179, 88,103,103,231,140,196,196, 68,139, 86,171,101, 69, 69, 69, 76, 46,151,179, 35, + 71,142,152,157,156,156, 86, 85,185,226, 66, 94, 22, 59,185,189,210, 33, 28, 30,206, 28,202, 34, 4,220, 71,207,114,164, 72, 36, +146,194,130,130, 2,150,157,157,205,146,147,147,217,190,125,251, 88,143,182,173,216,174,241,253,216,246,247,251,176,197, 61, 90, +177,215,236, 68, 42, 15, 59,219, 88, 59, 59,187,220,218, 92,117,232,225,225,113, 74,167,211, 85, 12,223,224,227,227, 35, 11, 9, + 9,217, 31, 26, 26,186,244,240,225,195,147,151, 45, 91,214,167,211, 43,254,211,190,234,222, 86,163, 62,189,135,149,236,254,142, + 77,111, 17,172, 45, 43,230, 43,229,237,236,180,237,220,217,179,150,242,226,215,100, 50,177,131, 7, 14,176,129,111,188, 30, 95, +124,252,167, 31, 47, 68, 77,220,249, 73,139,224,131, 17, 34, 12,174,174, 96,171,248, 40, 98, 11,231, 72,123,238,234, 55,253,156, +178,218, 75,185,223,181,182,251,211,244, 82, 3,131,131,131,147, 25, 99, 89, 13, 27, 54, 76, 6,176,189, 97,195,134,143,223,127, +175,138,216,138,193, 73,231,204,153,195,202, 94, 31, 92, 0,179, 23, 44, 88, 32, 99,140,201,130,130,130, 46, 2, 64, 51, 9, 92, + 58, 72,185, 63,246, 14,112, 47,232, 32,229,254,216, 76, 82,249,148, 81,254,214,104,208,222,213,230, 66,159, 32,207,146,142,222, +210,243,219, 55,109, 88,244,230,155,111,174, 7,176, 10,192, 60,103,103,231, 11,131, 7, 15,190,189,117,235,214,219, 75,150, 44, + 49, 36, 38, 38,178, 81,163, 70,169,132, 66,225, 60,122, 31, 36,132,144,151,166,124,100,120,207,186, 20, 90,111, 77,155, 54, 77, +198, 24, 43, 31, 75,107, 88, 37,143,233, 61,115,230, 76, 25, 99,172,124,116,248, 39, 7, 48,171,108, 64,179, 57,171, 87,175,102, + 66,161,240,199,103, 92,153,199, 51, 61,250,246,237,219, 90,161, 80,188,234,238,238,254,106, 89,203,149,175,139,139, 75,242,142, + 29, 59,148, 26,141, 70,201, 24, 83,154, 76, 38,101,108,108,172,178, 99,199,142,202,199, 62,245,215,180,156,127,242,185, 7, 46, + 94,157,245, 62,251,220, 3, 23,159,248,213,208,141, 27, 55, 30, 75, 73, 73,249,217,222,222,126,106, 45, 51,125, 93, 93, 93,103, + 59, 57, 57,157,112,113,113,249,220,201,201, 41,203, 96, 48,176,162,162, 34,150,144,144,192,206,158, 61,203, 98, 98, 98,152,147, +147, 83, 70, 85,203,217, 69,204,255,189,104,209,135,204,178,113, 1,211,175,156,193, 0, 48,249,178,233, 44,127,205, 92,118,117, + 76,119,214, 81,196,251,237, 25,182, 39, 28, 28, 28,214, 29, 56,112,192,146,148,148,196,162,163,163,217,145, 35, 71,216,164, 73, +147, 88, 3, 47, 79, 93,107, 1, 55,167,189,144,127,226, 89, 6, 44,213,233,116, 50,133, 66, 33, 83, 42,149,178, 70,141, 26,201, + 90,181,106,181,191,117,235,214, 75,247,236,217, 51,249,171,175,190,234,211,197, 78,152,160, 62,189,135,177,207,222, 96,236,195, +118,236,254,232,142,172,179,152,127,189,202, 76,119,247,140,242,209,218, 85, 42, 21, 59,127,254, 60,251,245,215, 95,153,135,139, +139, 34, 82,204, 27, 27, 33, 68,135, 8,123, 56,212,118, 57, 59, 73,185,155,126, 95,243,181, 89,115,108, 43,251,105,196, 27,166, +142, 14,220,213,143, 61,110, 23, 99, 44,171,127,255,254, 15, 24, 99, 89,251,246,237,123,200, 24,203,234,215,175,223, 3,198, 88, + 22,128,157,149,101, 62, 49, 56,233,198,178, 34,235,195, 57,115,230,200, 24, 99,178, 57,115,230,200,128,210, 65, 84, 59, 72,185, +155, 47,175, 93,108,209, 29,217,204,246,140,234,105,238, 32,229,110,174,116, 57, 29,248, 63,199,109, 92,198,244, 39,182,179, 3, +147,134,152,219,121,216,159, 11, 14, 14, 94, 60,121,242,228,253, 49, 49, 49, 55,204,102,243,237,228,228,228,219,171, 86,173,186, +221,166, 77,155,139,206,206,206,241, 2,129,224,131,154,246,209, 11, 66,153,148, 73,153,148, 73,158,108, 96,170,230,119, 63, 47, + 92,184, 80,194, 24,251,100,192,128, 1,248,230,155,111, 6, 54,105,210,100,176,183,183,183, 43, 0,100,102,102,170,111,222,188, +169, 24, 48, 96, 0,102,207,158,141, 69,139, 22, 45, 69,105, 95,150,255,165,236,131, 7, 15,250, 76,156, 56, 49,247,171,175,190, +178,140, 26, 53,170, 33,128,155,249,249,249, 13,134, 12, 25,242, 33,159,207, 31,224,239,239, 31,154,149,149,149,167,209,104,182, + 3, 88,139, 26,206,153, 86, 69,200,133,185,101, 61, 79,156,224,194,252,216,143,223,152, 61,123,246,160,126,253,250, 25,150, 45, + 91,102, 82, 40, 20,135,107, 25,247, 48, 47, 47,239,203,242, 59, 78, 78, 78, 30,215,175, 95,255,192,205,205,141,155,156,156, 12, +157, 78,135,164,164, 36, 11, 74, 79, 77, 85, 74,105, 98, 43,190,223,119, 42,228,147,161,189,236,213,119,175,193,154,199,131,209, + 74,128,236,223, 79, 96,227,249,187, 10,149, 1, 43,159,101, 61,229,114,249,183,147, 38, 77, 26, 50,117,234, 84,145,191,191, 63, +231,183,223,126,195,238,221,187,117,185,185,185, 61, 0,156,251, 99,232,167,186,177, 88, 44, 16, 8, 4, 0,128,233,211,167,131, +203,229, 90,229,230,230, 10, 56, 28,142,144,195,225,216,112, 56, 28,158, 49,229, 54, 44,138, 34,228, 20,201,241, 48, 71, 94,109, +158,217, 98,217,125,249,242,229,143,155, 55,111,206,189,122,245, 42,242,242,242,144,148,148,196,204,140,237, 60,175, 49,151,118, + 74,212,213,126,249,108,156,156,251, 54,115, 20,114, 5,155,102, 35, 82,207,229,253, 96, 65,127,148,142,165, 5, 0, 27, 57, 28, +142, 53,128,130, 70,141, 26,117,186,115,231,142,184, 81,163, 70,154,187,119,239, 30,227,112, 56,222, 0, 54, 87,150, 41, 22,139, +243, 1,228,239,219,183, 15, 0,198,160,116,227,181,136,138,138,202, 58,127,254, 60,230,204,153,147, 3, 96, 53, 0,216, 58, 58, +247, 14,149, 90,115, 4, 91,230,160,141, 14,220,149, 22, 86,105,171,171,173,155,123,231, 38, 18, 46,172, 54,124,129, 87, 61, 66, +184, 2,147,161,233,220,185,115,207, 43,149, 74,221,174, 93,187,244,239,189,247, 30, 47, 49, 49,241, 10,128, 11, 0,246,161,172, +143, 37, 33,132,144,151,234,201, 22,172, 26,251,104, 61, 89,181,126, 3,224,251,123,247,238, 85, 76, 42,125,239,222, 61, 25,128, + 31, 80, 58, 26,252, 91,117,168,120,103,149,181,104,173,125,198,149,121, 50, 83, 20, 30, 30, 46,190,115,231,142, 53, 42,159,196, +145,243, 12,153, 79,169,108,174,195,224,224,224,229, 70,163,113,255, 15, 63,252,176,135,199,227, 13,121,142,106,223, 63, 40, 40, +168,104,199,142, 29,150,232,232,104, 54,107,214, 44,179,167,167,103, 17,158,238,163,245,167,204, 72, 1,111,239,148,134,222,138, +216, 97,237,216,253,201,189,217,133,161, 29,217, 88,111, 91, 69,164,136,183,251, 57, 63,149, 4, 73,165,210,141, 98,177, 88, 97, +111,111,127, 10, 64,219,231,217, 71,206,206,206, 91, 61, 60, 60, 78, 61,126,115,119,119,223,239,234,234,250,157,139,139,203, 44, + 7, 7,135,113, 1, 34,193,178,201, 13,188,180,241,125, 27,177,211, 17,174,108,168,139,224,201, 83,135, 79, 46,167,103, 64, 64, + 64,193,182,109,219, 44, 63,255,252, 51,155, 49, 99,134,165, 94,189,122, 10, 84,211,175,173,218, 22, 45, 7,222,238,189,253, 90, + 91,114,122,122,179,111, 26,218, 89, 58, 57,242,170,186, 66,113,104, 89, 1, 60,162,166,204,192,192,192, 31, 24, 99,155,230,207, +159,191, 9,127,204, 5,250,250,220,185,115,163, 24, 99, 81,115,231,206,141, 2,208, 29, 0, 34,165,220,109,219,251,180, 52,103, +190,233,197,190,110,104,107,142,148,114,183, 85,218,146,233,196, 63,120,104,116, 79, 75,214,232, 8, 54, 59, 72, 98,110,237, 36, +252, 69, 32, 16, 76, 70,105,139,115, 43, 0, 2,250,212, 76,153,148, 73,153,212,162,245,183, 43,188,106,197,195,201,201,105, 99, +253,250,245,247,248,251,251,239,177,181,181, 93,138,210, 78,243,117,221, 17, 1, 11, 22, 44, 80, 72,165,210,102, 47,112,231,186, + 1,240,198,211, 19,231,190,176, 3,230, 75, 79, 76, 76,156, 58,240,250,151,158,152,248,216,143, 91, 53,108,216,240,107,148,142, +230,253,188, 7,161,191,147,147,211, 42, 39, 39,167,140,178,190, 89,254,181,201,108,201,227, 13,233, 36,226,253,214, 86,192,205, +238, 36,226, 95,122,149,199,123,247, 31,250, 2,172,238, 98,139,170, 50,125, 92, 92, 92,150, 57, 57, 57,101,186,184,184,172,170, + 99,145,245,167,204,102, 98,120,118,118,224, 29,108,107,199, 81,117,150,242,246,181,180,169,250,162,142, 58,172,123,248,156, 57, +115, 70, 50,198, 70,122,121,121, 13,120,172,240, 15,157, 61,123,118, 47,198, 88,175,242, 17,224, 91,217,192,173,163, 3,111, 71, +132, 61, 71,222,209,129,183,163,149, 13,220,170, 90,206, 78, 14,188,221, 17,246, 28,121,164, 61,119,135,159, 16,245,232,205,156, + 50, 41,147, 50,169,208,250,119, 20, 90,116,192, 80, 38,101, 82, 38,101, 82, 38,101, 82, 38, 21, 90,149, 23, 86,143,223, 42,206, +176,241,105,219, 16, 66, 8, 33,132, 60,151, 42, 7, 44,229, 84, 83,149,214,165, 99,251,179, 84,182,167, 41,147, 50, 41,147, 50, + 41,147, 50, 41,243, 63,151, 89, 83,246,255,250,194,186,127, 52,106, 86,165, 76,202,164, 76,202,164, 76,202,164,204,255, 44, 46, +109, 2, 66, 8, 33,132,144,231, 18, 94,246,245,201,129, 75, 43,239,163,197,111, 53, 63,199,100, 50,185, 1, 0,159,207,207, 53, + 94,153,229, 89, 93,186, 21,208,197, 84, 58,253, 14,248,192, 24, 19,112,170,146,204, 83, 38,147,201,177, 44,179,200,120,101, 86, +247,106, 51, 91,205, 63,241,248,227, 77, 87,102,189,254,228, 99, 24,192,179,106, 53, 63,243,137,101,245,170,237, 86,225,224, 79, + 99, 98,189,180,229,252,167,100,254,151, 89,189, 54, 63,199,104, 44, 61,142,172,172,248,185,134,203,213, 31, 71,214,175,205,207, +124,252,241,198,203,179,220,171,203,180, 17, 11, 11, 2,189, 93,151, 86,151,153,156,153,255,137, 74,173,117,174, 46,179,174,175, + 77, 95, 79,207, 46,230,178,215, 38, 15, 24,147,145,149,117,234,111,118, 44,181, 4, 48, 11,128,253, 99, 63,139, 7,240, 17, 29, +149,132,144,127, 88,161, 21,135,210,121, 14,215,149, 21, 91,235,170, 44,180, 76, 38,147,155,236, 64, 20, 84, 58,160,203,240,249, +110, 1,125,215, 62, 53, 81,178, 73, 91, 36,144,223,218, 21,202, 51, 42, 28, 93,249, 6,251,204,204, 76, 14, 0,112, 56,156, 31, + 1,248, 85,146,233, 40, 59, 16, 5,181, 30,136, 28, 60,215,209, 15,176,207,179,182,254, 84, 44,145,116,210,104, 52, 77, 0, 64, + 44, 22,223,210,168, 84,103, 92, 13,134, 37, 79, 62,190,170, 53,123,124, 89, 59, 15,155,239,214,176,239,218, 73,102,139, 69,240, +232,234, 15,145,218,252, 68,190,149, 73,183,250,115,224, 88, 84, 37, 69, 85, 21,121,127,252,221,119,102, 56, 91, 1,157, 5, 34, + 81, 51, 7, 71,199,246, 22,198, 26, 89, 44, 22,142,217,100,186,173, 40, 46,190, 96, 49,153,174,155,244, 42,103,217,225,175, 45, +213, 45,231,147,235,242, 14,192, 63, 0, 12,144,216,218,118,226, 89, 89,181, 5, 0,179,209,248,155, 74,169, 60,243, 54,176,183, + 54,235, 94,219,237,243,172,143,255,175, 49, 26, 77,110, 41, 39,162,160, 51, 2,225,253,191,118, 11, 27,178,101, 7, 0,232,115, +175,187, 43, 19, 15,191, 6, 0,146,192, 94,151,133, 30,225, 57, 0,192, 79,203,114, 75,136,158, 9,157, 17,104,212,107,174, 91, + 77,153,239,205,222,237, 60,117,108, 63, 33, 0,156,220,247, 93,131, 95,247,127,255, 6, 0,116,238, 55,225, 88,183,254, 19, 19, + 0, 96,209,186,253,206, 59,191, 30, 88,109,102,237, 94,155,197,214,197,137,209, 65,122, 69,150,131,175,132,239,145,152,152,200, + 5, 0, 47, 47,175, 90,189, 54,125, 0,105, 22,240, 33,151,199,107, 31, 24, 20, 20, 14,128, 37,223,191, 31,103, 54,153, 46,122, + 2,171, 95,240,177, 52,137,177, 63, 15,206,202,225,112,232,128, 36,132,252,211, 28, 41, 43,174,142, 60,245, 97,182,170,103,168, +116,192,185, 36,160, 67,235, 48,140, 29,242,166,237,227,191,219,187,118,174, 95,226,213, 67, 13, 55,108, 89,194, 13, 11, 11, 67, + 74, 74, 74,173,150, 66,173, 7,206, 38, 2,144,223,177, 43,146, 72,238, 47, 91,188,216,254,245,215, 95,231,123,121,121,129,195, +225, 32, 59, 59,187,245,233,211,167, 91,126,252,241,199,227, 33,191, 83,164,214,163,228,108, 98,205,185,229,203,218,164, 65, 61, +204,154, 56, 80, 10, 0,159, 15, 95,221,242,234,189, 28,167,251,247,239,119,153, 54,109, 90, 1,239,204,153,239, 93,128, 77, 57, +192,195,218, 44,231,214,159, 47,139,164, 89, 63, 5, 12,157, 56,113, 95, 80, 80,144,173,191,191, 63,199,206,206, 14, 60, 30, 15, + 69, 69, 69,126, 55,111,222,124,227,202,149, 43,170,211,231,126, 20,196, 94,233,157,156, 43,122, 77, 91,171,117,215,100,138, 78, +218,217,221, 26,246,246,219, 62, 3, 7, 14, 20, 5, 6, 6, 2, 0,238,223,191, 31,188,119,239,222,193,251,246,237,155, 13, 77, +166, 73,173,135,182,166,117,175,200, 4, 32, 2,218, 58,184,185, 13,229, 89, 89, 53, 49,153, 76,222,101,173, 13,143,204, 70,227, + 45,121,110,238,246, 39, 31, 79,158,166, 51, 2,119,178,128,174,237,195, 49,172, 95, 87, 9, 0, 76, 27,180,160,117,218,131, 36, +107,189, 94,143, 6, 33,141, 34,230,125,189,244, 4,184, 92,108,219,127,186,226,241,181,201,140,191,147,130,168,121,203,144,121, + 99,111,107,115,113, 82,167, 18, 69, 49, 15, 0,236,165,210,126,123,119,253,116,198, 43,116,192,239, 73,249,134, 90,101, 86,247, +218, 60,190,107,149,103,198,205, 51,141,215,156,220,104,229,231,231,135, 27, 55,110,212,237,181, 89,124,207,206,226,233,121,123, +201,103,159,121, 68, 70, 70,194,214,214, 22,124, 62, 31, 38,147,169,235,197,139, 23,187, 70, 69, 69, 77, 64,241, 61, 85,109, 95, +155,181,176,132,195,225,116,122,111,236, 36,207, 55,251, 12, 64,191, 30, 17,116, 32, 18, 66,254,105,202, 91,175, 30,191,242,112, + 93,181,133, 22,159,207,207,125,125,196, 87,110,237, 95,107,138,171,215, 19,138, 83,211,179,148,229,191, 43,188,181,183, 65,159, + 8,239,198,231,207,159,131, 78,167,195,111,191,253,134,235,215,175,227,193,131, 7, 24, 55,110,156,174,236,212, 97,101,153, 69, +145,131,231, 58,162, 56,209, 54, 88,112,239,149,211,119,239,242,180, 90, 45,206,159, 63,143,162,162, 34, 8, 4, 2,248,248,248, +160, 91,183,110,252,187,119,239, 58,117,121,189,135, 52,178,199,187, 41,144, 6, 43,249,124,126, 81, 85,243,136,240,249,252,220, + 46,195,231,187, 53, 14,174,135,251,169,153,197,179,190,222,160,180, 88, 24, 63,249, 65,154,225,220,185,115, 8, 15, 15,199,169, + 83,167,156, 11, 11, 11,191, 88,189,122,245, 44,171,133,107, 86, 24,245, 5, 83, 80,117, 94, 81,228,224,185,142,206,185,123,252, +127, 61,126,208,250,214,173, 91,214, 63,252,240, 3, 10, 10, 10, 32, 16, 8,224,224,224, 0, 15, 15, 15, 52,104,208,128,243,249, +231,159,219,246,234,117, 11,255, 55,102,128,191, 33, 96,244,189,170,150,179, 98,221,149,105, 54, 46,138,147,129,251,143, 28,225, +182,107,215,238, 79, 31,219,235,215,175,143,238,221,187,139,134, 14, 29, 26, 56,112,240, 16, 75,100,207,247,238,195,214, 95, 93, + 99,166,234,161,216, 89, 29,227,213,117,240,224,195,115,231,206,117,240,240,240,128, 68, 34, 1, 0, 20, 23, 23,251,164,166,166, +182,158, 61,123,118,255,203,241,187,248,145,189, 30,102, 66,226,171,169,110,123,254, 87, 89, 89,241,115,203, 91,145,236, 36,226, +162,135, 25, 57, 42, 0,208,235,245,208,235,245,208,233,116,248, 96,194, 56,222,152,254,173,130,252,219, 79,186,246,224, 81, 78, + 97,163,211,191, 59,149, 63,215, 88, 67, 38, 95,253, 64, 46, 79,255,101, 76,212,103,159,121,184,187,255,113, 70,112,219,214,173, +188,194,194,194,174, 81, 81, 81,141,153, 77, 71,121,163, 94,115, 29,170,203,172,238,181, 41, 79, 56,242,202,188,137,221,155,173, +253, 58, 26,102,179, 25, 49, 49, 49, 56,127,254, 60,150, 46, 93,202,142, 29, 59, 86,108, 47,145,140, 65,181,175,205,123,118,237, + 60,179, 3, 22, 46,220,199, 17, 10,133, 56,116,232, 16,238,222,189, 11, 46,151,139,176,176, 48, 12, 27, 54, 12, 93,187,118,245, + 24, 59,118, 28,139,236, 49, 40, 25,210,144,146,231, 60,150,184, 0, 38,205,136, 90,232, 57,124,244,135, 88, 52,239,115, 42,180, + 8, 33,255,228,214,172, 42,135,120, 64,116,116, 52, 43,187,117, 0, 0, 6,112,235,247, 93,187,115, 79,172,229, 72,253,190,107, +119, 50,128,203, 0,174, 61, 80,175,121,243,230, 70,185, 92,206,174, 92,185,194, 62,248,224, 3,213,138, 21, 43,206, 28, 57,114, +100,175,201, 96, 88,239,229,233,249, 45,171,162,131, 61, 3,184,254,128,212,198,198, 38, 47, 61, 61,157, 29, 61,122,148,205,153, + 51,135,109,223,190,157, 29, 59,118,140,157, 62,125,154, 29, 59,118,140,237,220,185,147,197,199,199,179,132,132, 4, 38,145, 72, +242,252, 1,105, 53,153, 60, 6,240, 26,244,253, 97,202,190,171,198,185, 33,125,215,126,204, 0,158, 35,208,176,121,243,230,230, +189,123,247,178,109,219,182,177, 45, 91,182,176,248,248,120,150,159,159,207,248, 66, 73, 94,249,243,170, 90, 78, 6,112,189,189, +189,243,228,114, 57,243,245,245,101, 2,129,128,185,187,187,179, 6, 13, 26,176,214,173, 91,179, 55,222,120,131, 13, 25, 50,132, +125,241,197, 23, 76, 46,151, 51,145, 72,148, 83,254,188,170, 50,195, 1,177, 68, 34, 73,151,201,100,172, 42, 26,141,134,229,231, +231,179, 19, 39, 78, 48,137, 68,146, 30, 14,136,171,203, 20, 3, 45, 66, 67, 67,243,242,243,243,153,193, 96, 96,233,233,233,236, +230,205,155,236,238,221,187, 44, 61, 61,157,105, 52,154,138,236,132,132, 4, 22, 16, 16,144, 39, 6, 90, 48,186, 8,162,202, 99, +233,201,155,159,187,251, 27, 30, 30, 30,154,125,251,246,177, 71,143, 30,177,205,155, 55, 51, 46,176,224,201,199, 85,151, 41, 0, +186,181,107,215,206, 28, 19, 19,195,174, 93,187,198,166, 79,159,206,186,119,239,206,122,244,232,193,162,162,162, 88, 70, 70, 6, +203,200,200, 96,111,188,241,134, 89, 0,116,171,233,248,172,236,181, 41, 5,252,122,245,234,165, 49, 24, 12, 44, 57, 57,153, 53, +105,210, 36,131, 7, 12,149, 0,141, 59, 0,194,154,142, 79,111,192,209,211,211, 51, 43, 38, 38,134,237,223,191,159,249,251,251, +231,241,128,247,236,129,250,246, 64,125, 30,240, 94,253,250,245,243, 98, 98, 98, 88, 65, 65, 1,243,243,243,203,242, 6, 28,159, +227, 88,226, 2,216, 56, 35,106, 33,187,151,161, 98, 51,162, 22, 50, 0,233,140, 49,134, 74,250,120, 18, 66,254,253,158,172, 69, +254, 45, 42,222, 36,123,245,234,197, 1,112,182,186, 7,107,120,188,175, 22, 45, 90,196,215,106,181,216,176, 97, 67,201, 59,253, +251,239,233,208,190,125,242, 43,254,254,114, 14,151, 91,227,108,195,121, 66,225,228, 69,139, 22, 57,232,245,122,196,198,198,162, +101,203,150,240,240,240,128,173,173, 45,108,109,109,225,230,230,134,144,144, 16,228,230,230,194,206,206, 14, 83,167, 78,149,230, + 9,133,147,107,202,181, 88, 24, 31, 0,204, 22,139,192, 26, 24, 27,240,234,171,177,179,103,207,230, 58, 59, 59,195,201,201, 9, +182,182,182,184,123,247, 46,244,122, 61,108,196, 54,181, 26,164,149,203,229,114,109,109,109,241,235,175,191, 98,210,164, 73,104, +219,182, 45, 28, 28, 28, 96,103,103,135, 38, 77,154,160, 91,183,110, 24, 51,102, 12,146,147,147,193,169, 69,167,146,219,124,254, +135, 99,198,140,113, 11, 15, 15,175,244,247, 90,173, 22,114,185, 28,121,121,121,240,241,241,193,128, 1, 3,220,110,243,249, 31, + 86,149,231, 12,120,248, 4, 7, 31,190,114,229,138,139, 68, 34,193,182,109,219,112,240,224, 65, 28, 63,126, 28, 71,143, 30, 69, +116,116, 52, 14, 29, 58,132,188,188, 60, 0, 64,112,112, 48,118,239,222,237, 98,235,230, 22,237, 12,120,208, 75,186,118,210,114, +114, 78, 54,201,206,118, 25, 58,100,200, 5,165, 82,137,161, 67,135,226,171,111,190,249,220, 10,248,184, 54,207, 15, 1,164, 78, +158,158,155, 22, 46, 92,200,205,206,206,198,219,111,191,157,191,228,155,111,222,143, 59,113, 34, 80,118,252,120,224, 87,115,231, +190,223,161, 67,135,252,140,140, 12,108,221,186,149,235,238,231,183, 41, 4,144,214,117, 57, 75,128, 73,203,151, 47, 23,105,181, + 90,188,254,250,235,201,150, 91,183, 66, 76,192, 79, 74,224,238, 89,192, 80,211,243,179,128, 15,167, 78,157,234, 33, 20, 10,241, +233,167,159,230,171,211,210,154,154,128, 45,197, 64,106, 49,144,106, 2,182,148,164,164, 52, 29, 62,124,120,190, 80, 40,196,178, +101,203, 60,178,254,152,116,187,182, 90, 2, 56, 12,224, 28,128,204,247,198, 78,122, 47,188, 85, 27,108, 93,191, 26, 95,207,157, +182, 9,192, 59, 28, 14,103, 59,128, 41,116,228, 17,242,223, 84,155, 90,228,111,170,202, 41,119,248,143, 87,146, 0, 58, 86,151, +226,232,236,220,178,105,211,166, 56,127,254, 60, 66, 67, 67,175, 56, 56, 56,152,172,133, 66, 88, 89, 89,129, 89,106,172,179, 32, +150, 72,186,116,237,218,149,255,251,239,191, 35, 32, 32, 0, 98,177, 24, 86, 86, 86,127,186, 89, 91, 91,195,211,211, 19, 10,133, + 2, 93,186,116,177, 90,185,114,101, 23,232,116,243,106,252,135,152,120,211, 54,239,247,133, 67,126,220,188,169,126,100,100, 36, +138,139, 21,176, 88, 44,176,177,177,129, 94,175, 7,159,207, 47, 61, 5,100,100,138,218,108, 49,179,217,108,230,241,120, 8, 8, + 8,192, 87, 95,125, 5,173, 86, 11,107,107,107, 0,128, 66,161,128, 92, 46,199,205,155, 55,145,154,154,138,178, 79,225,213,178, +147, 74,223, 28, 56,112, 96,165, 19,254,234,116, 58, 20, 23, 23,163,184,184, 24,114,185, 28, 90,173, 22,109,218,180, 17, 28,137, +142,126, 19, 5, 5, 75, 42,125,142, 72,212,127,235,214,173,110, 2,129, 0, 26,141, 6, 37, 37, 37,120,248,240, 33,210,210,210, +180,185,185,185, 38, 59, 59, 59,174,191,191, 63, 87, 40, 20, 10,251,246,237,203, 81, 40, 20,224,112, 56,232,213,171,151,243,142, +109,219, 6, 66,175, 95, 74, 47,233,218, 57, 9,232, 90,232,245,111,189,214,170,213,175, 87,174, 94, 13,159, 60,121, 50,226,227, +227, 23,218,236,218,117, 78, 13, 92,175,238,185,201,192,135,223, 62, 86,192,176,180,180, 80, 3,144,247,216, 67, 82,253, 83, 82, +142, 15, 31, 62,252, 70,124,124,188,203,178,101,203, 60,222,121,251,237, 15, 1, 44,168,203, 50,218, 73,165,175,122,122,122,226, +216,177, 99, 72,127,240, 96,154, 9,208,212,233, 19, 23,143,215, 46, 50, 50, 18,135, 14, 29, 66, 70, 90,218, 52,211,159,151,177, +244,131, 18,144,199, 79, 78,158,182,105,211,166,141,163, 70,141, 2,143,207,111, 7, 83,157, 78, 28, 62,213,241,125,212,184,201, +216,180,110,229, 38, 0,163, 1, 88, 0, 92,161, 35,142,144,255,118,171, 86, 77,181,200, 63,168,216, 90, 87,231, 22, 45, 55, 55, + 55,111, 91, 91, 91,100,102,102,162, 81,195,134,185, 66,161, 16, 2, 43, 43,136, 4,130, 90, 45,129, 90,173, 14,245,242,242, 66, +113,113, 49, 92, 92, 92, 96,109,109, 93,113, 19, 8, 4, 21,223,219,217,217,129,203,229,194,207,207, 15,106,181, 58,180,198,220, +156,155,110,187, 86, 78,248, 32,230,220,177,250,111,191,221, 15,142,142, 78,240,245,245,129,155,155, 27,196, 98, 49,124,125,125, + 17, 24, 24,200,150, 44, 89, 2, 27,183,176, 90,189,145, 63, 94, 60,241,249,124,152,205,102,228,228,228,224,222,189,123,136,143, +143, 71, 76, 76, 12,174, 93,187,134,146,146, 18,212,162,206,130, 90,163,105,198,231,243, 43, 45,178,228,114, 57,228,114,121, 69, +161,149,151,151,135,212,212, 84, 40, 85,170,230,213, 20,189,253,154, 54,109,202, 3, 0,177, 88,140,230,205,155, 99,237,218,181, +166,159, 15, 30, 28,212, 56, 38,198,201,247,196, 9,135, 31,127,248, 97,208,128, 1, 3,204,191,255,254, 59, 20, 10, 5,238,220, +185, 3, 87, 87, 87,190, 64, 36, 26, 72, 47,231,186,145, 1, 42,151,146,146, 30,109,219,182, 77, 41, 46, 46,198,226,197,139,185, + 86,118,118,235,230, 86,113,138,175, 2,143, 23, 17, 25, 25,137,195,135, 15, 35, 51, 45,109,122, 90, 37, 5, 76, 26,144,151,158, +156, 60,125,211,166, 77,232,214,173, 27, 56,124,126,157, 59, 42,181,110,221,186,169,197, 98,193,141, 27, 55,224, 0, 92,174,235, +243, 3,131,130,194,203, 91,126, 37,192,133,170, 30, 39, 1, 46,196,197,197, 65, 44, 22,163, 81,227,198, 45,234,248,103,150,112, + 56,156,172, 81,227, 38, 99,255,241, 75, 0,128, 77,235, 86,230, 60, 86,100, 17, 66,168, 69,235,159,218,162, 85, 94, 88, 61,126, +195,159, 10,173, 90, 22, 31, 0, 0, 43, 43, 43, 8,132, 66, 8, 4,130,210, 2, 73, 40,172,117, 6,135,195,129, 72, 36,170, 40, +172, 30, 47,176, 30,255,222,198,198,166, 86, 5, 12, 0, 20, 37, 29,111, 63,250,253, 81, 2,161, 80, 8,189, 94, 7,198, 24,132, + 66, 17, 28, 28, 28, 16, 16, 16, 0,133, 66,129,182, 17, 29,116, 15,229,214,209,206,141,250,198, 63,203,214, 51,153, 76, 80,169, + 84, 40, 42, 42, 66, 97, 97, 33, 20, 10, 5, 52, 26, 77,173, 47, 69,183, 88, 44,188,135, 15, 31,226,167,159,126, 66, 65, 65, 1, +128,210,142,214,229,197, 85,249,215,148,148, 20,108,219,182, 13, 15, 30, 60,168,211,254,105,223,190, 61,162,163,163,121, 29,187, +116, 89,127,202,223, 63,243,148,191,127,102,199, 46, 93,214, 31, 62,124,152,231,237,237,141,212,212, 84,196,198,198,162,168,168, + 8,140, 49,186,126,254, 25,220, 7,138,212,133,133,163, 62,255,252,115,102,107,107,139,197,223,126,219,108, 1,240,110,109, 11, + 24,105, 53, 5,140,244,249, 10, 24, 48,198, 96,177, 88, 96, 54,155,159,105,221, 56, 28, 14,199,202,202,170,174, 67, 43,212,229, +193, 21, 29,223,167,126,241, 21,142, 30,218, 91,254,243, 68, 42,178, 8, 33,255, 2, 85,118,132,231, 63, 86, 65, 86,124,173, 74, + 78, 78,206, 35,149, 74, 85,223,223,223, 31, 25, 25, 25,110,126,126,126,105, 2, 43, 43, 88, 11, 4,224,112,107,174, 9,108,108, +108,110,100,102,102, 70,120,123,123,195,100, 50, 85, 20, 85, 79,158, 58, 44,111,165,185,118,237, 26,108,108,108,110, 64, 91,237, +200, 9, 48,235,139,234,181,104,209,162,162,101,200,193,193, 1, 14, 14, 82, 8,133, 34,204,156, 57,211,178,108,201,146,213,126, +157,231, 22,143,252,248,115,246,249,130,245, 47,116,203,214,246, 31,147,141,141,205, 13, 95, 95,223, 54, 82,169, 20,251,247,239, + 71,106,106, 42,138,138,138,160, 86,171,161,211,233,160, 86,171,161,215,235, 33, 18,137,208,184,113, 99,216,219,219,227,244,233, +211, 55,160,211, 85, 94, 92, 22, 20,236,191,113,227, 70,155, 86,173, 90, 85,180,168,116,234,212,137,211,169, 83, 39,151,138, 86, + 52,181, 26,249,249,249,184,114,229, 10, 78,159, 62, 13, 14,135,131,196,196, 68,179, 78,163,217, 73,175,137,103,163, 5,126,227, +109,218,180,113,252,248,241,239, 71, 68, 68,192, 12,188, 1, 96,219, 95, 88,192, 0, 0, 98, 98, 98,110,154,205,230,136, 6, 13, + 26, 64, 14,188, 6,224, 80,157,138,200,164,164, 56,147,201,212,165, 89,179,102,216,191,103, 79,123, 0,169,149, 61, 78, 5,180, + 15, 15, 15,135, 70,163,193,157,219,183,101,117, 40,178,214,207,136, 90,248,222,240,209, 31, 98,235,250,213,216,180,110,229,195, +141,107, 87,248,162, 22,253,199, 8, 33,255,169,214,172, 26,107,145,191,169,177, 85, 21, 95,252,186,164, 20, 23, 21,201,226,226, +226,234,183,104,209, 2,235,215,175,111,213,182, 77,155, 71,214, 2,129, 73, 96,109, 13,110, 45,254,145,104, 84,170, 95,126,249, +229,151,215,250,246,237,203,255,253,247,223,225,225,225, 81, 81,104,149,127,229,243,249, 96,140,193,198,198, 6, 7, 14, 28, 48, +104, 84,170, 95,106,108, 45, 50, 91,204,220,178, 66,143, 49, 6,185, 92, 14,107,107,107, 44, 93,186, 12,171,150, 44, 25, 98, 6, +246, 6, 75, 92, 63, 3, 32,250,203,254, 65,171,213,191, 30, 61,122,180,229,236,217,179,173,124,124,124, 32,151,203, 81, 84, 84, +132,130,130, 2, 40, 20, 10, 40, 20, 10, 20, 21, 21, 65, 46,151, 67, 36, 18, 33, 62, 62,222,168, 85,171,127,173, 42, 79,168,213, +238, 27, 49, 98,196,212,184,184, 56, 79, 62,159, 15,163,209, 8,139,197, 2,139,197, 2,131,193,128,164,164, 36,220,186,117, 11, +119,239,222, 69, 97, 97, 33,172,172,172,192,227,241,112,237,218,181, 34,137,209,184, 71, 79,175,233,103,102, 5,236,191,120,241, +226,251,195,134, 13,131,151,143, 79, 7,100,100,212,170,128, 57, 88, 77, 1, 83,252,108, 5,204, 31, 5, 80, 73,201,213,148,148, +148,136,142, 29, 59,194,211,199,103, 97,227,140,140, 83,183,235,208, 79,203,108, 50, 93,184,120,241, 98,151,225,195,135, 99,253, +250,245, 11, 93, 83, 82,142,231, 61,113,154,211, 21,112,125, 37, 48,112,225,123,239,189,135,147, 39, 79,194,108, 50, 93,168, 38, +242,241, 17,223,235,189, 55,118,146,239, 19, 29,223,215,114, 56,156,137, 0, 22,211, 17, 69, 8,249, 55,183,104,213,233,212,161, +216,108,158, 49,101,202, 20, 35,151,203, 69,191,126,253,236, 14, 29, 62, 60,224,218,245,235, 1,185,185,185, 14,102,179,185,198, + 44, 87,157,110,197,148, 41, 83,228,122,189, 30, 33, 33, 33, 40, 44, 44,132,217,108, 6,159,207, 7,159,207, 7,135,195, 1,151, +203,133,173,173, 45,226,226,226,176,113,227, 70,133,171, 78,183,162,198,127, 18,102,243,141,109,219,182,129,199,227, 49,145, 72, + 4, 14,135, 3, 62,159,143,101,203,150,229,174, 2,246, 3, 0,143,203,213, 3, 0,151,203,169,109,239,221, 26,207, 91, 10, 4, + 2, 88, 74, 47, 2,168,241,177,142, 58,221,242, 69,139, 22,149,220,185,115, 7, 42,149,170,162,245, 77,169, 84, 86,116,174,151, +203,229,224,112, 56, 80,169, 84, 56,124,248,112,137,163, 78,183,188,170,188, 2, 32, 59, 35, 49,177,119,171, 86,173, 10, 82, 82, + 82, 80, 92, 92,140, 27, 55,110,224,244,233,211,216,189,123, 55, 78,158, 60,137,164,164, 36,152, 76, 38,120,123,123,131, 49,134, +131, 7, 15, 22,155, 74, 74,222, 40, 0,178,233, 53, 81,181,122, 30, 30, 93,220,221,220,210, 93, 93, 92, 50,234,121,120,116,121, +242,247, 82, 32, 33, 33, 33, 1, 38,147, 9, 1, 1, 1, 78,213,245,211, 98, 38,211,197,139, 23, 47, 98,248,240,225,240,173, 95, +255, 27,127,192,245,201,199,248, 3,174,254,129,129,223,148, 23, 48,204,100,186, 88,215,101,182, 3, 86,126,246,217,103, 26,107, +107,107,236,218,181, 43,192, 24, 20,116,151, 15,188,107, 11, 52,236, 8, 88,215,244,124, 79, 96,245, 23, 95,124,145,205,225,112, +176,125,251,118, 23,105, 96,224, 77, 62, 48, 66, 10,212,147, 2,245,248,192, 8,105, 96,224,205, 93,187,118,185,152, 76, 38,124, +252,241,199,217,158,192,234,106, 34, 39, 49,198,222, 98,140, 69, 50,198,124, 55,174, 93,129,163,135,246,150, 23, 89,163, 81,218, +233,125, 24,128,155,116,196, 17, 66,254,205, 42,109,134,226,183,154,159, 3, 48,183, 14,173,195,112,245,250,189, 98, 23, 71,251, + 19,229,191, 43,188,181,183, 65,231, 80,251,176, 53,107,214,192,202,202, 10, 15, 31, 62,196,237,219,183, 97,111,111,143, 33, 67, +134,232, 52, 37, 37,189, 31,155,235,176, 43,128,211,101,153,165,243,169, 21, 39,218, 6,242,227,235, 31, 63, 26,205,147, 74,165, + 80, 42,149,224,114,185, 16,137, 68,176,177,177,129, 88, 44, 70,108,108, 44,122,190,213,199,156,103, 19,249,199,128,165,127,204, +167, 86,145, 89, 62,214,208,107,128, 77, 28,240,169,155,151,215,148, 89,179,102,137,187,119,239, 14,107,107,107,248,212, 11,206, + 14,232,177,120, 37,151,203, 49,101, 20, 40,102, 6,214,243,146,222, 78, 76, 5,192,201, 53, 94,153,229,245,216, 92,135, 79, 45, +167,159,254, 92,192,129, 45, 75,236,155, 55, 47,237,143, 46,151,203,145,147,147,131,220,220, 92,200,229,114,168, 84, 42, 0, 64, +116,116, 52,142,158,191,171,208,248, 12, 72,174,106, 57,255, 88,247,123,118, 94,134,203,175,236,216,182,133,231,234,234,138,156, +156, 28,228,229,229, 65, 46,151, 67,163,209,192,108, 54,163,176,176, 16, 27, 54,109, 49, 23,216, 70, 62,168, 24, 16,178,186, 76, +213, 67,177,147,242,146,119,120, 99,127,246,254,251,239,219,217,219,219,195, 98,177,160,168,168, 8,233,233,233, 72, 73, 73,193, +249,243,231, 85,185,114, 61, 84, 46,175,103, 84, 12, 88, 90, 73,230, 11,244,143,203,124,124,220, 42, 47, 79,207,204,180,180, 52, + 55,179,217, 12,111,111,111,147,188,176,240, 27, 1,112,210, 14,200,250,127,246,174, 59, 44,138,107,125,191, 51, 59,219,119, 89, +250,210, 81, 68, 64,186, 34,150, 24, 75, 20,236,216, 75, 52, 26, 77,108, 49, 49,177,196, 36, 26, 19, 91,212, 24, 99,162,166, 89, +163,198,146,216,176, 4, 59,138, 98,185, 54,176,208, 65, 4, 1, 41, 75,221, 93,182,183,249,253, 33,112,209, 0,187,152,228,222, + 27,127,251, 62,207, 62, 44,187,179,239,156,115,230,204,153,247,124,231, 59,223, 7,128,174, 0, 62,219,248,221,119,111,143, 24, + 49, 2, 93,186,116, 41, 44, 45, 43,243,105,170, 47,209, 0,163, 3, 96,171,244,244, 76,189,117,235,150,107, 65, 65, 1,222,124, +243,205,138,199, 15, 31, 46,170,247,215,146, 2,189,218,180,111,191,246,192,129, 3, 78,237,218,181, 67, 88, 88, 88, 41,183,160, + 32, 36, 19,144, 54,211, 63,155,189, 55,107,178, 78,250,204, 30, 21,218,229,221,119,223,133,193, 96, 64, 98, 98, 34,110,222,188, +137,199,143, 31,227,218,181,107, 53, 34,129,224,245, 70,185, 14,155,236,159,131,253, 21,190,251,246,237, 37, 88, 44, 22,118,237, +218,133,228,228,100, 0, 64, 68, 68, 4,222,122,235, 45, 24, 12, 6, 76,154, 52,153, 62,153,201,203,109,169,127, 2, 8, 5,176, + 30, 79, 69, 94, 23,154,166,185, 4, 65, 20, 3,240, 66,235,124,178,172,253,211,202,105,229,252,255,195,249, 82,194,108,174,195, + 85,155, 97,251,108,154,143, 25,197,135,183,174,160,122,246,234, 29,184, 98,249, 50,178,107,215,174,240,242,242, 66, 68, 68, 4, + 10, 10, 10, 56,118,118,118,230,242,169,213,246, 30, 52,241, 81,120,120,184,221,162, 69,139,108, 7, 12, 24,192,244,242,242, 2, + 77,211, 72, 78, 78, 70,108,108,172,110,199,142, 29, 50,165,203,176,154,164,132, 95,107, 45,201,167,118, 19, 80, 2, 88,233, 89, + 92,188,237,189,217,179,151,117,234,220,121,218,242,229,203, 73, 33,159,199, 92,179,100, 58, 23, 0, 86,253,112,208,118,196,216, + 55,176,209,237,243,221,133, 0, 0, 32, 0, 73, 68, 65, 84, 15,232, 51,177,233, 60,114,141,203, 89, 80, 52,227,241,144, 81, 81, +126, 31,206,121,219, 56,126,252,120,129, 72, 36,130,151,151, 23,236,237,237,145,155,155,139,162,162, 34,250,247,223,127,175,253, +215,221, 44,230,177,115,183, 31,115,109,221, 44,201, 75, 40,239, 61,112, 92,222,144, 33, 67,236,167, 76,153, 98, 19, 25, 25,201, +228,112, 56,224,112, 56, 40, 43, 43, 67, 78, 78,142,238,247,223,127,175, 85,138, 7, 87, 39, 37, 28,144, 91,152,235, 80,213,123, +194,138,156, 43,231,151,207, 79,125,240, 96,178, 9,232,168,211,233, 60,140, 70, 35, 65,146,100,137,201,100,122,160,147,203,119, +106, 34,150,111,176,230, 58,180, 12, 70,163,145,101, 52, 26, 81, 83, 83,131,243,231,207, 83, 15, 31, 62,252,236,222,189,123,159, + 21, 23, 23, 67,175,215, 99,204,152, 49,136,136,136, 64, 66, 66, 2,202,203,202,126,111,137, 43, 19,144,114,138,138,222,154, 49, + 99,198,233,189,123,247,146,247,238,221,115,218,181,107,215,207, 77, 9,152,201,147, 39,155,202, 10, 10,222,210, 0,210, 22,250, +103, 75,247,102,197,153, 3,223,223, 27, 57,122,108,240,242,165,159, 49,123,244,232, 1, 39, 39, 39,244,234,213, 11, 58,157,206, + 46, 40, 40,200,220,189, 41,239, 61,232,245,220,142, 29, 59, 10, 54,108,216,224,250,246,219,111, 99,206,156, 57, 0, 0,149, 74, +133,115,231,206, 97,254,252,249,165, 5, 84, 55,133,185,254, 89,103,169,170, 23, 96,151, 1,244, 6,144, 11,171,227,187, 21, 86, + 88,241,114,162, 62,169,180, 27,158, 38,150, 62,137,167,147,115,243,185, 14,175,220, 76, 65,227, 52, 31, 79,225,150,102,240,158, +242,112,214,194,181, 97, 12,189,204,158, 73,168, 69,217, 89, 89,132,185,156,135, 13,249,212,108,253,107, 29, 31,253,214,117,205, +170, 85,115, 55,110,220, 24, 85, 31,194,129,207,231, 63, 80, 41, 20, 23,156, 53,154, 77, 74, 91,255, 11,173,205,205, 87, 4,148, + 1,152,109,159,148,244, 93,204,136, 49,235,184, 14,190,204, 79, 87,239, 80, 51, 72, 82,155, 83, 92,142,141,126,128,192,130, 13, +146, 74, 45,144, 90,227,102, 40,115, 28,155,249,249, 71, 31,125,184,106,229,202,174, 66,161,176,143,206, 96,240, 55,153, 76,128, +201,148,173, 84, 40, 46,211, 58,221, 45, 77,196,210,111,184,182,110,180,197,121, 9,237,130,228, 14,121,135,187,238,222,185,243, +131, 67,135, 14,253,161,238,142, 26,205,119, 74,187,160,120, 75,234,222,248, 24, 53,112, 29, 18,201,245,150, 76,151,214, 92,135, + 22,206, 62, 76,166,153,246,246,246,123,162,162,162,184,209,209,209, 24, 58,116, 40,122,244,232, 1,147,201, 4,154,166, 33,151, +203,113,240,224, 65,172, 91,183, 46,219, 7, 88,105,142, 79, 3, 92,224,156, 58, 53,184, 99,199,142,187, 90, 18, 48,117, 34,203, +172, 79, 98,203,247, 38, 39,219, 96, 59, 60,127,194,123,107,252,180,178, 18, 59, 71,190,193, 53, 53,229, 1,105,249,189,217, 65, +110, 76, 62,216,109,204,168, 81,239, 49, 40,170, 87,221, 14, 72, 58, 61, 45, 45,169, 62,169, 52, 34,222, 58,223,202,190, 84, 31, +187,206,234,248,110,133, 21, 86,188,236, 66,107, 40,158,250,107, 53,164,228,105, 54,215, 97,189,213,135,162, 40, 73,238,177, 89, +111,180,196,206, 4,162,234, 44, 89, 48,155,235,176,238,125, 62, 32,135, 70,243,197, 51,193, 72, 27,237, 46,100, 62,119,124,107, +194, 34, 86, 3,153, 48,104, 98, 32, 73, 3, 78,204,126,202,215,117,213, 39,141,235,212,236, 67,246,153,243,178,170,212,192, 21, +212,214, 94, 65,109,109,147, 78,187, 76,138, 85,101,174,156,207,215,189, 0,144,253,217,186, 63,207,105, 86, 60,252,137,246,252, +255,134, 39, 21, 21,199, 0, 8, 61,227,226, 92,206,196,197,141,255,112,193,130, 49,110,238,238,237,157,156,156,236,109,108,108, +200, 27, 55,110, 60, 50,168,213,223,117, 2,118,215, 89, 83,205, 66, 3, 92,232, 80, 80, 16, 50,110,212,168,247, 8,138,234,217, + 88,192,208, 6,195, 53, 95,224,199,150, 44, 89, 47,122,111,122,113,220,162,234, 44, 89, 96, 0, 51, 44,233, 27, 69, 79,203,177, + 26, 6,195,106,220,191,223, 68,159,111,117, 95, 90, 69, 16,132, 28, 86,199,119, 43,172,176,226,229, 69,125,190,195,147,255,233, + 19, 71, 91, 57,173,156, 47, 17, 39, 3, 79,119,209, 89,219,211,202,105,229,180,114, 90, 57,173,176, 8,148,181, 9,172,176,194, + 98, 24,241,239,101, 48, 43,172,176,194, 10, 43,172,168, 71,189,111, 86, 99,108, 3,158,186,238, 52,167, 74, 91,179,155,224, 69, +148,109,188,149,211,202,105,229,180,114, 90, 57,255, 43,156,124,252,113,217,219,218,158, 86,206,255, 20,167, 57,238,127,226,110, +198,122,159,172, 6,223,172,255, 20,172,102, 85, 43,167,149,211,202,105,229,180,114, 90, 57,173,156, 47, 59,220,234, 68, 86,227, + 23,128, 86, 6, 44,181,194, 10, 43,172,120, 89,177,124, 57, 72,154, 6, 65,211,203, 73,154, 62,196,160,233,177, 12,154,198,159, + 74, 5, 50,118,108,211,193,108,223,127,195,222,198,218,226, 86, 88,241, 82,161, 4,205, 36,149,182,250,104,253,119,225,237,234, +234,186, 21, 0, 81, 90, 90, 58, 19, 64,129,181, 73,254,247,224,224,224, 16,101, 48, 24, 32,147,201, 46,188,140,245, 11,110,143, + 81, 52,137,160,134, 15,104, 20,164,231, 96, 79, 83,199, 6,249,225, 77, 16,255,142,197, 69,152,144,158,246, 16, 71, 91,113, 58, +114,112,180,215,143, 0,112, 58,190,240, 61,252, 61,113,181, 2,156,157,157,207, 82, 20, 69, 25,141,198,217, 18,137, 36,174,121, + 33, 52,150, 1, 0, 76, 58, 97,113, 77,169,120,209,188,119, 8,166, 82,179,179, 70,163, 82, 72, 25, 76, 70, 30,135,233,122,117, +214,219,228,233,234,218, 87,210,154,250,253,225,195,135,155,205,226, 29,226,135,193,164, 49,120, 88, 68,232,163,220,245,155,186, +110,236,227,235,196,124, 84,120, 87,248,213, 22,233, 86,182, 93,155, 97,111,142, 39,226, 40, 62, 49,121,231,206,202,218,151,245, +222, 89, 3,144,122, 38,179, 3, 97, 50,249,130, 32,248, 4, 0,218,100, 50, 17, 36,249,136,107, 48,100, 45, 4,106, 95,128,211, + 65, 7,132, 49, 57, 28, 47,163,193,224, 66, 0, 52,131,162,202,244, 26, 77, 33, 11,184,191, 24,168,121,217, 57, 89, 28,142,167, +209, 96,112, 1,128,255,197,114, 90,241, 44,154, 21, 90, 66,161,240, 14, 73,146,158,141,147,225,214,231, 19,172,255,172,241,119, + 4, 65,192,104, 52, 22, 85, 87, 87, 71,182,226,252, 34, 0,227, 1,212,111, 81,223, 15,224, 32, 94,220,225, 88,196, 98,177, 22, + 10, 4,130,126, 42,149, 42, 4, 0,120, 60, 94,170, 66,161,184,168,211,233,214,191, 32, 47, 5, 96,156, 80, 40,236, 75,146,100, + 95,154,166, 9,154,166, 19,106,107,107, 47, 2, 56, 4,224, 69, 34, 37,240,196, 98,241,106, 7, 7,135,137,139, 23, 47,174,116, +116,116,236, 48,127,254,252,219, 85, 85, 85,191, 86, 84, 84, 44, 65, 43,114,212,253,205,104,239,234,234,186,159,201,100, 50, 10, + 11, 11,251, 2,128,151,151, 87,130, 86,171, 53, 74, 36,146, 55, 0, 60,108, 37,159, 0, 64,119,161, 80, 24, 41, 20, 10,123, 27, +141,198,160,186,252,140,233,181,181,181,137, 58,157,238, 14,128, 27, 0, 20,255, 67,247,136, 13, 69, 81,123,235,250,186, 63, 0, +249,203, 54, 8,208, 36,130,210, 82, 51, 58, 52, 8,175,144,192,230, 15, 38,224,221,196,177, 22, 11,173,126,125,220,134, 13, 31, +222,159, 4, 0,173,254,244,176,139,151, 75,142,255,197,213, 9, 24, 61,122,244,245,189,123,247,218,107, 52, 26,204,156, 57,115, +127,124,124,252,143, 50,153,108,113,139, 3,135,208,126,254,215, 27,206,241, 9,130, 4, 0,177,201,100, 20, 63,121,242,208, 63, + 45,229,250,160,212,212,127,173, 81,101, 92,188, 97, 34,152,179,116,232,149, 97, 73, 33,130,124, 17, 51,108,204,168,161, 43, 87, + 46,199,196,215, 39,182, 77, 77, 85,243, 60, 68,185,236, 42,149,192,207,209, 89, 60,124,229,170,195,196,213, 43,199,134,239,221, +181,226,226,219,111, 59,246,123, 9,197, 22,177,140,205,246,214, 27,141,131, 72,160,132,178,177,201, 5,139,165, 4, 0,210,104, +100,104,101,178,246, 74,138,154,244, 5,112,235,115,131,225,174,165,156,171, 40,170,187,173,159, 95,239,215,143, 29,131,208,203, +139,162, 56, 28, 18, 0, 12, 26,141, 87,109, 97,161,219,129,225,195,187, 45,207,202,186,180, 28,184,105,229,252,175,112, 90,209, + 26,161, 69,146,164,231,147, 39, 79,196, 2,129,224,233, 96, 76,211, 48, 26,141, 48, 26,141, 13,201,139,105,154,110,248,107, 48, + 24, 16, 24, 24,104,209,140, 22, 64, 63, 0, 83, 95,123,237,181,177,235,215,175,103,134,133,133,213,167, 12,233,245,233,167,159, +254,144,156,156,124, 4,192,110, 60, 13,222,104,233,140,119,160, 64, 32,216,247,245,215, 95,139,250,247,239, 79,185,187,187,131, + 32, 8,148,150,150,118,143,143,143,143,156, 63,127,254,108,133, 66, 49, 9,192,217, 86,180, 79,168,141,141,205,225, 81,163, 70, +121,246,233,211,135, 27, 28, 28, 12,163,209,136,187,119,239,190,125,231,206,157, 9, 71,142, 28, 89, 38,151,203,199,194,242,124, +109,132, 80, 40,156, 34, 18,137, 86, 47, 93,186,212, 97,210,164, 73,236,148,148,148,106, 95, 95, 95,226,234,213,171,206, 7, 15, + 30,156,189,118,237,218,113, 50,153,108, 73,109,109,237, 47,176, 32,135,162,141,141,205, 29,146, 36, 61, 45, 17,194, 0, 90, 35, +134, 59,249,248,248, 28,188,114,229,138, 79,126,126,190,113,228,200,145,123, 0,224,226,197,139, 97,122,189,158, 24, 48, 96,192, +233,162,162,162,241, 0, 44, 29, 36,195, 29, 28, 28,142, 79,156, 56,209,161,125,251,246,124, 31, 31, 31, 66, 32, 16,128,193, 96, + 64, 42,149,186,167,164,164, 68,223,188,121, 83, 21, 31, 31, 95,165,209,104,134, 3,184,223,138,235,212, 67, 44, 22, 79,102, 50, +153,161, 6,131,193, 3, 0, 40,138,122,162,215,235, 83, 36, 18,201, 94, 0,215, 95,244, 6,113,113,113,249,126,245,234,213, 78, + 18,137,132, 94,187,118,237,247,114,185,124,202,203, 58, 24,236,255,245, 16,238,220,190, 9, 60, 77,155, 67, 52,209,255, 8, 0, +172,121,243, 22, 32,178, 75, 55,188, 49,113,156, 89,206, 33, 81,158, 95, 51,217, 44, 71,181, 90,125, 93,170,212, 28, 18,240,185, +227, 39, 78,136,201, 6,128,211,103, 46,141,239,218,213, 62,193,150,207, 25,199,229,114,123,232,181,186,202, 83, 23,138, 62,106, +141,168,242,240,240, 56,107,111,111,207,175,170,170, 42, 45, 47, 47,223, 60,108,216,176, 85,187,119,239,182,127,244,232, 17, 10, + 11, 11, 49,119,238, 92, 97, 81, 81,209,123,247,239,223,255,151, 86,171,109,214,178, 37,151, 87,109,250,116,209,136,165,182,182, + 78, 12, 1, 95, 4, 27, 91, 7,248,182,239,136,238, 61,134, 97,240,208,105,200,201, 78,238,190,123,215,202,228, 39, 79,226,191, + 20, 58,180, 91, 85, 83,227,211,236,184, 20, 28,128, 62,195, 71, 61, 21, 89, 75,151, 46, 71, 86, 70,134, 60, 63,143,124,255,228, + 49,138, 63, 56, 42,144, 99,208,150,230, 95,189,114,204,167,103,175,145, 0, 16,185,119,215,138,139,239,191, 97, 31,245,253,254, +234,151, 69,196, 19, 43,153,204, 80, 24, 12, 1,142,110,110, 7,212, 38, 19,173,151, 74,189, 76, 74,165, 27, 0, 24,152, 76,173, + 64, 40,124,224,238,231,151,152,149,148,212,251, 11,138,234,245,121,203, 9,202,235, 57,167, 12,220,176, 65, 28, 49,123, 54,171, + 54, 47, 79,151,187,101,139,178, 44, 49,209, 72,113, 56,180,215,160, 65,132,115,223,190,220,217,233,233,172,107,107,215,246,102, +174, 88,225,187, 68,167,219,103,229,252,143,114,254,127, 71,189, 19,124,227,221,135,219, 90, 20, 90, 4, 65, 64, 32, 16,224,192, +129, 3, 96, 50,153,160, 40, 10, 76, 38,179,217,247,222,222,222,150, 20,100,180,171,171,235, 15, 63,254,248,163,203,192,129, 3, +193,229,114, 27,190, 96, 48, 24,232,223,191, 63,162,163,163,153,197,197,197, 19, 14, 28, 56, 48, 97,205,154, 53,101, 53, 53, 53, +115, 80,151, 24,186, 5,244,237,208,161, 67,236,185,115,231,120,106,181, 26,137,137,137,168,174,174, 6,155,205,134,167,167, 39, + 6, 12, 24, 64,101,100,100, 56,244,239,223, 63, 54, 43, 43, 43, 6, 64,130, 5,101,141, 20,139,197,151, 15, 29, 58,196,237,216, +177, 35,145,147,147,131,136,136, 8, 0,128, 84, 42,197,200,145, 35,185,147, 38, 77,106, 63, 97,194,132, 27, 18,137,164, 15,128, + 59,102,248, 58,187,186,186,254, 50,106,212, 40,247, 53,107,214,136,108,108,108,144,159,159, 95,226,234,234,234, 95,223,222, 19, + 38, 76, 96, 15, 27, 54,204,109,221,186,117,155, 14, 31, 62,252,145, 68, 34,153, 2, 32,169, 69,213, 90, 39,136,249,124, 62,202, +202,202,176,127,255,126,188,247,222,123, 96, 48, 24,144, 72, 36, 56,120,240, 32,222,127,255,253,122, 65, 99,145, 24,230,243,249, +209,126,126,126, 63, 95,188,120,209,211,206,206, 14,238,238,238,228,231,159,127, 30,234,235,235,203,107,219,182, 45,163,164,164, + 4,177,177,177,190,147, 39, 79, 62, 94, 80, 80,240,182, 70,163, 49,187,164,230,226,226,178,243,228,201,147,222,169,169,169,216, +178,101, 11,170,170,170,192,102,179, 97,103,103, 7, 87, 87, 87,248,251,251, 19,139, 22, 45,226, 15, 27, 54,140, 63,103,206,156, +157, 90,173,182,147, 5,215,168,163, 88, 44,222,218,183,111, 95,223, 21, 43, 86,216,185,186,186,162,126, 98, 32,149, 74, 61,243, +243,243,187, 47, 93,186,116,236,157, 59,119, 30, 73, 36,146, 89, 0,238,181,242,198,233, 20, 28, 28, 28, 51,114,228, 72, 70, 73, + 73, 9,246,238,221, 27, 35,151,203, 59,181, 66, 92,254,163,112,231,246, 77,204,124,119,110,173,187,151, 23,235,220,217,159, 71, + 31, 62, 26,112,219,142,247, 52, 33,117,141, 10,186,177,163,178,186, 12, 24, 56,141, 53,100,232,200,218,109, 63,109, 18, 90, 34, +180,152,108,150,227,254,125,223, 22, 92,185,122, 39,244,124,252,205, 65,163,135, 15,167, 89, 44, 59, 95, 0,248,104,254, 60,102, +236,137, 19,187,250, 71,119, 43,238,213, 51,178,224,141, 73, 11,188, 91, 81,220,128,128,128,128, 75,201,201,201, 46, 28, 14, 7, + 85, 85, 85,142,219,182,109,251,182,103,207,158,100,110,110, 46, 50, 50, 50,144,151,151, 7,169, 84,138,254,253,251, 11,147,146, +146, 54, 3,104, 86,104,233,200,126,171,221,219,234,191,115,228, 9,124,116, 70,153,152,214,151, 4,159, 63,121, 62,252,183,189, +170, 8, 23,183, 64,255,169,111, 45,195,202, 85, 71,152,191,238,255,106,233,133,248,223, 0,210,167,249,140, 0, 52,122,124,186, +100, 49,100,114, 13, 38, 77,156,129,201, 19,103, 56,210,208,186,209, 70,181, 64,171,170,182,179, 97,165,199,253,184,227,219, 81, + 0, 60, 27,137,173, 11, 47,139,216, 90,201, 98,249,192,100,242,245, 31, 57,242, 88,238,153, 51,237,104,157,206,137,193,102, 23, +217, 56, 56,148, 25, 52, 26, 90,175,211,177, 84, 42,149, 71,110,106,170, 91,207, 69,139, 46, 92, 93,187,182,207, 23, 12, 70,151, +207,141,198,219,205,114, 82, 84,183,152, 31,126,112, 14,157, 62,157,115,111,197, 10, 69, 69, 98,162,202,111,200,144,234,136,119, +222,209, 0,128, 60, 47,143,149,181,108, 25,223,185,119,111,222, 43, 11, 23,218, 27,181, 90,215,149, 43, 87,118, 93,250, 52,121, +121,171, 56,189,199,143, 55, 46,221,181,171, 75,226,130, 5,175, 17,122, 61, 99,208, 43,175,220, 93,187,119,239,147, 63,195,249, + 87,150,179,248,242,101, 77,149,175, 47, 34, 70,142,172,244, 22,139, 53,127,101,221,255, 76, 57,173,104, 64,189,175,214,204,198, + 51, 84,196,197,197,245, 1,112, 9,192,138,152,152,152,229, 0, 96,107,107, 91, 86, 83, 83, 35,142,141,141, 53, 43,178,152, 76, + 38,220,220,220,224,239,239, 47,145, 72, 36, 46, 45, 20,160,208,100, 50,121,210, 52,221, 96,125,105, 14, 26,141, 6,217,217,217, + 8, 15, 15, 47,194,211, 68,180,205, 26,117,248,124,126,110, 70, 70,134, 83, 90, 90, 26,238,220,185, 3, 95, 95, 95,216,219,219, +131,201,100, 66,175,215, 67, 38,147,161, 67,135, 14,224,112, 56,232,220,185,115,133, 66,161,240, 53,179, 4,196, 17, 8, 4,217, +151, 47, 95,246,138,136,136,192,173, 91,183,224,229,229, 5, 87, 87, 87, 0, 64, 94, 94, 30,174, 94,189,138, 33, 67,134, 32, 57, + 57, 25, 99,198,140, 41, 84, 40, 20,254, 0, 52,205, 17, 58, 56, 56,148, 92,188,120,177, 40, 44, 44, 76,173, 80, 40,200,178,178, + 50,102, 98, 98,162, 65, 46,151, 11,165, 82, 41,179,166,166,134, 41,147,201, 40,133, 66,193, 36, 73,146,165, 82,169,152, 23, 46, + 92, 96,232,116,186, 22, 3,100,214, 95,167, 19, 39, 78, 32, 44, 44, 12,177,177,177,248,240,195, 15,113,237,218, 53,120,121,121, +225,208,161, 67, 88,184,112, 33, 50, 51, 51,225,228,228,132,224,224, 96,115,215, 8,237,219,183,207,121,240,224, 65,123, 22,139, + 85,159,215,177, 62, 95, 30,202,203,203,241,240,225, 67, 60,121,242, 4,126,126,126,152, 56,113,226,195, 39, 79,158,248,153,235, +121, 30, 30, 30,229,169,169,169, 78,225,225,225, 40, 43, 43,131,157,157, 29,108,109,109, 97,103,103,215,240,222,215,215, 23, 11, + 22, 44,128,171,171,171, 68,173, 86,187,152, 19, 65, 97, 97, 97,103, 47, 92,184,224, 36, 18,137, 80, 90, 90, 10,153, 76, 6,138, +162,192,231,243,225,228,228,212, 32,228,179,179,179, 49,116,232,208,138,220,220,220,129,173, 16, 73,164,139,139, 75,198,253,251, +247,253,105,154, 70, 65, 65, 1, 50, 51, 51,241,238,187,239,102,171,213,234, 64,188, 68, 57,251, 26,249, 93,177,166,188, 53,147, + 53,106, 68, 15,109,122,106, 28,193, 49,101,162, 83,168, 72, 10, 0,119, 83,100,182, 26,178, 3,130, 66, 98,232,163,199,175,179, +127,217,189,141, 9, 19, 92, 64, 32, 51, 61, 27, 95, 52,199, 61,160,175,219,244,121,243,222, 14,125,173,103, 31, 82,174, 80,136, + 55,111,222,208, 57, 55, 55, 93, 12, 0,190,190, 65,146,217,179,231, 39,217, 8, 4,146, 75, 87, 47,155, 54,110,220,153,114, 46, +161,100,135, 5, 69,246,245,247,247,255,215,137, 19, 39,156,196, 98, 49,108,109,109,161, 80, 40,160,211,233,144,150,150,166, 62, +112,224,128, 94, 36, 18,217,148,150,150,162,166,166, 6, 4, 65,224,196,137, 19, 5, 0,218, 60, 79, 84,239,163, 5, 0,239, 14, + 14, 98, 6,247,243,183,103,113, 12, 60, 30, 51,203, 13,132,145, 67,208, 66,151,211,103,239,134,159, 62,127,235,141, 81,163, 63, +116,238,213,103, 20,150,126, 54, 86, 95, 92, 92, 16,161, 67,175,140,166,124,180, 2,253,208,111,228,152, 81,227, 86,174, 92,142, +229, 75, 87, 32,238,196, 49,169, 80, 64,106, 68,118, 76,219,222,221, 95, 85, 47,120,111, 68, 97,109,109,177,215,202,117, 7, 38, + 14, 29,177,192,179,103,175,145,184,122,229, 24,246,238, 90,113,135,224,209,255,232,101,196,101, 0,139,164,168,105,238, 62, 62, +251, 36,197,197, 30,124,161,144, 57, 55, 62, 94,108, 52, 26,111,143, 91,184, 80,126,244,194,133, 6, 43,233,231, 36,233,206, 96, + 48,220,253,135, 14,189,159, 19, 23, 55,141, 99, 48,196,126, 2,148, 63,207,185, 28,176,183,243,245,157,245, 65,118, 54,235,222, +242,229,181,134,226,226,234,200,249,243, 43,154, 58,127,209,249,243, 2,182,187,187,200,126,248,112,135, 77,109,218,208,122,137, +100,107, 83, 62, 70, 77,113,198, 11,133,118,191,157, 62, 29, 69, 51,153,125, 62,254,228, 19, 94, 76, 76, 12,100, 50, 25,142, 28, + 57,130,173, 91,182,104,220,220,220, 30,184,167,164, 36,135,202,100,159, 89,202, 25, 57,127,126,133,209,104, 36,198, 45, 92,216, + 63, 53, 47,175, 95,169, 68,210, 22, 0,220, 28, 28, 10, 35,125,125,239,236,140,139,203,252,222,199,199,100,105, 57,183,159, 57, +227,114, 56, 63,127,186,131,131, 3,175, 76, 34,161, 56,108,118,101,247,224,224, 67, 63, 45, 89,114,201,112,255, 62,139,235,233, + 41,178,141,137,105,117,221, 35,231,207,175,168,146,203,169, 15, 86,173,122,245,113, 89, 89,219, 90,141,198,175, 70, 46,119, 53, +234,245,164,136,207,175,108,215,161,131, 68,149,152, 88,210, 78,169,156,187, 3,144,252, 93,253,167, 41, 45,242, 15,194,243,113, +180,254,144,235,240, 82, 76, 76,204, 31,118,215,208, 52,109,145, 53,139,201,100, 62,179, 76,213, 2, 88, 4, 65, 32, 41, 41, 9, +142,142,142,112,117,117, 5,135,243,108,242,193,242,242,114, 92,187,118, 13,233,233,233,232,216,177, 99,253, 50, 70,243,138,136, +195,153,183,110,221, 58, 59,173, 86,139, 59,119,238, 32, 50, 50, 18, 28, 14, 7, 44, 22,235, 25, 17, 40,145, 72, 16, 18, 18,130, +143, 63,254,216,118,205,154, 53,243, 52, 26, 77,179, 51, 82,138,162,230,204,152, 49, 67, 92,111,193, 42, 44, 44, 68,231,206,157, + 27,190,119,118,118,198,221,187,119, 17, 25, 25, 9, 79, 79, 79,140, 29, 59, 86,188,119,239,222, 57, 6,131, 97,125,115,156,108, + 54,155, 12, 11, 11,235, 2, 0, 2,129, 0, 36, 73,102,137, 68, 34,103, 23, 23, 23,129, 72, 36,250, 67, 29,119,237,218, 85, 67, +146,164,222,172, 26, 32, 73,148,150,150, 34, 52, 52, 20, 82,233,211, 12, 46, 10,133, 2,126,126,126,144,201,100, 13,162,213,221, +221, 29, 42, 85,203,174, 95,225,225,225,203, 3, 3, 3, 7, 8, 4, 2, 14,147,201,196,189,123,247, 16, 17, 17,129, 3, 7, 14, +192,219,219, 27,124, 62, 31,217,217,217, 8, 11, 11,195,229,203,151,225,236,236,140,144,144, 16,142, 88, 44,190, 82, 85, 85,149, +240,248,241,227,229, 45,148,147, 20, 10,133,184,124,249, 50,118,238,220,137,188,188, 60, 20, 23, 23,195,198,198, 6,157, 58,117, + 66,112,112, 48,122,244,232,129,236,236,108, 16,230, 59,147,171,191,191,127,220,173, 91,183,156,104,154,198,222,189,123, 81, 91, + 91, 11,173, 86, 11,146, 36,193,229,114, 97,111,111,143,126,253,250,193,217,217, 25,254,254,254, 56,120,240,160,211,224,193,131, + 79, 73, 36,146, 78, 0, 74,205,181,171,189,189,253,220,101,203,150,121,137,197, 98,228,231,231, 67, 42,149,194,197,197, 5,175, +189,246,154, 71,124,124,252, 92,189, 94,191,225,101, 17, 90,141, 28,223,137,115,103,127, 30,237,223,174, 58,172, 99, 7,190, 87, +108,156,139,215,129, 56, 73, 8, 0,132, 6,185,164,142,142,225, 23,222, 75,141, 43, 60,119,246,216,157,244, 44,196,194,130,165, +109,169, 82,115,232,124,252,205, 65, 17, 29, 59,155,214,125,181,112,232,123,239, 78,231,136, 93,166,161,172,224, 24,226, 47, 38, +121, 47,252,112,134,243,250,111,182,159, 62, 31,127,147,148, 42, 53,159, 89,102,202,242,254,126,247, 79, 61,156,228, 21,135,145, +147,193, 6,207, 38, 20,190,190, 1,144,201,100,224,114,185,220,137, 19, 39, 26, 23, 47, 94,172, 20,137, 68,124,130, 32,144,144, +144, 32, 1, 48,208, 28,175, 90,108, 79, 27,117,122, 3,205,102,152,104,194, 70, 69, 24,171,216, 41,105,143, 48, 32,186,111, 89, +207,110,161,107, 22,175,252,230, 83,255,128, 8,231,183,167,175, 96,174, 90,254,198, 22, 16,232,213, 20, 79, 70, 14, 46, 18,135, +142,242, 0, 12, 93,249,197,114,228,230,102,219,207,156, 90,179,130,226,240,220, 3,219,188,106,179,101,103,194, 32, 63, 63,159, +182, 11,230,140, 61,249,237, 15,223, 14,109,108,217,218,189,107,217,113, 0, 81,150,180,237,255, 34, 72,138,234, 64, 18, 68,161, + 76,169,100,208, 58,157,211,220,248,120,213,185, 27, 55, 46,220,159, 57,211, 38,156,197, 10, 8,103,177,192,208,233, 42,151, 0, + 21, 95,152, 76,197,203, 40, 74,244,232,248,113,119,138,205, 78, 86,155, 76, 97, 48,153,154,138,159, 20, 62, 57, 46, 14,181, 5, + 5,250,170, 43, 87,212, 81, 63,252, 80,225, 53,112,224, 6,173, 78,231, 84, 63, 84,144, 4, 1,162,222,117,194,100, 34,168,143, + 63, 38,105,138,130,222,222,126, 42,170,171, 3,204,113,126, 88, 82, 50,250,141,233,211,135, 30, 63,115, 6, 62, 62, 62, 13,207, + 51, 59, 59, 59, 44, 92,184, 16,243,231,207,231,220,189,123,183,235,225,195,135,187,174,255,250,107, 23, 0,163, 45, 41,231,185, + 27, 55,236,223, 89,185,114, 73,199,200, 72,239, 61,251,247,115,218,183,111, 15, 0,120,248,240,161,255, 87,107,215,182, 9, 13, + 11, 43, 91, 51,111,222,238,212,197,139, 67, 0, 92,105,137,179, 52, 49, 81,123, 56, 63,127,250,197,132, 4,187,208,208, 80, 0, + 64,102,102,166,120,211,166, 77, 51, 66,198,142,157,180,114,246,236,207, 98,212,234, 26, 81,121, 57, 39,230,251,239,169,223,198, +141, 51,203, 89, 95, 78, 0,120,237,237,183,231,245,234,219, 55,120,244,244,233, 14,222,222,222,132, 80, 40,132, 78,167, 67,113, +113,177,125,106,106,106,251, 56,185, 92,118,244,198,141,189, 48, 26,251,255,141, 93,168, 73, 45,242, 15,179,100,253,241,190,168, +251,251, 90, 92, 92, 28, 93,167, 38, 27, 30,224, 70,163,209, 34,145, 69, 81, 20, 8,130,176, 84,108,129,166,105, 84, 84, 84, 32, + 37, 37, 5, 15, 31, 62,132, 66,161,192,163, 71,143,176,109,219, 54,124,245,213, 87,184,125,251, 54,244,122, 61,116, 58,243, 57, +104, 5, 2, 65,116,116,116, 52,117,227,198, 13,248,250,250,130,199,227,129,205,102,131,197, 98, 53,188,184, 92, 46,220,220,220, + 32,147,201, 16, 21, 21,197, 20, 8, 4,209,102,172, 68, 67,198,143, 31,207,174,255,191,182,182, 22, 12, 6,163, 65,180,212,214, +214,162,170,170, 10, 53, 53, 53, 40, 41, 41,193, 43,175,188,194,182,181,181, 29, 98,233,213, 80, 42,149,181, 18,137,196,174, 87, +175, 94,246,233,233,233,127,200,246,123,233,210, 37,181, 90,173,102,146, 36,105,145,163,253,190,125,251, 16, 27, 27,139, 11, 23, + 46,160,168,168, 8, 91,182,108,193,158, 61,123,112,226,196, 9,100,103,103,227,187,239,190,195,230,205,155,177,123,247,238, 22, +175, 81, 96, 96,224,224,189,123,247,118,235,222,189, 59,159,193, 96, 32, 51, 51, 19, 11, 22, 44, 64, 77, 77, 13,156,157,157, 1, + 0,101,101,101,216,176, 97, 3, 52, 26, 13,132, 66, 33, 60, 60, 60,184, 43, 87,174,236,233,236,236, 60,160,165, 50, 26,141, 70, + 35,131,193, 64,155, 54,109,176,116,233, 82,108,222,188, 25,103,207,158,197,161, 67,135, 48,123,246,108, 4, 7, 7, 35, 57, 57, + 25,183,111,223, 6, 77,211, 45, 62,100,184, 92,238,216, 61,123,246,136,217,108, 54, 76, 38, 19,228,114, 57, 10, 10, 10,112,243, +230, 77,245,177, 99,199,106, 79,158, 60,169,188,114,229,138,250,250,245,235, 52,128, 6,193, 25, 19, 19,227,200,102,179, 95,183, +160, 73,157, 93, 93, 93, 63,157, 49, 99, 6,183,113,159, 45, 45, 45,197,232,209,163,249, 60, 30,111, 49, 0,231,151,208,228, 77, + 31, 62, 26,112,155, 99,202, 68,108,220, 19,175,199, 69,198, 87, 23,126,244,141,195,194,143,190,113,120, 92,100,124, 53, 54,238, +137, 23,199,148,137,195, 71, 3,110, 91, 32, 4,200,126,125,220, 70,184, 56,218,109, 29, 61,124, 56,189,121,243,134,206,239,189, + 59,157,211, 38, 96, 33,184,182, 19,225,225,251, 14,162,122,123, 19,225,193, 36,119,243,230, 13,157, 71, 15, 31, 78,187, 56,218, +109,237,215,199,109, 4,204,132,157, 17, 59,114, 61,248, 28, 5,218,251, 7,227,181, 62, 29,193, 36,114,112,228,208, 78,148,148, +148,160,184,184, 24,101,101,101,130, 97,195,134,161,180,180, 84,157,144,144, 32, 81,169, 84,125, 0,100,153,171,124, 81, 81,154, + 73, 93,107,212,153,140, 76,131, 92,202, 82,206,158,123, 56,250,118, 42,235,173,210, 26,143, 97,108,142, 61,123,112,255,174,251, +119,238, 88,138,118,237, 66,209,165,235,128, 87,236,133,255, 10,110, 86,188,230, 34,238,247, 35, 71,143, 79, 28, 63,209,144,247, + 40,255, 81,128, 11, 87, 75,211,180,126,238,162,237,253,153, 2,175,240,246, 65,189,157,211,115,140,110, 75, 63,126,253,215,147, +199,191, 45,186,122,229, 24,122,246, 26, 9, 15,119,255, 62, 83,167,130,253, 79,237, 64, 4, 77,251, 50,133,194, 92,189, 84,218, +134,226,112, 10,140, 70,163,211,173, 89,179,236,116, 44,150,155, 81,167, 43, 54,234,116,197, 58, 54, 91,244, 99, 80,144, 39, 77, +211,142,118,158,158, 79,104, 54,219,219,160,211,229, 16, 36,217,174,201,217, 57,135,227, 41,108,211,134, 42, 61,119, 78,235, 59, +108, 88, 53, 0,104,117, 58,167,188,252,124,219, 50,137,196,182,180,172,204,246,113, 97,161,109,238,163, 71,182,217, 57, 57,182, + 25, 57, 57,162, 7, 41, 41,194,187, 15, 30, 8, 9, 6,195,197, 18,206,188,226,226,240,143, 63,254, 24, 60, 30, 15, 6,131,161, +169, 49, 27, 10,133, 2, 83,167, 78,133, 18,232,110, 9,167,209,104, 36,222, 89,185,114,201, 39, 75,150,180,143,141,141,229,116, +235,214, 13, 14, 14, 14,112,112,112, 64,183,110,221,112,248,200, 17,246,236, 57,115, 60, 63,221,177, 99, 42,201,225,120,153,227, +172,240,243,131,131,131, 3,175, 94,100, 1, 64,135, 14, 29,176,101,203, 22,206,153,179,103,109,191,248,249,231,111, 86, 92,191, + 30,166,121,252, 88,225, 24, 16, 64,179, 57, 28, 79, 75,219, 19, 0,228,106,117,232,134, 77,155, 28,157,156,156,136,178,178, 50, +228,228,228,224,241,227,199, 48, 24, 12,232,210,165, 11,113,232,200, 17, 91, 45,131,209,245,111,238, 66,127,208, 34,255, 32,204, + 68, 51,113,180,168,186, 7,208,101, 0, 68, 92, 92, 28, 93,191,156, 88,247,112,108, 16, 83,150, 8,173, 23, 65, 77, 77, 13,106, +106,106,176, 99,199,142, 6, 97, 84, 15,173, 86,107,137,104, 9,115,119,119,135, 84, 42, 69, 64, 64,192, 51,150, 44, 22,139, 5, +138,162,192, 98,177,192,225,112,160,209,104,224,237,237, 13,165, 82, 25,214, 18,167, 74,165,234,228,224,224,208,240,128,213,104, + 52, 13, 34,171,190,188, 90,173, 22,213,213,213,168,173,173,133, 92, 46,135, 66,161,136,176,164,190, 38,147, 9, 41, 41, 41, 15, + 59,116,232,208,137,193, 96, 64, 40, 20, 10, 20, 10, 69,131,111, 81, 85, 85, 21,126,249,229, 23,197,155,111,190,233,116,226,196, + 9,179, 9,139, 9,130,192,251,239,191, 15, 14,135, 3,165, 82,137,205,155, 55,227,131, 15, 62, 0,139,197,130, 92, 46,199,150, + 45, 91,176, 96,193, 2, 80, 20, 5,173, 86,139, 77,155, 54, 53,203,149,150,150,150,119,227,198,141,136,206,157, 59,219, 31, 61, +122,180,188,127,255,254,206, 3, 7, 14, 4,143,199,131, 74,165,130, 94,175, 71,247,238,221, 17, 24, 24, 8,137, 68,130,211,167, + 79, 87,248,251,251, 59,221,188,121,211, 84, 90, 90,250,216,140,184,166, 27, 89, 12, 97, 52, 26, 81, 86, 86,134,154,154, 26,148, +151,151,163,184,184, 24, 69, 69, 69,160, 40, 10,102,116, 22, 28, 29, 29,199,132,134,134, 50, 0,128,199,227,161, 83,167, 78, 88, +178,100,137, 65,165, 82,141, 7,112,186,238,176,193,219,183,111, 63,122,245,234, 85,202,221,221, 29, 25, 25, 25,112,118,118,166, +184, 92,238,235, 90,173,182, 69,107,148,171,171,235,174,223,127,255,221,161, 94, 92,215,183,179, 82,249,244,114,140, 30, 61,218, + 97,207,158, 61,187, 12, 6,195, 16,188,100,176,227,129,213, 41, 84, 36, 61, 16, 39, 9, 89,248,209, 55, 84, 96,232,211,201,235, +204, 89,160,214,127,253, 97,200,164, 17,162,147,118, 60, 25,203, 28,207,224,104,175, 31,135, 15,239, 79, 78,156, 16,147,205, 98, +217,249,110,221,182, 66, 44,118,153,214, 72,134,137,224,232, 36,130,111, 27, 54,113,248,100,186,120,209,226, 47, 52,251,246,124, +155,251,235,111,113,131,216,204,243, 3, 78,199, 23,206,110,142, 59,235, 97,205, 9,165,134, 27, 36,171,188, 79, 56,184,188,138, + 78, 29, 59, 64,236, 92,141,237,187, 14,192,167, 93, 23,104, 52, 26,136, 68, 34,190,209,104,212, 49, 24,140,125,150,136, 44, 0, +184,112,161,198, 20, 18, 82,163,101,200, 77,134,247, 62, 88, 63,170,255,224,225,193,253,250, 69,155,206,157, 63,167,123, 53, 66, + 87, 50,120, 96,167,178, 51,231,127,204, 46, 41,126,228, 31, 18,214, 19,105,169, 9,131,104, 26, 41, 4,209,180,232, 76,205,193, + 25,181, 41, 45,225,192,129,153, 38,149, 41,153,183,106,245,131,193, 67,135, 78, 9,237,221,171,183,233,124,252, 69, 45, 27, 21, +233,162,158, 61,158,188, 55,125,240,209,159,247,109, 26,112,230,244, 46, 63,169,236,113,220,238,221,205,187, 32,252,207, 43,117, +130,112,182, 17, 8,202, 43,229,242,142, 99, 86,172,144,141, 91,184,240,108, 56, 69, 5, 27,117,186, 71, 43, 0, 21, 77,211,132, +201, 96, 88,252, 96,255,126,198,114,130, 88,180, 2, 48,173,102, 48,152, 69, 38,147,210,131, 36,249,203, 0,106,197,115, 59,185, +141, 6,131, 11,197,225,144,229, 9, 9,134,176,105,211, 52,245,247, 35,159,207,199,241,227,199,193,102,179, 27, 94, 44, 22,171, +225,189,139,139, 11,136,186,109,164,127,152,248, 53,193, 9, 0, 37, 37, 37, 40, 45, 45,133,173,173, 45,156,157,157, 81, 90, 90, +138,235,215,175, 35, 43, 43, 11, 76, 38, 19,131, 6, 13, 2,217,140,111,243,243,156,227, 22, 46,236, 31, 20, 22,230, 61,107,214, + 44,242,249,231,163, 78,167, 67, 85, 85, 21, 70,140, 24, 65,158, 62,125,218,245, 76, 65,193,112, 0,251, 90,226,140, 24, 58,180, +178,236,240,225, 38,207,221,185,115,103,226,218,181,107,156, 65, 3, 7,206,255,112,245,234, 31,191,223,179,167,208,104, 48,184, +182,166,238, 36, 73,146, 4, 65,192,203,203, 11, 85, 85, 85,168,173,125,186,130, 45, 20, 10, 97,111,111, 15,189, 94, 15, 19, 77, + 51,255,206,254,211,156, 22,249,135, 96, 91, 35,193,245,140,101,139,170, 91, 23,173, 31, 40, 94,107,252, 96, 49,153, 76, 22,137, + 44, 38,147,105,214,231,202, 18, 43,215,243,176, 68,104,213,151,149,203,229, 62, 99,201,170, 23, 88,245,229, 36, 73, 18, 12, 6, +195,236, 67,188, 78, 12, 49,228,114, 57,142, 28, 57,130, 62,125,250, 52, 44, 75, 73,165, 82,212,212,212, 64, 42,149, 66,173, 86, + 35, 47, 47, 15, 23, 46, 92,128,159,159, 31, 96, 97,240,215,220,220,220, 59, 62, 62, 62,145,245, 15,241,190,125,251,122,238,222, +189,187,120,200,144, 33,238, 52, 77,227,179,207, 62,171,232,222,189,187, 83,227,135,188, 57, 48, 24, 12, 92,191,126, 29,126,126, +126,160,105, 26, 44, 22, 11,153,153,153, 16,139,197, 48,153, 76,160, 40, 10,229,229,229,176,177,105, 57, 70, 98, 74, 74,202, 91, +111,191,253,118,177,173,173,109,120,101,101,101, 9,135,195,233,149,152,152,232,165,211,233, 32, 18,137, 32, 18,137,112,234,212, + 41,216,217,217, 97,222,188,121, 5, 42,149,234,186, 64, 32,112, 81,169, 84,247, 75, 75, 75, 63,107,205,245, 54, 24, 12, 80, 40, + 20,168,174,174, 70, 85, 85, 21,100, 50, 25,212,106,181,217, 50, 54,133, 94,189,122, 33, 46, 46,142,241,229,151, 95,254,156,155, +155, 11, 0,240,245,245,197,188,121,243, 24, 30, 30, 30,200,203,203,195,157, 59,119,160,211,233, 64,211,116,139, 55, 47, 69, 81, +125,223,124,243,205,158,222,222,222,132, 78,167,131,201,100,130, 70,163, 65,253,251,130,130, 2, 4, 5, 5,145,109,218,180,121, + 37, 55, 55,183, 47, 44,219, 88, 97, 5,128,178,130, 99,240, 96,138, 1, 82, 4, 90,117, 12,149, 21, 47, 22,197, 69, 34,145,172, +254,248,243,107,211,190, 95,167,115, 41, 42, 1, 58,132,142,132,127,112, 20,222,154,108,192,151, 95, 31,129,119,155, 14,120,252, +248, 49,250,246,237,203, 42, 46, 46,126,187,182,182,118,161,165,220,231,207,223, 48,158, 59,117,122,236,184,215,167, 68, 70, 71, + 15, 49,156, 61,123, 10, 41,247,207,166,190,253,250, 24, 9,109,170, 37, 28,236,120,201,153, 25,183,253,195, 59,189, 6,173,193, +216, 11, 88,190, 14, 88, 78, 55,127,191, 67,123,242,164, 27,121,242,216,174,201, 19, 39, 77,237, 24, 21, 53, 64,127,246,252,239, +184,243,175,243,247,190, 89, 55,227,242,151,155, 14,246,237, 63,104, 76,136,179,203,245, 83,161, 1,154,233, 94,142,182, 15,183, +239,174,250, 39, 95,102,138,197,229, 26, 0,144,118,109,218,120, 30,189,112, 33,191, 19,147,201, 16, 1, 70,154,166, 59, 0,112, + 34, 41,234,211, 19,211,167, 71, 4,213, 61, 72, 13,128, 41, 8, 32,165,128, 86, 0,176,209, 76,200, 28,138,203, 53,161,110, 92, + 36, 9, 2, 52, 77, 63, 35,178,158, 23, 90, 36, 73,154, 53, 0, 52,230,108,252, 44,170,159, 80,111,221,186, 21, 28, 14, 7,108, + 54, 27, 76, 38,211,172,251, 69, 99,206,212,188,188,126,191,236,219,199,105, 74,100, 85, 86, 86,162,178,178, 18,181,181,181,152, + 48, 97, 2,107,197,237,219,157, 81,231,250,209, 28,167,183,155,155, 70,192,227,149,165,165,165,185, 7, 7, 7, 63, 83, 94,153, + 76, 6, 30,143,135,125,251,247,179, 98,134, 14,125, 55,234,212,169,111, 96, 38,254, 85, 83,117, 39, 8, 2, 98,177, 24,246,246, +246, 32, 8, 2, 6,131, 1,165,165,165, 72, 77, 77,197,237,175,151, 40,128, 0, 0, 32, 0, 73, 68, 65, 84,219,183,193, 32, 8, +195,223,217,121,154,210, 34,255, 64,171,214, 31,150, 15,235, 45, 90, 68,115,214, 23, 75,133, 22,131,193,120, 97,171, 86,115,176, +100,233,144,207,231, 63, 40, 46, 46,126,213,195,195, 3, 6,131,161, 65,104, 53,182,196,213, 91,201,120, 60, 30,238,222,189, 11, + 62,159,255, 64,173, 86,183,200, 73,211,244, 43, 93,187,118, 69,108,108, 44, 18, 18, 18,240,232,209, 35, 40,149, 74,104, 52, 26, +168, 84, 42,164,166,166,194,100, 50, 33, 52, 52, 20, 2,129, 0,124, 62,255, 65,189,229,171, 57, 40, 20,138, 18, 38,147,217,129, +199,227, 53,124,230,230,230,134,202,202, 74,147, 94,175,199, 47,191,252, 34,115,117,117, 21,240,120, 60,139,133, 43, 65, 16,144, + 72, 36,240,244,244,108,240,209,146,203,229, 16,139,197,245,194, 2, 26,141, 6, 54, 54, 54,160,105,218,220, 53, 82,231,228,228, +124,216,232,255, 46,227,198,141,251,245,192,129, 3,237,226,227,227,113,243,230, 77, 56, 59, 59, 99,205,154, 53,143,242,243,243, + 39, 2,184, 45,145,252,181,126,145,150,244,161,202,202,202, 35, 15, 30, 60,120,165,107,215,174, 13,163, 68,223,190,125,137,190, +125,251, 58, 53, 54,245,151,151,151,227,214,173, 91,136,143,143, 7, 65, 16,200,206,206, 54,170, 84,170, 95, 91,160,102,121,120, +120,236, 94,178,100,137,208, 96, 48, 52,244,109, 30,143, 7, 46,151, 11, 22,139, 5, 6,131,129,252,252,124,140, 24, 49,194,246, +135, 31,126,216,165,209,104,218, 3,208,225, 37, 65,141, 10,186,187, 41, 50,219,208, 32,151,212,109, 91,191,124,117,230,172,167, + 99,196,182,173, 95, 26, 66,131,196,169,119, 83,202,108, 35,197,230,235,123, 58,190,240, 61,173,254,244,176,211,103, 46,141,255, +104,254, 60,166,175,111,144, 36,254, 98,146,119,148,225, 11,194,209, 73,132,202, 10, 25,242, 11,202,144,251, 88, 75,251,250, 6, + 73,238,220,122,192,249,122,195, 70,127,133, 82,125,240,226,229,146,223,205,208,171,175, 92,127, 52,242,155,239, 56,151,167,188, +221,133,205,227,185,163,170,226, 1,188,189,157, 49, 34, 38, 28, 59,247, 92,135,173,173, 3, 92, 92, 92, 64,146,164,192,210,186, + 87, 84, 84, 16, 71,126,187, 50,237,205,169, 51,186, 15, 28, 48,212,112,230,236, 73, 42,225,220,137,235,187,182,125,122,148,102, + 40,248, 4, 45,231,181,245,113,189,255, 48,231,238,196,126,209, 19,192, 99,217,248, 1,129, 77,118,216,134, 13, 6, 52, 10, 98, + 15, 44,231,190, 57,117,102,143,129, 3,135, 27,206,158, 61,134,179,167,246,220, 88,182,172,237,169, 71, 79,246,179,254,117,187, +136, 59,114,236,236,234,184,211,233,218, 49,195,124,178,220, 5,157, 84,192,163,127,108,255, 33, 9, 66, 86, 81, 94, 46, 98, 50, +153,170, 93,111,188,145, 13, 0,122,138,170,148, 51, 24,206, 4, 65,100, 2,200, 92, 13, 56,129,205,150,142, 51, 24,140, 11,189, +189, 89, 84, 73, 9,163,218,104, 52, 50, 0,246, 71,127,204,191, 8, 6, 69,149, 25, 52, 26, 47,207,129, 3, 25,202,199,143,153, + 66, 23, 23, 3, 0,232,245,122,179, 66, 11,205,108, 90,121,158,211,210,250, 41,149, 74,152,154, 17,130,207,115,150, 74, 36,109, +235, 38,225, 13,208,235,245, 13, 34,171,178,178, 18, 53, 53, 53, 16, 8, 4, 40,215,104, 92, 44,225, 28,208,173,219, 47, 43,150, + 47, 95,120,248,200, 17, 86, 99,145, 85,255, 98, 50,153,248,106,221, 58,214, 7, 31,125, 52,251, 93,138,154,139, 38,150, 65,155, +107,207,250, 73, 59,131,193, 0, 69, 81,120,252,248, 49, 10, 10, 10,240,248,241, 99, 60,126,252, 24, 60, 30, 15,244,223,188, 9, +232, 31,236,159,133, 70, 75,133, 51,159,183,114,181, 24,222,161, 53,206,240,150, 10, 3,163,209,248,151, 10, 45,133, 66, 17,127, +225,194,133,110, 35, 71,142,164,110,220,184, 1, 87, 87,215, 6,161, 85,255,183,126, 57,138,207,231,227,232,209,163, 58,133, 66, + 17,111,230,102,186,112,234,212,169,200,165, 75,151, 50,223,122,235, 45,164,165,165, 97,214,172, 89,168,169,169,129, 76, 38, 67, +101,101, 37,148, 74, 37,186,117,235, 6, 46,151,139,251,247,239,235,149, 74,229, 5,115, 75,103, 18,137,164,214,217,217,217,237, +249,239,198,142, 29,235,242,211, 79, 63, 41, 51, 50, 50,244,175,190,250,170,200, 82,193, 81,143,223,126,251,173,193, 82,151,149, +149,133,159,126,250, 9, 52, 77,131,166,105, 36, 37, 37, 97,253,250,245, 13,177,207, 90,137,219, 21, 21, 21, 6,189, 94, 15, 63, + 63, 63,120,120,120, 64,173, 86, 99,227,198,141, 6, 0,183,255, 91,189, 89,173, 86, 31,158, 50,101,202, 39,201,201,201,110, 20, + 69, 61, 53,105,215,213, 79,167,211, 33, 39, 39, 7,169,169,169,200,200,200, 64, 85, 85, 85,195, 68,224,238,221,187,213,122,189, +254, 96,115,188,206,206,206,159,237,220,185,211,149,207,231, 63,211,159,235,173,161,245, 86,210,242,242,114,216,217,217, 33, 42, + 42, 74,124,225,194,133,207, 52, 26,205,210,151, 68,103, 17, 99, 71,101,117,249,224,189,145, 24, 29,195, 47,140,141,123,114,109, +253,215, 31,214, 57,195,139, 83, 71,199,120, 20,222,203,180,195,216, 81,199,186, 0, 40, 66,203,126, 90,166,139,151, 75,142,119, +237,106,159, 16,123,226,196,174,197, 31,207, 79, 90,248,225, 12,103,165,234, 33,215,183, 13,155, 0,128,220,199, 90,250,126,154, + 73,189,254,155,249, 73, 95,174,251,129, 44,171,172,153,117,235, 86,243,225, 13, 26,139, 23,146, 4,215, 55,176, 79,177,127, 64, + 79,159, 27,215,247, 65,200, 87,161, 67, 96, 23, 12, 28,240, 10, 18, 46,221, 69,105,185, 26, 37, 37, 37,208,104, 52, 45,134, 75, +200,184,127,116, 50, 77,208,222, 4, 77, 20, 16, 36,205,157, 60,101,122,175,161, 67,135,211,113,113, 39, 12,199,142,238,187,122, +112,239,119,135, 73, 22,147, 82,105,109,181, 4,161,150,130, 76, 73,171, 85, 60,157,208, 48, 57,172,230,205,175,117,129, 93,131, + 67, 2, 93, 39, 79,153,101, 59,100,240, 8,250,212,169, 99,166,131, 7,126, 73, 56,184, 35,108,159,137,148,177, 74, 10,149, 28, +169, 76, 47,165, 9,182, 93,173,204,164, 44,203,109,175,118, 31, 58, 86, 7, 28,254,199,118, 32,218,100,122, 76,107,181, 62, 96, + 50, 11,105,131,193, 21,122,125,213, 10,181,250,201, 23,108,118,219,101, 20,213, 25, 4, 97,210, 17,132, 2, 90,109, 46, 0, 56, + 20, 20,184,105, 69,162, 82,134, 90,221, 30, 70, 99,147, 1,144,117, 26, 77, 81,109, 97,161,155, 67,159, 62,156,156,229,203,249, + 46,221,186,169,137, 58, 31,226,150,132, 22,131,193, 0, 72,210,100, 9,167,165,245, 83,169, 84, 48, 1,250, 23,225, 52, 24, 12, +207,136,172,122,161, 85,127,191, 88,194,185,109,217,178, 27,222, 3, 7, 86, 93,186,116,201,229,181,215, 94, 35,228,114, 57,228, +114,249, 51, 98,203,221,221,157, 8, 14, 13,229,255,150,144,224,107,105,123, 90, 36,162, 73,242,111, 23, 90,255,112, 52,155, 72, +154, 50,179,132,102,177,208,178,208,162,165,215,235,245, 16,139,197,168,168,168,104,246,193, 79,146, 36,120, 60, 94,253, 26,113, +139, 59,239, 52, 26,205,198,133, 11, 23,206, 25, 60,120,176, 83,135, 14, 29, 80, 94, 94, 14, 23, 23, 23,112,185,220, 6,223,177, +122,190,164,164, 36,236,220,185, 83,166,209,104, 54,154,225,220,176,110,221,186,247, 70,143, 30,237,224,234,234, 10,123,123,123, +220,191,127, 31,246,246,246,144,201,100,200,204,204,132,141,141, 77,131,223,206,137, 19, 39,228, 26,141,102,131, 25,241, 70, 39, + 38, 38,234,108,108,108,238,151,151,151, 51,170,170,170,168,234,234,106, 74, 38,147, 49,165, 82, 41,243,204,153, 51, 78,182,182, +182,202,139, 23, 47,150,123,123,123, 51, 30, 61,122,196,208,235,245,102,213, 43, 65, 16,152, 59,119, 46, 88, 44, 22, 52, 26, 13, + 54,110,220,136,133, 11, 23, 54,248,100,173, 91,183, 14, 75,150, 44,105, 16,206,219,183,111,111,221,192, 73,211,208,233,116,208, +235,245, 22,111, 80,248, 83, 51, 98,203, 4,123,105,118,118,118, 76,215,174, 93,207, 29, 58,116,200,177, 46, 38, 25,202,202,202, + 80, 86, 86,134,242,242,114,212,214,214,194, 96, 48,192,195,195, 3,101,101,101, 56,118,236,152, 84, 46,151, 15, 68, 11, 59, 14, + 25, 12,198,148, 94,189,122, 81,207,151,161,126,150, 87, 47,222, 57, 28, 14,138,139,139,209,183,111, 95,246,165, 75,151,166, 0, +248, 71, 11,173,198,225, 29, 6, 12,156,198, 10, 10,233,161,189,151, 26, 87, 24,232, 83, 86, 56,105,132,232, 36, 0,220, 77, 41, +179,189,151,105,135,160,144, 24,122,192, 64,251,200,178,210,109, 97, 0,116, 45,165,235, 1, 0, 91, 62,103, 92,255,232,110,197, + 54, 2, 1,185,254,155,237,167, 55,111,222,208,249,240,201,127,135,119, 88,255,205,211,240, 14,253,163,187,153, 50,210, 51,198, + 1,216, 97,169,120,137,137, 25,150,188,115,247, 78,100,164, 94,116,255,100,110, 56,187,170, 76, 15,158,208, 11,145,157, 92,176, +109,247, 3,220,187,119,175, 84,171,213,246,109,177,127, 19,180,119,106, 90, 74, 64, 88, 72,176,235,228, 41, 51, 69, 49, 49, 35, + 16, 23,119, 28,123,127,217,145, 56,102,194,232,159,159, 84,203, 24, 98, 38,159,197,167, 77,108, 6,203,150, 98,113,120, 18,173, +246,105, 4, 2, 38,147, 43, 2,198,181,248,224,121,103,230, 36,219,126,209, 35,112,242,212,113,236,253,101,219,229,207, 67,198, +238,240,137, 8, 34,186,117,254,122,182, 79, 59,159, 54,138,218, 50, 25, 73,176,117,106,181,201,230,235, 95,242,191,205, 93, 50, + 37, 23,192, 55,248,135,238, 58,100, 27,141,247, 52, 58,221, 36,175,200,200,219,197,183,111,135,173,209,235, 29, 62, 5,170, 62, +215,106,243, 15, 1,133, 53, 0, 57,171,110, 76,255, 6,224,170, 40,202,205,150, 36,239,202,141,198,193, 96, 48, 82,209,244, 68, +252,254,222, 33, 67,186,126,240,240, 33,203,185,103, 79, 94,113, 66, 2,191, 46, 19, 73,139, 66,139,162, 40,208,205, 47,117, 61, +195, 73,236,217, 67, 2, 0,139,197,106,118,140, 99,177, 88, 80, 42,149,208, 55,111,193,126,134,211,237,236,217,194,135, 15, 31, +250, 59, 56, 56, 60, 35,178,170,170,170, 26,222,171,213,106, 40,149, 74,240,120,188, 84, 85,211, 43, 34,207,112,150, 37, 38,170, +215,206,157,187,116,226,132, 9,223,197, 95,184,192,117,116,116,132, 84, 42,125, 70,104,105,181, 90,244,139,138, 98,173, 75, 78, +158, 12,153,108,153, 37,237,233,210,183,175, 89,127, 96, 6,131, 1,211,223,188,116,248, 18, 96,102, 83,194,139, 52,183,132, 99, +233,174,195,102, 30,144,207,239,238, 91, 18, 25, 25,169,206,202,202,130,183,183,119,131, 88,105,124, 78,145, 72, 4, 59, 59, 59, + 36, 37, 37, 97,245,234,213, 42, 0, 75,204,112,202,149, 74,229,235,253,251,247, 87, 81, 20,133,192,192,192,134,248, 89, 38,147, + 9,108, 54, 27, 2,129, 0,201,201,201, 24, 54,108,152, 82,169, 84,190,142, 63,198,208,122,158, 83,170, 84, 42,223, 24, 48, 96, +128, 50, 45, 45, 13,189,122,245,194,189,123,247, 80, 91, 91,139,218,218, 90,228,229,229, 33, 56, 56, 24, 74,165, 18, 63,253,244, +147, 74,169, 84,190, 1, 64,218, 18,167, 92, 46, 31,182,112,225, 66,198,175,191,254,234,227,225,225, 17,210,165, 75,151, 14, 81, + 81, 81,237, 71,141, 26,213,102,200,144, 33,110,254,254,254,234,129, 3, 7, 58, 15, 30, 60,216, 89,169, 84, 50,175, 93,187, 86, +162,215,235, 7,155, 41,103,131, 56,201,202,202,106, 88, 42,164, 40, 10, 21, 21, 21, 13,145,251,235, 7,165,102,132,112,180, 57, +177, 93, 47,176,234, 5,151, 5,126,110, 77,113,154,253, 17,155,205,174,183,120,210, 22,112,222, 77, 79, 79,239,223,167, 79,159, +187,211,166, 77,147,151,150,150,194,198,198, 6,190,190,190, 8, 8, 8,128,147,147, 19,116, 58, 29,142, 30, 61,170, 56,118,236, +216, 3,169, 84,218, 23,127,140,161, 21,253, 92, 59,230, 53, 53,200,214, 91,179,234,133, 22,151,203,133,135,135, 71,125,219,230, +181,166, 61, 95, 16,127, 47,103,157,128,137,234, 55,176,221,144,161, 35,109,143, 30,191,206,254,238,199, 99, 15, 34,163,177,221, +177,173,236,132, 99, 91,217,137,200,104,108,255,238,199, 99, 15,142, 30,191,206, 30, 50,116,164,109, 84,191,129,237,210, 82, 51, + 58, 52,206,123,216, 84, 57,185, 92,110,143, 94, 61, 35,171, 47, 93,189,108,250,114,221, 15,100,191,190, 99,146,119,252,124,244, +232,142,159,143, 30,237,215,119, 76,242,151,235,126, 32, 47, 93,189,108,234,213, 51,178,154,203,229,246,176,164,238,239,204,156, +100, 59,116,200, 8,196,197, 29, 53, 28,254,237,167,117, 7,142,100,247,153, 62, 39,177, 44, 43,235, 30, 45, 41, 58, 11, 38,249, + 24,233,233,233,210, 58,145,149,101, 9,231,172, 25,147, 26,139,172, 43,142,174,189,182,167,167,195,120,254,252,239,250, 11, 23, +146, 85, 87,238, 74,164,119,210, 42,170,138,203,171, 30,201,100,149, 90,147,201, 8,163,209,200, 88,177,162,193, 97,183,201,107, +244,234,171,175,225, 98,252,126,252,178,123,171,212,100,130,122,220,225,195,198,113,227,150,211,109,218,182,109,179,239,183,253, + 68,204,240,145,182, 52, 96, 26, 54,122,132,221,175, 7,126, 37,218,249,181,107,235,235,219, 16,210,230, 31,215,151, 62, 1,106, + 9, 32,189,228,214,173, 46,194, 94,189,238, 27,152,204,128,149, 44, 86,251, 77, 0,123, 28, 96,156, 5,232,151, 1,228, 50,192, + 67, 69, 81, 29,121, 6,195, 61,185, 82,233, 9, 0, 95,208,244,163,166, 56,151, 3,213,178,199,143, 47, 39,253,240,131,198,229, +245,215, 29,216, 46, 46, 34, 24,141, 68,253,248,222,220,139,162,168,231, 45, 48,205,114,122, 56, 57, 61, 57,113,226, 4, 2, 2, + 2,224,225,225,129,198, 62,178,245, 1,185, 29, 29, 29,113,228,200, 17,208,207, 6,167,110,150, 51,194,199, 39,233,171,181,107, +181, 38,147, 9,213,213,213,127,176,102, 85, 87, 87,195,100, 50,225,212,201,147, 90,217,211, 76, 32, 22,213,189, 47,131, 81, 59, +177,119,239, 47,135, 14, 29,170,123,248,240, 97,195,206,235,122,203,150, 68, 34,129, 80, 40,132, 90,163,241, 2,192,183,132, 83, +114,230,140, 0,102,198,245, 38, 44, 90,127, 71, 95,250,167,139,172,198, 9,165,103, 90,100,209, 50, 24, 12,240,242,242,122, 38, +165, 11, 73,146,207,188, 90,185,227,112, 79, 90, 90,218,217,129, 3, 7, 46,237,222,189,251, 59, 75,151, 46,101,116,232,208, 1, + 82,169, 20,246,246,246, 16,139,197,200,204,204,196,137, 19, 39,140, 21, 21, 21, 91, 0,172, 68, 19, 1,236,154, 64, 66,118,118, +118, 76,120,120,248,129, 69,139, 22,217, 14, 24, 48,128,233,229,229, 5,154,166,145,156,156,140,216,216, 88,221,142, 29, 59,100, +117, 34,203, 82,231,229,115,197,197,197, 99, 6, 15, 30,188,111,202,148, 41, 54, 70,163,145,153,151,151, 7,141, 70, 3,189, 94, +143,130,130, 2, 93, 92, 92, 92,173, 82,169,156, 4,224,156, 5,124, 73, 53, 53, 53,193,231,207,159,159,114,237,218,181,213,211, +166, 77,115,140,138,138, 98, 25, 12, 6, 92,189,122,181, 60, 34, 34, 66, 44,145, 72,116, 71,142, 28,169, 84,171,213, 75,140, 70, +163, 69, 41,120, 8,130,128, 76, 38,131,147,147, 19, 52, 26, 13, 76, 38, 19,180, 90, 45,132, 66, 97, 67,218, 36,154,166,209, 26, +231,250,231,250, 0, 67,167,211, 97,194,132, 9, 48,153, 76,216,184,113, 35, 12, 6, 67,171,201,108,109,109,239,220,189,123, 55, +166, 83,167, 78, 13,226,165,190, 15,113, 56, 28, 56, 57, 57,193,209,209, 17,113,113,113, 96, 50,153,119,204,249,187,213,225, 94, + 69, 69, 69,196,249,243,231,123, 60,120,240,224, 77, 0,157,116, 58,157,135,209,104, 36, 72,146, 44,161,105,250,190, 76, 38,251, + 25, 22,166,224,145, 72, 36,171,167, 78,157, 26,177,127,255,126, 33, 69,253,251,214,160, 40, 10, 28, 14, 7,245,193, 49,105,154, +134, 86,171,197,103,159,125, 38, 83, 40, 20,171, 95,150, 81, 34,178, 75, 55,108,251,105,147,240,194,197,179,229,233,217,136,181, +183, 79,127,190,255, 21,149,149,110, 11, 43, 46, 44, 20, 70,118,233,102, 17,167, 94,171,171,124, 99,210, 2,239,186, 20, 60,159, +229,229,229,111,221,183,231,219, 92, 0,248,122,195, 70,255,178,202,154, 89, 25,233, 25,227,182,110,253,173,135, 94,171,171,180, +132,243,223,226,101,159, 20, 52,212, 0,110, 38, 63, 40,243, 25,246,250,153, 37,126,237, 68,195, 37,149,170, 39,181,181,202,247, + 1,228, 90, 90,247,158,175,246,193,197,115,191, 98,239, 47,251,100,180,137,161,118,114,114,162, 1, 32, 61,221,137, 78, 79,175, +161,255,237, 87,108,167, 96,210,247, 86, 46,120, 63,106,129, 84, 86,181, 97,227, 79, 45, 47,165,132,119,236,142,240,142,221, 49, +231,253, 79,109,131, 67, 2,189, 1,224,240, 97, 24, 67,252,210,126, 95,250,249,242,225, 43, 87, 46,135, 76,174, 65,125,186,158, +204,148,180,147,185,185,208,254,147,251,209, 82,131,225,234, 74,154, 30,165, 76, 76, 12,235,241,209, 71,183,174,172, 95,239, 35, +101, 48, 94, 93, 1,152, 72,130, 48,130,166,121, 36, 73,150, 8,244,250,100, 57,155,237, 70,152, 76,157,109,140,198,163,122,163, +145,110,129,243, 38, 22, 44,240, 87, 86, 85, 57,247,252,228, 19, 39,234,163,143,200,150,156,225, 27,223,191,150,112,222,190,127, +255,228,172,233,211,159, 44, 91,186,116,224,150,173, 91,121, 97, 97, 97, 40, 45, 45, 69, 96, 96, 32, 60, 60, 60,112,254,252,121, + 28, 57,120, 80, 81, 35,151, 47, 1,176,217, 18,206, 61,167, 78,101,118, 8, 9,169,216,186,117,171,251,208,161, 67, 9,133, 66, + 1,169, 84, 10,169, 84, 10,141, 70,131,186,128,208,116, 86,118,118,186, 94,175,223, 98,105,221,141,229,229,220,149,221,186, 21, +177, 76,166,175,198,140, 30,189,112,229, 23, 95,112,218,181,107, 71,104, 52,154, 6,171,150, 78,167,131, 80, 40,212,105,181, 90, + 71, 52,225,247,214, 20, 39,103,199, 14, 67,121,121, 57,156,157,157, 27,194, 53, 53,142, 75, 40,151,203, 65,211,244, 75,155, 0, +253,239, 68,179, 10,201,222,222,254, 14, 69, 81,158,141,173, 91, 77,229,206,107,252,153, 94,175, 47,170,168,168,136,124, 78,241, + 54,231, 15,229, 11, 96, 77,191,126,253,198,124,248,225,135,196,165, 75,151,112,236,216, 49, 58, 55, 55,247,112,157, 21, 43,183, +133,217, 83,115,156, 54, 28, 14,103,158, 64, 32,136,174, 15,225,192,231,243, 31, 40, 20,138,248,186,229, 66,249, 11,112,138, 56, + 28,206, 92,129, 64,208,191, 46,253, 10,108,108,108,238, 42, 20,138,243, 26,141,102, 19,154, 79, 84,221, 18, 39,207,214,214,118, +181,147,147,211, 27, 31,125,244,145, 99, 98, 98, 98,201,197,139, 23, 89, 53, 53, 53,251,181, 90,109, 75, 73,165,255,192,233,224, +224,112,135,193, 96,120,254, 77,215, 8,225,225,225,113,195,134, 13, 27, 58,105,210, 36,232,245,122,108,222,188, 25,231,207,159, + 63,153,147,147, 19, 99,102,134,251, 60,167,147,167,167,231,165,119,222,121,167,205,132, 9, 19,248,246,246,246,160, 40, 10, 10, +133, 2, 57, 57, 57, 72, 78, 78,166,143, 31, 63, 94,155,148,148, 84,164, 84, 42, 95, 3, 80,209,138,246,252, 51, 51,241,103, 56, + 41,138,234,227,229,229,245,219,178,101,203,108,250,247,239,207,115,116,116, 4,131,193,128, 94,175, 71, 73, 73, 9, 82, 82, 82, +112,246,236, 89,197,225,195,135, 21,149,149,149, 19, 0, 92,254,111,148,243,175,228, 12,242,199,231,207, 37,138,110, 54,218,187, +153, 99,205,150,179, 95, 31,183, 17,227,198, 12, 30, 4, 0,135,142,156, 62, 99, 65, 82,233,102,203,105,174,172,150,112, 6,250, +145,203, 82,211, 82,158, 9,104, 25, 18, 28,154, 21, 20, 54,122,149, 37, 68,141, 34,195, 63, 83,247, 70,203,177,141,109,186,207, + 44,179, 6,249, 34,102,196,184, 81, 67, 63, 93,178, 24,107, 86,127,137,227,135,142,158, 76,207,125, 38, 77,208, 63,174, 47, 53, +126,182,172, 96, 48,250,145, 36,233, 69,176,217,183,244, 10, 69,182, 13,192,148, 3,140, 21,128, 98, 37,139,213, 30, 70, 99, 8, +104,154,146, 19, 68,220,122,163,209, 30, 64,177, 57,206, 85, 20,213,157,239,230,214,123,163,201,180,248, 94, 74,138,176,241,132, +173,222,242,220,120, 82,233,238,238, 46, 41, 41, 41,113,177,132, 51,230,251,239,117, 74,129,128,179,248,171,175,250,212,170,213, +125, 86,174, 92, 73,221,190,125, 27, 63,253,240,131, 65, 93, 84,180,175, 28,152,219,204,106, 72,179,156,109,230,206,229,126,252, +211, 79,111,249,250,249,137,223,124,243, 77, 38,147,201,132, 66,161, 64, 97, 97, 33,206,157, 61,171, 77, 75, 79, 79,147,201,100, +195, 91, 83,247,152,239,191,215,217,249,250,130,239,236, 76, 95, 72, 72,176,157, 53,111,222, 59,109,125,124,108, 7, 14, 26,196, + 20,137, 68,168,174,174, 70, 94, 94, 30,142, 30, 61, 42,169,173,173,117, 7, 96,180,132,115,223,181,107,225,167, 46, 95, 30,187, +106,213, 42,118,104,104, 40,108,109,109, 33,151,203,145,146,146,130,203,151, 47,107,182,108,217, 34,149, 74,165,239, 24,141,198, + 19,127, 99, 95,122, 41,151, 14,255,110, 15,127, 75, 46, 68, 36,128,207,235,222,127, 1,243, 57, 3,255,201,131,207,243,240,118, +112,112,216,166, 86,171,105,149, 74, 53, 11, 64,193,255, 96, 57,169,200,200,200,159, 36, 18, 73, 15,154,166, 97,107,107,123, 61, + 53, 53,245, 93, 52,179,243,198, 12, 39, 3, 64, 15,161, 80,216,205,198,198,166,143, 70,163, 9,170, 91,126, 75, 87, 40, 20,151, +117, 58,221,205, 58,235,147,241,191, 92,119, 6,128,254,238,238,238,211, 77, 38,147, 31, 65, 16,118, 70,163, 17,122,189,190,198, +100, 50,229, 72,165,210, 29, 0,206,255, 15,148,243, 47,225, 12,110,143, 81, 52,137,160,230, 4,193, 51, 66,235, 57, 1, 65,152, +144,158,246, 16, 71, 91, 81, 78,114,112,180,215,143,192,211,157,137, 48,239, 92,251,111,161,101,129,120,105,181,200,108,207,152, + 74, 19,244, 51,156, 4, 77, 20, 4,134,143,218,251,103,132,150,165, 8, 14, 64, 31,208,232, 97,162,113, 51, 35, 7, 23, 95,182, +177,110, 25,224, 66,146,100, 87,130, 36,219,211,128,130, 32, 8, 3,104,218, 1, 52,253, 16, 12, 70,234, 82,157,238, 33,154, 78, + 96,222, 44,231, 26,192,225, 7,123,251,235, 36, 69,185, 2, 32,235,172, 47, 38, 19, 65, 24,105,130, 48, 52, 94,222,122,110, 98, +217, 34,167, 14, 8, 99,114, 56, 94, 70,131,193,165, 20, 16,158, 50, 26, 59,171,105,186,214, 19,248,252, 46,144,217,218,186,215, +115, 50, 56, 28,239, 83, 52, 61,162, 92, 32, 8,151,168, 84,206, 0,104,161, 64,144, 46, 83, 40,126, 81,171,213, 63,182,182,238, + 58, 32,140,197,225,120, 26, 13, 6, 23, 0, 32, 41, 74,114, 64,163,241, 42, 18,137,222, 84,107, 52,109,132, 66,161, 94,171,213, +202,212,106,245, 36,131,193,112,161, 53,117,207, 49, 24,130,175,145,100, 47,157, 64,224,168, 35, 8,129,214, 96,208,105,117,186, + 66,181, 90,253, 0,192,183, 0, 30,254,205,125,201,138, 23,188, 1,173,156, 86, 78, 43,167,149,211,202,249,255,156,115, 45, 32, + 90, 3, 56, 88,219,243,111,229,228, 3,240,174,155, 44,254, 19,235,254, 82, 90,183, 40,107, 91, 88, 97,133, 21, 86, 88,241,119, + 99, 81,243,110, 22, 86,252,117, 80,162, 9,159, 44, 43,254,187, 32, 90, 80,165,173, 49, 9,190,136,178,141,183,114, 90, 57,173, +156, 86, 78, 43,167,149,211,202,249,255,142,211, 28,247, 63,113, 73,114,102, 19,159,109,251, 79,156,216,106,254,181,114, 90, 57, +173,156, 86, 78, 43,167,149,211,202,249,255, 22,164,181, 9,154,133, 75,221,235,175, 62,214,138,151,187, 47,252, 39,224, 81,247, +106,205,241,110,214,203,104,133, 21, 86, 88,241,255, 67,104, 89,250,208,250, 51, 15,183, 63,251, 96,252,146, 32, 80, 76, 16, 40, + 6,240,229, 95,120,172, 57,184, 59, 57, 57,125, 16, 28, 28,188,207,197,197,101, 14, 0,113, 43,127,239,207,231,243, 55, 9, 4, +130, 75, 2,129,224, 18,159,207,223, 4,192,255, 47,186,110, 4,128, 89, 28, 14, 39,193,205,205,237, 9,155,205, 78, 0,240, 14, + 94,124,231,106, 7, 60,141,147,246, 5,128,240,214,252, 80, 28, 50,226,160,115,200,136,251,206, 33, 35, 82, 28, 67,135,249, 59, +135,140, 72,113, 14, 25,113, 95, 28, 50,226,224,223,208, 95,255,202,235,251, 87,149,167,128, 32, 80, 96, 97,121,190, 37,128, 66, +130, 64,209,255, 72,249,173,176,194, 10, 43,172,104, 86, 5,184,187,143,113,115,115,139,119,115,115, 59,239,238,238, 62,198,130, +159, 68, 55,241,144, 48, 18, 4,140,102, 6,253,150,142, 51,103,174,108,252,219,245, 22, 86,173, 49,167, 11, 65,192, 72,215,129, + 32, 96, 18,139,197,223,185,185,185,125,249,252, 75, 44, 22,127, 71, 16, 48, 53, 58,214,216, 72,224,181,214,172,234, 50,121,242, +228, 67,213,213,213,113, 90,173, 54, 46, 59, 59, 59,238,181,215, 94, 59,240,156, 37,162, 89, 78, 46,151, 59,177,107,183, 30, 73, +151,175,222,204,206,202,201, 47, 78,203,124,148,255,251,153, 11,183, 67,195,194,111,113,185,220,137,173,184, 70, 4,128, 89, 20, + 69, 37, 8,133,194, 34,138,162, 18, 0,204,102, 48, 24, 39,214,174, 93,155,159,154,154, 90,118,237,218,181,154,203,151, 47, 63, +153, 54,109, 90, 14, 65, 16,191, 55, 33,216,163, 45,176,192, 44,125,252,248,241,153,146,146,146,179, 60, 30,111,181, 5,199, 55, +112, 58,135,140,184, 47,145,234,104,137, 84, 71, 59,135,140,160, 27,189,191,223,202, 54, 55,119,141,254,208, 23, 56, 28,142,183, + 25, 65,255,119,154,232,255, 80, 30, 0,174,117,223, 69, 2,248,190,238, 85,191,157,221,149,203,225,252, 85,253,243,175,104, 79, + 43,167,149,211,202,105,229,124, 89, 17, 81,247,215, 13, 79,253,181, 26,158,221,173,221,117,248, 94,118,118,182, 16, 0, 2, 2, + 2,222, 5,112,164, 53, 66,130, 32,240,177,201, 68,147, 0, 64,146,196, 39,125,251,246,139,224,241,120,207, 68, 65, 86,169, 84, +236,132,132,139, 81, 38, 19, 77,212, 29,247, 49, 77, 99, 19,128, 50, 75,207,161,213,106, 72, 38,147, 13,146, 36, 22,132,134,134, +181,173,168,168, 72, 36, 73,114,223,147, 39, 79,170, 91,109,198, 33, 8,108,223,190, 61,192,205,205,237, 15,209,154, 75, 74, 74, +216, 35, 70, 12,111, 21,223, 84,128,163,225,112,186,177, 8,194,205,104, 48,216, 1, 0, 69, 81,213,183,217,236,200, 53,171, 86, +241, 9,130, 48, 85, 86, 86, 66,165, 82, 97,254,252,249,188,180,180,180,145, 21, 21, 21, 63,154,161, 13, 8,239, 24, 49,255,236, +217, 51, 65,178,170,106,245,246, 13, 91,147, 84, 20, 75,233, 19, 28,200,250,105,219, 47,246, 51,223,154,244,126, 70, 70,234, 93, + 52,157,142,164, 49, 72, 0, 71,231,205,155, 23, 18, 19, 19,195,150,203,229, 92,149, 74,213,118,223,190,125,159, 69, 70, 70, 10, + 59,117,234,196,254,237,183,223, 8,169, 84, 10,154,166,249,129,129,129,244,248,241,227,213, 7, 14, 28,152, 3,224,187, 22,132, +239,199, 79,219,146,220,216,161, 67,135,101, 0,144,157,157,205,106,212,198,204,160,160, 32, 1, 0,100,102,102,174,160,105,211, + 60, 0,160,105,172, 3,176,184, 9,211, 90,118, 72,207,113, 0, 1,191,212,171,135,184, 33,189,198,169, 65, 35,135, 0,178,235, + 38, 4, 43,129, 70,113,161,158, 69,122,113,113,241, 11,229, 38, 28, 58, 52,134, 32, 8,226,112, 82, 82,210, 17,137, 68,226, 99, + 50, 25,103,180, 84,206,230,174,149,179,179,243, 89,163,209,168,169,170,170,106, 8,148,233, 28, 62,170,135,163,141, 32,170,188, + 90,158, 88,153,118,252,178,133,125,147,112,116,116,156, 90, 81, 81,241, 37,128,233,233,233,233, 17, 0, 16, 20, 20,196, 2,112, + 71, 36, 18,189,170,211,106, 9,235,248,103,133, 21, 86, 88,241, 31, 17, 90,201, 0,134,226,223, 41,120,182,189,136,208, 98, 3, + 64, 98, 98, 34, 0,112, 94,160, 32, 68, 99, 1, 51,119,238, 92,184,185,185, 61, 47, 94,112,233, 82,194,159,169,236, 51,231,248, +226,139, 47,132, 53, 53, 53,209, 63,255,252,115,111,154,166,215, 23, 23, 23,223, 48,243,251, 50,154,198, 58,146, 36, 62, 33, 8, + 2, 28, 14, 55,235,157,119,222, 73,174,251,174,237,239,191,255,206, 31, 54,108,152, 18, 64, 62, 0,112, 56, 92, 15, 6,131, 12, +160,105,186,254,129,219,172, 32, 28, 11,248, 26,216,236,126,179,190,255,222,208,121,216, 48, 74,224,236, 76, 0, 64,126, 70,134, +227,186,175,191,126,181, 58, 55,151,173,114,116,172,172, 84, 40, 84, 89, 89, 89,224,112, 56, 4,131,193,232,108,174,194, 2,129, +224,131, 85,107,190, 18,200,170,106, 84,106,153, 92,203, 48,232, 53, 54, 60,190,177,172, 84, 82, 41,228, 9,148,159,124,190,156, +253,222,140, 41, 31, 40, 20,138,119,205, 80,205, 89,176, 96, 65, 80,215,174, 93, 61, 14, 30, 60, 72, 72,165, 82, 80, 20, 37,236, +212,169, 19, 34, 35, 35,141, 23, 47, 94, 36,124,124,124, 16, 26, 26,138,171, 87,175,226,250,245,235, 68, 68, 68, 4, 63, 54, 54, +118,178, 94,175,255,206,156,184,102, 48,200,249,129,129,129,157, 4, 2,129, 54, 32, 32, 0, 51,102,204, 0, 77,211,136,142,142, + 14, 21, 10,133, 71, 20, 10, 5, 59, 51, 51,163,183, 57,145, 45, 73, 61, 62,190,222,178, 5, 32, 12, 52,114,202, 83,143, 55, 94, +126, 12,202,204,204,236, 94, 93, 93,141,167,215,133,110, 72, 96,222,187,119,239,214,244,165, 50,154,198,186, 97,195, 98, 62, 1, + 8, 34, 58, 58,186,102,206,156, 57,100, 70, 70,198, 27,163, 70,141, 12,205,206,206, 65, 43, 39, 3, 1, 3, 6, 12,184,122,234, +212, 41,199,128,128,128,242,170,170,170,134, 47, 92, 29,237, 6, 94,142,221,248,193,234, 77,251, 2,247,208, 68, 77,121,250,177, + 7,102,250, 38, 49,117,234, 91,101, 66,161,112,244,225,195,135, 51, 75, 74, 74, 40, 22,171, 65,187, 50,196, 98,177,115, 64, 64, +192,108, 7, 7, 7, 9,131, 36,197, 52,104,218, 92,255,180,194, 10, 43,172,176,226,133,113,178, 78, 92,157,124,254, 11, 10, 0, +226,226,226, 26, 34,211,198,196,196, 52, 59, 3,166,105,186,236,222,189,123, 94, 74,165, 18, 52, 77, 91, 50, 96, 55,222,162, 89, + 70, 16,228, 79, 36, 73,188, 75, 16, 4, 66, 67,195, 30,109,220,184,177,169,156, 94,218,208,208,176, 71, 12, 6,217,142,166,105, + 16, 4,185,153,166, 77,101,205,112, 54,249, 32, 98,179, 57, 31, 3,128,171,171, 91,238,233,211,167,181, 99,199,142,197,215, 95, +127,205, 90,180,104,209, 66,138,162,230, 20, 20, 20,148,182, 80, 78, 0, 88,236,236, 44,230,111,223,190, 61,224,157,119,222, 73, + 46, 41, 41, 89, 12, 0,110,110,110, 95, 2, 8, 6,144,223,232, 51,108,217,114,224,201,140, 25, 51,178, 36, 18,201,226,230, 56, + 71, 3,237,189, 2, 3,251,173, 76, 76,164, 73,141,134,168,184,114, 69, 86, 94, 86,166,127, 88, 94,206,223,125,231, 78,204,103, + 95,126,201,244,242,246,198,165, 19, 39,156, 42,148,202,114,169, 70,163, 46, 43, 43,163, 13, 6,195,117, 11,234, 30, 34,118, 22, +243,183,126,187,249,182, 13,147, 97, 18,123,122, 16, 76, 7, 7,138,228,139,216, 12,138,212,180,107,235,207, 6, 16, 98,238, 26, +177, 88,172,201, 3, 6, 12,224, 31, 56,112,128, 8, 13, 13,133,157,157, 29,174, 92,185,130,187,119,239,162,186,186,154,212,235, +245,232,210,165, 11,190,250,234, 43,120,123,123,163,166,166, 6, 5, 5, 5, 78,108, 54,219, 89,175,215, 55,215,158,207,244,167, +143, 63,254, 24,110,110,110, 48, 24, 12,168,170,170,130,193, 96,128, 80, 40, 4, 0, 20, 21, 21,225,196,137,227,150,244, 37,179, +160,105, 26,175,188,242,138,156, 32,136,244,231, 45, 90,173,225,244,240,240,248,173,188,188, 98,112,191,126,253, 80, 93, 93,173, + 95,190,124, 57,194,195,195, 17, 16, 16, 96,182,156,238,238,238,179, 12, 6,195, 82, 0,208,233,116,187,185, 92,238,219,123,247, +238,117,108,156, 34,164,222,146, 85, 38,169,172,190,126, 59, 53,115,193,172,177,175, 37,222, 72, 41,212, 49, 71, 20, 72,239, 31, +151, 54, 81,206,197, 44, 22,251,231, 54,109,218,124, 59,119,238, 92, 55, 7, 7, 7,104, 52,154,207, 74, 75, 75, 49,123,246,108, + 0,192,144, 33, 67,194,153, 76,230,233,105,211,166,193,199,199,231, 73, 85, 85, 85, 65, 82, 82,210, 12,165, 82,153,242,162,237, +105, 33,172,156, 86, 78, 43,167,149,243,133, 97,169, 22,249, 31, 69, 9,158, 13,231,176,237, 25,161, 21, 19, 19, 67,196,197,197, +209, 22, 84,172,210,211,211,211,139,199,227, 1, 64,101,107, 75, 97, 50,153,230, 56, 58, 58, 74, 22, 47, 94,220, 51, 32, 32, 64, + 59,103,206,156,148,252,252,252, 37,141,143,105,219,182,237,234, 31,126,248, 1, 89, 89, 89,249, 95,126,249,229,213,202,202,202, +214,230, 49, 91, 68,211,216, 88,103, 29,171, 56,113,226, 68,120, 98, 98,226,187, 27, 54,108,112,126,239,189,247, 88, 31,124,240, +193, 36, 0, 95,155, 35, 97, 48, 24,202,166,150, 11,155,130,155,155,155,150,193, 96, 52, 27, 36, 46, 6,224,113,217,236,190, 43, + 19, 19,105,109,126,190,114,231, 55,223,216,108,189,117,107,153,158,166, 93,196, 98, 49,122,189,250,106, 45,151,193,168,144,148, +150,154,196,237,219, 51,242, 78,159,118, 82,177,217,197, 7, 14, 28,144, 86, 86, 86, 30, 51,107,194, 35, 8,153,137,166,181, 66, + 79,111,253,216,145,253, 67,111,223,188,155, 97, 35,118, 34, 35, 58,133,134,103,100,229, 39,193,100,210, 17, 4, 97, 54, 88,160, +173,173,109, 64,101,101, 37,100, 50, 25,156,157,157,177,113,227, 70,184,186,186, 66,169, 84, 34, 53, 53,149,246,244,244, 36, 18, + 19, 19,225,233,233,137,242,242,114,104,181, 90,200,229,114,137, 70,163,105, 46, 55, 99, 25, 73, 50,118,145, 36,241, 22, 65, 16, +104,215,206,247,241,143, 63,254,168, 53,153, 76, 8, 10, 10,194,168, 81,163, 16, 27, 27,139,212,212,212,122,203,147,182, 77,155, +182,143, 73,146,104, 83,167,149, 94,216, 2, 83,159,218,167,184,184,120,244, 11,222, 52,164,187,187,251, 36, 63, 63,191,119, 39, + 78,156,168,103,179,217, 80, 40, 20,245,109,161, 31, 60,120, 72,205,176, 97, 49,182, 39, 79,158,108,182,156, 58,157,110,233,147, + 39, 79,220, 84, 42, 21, 6, 13, 26,244,193,250,245,235, 5,108, 54, 27, 0, 96, 52, 26,159,177,100,173,218,176,231,236,188,165, + 63, 38,156,253,237, 43,247, 85,139,222,126,109,210,156,213, 9, 0,206, 52, 85, 48,173, 86,155, 43,149, 74,167, 47, 88,176, 96, +223,150, 45, 91,236,151, 44, 89, 2,147,201, 4,154,166, 97, 48, 24, 26, 18,137,155, 76, 38, 28, 61,122, 20, 15, 31, 62, 92,253, +156,200,178,194, 10, 43,172,248,159, 67, 43,180,200,255, 34,220,240,116,217, 16,207,139,173,255,120,100,120, 6,131,177,245,220, +185,115,157,122,247,238, 77, 69, 69, 69,133,158, 57,115, 38,244,201,147, 39, 41,117,214,131,208,168,168,168, 80,177, 88,140, 77, +155, 54, 41, 25, 12,198,214, 23, 60, 77,195, 67,175,180,180, 52, 25,192,250,216,216,216,117,179,102,205,130,171,171,107,112, 73, + 73,201,127,180,206, 34, 14, 39, 98,218,198,141, 6,166, 94, 79,126,191,126,189,232,155,132,132,117, 7, 15, 29,162, 94,121,229, + 21,130,166,105, 60,184,127,159,247,213,119,223,241, 39,140, 28,153,159,153,155,107, 56,126,246,172,190,236,201,147,170, 39,229, +229, 75, 1, 84,153,227,215,235,245,255,202,206,206,118,239,213,231, 21,143,203,183, 82,238,142, 29, 57,164, 31,147, 34,137,156, +252,162, 59,110,174, 78,182,151, 18,226, 85,122,189,254, 95,230,120, 20, 10, 69,158,193, 96,112,160,105,218,249,210,165, 75,112, +118,118, 70,117,117, 53,244,122, 61,180, 90,173, 86,169, 84,114, 43, 43, 43,161, 86,171,161,209,104, 32, 18,137,240,224,193,131, + 50,131,193,112,177, 57, 78,163,209, 56,141,195,225,124,193,100, 50,217, 44, 22,171,248,206,157, 59,144,201,100,109,237,236,236, +190, 54, 24, 12, 40, 46, 46, 70, 98, 98,226, 71, 34,145, 40, 31, 0,184, 92, 46,216,108,142,163, 70,163, 49, 0,120,242,162,109, + 78,211,244, 11, 95, 47, 87, 87, 87,111, 30,143,183,242,147, 79, 62, 14,234,216,177, 19,202,203,203, 97, 50,153, 32, 16, 8,160, + 84, 42, 33, 18,137,208,163, 71,143,188,149, 43, 87,150,208, 52,102,182, 32, 6, 25,117,215, 7,179,102,205, 18,136, 68, 34, 20, + 22, 22, 34, 48, 48,176, 65,104,149,148, 87, 62,184,118, 59, 37, 99,193, 59,227,250,236, 63,145,144,126,246,210,157,244,145,131, + 94,237, 72, 16,116,219,150,202, 40,145, 72,202, 41,138,154, 51,107,214,172, 47, 2, 2, 2,218,209, 52, 13,127,127,127, 12, 24, + 48, 0,167, 79,159, 70, 86, 86, 22, 20, 10,133,241,198,141, 27,191,150,148,148,252,110, 29,194,173,176,194, 10, 43,254, 86,252, +193, 55,235, 25,139,214,127, 18, 18,137,164, 60, 35, 35,227, 76, 82, 82, 82,204,248,241,227,113,233,210,165,241,103,103, 1, 0, + 0, 32, 0, 73, 68, 65, 84,169, 0, 22, 0, 0,135,195,153, 58,126,252,120, 36, 37, 37, 33, 35, 35,227,140, 68, 34, 41,255, 43, +206,201,102,179,213, 90,237, 83,227, 20,151,203,229,182,242,231,109,235,150, 12, 1,160,109, 11,159, 53,111, 26,161, 40,183,176, + 65,131,168,234,187,119,101,219,111,222,252, 98,223,190,125, 84,207,158, 61, 9,189, 78, 7,163,201, 4, 95, 95, 95, 34, 42, 58, + 90,176,107,223, 62, 7,163, 66,145,184,234,147, 79,174,108,155, 54,173, 54,187,206, 15,204, 28, 52, 26,205,119,239,206,158, 30, +157,112,233,138, 71,112, 96,123,135, 51,231, 18,146, 29, 29,109,249, 1,126,126,130,202,234, 42,227,146, 69, 31, 81, 26,141,230, +123,115, 60, 42,149,234,104,124,124,252, 72, 47, 47, 47,231,148,148, 20,104,181, 90, 24,141, 70, 68, 69, 69,129,166,105, 14, 0, + 19, 69, 81,200,200,200,128, 78,167,147,100,103,103, 23,231,228,228,112, 0,172, 53, 83,190,199, 26,141, 6,233,233, 79, 87,237, + 60, 61, 61,251, 15, 29, 58, 20, 6,131, 1,131, 6, 13,194,241,227,199,251,167,167,167,127,211, 88,243,253,217,107, 94,103, 33, + 11,114,119,119,143,173,251,200, 34, 39,120, 15, 15,143, 80, 95, 95,223, 45,107,215,174,101,121,122,122,130,166,105,216,219,219, + 65,169, 84,162,162,162, 18,193,193,193,240,242,242,194,218,181,107, 1,224,215,150, 44,110, 38,147, 9, 37, 37, 37,200,203,203, + 67,110,110, 46,188,188,188, 64, 16, 4,228,114, 57, 12,134,167, 57,185,249,114,217,201, 31,118,253,222,247,208,150,165, 33,221, +194,252,189,111, 38,167, 73, 38,143,238,207,247,247,241, 14, 40, 79, 89, 78, 2,203,155, 77,186, 92, 92, 92,156, 83, 92, 92, 60, + 94, 34,145,176,106,106,106, 34,251,247,239,191, 41, 58, 58, 26,201,201,201,184,114,229,202, 4, 14,135, 35,209,233,116, 6, 87, + 87,215,153, 4, 65,136,116, 58,221,254,202,202,202, 18,235,120,104,133, 21, 86, 88,241,151,163,222, 71, 11,141,254,182,206,162, +245,127,236,157,119,120, 20, 85, 27,197,207,108,223,108,122,217,144, 66, 2,132,146, 16, 2, 4,164, 72, 15, 8,210,130,116, 80, + 41,130, 74, 19, 69,164, 8, 22, 64, 44,128, 74, 83,145,170,210,123,211,128, 64,162,180, 72, 64, 58, 36, 36,129, 4, 82,119,211, +203, 38,219,167,220,239,143, 20, 19, 72,217, 77, 98,129,111,126,207, 51,207,236,206,206,156,185, 83,246,206,153,247,182,192,192, + 64,219,164,164,164, 73, 77,155, 54,149, 2,128,141,141, 77,155,230,205,155,207, 79, 76, 76, 44,178, 54, 53, 58,157,238,192,238, +221,187, 95, 92,179,102,141,100,200,144, 33, 45,142, 28, 57,210, 5, 0,134, 12, 25,210,194,222,222, 30,187,119,239, 54,235,116, +186, 6,235, 19,137,166,233,222,157, 59,119, 70, 94, 94, 30,146,146,146,172, 42, 66,249,229,151, 95, 20, 40,169,151, 85,227,178, +154, 96, 76, 38,103, 39,111,111, 65,250,217,179,230, 60,141,198,179,119,159, 62, 20,109, 54, 67, 32, 16, 32, 55, 55, 23, 41, 41, + 41,112,116,114,162, 98,239,223,183,219,182,112,225, 47, 77,131,131,165,172,201,228,106, 69, 50,181, 57, 89,153, 83,222,158,253, +214,209, 61,123,246, 42, 11, 52,154, 4, 27, 27,133, 81, 38,147,120,204,121,251,109, 54, 47, 47,111, 50,128, 98, 11,116, 86,238, +217,179,103,208,160, 65,131,110,251,250,250,186,103,103,103,123, 20, 20, 20,176,121,121,121, 66,148,212,181,162, 0,224,236,217, +179,208,104, 52, 12,203,178, 23, 80,210, 23,150,201,210,132, 54,105,210,196,177, 83,167, 78, 33, 74,165, 18,133,133,133,112,117, +117, 69,135, 14, 29, 66,132, 66,225, 15,201,201,201,133, 13,121,215,135,135,135,219, 19, 66,158, 39,132, 96,208,160, 65, 22,109, +195,178,236,212,161, 67,135, 74, 40,138,130, 94,175,131, 92,110, 3, 91, 91, 59,216,219, 59,192,223, 63, 0, 42,149, 10, 3, 7, + 14, 52, 37, 36, 36,124,175, 86,171, 15,212,162, 5,149, 74,133,236,236,108,164,164,164, 32, 39, 39, 7, 0,144,147,147, 83, 94, + 57,191, 33, 40, 44, 44, 28,222,189,123,247,121, 51,103,206, 4,195, 48, 24, 62,124, 56, 82, 83, 83, 87, 63,122,244,104,191,151, +151,215,132,169, 83,167, 42, 93, 93, 93, 49,111,222, 60, 27, 0,159,240,249, 33, 15, 15, 15, 79,131,243,120, 29,173, 39, 35, 90, + 53,149,137,122,120,120,244,162, 40,234, 35,189, 94, 47, 45, 43,146,161, 40, 74,170, 84, 42,143,235,245,250, 21,106,181,218,170, + 74,113, 5, 5, 5,154,135, 15, 31, 30,143,138,138, 26, 59,106,212, 40,132,135,135, 79, 6,128, 81,163, 70, 33, 42, 42, 10, 15, + 31, 62, 60, 94, 80, 80,208, 32, 3,144,122,123,123, 15,238,211,167,207,168,206,157, 59, 35, 44, 44, 12, 44,203, 94,178,102,251, +138, 45, 12, 81, 69,171,195,178,101, 22,137, 9,133,160, 40,170, 60,154,145,147,157,141,248,184, 56,228,229,231,195,104, 48, 64, +171,211,177,254,205,154,233, 11, 77, 38, 49, 5, 88, 91,246,149,124,253,234,229, 20,157, 86,235,238,234,236,162, 87, 40,100, 40, +208, 20, 74,174, 93,189, 92, 12, 32,193, 66, 13, 19, 33,164,207,175,191,254,186, 68, 40, 20,142,179,179,179,195,172, 89,179,132, + 33, 33, 33,144, 72, 36, 48, 26,141, 40, 40, 40,192,238,221,187,179, 89,150,245, 43,221,198, 78,161, 80,236, 16, 10,133,105, 69, + 69, 69, 31,213,186, 3,147,105, 72,104,104,168,200,100, 50,225,179,207, 62,195,210,165, 75, 49,104,208, 32,209,213,171, 87,135, + 0,216,211, 80,119, 60,199,113, 24, 48, 96, 64,197,202,240,247, 44,217, 78, 44, 22,183,109,217,178, 37,178,179,179,145,157,157, + 13,165, 82, 9, 47, 47, 47,120,120,120, 96,245,234,213,100,253,250,245,167,204,102,243,247, 57, 57, 57,153,150,164, 33, 49, 49, +177, 60, 50,104, 48, 24,160,213,106,145,154,154, 90, 94,116,168,183,117, 24, 52,123,202,176, 96,173, 94,175,187,114,231,126,202, + 71,239, 76,232,166,213,235,117,247, 31,165,196, 3,223,112, 22,220,223,211, 38, 79,158, 60,109,236,216,177, 40, 46, 46, 70, 84, + 84, 20,122,244,232,129, 47,191,252,210,243,194,133, 11,239,117,238,220, 25, 98,177, 24,231,206,157, 3,195, 48,169,124, 94,200, +195,195,243, 95,230, 41,173,159, 85, 35, 53, 70,180,124,124,124,156, 88,150, 93, 48,116,232,208, 1, 35, 70,140,192,192,129, 3, + 43,253,190,103,207, 30,251,195,135, 15,175,248,230,155,111, 6,153,205,230,149,214, 20,245,113, 28,119,116,207,158, 61, 67,186, +117,235,166,232,219,183,111,115, 0,144,201,100,166, 61,123,246,232, 56,142, 59, 90,135, 99, 41,235,136, 49, 19, 0,188,188,188, +218,139, 68,162, 81,131, 7, 15,110, 63,101,202, 20, 68, 71, 71, 99,247,238,221, 15,252,253,253, 35, 51, 51,173,170, 95,157, 84, + 75,171,195, 21,181, 69,183,132, 82,105,110, 65, 70,134,147,157,175,175,216,217,222, 94, 29, 22, 22,230,211,191,127,127, 42, 53, + 53, 21,249,249,249, 48, 24, 12,184,122,245, 42, 39, 2,146, 69,206,206, 84,114, 84, 20, 37,148, 74,115, 81,185, 37, 95,173,248, +120, 58,183,250,120,209,140,166, 6,163, 33,168,176,176,144, 17,137,197,226,198, 30, 78,169,113, 9, 86,149,196, 25, 21, 10, 69, + 39, 0, 34,142,227,116, 46, 46, 46,138, 51,103,206, 64, 42,149,130,162, 40,180,107,215, 14,114,185, 92, 66, 8, 73, 1, 0,123, +123,123,233,230,205,155, 29, 39, 76,152,112,177, 54,225,142, 29, 59,138,101, 50,217, 75,254,254,254,136,138,138,194,221,187,119, +147,163,162,162,154,116,236,216, 17,190,190,190, 47,121,122,122, 30,188,113,227, 6,221, 16, 55,118, 73,139, 85,235, 43,195,179, + 44,203, 81, 20, 5,129, 64, 0,142,227,144,157,157, 13, 63, 63, 63,108,216,176, 1,235,214,173,251, 76,173, 86,255,108,133, 22, +171,209,104, 96,107,107,139,187,119,239, 26,135, 14, 29, 42, 19, 8, 4,120,240,224, 65,185,209,114,119,115,105,211,163,115,219, +214,159,173,221,121,218, 86, 38,147, 13, 12,233, 20, 24,115, 63, 57,141, 16,170,214, 98,227,192,192, 64,137,159,159,223,228,177, + 99,199, 34, 49, 49, 17, 43, 86,172,200, 81,171,213,103, 79,159, 62, 61,122,230,204,153,194, 30, 61,122, 32, 55, 55, 23, 63,253, +244, 19,115,237,218,181, 31, 51, 50, 50,118,242,217, 56, 15, 15, 15,207,127,196,104,249,248,248,140,149, 72, 36,243,198,143, 31, + 47, 12, 8, 8, 64,102,102, 38, 28, 28, 28,104,138,162,196, 0,224,228,228, 68,219,216,216, 96,198,140, 25, 8, 14, 14,238,181, +112,225,194, 30, 34,145,104,131, 74,165,218, 97,201,142,179,178,178,116, 2,129,224,208,172, 89,179, 86,222,188,121,195, 15, 0, +254,252,243,207,135, 42,149,106, 81, 86, 86,150,206,202,227, 40,235, 20,147,146,201,228, 87, 90,181,106,245,168, 83,167, 78, 14, + 35, 70,140,128, 82,169,196,245,235,215,177,106,213,170,251, 38,147,105,201,249,243,231,153,127,250, 36, 51, 70, 99,198,181, 99, +199,236, 67, 94,125,213, 97,206,208,161, 95,191, 53,107,214,154,143, 63,254, 88, 20, 16, 16, 64,233,116, 58, 92,185,114,133, 28, + 62,124,152,254,233,211, 79,215,193,214, 86, 28,117,248,176,212,100, 50, 37, 91, 25,185,235,211,179,119,175,128,175,215,124, 3, +131,190, 24, 87, 46,157, 64,126,126, 54, 54,111, 57, 18,224,237, 77,250,164,167,167,159,183, 84,139,162, 40,255,240,240,112,119, + 66, 8,164, 82, 41,150, 47, 95, 14, 47, 47, 47, 56, 56, 56,160,168,168, 8,239,189,247,158,227,187,239,190,235, 8, 0,209,209, +209,229,221, 51,212,134, 74,165,234, 62, 99,198, 12,123,134, 97,112,234,212, 41, 19, 69, 81, 31, 69, 68, 68,252,208,174, 93, 59, +105,175, 94,189,236,119,238,220,217, 3,192,185,134, 50, 90,117,220,238,193,153, 51,103, 58,143, 27, 55,142,136,197, 98,170,160, +160, 0, 78, 78, 78,216,176, 97,131, 86,173, 86,159,176, 82,107,249,162, 69,139,150,148,126,222,254,209, 71, 31,189,177,114,229, + 74,101, 70, 70, 70,121, 84, 51, 43, 39,239,247,238, 67,223,102,115, 11, 10, 77, 63,174, 93, 56,198, 70, 46,147,126,180,242,199, +115,180, 16,151,107,189,175, 24, 70,170, 80, 40,164,132, 16, 28, 58,116, 8,201,201,201, 83,115,115,115, 51, 88,150, 61,178, 96, +193,130,249, 1, 1, 1,205,226,226,226,146,139,138,138,190,204,202,202,122,196,103,119, 60, 60, 60, 60,127, 27,101,149,224,203, + 90, 31,158, 64, 73,113, 98,245, 70,139,101,217, 25,167, 79,159, 22,114, 28,135, 45, 91,182,224,218,181,107, 68,161, 80,124,164, + 80, 40,190,179,177,177, 97,245,122,253,244, 55,223,124,115,194,210,165, 75, 5,189,122,245, 66, 84, 84,148,192,207,207,111, 50, +128,138, 70,171, 63,106,232,107,163,176,176,240,106,102,102,134, 95,133, 14, 42,253,100, 50,249,213, 90, 14,230,113,205,199, 59, +197,236,186,124,249,114,173,167,167,167,233,238,221,187,216,180,105, 19,119,237,218,181,179, 82,169,116,179, 90,173, 54, 90,168, +217, 16,148,107, 74, 25,230,250,174,249,243, 3,159, 27, 62,156,123, 99,222,188, 98,137,141,205, 59, 95,127,243,205,194,130,162, + 34, 47, 80, 20,113,117,116, 76,222,178,124,249,138, 65, 47,189, 84, 28,125,254,188,252,102,120,184, 88, 73,211,183,172, 73,103, +122,122,250,249,115,231, 46, 98,251,214, 53, 48,155,141, 80,167,151,248,180,156,220, 66,212, 98,178,158,208,100, 24,166,112,244, +232,209, 18, 0, 54, 19, 39, 78,148,102,101,101,161, 69,139, 22, 0, 0,141, 70,131, 19, 39, 78,160,117,235,214, 0,128, 59,119, +238,148,127,174, 45,157,182,182,182, 47,245,232,209, 3,201,201,201,136,142,142,254, 77,173, 86,231, 2,248, 45, 53, 53,117, 72, +231,206,157,113,244,232,209, 97, 53, 24, 45,171,174,145,133, 70,235, 9, 77, 27, 27,155, 69, 71,142, 28,153,122,233,210,165,113, +243,231,207, 23,191,240,194, 11, 0,128,162,162, 34, 29, 0,214, 26, 77,189, 94,191, 25, 64,121,203,217,164,164,164, 93,243,230, +205,187, 48,119,238, 92,101, 89,250,178, 99,126,142,202, 6,162,130, 66,166,126,220,189,115, 80,192,231,235,119,159, 78, 73,205, +220, 93,120,239,120,161, 37,199, 78, 8, 1, 77,211,224, 56, 14, 46, 46, 46,218,220,220, 92,100,101,101, 61,202,202,202,154,149, +144,144, 96,213,177, 55,228, 61,207,107,242,154,188, 38,175,249,127,138,229, 61,195, 19, 66, 24,142,227,112,238,220, 57, 28, 57, +114,132, 53,155,205,211,212,106,117,197,222,170,191,185,126,253,122,248,232,209,163,119,196,197,197, 9, 99, 98, 98, 64, 8, 97, +173, 73,141,193, 96,160, 41,234,201,101,245, 61,202,237,219,183, 35, 35, 35,195,156,154,154, 26,193, 48,204,209,122,182, 94,172, +119,171,195,237,128,241, 21,147, 41, 98,105,207,158, 3,150,132,135,203,222,248,224, 3,227,107, 83,166, 44, 96, 77, 38, 90, 40, +145,112, 82, 91, 91, 1, 43,147,137,163,207,159,151,175,159, 57,211, 69,111, 52,158,218,109, 69, 5,243,178,136, 86, 72, 72, 47, +188,246,198, 92,232, 43, 68,180,162,174,198,195,104,134, 85, 17, 45,163,209, 24,164, 86,171, 33,151,203, 83, 0,120, 76,154, 52, + 9, 28,199, 65,175,215,163,168,168, 8, 42,149,170,112,202,148, 41,108,169,121, 18,141, 26, 53,202,193, 18,221,230,205,155,123, +137,197, 98,156, 58,117, 10, 98,177,248, 4, 0,136,197,226, 19,225,225,225, 67, 94,126,249,101,120,123,123, 55, 79, 76, 76,164, + 80, 75,253, 52,247,160,225, 7, 8,208, 10, 20, 90,150,132,224,208, 82, 25, 52,252, 54, 5,220, 47,237, 53,254, 94,199,142, 29, + 1, 11,235,101, 85,164,180,113,199, 58,154,166, 15, 46, 92,184,112, 86,215,174, 93, 95, 92,186,116, 41,133,210,174, 26,234, 73, +124,122,122,122,239,197,139, 23,159, 38,132, 84, 50,253, 89, 57,121,191,119, 11,157, 77, 10, 10, 10,111,102,223,251,249,142, 85, + 17, 83,134,169, 87,119, 22, 60, 60, 60, 60, 60, 13, 22,213,122,130,106,141, 22, 69, 81, 91,250,244,233, 51, 13,128,144,162,168, + 77, 42,149,234,137,204, 95,173, 86,199,123,121,121,125,213,172, 89,179,233, 0, 8, 69, 81, 91,172, 76, 84, 38, 33, 88, 37, 16, + 80, 11, 75,204, 93,157, 58,168, 44, 27,150,100, 33, 0, 74, 32, 16,238,184,113,227,198, 7, 41, 41, 41,217, 22, 70, 32,106,164, + 33, 90, 29, 2,192, 94,224,209,248,228,228,211,243,218,182,237, 63,104,230, 76,180, 31, 52,200,193,171, 73, 19, 86,111, 54,115, +119, 34, 35,169, 75,135, 14, 73,110,134,135,139,245, 70,227,169,163, 64,138,181,233, 76, 79, 79, 63,255,251,217,243,103,198,140, + 26,242, 98,243,102, 94, 37,166,225,145, 10, 57,121,133,103,172, 49, 89,143,153,222,225, 27, 54,108,248, 89, 34,145,136, 42, 14, +101, 99, 54,155,243,140, 70, 99, 16, 0,228,231,231,123,109,217,178,101,159, 64, 32, 72,174, 77, 47, 38, 38,230,248,146, 37, 75, + 70, 37, 37, 37,157, 73, 77, 77, 77, 2,128,148,148,148, 36,154,166,119,168,213,234, 81,201,201,201,135, 97, 65, 35, 0, 2,180, +138,142, 60,216, 14, 0,130,122,142, 69,116,228, 65, 57,128,118, 65, 61,199, 2, 0,234, 58,150, 97, 69, 74,187, 65,248, 40, 42, + 42,106,207,139, 47,190,248, 38,234,209,167,215,227,102,203,108, 54, 55,121,124, 97, 89,100,203, 26, 33,147,201, 68,235,245,122, +134,101, 89,145,217,108, 38, 38,147,137,230,243, 57,158, 90,224,199,190,228,121,106, 33,132,116, 6,160, 44,203, 54, 75,231,202, +199, 62,155, 80, 58, 92, 96, 89, 86, 89,250, 61,155,162,168,171, 21, 52,202,151, 91,176, 45, 0,228, 0,184, 77, 81, 84,117, 65, +144, 45,213,125,175,214,104,169, 84,170,195,176, 96,208,104, 75,215,171,129,197,165,227,196, 1,117, 31,135,173, 92,131,101,217, +204,148,148,148,122, 95, 80,129, 64,240,104,216,176, 97, 86,173, 95,219, 58,251,129,228,183,141,198,157, 97,223,126,219,225,212, +166, 77,222, 44,195,184, 82, 0, 17, 74,165,185, 38,147, 41, 73, 73,211,183,172,141,100, 85,138,198, 60, 76, 31,152,248, 48, 29, + 45, 91,182, 36, 15, 30, 60,104,136, 76,245,150, 86,171,245,169,237, 22,208,233,116,189, 44, 52,131,123,211,211,211,247, 86, 97, +216,247,169,213,234,125, 86, 60, 41,238,151,154, 42, 1, 71,113, 99,130,122,142, 61, 4,128, 43, 27, 84,186, 33,201,200,200,136, + 67,105, 63,111,255, 53,146,147,147,141, 20, 69,237, 90,181,106,213,196,155, 55,111,238, 87,169, 84, 70, 62, 43,230,225,225,121, +150, 77, 22, 69, 81, 97,165,223, 67, 75,131, 66, 97,143,127, 46, 91,167,108,189,138,235,148,105, 60,190,188,166,109, 1, 96,209, +162, 69, 31,172, 88,177, 66, 1,192,210,193,152,235, 60,168,244,223, 69,230,127, 68,163,162, 41,216,250,119, 28,232,183,128, 9, + 12,115, 25, 76,133, 58,249,116,195, 6, 34, 30, 60,120,240, 76,191,181,150, 13, 42, 93,129,182,255,175,153, 79, 82, 82,210, 6, + 95, 95,223,205, 42,149,138, 1, 15,143, 5,207, 43,254, 20,240, 60,165, 40,171, 50, 70,213,152,178,208,154,126,175,244,226, 94, +197,122, 85,125,167, 40, 42,108,197,138, 21,161, 86,164,183, 60,162, 37,224,175, 29, 15,207,211,205,191,209,146,150,135,135,135, +231,153,120,243,120, 44,138, 85,102,190, 30,255,190,104,209,162, 15, 80,115,137,147, 39, 74,162, 88,158,165,223,203,235,107, 81, + 40,105, 57, 80, 21,214,180, 38,232, 95,135,227,139,224, 53,121, 77, 94,147,215,228, 53,121, 77, 94,243,255, 78,179, 54,237,136, + 42, 12,209,208,234,138,250,106, 42, 70,124,252,115,109,219,214,182, 46, 69, 81,213,117,243, 83, 86, 84,248,248,252,111,167, 63, +175,201,107,242,154,188, 38,175,201,107,242,154,188,102,125, 32,132,116, 38,132, 12, 69, 73,241, 55, 33,132, 12, 37,132, 12, 90, +180,104,209,226,178,101,139, 22, 45, 90, 76, 8,121,161,108,189,210,117,202,183, 41, 91,246,248,252,241,101, 53,173, 91, 67, 18, +167, 61,246,185,252,251,127,165,142, 22, 15, 15, 15, 15, 15, 15, 15, 79,149,148,181, 24,172, 16,109,202, 6,112,103,197,138, 21, +249, 21,234, 78,101, 3,184, 5, 32,184,116,189,236, 82,147, 86,177,110,149,169,244,187,169,138,117, 76,150,172, 91, 13, 91,170, +249,204, 27,173,234, 8,246, 16,124,234,219,216,189, 83,233, 5, 0, 41, 29, 4,152, 43,237,175,136,148,117, 92,196,113, 32,132, + 64,149, 85,112,253, 78, 22, 62,174,235,254,252,189,224,226, 46,151,175,227, 8,233, 89,186,232,124, 97,174,113,110,180, 6, 5, +150,106,180,110,132, 64,185, 0, 11, 56,130,246, 0, 32,160,112,219,192,225,171,216, 76,235,251,147,170,234, 62, 15, 82, 98,154, +212, 70, 49,222,209,201,185,101,126,126,206,125,179,193,120, 48, 38, 27,155, 81,135, 10,182,205,157,241, 60, 71,240, 1, 0,129, + 88,128,213,247,243, 44,110,201,193,195,195,195, 83,223,232, 72,189,250,197,163, 40,138,173, 66,147,170,167, 38,223, 80,193, 2, +179, 85,197,226, 63,171, 88,118,245,191,148,110,171,140, 86, 27, 37,102,130,194, 50, 0, 4, 4,159,196,100, 99,163, 85,219,123, +162,191, 92, 40,220, 6, 64,104, 48,179,243, 8,135, 11, 85,158, 76, 1,122,203, 37,194,213, 0, 56, 3,203,190, 30,163,182,188, +190, 88,144, 55, 6,137, 56,193, 46,142, 16, 49,203,145, 29, 32, 8,179,147,224,143,203,233, 48, 88,147, 86,223,198,238,157,142, +253,169,126,241,236,198, 57,232,218,190, 5, 8,203, 0, 28, 13, 69,175, 5,248,109,237, 36,116, 13,244, 5,225,104,128, 99, 96, + 55,248,107, 12,110,235, 72,238,100,213,109, 28,108,127, 47,184, 52,113,115,191,187,117,235, 54, 15,175,230,109, 40,142, 49, 35, +238,207, 51, 19,222, 93,184,164, 95, 16, 10,219, 90, 98,182,218,123,226, 13,223,166, 1, 11,230, 46, 91, 35,244,244,242,177,229, +104, 35,147,241,232, 94,199,111,190, 92,114, 88, 34, 72, 94,125, 91,141,109,150,222,203,109,148,152, 46,146, 73,199,218,200,109, + 91,234,116, 69, 15, 88, 51,125, 80, 32, 22, 13,250,234,235,117, 29, 66, 6, 12,177, 99,139, 50, 4, 52,135, 54, 7,246,239,107, +242,237,134,239,135,220, 85,179, 47, 1,224,172, 57,102,142, 96, 97,252,206,105, 67,196, 34, 33, 21, 56,117,171, 16, 96,234,100, +180, 2,221,241, 10, 69, 80,107,247, 18,132,194,197,123, 89,216, 91,151,125,180,118,199, 15, 20,129, 63, 40, 28,162, 8,246,197, +100, 35,139,207,242,120,120,158, 45, 4, 2,193, 89,142,227,250, 54,176, 49,120,158, 16,114,153, 63,187,255,223, 88, 23,209,162, +240, 89,116, 66,170, 51, 88, 51,130,252,155,127, 10, 88,103,180,228, 66,225,142,171,247, 51, 61,192,152,177,245,243, 89,251, 77, + 52,192,208,102,176, 12, 13,150,161,193, 48,102,176, 52, 13, 66, 27,177,228,199,179,128,169, 8,157,218,182,218, 1,176,158,150, +238, 67, 76, 4,187,174, 71,158,113,161, 76,133,216,187,113,197,219,169,217,197,111, 71,220, 86,229,180,113,215, 47,142,201,194, + 79,214, 24,130,179,155,230, 96,247,209, 19,105,235,127,208,198,114,132,192,197,193, 38, 96, 66,104,180,207,206,227,103, 83,215, +237, 48,196, 2,128,163,173, 52, 96,242,237,251,190,245,185, 8,238,114,249,186,205,223,127,235,225,233,106, 67, 49,151, 86,130, + 97, 89,248, 52, 25, 42, 92, 60,123,130,231,103,107,183,173,133,198,248, 90, 77,219, 7,184,163, 77,211,102,129,243,118,156,184, +228,171,213,100,153,206,236,249, 32, 1, 70,208, 30,222,129,226, 79, 87,172, 17,126,248,254,156,247, 76,108,218,149,184, 44,196, +212,150,215, 4,186,227,248,138,149, 95,183,239, 55, 56,212,142, 43,206, 22, 26,180,197,254, 91,127,220,182,172,117,251, 46,138, + 94,109, 27, 75,178, 14,206,160,244, 69,121, 48, 11,228,178,126, 65,253, 29,244, 19, 95,166,183,110,223, 61, 59, 38, 11,223, 88, +115,204, 44,249,235,222,227,184,186,247,186, 78, 17,244,186,121,249,236,116, 86,117, 21,132,165, 1,214, 92, 62, 7, 75,131,112, + 37,243,174, 51,126, 4, 80, 55,163, 37, 32,120, 49, 34,242,170,103,102,134,186,243,218,175,191, 88, 76,174, 94,253, 21, 44,118, +221,203,195,121,107, 13, 38, 0,127, 63, 87,225,105,154,133, 49,181,128,245, 47, 91,216,207, 95,214,221,211,142,122, 33,165,144, +186,112, 49, 65,127,158,207,154,120,120,254,149,136, 9, 67, 8, 17, 53,176,230, 16, 66,200,201,122,202, 44, 0,240, 70,233,231, +109, 0,190,106,128,164, 53, 6,224, 81,250, 57, 3, 64, 26,127, 7,212,139,199, 43,191,215,185, 31, 45, 57, 8, 7, 28, 26, 1, + 0, 54,214,166,130, 0,114, 80, 66,128,214, 98,248,224, 1,112,115,247, 0,104, 29, 96,214, 1,180, 30,160,181, 0,173, 71,142, + 58, 25, 48,107,129,196, 95,193, 16, 34,179,250,112,141,133, 64,252, 65,188,208,209, 23, 74, 71, 57,230, 12,111,227,182,229, 84, +252,182,109,103,226,250,199,100, 97,188, 69,105, 37, 4, 93,219,181,196,250,109,218,216, 95,110,100, 15, 4,128, 33,193,174,167, +186,182,105,226,179,110,135, 33,246,228,157,252, 65, 0, 48, 40,200,225,215, 46, 1,158,190, 92, 61,186,167,225, 8,233,229,213, +180, 37,197,222,220, 12, 78,147, 6,141, 70,143,180, 71, 59,225,236,253,156,128,229,208,167,182,237,109,132, 88,244,206,135,171, +196, 58, 77,166,137, 51,103,179, 74, 97,190, 80, 36,229, 40,164,159, 55, 22,115, 5,236,220,105,147,152,121, 31,127,190, 8,192, +132,154,116,218,184, 99,246,234,213,235,218,245,232,212,218, 61,227,240, 28,170, 56, 63, 19,140, 80, 33, 27,222,173, 7,156, 90, +181,225, 50,207,173,166,164,205,251,195,201,181, 57,210, 47,237, 65,210,229, 35, 84,207,142,163,100, 63,237,149, 76, 4,204, 85, + 26,173,150,110,232, 57,176,119,151,253,205,125,189, 60, 9,225,192,113, 4,132, 99, 81,108,160,177,248, 64, 34, 88,150,197,232, +129, 61, 95,176,149, 82,132,227, 56, 16,194, 33, 53, 35, 87,247,251,149,216, 23, 18,243,113,197,146, 72, 85,240,243,125,123,222, +190,126,185, 53, 29,255, 11, 58, 77, 88, 17, 75, 1,145, 21,238,185,158, 55, 78,255,212, 26,248,177,238, 94,142, 2,155,116,106, + 37,124,123, 79, 19,110,222,123, 74, 89,152,157, 62,249,240,206,239,199,108,220,188,121,119,108, 22,102, 88, 99,178,222,237, 45, +141, 92,251,187,198,181, 91,115,219,236,212, 10,113, 74, 63,103,193,192, 77, 39, 99,222,137, 90,222,181,245,135, 39, 72,193,133, + 4,195, 29, 62,223,226,225,249,103, 33,132, 52,184,217, 74, 78, 78, 86,213,199,108,121,123,123,247, 78, 79, 79,255,178,172,182, + 10, 69, 81, 95, 54,109,218,116,201, 95, 47,170,149,222,245, 10, 89,150,157,144,158,158,126,161, 38,205,161, 67,135,122,157, 56, +113,162, 89, 5,205,102, 0,154, 85,181,174,147,147, 19,219,189,123,247,164, 19, 39, 78,168,248, 59,164, 78,134,203,106,163, 21, +155,114,112, 78, 71,163,186, 24, 0, 98, 45, 88,191, 82,145,159,129,102, 87,110, 95, 54,105,101, 80, 83, 23, 20,105, 77, 56,115, + 45, 9, 44, 75,131,101,152,210,200, 22, 3,150,161, 49, 48,216, 13,221, 13, 51,240, 77, 88, 28, 24,150, 91, 81,147,230,227,152, + 9,247, 74,135,254,227, 14,112, 28,145,202,196,130, 66,127, 31, 87,247,121,163,131, 5,115,134, 7, 65,111,102,198,237, 57,151, +240,251,189, 44,108,181, 72,147,123,178,123, 34, 82,213, 50,150,169,245,216,107,136, 70,117,237, 31,210,203,129, 24, 11, 65,231, + 36,162, 72, 71, 35, 49,151, 70,134,161, 0, 50, 74,109,145, 38, 71,208,190,177,183,167,226,143,253,239, 63,114, 21,106, 68,238, + 66, 70, 34, 21, 48, 96, 57, 34, 36, 5, 49, 70,151,214, 3,196,101,245,182,106, 74,167,141,194,126, 82,239, 23,135, 58,166,236, +153, 70,217,248, 15,132,123, 71, 31, 60,186,176, 29, 89,215,194,144,171, 74,162, 28, 12, 5,104,228,218, 2,131, 39,140,199, 87, +227, 59,163, 72, 83, 4,161, 58,193, 81, 42,150, 57, 1,230, 42, 53, 9,139, 9,171, 87,125,238, 41, 18, 10, 74,206,103,217,196, +210,208, 27,141, 0,203, 64, 46,226, 64,145,178,223,104,176,180, 89,209,126,212,251,179, 0,246, 74,109,199,126, 47, 11,123,219, + 40,209, 11, 28,221,154,208,122, 80, 64,100, 76,246, 95,230, 39,208, 29,175, 60, 55,112, 74, 47, 66,225, 98, 93,174, 81, 91, 87, +132,118,106,102,103,107,171,137, 69,218,161,183,145, 0, 57,105,212,227, 13,188, 50,117,182, 98,203,150, 45,195, 0, 50, 19,149, +235,168,149,107,182,110, 36,156, 78,179, 88, 2, 0,122,154,108,183,151, 82, 83, 87,239,139,114,133,240,175, 17, 30,202, 34, 89, + 9,185, 92,190,249,236, 71,113,207,207, 11, 11,105,119, 51, 36,149,162,100, 41,231, 31, 24, 11,173,185,151,172,132,215,228, 53, +255,118, 77, 7, 7, 7,191,166, 77,155, 46,161,105,186,183, 68, 34,105,100, 54,155,193,113, 92,134, 84, 42,189,152,148,148,180, + 92,163,209, 60,252,175, 29,251,237,219,183,173, 49, 91,181,106,138,197, 98,196,197,197, 61,176,194,108, 69, 60,182,253,174,200, +200, 72, 28, 56,112, 0, 0, 16, 31, 31,143, 86,173, 90,217, 86,181,225,163, 71,143,108, 67, 66, 66,118, 1,240,169, 73,243,206, +157, 59,126,191,252,242, 11, 14, 29, 58, 4, 0,136,139,139,131,191,191,127,149,137,137,140,140, 20,190,250,234,171,126, 0, 84, +255,192, 53,122, 22, 76, 86,197,249, 95, 70, 43, 44, 44,140,132,134,134, 82,143,127,174,130, 68, 95,103,105, 71, 24, 88, 0, 72, +180, 54, 5,247, 50,177,106,253,206,211,131,126, 59,180,161,183, 92, 34,192,210,173,243, 82,179,243,138,158, 23, 81, 37,197, 47, + 12,129,192,217, 78, 26,181, 98,114,176,111,126,177, 1, 63,255,153,126, 33, 38,203,186, 16,105,140, 26,225, 0,231, 84,242,141, +133, 65,159,229, 63,249,171,240,125,251, 22, 13,106, 63,119,120,123, 28,191,148, 52, 23, 96,106,237,245,157,112, 28, 8,199,148, + 87,126, 47,125,117, 0,184,202, 3,248,114, 32, 37,203, 56,235, 34, 90,125, 0, 81,190, 59, 6,219, 43,164,223, 77,159,254,166, + 3,157,125, 31,121, 38, 9, 82,243, 13,200,208,139, 81, 44,114, 71,122,236, 29, 86, 64, 33,188,214,144, 11, 5, 13, 97, 12, 78, +206, 82, 59, 65,219, 1,179,188, 53,167, 62,200,151, 82,140,208, 97,228,103, 78, 57,191,173, 73, 98,180,217, 90,138, 66,173,221, +207, 59, 58, 58,181, 50,228, 38, 9, 11,243,115,224,228, 17,132, 65,227, 66,241,201,208, 54, 40,210,104,145,157, 23, 69, 90,122, + 58, 80,201, 23,119,227,195,193,129,200,205, 84,195, 72, 3,148,214,152,103, 48, 25,138,171, 61,143, 2,108,126,119,254,194, 87, +154,120, 42,109,203, 26, 21, 16,142, 69,112, 96,115, 12,232,221, 21,225,145,127,224,234,157,120,112,165,141, 10, 8,199, 33, 45, + 43, 63,211, 96,102,183, 91,117, 66, 89, 6,132, 54, 84,105,196, 80,135, 34,195,182,238, 80,176,192,199,157,253,236, 95, 95, 20, +218,196,222, 86, 70,193, 64,179, 48,152,104, 20,253,241, 29, 92,155,182,131, 66, 46,167, 58, 66, 47,186,129,170,207,173,129,198, +146,135,234, 2, 79, 20,103,224,213, 1, 65,239,236, 88,241,150, 45, 37, 47,185, 53,105,182,114, 36,235,143,101,157, 79,191,250, +233,177,179, 7, 14,190,236,245,213,130, 73, 33, 3,223,219,126, 22,192, 41, 62,223,226,121, 26, 25, 51,102,140, 60, 51, 51,243, +156,143,143, 79,155, 1, 3, 6, 40,122,245,234, 5,173, 86,139, 51,103,206, 64,171,213, 54,241,241,241,105,114,230,204,153, 81, + 41, 41, 41, 49,141, 27, 55, 14, 57,116,232,144,197,117,104, 75, 13,144,176, 60, 11, 6, 24,138,162, 80,186,140, 42, 93, 86,231, +113,110,165, 82, 41,146,147,147, 27, 60,178,149,158,158,254,160, 46,145,173,226,226, 98,137,183,183, 55,148, 74, 37, 88,150,133, + 86,171,197,177, 99,199, 80, 88, 88, 8,142,227, 96, 99, 99,131,207, 86,111, 69,236,141,115,184,114,229, 10, 10, 11, 11, 37,181, +105,166,165,165, 81,193,193,193, 48, 26,141, 96, 24, 6, 6,131, 1, 17, 17, 17,229,223, 69, 34, 17, 22,126,186, 22,241,215,206, +225,230,205,155, 72, 75, 75,251, 71, 70, 27,177,194,139,252, 23,169,182,207,172,127,188,213, 33,203, 50,139,183,236,216, 23,181, +120,198,120,204,126,185,191,207,242, 13, 71,250,223,203,193, 14, 0, 8,116,195,228,137,125, 91,250, 58, 41,196,248,100,207, 53, +128,144,197,245,221, 95,116, 30,226,219, 52,226,230, 30,189,146,124,238,131,241, 29,209,220,211,161, 85,190, 52, 79,154,152,104, +193,152,130, 28, 3,103, 59, 89,192,144, 96,215, 83,224, 56, 56,217,203, 90,131,101,224,100, 39, 11, 24, 20,228,240, 43, 0, 56, + 40,196,173,171,138,124, 85, 71, 39, 31,241, 52,133, 76, 52,205,214,222,201,247,181, 97, 3,108,134, 12, 27,101, 99, 39,102,144, +123,229, 12, 52,226,198,160, 93,154,192, 72,231, 33,237, 97, 2,251,219,229,123,233, 57, 69,198,121,181, 38,147,224, 66,250,195, + 56,165, 95,251, 1,206, 57, 97, 31,102,249, 77,217,211, 76, 0, 78, 80,180,123,100,166,173,123, 23,155, 63, 19, 31, 22,115,164, +202,136, 78, 37, 52,133,133, 73, 52, 11, 79, 61, 43,178, 79, 56,251, 19, 22, 13,110,135,252,188, 44, 24,204, 12, 10,245,140,217, +195, 73, 46, 51, 62,188, 11,163,153,129,137,230, 32,118,242,198,153,168, 59, 57, 28, 77,255, 90,157,102, 98, 46,110, 38, 30,187, +105, 87,113, 89,115, 55, 4,191,239, 96,115, 19,180, 30,201,105, 42,236, 56, 17,213, 49, 49, 23, 55,235,115,157, 9,199,148, 20, + 63, 87,136,100, 81, 4,189,234, 82, 9,190,181, 59,186, 72,228,146,111,191,156,251,106,155,110,254, 46, 50, 46, 45, 10, 20,103, +134, 45, 43,130, 94,202,194,209,167, 57, 56, 83, 17,209, 25, 12, 5,209, 64, 77, 23, 95, 8, 0,196,172,197, 87,147,130,108, 41, +231,230, 96, 19, 79, 65,212, 97, 26,232,210,104,127, 66, 46,119,199,124,246,163,216,238,243,127,233,243,105,120,223,123,170, 19, + 75,239,121,143,249, 46, 24,216,222,148,127, 92,243, 60,141, 4, 4, 4,120,164,167,167, 71,207,159, 63,223,101,228,200,145, 56, +122,244, 40, 52, 26, 13,182,111,223,142,117,235,214, 97,217,178,101,160,105, 26, 91,182,108, 81, 28, 62,124,184,203,247,223,127, +159,230,235,235, 27,148,146,146,146, 81,139,193,162, 0,200, 0,136, 75,159, 93, 20, 0,238,228,201,147, 24, 50,100, 8, 78,158, + 60,201,149, 46, 99, 81,242,242, 83,167,177, 63,165, 82, 41,164, 82, 41, 10, 11, 11, 27,196,108,137,197, 98,216,217,217, 65, 42, +149,162,168,168,200,106,179,197, 48,140, 48, 45, 45, 13,133,133,133, 24, 48,108, 24,214,174, 88,129,190,125,251, 98,192,128, 1, + 32,132, 32, 34, 34, 2,253,123,180,197,248,151, 66,112,239,222, 61, 48, 12, 99, 81,122, 51, 50, 50,144,153,153,137, 65,195,134, + 97,235,247,223,163,107,215,174, 8, 8, 8, 0,195, 48, 56,119,238, 28,198, 12,236, 1,249,136,254,136,143,143,231,111,106,203, +163, 89, 13, 82, 71,171,222, 68,103,227, 50,119,252,124,216,203, 3,187,132, 14,235,217, 6, 91,247,255,246, 57,148,154,125, 0, +224,106,148,125, 54,169,111,115,196,164,228,227,183,155,170,176,123, 57,104,144,214, 26, 28, 11, 55, 87, 7, 5, 32,148, 66,111, +230, 24,135,196,218, 43, 48,115,132, 64,209,251,125, 76, 28, 22,227,211,181,141,143, 79, 89,171, 67,187, 33,107, 48,249,206, 3, +223,206, 1, 30,190, 96,105,128,165,225, 48,126, 15,240,169,109,173,233,232,209, 76, 26,254,238,156, 57,221, 7,143, 24,103, 35, + 85, 56,130,213,164,130,206,184,131,220,251, 23,160, 85,180, 66, 70,114, 34, 14,156,190, 82,120, 63, 45, 87, 35, 16,224, 76,102, +161,113, 65, 98, 62,138,107,211, 53,208, 88,177,228,195,121, 67, 15,236,219,111, 47,107,222,147, 74,248,110, 72,161, 84,196,200, +148,205,158, 19,232,228,110,228,139,237,251, 29,180, 38,172,172, 77, 71,167,213, 28,137, 56,115,106,124, 75,191,158,246,143,174, +158,128,222, 96,132,145, 6,130,186,132,128,101,137,148, 18, 80,156,131, 80, 72,101,229,230,131,162,217,204,139,183, 30,169, 35, +111, 37, 10,141,246, 88, 89, 99,239, 34,143,187,123, 74,248,206,176,144, 14, 0,173,199, 75,189,219, 97,237,238,223,222, 6,216, + 41,245,187,200, 37, 17, 45, 2,244,108,163,196, 38, 66,208,243,218,177,117,173, 59,141,120, 23,214, 68,180,130,220, 48, 56,208, +207,235,167,181,159,189,239,226,218,184,149,144,226,104, 16,143,246,128, 38,141, 80,105, 81,112,244,238, 10,214,171, 7,182,124, +243,117, 49,199,145,125,168,161,107, 11,150, 3,184,148,243, 96, 99,143, 34, 49, 49, 17,110, 77,174, 1,148, 0,164,233, 35,152, +153,146,205,140,102,114, 98,253,246, 95,250, 46,232,183, 34,104, 88,107,145,111,212,173,132,172,113, 83,189, 20,207,251, 10,253, + 99,212,182,130, 28,173,150,227,243, 47,158,167, 9,131,193,112,100,213,170, 85, 46,161,161,161,101, 17, 25, 68, 69, 69, 97,219, +182,109,176,181,173,156, 79, 14, 25, 50, 4,132, 16,151,165, 75,151, 30, 1,208,173, 58,205,238,221,187, 15,187,121,243,166,170, + 67,135, 14,137,165,102, 75, 2, 64,112,247,238, 93, 65,106,106, 42,229,236,236, 76,188,188,188,104,149, 74,197, 1, 96,167, 78, +157, 42, 60,120,240, 96, 75,173, 86,123,190,174, 70, 75, 42,149, 54, 72,157, 45,177, 88, 12,138,162, 32,149, 74, 33,145, 72, 64, + 8,177,202,108,177, 44, 43, 58,121,242, 36,174, 93,187,134,101, 29, 58, 96,174,183, 55, 92, 92, 92,112,238,220, 57, 16, 66, 96, +107,107,139,188,188, 60,236,219,183, 15,253,250,245, 3,195, 48, 18, 75,116, 15, 29, 58,132,235,215,175,227,211, 78,157, 48,215, +209, 17,118,118,118,136,136, 40, 41, 13,148,201,100, 72, 78, 78, 70, 68, 68, 4, 66, 66, 66,248,155,186,158, 88,124,243,244, 1, + 68,121, 20, 60,204, 38, 61, 8, 67, 0, 10, 94,129,129,144,220,187, 87,185,114,142, 37, 8, 4,248,240,155, 29, 97, 67,215,188, + 59,140,154, 54,188,163,215,242,159,206,206, 4,128,215, 71,251,123, 43,100, 34,172, 63, 30, 67, 4, 2,124,216, 16, 7, 24, 24, + 8, 9,149,139,153, 3,186, 6, 64, 85, 96, 66,130,170,224,247,123,128, 69,163, 56,255,182,102, 34,118,254,124, 46,117,221, 78, + 67, 44, 33, 4, 78,118,178,128,201,183, 19,124,127, 58,121, 61,101,245, 1, 67, 44,225, 8,156, 20,226,214, 83,238,245,168,181, +213, 97, 39, 31,241,180,247,230,205,235, 49,124,202,124, 57, 19,123, 16,166,132,211,224,204,122,104,204, 18, 20, 8, 61,144,150, +146,130, 47,182,132,165,106,180,166,241,209,217,214, 25,204,251,185, 40, 22, 81,154,145, 95,124,242, 65,248,138,207,150,218,233, + 19,207, 21, 11, 41, 70, 47,108,218, 71,244,217,178, 53, 84,145,209, 52, 46, 49, 31, 69,181,233, 24,237,177,114,213,234,111,134, +190, 57, 97, 84,172,127,171, 62,174,172,234,161,171, 65,163,201,218,115,234,186, 71,233,155, 34, 5, 0, 9,105,185,200, 46,212, + 50, 44, 67,159,183, 23, 99, 63,250, 14, 83, 0, 0, 32, 0, 73, 68, 65, 84,121,140, 37,209,193, 82,252,220,161, 12,237, 25,244, +170,210, 94, 2,125,113, 1,220,237,197, 24,216,181,197,171,244,159,241,239, 63,204,178,198,174, 61,110,180,104, 16, 90,143,203, + 43,251,181, 38, 44,221, 26, 44, 13,243,237, 93,214, 71,198, 40,204,157,221,219,206,193,217,244, 72, 0,173, 45, 96,227, 6,202, +161, 9,224,216,140, 18, 7,142,131, 42, 49,154,121,251,213, 9,185, 15,147,210,126,112,179,169,185, 88,155,230, 8,184,164,115, + 40,206, 76,192, 93,149, 25, 65, 89, 37,165,237, 14,153, 55,192,242, 61,230,240, 60,163, 36, 39, 39, 79, 90,188,120,113,100,215, +174, 93, 27,185,185,185,161, 93,187,118,248,249,231,159, 49,127,254,252,242,117, 58,116,232, 0, 66, 8,242,242,242,176,106,213, +170, 12,149, 74, 53,169,198, 23,244,232,232,216,157, 59,119,246,110,211,166,141, 89, 34,145, 20, 0,144, 21, 20, 20,200,243,242, +242, 40,131,193, 0,142,227, 56, 71, 71, 71, 86,165, 82,209,227,199,143, 55, 94,186,116,169,133, 86,171, 77,174, 79, 68,203,199, +199,231,110,110,110,110, 33, 69, 81,245,238,250,161,204,100,185,185,185, 41,139,139,139, 57, 0,249,117,233,250,129, 97, 24,116, +234,212, 9,167, 47,220,192,201,223, 46, 65,163,138,195,204, 55, 39,161, 93,187,118, 56,125,250,116,157,175, 89,112,112, 48, 78, + 69, 68, 34,242,218, 45, 36,199,223,198,219, 51,223, 68, 80, 80, 16, 78,157,226,107, 47, 88,193, 9, 84,174,155,117,226,113,163, + 21, 18, 22, 22, 86,150,245, 63, 97, 95, 91,187, 33, 88,236, 36,221,181,116,112,139, 64,241,128,165,160,196, 54, 56,216,234, 84, +143, 15,191,248, 46, 86,232,158, 60,225,110, 86,237,173,195, 42,253,105,178, 16, 77,174,196,238,189,117,175,245,171, 47,117,245, +193,214,159, 21, 31, 3,192,184, 94,126,248,243,126, 54,174,196,103,237,141,201, 70,116,125,143,186,173, 59, 20,108, 14,246,174, +122,103,120, 72,147,198, 30,216,118, 52, 18, 20,133, 35, 22, 61,112, 9, 33, 93,219, 52,193,186,157,143,183, 48,244,240, 93,125, +192, 16,123, 38,186,104, 48, 0, 12,104,173,248,181,115, 11,103, 95, 82,177,226, 86, 21,216, 72, 69,211, 7,143,154, 40,103,226, +127, 6,146, 34, 64, 49, 70,232,205, 28,212, 57, 69,208, 57,250,224, 92,212, 45,125,161,193,244,110, 76,118,221,162,120,247,114, +144, 40,185,122, 43,165, 88,171,247, 84, 40, 91, 24,132, 2,142, 43, 54, 18,252, 25,147,164,137,201, 64,156, 37, 26,137,137, 48, + 61,239,205,244,218,180,227,192, 18,177, 68, 58, 78, 72,129,114,119,178, 85,110, 90,243, 41,236,237,237,192,153,138, 1,109, 54, + 70,190,245, 69,246, 93, 21,237, 7, 0,173, 92, 97,215,203, 79,188, 67, 36,160,210,206, 38,152, 63,170,109, 31, 20,141, 25, 19, + 6,118, 16,115, 38, 45,222, 89,181, 31,155,223, 31,142,137, 47, 4,138, 79,252, 17, 63, 3,192,242,186, 94,107,194, 50, 32,180, + 30,221, 62,184, 16, 75, 1,145, 4,232,121,237,192,103,173,129, 27, 22,107,116, 4,196,172,136, 10,108,239,107, 43,225,210,254, + 0,151,246, 7, 17,250,244, 0,229,219,155,162, 60, 58,145,111,191, 92,166,221,186,117,219, 25, 78,128, 79, 44,232, 42, 3, 44, + 7,228,196, 71,194,100, 50,129,102, 1,131,193, 0,173, 86, 11,219,132, 83,229,117,180, 36, 98,106,208,156,215,134, 5,147, 98, +149,238,151, 88, 38,101,219,155,173,187,145, 98,149,238,114, 10, 27,159,163, 53,242,209, 44,158,167,145, 68,149, 74, 53,104,200, +144, 33,191,157, 62,125,218,165,109,219,182, 0,128,107,215,174,149,188,116,118,234, 4,127,127,127,100,102,102,226,229,151, 95, +206, 81,171,213,131, 80, 75,157,223,162,162,162,135,135, 14, 29,106,164,213,106, 59,124,244,209, 71, 89, 77,154, 52,209, 24, 12, + 6,170,160,160,128, 99, 24, 6,206,206,206,210, 14, 29, 58,160,123,247,238,197, 81, 81, 81, 77, 83, 83, 83,139, 0, 36,213, 37, +241,195,135, 15,199,133, 11, 37,141,246, 26,162, 95, 45,137, 68,130,182,109,219,122, 39, 38, 38,166,151, 62, 91,172,206,227, 43, + 62, 94,110,221,186,133,243, 55,210, 32, 50,233, 33,205, 86,225,242,209, 67, 24, 54,125, 22, 24,166,238, 99,203,223,186,117, 11, +199, 34, 46,195, 86, 38, 66, 92, 92, 52, 14, 29, 58,132,153, 51,103,214, 75,179,142,212,232, 69,254,227,168, 81, 77, 61, 45, 17, + 0,132,134,134,158, 47,139, 86, 84,164,121,115, 72,101,197, 88, 58,160,163,247,194,113, 61, 91, 8,105,141, 10, 28,203, 65, 40, + 6,220,221, 28,176,107,215, 94,191,189,251,247, 71,125,191,225,251,111, 56,134,249,240,110, 22,116, 86, 36,106,233,154,253,145, +227,118,205, 11, 17,205, 28,220,218, 5, 0, 36, 34, 1,214,255, 28,205, 0, 88, 90,159,163,125,222, 27,242, 98, 26,211,220, 93, + 29, 63, 94,252,198, 80,151,144, 78,254, 56,127,229, 46,190, 57, 20,117, 65,154,133,157, 22,223,220, 28,141,199,253, 83, 85,173, + 14,193,213, 94,239,146,101,137,135,196,214, 25,230,164,179,128,217, 0,131,209,140,212, 92, 22,169,121, 6,136, 20, 18, 92,139, + 79,211,187,102, 32,172, 30,135, 77,217, 42,228, 94, 75, 62, 95,221,216,160, 47,102, 52,249, 57,140, 68,122, 89,172,176,145,169, +173,169,170,112, 57, 29,134,222,205,196,207, 1,156, 80, 42, 39,186, 15,222,123,205, 54, 61,230, 52, 90, 10, 84,160, 8,129, 77, +224, 80,216,219, 8, 37, 61,155,138, 83, 0,192,214, 86, 33, 93,245,201,124,199,119,223,255,164,214, 58, 96,129,128,196,191,185, +199,187,109,155, 56,227,194,245, 88, 92,184,147, 28,125,225, 90, 92, 80,223,118, 94,240,111,236, 52, 71,154, 95,176,242, 30,172, +143,144,150, 92, 24, 6,160, 13,229,173, 14, 3,221,241, 74,231,113, 31, 85,215,218,176, 74,154, 1, 92, 60, 75, 64, 9,133, 0, + 37, 40,105, 1,153,250, 7, 68, 78,205,201,222, 3,199,116,219,182,237,252,244, 94,142,229,141, 51,104, 22,172, 70,163,129,173, +173, 45, 78,197, 51,198,137, 3, 37, 50,129, 64,128,212,248, 27,127, 85,134,119, 17,180,145,244,253,172,245, 31,203, 58,159,182, +151, 82, 50,175,161,159, 4, 50,119,118,166,213,245, 33,193,195,243, 95,160,176,176,240,246,189,123,247, 6,182,111,223,126,251, + 59,239,188, 99, 63, 97,194, 4,175, 55,223,124, 83, 0, 0,153,153,153,220,186,117,235, 84,223,126,251,109, 97, 78, 78,206, 20, +154,166, 45,233,202,132,168,213,234, 75, 63,252,240, 67,246,197,139, 23,131,186,116,233, 34,123,238,185,231, 56,103,103,103,145, + 76, 38, 99, 77, 38,147, 33, 62, 62,158, 77, 76, 76,244, 44, 40, 40,120, 0, 32, 1,117, 24,177,162, 52,122,181, 92, 40, 20, 46, + 33,132,180,109,136, 58, 90, 10,133,194, 11,192, 3,138,162, 90, 90, 91,108,248,196, 3, 91, 36, 66,126,126, 62,116, 25,209,144, +167,221, 71,123, 91, 1,218, 56,219,193,193,193,161, 94,166,168,176,176, 16,208,166, 35, 50,242, 22,192, 48,112,116,116,132,163, +163,227, 63,110,180,170,243, 34, 79, 9,211,170, 88, 86,115, 29,173, 54, 74,204,180, 49, 97,221,244,161, 45, 36,205,124, 27,195, +152,118, 13,183, 82,139,241,225,243, 93, 98,132, 50,123,195,244, 73,195, 59,141, 26,211, 20, 33,221, 59, 83,205, 60, 29,231,172, + 92,179,241,173, 54,200,153, 31,147,133,245,150,164, 40, 38, 27, 15, 57,100,109, 59,123, 59,109, 70, 99,133, 30, 28, 71,112,246, +142, 26,119,146,242,183,197,102,227,161, 53, 71,215,198, 19,253, 69, 16,236, 39,132,200, 29,109,109,139,218,248, 55,118,235,223, + 45, 88, 48,168, 79, 39, 72,132, 64,228,159,183, 48,119,205,145,203, 28, 71,134,222,176,176,216,176,164,133, 97,101, 3, 85,210, +194,144,174,212,194,144, 16, 66, 74, 90, 29,214, 28,124, 16, 10,169, 12, 93,242, 85, 15,177,107, 43,232, 19,206, 34, 41,159, 67, +114, 86, 17, 52, 34, 15, 24,211,211, 1,194,165,156,175,185, 98,117,141,184,185,185,185,251,181,241,111,241,221,142, 67, 48,235, + 10,241,240,220,118, 20,231,171,241,217,166,159, 91,120,123,187,246, 73, 79, 79, 63,111, 69,102,227,255, 91,216, 94,119, 16, 64, + 40,150,225,196,247, 7,144,227,106, 3, 55,133, 4,156, 62, 27,211,223,157,224, 56,120,192, 4, 71, 0, 72,142,187,137, 38, 10, +189, 69,186,102, 87,140, 26,215, 55,192, 9,180, 30, 59, 78,221, 52, 8,128, 65, 59,207, 68, 39,244,109,237, 36, 31,215,179,137, +243,114, 85,193,104,228,214,173, 83,209,178,136, 86,121,132,175, 14,173, 13, 15, 1,108,107, 14, 9,251, 47,101,217,142, 25,240, +156, 66, 34,162, 40, 82,156, 14, 98,227,134,141, 59, 14, 22, 75,105,235, 70, 98,231,128,229, 93, 87, 60, 92, 82,114,159, 96,251, +224, 21,215,222, 8,255,248,121,101, 70, 70, 6,204,165,101,135, 15,243,184,223, 39, 13,104,195,166, 21,114,166, 51, 43, 71,142, +161,108,148,210, 5, 95,237, 60, 71, 0,190, 55,105,158,167, 26,189, 94,127, 93,175,215,183, 91,176, 96,193, 43, 31,124,240, 65, +111, 91, 91, 91, 63, 0,208,106,181, 15,105,154,190, 80,250,255,180,166,117, 32, 1,240, 32, 33, 33,225, 97, 66, 66, 66,163,221, +187,119, 59, 1,144,151,254,102, 0, 80, 0, 32, 19,245,104,113, 88,102,170, 40,138, 90,210, 80,231,161,204, 84, 81, 20,213,178, + 46,219, 11, 4, 2,150,162, 40, 80, 20, 5,153, 76,134,139, 23, 47, 98,236,208, 1,184,119,162, 0,109,157,236,208,101,202,116, +236, 15, 15,135, 80, 40, 4, 69, 81, 16, 10,133, 86, 61, 71, 68, 34, 17, 34, 35, 35, 49,241,229, 49,144,137, 0, 71, 71, 71, 44, + 88,176, 0,199,143, 31,135, 72,196,143,210,103, 5, 91, 42, 24, 46, 11,251,209,162,176, 60,124,251, 23, 18,176, 52,126,217,254, + 53,194,238, 22,155,226,178,241, 97, 64, 54,214, 29, 66, 17,151,189,102,231,140,240,200,187, 95, 77, 29, 31,170,232,215,119, 0, +250,133,244, 21, 5,117,238,243, 49, 80,201,104,245, 71, 13,125,109,176, 28, 62,221,114, 42,118,250,254,115,241, 20,204, 69, 24, +255, 98,103,194,114,248,180,150,131,121, 66,211,209,198,110,127,100, 84,148, 51,204,197, 72,186,249,187,188,169, 95, 11,128, 53, +227,193,131,251,248,118,199, 81,238,220,159,113,187, 76, 12,222, 73,204,135,214, 82,205,146, 39, 37, 3, 71, 91,105,192,160, 32, +135, 95, 57, 16, 56, 41, 36,173, 9,199,194, 73, 33,110, 61,160,181,226, 87, 66, 8,177,183, 17,183, 38, 44, 93,171,166,222,196, +108,222,241,227,182,213,175,191,254,186,109, 78, 90, 6, 84,154,187, 40,150,122,131, 86,248, 32,225,230, 5,189,206,200, 88,242, + 16,175,246,124,230,228,228,100, 93,191,146,135,253,155, 86,128, 54, 25,145,149, 86,226, 85, 85, 57, 26, 56,184,121, 71,165,167, +167, 91,172,105,102,184,194, 81, 19,166, 73,108,236, 97, 51,113, 84,168, 52, 33,215,136,142, 94,246, 37,153, 70,113, 54,238, 69, + 68, 34,164,180,142,105, 98,170, 0, 77,130,189, 44, 74,167,189, 92,242,206,224,231,188,241, 48, 69,141,139,209,233, 59, 30,230, + 65,197,198,170,119, 36,168, 10,102, 12,127,222, 23,107,143,199,188, 13,208,123,173, 57,246, 64,119,188, 66, 8,122,150, 84,134, +215,131, 0, 61, 3,221,241,138,133, 45, 13,159,208, 20, 73,240,234,234, 95,147, 63, 58,120, 53,103,248,194, 87,123, 57,116,239, + 62, 68, 10,198,132, 34,189,145,190, 87, 0,141, 53,154, 26, 61,183, 25,192,230,178, 31,174,167,113,187,122, 45,141,186,176,247, + 77, 31,101,153, 87,191,144, 96,140, 2, 16, 53,181,171,205,199,146,190,159, 5, 68, 45,239,122,250,142,154,219,125, 33,161,188, + 15,173, 90,255, 71,117,132,215,228, 53,255, 9, 77, 22,192, 46,154,166,119, 21, 20, 20, 52,164,166, 10, 79,246,235, 84,175, 99, +175, 88, 76, 72, 8, 17,149, 70,179,106,171, 12, 95,163,102,197, 98, 66, 66,200,201,210,104, 86,109, 81,173, 74,154, 28,199,169, + 58,117,234,228, 50,108,216, 48,176, 44,139,251,247,239, 35, 57, 53, 21,253,103,188, 13, 39, 39, 39, 92,184,125, 27,113,113,113, + 88,178,100, 9,104,154,198,177, 99,199,210,106,211, 20,137, 68,230, 22, 45, 90, 72, 70,140, 24, 1,134, 97,144,152,152,136,244, +244,116,204,157, 59, 23,142,142,142,184,126,253,122,185,102, 78, 78, 14, 68, 34,145,185,138,232,214,223,113, 47, 61,237, 60, 97, +178,106, 54, 90, 0, 11,150, 70, 97,248, 82,172,191, 8,179,153, 70,235,152,108, 60,138,249, 43, 34,181, 81,120,229,246, 47,183, +239,198, 62,188,254, 71, 63, 41,178,238,192,218, 55,137,251,185, 80,219,203,139,138, 96, 46,114, 64,226,175,120,148, 89, 84,124, + 63, 23,106,171,223, 24, 56,150,130, 89, 7,168,175,225,210,133,243, 56,119,249, 22,174,222,137,101, 47, 93,143,223, 47,224,240, +233,189, 92,220,175,195, 91, 8,236,134,174,197,107,119, 30,248,118,246,111,228, 11,150, 1,225,104, 56,142,223,139, 41, 49,221, +125, 59, 55,119,242, 45,137,100,209,112,126,227,119, 96,181,188, 70,189,107,169,244, 22,233,241,211,163,139, 10,114,159,127,161, + 79, 55, 91,199,192,193,200,121, 16,143,251,183, 34,245,215,239, 38, 92,186,150, 74,111,169,207,213,245,246,246,238,253, 66,159, + 0,140,159,190, 24,102, 93, 33, 18,207,253,136,226,188, 12, 92,140,178, 67,172, 70,211, 13,128,197, 17,173,168, 20, 38, 8, 41, +249,232,209, 84,156, 98, 15,163,199,164,208, 97,144, 81, 6,112, 70, 13, 40, 93, 14, 18,210, 77,133,163, 55,165,178, 0,160,144, + 81, 34, 91, 82,232, 96, 81,228,177,137,107, 43,133,144,198,206,240,104,112, 92,201,240, 77, 28,135,141, 59,127, 79,152,241,233, +196,142,104,227,235, 28,124, 51, 61,139,130, 21, 33,127,138,160,215,213,253,159,180, 54,252,246, 49,192,153, 17, 57,199,165,117, +175,245,121,189, 80,199,225,118,238,170,144, 14, 96, 6, 68,186,205,115,214,159,250,184, 83,120, 76,207,121,111, 12,119, 0,105, +144, 22,186,241, 49, 25,108,239,174, 43,147, 79,115,164,114,121,110, 73,100, 43,144,168, 52,228,230,133, 4, 35,223, 43, 60, 15, + 15, 15, 0,160,184,184,120,250,148, 41, 83, 54,139,197, 98, 37, 0,138,227, 56,112, 28, 39,250,234,171,175,196, 44,203, 10, 4, + 2, 1, 43, 20, 10,153,147, 39, 79,210, 44,203,102, 27, 12,134,233,181,105, 50, 12,147, 48,107,214,172, 22,181,181, 80,220,183, +111, 95,153,201, 74,224,175,132, 69, 38,171,226,188, 60,202, 37,170, 33, 72,251, 73,143,137, 75,151, 2,160, 64,176, 44, 38, 27, +143, 30, 95,229, 78, 30, 84,109,132,230,185, 65,157,251, 44, 45,219,198,218,148, 25, 88,118, 76,231,118,254,251, 0,192, 72,216, +137,117, 57, 58,141, 81, 63,174, 67,231,110,251, 57, 66, 68, 12, 33,219, 4, 28, 14, 27, 24,220,179,164,165, 93,117,168,178, 10, +174, 15,110,235, 72,128,146, 34,195,242,226,194,210,110, 28, 8, 33,164,188,184,240,107, 57,114, 10,141,181,246, 3,245,199, 35, +211, 0, 19,115,117,218,153, 63,110, 78,103, 89,226, 33, 20, 82, 25,122, 19,179,185,190, 38, 11, 0,210,211,211,207, 71,132,167, +159,185, 29,220,232, 69, 55, 69,105,148, 75, 7,228,232,112, 38, 61,187,248,124, 93, 52,243,181,244,240, 15,214, 29,255, 89, 42, + 22,138, 64, 72, 73,135,162,132,192, 96,102,243,162, 82,152, 32, 0,104,231, 2,175, 5,199,152,125, 66, 33,149, 92,155,222,149, + 56,245,218,241, 43, 35,230, 71, 39,229,111, 75, 42,192, 93, 0, 72, 42,192,221, 3,145,143, 62, 78,200, 40,154,127, 55, 57,255, +107, 88, 89,175,130, 80,184,216,121,252,210, 39,150,213,247,124,198,170,113, 11,192, 72, 32,109,192,248,121,223,206,163, 40, 52, +212,240, 19,241,122, 51,105,242,248,194,178,200, 22,159, 87,241,240,252, 55, 40,139,106, 9, 4,130,229, 13,168,121,146,162,168, + 33, 0, 30, 88,177,217,149,226,226,226,118, 13,124,120,185, 12,195,228, 90,178,226,191, 80, 33,254,105,101,203,191,181,227,254, +188,230, 63,175,217,178,101, 75, 98,133, 97,225,207, 39,175,201,107,242,154,255, 87,154,132, 16, 97,125,166,106, 52,169,250, 76, +252, 53,122,234,153, 86,221,119,190,166,219, 51,200,131, 7, 15, 40,254, 44,240,240,240,240, 84, 13, 69, 81,236,223,160,201,247, +142,199, 83,102,176, 42, 69,183, 4,252, 57,225,225,225,225,225,225,225,225,105, 16,147, 85,113, 94, 98,194, 81,125,248,207,154, +214, 4,117, 9, 33, 70,240,154,188, 38,175,201,107,242,154,188, 38,175,249,127,167, 89,155, 54,223,154,241,111, 54, 96,188, 38, +175,201,107,242,154,188, 38,175,201,107,254,255,105, 62,205, 84, 91, 71,139, 47, 58,228,225,225,225,225,225,225,225,249,155,224, + 43,195,243,240,240,240,240,240,240,240,212,143, 90, 7,149,230,225,225,225,225,225,225,225,225,169, 27, 53, 15, 42,205,195,195, +195,195,195,195,195,195, 83,103,172, 31, 84,154,135,135,135,135,135,135,135,135,199, 34,182,240,167,128,135,135,135,135,135,135, +135,231,159,161,114,171,195,176,176, 48, 82,113,206,195,195,195,195,195,195,195,243, 79,242,172,122, 17,190,232,144,135,135,135, +135,135,135,135,167,126, 76,227,141, 22, 15, 15, 15, 15, 15, 15, 15,207,223, 67,181,117,180,202, 58, 44, 13, 41, 13,213,133,240, +231,138,135,135,135,135,135,135,231, 95,224,217,246, 34,124,253, 44, 30, 30, 30, 30, 30, 30, 30,222,139,240,240,240,240,240,240, +240,240,240,252,151,224,199, 58,228,225,225,225,225,225,225,225,249,135, 13,215,223,110,180,248,145,205,121, 77, 94,147,215,228, + 53,121, 77, 94,147,215,252,127, 50, 89,149,204, 22,223,234,144,135,135,135,135,135,135,135,167,126,212,218,234,144,135,135,135, +135,135,135,135,135,167,110, 76, 3, 16, 90,250, 57, 20, 21,162, 90,124, 68,139,135,135,135,135,135,135,135,167,126,108, 1,224, + 89,106,176, 78, 0, 80,243, 70,139,135,135,135,135,135,135,135,167, 97,168, 88, 47,107,104, 5,243,197, 27, 45, 30, 30, 30, 30, + 30, 30, 30,158,122, 82,109, 29, 45, 10,213,183, 28,136,176, 98, 7,117,105,125, 16,193,107,242,154,188, 38,175,201,107,242,154, +188,230,255,157,102,109,218, 17,120,250,152,102,141,249,106, 72,248,166,175,188, 38,175,201,107,242,154,188, 38,175,201,107,254, +223,210,224,173, 14, 59, 2, 54,252,105,125, 38,105, 84, 58,241,240,240,240,240,240,240,212,204,223,211,234, 48, 16,120, 99, 66, + 91,229, 38,250,110,182,195, 93, 64, 87,211,186, 74,165,114,179, 66,161,152,160,211,233,180, 20, 69,113,101,203, 9, 33, 0, 80, +113,172,163,196,236,236,236, 94,181,237, 91, 42,149,174,107,212,168,209, 27,197,197,197, 58,138,162, 8, 69, 81,160, 40, 10, 0, +158,152,179, 44,155,150,155,155,219,233,169,190,132,132, 8,221, 26, 53,250, 83, 44, 20,122, 91,187, 41,203,113,143,178, 50, 51, +187, 89,177,201, 10,138,194,194,146,221,226, 75, 0,139,159,181,127, 4, 1,132,150,172,215, 22,176,143, 7,198,179, 2,193,219, + 98, 96,131,145,227, 54, 1, 0, 5,176,117,221,183,241, 10, 90, 80, 4,193, 20, 5, 71, 66, 80, 72, 40,220,146,117, 69,194,191, +116, 42, 70,137,197,226,225, 14, 14, 14,118,185,185,185,231, 1,236, 3,240,178,171,171,107, 31,141, 70, 83, 76,211,244,113, 0, + 71,234, 34,220, 43, 24,239, 75, 37,226,169, 6, 51,189,234,143, 91,248,177, 79, 71,184, 50, 28, 86,202, 37,162, 94, 70, 19,243, +101,228,109,108,179, 82,146, 42,157,202,242, 12,171,199, 72, 59,104,225,117, 7,128, 99,206,206,254, 50,165,195,111, 98,169,240, + 81, 65,102,241,132, 49, 89, 89,169, 99,235,113,221,255,139,184,185,185,189, 38, 16, 8, 62, 39,132,128,101,217, 15,243,242,242, +182, 55,144,244,135, 0,156, 74, 63, 23, 0,248,188,158,122,201, 0,124, 75, 63,167, 0,104,194, 63,215,235,204,198,163, 71,143, +206,232,219,183, 47,214,174, 93,139,141, 27, 55, 38,101,103,103,175, 4,176, 3,128,233, 95,208,225,169,142, 54,192,144,175, 6, +118,101,233,159, 62,229, 42, 44,238, 95,205,159,249,135, 73,147, 38,153, 9, 33, 36, 46, 46,142,152, 76, 38, 66,211, 52, 97, 24, +134, 48, 12, 67,104,154, 46,159,188,189,189,211, 31,219,252, 9, 77,129, 64,176,126,244,232,209, 69,132, 16,114,237,218, 53,162, +215,235,137,209,104, 36, 38,147,137, 24, 12, 6,162,215,235, 43, 77,141, 26, 53,202,172, 73,211,193,193,225,154,179,179,115,166, +179,179,115,166,139,139, 75,166,139,139, 75,166,171,171,107,249,228,230,230, 86, 62, 41,149,202, 76,165, 82,153,233,226,226,114, +173,182,116,150, 50, 16,192,121, 11,166,129, 85,108,219,191,162,209,242,244,244,204, 36,117,160,113,227,198,169, 22,164,179,140, + 70, 20, 5,182,108, 91,138, 2, 39,147,201,124, 43,254,142, 39, 35, 93,181,134,148,189,188,188, 70,123,122,122, 70,120,122,122, +134,123,121,121,141,182,224, 22,171,164,105,111,111,127,205,205,205, 45,211,195,195, 35,171,108,242,244,244,172, 52,121,121,121, +149, 79,141, 26, 53,202,116,118,118,174,246, 26, 17, 64, 88,221,116, 14, 16,201,128,126, 34,161, 48,172, 81,163, 70,154, 59,119, +238,176,132, 16, 34, 16, 8,210,203,214,177,230,216, 31, 55, 89,186, 72,124,152,115, 86,118,165,248,209,202,194,156,179,178, 43, +186, 72,124,104,188,130, 22,117,213,180,144,170, 52, 39, 79,158, 60,249, 86,102,102,102,122, 65, 65,129,122,211,166, 77,241,114, +185, 60,114,211,166, 77,241, 5, 5, 5,234,204,204,204,244,201,147, 39,223, 2, 48,203, 10, 77, 0, 64,183, 96, 60,255,250, 40, + 79,221,173, 99, 19,117,253, 58,139,110,246,104,139,208, 1,221, 36,233,223, 45, 10,212, 93,216,218, 83,215,247, 57,193, 93, 43, + 53, 41,145, 72,212,221,215,215,119,170, 82,169,156, 84, 58, 77, 44,155, 60, 60, 60, 38,122,120,120, 76,116,118,118, 30, 91,147, +230, 65, 64,104,201,228, 35,151,119, 31,235,231,171, 75, 94,190,140,220,121,247,109, 50,181,185,143,102,140,187,123,211,127,225, + 26,253,173,154,238,238,238, 42,154,166,137,217,108, 38,174,174,174,170, 6, 76,231,215,132,144,175, 9, 33, 95, 3,248,186, 1, + 52,203,243, 51, 43, 12,118, 77,154,114,145, 64, 48, 79, 33,149,134,203, 68,162, 44,153, 72,148,165,144, 74,195, 69, 2,193,124, + 0,242,255,210, 53,250, 27, 52,237,148, 74,229,195,117,235,214, 17,157, 78, 71,116, 58, 29, 89,183,110, 29, 81, 42,149, 15, 1, +216, 89,161, 89, 87,157,103, 41,130,245,248,212,112, 17,173, 64,160, 83,191,224,150,135,231,188, 54, 30,220,161,117, 84, 45,111, + 76, 63,116,235,212,105,234,142, 29, 59, 0, 0, 19,134, 15,199,139, 93,186,192,222,206, 22, 82,105, 73,114, 40, 66, 65, 34,150, + 96,196,220,247, 44,217,253,151, 35, 70,140,120,245,208,161, 67,118, 0,176,113,227, 70,140, 26, 53, 10, 46, 46, 46, 80, 40, 20, +144, 72, 36, 16,139,197,149,230,181, 33, 20, 10, 27,167,167,167,187,203,229,242,242, 40, 27,199,113,149, 38, 66, 72, 89,244, 13, + 12,195,160, 85,171, 86,150,158,174, 69,133,133,133,189,181, 90,109,185, 70, 85,147,159,159, 31, 0,156,182, 68,240,243,207, 62, + 5,199,104, 33, 18, 1, 12, 3, 24,205, 2,112,164, 74,115,131, 89,179,102,149,167,187, 46, 12, 29, 26, 74, 81, 20,117,232,250, +245,235,135,179,178,178,154,113, 28,251,102, 29, 35, 93,111,221,191,127,223, 14, 0,252,253,253,103, 1, 56,108, 77, 58, 68, 34, + 81,227,219,183,111,187,203,100,178,106, 35,151, 21, 34,152, 48,155,205,232,216,177, 35, 99,205, 62, 26, 1,190,121, 2,193,155, + 29,158,123,110,218,210, 17, 35,228,127,254,249,167, 92, 32, 16,128, 97, 24,124,245,213, 87, 12, 33,196,169, 13,224, 16, 3,104, +106,144,249, 0,192,107,165, 15,131,109, 0,190,170,228, 22, 8,130,245,180, 44, 52,177,120, 68,151,174, 77,223, 71, 76,244,157, + 46,205,237,142,193, 94,100, 76, 0,254,217,168,150,131,131,195,240,181,107,215, 42,183,109,219,166,137,139,139, 51,111,218,180, + 73, 57,125,250,116,123,179,217,140, 25, 51,102,100, 7, 4, 4, 72,214,174, 93,171, 60,114,228, 72, 63,173, 86,251,189, 85,215, +139,194,167, 47, 15,127, 17, 6, 90, 0,154,102,148,158, 74,251, 93,115, 38,135,136, 9, 49, 97,231,241,235,160, 25,238, 71, 43, + 35, 89,221,198,140, 25,211,124,239,222,189,162,216,216, 88, 81,235,214,173,193,113, 28, 88,150, 5, 77,211, 0, 0,142,227,208, +178,101,203,122,159,151,169,128,191, 91, 35,151,240,110, 67, 6,219,120,202,101,112,201,207,198,235, 18,145,253,118,133,113, 55, +128,238,207, 84,100,151, 16,136, 68, 34,164,166,166,194,221,221,221,134,227, 56, 53,128,101,249,249,249, 91,240,236,210, 69, 42, + 18, 29,222,249,227,122,143,174,221,187, 11, 27,121,186, 35,254,126, 10, 68, 20,219,255,246,213,235, 33, 83,103,206,155, 99, 98, +152,209, 0,254,124,214, 14,220,163,251,172,145,148, 64,184,145, 34, 28, 62,249,238,231,162, 21, 95,174, 83,204,120,115,178,112, +238,220,185,240,241,241,105, 54,114,228,200, 47, 1,204,172, 85,167,235,172,145, 16, 10, 54,130, 16, 44,253,246,231,162, 47,190, + 92,167,152, 89, 7,157,167,156,106,255, 35,245, 54, 90,129, 64,243, 32, 31,247, 51, 43, 22,206, 20,147, 95,127, 18,232,114,179, +170, 93, 87,169, 84,110, 30, 52,104,208,132,237,219,255,138, 70,119,107,219, 22, 35,251,245,132,187,171, 35, 20,182,210,146,199, + 17, 71,225, 86,220, 35,139, 12,129,143,143,207,140,195,135, 15,219, 85, 52, 19, 18,137,164,124,170,104,178,202,166,178, 7,112, + 77,200,229,114, 68, 68, 68, 64, 36, 18, 65, 40, 20, 66, 36, 18,149, 79, 21,191, 11,133, 66, 52,106,100, 85,213,165,149,142,142, +142,237,139,138,138, 28, 10, 10, 10,224,235,235,171, 1,112,187,194,239,237,179,179,179, 29,172, 17,228, 24, 45,230,190, 30, 8, +177,233, 50, 76,226, 46,208,139,122,224,210,213,123, 8, 59,125, 30,233,170, 12,244,124,190, 3, 38,189, 50, 6,225,225,225, 96, + 89,171, 75, 58, 50, 9,193,151,195,134,133,190, 15, 80, 84,255,254,253, 11,102,207,158, 45,136,141,141,125,117,228,200, 17,109, +239,223,127, 80, 26, 85,164, 22, 18,130,245, 0, 50, 45,212,149, 2,192,133, 11, 23, 0, 64, 86,151,123, 79, 38,147, 33, 42, 42, + 10,101,197,196, 2,129, 0, 2,129, 0, 66,161, 16,191, 60,112,131,214, 36,128, 46,243, 46,222, 14,245,133,159,159, 31, 4,130, +218,171, 36,134, 0,242, 75,192, 72, 74, 44,158,235,233,229,213,172, 79,243,230,138,136,136, 8, 33, 0, 52,105,210,132,168,213, +234,130,227,199,143, 23,137,128,141, 77, 8,217, 81,147,201,242,241,241,233,145,158,158,254,121,217, 57,167, 40,234,203,166, 77, +155, 46, 41,191,110, 28,135,101, 63,106,197,115,230,188, 43,233, 26,242, 17, 0,160,235,176,189,208, 36,174, 8,164,242, 62,112, +252,167,115, 9,141, 70,179,191,101,203,150,194,220,220,220, 75, 0,146,105,154, 94,180,107,215, 46,247,215, 95,127, 61,107,247, +238,221, 43, 1,120,173, 90,181, 42, 68,171,213, 30,176, 70,183,103,123, 12,121,174,125,219,231,125,125,124,112,254,210,159,144, + 72,197, 78,179, 94, 11,133,157,157, 8, 95,111, 59,193, 37,167,229,205,142,188,141, 29, 86,152,172, 46, 99,198,140,105,182,119, +239, 94, 41, 0,220,190,125, 27, 25, 25, 25, 80, 42,149,176,177,177,129, 88, 44,134, 80, 40,132, 88, 44,110, 16,147,229,232,227, +122,229,216,177,227, 54, 46, 46, 78,248,238,189, 57,152,148,149, 9, 39,123, 59,208,197,218,102,207,216,131,194,191, 87,175, 94, +114,150,101,161,213,106,113,238,220, 57, 71, 27, 27, 27,199,198,141, 27, 47,133, 21,173,167,228,114,121,166,193, 96,112, 47,253, +156,101, 48, 24, 26, 1,208,200,100,178,178,124,186,184,116,110,105,113, 98, 50,158, 44, 38, 76,161, 40,170,226,178,186,210,185, + 75,231,246, 17, 71, 14,237,177, 43, 44,202,128,147,115, 22, 4, 40,196,150, 45, 27, 96, 99,227,128,165, 75, 63, 16, 61,234,223, +207,123,224,144,209, 17,209,247,226,251, 63,115,102,139, 80, 91,250, 15,155,224, 98,163,176, 47,125,150,208,216,190,117, 14, 4, + 2, 1,150, 44, 89,130,160,160,160,105,209,209,209, 31, 1,200,171, 89, 6, 91,218,245, 30,231, 34,149,151, 92, 98,142,165,177, +105,223,252, 18,157,197,211,241,242, 48,191,105, 11,198, 60, 60, 21,212, 28, 69,165, 47,230,122,177, 0, 41, 84, 87,148, 27,134, +176,176,176, 62,161,161,161,231,171,251,254, 20,224,137,191,250,207,170,100,190, 68, 97, 97, 97, 36, 52, 52,148,170,112,112,149, +190,215, 68, 48,224,230,236,168,136,216,184,108,142,157,232,242, 9,161, 62,229, 1, 84,134, 74, 15,242, 74, 77, 52, 21, 10,197, +132,237,219,183, 87, 10, 41,249, 54,114,135, 68, 34,134, 88, 66,193,169, 87, 73,239,245, 5, 23,195, 64, 81,213,154,172, 74,154, + 90,173,214,112,243,230, 77,187,109,219,182,193,221,221, 29,205,154, 53,131, 66,161,128, 92, 46,175,100,174, 42, 26,174, 42,140, + 86, 37,205,178,223, 69, 34, 17, 4, 2, 1,194,195,195,193, 48, 12,198,140, 25,243,132,201, 18,137, 68,213, 25,183,234,154,167, +158, 6,112,155, 16,210,187,244, 1,124, 27, 64,159, 10,191, 15, 84, 42,149,139, 0,172,180, 84, 83, 40, 36, 16, 26, 46,129,107, +188, 14,162,212, 57, 48,137,131,113, 54,242, 58,182,111, 94, 11, 0,104,214,186, 51,198,142, 12, 45,143,198, 89,152,206,114,188, +189,189,247,101,103,231, 12,238,215,175, 31,242,243,243,233,101,203,150,161,125,251,246,240,247,247,183,232, 26, 85,243,230,156, +121,251,246,109, 31,189, 94, 15, 66,136, 37,230,236, 9, 77,138,162,176,107,215, 46, 24, 12,134, 39, 86,118,238,243, 5,230,143, +106,130, 41,111,239,192,151,113, 7,240,253,247,223,215,120,236, 10,160,189,193,177,229,122,169,144,105,191,242,131,183,100,147, + 38, 77, 18, 78,153, 50, 5, 41, 41, 41,120,253,245,215, 13,225,225,225,166, 12,181,250,184,148,227,190, 51, 87, 54,198,213,106, +202,100,178,157,167, 79,159,198,129, 3, 37,190, 36, 62, 62, 30,173, 90,181,178,173,100,146,243, 14,162, 40,249, 59, 92,249, 37, + 22, 93,135,237,197,149, 95, 94, 1, 91,112, 66,220,169, 21, 10,173, 57,159,117,160, 42,205, 3,185,185,185,229, 38,106,247,238, +221, 54,187,119,239, 30, 1,224,103, 0, 7, 0, 32, 47, 47,111,141,149,154, 0,133, 41,227, 70,141,128, 72, 98,143,216, 7,105, +232,211,173, 35, 26,185,187,227,246,189, 4, 36,167,231,101, 82, 20, 94, 27,216, 93,186, 82,175, 55,125,116,241, 22,126,168, 69, +147,106,220,184,177,255,193,131, 7, 37, 21, 34,208,229,255,113,161, 80, 88,254,189,204,120,215,229,254, 44, 51, 89,246,141,237, +174,124,186,161,135,237,149, 59,187,209,170,201, 16, 56, 15, 9,197, 15,103,206,224,126,116,140,193,164, 99, 94,248, 23,174,209, +223,165,233, 63,106,212,168, 75,123,246,236,113, 74, 77, 77,197,133, 11, 23,208,172, 89, 51,232,116, 58, 75, 94,120, 43,105, 26, + 12, 6,247,178,109, 40,138,114, 47, 11,188,155, 76,166,178,139, 81,246, 71,116,170,176,158, 83, 13,154,190, 21,214, 43, 51, 87, + 77, 26,224,216,165,114,137,228,224,177, 35,251,236, 98, 98, 47,160, 67,240,243,176,115,108, 3,142,205, 64,110, 94, 49,242, 31, +168,240,217,103, 95, 98,233,178, 15,241,243,209, 67,118, 1,129,193,135, 77, 12,211, 18,128,225,153,185,238, 20,153, 22,241,203, +238,141, 20,225,160,207,140,149,137,181, 15, 21, 19, 94, 25, 45, 28, 63,126, 60,126,254,249,103, 68, 71, 71,111,172,193,100, 69, + 84,136,204, 79,187,123,225,192, 70, 16, 2,125, 86,172, 76,162,127,168,152,252,234, 88,225,164,151, 95,196,229,223,215,227,197, + 14, 15,239,122,185, 99,100,126,169,197, 22, 9,145, 43,147,227, 15,114, 5,151, 43,152,173,115, 0,168, 10, 6,235, 28,254,170, +131,249, 52, 48,180,212, 88, 77,123,252,197, 68, 84, 23,131, 5, 0,173, 0, 59, 74, 42,185,178,125,233, 91, 94,138,148,104,145, +241,110, 20, 84, 70,142,108, 74, 98,184,142,128,205, 13, 64,255,248, 54, 58,157, 78,155,144,144, 96,243,218,200,145,232,222,182, + 45, 60, 93, 93,209,178,113, 99,216,200,164,144, 74,196,149, 94, 89, 45, 46, 67,160, 40, 18, 16, 16,128, 97,195,134, 65, 44, 22, + 67,161, 80,192,206,206, 14, 82,169,180,202,104,150,165,111,185,132, 16, 8,133, 66,220,189,123, 23,201,201,201,112,114,114,194, + 31,127,252,129, 23, 94,120,225,137,168, 86, 69,115,102, 77,136,190,138, 7,127,153, 17, 59,109,141, 22,203, 82, 40, 38,193,144, + 39,205,134,142,234, 8,163,145,129,209,104,196, 15,145,102,252,153,160,133,217,108,130,209,104,172,105,159,213, 33,240,242,242, +154,208,178,101,203, 89,175,188,242, 10, 45,149, 74,161,213,106,161,211,233, 16, 29, 29, 77, 15, 30, 60,164, 96,216,176, 80,199, + 19, 39, 78,144,210,162,195, 76, 43,180,115,189,189,189,125, 74,139,103,115,235,114, 87, 83, 20, 85,110, 98, 30,231,181, 53, 49, + 16, 9, 75,174,201,198,141, 27,193,178, 44, 8, 33,213, 94, 36, 3, 69,253,182,236,139,213,142,171,214,253, 8, 71,151, 70, 56, +127,254, 60,123,234,212,169, 34, 10,136,191, 31, 29,189,230, 37,224,228, 65,192,108, 77,250,242,243,243,109,154, 53,107,134,198, +141, 27,131,227, 56,208, 52, 93, 30,125,201,205,205,133, 94,175,135,139,109, 1, 90,184, 54, 6, 83,116, 14,234,187,159,192,211, + 46, 22, 59, 78,155,232,231,252,113,235, 63,144,113,252, 84, 58,213,243,173, 25,222,238, 30, 62, 16, 16, 26,170,172, 92,140, 24, +250, 34,132, 18, 59, 60, 74,205, 65,112,155,230,158,175,190,212,195, 83, 72, 49, 88,184,114,239, 44,128,251,161, 54,185,226,226, + 98, 54, 54, 54, 22,183,111,151,248, 93, 7, 7, 7,216,218,218, 86,250,143, 11, 4,130,122, 69,180,202, 76,214, 23, 27, 95,176, + 21,136,181,208,176, 17,216,182,235, 58,130, 3, 66,177,233,202, 85, 3,155,153,215,255,107,131, 33,126,223, 83, 28,204,240,240, +240,152,206,113,220, 82, 66, 72, 65,207,158, 61, 27,237,221,187,215, 57, 61, 61, 29,215,175, 95,199,146, 37, 75,178, 89,150,101, + 8, 33, 20, 33,228,147, 6,216, 29, 87,193, 96, 53, 36, 98,133, 28,111,187, 57, 80,195, 69, 2,135,102,140,166,248, 81,142,137, + 28,215, 49,220,183, 0,232, 26, 51, 55,129,224,141, 67,251, 55,122,185, 41, 57,132, 40,251, 65,157,105,198, 23,239, 77, 70,110, +110, 17,126,216,186, 2,128, 20,102, 70,136,222, 33,163,225,238,238,141,105,111, 78,243,216,184,121,211, 91, 12,199,125,141,103, +132,140, 75,223, 31, 5, 16,161, 84, 42,163,223,154, 54, 77,217,172,217, 68,200,229,114,236,219,183, 15,123,191,251,142, 93, 7, +140,149, 1,103,103, 0, 71,107,212,185,242,151,206,156, 25, 51,148,129,129, 51, 32,147,201,240,251,169,159, 96,200,216, 85, 52, +180, 59,204, 58, 3,134, 54, 29, 70, 92,146,126,161,242,196, 98, 60, 0, 0,177, 28,106, 0,143, 23,131, 61,109, 6,171,140, 19, +248,171, 94,214,180, 74, 17,173, 58,231,157, 98,233,157,173,239,190,220,164, 17,140,148, 41,242, 23,164, 27, 57,118,213,125,179, +240, 70, 33,153,127,175, 10,147, 85,122, 99,115,190,190,190,232,215,169, 19, 70,246,234, 5,145, 72, 4,185, 84, 2,123,185, 13, + 8, 91, 18,201, 42, 43, 58,172,225,153,136,170,162, 79,174,174,174,144, 72, 36,229, 6,203,138,104, 86,149,154, 28,199, 65, 36, + 18,225,246,237,219,232,217,179, 39,124,124,124,112,224,192, 1, 12, 28, 56,240,137,162, 68,107, 77, 86,153,209,122,172, 24,111, + 32,128,178, 72,150, 85, 70,203, 96,162,144, 99, 10, 6, 69,181, 5,195, 0, 44, 1,140, 6, 3, 8, 1, 8, 1,104,179, 9, 6, +131,161,124,159,150, 20,201,122,120,120,248,218,216,216, 44,127,255,253,133,129,193,193, 29,144,157,157, 13,142,227, 96,107,107, + 11,157, 78, 7, 7, 7, 7,116,239,222,253,209,242,229,203,213,132, 96,154,149, 38,171,222,148,157,243, 51,103,206, 84, 42, 54, + 44,155,180,234, 52, 76,121,103, 55,164,162,146,162,165,178, 58, 60, 53,229,187,125,123,247,192,165, 27,241,204, 27, 11,215, 27, +197,185,215, 87,122,112,220,246,180,122, 28, 23, 33, 4, 57, 57, 57,200,204,204,196,240, 17, 35,176,119,207, 30, 36, 37, 37,161, + 77,155, 54,232,219,183, 47,220,221,221,145,148,148,132, 63, 47, 26, 97,204,207, 67,158,233, 58, 20,246, 93,113,236,124,130,113, +201, 70,115,194,191,152, 97, 12, 7, 48,217,193,193,193, 79,167,211,169, 25,134, 57, 8,224, 32,128,177, 34,145,104,172, 66,161, +240,212,104, 52, 15, 81,210,154,232,120,109, 98, 54,114,185,171, 76,238, 0,142, 49, 66, 36, 18,193,199,167, 25, 8,107, 66,190, + 70,143,215,198, 15,195,141,219,247,112,234,236,101,134,166,185,111, 44, 57,165,223, 22,203, 0, 0, 32, 0, 73, 68, 65, 84,173, + 66,161,144,248,251,251, 35, 43, 43, 11, 98,177, 24, 54, 54, 54,176,179,179,195,226,197,139,241,221,119,223,149,155,172,186, 26, +173,169,128,191,131,175,221,229,207, 55,148,152,172, 12,149, 26,153,105, 98, 40, 93, 27,225,155,239,214,105,243,147, 50,186,254, + 8,196, 63,237, 15, 89,142,227, 62, 73, 79, 79,119, 23,137, 68, 30, 12,195, 32, 53, 53, 21,215,174, 93,195,236,217,179, 51,115, +115,115, 67, 80,199, 99,148,203,229, 89,101,145,172,210,162,195,234,138, 19, 11, 42, 68,178, 10,106,144,172,174,152,176,121,179, +198,246,225, 91,215,206,245,237,220,181,187, 64, 33,114,200, 47,126,144,209, 51,242,194,249,238,179,215,254,240, 86,114,126,241, +139, 0, 18,171, 19,149,137,197,131,159,239,209, 67, 4,146, 9,145,180, 39,190, 92, 53, 30,217, 57, 26,228,231, 21, 65, 34,177, +133,137, 22,130,229, 40,116,239,217, 11, 63,237,216,143,160, 55, 95, 23, 74,197,226, 1,140,201,244,204, 24,173, 82, 86,124,251, +237,183,190, 1, 1, 1,216,190,125, 59,206,238,220,137, 73,133,133, 56, 47, 16, 8,105,177,216,237, 36, 77,111, 65, 45, 70,171, +162, 78, 80, 80, 16,126,252,241, 71,236,218,181, 43,101,194, 11, 89,135,231, 78,128,187,217,140, 65,215,227,224,210,116, 24,112, + 61, 14, 46,207, 5,160, 37, 35,194, 3,138,170,220, 29, 84, 88, 88, 88,159,138,243,167, 12, 53,170, 41, 98, 23, 1, 8, 9, 11, + 11, 35, 21,231,181,102,156,202, 86, 51, 86,188,232,215,164,109, 11, 95,138, 62,176, 30,169, 90,198,244, 81,156, 89,122,191,152, +204,189, 7,172,171,225, 13,130, 8,133, 66,216,219,216, 64,233,228, 84, 18,230, 23, 8, 0, 14,224,104,128, 98, 75, 12, 0,225, + 40, 16,214,170, 12, 3, 82,169,180,202,138,239,214,214,205,170,168, 89, 84, 84,132, 71,143, 30, 97,218,180,105, 80, 40, 20, 37, +206, 61, 35, 3, 77,154, 52,129, 72, 36, 66,122,122, 58,126,255,253,119,248,249,249, 65, 38,147, 89,229,182, 42, 68,151,218,163, +164,149, 97,123,181, 90,237,224,233,233, 9,171, 35, 90, 28,129,206, 72,193,100, 98,113,255,254,125,168, 84, 42, 60,122,248, 0, +157,181, 26, 16, 8, 65, 8,177, 42,162,229,237,237,221,182,121,243,230,155, 86,174, 92, 41,105,220,184, 49, 8, 33,112,118,118, +130, 78,167, 67, 78, 78, 46,218,180,105, 3, 31, 31, 31,172, 92,185, 18, 0,246,254,211, 38,235,177,123,170,220,104, 85, 52, 92, +239,188,228,139,188, 60, 59, 8,133,130,114,227, 92, 75, 29, 45, 9, 0,132,188, 56, 74, 20,126,234,164, 45, 3, 44,207, 16, 10, +151,139,106,191,142, 52,203,113,138,234,126, 79, 77, 77,133, 88, 44,198,161,131, 7,145,151,153,137,224,224, 96,116,233,210, 5, + 15, 30, 60,192,141, 27, 55,224,234,234, 10,101,227,110, 56,255,208,140, 24,149, 30,142,142,142, 72, 72, 19,252,155, 93, 6,188, +217,191,127,255, 37,107,214,172,113,247,240,240, 16,103,103,103, 7,108,216,176, 33,120,195,134, 13,115,222,122,235,173, 70,111, +189,245,150,179, 82,169, 20,101,100,100,248,191,247,222,123,207, 69, 68, 68,248, 1, 88, 93,147,160,173,173,189,139, 80, 98, 11, +138, 18,193,201,209, 25, 34,169, 45, 56, 70, 4,150, 3, 28, 28,149,184,116,227, 16,254,184, 83, 52, 61, 43, 23, 7, 45,138,143, +149, 94,119, 87, 87,215, 39, 34,213,179,103,207,198,214,173, 91,203,139, 17,235,106,178,190,216,240,130, 29, 85,106,178, 50, 82, + 69,160,140,126,248,229,104, 84, 65,126, 82, 70,207,103,193,100,149,229,113,132, 16, 60,124,248, 16, 58,157, 14, 23, 47, 94,196, + 39,159,124,146,253,184,201,114,119,119,127,211,193,193, 97, 89,113,113,241,151, 25, 25, 25,235,107,125,241, 43, 49, 81,101,159, +203,230, 85, 22, 39, 90,152,212, 38, 85, 69,178,124, 60,229,167,111, 92,220,221,196,145,220,162,144, 60, 13,184,175,137,182,191, +226,222,123, 72,231,161,130,142,223,127,218,180,203,244,197,167, 83, 53,134,128,234, 34, 91, 28,203,118,180,181,179, 7,144,133, +235,215,206,149,155,172,220,188, 66, 24,205, 66, 24, 77, 20, 12,102, 1,250,245, 31,132,239, 54,237, 66,122, 86, 30, 88,150,109, +247,140,153, 44,151,182,109,219,206, 24, 59,118, 44,150, 47, 95,142,136, 53,107, 76, 51, 41, 74, 35, 2,200, 9,150, 5, 71, 8, + 37,176,172, 18,123, 37,157,175,191,254,250, 40,128,151, 87,206, 70,183,252, 98,188,230, 53,140,184, 52, 29, 86,178,226,152,247, + 9, 0,184,100, 71, 84,126,100,134,134,134, 82,101, 37,107,214,150,176,253,215, 17,133,134,134,158, 15, 11, 11, 67,197,121, 77, + 27,216, 55, 10, 24,178, 96,222,172, 85,157, 7,246,162,212,243, 6, 32, 79, 99, 96, 62,136, 49, 75,211,244, 53,155,172,138, 44, +216,176, 1, 55,226, 75,254,199,141,221,221,177,240,213, 87, 65, 24,224,143,232, 24,236,143,136,192,248,254,253, 97, 43,151, 91, + 28,217,224, 56,174,202, 40, 86,197,104,150,181, 81,167,130,130, 2, 28, 60,120, 16, 93,186,116,129, 66,161,128, 72, 36, 66,251, +246,237,113,239,127,236, 93,103, 88, 20, 87,219,190,103,182,194,178,244,222, 85, 20, 12,138,189, 37, 98,236, 45,182,168, 81,177, +188,246, 26, 11,106, 84,108,177,196, 26, 53,246,138, 49,118,236, 26, 43,118, 44,216, 5, 65, 17,164,151,101,233, 44,176,125,118, +118,230,251, 65,121, 81, 41, 11,166,188,201,231,115, 93,123,205,206,206,238,189,103,230,204,156,115,159,167, 70, 69,193,195,195, + 3, 4, 65,224,252,249,243, 24, 56,112, 32,226,227,227,241,229,151, 95,138,147,147,147,107, 76,180,222,188,121, 99,198,178,236, +215,165,218,143,218,138, 70,163,193,219,183,111,209,175, 95, 63, 88, 90, 90,194,217,249, 56,110, 6, 31,133,200,231, 63, 32, 8, +212,136,104,233,245,250,113,125,250,244,225, 19, 4, 1,149, 74, 9, 35, 35, 99,152,152,136, 97,106,106, 6, 47,175,134, 72, 79, + 79, 71,207,158, 61,181,113,113,113,187,164, 82,233,201,154,182,213,219,219,219, 36, 41, 41,233, 63,117,234,212, 17, 0,128,177, +177,113, 35, 15, 15,143, 31,226,227,227,139,106,170,213, 42, 37, 88, 4, 65,128,195,225,148, 17, 45, 46, 73,194,209,193,174,108, +191,196, 63,141,168, 2,171, 80,146,171, 17, 2,128,155,155, 27,118,236,253,157,236,211,167, 15,102,205,154, 5,157, 78,135, 93, +187,138,131,236,134, 15, 31, 14,138,162,112,230, 76,113,144, 36,151,203,173, 82,109,242,252,249,115,188,120,241, 2, 58,157, 14, + 5, 5, 5,184,122,245, 42, 66,238,221, 67,208,249, 91, 72, 74,136, 69,211,134,238, 24, 63,126, 28,120, 60, 30, 14, 29, 58, 4, + 95, 95,223,191,117, 64,224,241,120, 35, 3, 3, 3, 29, 15, 30, 60, 40, 59,127,254,188,162, 93,187,118,194, 45, 91,182,216,237, +216,177,195, 86,171,213,194,223,223, 63,235,241,227,199,154,111,191,253,214,100,223,190,125,142,245,235,215,239, 78,211,116, 69, + 68,203, 4,192, 48, 0,163,242,139,180, 92, 89,145, 10, 12,173, 69, 66, 82, 34, 10,228, 90, 48,122, 10, 41,105,233,144,171,245, +200,205, 43, 66,211, 22, 61,182,223,189,123,119, 49, 69, 81,139, 0, 92,170,174,157,175, 95,191,198,227,199,143,145,148,148,132, +132,132,132,247,153,226,196,137, 56,114,228, 72,141, 53, 90, 21,147, 44, 14, 8,141, 7, 46,157,127, 34,203,138,149,254,107, 72, + 86,201, 24,180,204,209,209,113,153,163,163,163,209,245,235,215,205,235,212,169, 3,154,166,181, 31,106,178, 58,117,234,180, 36, + 48, 48,208,209,195,195, 99, 58,128,173,255, 11,109, 39, 73, 76,252,121,247, 20, 27, 83, 65, 74, 58,222,109, 42,201, 37,200, 1, +148,133,192,221, 99,224,182, 95,154, 56,253,219, 5,150, 1, 7, 87, 78,100,192, 84, 26, 33, 27, 23,159,138,221,187,119, 96,182, +255, 24,252,246,235,207, 96, 24, 46, 52, 58, 14,220,234,182,131,134, 98, 64,144, 92, 52,107,209, 10,119,238,222, 7,143, 4, 78, + 29,220,253, 47,227, 89,200,139,140,140,220,117,254,252,249, 25,179,102,205, 2,195, 48,130,229,187,119,171,178,179,179,215,162, +102,249,175, 62,196, 25,184,123,247,238,152,128, 29,217,231,102,143, 4, 39,233, 34,145,247, 34, 26, 86,223, 45, 96,113,122, 61, +129,150, 13,145, 39,170,120,138,191,247,193,246,223, 65,180, 74,153,100,249,109, 69,210,194,179,222, 79,230, 86,150,227, 72, 83, +103,155,249,179,166,114,227, 51,212, 56, 83,103,132,252,246,225,109, 38, 25,180,112,123, 28,212, 91,106,242,199, 39,110,223, 46, +123,191,225,248,241, 10,143, 73,191,251,206,224,149, 89,101, 90,172,154,106,178, 0, 64, 36, 18, 89,116,239,222, 29, 93,187,118, +197,224,193,131,203,124,178,154, 55,111,142,160,160, 32, 12, 26, 52, 8, 97, 97, 97,112,116,116,196, 23, 95,124,129, 47,190,248, + 2, 87,174, 92,169,233, 32, 7,189, 94, 15, 31, 31,159,210,168,195,166,105,105,105,102,181,237, 72,141, 70,131,220,220, 92, 88, + 89, 89, 65, 32, 16,160,109,219, 54,152, 49,179, 45,108, 28, 15,192,199,187, 33, 20, 10, 69, 89,248,187, 1,147,173, 79,131, 6, + 13,144,157,157,141,236,236,108,216,218,218,194,201,201, 9, 14, 14, 14,216,180,105, 19,187,117,235,214,107, 20, 69,237,202,201, +201,169,177, 38,203,193,193,161, 3, 65, 16, 75, 84, 42,149,160,220, 10, 87, 96,107,107,123, 65,165, 82,173,149, 74,165, 6, 59, +130, 18, 4, 1,138,162, 64, 16, 4, 46, 39, 56, 65,161, 37, 80,152,246, 2,179,250,187,191, 71,188,120, 60, 94,181,230, 82,150, +101, 21,126,126,126,118,174,174, 46, 72,141,123,141,211,167, 89,252,242,203, 47,165, 81,145,136, 41, 89, 24,148,238,119,238,220, + 25,117,235,214, 5, 91,131, 92, 25, 12,195,224,213,171, 87, 56,126, 33, 4,142,238,222, 72,121,247, 22, 47,175, 92, 68, 29, 91, + 43, 52,110,209, 10, 58,157,238,147, 82,111,252, 17,162,211,233,246,123,122,122,178, 90,173, 54, 4,192,142,136,136,136, 49, 82, +169,212,255,247,223,127,119, 26, 50,100, 72,250,197,139, 23,183, 0, 56, 24, 17, 17, 49,101,213,170, 85, 93,105,154,174, 48, 90, +144,195,225,252, 54,103,206,156, 78, 67,134, 12, 33,248,164, 78,123, 61,248, 16,151,166,117,196,188, 69,251,245,119, 31,132,144, + 52,173, 35, 6,251,205, 97,174,220,142, 32, 39,207,220,160,111,222,174, 15, 34, 35, 35, 29,250,246,237,187, 74,167,211, 85, 73, +180, 74, 53, 85,149,105, 40, 57, 28, 14,198,140, 25,131,160, 32,195, 61,168,198, 3, 30,102,238,226,199,107,118,118, 19, 19, 92, +121, 57,146, 85, 31,151,206, 63,145,101,190, 75,255, 87,145, 44, 0,200,205,205,221, 11, 96, 47,195, 48,153, 38, 38, 38, 40, 42, + 42,170,232,254, 51,138,136,136, 48, 18, 8, 4,232,209,163,135,213,205,155, 55, 99, 72,146,220,154,158,158, 94, 41,227,168,200, + 76, 88,145, 57, 17,159, 16,117,104,105,139,190,109, 59,180, 48,141, 54, 95,105,106,196, 85,135,213,137, 49, 50, 35, 0, 20,104, +236, 19, 66,147,135, 21, 18, 89,194,230,173, 58,183,132, 25,215,164,175,140, 46,170,144,104,145, 28,206,203,130,124, 89,239,194, + 34, 45, 30, 60,140,132,223,176, 6,208, 80, 4, 24,134,132, 92,161, 1, 56, 60,144, 0,134,143, 24, 13,150,224, 34, 47, 51, 29, + 28, 14, 39, 2, 52,141,127,153, 44,156, 50,101, 74,239, 69,139, 22,213,155, 63,127, 62,230,207,159,239, 30, 24, 24,184,119,205, +154, 53,243,179,179,179,155,160,154,228,227, 85,224,212,185, 24,180,116,238,133,251,123, 10,250,124,165,122,215,178, 97,177,230, +171,101, 67,228,241,120,136,229,114,144,203,178,239,187, 25,245,237,219,183, 99,249,237, 63, 76, 62,116,130, 47,219, 55,200, 71, +171, 65, 61,231, 94, 45,154,251,204, 92,188,104,177,105, 84,232, 93, 4,252,180,131,245,108,213,189,104,239,253,151, 90,185, 73, +221,222,242,156,216,135,134,242, 11, 0,232,213,101, 16,154, 54,106,243,209, 65,223,206,197,201,218, 31,220,121,142,204,108,137, +193,147,109, 9, 57,168,208, 39,203,144,144,254, 15, 69,165, 82,201, 34, 35, 35,237,210,210,210,222,115,124,175, 91,183, 46, 8, +130,192,147, 39, 79,240,248,241, 99,248,249,249,129,203,229,130,199,227, 33, 36, 36,164, 70,218,152,114,218,165,210,168,195,158, + 46, 46, 46,149, 69, 27, 86,139,165, 82,169, 80, 80, 80,128,224,224, 96, 52,104,208, 0,107,214,172,129,147,163, 61, 22, 47,158, + 11,134, 97, 80, 88, 88, 8,189, 94,111,168, 70,139, 41,213, 22, 49, 12,131,236,236,108,212,171, 87, 15, 59,119,238,196,150, 45, + 91, 86, 73,165,210,223,107,218, 70, 87, 87, 87, 11,189, 94, 63,175, 79,159, 62,221,191,253,246, 91,244,236,249,126, 62,214, 99, +199,142,153,158, 57,115,102,237,182,109,219,122, 81, 20,181, 46, 43, 43, 43,219, 16,220, 3, 7,138,211, 47,137,218, 45, 67,192, +144, 58, 24, 53,237, 16, 54,109, 58, 11,161, 80,248,222,196,187,114,229,202, 42, 73, 12,195,178,158,252,156,208,244,185, 11, 54, +218,173, 93,123, 19, 55,111,102,129, 36, 73, 56, 58, 58,130, 36, 73, 36, 38, 38,130, 36, 73,184,187,187,131, 36, 73, 72, 36,146, + 82,159,192,124, 84, 16,245, 88,241, 42,156,132, 90,173, 70,106, 74, 18,210,226, 98, 32, 46,204,128,173,153, 8,249,175, 95,161, +233,248,137,101,249,159,254,102, 57,162,213,106,143,148,219,223,120,241,226, 69, 45, 65, 16,131, 81,236,167, 81,170,209, 88, 69, +211,244,170,202, 64,218,181,107,215,124,209,162, 69,188,210,116, 27, 78,110,171,105,138,162, 24, 0,104,216,244,235,247,216,126, +108,108, 44, 54,109,218, 4,133, 66, 1, 62,159,207, 55,228, 58, 48, 12, 83, 22, 97, 88, 17, 9,171, 9,201, 2, 0,107,119,151, +237, 79, 94,132,232,195,227,246,168, 34,162,175, 26, 75, 83, 72,144,218,127, 47,201,250, 80,179,229,226,226,178,140, 97, 24,150, +101,217,165,229, 14, 9,221,220,220,238, 95,191,126,221,154,166,105,108,219,182,205, 34, 35, 35,195,226,235,175,191, 14, 0, 80, + 41,209,170,200, 76, 88,145, 57, 17,229,162, 14,133, 66,161,149, 86, 91,169,242,228,163,168, 67,189, 30, 94,102,166, 22,200, 71, + 26, 52, 54,186,230, 50,107, 58,239,134,116, 98,152, 83,114,139, 70, 38,122, 93, 61,178, 80, 11,103,145, 5, 24,150,173, 52, 52, + 90,163,211, 93, 13,123,241,178,135,155,107, 3,206,239,151,238, 97,192,192, 33,208,104, 72,168,117, 4, 8, 14, 15, 4,135,143, + 38, 77, 91,224,139,198, 77,193, 2,120,254, 52,148,214,234,116, 55,254, 77,125,239,216,126,134, 31, 65, 96, 43, 88,134,173, 32, +143, 86,189,129, 3, 7,174, 5, 48,179, 58, 28,187,118, 51,252, 72,178, 24,167,124, 30,173, 57, 51,166,224,245, 83,158,249,189, + 23,235,249, 61,219,225,114,246, 77, 2, 34,163,255, 70, 29,242,200, 79, 74,205,241, 79, 33, 92,213, 19, 45, 87, 87, 87, 11, 51, +161,209,129,239,199,143, 51, 77, 14,127,132,140, 55, 79,240,240, 94, 76,254,137, 51,103,243, 20,185, 89,227,107, 64,178,202,204, +124,214, 14,117, 80,215,251, 99,162,101, 36,182, 5, 0,212,245,110, 3,142, 73,205,210, 8, 85,164,205,170, 13,201, 42, 63, 96, + 87,148, 67,107,242,228,201, 8, 12, 12, 68,251,246,237,225,233,233, 89, 54,216,215, 84,107, 86,129,118,169,198,209,134,229,165, +168,168, 8,238,238,238,216,183,111, 31, 34, 34, 34, 96,106,106, 10, 63, 63, 63, 20, 21, 21,149, 17, 44, 67,157,225, 89,150,141, +189,126,253,122,235,161, 67,135,178, 60, 30,143,144,201,100,176,176,176,192,206,157, 59, 21, 82,169,244,114, 45, 72,214, 16, 62, +159, 63,119,216,176, 97,156,134, 13, 27, 34, 51, 51, 19,102,102,102, 58,130, 32,120, 0, 96, 97, 97,161, 51, 54, 54,198,148, 41, + 83,208,172, 89,179, 14,243,231,207,111,207,229,114,119,166,167,167, 31,170,234, 94, 34, 8,162,108, 66, 29,191,245, 45,180,218, +226, 9,122,215,174, 93, 40,241,117,251,175,137, 32, 46, 14, 48, 32,146, 69, 44, 22,195,211,211,179,194,190,239,208,161, 3,158, + 63,127, 94,108,154,228,114, 97,103,103,135,135, 15, 31, 26, 20, 73, 85,154, 8, 50, 50, 50, 18,222,117,109, 16,113,243, 58,108, + 68, 60, 52,115,114,128, 75,135,142,136,137,137,249, 59,181, 89, 4,138,253, 48,186,149,220,131,251, 1, 76, 46,183,191, 19,192, +246,154, 0,210, 52,205,146, 36, 73,164,166,166, 82, 34,145,136,176,178,178,226, 10,133, 66,104, 52,154, 50,194, 21, 27, 27,139, + 75,151, 46, 33, 45, 45, 13, 86, 86, 86,164,185,185, 57, 40,138,202, 55, 4,223,203,203, 11, 14, 14, 14,239, 57,190,143, 31, 63, +190, 86, 36,107, 12,224, 19,184,122, 93, 29, 33,201, 49,247,182,233,133,132,183,137,106, 82, 11,163,255, 15, 36, 11, 0,100, 50, +217, 94, 0,123, 75,247,109,108,108,198,114, 56,156,197, 26,141,198, 60, 36, 36,196,194,214,214,150, 56,116,232,144,110,233,210, +165, 50, 14,135,147, 79, 16,196,230,191,159, 28,226, 77, 78, 65,156, 59,207,210,137, 9, 87,179,161,254,169, 1, 95,228,243, 26, +216, 18,141,125, 48, 48, 43,234,193, 88, 58,238,171, 76,105, 6,201,130,121, 83,197, 24,188, 63, 96,209,202,121, 49,111, 95,186, + 25,153, 25, 97,242,148, 69,184,124,237, 14, 8,146,135,251,161, 79,160,165,244,200,201, 43,192,176,225, 35,225,226,104,131, 55, +143,131,179,105,134,217,249,239, 34,217,204,142, 30, 3,198, 90, 10,141, 69, 37,215, 68,143, 35,191,206, 5, 73,110,197,143, 63, +254, 8, 31, 31,159,105,145,145,145, 43, 80, 77, 30, 45,130, 96,118, 52,233, 56,220,146, 47, 44,198, 97, 25, 61,246,157, 10, 40, +201,163, 53, 27, 59,247,158,105,210,184,110,194,242,170,242,104,253,139, 72, 86,249,109,213, 68,203,221,221, 93,104,194,195, 36, + 30,135, 59,255,251, 17,223,218,102,197,189, 70, 90,212,203, 98,243, 2,165,162, 50,222, 69, 25,146, 10,189, 27,222,207,223,193, + 86,101,186, 82,171, 13, 90,209,191,135, 89, 58,225,126,168,205,170, 33,201,250, 8,179, 60,217, 42,159, 55,203,213,213, 21,107, +215,174, 53, 36,143,214,135,231, 94, 42, 61, 81,236, 0, 95,222, 25,190,167,129, 36,171, 66, 76, 91, 91, 91,228,230, 22,103, 72, +232,212,169, 19, 58,117,250,111, 60, 3, 69, 81,101, 90, 44, 83, 83,211,138, 52, 90, 31, 97, 26, 27, 27, 7,156, 61,123,118, 92, +104,104,232,208, 31,126,248,129,215,181,107,215, 82, 50,167,132, 97,181,221,222,195,212,235,245, 83,130,131,131, 57, 12,195, 96, +223,190,125,120,254,252, 57, 43, 18,137,150,136, 68,162, 29,198,198,198,122,149, 74, 53,121,226,196,137, 35,151, 47, 95, 78,118, +232,208, 1,143, 30, 61, 34,235,213,171, 55, 26,120, 47,137,101,133,231,254,228,201, 19,144, 36, 9, 58, 47, 5,211, 2, 78,192, +196,152,139,183,111,223, 34, 47, 47,239,163, 36,166,134, 92,207,242,154,146,210, 87,135, 14, 29,202,204,144,109,219,182, 5,135, +195, 65, 88, 88, 88,101,102,216,242,152,172,181,181,117,217,253,193,231,243,113,231,206, 29,252,244,211, 79,112,179,178, 64,126, + 84, 4, 28, 58,117, 65,247,113, 19,225,231,231, 7, 14,135, 3, 43, 43,171, 50,205,175, 1,247,210,167, 72,121,204,113,222,222, +222,163,223,188,121,227,210,164, 73, 19,199,200,200,200,206, 62, 62, 62,238, 17, 17, 17,165,251, 66, 24,230,155, 83,134,249,236, +217,179,211, 59,118,236,152, 50,102,204, 24, 62,195, 48,250,228,228,100, 29, 0,194,193,193,129,243,236,217, 51,230,247,223,127, +135, 74,165,130,139,139, 11,233,236,236, 76,220,184,113,131,137,138,138,122,194,178,236, 34, 67,206, 93,175,215,191,151,198,161, +244,253,177, 99,199,106,252,188,215,249,194,107, 77,215,175, 27,186,230,164,135, 65, 42,137,131,190,192,150,186,116,254,162,166, +134, 36,235,207,238,163,191, 18,115,229,187,119,239,156, 53, 26, 13, 4, 2, 1,118,237,218, 69,173, 93,187,246, 77, 78, 78,142, + 47, 42,142, 40,127, 15,179,150, 81,135,121, 85, 96,126, 20,117, 88,144,139,203,231, 47, 60,107, 45, 30,184, 31,211,210,179,203, + 28, 27, 89,130,176, 58,107,223,200, 87,212,166,137,132,188,178,140, 44,210, 43, 47, 87,113,238, 90,149, 86, 59,100,224,160,225, +183,130,130,142,139,151, 46, 91,134,135, 79, 34,144, 43,147,131, 97, 57, 96, 8, 2,139, 23, 47,133,131,141, 21, 10,211,223, 41, + 53, 20, 53, 16,239,231,208,250,199,247, 59, 65,144,211,111,252,126,104, 43, 73,128, 81,100, 70, 11, 57, 69,113,162, 81,126, 3, +185, 67,134, 12,193,217,179,103, 17, 25, 25,185,167, 10,146, 85,134,201,178,228,244,136,144, 19, 91, 9,128, 81,101, 71, 11,185, +242, 4,209,232, 17, 3,185,126,126,126, 56,119, 41, 20, 65, 23, 19,118, 7, 93,196, 69,252,187,165,230,153,225, 77,185,136,244, +109,228,225,220,161, 69, 99, 35,174, 94,133,180,168, 56,228, 41,212,184,241, 58, 89, 70,178,100,173,115,235, 20, 15,144,124,164, +164,188,171, 96,101,101, 84, 50,161,171,107,132, 73,146,228,123,218,172, 79,209,100,149,111,167,189,189,253,123,229, 92,202, 79, +220,165, 62, 64,181, 72,237, 16,144,146,146, 98,150,146,146, 2,150,101,241,228,201, 19,179,182,109,219, 6,124,138, 54,107,238, +220,185,101, 90,171, 15,183, 21,125, 86,157,148, 56,165,111,209,233,116,167,230,207,159, 63,173,109,219,182, 61,150, 45, 91, 70, +160, 6, 5,120, 63,208,230,208, 12,195,224,238,221,187, 56,123,246,172,158,162,168, 73, 82,169, 52,162,220, 87,182,189,120,241, +226,198,160, 65,131, 14, 69, 71, 71,115,222,188,121, 3,150,173, 62,238, 84,165, 82,193,211,211, 19, 52, 77, 99,253, 52, 87, 20, + 21, 53, 1, 77,211,208,235,245, 48, 49, 49, 41,211,226,149, 39,207,213,221, 71,122,189,254, 35,162,245,228,201, 19,112, 56, 28, +248,250,250,226,229,203,151,101, 26,173,234, 52, 80, 20, 69,165,216,219,219,219,175, 92,185,178,172, 93,217,217,217,184,126,253, + 58,218,125,249, 21, 26, 77,154,140,244,244,116,108,222,188, 25, 78, 78, 78, 88,179,102, 13,242,242,242, 64,211,244, 95,173, 78, +239,253,230,205, 27,151, 17, 35, 70,100, 69, 68, 68,184, 92,186,116,201,162,111,223,190, 38,195,135, 15,207,138,136,136,112, 33, + 8,226, 43,212,208, 9,154, 97,152,133,139, 23, 47,190,182,102,205,154,128,153, 51,103,182, 29, 51,102, 12,143,199,227, 49, 18, +137,132, 62,126,252, 56,225,233,233, 73,242,249,124, 34, 56, 56,152,121,250,244,233, 99,154,166,215, 3,184, 95, 19,141,115,121, +146,197,225,112, 12, 37, 89,239,137,191,157,112,180, 41,153,237,187, 99,215, 90,178, 97, 93, 23,234,240,241,235,169,247, 31,189, +139,231,104,104,255, 3, 85,164, 6,248, 55, 11,135,195, 57,233,237,237, 61,118,250,244,233,198, 61,123,246, 20, 46, 95,190,188, +160,168,168,168, 50,146, 85,193,130,249, 47,137, 58,252,117,225, 15,151,252,231, 52, 25,235, 49,193,161, 14,110, 42,178,144,207, +229,144,102, 22, 36, 90,184,115, 80,148, 19,107,123,241,214,193, 68, 0,213,229,101,123,246,226, 85,100,183,198, 77,154,159, 89, +191,102,189,221,146, 5,243,121,103, 46, 93, 5, 75, 83,120, 18, 18, 2, 49, 95,207, 70,189,184,153,169,161,180,223,226, 95, 88, +130, 71,250,112,123, 16,128, 11, 86, 86, 86,225,227,198,140,241,244,246, 30, 14,145, 72,132,211,167, 79,227,200,182,109,250, 45, +192, 80, 33,240,114, 74, 53,249,244,178, 30,151,225,132, 77, 28, 55,206,171, 69,139, 9, 16,137, 68, 56,117,234, 20, 14,109,217, + 98, 48,206, 63, 92, 74, 51,195, 95,198,127, 51,196, 87,227,163, 69, 18, 69,143,223, 37,203,159,188, 75,150,131, 97, 89,134,101, + 53, 36,137, 84, 5, 69,173,121,151, 32,169, 21, 41, 40, 53, 29,174, 90, 61,253,143,179,121,148, 35, 63,181, 13,233,174,128,100, +165,149,175,145, 86,126,146,174,236,189, 78,167, 75, 51, 16,126,157,155,155,219, 71,159,213, 94,245,203,214,136,100, 25,154, 71, + 11, 0,114,115,115,165, 0,150, 60,122,244,232, 88,143, 30, 61, 38, 2,144,212,178,143,246,117,236,216,113, 18, 0, 14, 65, 16, +123,210,211,211, 35, 62,122,224,165,210, 24, 39, 39,167, 13,117,235,214,157, 92,188, 48, 37,246, 85, 51,145, 39, 52,105,210,132, +170,168, 47, 42,219,103, 24,166,218, 62,146,201,100,104,211,166,205, 71, 53, 45, 89,150, 69,114,114,114,169,198,169,236,218, 87, + 69,224,228,114,249,228, 25, 51,102,236,229,241,120,110, 0,136, 82,146,171,215,235, 57,219,183,111, 55,210,235,245, 28, 0, 4, + 73,146, 52,143,199, 83,159, 61,123,150,166,105, 58, 69,163,209, 76,254,139, 7,136, 83, 68,113, 41, 6,197,155, 55,111, 26,150, +104,178,210, 34, 35, 35,195,130,130,130,108, 1,156,168, 37,238,125,165, 82,121,127,237,218,181, 29,118,237,218,181,112,242,228, +201,109,252,252,252,184,157, 58,117,194,229,203,151,245,119,239,222,125,162, 82,169,214,213,132, 96,149,244,101,129,171,171,107, + 25,225,170,230, 89,174,210,145,215,218, 93,184, 99,228, 84, 39,163,125,235,174,203,115,210,181,161, 58,185,118,209, 65, 32, 18, +255,143, 37, 51, 51,243, 7, 0, 75, 55,111,222,156,222,172, 89, 51, 33,159,207,215, 26, 74,178,254, 66,161, 25,153,252,155, 95, +186,127,119,161,227,226, 25,117,187,119,246, 21,185,214,177,115,142,138,203, 68,236,163,203,138,240,139,171,147, 88, 77,254, 0, + 0,134,120,174, 63,213, 80, 84,131,185,243,231, 78, 19,240,120, 61,244,122,125,211,174, 55,206,179, 28, 14, 39, 66,171,211,221, + 40, 49, 23,170,255,197, 93,190,106,195,134, 13,158,222,222,222, 56,125,250, 52,110, 28, 61,138, 97, 57, 57,184,195,225,112, 72, + 62,223,250, 34, 69,109,132, 97, 4,105,213,166, 77,155,188,124,124,124,112,242,228, 73, 4, 31, 58,132,161,181,195,169,108,174, +107, 13,192,182,100, 55, 7, 64, 52,128,150, 0,140, 1,104, 80, 92,218,201,166,252, 20, 86,114,172,244,248, 61,130, 32,254, 76, + 71,216,234, 51,195,127, 40,145,177, 73, 45,255,232, 86,168, 84,170, 60, 79, 79,207, 26,197, 92,235,116,186, 42,109,184, 52, 77, +167,121,120,120, 24,172,181, 48,132, 20,229,229,229,181,250, 19, 59,227,147,124,177,222,155, 68, 24, 38,201,209,209,145, 41,157, +244, 43, 34, 97, 21,125,198, 2,137, 53,249,159,140,140,140,104, 0,115,106,219,206,244,244,244, 51, 48,160,104,180,161,223, 3, +128,252,252,252, 63,188,152, 47,193,178,146,229,203,151,215,136, 96,131,101,171, 34,159, 17,114,185,188,173, 33,255, 77, 81, 20, +254, 70, 57, 89,242, 34, 35, 35, 35, 39, 18, 4,209, 19,197, 38,129, 61,248, 99,178,121,223, 47, 44, 44,188,255,243,207, 63,119, +216,183,111,159, 63,203,178, 40, 44, 44,220, 82, 83,130, 85,182,122,206,202,186,252, 71,157,120, 94,166,246,246,241, 61,105, 93, + 84, 50,202, 63, 80,174, 61,132,207, 82,166,140, 98, 89,246,183, 81,163, 70,181, 3,112,240, 83,193, 42,137, 58,252, 84, 73,100, +242, 11,154,221,153,251,211,184, 59, 22,166,125,160,231, 54,132,150,188, 8,109,238,101, 0, 7, 96,152,155, 67,217,249,210, 12, +179,137,214,106, 55,149,155, 92,254, 63,244,179,149,143,143,143,255,216,177, 99,177,116,233, 82, 4,111,220, 72, 77, 37,136, 2, + 30,192, 94, 43, 94,104,146, 4,176,192, 80,156,209,163, 71, 99,233,210,165,184,178,126,125,109,113,170, 18, 91,130, 32, 46, 1, + 64, 64, 64,192,162,181,107,215, 90, 46, 92,184,176,233,186,117,235,214,148,236,191, 46, 61, 94, 50,215,245, 93,184,112, 97,227, +114,199,139, 0, 60,251,147,175,103,133,153,225,255,108,233,246, 25,243, 51,230,103,204,207,152,159, 49, 63, 99,126,198,252,140, +249, 41,194,178,108,159,226, 77,229,219,202,222,151,219,254, 45,194,197,103,249, 44,159,229,179,124,150,207,242, 89, 62,203, 63, + 80,202,107,177,106,115,252, 15,148, 82, 31,173,242,178, 15, 40, 14,235,174,140,149,214, 36,234,161, 54,204,246,230,103,204,207, +152,159, 49, 63, 99,126,198,252,140,249, 25,243,255, 29,102,117,216, 31,253,158,101,217, 62, 4, 65, 92, 98, 89,182,111,101,219, + 82, 98,245,225,251,114,219, 63,204,237,160, 2, 41,245,205,250,200, 71,235,207,150,207,106,213,207,152,159, 49, 63, 99,126,198, +252,140,249, 25,243, 51,230, 39, 73,169, 9, 16, 0, 27, 16, 16,176,240,127,208,116,232, 88, 66,178,202,191, 0, 84, 97, 58,100, +217, 83, 28,137, 4,102, 2,129,136, 15, 0, 90,173,146,114,118, 70, 33, 65, 12,249, 59, 11,222,126,150,127,166,148,134,123,103, +254,193,223,253, 44,159,229,179,124,150,207,242,255, 67,178, 75, 53, 85, 0,178, 1, 16, 37,251,218,146,109,118, 9, 33,251,240, +253,123,199,255, 68,145,162, 18, 77, 22,183, 50,146,149,147, 35,178,225,114,243,189,244,122,245, 23, 0,192,229,146,111,115,114, + 44, 99, 88,246, 84, 78,109,200,150,141,157,221, 11, 30,135,227,108,200,119,117,122,189, 36, 39, 51,243,253,212,241, 4,241,111, + 32,120,134,146,136, 79, 33, 27,127, 58, 81,177,177,177,177,183,183,183,239,111,102,102,246,165, 76, 38,123,154,157,157,125,174, +138,186,135,107, 9, 2,243,139,239, 43,252, 12, 96, 97, 21,208, 53,249,238,135,226, 41, 18,137,166, 17, 4,225, 83,242,128, 69, + 42,149,202, 93, 0,222,253, 63, 28,144,140, 1,124,203,229,114, 71,219,216,216,180,201,200,200, 88, 14,160,182,217,188,185, 0, +230, 90, 88, 88, 12,179,176,176,240,200,203,203,139, 47, 44, 44, 60, 9, 96, 19,128,106, 67,165,151,207,116,252,178, 83,207, 78, + 75,238, 6,223, 93,181,124,155,244,209, 71,199,231, 58, 90,247,232,222,126,233,221,139,161, 43, 23,237, 76,207,171, 97,219,200, +146, 23, 80, 28, 29,201,226,227,100,175,159, 42, 60, 0,253, 0,116, 2,112, 23,192, 69, 67,206,187, 18,105, 7, 96, 81, 73,155, + 55, 1,184,243, 63,126, 31,153,216,219,219,175, 7,208,143,203,229,190,145, 72, 36,147, 0,164,253,205,109,226, 2,104, 13,192, + 7,197,105, 56,158,193,176, 20, 14,213,138,181,181,117, 95, 46,151, 59,173, 36,181,203,174,220,220,220, 75,255,171, 29, 35, 16, + 8,182, 56, 56, 56, 76, 80,169, 84, 74,130, 32,216,242,249, 30,105,154, 78,203,201,201,105,245,111, 27,212, 8,130,120,246, 63, +222,196, 73, 21,124, 86,121, 30, 45,137, 4,102, 92,110,190, 87, 86, 70,196,176,116,233,171,161, 0,224,228,216,244,164,157, 67, +147, 19, 18,137,128,114,104, 56, 80,204, 19,113,119,113, 56,188,230,106,173,198,134,199,229,229, 80,180, 46,140,212,178,211, 50, +162,207, 85,152,108,145,199,225, 56, 39,197,220,177,163,169, 60,240,140,156,192, 51,118,171,180,181, 78, 78, 78,181, 58, 75, 75, + 75, 15, 83, 74,104,228,207,227,113,186, 51, 44,237,195, 50, 0, 73,240, 34,105,189,238, 22, 95,163,249, 37, 63, 63,190,168,182, + 87,176,161, 53, 28, 88,192, 15, 4,186,131,197, 13, 2, 8,138,206, 69, 70, 13, 32, 12, 37, 17,159, 66, 54,202,255,118, 51,128, + 31,254,232, 59,201,217,217,217,178,111,223,190, 91,126,250,233, 39, 99,177, 88, 76,164,164,164,244, 92,176, 96,193,215,207,159, + 63,159, 35,145, 72,210, 63, 36,125, 4,129,249, 12,195,146, 0, 64,146,196, 2, 91, 91, 59, 17,135,195,249, 40,183,145, 94,175, + 23,101,103,103, 77,103, 24,150, 40,249,238,124,150,197, 86, 67, 8,163,145,145,209,112,159, 38,205,231,172,223,176, 73,108,111, +103,103, 66,235, 25, 42, 49, 57, 73,180, 36,224,135,182,113,177,239,182,170,213,234,227,181,121,174, 57, 28,206, 48,161, 80,216, + 23,128,119,201,103, 81, 26,141,230,146, 94,175, 63, 97,232,132,110,111,111,127,143,195,225,212,169,201, 31,235,245,250,148,204, +204, 76,223, 90,118,209, 16, 55, 55,183, 3, 29, 59,118, 20,181,105,211, 6, 2,129, 0, 75,151, 46,157, 43,149, 74,171, 35, 90, + 92, 0,115, 69, 34,209, 48, 19, 19, 19, 15,185, 92, 30,167, 82,169,206, 8, 4,130,110, 91,183,110,117,109,223,190,189,105,102, +102, 38,193,225,112,236,175, 92,185,242,159, 45, 91,182,244,164,105,186,107,117,147, 92, 65, 28,187, 68,216,207,187, 67, 65,220, +157, 37, 0,122,127,120,156, 86, 27,141,102, 57,174,125, 85,236,203,212, 18,242, 97, 48,201,226,241,120, 91, 29, 28, 28,198,170, +139,115, 5,176, 31, 78, 56, 0,160,213,106,243,101, 50, 89,195,218, 60,242, 0,198, 91, 88, 88,140,157, 55,111,158,101,239,222, +189,113,244,232,209,239, 3, 3, 3,243, 11, 11, 11,127, 67,113, 34,204,232, 26, 98,206,207,200,200,248,134,199,227, 17,174,174, +174, 28,149, 74, 85, 19,162,229,133,226, 34,204,207, 0,236, 66,113,234,130,206, 64,241,243, 14,224,231, 82,226, 70,146,228,174, +134, 13, 27,246,143,138,138,218, 13, 96, 85,109,159,117, 7, 7,135,189, 59,119,238, 28, 58, 96,192, 0, 78,118,118,182,115,179, +102,205,142,101,100,100,116,248, 3,134,145,113, 66,161,112,118,211,166, 77, 27, 69, 71, 71,199, 20, 22, 22,110, 42,185,158, 85, + 61, 83, 46, 0,186, 89, 88, 88,116, 93,188,120,177,184,111,223,190,216,183,111,223, 55,129,129,129,242,162,162,162, 91, 40,246, +233,249, 36, 18,200,229,114,167,165,165,165,217,176, 44, 11, 71, 71,199,105, 0,254, 39,137, 22, 73,146, 91, 7, 13, 26, 52,246, +216,177, 99,162,164,164, 36,145,179,179,115, 89,242,108,130, 32,106, 61,127,126,150, 79,150,125,229, 8, 87,245,121,180, 4, 2, + 17, 95,175, 87,127,145, 46,125, 53,244,235,142,219,205, 1,224, 94,200,140,161,118, 14,141, 35, 5, 2, 81,140,208,204,232,236, +160,126,221,154,127,215,183, 35,225,226,104,135, 52,105,150,253,175, 65,193,189, 46, 5,223, 57,139,226, 4, 98, 21, 10, 77,229, +193,152,186,137,232, 7,219, 96,211, 41, 29, 59,174,164,225, 81,120, 34,148, 5, 57,168,227, 96,140, 13,254, 61,224, 96, 41,170, +221,210,203,206,179, 51,205, 21,158, 24, 49,124,148,121,255,111,189,121,238, 14, 14, 96, 89, 33, 98,226,228, 95, 93,189,126,167, +245,153, 83,199,167,153,240, 60,135, 41,178,222, 25, 60,184,181,112,132,177,130,194,183, 92, 14,241,159,246,173, 26,117, 29,254, + 77, 7,178,145,119, 3,188,121, 29,213,227,194,237, 39, 27,200,208,215,183,104, 61,123,216,132,143,243, 47,165, 85, 38,244,251, +136,112,116,237,218,173,131, 80, 40,124, 47,121,146, 70,163,225,223,186,117,179, 93,109,200, 70,233,127,104,181, 26,146,199, 19, +128, 36,137, 57, 62, 62, 77,188,115,114,114,238, 16, 4,113, 32, 61,189,102,218,130, 25,128, 32,159,203,109, 73, 10,133,142,122, +173,214, 26, 0, 8,129, 32, 63,145, 36,155, 44, 94,180, 72,204,225,112,152,220,220, 92, 40,149, 74, 98,226,196,137, 70,113,113, +113,131, 36, 18,201,182,106, 86, 36, 8, 12, 12,244,114,116,116,252,168,122,172, 84, 42, 21, 12, 24,208,191, 54, 93,239,213,180, + 89,139,217,193,193,215,188, 11,243,242,213,129,155,247,190,208, 25,137, 52,245,188, 27,242,118,237, 59,100, 62,105,236,200, 25, +111,223,190, 14, 67,205,234,213,185, 25, 27, 27,159,221,184,113,163, 79,231,206,157,121,118,118,118,200,204,204, 68, 84, 84,148, +207,237,219,183,191, 61,116,232,208, 92,149, 74, 53, 8, 48,168, 32,170,231,173,195, 7,236, 76,172,172,161,215,233,224,212,180, + 69, 89,126,179,216,219,215, 65, 83, 20, 24,157, 14,222,125,191, 45,209, 38,179,240,246,246,174,109,214, 93,167,198,141, 27, 31, + 89,179,102, 13, 95,163,209,224,201,147, 39,184,115,231, 14, 35,149, 74,171, 75,136,203, 37, 8,226,250,178,101,203, 92,124,125, +125, 77,115,114,114,160,215,235,109,206,159, 63, 63,173,121,243,230,102,174,174,174,130,195,135, 15, 67, 46,151,131,166,105, 43, + 15, 15, 15,171,225,195,135,107, 15, 31, 62, 60, 23,192,250,202, 52, 89,133,113,236, 18, 41,225,209,171, 97,203,209,200, 32,174, +245,154,221, 11, 87,205,234, 19,101,154,173, 94, 30, 30,166,133, 18,209, 2,177, 89, 19,171, 66,201,205, 5,189, 60, 60, 2,175, +197, 27,180, 24, 34, 75, 38,155, 17, 65, 65, 65,162,168,168, 40,145,183,183, 55, 24,134, 41,203,192, 95,154,112,214,211,211,179, + 54,215,113,221,148, 41, 83, 22, 12, 29, 58, 20, 77,155, 54, 45, 75,138,250,227,143, 63, 98,193,130, 5,150,247,238,221,155,123, +252,248,241,185,231,206,157, 91, 15, 32,160,134,218,152, 82,169,105, 31,175, 72, 72, 72, 24,114,246,236,217,145,243,231,207,247, + 4, 48, 29,192,210,220,220,220,142, 37,218, 24, 65, 9,209, 26, 55,119,238,220,169, 1, 1, 1,248,230,155,111,150, 62,121,242, +100,117, 45,181,124, 28,154,166,191, 25, 48, 96, 0, 71,167,211,193,196,196, 4, 58,157,174,254,167, 42, 37, 0,236,156, 60,121, +242,212, 41, 83,166,192,210,210, 18, 58,157,206, 43, 40, 40, 40,112,233,210,165, 95, 2, 24, 95, 73, 91, 71, 79,157, 58,117,129, +137, 32,113, 0, 0, 32, 0, 73, 68, 65, 84,240,168, 81,163,208,170, 85, 43,112,185,197,151,113,227,198,141, 88,185,114,165,248, +250,245,235,223, 30, 62,124,248,219, 11, 23, 46,156,193,251,101,187,106, 36, 12,195,128,203,229, 34, 53, 53, 21,118,118,118, 66, +134, 97,130, 9,130,216,151,151,151,119,238,127,104, 50,255,121,200,144, 33, 35,142, 29, 59, 38, 6,128, 13, 27, 54, 96,246,236, +217,176,183,183,135, 88, 44,254, 76,117,254,119, 52, 90,147,170,213,104, 85, 39, 74,165,178,197,194,153,255, 1, 73, 22,175, 26, + 27,212,115,195,218, 69,147,136, 11,151,130, 91, 84,169,131, 55,114, 66,244,131,109, 16,186,250, 67,163,163,241, 56, 60, 1, 55, + 54,244, 44,158, 45,123, 47,134,134,234, 90, 58,217, 88, 9,140,141,127,214,234,245, 15,225,224,240, 4,201,201,217,213,145, 44, + 91, 7,251, 75,123,246,172, 55,246,169,223, 16, 20,173,131, 36, 75, 2,130, 16,194,197,217, 20,227, 70,247,230,117,236,232,100, +179, 98,197,222,203, 25, 12, 6, 42,115,222, 85,155, 48,212,203, 6, 7, 91,248,120, 14, 29,222,199, 87,216,196,167, 49,248, 66, +227,178, 99, 45, 91,181, 66,203, 86,173,200, 0,121, 81,247,167,207, 94,116, 63,125,253,177, 70,169, 75, 62, 25,147,131, 49,213, + 12, 50,101,132, 99,214,172, 89,176,183,183,127,239, 11,153,153,153,184,125,251, 86,133,191,169,193, 64, 86,246, 31,171, 87,175, + 54,205,207,207,239,189,127,255,254, 46, 12,195,172,206,200,200,120, 96, 8,200, 40,160, 78,129, 80,216,117,236,166, 77, 76,243, +254,253, 57, 22, 14, 14, 36,163,215, 19,233,241,241,214,155,183,109,235,148, 23, 27,107,172,176,178,202,203, 87,169,148, 49, 49, + 49, 48, 50, 50, 34,184, 92,110,235, 10,160, 50, 89, 22, 63,147, 36,177,128, 32, 8, 8,133, 70, 49, 83,166, 76,121, 89,114,172, +206,197,139, 23, 69,253,250,245, 83, 2, 72, 2, 0,161,208,200,153,195, 33,189,138, 51,177,227,103, 67, 8,166,137,137,201,204, + 85,107,214,155, 20,230,201, 84,148, 66,161,179, 53, 19, 19,132,216,148, 83, 88, 80, 84, 36,145,102,107, 22, 47, 95,201,153, 60, +110,212, 76,133, 66, 49,205, 80,146,213,172, 89,179,167,103,207,158,181,179,182,182,134, 76, 38, 67,110,110, 46,158, 62,125, 10, +134, 97, 48,104,208, 32,225, 87,109,219,180, 88,180,120,201,163, 84,137,228, 75, 67,200,150,137,149, 13, 54,248, 54, 47,158,172, +147,114,203,250,103,223,144,190,101,223, 89,153, 86, 80,170,157,251,148, 18, 82, 95,118,237,218,149, 15, 0,227,199,143, 47, 44, + 42, 42, 90, 11,224, 24,170,207,232, 63,119,201,146, 37,206,245,234,213,115, 63,118,236, 24,228,114, 57, 0,216,213,171, 87, 15, + 94, 94, 94,250,187,119,239,194,203,203, 11,166,166,166,184,119,239, 30, 30, 61,122,132, 86,173, 90,153,242,249,252,161, 20, 69, + 85, 72,180, 58,245,236,180, 68,216,207,187, 67,195,150,163, 33, 54,115, 68,224,241, 19,136,126,113,168,131,134,138, 90,194,215, +135,140, 82,177,194, 49,217, 41,226,128, 58,173, 58, 90, 55,104,220, 31,238, 45, 95,218,168,245,247, 19,150,116,175,183,142,107, +164, 62,180,124,147, 52,183, 50,146, 5, 96,195,160, 65,131,134, 4, 5, 5, 89, 0, 64, 68, 68, 4, 50, 51, 51, 97,107,107, 11, + 35, 35, 35,240,120,188,178,250,164,181,148, 49,187,118,237, 42, 35,109, 52, 77,151, 85, 1, 16,137, 68,248,250,235,175,209,188, +121,115,156, 59,119,110, 76, 37, 68,203,183,109,219,182, 71,221,221,221, 93,203,127,168, 80, 40,224,231,231, 7, 0,232,216,177, + 99, 87, 99, 99, 99,182,148, 16, 74,165, 82,249,179,103,207,186, 3,120, 82, 9,179, 84, 73, 36, 18,204,155, 55, 15,137,137,137, +223,239,217,179, 39, 25,128,145, 64, 32, 40, 91, 31, 3,240,106,220,184,241,214,217,179,103, 35, 46, 46, 14,111,222,188,121,138, +218,155, 82,245, 38, 38, 38,177, 58,157,174, 21, 77,211, 80,169, 84, 24, 56,112,160,209,153, 51,103, 50, 57, 28,206,219,156,156, +156,145, 40,246, 73, 49, 84,140, 0,108,154, 50,101,202,212,249,243,231,227,214,173, 91,184,112,225, 2, 70,141, 26, 5,127,127, +127,136,197,226,177,254,254,254,143, 80, 92,208,252, 67,233,186,107,215, 46,232,245,250,143,158, 13, 35, 35, 35,248,250,250,162, + 81,163, 70,184,112,225, 66,215, 79, 32, 90,238,190,190,190, 2,134, 97,160, 80, 40,112,247,238, 93,177,177,177,177,216,197,197, +101, 34,128,255, 25,162,229,238,238, 62, 37, 40, 40, 72, 92,222,250, 35, 20, 10, 81,238, 62,248, 44,127,191, 70,171,202, 21, 86, +153,104,181, 74,138,203, 37,223, 58, 57, 54, 61,121, 47,100, 70,153,233, 16, 32,223,106,181, 74, 10, 0,244, 12,139, 66, 37, 13, + 99, 33,137,164,140, 34,188,142,207,169, 8,234,189, 16, 77,158,177, 27,132,109,146,192,178, 44,180,148, 30,154,130, 12,172,189, +172, 68, 84,154, 26, 90, 69, 62,180, 84,177, 27,150,141,141, 13, 55, 56,248,234,236,155, 55,111, 79,253,237,183,223, 56,105,230, +230,111,138,128, 22, 21, 97, 90, 90,122,152, 50, 2,193,201,221,123,150, 26,179,156,120,196,164, 40,208,192,165, 13,108, 44, 92, +145,145,163,192,195, 55, 87,240,246,221, 37,212,115,116,135,255,204, 94, 70,171,214, 28, 59,193,167,235,186,201,100,137,133,149, +181,179,116, 21,181,247, 90, 12,232,188,120,232,115,227,160, 47, 74,255,232, 11, 98, 91, 55,180,236,236, 12, 91,215,250,194, 49, +254, 43, 71, 3,239, 17,173,242,152,153, 4, 65,238, 38, 73, 98, 42, 65, 16,104,218,180, 89,218,166, 77,155, 42, 74, 5, 78, 53, +109,218, 44,141,195, 33, 93,138, 7,118,114, 23,203, 50,153,213,180,243, 61, 82, 35, 16, 8,231, 23,171,253, 29, 83, 47, 95,190, + 76, 13, 25, 50, 4, 27, 55,110, 20, 44, 88,176, 96, 49,135,195, 25, 95,129,121,239, 61,204,129,128,155, 69,253,250, 61, 86, 63, +124,200,242,116, 58, 34,239,233,211, 66,153, 84, 74,103, 20, 21, 9, 78,189,125,251,205,132, 31,126, 16,184,186,186,226,193,165, + 75,214,217, 10, 5, 43,211,104, 84, 50,153,140,165,105,250,105, 37,152, 11,109,109,237, 68,129,129,129, 94, 83,166, 76,121, 41, +149, 74, 23, 2,128,163,163,227, 90, 0,141, 0, 36,149,251, 12,123,246,156,144, 76,156, 56, 49, 38, 43, 43,107, 97, 85,237, 44, + 39,141,237,108,237, 68,199,247, 30,126,101,101,106, 76,218,186, 56,145, 60, 11, 11, 46, 45, 48,230, 51,128,170,158,107,125, 19, + 0,141, 43,249,237,135,152,132,177,177,241,217,223,127,255,221,142,199,227, 65,175,215,195,214,214, 22,137,137,137,144,201,100, + 40, 42, 42, 66,194,219, 40,212,117,117,197,138,128, 5,142,211, 23, 4,156, 85, 42,149,173, 62,152,204, 62, 46,128,172,163, 62, +210,236, 85, 84,197,224, 67,179,151,129,253, 94, 94, 18, 83, 82, 82, 32, 22,139,225,227,227, 35,126,248,240,225,253, 42, 72, 86, +249, 34,192, 67,219,183,111,111,122,236,216, 49,180,106,213, 10,230,230,230,184,123,247, 46, 34, 34, 34, 64, 81, 20, 41,151,203, + 33, 22,139,177,110,221, 58,184,185,185,161,168,168, 8, 73, 73, 73,214, 60, 30,207,230,131,140,246,101,152,119,131,239,174, 42, +136,187,179, 36,131,184,214, 43,240,248, 9, 76, 28, 62, 12, 14,108,252,125,243,250,196,170, 30,253,218,255,200,114, 92,251,154, +152, 54,181,244,244,233, 7,190, 64,140,233,243, 87, 34, 38,242,162,165,178,232,213,247,132, 62,213,117,249,166, 83,179, 42, 56, +119, 2, 0,233,234,234, 58,225,212,169, 83,166,101,170, 23, 14,167,172,230, 97,249, 34,240, 85, 20,124,175,246,122, 18, 4,129, +196,196, 68,216,217,217, 65, 44, 22,151, 21, 16,143,138,138,194,227,199,143, 81, 90,141,162, 18,204,145, 55,111,222,116, 53, 49, + 49,121,239, 11, 44,203, 34, 39, 39, 7, 52, 77, 67, 36, 18, 65,175,215,131,162, 40,232,116, 58,168,213,106,113,163, 70,141,166, +233,116,186, 39, 21, 97, 50, 12, 51,103,232,208,161,237,159, 60,121,226,177,109,219, 54,104,181,218, 13, 25, 25, 25, 24, 60,120, + 48, 24,134, 65,215,174, 93,219,177, 44, 27,189,120,241, 98, 0,192,236,217,179,117, 10,133, 98, 74,109,206,189, 68, 26,181,108, +217,210,227,214,173, 91,232,208,161, 3, 52, 26, 13, 54,110,220,104,182,103,207, 30,179,195,135, 15,219,206,159, 63,255, 64,118, +118,118,207,106, 48, 9, 0, 27, 28, 28, 28,166,118,234,212,201,184,164,134, 41, 14, 29, 58,132, 21, 43, 86, 4, 1, 88,124,245, +234,213,101, 23, 46, 92, 24, 61, 97,194, 4,172, 88,177,194, 95, 38,147,237,175, 12, 51, 33, 33, 1,182,182,182, 48, 51, 51, 43, + 30, 44, 41, 10, 97, 97, 97,184,113,227, 6,190,248,226, 11, 67,206,169,178,118,186, 15, 26, 52,232,192,241,227,199, 77, 83, 83, + 83,113,239,222, 61,212,173, 91, 23, 74,165,210,144,218,176, 55,255,132, 9,187, 82, 76,149, 74,165, 78, 73, 73, 17,175, 95,191, + 30,142,142,142,112,119,119,135,145,145, 17, 8,130,128, 78,167,171,170,188, 90,181,237,236,216, 17,220, 28,137,229, 0,115, 11, +203,239, 89,150,229, 22, 20,228,239,165, 32, 59, 29, 31, 15,237, 95,120,238,255,100,105, 1,224, 37,222,175,121, 40, 45, 35, 90, +151, 46, 93, 98,251,246,237, 75,148,110,157,157, 81,152,147, 99, 25, 99,231,208,228,132,157, 67,227,146,186, 95,228, 91, 14,199, + 50,198,222, 94, 89, 8, 0, 20,205, 34,244,173, 12,175, 98, 51, 16, 17,155, 1, 19,161, 97,202, 23, 13, 69, 23,123,172,178, 44, +212,242,255, 46, 90, 41,101, 62, 52, 84,177,187,135, 86,163, 68, 65,246, 27, 98,200,192,238, 70, 83,167, 78,134,163,163,179,109, +101,120,148,208,200,127,250,236,111, 44,172, 44,120,184,244,240, 26,218,125, 49, 16, 70, 66, 30,114, 11,212, 0, 1,188,139,191, + 1, 48,166,136,140, 73, 65,219,198, 34,244,236,225, 45, 62,119, 58,250, 7, 0, 75, 13,105, 47,157,246, 20,124,207,222,224,233, +117,208,229, 68,131,145, 37, 3, 38, 14, 80, 17, 98,228, 74,147,241,246,254, 25,131,214,140, 12,195,124,111, 99, 99, 35, 91,188, +120,113,167, 6, 13, 26, 80,211,166, 77, 11, 79, 78, 78,158,243,193,106,229,151, 93,187,118, 33, 54, 54, 86,178,122,245,234,187, + 57, 57, 57, 75,106,216,209, 1, 44,139, 45, 37,166,184,156,243,231,207,183, 12, 9, 9,241,223,178,101,139,253,140, 25, 51, 4, + 51,102,204, 24, 7,224,167,170,204,133,133, 66, 97,183,213,247,238,177,116, 90,154,230,200,246,237,130,157,161,161,139, 41,134, +113,178,177,179, 35,190,106,219, 86, 33, 34,201,156,220,204, 76,218,214,195,131,147,120,227,134, 53,107,108,156,126,245,234,213, + 66,185, 92, 94,105,233, 28, 14,135,163,172,200, 92, 88,145, 56, 58, 58,106, 43,242,225,170, 98, 66, 44,100, 88,150,178,168, 87, +143,237,209,245,203, 6,177,209,241,241, 70, 22, 22, 28,207, 6,117, 27,190,126,155,248,148,213,235,213, 4, 65, 20, 26,100, 43, +225,112,134,109,217,178,165,137,153,153, 25, 24,134,129,185,185, 57,178,179,179,161,213,106, 81, 88, 88, 8,109, 81, 1,180, 5, + 5,136, 72, 78, 68,251, 78,157, 48,164, 87, 15,239,195,231,127, 31,166,215,235,131,170,180,231, 53,109, 81,166,201, 90, 89,199, +250,191,182,160, 84, 89, 25,233, 90,223,194, 19,124,177, 24,221,231, 4,124,202,131,254,242,242,229,203, 87, 6, 13, 26,244,205, + 15, 63,252, 64, 74,165,210,107,137,137,137,237, 1,188,169,234, 71, 98,177,184,126, 78, 78, 14,228,114, 57,204,205,205,177,101, +203, 22,216,219,219, 67,169, 84,226,217,179,103,172,139,139, 11,113,247,238, 93,184,184,184, 32, 55, 55, 23, 20, 69, 65,165, 82, +101,104,181,218, 74,205,229, 37,230,193,222,179,123,225,106,244,139, 67, 29,156,137,132,103, 67,231,118,140,141,142,120,155,114, +253,198,195,159,104,181, 81,170, 44,237,230,130,122,173, 95,218,124, 63,111, 5,118,108, 88,134,232, 39,247,242,236,221, 10,119, + 26, 19,154,131, 85,181, 87,161, 80,168,223,190,125,107, 26, 30, 30, 14,130, 32, 96,110,110, 14,145, 72, 84, 33,217,170,133,144, +229, 53, 80, 10,133, 2,124, 62, 31,214,214,214,216,191,127,127,217,196, 91,183,110,221,170, 48,246,118,239,222,125,152,155,155, +155,105,249, 15, 91,183,110,141,201,147, 39, 99,247,238,221, 8, 13, 13,125,175,158,102, 70, 70,134, 84,167,211, 85,117,222,178, +204,204,204, 94, 3, 7, 14,124,113,255,254,125,179,253,251,247,131,166,233, 10, 95,129,129,129,120,252,248,241, 82, 0,111,107, +121, 31,125, 49,120,240,224,123, 71,143, 30,181,200,206,206, 70,233,189,161, 80, 40,160,215,235,209,176, 97, 67,130,166,233,234, +252,222, 72, 14,135,115,126,251,246,237,253, 38, 78,156, 8, 46,151, 11,173, 86,139,237,219,183, 99,193,130, 5,153, 37,139, 82, + 10,192,226,131, 7, 15,142,238,223,191, 63,154, 53,107,230,125,231, 78,229,158, 29,114,185, 28,114,185, 28, 60, 30, 15, 14, 14, + 14, 88,181,106, 21,180,218,226, 97,197,203,203,171,236, 49, 6,176,215,203,203,171, 95, 76, 76,204, 70, 20,251,174,125, 36, 14, + 14, 14, 3, 89,150,157,164,215,235,139, 58,116,232, 96,125,252,248,113, 83,137, 68,130, 23, 47, 94, 96,233,210,165,249, 12,195, +232, 25,134, 33, 84, 42, 85,130,157,157,221, 11,161, 80,104,172, 84, 42,243,114,115,115,215, 0,184,246,119,205,228, 4, 65, 16, + 60, 30, 15,227,199,143, 7,151,203,133,177,177, 49,212,106, 53,116, 58, 93, 25,153, 71, 13,205,210, 13, 26,136,173,185,224, 79, +180, 52,109,228, 63,100, 86, 95, 91, 71, 39,103, 88,152, 9, 17, 21,245,166,253,237, 91, 55,182, 11,184,209,123, 24,173,110, 79, +116, 82,193,159, 94,236,254, 67, 46,242, 15, 37, 90, 31,213, 60,228, 86,220,153, 67,244, 44,123, 42, 71, 34, 17, 80, 2,129, 40, +166, 84,203,101,111,175, 44, 36,136, 33,122,219,198, 3, 64, 83,186,146,129,130, 45,121, 25, 72,180,116,122,196, 70, 71,226,254, +245,223, 97,163,148, 32, 39,161, 57,192,111, 2,173,170, 0,106, 45, 85, 66, 74,244, 8,127,113, 11,133, 5,121,240,105,213, 23, + 32,201,199,149,225,153, 91, 19,125,191,106,217,148, 19,155, 18,137,214, 94,223,193,195,165, 3,146,165,133,144,201, 53,200, 47, + 84,163,185, 79, 0,178,243, 85, 40, 84,170,241, 38,246, 48,156,157, 60, 72,130, 27,223,213, 80,162,165,121,115, 22,154,183, 23, +192,119,111, 15, 65,195,254,224,184,251, 34,229,213, 29,132, 95,221,140,180,215, 15,192, 50,122, 56,122,181, 49,244, 33,217,126, +237,218,181, 54,237,219,183,231,118,235,214,173,217,149, 43, 87,154, 73,165,210,240, 18,130,209,172, 91,183,110,205,108,109,109, +177,117,235, 86, 21, 65, 16,219,107,217,217,101, 26,176,172,172,172,167, 0, 86,159, 61,123,118,251,228,201,147, 97,103,103,215, + 36, 61, 61,189,210, 31,102,243,120,205,198,172, 89,195,242, 56, 28, 54,104,199, 14,254,138,107,215, 54,253,118,240, 32,191, 75, +231,206, 4,203,178, 8, 11, 11, 19,173,223,177, 67, 52, 98,192,128,164,228,172, 44, 58, 36, 52,148,146,166,165, 21,101, 41, 20, + 43,164, 82,105,198,223,113,103,235,116,186, 71, 9,137, 9,206,173,218, 54,183,125, 25,149,240,186,103,151,175,190, 34, 73,146, +140,142, 79, 14,181,181, 53, 19,221,184,126,131,210,233,116,143, 12,193, 18, 10,133,125,187,116,233,194,205,207,207,135,147,147, + 19,178,179,179, 33,145, 72,138, 53, 14, 5,249,160, 10, 10,160, 43,148, 65,175,144, 35,225,217, 83, 52,247,168, 39, 60, 37, 20, +246, 85, 42,149, 85, 18,173,210, 85,102, 69,133,174, 75, 63, 19,152,154, 66, 32, 22,131,168,185,217,112,128,133,133,197, 2,153, + 76,118, 5,192, 42,138,162,166, 47, 88,176,160,245,182,109,219,108, 86,175, 94,109, 54,105,210,164, 83,114,185,188, 57,138,139, +170, 86, 54,129,197,209, 52,109, 13,192,254,214,173, 91,176,179,179, 67, 65, 65, 65,169,166, 69,171, 84, 42,141,114,115,115,161, +209,104,160,213,106, 97,102,102,134,231,207,159,231,209, 52,125,177,186,198,153,213, 39, 86,105,168,168, 37,214,222, 38,233, 20, +109,217, 49, 43,143,201, 95,190, 73,186, 18,192,166, 94, 30, 30,129, 20,115, 47,225, 93,228, 69,203,196,103,119,243,210,223, 41, + 60,246, 95, 73,168,202, 71,139, 5,192, 16, 4,193,122,121,121, 33, 59, 59, 27, 28, 14, 7, 34,145, 8, 98,177, 24, 11, 23, 46, +196,246,237,219,107, 67,180,140, 76, 76, 76,214,144, 36, 57,140, 36, 73, 91,189, 94,143,128,128, 0,244,235,215, 15, 2,129, 0, + 20, 69,149,105, 52, 75,181, 84,213,104, 58,194, 30, 63,126,108,246,248,241,123,195, 86,103, 27, 27,155,219, 26,141, 6,241,241, +241, 56,127,254,124, 39, 0, 33, 53,236,235,248,176,176,176, 94,190,190,190,135, 90,182,108, 89,159,101, 89, 52,105,210, 4,126, +126,126, 56,124,248, 48,194,195,195, 81, 80, 80,192,220,184,113,227, 55, 0, 27,107, 58,135,151, 92,223,134,131, 7, 15,126,112, +236,216, 49,203,220,220, 92,168, 84, 42, 40, 20, 10,156, 58,117, 10,237,219,183,135,141,141, 13,142, 30, 61, 74,179, 44, 91, 85, +223,147, 36, 73,238,223,179,103, 79,191, 9, 19, 38, 96,231,206,157, 8, 10, 10, 66,255,254,253, 49,108,216, 48,100,103,103,219, +111,216,176, 97,116,137,153,112,153,159,159, 31,228,114, 57,158, 61,123, 22,101,224, 51, 15,153, 76, 6,153, 76, 6, 99, 99,227, +242,207, 24, 1,224,240,230,205,155,135,251,251,251,195,195,195, 99, 89, 66, 66,194,102, 84, 16, 37,202, 48,204, 20,137, 68, 98, +201,229,114,173,105,154, 70,106,106, 42,158, 63,127,142,239,191,255, 62, 47, 47, 47,111, 50,128,100, 0,139,199,143, 31,191,106, +206,156, 57,101,247,210,156, 57,115, 46, 93,185,114,165,215, 95,173,205,241,242,178,104, 44,224, 8,103,229, 23,113,172,243,243, +243,203,198, 14,173, 86, 11,141, 70,243,158, 38,139,207,231, 89,183,110,238,118, 89,165, 44, 90,244,230,157,172,210, 2,233,222, +245,205,155,138, 76,204,253,219,119,232, 50,178, 71,175,111, 57,180, 78,135,224,224,139,248,245,215, 93,232,236,235, 5,143, 6, + 77, 48, 99,230, 44,115,141,150, 14,184,113,227,218, 2,139,199,247,175, 21, 21,202, 22, 86,133,249,255, 92, 46,151,144,171,203, + 21,154, 14, 43, 98,144, 37, 41, 28,242, 75,118,109, 44, 45, 45,119,232,245,250,206,102,102,102, 96,100, 49,120,243,252, 9,242, +242,121,208,168,244, 96,216, 98,178,101, 16,113,209,104,113, 47,248, 2,182,108,222,132,220,220, 92,248,126,221, 9,114,174, 43, +220, 92,221,160, 86, 41, 75, 30, 26,128,210,234, 96,107,239,142,151, 47,195,117,133, 10, 69,165, 3, 18,223,136,242,118,179,247, +130,134,250, 18, 70, 2, 1, 10,138,180,200, 47, 33, 89, 71, 79, 15,133, 70,169, 2,173,165, 64,107,117,176,117, 27,140, 47,236, +187,128,209, 95,108, 92,163,203,199,232, 65, 37,222, 3,149,120, 15,198, 95,206,196,239,107,135,127, 48,145, 26, 86,119, 55, 59, + 59, 59,235,245,235,215, 23,195,194,194, 6, 14, 29, 58, 20,119,238,220,153, 4, 96,106,137,249,102,210,208,161, 67, 17, 22, 22, +134,215,175, 95, 95,204,206,206,206,250, 35,122, 94, 32, 16,168, 52,154,226, 57, 86, 36, 18, 25, 85,243, 93,231,214,131, 6,145, + 5, 47, 95, 22,110,126,248,112, 89,224,254,253,252,110, 93,187, 18, 58,154, 6,163,215,163,129,167, 39,209,163, 71, 15,147,195, + 39, 79, 90,115,116,186,199,243,166, 79,191,181,123,212,168,162,167, 10,133,161,142,230,117, 74, 76,134, 0, 80,167,138,207, 12, + 22,141, 70,179,109,202,196,177,221, 66,238, 61,112,117,115,117, 54, 11,190, 17, 18, 46, 52, 22,144, 30,117,235,115,242, 11,242, +184, 43,151, 45, 50,214,104, 52,134,146, 86,111, 27, 27, 27,100,100,100, 32, 54, 54, 22, 26,141, 6, 58,157, 14,140, 82, 1,109, +190, 12,218,130, 60, 16,106, 21,132,122, 61,212, 57,153,168,227, 81, 15,248,111, 68, 98,181,166,168,138,136, 86,233,214,200,204, + 12,124, 19, 49, 72, 30,207,224,226,232, 0, 90,182,105,211,230,228,153, 51,103,248,227,198,141,107,123,243,230,205, 29, 0,146, + 37, 18, 73,215,165, 75,151, 62,221,177, 99,135,112,242,228,201, 13, 55,110,220, 56, 26,192,222,202, 64,212,106,245,201,203,151, + 47,143,112,119,119,183,143,136,136,128, 90,173, 6,195, 48,232,221,187, 55, 80,236, 91, 3, 0,136,142,142, 86,169,213,234,172, +200,200,200,194,228,228,100, 10, 6, 68, 9, 46,223, 38,125, 84,152,113,111,144,189,131,243, 99, 35,227, 58,117, 89,249,203,129, +179,191,115,222,176,249,180, 68,125, 45, 62,190,104, 73,247,122,235, 20, 69,175,190,183,112,145,239,188,118, 41,193, 16, 71,248, +178,232, 66,107,107,107,112,185, 92,240,120, 60,240,249,124, 16, 4,129,153, 51,103, 98,223,190,125,213,153, 14,223, 35, 89,166, +166,166,175, 87,172, 88,225, 50,121,242,100,190,145,145, 17,242,243,243,113,244,232, 81,140, 31, 63, 30,191,254,250,107,133,254, + 47, 6,152,148, 62,212,150,250,143, 26, 53, 10, 90,173, 22,126,126,126, 8, 12, 12,244,215,235,245, 33,181,120,164, 31,135,135, +135,123,134,135,135,155, 1,232, 63,108,216,176,131,131, 7, 15, 70, 72, 72, 8, 46, 94,188,216, 9,197, 65, 31, 42, 0,107, 1, +216,149,108,171,122, 62, 77,236,237,237,119, 49, 12,211,223,214,214, 54,220,203,203,203,231,216,177, 99, 22, 89, 89, 89,165,193, + 15, 72, 76, 76,196,129, 3, 7,164,251,247,239, 47,212,235,245,214, 36, 73, 94,150,201,100, 11,171, 32,108,251, 55,111,222, 60, +182,196, 28,136, 51,103,206,176,155, 54,109, 34,150, 46, 93,138,252,252,124,116,238,220, 25,123,246,236,153, 37,151,203,155,109, +218,180,105,226,144, 33, 67,176,114,229, 74, 40, 20,138,205,213, 45, 86,170, 32, 95, 4,128,175, 54,111,222,236,238,239,239,143, + 51,103,206,160,101,203,150,198, 9, 9, 9,187, 1, 76,168,168,255, 88,150, 69, 66, 66, 2,148, 74, 37, 30, 60,120,128,101,203, +150,229,151, 35, 89,179,166, 78,157,186,106,214,172, 89, 88,179,102, 13, 27, 17, 17,145, 53,120,240, 96,251,125,251,246,113, 26, + 52,104, 48, 75,169, 84,254,101, 68,171, 97, 3,171,117,173, 91,118, 88,224,232,220, 0, 71,143, 29, 71, 94, 94, 94,217, 53, 41, +189, 46, 44,203,162,168,168, 8, 25, 25, 25, 48, 55, 51,197,134,141,171,190,153, 54,105,172, 43,138,211, 96,124,172,178,244,176, +220, 56,120,216,184,185,126, 35,198, 34, 34,252, 5, 14, 31,220,139,200,136,176, 50, 60, 90, 71, 33, 38,234, 57, 98,162,158,195, +222,193, 29, 61,186,117, 34,134, 15, 31,222,123,212,136, 97,182, 0,254,180,212, 17,255, 96,109, 22,240,113, 30,173,125,239, 17, +173,106,212,117, 54,150,150,150,175, 79,156, 56, 97,237,235,235,203,161,105, 26,215,130,131,241,253,212,255, 96,244,168, 0, 80, +176, 4,173,229,131,225, 27, 25,212, 18,149, 74, 9, 22, 44, 20, 10, 5, 66, 67, 67,193, 50, 52, 14,239,219, 4,150,101,202,136, + 22,192, 66, 75, 81,112,118,107,136, 93,129,171,105,240,120, 79,161,171, 56,117, 77, 97, 46, 71,175,163, 89, 72,178, 82,144, 34, +141,132,185,169, 27,184, 60, 55,228,202,148,224,146, 14,208,169,163,161, 47,249,173, 82,145, 6, 21,245,105,253,167,175, 64,123, +202,214, 96,208, 85,169, 84, 71,142, 28, 57,242,205, 47,191,252, 34,232,211,167,143,215,233,211,167,191, 2,128, 62,125,250,120, +153,153,153,225,200,145, 35, 90,149, 74,117,228, 15,212,248,116,105,211,166, 13,242,243,243,145,152,152, 24, 94,229,185,105,181, +214, 98, 59, 59, 78,214,157, 59,186,236,252,124,215, 46, 93,186, 16, 58,154, 6, 73, 16,200, 43, 40, 64,114, 82, 18, 44, 44, 44, +136,215,209,209,226,237, 51,102,156,243,242,241,225,150, 70, 36, 26, 34, 23, 47, 94, 20,161,216, 47,171,202,207,106, 40,138,172, +204,140,177,211,167, 79, 63,119,228,200, 81,243,204,172,204, 24,161, 64, 64,139,197, 70, 78,163, 70, 78,227,202,100,178, 17, 0, +228,134,130,229,231,231, 35, 33, 33, 1,198,198,198,224,243,120, 96, 84, 74,232, 21,114,168,243,178,193,161,180, 16,232,245,176, + 18, 9,225,106,111, 15, 55, 91, 27,131, 48, 99,111, 95, 47,115,124, 47,111, 46,220,208,198, 27, 2, 19, 49, 4,166, 98, 76,187, +116,183,100, 53,202, 7,150,254,100, 8,172,141,179,179,243,239,199,142, 29,227,103,103,103, 35, 44, 44, 44, 28, 64, 1, 0, 83, + 0, 76, 84, 84,212,205,200,200,200,190, 37, 81,119,213, 69,139,109, 58,123,246,108,119, 95, 95, 95,186,110,221,186, 38, 89, 89, + 89,174,249,249,249,140, 84, 42,125, 79, 37,116,253,250,117, 97, 81, 81,145,130, 97,152,115, 37, 36,171,218,252, 69,179,191,115, + 54, 10,125,137,153, 29,123,214,105, 98,102,211, 20,121,244,203, 38,143,195,165, 51,103,127,231,188,109,243,105,137,218,152,208, + 28, 36,244,169,174, 92, 35,181,161, 78,204, 44, 80,236, 43, 21, 26, 26,138,228,228,100, 36, 36, 36,188, 71,168, 38, 77,154,132, +195,135, 15, 27,164,209, 50, 49, 49, 89,179,124,249,114, 23,127,127,127,126, 57, 82,132,233,211,167,163,160,160, 0,129,129,129, +152, 62,125,122,141, 39,254, 15,164, 94,151, 46, 93,250, 56, 58, 58, 34, 55, 55, 23, 14, 14, 14,240,245,245,237, 23, 18, 18, 82, + 23, 64, 98, 45,239,251,105, 61,123,246, 92,181, 98,197, 10,232,116, 58,140, 31, 63, 30,239,222,189, 59,249,238,221,187, 45,110, +110,110, 51,231,207,159,111,111,111,111,143,161, 67,135,154,208, 52, 61,168, 50, 16, 43, 43,171,181,123,247,238, 29,209,167, 79, + 31,146,162,168,175,111,223,190,141,164,164, 36,104,181, 90,208, 52,141,184,184, 56, 76,159, 62, 93, 90, 18,221, 24,103, 64,187, +198, 45, 94,188,120,236,204,153, 51,177,126,253,122, 44, 95,190,252, 55,115,115,115,159,230,205,155,183, 88,190,124, 57,230,205, +155, 7,119,119,119, 88, 91, 91,127,177,116,233, 82,239, 57,115,230, 96,219,182,109, 88,182,108,217,111, 0, 14,212,230, 66, 48, + 12, 67,172, 91,183,174,217,230,205,155, 29, 75, 73, 22, 73,146, 56,113,226, 4, 94,190,124,217, 47, 62, 62,190,162,223,236,113, +112,112,152,228,232,232, 40,184,113,227,134,216,221,221, 29, 52, 77,235, 74, 72,214,118, 55, 55,183,239,227,226,226,208,167, 79, + 31,196,199,199, 31, 1, 48,218,220,220, 92, 49,103,206, 28,145,177,177,177,185, 82,169,252,171, 38,111,112, 72, 98,204,154,149, +243,240,236,101, 52,206,158,229,227,217,179,103,176,183,183,135, 80, 40, 4,203,178,208,104, 52,200,206,206,134,142,210,160, 73, +227,122, 56,180,127, 29,178,178,178, 1,146,168,212,229,134, 32,137,145, 99,255, 51, 16,247, 31, 4, 99,247,238,189,144,203, 21, +149, 44,190,141,208,192,203, 27,206, 78,118, 72, 77, 75, 5, 65,194,230,207, 60,215,127,184,233,176,108, 8,130, 33,233, 29,202, +139,133,133,197,150,160,160, 32,235,206,157, 59,115, 20, 10, 5, 24,134, 65, 7, 95, 95,204,244,247,199,197, 99,199,224,217,214, + 15,132, 86, 12, 90,100, 88,212,131, 90,165, 68,163, 22, 95, 97,200,208, 97, 72, 73, 78, 70,207,190,131,161, 86, 43,203, 86, 24, +165, 26, 45,173,150,130,141,157, 43,174, 95,191,206,193,248,241,111,176,189, 98,165,132,158, 18,188,138,137, 83,183,151,169, 94, + 34,244,217, 97, 80, 26, 10, 77,154, 44, 5,197, 88,195,206,101, 18,116,186,243, 40,204,190, 93,108,198,176,238,140,180,148, 20, +144, 28,254,235,218, 94, 65, 70,145,253, 73,131,110, 65, 65, 65, 65, 66, 66,194,233,208,208,208,145,131, 6, 13,194,245,235,215, + 39, 2,192,160, 65,131, 16, 26, 26,138,132,132,132,211, 5, 5, 5, 5,127, 68,111, 59, 58, 58,246,239,212,169,147, 95,235,214, +173,113,233,210, 37,176, 44,123,223,160, 7,155,199, 99, 73,146, 4,195, 48, 32, 0,228,202,100,120,247,238, 29,114,115,114,160, +211,233,160,144,203, 25,111, 47, 47, 57,203, 48,166, 53,105, 79,249, 8, 67, 84, 16,117, 88,250, 89, 45, 78, 53,249,233,227,135, + 41, 69,114,185,173,165,133,101,145, 64, 32,208,231,203,100, 5,111, 94, 71,104, 13,156, 28, 74, 37, 42, 50, 50,210, 39, 61, 61, + 29, 41, 41, 41,160, 21, 69,224,104,180, 32, 53, 74,116,253,234, 75, 24,131,133, 17, 24,240, 24, 29,120, 28, 30,138,138,163,243, +170, 53,119,232,203, 45, 18, 74, 73, 22, 65, 16,197,230, 66, 19, 19, 8,196,166,239,105,184, 12,185,159,132, 66,225,177, 83,167, + 78, 57, 58, 59, 59, 99,229,202,149,112,113,113,249,194,201,201, 73,105,110,110,110,108,111,111,143, 70,141, 26,225,171,175,190, +194,213,171, 87, 97,192, 53,160, 89,150,237,113,255,254,253,185, 15, 31, 62, 28, 98, 98, 98, 66,204,152, 49,131,219,187,119,111, + 8,133, 66, 40,149, 74,228,231,231,227,248,241,227, 57, 12,195,148, 6,165, 88,139, 68,162, 3, 4, 65, 36, 42, 20, 10,255, 15, + 1, 15,253,210,196, 41, 43,143, 25,207,202, 69, 3, 59,246,172,211,164, 75,207,110,168,231,217, 5, 93,122,166, 0,192, 58, 43, +110,146,223,207,139, 45,206, 89,152, 18, 7,174, 95,187,177,204,183, 99,151,197, 11,228,119, 86,173,223, 39,171,214,159,142, 32, + 8, 48, 12,243, 94,238,160, 15,143,143, 30, 61, 26, 39, 78,156,168,246, 58,146, 36, 57,108,242,228,201,252, 15, 52,207,144, 72, + 36,232,219,183, 47, 6, 13, 26,244, 30,209,178,177,177,129,131,131, 3,146,146,146, 0, 32,215,192,251,106,230,184,113,227, 8, +149, 74,133, 9, 19, 38, 32, 48, 48, 16,126,126,126, 68, 72, 72,200, 76, 0,254, 53,189,217, 73,146,220, 48,127,254,252,185,211, +167, 79, 71, 94, 94, 30,174, 92,185,130,222,189,123,227,196,137, 19,182, 87,174, 92, 89,211,185,115,103,112, 56, 28, 92,186,116, + 9, 52, 77, 87,153,235,139,207,231,247,239,211,167, 15,153,154,154, 10, 62,159,143, 86,173, 90, 33, 45, 45, 13, 74,165, 18, 18, +137, 4,179,102,205,202,200,205,205,237,100,232,115,196,231,243,253,103,206,156,137,160,160, 32, 4, 4, 4, 28, 4, 48,161,160, +160, 96,200,195,135, 15,131, 6, 12, 24, 0,137, 68,130,115,231,206, 97,217,178,101,196,232,209,163,177,115,231, 78,204,154, 53, +235,183, 18,173, 83,101, 55,126, 81, 86, 86,150,121,253,250,245,145,153,153, 9,185, 92,142,115,231,206,217, 93,189,122,181,174, +179,179,179, 89, 66, 66,130,254,167,159,126, 18,248,251,251, 99,203,150, 45, 8, 11, 11,195,225,195,135,209,165, 75, 23, 58, 62, + 62,190, 66, 45, 89, 73,202,134,115, 44,203,222, 48, 49, 49, 65, 81, 81, 81,233,115,247, 67, 64, 64,192,244,181,107,139,149,236, +233,233,233, 24, 51,102,204,168, 91,183,110, 49,157, 59,119, 22,241,249,124,168,213,106,197, 95, 57,107, 51,122, 6, 0,131,186, +174, 98, 4, 95,220,143, 23,225,241,120, 17, 30, 9,129,176,216, 9, 94,165, 82,162, 69,147, 6,104,219,170, 13,210,165, 18, 28, + 57,188, 31, 86, 54,206, 85,142, 35, 44,203,130,207,213,195,219,203, 1,199, 14,239,197,165, 43,183,112,248,200,241, 50,159, 55, + 46,151,135,230, 45,218,162, 85, 43, 95,196, 39,196, 97,255,254,221,176,181,115,253,108, 28,172,165,148,153, 14,203,111, 63, 96, +254, 93,124,125,125, 57,114,185, 28,106,181, 26, 25, 25, 25, 72, 74, 74,130,133,165, 5,226,211, 19,209, 73, 68, 33,131, 41, 68, + 84,248,107, 61,193,225,133, 85,247,135,125, 58, 54, 7, 58, 54,199,247,227,252,170, 88,178,178, 48, 49,179, 41, 54,221,208,116, + 44,182,109,163, 43, 35, 90,180, 94,119, 51,248,198,237, 54,227, 70,247,231, 93,191, 29, 8,157,150,129, 74,103, 14,133, 90, 11, + 5,197, 3,105,222, 27,200, 9, 1,135, 43, 68,187,102, 13,112,238,236, 85,138,165,117,183, 12,190, 64,246, 62,160, 51, 35,203, + 17,173,172, 15,236, 14, 86, 6,155, 14,203, 38, 94,189,254,196,209,163, 71,191,253,242,203, 47, 69,157, 59,119,174, 95, 50,113, + 82, 71,143, 30, 85,150, 36,195,172,169,188,151, 13,222,193,193,161, 5,159,207,247,235,221,187,119,139,177, 99,199,226,205,155, + 55, 56,114,228, 72, 76,131, 6, 13,238, 72,165,149, 71,100,115, 4,130, 92,121, 86,150,133,184,110, 93,174,165,169,105,250,213, + 43, 87,220,187,117,239, 78,164,164,164, 32, 55, 55, 23,106,181, 26, 97,225,225, 44,143,195, 73, 35,204,204,200,232,151, 47, 73, +142, 64,144, 91,153,182,177, 2, 73,170, 38,234,112,109,109,181, 91,174,142,150,245,151, 5, 76,169,167,214,168,125, 10, 11, 11, +105, 46,143,199,115,113,176, 72,142,142, 51,124, 76,212,104, 52,151,110,222,188,249,109,183,110,221,132, 49,175,194, 64, 23, 20, + 64, 91,144, 15, 62,163,135, 85,139,102,224, 80, 26, 64,171,131,179, 55, 11,181, 76,132,144, 39,209, 58,141, 70, 83,109, 82,195, + 82,162, 69,126, 64, 12, 4, 98, 49,132,166,102, 16,138,197, 31, 18,134,234, 86,114,162, 30, 61,122,116,109,215,174, 29, 88,150, +197,190,125,251, 64, 81,148,128,162, 40,104,181, 90, 80, 20,133,194,194, 66, 28, 62,124, 24,187,118,237,122, 8,224, 55, 3, 78, +159, 54, 54, 54, 30, 64, 16,132, 29,151,203, 85,218,218,218,154,156, 56,113,162, 44,221, 68,243,230,205, 97,106,106,202, 71, 73, + 82, 72, 59, 59, 59,222,175,191,254,106,209,175, 95,191,123, 21,154, 59,154,124, 49,175, 30,109,217,209,200,184, 78, 93, 51,155, +166,168,231,217, 5, 0,208,189,239, 56,212,107,224,134,194,156, 87,117,213,170,164,129,124,110,190,229,235,109,146, 55,198,125, +124,198, 42,178,238,190, 67,197,225,253, 21, 78, 20, 36, 73, 86,106,142, 53,132,100, 21,115, 22,210,182,212,207, 7, 0,114,115, +115, 33,149, 74, 17, 21, 21,133,134, 13, 27, 34, 47, 47, 15,206,206,206,208,106,181,104,221,186, 53, 84, 42, 21, 54,111,222,140, + 7, 15, 30, 60, 4, 48,203,128,255, 48,246,244,244, 28,211,162, 69, 11, 92,185,114, 5,207,158, 61,147, 4, 7, 7, 59,251,250, +250,162,110,221,186, 99, 19, 19, 19, 23,149,152,250, 12, 21, 19, 95, 95,223, 25,211,167, 79, 71,100,100, 36,166, 76,153,146,155, +154,154,122,238,228,201,147, 19,150, 45, 91, 70,246,236,217, 19, 82,169, 20, 27, 54,108,208, 63,120,240, 96, 35,128,149,213, 92, +199,183,169,169,169, 46,106,181, 26,121,121,121,160,105, 26, 74,165, 18, 87,175, 94,197,225,195,135, 51, 75, 72, 86,172,161,141, +107,214,172, 89, 35,146, 36, 17, 20, 20, 4, 0, 75, 80,156,177,255,220,192,129, 3, 37, 63,253,244,147,243,194,133, 11, 49,113, +226, 68, 80, 20,133,245,235,215, 99,225,194,133,151, 75, 72, 86, 85,131,232, 47, 14, 14, 14,147,166, 76,153,242,197,156, 57,115, + 16, 26, 26,106,247,252,249,243, 86, 97, 97, 97,112,117,117, 69,110,110, 46,215,218,218, 26, 91,182,108,193,236,217,179,207, 0, +200,121,244,232,209,176,132,132,132,181, 0, 54, 84, 67,218,247, 56, 59, 59, 79, 98, 89,150, 85, 42,149, 73, 1, 1, 1, 27, 86, +175, 94,141,217,179,103,227,245,235,215, 40, 40, 40,128,169,169, 41, 49,127,254,252, 49, 75,150, 44,193,248,241,227, 89,133, 66, +177,235,175,158,168, 89, 86, 15,101,126, 36,244, 26, 75, 52,111,210, 16,205,125,234, 32,248,246, 11, 0, 64,215,193,190, 80, 42, +138,112,240,224, 62,196,198,190, 3,151,199,131,133,149,131, 33,154, 64,104, 11,223, 66, 70, 73,209,173,115, 43,244,238,217, 9, +191, 29, 58, 1, 90, 71, 97,194,184, 17,200,151,201,112,232,208,126,196, 39,196,129,203,227,193,218,230,207, 79,132, 90, 21, 23, +249,199, 19, 45, 3,204, 79, 96, 24, 6, 18,137, 4,207,159, 63, 71, 98, 98, 34, 68, 34, 17, 84,180,158,217,125,243, 1, 67, 16, +252, 52,134,101, 31,178,116, 89,150,226,143, 49,244,122, 73,185,140,181,230,150,150,150, 2,141, 70, 5,154,214,149,155, 85, 8, +128, 0,248, 92,192,209,169, 30, 82, 83, 82, 89,181, 90,125,183,202, 21,148, 70,189,229,194,185, 83,211,191,106,239,107,211,187, +235, 10,156, 59,191, 20,249,133,133, 80, 83, 60, 40,212, 20,148,106,192,194,202, 11,173,155, 52, 69,122,122, 46, 94, 61, 11,145, +115, 53, 74, 67, 28, 69,223,109, 95, 60,206,115,220,247,243, 96,236,222, 30,154,168,115, 96,228,153,101, 26, 45, 35,177, 37,172, +220,188, 33, 83,104,112,234,214, 11,160, 6,165, 94,178,178,178,148, 28, 14,231,232,244,233,211,215,191,120,241,220, 5, 0, 94, +188,120,145, 38,149, 74, 23,100,101,101,213, 84, 39, 93,154, 13,158, 48, 50, 50,126,209,160, 65,131,244, 86,173, 90,153, 15, 28, + 56, 16, 54, 54, 54, 8, 11, 11,195,218,181,107,223, 82, 20, 53, 47, 36, 36,164, 74, 83,143, 86,171,149,188, 56,127,222,172,211, +127,254, 99, 49,175, 95,191, 13,211,167, 79,223,178,114,229, 74,158,167,167, 39,161,163, 40, 68, 68, 68,176,199,142, 30,213,237, + 90,184,112,179,192,196,132,251,244,194, 5, 58, 60,122,154, 0, 0, 32, 0, 73, 68, 65, 84, 30,173,209, 72,254,238,155,216,217, +217,185,163,239,215, 29,188, 55,254,178, 13,106,149, 28, 79, 66, 47, 35, 63, 63, 27,123,247,157,245,118,118,102, 59, 74, 36,146, + 16, 67, 9,240,129, 3, 7,230,182,109,209,162,133,135,171, 43, 34,146, 19, 33, 96,244,224,211, 52, 56,148, 6, 36,173,134,171, + 15, 11,130, 52,133, 52,163, 16,171,131, 78, 71, 26, 66,140,191,248,166, 63, 86,166, 21,128, 32, 8,108,250,210, 7, 2, 83, 49, +248, 38, 98, 76,251,253,118, 25, 49,184,180,114, 33, 4, 98, 49,234,183, 53, 40, 33,188,242,206,157, 59,207, 35, 34, 34, 90,251, +248,248, 96,238,220,185, 72, 74, 74, 2,195, 48,200,204,204, 84, 75,165, 82, 73,118,118,118, 18,138,243,255, 4, 86, 51,137,149, +103, 29,206, 33, 33, 33,101,230,134, 91,183,110,193,201,201, 9,230,230,230, 40, 44, 44,196,228,201,147, 45,126,252,241, 71, 0, +192,243,231,207, 81,158,160,124, 40, 17, 47,162, 54,202,138,216,124, 86,254,114, 96, 30,253,178, 73,151,158,169,232,222,119, 44, +110, 92,250, 13,183,131,111,194,138,155,148, 8,147,162,171, 57,137, 57,133,105, 10,207, 61,222, 45, 39,112,164,138,224, 61, 51, +250,199,112, 28, 29,153, 83, 11,119, 23,202,170,106,171,167,167, 39,236,237,237,203,124,180,184, 92, 46,198,143, 31, 15,150,101, + 13, 37, 89, 37,115, 13,147,173, 86,171,237,141,140,140,144,145,145,129,184,184, 56,196,199,199,151,165, 14, 96, 24, 70,247,195, + 15, 63,240,102,204,152,129,221,187,119,227,238,221,187, 15, 1,172, 0, 96,232, 98,109,196,208,161, 67, 77,181, 90, 45,142, 31, + 63, 78, 3,232,123,234,212,169,231,173, 91,183,230,246,234,213,203,116,231,206,157, 35, 74,250,200, 96,162,101,102,102,198,167, + 40, 10, 59,119,238, 68,106,106,106, 71, 0, 81, 79,159, 62,221, 51,116,232,208, 93, 62, 62, 62, 13, 34, 35, 35,223,201,229,242, +105, 0, 94, 85, 7,150,153,153, 57,174, 85,171, 86,167, 24,134,113,239,214,173,155,201, 47,191,252, 98, 22, 29, 29, 13, 23, 23, + 23, 48, 12, 19,129, 26,150,176,122,247,238, 93,148, 84, 42,245,238,212,169, 19,174, 94,189,186, 78,175,215,175, 1,176,126,234, +212,169,206,201,201,201,104,209,162, 5,172,172,172, 16, 29, 29, 93, 36,149, 74,119,161,184, 36, 81,117, 42,220, 4, 0, 11,246, +236,217,211,116,207,158, 61,126, 86, 86, 86,237,194,194,194,112,255,254,125,108,220,184, 17, 63,254,248, 35, 58,116,232,128,185, +115,231,230, 0,240, 3, 64, 39, 36, 36, 24,148, 55,175, 84,179, 5, 0, 45, 91,182, 76, 95,187,118, 45, 38, 76,152,192,254,250, +235,175, 91,143, 30, 61,234, 63, 98,196,136,178, 57,112,204,152, 49,236,145, 35, 71,198,160,184, 12,211, 95, 41, 58,138,210,194, +204,170, 30,228,178, 20,100,167,134, 66,100,234,128,158, 93,154, 65,169,210,226,226,133, 51,120, 21, 17, 14,146, 36, 97,239,224, + 10, 11, 75, 27,196,196,188, 3,170,142, 54,214, 81, 20, 5, 83,203, 58,144, 23,164, 66,155,245, 2,198, 98, 59,140,253,207, 64, + 40, 85, 20,206,158, 59,131,200,200, 87,224,112, 56,112,112,116,133,185, 69, 49, 38,193, 86, 29,193,252, 89, 0, 84,144, 79,171, + 90,162,197,225,112,238, 92,187,118,237,187,182,109,219,114, 99, 99, 99, 17, 27, 91,188,184,201,207,207,167, 9,232, 79,103, 69, + 92, 24, 94,197,207,187,161, 36, 58,163,124,237, 66,177,169,169, 36,250,109,148,125,126, 94, 38,194, 95, 62, 64,108, 76, 4, 18, +227,163, 64, 81,106,112, 72, 18, 36,135, 68,157,122,141,241,224, 97,168, 86, 77,211,161,149, 97, 22,183, 35,190,200,196,206,115, +216,170,149,139, 46,205,158,183,220,120,200,119,187,241, 42,250, 13,228,180, 3, 88, 22,112,176, 54, 65,115,143,249,144,164,103, + 35,232,183,157, 74,134,162, 70,126,144, 67,235, 35, 76, 0,176,207, 65,163, 93,251,126, 27, 31,120,248,216,242,121, 51, 38,219, + 15, 24, 52, 18,130,188, 55,208,165,191, 64,189,214,189, 65, 8, 45,112,229,250,109,132, 60,127,147,201,232,217,229,246,185,248, + 53,166, 26,204,242, 34,147,201, 30,101,100, 72, 93,202,101,129,119, 17, 10,141,170,139,142,251, 16,243,189,140,243, 28, 14,217, +114,213,170, 85, 58,123,123,123, 42, 50, 50, 18,187,119,239,102, 94,188,120,113,157, 36,201,237, 82,169, 84, 93, 29,166,173, 78, + 23,126, 44, 32,160, 81,155, 65,131,216,225, 51,102, 40, 33, 20,206,220,176,105, 83, 64,118,126,190, 19,203, 48,176,181,178, 74, +219,176,112,225,218,239,134, 14,205,127,253,224,129,113,232,249,243,198, 2,154,126, 97, 64, 59,255, 8,169, 20, 83, 34,145,132, +220,189,123, 31, 7, 3,127, 1, 69,105, 32,149, 36, 3, 0,114,114, 11, 80, 13,201,250, 16,147, 85, 42,149,131,150,252,248,227, +227, 37,179,253, 29,190,238,218, 13, 41,225, 97,160,242,178, 65,232,104,240, 8, 46, 20, 89, 34,100,101,202,177,224,200,201, 44, +185, 82, 57,168,130, 73,162,194,118,150,106,172,132,102,166,224,155,136, 33, 16,155,190,167,197, 50, 50, 51,131,192, 68, 12,174, + 64, 80,145, 3,247, 71,152,114,185,124,240,119,223,125,247,234,233,211,167,150, 19, 38, 76,192, 87, 95,125,245, 82,165, 82,117, + 6, 80, 84,219,235,201, 48,140,228,235,175,191, 38, 9,130, 16,143, 28, 57, 82,152,157,157, 93,150, 89, 93, 46,151,227,234,213, +171,104,216,176, 56,170,255,245,235,215,104,220,184,113,165,152, 19, 23, 68, 74, 0,172,156,253,157,243,134,199,225,210,153, 0, +214,213,107,224,138,219,193, 55,113,255,118,104, 64, 59, 31,102,219, 55, 35, 91,255, 36,234, 60,116,158,119,203, 9, 28,177,153, + 35, 14,157, 61,195,137,122,177,127,181, 82, 25, 81, 31,187,207,253, 80, 89, 59, 9,130, 0,203,178, 31,165,114,224,112, 56, 56, +122,244,104, 77,207,253,100, 96, 96,224,212, 41, 83,166,240,165, 82, 41,222,190,125, 11,133, 66, 1, 35, 35, 35, 4, 7, 7,211, + 0,118, 30, 61,122, 52,248,232,209,163,189, 80, 28, 77,116,171, 38,247,167,137,137,201,244,158, 61,123,226,237,219,183,120,246, +236,217, 25, 0,175, 94,190,124,121, 38, 54, 54,118, 88,135, 14, 29,240,219,111,191, 77, 87,169, 84,129, 53,193,100, 24,166,124, +206,164,210,138, 15,225,114,185,188, 93,104,104,104, 77,251, 93,154,155,155,219,190,132, 88,167,218,219,219,155,133,135,135,195, +205,205, 13, 20, 69,181,173,233,189, 84, 80, 80,240,203,246,237,219,127, 29, 55,110, 28,126,250,233,167,145, 39, 79,158, 28,249, +205, 55,223,160, 79,159, 62, 56,112,224, 0, 94,189,122,181, 14,134,149, 21,171,232,220, 95, 1,120,101,111,111,255,189,171,171, + 43, 54,110,220,136,136,136,136,181, 43, 87,174, 92,248,234,213, 43, 52,108,216, 80, 24, 21, 21, 69,215,102, 12, 1, 0, 51, 51, + 51, 51,157, 78,135,243,231,207, 63, 1, 48,123,228,200,145,118, 91,182,108,241, 19,139,197,200,203,203, 83, 69, 70, 70,142, 0, +112,225,175, 30,235, 88,130, 88, 60, 97,226,204, 61, 19, 39,140, 48,106,213,178, 57,148,133,105, 80,201, 51,161, 44,202,192,246, +192,235, 32, 8, 18,182,182,142,176,115,112, 65,114,114, 10, 30, 94,190,162, 85, 40, 85, 91, 4, 58,102, 93,213,152, 51,138, 49, + 91, 20, 99, 42, 21, 89, 80,201,179,202, 48,237,236,156, 74, 48,147,241, 32,244,138, 90,165, 80,252,162,101,137,159,255,228,115, +255, 39, 75,205,106, 29,150,151,252,252,252, 89,147, 39, 79,238,188, 96,193, 2,107,154,166, 57, 86, 86, 86, 72, 78, 78,166, 79, +159, 62,157, 39,151,203,103,213,166, 53, 92, 30,239,149,167, 87,195,206, 3, 6, 12,160,251,247,239,199, 31, 53,174, 23,215,214, +206, 14, 5,178, 92,196,188, 13, 67,244,155, 23,240,108,216, 12,203, 86,110, 6, 44, 44,170, 45, 36, 89, 82, 86,167,239,138, 37, + 63,156,104,223,177,135, 89,195,198,205,248,205,235,155,131,210,209, 72, 75, 75,195,133,243,225, 84,228,243,251,133, 12,173, 29, +166,204, 49,172, 4, 79, 8, 64, 35, 23,123,125,236,168,163,107, 54,108,159,187,115,239,193,121, 11,102, 78, 48,233,224,219, 29, + 17, 55,127,195,153, 75, 39, 20,106,141,118, 3,159,131, 77,145,185, 80,198,212,240, 26,168,213,106,234,195,249, 84,173, 86, 83, +159,218,211, 7, 14, 28, 64,102,102,166, 54, 41, 41,233, 26, 77,211, 39,171, 40,246,252,145,108, 7,180, 3, 53,154,155, 75,124, +125,123, 45, 9, 14, 54, 26, 51,127,190,118,228,168, 81, 63, 64,163,161, 32, 16,176, 92, 19, 19, 18, 66, 33,239,245,131, 7,198, + 91,167, 78,181, 34,180,218, 27, 7,171, 72, 27, 80,129,252,225, 81,135,165, 26,173, 78,157, 58, 96,204,132,217, 80,149,211,104, + 61,122, 22, 3, 13, 5,131, 53, 90, 37,146,146,148,154,218,110,230,226, 37,103,135,245,236,234,237,227, 94,231,255,216,187,238, +176, 40,174,245,253,206,204,246, 93,138, 72, 71, 20, 43, 74, 81, 80,108,216, 16, 75,236,137, 53,118, 81, 19,141,221, 88, 34,234, + 53,150, 68, 33,154,216, 53,106,212, 88,110,236, 45, 98, 23, 13, 26, 27, 42, 74, 81, 68, 69, 4, 4, 68,122,221, 58, 51,231,247, + 7, 69, 68, 88, 22, 52,191,155,155,187,239,243,204,179, 59, 59,103,190, 61,115,206,204, 57,239,188,231, 59,223,145, 88, 55,168, + 15, 19, 59, 59,100,164,165,225,207,187, 79,116, 43, 14, 29,143, 44, 38, 89, 6,197,149,225,121,190,200,201, 29, 64,247, 89, 11, + 64, 49, 12, 80, 28,198,161,100,230, 80,131, 54, 29, 64, 9, 4,224, 8, 15,181, 90,109,136,211,223,171,231,207,159, 15, 25, 61, +122,116,112, 80, 80, 16,221,171, 87,175,150, 39, 78,156,224, 63,228,222, 81, 42,149,237, 1, 64, 42,149,198,213,170, 85,171,206, +132, 9, 19,160,211,233, 80, 88, 88,136,156,156, 28,188,122,245, 42,123,194,132, 9, 90, 0,144,201,100,226,161, 67,135,154, 85, +101,115,221,209, 36,213,215, 67,235,108,172, 45,120, 57, 34, 55, 61,188, 65,109,193,203,184,246,205,249,141,235,142, 38,169,204, + 28, 10,190, 79,127, 25, 18,147, 82,112, 97,219,222,227,199,152,113,131,134,112,142, 38, 79,253,165, 54,228,104, 85,118, 41,138, +122, 47, 56,169,129, 36,235, 29,228,229,229, 45, 92,178,100, 73,191,172,172, 44,199,222,189,123,139, 92, 93, 93,113,251,246,109, + 4, 5, 5,177,183,110,221, 74, 44, 40, 40, 88, 4, 64, 5,224, 98, 77,202,180,105,211,166, 13, 4, 2, 65,201, 80,218,230,226, +159, 55,159, 56,113, 98,248, 23, 95,124,129,250,245,235,187, 61,126,252, 88,130,106, 60, 71,132,144,210, 81,134,143, 9,138,162, + 98, 55,108,216, 80,199,206,206,142, 58,119,238, 28,203, 48, 76, 77,148,155,221, 59,119,238,108,167,211,233,190,156, 52,105, 18, +124,124,124,192,178, 44,246,239,223,143,157, 59,119, 26, 74,178,244, 34, 38, 38,230,126, 98, 98, 98,151,121,243,230,225,199, 31, +127, 92, 56,111,222, 60, 36, 38, 38, 34, 38, 38,230,193,135,216,205,205,205, 85, 38, 36, 36,200,189,189,189, 91, 71, 70, 70, 70, +250,250,250,186,127,241,197, 23, 8, 12, 12, 36,127,252,241,199, 80, 0,231,254, 19,189,247,147,103,153,251,132,156,224,194,138, +239,215,126,219,184, 81,131,175, 38,142,255,156,105,234,236,142,130,156, 87,176,180,178,133, 99,221,134, 72,123,147,142,243,231, +207,113,233,233,217,187, 57,154, 90,254,236, 89,102,242,135,216,172,227,216, 16,111,222,188,193,217,179,103,185,236,172,220, 29, +208,209, 43, 30,199,103,167,194, 8, 67,148,172, 73,208, 19, 37, 94, 31,172, 44, 44, 44, 14,152,153,153,165,154,153,153,165, 90, + 88, 88, 28, 0, 12,154,125,208,163, 76,235,192,188,179, 13, 29, 42,133, 84,218, 30, 2,193,156, 90, 22, 22,231,204,205,205, 51, +186,118,237,170,217,182,109,155,234,241,227, 40, 62, 41, 41,145,152,155,155,231,148,166,175,200,102, 57, 88, 88, 52, 50, 85,216, +187,127,107,238,216,242, 79, 19,123,183, 60, 19,123,183, 60,115, 71,207, 27, 10,123,183,101, 22, 22,141, 76, 13,202,103, 37,104, +104, 3,107,103, 43,108,105,102, 77, 41,157,173,176,165,161, 13,172, 13,190,118,253,195,126, 28, 69,129, 67,209, 52,108,212,192, +102,137, 13,158, 97,152, 61,142,142,142,246,168, 94,192,186,247,108,142, 1,234,143,145, 72,190, 60,226,239,239, 23,247,199, 31, +163,115, 95,188, 24,153, 19, 27,251,249,131, 67,135,134,111, 30, 62,124,204, 72,137,100,210, 80,160,145,161, 54,237,237,237, 3, +238,223,191, 31,100,232, 86,134,120, 25, 92,158,141, 26,214,185,208,171, 71, 59, 50,125,242, 96, 50,125,242, 96,210,171, 71, 59, +210,168, 97,157, 11, 31, 80, 71, 20,195, 48, 35,228,114,249, 1,133, 92, 30,161,144,203, 35,228,114,249, 1,134, 97, 70, 64,191, + 15,213, 59, 54, 45, 45, 45,239,217,218,218,166, 86,103,179,178,178, 10,171, 70, 62, 71, 54,104,208, 32,145,166,233,117,213,124, +166,245,217,116,150,201,100,177, 10,133,226, 85,217, 77, 38,147,149, 13, 12,101, 41,151,203, 79, 43, 20,138,245,134,216, 92,189, +216,253,219, 27, 23,167,133,175, 94,236,254,109,249, 99, 51, 6, 90, 76,184, 29,188, 60, 99,198, 64,139, 9,134,228,211,198,198, +230, 15, 27, 27,155, 20, 27, 27,155, 20, 91, 91, 91,189,155,149,149,213, 61, 3,108, 74, 77, 77, 77,215,155,154,154,166, 42, 20, + 10,206,196,196, 36, 85,161, 80,172, 67,153,208, 22, 53, 45, 79,154,166, 3,221,220,220, 84, 12,195,236, 42,119,232,199,198,141, + 27,171, 4, 2,193,154,106,218, 52,235,220,185, 51,247,240,225, 67,226,227,227, 67, 0, 88,124,196,122,183,179,176,176, 56,103, +102,102,150, 96,106,106,186, 9,128,162,134, 54, 41, 0, 35,234,212,169,243,160, 91,183,110,133,117,234,212,185, 9,224,179,143, +152,207,126, 3, 7, 14,228, 19, 18, 18, 8, 33,132, 36, 36, 36,144,129, 3, 7,242, 40, 10, 20,249, 33,109,242,226, 41, 83,166, +144, 91,183,110,145, 91,183,110,145,155, 55,111,146,126,253,250,241, 0,198,126, 96, 59,143,143,117,237,174, 13,173, 26,185, 52, +177, 56, 60,106, 72, 39,254,226,169,117,100,233,162,175, 72, 79, 31,119,210,172,177,197,113,103,103, 75,231,143, 97,243,219, 69, +147, 73,143, 46,110,188,107, 35,139, 67,174, 13,173, 26,253, 63, 95,251, 63, 81,213,194, 95,237,112,246, 86, 90,124,151, 44, 85, + 12, 7, 7, 7,100,100,180,147, 10, 4,157, 36, 18,137, 47,205, 48, 87, 51,211,210,102, 23,191,110,113,255, 95, 82,173,222, 14, +189, 17,196,122,150, 36,168,137,205,119, 28,217,107,104,179, 58, 54, 12,178, 89,217,162,210,188, 90,157,108,201,178,247, 54, 65, +111, 25,188, 99,179, 78,157, 58, 95,242, 60,223,192,208, 12,209, 52, 29,151,148,148,244, 75, 77,202,179, 73,147, 38,164,120,120, +155,250,152,245,254, 87,220, 75,255, 75, 54,247,174,109,225,208,172,133,203,252,136,251,143,127, 44, 30, 86, 44,197,178, 25, 22, +166,157,186,117, 93,242,231,149, 63,190, 91,182, 41, 43,239, 63,124,237, 52, 12,244,105,251, 8, 54, 75,130,132, 86,203,166, 80, + 40,220,214,182,109,219, 47,111,223,190,189,139,227,184, 73,255,163,247,103, 63,134, 97,230, 53,109,218,180,101, 76, 76,204, 3, +142,227,126, 68, 5,129, 34,107,144,207, 69, 13, 26, 52,152, 42, 18,137, 36,249,249,249, 89,201,201,201, 75, 0, 28,254,187,149, +167,107,147,218,173, 9, 41, 13,186,189, 50,250,121,102,232, 71,179, 73,120,142, 39,204,247, 49, 47, 50,194,254, 3,245,254, 79, + 35, 89, 59,254, 63,254,184,135,209,166,209,166,209,166,209,166,209,230, 71,183, 41, 51,150,167,209,230, 63,208,230, 63, 18, 2, + 99, 17, 24, 97,132, 17, 70,252,215, 65,105, 44, 2, 35,140,248,219,161,172,170, 85,170,102, 81,122, 88,105,117, 36,193,154, 48, +219,203, 70,155, 70,155, 70,155, 70,155, 70,155, 70,155, 70,155,255,115, 54,255,169, 36,107,135,158,253,191, 12, 70, 89,213,104, +211,104,211,104,211,104,211,104,211,104,211,104,243,127,129,104, 85,184,111, 28, 58, 52,226, 47,199,198, 65,168, 3, 0, 51, 79, + 32,233,175, 72,111,132, 17, 70, 24, 97,132, 17,255, 97,236, 64, 37, 67,135,127, 7,162,229, 0,160, 61,138, 22,190,125, 2,224, + 58,128,172, 15,176,103, 5,224,115,138,162,134, 1, 0, 33,228, 8,138,102,141,164, 27,114,178, 84, 42, 77, 85,169, 84, 54,197, +223,223,168, 84,170,178,107, 25, 80,120,127, 54, 27, 41,179, 85,136, 6, 13, 26,164,170,213,106, 27, 3,254, 62,135, 16, 18, 78, +211,116,132,137,137,201,149,152,152,152,160,234, 92,184,175,175,175, 31,195, 48, 43, 1,128,227,184,197, 87,175, 94,221,243, 23, +214, 91,187,186, 14,118,191,106,117, 90, 54, 53, 45,115, 9,222, 15,228, 7, 0,216,210, 31, 1, 20,139,249,197,223,215, 76, 11, +210, 31, 71,167,186,233,245,160,181, 80, 40,156,110,107,107,219,231,213,171, 87,247, 0,124, 3, 84, 29,213,184,110,221,186, 99, + 5, 2,193,104,142,227, 26, 49, 12, 19,203,178,236,191, 19, 19, 19,247, 25,219, 16, 35,140, 48,194, 8, 35, 12, 32, 91,239,161, + 90, 68,171,153, 37,236, 8, 48, 2, 20,122,130,224, 18, 5, 28,124,146,129,215,134,158,223,183, 25,116, 58,182,232, 63, 69, 52, +184,115,207,233, 29,125,250,244,113,156, 49, 99, 6, 58,116,232,128,219,183,111,123,239,222,189,123,194,225,195,135,195,121,158, +191, 10,224, 54, 96, 80, 40, 5, 5,138,226,180,140,234,211,167, 79,143,149, 43, 87, 50,238,238,238, 80, 42,149,248,227,143, 63, + 58,173, 89,179,102,253,141, 27, 55, 46, 3,248,173,152, 16, 84,186, 0,158, 74,165,178, 41, 89,140,147,162, 40,155,161, 67,135, +134,150, 37, 87,197,235,171, 81,132,144, 91, 20, 69,221,228, 56,238,246,209,163, 71, 19,155, 1,237, 38, 55, 16, 29,157, 29,167, +117, 44,111, 83,173, 86,219,156, 92,189, 10, 2,137, 4,234,188, 92,120,143,127, 75,122, 47,125, 59, 31, 20,207,130, 1,201,242, +253,126,125, 56,128,136,228,228,228,112, 31, 31,159,184,234,214, 48,195, 48, 43,207,159, 63,111, 79, 8, 65,175, 94,189, 86, 2, +248,171,136,150,164,125,107,207,171,167,143, 29,144,230,103,166,162,247,103,195,255,253, 52,241,141, 31,128, 99,239,144,166, 62, +176,165, 40,204,159,178,234, 55, 6, 0,182, 46, 26,245,205,186, 79,176,241,235,139,120, 13,192,183,152,252, 0,192,106, 0, 87, +183,244,129, 45,128, 5, 83, 86,253, 70, 1,192,207,139, 70,205,223,210, 7, 27,166,157,171,118,216,138,169,126,126,126, 27, 87, +174, 92,201,216,219,219, 35, 41, 41,169,183,155,155, 91,211,220,220, 92, 55,232,113, 34,174, 95,191,254,161,206,221, 6, 52, 28, + 60,108,132,220,218,202, 2,201, 41,233,102,135, 14,236,154,204,220,250,163,207,203,151, 47,135, 27,219, 16, 35,140, 48,194, 8, + 35, 42, 65,205, 35,195,183,178,135,172, 64,139,129, 2,134, 26,219,177,181, 91,247,145,125, 59,211,110,174, 77,240, 40,234,241, + 39,167,174,220, 89, 67,223,140, 10,102, 57,178, 79, 33,194,201,176, 20,253, 51, 97,116, 44, 4, 23, 79,254, 86,212, 19, 78, 24, +197,132,134,134, 54,241,242,242, 42, 93, 26,166,123,247,238,232,222,189, 59,181,117,235, 86,207,139, 23, 47,122,238,220,185, 83, + 27, 28, 28,252, 43,244,199, 71,153,222,184,113,227, 53, 27, 55,110,148,248,248,248, 64, 34,145,148, 30, 48, 49, 49,193,128, 1, + 3, 48, 96,192, 0, 38, 57, 57,185,215,233,211,167,123,173, 94,189, 90, 19, 31, 31, 63, 15,111,163, 52,235,197,146, 37, 75, 90, + 87,240,243,121,138,162,158,179, 44,251,192,211,211, 51,177, 41,208,100,114,223, 14,151,166,118,116, 86,204, 94,184,187, 66, 59, + 2,177, 24,123,253,138,250,234,178, 68, 43,238,202, 57,152,152,153,102,200, 77, 77,195, 1, 68, 0, 8, 39,132, 68,196,198,198, + 62,118, 1, 60,219, 91,208,191,238,202,226, 61,170, 65,182,144,152,152, 8,115,115,115,153,143,143, 79, 10, 69, 81,203,254,248, +227,143,143,237,144,215,110,217,252,169,162,172,151,225,120, 29,125, 11,115,134,117,146,207,222,244,251,119, 42,141,238,152,190, +147, 40,138,166, 87,223,228,253, 81,180, 24,239,146,140,140, 12, 31, 0,176,180,180, 20, 3,184,186,238, 14,250,126,221,145,250, +144,216,110, 34,134, 97,182,236,222,189,251,139,177, 99,199, 22, 45, 29,241,231,159, 48, 49, 49,193,138, 21, 43,234,207,157, 59, + 55,128,101,217, 89,149, 41, 89,157,187, 13,104,184,225,199,239,220,242, 50,115,212,219,183, 28,190,235,208,188, 25, 61,101,250, + 92,211, 13, 90,181, 29,199,113, 99,141,202,150, 17, 70, 24, 97,132, 17,213, 81,179,170, 36, 90, 77,173,176,167, 85,115,231,207, + 71,246,235, 36,105,209,220, 29, 34,201,219,208, 45, 94,173, 91,195,171,117,107,218, 63, 63,175,103,232,221,251, 61,143, 94,188, +173, 46,212,197, 31,142, 73,135,159,161,185, 42, 89,148,118,229,103,182,221, 10,178,223, 72, 1, 64, 81,203, 70,181,232,228,235, + 43, 29, 59,118,132,163,163,163, 40, 56, 56,120, 98, 21, 68,107,209,147, 39, 79, 36, 12,163, 63, 30,170,131,131, 3,134, 14, 29, +138,102,205,154,137,187,118,237,186,168, 50,162, 37,149, 74,223, 80, 20,101, 3, 0,181,107,215,230,150, 45, 91,246,128, 20, 1, + 0, 8, 33,228, 22, 77,211,183,121,158,191,243,251,239,191,191,114, 3,108,122,123, 53,187, 62,117,204, 80, 57, 57,186,190, 82, +146,160,202,205,173,240,119,185,137, 34, 77,166, 80,132, 75,228,210, 8, 20,173,229, 21,225,232,232,248,216, 13,112,108,219,172, +193,197,173, 95,143, 50,221, 53,233,187, 42,203,178, 85,171, 86, 77, 61, 60, 60,164, 28,199,161,160,160, 0, 63,255,252,179,185, + 76, 38, 51,239,211,167,207,210,178, 55,128, 43,208, 98,136, 3, 51,105,121, 50, 55,173, 6, 55, 82,173,206,222,173, 95, 14, 29, +208,199,172,117,251,206,120,122,117, 63, 50, 51,243,144,147,157, 15,158,231,223,139,235, 51,237, 28, 82,183,244,199,154,173, 11, + 71, 45,160,104,154,242, 28,244, 13, 62,181,203,153,185,109,219,182, 40, 0, 66,177, 88, 92,246, 62,116,144,213,105,190,166,201, + 39,157,241,243,226, 49, 32, 60, 79, 0,172,169,134,154,101, 99,106,106,122,234,226,197,139,237,218,180,105,131,219,183,111,227, +197,139, 23,152, 58,117,170,102,218,180,105,162,113,227,198, 81,115,230,204,153,177,122,245,234,163, 0,110,188,247, 32, 8, 4, +163, 63, 27, 60, 92,156,159,157,171,210,168,181,154,218, 86,181,120,117,129,170, 48, 61, 43, 87, 53,124,212,151,154,168,176, 59, +163, 1,188, 71,180, 62,176, 60,141, 48,194, 8, 35,140, 48, 0,132,144, 54, 0,172, 1,164, 81, 20,117,183,236,126,113,146,146, +213, 90,202,239,167,163,104, 84,202,178,140,185,116, 20,185,251, 88, 3,224, 0,132, 82, 20,149,245,129, 89,212, 63,203, 48, 40, + 40,136,148,253, 44, 67,180, 8, 33,132,232, 50,158, 19,117,204, 57, 82,120,247,151,247, 54,101,212, 49,146, 18,122,152,220,249, +237, 91,210,212, 74,255, 42,236,125,155, 65, 55,202, 3,100, 74, 27,144, 89, 93,107,169, 66, 67, 67,131,121,158, 15,242,239, 12, + 66, 30,253, 70,200,163,223,200,215,222, 32, 71,143, 30, 61, 31, 16, 16, 16,180,111,223,190, 32, 0, 85,249, 41,165,230,221,189, + 73,238,216,128, 84,134, 39, 79,158,144,109,219,182,145,133, 11, 23,146, 93,187,118, 17, 84, 17, 65,189, 87,175, 94,127, 68, 70, + 70,146,113,227,198, 61,128,158,192,128,174,128, 98,116,125,187,104,245,161,245, 90,205,216, 22, 36,171,139,180,194,235,183,183, +183,127, 39, 63,129,206,118,100,115, 91,103,178,167,167,215,107, 66,200,121, 66, 72, 32, 33,100, 56, 33,164, 25, 0,180, 2,204, + 62,179,183,124,166, 58,188, 65,169,153,212,190,202,117,239, 90,181,106,213,116,222,188,121,153, 26,141,134,196,197,197,145,237, +219,183,147, 75,151, 46,145,147, 39, 79,146, 78,157, 58, 37,151,201,175,237,132,102, 78,169,154,157,203,213, 53,185,139,132, 12, +179,249,238,165,163,228,217,245, 35, 36,244, 96, 0,249,247,191, 70,146, 25,159,181,211,154,201, 36, 42, 0,221, 42, 59,111, 90, + 71, 52,105, 86,223, 58, 38, 62, 62,158,104,181, 90, 50,126,252,120,210,171, 87, 47,242,201, 39,159,144, 30, 61,122,144,238,221, +187,147,110,221,186,145, 43, 87,174,144,228,228,100,210,163,179, 87, 65,127, 87,180,174, 70,214,154, 59, 57, 57,189,142,139,139, + 35, 90,173,150, 4, 7, 7,147,253,251,247,147,224,224, 96,226,239,239, 79, 0,236,153, 50,101,138, 50, 43, 43,139,244,234,213, +235, 21, 42,136, 26,239,228,228,244, 56, 50, 38, 49,113,221,170, 95,174,236,221,124,224,202,241,163,151,174,156,186, 16,122,230, +228,133,187,135,239, 60,140, 61,233,228,228,244,184,130,250,255,160,242, 52,194, 8, 35,140, 48,162,106, 46, 82, 76,180,250, 21, +139, 29,253, 8, 33, 61,202,237,247, 43, 38, 78,239,237,251,251,251, 47, 44,187, 95,146,198,223,223,127, 33, 0,226,237,237,125, +128, 16,210,228, 35,100,127, 82, 5, 91,213,138, 86, 9,216, 87,161, 16, 57,247,129,144,211, 65,151,254, 4,124,118, 60,160,176, +131,146, 50, 65, 70, 74, 60,162,175, 31,211,191,144, 68, 49,206, 62,129, 16, 64,240,227,199,143, 17, 29, 29,141,196,196, 68,200, +229,242,247,210,253,249,231,159,144,201,100,176,183,183, 55,140,233,106,222,237,231,194,189,156, 96,226,237,131,244,145, 95, 33, + 56, 56, 24,111,222,188,129, 72, 36,130, 88, 44, 6,203,178, 85,218,163,233,162, 21,127, 75, 84,172,138,210,248, 0, 2, 73,109, +147,211, 91,151,206,106, 64,223, 10, 18, 42, 19,158, 33, 89,197, 25,166,228,153, 40, 32, 87,200, 83,100, 50,121,233,112, 33,128, + 8,138,162,158,182, 2,132, 10, 19,233,233, 95,191,159, 99,199,132, 5, 75,149,207,194, 43,180,209,163, 71,143,201, 0,150, 18, + 66,178, 61, 60, 60,108, 87,174, 92,105,145,148,148,132, 71,143, 30,225,240,225,195,105,108,209,133, 82,132,144,229, 0,208, 30, +144,214,178,174,117, 97,243,183,179, 76,113,245,144,184, 38,119,145,185,235,128, 51, 67,198, 77,153,182,113,214, 0, 20,228, 41, +241,219,165, 48,156,191,255,252, 83, 0,127, 66,143,223,219,150, 27,120, 6,164,117, 31, 60,120,240,131,107,215,174, 89,237,220, +185, 19, 44,203, 86,184,237,220,185, 19,151,175,223,159, 9,224,158,129,217,114,104,208,160,193,229, 59,119,238, 88,203,229,114, + 92,186,116, 9,217,217,217,165, 74,150,159,159, 31,149,157,157, 61,226,231,159,127, 30,242,242,229,203, 31,175, 95,191,158,129, +162,181, 32,223,185, 17, 24,134,121,206,178, 90, 23,123,215, 38,130, 97, 3, 58,119,206,207, 8,135,137,165, 7,110, 61,124,126, + 58, 59, 43, 67,201, 48,204,243,178,233, 63, 70,121, 26, 97,132, 17, 70, 24, 81, 61, 80, 20, 21, 68, 8,233, 79, 81, 84, 80,249, +223,202,127, 47, 73, 23, 16, 16, 80,186, 95,114, 78, 96, 96,224,170, 50,251,133, 31, 41,123,122,157,225,187, 22, 51,200,174, 21, + 37, 82, 63, 58, 14,117,244, 41,136,156, 58, 66,220,236, 83, 48, 78,157,144, 16,126, 21, 15,207,173,195,171,168, 63, 65,120, 14, +246, 77,219, 26,154, 17,149,139,139, 11, 84,170, 34,215, 44,181, 90, 13,145,194, 66, 53,103,210, 40, 41, 0,240, 2,169,186, 12, +131, 53,200,160,105, 71, 95,180, 77, 37, 8,181, 45, 18, 42,218,166, 22,157,247,253,248,241, 16,137, 68, 16,137, 68,160,138, 93, +127, 12, 33, 90, 84,113, 98,190,104,248,170,162, 76, 80,133, 18,225,111, 7,151, 78,111, 43,121, 25, 33, 86, 71,222, 66,178,154, + 39,167, 83,185, 51,134,228, 87,174,144, 39,201,228,242, 8,153,137,162,148,104, 81, 20,245, 28, 0,136, 80,184,111,255,242,233, + 30,138,212, 88,133,234,110, 48, 82, 84,188,182, 18, 51,203,207,157, 59,103, 35, 16, 8,236, 56,142, 67, 66, 66, 2,162,162,162, +176, 97,195,134,212,188,188,188,174, 97, 97, 97, 49,101,185, 35, 39, 19, 31,222,183, 98, 86, 67, 65,120,136, 84,253, 60,178,218, +119,143, 85,243,129,189, 62,237,234,121,102,242,152,197, 24,216,247, 19,140,235,234, 70,226,146, 51, 85, 0, 46, 21, 75,175, 85, + 33, 41, 44, 44,172,103,151, 46, 93,254,221,178,101, 75, 87, 66, 8, 90,180,104,129, 17, 35, 70, 96,223,190,125,120,248,240, 33, +114,115,115,181, 23, 47, 94, 92, 15, 96,183,129,217,146, 91, 88, 88,156,191,114,229,138,181, 92, 46,199,197,139, 23,161, 84, 42, + 97,111,111,143,105,211,166,137, 3, 3, 3,247,230,230,230, 14, 11, 8, 8,144,198,197,197,109,190,112,225, 66,125, 20,173, 59, +247,222, 77,160,209,104,118,252,182,111,207,198,105,211,103,212,185,114,251, 81,176, 58, 63,207,220,201, 41, 49,215,218,194,196, +116,253, 15,203,235,105, 52,154,201, 21,151,231, 31, 53, 42, 79, 35,140, 48,194, 8, 35,222,131, 94, 46, 82,150, 60,149, 39, 91, +213, 33,105, 0,148,254,254,254,139, 40,138, 10,242,247,247, 95, 20, 16, 16,160, 4,144,252, 87,144,172, 82,162,213,191,127,255, +144,160,160, 32,244,239,223, 63,164, 82, 19, 60, 7,109,220, 53,104,227,174, 65,230, 61, 19,191, 7,140, 44,119,241,124,141,115, + 55, 96,197,165, 43,106,181, 90,176,103,207,158, 82,191, 45, 0,224, 56,238,163,215, 98,117,136, 86, 49,209,123, 47, 19, 13, 36, + 38, 33, 59,190, 30,214,222,146, 43, 20,106,254, 60,141, 36, 53,207,254,248, 76, 91,120, 55,155,172,174,204,230,201,217,147,145, +120,253, 50,228, 38, 38,137, 95, 92,139, 40, 85,177,138, 73,214, 11, 0,168, 47, 49, 13,222, 54,107, 96, 39, 59, 17, 68,154, 51, + 71,144,172,230,213,219, 94,234,118, 87,114,179,129, 16,130, 23, 47, 94,160,176,176, 16, 55,111,222,196,177, 99,199,210, 42, 32, + 89,104, 32, 49,249, 99,215, 55,163,219,153,229,189, 22,105,238, 94, 70,178,154, 55,104,168,203,170,197,192,142, 34,154,186, 72, +209,140,172,123,251,166,152,253,229, 32,172,219,245, 59,171,177,233,220,127,227,169,179,159,231,171,181,139, 12, 36, 89,165, 98, + 99, 88, 88,152, 91, 88, 88,152, 4,128,239,136, 17, 35,206, 14, 25, 50, 4, 33, 33, 33, 56,125,250,180, 51,128,148,226,116, 43, + 80,180, 80,246,106, 0,177,149, 9,143, 34,145,232,224,229,203,151,221, 29, 28, 28,112,249,242,101, 40,149, 74, 76,153, 50, 69, + 51,125,250,116,145,159,159, 31,149,147,147, 83,170,100,221,188,121, 51,163, 50,146, 5, 0, 73, 73, 73,231,142, 29,222,223,161, + 75,151, 46,131, 26, 58, 55, 51,139,205,203,125, 35,151, 75,101,215, 67,174,138,238,222,185,177, 57, 41, 41, 41,180,226,242, 12, + 54,184, 60,141, 48,194, 8, 35,140,168, 28, 6,113,145,114,202, 84,117, 80,230, 60, 97, 64, 64, 64, 84, 64, 64,192, 59,138,215, + 7,162,252,172,195, 51, 37,125, 90,141,226,104,113, 57, 9,239, 95, 0,207, 87,231, 98,223,251,205,194,194,130,149,201,100,239, + 16, 45,222, 64,155,153, 39, 14, 32,118,234,168, 82, 37,171, 68,217, 66,111,191, 15, 34, 90, 60,207,223, 4,240, 78, 38,228, 54, + 77, 71,174, 31,224,218,209,173, 97, 29, 90,119,120, 3, 94, 21,178,170,165, 79,180,170,232, 60,242,233,227, 10,156,172, 75,109, +178, 58, 72, 21,178,120,153,137,162, 60,201,122, 9, 0, 10, 91,231, 33, 63,246,105,214,213,179, 89, 99,154, 61,180, 22, 73,133, +186,124,255,199, 90,109,108, 1, 57, 94, 73, 25, 46,253,228,147, 79,150, 90, 90, 90, 74, 55,110,220,104,238,228,228, 4,150,101, + 53,229, 73,150,220,166,233,200, 13, 3,155,119,108,106,103, 65,235,142,110, 66,162,146, 43,220, 16,171,219,107, 8,201,178, 50, + 55,185,176,109,213, 84,153, 92, 34,132, 74,165, 66,224,214,163,184,120, 35,178,127,122,228,201, 11, 0, 46,124,192, 13,249, 69, +255,254,253,215,173, 88,177, 2, 58,157, 14, 19, 39, 78,196,243,231,207, 47, 62,121,242,100, 67,189,122,245,230,125,243,205, 55, + 14,118,118,118,248,252,243,207, 69, 58,157,206,175, 18, 27, 63,252,246,219,111,253, 61, 61, 61, 17, 18, 18,130,236,236,108,216, +219,219, 99,250,244,233,226,128,128,128,189,185,185,185,195, 86,173, 90, 37,125,241,226,133, 94, 37,235,157,251,154,227,190,223, +190,110,234,188, 54,237, 59,209,207,158,197,176, 9,109,125,232,171,151, 79, 95,179,180,180,220,155,144,144,240,182, 60, 7,181, +168,118,121, 26, 97,132, 17, 70, 24,241,113, 64, 81,212,153, 98,191,171,119, 84,174,242, 36,172, 68,177, 42,187, 95, 62,125,241, +241,143,241,178,188,163, 2,226,245,110,120,135,254,253,251, 27, 60,173,158, 47, 72, 51,136, 60,149, 71,223,102,208,213, 49,129, + 96,145, 15, 13,145,194, 66, 53, 96,197,165, 43,149,165, 85, 40, 20, 6, 43, 90,188, 90, 85, 85,165, 84,139,104, 21,251,104,157, + 39,132,188, 67,180,204,109,155,250, 44,248,102,214,250, 78, 67,122,211,169, 95,122, 35, 59, 95,173,254,230, 17,203,191, 42,212, + 79,178,138,122,113, 93,156, 92, 97, 18, 33, 85,200,203,146,172, 4, 0,144,218, 52,110, 59,127,246,180,173,221, 70, 14,160,210, +166,116, 66, 86,182, 82, 61, 47,138,165,146,148,100,216, 99,224,106, 69,230,174, 92,185,178, 29,192,118, 31, 31,159, 84,133, 66, +129,252,252,252,247,234,160, 36,191, 29,135,244,166, 83,191,104,135,204, 2,173,250,155, 40, 22,201, 74,254, 96, 85, 36,203,186, +150,233,133,109, 43,167,202,147, 95,189,132, 72, 36,130,137,137, 9, 46,253, 25,129,244,168, 83, 31, 66,176, 64,211,244, 50,127, +127,255,165,211,166, 77, 67, 70, 70, 6, 78,159, 62,141,190,125,251,226,192,129, 3, 78,103,207,158, 93,231,235,235, 11,134, 97, + 16, 20, 20, 4,157, 78,247,180, 18, 51,131, 38, 77,154, 52,111,200,144, 33, 8, 13, 13, 69, 74, 74,202, 59, 74, 86,118,118,246, +136,173, 91,183, 14,137,139,139,171, 82,201, 42,135,182, 13, 26,183, 18, 45, 92,242, 19,212,133,111, 4,105, 73,183, 67,130, 47, +209,183, 50, 51, 51,229, 0,114,106, 90,158, 70, 24, 97,132, 17, 70, 24,172,106, 85,198, 69,210,138, 73, 84, 90, 69,251,101, 8, + 86, 69,251, 84, 57, 21, 76, 83,238,248,195,191,242,154, 12, 82,180, 4,182,205,193,166, 70,150, 33, 90,111,222, 57, 46, 53,173, +109,208,208,161,142,133, 96,219,238,210, 56, 90,210,140,140, 12,169,149,149,149,170, 44, 65,144,203,229,112,112,112, 64, 86, 86, + 22,118,236,216, 1, 84,237, 20,205,154, 13, 25,131,182, 35, 39,226,174,163, 24, 68,167, 45, 85,182,182,141, 31,255, 14,217, 18, +137, 68, 37,190, 97, 85,117,186,119,138,149,166, 91, 0, 72, 43,231,134,223, 73, 21,138,241, 82,171,186, 86,179,167,126, 33,140, +123,163,198,149, 78, 11,179,143,254,176,192, 36,145,152, 76, 75, 64,206,141, 42,236,197,126,246,243,254,242, 74,214,171,150,206, + 13, 23, 75,229,210, 47,197,181,235,219,249,207,153, 42,140, 75, 85, 83, 87,218,126,147,123,108,245, 55,242, 23, 48,157,247, 10, +217, 87, 13,168,158,165,125,251,246, 93, 74, 8, 33, 60,207, 47, 1,128,178,249,157, 51,253, 75, 97,236,107, 21,130, 59, 45,206, + 58,246,195, 2,211, 68,232,207,175, 85,139,129, 29,109, 45,204, 46,108, 91, 53, 77,158,146, 20, 15,137, 68, 2, 83, 83, 83, 36, +166,230, 64, 40, 96,148, 31,120,191, 73, 58,119,238,188, 96,234,212,169,136,136,136,192,148, 41, 83, 82, 18, 18, 18,142, 31, 58, +116,104,202,183,223,126, 43,232,213,171, 23, 82, 82, 82,176,102,205, 26,221,159,127,254,185, 10,192,154, 10,239, 71,129,224,139, +239,190,251,142, 36, 39, 39, 83, 47, 94,188,128,189,189, 61,102,204,152, 33, 94,181,106, 85,169, 79, 86,117,148,172, 18, 36, 37, + 37,133, 92,188,124, 11,159,158, 91, 15, 86,167, 14,201,206, 72,184, 22, 29,155, 21, 82, 91, 44,158, 91,167, 85,139, 26,149,167, + 17, 70, 24, 97,132, 17, 31, 69,197,186,171,111,255,111,128,138,134, 14, 13, 34, 90, 79, 55, 45,158,224, 60, 97,218,124,200,156, + 58, 66,253,248, 4,248,252,212, 82, 69, 75,106, 98,129,218,245, 92,145, 93,160,198,145,224,251, 0,240,180, 58,185,202,203,203, +131,151,151, 23,182,248, 53,237,166,202,203,144,202, 0,168, 37,102,170,147,226,206, 87,206,158, 61, 91,200,243,252, 65, 0,103, +171, 48,179,204,221,221,125,243, 79, 63,253, 36,118, 29, 57, 1,249,183,175,151, 87, 80, 32,147,201, 32,145, 72, 16, 30, 30,142, + 43, 87,174,104, 0, 44,171,162, 66,239,176, 44,251,240,208,161, 67,175,154, 52,172,211,219,171,165,199,204, 69, 11,253, 77, 31, + 93,191,136, 37,171, 54,243, 77, 90,247,202, 9, 60,112, 50, 47,199,164, 94,119,101,202,147, 7, 6, 92,234,195,114, 36, 43,217, +165, 65,221,110, 45,155,187,207, 95,178,100,177, 89,212,245, 75,248,118,245, 54,226,236,217, 35,103,245,177, 83,185,233,242,250, +159,168,222, 68,135, 26, 82,134, 33, 33, 33,219, 1,108, 47,217, 47,159, 95,255, 21, 27,248, 12, 99, 47,114, 0, 0, 32, 0, 73, + 68, 65, 84,166,109,122,103, 5, 30, 56, 86,144,107, 90,175,135,190,252, 90,187, 14,234,224,104,109,113, 97,211,247, 95,201, 95, + 39, 37, 64, 34,145,192,196,196, 4, 9, 41,217, 88,186,254,112,129,150,231,123,127, 40,209, 50, 53, 53,149,104,181, 90,108,217, +178, 5, 9, 9, 9,222, 0, 18,238,221,187,183,109,248,240,225, 27, 91,180,104,225, 18, 21, 21,245, 52, 63, 63,127, 26,128,232, +202,140,212,170, 85,203,219,218,218,154,186,117,235, 22,190,250,234, 43,205,140, 25, 51, 68,227,198,141,163,178,178,178,106,170, +100, 1, 0,234,212,169,227,211,179,123,123,116,236, 57, 37, 68,163,202,190, 22, 23,189, 55,132, 38, 55,164, 53, 45, 79, 35,140, + 48,194, 8, 35,254,103, 80,179,192,224, 62,128,160,169, 37, 38,187,215, 17,189,222,247,195, 12,146, 23,123,147, 40, 67,183,147, +220, 19, 95,146, 51,107,198,145,179,155,102,147, 41,253,220,137,139, 13,245,186,169, 37, 38,251,188, 79,220,222, 89,221,187,111, + 51,232,122, 54, 6,233,217, 24,164, 95, 83,232, 0, 44,106,213,170,213,201,233,109,223,198,209,154,222, 22, 4,192, 87, 0, 76, + 42,201, 86, 69, 43,134,219, 3,216,225,229,229,197, 94,189,122,149, 60, 25,214,131,132,185, 88,145,105,211,166,145,111,191,253, +150,140, 26, 53,138, 88, 91, 91,179,197, 5, 97, 95,149,205, 79, 63,253,212, 17, 0,234,214,173, 91,171,181,107,147,215,225,193, +167,201,181,125, 27,201,174,233,131, 73,187, 22,174,233,118, 46, 93, 30,202,236,155,181,172,162,248, 74,109,218,217,217, 45, 36, +132,244, 38,132,216, 3,128,179,179,165, 73, 43,151, 38,201, 15, 47,159, 38,215,247,111, 38,187,166, 15, 38,237, 61,220, 50, 28, + 93,125,163,165, 54, 46,109, 13,177, 89, 17, 42,204,111,115,151,116,219, 38, 29, 30,232,201,111,169,205,134,109, 63, 63,245, 42, + 57,149,220,185,115,135,156, 61,123,150, 92,191,126,157,236, 59,116,138,212,107, 51, 44,223,170,197,192,142,213,184,117, 42,203, +167,121,191,126,253,200,211,167, 79, 73,159, 62,125, 8, 0,243, 26,218, 60, 25, 23, 23, 71, 34, 35, 35,201,162, 69,139, 8,128, + 61, 83,167, 78, 85,230,228,228,144, 30, 61,122, 36, 20, 19, 44, 65, 77,242,217,168, 65,157,192, 65, 3, 58, 47,155,254,213, 16, +159, 15, 45,207,143, 8,163, 77,163, 77,163, 77,163,205,255, 5,155,255,205,176, 47, 86,181, 74, 62, 91, 25,164,104,133, 0, 44, + 50,176,189,185,141,246,223,171,214,108,154,187,101,251,158,249, 11,102,126,161,232,220,169, 39, 34, 46,255,138, 99, 65,135, 10, + 84,106,205, 26, 17,131,159, 34, 51, 80, 24, 83, 69, 46,138,227,104,189,131,176,176, 48,121,237,198,111, 99, 48, 61, 43,138,205, +186,173,154, 23,152, 2, 96,210,253,251,247,127,242,245,245, 93,249,101,199,182,131,167,119,232, 6,157, 78,135,125,251,246, 33, + 62, 62,254, 56,128,197,134, 42,110, 17, 17, 17,233,110,141,157,102, 9, 25,193,252,105,163, 6, 89,167, 61,127,132, 87,143,195, + 0, 0,106,181, 82,247,250,233, 53,207,234,100, 78, 38,147,221,177,182,182,126, 98,109,109,157,213,180, 97,221, 73, 18, 8,151, + 76, 25,241,153, 77, 70, 92, 52, 18,163,138, 70, 70,213,170, 66,237,171,167, 87, 93,106, 82,187, 78, 78, 78, 18,133, 16,147, 43, +204,175, 70,165, 75,125, 22,221,210, 16, 59,133,106,205,170,229,235,246,125,242,253,252,241, 18, 51, 51, 51,220,143,124,134, 37, +107, 15, 20, 40, 53,186,222,233, 17, 39, 63,202,240, 24, 33, 4, 58,157,206,224,137, 14,149, 96,129,167,167,103,179,149, 43, 87, + 58,251,249,249,225, 67,149,172,178,136,141, 75,242,175, 83,183,145,219,179, 39,247,125,107,203, 68,255,254,144,242, 52,194, 8, + 35,140, 48,226,127, 6,253,138,197,156, 73,101, 62,195,170, 36, 90, 37,136,124,131, 66, 0, 43, 26, 50,249,219, 22,174, 92,183, +148,166,214,143,231, 9,249,149,165,177,252, 69, 6,210, 62, 48,115,133, 66, 1,216, 79, 6,142, 18, 0,128, 80, 80,179, 14,178, + 24, 79, 1, 12,249,229, 70,104,155, 95,110,132,254,171,248,183,239, 1, 84,107, 44,215, 84,128,200, 78,110,141,234,116,110,229, + 46,101, 56, 37, 94, 61,126,142,204, 2, 21, 46, 69,197,103,211,132,254,181,186,153,122,241,226,197, 31, 0, 96,107, 46,127,220, +217,173,113,189, 46, 94,238,114, 33,165,193,171, 71,247,145,163,212,224, 98, 84,124, 14, 40,170,198, 14,213, 31, 43,191,169, 17, +167,238,254, 14,170, 7, 69, 81,151, 23, 77, 31, 41, 89,186,246,224, 71, 37, 89, 0, 10,147,146,146, 50, 10, 11, 11, 45,147,147, +147, 53,168,121,144,184,103,185,185,185, 45,102,207,158,189, 98,222,188,121,243,127,248,225, 7, 81, 77,124,178, 42, 67, 86, 82, +252,137, 46,238, 31,175,254,141, 48,194, 8, 35,140,248,159,192,164,114,159, 48,152,104,149, 18,134, 55, 72, 3, 48,173, 81, 35, + 50, 39, 54, 22,154,143,149,179,138,148,174, 15,196, 93, 0, 3,106,124, 54, 77,229,221,126, 26,159,127,231,105,124, 62,120, 66, +120, 66,212, 52,141,196, 2,173,118,213,211, 23, 73, 53,159,117, 71, 81,220,221,103, 9,202,123,207, 19, 85,132,231, 9, 79,136, +134,162,240, 90,167,227, 87, 69,189,136, 63,245,119,200,111,122,196,201, 27, 65, 44,213,249,198,157,200, 57, 5, 5,218,205,233, +143, 79,222,252,136,245,162,139,136,136, 24,237,237,237, 61,129,227,184,109, 0,116, 31, 96, 75,195,178,236,130,192,192,192,227, + 17, 17, 17,135,111,222,188,153,242, 49, 72,214, 95, 90,255, 70, 24, 97,132, 17, 70,252, 83, 81,179, 69,165, 43,195,199, 36, 89, +127, 71, 68, 62,123,233,245, 87,216,141,122,246,178,249,127, 67,126, 83, 31,159,184,151, 10,140,248,139,138,247, 34,199,113, 23, + 63, 38,169, 62,127,254,124, 3, 84,176,172,206,223,173,254,141, 48,194, 8, 35,140,248,199, 98, 82,101,228, 75, 96, 44, 27, 35, +254, 1, 32, 31,139,100, 25, 97,132, 17, 70, 24, 97, 68, 13, 80,169,162, 69,161,242,153, 3,151,171,241, 7, 53,153,125,112,217, +104,211,104,211,104,211,104,211,104,211,104,211,104,243,127,206,230, 63, 17,246, 40,114,136, 63, 83,252,169,151,124,125, 76, 24, +167,190, 26,109, 26,109, 26,109, 26,109, 26,109, 26,109, 26,109,254,211, 81,161, 35, 60, 80,228, 60,108,132, 17, 70, 24, 97,132, + 17,255, 77,144, 20,111, 53, 61,110,132, 17,127, 53,217, 42, 37, 92, 53,241,209,106, 82,252,249,236, 47,204,236,116,123,123,251, + 73, 30, 30, 30,174, 34,145,136,206,203,203, 91,126,245,234,213,101,229, 19,117,118, 19,220, 99,104, 56,190,253,133, 2, 40, 6, +160,105,112, 4,175,174,135, 43, 91, 27,235,253,111, 13, 39,153,153,245,239, 20,205,136, 57, 86, 11, 78,167, 69,145,187, 85, 17, +120,158,141,231,180,234, 94,149,157,108,231, 57,168, 30,203,241, 63, 0,100, 11, 64, 79, 5,248,173, 20, 4, 83, 8,216,159, 41, + 48, 95,129, 33,171,193, 81,223, 8,132,204,194,148,176,163,137,255,132, 2, 59,114,228, 8,243, 33,231, 15, 27, 54,172,194, 5, + 68, 29, 28, 28,130,228,114,121,227,202,206, 43, 40, 40, 72, 73, 73, 73,241,253,135,223,143, 93, 0,108, 2,224, 94,238,247,104, + 0,179, 0, 4,127,232, 31,248, 0, 2, 91, 96,178, 8,248, 6, 0,180,192,234, 84, 96,123,200,223,200,199,208,218,218,250,154, + 64, 32,112, 46, 40, 40, 40,200,203,203,107,100,106,106, 26,171, 80, 40, 20, 44,203, 62, 77, 75, 75,235,162,239, 92, 82, 52, 41, +165, 74, 52, 7, 76, 99,128,225, 28, 77,207, 16, 2, 91,212, 60,191,173,184, 5, 55,100,129,219,169,120,187, 60,215,124, 0, 91, +171,121,220, 8, 35,254, 10,124,208,172,195,166, 69,237, 3,124, 0,116,105,211,166,141,109, 65, 65, 1,162,163,163, 83, 1, 92, + 3, 16, 82,188,197,124,140,156,210, 52,253,227,186,117,235,230,206,152, 49,163,116, 49,232,240,240,112,120,122,190, 31, 35,148, +161,225,120,245,244,101,155,187, 17, 49,104,211, 99,104, 49,209,162,129,130, 20,248,246,108, 91,211, 44,152, 90, 88, 88, 44,167, + 40,106, 24, 77,211, 85, 54, 26, 60,207,115,132,144, 35, 89, 89, 89, 75, 1,228, 85,231,143, 20,114,137,142,229,184, 10,255, 67, +192, 48, 92, 65,161,186,210,176, 23,181,107,215,190, 73,211,116,195,178, 11,102, 3,239, 46,160, 93,217, 49,150,101, 95,165,167, +167, 27, 66, 66,165,180, 64, 52,139,162, 68, 61, 65,243, 77, 1, 10, 20,232, 24,158,211, 92,226, 89,237, 6, 0,170, 15, 33, 89, +246,117, 27, 93,255,122,113,160, 99,228,227,104, 44,154, 62, 10, 63,108,218,131,133,179, 38, 96,195,142, 3,152, 53,105, 36,220, +220,220,245,182,186, 60, 68,171, 22,207, 28,214, 35, 96,203,225, 78, 11,167, 13,147, 4,108, 57,210,121,209,244,225,226, 85,155, + 15,119, 94, 52,253,115, 73,192,230,195,157, 22,206, 28, 38, 91,181,245, 40, 15, 96, 76, 77, 50, 57,210,217,161,128, 98,217, 10, +223,140,137, 64,160, 62,240, 52, 89,241,159,120,162,253,252,252, 60,148, 74,229,253, 81, 61, 91, 5,182,108, 90, 39,169,162, 52, + 25,175,147,234,196, 62, 9,243, 23,138,100, 94,159,249,239, 9,215, 43, 15, 72, 36, 13,163,163,163,157,121,158, 7,199,113, 96, + 89,182,244, 83,163,209,160, 75,151, 46, 31,107,226,204, 0, 0,203,139, 30, 86, 4, 0, 56,252, 1,182, 76, 4, 2,193,215, 98, +177,216,135,101, 89, 87, 0, 16, 10,133,143,213,106,117, 8,203,178,235, 0,228, 87,211,222,250,164,164, 36, 55, 19, 19, 19,104, +181,218,210, 5,232, 25,134,113,169, 87,175,222, 22,149, 74,229,252,161, 23,111, 11, 76,238,208,169,211,134,113,115,231, 50,202, +107,215,176, 97,247,238,245,200,205, 5,128, 45, 85,157, 43, 22,139, 47,208, 52,237, 84,157,255,227,121, 62, 94,163,209,244,170, +206, 57, 2,129,192, 57, 57, 57,217,198,193,193, 1,121,121,121, 80, 40, 20,138,146,253, 15, 65, 8, 64,245, 6,186,176, 12, 51, +219,210,202,170,243,253,139, 23, 21,205,155, 55,167, 25,134, 89, 8,195,131, 84, 75, 0,172, 33,132,200,138,251,139, 13,237,219, +183,247,166, 40,138, 5, 64,120,158,167,239,220,185, 51,146,231,121, 65,113,155,183, 6,192,110, 0,106, 35, 15, 48,226,255, 65, +205,218, 81, 93,162,117, 22,128, 79,155, 54,109,100, 35, 70,140,128,143,143, 15,156,157,157, 33,149, 74,139, 26,241,140, 12,219, + 7, 15, 30,124,126,237,218,181,207, 79,159, 62,141, 71,143, 30, 41, 1,252, 9,160,194,135,186,123,255, 78, 51,164, 38,146,141, + 0,144,246, 42, 35,229,213,139, 55, 27, 83, 82, 82,214, 0, 40, 27, 34,188,209,152, 49, 99,230,204,156, 57, 19, 65, 65, 65, 56, +112,224, 0,212,106, 53,242,242,244,240,151,194, 55,200,186, 18, 8, 40,226,128,132, 16, 64,110, 3, 40,108,107, 92, 82, 22, 22, + 22,203,103,205,154, 53,219,205,205,173, 52,138,185, 78,167, 3,203,178,208,233,116,200,202,202,194,156, 57,115,138, 58, 90, 66, +192,243, 60,206,157, 59, 55, 99,210,164, 73,200,202,202,250,186, 34,155,237,189,234,222,163, 41,218,177, 68,171, 33, 28,247,234, +246,131, 87,173, 89,142, 99, 84, 42,109,133, 43,149, 75,165, 34,189, 36, 79, 40, 20, 58, 62,250,253,119, 27, 90, 44, 6,225, 56, +128,231, 65,120,190,184, 56,139, 55, 82,244, 27,225,120, 16, 29, 7,158,229,193, 42,213,104, 59,117,170, 33, 69,209, 65, 40,150, + 29, 24,253,229, 92,187,118,237,219, 11,235,215,117, 0,203,241,120, 30,247,202,238,254,189,219, 29,143,236,221, 50, 69,163,204, + 27, 9,160, 70,113,182,196,114,179,139,155,127,254,197,241,238,131, 72, 4, 95,189,134,203, 87, 66, 0, 0, 23,174,222, 44, 33, +220, 85, 86, 21,216,252, 22,179, 38, 14,148, 4,110, 62, 40,156, 53,113, 16,243,195,230, 67,194,153, 19, 62, 99, 2, 55, 30, 16, +205,156,240, 25, 19,184,233,128,104,230,196,129, 76,192,134, 93, 30, 0, 44, 0,100, 85,102,172,178, 58,162, 88, 86,242,239,216, + 84, 6, 0,210,182,109,131,238,205, 27, 56, 44, 93, 10, 0, 24,221,200,214,224,161, 9, 43, 43,171,123, 66,161,208,177,170,116, + 58,157,174, 74, 18,236,231,231,231,169, 84, 42,239,177, 44, 75, 4, 2,129,255,168, 65,159,156,236,221,217, 51,163,108,154,240, +240,135,150,171, 86,253, 62,240,240,253, 60,242,185,151,233,253,160, 31,253, 90,247,159,183,231,161,158, 14,153, 86,171,213,120, +250,244, 41,202, 46,242, 94, 6, 92, 13, 31, 41, 26,192, 6, 75, 75,203,118, 25, 25, 25,163, 1, 44,202,205,205,245, 96, 24, 6, +181,107,215, 94,164,209,104,158,155,155,155,239,204,201,201,185, 89,172, 26, 25,186,100, 64, 23, 51, 51,179,125, 39, 78,156,176, +104,213,170, 21,157,158,158,142, 6, 13, 26, 32, 51, 51,179,237,181,107,215,188, 38, 78,156, 56, 49, 47, 47,111,108,241,203,160, +161,104, 38,151,203,201,184,113,227, 40,142,123,123,185,187,118,237, 66,175,230,108, 99,235, 90,242, 66,149,134,228, 4, 63, 53, +255, 74, 36, 18,253, 25, 31, 31,159, 83,221,194, 16, 1,223,140,155, 59,151, 49,121,249, 18, 38, 15, 31, 98,116,110,174,224,135, + 34,117,171, 74,162, 69,211,180,211,190, 3,191, 58,139,197, 98,176, 44, 91, 74, 6, 75,218, 40,157, 78, 7,173, 86, 11,157, 78, + 7,142,227,160,211,234, 16,240,253,234, 26,183,133,114,185, 92,110,111,111,159, 42,151,203,229, 31, 72, 46,235,101,210,244,151, + 45,189,188, 38, 45, 29, 56, 80, 26, 26, 26, 42,165,105, 26, 44,203, 98,205,154, 53, 44, 33,164,150, 27, 96,246, 8,200,173,174, +109,137, 68, 34,216,187,119,239, 72,177, 88, 12, 0,208,104, 52,104,222,188, 57,101,236,243,141,248, 15,146,173,247, 84, 46,125, + 68,171, 79,110,110, 46, 56,142,131,169,169, 41, 24,230,221,126,223,210,210, 18, 61,123,246, 68,151, 46, 93, 48, 98,196, 8, 60, +122,244, 72, 54, 98,196,136,158,149, 25, 27, 53,183, 63,234, 58,219, 22,119, 38,188,253,141, 51, 15, 2,119,125,119,212,250,245, +235,215,115,203, 36,155, 56,121,242,100, 42, 35, 35, 3,195,134, 13,187,166, 86,171, 63,133,158,135,143,227,241,202,119,196,104, +240,132,146,173,187,243, 11,165, 81, 41, 9, 77,211,202,146,161,195,154,148, 18, 69, 81,195, 28, 28, 28,112,240,224, 65,104, 52, +239,135, 11, 51, 51, 51, 67, 84, 84,212, 91, 85,141, 97,208,190,125,123,134,162,168, 97, 0,190,174,216, 38,237,120,227,238, 75, +155,146,253,254, 61,221, 69,237,189,232,212,228,212, 2, 2,128, 90,188,120,113, 41,113, 3,128,229,203,151, 27,146, 79,208, 66, + 33,210, 66, 66,222, 54,196, 2, 26,180,136, 2, 37, 4,104, 65,209, 40, 42, 8, 64, 56,128,103, 1, 94, 7, 72,237,235, 26, 82, + 12,109,235,212,115, 14, 90,181,118,107, 45,181,142,224,224,169, 96,196,197,189, 0, 67,211,104,212,216, 25,159,116,237, 44,244, +106,227, 93,119,245,178,185,167,147, 19,158,245, 1, 16, 90,237,130,230,137,180,113, 61, 43,236,220,117, 31,214, 22, 38, 24, 54, +176, 47,100, 82, 9,126,216,244, 43,190, 95, 56, 29,206,141,156,176,125,253,202, 74, 79, 55, 55, 55, 95,225,234,220,216,105,235, +222, 51,112,117,113, 97,182,238, 59, 3, 87,183,226, 79,119, 87,102,235,190, 51,112,115,119, 99,182,238, 59, 3, 15,247,102,245, +239,165,220, 89,145,153,153, 57,189,242,242, 44, 87, 71,159, 20,213,145, 48,159, 47,109,180, 95, 78,153, 2, 0,165, 68,171, 58, + 16, 10,133,142,201,201,201, 54, 85,165,171, 74, 53, 40, 86,178,238,177, 44,139, 55,111,222, 80,217,217,217,164, 86,173, 90, 3, +207,111, 95,116,162, 87, 39,207, 76, 0,120,248,240, 97,237,128,128, 85, 3, 15,221,203,133,242,246,102,234,223,191,135,240,163, + 63,245,185,119, 42,208,207, 11,197, 75, 66,148,135, 90,173,142,107,217,178, 37, 41,254, 94, 71, 34,145,136,202,221,111, 14, 77, +154, 52,121, 79,181, 54, 96, 72,113,195,173, 91,183,166,187,185,185,193,197,197,229,102,187,118,237,204, 20, 10, 5,206,159, 63, + 15, 87, 87, 87,119, 51, 51,179, 59, 71,142, 28, 17, 46, 88,176,192,115,247,238,221, 0, 48,195,128,226,236,225,235,235,123, 48, + 40, 40, 72, 42, 18,137,160, 84, 42, 17, 21, 21, 5,115,115,115,136,197, 98,124,246,217,103, 76,199,142, 29, 45,187,118,237,122, + 44, 38, 38,102, 36,170, 49, 3, 74,165, 82,145, 69,139, 22, 65, 46,151, 67, 46,151, 67,161, 80, 64,161, 80,192, 68, 10,106,219, +172,122,178,153, 59,178,101, 95, 47,221, 22,184,111,235,178,171,117,235,242,223, 38, 38, 38,102, 87,247, 94, 80, 94,187, 6,147, +135, 15,129, 50,207,174,161, 48, 87,212,134,191,191,127, 85,138, 20, 68, 34, 17, 58,116,232, 80,165,189,218,181,107, 31, 23, 8, + 4,239,188,153,178, 44, 43,245,247,247,231, 98, 98, 98, 20, 52, 77, 43,120,158,135,191,191, 63,199,178,172,212,198,198,230, 38, +207,243,169,233,233,233,131,245,217,237, 10, 72,111, 2,131, 40,161,240,107,123, 7,135, 6, 62,141, 26,201, 47, 95,190,204, 0, +128,147,147, 19, 73, 73, 73,201, 62,117,234, 84,158, 0,248,217,137,144,189,213, 32, 89,106, 0,243,105,154,222, 32,145, 72, 4, +245,235,215,143, 95,178,100,201,173, 98,133, 20,132, 16,186,126,253,250,109,101, 50,153,147, 90,173,102, 81, 52,116,104, 84,179, +254, 1, 32,132,120, 21,241,246, 82,104, 0,136, 75, 4,252,162,222, 14, 86,229,126, 7,128,244,226, 23, 69,219, 74,246, 51, 0, + 60, 2,208, 12,128, 77,241,177,187, 20, 69,101,214, 32,155,149, 43, 90, 65, 65, 65,165,175,176,253,251,247, 47,237, 88, 76, 77, + 77,113,247,238, 93, 80, 20, 5, 83, 83, 83,152,153,153,193,220,220, 28,185,185,185,120,244,232, 17,162,163,163,241,242,229, 75, + 80, 20,133, 70,141, 26,161,228,102, 47,131,210, 6,238,183,159,130, 32, 53,145,128,162,128, 86,221, 60,224,209,165, 57,218,132, +198,206,186,119,153,218,145,146,146,242, 20,128,160,121,243,230, 19,219,183,111,143,181,107,215, 66,173, 86,175,173,132,100,149, +218,188,254,136,109, 13, 0,246,246,246,243,246,159,127, 46, 31,211,187,113, 97, 74, 74,202,143, 53, 40,156,119, 26,226,244,244, +116,131,215,226,227,121, 30, 89, 89, 89,122,109,150, 87, 8,214,109,216, 92, 43, 47, 39, 21,223,253,176, 31, 58,157, 14,115,231, +206, 5,207,243,165, 91,118,118,182, 65,249, 36, 28,247,190,118, 64, 23,141,158, 82, 2,160,222,240, 34, 94,145,112,112, 51, 40, + 2, 80, 28,128,247,175,171,124, 39, 36,101, 68,178, 67,203,126,216, 88, 43, 44,250, 21, 78, 5,135, 65,155,155,132,148,135, 39, +138, 36,199, 14, 35,113, 88,205,160,157, 71, 99,204, 94,188,218,226, 95,179,199, 30,210, 40,243, 92,240,238, 48,226,229,170, 31, + 26, 14,223,173, 88,129, 29, 27,215, 98,245,218,141,200,205,201,134, 80,104, 85,220,208,115,224, 56, 78,255,181, 19,210,219,127, +214,120,234,135,159,143,163,173,155, 61,142,157, 15, 69,167,150, 78, 56,113,241, 30,186,120, 53,192,169,203, 97,232,214,174, 49, +206,134, 68, 98,246,228,145,212,200, 11,187,123, 87,167,142,214,175,223, 92, 43, 47, 55, 21, 65, 43,247,226,205,150, 45,136,159, + 62, 29,109,139,211,132, 82, 20, 68,142,142,128,168,234, 58, 42,143,199,143, 31, 67,173, 86, 87,244,102, 14, 87, 87,215, 42,235, + 93,169, 84,222,103, 89,150,164,166,166, 82,169,169,169, 80, 40, 20, 84, 84, 84, 36,231,238,222,124, 16,137, 62,250, 11, 0, 4, + 4,172, 26,116,248,126, 46, 10,111,110,132,242,214, 38,136, 26,132,211, 59,150, 79,214, 78, 90,186,253,126,153,103,244,157,124, +190,126,253,186,207,235,215,175, 1, 0, 13, 27, 54,140,142,137,137,105, 86, 50,212, 92, 60,132, 40, 98, 89,214,185,100, 56,145, +101, 89,168,213,106,244,232,209,131,209,119,237, 22, 22, 22,237, 93, 93, 93, 17, 22, 22,134,141, 27, 55,214,246,245,245,197,179, +103,207, 64, 81, 20, 86,173, 90, 69,185,185,185, 9,211,211,211,209,171, 87, 47, 28, 63,126,188, 67,110,110,110, 85,229,105,170, + 80, 40,118,159, 62,125, 90, 74,211, 52,242,242,242,192,243, 60, 58,118,236, 8,154,166, 17, 25, 25,137,197,139, 23,227,248,241, +227, 56,121,242,164,204,203,203,107,119, 97, 97,161, 43,222, 29,214,175,172,142,136, 74,165, 34, 18,137, 4, 18,137, 4, 82,169, + 20, 82,169, 20, 98,177, 24,249, 42, 96,210,186,120, 53, 35,181,226,221, 91,118,106, 60,126,230, 42,250,199, 37, 19,174, 0, 56, +101,232, 61, 15, 20,249,100,109,248,245,215,141,163,115,114,104, 0,216, 73, 81,188,150,144,213,134, 60,239, 0,144,175,202,129, + 83, 35, 71, 28, 59,116, 18, 67,134, 15,172,144,100, 9,133, 34,136,132, 66,152,213, 86, 84,105, 83, 36, 18,217, 70, 71, 71, 91, + 10,133, 66, 16, 66,192,113, 28,180, 90,109,234,191,254,245, 47,235,126,253,250,153,158, 59,119,142,238,215,175, 31,111, 97, 97, + 81, 16, 26, 26,250,134,101, 89,203,206,157, 59, 87,106, 83, 14,120,168,204,155,108, 16, 51,172, 71,224,162,105,146,177, 99,199, + 50,227,199,143, 71, 66, 66, 2, 38, 78,156,168,186,116,233,146,230,117, 74,202, 41, 49,207,111,214, 2,225,134,182,201,229,176, +213,195,195,163,213,137, 19, 39, 38,248,251,251,223,155, 55,111,222,119,101, 15,174, 89,179,102,197,217,179,103,157, 6, 13, 26, +180,239,225,195,135, 91,171,211, 46,125,104,223, 97,180,249, 97,168,140,139,148,136,163, 20, 69, 5,149,105,179,251,151,236,251, +251,251, 47, 10, 8, 8,136,162, 40, 42,168,236,239, 37,233,138, 95, 22,131, 42,218, 47, 62,183,246,194,133, 11,155, 7, 6, 6, +174,242,246,246, 62,120,243,230,205, 23, 0,170, 75,180,244,251,104,149, 92, 80,217,139, 44,215,169, 33, 55, 55, 23,185,185,185, + 72, 76, 76,196,182,109,219,138, 31,104, 33, 4, 2, 1, 4, 2, 65,169, 63, 67,101, 8, 14,250,115, 19,128, 77,173, 90,181, 18, + 70,220, 58,114,238,155, 29, 51,187,183,238,209,138,185, 31, 28, 49, 20, 69,235, 17,246, 25, 55,110,156, 21, 0,236,221,187, 55, + 29,192,185,255, 16,107, 62,242,244,233,211,217,246,246,246,165, 62, 42,101,135, 15, 89,150,133, 84, 42, 69,137, 47,139, 74,165, +194,182,109,219, 88, 66,200, 17, 61, 54, 17, 19,117, 5, 79,163,174, 22,157,199,243,224,185,183,231, 47, 91,182, 12,132,144,210, +206,126, 74,177,114, 82, 37,201,171,168,204, 73,185,207,114,191, 19,142,171, 98,120, 66, 52,115,232,216,233,246, 60, 37,192,239, + 87, 30, 64, 40, 20,130, 47,163,102, 10,153,162,183,229,168,103,201,112,176,117,199,167, 35, 39,219,157,216,183,121, 38,171, 85, +253, 80,221,178,118,241,240,198,172,217,179,241,203,142, 29, 88,188,116, 69, 41, 3, 96, 57, 14,108,149,249,164,233, 30, 29,155, +131,205, 79, 6,195, 48,232,214,182, 49, 24,134, 65, 79,239,166, 96, 24, 6,189, 58,186, 64, 32, 16,160,119, 39, 55, 52,105,210, + 4, 2,129,128,174,162,222, 17, 19, 21,140,167, 81,127,148, 33,189, 4, 4,128, 54, 37,229,189,244,186,148, 20,144,122,150,213, +189,183, 48,113,226,196,236,196,196, 68,109,249, 99,117,235,214, 21, 93,187,118,173, 86, 37,195,118,165,144,201,100, 94, 2,129, +224,126,102,102, 38, 47,151,203,105,158,231,120,119,247,230,204,249,237,139, 78,148,164, 89,184,112,209,137,207,189,204, 6,237, + 63, 18, 68, 68,245, 59, 81,148, 80,194,126,185,116,187, 72, 40,146,121, 1, 74, 67, 94, 30,104,181, 90,141, 39, 79,158,160,170, +252, 16, 66,244, 14,211,100,101,101,141,115,117,117,189,182,105,211,166,218, 20, 69,225,250,245,235, 96, 24,166,116,139,141,141, + 5, 77,211,248,230,155,111,180,185,185,185, 95, 84,149, 55,129, 64, 48,251,216,177, 99,230, 98,177, 24,121,121,121,165,207, 13, +195, 48,136,142,142,198,143, 63,254,136,113,227,198, 33, 33, 33, 1, 14, 14, 14,152, 59,119,174, 73, 96, 96,224,108,173, 86,187, +194,128, 42, 10,215,104, 52,173,229,114, 57,164, 82, 41, 74, 8, 23, 0, 92,140, 18, 70, 42,149,202, 22,150,150,133,118,214, 33, + 65,191,119,240,253,212,211,210,218,222, 59, 37, 37,165, 90, 75,103, 61, 7,118,196,113,220,191,250,156, 56, 97,115,227,196, 9, +254,246,233,211,175, 36,121,121,219, 13,190,135,116, 52,226, 99, 95,193,203,203, 11,247,239,223,135,151,151, 87, 89,210, 4,177, + 88, 12,145, 72, 4,145, 72, 4, 43, 11,131, 92, 40, 8, 77,211,184,113,227, 6, 56,142,131, 70,163,129, 70,163,129,155,155, 91, +230,213,171, 87, 77, 0, 32, 54, 54,150,140, 25, 51, 38,251,206,157, 59,104,217, 82,255,122,234, 42,138, 10, 94,182,234, 39,243, + 31,214,239,134,121,109, 91,132,132,132,112,231,207,159,207,163,128,152,167, 81, 81,107, 63, 5,206, 30, 1,180,213, 41, 51, 91, + 91,219,107, 12,195,212, 47,251, 91, 70, 70,134,197,224,193,131,145,149,149,213,119,240,224,193,157,138,219,132,164,163, 71,143, +142, 1, 0,177, 88, 12,154,166, 57, 24,241, 95,133,170,184, 72, 89,162, 84,158,112, 5, 4, 4,244, 47,255, 91, 89, 82, 85,209, +247,178,231, 6, 6, 6,174, 42, 99, 91, 89,131,236, 87,237,163, 21, 20, 20, 68, 42, 96,144, 6,163, 42,162, 85,130,176,176, 48, +157,131,131,195, 47, 79, 31,188,236,222,216,163, 17,100, 10,201, 39, 0, 54, 73, 36,146, 57, 99,199,142,197,237,219,183, 17, 25, + 25,185, 11, 31, 56, 11,167,121,243,230, 23, 36, 18,137, 83, 37,195, 36,241,145,145,145,189, 42,233, 24,150,158, 62,125, 26,250, +156,225,175, 92,185, 82,182, 83, 42,235, 12, 95,241,141,193, 19,232,180, 58, 20, 20, 42,223,118,226,197, 68,171,160,160, 0,195, +135, 15,127, 71,209,122,243,230, 77,149,215, 71, 81, 20,126, 60,117, 10,151,142, 28, 65, 95, 79, 79, 28, 15, 13, 69,224,216, 81, +112,113,170, 3,194, 81, 32, 20,144,112, 96, 51, 50,114,243,241, 91,240, 13,100,230, 21, 98,116,231,206,112, 54,179,210,111, 87, + 40,234,217,182,189,183,232,242,205, 71, 16, 10, 5,160,193,131,232, 10,225,224,218, 21, 12, 77,195,220,182, 1, 68, 66, 33,132, + 66, 1, 98, 19,211,225,218,188,141, 56, 72, 44,237, 89, 19,162, 85,215,169, 1, 56,142,195,184,113,227,112,240,224, 65, 88,218, + 57,193,188,110,115,124,191,118, 7,250,246,232, 92,229,245,151,188,193, 11, 4, 2, 48, 12,243,222,103,201,119, 67,212, 73,194, + 19,104,203,215, 17, 79, 0, 66,224,184,114, 37, 28, 87,174, 68,104,241,127,186, 21, 20, 64,169, 84, 2,237,220,171, 69,178, 52, + 26, 13, 18, 19, 19,181,175, 95,191,182,173,224,120,170, 70,163,169,146,216,236,217,179, 39,220,207,207,175,117,237,218,181,239, +133, 63,124,168,243,240,244, 20,158,219,182,232,100,201,176, 33, 0,120,122,122,102, 46, 90,180,232,228,152, 97,253, 7,110,245, + 31,193, 77, 93,177, 79, 32,145,201, 90,247,159,183, 39,252,192,176, 97, 85,143,205,168,213,113, 30, 30, 30,196,144,235, 42, 44, + 44,124,173,231,240, 0, 0,203, 91,181,106,101,230,235,235,139,107,215,174, 97,200,144, 33,106,173, 86,251, 20, 0,250,245,235, +215,244,183,223,126, 19, 63,122,244, 8,214,214,214,194,248,248,248,221,168,194, 65, 94, 44, 22,119,109,211,166, 13,173, 86,171, +223, 35, 89,129,129,129, 24, 57,114, 36,154, 54,109, 10,158,231,145,159,159, 15, 95, 95, 95,225,198,141, 27,187, 26, 72,180,102, +185,184,184,252,136,162, 89,135,101,219,194,199,197, 67, 80,200,200,200,120,253,224, 78,112, 84,231, 30,131, 91,215,111,210,220, + 62, 50,252,190, 94,131, 54, 54, 54, 11,105,154,254,156,231,121, 38, 55, 55, 55,241,129, 70,211,196,205,201,201,182,227,192,129, +200, 17, 10,153, 13,193,193,116,106, 94,158, 9, 0,131,134, 32, 85,186, 2, 56, 53, 42,114,245, 27, 50,124, 32,238,223,191,143, +161, 35, 6, 65, 36, 18, 65, 32, 16, 22, 61,155,162, 34, 69,171,150,149,153, 65,247,166, 78,167, 43,109,195, 75,252,188,180, 90, + 45, 74, 92,179,228,114,121,233, 49,181, 90, 13,138,162,244,221, 27,180,111,151,142,184, 25, 22,195,126,241,205, 6,181, 48,227, +126,160, 29,207,239,121, 5,164,126, 64,115,238,124,120,197, 18, 27,153,153, 57, 56,157, 14,238, 3,135,150, 62, 39,119,118,110, +149,129,231,101,217,241,113,152,113,228,244,199, 94, 51,215,136,255, 0,170,226, 34,101,137,210,135,130,162,168, 32,127,127,255, + 69, 0,136,191,191,255,162,146,253,128,128, 0, 37,128,164, 26,146,173,247, 84, 46,193,199, 32, 89, 37,195, 11,250,224,235,235, + 59,195,212,212,116, 99,201,126,226,237, 36, 36,222, 78,130,107, 51,247,142,173, 60, 91,231,140, 28, 57, 18,150,150,150,152, 55, +111, 30, 1,176,171,186,255, 31, 27, 19,101, 2,128,216,219,219,207, 43,110,144, 61, 67, 67, 67,173,239,222,189,139, 54,109,218, +188,149,238,181, 90,116,234,212, 73,159,169,188, 98,167,246,175, 63,158, 74,198, 67,171,213,162,176, 80, 9,141, 70, 11, 86,199, +131,101, 89,120,185,155, 98,223, 14,255,162,223,216, 18,245,172, 72, 53,115,180, 51,133,169,137, 80, 71,211,148,242, 94,248,235, + 10, 91, 76,141, 70,131,240,248,120, 60,124,249, 18, 0,240,105,128,126,199,215,125,193,215,224,230,230, 86, 85,110, 27, 59, 58, +216, 33,249, 82,120, 81,227,173, 76,196,221, 63, 15,195,212,212, 4, 0,224,238, 51, 26, 34, 81, 17,209, 42, 80,106, 97,213,172, + 46, 40, 66, 42, 13, 11, 32,183,176,187, 32, 16, 73,157, 8,199,131, 16, 30,132,231, 64, 8, 15, 70, 40,146,207,152, 50, 1, 60, +207,161,109,219,182,160, 24, 6,156, 78,141, 97, 3,122, 34, 43, 39, 15,150,181, 12,235, 36, 68, 34, 17,124,124,124,100,149, 29, +127,246,236,153,178, 44, 49,211, 95, 71, 58, 20, 20, 40,161, 86,171,161,213,176,208,234, 88,112, 13, 69,248,238, 95,163,192,106, + 89, 20,142,240,134, 86,199,130,159, 61, 8, 90,141, 14, 9,114,154,246,112,181,210,209,160,148, 15, 30,167,153, 85, 69,180, 74, +200, 65,101,168,200, 39,176, 18,178,245,208,207,207,207,203,195,211,243,254,231, 61, 60,127,138,136,140, 74,142,136,140,122, 47, +157, 83, 83,207,184,169,129, 7,231, 10, 69, 50,175,254,243,244,207, 58, 44,139,178,195,136, 31,136, 69,121,121,121, 30, 38, 38, + 38,136,137,137, 1,195, 48,160, 40,234, 25, 0, 15, 0,176,183,183,127, 46, 16, 8, 26, 49, 12,131, 45, 91,182, 80, 2,129,160, +133,183,183,247, 34,149, 74,117, 88,207, 11,157,171,169,169,233, 59,106,150, 72, 36,130,191,191, 63,198,140, 25, 83, 74,178, 68, + 34, 17,246,236,217,131,214,173, 91, 67,163,209,184, 26,152,223,187, 0, 58, 27,160,248, 81,197,228,188, 74, 50,202,178,172, 95, +198,231,159, 55, 65, 72, 8, 58, 54,106,228,230,229,229, 5,173,246,173,160,211,168, 81,163,186,121,121,121,175,149, 74,229,191, + 81, 20,134,224,129, 94, 82,164,226, 17, 31, 91,228,126,122,255,254,125,180,109,219,182, 84,193, 42,171,102,137, 68, 34,200,196, + 38,213, 34, 90, 60, 95,212, 46,229,229,229,209, 33, 33, 33, 86, 46, 46, 46, 20, 0,184,184,184, 80, 15, 30, 60,168, 45,151,203, +211, 27, 55,110, 92,213, 11,176, 8, 0,186,126, 50, 88,112,233,252, 89, 5, 11,172,120,205, 48, 43, 4, 85,182,145, 68,199,241, +124,165, 78,247, 50, 51,115,236,241, 27, 14, 0,248,182, 71,239,210,151,173,243,203, 23, 65, 40, 20,162,251,188, 69,239, 61, 75, + 60,207, 51, 48,226, 31, 69,178, 42, 82,180, 62,172,111,126,171,104, 5, 4, 4, 68, 5, 4, 4,188,167,142, 85, 19, 85, 43, 90, +101,165,187,234,162,228, 97,173, 12,107,215,174, 69,139, 22, 45,244,118, 68, 27, 55,110,196,254,253,251,215, 2,136,173,182,228, +216,189,149, 59,214,157,136,106,212,212,157, 2,128, 21,179, 7,208, 5, 5, 5,184,113,227, 6,204,205,205,241,236,153,193, 97, +191, 76,205,205,205,151,211, 52, 61,140, 41, 63, 3,160, 98,130,201,241, 60,127, 36, 39, 39,167,210,240, 14,132, 0, 90, 29,139, +130, 66, 21, 52, 26, 13,102,127,179,185,202, 76, 4, 0,148, 86,147, 39,240,233,226, 45,171, 76,209,105,219,162, 43,166,141, 53, +121,175,243,102,104,128,166,129,150,109,139, 20,151, 7,161, 81,224,121,128,227, 1, 43, 27, 11,236, 58,240,147, 94,146,207,114, +124,241,219, 49,135,124, 53, 7,215,246,253,241,234,113, 72,169,130, 36, 22, 21, 13, 25,139,132, 66,240,132, 42,138,250, 80, 89, +171, 43,150, 57,101,165,196, 58,239, 8,138,192,164,254, 45,112,244,114, 56,134,246,240,192,213, 59,143,224,219,206, 13, 81, 79, + 95,194,221,185, 62,182,236, 62, 2, 66,144,247,243,186,239, 95,191,237,208,216,120, 67, 20,173,219,183,111, 43,203,171, 88,101, + 63, 73,213,253, 33, 8,121,171,104, 41, 85,106,204, 91,104, 80,232,157,162, 58,234,220, 94,102, 72, 98,125,138,149, 33, 68,172, +188,178,133, 42,194,179, 52, 4,208, 26, 88,240,159,108, 56, 57,142,195,153, 51,103, 74,235,163,162,122, 44, 91,119, 6,144, 28, +196,199,199, 35, 42, 42, 10,237,219,183, 71, 78, 78, 14,132, 52,141,185, 17, 17,112, 27, 59, 22, 26,145, 8, 60,207, 67, 44, 22, + 99,242,228,201, 6,151,103, 53, 91,231, 98,199,107,174, 42,227, 63,121,123,123, 55,137, 41, 40, 64, 84,116, 52,122, 44, 91, 6, + 0, 56,123,246,236, 59,247,196,156, 57,115,196,143, 30, 61,154,120,239,222,189,137,201,201,201,107, 1,204,173,180,157, 37,234, + 82, 31,173,207, 71, 13, 65, 19,151,134,216,255,235,129,210,227,115,230,207,130, 80, 40,130, 80, 36, 68, 45,243, 90, 6, 93,141, + 78,167, 43, 37,173,133,133,133,244,217,179,103, 29,123,246,236, 41,154, 53,107, 22, 5, 0,251,247,239,167, 55,109,218,164,184, +116,233,146,168, 78,157, 58, 41, 85, 40, 4,185, 73, 25,106, 9, 0,212,171, 87, 15,155,183,255, 78,247,235,215, 15,179,102,205, +130, 78,167,195,214,173, 69,207,213,200,145, 35,161,213,106,113,236,216,177,146,231, 88,175, 26,197,106,181,239,221, 55, 20, 69, + 65, 40, 20, 66, 36, 22, 1, 60, 15,138,162, 20,107,214,172, 89, 17, 21, 21,213,198,197,197, 5,106,181,122, 44,138, 38,127, 24, +227,104,253,151,145, 45,125, 92,164, 34, 95,171, 98, 85,170, 50,164,149,245,219,170,140,168,149,245,217, 66,205, 38, 80, 24,230, +163, 85, 17, 24,134,169, 82,173, 42,153,170,171, 15,115,230,204,129,169,169,105,101, 29, 16,137,136,136,120,148,146,146,178, 3, +192,230, 26, 85, 78,112, 88,212,242,175, 7,229,161,120,108,181, 86,173, 90,233,221,186,117,203, 7,160, 61,124,248,221, 23,100, +181, 90, 93,105, 7,110,110,110,190,124,231,206,157, 51, 7, 14, 28, 72,151, 15, 49, 80,118,120,175,100,211,233,116, 56,124,248, +240,204, 5, 11, 22, 32, 39, 39,231,107,125,157,120, 97,129, 18,202, 98, 71,232,231,145, 71, 13,109,212, 43, 61,100, 82,203, 30, +142, 13, 61, 42,237, 76,104, 81,145, 15,145,109,189,183, 29,152,169,169, 20,156, 30,155, 20, 69,199,190, 76, 72,174, 83,215,174, + 54,158, 39,166,193,182,126, 11,100, 37,189, 45, 7,129,128,129,176,120,232,176,150,153, 2,105,111,222,128,166, 25,189,196,248, +251,223,194,112, 39,242, 37,142, 93,126, 0,173,170, 0,235,246,158,135, 86,157, 15,173,170, 0, 90, 85,209,231,170, 5, 95,130, +162,240, 90,167, 46,104, 90,157,122, 23, 8, 4,104,215,174, 93,165, 68, 39, 41, 41,201, 64, 69,139,148, 42, 90, 74, 85, 53,235, +200,176, 55, 39,189,138, 85,201,241,154, 18,131,146,144, 15, 50,153,172,245,158, 61,149,135,113,168, 8,118,118,118,231, 76, 76, + 76, 26, 24,154,190, 26,193, 75, 87,213,170, 85,107,185,139,139,139,235,186,117,235,132, 12,195,160,123,247,238, 77,237,236,236, +226, 1,192,221,221,221,161,164,141,153, 58,117, 42,185,125,251,118,100,209, 59, 70,229, 16,139,197,209,230,230,230,173,125,125, +125,145,147,147,131,196,196, 68, 40, 20, 10,184,253,244, 19, 34,166, 78,133,231,182,109,160,187,117, 3, 69, 81, 16,139,197,136, +136,136,128, 76, 38,139, 86,169, 42, 13,249,214, 14,192,106, 0, 29,241,118,184,144, 0,184,129,162,176, 11,119, 42,104,239,104, + 0,224,120,190,170,202, 26, 53,111,222, 60,100, 11,133, 64,191,126, 16,197,198, 66,171,213,162,125,251,246,165, 42,123,251,246, +237, 33, 16, 8,224,225,225, 1, 7, 7, 7,108,217,178,101,148, 62,162,165,202,215, 34, 62,246, 21,188,189,189, 75,149,171,126, +253,250,149, 42, 90, 66,161,176, 84,217,162,184,170,137, 43, 69, 81,164,236, 75, 50,199,113,148, 64, 32, 16,124,253,245,215,212, +144, 33, 67,136, 70,163,225,197, 98, 49,125,236,216, 49,234,234,213,171,130,130,130,130,170,212,134,130, 17, 35, 70,216,212,173, +235,136,196,231, 81, 56,122,148, 96,237,218,181,184,118,173, 40,202, 70, 76, 76,209,196,213,146,125, 95, 95, 95, 52,104,208, 0, +164,138, 27,185,181, 22,192, 0, 0, 32, 0, 73, 68, 65, 84,191,249,160, 97,248,182,103,159,162,246,164,129, 53,132, 34, 33,196, + 34, 17,230, 69,191, 42,173,107,179, 61, 7,197,129,129,129, 67, 93, 92, 92,138,134,246, 1,129, 49,142,214,127, 23,170, 16,122, +210,202,145, 36, 77,153,253, 52, 0, 84,241,126, 90, 25, 66,149, 70, 81,212, 93, 66, 72,155,114,105, 75,142,107,202,125,150, 28, +127, 88,131,236,151,172,117,248, 30,249,210,247, 70,252,244,214,173, 91,206, 94, 94, 94, 72, 72, 72,120,111, 38, 92, 73,199,165, + 80, 40, 32,147,201,112,243,230, 77, 0,120, 90,153,177,171, 87,175,110, 66, 81,212,101, 20, 15, 27,120,251,126,222,245,102,219, +222,109,240, 91,192,129,156,148,148, 20, 15,188,141,161, 67, 57, 56, 56,140, 17,138, 5,195, 27, 53,175,231, 3,158, 95, 29,124, +250,198, 50,125, 87,216,168,169,123, 62, 0,101,201,172,195, 26,206, 62, 4, 77,211,195, 6, 14, 28, 72, 63,122,244, 8,195,135, + 15,199,254,253,251, 43, 77, 59,102,204, 24, 28, 60,120, 16, 3, 7, 14,164, 23, 46, 92, 88,105,120,135,119,213, 18,205, 71,187, + 41, 99,158, 61,196,190,131, 59, 43,245, 65,178,177, 41,242,199,122,243, 38,189,244,183, 54, 94,250, 71, 70,120, 86,115, 41,236, + 94,168,119,135, 46,221, 69,137,169,217,224, 89, 53, 84,121,111,207, 47,204, 78, 5, 97, 85, 16,201,107,195,206,202, 28,247,111, + 93,212,104, 53,170, 75,250,108,206, 28,232,142,169, 3, 92, 1,194, 99,208,220, 93, 8,218, 60,163,244, 13,186,211,144, 89, 8, + 62,188,193, 96, 31,191,242, 16, 10,133,136,136,136, 80, 86,166,102, 49, 12, 99, 72, 76,174, 98,213, 81,135,194, 66, 37, 10,149, +170,143,217,118, 88,219,218,218,254,108, 97, 97, 33,173,132, 72, 89, 91, 91, 91,255,108,105,105, 41, 53,116,232,176, 50,146, 85, + 28, 87,235,158,159,159, 95,181,200,150, 68, 34,105,240,244,233,211,210, 96,165,250, 62, 53, 26, 13,124,125,125, 13, 13, 94,122, + 26,192, 11,123,123,251, 27,110,110,110,230,207,159, 63,199,129, 3, 7, 68, 66,161,176, 94, 73,251,145,151,151, 7,134, 97,240, +230,205, 27, 29,128, 9,168, 98,232, 76,173, 86,135,132,132,132,180, 28, 48, 96, 0, 19, 29, 29, 13,134, 97,138,242,229,237, 13, +207,109,219, 16,249,245,215,240,121,249, 18, 42,173, 22, 82,169, 20, 23, 46, 92,208, 22, 22, 22,134, 84,102, 79, 38,147,237,136, +139,139,115,151, 74,165,208,106,181,224,121, 30, 52, 77, 83, 2,129,160, 83,173, 90,181, 54, 2,104, 83,174,178,108, 60,219,248, + 54,227, 88,150, 75, 73,120,158, 86, 85, 1,100,100,100,224,244,233,211,104,223,190, 61,124,124,124,144,148,148,132,216,216, 88, +244,237,219,183, 52,205,195,135, 15, 17, 22, 22,134,198,141, 27, 87,173,232,209, 58, 52,110,214, 0, 34,145,168, 72,205, 17,138, +138, 95,124,132,165, 74,150, 72, 40,130, 80, 32,132, 84, 38, 53, 88,209,162, 40, 10, 52, 77,131,162, 40,200,100,178,146,151,108, +222,209,209, 49, 37, 51, 51,211, 30, 0, 35,147,201,192,113,156,222,151, 22,158, 16,103, 81,250,205,228,185, 11,126,180, 9, 8, +184,140,203,151,223,128,166,105,216,219,219,131,166,105,196,197,197,129,166,105, 56, 57, 57,129,166,105, 36, 37, 37,149,144,196, + 44, 84, 78,134, 75,159, 27,138,162, 74, 73,150, 72, 44, 42, 85,182, 0, 32, 59, 59, 91, 53,112,224,192,127,171,213,234,241,168, +217,170, 39, 70,252,141, 65, 81,212,221,255,196,185,213, 64,191, 98, 98,245,158, 83,188,190,155,177,111,135, 14, 29,182,141, 28, + 57,178,251,250,245,235, 97, 98, 98,130,148,148,148,210, 14, 81, 44, 22,163,110,221,186,200,204,204,196,246,237,219,241,234,213, +171, 43, 0, 38, 27,154,163,148,148,148,219,207, 30, 60,205,240, 29,218,193,210,189, 67,179, 90,137, 79, 95,181, 79, 73, 73,185, + 89, 76,178,118,141,156,211,119,188,239,224,182, 16,137,133, 72,124,246, 26,193,167,111,252,191, 84, 38,195, 48, 12, 69, 81, 24, + 62,124,184, 65,233, 71,140, 24,129,144,144, 16,232, 27,102,228, 75, 20,173, 66, 21, 10,148, 31,239,197,106,218,140, 49,152, 54, + 99, 76, 41,153, 48,100,232, 5, 0, 28, 28, 14,233, 33, 90,218,245, 65,135,182, 79,106,213,214,219,169,181,123, 3,220,185,247, + 0,191,109,123, 43, 50,236,222,180, 2, 63,236,190,130,186,182, 22,208,170, 11,112,238,232, 47,175,181,234,194,245, 53, 20,229, +138,200, 45, 69,129, 16,190, 90,215, 94, 66,158,132, 66, 33,154, 55,111, 94,169,162,149,153,153,169,172, 74,205, 42,173, 35,141, + 14,249, 5, 74, 40, 11, 63, 26,209,242,236,212,169,211,165, 35, 71,142, 88,218,216,216, 32, 57, 57,185, 60,209,242,236,216,177, +227,165, 35, 71,142, 88,218,218,218, 34, 49, 49,209,224,176, 34, 21,144, 44,164,165,165, 81, 89, 89, 89,188,133,133, 69,181,200, + 22, 77,211, 80,171,213,120,252,248,177,161,127,107,240,108, 46,115,115,243, 61, 7, 15, 30, 52, 79, 79, 79, 7,195, 48,120,252, +248,241, 59,179, 14, 75,182, 93,187,118,137, 6, 13, 26,180, 51, 59, 59, 91,239,180, 54,150,101,215,142, 25, 51,102, 98, 82, 82, +146,133,141,141, 13, 82, 82, 82, 32, 22,139, 65, 8, 1,229,235,139,206, 47, 94, 64,203,113,144,201,100,136,137,137,193,142, 29, + 59, 10,138, 67,197, 84, 40,144, 81, 20,229, 44, 18,137, 48,122,244,232,119, 14,236,221,187, 23,159,182,102, 90, 91,155, 11,242, + 89, 72,213,169,178, 62,231, 24,134,161, 60,219,117,107,218,174, 75,191,230, 79, 34,239, 60, 79, 75,125, 85, 85,163,164,211,104, + 52,112,113,113,193,221,187,119,113,249,242,101,116,235,214, 13, 62, 62, 62, 8, 15, 15,199,197,139, 23, 17, 22, 22, 6,138,162, + 96,105,105, 89,226,126,161,215, 7, 67, 83,200,226, 77,114,198,123,234, 85,249,125,145, 72, 4,181,210,176,201,125,209,209,209, +184,123,247,110,105,104, 25,134, 97,216,177, 99,199,130, 16, 66,226,226,226, 96,106,106, 74,252,252,252, 56,129, 64,192, 38, 37, + 25,230, 31,108, 98, 98, 2,103,103,231,119, 94,124, 74,182,206,157, 59,227,222,189,123,160,105, 26, 2,129, 0, 54, 54, 54,184, +113,227, 70,149, 55,126, 9,169, 42, 33, 89, 2,145,240, 29,210,199,243,124, 94,120,120,248, 36, 0,225,197, 74, 22, 96,140,163, +101,196,255, 31,206,224,253,133,165,171, 84,180, 94, 0,232,113,224,192,129, 81, 39, 79,158, 92,187,113,227, 70,235,254,253,251, + 35, 43, 43, 11, 78, 78, 78,176,183,183, 71, 80, 80, 16,206,158, 61,155,206,113,220, 92, 0, 21, 73, 63, 61,160, 39,102, 77,210, +243,148, 35,234,252,252,169, 94, 62,174,184,114,248,122,128,157,157,221,100,134, 97,102,251, 45,250,108,124,215,129,109, 16, 19, + 22,135,219, 23, 35,144,154,144, 94,165,205,242,206,240,181,106,213,154, 40,151,203,197,168, 96, 42,113, 5,179, 14, 75,109,114, + 28,199,105, 52, 26, 28, 58,116,200, 32,178,117,224,192, 1,168, 84, 42,112,239,143,175,150,218, 36, 60,161, 4, 66, 9, 28,234, +186, 64,171, 45, 0,207,215,120, 66,101,169,205,146, 55,208,231, 98, 49,108,210,211,113,231,206, 29,195, 40,119,191,126, 85,213, +145, 74,163,202, 27,189, 97,229,188,160,233,254,171,107,117,235,208, 18,223,254,180, 23, 90,237,110,208, 12, 13,153, 68, 4,175, +182, 29,193, 64,141,159, 3,231,103, 23,230,102,141,198,251, 75,241,188, 99,147,232, 27, 97, 33, 0,199,243,184,124, 45,212,224, +107, 47, 51,204, 1,129, 64,128,103,207,158, 41, 43,154,109,200, 48, 69,195,156, 37,111,234,250,108, 18,158,167,132, 34, 41,234, + 58,185, 65,163,206,255, 40,117,100, 99, 99, 51,255,196,137, 19,150, 37,161, 18,194,195,195, 65, 81,212,227,183,138, 99,209,113, +165, 82,137,200,200, 72,132,135,135, 3, 69, 51,220, 12,126,142, 74,148,172,180,180, 52, 42, 37, 37, 5,114,185,156, 14, 15, 15, + 87,123,120,120,220,171,226,249, 46,181,169, 82,169, 94, 86,230, 63,169, 82,169,234, 72,165, 82, 97,185, 14,207,161, 73,147, 38, + 49, 21, 12, 33,190,151,207,156,156,156, 59, 11, 22, 44,240,234,221,187, 55,230,207,159,159,105, 97, 97, 97,250,243,207, 63, 11, + 24,134,161,166, 79,159,206,189,121,243, 38,255,151, 95,126, 49, 63,121,242, 36,178,179,179,111, 26,112,237,121, 42,149,106, 82, +135, 14, 29,246,158, 63,127, 94,238,236,236,140,220,220, 92, 16, 66,176,103,207, 30, 76,159, 62, 29, 82,169, 20, 49, 49, 49,248, +244,211, 79, 11, 11, 11, 11, 39,225,125,223,201, 18,155, 20, 69, 81,132,231,121, 44, 89,178,164, 52, 56,105, 73,176, 82, 83, 25, +133, 29,115, 26, 42,102,253,146,163, 24,245,237, 47, 99, 1,128, 99, 89,238, 73,228,157,231,123, 54,127,123, 85, 36, 18, 93,171, +162,142, 22,207,154, 53,235,231,126,253,250,201, 76, 76, 76,144,153,153,137, 27, 55,110,224,214,173, 91,184,125,251, 54, 52, 26, + 13, 44, 45, 45, 97, 97, 97,129,148,148, 20, 68, 71, 71, 43, 1, 44,214,103, 83, 44, 23,162, 81,211,146,153,191, 69, 10,150,176, +204,108,195,178,234,150, 72, 40, 52,232, 57,234,210,165, 11,218,181,107, 87, 66, 86,184,248,248,248, 20,181, 90, 77,149, 33,253, + 73, 37,132,188, 94,189,122,236,254,253,251, 73, 85, 54,121,158,127,143, 76,119,238,220,185,244,165,176, 93,187,118, 96, 24, 6, + 15, 30, 60,168,204, 53,229, 29,155,183,119,108,193,249,239, 22, 67, 44, 18, 97,238,227,196, 82,210,181,183, 91, 43, 8,197, 34, +184, 14, 24, 82,246,220,173, 40, 26, 46, 68, 57,146,165,175, 63,250,224,231,221,104,243,127, 30, 41,168,193, 18, 60, 37,248, 77, +165, 82,157,251,242,203, 47, 3, 61, 61, 61,191, 92,183,110, 29, 37, 18,137,176,108,217, 50,146,156,156,252,107,241, 27, 67, 86, + 77,114, 69, 8,249,245,143,227, 55,167,140,243, 31, 72,205, 89,239,215,233, 94,112,100,116,139, 14,206,104,209,193, 25,247,174, + 60,194,230, 69, 7,246,115, 58,110,201,235,215,175, 19,170, 48,165,238,209,177, 89,121,103,120,203,144,171,193,150,213,157,117, +200,243,252,145, 3, 7, 14,204, 28, 60,120, 48, 29, 26, 26,250,158, 79, 86,201,178, 59, 60,207,227,210,165, 75,208,106,181,248, +245,215, 95,121,158,231, 43,143,163, 5,114,106,195,250,192,113,191,238, 59, 37, 22,139, 40,220,186,118, 12, 57, 89,250,103,117, +137, 68, 66,236,218,115, 92, 43, 18, 9,159, 84,116, 92,171,213, 38, 6, 7, 7,219,246,226, 56, 33, 77,211, 21, 17,168, 10,113, +228,200, 17, 29,207,243,241, 85, 36,187,153,250, 42, 97,192,247,243, 39, 28,232,247,249,151,182, 29, 58,116, 18, 90,217,216,130, +162, 40,188, 73,125,131,152,200, 80,221,185, 99, 59, 83, 11, 10, 13, 91,130,103,194,143,127,148,250,100, 1, 64,255,233, 27, 75, +253,179, 0, 96,128,223, 2,248,182,119, 7,101,136,244,244,150,100,241, 44,203, 66,161, 80,128,101,217, 10, 67, 60,152,155,155, +203, 84, 42,149,178, 56, 16,163,222, 55,102, 2,124,244, 58,226, 56,206, 53, 43, 43, 11, 5, 5, 5,184,117,235, 22, 89,185,114, +101, 90, 90, 90, 90,169,211,166, 78,167,115,205,204,204, 68,126,126, 62,110,222,188, 73, 2, 3, 3,211, 50, 50, 50, 22, 85,231, + 25,146,201,100,173, 5, 2,193,189,172,172, 44, 94, 46,151,211, 58,157, 78,231,225,225, 33,145,201,100, 6, 47,168,158,146,146, +210,187,178, 99,141, 26, 53,122,250,244,233,211, 38, 28,199,149, 93, 3, 81,164, 82,169,156, 59,116,232, 96, 72,251, 49,107,247, +238,221, 56,126,252,120,219,220,220,220, 49,241,241,241,123, 1,180, 21, 8, 4,120,240,224,193, 99,149, 74, 53,114,240,224,193, +123,178,178,178,238,160,104, 9, 30, 67,112, 62, 38, 38,102,180,171,171,235,238,229,203,151,155,248,248,248, 8, 28, 28, 28,208, +166, 77, 27,196,196,196,224,204,153, 51,186,173, 91,183, 22, 20, 22, 22, 78, 0,112, 73,127,181,131, 98, 89, 22, 98,177,184,116, +147, 72, 36, 16,137, 68,200, 83, 18,124,241, 83,172,146,133, 76,185,118,217,164, 51, 4,160, 94, 39,198,166,191,121,157,120,135, +162,168,107, 41, 41, 41, 57,149,148,153, 88,165, 82,181, 36,132, 48, 20, 69,173,215,106,181,126, 51,102,204,176, 95,181,106, 21, +154, 53,107,134,244,244,116, 40, 20, 10, 56, 59, 59, 35, 45, 45, 13,161,161,161, 92, 97, 97,225, 54, 0, 43, 80,236, 63, 82, 25, +178,211,115,225,104, 87,239, 29,229,147, 16, 2,194, 1, 58, 53, 7, 78, 75,160,161,116, 16, 10,117, 16,137, 68,134, 12,169, 16, +158,231,145,101,111, 15, 62, 50, 18,183,111,223, 6, 33,164, 82, 85,205,197,197,197, 32,133,148,227,184,247,136,214,157, 59,119, +192, 48, 12, 58,117,234,132,176,176,176, 82, 69,203, 32,191, 68,194, 67, 44, 17,191, 51, 92, 72, 81, 20, 68, 98, 49,132, 98, 81, + 69,179,113,140, 42,150, 17,127, 27, 24, 58,142,157, 13, 96,242,195,135, 15,247,118,237,218, 53,136, 16, 34, 68,209,120,228,245, + 15,249,243,215,175, 95,223,191,121,230,254, 66, 91, 71,139,192, 62, 99, 58,161, 89, 75, 39,112, 44,135, 27,103, 31,224,215, 85, + 39, 15, 38, 37, 38,249,193,128,181,207,120,158,191,218,177,117, 51, 26,101, 98,117, 59, 56, 56,240, 53,153,117,152,147,147,179, +116,238,220,185,152, 63,127,126, 77,102, 29, 86,136,136,232,180,201, 20,136,227,128, 62,157,123,129,162,137, 70,163,214,211,240, +161, 52,114,169, 72, 36,124,114, 55, 60,197,163,162,116,105,105,105,189,198,143, 31,127, 73, 32, 16, 52,168, 78,153,243, 60, 31, +159,154,154,218,189,234,148,236, 13,181, 50,215,249,244,193,237, 95,159, 63,190,187, 23,207,115,141, 41, 0,140, 64,244, 92,167, +213, 94, 80, 43,115,215,193,192, 69,165,215, 76,246,198,172, 13, 23,177,101,254, 0,204, 8, 60,140,157, 75,190,192,194,159, 14, + 96,245,252, 89, 88,185,241,223,248,118,214,104, 12, 29, 53,158, 39, 20,253,167,161,215,193, 48,204,249,237,219,183,143,251,226, +139, 47, 74, 39, 45, 16, 66,222,105,132,117, 58,157,146,231,121,108,219,182,141, 7,112, 94,159,189,119,235,136, 34,250,252,165, + 12,173,163,220,220,220, 9,222,222,222,123, 0, 72, 8, 33,207,178,178,178,190, 2,222, 46, 13,149,159,159, 63,161, 67,135, 14, +123, 8, 33, 18,138,162,222, 59,110, 8,138, 67, 61,180,182,176,176,184, 87,172,100, 73,106,226, 16,175,175,168,245, 12, 43, 26, + 50,132,248,127,236, 93,119, 92, 20, 87,219, 61, 51,219,151, 93,202,210, 89,138, 2,138,130,162, 66,108,216, 91, 36, 42,214,136, +198, 40,150,152,152,188,182,168, 73, 4,163,177,151, 36,182,168, 49,106,236, 70, 99,195,168,136, 53, 88, 18,141,177,128,136,160, +210,123, 91,150,178,192,246,157,153,239, 15, 74, 16, 41,139, 38,239,151, 55,217,243,251, 45,187,195,204,156,189,247,238,157,185, +103,158,251,220,231,161, 1,204,173, 19,241,125, 93,247,238,221,235, 38,149, 78, 40, 41, 41,233,250, 10,229,186,170, 82,169, 58, + 46, 91,182,108,129, 64, 32, 24,168, 84, 42,219, 1,128, 72, 36,122,174,209,104,174,171, 84,170, 45,104, 62, 54,149,150,166,233, +231, 6,131,193,215,206,206,174,106, 69,109,181,216, 2,128,115, 15,168, 7, 0,213,173,202, 40,126,212,232,130, 69, 70, 70,182, +150, 72, 36, 67, 9,130, 24,207, 48,140,119,121,121,185,102,217,178,101,119, 78,158, 60, 89,230,238,238, 62,108,196,136, 17,132, +181,181, 53,238,223,191,207,200,229,242,211, 0,150,192,136,149,214, 52, 77,103,124,253,245,215,104,233,245,222,212,126,157, 78, +151, 31, 25, 25,105,251, 86, 97, 33,155,166,105,140, 28, 57,242, 5, 1, 87, 31,207,158, 61,131, 70,163,105, 54,152, 99,105,105, + 41,186,119,239,254,194, 3,106,205, 43, 35, 35, 3,214,214,214, 47,124, 79,115,207, 88,154,178, 18, 12, 90,176, 24,168, 94, 81, + 90,131, 42, 75, 22, 3, 70,107,210, 85, 38,252,125,241, 87, 39,223, 52,202,180,232,228,228, 52, 81, 32,226,207,110,213,206,169, +115,110, 74, 97,124,121,153,242, 72, 94, 94,222,238, 70,110,228, 70,113,182, 48, 96,169,201,252,251, 23,113,254, 17, 71,139, 2, +195, 80, 96,104, 6, 12, 67,131,166,169,170,132,215, 12, 13,134,162, 8,130,192,175, 90, 85,147,145,193,235,151, 83, 98,107,107, +187,138, 97,152,183, 88, 44, 22, 89,247, 70, 93,247,115,181, 37,235,146, 76, 38,251,162, 1,203,235,255, 92,123,158, 60,121,178, + 65,241,111,236,170,195,224,224, 96,170,133,215,230,117,145, 72,228,212,208,190,202,202,202,204,188,188,188,161,127,147,246,172, +187, 98,176, 37,156, 45, 94,117,216, 28,103,171, 86,173,248, 58,157,206, 31,128, 23, 65, 16, 86, 0,138,117, 58,221,229,162,162, +162, 2, 0, 93, 1, 44,171, 62,103, 53,128, 7,255,207,215,187,208,214,214,118, 63, 73,146, 46,198,156,108, 48, 24,180,197,197, +197, 83,235, 61, 16,252, 49, 5, 15,176, 4, 92,238, 61,144,164,115, 67,215, 99, 99,159,193, 48, 57,149, 42, 85,119,226,143,123, +126, 45,167,141,141,205, 3, 54,155,237, 98, 68,217,178,229,114,121, 87,211, 61,249,127,154,243,127, 25,245,157,224, 27,141, 20, +255, 87, 8, 45, 19,167,137,211,196,105,226, 52,113,154, 56, 77,156, 38,206,127,186,208,106,112,219,180, 4,214, 4, 19, 76, 48, +193, 4, 19, 76, 48,225,245,112,161,158,216,186, 80,243,129,104, 66,149,182,196, 36,248, 42,202,246,154,137,211,196,105,226, 52, +113,154, 56, 77,156, 38,206,127, 29,167, 9,127, 34, 76,102, 85, 19,167,137,211,196,105,226, 52,113,154, 56, 77,156,255,116, 52, + 58,117, 72,154,218,198, 4, 19, 76, 48,193, 4, 19, 76, 48,225,175,129,209, 66, 75,228,224,237, 99,219,170,243, 65,137, 75,167, + 88,137, 75,167, 88,219, 86,157, 15,138, 28,188,125,254,165,237, 38, 4,240, 46,155,205,190,234,232,232,168, 64, 35,169,119,254, + 1,176, 0, 48, 30, 85,241,125,198, 2, 48,251, 51,201,251, 3,236,137,192,236, 16, 32, 51, 4,200,156, 8,204,238,255, 15,244, + 27, 92, 49,207, 41,224,214,197,119, 47,174,152,231, 20,208,224,254, 69, 78, 54,119,175, 4,127,179,110,182,212,250, 79,250, 74, +115,123,123,251, 61, 14, 14, 14,233,246,246,246, 25,246,246,246,251, 1, 88,154,110,119, 38,152, 96,130, 9,127, 25,106,124,180, +106, 94,181, 62, 90,108, 0,136,136,136,232, 15,224, 6,128, 1, 65, 65, 65, 55,235,159, 45,113,243,157,217,198,163,205,167,107, + 86, 44, 33, 28,237,109,205, 12, 20,173, 75, 75,207,234,176,124,205,134, 83,185, 60,246,230,146,204,184,189,175, 80, 40,130,197, + 98, 77,228,243,249, 65, 0,106, 4, 91,130, 70,163,137,160, 40,234, 56,140, 91,166, 13, 7, 7,135, 91, 44, 22,171,117, 75,190, +152,162,168,204,130,130,130, 62,175,216,152,193,110,110,110,251,251,247,239,111,214,189,123,119,240,120, 60, 44, 91,182,108, 81, + 94, 94,222, 22, 99, 9, 36, 18, 79,115, 29, 95,240, 49,155,199,123,147,209,107,125, 25, 48, 0,201,143,163, 13,154,159,185, 26, +205,230,146,146,148,114, 35,169,150, 0,152, 86,221, 86,123, 1,124,253, 58,189,100,170, 31,244,122,170,170, 79,112,217,160,206, +166, 90,222,248,252,243,207,217, 65, 65, 65,216,187,119,111,159, 61,123,246,124, 80, 94, 94,254, 51,128,115, 0,146, 95,183, 87, + 58, 0,179,122,245,233,243,205,212, 69,139, 88,170, 91,183,240,205,254,253, 91, 81, 21,111,233,219,150,246, 37, 46, 23,227,109, +109, 57, 65, 12, 3,127, 2, 32, 8, 32, 70, 38,167, 35,117, 58,234, 56,140,136,197,214, 4,222,197,139,203,241,143,182,148,160, + 44,153, 89,202, 31,233,211,183, 44,249,250, 82, 0,195,234,239, 55,168, 5, 83, 25,150,107,144,138,137,206, 2,176,233, 53,155, +213,204,206,206, 46,246,236,217,179, 46,221,187,119,103, 3,192,131, 7, 15, 66,130,130,130, 6,201,100, 50, 95, 0,138,255,167, +155,144,128, 77,146,179,121, 28,206,155, 20, 69,117, 2, 0, 22,139,245, 88,171,215, 95, 53,208,244,183, 48, 50, 38,155, 9, 38, +152,240,207, 69,115, 90,228,111,142, 70, 35,195,215, 84,142,169,251, 94, 23, 34,251,246, 29,122, 14,126,251, 89, 89,185, 82,157, +158,158, 83,178,112,246,218,171, 31,204,223,248,211,166,239, 35, 34,111,254,158,112,215,167,251,208,120,145,125,251, 14,141, 80, + 55, 54,135,235, 38, 20, 10, 31,238,220,185, 83,247,252,249,115,166,180,180,148,121,246,236, 25,115,250,244,105,230,163,143, 62, + 82, 11,133,194,135, 0,220,140,225,116,112,112, 40,120, 22,117,133,201,142,141,102, 50, 30,252,206,232,245,122, 70,167,211, 49, + 58,157,142,137,191, 20,193,196,158, 11,103, 98, 78, 31,103,180, 90, 45,163,213,106, 25,141, 70,195,120,120,120,228, 26, 89,206, +250,144,118,236,216, 81, 27, 17, 17,193,156, 58,117,138, 89,180,104, 17,211,165, 75, 23, 10,192, 28, 99,235, 46,178,247, 26,104, +238,220, 89, 54, 51,244, 91,221,133, 59,151,153, 39,169, 49,204,147,212, 68,230,228,181, 4,102,218, 39,219,116,230,206, 93,100, + 34,123,175,129,205,213, 93, 34,145,244, 36, 8,130,169, 1, 0,166,117,235,214, 21,117, 95,110,110,110, 47,188, 92, 93, 93, 43, +220,221,221,147,109,108,108,252, 27,226,156,212, 9, 12, 19,127,148, 97,226,143, 50,159,247, 3,243,228,201,147,187, 12,195,220, +168,121,169, 84,170, 27,103,206,156,185, 49,122,244,232, 27, 0, 70, 53,209, 78, 70,181,103, 8,144, 89,126,246, 44,195,108,217, +194, 48,253,251, 51, 9, 0, 19, 2,100,182,144,211,195,209,145, 19,179,241,235, 15,180,103,207, 30, 96, 46, 94,188,192, 68, 70, + 70, 48, 63,157,217,207,108,221, 50, 91,231,224,192,137, 3,208,182, 5,156,108, 0,107, 1,108, 70,149,229,242,185, 76, 38, 99, +242,243,243, 25, 0,207,171,255,183,217,206,206,110, 19, 26,182,190, 13,169,107,201, 90,240,150,227,197, 9,195,250, 48,229,101, +185,204,132, 97,125,152, 5,111, 57,190, 96,217,122,203,211,211,124,238,200, 78,178, 39, 15,142, 80,115, 71,118,146,189,229,233, +105,254,138,237, 73,160, 42, 79,232,206,168,168, 40, 3, 83, 7,122,189,158, 57,116,232, 16, 37,145, 72, 14,180,128,179,157,157, +157, 93,134,181,181,245,243,186,255,180,235, 60,182,151,119,223,144,229, 54, 29, 70,247,111, 65, 57,187, 11,184,220,236,171, 39, +190,163,228,153,143, 25,173,170,128, 41, 75,138,102,178, 19,238, 50,135,118,111,214,243,216,236,108, 0,221, 95,167, 47,181, 16, + 38, 78, 19,167,137,243,111,200,217,148, 22,249, 95, 6,187,126, 5,235,131,207,231,133, 46,255,124, 49, 81, 42, 47, 85,169, 21, +229, 90,189, 90,173, 38,185,140,250,113,124,106, 33,201,102,149, 46,152, 63,207, 60, 52,236,243,208, 74, 96,178,145,223,233,214, +165, 75,151,123,225,225,225,246,214,214,214, 40, 43, 43,131, 92, 46,199,189,123,247,192, 48, 12,198,141, 27,199,239,209,173,155, +255,210,101,203,126,203,206,201, 9, 64,227, 3,239, 31,226,197,218, 22, 95,247,169,202, 69,251, 69,186,188,106,212, 33, 8,236, + 9, 14,170, 61,102, 85,118, 85,182, 12,129, 64, 80,155,144,248, 21, 16, 48,120,240, 96, 46, 0,188,247,222,123,138,242,242,242, +245,213, 22, 14,163, 50,173,138,236,189, 6,218, 58, 73, 35,190,219,245,181,176, 83, 27, 47,232,244, 6,100,228,231,130,205,177, +130,139, 11, 23,211, 39,191,201,233,215,203,218,118,237,234, 61, 23,242,105,140, 85, 22, 37, 94,110,140,203,202,202,234,208,241, +227,199,113,226,196, 9, 0,192,243,231,207,225,229,229, 37,106,174, 12,113,113,113,158,163, 70,141,250, 81, 46,151,183,109,238, +216,250,129,241,249,124, 62,250,244,233,131, 14, 29, 58,224,236,217,179, 3,170, 45, 91,175, 5,213,173, 91, 16, 63,122, 4,220, +124,165,135, 23,143, 55,222,104,117, 55,242,194, 17,219, 11,145, 9,216,180,105, 63,146,147,171, 12,109,158,158,158,120,119, 82, + 48,231,241,227, 59, 29,199,143,127,247,206, 47,191, 36,247,169, 22, 74,205, 97,229,247,223,127,191,196,221,221, 29,227,199,143, + 15,238,216,177,163,163,133,133, 5,118,239,222, 13, 39, 39, 39, 79,173, 86,155,116,246,236, 89,105,126,126, 62,230,205,155,135, +130,130,130, 69,141, 17, 13, 8, 28,176,148, 63,210,167,111,251, 55,166, 66,108,225,132,239,143, 29,199,179,135,135,250,106,116, + 9, 75,185,212,205, 41, 42,134, 63, 77,150, 41, 14,109,221,181,191, 77,219,142,163,208,234,141,104, 91, 53,245, 75,234,210, 55, + 61, 54,176, 5,234, 67, 43, 54,229,201, 95, 34, 29,127,146,229,171,120,106, 29,119, 21,114, 96, 5, 93, 35,176,106,173,181, 12, + 70,245,235,215,175,246,135, 75, 79, 79,135, 70,163,129,143,143, 15,169,213,106, 7, 26,217,174,237,134, 14, 29,250,107,100,100, +164, 77,187,118,237,100,197,197,197,181, 59, 28,109,172, 2,111,134,111,157,183,246,155, 31,188, 15, 51, 68,169, 44,225,167,199, +205,112,117,239,221,243,141,107, 23,195,143,136,137,138, 44,240,172,138, 0, 90,142,148, 31,247,129, 48,179,198,196,143, 22,178, + 7, 14, 30,228,252,230,176,183,175, 61, 75, 76, 30, 12,224,190,233,185,222, 4, 19,254,213, 86, 45,230,159, 86,167, 90,161, 21, + 20, 20, 68, 52, 84, 65,154,161, 59, 59,216,219, 8,183,110, 60,120,159,165,211,106, 69, 86,150, 90,142,165, 5, 77,152, 91,178, +116, 90,125, 69, 43,207, 86, 60,154,161, 59, 55,194, 95,127,137, 39, 33, 20, 10,195,207,157, 59,103,207,225,112, 64,211, 52,236, +236,236,144,150,150,134,210,210, 82,148,151,151, 35, 57, 33, 1,238,110,174, 88, 17,186,216,105,222,226,208,112,165, 82,217, 21, + 47, 78, 35,190,180,108,148,210,191,152, 55,186, 38, 5,203, 75,143,252,213,255,107, 96,159,177, 75, 81,211, 50, 51, 51, 33, 22, +139,225,235,235, 43,190,125,251,246, 47, 77,136,172, 23, 56, 37, 18, 79,115,154,207, 59,177,243,187,101, 66,157, 62, 14,241, 41, +197,104,239,222, 23, 14, 54,110,200, 45,214,226,238,189,115,136,139, 61,138, 54,206,110,152,243,209, 32,193,134,175, 79, 29,231, + 26,220,221, 74, 75,211, 20, 13,113, 42, 20, 10,177,135,135, 7,220,220,170,242,158, 81, 20,133,248,248,120, 80, 20, 85,187, 93, +247,253,224,233, 40, 24, 20, 25,152, 26, 18, 2,185, 92, 46,110,136,147,195,130, 97,225, 7,239,178,133, 28,128, 39,178,214, 86, + 84, 84,212,166,225,208,233,116,136,137,137, 65, 64, 64, 64,255,147, 39, 79, 54,167,138,140,106, 79, 29,240,213, 55, 7, 14,108, +155, 92, 86, 70, 2,192, 94,130,160,117, 12,243,149,177,125,201,222,158,115,250,210,197,195,182, 44,242, 41,172, 45,191,196,189, +123, 25,208,233,170,202, 43,151, 23, 98,238,108, 5,184, 28,115,156, 61,251,131,141,143, 79,159,211,249,249, 58, 95,188, 56,141, +216, 80, 57, 5, 23, 47, 94,196,220,185,115, 17, 31, 31, 47,173,201,209, 38, 20, 10,177,113,227, 70,150,143,143,143, 84, 36, 18, +225,210,165, 75, 40, 40, 40, 32,154, 42,231,141,203, 55,214,148, 37, 95, 95,154, 79, 92,122,235,251, 99,199,241,254,164,137,112, +100, 82,126,177,108, 67,172, 25, 58,178,247, 23, 12,203, 53, 72,100,222, 89,226,229, 59, 18, 92,158, 24,115, 62, 91,133,231,113, +231, 37,202,242,216,217, 4,149,229,186, 98,211,201,249, 47,149,243, 84, 48,245,222,209,219,111, 92,117,187,223,234, 81,204, 7, +191,231, 69,239,137,253, 67,104,121,178, 9,146,178, 4,170,210,154, 36, 37, 37, 33, 57, 57, 25,108, 54, 27, 42,149, 10, 6,131, +161,193,114, 74,165,210, 89, 6,131,225,139,234,223,249,160, 64, 32,152,113,228,200, 17,155,186, 66,219,174,243,216, 94, 54,230, +162,193, 5,133,242,146, 59,247,159, 60, 91, 56,107,252,128, 91,119,227,178,116,156,209,153,101,177,103,203, 26,105, 79,129,144, +199, 59,125,233,204, 15, 98,125,106, 20, 68, 62, 3,192, 17,123,129,210,231, 64, 89, 82,137,242,228, 60,104,190,219, 1,191,217, + 11,112,254,167, 83,226,142,157,186,158,212,232,245, 94, 0,180,175,112,109,182, 4, 38, 78, 19,167,137,243,239,201,217,168, 22, + 97, 24,230, 13, 0, 14,213,155,242,106, 93, 96, 11,160, 8, 85, 25, 5, 28,170,239, 29,188, 58,167,213,223,174,123,108,253,237, +186,159,229,213,159,237,171,223,239, 19, 4, 81,220, 76,209,157, 80,149,154,240, 66,245, 59, 80, 61,149,216,172,227, 49, 65,144, + 10,138,162,249, 92, 59,123,245,123, 19, 6,119,186,114,237, 65,140,153,173, 5, 59,112,128,127,255,123,143, 83,127, 35, 72, 66, + 79, 16,164, 81,126, 31, 44, 22,107,226,214,173, 91, 59, 89, 88, 88,128,166,105, 88, 90, 90, 66, 38,147, 65,171,213,162,172,172, + 12,154,114, 5,116,229, 10, 60,202, 74, 71,239,254, 3,240,246, 91, 67,125,126,248,233,220, 68,138,162,126,108,138, 87,218,217, +191,214,146,181,170,181,205, 31,166,137,172,210, 90,209,245,165,191, 23,184, 98, 49,222, 92, 24,250, 58,125, 32,250,194,133, 11, + 23,199,141, 27, 55,236,147, 79, 62, 33,243,242,242, 46,165,165,165,245, 6, 16,223,172,168,224, 11, 62,254,207,199, 65, 18,137, +152,193,201,171,231,208,207,127, 18,204,120, 44,200, 21, 58, 16, 4,144,240, 36, 28, 4, 97,141,216,231,121,232,235,103,129,161, +129, 62,226,159, 78, 37,124,130, 63,252,131, 94,250,105, 74, 74, 74, 80, 88, 88, 8,189, 94, 15,189, 94,143,241,193,193, 56,124, +232, 16, 42, 43, 43,161, 82,169,160,213,106, 65, 81, 20, 72,146,196,213,136,147,200, 74, 77, 64,175,128, 0,160,145,212, 75,135, + 98,192, 1,112,247,217,179,103, 72, 72, 72, 64,118,118, 54, 4, 2, 1, 28, 29, 29,177,106,213, 42,104, 52, 85,249,196,130,131, +131,251, 3,120,252,186, 23, 84, 50,176, 39,141,162,150, 14, 59,115,198,254,246,153, 51,244,221,243,231,179,249,229,229,187,141, + 57,151,203,197,248,175,191,250,168,189, 72, 36, 66,118,230, 86,120,123,115,177,104,129, 13,214,127, 89, 4, 0,152, 55,215, 5, +221,186,218, 66, 81,122, 10,182,246, 75,176,109,219,252, 54,211,166,109, 14, 81, 42,169,131,205, 80, 47, 61,119,238,220,219, 94, + 94, 94,206,209,209,209, 4,143,199,131, 80, 40,132, 80, 40,132, 64, 32, 64, 97, 97, 33,210,210,210,152,175,191,254, 58, 7,192, +210,166,136, 86,108,203,251, 13,192,176, 5,111,225,226,179,135,135,250, 58,179, 82, 31,189, 61,167, 79,122,236,221,232,242, 43, + 87,111,175, 54,168, 5, 89,165,217,215, 22,123,116,139,182,157,253,233, 74,236,248,122, 57,158,253,126,171,216,193, 77,241,173, +144,208, 52, 88,206,254,253, 87,176,157, 28,172, 13,179,166,189,109,117,222,225,206,172, 72, 54, 33,203, 47,122,184, 17,105,209, + 42,126, 91,255, 41,237, 60, 73,109, 84, 84,148,176, 95,191,126, 80,171,213,181,150,201, 35, 71,142,208, 6,131,225,122,131,125, + 83,167,251, 34, 39, 39,199, 73,165, 82,225,173,183,222,154,183,113,227, 70, 81, 77, 62, 57,138,162, 94,176,100,173,217,114,248, +242,199, 95,124,123,253,242,143, 95, 74,215,132,206, 24, 48,121,206,218,235,104, 36,143, 36,155, 36,103,159, 63,179,223, 81, 32, +209, 67,104, 61, 20,234, 2, 21,158,237,121, 31, 74,133, 26,221,214,172, 4,192,131, 86, 79, 98,247,200,241,224,216, 72,177,124, +230, 12,233,231,187,191,255,136,166,233,173,166,231,122, 19, 76, 48,161, 30, 28, 8,130,136, 0,128,208,208,208, 37,235,215,175, +127, 66, 16, 68, 4,195, 48, 65,213, 6,148, 8,134, 97,130,106,142,169, 22,103, 47,109,215, 28, 91,127,187,254,231,176,176,176, +142, 27, 54,108, 88, 23, 16, 16,240,227,157, 59,119, 82, 1, 52, 39,180, 70, 84, 11,171,151, 82,239,144, 53, 10,178,238,251, 11, + 22, 45,154,190,149,148,154,174, 28, 58,164,135, 75,196,205,199,247,167, 79, 31, 49,120,226,200,126,129,105,153,242,132, 54,173, + 28,109,159, 60,121,108, 65,211,244, 45, 99, 90,137,207,231, 7, 13, 26, 52,136, 93, 82, 82, 2, 51, 51, 51,200,100, 50,228,228, +228, 64,167,211, 65, 93, 86, 10, 77, 89, 41,212,165, 37,208,149,149, 32,249,193, 61,116,110,227,201,175,118,150,111, 18, 53, 86, +151,250,150,170,186,150, 45,158,185, 57,248,230,230, 32, 90, 62,109, 56,218,202,202,234,110,205,160,170,211,233,102, 47, 94,188, +184,136,166,105,172, 93,187,214, 66, 44, 22,159, 4,192,111,142,196,220,142, 21, 20,224,231, 75, 62, 77,139, 69,159, 46, 83,209, +206, 99, 56,210, 10, 84, 40, 42,215,161,176, 84,135,110,253,182,163,117,151,149,112,245, 91,143,132,140, 98, 72,157,189, 72,176, +249, 77, 38,127,206,202,202,122, 97,251,199, 99,199,160, 84, 42,209,166, 77, 27, 76,154, 52, 9,139, 23, 47,198,164, 73,147, 32, +149, 74, 49,121,194, 40, 44, 95,190, 28,249,249,249,205, 21, 85,211,174, 93, 59, 77,171, 86,173, 52,173, 90,181,210,232,116, 58, + 84, 84, 84,160,180,180,180,126,123,207,111,105, 67,218,219,219,135, 57, 58, 58,198,218,219,219, 63,225,243,249,145, 49, 4,241, + 84,221,170,149, 67,239, 49, 99,136, 14, 19, 38,176, 50,132, 66,226, 38, 32, 54,134,203,214,154, 51, 98,224,160, 97,188,210,146, +253,181, 70,170, 25,211,237,240,235,205,142,184,253, 75, 87,204,157,221, 6, 4, 41, 0, 65,242,160,172,140, 66,143,238, 1, 92, + 43, 43,162,185,190,244, 46,128,152,222,189,123, 75,231,204,153, 67,240,249,124,204,155, 55, 79, 55,115,230,204,196, 73,147, 38, + 37,254,252,243,207, 84,171, 86,173,224,234,234, 74,184,186,186, 58, 1,136,169, 62,167, 73, 88,180, 33,214,104,116, 9,191, 88, +121,137, 82, 41,216,246,170,208,243,199,175,216,148, 39, 95,179, 51,117, 83,218, 51,165,231,179,223,111,201, 19,227,206,211,105, +247,111, 20,229, 38,150,123,174,217,153,186,105,201,183,185, 13, 94,212, 55,111,130, 14,143,184,169, 83, 86, 42,217, 99, 70, 14, + 84,206,122,111, 98, 59,107,113,199, 35,112, 30,218,165,181,155,203,228,229,235,182,233,102,126,244,177,110,239,190,253, 76,121, +121, 57, 20, 10, 5,182,109,219,102, 56,127,254,124, 14, 69, 81, 31, 55,246, 12, 4, 0,122,189, 30,179,102,205, 18, 89, 88, 88, + 32, 43, 43,171,214, 34, 10, 0,121, 50,249,227,219,247,227,158, 46,252, 48,184,127,165, 70,163,185,124,227, 65, 66, 7,175, 86, + 46, 4,193, 52,186, 16,133,199,225,188,217,181, 71, 15, 22,195,148,130, 96,187, 33,249,208,215, 80,228, 23, 67, 81, 88, 12, 22, + 71, 4, 3,248,208,211, 60, 88,117,238,142,231,247,163,225,108,231,192,230,115, 56,129,166,241,196, 4, 19,254,157,104, 74,139, +212, 21, 75, 27, 54,108, 88,215,212,254, 58,239,218,122,219,181, 66,170,190, 8,171,251, 25, 0, 54,108,216,176,142, 97,152,160, + 59,119,238, 28, 3,160, 50,178, 10, 31,212,121, 55, 62,142, 22, 75,173, 93,255,201,226,165,144, 88, 10, 45,187,251,123, 57,158, +189,116,243,193,173, 59, 15, 18, 90,187,218,218, 49,122,173,228,171,205, 59, 92, 8,165,106,131,145,133,240,177,181,181,133, 78, +167, 67, 82, 82, 18,178,179,179,161,211,233, 96,168,172,132,166,180, 20,234,146, 18, 80,149,229,224, 82, 20, 84,178, 66,216,152, + 9,128, 63, 86, 36, 54, 99,121, 35, 26, 20, 90, 53,239, 2, 11, 11,240,205, 45, 64,114, 56,205,102,138,175,131, 55,186,119,239, +126, 34, 46, 46,174,199,144, 33, 67, 86,163,106,137,124, 70, 78, 78,206,224,101,203,150,105, 28, 28, 28, 48,107,214,172,246, 0, +166, 54, 43, 50,121, 90,159, 86,142,237,209,206,115, 42, 90,187, 14, 66,105,165, 30, 50,133, 30,133,165, 58,236,222, 30,128,211, +123,187,227,215,211,125, 17,119,249, 77,148,234, 29, 33,150,142, 6, 67,105, 59, 54,197,121,245,234, 85,172, 90,181, 10,171, 87, +175,198,218,181,107,177,122,245,106,228,228,228,192,215,215, 23,153,153,153,184,120,241, 34,242,242,242, 96,107,107,139,123,247, +238, 97,203,150, 45,248,245,215, 95,155,173,116,141,112, 53,226,152, 22,205,165, 27, 12,134,105,121, 99,198,116, 42,176,182,238, +224,239,239, 63,108,222,188,121,158,189,123,247,174,221,239,233,233,233, 38, 20, 10,243, 81,181,130,210,175, 41, 46, 26,240,183, +179,243,133, 86,243,180,250, 55,230,128, 32, 4, 24,244,102, 2,122,247,125, 0,157,158, 11,146,224,131, 36, 5, 48, 24,228,144, + 72,164, 96, 24,194,183,153, 34, 46,147,201,100, 94,215,174, 93, 35,211,210,210, 32, 16, 8, 0, 32,125,197,138, 21, 59, 54,109, +218, 20,111, 99, 99, 67, 69, 68, 68,224,167,159,126, 66, 80, 80, 16,107,230,204,153, 94,174,174,174,187,154,171,247,138,109,121, +191, 29,221,124,241, 29,142, 94,226, 39, 16,182,118, 71,165,120,244,127,250,219,138, 0,224, 82, 74, 74,185,189,155, 98, 67,101, +121,108,166,149, 75,197,151,151, 82,154, 91,113,186,130,126,152,248,244,238,209, 51,151,202, 10, 11, 74, 56,254,157, 58,170,214, +175,250,148,219,218,189,237, 87,203, 23,127,232,152,163, 16, 44, 42, 9, 57, 0, 0, 32, 0, 73, 68, 65, 84,148,190, 57,239,226, +211,240, 75,247, 42,166, 76,127,223,240,222, 7,115,212, 23, 47, 93, 61, 67,211,116, 39, 52,178,226,144,166,105,228,229,229,225, +201,147, 39, 72, 73, 73,129, 76, 38, 67, 81, 81, 17,202,203,203,107,167, 27,205,202, 21, 23,118, 28, 56,255, 72, 36, 20,154,245, +232,228,229,246,123,116,124,161, 72, 40, 52,243,114,119,107, 7,172,104,240, 62, 66, 81, 84, 39,129,153, 16, 0,129,210,184, 91, +168, 40,169, 64, 69,105, 5,202,139, 43,160,209,177,160,214,144, 80,105, 73,180,234, 63, 20, 21,149,106, 84,200,203, 64, 83, 84, + 23,211,112, 99,130, 9, 38, 52, 49,214, 71,132,134,134, 46, 49,242, 88,163,167, 55,235, 11,175,208,208,208, 37, 4, 65, 68,132, +133,133,117, 68,227, 11,170,234, 98, 79, 3, 47, 0, 70,132,119,144,203, 19, 43,204, 9,159,113, 11, 62,251,226,226,177,125,219, +237, 53, 26,101,166,141, 68, 76,137,205,120,182,239,205, 90,139,242,138,146,177,149,198,135, 35, 64, 73, 73, 9, 82, 83, 83, 33, + 20, 10,193,229,112, 64,169, 84,160, 84,149, 80,149,200, 65,234, 52,224, 82, 20,172,205,132,104, 37,117, 68,107, 7, 71,163, 56, +147,162,174,212, 58,190,215,157, 46,252,186,187, 15,120, 34, 49,120,230, 98,252, 39,226, 6, 0,128,203,229, 2,203, 86, 27,101, + 52,113,118,118, 62,119,244,232, 81,174, 76, 38, 67, 76, 76,204, 35, 0,101, 0,204, 1,208, 9, 9, 9,215,226,226,226,130,188, +188,188, 0,160, 77,115,100,138, 34,146,210, 27, 24,100,229,167, 35, 45, 59, 26,214,150, 30,224,152,181, 67, 97,169, 14,124,161, + 7,244,154, 63,102, 31,213,138, 12,168,116, 44,163,234,174,213,106, 97, 48, 24, 96, 48, 24,160,213,106,241,193, 7, 31,224,246, +157, 59,248,241,167,159,145,154,252, 28,237,221, 29, 17, 18, 50, 5,221,187,119,199,157, 59,119,154,228,154,234, 7,189,179, 24, +236,205,195, 72,240,196, 54,154,158,139, 47,255,222,156,216, 34, 8,130, 65, 35, 83,145,245,176, 41, 32, 32,160,237,243,202, 74, + 60,121,250, 20, 67, 86,172, 0, 0, 68, 70, 70,190, 80,151,133, 11, 23,242,226,227,227,223,123,240,224,193,123,185,185,185,155, + 1, 52,236,108,206, 0, 23, 46,252,134, 15, 63,140,135, 76, 38, 3, 0, 28, 63,246,135, 46, 77, 75,213,225,173, 17, 85, 51, 90, + 86, 86, 86,216,188,217,215,168,246,164, 40, 10,123,246,236,169,157, 46, 4, 0, 54,155,221,123,225,194,133,227, 26, 58,190,109, +219,182,220,230, 56, 23,140,119, 22,252,250,136,153,109,217,182,117, 71, 11,219,206,144,235,163,125,163,115,242,230, 46, 24,239, +188,117,203,169, 28,181,144,208, 28, 36,168, 44, 87,182, 64,125,200,152, 50,166, 92,218,174,149,183,154,118, 40, 95,166,248,124, +206,251,239,218, 88, 88,217, 87,238,221,177, 94, 66,178, 72,230,220, 3, 93,105, 71, 79, 27,171,209, 61,191,169,248,112,193,178, +104,173, 33,107, 14,178,206, 61, 71, 19, 33, 46, 40,138, 66,110,110, 46,100, 50, 25, 50, 51, 51, 81, 84, 84, 53,253, 90, 84, 84, + 4,154,166, 95,231,134, 8, 85,102, 38, 50,206,236, 69,235, 41, 83,208,109,245, 42, 80, 52, 27, 42, 37,133,205,189, 6,163,164, + 76, 5, 13, 77, 64,250, 70, 47,188, 31,249, 11, 72,134, 2,118,127,107, 26, 73, 76, 48,225, 95, 10, 99,194, 59,212, 8,162,245, +235,215, 7,253,217,223, 95, 87,108,173, 95,191,254,201,250,245,235, 91,242, 93,245,167, 12,107,183,107,124,180,110,212,113, 64, +123,105,208, 44, 47, 74, 72,137,143,103,231, 86,170, 42,205, 28,236,237, 52,102, 2, 62, 93,166, 40,103, 69, 63,126,164,171,204, + 79,126,214,130,122, 36,196,197,197,249,230,230,230, 34, 51, 35, 3, 6, 85, 37, 72,141, 22,140, 90,137, 33,125,122, 65, 0, 64, + 64, 18,224,210, 58,176, 89, 60,148, 87, 40, 0, 32,161,217,193, 81,175,127,201,178, 69, 16, 4,120,230,230,224,137, 68,224,137, +205, 95,176,112, 25, 99,177,225,243,249, 71, 79,158, 60,233,228,236,236,140, 85,171, 86,193,197,197,197, 91, 42,149, 42, 45, 45, + 45,133, 14, 14, 14,232,208,161, 3,122,245,234,133,139, 23, 47, 2, 70,196,148,210, 27, 4,177,207,210,209,187,168,248, 14,126, +185,241, 29,180, 42, 13,252,251,127, 7, 29,187, 53,236, 58,174, 4,157,116, 4,202,252,179, 85,214, 3,199,145,200,206, 76, 7, +193,226, 61, 49,214,242, 84,243,249,209,163, 71, 56,118,246, 38,156, 90,249, 32, 51,241, 41,158, 94,191,134,219,118, 54,104,229, +211,161,118, 26,168,209, 50, 82, 96,175,249,182, 42, 76,212,210,217,239,242,139,139,139,249,214,214,214,154,154,182,115,114,114, +122, 29,177,245,238, 39,159,124,130, 82, 14, 7, 24, 49, 2,220,148, 20,232,116, 58,244,236,217, 19,221,186,117, 3, 0,244,236, +217, 19,108, 54, 27,157, 59,119,134, 84, 42,197,183,223,126,251,110, 99, 66,139, 36, 16, 99, 48,200,189, 61, 61, 61,107,133,214, +161,195, 50, 68, 63,120, 19, 4,120,216,182, 35,169,246, 88, 55, 55, 55,228,231,165,128, 32,152,184,102,202,184,218,209,209,113, +153,147,147,147,231,166, 77,155, 88, 2,129, 0, 31,125,244,145, 71, 69, 69, 69,235,106, 83, 50,194,194,194, 0, 0,203,151, 47, +199,138, 21, 43,160,209,104,148,141,145, 29,218,220, 73, 90, 88, 76,191,199, 84,152,141, 29,104,219,186,211,160,192, 33,240,240, + 26,132, 65,129,153, 0,176,206,154,157, 62,225,171,207,173,206, 88,153, 19,251,175, 92,186,186,188, 79,255, 65,159, 47,174,184, +190,230,203, 61,165,205,250, 60,150,101, 28, 44,127,198,155,184,101,251,174,195, 91,190, 8,155, 47,200,148,105, 75,114, 74,152, + 10, 49,159, 45,110,227, 64,136,231,126,182, 58, 53, 55, 55,101, 17,178, 46, 53,187,210,146,166,105,164,164,164,212,250,244,169, +213,106, 84, 86, 86, 34, 43, 43,171,182,207,168, 68, 22,111,205,153, 62,178, 75,165, 74,165,252,253,113, 98,230,210,121,147, 3, + 42, 85, 42,101, 98, 90,230,115, 96, 91,131,106,140, 36,201,199,202,114,229, 16,101,169, 26,178,152,103,112, 25,220, 10,122, 3, + 1,173,129,130, 76, 94, 14,141, 1,160, 72, 14, 58, 78, 8, 1, 69,176, 81,148,155, 3,146,197,122,132, 23,157,246, 77, 48,193, +132,127, 15,154,212, 34, 53, 22,173,128,128,128, 31,235, 90,157,106, 62, 3,208,160,105, 87, 30, 89, 93, 49, 85, 51,157,216,216, +247,212,227, 53, 22, 47,249,104, 53, 27,222,161,230, 59, 93, 45, 21,210,175,151, 79,118,161, 13,134,246,133, 69, 5, 6, 54,155, +207,113,181, 84,229, 21,103, 26,255,237, 26,141, 38,226,218,181,107, 99,222,124,243, 77,126,226,227, 71,208,150,149, 65, 91, 86, + 10, 14,109,128,181,176, 43, 72,157, 6,132, 86, 11,103,111, 26,234,114, 33,110,222,142,211,107, 52,154, 8, 99,133, 22,201, 98, +189,232,151, 37, 22,131,111,110, 1,190, 88, 92,127,106,177, 57, 81, 96, 54,116,232,208,193, 61,123,246, 4,195, 48,216,179,103, + 15,116, 58, 29, 79,167,211, 65,171,213, 66,167,211, 65,161, 80,224,240,225,195,216,185,115,231,109, 0, 7,154, 29,204, 12,218, +107,151,175, 70,117,159, 49, 57,136, 19, 25,177, 25, 6, 45, 5, 21,225,130,202, 74, 61, 42,180,102,160,108,166, 0, 5, 23,192, + 98, 11, 16,208,217, 3,103, 79,133,235, 96,208,252,108,164, 10,127,193, 42,148,149,153,142,236,228,231, 16, 43,242, 97,103, 97, + 6,101,202,115,248,135, 76,125, 37,235,132,171,171, 43,104,154,198,192,129, 3,107,157,171, 95, 85,108,201,229,114,156, 63,127, + 30, 61,123,246, 68,255,254,253,145,147,147,131,148,148, 20, 12, 31, 62,188,246,152, 71,143, 30, 33, 58, 58, 26,109,218, 52,109, + 36, 44, 42,214, 71,102,103,197, 4,143, 30, 61,154,123,247,238, 93, 48, 12, 3, 47, 47, 11, 88,152,139, 64,144,124,248,248,216, + 3,168,122, 6, 24, 48, 96, 0, 20,138, 20, 67, 73, 9, 19,217, 76,117,143, 2,248, 73,171,213, 38,245,235,215, 79,154,156,156, +140, 5, 11, 22,176,143, 31, 63, 94, 99, 74, 70,104,232,139,139, 41, 84,170,198,167,238,219,119,242,254,212,195, 32,233, 47, 16, +182,118,183,176,237, 12, 15,175, 65, 0,128, 55,131,102,192,163,173, 27, 20, 69,177,238,106, 85,250, 88, 46,187, 68, 18,187, 45, + 39, 94, 56,194,119,186,186,240, 70, 34,170,166, 78,155,253,217, 85,137,199, 11, 50, 57, 83, 78,252,116,238,226,172,225, 65,163, + 56,122,202, 96,240,109,197,177, 58,121,230, 66, 97, 78, 70,230, 55,200,188, 20,247,135,253,175, 73, 43, 30,165, 80, 40, 32, 18, +137, 16, 23, 23,167, 25, 49, 98, 4,159, 36, 73, 36, 37, 37,213, 10, 45,123, 91,235, 14,189,187,249,122,175,217,114,248,178,136, +207,231, 7, 14,232,234, 19,159,152,145,205, 48, 68,122,163,214, 86,189,254,234,227,152, 71, 3,237,164,109, 89, 41, 55,238,194, +166,239,112,104, 52, 36, 84, 90, 26, 26, 3, 96, 96,113,225,228,215, 3, 86,109,124,192, 0,184,127,247,182, 94,163,215, 95, 54, +141, 53, 38,152,240,175,182,106, 49, 77,137,164,234,207,197, 0,210,215,175, 95, 95, 84,199,218, 36, 3,240, 8, 64,151,234,227, +100,245,206,147, 17, 4,113,159, 97,152,110,117,120,100,117, 4, 87,221,207,218,122,199, 60,106,129,200,170,251,254,162,208,106, +108, 73, 37, 0,216,218,218,218,251,251,119,109,243,253,190, 19, 96, 24, 6,207,162, 55,162,164,240, 41,150,173,251,173,141,179, +179,115,255,156,156,156,155,198,148,128,162,168,227,251,247,239, 95,212,227, 13,127,127,119, 23, 23, 60, 74, 79, 3,151,161,192, +165, 40,144, 58, 13,216,148, 22, 46,190, 20, 72, 66,140,220,220, 50,108, 56,122, 34,174, 58, 74,124,147,240, 30, 62, 10,171,178, +203, 64, 16, 4, 54, 5,248,130,103, 46, 6, 87, 36,198,127,206, 69,213,138,171,136, 85, 97,224,137,197,104,211,195,168,128,240, +202,235,215,175, 63,120,252,248,113, 55, 95, 95, 95, 44, 90,180, 8,233,233,233,160,105, 26, 5, 5, 5,234,188,188,188, 28,153, + 76,150, 14,224, 12,128,239, 97, 68,228,113,174, 70,189, 53,226,244,161, 57, 1,125,250,219,142, 30,187, 19, 63,157, 90,136,210, + 50, 5,148, 6, 33, 42,213, 6, 84,106, 88,176,182,233,132, 30,157, 59, 35, 55,167, 16, 79,238, 94,174, 96,107,148, 27, 91,210, + 65, 9,130, 64,116,116, 52, 60,165,230,120,254,203, 77,216,154,113,208, 69,234, 8,105,239, 62,181,241,165,154, 2,135, 5,195, +187,239,190, 91, 27, 25,126,232,208,161,105, 83,166, 76,113, 90,184,112, 33,246,237,219,135,219,183,111,191,228,160,221,191,127, +127,220,186,117,107, 37,128,229,205, 25,245,180, 90, 45,188,189,189,113,255,254,125, 92,187,118, 13,131, 6, 13, 66,255,254,253, + 17, 27, 27,139, 43, 87,174, 32, 58, 58, 26, 4, 65,192,198,198, 6,250, 42,241,172,111,140, 76,167,195,201, 47,191,218,191,100, +203,150,157, 29, 39, 79,158,140,211,167,127,196,140,233,237, 65,144,124, 16, 4, 31,163, 70,182,199,170,213,247,209,163,199, 0, +216,218,114,176,101,243,217, 84,149,138, 58,108, 68, 51,174,185,114,229,138, 84,173, 86,163,180,180,148, 17,139,197,132, 92, 94, +181,162,181, 33,139,150, 82,169, 20, 52, 70,244,248, 97,194,198,210,114,166,132,169,136, 30, 91,108,136,238, 52, 40, 48, 11,111, + 6, 77,199,213,136, 3,136,186,124, 13,214,236,244, 52,136,202, 47, 22,165, 21, 41,242, 42,189,118,249,188, 49,147,149, 93,121, +121,215,220, 81,207, 89, 78, 78,244,201,176,239, 20,165, 77, 9, 45, 0, 68,113,252,145,115,103, 24,140,234, 21,208,163,173,175, +155, 19,175,164,168,144, 57,117,246, 98,156, 46,237,244,249, 58, 2,139,105, 70,168,175, 10, 13, 13,253,162,250,243,193,165, 75, +151,206,220,176, 97,131, 93,126,126,126,173,143, 86, 97, 81,113, 84,175, 17,115, 41,121,105,153,118,255,150,207,198, 11, 5,124, +222,210, 13,251,111,232, 89,184,219, 24,175,129,166,191,157,176, 96,217,252,196,103,209,206,173,133, 60,156,253,108, 57, 30, 93, +185, 14, 61,201,197,135,215,126,135, 70, 71,161,180, 72,142,159,223,155, 13,177,131, 4, 59,111,156, 46,160,105,250, 59,211, 80, + 99,130, 9,255, 94, 52,166, 69, 8,130,104, 40,198, 94, 65, 3,255,187,223,212,121,141,240,252, 25,104, 52, 42,188, 81, 75,240, +138,138,138, 10,111,221,250, 29, 55, 34,214,224,102,196, 26, 60,137,126,132,220, 28, 45,114, 10,212,176,176,176,248,173,137, 83, +235, 71,142,101,148, 74,229,184,165,203,190,200, 23, 8,205,208,111,240, 96, 56,218,217,195,140,203, 1,203, 64,131, 69,112, 80, + 33,179,194,243, 88, 37, 22,239, 63, 82, 88,161, 84,142,107, 96,144, 24,210,152,200, 32, 8, 2,124, 11,115,240,196,230,224,155, + 91,188, 48,141, 40,176,176,128,192,220, 2,108, 30,175, 33,103,248,151, 56, 43, 42, 42,222, 30, 63,126,124, 73, 89, 89, 25,102, +206,156,137,155, 55,111, 70, 95,190,124,217, 34, 54, 54, 86, 40,147,201,218, 2, 24, 10, 96,119, 19, 34,235, 5,206,146,146,148, +114,198,160,153,184,254,139,143, 85,106,131, 13,130,167, 30,135,136,204,130,129,162,193, 0,144, 90,243,208,123,200,106, 20,106, +123,225,248,174,181, 74, 90,167,158, 92, 47,134,214, 11,156, 12,195, 48, 14, 14, 14, 47,181,193,181,107,215, 16, 60,254,109, 4, +142, 29, 3, 59,119, 79,216, 15, 25,142,192,153, 31, 98,215,174, 93, 32, 73, 18,182,182,182,245, 7,222, 90,206, 67, 49,224, 28, +123, 12,226,216, 99, 16, 7,163,193, 6, 16,114,228,200,145, 47,187,116,233,114,253,246,237,219, 27, 1, 76,172,251, 93,117,176, +162,158, 53,171,161,223,232,243,249,243,231,171, 18, 19, 19, 33, 18,137, 96, 48, 24,112,251,246,109,236,220,185, 19,155, 54,109, + 66,116,116, 52,108,108,108,208,166, 77, 27,104, 52, 26,220,191,127, 95, 5,224,243, 38, 56,105,153,204,240,246,182,109, 27,228, + 65, 65,125,177,127,255, 14, 56, 58,246, 2,135,237, 8, 54,199, 14, 34,177, 55,246,126,255, 37,134, 13,243,199,185,179, 39,138, +139,228,134,183, 1, 24,140,232, 75,234,223,127,255, 29,187,118,237,194,248,241,227,115,130,131,131,169,178,178,178, 90,139, 22, +195, 48, 96, 24, 6, 43,170,125,204, 52, 26, 13,191, 49,206,247, 23,199,229,124,182,246,201,170,130,252,156,158, 55,175,255,246, +110,212,229,107, 72, 77,140, 66,212,229,107,248, 37,234, 78,104, 65,126, 78, 79,255,238,237,184,227,102,206,249,244, 80,248,105, +150,216,194, 9,135,194, 79,179, 38,205,253,120,109,215,192, 65,159, 55,215,231,171,127, 71,166,162,176, 32,108,221,198,237, 21, + 6,157,154,252,250,155,111,115, 85,178,188,207,235,244, 75,166,185,254,169, 82,169,118,171,213,106,169, 90,173,150,106, 52,154, +207,211,211,211,251, 45, 90,180, 72, 70, 81, 84,173,181, 84, 22,127,238,183,167,191, 30, 92,103,111, 43, 17,246,234,214,177,253, +230,221,167,110,100,102, 21,252, 80, 39,134, 86, 67,229, 84, 87,168,212,111,143, 25, 55,165,178,180, 68,131,128,143, 67, 65, 11, +196,208, 80,128,158, 97,193, 64,176,241,120,205,102, 8,173,205,113, 52,237,161,178, 76,175,123, 27, 47,198,208,106,170,238,175, + 3, 19,167,137,211,196,249,247,228,252, 95,134, 19, 94,204,117,232,244,130, 69,171,185, 37,149,206,206,206,253, 70,143, 26,130, + 1, 65, 75,193, 48, 12,158, 62,252, 10, 37,178,103,112,118,228, 35, 37, 83, 17, 0,224,102, 11, 10,147,153,158,149,213,115,254, +231, 75,195,131,135, 14,246,241,117,119,231,183,110,221, 10, 34,123,123, 20, 21,201,240,235,221,120,253,218, 99, 39,227,170, 69, +150, 81, 19,147, 52, 77, 87, 57,185, 3, 24, 60,127, 49, 8, 22, 11,168, 14,227, 80, 51, 48,186,119,235, 5,130,205, 6,197,208, +208,104, 52,198,172,150,203, 78, 78, 78,126,123,242,228,201, 63, 71, 68, 68,144,129,129,129,126,103,206,156,121,157,156,121,168, + 44, 76,188, 14, 32,104,109,216,172,227, 61, 7,141,177,240,234,216,149,219,181, 53, 11, 58, 61,129,220,156, 12, 68,132,223,211, +197,255,126, 89,193, 24,212, 19,149, 69,137,215,155,226,210,233,116,153,109,219,182,117,216,181,107, 87,173, 51, 60, 69, 81, 40, + 42, 42,194,111,191,253,134, 78,221,122,192,103,250,123,144,201,100,216,182,109, 27,220,220,220, 48,114,228, 72, 20, 23, 23,195, + 96, 48, 24, 59,225, 75, 1,184, 92,253, 66, 61,145, 69, 84,167, 0,106,114,218,208,211,211,147,167, 86,171,253, 24,134, 97, 17, + 4,177, 85,171,213, 78, 11, 11, 11,115, 90,183,110, 29,218,183,111,143,162,162, 34,136, 68, 34,120,121,121, 65, 38,147,225,222, +189,123,148, 82,169,220,133,170, 68,214,178,102,202,151,116,239, 94, 90,207,121,243,254, 19,254,229,134, 89, 94,106,205, 0,158, +181,117, 31, 48,140, 1, 50, 89, 58,202, 21,183,117,171, 87, 29, 72, 46, 40,212,143, 3,144,104,100,157,151,207,153, 51, 7, 0, + 4, 0,150,166,164,164,196,248,248,248,120, 53,102,209, 50, 6, 91, 78,229,168, 1, 28,123, 59, 80,186, 64, 81, 20,235,101,205, + 78, 79,235,233, 75,111,219,114, 42, 71,109, 33,173, 92, 83,148,126,243,121, 94,229,229, 93,135,194, 79,179,166,142,125,155,114, + 17, 39,134, 10,236,153, 83, 70, 80, 51, 93,186,116,113, 37,136, 98,143, 66,249,179, 7, 51,102,206,154, 96,201, 85, 69,118,113, +145,183, 33,221,252, 5,209,209,209,105,104,225,202,208,106, 60,207,201,201,233, 23, 22, 22,118,153, 97,152, 23,124, 19, 10,139, +138,163, 2,130,230, 48,165,165,101, 49,178,132,115,198,196, 82,187,119,239, 97,244, 96,223, 78,254,167,191, 92,183,193, 97,192, +252, 69,236,231,215,111, 0,148, 30, 25, 55,111,128,226,107,233,205,119,174, 22,148,233,116, 99, 97,138, 10,111,130, 9,255,122, +107, 86, 83, 90,228,111,142, 17,104,196, 25,222,232,202,120,122, 56, 95,110,239,213,122,168,155,139, 29, 0, 32, 37, 45, 23, 41, +105, 57, 87, 82, 82,115, 2,155, 81,188,141, 45,175,172, 77, 42, 77, 84,135,112, 96,140, 75, 42,253, 2,167,141,141,205, 3, 54, +155,237,210,146,214,160, 40, 42,183,168,168,200,223,200,114, 78,114,119,119,223,144,145,145, 17, 78,211,244,130, 22,170,253, 6, + 57,107,146, 74,147,108,222, 16,198,160,237, 4, 0, 4,155,103, 76, 82,233,186,156,157,196, 98,241,110, 14,135,227, 86,243, 59, +214,248, 96, 81, 20,197,210,233,116, 2,138,162, 88, 0, 8,146, 36, 13, 28, 14, 71, 77, 16,132,193, 96, 48,100,106, 52,154, 89, +248, 35,224,104, 83,117,111,118,160,175, 22, 90,104,192,162,117, 13, 0, 18, 19, 19,219, 73, 36,146,137, 4, 65,140,103, 24,198, +187,188,188, 92,179,108,217,178,232,147, 39, 79, 42,220,221,221,223, 26, 49, 98, 4, 17, 27, 27,139,184,184, 56, 70, 46,151,159, +170,182, 98,165,180,176, 47,145,124, 62,235, 29,107,107,114, 4,195,160, 11, 24, 16, 4,137,199,101,101,116,164, 82, 73,253, 80, + 45, 24, 91,218, 63,107,240,110,235,214,173, 15,164,165,165,113, 26,179,164, 54, 86,247,250,248,234,243,142, 75, 3,250,246,125, +251,183, 95,126, 57,243,217,218, 39,171,234,238,155, 59, 70, 50, 99,210,236,249, 95, 29,251,246,155,207,182,255, 84,178,223,152, +114,250,249,249,121, 18, 4, 49, 17,128, 47,195, 48,109, 25,134, 16, 16, 4, 83, 66, 16,196, 19, 0,177, 90,173, 54, 34, 62, 62, + 62,251, 53,234,254, 42, 79,184,141,113,214, 38,149, 6, 69,117,166, 0,198,200,164,210,255,237,114,154, 56, 77,156, 38,206,255, + 63,206,255,101,124,208,192,255,140,139, 12, 95,131,148,212,156,192,148,212, 28,180,109,219,150, 73, 74, 74,106,145, 72,107,108, +144,166, 40,234, 71,165, 82,249,227,235,144,200,229,242,174,127,113,227, 29, 75, 75, 75, 59,246,103, 18, 86, 11,169, 85,213,175, + 87,197,227,138,138,138, 30,198, 30,172,211,233,254,138,182, 33,170,173, 89, 43, 27, 59, 96,232,208,161, 25, 58,157,238, 26,128, + 44,130, 32,172, 0, 20,235,116,186,203, 6,131,161, 32, 41, 41,169,235,230,205,155,107, 34,223,175, 6,240,224, 21,203, 65,107, + 52,212,209,220, 92,234,232, 95, 80,199,163, 90,173,118,161,141,141, 77, 27,181, 90,205, 83,171,213,220,186,139, 15,132, 66,161, +172, 41,135,248,186,176, 50, 39, 14,114,217, 37, 54, 86,230, 68,125, 33, 5,107,103,156, 86, 85,198,181,183,118,198,105, 99, 11, + 22, 19, 19,147,210,165, 75,151, 35, 36, 73,186, 51, 12,227, 0, 48,150, 12, 3, 25,195, 48, 69,108, 54, 59, 39, 62, 62, 62,231, +111,116, 19, 82, 27,104,122,163, 65,171,253,195,239,208,180,186,208, 4, 19, 76,248,231,160, 81, 31, 45,118, 75,153,146,146,146, + 8, 83,123,154, 80, 87,108, 53,181, 51, 35, 35, 67, 3,224, 78,245,171, 62, 30, 0, 24,249,119,175, 96, 94, 94,158,127, 99,251, +140, 21, 89, 64,149,207, 22, 16,215, 96,116,246, 21,219, 75,202,177, 61,252,211,150,150,237,209,163, 71,153, 48,114,138,221, 4, + 19, 76, 48,193,132,191, 12,175,111,209, 50,193, 4, 19, 76, 48,193, 4, 19, 76, 48,161, 65,236,169, 35,184, 94,176,110, 17,104, +124,229, 64, 75,230, 94, 95,101,245,193, 53, 19,167,137,211,196,105,226, 52,113,154, 56, 77,156,255, 58,206,127, 42, 94, 18, 89, +255, 13,152,150,190,154, 56, 77,156, 38, 78, 19,167,137,211,196,105,226,252, 55,136,172,250, 47, 0,166,169, 67, 19, 76, 48,225, + 95,140,147, 39, 79, 26,149, 84,244,157,207,246, 6,137,197,146,101, 21,138,178, 13, 63,110,156,113,166,230,255,193,193,193,148, +169, 21, 77, 48,193, 4,188,138, 51,188,135,135, 75, 7,146,162,123, 51, 12,201, 98, 72, 70, 79, 40, 84,199, 83, 74, 74, 94, 8, + 59,224,234,234,106,197, 33, 49,146, 96, 24, 17, 65,208, 20,205, 34,111,167,166,102,199,183,160, 96, 60,137, 68, 50,135,203,229, + 14,209,106,181, 46, 36, 73,102,107, 52,154,107, 74,165,114, 7, 94, 14, 92,248,255,134,118,237,218, 77,186,113,227,134, 85,159, + 62,125, 52, 66,161,208,160, 82,169,216,151, 46, 93,226, 15, 27, 54,172, 52, 57, 57,249,149, 86, 36, 74,165,210, 65,123,247,238, +245, 8, 12, 12, 68,219,182,109, 43, 39, 78,156,200, 13, 8, 8,224,206,156, 57, 51, 53, 55, 55, 55,170,133,116, 29, 8,130, 56, + 76, 16, 4,139,166,233, 16,252, 17,186,225,207, 6, 73,146,228, 44,130, 32,198, 50, 12,227, 73, 16, 68, 10,195, 48,103,104,154, +110, 42,112,107, 83,120, 27,192,112,146, 36,253, 1,128,166,233,104, 0,145,128,241, 43,239,254,155,156,102,102,102,126, 0,160, + 84, 42, 99,254, 44, 78,130, 32,252, 0,128, 97,152, 87,229,156, 46, 20, 10,223, 7, 0,149, 74,245, 61,140, 72, 7, 85, 31,204, + 46,111,198,127,229, 83, 0, 64,244,114,111, 0, 64, 75,182,137, 15,159, 18, 45,249,174,134,248, 90,194,209, 0,134, 79,158, 60, +121,221, 15, 63,252,176, 28,192,217,191,162,227, 59, 58,186,238,216,244,205, 30,233,199,115,222,219,128,170,140, 16, 77, 95,144, +192,155, 60, 22,107,148,150,162,126,137, 7, 78, 2, 96, 91, 91, 91, 79,226,241,120,253,180, 90,173, 19,155,205,206,211,106,181, +183,202,202,202,142,161,137, 12, 8, 70,183,107, 2, 36, 58, 37, 28, 9,250,143, 60,111, 12, 9, 13,215, 12,249,132, 15, 74,254, + 6,183, 81, 18,192,252,234,186,238, 67,227,225, 60,154,186,249,124, 44,149, 74,199, 42, 20, 10, 37,139,197, 98, 80,181,234,185, +234, 79,213,126,130,166,233,194,226,226,226,144,230,184, 68,110,104,207, 19, 17,135, 41, 61, 84, 6, 13,243, 81,101, 22,158,138, + 93,209,139, 1, 66, 24,192,157,100,145,118, 52, 77,231, 1,136, 34, 13, 56, 95,145,139,164,191,233,224,222,170,186, 93, 91, 87, +111,115, 0, 56, 0,136, 5,240, 49,128, 10,147,254,249,175,161,190, 51,252, 5, 0,121,181, 66,171, 78,184,251, 1, 65, 65, 65, + 55, 61, 60, 92, 58,140, 31, 51,110,221,135,179, 62, 34, 88, 44, 18,113, 79,158,176,223, 13,153, 62, 84, 34,145, 56,139, 53, 26, + 31, 16, 4,173, 20, 8,226, 20,138,178,156,147,199,126, 48,247,110,223,158,162, 40, 26,187,118,127, 55,236,212, 79,225, 75,140, + 20, 91,237, 28, 29, 29, 15,135,134,134, 58,142, 26, 53,138,229,232,232,136,244,244,116,171, 31,127,252,177,253,246,237,219, 39, +148,148,148,132, 0,120,254, 10,149,237,235,104, 77, 14, 53, 23, 18,131, 81, 78,161, 92,143,159,243, 85,184, 2,224,151, 87,109, + 61,165, 82, 57, 87,169, 84,246,232,214,173, 27,179,111,223, 62, 98,218,180,105, 12, 65, 16,132, 74,165, 58, 8,224,149,132,150, + 72, 36,250, 54, 48, 48,208,203,203,203, 43, 37, 57, 57,121,248,137, 19, 39, 34,167, 78,157,234, 41, 18,137, 18, 1,180,107, 33, +221, 1,185, 92,222, 69,165, 82,193,197,197,101, 31,128, 55,254,130, 78, 68,176, 88,172, 51,206,206,206,204, 87, 95,125,117,182, + 75,151, 46, 14,197,197,197,134, 79, 63,253,116,200,221,187,119,135, 81, 20, 53,170, 5, 98, 75, 66, 16,196,110, 7, 7, 7,219, + 13, 27, 54, 36,117,237,218, 53,150,207,231,243, 18, 19, 19,205, 22, 46, 92,184,224,249,243,231, 19, 24,134,153, 5,180,104,128, +144, 16, 4,177, 91, 42,149,218,174, 91,183, 46,221,223,223, 63,142,203,229,114, 19, 19, 19, 69,139, 23, 47,254,248,233,211,167, +175,196, 73,146,228,174, 30, 61,122, 72,150, 47, 95,158,208,190,125,251, 59, 44, 22,139,151,157,157, 77,174, 88,177, 98,206,213, +171, 87,131,105,154,254,240, 85,202,105,111,111, 47, 89,177, 98, 69, 66, 64, 64,192, 93, 46,151,203,125,246,236, 25, 25, 26, 26, + 58, 39, 41, 41,201,232,114, 90, 91, 91, 15, 36, 8, 98, 79,126,126, 62, 27, 0,156,156,156,186, 91, 88, 88,108,175,155,211,178, + 38, 20,133, 94,175, 47, 87,171,213,147,139,139,139, 27, 12,132, 59, 45,108,219, 72, 0,216,174,171,217,174,122,111,110, 27,216, +117,222,152, 74,251, 57, 86,197,197,219, 84, 57, 99, 12, 0, 76,170, 78, 21,190,169, 18, 96,179,217,180,159,227,199, 76, 76,126, +139, 66,198,140, 30, 52,104,208,138,168,168,168,239, 6, 12, 24,176,248,200,145, 35,246, 89, 89, 89, 95,254,242,203, 47,174,239, +188,243,206,180,159,127,254,121,125, 81, 81,209,169, 63,171,243,243,184,124, 62, 65, 18, 16, 10,204, 44,140, 57,158, 67,146, 65, +119, 70,143,126,255,251,103,207,252,183, 63,125,234, 81,233,228,212, 99,222,188,121, 14,227,198,141, 35, 93, 93, 93,145,148,148, +100,115,228,200, 17,159,239,191,255,126,108,105,105,233,124, 0, 25,175, 35,178, 42, 75,209, 73,163,133, 63,195,192,170,246,130, + 37, 80,202,215, 33,154, 73,192,227,191,129,216,250,226,192,129, 3,203,147,146,146,176,126,253,122, 0,216,209,194,243, 23,142, + 30, 61,122, 68,120,120,184,240,228,201,147,194,110,221,186,193,209,209, 17,213, 15, 83,181,129,169, 61, 60, 60,140,107, 51, 26, +155,182, 70,206,120, 35,174,248, 34,190, 29,151,191, 94,232, 2, 67,175,209, 94, 99,131,166,249,195,210,206, 12, 2, 49, 27,165, +114,133,239,179,232,172,192,235, 39,146,190, 76,122, 40,219, 80,153,137, 47,208,120, 76,190,255, 23,216,216,216,236, 75, 77, 77, + 29, 40, 18,137, 94,248,127, 74, 74,138,159,151,151, 87, 25,128, 69, 45, 21,110,118,118,118, 71,105,154,214,200,229,242,247, 0, +192,220,220,252, 7,145, 72, 36,201,203,203, 91,242, 87, 61,200,212,160,190, 22,249, 31,183,104,213,250,107, 53,148,235,144, 32, + 41,186,247,135,179, 62, 34, 38, 78,122, 39, 63, 41, 37,149,102,115,120,147, 46, 93,190,108,214,161, 67, 7, 82,179, 99, 7, 12, + 50, 25,244, 11, 22,244,186,118,237,154, 62,120,210, 20, 21,135, 69, 28,240,244,112, 55, 59,126,236, 71,199,240,211,167,122, 3, +104, 78,104,241, 28, 29, 29, 15,223,184,113,195,217,195,195, 3,165,165,165, 72, 79, 79, 71,101,101, 37, 38, 76,152,192,233,221, +187,183,243,248,241,227, 15,151,149,149,245,105,129,101,203,161,173, 11, 59, 98,214,244,113,237,134, 13,237, 45,114,118,109, 3, + 38, 95,141,172,228,167,221, 34,110,220,157,119,224,116,228,243,164, 50, 38, 8, 13,231, 70,106, 18, 69, 69, 69,159,141, 29, 59, +246,244,192,129, 3,237,248,124, 62,164, 82, 41, 49,106,212,168,194,220,220,220,149,175,172, 90,170, 83,216,144, 36, 73,213,125, +111, 32, 61,144, 49,112,145, 72, 36,144, 72, 36, 0,224,252,186, 79,158, 86, 86, 86, 59,204,205,205,199, 43, 20, 10, 21, 73,146, + 12, 65, 16,140, 86,171, 21, 74, 36,146, 71, 9, 79,159, 75, 53, 26, 77,219,141, 91,191,255,102, 80,223, 46, 22, 87,175, 94,197, +184,113,227,152, 43, 87,174,204, 50, 54, 79, 29, 65, 16,187,199,142, 29,171, 92,182,108,153, 58, 41, 37,221, 57,225,121, 10, 33, + 18,240,104, 91, 91, 91,206,189,123,247,216, 91,182,108, 17,172, 88,177, 98, 55,195, 48,227, 91,208,158,187,223,121,231, 29,221, + 39,159,124,146,247, 44, 41,213,254,113, 66, 18, 35, 22,112, 12,182,182, 54,172,187,119,239,210,175,194, 73,146,228,174,207, 62, +251, 76, 49,107,214,172, 18,121,113,153, 99,137,162,130,225,115, 88,122, 71, 71, 71,246,217,179,103, 53, 71,143, 30, 37,223,127, +255,253, 93, 52, 77, 7,183,160,125,119,141, 26, 53,170, 60, 52, 52,180, 52, 49, 37,205,241,113,252,115,152,241, 57,122, 7, 7, +123,214,253,251,247,117, 27, 55,110, 36,215,172, 89, 99, 84, 57, 69, 34,209,161, 19, 39, 78,176,207,158,173,186,247,253,246,219, +111,164,167,167,167, 89,221, 99, 84,106, 13, 72, 2, 40, 42, 42, 50, 11, 8, 8, 56, 4,224,165,224,190,254, 43,159, 98, 90, 24, + 48,119,238,220,188,150,118, 22,127,167,121,205, 30, 67,125,231,205,108, 81,206, 24,195,102,179,233,247,223,127, 63,191,254,126, +181, 90, 77, 0, 24,133, 47,141, 23, 91,195,135, 15,255,252,194,133, 11,109,142, 28, 57,178,249,232,209,163, 90, 0, 16, 8, 4, +182, 63,254,248,227,250, 9, 19, 38, 96,194,132, 9,203, 78,157, 58,245,167, 9, 45,138,161,116, 0,192, 23,240,249, 79,159, 62, + 37,188,189,189,155,140,184,175,163,233, 7,223, 63,123,214,245, 63,222,222,221,138,105,186, 45,119,216,176,138,133, 11, 23, 22, + 41, 20, 10,164,167,167, 67,167,211, 97,218,180,105,172, 1, 3, 6, 72, 39, 76,152,176,173,188,188,252,109, 0, 58, 35,250,228, + 70,103,103,231, 15,202,202,202, 42,106,172, 58,125, 66, 40,118, 63, 63, 3,191,115, 91, 61,143,203, 50,112, 71, 46,160,137, 43, + 59,136, 74,111, 15,252, 10, 0, 92, 37,100, 45,124, 24,104, 16, 22, 46,240,160, 56, 88, 99,231, 34, 28, 36,203, 80,173,170,204, +108, 82, 44,189, 45, 18,137,198, 84, 86, 86,158,170, 30,156,219, 5, 5, 5,225,238,221,187, 0,208,187, 90,104, 13, 34, 73,242, + 93,154,166,247, 2,104, 42,149,219,188,209,163, 71,191, 25, 30, 30,110, 14, 0,167, 78,157,130, 94,175,135,167,167, 39,184, 92, + 46,120, 60, 30, 56, 28, 78,109,118, 16, 35,225,100,103,103, 11, 91, 75, 14, 36,214,162, 97,139,119,142,102,187,117,176, 64, 33, +245, 4,197, 76, 41, 12,140, 6, 92, 27, 17,218, 7, 90,193,127,232, 32,242,252,174,184, 37,231,191, 77,232,170, 36, 49, 18, 25, +208,252, 93, 70,118,146, 36,249,177,177,177,144, 74,165, 47,252,159,197, 98, 1, 64,191, 87,160, 92,150,146,146, 18,240,240,225, + 67, 12, 28, 56,112, 89,167, 78,157,222,186,121,243,166,163, 92, 46,199,192,129, 3,183,101,103,103,159,253,171,235, 84, 87,139, +252, 83, 76, 93,100, 61, 37, 57,160,234, 41,152,100,177, 88, 36, 82, 83,210,245, 3, 7, 14,158,154,153,153, 41,238,209,163, 7, +201,225,112, 80, 25, 21, 5,245,253,251, 16,139,197, 24, 59,118, 44,231,214,173, 91, 22, 22, 98,139,153,105,169,105,229, 44, 22, + 9,134, 33,155,245,121,144, 72, 36,115,150, 44, 89,226,232,229,229, 5,131,193, 80, 27,209,220, 96, 48, 32, 43, 43, 11, 98,177, + 24, 33, 33, 33,246,102,102,102,115,140,172, 71,235,118,158,246,209, 55, 34,119,191,177,240,195,225,162,118,102, 87, 33,202,154, + 15,241,169,255,192, 39,247, 18, 66,199,244, 16, 93,249,118,153,127, 27,169,117,116, 29, 19,171,209,208,104, 52,191,198,197,197, +205,188,121,243, 38, 13, 0,215,175, 95,103, 18, 18, 18,102,189,206, 83, 40, 77,211, 40, 45, 45, 5, 77,211,172,234,237,154,247, +255,215,254, 96, 97, 97,177,235,173,183,222,122, 39, 35, 35, 67,120,241,226, 69,155,204,204, 76,219,180,180, 52,187,118,237,218, +177,215,175, 95,127, 65,173,209,177,244, 20,163, 53, 80,250,242,188, 39, 79, 82, 74, 10, 10,162,247,239,223,175, 34, 8, 98,172, +145,223,241,182,147,147,147, 77, 88, 88, 24, 8,142, 89,247,246, 62,157,188, 88, 28,161, 37,201,225, 89,170, 84,106, 42, 53, 53, + 53, 43, 44, 44,204,189, 75,151, 46, 82, 84, 77,175, 25,197, 41,149, 74,109, 63,249,228, 19,176,249,230,126,157,187,248,183,225, +241, 69,230, 44,142,208,188, 71,143, 30, 3, 82, 82, 82,114, 67, 67, 67,157,186,117,235,214, 34,206,110,221,186, 73,222,127,255, +125,131, 64,104, 30,224,225,225,233,211,185,163,207,136,118,237,218,141, 97,179,217, 6,153, 76,150, 17, 18, 18,226, 52,114,228, + 72,135,150,112,218,219,219, 75, 66, 67, 67, 13,174,173, 60, 3, 3,223, 28,218,147, 43, 52,183,100,243, 68, 86, 74,165,154,122, +246,236, 89,198,210,165, 75,157,252,252,252,236,141,225, 84, 42,149, 28, 91, 91, 91,248,250,250,162,131,167, 39,202,202,202, 16, + 30, 30,142, 3, 7, 14, 96,239,222,189, 56,118,236, 24,186,246, 25, 10,115,115,115,228,230,230, 66,161, 80,112,254,219, 29,138, +250,206,155,217,174,253, 96,212, 71, 31,125,148,251,254,251,239,231, 11,133, 66,186,254,203,218,218,154,154, 60,121,114, 65,200, +226,173,163,106,166, 22,155,177,100,197, 70, 70, 70, 38, 31, 57,114, 4, 29, 58,116, 64, 96, 96, 32, 15, 0,230,204,153,195,155, + 48, 97, 2, 78,156, 56,129, 83,167, 78,197,123,121,121,221, 6, 48,218,152,114,134,132,132,244, 9, 14, 14,254, 37, 56, 56, 56, +102,226,196,137,123,102,205,154,245,194,200,149,151,155,253, 64,171,213,162,139,127, 55,179,213,251,126,159,220, 28, 95, 2,112, +100,207,211,167, 7, 54, 60,121,146,177,172, 67, 7,171, 86,105,105,214, 7, 55,110,180,173, 73,210,173,215,235,145,149,149, 5, +137, 68,130,201,147, 39,219,242,249,252, 16, 35,138,185,101,244,232,209,211, 51, 51, 51,197,223,127,255,189, 83, 76, 76,140, 52, + 47, 47,207,233,231,107,151,237, 62, 93, 52,199,220, 82,204,227,229,202, 24, 2, 0,210,114, 33,122,154,138, 62, 12, 3,171,186, +211,137,175, 4, 39, 8,133, 46,216,222,166,143,213,243, 79, 78,248, 77, 12,141,240,183,149, 56,241,195,154, 56,163,243, 87, 95, +125,117,242,252,249,243,147,250,244,233,115, 26,128,176,129, 99, 4, 93,187,118, 13, 63,113,226,196,244,190,125,251,254, 10,192, +183,209,167, 72, 23,151,177, 63,253,244,147, 77,205,182,173,173, 45, 4, 2,193, 75, 34,139,203,229,130, 36,201, 22, 87,111,237, +143,147,216,214, 62, 26,196,149, 68,226,196, 87,177,248,106,216, 51,122, 93,175, 52,205,142,144,167,184,114, 34, 22,133,136,197, +240,255,180,193,164,165, 93,134,152, 81, 88,243,119, 26,192,101, 50,217,187,253,250,245, 59, 57,124,248,112,205,195,135, 15, 33, +147,201,224,236, 92,251,172,157,255, 10,148,214,102,102,102,112,117,117,133,151,151,215,164, 91,183,110, 57,234,245,122,164,165, +165,161,176,176, 48,250,191, 81,167,186, 90,228,127, 12,245, 29,225, 47,188, 36,180,170,115, 11,221, 0, 0,134, 32, 42, 99,227, +226, 56, 44, 30,111,202, 15, 71,143,242,185, 92, 46, 50, 50, 50, 16, 31, 31, 15,229,207, 63, 67,117,231, 14, 10, 10, 10, 80, 81, + 81, 1, 7, 7, 7,236,222,183, 79,164,165,152, 25,207,158, 63,103, 49, 36, 83,215,223,160,193, 37,158,124, 62,127,200,184,113, +227, 26, 21,100,185,185,185, 24, 62,124, 56,135,197, 98, 53,180,170,161, 62, 39, 33,181, 35,206,255,124,122,181,147, 19, 47, 30, + 72, 90, 8,148, 71, 3,140, 6, 48,104,129,156,199,192,133,149,104, 85,241,148,184,188,122,170,163,179, 25,251,124, 3, 74,185, +185,165,168,158,222,222,222,123,167, 76,153, 66, 2,192,160, 65,131, 8,111,111,239, 61, 0, 60,155, 56,231, 90, 51,131,228,221, +146,146, 18, 76,152, 48,193,166, 77,155, 54,215, 38, 76,152, 96, 83,243,255, 87,229,172,177, 38,119,232,208, 65, 46, 16, 8,142, + 1, 70,221, 96,107, 57,173,172,172,118, 12, 31, 62,124,252,209,163, 71,185, 0,112,227,198, 13,156, 63,127, 30, 79,158, 60, 65, + 98, 98, 34,237,239,239,111,183,117,239,201, 93, 59,190, 59,180,101, 76,239, 46,210, 1,221,253,125,196, 21, 37, 21, 14, 14, 14, +189, 25,134,241, 52,178,156,195, 87,174, 92, 25,159,144,156, 97, 73,178, 57,108, 46,135,205,183,176, 16, 57, 54,112,168,183, 0, + 0, 32, 0, 73, 68, 65, 84, 72,204, 69, 46,214,102, 2,103, 62, 73,136,149, 74,101,254,177, 99,199,104, 0,195,141,229, 92,189, +122,117,106, 66, 82,134, 21, 65,178,217, 28, 54,135, 43, 22,155, 89, 13, 11, 28,216, 13, 0,184, 96,184, 10,133,162,224,192,129, + 3,186,150,112, 46, 95,190, 60,174,184,180, 66,194,230,112, 56,108, 54,171,182, 45, 69, 66,161,157, 25,159,207,211,104, 52, 57, +223,124,243,141,170, 37,156, 43, 87,174,140,127,150,156,105, 77, 18, 4,139, 32, 72,182,133,185,200,198,198,210,204,206, 78, 44, +180, 53, 99,179,120, 10,133, 34,231,240,225,195, 70,113,234,116, 58,110, 65, 65, 1, 18, 18, 18,224,218,173, 27,174, 94,189, 10, + 55, 55, 55, 76,152, 48, 1,239,188,243, 14,132, 66, 33, 6, 5,116, 66, 88, 88, 24,146,147,147,161,211,233,248, 13,113,214,248, + 73,213,135, 84, 42,125,216, 92,231,169,119,238, 11,229,244,115, 4,179, 93,251,193,168,186, 2,171, 49,126,107,107,107,170, 33, +107, 87,125,206,225,195,135,127,254,243,207, 63,183, 57,124,248,240,168,144,144,144, 95, 15, 31, 62,140,158, 61,123, 34, 33, 33, + 1,238,238,238, 56,120,240, 32,222,121,231,157, 95,183,109,219, 54,234,225,195,135, 93, 60, 60, 60,150, 52,199, 57,113,226,196, +217,126,126,126, 81,249,249,249, 1,197,197,197,190,225,225,225, 51,198,142, 29,155, 58,105,210,164,193,181,130, 81,175, 63,122, +225,220,105,140, 24, 53, 14,237, 59,250,238,154,182,228, 72,167,102,174, 77,230, 9,176,231, 64, 94,158,236,168, 90,173,156,192, +225,152,153,253,254,187,245,169,239,190,179,173,155, 89, 32, 39, 39, 7, 35, 71,142,228,112,185,220,190,205,148,243,171, 49, 99, +198, 76, 8, 15, 15,151,212, 88,117,238,220,185,131,199,143, 31, 35, 61, 61, 29,165,165,165, 24, 60,171, 2, 31,173,175,226,254, +104, 61,131,161,115, 24,209, 43,222, 67,106, 33,116,131,163,141, 5,251,246,140,111,218,207,249, 96, 87, 7,182,216,154,131, 31, + 22, 39,162, 40, 77,115,170, 17, 78, 34, 32, 32,224, 72,112,112, 48,161,213,106,161,213,106,181, 0, 26,140,234,235,236,236, 44, +232,220,185, 51,102,205,154, 69, 90, 88, 88,108,107,172,156,149,149,149,154,200,200, 72,132,132,132, 96,254,252,249,104,219,182, + 45, 36, 18, 9, 56, 28, 14, 14, 29, 57,110,251,206,140, 15,219,189,209,167, 95,151, 14,111,244,236, 92,174, 97,117,227, 8, 37, +239, 55, 98, 13,105,176,238, 21,246, 15, 17,151,246, 27,182,143,202,166,239, 29, 84, 86,124,250,238,215, 79,159,221, 44,120,178, + 36,120, 79, 28,243, 91,175,162, 35, 31,103,162, 64,159,128,190, 19, 90,193,195, 79,178, 64,228, 10,239, 87,109, 79, 35,209, 34, +206, 78,157, 58,245,185,119,239, 30,191, 95,191,126,200,200,200, 0,135, 83,251, 60, 69,189, 78, 57, 87,174, 92,201, 87,171,213, +120,244,232, 17,166, 78,157,154,163,211,233, 22,188, 78, 57, 91, 98,209,170,209, 34,255, 99,216, 83,239,149,215,152, 69,107, 37, + 0,232,105,156,159, 50,117,134, 50, 34, 34,194,140,199,227, 33, 35, 35, 3,121,121,121, 56,116,224, 0, 53,200,222,190, 60,208, +217, 89,113,232,192, 1, 70,171,213,130, 97, 24,120,123,123, 99,252,248,241,194,183, 39, 76, 42, 36, 20,170,227, 70, 76,243, 56, +213,204,175,207,152, 49,227,165,253,159,126,250, 41, 44, 44, 44, 64, 16,132,163, 17,149, 11,158,183,114,140,139,196,195,170,128, +201, 63, 84, 12,150, 0, 96,155, 3,108, 11, 64, 96, 9,240,205, 1,158, 25, 52, 15,163,138, 73, 38, 48,125, 92,223,247,156, 1, +180,100,170, 7, 82,169,116, 89, 84, 84,148,221,195,135, 15, 25,133, 66,129,188,188, 60,102,221,186,117,118, 82,169,116,217,171, +254, 34,185,185,185,171, 71,140, 24, 81, 48,117,234, 84,203, 75,151, 46,185, 78,157, 58,213,114,196,136, 17, 5,185,185,185,171, + 95,231,151,230,114,185,172, 39, 79,158, 88,175, 89,179,230, 29, 0, 15, 58,118,236, 40,119,118,118,126,128, 42,167,201, 38, 97, +110,110, 94, 43,178,106,172,107,108, 54, 27, 28, 14, 7, 82,169, 84, 91, 92, 92, 76,245,125,195, 83,232,109, 73,234,165,124,174, +208, 90, 40,112, 49,183,176,236, 33,151,203, 99, 9,130, 72, 49,114,138,207,175,123,247,238, 28,138,225,208, 31, 77, 25, 36,157, + 51,125,160,253,206, 53,239,187,125,179,250, 3,231,175, 86,204,244, 94,253,217,228,129, 36, 77,171,221,221,221, 29,107, 28,218, +141, 48,159,251,119,237,218,149, 77,131,131,132,231,233, 5, 25,217, 57,229,111, 14, 8,168,181, 92,118,240,243, 15,180,179,179, +235,231,237,237,221,149, 32, 8,163,150, 36, 11,133, 66,191,246,237,219,179, 73, 22,135,176,145,152,187,154,139,133, 14,181, 83, + 40, 86, 86,189,172,237,236,130, 73,134, 41,115,114,114,178, 23, 10,133,126, 45,168, 59,155, 6, 23, 14,246,214,150,118,182, 86, +226,192,129,189,219, 6,244, 10,104,215,169, 71,207,128,142,111,116,125,155, 48, 24, 20,158,158,158,246, 53, 78,242,205, 88, 90, + 5, 71,143, 30,197,154, 53,107,208,185, 85, 43, 56, 59, 59,195,222,222, 30,119,238,220,193,189,123,247, 32,145, 72, 80, 88, 88, +136,141, 27, 55,226,204,153, 51,208,233,116,230, 45,237, 79,198,136,173,166, 96, 48, 24,200,250, 2,171, 49,126,161, 80, 72,215, + 56,201, 55,134,200,200,200, 35, 53,150,172,143, 63,254,184,207,214,173, 91,127,125,250,244, 41,196, 98, 49,238,221,187,135, 25, + 51,102,252,186,109,219,182, 62, 31,126,248, 33, 14, 28, 56,128,212,212,212,125, 77,241, 77,156, 56,113,197,204,153, 51,191,185, +121,243, 38,233,224,224, 0,137, 68,130, 49, 99,198, 96,223,190,125,108,131,193,176, 63, 56, 56, 56, 38, 56, 56, 56,134,202,186, +242,249,201,189,235,238,196,197,198, 96,246,188, 79,120, 90,131, 62,212,136,234, 51, 42,177,184,220,208,175, 95,241, 9,189, 94, + 57,145,203, 53,179,140,137,177, 62,191,127,127,173,216, 10, 11, 11,131,165,165, 37, 80,229,192,140, 38,172, 58, 31,156, 57,115, +166,246,126,104, 99, 99, 3, 30,143, 7, 46,151, 11, 14,135, 3, 22,139,133,107,187, 68,248, 46,172, 74, 95,124, 23, 70,224,202, + 14,162,242,117,126, 59, 51,103,248, 74, 28,120, 49,255, 57,216,177,139,239, 96, 27,220,249, 49, 31,235, 70, 60,204,190,119, 66, +182, 80, 93,136, 77,141,156,246,198,167,159,126,218,161,176,176, 16,247,239,223,199,253,251,247, 27,179, 0,169,207,157, 59,247, +101, 69, 69, 5, 60, 60, 60, 48,122,244,232,126, 0,186, 53,114,221,160,107,215,174, 24, 57,114, 36, 6, 14, 28,136,206,157, 59, + 67,171, 51,112,130,167,124,208,254, 73,170,204,121,221,198,117,102, 81,215,195,201, 95,127,189,201, 58,114,250,138,101,192,192, +161,223,112,205,157,238, 66,104,227,100, 76, 61,149,148, 28,126, 78,195,176,231,231,121,228,246, 27, 83,197,135,206,111,247, 52, + 55, 55, 39,162,239,199,232, 15,125,123, 34,211, 87, 52,186,240,238,143,114, 40,137,124, 12,158,238, 65,210,192,248,191,203,200, + 46, 16, 8,182,222,188,121,211, 81,167,211, 33, 46, 46, 14,243,231,207, 87,191, 38,101,173, 1,196,213,213, 21, 55,110,220,192, +228,201,147,213, 5, 5, 5,191,253,183,234, 84, 87,139,252, 83,192,174,163, 32,107,145,149,149, 85, 42,145, 72,156,219,183,111, + 79,106,181,218,170, 41,137, 83,167,168,189,251,247, 95, 80,171,213,243, 0,112,119,236,220,185,203,217,197,101,224,148,144, 16, + 66,175,215, 99,196,136, 17,188,136,136, 8,155,148,194,194,114, 35, 6,156, 23,190,111,218,180,105,216,186,117, 43, 0, 96,238, +220,185,181,166,117,194, 8,135, 37,177, 37,134, 7, 6,117,181,200, 18,109,183,208,245,210, 87,180, 78, 54,191, 43,170, 16,118, + 5,201, 99, 67,192, 2,173,211, 27, 18, 11,199, 62, 72, 78,244,233, 32, 44,150,187, 15,233,216, 31,123,175, 30, 30,174,164,212, + 39,140,190,225,152,153,117, 23,139,197,120,240,224, 65,113,215,174, 93, 75, 25,134,177, 92,189,122,181,173,153,153, 89,247,215, +104,251,180,231,207,159,247,235,221,187,247, 28,146, 36,135,208, 52,125,173,160,160, 96, 7,128, 52, 35,207,255, 8,192,114, 0, +181, 79,150, 90,173, 22, 36, 73,130, 97, 24, 76,156, 56, 17, 97, 97, 97, 29, 30, 63,126,140,168,168, 40,235, 33, 67,134,220, 5, + 80, 10,224, 61, 0, 13, 90,205, 20, 10,133,234,222,189,123,194,168,168, 40,208, 52, 13,107,107,107, 88, 88, 88,128,207,231, 99, +204,152, 49,226,208,208,208,193,151, 47, 95, 46, 84,180,118, 99, 9,242,114, 42,249, 98,177, 57, 28,157,251,126, 56,233,221,167, + 12,195,156,105,193,205,129, 39,100, 27,212, 4,165, 33,191,250, 98, 27,105,198,229, 18, 2, 46, 27,124, 90,137,207,191, 92, 75, +112, 25,138,141, 22,206,207,115,185, 92,174, 57, 31, 90, 22,143,165, 55, 35,192,252, 25, 23, 7,139,197,226, 9,184,141,251, 99, +112, 72,146, 36, 73,146, 11,192,232,164,125,124, 62,159,107,206,103, 26,229, 20,178, 8, 22, 65, 16, 60, 52,178, 18,205,207, 17, + 76,141, 21,137, 55, 47, 69, 83, 87, 20,247,237,219, 23, 23,162, 30,224,212,249,107, 40,202,136,197,210,197, 31,163, 91,183,110, +136,136,136,104,178, 76, 53, 62, 90,141, 89,151,165, 82,233,195,220,220,220, 55, 26, 59,183,169, 41,195, 70,172, 84, 47,243,127, + 97, 9,255,149, 79,209,140,143,214,232,190,125,251,206, 62,122,244,168,246,173,183,222,226, 77,156, 56, 17,190,190,190,125,166, + 79,159, 14, 0, 24, 50,100, 8,182,110,221,218,103,250,244,233, 56,126,252, 56,194,195,195, 53, 3, 6, 12, 88,124,227,198,141, + 28, 84,173,232,124, 9, 52, 77,143,220,189,123,119,125, 75, 33, 12, 6, 3,244,122,189,147,193, 96,112,170,190, 23,225,155,111, +182, 21, 93,185, 28,129,197, 75, 86,194,222,206,209,207,200, 62, 68, 76,251,228,147,162,131, 27, 55, 98,227,241,227,248,196,221, +221,236,112,124, 60,174,168,213, 56, 17, 21, 85, 84,253, 61,205,250,102, 86, 86, 86,170, 34, 35, 35, 45, 78,156, 56, 1, 43, 43, + 43,180,109,219, 22,214,214,214,224,112, 56, 32, 89, 66,176,184, 18,180,239,216, 29,192, 61, 0,128,187, 20,149,222, 30,248,149, + 32, 80,202,144, 45,247, 41,226,187,161,181,173,139,224,230,236, 3,190, 86, 22,246, 92, 92,218,145,137,203,219,179,206,168,139, +176, 25, 6, 60, 67,227, 62, 95, 93, 61, 60, 60, 80, 88, 88,136,200,200,200, 74,160, 81, 65, 6,154,166,191,220,185,115,231,167, + 75,150, 44,225,123,123,123, 3,128, 31,128,251, 13, 29, 43, 18,137,224,236,236, 92, 43, 44, 39, 78,253,208,115,214,194, 15,133, + 99,135, 14, 4,155,109,139,210, 74, 61,228,229,122, 72,108,197, 88,188, 48, 88,112,173,171,115,183,221,219,126, 56,167, 82,161, + 27,240,242,253,128, 32,112,255,247,216, 95, 59, 9,188, 1,130, 4,178,200,235, 32, 64,160,130,208,131, 96,177, 24,138,162,144, +153,153, 9,134, 97, 48,121,236,140,172, 15,214,133,219,247,153,172,128,107,123, 41, 8, 6,253,255, 46, 66,192,198,198,198, 79, + 46,151, 35, 45, 45, 13, 83,167, 78,205, 41, 42, 42,186, 90, 89, 89, 57, 35, 55, 55, 23, 0,138, 95,129,178, 86,204,251,249,249, +161,123,247,238,152, 48, 97,130, 64,169, 84, 6,123,122,122, 58,203,100,178, 94,127,101,125,234,107,145,127,148,208,106,240, 66, +211,235,219,107,118,237, 66,229,181,107,224, 93,185,130, 19, 82,105,133, 90,173, 94, 4, 32,171,250,194,255,248,192,193,131,183, + 71,253,246,155,133,246,233, 83,120, 62,126, 12,142,149,149, 95, 75, 11,176,127,255,126, 40, 20, 10,148,149,149, 1, 0,182,111, +223, 14,133, 66, 1,131,145, 9,103,217, 92,244,113,180,119, 71, 62, 18, 65,179, 73,113,122,123,101, 79,177,218, 60,215, 57,211, +161,178,140,116,198,211,140, 30, 34,149, 92,219,147, 96,105,161, 46, 82,194,185,119, 91,176,193,238,211,146, 50,214,204,251,179, +217,236,226,231,207,159,143,108,215,174,221,121, 0,182,175,226, 15, 80, 15, 73, 5, 5, 5,243, 94,229, 68, 22,139,181, 60, 53, + 53,213,126,223,190,125,115, 86,175, 94,205,212, 21, 90, 53,159,217,108, 54, 24,134,129,165,165, 37, 56, 28,142,195,157, 59,119, + 28,122,244,232,241, 45, 77,211,126,141,212,147,241,245,245, 69,106,106, 42,216,108, 54, 44, 45, 45, 65, 27,116, 88,185,240, 67, + 80, 44, 62,251,179,207, 62,243, 27, 55,110, 92,220,190,125,251,244, 22, 1,189,123,201,229,242, 39,179, 39, 79,137, 59,123,246, +172,182, 58,196, 67,243,143,248, 12, 19,147,152,152,200,114,145, 58,176, 24,131,146, 22,113, 1, 65,236, 55, 12, 79,236, 8, 1, +155,197,112, 9, 18,124,129,208, 50, 45, 59, 91, 78,211,116,130, 49,156, 52, 77, 71,167,166,166, 10, 29,236,109,216, 74,149,182, + 66,200, 97,120,233,209, 15, 82, 90,251,119,245, 4, 0,117,244,189, 27,252,246, 62,194,244, 2,153,200,221,221,221, 40, 78,149, + 74, 21,147,147,147,195,114,112,112, 96,103,100,101,159,179, 18,139,236, 44,172,172,122, 2,128,174,188,236, 30,169,209,200, 88, + 28,182,131, 76, 46, 47, 86,169, 84,169,198,214, 61, 57, 57,153,237,228,100,207,186,116,229,231,243, 14,102,124,123,115, 30,219, +130, 79, 16,132, 25,139, 80,112, 13,116,145,192,204,204, 62, 45, 59,187,152, 97,152, 70, 45,132, 27, 74,167,140,173,250,189, 86, + 30,175,195,141,216,216, 88, 92,252, 53, 1, 34, 70, 11, 66, 93,134, 43, 7,190,199,228,207,150,188,182,223, 95,115, 98,235,149, +172, 89,187,125, 30,214,227, 71, 94, 51,142,240,147, 39, 79, 94,121,228,200,145, 90, 7,148,132,132, 4, 12, 26, 52,168,102,154, + 3,129,129,129,232,209,163, 7, 18, 18, 18,224,229,229,133,168,168, 40, 62,139,197,226, 79,153, 50,101,221, 15, 63,252, 16,217, +172,221,127,207, 30,204,152, 49,163, 33,199,234,100, 0,106, 66,226, 93, 17,182,225,144,109,177,188, 8,133,178,252, 24, 99,219, +129, 32, 8, 76,251,228,147,162,221, 90, 45,142,254,254, 59, 66, 68, 34,179,131, 73, 73, 24,209,163, 7, 58, 13, 26, 84,100,204, +189,174,198,170,163, 86,171,193,225,112, 96, 97, 97, 1, 27, 27, 27,112,185, 92,176, 56, 82,176,121, 93, 64,114,185,240,239,219, + 5, 27, 23,137,148, 83,135, 97, 27, 65,160,148,207, 67, 52,215,172, 81, 95, 29, 66,228,134, 49, 12, 3,133, 50, 11,215,107, 4, +137,101, 43, 88,114,204, 57, 87,102,126,235,109,101, 97,207,197,197,109, 25,184,242,109,246,105,117, 62,150, 86,183, 5,221,196, +131, 68, 39, 43, 43, 43,100,101,101, 33, 51, 51, 51, 30, 77, 59,248, 43, 19, 18, 18, 82,248,124,126, 7, 59, 59, 59, 0,240,104, +236,193,156,166,233, 90, 63,172,195, 71, 79,218,250,245,243, 20,188,217,167, 3, 14,157, 95,139,255, 4,111, 3,135, 69,128,162, +116,216,188, 53, 8,148,166, 2,193,163, 62, 32,250, 15,241,234,114,237,188,118,166, 94, 85,242,253, 75, 15, 2,108,172,249,250, +157, 59, 86,124, 49,217, 9, 52, 97,101,107,107, 47,226,114,185,176,177,112,210, 46,153,181, 32,143, 97,152,218,235,134,195,226, +234,201,114,107,149, 60,191, 66,104,197, 81, 1, 12,217,250,213,162,217,252,249,200,206,206,158,215,175, 95,191,117,229,229,229, + 37,149,149,149,147, 1,192,195,195,163, 21, 73,146,124, 0, 77,205,142,180, 66,195, 97, 33,184,143, 31, 63,134,185,185, 57,114, +114,114,234, 26, 95, 64,211,244,223,102, 17,192,223, 20,254, 0,162, 1, 56, 1, 24,129, 58,225, 29,200,106, 83, 93,255,136,136, + 8, 38, 34, 34,162,127,237,224,197, 48,180,161,184, 24,140,166,170,109, 57, 28, 14, 3,160,238,138, 38, 51, 43, 43, 43,130,227, +226, 2,130, 95,229,250,193,252,137, 75, 95,245,122,227, 66,203,208, 20, 88, 32,116, 96,234, 60,180, 84, 10, 8,172,181, 29,140, +121,188,101,200,231, 89,213, 29,233, 0, 3, 3, 10, 52,171,133,197, 97, 42, 43, 43, 97, 48, 24, 36,109,218,180,185, 96, 48, 24, + 36,213,131, 27,243,255,245,139, 82, 20,149,194, 98,177, 48,103,206, 28,212, 88,127,180, 90, 45,242,243,243,161,209,104,160,213, +106,145,154,154,138,178,178, 50,104,181, 90, 60,121,242, 4, 30, 30, 30, 96,177, 88, 78, 77,220,204, 25,134, 97,224,234,234,138, +214,173, 91,131, 69, 48,216,251,213, 10,124, 62,255, 67,188,227, 65, 99,255,142,205, 24, 48, 96,128,143,187,187,123, 0,155,205, +166, 28, 29, 29,185,225,225,225,231, 40,138, 26, 3,227,239, 60,145, 97, 97, 97,173, 59,118,236,104,111,101, 97,174,231,243, 88, +224,233, 43, 25,190, 70,206,176,149, 69,112,117,109,101,128,208,204, 43, 36, 36,132,106,204, 10,209, 16,231,162, 69,139,156,188, +189,189, 45, 37, 86,230,149, 60, 14,171,144, 11,166,168, 44,246,254, 93, 0,224,217,217,171, 33, 48,235, 48,117,234, 84, 67, 75, + 56,151, 45, 91,230, 97,103,103,103, 69,130, 41,167,116,186, 63,230,219, 53, 90, 57,193,225,168,192,229,117,157, 59,119, 46,209, + 18,206, 79, 63,253,212,189, 67,135, 14, 86, 86, 22,162, 10, 54,135,149,199,165,233, 60, 1,232,124,142, 86, 87, 34,176,179, 85, +194, 76,236, 31, 18, 18,210, 40,103,141, 53, 43, 52, 52, 52,171,158,240, 70,113,113, 49,212,249,113,224,230, 60, 69, 23, 49, 7, +221,236, 36,224,243,249,181, 75,223, 27,235,174,141,249,104, 53, 36,182,140, 61,183,235,170, 38,166, 0,119,251, 60,172, 31, 55, + 43, 55, 55, 23, 78, 78, 78, 77, 94, 79, 63,252,240,195,146,129, 3, 7, 22, 6, 6, 6,106, 47, 92,184, 0,130, 32, 16, 21, 21, +133,156,156, 28, 4, 6, 6,130, 97,152,154, 85,109,136,137,137,193,144, 33, 67,254,143,189,235,142,111,170,122,223,207,189,217, + 77,154,116,143,116,208, 66,161,165,180,133, 2, 66,217, 67, 80, 16, 80,148,249, 69,144,189, 5, 1, 21, 17, 80,145, 13,162, 40, +178, 5, 4, 28,200, 20, 40, 2, 50, 75, 89, 5,202, 42,165,180,172,210,221,210, 38, 77,154, 52,251,222,251,251,163, 73, 12,165, + 35, 41,160,226, 47,207,231,115, 63,201, 29,121,114,238,185,247,156,243,156,247,156,243,190,250, 78,157, 58,229,154,253,107,213, +138, 81,163, 70,193,104, 52, 66,165, 82, 65, 38,147, 33, 62, 62, 30,177,177,177,140, 80, 40,236,199, 10,126,125,209,192, 49,179, +219,197, 52,107,142, 53,171, 86,232,121,108,206, 82, 71,202, 43, 65, 16, 24,254,225,135,197,138, 22, 45,100,219,213,234,242, 17, + 18,137,176, 97,118,182,231,149,163, 71,189, 13, 6,131, 93, 28, 22,171, 78, 80, 80,144, 85,100,113,185, 92,176,121, 62, 96,137, +154,130,231,213, 3, 66,255,126, 56,117,149,175,115, 19, 97,159,216, 21, 71, 68,238,213,187,118, 16, 6, 99, 81,187,193,210,189, +237,255, 39, 61, 33,172,135,205,230,246,128,100,216,196,222,145,223, 68, 52,244, 9,117,193,133, 93, 5,248,115, 77,206,239,218, + 2,204, 3,112,183,182,114,110, 48, 24,180, 20, 69,129, 36, 73,176,217,108,219, 57,129,231,126,255,253,119, 92,185,114, 5,176, +113,219, 83, 86, 86, 70,177, 88, 44, 8, 4, 2, 0,112,173,161,190, 3,135,195, 1,135,195,193,233,139,103,188,254,215,191, 15, +113,254,250, 49,180,143, 29,130, 18,149, 1,133, 10, 3, 74,203,129,232, 86,115, 17,211,125, 31,110, 60, 40, 67,243,102, 49, 44, + 22, 79, 52,188, 42, 62,237, 67,100,171,179, 48,160, 36,149,110,164,207,113, 57,124, 97,255,237,212, 51,187,111,220,218,177,246, +224,221,118,173, 58,169,205,198, 4,168, 84, 42,134, 32, 8,102,250,216,217,247,183,143,146, 83,171,134,222,160,217, 58,193,189, +191,177,170, 15,241,241,241, 57,239,229,229,117,210, 44,142, 66,196, 98,241, 57,169, 84,154,134,138,133, 30,251,243,243,243, 35, +213,106,117,123, 84, 44,206,122, 84, 82, 82,242,170,217,242,244,168, 6, 75,216,102,165, 82, 57,141,162,168,183,204,219, 27, 20, + 69, 53,207,200,200,136,106,222,188,121,106, 88, 88,216,181,176,176,176,195, 97, 97, 97, 7,194,194,194, 14,116,237,218,245, 91, +139,187,135, 23, 60,108,248,148, 22,121,201,132, 22,204, 34,107,163,249, 19, 86,161, 5,224,116,229, 9,104, 38, 62,255,150,105, +242,100,184, 31, 56, 0, 78, 70, 6, 70, 14, 31, 46, 17, 10,133,171, 80,225,163,169,189,171,171,235,154,121,243,230,137,189,151, + 44, 65,192,153, 51,200,140,143,135,145,195,185, 92,151,212,105, 52, 26,176,217,108,171, 37, 70, 36, 18,129,162, 40, 84,101,242, +125,170, 0,154,112, 33,183, 48, 13, 60,132,130, 6,163, 58,162,236,148, 52,228,254, 92,223,120,101,131,240,187,106,110,248,124, +159, 54,190,171, 66, 58, 36,169, 9,182,138,231, 46, 64, 86, 86, 54, 40,208, 14,141, 55,107,181, 90,133, 90,173, 70,243,230,205, +189,174, 92,185,210, 48, 54, 54,214,211,124,252,210, 51, 62,152,182, 1, 1, 1,187, 2, 3, 3, 31, 6, 4, 4,236, 2,208,214, +129,223,110, 78, 76, 76, 4,139,197,194,188,121,243, 80, 86, 86, 6,131,193,128,146,146, 18,100,101,101, 65,175,215, 35, 39, 39, + 7,119,238,220,129, 94,175, 71,102,102, 38,116,186,218, 59, 36, 52, 77, 67, 34,145, 64,171, 81, 97,221,162, 57,248,108,214, 12, + 40,238, 37, 35, 39,175, 16,238,110, 34, 76,157, 58,149,229,225,225, 65,211, 52, 29, 74, 81, 84,119,154,166,215,219,243,156,108, +222,183,179,193,193,193, 49,203,151, 47,143,154,179,104, 61, 87,194, 86, 49,124,177,128,230,137,249, 12,175, 73, 27,140,154,187, +138,251,221,202,175,211, 47, 92,184,144, 11,251,156,119,146, 0,206,182,104,209, 34, 34, 55, 55, 55, 54, 50, 50,178,177,119, 72, +125, 62, 95, 26, 88,202,149,214, 83, 50, 58,109, 18, 17, 88,175,227,250,245,235, 83,206,157, 59,151,231, 8,167, 72, 36,106,178, +109,219,182, 24, 63, 63,191, 24,142,139,139,160, 92,161,216,105, 42, 87,239, 98,185,123, 8, 72,137,251, 27,251,246,237, 75,222, +179,103, 79,129, 35,156,225,225,225,145,139, 22, 45,138,110,218,180,105,180,127,131,134,124,151,192,224, 18, 65, 80, 72,137, 75, +211, 88, 62,130, 66,123,174, 89,179,230,218,133, 11, 23,236,226,100,177, 88, 38,146, 36,193,225,112, 32, 20, 10,113,228,200, 17, + 76, 30, 51, 4,193,129, 94,104, 28, 25,137,110,147,166, 97,207,158, 61,214, 57, 60, 44, 22,171,218, 22,125,235,146,169, 7, 91, + 72,137,100,108,104,146,140, 13, 77,146, 91, 72,137,228,106,197,150,249,124, 85,215,216, 85, 27, 85, 51,220,104,135,216,250,227, +244,233,211,203, 70,140, 24,193,235,213,171, 23,146,146,146, 48,106,212,168,179,123,247,238, 5, 0, 36, 37, 37, 97,250,244,233, +103, 79,156, 56,129, 9, 19, 38,224,213, 87, 95,229, 37, 38, 38,174,129, 29,190,127, 76, 38, 19,182,108,217, 2,147,201, 4, 87, + 87, 87,120,122,122,162, 79,159, 62, 72, 73, 73,153,240,227,143, 63,166,177, 56,156,119,123,191,213, 31,135, 14,236,197,157, 91, + 41, 19,182, 46, 30,230,176, 83, 96,146, 36,209,107,248,240,226,226,232,104,217, 86,165,178,124,180,135,135, 48,178,160,192,243, +212,174, 93,222,118, 8, 53,130,162, 40,171,184,178,136, 14,203,198,230,249,128, 45,138, 1, 91,220, 10, 55,238,114,141,220, 56, + 92,229,181,194,237,154,252,103,113,120,228,168,126,115, 26,160,223,156, 6,232, 59,179,254, 72, 97, 61,108, 18,213,195,196, 94, + 31,132,118, 13,107,229, 6,101,145, 1,241,223,100, 62,210,150, 96, 9,128, 59,246,148,115,154,166, 83,115,115,115,193,227,241, + 80,175, 94,189, 8, 0,150,121,129,155,199,142, 29, 59,101,254,252,249, 51, 0,204, 55, 31,115,237,218,181,107,180, 74,165, 66, + 70, 70, 6, 0, 92,169,193, 26,108, 93,101, 40, 83,102,242,235, 7, 52, 69,108,147,241,240,240,104,134, 92,153, 30,121, 50, 61, + 54,173,123, 27,201,137, 11,113,229,207,247,240,168,160, 0, 46,254,239,128, 50,233, 98,236,232,212, 7, 92,191,126,157, 72, 76, + 76, 36,104,154,134,209,104,100,202,148, 74,230,234,217,179,208, 36, 36, 16, 18,137,132,232,208,186,147,106,235,194, 67,151,246, +173, 62,123,197, 80,238,112, 71,253, 89,240,217,253,251,247,219,238,218,181,171, 43,128,207,154, 54,109,122, 33, 43, 43,171,221, +153, 51,103, 26, 7, 5, 5,173,170, 43,169,197, 45, 68,102,102,230, 19,155,217, 45,132,222, 44, 26,122,153,197, 92, 95, 0,211, +241, 12,171,236, 29,192,233,151,120, 50,252, 33, 84, 90,109, 88, 89,104,217, 58, 10, 67,152,135,135,216,104, 52,228, 28, 59,118, +204, 64,146, 36,132, 66, 33, 70,140, 26, 69,174, 91,187,182,227,144,182,109, 79,142,123,237,181,195, 39, 79,156,104, 17, 23, 23, + 7,134, 97, 64,146, 36,126,251,237, 55,141, 86,171, 41, 9, 14, 14,118,183,167,210,176, 45, 64, 74,165,210, 42,180, 20, 10, 5, +252,252,252,236, 30, 58, 84, 43,113,252,196,145,100, 57, 67, 77,202,234,117,119,165, 97,105,193,219,113,165, 52,197, 86, 80, 70, + 40, 52, 12,202,180, 96, 39,145,158,113, 35,194,223, 49, 60,232, 30,119, 39, 33,237,124,137,150,210, 58,180, 90,162,168,168,104, +206,192,129, 3, 75,164, 82, 41, 33,145, 72, 16, 24, 24, 72,246,237,219,183, 56, 59, 59,123,126, 93,159,136,151,151,215,255,186, +118,237,122, 48, 55, 55,119, 64, 66, 66, 66,232,153, 51,103, 6,116,237,218,245,160,151,151,215,255,236,164,216, 57,123,246,108, + 53,143,199, 67,155, 54,109, 80, 86, 86, 6,243, 42,159, 26, 55,123,134, 72,185, 92, 46, 54, 44,255, 2,159,205,154, 1, 89, 90, + 18,110,156, 61,134,211, 5, 4,230, 46,250, 26, 92, 46,183, 78,190,190, 26,249, 8,155, 54, 13, 16,223,158, 62,106,112,222,167, +179,102,137,175, 93,187,198,153,242,193,116, 38, 51, 95, 6, 94,175, 21, 44,116,158, 67, 94, 87,251,160,247, 27,221, 48,239,179, +143,154,154,157,118,214,136, 38, 62,194,166, 49, 1,226,212,143,198, 13,185,255,193, 7, 31,184, 44, 93,186, 84,219,182,109, 91, + 77, 97, 97,161,139,200,195, 51,146,237,230, 30,147,153, 95,224,218,182,109,219, 7,147, 38, 77, 42,117,148,115,238,220,185,194, +163, 71,143,178, 7, 14, 28,104,146,203,229,174, 28, 23,151,230, 4, 95,208,250,177, 92,238, 54, 96,224,192,187, 3, 6, 12, 40, + 55, 59, 44,181,155,243,243,207, 63, 23,222,185,115,135,221,182,109, 91, 99, 65, 65,129, 88,228,229, 29,203,114,247,108,245, 48, +191, 80,210, 58, 46,238,222,148, 41, 83,212, 53,165,211, 86,164,136,197,226,220,246,237,219,227,155,111,190,193,119,223,125,135, +158, 61,123, 34,229, 86, 10,122, 79,153,129,168,137,211,113,224,252, 69,228,230,230, 98,193,130, 5,136,141,141, 5,151,203,189, + 83,101,121,156,144, 70, 92, 43, 0,113,173, 0, 4, 49, 33,141,176,236, 87,107,217,154,175,128,237,245, 85, 93,119,229,243,170, + 45, 93, 45,164, 68,114, 77,243,176,106, 19, 91, 3, 6, 12,152,108,113,225, 48,122,244,232,179,171, 86,173,234, 48,122,116, 69, + 71,187, 77,155, 54, 88,184,112, 97,135,185,115,231,158, 93,180,104, 17,186,117,235,134,176,176,176, 90, 23,190, 80, 20, 5,147, +201,132, 33, 67,134,192,100, 50,225,241,227,199, 72, 79, 79,199,198,141, 27,193, 48,140, 0, 0,164, 1, 65,175,240,120, 60, 92, +191,122,185,252,179,209,113, 63, 59, 96,201, 34,108, 59, 49, 42,149, 10, 3, 38, 78, 44,206,105,212, 72,182,190,184,184,124,140, +135,135,176,254,163, 71,158, 98,189, 62, 16, 53,204, 75, 36, 8, 2, 52, 77, 91,133,149, 69,112, 85,222,204, 13,165, 93, 48,148, +211,127,156,249, 41, 15, 0,208,105, 88, 0,250,206,172, 63, 82, 26, 46,252,190,227,208, 10,163,247,158,133,247,153,178, 60,106, + 41,140, 72,117,192, 98,157,148,148,148, 4,119,119,119, 12, 28, 56,144, 79,146,228, 18, 75,127, 21, 21,190,179, 86, 90,184,248, +124,254,138,247,222,123,143, 44, 45, 45,197,141, 27, 55, 0,224, 68,117,245, 18,195, 48,214,123, 87,201, 8, 80, 52, 15,231,174, + 30,193,159,103,118,227, 97,238, 99, 60, 42,210, 2,108, 55,104,213, 57, 48,104,114,161, 47,189, 10,165, 78,104, 87,130,185, 92, +238,227,166, 77,155, 50,173, 90,181, 98, 24,134,193,189,123,247, 76,153,143, 30,153, 46,127,251, 45,115,115,252,120, 66,156,158, +206,117,113,113, 33, 26, 52,104, 0,129, 64, 64, 11, 4,130,146,191,177,241,126, 33,238, 22, 94,128, 91,136,231,105,213, 98,240, +114, 34, 31, 79,174, 54,180, 58, 48,173,202, 97, 41, 24,137,203,224,221,107,214,185, 13, 28, 50, 76, 29, 27, 27,235, 17, 24, 24, + 8,130, 32,240,246, 59,239, 16, 93, 19, 18,196,156,128, 0,120,181,108,105, 29,142, 56,126,236, 24,142, 28, 57,162, 62,244,251, +190,192, 81, 99,198,188, 9, 96, 91, 13,137, 97,243,249,124,235,255,230,231,231,131,207,231, 91,231, 68, 40,149, 74,248,248,248, + 32, 63, 63, 31,118,142,204,109,255,116,214,197, 89, 69,113,115, 26,196,137, 57,196, 97,117, 1, 40,134, 1,135,160, 0, 13, 3, + 35, 5,232,140, 12, 94,169,207,242,252, 83, 99,242,136, 79,218,251, 0,192,118, 71,114, 79,167,211,157,186,118,237,218,120,154, +166,119, 3, 32, 19, 18, 18,232,212,212,212,201,176,127,226,250,211,102,123,161,112,230,201,147, 39, 61,103,206,156, 41,143,143, +143, 87,244,233,211,199,109,227,198,141,158,175,190,250,234,204,146,146,146, 29,246, 24, 2,179,178,178,182,101,103,103, 79,110, +213,170, 21,100, 50, 25, 12, 6, 3,146,147,147, 17, 30, 30,142, 43, 87,174, 32, 34, 34, 2,151, 47, 95, 70,227,198,141, 65, 81, + 20,180, 90, 45,104,154,166,106,171,204,101,197,143,129,146, 44,228, 37, 29, 70,250,205,100,156,204, 35,176,122,199, 65,212, 11, +109, 80, 39, 63, 53, 17,190,194,104,169,143,215,159, 75,191,252,220, 55,243,212,111,216,187,101, 53,125,250,240,225, 40,158, 24, +227, 59, 15,153,214, 95,111, 68, 8, 0, 94,187,184, 86,232,229,113,135, 18,134,162,224,100,106,205, 14, 22, 35,124,133,209,126, +222, 94, 71,191, 90, 50, 95,124,239,200, 86,236,220,240, 13,179,231,167, 95, 99,181, 64, 92,116,116,116, 47,146, 36,221, 1,104, +205,243,188,236, 10,109, 83, 21,231,241,131, 7, 91,104,129,184,253,251,247,247, 18, 10,133,254, 0,140,229,229,229,247,159,133, +243, 68,124,124, 11, 75, 58, 9,130,240, 5, 96, 96, 24,230, 30, 28, 12,193, 51,104,208,160,133,211,167, 79,159, 69, 81,148,143, + 77,239,156,181, 98,197, 10, 54, 77,211, 44,134, 97, 12, 36, 73, 26,142, 30, 61, 74,153, 76,166, 60,173, 86, 59,241, 89,106,145, +254,253,251,227,226,197,139, 95,162, 98, 17,134,189,214,234, 39,230,105,153, 67,246,212,153, 63, 33, 33, 97,193,187,239,190,251, +233,142, 29, 59,210, 87,173, 90,245,214,132, 9, 19,240,219,111,191,161, 81,163, 70,184,126,253, 58,230,204,153, 3, 0, 29,230, +206,157,123, 96,243,230,205, 97,153,153,153, 43,236,176,104,192,100, 50,225,215, 95,127,197,219,111,191, 13, 31, 31, 31, 4, 4, + 4,128, 32,136, 83, 99,198,140, 89, 11, 0, 44,130,197, 5, 0,157, 86,167,139,140,108,101,183, 5,151,203,229, 90,235,186,130, +130, 2,235, 74,193,215,223,125,183,120,211,210,165,248, 89,163,193, 24, 15, 15, 97, 78, 80,144,244,192,189,123,227,110, 85, 84, +206, 76, 77, 86,157,218, 68,150,189, 83, 26, 52,249,152,253,251,226,135,254, 0,122,118, 26, 22,128, 78,195, 2,208,170,175, 47, + 65,178, 8,220,252,179, 4, 41,199,101,123,140, 74,156,130, 99,225,114, 82,151, 44, 89,114,160,115,231,206,111, 53,105,210, 4, + 99,199,142,157,180,101,203, 22,174,209,104,252, 0,127,185,121,112, 35, 73,114,254,134, 13, 27,198,121,122,122, 34, 49, 49, 17, +103,206,156, 57, 5, 32,171,186,122, 9,128,213,103, 86,189,224, 8,237,157, 76,149,176, 40,247, 28,206, 38,254,142, 70,177,211, +224,226,255, 38, 60, 35, 23,193,144,246, 29,244, 37,127,194, 51,184, 15,114, 50,239,129,197,230,167,212, 54, 9,133, 97,152, 91, + 57, 57, 57, 97, 97, 97, 97,196,195,135, 15, 77, 0, 24,138,162, 24, 67,199,142,198,168,165, 75, 57, 41,147, 38, 17,237,238,220, + 97, 49, 4, 65, 39, 39, 39, 3,192,237,127,162, 21,183,184, 91, 72, 73, 73,169,206,221,130, 67,104,218,180,105,135, 51,103,206, +240,181, 90, 45, 78,159, 62,141,214,173,173,107,187,254, 81,239,247,182, 90,228, 37,195,184, 42,142,109,124,194,162,245,196,139, + 77, 19,156,198, 17, 17, 20,151,196,143,111,191,249,102,249,181,107,215,172,189, 62,237,165, 75, 80, 31, 57, 2,138,162,192, 48, + 12,206, 36, 36,224,189, 97,195, 84, 28, 22,177,169,126,253, 80,134, 96,158,240,221,210,189,138,222,195,192,129, 3, 7, 90, 43, +159,236,236,108,136, 68, 34,240,120, 60,208, 52, 13,147,201, 4, 22,139, 5, 55, 55, 55,152, 76,166,170, 76, 48,149, 57,141,148, + 76, 61, 96,115,239,161,249, 1, 42, 3, 51,222,189, 62, 66,184, 46,214,194,233, 47, 33,240, 86, 44, 7,222,236, 34,230,196,138, +215,242,104, 93,201, 0, 60,189,162,171,182, 37,255, 17,205,154, 53, 91,251,222,123,239,145, 0,208,189,123,119,178, 89,179,102, +223,163,230, 80, 57, 53,114, 10, 4, 2, 62, 0, 28, 60,120, 80,150,158,158,222,243,224,193,131, 50,219,227,118,114,110, 92,190, +124, 57,132, 66, 33, 76, 38, 19,244,122,189,117,126,150,237,167,193, 96,128,183,183, 55, 14, 29, 58, 4,138,162, 14,213,150,206, +224,144, 80, 16, 62, 13,177,237,224, 73,156, 41,230,214, 69,100, 89, 57, 27,250,139, 26,251,123,123, 29,251,106,241, 2, 31,249, +221,100,228,228,228, 48, 71,143, 28,186,160, 5,114, 21,101,248,172, 84,141,198, 26, 61, 4,173,195,144,117,108,195, 39,204,220, + 78, 48,162,234, 85,131, 86,206, 40,127, 81,227, 64, 31,175,163, 95,127,181, 88, 92,122, 55, 25,249, 5, 5,248,227,208,193,107, + 90,192, 50,220, 56,146,166,233, 24,154,166, 99, 0,140,172, 65,188, 56,196, 89, 94, 94,222,180,188,188,188,233,243,228,100, 24, +166, 41,195, 48,118,115,218,206,137, 90,185,114,101, 90,126,126,254,123, 69, 69, 69, 61, 44,155, 92, 46,239,174, 82,169,186,148, +151,151,119,212,172, 12,117, 43, 47, 47,247, 85,169, 84, 82,173, 86,251, 10,128,100, 7,222,121, 43,108,189, 78,231,231,231,207, +203,207,207, 39,106, 75, 39,107, 98, 26,241,203,215, 31,253,190, 97,195, 6,233, 51,242, 63,145,206,226,226,226,221, 59,118,236, +104,222,160, 65,131,176,145, 35, 71, 98,253,250,245, 88,181,106,149, 14, 0, 54,111,222,172,179,177,100, 5,103,102,102,182,170, +102,216,176,187,141,181,100,251,235,175,191,206,156, 57,115, 6,111,191,253,182,213,145,232, 15, 63,252, 0,147,201,164,236,214, +173, 27, 13, 0, 26,109,185,146,161, 25,232, 13,213,142,191, 63,149,159, 60, 30,239, 13, 91,127,129, 22,103,204, 60, 30, 15, 12, +195,160,113,135, 14,197,165,177,177,178, 45, 10, 69,249,188,166, 77, 37,227, 34, 35, 71, 54, 1,134, 85,197, 73, 16,196, 19, 86, +157,202,155, 3,150, 44,219,116, 22,105,242, 48,246,247,197, 15,143, 88, 44, 91, 2, 87, 54,180,101, 38,236, 91,250,240,177,246, + 49,126,168, 78,252,212,116,239, 50,153,108,202,210,165, 75,117, 30, 30, 30,232,223,191, 63, 22, 45, 90, 52,166, 67,135, 14, 10, + 95, 95,223,139,141, 26, 53,186, 57,120,240,224,252,228,228,228, 41, 93,187,118, 69, 70, 70, 6,190,254,250,235, 82,185, 92, 62, +180, 38, 78,130, 32,172,150,188,190,189,187,203,214,125,255, 13,221,173,243,100, 8, 93, 36, 48,114,130, 33, 83, 25, 33, 87, 51, +208,243,227,192,227,242,209,163,109, 52, 46, 30,221, 90, 78,233,213,219,106,123,231, 85, 42,213,158, 17, 35, 70, 40,185, 92, 46, +244,122, 61,195,225,112,192,175,152,119, 76,115,122,246, 52,180, 75, 77, 53, 81, 12, 67, 19, 4,129, 15, 63,252, 80, 45,151,203, +119,212,165, 28, 57, 0, 91,206,231,229,110,161,123,165,246,231,121,184,133,120, 17,247,254, 50, 99, 99, 21,219, 95, 22, 45,203, +146, 74,203, 39, 65,208, 20, 69,209,168,223,160,190, 56,243, 97,214,234, 65,131, 6,142,238,213,171,183,176,119,239,222,130,232, +180,138,222,232,193,131, 7,177,119,239,222,242, 63,255,252, 83,201,231,176, 54, 7,215, 11,246,163, 40, 26, 4, 65,215,168,134, +197, 98,241, 7,179,103,207,118, 81, 40, 20, 88,181,106, 21,221,188,121,115, 82, 36, 18,193, 96, 48, 96,243,230,205,198,232,232, +104, 14, 73,146, 80, 40, 20, 32, 73,242,142,157, 55,120, 67,145,149,219, 99,109,215,126,123, 91,189, 63,202, 43,170,107, 59,143, + 46,193,129, 48,182,100,144,151,253, 16,233, 39,254,148,223, 58,250,109, 9,180,133,253, 80,123,120,160,170, 26,130, 47,254,252, +243, 79,223, 41, 83,166, 48, 90,173,150,200,202,202, 98, 22, 47, 94,236, 59,118,236,216, 47,242,242,242,254, 87,199,135, 66,148, +150,150,130, 32, 8,218, 92,114, 30,194, 56, 0, 0, 32, 0, 73, 68, 65, 84,145, 88,122,253,142,140,203,165,108,219,182,109,255, + 59,239,188,211,183, 91,183,110, 72, 75, 75,179, 14, 17,218, 10, 45,203,234,195, 37, 75,150,148, 2,248,180, 54, 82, 14,135,131, + 85,219,118,163, 84, 94, 12, 63,191, 0, 8, 92, 92, 80,215, 21,150, 60,146,156,183,108,193,231,190,197,183, 47, 18, 41, 23, 78, +210,187,110, 20, 22,153, 40,166,106,143,255,101,121,140, 89,253,215,220,155, 33, 89,243,150, 45,158,239,102, 25,214,220,113, 53, + 95, 73, 80,204,148,103, 42, 34, 47, 11,231,223,140,128,128, 0,228,231,231, 19, 1, 1, 1,140,121,142, 22, 83,131,208,122,242, + 5,175, 24, 46, 35,106, 26, 54,172, 43,255,131, 7, 15, 22,183,108,217,242,163,140,140,140, 93, 81, 81, 81, 19, 0,212,211,233, +116,165,115,231,206,253,106,243,230,205,163,237,177,100, 1,192,111,191,253,246,237,168, 81,163,142,188,249,230,155,159,208, 52, +221,204,166, 97,127,224,235,235,107, 29,194,125, 92, 88, 48,107,252,232, 33,179, 84, 42,185,221,126,238, 92, 93, 93,199,205,157, + 59, 87,160, 86,171,177,102,205, 26, 58, 58, 58,154,180,116,138,126,250,233, 39, 83, 68, 68, 4,123,224,228,201,197, 43, 11, 10, +176, 48, 49, 81, 61, 43, 38,166,249,150,244,244, 87, 64,211,219,171,179,234, 84,101,201,178, 76,187,168, 35,242,204, 98,235, 7, + 0, 61,219, 13,242,199,254,229, 15, 33,207,212,127, 5, 19,238,193,142,176, 64, 85, 32,103,207,158, 61, 61, 10, 11, 11,247,127, +254,249,231,110,175,188,242, 10, 98, 98, 98, 56,174,174,174,113, 22,119, 49, 10,133, 2,199,143, 31,199,250,245,235,245,183,110, +221,122,167,166,225, 42,138,162,138, 34, 34, 34, 44,249,192, 16, 4, 81,162,212, 17,110, 59,155,196,185,142, 28,191,139, 56,123, +249, 60,242, 12, 52,116, 70, 26,245, 27,180, 64,151,158, 43,113,224,240, 77, 42, 47, 51, 53,213,168,145,111,178, 35,189,247,238, +222,189,187,111,193,130, 5,131, 62,249,228, 19,151,226,226, 98, 74,167,211,209,187,119,239,102,141, 28, 57,146, 98,216,108,154, +203,102,227,131, 15, 62,208,148,150,150,254, 14,252,173, 1,166, 95,136,187,133, 23,224, 22,226,185, 89,179,108, 63,255, 43,168, +178,132,210, 44,242,220,250, 13,235,222,248,237,215, 29,254, 44, 22,233,127,239,254,253,203,111,245, 27,144,123,236,216, 49, 79, +174,155, 91,107, 0,180,126,194,132, 11, 6,157, 70, 22,191,127,127, 72,253,250,161,177,230,160,210, 12,205, 34,207,213,244,135, + 42,149, 74,157,152,152, 88,254,233,167,159, 18,217,217,217,191,248,249,249, 13, 62,124,248,176,107,191,126,253, 52,105,105,105, +123,252,253,253,251,118,237,218, 85,252,209, 71, 31,233, 84, 42,149, 35,129, 71, 83,153,199,242, 38,151, 62, 95,241,238,165,229, +235, 94, 3,155,213, 30, 58, 14, 64, 27,207,193, 80,118, 12,192, 47,112,192,223,145, 45, 68, 34, 81,172, 80, 40,196,181,107,215, +228,113,113,113,122,173, 86,203, 93,180,104,145,151, 72, 36,138,173,107,198, 51, 12,195,200,229,114,208, 52,205, 6, 64,152, 63, + 65, 59,190, 22,255,127,111,189,245,214,254,157, 59,119,190,222,187,119,111,132,133,133,193,104, 52, 34, 34, 34, 2,122,189, 30, +225,225,225,208,233,116,248,242,203, 47,161, 80, 40,102,160,134,152,103, 4, 65,192,100, 50, 89, 39,219, 6, 6,133, 84,248,233, +121, 6, 55, 22, 34, 14, 25,118, 39,126, 11,138, 74,138,233,157,215, 11, 11,203, 13, 84,143,187,143,203,111, 85,190,174,156,130, +186,235,200,169,185, 0,160,163,107,142, 56, 47,226, 33, 44,253,208, 15, 40, 44, 42,198,111, 87,243, 75,213, 6,186,103,122, 21, +156, 14,165,243, 37,225,108,241,101, 26, 6, 76,181,255,218,103,129,189,130,170, 58, 92, 43, 0,113, 69,184,133,193,134, 45, 85, +250,200,122, 70,254,253, 25, 25, 25,251, 1, 32, 53, 53, 53,123,200,144, 33,179, 30, 62,124,184, 0,192, 31,153,153,153, 27, 28, + 33,218,178,101, 75, 6,128, 81, 53, 93,179, 99,197,168,125, 0,246, 57,194, 91, 86, 86,166, 77, 78, 78,214,126,244,209, 71, 68, +118,118,246, 97,127,127,255,215,143, 28, 57, 34,236,215,175,159, 46, 37, 37,229, 68, 64, 64, 64,167,238,221,187,187,254,145,148, +148, 91,126,239, 94,124,252,195,135, 65, 70,154,142,175,169,124, 62,103,145,245,132,216,218,183,240,225,178,253,203, 30,118,167, +117,216,163,151,227, 2,128,156,103,224, 60,115,238,220,185,168, 97,195,134,237,236,211,167, 79,187,168,168, 40,212,171, 87, 15, +233,233,233,120,252,248, 49,110,220,184,129,131, 7, 15, 30,212,106,181,181, 6,212,150,201,100, 79,135, 39, 18,120, 6,108, 93, + 51,239,224,229,179,173, 35, 58,246, 30,225, 18, 19, 64, 67,111, 96,144,253,232, 30,190,252,108, 83,121,254,163,140, 84,131,201, +240, 14,236, 92,168,163,209,104, 54,126,247,221,119,156,248,248,248,222,171, 87,175, 22,135,132,132,176,184, 92, 46, 9,128,185, +114,229, 10, 51,117,234, 84,117,113,113,241, 33,165, 82,185,241,111,110,163,207,220,191,127,191, 5,139,197,122,174,238, 22,158, +193, 45,132, 19,207, 19, 13, 26, 4, 69, 53, 12, 9,152, 16, 86, 47,104,114,131,144,224,225, 85, 77,114, 15,243,240, 16, 55, 8, + 13, 28, 23, 86, 47,104,114,195,144,128, 9, 13, 26, 4, 69,217, 97, 90, 12,147, 72, 36,135,165, 82,105,115, 0,112,115,115,235, +235,238,238,126,203,205,205,173,175,185, 23,216,215,213,213,245,118,116,116,244,216,191,209, 92, 89, 35,103, 68, 68,196, 16,149, + 74, 53, 41, 34, 34, 98,136,101,255,222,189,123,214,253,186,112, 6, 7, 7,119,187,114,229,202,255, 86,172, 88,209,191, 81,163, + 70,125, 23, 47, 94,220,255,247,223,127,255, 95, 80, 80,208, 43,117,224,228, 3,248,153,195,225, 20,242,120,188, 34, 14,135, 83, +104,217,216,108,118, 33,139,197, 42, 4,176,161, 26,107, 89,119,155, 94,206, 89, 63, 63,191, 76, 63, 63,191, 76,127,127,255, 76, +127,127,255, 76,169, 84,250,212,230,237,237,125,214,222,252,140,244,119,237, 16, 87, 79,124,174,169,212,245,108, 19, 63, 81,228, +243,120, 70,145,254,174, 29, 90,215,115, 59,215, 84, 42, 78,252,255,198,217,220, 31, 12,179, 62,146, 97,214, 71, 50,205,253,193, +212,182,255, 60,205,254, 82,169,148,145, 74,165,243, 94,212, 80, 66, 53,252,127,123,121,127,142,156, 97, 98,177,120, 71,189,122, +245, 44,117,221,155, 18,137,228,148,171,171,235,155,230,186,238, 77,145, 72,148, 16, 29, 29, 61,162, 54, 78, 79, 79,207, 43,190, +190,190, 5,230, 45,223,207,207, 47,223,207,207, 47,223,215,215, 55,207,215,215, 55,207,199,199, 39,215,178,185,187,187, 95,172, +227,189,251, 2,104, 3,224, 21, 0,146,231,152,159, 13, 0,140, 55,215, 65, 75, 1,140, 5,208,236, 57, 60, 35,130,227,226, 57, +145,239, 30,124,142,227,234, 83,198,113,245, 41,227,187, 5,157,171, 33, 4,143, 61,156,141, 61, 61, 61, 23, 73, 36,146,223,197, + 98,113,162, 88, 44,222,239,237,237,189, 24, 64,227,127,232, 93,114, 5,176, 25, 21,254,153,254, 64,197, 80,248,126, 84, 44, 42, + 8,249, 23,190,243,255,159, 49,238,159,250,227,238, 78, 78, 39,167,147,211,201,233,228,116,114,190,132,156,164, 51, 63,157, 66, +203, 65,161, 85,121, 3, 80,131,103,120, 39,156,112,194, 9, 39,156,248,127, 12,218,153, 5, 78, 56,136, 42,135,150,137, 26, 84, +169, 35,190,166,234,162,108,143, 59, 57,157,156, 78, 78, 39,167,147,211,201,233,228,252,127,199,233,196,115,132,211,172,234,228, +116,114, 58, 57,157,156, 78, 78, 39,167,147,243,191, 14,231,208,161, 19, 78, 56,225,132, 19, 78, 56,225,196, 11,194, 70, 27,193, +245,196, 16,162, 83,104, 57, 14, 18,192, 36, 0, 3, 0, 52, 68, 69, 52,251,221, 0,214,162,110, 99,250, 18, 0,179, 0,180, 71, +197,234,156, 7, 0, 18, 81,177, 58, 71,229,204,238,170,225,237,237, 61,155,195,225,184, 3, 21,161, 77, 44,159,182,223, 41,138, + 42, 85, 42,149,139, 95, 80, 18, 88,176,211,131,178, 37,173,182,105,179,253, 52, 26,141, 47, 50,157, 78,252, 59, 17,225,233,233, +249,179, 76, 38, 27, 10,155, 32,203, 78, 56,241, 95,128,143,143,207, 4,131,193, 48,151,203,229, 46,122,252,248,241,186,255, 71, +183,254,148,200,122, 66,104,197,199,199, 39, 0, 64,159, 62,125, 58, 3,128,187,187,251,121,146, 36, 27, 56,242, 15, 52, 77, 63, + 40, 45, 45,173,214,129,154,187,187,251,121, 22,139,245, 20,167,209,104, 20,179,217,236,178,170,126, 99, 50,153,114,148, 74,229, + 43,255,146, 76, 36, 0,196,123,120,120,104, 23, 44, 88,176,182, 75,151, 46,193,121,121,121,166,153, 51,103,118,186,126,253,122, +111, 0,111, 56, 40,182,218, 18, 4,177,181,121,243,230,251,134, 15, 31,190, 51, 46, 46,142, 87, 82, 82, 34,222,189,123,119,224, +182,109,219,146,105,154, 30,138, 26, 2,173,254,127, 6,135,195,113,207,201,201, 17, 3, 21,161, 73,204,194, 10, 70,163, 17, 70, +163, 17,106,181, 26,177,177,177,207,253,127,253,253,253, 91, 16, 4,177,218,213,213,245, 21,149, 74,117, 25,192,228,252,252,252, +235,142,164,213,100, 50,129, 97, 24,107, 58,163,162,162,156, 15,212, 49,140,225,241,120, 61,195,195,195, 91,235,116, 58,249,131, + 7, 15, 46, 81, 20,245, 57,158, 95,140, 54, 55, 0,159,243,249,252,184,134, 13, 27, 6,103,100,100,100, 27, 12,134, 36, 84, 4, + 67, 86, 60, 15,145,213,185,115,231,179,107,214,172,241,154, 56,113,226,217,196,196,196, 14, 78,177,229,196, 63,133,224,224, 96, +119,181, 90,189, 9, 64, 11, 14,135,227, 47, 16, 8,224,226,226, 82,192,231,243,175,185,184,184,140, 62,119,238, 92,169,163,156, + 20, 69,125,158,153,153,233,223,166, 77,155,229,190,190,190, 95, 22, 23, 23,107, 13, 6,195, 9,185, 92, 62, 3,128,178,166,223, + 86,214, 34, 47,153,200,178,253,132, 69,116,177,205, 55,198, 0,232,242,132, 2, 99,179,131, 30, 61,122,228, 43, 16, 8, 64,211, +180,181, 49,171,188, 89,142,235,245,122,196,196,196, 24,106,105,112,130,179,179,179,125,121, 60,158,245,152, 94,175, 71, 96, 96, + 32,157,147,147,227,107, 14,123, 96,133, 78,167, 67, 80, 80,208,191, 41,230,209, 36, 79, 79, 79, 69, 86, 86,118,172, 86,103,152, + 63,118,202,167,179,135, 14,120,205,227,252,249,243,244, 27,111,188,161, 75, 72, 72,152,132,138,192,169,118, 85,230, 4, 65,108, +155, 57,115,230,151, 2,161,196,235,228,249, 84,221,182,221,135,114,155, 71,212, 39,102,204,152,193,154, 58,117,234,153, 22, 45, + 90,252, 76,211,116, 75, 56, 96,217,242,240,240, 56,194,231,243, 67,205,249,151, 37,151,203, 95,255, 23,190,144,108, 60,237, 60, +182,170, 99,181,162,164,164, 4, 26,141,230,169, 45, 42, 42,202,222, 88,153, 14,165,155,195,225,236, 95,178,100, 73, 96, 65,126, + 62,190, 89,185,178, 13, 42, 44,153,109,236,249,113, 81, 81,209, 83,233,140,140,140,132, 19, 14, 97,214,151, 95,126,185,228,221, +119,223, 5, 69, 81,208,104, 52, 1,119,239,222,141,158, 59,119,238, 59,247,238,221,107, 13,224,254,179,118,198,195,195,195,211, +166, 77,155,230,217,186,117,107,152,163, 84, 4, 36, 38, 38,182,217,188,121,243,123, 89, 89, 89,145, 0, 30, 63,203, 31,120,122, +122,254,252,195, 15, 63,120, 9,133, 66, 28, 56,112,192,171, 91,183,110,137, 87,175, 94,237,248, 12, 98,139,244,242,242,154, 10, +224, 85,154,166,121, 0,146,228,114,249, 66, 56,238,213, 93,234,234,234,186,135, 36,201,250,192, 95,222,232, 73,146,244, 38, 8, +162,216,114,140, 32, 8, 95,154,166, 47,200,100,178,118,206,215,241,229,134,151,151,215,152,194,194,194, 53,124, 62,159,235,225, +225, 1,161, 80, 8, 54,155, 13, 54,155, 93,143,207,231,215,227,243,249,189,186,118,237, 58,249,212,169, 83, 53,122,216,111,219, +220,111, 36, 72, 98, 62,139, 32, 89, 0, 64,114, 68, 18, 55, 55, 55,204,159, 63, 95,212,183,111, 95, 17, 0,156, 61,123,118,248, +136, 17, 35,186,229,228,228,196, 84, 39,182,170,210, 34, 47, 17, 54,214,212,224,193,172, 30, 19,158, 40,185, 36, 9, 30,143,135, +139, 23, 47,194, 30,103,229,150, 16, 9, 53,214, 6,102, 15,227,215,175,255,101, 0,176, 52, 52, 60, 30, 15,231,206, 61,233, 84, +190,109,219,182,214,194,254,119, 97, 64, 84,133,147,199, 93,239, 87,164,107,224,234, 10,239,218,187,222,143, 68,167,175, 31, 97, +192,212,121,131,203,181,134, 86, 0,212,165,114,185,252,242,222,189,121,205, 35, 34,184, 63,255,252,115,235,192,192,192, 1, 14, + 8,173, 89, 45, 91,182,220,195,114,113,243, 30, 62, 98,228,240,209,108,210,240,222,248,143, 22,101,231, 23,171,199,141, 27,183, +247,192,129, 3,195,151, 45, 91,118,251,227,143, 63,158, 5, 96,142,189,233, 23, 8, 4,161,119,238,220, 9,167, 40, 10, 81, 81, + 81,255,198, 48, 6,205, 81,225,124,239, 93, 0,191,154,143, 13, 65,133,231,254, 22, 0,174, 57, 66,102,177, 96, 85,181, 61,111, + 4, 6, 6, 70, 14, 27, 54,204, 91, 86, 92,140,111, 86,174,180, 28,126, 5,181, 12, 35, 90,202,143, 94,175, 71,255,254,253,135, + 81, 20,197,182,136, 64,157, 78,167, 87, 40, 20, 90,252, 53,177,244, 49,128,215,236, 72, 78, 3,145, 72,244, 21,128, 22, 26,141, + 38, 16, 0, 68, 34, 81, 46, 77,211,251,212,106,245, 28,252, 21,192,215,225, 14, 46,128,104, 84, 31, 10,138, 89,178,100, 73,198, +167,159,126,122,255, 31,224, 12,245,243,243, 91, 60,112,224, 64, 28, 58,116, 8,127,252,241,135,209,197,197,133, 61, 98,196, 8, + 98,242,228,201, 30,211,166, 77,235, 5,224,187,103,124,204,189,190,252,242, 75,207, 38, 77,154, 96,247,238,221,184,113,227,134, + 38, 60, 60,220,165, 75,151, 46, 96,179,217,158,179,103,207,126, 3,192,214,103,249, 3,153, 76,182,240,163,143, 62,218,246,235, +175,191,138, 31, 60,120,128,213,171, 87,123, 15, 30, 60, 56, 33, 43, 43,171,179, 3, 98,139, 15, 96, 42,128,174, 44, 22,171,227, +136, 17, 35, 76, 83,166, 76,225,144, 36,105, 92,185,114,165,207,230,205,155, 7,115, 56,156, 22, 37, 37, 37,246,116,210, 72, 0, +243, 71,143, 30, 61,234,212,169, 83, 30,151, 46, 93,226,121,121,121,129,162, 40,171,165,152,166,105, 95,203, 59,107, 50,153, 16, + 25, 25, 25,100,243,123,151,151, 85,104,144, 36,105,160,105,154, 3, 64, 0, 64, 87,219,254,127, 73,100,121,122,122, 78,148,201, +100,107,253,253,253,225,231,231,247, 84, 91,171,211,233, 32, 16, 8,184,254,254,254, 63,244,237,219,151,179,127,255,254,106,135, + 0, 9, 22,241,249,129, 29, 11, 2, 61, 61,196, 0,128,111,215, 31, 45, 7,128,223,127,255, 29,121,121,121,240,240,240, 64, 76, + 76, 12,107,193,130, 5,210, 25, 51,102,124, 35,151,203, 71, 87,199, 85, 89,139,188,100, 22,173,141, 85,237,215, 56, 71,139, 97, + 24,107,156, 60, 59, 95,218,202,135,142, 87,226, 35,244,122, 61, 42, 91,180, 44,133,151,195,225, 84, 54, 63,130, 32, 8,166, 38, +206, 42, 48, 66, 36, 18,197,170,213,234,239, 29,232,221, 90, 57,119,189, 31,137,109,252,153, 67, 44,145, 72,123,125, 84,241,185, + 13,192,249,135,163, 87,175,233,220, 57,112,234,103,171,230,105, 74,242,138,103, 15,123, 51, 52,220,223,203, 69, 84, 90,164,240, +108,220,184, 71, 37,139, 76,109,233,236, 52,124,248,240,237,127, 94,204, 36, 4, 2, 46,151,205, 98,113, 58, 52,141,240, 10,118, + 99,185,137, 1,183,236,251, 25,231, 71,142, 28,217,244,227,143, 63,238,232, 0, 39,204, 13, 46,126,250,233, 39, 16, 4, 65, 58, +114,239,207, 17,199,107, 18, 89, 12,195,128, 32,136, 95,108, 26,149, 95,204,199,174,218,136, 45,118, 77,249,105,177,166, 90, 68, +213,136, 17, 35,134,153, 76, 38,182, 77, 37, 81, 89,192, 84, 37, 98,236,186,119,169, 84,250, 39,128,215, 8,130,128, 94,171,213, +127,245,245,215,182,167,175, 84, 18, 89,199,171, 43, 75, 70,163, 17, 20, 69,177,175, 94,189,202,177,121,215, 57, 0, 68, 0,188, + 25,134, 1, 73,146, 55,237,200,207, 72,161, 80,120,254,224,193,131,146, 87, 94,121,133,224,241,120, 48,153, 76, 72, 73, 73, 9, + 94,182,108,217,248,227,199,143,191,161, 86,171,163,240,116,240,116,123,158, 81,116, 98, 98,162, 58, 44, 44,172, 74,225,168, 84, + 42,217, 17, 17, 17,157,171, 17, 69, 47,154, 51,167,176,176,240,237,215, 94,123,109, 66, 65, 65, 65,154,201,100,250, 4, 64,140, +183,183,247,213,126,253,250,193,197,197,165,171, 70,163,249,238, 89,222,121, 95, 95,223,190,237,218,181,195,234,213,171,177,108, +217,178,238, 0, 78, 0,232,166, 84, 42,143,191,245,214, 91,112,119,119,127,187,180,180,116,235, 51,148,163,136, 78,157, 58,253, + 48,127,254,124,241,161, 67,135, 16, 30, 30,142,178,178, 50,124,248,225,135,190, 95,124,241,197,233,210,210,210, 46, 54,229,162, + 58,206, 40, 62,159,191,245,215, 95,127,117, 13, 11, 11, 11,227,114,185,100, 88, 88, 24,100, 50, 25,180, 90, 45,127,209,162, 69, + 77, 93, 92, 92,174,127,247,221,119, 91, 1,244,171, 37,157, 36,128,133, 27, 54,108,152, 48,110,220, 56,247, 97,195,134, 81,122, +189, 30, 59,119,238, 4,139,197, 2,135,195,129, 80, 40,180, 6,175,230,114,185,104,220,248, 41, 39,233, 7,106,184, 95, 5, 42, +230,161,186,195,177, 97,215,227, 53,240, 89,135, 62, 56, 28, 14, 4, 2, 1, 4, 2, 1,248,124, 62,238,220,185,243,153, 64, 32, + 88, 73, 16,132,201, 30, 78,226, 47,117, 17, 11,224, 82,109,251,120,122,106,200,223, 89,127, 90, 16, 68, 16,196,183, 0,186, 86, + 52,187,100,130,183,183,247, 7,133,133,133,143,236,229,148, 74,165, 94, 37, 37, 37,223, 73,165, 82,248,249,249, 89,219,239,192, +192, 64, 24,141, 70, 20, 22, 22,130, 97, 24,148,150,150, 66, 40, 20, 34, 32, 32,224,187,113,227,198,237,222,184,113, 99, 73,149, +156, 52,150,189, 53,120,238,231, 44, 22,139, 4, 0, 22,219,213,117,218,167, 64,104,104, 40, 58,116,232, 0,173, 86, 11,133, 66, +129,232,232,104, 54, 65, 16,195, 9,130,144, 48, 12,179, 14,192,201,255,160,161,176,218,201,240, 95, 86, 30, 23,181, 68,139,231, +114,185,118, 9, 45,243,245,181, 89, 80, 72,163,209, 8, 46,151,251,132, 69,130, 32, 8, 80, 20,245,196,113,139,208,170,139, 80, +159, 60,121, 50,253,195, 15, 63, 76,144,203,229,235, 81,199,161,132,225,195,135, 63, 53,223, 99,198,140, 25, 57, 69, 69, 69, 76, +255, 30,177,162,180,195,121,249, 13, 61, 92, 93,124,196,226,250, 2, 15, 79,247,146,146,146, 11,230,202,196, 94, 52,106,217,178, +165,203,182,189,137, 57, 99,167, 47, 89,240, 74,152,151,164, 89,144,183,135,191,155, 11,207,149, 36,212, 2,147, 49,199,211,211, + 51,220,209,116, 91,234, 5,161, 80, 8,146, 36,255, 77, 22, 45,182, 69,100,201,100, 50, 28, 58,116, 8,189,123,247,190,106, 17, + 33, 74,165, 18,249,249,249,144, 74,165, 87,205,150,143, 90,135, 17,105,154,134,193, 96,128,193, 96,176, 10, 24,155,119,200, 42, + 96, 44,215,178, 88,172,155,117, 76,251, 2, 15, 15,143, 78, 93,187,118,229,237,216,185,147,199, 48,140, 26, 21, 49,212, 84, 12, + 83, 77,128,236, 74, 48,153, 76, 86, 43, 27,135,195, 65, 86, 86,150,181,225,178,196,150, 20, 8, 4,246,153, 50,248,252,143,126, +251,237, 55, 73,235,214,173,137,146,146, 18,208, 52,109,173, 36,215,174, 93, 43, 24, 48, 96, 64, 96,114,114,242,108,157, 78,247, +101, 29,238,149,168, 78, 16, 1,128, 68, 34, 49,193, 62,143,217,181,114,154, 76, 38,162,125,251,246, 31, 23, 23, 23, 55,213,104, + 52,139,236,201, 70, 0, 7,114,114,114,108, 27,246,235,105,105,105,154, 65,131, 6,185,212,175, 95, 63, 46, 53, 53,245,153, 94, +210,136,136,136,182, 28, 14, 7, 73, 73, 73, 58, 0,150,158,117,194,141, 27, 55,116,253,250,245,227, 7, 7, 7,183, 45, 45,181, +123,202, 74, 68,100,100,228, 49, 95, 95, 95, 23, 75, 29,234,227,227,195,217,184,113,163, 56, 55, 55, 23, 6,131, 1,179,102,205, + 66,159, 62,125,224,237,237,141, 25, 51,102,248, 45, 95,190,252,103,149, 74,213,178, 38,163, 53,143,199,219,126,247,238,221,112, +169, 84,234,114,241,226, 69, 52,107,214, 12,197,197,197, 40, 40, 40,128, 74,165, 66, 65, 65, 1, 70,143, 30,237,251,205, 55,223, + 4,216, 97,201,178,138,172,141, 27, 55,150,238,217,179,135,181,105,211, 38, 49,135,195,177, 10, 45, 54,155,109, 21, 90,150,216, +138,117, 24,105, 40, 53,139, 54,119,133, 66,241, 44,243,220,248, 0,120,182, 34,139,207,231,131,207,231, 67, 32, 16, 60, 83, 92, +214,151, 4,129, 4, 65,164,114,185, 92,190, 80, 40,228,146, 36, 9, 62,159,223,195,211,211,243, 86, 76, 76, 76,204,177, 99,199, + 50,237, 33,209,106,181,219,249,124, 62,199,215,215, 23, 0, 16, 30, 30,142,102,205,154, 65,173, 86,211, 10,133, 2,238,238,238, +228,163, 71,143,160,209,104,144,159,159,143,144,144, 16, 14, 73,146,219, 81, 49, 15,249, 41,156,191, 90,176, 30,192,122,203,190, +183,183,119,161,173,165, 83, 32, 16, 32, 48, 48, 16,185,185,185, 16,139,197,172, 47,190,248,162,223,206,157, 59,223, 57,127,254, +252,112, 0, 63,217, 80,125,249, 18,207,209,178,136, 44,219,207,191,132, 86,159, 62,125,230,197,199,199,119,174,170, 23,206,225, +112,158,219, 92, 23,139,160,146, 72, 36,149,173, 86,160,105,186, 58,139,150,195,255, 35, 16, 8, 92, 38, 78,156, 88,182,110,221, + 58,135,197,214,192,213,105, 86, 43,214, 83,221,200,168,168,243,179,103,207,238,123,234,212,169,220, 87,194,234,179, 69,121,143, + 84, 2,137,187, 59,130,234,245, 30,241,118,191, 27,168, 88,125,104, 47,238,150,149,149,185, 52, 12, 18,234, 73, 82, 75,212,227, +179,197, 82, 17,151,239,239,225, 17,200,213,235,138, 36, 30, 30, 60,157, 78, 87,138, 26,130, 64, 3,128,159,159,223, 81, 23, 23, +151, 16,203,190,135,135,135, 27,195, 48, 16, 10,133,144, 74,165,174, 44, 22, 43,221,166,112, 61, 42, 44, 44,236, 81, 91,194,220, +221,221,143,242,249,252, 16,146, 36, 65, 16, 4, 88, 44, 22, 72,146, 4, 73,146,214,239, 44, 22, 11, 4, 65,160,188,188,252, 81, +102,102,102, 15, 59,238,215, 4,160, 5, 65, 16, 87, 15, 29, 58,132,184,184, 56, 28, 62,124, 24, 61,123,246,132, 66,161, 64, 74, + 74, 10, 58,117,234, 4, 84, 12, 41,218, 5,219,201,239,150, 78,193,157, 59,119,172,194,197,118, 19,139,197,207, 98, 98, 63, 59, +112,224, 64,252,240,195, 15,140,185, 51, 33, 34, 8,162,153,155,155,219,157,219,183,111,219, 53, 15,134, 97, 24, 24, 12,127, 93, +106,105,188,204,243, 33, 28, 10, 14,204, 98,177,122,180,108,217,146, 80, 40, 20, 22, 1, 9, 54,155, 13, 22,139, 5, 22,139,133, + 53,107,214,184,180,110,221,122, 46,159,207,255,152,203,229, 42,141, 70,227, 14,173, 86,187, 8, 64,233,191,169, 70,234,216,177, +227,244,236,236,236, 62, 33, 33, 33, 7,159,129,134, 49, 26,141,122, 0, 46, 44, 22,139,243, 28,234, 40,150,249,221,210,218,136, +125,147,121,159,143,138, 97, 98,187,224,237,237,253,243, 31,127,252, 17, 20, 18, 18, 2,163,209, 8,147,201, 4,149, 74,133,132, +132, 4,232,116, 58,152, 76, 38,132,135,135,227,243,207, 63,215,126,240,193, 7,130, 13, 27, 54, 20,169, 84,170,161,181,208,126, +176,123,247,110,145, 84, 42,117,209,104, 52,184,127,255, 62, 90,182,108,137,178,178, 50,168,213,106,148,151,151,195, 96, 48, 64, +169, 84,186, 83, 20,165,175,133,235, 51, 91,145, 53,126,252,248,155, 60, 30,175,229,148, 41, 83,144,147,147, 99, 45,243, 99,199, +142,133,159,159,159,181, 44,153,235,100,135, 42,102, 54,155, 13, 62,159, 15, 46,151, 91, 90,175, 94, 61, 16, 4, 33,120,244,232, + 81, 93,134,226, 36, 0,148, 28, 14,135,103, 43,176,248,124, 62,146,146,146,102,243,120,188,234,172, 89,213,149, 75,198,145,253, +127, 26, 4, 65,124,203,229,114,249,158,158,158, 92,155, 14, 39,215,213,213, 21,190,190,190,171, 1,244,178,243,190,155,123,122, +122, 90,235,247,216,216, 88,100,103,103,239, 83, 40, 20,239, 21, 21, 21,129, 36,201,237, 36, 73,190, 99,233,164,202,229,114, 4, + 7, 7, 55,175,142,175, 93, 11,255, 9, 32,152, 39, 44, 90,149, 58,104,144, 72, 36,120,248,240, 33,212,106, 53,147,145,145, 65, + 76,156, 56,145,208,235,245, 63, 38, 39, 39, 95, 64,197,106,251,106,181,200, 75, 2,199,231,104, 89, 44, 90,246, 54, 0, 4, 65, +212,218,155, 48, 26,141,174,209,209,209, 85, 77,248, 34,170, 18, 90,230,225,164, 58,189,232, 28, 14, 71, 92, 87,177, 85, 25, 7, +247,252,234,183,236,243, 89,159,123, 6,212,111,248,241,199,159,177,223,124,243,205,139,219,182,109,163, 60,155,244,234,118,242, +232, 79,126,223,125, 56,243,240, 31,127,252, 1, 84, 76,140,182, 23,103,227,227,227,253,103, 76,157,140,207, 63,250,224,136, 36, +220,155,231, 74,120,138, 4, 58,245, 99, 87, 48, 26,126,163,200, 62,123, 15, 30,204, 7,144, 92, 19,137, 80, 40, 12, 73, 77, 77, + 13,183, 93, 72,160,215,235, 33, 20, 10,113,242,228, 73, 31, 23, 23, 23, 31, 0,208,104, 52,136,137,137,177,215, 98, 18,146,158, +158, 30, 46, 22,139, 81, 94, 94, 14,157, 78, 7,163,209, 8,154,166, 65, 16, 4, 56, 28, 14,120, 60, 30, 68, 34,145,163, 43,251, +174, 1,120,183,119,239,222,191, 28, 62,124, 24,209,209,209,144,203,229, 72, 75, 75,179,136, 44,135,230,104, 89,172, 68,182,243, +177,216,108, 54,126, 14, 11,195,216,188, 60,171,128,249,214,205, 13,159,211,117,139,166, 17, 19, 19,195,156, 61,123, 22, 71,142, + 28,193, 91,111,189, 69,236,223,191,223, 64, 81, 20, 55, 47, 47,239,102, 94, 94,158, 93, 28, 52, 77, 91,211,106,169,183,109, 5, +150,163, 66,203,100, 50,137,121, 60, 30,180, 90, 45, 44,150, 7,219,173, 65,131, 6,144,201,100,108,165, 82,201,206,203,203, 19, + 46, 92,184,112,202,233,211,167,165,101,101,101, 67,254,201, 90,104,221,186,117, 33, 99,199,142,205, 98,179,217, 76,207,158, 61, +135, 61,122,244,232,109,169, 84,122,226,212,169, 83, 95, 3,136,112,148,207,219,219,251, 10,155,205, 14, 82, 42,149,220, 93,187, +118, 25,203,202,202,184, 62, 62, 62,133,150,186,195,146,215, 70,163,209,174,149,203,222,222,222, 87,138,139,139,185,223,127,255, +189,177,164,164,132,235,231,231, 87,104,225, 41, 45, 45,229,238,218,181,203,168, 84, 42,185,110,110,110, 87, 20, 10, 69,173,124, +197,197,197, 67,135, 15, 31,158,120,226,196, 9,111, 22,139,133, 71,143, 30,161,164,164, 4,238,238,238,216,190,125, 59, 66, 66, + 66,176,123,247,110,153, 76, 38, 27,243,213, 87, 95,205, 53,139,172,218,230,104,117,138,139,139, 11, 41, 45, 45,133,187,187, 59, +212,106, 53,174, 92,185,130,168,168, 40,228,229,229,129, 36, 73,184,187,187, 99,237,218,181,229, 4, 65,200,106, 34,114,113,113, +121,123,220,184,113,238, 0, 48,110,220, 56,247,113,227,198, 85,217,192,181,109,219, 22,171, 87,175,174, 44,180, 28,233, 24, 88, +173, 78, 54,226, 72,219,166, 77, 27,156, 62,125,122,166,131,226, 72,111, 17,109,149,173, 89,124, 62,223,225,197, 52, 52, 77,115, + 81, 49,165,129,176,103,255, 95,128,206, 46, 46, 46,220,202, 7,203,203,203,185, 82,169,180,163, 3,194,215,203,197,165,194,224, + 20, 18, 18, 2,133, 66, 65,233,245,250,193, 63,253,244,147, 17, 0, 90,180,104, 49,152,162, 40,173,201,100, 98,241,120, 60,168, +213,106,248,250,250,122,213, 96, 27,253,228,192,142,133,254,149,231,104, 73,165, 82,180,104,209, 2, 58,157, 14,249,249,249, 72, + 72, 72, 48, 82, 20,245,203,186,117,235,104, 31, 31,159, 81,253,251,247,103, 37, 39, 39,191, 15, 96,122,117, 90,228, 37,179,102, +109,172, 86,104,153, 21,228,105, 0, 93, 42,223,100,101,241, 83,147,208,170,109,232,144,199,227,149,102,101,101,137,108, 27, 21, +147,201,132,128,128, 0,154, 97, 24,162, 42,161,245, 44,166, 96, 14,135, 35,254,244,211, 79, 75,215,173, 91, 55,244,225,195,135, +243,236,249,205,174,247, 35,177,173,146,200, 90,191,108,254,234,239,151, 45,244,188,119,228, 71,108, 90,181,130,162, 40, 36, 55, +109,218,180,163, 74,165, 98,187,137,140, 40, 46,197, 97,179,200,178, 87, 20,146, 0,182, 92,186,116, 41,185, 87,175, 94,231,182, +252,182,215, 51,239,254,253, 11,124,101,113,190,164, 81, 56,155, 27, 24,242, 78,153, 86,203, 29, 60,120,176, 15,128,254,181, 85, + 98,165,165,165, 40, 40, 40,168, 44,192,112,231,206,157,167,174,181, 43,113, 36, 9,138,162,176,103,207, 30, 8,133, 66,136, 68, +162, 39, 54,139,200,170,227, 66,133,116, 0,232,217,179, 39,100, 50, 25, 92, 93, 93,237, 78, 87,101,241,194, 48, 12,244,122, 61, +244,122, 61, 12, 6, 3, 5,128,195,102,179, 49, 58, 39,199,106,229,113, 68,192, 84, 70,211,166, 77,153,243,231,207,227,220,185, +115, 80,171,213,248,254,251,239, 33,149, 74, 95, 5,240,153,163, 92, 54,147,244, 41,165, 82,201, 81, 42,149, 86,235, 32,135,195, +177, 90, 15,236,180,228,113,217,108,182,181, 55,106,217,108,173, 90, 44, 22, 11,126,126,126,240,247,247,199,250,245,235,185,245, +235,215,239,243, 79,214, 64,203,151, 47,111,244,237,183,223,110,222,182,109,219,225,161, 67,135,238, 76, 73, 73, 25,233,230,230, +118,243,228,201,147, 11,249,124, 62, 93,199,242, 29,148,151,151,231,107,123,136,166,105,161,201,100,178, 10,219,242,242,114,187, + 59, 24, 28, 14, 39, 40, 53, 53, 85, 8, 0, 11, 23, 46,228, 0, 16, 90, 38,131, 91, 56,203,203,203, 57, 81, 81, 81, 65,246,190, +235,137,137,137, 29,187,119,239,126,254,216,177, 99, 30, 33, 33, 33,200,205,205, 69,110,110, 46, 26, 53,106,132,197,139, 23,171, +149, 74,101,123, 0,233, 42,149,106,191,157,156, 1, 30, 30, 30,156,172,172, 44,152, 76, 38, 52,111,222, 28,107,215,174,197,224, +193,131, 17, 19, 19, 3,165, 82,137,212,212, 84,108,221,186,213,131,203,229,214, 88,119,104, 52,154,253, 27, 55,110, 12,174,108, +209, 26, 54,108,152,168,176,176,208,250, 78,206,159, 63,255,137, 33, 68, 71,234,100,243,208, 86,181, 91, 93, 96, 50,153, 36, 2, +129, 64,201,231,243,121,150,249, 89, 9, 9, 9, 14, 91,179, 42,117, 0, 29,217,255,199, 96, 17,173, 85,180,173,240,247,247,183, +155,135,207,231, 19,150,186,209,100, 50, 65,161, 80, 80, 82,169,212, 58,188,127,245,234, 85, 42, 52, 52,148, 98,177, 88, 44, 30, +143, 7,130, 32, 32, 20, 10,171,173,240, 25,138,153,255,230,224,207,158, 88,117, 56,237, 83,192, 96, 48,224,234,213,171, 48, 24, + 12, 72, 72, 72, 48,126,245,213, 87,121,165,165,165,211, 0,176,143, 30, 61, 58,124,230,204,153, 44, 95, 95,223,238, 69, 69, 69, +168, 77,139,188, 68, 98,235, 41, 43,151,165, 21, 58,221,167, 79, 31,194,188,180,146,176, 8, 39, 71,132,150,185,240,213,218,242, + 18, 4,129,252,252,124,235,190,175,175,175,195,255,101, 47,188,188,188,212,109,219,182, 21, 23, 23, 23,239, 95,190,124,121,157, + 44, 89,235,151,205, 95,189,100,193, 23,158,178,219, 23,145,147,151, 15, 89,145, 49,249,236,205,135,251, 0,236, 3, 0,108,104, +114,154,152,144,182,198, 94,206, 72,111,151, 88, 14,151,189,239,181, 94,125,130, 7,141,155, 78, 78,154, 52,169,195,240,225,195, + 21, 67,135, 14,157,234,234,234, 26, 97, 48, 24,228,123, 15, 29,202, 28, 52,104, 80,125,138,162,134,163, 22,159, 35, 26,141,230, + 81,151, 46, 93,108,243, 83,114,252,248,113,191,204,204, 76, 76,158, 60,249,113,110,110,110,169,237,181,246,164,209, 96, 48, 60, +138,141,141,173,118,184,208, 50,164, 8, 0,101,101,101,143, 28,200,210, 33, 48, 79,124, 47, 41, 41,193,157, 59,119,192,102,179, +209,166, 77, 27,156, 61,123, 22, 29, 58,116,184,234,136, 85, 75,171,213, 34, 36, 36, 4, 90,173, 22,106,181,186, 28, 0,127,123, +253,250, 0,128,247, 75, 74,112,229,171,175,112,113,201, 18,216,190,207,246,162, 89,179,102,204,197,139, 23,113,243,230, 77,232, +116, 58,140, 25, 51, 6, 0, 8,243,187,235,136,203,140, 48, 22,139,213,179, 87,175, 94, 1, 0,160, 86,171,137, 75,151, 46, 65, + 32, 16, 88,203,194,193,131, 7,145,155,155, 11,130, 32,224,225,225, 17, 36,151,203,235, 3,120, 88,131,217,159,120,248,240, 33, +150, 46, 93, 10,154,166, 49,115,230, 76,132,135,135, 91, 5,214,163, 71,143,176,112,225, 66, 80, 20,133, 47,190,248, 2,141, 26, + 53,130,209,104, 20,160,142, 46, 52,158, 7,102,204,152,113,111,223,190,125,135,179,179,179,223, 88,182,108, 89,103,130, 32,232, +143, 63,254,120,169, 68, 34,161,158,133, 87,174, 40,195,157,187,143,172, 66,168,242,230,227,237,233, 48, 95,198,253,108,235,239, + 41,202,150,143,130,151,167,135,163, 73, 44, 55, 26,141,234,119,222,121,199,125,207,158, 61, 68,163, 70,141,240,224,193, 3,139, +101,168, 28,142,187,116,200,149,201,100,225, 44, 22,139,123,247,238, 93,132,134,134, 34, 46, 46, 14,139, 22, 45, 66,113,113, 49, + 76, 38, 19,124,125,125,105,163,209,120,213, 96, 48,156,169,133,107,254,248,241,227,185, 0, 38,152, 45, 91, 77,167, 77,155, 70, +175, 88,177, 2, 87,175, 94,181, 90,176,108, 39,195, 59, 58,116,104,107,117,178,221, 18, 18, 18,102,242,120, 60, 6, 64, 18, 28, +119,244,172,175,108,209,170,139, 53,235, 69,225, 69,174,100,148, 74,165, 9, 98,177,184,143, 92, 46,127,194,170,213,190,125,123, +131,159,159, 95,162,189, 60,174,174,174,114, 22,139,229, 5, 0,185,185,185, 16,137, 68,220,251,247,239, 47, 65,133,243,108,212, +175, 95,127,137, 76, 38,227,214, 55,215,167,254,254,254,208,235,245,213, 78, 99,185,112,173,240, 71, 0, 63, 90,246, 61, 61, 61, +243, 21, 10,133,203,138, 21, 43, 84, 75,150, 44,209, 80, 20,165, 3,112,178,180,180,212,234, 71,171,160,160, 64,193,225,112, 60, +221,221,221, 3, 45, 66,171, 42, 45,242,146,161,122,139,150, 89, 73, 50,149, 5, 17, 65, 16, 79, 77, 80,175, 69,104,213, 42,178, + 40,138,122,194,202, 96,153,240, 94,213,127,153, 27,245, 58, 13, 29,154, 69,150, 96,239,222,189,219,151, 47, 95,158,100,239,239, +108,231,104,109,248,122,193, 50,139,200,186,113,238, 24,246,167, 41,138,103, 46, 89,249,109, 93,159, 64, 19,111, 97, 51, 63, 63, +175,211, 95, 45,158, 47,185,119,100, 43,118,110,248,134,185,113,249,114,235,203,151, 47,191, 55,121,242,228,122,230, 23, 75, 6, +224, 58,128, 65,176, 99,149, 78,110,110,110,143, 74,141,112, 58,151,203,245, 19, 10,133,200,205,205, 85,101,100,100, 56, 60, 36, + 83, 92, 92,220,227, 5,188,128,108,139,200, 42, 46, 46, 70,106,106, 42,186,118,237, 10, 0, 56,123,246, 44,218,183,111,143,228, +228,100,180,108,217,242, 42,128, 86,168,197, 81,171,209,104, 44,109,210,164,137,213,186,165, 80, 40,104, 0, 24,151,159,143,141, + 82, 41,216,108, 54, 46, 46, 89,130, 57, 70, 35, 22, 57, 40,224, 99, 99, 99,153, 75,151, 46, 33, 51, 51, 19, 38,147, 9,125,251, +246, 69, 29, 11,125, 76,100,100,228,241,147, 39, 79,250,184,186,186, 66,173, 86, 67,165, 82, 97,196,136, 17, 24, 60,120, 48,116, + 58, 29,118,237,218,133, 3, 7, 14, 64, 44, 22, 67,173, 86, 67,173, 86,123,244,238,221,251,124,122,122,122, 39, 0,119,171, 17, + 90, 76,143, 30, 61,144,152,152, 8, 22,139,133,214,173, 91,163,164,228,175,197, 64,126,126,126, 85,157, 99,253,147, 66,139,205, +102, 51, 9, 9, 9,203, 58,119,238,140,236,236,236, 55, 90,182,108,249,253,200,145, 35,115,159,149,215,195, 77,140,216,168, 48, +232,116, 58,232,116, 58, 4, 4, 4,160,172,172, 12,247,238,221,131, 78,167,131,159,175,187,195,124, 45, 98, 26, 89,249,124,125, +125,161, 86,171,241,240,225, 67,232,245,122,120,123, 59, 36,180,130,123,244,232,113,234,151, 95,126,241,218,186,117,171,190, 75, +151, 46,188,239,191,255,158,144, 72, 36,176,105, 88, 28, 69,194,217,179,103, 67,186,119,239,222,248,246,237,219, 72, 72, 72,128, + 94,175, 71,139, 22, 45,144,145,145,129,182,109,219, 66,165, 82, 37, 93,190,124,249,128, 61,134, 97, 0,115,199,143, 31, 15,139, +216, 74, 76, 76, 68,126,126, 62,196, 98,241, 83, 66,203, 50,247,209,188,106, 60,192,158,196, 90, 4,145,141,229,105,142,187,187, +187, 1,192,183,117,180, 62, 1, 0,178,179,179,249, 77,155, 54,213, 9, 4, 2,158, 89,180,173,124, 22,190,231,137,231,176,146, +177, 90,248,251,251, 79,243,246,246,238,222,160, 65, 3, 20, 22, 22,114,121, 60, 30,218,183,111,111,104,213,170,149,193,223,223, +255,125,123,121,248,124,254,109, 46,151,219,169,162, 51, 65, 33, 43, 43, 11, 66,200, 69,216, 0, 0, 32, 0, 73, 68, 65, 84, 12, +195,204,140,137,137,249,160,172,172, 12, 37, 37, 37, 60,137, 68, 98,237, 84, 55,110,220, 24, 58,157,238,182, 3,150,183,249,161, +161,161,115,185, 92,238,162,226,226,226,170,220, 66,240,220,221,221, 37, 92, 46, 23, 6,131,225, 9,177, 89, 89,139,188,236, 34, +235, 9,161,101,163, 34,159, 16, 58,142, 88,180,236,177, 26, 88, 38,216,219,238, 91, 68, 93,229,255,170,171, 15, 45, 55, 55, 55, +157, 69,100, 45, 90,180, 40,169, 46, 28,187,127,249, 73,234, 70,151, 7,231, 37,253,129,244,155,201,216,151, 90, 90, 60,115,201, +202,169,111,246, 31, 82, 88, 89,152,217,131,112, 31, 97,140,159,175,215,233,175,151, 47,145,200,110, 95, 68,126, 65, 1,254, 72, +186,156,108, 0, 82, 1,204,124,158,166,101,160, 98,232,144,197, 98,253,155, 94, 88,235,100,248,252,252,124,139,200,106, 1, 0, + 29, 58,116,184,106, 22, 89,176,215,162, 85, 90, 90, 90, 57,100, 77,119, 0,222,150,251,103,179,217,104, 63,119,174,195, 34, 11, + 0,147,156,156, 12,153, 76,102,233, 41,214, 85,100,193,223,223,255,163,147, 39, 79,250,108,217,178, 69,185,109,219,182, 18,154, +166, 57,177,177,177, 65,175,188,242, 10,177,125,251,118, 0,192,160, 65,131, 48,115,230, 76,220,186,117, 11, 34,145, 8, 29, 58, +116,160,230,205,155,231, 59,109,218,180,247, 11, 11, 11,167, 86,217, 58,210, 52, 87, 32, 16,156, 0,240,234,237,219,183, 1,224, + 60, 42, 66, 56, 89,172, 8,213,158,179,167,241, 45, 43, 43,227,136,197,226, 42, 93, 67,112, 43,122, 67,142, 90, 32,172,156,231, +206,157, 91,250,245,215, 95,239,251,240,195, 15,239, 62, 35,103,149, 22,173, 62,125,250, 64,163, 51, 32,167, 80, 1,138, 50, 65, + 99, 40,114,152,207,214,162,213,167, 79, 31,148,107,245,200,202,151,193,100,162, 80,166,177,187, 45, 23,190,246,218,107, 71,119, +236,216,225,127,225,194, 5, 80, 20, 69,103,100,100, 60,124,231,157,119, 36, 31,127,252,177,215, 51, 44, 50, 90, 53,100,200,144, + 1,231,206,157,147, 53,110,220,216, 51, 41, 41, 9, 69, 69, 69, 48,153, 76,120,245,213, 87,193,227,241,178,150, 44, 89,194, 5, +176,202,222,103, 99, 22, 91,134,203,151, 47,143,189,120,241,162,167,167,167, 39,143,142,140, 68,254,177, 99,216,179,103,207, 83, + 63,216,176, 97, 3, 96,167, 23,126,139,197,233,210,165, 75,207, 69, 96, 61,209, 82,243,120,117, 30,126,124, 89,113,233,210,165, +220, 73,147, 38, 69, 73, 36,146,111, 59,118,236,216,213,203,203,139,244,240,240, 72, 8, 12, 12,252, 32, 54, 54,214,238,209, 5, + 14,135, 51, 82, 36, 18,221, 51,153, 76, 44,149, 74, 5,181, 90, 93, 81, 73,155, 76, 60,146, 36, 81,191,126,125,107, 91,210,186, +117,107,248,251,251, 83,105,105,105, 35,237,229,127,252,248,241, 19,171, 16,171,192,248,246,237,219,179,117, 58, 29, 50, 51, 51, +207,218,158,168, 74,139,188, 36, 24, 87,163,248,178,220,148,237,205, 5, 6, 6,102, 27,141, 70, 38, 21, 96,174, 95,191,206,140, + 27, 55,174,198, 77,171,213, 50,190,190,190,249, 85, 52,126,176,229,212,233,116, 79,252, 78,167,211, 49,126,126,126,148, 70,163, +121,138, 83,163,209, 48, 65, 65, 65,185, 53,113, 86,129, 17,215,174, 93, 91, 55,103,206,156, 56, 7, 50,200,202,201,172,143,100, +182,110,221,250, 63,134, 97, 58,119,140, 10,185, 57, 48,214,143,105, 31,238,155,119, 96,247, 47,131, 25,134,233, 92,121,179, 56, + 56,173,137, 51,210, 79,212,164, 91,116, 61,249,141, 35,191, 50, 39, 87, 76, 97,190,238, 27,206,180, 12, 18,151, 70,122,187, 56, + 26, 35,166,214,104,233,209,209,209,233, 52, 77, 51,122,189,158,137,142,142,206,120, 30,156,117, 64, 77,156,205, 81, 49,151,109, + 72, 21,199,154, 63, 67, 58,111, 48, 12,195,200,100, 50, 70,165, 82, 49, 58,157,142,161, 40,138,177, 5,128, 27,118,112, 50, 6, +131,129,145,203,229, 12,236,159,115, 87, 37,167, 84, 42,125,120,255,254,125,166, 97,195,134,217,102,115,252, 52,181, 90,205, 84, +134, 90,173,102,186,118,237,202,100,100,100, 48,161,161,161,218,140,140, 12, 70, 42,149,222,169, 37,157, 13,130,131,131, 79,120, +123,123, 39, 0, 8,119,224, 92,141,249,185,107,215,174, 48,134, 97,198, 48, 12, 51,174,154,109, 12,195, 48,145,255, 52,167, 57, +127, 11, 25,134, 97,202,203,203, 25,153, 76,198,228,229,229, 49,229,229,229,140, 74,165, 98,174, 93,187,198, 92,184,112,129,185, +121,243, 38,227,233,233, 89,104, 15,167,133, 79,175,215, 51, 74,165,146, 41, 42, 42, 98, 52, 26, 13,163, 86,171,153,148,148, 20, +230,202,149, 43,204,237,219,183,171,226,123,138,211,203,203,107, 67, 65, 65,129,234,252,249,243,229,235,215,175, 47,247,247,247, +191, 13, 32, 4, 64,132,135,135, 71,193,148, 41, 83, 24, 87, 87,215, 71,117, 44, 71, 81, 28, 14,231,218,178,101,203, 46,197,199, +199, 23, 30, 56,112, 64,191,121,243,230,156,201,147, 39,159, 97,179,217,215, 0, 68,213,177, 28,249,186,187,187,159, 79, 74, 74, + 50,201,229,114,166,180,180,148, 81, 42,149,140, 90,173,102, 52, 26, 13,163,215,235, 25,163,209,200,156, 57,115,134,241,243,243, +179, 29,150,252,164,134,142,245,116,134, 97, 62, 98, 24,134,253,188,235, 58, 27,238,142,207,139,243,121,212,117, 36, 73, 26,204, +117, 71,155,138,221,154,247,255,169,116,118,235,214,237,139,193,131, 7, 51, 61,123,246,100, 90,180,104,241,212,214,178,101, 75, +102,226,196,137, 76,124,124, 60,243,213, 87, 95,125,241, 28,210,201, 70,197,162,151,197,221,186,117, 51, 38, 38, 38, 50,131, 6, + 13, 98, 0,244,168, 73,139,252, 23, 4,151,197,189, 3, 97,251, 9, 0, 6,131, 33, 59, 61, 61, 93,218,216,100, 98, 1,192,154, + 53,107,158,178, 76,217, 34, 49, 49,209, 68, 16,196,189,154,254,221, 96, 48,100,159, 60,121,210,111,245,234,213, 28, 27, 19, 48, + 76, 38, 19,157,151,151, 71,126,255,253,247, 79, 92,127,250,244,105,147,201,100,202,114,240, 38,183, 54,111,222,124,235,243,200, +173, 51,183, 50, 63, 56,250,199,239,222,109,226, 58,150, 74, 60, 61,171,236,133,237,122, 63, 18,196,132,154,173, 90, 4,155, 92, +180,108,241,124,119,203, 16,228,111, 87, 11, 74,181, 58,170,107, 90,177,230,198,243,126,194, 42,149, 42,211,178, 18, 80,173, 86, +103,253, 11, 95,194,107,168,240,113,101,170,116,172, 21,158,113,210, 41, 77,211,112,115,115,179, 90, 67,235, 96, 17,101, 44, 22, + 86,203,163,123,150,244, 48, 12,115, 46, 37, 37, 37,116,196,136, 17,226,109,219,182,221,167, 40,138, 51,122,244,104,131,191,191, + 63,247,236,217,179, 70, 0, 68,231,206,157,217, 5, 5, 5, 76,110,110,174,236,173,183,222, 42, 27, 59,118,172,215,245,235,215, +121, 52, 77,215,230,180,240, 65,118,118,118,183, 58,156,171, 17, 3, 7, 14,188,143,103, 15, 99,243,194, 57, 45,144,149, 42,113, + 63, 51,215,236,193,156, 6,245,168,208, 58,175,202,104, 52, 65,166, 44,113,216,162,117,239, 97,174, 57,196, 24, 5,138,202, 51, +243, 85, 76,136,103,228,229,181,183, 38,108,118,135,121,243,230,245, 34, 73,146,188,120,241,162,110,249,242,229,217,143, 31, 63, +238, 11, 32, 11, 0,228,114,121,151,173, 91,183,254,108,135, 43,135,234,144,106, 52, 26,219,126,242,201, 39, 83, 1,116, 0, 80, +207,204,125,214,108,201,170,171, 7,243,162,210,210,210,215,123,245,234,117,140,197, 98,213,183, 41, 71,222, 0,138, 45,229,130, + 97, 24,223,194,194,194, 55,236, 33, 36, 8, 98,229,139,170, 72, 94, 36,247, 51,214, 67, 47,197, 74,198, 19, 39, 78,124,217,183, +111, 95,118, 72, 72,200,236,144,144, 16, 82, 46,151, 67,165, 82,129, 36, 73,248,251,251, 35, 58, 58, 26,254,254,254,244,237,219, +183, 23,207,154, 53,171, 86,159,124, 77,154, 52, 9, 51, 26,141, 13, 73,146, 12, 3, 16,198, 48, 76, 24, 65, 16, 97, 0, 60, 1, + 64, 34,145, 72, 66, 67, 67,217,109,218,180, 65, 92, 92, 28, 78,159, 62,141,221,187,119,255, 8,224,168,173, 53,171,178, 22,249, + 55, 32,181, 57,152,168,107, 32,110,181, 68,103,130,198,105,134, 68,151,232,100,171,159,189,202, 34,171,250,160,210, 85,152,254, +122,188,250,234,171,214, 2,103, 71,163,146, 89, 91,225,123,252,248,113,143,145, 35, 71, 62,193, 73, 81,148,174,164,164,100, 82, +187,118,237,214,178, 88, 44,126,165, 23,246, 81, 81, 81,209,223, 26,171,175,178, 31,173, 30,189,222, 46,126, 86, 78, 87, 46,217, + 48,253,208, 15, 40, 44, 42,198,111, 87, 11,228,101,122,170, 75, 70,113,121,202,139, 72,255,163, 71,143,122,190, 4,138,191, 42, +209,250,172,193,179, 31,219,225,144,180,182, 24,117,132,217,157,200,115, 41,228, 5, 5, 5, 43,230,206,157,251,250,226,197,139, +125, 14, 31, 62, 44,177,116, 80,250,245,235, 87,148,146,146,210, 17, 0, 95,171,213, 30, 95,188,120,177,207,252,249,243,189, 0, +120, 1, 64,239,222,189, 11, 11, 11, 11, 87,195,137, 26, 97, 52, 26,115,162,155, 52,182,118,252,108, 93, 58,216,126, 55,153, 76, + 57,142,240, 85,197, 99,187, 79, 81, 84,141,124, 44, 22,235,195,184,184, 56,214,135, 31,126, 88,120,248,240, 97, 75, 32, 93, 91, +133,150, 94,139, 83, 82,123,160, 3,176,220,188, 61, 79,168,101, 50, 89, 91, 7,127, 67, 57,223,198, 42, 59,148,142,236,255, 35, +216,191,127,255,103,131, 6, 13,218,234,233,233,249, 83, 88, 88, 88, 99, 63, 63, 63,137,139,139, 11,116, 58, 93,153, 94,175,191, +147,158,158, 62,244,179,207, 62,123, 96,151,133, 99,235, 86, 22, 0, 46, 77,211, 2,146, 36, 69, 0, 36, 4, 65,120, 88,132, 22, + 65, 16, 48, 24, 12,200,204,204,196,156, 57,115,168, 19, 39, 78,124, 5,224, 11, 7, 58,174,173, 0,248,216,212,227, 62, 0,244, +168,112, 96,251,152, 32,136,203, 47, 58,191, 8, 26,167,163,174,129, 72,109,142,170,218,137,154,131, 74, 87, 87,224, 30, 63,126, +220,246,121, 23,226,234, 56, 31, 63,126, 28,242,111, 41, 33,195,117,203,127,197,134,229, 79,196, 57,180,136,176,170,246,107,131, + 66, 99,154,188,234,232,173, 21, 58, 19, 67, 27, 76,244,168,140,199,229,169,206,122,232,185,227,181,231, 85,150,158, 99,154, 82, +210,210,210,218, 77,158, 60,249, 51,161, 80,216, 26, 0,202,203,203, 47,230,229,229, 45,128,121, 85, 97,109,231,157,168, 30,197, +197,197,175,252, 27,249,244,122,253, 7,237,218,181,251,142,162,168,175, 77, 38,211,217,255, 7,143, 66,235,124, 27, 95, 94,236, +220,185,243, 1,128,182, 0, 48, 96,192, 0, 22, 0,236,222,189,219, 97,241, 60, 98,196, 8,138, 97, 24,131,249,125, 80,163, 98, +117,161,220, 82,167,170,213,106,121, 94, 94,222,109,138,162,110, 3,248, 25,142,175,184,245, 33, 8, 34,158, 97,152, 62,102,225, + 22,207, 48, 76, 31,219, 99, 47,218,170, 85,203, 37,181, 79,134,119,162, 2,187, 83, 65, 84, 30, 10,172,109,191, 54,164, 23,170, + 19, 0,180,116,230,238,255, 75,220,207,203,203, 27,254, 12,231,157,120,249,144,165,215,235,251,254, 63,186, 95,133,243,145,255, + 71,218,191, 58, 8, 44, 11,110,223,190,253,194,166, 8,252,211,136,186,246,100, 7,188,242,190, 13,198, 85, 37,188,156, 66,203, + 9, 39,156,112,194,137,103, 65,169, 51, 11,156,248, 47,195, 50, 55,203,178, 95,205, 28,173,202,243,179,172,251, 4,170, 95, 57, +224, 72, 84,242,186,172,146, 56,238,228,116,114, 58, 57,157,156, 78,206,127,156,211, 29, 64, 40,128,101,181, 92, 87,121,117, 97, + 33,128, 98, 0, 70,103,126, 58, 57,159, 65, 63,216, 5,134, 97,122,215, 52,116, 72, 16,196,161, 23, 37,180,172,147,225,155, 99, + 94,244, 53,204,179,236,219, 43,180, 94, 52,186, 59, 57,157,156, 78, 78, 39,167,147,211,201,233,228,116,114, 62,163,208,234, 58, +107,214,172, 79, 81,225, 26,131,153, 53,107,214,167, 12,195,244,174, 56,197,244,126,145,255,125,171, 37, 58,167, 54, 7, 99,217, +110,181, 68,231,106, 46, 29,103,179, 89,225, 28, 58,116,194, 9, 39,156,112,194, 9, 39,254,237, 56,191,100,201,146,242, 37, 75, +150, 88, 38,190, 63, 6, 64,152, 45, 92,143, 95,228, 31,155,135, 9,237, 89, 40, 85,115, 8,158,127, 0, 1, 36,155, 59,140,195, +229,119, 5, 67, 71, 3, 0, 72,214, 45, 74,175, 61,101, 50, 25,126, 2,144, 87, 87,226, 72,160, 73, 35,119,151, 3, 58,138,226, +102,151,233, 7,164, 85,132, 57,112, 24, 3,128,246,124, 30,239, 79,190,187,187, 75, 85,231,117,165,165, 26,157, 94,255,250,110, +224,156,179, 12, 56,225,132, 19, 78, 56,241,146, 64,228,225,225,113,130, 36,201, 16,203, 1, 91,191,131,149,125, 16, 82, 20,149, + 47,147,201, 94, 71,197, 80,241,223,201,105,251,123, 61,234,216,150, 63,111, 56, 58,116,200, 6,158,240,194,250,183, 68,204,102, +113,248, 99,197,110,238,139,254, 55,242, 3,175,240,136,198, 68,112,112, 32,192, 0, 89,217, 57,126,247,238,102,116,219,185,109, +213, 12,165, 66, 54,199,168,211,253,224, 40,119, 19, 64, 84,207,149,127,246,135, 89,239,186,179, 97,194,144,133,191, 28, 33, 84, +134,224,219, 21,203, 77, 29, 18, 89,238, 94, 94, 71,151, 28, 63,238,226,209,172,217, 19,231, 24,134,169,136,175,119,227,134,203, +236,215, 95, 63, 58, 64, 38,235,225, 20, 91,255, 73,248, 75, 36,146,105, 28, 14,167,139,193, 96, 8,225,241,120,217, 20, 69, 37, +200,229,242,111, 1,228, 58,179,231,191,141,198,254,162,142,141,195, 66,126,201, 43, 40,188,170,212,234, 71,167,231,169,100,206, + 92,113, 24, 53,197,215,252,199, 98,111, 2,128,171,171,235, 21,146, 36,131,108, 69,128, 37,102,175,101,191,242, 39, 77,211, 15, +100, 50, 89,187, 26,104,195, 60, 61, 61,215, 2,104, 85,155,195,100,179,111,182,203, 50,153,108, 18,170, 95,173, 39,246,240,240, +248,146, 32,136,129, 36, 73,178,106,187, 39,154,166, 41,134, 97,118,201,229,242, 47, 0,148, 85,119,157,135,135,199,241,180,180, +180, 86,190,190,190,181, 90,105, 76, 38, 19,178,178,178,124, 90,183,110,125, 70, 38,147, 69,190, 72,206,191, 91,139,212, 21, 53, +172, 58,172,246, 69, 7,240, 68,124,161, 23,234,145,149, 43,112, 61,208,182, 83,143,174, 19,167,126, 40,186,150,114, 7,127,158, +190, 0,165, 90, 7, 22, 73,194, 93, 44, 68, 68, 68, 67, 98,229,198, 61,222, 63,174, 95,249,245,197,196, 99,189,181,106,197, 91, + 14,201,116, 33,123,206,204,119, 90,139,188, 60, 41,128,166,240, 81,175, 88,209,236,248,171,115, 80,110,250,212, 97,145,117,226, +132,176,168,176, 16,243, 3, 2,192, 54,153, 32, 32, 73, 8, 8, 2, 2,146,132, 72, 32, 64,207,205,155,177,224,240, 97,225,103, +111,188,225, 20, 91,255, 49,184,186,186,142, 12, 8, 8, 88,190,105,211, 38,175, 6, 13, 26, 64, 36, 18, 65, 38,147,121,167,167, +167, 55,159, 62,125,250,240,252,252,252,185, 74,165,114,131, 51,167,254,187,160,105, 12,219,178,104, 82, 96,254,163,187,129,227, + 23,255, 26, 65,120, 81, 93,238,148,104, 10,156, 57, 99, 55,154, 3,184,138,170,227,151,214,116,174, 90, 8, 4,130, 66,173, 86, +235, 91,211, 53, 60, 30,175, 72,175,215,251,213,198, 69,146,100, 80,110,110,174,175, 80, 40, 4, 69, 81,230,104, 0,180,181, 35, +109, 27,253,196,236,168, 22,145,145,145,134,154, 56,197, 98,241,154,162,162,162,238,150, 56,129, 54,130,170, 74,228,230,230,118, +143,138,138, 90, 83, 86, 86,246,122, 53,226,229,203,169, 83,167, 78,139,137,137,177, 88,129,204, 81, 16, 42, 62,139,139,139, 49, +121,242,100,235,127,208, 52,141, 99,199,142, 77, 29, 57,114, 36,228,114,249,244, 26,238, 61,196,215,215,151, 48, 7, 20,175, 22, +243,230,205,195,188,121,243,176,106,213, 42,130,195,225,184,215,146,159,207,133,243,239,210, 34,117,177, 96,213,226, 25,254, 16, +158,156,155,117,232, 41,161,245,119,128,197,225,143,106,213,174,123,151,201,211,102,138,126,253,253, 36,210,111,223, 64,218,217, + 29, 79, 92,243,202,235, 35, 81, 80, 92,134,145, 19, 63,114, 37, 88,236, 46,137,199,247,143, 50,234, 52, 91,236,180,102,249,133, +240,121, 83,218,180,142,230,228,186,164,195,223,195, 5, 29, 90, 54,226, 4, 31,189, 57, 69, 13,211,119,183, 43, 86,201, 56, 36, +178, 54,189,251, 46, 58, 26,141,240,101,177,192, 34, 8,176, 0,144, 4, 1,173, 78,135,203,195,134,161,245,246,237,248,226,224, + 65,225,151,111,190,233,144,216, 18,137, 68,215, 8,130,240, 80,169, 84,189, 81, 17, 88,250,101, 64,148,171,171,235, 33,134, 97, +228,106,181,186,249,191, 40, 93, 82, 84,140,209, 87,238, 29,115, 81,177,162,202,161,200,194,124, 62,127,236,128, 1, 3, 86,174, + 94,189, 90, 88, 88, 88,136,188,188, 60, 80, 20, 5,129, 64,128,240,240,112,226,248,241,227, 94, 51,103,206, 92,113,232,208, 33, +126, 89, 89,217,119,142,116,108, 56, 28,206, 70, 79, 79,207, 55,252,252,252, 68, 69, 69, 69,229,165,165,165,199,116, 58,221, 88, +212, 61,108, 10,201,225,112,134,134,134,134,190, 29, 16, 16,224,151,155,155, 91,156,147,147,115, 64,167,211,253,136, 58, 6,106, +182,201,211,102, 48,123,171, 7,144, 31, 26, 26,122, 43, 51, 51,179,232, 57,114,230,133,134,134,166,214,129, 83, 4, 96, 39,128, +128, 90,174,203, 3, 48, 8, 14, 90,179,173, 25,203,208,127, 44,252,118,211,232,249, 35, 58, 16, 91,166,119, 15,159,176,234,248, + 5,146,203,116,186,157,175,205,118,106, 40,251, 68,150, 57,164, 85,101, 65, 85,211,185, 26,161,211,233,124, 12, 6, 3, 56,213, + 4,139, 87,171,213, 16,139,197, 62,246, 38,210,197,197, 5, 59,118,236, 0,135,195, 1,135,195,129, 92, 46, 71, 80, 80,144,117, +159,203,229, 90,191,215,171, 87,175, 86, 62,138,162, 90,179, 88, 44,168, 84, 42, 80, 20,101,221, 74, 75, 75,193, 48, 12,248,124, + 62, 40,170, 34,156,147,205,249,214,213,241, 17, 4, 49, 48, 32, 32, 0,191,254,250, 43,244,122,253, 83,231, 37, 18, 9, 82, 82, +254, 10, 50,194, 98,177, 16, 23, 23, 71, 18, 4, 49, 16,192,244, 26,120, 25, 0, 24, 55,110, 28, 88, 44, 22, 88, 44, 22, 72,146, +180,126,183,108, 20, 69, 97,222,188,121,168, 20,154,236,111,227,252,183,161, 22,207,240,249,168,102,142, 22,249,130,211,101,187, +196, 51, 64, 40,146, 44,157,244,193, 71,174,135,206,220, 68, 86,118,214, 83, 34, 11, 0,174,252,249, 35,242,243,114,113, 53, 45, + 7, 67, 71,189,239, 42,145,184, 47,173, 84,161, 86,187,108,212, 77,204,253,106,214,160, 14, 2,149, 49, 15,101, 30, 0, 43,140, + 7,142, 80,141,153,125,154,241, 37, 98,238,114,123,210,201,231,241,254, 92,114,252,184, 85,100,181,215,233,192,167, 40,152, 40, +202, 42,178,244, 38, 19, 52,122, 61,164, 42, 21,238,141, 28, 9,198,104,196,220,125,251,132,124, 30,239, 79,123,210, 9, 0, 92, + 46, 87,122,224,192,129,122, 77,155, 54, 61, 13,251,157,153, 30,127,193,207,168, 38,180,140,141,141, 77,216,190,125,123, 61, 46, +151, 43,125, 30,156, 2,129,160,191, 72, 36,122, 44, 16, 8,250,215, 49,157, 36,128,133,163, 71,143, 78,110,216,176,225, 73,179, +176,178,138,154,134, 13, 27, 30, 31, 61,122,244, 53, 0,243,170,121,215,171,226, 12, 12, 8, 8, 88,180,122,245,106, 97, 70, 70, + 6,114,115,115, 97, 52, 26, 49,100,200, 16, 80, 20, 5,141, 70, 3,189, 94,143,101,203,150,137,188,188,188,230,160, 34, 80,176, + 61,247,206,117,115,115,203,216,182,109,219,128,135, 15, 31,186,158, 60,121,146, 72, 73, 73, 17,173, 88,177,162,175,151,151, 87, + 58, 0,126, 29,242,147,148, 74,165, 91,246,239,223, 63, 41, 37, 37, 37,104,239,222,189,156,139, 23, 47, 74,215,175, 95, 63, 70, + 42,149,110, 7,192,170,227, 51,106, 46, 20, 10,187,125,252,241,199,244,249,243,231,115,207,159, 63,159,187,114,229, 74,116,236, +216,177,253,252,249,243, 91,212,145,179,165, 88, 44,126,245,227,143, 63,166, 19, 19, 19,243,146,146,146,114, 86,172, 88, 65,190, +250,234,171, 29, 22, 45, 90,212,204, 65,206,157,231,207,159,239,156,157,157,221, 32, 39, 39,167,126, 78, 78, 78,104, 78, 78, 78, +104,110,110,110, 72,126,126,126,189,130,130,130,224,162,162,162,224,132,132,132, 14, 0,126,177,135,179,177,159,104,210,244, 33, +221,203,231,140,234,197,124,250,222,107,204,204, 33,157,153, 55, 58, 53,253,157,197,102, 19, 73,169, 89, 8,114, 3,126,156,220, + 42, 36,216, 91,148, 18,237,233, 26,241, 47, 43,155,255, 54, 78,182, 69, 72,201,100, 50, 28, 58,116, 8,102,235, 85,115, 91,145, +165, 84, 42,145,159,159,111, 57,199,182, 39,157, 18,137,228,196,166, 77,155, 24,173, 86, 11,133, 66,129,162,162, 34,100,103,103, +227,222,189,123, 40, 41, 41,193,157, 59,119, 32, 20, 10, 79,216,147, 78,130, 32, 64, 81,148, 85, 72, 29, 59,118, 12,163, 71,143, +134, 76, 38,179, 30, 99,179,217,214,239,150,223,212,198,105,177, 60, 81, 20,133,164,164, 36,140, 31, 63, 30, 43, 87,174,196, 47, +191,252,130,248,248,120,200,100, 50,171,216, 50,153, 76,181,114, 22, 23, 23,131,166,237,235, 51, 49, 12, 3,133, 66, 97,247,115, +183, 21, 64,108, 54,251, 41, 81,100,217, 28,121,151,158,145,243, 95, 11, 59, 60,195, 87,223,195,182,124, 49,155,234,186,188,168, + 68,146,108,238,208,129, 35,166,122,229, 20, 41,145, 91,168, 0,139,252,171,221,107,209,125, 4,216, 44, 18,151,142, 86, 24,174, + 72, 22, 11, 10,181, 14,165, 42, 3, 6,140,152,230,249,195,202,207,135,154, 12,218, 26,125,188,196, 0,225,209,174,174,239, 68, + 69,213, 35,111,243,211,208,226,141,179,160,104,128, 73,124, 19,205,229,190,172,200, 63,121,239,168,203, 12,139, 82,128,140, 26, +173, 25,238,238, 46, 30,205,154, 97,126, 64, 0, 58, 25,141,224, 50, 12, 94, 43, 44,196,141,105,211,160,219,179, 7, 36, 0,110, +255,254,232,250,237,183, 56, 19, 16, 0,127,141, 6,165, 51,102,192,231,200, 17,112, 37, 18, 23, 60,182,111,241, 3, 65, 16,232, +210,165, 11,142, 31, 63,238,213,179,103,207,163, 55,111,222,236,103, 50,153,206,212, 37,111,221,220,220,174,176,217,236,160,218, +174, 51,153, 76, 57, 10,133,194,225, 48, 35,108, 54,187, 83, 92, 92,220,190,189,123,247,122, 24, 12,134,231,210, 11,225,241,120, + 61,251,246,237,187,105,221,186,117,146, 49, 99,198,108,138,143,143, 47,215,235,245, 71, 28,121,165, 0, 44,220,176, 97,195,132, +113,227,198,185,143, 25, 51,134,185,119,239,158,173,245,202,167, 99,199,142, 13, 55,109,218,228,223,170, 85,171,169,227,199,143, +231, 2,152, 91,155,149,199,213,213,117,226,166, 77,155,188,139,139,139,161, 82,169,172,149,108, 78, 78, 14, 92, 92, 92, 64,146, + 36, 72,146, 4,135,195,193,210,165, 75,189, 38, 78,156, 56, 77, 38,147, 77,179,195, 74,182,113,237,218,181, 62,175,191,254, 58, +249,240,225, 67,144, 36, 9,129, 64,128,119,223,125,151,212,104, 52, 30,243,231,207,223,170, 86,171, 7, 59,146,135, 28, 14,103, +232,198,141, 27, 35,218,183,111,207, 78, 75, 75, 67,219,182,109,113,233,210, 37,244,239,223,159, 83, 86, 86, 86,127,230,204,153, +163,117, 58,157,163,126, 92,164, 66,161, 48,230,212,169, 83,217,193,193,193,214,138,165,126,253,250, 84,239,222,189,101,105,105, +105,141,207,159, 63, 95,210,174, 93, 59, 71, 2,150, 7, 10,133,194,200, 63,254,248, 35,127,254,252,249,221, 54,108,216,208, 23, + 0, 90,183,110,125, 96,193,130, 5, 39,101, 50, 89,244,153, 51,103,100,157, 58,117,202,177,147, 47, 64, 42,149, 82,147, 39, 79, +118,173,233,162,205,155, 55,151,162, 34,224,114, 3, 0, 53,198,107,107, 28,234, 63,103,249,180,129, 46,160, 12, 96,140, 26,192, + 80, 14, 24, 84,160,245,229, 32,184, 46,128, 81, 3, 31,190, 12, 59, 39, 54,150,124,242,235,253,219,212, 29,162,119, 90,113,217, + 17, 56, 81,101, 85, 3,160, 5, 65, 16, 87, 15, 29, 58,132,184,184, 56, 28, 58,116, 8,189,123,247,190,106, 43, 6, 82, 82, 82, +208,169, 83, 39,152, 45, 90,118,205,213, 82, 40, 20,179,230,205,155,151, 56,116,232, 80,225, 19,149, 1, 73,194,221,221, 29,189, +122,245,210,170,213,234, 89,246, 38,148,162, 40,176,217,108,228,228,228, 96,243,230,205, 88,188,120, 49,194,195,195, 97, 52, 26, +159, 18, 91,230,122,207,174,202,207,100, 50,225,242,229,203,248,105,251,118,204,157, 51, 7, 98,177, 24, 0, 96, 48, 24, 32,147, +203, 33, 16, 8,172, 98,172, 22,225,180,235,238,221,255,107,239,218,195,154,186,178,253,111,159,115,242,132, 64, 32, 16, 16, 4, +100,116,172,180, 87,171,131,232,197,199,248,168,212, 50, 90, 71,107,125,116, 20,116, 70,138,218,250,205,168,157,142, 95,191, 78, + 91, 95, 51, 78,123,117,208,218,218,150,145,106,107,181, 29,139,218, 58, 85,219,218, 14, 62,166,222,170, 80, 91,161,248,192, 7, +162, 16, 72, 8,132, 16, 66,158,231,220, 63,200,137, 1, 9, 36,112,162,216,203,250,190,243,145,199,225,151,181, 95,103,255,246, + 90,107,175,125,121,121, 92, 92, 92, 43,151, 33,255,215,245,204, 2,203,178,112, 56, 28,104,110,110, 70, 78, 78,142,131,227,184, +189,157,205, 63, 60, 41, 90,190,124, 57, 44,150,219, 6,245,161,174,152,228,196,196, 68, 12, 27, 54,204,253,158,162, 40,206, 87, +204,127,140, 30, 2,179,199,221, 73,171, 55, 2, 0,226,226,226,144,148,148,132,152,152, 24,175,152,129,230, 34, 93, 17, 63, 50, +195,123, 39, 90,119,227,164,108,145, 88, 54,113,192,192, 65,228, 70,149, 30, 12,195, 32, 88, 25,137,209, 51, 86,128,166, 41, 40, +194, 34, 65,156,230,219,140,152,162,193,208, 12,244, 70, 51, 18,251, 15,164,164, 50,249, 68, 83, 39, 68, 43, 84, 41,218,246,252, +220,209,178, 90,199, 77,200, 19,100,112,242,211,105,172, 4, 84,132, 17,207,165, 63, 32,207,254,244,135,109, 48,216, 31,241, 69, + 95,218,225, 64, 20, 77,195,198,113,248,126,249,114, 36,231,230,162,136, 39,134,185,185, 40,202,206,134, 74, 36,130,148,162,192, +217,237,119,248,244,125, 33, 90, 0, 80, 81, 81,129,252,252,124,213,236,217,179,247,159, 63,127,126,190,159,100,131,199,138,252, +246,219,111,163,250,247,239,239,245,158,171, 87,175, 34, 37, 37,197,111,247,148, 68, 34, 73,127,228,145, 71,246,228,231,231, 43, + 75, 74, 74, 16, 21, 21,213,109,162, 37,149, 74,199,165,165,165,237,121,239,189,247, 66,181, 90, 45,114,115,115, 67,167, 77,155, +182,187,176,176,112,134,197, 98,241,133,108,182, 34, 89,185,185,185,245,121,121,121,255, 64,107, 23, 97, 85, 94, 94,222,187, 35, + 70,140,120, 38, 59, 59, 59, 12,192, 18, 87,236, 64,135,100, 75, 42,149, 78, 24, 48, 96, 64,171, 85,173, 84,218, 98,108, 10, 14, + 14,134, 82,169,132, 88, 44,134,197, 98, 65,114,114, 50,145, 72, 36, 99,125, 41,115, 72, 72, 72,218, 19, 79, 60, 65,157, 60,121, + 18, 26,141, 6, 97, 97, 97, 80, 40, 20,112, 58,157,200,202,202,162,115,114,114, 38,152, 76,254,121,184,226,227,227,167, 79,154, + 52,137, 41, 46, 46,198,181,107,215, 96,177, 88,112,241,226, 69,132,134,134, 34, 51, 51, 83,252,218,107,175, 77,187,117,235,150, +191, 68,107, 72,118,118,118,181, 39,201,226, 37, 56, 56,152, 12, 26, 52, 72, 31, 17, 17, 49, 28,128, 63, 68,107,200,178,101,203, +106, 54,108,216, 48,238,232,209,163,238,164,151, 71,143, 30,253, 19, 0,108,217,178,229,132, 90,173, 30, 14,192, 87,162, 5,142, +227,216,167,158,122,170, 92, 34,145, 64, 36, 18, 65, 34,145,180,186,196, 98, 49, 40,138, 10,225,135,115,103,120, 63, 94,211,188, +154,245,167,141, 27,131,101,180,232, 15, 51, 30, 70, 66,152, 24,144,171, 32, 30,183, 10, 36,172,197,104,201,233,175, 2, 95,172, +194,166, 39,244, 84,246, 7,205, 7,108,206,112,245,149,186, 58,227, 61,158, 3, 70, 0,248, 59, 90, 14,215,125, 17,192,183, 61, +100,110,250, 14, 64,242,212,169, 83,221,100,235,240,225,195, 72, 79, 79, 71,125,125, 61,138,139,139, 61, 73,150, 63, 7, 44,127, +103,183,219,207,125,248,225,135,163,103,207,158, 77, 60,198, 23, 74, 74, 74,112,225,194,133, 34, 95,241, 40,138, 2,203,178, 16, +137, 68,216,184,113, 35,108, 54, 27, 62,248,224, 3,124,252,241,199,160, 40, 10,132, 16, 16, 66, 16, 26, 26,138,215, 95,127,221, +175,231,158,211,233,196,206,157, 59,177,234, 79,127,114,147, 44,151, 39, 3,125,162,163, 17, 17, 25,137, 43, 87,174,116, 74,180, +234,234,234, 94, 57,120,240, 32, 58, 10,134, 63,120,240,160,251,117,155, 96,248,206,231, 57,154,134,197, 98,193,163,143,222, 62, + 42,118,217,178,101,238,215,122,189, 30, 52, 77,243,117, 65,124,197, 52,115,192, 12,217,237,207,166, 60,247, 92, 43, 11,157, 55, +204,187,193, 69,132,178,110,181, 67,182,146, 93,214,217, 24, 0, 83,209, 18,163, 85, 5,220,197, 24, 45,142, 99, 31,140,235, 27, +139,115,101,231,193,208, 52, 36,202, 72, 40, 85,209, 96, 29, 86, 24,106,174,161, 96,223,155, 0,128,119,118,238, 5, 69, 81, 96, + 24, 26, 22,171, 19, 15, 36,196,130,101,217, 7, 59,194,126, 8, 24, 61, 33, 58,242,191,227,251,133,145,226,240,107, 24, 20, 21, +209,198, 17, 34,197, 3,149, 10, 50, 74, 33, 31, 89,103,104, 24,253, 35,240, 77,167,100,128,162, 64, 17,130, 32,177, 24,150,252, +252,150,168,205,220,150, 57,171, 40, 59, 27,212,129, 3, 8,145, 74, 65, 19, 2,198,101,130,238,138, 52, 52, 52,128, 16,130, 93, +187,118,133,103,102,102,238, 46, 46, 46,206,110,110,110,206,247, 7,163,190,190,126,234,152, 49, 99,190,222,185,115,167,186, 79, +159, 62,119,124,175,209,104,176,112,225, 66,109,125,125,189, 95, 73,221,100, 50,217,147,211,167, 79,223,190, 99,199,142,208,203, +151, 47,163,177,177, 17,106,181,186,187, 93, 97,120,106,106,234,254,252,252,124,165, 70,163,129,193, 96,128,197, 98,193,174, 93, +187,194,166, 76,153,146, 95, 90, 90,154, 14,160,176, 19,140,151, 60, 73,214,226,197,139,127, 0, 16, 5, 96, 91, 91, 14,234,250, +238, 97, 15,178,101, 0,240, 90, 7, 43,209,126,193,193,193,168,169,169,193,194,133, 11,113,233,210,109, 3,104,108,108,172,123, +165,119,229,202, 21,168,213,106, 16, 66,162,124, 41,180, 90,173, 86, 88,173, 86, 44, 90,180, 8, 21, 21, 21,173, 48,111,222,188, + 9, 66, 72,144,191, 21, 25, 29, 29, 29,109, 54,155,241,203, 95,254, 18,205,205, 45,231,250,206,153, 51, 7, 34,145, 8, 53, 53, + 53, 16,137, 68,145, 93,104,159,200,169, 83,167,122, 77,173, 18, 26, 26,106, 11, 15, 15,127,200, 79,204,136,105,211,166,221,202, +205,205,189, 99, 99,203,233,211,167,127,173, 82,169,142,170, 84,170, 65,126, 98,178,158,164, 74, 44, 22,183, 34, 90, 34,145, 8, + 20, 69,249, 28,163,118,169,198,244, 6, 67,170,134,109,120,118,242,194,132, 40, 37,184,198,106,136, 31,121, 5,231,180,114,108, +204, 57, 4, 0,248,227,188, 20, 12, 77, 91, 15,235,142,201, 88, 62,138,150,100,220,180, 60, 15,224,165,123,252,204,255, 31, 0, +252, 46,184,183, 0, 12,235, 65,243,145,155,108, 29, 62,124, 24,131, 7, 15, 70, 93, 93, 29, 74, 75, 75,187, 74,178,248,231,221, +170, 53,107,214,124, 49,115,230,204, 96,126,209, 42,151,203,177,114,229, 74,115, 99, 99,227, 42,191, 58, 17,203,130, 97, 24,247, + 34, 89, 38,147, 33, 57, 57,217, 77,178, 8, 33,104,106,106, 2,195, 48,252,142, 68,226,163,142,136,233,211, 7, 33, 33, 33, 24, +248,192, 3,184,236,122,142,240,175,165, 82, 41, 8, 33,112, 56, 58, 53,228, 25, 93, 65,237, 43,132,158,146,121, 82,212,161,233, + 56, 54, 22, 44,203,242, 36,147, 19, 2, 51, 50, 50, 18,141,141,141,190, 98,246, 72,241, 98,209,226,137,214, 84,180,196,106,221, +145,222, 97, 60,128, 2, 4,112, 75, 37, 1, 71, 88,142, 3, 67, 83, 46,223, 45, 13,154,166,160,215, 86, 97,243, 43, 75, 92, 36, +235, 99,124,118,162, 20,113, 3, 6,223,246,227, 18, 2,112, 29,119,110,181, 82,156,187,116,102,170,188,154, 84, 33, 44, 54, 8, + 50, 89, 27,254, 24, 46, 6, 73,164,240,236,132,184,160, 51, 7,155,115,127, 52,216, 58,157, 40,100, 20,213, 18,252, 78, 72,187, +193, 61,148,235, 59,154, 16,112, 28, 7,142,245, 47,238,152, 39,242,114,185, 28, 54,155, 13, 52, 77, 99,235,214,173, 97,105,105, +105,219,252, 37, 90, 0, 74,170,171,171,167,100,101,101, 29,222,187,119,111,100,100,100,100,171,213, 67, 86, 86,150,174,186,186, +122, 10,252, 12,186, 23,137, 68,219,222,122,235,173,208,235,215,175,163,169,169, 9,114,185,220,253,240,233,106,255, 28, 57,114, +228,231, 71,142, 28, 9, 55, 24, 12,176,217,108,144,203,229,224, 56, 14, 52, 77,227,163,143, 62,138,120,252,241,199, 15,221,184, +113,227,145,142,116,149,203,229, 51, 92,196, 9,217,217,217, 97,217,217,217,227, 1,175,153,122,221,146,157,157, 29,182, 98,197, +138,105,102,179,249,181, 14,202, 92,161,215,235,251,200,229,114,236,219,183, 15, 10,133, 2, 65, 65, 65,136,141,141,133, 94,175, + 71, 80, 80, 16, 56,142,131,221,110,231, 31, 22,181,190, 20, 92,171,213, 54, 58, 28, 14,229,225,195,135, 81, 91,123,251, 95, 18, + 18, 18, 80, 95, 95, 15,150,101,155,252,173,204,202,202,202,106, 66, 72,252,185,115,231,112,253,250,117,164,167,167,227,192,129, + 3, 72, 73,105,241, 14, 91,173,214,174, 36,241,115,210, 52,205,117,208,111, 9,128,112, 33, 49, 93,147,151, 95,152, 44,203,178, + 60,201,242,252,235, 73,190, 58,249,205, 86,195,249,161,104, 69,222,134,165,147, 22, 78, 30, 28, 9,179,246, 26,100, 33,145, 32, + 97,137,216,152,115, 8,197, 87, 91,218,107,227,238,179,216,179,118, 10, 32, 87, 33, 73,169, 67,159, 16,230,137, 11, 53,247,156, +104, 41, 61,215, 9, 61,117, 98, 74, 79, 79,135, 94,175,135, 66,161, 16, 34, 62,231,148,217,108,190,248,201, 39,159, 12,159, 58, +117, 42, 36, 18, 9, 46, 94,188,136,194,194,194, 82, 0,167,252, 37, 90, 34,145, 8,107,214,172,193,146, 37, 75, 16, 29, 29,141, + 85,171, 86,129, 97, 24,247, 69, 8,113, 91,184,252,145,168,232,142, 55, 62,242, 1,241,157, 25,195,149, 74,229, 26,138,162,102, +211, 62, 84,156,211,233,116,178, 44,187,215, 96, 48,116,152,222,129, 15, 92,247,165, 45, 60,235,160,147, 57,173,219,152,119,131, +139,116, 69,218,238, 54,244, 98,209,226,119, 29,222,113, 20, 16, 95,202, 2,151,201,174, 32, 80,138, 18,138,190,112,243, 86, 37, + 34,194, 21, 46,146,229,186, 40, 10, 67, 7,183, 44,102, 63, 59, 81,138,184,254,131,193,208, 52, 24,154,134, 66, 46, 69,181,166, + 10, 12, 67, 93,240,134, 59,132,198,204,153,131,226, 19,195, 35, 68,208,169,173,136,137,246, 98, 24, 24, 30,130,184, 24, 9, 30, +139,144,245, 27, 66, 99,102,199,214, 55,206, 77,180,108, 14, 7,196, 79, 62,233,118, 23, 22,101,103, 35, 57, 55, 23,206,233,211, + 97,178,217, 90,153,138,187, 74,180,228,114, 57,140, 70, 35,230,207,159,175,183,219,237,207,116,177,138, 11,107,107,107,103,101, +100,100,212,242, 4,198,102,179, 33, 35, 35,163,182,182,182,118,150, 15, 86,162, 59,196,110,183, 63,147,146,146,162,215,233,116, +110, 61,187,242,192,225, 69,165, 82,125,150,151,151,167,178, 88, 44,112, 56, 28,110, 76,185, 92, 14,154,166,161, 86,171,177,103, +207, 30,181, 74,165,234,240,204, 42,179,217,252, 73,110,110,110, 61, 0,228,230,230,214, 19, 66,142, 17, 66,222, 38,132,188,213, +230,122,155, 16,114,204,243, 94,179,217,188,191, 35,108,171,213,122,172,180,180,148, 11, 10, 10, 2, 77,211,176,217,108,144,201, +100,110,147,120, 67, 67, 3,204,230, 22, 55,119, 97, 97, 33,236,118,251, 73, 95,202,110, 52, 26,191,218,185,115, 39,155,144,144, +128,193,131, 7, 35, 57, 57, 25,169,169,169,232,215,175, 31,214,173, 91,231, 52,153, 76,126,143,189,202,202,202,207,254,249,207, +127,218,227,227,227, 49,124,248,112, 72,165, 82, 12, 29, 58, 20,177,177,177,248,235, 95,255,106, 53, 24, 12,135,187,208, 76, 55, +206,159, 63, 79,119, 64,114, 67,225,195,238,221, 54, 82,113,230,204, 25, 58, 53, 53,245,211,182, 95,140, 28, 57,242, 83,133, 66, +161,228, 77,236,254,172,200, 61,201,149, 84, 42,117, 95,252,231, 12,195,248,178,250,161, 30,138, 86,228,253,109,201,196,133,147, + 7,135,227,211,175,190,133,216, 86, 15, 88, 59,240, 8, 58,237, 32,226, 96, 68, 43, 69,113, 61, 96, 14, 88, 14,224, 7,180,228, + 97, 90,133,158, 37,238,192,247,218,218, 90,148,150,150,162,176,176, 16,169,169,169, 56,121,242, 36,112, 59, 64,222,111, 49, 24, + 12,171,214,174, 93,107,226,119,242,189,248,226,139,102,163,209,184,202,223,103, 48,199,113, 16,137, 68, 72, 74, 74,194,138,112, + 76,117,201, 0, 0, 13, 69, 73, 68, 65, 84, 21, 43,112,232,208, 33, 92,188,120, 17,118,187,221, 77,132,248,152, 76,127, 44, 90, + 98,177, 24,209,209,209,176,219,237,110,107, 22, 0, 92,190,116, 9, 12,195,128,101, 89, 88,173,214, 78, 45, 90, 74,165,114,205, +246,237,219,127,175,211,233, 98,180, 90,109,148,231, 85, 93, 93, 29, 85, 85, 85, 21,117,235,214,173,168,138,138,138,168,242,242, +242,168,107,215,174,197,188,250,234,171,191, 87, 42,149,107,124,209,147,166,105, 12, 29, 58, 20,203,150, 45,115, 95,111,188,241, +134,251, 42, 40, 40,240, 59,120,157,166,105, 36,173,222,136, 41, 90,206,125, 29, 82, 19,247, 85,252,199,197, 29, 97, 6,156,139, +116,137,191,184,118, 27,122, 30, 44,221,142,240,187, 14,249,103,153, 59,108,163,109, 48,124,192,196, 97,109,254,250,106,217,165, +137, 73, 67, 70, 80, 26, 93, 99,171,237,159,201, 19,102,129, 16,130,190,253, 7,131,102, 24,208, 52, 5,134,166, 17, 22, 42, 67, +233,185,115,172,197,108,254,186, 61,204,241, 0, 35,145, 75,222,152,247,216, 80, 89,165,164, 6,234,152, 96,136, 69, 45,220,145, +187, 58,171,205, 12,193, 0, 67, 66,240,219, 91, 17,242,175,171,155,223, 8, 55,217, 62, 61,230,101, 5,200,178, 44, 20, 82, 41, +154, 45, 22,152, 29, 14, 76,216,188,217,237, 46,164, 8,193,119, 0, 30,222,188, 25,223,228,231, 35, 84, 34, 1,164, 82,159,119, +133,180, 71,180,116, 58, 29, 22, 44, 88, 80, 91, 85, 85,149,217,149, 24, 45, 94, 44, 22,203,113,141, 70,147, 57,107,214,172, 93, +251,246,237, 83,205,154, 53, 75,175,209,104, 50,125,140,123,186, 67,154,155,155,243, 43, 42, 42,154, 22, 44, 88,240,254,238,221, +187, 35, 34, 35, 35,221, 43,145, 46,117, 86, 66,116,147, 38, 77,146,250,114, 95, 39,183,172,117, 5,183, 47,113, 89,182, 30, 94, +188,120,241, 55,104,137,191,242,148,213,239,188,243,206, 28, 15, 23,227,219, 0, 54,119, 4,220,208,208,240,214,138, 21, 43,126, +119,252,248,241, 72,153, 76, 6, 66, 8,196, 98, 49, 6, 14, 28,232,222, 69, 35, 18,137,192,113, 28,158,123,238, 57, 93, 77, 77, +205, 22, 31,219,102,241,218,181,107,199, 53, 55, 55,135, 47, 88,176,128,150,201,100,168,174,174, 70, 78, 78,142,115,199,142, 29, +245, 38,147,105, 97, 23,136,240,206,151, 95,126,121, 66, 99, 99, 99,255,172,172, 44,177,193, 96,128,217,108,198,243,207, 63,111, +125,247,221,119,111,154,205,102,191, 19,254,142, 26, 53,170,172,188,188,124,108, 83, 83, 83, 93, 80, 80, 80, 91,107, 31, 9, 14, + 14, 30, 1,224,125,127, 48,147,147,147,175,220,184,113, 35,117,253,250,245,199,236,118,187,232,244,233,211,238, 96,248,173, 91, +183, 22,200,100,178, 73,240,243,240, 85, 66, 8, 43,149, 74, 91, 89,176,218,190,102, 24,166,211,103,218,131,125,130,214,255,237, +233,113, 11, 31,125, 72,137, 79,190, 58,139,181,251,175, 94,120, 96,161, 58,233,231,225, 90,176,218, 82,252,113, 94, 10, 54,238, + 62, 11,160,197,117,200,214, 20,131,171,187, 2, 46, 36, 30,215,244,186,202, 30, 48, 7, 20,160, 37,101, 70, 79,147, 86, 36,171, +184,184, 24, 19, 39, 78, 4, 0,156, 60,121, 18, 99,198,140,193,201,147, 39, 49,118,236, 88,191,115,105,185,228,223, 13, 13, 13, +229, 5, 5, 5,255, 21, 31, 31,143, 83,167, 78, 93, 3,240,111,127,149,228,137, 22,195, 48,248,205,111,126,131,180,180, 52, 36, + 36, 36,180,218,109,200,191,246,135,108, 56, 28, 14, 12, 25, 50, 4, 22,171, 21, 98,177,216,237,154,100, 24, 6,234,168, 40,148, +149,149,249,100,209,162, 40,106,246,140, 25, 51,168,146,146, 18,204,157, 59, 23,187,118,237,242,122,111, 70, 70, 6, 62,252,240, + 67,204,152, 49,131,122,225,133, 23, 58, 76,239,192, 7,161,251, 82, 38,126,158,238,236,185, 47, 20,102,160,185, 72,119,196, 35, +181, 67,187, 78,147,118, 62,203,109, 69,180, 60,146,132, 5,134,104, 57,108,187, 14,124,240,230,138,212,109, 99,213, 49, 81, 74, +232, 13,102, 55,217, 42, 42,248, 24, 0, 48,115,241, 95,192,208, 45, 46,197, 80,133, 12,114, 49,141,252,247,182,232,108,182,230, +118,123,151, 81, 68, 45,121, 97,244, 64,165, 36,216,142,134, 62, 28, 6,171,111,159,148, 67,250,127,124, 39,225,250, 69, 56, 34, +139,235, 48,239,231,138,208, 45, 37,245, 75, 96,103,223,184, 99, 66,172,175, 55,215,159, 59, 39, 79,223,190, 29,167, 51, 51,209, +215,233,196,177,216, 88,168, 68, 34, 40,165, 82, 80,132,192,252,175,127,225,155,125,251, 16, 45,149, 2, 33, 33,112,172, 91, 7, + 75,105, 41,236, 70,163,185, 11, 43, 51,204,153, 51, 71,167,211,233,102, 89,173,214,227,221,173,103,179,217,124,164,162,162, 98, +201,168, 81,163,182,217,237,246,103,204,102,115,183,118, 70, 89,173,214, 35, 26,141,230,201, 57,115,230,124,188,127,255,254,200, +176,176,176, 46, 99,213,214,214,166, 8,212,157, 88, 0,127,118, 5,183, 47,201,206,206, 14, 59,115,230,204,239,242,242,242,182, +121,172, 38,162, 22, 45, 90,244,116, 27,146,213,233,174, 67, 0, 55,106,106,106,214,173, 92,185,242, 47,155, 54,109, 82,240,129, +239,223,127,255, 61, 28, 14, 7, 68, 34, 17,156, 78, 39, 22, 45, 90,212, 88, 91, 91,187, 17,222, 51, 58,223,209,181, 26, 26, 26, + 6,174, 95,191, 62,111,243,230,205,105, 52, 77, 7, 59,157, 78, 83, 83, 83,211,177,230,230,230,133,232, 90, 30, 45, 86,171,213, + 46,120,233,165,151, 22,228,228,228,204,160, 40, 42,202,225,112,232,140, 70,227, 65,179,217,252, 46,186,224, 74, 58,117,234,148, +118,222,188,121, 87,181, 90,237,131,113,113,113, 6,133, 66, 97,181, 90,173,180, 92, 46, 15, 13, 14, 14, 78, 6,112,138, 16,242, +163, 63,152, 69, 69, 69,154,172,172,172,235, 22,139, 37,233,237,183,223, 62, 17, 26, 26,250, 21, 33,132,136,197,226,112,185, 92, + 62, 17,192, 49, 66,200,101,127, 48, 41,138, 98, 61,173, 87,109,227,179, 36, 18,137, 79, 49, 90,253,213, 65,191, 77, 27,200,224, +147,175,207, 98,237, 39, 55,118, 58, 57,110,223,190,162,186,127,173, 26, 3,216,246,206,195,208, 89,239,183,184, 11, 1,176, 53, +197,176,237,205, 0, 9,138,196,137, 91, 34, 24,204,182,207,208, 43,237,137, 59,189,131, 78,167, 67, 73, 73, 9, 79,178,146, 1, + 96,236,216,177, 69, 60,217, 42, 44, 44,196,240,225,195,139, 0,136,252,237,175, 13, 13, 13, 43,231,207,159,127,196,181, 56, 94, +217,133,133,159,155,104,241,132, 42, 33, 33,193,253,222,243,242,136,209,242, 73,156, 78, 39,196, 98, 49, 24,134, 65, 76,108,172, +251,183, 56,142, 67, 89, 89, 25,244,122,189, 79, 68,139,166,105,154, 16,130,185,115,125,219,144,252,212, 83, 79,225,216,177, 99, +160,125,100,133, 52, 77, 35, 49, 49,177,211,123,120, 94,234, 43,102, 92, 92, 92,151, 49, 3,205, 69,186, 74,176,218,123,221, 30, +169,242, 54, 32,238,150, 84, 54, 54, 26,254,252,222,246,173,155, 22, 45,125, 78, 81,124,165, 26,134, 70, 11,104,154,242,124,120, +130, 97,104,132, 6,203, 16,223, 71,137,221,255,248,187,209,216, 80,255, 18,188,156,123,152, 16, 34, 94, 60,105,196,207,165,226, + 24, 19,146, 30,158, 3, 90,118,155, 4,112, 26, 47,222,193, 49, 95,224, 87, 55, 76,178, 3, 55, 76,139,191,171,179,222, 73,180, +172,214,201, 47, 62,246,216,231,107, 15, 29, 10, 26,185,115, 39,174, 44, 90,132, 88,179, 25, 82,151, 43,145, 34, 4, 10,177, 24, + 10,177,184,133,100,229,228,192,236,112, 96,115,102,102,147,197,106,125,204,159, 65, 94, 91, 91,139,233,211,167,107, 43, 43, 43, +167,160, 11,174, 61,111, 98, 50,153,242, 1,228, 11,133,103,177, 88,142,223,188,121,243, 87,211,167, 79, 63,116,228,200, 17,117, + 15, 73, 50,199,147, 45,219,153, 51,103,158, 62,113,226,196, 21,180, 62, 88,180,254,196,137, 19, 87,178,178,178, 72, 94, 94,222, +187, 0, 94,134,143, 9, 60, 77, 38,211,214, 47,191,252, 18,227,198,141,123,121,195,134, 13, 17, 41, 41, 41,136,138,138,130,209, +104, 68, 97, 97, 33,150, 47, 95,174,111,104,104,216, 80, 95, 95,191,201, 79,157,109, 22,139, 37,195,115, 43,181, 16,245, 96,177, + 88,118, 84, 85, 85,237, 16, 10,240,217,103,159,253,190,172,172,172, 86,173, 86,255,183, 88, 44,126, 24, 45,113, 64, 26, 0,239, +250, 75,136,120, 89,186,116,233,185,178,178, 50, 93,223,190,125, 83, 93,152, 97,104, 57,198,104,123, 23, 48, 43,207,158, 61, 27, + 55, 98,196, 8, 74, 36, 18,113, 52, 77, 67, 36, 18,113, 12,195,112,174,184, 26, 14, 0, 14, 30, 60, 40, 5,208,225,177, 57, 87, +106,204,235, 51,254,254,159, 23,126,212, 52,239, 43,173,110, 90, 1,128,219, 91, 28,244,197, 80, 53, 61,121,242,160,155,176,228, +142, 5, 9,109, 73, 84,201, 53, 86,129, 4, 71,227, 38,219, 23,171, 63,189,160,113,128,188,214,203,169,218, 95, 87,195,149,222, +161,170,170,202,147,100,241, 86,171,228,177, 99,199, 22,185, 72, 22,255, 93, 87,226,203,142,178, 44,219,173, 57,140,227, 56,172, + 93,187, 22,239,188,243, 14, 58,203,104,238,218,221, 71, 58,195,227, 45, 90, 78,167, 19, 54,155, 13,197,197,197,238,156, 93,188, +187,144, 79,237,224,112, 56, 58,220,173,238,116, 58,157, 86,171, 21, 31,125,244,145, 79,100,107,207,158, 61,104,110,110,134,179, + 19, 6,231,153,138, 97,216,176, 97,208,235,245,238,205, 62,201,201,183, 83,229,217,108, 54,191,136, 43,143,153,148,148, 4,157, + 78, 7, 62, 94, 56, 62,243,182,177,199, 97, 50,253, 84,251,189, 87,139,214, 93,159, 49,165, 65,161, 71, 82, 70,167,141,201,124, +122,121,112,163,197,137,235,215,203,161,173,169, 2, 69, 40,196,244,141, 67,191,126,137,144, 75, 40,236,202,221,100, 42,250,230, +171,255, 52, 26,235,210,189, 97, 77, 85,138,191,201,121,114, 76,234,128, 1, 33, 4, 14, 59,224,180, 3, 14, 59,192,186,254,242, +159,177,173,251, 92, 73, 73, 61,247,194,119,250,255,253,204, 96,107,247,204,170, 89,192,152, 48,149,234,243,213, 7, 15, 6,177, + 54, 27,106, 87,174, 68,144,195, 1,153,107, 85,210, 82, 16, 41, 28,235,214,181,144,172,140,140, 38, 67,125,189, 95, 71,240, 68, + 70, 70,158, 37,132, 68,106,181,218,251, 42, 51,188, 90,173,254,140,227, 56,157, 78,167, 75,233, 65,122, 69, 1,168, 7, 96,107, +103, 33,161,134,255,241, 63,188, 36,170,213,234, 23, 40,138, 26,197,113, 92, 4, 69, 81,117, 44,203,158,170,169,169,121, 21, 64, + 89,239,124,122,207,132,207, 12,255,179, 78,238,171, 1,240, 7,180, 4, 5, 95,247, 21,124,168, 82,169,180, 72,236,251,127, 61, + 88, 58, 97,118,178, 18,253,251,132, 64, 36,150,161,178,193,129,163, 63, 54, 96,123,129,166,194,108,119, 62,126, 73,219,116,190, +183, 41, 58, 20,193,143,224, 17, 82, 84, 42,213,183,159,127,254,121, 74,255,254,253, 41,207,128,119, 62, 87, 30,239,222, 98,152, + 22, 46,119,252,248,113,199,220,185,115, 79, 85, 87, 87,143,243,134, 25, 18, 18,242,197, 15, 63,252,240,168,193, 96,184,131, 80, +121,102,138,231,223,155, 76, 38, 44, 93,186,244, 75,111, 71,240, 40,149,202,156, 77,155, 54,253,126,230,204,153, 20,159,142,194, +243,226,143, 11,226, 47,155,205,134,247,223,127,159,221,178,101,203,235, 6,131,193,171,235, 48, 38, 38,166,162,178,178, 50,142, + 79,181,224, 75, 82,209,196,196,196,170,242,242,242,216,187,137,121, 31, 19,174, 86,214,173,123, 98,154, 16,201,229,207,134, 40, +194, 95,153, 57,127, 89, 68,226,128, 7, 72,116, 76, 95, 16, 80,168,214,220, 66,249,213, 75,220,254, 15,222,172, 53, 53,232,215, +152,205,166, 55, 59,194,121, 8, 24,240,179, 80,241, 94,137, 19,131,192, 19,160, 54,231, 83,221,177,226, 0, 96, 19, 81, 23,174, + 27,237,115,126,236,192,237,195,147,173, 63,239,223, 31, 36, 25, 52,232,142, 68,113, 44,203,194, 82, 90,138,205,153,153,126,147, +172, 94,233,149, 94, 17, 68,250,163,243, 28, 89,118,180,228,231,242,215, 98, 66,146,162,130,231,112,192,108, 10,236, 16,138, 16, +137,131,195, 69,112,248, 34,136,105,218, 86, 84, 5,115,111,245,251, 36, 61,246, 80,105, 0,193, 42,149,234, 43,154,166,251,241, + 22, 25, 79,107,125, 59, 7, 74, 95,175,174,174,158, 4,160,163, 29,194, 3, 66, 66, 66,222,116, 58,157, 35,125, 57, 84,154,166, +233,211, 70,163,241, 89,116,112,168,116, 32,118, 29, 70, 68, 68,148,149,151,151, 15,224,119, 81,123,206,149,237,237, 44,191,124, +249, 50,198,143, 31, 95,174,209,104, 18,239, 38,102, 79, 21, 47,187, 14,123,142, 69,203, 67, 98,197, 82,197, 2,137, 92,246, 8, +107,119, 36,129, 0,140, 72,116,193,218,108,254,218, 98,110,124, 15, 94,220,133,119, 83,102, 1, 99,164, 18,201, 23,226,208, 80, +121,123,164,205,110, 52,154, 45, 86,235,228, 94,146,213, 43,189,210, 43,189,210, 43,247,145, 12, 82,169, 84,159,139, 68, 34,169, + 39,153,108,251,154, 23,135,195,209,172,213,106,211, 1, 92,188,203,152,255, 63,197,207, 32,181, 52, 95, 49, 93,215,248,158,142, + 25,192,178,115, 2, 98,142,119, 97,174,190, 79,244, 28,223, 83, 49,249,242,250,129,155,230, 79, 63, 18,170, 62, 61,244,228,132, +214, 51, 80,152, 66,141,163,118,244,228, 2,208,238,171,239, 19, 61,199,247, 52,204,182,253,199, 71, 92,191, 48,125,236, 83,254, +234,201, 9,173,103,160, 48,187, 59,142, 58,208,147,235,110, 95,242,210,246,171,113, 31, 74,201, 47,192,149,252, 2, 92,241,240, +118,243, 54,102,123,251, 63,191, 2, 9, 3,181, 19,128, 79,187,239,194, 39, 61, 21,211,179, 30,132, 60, 42, 32, 0,199, 14, 20, + 8,141,217,166, 62,133,146,213,174, 29, 38,199,224, 67,194, 81,127,202, 46, 68,187,183, 41,171, 32,184, 93, 32, 89,126, 97, 10, +213,239, 3,141, 41,212, 88,106,139, 41, 68,191,111,175,221, 3,216, 70, 66,233, 41,200, 88, 10, 68,159,111,167,255,116, 27,183, + 45,166, 16, 99,169, 45,166, 16,253,254,110, 96, 10, 49,150,218,195, 20,162,223,123,107,251,251,213,208,196,187, 11, 93, 41, 30, +136, 15,100, 43, 23, 0,168,174, 84, 90, 0, 45,101, 19,132,198, 20, 90,231, 64,144, 77, 63, 44, 48,247, 28, 83,224, 54, 90,237, +194, 20,114,117, 51, 65,168, 54, 10, 68,127,247,196, 20, 10,191, 45,142, 16,237,212, 30,102,119,245,245,162,167,224,101,239,110, +191,191, 91,152, 2,183,145, 32, 99,169, 13,230, 4,129, 23, 3, 19, 60,222,175, 22, 18, 83,168,177,212,142,158,221,110,167,246, + 48,187,171,175, 23, 61, 5, 47,187, 16,115, 72,160,112,239,165, 69,139,163,188,246,137,220, 54,215, 93, 33, 26,247,204, 37,231, + 39,246, 79, 10,211, 79,247, 76, 90, 0,218,254,158,234, 41, 36,102, 91, 29,133,116,247, 4, 82, 79, 33, 49,253,208,245, 39,135, +121,191,181,123, 79,172, 79,111,120,221,113, 75,121,179,142, 6, 66, 79, 33, 49,125,196,254, 73, 96,118,163,237,127,114,194,244, + 20, 69,248,138, 23,120,101, 2,129, 45, 48, 1, 43,183,192,122, 78, 8,132,133, 48, 0, 34,184,158,174,149,242, 43, 1, 40,251, +253, 82,167,189, 99,169,119, 44,245,184,177,212,166, 79, 78, 16,208, 82, 36,168,229,185, 45,166, 16,191,225,137, 33, 84, 31, 13, +116,217,133, 28, 75,129,104,251,251, 77,254, 15,176, 49,196,128, 26,186,125, 59, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130, 0}; diff -Nru blender-2.61/source/blender/editors/datafiles/splash.png.c blender-2.62/source/blender/editors/datafiles/splash.png.c --- blender-2.61/source/blender/editors/datafiles/splash.png.c 2011-12-13 19:54:09.000000000 +0000 +++ blender-2.62/source/blender/editors/datafiles/splash.png.c 2012-02-15 19:38:23.000000000 +0000 @@ -1,6113 +1,5898 @@ /* DataToC output of file */ -int datatoc_splash_png_size= 195415; +int datatoc_splash_png_size= 188517; char datatoc_splash_png[]= { -137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 1,245, 0, 0, 1, - 26, 8, 6, 0, 0, 0, 8, 90,206, 70, 0, 0, 10, 79,105, 67, 67, 80, 80,104,111,116,111,115,104,111,112, 32, 73, 67, 67, 32, -112,114,111,102,105,108,101, 0, 0,120,218,157, 83,103, 84, 83,233, 22, 61,247,222,244, 66, 75,136,128,148, 75,111, 82, 21, 8, - 32, 82, 66,139,128, 20,145, 38, 42, 33, 9, 16, 74,136, 33,161,217, 21, 81,193, 17, 69, 69, 4, 27,200,160,136, 3,142,142,128, -140, 21, 81, 44, 12,138, 10,216, 7,228, 33,162,142,131,163,136,138,202,251,225,123,163,107,214,188,247,230,205,254,181,215, 62, -231,172,243,157,179,207, 7,192, 8, 12,150, 72, 51, 81, 53,128, 12,169, 66, 30, 17,224,131,199,196,198,225,228, 46, 64,129, 10, - 36,112, 0, 16, 8,179,100, 33,115,253, 35, 1, 0,248,126, 60, 60, 43, 34,192, 7,190, 0, 1,120,211, 11, 8, 0,192, 77,155, -192, 48, 28,135,255, 15,234, 66,153, 92, 1,128,132, 1,192,116,145, 56, 75, 8,128, 20, 0, 64,122,142, 66,166, 0, 64, 70, 1, -128,157,152, 38, 83, 0,160, 4, 0, 96,203, 99, 98,227, 0, 80, 45, 0, 96, 39,127,230,211, 0,128,157,248,153,123, 1, 0, 91, -148, 33, 21, 1,160,145, 0, 32, 19,101,136, 68, 0,104, 59, 0,172,207, 86,138, 69, 0, 88, 48, 0, 20,102, 75,196, 57, 0,216, - 45, 0, 48, 73, 87,102, 72, 0,176,183, 0,192,206, 16, 11,178, 0, 8, 12, 0, 48, 81,136,133, 41, 0, 4,123, 0, 96,200, 35, - 35,120, 0,132,153, 0, 20, 70,242, 87, 60,241, 43,174, 16,231, 42, 0, 0,120,153,178, 60,185, 36, 57, 69,129, 91, 8, 45,113, - 7, 87, 87, 46, 30, 40,206, 73, 23, 43, 20, 54, 97, 2, 97,154, 64, 46,194,121,153, 25, 50,129, 52, 15,224,243,204, 0, 0,160, -145, 21, 17,224,131,243,253,120,206, 14,174,206,206, 54,142,182, 14, 95, 45,234,191, 6,255, 34, 98, 98,227,254,229,207,171,112, - 64, 0, 0,225,116,126,209,254, 44, 47,179, 26,128, 59, 6,128,109,254,162, 37,238, 4,104, 94, 11,160,117,247,139,102,178, 15, - 64,181, 0,160,233,218, 87,243,112,248,126, 60, 60, 69,161,144,185,217,217,229,228,228,216, 74,196, 66, 91, 97,202, 87,125,254, -103,194, 95,192, 87,253,108,249,126, 60,252,247,245,224,190,226, 36,129, 50, 93,129, 71, 4,248,224,194,204,244, 76,165, 28,207, -146, 9,132, 98,220,230,143, 71,252,183, 11,255,252, 29,211, 34,196, 73, 98,185, 88, 42, 20,227, 81, 18,113,142, 68,154,140,243, - 50,165, 34,137, 66,146, 41,197, 37,210,255,100,226,223, 44,251, 3, 62,223, 53, 0,176,106, 62, 1,123,145, 45,168, 93, 99, 3, -246, 75, 39, 16, 88,116,192,226,247, 0, 0,242,187,111,193,212, 40, 8, 3,128,104,131,225,207,119,255,239, 63,253, 71,160, 37, - 0,128,102, 73,146,113, 0, 0, 94, 68, 36, 46, 84,202,179, 63,199, 8, 0, 0, 68,160,129, 42,176, 65, 27,244,193, 24, 44,192, - 6, 28,193, 5,220,193, 11,252, 96, 54,132, 66, 36,196,194, 66, 16, 66, 10,100,128, 28,114, 96, 41,172,130, 66, 40,134,205,176, - 29, 42, 96, 47,212, 64, 29, 52,192, 81,104,134,147,112, 14, 46,194, 85,184, 14, 61,112, 15,250, 97, 8,158,193, 40,188,129, 9, - 4, 65,200, 8, 19, 97, 33,218,136, 1, 98,138, 88, 35,142, 8, 23,153,133,248, 33,193, 72, 4, 18,139, 36, 32,201,136, 20, 81, - 34, 75,145, 53, 72, 49, 82,138, 84, 32, 85, 72, 29,242, 61,114, 2, 57,135, 92, 70,186,145, 59,200, 0, 50,130,252,134,188, 71, - 49,148,129,178, 81, 61,212, 12,181, 67,185,168, 55, 26,132, 70,162, 11,208,100,116, 49,154,143, 22,160,155,208,114,180, 26, 61, -140, 54,161,231,208,171,104, 15,218,143, 62, 67,199, 48,192,232, 24, 7, 51,196,108, 48, 46,198,195, 66,177, 56, 44, 9,147, 99, -203,177, 34,172, 12,171,198, 26,176, 86,172, 3,187,137,245, 99,207,177,119, 4, 18,129, 69,192, 9, 54, 4,119, 66, 32, 97, 30, - 65, 72, 88, 76, 88, 78,216, 72,168, 32, 28, 36, 52, 17,218, 9, 55, 9, 3,132, 81,194, 39, 34,147,168, 75,180, 38,186, 17,249, -196, 24, 98, 50, 49,135, 88, 72, 44, 35,214, 18,143, 19, 47, 16,123,136, 67,196, 55, 36, 18,137, 67, 50, 39,185,144, 2, 73,177, -164, 84,210, 18,210, 70,210,110, 82, 35,233, 44,169,155, 52, 72, 26, 35,147,201,218,100,107,178, 7, 57,148, 44, 32, 43,200,133, -228,157,228,195,228, 51,228, 27,228, 33,242, 91, 10,157, 98, 64,113,164,248, 83,226, 40, 82,202,106, 74, 25,229, 16,229, 52,229, - 6,101,152, 50, 65, 85,163,154, 82,221,168,161, 84, 17, 53,143, 90, 66,173,161,182, 82,175, 81,135,168, 19, 52,117,154, 57,205, -131, 22, 73, 75,165,173,162,149,211, 26,104, 23,104,247,105,175,232,116,186, 17,221,149, 30, 78,151,208, 87,210,203,233, 71,232, -151,232, 3,244,119, 12, 13,134, 21,131,199,136,103, 40, 25,155, 24, 7, 24,103, 25,119, 24,175,152, 76,166, 25,211,139, 25,199, - 84, 48, 55, 49,235,152,231,153, 15,153,111, 85, 88, 42,182, 42,124, 21,145,202, 10,149, 74,149, 38,149, 27, 42, 47, 84,169,170, -166,170,222,170, 11, 85,243, 85,203, 84,143,169, 94, 83,125,174, 70, 85, 51, 83,227,169, 9,212,150,171, 85,170,157, 80,235, 83, - 27, 83,103,169, 59,168,135,170,103,168,111, 84, 63,164,126, 89,253,137, 6, 89,195, 76,195, 79, 67,164, 81,160,177, 95,227,188, -198, 32, 11, 99, 25,179,120, 44, 33,107, 13,171,134,117,129, 53,196, 38,177,205,217,124,118, 42,187,152,253, 29,187,139, 61,170, -169,161, 57, 67, 51, 74, 51, 87,179, 82,243,148,102, 63, 7,227,152,113,248,156,116, 78, 9,231, 40,167,151,243,126,138,222, 20, -239, 41,226, 41, 27,166, 52, 76,185, 49,101, 92,107,170,150,151,150, 88,171, 72,171, 81,171, 71,235,189, 54,174,237,167,157,166, -189, 69,187, 89,251,129, 14, 65,199, 74, 39, 92, 39, 71,103,143,206, 5,157,231, 83,217, 83,221,167, 10,167, 22, 77, 61, 58,245, -174, 46,170,107,165, 27,161,187, 68,119,191,110,167,238,152,158,190, 94,128,158, 76,111,167,222,121,189,231,250, 28,125, 47,253, - 84,253,109,250,167,245, 71, 12, 88, 6,179, 12, 36, 6,219, 12,206, 24, 60,197, 53,113,111, 60, 29, 47,199,219,241, 81, 67, 93, -195, 64, 67,165, 97,149, 97,151,225,132,145,185,209, 60,163,213, 70,141, 70, 15,140,105,198, 92,227, 36,227,109,198,109,198,163, - 38, 6, 38, 33, 38, 75, 77,234, 77,238,154, 82, 77,185,166, 41,166, 59, 76, 59, 76,199,205,204,205,162,205,214,153, 53,155, 61, - 49,215, 50,231,155,231,155,215,155,223,183, 96, 90,120, 90, 44,182,168,182,184,101, 73,178,228, 90,166, 89,238,182,188,110,133, - 90, 57, 89,165, 88, 85, 90, 93,179, 70,173,157,173, 37,214,187,173,187,167, 17,167,185, 78,147, 78,171,158,214,103,195,176,241, -182,201,182,169,183, 25,176,229,216, 6,219,174,182,109,182,125, 97,103, 98, 23,103,183,197,174,195,238,147,189,147,125,186,125, -141,253, 61, 7, 13,135,217, 14,171, 29, 90, 29,126,115,180,114, 20, 58, 86, 58,222,154,206,156,238, 63,125,197,244,150,233, 47, -103, 88,207, 16,207,216, 51,227,182, 19,203, 41,196,105,157, 83,155,211, 71,103, 23,103,185,115,131,243,136,139,137, 75,130,203, - 46,151, 62, 46,155, 27,198,221,200,189,228, 74,116,245,113, 93,225,122,210,245,157,155,179,155,194,237,168,219,175,238, 54,238, -105,238,135,220,159,204, 52,159, 41,158, 89, 51,115,208,195,200, 67,224, 81,229,209, 63, 11,159,149, 48,107,223,172,126, 79, 67, - 79,129,103,181,231, 35, 47, 99, 47,145, 87,173,215,176,183,165,119,170,247, 97,239, 23, 62,246, 62,114,159,227, 62,227, 60, 55, -222, 50,222, 89, 95,204, 55,192,183,200,183,203, 79,195,111,158, 95,133,223, 67,127, 35,255,100,255,122,255,209, 0,167,128, 37, - 1,103, 3,137,129, 65,129, 91, 2,251,248,122,124, 33,191,142, 63, 58,219,101,246,178,217,237, 65,140,160,185, 65, 21, 65,143, -130,173,130,229,193,173, 33,104,200,236,144,173, 33,247,231,152,206,145,206,105, 14,133, 80,126,232,214,208, 7, 97,230, 97,139, -195,126, 12, 39,133,135,133, 87,134, 63,142,112,136, 88, 26,209, 49,151, 53,119,209,220, 67,115,223, 68,250, 68,150, 68,222,155, -103, 49, 79, 57,175, 45, 74, 53, 42, 62,170, 46,106, 60,218, 55,186, 52,186, 63,198, 46,102, 89,204,213, 88,157, 88, 73,108, 75, - 28, 57, 46, 42,174, 54,110,108,190,223,252,237,243,135,226,157,226, 11,227,123, 23,152, 47,200, 93,112,121,161,206,194,244,133, -167, 22,169, 46, 18, 44, 58,150, 64, 76,136, 78, 56,148,240, 65, 16, 42,168, 22,140, 37,242, 19,119, 37,142, 10,121,194, 29,194, -103, 34, 47,209, 54,209,136,216, 67, 92, 42, 30, 78,242, 72, 42, 77,122,146,236,145,188, 53,121, 36,197, 51,165, 44,229,185,132, - 39,169,144,188, 76, 13, 76,221,155, 58,158, 22,154,118, 32,109, 50, 61, 58,189, 49,131,146,145,144,113, 66,170, 33, 77,147,182, -103,234,103,230,102,118,203,172,101,133,178,254,197,110,139,183, 47, 30,149, 7,201,107,179,144,172, 5, 89, 45, 10,182, 66,166, -232, 84, 90, 40,215, 42, 7,178,103,101, 87,102,191,205,137,202, 57,150,171,158, 43,205,237,204,179,202,219,144, 55,156,239,159, -255,237, 18,194, 18,225,146,182,165,134, 75, 87, 45, 29, 88,230,189,172,106, 57,178, 60,113,121,219, 10,227, 21, 5, 43,134, 86, - 6,172, 60,184,138,182, 42,109,213, 79,171,237, 87,151,174,126,189, 38,122, 77,107,129, 94,193,202,130,193,181, 1,107,235, 11, - 85, 10,229,133,125,235,220,215,237, 93, 79, 88, 47, 89,223,181, 97,250,134,157, 27, 62, 21,137,138,174, 20,219, 23,151, 21,127, -216, 40,220,120,229, 27,135,111,202,191,153,220,148,180,169,171,196,185,100,207,102,210,102,233,230,222, 45,158, 91, 14,150,170, -151,230,151, 14,110, 13,217,218,180, 13,223, 86,180,237,245,246, 69,219, 47,151,205, 40,219,187,131,182, 67,185,163,191, 60,184, -188,101,167,201,206,205, 59, 63, 84,164, 84,244, 84,250, 84, 54,238,210,221,181, 97,215,248,110,209,238, 27,123,188,246, 52,236, -213,219, 91,188,247,253, 62,201,190,219, 85, 1, 85, 77,213,102,213,101,251, 73,251,179,247, 63,174,137,170,233,248,150,251,109, - 93,173, 78,109,113,237,199, 3,210, 3,253, 7, 35, 14,182,215,185,212,213, 29,210, 61, 84, 82,143,214, 43,235, 71, 14,199, 31, -190,254,157,239,119, 45, 13, 54, 13, 85,141,156,198,226, 35,112, 68,121,228,233,247, 9,223,247, 30, 13, 58,218,118,140,123,172, -225, 7,211, 31,118, 29,103, 29, 47,106, 66,154,242,154, 70,155, 83,154,251, 91, 98, 91,186, 79,204, 62,209,214,234,222,122,252, - 71,219, 31, 15,156, 52, 60, 89,121, 74,243, 84,201,105,218,233,130,211,147,103,242,207,140,157,149,157,125,126, 46,249,220, 96, -219,162,182,123,231, 99,206,223,106, 15,111,239,186, 16,116,225,210, 69,255,139,231, 59,188, 59,206, 92,242,184,116,242,178,219, -229, 19, 87,184, 87,154,175, 58, 95,109,234,116,234, 60,254,147,211, 79,199,187,156,187,154,174,185, 92,107,185,238,122,189,181, -123,102,247,233, 27,158, 55,206,221,244,189,121,241, 22,255,214,213,158, 57, 61,221,189,243,122,111,247,197,247,245,223, 22,221, -126,114, 39,253,206,203,187,217,119, 39,238,173,188, 79,188, 95,244, 64,237, 65,217, 67,221,135,213, 63, 91,254,220,216,239,220, -127,106,192,119,160,243,209,220, 71,247, 6,133,131,207,254,145,245,143, 15, 67, 5,143,153,143,203,134, 13,134,235,158, 56, 62, - 57, 57,226, 63,114,253,233,252,167, 67,207,100,207, 38,158, 23,254,162,254,203,174, 23, 22, 47,126,248,213,235,215,206,209,152, -209,161,151,242,151,147,191,109,124,165,253,234,192,235, 25,175,219,198,194,198, 30,190,201,120, 51, 49, 94,244, 86,251,237,193, -119,220,119, 29,239,163,223, 15, 79,228,124, 32,127, 40,255,104,249,177,245, 83,208,167,251,147, 25,147,147,255, 4, 3,152,243, -252, 99, 51, 45,219, 0, 0, 0, 6, 98, 75, 71, 68, 0,255, 0,255, 0,255,160,189,167,147, 0, 0, 0, 9,112, 72, 89,115, 0, - 0, 11, 19, 0, 0, 11, 19, 1, 0,154,156, 24, 0, 0, 0, 7,116, 73, 77, 69, 7,219, 12, 13, 17, 26, 29, 77,120, 44,213, 0, - 0, 32, 0, 73, 68, 65, 84,120,218,236,189,121,188,109, 89, 85,223,251, 29,115,206,213,236,230,180,183,173, 14,170,138, 70, 16, -165,171, 2, 84, 8, 2, 94, 94,130,109, 52, 84,229, 35, 79, 77, 66,158, 85, 81,223, 67,226, 83, 11, 19, 99, 72,158,137,162,143, - 72, 64,125, 84,105,162,190,232,203,123, 20, 24,141,138, 13, 85, 98, 20,108,128,139, 2, 82,101, 81,197,173,134,186,213,220,123, - 79,115,207, 57,187, 91,107,205, 57,223, 31,115,174,181,215, 57,220,170,219, 80, 13,133,107,240, 41,238, 57,251,236,189,246,106, -230, 26,191, 49,126,227, 55,198,130,206, 58,235,172,179,206, 58,235,172,179,206, 58,235,172,179,206, 58,235,172,179,206, 58,235, -172,179,206, 58,235,172,179,206, 58,235,172,179,206, 58,235,172,179,206, 58,235,172,179,206, 58,235,172,179,206, 58,235,172,179, -206, 58,235,172,179,206, 58,235,172,179,206, 58,235,172,179,206, 58,235,172,179,206, 58, 59,119,147, 39,227, 75,253,111,188,241, - 91, 41,253,155, 80,164, 40,255,110,254,254, 47,255,170, 8,190,187, 28,157,117,214, 89,103,157,117,246, 20, 2,117,255,155,223, -245,106,182, 70,127,200,230,200,179,176, 4,251, 87,133,170,248,127, 40,182,174,151,107,111,222,233, 46, 73,103,157,117,214, 89, -103,157, 93,152,169, 39,252, 27, 31, 56, 54,224,193,123,224,228,241, 9,247,222, 49,230,158, 99, 99,188,126, 3,249,202, 39,253, -239,124,247,179,187, 75,210, 89,103,157,117,214, 89,103, 79, 21, 80,255,103, 31,250, 29,122,234, 71, 24,166,125, 4,195,201, 7, - 28,199,110, 31, 51, 45, 47,199, 37,183,251,223,249,238,127,208, 93,150,206, 58,235,172,179,206, 58, 59,127,147, 39,235,139,253, -187,190,234,117, 76,171,247, 50,243, 25,182,154,144,230,138,167, 61,211,176,186, 47,197,206,222,129, 74,223, 34, 95,255,174, 89, -119,137, 58,235,172,179,206, 58,235,236,139, 28,212, 1,252,141, 87, 61,131,145,126, 63, 83,251,108, 74, 59, 70,107,184,248, 10, -197,225,139,115, 92,249, 9,180,255,251,242,186,119,223,243, 84, 57,153,222,251,171,128,149,248,235, 49, 17, 57,246,165,188,120, -254,182, 29,111,103,157,117,214, 89, 7,234,103, 3,134,159,126,254,128, 36,249, 85,198,254,155, 41,253, 20, 28, 28,186, 76,184, -232,105, 61,180, 20, 36,213, 55,202,223,189,241, 3,143, 49, 24, 93, 9, 92,121,142,111,223, 16,145,163,231,184,221, 15, 0, 71, -226,175,111, 17,145,183,125,137,131,250,223,170,227,125,140,206,153,136, 72,215,233,209, 89,103,157, 61, 46,102,190, 96, 39,245, -193, 87, 25, 62,151,102,103,252,227,118, 33, 44,164, 30, 14,193, 33,224,244,116, 30, 68,100, 11, 66, 50, 19, 88, 5,191,246,102, -238,187, 47, 99,199,253, 79, 56, 10, 54, 78, 65,127, 56,101,249, 64,130, 77,255,192,255,222,255,250, 99,100,127,253, 19,242,234, - 63,170, 30,163,227,190, 6,248,201,243,112,196, 0, 55, 3,183,136,200, 77,221,178,249,146, 0, 87, 37, 34,174,245,251, 37,192, -203,128, 23, 1,207, 3,174, 0, 46, 1, 22, 9,218,147, 77,224, 94,224,207,129,255, 42, 34,127,122, 65, 81,244, 89, 0,221,123, -255,194,184, 62,143,196,239, 63, 8, 20,192, 3,192,167,129, 15, 1,191, 45, 34,119, 60,194,231, 15, 2, 95, 1,124,101,235,223, -231, 1,195,214, 62, 72,183, 2, 58,235,172,203,212,119, 59,143,183,190, 85,177,120,235,117, 88,249,151,136,236, 71,107,135, 8, - 40, 21,254, 19, 1,173, 5,165, 64,199,223,149, 2, 21, 95, 19, 1,169,223,171, 44, 90,207,240, 50, 64, 90,239,213, 26, 28,138, - 60, 77, 16,251, 63,232,113,141,188,242, 93, 39, 31, 3,135,126,195,249,128,250, 30,187, 5,184, 86, 68, 54,186, 76,253, 75,231, -120,125,140,220,206,195,254, 24,120,163,136,124,246, 49,250,254,139,129,159, 1,174, 61,199,224, 64, 46,244, 56, 58, 80,239,172, -179, 46, 83,255,124, 91,190,245,251,113,234, 63, 80,249, 2, 45, 30,208,136,128, 39,252, 23,126, 22,148, 7,231, 65, 73,248,131, -114,160, 37,188, 65,121, 80, 30,196,107,156, 77,208,218, 71,175, 19,183,227, 65, 41, 71,105,103,104,245,181,140,253,223,248, 91, -191,239,181,242,117, 63,247,241,199,248, 60,220,242, 40,127, 59,114,134,223, 63,224,189,127,237,153,128,189,179,191, 53,246, 74, -224,163,222,251,215,136,200, 95,125,129,128,254, 60,224, 15, 99, 86,222, 89,103,157,117,246,196,130,186,127, 43, 10,231,191,135, -113,233,177,101,137,117, 32, 34, 33,239,151,144,255, 71,220, 6, 97, 92,218, 62, 90,161,246, 29, 4, 99,192,122, 36,100,232, 1, -228, 69,129, 85, 1,224,149,155,103,234,162,200,242,100,134, 0,150, 2,203, 10, 36, 71,253,173,111,250, 30, 94,243, 31,111,124, -172,106,147, 34,242,218,179, 56,221,154,174,175,235,240, 87, 1,215, 1, 93, 13,249, 75,207, 70,192,239, 1, 31, 0,142, 18, 40, -247, 77, 2,125,253, 34,224,159, 2,111,136,239, 93, 1,254,187,247,254,185, 34, 50,186, 64, 64,127, 6,240, 65,224, 64,124,169, - 0,126, 17,248,117, 2,221,126, 10,200, 9, 84,252,151, 3, 47, 7,190,241, 81, 54,121, 42,126,238,211,192,109,173,159, 79,116, -151,182,179,206,190,244,237,194,233,247,119,190,252,122,182,167,239,166,178, 17,188, 91, 91, 19,153,255, 92, 89, 55, 46, 80,178, -176,130, 44, 44,204,105,119,173, 17,165, 67, 6, 47,177, 84,174, 36, 80,238, 74,133,141, 41, 67,150,245,102,212,239, 67, 11, 34, -138,220, 24,112,239,101,188,244,143,228,155,223, 58,190, 0, 71,186,139,126, 63, 23, 58, 50,138,235, 62,198, 92,237,125, 84, 68, -174,222,243,158,142,126,127,234,236,123, 42, 34, 69,235,247,143, 0, 63, 7,188, 71, 68, 38,103,249,236, 63, 0,254,223, 86, 80, -124,131,136,252,212, 5,236,131, 0,127, 20,179,126,128,187,128,175, 23,145, 59, 31,135,227,245,231,179,222, 59,235,172,179,191, - 69,153, 58,128,188,233,195, 55,250,255,240,226, 91,209,234,153, 56, 37,136,115,243,191,170,248,179,157,145, 14,190,122, 54,205, -127,178,159,244,112,206, 5,208, 22,192, 57,124,177,131,104, 65, 93,246, 2,212,129,103, 34,139,135,145,124, 17,170, 25,110,116, - 18,191,253, 32,179,147,159,201,152,237,128,238,129, 88, 80, 26,217,113,164,131,236,245, 12,183,174,240,191,255,131, 95, 43,127, -247,255, 28, 61,222, 39, 74, 68,142,121,239,111,142, 25,122,157,173, 63, 22,206,118,101,207,182,142, 62, 22,180,254, 30,133,255, - 5,181,155, 61, 22,219,120, 34,142,119,207,126,158,211,246,218,128, 30,127,127,233,121,172,133,247,121,239,127, 26,248,145,248, -210,183, 2, 63,117, 1,187,254,143, 91,128,190, 14,188, 90, 68,238,239,220, 82,103,157,117,246,132,131, 58,128,252,192,199,239, -138,217,197,153,157,237,175,124,243,243,153, 86,223, 49,212,158,170,174,171, 79,167,248,217, 8,236, 8,253,236,191,131,185,250, - 13,232, 43,190,234,243, 62, 91,143,186,243,235,247, 80,125,246, 86,236,189, 31, 70,116, 10,222,227, 5,138,113, 65,218, 79,175, - 66,251,247,251,143, 93,119, 68,174,190,169,124, 2,206,215, 99,210,135, 29,129,237, 58,130,202,249,170, 51,252,253, 24,112, 19, -112,211, 35, 1,148,247,254, 39, 91,159,189, 89, 68,110,106,109,247, 58,246,180,236,197,109,190,237, 92,212,251,222,251,235,128, - 27, 30, 97, 27,143,186, 95,143,199,241, 62,202,177,222, 16,183,187,210,122,251, 45,192,107,159,128,181,240, 75, 45, 80,191,208, -241,198,111,106,253,124, 67, 7,232,157,117,214,217,147, 10,234,143,234,200,255,243,107,175,103,103,250,110, 42,177,149,245,248, -114,134,159,142,161,154,129,241,100, 95,255, 35,152,171,191,253,236,129,195,234,229, 36,171,255, 20,117,248,249, 84, 31,253, 69, - 80, 54, 64,190, 8, 20,174,160,159,188,146,141,254,191, 6,126,244, 9, 56, 95,109,240,184,160,236,210,123,127, 4,120,207,158, -109,237,181, 43, 9,229,129,235,188,247,215, 62, 66,159,252, 85,204,169,239, 91,226, 32,152, 27, 31,133, 65,184, 18,184,209,123, -127,149,136, 92,255, 40,224,123, 99, 4,223, 71,219,175,107,188,247,175,125, 2,143,247, 76,199,250,129,179,108,243,241,182,251, - 90, 63, 15, 47, 96, 29, 92, 13,188, 48,254,186, 6,252,151,206, 29,117,214, 89,103, 95,116,160,238,111,252,198, 62,110,242, 46, - 70,254,141, 88,153,225, 75,235,119,118,250, 84, 37,136, 71, 18,200,190,245, 39,208, 95,241, 13,205,103,182, 38, 51,126,255,175, -238,225,247, 63,113, 15,235, 59, 19, 18, 45, 60,247,226, 85,190,249,234,103,242,226,103, 92, 4,128,190,236, 37, 72,186, 64,249, -161,183, 67,106, 8, 74,122, 96, 82, 86, 36,230, 95,250, 15,254,243, 95,150, 87,255,204, 93,143, 91,144, 18, 0,239,154, 61, 25, -225,249,110,227,154, 8,112,109, 59, 26,183, 85, 7, 9,237,108,246, 74,230, 74,251,163,103, 9, 54,222,211,202,172,111,142,219, -173, 1,177,189,223,215,121,239,143, 61, 66,253,251, 39,207, 0,232,237,109,213,251,118,213, 25,142,227,137, 58,222,149, 61,128, -190,209,218,191, 43,159,192,123,231,146,214,207, 23,210,102,249,154,214,207,255, 77, 68,186,145,200,157,117,214,217, 23, 23,168, -251,119,191,242, 89,204,118,222, 79,165,158,137,103,130, 29,123,202, 25, 56, 7, 70, 35,213,136,228,229,255,203, 46, 64,255,243, - 59, 31,228,135,126,237, 79, 56,118,106,155, 60, 75, 72,140, 66,121,248,196,231,214,121,239,159,253, 13,223,116,245, 51,248, 87, -215,252, 29,250, 89,130, 58,244, 28,204, 87, 92, 75,245,151,191, 4, 11,135,106,133,189,195, 11, 84,250, 63, 2,223,240, 56, 2, -250,141,123, 64,227,166,243,220,198,149,113, 27,181, 29, 3,174, 23,145,189,193,193,219,246,100,183,245,119, 95,253, 40,155,191, -161, 5,192,215,239,165,176,227,119,191,167, 5,158, 55,120,239,119, 81,221,145,114,191,110, 15,248, 94,187,167,142,222,222,183, - 35, 79,210,241,222,208,218,222, 91, 68,228,230, 51, 92,171, 39,194,190,173,245,243,199, 46,224,243,237, 26,254,159,196,125,223, - 79,168,179,191, 62,174,181, 69, 66,173,253,179, 4, 65,221, 47,117,163,120, 59,235,172,179, 39, 4,212,253,207,189,226,239, 49, -241,191, 65,133, 65,217, 49, 85, 1,182,138,138,118, 1,111,145,253,151, 97, 94,250, 93,205,103,238,124,104,131,239,250,185,223, -231,196,164,162, 63,232, 81,106, 77,146,104, 82, 45,104,159, 34,182,226,125,127,113, 23, 90, 41,126,252, 13,175, 10, 25,251, 51, - 95,141,189,227,247,192,238, 64, 50, 12,192,110,109,133,150, 35,254,143,223,124,145,188,242, 29, 15, 94, 0,104,223,240, 40,127, - 62,114, 6, 0, 59, 19, 56,157,205,110,220,147, 93, 94,253, 72,117,105, 17,185, 37,210,219,117, 70,122,149,247,254,186,179,212, -195,111, 17,145,107, 31, 97,123,199,188,247,111,137,219,171,179,221, 35, 49, 8,216, 11,150, 53, 96,158,177, 15,191,181,111, 31, -123, 18,143,247,216, 35,109,239,137,152, 29,224,189, 31, 2,111,110,189,244,155, 23,176,153, 47,111,253,252, 73,239,253,183, 16, - 90,217,246,239,121,223, 69,241,191, 87, 0, 63,226,189,127, 55,240,191,119,153,125,103,157,117,246,184,128,186,191,241,170,132, -105,239,199,153,249, 31,166,146, 25,186,154, 97, 3,213, 78, 82,203,221, 4, 95, 22,152,103,191, 18, 25,206,125,214, 91,126,237, -195,220,121,255,105, 88, 26,114,122,167, 2,177,104,129,190, 22,246, 15, 12, 43, 61,195,210,210,144,223,248,200,157,188,234,121, - 79,231,200, 11,174, 0,109,208, 87,190,146,234,175,126, 5, 6,139,224, 29, 40,113, 36, 58,165,116,223, 2,188,251, 2, 14,227, - 92,167,203,221, 68, 16,106,157, 23,160,199, 26,112, 59, 48,120,203,217,192, 71, 68,142,122,239,111,106,129,237,145,179,176, 3, -215,159,101,123,183,120,239,143,178,155,234,174,247,239,154, 61, 44,196,219, 30,109,255, 90,251,118,221,147,116,188,111,123,146, - 7,255,252, 28,115,250,253,179,192,175, 93,192, 54, 86,247,100,237,239,230,236, 45,166, 26,248, 62,224,133,222,251, 35, 34, 50, -237, 92, 88,103,157,117,214,182, 47,232,121,234,254,157, 47,187,148,237,228,195, 76,237, 15, 83,250, 49, 98, 45,182, 12,174,199, - 8,104, 17,140,136,104,133, 24, 65, 93,252, 21,205,103,239,126,120,147,223,253,171,251,160,223,155,247,166,107,141, 69,177, 61, -179,220,125,114,204,177, 19, 99, 74, 47, 56,173,185,245, 83,247,206, 1, 96,255, 51,241,147, 45,160,138, 20,188,135,202,129,227, -165,143,243,249,186, 38,102,145,231, 75,241,182, 1,110,227, 60,230,199,223,178,231,187, 31,201,142,158, 35, 45,123,244, 17,246, -233,200, 30,128, 61,151,253,187,249, 73, 58,222, 99, 79,230,252,125,239,253, 63, 7,106,186,201, 3,215,237,109,143, 59, 71, 91, -110,253,252,142, 22,160,223, 10,124, 11,225,105, 9,105,252,247, 91, 8, 19,231,106,123, 57,240,179,157,251,234,172,179,206, 30, -179, 76,221,191,235,171, 94,206,216,222, 74,169, 18,140,140,209, 46,100,205, 30,161, 18,193,136, 71, 75,156, 14,103, 17,147,162, - 86,158,214,124,254,158,147, 91, 76,198, 37, 44,102, 52, 35,232,234,241, 24, 74,129,247,108,238,148,148, 69,197,165, 75,134,237, -233,188, 99, 77, 22, 14,133,164,101, 54,130,222, 66,152, 63, 91, 86, 96,120,129,247,111, 85, 34,111,117,231,121, 56,111,121,148, -191, 93, 25, 65,234, 74, 2, 53,220,168,191,207, 35, 91, 60,242, 8,192,202, 57,100,215,187, 50,224, 71, 16,144,157, 43,115,112, -236, 81,142,241,188,182,181,119,223,158,192,227, 61,250,100,221, 44,222,251,255, 25,120,123,235,165,127, 43, 34,127,248, 24, 4, -212,189,214,246,254,245,158,247,157, 0,254, 59, 97,114,221,191, 5,254, 85,124,253,159,120,239,223, 33, 34,127,221,185,177,206, - 58,235,236,130, 65,221,191,231, 26,205,189,119,255, 0,219,213, 79, 97,165, 32, 99,138,114,130,245,158,210, 9, 90, 82, 18, 54, -176,126,128,209, 33,107,119, 49, 13,241,243,135,172, 29, 92,234,163,211, 4,235, 0, 47, 97,206,187,143,201,143,143,175,105,197, -104, 92,114,239,116, 74,246,130,214,174,122, 11,190,132,106, 10,106, 17,188, 21,176, 30,235, 47,230,119,215, 18,224,188,234,141, -231, 50, 9, 45,214,221,111,136,192, 94,183, 84, 93,125,142, 95,209,110, 51,187, 50, 78, 98,187, 16,123, 36,134,224, 11,165,162, - 47, 8,132,227,123,175,122,130,143,247, 73, 1,117,239,253, 63, 4,126,165,149, 81,223, 40, 34,111,253, 2, 54,185,205,110, 10, -254, 3,103, 0,244,189,235,244,199,188,247, 95, 29,175,151, 34,136,234,126,176,115, 99,157,117,214,217, 5,129,186,191,241,170, - 37,238,249,236,123, 41,228, 8, 34, 19,122, 26, 20, 66,233, 60, 51,107, 72, 85, 74, 38,223, 13,254, 74, 44,111,193, 51, 69, 5, -250,157,178,196,157,186, 11,117,217, 75, 0,120,238, 37,251,120,217,179, 14,242,167,183,159, 12,243,224,189,132,217,239, 62, 4, - 1, 0,184,144,233, 79,215, 71, 60,235,240,220,191,251,173, 7, 96,182, 5,197,216,199,136, 0, 28, 30, 5,244,182, 31,151, 17, -152, 34,242,182,152, 69,214,245,247,115, 17,175,157, 9,156,206,231, 89,238, 79,134,109, 60, 6,239,125, 42, 29,239,185, 0,250, -183, 19,250,200,117,124,233, 87,129,239,253, 2, 55,187, 23,212,223,121,142,159,123,103, 43, 8,123,117,231,194, 58,235,172,179, - 11, 2,117,255,246,151,190,128, 53,251, 91, 84,114, 25,137, 30,147,171, 0,158,133,243, 20, 54, 39,151, 41, 61,249,102,249,223, - 62,242,251,254,237, 87,255, 56, 78, 4, 65,130,242, 93,192, 40,252,195,115,166, 80, 41,225, 71,191,245,106,190,254,182,223,134, -105, 9, 89, 26,222, 71, 4,117, 71,160,243,119,198,188,232,203, 47,225, 59,191,246,121,205,103,221,137,219,241,190, 4, 91,132, - 55,122, 15, 56, 5,242, 32,175,186,188,120,188, 78, 86, 4,246,182,168,238, 26,206,179,181,141, 64,129, 95,104, 91,210, 83,241, -169,112, 79,233,227,245,222,127, 7,240,203, 45, 64,127, 31,240,143,219,207, 98,191, 64,187, 31,120,122,235,247, 63, 63,199,207, -181,223,247,180,206,133,117,214, 89,103,231, 5,234, 30,132,159,126,209, 27,153,218, 95,192, 73, 69, 79,143,201,148,224,189,103, - 98, 61,206, 15, 24,234, 59,232,201, 55,201, 63,251,139,248, 32, 10,185, 11,241,224,241, 40, 17,148, 64,222,199,222,243, 33,204, -198, 61,200,202,229, 0,188,238, 69,151,115,211,247,188,154, 55,255,167, 63, 97,188, 57,131, 60, 11,207, 94,247, 30,138, 18,198, - 19, 94,252,156, 67,188,247,135,190,129, 65,158,132, 77,151, 19,236,109,239, 67,210, 44,204,130,247, 14,156, 11, 89,186,241,127, -121, 1,245,244,243,181, 91, 90,153,210,145, 11,248,252, 77, 95,234, 15,122,249, 82, 57, 94,239,253, 27,129, 95, 96, 94,255,254, -109,224,219, 69,196, 62, 6,155,255,107,130,224,173,182,205,115,252, 92,251,125, 75,157, 11,235,172,179,206,218,118,118,245,251, -219,175,190,142, 82,253, 34,168, 41, 11, 73, 73, 79, 11, 30,207,200,130,146, 1,125,253,235, 28,144,151,206, 1, 29,200,249, 52, - 42,148,185,129, 0,212,198, 64,181, 67,249,161,159,217,181,249,239,254,186,231,241,103, 63,241,122,222,252,141, 95,201, 21,171, - 25,185, 47, 25, 42,203,215, 60,107, 63, 63,251,189,175,225,143,255,221, 53, 92,113,104,238,187,170,143,254, 34,126,243, 30, 72, - 50,144, 16, 57, 80,197,126,120,241, 71,191, 72,207,243, 35,169,206,159,234,251,119,228, 41,122,188,231, 2,232,223, 67,232, 27, -175,239,145,223, 5, 94, 47, 34,143,213, 51, 6,246, 62,131,125,249, 28, 63,183,124, 1,129, 64,103,157,117,214,101,234,224,111, -188,170,207, 9,251,239,113, 82,176,168, 33, 17,161,244,158,113,169, 73, 85, 70,162,126,138,188,252, 81,249,142,163,187, 29,157, -113,159, 70,212,231,176,238, 48,222,219, 60,213, 83, 4,200,134, 76,239,251,227,188,250,240, 59, 48, 47,159,207,238,120,254,211, -247,243, 51,111,124, 37, 63,241,157, 21, 15,173,143, 72, 19,195,197,171,131,207,219, 31,123,219,111, 82,125,242,191, 64,222,143, - 33,137, 14, 2, 61,235, 4, 95,150, 40,255,219, 79,192, 57,187,144,250,112, 91, 80,118,196,123,191,242, 36,247, 89,239,181, 99, -173,253, 59,167,167,207,197, 94,244,167,234,241,158,237,216,190,159,208,102, 86,219, 31, 0,223,246, 24, 15,124,249, 45,224,231, -153, 11,239,190, 58,190,118, 54,251,234,214,207,247,118, 46,172,179,206, 58, 59,247, 76,125,194,126, 60, 43, 32, 21,206,123,198, -214, 51,174, 82, 82, 17, 22,184, 86,190,255,207,111,144,235,143,126, 94,230, 34,215, 31, 29,147,201,187, 16,159, 48,181, 62,146, -248,130, 82, 34,253, 5,236, 39,255,111,202, 91,126, 20, 63, 62,181,235,115,121, 98,184,252,208,210,231, 3,122, 57,193,254,197, -207, 83,253,201,191, 67,178, 20,209, 58, 60,194, 61,201,160, 44,193,185, 4,236,251,229,181, 55,221,247, 56, 59,251,189,162,175, -115,101, 6,246,182,137, 93,247, 69,182, 14,218,251,183, 18,199,182, 94,104,150,254, 84, 56,222, 71,187,198, 63,180, 7,208, 63, - 0,124,203, 99, 61,232, 69, 68,142, 3, 31,106,189,244,166,115,252,104,251,125,183,118, 46,172,179,206, 58, 59,119, 80,191,120, -242, 16, 61,125, 15,137,244, 25,149,125,156,235,211,151,109, 22,244, 43,229,250,143,220,252,232, 28, 64,250,139,104, 78, 51,171, - 12,165, 11,253,234,154, 48, 50,118,176,128,251,236,239, 82,188,239,187,176,159,126, 31,126,235,248,153, 29,236,232, 36,238,179, -183, 80,252,183, 55, 82,253,229, 47, 64,158,131, 54, 97,216,140, 8, 72, 34, 76, 74, 65,123,240,205, 99, 48, 31, 47,103, 95, 63, - 52,165,109, 55,159,163, 3,191,153,221, 98,177, 27,206,146,233, 62,209,118, 51,187, 69,105, 55,156,195,185,184,225, 41,124,188, -143,116, 92,255,130,221,207, 69,127, 92, 0,189,101, 63,222, 14,146,188,247,255,230, 44,251,247,111,128,175,139,191, 90,224, 63, -117, 46,172,179,206, 58,219, 5,189,143, 10, 70,215,222, 86,248, 27, 95,241, 42,166,229, 15,224,212, 37,164,234,163,244,146, 95, -146, 55,254,201, 89,159, 74, 37,223,251,161, 13,255,243, 95,253,221,204,220,123,216,169, 42,140, 2,173, 37,164,216, 64,127, 17, -170,211,148, 31,250,247, 72, 58, 68,246, 61, 7,181,250, 12, 48, 57,184, 18,183,121, 31,254,228,167, 97,186, 9, 73, 2,131,150, - 38,168, 22,187, 23,202,147,145,226,171,159,144,111,250,149,219, 31,199,236,252, 8,159,255,124,241, 13,206, 79,249,126, 61,187, -103,175,127, 32, 62,102,244,150,115,248,254,107, 34, 88, 62, 46,130, 51, 17,217,240,222,191,141,121,187,222, 17,239,253,141,103, -122, 68,107, 4,244,115,121,236,233, 23,237,241, 62,194,247,254,107,224,173,103, 0,244,201, 23,176, 77,223, 58,199,114,134,243, -254, 7,222,251,223, 36, 76,140, 3,248, 49,239,253,215, 16,218,214,254,140, 80, 51, 95, 38, 80,238,111,218,195,142,252,172,136, -220,217,185,176,206, 58,235,236,156, 65, 29, 64,174,255,208,125,236,126,120,197,185,219,247,254,217,123,249,217,151,189,131,202, -191,153,173, 98,194, 66, 42,104,130,168, 13, 15, 73,130, 36, 9,120,135, 95,251, 4,213,137,163,212, 99,229, 68, 25, 48, 41, 12, -246, 60,170,218, 3,133,197,187, 30, 40,157, 65,245, 65, 38,147,183,126,129, 14,221, 95,192,199,174, 63,159, 58,113,156,150,118, - 61,243, 39,151,213, 64,119, 11,129,174,110, 83,249, 53,205,127,132,121,109,250, 45,143,243, 90,184,137,221,143, 65,189, 46,210, -240, 55,181,246,237, 8,129, 74, 95,137,153,248, 6,143, 80,131,127, 10, 28,239, 94,219,187,134, 94, 11,140,207, 99,105, 60, 75, - 68, 46,228,209,191,223, 73,120, 2,219,139, 91,231,248,108,229,143, 63, 0,126,232, 66,215,242, 35,189,231, 76,129, 71,103,157, -117,246, 37, 6,234, 95, 80, 6, 8,222, 39,213, 15,163,146,131, 20,254, 13,108, 21, 83,159,107, 36,215,129,134,175, 93,136, 40, - 72,243, 71,127,154,133, 7,156,135,153,197,109, 21,244, 46, 58, 4,218, 30,165, 50,223, 38,215,222, 92, 60,129,231,236,104, 4, -244,243, 86,218,139,200, 77,173, 1, 54, 43,231,225,196, 31,119,139,217,250,181, 49, 67,189,178, 5,182,103,122,216,205, 6,112, - 45,103,121, 16,206, 23,243,241,126,177,152,136,108,199,224,233,157,192,119,156,229,237,101,124,223, 91, 68,164,234,206, 94,103, -157,117,182,215,212,227,253, 5,114,253,209,146, 19,249, 63, 34,145,159, 66,200,147,173, 18,119,186,132,169,131,138, 70, 67, 39, -114,134,255,226,255,176, 64,225,240, 91, 21,178, 49,163,183,178, 12,253,252,215, 97,235,213,242,173,191,252, 68,180,245,220, 18, - 51,214,107, 69,228,234, 11, 1,244, 54,208, 17,198,203,222,196,185, 13, 87,185,153, 64,101, 63,238, 15, 49,137, 15,133,185,250, - 44,223,117, 11,225,177,167, 71,159,234,199,251, 69, 4,236, 27, 34,242,157,192, 87, 69,208,254, 20,176, 22, 65,252, 4,240,167, -192,255, 17,217,128, 31,236, 0,189,179,206, 58,123,148,100,250,137, 51,255,127,125,205,107,238, 61, 49,190,245,233, 43, 25,213, -204, 83, 25,129, 92, 35, 70,133,204, 93,181,118,199,123,176,224, 43, 7, 83,139, 46, 29, 73, 34,108, 89, 88,124,250, 69,111,224, -175, 95,248,255,201, 91, 31,247, 65, 51,143,255, 57, 9, 89,218, 94, 10,251, 24,225,233,102,183, 60,137,251, 85,211,225,237,103, -162,223,114,142, 79,131,123,202, 29,111,103,157,117,214, 89, 7,234, 23,226,212,223,249,178, 69,114,249,135, 76,252,191,192,249, -203,195,104, 88,239, 81,202,161,152,131,180, 67,225,156, 34, 36,242,160,213, 73, 12,239,160,151,255,103,249, 39,127,244, 80,119, -233, 58,235,172,179,206, 58,235,236, 73, 6,245, 6,220,223,255,186,140,207,109, 62,155,210,189, 30,228,229, 88,127, 17,206, 45, -227, 73, 65, 74,140,156, 70,203,195, 56,255, 87,164,242, 95,169,242, 79,203,247,253,209, 78,119,201, 58,235,172,179,206, 58,235, -236,139, 12,212, 63, 15,228, 63,248, 42,195, 61, 24,244,186, 38, 31, 56, 54,138,234, 76,131,109, 58,235,172,179,206, 58,235,172, -179,206, 58,235,172,179,206, 58,235,172,179,206, 58,235,172,179,206, 58,235,172,179,206, 58,235,172,179,206, 58,235,172,179,206, - 58,235,172,179,206, 58,235,172,179,206, 58,235,172,179,206, 58,235,172,179,206, 58,235,172,179,206, 58,235,172,179,206, 58,235, -172,179,206, 58,235,172,179,206, 58,235,172,179,206, 58,235,172,179,206, 58,235,172,179,206, 58,139, 38,111,191,238,245,222, 36, - 6, 17, 1,239,177,206,147,101, 41, 74, 4,147, 24,172,117,100, 89,138,136, 48,155, 21, 40,165,240,222, 81, 76, 11,172,117,224, - 61,101, 89, 98, 43,139, 7, 68,132,170, 40, 80, 90, 35, 34,164, 89,138, 49, 9,251, 15, 29, 64, 27,195,104,235, 52,219, 91, 59, -148,101,133, 82, 66, 81, 84, 40,165,209, 90,112, 14,242,193, 2,139, 75,139,244, 7, 25,101, 49, 99,235,244, 22, 85, 81, 97,210, - 4, 17, 33, 73, 52,222, 67, 89,150,120,231, 41,171, 10,103, 29,218, 36,228,189, 28, 81, 10, 17,161, 44, 43,138, 89,217, 60,241, - 77, 27,131,247,158, 98, 86,197,239,242, 88,235,176,214,209, 31,228, 36,105,130, 82, 66, 85, 88,172,173, 40,102, 5,206,121,146, - 36,193,123,135, 82, 10,147, 36,104,163, 72,211,140, 94, 63, 69, 41, 69,154,165, 12,134, 57, 74,107,140,209,100,121,134,136,167, - 42, 45,182, 42,217,218, 28,177,177,182, 69, 85, 57,188,119,128,167, 42, 43,148, 82, 32, 96, 43,135,210,130,224,113,206,225, 28, - 40,173, 1, 88, 90, 93, 33, 77, 83, 78,175,175,161,180, 33,239,247, 88,123,248, 33,202,178,162,126, 34,182,136, 71,107,131,247, - 14, 17,193, 24,133,247, 96, 18,131,115,142,170, 12,199,235,189,199, 86,142,162, 40,177,214, 81, 22,225,220, 40,109, 48, 70, 49, -155,206, 40,203, 2, 17, 72,179, 12, 91,121, 76,162,153, 78, 42, 94,242,138,151,114,223,177,251,240,174,100, 58,153,177,176,188, -200,131,247,221, 71,175,151,147,247,123, 0, 20, 69,137,214, 97, 64,225,108, 50, 97,180,179, 67, 85, 89,190,226,170,171,185,239, -174,187, 88,221,191, 2,162,184,237, 83,119,146,247,122, 88,235, 24,109,111, 50, 43, 42,178, 52, 35, 73, 83,188, 87,164, 89,194, -120,103,135,157,157, 45,202,114,198,171,255,222,235,184,245,119,126, 27,235,194,241, 93,114,233,165, 60,253,138,167,145,229, 25, - 85, 89,114,226,161,147, 60,112,252, 65,202,162,192,186,112,237,156,181, 56,103, 89, 88, 60,200,161,139, 46,226,115,119,223,193, -100,178,131,224, 17,132,231, 62,255,165,140,182, 78,241,224,253,119,179,239,224, 37, 92,250,180, 75,185,228,138, 43,168,138,146, -187, 63,115, 7, 15,221,119, 7, 87,191,226,235, 56,117,114,141, 83, 15,220,203,129,139,175, 96,115,237, 97, 38, 91, 15,162, 84, - 56,151,120, 7,222,225,177,241,209, 5, 10,188, 67, 36, 92, 19, 17, 65,148,230,210, 47,123, 5, 27, 15,220,193,108,188,206, 11, - 95,249,141, 96,134, 60,112,236, 51,172, 29,191,157, 23,188,252, 8, 58, 25,112,199,199, 63,204,246,233,181,120,221,114,150, 87, - 87, 73,210, 20,147, 24, 60, 30, 91,121,188,247,244,134,203,160, 50,238,250,212,135, 41,139, 49,206, 78, 17,226,190, 64, 60, 62, -143, 8, 40,165, 73,178, 37, 22, 14, 62,143,201,169, 79,225,189, 69, 41, 65, 43, 5,184,248, 62, 3, 34, 40,165,113,241,252,106, -229,240,174, 2, 28, 72, 6,122, 9, 17,135,216, 83, 8, 21, 34, 26, 68, 35, 42, 69,233,112, 47,122,239,241,104,130, 11,177,120, -231,176,182, 8,127, 3,156,243,104,147,211, 27,174,144,102, 57,158,176,127,147,105,193,108, 50,101, 50,222,164, 44, 11,156,115, -120, 52, 94,194,218,141, 11, 28,239,108, 56,231,241,105,142,222,251,248, 93, 62, 30, 79,248, 93,240, 40, 37,205,207, 32, 40, 21, -238,123,173, 21, 90, 9,222, 91,164, 57,126, 1,194, 78, 42,109,208, 58, 65, 68, 97, 76, 26,183, 25,182,225,124, 60,183, 18,238, - 95,239,226,121, 86,225,115,225,154,179,107,223,136, 62,195,227,113,182,194,123,139,179, 22, 31,191,215, 57, 11, 8,214,133,123, - 57, 28,174,224,227,126, 55, 79,188,143,143,184,247, 46,248,143,224,139,192,199, 99, 83,218,128, 15,107, 45,156,111,143,136, 2, -234,107, 26, 30,159,225, 92,120, 93,107,131,179, 21, 74, 25, 36,110, 62, 28,143, 67,107,141, 45,103, 97,141,187, 18,163, 21, 96, -209, 90, 35,128, 82, 30,188,141,254,202, 69,204,136,255, 66,196, 6, 31,190, 75, 9, 62, 60,215, 35,172, 51,194, 51,186,240,196, -107,171,112,206, 34, 74,225,157,199,121,135,243,210,236,171,247,225, 73,219,206,131,143,127,115,206,134,223,145,224, 43,189,196, - 53,163,112, 94, 16,209,225,111, 62,252,231, 81, 32, 26, 36, 1, 20,196,115, 84, 89, 11,162, 16, 73,240,120,170,202,198,245, 68, - 92,155, 42,158,127, 1, 28,222,131, 82,130,138, 15, 28,243,184,230, 56,172, 45, 27, 63,236, 93,240, 59,205,121,245, 14,188,109, -214,167,119, 54,248, 12, 31,222, 67,196, 3,239,125,248, 93,234,147, 20,205, 55,255, 23,215,126,251,245,250,213,221, 63, 8,160, -180,209,241, 36,122,172,245, 24,173,113,214, 99, 93, 0, 60,128,170,178, 84,165, 69,226, 98,243, 14,146, 52, 9, 78,199,123,140, -209, 36,169, 33, 49, 26,173, 2,144,215, 55,146,173,108,115, 48, 90,107, 76,154,226,156, 67,137, 32,162, 72, 18, 19, 22,172,243, -104, 5,174, 28,179,126,234, 20,227,209, 20,147,164, 28,186,232, 16,139, 43,139,164,105, 18,222,235,195,129,167,105, 0,216, 0, - 36,225,187, 2,112, 89,128,230, 95,173, 53, 89,150, 53,159, 55, 70,199, 27, 47, 0,160, 49, 26,165, 20,206,186,112,220,214, 98, -173, 67,233, 26,160,131, 35, 81, 74,145,166, 9,198, 24,146, 84,211,235,247, 88, 92, 26, 50, 24,246, 48,198,160, 36, 44, 6,165, -192,217,112,177, 70, 59, 83, 54,215,183,176,214, 81, 85,101,235,230,244,225,198, 16,193,249, 16, 92, 20, 69, 25,157,159,161, 44, - 74,156,179,140,118, 70,152, 36,220,184,163,157, 29,108,229,232, 13, 23,154,155,222, 86, 22, 99, 12,218,104, 76, 18,175, 7, 10, - 81, 10,231, 28,179,105, 65,146,104,108,229, 40,203,138,233,116,198,120, 60,102, 50,153,134,235,150,152,112,243, 33, 40, 29,110, -174,170,172,152,140,103, 88,107,153,140,103,193, 73,227,169,202,146, 36,203, 80, 74, 72,146,148,229,213,101,108,116, 52, 85, 21, -174,167, 82,130, 45, 43,180, 86,205,162, 61,249,240, 26, 73,154, 98,157, 67,107, 69,158,103,209,113, 26,148, 40,210,196,160,148, -194, 90, 27,207, 69,248,215, 57, 63, 7,208,104,198, 36, 44, 46, 45,144,164,225, 51,179, 89,193,104,103,132, 86,154,188,151,147, -166, 41, 90,233, 38,192,233,245, 7,128,167, 44,103,120,231,234,187,134,125, 7,246,177,177,118, 18,165, 12,121,158,147,247,122, -136,132,243,182,254,240,253, 44, 44,237,167,183,176,200,137,251,143, 49, 88, 88,194,122,176,229, 52, 56, 2, 20, 74,169,230,253, -120,162,147,118, 1,128, 34, 72,120,239, 89,220,119, 5,182,156, 49, 29,157,228,203, 94,252, 42,210,172,199,104,107,155, 83,247, -125,138,149,253,151,208, 95, 88,229,196,253,247,178,181,254, 32,196,251,101,176,176, 64,214,203, 26,112,114, 54,120,194,172,183, -136,201,134,220,125,219, 71,130, 99, 85, 26,165,146,230,220,204,215,159,198,152,140, 44, 95, 96,233,208,115, 81,213, 58, 73,214, - 39, 73,251, 1,172,234, 71, 26,171,250, 56,194,218,214, 74,161,181,154,251, 12, 73,144,100, 9,165, 5,229,183,193, 77,119,221, - 11, 34,126,238,128, 68, 53,206,169,118,112, 53, 96,138, 40, 4,135,179, 5,197,108, 28,215,143,137,251,170, 80, 70,163,148,158, -123,170, 8,136, 18,144, 25,226,189, 26, 2, 21,105,112, 78, 68,208, 90,163,180, 66,226,235, 74,235,230,103, 81, 58, 0,158, 72, - 56, 46,145,176, 46, 98, 64, 81,175, 5,169, 3, 7, 31,128, 5, 81, 32, 62,252, 71, 29,192, 5,144, 18, 9, 62,166, 70,241,240, -187,155,127,222,218, 38,184,210,198, 68, 71, 27,142, 37, 4, 74,190, 73,138,234,115, 95, 39, 83,193, 31,250, 93,143,161,174,145, - 80, 90,248, 46, 82,131,128,195,251, 10,103, 11,194,179,169, 29, 80,131, 69, 12,236,132, 38,248, 17, 9,231,199, 55, 64, 31,207, -107,235,124, 58, 91, 54,201,152,138,231, 91,199,223, 67,128, 67, 56,191,113,159,194,182,104, 2, 13, 36,252, 93,105,133, 18, 21, -175,153, 10,215,168, 14,160, 36,156,117, 81, 58, 6, 34, 49, 32, 65,135,251,169, 62,131,162, 98, 64,232,162, 63,176,115,160,175, - 65, 63,222,211, 62, 62,190, 27, 81, 13,232,123, 31,130, 49,235,194,253,227,145, 24,251, 10,160,168,170, 24,124,196,245,172,148, -158,195,167,196,251, 59, 6,199, 90, 43,180, 14,127,247, 4,255, 46, 66, 19, 8,135,251,191, 62, 63,170, 57, 14,145,122,109, 69, -128,111,225,113, 8,132,227, 45, 36, 18,127,158,191, 86,239,117,253,183,112,127,213,239, 9,107,160,249, 57,254,141,120, 75, 42, - 16,146, 52,193,123, 2, 48,226,241,222, 97,173,165,170,108, 4,123, 75, 89, 85,232, 8,218,245, 13,105, 98,118,170,181, 38, 73, - 18,210, 44, 0,139, 54,134, 36, 73,154,136, 21,160, 42, 75,170,178,100, 48, 28,176,184,188,136,210,170, 57,129,117,134, 39, 34, - 84,149,197,150, 5,235, 39, 79,176,126,106,131,233,180, 98,117,255,126, 86,246,173,146, 70,198, 64,148,132,108,204, 90,240,144, - 36, 9, 85, 85, 81,149,182, 1,187,144, 89, 7, 16,215, 38, 44, 44, 99,194,239,243,136, 63, 28,115,146,104,148,146, 24, 57, 6, -112,202,210, 0,212,206,185,176,157,196,160,180, 34, 77, 83, 86, 86, 23,227,118, 53,105,150, 96,173,107,246,171,152, 85, 84,149, -101, 58, 41, 40,139,200, 96,196,133,232,156,195, 58, 23, 89, 7,197,120, 60,139,129, 79, 21,111, 52, 69, 81,148,136, 10, 17,117, - 57, 43,216,218,220,166, 63,236,131,247,108,174,175,211, 31, 12, 73,146, 20,173, 21, 89,158,133, 27, 68,194, 53, 20, 21,174,133, -179, 33, 67, 79, 82, 19,162, 80,173,176,149, 99, 54,155, 49, 25, 79, 3, 83, 16,207, 63, 30,202,162,106, 22,229,108, 86, 50, 25, -143,153, 76, 38,205,113,149,179, 50, 6, 64,134,193, 66, 31,109, 20,131,133, 33, 74, 96,180, 61,106, 28,155,173, 28, 85, 85, 49, -157,204, 40,138,146,201,120,194,198,169,117,250,131, 62,179, 73,129, 73, 12,105,150,160, 84, 56,239, 53,152, 7,144, 15,153, 69, - 85, 89,242, 44,195,196, 32, 3, 31,110, 20, 37,225,220, 15, 6,125,180, 54, 8,158,241,104, 18,217, 35, 1, 15, 70, 71,128,240, - 30, 91, 85,164,105, 74, 85,149, 56,107,227, 77,104, 81,162, 81, 90, 51, 25,111,163, 77,130, 49,154,254,112, 72,222,239,115,234, -193, 7, 41,102, 99, 46,127,214,115,121,232,254,227,204, 38, 59, 36,105,143,178, 40,169,170, 41, 34, 10,231, 3, 80, 37,105, 30, -178,157,232,232,165,229,128, 61,158, 36,233,177,124,232,114, 78,221,127, 27,151, 63,247,101, 44,174,172,176,189, 93,240,192,157, - 71, 1,207, 37,207,120, 14,224,121,224,179,159,136, 32, 8,253,225, 34,121,158, 7, 96, 78, 18,170,202,197,215,151,201,135,203, -220,115,251,199,230,206, 53,130, 74, 56,119, 25, 73, 58, 36,203,151, 24, 44, 30,100, 97,229, 98, 22, 15, 92,201,210,190,125,104, -147,144, 13,246, 49, 88, 58, 64,111,184,143,222,112,149,124,184, 74,154, 45, 96,146, 28, 99,146,224,156,149,224,157, 11, 25,137, - 40,148, 89, 64, 41,131,102, 10,110,212,164, 8, 1,132,234, 71, 39,198, 87,157,111, 64, 40, 56,175,112, 78, 66,176, 92, 65,157, -153,198,172,197, 89,135, 7,180, 49, 40,165,227,218,167, 1, 56, 23, 25,143, 6, 76,149, 52,204,199,220,111, 4, 63, 20,182, 27, -153,146,232,213, 84,235, 17,206, 77, 32,128,111, 28,174,111,101, 64,115, 71, 46, 17, 88,153,103,184, 34, 17,228,163,167, 21,105, -152, 64,234, 76, 12, 31, 0, 91, 84,124,171,219, 21, 64,132, 68,200, 5,240,146, 16, 4,170,246, 62,248, 0, 28,210, 4,138,154, - 6, 61, 98,112, 66, 3,244,115,176,105,167,190,129, 29,169,226,126,249, 38,163,167, 1,220, 24,192, 69,164,145,232,195,235, 75, - 88, 7, 85, 74,155,248, 62,143,104, 19, 89,131, 57,184,171, 38, 99, 87, 49,136,154, 95,103,239,133, 26,145, 68, 4, 79, 88, 75, - 77,192, 23,143,165, 14,182, 66, 16,172, 64, 84, 8,173, 36,128,174,117, 33,209, 9,151, 50,114, 79, 94,199,123, 47, 70, 14, 17, -176, 27, 22, 69,233,248, 62, 98, 6, 94, 3,116,100,106, 80,129,253,148, 58,243,247,225,120,148, 4, 6, 53, 6,166, 66, 96,139, -235,184,205, 53,235, 79, 71,254, 36,220, 35,218, 24,230, 68,146,154,199,162,245,177,251, 57,208,214,247, 86,125,178,155,100, 60, - 6, 45, 53,147, 21, 64,186,195,206, 76, 7, 0, 0, 32, 0, 73, 68, 65, 84, 5,232, 17,224,235, 0,166,121,173,245, 30,118, 37, -246,243,160, 90,137, 8, 11,139, 11, 44, 45, 47,198,104,205, 69, 10,161,190,201,117, 4,240,176, 40,172,117,209,137,133,157,204, -251,189,221, 17, 60,160,149,132,140,216,249,102,193, 76,198, 19,132,176,192,250,131, 1,121, 47,143, 55,156,111,168,113,107, 45, - 73,162, 73,211,224,152,203,233,132,211,235,235,108,110,110,147,102, 57,171,251,247, 49, 92, 28,144,231,105, 3, 66,170, 1,225, - 4,239, 61,105, 22,162,243, 36, 53, 36, 17, 68,146, 52,105,178, 16,147,232, 38, 91, 15,191,155,184, 80,194, 5,170, 74, 27, 35, -123,213,156,236,196,104,210, 44, 69,107,205,226,210,128, 52, 75, 73,179, 16,180,212, 89,173,247,176,179, 53, 10,217,240,206,148, -237,211, 59,140,118, 38,113,251, 45,170, 15,193, 24, 67, 81, 84, 24,163,169,170, 0,168, 38, 73,176, 46, 48, 16,245, 62,149,101, -201,198,218, 58,222, 43,134,139, 11, 20,179,130,233,100,202,210,234, 82,188, 97, 32,203, 83,178, 60,141,231,191, 14, 76, 2, 67, - 81,211,252,227,209,152,209,206,136,201,100,134, 8,100, 89, 18,168,191, 24,113,214,217,250,108, 86, 96,227,254,104, 37,104, 29, - 28,192,116, 58, 35,239,165, 40,165, 73,179,140,217,100,134, 73, 18,138,162,108,168,232,170, 44,155, 32, 48,252,235, 24,143, 71, -156,222, 88,103,176,176,192,108, 58, 13,215,190,223,195, 90, 31, 89, 20, 5, 53, 99, 32, 66, 76,168,112,222,199,232, 62,236, 91, - 77,177, 46, 45, 46,134,136, 57, 6, 71,211,241,164,185,249,141, 49,209,225, 73,204, 86, 19,210, 52,141,212,109, 96,130, 20,144, -245, 22,169,138, 25,120,200,178, 30,131, 97,159, 44, 31,224,189,231,196,241,123, 25, 12, 87, 88, 62,176,159,227,119,223,137, 82, - 9, 73,154, 51,155,140,241, 54,128, 85,160, 91,235,181,148, 97,146,180,137,196,219, 20,241,202,225, 47, 99,180,121,146, 3, 23, - 61,157, 75,159,241, 76, 30, 62,254, 48, 91,235, 15, 49,217,122,144,149,131,151,113,240,178,167,115,207,109,127,137,171,102, 8, -208,235, 15,232,245,135, 36, 89,218,148, 98,188,115,244,134,203,244, 22, 86,249,220, 29, 31, 15,153,148, 82,104,147,160,117, 74, -150, 15,233,245,150,201,251,203, 44,172, 28,102,105,255,101, 44,172, 94, 66,127,241, 32, 43,135,174,164, 26,111,144,102, 41,121, - 44,129,153, 36,139, 1, 64, 78,214, 95, 34,237, 45,146,100, 3,146, 52,139, 14, 48, 56, 31,157, 45,163, 76, 31, 45, 21,190,218, -110,104, 66,162,147, 21, 21, 28, 82,200,234, 90, 89,182,119,141, 95, 8,217, 75,164,164,157,101,158,120,134,181, 30, 0, 46,128, - 69,160, 48,125,227,168, 84, 4,207, 58, 72, 8,142, 81, 53,215,178, 14, 32, 92,244, 79, 18, 65,180, 73,143,124, 43, 27,106, 74, - 34,210,162, 49,165,201,232,219,160,230,226, 53, 12, 89,183,139, 14,216,181,178, 56, 31, 0, 35, 6,118, 53,149,238,125,200,108, -125,204, 18,109, 85, 6,226,214,187,120, 29, 3,229, 79, 3, 53,177, 68, 80,179, 61,141,123,151, 24,248,212, 37,132,176, 81, 31, - 51,249, 38,187,143,255, 83,210,226,180,227,127, 82,179, 1,174,138,193,108, 93, 98,136, 64, 95,151,106,164,197,110, 8, 40,157, - 52,199, 37, 49,115,141, 41, 48,222, 91,144,249,117, 9,247,165,106,125, 87,100, 10,124,213,176, 31,117, 16, 18,216,137, 36, 6, - 46,177,116, 35, 42,150,110, 66,182, 28, 63, 17, 83,219,240,187,173,193,204,215, 84,123, 67,174, 4, 70,197,215, 44,158,110,178, -221,152, 26,199, 64, 99, 30, 12, 5,166,212, 70, 70, 82, 35, 42,248,215, 16,228, 69,198,197, 5,112, 79,146, 36, 38, 27, 14,163, - 13,222,205,207,127, 83,218,240, 49, 30,169,215,157,119, 45, 58,124,158, 48,214,126,213,123, 2, 3,236,108,120,182,184, 8,206, -219, 22, 43, 86,255, 43,173, 12,188,117, 91,181,193,190,157,237,195, 60,179,111, 1,191, 26, 46, 12, 88, 94, 89,164,215,239,163, -180, 66,199, 76, 54,100,187, 33, 35,174, 35, 60, 27, 51, 30, 99,116,164,181, 12,222, 65,154,134, 26,188,214,115,240, 51, 70, 99, - 18, 67,146,134,236,216, 89,139,173, 42,108, 89,146,230, 57,203,171,203,225,239,137,193,104,213,128,112,213,212,194,125,160,116, -188, 99,186,179,205,198,250, 38,214,193,226,242, 50,105,150, 97,140,106,168,161, 64,157,133, 5,104,173, 39, 73,116,100, 0, 52, - 58,214,140, 27,186, 79,207,233,247, 58,234,175, 3, 4,231, 28, 89,150,196,155, 39,156,184, 36, 9, 81,180, 49,138,213,253, 75, -244,135,189,230, 68, 59,231,201,123, 1, 80,203,162,164, 42, 43,198, 59, 19, 38,227, 41,179,105, 25,162, 57, 81, 49,250,171,107, - 77, 33,112,168,121,175,217,180, 68, 27, 19, 40,108, 21,162, 84,165,132,217,116, 26,153, 8,139,181, 37,189,193, 16,173, 21,219, -155,155, 36,105,206,112,113,129, 94,191, 23, 74, 4, 77,116, 31, 46,115,205,146,104,163,217,217, 25, 51,157, 22,204,138,178, 97, - 47,172,181, 77,144, 83,150, 21,147,241,148,201, 56,208,171,225,102,114,120,132, 52, 77,201,243,140, 98, 54,101,184,184,128,247, - 22,173, 13, 85, 85,162,117, 66,150,101,120,103, 41,203,170,169,223,135,227, 12,212,191,119,142,217,100, 20,178,206, 50, 4, 0, - 89,150,161,117,200,204,147, 36,105,162, 87, 99,116,116, 85,225,247,196, 24,240,160, 99,157, 46, 73, 18, 22,151, 23, 72,211, 20, -107, 45,211,241,148,217,172,192,123, 79,158,167, 49,160,148,150,147,139,245,249,209, 40,158,234,224,128,246,237, 63,200,230,218, - 26,120, 79,127, 48, 36,207,123, 44,239, 91,101,227,196, 9,118,182, 54,185,236, 25,207,230,212, 67, 39, 24,111,175,145,245,134, -120, 81,216,114, 26, 28,157,214, 24,147,162, 77, 8,138,194, 58,207, 48, 38,105,130,170,160, 73, 88, 98,184,114, 16,113, 19,158, -253,162,171,185,227,227, 71, 49,189,101, 78, 28,251, 24, 74, 25,174,252,202,151,176,189,113,138, 19,159,187, 19,240,244,135, 75, -244,250, 11,228,189,140, 36,209, 32,129,189,201, 7,139,100,131, 85,238,185,237,163,120, 95, 6,118, 67, 20,105,154,135,236,189, -191,204,112,229, 48, 75,251, 46,102,184,180,159,188,215, 39, 73, 12,249, 96, 5, 69, 1,222, 70,240,169,179, 74,139,146,232,248, - 9,247, 87, 8, 18, 76,115,158, 69,247, 16,221, 71,107,143, 43, 55,241,174,108,101, 8,174,185, 66, 66, 72, 0,172,173, 34,181, -233, 26,176, 15,181,207, 80,191,110,192, 10,133, 73,178, 57,165, 29,247,201, 86,101, 4,133,144, 41,207,125,187,223, 69, 67,207, -147,134,154,198,149, 38, 51,175, 51, 88, 98, 86,140, 82,145,181, 10, 76, 0, 77, 41, 64,106,191, 63,207,156, 34, 56,207, 19, 30, - 55,175, 40,196,213, 89,215, 73,125,235,187,130, 51, 15,201,141, 82,210,232,139,106,122,223,121, 7,206, 33,196,115, 32,106, 87, -240,215, 80,249, 49,153, 16,116,195, 12,132,253,172,233,232,152,197, 74, 60,199,245,235, 17, 8,234, 42, 5, 77,253, 22, 16, 31, -147,177,121, 96, 67, 4,210, 80, 50,242,243,224,168,198,211,150, 30, 65,105,141, 18,223,148,106, 2,192, 7,253, 72,205, 42, 52, - 1, 74,227, 71, 93,195, 54,212,231,215,123,135,214, 73, 96, 83,154,215,252,252, 56,163, 38,192,199,100,209,186,122,101,214, 58, -143,121,169,195,123,105,232,247, 58, 67, 15,153,124,157,173,170,200, 90,234, 80,155,151,154, 82, 87,145,141,242, 77,153,108,174, -177, 2, 37, 58, 18, 38,130,214,193, 31,133,242,171,106,216, 4,165, 2,173,175, 36, 4, 1,206,185, 72,193,135,128,192, 58, 27, -180, 41, 17, 91,106,124,113,182,205,150,212, 76,205, 60,128,219,157,109,207,207, 77,139,196,137,199,203,156,122,247,187,107,234, - 53,184, 55,235, 0, 48,189, 65, 31,231, 96, 50,154, 4,154, 53,214,187, 68, 5, 26, 91, 18, 69, 85, 85, 49,123,164, 1, 60,145, -144,105, 57,231,209, 89,168,205, 54,236,191,115,205,142, 6, 70, 45,220, 84, 59, 91,219, 44,174,104,242, 52, 37, 93, 92, 96, 54, - 9, 66, 56,165, 85,168, 35,123, 23,178, 53, 64,235, 36,128,143, 49,136,120,102,227, 17,107,101,193,226,242, 50,131,133, 69,210, - 44, 99, 99,109,157,201,104,210, 0,123, 40, 5,168, 72,159, 8,121, 47,141, 34, 50,143, 82,158,138, 16,125,155, 36,208,210,222, -121,146,152, 37, 86,101, 96, 9,132, 80,131,155, 76,102, 36,137,161,215,207,201,251, 57,189,126,222,232, 8,170,178,138, 96, 47, - 56, 27,182, 49, 30, 77,168,202,138,178, 44,153,140, 2, 37, 44, 49,232, 48,137, 6,130, 70, 65, 16,108,172, 5,133, 26, 92, 88, - 96,182, 10,223,111,140, 97, 50,158,236, 10, 60, 78,175,111,114,224,240, 33,134,139, 11,140, 71,129,238,190,232,210,195, 60,252, -224,137,168, 29, 8, 87,218,185,224,196,173,173,168,172,101, 54,157, 81, 85, 21,182,170, 34,149, 9,130,162, 44, 43,144, 34, 44, -250,186,142,237, 28,214,121,242, 94, 22,106,212,253,156, 44, 15,231,111, 60, 26,177,186,111,137,147, 15,157, 98,176, 48, 36, 49, -193,105,166, 89,202,100, 60, 66,170, 50,126,111,200, 70,106,145, 97,168,237, 87,148,165,163, 44,203,152,145,230, 49, 67,159,215, -250,156,115,228, 73,134,247, 80, 20, 85,172,127,131, 54,129,158,207,210, 4,231, 97, 48, 24,196,117, 6, 59, 91, 59, 84,101, 25, -106,243, 42,148, 23,154,192, 9,137, 64,171,168,138,105,200, 22, 36,100, 22, 75,171,251, 56,249,192,189,136, 50,100,121,200, 90, - 77,170, 57,121,252, 62,210, 52,231,192, 69, 23,241,241, 15,253, 15,196,123, 6,195, 69,156, 11,245,116,239, 64,180,180, 50,148, -184,190, 85, 29,220, 70,113, 25,194,129,203,190,156, 98,188,206,243, 94,250, 53,220,254,145, 15,179,124,241,115,120,248,238,191, -164, 42,199, 92,116,229, 75,200,122, 3,238,187,253, 40,222,149,100,249,128,222, 96,129, 44,207, 81, 2,211,113, 96, 52,146, 52, -103,184,114,136,251,110, 63,138,171,166,161,228, 32, 6, 68,163,141, 33,239, 13, 49,105, 70,146, 36,204, 38,163, 70,163,130, 8, -217, 96,145,141, 7,239, 4, 23,106,174,182,152, 96,109, 17,152, 23,162,224, 51, 2,158, 18, 79,229,125,160, 75, 77,134, 36,203, - 40,177, 72,181,131,183,179,230,126, 70, 90, 25, 21,210,202, 50, 36, 36,105, 66, 84,123,213,206,171,154,131, 55, 66, 98, 82,146, - 52, 11, 66, 45, 23,216, 24,239, 29, 85, 89,204,105,108, 95, 75,147,230, 34,162, 26, 36,234, 53, 49, 7,240,154,154,118,248,152, - 49,170, 58,187,165,166,230, 29, 58, 82,250,210,232, 51,230, 2, 56, 26, 97, 91, 40, 57, 52, 96, 19,193,202, 58, 55,167,202,101, - 78,181,250,128,155, 17, 52, 92,212, 40, 72,100, 50,124,204,160, 67,166, 22, 88, 41,105,125,111, 60,158,154, 42, 85,181,144, 13, - 84,244,160,117, 62, 31,246,173, 22, 63, 42,188,154, 7,172, 68,122,157, 58,183,109,216,138,200, 26,196,114,131,179, 22, 37, 38, -178, 15, 37, 74, 37, 13,184,105, 5,222,201, 92,255,160,116, 4,135, 0,102, 90,116, 8, 74, 68, 80, 58, 1,111,131,200,171, 62, - 23,222, 70,102, 68, 34, 99, 19,179, 84,234,250,125, 4, 56, 53,167,196,189,183,177,142,174, 32, 10,203,156,115, 49, 49,241, 17, - 43,162,143, 20,193, 86, 85,147,237,214, 92,132,141, 66,187, 16, 40, 73, 19, 24, 8, 10, 27,191,207, 90,135,212,154, 19, 17, 68, -199, 96,204,213, 1, 21,141,208,211,197,200,192, 19,104,121, 98, 57,140, 88, 63,167, 14,168,116, 0,234,250,152,156,173,176,182, -154, 7,147,109,160,141,219, 19, 36, 48, 64, 17,153,125, 35,106,157,215,192, 27,150,170, 93, 22,218,171,151,195,239,122, 78,122, -179, 38, 91,191,215, 92,176, 89, 88, 24, 82,204, 10,118,182,183,231,130, 19,145, 64, 11,219,144, 33, 41, 81, 77,148, 82,223, 4, - 58, 82,188,218, 4, 33,157,142,145,161,115,150, 44,207, 40,203,146,158, 81, 20,211, 18,148, 3, 66,109,123,188,179,141, 82,194, - 48, 91, 98,184,180, 72, 89, 22,204,166,161,182,236, 35,125,139,247, 49,163,239, 53,244,186, 40,133,194,179,189,185,193,104, 39, - 99,101,117,145,131,135, 15,178,126,106,157,157,237, 81, 20,204,132,122,178,210, 42, 82,209,208,235, 39,204,102, 37, 68,134,161, - 44,162, 3, 80, 30,147,134,133,231,112, 49, 2, 11, 89,126,157, 45,247,122, 57,131,133,126, 0,186, 24,133, 77, 39, 97, 95, 37, -214,128,148, 10, 74,251, 90, 44, 49,155,150, 49, 75, 54, 17,212,124,172,219, 72, 20, 22,130,142,234,125,240, 12, 22,250, 56,235, -130, 8,144,121,176,228,241, 24, 29, 0,184, 44,166,156,222,220, 98,101,117, 5,239, 29,211,201, 4,115,104,149,133,197, 33,147, - 81, 16,190, 41, 45,248,194,199,154, 90, 16, 12, 78,167, 5,197,108, 70, 21, 89, 23,239,160,116,129, 94, 47, 70,227,112,205,180, -142,130, 69, 77,158,167, 77,205,182,102, 65,148, 22,202, 89, 65,150,231, 76, 39, 19, 6, 11, 67, 68,107,202,162,160, 55, 28,176, -126,234, 20, 85, 85,145,102, 57, 85,101,153,140, 39,148, 69, 25, 51, 89, 67, 89, 20,161, 59, 65,107,202,178, 34,203, 83,188, 3, -167,124,140,240,231, 74,102, 16,140, 86,204,170, 50,100, 8,209, 73, 56,235, 24, 46, 44,132,204,222,131,181, 21,155, 27,155,140, -118, 38, 77,233, 6,124,168,175, 71, 53,175,206,210,160,202,159, 5,122,219, 57,139, 19, 97,255,193, 85,142,221,246,113,178,172, - 71, 98, 12, 11, 75,139,108,173,175,113,122,125,157, 75, 46,127, 38,107, 39, 79, 49, 58,125, 34,148, 26,242,126, 0, 29, 27,130, -150, 16,213, 75,204,226, 84, 44, 49,129,215, 26,188,193, 86, 5,131,197, 67,244, 23,150, 56,124,233, 1,238,185,237,147, 72, 50, -164,156,108,179,179,126, 55,195,165,139,217,127,233,149, 84,211,211,172, 29, 63,134, 54, 41,139, 43,251, 72,243, 60,172,175, 8, -204,202,100, 44, 31,122, 26,247,124,250,163,148,197, 56,208,133, 98,200,242, 30,214,194, 96,105,137,188,215,111,238,252, 36,205, -152, 77,199, 76, 71,219, 12, 87, 47,225,228,125,183,177,179,126, 95, 84, 40,215, 37, 42, 5, 46, 64,158,171, 66,208,172,116,237, -224,195,189,158, 14, 87, 72, 18,131, 43, 38,204,102, 91, 33,131,117,118, 87,237,183,201, 56, 27, 10,183, 86, 8,123, 98,106, 24, - 0,187,201,208, 67, 78,146,245,130, 22, 36,220, 19, 18, 50,124,231,168,202,105, 3,222,245, 26,192,123,148, 14,247,161,119, 54, - 2,165,154,103, 64,141,120,172, 86,174, 71,186, 89, 84, 44,213, 4,231, 93, 51,132, 90,107,136, 0, 93, 43,255,131,215,214,141, - 48,207,225, 80, 62,214,191,197,180,202, 17,109,229,177,111, 50,189, 58,107, 18, 84, 44, 3,196, 12, 56, 72,216,226, 58,116,173, -186,119, 60, 83,222,198,192, 80,230, 12, 65, 64, 24, 20,117,201,207,134,123, 35,130, 34,145, 25,144, 70,144,104,119,169,157, 27, - 0,105, 68,134, 33, 1,115,126, 94,255, 22, 31,124,176, 80,151,180,130,175, 76,106,241,156,154,171,171,165, 6,106, 21,217, 51, -241, 17,192, 67,182, 10,110, 14,236,248,134,150,174,131,131,186,227,128, 22, 51,226,252, 92,167, 32, 74,135,164, 42,208, 2, 49, -193,241, 49,235,173, 34,248, 75, 12, 38, 2,179, 40, 42,136,174, 3, 13,111,230,107,176, 14,186, 84,232,212,106,128, 94, 25,108, - 76, 44, 66,252, 83, 3,189,198,232,132,202,186,166, 94,173, 35,184, 71, 9, 95,131, 57,243, 12, 58,126,127, 20, 66, 6, 22, 33, -176,147,117, 2,169,164,102, 99,231, 73,150,119, 14, 47, 45,178, 92,194,126,248,184,142,106, 86,168,206,190, 27,189, 76, 43,251, -158,103,229,145,254,159, 43, 20,144,189,192,222,112, 98,192,104,103,135,233,100, 18,197,102,101,163,112, 55,137,222, 37,150,171, -105,234,154,102,181,214, 54,130,185, 44, 79,209, 70, 55, 66, 14, 99, 76, 84,115,135,236, 57, 73, 19,138, 89,104, 67,171,138,130, -201,206, 14,121, 47,103,105,117, 31,105,154, 54, 7, 19,232, 43,154, 90, 69, 83, 15,243, 30,235,108, 0,169, 98,196,218,137, 83, - 76,103,142,125,135, 14,178,239,224,190, 93,116, 77,154,154, 80,107,206,146, 0,184,145,218, 19, 32,205, 18,178, 44,137,226, 56, -133, 54, 42,182,202, 37,145,182, 14,206, 35,239,101,228,189,156, 44,207, 72,123,121,227, 88, 84,108,211, 83, 53,165, 32, 66, 85, - 86,161,110, 83,148, 49, 58, 37, 10, 56,164,105,153,203,242, 44, 42,253,231,229, 35, 99,146,152,129, 73,115,158,138,162, 12, 34, - 34,165,163, 40, 43, 44,152,201,104, 7,157, 24,246, 31,218,135, 86,194,214,198, 22,131,133, 97,160,126,240,148, 69,133, 68,225, -135,181,129, 18, 47,203,114, 46,118, 43, 99,246, 62, 43,152, 78,167,148,179, 34, 30,119,100, 35,122, 57,189,126, 80,242,167,105, -216, 47, 68, 40, 11, 75, 85, 85,232,196,132,172,187,152,133,182,144,178, 36,203,115, 68, 66,128, 50,155, 78, 25,143, 38,187,168, -253,218,209,141, 71, 35,146, 36,193, 86, 65, 71,144,102, 73,163, 40, 53, 90,135,104,220,209, 8, 25,117, 84, 52,187, 24,224, 5, - 45,195, 34, 73,106,154,146,193,246,233, 45,108,140,148,171,178,196,150,101, 12,228, 2,213,149, 38, 25, 90, 41,108, 85,204, 21, -204, 18, 90, 16,103,179,113,168, 97,247,114,146,124,192,201, 7, 30,196, 86,150,195,151, 93,202,189,119,220, 30,110, 94,209, 40, -157, 48,222,217,198, 86, 5, 58,214, 51,141, 73, 34,160,135,122,155, 54, 73, 40, 61, 69,145,226,254,203,158,203,129,195,251,216, - 94, 59,193,218, 67,159,227,240,229,207,226,248,103,254,148, 36,237,113,209, 51, 94, 64,158,105, 54, 31,190, 31,239, 75,134,139, - 43, 36,105,218,100,149,182,178,152, 52,101,249,208,211,184,239,246,143, 51,155,108,135, 96, 88,167,104,147, 98,146,156,225,210, - 10,189, 94, 15,173,194, 61,133, 8,197,108,194,233,147,247, 83,149, 21,174,154,177,249,240,109,184,106, 20, 85,209,190, 1, 40, -129, 64,191,139,135,168, 72,247, 62,180, 55,165,131,125,228,189, 1,226, 75,170,217,102, 83,211,103,238,182, 35, 88,186, 6,208, -156,155,215,157,137, 20,124,253,243,156, 62,116,152,164, 71,154,247, 16,101,168,236,156,234, 46,139, 89, 0,245,154,102,111,105, -115, 92,236,152,105,106,228,241,239,193, 25,198, 54,167,150,250,184,214,254, 32,115, 38,177,166, 92,189,155, 43,212,231,220,186, -236, 18,195, 53,199, 33,210,116, 93,212, 76, 68, 29,188,132, 86,211,118,251,150,139,170,108,191, 27,196, 26,134,194, 69, 48,214, -243, 58,107,147,237,215,244,118,108,139,107, 94, 11,107,202,199, 54,187, 58,145, 82, 53,104,198,253,169, 25, 9,223,114,249,237, -214,170, 90,199, 80,127, 31, 50, 47,111,212,106,241, 58, 81, 81, 90,163,148, 1, 84,147,105,215,181,102, 21,197,167, 97, 31,104, -213,212, 5,223,252,190, 87, 27,208, 42,111,214,129,106, 44,137,212, 34,185, 70,216, 24,207,139,170,253,157,142,181,247,250,254, -143,138,246,154, 82,119,117,224,133,196,224,165,181, 46,162, 14,170,190,174, 38, 73, 27,113, 99,125,205, 65, 26, 49,114, 19,168, - 54,224,163, 26, 65,115,205,250,213,250,170, 42,118, 83,249,136, 67,109,218,187, 22, 64,215,165, 21, 23,215, 5,113, 13,182, 42, -163,187,107,229,168, 38, 35,175,239,177, 93, 34,184, 93,117,243, 40, 30,100, 14,252,187, 82,247,121,247, 35,202, 90,207,246,233, -157,176, 80, 98,123, 85, 85, 22,243,218, 22,117,102,174, 98,127, 93,136,128, 85,172,139, 10,190,169, 63,212, 32,105,162, 74,190, -223,239,145,101,105,236,181,181, 81, 24,102,153, 78,166, 84,101,201,120,103,135, 36, 49, 44,237,219, 71,175,223,139, 53, 69, 67, -154, 24,210,212,132,236, 42,214,226,235,144, 70, 69,113,149,173,102,108,156, 60,201,206,246,132,225,226, 18,251, 15, 31, 12,226, - 59,153,139, 19,202,210, 54,173, 86, 74, 73,212, 11,208, 40, 88,235,104, 76,199,204, 94,105, 65, 41, 72,211,100, 94,223,196,227, -171,138,196, 24, 68,121,210, 60,109,192, 35, 56,166, 16, 4, 21,211, 34,182, 94, 4,166,160,166,152,211, 44, 13,237, 45, 4, 42, -206, 36,186, 17,215, 36, 89,216, 86,154, 37,205,149,212, 38,232, 26, 84,252, 60,177, 54, 30,122,198, 67,109, 91, 41, 97,123,107, -139,170,178, 44, 46, 45, 5,103, 30,157,139,224,152, 77, 75,166,211, 25,206,250, 72, 77, 7,225, 99,208, 43,204, 98, 57, 37,128, -107,158,103,100, 89,168,157, 39, 73, 18, 4,123, 54, 42,136,189, 71, 27, 21, 91, 4,131, 96,232,244,198,233,102,141,212,148,219, -108, 58,101,103,123, 43, 0,104,188,169,130,248, 77,147,164, 9, 91,155, 91, 44, 44, 45, 48, 25, 79,201,122, 65,115,209,168, 58, - 99, 59, 76,211,235,171, 66,155, 99,173,254,112, 81, 72,215, 31,244,163, 90, 90,216, 62,189,197,104, 52,106,222, 83,211,105, 54, - 6,160,222,185,112, 67,123,139, 45,203, 38,251, 72,146, 30,179,201, 20,188, 39,203,114,134, 75,203,164,121,143,205,147,167,216, -127,248, 18, 78,111,110,177,121,234,126,192,211,235, 47,226,189, 80,205, 70, 77,159,180,139,130, 27, 98,159,108,168,201, 65,146, -134,249, 8, 11, 43,151,112,241,229,151, 99,180,227,246,143,125,144,203,190,252,171, 56,126,199,199,193,205, 56,124,197, 11, 99, -169,199,113,242,248,221, 12, 22, 87,233, 13, 22, 72,146,208, 10, 74,116,238,203,135, 46,231,129,187, 62, 69, 49,217, 66,169, 4, -147,164,136,210,244, 6, 3,250,195, 1,105,106, 26,145,228,116, 60, 98,103,227, 20,163,211,107, 56, 87,113,240,178,103,177,246, -185, 79,180, 20,216, 62,106, 93, 84,147,209, 42,147, 52,253,196,117,205,214,228,139,244, 6,139,136, 47, 41,167, 91, 56, 91,197, -123,191, 86, 37,207, 53, 39,109, 5,184,111,178,114,213,212,213,173,245,115,209,160, 7,173, 83,250, 11, 43,104,147, 54, 74,110, -111, 29,229,108, 70, 49,155,196,140,221, 54,247,247,156,182,164, 9, 20, 2, 77, 58,175, 1,215,128, 35, 77,189,213,205,213,207, - 77,145,120, 46,230,219, 69, 83, 71,182, 65,234, 90,123,236,174, 8,181, 83, 19, 1,140, 93,212,188,139, 96, 95, 39, 13,181,110, -164, 6,164,154, 74,109,148,243, 74, 90,190, 83, 53,179, 12,106, 96,175,147, 21, 85,239, 71,108,215, 84, 74,163,149,105, 74, 87, -196,154,111,160,132,165, 97, 49,230, 30,220,207,245, 97,117, 22,215,162,120,195,253,209, 18,233,213, 52,114, 19,232,169,121,135, - 64, 12, 72, 26,170, 87, 41,148, 14,125,232, 65,124,171,155,206, 40,137, 98,183,250,251,230,252,111,236, 11,111,128, 72,230,231, -153,121, 11, 90,104,247,155,235, 7, 66, 11, 27,136, 74, 16,101, 98,253, 92, 26, 1, 24,162,231,202,246, 40,188,155, 3, 94, 13, -244,210,116, 15, 4,102, 75, 71,166,194,180,102, 0,132,238,170,166,109, 47,210,246, 33,179, 87, 13, 54,232, 24,200, 4, 77, 86, -196,134, 38, 29,150, 38,161,245,113, 46, 70,221,109, 80, 39, 97, 66,221,163, 63,207,164,165,213,182, 54, 15, 44,221,110,225,155, -159, 83,239,126, 23, 61,255,249,109,235,237, 98, 24,187,106,234, 30, 53,175,185, 18,157,119, 21, 23,106, 93,155,212, 1, 20,132, -166,157,161,238, 51,119,222, 82, 69, 5,117, 93,139, 79,147,186,151,219, 52,180,170,105,245, 71,214, 3, 53, 70,219, 59,216,178, -192, 85, 37, 73, 98,216,119,248, 16, 11, 75,139,241,239,109, 45, 76,168, 89,183,157,168, 73,234,108, 18,198,219,167, 89, 95,219, - 68,196,176,239,224, 1, 6, 11,131,152, 5,134, 69, 25,250,157,213,174, 1, 2,206,206,135, 7, 4,193, 86,136,136, 27,135,137, -144,101,129,121,168,107, 94,149,181, 49,155, 55,205, 80,158,102, 8, 6,145,201,176,190,105,211,128, 0,232,189,126,160,238,179, - 60,109, 28,138,214, 58,158,159,216, 31,238,193,196, 44, 20, 95, 59,209,112, 2,140, 14, 61,241,105,146, 48,155, 76, 40,102, 21, -195,165, 5,156,181,156,124,232, 36,189, 97,159, 94,191, 71, 89,134, 89, 2,179,162,162,170,202, 88,215, 14, 61,247, 33,168, 8, - 25,181,210,154, 60, 15,204, 65,150,101,152,196, 68,177,159,106, 74, 47,225,220,133,154,121, 45,104,218,217,222, 33,203, 82,198, - 59, 59, 16, 65,174, 42, 45,105,158, 51,155, 78,130,176,207,185,102,168, 79,205,126,136, 8,147,241,136,222, 96,192,120,103, 4, - 30,122,189, 44, 4,134, 49, 43,171,153, 31,173,231, 2, 71, 36, 48, 54, 90, 9,131,126,159,225,226,160, 41, 77,108,159,222,138, -195, 61, 2, 19, 82,247,203,106,173, 16, 31, 75, 64, 89,206,116, 58,197,218, 18,111, 67,208, 51, 92,220,199,120,251, 52, 73,146, -209, 31,244, 88, 92, 61, 0,190, 98, 58, 30,115,248,105,151,114,207, 29,127,211,128, 89,127,176, 68,229, 60,229,116,187, 9, 30, -154,168,222,207,107,163,181,166, 65,107,195, 37,207,122, 1,131,129,225,227, 31,252, 29, 86, 47,122, 14,222,150,108,157,252, 12, -203, 7,175,164,183,176, 66,150, 27,198,155, 39, 1, 33,239, 15,131,230,195, 68, 81, 21,176,116,240,233, 28,191,243,211,140,183, - 55, 80, 73,222, 56,152,197,149, 21,210,172, 23, 6, 36,105,197,206,230, 38, 59,155,167, 24,111,173, 81,149, 65,224,120,201, 51, - 95,204,250, 3,119, 82, 21,167, 27, 7,173,181,137,117, 82,105,234,154, 33,152, 53,104,147,134,108, 63, 27,144,100, 67,180,130, -114,186, 69, 85,142, 90,130, 52, 23, 41,229,182,186,150, 6,228, 27, 37,121,147,229,170, 38, 96,173, 51,225,222, 96,153, 36,235, -197,222,224, 0, 16,101, 89, 50,157,236, 48, 29,159,110, 1,115,171, 45,206,181,232,229,122, 42, 72, 4,120,124, 77, 1,199,253, -114, 62,182,208,185, 24,100,206,149,221,161, 91,199, 54,175,207,101,198,204, 7,188,200, 92,223,209,118,172,141,130,223,250, 88, - 59,151, 93,169, 81,157,205,213,181,239,134, 82,109,128, 53, 6,152,113, 80, 9,209, 79,212,165,196, 80, 75, 14,195,124,106,117, -189,196,246,174,208,178, 57,103, 2,241,181, 46, 64,181, 84,252,187,219, 10,137,172,200,156,234,245,177,254, 61,167,109, 93, 13, - 64,225,221, 77, 0,224,234,214,171,102,136,140,110,174,159,104,221,234,248,152,179, 27,222,187, 38, 40,172, 3, 19,105,245,102, -135, 54,184,164, 17,253,209,100,235,237,214, 60, 29,216,129, 58, 59,175,187, 29,154,214, 59, 29, 84, 42, 81, 24,232,188,199,135, -137, 63,187,214,182,247, 32, 90, 71,145,111, 88, 79,214,249, 72,193,187,134, 73,208,218,132,228, 44,130,127,189,230,234,150,238, -122,230, 68, 80,220,215,235, 65, 62, 47, 27,246, 77, 63,155,106,186,120,218, 3,100,194, 18,114, 13,165, 95,119, 81,213,107,195, -197,196,163,222,182,111,129,183,111,177, 47,123,138,234,143, 60, 65,174,213, 89, 34, 34,152,114, 86,196,158,209, 88,143,174, 51, -114, 73,154,161, 44,181,176, 34,212,162,133, 52,205, 26, 16, 75,211,121,175,162, 40,133,171,170, 38,186, 17, 44,149,170, 66,107, - 75,157,221,198, 41,109, 8, 76, 39, 99,202,162, 10, 52,119,191,207,194,202, 62, 4,216,218,220,104,181, 83,184, 72,253, 71,167, - 77, 0, 61,147, 38,100,121,200,252,157, 45,216, 92,223, 96,113,101,133,197,149,101,140, 38,208,179,142,160,222, 87, 65,141, 31, - 22,148,221, 61,142, 39,210,102, 90,197,237, 38, 9,105,106, 34, 29, 30,197,112,222,145,247,114,242, 60,101, 54, 45,176, 51,139, -173, 92,204,220,170,160,116,143, 10,202, 16,208,132,193, 56, 52,180, 93,168,231, 36, 49, 24, 40,139, 89, 0, 53, 99,192, 57, 92, - 92,152,198,104,138, 72,139,251, 24,204,132,126,248,160,224,175,172, 99,123,107,155,165,149, 69,146,116,139,141,181, 77,180, 49, -172, 30,216,199,206,246,136,162,152, 81, 22, 85, 16,237,197,136,180,206, 2, 19, 99,226, 48,157,144,161,167,105, 66,111,208, 39, - 77, 3, 59, 98,210,132,178, 8, 98,175,154, 25,177, 85,133, 46,131,224,110,115,125,139,172,151, 97,109,201,198,218, 38,131,197, - 33, 69, 81,160,117, 18,166,251,121, 72, 83,135,137,215, 86, 34, 69,171,148,102,180,181,141, 73, 50, 38,147, 9,206,121,178, 60, - 99,180, 51,137,181,197,185,250, 86,132,208, 1,129, 35, 49,134, 73,236, 76,232, 13,250, 97,202,161,210,204, 38, 19,182, 54, 79, -163,213,124,104,135,141, 29, 26, 97,174, 64, 21,196,144,105, 74, 89,204,112,182,108, 50,138,213,253, 7,216, 56,117,138, 44, 31, -176,188,186,143,149, 3,251, 88,123,240, 56,131,197, 37,138,162, 98,107,237, 33, 68, 98, 59, 92,111, 64, 85, 22,184,106, 22,123, - 83, 19,146, 36, 13, 78, 55, 50, 84,186, 17,135,122, 22, 15, 62,141, 75,159,113, 37,159,248,224,111, 33,162, 57,124,197,115,185, -235, 99,239, 39,205, 23, 89,189,248, 89,108,157, 60,206,129,131, 95,201,253,199,239, 36,239,133,182,204,186,100,230, 29, 44, 29, -186,130, 83,199,239, 97, 54,222,136, 45, 55,138, 44, 79,232, 13,151, 17, 21,130,100,103, 43,182, 55,214, 24,109,173,161,116, 66, -222, 31,144, 24,205, 96,241, 18,140,134,209,198,221, 13, 29, 45, 13, 13, 74, 67,127, 6,193,160,142, 61,233,130,152,156,108,120, - 32,204, 74,152,109, 81, 21, 59,177,118, 93, 5, 48,218, 53,244, 36,102, 32, 81,196, 86,183,111, 5,177,103, 45, 66,138, 19,194, -162, 0,180, 55, 88, 38, 73,123, 17,180,116, 12, 4,203, 16, 4, 78,182,155,233,108,141,234, 92, 76,107, 42, 94,164,224, 91, 0, - 91,143,253,178,177, 85, 75,226,164, 13,223,244, 60,215,109, 74,180, 4, 73,115,245,186, 40,153,103,215,117,203, 86, 61, 16,197, -185,144, 17,214, 34,175,200, 12,132, 97, 66, 97, 26, 93, 45, 68, 69, 92,171,166, 62,207,216,105,234,218, 68, 1,221,156, 24,175, -157,122,221,114, 90,139,192,131,243,215, 13, 51,170,180,142,173,104, 65,100,170, 34, 21, 93, 31,199,188,147,225, 12, 10,232, 93, -173,109, 45,182, 33,126, 70, 84,210, 4, 8,141,202, 94,155,185,152, 76,164, 37,186, 10,193,185, 49, 10,239,138,184,126, 84,156, - 76, 24,174,103, 96, 28,194,245,242,115, 68, 15,215, 52,182,186,137,104,188, 4,138, 63,168,202, 77, 51,220,203,227, 98, 96, 35, - 17,220,109, 80,210,120,162,150, 98, 94,135, 15,135,236,154,242,168,171, 1,177, 17, 69,250,216, 25, 16, 2,133, 36, 81, 17, 51, - 76, 19,144,213, 90, 6,231,194,160,160, 48,120, 45,148,147, 69, 9, 42,150, 98, 67,251,153,195, 68, 6, 90,199,146, 65, 85,149, - 49,232,168, 7, 13,185, 93, 32,239,234,217, 4, 66,156,152, 87, 69,231, 22, 7, 27, 53,211, 2, 93, 75,220,188, 87,206,238,155, - 14,143, 57, 13,239,217,203,182, 75, 43, 91,111, 4,233,117, 39, 81, 93, 59,107, 38, 52,169,240,165,229,172,104,134, 58, 36,105, -104, 9, 80, 26,202,216, 70,164,181,166,215,207,113,149,197, 24, 21, 84,158,205,120, 76, 9,237, 28, 42,212,229,131,138,209, 54, - 2, 13,165,107,209,131,103, 58,217,137,244, 38,100,189, 30,131,229, 21, 68, 41,182, 54,214, 3, 53,110, 12,206,186,160,114,214, - 58,168,161,123,217, 92,149, 88, 83,110,174, 98,107, 99,157,197,229, 85,122,251, 22, 89,222,159,176,115,122, 59,140, 73, 85, 10, - 27, 79,248,124,138,144, 68,186, 91, 55,130,146, 44, 11, 89,184,179,237, 41,102,154, 52, 77, 49,137,102, 50,158,198,172,117,210, -156,216,178, 40,153, 76,138, 38,106, 79, 98,191,188,210,134, 94, 63,163, 44, 28, 73,170,231,206,182,172,168,202, 56,214,208,249, -166, 45,206, 86,150,170,242, 77, 43,154, 18, 67, 18,105,249, 26,228,181,146,144,173,247,123, 12,134, 3, 78,175,111,178,185,182, -206,194,210, 2, 75, 43,203, 60,240,185,227, 65,152,230, 92,211, 57,144,102, 41, 38,210,119,117,189,114,105,121, 33,102,194, 97, -106, 94, 61, 4,164,110, 93,145, 60,141, 76, 68, 0,217,217,116, 22, 38,236, 45, 44,115,247,103, 62, 75, 85,110,146,100, 41,101, - 81,209, 27, 44,144, 38, 41,179, 98,198,108, 58, 13, 0,148, 36, 49, 80, 20,108,165, 40,139, 9, 38, 73, 40,103,179, 56, 75, 32, - 37, 73, 12,197, 44, 46, 77,239,176,206,146, 42, 21, 71, 54,134,114, 79, 29,115, 45, 46, 45, 68, 96, 10,212,251,108, 58,142, 45, -116, 37,105,150, 5,193, 77,100, 75,234,207, 36, 73,202,206,230,102,147,133, 13,134, 75,124,217,243,159,195,167,254,252,207, 88, -217,183,143,125,135, 15,227,157,101,123,115,147,131,151, 94,198,253,119,223,141,179, 37, 90, 27,180, 78, 73,243,156,201,198,122, - 51,157,203,150, 5,149, 78, 91, 3, 83, 66,237, 82, 27, 77,146,246,120,214,139,191,134,123,254,250, 40, 59,155, 15,115,197, 11, - 95,195,137,123, 62,141,171, 38, 92,246,188, 87,178,189,246, 16,251, 14, 93, 4,190,192, 86, 54,150, 18,194,228, 70,239, 29,131, -125,151,178,246,224,113,182,214,142,135,178, 76,154,146,247, 7,161,198, 45,144,100, 9,182, 44,216, 57,189,193,120,123, 61, 40, -203,109, 96, 85,146, 44, 99,113,223, 33, 30,188,243,104,188,239,216, 53,182, 52, 56, 76, 27, 89, 33,221,244, 90,235, 52, 35, 91, - 56, 24, 70,246, 22, 35,198,227,205,121, 50, 27,155,130,149,214, 56, 87, 54,162, 56,105,234,143,186,153, 46, 25,232,233, 57,245, - 23, 58,189,132,188,191, 68,214, 31, 98,146, 60, 6,188, 97, 92,170,179,150, 98, 58,106,196, 85,243, 76, 54, 10,146, 68,135,128, -163, 6,200,166,102,106,231,131,106,118, 77,123,163,105,213,170,123,230, 67,246,171,112,182,140,181,100,213, 48, 10,160, 3,173, - 12, 40, 99,112, 85,156,181, 64,157,117,153,121,141, 28,217,149,157,138, 10,140, 99, 8, 18,234,190,253, 58, 40,117,243,122,185, -111, 77, 26,139, 10,241, 32,216,114, 77,246, 23, 74, 78,186,225,103,107,113, 89, 93, 19,118,126, 46, 62,171,135, 98,181, 6,129, -134,158,112, 57,195,184,208, 70,164,232, 98,253,218, 71, 65, 96, 0,217,250,123,124, 11, 64, 68, 20,226,109,152, 70, 41, 58,150, -222,170, 40,246,179,173, 65, 93,186, 9,194, 66,125, 94, 71,240,109,181,248,197,172,186,201,162,235,125,138, 44, 75,141, 41, 97, -212,117,160,221,235,178, 11, 94,197,253, 14,153,118, 96, 27,164, 41,105,250,168,250,247,209, 95, 91, 23, 2, 21, 17, 29,197,184, -134,202,210, 36, 68, 68,112,181,173,178, 9,177,157,141,216, 11, 95,179, 88,117,208,235,162,198, 64,107,141,117,150,196, 24,138, - 98,214, 12, 19,170,203,123, 8, 13,205,238,154, 73,138,243, 62,250,122, 13,184,102, 70,131, 52,215,198,215, 12, 88,211, 24, 33, -115, 49,165,204,127, 70, 62, 95,245,222, 68,112,106, 78,235,215,197,250,250, 30, 52,245, 56,192,122,176, 64, 85, 86, 81, 12,150, - 52,253,195, 42,102, 82,245, 76,241, 58, 19,175,138, 2, 81,138,217,180, 34,205,235,158, 99, 21,163, 24, 31,231, 12,123, 84,170, - 40,162,115,173, 5,119,161,254, 20,230,204,151,101, 9,147, 49,120, 75, 62, 24, 48, 88, 90, 65, 39, 9,219, 27,155,113, 24, 9, -232,216, 50,149,231,105,160,228,211, 36, 12,109, 49,181, 74, 86,129, 18, 70, 59,219,120, 60,203,171, 75, 44,173, 44, 49, 30,141, - 66, 95,120,116, 14,198,248, 70,140, 86,215, 80, 18,165, 98,251, 91, 80,232,215,103, 52,140,134, 13, 20,244,108, 26,178,224, 98, - 86, 53,153,208,246,214, 24,239, 44, 85, 25, 70,160, 6,186, 94,230, 34,144,152,213, 41, 29, 90,230,130,122, 56,212,179,195,194, -182,244, 7,121, 51, 63,223,213, 45,101, 38,244, 78,154,122,132,174,119,148,165,109,232,178,205,181, 13,246, 31,218, 71,146,165, -140,119,198, 60,116,252, 33, 14, 95,124, 8,165,117,168,165,215, 98, 38, 7, 89,150, 5, 49, 99,156,216, 6, 48,157,206, 90,109, - 63, 65,152, 83,255,205, 86,193,241,214,186,137,170, 44, 99,109, 20, 14, 94,124,136,149,125,171, 60,252,224, 67, 20,211,130, 52, -207, 72,179,140,254,112,129,233,169, 41,152,176,168,170,202,146, 24, 69, 21, 3,139,217,116,214, 56,168,178, 40,231,199, 24,233, -208,122, 30,130,107, 70,185,198,209,165, 58,180, 44, 13, 23, 6,161, 68, 2,108,159, 62, 77, 89, 22,177,219,162, 14, 22, 85,220, - 71, 69, 37,129,246,203,123, 41,167,215,202, 70, 74, 90, 85, 21,139,203,139,124,237,235, 94,205,237,159,248, 27,122,195, 5,138, -233,148,170, 40,209, 38,225,225,251,142,197, 58,161,208, 31, 46,131,210, 20,147, 29,242,193, 18,121,127,200,214,218,131, 77, 27, - 91, 24, 76, 17,196, 89,218, 24, 94,252,170, 35,120, 20,199,239,250, 36,171, 23, 61, 19, 17, 97,235,196,157, 28,190,226, 5,148, -165,101,178,245, 48,135, 94,114, 53,167, 62,119, 23,189,126,142, 73,116,164, 9, 61,217,240, 48, 59,167,183,216, 62,117, 31, 34, - 33, 32, 74,251, 67,242,254, 48,234, 74, 74,102,227, 17, 59,155,167, 40,139, 9, 74,234, 28, 58,172,185,213,195, 79,103,123,237, -193,102,118,183,243,101, 51, 40, 68,137,111, 4, 76,170,110, 87,146, 80,115,204, 23, 15,146,164,125,240, 21,147,157,141,224,132, -189, 39,142,152, 10, 83,187,156,109,209,170,170,105,235, 10,123, 16,187, 77,234, 81,157, 45,197,114,111,184, 76,214, 27,146,102, -189,160,137, 80, 38,172, 35, 28,101, 57,139,179, 20,122, 88,103, 81, 62,140,205,121,238, 40, 0, 0, 32, 0, 73, 68, 65, 84,241, -165,233,239, 13,140,139,173,202, 70,161,174, 98, 73, 38,168,137,107,125,175,111,169,193,125,116,176,117, 11,149, 71, 5, 78, 54, -222,143,122, 62, 85,189,165,210,158,211,169, 13, 9, 16,133,158,177,115,197,250,152, 81,250,185, 51,143,157,123,222,187,192,122, -212, 37, 0, 45,205,253,169,212,124, 4,105, 67,187, 70, 13, 73, 96, 53,124,171, 52, 62, 31, 55, 91, 11,233, 66,144, 84, 53,157, - 6,170, 25,125, 28,218,200, 92, 28,166, 68, 51,231,190, 37,153,174,149,215,222,199,118, 43, 21, 59, 55,124,211, 38, 38,187,104, -244, 57,208,134,172,155, 22, 64, 7, 49, 90, 45,174, 12,101, 17,213, 8, 20, 85, 92, 79,245,190,181,167,171,213,162, 48,165, 37, -100,245,113,226,158,167, 30, 74,164, 80, 26, 52, 6, 43, 14,113, 65,183,211, 48, 41,141,200,207,205,131,131,230,103, 21,129,180, -158,253,238,155, 26,186, 49, 73, 51,100,198, 91,223,244,121, 55,251,163,234,222,114, 63, 23, 64,170, 57, 19,237,156,199,232, 80, -122, 82, 18,124, 88, 45, 84,116, 98, 99, 23,150, 14,207,201,160,214, 47,184, 56,176, 38, 96,167,179, 85,195, 76,183,199, 70,215, - 9, 76, 51,214,182, 6,239, 61,153,120,131, 77,126,215,133,221, 85, 75, 15, 34, 4,118,181, 80, 54,195,148,108,101, 81, 49, 59, -244,117,141, 57, 77,154, 40,160, 42,138,102, 34,145, 68,119, 18, 68, 2,241, 36,216, 32,166,170, 23,105, 89, 86,177,159, 59,105, -196,105,225,166, 84,173, 33, 13, 97, 94,184, 73, 76,163,142,156, 77,103,108,109,110,179,189,121, 26, 87, 76,233,245, 7,172, 28, - 58, 68,150,247,154,186,126,154,154, 88,119,109,215,145,106,103, 18, 22, 69,146,132,135, 18,172,159, 92, 99, 86, 88,134,139,139, -244,250,189,144,237, 84, 33,106,206,178,148,188,151,145,229, 41,105,154,144,229, 73,168, 49,231,105, 84,110, 75,156, 29,158,227, -156,163, 40, 10, 70, 59,161,102,172, 77, 88,212,227,209, 52,170,164,101, 87, 93,176,158,251, 94,103,197,181, 80,194, 36, 10,157, -168, 38,202, 52, 70, 51, 24,230,205,108,253, 80, 59, 79, 67,230,220,170,103, 87,205,152,217,154,234, 47,216, 92, 91,103,103,123, -194,254,131,251,113,206,177,185,182,206,198,218,105, 14, 28, 58, 24,149,238,113, 28,170,146, 86, 22, 19,104,165,205,141,211,108, -172,111,178,179,181,205,120, 52,162, 44, 10,198,163, 17,163,157, 17, 91,155,219,140,118,254,127,182,222,235, 73,146, 44,205,238, - 59, 87,184, 12,145,145,162,116,181, 22,211, 35,129, 21, 92, 5, 35,214,104, 52,130, 70, 60,144,255, 42,159,104, 52, 35,204, 96, - 32,184,160,129,139,197,206, 46,118, 71, 79,119, 87,151,206,170,204,200, 12,233,226,250,189,124,248,132,123,246,238,140,141,245, -204,148,200, 8, 15, 15,191,159, 56,231,119,246,184,189,185,197,203,231,175,241,246,213, 91, 60,255,246, 57,158,125,253, 29, 94, -191,120,133, 24, 19,242,162,196,131, 71,143,152,191, 78,239,253,228,244,140, 11,184, 65, 5, 37,164, 28,117, 74,190, 58, 30, 27, - 56, 71, 98, 63, 35,136, 80, 55,162, 42,135, 48,240, 68,134,144,190,214, 57, 10,148, 72, 73,233,131,205,225,128,155,235, 53,107, - 59, 12,119,202, 94, 31,210, 4,235, 73,240,158, 20,229,237,241, 48, 98, 56, 97,113,125,121,133,162, 42,241, 39,127,249,103, 48, - 38, 34,134, 30,171,139,115, 92,189,125,131,208,183,248, 31,255,183,255, 21, 62,203, 81,206,150,116,120,119, 7,164, 24,240,217, -143,127,140,217,242,148,187, 13,206, 41,224,208,157, 15,190,248, 17,238,127,240, 1,186,221, 26, 85,189,196,227, 47,126,138,183, -191,251, 27,156,156,127,128, 98,126, 31,239,190,253, 91, 60,250,228, 71,112, 54,161,217,109,238,232, 20,242,217, 57,218, 54,224, -250,213,175,145,241,244,162,168,231, 40, 42,218,183,199, 24,208,236,110,113,251,254, 5,250,238, 64, 86,166, 20,148,255, 93, 47, - 47,224,108, 66,232, 54, 35,221, 77,239, 59, 22, 53, 33,242, 53,130, 94,247,114,126,129,106,182,128, 53, 3,218,253,154,114, 25, - 88,188, 68, 29,214, 8,108,209, 93,247, 68,197,172,208, 22, 86,186,203, 8,208,250, 2,229,236, 20,245,252, 12, 69, 57,227, 80, - 13, 79,225, 70, 67, 68,115, 60,176, 6,129, 10, 11,162,219, 85, 40,202, 57,178,188, 70,150,229,234, 63,166,238,201, 79, 24,225, - 18,158, 50, 1,210, 88, 81, 87,143,226,182, 41,251,221, 89,135, 44, 47,117,244, 58, 70,222, 72, 91,197, 2, 63,238, 58, 13,171, -219,199, 9, 64,198, 35,103, 40, 72, 74,133,104,105,220,171, 79, 89,220, 35,192, 38,170,194,125,228,128,147,165, 77,247,241,102, -250,186,160, 34, 51,234, 24, 71, 58, 90,156,232, 25, 98,250,158, 56,237,123,255, 53,169, 32, 45,233, 56, 62, 37,242,131, 83, 97, - 52,168, 64,117, 8, 65,247,187, 52,146, 30,197,147, 2,110, 73, 60,245, 75,162, 76,215,125, 56,161, 96,199,107, 50,117, 12, 88, - 21, 37, 14, 17, 19,119, 0,116,183,174, 88, 88, 70,125, 67, 80,174, 92,112, 36,121,112,218,241,222,163, 17,243,116,173,233, 89, -208, 54,226,134,201,198, 54, 17, 27,242, 58, 69, 66,178, 70, 93,137, 27, 97, 68,211, 17, 62,235, 30, 98,164, 85,158, 76,173,232, -204,163,103, 12,225,171,211, 68,247,193,133, 14, 70,141,129, 56, 41,244,108,224, 41,192,200,110, 72,119,225, 51,105,186, 91, 55, -248,231,246, 43,186, 74,249,222,162, 61,165,187,211, 26, 43, 41, 77,130, 20, 21,182,179,207, 70,236,170,168, 43,197, 50, 97, 21, - 98, 31, 21,170, 96, 89,205,105,173,225,132,178, 17,225,104,153, 24,103,140,165,238,131, 71, 57,162,128, 6,139,156,128,136,227, -126,143,205,205, 45,154,253, 14,121,158, 97,190, 58, 69, 89,207,216, 70,230,149,236,165,106,123, 55,126, 72,116,224, 10,159,122, -192, 97,187,193,110,123, 64, 89, 87,154,224,230,249, 48, 41, 75,234, 96,139, 50,199,124, 49, 67, 81,230, 4,152, 97,118,253,124, - 73,232,208,190,235,208, 30, 91,190,183,104,109,208, 28, 26, 14,126, 25,198,113, 49,219,184,178,194,179, 56,111, 84,223, 11,125, - 47,244, 52,138,201,203, 28,245,188, 98,139, 85,166,162,185, 60,207,239,116,232, 10, 64, 96, 64, 67,123,108,249,115, 50,120,255, -246, 61, 96, 60, 39,158, 13,120,253,226, 37,156,207,113,118,126, 78,225, 53, 5,137, 63,132,186, 38, 28,252, 60,207, 80,112, 2, - 88, 8, 3,118,219,131, 90,127, 8,246, 66, 52,184,158,177,175,132,166, 61,224,213,243, 23,120,247,102,141,247,151,239, 16,134, -136,162, 44,177, 92,173, 16,194,128,249,201, 74, 15, 1, 74,207,139, 44,154, 27, 52, 44,230,184, 59, 96,185, 90,226,176,223, 35, - 47,115,228,185,103,209,147, 84,207,244,160, 12,253,192,225, 62,100, 31, 36, 98, 28, 5,235,208,107,217,179,254, 33,142, 4, 58, - 3, 62,100, 73,255, 96,172,135,115, 6, 79, 63,254, 20,143,159,126, 12, 48, 30,182, 57,236,241,183,255,233,231, 56,123,120, 15, -125, 75, 54,188,106,190,192,118,125, 3,107, 29,222,188,188,196, 95,254,219,255, 25,245,124,129,237,205, 6,161,111,209,181, 13, -158,255,246,119,248,248,135, 63,161,245,145,247,122,207,221,123,242, 33, 62,248,242,115,124,247,219,111, 80,205,107, 60,249,234, -143,240,254,197,215, 0,128,139, 15,127,136,247,223,253, 2,101, 85,227,195, 47,191,196,246,234, 45,178,124, 20, 36,186, 98,129, -126,240,184,126,249,107,253,110,185,156,130, 87,202, 50, 67,232, 90,236,110,174,176,189,126, 77, 96, 27, 69,181,210,104,117,182, - 88, 97,117,239, 17,182,239,159,235,148,194, 57,199,215, 45,169,254,133,166, 74, 81,201,113,197,236, 12,203,243,251,168,170, 28, - 22, 68, 51, 44,103, 11,100,249, 12,245,236, 4,121, 89,195,231, 21,124, 86,194,250,130, 31,196, 78,197,102,226, 55, 38,149,183, -135,203, 74, 24,151,195,186, 10, 89, 62,195,114,117, 14,155,149, 8,201, 34, 12, 6,125,160,220,136,227,126, 79, 22,203,104,144, -140, 87,133,114, 2,249,242,125, 86,194,101, 53,124, 94,194,249,156, 45, 86, 99,103,125,215, 18,102, 56,204,198,168, 18,218,232, -104,158,214, 72,214,121,221,223,210,200,181,132,243,133,134,136, 76, 5,115, 70, 14,117, 99,245,160, 72,178,123,213,229,247,100, - 34,193,247,245,196, 72, 54,225,125, 70, 86,198, 59,157, 58,165, 9, 1,109,228,201,143,226, 59, 65,143,138,208,212,240,245,142, -140, 46, 37,235,220,104,207, 75,105, 60, 18,210,247, 65, 37,122,200,203,180,110,228,245, 71, 57,156, 13,238, 64,132, 52,244,133, - 39, 95,152, 16,209, 4,169, 74,135,254, 8, 94,129,185,235, 52, 48,242,190,210, 52,236, 38,221,229,163, 79,236,117,102,162,129, - 72, 48,147,240, 23,167, 97, 96,227,234,131, 41,121,188, 30,182,198, 50,213,145,127, 63,139,251,196,189, 48, 61,226, 68, 16, 39, -118,229,209,138, 38, 89, 2,238,206, 25, 68,169,156,152,100,132,140,170,109,209, 70,196, 72, 28, 1, 51,129, 28,201,143,140, 92, - 64,141, 46, 4, 51, 73,216,251,167, 7,241,212,190,118,135, 36,243,125,149, 28, 79,223,116,245, 1,189, 44,119,128, 55, 64,130, -205,178, 92, 11,162,204, 59,102,113, 59,120,111,149, 41,142, 56,101, 59,243,173,204,128,150,178,204,248, 2, 36, 77, 33,242, 57, -169,201, 59, 70,147,138,154,150,246,205,227,141,100, 57, 25,106,244,166,146,130,244,120, 32, 49,212, 97,179, 69,150, 57, 44, 79, - 87, 56,127,112,143,186,156,239, 37, 11, 1,196, 50,247,153,211,144, 16,217,145,164, 20,113,216,110,177,189,221,161, 40, 43,156, -223, 63, 83,187,152,140,186, 37,100,164, 40,115,246,221, 59, 84, 53, 29,248, 93, 23,212,159, 40,160,148,174, 11,232,251,128,182, -105,201,119,159,128, 44,151,164, 52,175, 54,182,148,198, 14, 84,128, 25, 96, 98, 81,150,101,232,251, 65,121,234,116,232,228,202, -162, 79, 49,170, 26, 62,165,136,190, 11,234,133, 31, 2, 89,252, 14,187, 13,186,182,195,234,252, 20,113,136, 56,236, 15,120,249, -221, 43, 60,253,248, 41,234,186,198, 16, 56,177, 46,129, 25, 2, 94,255, 19, 36,137,142,175, 83, 8, 3,134, 48,160,107,123, 13, -195, 33,208, 78, 67, 96,162,221, 30, 49, 70,236,182,123, 28,246, 59,188,120,246, 13,110,215,107,148, 85,137,122, 86, 97, 54,159, - 99, 54,155,211, 52, 32, 4,253, 18, 80,172, 43,189,191,253,110,139,217, 98,129,195,118,207,122,140, 74,175,105,226, 80,142,129, - 69,150,164,190,103, 5,126,238,149,226,183,190,186, 86,255,173, 4, 85, 8,178, 81,104, 77,214, 0, 85, 93, 3, 72,120,246,187, -223,224,147,175,190,194, 71,159,126,137,139, 7, 15,176,187,189,133,113, 57, 82, 76, 88,174,230, 48,198,226,230,106,141,174,165, -213,199, 47,254,230,175, 49, 95,157, 97,113,186, 66,123,220, 48, 98, 56,195,237,245, 27, 0,192,253, 39, 31,234,151,172,154, 47, -241,213, 31,253, 33,222,189,126,135,183,223,252, 14,243,213, 25,202,122,134,155, 55, 95,227,241,231, 63,195,110,253, 14,222,246, -184,255,225, 15, 81,214, 25, 16, 3,170,249, 28,229,172,130, 47,230, 72,254, 4, 87,207,255, 17,206, 12,200,139, 2, 89, 62, 67, - 53, 91,162,172,115, 12,161,193,126,115,131,246,112, 67, 34, 27,166,213, 73,231, 69,158,247,159, 98,251,254, 25,163,123, 39,156, -124, 38, 48, 10,245,206, 26, 81, 53, 71, 84,243, 51,156, 61,120,138,197,114, 6,147, 58,248,204,162,154,213,152, 45, 22,152, 45, -230,200,171, 26,245,252, 4,245,108,137,162, 94,194,103, 37,178,172,210, 14, 25,106,205,177, 48,174, 32, 2,157,113,112,190, 64, - 86, 84,168, 22,167,128, 43,144,140, 71, 74, 52, 34,141, 97, 64,232, 90,244, 66,246,211,180, 51, 70,161,106,105,102,225, 92, 14, -235,114,248,124,134, 44,175, 96, 12, 59,104, 24,225,105,212,135,110,245,144,167,162, 49, 83,229,153,157,142,179,185, 91,148,180, - 54,245,107, 59,199, 29,160, 85, 71, 10,253, 30,171, 98, 52, 96, 36, 66,170, 34,154,187,219,164,180, 55,166,193, 49, 36,103,136, -114,232, 49,212, 74,224, 36,214,194,186, 12,214,229,112,158,138, 31,159,207, 96, 93, 9,227, 10, 85,116,143,168,219,105, 23, 47, - 74,125, 34,169, 77, 69,119,233,142, 36,123, 82,160,164,187,220,123, 17,222, 25,214, 75,141,142, 17,233,138,237,168,120,183,164, - 70,143,156,219,145, 18, 93,123, 65,168, 10,179, 95,126,198, 52,222, 85,197,205, 19,119,132,172, 50,132,227, 46,148,182, 52,225, -238, 75,103, 46,207,127,125, 94,138, 69,141, 11, 36,241,210, 39, 22,155, 25, 51,117, 49, 24,181, 89,139,123, 70,138, 79,128, 96, -106,170,214, 55, 86,167,205, 52,157,224,144, 24, 22,135, 12,236,208,208,169,180,238,252, 19,239,246,169, 88, 10, 33,208,223, 43, -147, 66, 22,211, 77,187,238, 24,199, 67,126, 42,126,251,103, 52,236,147,252, 84,243,207,254, 14, 1, 12,141, 5, 93, 82,145,241, - 8,183, 1,108, 94,144, 39,187, 40, 50,164, 52,162, 82,201, 51,105, 21, 11,155, 34,189, 17,171,118, 25,250, 42, 14,129,189,192, - 41,114,124,169,228, 6, 27, 20,101, 49, 34, 18,121, 44, 38,227,125,231, 61,251,171, 35, 83,194,162, 86,170,214,209,135,176,189, -189,197,238,102,141, 24, 58,248, 44,199,201,249, 57, 22, 39, 11,250,243, 19,175, 57,237,202,157,238,141,221, 36,129,140, 2, 77, -246, 88, 95,221, 32, 37,139,211,243, 21,202,178,196,108, 81, 97,177,172, 53,240,101, 68, 7,210,129,127, 60, 52,108, 11, 35,180, - 41,140,193,241,208,162, 57,146, 88,174,109,136,197, 45,106,111,192,234,251,146,209,158, 60,104,219,166,215,100,180,140, 15, 41, -239,157,190,126, 9,158,145, 36, 56,241, 92,183, 71,217,143,199,201,104,218,168,215,255,197,179,151,240, 62, 71, 61,155, 33,132, - 1,235,235, 43,220,222, 28,240,224,241, 67,221,137, 11,227, 88,252,244,178, 34,232,218, 30, 93,215, 83, 30, 61, 71,174,246, 93, -143,227,161,197,225,208,162,109, 90,180,109,139,166,105,121,170, 18,177,185,217, 96,117,186, 66,215,182,120,253,226, 57,190,249, -237,215,164, 11, 88,204,113,114,186, 66, 8,129,191,108, 81,195,125, 36,195,249,176,219,163,172,107, 28, 15,123, 94, 99,176, 35, - 65,210,205,100, 55,101,160,209,166,121,150,147,208,207,123,120,103,176,219,108, 38,123,200,145,213, 45, 64, 12,231, 12, 3, 97, -114,116, 77,139,188, 40,240,245,175,127,139,199, 31,125,140,175,126,246, 35,236,110, 55, 56,127,248, 0,151,175, 46,241,224,201, -125, 20,117,133,215,207, 95, 78,178,146, 19,254,191,255,240,215,248,232,139,143, 17,187,195,152, 14,150, 18,190,251,213, 63,226, -233,231,159, 35,207, 11, 20,101,129,159,253,197,159,227,242,249,115,180,199, 6,251,205, 53,230,167,167,120,251,245, 47,113,254, -248, 51,116,125,196,241,246, 53,150,231,143,241,209, 87, 95, 33,245,123,210, 31,148, 57,117,140,245,125,172, 95,252, 18, 38,245, - 28, 62, 84,163, 94,158, 98, 54,207,225,204,128,253,102,131,102,127,203,156,118, 9,238, 24,128,212,195, 58,139, 7, 31,253, 4, -135,155, 75,116,205,150, 39, 72, 73, 39,104,227, 14, 60,233,186,204,152,132,114,182,194,234,193, 71, 88,156,204,145,134, 14, 6, -145,156, 15,121, 1,235, 61,140, 99, 16,146,245,176,220, 41, 75,183, 46, 62,124,234,110,232, 61, 88,151, 97, 24, 12,146,201,224, -139, 25,170,217, 9,178,162, 64,215,247,172,155, 33, 93, 77,232,143,104, 14,183, 36,184, 75, 3,189, 46, 59,142, 31, 35, 12,217, - 98,157, 83,193, 26, 21,251, 57,242,162,254,231,109, 63, 60,230,165,142, 94,186,114, 9, 13,241,106, 43,213, 61, 47, 67, 75,192, -222, 99, 25, 82,170,194, 61, 77,187, 71,234,220, 92,150,113,103, 74, 43, 48, 24,233,116,199, 3,147,194, 72,210,100, 41, 31, 53, - 54,152, 18,190, 50,184,108, 6,235,106,184,108, 6, 95, 44,224,124,141,100, 11, 88, 87,193,216, 2,198, 22,112,190,134,243, 21, -172, 47, 97, 93,174, 7,156,140,253,199,104,228,120, 7,254, 35, 7,185,142,188, 89, 71, 51,122,156, 89,176,197, 8,105,202, 77, -183,250,217, 8,213, 76, 86,115,114, 0,202,232,154, 18,202, 48,194, 93,100, 21,145,104,196,141,196, 5, 18,143,219, 97,100,236, -205,193, 45, 12, 4,139,105,202, 11,176, 99,145,104,204,157, 72, 86,153,194, 90, 55, 6, 51,201,217,161,226, 65,123,119, 76, 31, - 83, 34, 82,161,209,236, 87, 22, 7,210,123, 18,106,166,132, 11,137,206, 33,207, 51,125,142, 56, 94, 81,138, 75,233,142,103, 92, -139, 51,250,108,133, 83, 33, 22, 90,209, 79,221,225, 3, 76,130,207,135, 97,152, 28,228,230, 14,235, 93,239,209, 73, 65,247,207, -255,115, 2, 52, 26,221,206,250,236, 76,233,110, 83,111,169, 18,179, 58,122, 32,171, 80,212,110,220,177, 42,122,140, 39, 37,187, -145, 84, 53,137, 13,254,212,161, 58,141,227, 27,194,128,190, 31,198, 17,123, 98, 98, 24,135,120,200,104, 73, 50,204,227, 48,112, - 38, 56, 7,218, 51,241,168,107, 90,108,214,107,236, 55, 91,100,222, 98,126,114,130,106,190, 68, 53,171,245, 93, 80,228,231, 64, -112, 23, 47, 55,194, 8,131, 32,161,219, 17,219,219, 91,196, 4,156,221, 63,195,108, 94, 3, 48,152, 47,102,186,118,144, 3, 62, -165,196,244,187,136,162, 36,111,112,232,130,170, 45,250,182, 39, 91, 19,143,136,133,239,158, 82,130,227,137,129,207,156, 86,158, - 52,174, 49, 42,162,147, 95, 55,220, 17,139,162,218,121,199,211, 2, 67,221, 35, 39, 84, 77, 41,254,161, 15,232, 58,178,189,109, - 55, 55,120,251,230, 10, 23, 15,239,147,231,220, 57,188,121,245, 10,167, 23,103,168,231, 51,238,156, 7,132, 46, 48,119, 30, 35, -139,153, 63,203,190,235,177,223,239,245, 75, 45, 0, 29, 37,134, 25,104,113,119,115,189,198,233,249, 57, 93,159,174,197,203,103, -223,194,154,132,213,217, 10, 15,158, 60,225,135, 67,208, 47,130,238,180, 44,225,129,235,249, 12,205,225,128,148, 34, 19,217, 56, - 63, 96, 96, 66, 97, 24, 3, 97,172,115,240,121,206,133,146, 67,115, 56, 98,183,185,157, 12, 60,205, 8,201,152, 40, 76,140, 73, - 40,203, 10,137,153,204,247, 31,220,195,239,126,241, 75,228, 85,133, 15,191,248, 20,101,149,227,213,179, 87,200,203, 2,155,245, - 26,187,205, 86,199,175,224,142, 37, 14, 17, 95,254,228, 43,165,196, 25,107,209,119, 13,222,126,247, 2,159,252,232,199,248,241, -159,252, 9,182,215,239,209,118,192,205,155,239,112,239,195,207,177, 93,223,224,222,227, 71,152,157, 62,192,237,155,111,176, 56, -189,135,211, 7,143,177, 60,157, 51,102, 55,167,142,193,173,112,243,234,183,176, 38, 32, 70, 3,207, 7,122, 85,121,164,161,197, -110,179, 70,104, 54,148, 65,206,234,122,154, 64,210, 61,112,250,224, 83,120,111,177,187,126, 65, 25,232,146,119, 16, 7,142,180, -165,215,108, 13,237,211, 13, 6, 20,213, 18,167, 15, 62,193, 98, 89, 35,246, 13,186,246, 8,227, 50, 24, 62,196,157,203,136,110, -152,229,100,196,178, 14, 96, 16,136,115, 57,237,191,179, 18, 46,171,224,124, 1, 88, 25,155,231,168,102, 11,204, 22, 75,248, 60, -227, 80, 34,135,204, 91, 32,246, 8,205, 6,237, 97,141, 52,116,112, 54, 1,177,167, 85, 66, 12, 28, 62, 34, 43, 52, 94, 89,249, -140, 45,150, 57, 63,220, 51,248,188,100,110,248,216, 89, 98, 50, 53,208,238,118,194,114, 31, 83,186, 44, 79,131, 70, 42,220,120, -224,115,135, 47,193, 31,220, 85,201, 24,153, 81, 22,163, 16, 48, 70, 12,241,110, 23, 37,222,116, 57,232, 70,161,158,131,207,231, -176,190,162,105,134, 47, 0,155,147,173,207,120, 56, 87, 32, 25,199,147, 14,203,208,149, 2,201,228,128, 45, 96,125, 5,227,114, - 62, 24,121,175, 29,122,237, 80, 19, 19,214,244,240,143, 99,168,201,116, 29, 43,141,216, 93,223,124,210,224, 40,176,224,140, 72, -110,126,114,152, 73, 81, 33,187,229,164, 19, 9,185,126, 67, 24, 40,236, 40, 26,101, 5,168,229,111, 18, 19, 42,145,166,244, 8, - 51,250,204,211,164, 52,254,251, 28,255,124, 35, 49,168, 28, 35, 43, 94,119,249,124,113,135,251, 79,110,170,105, 52,173,252,119, -167,251,127,163, 83, 28, 13,136,193,216,192,165, 9,230, 77,154, 44,107,238, 10,139,165, 75,151, 53, 40,144,116, 42, 51,134,123, -197, 73,240,209,228, 94,152, 58, 20,204, 93, 39,133,193,221,215, 44, 69,168, 21,184, 15, 31,246, 86,113,222,102, 18,251,251, 79, -119,238,134,139, 11,235,189,229, 40,196,113, 95,227,120, 31, 39, 99,189,162,204,244, 48, 10, 93, 79, 42, 63,107, 52, 43,216, 78, -118,156, 25,119,160,224, 49,105,158,123, 56, 75, 68,180,190,239,168, 56,224,110, 44,207,115, 62,248,104,231, 36,130, 26, 39,251, - 48,190,161,134, 48,224,176,223,226,118,189, 65,232, 58, 20,101,129,122,113,130,147,179, 83,148, 85, 73, 20,187,204,107,229, 53, - 4,134,227,176,101,204,178,255, 57,197,136,221,237, 22,113,136, 56,189, 56,197,189,135, 23,164,114,229, 67, 51, 14, 52,234, 78, -145,170,195,122, 49,131,243, 14, 93,215,163,235, 58,180, 13,253,147,162, 82, 61,202,178, 68, 94, 82, 33, 18,135,136,178, 42,120, -180,147,208,182,129,187,126, 16,206, 51,141,235,130,209,182,101, 20, 17, 43, 54, 46,103, 45, 77, 8, 88,144, 49,132, 65, 65, 55, -116,160,247,180, 95,111, 91, 28,118, 7, 92,190,126,131,178,170,113,113,255,156, 86, 6, 77,139,231,223,190,194, 71,159,126, 56, -190, 55,134,164,116, 93, 64,215,145,186,157,168,112, 3,218,230,136,174,105,113, 60, 54,104,142,157, 38, 20,229, 98, 99,180, 35, -135, 96,187,185,193,233,197,153, 38, 13,246, 93,131,183,175,222, 32, 38,131,199, 31, 61, 69, 89,150, 10, 23, 25, 87, 81,244,101, - 12,221,145, 96, 16,161, 71,232,123, 2,159,100, 94,215, 48,194, 74,150,107, 2, 0, 85, 85,106, 26,223,126,183, 67,223,181,218, -157,219, 73, 78, 1,197, 63,142, 57,218,101, 93, 97,191,219, 97,119,251, 30,235,171, 53,206,238,221, 71,138, 3,242,106,142,147, -147, 26,195, 64, 28,254,223,253,195, 47,185,139,225,181, 72, 94,163,168,231,248,197,127,249, 57,126,242,199, 63,155,196, 80, 90, - 56,151,225,250,242, 53,206, 30, 62,196,124, 57,195,155,239, 94, 32,203, 61,169,255,151, 43,236,174,222,226,225, 39, 95,224,253, -243,223,227,228,236, 20,245, 98,129, 7, 31,125, 12,103, 2,242,156, 84,242, 61,150,216,189,127, 9,239,122, 12, 33,194,101, 5, - 22, 39,167,168,234, 28,113,232,176,187,189,193,113,119,171, 2, 76,239,189, 38,127, 1, 3,234,249, 57, 86,247, 63,192,229,179, -255,166,247,189, 0,153, 8,249, 74, 78, 6,195,161, 29,116,104, 58,172,238,125,136,229,233, 9, 98,104,208,119, 71,197,203,250, - 44,131,147,104, 96, 7, 78,161,115, 10,212,160, 14,216,113,103, 94,194,250,146,242,174,163,129,113, 25,230,139, 37,225, 95, 13, -209, 18,173, 51, 72, 49,160, 61,238,113,220, 94, 99,119,115,137,238,184, 65,232, 15,232,154, 29,186,246,128,230,112,131,174,217, - 33,198, 14, 67,104, 53, 99, 93,196,112,145, 69, 87,196,166,231, 20,188,172,212, 66, 63,106, 94,183,229,174,124, 20, 76, 9,106, - 84,124,197, 98, 93, 26,195, 81,160, 99,101,141,232,116, 30,198,121,190,110,110, 12, 27, 73, 24, 19,238,144, 84, 45, 77,207,148, -129, 5, 96,147, 3, 93,247,239, 25,165,220,101,164, 75, 72, 24,119,189,198,121,248, 60, 31, 31,208,214, 33, 25, 71, 92, 49, 51, -134,229,200,107, 52,214, 43,255, 34,114,230, 65, 24,194, 8,170,249,126, 52,167, 76, 51, 20,158, 50,194,101, 20, 78, 50,233, 27, -137, 95, 78, 26, 1, 42,232,205, 40,186, 98, 32, 14, 1,181, 60, 89,112, 49, 58, 86,198,201, 0,249,217,147, 76, 63, 32, 98,182, -239,117,154,176,236, 93, 79,227,250,130,127,134, 78, 86,153, 5,111,120, 10, 67,148, 61, 22,181, 9,180, 6,105, 18,207,107,198, -159,195, 26, 11, 90,131,102, 58, 89,138, 28,245, 43,154, 18,105, 98, 37,101, 83, 20,244,146, 58, 72, 77, 5, 1,217, 66,223,211, -234, 75,149,243, 78, 57, 9,113, 24, 65, 91,130,171, 86,209,164,168,220,133,209, 46, 25,239,186, 34,113,119, 15,115,216,137, 0, -209,170, 6,203,232, 97,239, 88,248,236,249,208, 55,255,196,179, 62,221,196, 88,164, 68,177,171,118,220,109, 11,119, 93,236, 88, -102, 2, 87,200, 11, 30, 75, 73,146,150, 10,114,172,226, 37, 29,167, 89, 13, 33, 16,139,156,225, 16,121,158,161,239,122, 85,227, - 58,111, 73,208, 37, 10, 69, 79, 74,198, 65, 41, 81, 73, 81, 10,206, 90,244, 93,135,205,122,131,195,110,135,208,119,240, 89,129, -217,201, 10, 37,191,254, 44,247, 58,190,137, 42,118,136,122,163, 58,103, 81,205, 10,244, 93,139,174,235, 81,214, 21,170, 89,141, - 44,203,148, 83, 31, 99,164,224, 17, 86, 35, 27, 24, 18,142,117,129,133, 35,134, 11, 8,222, 81, 69,186,241,229, 64, 23, 86,185, -181, 22, 93,219, 35,203, 28,103,196,123,148,101, 78, 35,116,217, 9, 59,163, 54, 56, 17, 30,138, 79, 85, 34, 18,199, 66, 32,160, -109,105, 28,223, 28, 91, 28,143, 45,117,248, 6,120,247,246, 26,231,247,239,179, 10,212,224,230,250, 26,109, 27,240,228,131,199, -172, 94,141,202,144, 86, 46,124,215, 49,217,171, 69,115, 60,162, 57,182,176,214,240, 90,192,106,248,204,152, 73, 28,208, 53, 71, -228, 5,209,232, 72, 83, 1, 92, 93, 94,226,234,237,123,156,156,157,226,236,226,130, 70,192,186,239,146,244, 44, 78, 52, 10, 1, -153,119, 56,236, 14, 40,171, 28,121,153, 79,210,183,136, 32, 39,233,121,206, 89,148,117,173,163,174,155,247,215, 92, 56,210, 61, - 7,246,237, 71, 22,229,121,239, 84,181, 92,148, 5, 98,160,244,175,245,213, 37,125,238, 53, 65, 80, 54, 55, 91, 60,249,244, 3, -154, 16,132,110,228, 55, 15, 3,170,249, 18, 9,192,245,219, 55,184,189,217,225,236,254, 3, 62, 72,168, 83, 88,157, 95, 96,121, -182,194, 55,191,252, 21, 22,231,143,176,185,124,129,139, 15, 63,199,229,215,191, 66,178, 5,118, 55,215,168,170, 12, 69, 85,227, -244,222,125,156,221, 59,197,113,183, 69,215,118, 56,116, 5,250,227, 22, 38, 30,176,189,217, 32,165,136,211,243,115,204, 79,230, - 24,250, 30,187,219, 27,242,111,115,158,130, 70,133,114,151,238,156,199,147, 47,255, 16,111,190,254, 57,135,184, 48,127, 32,209, - 30, 47, 14,228,217, 55,198, 34, 43, 42,222, 79,123,212,171, 15,176,186,184,128, 77, 29,186,195,142, 11, 34,135,188, 40, 20,186, -100,144,144,134,128,161,111, 97, 18, 21, 86, 89,158,243, 3,178, 0, 76,166,157,166,203, 10,248, 44,195,108,126,194, 46, 25,234, -222,178,140, 30,120,161, 61, 98,119,123,137,221,230, 45, 66,191, 69,140, 29, 98,236, 49,196,158, 99, 92, 35, 98,236,209,183, 7, -132,190, 65,215, 30, 48, 12, 61,226, 16,116,135, 25,120, 37,228,157,211,201, 94, 86,212,176,206,243,190,148, 0, 65, 81,125,215, - 96,109, 8,219,144, 66, 15,231,243, 81,140,102,238,118,232, 18, 26, 66,234,118, 81, 20,155, 81,200, 6,139, 40,187,242, 59, 20, - 57, 14,236, 16, 0, 74, 28,197, 80,116,160,123,248,188,134,117, 57,133,229, 88,210,100,168,154, 95, 50,201, 13,168,136, 48, 73, -227,116, 37,124, 36, 74,186, 90,154, 76, 65, 85,108, 53, 76, 50,198,211,157, 61,181, 28,148, 41, 78, 85,248,230,142,197, 76, 96, - 39,145, 21,231, 70,199,219, 78,133,149,138,116, 29, 2,195,200, 28,226, 16, 88, 60,152,184,224, 20,165,248,168, 40, 31, 99, 80, -141, 30,152,114,141,192, 68, 57,113, 54, 56,231,190, 55, 61,241, 42, 94, 27,113,171, 35, 43, 64,166, 10,100, 87,131,226, 93,237, -100,146,102,184, 72, 85, 66, 46, 79,251,100,242, 70,241,194, 20, 58,214,117,129,167,133, 14,211,122,202,186,145, 99, 34, 25, 22, - 49,113,215,143,201, 58, 99,204,229,229,207,100, 60, 99,172, 76, 43, 39, 54, 58, 57,199,244, 32,159,216,169,197,105,112,135,132, - 40,136,103,126,118,170, 85,205,140,147, 13, 37, 69, 78, 51, 87, 37, 27,136,132, 31, 19,252, 96, 26, 5,111, 72,212,241,166, 72, -190, 92, 58,180,248,129,157, 6,164, 24, 52,212, 64,152,230,113, 24, 16,195,128,188, 16, 34,221, 64,225, 46, 44, 76, 40,203,156, -198,220,153,215, 55, 64, 1, 31, 30,158,133, 92,114, 96, 2, 84, 93,249,140, 16,128,210, 69, 14, 33,160,217,239,209, 29,247,136, - 67,192,226,100,137,197,234,148,226, 43,237, 24,170, 16, 99, 66,158,231,188,179,206, 49, 91,212,152,205, 43,238,156,105, 71,156, - 23, 57, 19,218, 60,142,135,150,200,111,121, 70, 66,191,182, 67,115, 56,234,184, 93,246, 82,206,123, 21,211,137,136, 46,113,128, -139,168,213, 83, 28, 80, 20,217,196,107,106, 39, 20, 41,154, 74,116,109, 96, 95, 56,173, 15,132, 77, 95, 85, 5, 23, 70,164, 45, - 24,134,129,173, 64, 64,215,117,228,255,230, 49,107, 8, 1,215,239,222,193, 88,143,123, 15,239,177, 98,191,199,183,191,127,134, -147,179, 51,148,117, 73, 30,247,152, 24,153, 8,218,165,247, 61,246,187, 61,154,134,246,230,202,199,215, 47,137,213, 85, 74,226, - 93, 82, 74,195, 29,145,144, 1,208, 28,182,184,124,245, 6,109,211,225,193,147,199, 12,154, 8,228, 51, 6, 56,146, 20, 44, 50, -164, 16,152,195,118, 7,231, 61,178, 44,215,241, 59, 56, 36, 70,174,167, 49, 22, 85, 77,249,224,161,239,113,179, 94,223, 17, 71, - 10, 95, 91, 83,237, 88, 36,231,125,198,222,248, 35,133,201,108,111,112, 60,182, 40,170, 26,222, 39, 92,191,187,166, 95, 63,144, - 26,159, 30, 96,116,144,214,243, 19,130,130, 96,192,175,127,254, 75,124,254,227, 31,234,248,171,172,103,248,217, 95,252, 25,190, -249,135,127,192,234,254, 35,248,204,227,228,222, 3,236,111,174,145, 85, 21,251,169, 41, 65,109,182,152,225,226,233,135, 72, 67, -139,246,112, 64, 19, 10, 28,118, 71,196,110,131,219,245, 45,250,174,199,236,228, 20,213,108,134, 33, 4,236, 55,107,116,205,142, - 59,148,140,194, 54, 44, 61, 88, 8,156, 18,241,244, 7,127,138,155, 55,207,208,236, 46,201,230,153, 57,205, 12, 39, 27, 31,237, -103,179, 98, 78,226,181,172,194,108,245, 49, 78,239, 63, 2, 98,192,238,246, 10, 41, 5, 21, 13, 9, 42,185,111, 41,201,175, 57, - 28,145,210,160,214,157,161,239,128,100, 48, 36,135,152, 40, 37,206, 88, 7,159,229,152, 45, 78,244,251,158, 21, 5,107, 76,142, - 56,238,214,216,221,190, 69,215,220,234, 62,255,206,252,209, 90, 13,188, 24,239,171, 30, 93,123, 64,232, 91,205, 85,151, 83, 72, - 58, 76, 57,216,197,139, 12, 67,216,230, 49,115, 28,227,193,233, 61,172,203,117, 36, 79, 48,155,168,221,177, 28, 20, 50,197, 74, -176,128, 40,237,173,163, 61, 61,255, 94, 64, 82, 22, 3, 6, 9,237, 0, 52, 58, 89, 34, 83,197,142,102, 93, 9,235, 72, 97, 47, - 5,129, 4,205, 24,195,214, 43,231,244,224, 67, 26,115, 42, 68, 40, 74,205,209,160, 66, 54,249,185, 49, 37,141,106, 78,147,241, - 54,237,172,205,104,187, 27, 99,177, 20,255, 42,232, 85,121, 14, 73,160,207,104,223, 98,108,233, 36, 80, 68,178,206, 97,173,134, -176,200, 72, 94, 68,142,146,136, 22,185,113, 96, 96, 40, 95,247,187, 33, 42, 73, 45,122, 24, 33, 43, 19, 81,163,238,208,133,195, -206,159,115, 76,162,108, 55, 60,133,201, 52, 69,146,118,235,118, 50,242, 7, 71,132, 91, 13,197,113,206, 82, 1,155,198, 68, 55, -217,133,247, 93, 79,211, 37,190, 78,116, 29, 6, 18,187, 41,162,151,252,254,131, 10, 11,217, 78,171,180,198,105,192, 79, 82,132, -186,157, 8, 58,133,127,161,215, 67,249, 0,162,137,136, 99,194,154, 53,218,161, 79, 27,237,239,227,129,245,223, 26,238, 51,238, -217,173, 49, 81, 31,160, 69,145,241,184,211,142, 62, 71, 46, 65, 6,222, 37,200,131, 94,188,125,222, 75,218,205, 72,219,161, 46, -136,198,207,242,133, 52,214,178,122,157, 46, 64,198,172,120,173, 84,140,101,241,205, 72,244,201, 11, 47, 32, 64,133,148,136,234, -158,246,228, 13,246,219, 29,142,135, 35,202,178,192,108,177,196,201,233,138,210,183,152,147, 45,187, 14,231, 44,199,126, 38, 85, - 71, 38, 22,127, 29,246, 45,202,186, 70,201,150, 54,239,105,237, 64, 1, 40,253,152, 17, 47,192,127, 79, 15, 84,217,247,122,239, - 84, 96, 17,194,228, 6,229,221,142,168, 65, 73,232,146,152, 38,197,251, 49,238, 52,133, 73, 79, 5, 76, 36,125,131, 76, 29,216, -163,126, 56, 52, 52,214, 55,156, 18,198,215, 36,165, 1,175, 95,188,197,114,181,226, 68,161,128,190,109,240,234,249,107,124,240, - 49,117,165, 83,133,123,223, 81,135,174,157, 3,160, 95, 74,218,253,147, 24,197, 77,252,237,242,175,230,216,106,174,121, 2,208, -245, 13,214,239,223,225,234,237, 53,197,136,242, 67,222,104,108,231,248, 96,238,219, 22, 69, 85, 81, 6,187,181, 40,171, 66,251, -164,200, 90, 2,217, 13, 57,231, 48, 91,206, 73,156,210,245, 8,125,171, 98, 27, 99, 45,165,216, 9,125, 43, 4,181,229, 56,159, - 17,248,166,111,117, 90, 32,104, 87,196, 1, 69, 61, 67,123,216,163, 57, 54, 56,189, 56,163, 46,105, 32,110,120,189, 88, 98,127, -187, 65,140, 3, 46, 95,190,192,236,100, 73,133,135,181,248,233,159,253, 41,214,111,222,224,250,205, 43,216,124,134,161,223,163, - 90,158,161,217,188, 71, 86,159, 98,127,243, 14,179,229, 2,179, 69,141,147,139, 7,168,102, 21, 54, 87, 87,104, 67,142,182, 77, - 24,154,107,108,111,119,136, 67,194,217,253, 7, 88,157,159, 1, 6,184,121,255, 30,237, 97, 75,157,201,200,101, 3,192,186,131, - 20,112,246,240, 75,164, 24,113,243,246, 87,240, 89,129,188,170,120,101, 6, 94,119,116,140, 66,206,145, 23, 21,202,217, 9,150, - 23, 31, 99,117,239, 9,138,220, 97,115,245, 26,161,107,232, 62,212,113, 37, 49, 40,182, 55, 87,216,221, 94,163,107,246,104,246, - 91,244,237, 30, 93,123, 68, 31, 18,218, 46, 32, 38,203,182, 35, 32,203,201,233, 80, 86, 37,121,202,173, 35, 20,111,104, 17,186, - 29,218,195, 13, 66,183,103,143,238, 36, 63, 44, 37, 85, 76,139,154, 89, 66, 96,160,185,223, 29,186,238,136,148, 8,243,203, 78, - 52, 30,115, 78,211,216, 44,167,249,121, 18,248, 89,167, 15, 74,249,187,105, 87,202,100,204, 62, 16, 57,142, 15,158,196,147,133, -196, 4,185, 36,153, 7,252, 12,138,137,138,223, 24, 73, 5, 45, 74,244,148,164, 99,114,220,129,141,123,222, 24,147,142,219, 37, -221, 79,108,121, 17,102, 60,120,172, 99,254, 61, 70,255, 57, 23,244,218, 33,114,147, 53,196,132,158,217, 13,137,237,104, 67,164, -232,209,200, 35,108, 57, 64,233,215,227,232,195, 79,211, 29,187,157, 36,132,241,243, 16, 78,191,239,163,165,111, 50, 97,147,192, - 18, 41, 26,162,216, 26,253,100,130,106,198,168, 83, 88, 61,176, 41, 45, 19,186,143, 23,145,157,124, 63,163,210,251, 8,108, 51, -134, 3,217,209,153,160,247,134, 28,192, 78, 29, 14, 66,218,163,195,221,112, 3,224,148,161, 32, 19,229,190,235,181, 96,145, 51, -101,154, 14,151, 56,143,158,174,111, 28, 83, 71, 21, 69, 30, 57,242, 85,138,129,200,248, 88, 66, 29, 27, 41,142,227,192,186,132, -120, 55,172,197,140,234,159, 52,213,183, 11, 89,212,140, 66, 57, 61,166,229,245, 79, 38,230, 90, 60,136,232, 88, 14,248,105, 2, - 31,238,134, 10,217,253,118, 71, 7, 75,178,122, 33, 44, 91, 67,164, 19, 29, 66, 15,199,163, 89, 49,222, 75, 52,226,192,240,153, -208,135, 49,227, 24,156, 70, 6, 25,163, 68,164, 33,242,190,124, 76, 29,114,146,244,198,100, 46, 24,138, 70, 53,119, 60,121, 22, - 62,119,200, 10,178,215, 89,217, 63,243,174,213, 32,225,184,219,227,230,154,236, 63, 62,207, 81, 47, 23,168,231, 51, 61,156,172, -179,204, 61, 55,234,177,148,139,211,183, 29, 54, 55,183, 56, 30, 90,204,151, 75,204,151,115,142, 28, 13,104,142,173,170,242,187, -142,246,224,244, 64,243, 99,128, 8,239,118, 68, 0,226, 61, 77, 25, 4,206,226, 29, 89, 5, 19, 8,153, 75,234,245,168,241,142, -194, 14,142, 98,157, 99,237,130,242,173,249,131, 47,120,119, 73, 49,182, 57,199,128, 58,100, 89,142, 56, 68, 52,199, 29,188,207, -240,228,131, 71, 40,248, 90,221, 92, 93,161,239, 6, 60,122,250, 80, 21,253,161,239,153, 52,149, 70,180, 47,167,213, 89,249, 2, - 25, 51,106, 1,120, 71,228, 88,125,187,190,186,193,234,108,197,171,149, 0,147, 18,246,219, 27, 92,190,122, 75,104,211,122,166, - 7, 13, 56,174,214,176,224,232,184, 63, 98,182, 88,168, 56,141, 16,182, 99, 82,148, 99,215,131, 84,225, 69, 89,194, 57,139,195, -254,192,175,153,190, 34, 86,209,142,142,239, 75,175, 24, 80,242,175, 2, 93,219,168,192,101,177, 58,195,238,118,131,208,247, 88, -172, 78,240,245, 63,254, 26,255,238,127,255,119,248,224,243, 79,121,149, 2,100,229, 12,229,172, 66,119,220, 97, 8, 1, 93,215, -224,230,253, 53,206,238,223,199,211,207,191,196,234,108,133,175,127,249, 11,184, 44,199,226,100,134,243, 71, 31,224,230,205,105, - 79, 91, 20, 0, 0, 32, 0, 73, 68, 65, 84,183, 88,222,127,130,195,250,146, 92, 13,222,225,228,236, 12,203,139,251,104,247, 27, -172,215, 71,244, 49,199,241,246, 45,110,215,132, 44, 94, 93, 92, 96,113,122, 14,107,128,205,250, 6, 93,115,224,107,238,244, 97, - 41,163, 66, 99, 12,102,203, 7, 56,123,252, 49,222,126,253, 95,128, 20, 81,205, 78, 80,215,149,222, 23,125, 71,247,168,245,148, -232,230,179, 18,213,226, 30,206, 31,125,140,170,174,112,220,222,234,104, 27, 41,162,111, 27,196,208,163, 59, 30,209,182, 13,175, -149, 70, 91,161,116,159, 98, 49, 35,133,177,101,171,219,140,199,242, 57,239, 91,123, 26,161, 55,123, 52,251, 53,237,200,229,129, -149, 70, 74,150,115,153,118, 62, 50,174,150,206, 38,113,128, 81, 98,182,121,215, 82, 8,143,181,208, 68,193,209,234, 52,142,119, -101,239, 45,193, 34,210, 33, 81,151, 60,238,166,105,194,150,116, 74,166,222,105,177,199, 1, 24, 88,161, 45,248,107, 76, 34, 89, - 99, 74,176, 54, 39, 33,153,201,238,210,213,141,213, 8, 80, 99, 51, 22, 16,242,193, 26,185, 80,230, 12,239, 33, 70,180, 13,113, - 38,186,190, 67,215,117,180, 10, 11,100,155, 37,155, 41, 93,143, 97,160,253,182, 40,199, 41,218,115,224, 17,247,221,142,119,186, - 27,150,195,125,252,181, 56, 10,183,184, 43,159,166,196,129, 53, 6, 41, 6, 45, 22, 8, 47,157,233, 84, 65,227, 70,195, 72,184, - 35,241, 92,212,105,192, 84,160, 40,184, 93, 41,182,232,247, 74,167,110,217, 97, 97,238, 8,202, 98,148,215,102, 38, 22, 67,167, - 66,190, 81, 33,207,214,232, 44,231,191, 99,124, 78, 73, 55, 43, 29,173,132,113,137, 94, 76,193, 73,102, 18,151, 58,121,230, 26, - 3,100,158,119,246,102,146,115, 63, 1,207, 64, 83, 15,157,174,199, 36, 9, 81, 86,165, 42,220,140,152, 60,191, 39,171, 6,221, -169,143, 14, 30, 43,175,141, 39, 24,110, 18, 54, 35, 13, 45,237,210,199,224, 24, 59, 41, 14, 68,224, 39,207, 64, 27,251, 30,206, -146, 50, 61,231,195,128, 42,115, 26, 59, 65,192, 30,102,140, 94,204,242, 81,145, 56,142,164, 29, 83,139, 44, 41, 53, 57, 68, 1, -147,152, 63,201, 60,151,125, 1,209,181,204,228, 3,177, 19, 95, 32,231, 41,195, 32,244, 81, 59,117, 51,217,111,201,239, 5,119, -147,155,155, 13,186,166,161, 73, 64, 81,162,154, 47, 80,148, 37,234,121,173, 7, 60,237,184, 39, 20, 50, 86,241, 55,135, 35, 14, -187, 61,178,130, 44, 75, 4, 96,161,131, 11,140, 59,148,155, 39,227,213, 66, 8,145, 99,101,163, 22, 60, 50, 14,177, 50,226,233, - 3,218,182,225,174,131,174, 69, 94,228, 12, 94, 25,101,219, 33,144,165,172,239, 58, 28,143,237, 24,219,103,104,191,153, 23, 5, - 22,203, 37,138, 34,135,247,142, 38, 19,243, 25,156,183,168,103, 53,242,204,225,246,230, 22,247, 30,222,199,201,233,146,248,234, -185,199,229,235, 75,172, 88, 80, 72,239,103, 80,241, 33,197,170,210,151,109, 96, 26, 27, 89, 2, 69, 48,101, 71, 17, 36, 87,243, -251,237, 22,171,211, 51,221,111,211,196,100,143,227, 97,135,188,200,113,241,224, 33, 23,101,137,109,116,137,163,104, 29,246,219, - 45,165,181,109,183,196,250, 47, 75,101, 82,203, 8, 76,236, 33, 68, 37, 36, 52,108,115,108, 53,119, 94, 50,166,101, 85,227,179, - 76, 83,146,196,195,109, 77, 68,232, 26, 13, 61,168,102, 11, 92,191,121,131, 97, 72, 88,157, 45,241,205,175,127,131,155,171,107, -184, 60,199,167, 63,248, 20, 49, 70,204, 87,231,100,233,219,221,114, 17, 58,224,245,179, 23,248,224,243, 79,241,227, 63,249, 67, -252,221, 95,253, 39,164, 24,113,114,239, 17,246,183, 27,236,111,215,200,235, 37,182,215,107, 84,149, 39,221, 68, 89, 34,171, 22, -200,114,135,235,203,107, 4, 84,216, 93,191,194,250,253, 26, 67, 8,168, 23,115, 84,243, 19, 24, 3,236,119,123,180,135,221, 24, -148, 1,139, 44,203,225,189, 81,252,164,207, 10, 60,254,226, 95,224,229,175,254, 51, 98,108, 73, 41, 63,155,241, 62,150, 2, 35, -250,190,165,233,138,179,176,222,193,231, 5,150,231,143, 96,173,193,238,118,141,174,107,224,153,170, 54,198,134,210,222,154,114, -236,229, 80, 76,188, 7, 38,175, 56,201, 90, 28,103,217,159, 32,243, 14, 62,167, 61, 49, 57, 37, 2, 98,232, 17, 58, 18,191, 13, -129, 44,107,130, 33,149,221,180, 68,160, 26, 41, 90,248,193, 29,153,252, 53,210,195, 70,124,107,215, 30,168, 40,100, 5,180, 49, -208, 17,244,157, 24, 82,201,242,150,208, 26, 62,136, 52,155, 91,132,116, 60, 53, 27, 98,212, 93,251,192, 7,169,170,214, 37,154, -115, 32,193,236, 16, 5,243,156,235,190,157,158,139, 28, 47,106,198, 98, 33,175, 22, 28, 25,234,184,168,100,174, 56,123,223, 67, - 8,232,218, 14,109,115,196,126,183, 65,115,220,163, 61, 30,176,189, 93,227,176,223, 81,113,213, 7,116,125,207,135, 60, 61,115, -194, 16,180, 99, 36, 33,155, 88,172,160,221,240,247,119,236,162, 35, 16, 61,140, 50,139, 34,121,236,105,194, 38,147,140,129, 74, -118, 67, 83, 44,162, 60,122, 42,164, 18,107,161, 32, 86, 51,175,215, 72, 86, 30, 73,247,246, 36,234, 75,162, 67,144, 36, 63, 73, -102, 99,110,187, 40,237,169, 43,183, 74, 11,116,124,157, 40,110,122,132, 27, 89, 3,118, 95,184, 9,136,136,166,142,214,102, 26, - 87, 43,170,118, 17, 15, 78, 83, 2, 9,253,237, 88,177, 62,242, 85, 70,192,205, 24, 43, 60,240,212, 68, 34,156, 49,205, 75,103, -244,185,136, 37,167, 10,119,113, 20,105,186,156,172, 7, 49,229,179,143,163,123,197, 97,167,169,192,109,156, 24, 37, 13,134,153, -140,225,217,114, 43,108, 17, 5,187, 25,123,103, 23,207,247,187, 65, 28,122,142,224,172, 56,123,121, 80, 15,156, 68,157, 74,192, -134,136,188,140, 1, 98, 8, 35, 5,140,171, 12,129,143, 16,240,128,254,153,101, 78, 1, 13,134,147,223,136,149, 27, 21,205,106, -172, 65, 81,120,100,153,213,232, 79,177,121,249,140,246,234,224, 49,177,153, 78, 17,216,191, 77,187,147, 12,109,211,226,184,223, - 35,116, 29,178,204, 99,121,122,130,197,201, 9,170, 57,237, 33, 19, 70, 17,199, 48, 16, 49, 79,130,108,226,208, 99,253,254, 26, - 41, 25, 44, 79, 79, 80, 86, 5,135,200, 36, 37,209, 21,101, 6, 3,203,194, 56, 76,132, 28,244,224,145, 15,192,106, 36,165, 80, -157, 70,123,131, 36, 16,201,158,170,239, 8,186,210, 54, 13, 17,224, 98, 68,203, 74,245,190,167,255,100, 89,134,170,174, 49,155, - 47, 52,163,157,136,120, 37,140, 33, 60,239,250,234, 26,128,197,189, 7,247,248,115, 50,104,219, 6, 47,158,189,198,135,159,126, -168,175,217,178,226,158, 98, 89, 51,238,116, 5,110, 48,230,204,123,239, 24,174, 0,173,104,223, 95, 94, 98,121,186,226,130,104, -224,162,166,199,250,253, 59,180,199, 22,159,254,224, 83, 24,174,110, 69,188,150,152,115,217, 28, 15,168,234, 26,161,107,208,247, - 61, 81, 2,141,213,116, 43,242, 1, 71,117, 18,212,243, 26, 41, 69,181, 23, 90,182, 16, 10, 3, 64, 4, 55,214, 57,173,150,243, -178,226,221, 60, 85,180, 69,185,192,195, 39,231,232,142,123,216,172, 64,223,182,188,159, 12,216,111,118,152, 45,151,152, 45,102, -168,230,115, 28,119,155, 73,106, 20,197,250,254,228, 79,255, 16,191,253,249,223,161,107, 91,248,188,192,124,117,134, 98,182,100, - 1,166, 69,230, 3,170, 89, 73,247,105,158, 97,121,118,134,245,187,119,104, 99,137,227,205, 37,174, 47,223, 35,166,136,162,240, -152,175,206, 49, 95,212,136, 41,226,184,219,170,191,120,244,245,122, 26,175,115, 55,252,232,243, 63,192,155,223,255, 61, 97, 96, -173,199,242,244, 2,121, 81,114, 84,114,196,126,115,139,161,239,224, 88, 93, 93,148, 21, 78,238, 63,165,233,198,230, 22,125,215, -232,158,216,231,149,146,212, 52, 88, 36,142,241,153,214,149,136,200, 16, 6, 32, 38, 58,184,242,188, 64, 61, 63, 65, 85, 87, 40, -103, 51, 62,140, 7, 74,190, 75, 3, 66,119, 68,215,236, 32,234, 36,101,172, 39, 14, 85,241,126,226,193, 5,143,198,253, 68, 36, - 52,142,103, 5,171, 41,120,213,174, 59,162,235, 26, 94, 25,181,228,113,103,162,157,160,162,133,185, 50, 76, 56,235,194, 9,215, - 7,249, 16,116,189, 5, 99,209,115,163, 34,163,207,190, 15,128,241,186,231,164,115,209,115,119,157,116, 63,174, 94,109,101,143, -243,238,216,230,164, 12,103, 11, 32, 21, 79, 60,202,103,171, 89,223,245,104,154, 3,218,166,225, 53, 29,123,169,141,231, 46, 54, -241,193,223,146,232, 49, 70, 14, 17, 1, 31,242, 29,239,171,105,228, 30,181, 91, 78, 58,202, 7,143,214, 85, 64,167, 71,138,168, -177,167,182, 43,126, 97,201,232, 20, 13,204,241, 55, 83,166, 45,192,236,115,232,123,178,206,179,160,208,241,251,247,204,204,103, -123, 95, 28,113,182,186,131,215, 16, 45,167, 62,121,213, 95,241,159, 51, 18,212,103, 51,205, 13, 17,220,170,172,111,100,100,237, -188,215, 2, 65, 16,176, 36, 72,148,213,225,168,188, 39, 65,101, 82,183,145,138,247,120,125, 16,239, 88,211,146,134,186, 76, 5, -104, 73,161, 51,172,151,210, 81,251,228,207, 73,240, 86,156, 0, 96,205,100,231,109, 70,199,130,153,146, 18,229,240,214, 48,161, - 72, 86, 90,235,120,202, 57,177,240,106, 92, 45,199, 16,203,238,221,140, 60, 25, 86,191, 3, 93,211,208,167, 96,188,238, 53,169, -123,151,196,158, 65, 73, 94,100, 87,227, 64, 1,102, 75,167, 56, 32,116, 61,139, 50, 0,239, 28,239,216,233,193,219,235, 14,130, -118,186,146,213,237, 89,197, 8, 67, 63,139,212,243,134,197, 83, 17,158,247,226,196,136,151, 61,114,186, 99,101,202, 25, 28, 35, -158,241, 44,231,236,245,216, 99,191,221,146, 74,222, 59,204,230,115,212,243,153, 90,129, 66,224,221,191, 78, 14, 12, 41,193, 15, - 7, 92,189,125,143,208, 71, 44, 79, 87,196, 29,103,225,140, 87,139, 12, 70,127, 42,135,204, 20, 37,197,153, 58, 79,126,127, 25, -243,123,111,225, 50, 74,158,138,145,119,230, 34, 82,234,169,130,183, 22,216,239, 14,232,218,158, 38, 6,251, 3,218, 35, 85,239, -212, 85,211,107, 93,174, 22, 56,189, 88, 81,146, 24,119,170,146,207, 76,100, 61,135,215, 47,223,226,244,226,140,130, 67,120,122, -176,189,185,193,225,208,225,201,135,143, 40, 90, 52,243,204, 30,240,252,160, 76, 10,163,160, 52, 62,190, 46, 24, 87, 12,146, 76, -213, 53, 71,212,243, 90,247, 83, 98, 37,219,111,214,216,220,220,226,193,211, 39,152, 45,150, 28,208, 50,140, 42,120,231,209, 30, -143,168,102, 53, 98, 12,232,154,150, 83,228, 10, 5, 87, 59, 79, 83, 30,107, 13,234, 89, 77,187,173,129, 51, 2,238,220,216,137, -191,176, 92,165, 99,236,242,138,178,164,251, 57, 69,196, 20,113,255,233,231, 56, 61,155,195,101, 25,150,167, 43,188,125,254, 18, - 85, 61, 67,150,101,168,103, 21,190,249,245,215,120,250,217, 39,180,235,223,109, 38,108,115,224,179,159,254, 12,135,221, 30, 55, -239,222,113,120,202, 19,212,203, 19,236,214,239, 16, 81, 96,104,183, 40, 74,226,245,231,101,137,188,204, 41,166,246, 54, 96,119, -245, 22,183, 87,239, 16,250,128,178,112, 40,231, 39, 40, 10,143,174,235,176,189,217,168, 38, 35, 38, 32,194, 97,148, 45,208,131, -250,241,231,255, 2,251,245, 37, 14,155, 55,148,239, 62, 95,161,168,102,108,211, 2,218,230,128,246,184, 87,177,170,207, 75,204, -207, 30,147,173, 48,208, 97, 75,110, 8,207,227,200, 28,214,151, 52,222,101,205, 5,233, 92, 42,164,228, 1,203, 35,100,230,190, - 23, 69,133,162, 44,233,243,177,185,250,115,169,232,234,112,220,173,209,183, 7, 46,106, 49,114,189,149,252, 54, 66,172, 18,119, -253,218,113,137,114,151,150, 41, 19, 95,115,186, 27, 56,153, 6, 12,172,156, 55,130,231,228,177,189,168,168,233,123,153,141,221, -100, 2,123,158,141,134,126, 36, 36,244,125,224, 14, 12,188, 94,233,212,149,163, 84, 53,246, 54,247, 97,224,245,151,101,112,138, -103, 0,140,103,235,154, 25,105,107, 89,201,228, 59, 62, 76,120,167, 44, 19, 72, 24,131,166,105,184,120,144,189, 61, 16, 19,199, -209, 2,108, 19,164, 29,239, 48, 80, 96,139,176, 59, 20, 57,170,129, 53,134,199,240,163, 72, 45, 37,153,112, 90,181, 4,210,175, - 25, 85,209, 79,187, 76, 89,141,196, 68,147, 10, 57,216,229,208,164,252, 3, 74,216,171,231, 75, 98, 5, 88, 18, 37,210,225, 13, -221,163, 15,195, 64,178,113, 14, 82, 18,151,129, 20, 24,164,141,152, 8, 7,157, 27, 21,220, 60,102,167,194,105,146, 83,142,187, -133,129,172,227, 36,123, 94, 61,234,142,236,196,211,196, 64,106,250, 44,131,188,232,231,122, 70, 59, 43,102,214, 10,151,197, 41, -116,106,154, 63, 65, 13,108,210, 98,203, 72,132,239, 16, 85,216, 39,233,166, 35,227,128, 15,118, 17,186, 73,144,139,228, 34, 76, - 68,115,150, 93, 43,162, 39,155,102,135, 88,142,255,133, 25, 71,245,162,142, 31, 87,227, 86, 27, 81, 76, 3, 97,216,238,102,105, -180,154,248,240,243, 44,240,192,157,240,247,129,197, 95, 41, 14,136,161, 31,115,176,185, 83, 22, 11,220, 16, 6,218,139,246,129, - 25,222,145, 59,118,163, 9, 61,163,109, 14, 52, 46,244,158, 80,160,206,168, 34,158, 44, 59,153, 90,229,228,203, 43, 54, 53, 10, - 23, 16, 2, 80, 82, 69,163, 84, 74,214,144, 13, 41,203, 8, 94,179,223,237,176,219,238, 73,113,157, 23, 40,138, 18, 89,238,137, -100,101,140,142,227,135, 48, 32,244, 3, 66,223,227,118,189,198, 97,223,224,228,108,133,197,106,206,126, 93,186, 33, 41,219,122, -180, 28, 89,222,129,203, 94,195,103,142, 67, 98,200, 86, 84, 20,197, 29,241,157,140,119, 68,240,119,216, 55, 12,235,233,121,151, -223,160,107, 91,116, 13, 69,117,250,204,161,235, 3,154, 99, 7,239,115, 44, 87, 75,228, 5, 85,180, 3, 91,192,242, 34,195, 97, -223,224,246,154,194, 94,206,238,221,211,235,157,144,240,242,187, 23, 56,187,184,135,135,143,239,163, 40, 75,204,231, 51,170,110, - 57,165, 8,124, 3, 91, 51,221,113,165, 49,197,137,217,223, 41, 18,191,155,120, 0, 65,199, 73,125,215,224,253,219, 75,148,117, -141,135, 79,159,144, 37,134, 71, 90,194,181,238,187,142,217,220, 22,251,221,129,189,225,153,170, 70,105,183, 75, 95,226,162, 42, - 96,121,159, 62,142,166,172,142,178, 4,108, 33,116, 62,239, 51, 85, 99, 15,125,171,209,158, 95,252,244, 71,136,125, 11,155,149, -168,231, 21,190,249,205,215,152,205,106,148,243, 57,178, 60, 67,215, 30, 97,125,137,204, 59, 52,135,157,186, 63, 62,248,252, 7, -120,252,209, 19,188,126,246, 2,139,213, 9,156,115,120,244,201,103, 24,218, 45, 81,191,250, 29,178,140,238,199,114, 54,163,160, - 23,147,227,118,189, 71, 56,110,113,245,230, 13,154,195, 17,222, 14,168, 23, 43, 84,179, 25,250,126,192,237,213,181, 82,239, 0, - 34,161,165, 72, 65, 68, 82,205, 95, 60,253, 12, 62,243,216,188,251, 22,214,102,164,100, 63, 57,167,117, 5, 44,134,208, 97,127, -251,158,114,174,121,181,177, 60,125,192,171,141, 13,182,235, 43, 86, 81,211,119,114,204,108, 38,127,185, 28,164,195, 96, 48, 68, -242, 79, 15,145,118,231, 9, 14,179, 57, 9,254,202,122, 14,151, 21,250, 16, 11,109,139,238,176,193, 97,187, 70, 8,157, 78,118, -188,207,225, 92, 14,231, 50,100,121,133,178, 62,161,177,169,203,148, 48,230, 20,164,145,233, 78,122,220,151, 26,221, 1, 79, 31, -248,195, 16,104, 42,128,136,132, 65,187,159, 36,106, 99,182,194,142,190,106, 94,197,113, 7, 59, 42,134,141, 78, 59, 99,138,232, -250, 94, 5,191,150, 9,116,114,128,139,248, 50,193,192,176, 8,139, 86, 19,126,228,158,115, 82, 27, 49,235, 11, 88,159, 81, 18, - 25, 44,239, 82,169,168,105,142, 13, 14,251, 3,113, 41,108,198,254,254, 2,128, 87, 47,119, 76, 86, 59,238, 16,162,114, 44, 36, -110, 54,178, 56, 78,199,236, 2,158,225,127, 2, 14, 49, 69, 68,217,111,167,113,188, 27, 53,191,211,142, 10,119,141, 33,141,119, - 2,122, 44, 91, 33,171,249, 2, 69, 53,131,247, 5,242,178,130,243, 37,178,178, 70, 86,206,144,229, 51,100, 69,205,160, 26,154, - 68,200, 58, 6,102, 12,111,193, 29,160,138, 97, 93,130, 99,208, 88,210, 67, 74,224, 57,244,225,176,111,159,209,178, 0,137, 97, -189,207,120,229, 48,113, 45,196,168, 41,141,134, 59,119, 33,103,122, 22, 96, 59,235, 39,142,135,187, 20, 74, 99, 70,111,188, 26, - 2, 37,230,212,178, 64,114,194,229, 23,188, 46,245,179, 65, 11,160,196, 69,205, 24,229,157,120,242,104, 70,109, 1,140,240,114, -248,126, 31, 1, 96, 90,160, 78,149,236,198,222,201, 72,151, 51, 98,228,200,196,187,192,119,195,128, 56, 77,205, 51,176, 62,115, -136,125, 15,131,129,187,226, 2,121, 81,178, 85, 38,194,130,186,246, 20, 57,156, 4, 9, 67, 31, 88,185, 61, 48,185, 43,142,230, -251, 52,166,197,165, 9,226, 52,165,136,140,197,109, 18,191, 71,126,217, 92,111, 44, 25,165, 58, 55, 86, 90, 46,115,250,224,202, -178, 17,214, 31,195,192, 99, 54,218,113, 59,239, 85,176, 86,176,109, 78,196, 95,206, 89, 56, 11, 28,182, 59, 28,246, 71,102,100, - 83,144, 11, 5,155, 68,180,109,135,190, 39, 15,183,140, 55,104,239,181,195,108,190,192,201,233, 9,237,207,138,140,247, 82, 52, - 71,161, 3,219,115,113,146,169,239,124, 8,244,197,242,153, 71,215,243, 14,147,133, 51, 49, 38,116, 93,135,190, 35,124, 44,237, -240,232, 1,220,182, 45,134, 97,192, 97,223,160,109, 26,181,117,196,129,213,152, 6,196,233,206, 11, 58,132,157, 81,155,154, 49, - 6, 33,244,120,241,237, 75,156, 94,156, 97,177,172,145,229,158, 39, 10, 1,111, 94, 93,226,147, 47, 63, 71, 61, 95,160,172,103, - 88,174, 86,168,217,167, 47,227,216,190, 31, 16, 89,213, 73, 46,133,156, 43,222, 65,247,177,135,253, 17,139,197,114, 12, 67,224, - 27,114,253,238, 18,251,205, 30, 31,126,246,137, 86,163,113,136,252,153,122,229, 78,123, 79, 89,247, 89,158, 97, 54,159,179,160, -114,204, 68, 39,145, 92,129,162,200,177, 89,111, 52,137,205, 50,156, 71, 51,175,217,105, 17, 24,214, 98,173, 67, 81,148, 56,238, -119, 0, 18,230,171,135, 56,189, 88,225,120, 56, 98,113,118,134,102,183,195,205,213, 59, 24,107,177, 60, 61,213, 81,217,230,118, - 7,159, 89, 12, 61,141,230, 23, 39,167,248,131,127,253,231,248,155,255,240,255,160,217,237, 81,214, 21, 86, 15,159,194,231, 25, -154, 99,139,174,235, 80,228, 64,158,121, 44, 86,167,240,222,162, 15, 6,109, 27,112,216,109,241,254,213,115,132,174,129,119,137, - 58,244,154, 38, 27,219,155, 27,116, 93,175, 66, 44,231,233, 32,116,188, 27, 76,113, 64, 57, 63,195,236,244, 30, 94,254,246,191, - 1,198, 33, 43,103, 88, 93, 60, 70, 53,155,243,222, 50,162,217,111,208,119, 71, 12, 67,143, 52, 12,152,173, 46, 80,212, 21,154, -253, 22,205,110, 77, 64,140, 24,185,195,100, 68, 42,172,118,179,198,229,112,121, 13,235,100, 82, 96,117, 39, 57, 95,204,144,151, - 4,155,161,221, 51,237,117,211, 16,208, 30,183,232,219,195,196,162,149,177,141, 43,167, 32,154,217, 9,202,122, 1,159, 21, 40, -235, 57,178,188,226,253,191, 81,123, 87,210, 24, 88,163,251,195, 17,254, 52, 6,142,104, 32,201, 68, 59, 44, 7,184,192, 67,198, -135,238,152,249,240,253, 20,172, 33, 70,218,157,243,152, 53, 14, 3,140,117,188,183, 54, 42,146,211,177, 53,187, 33, 84, 16,150, -162, 22,237, 67, 4,147,230, 56, 67,158, 83,200, 98,156,164,191, 97, 66,122,227,233,164,116,157,162, 37, 16, 27, 93,156,240,211, - 71, 70,157,101, 88, 84,224, 93, 58, 84,100, 6, 8, 51,223,234, 94, 60,178, 88, 76,187,115, 86,189,235,152, 95,130, 98,166,218, - 1, 1,192,112,110,130,207,114,212,243, 5,138,178,230,226,204, 79,158,191,153,102,150, 39, 24, 88,159,147, 23,223,231,122,192, - 26,166, 49,194, 88,186,151,210,212, 25, 64,207,193,190,235,117,237, 66, 19, 72, 40, 48, 72,124,220, 98, 41,139,201,232,184, 59, -113,234, 25,193,123,168,248,242,124,223, 14,113, 44, 90,172, 27,173, 98,214,209,239,149, 35, 59,203, 29,237,225,121,101, 39,231, -148,166, 88,178,238, 33, 73, 86, 7, 12,188,179,122,224,199, 97,184,227,187, 55,186, 50, 74,255,132,102,151, 52,151,100, 82, 84, -106,168,155,157, 36,184,152, 59, 64,178,113, 69,245,253,131,221, 40,155, 67, 67,154,116,236, 78,197,152,104,175,140,132,170,129, -161, 7, 41, 14, 64, 28,224,243, 98, 18,155,234, 89, 40, 53,138, 10, 72,165, 55, 0, 60,246, 75,137, 2, 27,200,190, 68, 49,165, - 98, 53,232,187,142, 31,190,131,226, 96, 13, 11,131, 2, 43, 61, 37,226,116,190,156,195,103, 25,178, 44,227,174,152,136,114,218, - 77,242,135, 36, 88, 76, 76,240,121,130, 79,165,145, 12,141, 55, 40,152,132, 97, 42, 24, 73, 73, 49,244, 56,236,142,104,142, 13, - 98, 2,138,138,124,235,113, 96, 70, 50,103,240, 22, 21, 29,214, 45,171,227,125,158,225,244,226,148, 51,198,105, 52,151,101,158, -173,115, 70,177,175, 50, 94,177, 19, 98,163,101, 29,129,166, 46,177,210, 56,242,204,213, 24,242, 11,183, 77,199,138,230, 65,189, -235,125,215, 77,132, 59,132,175,141, 67,196,226,100,129,178, 40,248,186, 10, 65,143, 4,123,135,253, 6, 55,215, 91, 60,120,252, -144, 85,235,116, 0,110,214, 55,136, 49,225,195, 79, 62, 96,240,206, 12,243,197, 18,203, 19,210, 29, 20, 69,161,176,161, 44,227, -108, 97, 63,146,250, 4,244,114,123,125,131,179,139,123,147,241, 17, 61,100, 15,187, 91,188,248,230, 37, 78,206,239, 81,122, 92, - 8,148, 64,135, 17, 94, 20,135,136,162,172,112,216,237, 72, 44, 87, 85, 92, 16, 70,205,169, 47,171,146, 59,181,136,205,237,134, - 17,188, 81,173,117,198,144,176,147,130, 51, 34, 28, 79,104,140,245, 40,202, 28,135,221, 14,128,193, 71, 95,126, 5,203,233, 90, -203,211, 21, 46, 95,188, 66,232, 73,176, 84,148, 21,209,212, 18, 96, 82,194,233,249, 18,198, 36,100,222,227, 95,253,219,127,131, -175,255,225,151,136,161, 67,223, 53, 40,103, 53, 30,126,252, 41,118,235,107,116, 77, 75,157,227, 16, 80,206, 23, 48, 32, 74, 97, - 62, 63,195,126,179,195,139,223,254, 6,205,126, 15,139, 30, 85, 61, 67,189, 88,194, 34,225,230,253, 21,229, 6,232, 67,192,179, -216, 10,106, 15,204,171, 5, 30,127,246, 67,188,249,253,223,211, 94,209,103,152,159,156, 99,190, 58,229,221, 37,197,183, 54, 7, - 18, 26, 58,239,113,114,255, 41,234,197, 10,205,126,139,235, 87,191,199, 97, 71,106,119,153,146,145,247, 60,114, 23, 40,136, 85, - 79,157,165,245,176, 62,131, 49,132,131,173,102, 21,124, 78,129, 44, 68,120,164,207,165,111,143,104,246, 91,132,174,153, 88, 68, - 61,143,128, 19,139, 71, 43,212,179, 57,242,178, 66, 81,214,200,138, 10, 89, 94, 81, 39,235, 28, 63,124,204,100,189,225,148,118, -102,140,120,146,133,206, 53, 73, 19, 75,228,159,206,178,252, 78,204,232, 29,223, 46, 79,163,156, 38,110,165,137, 42, 28,170,159, - 25,115,191, 49,142,124,245,181,140,157,163,181,226,135,183, 42,202,149,172,117,186, 87,217,104,107,233, 26, 8,253,140,176,124, -158,163, 63,193,251,226,164,234,239,196,142,130,152,198,162,196,218,169, 0,205,221, 73,248,146,149,135, 20, 31,178,243,191,227, - 25, 23, 15,184,138,229, 24,221, 58, 69,200,106,156, 41,113, 35, 18, 4,162, 67,110, 17,159, 21,240, 57,125, 78, 62,243,112, 89, -174, 26, 15,133,190,176, 56, 48, 37,199,161, 59, 20, 70,227,124, 62, 25,241,219,113, 4,143, 49,112,103, 8,131,210,227,134, 48, -144,229,207, 57, 37,101,202,158,152, 38,161, 78,247,235,208,137, 18, 77, 74,172, 33, 33,226,192,207,165, 60, 47,180,152, 27, 2, - 33,194,115,110,178, 28, 55,135,198,138, 11,194, 78, 84,250,106, 65,103,209,157,209,113,182,230,160,243,129, 33, 98,223, 41,187, - 37, 77,160, 96,227,164,105,116,123,164,201,121, 35,129, 68,134, 29,101,212,149,143, 35,247,201,226,126, 18,103, 12, 37,140, 78, -233,113,163,218,157,239, 24,193, 29,171, 91,205,193,152, 4,111,157, 81, 49, 74, 86,148,240, 62, 67, 94,205,216,139,199,201, 79, -133, 69,232,123, 13, 26,137, 19, 36,158,132,111,128, 59, 39,128,189,150, 60, 18,143, 33,192, 88,135,122, 49,195,249,195,135, 44, -218,201, 38, 95,152, 49, 82,146, 58,191,136,190,105,208,247, 45,113,201,119,205,104, 77, 19,200,183,145,221,158, 81, 79, 59,238, -100, 26, 39, 37,214,137, 74,218, 58,163, 21,184, 69,226, 49, 56,189,206, 44,243, 88,156, 44, 41,130, 54,108,185,227,141,227,152, -198, 0,205,225,128,178,170, 49, 91, 46, 96,221, 1,237,177, 69, 53, 43, 9,172,195,138,113,162, 18, 89, 78, 64, 35,180,161, 55, - 6, 49, 24,116, 45,117,149,125, 23,244, 75, 73,249,243,212,173, 7, 78, 40, 19, 33,143,227,221, 59,141,234, 91, 84,117,197,161, - 43,129,190,120,206,161,158,207, 8, 91,155,100,122,146,244,207,188,123,115,137,207,190,250,140,108, 77, 7, 18,224, 56,231,240, -252,155,231,248,242, 39, 95,162, 57, 28,177,185,221, 33, 47,115,202,170, 47, 50, 45,140, 72,112,120,164,247, 18,199,112, 28,129, -221,172,175,214,120,240,240, 1,158,125,253,245,168,113,112,196, 71,127,245,221, 11, 60,252,240, 9, 86,103, 23,184,124,245,138, - 71,101,252,165, 49,180,115, 94,172, 78,208, 28,142,128, 1,234,121,205,157,247,200, 51, 46, 74,210, 3,132,190,199,241,112,128, -177,231, 8,161,135,247,163,165, 67,231,169,178, 38, 64, 2,165, 70, 38,132,190,129,243, 37, 30, 60,121,128,162,204,112,140, 3, -202, 50,195,243,223,127,131,148, 18,118,219, 61, 30,242,248,213,103, 57,226, 16,176,227,137,204, 87,127,240, 47,113,220,237,241, -254,245, 75,228,185, 71,138, 3,150, 15, 30,161,154,149, 56,108, 54,112,166, 67, 86, 44,144, 59, 10, 3,218,111,110,209, 5,143, -174, 79,120,255,226, 57,154,253, 22, 38,181,200,235, 25,138,249, 18,121,110,177,185,185,193,113,191, 99,225, 39,137,178,134, 52, - 58, 33,172,165,168,213, 39, 95,252, 20,175,127,255, 11,206, 65,200, 81,205, 79, 48, 63,153,147,242, 53, 38,154, 28,173, 47, 49, -176,255,127,113,250, 24,171,139,135,216,111,118,184,125,247, 12,125,123,228,132,173,136, 44, 43, 56,125,139,166, 52, 33,208, 97, - 99,156, 7,236, 64,228, 58,231, 97,189,197,172, 20, 53,112,198,221,222,160,169,119,221,113,143,174, 61,160,107, 26,202,160,143, - 9,214, 59, 34, 41,198,129,189,217, 6,203,211, 83,109, 14,186,230,168,221, 67,140, 3,239, 93,239,100, 75,178,200, 82,196, 61, -142,223, 83, 98, 4,245,152,170, 70, 65, 45,108, 45,115, 94,193, 47,142,211,184, 36,171,192, 89,210,238,164, 4, 56,107,244,251, - 78, 52,192,209,139,108,184, 75,146,135,186,115,110, 2,147,185,155, 29, 47, 35, 83,162,190, 25, 32, 24, 45, 18,156, 47,180,177, -136, 41,193,194, 32,207,114, 22,230,145,210, 58, 12,145,109,163, 78, 1, 46,178,242,163,233, 73,194, 16,233,144,147,117, 21, 96, - 38,250, 2,246,159, 79,146,226, 82, 28, 4, 20, 7, 39, 43, 8,101, 54, 24,221,145, 79,193, 63,234, 94, 17, 63,190,230,175,211, -243,145,236,178,180, 75, 31,113,178, 70,237,186,114, 13, 66, 52,244, 92,234, 7, 0, 22,121, 89,163,239, 90,120, 24,132,190,209, -226, 61,166, 72, 72, 83,144, 85,211,120, 42,146, 68,208, 37, 28, 0,231, 61,250, 62, 32, 49,147, 65,174,141,138,212, 98,100,117, -125, 26,167, 29, 44, 40,243, 89,174,164, 71,121,255,142, 59,120, 1,207, 36, 36,216, 72,122, 10, 17, 82, 10,120, 70,132,188,228, - 98,234,249,126, 79,250,158,165,128,203,115, 63,126,166, 97,208,233,202, 24, 6,148,180,168,148, 67,219,154, 52,201, 69, 55,234, -114,138,170, 7,195,228, 32, 31,115, 10,229,200, 87, 13, 19, 79,132, 41, 28, 43, 42,112, 38,242, 42,192,114, 49,108, 82, 28, 87, - 4, 48,240,113, 24, 20, 93,216,236,247,168,173,135,245,100,207,105,247,123,186, 49,134,129,247, 69, 20, 26, 33,157,123,100,161, - 9, 89,128, 2, 7,145, 4, 21,194,136, 98,220,152,132,227,126,135, 87,223, 62,131,243, 57, 39, 66, 89, 49, 19,168, 72, 74, 84, -156,206,103,168,102, 21, 78, 46,238,225,228, 60, 81,106, 85,211,106, 87, 48, 70, 19,146, 48,142, 42, 78,195, 55, 10,171,186,121, -199, 78,160, 24,131,190, 27, 80,148,153, 10,207,140, 49,122,176,111,219, 14,195, 0,148, 85,137,243, 7, 23,232,218, 22,155,245, -102,220, 73,115,149, 28,250, 14,206, 91, 44, 78, 22, 26, 75, 43,186, 3,249,128, 83, 76,188,247, 7,239,147, 71,207, 35,217,198, -162,198, 15, 54, 77, 7,168,255,150, 62,244,182,237, 53, 27,123, 8, 45, 3, 51, 12,110,174,111, 80, 84, 37,138, 34,199,246,118, -135,197,201,156,170,210, 44,199,230,118,173, 59,122,105, 96,118,219, 45,222, 95, 94,227,226,193,125,172,175,110,128, 68,190,223, -190,239,241,221,239,159,225,193,227, 7,184,190, 90, 35,197,196, 90, 6,163,201,110,243,197,140,132,118,155, 29, 54, 55,183,228, -133, 23, 75,140, 49,120,127,249, 22, 95,254,240, 99,178, 81,201, 13,205,163,212,205,205, 45, 66, 31,241,244,211, 79,240,246,229, -243,137,169,145, 30,202,125,215, 99,117,126,142, 55, 47,223, 97, 8, 17,179,197,130,173,105,212, 53,103,153, 71, 61, 39,120,208, -113,187, 85,218, 27,217,222, 6, 30,219, 17, 85, 48,175,172,198, 38,134,148,144,229, 5, 50, 14,214,121,244,241, 87,200,108,194, -108, 49, 67, 31,128,253,102,131,155,245, 53, 23,134,228,152,104,155, 22, 69, 61, 67,115,216, 99,191,185,198, 71, 95,253, 0, 31, -253,224, 19,252,231,255,235,223,211, 53, 49, 68,193, 59,123,244, 24,111,159,191,134, 77, 7,248, 44,199,124, 94,192, 91,135,237, -122,141,230,216, 99,249,232, 19,108, 46, 95,225,184,223,193,196, 6,198, 36, 84,139, 83,212,117,142,246,120,196, 97,183,213,110, -172,235,200,135, 79, 41,199,145, 11,217, 1,143, 63,255, 9,182, 87,111,200, 82,135,136,122,190,192,114,117, 66,224,148,161,199, - 16,122,236, 55,107,133,114,204, 79, 31,227,236,225, 7, 8, 93,135,155,203,103, 8,221, 1,214, 57,132,208,195,218, 12, 49,246, - 44, 44,204, 85,235, 49, 68,240,231,101,233,224, 6, 48, 91, 44,128, 72, 14, 7, 66,244,210,168,122,232,123,116,205, 30,161,107, - 0, 68,184,204, 35, 13, 1, 62, 19,168, 8,193,104, 96, 12,242,178, 70, 89,215,148, 83, 16, 45,224, 2,140,139, 48,218,213, 72, -112,198,152,146,229,188,167, 3, 79, 80,208,147, 0,140,200, 10, 96, 9,216, 25,119,222,113, 84, 58, 99,124,160,170, 70,199,202, - 3,155, 10,220,192,164,194, 49,211, 99,180, 62,202, 23, 37,176, 48, 74,172,114,195, 16,120,101,153,216,245,194,110, 29,201, 36, -231,142,148, 32, 53,128, 77, 6, 57, 11,245, 2,139,235, 82, 28,184, 80,181,164,172,215,191, 43, 27, 71,210, 18,129,202, 33, 68, -244, 28, 13,116,143, 79, 86,153,146, 68,166,122, 40,158,112,200, 65, 39,163, 99, 25, 35, 11,170, 91, 85, 79,198,170,195, 68,176, - 70, 33, 4,100, 89,129,146, 39, 42,106,107, 13, 3,178,162,160,123, 68,133, 92,210, 48, 64,167,165,201, 24, 32,145,184,211,185, - 12,112,226, 73, 15, 42, 90, 21, 23,130, 8, 7,101,250, 26, 69, 16, 59, 4,222,159, 91,116,157, 20, 46,227,244,134,206, 68,207, -153, 16, 1,214,103,202,248,112,222, 83,135,237, 51,213,235,200,228, 37, 47, 50,116, 93, 84, 72, 81,207,233,152, 96, 80, 78, 52, - 73, 35,128,233,140,141,119, 38, 62,113, 72, 58,245, 20, 27,153, 76, 40,101, 39,110, 96,105,122,158,100, 58, 20, 85, 20, 39,120, -219,169,135, 60,241,235, 27,217, 36,134,239,123,115, 39,145, 69,137,173, 98, 27, 76,140,140, 78, 99,180,170,100,173,208,253, 56, -176,175,158,233,154,188,242,176, 10, 79, 97, 17, 64,223,181,172,221,227, 15, 97, 8,170, 90,149,234,130,162, 56, 25, 89, 24,131, -166,178,117,109,167, 35, 51,217, 9,133,158, 2, 82,192, 86,152, 24, 58,164, 72,161, 30,226,221, 22,138, 15,141,172, 6, 12,125, -139,221,237, 45,222, 62,127,137,219,235, 13, 78,239,223,199,234,236, 84,147,115,196,167, 39,227, 29,231,236, 56,162,151, 74, 93, -176,172, 50,238,179, 80, 15,165,177,208, 81,238,192, 49,164,199,253, 1,183,215, 55,104, 57,178,243,244,222, 25,202,170,226,157, -140,231,209, 16,216,111,218, 97,182,152, 99,190,156,141,236,112,182,105, 88,231, 88, 37, 9,181,154,181, 77,135,208,247,106,169, -115,126,132,101,132,129,246,216,194,189,206, 50, 18,225,201,190,135, 44,111,228,153,111, 14, 71,116,109,135,142,217,245,125, 79, -228, 57,201,146, 15, 33, 96,183, 59,226,112,104,208, 52, 45,158,127,243, 29, 66, 72, 56, 57, 91, 33, 4, 26, 35,101,222, 97,125, -117,141,182,233,240,244,195, 71, 56,236,247,104,142, 7, 82,220,183,157, 90, 18,151, 39,115,156,156, 46,177, 56, 89, 0, 2,247, -144,252,245,238,136,162,158,233,129,237,196, 14, 99, 12,195, 80, 2, 30,126,240, 4, 89, 94,106,208, 79, 94,176, 61, 48,244,168, -230, 11,181,158, 84, 51,162,163, 81,232, 79,134, 44,207,201,161,224, 44,174,223,223,144, 26,149, 87, 44,145,161, 57, 50, 25, 32, - 58, 87,212, 47, 87, 57,155, 33,207, 29,178,188,196, 39, 63,248, 28, 49,116,200,138, 2, 85, 93, 96,183, 38, 47,181,207, 60, 67, - 84, 36,132,167,198,237,213, 59,244, 93,135,159,253,217, 31,227,239,254,234,175,117,109,227,156,195,226,252, 62,229,217, 31, 55, -176, 41, 32,153, 28,121,102,112,216,110,113, 60,180,176,213, 5,156, 29,240,254,245, 43, 24, 16, 58,121,190,186,192,108, 94,163, -107, 26, 92,189,125,131,246,112, 64, 26,122, 22, 14, 38,124,240,217, 71,248,240,139, 79, 57, 73, 47,225,222,211, 79, 17,135, 30, -155,119, 47, 16,227,128,170,174,177, 60, 61,165,212,180, 8,244, 93,135,195,150,236,118, 48, 14,179,147,135,184,120,252, 49,154, - 99,139,119,175,126,135,208, 29,244, 94,166,177, 38,167,242, 25, 98, 83,135,126,208, 61,176,114,180,243, 18,101, 85,209,238,212, - 23,236,169, 38,200, 72,232, 26,180,199,237,152,158, 55, 1,154,140,160, 19,234, 38, 92, 70,130, 42,192,193,250, 12, 69, 89,192, - 90, 66, 0,123,231,213, 31, 15,102, 90,168,117, 44, 25,141,236,148, 67, 74,187, 25,118,219,104,183,110,141,194,135,156,134,177, -136,212,202,104,220,175,104, 62,232,192, 29,152, 23, 49,142,129,213,154,150,198,209,181,146,200, 48,134,189, 36,110, 18,105, 18, - 64, 7,121, 31,200,190, 25,153,125,110,140, 87,229,246, 8,171,113, 76,109, 35,190,120, 24, 34,134,100, 0, 75, 35,238, 41, 80, - 70, 84,226, 2,176, 81,148,234,244, 16, 55, 6, 73,131, 64,248, 53, 42, 79, 92,160, 57,100,167, 75,108,113, 35, 75,216,232,167, - 31,201,110, 86,237,101, 72,137, 24,254,121, 9,159,229,176,140,167, 54,206,242,254, 56,242,153, 64, 19,205, 56, 33,205, 65, 0, - 91, 44, 82,142,201,105,199, 44, 80, 34,241,241, 11, 74,214, 90,171,222,122, 89,103, 88,206, 89,151, 40, 86,121, 96, 90,137, 0, -102, 71, 1, 96,104, 29, 0, 10, 13, 18,139,164, 0,184,100,229,153,101,158, 27, 58,232, 20, 71, 58,116,195,174, 40,199, 16,176, -177, 9, 27, 87,122, 99, 13,100, 70, 14,254, 36,117, 77,247,217, 60, 85,146, 34, 18, 19,186,170, 20,143,162,111, 24,249, 53,118, -146,201,142, 59,247,111,226, 2, 79,130,100, 68, 79, 98,152,201, 79, 5,200, 93, 46,188,168,235, 5, 63, 43, 90, 55,221,171,127, -249, 7,127,132, 39,159,125,202,169, 48, 64,232, 90, 52,251, 35,141,189,124,198,201, 90,131, 90,151,236, 36,143, 24, 44,243, 39, - 49,205, 48, 9, 2, 8,119, 50,105,133,195,158,248,129, 16,122,238, 12, 58,178,115,105,226,150, 21,220,163,101, 26,144, 71,140, - 61,222,190,124,131,162,170,112,254,240,190,126,137,100,175, 22,133, 57,204, 22, 51, 39,196, 54, 22, 91,229, 69,198, 95, 70, 30, -101,179, 98,124,224, 3,161,239, 7,221,211, 91, 11, 28,247, 7,220, 92,221,224,120,104, 81,206,106,156, 94,172, 80, 84, 5,114, - 94, 25,100,185, 67, 81, 50,133, 44,207,177, 88,206, 56,173, 43,215, 46, 36, 43,104, 34, 32,254,234,208,247,234,203,247,222,145, -173,143,171,182,162,204,152, 50, 69,100,175,208,211, 67,105,191, 59,162, 57, 52,104,155, 86,175, 77,140, 17,199,195, 1,251,221, - 17,187, 13,113,239,243,130, 30,206,100,191,136,227,218,193, 57,244, 93,131,239,190,126,129,139, 7, 23, 92,101,143,252,231,103, -191,127,134,229,233, 41,238,221, 63,199, 16, 35,250,190,197,246,118,131,227,225,136,162,240, 88, 44,107, 58,216, 87, 75,148, 37, -173, 25,198,117, 11,221,180,121, 94,192,223,177,215, 57, 32, 13,204,212, 47,177, 58,191,224,105,137,215, 47, 98,219,180,124, 8, - 0, 93,219,147,232,175, 40, 89,188,232,120, 9,253,234, 19, 0, 0, 32, 0, 73, 68, 65, 84, 28, 88, 32,198,132,253,110,143,132, - 68,123,121, 30, 73,201, 78,150, 88, 7,134,115,236, 41,115,189,154,205, 17, 67, 64,181, 60,197,124, 81,193,122,143,190,167,209, -235,187, 55,151,188, 55, 35,191,191,243, 25,250, 62,194, 57,131,227,238, 6, 95,252,228,135,120,247,242, 37, 9,193,248, 28,154, -157,156,161, 62,123,132,195,237, 26, 46, 53, 72,198, 34,175, 74,236, 55, 55, 56,236, 14, 64, 54, 71,189, 60,193,219,111,191,134, - 53, 1,105, 8, 40,234, 57,202,249, 2,214, 12,184,122,251, 26,125,219, 82, 80, 17,219, 33,255,251,255,229, 47,241, 23,255,230, - 47,112,255,201, 67,156,156,157, 96,117,255, 17,138,186,196,245,235,111,225,178, 28,179,249, 28,171,139,251,200,203,146,133,149, -116,160, 31,247, 91,164,100, 48, 95,221,195,197,227, 79, 16,194,128,155,183, 95,143,176,156,137,181, 37,113, 24,147, 60,108,135, - 40,133, 35, 21,190,213,124,134,162, 40,144, 21, 5,163,142,233, 97,208,119, 29,142,251, 13,218,227,158,129, 47,116, 47, 58, 47, -209,168,126,178,199, 5,172,207, 81,207,230, 40,171, 10,188,129, 67,140,100,253,138, 41,177, 64,109,208, 52,180,209,163,238,212, - 77, 51,205, 39, 31,163, 55,211, 24,143,170, 93,248, 40,146, 37, 45, 13,139,254,236,232,255,181, 58,130,228,241,168,142, 81, 7, - 45,186,167,251,208, 24,131,118,235, 74,100,211,194, 95, 58,106,168,178,153, 86, 6,152,236, 88, 41,176, 69,108, 91,146,145, 32, -135,118,226, 84, 51,177,182,137,178,127,202, 87, 55, 19,177, 24, 5, 52,241, 94, 89,112,186,130, 66,150, 98, 64,230, 94,154,253, - 30, 25, 22, 3,238,146,221,196,238,102,238,104, 5,164, 80,112, 89,137, 44, 43,105, 92, 29, 39, 64, 32, 70, 93, 15, 67,224, 85, - 95,139,182,105,208, 53, 13,175, 95, 19, 51,127, 12,133,188,120,158,210,242, 33, 77, 43,213,145, 36, 7,195,127,167,165,176, 46, - 5, 2, 65,176,179,118,130, 74,149, 56, 92, 90,181, 38,213,122,141,112, 22,231, 61, 23,106, 78, 69,137,228,160,241,147,152, 82, -171,120,109,129,133, 57, 93,137,142,156,118,185,175, 50,118,207,216, 59,251,235,209,230, 76,231,246, 40,138, 27, 15,120,123,103, -202,132,127, 18,163,106,198,247, 36,254,121, 69,217,198, 59, 74,124,106,243,105,138, 43, 19, 73,250, 62,196, 59,135,185,238,206, -205, 36,224, 69,253,233,102,100,191,255,230,111,255, 22,239, 94, 95,227,195, 31,253, 20,159,252,232, 43,228, 69, 70,185,232, 76, -101, 35,249,189,129,207,189,242,130,229,208, 20, 17,128,149, 47,104,164,195,114,140, 5,138, 58, 42,151,156,118, 48,116, 37,240, - 14, 88,246,196,129, 15, 90,169,108,172,247, 35,124,223, 36, 92, 95,190,199, 97,223, 98,126,178,164, 3,138,173, 99,121,153,105, - 23,153,231,158, 21,190,172,148,231,220, 95,193,236, 73,199, 55,142,250,153, 45, 45, 41,102,144, 74,122, 96, 46,246, 6,161, 31, -176, 88, 46,176, 92, 45,177, 92,205,144, 23, 5,202,178, 64,150, 89,130, 98,192, 98,190, 92, 40,254, 86,132,105,211,232,156,130, -209,183, 50,130,151,247, 73,232,200,142,189,144, 70, 57,239,152,216, 8,179, 60, 83,136,197, 48, 68,116, 93,143,230,120,192,118, -179,197, 16, 19, 28, 71,192,150, 85, 5,239, 29,138, 34, 67,150,145,250,191, 44, 11,108,110,111,176,223,182,184,255,240,190, 50, -168,169, 58, 29,240,226,219,151,248,244, 7,159,177,255,158, 10,162,195,254, 0,107,105,175, 94,213, 5,202,138,220, 16, 36,118, -162, 7,144,247, 30,219,219, 61, 78,207,207,249,225, 7,120,142,191,140,113,192, 97,187,195,113,223,224,241, 71, 31,208,231,170, -185,196,212,113,149, 53,137, 19,135, 16,144, 21, 5,234,249, 2, 62, 35, 8,206,108, 49, 71, 86,228, 8,125, 64,219,180, 74,166, -210, 7,188,164, 3, 50,202,178,172, 74,166,231,229,152, 47,230, 24,134,128, 71, 31,127,138,118,191, 69, 53, 95, 0, 41,162,107, -104,242, 99,141,193,124,185,212, 93,172,207, 11, 28,182, 91, 60,120,250, 1,158,124,252, 20,251,205, 22,206,142,232,226,135,159, -127, 5,147, 2,170,146,127,126,177,132, 9,123, 28,118,123,180,189, 69, 55,148,200,125,196,229,119,191, 69,158, 83,183,177,186, -255, 8,117, 93, 96,253,254, 10, 93,219,168,255,181,235, 35, 62,251,209, 23,248,244,135,159,224, 63,254, 31,255, 30,255,245, 63, -254,191, 56, 30, 58,212, 39,103,120,243,205,175, 49,132,128,178,174,113,114,126,129,172, 40,104,196, 59, 12, 56,108, 55,232,187, - 6, 48, 14,229,108,133,139,199,159, 0,214, 99,253,246, 57,154,253,173,142,229, 96,196, 15, 12, 6,128, 24,206, 62,207, 8, 1, -221, 83, 30,119, 89,213,228, 46,201,105,117, 35, 20,193,190,235, 48,244, 45, 7,171, 48,210,153, 69, 95, 20, 21,236,212, 82, 68, -133, 43,121,152,229, 97, 30, 35,173,167, 14,251, 61, 91, 45, 3,142,251,157,118,101,162,146, 78, 83,252,169,238, 75,211, 36, 1, - 11,122,144,137,141, 85, 44, 88,100, 91, 28, 59, 45,233, 42, 33, 24,227, 36,194,192, 48, 18,212, 48, 62,248, 36, 61,139, 84,219, - 3, 98, 52,119, 58, 69,163,177,191, 73, 39, 12,162, 9, 16,129, 28, 96, 20, 22, 36,224, 32,231,172,218,232,164, 3,149, 2,198, - 58, 58,244,195, 32, 89,228,142, 59, 81,199,133,176,159, 64, 69,172,238,132,189, 47,232,255,179, 36,190, 27, 73,117, 52, 73, 38, - 6,189,209, 34, 74, 92, 14,129,237,101,202, 99, 23, 70,189,170,231, 35,188, 47,120,239,156,244,185, 36, 22,208,192,232,212,246, -120,196,230,102,141,221,237, 26,219,205, 45,118,155, 27,180, 77,131,208,245, 52,210,230,233,174,168,212,245, 61, 88,186, 38, 4, -237, 26,148, 46,103, 96,117,115,108,120,178, 39,122, 1,203, 36, 59,186, 79,104,215,111,156,191, 19,208, 66,110,145, 76, 53, 41, -114,200, 75, 8,140,192,168,202, 50, 87,181,185, 70,161,166, 49,131,160, 44,243, 81, 68,103, 70,148, 47, 20, 74,147, 38, 14, 12, -114, 41,137, 2, 93,136,151,114,160,203, 20, 88,181, 94,119,242,139,204, 29,109,131,153, 20,131,163,200, 51,142,197,172,181,227, -159, 72, 99,142,138,228,131, 72,163, 33,133,149, 76,196,193,250, 7, 59, 9,150,177,113, 8, 56,220, 94,225,235,191,255, 57,214, -239,110,240,241,143,126,130, 39,159,125, 76,222,241, 44,135,207, 41, 4,133, 84,128,228, 45, 55,214, 41,167,120, 10, 3, 32, 12, -161, 69, 26,198,189,129,177,134,192, 15, 60, 26, 52,188,235, 16, 49,155,124,145,197, 10, 70,222,238,209,187, 73,138, 81,122, 8, - 55,135,195,248,101, 50,227,120,122, 58, 21, 48,204, 16, 55,214, 42,133,142, 58, 5, 78,214, 1,112, 60,180, 58, 90,146, 34, 64, - 14, 97,159, 57, 13,115,112,142, 42,210,195,238,160, 9, 99,171,179, 37,138,170, 24,201,107,145,200,111, 5,119,203, 67, 24,208, -119,129,199,216,180,167,156, 66,100,218,166,159,164,185, 81,224, 4, 77, 36,162,126, 40, 33, 12,200, 11,207,156,109,175,227, 96, -200, 40, 52, 14, 56,114, 40, 73,215, 82,228,102, 94,208,161,150,229,185, 6,229,192, 88, 56,155,240,252,219, 23,120,240,248, 17, -170,186, 64,219,118,154,121,191, 89,175,113,179,222,224,243, 31,124,130, 20, 35,242, 34,199,233,217, 9,242, 60, 67,150,123, 84, -117,137,170, 46,148, 49, 63, 13,123,217,109,183, 88,157,159,177, 29,203,232,193, 29, 66,143,230,120,196,213,229,123,220,123,252, - 72, 31,184, 66,111, 34,107, 11,221,149,205,177, 67, 81, 21, 52, 14, 47, 74, 36, 24,228,101, 65,215, 35, 4,186,199, 56,145, 41, - 33,113, 96, 73,137,162,100, 48, 74, 89,192,121,135, 60,207,185,240, 44,208,181, 29, 46, 30,220, 67,215, 28,177, 56, 91,113,154, - 95,195,130, 59,139,106, 86, 35, 25,131,195,190, 65,223, 15,232,154, 3,254,252,127,250,215,248,213,127,253, 57,119,128,244,218, - 78, 31,127,132,114,182,132, 9, 59,132,190, 71, 86, 47,136,244,213, 28,112,108, 34,144, 45, 48,155,231,120,255,226, 91,196,161, -129,245, 57,138,106,134,178, 42,176,189, 89, 99,183,185,213,164,169,148, 12, 22,203, 5,254,229,191,250, 99,252,213,255,249,127, -227,197,239,191, 1, 82,194,233,195, 15,240,252, 87,127, 71,140,136,188,160, 64,156,154,172,107,161,239,177,189,185,198,113,191, - 71,130, 65, 81,205,112,241,244, 19, 12,209, 96,253,230, 59,116,199, 13, 92,150, 99,156,138, 10,163,154,191, 3, 62, 3,108, 6, -152, 12,214,121, 84,179, 37,138,170,166,209, 59,179,179,187,166,193,113,191, 71,223, 54,104, 15,123,206, 36,200,238,116,183,212, -225,114,160, 69,164,239,187,207,114,204,151, 75, 29,223, 43,202,148,187,194,182,105,209, 53,141, 6, 25,169, 45,139,195,120,198, - 17,232,212, 35, 60, 10, 96,101,170, 4, 30,173,219, 9,248, 73,184,217, 49,138,232,201,176, 24,112, 24,239,123, 46,116,162,100, - 90,167,120,135, 14, 22,135, 65,129, 57, 10,122,137, 99,114,220,152, 15, 14, 69,232,142, 86, 57, 9, 40,177,147, 46,152,161, 49, - 48, 58, 49, 28, 56,177, 76,224, 53,110, 50, 98, 78,172, 27,162,113,178,189,211, 69, 11,147, 62,166,177,155, 85,245,190,100,200, -243, 40,126,144,117, 10,135,200, 8,118, 85, 66, 86, 6,205, 46, 55,147, 85,101,129, 44, 47,212, 2, 12,227, 16, 6,154, 38, 18, -143, 62,162,109, 26, 28, 15,123,181,229, 38,158,132,118, 93,139, 33, 14,148, 44, 25, 35,235, 47,216,234, 37,193, 59,118,140, 88, -149, 73, 68, 76, 96,228,184,153, 56, 27,104,132, 79,148, 57,163,236,119,235, 60,188,207, 53,111, 30, 19,187,165,160,114, 37,201, - 77,108,190, 2,177,242,158, 44,134, 52,102, 39, 13,135,172, 27,166,209,204,244, 94,122, 14, 21,147, 80, 33,202, 19,145,169,137, -248,196,245,248, 77, 99,208,152,134,252,240,106, 17,152,142,198, 5,225, 58,174, 73,226, 16,121,133,113, 55, 9,117,154,113,162, -168,185, 9,215,125, 20, 57,114, 65,161, 59,253,201,207,211, 3,126,100,208,219, 16, 6, 85,108, 95,191,125,141, 95,255,205,223, - 96,253,110,141,199,159,127,134,178,170, 80,204,230, 84, 69,240,195,124, 24, 70,175,158, 84,117,242,191,173, 49,176, 24, 84, 68, - 23,250,128, 24, 6,173, 48,104,223,156,216,174,227,212,147, 71,201, 97, 1, 73, 70,239, 60,166,176, 76,150, 19, 21,168, 84,205, -178,235, 6, 64, 29, 18,191,193,190, 31, 88, 97,156,177,207,210,222, 65,203,146,186,156,148,189, 93, 75,113,122, 41, 69, 69,204, -250,204,145,186,220,143,204, 96, 26,237,208,131,138,162,250, 28,143,127,198, 80,138,208,117, 56,236, 14,168,231, 51,138,145,245, -227, 56, 80, 42, 66,233,194,141,165,245, 67,115,108, 16,250, 1,109,195,239, 61, 37, 58,240,141, 33,213,117, 50, 90,108,164, 4, -116, 60,150,151, 81, 91, 8, 1, 55,215,107, 85,191,139,104,112, 54,167,131,197,179,248, 45, 1,232,219, 61,214, 87, 91, 60,253, -232, 9, 98, 28,176,103, 32,198, 16, 7, 60,255,230, 25,202,122,134,139,251, 23,168,103, 21,238, 61, 56,199,124, 73,228,178,188, -204,225, 51,218,147, 58,173,166,169, 40,187,185,186,198,197,253,123,119, 99, 7,185,235, 75, 9,120,245,221, 75,212,243, 57,170, -186,166,107,193, 95,232,230,120, 84, 81, 30,169,149, 13,119,166, 64, 81,228,152, 45,102,112,206,226,120, 56,242,231, 75,226,162, -170, 94,160,172,201, 50,229,179,156, 68,113, 76, 19,164,181,134, 71, 81, 21, 40,234, 25,156, 25, 48, 63, 89,226,228,236, 4,135, -221, 1,251,205, 45, 66,215,162, 40,107,228, 69,129,227, 97, 15, 24,139,238,216,224,127,248,243, 63,192,205,229, 59,116, 77,131, -190,235, 16,250,128,249,234, 20,103,143, 63, 68,236, 14, 24,250, 14, 62,207,112,236, 12, 98,187,197,118,115,128,201, 87,216, 92, - 95, 99, 57,207,241,230,219,223,192, 57,143,106,190,194,226,100,134,161,111,113,123,189,102, 43,234,104,109,249,217,159,255,119, -120,246,171,223,226,187,223,252, 6,206,123,124,240,213,207,240,236, 23, 63,167,189, 63,227,101, 13, 39, 79, 33, 6,236,110,174, -169,211,231, 14,229,226,241, 71,128,241,184,185,124,142,227,254,134, 15,183, 73,202, 21, 11,102,200,135, 94, 34,153,130, 8,145, - 62,195,226,244,140,252,198,236, 23, 15,161, 67,123, 60,208,174,126,183, 69,123, 60,106,154, 88, 76, 20, 44, 45, 54, 74, 43,239, -129,139, 19,227, 50, 84,243, 5,242,178, 98, 59,145,227,251,146,133, 95,145,138,239,208,247, 19, 12,174,209,195, 75, 20,192,164, - 47, 8,186,155,135,225,133,158,216,253, 68,175,193, 2, 54,217, 81, 70, 94,243, 25,200,222, 28, 42,226, 26,152,175, 32,226, 37, -207, 58,152,105,216, 71,210, 20,182,168, 29,179,102, 64, 76,187,180, 56,140,204,117, 46, 88,123, 70,184, 10, 2,215, 50,130,116, -138,239, 28,134, 4,227, 50,210,123,128,104,119, 10,138,225,209,186,216,117, 5, 10, 35,150, 70,217,245, 83, 71, 13, 61, 24, 1, -135, 40, 24, 94,235,152,153,207, 8,213,105, 90, 92,154, 4,222, 24,167,135,226,184,215, 53, 28, 45,235,117, 79, 63,200,243, 25, -146,104, 22, 88, 80,219, 17,212, 70, 14, 51,118,249,132,174, 85,181,248,116,220, 45,158,114, 42, 24,173,254,154,248,227,165, 1, -179,214,114,240, 13,148,249, 46,233,100,150, 63,235, 48, 12,148,141, 46, 83, 94, 65,211,194, 32,207,115,229,150, 72, 10,168,120, -253,197,138,109,140, 65,158,101,186,218,165,105,103, 36,250,168,157,234, 52,134,137, 74, 29,163,253, 6,105,116, 75,176, 11,194, - 59,167,228,203,105,182,121,156,252,127,224, 76,121, 35, 90, 13, 35, 92, 13, 78,126, 75,227, 84,202,240,150, 73, 28, 25,170,128, - 23,247,133, 4,189, 24,171,223, 91, 76, 60,240,246,206,142,125,186,115, 7,172,230, 5,135,128,208,247,136, 49,225,253,235, 87, -248,237,223,253, 2, 23, 79,159, 96,117,239, 2,174,168,244,133, 15, 2,109, 24, 48,217,109, 11,238,207,170, 82,217,241,188, 32, -240,223,155, 18,237, 80, 9,239,200,135,117,226, 52, 55, 5,236, 59, 22,206, 57, 61,244, 53,138,153, 69,112, 93,211, 2,198,161, -168, 74, 88,107,209,117,189, 42,196,203, 42,103, 26, 89,134, 33, 8,122,212,161,172,242, 17,194,194,212,184,255,159,173,247,234, -177, 44,201,178,244,150,169, 35,174,114, 45, 67,101,100, 70,164, 46,209,138, 61, 67,206,144, 47, 3,240,141, 0,255,209,252,167, - 1,248, 64,144, 28, 2,100,163, 85,117, 87, 87,117,102,167, 12,149, 33, 60,194,181,251, 21, 71,152,154,135,189,205,206,245, 34, -251,165, 26, 89, 89, 17,238,247,158, 99,182,197, 90,223, 74,162, 32,165, 6, 95, 98,100,155, 69,190,208,141,206, 66,184,122, 84, - 98, 52,169,208, 49,237,173, 40, 13,198,211, 49, 89, 49,172,131,237,122, 92, 93,220, 16, 46,180, 44,104, 21, 32, 68, 22, 71, 57, - 75, 99,232,224, 9, 68,211, 91, 55,120,212,215, 40,115,158,109, 48, 97,205,147,154,166, 30,142,213,231,201,162, 18, 60,225, 86, -187,182,103, 79, 35, 61,228, 69, 89,241,195,128, 28,237,122,242,246, 45, 70,147, 25,118,246,182, 32,133, 32,241, 93,223, 99,181, - 88,226,197, 79, 47,241,235,191,250, 53, 30, 61,190,143,237,189, 45,108,110,207,242, 88, 39,230, 16,159,114,152, 20, 32,162, 89, -206, 49,219,218,204,149,173,228,240,143,209,168,134,210, 10,205,114,142,174,105,177,127,239, 40,199, 28, 18,181,207, 82, 26, 87, -111, 73, 20,233, 3,202,170,132,102,209, 81, 85, 87, 89,119, 80,150, 5,148, 54, 12, 19,170,134,130,173, 40,242,232, 75,177, 98, - 63, 68,138,119,221,220,219,195,234,246, 6,179,157, 93,194, 61, 74,129, 15,111,223, 35,132,128,209,100,130,174,235, 49,191,190, -198,100, 99,134,178,210,144,251, 59,120,243,236, 25,138,122,132,174,109, 80,141,199, 56,252,228,115, 74,255,187, 57,135, 41, 43, -116,173,135,136, 22,139,219, 91,152,241, 14,206,222,189,197,227,207, 30,227,244,245, 79,144, 74, 97,247,222, 71,168,103,155, 40, - 75,131,249,237,146, 59, 20, 77,248, 85,161,176,181,191,135,157,253,109,252,241,239,254, 17, 0,240,248,235, 63,195,201,243, 31, -208,173,110,161,180,193,230,238, 62, 74,190, 36, 17, 61,174, 47,174,208, 54, 43, 4,239,160,181,193,254,253,143, 81,212, 35, 92, -159,190,197,106,113,189,150, 58,198, 16,146, 60,186, 38, 11,162,169,102, 80,166,192,104, 58,195,100, 99,147,187, 90,141, 16, 60, -133,239,204, 23,232,219, 21, 86,139,249, 16,108,196,151,184, 50, 21, 83,202,134,149, 79, 96, 11,210,104, 50, 65, 61,158,193,152, -138,220, 32, 44, 50,237,251,192, 32, 37,139,197, 13, 9, 18,215,129, 46,136,107,249,218,252, 12, 57,231,178, 16, 8,107,148,242, - 97,215,202, 76,107, 69,137,117,169, 75,202,214, 44, 53, 0,103,178,211,117, 8, 87,200, 43, 37,178, 0,249,236,251, 22, 24, 96, - 47,113, 45, 98, 84,200,180, 91,231,177,106,194,216,242, 8,215,242,187, 71, 93,180,200,123,238,228,125,102,127, 17,217,238, 50, - 49,146,241,169, 90,223,233,192,157,143,107,133, 78, 96, 49,153,206,108,124, 90, 7,208,200, 93, 72, 34,254,229,213, 74, 28,210, -225, 72, 84, 86, 12, 78,155, 20,231,153,196,123, 57,124,134,233,111, 72,241,214,100, 21, 75, 26,130,245,196, 50,234,216, 59,230, - 26, 8,166,215, 5, 88,107,243,196,212, 59,151,195,161, 8,202, 19, 50,207,162,107,187,188, 54,137, 49, 50,216, 74,228, 34, 35, - 97,106, 99, 96,253, 65,138, 67,229,162, 43, 89,144,147, 91, 32,253,239,180,150,217,133,180,110,127, 5, 51, 19, 12,219,241,214, -191,147,180, 51,167,245, 17, 77,155, 83,102,121,138,255, 70, 12,153,133, 79,157,124,200,187,245,132,238,213, 74,229, 93,122, 90, - 3,202,181,194,101, 24,157,199, 44,186, 20,195, 78,236, 14, 68, 38, 93,207,201,178, 56, 4,193,172,141,236,227, 16,205,157,239, - 63, 49, 8, 67,177,166, 63, 17,235, 34,191, 20,115, 77,151, 90,204,194,163,224,201, 30,129,208,227,229, 15,207,240,224,201, 71, -112,125,143,247,175, 94,193,247, 93,190,140,177,198,178, 37, 33, 24, 97, 89,109,111,105, 31,206, 74, 85, 33, 73,184, 22, 84,128, - 50,124,153,115, 5, 29,179, 87,215,100, 85,160, 54, 26, 33, 10,174,112, 98,190,212,210,232, 62,176,239, 16, 66, 13,118, 56, 86, -191,211, 78,139,254,127, 93,168, 33, 96,128,115,206,165, 32, 12,160,203,249,219,130,193, 6, 50, 67,253, 6, 96, 65,200, 2, 13, - 83, 24,152,194,192,246, 84,244, 8, 15,116, 33,160,231,221,213,214,238, 38,110,174,110,209, 53, 61,230,215,115, 20, 85,141,162, - 42, 17, 86, 52, 30,119, 28, 67, 74, 49,151, 92, 84, 68, 74, 31, 11,126,224,173,139,232, 51, 90, 85,105,147,117, 7,182,183,156, -124, 23, 56,100,197, 15,226, 29, 79, 5,138,245,142, 97, 12, 10,198,136, 97,100,173,168,104, 64,116,248,240,238, 28,247, 63,122, -128,155,171, 27,244,109, 15,169, 4,182,182,103,168, 42, 34,135,125,244,233, 71,184,185,188, 30, 58, 41, 94, 29, 88,235,242,170, - 69, 73, 58, 4,187,174,205,180, 48,186,136,147,106, 93,229,191,251,228,245, 9,182,246,246,241,238,213, 27, 72,182, 74,218,206, -102,180,112, 26,129, 87,163, 17,148, 49, 40,138, 2,179,173, 25,148,146,104,155,150,254, 89, 36, 59, 72, 89, 86, 44, 72,162,104, - 66,201,121,243, 33,198,172,140,174,235, 10,163,113,137,110, 14,152,170,102, 80,143,195,252,230, 6, 85, 77,138,247,229,146,192, - 52, 91, 59,155, 56,186,183,133,239,254,241,119, 84,180,141,199,240,221, 2, 7, 31, 61, 33, 71,129, 6,100, 77, 52,189,182,245, -152, 95,156, 66, 22, 51, 52, 77,135,253,163, 67, 28,221,219, 66,119, 59,193,195, 79,191,192,120,115, 15,245,116,130,155,211,119, - 24,207, 54, 81, 84, 99,138,211,100, 1,233,159,253,135,127,143,111,254,225,247,232,219, 21, 30,126,241,103,184, 62,125,143,249, -213, 25,234,209, 24,219,251, 7,208,166, 36,138, 88,223,224,234,252,130, 5,164, 84, 92,238, 28,221,135,212, 5,206,223,189, 65, -179,184,226,192,165,152, 15, 71, 41, 53,188,239,249, 66, 23, 48,229, 8,186, 40, 49,154,110, 16,228,201, 5,140, 38, 99, 4,158, -146,216,174,129,237,104, 58, 0, 49,164,121,105, 99,136,106,152, 64, 31,222,193,121,222, 73, 11,160,172, 71, 48, 76,154, 84,154, -194, 78,164, 50,112,222,193, 59, 11,219,183,232,218, 21, 49,229,185,115, 21,107, 1, 30,217, 22, 20, 40, 76, 71, 74,205,227,212, -176, 38, 28, 26,162, 42,115, 7,186,182, 67,244, 33,237,246, 61, 4,244,157, 2, 55,230,115,130, 71,243,146,196, 86, 1, 52,189, -179,182,207, 63, 3, 33,122, 99,102,101, 40, 14, 52, 18, 12, 58, 25, 98, 53, 3,239,233,233,159, 57,239, 33,133,102,239,118,186, -216,233, 52, 85, 76,130, 75, 89,235, 57,130,118, 13, 83,138,181,242,197, 59,207,158,124,153,131,140,104,253,103, 96,251, 30, 82, -166,188,110,182,150, 41,195, 26,160, 97, 37,146, 62,152,148,193,144,206,229,116, 81,122, 31,233, 66, 74,209,198,140, 1,167,209, -191,135,224,239,146,138,175,192,225, 73, 61,188,117,153,218, 72,226,101,166,231,249,176,150,216, 73,176, 49,114, 72,197, 44,114, -214,166, 96,239,116,204,122,155,236, 64, 98,250, 89, 76,250,161,152,172,209,200, 48,165, 20, 60, 67, 43,189,193, 51, 15, 80,152, - 86,136,130, 68,192,214,195, 20, 5,179, 24,210, 4,134, 46,241,158, 87,197,137, 5,175,181,162, 85,130, 34,183, 69, 81,104,216, -158, 82,241,214,121,248,113, 45,141, 45, 70,122,134,146, 61, 82,172, 33, 93, 37, 35,140,101, 22,242,197, 76, 75, 76,216,237,124, -201,175, 37, 13, 82,162,169,200,249,236, 67,104,218,176,170, 78,126,247, 4,177, 17,107, 69, 99,250,167,128, 92,139,122, 5, 11, -234, 6,122,172,166,224,117,178,129, 37,234, 82,250,144,186,213, 2, 39, 47, 94, 99,255,225,125,244,109,139,247, 47, 95,229,145, - 8, 34, 65, 40,188,179,121,204,221,247,164,146, 23,201, 82, 34, 34, 98,224,138, 50, 49,219, 5, 67,239,163,204,152, 63,250, 69, - 35, 63, 36, 18,129, 35, 77, 37, 51,230, 29, 71,155, 18,225,135, 82,149,138, 82,163,239, 58,218, 55, 27,149, 47,116,242, 78,175, -115,117,217, 39, 27, 34,154,174,207, 69, 2,253, 12, 17,166, 80,121,239,145,202,158, 16, 34,138,162, 64, 81, 25,174,198,214, 14, -139,148, 6,215,244,112,158,148,233,151,139, 64, 57,235, 69,137,118,213, 98,181,152, 67,233, 18,213,168, 70,195,145,174,105,156, - 99,173, 37,254,116, 71,121,202,130,133,123,206,250, 60,177, 48,172, 99,144, 66,240,131,135, 97,132, 31,227, 90,212, 40, 61, 40, - 10,196, 72,143, 81,228,139,213, 24,170,232,150,139, 62,143,148,174, 46,206,112,112,188,139,131,227, 67,204,175,175,161,141,194, -104, 84, 97, 60,169,113,121,118,142,195,251, 7,180, 19, 95, 54,104,155, 30, 55,215,139, 12, 93, 16, 82, 66, 25,131, 64, 11,182, -108, 39, 57,126,112,156, 19,143, 98, 32, 91, 99, 26, 41,189,121,249, 26,127,245, 31,255, 26,101, 93, 1, 81, 2,188,103,236,154, -142, 70,250,108,195,171,234,154,173, 80,138,118,222,124,105, 81,200, 15,137, 54,149, 46,160,248, 37, 77, 93, 17,191, 41, 60, 89, -209,152,108,109,226,246,244, 29,182,247,119, 81, 20, 5,108,111, 73,236,232, 61, 54,102, 83,132,232,177,184,190,194,253,167, 95, -224,248,225, 1, 22, 23, 31,176,154,207, 1, 8, 34,219,105,129,237,195, 67,248,118, 5, 4, 1,101, 52, 60, 12, 16,110,177,177, -127,132, 85, 35,176, 61,113,120,244,228, 33, 94,255,244, 3,108,223, 99, 52,219,130, 82, 2, 55,151, 87,184, 62,191, 96,224, 9, -216, 41, 81, 96,255,248, 0,218, 40, 44,110,174,241,248,235,191, 64, 8,192,242,230, 18,155, 59,187, 24,111,108,240, 5, 3,248, -190,197,237,213, 21, 93,138, 76,220,218, 57, 60, 66, 57, 26,227,244,205, 47,104, 87, 55,236, 93,229,125, 98,112,185,200, 85,186, -132,247, 2, 82,143, 49,154,110, 96,182,189, 13,231,105,159, 88, 79, 70, 8,222,194,182, 13, 86,243, 27,180,203, 57, 31, 64, 99, - 84,163, 17, 98, 20,176, 61, 49,255,169, 75, 4,188, 35, 92,106,138, 27, 29, 77, 24, 11, 42,152,154, 40,201,234,218, 55, 29,229, -128,219,158, 46,244,190, 31, 50,198,243,232, 61, 34,250,245,125,181,229,110, 38,102, 24, 74,136,233,224, 84,108, 25,162, 75, 66, - 43,189, 6, 35,145, 80, 66, 66, 40,149, 59,167, 36,186, 74,150, 56,107, 45,121,193,163, 37,216,146,214, 16, 30,249, 61, 67,162, -206, 5, 34,156, 73, 17,115,236, 48,217, 96,197,154,184,139, 24,219,217,187,207,171,249, 32, 35, 95,252,236, 89, 15, 33,135,173, - 36,189, 9,130,224, 49,121, 24,172, 79,105,180,207, 92, 5,239,237, 16, 14,194, 93,125, 12, 1, 93,103,239,236,239,137, 60, 72, -190,115, 18,125,101,185,217,176,131,167, 50, 33,239,167, 67, 0,162, 15,140, 21,142,121,178, 76,207,154,100,241,160, 26,136,106, - 66, 16,252, 39, 82, 6,136, 72, 5, 10,167,176,145,247,157, 3,107, 4, 24, 44, 19, 51, 63, 61,239,153, 25, 69,156,224, 49,235, -252,128,117, 94,127,250,204, 16,147,107,192,221,217,153, 43,169,192, 30,134,220,229, 82, 83, 38, 17,125,128, 7, 5, 99, 73,153, -158, 71,149,207, 11,228,139, 48,228, 46, 54,248,144,155,178,190,119,148, 96,153, 59,102,106,246, 60, 23, 18, 84, 67, 9, 40, 33, - 97,109,127, 39, 51,157,210, 0, 49, 20, 90, 25,111,158,178, 82,116, 14,106, 73,123,161,245, 48, 29,121, 71, 79,194, 20,204,204, - 91, 88, 23,215,197,187,154, 19,196,187, 49,173,217,226,150,126, 7,113,135, 7,175,211,136,118,253,162,240,206, 33, 68,129,162, -170,208,119, 13,206,223,189, 71,189,177,139,209,236, 10,203,155, 27,230, 39,139,156,234,149,196, 50, 80, 68, 15,242, 28,201, 26, -229, 96, 63,176,157,131,169,146, 48, 65,172,249,187,105,108,164, 37,241,211,251,206, 18,190,147,187, 69,173,117,174,238, 18, 78, - 50,129,101, 36, 43,214,109,239, 81,177,160, 75, 41, 69, 86,139,128, 44,184,147, 82, 34,136, 0, 33,129,190,181, 76, 63,115, 40, - 75,205, 23, 8,131, 55, 0, 98,254,114,104,139, 0,169,246, 43,238,216, 84, 36, 33, 93,219,244,172,220,167,241,147,237, 41,245, - 74,155, 2, 69, 85,161,170, 43, 92, 93,220,160,109, 90,140,167, 83,180, 77,131,155,203,219,188, 79,143,107,228,164,224,147,122, - 87, 48,247, 92,102,117,105,215, 90,104, 77, 29,253,112, 40,200,204,178,214,236,109, 87,129,128,254, 93,215,101,150,190, 82, 10, -245,168, 2, 16,176,152,207,233,223, 87, 1, 87,231,151,248,252,215,159,226,249,119, 63,194, 57,143,146, 73,114, 69,105,240,238, -213, 91, 60,248,248, 1,158,159, 63,195,135,119,103, 88,204, 87,240, 94,162,170, 43, 52,141,165, 42, 60,120,148, 85,129,170,170, -209, 54, 61,118, 15,246,113,125,121, 13,192, 82,104,102, 4, 41,250,189,195,106,113, 3,219, 91, 76, 54, 54,176,184,153,211,247, - 99,106, 0, 17,227,217,140,124,250,206, 99,186, 49,133,179, 30,101, 77,208,161,174,233,120, 39, 43, 50, 61, 76, 27, 26, 97, 42, -102, 25, 40,185, 22,191, 26, 3,164, 54, 24,141, 42,188,191,189,197,189,199,143,104,149, 20,129,179,147,247, 24,141,198, 80, 70, - 97,126,115,139,237,221, 29,220,123,244, 0,193,245,120,251,252, 21,192, 10,219,122, 50,198,116,251, 33,154,235, 51,148,147, 77, -196,208,194, 7,133,241,230, 20,101, 1, 44,155,136,224, 46,176,185,183,131,179,215, 47,241,226,187,111, 48,217,220, 69, 57,158, - 97,113,115,131,219,155, 21,174,206,222,115, 50,150,132, 49,164,141,120,240,228,175,241,237, 63,252, 35,198,155,123,208, 69,141, -211, 87, 63, 97,107,111, 23,245,120,194,187,205,128,118,113,139,171,179, 83,216,190, 99,130, 97,196,246,193, 17,170,201, 6, 46, - 79, 94, 99,117,115, 65,239, 0,175,137,146,253,207, 89, 71,221,178, 11, 16,186,194,100, 99, 11,211,205,109,248, 64, 69,109, 81, - 27, 4,215,161,111, 86, 88, 45,110,209,173,150,104,155,134, 46, 30,105,200,163,204, 32,168,156,140,197,201, 83,186, 40, 17, 3, -165,222,145,234,152, 15, 80,165,209,245, 36, 98,116, 46,160,109, 86,204,157,224,213, 16,200,161, 16, 17, 6,158,181, 12, 28,202, - 17,214,124,218, 60,250,245,158,161, 86, 18, 2, 58,175, 21,180, 46,243,222, 53, 35, 51,213,176, 35, 38, 65,169, 99, 16,145, 29, -108, 70,136,156, 59, 48,160, 86,179, 56,139,145,215,224,213, 20,237,179, 99,222,207, 15, 34, 41,220, 21, 41, 37, 69,254, 90,162, - 87, 58,116,135,172,107, 22, 89,113, 66, 27, 57,106,232,217, 76,197, 87,226, 6, 80,147, 96,224,189,165,137,194,154, 86,128, 72, -138, 52,157, 32,194, 31,216, 79, 77,103,234,224,239,142,119,216,225, 57, 87, 33,167,153, 9,214, 5,112,209,107,200, 43,159, 34, -101,149, 24,252,215, 89, 20,201, 84, 59,173,210,184, 30, 16, 50,230,116, 76, 34,110, 90, 8, 17, 6,160,163, 84, 89,164,152, 58, -215,176, 6,252,201, 98,230,212, 17,175, 9,156, 83,247,171,180, 25,156, 79,224, 2,131,163,100,137, 98,233, 89, 72, 45, 33,139, -193,251, 78,122, 40,195,122,133,244,252,250, 33, 58,186,208,232,186, 46,115, 65, 4, 64, 49,224,158,213,228,136,208, 74, 2,145, -244, 61,224, 66, 32,237,232, 83,180,179,227,117, 67,246, 69, 8,153,185, 8,119,215, 62,169,195, 23,121, 18,164,148,228,149,227, -176, 51, 72,163,120, 40,149, 3,207,210,119, 40,214,198,245,105, 18, 77,223,247,240,238, 15, 84,205,136,152, 56,243,224,137, 0, - 0,173,180,132,128,202,152, 82,170,156, 3, 20,251,230,218, 85, 67,157,175, 46,177,115,124,143, 5, 69, 54,143,117,165,214,156, - 95, 45,152,209,141,129,241,156, 1,251,226, 78,186,209,160, 30, 92, 31,175, 12, 41, 54,222, 81, 24, 69,226,245, 14,123,191, 65, -241, 71,187, 84, 98,188, 67,200, 1,216, 34,233,207,245, 33, 16,226,207, 13,182,151,244,225, 41, 37,161,234,130, 68, 45,130,129, - 21,129,186,118, 99, 76,190,104,165, 26,128,255,244,176,243,223, 23, 57, 81, 12,233,203,167,221,126,223, 45,113,123,189,132, 80, - 26,179,141, 9,132,240, 56,125,119,129,241,108, 19, 82, 74, 92,156, 94,230, 3,195, 90,155,127,174, 52,110,162,203, 92,177, 61, -200,179, 7, 53,102,209, 80, 74, 76, 83, 28, 82, 19, 2, 5,119,244, 29,127, 15,206,163,107, 91,232,201, 36, 87,201, 85, 93,177, -205, 35, 97, 39,123,196, 40,113,120,255, 16, 31,222,126,200,123,124,219, 83, 24,201,203,159,223, 96, 52,153, 96,181,248, 5,203, -249, 18,101, 61,230, 44,247, 10, 82,148,144, 98,140,186, 38,171, 99,179, 92, 97, 60,157,224,242,236,146,130, 78,218, 6,109,211, - 96,107,159,217,224,193,227,252,195, 57,142, 31,222,199,203, 31,159, 81,172, 32,187, 14,198,147, 9,122, 75, 69,214,120, 58,130, -210,196, 21, 48, 69,129,197,205,156, 14,168,130,180, 16, 82,202,236,111,149, 50,146,255,151, 87, 63,218, 40,216,182, 69, 81,214, -232, 87,115, 76, 54,102, 16, 82,162,109, 58, 68, 14, 98,216,222,221,192,106,213, 96, 52, 42,177,115,112,136,163, 71,247, 96,219, -134, 8, 96, 82, 32,170, 10,219, 7, 7,232, 87, 11, 52,171, 30,147, 45, 1,219, 68,108,238,237,145,198,228,186,195,235,103,207, -225,251, 21,118, 15,119,241,111,191,251, 71, 72,173, 49,222,220, 69,116, 61, 86,141, 71,179, 88,176, 26,151,158, 41,215, 6, 28, -222,251, 24,203,171,115, 44,231, 75,140, 55,247,241,226,155,223, 97,107,119, 23,229,104,130,200, 7,175,237, 45,154,101, 3, 93, -140, 72,205, 30, 61, 54,246, 14, 48,154,109,225,252,228, 45,230,215, 23,217, 37, 34, 57,170, 56,132,158, 31, 6,137, 40, 12,138, -209, 8, 91,187, 59, 48,229, 40, 95, 46, 85,101,208, 53, 45,154,197, 45, 86,243,107,178,141,242, 26,136,152, 13,150,108,147, 50, - 32,138, 20, 43,201,227,111, 37, 80, 23, 99,212,163, 17,119,127, 76,190, 19, 10,125,239,209,247,196,162,104,155, 37,162, 31,252, -203, 66, 26, 14, 90, 18, 67, 78,182, 92,203, 93,224, 67, 93,164, 46, 44, 6,242,231, 34, 81,238, 2,239, 79, 75, 58, 80,243, 14, - 83,173, 37,244,197, 28,182, 34,153,235, 45,214, 25,218,105,192,157, 34,162,227, 48,125, 36,234,104,204,177,154,116,113, 71, 8, - 21,215, 44, 75, 88,219,191,179, 11,134, 47,179,116, 70,105, 41, 88,160,197, 72,212, 72,144,155,176, 14, 36, 97,124,103,228, 11, - 62,179,237,215,236, 73,233,172, 77,222,123,103,187, 76, 95,203,197,133, 0,130, 11,208, 60,209, 33, 98,160, 26, 4, 93,204, 78, -149,140,202, 14,124, 70, 12, 43,186, 84, 24, 23,131,151, 92,144, 91, 37,101,247,209, 25, 73,208, 33, 41, 37,156, 31, 4,138, 33, -196, 44, 70, 12,158, 86,171, 84,172,196,140, 13,167,248,211,181,212, 48,165,224,172,103,216,150, 96,170, 40, 53, 35,133, 41, 24, -141, 75, 2,215,188,234,228,239, 43,237,223,147,171, 41, 35,124, 35, 53, 0, 90, 83, 3, 41,148,206, 83, 21, 41, 5, 4,139,212, - 72,155, 37,216,240, 48,140,178,165, 0,132,150, 8,189,207, 69,153,214, 10,203, 37,145, 74, 53, 79, 65,165,212,232,251,142,167, -204, 88,155, 40,201,172,187, 66, 28,246,226,226,142, 47,125,125,106, 33,178, 94, 43, 61,187,105,100,159, 38, 4,145, 1,100, 73, - 9, 47, 98,190,170,241,167,255,151,196,198, 67, 17, 17,239,168,230,215, 39, 19,218, 24,234,142, 13,239,212,140, 81,104,219,142, -246, 80, 61, 7,140, 88, 11,204,175, 49,219, 59,192,198,206, 14,110, 47, 47,184, 2,228,202, 67, 27,126, 17,192,187, 97,222,191, -240,200,221,251, 0,197,163, 59,197,220,104,150,236, 13, 47,134,247,208,236, 67,244, 62,174, 37,119, 37,165, 34,117, 17,101, 93, -228, 63, 51, 61,252, 69, 97,214, 66,104,232, 3, 44,149,225,228, 50, 2,198,216,222,194, 90, 63,132, 49, 8,129, 24, 44,179,146, - 5,234,186, 96, 59, 28,141,215,211, 11, 81,148,100,191, 35,210, 27, 9, 70,172,165,128,154,190,163, 60,116,193, 92,107,122,169, -129,213, 98,137,158, 67, 67,118, 14,118,112,123,117,131,106, 52,193,209,253, 2,175, 95,188, 65,219,246, 89,109,155, 46,246,166, -233, 88,176, 67, 49,180, 54,120, 8,132,188,155,213, 58, 37, 15, 81, 70,187,247,158, 34,100, 13,137, 73,108,239, 97, 76,193,227, - 55, 26, 55,105, 67, 2, 19, 74,141,115,153,177,127,250,238, 3, 30, 63,125,128,211,147, 83, 44,110,151,156,187, 30,176,152,175, - 0, 92,224,254,227,199,152,109,206,112,117,121, 13,101, 45,202,170,196,214,206, 54,180, 2,154,229, 60,179,193, 47,207,207,241, -233,151, 31,227,246,230,134,227, 68, 53, 97, 95,149, 66, 61, 26,193,118, 45,174,207,207,113,252,232, 55,152,204, 78,225,122, 7, -207,160,148,122, 50, 66,127,185, 66,136, 1,101, 61,202, 83,136,228, 52, 0,235, 40,146,103, 88, 27,178, 4, 57,235, 32, 69,200, - 14, 7,178, 90,134,156,149,190,119,239, 8,182,107, 17,163,196,106,177,192,198,230, 12,182,239,128, 24, 49,219,156, 97,255,193, - 67,196,224, 72, 1, 31, 35,172,243, 56,254,232, 35, 0,192,242,234, 28,147,173, 61,136, 96, 49,219,221,133,136, 22,203, 38,226, -231,111,127,192,252,226, 45,254,242,127,250, 15,120,243,211,247,112,206, 97,247,240, 17,234,138,216,239,171,142, 98, 91,173,243, -208, 74, 65, 10,194,208,126,242,245,151,248,233, 15,127,192,193,163, 39,248,249,247,255, 47,102,155,219, 16, 74,161, 93, 46, 32, -165,192,245,114,201,122, 0, 58,248,140, 25, 97, 99,119, 15,229,104,140,139,247, 39, 88, 92,157, 83,247,203, 93, 8,214, 34, 84, -163, 16,144,166, 64, 53,222,194,246,193, 94,230,231, 39, 11,208,106, 62,199,106,126,141,190, 93,162,103,139,101,207, 73, 89,206, -245, 16,210, 64, 23,150, 56,238, 9, 78,194, 24,214,228,253,143,222,195, 57, 75, 69, 38,139, 81, 73,248,218,195,245, 45,108,215, -178, 98,153, 14, 42,207,226, 55,239, 66,246,151,131,211,196,136,159,237,249,231, 27, 38,116, 67,118,180,228, 14, 51,121,178, 19, - 96,104, 45, 95, 34, 29,174, 33, 14,190,252, 96, 51, 24,134,206, 15,153, 45, 87,137, 37,158, 70,252,220,204,220,241,191,167,203, - 92,170,100, 85, 75, 93,186, 67,100,245,177, 15, 97, 16,102,101,207,119, 74, 15,211,185,232, 72, 19,132,100,237,114, 54, 12,129, - 74,113,200, 88,143,108, 11, 75,251,220, 92, 76, 9, 18,125,210,207, 35, 25, 75,203, 33, 52, 60, 69, 72,106,250,132, 55,141, 34, -230, 41, 66,186, 52,188,227, 9, 0, 79, 9,124, 10,169, 9,228, 58,162,207,113,176,235, 73,206, 34,160,253, 49,119,249, 50, 65, -102, 72,151,148,121, 25, 33, 32, 4,153, 3, 89,180, 81, 96,247,216,157, 2,204, 20,154,173,172,158, 21,249,124, 33,199,144,127, -150,129, 89, 79,239,185, 46, 43, 22, 13,115,241,195, 66,202, 32,134,156,114, 68, 34,124, 2, 34,195,101, 82,145,146,172,113,138, -225, 53, 33,143,212,125, 14,248,162,203, 22, 8,158, 27, 63,163,208,117, 61,148, 18,128, 7,143, 95, 0,151, 0, 0, 32, 0, 73, - 68, 65, 84, 44, 55,183,129,215, 47, 49,172,161,201,105,100, 67,129, 57, 73,181,206, 63,151, 92,239,166,211,165,155,199,236, 33, - 79, 53, 82,209,152,213,254, 97, 16,234, 65,252,127, 39, 65,105, 98,189,206,139,143, 57, 63,253,255,255,242,215,193,147, 63, 57, - 9,229,210,184, 38,184,158,191, 56, 15, 21, 60,164,136,232,219, 6,227,157, 67,172,230,115,120,215,242, 11, 76,156, 99,193,130, - 15,109, 20, 44, 36,148, 24,224,247, 66,166,189,146,204,138, 75, 83,168, 65,253,201,190, 78, 18,111,200,172, 8, 36,204,108, 64, - 81,146,111,218,148,134,153,201, 36,247,247,184,155,144, 3,182,181,145, 39,209,231,106,214,246,142,237,110, 98,205,102,150, 72, -103,195,190, 35, 77, 5,138, 82, 15,105, 78, 28,234, 66,172,246, 14,182,247,195,139, 31, 61, 31, 34, 44, 40,235, 93,222,231,216, -222, 99,113,187,192,251,183, 30, 91, 59,219,152,110, 84,104, 91,137,163, 7,199,120,249,211,115, 2,171, 36,166,111, 14, 88,160, -159, 95,165, 12, 93, 41,160,162,128, 44,139, 28, 29, 40,249, 69,204, 94, 80, 22,159,152,194,228,212,184,241,100, 4, 41,129,170, - 46, 81, 85, 5, 7,161, 4,172, 22, 13,250,190,195,252,250, 10, 31, 78,198,216,216,218,194,245,229, 13, 86,203,134, 62,107,231, - 48, 26,143,240,226,199,231,120,250,213, 19,188,123,125,130,209,184,196,246,238, 54,135,188,180, 16,240,184,189,190,198,252,230, - 54, 11,120,138,162,192,104, 92,101,165,116, 85,151,112,147, 49,186,102,133,102,181, 66, 8, 17,227,233, 4,139,155, 69,182,113, -212,227, 17,110,174, 26,216,206, 81,165, 47, 64,157,186,214,232,218,158, 31,122, 58, 4,138,138,126,127,205,185,247, 96, 81, 74, - 34,232, 5, 8,168,178, 70,215,222, 98,188, 49,197,226,250, 6,213,100,131,198,244, 90, 34, 4,133,201,184,194,108,123, 11,213, -100,138,110,213, 32,186, 22, 77,211, 96,178,189,143,217,206, 14,154,235,115,168,178,198,100, 86, 67, 0, 88,221, 92,226,242,114, -133,213,202, 97, 53,191,194,238,193, 30, 38,147, 18,223,253,253,207,216,216, 61,198,230,206, 54,209,215, 58,135,222,146,192, 84, - 75, 64,203, 0, 1,143,227,143, 62, 67,223,182,216,185,247, 24,207,255,248,247,216, 57, 56, 68, 53,222,160,139,204,247,184, 58, - 59,227,142, 64, 18,221,203,148,216,216,217, 67, 61,219,194,242,234, 2,209,247, 40,235,113,198,238, 10,145, 92, 16, 18, 8, 17, -101,189,129,241,198, 46,198, 27, 91,119, 16,177, 2, 17,139,155, 43,180,171, 91,116,109,203,108, 4,178,235, 81,167, 73,130, 58, -199, 23,182, 9,140,239, 13,180,143,174,199, 35, 20,101, 65,130, 85, 79,222,226,166,105,208,181, 14, 33,244,240,174,135,119,150, - 39,123, 26, 62,114, 8,168, 20,136,142,199,229,190, 31,114,188, 19, 98,118,109, 26,151, 58,153,224, 29,123,200,117,182,199,105, - 83, 12,170, 98, 86, 47,103, 4,103,126,163, 1, 1, 14,107,201, 72, 83,121, 39,190, 53, 53, 3,153, 86, 23, 83,182, 53,103, 68, -228,201,161, 95,203,221, 14, 92, 20,251,187,221,153,243,119, 40,114, 67,188, 42,101, 78,104, 99,232, 89, 75, 28,240,161,103,201, -221,164, 54, 10,174,119, 67,106,152,146, 28,203, 26, 89,216, 55,208, 58,147, 77,147, 28, 45, 10,208, 34, 3, 73,132,212, 64,240, - 16,130,247,229, 84,237, 33, 4,199,162, 53,154,232, 56,231,169,251,244, 14, 69, 81, 65, 72, 74, 95, 75,197, 81, 76,217,223,108, -241,243,150,138, 62,173, 5,140,161, 9,134,227,142, 90,112,144, 83,138,185, 77, 98, 70, 74, 71, 11,128, 78, 23,172, 90,243,109, -135,193,107, 15, 64,200, 34,127,135,206,186,140,114,133,143, 57,245,207, 89, 71, 33, 53, 84, 39,144, 11,166,183, 28,154, 21,115, - 1, 73, 44,134,200,244,188,152,163, 82, 93,202,244, 96,235, 33,101, 90, 4,210,108,177, 80, 77,138,225,217,112, 46,240, 90, 97, -200,233, 80,235,119, 96,134,191,196,172,179, 32,171, 26,141,189,233,125, 27, 86, 53, 50, 39,153,138, 12,170, 1, 23, 49, 41,122, - 46, 77,128,242, 8,254, 79,167, 76, 2,195,152, 63,135,166,137,204,196, 87,114,125, 21,148, 70,244, 98,141, 31, 15,232,152, 57, -195,128, 18,244,229,105, 99,224,250, 62,123,116,189,115,104,219, 14,144, 11,148,245, 62,182, 14,143,112,250,234, 37, 95,228,100, -201, 72, 40,201,196, 76,246, 66, 66, 1,107, 15,131,200, 35, 23,165, 21,172, 13,208, 70,176,128, 67,101,108, 43, 85, 64, 52, 70, - 18, 49,162,170, 11,174,104,193,123, 58, 74, 10, 10,107, 97, 14, 41,214,111, 29,255,167, 20,129, 0,160, 35,188, 27,188,245, 69, -105,178,194,213, 24, 5,165, 37,250,158,147,209, 24,102, 17, 3,160, 10, 94,166,177,151,212,177,237, 44, 41,100, 7,107,159,227, -238,133,188,182,150,173,106, 84, 53, 3,182,109,112,118,114,130,235, 75,186, 24,202,209, 8,159,253,250, 11, 60,251,238, 39,156, -159, 94,230, 61, 76, 96,109, 66, 26,245, 71, 36,123, 27,161, 76,169, 59, 79,227, 59,130,244,132, 32,201,147,174, 13,148,162,202, -175, 44, 75,148,149,225, 85,130,166,128, 19,158, 76, 40,173,113,123,122,129,174,109,241,252,135,231,248,252, 87,159,161, 89,117, - 56, 59, 61, 71,201,152, 91,219, 59,152,162,197,171,103, 53,126,251,215,191,197,237,245, 77, 78, 23,147, 82, 97,181,106,112,125, -117,205,118, 64,122,201,118,246,183,243, 62,208,246, 84, 84, 77, 55,166, 88,220,220, 66, 74, 96,113, 59,199,206,225, 1, 86,139, - 22, 69, 89, 64,105,133,122, 84,147, 72, 17, 17, 69, 85, 66, 8, 42, 66,132, 4, 22,243, 21,121, 81,181, 68, 12, 36, 34, 76,123, -184,144,198,109,188,238,233, 91, 11, 93,141,177,177, 57, 65, 35,123,242, 73, 55, 13,234,233, 6,148,164, 98, 7,193,161, 40, 70, - 56,250,248, 19,172,110,151,152,110, 77,240,238,249, 91,152,178,198,241,227,143, 81,153,128, 27,215,161,154,236,192, 20, 6, 23, -111,223,224,228,205, 41,246, 30, 62,193,242,228, 5,170, 82,226,243, 63,251, 45,158,127,251, 7,168,162,194,222,241, 49, 68,232, -112,123,117, 13,168, 49,250,118, 5,239,123, 24, 21, 32, 88, 17,252,241,175,126,133,118,213,226,205, 15,255,128,157,253, 61,148, -163, 9, 89, 71,251, 6,215,103,239,233, 66,151, 10, 34, 58,120, 68,204,182,119, 48,222,216,192,213,251,247, 88,221, 94, 33, 10, -242,239,123,239,160,117, 65, 5, 35, 11,165,198,179,125,212, 27, 59,168,199, 27,121, 58, 4, 4,216,190, 67, 51,191, 66,223, 46, - 96, 45,141,215,251,190,135,117, 30,214,246, 40,202, 26, 34, 10, 8, 86,160,123,103, 9,194, 81,128,153,251, 53,170, 81,157, 11, -223, 16, 20, 92, 0, 11,104, 61,156,237,224,108,207, 29, 91, 68,144, 50, 31, 56, 8,113,109,108, 76,214, 46,107,187, 44,134, 26, -120,228, 76,210, 74,126,115,105,114, 42,155,214, 5, 95,154,195,101,155, 80,160, 96, 13, 13,117, 92,220,237, 59,203,211,181,225, -239, 77,148,174,192,232,215,164,203,241, 28, 67, 27, 19, 43,158, 59,230, 20,162, 65,120,211,116,198, 32,171,191, 19,188,132, 10, -121,149,189,216, 42, 91,120, 85,198,224,166,125, 39,216, 2,150,118,214,136, 49,195,168,164, 16, 89,123, 34,185, 8, 35,180,108, - 28,192, 57, 0, 77, 78,125,160,110, 44, 14, 28,130,248, 39, 1, 56,228,251, 6, 36,116,142,114,150, 82, 19,112,142, 47,130,100, - 1,165,149, 5, 6,212,106, 36,171, 94,112,142, 45,107, 58,123,180,125, 96,106,155, 72, 25,224, 67, 14,121,154, 50,166, 56,238, - 52, 97, 21,144,107,193, 86, 50,127,103,233, 76, 78,214,183, 36,255,114, 46, 48,224, 75, 12, 99,118, 73,225, 43,228,170,114, 40, -202,130, 38, 30,140,154, 78, 34, 7,197,196, 62,191, 38, 68,211,134, 9,162,220,197,219,174,203,164,204,224, 83,102,132, 96,154, -157,131, 86,130,182, 63,116, 83, 18,171, 33,241, 24,146, 74, 95, 82, 97,164,164,128,245,131,207, 92,138,181,196,190,108,181, 76, -186, 13, 22,155, 99, 0, 30, 37,119,198,154,174,157, 93, 12, 73, 32, 23,215,168,115,131, 22, 56,174,161,129,169, 51, 23,119,172, -222,105,242, 37, 56,194, 71, 32, 66,251, 8,136, 16,208,247, 46, 87,151, 49, 6,130,252,243,200, 47, 70, 7, 89, 80, 55,213,220, -222,160,156,110, 96,115,111, 23, 87,167,103,144,154, 82,147,188,247,208, 69, 65, 35,238,112,151, 10, 69, 94,248, 0, 93,208, 11, -152, 98,246, 28,127, 1,206, 57, 20,165,102, 75, 3, 95,114,145, 46, 7,239, 67,254,133,138,210, 12,133,129, 81, 40, 74,131,224, -169, 96, 72,160,137,244, 82, 36, 15,100,170,206, 83,117, 20, 98,164,145, 58, 87,190,214,122, 20,133,206,161, 50,233, 63, 9,144, - 66,191, 67,215, 17, 44,198, 24, 77, 48,127, 46, 16,218,142, 44,105,182,119,217, 95,158,241,126, 60, 33,160,238,138, 72,100,207, -191,255, 17,163,233, 12,251, 71, 7,248,252, 55, 95,227,197, 15, 63,227,245,203, 55, 89,156, 68, 47,249, 32, 64, 12,153, 34, 52, -132, 19,148, 5, 33, 96,149, 82,156, 9,110, 80, 85, 21, 66,112, 12,138, 49,180, 67, 23, 20, 16,208,181,116,104, 8, 14, 40, 48, - 69,129,197,237, 28,183, 55, 87,248,249,135, 26,247, 63,122,136,139,243, 75, 34,219,105,178,131, 20, 85,137,241, 88,195, 20, 21, - 54, 54, 3, 62,156, 92,161,240, 17, 93, 71,107,153,162, 44, 17, 53, 29,180, 93,211, 97,123,111,103,224, 70, 59, 15,105, 42,184, - 62, 96, 50,155,194,217, 30,183, 87,215,116,105,205,102,228, 79,143, 73,204,196, 35, 86, 37,161, 11,131,201,198, 20, 93,107,209, - 53, 29, 87,202,200, 33, 28, 66, 41,120,235, 88, 71,225, 16,225, 17,133, 69, 12, 17, 7, 15, 31,194,118, 29, 54,118,182,105, 71, - 43, 13,116,138,140,148, 64,189, 49,198,116,103,143, 39, 9,204,225, 15, 17,123,247, 30,162,170, 75, 52,183,103, 40,234, 49,234, -113,141,235,211,247,248,254,143,223, 99,247,193, 19,216,174,129,239,230, 56,122,244, 8, 34,116,184, 60, 61,197,222,131,167, 64, -116,184,185,188,198,124,222, 96,188,181,129,232,174, 33,130,165,110,183, 52, 56,254,228, 51, 76, 55,183,240,237,223,253,111,216, -216,218, 70, 49, 26, 67, 32,192, 54,115, 92,188,127,199,214,150, 8, 83,210,115,183,185,119,136,237,163,123, 56,123,243, 26,171, -155, 83,132, 0,152,178,130, 79,164,198, 16,121, 44, 45, 49,221,218,197,104,186, 13, 83, 22,176,150,170,126, 66,188,182,184,189, - 58, 71, 12, 62, 63,143, 93,215,161, 93,173,114,135,103, 93,200, 94,127,250,239,123,152,210, 67,235, 17,170,209,152, 66, 50, 64, -164, 47,231, 19, 48,132,132,137,237,106,145, 11, 86,109, 10,244,206,145, 26,217,210,232,218,135,152,173, 82, 16, 67,252,242, 58, - 23, 59, 93,160, 57,204, 34,217,189, 98,132, 49,101, 70,255,146, 50, 92,241,193,157, 18,171, 34,139,207, 56,115, 58, 14,216,224, -129,198,152, 66, 67, 88,221, 29,104,186,229,115,244,168, 92,243, 0, 71,246,134, 99,136, 64, 77, 16, 31,200,129, 62,151,244, 63, - 44,198, 74,227,248, 16, 34, 10, 38,146, 9,222,147, 74, 30, 3,123,230,204,135,148,105,159, 97, 37,200,204,134, 44,146,145,146, -213,223,200,205, 75, 26,217,166, 44,121,145,109,113,248, 19, 6,185,202,151,120, 20, 4,211,233,251, 46,175,178, 36,251,222,139, -162,204,211, 15,239, 2, 76, 65, 69,206,112, 49,113,190,124,246,141, 71,136, 56,232,144,168,192, 72, 25, 25,122,200,231, 72,238, - 4, 46, 24, 10,230,122, 80,129, 55,136,194, 98, 76,252,129,180,235,151, 57, 45, 16,136, 16, 74,128,148, 27, 49, 83, 8, 41, 31, - 39, 77,130,213,157, 0, 31,178, 84, 82,152,149, 76, 90,140,100,246,146,146,121,237,180,106, 72,197,171, 82, 50, 23, 90, 9, 11, -107,109,191, 54,251, 9, 72, 63,145, 96, 17,170,144, 18, 50,143,240,105, 4, 30,114,238, 73,164,169, 99,162, 33,176, 70, 34,198, -136, 32,249, 41,226, 6,109, 8, 91, 17,107,250,168, 20,200, 66, 43, 20,228,154, 78,220, 25,171,139,245,125,250,128,143, 27, 80, -180,156, 58, 71,246, 81, 46, 56, 50, 57,106, 77,158,239,172,207,216,191, 16, 28,148, 2,188,237,225,122, 78, 88,235, 41, 52, 99, - 52,157,210,216, 69,137,252, 97, 9, 1,138,105,228,202, 60,225, 11,201, 83,136, 76,159,114,172,118, 20, 28, 76, 79,162,139,144, - 5, 54, 49,146,189, 99, 64, 1,166,152, 77,172, 81,215,232, 23,166,203, 94,176,184, 44, 49,221, 99,142,119, 77,151, 90,218, 31, -101, 64,190,162, 81, 59, 21, 4, 50,143, 52,164, 38, 33, 90,219, 90,180,109,143,182,233,136,223,205,135, 37, 89,208, 92, 78,166, - 91, 71,246, 5,246, 57,230, 14, 60,146, 7,221, 89, 18, 23,157,159,188,195,183,255,252, 71,188,124,246, 22, 79,191,254, 18,127, -254,239,126, 59, 84,157,124, 49, 38,114,158,115,204,170, 22, 2,227,201, 8, 91,219, 27, 24, 79, 71,140,109,165, 16,153,178, 42, - 33, 21,113,239,139,194,240,239,197,222,125,246,147,123,103,115,180, 38,133,218,144,207,242,245,139,231,168,199, 83,220,123,112, - 12, 99,168, 40, 26, 79,106, 60,253,252, 49,219,220, 78,135, 14,211, 57, 24, 99, 80,141,106,212,227, 49,202,154, 84,254, 93,215, - 98,182, 57,227, 21,137,129, 46, 76,222, 73, 17,165,143,198,246, 74, 73,236, 29,237, 96, 52,169,115,247,166,180,132, 97,107,202, -104, 60, 66, 61,161,221,186, 50, 67, 64, 67,162, 77,133, 16,161,211,239,199,168, 97, 93, 24, 84,227, 49,182,182,103, 0, 34,166, -155, 83,132,224,177,127,124, 8, 41, 3,138,130, 88,248, 17, 18,219, 7,123, 44,192,163,169,204,206,225, 33, 70,179, 25,140, 38, - 16, 78, 61,221,132,109,110,240,199,191,255,103, 76,119,143,113,246,238, 29, 16, 3,170, 74,225,147, 47, 63,197,247,191,255, 61, -198,155,135,168, 71, 5,108,187,194,229,217, 25, 76, 89,211,229,101, 23, 64,236,104, 90, 34, 37,238,127,250, 21,190,249,219,191, -193,120, 58, 70, 61,157, 66,138,128,155,243,247,184, 56,121, 67,148,184, 24,178, 64,115,115,247, 8,219,199, 15,113,121,242, 22, -183,103,111, 97,187, 14, 2, 30,205,226, 6,182, 89,192,219, 6, 2, 17,163,233, 6,182, 15, 31, 96, 99,247,152,211,219,104, 42, -214,181, 13,250,102,142,213,237, 85,214,104, 56, 31,176, 90, 46,208, 53, 43,222,133, 15, 28, 7,154,246,248,220, 97, 43,173, 24, -205,107, 96,202, 2,210, 16,193, 76, 42,197, 92, 5, 7,103, 59, 90,141,241, 69,213,119, 61,171,210,177,230,195, 78,153, 2, 34, -143, 74, 37, 95,202, 41, 26, 51,249,194,147,231, 91, 96,192,206, 38, 85,119,100,248,139, 41, 6, 70,119,238, 85,248,123, 15,108, -159, 36,220,107,204,161, 29,193,199, 59,227,208,129,226, 62,248,223,115,154,162,144, 60,225, 72,145,151, 17, 62,184, 33,130,147, - 87, 6, 41,230,149,254, 29, 78, 13,147,195,184, 94, 74,197, 23, 20, 50, 14,122, 29,113,235,152, 67, 31,217,147, 79,222,243,248, - 39,194, 87,149, 49,210,169, 41,176, 46,228,117,165,231,209, 62,214, 58,116,173,239,238,242, 5,227, 96, 9,219, 76,140,125,231, - 61,217,216,216,250,149, 66, 99, 4,227,116, 29,231, 98, 68,112,241,193,154, 12, 58,119, 4,115, 40,100,230,102, 36,238, 65, 34, -214,133, 20, 4, 19,169,176, 72,164, 62,210, 5,164,103,130,240,182,166, 48,208,218,100,142, 72,224,110, 56,137, 21,210, 89, 25, -153,170, 55,196,228,138,252, 28, 40,142,242,150,107,211, 25,109, 24, 36,195, 58, 40, 99, 82,209, 23,178,160, 77,107,210, 22, 41, -153,224, 46,158,169,161, 60, 46,231, 41,237,250,189,169, 20, 89, 30,211, 26,118, 61,218, 90,166, 0, 21,158, 66, 32, 23, 88,244, -189,148, 69,137,170, 44, 9,164,147,161, 73,114, 96,188,139,132,146,101,166,189, 84, 80,202,228, 66, 86, 74,157,237,157, 41,240, -135,231, 43, 67, 70,123, 18, 75,166, 52,188,164,243, 16, 26, 90, 72, 9,215,219, 92,217,248,100,237,210,212,205,118,150,198,115, - 69,201, 31,150, 16, 80, 50, 0,162,192,104, 58,165, 78,193, 58, 72,197, 36, 56,164, 17,116,230,217,229, 17,125, 2, 38, 72,173, - 80,104, 5,231, 57,184,132,105, 75,166, 52,136, 33,102,158,175,247,196, 70, 79,162, 19, 41, 35, 32, 34,137,120, 66, 96,133,165, -204, 35, 16,165,249,197,230,234, 60,216,100,121,138,185, 66, 78,176, 5,109,210, 62, 95,176, 69, 2,136,158, 20,239, 67,134,122, -132,179,150,128, 58, 82,230, 78,223,246,238, 79,196, 9,100,111,203,123, 56, 68,182,224, 16,237, 42,117, 44,148,192, 6, 88,219, -225,213,207, 63,227,195,219,247,248,226, 55, 95,225, 63,253, 47,255, 9,223,252,211, 55, 56, 59,189,228,169, 3,249, 29,203,106, -204,194,189,146, 46,213,130, 68,134,213,184,226,253, 35,137,197, 52,115,243,211,216,191,239, 98, 14,195, 81,146, 42,212,219,171, - 57,186,206,162,105, 58, 20,133,193,120, 50,193,106,185,196,171,103,175,240,244,139,167,184,190,186,134, 82, 10, 95,253,230, 51, -108,238,108,226,250,226, 6,215,151,215,104, 27,139,167, 95,126,140,179,247, 23,252,251, 68,120,219, 99,181, 32,101,121,179, 92, -225,225,227,163, 44,248,162,196, 57,129,122, 92,195,118, 29,165,141,185,128,182,105,177,185,189,129,197,237,138,200,115,147, 10, -101, 93,178, 88, 42, 66, 23, 5, 20,231,173,147,243,129,158, 67,234, 58, 61, 11, 44, 89,248,164, 21,170,186,134, 84, 26,163,233, - 6,156,237, 49,154, 76, 32, 16, 81, 86, 37,198,155, 19,220,158,159,194,104, 9, 17, 11,220,251,228, 49, 78,222,156,162, 40, 12, -186,198,162, 30,213,112, 14,152,110,140,112,253,225, 45,198,179, 13, 24, 35,241,187,255,243,111, 81, 78,118,112,113,122,137, 66, - 3,182,153,227,248,241,199, 88, 94, 95,193,121,129,227,135, 7,240,221, 10, 39,175,223,161,235,122,140,183,106, 52,203, 5,224, - 87, 52,213,137, 17,159,254,229,127,196,234,234, 3,148,150, 40,138, 9,162,239,241,225,237, 47,152,223, 92, 33, 6,207,123, 62, -170,220,183,247, 15,113,240,209, 39, 56,123,251, 11, 46, 63,188, 38,123, 14, 71, 22, 39,157,139, 54, 6,163,233, 6,166,219,251, - 80,166,204,137,131,205,178, 69,112, 84,176,217,110, 5, 31,124,166,186, 17, 8,166, 33, 29,137,210,236,116,149,204,254, 86,108, -247, 41, 81,141, 70, 25,179, 25,185,168,140,105,212, 11,192,123,139,190,235, 50,221,203,121,143,200,187,222,222, 58,154,216,192, -231, 68,173,108,183, 97, 56, 71,138,181,164,105,109, 96, 31,179,230,188,241,130,242,160,133,132, 84,132, 35,206, 78, 93,230,187, - 43, 69,241,166, 50,147,231, 72,204, 69,239,176,231,145,172,200,182, 44,193,187,209, 20,226, 18,216, 6, 6, 17,179, 77, 73,102, -181, 53,178,205, 76, 10, 22, 30,242, 62, 85,112, 7,148, 46, 52, 41, 21,188, 72, 62,116,157,247,160, 73, 20,247,167, 59,124,234, -208,124, 30, 31,251, 28, 60,179,206,249, 30,192,226,142, 71,243,224,203,196,218, 62, 91,182, 2, 79, 54, 60,103,181, 39, 12,110, -200, 66,178,193,151, 13, 17, 73, 5,158,124,226, 66,115, 22,132,186,227,171, 87, 24,176,174, 49, 56,110,134, 6, 62, 63,120,127, -108, 45, 9,168, 83,145, 46,184,155, 22, 94, 32, 40,154,130,169, 28, 92,163,178,159,155,208,207, 5,159,207, 58, 79, 8,164, 34, -206,188, 90,195,119, 83, 40, 13, 83,229, 98,162,235, 13,192, 30,193, 5, 73,240,196, 63, 73,160,160,244,119,122, 79, 59,241,212, -225,165,162, 72, 41,106, 24,250,142, 10, 83,195,147,230,100, 31, 78,235, 44, 26,179, 7, 40, 41, 16, 83,115,233, 35,221, 37, 61, -161,201,147, 0, 47,248, 8,153, 62,131,136,188, 63,215, 90,103, 18, 94, 18,203, 73,165, 40,110,155,131,115,156,179,121, 58,146, -214,200, 89,119,225,104, 2,169,146,222,193,243,106, 51,242, 52,133,191,219,244, 14,164,172,122, 90, 91, 13,236,119, 2,178, 1, -186,172,106, 68,239,208,179,144, 70,241,254,105, 32,170, 9, 38,237, 68,232, 20, 88,210,117, 16,186, 64, 49,154, 80, 71,185,108, - 96,228, 16, 60, 64,227,117,159, 81,128, 9, 78, 34, 36,137,158, 82, 70,182,214, 18, 93,227, 32,184, 19, 91, 45, 59,218, 17,151, - 37, 26,142,127, 13, 1, 40, 11,197, 63,147,202, 29,119, 96,197,106, 98,238,210,136,110,136, 76,244, 46, 64,105,193,255, 59, 58, -116,232,126,143, 67, 88,189, 36,255,107, 8, 68, 94, 82, 37,211,149, 66, 64,111, 61, 71,164,130,225, 39,138, 49,134, 50,147,225, -144,130, 22, 98,200, 99, 37,170,170, 69,182,138, 40, 38,192,121,134,250,123, 55, 84,144,171,229, 45,254,229,239,254, 1,247, 31, -127,140, 95,253,213,111,177,188,189,193,179,239,159, 97, 49, 95, 0,145, 56,197,101, 97,104, 47, 54,170,214,126,223, 72,105,113, -117,205,244, 61, 42,164,156,117, 40, 75,138, 63, 44, 74, 3,215,211,190,191,239, 45, 22,243, 5, 63,172, 84,217, 77, 55,103, 40, -171, 2,125,183, 68,211, 56,124,241,171,207,224,108,143,195,251,135,232,218, 22,215,151,215,152,223,206, 97,123,139,219,155, 93, -204, 54,103, 88,204,151,208,133, 70, 81,149,232,251,130,145,187, 61, 70,147, 49, 62,188,121,159,139, 66,193,161, 33,105,157,162, -107, 3,215,181,144,106, 7,211,141, 9,250,174,103,198,190,230, 0, 31, 13, 83,210, 37,223, 44, 26,116, 29, 51,246,165, 64, 89, -167,138, 87, 3, 50,100,129, 75,194, 18,111,237,237,160, 93, 46,176,177,179,141,122, 84, 96,113,235, 81,150, 5,124,223,195,246, - 22,211,205,141, 28,106,113,123,117,141,141,237, 77, 78,214, 27,195,182, 11,148,117,141,201,214, 54, 94,124,251, 45, 2, 74, 72, - 83,225,234,195,115,124,242,197,231,144, 34, 96,239,248, 0,191,255,127,254, 22,219,135,247,160, 68,196,229,229, 53,154,166, 69, - 81, 20,136, 81, 34,118, 87, 64,116,136,193,224,147,223,254,123,220,127,250, 41,126,249,183,127,129,214, 6,221,242, 22, 31,222, -188, 98,245,125,184,147,230,180,123,252, 16,123, 15,158,224,195, 47, 47,112,123,254, 14,136,150, 59, 45, 13,111,123, 4, 41, 80, -143,167,152,110,239, 96,188,177,141, 32, 74,184,190,131,181, 14, 61,119,231, 49,116,153, 48, 70,182,196, 30,125,215,163,109,150, - 57,250, 50,197,127, 66, 12, 30,238,178, 26,161,170,107, 42,142,211,127, 39, 36, 44,243,219, 5, 8,255, 42,224, 6, 12,166,210, - 28, 15, 38, 96,249, 89,167,119,155,109,157,201,208,189,182,103,164,144, 23, 63, 8,227,114,142, 53,239, 11, 33, 81, 20, 21, 31, -124,195, 37,153, 14,200,152,119,221, 3, 68,138, 6,160, 49, 3, 83,136,168,231, 51,242,117,184, 56,195,208, 53,199, 1,254,146, -152,229,193, 15, 69, 65,196, 32,214, 74, 48,154,184,230, 15, 30, 48,187,129,227,123, 85,222,241,166,127,150,138, 6,210,223,244, -121, 95,186,206,163,207, 88, 83,173, 50,139,194,123,151, 39,144, 57, 15, 62,117,188,233,240, 22,226, 14, 89, 51,217, 3, 99, 76, - 23,188, 31, 40,108, 60,237, 83, 74, 67, 41, 74,108, 76, 22, 52, 98,144, 15,241,178,217, 2,151, 59,229, 0, 4,129,162, 48, 84, - 0,230, 93, 56,205,122,140, 97,242,158, 88, 15, 89,137,121,109,160,185, 96,204, 35,105,102, 11, 4,206,102, 72,224,172,116, 79, -101, 45, 68, 72,255, 27,234,198,147, 24, 89, 41,149, 5,137, 67,116,116, 2,245, 80,169,154,152,244, 3,152, 37, 77,113, 67, 62, -191, 3,175,131, 36,187,148, 92, 31,120, 92, 46,178,110, 33, 9,235,250,222, 66, 73,158,114,112,172,111,223, 91,210,128,112, 1, -144,224, 53,233, 57, 37,146,167, 88,227, 21,208,180,195, 20, 37,103, 94,184,252,157,144,248, 84,178,224,155,222,155, 52, 37, 39, -190,125, 88, 35, 61,242,190, 60,229, 26,179, 88, 51, 66, 64,172, 5,129, 70, 36, 33,105,132, 20, 17,218, 7,192, 20, 37,198,101, -137, 16, 2,218,213,138, 40,110,236, 61,167, 47, 64, 66, 72,234, 2,148, 54,204,118, 39,142,177,212, 5,180,182,136,145, 46, 47, - 17,169, 99, 80, 74,195,139,136, 66, 42,194,196,114, 37,104, 45,231, 26,243, 15,175, 12, 85, 57,130,129, 41, 66, 8, 22, 70, 81, -215,166,140,129, 9,128, 54, 50,195, 35, 8, 84, 66, 2,138,132, 2, 84, 33, 32, 74,145,163, 95,181,161,195, 95,115, 85, 43,152, - 44, 68,126,104, 26,221,219,222, 35, 32,217,227, 72,160, 17,124,228, 47, 49, 50,162, 53,220,137,106,181, 61, 85,224, 57, 2, 84, - 2,109,235,242,225, 64,145,175,130,145,178, 30,158, 5,116,116,241,115, 90,143, 36, 62,212,184, 46, 33,165,196,205,229,123,124, -255,199,136, 39, 95,126,130, 63,255,239,255, 2, 87,231,103,120,245,211, 75, 88, 22,146,164, 66, 36, 41,129,137,158,100, 56, 92, - 39, 32,136, 1,183, 27, 65, 85,239,114,209,112,172, 45, 33, 39,235, 81,153,171, 80,109, 10,196, 24, 48, 30, 87, 88, 46, 86,184, - 56,125,143, 79,191,250, 12,136, 29,234, 81,137,139,211, 11, 98,152, 3,232,187, 30,111, 95,253,130, 79, 62,255, 12,101, 85, 34, - 6,186,140, 77, 81, 32, 40,207,151,108,204, 65, 54,206, 57,192, 35,239, 8,181,209,217,210,226,125,128, 41, 10,222,183, 70,138, - 95,245, 49,119, 52,218,104, 52,171,150, 1, 60,150, 70, 82,156,157, 93,148,134,149,206, 18,101,173, 32, 85, 1,169, 13,170, 90, -163, 89, 74, 24, 45, 49,153,141, 96,109,100, 13, 67, 11, 83, 22,216,189,119,132,159,190,249, 25,186,168, 80,215, 5, 54,247,247, -224,173, 69, 61, 46,225,187,136,143,191,124,138,151, 63,189,198,243, 31,158, 97,239,193, 19,188,248,238, 91,200,216, 98, 60,157, -224,248,227, 7, 56,125,253, 22,197,104,134,201,164,192,252,234, 10,103, 31, 62, 64, 68, 15, 37, 43, 82,148,135, 6,136, 1,143, -190,250, 11, 60,252,252, 43,220,158,189,131,136, 30,243,139,247,184, 60, 61, 97, 48,138,202,246,188, 24, 35,118, 14, 31, 98,255, -193, 19,124,248,229, 57,174,207, 94, 67, 42,147, 99,107,165, 4,170, 81,141,241,108, 3,179,237, 61, 20,147, 77,120, 79, 7, 67, -111, 61,230, 87, 87, 48, 58, 0,209, 34,184,142, 98, 61,237,144,127,221,247, 45, 95,154, 10, 92,231,210,238, 91, 72, 24,173, 48, - 30, 79, 96, 10, 42,160, 82,241,222,119, 22, 33,118,116,217,112,212, 36, 21, 32,138,223,191, 10,161,109, 0, 73,196, 57,169,136, -179,160, 25, 18, 37, 89,230, 35, 32,114,192,137, 75,120, 77, 33,115, 55, 79,217,227,116, 17,211,133, 68,216, 82,114,162, 80, 17, - 96, 10,147,243,167,105,111, 46,214,132,110, 33, 43,220, 83, 39,159, 58,151,164,189,161,113, 50, 51,221, 65, 23,174,231, 16,167, -116,232,167, 49,104, 42, 62,192, 59,229,117,156,107,222,107,243,254, 58, 5,192, 40, 73,107,174,161,120,145, 25,218,147,128, 33, -233,239,167, 2, 95,102, 1, 47, 21, 65, 1,209, 49,131,222,135,124,224,167,253,123,162,177, 9,222,207, 43,169,178,165, 78,222, -137,134, 93,179, 59,201,245, 52, 74,197,251, 87,228,204,134, 84, 96,173,255,254,185, 48,224, 96, 29,191,246,231, 56,134,179,200, -245,177,189, 34, 7, 74,102,185, 67,228,144,149,148,151,145,196,126,169,211, 38,191,250, 58, 45,110,208, 3,144,211, 64,229,127, - 63,196,200, 59,244,192, 19,193,181, 53, 78, 90,203, 96, 16,159,165,247, 41, 21,103, 52,253,145, 16,156,216, 23, 67,128, 49, 18, - 93,155, 44,106, 4, 57, 2,167, 0, 58,206,160,160, 14, 92,112,222, 68, 63,100, 16, 68, 90, 75, 39, 55, 3, 61, 71, 22, 76,105, -134,214, 20,116, 37, 4,177, 77,164, 90,123,158, 82,194, 28, 63, 23,180,170,226,159,129,113,188, 73, 59, 33,132,192,218, 12, 39, -143,233, 9, 36, 35, 6, 77, 10, 63,179, 50,125,181,136,119, 28, 90,233,131, 9, 16,208,193,118, 8,122, 68,106,116, 45, 80, 86, - 21, 7,176, 36,218, 16,243,125,215,176,164,125,219,210,158,164,174, 81,212, 99,184,222,114,101,162,160,184, 75, 78,158, 77,107, -125, 6, 53,152, 66,163,235,232, 0,191,163,226, 19,131,221,197,249,196, 55, 15, 40, 42,195,161, 6,244,210, 22,212,148,163,172, -139, 33,114,149, 85,152,214,210,151,106, 10,197,122, 0, 30,171,173, 81,124,214,125,243,182,231, 23, 78, 9,230,108, 75, 74,110, -227,206, 62,219, 30,108,132,228, 84, 60, 2,120,208,165,158, 14,147, 36, 30,162,240, 2, 53,216, 13, 25,108,161,180, 68,215,217, - 28,235, 10, 68,148,101,193,255,254,144,122, 22,125,135, 23, 63, 60,199,253,199, 15,176,185,179,139,221,131, 61,188,121,254, 18, -103, 31, 46,201, 67,201, 5, 22,237,228,136,210, 37, 49,236,133,210,170,192, 57, 71, 93, 22, 67, 32,202,210,240,197, 74,135,200, -252,118, 9,173, 53,138,162,128, 98,184, 78,179, 92,225,226,236, 10,159,125,245, 17, 98,180,184, 60,191,166,201, 77, 4, 70,147, - 26, 49, 16,152,230,248,225, 61,124,120,251,142, 4, 35,252, 28, 0,164, 86,175, 70, 21, 81,250,170, 10,171,149,135,102, 94, 62, -237, 5,233,103,187,189,186,197,116,115,132,243,211, 11, 76, 54,122, 6, 60, 68,190,236, 13,170,186,162, 23, 75, 72,130,221,240, - 62, 73, 42,137,122, 84,175, 81, 6, 13,148, 41, 49,217,220, 66,183, 92, 97,107,111, 27, 27, 91, 99, 72,165, 81,141, 71,232,154, - 37,180,209,152,110,111, 97,126,115,139, 85, 99, 97,172,199,211,175,159, 80, 49, 18, 35,108,215, 98,247,232, 16, 93,211,226,197, -247, 63,227,224,209, 83,188,255,229, 53,124,191,194,108,115, 3, 27, 59,219, 40, 10,141,197,124,137,173,221, 45,244,203, 91,188, -127,253, 6,193, 89,148, 69, 68, 49,154,160,109,110, 32,162,195,163, 47,255, 18, 71,143,159, 64, 9,143,235, 15,111,113,242,242, - 25,110, 46, 47, 88, 33,173,242, 4, 71, 10, 96,247,222, 35,236, 61,120,130,211, 95,158,225,226,228,121,238, 64,133,210, 64,244, - 24, 77, 54,176,181,183,143,241,108, 3,194,140,208,117,148,166,119,123,117, 13,111,123,128,139,102,239,122,138,202,116,148,249, - 76, 99,114,166,162, 41,149,189,237, 29,115, 20,170,170,194,120, 58, 33,101,112, 89, 80,168, 8,135,125,208,191, 67, 66, 38,173, - 37,234,209, 56,219,198, 98,136,104,181, 70, 89, 87, 20, 35,220,247,104,150,171,220,109, 11, 80, 39, 36,214,210, 16,147, 55, 89, -240, 37,161, 85, 68,231, 59,166, 0, 42, 22, 88,233, 97,116,155,178, 34,148,202,151, 70,242,142, 75, 41,137,180,151,186,234, 48, -172, 9, 37,147,180,172,181,119,118,219,142, 69,122, 82, 12, 30,241,144, 89,217,156,123,158, 58, 73, 46,166,210,229,146, 84,224, -169,235, 78,228,176, 68,143,139,172, 86, 55,133,200, 5,118,178, 27,230,128, 24,206, 10, 23, 98, 16,111,209,207,200, 33, 43, 96, -198,120, 34,120,250,161, 73, 32,161,161,204,135,182,103, 91, 97,242, 55, 99, 13, 43, 42, 88, 40,152, 16,161,169, 43, 78,233,229, - 69, 81,146,208,145,139, 69,250,188, 67,238, 10, 35,168, 35, 77,186, 29,154, 72,168, 60, 53, 32,146,155,134, 20, 42, 91, 74, 83, - 65, 36,181,102, 49,239,186, 16, 50,102,198, 64,228, 21, 7, 77, 53, 56,145, 51,130, 59,222, 8,159, 18,237,210, 90,211,179, 53, -205, 72, 38,210,201,156,180,151,154, 46,210, 68,173, 41,200, 64,201,148,105,101, 44, 57, 42, 91,128, 38, 72,116, 78,135, 12, 41, - 74, 65, 40, 73,128,172, 53, 53,144, 4,137,241, 67,247,238, 98,158,170,133, 32,200,194, 6, 32,166,252,116,165,120,194,164,115, - 48, 79, 90,137, 8,230, 40, 24,109,184, 96,147,153,151, 32,132,164,102,215, 57,130,104,113,163, 75,147, 15, 46, 80, 84,202, 13, - 96, 83,104, 18, 21,134,225, 25, 75, 54,236, 52, 13,137,172, 19,201,137,114, 49, 88,216,213, 45, 34, 20,140, 25, 81, 69, 95, 20, - 80,146, 67, 53,248,133,115,214, 67,245,150, 71,117,158, 60,162,144,168,199, 53,132, 54,176,140, 50, 21, 66,192, 84, 21, 98, 8, -140, 55, 77,123,236,228, 79, 47, 16,133, 92,171,236,144, 97, 41, 97, 45,234, 81, 39, 44, 37,127,121, 85, 85,228, 2,195,246, 14, - 69,161,179, 42,147, 46,104,129, 32, 4,250,206,195,176,181,129,212,143, 33,171,225,211,184, 69, 58,228,241,123, 42, 0,136,206, -196,217,202,158, 70, 77, 62,210,206, 94, 96, 77,100, 22,134,240,137,190,239, 81,148,134, 11, 10,126,248,210, 62,159,247,192, 36, -158, 32,134,121, 93,151,192,136,216,236, 5,199, 1,198,181,211, 49,120,139, 55,207, 95,226,240,254, 49,198,211, 26, 71,143, 30, -225,232,225, 49,126,252,230, 39,172,150, 43, 8, 65, 73,119, 85, 61,226, 64, 14,218,240, 36, 15,254,250,202,132, 20,242, 50,123, -124, 83,145, 17, 99, 68,219,118, 40, 37,189,240,198, 24, 96, 84,227,230,242, 28,109,251, 0,219, 59, 99,104, 45, 49,219,152,194, - 24,205,238, 0,131,102,185,196,252,102,137,201,108,130,235, 11, 66,198, 6, 31,208,119, 29,218, 85,131,217,108,132,190,187,225, - 0,155, 0,111, 36,250,222, 35,248, 62,119, 7,229,168, 67, 8, 99, 24, 35,176,156, 47,233,165, 98,204,238,120, 50,202,130,168, -178, 42, 56,118,181, 36, 48,145,184,203, 89, 78, 99,189,241,116,140,219,243, 83, 28,108,207, 48,219, 24,243,129, 76,127,166, 41, - 75,108,238,110,227, 15,127,247, 47,168,234, 9,142,238,109, 67,168, 2,163,105,141,110,213,192, 69,141,217, 70,141,111,255,240, - 2,202,148,184,185, 90,160, 89,222,194,200, 30,123,247,191,196,222,209, 46, 78,158,255, 12, 85,142, 32, 5,240,250,197, 43,180, -171, 57, 36, 58,152, 98, 3, 54, 40,192,222,226,225,231,127,142,135,159,127, 5, 41,129, 15, 47,126,196,243,111,254,136,190,107, -160,180,204, 2,168, 84,183,238, 28, 61,192,225,227,207,240,238,217,143,184,124,255,156,125,179, 2,193, 91, 40, 93, 96,247,232, - 16, 59, 7, 71, 48,229, 24, 62, 10,172, 22, 45,250,174,199,106,185,132, 82, 32,138, 99,136,236, 63,119,104,150, 13,250,182,201, -188,117,197,137,129,145, 57,221,222,121,148, 85,141,241,100,138,162,164,142,205, 20, 5,132,210,208, 50,165,102,121, 78,131,147, - 57, 98,183, 40, 74,164,249,158,237,123, 20, 53,241,227, 37,119, 93,180, 51,173,168,176,235, 58, 4,132, 12,216,240, 44,178,202, -110,242,224, 0, 57,128,132, 72,212, 86,242, 84,203,100, 37,177, 76,118, 37,214,243,120,111, 51,104,133,138, 34,151, 69,174,132, - 11,101,193, 85, 82,219,243,127, 58, 22,133,166, 66, 42,161, 55, 37,119,150,206, 58,154, 84, 33,194, 40,205,246, 35,149, 17,163, - 3,220, 37,230,105,147,228, 98, 36, 9,210,210,207,147,253,218,220, 21, 39,143,188,231,130,196,187,200,147, 50, 57,236,189,121, -196,238,108,207,251,122,172, 81,196,100,118, 28,100,142,100, 22,193,145,158, 8,121,143, 79, 19,147, 64,140,235,220,188,100, 91, -154, 80, 57,202, 52,135, 44, 5,127,135,224, 41, 88, 48,155,108,130, 41,143, 62, 51,234,249,220, 3, 8,240,229,157,131, 42, 10, -206, 11,240,204,130, 23, 57, 30, 58, 1,106,210,100, 84,240, 51, 9, 68, 18, 87,106, 18,129, 57,219,147,146, 94, 15,222,242,180, -230, 76, 80, 49,154, 40,234, 76, 0, 77, 50,240, 0, 1, 37,210, 69, 42,115,103, 79, 80,150,192,200,223,192,223, 15,187, 14,192, -232, 86,163, 56,209, 82, 32,114,183,206, 28, 58,166,187, 33,175,114,144, 47, 79,228, 61, 57, 57,120,169, 24,213, 70, 17,235,128, -145,226,146, 3,111,164, 20,240, 98, 88,243,172, 23,124,105,125, 18, 66, 64, 76,147, 19, 49, 76,135, 36,107,169,148, 20,185,163, -207,171,101,201,174,130,228,248, 72,228,188,204,243, 32, 65,162, 64,128,250, 95,255,221,151,255, 25, 28,190,210, 55, 13, 43,142, - 53,116, 89, 82, 44,106,170, 30,217, 79,158, 42,188,100, 89, 81,166,100, 21, 40, 43,194,189,207, 21, 88,206, 10, 14, 41,144,132, -189,157, 28,188,146,246, 75,235,135,117, 82,132, 70, 38,167,165, 17,156, 41, 56, 13, 72,145,160,206, 51, 22, 54,253,114,130, 61, -179,148, 10,231,225, 92,128, 41, 82,178,208, 16,249,152, 24,247,195, 37,145,170,229,228, 73,101,133,163, 98,224,190, 24, 8, 64, -233, 75, 75,179, 18,219, 19,253,136,112,165,180, 31,206, 94, 85, 12,222,115, 41, 73,157,174,148, 68, 89, 21, 48, 70,231,204,245, - 52,190,211, 70, 51,201, 14, 88,220,222,210,193, 89,104, 92,158,221,226,241,167,143,161,181,196,245,229, 13,164,162,208, 19, 64, -101,253, 64, 96, 47,187, 82, 18,117, 85, 65, 27,153,247,103,121, 55, 21,239,230, 74,175,150, 43, 20, 69,145, 71,228, 52, 14,140, - 56,184,119, 8,103, 59, 2,210, 88,246, 91, 50, 45, 46,196,136,253,227, 3,172, 22, 11,234, 12,217,223, 42,149,196,246,222, 54, -110,175,111, 41,206,117,105, 81,143, 42,220, 92, 93,195,246,125, 46,172,250,214,162,158, 76, 33, 4,133, 51, 20,165, 65, 8, 2, -166, 80,144, 74, 96,186, 57,193,219,151,239, 0, 86,205, 86,117, 5, 33, 5,166,155, 83,156,190, 61,201,105,118, 49, 0, 69, 85, - 97,182, 69,244,186,135, 31,223, 67, 89, 42, 44, 23, 45,177,167,109,139,122,182,129,247,175, 79,176, 92, 58,236, 29,238, 98,247, -112, 15,136,132,225,237, 86, 11, 22,209, 88,188,251,229, 20,214, 70, 92,188, 63, 65,236,231, 48, 69,137,207,255,226,191, 67,183, -184,194,124,194, 95,203,230, 0, 0, 32, 0, 73, 68, 65, 84,222, 96,107,119, 19, 31, 94,191,193,201,203,159, 33,209, 67,138,128, -241,230, 61,116,109,139, 39, 95,125,134, 71, 95,124,141,118,126,137, 24,128,127,253,155,255, 3,182,111,120, 5, 28,134,112, 36, - 68,236, 30, 61,192,209, 39, 95,226,195,171,159,113,245,254,101,142,186, 20, 66, 96, 60,219,194,246,193, 17,118, 14,143, 81,142, -166, 8, 80,152,223,174,176,156, 47,176, 90, 46, 96,180, 34,194, 89,116,232,218, 14,182,235,209,174, 86,104,155, 57, 11,164, 20, - 36,219,212, 34, 20, 76, 81, 33, 70, 5, 93, 84,152,206, 54, 81, 86, 53,234, 81,141,122, 50, 70, 61,158,160, 30,141,249, 80, 20, -124,168, 59, 62,112, 76, 46,226, 35,119, 95,158,157, 35,214,122,230, 89,176,237, 50,210, 62,214,100, 52,180,202,157,164, 88,139, - 53, 77,239,209, 96,183,165,191, 71,240,168, 81,105,197, 29,154,225,241,169,228, 81, 61,231, 87,139,200, 90, 18,145, 93, 48,138, -243,222, 83, 72, 82, 12, 3,239,253,110, 6,186,200,227, 99, 26,137, 91, 14,141, 42, 88,137,205,148, 75,165,249, 60, 81, 67,164, - 42, 68,126,231, 5, 79, 17,232, 48, 47,242,152,149, 20,232,242,142,133, 54,169,169,251,174, 91,203,114, 7, 39, 46,130, 5, 83, -142,189,244,110,141, 64,150, 82, 35, 7, 6,248,250,229, 10,129,156, 24,150, 89,239,108, 43,148, 60,113, 24,138, 7,193,211,184, - 50,239, 99, 53, 95,174,169,208, 36,100, 52,137,200, 82,103, 44, 48, 92, 16,105, 82, 33, 57,121,141,206, 42, 82,101, 27,147,184, - 2,169,115,231, 17, 57,239,254, 11,190,248,179,115, 33,112, 51, 23,227, 26, 40,140,249, 19, 82,102, 61, 69, 74,181, 11, 65,100, -162,158,100, 34,159, 82,114, 8,215,210,138,187, 88,106, 12, 13,223, 83,136,137,127, 16,185,123, 13,204, 8,240,249,179,142, 49, - 18,139,221,219,181,104,108,159,195, 81,144, 45,140,126, 45, 91,157,125,240,218,100, 87, 70,202,117, 47,202,146,159,155, 20,216, - 66,206,138, 36,142, 86, 74,174, 9,170,195,157, 81,121,130, 27, 73, 12,157,248,192,162,137, 67,252, 56, 63, 11,201,117, 33,114, -145, 44,114, 49, 60, 20,158, 17,154,210,141, 60,208, 19, 50,210,245, 45, 91,176, 8, 32, 33,181, 64, 33, 21,154, 85,131,190,235, - 81,141, 8,114, 32,148, 70,187, 90,161, 26,143, 33,148, 65,223,175,178,197, 65,178, 42,144,246,222, 68, 91,211,236,163, 83,114, -216, 17, 75,169,209, 91,199,185,182,100,117,171,106,195,227, 11,149, 71,230, 73, 80,145, 68,114,206,133,129,252,163, 9,128,163, -139, 33, 70, 50,141,250,155, 85,143,122, 84,160,239, 28,137,171,164,224, 67,102, 77, 45,201, 16, 4,103, 73, 33, 25,121, 76,238, - 24,134,147,130, 9,232, 75, 85,252,162,210,180, 96, 52,174, 97,173,227,220,239,132, 60,180,100,203, 83, 30,179,205,146, 53, 2, -142, 87, 4, 14,136,180,179, 79, 41, 70, 41,125,174,168,104,124, 45,165, 70,215,182,184, 56,253,128,190,235,112,255,241, 61,188, -127,123,130,233,230, 22,254,250,127, 60,194,139, 31, 95, 98,181,234,179,146, 85, 74,137,209, 88,175, 9,129, 18,167,217,103, 61, - 68,218,131, 59, 22, 18,165,223,101,181, 92, 98, 52,153, 64, 10,133,217,230, 12,182, 91,225,246,102,137,251, 31, 63,194,251,183, -103,164,214,103, 65,206,252,102,142, 8,133,103,223,191,196,209,253, 93,156,188,254, 0,128,166, 49, 55,151,183,240, 46,162,107, - 58, 98,224,247, 14, 93,219,163,109, 90,226, 23,104, 13,229, 28,138,138,170, 76, 83,148, 88,221, 46, 81, 86, 69, 22,242,213,149, -201,137,112, 33,112,140,175, 37,184, 72, 10,126,145, 2,112,150, 84,212,213,120, 12,215,117,216,222,223,195,116, 99,140,102, 62, -207, 69,100,111, 61, 74, 3,188,250,249, 23, 28, 60,252, 8, 7, 15,246, 97, 20, 0, 89, 34,184, 14, 87,167,231,120,250,171, 79, -241,203,203,115,248, 40,112,254,225, 61,130,107, 80,213, 21, 54, 15,238,163,172, 52, 94,126,247, 14,187,199, 71,232,155, 6,239, - 94, 60,131, 8, 43,132,232, 81, 77,183, 17,100,133,207,190,126,132,199, 95,126,142,179,151, 63, 96,180,185,143,239,255,241,111, -232,160, 64, 68, 12, 22,144,164, 61, 9, 66, 96,239,248, 35, 28,126,242, 5,222, 61,251, 1, 87, 31, 94,178, 40,199, 64, 42,141, -122,186,137,205,221,125,108,237,237, 67,232,146, 98, 94,111, 22,104, 22,115, 74,129, 27, 23,176, 93, 15,192, 99,185, 88,161,235, -122,116,109, 11, 4, 75,116, 49,190,212,133, 80,144, 90,195,176, 5,107, 60,157, 96, 52, 38,117,187, 41, 52,138,170,206,133,179, -179, 14,190,245,232,154,134,195, 51, 40,230,210,135, 0, 21,129,224, 60,164, 74, 35,216,196, 59,160,116, 65, 41, 53, 7,104, 36, - 81, 83,207,157,149,187, 51,125, 3,191,187,129, 5, 70, 50, 45,227,133, 96, 7,128,201,135,165,224, 93,177, 74,172,137, 4, 86, -201, 10,113,234,248, 53,239,221, 35, 43,129, 93,186,212,152, 93,225,172,205,163,244, 28,169,137, 33, 79,130,254, 46,250,220, 41, - 79, 60,230,203,147,236,175,252,115,112, 1,145, 14, 79,191,182,191, 78,118,178,192,150, 83,250, 93, 68, 38, 79, 38,157, 11,141, -230, 61, 95,232,150,167, 1,100, 17, 78,133, 20,145,232,104,146,225,108,128, 80,106, 45,130,150, 16,184,105,186,182, 30,128, 66, -169,114,138, 87, 7,195,170,115,216,151,199,236,153,166,207,108, 8, 40, 9,193,231, 9, 0, 31, 33,217,169,148,206,185,200, 23, - 53, 5,194, 68, 8,107,185,216,163,207,167,183, 14, 90, 83, 87, 78, 19,211,130,223, 83,133,200, 12,117,145, 2,119,148,202,238, -131,244, 25,248, 56,140,142,133, 76,169,156, 67, 30,121, 18, 61, 75,254,190,211, 94, 93,240, 24,156,118,253,224,240,146, 36,130, - 19,185,168, 74,221,174,227, 49,186,227, 17,188,179, 14, 8, 52,250,246,108,109, 91, 23, 94,130,239, 20,210,123, 36,203, 31,113, -225, 37, 11, 15, 83, 22, 72,166, 91, 98,232,202,105,161, 31, 50,240,102, 8,167, 73, 43, 16,153,113,221,137,217,160,185, 24, 77, - 22,211, 12,167, 17, 18, 2, 41,180, 70,241,247,193,120,228, 44,236, 84, 3,127, 37,144,192, 85, 72, 9,221,183, 45, 87,207, 58, -251, 56,219,229, 2,202, 84,144,154,201, 73, 34,162, 30,141,177, 92, 44,209,182, 61, 76, 81,102, 32,189,237,122,168,162, 32,132, -157,214,180, 71,144,146, 51,184, 35,103,236,154,252,210,100,145, 6,239, 65,162,143,232, 92,207,228, 56, 78,162,194,176,107, 87, -185,154, 86,140, 6,148, 52,118,207,153,232,220,189,229,221,124, 28,198,236,138, 70,192, 34,221,204, 16, 89,125, 14, 33, 32,194, -176, 11,215, 70,101,159,104, 26,249, 8,164, 75, 6,168, 71, 69, 70, 5,146,237,138, 42,250,201,116,196, 42, 77,112,124,170, 66, - 81,146,205, 66,105,218,151, 59, 99,209,119,150, 31, 4,112,226, 21,141,235, 72,109, 73, 66, 19, 24,112, 87, 82, 96,164, 42, 64, - 56,188,125,241, 26,199, 31,221,199,252,234, 18,167,239, 78,241,248,179, 39,176,125,139,147, 95,222,179,207,152,108,107, 82,130, - 68,136, 0,218,182, 69,215,244, 48,165, 97,124,162,231, 49,182, 68,219,119, 84,109,106, 5,215, 91, 72, 17, 80, 20, 37,180,210, -232,125,192,201,235,183,120,244,228, 99, 28,222, 63,194,247,127,248, 14, 93,215,193, 57,135,178,170, 81, 84, 21,218, 85,139,186, - 46,177,119,184,139,243, 15,231, 28,105,216,145, 85, 69, 43,132,166,163,189, 86,162,251, 97,240,128, 42, 37,208,183, 45,198,179, - 17,172,189,165,162, 81, 18, 94,247,240,222, 46,141,215, 82,117,206, 99,247,164, 75,144, 9, 32,196, 10,211,241,116, 12, 37, 34, -202, 81, 77, 80,164,166,207,150,149,241,108,134,111,127,247,175, 40,199, 19, 28,220,219, 71, 89, 26,132,224, 49, 42, 13,158,127, -251, 51,102, 91, 91,184,185,188, 65,215, 5, 92,157,158, 33,218, 6,211, 73,133,241,108,138,143,127,253, 27,188,251,249, 39,232, -106,132,186, 54,248,238,159,126, 7,219,220,144,154, 95, 2,155, 7, 15,177,125,252, 16,143, 62,123,132, 87,255,250,207,184,190, -186,193,126, 44,112,125,246,150,119,190,169, 83, 32, 14,250,254,253,143,112,239,233, 87,120,243,227,119,184, 62,123, 77,122,129, -241,152,253,254, 51, 76,183,246, 80,140,198,136, 82,225,242,236,134, 46,237,213, 18, 70, 43, 24,163,208, 53, 45,101,160, 91, 75, -144, 25,246, 44,247,158, 16,189, 36,222,145,128, 32, 8,148, 49, 5,166,155,155, 40,170, 17,202,170,164,105, 12, 79,205,156, 15, -112,182,199,252,150,236,141, 49,112,182,128,117,112,118,137,182,105,217,230,166,249,189,167,195,189, 89,181,196,123,119, 30, 82, -218, 12, 30,233,154,150, 69,144,228,118,232,186,150, 15,110,143,232,135,224, 21,193,150,209,144, 48,155,137,194, 38,239, 18,185, -214, 53, 48,169, 59,141,129, 2,103,210,128, 58, 9,145,172,237, 57, 43,124, 8, 29, 25,114,198, 19,201,114,152, 14,164,238,151, -226, 49,145,113,177, 90,203,204, 33, 23,217,214,199,194,152, 48,228, 78,164, 66, 33, 83,191,132,160,203, 90,136, 53, 27, 22, 93, - 14,129,111, 28,173,117,142, 45,246,193,211, 52, 44, 4,238, 34,211,126,153,127,126,169, 32,133,100, 91, 94,204,157,158,231,247, -150, 56,228,142,181, 10,116, 89,164,213,157,214, 50, 67, 95, 66,182,247,234, 53,117,250,208,236, 36, 94, 65,136,116,142,197, 53, -209,224, 0, 58, 26,160, 71,145, 27, 31,136,245,245, 30, 53, 35, 82, 41,152,178,204, 34,201, 44,116, 76, 29,168, 44,184,120, 41, - 96,123,230,171, 39,112,139,144,252,115, 11, 40, 61,100,207, 19, 95, 68,231, 85, 69,114, 18, 37,160,142, 86, 42,219, 91,147, 67, - 65, 10,192,246,221,192, 38,136, 64,136, 62, 67, 92,148,146,112,125,207,202,114,138, 2, 22, 8, 8, 8, 16,209, 35,101,240,144, - 16, 55, 2, 97,136, 53, 77,147, 78,154,236,232,204,206,144,140, 38,150,236,211, 31,124,236, 84, 96, 66, 8, 8,170,103, 51, 23, - 34, 5, 28,137, 72,192, 33,164,244, 63, 38,205,173, 23, 9,108,136, 24,248, 10,158,210,243, 82,227,150,206,193,152, 50,217,215, - 20,244, 58,237, 88,104,180,206,177,150, 70,163,111, 87, 16,202,162,168, 70, 80,198, 32,122,159, 61,173, 96,117, 39, 98, 68,223, -181,208,130, 4, 95,203,155, 57,191, 4, 60, 86,103,128, 64, 85, 21, 76,102, 98, 94, 57, 63, 48,105, 36, 81,148, 6,206, 7, 14, - 48,136, 57, 82, 53, 56, 82,249, 86,163,138,247,198, 68, 15,138, 38,100, 94,111, 8,128, 41, 20,251,216, 69,198,149, 6, 71,204, -121,219,211,151,102, 74, 3,219, 57, 72, 53,228,175,139,181, 49,122,224, 15, 43,219, 44,248,131, 83, 90,163, 46, 52,139,226,124, - 78, 28, 10,222,163, 40, 77,174, 56,201,222, 16, 1,209,161,111, 3,202, 42,117, 4, 36,140,211, 76, 41, 10, 33, 18, 1, 46, 6, - 86,125,151, 8, 33,162, 30,215,148,252, 22, 3, 95,208, 14,174,179,232,186, 30, 63,125,243, 61,238, 63,254, 8,251, 71, 19,252, -242,236, 21,182,118,119,241,213,159,127,129,179,147, 15,152,223,204, 89, 28,131,108,201,208, 90, 33, 50,246, 85, 42,133, 98,205, - 6,179,177, 53,205,107, 4,107, 29,130,243,104,154, 6,189, 53, 48, 90,226,234,236, 18, 49, 42, 60,250,228, 30, 46,207, 46,240, -234,217, 47,100, 99,100,139,152, 16, 2,111,127,121,141, 7,143, 63, 66, 89, 85, 88, 46, 87,144, 34, 98,126,179, 32,155, 88,239, - 16,110, 27, 24,163,184,115, 10, 57, 15,216,249, 6,166, 90, 96,107,127, 27, 74,179,200,101, 78,147,139,122, 92,163, 89,172, 16, -188,135,239, 57, 67,192, 59, 8,153, 70,155, 67,117,106,202, 10,245,168,100, 15, 45, 49,248,151,139, 14, 82, 6,212,147, 49, 46, - 46,174,112,121,126,129, 79,126,253, 91,140,167, 35,148,165, 70,211, 10, 92,159,159,227,236,253, 5,158,124,249, 20,207,126,250, -128,147,215, 39,240,125,131,157,221, 41,170,186,194,222,131, 71, 8,206,195, 71, 96,119,127, 11,207,190,249, 22, 55,103, 39, 52, -222,147, 2, 7, 15,159, 96,118,248, 9, 30,125,124,132,239,254,246,255,198,135, 55,175,240,213,255,240, 63,227,167,223,253, 87, -128,213,253, 66,106,182,177, 4, 28, 61,120,138,227,167, 95,225,151,239,254, 21, 23,239, 95,163,172, 42, 76, 54, 54, 80,141, 39, -168, 70, 99,140, 55,182,160,203, 10,203, 69,139,249,205, 21,150,243, 37, 34, 4,170, 82, 67, 10,160, 89,182,104,150,215,132,187, -100,206, 67,228,164, 49,178, 94, 37, 40,136, 66, 81,141, 48,154,204,136,221, 94, 85,128,160,195,198, 5, 1,219, 81, 7,219, 44, - 87,104, 87, 43,172,150, 43,120,103, 9,253,234,108, 22, 60,201, 68,225,140, 21,130, 50,168,106,147, 35, 39,243,247,152,157, 49, -242, 14, 12, 37,117, 80,150, 19,174,148, 78,217,210,145,113,155, 2,202, 80, 1, 26,185,147, 81, 82,194, 7,199, 99, 69, 12,105, -111,121, 43, 38,216, 33,225, 73, 41,157,188, 80, 89,157,158,210, 30, 61, 81,227,228, 48,130, 79,107, 45,234,142, 7,171, 27,161, -230, 19, 86, 58,193,172,100, 78,151, 20, 89,152,148, 70,181, 46,179,199,227, 90, 18, 88, 12, 1, 85, 89,101, 75, 85,234,150, 98, -230,122,243,197,203,204,138,224, 61,156,103, 71, 76, 74,128, 75,145,176,130,166, 24,222,246,156,120, 38, 73,139, 16,147,159,222, -103,189, 2, 69,157,174,169,164,249,207, 17,156, 17, 63, 16,222, 6,178,102, 86,133,179,245,113,157, 70,135,100,151, 98,215,140, -128,128, 34,248,251, 64,247, 12,180,226,136,146,236,109, 74,129,214,155, 82, 83, 35, 35, 40, 63, 36, 5,244, 36, 39,130,148,180, -218, 75, 94,255,212,171, 41,182,130,229, 44,119,182,188,185, 52,121, 13,195,218, 65, 51,199,222, 20, 58, 95,236,137,221, 47,147, -157,143,197,213, 82, 1,222,122, 40, 25, 33,160,178,179, 9, 89, 36,137,129,252, 7,186, 36,109,144,128,167,188, 13,199, 12,254, -168, 98, 94,105,106,105,184, 72, 50,195,103,198,235,134,100,234, 79, 76,248,180,246,137, 49, 34, 56,186,192,101, 66,231,230, 33, - 66,204,107,170,196,247,207,142,139,212,245, 43,126,206,179,176, 47, 50,228, 39,174,129,211, 84,158, 10,136, 20,222,195, 69,136, - 38,118,176,228, 47, 27, 25,223,233,125,132,140,228,137,173,148,134,245,128, 46, 43, 4,230, 69,135, 72,213, 90,187,106, 49, 50, - 21,164, 50,136,130,246, 42,214, 54,240, 94,210,195, 1,129,182, 35, 40,127, 4,189,120,101, 69,118, 26,107, 29, 87,221,142,120, -190,102, 80,167,199, 96,201,211,206,241,126, 16,148, 81, 29, 50,122,146,141,255, 38,137, 37, 56, 96, 65, 9, 98,185,131, 64, 12, - 89,101, 24,104, 55, 71,127,118, 24, 34, 93,185,211, 15,150,232,109, 62,120, 72,198, 73,166,113,189,229,209, 61,217,226,168, 26, -214, 70,177,199,154,246, 43, 33,103, 81,243,232, 37, 14,135,130,247, 97,240,230, 27,137,209,120, 4, 83,106, 74, 35,242, 36,192, -243, 62,162, 44,201, 86,209,181,224,157, 33, 41,228, 99,140, 56,125,119,130,221,195, 35, 60,252,248, 1, 46,207, 46,241,211,191, -189,192,241,131, 67, 76, 55,166,120,251,234, 29,143,136, 56,147, 93, 72,196,160, 88,173,108,185,232, 32, 37, 60, 21, 42,134,113, -145, 6,171,206,178,117,175,131,209, 52,117,152, 95, 95,226,230,122, 11,159,255,230,115,216,222,226,226,244,156, 69,104, 52,234, -236, 59,139,235,203,107, 28,222, 63, 66,215,117,240,206,162,107, 91,108,223,219,197,205,229,156,127,102,160,107, 91, 56, 71, 32, - 21,197,159,241,252,230, 6,171, 69,203,251, 69,143,190,181,136,158,246,117,109,211, 17,247, 93, 42, 88,171, 96,138,146, 57,229, - 28, 41,107, 72,113,187,119,111,135,139,166, 2, 69,161,178, 7,117,113,187,192,100,115,134,127,251,167, 63, 98,231,224, 0, 59, -251, 59,216,216,172, 96, 93,196,106, 62,199, 79,223,252,136, 79,191,254, 20,167,239, 47,120, 92,212, 97, 54, 51, 24, 79,198, 24, - 77,102,152,108,110,227,197,247, 63, 99,239,112, 15,190, 91,224,252,221, 11,120,215,161, 28, 79,112,239,227, 79,177,125,252, 17, - 84, 89,227,159,254,247,255,130,235,211, 95,112,244,228,207, 48,191,248,128,213,252, 42,131, 73,210,129,126,252,201,231,184,255, -244, 75,252,244,251,127,128,109,111,177,185,179,131,201,198, 38, 76, 89,195, 84, 35,140,102, 27, 80, 74,225,246,250, 6,151,103, - 87, 88,173,104,140,173, 24, 90,209,183, 43,244,171, 57,156,235,216,231, 92,242, 20, 67, 32, 66,113, 26, 33,185, 4, 38,179, 45, - 76, 54, 54,161,139,146, 46,127,126,159,173,165,245,200,114,190,192,114,126,141,102,181,204,182,169,236,115,102,155,153, 96, 86, -117, 58,152,148, 22, 28, 56,194, 34,199,170, 98,113, 23, 80, 20, 5,218,182, 67,219,246,212,149,135,144,195, 72,214,119,190,105, - 34, 38,121, 84,159,160,214, 42,163, 67,233,208,166, 49, 61,237,200,169, 27,241,185,251, 13,140, 75, 13, 49, 64, 75, 13, 31, 1, -111, 45,139,201, 34, 36, 6, 10, 27, 97, 85,185,168, 15, 49,239, 74,215,173, 70, 82,146,126, 36, 41,243, 7,210, 92,204,187,115, -235,124,158, 28,120,102,116,211,138,158, 67, 96,188, 35, 82, 27,159, 93,138, 39, 75,217,206,149,226, 96,185,227,115, 12,226, 73, - 16, 25,242,135,179,162, 94, 25,102,202, 71, 22,126,177,127,221,245, 44,208, 26,172, 79,196,100, 71,142,245, 76,227,247,116,193, - 36,145,113, 2,113,101, 38, 0, 51, 51,242, 78,251, 14,198,151, 67,162,214,206,255, 20,178,149,246,235, 73, 67,161,197,160, 51, - 80, 58, 21, 9,116, 14,230,120, 93, 22,186,165, 84,203,212,100,209, 10,128, 26, 65,145, 83,218, 36, 11, 98, 11,132, 53, 37,123, -226,139, 36,178, 95, 82,122, 15, 9,159, 41,152,199,243,231, 32,224, 29,232, 12,207, 32, 32,100, 7,148, 15, 46, 59, 57,232,169, -185,235,160,128, 20,185,200, 35,254, 72,210, 78, 81, 39,158,246,232,164,211, 42, 56,234,155, 51,229,249,254, 32, 61,130, 97,122, -167,128,133,205, 93,116,188,147, 83, 34, 51,163, 63,229,212, 39,126,129,200,239, 77,200,223, 93,210, 55,104,222,205, 75,214,174, - 12,223,157,200,132,217, 4, 71,211,224, 89,189, 79, 35,167,100,247, 98,190,110,116,116,177,235,178,134, 84, 42, 99, 81, 83,202, - 16,124,128, 92,181, 40,170, 34,251, 33, 5,143,166,132, 0, 66, 20, 40,100,193, 20, 39,201,221,125,207,227, 33,133,162,160, 14, - 22,140,220,115,142,170,174,192,187,231, 52,170, 19, 34,162,107,237, 90,136, 2,141,179,156, 5, 76,169,184, 35, 87, 3,232, 70, - 96, 16,197,113,222,185, 41, 12,161, 44,178,234, 62,162, 44, 73,225, 77, 54,154,152, 99, 84,165,162, 23,167,239, 60,202,146, 58, -224,224, 99, 22,232, 8,118, 9, 72,165, 80,214, 37,217,221, 92, 92,143,184,205, 73,112,169, 90, 53,102, 8,156, 17, 66,162,170, - 13,199, 84, 18, 29,111,181,108,208,181,100, 37,211,172, 14, 77,197, 5,132,198,114, 62, 71, 8, 1,251,135,123,184,189,190,196, -201,235,183,152,110,110,224,233,215, 79,113,117,118,129,211,147, 51, 56,107,209, 54,109,126, 64, 35,232, 97, 15,158,211,174, 66, - 98,218,211, 83, 81, 86, 5,116,160,221,104,211,180,168,170, 10,245,184,192,213,233, 41, 54, 54, 31,225,171,191,248, 26,175,126, -122,142, 23, 63,189,162,207,171, 42,208,119, 61,150,243, 57,220,222, 14,238, 63,186,135,247,111, 78, 16,131,199,104, 58,198,104, - 90,163,109,105,186, 50,153, 77,208,247,150, 0, 28,145, 34, 28,131,119,104, 86, 45,102, 91,179,204, 40,183,182, 71, 81,149,131, -103, 55, 6,218, 39,177,224, 37,143,150, 66, 68, 57, 42,113,244,224, 16, 90, 11, 78,132, 51,184, 60,189, 6,221, 41, 18,191,252, -248, 28, 82, 41, 60,253,245, 23, 56,186,191,131,162,212, 88,126, 56,135,235, 59,104,173,112,239,241, 61,188,248,249, 20,243,171, - 83, 40,225,115,116,237,214,209, 49,174,206, 46,161, 53, 80, 21,192,183,127,252,158,197, 70, 83, 60,254,242,215,216, 57, 56,192, -237, 66,224,245,239,255, 47, 44,175,222,194, 84, 19,220,127,250, 41,254,240, 95,255, 75,166,165,165,124,235,251,159,254, 26,199, -159,124,134,103,127,252, 29,162,239, 48,221,220,198,230,222, 30,132, 42, 32,149,193,120, 54,131,247, 1,151,167,167,184,190,188, -197,114,213,211,174, 58, 68,184,126,137,198,245,100,165, 98,225,146,179,150,187, 7, 64,177,184,108, 52, 25,163, 40, 43,148,117, -141,233,230, 6,237,252,140, 65,215,210, 97,237,251, 22,205,106,137,249,213, 53,218,102, 65, 43, 18,107, 9,100,164,147,118,164, - 32,119, 70, 81,102, 33, 87, 58,176,104, 52,108, 32, 4, 51,224, 99, 96,228, 51, 3,108, 0,116,109, 15,107,195, 90,126, 55,238, - 80,207,146,165, 71,107,157,163, 82, 83,113,156,118,211, 96, 56, 13, 97, 94,193,217, 10,158,247,133, 34,143,174,181,210,112, 41, -143, 90, 8, 0, 84,188,166, 76,132,129, 22,135,124,161, 43,222,181, 39,220,170,100,113, 87,140, 84,120, 17,199, 28,252,217,115, -184, 6, 59, 74, 72,137, 61,136,100,135,221, 41, 29,222,105,178,153,199,238,236,225,167,151,219,231,142, 62,217, 95,243, 46, 59, -195,191,215,132,193,220,169, 57,182,195,145, 45,174,207, 5,135,207, 68, 78, 49,172, 27, 89,116,151, 84,249,116, 97,123, 70,243, - 38, 34, 40, 77, 37,227, 26,150,150,252,216, 22, 62,144, 74,156,214, 17, 97,136,125, 69, 18, 11,167,220,111, 90,167,138,236,215, -143, 48,122, 56,199, 2,187,143,180, 1,199, 35,203, 76,175,139,105,125, 38, 21, 32,124,234, 69,121,205,192, 13,136,210, 16, 74, - 66,229,192,159,200,154, 38,159, 97, 55, 80,131,182,130,100, 25,130,109,207, 92,204, 33,228,201,130, 20,128,139,241, 79, 20,236, -130, 84,243, 18,204,125,119,100, 57, 68,224,120,121, 5,231, 44, 23, 28,128,201,110, 18, 3, 33,117,206, 15, 49, 12,181,145,153, -227, 32, 0,153, 64, 64,244, 89,101, 81,157, 49, 25,243, 45, 5,152, 57, 34,243,133,157, 98,105,165,144, 60,221,137,185,128, 34, - 37,189,203,162, 71, 33, 4,156,119,220, 24, 15,197,229,157, 96, 23, 33,115, 76,175,238,219, 30,138, 5, 27, 66, 72, 88, 86,100, -251, 64, 99,179, 16, 41,245,170,132,132, 52, 37,117, 3,145, 66, 76,162,144,240, 44, 62, 8,193,160,172, 10,172, 22, 43, 40,182, -154, 45,110,151,208, 69,193,127,153, 98,254, 47, 77, 2,172,245, 89,221, 71,176,170,128,182,233,121,164, 77,123,231, 84,142, 80, - 87, 73,169, 93, 33, 50,118, 22, 33, 39,251, 8,250, 62,160, 84,100, 47, 32, 21, 28,100, 39, 0,171,105,101,102,110,167, 42, 71, - 41,201,140,101,218,127, 11, 31,179,224, 36,240,200, 40,137, 95, 82,227, 65,236, 97,197,176, 21,170,226,124,136,232,173,131,237, - 44, 89,102,248, 50, 46, 42, 82, 36,107,222,249,167, 21, 31,113,227, 29,218,166,203,135,148,115, 30,101, 89,146, 74, 28, 49,127, -153,137,215, 76,118, 85,202, 74,254,112,242, 1,187,251,187, 40,171, 10, 55,151, 55,255,141,171, 55,253,177,236, 56,211,252,158, -136, 56,235, 93,115,207,202,202,218,201, 98, 21,119,145, 90, 90,234,150,166,183,105, 55,166, 1, 3,246, 7,255, 63,250, 99,108, - 3,254, 98, 24,240, 96, 96,140,167, 61,221,211,238, 77, 82,107, 33,197, 18, 89,100,237, 91,238,121,247,179,196,230, 15,239, 27, -113,110, 89,128, 32,138, 44,102,230,205,123, 79,196,187, 60,207,239,193,119, 15, 22,216,187,186,143,219,119,111,225,187, 63,124, -199,209,175,107,248, 74,222,105, 55,117, 67,254,127,198,241, 66, 8,164, 65,168,199, 43,130, 96,103, 20, 41, 48,185,152,161, 63, - 40,112,237,246, 77, 24,227,113,242,230, 28, 16,136,118,188,211, 55, 71,120,231,222, 29,204, 38,147, 16,167,192,106, 89, 21,199, -157,105,170,232,189, 98, 21,181,247, 30,245,106,133,157,189, 3,194,161, 22, 53,230, 19, 66,199, 86,171,134,220, 13, 25,225, 99, -179, 60,163, 66, 72, 9,244, 6, 61, 8, 41,113,239,227,123, 24,140, 74, 52,181,198,214,246,128, 67,118,128,233,197, 20, 27, 59, -219,248,250,183, 47,241,163, 63,251, 49,118, 14,246,209, 27, 20,168,150, 21,102, 23,151,176,214,225,227, 31,125,140,197,162,133, -209, 6,203,249, 28,112, 30,109, 99,209,223,232,163,174, 13, 94, 61,125,129, 27, 55,182,240,252,225, 67,212,203, 37,198, 59, 87, -112,235,222,187,216,220, 26,225, 98, 42,240,244,193,175,176,186,120, 3, 41, 4,110,127,242, 99, 60,255,195,151,176,166, 37,244, -169,167, 81,219,181,247, 62,194,141,251, 31,224,197, 31,190,128,146, 30,155, 87,174, 96,184,181, 67,130, 35,149, 32, 47,251, 88, -205,103,152, 93, 94, 98, 49,175,209,180,244, 96,215,213, 10,158, 61,182, 73,194, 30,111,169, 32,189,224, 3,220, 96, 48,218, 68, - 86,246,184, 91, 72, 81, 14,135,108,247, 73, 80,215, 6,122, 86,147, 38,102, 85,161,105, 42,232,166, 37,247, 1,191,215,144,148, -186, 21, 16,147,225,179,110, 57,188,133, 14, 82,178,203, 4, 68,175, 88,251,243, 73, 34,162,115,132,124,203, 10,109, 75,187, 72, - 99,153,228,103, 45, 43,226, 93,228,147, 59,238, 98,211, 44,141,100, 46,197,151, 8,133,172,116,162, 84, 90,211,216,152,205, 16, -166, 0, 70,107,206,108,183, 81, 72, 22, 26,136,208,157, 82,175, 99,163, 15, 57,100,117, 43, 37, 98, 83, 65,142,148,148,145,181, -235,224, 24, 48,197,142,178, 43,140,214,188,183,117, 29,251,157, 99,179, 20, 59, 48, 56,216,141,245, 66, 30, 82, 40, 88, 71,226, - 61,218, 73,187,136,245, 21, 44,146, 10, 30,115, 26,195,202,152, 80, 23, 70,196,206, 27, 34, 5, 58, 27,187,229,128,207, 13, 22, - 68,203, 66,198, 64,224, 51,166, 75,200, 19,252,251,114,156,116, 22, 34,181,105,103,237,215, 20,223,230,173, 11, 33, 20, 39, 65, -189,110, 12,137,225, 18,149,197,179, 66,172,161,178, 45,175, 75,211,148,166,127,225, 53, 72, 25,236,148,107,223,151, 11,242, 96, -219, 10, 86,227, 16, 98,101, 45,193,197,242, 44, 69,211,208, 58,133, 40,146, 34,158, 87, 81,180,236,124, 92, 63,133, 4, 56,203, - 2,100,185, 46,246, 11,224, 35,103, 67, 8, 48,140, 15, 90, 41, 42,220, 32, 82,178, 52,243, 94, 61, 20,114,130,155,168,144,154, - 25, 45,199,236,227,239,252,249,136,211, 94, 33, 68,116,180,144, 45,218,162,213,154,137,143,158, 5,180, 33, 38,152,184, 29, 97, - 58, 22, 86, 73, 34, 94,206,157,216, 83,112, 62, 65,152,158,120,248,183,248, 46, 62, 40, 30, 41, 1,135, 58,117, 47, 4,234,170, -137,161, 42,212, 85, 10, 56,163,153, 21, 77,213,210,114,177, 64,217, 7, 20,199, 14,166, 60, 42,150, 82,146,111,214,203, 40,106, -112,108,129, 18, 74,195, 57,131,182,182, 4,253,176, 52,174,234,245, 83, 88,215,249, 18, 85,154, 64, 88,199,214, 42, 17,109, 36, - 36, 54,145,104,219,182,195, 49, 66, 66, 42, 11,107, 13,242, 44,137,227,247, 52, 75, 72,172, 39,120,223,147, 42,180,173,225, 93, - 11,121, 70,137,167, 30, 0, 12,140,224,243, 68, 80,202,178,132,118,239, 89, 18,225, 57,142, 83,215,232,162,225,104, 89, 86,144, -135,144,145, 0,186, 80, 74,194, 41, 9, 41,211, 88,221, 11, 33,145, 23, 52, 82,146, 0,145,234,188,135,110, 45,172, 49,140,143, - 37,173, 2, 5,148, 36,232,245, 89,248,197,190,116,170,218,200, 3,106, 12, 21, 83,240, 22,175,158,190,196,254,225, 30,182,247, -182,113,113,122,134,151,143,159, 66,165, 5,110,223,187,139,179, 55,175,241,236,241,139, 72, 33, 50,198,162,169, 91,222,163, 91, -180, 53, 21, 88, 66, 10,152,150, 98, 55,203, 94, 17, 63, 68, 69, 47, 71,154, 37,128,112,200,138, 18,211,139, 11,220,124,247, 22, - 84,146, 98, 54, 89, 0,222, 98, 49,155,195, 57,224,252,108,130,195,155,135,120,241,248, 57, 22,243, 21,122,131, 18,243,233, 34, - 34,117,219,150, 82,240,106, 75,239, 69, 94,100,112,166,133,243, 18,195,113,129,201,197,156,191, 23,231, 44,199, 0, 4,122,239, -133, 32,133,109, 94,100,184,118,235, 26,198,219,155,104,235, 26,101,127,128,162,204, 96,116,139,186,106,201,133, 33, 5,174,221, -186,134,209,214, 22,242, 50, 35, 23,193,241, 41,140,241,104,170, 10,131,241,109,188,124,113,142, 55,207, 95, 64, 55, 21,117, 51, - 82, 97,188,179,141,199,223, 60,197,230, 70,134,201,201, 27,204, 47,207,177,127,253, 58,110,221,123, 15,194, 53,104,108,129,111, - 31,124,137,122,250, 18, 66, 8,244,198,251, 40,122,125,124,247,226,219,184, 6, 18, 82,225,218,123,159,224,238,167,159,226,241, -151,191, 6, 0, 92,185,113, 27,229, 96,128,106,213,192, 11,129,188,200,177,184, 60,193,124,186,192,116,178,130, 23, 18,206,104, - 52, 77,197,170,126,135, 68,121,104,175,144,164, 34,142,135, 71, 91, 59, 40,202, 30,146,188, 7, 15,133,162,223, 67,154,151,104, - 27,141,186, 54, 48,139, 58,218,118,172, 53,168, 86, 21,140,110,249, 0,118, 81,120, 20,216, 85,244, 44,122,246,183,211,129,170, - 91,222,239,242,239, 63, 16,253,178, 92,118, 59, 60,136, 8,101, 82, 82,178, 0,182,129,118, 38,226, 48, 73,196,229,226, 90, 43, - 20, 4,193, 74, 21,138,216,208,233,136,181, 81, 52, 93, 20, 84, 12,132,112, 36,218,187,187,104,113,242,140,215,140,132, 57, 65, -140,247,132,197,179, 93,164, 43,171,217,185,107,148,107, 93, 49,229, 40, 20, 93,183, 25, 71,193,116,120,251,112,254,160, 99,155, -135,160,145,160,196,118, 14,111, 69,145, 38,172,130,247, 28, 35,234,227, 56, 21, 17,158,133,117,250, 87,100,219, 39,124,177, 16, -219,194,217, 22,214, 52, 29,131, 29, 93,154, 28,209, 40, 69, 12,201,161, 2, 42,139, 42,255,112, 73,202, 88,188,136, 24,225, 44, - 61, 53, 59, 20, 51,205,144, 22,246,247,203, 8, 79,177,209,190, 22,118,246,142,237,104,225,194, 14,247, 4, 17, 44,147, 40,250, - 13,207, 0, 77, 73, 12,114,230,138, 68,177,108,162,232, 44,224, 64, 19, 23,126, 63,142, 97, 92,144, 12, 68,146,112,130, 83,222, -132,100,253, 83, 23,217,170, 50,201,168, 86,254, 12,121, 7, 47, 37, 44, 58, 75, 97,154, 42, 52,181,101,110, 59, 56,103,158,226, - 83,157,227,169,141, 84,252, 59, 0,148, 32,198, 9,216, 70, 45, 84, 22,243, 6, 98,230, 7,175, 60,188, 23,240, 74,112,178, 90, -135, 47, 22,204,155, 8,152, 92,163, 27,184,176,198,145,226, 45,124,113, 40, 32, 73, 56,137, 40, 0,246,126,253,107, 98,141, 41, -192, 69, 3,115,232,201,101, 2,218,255, 7,174, 0, 55,111,214, 58,168,255,238,227, 59, 63,239,178,208, 73,120, 99,152, 8, 21, - 30,164,182,165,125,170,209,134,121,210, 33,120, 65,160,213,186, 19,195, 40,178, 44,101,121,142,162,223, 7, 98, 76,169, 92,179, -163,177,133,198, 24,228,101, 22,253,135,158, 61,148, 34,170, 10, 59,175,159,224,139, 90,188, 69, 40,242,232, 68,242,244, 11, 23, -107,213,164, 20, 96,187, 73, 96,183, 75,174,216,193, 35,254,142, 91, 44,214,194, 28,194,195, 29,254,126,160,177, 5,192, 5, 89, -227, 36,131, 60, 18,142,139,164,192,129,176, 23, 11,194, 9,176,122,222, 59,135,186, 38,161, 89,181,106,216,207,239,226,247, 15, -127, 38,178,208,249,225, 12,104,217, 36, 77, 57, 11,185,203,236, 85, 74, 96, 49, 95,192, 67, 98,231,202, 46,234,213, 10,243,233, - 4,199, 47,143, 48,218,218,193,245, 91, 7, 56, 61, 58,129,110, 27, 34,144, 89,170,102, 45, 7,212,232, 86,195,106, 98,172,143, -198,253,232,115, 15,221, 74, 96, 51,215, 28,128,242,252,209, 11, 28, 92, 63, 32,141, 65,211, 96, 57,159,193, 90,129,225,168,143, -254,112,132, 52, 21,104,106,141,141,173, 1, 38,231, 19, 36, 89,129,249,228,156,119,180, 29,167, 64, 74,170,128, 7,227, 13, 12, -134, 61,172,230, 75,232,182,197,173,119,174,227,232,197,107, 92,158,207, 99,210, 91, 86,228, 72, 18,129,241,230, 24,109,221,224, -131,207,238,163,109, 61,137,228,242, 12,214,106,204, 47,151,112,206,160, 55, 32, 72,204,198,238, 54,154,214, 35, 77, 8, 14,244, -229,191,254, 14,155, 59,219,232, 13,250,152,205, 26, 92,158, 93,224,245,227, 71,132, 68,174, 91, 92,191,251, 46, 78,143, 46,144, - 39, 22,189,204,226,201, 31,254,128,107,119,239,225,206,251,119,177,154, 76, 32,139, 13, 60,127,252, 26,171,179,167,144, 32, 32, -202,189, 31,253, 12, 79,126,247, 11,180,245, 50,138, 41,223,249,228, 71,184,247,249,103,120,246,224, 11, 40,165,176,123,120, 13, -121,175,143,229,124,201, 12,135, 6,243,139, 83, 76,207, 47, 49,155, 46, 81, 55, 6,109, 85,197,108,113,103, 26,250, 12,242,251, -156,102, 57,134, 27, 27, 24,109,108,160,236,143, 72, 16, 39, 83,100,101, 15, 66, 16, 66,121,185,172,176, 90,172, 80, 87, 21,146, - 68, 98,181, 92,162,173,170, 72, 39,243,188, 59, 14, 66,195, 36, 80,217,120,244, 27, 49,175,146,194,149, 28, 83,195,194,161, 27, - 88,232,193,218,149,114,232,138, 99,177,207,106, 89,113, 2,162,140,121,225, 97, 12,166,216,195, 29,158, 87,143,110,135, 74, 86, - 78,217, 89,177,162,114,157,189,216,108, 65, 90,207,172,118,188,211, 50,214, 67, 72, 58,163,224, 29,100, 12,246,176,112,206,112, - 34, 29, 56,225,138,185, 12,232,136,107, 50, 38, 98,137,181, 24, 86,196,162, 37,194,170, 44,117,111,193,130,228, 29, 98,242,156, - 84, 10,137,234, 40,120,116, 94,209, 25,170, 56,136,133, 28, 33,221, 24, 62, 48,250,169, 8, 48, 72, 84,202,158,127,196,125,185, -115, 13,253,215,191,157,244,230,187, 96,238,232,185,239,254,185,143,202,113,242,163,103, 17, 50, 20,184, 14, 33, 85,204,152,110, - 53, 26,214, 2, 65, 11, 17,206,187, 48, 18, 14, 13,150, 16, 10, 9,159, 11,129,247, 30, 2,181,162,176,142,221, 63,235,226,184, -184, 71, 86, 18,150,225, 88, 97, 93, 41, 24, 62, 70,127,173,162,181, 45, 0,199, 44,139,251,194,170, 34,124, 78,163,194,156, 11, - 75,201,163,111,199, 7,204, 58, 24,140,175, 59,242,167,115,250, 94,244,174,139, 0,114,233,112,192,221,207,148, 32, 77, 20, 79, - 55, 85, 44,226,194,101,179, 78,117,147,129,164,232,232,251,208,159,243, 44, 66,237,182, 45, 2,235,105,187, 29, 74, 55,128, 93, -169,224,246,107, 86, 78,185,166,127, 8, 96, 28,177, 70,210,235,108,214,241,125, 8, 22, 78,239,161,254,230,243,123, 63,119, 14, - 16,124,185, 82, 88, 67,120, 81, 34,218,202,172,115,220, 93, 26, 40,153,176,165,139,195,238,153,209,174,141, 67,145, 43, 52,181, -198,120,107, 27,123, 87,247,161, 91,141,186,170, 24,172,224, 98,119,238,128,152,208, 22, 66, 8, 66,213,155,102, 73,204, 56, 79, - 18,197,190,110,242, 29,210, 78,221, 71, 49,154,148,212, 69, 19, 28, 71,118,126, 82,116, 2, 11,231,232,123,133, 3, 41,116,172, -214, 56,126, 64, 68,164, 69, 57, 30,213,123,142,169, 12, 29,134,179, 62,142,123,214, 67, 39,164,146,209,194, 17, 46,113,240,142, -196,104, 11,221,104, 26,123,183, 38,230,173, 19,241, 45,137,235,141,162,200,248,161,167,175, 91,148, 57, 71,205,242,229,238, 56, -162, 86,144,234, 51, 77, 85, 20, 91,172, 22, 43, 84,203, 26, 59, 87,246,224,140,198,106,177,192,197,233, 41,154,198,225,163,239, -127, 4,107, 53, 86,139, 85,247, 51,146,247,133, 80,178, 82,144,221,139, 49,134,180, 30,161, 98,167,170, 26, 76, 47, 23,104,170, - 10,144, 25,122,165,196,139,167, 47,113,112,227, 26,122,253, 18,147,179,115, 90, 45,100, 5,140, 54,216,189,178,143,197,116,138, -221, 43, 59,152, 93, 78, 96,140,160, 12,238, 86, 71, 27,144, 49, 97,215,234,145, 21, 61,236,236,109, 98,114, 62, 69,181, 92,225, -250,237,171,120,245,236, 21, 22,179, 5,211,166,232, 18,241,222, 99,123,119, 19, 91, 59, 99,228,101, 9, 15, 79,234,110,239, 80, - 45, 87,104, 27,210, 74,204, 39, 83,140, 54,199,112, 62,193, 96, 88, 64,183, 53,190,250,197, 23, 88, 45, 87, 24,109,140, 0,149, -227,226,244, 18, 47,190,251, 22,213,124,134,106, 89, 99,107,111, 31,101, 47,199,106,213, 96,103, 51,195,171, 39,143,113,120,247, - 30,246,174,236,224,248,249, 51,244,183, 15,112,121,122,137,201,217, 57,164,157,193, 89,141,131,119, 63,130,109, 91,156, 60,255, - 22,240, 30,195,241, 22,222,249,228,135,184,253,193,251,120,250,224,247, 40,251,125,236, 28, 92,133,115, 36,220,115,166, 69,189, -156, 99,122,118,130,203,179,115, 44, 87, 6, 77,107,225,116, 75,227,108,103, 96, 77, 27,227, 73,243,162,192,112,188,129,254,112, -140,178, 63,128, 80,212,197,120, 86,191, 11,198,186, 86,171, 58, 70,125, 54, 77,139,106, 73, 34,184,182,105, 33, 19, 5,168, 52, -218,153,200, 11,108, 33,147, 16,184, 33,184,123,113,112,158, 5, 87,150, 70,232, 49,249, 47, 77,249,210,162, 75,126, 48, 28,112, -103, 41,163,200,149,242, 13,124,116,109, 68,215, 8,119,161,129,239, 79,194,174,128, 17, 37, 17,149,231,238, 56,116, 92,186,109, -105, 95, 25,237,143,170, 99,189, 59,207, 59, 79, 5,169,114, 62, 68,109,188,144, 98, 39, 99,130,165, 77, 70,171,103,188, 4,189, -131, 74, 56, 87, 60,248,158,101,200,187,150,220,109,170,181,172,190,198,229, 0, 0, 32, 0, 73, 68, 65, 84,130,200, 69,219, 44, - 47, 94,249,245,228,113,191, 29,138, 36, 64, 69,192,147,247,228,151,175,235,154, 95, 35,249,163, 29,191, 22,107, 53, 18,149, 34, -205, 10, 90, 3,176,242,220,152, 6,186, 93,145, 86,136,153,222, 42,234,111,186, 8, 89,110,159, 34,126, 54,140,123, 37,127, 54, -210, 44, 67,154,102,111, 1, 91,162,163,151, 69,131,148,232,215,240,153,199,174, 36, 15,116, 91, 26,201,103, 84, 78,226, 88, 46, -244, 67,204,104, 0,134, 37,105, 26,197,196,105,146,118,196,180, 53,139, 21,233,205, 72, 81,239, 57, 46,184, 43,134,232,126, 9, - 5,149,224, 98, 47,224,126,195,229,253, 54,217,111, 77, 40,103, 76, 92,221, 80, 50, 27,243, 9, 44,211, 67, 89,215, 69,157,172, -103, 46,188, 99, 4,111,232,188, 93,188,235,168,169, 73, 25,172,163,162,112,149,196,162, 29, 80, 77, 37, 50,218, 12,131,242, 60, -176,225, 3,181, 47, 92,240,225,247, 64,192, 28, 78,239, 20, 62, 70,184,146,194, 95,118, 65, 99,113, 13,229,209,173,204, 69,215, -193,179,109, 77,188,197,192, 23,111, 33,132,213,223,124,126,255,231,209,182, 16,186,237,240,129, 89, 99,178,211,159,233,124,117, -214, 1,131,113, 31,166, 53, 12,165, 80, 8,233,130, 2, 30,203,197, 2,179,233, 18,229, 96,136,253,195, 43,176,124,224,132,138, - 48,196,249, 81,236,159,139, 66,157, 32,142, 8, 59,139, 16, 63, 25, 46,227,132,149,213, 97, 60,187,230,106,141, 54, 57,201,151, -185,209,102, 45, 76,190,235, 10, 2, 39, 55, 88,228,156,113, 93, 56,138,113,209,150, 17,130, 36, 66,197, 25,118, 25,132,104, 37, -225, 68, 0, 37, 80,183, 78,222,207,166,106, 57, 31,222,172, 1, 46,168,232, 8, 31,232, 80,105,173,255, 76, 68,205,163,241, 34, - 29,172, 9,172,161, 17,127, 0, 33,132,170, 63, 88, 53,156,117, 48,186,193,229,249, 4,219,251,251,232, 15, 10,172,230, 75,212, -213, 2,199,175, 79,113,112,227, 38,174, 94,223,199,249,241,121, 12, 82, 8,149,127,150, 37,196,178,214, 52, 69, 0,128,186,226, -157,243, 98,197,163, 59, 58,136, 54,119,118, 49,189, 56,199,217,201, 37,118, 15,246, 48, 24,245,112,118,116, 2,231, 37,250,131, - 30,154,198, 96,107,103,136, 44, 47,176,156,205,161, 53,160,155, 21,116, 75, 89,244,180,163, 83, 48,218,146,170, 93,166,216, 61, -216, 65,189,170,161,155, 26, 87,174,237,225,197,163, 23, 56, 59, 57,143,163,197, 32,226,185,249,206, 33, 70, 27, 3, 92,156,205, - 24, 93,235, 0,111, 49,189, 92,208,248,210,181, 80, 73,138,254,104,128,182, 53,144,176,120,242,205, 51,252,254,151,191,198,193, -205,235, 72,139, 18,167,175, 79, 97,173,197,235, 39, 79,200,114,153, 21,248,232, 7, 31,227,233,183, 79,113,120,109, 27,182, 93, -225,224,214, 45,100, 10,120,240,171, 95,225,230, 7,159,226,244,205, 49, 46, 47, 43, 36,152, 35,145, 10, 69,127,128,171,119,238, -227,201, 23,255,202, 24,218, 61,220,249,228,251,184,254,206, 29,188,121,252, 29,198,219,219, 24,108,108,161,174,106,204, 47, 47, -176,154, 78, 48,187, 60,195,244,252, 4,243,217, 2,181, 86,108,199, 1,148,240,240, 86,195,123,218, 91,247,135, 35,108,110,111, - 99,184,185, 9,149,150, 80, 73, 22,243,207,165,162, 75,217, 26, 11,109, 61,211,221, 2,231,160, 37,145,226, 96,136,222,112,140, -254,198, 54,242,222, 8, 66,165,112, 70,243, 88, 84,210,251,187, 86, 52, 59,215, 93,188, 97,183, 76,251, 80, 65, 28, 8,246, 43, - 43,149, 96, 48,236,211, 1,206,207, 64, 93, 53, 88,204, 22,145,103,238, 61, 61,163,186,109, 72, 96,154,132, 56, 96,234,196, 2, -159, 33, 32, 86, 67,232, 72,240,165,119, 34, 50,183,102,243, 66,236,224,233, 2, 79, 1,208,228,128,246,179, 14, 64, 23, 26, 19, - 68, 99,193, 58, 37,184,128,143, 52, 46,165, 32,101,218, 49,179, 89,132, 20,120,236,225,194,164, 84, 50, 18,225,218, 72, 33, 35, -171,162,146, 10,105,154, 33, 81,148,156, 24, 83,212,194,193,202,206, 1,231, 60,180,110,187,231,148, 37, 98,134,153, 2, 73,154, - 83,134,124,156, 94,182,176,182,133, 53, 93,228,106,119,110,137,216,235, 69,184, 84,180,159,117, 23,100,216,237,167,105,198, 22, - 60, 23,131, 76,194,104, 87, 5,240,144,209,107,136, 82, 22,205,114,215, 25, 38,117, 89,150, 69,101,125,196,183,134, 16,175,181, -240,173, 44,207,120, 18,154,196, 34, 34, 9,172,247, 64,157, 11,189,132,144,164,226,142, 28,125,106, 36,194,138, 36, 20,123, 88, - 31, 41,135,137,146, 39, 87, 81, 32, 13,134,230,131, 10, 58, 31,147,236, 8, 84,197, 41,154,108, 41,148,188,147,150, 17,112,131, -184,122, 13, 52, 56,114, 12,100,145,114, 24,168,124, 33, 98, 55,236,210, 73, 15, 96, 58,244,182,119,172,244,183, 81, 32, 26,132, -210, 97,141, 20,252,231, 42,192,207,248,210, 15,175, 49, 18,129,227,223,119,111,209, 76,197, 26,109,181, 19,138, 50,108,200,135, - 0, 29, 17,233,138,234,175,191,247,222,207,195, 33,159, 50, 54, 84, 8, 9,190, 51,200, 95,169, 13,143,151, 17, 1, 4,121,145, -147,141, 45,170,205,187, 12,227,144, 83,110,140,193,106,185,192,244,146, 44, 61,251,135,251, 28, 3,186,138, 56,200, 32,186,176, -142,246,204, 20, 85,216, 61, 28, 89,158,196,135,178, 40, 11,238,100, 51,246, 93, 50,194,145, 63, 32, 42,236,107,172,139,251, 89, - 18,106,173,193, 5, 68, 7,160,161,106,207,161, 40, 67,192, 74, 26,225,251,228,179, 94,247,187, 34,238,134,194, 88, 47, 97,155, -131,181,142,240,157,173,102,150,188,125,203,195, 75,214, 61,172,165,253,216,168,109,112,214, 70,212, 97, 83, 53,145,157,236, 61, -208, 31,148,124, 96, 25,172, 22, 43,142,148, 37,111,113, 16, 96, 4,171,131,110, 91, 92,156, 93, 64,169, 28, 87, 14,247,112,121, -118,129,197,108,134,163,151,175,208,106,137,251,159,220, 71, 83, 45, 49,155,204, 32, 0,148,189,156,252,236,222,193,180, 6, 77, -211, 98,181,168,176, 92,172, 80, 85,117,196,204, 38,105, 18,187,200,157,253,109, 28,189,124,131,229, 98,133,205,157, 45, 12,199, - 3,188,124,246, 10, 89, 94,192, 91,131,114, 48,160,175,233, 52, 22,139, 22,186, 93, 97, 62,153,118, 92,110, 77, 64,150, 36,203, - 33, 85,130,173,221, 45,232,182,197,228,124,130,189, 43, 59,120,246,232, 25,166, 23,211,136,250, 36, 1,154,195,247,126,252, 1, -206,142,207,209,212, 36,116, 20, 82, 98,181, 88,160,170, 12,202, 94,134,233,249, 57, 84, 90,162, 63, 44,225,172,193,244,114,138, - 95,252,215,127, 64, 85,213,248,232, 71,159,163,173, 45, 22,139, 10,179,179, 83, 44,231, 43,120, 41,241,217, 79, 62,199,235,199, -143,177,123,245, 26,110,222,218,197,112, 99,132, 87,223, 61,194, 31,254,237,215,248,248,167,127,138, 55, 79,159,161,110, 20,164, -157, 33, 81, 30, 42,205,112,253,254,199, 56,122,244, 0, 74, 41,108,237, 95,193,173, 15, 63,193,104,107, 19,179,179, 99,108,238, -239, 35, 45, 74, 76,206, 47,112,252,236, 25,166,103, 39,152, 93,156, 97,181,152,163,213, 30,173,205, 34,224,137,114,125, 40, 23, -188, 28,140,176,177,179,143,225,230, 22,100,146, 3,130, 66,143,218,150,236, 98,253, 65, 15,105, 86,160, 24,140, 32,147, 2, 42, - 45,144,247, 70,128, 76,225,124, 2,235,147,152,144,216,214, 75,172,230, 83, 52,171, 41,218,122,201,105,135, 50,142,223,227,152, - 50,164, 47,198,157, 97, 39,214, 36, 49, 83,202, 4, 45,133,225,120,128,222,112, 16, 17,204,100,185, 36,140,112,216,111, 7,149, -121,240, 63,211,168, 53,141,160,148,176,139,149,188,135, 15,137, 97, 82,201,181,241, 54,141,207, 3,139,187, 3,177,112,192,137, -204,227,179,225,156,129,247, 58, 62,103,214,248,184, 14,148, 66,118, 7,124, 72,100, 99, 69,177,103, 64, 86,184,112, 2,250, 51, -230,136,115, 83, 78, 60,137, 96,145, 99,128, 73, 0,230,168,132, 69,131, 10,130,139, 19, 1, 25, 15, 99,173,153, 24,199,211,132, -160, 82,247,156,208, 37,164, 64,150,151,244, 51, 50,175,220,232, 6, 70, 87,111,173, 19,215, 17,214,235,227,241, 40,144,242,126, -205, 50, 5, 22, 38,166,132, 47, 13, 40, 87,190, 20,173, 49, 72,148,138, 77,134,181,250, 45,194, 91,154,166,112, 76,126,164,105, -161,138,159, 9, 26,227,119,145,179,105,154,208,185,144,165, 76,251,148,113,114, 17, 68,101, 49, 73, 45,224, 92, 67, 17, 23, 19, - 51,101, 36,176,169,128, 13,231, 41,128,136, 36, 24,250,247,146, 68,114,177,193,223, 43,172,107,172,139, 23,171,209,134,154,209, - 48,241,101,182,186,247, 54, 22,101,235,132,191,216,125,243,248, 61, 88, 29, 3,180,135, 62,251, 50,174,104,128,128,123,117,156, -147,160,162,179, 42, 10, 16,215,198,243, 42,104, 15,156,225,189,191, 71,192,228, 19, 4,108,109, 30,207,133, 1,173, 21,124,252, -126, 33, 35,190, 35,198, 5,148, 45,253, 30, 3,102, 57, 38, 43, 5, 12,173,148, 72,194,155,224, 29,141,212,194,152, 39,176,217, -121, 76,207,246, 7,122, 48,154, 86, 35,105, 53,188,108,145,229, 25,178, 60, 35, 91,152,117,208,198, 34, 97, 98,158, 74,168,171, - 18,176,120,241,248, 9,164,202,112,245,198, 33, 54,183, 55,113,122,116, 74,233,101,193,203,152, 38,176,142, 70, 87,109,211, 34, - 73,105, 47,164, 91,205, 5,132,231,194, 35,137,132,178, 48, 57,114, 33,103,214, 3,186, 49,200,178,224,211,228,168, 84, 14, 44, - 80,137,236, 34, 8, 5,229,162,135, 3, 73,113,126,119,168, 6, 3,127, 58, 48,218,165, 16,104, 26, 3, 41,124,156,155, 52,117, -139, 36, 75, 99, 32,130, 19, 54,126,152,171, 21, 17,142, 90,246,129,135,110, 31,232, 24,242, 89,158, 80,132,165,146,168,150, 76, - 24,242, 6,222, 73, 24, 3, 12,199,212,189,247,250, 5,230,211,121, 76, 95,211,186,229, 42,156,130, 22,218,166,141, 86,152,147, - 87,207,177,156,111,226,206,251,247,241,234,233, 99,188,121,113,132,151,143,191,197,233,155, 55,248,224,179, 79,176,177, 53,198, -183,191,127,200, 15,134, 97,132, 46,117,124,117,221,196,228,181,237,221, 45,244,250, 61,148,174, 7,153,150,152, 77,102, 72,146, - 29,108,108,142,112,113, 62,195, 87,255,246, 5,110,190,123, 27, 31,125,254, 62,254,240,229, 99, 92, 61,220,199,155,231,175,209, -255,240, 61,100,121,142,106,113, 2,103, 52, 38, 23, 23, 44,168, 34,174,184,169, 43, 64,164,208, 6,120,253,252, 20, 69,161,176, - 90,174, 80, 87, 13, 86,179, 25, 46,207, 79, 81,148, 3,200, 36, 69, 94,246,112,237,230,117,212,171, 26,151,103, 19,140,182, 54, - 96,180,195,246,118, 15, 47,190,123,138,114,184,129, 44, 19,232, 13,123, 40,250, 5, 86,139, 26, 2, 22,223,126,249, 13, 38, 23, - 23,184,125,239, 62,146,172,196, 98,122,142, 44,207,241,250,226, 18, 42, 77,112,229,218, 1, 36, 12,146, 98,136, 79,127,116, 15, -237,114,142,127,250,191,254, 22, 71,207,159,224,135,127,245, 55, 56,122,250, 12,218, 42,212,245, 12,131, 92, 35, 47,123,232,111, -238, 34, 77, 36, 70, 27, 35,136,237, 77, 92,189,115,151,118,229,109,133,225,214, 46,172,213, 56,126,246, 24,199, 47, 95,160, 94, - 46, 96,218,154,182,122, 34,135,151,228, 44,144,240,144,194, 66, 41,135,254,112,140,254,120, 19,105, 65,162, 55, 10, 72, 34, 5, -119, 62, 8,118, 43, 82,255, 46,170, 6,122, 66,216,216,197,108, 10,219,214,144,138, 46, 88,235, 40, 25, 43,203, 19,142,149, 12, - 41,133,164,138, 38, 59,140,141,105,130, 84, 40, 43,134,153, 56,230,102,139,104,103,163, 75,139,152,214,101,175, 92, 75,237,162, - 34, 53, 20,229,225,114, 9,201,101, 16, 64,146,101, 16, 96,244, 37,186,216,212, 46, 93,143, 38, 6,100, 71,210, 16, 49, 86, 82, - 68,101, 51,224,226,232,221,180,150,213,225,105,164,172,145,100, 73,199,110,149, 70,163, 84, 36, 43, 25,188,245, 96, 31,178,137, - 23,161,243,221, 97,174,164,128, 76, 18, 18,148,113, 91,165, 20,173,180, 40, 26,154, 14, 95, 66,197,202,200,237, 8,148, 54, 33, - 2, 28,139, 52, 8,172, 27,163, 66, 66,209,179,219,241,239, 77,252,122,222, 59,100,217, 32,138,239,192, 29, 37,145,226, 92,156, - 40, 70,168, 73,156,242,185,152, 24, 22,109,109, 66,197,208,156, 32,214,234,244, 64,157, 21, 79,241, 10,211,114,243,224,226,247, - 10,151,137,138, 98, 96,199,238, 32, 25,168,105, 28,136, 34, 3, 99, 0, 29,179, 92,196,156,119,143, 44,149, 49,143, 93, 73,209, - 89,241,140,133, 72, 21, 60, 67,101, 84,146, 64, 59, 48, 33,178,139,196,142,124,124, 19,108,192, 50,250,211,131, 37,205,179,123, - 65,128,126, 86,203,163,104,103,233,236,215,173,142,161, 44, 33,119, 97,125,231, 28, 58,106,173, 91,178, 82,231, 42,174,167, 58, -240,144,138,220,255,240,255, 45, 76,220,133,211,221, 64, 32, 53,239, 16,161, 68, 36,250,211, 76,129,163, 75, 94, 90,194,254,122, - 96, 77, 88, 29,194, 90,120,204,174,130, 40, 92,172,241, 29, 2, 78,214,114, 39,206,200,239,183,130,118, 68, 23, 65, 44,197,154, -163,130,232,139, 9,120,252, 98,172,129,144, 52,134, 14, 16,128,245,220, 97, 10, 79,113,108,237,242,168,150, 43,130, 19,100, 36, -248,128,183,236, 49, 76,209, 86, 75,228,101, 1,107, 13,227, 87,233, 23,215,214, 21, 94, 60,126,130,178, 63,194,245, 59,215,177, -154,207,113,126,122, 14,107, 61,169,186, 25,254,146,112, 5, 31, 72, 77, 90,183,124,177,211,248,173,236,147, 66,147,216,225, 65, - 96,227,185,226,108,187, 17, 60, 87, 66,121,158, 50, 27,218,241,254, 67,178,114, 52, 89,243,215, 34, 70,128,134,191,159,231,164, - 56, 15, 62,245,162, 76,121,106,225,216,206,166, 98,116,104,128, 70,144, 96,131,194, 74,170,101,133,166,161, 49, 92,146, 38,112, -181, 91,219, 91, 9, 44,102, 75,138,187, 76, 21,119,228, 52, 98, 47,122,189, 24, 59, 89,148, 25, 91, 60,136,197,236,172, 69,150, -166, 92, 29,174,161, 12, 25,224, 1, 8,172,230, 19, 60,252,253, 28,119,238,189,139,254, 96,128,151, 79,158, 67, 74,135, 7,255, -246, 43, 92,187,115, 23, 63,254,139,159,226,193,175,191, 64, 93, 53,164,110,150,134, 68, 61, 86,199,196,174,201,249, 57,135,182, - 88,244,134, 4, 93, 56, 61, 58,195,193,181, 67,204,103, 43, 8,175,240,219,127,254, 39,188,255,217,103,248,228,243,247,241,250, -229, 49,178, 84,226,252,248, 12,239,189,127,136,239,190,126,129,172, 40, 8,151, 10,178,167, 20,101, 14,107,233,103,205, 50,133, -179,147, 11, 92,187,121,192,211, 11,131,186,170,120,191,108,225,173,196,214,206, 38,238,127,122, 23,231, 39,103,104, 27, 67, 41, -101, 90, 66,194,225,242, 98,142, 43, 55,174,193,154, 26,229, 96,132,209,120,128,249,116,142,201,229, 4,223,124,249, 37,156,115, - 56,184,125, 11,105, 2, 44, 87, 45,154,229, 28,198, 2, 89,145,225,222,199,239,224,193,191,125,129,143,254,232,135, 88, 92,156, -225,191,253,199,255,140,229,124,134,207,255,226, 63,224,245,147,167, 16, 66, 98,177, 52,216,236,183, 40,202, 30,202,225, 24, 59, -135, 55,176,188, 60,193, 96,107, 23, 59,135,215, 32,188, 67,219,212,144,105,129,213,124,134,231, 15, 31,226,236,205, 43, 34, 49, -178,192,198,203, 28,214,167,240,198, 35,203, 60,138, 50,195,120,139, 88,239, 89,111,136, 86,211,186, 99,190,170,176,154, 77,224, -109,139, 52, 75,145,151, 37, 7, 19, 81,145,235, 33, 97,181, 70, 53,159,161,173,150,144, 66, 64, 91,130,113, 36,114,109,146,228, - 28,107, 98, 36, 11, 29, 69,244,250,135,201, 87, 0,129,132,233,151,243, 64,154, 40, 56,109, 98, 14, 65,175,223,195,104, 99, 28, -167,105,225,130,208,218, 80, 33, 97, 45, 95, 82,157, 26, 40, 73,168,131,211,186,133,177, 14, 57,175,174,136,253,175,226, 24, 55, -164, 76, 5,135,131, 4,217, 91, 37,139, 82,219,166, 1, 64,116, 52,165, 50, 14,138,161,130, 92,183, 53,188,111,187,236,241,120, -137,201,183, 50, 26, 66, 7, 39,215, 70,150, 30,226,237, 11,217,122, 56, 56, 46, 98,200, 98,100, 3, 59,156,207, 15,195,213, 0, -253, 44, 10,134, 1, 45, 97, 42,232,215,162, 60,165, 19,107,108,111,209, 37,149,113, 92, 50,188, 67,158,151,132, 27,230,209, 53, - 65,109, 52,193, 81,214, 66, 64,240,214, 82, 17, 49,168, 35,230, 59, 64,192, 11,199,239,113,208,243, 56,166,120,242,207,195, 54, - 53,112,247,166,148, 88, 91, 7,116,109, 98,224, 89,132,226, 43, 4,132, 40,158,172, 64,116,254,126,163, 53,178, 44,141,121,233, - 97,180,236,248, 44,117,206,147,111,219,218,168,152, 23, 16, 16,220, 56, 57,103,226,190,154,214, 64, 41,103,119,248,120,214, 83, - 33,196,171, 2, 67,121, 28,138,249, 7,164,159, 73, 56,166, 21,113,173,167,184,187,183, 12,251,114, 1, 48,230, 77, 92, 95,208, - 36,192,113, 2,161,136,186,167, 0, 36, 11,171, 14,149,210, 51, 65, 27, 9, 15,145,136,200, 66, 88, 31,173, 27,126,207,164,232, - 38,179,244,108,241, 74,136, 5,211, 33, 46,214,161, 19,230,209,244,201, 67,248, 48,101,246,172,225,178,140,124, 70, 55,134, 15, - 77,168, 20,240,150,197,175,107, 48, 27,191,150,116, 42,248,223, 81,127,254,225,221,159, 83,158, 47,143,182, 2, 97, 40,216, 53, - 66, 21,195, 16,132, 80,217, 82, 40, 1,117, 9,126,141,145,171,141,131,227,144,142,144,248, 20, 44, 31, 70, 27,120, 16,189,236, -226,236, 2,189,209, 24,215,111, 31,194, 26,141,197,124, 25, 37,253,158,199, 94,129,197,174, 4, 98, 36,106, 24,217, 9,182,106, - 56,222,245, 36,108,173, 72, 82, 21, 71,128, 20,249,103,214, 34,232, 17, 63,148,244, 48,119, 98,186,144,138,230,172, 71,150,167, -204, 11,247, 17, 79, 24, 4, 27, 74,169,152,180,230, 92,247,243, 88, 99, 59,224, 76, 84,210,139,184, 79,215,173,137,175, 47,140, -209,129, 46, 23,183, 94,145,103, 61,205, 83,100,121,142,173,157, 13,140, 54,250,196,104, 55, 6,139,217,146, 15, 1,215,129,255, -185, 18, 77, 83, 69, 92, 1,238,116,156,243, 16,222, 97, 62,155,162, 28,108,226,234,141, 3,204,103, 51,234,234,171, 37, 38,151, - 43,220,251,244, 35,228, 69,134,201,197,132,108,137, 85, 69,241,132,225, 97,149, 18,166,213, 48, 28,212,145, 38, 2, 73, 86, 64, - 27,224,224,112, 23,203,197, 28,205,106,137,227, 23,207, 49,220,220,198,246,222, 46,102,147, 57, 18,101,145,230,125,180,245, 18, - 42, 73,113,244,226, 57,237, 85,147, 20,101,175,135,188, 40, 33,211, 28, 89,158, 17, 38,183, 55, 64, 91,205,177,115,101, 23,175, -159, 61,195, 98,182, 68, 94, 20, 40,202, 18, 63,248,233,247, 81,148, 25, 46,143, 79,145,247,250, 72, 19,137, 36, 43, 48, 57, 59, -131,117, 18, 87,175,239,192,121, 2, 22, 25,163,177, 90,212,248,226, 95,126,133,201,249, 57,174,221,126, 7,159,252,232, 19, 60, -254,230, 57,210, 44,195,203, 71, 79,225,225,240,147,191,248, 17, 38, 39,199,184,122,231, 46,124, 51,199,255,251,159,254, 11,180, - 49,248,236,223,253, 25,222, 60,121, 2, 37, 61,106, 55,192,168,172,177,185,189,129,241,246, 22, 54,174,222, 2,108, 3,165, 20, -174,220,190, 13,225, 12,180,110,225,173,197,209,179,151,120,244,229, 23, 56,125,253, 28,186,169,233, 0, 73, 82,228,131, 77, 20, -163, 61,236, 94, 61,192,193,205, 91,216,185,122, 3,219, 7,135, 72,178, 30,230,139, 26,151,103,231,184, 60, 61,193,228,228, 53, -170,233, 41, 18, 5, 12, 70,125,228,101, 1,231, 58,251,163,181, 14,213,114,137,106,185,160, 93,168,247,107,217,224,180,255, 14, -112, 35, 15, 31,247,114, 65, 68, 71,105, 88,102, 45,143, 91, 70,187, 18, 89, 88, 83, 62, 32,104,212,222, 31, 12,208, 31, 14, 40, -141,139,241,200,173, 54,104, 26,141,249,108,129,106, 85,175, 5,150, 16, 43, 34, 97, 37,179,214, 26, 41,123,211, 61, 79,223, 98, - 66,160,144,209,119,222,141, 67, 93,156, 42,184, 64, 90,179,150, 65, 46, 41,164, 76,217,109, 35,136, 61,175, 87,113, 60,233,215, - 94,135,115,126, 77,120,239,187,102,196,117,190,236, 52,205, 35,162,154, 88, 12,138,137,105,174,179, 18,121,234,148, 44,175,208, - 58,252,109,216,173, 42, 22, 18,118,251,230,120,201,250,208,124,107,166, 68, 26,238,252, 53,129,114,164, 68, 94,148, 40,202,146, -181, 13, 14,186,109,209, 54,171, 72, 33,131,192,218, 37,164,186,221,255,218, 8,222,175,169,229,101, 4,253, 36, 72, 84,130, 44, - 47, 88,124, 72, 69,144, 95,163,182,133,223,145,229,148, 56,202,159, 71, 71, 89,243, 64,194,182, 54, 74,111,100,230,121, 12,211, -146, 88, 27, 34, 16,139, 0, 34, 22,130,130,153, 30,193, 85, 33, 99,154,152,140, 59,255,176,182,164,236,137,132,247,226,136,169, -157,146,113,219, 93, 40, 77,103, 91, 3,139, 59,105,133,234,201,114,205,211, 73, 17,211,212,104,173,234, 29, 97, 95, 85,194, 74, -118, 25, 18,227,232,119,172,184, 0, 13, 9,154, 73,154,208,132, 65,210, 84, 74,138, 80,236, 80,163, 70,171,140, 14,224, 35,163, -192, 50, 88, 48,101, 20,234,201, 32,228,139,153, 23, 93, 30,201,250, 14,189,219,165,119,197,154, 20,162, 11,103, 17,235, 2,185, -110, 37,211, 33,149, 69, 20, 36,250, 24, 31, 75, 95, 39, 9, 92, 97,194,224, 17,206, 85, 27,131, 52, 33,223,119,240, 90,134,145, -117,216,169, 27,235,224,234, 26, 89, 93, 65,165, 84,253,228, 57,219,161, 32,185, 99, 33, 5,165,243, 30, 86,115,132, 99,107,152, - 31,236,240,230,249, 75, 92,156,158,227,198,157, 27, 24,140, 6,120,252,240, 25,171, 63,195,155, 36, 80,150, 57,141,101,156, 71, -154,121,142,215,163, 24, 79, 98, 40,147,176,161,232, 21,200,101,134,166,214, 49,114, 21,144, 72, 50,245,255,123, 13,244, 11, 33, - 31,173, 66, 94, 4,132,161,103,173, 64,134, 52,227, 14, 94,113, 22, 47,171,234,193,194, 18, 99, 60,219,116, 64, 59,127,134, 10, - 40, 41,208, 52,154, 70, 77,150, 30,134,178, 95, 66, 8,234, 82, 41,188, 69,196,145, 73,168,112, 33,128,225,184,223, 29, 26, 25, - 89,253,234,138, 18,243, 22,179, 10,186,181, 12, 63, 16, 0,123, 91,163, 26,159,193, 31,244, 64, 16,168, 97,181,168, 97,141,198, -233,235, 23, 88, 14, 55,112,247,163, 15,113,254,230, 53, 86,171, 10,206, 52,120,244,213, 55,216, 62, 56,196,247,126,242,125,124, -249,139,223, 32, 73, 18,164,101, 22, 63,132, 90, 27, 24,163, 81, 45,151, 92,245,122,236,245, 7,200, 82, 1, 47, 83,220,185,247, - 46,234,197, 20,103, 77,141,135,191,251, 13,222,251,244, 71,184,241,206, 13, 76,207, 78,241,230,213, 25,174,222,188,134,227, 87, -199,140,140,181,177,154,117,214,162, 24,100, 40,202,146,194,129, 18,201,171, 22, 58,100,210,140, 98, 49,239,127,124, 15,155,219, - 99, 76,206, 39,152, 77, 23,184,241,238, 14,230,211, 21,242, 66,227,228,205, 5, 9,224,178,148,214, 59,173,197,236,114,129,217, -229, 5,158,125,251, 29,250,195, 33, 62,252,225,103,168, 87, 45, 22,243, 26,171,249, 20,198,106,124,255,143, 63,197,104,220,195, -120,235, 46,154,101,133, 95,254,237,191,194, 58,135,207,254,221,207,240,228,171,175,209,214, 11,244,118,110, 99,148, 52, 56,188, -126, 3,229,160, 7,153, 13, 88,131,225,112,112,251, 54,154,170, 66,219,106, 76,207, 47,113,244,236, 25,142,158, 61,129,110, 42, -164,121, 15, 59, 7, 7, 24,109, 31, 64,230, 3, 44, 23, 13, 86,243, 25,170,249, 28, 48, 43,100,121,134,138,133,106,213,114,137, -201,197, 37,164, 20, 40,122, 61, 12, 70, 27,228,155,206,114,180,117,131,182,165, 14,196,104,141,122,181, 36,207, 56,143,126,173, -235,162,134, 11,238,232,227,120,207, 75,120,173, 97, 76, 23,108,208,212, 13,141, 9,189, 71,146,164, 81,241, 29,176,182,101,175, -100, 59,160, 88,139,138,164,195,180,169, 53,140, 49,168,171,154, 64, 52,188, 43, 20,130,212,234, 66, 10, 20,105, 6,173, 13, 36, - 4,178, 44,235, 28, 38,194,115,192, 71, 70,157, 5,103, 13, 40, 41,216, 73,210, 93, 40,130, 47, 5,163, 53, 36, 43,195,157, 23, -236,221,183, 92, 64,181,124,169,249,184, 55, 15,151,155,128,143,238,149,117,212,117,236,212,217,126, 22,138,151,232,151,103,159, -116,216,181,122,111,187,110,157,155,154, 48, 5, 64,220,203, 19,140,138,108, 94, 76,195,228,157,170,143,123, 78, 42, 10,180,110, - 57,105,205,160, 63,218, 64, 89,246, 34, 82,212, 57, 11, 99, 90,104,163,185, 0,233, 44,187,129, 25, 31, 46,219,104, 87, 18, 88, - 27,199, 11,134,166, 40, 56,111,145,167,148, 29,145, 40,193,107, 70,135, 60,235, 44,136, 36,110,166,255, 77,147,132,121,242,146, - 59,125,186,140,156, 11,132,197,110, 63, 28,176,175,130,155,185, 14, 46, 21, 68,205, 68, 79,147,188, 94,244,140,245,150, 41,103, -156, 59, 15,227, 40, 79, 36, 77,211, 46,128, 71, 10,202,179, 23,142, 93, 71,100,127,118, 28,132, 99,140, 1,156, 99,107,181,232, -178,197, 5,133,128, 37,105, 2,237, 56, 80,199, 91, 88,109,160,164, 71,107,117, 12,124, 33,124, 44, 77,139,117,107, 88, 32,202, - 64, 33,129,142,149, 32, 37, 28, 36,132,243,148, 81,207, 14, 33,169, 58, 43,155, 74, 82, 72, 31,104,127, 54,166,141, 58, 31,216, -239, 22, 16,116,249, 75,120,120, 25,132,107,156,144,105, 52, 43,222, 37, 0,194,130,203, 64, 18,134,224,224, 45, 29,167, 10,244, -185, 52,111,249,213, 3,142,216,123, 25,227,171,237, 90, 46,187, 15,128,156, 63,123,255,157,159,167,105, 2, 47, 58, 83,187,115, -158,149,228,164,120,215, 81,216, 37, 40, 1,172,105,153,129,238, 96,157, 71,158, 23, 49,147, 55,136, 54,170,170,238,222,112, 70, - 2,194,139, 40, 30,241, 8, 41, 70, 6,151,231,151, 72,210, 2,119,238,222,192,229,217, 37, 85,183,107, 99,106,199, 98, 28,169, -136, 72, 71,150, 12,226,125, 27, 22,218,232, 86,163,174, 27, 14, 53, 49, 60, 98,235,124,231,138,247,228, 70, 91,190,136, 61,171, -220, 61,235, 7,232,114,145,188, 91, 15, 85,143,228, 49, 40,188,103,165, 62,162,218, 61,236,236,131,119, 18,126,221,247, 78, 15, - 76,208, 28,132,238, 95, 8,129,188,200, 80,148, 57,137,160,210, 20,189,126, 73, 99,215, 34,135, 82, 73, 36, 40, 89,107, 81, 87, - 45,150,139, 42, 90, 92, 2, 44,194,240, 88, 51,140,133, 36, 91, 73, 4, 64, 74,103,129,120,225, 59,219,162,109, 53,118, 15, 15, -145,101, 9,218,166, 69,221,104,212,243, 41,102,211, 26, 31,124,254, 49,132,119,168,171,154,208,136,236, 78,160, 7,131,162, 19, - 87,203, 21,188,179,216,220,217, 38,168, 78,111,128,126, 63,195,209,139,151,176, 70,227,236,248, 24,219,251,135,216, 63,220,131, -183, 45,138,193, 8,222,123, 28, 63,127, 76,182, 54, 31, 60,254,164, 32, 54,142,166, 38,135, 55, 15, 80, 47,230,216,222,223,198, -155,231, 47,209, 84, 53,222,251,232, 62, 62,254,193,135,152, 92,206,136,231, 62, 26, 96,188,217,199,114,105,104,175,149,102, 56, -188,117, 5,139,249, 10, 27, 91,125, 28,191,186, 64,146, 9,252,227,127,254,175,104,234, 37, 62,251,147, 63,193,254,181, 67, 60, -121,248, 20, 89,150,226,249,163, 39,184,121,235, 0, 63,249,203, 31,195, 91,135,243,211, 57,190,251,221,111, 49,155, 76,241,131, - 63,255, 83,124,251,197, 3,204,206, 79, 48,216,189,131,225, 32,197, 59,247,175, 49,204, 38, 67,211, 2,182, 93,226,224,157,119, - 48, 57,155, 96,126, 49,193,209,179,231,120,253,232, 59,120,239,113,245,206, 61, 92,185,115, 31,253,141,125,172, 42,135,215,207, - 95,225,244,245,107,184,102,134, 50, 7, 70, 27,125, 36, 89,138,166,110, 49,187,184,192,217,209,107, 84,203, 5,210, 60,199,230, -206, 14,134,227, 49, 32, 82, 64, 38, 4,147,105, 52,116, 83, 81, 65,176, 88, 68,186,161,103,228, 39,161,107, 51,244,250, 37, 11, -143,104, 71,105, 76, 8,137, 48,107,220,232,176,231, 77, 98,234, 86,146, 40,100,121,142,254,112,136,225,104,128,209,120,136, 60, -207,186, 24, 76,134,164, 88,235,208, 52, 13,163,139, 27,222,253,209,148,201, 88, 27,229, 80,212, 41, 74, 78,124,115,220,221,203, -110, 10, 22,146,205, 66, 65, 26, 5,164,142, 5,100,156,238,231, 45,210,180, 64,154, 21, 76,213, 18, 48,186,134,179, 13,116, 91, -117,138,120,102,182, 75,149,196,157,174,181, 38,226, 54, 37,199,187,190,149,103, 45, 4, 18,182,179,165,105,182,214, 0,117, 99, -110,247, 22, 48,198,199,208, 21,120, 25,137,117,244,250,242,136,127,166, 51,196, 67,201, 36,234,122,180,209,208,186, 69,219, 52, -112,206,192, 57,131,178,215, 71,127, 48,140,128, 26,103, 29,218,182, 70,181,154,115,113, 34, 35, 6,245, 45,194, 88,232,210, 61, - 98,144, 84,248,143,146,114, 77, 64, 7, 74, 90, 76, 18,158,188, 72,238,154, 69,103,235, 11, 97, 37,174, 91,107, 70,205, 3, 43, -227,133, 16, 49,213, 79, 73,196,233, 39,233, 42,232,146, 83, 44,122, 3, 11,182,140, 54,113, 12,111,173, 99,206,198, 90, 12, 54, -119,172,193,190, 28,196,104,105,154,196, 21,104, 88, 27, 90,227, 98,132,117, 96,186,171, 68, 69,219,163, 35,172, 38,233,191, 90, - 29, 45, 96, 96, 1, 98, 32,126,146,235,163,179, 46,166, 89,194,231,177, 96,202, 28, 5,105,137, 56,213,232,196,147, 97, 39, 79, -103,106,167, 79, 8,159,113, 68, 11,180,165,241,126,244,205,175, 9,248,194,234, 34, 80, 2,215, 34,175, 61, 3,160,186,162,179, - 3,205, 36,172, 37, 9, 5,222, 26,178, 38,138, 92,165, 72, 24,190, 35, 99,242, 81,151,209,206, 58,138,191,250,244,222,207, 67, - 46,113,144,243, 91,103, 35,114, 15,162, 27,137, 88,235,208,182,148, 25,109,157,231, 64, 18, 98, 66, 39,172,118, 5,128,182,165, -234,190,105, 26, 78, 54, 18,209,167, 76, 20, 53, 19, 31,148, 32, 32,171,171, 21,154,198,224,189,143,222,195,124, 50, 99, 62,188, -140,251, 49,218,245,231,108, 21, 32,138, 93,240,248, 89, 30,125,132,224, 2,218,123,119,227,109,185,198,128,167,145,160, 68,171, -187,176,135, 32, 12, 12, 34,158, 80,120, 0,158,249,214,134,217,239, 20, 66,226,217, 27,218,212, 45,217,225,140,161, 67,128, 71, - 78, 49, 88,129, 71, 63, 73,150,162,236, 23, 72, 57,219, 58, 60, 84, 70, 91,198, 72,130, 15,220, 36,142,168, 0,143,213,178,166, -177,187,181,204, 67,166,170,175,105, 90, 54,224,128, 31,228, 36,238,151,116,211,114, 92,172,139,175,175, 44, 11, 56,107, 48,187, -156,162, 63,222,196,214,238, 38,170,197, 2, 70,183, 88,206,166, 56, 59,190,192,246,193, 33,110,222, 57,196,197,233, 5,163, 34, - 83,228,236, 54, 8, 48,145,166,170, 80,215, 26,163,241, 8, 73,154,226,240,214, 1, 22,147, 9,166,231,151,240,182,198,100,178, -196,230,238, 62,174, 92,219,133,119, 30,147,139, 37, 38,199, 47,161,155,138,149,164, 22,214, 1, 66,229, 40,251, 37,138, 34,199, -246,254, 46,202, 66,162, 63, 28,226,244,213, 43,100,121,142,159,253,245,207,208,182, 6, 79, 30,190, 64,150, 37,216, 61,216,131, -105, 91, 88, 43, 81,246,115, 0, 10, 82, 2,101,153,227,242,244, 18,109,107,240,244,155,111,241,237,239,191,192,237,247,222,199, -157, 15,223, 71,219,104, 92,158, 77,112,126,116,130, 44,245,248, 15,255,211, 95,227,226,232, 4,175, 94, 92, 98, 53, 57,193,171, - 39, 79,241,233, 31,255, 49, 30,253,254,107,204, 46, 78, 48,218,189,141,209,214, 8,239,188,119,128, 0, 99, 66,210, 67,191, 84, -216,191,117, 11,207,191,125,142,217,197, 4,203,217, 2,121, 89,162, 28,239,162,109, 29, 94, 63,254, 14,111, 30, 61,192,236,236, -136, 52, 10, 69,129,157,221, 13,108,108,111, 34,239,245,160,219, 22,151,199,199,184, 60, 61, 66,189, 92, 0, 34,193,112,115, 7, - 27,219, 59, 40,251, 61,180,154, 4, 64,214, 81, 38,194,114,122,137,102, 69,163,118,201,194, 47,201, 46,142,178, 63, 32,242,159, - 12, 23, 85, 26,237,151,193, 67, 75, 98,182,150,221, 39,154, 71,207, 25,146, 52,193,104, 60,194,104, 99, 3,131,225, 0,253, 97, - 63,218, 99, 2,117, 48, 68, 1,207,102, 75,180,173, 70, 83,119, 2,204,112,248, 74,118,151,208,202,206,241,116, 73,173,141, 51, -213, 91,118,172,144,193, 16, 14, 46,207,123,195, 40,146, 82, 20,220, 67,151,165,130,214, 52,213,169, 86, 11, 88, 83,195,232, 38, -178,174, 3,218, 54, 60,179,214,146, 29, 44,142, 47, 37,251,169, 5,214, 14, 75, 64,202,148,133,178, 89, 44, 50,194,121, 22, 58, - 98,183,134, 87, 37,245,187,125,139,203, 30,132,118,105,146,178, 98, 62,116,191,142, 67, 67,248, 28,224, 66, 69,183, 13,156,163, -117, 68,175, 55,164,181,159, 74,226,216,189,169, 43,104,221,242,104,223,199, 2,129,205,120, 76,196, 67,140,123,117,145, 1,176, - 54,162,231,137,133,146, 9,178,172,224,212,194, 36,122,201, 37, 67,189,104,247, 43,161,117, 27, 71,150,138, 47,235,224,217, 22, -188,131,151, 2,113,255, 28, 4,194,193, 69, 32,197,250, 72, 57, 96, 83, 37,175, 51, 4,210, 60,143, 83, 5,106,116,194, 94, 94, - 70,168, 17,157,193,235,191,191,142,135,223,217,189,214,232,110, 66, 34,225,181, 77,224,237,119,156,119, 2, 38,121, 22, 97, 2, - 36,148,203,178,148,166, 2,252,243, 73,142,166, 38,221, 9,133, 24, 17,194, 88, 68,181, 58,216,203,174, 98,247, 46,214,130,116, - 34,234, 39, 6,174, 56,214,126, 5, 91, 36, 21, 11, 62, 42,254, 59,193, 99,199, 81,232,120,239,161, 1,166, 51, 58,156,177, 16, -190,179,182,133,116,190,168,222,239,148,248,240, 93, 32, 82,224, 42, 4,199, 20,224,145,208,129,160,216,159,232,227,152, 73,107, - 67,111,132, 20,252,129, 34,191,180,148,114, 13,106, 17,248,198, 46,190, 65,121,158, 65,240, 62,189, 93, 53,104,155, 26, 66,130, -115,112, 37,140,145,172,234, 37,120, 69,194,236, 96,231, 4,166, 23, 23,248,253,175,151,248,248, 7, 31,226,197,163,199, 56,122, -117, 2,159, 18,132, 36,236, 87,156,163,142, 82,176, 31, 62, 84,216, 90,211,133,103,195,190, 90, 8, 20, 69,134,214,121,254, 62, - 4,123,161, 93,185, 68,150, 37,107,108,117, 21, 45, 20,212,245,155,248, 65, 51,198, 68,107, 90,107, 52,211,182, 26,194,109,166, - 60, 38,226,106, 84, 70, 10, 18, 21, 61, 65,252, 35, 4,225, 93,179, 60, 35, 69,121, 47, 71, 83, 53, 88, 46, 42, 30, 5,185, 88, - 48, 72, 9, 52, 77, 75,254,237,182,141, 29,191,146, 68,111, 11, 97, 53, 77, 93, 83,120, 1,167,192,209,184,150, 3, 47, 82, 5, -173, 61, 63,144,146,173, 97,244,187, 58, 63,122,131,172, 28,226,198,221, 59,120,253,228, 49, 39, 21, 89,188,126,242, 8,211,241, - 14, 62,253,241, 15,240,251, 95,254,154,226, 53,185, 66, 77, 18,138,133,244, 0,172,174,113,250,230,152, 1, 62, 35,188,255,217, -247, 80, 45,230,120,253,236, 25, 76, 61,195,147,111, 30, 98, 56,254, 28, 59, 87, 54,112,126,124,142, 79,126,248, 61,252,227,255, -253,183,212, 1, 58, 11,143, 4,206,232,184,159, 19, 2,216,187,186,135,172,200, 49, 28, 15,240,254,247, 62,196,238,213, 93,252, -211,127,249, 37,154,166, 1,196, 0, 89,150,224,244,104,130,131, 27, 87, 49,189,152, 67, 72, 2, 28, 37,194,224,205,203, 51, 12, -199, 37,126,249,247,127,135, 94,127,128,155,247,238,161,105, 28,142, 95,188, 66, 81, 22,104, 86, 51,252,213,255,240, 23,248,234, -151, 95, 96, 62,175,177,119,176,139,175, 31,124,131,143,254,232,143,240,240,139,175,208,174,102,184,118,247, 3,136,116,128,187, -247,118,169,200,114, 30, 50, 31, 96,123,123,132,180, 40,113,118,116, 10,149,230,176,190,197,217,241, 37,206, 95, 61,130,109,102, -113, 79,221, 27,237, 96,180,189, 7,149, 80,241,150,101, 41,166,231,231,152, 95,158, 97, 57,187, 36, 91,147, 21, 24,108,108, 97, - 99,123, 7, 73, 94,192, 26,139,166, 49,208,218,193, 57, 13,221,172,208, 86, 43, 22, 67,178,245, 47, 85,200,203,140,159, 79,197, -249, 82, 93, 7, 98,121, 52,106,184, 19, 8,148,194, 64, 4, 27, 12,169, 59, 84, 73,138,140, 73,133,161,240,180,142,166,108, 82, - 73,212,117,131,166,110, 40,203,189,169, 33, 32,248, 89, 87, 8,124, 23,203,187,239, 16,195,170,148,130, 89, 3,200, 4,159, 78, - 56,244, 73, 12, 69,207, 56, 77,104,152,197, 13, 27, 19,255,138,178,207,187, 90, 18, 69,105,173,209,182, 45,172,174, 88, 17,206, -186, 30,107,162, 29, 48, 48,191, 29,143,205, 41,132, 73,178,162, 92,112,114, 24,251,168,249,107, 11,149,240,107, 15,135,122, 18, -161, 45, 97, 39,171, 34, 96,133,192, 91,218,120, 30,149,130,199,238, 4,177, 10,235, 11,250, 26,157, 38,198, 59,178,179,133, 67, - 24,220,225,229, 69, 31, 69,175, 68,202, 54, 49,195,200,235,186, 94,242,101, 67,194, 90, 47,125,196,224,134,137,103,128,225,184, - 53,222,119, 92, 35,132, 92,122,120,158,134, 74,214, 18, 73, 4,203,146,181, 38,218,212,130, 10,223, 58, 19,255, 92,152,116,168, - 36,141, 25,222,206, 57, 4,205,182,226, 80, 43,193,221, 96, 56,115,165, 96, 95,123,196,222, 58,200, 36,227, 54,212,137, 20, 0, - 0, 32, 0, 73, 68, 65, 84,132,179, 48,153, 9, 43, 32, 25,109,196,105,158,116,162,184, 64,145,227,104,101,176,210,221,123,250, -158, 68,221,244,200, 50,210,132,196, 88, 81, 5, 88, 72, 72,203,193, 46,169,130, 1,119,199, 94,198, 66,210, 26,139,172, 72, 89, -216,109, 1, 39,161,148,103,109,133, 90,179, 8,242,142, 89, 3, 70,251,152,214,230,121, 85, 40,164, 66,154, 10, 82,215, 71, 24, -146, 65,154,210, 26, 70, 41, 17,103,223,222,185, 24, 29, 30,120, 11,158, 19,214, 52, 55, 90, 74,137,206,229, 33,101,164,222, 1, - 30, 54, 76, 61,224, 99, 83,234,215,162,171, 59,170,157,231,226,166,187,216,195,107,161, 78,253,179,251, 63,119,220,250, 75,165, -128, 53, 27, 74,164,169, 57, 31, 85,240,214,145, 66, 62, 50,125,165,228,176,150, 28,105,158, 34, 77, 51,174,182, 29,172,209,208, -218,196,232, 58,197,226, 15,165, 36, 7, 77,128,209,178,158, 15, 41, 11,107, 53,222,188, 56,194, 59,239,223,195,106, 49,163,135, -220, 6, 86, 59,141,174,210,148,186,234, 0,176, 65,136, 52,140, 70,124,207, 16, 40,201,182, 20, 17,217,216, 93,210, 93,103,101, - 17, 12,232, 8,222,206,132, 59,108, 58,144, 12, 7, 26,208,179,162,181,137, 59,241, 36,149,100,107, 99,191,119, 40, 48,140, 89, - 31, 79,186, 46,160, 70,116, 21, 92,209, 43,137, 83,156,165,221,206,139,193, 34,186,105,249,112,119,208,198, 64, 8, 31,109,115, -129, 56,151,176,218, 52, 73,187,239, 45, 98,199, 96,217,142,151, 32,205, 11, 86,210, 19,238,209, 90, 15,221,172,112,113, 58,193, -193,205,155,200,243, 4,245,138, 48,163,109,189,196, 98, 78,227,120, 88,141,229,108, 1, 33,169, 0,138, 1, 16,158, 70,193, 77, -181,130,247, 18, 59, 87,246,176,181,187,137,217,229, 57,170,197, 12, 42, 45, 88, 39,144, 35,203, 37,246,174, 29,224,217,215, 15, - 99,129,146, 23, 61, 36,105,129,114, 56, 68, 81,228,216,216,222,194,198,230,128,210,226, 36,112,243,189, 91,104,107,131,135, 15, -158, 33, 77, 19,148,189, 30,198, 27, 61, 76, 39, 21, 54,183,199, 56, 59,153, 32,205, 82,140,199, 57, 30,252,230,107,236, 93,187, -138, 95,253,221, 63,224,226,244, 8,127,244,151,255, 30, 16,196, 28,104,170, 6,171,217, 5,254,234,127,252,115,124,245,203,223, -227,233,183, 79,240,238,199, 31,226,249, 55, 95,227,206,135, 31,224,219, 47, 30, 64, 9,135,155,247, 62,128, 21, 61,220,186,181, - 73,218,140, 34, 67, 90,150,216,189,186, 7, 33,115,188,120,242, 26,143,190,122,136,175,127,243, 5,142,158, 62, 66, 53, 61,129, -211, 43,210, 8, 8,137,225,214, 1,246,111,220,134, 76, 83, 12,198, 99,140, 54, 7,152,157,159,226,232,217,183,152, 93,158,195, - 56,137,180, 24,226,234,205,155, 24,109,109,195, 11,137,166,110, 88,192,214, 98,122,126,142,213,108, 26,249, 14, 89,145, 33,205, - 82,100, 25, 9, 38, 3,221, 13, 60, 38,148,124, 89, 17, 1,204,243,123,157, 32,205, 72,136, 88,246,123, 40,202, 2,101,175,135, -193,104, 64,132,177, 60,237,116, 36,137, 66, 83,183,252,223, 26,171, 85,133,197,108, 73, 17,186,214,194,104, 13,173, 45,175,130, -212, 91, 0, 18,240,243, 79, 43,174, 54,118, 59,145,104, 38, 3,125, 75,198,103,147, 62,183, 34,138,195,104,252, 95,160,236, 15, -160, 84,202,221,182, 70, 93, 87,168,171, 37,116,187,130,179, 6,218,104, 14,126,210, 72,146,140,120,245,174,243, 49,203, 53, 43, -143,228,115, 42,244, 69, 9, 39, 64,134, 41,163,224,110,177,139,190,244,113,138, 17,166,147,142,139,255,160,253, 96,150,110, 76, -125, 11,157,155, 82, 20, 85, 27,166,140,134,207, 3,186,120,232, 34, 13,151,104,146, 36,216,216,220,142,161, 39,214, 26,198,251, -206, 98,209,132,152, 35, 47, 98,199, 28,208,182,235, 64,216, 32,156,147, 82, 34, 77, 50,222,111, 43,162, 16,230, 57,148, 10,221, - 41, 23, 28, 60, 82, 15,190,237, 16, 25, 27, 46,111, 17, 38, 31,220,201, 10,129,216, 96, 73,238,146, 3,170, 85,112,148,233,186, -222, 34, 52, 67,137, 82,113, 90, 24,145,220, 74,197,176,171,160, 75,144, 74,198,207,148, 7, 11,144,215, 44,101, 73,188,236,192, - 64,154, 46,192, 37, 32,190,131,203,200, 51,163, 35,136,232, 18, 14,136, 81, 28,227, 27, 40,118, 0,117,249,130, 61,224,244,236, -168, 14,108,198,211, 34,103, 44, 28,199,119,119, 25, 55,226,173,207, 25,193,176, 4,167, 70,118,239,147,228,105, 71,180,197, 5, - 15, 62, 23, 53,225, 57, 16,107,112,156, 88,160,189,229, 32,241, 29, 74,214,117,126,123,210,123, 8,158,164,119, 92, 2, 90,169, - 81,215, 46,217, 58, 23,154,114,245,151, 31,191,247,243,144,172, 19,196, 56,142, 67, 8, 8,191,199, 30, 70,134, 75, 68, 38, 45, - 13, 59, 98,114, 77, 94,228, 16, 50,137, 17,170, 84,113,235,168,116,165,209, 92,231,181,107, 27, 13,163, 45,199,245,117, 73, 52, -129, 96,246,250,229, 17, 62,250,252, 19,156,188, 57,226, 29, 49,209,173,130,153, 31,222,198, 12,224, 64,125, 11,222,109,242,226, -166,145, 54, 21, 73,108, 65, 1,202,190,221, 48,106, 11,200,215,240,161,164, 48, 2,102,112,115,170, 16, 21, 5,238,109,127,174, -243, 81, 89, 76, 20, 41, 77,217,232,188,102, 48,173,137,241,123, 70,155,136,141, 36, 59,134,129,115,130, 59, 8,137,170,106,217, -135,142,232,157, 79,178, 4, 9,143, 46, 35,144,197,119, 99,119,126,239, 33, 3,221,142,127, 7, 89,150,240,200, 43,101,191,163, -140,170,232,182,213, 52,178,242, 14,147,243, 11, 12,183,182,177,181, 61,198, 98, 58,229,223,173,197,233,209, 57,246,111,220,198, -214,206, 8,147,179, 11, 38, 85,209, 69,227,173,142,175,127, 62,153,160, 24,110, 96,255, 96, 23,253,225, 0, 23,199,199,104,235, - 6,253,209, 24,189, 94,129,171,183, 14,113,122,116,137,221,253, 77, 28,191,124,137, 52,205,144,230, 5,178,178,143,178,236, 99, - 56, 30,160, 28,244,177,185, 61, 66,209, 43,177,179, 55,194,112,123,140, 63,252,250, 27, 44,230, 53,146, 68, 98,255,112, 15, 74, -210, 8,121,114, 62,129, 67,138,225, 48,131,105,150,152, 76,106, 56,221,224, 23,127,255,223,112,239,211,239,161, 28,108,162, 63, -218,192,233,235,215,184,125,247, 58,126,242, 23,159,227,241,131,239,240, 47,255,207, 63,224,179,159,253, 12,245,236, 2,227,221, - 61,188,248,238, 49,198, 27,125, 92,123,247, 46,102, 43,129,237, 13,133,141,173, 1,146, 52,161,228,179,172,143,227,151,167,248, -195,175,126,131,239,190,248, 18,147,179,115,138,194,116, 45,224, 90, 8, 1,140,119,246,112,251,195, 79,177,177,127, 21, 69,175, -132,146, 10,109,181,196,197,209, 49,166,147, 25, 21,190, 73,142,157,131,107,216,222,191, 2,161, 82,180,154,156, 24,198, 58, 44, - 39, 23, 88,205, 39, 16,222, 65, 42, 32,205, 51,148,172,173, 8, 43,162,136,230,148, 29, 35,155, 28, 18, 57, 79,124, 74,244, 6, -125,244, 6, 67, 66,122, 38,157,229,134,124,182,116,112, 6,161, 91, 85,213,168, 86, 53,150,139, 37,218,150, 62,111,142,253,188, - 66, 72,180, 60,233,113, 28, 91, 42,100, 39,152, 10,221,177,110,219,183,192, 31,164,248,237, 86, 70, 73,150, 70,198, 69,228,119, -115,131, 80,244, 74,148,189,126, 92,189, 57,103,209,182, 13, 86,203, 57,150,179, 41, 44,219, 81, 67,244, 46, 9,133,152,183, 46, - 21,137,149,100,200,244,102,235,152,239,186, 88,186,120, 85,156, 72,120,116,207, 87,244, 61,115,128, 76,236,202, 89,252, 27,248, -223,206, 59, 74,253, 90,227,170, 7,191,179,247,130,249,247,244,191, 65, 44, 72,151,185, 69,221, 52,244,215,134,120,227,101,217, - 71, 89,150,200,242, 12,150, 29, 65,213,106,133,138,109,137, 65, 85, 30, 83,216, 56, 35, 35, 73, 82, 30, 99, 73, 30,139,171,248, - 26, 67,234, 93, 71,145, 83,200,243, 2, 9,243, 5,194, 94, 56, 52, 15,193,118,103, 35, 3,157,116, 82,235,255,190,231,117,155, -148,130, 5,128, 29, 7, 36,184,136,194,254,154,233,167,252,254,178,226, 61,114, 77, 4,239,161, 69, 44,138, 60, 11,146, 19,166, -112, 26, 75,141, 76,128, 22,133,140,145,112,223,208,185,106,163,126, 34,122,212,215,114,198,233,226,103,183, 19,175, 86, 83,214, - 76,209,159, 67,167, 11, 34, 91, 87, 20,134, 6,219, 30, 53,153,178, 19,107,242, 62, 59,144,241, 98,248, 25,251,245, 41,163,193, -133,212, 19, 64,120,182,214,137,104, 39, 77, 88,157, 31,236,126,240, 29,254,188,163, 24,250, 14,159, 27,214, 14, 2,111, 21, 25, - 1,158, 20, 98, 94, 41,205, 77,198,105,140, 16,201,218,103,231,237, 61, 61, 0,168,127,255,189,123, 63,199, 26,140, 31,108, 83, - 8, 86,136,240, 67,173,135,144, 88,235, 57, 37, 38,196, 29, 10, 56, 47,162,208,139,160, 51, 76, 47, 98,184,125,224,164, 19,176, -223,197,108,218,136,109,236,214, 87, 52,246,214, 45, 46,206, 38,248,252, 39,159,225,248,245, 17,140, 37,208, 10, 89, 36, 4,218, -166,129,224, 72, 69,165,100, 4,222,199,196, 37, 17, 34, 34, 13,117,242,198,194,114,156, 97,168,120,194, 1,145, 36, 50,142, 23, -157,247,240,150,160, 49, 97,213,224,215, 42,229, 16, 74,211, 54,154, 14, 56,126, 88,155,186,161, 67,210, 57,190,208,201, 14, 6, -143,248,207, 40,235,156,124,190, 77,163,185, 75, 97,241, 88, 78,151,166, 99,161, 4,141, 93, 68,215,161, 51, 66,209,178,205, 66, -183, 6,101,191,232, 48,142, 28, 82,227, 25,163,153,102, 41,137,239,242,140,198,184, 28,105, 27,198,247,214, 16,249,106, 62,185, -132,245, 9, 14,111,221,128,110, 27,202,183,118, 6,243,203, 75,164,229, 24,239,125,244, 46, 46,207, 46,224,217,166, 67,156,125, - 7,235, 20, 18,233,225,156, 64, 90,148,216,218, 25,163, 55,232,227,236,245, 75,168,180,196, 96, 52,194,104,107,147,247,123, 41, -102,231,103, 76,126, 74, 33,100,138,188, 71,107,136,225,198, 8,227,205, 17,250,195, 30, 18,229,225,173,199,111,254,249, 43, 8, -149,161, 63,200,176,119,176, 3,173, 29,246, 15,183,112,126,182,132,181, 14, 7,135, 27,248,250,183,223,224,240,206, 77,124,245, -203,127, 67,219,180,120,255,179,207, 80, 55, 2,195, 81,142, 44,203,240,241,231,239,224,252,232, 12,255,231,255,252,191,225,253, - 31,252, 16, 91, 59, 27, 72,211, 28,167,175, 94, 97,255,234, 46, 6,155,187, 56, 57,173, 80,164, 26,251, 87,119, 80, 14,199, 48, - 46,193,217,217, 10,213,228, 18,175, 30, 61,194,201,155, 83,212, 53,197, 96, 38,146, 32, 74,189, 65, 15,215,222,189,143,119, 62, -249, 30, 54,247,247,208, 31, 14, 80, 47,231,120,254,245, 3,188,121,254, 20,117, 99,145,100, 57,198, 91,219,216, 63,188,138,162, - 63,132,245, 2,121, 73, 66, 45,167,107, 84,179, 11,152,182, 33,247, 69,153, 33,205,115,190,204, 21,243,197,179, 40,112, 75,210, -140, 58,240, 94, 15,253,193, 0,189, 65, 15,227,141, 49,146, 52, 67, 94, 20, 49, 50, 85,107,205,162, 54,214,128, 52, 13,234,170, -198, 98,190,192, 98,190,192,124, 54, 39, 72, 81,204,225,150, 49, 60,137, 66, 41, 92,100, 62, 52,220,133,147,239,150,159, 47,185, -246,112,138,181, 98,217,117, 74, 98, 33, 9,100, 19,172, 81,222,131,114, 12, 84, 66, 41,115, 44, 46, 19, 18,168, 43, 42, 46, 86, -139, 41,234,106,249, 22,225, 44,140,197,169,227,167,174, 59,240,198,131,131,130, 16,206, 6, 82, 38,177,112, 13, 99,101, 33,232, - 34,207,152,144,153,132,131, 26, 29,150, 57, 64, 87,130,127, 63, 8,173, 92,164, 92, 82,244, 40,173,223, 28,143,253, 85,236,208, - 35,159,157,247,240, 36,112,162, 68,194,209,198, 24,195,209, 8,189,126,159,166, 36,108, 55,213,218, 96,181,154,195,152,150,187, -116, 25, 87, 26, 88, 11, 60, 10,205,136, 74,210, 24,152, 18, 19,227,184, 32, 10, 62,116, 41,201, 46, 26,172,137,225,207, 6,145, - 91, 72,105, 19,204,157,151, 81, 96, 23,194,118, 4,217,251,164,228,125, 50,226, 74, 35,101, 54, 6, 21,117,116,193, 5,134,121, -152,230,166,108, 11,139, 22, 70,182, 49,135, 88,109,239, 61, 57,160, 2, 60,134,187,246, 0,247, 10, 14, 43, 56,191,198, 95,231, -207, 29, 59,133, 20,211, 67,193, 0, 24, 21, 73,129,157, 72, 76,112,240, 9,229, 87, 36,107,220,116,178,105,147,245, 90,196, 53, -169, 15, 43, 82, 41,223,186, 15, 16,217, 3,134, 87, 90, 54, 22, 67,129,244, 38, 85,128,147, 37,107,107, 9,172, 9, 84, 93, 12, - 97, 9,194, 83,193, 95,179,203,169,247, 81,247, 68, 77,167,141,240, 25, 31,138,169,184, 14,151,107,137,127, 60,149,224, 6, 60, - 60, 55, 65,191,224, 1, 36, 97,143, 76, 23, 51, 85,222,150, 5, 48, 66, 42,120,211, 81,210,188, 1,224,108,180,112,208, 78, 78, - 49,238,208,243,168, 61,143, 99,136, 80, 37,183,124,128, 5,118,123,128,219,228,121,138,182,181,252, 11,202,226,139,247, 44, 68, -168, 87,115, 60,248,221,183,184,255,241,251,120,240,197,195,184, 14,168,235, 22,222, 58,184,186, 69, 89,230, 81,101, 24,114,124, -243, 60,225, 75,151,128, 26,228, 21, 5,127, 16, 61,146,132,118,248, 33,109, 39,218, 90, 18,234, 18,180, 51,104, 27,141,182, 17, -156, 78,231,226,197,158, 21, 25, 18,235,121, 52,175, 97,195, 46,138, 71,122,186,109,163,250,215,121,162,206,101, 44,142,131, 79, -161,148,131,214,154,236, 72, 10, 40, 10,234,176,116, 75, 86,140, 81, 49,132,209, 26,139,249, 2,166,213,113,236,231,215, 18,165, - 76, 75,233,106,245,170,134, 74, 9,107,216, 27, 80,114, 87,154, 1, 90, 39,236,149,183,157,110,128,187,166,178,228,176, 25, 67, -147,140,182,110,177,156,156,225,121, 93, 97,239,240, 16,205,242, 18,211,203, 9,146, 4, 88, 92,158,224,241, 98,137, 15,127,248, -125,124,243,155,223,162, 94, 46,209,212,164,103, 72, 83,234,132,230,151,231,152,158, 21, 72,147, 93, 92,189,121, 3,203,233, 12, -143,190,126, 12,113,231, 38, 22,211, 57,180,118,216,216,222,196,251,159,127, 15,255,250,183,127, 31, 47,130, 94,175,196,120,163, -143, 44, 85,209,167,122,113, 50,229, 93,189, 65,191, 55, 64,209, 43,176,177, 53,192,108, 90,209, 7, 91, 41,228, 9, 96,218, 10, - 50, 43, 33, 4,101,186,127,254,211,159,224,226,108,134,235,239,222, 70, 53,155,224,240,250, 14, 38,103,151,248,143,255,235,255, -129,253,107, 55,241,206, 7,239,193,180, 45,206,207,222,224,224,250, 1,156, 87,184,156, 25,236,239,245, 48,222,222,132,245, 2, -203, 69,131,186,177,176,245, 2,199,111,142, 81,173, 26,234, 6,157,129, 18, 22,105, 34,177,127,235, 14,250, 91,123,200, 7, 99, -100,101, 15,186,105,112,244,236, 25,158, 61,124,136,182,174, 33,100,130,225,120, 3,123,135, 7, 40, 7,189,152, 92,166, 26,131, -106, 49,199, 98,114, 1,163, 27, 40, 37,209, 27,246, 98, 80, 4, 29,132, 2,121, 89,210, 52, 35, 75, 33,147,148, 87, 67, 9, 83, -170, 2,186,217,163,105, 73,164,105,180, 70, 83,215,104,234, 6, 85, 85, 97,181,172,208, 54, 13,235, 97, 36,143,196, 19, 70,136, -210,133,209,237, 30, 73, 80, 68, 19, 38, 27, 15, 5,173,117,236,186,105,164, 41,214,242, 26,152,210,230,201,202, 89, 85,134,159, - 41, 23,161, 37, 65,253,222, 47,250,145,194, 38, 5,120,221,230, 24, 50,180, 66, 91,175,208,182, 13, 5,139,240,165, 70, 69,183, -103, 65,156,139,118, 35,201,156,118, 26,115,202, 40, 14,164, 75, 95,177,210, 94,198,104,102, 82,167,103,176,204, 88,232, 60,190, - 12,218,114, 93,202,153,144, 18,112,150,162,153,215,186, 24, 41, 84, 76,148, 4,119,226,196, 6, 95,183,199, 10,142,122,165,203, -101, 52, 30, 97,123,119, 59, 82,210,170, 85,133,166,174,163, 99,160, 90, 45, 81,215, 21,251,239, 17,109, 74, 88, 19, 86, 9, 65, -156, 3,203, 13, 65,135, 49, 85,241,194, 94, 7,228,164, 89,142,162, 40, 34,165,142,132, 95,221,159,243, 76,203,164,156,136,183, -131, 83, 66, 81, 34,208,117,247,244,125, 68,164,124,250, 32, 50,230,182, 82, 55, 84,240, 89, 4, 66,160, 65,209, 75,227, 94, 95, -196,236, 13, 68,123,161,230,192, 47, 99, 44,178, 76,198, 29,176,103,191,187,140, 14, 15,207, 83, 81,221,121,195, 57,204, 42,161, -192, 4, 10,113,225,215,104, 13, 17, 6,147,132,166, 38, 42,205, 35,138,151,214, 66,136,209,225,142, 83,247,188, 99,151, 23, 73, -213,161, 50, 82,240,211,180, 94, 1,158, 84,229,164, 98,167,207,175,110,216, 39,175,212, 90,116,111,202,202,127, 74,103,247, 96, - 32, 18,211, 89,101,128,204,128,172,120,193,229,224,157,141,214, 60,138,130,181,177,232, 2,243, 71,226,215, 18,146,223, 11, 9, - 48,216, 6, 80, 72, 56, 35, 36,120,238,125,200,228,241, 14,176, 64,146,164,105,103, 33,123, 43,252,132, 66,215,141,145, 12,141, - 65, 84,136, 74,239,121,199,173,162,133,204, 89,131,213,146,252,184, 25,143,227,225, 45,154,138,144,151,186,109,209, 31,244, 96, -141,229, 44,111, 10, 82, 0,108,167, 48,101,113,153,136, 33, 2, 22,151,167, 71,216,220,217,193,104, 60, 68,211,180, 40,138,140, - 59, 86,139, 44, 73, 99,106,148, 99,133,160, 74, 84,236, 72,228,218,248, 48, 91,131,200,180,141, 65,146,102,113,188,232,156, 67, - 94,228,188, 11, 39,202, 87,216,187, 47,231,154,223, 60, 25,247,154, 1,170,161,188,143,182, 50,147,104, 26,239,120, 27, 71,157, - 33, 20, 38,120, 38, 61,175, 5, 72,136,168, 1, 77,111,120,238, 67, 68, 34,197,133, 74, 73, 56, 82, 82,201, 54,104,235,102,109, -245, 1,120,225,209,212, 13,178, 60,131,240, 14,121, 89,196,202,158,128, 25, 13,113,135,185,144, 18, 0,178, 60,141,171, 6,107, - 45,178, 34,135, 53, 6,131, 97, 31,214, 88, 44, 23, 21, 38,167, 71, 24,110,237,224,206,253, 29,188,122,242,130,185,255, 19, 60, -252,178,193,237, 15, 63,198,229,209, 43,188,126,246,130,185,225, 18, 89, 57,128, 51, 26,213,114,133,211,215, 39,104, 55,199,184, -253,193,125,204,167,115, 28,191, 58, 70, 57, 28, 97, 48, 30,194,122,137,221,107, 55,112,237,246, 13, 76, 39, 43,140, 54,183,176, -177, 61,130, 82,138,236, 82,134, 24,229,163,173, 49,126,251, 79,191,139,187,175,162,215, 99, 27, 23, 48,155, 17,247, 96,115,187, -143, 71, 15, 30, 97,103,111, 27,147,211, 83, 92,189,117, 3, 77,109, 48,216,216,194,181,155,187,104, 86, 3, 56, 83,227, 95,254, -246,159,209,182, 26,127,250,103, 63, 69,154, 38, 88, 92,156, 98,115,103, 19, 85,101,224, 85,142, 59,239,238, 98, 54, 89, 96,181, -172,113,245,230, 21, 44,230, 45,218,203, 83,232,122,129, 52,241, 56,157, 92,194,182, 21,242, 76, 98,247,224, 0,219, 7, 7,112, - 72, 96, 29,137,126, 22,211, 25, 46,142,142,112,246,230, 13,138, 94, 15, 27,219, 91,232, 15,134,216,218,219,133,151,105, 92, 39, -173,230,115,218,153,155, 22, 89,166,144,164, 5,171,127, 5,185, 11,210, 20,189, 65,159,139,221,140,152,225, 12,159,161,144, 29, -139,229,178,134, 49, 22, 77, 85,195, 24, 67,169,127,198,193, 90,205, 59, 95, 62, 24,216, 27, 78,147, 24, 7,175,136, 51,175, 84, -178,214,141, 18,191, 60,144,229, 8, 48, 18,128, 82, 34, 30,178,161,107,141, 93, 42,251,171,233,121, 51,168,170, 38, 78,215,194, -215,206,139, 2, 66, 40,244,250, 37,255, 60,134,159, 99, 13,221, 54,104, 27, 18,206,134,184, 73,163,117,204,121,160,221,183,136, -194, 84,178, 76,165,145,136, 22,187, 32,103, 32, 5, 11,196,162,246, 39,229, 91, 86,241, 69,201, 96, 41, 36,209,199, 31, 58,125, -218,141,170,152, 87,225,152, 38, 22,162,151,201,239, 31,118,182, 10,102, 45,135, 34,201, 72, 12, 71, 94,238,238,172, 12,214,212, -254,160, 71,218, 16,110, 30,136,223,223,237,111,155,166,130, 82,105, 36,244,117,148, 50,214,247,112,192, 84,244,187,175,229,185, - 99,109,205,208,141,197, 57,215, 62, 73, 72, 16,200, 69, 11,237,212, 45,159,175, 20,181,234,124, 23, 93, 26,134,176, 1, 45,154, -102, 93, 20,109,112, 42,132, 88, 81,143,144,112,166,162,224, 43,232,143,132, 36,123,100,152,218, 4,142, 1,130,191,159, 53, 12, -150, 49,177,224,120,106,107, 67, 99,229,160, 88,131,225,215,178, 50,194,251, 18, 18,217, 58, 49,164,132,204, 83,180,117,179,246, -251, 96,182, 61, 91,228,194, 36, 39,176, 18, 72,114, 37, 33,184,206, 17,158,197,108, 0, 84,145,145,163, 40,203, 34,184,198, 69, -126,136,138, 19, 27,165,100,180, 72, 67, 72,214,130,152,168, 57, 9, 59,243,208,177,135,226, 23, 76,140, 11,246,228, 68, 41, 88, - 62, 23, 4,200,147, 79,194, 87, 17, 87, 14, 60,217,231,176,165, 0, 14,226,137,144,103,147, 27,239,209,109,176,150, 70, 37,189, -132,148, 14, 73,194,185,199,224, 95, 54,249, 46, 85,252,101,102,121,142, 52,203,208, 54,196, 96,119,150,230,215, 52,134, 7, 95, -164,244, 3, 40, 37,226, 88, 33,100,130, 75,149,192,235,144, 0, 86, 33, 43, 10,134,176,240,155,190, 62,250,224,253, 70,162, 36, -124, 66, 92,116,107, 29, 94, 60,121,130, 79,126,240, 9,190,125,240,144,199,209,116,184,180,141,166, 46, 63, 37,161, 16, 97, 79, -243, 40,242,160, 85, 12, 43, 22, 61,199,167, 42,129, 44,167, 46,200,104, 7,149,208, 97,209,182,134,217,209, 44, 82,115,136,212, - 32,242,212, 90, 22,197, 72,222,173, 81, 5,152,229, 84,165,102, 69,142,188, 40,162,234, 49,205, 51, 88,163,177,156, 87,104,185, - 99,203,243, 20, 43, 94, 35,164,144,144,138, 58,249, 0,191, 8, 35,246,188, 8,113,168, 18,253,193, 0,121, 81,160,169, 43, 52, - 85, 77,147, 20, 67, 31,162,128,236, 52,134, 70,181,244,186, 36,202, 94,193,106,202, 54,146,237, 60,127, 16, 72,152,199, 0, 33, - 29, 40,124, 41,210, 60,135,213, 6,205,114,138,137, 29,224,230,123,239, 97,118,113,130,102,181,130,243,192,201,203, 23,216, 62, - 56,196,222,225, 21, 60,255,246, 41, 85,221,101, 31, 82, 0,171, 85,131, 52,149, 88, 44, 27, 12,198,125,252,224,207,127,134,135, -191,251, 10,105, 74,193, 30,205,106,133,141,157, 77,124,242,147, 31,226,193,175,190, 68,222, 27,112,150,178,224,152,202, 22,179, -203, 57, 70, 59, 3, 28,191, 58,129,177, 41,178, 44, 65,127,212,195,235, 23,103,216,218, 25,226,242, 98,137,188, 32, 34,158, 19, - 41, 86,243, 41, 38,103,151, 56,188,125, 19, 47,159, 95,224,243, 79, 14, 49, 59, 59,195, 96, 99,136,111,191,126,142, 39,223, 60, -196,191,251,239,255, 6,163,205, 17, 46,222,188,193,120,115,140, 55,175, 47,161, 93,129, 60,111,241,232,235,103,184,118,251, 0, - 87,111, 94, 65, 93, 25,204, 47, 46, 32, 92,131,182, 90,225,228,245, 17,140,174,177,119,120,128,157,131, 3, 8,149,226,252,108, -134, 36, 77, 48,222, 28,162,215, 75,177,154, 78,224, 76,139,253,195, 43, 68, 42,204,115,148,131, 1, 32,105,245,180,156, 47,176, -156, 92,192,182, 21,210, 44, 67,185,177,133,178, 44,144,100, 25, 31, 34,136, 22,207,186,106,177, 92,173,176, 90,158, 71, 84,176, -209,154, 45,161,212,173,212,117, 3, 99, 93, 76, 46,164, 60,121,206,195,118,224, 81,166,135,148, 38,122,214, 67, 81, 75,151,152, -142,212,170,206, 54, 36, 72, 80,186, 22,118, 65,251, 98,230,114,203,176,127,228,245, 22, 31, 58, 41, 19,236,116,171, 73,107, 81, - 12, 80,150, 37,156,167,201, 83, 44, 44,172,103,207,118, 13,107, 53,172,213,113, 55, 25,198,218,221,216,157,138,147, 48,150, 94, -107,245, 24,188,226,248,226, 74, 58, 53, 48,143,160,195, 8,156,162, 76,201, 30, 42, 65,175, 89, 34,129, 74, 68,180, 95, 97,109, -175, 25, 52, 52,129,251, 32,101, 71,174,116,222,147,115, 39, 0, 61,120,117,160, 98,182, 60,141,154,243, 34,103,161, 90,224,151, - 91,148,189,146,116, 11,220, 92, 56,231,177, 90, 46,153,191,207, 64,153,192,240, 94,203,255, 14,246,184, 78,231,208,237,197,229, - 26,120, 7,107,233,106,161, 96,203, 50,181,134,198,117, 17,134, 67,218,154, 12,186,173, 99, 76,167,146,178,163,172,241,138, 52, -229,177,121, 24,221, 59,211, 21, 30, 1,172,165, 91, 29,179, 1,156, 37,146, 32,161,136, 17,133, 93,173,182,200,242,188,139,121, - 53, 62,158,181,130, 11, 16, 10,240,242, 72, 21,253,158,195, 20,192,121,143, 60, 85,112,150,132,135, 33,130,217,219, 54,174,106, - 99,250,156, 49, 28,222,101,162,227,130,120,234, 18,206,120, 8, 56, 86,210,119, 14, 6, 90,173, 72,250,103, 82, 2,222,174, 5, -209,240, 10,196, 91, 8, 72, 88, 39, 32,133,139,221, 62,173,153, 77,196, 0,135,139, 62,124, 78,195,115, 27,147,232,188,130,148, - 62,238,216, 3, 86, 88, 8,188,197,247, 87, 82,174,165,230,137,104, 9,244,111,193,147,216, 22,168, 40, 29, 53, 56, 45,131,251, -193,175, 81,231,148, 74,144, 56, 38,192, 9,176,220,158,113,124, 20,210, 98,226,190, 77,169,132, 71, 80,129, 8, 69,244, 29,120, - 17,121,190, 33,254, 45,120,239, 22,154, 42,112,195, 59, 54, 82,172,115, 32, 75,162,224,180,231,206, 90,163,169, 53, 84, 42, 25, -176,210,137, 13, 72,225,219, 98, 54, 93, 97,103,119, 11,179,201,140, 39, 11,157,112,143, 58,202, 0,136, 48,200,178,156,247, 11, -172, 4, 79, 19, 88,227, 88,236, 99,225, 28,125,184,179, 34,133,209, 54, 10,129,140, 49, 28,218, 66, 80,126,239, 29, 67,110,104, - 44,233, 61, 96, 53,121,118,235,170,226,174,191,142, 94, 95,239, 8, 44, 67,169,107, 36,238,217,222, 43,209, 54, 58, 38, 36, 25, - 75,254,126, 99, 91, 0,130, 39, 4,196,134,150,140,185, 93, 45,150,200,242, 12,121,145, 17,117, 45, 85, 72,179, 2,121, 94, 64, -183, 13,234, 21,141, 89,133,148,104,235, 22,173,104,121,111,101,227, 97, 35,149, 68,154, 23, 48,203, 21,179, 3, 90, 56,107,104, - 61, 81,116, 0, 14,193,158, 76, 56,135, 52, 79, 33,141,131, 20, 45,206,143,143,176,177,187,143,141,109,139,203,179, 75, 56,231, - 49, 61, 59, 69, 59,220,192,187, 31,127,128, 55, 79,159,195, 24, 67,248,214, 84,161, 28,244, 81,207,231,168, 42,139,254,160,192, -221,143,223,199, 98, 78, 57,238, 69,191,135,163,103,175,112,227,238, 77,108,238,190,134,214,142, 47, 53,131, 86,107, 84, 75, 10, -191, 25,244, 19, 76, 39,115, 20,195, 45, 72, 37,145,101, 10, 23,167,115,140, 54,122,204,246,151, 56,126,122,140, 52,207,224,189, -193,120,123, 19,175, 95, 94,226,214,123, 55,241,230,201, 19,108, 95,217,197,252, 98,130, 95,252,221, 63,226, 71,127,254,167,184, -117,247, 22,230, 23,167, 72,210, 4, 23, 23, 53, 22,149, 66,181, 56,199,104,220,195,181,219, 87,113,120,115, 31,198,120,156,190, -124, 13,216, 10,139,233, 20,231,167, 19, 12,183,182,113,247,250,199, 16, 82, 97, 49,175, 97,150, 21,178, 60,193,112,212,199,238, -254, 6, 46,143, 79,176, 90, 44,176,185,179,133, 36,203,128, 96, 9,229, 64, 34,219, 54,232, 21, 9, 54,110, 94,141, 74,224,166, -105,161,181,197,124, 81,161,174,102,168,150, 21,103,110,147, 86, 33,192, 52,168,195,167,203, 94, 37, 9,154,186,165,221, 43,103, -159,219,224, 85,214, 52,134,164,194, 90, 5, 36, 70,180,161, 5,109,135, 84,138,120,240, 12, 14, 9, 26, 18, 99, 44,138,178, 32, -224, 7,239,229,169, 80,102,255,185, 34, 61, 71, 86,230, 81,253, 75,107,151, 20,206, 26,244, 6,125,128,133, 99,193, 58, 20,242, - 22,156, 53,168, 86, 43,178,237,213, 77, 20,200,134,142, 23,222,161,109, 26, 38,104,201,248,186, 67,179, 32, 21,189, 38,163,117, - 12, 84, 2,186, 84,172, 0, 13,161,195,152,187, 39, 14, 12,161,144,154,206,126,166,216, 74, 70,122,152,110, 39,239,177,150,120, -198,251,218, 96, 77,179,140, 99, 14,132, 47, 26,155, 34,166,151,245,250, 61,214, 8, 40,206, 51,112, 76,205,108,145,166, 25,166, -151, 51,172,150, 43, 98,114, 4,136, 84, 93,189,149,163,225,157, 3, 36, 40, 9, 50, 81,156, 88,198, 28,114, 15,186,156, 24,170, -163,184, 43, 91,199,136, 66,120, 62, 75, 85,244,178, 7,187, 91,232,168,215,113,166,148,110, 40, 98,142,184,227,240,143, 32,116, - 12, 90, 29, 37,137,211,193,115,100,238,230, 5,180, 53,220,200, 72, 78,225,203,216,162, 40,226,110,220, 57, 27,221, 56,158,221, - 74, 41,175,215,130,235,192,177,151,155,238, 63,186, 76, 77, 75,103, 97, 81,228,244,179,120,139,162,204,136,131, 98, 44, 23, 83, - 65, 72,230,227,179, 70,190,249, 52, 54, 82, 73,146,194, 90,205,147,138, 46,205, 14,222,194, 5,113, 89,152, 6, 72, 1,153,100, - 16,214,172,133,226,144, 70, 72, 40, 5, 8,187, 38,100, 22,252,217,180,220,140, 0,222,201, 40,214, 4,115, 0,156, 12, 43, 43, - 5, 33, 44,132, 80,104,181,137,252,123, 99,108,244,196,147,246,201,112, 17, 69,177,197,225,247, 73,207,175,136, 57,247,222, 3, -206, 4,248, 12, 89, 17,130,115,128,116, 6, 4,164, 33, 71,140,163,148, 54,149, 8,154,213, 39,221,232, 13, 97,231,230, 61,164, - 15, 42,111, 17,247, 71,222,123, 8,235,129, 64,161, 10,249,220,206, 34,168,233,179, 44,133, 51,170,163, 37,113,122,142,135,236, -198, 43,236, 45,180,206, 66, 88, 48, 27,221, 71, 27, 76,194, 30,242,231,143,159,227,238,251,239, 96,122, 57,101, 15,166,141, 95, - 67,200, 20, 42,138, 51,168,235,166, 49,132, 66,198, 97, 46, 89,158, 98,181, 88,161, 63,236,147,152,135, 71,119, 97,164, 13,239, -217, 62,195, 0,138,150,162,251, 66,190,185,148, 2, 22, 20,145,218,182,148,150, 70,149, 61,117, 69,205,146,108, 97,117,181,138, - 62,214,160, 66,238, 15,122, 16, 42, 65,206,226, 53,207,227,149,106,213,196,162,164,109, 53,148, 2,234, 21,193, 55, 22, 51,138, -183,205,242, 12,240,217, 91, 28,128,254, 40, 69,214, 50,152,134, 1,253,206,104, 24,103, 33,144,211,123, 40, 4,188,162,241,152, -247, 22,153, 32, 31, 38,249,252,155, 40, 80, 76, 51, 5,109, 57, 39,216, 9,180,173, 65, 46,232,161, 59,125,253,134,163, 65,119, -112,246,230, 13,132,243,168,231,231, 56,106, 43, 92,185,121, 19,211,179, 35,204,231,148, 24, 87,175, 42, 36, 89,138,233,217, 9, -202,222, 53,244, 7, 5,198, 89, 14,163, 61,132,202, 32, 96, 49,157, 44,112,243,254, 93, 60,248,245, 31,144, 42,131, 52, 81, 88, -204, 87, 24,173,106, 24,221,226, 69, 75,221, 77, 82, 90,228,101, 1,239, 29, 54,182, 70, 12, 57,242,104, 86, 11,228,253, 18,199, -207, 95,226,221,143,222,195,249,233, 20, 91,123,219, 24,143, 82,124,247,124,142, 27,119,111,225, 63,253, 47,255, 59,190,255, 39, -127,132,207,126,250, 3,232,213, 28, 16, 9, 12, 36,142, 79, 39,184, 56, 57,193,253, 15,111,225,224,112, 7,227,173, 17, 86,243, - 21,102,151, 51,152,118, 73,100,192,164,192,157, 15,238, 99, 99,123, 12,163, 45, 46, 47,230, 48,198, 34, 77, 5,182,118,182,176, -189,183,129,233,249, 5,178,162,192,245,119,182,162,162, 58,205,211,255,143,171,247, 90,146, 44, 75,179,243,214,150,231, 28,151, - 33, 82, 87, 86,101,169,238,153, 22,104, 12, 6, 52, 26,134,164, 25, 73,227, 21,223,135, 79,192, 55,162, 25, 13,102,184, 0,134, -128, 17, 36, 48,152, 65,115, 68,203,170,169,233, 18, 41, 34, 67,135,187, 31,177, 37, 47,254,127,239,227,217, 87,101, 93,157,149, - 17,238,126,124,239, 95,172,245, 45, 72, 1,184,113, 68,140, 45,140,109,208,247, 35,118,251, 1,135,221, 30,253,126,143,105, 28, -225,167,129,199,114,137, 39, 44, 97,190, 48,145, 41,225,144,215, 35,212, 93, 57, 62,236, 21,146, 32, 50,150,138,153, 9,143, 12, - 35,161, 13,220,108,133, 82, 10,146, 49,206,154, 47,191,130,239,164, 3, 85, 48,157, 78,207, 4,174,148,209,117, 13,198, 97,224, -191,131, 70,154,182,105,224, 61, 29,212, 77,219, 97,177,108,121, 2, 0,134,219, 68, 40,190,152,202,101,120,240,129,105, 91, 84, -224,212, 16, 18, 46, 0, 98, 8, 53,138,152, 70,243,185,170,131, 73,156, 70,152,224,162, 5, 17, 0,148,225,248,229,234, 80,153, -199,229, 69, 41,126,108, 65,154, 87,136,242,104, 13, 71, 23, 90, 96,134, 70, 8,137,247,225,243, 25,144,145,224, 60, 51,197, 3, - 31,198, 60,153,107,154, 6,221, 98, 69, 52,190,213,154,119,200,168,220,120,239, 29,250,195, 1,198, 6, 6,245, 68,182,238, 2, -253,161,167,166,160, 80,235,152, 14, 87,214, 25,180,126, 48,236,112,225,125,108,136, 48,198,242,132,101,102,126, 23,254, 55,157, -175,150,242,235,149, 98,139,155,172,160,156,146, 32, 38,165,160, 70,132,119,213, 69,253, 78, 59, 93,226,164,199, 20, 89, 11, 65, -235, 13, 90, 85,204,148,204, 98,165,205, 5,159, 42, 52,133,201,104,214, 0, 40, 10, 27,209, 90,145,186, 93, 11,126, 93,156,162, - 25, 35, 36, 68,101,255, 39,240, 5, 28, 34,218,206, 16, 83, 67, 42, 72,173,234,148,151, 56, 13,116,113, 42,118, 26, 72, 41,160, - 68,177,223,209,232, 92,208,104,134, 68,194, 69, 64, 89,187,105,162, 97,230, 72,122, 49,205, 5,169, 96, 72,145,214, 2, 62,203, -138,222, 77, 33, 67,105, 75, 58,143, 84,200,161,186, 78,107,138,112,178, 52,104, 41, 81, 39,174,164, 68,150, 26, 50, 39, 58,139, - 83,166, 16,158,148,106, 67, 89,115, 63,114,162,133, 70,138,208,122,158,154, 86,234, 99, 76,200,130, 24, 21, 41, 1, 9,128, 98, - 65, 92,206, 71,216, 96, 33,230,245, 66,113,164,241,138, 74,131,171,239,242, 38, 80,116, 96,248, 32, 23,183, 8,174,138,237,128, -118,250,164, 10, 87, 66, 64,113,252,104, 76,164,226,115,211, 4, 99, 69,245,241, 89,107, 48,241, 94,120,232, 71, 44, 86, 93, 5, -253, 39, 49,251, 94,179,226, 67,136, 71,226,130,191,184, 49,122, 64,140,216,239, 39, 88,107,248,226,156,147,157,192,185,208,222, - 5,246, 84,199,202,142,143,145,138,141,178,119,161,177, 9, 21, 38,110,242,213, 62, 64, 44, 94, 1, 63,121, 74,155,211, 18,158, - 39, 9, 37, 56, 70,243, 84,129,198,147,116,225, 19, 27, 89,114,215,238,171, 87,125, 26, 70,126,160, 51,198,190, 71,211,117,112, -166, 40,157, 45,140,149,104,186,134, 33, 29,116, 8, 78, 28,125, 74, 59, 83, 78, 45,243,212,177,173, 54, 43, 44,150, 29,130, 44, -137,116, 13, 78, 31,119,240,147,195,216,247,232, 15,125, 77, 63, 34,174,125, 32, 27, 73,221,233, 1,214, 90, 24, 99, 48,244, 67, - 85, 53,187,201, 85,186, 81,241,237, 78, 83,100,112, 71,134,235,239,113, 57,246, 56,127,250, 28,211,225, 30,253,238, 1, 72, 17, -223,126,221,227,163,207, 94,193, 52,123,236,247, 35,194, 52,160, 93,172, 49, 13, 87,248,254,155, 31,240,242,179, 23,120,250,226, - 28,206, 69,220, 92,247, 88,158,108,241,246, 15,223,227,229, 23,159, 98,181, 89,227,230,102, 15,239, 52,250,221,136,221,253, 30, - 90, 43, 28, 48, 32,103,144, 26,126,213,225,176, 27,240,248,217, 25,222,190,190, 69,219, 53, 8, 83,198,176, 63, 64, 91, 13,101, - 45, 32, 45, 94,126,186,197,215,127,251, 43,252,233,159,255, 20,127,243,127,253,191,248,111,255,167,191,192, 39, 63,254, 18,211, - 97,143,119,111,238,113,191,243,120,253,135, 31,160,224,241, 63,252,207,127, 6,129,132,110,217, 98,247, 48,224,254,118, 15,153, - 39,172, 54, 27,216,182,173, 99,241,235,247,183,216, 63, 80,167,181,217,116,248,228,243, 23,117, 42,243,232,249, 83,116,203, 14, -227,232,209, 31, 70,184,209,225,230,242, 30,187,251, 7,244,251, 3,134,253, 0,239, 60,166,113, 64, 78, 30,195,225, 1, 57, 6, -158, 56, 77, 53, 2,181,140,162,132, 44,156, 1,154, 52, 57,239, 97, 12,169,133, 41, 56, 36,215,231,149,116, 29,244, 28, 78,227, - 4,109,169, 96,211,204,224, 78, 41,161,177, 22, 67, 63,144,253, 48,151,238,151, 44,129,213, 34,199,150, 74,173,116,141, 35,142, - 33, 30,197,118,210, 74,171,109, 91, 52,109,139,197,178, 67,219,181,213,238, 38, 4, 71, 10,167,128,187,251,253, 17, 38,116, 78, -100,243,204, 74, 40,177,160, 33,149,174, 55,179, 8, 44, 51,141,107, 22,129, 42,221,212,215,130, 42,180, 69, 77,151,211, 60, 34, -166, 34,136, 41,117,188, 94,192, 31, 89,184, 50,139,120,149, 54, 85, 8, 92,132,139,117,119, 91, 44, 65, 49, 32,242,196, 36,114, - 32,139, 98, 93,135, 84,196,222, 88,173,215,244,189, 53,182, 38,210,165, 24,145, 66,198, 52, 77,184,191,187,163, 85,101, 37,161, - 25,140,195, 72, 65, 67,253,129, 35, 63, 69, 37,143,165, 28,171,152,184,124, 30, 37,243,162,140,112,201, 14, 76,141, 82,133,222, -240,186, 32,241,228,164,240,241, 82, 34, 71,145,146,146, 24,250,154, 50, 23,104, 31, 78,136, 85,142,193,129, 64,164, 66, 49, 49, -172,138,159, 47,210, 33,208, 77, 82,206, 61,173, 52,119,248,244,204,106,166, 19,166, 44,184, 35, 38, 11, 96,113, 97, 28,179, 67, -138, 82, 30,252,243,149, 52,252,249,104, 30, 27, 39, 76, 35, 21, 17,218, 40, 70,115,163,114, 3,102,192, 24,145, 67,193,197, 14, -137, 4, 75,193,146, 56,243, 61, 34, 75, 32, 50,255,132,138, 86, 82,179,155,198,206,186, 4,105,233, 48,228, 98, 84, 32, 33,167, -130,234,157,121, 32, 66, 17, 11,210, 92,209, 0, 0, 32, 0, 73, 68, 65, 84, 40,168,116,197,200,169,126, 70, 74,155, 58, 97,211, -182,129,159,166,163, 2, 17, 31, 62, 99, 60,185,150, 66, 66,104,126,118,153, 49,193,162,129, 35,148,179, 68,202, 17,170, 0, 98, - 69,230,201,120,170,218,132, 98, 47,167,207,111,246,204,211, 84,157,238, 84,109, 45,161, 38, 67, 8, 60,134, 5,231,206,134,163, -202, 64,242,200,196,179, 73,128,130, 3,188, 39,235, 73,102,192, 68, 78, 9,210,170, 15, 10, 1,173, 53,188,208, 80,138,108, 54, - 25, 2, 67, 47,224,117, 64,203,163,189,196, 22, 14, 34,162,137,202, 56,255,160,160, 16, 25,187,251, 61,150,139,134, 47,161,128, - 16, 19,220,228, 96,173,229, 47, 74,169,146,168, 26, 78,137,126, 79,169, 36, 2,199, 59,122,231, 57, 22, 54, 31,101,169,139, 26, -202, 98, 44, 21, 9,129,115,149,181,150, 92,105,129,129, 54,165, 58,231, 56,188, 80,166, 24,185,174, 30,202,174, 91, 73, 81, 83, -239, 98,136, 80, 42, 98,228,148,171,195,174,135, 54,148,149, 94, 94, 95,129,141,108, 78,183,240,147,163, 64,149,126, 64,191,239, -113,127,123,139,135,219, 59,172,182, 43, 40,109,176, 88, 46,234,231,178, 88,175,177, 92,175, 48, 49,154,119,154, 8, 7,217, 68, -139,204, 65, 27,198,218, 58,166, 90,174, 55, 8,193, 49,221, 74,214, 81,184,109, 26, 76, 35, 59, 5, 4,117, 78, 57, 38,196,112, -192,119,247, 55,216, 62,126,142,229,201, 41,174,222,188,134,214, 10,255,244,235,223,224,228,201, 11,172, 54, 27, 12,123,192,141, - 14, 39,143, 30,225,187,175,254, 17,111,190,211,144, 34,227,197,167, 31,225,250,106, 15,219, 44,176,187,189,197,111,126, 57, 96, -123,186,193,238,110,135,110,189,198,106,187,196,254,126,143,237,217, 26, 55,151,183,208, 90,225,197, 39,207,160, 20,192,250, 77, - 0, 2,251,135, 30, 93,103,240,237,111,191,194,207,255,213,191, 68,127, 8, 88,111, 23,112,253, 1,219, 71,231,184,121,119,129, - 63,251,239,254, 28,186, 93,227,221,155,107, 92, 95,238,240,240, 48,225,225,230, 26,175, 62,123,140, 23, 31, 63,197,197, 15,239, -240,248,163, 39,184,185, 62,160,237, 26,156,157,117,216,156, 62,165,177,109,204,184,190,184,198,229,197, 29,114, 22, 88,174, 23, - 88,173, 58,124,241,211, 79,177, 92, 47,113,115,121, 11,239, 19,190,255,246, 2,183, 87,119,216,221,221,243,151, 57, 96,234, 7, -238, 78, 9, 98,145, 64,150,203,232, 7,120, 55,206, 94,100, 41,107,215, 88,114, 9, 50,128,166, 93, 48, 62, 57, 33,231,192,145, -197,182,142,207,137, 52, 72,226,155, 12, 1, 31, 18,101,151,139,162,204, 38, 42,100, 1,107, 40,163,107, 87, 72,194, 84,205,227, - 73, 13, 31, 34,218,150,132,122,162, 82, 26, 21,180, 46,105, 84, 29,132, 36,177,155,146,170,138, 90, 37,239,254,156,115, 24, 14, - 7,196, 64, 98, 80,228, 8,165,200, 91, 79,221, 92,226,238,133,214, 89, 5, 0,165,181,134,115, 99,181, 96,249, 92, 34, 36,105, -109, 37,143, 18,173,128,121, 63, 92, 19,197, 56, 57, 82, 74, 73,140,108,100,142,247,172, 58,246,185,227,230,192,147,152, 18,192, - 63,187,172, 52,170,247,158, 47,198,156,104, 98, 34,133,128, 79, 9, 74, 25, 72,101,171, 47,222, 48,114, 84,107, 11,165, 12, 63, - 43,116, 54, 4, 63,193, 57,138,163,165, 48,168,150,132,188,156, 19,225,125, 96, 82,223,200,187,111,218,187,166,163,216,211,154, -170, 8, 90,189,137, 36,185,243, 47, 69, 81, 98, 87, 15,135,206,240, 57,163, 53,185, 94,170,128,140,197,106, 37, 99, 27, 72, 85, -232,150, 99,168,224,153, 44, 50,148, 50, 16,130,173, 84,145,156, 52, 57,122,218, 55,179, 32, 50,184, 80, 89, 2, 50, 39,100, 97, -170, 53, 45,231, 50, 14, 39,245,119,228, 11,204, 52,244, 76,210,234,136,220, 97,193, 83,129, 8,134,239,216,198,242,103,153,234, - 68, 88, 84, 93, 86,174,122,141, 66, 83,203, 41, 67, 25, 5, 1,134, 14,153,130, 41,201,176,141,133,131,175, 64,150, 26,199,155, - 18,197,129,131,117, 24, 92, 36, 70, 70, 33, 43,163,144, 56,232,133, 86,198, 9,137, 39, 70,199,208,164, 82, 72, 21,192, 16,253, -222,168,105,137, 82, 42, 4,231,232,189,151,100,195, 46, 80,153, 20, 8,186,230,189,175, 74,248,153,149, 34,234, 58,123, 14, 11, -162,201,138, 49,134,248, 47, 49, 66, 49,251,159, 88, 10,153, 39, 33,137,155, 93,207, 80, 52, 1,165,242, 7, 22, 77,237,216, 74, -165, 89,174,111,172,161,180, 31, 99,216,155, 78, 74, 64,239, 2,135, 22,160,254,114, 52,174,214,140, 89,101,108, 99, 54,213,163, -170,141,194, 48, 36,216,198, 34,165, 0,197,196,170, 20, 35, 4,203,242, 37,239, 26,180, 38,225,219, 52, 57, 6, 33, 72, 14, 80, -201,117,108,239,198, 30,167,167,231, 53,240,126, 14,150, 79,117,140, 81, 70,229,227, 48,161,233, 26,116, 11,226,197,155, 70,195, - 79, 84, 81,250, 41, 64, 45,216,223,202,123, 11, 74,161, 42,169, 77, 51, 24, 97,134, 36,228, 15,176,173, 82,203,218,117, 37,126, - 8, 83,244, 8, 62, 85,255, 33,253, 46,138,119,117, 84,113, 66, 0,211,224, 56,103,222, 99,232, 73,165,233, 28,145,227,172, 49, -188, 87,164, 11,123,181,217, 98,181,217,176, 45,131,184,209,253,161,135,159, 28,129, 39,186, 6,198, 88,180,203, 14,221,122,133, -197,122, 5,129,132,135,187, 29, 0,192, 79, 19,220,228, 56,253,140,132, 45,125, 63, 17, 61, 73,208, 62,116,236, 71, 76, 99, 64, -240,229,119, 6,144, 3,220, 56, 85,177,135, 64,198,237,219,239,112,111, 23,120,254,201, 43,220,188,249, 30, 41, 12,184,252,254, - 27,220, 47,206,240,252,213, 11, 12,247,215, 24,199,132,213,102,133,239,126,247, 43, 56,247,167,232,247, 3,158,127,250, 18, 63, -124,123,133,229,102,139,203, 55,239,176,220,110,177, 88, 46,106, 40, 71,100,142, 0, 50,251,124,207,182, 24, 15,123,156, 61,218, -226,230,114,135,229,170,197,254,254,128,171,215,111,160,173,129,233, 22,232, 15, 19, 94,125,118,142,175,254,238,247,120,252,226, - 41,214,219, 53,238,119, 1,253,253, 1,111,191,191,192, 56,102,216, 70,225, 95,254,197,207, 48,246, 61,222,189,126,143, 71,207, -159,226,176,119,208, 90,226,228,164, 97,170,159,192,197,235,247,120,184,221, 35,102,137,205,217, 41, 22,203, 22,235,245, 2,143, -158,159,227,176, 59,224,219, 95,254, 14,247,183, 15,216,221, 61,224,246,253,123,236,239,110,233,128,230,232, 81,201,112, 15, 90, -201,104,100,112,158,122,182, 80, 12, 74,145,162, 8,101,216,154, 34,230,110,145, 10,106, 5, 68,202,123, 46, 16, 35,197,188,117, -109, 40, 36,163,116, 71, 74,167,154,137, 94, 38,106,249,232,153, 1, 91,200, 74, 33, 90,104, 84,164, 90, 38,221, 76,140, 9,157, - 49,104,154, 6,107,107, 42,179,186, 8,216,220,228,144, 83,198, 52,141,149, 80,152, 18, 77,225,202, 40,209, 90,141,105,138, 85, - 1, 76, 69, 1,191, 30,246, 28, 11, 8,208, 93, 70,239,141,177,162,142,153,173, 53,224,218,189, 42,210,101,205, 72, 23, 71,145, -153,220,189,234,178,175, 21,208,138, 58,177, 34, 40,203,220,249, 10,222,205,231, 35,232, 7,241,235, 19,119,159, 37, 88, 72,214, -179, 76, 27,203, 66, 59, 0, 66,207, 94,119, 89,224, 47, 69, 68,150, 17,188,171,104, 79,199, 54,189,146, 65,223, 52,246, 8,231, - 74,231,200,225,112,168, 12,111,121,196,188, 7,168,161,192, 81,252,169,136, 51,130,183,232, 16,102,107,161, 98,133, 54,152,250, -105,171,119,158, 34, 67,233,156, 52,214, 84, 33, 34,216, 94,149, 18,143,169, 69,174,169,102, 36, 58, 20,144, 66, 85,161, 52,162, -231, 78,182,132,180,144,216,139,248,254, 52, 49, 40,246,184,156, 34, 79, 16, 20,180,149, 60,254, 78, 16,138,108,209,200,128,182, - 10,193,211,153, 47,165,132, 50, 22,193,121,100, 4, 72,173, 88, 65, 63,175, 66,105,218, 26, 25,191,157, 16,249,252, 87, 42,215, - 46, 93,107,158, 68, 40,197,141, 26,224,125, 68, 46, 0, 50,246,236,135, 16,121,202, 32,235,164,166, 12,116, 18, 23,193, 53,237, - 46,230,202,189,143,172,163, 40,147,232, 66,232, 11,172, 97, 41, 43,158, 24,242, 81, 6, 65,172,108,129,148, 2, 39,197, 50, 75, - 5,224, 21,158,134,247,145,237,123,243,119,151,220, 10,166, 18,233, 50,138, 11,193, 80, 1, 17, 73, 59,144, 69, 98, 91,158,172, - 19, 85,169,115, 45,154,115, 74,140,182, 13,208,197,158, 85, 60,222,206, 49,249, 76,113,104,201, 52, 33,248, 63, 34,146,165, 34, - 32, 83, 20, 15, 90, 63,116, 64,107, 38,159,177, 48,129,186, 96,170,114,232, 75, 28, 17,130,135,156, 36,251, 41,231, 36,180, 25, -230, 64, 15, 76,230,160, 3,197, 23,168,119, 35, 98,146, 21, 60, 81, 0,246,137, 1, 24,222,147,213,166,120, 28, 41, 14,214, 64, - 52,134, 69, 43, 17, 50, 68, 34,173, 69, 18, 18, 25,203,161,244, 85,185, 31,107, 97, 80,184,213,130, 89,245, 36,196,137, 71, 41, -110,168,144,142,161, 31,129, 76, 21, 84,138, 12,144,129,128,144,134, 49,180,220,157,241,106, 97, 28, 28,165,177,197, 4,200,132, - 24,136,212,229,198,137,132,127,252,165, 44, 35,186,197,106,193, 74,123,139,211, 71,139,186,207, 87,146, 82,217,250, 7, 18, 29, -153,134,210,222, 54,167,167, 16, 34,195, 79, 35,134, 67,143, 20, 61, 70,231, 42,220, 33, 5,178, 37,122, 71,220,230,205, 73, 11, -207, 93, 88,191, 31, 32, 16,121,204, 51, 63,220,180,143,186,199,254,238, 22,143, 95,190,130, 10, 7, 92, 95, 92, 32, 76, 19,190, -233, 7,124,242,229, 39,120,184,122,143,118,185,133,209,223,227,135,175,191, 66,206, 95,242, 14, 75,225,244,233, 99,220, 94,221, -225,230,226, 10,219,243, 83,244,135,177,226, 49, 11,199,251, 71,255,236,199,152, 70, 71,201, 74,138,130, 78,250,155,123, 52,173, -193, 87,127,255, 91,252,248, 95,252, 2,247,119, 61, 62,250,120,139,225,208,227,147, 31,127, 6,109, 44,174,175, 15, 80, 2,248, -238,171, 63, 32,201, 22, 79,158,111,113,254,228, 4, 15, 55,183,212,117, 51, 55,255,229,167, 79,177, 61, 89,224,250,253, 45,118, -119,123, 42,234,164,129,180, 11, 60, 92,221,225,250,226, 26, 79,158,159, 98,185,252, 8,215, 23, 87,120,253,135,215,184,187,188, -197,221,205, 45,134, 67, 79, 36, 66, 86,174,131,199, 95,137,225, 17, 21,123,156, 5,132, 50, 80, 85,201, 74,207,162,150, 26, 41, -199, 35, 31,172, 34,215, 1,219,171, 20, 43,131, 75, 84,104,211,118, 71,208, 21,193, 98, 36,218,243,133,224,106, 94, 58, 93, 14, -169, 6,209,144,203,129, 39, 51, 41, 87,107, 81, 25,161,119,139, 14, 90,179, 99,163,177, 85,121,238, 38,178, 80, 14,253, 1,253, -190,231,221,190,130,181, 22, 94, 42, 58,184,185,144,214, 86,177,230, 69,215, 52,169, 24,249,162, 46, 69, 0,243,185,173,108,216, - 18,102, 48, 13, 3,239, 25,105,231, 90,220, 55, 37, 1,173,168,156,107,152, 13,135,215,148, 32,151, 84,245, 31,212, 52, 80,119, - 26,102, 81, 20,251,136, 99, 76, 20, 5,203,149,141,168,148, 46, 48, 23, 34, 49,173,142,241,171, 42, 67, 66,162, 81,115, 70,115, - 17,133,121,239,160,179, 66,138, 84,232, 96,185,224, 44, 11,234,172, 41, 89,209,162,105,104,207, 75,199,145,192, 56,244,216, 31, - 30,102, 7, 78, 58,142,176,206, 71, 8, 87,238, 2,203, 8, 55, 69,222,187,131, 59,184, 80,109,112, 5,124, 82, 4,135,130, 51, -210, 13, 79, 73,162,247,220,169,231,122,142, 74,145,171,133,173,228,124,231, 28,161,164,174,192,147, 50,166,207, 57, 64, 10,205, - 23, 91,100, 17,104, 65,175, 22, 53,182,168,201,106, 74, 0,201, 71, 36,161,144, 65, 83, 27,234,142, 34,166,222, 67, 40, 93, 95, -159,119,174, 66, 96,104,237, 9, 52,204,118, 87,140, 28, 78,124, 22, 32, 39,216, 70,147,202, 93,146,218,157,130,191, 60, 12,199, -186,166,148,224, 39, 79,186, 2, 6,136,101, 46, 14,140, 85, 85,243,144, 51, 7,191,240,132, 6, 49, 31, 45,151,115,109,204,106, -238,130, 80,140, 29, 47,133,119, 89, 57, 71, 94,163, 49,219,132,161, 67,168,251,110, 6,134, 37, 58, 27, 4,143,214,139, 48,181, -236,250, 9, 48, 83,224,110,199,244, 67,210,152, 20, 97, 94, 12, 97,142,161, 45, 23, 62, 74,158,123, 96,125, 66,154,129, 55,244, -169, 67,151,125,178,102,145, 66, 8, 52,166, 70,152, 57,202,211, 56,161,109, 45, 66, 72, 20,146, 50,121, 68,149,142, 18, 98, 34, -229,125,115,197, 67,234,121,122, 96,218,182,129,155, 38, 40, 77,138,241,226,203, 12,129,224, 46, 21, 48,161, 36,178,144, 76,139, - 82, 53, 73, 40, 8,218,149,175, 54,180, 63,116, 46, 64, 42, 13,239, 93,237,240, 1, 93,105, 88,101,196,162,149, 68,110, 8, 18, - 35,164, 96, 70, 59, 29,154,182,149, 21,209,167, 25, 1, 43,165,168,130, 31, 89, 2,103,184,178,170,164, 33, 14, 27,144,146, 70, - 78,245, 50,202,100, 87, 35,106,147, 70, 10, 35,124, 8,104,187,150, 15,101, 89,233, 81,136,116, 88, 53,141,101,214, 48,141,119, - 34,119, 55, 33, 4,142, 75,141, 21,121, 11, 0,211, 52,212,160,142,166,165,195,121,185, 94, 64, 89, 11,203,255,155,186, 49,202, -240,141,137,178,201, 55,103,103, 88,109,183, 0, 18, 14, 15,123,244,135,129,248,222, 46, 50,134, 86,241, 4,129,188,188,221,162, -133,146,148, 50, 53,197,192,106,253, 80, 61,173, 57, 0, 70,143,120,247,135,223, 99,177,125,134,103,159,126,142,135,171, 11,164, -176,195,213,219,247,120,250,241,115, 76,135, 61, 94,253,201,143,241,219, 95,254, 29,222,124,247, 26, 74, 73,188,252,252, 37, 14, -251, 17,155,211, 45, 30,238, 30, 96,187, 14,125,239,232,253, 73,212, 86, 45,214, 29, 62,251,147, 87,184,188, 60, 32, 37,218,219, -110,182, 11,188,185, 63,224,205, 63,254, 30,175,254,228, 75, 8,179,192,201, 73,139,237,201, 18, 15,247, 3,156, 23,244, 94, 55, - 26,127,248,253, 15,128, 94,226,227, 79, 30, 97,177,176,232,239,111,241,232,201, 25, 67, 36, 44,158,190,120,132,118,209,224,230, -242, 14,211, 24,113,241,230, 26, 23,111,111, 49, 77, 30, 34, 7,156,159,175,240,211, 63,251, 2, 82, 41, 92,188,126,143,171,183, -151,184,191,185, 33, 69,123,160, 47,141, 49, 10, 57,105,136, 64,196,192, 2, 59, 17, 82, 81,167, 34, 5,140,182,136, 9, 64, 18, -149, 17,159,217, 62, 35, 25, 41,153,145, 89, 37, 91,200, 96,146,211,185, 72,220,216, 46, 90, 22,106,169,122,252,208,133,205,150, -160,152, 48,185, 0,114,236,168, 90, 8, 10, 33, 97, 27, 34,145,117, 93, 7,219, 90,116,139, 14,203,213,146, 99,117,153, 32,199, -138,237,254, 48,192, 57, 7, 63, 57,236,247,123,210,116, 48,238, 52,103,160, 91, 16,237,206, 54, 13, 57, 43, 20,101, 20,216,198, -206,138,246, 72,235,129, 98,151, 44,201, 88, 37,125, 12, 16,236, 30, 73,112,139, 9,193, 59,140,195, 88,105,116,133,182, 22,131, - 3, 96,184,176,142,245,112, 35,171,172,224,224, 21, 85,249,226,244,157, 39,221, 14, 65,115,240, 65, 30,117,228,223,139,205,107, -148,248,101, 4,139,255,116,253,206,148, 84, 67,133,204, 59, 91,250, 14,145, 53,144,166, 87,198, 26, 40, 41,171,254,136,210,222, - 10, 3,162,161,244,188,178,110, 12, 30, 25, 25,187,135,125, 61, 35, 75, 76,105,153, 44,146,154, 63, 85,225, 97,233,202, 9, 6, - 83,176,177, 37, 47, 94,214,112,151,204,120, 86, 99,168,153,160, 61, 57, 49,242,219,214, 84,139, 26,137,184, 34, 82,244,148,248, -199,160, 18,154, 0,240,133,149, 2,227, 93,105, 18, 39, 50,137,205,146,146,140,157,165, 66,174, 96,173, 73,227, 17, 88, 4,150, -235, 26, 73, 40,193,240, 44,202, 53, 80,122,118,131, 16,194, 20,240,172,118,167, 11, 76, 1, 40,148, 63,137,110, 97,217,105, 52, -223,179, 41,206,202,247, 24, 73,193,174,141,174,147, 93, 33, 5, 68, 46,211,147, 84, 99,195, 37,128, 16, 18,223, 33,162,190,103, - 37,241, 62,213, 2, 43,147,202, 60, 82, 33, 30,156,255, 96,125, 83, 45,101, 49,113,108, 44, 5,239,240,156,171,134,156, 33,139, -170,175,226, 33, 19, 51, 94,138, 8, 52, 33, 71, 65,147,132, 18, 98, 37, 45, 21,167, 74, 81,198,189, 84, 16,108, 97,206, 50, 33, - 39, 28, 37, 46,250,234,208,160, 20,193,192, 97,109,185, 78,232, 74,128, 16,167,215,208,248,189,235,186,250, 70,229,156, 16, 51, -137,170, 10,200,101,177,236,120,150, 21,171,245,165,105, 12,239, 95,243, 7, 9, 81, 67,223,163, 91, 46,225,189, 71,199,241,119, - 66, 72, 52, 77,131,177,239,107, 7, 58, 12, 3,195,240, 5, 90,171, 25,127,135, 57,198,128,173,168,244,128, 48,211, 61, 70,140, -195, 4, 99, 12,250, 3, 93,232,178,236,126, 43,184,128,245, 1, 98, 14, 58, 9, 62,212, 46,220, 88,139,224, 2,132,149,100,135, -101,138,145,144,128,231,221, 88,137,192,179,141, 70, 12,153,247,251,162,138, 81,114,202,180,115,210,234, 40,138,111,134, 16, 64, -144, 85, 45,103, 89, 67, 47, 10,156, 33,198,132,182,109, 8,231,167, 36,119,168,145, 5, 65,137,237,121,190, 86,157, 72,168, 4, -161,152,231,228, 31, 0, 24, 15,135,154, 87, 76,204,250, 6,182,105,208,116, 45,186,101, 87, 15, 46, 90,127,100,194,151,158,103, -184,113, 66,191, 39,113,221, 56,240, 1,158, 20,191, 14,192,182, 11,104, 99,177, 92,175,112,120,216,161, 63,120,140,253, 80,249, -226,137, 99, 10,199,135,183,120, 51,236,241,236,147,143, 17,134, 59, 12, 15, 87,184,122,171,240,226,179,143, 49, 29, 90, 60,123, -249, 18,175,191,253, 30,215,151,107,172,182, 43, 52,139, 37, 54,103, 91,220, 94,223,227,246,242, 22,139,245, 18, 72, 36, 76, 20, - 82,224,249,171,143, 48,142,158,109,137,180, 71, 63, 57, 91,195, 79, 35,164, 20, 88, 63,122, 10,239, 60,206, 31,175,224,124,198, - 97, 31,107, 16,206,205,213, 3,148,237,240,179,159, 62, 67,107,105,180,216, 46, 90,244, 15, 7, 72, 99,113,182, 93,225,250,234, - 1,119,215, 15,184,248,225, 61, 14,251,129,253,245, 10,167,231, 91,156,158,173,241,244,163, 39,208, 90,226, 31,254,250, 31,112, -115,121,141,161,159, 96,173,132,214,150, 58, 57,238,128,134, 97, 36,104,132,182,180,115, 68,217, 79,107,254,119,244,204, 79, 62, - 65, 72, 77, 29, 37, 88, 13, 46, 20,132,204, 16, 50, 67,155,134,145,205, 25, 41,147,114,189,227, 66, 80, 41, 93, 67,123, 10,170, - 88,228,196, 93, 57,199, 87, 98, 14, 53,105,219,134,130, 92,150, 75,180, 29, 49, 19,202,115, 17, 88,200, 52, 14, 19,145,251,174, -239,234, 97,183, 88, 46,234,232,111,123,178, 5,242,134, 64, 78, 66, 85,157,135,226,105, 20,209, 21,195,220,221, 9, 90, 91, 69, - 31,145,114,132,159,202,184, 88,112,151,146,171,248,171,120,134, 23,139, 5, 82,106,177, 88,174,106,225, 58, 7,170,144, 96,173, -223,239,225,166, 17,146,167, 80, 4,238, 96, 37, 87,241, 8, 87,194, 98,230,162, 66,124, 96,121, 35, 63, 59, 93, 32, 41,207,232, - 81,194,240, 42, 62, 56,227,220,201,165,136,224, 39, 42,240, 16,103, 87, 12, 39,184,153, 2,156,210, 51, 12, 6,204, 60, 95, 44, - 90, 40, 45,107,167, 21, 66,194,112,232,225,188,171,187,251,200,107,141,121,205,128, 15, 80,220,115,106,216, 12,226, 58,118, 0, -120,239, 96,180,230, 75,149,211,220, 80,108,103,146, 29, 76,185, 78, 58, 88, 83, 9, 32, 81, 88, 74, 46, 74,247, 84,243,209, 1, -218,165,139,218,133,179, 29,139, 47,249,227,134, 70, 41,131, 88, 82, 42,131,103,117, 58,173, 10,163,247,176,141,169, 17,205,137, - 19, 35,115, 22,160, 56, 53, 5,109,104, 15, 46,149,132,109, 45,119,178,244,223,120, 23,208,180,166, 78,150, 38, 23, 16, 60,119, -228, 71,221,116,233,202,133,148,136,222,215,159, 7,182,123,149, 49, 62,253, 23, 18,211,228,200,223,159, 2,211,226,248, 61, 77, - 84, 52,208,253,158, 72, 28, 88, 99,111, 69,205, 51,153,198,169, 58, 14,114,204,204, 87,225, 38, 52, 83, 49, 93, 46,118, 48,158, -187,124, 31,201, 97, 64,187,243,196,175, 27, 34,215,231,220, 24,131, 44,100,157,122,100, 70,130, 67,170,242,193, 85,215, 10,233, -197,136, 4, 58,243, 21,136,163, 79, 23, 58,253,192,146,140,167,141, 49, 76, 49,163, 20,181,204,135,128,231,113, 69, 9, 9,200, -108,209, 8, 33,214, 64, 6,165, 34, 98,154,253,163,101,125, 81,190,248,222, 27,180, 12,100,137,137,170,165,178,111,179,214, 32, -120,143,166,109,107,206,114,137,243, 43, 24, 65,130,218, 73,196, 40,120,138, 16,200,230,163,233,133,134, 20,184, 42,162, 15,142, -144,150,115,212, 95, 25,183,145, 37, 99, 14,165,208, 70,206,163, 40,158, 80,224, 40, 77, 45,134, 84,247,249,229, 67, 40,241,170, -133,135,109,172, 33,117, 98, 38,112,133,115,108, 89, 73,212,133,211,254,147, 99,101, 51,160,121,151,222, 46, 90, 22,224,105, 70, -212,198,186,130,136, 33, 48,250,211, 85,129,152, 16, 2, 40, 97, 48, 85, 89, 74,234, 98,163,233,139, 24, 28, 83,178,252,136,251, -155,200,116, 58, 9,109, 27,172, 54, 43, 40, 99,209, 45, 87, 88,109,150,176,141,133,110, 21, 54, 77,135,245,233, 9,130,155, 48, -236,239,113,119,117, 83,243,157,233,181, 73,132, 0,180,171, 13,186,229, 18,110, 28, 48,246, 7,140,227, 52,163, 40, 5, 16,198, - 59,188,253,167, 1,203,211, 23, 56,123,250, 12,251,219, 27,252,240, 13,240,244,227,151,120,254,249, 23,232, 15, 61,118,183,239, -112,117,177,198,179,151, 6, 49, 83,234,216,238,238, 30,139,237, 6, 82, 36,228, 24, 96, 27,131,205,217, 22, 23,111,110, 49, 77, - 17, 57, 42,108,207, 86,120,247,230, 6,135,251, 7,188,252,241,231,184,189,233,113,126,102,113,123, 51, 97,191,223,211,151, 49, - 3,206, 39, 18, 16, 42,133,177,119,232,247, 25,167,143,182,144, 50,194,116, 75,196,224,241,246,187,215,152, 6,135,235,171, 29, -250,131, 67,244, 35, 30, 61, 90,225,228,124,139,118,209, 98,123,186,197, 56,140,248,155,255,240,119,184,191,185, 37,229,177,162, - 29, 31,144,209,118, 84, 36, 13,135, 30,214, 90,140, 33, 32, 51,246, 49, 73, 16,122, 85,146, 42, 88,242, 51,210, 45, 59, 68,239, - 43,227, 64, 86, 37, 54, 72,225,202,202,203,210,125,118,139, 69,245, 0, 23,210,163,210, 68,112,140, 12, 87, 25, 6, 7, 37, 37, - 86,235, 21,108, 75, 60,134,213,122, 5, 41,185, 8,200, 96, 20,235,132,222,123,162,191, 29, 70,190, 15, 37, 22,139, 14,155,205, -170,114,227, 75,212,104,138,101,143, 30, 49,244, 61, 59, 48, 60, 26,182, 18, 21,229,122, 74,145, 47, 25, 95, 45, 59,110, 28,137, - 72, 23, 18,243,191,143,248,227, 0,129, 93,152, 53, 95, 58, 26, 33, 4,246,187, 3,211,217,136, 30, 71,105,142, 22,106,179, 69, -140, 43, 72, 37,224,157,131,119, 14,110, 28,234,168,179,154,119,249, 59, 25,242, 60,146,167, 29,227,124, 97, 42, 77,122,129, 84, -207, 23,218,201, 10, 81, 94, 3, 77,201, 2, 59, 19,138,206,167,208, 51, 99, 72, 48, 37,161, 50, 38,222, 49,203,154,121,177, 88, -118,208,214,144,199, 60,132,202,164,232,251, 1,193, 59,178,162, 85,205,133,168,211,131,227,128, 41,173,143,245, 65,116, 78,170, -163, 34,165,120,178,115,230, 73,162, 17, 12, 17, 74,144, 44, 42,172,187, 98,190,240, 51,143,147,145, 99,141, 12,173, 9,107, 41, - 48, 50,149, 94, 99,217,199, 75, 62,231, 5,219, 4, 37,167, 1,150,160, 39, 26, 83,123, 74,192, 99, 75,163, 86, 18, 66,203,170, - 55, 42,187, 93,201,251,237,152, 40,176, 36,133, 4,109, 37,131,149, 2, 22,171, 69,189,164,164,204, 24, 7, 87, 17,188, 69,213, - 29,125,224,198, 75, 84, 87, 15, 25,155,210,124,121, 23, 75,100, 6, 33,187, 57, 59,157, 44,137,156,101,174, 52,173, 34, 50, 79, -200,164, 64,202, 18, 82,144,160, 49,213,152,212, 92, 39, 28, 36,218, 35,139, 94,113, 26,148,172,245,232,153, 41,193,248, 95,106, -148,169, 25, 77,145,242,218,131,159,234,138,162, 20,109,224, 59, 82,107, 81,109,221,164, 3, 99, 24, 81, 13, 28, 74, 92, 40,240, -231,207,235,225,130,210,157,145,238, 10, 73,228,202, 57, 41,207,138, 38,216, 65, 70,204,161,238,245,154,182,169, 10,192,182,107, - 42, 8, 99,246,147,198,250,208,171, 72,111,148,143,129,194, 78,124, 96,177, 12, 5, 91,132, 16,185,163, 16,232,186, 22,206, 57, - 14, 4, 80,240, 62,210,255,102, 91, 93,140, 9,109, 71,150, 28, 26,243, 1, 49,145, 96,163,236,135,134,126,128, 92,154,234,151, - 7, 15, 86, 76, 67, 30, 66,173, 24, 90, 97, 84,197, 48, 18, 2,145, 70, 94, 77, 99,171, 18, 82,178,165,203, 24, 85, 43, 35, 82, -178, 18,108, 70, 43,205, 15, 71,102,145,160,172, 33, 47, 49,205,213,124, 42, 79, 21, 43,227,203,232, 91, 41,226,220, 11,169,102, -191,111, 99,200, 67, 44,104,172, 3,166,213,105,173, 42, 16,134, 32, 3,162,230, 43,199,144,103,138,147,214,228,147, 71,198,216, - 79,213,155, 79,157, 0, 39,192,121,135, 41, 68,136,190,199,120,216, 81,209,160, 52,164, 50,176,237, 2,139,213, 10,155,211, 13, -132, 16,104, 23, 13, 78, 30, 63,195,217,147, 39, 24, 15,123,220,223,220, 98,127,119, 79, 22, 57,107,209,118, 13,132,182,104, 86, - 91,116,171, 13,252, 52,194, 77, 3,134,253,158,198, 75, 41, 34,248, 3,166,225,107,220, 95,111,240,226,179, 79, 33,211,132,171, -215,111,113,250,244, 49, 62,255,249,207,240,253,239,191,194,238,234, 29, 78,206, 55,136, 41,225,236,233, 35, 28,246,223, 33,133, -128,182, 83,220,157,211, 20,228,230,122, 7,219, 54, 48,134, 14,201,219,203,123,124,244,217, 11, 12, 83,132, 81, 25,163,151,112, -135, 1,154, 71,174,182,109,176, 57, 89,162,105, 52,218, 86,227,225,190,135, 82, 2,251,135, 3, 85,174,137, 2, 78, 14, 15, 61, -110,111,246,240,147,195,147,199,107,156,158, 63, 37,109,135,200,216,108, 90,124,247,245, 55,248,229,255,243, 55,184,191,185, 37, -196,177, 96,210,158,181,136,222, 34,133, 0,219, 54, 16, 57, 50, 21, 45, 98, 28,134,186, 19, 46, 88,202, 92,246,222,198, 32,199, - 0,169, 53, 26,173,169, 11, 13,156, 90,168, 5,178, 8, 72,153, 18,185, 12,115,179, 51, 4,180,109,232,146,208, 10,224, 41,139, - 54, 6, 90, 27,116,203, 14, 57,211,191, 35,162, 91,168,226, 82,138, 45,245,240, 33,192, 90, 58,148, 23,171, 5,186, 69,139,229, -114, 69, 94,235,214,144, 63, 59,211,184,219, 29, 70,118,101, 8,238,136, 3,166,129, 46, 79,242,172, 3,222,145,248,139,212,240, -243,222, 87,136,121,130, 84,246,223, 37, 71, 93, 41, 9,101,200,187,159,114, 70,107,116, 85, 16, 91,107,225, 70,135,156,139, 0, -151, 86,115,222,121,238,148, 29,107,116, 44,218,174, 69,219,182, 48,198, 96,181, 94, 35, 84, 58, 29,141,198,141,144,212,121, 66, -213, 48, 24,154,186,229, 74,125,204, 53,150,153, 40, 99, 3,163,118, 75,136, 6, 9,153, 60,163, 61, 35,114,205,106, 39, 91, 43, - 84, 29,134,179, 62,129,166,146,214, 24, 40, 43,209,182,109,229,223, 71,142,202,236, 15, 3,166,105,172,130, 57,218,229, 42,148, - 70, 43,179, 5, 23,249, 8, 28,196, 93,186,148, 68, 31, 11, 49, 0, 76,176,155,237,166,122,206, 82, 87,178,238,113, 11,129,172, -252, 89, 81, 45,111, 52, 98,207,165,187,231,224, 39,186,244,202,234,209,145, 23,187, 78,125, 36, 19,218, 88, 63,193, 81,203,145, -247,186,179, 74,187,104, 30,120, 30, 34, 41,103, 60, 68,218,143, 39, 33,145,156,131, 80, 36,122, 35, 61, 82, 97, 36, 52, 8, 62, -194, 88, 26, 39, 79, 17,117,124, 14,144,174,200,104,186, 12,163, 75,188,242,162, 12,242,200,217,235, 53,194, 84, 8,120,126,134, -115, 6,172,201,152,124,132, 18,128,210,156,197, 46,230, 24, 83,169, 36, 34,159,215, 33,208,115, 20, 38, 7,211, 88, 10, 58, 42, - 94,241,156, 56, 64,135, 25, 37, 33,206, 54, 59,126, 70,138,214, 35,101, 22,174,114, 81, 89,237,134,130,244, 53,137,245, 54,101, -229, 82, 84,245, 82,106,210,121,169,162, 7, 40, 49,175, 20,122, 84, 10, 25,193,194,205, 50,189, 41,127, 55,137, 97, 57,172,135, -191,151, 41, 37,104,197,132,156, 50,162,118,147,131,109,108, 85, 96,150, 20,161, 68,190,250, 35, 80,190,226,206, 60, 99, 24,166, - 90, 53,123, 71, 25,224, 90, 43, 76,195, 4, 41,103,234, 81, 74,168,136, 66,122,211,230, 40,215, 50,226,158,166, 80, 47,213, 20, - 35,108,211, 18,119, 55, 21, 5,161, 71,206,102,150,239,115,149, 59, 43, 3, 99, 5, 67, 72, 41, 43, 69,169,132,134,164, 68, 32, -154,177, 31,160,179,230,116, 41, 82,203,227, 72,145, 88,246,219,206, 57, 22,254, 24, 36,153, 56,228, 97,174,170, 75,236, 98, 97, -231,211, 69,208, 80,218,157, 49, 85, 8, 38, 5,216, 47, 41, 42, 1,138,136, 68,185, 42, 74, 75,192, 67,241,162,122, 95,252,226, -243,126,109, 28, 70, 88,163,120, 98, 18,145, 92,172,156,230, 84,114,158, 37, 37,101,121,231,145,120,122, 49,142, 30, 74, 50,130, -212,245,232,239,175,208,180, 22,235,147, 21, 6,211, 97,115,118,138,211,167,207,240,228,227,143, 17,189,195,176,223,225,250,221, - 5,110, 46,175,225,134,123, 8,169,209,116, 29,132, 50, 88,110, 23, 88,159,156, 97, 26,122,140,135, 61,130,119, 24,250, 1, 98, -186,199,119,191,249,123,156, 62,123,133,199,207, 55,184,191,190,197,114,179,194,199, 63,254, 17,254,240,155,223,225,112,255,128, - 71, 47,158,224,176, 31,241,232,217, 35,140,125,143, 39,207,158,225,208, 79, 80, 90,224,225,110,199, 66,160, 8,165, 52, 46,222, - 94,163, 91,182, 24, 93,130,155, 18,164,238,144,146, 66,219, 50, 94, 88,208, 36,226,249, 71,103,200, 57,227,246,234, 14, 82, 68, - 0, 10,195,110,135,174, 51,232,251, 9,247,119,196,141,127,242,244, 4, 77,171, 49,236,118,248,234, 31,126,139, 79,190,120,137, -211,231, 79,240,183,255,249,111,241,205,239,190,193, 52,142,228,221,119, 19,117,115,197,134,166, 20,154,182, 69,211,117,148,134, -133,196,236,103, 81,249, 4,166,105, 16, 83, 66,246, 1,202, 8, 36, 71, 29, 95, 97, 7,104,195,135,104,140,244,185, 75, 93, 89, - 13, 90, 27, 52, 29, 9,173,186,101,135,211,243, 83,202, 80,104, 90,152,198,194,185, 0,239, 2,118,247, 59,236, 30,246, 56,236, -175,121, 7, 73,222,103,203, 81,172,246,204,178, 16,135,186,208,113,112, 8,142,153, 7,227, 88,211,161,202,184, 59, 67,240,119, - 42,213,248, 84,193,150, 49,138, 6,166,113,168,109, 77, 5,101, 16,147, 58,113,124, 38,127, 39, 29,161, 89,149, 84,124,233,101, - 40,157, 16,216, 54, 90,214,143,141,181, 44,150, 34,123, 87,211,210, 26,193,187,192,187,110, 95,213,217, 41, 58,236, 31, 38,206, - 34, 87,176,182,133,210, 13, 54,139, 53,229,192,239,247,200, 72,196,201,214,178,102, 51,148, 53,150, 16,180,226, 11, 62, 64,177, -232,183, 58,105, 10, 32,139,109,130, 82,210,231, 66,234,225, 92,119,246, 31,250,142, 81,247,232, 74,209, 65,190,236, 22,180, 42, -145,229,220,202,152, 70, 7, 55, 57, 34,197, 41, 18,244, 26,109,152, 53,192,113,205,199,251,213, 35, 44,108, 57,179, 34, 39, 52, - 66,204, 57,222,101, 14, 92, 86, 0,177, 20,111, 25,149,231,158,145, 56, 18,148,196,152,193,123,228, 28,249,156, 78,236, 21, 23, -200,177,208,200, 68, 77,123,203, 60, 98,167,179, 72,208,138, 8, 84,148, 9,182, 79, 73,221,208,154,168,164, 66, 42, 65, 62,239, - 72,223,135, 88,108, 87, 62,243, 93, 97, 32, 57,161, 51,167, 4,219, 72, 70,135,163,218,188, 74,206,121,129,155,145,245, 46, 97, - 28, 74,152, 16,125, 38,211, 68,191, 59, 4,237,167, 21, 59, 13, 74,252,118, 57,143, 61,167, 85,198,144,144,120, 31, 29, 67,164, -245, 8, 3,224, 75, 24, 74,100, 13, 24,164, 32,122, 32, 59, 83,200,185, 34,143,162,186,211, 7,235,221,156, 18,251,194,233, 34, - 14,126,170,153, 10,168, 5,144,172, 84, 70,193, 96,154,242,187,150, 53,109, 46,204,151, 50,169, 45,209,179,197, 46,157,168, 75, - 47, 43, 87,114,156,147,238,131, 58,118, 18, 88,227, 8, 47, 11, 74,105,155, 15,158,224,105, 87, 18,188, 7,178,174,162, 54,207, - 65, 39,197,135, 90, 42, 52, 18,219,204,187,173,242, 48,119, 28, 29, 57, 77, 30, 74, 59,116,139,142, 58,110, 85,246, 48,177, 70, - 8, 30, 95,234,134, 51,215,165,164,206, 6, 5, 19, 27,169,170, 35,239,119,170, 94,191,116,180,195,192, 17, 15, 87,114, 37, 99, - 57,168, 64, 72, 73, 0,127,165, 42, 39,186, 80,239,230,176, 4,122, 29,206,121,178, 28, 48,210,210,187, 0,173,100, 21,140, 8, - 38, 54, 21,113,196,252,144, 16,104, 95,155, 6, 74, 27, 62,200, 53,220, 20,168,144,104, 27, 78,149,146,208,134,193, 6,121, 30, -245, 21, 71, 65, 57, 60,136, 48,167,102,223,101, 78, 21,151, 72, 65, 31,116,208,104, 37,170,248,166, 84,128, 2,204, 78, 86,138, -210,166,152,129, 47, 13,237,195, 36,128, 97,152, 48,236, 18,118,183, 87, 80, 74,227,234,109,139,110,177,132,237,150, 88,157,156, -194, 52, 11, 60,126,245, 37, 62,254,147,159, 32,184, 17,253,195, 61,238, 46, 47,177,187,223, 33,186, 8,187, 92, 66, 44, 55,104, - 87, 27,164,224,225,199, 30,251,187, 91, 28,246, 61, 30, 46,190,193,238,246, 26, 79, 94,125, 1,219, 6, 52,235, 14, 95,252,179, -159,224,245, 55,223, 97,236,183,136, 49, 97,177, 94,163,223, 95, 98,185, 89, 32,191,190, 4,114, 70,127,152, 88,197,156, 24, 86, - 68, 7,192,213,229, 1,182,105,209, 88, 64, 36, 18,146, 72,173,233,210,190,191,199,119,195, 1,109,215,146,207, 87, 40, 24, 13, -120, 37,113,232, 3,148,182,120,244,180,197,212, 31,112,243,254, 10, 55,151,215, 88,174, 22,248,179,191,248, 5,134,195,132,127, -247,127,252, 91,220, 94,223,204,234,106, 30,127,106, 83,132, 96, 36, 92,116, 99, 79, 97, 36,156,152,165,141,170,246, 18,211, 24, - 18,103, 26, 61, 95, 26,154,186,216,192, 2,161, 66,112, 35, 82, 30, 93,172,155,147, 53,214,219, 53, 22,203, 5, 22,171, 69,165, -190, 77,163,195, 56,121,188,191,184,192,208,247,216,221,239, 40, 95,192,106,104,107,113,122,182,129,144, 26, 96, 33,205, 56, 76, -184,187,121,128,115, 30, 33, 56,186,148,121,245,164,181,228, 11,119, 78, 91, 19, 0,140,213, 8, 33,179,173, 83, 64,106,129, 24, -102, 94,188,109, 8, 95, 76, 23, 13, 29,174,198,106,178, 19, 49,236, 34, 86,171,149,172, 0,144, 20,203,193, 87,128, 52,244,103, -154,182, 97, 74,154, 97,187,153,226, 46, 40,213, 44,131,134, 11,248, 18,105, 73,110, 28, 15, 9,210,234, 40,109, 8,188,100, 13, -150,155, 18,120, 52,112, 67,146,144,162,167, 51, 40, 6,178, 59, 49, 88, 37,167, 57,121, 43,242,190, 20, 71,157,105, 81, 5,215, - 40, 76,254,179,199,151, 5,101, 82,232,153,220,199, 83, 77,173, 9, 77, 29, 99,164,149, 29,127, 23,189,119,181, 96, 39, 72, 87, -233,202, 20, 20, 23,244,169,166,210, 73,114, 75, 48, 14, 86,113, 48, 20,117,121,185,162,101, 83, 74,200, 74,113, 17, 95,160, 61, -197,242, 43, 42,191,188,132,229,228,228,128,228, 17,203,174, 92,228,218,164, 73, 33,105,148,174, 8,149,109, 77, 83, 47,134, 2, -154, 33,209, 93,161,255,177, 86, 68, 50, 14,150, 87, 54,200,146, 33, 60,196, 80, 72, 60, 42,166,164,182,200, 94,117, 64,105,166, -211,177, 21, 77,136, 8, 45,136, 46, 90,214,155,211,232,120, 55, 28,185, 59,167, 99,117, 26,139, 86,137, 58,123,194, 39,143,172, - 12, 39, 81,156,119,161, 58,173, 98, 34,141, 10, 56,156,135, 64, 99,129, 38, 47,153,238, 44, 36, 62,123,195,220, 24,146,102,160, -140,201, 5,105,152,152,202,231, 67,100,205, 81,209,119,249,154, 28, 72,152,216,204,154, 25, 57, 95,220,114,158, 62,148,233, 93, -154, 8,137, 27, 66,100,215, 21,115, 1, 56,144,137,186,122,182, 46, 34, 49,209, 78, 32, 70, 1, 63, 77,179, 70,133, 53, 32,101, -162,146,170,232, 52, 66, 7,222, 35,145,233,158, 20,184, 49,230, 58, 82,108, 90, 11, 37, 43,225,129, 20,227, 70,147,218, 61,209, -104, 36,120, 42, 12, 28, 43,205,189,247, 12,132,161,135,221,243,126, 26, 89,240, 62, 94, 32,129,132,106,110,162,241,104,129,242, -107, 45,107, 54,114, 8,148,144,102,155, 22, 37,159,209,179,119,190,118,188, 53,248,128, 14, 1,105, 56, 77,141,211,219,234,159, - 97, 69,172,155,124,253, 57, 37, 91,183,120,207,139,218, 82,178,157,196,243,197, 75, 80,143,196,214,181,161, 10,223, 34, 43,213, - 5, 31, 4, 33, 2,109, 67, 59, 69, 93, 57,214, 36, 98,145,149,105, 79,254,203, 24, 60,141,218,142,196, 71, 82, 10, 76, 35, 85, -252,101,215, 24,120,175, 68, 99, 33, 95, 4,142, 31, 4, 72,104, 93, 4, 21,105, 78,249,209, 4, 4,129,144, 8,211, 68,161, 19, - 34, 3,201, 99, 26, 60, 43, 65, 3, 82, 0,134,224,177,191,167,247,183,233, 90,216,166, 69,183, 92,161, 91,109,208,174,214, 48, -237, 2,139,213, 18,143, 95,157,224, 49, 18,146,159,208,239,246,136,110, 66,202, 9,211,100,208, 46, 86, 88,157, 62,130, 27,122, -244,187, 59, 28, 30, 30,240,238,171,191,195,254,201,167,120,252,226, 41,158, 34,237,237,155, 0, 0, 32, 0, 73, 68, 65, 84, 62, - 63,161,104,212,195,136,105, 18, 80,198, 98,185,110,113,123,189,135,182, 68,191,146,236,197,213, 6,188, 79,141,152, 92,134,181, - 22,109, 67,246,199, 47,126,252, 2, 41,101,124,247,205, 59,236, 14, 7,108, 79,183,216,158,174,209,247, 3,220,142, 70,185,144, - 13,158,125,114,138,126,119,192,229,155, 75, 92,190,185,192,221,245, 13,172,213,248,217,159,255, 20,155,211, 13,190,254,213,215, -248,246,235,111, 49, 77, 36,150,155,198,137,227, 71, 57, 50,145,191,216, 66,154,106,127, 73, 5,251,152, 18,172, 32,111,105,204, -153,247,122, 28, 97, 42, 40, 20,168,211, 26,203,213, 2,203,245, 18,235,237, 26,109,215, 97,181, 89, 84,190,115,206,192, 48,140, -152,134, 9,151,239,239, 49,254,225, 29,239,241,201,134,105,172,197,114,213, 97,177,236,112,254,228, 49, 98,136,216,221,239,225, -156,199,219,215,239, 49,244, 3, 29,248, 37, 83, 65,203,122, 89,185,113,226, 34,135,148,242,166,184, 73, 74,215, 92, 98,136,115, -172,106, 98, 41, 36,178,204, 48,172,112,206, 37, 0,133, 83,191,100,153, 24,241,212, 12,133,249,157,136,105, 65, 25, 8, 37,210, -147, 58,199,224, 19,140, 85, 71, 76,119,186,224, 10,115, 62,229, 12,149, 51, 32, 88,181, 29,231,203, 41, 48, 67,162,105, 27,238, - 2, 35,188, 27, 17,252,132, 24, 27, 98,206, 91,131,224, 38,140,158,254,125,153,238, 37, 30,107,131,153,219,130,131, 83, 40, 38, - 58,214, 11,189,168,210,139, 93,183, 56, 79, 10,228, 71, 1,181,208, 42, 48, 27,205,112,157,118, 65,190,244, 99,145, 91,140,145, -246,255,156, 71, 95,108, 70, 18, 52, 78,151,236, 41, 46,217,224, 82, 72,100, 81,210,226, 34, 50, 99,125,139,255,185, 28,224, 41, - 70, 8,165, 25, 45,186,160,223, 93,138,186,131, 46,133, 68,101,232,231,196,150,212, 9, 57,115,119,158, 60,147,205, 4,167,235, -177, 0, 42, 71,206,112, 79,156,216,214,208,249, 98, 44,130,119,124, 97, 8,216,150,186, 95, 32, 85,190,123,138,129,167, 14, 5, - 36, 35,153, 19,239,235,200, 88, 40,194,105, 27, 67,208,176,224, 2,148,209, 64, 10,164,118,231,177,114,244,196, 64, 32, 54,129, -128,247,185,102,164,151, 4,203,196, 48,154, 88,156, 65,124, 15,184,224,209,118,182,118,243, 51, 82,149, 20,238,153, 93, 75,197, -207,157, 82,230, 59, 45,115, 30, 7,105,170, 42, 57,212,168, 15, 38,178,180,227, 7, 93,232,117,245, 92,246,244,236, 76,201, 51, -217,175, 60,203,178,102,161,204, 77, 47,221, 73,170,142,241, 75,252,183, 64,137,100,229,169,108, 49,168, 49, 52, 40,149,245, 67, -164,247,189, 4, 52, 81,224, 88,174,220,139,140, 4, 77, 85, 12,197,120, 22,123,151,243,129, 85,211, 13, 31, 24,186, 2, 39,114, - 6, 9,169,216,206, 80,184,234,222, 11,230,180,103, 86,117, 39, 86,239, 18, 94, 79, 41,137,172, 40, 0, 33,184, 17, 17,236,247, - 99, 91,130,119, 52,166,138, 49, 64, 75,186,144,130,151,252,179,192, 24, 65, 82,229,106, 37, 33,172, 97,181, 60, 42,240,161, 88, -131,200,167, 78,163,240,162,150,117, 19,137,149,154,150, 99, 6,197,156,135, 28, 60,170,165, 65,112,181,227,125,228, 64, 7,212, - 75, 31, 12,231,192, 81, 40, 67,206,229, 61,104, 24, 62,194, 92,103, 14,155, 16,108, 37, 33, 76,101,130, 23, 52, 14, 44, 52, 47, -129,249, 50, 46, 25,243, 49, 37,182,116,208, 62,200,141, 19, 97, 50, 21,117, 72, 5, 91, 88, 38, 30,200,242, 8, 35, 73, 29, 68, -202,160,177,170,204,104,187, 22, 34, 51, 61,203,187,218,237,147,127,210, 83, 70,113,166,177,176, 31,247,144, 82,226, 94,105, 24, -219,194, 52, 13,150,235, 13,214, 39,167,208,205, 2,221,122,141,118,185,196,250,252, 17, 71,185, 42, 68,239, 17,188,131,214, 51, -222, 51,248, 9,119,151,151,184,125,127,133,183,223, 28,144,226,167,248,232,147,199, 88,110,150, 56, 9, 2,239, 47,238,176, 61, - 63,197,221,245, 61, 76,163, 97, 27,129,105,114, 48, 6, 16,136, 56,236,129, 97,162,189,166,181, 2,198, 10,252,233,207, 63,197, -237,205, 30,191,254,255,254, 17,155,237, 18,159,124,241, 17,188,243,216,221, 61,160, 93,180,104,187, 37,214,219, 5,118, 55,183, -248,235,191,252, 79,184,190,184,196, 56, 78, 88,174,150,248,242,167,159,227,179,159,124,142,239,191,254, 1,127,245,151,255,133, -118,185, 82,162,109, 59,246, 66, 75, 76,195, 80, 29, 8,169,138,110, 36,239, 68,139, 85,138, 86, 72,145, 47,169,213,154,240,189, - 39,231,167,216,156,108,176, 98, 17,154, 16, 84,228, 78,163,199, 48,140, 56, 28, 6, 92,190,191,163, 14,141, 49,198, 49, 70,172, - 56,174,243,236,227,167,124,129, 81, 40, 67,127, 24,112,216, 83, 30,247,126,119,192,208,247,200, 41,240,148, 40,179, 22,196, 2, -160,194, 59,149, 32, 16, 9, 6,212,112,129,196,163,238, 50, 13,107,187,150, 15,196, 84,185,239,134,191,167,133,151, 94,186,131, -156, 56,251,186,160, 44,235,234, 76, 84, 33, 85,153,210, 53,109,131,224,124,197,223, 2, 18,221,210,146, 3,196,146,197,174, 4, -121,104, 99, 32, 36,173,251,166,209,241, 1, 73,218,156,154,179, 34,105, 90, 69,124,235, 0,239, 38,164,200,207, 42,201,157,176, - 88, 46,161,140, 65,211,182, 8,126,164,139, 44,209,184, 83, 8, 1,109, 77, 77,146, 75, 12,110, 81,108,225, 44, 86, 55, 33, 0, -213, 88,226,109,112,240, 11,141, 96, 53,255, 57, 98,172,207, 98, 54,154,212, 52, 44, 82,244,206,147,110, 6,212,160,128,119,248, -225,232,192, 15,145, 84,240,145,191,175, 82, 10, 4,254,187, 83,200,188,183, 47,171, 1,250,255,139,171, 37, 21, 26, 90,156,195, - 64,164,152, 69,108,197,193, 83, 58,116, 32, 33, 4, 7, 37, 50, 34, 18,239,158, 49,239,239,211, 44,166, 43,175,151,188,216,138, -166, 63,108,163, 12, 12,214, 41, 49,200,222,209, 88,154, 82, 34, 3,132,230,108,112,182,172, 85, 60,111,189, 39,200,243,142,164, -160, 23,134, 35, 96, 3,164,166,201,227, 52,122, 22, 18,131,245, 20,142,186,250,144,145,148,172, 66, 62, 82,184,211,251, 64,204, - 30,202, 37,160, 2, 81, 86, 29,194,208,143,164, 62,151, 92, 16,242,181, 8,163, 33, 20,113, 57,102, 26,104,172, 65, 58,153, 85, -227,197, 13, 2, 68,158,132,138, 90, 0,148,213,140,228,201,147,100, 48, 79, 18, 5, 49,203,175, 95,240,132, 5, 76, 10,100,203, - 34,233, 58, 48, 11,223, 50,133, 51,201,156, 72,252, 40,102,149,127,138,244,185,148,243,135,214, 96, 28,175,154, 34,162, 15,148, - 36,202,207, 65,140,158, 89,242, 84,248,102, 0, 58,243,242,189,236,210,133, 20,104, 26, 59, 67, 98,142,186, 84,231,104,204,133, - 48, 71, 22, 74,201, 62,196, 34,211,103,145, 73,211, 18,129, 74, 73,234,138, 33, 4,140, 84,240, 73,178,239,112, 6,199,120, 79, - 72,189, 84, 72, 71,188,195, 55,214,192,251,128,110, 97, 9, 13,169,228, 60,146,130,168,177,125, 37,153, 73, 72,197,157, 80,233, - 68,128,166,177,108, 15,202,213,114,160,217,126, 82,115,167,107,130, 20, 42,251,183,120,199,173, 53,196, 29,230,203, 87, 43,137, -161,239, 73, 68,199, 56, 44, 99, 40, 77,171, 91,118, 20,173,105, 12,252, 68, 94, 81,194,206, 82, 81,225,189,167, 78,136, 65, 10, -101,183, 89, 34,111, 11, 86, 80, 21,190, 47, 23, 71, 5, 22,225,125,134,150, 36,244,200, 41, 66,100,218, 93, 57,231, 56, 67, 90, - 86,245, 47,111,131, 32,133,134, 64, 68,244,142,121,249, 25,211, 88, 84,191,168, 35, 57, 57,167, 64,210, 3,233, 71,184, 56,193, -245,192,238,250, 2,151,166,129,177, 13,218,197, 18,237,114, 5,221,110,112,242,248, 49,150,155, 13,150, 43,226,166,215, 64,156, - 4, 52,203, 22, 31,157,156,225,229,151, 95,162,223,237,240,112,251,128,254, 48,226,241,243, 51,108, 58,138,201, 61,244,142,179, -224, 19,144, 35,189, 71,110,130, 75, 18,195, 68,159, 77, 99, 13,140,150, 88, 46, 59,252,254,215,223,163,223, 29,240,249,143, 62, -194,106,221,194, 77, 30,219,147, 21,242,233, 22,135,135, 3, 46,190,251, 22,255,254,191,254, 3,238,174,175, 49, 77, 14,139,213, - 2, 63,253, 23, 63,195, 47,254,213, 47,240,246,187, 75,252,135,255,243,223,163, 63, 12,228, 37, 55, 6,237,146,118,125,235,147, - 53, 37,217, 77, 19, 0,138,198,181, 45,117, 22,221,146,130, 76,186,197, 2,135,253,200,222, 83,138,239, 61,125,116,130,110,217, -241, 56, 45, 97,236, 29, 14,135, 1,253,205,136,200, 83,166, 34,234,105,187, 37,182,167,167,196, 46, 80, 10, 67, 63,225,176, 31, -160,141,192,122,179,132, 16, 18,195,224,216,206, 72,153,225,221,130, 69,141, 39,167,149, 92, 86,184,230, 49, 38, 72,205, 93,104, -189, 72,243, 7,128, 21,197,211,142, 18,171, 90,186,196, 57,106, 82,212,221, 94,138,177,218,199, 82,140,104, 91,133,105,242,144, - 70, 85,244, 41,219, 97, 96, 20,131,163,216, 19,159, 98, 34, 14,132,165,181, 68,112,133, 5, 78,239, 83,206,242, 8, 24,163,121, -159,207,201,135,200, 92,168,134,122,144,122,231,232,178, 8, 30,147,163, 20,196, 28, 61,139,190, 56, 19, 34,120,236,238, 71,180, -221, 26,182,109, 96,109, 7, 63,141, 60,238, 22,243, 46,149, 5,101, 74, 41,248, 20,217,199, 79, 35,224,194, 27,143, 33, 64,105, -195,138,121,137, 12, 87,249, 18,162,114,184,231,174,139,196,120,130,131, 69, 72,187,210, 31, 40, 79,129, 52, 63,153, 39,112,190, -238,231,227, 17,211,163, 76, 84,152,143,133,152, 2,140,110,136, 14,167, 36,143,124, 81, 65, 40,206, 79,212,129,114,107, 94, 98, -123,161, 18,180, 80,204,187, 96,209, 28,239,235,227, 7, 97, 53,133, 16, 63,143,123, 51,127,150,197, 29, 68,225, 47, 12,164,242, -129, 86, 72, 74, 67,170,166, 2,111, 52,227,135, 37,199,150,166, 24,200,232,205,123,103,193, 17,186, 82, 73,128,131, 70, 76, 99, -152,126, 71,128, 24, 31, 28,209,210, 34,144,146, 71,138, 35,101,102, 20,229, 62, 50,100, 40,246, 58,138, 27,157,122,199, 40, 89, - 85, 27, 56,231, 99, 73,230,173, 73,106,193, 57, 8,165,170, 31,221, 88, 75,231, 96, 85,190, 3, 57, 56,166,196,209,119,163, 48, -221, 41,100,201, 87,168, 13,216, 65, 85, 92,135, 57, 70,164, 50, 17, 78,168, 84, 62,169,152, 58,167, 24, 18,196, 34,241, 34, 40, -204, 16, 85,148, 73,211, 20, 14,223,201, 37, 21, 14, 21,182, 68,133, 51, 29,196,217, 5,100,169, 43,150, 55,197,192, 5, 89,170, - 46,148, 88, 94, 23, 55,120,153,173,144,186,120,132, 37,251,228, 34, 47,241,181,214,220, 13, 24, 8, 67,151,107,219, 90,178,110, -229, 4,163, 53,167, 45,205, 42, 83,147, 20,131, 49, 2, 87, 66,186,142,206,140,177,204,147,167, 42,212, 7,186,240,173,229, 61, -189, 15,136, 70,195, 24,170, 78, 76,211,240, 23, 56,207,226, 23, 41, 63, 56,132, 82, 76,156,252,202, 23, 60,239,196, 20,255,185, -166,181,136, 41,161,209, 18,110,154, 5, 48,164,108,253, 16,195, 72, 30, 72, 26,193,135, 92,200, 66,115,216, 68, 97, 28, 15,253, - 64, 63, 95,196, 10,116,112,158,132, 67,218, 24,130,185,196,116,228, 65, 37,191,164,159, 28,143,193, 98, 61,152,221,228,224, 29, - 67,110,254,136, 79,159,139,239,157,190, 29,117,220,228, 16,235,223, 17,185,155, 39, 42, 32,211,146, 36, 19,186, 92,137, 32,140, - 8, 83, 68, 10,244,197,136,169,236,110, 82,181, 14, 38, 6, 24, 20,190, 54,249,230,115,237, 58,168,123,160,177,125, 78, 30,227, -225, 30, 25,111,112,245,253, 87,144,186,129,237, 54, 56,125,242, 12,235,179, 51, 44,215, 11, 10,195,113,190,122,170, 87,235, 21, -206,219, 5,118, 15, 35,134, 62, 96, 28, 3,158,126,116,142,175,126,253, 61,114,166,105,129, 81, 17, 15,187, 30,214, 40, 60,236, - 73, 4,216,182, 22,221,162, 65, 74,192, 52,121, 32, 69,188,252,244, 9, 91, 58,200,167,249,213,175,254, 9,187,235,107,228, 52, - 34,184,128,199,207, 78,241,236,229, 35,124,241,147,207,241,163,255,230,231,136,131,195,175,254,250,215,232, 15, 3,190,252,249, -143,208,118, 45,173,131,120,210, 84,198,109, 57,103,130,182,112,103,100,216,227,239, 38,143,177, 31,113,121,113,141,215,223,190, -193,187,215, 23,144, 34,214, 36,178, 57, 4,137, 16,183,133,181,191, 92, 45,177, 92, 47,113,122,126,138,172,104,188,124,127,251, -128,155,171, 91,244,135, 1, 41, 69, 76,227, 88, 87, 48,132,103,142,213,110, 53,241, 90, 42, 48,193,174,116, 84,179,216, 38, 34, - 67,162,227, 29,125, 41, 46,203, 33, 77,222,106, 67,150, 37, 30,139, 23,141,134,214,154, 65, 30,138, 87, 14, 20, 83, 76, 42,238, - 92,247,234,180,223,101, 45,137, 20, 21,161, 92, 4, 57, 84, 8, 4,100,157,144,179,162,204,247,144, 33, 11, 53, 76, 75, 22, 46, - 9, 42, 16, 20, 77, 99,202,179, 21,188, 71, 74, 1, 90,102,248, 24,201,123, 12,162, 36,210, 52, 35, 50, 28,133,232, 92, 82, 40, - 64,229,202, 6, 79, 33,160,223,223, 66,200, 83,242,219, 35, 99,191,123, 96, 97, 89,201,209,214, 85,255, 67, 43,185, 60,115,212, -249,249, 87, 74,193, 88,250,253,181,197,156,120,197, 87,122, 81,198,151, 20,203,197,178,227,115,132, 69,196,153, 98, 90, 73,111, - 20,120,122,134, 74, 27, 44,156,112, 58,155,230,139,105,206,193,166,241, 50,209,249, 4,124, 14,148,106,103, 27,196,224, 97,155, - 14, 41,120, 74,175, 99,181,124, 9,124, 41,251, 87,114, 71,102, 62,216, 73, 95, 64,223,227,217, 26, 87,252,252, 36,248,227,105, -170, 50,128, 80,144, 82, 83,247,201,191,147,109, 23,204,244, 39, 81,178,110, 13,143,192, 35,119,241,164, 53, 10, 41,212,179, 88, - 73,138,139,165, 98, 78,176, 72, 90,127,136,187, 69,170, 14, 35,169, 20,118,119, 59, 18, 17,178,254, 35,103, 1,104,112,199,155, - 72, 15,148, 51,144,128, 20,248, 28, 76, 9,218,146, 24,154,178, 22,152,235, 15,192,176,112, 85, 25,197,186,165,121, 58, 1,145, - 17,125,224, 98, 55,205, 66,112,102, 93,208,244, 57, 86,221, 88, 17, 4,210,243, 46,103, 56, 13, 63,255, 66, 10,164, 16,217,161, - 69,174, 39, 42, 94, 12,162,247, 92, 28,204, 69,101, 6, 5, 40,209,254, 95, 86,225,105,228,207,176,172, 24,200, 90,152, 17,146, -171,118,187, 34,176, 45,107,143, 66,191, 75,108,137, 78, 44,184,203, 41, 66, 23, 59, 4,253,135,129, 59, 53, 98, 68,147,112,204, - 85, 81, 8,142,210,162, 68,141,227, 35,177,142, 54, 18,193, 43,116, 93, 3,231, 40,254,148, 8, 77, 30, 66,116,149,242,150,132, -134,246,134, 24,202, 28,147, 74,214, 49,170,146, 10, 77,174,192,234,141, 81,117, 68, 79, 20,157,204,254, 72,133, 24, 80,119,133, -101, 31,122, 44,128, 75, 57,163,181,134, 60,129,153, 18,138,168,155,205,117,247, 81,114,172, 51, 43, 87, 75,194, 84, 56,218,243, - 75,254, 2,185,105, 98,212, 95,102,177,145,169,160,253,218,245,148, 81, 37,239,240,156, 11,112, 35,117, 96,221,162,225, 49, 79, -132, 68, 73,199, 10, 85, 48, 72,130, 15, 87,147,242, 4, 7,203,144, 10, 57,209,239, 42,114, 21, 65, 9, 8,158,174,148, 24, 71, -138,249, 75,130, 46, 42, 41, 18,130,155,120,132, 25, 33,129,138,151, 36,251,143,228,181, 7, 79, 79, 4,169, 89, 73,181,235,235, -107,163,131, 60,192, 52,221, 7, 96, 31, 32, 64,120, 7, 55,238, 49,238, 46,241,238, 27,129,152, 52,186,245, 22,139,237, 25, 86, -219, 83, 74, 52, 59,140, 76, 78, 18,232,191,127,135,152,128,245,118,133,237,249, 6,151,239,110, 17,188,199,192,200,199,224, 41, -126,182, 91,118,176, 86,227,238,102,143,245,166, 69,138,100,161,122,184, 31,177, 94, 91,184,126,135,174, 81,248,201, 47, 62,129, - 50, 95, 32,134, 76, 33, 14, 2,216,223,237,240,112,187,195,127,252,215,255, 9, 99, 63, 96, 26, 61, 54,167, 39,216,158,159,225, -201,243, 71,208, 90,225,225,126,135,221,221,129, 56, 9,200,120,184,125,192,187, 31,222,227,230,234, 6, 55,239, 47,113,127,123, - 71,137, 93,193,215, 49, 93, 25,135,249, 20, 89, 44,103, 96,155, 22,171,245, 10,219,211, 45,186,197, 2,237, 98,129,148, 5,250, -195,136,161,239,241,250,251,247, 24,107, 98, 31,143,184,185, 83,179,214, 64, 25,195, 99,233,204,106, 95,195,157,114,195,154, 10, -207, 41,111, 36, 0,178,156,194, 86,242, 22, 66,240,213,194,164, 20,248,243,242,232, 15, 61,154,166,229,130, 79, 99, 28,124,117, -158,152,166,161, 44,110,214,109,144,130, 61,212, 64, 9, 99,168, 75,167,221, 98,134, 53,170,118,174, 90, 43, 40,163,235,168,190, - 93,144,232, 75, 55, 30,221,154,186,124,207,151,115,228, 78,220, 24,130, 88, 73, 33,161, 12,231,132,115,135, 67, 74,101,138,112, -205, 52, 93,174,151,110, 1,131, 8, 41, 17,121,119,152,120, 37, 70,212, 52, 18,149,141,253, 30, 98,181, 65,211,116, 8,158,196, -130, 5, 89, 82,136,153, 74,235, 15, 46, 83,218,147,234, 82,119,243,116,177,169,153,223,228, 44,144,204,107,136, 28,133,153,248, -242,148, 21, 69,237,157,175,194, 85,128,206,179,178,211,151, 74, 1, 49,147,245, 47,229,163, 36, 54,240,120,159,190,147,101, 84, -235,125, 64,219, 52, 53,102, 53,231,146, 8,150, 0, 73, 14, 28, 98,110,112, 88, 9,143,225,165, 32,148, 90,113,192,100, 30,235, -214,249, 63, 47, 44, 68, 25,239, 74,138, 36,149, 82,215,117, 89, 25,193,107, 99,232,217,224, 8,220,162, 11, 2,171,244,105,170, - 33,129, 36,145, 65, 98, 47,161, 36, 4, 7,157, 20, 5,184, 16,162,118,202,197,253,160,216,106, 40, 65,159,249,110,183,167,207, -145, 11, 85,239, 36, 71, 83,115, 51, 83,109,105,148,131, 80,162,124,165, 86,180,234, 65,129,188,164,138,243,142,145, 45, 98,222, -147, 61, 49,211,218,162, 92,134,180, 94, 97,215, 82,240, 92, 52,230,186,167,102,198, 47,175, 75, 35,211,254, 68,229, 51, 20, 33, - 47,217,206, 88, 55, 32,242, 7,252,129, 24, 35, 69, 95, 11, 81,109,173,101, 58, 18, 75, 28, 49,243, 5,104,154,205,188,139, 52, - 83, 74,117,177,123,170,146,254,201, 43,187, 48,113, 56,145,155, 45,141, 57,213, 59, 60, 35, 19, 38,182,166,177, 85,166,121,192, -195,189, 67,211,146,109,192,115,213, 65,132, 42, 85, 35, 72,149,150,148,150, 99, 45, 95,254,137,119,207, 98,142, 19, 84,244, 97, -216,134, 18,102,192, 99,230,200,191, 84,211, 8,254,187, 81,197, 70,203,101,203,226, 6,141,148, 51,133,179,180,134,213,246, 52, -142, 79,129,114,139,231,252,245,204, 44,119,122,243, 12,251,212, 11,163, 87,114, 97, 82, 66, 91,180, 86, 56, 60, 28,160, 12,147, -166, 82,230,144, 21,234, 24, 50,147,154,172,213, 85,132, 23,188,231, 78, 74,144, 32,143, 67, 25,178,160,240, 16, 64, 84, 37,167, -100,193, 80,244, 97,134, 41,132,128,192,201, 70, 19,219,106,142, 5,110,153,153,199,161,142,131, 82, 21,176, 20,223,105,136,137, -133, 46,162,198,225,106, 69,252,242, 16, 18,144,168,163,200, 49,112, 8,128,103, 66, 24, 42, 72,161,120, 27,179, 16,104, 26,205, -147, 1, 58, 24,148, 42, 15,179, 98,196, 36,103,134, 27,195,182,187,242,103, 80,237,130,185,242,183, 37,130, 27,112, 8, 61,198, -221, 21,238,222, 89, 58, 56,100,131,197,246, 20, 66,183, 80,218,146,135, 59, 1,166,161, 64, 15,231,128,221, 48,194,143, 35,116, - 75, 62,108, 37,129,221,125, 15,107, 37,218,206, 96,181,238,176, 94,183, 56, 57, 95, 66, 10, 5,231, 34, 39, 99, 53,136,145,158, - 17,109, 12,100, 78,152, 52,165,140, 45, 86, 43,174,178, 41, 10,247,221,247, 23,248,237, 47,127,131,155,203, 27, 76,227,132,152, - 34, 78, 30,157,227,233,243, 39, 88,109, 86, 56,127,124,130,147,211, 37,182,219, 14,111,190,215, 56, 60,236, 49,142, 83, 21, 67, -117,203, 14, 93,183,224,189,121,199,211, 36,178,116,246,135, 30,215,215, 23,152,198,145,139,129,192, 19, 36,208,229,173, 21,175, -152, 10,244,136,240,152, 4, 71,145,136, 37,146,149,167, 63,222,135, 42,208, 2,119,147, 50,129,213,191, 12,138,202, 96,187,151, - 2,178,230,216, 82,137,166, 51, 88,174,216,183,219, 16,189,112,161,215, 53, 44,101,142, 42,101,139,145, 36, 94,181, 86,154,138, - 47, 46,168, 41,156, 40,224, 48, 13, 92, 60, 11, 76,163,135, 49,179,134,165,172, 2,104,178,197, 35, 87, 67,107, 60,219, 52,244, - 89, 26,131,213,118, 22, 1, 81, 33, 75, 43, 63,226,180, 7, 76,125,143,137, 33, 82, 2,148,120, 69,214,172, 92, 3, 79,192,170, -241,156, 19,239,151, 37,251,199, 61,166,126,143,229,230, 20,203,245, 6,119, 55,215, 12, 11,161,201, 68,158, 1, 16, 16, 50,151, - 53, 48,159, 63,228,249, 15,133,191,175,112,132,150, 5, 98, 74,232, 44,229, 90, 72, 37,209,216,134,215, 23,162,194,170, 8, 39, - 77, 58,146, 34, 70,115, 44,230, 42,103, 66,161,251,149,131,183,160, 89,185,233,227, 44,121, 77, 62,111,198, 7,211,161, 31,184, - 32,153, 61,202,180, 70, 35, 55, 17,152,161, 33,114, 17,105,137,186,198, 40, 1, 55,243, 68,160, 0,143, 20, 55, 63,124,121, 27, -139,110,177,172,130, 96,197, 19,129,192, 5, 64,202, 25,201, 71, 2, 69,177,224, 75, 30, 5, 18, 81,240, 10, 19,218, 16, 96,219, - 14,198, 54, 20, 52,195,127,167,140, 14, 1, 10, 16,116, 31,140,195,136,254, 48, 16, 37, 47, 70, 30,221,147,130, 92, 73, 90,171, -130,253,244,166,105, 16,217,114, 45,181,230,168, 87, 77,211,145,226, 60, 98, 92,112,226,231, 67, 42,250,142,144,214, 36,177, 48, -121, 38,248, 21,177,103, 57,159, 83, 12, 72,209, 51,136,169,160,191, 36,124, 76,149, 8, 71,120,243, 2,240,103,134,124,221,126, -169,249,251,203, 77,165,146, 18, 1, 69,133,159, 42, 78, 90,213, 16,178,200,154,170, 34,158, 76, 53,241,174,196, 8,187,201,213, -181, 74,170, 94,244,192,171, 54, 70,219,214,158,151,158, 39, 93, 60,141, 37,108, 29, 57, 51, 74, 80, 86, 95,100,217,117, 16, 95, -184, 97,126, 58,165,185, 25,171,234, 3,206, 58, 6, 76,147,132,146,164, 84, 87, 0,119,189,196, 14,166,253,177,168, 86,174, 28, -121,108, 88, 68, 17,197, 82, 99, 21, 66,160,138,214, 88, 86,219, 26,133,148, 88,180,150,100,165,198, 73, 41,170,216, 39,215,177, -178,172,176, 28,239, 60, 23, 9,108, 7,209,108,159, 64,174, 25,203, 49, 37, 88,109, 16,193, 24, 78,109, 88, 65,108, 57,216, 62, -215,209, 38, 5,180,104, 30,227,210,216,168,237, 90,122,248, 35, 71, 93, 66,192,141, 14, 62,196,154, 46, 36, 56,116, 49,215, 61, - 73,170,222,196,178,195,175,116,163, 60, 31,102, 41,145,181,167, 68,173, 22,107, 16,133, 16, 0, 40, 99,214, 24, 33,141,226,140, -224, 68, 5, 68,177,232,164,217,215, 92,148,151,244,176, 23,228, 96,128,119,153,105, 95,236, 36, 96,221, 1,216, 39, 73, 93,202, -124,153,212,216, 79, 80,138, 16,197,100, 10,254, 61, 13, 31,112, 17, 49,236,241,240,254, 1,222, 17,175,223, 7,129, 96,159, 65, - 43,131, 47,127,242, 9,180,181,184,191,189, 37,128,208,148,208, 95,221, 99,179,182,120,249,233, 25, 94,125,241, 4,219,147, 37, - 14, 59, 7,239, 19,110, 46,123,158, 26,209, 30,240,226,237,129, 64, 42,163,167,192,149,137,242,232,165, 0,218,174,193,106, 77, - 86, 55,173, 21,206, 30,173,177, 61, 93,224,229,167,207, 48,244,244,231,250,195,128,221,253, 29, 30,110,111, 25, 30, 2,180,139, - 14, 63,251,243,127,142,229,170,195,237,245, 29,167,129, 73,236,238, 15,216,239, 15,216,221, 61,224,221,219, 27,140,125,207,214, - 22,170,152, 53,251,134,143,149,173, 0,112,146, 50, 94,172, 45, 46,161, 49,102,154,174,116,139,142,131, 50, 4, 91, 54, 13,171, -193,233,162, 48, 77,130,105, 90, 44,215,169, 22,152, 5,108, 83, 84,219,101,100,104, 27,195, 35,215, 84, 11, 90, 8,138,207, 44, -201,110,180, 91,167, 85, 77, 65, 61,151,144, 13,234,102, 35,166,129,108, 63,110, 20,117, 42,167,148, 64,112, 19,180,166,144,154, -174, 83, 85, 44, 10, 70,191, 18,160, 41,241, 56, 61,243, 78, 60,227,176, 3,147,235,116, 77, 86, 36,207, 50, 96, 27,138, 53, 85, - 77, 3,129, 6,235,237, 22,126, 26,105,229,192, 86,181,105,232,225,198, 1,110,114,164,228,230,213,128, 16,134,237,118,226, 40, -121,205,225,176,219, 65, 42, 93, 59,204,178, 7, 87, 74, 86, 0, 84,226, 98,186, 76, 3,169, 11,164,131,150,124,235, 17,182,105, -152, 50, 23, 89,225, 78,103,143,146,146,227, 88,117, 13,167, 34,193,169,194, 52, 6,242,217, 75,142,168,230, 73, 90,249,157, 73, -253, 46,184,139,166, 73, 1, 77, 73, 99,133, 99, 5, 63, 65,138, 22,224,209,126,177,174,149,104,106, 89, 83,227, 84,229,220, 19, -170, 86, 80,241, 94, 44,121, 57, 86, 98,102, 1,221, 72,148,221, 45,141,248,165,210, 80,202,194, 88, 66,246, 22,119, 14, 41,214, -109, 29, 49, 83,116, 43, 21, 17,132,220,158,170,245, 19, 71,175,165, 76, 64, 41, 14, 86,193,251, 0,153, 4,164, 81, 48, 58, 33, -103,186,252,189,155, 16, 99,196,112,160, 66,113, 28,136, 91,144, 35, 61,220,166,153,207, 91, 40,137, 12,133,105, 28,217, 59, 47, -145, 67,224, 73,142,231,139,146, 50, 23,164,226,238, 93, 74, 8, 86,189,151,145,124, 46, 8,238, 52, 19, 9,139, 55,191, 50, 82, -104,215, 75,147,209, 92, 66,147,184, 80,133, 66, 76, 64, 42, 25, 33,113, 22, 51, 22,254,124,217,103,151, 34,170,172,110,137,194, -234,235, 24, 62,113,232, 75,224, 34,163,232, 46,144, 83,181,170,129,157, 78,145, 39, 78, 37,208,135,254, 89, 88, 42,146,247,246, -179,250,189,248,156, 53,125,193,197,188, 7,226, 81, 11,177,127, 81, 71, 13,134,227,236, 92, 25,203,121,242,139,210, 27,156, 43, - 72,195,113,150,119, 17,159, 41,174, 32, 11, 24, 70, 74,133, 44, 19,101, 42,187,169, 70, 62, 54,109, 51,163, 6, 51,143,216,181, -129,212,154, 97, 17, 64, 74,179,234,179,188, 56, 34,209, 17, 36, 70,114,117, 43, 56,166, 81, 41, 89, 89,200, 77,107, 43, 31,186, - 64, 99,102, 79,162,172, 2, 6,207, 2,140,166,109,170,221, 37, 56, 15, 55, 18, 96,197, 26, 77,162, 26, 69, 9,117,166,177, 53, - 34,211, 51, 15, 94,176, 74,186,140, 17,173,165, 32,140, 20,200, 74, 22, 98,172,106,252, 92, 70,249, 70,177, 13,136,109,120,152, - 63,168, 2,181, 41,105,211,218,144,223, 94, 73,170,186,203, 88, 71,130, 98, 25,115,142,200,165,115, 98, 85,189,119, 19,237, 81, - 57, 64,131, 42,254,204,153,195,243,206, 45, 29, 17,237, 10, 3, 89,105,222,181, 87,254,112, 62,226, 12, 83, 90, 87, 40, 14,135, -242,144,179, 23,155, 44, 28,146,119,246, 0, 88,160,103,154, 9,187,171,247,248, 47,255,247,128,255,254,127,249, 57,126,244,211, - 87,184,190,218, 67, 43,129,243,117,135,207, 94,157,226,110, 8,248,230,171,107, 24,115,207, 99,198, 50,177, 16,213, 82, 89,126, -102, 8,180,223,214,182,133, 93,172,107,248,136, 16, 64, 63,140,200,217, 99, 26, 70,184,201,161,237, 12, 78,207,182,216, 72,137, -118,209,178,141,135, 0, 23,169, 70,116, 18, 29,113,115,118,142,229,170, 69,219,145,120,116,255,176,199,238,126, 15,239,105,236, -154, 98,194, 56, 76, 8,129,114, 9, 74, 86,183,102,244,171, 16, 18,191, 88, 89,124,242,106,139,209,174,241,126,239,240, 48, 56, - 76, 62, 96,242, 17,147, 39,118,122,165, 74,101,218,167,199, 20, 72, 77, 43, 19,180, 20,117,199, 14, 22,150,129, 1, 51,145, 41, -131, 74,137, 58, 98,165,247,170, 60, 45,153,225, 42, 25, 66, 36, 68, 79,240, 18,109, 52,192,140,121,106, 67, 51,160,192,192, 39, - 93, 45,107, 49, 38, 52,173,173, 69, 59,173,186, 84, 29,191,187, 34,114,229,231, 33,248, 80, 99, 74,203, 10, 12,137, 86, 3, 49, -120, 98,186, 43, 13, 32, 96, 56,236,121, 21, 86,162, 47,103,246,132,181, 13, 86,235, 21, 97, 98,189,195,238,238, 30,253,254, 1, - 3, 39, 93, 21,219,106,157,102,100, 32,134, 9,222,187, 90,204, 83, 55,171,171,200, 85,114,251, 71,100, 70,186,228,149,214, 80, - 82,147, 88, 19, 64,100, 98, 27,202,100, 79, 72,178,226,166, 4,221, 52, 53, 95,158,127, 4, 31,210,140, 41,173,104,106, 70,134, -178, 15, 61, 51,241, 49,178,218,190,164,182,205, 77, 20,105,105, 74,132, 51,142,108, 80,197,125,163,149,161,247,136,109,134,162, -136,230,152,147, 33, 89, 25,159,114,168, 74,116,250,188,116,181,100, 10,169, 25,215,171, 96,108,139,110,177,226,157, 55,224, 3, - 51,228,153,158,150,217, 83,158,121,173, 67,213, 36,117,147, 34,211, 52,215, 59, 95, 47,246,136, 12, 99, 91,104,219,113,190,129, -132,212, 10, 18, 30, 66,144, 11, 33,101,129,105,156,224,221, 84,217,240, 66,170, 26, 74,162, 21, 72,251,163, 4,175, 43, 34,132, -164,174, 92, 8, 1,164,204,182, 58,130,176,208,249, 36,104,213,171,115,205,241,144,146, 84,244,133,179,159, 93, 41,156,202,133, - 45, 48, 14,142, 21,246,177, 90,199, 34, 3,204, 66, 72, 85,248, 39, 65,107,233, 50,241,201, 66, 67, 42, 84, 61, 69,224,169,111, -121, 13,145,157, 45,213,110,200,150,232,210,156,149,233,177, 86,244,247, 17,194,152,180,105, 37,138,183,172, 59,143,147,223, 88, -217,200, 5,106,134, 72, 5, 60,131, 58, 33,163,164,189, 12, 29,130,135, 76,138,194, 75,202,120,220, 16,177,136,170, 80, 93, 71, - 29,150,171,168,105, 34, 76,162,224,135, 52,132,116, 52,230, 17,245, 80,115,206,147,153, 62,250,122,184, 19,180, 67, 64,183, 13, -164, 72, 53,129,230, 3,226, 83, 5,206, 80,197, 88, 72,114, 74, 73,100, 65,194, 36,149,100,237, 20,200, 86, 32, 42,102, 85, 41, - 18,132,197,152,160, 89, 84, 82, 48,180,162,136, 43,138,111,150, 69, 49, 5,154, 97,140,129,177,196,242, 85,140, 34,165, 34, 35, - 16,211,253, 40,139,151,246, 70, 13,137, 78, 98,174,220,107,239, 34, 19,223,184,202, 85,196, 63,142,188,131, 11, 76, 56,138,165, -146, 76, 9,222, 39, 4,199, 49,130, 5,199,201, 42, 87, 42,138,232,139, 82,124,237,214, 90, 4,222,235, 80,177,192,135, 76, 8, - 85, 29, 41, 89,112, 69, 94, 84, 42,134, 66, 76,176,134,120,245,154,133, 67,202,208,168, 93, 27,205, 2,165, 57, 34, 82,240,110, - 48,199, 48, 3, 46,202,248, 41,167, 26, 29,121,108, 43,180,109,203, 29,229, 60, 50, 77,145, 25,219,222, 1,162, 65,215, 72,236, -187, 51, 12, 59,224,175,255,227,239,112,122,190, 66,112, 17, 79, 94,156,226,229,103, 79,112,113,231,241,230,135, 43,104, 99,177, - 88, 90,172,214, 29, 5,113,100,170,204, 33, 21,175, 4,202,200,154,132, 89, 77, 67,163,195,182,109,104, 61,148, 51,148, 49,184, -186,120,192,237,109,132,146, 6, 39,143,207,208,172,214, 24,135, 9,215,215, 19, 4, 28, 95,142,212,117, 14,195,132,105, 32, 22, -120,211,104, 44,150, 13, 63,159,130, 5,109,138,115,194, 19, 14,187, 17, 49, 36, 76,206, 3,153,200, 98, 49, 70, 40, 77,202,220, - 6, 9,159,252,143, 63, 1, 78, 86,104,149,198, 39,136, 52,206,122,216, 3,247, 3,222,252,112,141,215,183, 14, 23,119,119,232, -167,128,161, 31, 89,116, 53, 91, 92,202, 62,190, 20,202,249, 72,228, 24, 66, 68,244,138,158,205,148, 57,174,146,246,184, 36,192, -212, 8, 1,104,172,168,217,229,197,206, 89,245, 37,153, 86, 79,218,176,101, 79, 73,222,251,147, 7,189, 8, 51, 67, 17, 24, 50, -146,148, 86, 65,178,130,144, 72, 23,164, 88, 64,168, 89,117, 47,248, 57,161,241,168,228,223,125,232, 71,158,202,177, 87,152,117, - 35,253,225, 80,131, 58,180,209,176,214,194, 88,131,205,201,150, 83,230, 4, 14,251, 61,180,210, 8, 49, 86, 96, 75, 77,150,175, -105,138,134, 71,161,172, 50,151, 52,161, 64, 6,132, 42,150, 49, 85,161, 29,138, 11,176,148,136, 96,102,140,193, 56,186, 25,137, -203, 57,221,116, 8, 51, 26,215, 19,194, 57,132,200,217,234,164, 41,160,213, 25, 79,221,144,234,247, 55,179, 66,153,224, 54, 44, - 98,227,162,186,188, 87,162,198,176,102,142,166,158,191, 95,146, 11, 41, 84,104, 14,179, 4,138, 2,154,223,231, 99,241, 93, 17, -116,201,218,233, 11, 24,219,113,172, 47, 19, 8, 57, 14, 84, 41,133, 84, 88,242, 12,171,201, 57, 34,133, 68, 62,247, 82,164,228, -192,221, 59, 77,111,165,210,176, 77, 7,109, 91,176,117,156,139,191,200,133, 14, 77,248,166,190,199, 52, 14,212,197, 43,154,206, -150,205, 10, 57,126,232,183,241,108,223, 35, 46, 61,234, 42,171, 52,152,138, 35,153, 5,175, 8,137, 45,207, 41,125, 44, 78, 75, -129, 26,155, 82,208,101, 94,139,144,208,175,172, 67, 83,133, 22, 21, 17,104, 0,189, 15,153, 61,241, 33,151,226,160, 4,171,164, - 90,108,149,166,199,243, 74, 86,105,253,193, 52, 38,231, 88,173,104,153,195,184,100,153,172, 36,193,192, 30,112,160, 11,234,127, - 71,218,129, 25,168, 22,121,138, 32, 24,198, 86,164, 18,196,208,224,148, 61,214,213, 32, 39,104, 99,103, 27, 26, 9,182, 72,245, - 42, 36,197,240,149,203, 86,105, 67, 56, 76,107,160,164,134,243, 44,208, 41,104, 64,166, 42, 89,107, 32,101, 70,127,160,152,214, - 84,236, 29, 33, 96,177, 92,240,131,171,129,204, 74,248, 60,135, 51, 52,141,169,138, 98,202, 41,151, 72,153, 46,158,166, 49,180, -143, 9,220,173,107, 5, 1, 93, 41, 64, 4,224, 97, 24, 63, 68,125, 40,114, 4,160, 68, 5,202, 68,222,193,100,160, 90,111, 36, -199,229,149,152,214, 2,160,241, 62,178,112,134, 70, 97,144, 10, 82, 25, 22,184, 69, 24,206, 80, 6,163, 12,203, 37, 89,131, 38, -124,160, 14, 54, 1,202, 42, 6, 91,208,193, 18,125, 17,212,128,187,180, 34,192,147,213, 39, 93, 56, 0,180,130, 48, 85, 16,103, -140, 33, 32, 68,163, 16, 61, 93, 72,202, 72,100, 22,123, 20,240, 78, 60,178, 66,216,198,242,200, 46,145,149, 67, 0,137, 71,116, -228,251, 20,117,114, 64, 5, 78, 70,211, 45,106, 14,181,177, 12, 1,137, 17, 41, 80, 65, 52, 95,228,224,176, 11, 5,219, 82,202, - 88,114,177, 90, 8,203, 62, 47, 70, 2, 76, 64,129, 70,240, 98,137,132, 30,151,183, 35, 46, 46,118, 80,136,232, 31, 14, 88, 88, -137,118, 33, 17,250, 91,236,247, 15,184, 85, 11,108,206,207,241,228,249, 57, 86,235,150,196, 98,135, 30,251,187, 61,121, 95, 43, - 14, 24, 60,254,165, 46,122, 28, 38, 76,195, 64,251,243, 64,200,200,166,177,184,187,160,139, 95,219, 6, 39,231, 39,120,246,226, - 49,206, 30,111,217,158,197, 30, 87,214, 33, 16,175,157,254,206,232, 3,137, 20,147, 36,166,123,123,138, 20, 35, 14, 15, 59, 92, - 95,222,176, 72, 75,241,197, 75, 57,220,159,156,156, 2,255,252,231, 76, 45,115,252, 79, 13,188,216, 2,135, 61, 94,252,232, 12, - 47,110,110,129, 93,194, 95,253,229,175,240,111,127,243, 14,235, 45, 77, 6,180,209, 72,178,196, 46,210,164,202, 24,162,104, 37, -198, 89, 22,176, 82, 41, 82,199,209,163,109, 45, 93,174, 66, 34, 69, 1,219,128, 71,163, 52, 89, 41, 60,121,165,105, 45,161,117, -170, 19,178,226,121, 22, 71,222, 89,161,168, 3,215, 37, 79,129, 87,100, 90,139, 10,132,130, 40,233, 89,129,196,123,124, 1, 21, -120, 72,206,148,130, 88,246,247,213,100,149, 73,197, 94,244, 35,229,103,250,105,196,176,247,244,123,107,139,245,118, 75,221,180, -144,213, 23, 77,177,193,212,229, 74,205,120, 83, 81, 68,104,153,114,177, 3,229,170, 23,158,133,228,255,134, 2, 79, 18,148,161, - 81,186,103,172,171, 82, 25,217,100,196, 3,135,149, 48, 8, 68,105, 5,107, 13,140,161, 60,135, 34,200, 45, 36,202,105,114, 92, -200, 83,145, 80, 46,234, 92,188,201, 44, 96, 43, 10,103,252, 81,215, 94,152,238,101,111,170, 89, 76,153, 18,193,136,168, 40, 8, - 60, 69, 40, 43, 24,134,250,212, 40, 49,212,223, 7, 40, 41,148,168, 23, 55,165,251, 53,104,187, 21, 55, 32,186,170,201,133,144, -136,137,180, 30,137, 89,249, 49, 80, 55, 27,253, 0, 63,141, 8,110,100,136, 13,185, 10, 50, 7,230,216,166,133,182, 13, 21,218, -218,212,144, 34,154, 48, 90,164, 68,209,215,161,138, 27, 37, 23, 98,146,201,116,129, 85,146, 20,113,170, 10,127, 63,135, 58, 53, - 41,211, 31,138,198,213,117, 61, 89, 52, 82,101,237,151, 83, 34,110,126,121,213,114,206,114,159,153, 13,169,238,205, 75,232,202, -156,117,158,234,247, 64, 8,114, 19, 81, 60, 10, 63,123, 41, 2,146,126, 62,173,178, 2,233,134,242,156,196, 87,254,222, 50,249, -240, 49, 84, 55, 4,253,108, 70,207,114,177, 33,164,230,194,130,155, 91, 16, 71,158, 50, 74, 18,164, 50,156,110,202, 77, 51, 3, -172,132, 36,167,126,202, 28,244, 37, 40, 3, 65,183, 45,133,172,148,106, 67,235, 98,139, 17,204,199, 37,144,130,229, 43, 39, 79, -192, 98,169,145,125,174,144,255,156, 85,133, 88,120, 71, 94,210, 50,146, 32,181,106,170, 97, 3, 4,133,209,136, 62,178, 15,221, - 49,218, 85,192, 31,237,193, 72, 81,152,176, 88, 46,224, 92,224, 12, 91, 69, 65, 31,145,170,241, 66,140, 43, 35,117,201, 95, 90, - 41, 69,245,169,131,191,144,153, 85,143,180, 3,244,245,139,112,156,142, 36,120,135,236,217,103,120, 28, 2, 80,118,116,226, 18, - 36,142, 71, 0, 0, 32, 0, 73, 68, 65, 84, 8, 33,217,118, 77, 21, 52, 17, 9,207, 0, 49,177,117,143,118,139, 82,240,158, 37, - 9, 22,224,144, 8,207, 26,205, 93,180,132,243,190, 38, 0, 21,142,125, 25, 73,106, 86, 40,151,195, 84, 41,137,144,200,191,153, -107,232,142,193, 52,142, 52,186, 2,117, 61,145,215, 42,244, 96,138, 57,100,160,178, 36,103, 61, 66,221,254,229, 92,247, 59,165, -107,209, 90,178,152,144, 71,132, 92, 49,230, 68,135, 61,169,176,169, 82,172,136,196,200,171, 27,126, 95, 67,160, 61,169, 27, 71, -214, 81, 12,240,185,169, 15,118,219, 26,108,159,108,176,222, 44,209,152,140,175,255,254,111,144, 99, 15,187,126,142, 87, 63,122, - 5,183,123,143,195,237,119,248,250,226, 15,216, 31, 18, 78, 30, 63,197,179,143,159,225,217,139,115, 8, 4, 28,238,239,113,253, -238, 61,222,191,185,196,238, 97, 95,109,153,138,159, 1, 99, 53,220, 68, 46, 7, 55,112,133,205, 54,167,171,215, 10,191,255, 91, -192, 52, 29, 86,219, 19, 60,121,254, 20, 39,231,167, 88,111, 22,128, 72,216,221,221,227,234,221, 21, 66, 8,100, 91,212,138,255, - 73, 34, 45, 42,182, 52,150,155, 83,244,187, 61, 78,207, 91,172,182, 43, 72, 37,113,241,195, 53,254,236,203,103, 0,152, 78, 21, - 70, 64, 91,190,216, 37,176,220, 0, 75, 0, 75, 9,124,253, 21,254,234,223,252, 87,252,155,255,252, 29, 86, 11,139,255,253,127, -251, 95,177, 62, 95,226,155,119,183,120,127,127,192, 20, 34,147,247, 50,154, 70, 33, 70,197, 49,162,164,109, 33,229,178,134,146, -132, 90, 85,202, 98,221, 26, 40,157,142, 58, 54, 58,147,104,181,164,171, 63, 86, 26, 89, 19, 25, 9,118, 81,124,238, 84,140,199, - 16,208,180, 13,117, 81,206, 35,241,207,173, 99,110,142,242,204, 57, 99,255,176,167, 98, 60,150,209,168, 67,138,162,178,212, 67, - 96,193,147,144,224,166,142, 83,220,202,254, 91,179, 45,202,241,232, 62, 33,165, 17,247, 55,100,131, 10,126,162,233,220, 31, 61, -179, 52, 85, 2, 68,230,103, 82,234, 57,178,146,113,177,165,107, 43, 99, 90, 64,160,105, 26, 88,107, 1,204, 66,170,192,128,167, -114, 30, 18,230,215,160, 91,116, 52,201,211, 4,196,114,163,103, 61, 66,152, 93, 49,236,143,207, 12,169,201, 28, 28, 82,253,206, - 71, 72,106,160,140,120,203,132, 3,188, 86,208, 44,118,163,137,133, 82,166, 78,199,228,209,148,176,194, 76, 56, 42,182,224, 79, - 75, 98, 23,193,168,230, 61,188,210, 6, 77,187,168, 48,172, 84, 38, 63,124, 33,136,226,142, 65,134, 68, 68, 74,164, 83,113,211, - 30, 57, 56,158, 30,122,222, 63, 43, 52,221,154,254, 62,211, 66,219, 5, 23,118,170, 50,236, 51, 55, 40,222, 7, 76,211,192,238, - 1,125,148, 66, 87,226, 73, 57, 30,152,147,207,200,136,195, 34, 98, 85, 18,208,138,128, 87,240,228,151,207,170,196,171,202, 44, - 32, 34,144,165, 56,122,143,129, 28,192,180, 53, 96, 26,135,202, 45,160,230, 53,176,150, 32,212, 98, 54,165, 8,145,232,189,242, - 33, 66,170,196,250, 32,174,194,196,172,119, 8,222,115,146,223,255,207,213,155, 60,219,150,158,103, 94,207,215,173,102,239,125, -218,123,110,147,153,247,102, 74,153,146,108,185, 85, 25,219,184,170, 2, 71, 85, 65,208, 4, 38,130,128,128, 33, 67,130, 1, 17, - 48, 97,192,204, 83,102, 4, 35,248, 19, 32, 32,160, 32,168,192,101,187,108,151,195, 14, 35,149,101,149,101,164, 82,102, 42,155, -155,169,188,153,183, 61,221,222,123,173,175,101,240, 54,107, 95, 75, 3, 73, 41, 41,207,185,123,175,245,125,111,243, 60,191,135, -238, 65,199, 73,136,133, 89, 1,181,100,228,180, 64,111, 14, 47,111,217,196,211,116, 60,107, 40, 15, 21,132, 14,181,241, 25,193, - 1,106, 42,136, 99, 11,165,222, 21,124,249, 27,217,203, 55,192, 15, 99,207,106,204,134,148, 19,143,140,150,241,220, 18,180, 50, -179,165,130,246, 34, 33,208, 31, 58,132,160, 57,188, 77, 70, 89,222,161, 20,139,113, 53,192,236,105,228, 27,231,153,237, 18,134, - 71,213,142,149,213,124, 73,176,125, 77, 80,125, 49,102,144,224, 90, 84,159, 30,182, 17,132,191,235, 3,166,109,212,120,199,253, -126,210,180, 35,129,226,148, 74,184, 60, 31, 60,179,164, 57, 99,152, 95, 84, 57, 92,164, 99,200,133,132, 60,113, 34, 75, 25, 1, - 93, 12,239, 9,139,254,185,114,170,154,110, 38,120, 69, 97, 73,236,119, 81, 99,101, 75, 46,152, 91, 85, 81, 83,228,238,145,176, -183, 52,218,179,206,106,101, 90, 88,161,191,116, 74, 7,170,103,206,180, 37, 70,116,135, 96, 27,123,132, 35, 31,180, 68,144,202, -165,232,136,150, 72,182,158, 45, 23,108, 17,226,248,192,156,121,212, 86, 50,124,215,107,231, 96, 29,249,109, 73,173,237, 17,250, -142, 5,114,140, 4,106, 85, 89,211,242, 2, 19,177,210,145,219,192,114,247,199, 33, 29,150,109, 73,150, 21,207, 42, 86, 49, 30, -251,220,161,228, 9, 93,231,112,116, 52,224,206,221, 99,188,251,205, 55,241,252,241,251,184,105, 19,206, 46,206,177,218, 56, 92, - 63,127,138,139,183, 30,193,117,207,240,233, 79,222,167,116,184,253,115, 60,123,252, 99,252,244,232, 12,247, 31, 61,194,197,253, -187,184,255,181,111,226,238,163,111, 32,167, 8,107, 43,226,126,143,105,191,195,126,187,197,246,230, 22, 87,175,174, 41,223, 32, -243,222,188,239,180, 88, 51,214, 96,222,223, 34,206,123,220, 92, 18, 11,127,125,116, 4,223, 13,184,115,247, 2,247, 31, 62, 68, - 8, 22,183, 87,215,120,245,242, 37, 94,189,120,133,148, 50,186,190, 35,140, 50,135,108,228, 84,112,125,115,139,147, 93,196,122, -179,194,171,167,215, 40,239,189, 1,119,123, 3,108, 54,128, 63, 3, 48,243, 37,207,121,204,168, 64,127, 4,188, 0,254,233,247, - 30, 99,218, 71,124,237, 98,131, 95,251,143,255, 46,176,234,240,205,109, 4,126,252, 62,190,252,155,143,241,185, 89,227,133,239, -144,184, 59,110,141,222, 19,154, 84, 88,158,224,200, 62,209, 98, 28,131,182,111,244,189,103,216,222,178,200,102,193,188,182, 86, -104, 95,103, 45, 26, 63,147,150, 11,200, 20, 27,179, 19, 50, 66, 32,161,102, 48, 78, 69,155, 41, 87, 21,197,154, 86, 94,195,114, -230,196,136,203,182, 40,183, 73, 12, 75,112, 20,219,220, 65,148,100, 85, 82, 99,173, 70, 59,177,192,118, 48,234, 90, 88,240,202, - 12,120,178,254,116,140,177,117,250,115, 96, 40, 36,167, 49,152, 73,248,220,222, 27,196, 10, 14, 46, 33,231, 71,215,119,122,198, -200,180,177,176, 18,190, 10, 45,210, 59,172, 86, 3,233,116, 60, 21, 58, 4, 25, 73, 42, 48,171,234, 96,161,139, 56,231, 3, 1, -165,179, 10, 0, 18, 0, 73,227,212, 72,175,233,151,203, 90,164,240,206,223,242, 26, 68, 88, 8,196, 70,169, 7,222,115,104,113, - 78, 26,130, 70,163, 90,213, 16, 64, 45,101,222,119,232,251,113, 41,230,100,252, 93,193, 13, 25,233,115,136, 33, 80,145,230, 25, -105,218, 98,222,223,162,230,153, 11,249, 4, 52, 34,152,117, 97, 68, 55,108, 96,195,128,208,175, 40,160,136,243,204, 41,200,132, -138,188,105, 46,152,247,123, 6,178, 88,248, 78,220, 2,225, 64, 48,204,136,217, 86,153,223,222,212,194,149, 75,102, 97,174, 20, - 92, 85,215,184,146,191, 78, 89, 26,105,209,242,184, 37, 14, 92,138, 23,203,247,147,132,173,136,136, 48,206,145,113,202, 73,193, -100,181, 25,222,171, 51,205,142,148,113,220, 73, 87, 78,148, 59, 16, 98,114, 74, 31,233,175,162,174,104,228,126, 2,128,220, 10, -219, 48,235, 65,186, 30,137, 87, 13, 39,189, 25, 41,167, 10,231,170, 75,186, 95,181, 48,166,168,213,174, 73,209,192,130,101,154, - 62,112, 94,169,181,240,180,123,113,154, 43, 30, 35, 33, 13, 73, 69,235, 25, 64, 66,163,190,148,104,132, 98, 29, 93,228,125,223, - 83,124, 34,135, 39,144, 39,214,105,152, 65,138, 73,187,217,156, 43,166,105,198, 56,246, 40,220,201, 27, 70,186,210, 14,210,243, -200,106, 94, 18,214, 12, 29, 22,214, 58, 30,145, 17, 2, 81, 16,151, 37,145,122,181,239, 59,254, 29,204, 66,186, 99, 91,136, 68, -163,154, 82, 57, 90,177,233, 5,147,115,133, 67, 33,180, 38, 63, 8, 93,239,105,151,102,248, 65,227,200, 87, 99, 40, 96,160,212, -202, 25,202, 29,225, 66,115,225,100, 36, 6,110, 57,226, 6,199,105,210,142,214, 89,139,221,156,152,221,236, 16, 39, 14, 46,169, -237, 32,217, 40,195,119, 30,211, 52,107,244,167,236,155,100,215,223,224,116, 47, 84,115, 38, 72, 7,239,132,114,169, 58,230,174, - 57,195,120,218, 55,145, 16,138, 19,246, 28, 9, 1,189,183,250, 66, 21, 33, 57,241, 75,228,120,135, 46,187,116, 88,163, 93, 17, - 81,172,205,146, 26,196,123,156,106, 13, 66, 63,234,197, 86, 88,180,102,172, 97, 69,244, 97,202,145,129, 63,126, 27,123,158, 38, -173, 87, 61,142,143, 87,184,255,198, 25,142,143, 60,158,236, 94,225,237,119, 31,161,235, 59,218,129,206, 17, 79, 62,250, 9, 76, -127,134,175,255,226, 47,225,131,127,249, 3,236,182, 91,212, 90,113,115,249, 2,207,191,248,148,160, 63,221,136,163,179,115,108, - 78,206,225,251, 21,206, 47,206,112,126,255, 45,140,171,192,120,220,172, 2,150,156, 51,186,224,176,219, 77,136,211,140, 24, 35, - 9,120,230, 8,199,211, 38, 58, 64,102, 60,121,252, 83, 60,254,176,162, 27, 55,184,115,239, 14,238,220,123,128,119,190,177, 66, -205, 17,151, 47, 94,225,217, 87,207, 49,177, 77, 48, 4,234,228, 47, 95,190,196,231,159,124,129, 23,159,221,226, 15, 34,240,198, -143,159,224,205,251,199,184,255,232, 14,240,230, 49,112,210, 1,227,200,251,210, 6,192,225,179,159,222,224,233,237,132, 6,224, - 27, 71, 14, 72, 91,224,244, 12, 56, 30,128,175,122,124,240, 23,239,163, 25,135,247,126,235, 87,240,189, 39, 59,164, 97,192,131, -135,231,216, 28,143,168,149,194,112, 90, 51,252,125, 86,214, 81,208,200, 53,197,164, 97, 36,162,148, 37, 62, 3, 3, 48, 88,240, - 21, 99, 60,152,214, 88, 37, 34,214, 82, 17, 44, 67,157, 88,208,102,216, 30,103, 44,141,205,125, 35,141, 75,215, 5,118,106,136, -229,137, 84,195, 21, 52,174, 52, 86,242,163,157,186, 73, 2,243,246, 75,109, 10, 10,145, 11,130,108,119,141, 47,115, 15,107,121, -143,107, 23, 33,159, 28,104, 50,169, 11, 61,225,118,157,138,110,147,238,221,189,163,137, 70,232,250, 37,150,249,192, 75,221,120, -135, 75,118, 61,139, 16,156, 66,124,200, 49, 66, 59,234,221,118,226,241,120,225,209,114,214, 61,104,230, 49,108,107, 34,188, 74, -139, 70,133, 71,164,181, 46, 22, 63, 17, 80,153,131,203, 88,127,167,218, 22,151,132,138, 92,205,114,161,243,136,121,209, 92, 36, -250,238, 37, 29,210, 58,116,221,136,192, 43,151,192,201,145, 82,132, 56,111, 17,140, 71,131,165,221,116, 73, 40,105,194,180,187, - 69,142,123,212, 60,233,206,190, 85, 90,171,116,253, 26,227,230, 28,161,167, 46,189,192,193,177,167,159, 87,254,108,247, 37,188, - 47, 56,104,171, 54,131,154, 5, 8,100,145,107,211, 51,179, 86,210, 19, 20, 22,160,129,237,120,133,189,229,141, 5,104,244,247, - 38,157,150,116,167,113, 90,116, 9,173, 22, 84,231,217,161,228,184,152,178, 26,191, 43,182, 70, 89,115, 80,144,204,164,141, 83, -202, 34, 6,174,124, 33,179, 82,157,155, 43,103,205,146, 5,193,162,218, 90,210, 1,255,160,161,177,206, 64, 92, 2, 50,161,168, - 53,190,246, 93,137,168,211,178, 5,177, 52,163, 29,187,101,145,105,225,187, 7,150,180, 68,212,128, 19, 27,192, 54, 32,151,164, -118, 64,240,123,224,137,102, 69,212,165,105, 74, 88,173, 87,152,246, 19,239, 63,170, 66,243, 69,172, 64,118,167,136,156,105, 76, -100, 83,162,202,151,119,224,104, 64,215,123,220,222, 52,149,248,231, 76, 31,182,120, 27, 67, 71,213, 80,223,247,122,232,103, 38, -204,201,135,107, 88, 4, 34, 44,247, 38, 49,128,188, 55, 17, 97,155,177, 70,211,205,108,112,170,136, 53, 88, 50,158,199,149, 85, -133,183,140,217,193,251,140,194, 22,180, 16, 2,163, 3, 51,141, 14, 61,237,218, 83,165,138,186,235,137,127, 60,140, 61, 66,215, -113, 81, 65,154, 3,218, 53,210,158,149,196,104,153,252,150,206,192, 5,143, 24,103,229,223,203, 36, 68,198, 79, 20,161, 73,190, -204, 24, 19,197,179,242, 30, 41, 56, 81,241, 59,228, 2, 37, 30,165, 73,168, 92,132,127,149,132, 33, 2,246, 16,154, 81,184,197, -173,146, 0, 78, 84,244,206, 5,173,236, 66,215,147,191,152,247, 81,180, 66,112,252,226,118,180,223,135, 96, 16, 73, 99, 80,234, -226,195, 36, 17, 23,217,124, 72,143, 65,121,224,141, 71,128, 4,206,161,135, 90,128, 57,214,247,176,227,125,228,235,136, 16, 44, - 54,155, 30,231,119,142,240,230,163, 11,108,159,125,130,187, 15, 46, 52,175, 56,165, 61, 74,109,120,254,229, 19, 76,251,143,240, -242,252,109,252,194,111,254, 93,124,242,163, 31,226,201,103,159,169,168, 47,198, 25,102,191,199,238,246, 10, 95,126,246, 9, 71, -239, 6,116,227, 6, 71,167,103,120,240,214, 61,220,185,119,138,243,139, 99, 12, 67,192,238,118,143,235,171, 91,236,182,147,170, -173,189, 31,208,245, 43,116, 67, 71,104,223,102, 52,184,135, 96, 47, 22, 41, 82, 90,219,228, 13,134,113,196,221, 55,223,196,241, -233, 57, 90,203,216, 28,141,168,181,226,242,229, 21,118,219, 61,158,253,236, 10, 67,232,241,234,114,135,237,118,198,103, 63,123, -133,245,143,159,224,120,237,113,113, 50,224,237,135,167,112,111,157, 1, 23, 27,160,183,248,127,191,251, 1, 42, 12,110,211, 14, - 62,238,129,159,252, 24, 24, 45,112,239, 1,112,247, 4,255,198,127,242,171,120,255,123, 79,241,239,254, 55,255, 35,182,200,136, -104,120,100,239,224, 63,248,183,126, 13,255,245,127,245, 59,248, 12, 6, 87,115, 66, 9,142,179,165,185, 96,179,180, 34,104,181, -161,235, 45,166,253,204,157, 56,244,192,107,236,182,232,122,207,107,151,166, 22, 46,112, 54,132, 92,144,164,190, 61, 84,158, 55, -180,230,200,155, 95,178,238, 25,227,156,248,146,106,203,197,201,226, 38, 42, 58, 36, 99,251,111, 69, 25, 91, 58,172,104,188,207, - 25,245, 48,140,134,165,125,185,231, 81,172, 4,158, 88, 3, 5,231,144, 19, 5, 58,189,232,135, 30,109,162,244,171,190, 39,160, -207, 48, 44,113,206,148, 56, 71,100,187,148, 50,226, 60,169,133,208, 89, 58,111,134,177,167, 38,132, 47,195, 28, 51,219,116,137, - 79, 31,231,153,157, 63, 9,153, 93, 39,214,154, 69,159,196, 30,102, 25,245, 74,225, 36,226, 66,103, 9, 35, 43,108,124,154,110, -155,131, 8, 88,171,249,222, 49,103,181, 86,137, 19, 5, 26, 96, 82,232,191,115,130,224, 38,186,161,239, 2, 66,232,153,211, 97, - 53, 9, 47,114,234, 87, 3, 21, 18, 41, 39,228,121,135, 52,237,144,211,132,154, 39, 30, 21,179, 0,203,123,116,195, 17,250,241, -152, 46,244,110, 5,235,123,142,152,134,226,180, 35,139, 69,247,187,253, 50,193,224, 21, 0, 49, 63,154,134, 38,201, 26, 1,166, -234, 84, 80,196,101, 57,165, 3, 7,128, 99, 97, 49, 59,119, 26,208,210,196,190,242,194, 34, 65, 42, 0,172, 76, 59,185,144,106, -172, 49, 0, 7,207,104,195, 87, 43, 1, 98, 88,152,109,125,167,103, 29,173, 89, 51, 59, 1,120,128,234, 73,147, 84,170,225,243, -174,162, 36,246,156, 84,182, 75, 58,199, 90, 14,137,112, 53, 92, 84,100,133,216,208, 58,198, 82,115,204,100,198,170, 43,135, 69, -105,159, 19, 33,117,155,104, 79, 80,152, 39, 98,153, 32, 71, 19,236, 37,233,148, 62, 63, 47,218,123, 98,190,211, 75, 86, 89,129, -103, 76, 62, 0,203, 88, 30, 84, 83,146, 80,201, 5,232, 73,184, 16,124,224,202,208, 50,196,194, 97, 28, 71, 26,219,165,196, 35, - 38, 30,255, 57, 15,107, 11,194, 24,248,101, 44, 64, 58,140, 65,132, 42,229,115,110,176,174,160,121,167,185,236, 34,188,241,222, -161,194,243, 65,226,216,234, 32,209,153,164, 26,239,122,143, 97, 53, 48,254, 53,243,184,177, 32,167,170,180, 56,176, 53,194, 48, - 34, 54,165,138, 97,236, 73,208,229,157,142,126,228, 3,147,209, 52,169, 95,179,242,123, 67,231, 49, 79,116,176, 17, 24,135,232, -112,173, 26,246,190, 50,188,197, 27,152, 44, 2,193,202, 65, 6, 77, 81,161,100,115,240, 76, 8,163, 9, 74,230,252,250, 28,137, -112,150,115, 98, 72, 71, 81,241,154,236,226,187, 46, 80,161,147, 73,253, 78,145,144, 28,225,231, 3,251, 33,229, 65,171, 7, 30, -226, 78,133, 59,174, 11, 60, 46,171, 58,233,168,188, 55,247,146, 28,197, 66,145,214, 40,166,212,178, 53,166,178,117, 45,167,229, -192,161,200, 64,234,236,252,250, 1, 82,113,240, 78,112,170, 35,222,120,120, 7,182, 77,120,241,236, 57, 11, 84, 12,226, 52, 97, -119,187,195,229,243,151,200, 49,162,213,130,155,103, 31,227,175,254,252, 18,191,248,235,127, 7,239,124,243, 61,252,245,119,255, - 18,183, 55, 55,154, 76, 85, 10,116,122,208,106,197,188,203,152,119,151,120,249,213,231,148,146,118,114,138, 71, 95,127,132,135, - 95,123, 11,239,254,252,123, 40,185, 96,191,221,225,230,250, 26,215,175,110, 40,202,115,159,176,187,161, 34, 51,231,130,253,110, -135, 56,207,136, 49,241,243, 65, 35,224,126, 92,227,244,252,140, 3, 82, 10,118,183, 59,132, 16,240,240,157, 55, 48, 14,107,228, -203, 25,171,163, 99,212,210,144, 80,104, 87,152, 11,182,219,134,103,207,111,240,225,167, 47, 48, 4,139,139,179, 17,155,206,224, -207,191,255, 41, 86, 99,143, 82, 11,142, 6, 15,220,220, 0,223,253, 43,224,235,239, 0,131, 1, 30,222,193,201,119, 31,227, 25, -246, 40, 0,254,145, 61,195,186,171,248,232, 7, 31,226,206,119, 30,226,206,186, 7,174,182,248,228, 47, 63,197, 39,151,147,134, - 32, 25, 67, 69,123,225,245,210,106,179,214,203, 70,196,152, 33, 56,181, 63,209, 74, 8,188, 19, 23,220,114,143, 56,205, 8,220, -105,139, 43,195, 7, 7,195, 9,119,253,208, 33,205, 13,153,247,178,214,121,196, 52, 49,149, 77,108, 87,141,242, 10, 88,203, 33, -145,197, 6,139,253,147, 52, 47, 52,233,233,186,142, 2, 63,102,178,130, 58,177,224, 97,137,109,166, 52, 45,192,241,106, 13,156, -223, 77, 10,126,218,223,110,216,249,162, 26, 0,107,120,143, 79,251, 86, 89, 11, 73,138,150, 20, 24, 34, 38,116, 28, 56, 83,114, - 89,248,108,173, 34, 39,234,234,231, 57,170,208,213, 26,131, 92, 23,148,173,116,203,130, 91, 54,102,217,147,162, 73,151, 90, 15, -152, 25, 70,145,205,170, 87, 64,211,142,159,238, 60,142, 16, 45, 69,197,114,149, 29, 38,100,133,162,104,226,208,245, 12, 97,241, - 68, 26, 11,157,126, 55,250,185,137,214, 33,206, 72,243,158,186,243,146, 22, 75, 21,200, 82,229,187, 17,227,234, 24,214,119,176, - 97,128, 13, 35, 90, 35,177, 96,232,188,134, 91,181, 70, 23,216, 60,199, 37, 49,142,227,176, 43,127, 95,206, 49,114,182,208, 20, - 5,173,194,153, 10, 27,130, 78, 81, 11,191,243, 68,168,147,166,165,232,154, 68, 32, 60, 37, 87, 22,247, 10, 60,198,211,197,104, - 28,103,154,211,157,101,140,132, 24, 57,181, 17, 54,206, 16, 81,123, 32, 11, 56, 73, 40,110,244,190, 49,198, 40, 81,208,123, 15, -148,172, 13,175,225,240, 21, 21, 3,231, 66,171, 37,107,168, 80,225, 63,115,173,146,191, 46,235, 38,214, 27,241,243, 86, 36,147, -225, 32,186,213,250,192,171, 30,163,247,107,147,248, 92, 6,138, 44,206, 24,168, 55,222,231, 68,213, 69,158, 35,179,218, 73, 92, - 81, 12, 48,207, 51,169,183,173, 69,232,189,166, 27, 9,142, 48,197, 8,191,162,139,178,115,157, 86,160,214, 57,244,131,209,125, - 60, 41,103, 3,128,172, 56,212,146, 11,108, 32,106,220, 48,200, 8,154,173, 60,124, 65, 53,199,201, 98,185,192, 27,242, 15, 82, -134,184, 69,205, 70,121,202,251, 29,133,116,152,234, 88,213,184, 68,170, 74,154,220, 66, 61,195,130, 23,180, 22,222, 57, 86,192, - 27, 20,166,102,197,200,220,223, 66, 9, 88,165, 52,180,148,105,132,229, 73,197,158, 35, 87, 92,156, 17, 79, 10,235,194, 30, 98, - 14, 27, 56,168,246,112, 16,223,153, 18, 77, 37,170,238, 70, 42,217, 75,204,178, 4, 91,173, 6,238, 80, 28, 60,239,126, 42,243, -127,173,105,136, 28, 76, 32, 2,184, 90,170,118, 55,168, 96,255,184,209,100,173, 90, 43,226, 52, 83, 65,196,137,119,134, 25,225, - 34,194,105,104, 8,189,231, 67, 67, 42, 63,222,157,242,206, 74,214, 20,214,123,206,137, 95,113,134, 60, 21, 9,193, 89, 76,251, - 73,149,154, 41, 70,181,103,133,174, 67, 56,121,136,219,151,145, 67, 90,122,156, 95, 28,225,236,124,141,191,252,103,191,135,235, - 87, 47,153, 53, 13, 76,251,137, 18,185,120,207, 24,186,158, 70,157,183,207,240,151,127,252,135,120,251, 91,191,132, 95,251,237, -223,198,147,143, 63,194,199, 31,124,136,105,191,167, 93, 30, 11,115,186,161, 71, 73,180, 34,162,253, 91,198,237,245, 37,126,244, -131, 75,252,171, 31,254, 24,155,163, 35,220,185,119,129,211,139,115,172, 55, 35,142,207, 78,145, 18,229,113, 75, 84,103,206, 25, -199,233, 8,149, 35,132, 75,230,176, 17, 67,240,162,146,119,184,185,218, 99,125,116,132, 7, 15, 31,192,152,138, 23,207,158,225, -233,251, 79,208, 95, 94, 82,231,181, 58,226,189,178, 81,184, 76,140, 25, 41, 27,220,222,102,188,124,181, 69,142, 9, 95,189,218, -147, 87,181, 53,188,255,228, 26,248,224, 57,112,113, 4,164,199,192,233, 10, 24, 3,126,248,170, 96, 15, 96, 3,131,255,238,191, -248,109,124,251, 63,252, 21,224,197, 22, 56,237,128,213, 6,240, 21, 95,251,133, 11,124,254,199, 31,163,244, 29,139, 25,161,221, -158, 21,186, 26, 42,235, 91,232,157, 18, 32, 71,227,152, 79, 11, 79,108, 5,217, 7,102,131,205,113, 80,173, 80,140, 25, 61, 43, -167, 91,171,234, 83, 39,234, 90,193,170, 54,122,214,152,120, 88,121,172, 46,235,151,208,117,234, 90, 16, 46, 56,173,225,178, 88, -114,152,165,207, 24, 92, 99, 88, 27, 66,135,161,239,122,141, 62,166, 72, 79,154, 0, 52, 35,112,152,142, 59, 36,246,117, 55,154, -230,228,152,216,210,190, 20, 21, 53, 23, 76,251, 9, 41, 37,236,110,119, 36,170,147,119,166, 16, 43,195, 49,187, 67,136,147, 49, -102,125,159, 39, 78, 7, 51, 60, 73, 20,111,186,164,185,137,198, 69,240,159,220,235,105, 19, 35,254, 98,107,196,122,181, 88,222, -156,243, 42, 32, 44,117,193,160,210, 36, 0, 58,105, 36,106,154,196,113,114,180, 39, 35,112,189,239,216, 61,211, 41,147, 35,231, - 12,240,154, 35, 83,254, 41,230,105,143,146, 39,181, 95,149, 60,115, 26,156, 67, 8, 61,134,205, 49,140, 9,176,174,131, 11,131, - 10, 81, 29, 35, 89,165,235, 78,145, 28, 39, 85,125, 87,178, 66,245,122, 41,138, 59, 68, 72,158,214, 54,216,208,163,230,196, 24, -235,162,147, 89,177,209, 9,183, 62,151,172,107, 10, 42,222,185,144,169,145, 48,209,168, 0,220,107,218, 3,212,204, 73,104,102, -241,159, 91,138,125,109, 57,163,177, 94, 74,114, 48,100,202,178, 36, 19, 90,250,123,212,134, 20,171,234,179, 40,114, 56,106,246, - 72,101,168, 19,216, 65, 84,138,225, 98,162,112,192, 78,123, 45,209,142,196,157,134,139, 21,175,174, 16,210,249,176,224,142,199, -238,165, 45, 56,247, 74,131, 13, 42, 4, 89,111, 98,157, 69,102, 17,158, 87, 50, 19, 87,108,228, 75,173,203,216,155, 95,196,194, - 81,130,228,217,244,156,204, 54,147,197,234,216, 99,191,219, 83, 76,231,122,212, 15,174, 99,101,169, 8,122,156,117,228,202,108, -132, 85,181,140, 56, 77,169,113, 80, 12,237,240, 36,164,196, 88,131,113, 53, 96,154, 18, 76,240,100, 25, 59,200, 71,151,181,136, -252,238,172,240, 99,129, 79,193, 48, 24,166, 66,209, 88,177, 52,195, 98,181,162, 84, 40,177,233,165,148,149,207, 59, 12, 1,187, -109, 81,161, 5,121,157,249,231,115, 48, 68,140, 76,124,178, 52,118,163, 42,191,106,119, 92, 57,225, 71, 98,253,140,133,126, 41, - 29,179,176, 11,119, 11,158,133, 62,242,121, 43,121,139,173, 35,187,219,157,198,166,150,156,144,227,196, 35,183,170,187, 55, 90, - 23, 80, 48,135,164,191,161, 86,205,131, 54,188,187, 34,127, 60, 17, 1,101, 52, 36,162,200, 90,201, 97,224,248,133,162, 46,161, -106, 81, 4, 48, 46,177,210,103,236,124, 0,172,103,122, 26,125, 1,153, 73,116,137, 85,211,243,204, 35,238,218, 96,250,115,228, - 26,224, 92, 68, 8, 14,155,205,128,251,111,158,227,250,249, 19,124,249,248, 99,182, 11, 86, 30,225, 82,183,182,168,136,232, 69, -233,250, 1, 57, 23,124,254,225,223,224,201,227, 79,240, 11,255,218,175,225, 55,223,124, 3, 31,255,228,125,124,254,233, 99,174, -188, 41,174,182, 27, 71,178,117,213, 6,231,141,238,188,188,111,184,190,122,133,219,155,107,124,250,209, 39, 88,109,214, 56, 58, -230,216,212,190,131, 15, 14,113,158,201,166,148, 18, 51, 18, 60,219,191,232,178,235,250, 97,217, 75, 58,143,105,183,197,209,201, - 49, 78,207,238,192,223,141,184,220,101,236,159, 62, 71,184,111,129,245,102,193,142,178,199,187, 85,113, 86, 87, 76, 49, 35, 38, -234,220,188,181,248,103, 79,158,227,191,252, 31,254, 12,247,142, 71,124,237,222, 17,190,253,206, 57,142,143, 71,252,207,255,247, - 95,147, 77, 8, 6, 23,191,240, 30,240,157, 95, 5, 2,241,187,177,189, 6, 94, 93, 2, 87, 79,241,247, 47, 26,126,255,171, 45, -127, 22,150,199,195,150, 15, 98,199,235, 37,175,105, 99, 68,120, 35, 45, 65, 97, 96, 84,138,137,169,111,172, 34,231, 76, 3,209, - 99,100, 6, 23, 9,143, 33,197,140, 56, 71,210, 84,112,144,143,239,122, 85,209,199, 57, 29, 88,146, 0,223, 81, 65,141, 3,190, -129,116,156,198, 58, 12, 12,108,113,140, 76,150,208, 28,239, 45,166, 41,161, 11,142,119,213,228,223, 46, 18,230,196, 98, 65,239, -140,198, 17,203, 58,143, 98, 62,163, 22, 55, 41, 38,164,148,105, 66, 35, 26,152, 6, 52,126,199,137,186,182, 48, 24,100, 77,216, - 88,212, 84,152,115, 95, 57,130,180,148,204,235, 38, 22, 69, 49,140, 68, 2,114,164, 35, 44, 69,244, 40,137,127,151, 69,111, 98, - 32,135,124, 80,113, 43, 57,137,200,162,122,152,196,183, 40,250,139,174,224,140, 76, 92,172, 71, 63,172,225, 67, 15, 31, 58, 10, -107,169,226,222,225,241, 61, 72,160, 53,239,183,168,101, 98,228, 54,237,212, 5,200, 21,186, 1,227,250,132,222,115,227,121, 82, - 66,171, 70,231,173, 78, 14, 74, 46,216,239,103,196, 56, 83, 99,101,192,211, 62,234,152, 75,109,108,243,204,156, 25, 95, 25, 30, -197, 35,100,246,128, 19,216,170,233,232,156, 58,225,170,212, 67, 97,163, 44,104,215,136, 90, 34, 39, 47,122,221, 47,211,191, 46, -187,120,113, 69,229, 2, 22, 17, 51,207,221, 46, 58, 0,137, 42, 46,236,193, 39,232, 80, 83,154, 40, 90,227,198,161,170,143,125, - 89, 65,209, 51, 88, 90,101, 59,101, 85, 60,177, 4,146,121, 31, 56,171, 65,220, 34, 18,212,196,116, 58, 94,179,192,200,234,134, -236,152, 41,237, 57,200,135,214,161,198, 84, 45, 32,205,129, 62,130, 2, 0, 12,188,204,226, 51,239,105,188,119,176,134,198, 94, -212,141, 36, 89,241,210, 5,196, 54,151,142, 45, 45,165, 22,108,183, 59, 28, 29, 31,105,232, 72,224, 46,193,243, 23, 79, 63,124, -166, 78,155, 43,149,146, 43,250,245,128,146, 35,239,156,132,160,100,121, 23,158,129, 92,113,117,121,203, 41, 90,157, 94,216,178, -211, 67,245,168,166, 49,141,167, 80, 86, 47,172, 86,193,198, 58, 37, 36,249, 96,217,183,189, 92,122, 18, 98, 81,106, 99,180, 32, - 85,232, 57,147, 72,162, 54,195, 95, 36, 29, 64,149,191, 32, 33,135, 53, 99,104,175,206,138,106,217,237, 24,222, 81,213, 92, 84, - 33,235,188,211,208, 1, 41,164, 8, 40, 67,194, 29,217,177,117, 93, 80, 27, 77,201,141, 46,242, 68,213, 40,189,180,149,233,125, - 20,145,104,189,248,152,217,118,198, 49,137,144,253, 36,199, 45,202,129,186, 88,189,196,142,181, 8,133, 66,215, 43,133, 78,130, - 21, 4, 28,228,248,240, 49, 48, 48,206,194,119, 52, 89,112, 62,104, 10,145,178,139, 57,188, 98,218, 79,212, 53, 32,195,120,143, -112,242, 8,219,125,132,119, 22,171, 85,143,243,139, 99,156,223, 89,227, 15,254,151,255,147,254, 44, 69, 80,141, 18,198, 33, 88, - 84, 74, 5,132,190, 28, 14, 49, 53,228,249, 22, 63,250,222, 95,224,193, 59,239,226,221, 95,252,101, 60,120,248, 22,126,250,175, -222,199,246,118,187,196,101, 50,159, 91,194, 24,188, 55,186, 91, 20,119,199,126,123,131,105,191,195,229,203, 14,171,205, 6,231, - 23,119,176, 62, 26,209, 15, 3, 51,170,111,113,115,117,141,155,235,173, 98,125,133, 24, 23, 66, 32,135, 69, 8,216,111,119,120, -245,233, 43,156,216,128,205,131,187, 24, 78,143,145,231, 25,213,189,206, 61,247, 65, 14,242,202,106,117,122, 94, 60,135, 75, 92, -161,226,127,122,254, 57,218,243,134,240,145, 65,248, 11,122,101, 39, 52, 84, 0, 3, 60,198,205, 26,232, 70, 96, 53,128,232, 50, - 35,176,138, 64, 44, 48, 23, 3,222,189,186,198, 71, 51,225, 58,199,224,116,250,146, 34,219, 80,115,194, 60, 17,171,188, 31,123, -220, 92, 77,164, 88,103, 98, 23,233, 9, 10,226,204,171,159, 92,244,114,115, 22, 58,126, 36, 62,117,102, 2,159, 20,254, 86, 33, - 80, 66,137, 35,175,246,146, 89, 64, 35,233,138,224, 45,195, 73, 72,180,229,189,125, 13,188, 65, 40,226, 5, 87, 13, 52, 12, 67, -224,137,160, 81, 21,115,222,237, 57, 26,180, 48, 38,182, 2,178,207,231,162,151, 68, 84, 52,129,203,153,176,174,211,126,210,252, -108,129,130, 72, 48, 19,141,207,169,144,239,123,203,156,123, 74, 80,243,157, 99,252, 52, 21, 11, 37, 31, 94,184,141, 47, 34, 97, - 30, 64,201,114, 58, 21,209, 96, 37,241,243,147, 3,193,184,165, 16, 17,229,180, 10, 98,154, 36, 55, 54,125,111,151,168,104, 86, -111,135, 1, 62,244,228, 29, 15,129,221, 1, 65,149,211, 51,199, 11,183, 76,186,128, 20,103,234,202,173, 1, 74, 98,175, 53,141, -234,251, 97,131,208,175, 96, 92, 96,208, 75, 37, 12,171,101, 90, 31,168,227,142,251,200,171,170, 61,159,153, 52,197,132, 49,216, -239,147,194,189,248,170,166,243,194,210,231,233,250, 30,176, 6,133, 45,115, 34, 76,166,221, 54, 61,191, 53, 39, 22, 41,146,185, -173,240, 56,187,164, 25,181, 70, 6,164, 5, 14, 73,225, 56, 89, 88, 93,135, 88, 71, 63, 3,198,193, 91,163, 83, 68,103, 27,119, -249,230, 64,100,188, 36, 87,202,234,168, 52,206,194,104, 21, 45,211,101,157, 82, 97,150, 0, 79, 75,234, 98,153, 52,156,243,209, -248,238, 16,118, 73,102, 29, 1,145,242, 12, 74,201,180, 51,111, 88,178, 51, 74, 93, 8,156,206, 33,229, 4,231, 59,246,222,155, - 37,167,133,145,191,185, 20, 21, 24, 54, 48,120,233,223,255,173, 95,253,221,156,104,196,238,236, 1,133,136, 91,122,107, 12, 18, -251,186,105, 12,212, 56, 75,124,153,227, 23, 94,252, 11,188,198,170, 87, 81, 68, 8,237,181, 4, 53,207, 33, 22, 57, 87, 5, 57, -164, 20, 53,234,211, 48,173,170,239, 59, 86,139,202, 56,221,243,197, 71,113,117,125,231, 15, 70,189, 22, 33,116,228,193,229,180, -161,113,236, 57,141,140,236,114, 98, 99, 3, 11,111, 36, 46,211, 26,167, 98, 34,203,137, 62,173, 25,177,253,169, 74,150, 72, 70, - 84,184, 8,189, 46,167,140,105, 71, 41, 92,161,243, 26, 31,233,157,209,253,190, 4, 11,144, 15, 56, 49, 33, 47,171, 7,189, 31, - 6, 66,222,242, 69,145, 11, 17,172, 74,202,186, 71,175, 37,161, 11, 34, 88,108, 7,145,139, 75, 42,221,114, 24, 26,221, 57,170, - 74,211, 57, 93,141, 40,183, 24, 84, 68, 88,222,231, 75, 39, 87,106, 85,205,128,172, 50,104,186,210,241, 1,215,195,119,157,142, -137, 28,199,205, 54, 14,190,153,167, 9, 41, 70,214, 98,240,197,236,143, 96,199, 55,200, 17, 49,120,156,223, 57,194, 59,239, 61, -192,211, 79, 63,196, 7, 63,252, 1,143,235, 36,224,162,113,145, 34, 10, 93,210,122, 72,210, 86,227, 96, 25,176,226,117,218, 94, -227,249,211, 87,184,120,240, 38,222,126,239, 29,172,120, 90, 20,186, 14,227, 72,176, 26, 26, 55, 59, 18, 34,242, 69,223,245, 29, - 12,131,142, 66, 8,186,183,220,239,119,184,189,222, 98,154, 34,237,161, 87, 43,172, 54,107,172,214, 35,101, 31,100, 42,228, 98, -140,216,110,119,152,166, 25,183, 55,183,120,249,244, 18,223,253,227, 31,227,241,135, 95, 32,199,130,205,233, 6,171,187,231, 88, -157, 29,115,156, 34, 19, 4,217,151, 45,135,163,183, 22,119,206, 54,120,239,209, 5,126,241,221, 7,248,185,187, 15,240,243,235, - 11,108,110, 44,108,105,216, 34, 33, 46,110,119,156,161,199, 55,223,120, 7,253, 87, 87, 56,125,122, 9,179, 57, 6,206, 31, 2, -214, 98,254,243, 31,195,143, 43,124,249,254, 19,124,190,163, 98, 86, 84,212,212,137,115,103,157,178,242, 20,230, 41,106,200,133, -168,214,169,115, 46, 10, 39, 34,129, 79, 98, 97, 39, 41,172, 73,131, 48,107,183,154, 18,137,155, 44,150,224, 32,177,168,102, 73, -207,170,228, 69,119,236,150,145,239,130,224, 49,172,201,112, 94,197,150,149,243, 11,196,226, 36,118, 92, 73, 12, 91,160, 46,132, -205, 53,252,108,203,248,221,176, 93, 85,198,233,148,218, 55,161, 20, 42, 58,229,240,173, 44,136,181,220,185, 81,151, 20, 48,114, -204,106,232, 2,197,198, 98,129,105,197,148,232,239, 55,199,215,104,127,153, 67,106, 4, 62,179,136,189,140, 78, 65, 15, 65, 59, - 11, 47,130, 46,222,190,163, 51,108, 92,141,252, 46, 47, 98,174,156,242,223, 10, 82,226,207, 57, 83,180,179,247, 61,250, 97, 68, - 55,140,232,250,129,223,119,230,116, 48,119, 3, 45,179, 37, 54,233,174, 23,181,160, 22,218, 99,119,253,136,213,230, 4, 97, 88, -195,186, 0,195, 98, 45,193,111, 11,179,160,129,196,179,243, 28,233,179,172,242, 59,114,230, 69,229,169,101,101, 92,111, 91,162, - 97, 37,131, 60,231,140, 86,146,230, 85,104,156, 45,103,102,148,156,208,176,144, 43,201, 62, 72, 99,119, 77,162,179,158,232,106, -138,205,110, 75,224,149, 11,186,198, 52,188, 2, 32,218, 93, 85,161,168,172, 37, 12,167,117, 90,179, 48, 75, 52,246,186,102,245, -151,107,184,150, 88,192,121, 74,130, 70, 77,152, 36,158,138, 85, 84,118,190,202,204, 87, 40,167,103, 91, 27,111, 93, 89,224, 41, - 52, 84,186,172,151,204, 17,192,168,125, 81,238,150,198,213,239, 2,139, 50,112,255,206,111,252,242,239, 90,222,167, 90,101,161, - 27,141,220, 52,172, 70, 39,161, 80,101,213, 37, 94, 3, 7, 56,103,181,187,236,250,160,240,151, 42, 9,105, 60, 90,243, 12, 61, -144,164, 40,177, 14,177,163,158, 43,111,246,188,242, 31,160,235,123, 18,101, 57,143,194,225, 47,180, 47,174,138,142,205,137,201, -112,206, 50,203,217, 97, 24,123, 12, 67, 7,107, 23, 37,173, 88,155,186, 46, 32,229,170,169, 59,196, 68,103, 31,187,165, 4, 0, -171,128,139,229,207, 41, 7, 32,253, 89,168, 8,152,167,121,209, 18, 88,218, 81, 9,206, 81,148,147, 48,148, 72, 38, 15, 73,156, - 35,140,163,177,100,215,247,220,241,209, 40, 82, 98, 49, 83, 76,200,115, 66,232, 44,231,211, 71, 30,229,208,129,108,152,125, 13, - 22, 5,214, 3, 69,173,230,192,243, 69, 78,147, 19,192,119,244,114,202,133, 34, 18, 81,153, 36, 20,174, 18, 9,189, 91, 85,200, - 68, 89,192, 84,220,132,224, 52,178, 19, 44,234,147,201, 72,101, 42, 88,156,247,216,239,247, 68, 17, 75,244, 50, 12,103,223, 68, -204,116,137, 29, 29, 15,184,255,224, 12,247,238, 31,225,159,255, 95,255,152, 68,137, 34, 26,145,232, 66, 46, 88,132,153,208, 56, - 63, 94, 30,106,231,105,114,226, 68, 48,130,130,151, 79,159,162,193,227,252,222, 61, 60,120,235, 62,186,190,211, 2, 76, 52, 22, -150, 11,151, 16, 60, 50,251,129,229,207, 40,200, 80, 25,147,237,247,123,220, 94,223,224,242,242,154, 40,135,161, 67,223,247, 24, - 87, 35, 54, 71, 27,172, 55,107,138, 0, 46,130,128, 4,214,155, 1,102,232,240,249, 23, 47,240,163,159,252, 12, 83, 53,184,251, -230, 29,172,143,214,240,206, 80,209,215, 26, 76,227, 49, 53,219,122, 86, 99,135,177,243, 88,175, 7,156, 28,175,112,255, 98,131, -159,123,239, 77,124,231,189,183,241,203,119,223,194,119, 46,222,194,195,182,198,201, 28,240,246,241, 5, 30, 61,186,143,159,125, -241, 18, 63,121,255, 43, 92,126,122, 5,251,248, 75, 60,253,222, 7,248,111,255,251,223,195,151,207,175,241,170, 24, 84, 75,113, -181,153, 83,180,136,162,152,148, 63, 45, 33, 72, 18, 37,106, 84,111, 82,149,253, 14,254,220,165,187,150,220,121,201,208,206, 41, - 49,112,138,254,253, 60,209,142, 57,177, 30, 39,206, 51,119, 91,153, 47, 69,202, 81, 23, 97, 85,213,108, 0, 66, 42,247,195,160, -160, 37,107, 27,139, 81,161,103, 14,157, 97, 77, 9, 91,181, 20,237,200,165,195,165, 63,175, 97, 49, 91, 86,166, 67,201,153,109, -185,133, 39,107,139, 59, 7, 7,209,149,116, 74,226, 42, 45, 0, 0, 32, 0, 73, 68, 65, 84,160, 18,127, 62, 48, 69,206, 8,238, -152,215, 38,214,145, 85,112,187,221,179,248,118,225, 48,104,162,150,210,201, 14, 73,111, 77,227,175,244,226,145,145, 50, 63,143, -125,223, 99, 28, 7,158,126, 65,115,239, 41,100, 38, 31,132,194,200,250,173, 0, 53,163,235,105,186,212,179,189,212,251, 78,152, -128,124, 25,209, 42,163,230,130,105,154,249, 98,100, 13, 80,161,245,136,239, 6, 12,171, 35,132,126, 77, 78, 21, 23,212,249,228, -120,165, 65,164, 69,234, 78,167,253, 68, 65, 74, 73,114,213,137,148, 41,184, 89,192,242,232,222, 28, 8, 13,237, 65,182, 4, 41, -190, 91, 43,186,170, 44, 60,225, 20,178, 41, 64,231, 64, 74, 51,235,149,178, 22, 80, 46,116, 48, 54,104,144,140, 97,111,183,117, - 94,115,226, 45,163,206,219, 1,108, 75,154, 82,171,128, 62,206,179,224,103, 95, 62,175,122,192,209, 95,198,220,141,197,202, 85, - 83,225,150,176,155,162,255, 31,195,238, 25, 17,166,138,138, 93, 10,178,156,179,106, 77,180, 40,228,203, 95, 65,171,198, 28, 68, -163, 19,133, 79, 38,150,130, 56,167,213, 5, 89, 66,141, 49,240,214, 24,184,224, 56, 23, 61,195, 59,163,204,221, 97, 28,105,135, -155, 50,198,149,197,180,223,107, 5,106,173,227, 17, 48,121,248,122,254, 82, 68,189,222, 56, 85,204, 58,143,121, 63,209, 8, 47, - 21,218,177,113,245, 50,174, 89, 53, 89, 11,124, 8,216,222, 78,100, 17, 99,156, 31,137, 13, 88,200,151,201, 78, 38, 21, 73, 63, -244, 28,169,153,153,226,211, 16,122,199, 83, 2, 14,151,137, 9,195, 16, 20, 39, 72, 42,244,142,237, 47, 78, 87, 14,180, 63,163, - 75,121,158,146,162, 99,107,109,240, 93,143, 56, 71,205,180, 37, 29, 0, 93, 0,187,221,158,119, 88,150,128, 26, 76,134,179,150, -172, 46, 80, 48,193,114, 49,213,214,208, 13, 29,127, 97, 86, 67, 7,172, 49,176,161,131, 49, 22,105,142,154, 69, 61, 79,244, 32, -123,207,159,181, 49,172, 83,104,252,240, 23,125,120,114,206,236, 67,133,166, 58, 9,154, 80,210,221,172, 51, 11,183, 29, 11,162, -183,230,194, 33, 3, 96,133, 55,184, 11, 7, 31,240,132,170,165, 49, 23,253,211, 50,226,177, 53, 42, 10,115,169, 72,243,132, 24, -231,165, 75,171, 21,190, 63,129,237,143,128,219, 9, 93,231,177, 57, 26,241,224,173, 59,120,255, 7, 63,192,205,245, 37,239,243, -101,204,203, 59,249,148,208, 82, 68,215, 15,136, 51, 11, 45, 13, 17,246, 42,195, 25,188, 55,156,146,199, 81,149,166,225,233, 23, -159, 97,119,123,139,187,111, 60,192,157,251,247,113,126,247, 2, 87,175, 94,225,234,213, 53, 7,162, 48, 74, 54,101,126,217,100, -138,195, 66,164, 90, 85, 79, 96,120, 90,145,226, 30,159,125,122, 13,239, 29,134,113,133,163,227, 99, 12, 67,135,174,119, 24,198, - 1,231,173, 97, 98, 28,237,184, 25,112,191, 53,160,189,129,219,203, 61,174,190,216,226,167,127,243, 49,238, 62,186,143,245,186, - 71, 42, 13,101, 63,163,243, 22,142, 5, 54,173, 22,100, 25,229,214,130,150, 35,208, 42,130, 3,186, 85,135,163,245, 8,103, 13, -190,253,173,183, 80, 51, 29,154,174, 85,164,153,144,147,159,125,121,131,199, 95, 94,227,135, 63,252, 16,127,231,239,127, 11,143, -126,254, 17,208, 34,230, 57, 51,131,157, 38, 98,164, 2, 54,188, 23,109,172,197, 96,236,108,107, 74,152, 67, 89, 2, 71, 28,143, -238,101,114, 35,182, 76,209,181, 80,244,171,209,139, 50,120, 82,208, 35, 91,102, 2, 20,157, 49, 8,215,154, 58, 86,135, 52, 87, -102, 27, 36, 42, 56,107, 69,219, 1,206,209,101, 29,167,137, 97, 65, 89,195,105,104, 31, 13,198, 55,103,237,164,136,125,222,150, -103, 41, 12,200,160,213,159,100, 89, 72,183, 95,107,162, 41, 92,165,157,120, 8, 22, 41, 55,189,216,197,137,220,245,129,162, 99, -197,207,222,160,193, 80, 41, 38, 76,211, 68, 5, 60, 23, 29, 60, 35, 96,157, 66,213,235, 84,148,211, 98,169,210,110,144, 89,142, - 50,245,211, 14,158, 59, 71,253, 87, 25,235,243,132,177, 85, 44, 81,157,188,255, 13,221,168,145,169, 4,172,225,224,153,218, 14, - 2,182, 10,169,220, 57, 80,197,218,198, 35,244,202, 49,204, 27, 66,200,118, 61,171,199, 73,112,230, 67, 80,187,150, 53,203,119, -157, 51,165, 28,150,186,104, 2, 96,200,174, 76, 5,162,231,149, 6, 52,151,189, 85, 34,138, 82,254, 6,233,110,196,234, 44,157, -168,134, 64,153,162,211,186, 90, 34,173,106,217, 22,215,216, 99,214,224, 56, 57,178,146,142,137,155, 37, 81,191,147,252,221,113, - 90, 97, 56, 8,243,178, 42,130,147,244, 54, 74,125, 91,152, 29,114,153,194,100, 93,201,180,146, 89,191, 33, 49,192, 80,215, 79, - 67, 85, 70,125,107, 13,166, 57,206,216,240,188,190, 40,154, 52, 39,147,128,156, 51,156, 15,168,185,105, 1, 45,174,137,202,147, - 15, 35, 19,116, 99,201,198,204,116,211, 37,118,220, 0,197,242, 68,171, 17,251, 93,118, 94, 29,139,211,148,167,205,137, 83,227, - 56,176, 53, 45,113,206,177, 36, 19,177, 85,202, 24, 78, 29,179,232, 82,135, 97, 28,149,192,214,106, 67, 55,208,197,232,184,147, - 38, 42, 92,207, 95, 32,133, 16,144,223, 59,176, 48,161, 32,206, 17,125,223,107,101, 85,217, 82,214,208,208,117, 65, 15, 7,235, - 28,243,152, 13,127,185, 13,214, 19,158,177,239, 3, 74,174, 8, 1, 58,118,201,185,170, 82,211, 0, 52, 50,202,133, 30, 52,222, - 77,147,106,214, 32, 32,104,215, 43,170, 83, 26,149, 80, 22, 52, 37,129, 81, 49,144,102,130,230, 52,102, 56, 31,142,187,133,226, - 6, 88,140,171, 21, 29,142, 60,122, 68,107, 92,160, 44, 59,178,148, 18,239, 87, 11,230, 56,211,193,228,173,114,163,157,147,233, - 73, 92,126,142,136,213, 4, 41,235,229, 33,242,104,153,194, 78, 68, 12, 66,154, 8,167,132, 36,235, 72,216, 88, 88,225, 31,188, -103, 46, 61,237,250, 42, 91,222,156,247, 60, 62,165, 34,104, 98,113,164,105, 6,211, 52, 33,199,136,237,237, 13,210, 28, 85,160, -214,106,197,120,246, 54,226, 76, 58,130,245,186,195,197,221, 19,120, 87,240,195,239,254, 5,227,123,105, 34, 36, 19,140,170, 2, -191,130,105,191, 71,215,117,116, 32, 27,171,158,247,202, 33, 16, 66,222,107,188, 99,114,206, 98,123,123,133,233,163, 45,174, 94, -158,225,238,131,251, 56, 58, 61,195,201,217, 41,174, 46,175,137, 6,183,155,153, 34, 69, 47, 97,140, 73,225, 69, 2, 20, 9, 28, - 19, 44,163, 78, 65,146, 78,251, 29,246,187, 45, 90, 51, 56,187,115,142, 97,160,110,174,239, 7,108,142,142,112,126, 81, 48, 79, - 51, 39,248, 5, 92, 62,185,198,179,199, 95, 98,119,187,199, 91,239,189,133, 97,213, 99,246, 30, 31,126,240, 57,108, 41, 56, 63, - 89, 97, 53,120,120,222,179,230,148, 48,239, 38,181, 90,122, 11,100, 46,120,140, 15, 48,104,240,166,161, 76, 59,228, 2,132,213, - 72,254,234,253,132,235, 28,241,235,111,159, 97,154, 18, 46,238,157,161,190,122, 69,160,149,224,217, 74, 99,117,119,188,196, 37, - 83,225,102,141,133,101, 17,101,232,131, 98, 41,107, 94, 52, 40,149,233, 93, 36, 68,148, 48, 23,250,255, 89,217, 91,183, 5,135, -154, 98,212,131, 71, 46,117, 74,132,116, 42, 18, 85,173, 65, 74,232,134,129, 85,224,244,189,199,105,175, 29, 20,169,147, 43, 12, - 10,114,172, 76, 58, 46,234,106, 17,154,164,231,181, 94,201, 51, 92,232,121,125, 64,118, 40, 48, 74,218, 8,248,131, 21,196, 49, - 10,181,140,117, 36,149, 86, 77,130, 5,150,238, 95,224, 90,210,117,215, 82, 53, 96,131,138,243,124,176,143, 21,251,156,229,188, -128,178, 68,177,170, 56,208, 30, 80, 45, 43, 39,243, 5, 70,187, 46, 32, 45,113, 38, 40, 43, 95, 2,125, 32, 33, 84, 29,199, 79, -119,172, 77, 8,100, 9, 78,130,134,182, 40, 57, 34,197, 61, 74,140, 20, 3,203,209,203,181, 21, 56, 22,196,117,195, 26,174, 27, -152,109,110,150, 68, 49,111,224, 44,101, 94, 68,222,225,206,243, 76,161, 60, 62,112,200, 79,227, 21,173, 81,219,156,211,120,224, -166, 43, 77, 99,232,175,201,138, 71, 11, 53,179,196,199, 54, 14, 50,106, 48,156, 93,145, 56,109,212,145,242, 27, 64, 5, 65,211, -228,204,175, 60, 53,180,206,115,215,238,121,164,238,148,149,160, 32, 32,195,232,240, 38,185,134, 12, 59,106,130, 62,247,220,244, -212,197, 58,199,187,242,198,150, 96,152,166, 97, 61,218, 97,139, 29, 78, 86, 0,150,157,100,149,176,187,150, 11,236, 82, 10, 76, - 93, 68,206, 41, 38, 52,188, 54,180,214, 68, 57,153, 70, 21,182, 6, 22,221,185, 55,242,223, 55,106,166, 84,183,210, 26,124,140, -137,237, 36,149,171,240,170,106,242, 82, 40, 52, 1,161, 49,108,162, 28, 36,206,144,184, 14,156, 63, 44,128,251, 24, 19,156,247, -232, 24, 66, 98,140,213, 48,145,121, 79,138,226,190,239, 89,152, 21,208,230,132,152, 40, 1, 45,167,168, 59, 2,231, 60, 82,206, - 48, 49,161,235, 44, 60,227, 28,187, 62,168,245,206,240, 33,111, 88,169, 41,177,177,158,131, 42, 72,245, 76,187,187, 56,211,206, -199, 7,135,148,120,183,116, 80, 17, 27,190, 24,134,177, 67, 76,153, 11, 18,246, 76,242,248, 41,165,162,220, 98,170, 8, 25, 58, - 32,121,195,134,148,167,133,237,101, 50,166, 35, 33,155,103, 50, 22,121, 72,201, 26,216, 72,112,198, 94,201,253,118,143,121,138, -116, 48,181,130, 52, 79, 48, 7,169,121,178,155,163,174, 99, 17,246, 89, 35, 64, 24, 25,149, 51, 63,160, 35,152, 2, 88,133, 79, -202,119,142, 10,108, 32,155,139,248,244,217,255, 47, 54, 14, 83,155,254,127, 58, 23, 16,148,218,103,217, 82, 65,133, 89, 99,196, -103,206, 5,187,237, 45,166,221, 78, 71,230, 57, 87,116,227, 9,194,120,134,253,213, 14, 67,239,113,116,178,194, 27,143, 46,240, - 87,127,242, 71, 58, 17, 64, 99, 69,174, 15, 90, 60,201, 63, 90, 45,152,231,137, 85,180, 6, 37, 4, 56,235, 96, 28, 39,205,249, -160,233,113,212,173,177, 98,213, 86,220, 94, 95, 98,191,221,226,228,252, 12,167,119,232, 98,223, 28, 29,225,250,234, 10, 47,159, -191, 66,227,110, 65, 80,169,181, 90,189,196, 19,179,168, 37, 0, 72,246,250,161, 11, 72,153,192, 35, 87,175, 94,226, 18, 6,195, - 48,226,232,120,163,223,201,230,232, 8,235,205, 17, 0,224,233,227, 27, 60,127,252, 10,229,242, 22, 55,255,242, 35, 60,120,116, - 23,111, 60,186,192,183,127,229, 61,124,254,209, 23,248,232,147, 39,196,165, 7,217, 1, 79, 55, 61, 86,125,128,227,239, 37,115, -242, 94,227,157,116,227,212, 65, 99, 44, 12, 3,146, 58,239,240,229,245, 30,223,249,173,159,195,241,233, 41, 63,219, 1,155,227, - 13, 29, 40,220,189, 90,103,104,157, 83,151,113,112,156, 51,227, 72,173,102,104,215,202, 43, 26, 44,121, 7, 18,206,147, 83, 89, -248,217,192, 98,189, 49, 6,195, 56, 96,123,179, 39,107, 21,143, 81,197, 75, 75,108,139,204,151,118,164,131,211,121,228, 72,202, -229,213,209, 17,199, 19,103, 18, 77, 21,194, 52,215,202, 48,165, 86, 20,104, 35, 90, 29,235, 44, 91,178,232, 16, 36,138, 37,209, -187,208, 42,114,140, 60, 13, 99,114, 91,201, 0, 8,206, 34,145,175, 85, 70,234,134,166, 78,162, 69, 33, 61,143, 81, 70,124,107, -139,109,171,150,162, 62,108, 10,105, 90,166, 0, 58,198,133,100,166,151,215, 58,112, 17,176,106,167,199,217, 18,194,164, 39,113, -177,103,128,146, 57,208,144,152,133, 51,207,192,172,194,105,141,178, 34,164,181, 84,208, 36, 61,145,132,229, 20,129, 74,250,156, -121,154,248,253,151,130, 96,128,247, 1,195,138,246,231,178, 30, 53,206, 1,149,199,245,213,177,181,152, 4,193,243, 68, 43,149, - 6,139,148,139,174, 85, 75,165, 73,143,236,175, 89,247, 74, 83,145,102,212,115, 46, 5,123,112, 52,169, 96,157, 26,253,253,101, -111,221, 26, 95,242,156, 12,119, 0, 40,162,207,137, 52, 50, 50,149,244,161,231,239, 43,112,247, 42, 62,117, 7,227,137, 12, 10, - 99,248, 44,141, 76, 8,229,244, 54,235, 88,160, 6,158,157, 84, 6,214, 24, 6,117,149,133, 74, 41, 54, 57, 69,208, 22,190,131, - 2,101,138, 88, 94, 49,243, 14, 92, 28, 11,165, 2,165, 38, 61,199,170,228,138, 48,245, 78, 46,124,221,175,243, 36,215, 24, 10, - 60, 18, 39,135,177,242, 59, 25,133,111,169, 56, 85,146,227,254,189,127,253, 87,126, 87,186, 63, 25,169,211,225,209,180, 3, 52, -127,235, 97, 92,198, 3, 85, 5, 70,244,224, 67, 69,106,210,121, 75,181,183, 40,247,136,199, 78, 23,189,213,252,233, 90,168,154, -141,115, 84, 50, 90,227,135,156,176,130, 6, 48,158,133,118,158,199,227,162,192,165,203,211, 57,143, 97,236,209,117, 1, 93,231, -209,143, 29,119,178, 70,147,124,164, 99,148,244,181,121,166,176, 10,199,248,200, 82, 26, 86,171, 81, 45, 5,153,247, 79, 50,166, -241,206,115,248,141,140,221,219, 18, 18,193, 4, 33, 65,220, 54, 0,193, 59, 78, 76,178,146, 47, 67,107,128, 46,240,174,199, 81, -103, 92, 42,246,219, 61,251, 83, 13,230,253,142,246, 61,156,150,103,140,140,201, 41, 18,151,118,102,158,199,226,157,250,255, 29, - 95,204, 4,200,129,198,187, 18,244, 65,254, 59, 42,120, 74,202, 44,144,179,140,194, 36,203, 10, 97,169,141,218,237,104,228,117, -168,150, 55,252, 48,146,127, 54,206, 51,230,253, 14,243,180, 37,122, 94,202,170,248, 28,207,222, 67,179, 35,172, 5, 54, 71, 35, -222,124,120,129,206, 37,252,217, 63,253,127,184, 91, 98,178, 95,173,236,229, 60,220, 23,113,246, 76, 91, 14,200, 86, 43, 18, 63, -204, 98,195,163, 21, 71,211,238, 73,146,177, 36,252, 96,191,221,225,230,234,150,236,141, 67,143, 97,181,194,201,217, 49,125,230, -187,137, 3, 56, 26, 11, 3,205,242,243,216, 14, 35, 89,199,150,133,140, 82,157,203,207, 40, 37, 97,123,123,139, 56, 39,101, 51, -120, 79,120,209,219,235, 61, 46, 95, 76,176, 93, 7, 52, 96,119,187,199,180,139,232,214, 35,134,205, 10, 38, 71,204,215, 55,240, - 6,120,241,226, 6, 31,127,250, 12, 31,124,244, 37,174,110, 38,122,182,141, 65, 99,196,109,137,108, 89,146, 17, 55, 12, 92,232, - 97,187, 30,159,125,245, 2,191,244,155,223,192,201,217, 49, 86, 71, 27, 24, 99,112,241,224, 46, 95,104,150, 84,203, 50, 30, 45, -133,198,234, 88,244, 5,137, 47,107,171, 22, 46,114,118, 52, 44, 86,204,229, 93,134,142,235, 51, 11,154, 68,131, 35,145,205,133, -197, 98,120, 77, 24,181, 68,173, 86,182, 10,141,171, 17,227,106,212,181, 85,201, 17,211,110,143, 28, 35,217,210, 12, 40,191,187, - 86, 29, 21,139,232, 44,197, 89,125,192,153,193, 45,194, 87,207, 26,176,226, 56,126,149,247,247, 44,152,171, 12, 16,201, 41,113, - 60,187,213,103,223,121,139,129,117, 19, 36, 2,165,113,112,240, 12,131,202, 5,219,155, 91,204,243,172,236, 8, 42, 80,121, 39, -204,129, 52,154,202,198, 92,123,163, 81,179,149, 69, 84,237, 64, 33, 79,135,127,215,141, 24,199, 21, 66,215, 29,228, 62, 64,145, -171,133, 3,178,136, 88,201,241,195,128,250,255,201,193, 98, 85, 47, 99, 76,227,168,219, 91,196, 56, 75, 53, 7, 99, 42,186, 48, -160, 31,214,232,134, 21,172, 13,108,155, 50, 10,235, 18, 64,116,173,141, 41,153, 5,243,156, 56,196,202, 48, 40, 43,208, 51, 10, -199,247, 6, 91, 93,141, 89,132,101,173,177,119,158, 10,199, 28,105,229, 33,223, 9, 90,195, 60,207,124, 97, 85,166,172,241, 62, -219, 88, 37,172, 21,222,163, 91,223, 45, 83, 80,223,193,119, 3, 96,232,223,135,142,137,159,214, 49,199,132,126, 15,239, 44, 91, -217,202,129, 54,195,112,222, 57, 19,228,114,209,125, 53,173, 98,232,187, 37,254,124,230,149, 98, 36,155, 47,167,241, 73, 1, 68, - 66,222,142,167, 11,149,227,108,177, 48, 10,164, 48, 19,225, 29, 95,196, 57, 39, 14,255, 33,151,133,144,246,100, 79,111,140, 33, -170, 39, 79, 8,170, 68,203,242, 4, 85,196,143, 44,221,160,169,209,239,252,189,239,252,174, 84,116, 98, 77, 18,239,178,136, 27, -164, 50, 23, 92,159,140,129, 37,247,183,241, 95, 55,172,104,165, 0,129,133,149, 91,249, 34,151, 7, 87, 96, 39, 11, 0,131,233, - 74,214,146,120,131,171, 34,137,211, 51,150,168, 78, 52,238,246,232,250, 94, 31,108,169, 98, 59,246,196,246, 60, 14, 13,157,215, -113, 25,101,148, 83,167, 45,194,184,166, 99, 65, 67, 85, 95,160, 80,142,213,122, 80, 17,197,126, 71,185,218,228,197,116, 72,185, - 48,145,173,177,245,175,105, 66, 27, 96,224,185, 59,111,135,187,116, 30,191, 72, 5, 79,135, 62, 61,252,161,239,249, 50,181,124, -233, 68,164,121,194,238,230, 22,222, 45,148, 28,234,168, 34,219,236, 56,189,141,213,234,135, 69,151, 32, 79, 29,103, 33,107, 66, - 21, 11,253, 36,105, 14, 98,203, 10, 52, 98, 44,165,114,176,197,226,169,183, 34,228,145,244, 47,222, 71, 9, 66, 23, 77, 46,244, -136,253,110,194, 60,147,226,157,118,252, 2,168, 89, 97,115,247, 91,200,169, 96, 24, 60, 78,207, 54,120,251,221,251,248,222, 31, -253, 33,158, 62,249,130,255, 30,109,217,161,181, 37, 22, 87, 4, 66,242,176, 58, 31,120, 74,208,224,125,199, 47, 88, 57, 80, 21, - 47,202, 90,233,176,165,240, 76,124,112,223, 92,223,224,230,242, 86,211,239, 86,235, 53,142, 79,143, 80, 10,129,121, 50,171,218, - 15, 28,192, 26,190, 96, 14,196, 65,181,138,158, 33,243,200, 21,186,215,107,220, 33,238,119,100,225, 76, 83,193,237, 85,212,194, -213, 56,139,253,110,194,246,122,135,147,243, 99,108, 78,143, 80,230,136, 23, 63,123,142, 15,191,120,133,175,110,174,145,114,198, -202, 90, 92, 94,238,240,211,207,158,227,179, 39,175,112,115, 59,209, 25, 82, 89,147, 81,155,218,190,174, 47,111, 16, 7,224,222, -195, 83,206, 5,160,103,220,119, 3, 41,149,173,135,239,104, 45,230,216, 27, 46,239,167, 76,228, 26,219, 61,233, 25, 99,164,112, -112,200,145, 68,152, 68,121, 91, 34, 88,155,114,170,101,240,104, 88,148, 70,223, 11,133, 13, 65,247,225, 75,164, 37, 71, 84,194, -226,248,228,132, 97, 82,134, 35, 62,103,236,119, 59,214,237, 84, 69, 33, 19,235,221,106,167, 42, 5,151, 38, 26, 22, 26,169, 74, -246,120, 61, 60,179,216, 94, 71, 71, 35,184,224,163,201,195, 52, 69,104,237, 40,112, 18,198,205, 14,227, 72,107, 68,118,143, 88, -231, 88,151, 0,196, 41, 98,154, 38, 22,201, 22,198,173, 46,227,216, 82, 18,249,189,153,204, 70,147, 19, 6,212,212,124,176,127, -135,186,138, 26,159, 43,227,184,198,122,179, 65, 23,186, 3, 20, 47,148,180,150,242,172,238,150,174, 31,116,148,239, 24, 48, 99, -173, 87,202,153, 36,137,205,211,158, 38,104,109, 9, 25, 9,221,136, 97,181,134, 11,129,187, 75, 40,107, 66, 26, 11,185,152, 40, - 47, 62,145,197,185, 54,180,102,225, 24, 18, 37,194, 92,137,186,133,125,125, 5, 67, 59, 98,171,232, 84,162,103,154,101,151, 47, - 10,126, 97,230,139,248, 81,138, 73,144,123,106, 33,187,117,148,109,223,117,234,193,247,161,135,247,157, 2,138, 52,241,207, 26, -141,193,134, 89, 0, 72,162,164,215,169, 0,255,231,198, 76, 14, 58,171,179,146,245,208,202,193,119,153,244, 18,149,117, 96,229, -145, 68, 83, 1, 94, 83, 82,167, 20, 14,144, 78,250, 32,189,135,116, 73, 4, 93,210, 48, 34, 88, 84, 86,205, 27,137,226,229,113, -123,109,117, 17,116,182,198, 19,144,166, 58, 32,161,213,121, 34,125,121,196, 57, 46,201, 48,172,116, 53,198, 32,248,128,148, 19, -167,177,129, 48,167,134, 14,220,253,110,167, 48,131,140,132, 16, 58,234, 42,217,238, 68, 93,152, 87,133, 33, 89,217,188, 94,216, -100,143,242,232, 74, 69,148,192, 16, 22,142, 73, 69, 13,142, 0, 28, 6,138,234,236,248, 32,178,134, 58,118,121, 0,140, 53,232, -250, 94,109, 23,170, 48,181, 11,190,182, 50, 69,169,176,253,202,200,104,142,225, 59, 62,120,238,202, 26,230,253,172,213,170, 11, -129,246,110,181, 34, 55,122,233,187,158,166, 7, 53,147,224, 36, 59,199,240,141,196, 2,177,134, 97,236, 53, 77, 74, 44, 36,150, -131, 98,250,224,209, 15, 61, 11,130,136,229, 78,241,164, 59,148, 20, 49, 53,234, 42,101, 76, 74, 1, 41, 22,195, 48, 80, 92,173, - 4,187, 20,192,240,248,187, 31,122,148, 92,105, 37,196, 68, 59, 25,143,214, 82,152, 12,151, 85, 29,106,212,147,239, 15,210,178, - 10,144,233,251,149, 81,160, 85, 52,103,160,232,219,156, 81,106,227, 75,156, 14,176, 90, 18,103, 3,243,244,197, 89,108, 46,222, -225,196, 46,160,239, 3,238,191,121,134,155,151, 79,241,201, 7, 63,209, 72, 74,249,236, 11,239,225, 94,183, 21, 10, 58,184,242, - 51,215,193,112, 10,150,156,198,226, 29,150, 96, 26,226, 16, 4,254,158, 59, 61,112,196,114,183,223,237,113,117,249, 10, 71, 39, -167,184,123,255, 2,195,106,192,201,217, 9, 86,235, 21,174,175,174,113,123,125,131,218, 10,166, 45, 1, 56,200,110,216, 84,248, -104, 56,124, 36,167,204,162, 78,234,124, 67,215, 96, 77, 64, 45, 21,169, 69,212,153,128, 38,219,155,136,123,103, 35,166, 84,113, -187, 39,235, 95,105,192,237,245, 30,159,190,255, 51,124,253,231, 31,226,205,247, 30, 34, 77, 17,255,252,195,207,240, 17, 94,226, -172, 89,124,163,110, 16,188,195,233,233, 10,159,188,184,193,112,255, 4,143, 95,109,241,226,167, 95,225,226,244, 24, 15,238,108, -112,113,186,198,177,113,120,126,181,195, 55,127,251, 91,232, 58,161, 62,103, 76,211, 30, 49, 87,220,123,112,161,187, 94, 99, 28, - 3, 97, 58,205,158, 55,166, 50, 63,130,198,229,165, 84,152, 86,120,191,207,187, 66,158,106,137,157,138, 34,131,177,100,162,163, - 33,206,121, 33,166, 21,201, 4, 7,246,115, 6,172,225, 9, 3,189,223,221,176, 98, 1, 26,189,139, 37,205,136, 19,119,246,162, -110, 46, 5, 83, 76,176,142, 38, 70, 57,145,208, 76,237, 87, 92, 96,150, 76,150, 79,231, 45,140,115, 12,144,170, 72,137, 39,103, - 53,194,216, 78,149,241,114,156,210, 14,154,198,208,115, 76,240,129,138,116,103,169, 1, 1,219, 85, 67,231, 85, 12,188,168,150, - 41,146, 52,231,116, 96, 95,227, 78,142,255,115,140,123,110, 0,184,225, 97,204,182,181,139,245, 72,168,142,114,240, 91,182,101, - 73,134, 59,137, 2, 9, 0,229,188, 67,155, 10,175,120, 28,250,126,208, 61, 62,141,221, 59,101,137,103, 70, 76,203,254,118,158, -103,164, 20,117,100, 61,172, 54, 8,161,163,208,149, 12, 84, 43,185,228,204, 36, 55,141, 48,207,198, 32,205,228,246, 73,185, 50, -218,148,190, 5,211, 40,199,219,123,186,204,172, 39, 81,116,229,115,167,168, 24,204,146,127,188, 86,213, 3,213, 90, 97,106,214, -213, 69, 19, 5, 63,255,255,148, 42,122,160, 6,183,134, 10,137,192,197,142,117, 65,167, 20,214, 46,113,181,134,181, 2,200,226, -146,177, 76,245,204,154,186, 9, 43,247, 67, 61, 8,242, 17,183,130, 80,234, 10,255,247,153,215, 36, 73,197,112,180,238, 43,104, - 45,232,101, 46, 69, 39,105, 40, 22,183,137,156,171, 37, 39,182, 6, 47,110, 4,203, 29, 62,135,152,208,200,223, 52, 88, 27,180, -208, 16, 50,160, 17, 81, 50,154,146, 7, 27, 22,125, 88,227, 21,166,177, 6,190,213,198, 10,208,192,196,164,172,169, 68, 2,109, -240,172, 14,174, 21,218,181, 24, 99,128,213, 10,105,142,136, 28, 91,151, 51,145,183, 10, 39, 22,245, 67,207, 12,121,250,131,135, -224,153,201,222, 33,197,130,213,138, 4, 30,162, 72,175, 70,176,134,204,120,247,180, 27, 26,198,142, 50,221, 61, 22, 67, 63, 31, - 64, 50, 25,176, 46,112, 37,231,149,153,188, 4, 34, 52, 29, 77,144,208,170,233,232,177,178,242,190,235,233,231,230, 84,212,118, - 70, 93,137,103, 42, 87,212,157,105, 63,144, 82,183,212,138, 52, 71,197,176, 46, 76,244,160, 42, 80,177, 45,204,251, 61,255,249, - 27,243,166, 23, 11, 97,138, 19,226, 52,193,123, 32,199,120, 32, 32, 41, 26,205,216,245, 29,171, 93, 51,255,236,178, 84,201,153, -214, 32,170,180,101,133,176,248,203, 27, 31,234,105,142,232,134, 65,181, 8,206, 7,125, 16, 8,192, 33,207, 23,217,224,132, 61, - 95, 53,215,153, 32, 23,153,197,124,165, 84,228, 56,171, 55,147, 86, 47,196,157,119,190,199,120,252, 6, 82, 36,230,248,201,233, - 26,103,231, 27,252,254,255,246, 79,148,140,167,213,242,193,238, 80,192,128,196,196,110, 60,130,236,216,191, 95, 88,235, 80, 85, -141,188,144, 57,160,133, 40,141,216, 12,230,121,210, 40, 75,153, 42, 9, 58,244,197,179,175,112,123,115,141,245,230, 8,231, 23, -103, 44,118,235,209,221,237, 16,231,136,155,235, 91,196,152, 20, 83,106,141, 65,105,244,125,211, 40, 52,241,168,206,162,235, 58, -122, 30,157,131, 45, 25, 37, 55, 70, 81,210,239,122,188, 89, 97,200, 13,222, 69, 92,223, 78,164,107,112, 6,113, 63,227,201,167, - 79,241,181,111, 60,192,197,215,222,196,187, 15, 31,226,167,159,191,196,215,176,193,217,134,211,180,208,240, 34,237,241,159,254, -195,159,199,184, 26, 48,111, 35,158,127,117,139,199, 63,253, 10,223,255,248, 57,122,247, 18,103, 15,207,240, 91,247,142,185, 0, - 99,213, 47, 12,134,222, 33, 70, 18,120,205,115, 68,220,205,202,146,144,110,219, 7,199,126,121,143, 90, 19,198,193,171, 90,186, -200,161, 91, 43, 21,131,134, 46,210, 44,220,114,211,216, 53,225,144,145, 22, 2, 90,224,245, 88, 41, 56, 58, 89, 35,231,198,239, - 23,217,192,186,174, 67,205, 9,177, 16,250,120, 42, 25,173,102, 29,207, 19, 36,169,170,208,140,214, 91,153, 58,113, 46,204, 43, -255, 94,104,133, 60,199, 5, 12,142,138, 12, 60,162,139,155,208,155,149,119,146, 5,238, 32,151,192,121,139,188,139,220,217, 21, -114,113,180,197,242, 41, 44, 11,225,230,147,166, 32, 47,177,153, 92, 44, 75,248, 71, 83, 76,108,229, 62,108,153,148,113,192, 27, - 4,151, 3, 99, 96, 57,232,197,200, 4,212, 58,116,221,160,106,123, 58,191,104, 87, 77, 19, 16, 97,226,147,150, 69,220, 51,128, -208,243, 68, 47, 67,147, 18,128,152, 17,113,154, 40,230, 53, 4,140,171, 53, 66,232,185, 67, 44,220, 92,101,216, 38,120,211,172, - 35,122,162, 41, 22, 6,214,112, 35, 96, 0, 7,195, 6, 9,210,176,144, 20,111,121,191,196, 85, 84, 10, 83,210,106, 81,221,133, -128,169, 40,124,165,234, 72, 93, 20,232,106,248, 99, 92, 47,106,165,228, 72,107,185,105, 51,212,153, 43,132,140,115, 63,248, 29, - 5,139,245, 40,178,151,215, 48, 60,170,110, 5,154,213,113,152, 80, 73, 43, 0,186,192,141, 78,149,168, 43, 39,173,205,124,112, - 54, 45, 63, 35,103, 42, 24,229,179, 47,181, 46,182,208,214,212,234, 44,205, 11,145,228,150, 6,131,152, 38,118, 89,151,192,162, -212,164,251,122,185,248,133, 17, 47,211,204,162, 83, 89,168, 0,177, 84,154,126,121,227,224,169,250,118, 48, 40,106, 59,200,156, -147, 94,100,183, 9,122,249,173, 29, 84,197,190,187,221,193, 59, 15,116, 80,149, 94,156,211, 18, 26, 80,201,211, 61,104,183, 73, -157,193, 56,246,152,166,136,110, 32, 97,129,235,101,108,222, 33,206, 13,195,106, 64, 78, 17, 19,219,185,156,119,228, 71,175, 13, - 62,112, 8,131, 68,120, 6,238,250,157,213,220,244,174,239, 17, 60, 61,228, 41,209,133,157, 19,217,242,230, 57, 34,206, 25,199, -167, 27,242,188,119, 1, 48, 9,125, 31,244,195,139, 49, 81,166,186, 53, 24,198,158, 21,207, 17,165,208,152,125, 24, 7, 29,163, -151, 28,169, 51,182, 4,142,105, 13,216, 28,247,106,143,154,167, 72,190,117,176,133, 46,101,196, 84, 73, 28,215,104, 23, 93, 75, -134,105, 13,222, 1,115, 42,228, 41, 47, 36,174,145,120, 76, 82, 18, 47,152, 86, 99, 14,224, 19, 28,237, 74, 89,189,150, 4,135, -173, 32,103,192,176,221, 77, 42, 57, 17, 64, 26, 0,193, 19,125,203,241,254, 76,254,225,124, 64, 63,246, 60,178,178,186, 75,167, -206, 45,243,119, 77,163,178, 28,103,196,121,210, 75, 64,162, 62,131,177, 88,157,189, 67, 99, 58,215,112,124, 50,226,238,131, 83, -188,248,242,115,124,245,179, 79, 57,240,128, 57, 8, 56,200, 62, 86, 1, 74,211,204,111, 17,226, 89,179,140,139,237, 65,198,124, - 46, 11, 83, 92,198, 79,214, 58,141, 75,148,131,164,242, 33, 79,233, 76,164,194,158,246, 59, 34,201,189,122,133,243,139, 59,216, - 28,109,224,189,195,241,233, 49, 86,235, 53,177, 25, 74,198,246,118, 71,248,203,186, 68, 38,202, 14,215, 58, 11,103, 29,239, 94, - 19, 98,205, 8,190,227, 0, 6,102,222,123,139,110, 8,252,191,181,216,238,102,236,247, 51,114,105,184,190,220,226,203,207, 95, - 34,172, 2,190,243,235,223,194,243,231,151,120,119, 36, 84,177,239, 59, 92,237, 19,238,223, 57,199,241,233, 6,161,243, 56,187, -123,138,251,111, 95,224, 87,255,222, 55, 49,109, 19,126,246,217,115,172, 55, 3, 86,235, 21,237, 56, 29,173,157,106, 51,136, 49, -163,180, 45, 78,207, 79, 48,199, 12, 23, 2,233, 7,106, 37,160,148,181,184,189, 73, 4, 21,202, 5,185, 52,244,125,165,132, 54, -182, 5, 81,162, 91, 89, 66, 77, 44,117,115,161,243,200,169, 98, 88,209,138,141,214, 51, 85, 5,117,210, 65,239,183, 91, 56, 95, -152, 24, 72,162,159, 41,147, 71,122,158, 8, 33,220, 5,178, 39,194, 88, 13,125, 66, 51, 40,168,100,245,225,189,121,171, 36, 96, - 77,243,164, 99, 78, 33, 84, 86,186, 65,136, 84,199, 7, 92,100, 36, 44,101, 92,119,250,172, 59,103, 81,138,161,243, 75,216,236, -252, 79, 24, 33, 4,210,154, 49,198,200, 44,131, 5, 20, 51, 79, 51,143, 69,229,103,231,131,140,243,133, 68,215, 26, 93, 72,178, -206, 84,129, 21,175, 12,197,177,162, 57,243, 18,138, 84,155, 42,223, 75,149,105, 20, 77, 63, 66,232,120,138, 70, 1, 81, 41, 21, - 78, 73,244,175,121,157,141, 53,152,246, 51,246,251, 61, 10, 51,215,187,126, 68,215, 13,128, 37,187,175,156, 49, 64, 69, 99,206, - 6,157,155, 89, 45,206, 41, 37,238,200, 3, 53, 67,124,193,122, 7,148,108,212, 22,137,131,221,191,115,116,161,139,206,170, 72, -144,151, 33,205,132,243, 22, 37, 25, 85,216,151,106, 52,208,164, 29, 96, 85, 41,249, 50,240,234, 53, 48,170, 57, 44, 52, 78,118, -140, 80, 44,117, 83,127, 55,167,147,234,234,164,112, 52,170,192,173,218,193,196,128,138,200,164,133, 34,216, 97, 81, 75, 66,107, -137,118,232,198,104, 99,104,140, 91, 10,143,118,216,237, 47,246, 56, 97,187,148,131, 41,114,227,132, 77,253,115, 41,131,195,106, -227, 7, 84,205,187, 47,124,199, 8, 62,150, 16,176,141, 3,179, 2, 26, 68, 43,197, 19, 17, 44,214, 58,223, 24,154, 47, 92,224, - 86, 27,114,205, 74,211, 98,151, 20, 10,163, 83, 67, 71,201, 49,171,205,138,118,218, 0, 6,195, 15, 2,147,206,114, 38, 1, 86, -225, 93, 76, 63,244,220, 93, 2,153, 33, 32,206, 82, 39, 75,222,105,167,151, 78, 2,117,137, 18,119,153, 83, 65, 48,158,199,254, - 6,187,221,132,110,232, 89, 82, 73, 23,175,196,216,117,189,231, 10,220,115,124,104, 96,127,109, 81, 80, 73, 63, 16,144, 97,181, - 25,144, 34, 85, 63,158, 5, 96,251,219, 25,251,221, 12,112,136, 76,215, 17,240, 38,165,204, 59, 72, 2, 98, 84, 30,169, 27,235, - 48,172, 2, 87,139, 69, 81,173,149,217,192,181, 36, 88, 67,251, 72, 18,155, 84,142,104,156, 17,131, 99, 99, 6,141,124,186, 62, -144,240,134,211,170,100,124, 69,147, 14,131,220,170,170,224, 15, 71,156, 52,102,166,131,182,164,132, 61, 31,214, 66,154, 51, 10, -152,161,181,130, 97, 42,151, 60, 48,181, 53, 85,201,122,239,208, 13,129,215, 16,150,193, 46,150, 69,131, 12,190,168,146, 80, 21, -153, 65, 79,194,176, 16, 28, 82, 42,188, 19, 2,198,147, 55, 16,231,130,190,119, 24,199, 30, 71,199, 3,126,255,127,253, 19, 46, - 10,140,170, 78,155,238, 21, 13, 91, 72,172,238, 96,101,146, 32,202, 80, 17, 39,214,214, 16, 83, 84,123,209,225,216,191,177,248, - 72,160, 56, 20, 7, 27,144, 83, 70, 46, 21, 93, 32, 98, 94, 43,139,208, 45,198, 9, 79, 62,255, 12,195,106,141,211,243,115,108, -142,142, 48,142, 61,198,177, 71, 46, 29,214,235, 53,182,219, 45,166,253,132,171,171, 43,134, 61, 52, 74, 6, 3, 80, 27,193, 50, -196,167,236,157, 67, 78, 77,119,244,155, 85, 64,105, 22, 22, 1,166,208,243,220,121, 96,191, 79,136, 49,227,171,207,159,163, 6, -131,227,179, 13,126,243, 55,126, 14,253,203, 23, 24,142, 54, 8, 93,192, 71, 31, 63,195,123,239,222, 87,215, 7, 96,121,122,230, -113,116,214,225,219,119,142,121, 92, 76,221,112, 76,172,242,237, 60, 12, 35,151,135,177,199,229,203, 43,221,167,230,220,128,204, - 76, 6, 11, 76,211,164, 85,255,246, 54,234,225, 40, 64, 26,217, 69, 90,179, 64, 58,100,183,158, 98, 70,198, 18, 92, 33, 46, 4, -242,222, 71,178,160,165, 9, 37,206,216,207, 9, 41,205,244, 57, 29,112, 18,138,237,233,185,170,228,177,110,133,118,152,133,115, -216,169, 88,100, 21,127,206, 58,174, 46,220, 1,101,254,107,149,133,121, 48, 4,167, 18, 33,146,243,134,252,255, 28,167,107,148, -208, 85,153, 41, 17,225, 59,122,126,134,161,215,194, 55,206, 51, 74, 41, 24, 87, 43, 37,210,149,156, 89, 91, 81,249, 32, 93,104, -113,210,157,233,174,220, 28, 90, 7,249,103,131,254,250, 50,104, 90,252,208,222,119,232,250, 14,195, 56,240,138, 9,220,229, 50, - 3, 60,206, 58, 57, 20,189,136,236,152, 43,175, 67,100,194, 82,107,198,180,219,233,216,125,181, 62, 98,133,187,211,206, 88,126, - 87,131, 5, 21,157, 18,117,212,211, 52, 35,166,124,144,255,190,100,214, 55, 78,181, 36,192,139, 81,251, 42,125, 6, 21, 45, 91, -142,182,109, 48,108,197,106,181,162,114,115,151, 82, 82,129,115, 41,245,181,116, 58, 73, 42,115,222, 48,222,217,176,181,153,132, -220, 10, 69, 99,126, 59, 97,195,249,115,109,224, 11,154,188,241,165,144,160,173,182,165,171, 21, 93, 67,173, 52,157, 33, 91, 96, -211, 85, 47, 90, 65, 46,145,168,123, 45,235, 56,157, 0, 87,140,119,174,162, 54, 23, 32,204, 18,162, 35,160, 46,153,170, 80,191, -123, 96,231,145,221, 58,135,181,228,146, 89, 24,206,133,177,236,247,213,209, 99, 22,225,175,177,104, 16, 71,133,167,112, 27,235, -233, 12,183, 30, 96,104,151,151, 12,227,156,146,230,132, 75, 5, 66, 95, 80, 67,232,130,114,120, 69, 37, 15, 24,184,218, 48, 12, - 84,237,245, 67,143,105,154, 69,174,204,187,205,131, 10, 85,105,104, 69, 69, 34, 82,117, 81,210,147, 71,201,212, 61,207, 19,229, - 32,239,110, 19,123,199,151,184, 61,199,214, 27,107,161,214, 41,192,240,161, 71, 15,143,216,112,230, 57, 97, 92,217, 37,134, 84, -198,185,206,177,216, 46,163,235,185,227,205, 36,188, 51,173, 18,105,140,121,236,187, 29, 1, 38,154,166, 34,209, 3,213,117, 65, -173, 53,173,150, 3,204, 35,237, 88,231, 24,209,245, 30,113,154,209, 0,220, 92,239, 40, 4,193,130,171, 75,218,145,116, 67, 64, - 73, 21,183,215,123,108,111,182,204, 3, 96,203, 73,173,168,150, 10,169, 90,133,116, 69, 68, 46, 26, 95, 47,137, 66, 70,220, 10, - 33,200,146,104, 33, 65,121,167,224, 16, 17,123, 89,231,152,119, 79,145,174,206,123,140,171, 1,150, 99,114,199,177,199, 60,179, -165,133, 93, 0, 37, 37,222, 39,207,152,118, 91, 93, 55, 8,152,193, 58,226, 35, 31,157, 60, 68,107, 30,222, 23,172, 86, 61,238, -191,121,142, 47, 62,254, 16, 47,158, 63, 85,133,125, 41,204,197,103, 7,132,192, 45,212,101, 33,137, 73, 62,104,208,144, 40, 63, -209, 10,107, 60,232,165, 58,220, 45, 30,138, 61, 11, 91,152,196, 10,130,102, 16, 83, 84, 13,129,140,230,193,118,204,156, 34, 94, - 62,123,134,171,203, 43, 28,159, 28,227,248,228,152,129, 59,132,138, 29,198, 1,195,216,227,229,243,151,184,189,189, 85, 60,178, -101,154, 94, 49, 84, 61,207,211, 4, 31,122, 88, 75, 23,127, 8,148, 1,238,157,129, 67,143, 91,103,225,124, 70,231, 44,182, 59, -131, 23, 47,111,240,215,127,253, 24,255,224,223,254, 53,188,247,115, 15, 97,118,247,112,251,242, 26,190,101,204, 49,225,235,223, -122,132,113,189, 86, 60,229,162,123,177,186,167, 35, 91, 78, 83,183,135, 76, 64, 66,176,216,109,103,205, 52, 72,145,166, 95, 52, - 38,231,157, 94, 51,106, 63, 77, 57,241, 33, 3, 88,215, 48, 79, 84,172, 80,122, 27, 37, 12,130, 89,216, 98,131,115,206, 18, 45, - 47, 39, 37, 82,166, 24, 17,167, 25, 37, 71,236,111,175,177,223,222,178,203,128,154, 58,129,175,192, 52,228,152,209,117, 61,199, - 39, 47, 65, 72,180,183, 4,106, 53, 42,222,146,206,170,112,241, 74, 99, 93, 90, 13,202,179, 43, 41, 95,234,235,206,145,221, 32, -158,185,226, 76,211, 43, 92, 8,177, 94, 66, 46, 11,153,178,136, 32,201,168,152,173,169, 64,147,196,104, 89,133,106,114, 57,182, -195,247,129, 71,234, 42, 58, 46,133, 17,165,130, 31,231,194,150,236, 38,220,113,203,116,137, 59, 58, 99,145, 27,157,131, 11,207, -130,172,180,127,107,251,164,145,211,198, 16, 12,137, 86,169, 29,250, 97,133,110, 24, 17, 66, 98,208,139,186, 0, 0, 32, 0, 73, - 68, 65, 84, 71,248, 86,222,143, 27, 80,232,147,243, 66,166, 36,205,200, 60, 77,136,137,214, 17,198,122,242,132, 91,167,221,160, - 20,227, 48,162,143, 55, 7,205,133,227, 11, 19,250, 59,138,224,203, 52,114, 29,148, 34,141, 14, 3,121, 14, 11,124, 71,241,208, -142,129, 82, 93,215,233, 4, 74, 66, 83, 12, 91,183, 66, 23, 84,105,174,187,121,254,124,114, 74, 74,219,164,160, 54, 17, 83,114, -119, 93,203, 1,188,168,234,133, 78, 23,253, 2, 26,147,223,191, 45,189, 58,175, 86, 57, 9,131, 9,164, 70, 10,154, 3,198,125, -213,152,107,163, 83, 37,117,210, 72,240,140,177,186,102, 38,221, 19, 33,196,233,146,239, 8, 78,195, 56, 93,210,128,121, 56, 71, - 69,156, 21,126, 11, 23,200,162, 43,240, 56, 80, 27, 10,238,114,217,111, 26,246,120, 71,202, 17,231,253,180,115,244,176,133, 16, - 16,231, 9,181,145,117, 75,200, 65,230, 32, 58,144, 16,138, 22,182,167, 11,222, 51,209,172,201, 14,194, 18,119, 60, 39, 34, 63, -237,110, 8,198,146,230,153,132, 95,181,113,168, 7,141,247,123,235, 15,144,139,226, 81,244,154,139, 59,174, 7, 85,112, 90, 75, -233, 80, 50,106, 25,198, 94,127, 71,241,227,203, 30,132,146,214, 18,156,165, 29,126,138, 5,211,180, 96,252, 28,171, 95, 69,184, - 35,149,123,102,239,118, 41,149, 89,202,149, 31, 56,194,115, 78, 83,194,126, 59, 41, 99, 60, 39, 26,247,199,121,134,119,134,168, - 96,153, 18,174,210, 28, 53,102, 80,186,101,240,165,231, 44,165,226,201, 24,178,164, 68,214, 65,138,237,209, 34, 67,106, 11,103, -249,129, 70, 83, 27, 71,170,196, 67,111, 76,100,163,189, 89, 65,232,123,244, 67,135, 6,139,214,232,176,166,174,187,234,158, 80, -153,214,204,161, 55, 92,208,104,120,134, 28, 43,198, 99, 60,125,139,132,123,157,195,217,157, 13, 86,107,143, 63,251,254,191,128, -115, 65, 97, 19, 20, 93,104,151,195,212,242,190,219, 7,245,219, 23,126,200, 13,231, 13,163, 45,214,142, 82,234, 50, 78,231,221, -149, 30,182, 60,186, 82,177, 9, 11,232,100,135,159,213,206, 66, 34, 59,195,138, 93,233,250,115,154,241,226,217, 51,196,105,198, -230,248, 24,235,205, 74,173,148,227,106,196,233,217, 25,142, 78,142,145, 83,194,237,205,237, 1,234, 17, 26, 53, 26, 99, 68,223, - 19, 52,199,123,246,237, 50,230,113,227,248,251,247, 22, 22, 13, 47, 95, 84,252,228,229,103,248,229,167,239,225,237, 71,247, 48, -220,177,200, 51,117, 28,183,219, 9,103,247, 78, 49,172, 70,252,233, 63,249, 23, 48, 63,123,138,119,190,126, 15, 71,111,222,197, -120,247, 20,126, 51, 0, 33, 80,138, 32,139, 48,173,115,228,185, 14, 36, 82,157,247, 19,198,177,199,246,118, 15,120,199,136,212, -202,191,103,134, 99,171,167, 76,129,114, 46,232, 6,143,221,237,130, 38,110,181,146,237,136,139, 74,235, 0,239, 60,117,194, 60, - 25,234,123, 71,187,110,249,249, 14,136, 51, 17,201, 66, 8,164,136,231,201, 14, 44,144, 11, 37,247,148, 68,121,222,171,245,138, -124,234,170, 34, 94, 64, 46,206, 59,148, 20, 25, 44, 5, 30, 61, 38, 62, 28,249, 66, 41,158,138, 30, 35,133,206,146,174, 70,162, - 87,198,150, 56,154, 90,201, 52,202, 40,251,219,107,134,186,176,224, 9,229,188,184, 13, 8, 65, 75, 83,191,172,150,165,165, 67, -167,180,182,178,164,178, 29,220,186,238,240, 57, 99,241, 87, 99, 30,193, 48,140,140,220,118,138,133,165,255,109,211, 34, 52, 69, -217, 29, 91, 29, 87, 59, 62,119,157, 35,140,107, 44,153, 4,183, 51,209,215,134,113,141,113,181,194,176, 26,120, 10,118,192,231, -224,203, 19, 7,153,224,251,237,142, 92, 62,112, 8,125, 79, 36, 54, 21, 80,179,163,128,173,105,198, 58, 56, 35,170,113,190, 60, -217,170, 37,150, 65, 42,106,150,105, 47,185,165,100,170,193, 22, 53, 39, 1, 61, 94, 47, 54, 73,129,148,117, 67, 43,153, 11, 62, -175, 86, 63,195,192, 36,113,190,136,141, 88,178, 13, 12, 42,129,135, 88, 3, 65,228,186,133,181,178, 64, 50, 50, 26, 50, 12, 95, -236,149,139,205, 70, 65,109, 26,134,180, 56, 4,202, 18, 5, 92, 69,187,145,121, 74, 41,164, 69,191,228,125,212,194,231,144,123, - 77,123,165,201,141,218,157,147,187,197,113, 60, 45, 36,248, 72,154, 25, 13, 26, 90,224, 69,181, 37,214,183, 72, 97, 95,224,101, - 39, 44, 57,183, 6, 36, 8,146, 49, 71,142,153,147,102, 22,177,145, 0, 78,156,183,104,173,215, 23, 43,116,244, 35, 19,143,187, -201, 91,108,225, 44,239,218,152,217, 76,149, 71,129,109, 88, 24,241,173,161,166,134,213,102,196,246,182, 96, 92,175, 56,145, 43, -107, 55, 6, 35,252,227, 66, 62, 71, 22, 84,128, 21,239,210,181,144, 88, 76,108, 45, 85, 47, 88,234,248,104,100,100,249,239,215, -210, 18, 95, 40,234,200, 82,232, 16, 33,203, 74,197,176, 26,232,207, 90, 42, 13, 96, 88, 1, 63,101,138,167,156,118, 19,192,100, - 50, 81,110,199,153,246,237,183, 55,123, 90, 55,152,197,251, 89, 56, 99,189, 11, 22,105, 38, 43,208, 60, 77,186, 58,176,156,150, - 69, 48,152,140, 86, 50, 98, 93,114,211,157, 51, 60,134,131, 6, 17,128, 41, 76,224,239,110,218,239, 9, 74, 19, 60, 43, 47, 29, - 17,152, 64,105, 81,210,189,134,142, 70,126,150,157, 9, 34, 32, 4, 91, 63, 50, 79, 48, 26,135,125,148, 28,213,167,175, 44,246, -131,110,101, 60,190,143,218, 2, 12, 10,198, 85,143,139,123,167,248,217, 71,239, 99,123,115,163,201, 67,150, 71,115,130,199,116, -222,195,155, 37, 33,206,123,170,192, 67,224,234,221, 26,120,222,147,203,238, 93,248,211,203,104,211, 45, 74, 86, 44,246, 54,233, -198, 29,143, 29,193,132, 40,195,130, 23,210,147, 44,162, 20,185, 68,188,119,152,227,140,114,121,137,105, 63,161,235, 3,214, 71, -107,210,148,132,128,222, 15, 40, 57, 99,189,217, 32,167,132,221,118, 71,180, 69,126,135, 52,192,161, 86, 14, 5,241,152,166, 8, - 99, 51,106, 75,112,166,163,136,207,163, 53, 74,254, 18, 91,204,248,252,211,175,240, 15,254,209,175,162,243, 1,253,106, 64,203, - 5,115, 42,232,122,135, 63,253,189, 31,224,127,255, 63,254, 8,111,218, 30,127,242,253,199, 8,206, 97,240, 30,111,223, 59,194, -253,135,231,248,198,111,124, 19,221,209, 26,231,111,158, 99,191,155, 16,198,158,121,253, 30, 41, 77, 88,221, 57,193,213,171,235, - 37, 34, 82, 80,159,115, 70,228,105,147, 10,195,114,197,180, 37,164,176, 50,218,115,102, 65, 17,123,247,155,225, 44,233,134,102, - 42, 90, 49, 72,145,113,198,243, 12,231, 12, 82,161, 68,186, 92, 61,172,235, 48,142, 9,187,219, 43, 42,128, 44, 21,175, 52, 92, -172,240,118, 68,138,179,242, 43, 40, 49,174, 49,221,143,223,231, 16, 88,132,229, 81, 76, 86, 65,169, 0, 94,106,171,176,144,206, -152,213,197,220,217,165, 24,153,155,225, 20, 18,227,188,131,243, 1, 93,223,243,153, 66,157,190,144,241, 90,147, 70,128,227,150, - 69,225,175,214, 92, 18, 25, 31,218,193,156, 88,148,170,104, 95,172, 94,238,106,167,107,102,233, 26, 5,199,204, 60, 8,117,118, -112,186,164, 49,116, 54, 83, 56,146,101, 49,239, 50, 17,209,247, 21,148,246, 87, 57, 14, 54,116, 20,123,221, 15, 35,134,213,112, - 0, 23, 98,165, 54,175, 11,149, 78,214, 42,230, 24,169, 67,103,174, 70,109,150, 11, 15,163,107, 49, 58, 71, 44,224, 15, 0, 58, -173,176, 72,205,145, 42, 94,227,166,221,146, 97, 46,152,108,102, 3, 24,136, 7,221,243, 37, 70,205,155, 15, 29,163,183, 89, 55, -128,134, 28, 39,110,170,122, 77, 87,132, 88,202, 56,147,221, 88,182,204,113,224, 80,171,153,193, 48,212,144,160,113,103,126,144, -105, 78,236,131,130, 6, 38, 14, 34, 43,159, 69, 83,250,200, 98,195, 5,187, 83, 34,160, 78, 87,172, 65,213, 5, 38,251, 35,121, -165,106,216, 23, 47,171, 79,152,170,103, 83,171, 50,237, 1, 63,147,180, 15, 7,251,212, 1, 3,203, 5, 66, 43,149, 39,103,225, -181, 38,147,160, 97, 5,125,223,209, 89, 37,212, 71,122,128, 43,103, 21, 59,148, 42,145,114,188, 47,228, 67,187,106,186, 80, 91, -104, 82,220, 33, 78,181,193,115, 40, 72,138, 9,158, 95, 12, 17, 54, 85,246, 58,122, 99, 48, 12, 29, 99, 98, 61,106,129,130, 43, -100, 95,108,140,199,106,189,194,174, 85,244, 35,101, 86,199, 57, 34, 37,234, 36, 2, 3,109,148, 61, 45,233,105,153, 46,101,202, -248,181, 76,100,106, 60, 82,178,232,122,186,240, 99,204, 8, 93,207, 15, 52, 80,139,197,180,159,121,244,199, 40,193, 84,144,102, - 18,116, 12,227,138, 70, 31, 0, 92, 16,187, 7,217,211,124,240,152,247, 51, 92,112,136,172, 65,200,153,200, 87, 57, 87,236,119, - 51,249, 64,209,244,192,175, 37,241,248,216,161, 36, 71,153,238, 7,149,181, 86,228,104,168, 37,242,136,122, 65,162,138,240,205, - 90,207,201, 74, 5, 40, 13,134,125,241, 21,192,180, 79,116, 16, 86,242, 76,135,174,227,221, 53,184,155,183,170,146, 30, 86, 3, - 77, 84,120,207,104,217, 90, 71,123,159, 37,109, 40,231, 72,204,104,246, 0,103,158,234, 72, 72, 65,163, 91, 17,195,209, 91,168, -141,132,129, 39,167,107,120, 95,241,255,125,255, 47,137, 50, 40, 94,116, 20,182,232, 45, 17,135,130, 20,110, 92,185, 54, 52,160, -178,162,185, 84,152, 66, 10,127, 1,121,148,156, 97,189,231, 32,160,101,252, 14, 86,104, 87,214, 25, 80, 83,104, 52, 10,178,177, -127,183, 52, 40, 56,201, 57,191, 88,103,236, 34,254, 49,134, 62,211,253,126,143, 57,206,184,188,188, 66, 8, 30,125,223, 51,176, -200,163, 99,239,242,230,232,136,137,102, 17, 41, 70, 76,251, 61,166,253, 76, 8,228, 74, 36,183,126,232, 80, 42, 16, 92, 70,174, - 13,190,101,160, 38,220,220,236,224, 65,135,210,217,201, 6, 46,120,172,143, 70,188,124,242, 12,187, 52,227, 79,127,255, 7,120, -245,215,239,227, 63,251,198, 27, 56, 94, 15,136,197,226,102,151,241, 98,159,177,223,205,120,252,201, 83,252,248,243, 43, 92, 94, -239,208,245, 30,103,235, 30,119,239,110,240,224,141, 51,188,241,238, 27, 56,126,112, 7, 39, 39, 27, 78, 19, 52,186, 78, 73,145, - 21,219,124,129, 89,222, 75,211,187,208, 80, 38, 16, 31,220,112, 14,122, 35, 42,153,247, 6, 69,173, 68,102, 1, 35,149,202,218, - 15,154,144, 25,182,136, 85,134, 3, 81, 26,158, 71, 73,123, 13,150,129,201,168, 5,200,206,193, 22,143,156,136, 33,208,228, 2, -169,196,116,144,238, 86, 4,183, 18,231, 41, 44,123,101,112,163,194, 48,217, 76,162, 55,179,114,215,205, 65,182,185,165,174,136, - 47,139,218, 34,156, 11, 28,223, 90, 37,239,138, 4,195,188, 74,148, 60,117, 24,198,246,178, 7,154, 46,122,222,151,114,129, 97, - 96, 84, 64, 74,159,173, 93,194, 91, 44, 96,141,103,219,147,161,132, 76, 22,129,117,221,194,108, 87,103,143,149,162,115, 73,209, -172,173,194, 91, 33,192, 73,150, 65,213,245,146,115,196, 97,160, 41,145,227,142, 49, 47,152, 90,158,182, 22,246, 89,167,148, 40, -178,216, 8,205,206,113,212, 41,189, 11,173, 80,158,187,151, 11,175,113,164,115,161,253,117, 51, 11, 55, 95,248, 24, 20,170, 35, - 94,245,202, 96,177,162, 98, 50,195,231, 52,217,101,185,184,247,142,253,229,212,192,129, 85,227,161, 31,121,237,203,221,109,171, -176, 77,152,255, 84,116,150, 82, 80, 82,228, 51, 32,171, 37,205,170, 69, 80, 82,254, 72,125, 79, 79, 49, 61,215,214,100,237,166, - 15,195,118, 68,117,224, 37, 88, 5,109,233,170,205, 18,242, 98,248, 66, 23, 10, 99,213,188,116, 0,112, 48,246,245, 64, 24,109, - 58,184,147, 23,152, 78, 45, 77,195,167,234,193,250,103,113, 43, 56,117,113,145,238,165, 59,136, 59,110,204,138,233,130,138, 49, - 14,149,135,242, 27,121,238,218,104, 39,235, 20,120, 34,226, 54,107,128,213,122,228,189,138,193,236,102, 37,227,180, 70, 23,136, - 96, 59, 91,173,116,169,134,192, 66, 38,161, 62,209,216,210,245,129,199,229,164,118,164,241, 54, 85,231,193,152,215, 32, 22,212, -169, 46,217,216,186,135,182, 52,218,107,169,192,122, 26,199, 81,194, 82, 83,114,148, 49,175,143,230, 4,150, 67,182,188, 2, 99, -129,113, 61,144,202,181, 53,132,206, 41,200, 33,140,129, 59,225,153, 5,134, 21,145,199,244,180, 87,161, 60,140,121,206, 52, 54, - 67,195,188,219, 19,115,152, 57,213,214, 52,250,162,141,193,126, 63,163,164,196,251, 55,234,218,115,206, 90, 29, 82, 88,137,196, - 30,210, 62,153,210,150,168, 48,244,204,235,174,149,198, 48,206, 56,250,107, 69,114,145,137,238,215,245, 61,143,236, 12,154,161, -196,177, 48,244, 74,187,115, 7,233, 89,206,187,229, 37,225,234, 55,206, 51,143,103, 73, 23,145,152,189, 79,241,128, 52, 94,234, -143,238,192,117, 35,218,156,176, 90, 15,184,184,127,130,143,127,252, 67,164, 24, 89, 4,211, 20,226, 99, 61, 85,252,198, 46, 94, - 81,203, 40, 86, 47,160, 27,177,253, 85,201, 31, 22,210, 92,227,188,249, 3,117,169,142, 66, 25,240, 97,205,235, 73, 86,178,253, - 51, 75,184, 68,101,145,168, 83,222,124, 59,216,131, 58, 86, 73, 83,183,148,226,140, 24, 35,110,174, 34,199, 98,174, 48,174, 86, - 56, 62,222,192,121, 79,154,144, 82, 49,140, 3,188,163,148, 64, 52,224,249,231,215,132, 65, 30,137,157,111,205, 76, 89, 0,219, - 27,248,235,151,200,187, 9,215, 79,159,193,195, 98, 61,116, 88,141, 1,206, 26,244,101,194,116,121,137,109,189, 65,253,232, 51, -252,155,223,190, 7,164,130,218, 44,186,206,225, 4, 6, 71,235, 30,253,216,225,238,183, 30, 0, 71, 71, 84,132,111,111,113,245, -242, 10,207, 31, 63,195,143,254,240, 99,252,193, 63,158,208, 13, 3,126,231, 63,255,143,240,253, 63,253, 1,198,163, 17,119,206, - 86, 56, 61, 93,209,244,107, 28, 88,108, 4, 52,107,224,123, 18,222,208, 58,169, 96,189,233,145, 82, 68, 41, 36,122,116,182, 98, -222, 39, 56,103, 16,186,158, 53, 36,149,247,145,148, 87, 95, 12,185,105, 10,219,176, 80, 43,121,210,179, 69,215,143,136,141,148, -197,173, 70, 77,228, 43,217, 34,115,215, 38,221,172, 53, 80,193, 35,137,194, 28, 39,178, 81,250, 86, 65, 62, 8, 18,225,131, 22, - 70,159,167,146, 11,235, 88, 44, 83,208, 50,208, 14,162,138,205, 18, 86, 84, 24, 48, 35,250, 14,192, 34,116, 28,201,220, 56, 39, -130,215, 22, 96, 91,173, 42,239, 43,141,210, 77, 99,240, 82, 17, 70, 43, 53, 28,138,109,199,178,111,111, 7,123,248, 16,122, 30, - 53,251, 69,245,222,170, 78, 44, 32,221, 35,133,250, 81,209, 41,180,180,214,144,203, 82, 60,132,208,193,187,128, 97, 53,178, 37, -213,235,115, 44, 68, 76,178, 15, 6, 78,127, 44,152,166,137,156, 56,205,162,227, 48, 23,233,226, 1,238,240,173, 67,207,147, 12, - 41, 52,104,242,102, 25,175, 76, 29,101,102,177,162, 82, 3,185,160,170, 2, 13,170, 50,117, 21, 26,158,209,243,219, 28, 80, 33, -101,205,235,217,155, 46,211, 3,137,207, 22,123,173,166,111, 50,223,159, 4,148, 60, 9,104, 85,215, 33, 36,206, 44,186,190,164, - 66,180,192, 32,243, 56,221,170,207, 93, 46, 71, 57, 15, 32,177,201,198,192, 66,244, 18,208, 21, 2, 12,255,222, 52,118,209, 73, -142,226, 94, 15,114,228,141, 56,101,242,130,195,150,123,181, 48, 73, 85, 68,221,134,155, 26,104,172,106,125, 45, 75, 93, 82, 37, - 91,109, 44, 42,174,156, 13, 33, 81,117, 86,188,232, 36, 60,145,236,234,204,158, 81, 99, 44,230, 73,130, 48, 22,139, 84,109, 64, -224,174, 89, 58,190, 14, 64,140, 81,247, 79,180,195,170,186,207,241, 33, 48,161,138, 20,211, 49,102,172, 55,180,252, 87,111,187, -163, 7,136,130, 95,232,195,219,239, 19, 54, 71,158, 71,110,128,243, 84,173,251,209,235,101,100,141,133,119, 22,177, 85, 98,106, - 51, 15,222,121,171,227,226,126,236,245, 18, 72,169,106, 21,220, 98,211, 23,139, 46, 32,160,168, 56,176,113,117, 13,182, 51, 65, -131, 32,172, 53,244,251,194,160,236,103,250,157,120,242, 48,239,118,140,127, 12,132, 26,172, 65, 47, 17, 1,218, 84, 78, 93,170, -149,180, 8,158, 63,123, 99,172, 62,136,206,129,187,124, 46,188,184,155,202,205,168,103,155,124,180,203, 14,210,121, 18,121,133, - 16,144, 75, 37,132, 98, 63,114, 53, 23, 84,176, 38, 23,183,236, 98,105,116,196, 15,174,105,216,239,118, 92,113, 39,221, 3, 74, - 23, 44, 7,183,177, 14,171,211, 71, 72,115,198, 48, 4,156, 95, 28,195,180,136, 15,126,244, 55,250,146, 84, 14,110,232,254,127, -170,222,236,215,182,244,186,238, 27, 95,183,214,218,251,116,247,214,189,117,171, 35, 89, 36,139,173, 68,145,161, 8, 65,162, 77, - 88,138, 19, 3, 70, 2,219, 65,222,242,144, 39,191,230, 15,202, 91, 16,228,193, 48, 2, 4,137, 19, 36,113, 12,199,129,109, 82, -164, 40, 82,148, 68, 81,165,106,216, 85,145,172, 42,214,109,207, 57,123,175,181,190, 46, 15,115,204,185,246, 37, 4,148, 88,188, -205, 57,251,172,245,125,179, 25,227, 55,134,225, 36, 91, 32,145, 51, 16, 78,108, 34,206,128, 51,237,228, 5, 83,166,182,228,110, -111, 59,169,156,139,133, 45,216,115, 73, 92,108, 37,126,216,112,159, 28,117,234,203,100,214, 18,142,170,229,165, 75,246,125,233, -222,189,181,130,227,225,200, 29,121,194,179,167, 79,112, 60,220, 98, 62, 28,112,117,231, 18,206, 7,140,227,128,148, 18,246,231, -137,122,142, 21,251,115,217, 43,230,181, 97,154, 34,246, 83, 68,184,126,132,240,236, 35, 20,231,145,107,199,135, 79,111,112,134, - 9, 95,248,220, 43,184, 28, 58, 14,143,175, 17,158, 62,193, 3, 20,252,243,255,228,203,120, 97, 2, 18, 26,234, 42, 25,213, 46, - 4,248, 36,251,222,118,117,142,178, 59,195, 68, 94,248,112,247, 10,211,157, 43,220, 45, 43, 94,191, 72,168, 93, 46,200, 79,156, - 71,220,121, 48,224,241,111, 31,226,248,236, 17,214,245, 37, 60,185,158,241,240,233, 1,183,115,193,179,195,130, 37, 55,124,235, - 31,127, 5,247, 94,186,162, 88,172, 97, 62, 10, 45, 45,175,114, 80,122, 22,103, 10, 82,146,110, 86,242,208,203,186,162,100,160, -228,133,221, 17,187,120, 47,233,102,243,220,208, 91, 68,136, 35, 90,157, 81,248,185, 58, 4,148, 60,195,187, 32, 29,187, 3, 66, - 26, 76, 15, 1,120,194, 55, 4, 73,171,185,217,112,129, 7,185,236, 64, 53,143, 29,102, 61,234,166, 8,246, 74,244, 51,245, 52, - 3, 98,104,199, 27,152,165,158,168, 67,152,231,138, 52,130,225, 71,163,156,103,107,222,112,196, 69,114, 49,100, 37,185,121,151, -213,153,233,221,134, 4, 53,108, 52,247,224,186,218,210,169,155, 66, 97,198,105, 34,219,160,219, 37, 47,227,100,125,190, 29,221, - 32, 50, 29,136, 20,225,229, 82,237, 29, 75,113, 32, 98, 54,218,138, 78,215,116,240,114, 37,117,159,144, 25, 98,116,156,103,220, - 92, 95, 11, 6,119,220,163,148, 46,202,115,120,187,128, 84, 95, 37,255,155,138,222,200,224,144, 17,221, 22,163,205, 9,138, 88, - 82,201, 60, 47,133, 68,182, 78,196, 43,211, 52,169,240,215,253,190,140,237, 69, 15,148,134,209, 38, 21,165,138,104, 83, 34,167, -157,164,187,145, 36,216, 72,116, 68,111,210,165, 67,224, 73,218,173,251,176,173,104,132,117, 80, 24, 12,212,108, 76,174, 46, 33, -237,202,213, 97, 35,103, 67, 39,107,110,203,104, 7, 39, 19,142, 77, 85, 33, 81, 78, 73,171,202, 96,151, 12,130,141, 19,111, 14, - 9, 77, 45,212,136,159,222, 4,208,227, 28,130,231, 61,210,100, 53, 45,137,120, 91, 67,173,233,163,186, 62,150,130, 86, 44,191, -154,135, 18, 3,247,208,141, 42, 72,223,165,106, 90,230,213, 0,247,178, 71,151, 31,158,118, 46,138, 47, 84,251,148, 74,252,163, - 38,179, 13, 3,128,204,203, 59,158,116, 66,222, 84,160, 82,149,110,234,234,105, 26, 49, 47,153,157, 79,130,191, 56, 67, 45, 18, - 56,115,115,125,139,148,228,162,222,157,193, 46,189, 52, 4,203, 43, 78,220, 45,109, 35,106, 29,227, 52,219, 59, 13,100,112,203, -191,215, 15, 76,132, 97,146,204, 36,221,226, 74,209, 90,136,204, 22, 55,102,122,227,136, 94, 58, 87, 21, 65, 29, 15, 43, 74,109, -146, 83,204, 17,113,171, 5,105, 24,248,123, 58,234, 10, 75, 13, 66,127, 62,121, 78, 65, 10,133, 15,149,140,241, 58,177, 14,253, -196, 3, 92, 44, 23, 88,109, 45,122,128,218, 75, 18,156,253,220, 92,237,200, 14,162, 58,143,194, 30, 72,156,178,232,101,238, 52, - 80,226, 36,144, 66, 29, 7,243,241, 40, 94,123,194,136, 42, 95, 62,245,245,251, 32, 5,222,238,234, 1, 66, 58,131,111, 13,231, -231, 19,238, 63,184,196, 91,127,249, 61,162, 31, 55,181, 54,156, 90, 85, 0, 16, 48,162, 99,204,222, 29,170,211,253,183,135,103, -188,108,173,133, 40, 70,230,212,115, 82,209, 56, 33,144, 28,251,186,101, 87, 83,125, 45,133, 82, 49,165, 41,156,131,111, 64,247, -157,106,240,108, 59, 79,157,248,168, 48,197,242,213,169,129, 88,150,249,196, 10, 84,137,208,236, 56, 28,110, 80,139,172, 56,174, -238,220,193, 56, 70,198,195, 54, 12,211, 0,239, 14,124, 73, 43,230,235, 25, 83,185,198,148,111, 17,119, 59,172,213,225,186,207, -120,218, 10, 62,247,210, 43,248,202,151, 94, 3,142, 43,250,188, 96,125,122, 0,114,193,189,203, 17, 67,116,136, 45,227,208,129, -247, 63, 62,224,221,135,207,240,184, 0,135,210,113,219, 62,194,189, 31,188,135,207,191,126, 31,127,240,181,215,241,234, 43,119, - 48,238,119,168,209,131, 10, 10,132, 49, 33,185,134, 59, 23, 59,236,242,130, 97, 63,226,226, 43,159, 64,129,199,237,188,162, 49, -175,250,209,227, 27,124, 60,120,180,188, 10, 56,137,211, 46,143,138, 24,153, 76, 24, 4, 4,211,106, 70, 41,142,209,154, 44,254, - 25, 30,226,156, 94, 48, 34,226,170,101,229, 51, 41,154,150,188,122,164, 97, 66,171, 51,208, 35, 85,219, 13,165,102, 68,229,234, -183,134, 52,142,114,128,114,108,190, 46,194,223, 87, 60,166,247, 17,185, 22, 30,199,116, 95,148, 45, 21,204,241,210,219,248,243, - 5,128, 96, 81, 69,239, 36, 93,127, 36, 13,173,119,113, 5,228, 53, 75,114, 89, 74, 2, 22, 98,110,124, 71, 55,212,234, 41, 44, -201, 25,155, 91, 58,118,239,229, 34, 82,129,149, 83,119, 7, 69,156,234,167, 7,164,179, 78,195,184,133, 51,113,218,151,248,126, -245,147,231, 92,225, 46, 58,106,205,165,108, 99,253,224, 49,142, 19, 82, 74,219,250,194, 68,200,153,130, 49,201,172,207,204,126, -191,189, 57,224,246,112,195,100,190, 17,206,241, 29, 8,138, 1,230, 90,198, 38,179,221, 10,164, 76, 48, 87,101, 46,253,169, 19, - 73, 59,215, 90,132,223,222,154,232, 52, 68,211, 32,120,106,245,124, 55,238,227, 11, 17,220,146,219, 49, 42, 68,119, 59, 99,108, -229, 82,184, 94,203, 39,121, 24,153, 19,159, 42,137,110, 0,245, 3,154,142, 82,196, 58,140, 74, 81, 99, 99,163,218, 54,248, 11, -241,217,202,244,240,110,131, 4,193, 72,128,180,243,241, 66,119,222, 89,134,249,134, 63,151, 19, 45, 70,218,155, 37,234,144, 62, -115,111,171, 31, 75,132,236, 98,137,141,180,166, 53,238,203,213,226, 39,211, 94,152, 6, 73,156, 89,201, 52, 31,170,113, 19, 38, -131,156, 89, 17,206,195, 97, 35,179,233,216, 68,198, 78,253, 57, 85,124,107,221,246,236, 34,173,247, 54,106, 17,220,170, 23,175, - 58,119,112,242, 82,104,226,149,127,110,156,169, 35, 53,181,133,105,231, 54,142,131,141, 49, 23, 39, 29, 91,168, 17,227, 52, 9, - 12,164,169, 15,179,194,119,111,246,167,113, 28, 49, 76,201,162, 52,245, 18,137, 41,201,127,247,158,149,173,136, 19,214,121, 21, -177, 21, 85,212,211,126, 20,237,138, 99,204, 42,154,249,187, 59,243,108,197, 75, 75,155,143,231,216,104, 24,140,243, 61,207,171, -252, 80,104,167,242, 62, 88,222,113, 43, 89,138,130, 78, 32, 66,107, 50, 18,175, 5,205, 9,239,183,183, 77,128, 99, 35, 97, 11, - 50,145,145,188, 39,233,170, 17, 40,161,197, 81, 39,188, 66,237,106,146,202, 37,223,171,239, 25,189,201, 24, 83,243,174, 67,220, -126, 6, 93,160,110,226,131,165,186,184,150, 38, 23, 99,149,213, 64,163,128, 67,172,116, 50,217,170,172, 74,125, 8,216, 93,125, - 2,189, 53, 12, 67,192,229,213, 25,202,114,131,159,190,249,183, 39,160, 28,108,197, 95,107,128,247, 76,119,210,110,187, 90, 71, - 97, 65, 6, 4,138,232,101,176,165, 97,193, 62, 35,121, 22,250, 9,241,169,161, 48,133,111,203,207,110,118,209,200,231,209, 68, -229,111,200, 78,229, 48,104,119, 9,243, 62,231, 44,113,195,157, 97, 50, 96,222,188, 82,203,130,247,104, 77, 14,232,227, 65,248, -253,103,231,103,216,237, 38,164, 52, 96, 72, 17,117, 93,209, 50, 16, 92,195, 24, 39,248,222, 16, 82, 66,244,128, 75, 17,175,222, -127, 9,127,244,247,127, 23, 15,238, 95,160, 30,102,220,126,244, 4, 1,210,221, 58,239, 48, 47, 11,254,244,237, 71,248,139, 15, -158,225, 73, 7,188, 11,136, 20, 48,117, 0, 31, 92, 47,120,239, 47,127,137,239,253,228,215,248,234, 27, 15,240,199, 95,123, 13, - 15, 82, 4,206, 70, 72,171,238, 48,207, 43,194,152,196, 29, 81, 42,234,211,103,240,247,239, 99,168, 13,240, 1,117, 93,241,242, -139, 23,184,153,103,226, 88,133,207, 93,214,140,152, 28,218, 42,124,234,238,153, 26, 5,229,184,203,225, 42,142, 65, 71, 37,182, -144, 17,129,193,200,134,181, 10,247, 97,153,143, 2,216,104, 3,134,233, 2,243,225,153, 89, 66,229,240, 47,168, 33, 34, 36,122, -121,121,209,168, 96, 76, 66, 92,188,117, 42,161, 69,179, 67,170,102,179, 54,136, 46, 72,227,127,187,166,207,245, 77, 23,196, 3, - 53, 13,131,100, 83,248,128,188, 86,219,131,167, 33,145,164, 73, 85,119,109,124, 39,138,233, 46, 60,213,234, 37,175,252, 26,229, -162, 85, 23,132,106, 77,132,105,225, 55, 6, 3,109, 92, 14,154,109, 47,197,254, 56, 77,162,255, 33, 40,199, 57, 65,213,110,150, - 58, 24,107,223,187, 0,120, 78,229,216, 81, 11,251,221,111,133, 47,121,252,242,123,154,129,135, 90,107,184,126,118,141,101, 89, - 4, 99,205, 11, 92,169,140,224,136, 57, 80,185,238,253,166, 48, 87, 27,169, 34,166,205,106,235, 3, 19,252,156, 89,216, 10,173, -135, 82,224, 78, 38,104,221, 0, 54, 30,173, 10,141, 79,168,113,194,116,215,220,120,157,210,169,251, 69,166,136,205,118,244,173, - 84,184, 94,236, 50,215, 56, 90,130, 89,165, 1,170,155,104,205, 59,181, 76, 90,162,203, 70,248,235, 27,129, 83, 39, 61, 26, 38, -165, 22,111, 89,251,184,147,127, 7,134,196,208, 1,208,182, 12, 1, 93, 41,107,175,191,201,119, 59, 11,166,102,169,117,222, 7, -123, 34,244, 12,215,224, 44, 45, 80,172, 96, 34,215, 64,223, 7, 41, 28, 58, 82, 26, 40,180,115,136, 3, 47,239, 82,152, 94,214, - 56, 82,200,197,172, 20, 50, 14,146,145,102, 72, 81, 62, 40, 95, 81,138,183, 3,123, 93, 51,197, 30, 1, 49, 4,212, 32, 59,244, -204, 63, 71, 59, 54,149, 60,231, 92,196,191, 75, 24, 70,171, 21,185, 3,227,228, 25, 9,200,189,106, 41, 8,177, 99,119,230, 76, -113, 93,178,188,196,162, 4,109, 72,105, 27,117,233, 14,125, 24, 5,179,169, 15, 94,226,238,185,123, 81,238,245,214,112,115, 88, -216,237, 15, 54, 38,113, 36,128, 45, 21, 8,154,165,205, 34, 69,210,209,182,136,215,228, 4,195,185,174, 5,199,227,194, 8, 86, - 41, 68, 96, 41,114,226, 59, 31,210, 36,213,104,109,112, 33,160,151,138,218, 36,245, 40, 69,143,222,156,141, 87,106, 41,224, 16, - 71, 46,244, 90,121,240, 9,185,200,161, 19, 58, 17,205, 18,161, 94,118, 40, 28, 2, 13, 30,244,215,247,128,224, 65,139,211,150, -219, 94, 21, 39,203, 60,235,112,178,135,158, 73,162, 50, 21, 60,201,125,157, 1, 3,226,253,103, 97, 51, 93, 34,141,151, 40,185, - 96,191, 31,113,255,165, 43,252,232,219,255,175,237,137, 78,171, 82,112, 42, 17, 25,179,170,187, 38, 45, 38, 10,113,181,157,234, -100, 17, 64, 6,123, 9, 61, 28, 74, 19,241, 75,169,133, 35,175,190, 93,182,232,194,249,167, 99,162,247,102,149,175,122, 76,245, - 50,151, 40,223, 73,246,194,196, 46, 6,231,144, 53, 2, 82, 39, 46,173, 89,170,152, 6,184,196,224, 16,131, 8,155,134,113,224, -216, 86,138,158,154, 87, 60, 91, 22,140,211,132,188, 22, 73,249, 67,199,184,155,176, 60,123, 2,119, 43, 94,240,233,124,196,213, -167, 94,193, 55,250, 25,238,222, 61,199,229,110,192,114,152,113,120,124,141,253,229, 30, 45, 23,188,255,241, 51,252, 31,223,251, - 25,126,177, 8, 86, 55,250,136,192,138,255,156,122,139,133,177,201,107,107,248,206,155,239,227,219,127,251, 11,124,235, 19,119, -240, 39, 95,120, 17,247,239,236,177, 30, 87,140,209,195,223,153,176, 60,140, 40, 77,222,161,154,129,167, 55, 11,230,165, 98, 64, -197,179,210,128,171,196,103,163, 19, 1, 42, 7,122,171, 2, 72, 10, 1,232, 77,190,199,170,185,212, 4,139,196, 20, 49, 76, 35, - 74, 94,140,193,221,155,183, 2,203,117,177, 91,201, 58,206,193,135, 1, 49, 77, 88,151,131, 60, 31, 28,199,171,234, 91, 70,202, -224,142, 49,200,123,131, 83, 30,132,144,227, 74, 89,144,124, 56, 89,191, 48,203,224, 68,136, 38,118,204, 98, 33, 47,222,123, 73, - 71, 20, 0, 5, 73,152,171, 81,218,198, 29, 93, 17, 36,144, 85, 38,246, 9, 16, 43,219, 51,109,137,133,189,217, 58,107,203, 44, -232, 6,168,145, 51, 83, 38,111,206,162, 99, 35,195,137, 58,166,105,226, 58, 40, 96, 24,100, 4,171, 42,119, 45, 92,101, 58, 23, - 72,118,108, 76, 80,148,239,101,226,232, 94,157, 48, 41, 12, 44, 80,212,106, 43,207,247,178,102,204,199, 3,150,117, 21,220, 47, -188,129, 79, 26, 28, 2,223,167,148,252, 9, 41, 31,240, 49, 81, 33,142,231, 46,218, 74, 69,189,166, 24, 10,118,124,181,226,161, -181,142,105,191,231,103, 28, 13,135,234,160, 59,247,237, 2,243,124, 79,185, 90, 70, 36,153, 77,178, 6,164, 17, 66, 35,167,158, -104,225,222,116, 93,216,237,226,244,232,104, 77,226,140, 27,207, 77, 71, 59,155, 92,232, 10, 82,114,219,106, 15, 91,114, 27, 7, -246, 66,253,115,202,206,102,110,123,219, 64, 67, 26, 83, 44,127,182, 51, 75,172,146, 6,205,214,216, 59,106, 19, 17,184,170,232, - 69,148, 46,188,128,224,189,137,221, 84,227,101,207,141, 6,167,245,110,169,148,186,165,108,154,173, 94, 27, 66,116,168, 69,138, -217,168, 21,128,250,141, 67,144,135, 90,213,225, 2,118, 25, 25,222, 81,236, 11, 45,115, 69, 26, 68,200, 37, 23,180,216, 15,214, - 92, 76, 52, 7, 31, 48,140, 82,193,165, 97,144,189,156,151,135,193,195,193, 13, 30,235,202,138,178, 48,149,201,201,223, 39, 35, - 28,170,179, 87,217, 79,250, 16,108,164, 38, 16, 21,152,135,120, 24, 18,169, 90, 9,203,188,152, 85, 41,183,204, 9, 1,161, 50, -172,222,197,183, 62, 48, 97,173,211, 54,163, 24,208,204,104,215, 46,221, 27,139, 26,239, 39, 57, 52, 26, 80,230,140, 82, 58, 14, -183, 71,220,222, 28, 76,197,143, 19,144, 66,111,128, 31, 34,171, 65,174, 2,168,160,245,142,142, 0,126,109,114, 41,173, 38,244, - 82,219,150,166,101,245, 30,108,175,210,170,160,102, 45,128, 1, 82, 60,216,158,142,177,171,112,157, 23, 47,171,208,146, 1,238, -143,148, 71,236, 25,197,169,165,167, 98, 35,101,188,165,197, 82,219,242,162,117, 92,125,210,249, 94,220,255, 12,122,239,216, 77, - 9, 87,119,207,176, 28,158,224,215,191,252, 57,197, 71,180,186, 40, 71,206, 44, 67,253, 57, 32, 71,173, 98,201, 27,198,193,124, -190, 10, 43,145, 67,163,216,244,194,220, 15,112, 22,131,186,137,228,148, 18, 37,251, 85,199,203, 63,132,196, 16,143,196, 93,148, -142,184,104,131,164, 56, 47,231,108, 14,138,101, 97, 74,211, 73,102,113, 34, 48,105,127,182,199, 52, 77, 38,218,217,184, 9, 34, -126, 76, 49, 96,157,103,148,236,208,252, 96,244,185,249,209, 99,132, 82, 49,237, 71, 76, 23,123,212,167, 25,151,119,206, 49, 69, - 15, 44, 11, 14, 31, 61, 70,190,189,133,115, 30, 63,255,240, 41,254,229,119,223,198,195, 90, 16, 93,192, 62, 36,124,254,193, 37, -190,112,111,143,215,238,157,225,206, 89, 66,227,187,144,115,197,135, 79,143,248,235, 95, 60,198,155, 31, 63,195,191,121,239, 67, -252,249,123, 31,227,191,253,131, 55,240,149,215, 95, 64,239,192,254,238, 5, 30,167,143,209,154,195,252,240, 26, 45, 59,148, 39, - 79,241,232,216,112,225, 10,126, 81, 28,238,237, 31, 8, 46,211, 59, 30, 66, 85,148,250,209,137, 90, 62,116,203, 4,144,247, 57, - 32,157, 37,198,252,106,178, 26,139,198, 34,214, 42,181, 15,245, 46, 19,193, 70,187,147,236, 85, 51, 60,249, 7,138,224,245, 97, - 16,109, 78, 76,128, 19, 69,176,138,140,244, 82, 17,226, 96, 20, 59, 28,243, 17,100,140,170,221,164,138,156, 84,221, 47, 29,178, -100,145, 39,211,180,248, 56, 96,156, 38,225,102,199,136,149,121, 1, 42,190,179, 73,101, 99,135,216,113,226, 73,119,182,238, 67, -133,113,225,109,148,101,222,238,102,200,101, 83,241, 67, 26, 23,231, 69,156,230,189,128, 86, 66,218,146, 30, 85,151,161, 9,122, -142, 54,183,202, 73,170,118,106, 41, 69,190,139, 13,209,109,234,232,192, 95,223,123, 37, 81,177,226,246,230, 86,220, 54,107, 97, -182,128,219,248,241,142,170,125, 78, 63, 55,192, 81, 56, 41,192,183,162,165, 54,240,110,200,128, 33,148, 79, 10, 50,231, 17,162, - 4,199,196, 33,154, 75, 65,201,132,104, 21,153,107,205,168, 17,213, 18, 97,199,240, 44,250,204,185, 6,211, 41, 69,175, 20,222, -149,153,235,141, 6, 23,156,136,110, 75,102,202,153, 76, 93,100,152, 92,121,158,118, 4,189,164,233,183,199, 9, 32, 6, 39,132, - 63,141,204, 85, 97,181,118,219,254, 52,154,149,116, 78, 1,193,128, 17,169, 32,252,136,103, 43,116,133, 65,242,155,163, 77, 25, -129,137,122,142,113,171,158,159, 87,162, 77, 82,214,198,195, 56,242,107, 87,132,174, 36,117,246,202,175,205,123,132, 8, 75,239, -172,165, 33,142, 99,162, 0,193,163, 54,207,128,134,110,138, 78,120,142,179,189, 99, 10, 88,165,157, 9,112, 57,163,142, 3, 58, - 42,247,164,241, 36,120,222,147, 31, 14,180, 37,195, 53,135,113, 26,204,247,220,188,216,127,198,105,148,151,139,233, 72,150,145, - 14,129,192, 44, 51, 48,140, 98,175, 26,134,122, 82,177, 80,192, 64,241,137,160, 20,101,100,162,118,186, 82,170,160, 44,179,130, - 71, 88,164, 12, 30, 43,194,137,237,197,155,178, 85, 16,163,158, 65, 4,221,198,239,106,163,200,107,150,241, 9,167, 19,243,156, - 77,165,174,226,171,117, 93, 17,124, 55,223,170, 90,226,106,227, 94,188, 53, 84,181,102,213, 66,112, 3, 51,151, 57, 86, 14, 30, -140, 57, 60,169,146, 77,108, 3,116,238,148,204, 59,172, 40,216,146,101,231,233, 2, 66,148, 17,207, 52, 9, 41, 48,141, 82, 8, - 84, 86,131,178, 35,239, 91,128, 76, 17,158,125,201, 43, 71,237,205,200, 74,182, 58, 49,235,151, 92,176,195,254, 46,226,112, 9, -244,134,253,249,136, 23, 95,186,194, 15,254,253,191,129,115, 18,124,163,137,127,176, 60,228, 45, 34,214,121,143,200,117, 7, 78, -246, 80, 26,165,170, 10,227, 82,178,113, 20, 96,186,141,198,177, 46,177,181,204,175,134, 69,165, 58,235,192,132,122, 22, 69,208, - 2,207,168, 73,207, 11, 94, 46,163,202,159, 65,100,138, 96,103, 74,147,142, 50,199,113, 48,177,203, 48, 16, 80,210, 59,246,251, -221,102, 55,164,245, 42, 70, 21, 91, 2,251, 81,224, 57, 75,115,136,107, 6,214,130,150, 87,140,103, 59,132, 56, 96, 46,133, 69, -104,195,227,159,253, 10,183, 79,174,209, 59,240,183,239,252, 6,255,226,135,239,162,184,128,215, 46,239,226,143,191,249, 59,248, -226,231, 95,198,221,201,163,253,242,151,168, 89, 38, 62,178, 43,140,112,232,120,229,254, 57,190,246,153, 23,240,244,217, 1, 63, -252,233, 99,252,235,183, 63,192,127,255,253,119,241, 79, 31,207,248, 47, 63,245, 58, 66,233,104, 93,210,160,106,233,104, 79,158, - 97, 31, 28, 62,121, 21,177,222, 54,228, 15,158,225, 7,191,190,193,227,155, 5,127,248,173, 79,227,242, 42, 88,170,148,236, 81, - 87, 52, 47,254,217,166,225, 72, 37, 19,246, 35, 63,211,113, 28,144, 91,230,200,186,152, 22, 37,120,135,222,188,125, 46,181, 64, - 8,120,113, 68,136, 2, 8,169,173,159,172,132, 88,152,217,146,161, 91, 17, 81,153,105, 96, 59,206,144,108, 76,169,228, 60, 67, - 88,240,215,108,216,205,190, 5, 20, 85,153, 94,197, 24, 1, 62,207,229, 86, 56,229,195,152,158, 35, 38,154,139,162,119, 22, 52, -164, 72,246,141, 83, 14,180,109,199,206, 11,191,182,138,224,195,182, 23, 55,191, 51, 12, 96, 18, 83,192,126,191,223, 60,216,236, -101,155,135, 21,172,176, 49,120,195,110,191, 51,224, 85, 76, 9, 49,137,179,162,113, 20,171,251,224, 74,207,122,206, 5, 57, 23, -220,222,222,160,148, 98,187, 91, 7, 79,107,169, 20, 79, 90,168,196,152, 78, 64, 46,206,220, 34, 18, 98,228,172,219, 78, 92, 79, - 56,175,251, 50,253,178, 83, 0, 0, 32, 0, 73, 68, 65, 84, 98,142,249,201, 52,177, 96, 46,218,245, 4, 64,148,141,213,175, 72, - 87,181,215,122,242, 79,116,237, 88,153, 81,239, 3, 25, 33,129,228, 56,166,166, 57,235,136, 27,201,106, 69,186,244,222, 76,157, -207, 81,139,104,194,216, 2, 91, 1, 46, 57,103,198, 22,113, 92, 59,240,255,108,143,126, 2, 34,176, 78, 94,173,242, 93,201,110, -104, 50,138,111,218,181,243,158,226,121,102, 24, 95, 78,170, 53,187,194,121,209,177, 41, 0, 72, 19, 21,149,141,160,161, 94,153, -188, 24, 71,139,110,103,199, 39,235, 93,177,197,169,229, 57,170,224, 65, 83,186,224, 29, 82, 24, 12,242, 98, 85, 43,156,169,148, - 91,235,136, 73, 58, 28, 25, 69, 53, 59,184, 79,131, 13,212,135, 55,237, 70, 9, 0, 41, 34,132,144,130, 1, 27, 14, 47, 4,254, -176,173, 95, 36,190,177, 74,244,225,218,153,186,147,196,227, 62, 13, 56, 30, 86,140,196,218, 74,210, 91, 98,247,219,204,166,149, - 6, 79,226, 27, 76, 21, 45, 47, 3, 48, 12, 17,183, 55, 11,134,193,195, 37,207, 76,101, 7, 87,229,240,145, 75,188,154, 31, 94, - 94,200, 2, 31, 2,230,121,193, 50,175, 56,220, 30, 77, 44, 23,163, 55, 59,220, 56, 10, 57, 78, 87, 22, 42, 22,170,117,235, 88, -236,129,229, 88, 89, 84,224,188, 96, 89, 69, 6, 39, 49,147, 53, 47,182,203,113,208,181, 0, 44,247, 87,237, 98,218, 41, 36, 23, - 17,146, 71, 8, 66,109, 11, 60, 72,161,193, 23,212,133,200,133, 39,123,168,101, 89, 80, 75, 54,176,140,238, 29,117,252,172, 8, -208,141,190, 41,240,146,233,234, 19, 40,185, 98,191, 75,184,119,255, 18,215,143, 63,194,199, 31,126,200,176,156,205,106,168,123, - 58,231, 20,221,216,201,165,142, 6,238, 0, 47, 69, 37,254,169,126, 37,132, 64,224,131, 50,236,197,215,217,105,253, 19,253,130, - 67,201,109, 19,228, 1,150,177, 28, 7, 81,180, 15,244,222,142,211, 72, 98, 30, 76,128,199, 6, 65, 18,228,106, 49, 77, 68, 8, - 1,187,105,226,115, 42,123,211,152, 18,198,113,176, 66, 78,112,163,137,207,118, 51,165,117,239, 14, 99,242,184, 56, 75,152, 51, - 4, 34, 17, 2,130, 19,177,230,186, 54, 60,124,248, 12,239,255,242, 9, 92, 95,240,169,207,222, 5, 98,194,175, 63,190,193,255, -252, 23, 63,199, 16, 71,252,189,223,121, 29,127,242, 15,126, 15,247,238, 95,202,101,145, 23,228,228,225,181, 99,116, 50,169, 41, -189,195, 51,111,249,236,124,135, 63,249,234, 30,159,121,241, 2,255,195,119,127,138,255,243,221, 15,241,217,247,159,224,235,159, -126,193, 14, 44,160,195,119,177, 95, 13, 83,192,244,165, 55,240,143,191, 33,123,207,255,233,127,253,115,156,157,239, 49, 76,194, -115,152,143,212,138,132,205,122,228,125, 68,136,242,185,231,156, 49,142, 34,126, 90,215,149,145,151, 17, 64,197, 50,207, 24,122, - 68,233, 14,195, 32, 41,114,121, 45,136,131,116, 32,121,105,136,113,148,226,177,117, 6,105, 52, 99,135,119, 10,155, 84,179,164, - 83,156,224, 68, 46, 32, 10,227,198,238, 7, 39,249,238,176, 73,147,118,215,122, 38,181, 6, 4,170,221,197,189, 38,103,151,231, -115, 31,131,252,220,213,161,148,215,124,130,100,117, 50,129,243, 14, 57,235,206,215,139,149,203,109, 35, 92,229, 55, 24,220,133, -192, 30,237,226, 53,255, 92,244, 64,194,122,215, 9,150,119,162,205,206,107,177,192, 14,253,121,167, 97,160,184, 83,138,136, 65, - 85,226, 39,185,235,157,223,167,142,237,115, 46,204,169, 23, 63,186, 88,167,248, 61, 19,219,108,188,113, 71, 11,151, 10,213, 88, - 44,233,229, 44,161, 79,226, 90,234,108,192, 84,227, 35, 86, 92,217,203, 7, 54,117, 46, 13,204,154,119,150,251,237, 85,183,228, - 61,198,113,164, 46, 71, 14,233, 82,171,116,240, 60, 31, 99,144, 85,176,119, 64,205, 34,118,172,101, 97, 0,153,140,221,157,171, - 70, 62, 84,204, 48,122, 67,240,178, 66,243,116, 47,137,141,248,121,180,174,174, 28,117, 23,174,188, 6, 93,197, 54,158, 93, 26, - 12,165,231,132, 61, 91,170,153,160, 86, 40,104,244, 42,188,184,133,124,180,113,250, 22, 26, 68,167, 14, 60,155,166,192,162,243, - 20, 72,228,204,166, 40,119,151,223, 2,107, 56,108, 40,122, 14,178, 49,149,233,120, 71, 84, 44, 41, 8,235,247, 81,252,149,126, - 24,208, 33,121,193,250,141,119, 10, 47,212, 23,172,135,218, 74,164,101,173, 69, 70, 72, 33, 2, 78,152,215,203,156, 49, 12,178, -252, 31, 6,138,181, 6,121, 17,215, 53,163, 22,142,121, 2,199, 29,206,227,112, 59, 91,220,168,236,188,101,207, 55, 76, 19, 5, -120, 17,216,251, 19, 92,160,116, 91,187, 75, 9,105, 81, 0,132,250,217,123,175, 76,108, 11,130,121, 13, 30,203,156,173,154,149, - 7, 3,198,150,159,215, 76,236,162,183, 96,133,101,201, 56,220, 10,124,229,120, 92, 48, 31, 87,198, 1, 38,171, 0, 85,109, 41, -254, 73,121,114, 74,173, 76,117,106, 39,156, 97, 57,140, 2,199,197,129,208, 2,101, 78,203, 5, 61,195, 59, 71, 82, 30,199,213, -157, 54, 51,134,171, 4, 29,213,163, 19, 18, 66,123,157,147,162, 43, 38,207,169, 95, 23, 46,182, 33, 8,229, 1,107, 20, 28,150, - 44,232, 87, 25,245, 53, 27, 55,169,149,240, 84,208, 88, 57,246,129,115, 24,207,238, 98,119,126, 15,181, 52,156, 93, 76,184,247, -224, 18,127,250,255,252, 7,126,246,160,104,198,217,216, 81, 62,107, 25,197,139, 40, 37,114, 47,180,133,134,104,202,151,198,124, -106,149,156,233,145,151, 84, 58, 71, 33,144, 18,199, 18,106,145,103, 79, 85,162,227,184,131,243,209,216,219, 10,174, 80,117,187, - 56,139,250,230,225,165,229, 70,166, 43,128,247,233,185,164, 58, 73,171, 19, 1,211, 52, 73, 78,187,194,107,210, 16,185,126,111, - 22, 97,108, 48,157,229,136,125, 2,198,208,176,252,246, 49, 48, 37,132, 48,161,149, 21,229,120,139, 95,189,247, 91,252,229,143, -126,129,111,252,209,235, 64, 76,152,115,197,191,250,238,187, 24,134, 17,255,249, 87, 63,133, 63,249, 71,223, 64, 96,198,115,121, -244, 16,158,208,155,226, 51,144, 43, 48, 12,232,181,195, 67,166, 22,174, 55,248, 46,251,236,207,188,122, 7,255,217,231, 95,198, -255,242,119,191,198,247,223,253, 8,159,124,241,108, 43,142,164,217,194,184, 79, 24, 46,247, 24,238,221,197,184,159,100,199, 55, -136,251, 36, 68,143, 82, 59,166,221, 36,133, 32, 54,118,186,163,224,169,148,138, 16,155,169,113, 99, 12, 2, 11,130, 19,215,132, -119,152,143, 51,166,253, 14,165, 20,166, 61, 6, 91,255,192,123,184,144, 16,135, 73, 58,203,146,105,197,244, 39,158, 95, 25,231, -235, 1,219,106, 69,117,155,200, 81, 4,187,202, 45,216, 92, 33,205, 14, 65, 61, 48,157,172, 22, 99,103,216,135,220,231,129,120, - 82,121,151,183,221,166,224, 73, 53,246,171,219, 59, 28, 8, 9,217, 78, 96,216,244, 80,119,201,218,213,115, 45,255,156,242,189, - 55, 96,156,118, 50,233, 26, 70,209,100,140,137,235,164,206, 14,125, 75,160, 3, 97, 72,137,171, 78,193, 56, 23,140,211,104, 10, -244, 77,244,217, 13,146,210,154,184,113,150, 69,105, 99,141,211, 42,119, 18, 79, 29,236,189, 74,105, 16, 22, 0,119,205,218,105, - 62,175,108,223,194,105,154,178, 63,156, 55,231,136, 83,104,144,247,178, 62,116,206,118,253,157, 52,185,224, 29, 65, 58, 68,159, -214,134,230,232, 55,103,216,139,162,137, 43, 54,156,172,216, 23,203, 70,108, 3,163,119,245, 75,211,162,138,118, 53,231,131,228, -155,177, 81, 82, 87,148,254,216,186,219,236,179, 54,130,239,218, 65, 59,107, 62,187,238,234,249,239,192, 11, 25,252,217, 40,205, -112,155,212,136, 40, 64,221, 74,112, 81,198,231, 39, 46, 1,189,176, 29,168, 73, 97,129,238,180,112,228,158, 63,156,228,180, 55, -234, 9,116, 42, 21,163,156, 59, 33,122,201, 47, 80,125, 18, 24,111,168, 34, 6,195,108,106,134,247,201,194, 30, 76,110,106,220, - 47,121,250,129, 99, 10,188, 0, 42,106,208,252,225,196, 49,151, 23,161,131,122, 5,185,187, 57,205, 87, 79, 41, 82, 77,219,185, -255,213, 61, 4, 76, 68, 53,216,154, 0,198, 46, 78, 99, 66,226,174,102,218, 37, 73,207, 33,250, 84, 89,223,149,192,255,141, 79, -223,208,153,131,156,146, 99, 20, 35, 49,139,185, 96, 94,169,230,245, 73, 42,169,218, 81,136,123,173,181, 96,153, 87, 41, 48, 70, - 25,211, 74,192,133, 28, 98,195, 16,159,131,242, 31,110, 14, 76, 36,234,180,190,193,130, 14,188,135, 89,213,148, 20, 37, 15,188, -172, 44,164,240,233, 36,168, 81,249,201,209,187,216,252, 60, 59,255, 98,197,132, 67, 23,132,233, 52, 24,224, 39, 14, 3,224,228, -176,106, 16,139,155,101, 69,231, 85, 64, 12,189,161,149,149, 62, 78,233, 60,225,213, 3,188,133,216,224, 4,127, 90,115,198,229, - 43,175,163,213,142,221,110,192,253, 7, 87,120,248,193,251,184,126,250,196, 68, 68, 62, 60,239,115, 85,100,107, 26, 18,163, 76, -171, 98,192,225,248, 44,136,125, 5, 44, 26,157,121, 83,189,183,102,222,198,248,162, 0, 21,204,237,186, 72,104,135,118, 44,250, -244,123, 31, 13,165, 91,248,252,104, 17,161,135,190,140,144, 69,121, 61,237,119, 86, 13,199, 52,136,245,144,151,117, 74,145,140, -125,207, 60,114, 66,108,106,231,138, 98,219,249,235, 68,170, 12, 30,104, 25, 67,136,240,247, 94, 64,197,125,249, 12,175,159, 0, -189,224,225,227, 91,236, 81,241,202, 75, 87,136,231, 19,254,213,191,254, 9, 30,151,142,255,234, 15, 62,139,111,126,243, 11, 8, -200,104, 23,151,162, 57, 88, 11,218,147, 39, 8, 14, 66, 36,116,178, 39, 14,209, 83, 57,235, 81, 22,201,143,238, 92,229,124,225, -213, 43, 92,189,243, 17,254,242,175,126,138,254,219,143,241, 95,127,253, 53,249,249,140, 3, 46,223,248, 36, 66,138, 8, 67,194, -238,234, 2,189, 55, 28,110,102,212,222, 49,237,146,237, 14,125,112, 12,212,113, 8, 44, 42,123,242, 88,142,210, 89, 87,126,230, -142, 99,102, 61,240,125,136,112, 53,194,123,249,108,133, 79, 33, 5, 65, 76, 28, 49,198,132,238, 21,231,188,179, 46, 95,199,203, - 62,168,111, 88, 68,118,114,129, 69,142, 39,149,147, 14, 56, 47, 24, 78,181, 58,106,176, 77,107,234, 29,150,253,242, 56,120,179, -131, 38, 22,129,242, 28,121,220,222, 30, 37,186,153, 35,121,213,222,168, 55, 94,255,188,206, 0,143,109,207,203,131, 90, 49,164, - 39, 23,135,172,221,212, 29,228, 24, 30, 52, 50,204,202, 99,183,159, 48,140,163,177, 41, 18, 45, 76, 61,103,238,195, 59, 39, 94, -209,186,219, 82,178,172,232, 20,108,211, 65, 11,110,227, 72,182, 88,254,192,241, 56,155,142, 71, 93, 64,232,142,239,133, 20,102, -173, 74,113,225,131, 71, 46,141, 64,171,138,224,187,157, 77, 74, 64,211,137, 98,215,179,137, 99, 99,125,207, 85,169, 45,199,152, - 20,188,173,138,107,160,243,125,151, 11,158, 8,107, 93,179,180,138,249,112,228,120,187,113,172, 12,212, 44,141, 70,231,202,177, -181, 98, 42,118, 71,150, 5,161,233, 91,236,173, 38,117,202,226,136,119,201, 41,174,151,182,187,147,128, 26, 29,198,251, 19,136, -145,102,140,200,133,173,122, 41,137,139,110,173,137, 21,212,176,201,125, 75,140,116, 39,247, 23,156,229, 85, 8, 95, 0,150,167, - 17,194,128, 82, 59, 87,202, 81, 38, 25,173,114, 34,210, 45,171,194, 10,135, 86,145,210, 96, 43, 20, 97, 15,104,163, 35, 98,205, - 24, 2,162, 2, 27,188,229,192,210, 39, 13,221, 73,178,243, 32, 74, 86,253,168,194, 7,167,108,223,109,241,112, 37, 75,230,177, - 8,219,188,169,185, 29,119,106, 18, 93, 39, 98,149,156, 59,243,110,133,118,148,156,199, 90,154, 65, 19,180,226,213,200, 87,253, - 6, 99,138, 72,137, 47,127,240,114,193, 50,195, 60, 4,143,188, 86,130,104,250,201,225, 47,157,147,119, 14,203,178,154, 71,113, - 24, 5,132,179, 16, 97,232, 0,120, 78, 32,116, 5,177, 46,162, 96,238,252,140, 98,234,198, 96,175, 85, 69,134,149,112, 27, 96, -158, 37,156,165, 82, 13,239,212,103,201,209,144, 84,123, 10,202,144, 73, 73,109,204,138, 39,221,104, 93, 22,218, 54,138,125,198, - 42,190, 9,129,126, 96, 84,195, 30, 58,120,238, 2, 71, 97, 4, 3, 34,186,241,201,214, 17,142,197, 90,173, 13,174, 9,208,166, -180,142,188, 46,100,207, 55, 30, 88, 82, 85, 22,250,216,107,219,116, 12,242, 79, 32,237,238, 96, 58,127, 17, 49,122, 92,222,217, -227,238, 11,103,248,246,255,245,111,173,179,210,234,184, 85,209, 96, 40,112, 70, 19,251, 58, 45,121,194, 40, 40, 98, 89, 63, 25, -147,106,202,145,134, 91,120,162,128, 19,195,121,116,186, 36,228, 61,161,114,105,110,116, 55, 76,229, 54,125,177,145,125, 43, 40, -228,119, 59,141,211,164, 8, 47, 48,184, 99,156,118,214,145, 52,218, 44,135, 65,130, 37,134, 97, 64, 26,105, 85,171,149,161, 24, -209,158,125, 41, 40,171,217, 56, 75, 41, 24, 2, 16, 47,206,225, 11,144,231, 89, 20,250, 87, 87,104, 15, 63,194,178, 44,248,212, -131, 43,220,121,225, 28,223,125,235, 67,252,236,227, 27,252,147, 63,124, 3,223,250,195,207, 73,183, 50,238, 17,247,231, 72,189, -193,191,250, 10,202,251,191, 4,214, 21, 46,122,116, 7, 44,199,130, 52,202,231,136, 74,222, 52, 19,248,186,243,120,249,238, 25, -254,139, 47,191,138,127,249, 55,239,225, 71,191, 42,248,214,103, 95,192,107,175,221,195,229,231, 62,137,116,182,151,156,235,224, -225, 52, 52,164,175, 38,126, 85,190,117,171, 21,197,109,171, 53, 31, 34,226, 40,238,139, 90, 86,198, 14, 71, 94,190,222, 18,178, -212,161, 82,139, 98,122, 61,162,249,255, 55, 98, 90,119, 14, 45, 68, 36,239, 49,237,207,225, 67, 66, 41, 29,222,211, 22,202,238, -168, 82,240, 88, 75, 59, 97,108, 51, 96, 42, 36, 32,111, 33, 34, 18,251,185,141, 85,149, 22, 38,231, 13,245, 26, 38,216, 19, 54, -119, 8,145, 60, 7,233,126,197, 61, 83,236,178,146,116,177,106, 9,130,202,235,208, 67, 26,182, 34, 10,150,177,238,188,131,239, -213, 58,110, 88,106,153,172,113,166,221,158, 19, 73, 71,176, 85,181, 73,131, 56,146,196,170,166,255, 41, 89,254,221, 48, 74,170, - 93, 24, 97, 84,206,156,183, 8,211,121,158,197,159,206, 6,108, 89,150,147, 75, 77,249, 34,186, 74, 29,136, 54, 5, 34,127, 77, -140,145,159,177,127, 62, 92,132,207, 88, 61,129,250, 56, 56,211,101,133,232, 44,178, 87, 63, 39,205, 83,208,240,172, 82, 36,113, -174,156,184, 76, 52,128,171, 50,194,184, 17,105, 11,198,163,202, 52, 77, 2,129,186,151,177,185,231, 26,210,187,206, 9, 32,207, -111, 71, 43, 30,141, 98, 81, 5,198,234,121, 84,139,152,131,197,248,186,109,152,179,209,223,116,114, 10, 61, 59,187,233,154,108, - 77,170,171,122,239, 81,123,181,194, 74,246,236,122,102, 71,203,185, 16,222,125, 71, 64,218,210,218,218,115,128, 67,129,175,249, - 77, 24,173,182, 92,229,189,108, 19,102,103,250, 18,239, 3, 92,147,166, 41, 2, 21,193,179, 99, 30,252,201,101,186,153,240, 37, -223,124, 65,140,130,108,213, 93,121, 87,186, 23, 43,245,134, 14,239, 26,242,218, 55, 38, 50,186,101,202, 46,203, 74, 36,101,176, -188,102, 57,172,217,109,244,138, 86, 5,150,209, 90,195, 50,175,216,159, 77,102,129,145, 10, 95, 95,136,136,152, 2,237, 42, 13, -227,200,234,157,200, 78, 85, 56,170, 77,111, 24,226, 9,107, 28,246,131, 6,247,201,199,219, 25,227,152, 88, 77, 49, 87, 26,192, -124, 92,177, 44,133, 44,102, 41, 12,198, 49,225,120, 88, 12,216,163, 69, 73, 99, 53,220,106,145,131,141,213, 84,161, 63, 52, 68, -217,111,107, 85, 29, 61, 44, 65, 40,120,143,117, 93, 88,125, 83,109,174, 59,125, 8,235, 28,138, 90,133,168, 58, 85, 24, 38, 34, -195,132, 97,218, 97,152, 38,132,144, 4, 38,193,125,153,115,226, 50,136,145,126,115, 70, 16,172,115, 22,252,233,124, 48,122,155, - 38, 81,157,142, 15,189,223,104, 88,146,204, 4, 92,189,244, 57,160, 3, 67, 10,184,119,255, 18,143, 62,124, 31,203,186, 72,232, -194,137, 64,166,214,134, 33,208,175,203,140,244,206, 28,104,153,164,136, 21, 82,193, 52, 58, 21,234, 0, 66, 15,102,181,236,189, - 35, 12, 65,212,209,238,196,154,230, 34,187,110,144,173, 0, 59,108, 27, 9,130, 78,195,110, 40,154, 1,119,243, 58, 41, 80, 21, -187,190, 28,202,234, 22, 87,132, 96, 70, 53,165, 48,166,128,196,201, 81,111,242,178,198, 24,176, 46, 89,116, 4,124, 67, 5,146, - 33, 99,215,221, 11,247,165, 0, 40, 11,206, 46,206,208, 91,197,242,100, 70, 91, 87, 60,185, 89,112,247,114,143,135, 55, 25,255, -223,143,127,131, 63,250,242,107,248,135,223,250, 18,252,221, 23,112,251,214, 91,146,163,112,118,134,158, 6,184,221, 14,225,254, -139, 8, 79, 30,162,173,194,104,223, 13,222, 86, 24, 34,151, 16, 61, 70,206, 13, 62,116, 32,120,252,254, 27, 47,226, 71,239, 63, -198,219, 79, 15,248,197,161,226,119,191,252, 89,196,200, 14,198, 73,104, 79,125,118,141,180,223, 9,105, 76, 87, 70,132,129,172, -107,135,227,101,182,155,162, 93, 32,226, 23, 23,152,139, 15, 14,105, 72,178, 58,138, 18,160,228, 60,199,223,189, 99, 62,222,202, -179, 23,131,140, 28,137, 1,149,212, 49, 1, 35, 57, 42,201,215,101, 17, 75,145, 75, 70,245,203,235, 98, 12, 3,197, 29, 43, 84, -168,107, 86,249, 9, 57,210,200,132,110,131,183, 56,207,206, 94,247,189,164,193, 45,179,240,236, 83, 74, 24, 71,153,118, 73, 92, -177,210,234, 28,187,167,108,228,195,110,133, 37, 71,235, 80, 56, 20,108, 90,100,170,117, 71, 68,113, 96,163, 20, 69, 56, 54,142, - 19,215,149,193, 86, 99,133, 77, 78,165, 77, 49, 70,225,209,207,199,217, 10, 37, 13, 92, 82, 8, 76, 56, 89,141,249, 32, 13,193, -178, 44, 40, 12,214, 42,132,192,200,222, 53, 88,102,185,163, 11, 68, 63, 15,125,119, 20,198,162, 90, 0, 93,181,170, 59, 72, 66, -117,220,137, 53, 20,132,118, 21,235,136,101,237,169,240,168,106, 69,128,172,172,156,249,255,117,234,167,239,140,198,136,162, 85, - 89,199,234, 5,223, 10, 98, 0,122,115, 42,206,103, 81, 95,120,214, 87,235,172,213,194,230,156,131,235, 10,235,169, 27,232, 42, - 50,139, 92, 19,213,220,137, 85, 76, 47, 94,108,235, 21,239,148,220,160,122, 9,122,197,149, 8,199,117, 0, 76,160,235,248,103, -176,177,177, 70, 5,204,164, 72, 54,226,151, 38,154,197, 35, 2, 45,116,221,210, 54, 59,127,127,103, 3,167,201,148, 41,249, 19, -111,189,125,225,128,235,136, 50,167,215,131,168, 18,130, 48, 96, 93,148, 4, 38,127,120, 74,114, 17, 79,211, 36, 17,138,204, 29, - 46, 85, 70,209,157, 62, 94,231,221,150,212, 3, 7,228, 98, 82,124,217,167,121,195, 28, 58, 31,144, 98,194, 82, 87,142, 65,101, -204, 89, 91,181,131,254,120, 88,144,115,197,217,249,132, 16, 28, 90, 5,134,113,131,150,196, 20, 49, 78,145, 59,161,104, 34,149, - 90, 26, 3,220, 2,134, 36,149,120,163,223,122, 24,182, 52,174,101, 94,112,184,153,233,203,148,145,108, 94, 10,242, 42, 52,160, -195, 97, 17,136,206, 20,216,101, 11,213, 78, 49,166,181, 20,180, 42, 99,248, 90, 42,150,121, 21,155,156,250, 29,117, 71,237,164, - 67, 93,151, 5, 67, 18,187,148,240,225, 37,213,170, 6, 39, 99,112,170,225,197,150, 37,135, 66,119, 91,231,171,188,117,231,129, -224, 54,142,125, 26, 39, 76,251, 51,120,166, 78,249,144,108,167, 44, 42, 89, 17, 63, 90,236, 45,247,200,181,172,150,194, 20,188, -136, 89, 82, 10, 20, 60,249,173,219,162, 69,200,133,128,180,187,194,249,221,151,209,123,199,197,229, 30,103,231, 3,126,248,195, -159, 32,132,100,171,140,142, 46,138, 77, 10, 13, 85,165,233,189,108,158, 60,191,246, 20, 61, 33, 47,133, 35,164,110,163,175, 92, - 50,233,122,186, 87, 93, 77,191,160,113,186,250,146,118,242, 8,192,201, 66, 35, 84, 40,176, 27,215,110,202, 91, 33,229, 12,222, -163, 30, 96, 61, 28,158, 83,200,186,110,157,135,198, 91, 74,232,132,116,202, 62, 72, 53, 94, 75, 17,126,182, 58, 28,184,247, 10, -110,194,176,223, 33, 31,142,168,168, 8,174,163, 62,123,132,225,241,199,168, 49,162,199,132, 47,188,254, 0,239,252,230, 26,251, -105,192, 63,248,250,235, 66, 53,123,244, 16,195,229, 5,220,186,162, 29,111, 17,199, 29,224, 61,202,249,185, 60, 83,183,183, 24, -234, 13,202,218,224,209, 0,142,198, 93,136,242, 30, 81,157,223, 29,144,162,195, 55, 94,191,135,119,254,250,128, 95, 95, 47,130, - 74,245,226, 73,174, 77,190,231,117, 94, 49, 31,102,228,226, 25,245, 40, 19,181,249, 88, 0,178,192,135,113, 64,206,176,207,160, -107,241, 15,241,247,107,216,143,136,190, 6,180, 90,176, 63, 15,152, 15,206,198,215,195, 56, 89,158,122, 94, 51,133, 95, 27,103, - 0,232,136,221,145,224, 6, 22,180, 43,173,143, 98,225,139, 41,162,172,197, 86, 58, 14,157, 23,182,240,204,141, 0,217, 27, 39, -120, 42, 50,146,157,122, 72,210,189,166, 16,132,114,198,115,100, 93,165, 48,235,224,250,128, 95,115,233, 39, 30,102, 10, 57, 79, - 99,129, 45, 6,211,183, 19, 33,150, 55,102,134, 9,158,154,147,119, 36, 38,236,247,123, 92, 94, 93, 98,152, 70, 78,162, 68,139, - 0,163,110, 50,182,212,111, 90, 1,209, 36,200,207, 55, 40, 28,172, 11,234, 90, 11,187,227,225,136,101, 89,172,171,172,165, 72, -106, 91, 20, 12,183, 78, 35, 60, 19,210, 68,143, 34,151,174,170,232, 85, 47, 82, 74,145,179,131, 83, 28,161,150,109, 80,175,206, - 12,112, 45,168,226, 36, 43,129, 86,183,181,197,178, 48,170, 25,242,174,116,238,208, 58,232,159,175, 91,183,222, 91,165,183,188, - 17,139, 93,209, 25,128, 37, 90,162,142,200,228, 77,113, 47, 54,222, 67, 50, 29,241,212, 35,105,196,170, 20, 39,253,185, 8,230, -222, 53, 30,156, 19, 64, 54,125, 98,127,212, 44,144,246, 92,152,139, 9, 47,149, 47,224,228,235,175,106, 33,174, 42,160,147, 34, -169,218,234, 69,120,240, 22,232, 3, 71, 87,147,124, 61,193, 11,119,161,148, 83, 33,168, 96,147,107,107,240,188,128,133,255, 18, - 45,133, 13,155,154,195,220, 28,141,211,209, 16, 2,162, 70, 18, 2, 74, 78,131,189,108,102, 45, 33, 1,104, 33,194,181,159, 0, - 57,134, 33, 17, 50, 82,237,129,200,172,228, 58,237, 51,250, 64, 26,238,143, 81,152, 1, 14,205,201,238,254,120,152, 81,138, 8, -110,198,105, 32,117,108,195, 19, 46,180,142,233,126,214, 7,233,128,207, 83, 32,192,166,157,208,163,156, 29,250,154,168,212,122, -133,235, 64, 26, 2,202,154,141, 93,189, 44, 5,227,148,248,195,109,152,143, 98, 83,211, 49,219,110, 39,197, 68,239, 13,243,113, -101,120,128,100,245,230,117,181, 46,125,157, 87, 27, 9,174,139, 6,178,176, 66, 99, 71, 93,104,255, 89,151, 21,173, 8,169,172, - 22, 71,133,123, 49, 96,199, 48, 36,126,238,222, 94, 40,239, 60,124,226,247, 85, 43, 29, 36,146,143, 62, 76, 35,198,221, 30,227, - 52,241, 48, 9, 8,105,176, 8, 92, 5, 94,200,231,207, 40,221, 86, 81,170, 42,206, 59,119, 99,176, 48, 7,239, 35,121,218,222, -176,134, 50, 18,138,184,124,241,211,200,107,195,217,217,128,123, 47, 94,226,241,135,239, 99, 57, 30,145,146, 40,155, 53, 62, 50, -165, 96,222,101, 41,128, 86,192, 24,198,180,173,241,208,242, 42, 18, 81,236,107, 41,114,113, 82,160,178, 46,139, 5, 63,108,143, - 52,131, 92, 74,177,245, 68,237,210,225,120,183, 89, 62,128,182, 29, 62, 44, 40, 66, 18,225,145,247,193, 46, 19, 29,177, 41, 31, - 64,199,158,129, 86,154,113, 74, 4, 69,180,109,228,185, 10, 72,102, 93, 22,155, 42, 84,142, 21,157,247, 24,247, 13,126,185,193, -248,240, 3,244,155, 5, 97,190,134, 95,103,248,139, 29, 50,130,140,177,167, 17,127,246,119,191,198,103, 63,243, 50,238, 62,184, -131,224, 58,194, 75,175,160, 31,110,209, 30, 61, 68, 59, 30, 81,246,139, 20,138, 33,160, 93, 92, 34, 92,221, 65,125,251,109, 70, -120, 74, 71, 14,146,207, 52,229,203, 19, 0,235, 6,143,171, 93, 66,116, 1,143,175,103,209,125,116, 15,172,183,232,113,194,202, -160,144,156, 51,110,143, 29,227, 46,202, 65,234, 60, 42,170,104, 47, 86,113, 60,228,213, 97,156, 18,122, 79,178,106, 35, 3, 65, -129, 34, 33,142,156,232, 56,161,246, 57,135,113,218, 11,192,137, 29, 91,140,130, 99, 14,180, 78, 57, 34,123, 37, 79,187, 33,132, -198,245, 83, 65, 43,171,117, 70, 10,152,106, 93, 46, 7, 25, 85,119, 50, 53,220,182,103, 4, 76,212,100,105, 90, 28,139,139,118, - 8, 22,218,227,204,139,222,128, 46,227, 99,158,185, 82,168,215,142,113,154,176, 44,171,113,222, 55,209, 48,117, 69, 20,177, 58, -183, 89, 35, 55,245, 59, 15,123,138,169,134, 97,100, 62,192, 30,211,110,162, 56,118, 91,109,149, 92, 54,252, 54,255, 89,114,161, - 48, 84,163,151,131, 81,244, 58,191,158, 92, 10,157, 27,138,148,173,182, 87,215, 34, 35,120,103,197, 38,232,100,104,198,160, 15, -182,154,139, 73,244, 75, 10,128,210,229,179,142,131,197,122, 12,211, 53,152,159,221,116,116,130,133,173, 68, 42,131,235, 79,253, - 79,235, 13,203, 44, 83,201, 94,149,109, 32, 14,134,202,128,150, 86, 56,169, 68, 59, 25,181, 83,152,215, 27, 47,120,216, 68, 77, - 99, 78,213,134,104,137,110,253,212,180,227, 78, 52, 89,145,133, 70,132,243, 58, 53,168, 22,227,171,187,113,168,167,222,144,189, -141, 83,140,106,231,181,114,223,183, 76,138, 13, 2,102,158,247,154,225,124, 66,213, 7,146,214, 59,177, 71,119, 91, 55,162, 3, -181,101,196, 56,160,212,130,105,218,177, 24,149, 21,161, 22, 4, 90, 92,169,205, 88, 27, 39,160, 35,138,127, 84,204,242,174,122, -123, 65,243,186,114, 52,230, 13, 17,106,244,185, 92, 49,237, 70, 30,212, 50, 38, 73,227, 32, 30,246,210,159,203, 17, 94,150,194, - 49,210,214, 77,203, 8,103, 11, 82,105,181, 98,156, 6, 19,214,213,218, 16,180,186,230, 72,169,208, 58, 22,210,102, 75,208,135, - 82,199,172, 41, 5, 19,186,182, 38, 54,163,202,188,221, 24, 60, 86,238,184,101,132, 38, 97, 47,170, 46, 92, 87,241, 11, 31, 15, - 2,123, 24,167, 68,241, 71,197,237,141,132, 90, 28, 15,179, 1,248,165, 32, 88, 36,154,243,246, 96, 85,109,175,109, 3,159,168, - 10,149, 95, 95, 45, 43, 59, 15,193, 26, 74, 72,140,131, 75, 17, 14,241,185, 29,138,142,177, 28,228,130,139,195, 32,225, 46,232, -240, 81, 18,219,156, 3,198,105,194,180, 19,143,107,154,246, 38,102,107,204,149,247, 84, 40, 43,207,189,115,135,115, 92, 86, 3, -121, 4,247,188,229,167,210,154,215,106,135,243, 29, 53, 87,248,152, 16,131,135, 75, 59, 12,251,123, 98,157,186,152,112,113, 57, -224, 39,127,246, 38,149,202, 91,114, 92,171, 32,177,170,211,239,222,101, 15,152, 11, 74,213, 41,138,231,222,211, 33, 13,145,209, -140,162, 28,151,112,182, 66,145,163, 82,225, 68, 12,165, 44,127,197,139,118,125,137, 84,161,170,249, 4,181,113,135, 11,140, 19, - 97, 39, 10, 46, 33, 63, 64,210,243, 26,253,229,210,181, 40, 99,161,181,138, 20,147,249,215, 85, 1,237,106,195,124, 56, 34, 13, - 50,102,214, 66, 47,175,235,137,122,181,162,151,134,155,242, 12,111,190,245, 19,124, 33, 14,120,112,231, 10, 45, 5, 92,135, 14, -220,125, 9,183, 31, 63, 66,115, 14,239,252,234, 33, 30,221,174,248,227, 79,191,140,120,126, 6, 63,237, 68,213,142, 14,119,251, - 20,225,252, 28,213, 11,240,168,174, 25,136, 17,249,233, 51,148,121, 70,115, 30, 8, 17,174, 85, 75,144,234, 0,134,216, 49,157, - 37,212,181, 32,103,135,253,110,192,218, 42,150,165, 0,203,130, 94, 87,244,203, 59,242,235,215,140,101,205,240,113,192,211,199, - 31, 99,119, 22,141,206, 88, 74,145,116, 48,205, 74,112, 29,232,242,189,170,203,100,154, 6,160,123, 83,253,171, 27,193,105,150, -182,247,240, 97, 64, 41, 71,225,251,119,135,158,169,222,101, 58, 70,136, 3, 74,158, 57, 46,174, 28,195, 31,205,218,104,214, 32, - 11, 47, 2, 45, 67,140, 68,205, 21,158, 44,241,231, 60, 75, 60, 92,209,221,150, 31,174, 20, 70, 42,188,101,183,235, 73,139,148, -194,180, 50, 83,161, 18, 62,227,253, 38,186,117,206, 83, 48, 9, 54, 13,133,211,197,128,188, 30,105,237, 18,139,129,119,226, 85, -239,173,210, 83,158,176, 63,219, 99,183,219, 75,183,219,186,105, 78,138,129,152,154,177, 14,150,101, 69, 46,121,211,135,152,150, -201, 91,110,121, 37, 95, 99,165, 5, 78,199,189,243,124,220,166, 25,238,212,131, 46, 99,253,214,177, 21,210, 4,208, 12,195, 96, - 28, 11,109, 40, 24,148, 72,224, 13,185,242, 77,196, 99, 41, 5,227,147,119,178, 67,250,218, 45,107,221,185, 19,180,172,158,103, -164, 61,138,210,189,161,243,231,168,147,135, 86, 87, 99, 19, 40,144, 76,133,212, 10, 98, 17,118,187, 59, 81,188,243,248, 33,191, - 66,187,114, 71, 47,184,218,209, 0,143,144, 6, 3, 87, 9,164,140,162, 96,120,132, 86, 12,252,163, 35,251,205, 53,195, 20, 62, -213, 79,212,106, 96,173,126,234, 97,103, 17, 9,167,119,129,219, 80,213,240,155, 61,178, 59,251,124, 59,164, 48, 52,193,107, 41, -116,107,100,106, 32, 2, 80, 65,219,163, 51,244,178, 57, 20, 12,122,212, 17,197, 95,205,174, 50, 54,162, 20,193,177,148,254,230, -134, 86, 57,102, 11, 50,134,214,143, 82, 2, 31,100, 28,186,180,213, 64, 20,219, 15, 85,170,140,218,128, 97,216,196, 1, 49, 58, -126, 65,221, 68,112,195, 32,157, 93, 28,156, 9, 96,212, 58, 34,255,191, 84,211,112, 13,174, 73, 36,170,238,146, 4,132,176, 81, -171, 98, 10,100,239, 74, 87,218,122,195, 56, 38, 75,157,219,159, 77, 88,103,249,192,106,149, 46,124, 93,139, 89,145,228,114,163, -138,116, 89,208, 90,177,203, 66, 71, 90,183, 55, 7,219,171,233,133, 84,233, 6,232,156,114,232, 4,192, 51,176,197,178,156,187, -170, 41,183,177,186,170,105,123,111,244,150,203,222,112,140,145, 15,113,178,135,221, 71,143,253,217, 57,210,144, 48, 78, 59, 62, -200,129,196, 39,103, 29,130,190, 56,178,195, 17,236,110, 94,102,180,186,152,136, 76, 70,252,167,124,129,106,149,185,143,201,192, - 16,206, 7,156,223,251, 52,214,181,226,252,124,196,221,123,151,120,255,221,119,176,206,179, 92,222, 44,202, 90,109,188,208,169, -248,109,219,228,196, 66,139,224, 54,208,140, 78, 31, 32,118,181,117,153,181, 52,129, 66,169,117,207,174, 46, 10, 87,130,249,138, -109,215, 90,164, 75, 23, 63,185, 28,188, 57,103,203,110, 87,171,165, 71, 20,209,162, 3, 39, 65,193,242,190, 55,143,121, 67,164, -224, 9, 8,240, 67, 50,242,158, 67, 39, 14, 83,104, 87, 74, 91, 84, 76,176,254,188, 85,187,241,238,163,103,120,239,131,140,255, -244,247,207,224, 99, 5,174, 46,225,206, 46,177, 62,155,177, 54,224,189,199, 71,164,224,241,210,213,132,233,222,125,209,158,112, - 61,213, 47,174,208,198,189, 80,222,196, 39,136,118,156, 81,127,243, 27,132, 96, 16, 79,192, 69, 17,136, 6,199,148, 43, 15, 71, -251, 38,178,236,149,207,199, 17, 87, 83, 68,123,252, 16,241,222, 61,184,152,128, 34,127, 15,122, 70, 15, 9,207, 14, 43,206,206, - 34, 15, 84,210,196, 84, 27,211, 36,252,167,148,130,200,119,178,172, 11,174,215, 5,187,253,132, 24, 35,230,227,145, 43, 19,158, -110,112,204,107, 16,144,137,226, 73,199,113, 68, 8, 35,137,126,213, 58, 40,237,114,212,194,214,186,120,202, 43, 97, 28,165, 84, -203, 87, 47,185,129, 57,147, 39, 23,185, 51,117,118,224, 14,178, 80,101, 47,128,156,138, 33,116, 62, 39,193,212,218, 29, 27,177, - 78, 5,111, 34, 16, 13,178, 6,211, 41,160,141, 73,197,114, 41, 34,189, 17,190, 54,196, 88,177,142, 51, 74,185,230,249, 74,219, - 28,125,231, 49,142,152,166, 9,187,253,153, 97,176,213,117, 36,152,109, 25,107, 59, 47, 62,237,117, 37,110,181,202, 68,174, 51, - 20,166, 50,185, 81, 45,122,219, 74, 16,156,134, 20, 19,227,110,107,164,112,162, 93, 9,198, 45, 87, 17, 45,168, 73,201, 69,244, - 61,162,113, 58, 33,134, 14, 9,206, 5, 54, 78, 34,134,171, 44, 70,182, 60,143,102,123,245, 16, 3, 82, 79, 27, 98,183,107,158, -130,156, 65, 64, 23,156,176,126,214,181,114,245,152,233, 49,119,155, 85,152,206, 29, 15, 57,219,108,225, 76,175,190,103, 99, 42, - 82,128,109, 34,224, 57, 45, 82, 65,164, 68,230, 10,171,194, 71,209,129, 24,114, 38,146,213,223, 6,212,186,210, 58,167, 94,117, -177, 14,203, 93, 88, 72,105,151,245,133, 68,194,118,179, 32,154, 91, 76,119,238,142, 69, 0, 5,167, 27, 27,126,107, 46, 58,215, - 43,157, 2,197,101, 89, 57, 89,226, 29,160,228,205,225,164,216,206, 50, 25,215,203,255, 52, 48, 45, 90,154,153,177,211,171,236, - 99,205,255,185,165,199,117,133,130, 56,111,222, 72, 77,137,233, 93,132, 50,128,195,124, 92, 49,142, 9,243,178, 10,167,184, 73, - 88, 61,200, 52, 86, 66,145,122, 33,107,107,152,166,145, 20,177,102,222, 59,185,128, 61, 21,171, 2, 34, 8, 76,126,106,173,193, - 87, 25,129,245,190,229,103,167,129,112, 11, 66,114,164,218,238,232, 77,188, 83, 34, 68,147, 2, 64,193, 55,135,219,163, 76, 1, - 98,192, 58, 47,232, 97, 75, 48,107,173, 11, 97,173,111, 97, 30,189,119,204,199,213, 14,128,154, 11,161, 45,236, 26,213,226,193, - 67, 37,240,229,170,154, 78,232, 3,125,209,205, 42, 84,137,255,219,144,163,222,109,161, 16,162,125,138,104,165, 34, 80,151, 48, - 77,131,248, 84, 9,173,112,124, 75, 29, 54,178,157,128,119,188,141,143,123,235,162,136,173,197,252,168,189, 53,185,184,217,137, -117, 84,243,158,106,133, 29,147,124, 61, 62,237,145,246, 47, 32,120,135,179,179, 17,251,157,195,223,188,245, 38, 97, 45,204, 64, -142, 17,235,146, 81, 74,197, 48, 73,166,120, 8, 78,246,103, 93,189,252,234, 63,175, 40,153,234, 97, 86,245,121, 61, 73,148, 58, -205, 37, 86,223, 48, 3,165,165, 67,231,200,189, 86, 50,179, 55, 76,175,162,109,119,187, 29,114, 41,228,124,147, 56,150, 43,188, - 69, 82,202,165, 21, 67, 64,227, 8, 56, 14,113,139,202,244,114,112, 28,111,111,205,238,148, 41,250,105,204,111, 86, 15,109,224, - 8, 76,196,126, 64, 28, 68,169,253,228,151,215,248,250,171, 47, 99,246, 1, 57, 78,112, 45, 96,184,185, 65, 15,226,133,159, 82, -192,241,184,162,246,142,101,201,200,243,140, 86, 50, 14,207,110,112,221, 60, 94,124, 81,136,105,205,121,244,245,136,254,254, 47, -224,123,177,213,150,186, 58,162, 87, 66, 96, 64,184,220,161, 92,223,152, 72,232,152, 27, 11,157,128,225,229, 87, 16,247,123, 75, -223, 42,237, 8,112,130, 49,207, 25,227, 62,144,245, 79,101, 56,187,146,234,156, 36, 93,161, 97,173,171, 93, 72,206,117, 44,243, -140, 54, 12,240, 14, 56, 30,212, 74, 40,251,194, 56, 4, 90, 17,121,126, 0, 70,169, 84,188,114,173,178, 2, 89,151,133, 77,128, - 88,191,114, 23,194, 91, 39, 9, 38,156,128,178, 90, 7, 90, 46,150,254,165,221,178, 42,192, 55,161, 90,160,173, 76,126,191,132, - 62, 21, 76,123, 15, 31,129, 50, 23,248, 24,249,253,116,172,235,102,229,148,149,141, 71, 41, 43,179, 38,202,115,152, 99, 64, 68, -170,126, 12,200,235,140, 97,220, 83,164,182,156, 8,157, 26,134, 65,112,180,103,231, 23,194,105, 63,205, 35,128, 80,229,212, 22, - 38,239,106, 51,161,159,194, 93, 2,137,107,150,212, 70,171,220,225,150,159, 25, 19, 39,107,115, 88, 41, 44, 4, 9,120, 82,160, -121,120,159,236, 66,145,117, 7,167,158, 67, 98,135, 46, 83,166, 49, 70,134,196, 4,140,211,200,181,134,112, 47,244,140, 26,167, -209,254,252, 82, 10,208,168, 70, 15, 30,190,138,182,162,150,138,228, 3,121,240, 21,165, 22, 75,139,243,102,155,109, 40,235, 2, -244, 98, 98, 55, 5,113,121,167, 43, 67,103,130,176,198,201,171,118,227,114,161,111,147, 25, 69,140,147,182, 33,207,182,134,189, -116,106,100,168, 15,210,108,151,222, 10,124,100,156,244,113,165, 59,198,111,164, 79,234,167, 36, 30, 53,160,180,110, 60, 3,249, -187,170,116,222,108,218,156, 89,184,101, 69,208,153,176,102,105,123, 44,250, 55,106,109,103, 3,188, 26,137,180,214,138,101,153, -217, 4, 39, 11,233,241, 20,154,107,232,148,211,209, 0,179, 54, 34,200,254,245,220,235, 8,223, 90, 50, 98, 91,238, 20, 91,121, -178,214,229, 33,146,196,159, 70, 90, 16,204,179, 30,200,207,214, 48,149,148, 18,188,243, 66, 49,170, 13,235,186, 98,208,248, 83, - 10, 4,206,206, 6,179, 61, 84,190,240, 58,234, 82,248, 76,136, 98, 83,147,138,180,216, 7,162,163, 51,231, 9,183,161,119, 60, - 4, 17,240, 69, 23,176,178, 74, 28, 70,185,248,114,145,252,220,186,200,165, 26, 83,192,157,187,151,112,174,227,201,227,107, 90, -211, 10,213,193, 30,173,174, 8, 94, 60,203, 2,103, 1,179,220,101,151,191, 44, 11,122, 8, 72,105,176, 7, 60,132, 77,221, 47, -187,121,152,186, 85, 59,237, 86,189, 21,156, 64, 35,141,200, 26,249,226, 88, 0, 0, 32, 0, 73, 68, 65, 84,109,227,225, 24,128, - 70,216,149,170, 48,185, 83, 30,167, 17,105, 72, 34,178,225, 47, 8,244,121, 91, 92,110,221,208,177, 90, 33,175,121,177,148, 53, -199, 61, 79, 59, 69,115,118,241,133,138,218, 55, 81,212,232,204,247, 59, 93,125,130, 16,150,136,187,247,175,240,222,219,111,226, -246,250,153,117, 28, 37, 23, 11,187, 8,222, 97,157, 15,178,155, 59,137, 77,236,246,119, 87,227, 36,195,121,234, 11, 50,139,174, - 98,118, 53, 61, 64, 85,146, 37, 35,210,184,209,149,188,116, 15, 10, 6, 81,230,127, 28, 71, 43, 58,199, 81, 52, 26,228,240,200, -158, 46, 70, 68,230, 29, 59, 30,108, 91, 55,228,108, 63, 85, 9, 18,242,222, 97,237, 13,189, 70, 94,244,180, 24,149, 44,123,176, - 90,144,210,192,159, 97,160,123, 99,198,199,239, 31,240,245,215, 94,197,203,111,188, 6,255,226,203,192,178,202,232,219,121,185, - 8, 91,199,211,219, 5, 41,120,228,219, 3, 60, 83,174,150, 53,227, 47,223,254, 16,223,254,225,207,240,223,253,243,127, 36,130, -194, 86,177,254,230, 3,248,227, 12,151, 0,248,200,208,137,142, 66,112, 78,109, 29,195,254, 28,238,193,171, 64,126, 31,235,245, - 17, 62, 38, 60,165, 35,229,165, 87, 94, 64, 79,137,147,153, 6, 31, 7,233, 54, 0, 44,115,198,245,237,130,179,125,183,239, 89, - 52, 26,213,224, 33,181,139,104, 22,168,134,243,212,189,182, 94, 80,243,113,193, 48, 80,208, 24, 35,214,121,181, 95,187, 28, 15, -242,231,122,143,188, 74, 17,144,131,184, 9, 74, 94,140, 46,214, 90,160,163, 97, 36,104, 67, 68, 69,114,209,110, 98,218,198,174, -212,135,190, 89,217,136, 25, 22,113,221, 32,221,103, 20,193,104, 72, 56,217,241,118,179, 49,169,110,165, 86,105, 16,114,150,231, - 32,165, 36,246, 92, 98, 71,117,237,163,234,229,245,184, 98, 10, 1,165,138,215,120,154,118,168, 53,227,233,227,153,123,126,121, -184,134,113,135,253,254, 12,103, 23,231,212, 48,129,152,104,153, 44, 42,146, 84,199,173,173,111, 64, 44,121, 46,219, 38, 66, 85, -146, 25,128,195,141,228,210,235, 8, 33,231,202,125,117,216,146,228, 98,226,101,189,193, 87, 20, 60, 35, 74,113, 2, 78, 92, 64, - 26, 7,158, 97, 81, 82, 2,121, 81, 6, 10,201,160,174, 5, 78, 75, 68, 64, 11, 19, 90,151,210,158, 11, 97, 10,222, 99,158, 23, - 34, 98, 87,163, 71, 10,191,188,160,215,138,146,103,123,142,184, 54,151,100, 75,134,165,200, 5,201,220,134, 46,169,151, 58, 9, -113,180, 0, 75, 58,166,179,201, 85,239,155, 91, 71,211, 21, 85,175,238, 67,132,227,228, 49,196,136,178,102,248,148,184, 18, 85, - 30,129,183, 8, 95, 37, 28,202,138, 47,152,208, 78,179,228, 69,136,183,185,193,244,159,206, 5,254,247,102, 44, 7,241,175, 7, - 54, 43,167,170,251,126,130,218, 85,184,150,183,233,109,109, 21, 81, 39, 95, 85,177,236,218,120, 21,226,180, 43, 82,140, 28, 94, -241,224, 23,146, 92, 18,197, 40,171,104, 31, 58,163, 37, 55, 85,166, 1,212,232, 53, 85,171,212,198,201, 15, 6,246,112,222,139, - 39, 49,203,203,151,215,204, 81,143,228, 78, 47,203,138,148, 18, 85,227, 17, 46,120,219, 73, 86,122,193,243, 90,120,240, 87,192, -117, 12, 41,146,189, 94,177,219, 15, 38,218, 59,222, 46,136,105,203,189,213, 56,207,200,238, 94,242,212,163, 20, 6,206,225,252, -226, 12,243, 44,233,106,243,241, 40,164, 48, 66,250, 59,197, 28, 25,157,170,223,108, 49,138, 58,154, 87,116, 32,152,199, 45, 5, -205, 96, 69, 16, 76, 49, 41, 63, 47, 29, 41,201,248,100, 35, 81, 5, 31,208,181,146,118, 32,206,208, 33,142,193, 20,222,158, 23, -244, 48, 37,140, 67, 18, 2,149, 35,213,200, 75,225,164,157,172,173, 35,214, 85,246,209,190, 99, 57, 30,101,236,222, 42, 71,202, -219, 88, 91, 20,195,178,163,212,125, 77, 43,154,137, 44, 35, 65,132, 9,227,249,125,212,218,112,118, 62, 33,250,140,119,127,252, - 35, 99,198,151,117, 38,101,140, 59, 83,122,110, 37, 39,185,155,197, 69,242,170, 87,196,152,144,215, 89, 34, 3,153,182,134, 16, -104,249, 32,185,137, 72,216,196, 78,204,249, 64,213,174, 50,145,189, 41,222,189,217,104,128,144, 6,235, 8,163, 30, 56, 44,137, - 69,232,179,219,172,155,220,165,107, 17,145, 43, 61,214,174,217,244, 5, 68,109,206,237, 22,227, 56, 89,215,163, 7,164, 56, 42, -146,237, 16,215, 85, 58,158,103,143, 22,188,122,231,101,188,244, 59, 95, 2,246, 59,100,120,184, 16, 16,210, 30, 46, 38,204, 43, -173,120, 73,220, 5, 79,110, 23,219, 9,250,105,194,107,159,124,128,223,207, 29, 88,142,232, 45,160, 35,192,173, 51,252,160,238, -128, 66,237, 9,237, 54,228,153,247,204,169, 72,147,131,165,118,224,167,143, 14, 24,135,132, 23, 38,143,128, 14, 87, 51,194, 52, -193, 59, 96, 72, 30,115, 76, 72,195,128,227,188,224,140,226,201,188,102, 84,118, 95,146, 52,213,205,142, 36,140,132,198,125,167, - 55, 38, 1,136, 87,213,181,157,121,112, 25,203,234, 67,192,202,136,223,117,145, 68, 68,231,129,117,174, 36,243, 9, 26, 86,133, - 85,165,108, 98, 52, 40,178,217,117,227,168,251, 32,130,167,198,115,137,170, 33,187,172,115,206, 86,244, 67,227, 78,163, 88,214, -116, 10,217,185,203,244, 81, 70,170,135,195, 34,239, 55, 5, 99,222, 59, 44,115, 53,152, 85,240,219,184, 83, 44,177, 51,166,105, - 39, 9,151, 41, 98,191, 63,195,186, 28,113, 56, 60, 3, 0,140,227,132,253,254, 12, 23, 87,151, 38,136,211,181, 92, 12,209, 64, - 50,250,174,136,230, 70,211,191,152, 5,193,162, 61,166, 68,152, 75,198,241, 56, 91, 51,164,236,134, 82, 86,251,218,228,207,141, -220,165, 71, 68,238,146,193,159,133,126, 45,206,123, 68, 42,172,135, 81, 8,119,167, 9,135, 33,198, 19,219,164, 92,112, 67, 10, -108, 14, 69,196, 42, 93,172,186,158,154, 9,248, 42, 5,175,130,132, 22,197,124, 94,142,146,102, 88, 50, 58,177,192, 65,228,238, -155,158, 8, 85, 66, 98, 56, 77,210, 29,178,212,142,142,140,130, 13,201,235, 44, 50, 74, 82,249,108,253, 81, 53,198,186, 24,158, -213,199,128, 97,220, 25, 80,103,152, 38,251,181,158,216,214,231, 66,172,160, 54,181, 45, 70,186,107,116, 43,163, 87,181,104, 56, - 45, 0,236,130,199, 70, 28, 52,218,160, 66,188, 26,172, 0,232, 39,147, 6,243,204,119,157, 58, 57,158, 71,222,180, 63, 33,108, -221,186,231,212,217, 57,143, 40, 66,133,110, 25,192,190, 87,172,185, 82, 21,232, 56,106,207, 39,182, 16, 37,217,176, 74, 96,119, -229, 84,176,196,111,192,187, 96, 57,188, 74,134,242, 1, 54, 94, 81,175,186,238,129, 20, 16, 2, 42,163, 83, 74,194, 23,230, 94, - 71,132,117,219,174, 75, 85,224,122,129,245,222,108,181, 86,153,104, 20,130, 99,198,239,182, 70,104,205, 89, 58, 91,239, 29,169, - 5, 28,111, 86,226, 93, 11, 5, 48, 29, 55,215, 55,172, 4,133,103,157,115, 49,101,234,186, 40, 82,148, 34, 32, 22, 48, 30,120, - 46, 97,201, 57, 37,240,117,219, 55, 13, 41, 26, 72,192, 49, 69,173,179,115,180,232, 64, 3, 82, 53, 83,116,150,218,176,219,143, - 84, 13,115,103,143,198, 48, 4,221,211,115, 92,221, 42,150, 89,146,175,188,151, 11,233,246,217, 19,174, 16, 4, 41,219, 91,101, -215,238, 76,149, 44,153,227,145, 2,168, 0,128, 47,116,235,216,221,253,180, 32, 67,199,136,123,247, 47,241,243,159,252, 0, 37, -175,204,115,119,112, 49,241,231,209, 79,188,172,162, 10, 13,209, 91,138,154,230,190,235,136,169,247,198, 60,106,190,140,221,115, - 50, 32,138,220, 13, 64, 20,141,118,232,177, 41,212,141,217,239,165, 35,225, 60, 78, 52, 27,124,225, 84,249, 30,211,176,173, 9, -194, 38,154, 3, 68, 65, 47, 22,194,194,139,200, 1,173,161, 48, 49,175, 80,172,116,172, 5,195, 48,162,205,178,227, 87, 27,229, -178,244,147,110,160, 35, 23,143,158, 47,241,197,111,254, 14,252, 56,202, 1,218,128, 52, 77, 76,253,170,120,244,248, 86,138, 32, -122,175,127,254,243,143,240,141,175, 61,129, 59,191,128,115, 14,175, 62,184,194,203, 47, 94, 97,157, 23,120, 39,121, 2,254,238, - 93,244,103,143,209, 15,139,224,115, 1,140,209, 51,116,168, 35, 57, 15,148,134,118,115,139, 94, 43,226,221, 11, 44,211, 5, 62, - 60,190,141, 16, 60, 94,185,119,142,246,244, 49,194,197, 21,106,172,104,222,163,187,128, 30, 28,110,142, 29,143,159,221,224, 69, - 92, 80,187, 0,142,198,155, 65, 93, 42,187,177, 20,165, 51, 27,166,145, 83, 18, 94,178,116, 74,172,171, 96,153,165, 91, 79,104, -181, 32,141, 35,128, 70, 23,200, 22,239, 41,232,231,100,151, 12, 36,244,140,207, 96,181,142, 5,236, 96,251, 73,106, 94,169, 5, -105,156,224, 3, 51, 5,216, 69,233,197, 37, 7, 57, 15, 99,238,247, 5,231,186, 57, 5, 34,167,110,189, 50, 84, 6, 27, 38, 57, - 37, 17,116,169, 32, 75,131, 60,204,121,209, 36,199,193,251, 64,175,189,140, 67,167,221, 25, 74, 94, 81,234,138, 97,148, 61,186, -247,222, 48,194, 62, 68,218,113, 71, 22, 47,197, 46, 19,231, 61,208, 68,219,164,207,116,109,221, 62,163,170, 60, 12,102,150, 43, - 13,113, 93, 23, 35, 48,234,101,174,251,219, 16,146,137, 12, 1,135,105, 26, 40, 88, 21,254,250, 48,136, 5,118, 24, 73,227, 12, - 50,181, 21, 16,152, 55,173, 72, 96,206,133,144, 52, 59, 71,254,178, 90,148, 21,192, 54,233,210,168,234,214, 43, 27,183,133, 19, -142, 32, 95,119,145,156,133,192,241, 56,168,124, 23,112, 76, 55, 18,164,196,255, 54,152,168,219, 57,106, 44,194,230, 25,247,155, -172, 66,217, 20,170, 18,223,198,241,160,118, 38, 89,172,179,106, 38, 78, 69,107,122,246, 74,151,236, 45,119,189,243, 60,217,184, -236,221,172,219, 22,211,234,157, 5,113,105,130,250,115,220,120,203, 35,104,112, 62, 73, 20, 12,207,237, 70, 78,139,247, 17, 13, -197,186,120,231, 52,238, 87,108,225,170, 85,171,181, 91,252,118, 87, 3, 76,111,136,173,109, 29,118,175, 29, 69,129, 50, 53,195, -117, 66, 17,152,182,182,174,217,184,190, 10, 32,208,180,170, 90, 26, 47,109, 7,201,126,103, 62, 53, 47,100,197,220,117,219, 47, - 87,184,193, 51, 68,192,243,101,237,182,167,108, 93,196, 54,109,229, 55,221,181,210,151, 15,168,201,111,147,140,116,150,232,145, - 29, 79, 94, 11,118,103,145,246, 42,111,168, 89,181, 75, 1,162, 92,175, 28, 85, 45,139, 18,224,138,249,219, 99, 10,204, 33,102, -150, 56,111, 90, 85,230,162,117,219, 77, 57, 64,118, 60,158,182, 17, 45,144, 20, 11, 25, 37, 68, 6, 65, 80,126,138,137, 45,165, - 32, 48,154,181, 41,218,211, 65, 4, 78, 94,178,197, 83,146, 47, 56,141, 73,148,242,189,161,148, 5,193, 71, 98,122, 43, 2, 21, -246,138, 92,172, 69,188,189,206,129,223,219, 1,228, 94,200,131,210, 96, 35, 68,157, 28,120,175,213, 34,137, 97,105,144,206,208, -121,196,221, 11, 72,103, 47,194, 59,224,234,206, 25, 98,200,248,205,207,223,230, 67, 4, 94,204, 20,146,148, 66,143,184,208,219, -164, 88,113,182, 98,144, 76,112,165,250, 17, 85,203,188,108, 9,193, 73,219, 10,161, 53,171, 76, 79,131,130,122,239,116, 98,200, -190, 30, 78, 34, 32, 59, 39, 54,206,188,165,242,191,249,184, 97, 63,245,251,116, 54,114, 85,170,220, 74,201,170,188,112,226,102, - 40,180,178,116, 75,150,130,243, 88,151,102,221,253,178, 44,219,216,222,235, 5, 18,112,253, 40,224,239,127,243,247, 4,122, 20, - 2, 92,111,168,101, 97, 88,144,195,188, 44,248,179,239,191, 9,133,131,123,239,241,203,223, 94,227,248,236, 6,187,105,148, 92, -119,186, 50,128,142,114,115,131,190,204,200, 31,124, 0,248, 0, 87, 42,133, 56, 29,107,237, 24, 61, 53, 8,154,152,117,156, 49, -125,238, 13,248,221,132, 31,124,231, 77,212, 14, 12, 41,226, 19,191,251, 57,132,203, 61, 16,100,140, 92,214,140, 86, 37,194,248, -250,120,131,181, 44,200,101,130,207, 78, 60,239,218, 1,195, 89, 55,182,121,177,229,179,179, 41,140, 33,211,194, 9,154,147,251, - 66,105, 43, 56,174,141, 92,115,201,217,146, 73, 73,243, 33, 26, 51,219, 57,111,133,161,115,162, 65, 9, 49,160,173,213, 84,217, -185,213,109, 34,208,157,132,187, 48, 93,175,219,243, 35,121, 15,202,203,214,139, 77,237,110,195,176,237,232,157,247,104, 37, 83, -217, 47,226,209,198, 88,100, 69, 19,215,162, 25, 18, 30, 61, 55, 19,105, 30, 15, 7, 92,221,185,195,181,219,128, 28, 87, 76,187, - 51,180, 54,224,236,252,130, 34,204, 96, 19,162,222,157,141,225,117, 84,172,211,192,117,201,156,222, 84,243,208, 55,142,233, 15, -183, 51,214, 92, 12, 2, 86,171, 76,169, 50, 81,176,142,142, 37, 79, 22,123,136, 9,105, 72,240, 46,216, 69, 40,142,152, 38,226, -198,148, 12, 89,235,131, 76, 74,210, 16,217,217, 11,199,161,228,138,204,203, 58, 70,209, 44,121, 47,228, 76,160, 97, 94, 51,224, - 58,230,227, 81,206,117,231, 44,227, 99,229,100, 86,222,167,106,239,145,186, 16,212,237,163, 88, 99,199,192,156,238, 28,156, 50, - 36, 66,223,210,245,200, 10,209, 40, 82,109, 46,123,231,165, 91, 79, 51, 48,164, 10,171, 6, 9,146,117,142,210, 38,211, 48, 80, - 4, 39,204, 14, 79,234,169, 93,226,132, 36,169,223, 92,160, 73,141,252,170,211,112,171,254, 92,247,173, 54, 32,239, 2,116,113, - 72, 58,199, 73,184, 21, 51,225,187,183, 4, 75, 45, 60,236, 50,167,243,199, 84,248,174, 99,158, 15, 76,188, 27,184,131,207, 54, -105, 81,225, 93,244, 54,122, 23,251,202, 48,141, 84,160, 75,114, 82,140,226, 95,238,173, 81,177, 9,190,144,218,221,121,120, 38, - 31, 41, 10, 79,255,125,235, 64,173, 14,105, 8, 28,219,108, 1, 13,173,117,233, 64, 72,121, 26,134,168, 42,127,169,142,107, 39, - 45,174,218,139,172,135,166, 38,197,213, 69,254, 30, 87,156,253,125,178,215,246,198,107,214,177, 95,229, 74,161,243,146, 62,222, -206,155, 32,171, 85, 6, 4,136,170, 28,189,161,172,178, 31, 86, 70,120, 91, 5, 46,163, 73,104,170, 18,239,167, 49,162, 58,246, -161, 82, 18,157,176,149, 38,123, 32,233,194, 59, 74,151,188,114,129,199,109,228, 36,157,190, 8, 76, 78, 30,242,154,133,194, 20, -131, 71, 26,130,140,154,233,217,172, 37, 19,119, 41,213, 95,240,226, 52, 80,254,118,205, 43,202, 50,147,227, 76, 0, 8,147,127, - 53,141,168,210,111,153, 56, 26,243, 33, 81,233,206,212,184, 56,226,234,229, 47,162, 54, 96,127, 57,226,238,253, 11,252,244,175, -191, 71,165,106, 19,255, 63,161, 50,153,161, 2, 26,166,208,171, 80,246,132,134, 36,246, 53,101, 33, 58, 78, 20,164,171, 78,128, -226, 42,153, 0,166,225, 47, 49,170, 81,203, 25,182, 52, 70,137,106,140, 62,108,168, 71, 34,126, 7, 83,169,107,148,163,179,130, -204,161, 33, 70, 66,120,208,129, 70,129, 35, 9, 86,162,110, 46, 28,101,174,214,137,128, 49,162,202,224,246, 70,225, 74, 38,164, - 25,134, 36,194,163,214,241,232,227,138, 47,125,254,139,120,229,181, 7, 40,243, 44, 22, 30, 39, 71,132,226,110,255,226, 47,222, -193,207,222,251,173,105,182, 99,111,120,122,155,241, 87,223,127, 11, 95,251,242,171,136, 47,221,151,200,221, 14,212,155, 3,240, -155,247, 17,122, 67,109,128,207, 69, 62, 63,239, 17, 18,215, 17,206, 35, 6, 57,208,251, 56, 34,125,226, 21, 52,239,112,115, 61, -227,207,127,252, 30, 98, 12,248,196,131, 43,156,159,203,216, 81, 97,250, 18,155,156, 16,207,207,112,243,211, 15, 48,164,104,103, -129,135,176, 13, 74,165,136,150,142, 22, 9,176,144,203,168, 46,213,214, 46, 27, 39, 66, 45, 87,242, 46,170,127,222, 19,246, 34, - 7,124, 70,107, 43,166,221,132, 14, 41, 62,133,255, 30,237,157,146,115, 66, 46, 94,193, 59,207, 82, 36, 54, 78, 3,201, 23, 55, - 71,137,121, 19,156,112,181,243, 44,127,191,238, 63,157,183,164, 73,213,229, 52, 69,117,118,152,146,188,179,155, 15, 1, 8,209, - 33, 31,138,193,160,182,221,113, 53,103,128, 82, 16,151,229,136,221,254, 12,232, 30,251,253, 30,193,123,248, 0,236,246, 98, 95, -243,126,115,101,140,187,105, 91, 93,114, 93,133, 34, 7,232, 56, 13, 40, 89, 64, 56,250,123,156, 83, 16, 87,182,207,106,158, 23, -230, 81, 44, 38, 52, 21,218, 88,226, 5,226,204,137, 80, 93,181,142,125, 24,101,213, 34,151,249,198,200, 71,239,216,237, 71,211, - 67,233, 69,234,188, 52, 45,165, 52,228,163,116,219,215,207,142, 6,142,169,181, 72, 56, 23, 69,184,193, 98, 97, 35,167, 94, 91, -156,106,111, 13,185,108, 34, 99, 43,114, 20,158,194, 70, 72, 5,103, 29,133,107, 10,143,214, 43,130, 11, 54, 33, 85,167, 15, 84, - 56,200, 34,221, 17,119, 13, 50,228, 37, 6, 91, 86,164,211,217, 37,179, 5, 28,163, 78, 43,139,127, 13,227,169,114, 95, 52, 90, -110,241,252,100, 70, 39, 29,142, 23,177,174,150,106,237, 34, 92, 85,115,123,239,164,204, 61, 63,154,215,187, 79, 87, 62, 50,153, -137, 0,167,185, 91, 1, 41,171, 37, 84,253,239, 13,142,103,144,234,190,148,208, 87, 74, 35,161, 81, 46,246,232,122, 19,225,129, - 99,215,205,195, 53,112,175, 42, 7, 93,197, 56, 73, 68, 94,201, 84,162, 71,226, 78,157, 67,173,126, 75,238,105,250,195,106, 4, - 70,200, 97, 63,142, 35,173,155,225,249, 49,189, 86,218, 76,128, 67,174,162, 94, 79, 1,153,130,180,224, 55,102,113,107, 2,140, -145, 8, 64,143,227, 49, 99, 28,101, 44, 5,250,151,229,128,245, 70,147, 26, 71, 9, 88,105,185, 96, 89, 86, 28, 15, 7,217,241, -179, 48,169, 57, 91,130, 84,201, 98, 81, 18, 76,102, 55, 53, 98, 39,191, 89, 70,201,110,203, 21,143,218,145, 83, 97,206,180,181, - 90, 42,134,193, 97, 93,178,140,186,155, 88,168,214,121,133,247,224,218, 66, 70, 41, 62,108,211, 4,101, 43,131,105, 71,195, 40, - 85,115, 26,162,225, 82,117,236, 23,130,162,111,165,184, 40,244,173,246, 38, 16,133,229,120, 96,199,228,184,131,118, 38,118,145, -206,181, 98, 72,147, 85,156,162, 8,149, 49,156,129, 25,134,187,112,195, 29,248,218,112,118,190,131,111,183,248,224,231,239,152, - 56,175, 45,178,183, 55,146, 26, 59,180,154, 87, 50,180, 69, 89,110, 38,118,118, 59,232,149,110,135,184,225, 21,109, 69, 34,227, -220, 24,189, 60,168,156,108,196, 52,112, 29,147,172,144, 82,246,186,217,246,156, 38,170, 37, 75,116,219,146,153, 40,214,227,184, - 82, 20,235, 84,220,215,188,101, 31,215, 76,221, 65, 55,171, 78, 34, 71,255,212,227,139,222, 48,142,227, 9,207,187, 97, 62,116, -164,114,134,207,126,234, 5,212,117,209,250,156,153,210,210, 37, 62,126,122,139,255,248,189, 55,101, 76,215, 58,134,224,240,223, -252,241, 23,240,191,125,231, 29,252,187, 31,255, 10,159,189,191,195,221,243, 61,112,117, 71,138,192,195, 13, 80, 42, 48,142, 24, -175, 46,208,142, 51,218,113, 69, 28,165,200,139, 67, 64,175,194, 7,240, 99, 66,250,228,107,112,204,138,255,187, 55,127,129,135, - 79, 15, 40,181,225,139,159,125, 0, 23, 19,124,175, 6,240,112, 46, 96,184, 56, 71,237, 29, 31,252,230, 17, 62,251,233, 87, 81, -251, 99,160, 74,135,164, 90, 24,225, 5, 84, 91,135,152,243,197,203,180,226,226,242,156,144, 20,254, 60,216, 69, 62,199,216,166, - 98, 61, 4,143, 74,148,112, 41,149, 23, 70,198,178,136, 39, 61,198,136,117, 93,105, 67,114,182,215, 86,224,139,163, 61, 84, 46, - 97,181,182, 58,218, 31,229, 18,247,209, 99,152,188,117, 66, 33, 6,212, 6,243,105, 59,174,233,210,232,133,128,217,229,235, 20, -203, 28,125,195,126,179,103,174, 89, 82, 12, 29, 17,197, 49, 6, 1, 98, 81,144, 39,142,152,163, 92,150, 65,198,216,206,203, 4, - 41, 4,103, 46,151,148, 34, 71,218,142, 14, 32, 7, 84,153, 8,148,156,145,198,100, 93,185,106, 75, 66,144, 70,105,153, 23, 91, - 31,109,239,146, 20,241,181,201,229, 36, 2, 53, 79, 66,154, 60,171,203,154, 49, 12, 9,195, 48, 98,156, 38,164, 52,112, 21, 34, - 86,220,152, 18,198, 73,247,233, 73,156, 66,156,154,138,165,183, 88,174,251,186,172,116,178,208,249,193,159,161, 93,240,165,162, - 58, 25,149, 47,243,108,240, 21, 79, 12,182,216,219, 58, 3, 85,156,173, 82,117, 90, 37,218,130,245, 36,167,222,157,196,155,246, -173, 97,169,213,166,162,114,142,202,132, 6,158, 57,232,100, 79,200, 58, 71,206,202,221,254,194, 70,240, 42,214,117, 0, 90,203, -230, 38, 16, 24, 76,149,105, 18, 33, 66,178, 14,177, 91,203, 28, 57, 50, 74,167, 69,205,235,162,157,161, 48,206,211,218,173, 13, - 73, 55, 24,141,131, 19, 76,173, 11, 38,166, 83, 82,161,138,252,132, 7,179,110,182,186,214,224, 66,148,142, 28, 10,213,146, 41, -151, 48, 52,152,149,225, 61, 98,229, 72, 81, 48,161, 30, 46,136,112,165,181,134,192, 12,110, 31,100,166,175, 30,116,221,179,234, - 56, 74, 8, 60, 14,109,110, 38,158,144,177,151,167,130,209,111,227,214, 78,101,164,146,148,186,238,173,202,137, 42,149,240, 26, -223,183,124,116,215, 57,174, 11, 40, 69, 70,218,243,177, 96,127, 54,178, 74,115, 38,126,209, 67,118, 24,252,166,140,102,100,146, -118,152,203,113, 62, 49,237,119,250,123, 29,230, 69,186,183, 82, 42, 43, 80,237, 72,155, 78, 64, 76, 36, 7,200,132, 66,172,126, -234, 57,231,232,175, 22, 34, 18,219, 22,120, 95, 10,119,138,133, 4,165, 78, 49, 76, 51, 70,180,122, 97,161,252, 98,205, 66,231, -223,229,221, 73, 82, 90,173,240,157,157, 16, 11, 10,181,169,101, 22, 92,157, 93,205, 48,122, 3,186,232,239,143, 12,243,208,203, -212, 7, 73, 10, 50,128, 10, 60,206,238,191,129, 90, 26,246,103, 3,238,189,120,129,119,126,240,239,165, 35, 45,153,187, 68,111, - 59, 34, 81,166,242,226,236,186,167,118,220, 1,121, 11,229, 64, 55, 11, 51, 17,186,222,246, 96,202, 54, 22,177,161,124, 94, 33, - 68, 3,131,216, 56,215,235,136,204,219,244,194, 83,180,225,135,141,196,167,187, 97,199,112,136, 90, 86,142,215, 42, 74,209,103, -160,146, 64,119,106, 67,113,246, 94, 32,240,197,118,222,184,241,137,151, 67,136,220,117, 51,174,245,246,105,197,183,190,254, 6, -198,216, 81,111, 30, 3,113,196,120,126, 97,246, 30,180,140,111,127,231,111,240,219, 71,215,102, 57, 42,181,227,234,108,196,223, -251,252, 3,252,139,255,248, 54,254,252,157,143,241, 15,239, 94, 74,145,229, 60, 92, 89, 49,220,189,196,238,149, 87,144, 99, 68, -155, 23,244, 52, 0,143, 62, 6,142,183,232, 49,194,237, 6,184,251, 47,194,143, 3,192,209,220,237,237,130,239,254,213, 47,208, - 1,140, 67,196, 23, 63,255,170,124, 14, 33, 34, 12, 1,173,103,189,190,208,225,240,244,201, 53,190,244,149,215,240,214, 47, 31, -113,212,183,200,196,134, 7,211,154, 89,144,214,138,222, 35,122, 43,232,193,145, 77,190, 96, 24, 7,138,185,154, 77,200, 58, 58, -227, 75, 97,106,248,249,120,144,179,160,214,109, 77, 69, 59,155,115,128,219, 57,179,178,118, 66,148,224, 60, 82, 26,248,220,119, - 11, 24,233,144,206, 74,246,171,178,142,242,129, 22,192,238, 17,124,180,240,164, 97, 8,166,250,150,226, 3, 22, 19,220,114, 59, -225, 40,248, 19,216,144,104, 82, 28, 96, 2, 52, 27,153, 86, 25,255,251,238, 25,226, 35, 14, 14, 9, 0, 74,184,184, 58, 63, 89, - 91,200,249, 52,140, 35,243, 41,146,101, 44,196, 24, 81,242, 44,151, 61,188, 9,199, 10,227,162,123,151,145,124,161,134, 72,197, -153,226, 42,170,198,202, 16,226,163,114, 37,136,128,109, 98,167,219,237,247, 24, 39,241,201,135,152, 4, 84,147, 51,198,105, 36, - 51, 32,156,164,211, 53,148,220,120,161,175,146,235, 78,255,123,111,186,251,173, 12,103,145, 2, 57,175,153,225, 79, 2,124, 58, - 28,142, 8,222,203,116, 37, 8, 83,162,209,142, 90, 40,146,211,219,140,122, 85,227,156, 11,237,173, 89, 4,179, 34,111,225,188, -129,166,100, 75,236, 24,186, 83, 41, 36,222,108,184,154,207, 46,226,229, 29,210,160,232,236, 77, 65,174, 2, 52, 93, 23,128, 26, -141,118,162, 84,119, 94, 26, 6,237,214, 37, 47,194,155,232, 87,245,246, 50,197,225,180,248, 36,205, 82, 52,105, 39, 25, 40,236, -206,133, 93,208,100, 91,228, 20,157,171, 97, 49,242,123,106, 43,136,113,148,203,157,231,126, 46, 43,134, 97,162, 11, 68,112,215, - 18,120, 84, 41, 8,236,136,211,126,111, 8, 70,169, 14, 68,241, 59,237, 70,212,186,193,251,117, 28,166,220,118, 37,199,137,224, -204,157,240,131,163,197,176,250,230,249,226,117, 19, 72,169,208, 64, 5,108,178,255,109,150,175,155,213,111, 87,165, 26,143, 12, - 47,200,107,165,101,163, 73, 78,251, 34, 23,199,241,152,205, 62, 97, 99, 15,170, 84,199, 49,114, 95, 75, 6, 47, 36,148,101,156, - 18,106, 73,104,213,155, 31,178, 86,142,214,209, 33,192, 32,103, 56, 90,201,158,119,152,231,197,112,164,162, 92, 36,254,149,226, - 20,245, 54,107,138, 79,163,160, 67, 42,173, 76,143,181,140,222,165,138, 84,253, 2,184, 91, 92, 17,169,244,244, 65,198,116,145, -194, 20, 29,173,201,231, 73, 50,104,136,176, 53,234, 56,200,215,223, 42,187, 13,142, 98,125, 55,204,173, 50,148, 45, 93, 73,145, -154, 33, 48,217, 77, 60,245,181,118, 9,131,153,238,163,226, 12,206,117,156, 95,236,113,124,250, 17, 30,127,248, 43, 1, 76, 48, - 0,166,214,186, 97, 81, 21,196,172,176, 7,136, 31, 85,212,234,133,161, 52,167,153,238,196, 94,178,144, 83,177,164,248,248,171, - 8,210,204,103,235,140,126, 21,153, 34, 40, 23,188,252, 12, 67,140,132,201, 68,122, 82, 97,187, 85,215, 43, 65, 30,149,171,149, - 21,181,172, 40,153, 94,222,214, 81,212,227,172,151,118,154,136, 63,222,152,223, 29,206, 98, 26,149, 21,239, 29,217, 2,112,120, -242, 48,227,171,159,123, 3,175,191,114, 9, 31,128, 60,238, 81,253,136, 56, 36,187,192, 62,250,232, 26,223,255,209,187, 82, 64, -215,138, 94, 43, 14,185, 32, 31, 14,248,189,207,188,128,127,251,163, 17,255,238,239, 62,194, 11,251, 17,191,251,153, 35,250,197, - 30,253,206,125,196, 59,231,104, 44, 12,252,217,185, 36,178, 5, 7,196, 8,119,255, 1,194,249, 5,124,244, 72,193,163,176, 51, -248,211, 31,188,139, 15, 63,190,134,243, 14,159,126,229, 46, 94,188,119,137, 94, 10, 48, 36,204,135,133, 29,144,140,215,231,249, -136,103,207, 14,184,119,239, 14,218,207,219,134,163, 12,160,213,170, 24,193, 49,232, 74,137, 5,103, 45, 21,227,180,229, 41,228, -156,177,219,237,182, 40,206,147, 9,147,228,207, 15, 88,230, 3, 61,225, 51, 66,216,157,228, 5,204, 22,198, 33,214, 81,141,103, -246,204, 45,168, 20,222, 10,195, 28,212,150,168,251,196,249,184,157, 97,211,206,166, 5,165, 86,218,186,100,250,151,115,179, 8, -103, 89,231,101,114, 28, 68, 36, 28, 57,120, 85, 92,168,178, 49, 84, 67,227, 24, 11,173,239, 66,229,249, 57, 31,143,152,118, 19, - 82,218,227,236,252, 92, 20,237, 76,213,146, 46, 61,217,243, 44,190,113, 9, 91,114,222, 99, 8,129, 56, 80, 89, 51,138,235,166, - 96, 62, 30, 45, 47, 91,221, 64,235, 42, 35,120,229,188,139,248, 75, 46,116, 13,113, 42,165, 98,127,182, 71, 76, 35,166,157, 92, -232, 29, 78, 38, 14, 94,220, 63, 66, 0, 28,204,246, 53, 31, 23,115,148,172,107,198, 45, 25, 30,153,194, 60,205, 57,208,226,119, - 93, 87,148,188,178,147,150,162,119, 89,229,217,210,127,102,114, 62,180, 96,232, 22,207,123,130, 60,213,115,181,109,211, 29,157, -236,168,184, 44,192, 61,135, 9,215,105,218,105,228,177, 94,218, 14, 64, 28, 39,122,237, 71, 22,229, 48, 11,176, 22, 71,186,138, -172, 85,128, 63,121, 93,184, 51,239,128,219,154, 87, 89,225,200, 63, 79, 57, 30,138,105,214, 53,144,142,219,197, 89,227, 21,130, - 7,205,109,235,246,164, 59,115,109,169,165, 82, 58,240,141, 22,232,157, 76, 45,156,247,228,205,119,190,139, 43,156, 19,177, 97, - 74,129,186, 40,191, 69,161,119,120,227, 93,151, 70, 95,104,223,124,227,150,124,229,229, 5, 23, 91,153, 67, 74,130,128,117, 74, -187, 9,178,227,170, 76, 68,242,188,112, 26, 65, 50,189, 59,100,142,195, 91,151, 95,191, 46,133, 98,187, 72, 28,106, 21, 97, 17, -167,165,235, 90,224, 73,110, 18, 43, 82, 64,206,242,226, 13, 99,218,136, 59,140, 3, 45,165, 97, 28, 2,179,122,189, 21, 34,133, - 66, 26,169,192, 28,197, 32, 3,242,178,176, 67,117,100,184,139,226,114,152, 18,242,202,204,229, 20, 49, 31,229,161,157,166,145, -248,220, 77, 89, 89,203,150,227,171, 80,148,218, 52,232, 3,132,156, 56, 11, 35, 80,155,148,176,207, 25,211, 23,228, 7, 38,185, -242,114,232, 76,187, 9, 41,146, 85,205,189,115, 55,150,177, 55,143,101,181,108, 93,249, 26,242,154,229, 80,163,157, 78,188,242, - 5, 49,137,130, 84, 4, 38,222,226,101, 53,189, 74,217,221, 62, 70,132, 36,163,163,241,206,167,209,152,173,253,194,189, 51,188, -245,189,239,152,144, 81,213,175, 10,143,240,126,115, 71,200, 51,145, 25,152,224,233,245,230, 14,191, 9,227, 89,198,138,209,178, -205,245, 65,118,188,220,225,196, 71,154,232, 15,246,118,225,122, 30,222,180, 8,186, 45,215, 60,198, 72, 47,181,132,241,232, 36, -166,183, 6, 71,174,115,111, 5,173, 74,142,124, 74,137, 19,162,141,222,148, 98, 2,188,130, 51, 50,162, 22, 20,250,156, 41,166, - 82, 45, 42, 85, 85,203, 1,231,195, 29,124,245, 83,151, 72,243, 45,250,221, 7,136,251, 51, 17,116,213, 46,120, 87,231,240,237, -111,255, 24,183, 7, 57, 8,255,233,215, 94,197,211,103, 51,254,239, 55, 63,196,245,245,130, 59, 83,196, 63,251,250,107,248, 31, -191,243,115,252,239, 63,254, 53,194,217,132, 47,125,234,147,162, 92,166,212,102,205, 21,111,189,249, 75,124,249,181, 61,166, 94, -225, 94,125, 13, 97,218,163, 66,196,164,203,154,209, 93,192,159,254,217, 91,248, 15,223,127, 7,206, 75, 17,244,205,111,124, 78, - 60,196,168,240,124,159,186,115, 88,142, 11,144, 59,150, 34, 29,105,138,170,127,225,180,206,156, 26, 26,158, 34, 63, 67, 15, 57, -180,208,186, 5,168,168, 11,193,169, 58,153, 7,105, 74, 17,199,227, 98,187,118,231,130,137, 11,107,150, 98, 58,141, 9, 46,175, - 18, 78,210,142,166,186,238,229,180, 83,151, 11, 62,151,133, 83, 18, 57,204, 53,139,188,163, 25, 24,165,201, 75,136,200, 78, 43, -210,129, 33,249,214,206, 34, 47, 59,247,253,122,192,250, 32,221,154,142,190, 51, 51, 25, 26,173,117, 53, 55, 25,157, 86,153, 44, -232,232, 93,180, 73, 29,203,124, 4,250, 29, 76,251, 9,251,179, 61,150, 69, 32, 61,121, 93,101,133, 73,145, 94,224, 94, 95,243, - 15, 44,160,200, 1,165, 74, 92,168,192, 71, 86,131,112, 9, 12, 75, 68,103, 57,103, 59, 75, 98, 76,180,123,146,151,193, 3,116, -154,118, 56, 59,191,192, 56,141, 44,108,154,137, 88,135, 97, 16,171, 40,243,212, 3,133,121, 57, 23, 89, 25,242,239,138, 76,171, - 43,156,154,229, 53,139,221, 49, 23,155,252,105,167,156,115,182, 14, 62,115,132,110, 60,246, 86, 49,207, 43, 5,113,206,166,114, -122, 73, 27, 92,135, 8,238, 83,225,165,103, 81, 45, 43,196, 96,107, 93,121,150, 54,251, 87,253,255,233,122,147,103, 91,178,243, -186,111,237, 46, 51,207,185,247,190,174, 58, 20, 88, 68,161, 33, 1, 82, 12,137, 22, 41,202, 38,105,133, 7, 30, 40, 60,176, 35, - 60,245,208,255,155,103, 14,207, 28,242, 64,161,144,108, 90, 38, 77,147, 4, 9,130, 68,145, 42, 20, 0,162,250,238, 53,247,222, -147,153,187,243,224, 91,223,183,243,210,225, 1, 2, 64,189, 87,175, 57, 39,115,239,175, 89,235,183, 88,184, 77,211,132,105,158, - 44,225,174, 59,200, 59,196,223, 79, 18,226, 26,249, 12,109,144,248,232, 36,176,110, 91,181, 83,125,136,249,164,176,108,104,189, -176, 41, 26, 92,248,238,250,129, 40,231, 44, 17,210, 49,188, 74,215,147,206, 41,116, 7,195, 54, 71,221,135, 2,147, 70,228,173, -116, 97,185,238,140, 94,237,214,145,135, 32, 43,141, 41,137, 24,184,100, 57,211,162,178,126, 69, 98,223, 45,208, 93,114,164,147, -229,148, 59,218, 14, 60,247, 31, 98, 73, 83,235,138,228, 80,203,206,202,219, 72, 69,227, 21, 21, 90,163, 81,129,222,115,204,222, -196,170, 85,155,140,172, 36, 60, 32,152, 48, 79, 41,103, 82,205,102,139,239, 3, 41,120,206, 7, 44, 41,202, 5,163,249,239,193, - 97, 62, 49,123, 59, 38, 10, 92, 60, 16, 58,106, 1,243,187, 69, 44, 87, 91, 55,225,219,216,179,192, 84,177,197, 59,134,219, 36, -193,228,170, 8,200,201,174, 92,198,208,237, 1,167,221,123, 80,244,231,135,154, 19, 13,101,247,104,173, 24,156, 68, 72,110,145, -161, 5,224,231, 47,224, 26, 13,125,240, 28, 77, 6, 79, 88, 72,235,140,185, 12,134, 27, 84, 46,126,201, 5,251,186, 49,108,198, -141,209,189, 87,177, 82, 51, 81,204,176,149,193, 70,214,114, 81, 10, 1,173,163, 34, 93,189,141,238, 79,240,189,227,241,211,107, - 92,158,127,140,231, 95,124, 66,199,152,224, 91,107,173,210,203,180, 6,159, 4,134,160,208,155,224, 3,242,190,201,180,130,227, -119,231, 28, 34,161, 24,145,244, 44,229, 64, 74,244,163,120,133,131,218, 52, 90,135,143,225,128,239, 4, 33, 28,222,108,145, 70, -153, 67,103,220,109, 99, 55,145,109,173, 32,157,132,240,202,189,235,112,196,240, 74, 40,134,178,157,163, 5,214,168,218,125, 89, - 78,166,109, 80, 48,146, 99,130, 89,201,178, 47, 60, 93, 93, 33,165, 19,126,254,254, 5,255,250,247,222, 65, 42, 43,240,218,155, - 8,143, 30,115,124, 91,225, 90,199, 52, 69,188,248,228,115,252,229, 95,255, 12,235,190,227,119,127,245, 41,126,255,159,189,139, -255,237,143,127,138,105, 74,120,121,183,161,191,126,198,175,190,113,131, 63,248,238,235,248,163,159, 63,199,255,252,127,255, 12, -191,191, 59,252,225,239,253, 26,150,229, 10,190, 3, 95,127,117,135,255,229,223,254, 37,254,199,255,254,247,240,237,119,223,130, - 75,147, 20,125, 78, 86, 12, 47, 46, 5,255,230,223,254, 25,222,251,224, 51, 9,183,241, 30,191,249,189,183,240, 43,223,124,138, - 38, 97,235,104,165, 89,247, 85,107,197,253,203,231,184,253,252,115,220,221,175, 56,159,102, 89, 5,133,113, 0, 58,230, 37, 40, -123,194, 4,157,173,195, 5,216,231,163,169,119,122, 48, 5, 47, 93,227,190,151, 17,211,217, 14,180,182, 16,225,107, 69,105, 13, -177, 3, 62, 38,148,114,129,144,117,212, 79, 62, 33,196,201,118,242, 18,127, 43,142, 10,207,162, 81,109, 79,137,157,160, 11, 30, - 49, 58, 59, 71, 66,244,134, 84, 21, 91, 89,192,229, 66, 10, 37,134,173, 86,221, 45,242,190,203,143, 43,165, 45, 67, 41,147,221, -214,145,165,102,138, 85,165,107, 10,244, 89,106,129,217, 58,112,253,232,138,206, 28, 78, 13,157, 51,191,123, 74, 9,219,101, 53, -203,154,172, 56, 59, 59, 52,185, 96, 45,103,156, 0,158,187,187,141,241,206,156, 88,248,104, 19,188,209,169, 59,156, 78, 39, 44, -167, 43, 78, 26, 61,182,109, 19, 31,250, 36, 34, 57,141,112,245,156, 50,237, 91,198,186,110,242, 14, 57,221, 85,123,177,198,214, -202,127,222, 57,165, 45, 54,177, 48, 46,126,161,149, 77, 39,190,156,202,185,131, 24, 88,181, 24,181,140,244, 70,109,122,156, 93, -156, 13,153,207,167,242, 43, 42,253,234,129,231, 84,107,157,124,134, 38, 46,168,224,140,107, 63, 77,147, 1,170, 4,113, 13,218, -126, 29, 39, 53,195, 26,233, 32,127,174, 74,101,254,122,185,151,245, 32,241,185,253, 31,141,210,161, 78,248, 16, 6,190,186,107, -163,218,216,173,247,193,203,111,221, 82, 49, 97, 74,127, 79, 69, 59, 56,241,109, 66, 83,116, 1,206, 41, 6, 54,142, 60, 11, 21, - 18,187,225,230,208,130, 71,185, 49,165, 85,248,220,141,217, 18,197, 70,162,251,139, 38,130, 11,163,225, 59, 42, 5, 37, 22, 48, -164,196,241,172,136, 35,224,100, 87,187, 94, 54,104,199,175, 54,148,152,102,120,126,137, 41, 9, 35,215,123,143, 56, 37,115,190, -116, 38,106,113,129, 76,168,130,164,209,120, 99,133,203, 14,102,223,170, 5, 26,104, 88,252,148,196,195, 41, 22, 12,143,137, 22, -140, 24, 60, 64,171,204,188,200,143, 93,238,183,113,113, 83, 1,223,154, 60,172,178,183,146,191,239,188, 76, 12,177,232,164,212, - 77, 36, 74, 37,219,209,224,128,144,236, 61,153, 71,177,115, 84,236, 89,116,200,175, 81, 49,207, 39,236,105, 67, 43, 5,181, 38, -120,215, 12,134,161,190,204, 64,178,211,188, 8,138, 52, 77,226,229,158,230,201,216,201, 2,158,144,142, 76,147,154, 4,204,211, -121,151,137, 88, 13,222, 35, 38,201,169,167, 76,153,251,217,209,241,118, 19, 96, 84,132, 56,153,119, 58,120,143,210, 60,166, 39, -223,198,158, 27,174,174,102,188,246,250, 25,127,245, 31,254,157, 84,251,101,248,182,197,182,230,232, 67,110,166, 2,110,252,140, - 28,228, 66, 85,132,109,239, 29,133,234, 99,249,254,229,223,117,222,141, 73, 4,139, 51,167,150,197,218,224,101,242,218,158, 0, - 0, 32, 0, 73, 68, 65, 84,217, 49,136,125, 18, 22,238, 18, 40,182,234,202,223, 5, 5,136,196,230,202, 97,180,171, 95, 83,242, -152, 21,253,169,144, 31, 90,127, 60, 71,120,150, 87, 60,157, 72, 22, 12,182,147, 31,137,111, 34,144,115,206,227,116, 58,227,171, - 47, 51,190,245,198,155,120,237,236,208, 79,207, 80,211,130,169, 73,100,169, 10,126,252,237,115,252,249,127,252, 43,220,174, 25, - 79,174, 22,252,215,191,243, 46,166, 41,162, 57,135,101,158,112,187, 22,209,101,132,128,127,245, 91,223,196,167,119, 25, 31,188, -216,240,199, 63,250, 5,254,238,103,159,225, 15,254,249,119,240,253,239,125, 3, 79,159,156,240, 63,252,119,255, 18,175,191,245, - 4, 13, 82, 48,191,120,117,193, 39, 31,127,133, 15, 63,121,142, 31,191,255, 41,110,137,156,141, 33,224, 59,223,120,130,255,234, - 15,254,137,116, 80,154,130,230, 52, 50,147,200, 79, 52,124,241,213, 45,166,232,209,246, 77, 8,121, 36, 47,182, 14,236,185, 32, - 17, 50,163,152,230,125,207, 12,103,146,142, 95, 97, 56,145, 1, 31,173, 85,116, 68,139, 40, 85, 45, 71,182, 80,138, 9,121, 95, - 57,209,171,156,210, 13, 17, 91,154,228, 80,142, 81,253,235,193,214,108,177, 70,130, 90, 64, 36,114, 28,124, 8,254, 29,189, 53, - 13,212,210,168, 0, 56, 70,166, 19,118, 11, 45,105, 20,123,201,251, 10, 76, 44, 56,203,182,217,251,165,218,147,214, 33, 46, 14, -218, 72,119,166, 92, 10, 59,165, 96, 94, 78,164,150, 73,227, 50,207, 34, 48,214,115,196,178,200,117, 66, 26,101,157, 86,115,230, -231,221,140, 80,184,239, 59, 53, 23,242,207, 50,193, 81,149,136,105,231,165, 51,247,212, 94, 72,176, 74,199,245,205, 13, 98,228, -229,230, 3,246, 61,203, 46, 61,136,207, 89,187,121,157, 12,212, 42,130,224,206,223, 75, 21,243,235, 46, 25,238,121,223, 41,154, -227, 78,159, 22,102,157,130, 85,106,142, 90,173, 84,182,119,187,188,245,125,243, 62,152, 9,172,249,118, 0,255, 16, 30, 21,184, -182,195,200,159, 16,145, 93, 55,220,183, 11,222, 58,118, 79,145,156,231,152, 62,198,196,189,185,220, 49,106, 66, 83,148,112, 39, -255,223,199, 40, 54, 96,142,239, 85, 73,190, 17,204,213, 15,227,126,221,161,119,232,148,174, 13,224,152,209, 97, 6,203,253, 24, -139,170, 32, 28,253,105,173, 54, 70,210, 86, 3,202,232, 58, 71,113,228,210,148, 11, 92,169,243,204,214,108,146,166, 36, 58,155, - 56, 15,247, 89,212,117, 75,206, 50,157,240,129, 47,139, 3,246,117,195, 60, 79,216,214,157,204,221,145, 22,166, 2,182,198,241, -176, 11, 9,161,202,229, 54,159, 2,189,214,157, 64,131,131, 16,174,117,250,167, 71,158,185,120,215,171,141, 82, 99,116, 6, 42, - 0, 24,148,177, 55, 83,168,202,248, 94, 70,190,177, 39, 9, 38,112,192, 60, 71,162, 3, 65,136,139,140,116, 36,196, 67,109, 86, - 5,121, 31,163,156,156,139, 28,166, 20,212, 4,138,175, 52,144, 67, 4,125,176, 93,115,222,229,210,191,220,175,216,182, 93,170, - 58, 69,191,242, 80,208,185,184,119,195,186,179,239, 5,137,156,246,245,178,138,142,160, 86,204, 36,143,165,192, 46, 32, 37,130, - 86,100,108,228,157,122,210, 41, 18,105,154, 24,196,106,148, 69, 81,107,205, 82,208,122,109, 88, 47, 23,228,204,145, 39,186, 88, -201, 90, 69,243, 14, 49, 48,224,133, 25,194,181,169,138, 95,227, 30,243,232,216,209,177, 60,126, 23,240, 51,188, 47,120,250,250, - 13,190,250,240,167,184,127,249,149,236,218,181,171,233,242,123, 84,227,215,195, 46,245,206,120, 66,207,253,158,146,152,128,209, - 85, 57,231,225, 35,201, 90, 7, 27,100, 96,190,186,250,223,131, 55,189, 42,215, 65,147, 69, 13,230,109, 35,155,187, 91,170,150, -166,254,229,125,227,239, 57,220, 4, 78,102,193,232, 85, 40,124,129,246, 45,231,186,129,100,132,179,204, 34,143, 17,174,181,237, -198,171, 90,150,217,118,189,211,188,160,212,128, 47,126,241, 10,255,234,247,175, 16,106, 69, 63, 95, 35, 56,143,253,178, 34, 6, -218,171,214, 11,190,254,240, 19,252, 31, 63,250, 16, 62, 4,124,247,141,107,188,249,248,132,146, 43, 46,165,201,100, 39, 4, 57, -112,224,144, 92,197,127,251, 59,239,224,223,255,248, 99,252,217,135,175,240,213,203, 21,255,235,255,254,183,248, 55,127,244, 19, - 60,185, 57,225,124,154, 17,131,172,126, 46,123,198,139, 87, 43, 59,107,140,201,152,247,248,195,255,236, 91,248,207,255,197,175, - 73,162, 98, 19,187, 94, 79,178,210,136,201,163,230,130, 24, 38,224,217,130,207,111,127,138, 55,159,156,176,189,124, 53, 60,232, -141,107, 55, 5,143, 4, 21, 42, 49,216,137, 86,212, 68, 27, 97,138,194,134,192,212, 45,110,185,121,119, 0,112, 84,219,149, 59, -134,126,148,146,109,125, 53, 47,103, 56, 72, 92,104, 48, 11,171,248,180,125, 28, 57, 19, 34,138,147,253, 47,156,132, 67, 57,229, -216,231,130,121,158,204, 87,110, 93,114, 19,209,109,140,137,202,117,165,220,141,140,234,118,152, 96, 57,115,231,200, 88, 93, 53, - 67, 71, 49,150, 2, 67,100,181,235,145,166,136,211,249,108,208, 46, 65, 57, 79, 54,221,144, 49,191,250,168,197,102, 91, 75, 29, - 35,104, 38, 74, 10, 82, 59,219,217,219, 90,145,105, 95, 25,254,244, 14,225,248,203,132,201,155,232,245,234,250,138,136,215,217, -198,218, 41, 69,195, 87,123,254, 60, 37,206,137, 21,111,199,133,187,116, 7,103,104,211, 86, 27, 19,226,154,145, 52,109, 66,227, -197,118,235,201,222,240,109,108,140,213, 34, 38, 28,122,197,204,202,208, 93, 38, 26,193,118,242,170, 91, 80,189,145, 35, 44,166, -113,242, 3,162, 99,125,148,253,178, 22,112,141, 46,152,137, 23,121,240,206,216,253,149,118, 96, 56, 9,192,129,243, 50,100,111, - 29,158,190,111,213, 8, 8, 77,244, 86,112,207, 44, 52, 80, 85,169,220, 45, 86, 85, 35,106, 85,153, 62,194, 91,154, 49,223, 71, - 28,116, 55, 18,104,109, 85,226,122,219,112,230,232,154,178, 99, 8,244, 52,145, 84, 38,224,205, 84,240, 18,102,211, 44, 85,110, -100,177,132,177,174, 41,133,232,117,208,254, 71,128,137, 98, 54,107,235, 12,162,144,145,153, 11,222,246,227,170,172, 30,192, 23, - 5, 1, 80, 64,183,151,129,231,107, 98,107,107,173, 35, 32, 72,202,142, 27,226,143,211,121,198,229,126,103, 21, 39, 86, 57, 65, - 11, 86,218, 36,138, 77, 12, 36,105, 71, 68, 26, 14,193,114,117, 99, 12, 28,119, 51, 17,139,197, 65,222,251, 17,163, 75, 91,147, -100,169,123, 31,208, 88, 57,247,222,224, 23,177,210,197, 24,209, 56,202,211, 75,187, 49,134, 79, 57,238,251,182, 83,120, 49, 80, -141, 71,214,186,163, 18, 83,199,147,121,207,182,175, 15,206,139,181,139, 28,101,231,135, 3,210,251,136,105,138,214,229,132,160, -135,168,227,152, 88,213,222,158, 35, 36, 57, 12, 26, 67, 48,182,109,229,206,235,144,149, 66,136,138,163, 88, 67,170,118,103, 26, -130, 78,161, 93, 35, 61,174,235, 10, 32,156, 16,174,190,137,188,101, 92, 63, 58,225,209, 77,196, 95,252,201,255,195,132,188,206, -189,147,140,183,229,193, 82,208,141, 63,248,147, 27,179,184,187, 41,240,187,209,236,228,101, 81,191,188,116,127,196, 80,134,110, -251, 79,129,240, 4,179,188,105,242,147, 35, 7, 64,177,149,199,138,183, 57,247, 96, 4,239,156, 67,160, 56,198,146, 9,225,224, -168,142, 22, 97, 39,215, 28,116, 98,140, 56, 71,241,149,151,178,115,247, 72,253, 4,247,120,154,115,252,193,123, 95,226, 7,143, -207, 56,213, 12,156, 94,199,180, 76,184, 92,118, 82,181, 0,151, 55,224,243,207,240,254,207,190,192,171,189,225, 60, 69,252,151, -191,241, 22,210,156, 80,106,199,125,149, 53,130,139, 1,126,154, 80, 86, 57, 92,151, 57,226,191,249,157,111,225,215,222,126,137, - 63,254,233,151,248,232,213,134,117, 47,120,121,191,227,235,219,149,118,158,142,156,229,243,234, 89, 14,146,243,146,240,155,223, -126, 29,127,248, 47,127, 13,223,251,238,219,118,145, 58,239, 81,247,140,238, 60,150, 37, 33, 56,160, 78, 19,226,249, 6,229,171, - 59,124,252,197, 43,252,254,111,191, 99,226, 45, 41, 56, 3,211,189, 24,142,161, 62,107,178,244, 91,111, 35,199,185,139,104, 42, -165,132,208,130,196,165,114,180,170,147,149, 61,231,113, 56, 86,135, 52, 77,140, 61,149, 21, 30,156, 19,136,208,193,215,235, 3, - 44,164, 69, 69,184, 26,196, 17, 72, 25,204, 37,219, 20, 33, 68, 97, 92, 56,122,173,229, 61, 33,206, 86,155, 13,245,168,107,113, -156,139,145,216,112,192, 9,195,138,145, 65, 53,212, 67, 84, 3, 53,100,106,181,195,135, 9,203,233,132,171,235, 51, 78,231, 19, - 78,231, 5,211, 44,123,235,202,203,188, 27,249,203, 97, 55, 24, 75,183,236,140, 90, 59, 71,250,197, 10, 29, 25,123,115,229,213, - 21, 93, 26,144,146, 51,161,108, 8, 17, 33, 69, 94,112,129,246, 99, 41, 18,150,147,216,212, 34,153, 13, 74,180,211,179,251,213, -203,187,195, 57,116,136,105,173, 93,152,229, 12, 96,209,245,132,240,219, 59,207,222, 65,118,203,117,183, 73, 87,167,206,161,212, -138,232, 15, 49,168, 26,237, 76,155,171,250,194,189, 27,156,141, 78,177,153, 50, 0, 36, 1,148,120,222, 64, 81,164, 79, 6,198, -241,252, 78,116,178, 43,231, 36, 76,207,213,125,167,112,215,147,233, 47,236, 17, 61,143,238,239,238,144,243,202,226,222,153, 48, - 79,149,237,232, 93,122,126, 34, 91, 85, 80, 46,232,225, 54, 64, 50,102,251,236,212,149,133,129, 18,102, 20,183, 98, 98,149,249, - 32, 26,167,136,218,138,172, 46,237, 0,119,150, 95,160, 69,133, 8,126,251,131, 9,130,112,100,102, 43, 52, 2, 39, 25, 17,109, -140, 50,116,190,148,184, 19,150,241, 48, 0, 47,226, 52,237, 4,130, 23,193,142, 10, 0,114,110,112, 85, 89,125,236,184, 14, 4, -176,204,110, 68, 70,246,242,178, 94,238, 46,166, 96,188,220, 75,151, 46,234,115, 25, 93,245, 60, 10,135, 94,186,217, 27, 64, 54, -251, 52, 5,164, 36, 95,212, 52, 69, 83, 97,247,214, 76, 25,218,106, 55,172, 97,100,146,144,197,167,214, 54,146,150,248, 31,169, - 12,157,165,208,205, 75, 96,222,113, 65,206,192,114, 58,161, 85, 57, 0, 0,201, 50,175,204, 81,143,204,144,158,231,201, 30,174, -156, 11, 2,157, 5,101,221,141,235, 14,116,184, 54,184,249,129,123,100, 79,228,170,236,193, 70, 66,153,250,114, 53,112,167,215, -110,182,174,188,113,114, 0, 71, 65, 9,197, 24,222,113, 44, 40, 52, 51,229,149,171,242, 83,168,125,221,146,226, 20,185, 20,111, -222, 69,105, 2,205,120,246,250, 13, 62,124,239, 47,113,185,187,147, 49, 85,206, 38, 54,212,253,168,163, 95, 92, 9, 93, 45,175, -114,217,243,192, 87, 91,146, 90,209,114, 21,139, 77,171,149,123,199, 46, 74,110,142,119,189,242,174, 99,178,195, 87,125,233,189, -100, 84,116, 19,137,180,146, 77, 89, 47,170, 89,114,242,163,135, 43,180, 8,122,254,154, 65,148,199,246, 34,246, 42, 93,191,243, -163,115,162,136, 40,239, 27, 71,211, 50, 21,170,173,194,117,103, 54,185,180,156,208, 91,197, 39, 31, 93,144, 94,117,188,243,235, - 11,106,239,168,206,193,191,186, 69,127,249, 2, 62, 70,244,109, 71,223,118,220,223,110,248,143,127,251,137,168,208,159,158,240, -237,111,220, 32, 70, 47,147, 22, 7,156,150,132, 92, 59,178,218, 68, 41,144, 41,165,226,187,111, 92,227, 55,127,247,251,184,237, - 14,127,247,159, 62,193,223,127,240, 41,158,223,110,184,187,144,241, 29, 28, 30,157,103,188,245,218, 53,254,233,111,124, 19,223, -255,245,119,240,214,235,215,136, 65,196,144,173, 86,226,129, 29,194,114,102, 1,235, 49, 79, 1,211,205, 35,148,238,241,245,135, - 31,227,203,207, 62,199,219,143,190,141,249,180,200, 94,150, 36, 64,203,174,225, 78,219, 59,111,172,235,192,172,122,153, 72,200, -132, 78,196,108, 66, 28,171, 94,206,129,125,219,173, 83, 20,229, 46,187, 21,120,204,203, 34,240,158, 57,113,119, 31,113,190,190, - 70,222, 54, 78,163, 10, 66,104,164,160, 9, 47, 35,239, 69, 14,107,120,131,121, 56, 39,248,224,146, 43,210, 20, 14, 4, 66,111, -151,152, 90, 94, 21, 25,171, 83,141, 74,143,120, 76, 51,225, 66, 14,217,196,115,205,120,196, 57,231,129,138,181,160, 15, 17, 59, - 37, 82,190, 98, 76,210, 37,235, 10,142, 68,184,245, 34, 83,208,162, 54,180,195,132, 32, 70,225,104,136,213,139,231, 9,153, 21, -165, 10, 7,190,181,194, 8,105,241,190,235,217,230, 92,144,204, 10, 47,226, 90, 41,212,229,123, 59, 95,157, 48, 26, 72, 17,199, -117, 94, 52,251,158,201, 15,247, 44, 14,139,173, 34,106,149, 61,243,195,198,170,211, 98, 10,130, 95, 58, 73,162,133,130,212, 67, -175,234, 37, 21,207, 59,137,255,237, 68,106,111, 12,196, 82,155,151,238,163, 65, 76,107,101,206,122,103,158, 5, 71, 60, 50,141, - 73,178,118,149, 88,225,137,147, 76, 45, 66, 58,139, 2, 63, 34, 89,121,198,187,174,162,228, 42,239, 40,173,116,165, 20,236,219, - 61,202,190, 26, 48,166,243,206,147,201,114,163,248,216,217,133, 94, 45,181,241, 64,193,115,227,179,232, 7,104,142,142,242,123, -131,173, 84,228,159, 13,212,185,126, 78,186, 39,215,181,131,248,226, 85, 61,223, 44, 42, 87, 47,116,163,178,214,102, 57,237, 10, -235, 2,128, 40,223, 89, 21,129, 88,147, 7, 5,157, 22, 3, 7,238,112,155,141,136, 53,123, 61,120,233,138, 52,187, 91, 67, 41, -116, 52,230,116,134, 69,101,228,122,127, 47, 29, 89,169,163, 66, 46,157, 54,162,142,109, 45,134, 70, 44,205,234, 31, 98, 19,119, - 75,106, 66,143,100,131,139,224,101, 90, 34,213,215, 96,215,186,225,114, 89,185, 47,150, 11,103, 89, 38, 42, 69, 69,196,118,127, -183, 10, 8,100,156, 87,246,133,180, 90, 12, 27,153,183,102,152, 76, 85, 5,123,159, 70,222,179, 41,191,165,130,181,108,242,222, -137, 43, 36, 57,136,151, 80,154, 40,144,227, 5,214,122, 71,156,162,237,139, 5,182, 50,128, 42, 58, 34, 3,237,105, 26, 24, 34, -135, 83,197,190,101,174, 39, 18, 28,201, 77, 66,254, 99,118,176, 31,129, 16,106,195,208,174,202, 51,161,172,225,104, 87,188, 70, -188,126, 11,251, 86,241,248,181, 27, 76, 97,199,199, 31,252, 68,252,200, 85,139,184,102, 80,138,110, 54, 22, 38, 46,117, 25,149, -181,154,121,161, 43, 1,169,219,186,194,251,104,251, 83,125, 41,192, 61,187, 12, 50,130,225, 71, 3,156,237,226,213,179,142,222, -109, 31, 38,123,125,162,120, 3, 65, 14,144, 23,151, 27, 45,219, 43, 58,146,220,228,179,243,136,113, 54, 1, 95, 63,248,236,161, -161, 60, 44,244,250,145,199, 16,132,191,157, 98,196,221, 93,198,171, 15,119,252,206,183,158,192,123,135,151, 95,223, 33,189,248, -123, 44, 87,147, 68,121,166, 8,191, 76,232, 62,224,167, 31,191,192, 47,190,190,224, 60, 79,248, 47,190,255, 6,124,154,144,171, - 80,205,155, 27,213,127,222,118,118, 72,164, 72, 65,132, 71,203,156,240,206,179, 71,248,173, 31,188,141,219,219, 13, 47, 94,109, -184,172, 98, 19, 90,247,134,235,115,194,163,155, 19, 82,240,136,203,132,121, 73, 56,205, 19, 60, 58,194,105,145,174,188, 84,160, -238,112, 93, 70,211, 55, 79, 30, 33,221, 60,198,254,209, 47,240,211,207, 62,196,228, 61,174,230,136,190,221,155, 54, 68, 4,111, - 29,206,119,146, 11, 27, 47,211, 78, 50,156,140,136,139,134, 57, 17,230, 36,142, 1,218,122,170, 20, 2,209,137,174, 38,196, 4, - 80, 81,223,209, 49, 47,139,185,111, 84,184,102, 73, 90,158, 98, 49, 90,100,211, 60,143, 17,182,151, 98, 88, 96, 52,132,183,236, - 93,126, 14,215, 63, 66,149, 4,106,174, 2,164, 57, 40,173,229, 50,239,214, 17,139,173, 44, 30, 34,127,137,113, 14, 30,165, 56, -123,175, 99,164,135, 90,213,254,164, 4, 78,243,132,229,180,224,116, 94,144,104, 69,213,104,105, 17,125, 53, 90,245,104,213,226, -129,172,201,108,121,207,114,209,114, 53, 86,184,230,139, 33,160,244, 98, 99,101,129,143, 72, 82, 98,173, 98,209,157,150,197, 80, -202,154,248, 54, 47, 51, 90, 17,151,144,160, 96,101,183,222,187,224, 93,107, 46, 7, 7,135, 56,123,246,109,183,134, 68,216,237, -187,173, 44,181, 91,111,236,210,215,109,167,189,176, 90,226,156,104, 5,226, 3,251, 98, 35,129, 80,185, 31, 7, 65, 21,155, 9, -197,166, 54, 22, 89,149,205,137, 67,156,102,203,104, 72, 41, 90,168,149,169,102, 21,195,195, 92,130, 70, 58,153, 62, 67, 33, 70, -138,209,228, 39,102,230,183,239,219, 42,161, 50,173, 28, 38,116,116,225, 56,111,147,186, 78,245,190,158, 43, 96,147, 2, 47,110, - 38,117,136,140,145,186,126,183,245, 96, 89,107,236,222, 31,254, 60,189,156,187,117,230,132,223, 80, 77, 15,106, 75, 36,176,136, - 85, 37, 27, 15, 33, 89,118, 75, 14, 20,237, 79, 20, 33,118, 72,136,218,185, 6,165,129,232, 47, 74, 50, 78,169, 69,126,177, 82, - 81,155, 8, 36, 44, 79,216,123,160,118,203,235, 86, 79,175, 4,159, 48, 66, 78,125,165,222, 97, 91,243, 65, 5, 40, 21,212,101, -219,121,153, 55,203, 27, 23,210,152, 51, 36, 35, 84,197, 26,100,207,182,204, 9,211, 28,109,164,156, 98, 36,109,105, 88, 61,164, -242,142,112,213,225,190, 86,217,203,183,138,203, 61,204, 87,142, 46,241,174,208, 2,192,233,143,193, 40, 73,219,186,155,189,165, - 17, 69,106,233, 64,125,236, 14,151,101,226,132,128,144,147, 58, 42,249,206, 68,161,188, 53, 17,212,208, 30, 53, 77,201, 46, 35, - 3, 30,176,242, 82, 27,155,121,249,107, 69, 43, 21, 62,176,138,133, 10,241,216,133,107,158,252, 28,196,105,224,186, 85,217, 33, - 58,134, 87, 4,116, 18,179,148,128,231,109,191,229,113,126,227, 7, 88, 55,153,170, 60,125,237, 10,191,248,241, 31, 97,187,220, -113,239,199,152, 81, 10,124,140, 92,215, 57, 66,204,154,121,236,134,216, 77, 73, 80, 20,154,120, 31, 77, 60, 34, 54, 26,217,133, -121,242, 8, 60, 11, 60,207,113,109,239, 77, 14,228, 30,208, 91, 49, 70,190,247,180,233, 69, 79,177, 94,165,192, 70,138, 50,137, - 7,142,182, 3,246,220,209, 47,167,133, 88, 73, 24, 56, 71,234,206,202,181, 71, 56, 8, 96,116,143, 90,104, 9, 20,180,167,168, -233, 51, 62,254,249, 5,223,127,114, 5, 95,129,187, 59,209, 72,192, 7,108,117,135,107, 13,137, 22,214,189,118,252,233,223,125, -138,243,245, 9,255,226, 91, 79,240,171,223,124, 6,106, 25, 81,107,195,186,107, 69,223,237, 29, 44,157,107, 61,105,141,177,175, - 43,214,251,132,103, 79, 22, 44, 87, 39,172,165, 33, 45, 19,124,175,200, 69,190,187,144, 38, 76,215, 87,184,190, 57, 97, 62,205, - 56,159, 38, 44,167,217, 44,121, 64, 67,219, 54,212,237, 30,249,178,225,252,228, 10,117,223,240,229, 47, 63,196,123, 31,124, 46, -193, 67,165,163,126,246, 9, 69,159, 32,124,199,150,135,230, 10, 0, 68,107,226,252, 16,220,233,247,176, 94, 86,156,175, 78, 28, -126, 17, 38, 20,228,217,113,156, 38, 21, 30,102, 82,204, 50,101,141,104,101,167,249,228,222,163,150,140, 52,113, 92,155,228, 98, -108,174, 15,251,163,243,220,201,139,253,213,209, 64, 30,147,236,153,149,101, 32,129, 32,157, 63, 22,108,242,229, 14, 16,167,209, -129,226,176,247,214,130,197,113,180, 57,146,249,116, 37, 17, 52,152,101, 94, 24,137, 60, 25, 60, 73,127,174,173,225,138, 20, 19, -153, 13,193, 17,171,187,231, 76,191, 59,108,207,222,232,159,110,173, 89,184, 85,136,137,161, 51, 14,167,243,140,101, 57, 97,154, - 39,174, 53, 43,197,121, 11,210, 20, 80,188, 36, 44,182, 46, 58,133, 82, 68,136,220, 56,229,211, 56,108,157,130,240, 43,199, 70, - 23,141, 4,243,136,210,125,223,118, 67,185,214, 34,216,220,157,239,144, 22,114, 18,151, 61, 31, 80,187,205, 2,123, 70, 97, 80, -144,162, 71,103,119,237,152,249, 33,107, 57,209, 21, 73,243, 53, 81,196, 9, 91, 85,154, 5, 78,221, 88, 18,101, 39,172, 10,158, -195,158, 40,236,214, 10,122,174,102,245,213, 34, 42,239,171,185, 97,192,184, 32, 35, 96,112,186,162,184,113,157, 38,129,216, 89, -167, 34,224,134,195, 37, 78,209, 27,255, 44,106, 71,235,173,137, 16, 79,129, 53, 93, 19, 37, 15,246, 56,112,165,122, 32,196,105, -129,131, 38,231,137, 3, 40,146,139,240, 8,232,182,215,135, 77, 89, 85,175,166,249, 22, 81, 69, 0,250,226,154,117,141, 10, 89, -231, 58,122,205,220,169, 58, 30,152,244,210, 57,145,206, 41,136, 70, 51,178,197,179, 88,205, 42, 85,246,157,216,206, 74,138,150, -116, 39,154,145,222,155, 55,107,210,168,148, 7, 46, 79, 95, 30, 21,235,120, 47,246, 21, 25,223, 68,222, 33,157, 66,146,108,185, -222,234, 3,175,181,227,124,158,209,170,166, 27, 21,214, 46,210,217,195,130,103,132, 91,236,188, 16,156,148,195,155,179,100, 99, -107,176,130,142, 73, 20, 7, 43,228,164,108,214, 52, 29,217, 40, 57, 8,246,240,145,142, 7,177,254, 77,196,219,206,147, 39,120, -161,195,209, 79, 46,105,105, 29, 46,114, 36, 84, 10, 92, 76,168,101,133,111, 94, 48,154,112,152,151,197,138, 40,231, 3, 2,119, -153,129,254,118,249,189, 61,171,255,138,192,164, 45, 83,254, 82,193, 26, 78,111,160,250, 71,112, 46,227,230,209, 9,229,254, 11, -124,250,243,255,196, 67, 69, 84,246,114,136,110, 70,141,211, 98,200, 98,119, 27,168, 62,174,220,185, 30,226, 9,155, 4, 46, 56, -218,126, 36, 69, 47,216,238, 83,173,114, 26, 82, 35,255,142, 8, 89, 26,195,105,228,193, 13, 98, 35, 50,123,220, 24,167,187,230, - 76, 44,231,220,248,179,132, 52, 41, 29,119, 36,246, 89,234, 84,196,178, 44, 44,218,196, 66,163,123,204, 70,187, 18, 66,176,195, - 6, 0, 94, 62,175, 56,191,200,120,244,230, 25,123,110, 8,231, 25,253,234,140,116,117, 66, 57,159,209,190,248, 28,121,189,199, -212, 29, 62,252,242, 30, 31,124,117,193,227,243,132,223,250,149,199,198, 18,104,165, 96,111, 50,203, 85, 33,106,205, 44,144, 74, - 67,131,199,118,217,112,158,129,237,178, 35, 78, 59,246,234,112,190, 62,225,126,111, 84,160, 23,212,178,163,182,142,251,187,130, - 37,223,225,235, 23,247, 50,110,228,184,115,154, 34,182,251, 21,181, 85,108,151, 13,183,183, 47,241, 15,255,240, 41,238,214, 13, -119,151, 59,220,111,247,240,209,225,141,239, 77,248, 63,127,250,247,112,222, 99,219, 11, 66, 18, 1,156,116, 6,162, 1, 9, 90, - 32,181,110,162,164,198,221,122,221, 51,153,252,188, 20, 89,213,213,218,224,179,103,168,136, 92,216,209, 57, 20, 28, 98, 69,131, - 71,173,194,242,214,168,226,121, 89,176, 94, 58,156,227,184, 52, 23,212, 34,124,137,202,247, 87,119,184,235,186,217,249,144,115, -198,180,204,210,169, 77, 82,140,251, 69,156, 32, 58, 69,204,123, 57, 76,230,154,217,101,101,154, 22,153, 45, 95,236, 44,210,145, -184,231,190,182, 41,244,209, 7,164, 83,194, 52, 37,156,174,206,152,166, 25, 49, 37, 99,104,168,167, 58, 80,192,103,142,152,170, -164, 76, 57,155, 54, 70,151, 74,250,176,231,116,162, 89,131,163,190,105, 31,100, 45, 26,130,104,124,230,121, 33, 92, 70, 58,183, - 20, 29, 93, 25, 48,198,136, 35,128, 68,130,174,100, 26, 16, 72, 71,204, 89, 57, 12,242,191,245,207,208, 8, 98,145,243,114,179, -244, 71,231,100,106,170, 0, 50,237,254,181, 32,246, 10,107,105, 56, 36,112, 54, 42,246, 9,172,177, 96, 41, 41,234, 28, 11,133, - 24,147,176,242,185,215,247, 65,169,162,114,237, 5, 10,242, 84, 11,225, 8, 41, 83,177, 89,135, 0,168,108,221,114, 96,173,244, -166,116, 80,225,213, 59, 77,147,112,221,162,104, 21, 50,164, 24,215,214,221, 97,138,235,108,218, 8,235,232,221, 72, 87, 99,135, -109,207, 84, 19, 2, 95,211, 32,168,134, 65,251, 68,231,222,222, 63, 88,101,134,144, 40,124,230, 42,220, 53, 30,221,188, 47, 9, -229,210,203, 60,165, 25,206,105, 76,236,241,222,172,136,101,223, 8, 47, 81, 16, 3, 44, 65,169,211,106,144,247, 17, 20,175,209, -154,157,127, 67, 5, 58,232,125, 86,184, 95, 81,208,126,167, 87,119,223,154, 49,116, 27,191, 84,217,191, 17,155, 74, 53,188, 20, - 13,220,235,176, 75, 23,209, 50, 71, 89, 41, 98, 57,205, 72, 83,194, 60, 79,210, 97,176, 59,211,176, 22, 71,129, 86, 41,133, 15, - 78,199,122,217,108, 4,239,208,105, 47,145,151, 89, 14, 28, 90,155, 60,255, 14,117, 76, 11, 98, 12, 40,140,234, 83,216,142,116, -244,242,208,184, 42,135,221,182, 83, 37,237,186, 49,173,213,174, 16, 24,235, 89,225,224, 19,153,237,181,216, 46, 94,186,206,110, -162,156,222,186, 0, 33,184,191,143, 73, 46,179, 86, 27,106, 47, 68, 51, 22, 19,239, 28,119,195,222,192,110,149, 58, 7,122, 66, -189,116, 89,193,123, 82,252,228,179,113,126,194,242,230, 15,176,174, 59, 78,167,132, 39, 79, 79,120,239,255,250,119,200, 59,243, -154,115,181, 49,165,114,136,125,224,159,135,222, 93,176,139,233, 10,241, 9,142, 76,230,102,144, 6, 79, 5,116,156,102, 98,137, -131, 88,122, 40, 4, 4,173, 61, 50, 5,145,169,139,119, 74, 21, 19, 11, 85,160,191, 86,214, 63, 59, 71,160, 71,238,123, 39, 85, -174,218,243,162, 32, 9,209, 26,137,167, 63, 77,179,113,246, 27,131, 38, 92,239,226,101, 15, 76,246,234,146, 28, 55, 45,139,165, - 3,150,226,241,217,251,175,240, 27, 79,174,113,161, 74,214,157,175,144,207, 87,232, 81,168,124,238,245,183,224,190,250, 12, 47, -110,239,241,167, 63,127, 1, 23, 60,126,235,237, 71,120,116, 53, 25,187, 92, 58, 73,177,139,229,204,226,165, 3,141,233, 85,117, - 47,152, 60,144,162,195, 79, 63,121,129,159,255,248,125,132, 63,237,120,237,217, 13, 82,114, 40, 77, 14,220,125,223,208,123,181, - 68,185,198,228, 50,207,176, 27, 69, 16, 87, 85,175,179, 51, 13, 49, 33,156, 59,206,179,183,207,251,235,124,135,214, 35, 98,156, -244, 35,179, 29,167, 17,179, 28,108, 29, 49,114, 7,100,229,211,122, 19,229,255,190,137,184, 80,187, 25, 62,211,105,154,216,225, -203, 5,149,152, 53,145, 38, 5, 33,201,129, 60, 77,193,224, 34, 49, 77,104,125,199,171, 23,119, 8, 49,113, 50,225, 12, 77,237, -131, 20, 12,165,116, 78,221, 70, 74,162, 34,170, 53,176, 68, 61,219,221,117, 75,155,212, 72,101,153,250,201, 65,171, 44, 5,155, - 72,129,193, 62,236,208, 43, 5,127, 49, 70,164, 20,177,156, 78, 88, 78, 39, 76,203,108, 29,250,114, 94, 16,147, 48,224, 47,247, - 43,187,192, 96,157,221,182, 21, 76,115,228,152,189, 24,239,189, 85,105,168, 42,139,165,222,155,197, 78,171,232,110,154, 19,230, -121,193,147,167,143,100,133, 25,229,157,150, 34,201,113,210,229, 13, 39,171, 59,242, 90, 71,194,157,228, 25,196,193, 0, 33, 21, - 50, 51,148,165,213, 42,216, 94,116,100, 42,253,229,252, 35, 89,175, 53,148,170,147, 78,207,181,236,112, 72,168,186, 93,162,122, -243, 64, 59, 43,124, 39, 70,115,178,136, 75,198, 91,103, 46,123,229, 96, 57, 21,206,123,203,206,240,206, 83,227, 2, 54, 85,197, -238, 0,242,134,184, 78,174, 38, 44,204,251, 69,196,140,204,232,104, 26,201,174, 52, 47, 22, 22, 48, 33,218, 64,211,154,142, 73, -221, 77, 29,195,142,172,182,188, 67,102,133, 76, 87,250,131,231, 89, 47,112, 1,239, 4,244, 94,108,154,169,239, 71,119, 18, 87, -222,221,192,229,154,251, 41,120,243,216, 71, 18, 22,181, 91, 55, 50, 94, 23,155,233,233,116, 66,108, 85,184,178,121, 19, 35,126, - 96,117,169, 93, 82, 45,172, 46, 26, 14, 50,126,205,176,245,244,237,118,180,174,212, 45, 33,187,237, 91,150,189, 48, 28,166, 73, - 4, 1, 58, 94, 86,219,155,144,145, 10,213,199, 64,111, 25, 13,193, 30,186,192, 49, 91, 41, 13,211,180,136, 47,115, 74,132, 11, - 56, 83, 60,106,183,216, 90,227,232,168,154,159,177, 85,221, 81, 53,126, 64,178,255,174, 53, 75, 84, 32, 31, 94,207, 81,149,140, -121, 2, 87, 15,221, 14,125,253, 2,106,145, 80,152,148, 34, 95, 22,194, 23, 56,134,214, 7,190,247,134,189, 22, 9,171,200,153, -171,133, 78, 5,103, 68,160, 42,216,187,110, 23,179,166,226,137,229, 75,162, 87,181,115,133, 27,188,226,237,178,241,159,201, 24, - 84, 35,112,149, 37,222, 29,108,100, 14,200, 56, 95,117, 2,158,158, 91,231, 61, 90,151,162,108,122,252, 46, 74, 75, 72, 9,120, -250,218, 13, 94,124,242, 62, 94,124,241,169, 4, 67,184,142, 22, 96,106,115,122, 89,196,206,150,179, 37, 72, 53,170,115,171, 93, -248, 21,221,139, 55,216, 81,184, 2, 45,156, 66, 28,192, 29, 72,168, 77, 0,197, 32,181,160,113,212,238, 57, 38, 69,175,210, 41, -171,206,130, 47, 48,208, 76, 23, 33,177,138,147,133,178,184, 56,217,110, 78,172, 52, 82,160, 74,225, 22, 56,150,211, 9, 73,229, - 30,158, 48,159,125, 19, 81, 82, 45, 70, 43, 19,176,134,195, 47, 62,184,197, 91,105, 70,243, 30, 91,131,176,214, 91,135, 91, 87, - 52, 23, 80,154,136,190,250,227,103,248,232,139, 11,126,249, 98,197, 57, 6,124,247,173,107,249, 76, 90,131,139, 73, 4,100,247, - 43,182, 44, 99,207,141, 42,246, 92, 58, 82, 12,112,121, 71,156, 59,220,147,103,120,254,179,175, 17,230, 29,215,215, 1,107,126, -142,220,152, 63,237,164,147,149,142,163,115, 76,237,120, 17, 20, 19,192,118, 30, 94,122, 17, 3,206,214, 61,129, 19,178,198, 73, -145, 90, 10, 77,164,211, 61, 59,105,233,252,106,107, 72,233, 24,101,234,209,208, 68, 60,218, 59,122, 20, 65,150,162, 90,245, 63, -161, 11, 81,177,146,106, 38,197, 65,176,117, 86,135, 67,175, 13, 33, 69,228, 34,100,172,105, 94,100,109,183,109,216,246, 21,125, -221,177,156, 26,150,243, 21,193, 37, 20, 50,213, 14,239,155,145, 37,229, 51, 14, 72, 49,114,228,221,172, 11,211,209,176,238, 55, -157,229,111,143,149,218,182,237,166, 76,151,179,165,217, 58, 77,173,147, 41, 5,184, 41,146,171,126,194,249,234, 76, 0,204, 8, - 70, 9,196,118,234,254, 83,253,240,194,170,119,216,214, 93,206, 64,186,104,244, 82,112, 22,138, 64,100, 51, 17,160,206, 59,204, - 81, 56,238,211, 60, 3, 78, 84,240,222, 59,211, 60,169, 0, 24,189, 90,218,151,188,251,157, 69,188, 27,120,235, 82,209,218,110, -161, 44,162,108,151,240,154, 66, 81,160,136,177, 6, 53, 79, 87,162,130,181,141,140,210,117, 44,254,186,217,137, 37,252, 75,130, -146, 68,175,227,224,125, 18, 49,172,119, 12,121,114,182,250,213,231,209,133, 1,237,114,182,194, 21, 17, 92,235,213,208,190,146, -133,209, 25, 6, 84,121, 94, 87,128,188, 13, 41,116, 51, 74,222,134,178,189,105,200,133, 31,129, 92,124, 31, 70, 50,160,179,187, -222,178, 35,104,157,209,233,179,194,102,116, 66,112, 76, 46, 29,194, 57, 28, 26, 95,141,111,165, 53,142,161, 67, 20, 66,177,208, -179, 32,215,131, 32,110, 32,103,189,143,230, 28,208, 0,155, 16,146, 5,123,181,222, 16,168, 87,138,222, 49,137,204,201, 1, 46, -249,214, 3, 70, 47,135, 69, 59, 48,156,199,126, 86,163, 54,165, 51,211,132, 49,103, 64, 24,221, 21,170,160, 78, 76,244, 26,169, - 87,141, 3, 44,171, 6,103,149, 71, 48, 91,141, 6, 30,120,170, 27, 3,230, 57,113, 92, 19,201, 72, 6,249,211, 5, 59,125,228, -219,186,139, 55,151, 56,214,194, 29,149, 84,173,160, 48, 79, 66, 91,246,109, 29, 23,121,240,136,113,178,106, 86, 65, 52,181,200, -142, 71, 58,212,136,211, 89,186,151,182,107,117, 93, 13,191, 88,154, 10,119, 58,202,158,129, 36, 10,239, 94, 11,166,137, 93, 41, -134, 88, 70, 89,227,158,161, 45,181,116, 90,189, 96, 97, 36,186,127, 43,121,199,118, 89,249,185, 56, 19,175, 9,246, 50,154, 18, - 84, 45, 34,222, 7,134, 1, 4, 59,192,101,124,229,172,210,140,203, 35,248,243,219,216,247,134,171,235, 25,167,185,225, 71,127, -252,103,112, 62,114,183,218, 16,208, 16,147, 27, 22, 62,215,137,250, 29,241,140,218,173,123, 66,113,100, 45, 34, 47,183,142,197, -188, 83,124, 48,119, 66, 14,232, 57, 75, 49,213,187,224, 91, 77, 52, 37,180,169, 16, 28, 28,162, 89, 54,208,155,248, 57,131,236, -112, 61,199,183, 33, 77, 86,252,104,252,164, 70, 61,182,222, 49, 45,179,113,232,237,185, 59, 88,135,188, 15,216,183,141,136, 93, -185, 8,230,101,193,180,156,216, 89, 39,180,210,241,226,179,140,119,191,113,133,181, 59,224,124, 70,127,252, 24, 27,128,190,222, - 99,158, 42, 92,243, 40, 77, 68, 68,127,241,193, 87,104,189,227,183,191,121,131,171, 36, 48,142, 20, 3,218,158,209,168,166,174, -188,236,246, 38, 34,195, 41,202, 52, 99,185,114,216, 78, 79,144,231, 5,207, 30,159,241,234,171,207,168,106,246, 3, 88,161,156, -130, 62, 24,229,186,239,148, 75,127, 0,147, 60,113,160,106,151,145, 21,154,124,126,131, 80,229, 76,208,229, 31,168, 11,168,252, -167,166, 68, 84,209,222,198,209,114, 48,123, 17, 86, 85,112,122, 32, 29,175,226, 63, 67, 12, 88,215, 77,138,242, 16, 24,191, 42, -239,147, 2, 77,172,191,225,119, 20, 99,180,164,171,206,241,103,206, 5, 97,207,152,102,242,188, 33, 34,175,245,178,155, 22,163, -182, 6, 87, 27, 66, 96,151, 3, 25,215,246,126,144, 12, 97, 60,183,141,207, 46, 14,120, 82, 85,137, 59,195,143,182, 17, 52, 68, - 20,105,107, 29,203,105,193,249,250,204, 9,226,194,120,217,104, 43,139, 20, 35,214,203,106,221,155,115,142,227,126, 25,231, 23, -238,165,197,211, 61,212,212, 58,246,117, 62,194,209,159, 47, 80,170, 25,203,233,140,148,130,137,140, 67,244, 86,152, 52,138, 85, -205,177,208, 52,239,193, 83, 20,214,236,188, 82, 50,156,172, 43,119,142,200, 9,148, 33,179, 94, 69,144,129, 25, 30, 58,205, 24, -224, 21, 54, 49,236,202,245,187,149,221,180, 76,165, 18, 59, 77, 77,219,180,132, 58,221,151,107,156,180,146,100,148,224,118,192, -111, 59,239,209,235,200,221,104, 96,212,116,169,112,104,168,112,212, 50, 21,244,154, 9,211,169,156,204,106,145,212,161,174, 69, -160,219,217, 9, 28,149,235,135,117,244,112,152,141,231,164,203, 84, 75, 5,143,131, 87, 32, 99,172,162, 42,116, 54,166, 93,187, -117,174,181,117,146,164, 58, 38, 17,125, 71, 43,192,132,182, 25,237, 98, 47, 53,203,101,221, 10,159,147,104,239,159,138, 13,117, -234,221,200, 17,137,219,186, 82,213,190, 91, 12,170,115, 28,104,246, 66, 3,189, 92,136,224, 72,164,213,134, 94,253,193, 79,215, - 80, 89,106,212, 3, 95, 93, 89,188,173, 53,177, 56,112,103, 82,107,230, 37,212,185,119,106, 54,230,214,145,190,226,135,122,147, -241,207,213, 44,251,174,214,192,156,225,161, 30, 84, 32,131,118,254,232,221, 62,192,198, 5,152,142, 0,143,162, 24,217, 69, 53, -148,188,211, 99, 27, 81,115, 65, 33, 51,120,223,216,201, 78, 50,246,243,204, 13,151, 47, 3, 60,116,228,162, 16,255,164,116,130, -138, 40,197,212,109,143,237,130, 88, 81,166, 20,169,202,148, 17, 85,154,100,215, 95, 90, 19, 43,142,143,195,247,223, 52, 61,205, -163, 53,114,149,189, 3,202, 33,151,156, 66, 51, 29,189, 43,232,191,213,102, 59, 33, 71,161, 94,247, 99,135,163, 79,229,252,244, - 59,216,101,229,143,103,175,221,224,195,191,251, 83,166,142, 69,118,112, 1,193,171,141,172,243,239, 87, 16, 34,189,202,181,162, -213,142,156, 55,179,206,132, 32,163, 53, 56,133, 16, 69,177,155, 81,148,167, 54, 31, 52,217, 27,229,245, 66,150,187, 55,159,180, -236, 23, 35, 21,239,196,146,234,133,229,228, 66, 10, 49, 26,211, 89,252,211,201,240,187, 53,239, 98, 81, 76, 73,220, 4, 28,225, - 53,102,169, 15, 50, 96,225, 1,151, 37,232,165, 10,136, 39,166,132,229,124, 37, 36, 68, 39,221,253, 60,123,156,175, 23,124,122, - 39, 8,209, 19, 46,240,165, 34, 62,122,132,234, 38,180,220, 17, 80, 49, 37,143,247, 63,248, 12,159,125,117,139, 39,215, 11,190, -255,235,223,128,219, 46,112,189,161, 87, 22,112,173, 97, 93,165,160,245, 14, 56, 77, 17, 41, 2,113,114, 40,197,161, 76, 55,136, -215,143,228,114,242, 28,199,146,213, 32, 99,188, 97,183, 18,206, 4,115, 23,104, 85,148,119, 50, 51,235,220,143,164,169,131,245, -200,135,177,143,115, 4, 59, 12,188,101,179,139, 46,248,192, 65,139, 55,140,166,138,233,212,230, 42, 17,197,244, 99, 55, 77,176, -234, 84, 47, 75,177, 16,200, 33, 16, 88,148, 31,172, 6, 78,184, 66, 12,216, 55, 89,179, 56,238,202,115,150, 53,211,124, 18, 88, -143,138,198, 66,172,214, 21, 43,111, 64,166, 14,117,116,215, 12,138, 50,113,174,237, 64,155,237,175,133, 77,126, 80, 33,115,244, -173,241,166,165, 20, 91, 13,193,116, 0,162,198,214,142,124, 89, 68, 36, 39, 89, 11, 9,137, 43,159, 52, 37,131,106,197, 20,177, -239,249,176, 91, 87,120, 20,108,114,230,117,111,157,139, 93, 6, 34,222,108, 92, 55,206, 88, 78, 39, 78,164,100,226,145,146, 31, -211, 16,238,241, 47,247, 27, 65, 60,154,132, 22, 41, 52,172,182, 74,211,108,190,156, 11,246,125,195,182,110, 38,100, 19,209,115, -179, 14,183,183,134,230, 7,183, 18,153, 40, 0, 0, 32, 0, 73, 68, 65, 84,100, 74, 46,150,106, 24,235, 76, 65,154,230,121,139, - 23,190, 48,215,189, 31,124,232,129,216, 83,174, 91, 44,198, 55, 88,241,233, 60, 76,107,211,122,229,153, 10,212, 74,141, 20,131, -162, 36,241, 17, 70,181,147, 73,212,206,137,237,142,195, 2, 92,206,198,134,193,137,239,162, 96,215,189,184,194,174,228,249, 45, - 54,197,209,117,147,237,232,185,179, 86,205, 66,227,106,198,188, 90,221, 1, 8,230,152,106,221,153,230, 71,227,197, 71,247,221, -249,122,141, 17,189,112,239, 3, 31,211,254, 48, 56,134, 69,168,247, 13, 83,154,237,222,169,181,153,176, 91, 28, 0, 29, 81, 42, -196, 54, 84,174, 24,201,108,208, 49,194, 65, 13, 47, 35, 8,217,125,111, 12, 68,145,142,204, 89,228,169, 9,177, 66,192,101,205, - 70, 12,114, 33, 9,149,201, 57,219, 3,143,131,105, 68,206,193, 57, 52,114,154,247,178, 34,132,100,163,216,121, 78, 99, 68,194, - 67, 74,186,244,140,187,219,123,218, 46, 26,214,117,195,233,124,226,197,215,200,137, 14, 88,215, 66,133,181, 67, 45, 35,227,214, -162, 81,157, 67,207,221, 32, 56,206,123,236, 59,173,122,220,133,214, 90, 56, 14, 18,139, 83,222,165, 3,217,214,237, 65, 23,158, -210, 4, 7, 33, 23,165, 16, 57,162,146, 78, 36,114,247,164, 44, 97,169,151,188,169,214,251,131,160, 12, 88, 80,139, 88, 8, 61, - 5, 92, 84, 10, 7, 9,110, 41,123, 70,154, 68,116, 36, 81,160,206,180, 17,173,117,248, 22,132,146, 70, 63,167,155,158,162,135, - 71, 40,235,138, 39,207,174,209,243,115,124,249,209, 63,200,222,135,170, 75,221,227,244, 94, 1, 39,113,155, 33, 78,180,135, 37, - 56,223, 16, 98, 23, 44,112,240, 6,101, 16,224, 75, 61, 20,114,176,142,209, 57,135,188,101, 73,222,234, 28,229,145,172,103,236, - 0, 34,116,155,133,107,136,229,204,113,199, 46,207,132, 35, 74,119, 49,254, 0,232,211, 15, 49,218, 46, 62,120, 79, 92,109,231, -122,168,154,191,118,223, 46, 76, 25, 44,134, 50,245, 33, 98, 62,223,208,149, 0,184,152,208,122,192,190, 53,228, 6,220, 6,143, -215,207, 9,190, 3,113, 22,219, 90, 74, 65,224, 16,232,216,114,199,143,126,242, 75,180,214,240,187,255,244, 93, 44,111,190, 1, - 60,255, 26,254,197,115,187, 52, 83,244, 0,225, 66, 29, 29, 87,147, 92,232, 62, 56,196,215,222,146, 28,241, 82,112, 90, 34,238, - 95,222,179,120,242,240,209,217,232,112, 92,240,163,176,117,156,142,116,219,217,117,248, 3,123, 90, 47,113,207,176, 21,181, 34, - 41, 39,189,163, 24,165,236, 65, 22,122,215, 48,160,134, 86, 58, 60, 1, 76,129,129, 31,170,144,246,174,217,123,225,181,211,114, - 64,219, 55, 94,176,238, 65, 7, 36,130, 50, 41,150, 53, 66, 84, 2, 83,220,200,108,143, 9, 33, 87, 52, 63,156, 17,138, 26, 22, -209, 80, 2,224, 13, 26, 37, 66,167, 17,163,234, 92, 27, 43,136, 58, 70,232,160,175, 61,239, 5,167,171,147,240, 57,218, 80, 74, - 43, 22,180, 20,217, 69,107,102,195,233,124,178, 32,170,211,105,193,180,204, 50, 14,231, 69,126, 58,159,100,252,238, 61, 90,136, - 88,203,134, 90, 68,168,216,121,145,110, 91, 54,240,147,167,245, 77,237,100,222,117,132, 52, 26,146,148, 18,210,188,224,116,117, - 30,254,123, 63,242, 34, 44,119, 34,120,138, 0, 97, 64,157,121,153,217, 93,118, 58,145,164, 72,242,228,218,239,219,134,117, 93, -205,107,190,179, 16,160, 6, 91, 88,245, 33, 90, 97,163, 32,159,100,241,219, 64,138, 73, 64, 49,138,252,238, 13,181, 13,232,144, - 3,108,106,227,186,156,241, 41, 70, 84,200, 84, 65, 91,141,214, 26,187, 77,189,240,128, 86, 26,217, 40,254,176, 90, 24,251,251, -188,239, 64,175, 76,130,171,230,172,210,162, 76,157, 47,253,216,241, 3,112,221,161,234,170,195,143,179,206, 25,229, 77, 53, 21, -120, 48, 13, 51, 62,129,218, 35,209, 13,187,173,191, 79,135,190,131, 67, 20,168,212,184,214,184, 47,247, 3, 77, 46, 69, 73,179, - 40,114, 41, 46, 3, 84,185,166, 98, 56, 41, 76,135,151,253,104,121, 6,167,105,206,121,196, 90,170,161, 31, 77, 48,224,130,189, -196,218,185,195,121,170,172,101,252,230,117, 68,113,176,188,168,218,207,192, 40, 57, 91,151,215,253, 8, 60,145,207,172, 35,171, - 5,129,135, 71,161,197, 74, 31,240, 14,134, 66,196, 32, 94, 87, 98, 60,245, 82,212, 48,150,156, 11,246,156,109, 23,111, 99,179, - 82, 40,148,210,209,136, 8,231, 52,221,168,240, 16,176,168, 60,139,234,237, 60,164, 86,248, 24,145, 8, 63,209, 17,118,224,158, -252, 56,186,237,173, 91,101, 90, 75, 6,226,225,208, 33, 96, 70,171,114, 57, 68, 59,247,242, 21,145,187,102,177,219, 72, 69, 29, -147,163,202, 18,216,183,213,200,105,141, 66,197,152, 38, 99,119,235,139, 51,205,146, 58, 38,190,244, 32, 59,202, 40, 8, 75,111, -233,110, 26,225,151,176, 60,253, 14, 94,221,110, 56,157, 38, 60,126,178,224,103, 63,252, 19,218, 6,101,199,191,109,155, 76, 74, -178,238, 28, 61, 60, 47, 83,225,189, 11,249, 76, 31, 90,101,204,171,106,210, 24,206,170, 90,175,197,178,237,153,168, 43,226, 55, - 30,236, 74, 35,236,228,198,235, 67,175, 20,187,224, 29, 69,118,210, 33, 76,167,133,119,134, 6, 7, 21,225, 32, 51, 75,185,146, - 46,167, 40,219, 66,129, 83,201,186, 71,204,128,210, 11,249,148,196, 52,227,124,243, 8, 33, 78, 40, 53,224,207,255,226,107,220, -222, 61, 71, 41, 29,123,233,184, 90, 78, 56,167, 29,174, 3, 79,175, 38, 60,122,124,131,235, 39,215,104,181,225,114,191, 33,120, -224,199, 63,249, 16,175,238, 55,124,239,157,103,120,247,157,215,132,202, 56, 37, 82,193,100,180,237, 99,192, 90,138,116,101,173, - 99, 78, 14,211,121, 70, 56,157,176,157, 22,132,109, 71, 93, 51,226, 20,112, 61,123,236, 95, 85,224,202,161,100, 48,228,199,161, -218,152,184,217,139,173,159,221,113, 47,219,213,126,217,117,106,213, 1,223,141,178,167, 98, 32,104,160,145,111,230, 99,142, 73, - 52, 40,137,222,253,105,154,176,173, 42, 58,149,164, 69, 80, 4,138, 94,205, 30,232, 29,184, 79,141, 8, 93,138,228,125,221, 48, -159, 70,174,132,171, 64, 11,221,222, 67, 79, 39,196,186,174,150,161,160,194,160,121,153, 81,234,133, 89,217,129,200,214,192, 92, - 9,118,123,209,161, 49,161,208,118,145, 65,118,169,226,171, 47,246,158, 15, 30,124, 52,160, 72, 43,131,250,229, 67, 64,203,242, - 1, 77, 76,135,243,206, 33,206, 19, 34, 83, 20, 99, 12,152,151, 9,243, 60,155, 55,252,116, 62,145,251,158,164,200, 45,213,236, - 98,149,217, 22,165, 8,147,163, 20,103,164, 68, 17,254, 73, 67, 19,210, 16,128,165,148,224, 67,194,188, 44,182,211,214,193,129, - 39, 44, 70,173,129, 98, 59,109,214,132,205, 44, 52,106,107, 40, 91,230,202, 67,132,173,247,247, 27,197,194,133,201,100, 21,219, -186, 31, 80,192,206, 20,228, 58,141,213, 76, 14,179,246,213,193,211,152,195, 68,191,127,182, 85,208,128, 12,141,110,247,152,191, -161,106,112,176,224,240,204,123,240, 78, 11, 3, 33,202, 73,198,185,140,235,213,250,215,123,149, 68,191,154,105,155,237,230,188, - 26, 43, 39,111, 20,118, 19,190, 81, 96, 55, 34, 93, 27, 80, 15,248, 86,189,192,155,198, 11,107,103, 61,212,236,120,208,157,143, -203,187,107, 10, 32, 84, 80, 55,246,234,181, 61,244,167,123,174, 9, 11, 83, 77,187,218, 40,221, 96,204, 43,159,164, 19,187,171, -236,151,218, 6, 24, 71,221,100,234,254, 10, 33, 32,194, 9,115,214, 7, 81, 19,235,174,163,247,134,170,149, 71, 3,122,205,150, - 12,134, 94, 37, 44,196,118,164,236,238,131,140,102,125,240,242,107, 58,238, 60, 88,149,212, 90,108, 4,219,154,103,247, 78,200, -131,119, 84,203, 86, 27,155,169,176, 71, 73,111, 49, 37,204, 11,253,139, 76,237,217,182,140,245,178, 98,223, 50, 5,105,149,244, - 42,207, 10, 88,186, 99, 23,228, 98,221,214,141,212,176,140,105,138, 88, 87, 25, 53, 21,170, 67,231,121,178,253, 99,151,183, 4, -205, 59,120, 23,108, 20, 34, 92,102, 32,239,170,112,167,112,208,113,197,224, 60,124,146,157,239,249,234, 44,169, 96,225, 97,186, -149,118,159,141, 30, 92,249,177, 96,112, 25,173,194, 42, 99, 99, 75,150,142,197,251,202,142, 32, 90,172,173,247, 2,254,232, 24, - 65, 50, 90,145,170, 45,194, 57, 79,138,155,140,128, 78,175,125, 23,247,171, 20, 89,215,143, 78,184,124,245, 75,228,109,165,138, -221,147,192,197, 65, 45, 99, 86,157,239,140,120,132,141,252,106,107,136,230,134, 24,158, 79, 56,245, 94, 71,138,223, 4,146,211, -109, 55, 68,200, 78,144,146,188,236, 59,153,226,145,207, 74, 54,216,142,163,242, 55, 26,195, 90,232,112, 67,196, 40,216,198, 24, - 84,129,223,152,174,229,152,119,159, 81,157,132,189,168, 88, 77, 86, 20,153,160, 37,160, 54,135, 52, 79,184,126,244, 20, 29, 1, - 64,196, 15,255,234, 5, 62,251, 66, 40,129,243,146, 16, 75, 69, 90, 78,168,104,184,119, 19,214,219,138,187, 79,111,241,122, 6, -222,124,227, 6,143,175, 34,238, 47, 25,239,189,255, 9,174,207, 19,126,239,159,127, 15, 33, 6, 76, 41,160,110, 27, 2,153,237, -189,117,164, 8, 4,250,184,247, 82, 81,111, 30, 35,190,243,171,168,205, 97,170, 25, 29, 13,201,157, 16,131,195,107, 79,207,184, -125,239,130, 39,143, 79, 38,190,106,165, 89,154,150,115,209,118,190, 15,105, 86, 50,114, 15, 12,187,108, 29,131,244,215, 20,164, -197,176,112, 46, 98, 29, 39,116, 29,141, 83,172,128,152, 24,126,225,100,101, 22, 2, 59,138, 14,218,154,132,201, 93, 25,230,161, - 68, 57,121, 95, 68,119, 51, 77,211, 33,139, 92,157, 17,157, 69,168, 36,205, 21,211, 6,200,103,148,247,221,224, 68,160, 78, 66, - 70,171, 2,197,106, 97, 76,146,148,149,209, 90,160, 38, 69, 27,133,106, 74,249, 52, 77,116,173, 52, 67, 41,151, 44, 69,200, 60, - 51,231,188, 54,244, 24,237, 64,119,214, 69,139,253,107,154,147, 1,102,148, 72,231,131, 39, 7, 95, 64, 47,105, 74,152, 79, 51, -208, 59,238,110, 47, 22, 83,188, 83,128,199,233,177, 48, 54, 88,148,128, 8,109,165, 26, 58, 42,237,125, 72,240,220,167,135, 32, -116, 62, 13, 53,170, 44,118,228,172,148,233,164,124,102,206, 66, 94,138,177,219, 11, 66, 0,106,145, 98,125, 91, 55,108,219,102, -171,167,109,207, 18,132,133, 49, 50, 14,196, 71, 71,186, 20, 52, 23, 65,133,107,157, 80, 28, 81,208,239,244, 75,215, 7,163,107, -221,253, 2, 35, 20, 71,173,198, 90, 52, 4,181,177,113,122,160,126,120,121,214,139,113, 12,180, 65,168,125,252,111,189, 54, 77, -255,209,117, 45, 9,158,177,149,193, 98, 92,243,246,142,230, 49,166,161,132,167,117,235,184, 49, 32, 48, 74,109,163, 53, 88, 69, -113,253,240,123,142,139,189,143,232, 84,186,191,218,131,127,174,243,143,193,111, 25, 43, 2, 45,170,245, 99,243,182, 58,232,180, -221,121, 22, 82,114,174, 37,101,218, 81,253,222,145,210, 66, 77, 67, 68, 84,111, 98,111,142,162,153,102, 59,166,166, 88,192, 48, - 56,191,186, 83,210, 17,123,171,133, 94, 99,207,177,142,140,209,244,146,143, 49, 80,188, 65,114, 22, 83,201, 74,145,125,159, 60, -196, 96, 18,145, 84,126,182,199,160,127, 87,124,171, 51,199,127,170,186, 23,161,145, 8,134, 10,187,135,194, 88,196, 66,242,155, -168, 49, 99,138, 6,116,112,222,163,108,187, 9,197, 90,131,169,198,209, 69, 9, 31, 56,110,210, 81, 76,219, 68,181,158,248,235, -232,200,195,170, 80, 18,246,132,131, 46, 59, 41,181,103, 36, 50,138, 29,132,202,215, 14,188,103,225,209, 51, 57,107,138,188,196, -162, 21, 38,146, 55,127,176,144,229,194,128, 20,201,164,158,151,161, 24,143, 73, 69,120, 30, 21, 69, 62,103, 47, 82, 22,209, 51, -116, 35, 85,165,211, 51,180,248, 4,117, 93,113, 58, 77, 88,166,138,159,255,228,239,200, 92,158,197, 86, 81, 43,189,242, 77,224, - 53, 77, 98, 35,187,217, 63, 48,236,126,244,220,202, 69,237,132, 40,231, 2,224,153,234,228, 60,224,154, 88,216, 18, 89,205, 94, -138,195,206,100, 38,169, 76,154,101, 26,171,224, 47, 16,158, 50, 77, 51,224, 58, 82,154,105,125,219, 31, 64,107,132, 20,181,161, -213,140, 16,147,100,215,239,155,133, 54,228,125, 51, 33, 93,183,116, 36,126,247,112, 72,193,227,116,245, 8, 33, 45,240, 33,226, - 39, 63,121,133, 23, 47,129, 39, 79,174, 13, 54,228, 67, 68,156, 18, 5,148, 13,251,186,225,242,209,231,120,254,245, 45, 62,253, -135, 79,240,108,114,120,177,101,132, 57,226,159,124,251, 77,252,202, 59,175, 65, 13, 3,113,142, 8, 97, 65,171, 29,209, 9, 36, -232,101,121,129,155,235, 19,182, 61,227,141,183, 94,147,238,174, 3,185, 22, 41,156,162, 67,108, 5,201, 55,220,222,109,104,117, -178,156, 6,141,223, 21, 6,255,176,144,170,136, 82,143, 57,111,169, 86,242, 25,121,117,151, 96,236, 75,189, 15,200, 69, 4,139, -106, 89,148,216, 83,134, 3,213, 62,162, 67, 67, 64, 8,130, 57,206,165, 34, 32, 90, 98,160, 22, 28, 57,239,216,209, 69,204,229, - 2, 90, 43,216,247,142, 24, 19,182, 77,214, 98,210, 37, 7, 19, 13,133, 24, 17, 3,164, 91,140,222,236, 67,128, 4, 28,229,189, -143, 41, 30, 15, 88, 97,218,187, 3, 2,185,195,149,138, 94, 69, 69,157,146,168,245,227, 36,106,227, 66,255,183,138,185, 74,238, -230, 28, 17,139, 85,146, 64,154, 92,198, 84,173, 57, 20, 62,231, 51, 33, 47,105, 74, 76,168,131,216,107, 83, 66,140, 17,203, 89, -176,172,167,243, 66,213,121,193,122, 33,238, 54,103,226,104, 5,198,212, 57,194,150,176, 42,216, 40, 91, 71,233,167,243, 66,205, - 3, 44,210,118,223, 55, 99,117, 0,130,129,213,116, 57,141, 71,213,164, 58, 31, 36,110,181, 86, 78,171,170,124,175,219,182, 97, -189, 92,100,191,207, 70, 6, 93, 28, 23,160, 63, 60, 96,146,180,182, 24, 13, 97,171,250,161, 66,248, 88, 35, 78, 92, 46,115,102, - 93,208, 78,236,120, 22, 42, 34, 53,248,177,242, 83, 24,149,234,154,130,235, 72,105,146,119,150,113,171,114, 97,203,101,158,247, - 13, 37,175,104, 45, 83,196,221,172,163,149, 6,177,216,109, 78,186,137, 53, 23, 77,199,233, 84,148,107,161,167,112, 33, 17, 13, - 87,168,199,205,238,190,166, 34,183, 62,242,206,209, 31,184, 70,154,195, 96,100,112,159,110,214, 54,117, 89, 28,199,242, 38,198, - 28, 68, 60,131,152,113,212,239,237,199,187,225,110,181, 80, 47,228,133,200,132, 89,196,115,193, 38,200,210, 12, 70,229, 7,232, -152,164,150,130, 56, 69,195,223,233, 94,163, 55, 94,220,222,163, 23,181, 86, 21, 38,152, 21,238,152, 59,186,243,135,216, 57,181, - 57,120, 99, 23, 23,138, 89, 40,209, 17, 97, 29, 59, 2,241, 44,139,130, 59,103,217, 23,136,218, 86, 62,160,243, 60,201,120,235, - 52,177,106, 13,204, 54,110,184,191,189,199,182,237,184,187,189,231,152, 8,244,245,137,130, 51, 77,137, 74,206,177, 43,144, 48, -130,136,187,219, 59, 76,115,196,190, 9,130,210,103,200,129,180,115, 28,232, 37, 96, 37,121, 1,231,108,171,170,167, 11,124,149, -142, 92,240,165, 14,123, 46, 12,156,168,182, 62,208,220,111,143, 78,159,115,163,248, 75, 14, 49,141,166,117,212, 20,132,200,189, - 17, 71,117, 62, 0,251, 42,144, 25,241,210, 70,230, 76, 75,106,149, 90, 50, 60,119,245,141,138, 90, 5, 88,152,125,195,195, 68, - 76,232, 1,243,211,239,224,213,237,138, 16, 60,158, 62, 59,227,211,159,254, 80, 84,211, 62,208, 34,232,105,151,216, 73, 53,138, -240,161,115, 20, 52,224, 64, 10,226,136,169,155, 37,100, 8,226,154,105, 47,228, 2, 15,118,152,186, 94,204,182, 18,102,134,122, -240, 32,237,135,170, 58, 77,145,251,243, 96,151, 59,200, 1,144,209, 59,171,105,122,107,189,138,159,106,198,186,238,134, 80,204, - 74, 27, 3,198,165, 24, 19, 2, 72,213,115, 30,167,235, 71,152, 79,103,192,121,124,244,241,142, 95,126,220,112,117,117,162,207, - 94, 94,230,249,180, 72, 81, 88, 41, 50,155,207,240,101,135,107, 25,119,155,195,165,122,124,246,245, 5,243, 60,225,219,223,121, -219, 94,224,114,127,143, 41,120,224,234, 49, 22, 10,127,122,107, 40,203, 11,204,203, 29,224,132, 14, 22,137,247, 45,247,130, 70, -141, 47,191,198,221, 47,126,137,242,245, 5,235, 37,155,218,213,244, 46, 60,144, 59,171,252,214,218,131, 32, 18,179,159,182,134, -198,224,160,170,157,143,186,123, 56, 10,245,166,206, 29,152, 76,112, 61, 2, 78,128,100, 74, 34,157, 77,169, 21,145,207,159, 67, - 64,233, 13, 21,222, 70,131,210, 29,122,244, 86, 16,225, 48,165,201,206, 5, 73, 62, 4, 80,164,200,206,187,188,179,232,193,220, - 12,141,147, 62,231,105, 71,244, 1,112,162,122,207,185, 29,196, 77,142,104,107,233, 10, 67,240,104, 44, 76,198,168,190, 99,154, - 60,122, 8,104, 81, 28, 38,222,203,254, 91, 16,206, 48,101,251,216, 83,170,115,167,114,194, 37,221,178, 68,124, 78, 36, 66,242, -249,140, 1, 87,143, 36,187, 92,216, 25, 19,139,155,138,187,219,149,154,152, 98, 13,129,126,238,106,171,148,119, 4, 8, 81, 58, -236,204,213,135,167, 86,163,183, 42, 66,102, 39,197,202,196,216,223,225,129,110,194, 87,144, 74,144, 34,193,130, 90,119, 27,249, - 3,192,190,109,216,168,205,201,202,160, 87,161,175,230,155,251,200,136,214, 1,144,177,115,140, 58, 11,163,110,238,114,209, 20, - 10, 29, 5, 59,221,208,115,167, 67, 70,191,155,110,224,173, 99, 20,105, 71, 71,138, 9, 33, 38, 76,211,130,105, 74, 60,166,187, -133, 71,249,184, 34,150, 25,235,253, 43,160,100,155, 64, 53, 84,139,115,181, 81,123, 31,152,215,163,210,220,222, 5, 12,103, 64, - 63,188, 43, 29, 35,180,167,211,226,170, 68, 63,103,176, 24,247,128,111,223, 91,183,100, 54,237,204,123,135,229,182,107,118,138, - 58, 5, 76, 36,215,135, 83, 72,139, 28,179,233,185, 49, 93,211,166,242, 65,150,187,115,135,196, 78, 24, 63, 66,159, 99,213, 1, - 68, 1, 48, 48,168, 35,203, 75,208, 74,102,116,166, 67,233,149, 9, 51, 85,236, 97,181, 73, 64, 70,101,104, 67, 27,129, 29,142, - 93,178,222,239,133, 15,103,167,120, 73,163, 11,101, 52, 2, 6, 30, 8, 62, 81,227, 17, 29,171,174, 66,149,102,154,102,120, 31, -132,199,173,130, 36,166,174,181,189, 98,223,118,236,171,100,225,186,126,196, 9, 50, 69,137, 99,150,105,153,177,222,111, 34, 68, -241, 1,189,107,152,193, 32, 62,169,143,186,247, 98, 36,164,188,239,216, 35, 19,144,104,197, 64, 15,168, 78, 30,138, 72,117,170, -116,225,133,153,196, 50,150, 87, 30,179,165, 62, 89,118,140,192, 34,156,107,182,123,138, 41,152,117,198, 19,172,146,247, 13,141, - 24, 80,217, 45, 55,219,157,169, 42,222,216, 0, 57, 91,232,134, 22, 0,170,135, 80,128,133,115, 14,231,215,191,139, 92, 35, 90, - 91,241,228,233, 21, 46,207, 63,196,139, 47, 62,133, 15, 84,142,115,127,214, 88, 80,105, 72, 64,171, 21, 62,121, 84, 62, 35, 42, -162,212, 74, 53,104,130, 22, 58, 16,104, 41,138,222, 44,123, 34,176,202,136,193, 1,144,188,227, 90, 50,234,222, 57,237,161,133, -199, 73, 84,172, 15,147, 40,232, 53,136,131,110,129,137, 5,158,238,229, 26,249,239,162,177,216, 70,138,156,166, 75,105,122, 29, -133,146, 50,133, 81,221, 70, 69, 76, 51,210,188, 96,185,186, 70,136, 19, 94,190,170,248,251,247, 87, 60,126,114,141,117,205,112, -193,217,103, 14,231,209,186,199, 20, 61, 82,242,184,190,154,208,219, 2,108, 23, 76, 1,248,244,249, 5, 87, 55, 39, 60,121,242, - 8,183, 91,195, 39, 95,222,227,113,170, 88, 92, 67, 63, 95, 35,222, 92,195, 47,147, 48,200, 29,112,223, 63, 50,188,102,107, 18, -176,216,247, 13,245,231, 63, 67,126,241, 18, 29, 5,174,137,133,175,213,145, 85, 96, 35, 95, 78,174,168, 14, 51, 43,140,138, 6, - 59,187, 10,207,131,191, 52, 30,138, 42, 38, 82,239,118,173, 50,205,170,170,244,110, 70,250, 66,111, 8,105, 34,129, 80, 28, 30, - 89,226, 29,237,189,209,137, 71,173, 99, 95,217,205,186, 33,133, 83,206, 59, 98, 18,129,165,159,188, 77, 15,192,149, 64,171, 29, - 46,241,204, 49,223,113,195,121,158,209,123, 65,103,161,223, 90,151,162,187, 55, 19,219,170,240, 46,166,128,142,132,245,190, 14, -114, 96,107, 8, 41,216, 59, 24,188,135, 79,204,173, 38,151, 96, 73,129,127,127, 41,196,183,203, 58,240,177,189,113, 37, 39,225, - 51,167,243, 44, 34,177, 46,246,220,232,188, 97,109, 5,176, 35, 86,187, 86, 10,214,251,149,163,101,207, 92,118,142,148,173, 17, -115,212, 13, 4,137, 2, 54,228,106,178,201, 67,171, 89,226,162,231, 40, 68, 79,254,152,231, 74, 45,239,178,126,244,193,155,192, - 56,231,221, 68,159, 42,140,188,220, 95,232,137,223, 13,121,173, 30,103, 33, 91,194, 44, 83,131,226, 57, 20,248,149, 35,243, 82, -138,196,177,106,199,202, 95, 71, 33, 71,122,107, 10,213,146, 43, 50,237,146, 7,233,196,214,171,141,133,119,173, 25,219, 54,138, -203,222,187,188, 99, 55, 55,112,104,240,175,191,134,219, 87, 47,241,226,171, 79,145,247,139,164,118, 66, 93, 22,222, 44,106,166, - 17,193, 0,215,244,166,192,162,192, 95,187, 62,192,124, 27,130, 70, 9,112,234, 65, 63,238,203,251,152,164,216,255, 7,198, 25, -200, 21,164, 5, 91,245, 54,148,238,102,151,235,227, 28,209,162, 98, 40,212, 15,127,158, 14,239,104, 13,228, 20,210, 52,167, 6, -196,145,115, 62,178,128,212,245, 65, 8,145,236,119, 56,187, 92, 44, 51,152, 68, 28,231, 27, 92,243, 18,107,154, 11,147,119,162, -141,186,117,174,175,209,157,154,213, 43, 25,192, 14,109, 47, 72,211,100, 30,233, 78,222,111, 45, 21,149, 29,171,116,168,163,195, -149,139,150, 10,119, 39, 93,209, 60,207,252, 53,228,162,200,123,198,229,238,130, 90, 50,238,239,238,169, 64,159, 88, 76, 80,137, -121,248,144,246,205, 33, 68,122,214,213,122,115,240,115,202, 75, 66,230,244,165, 30,176,123,226, 15,111,220, 87,232,223, 35, 70, -169,218, 11,187,149, 98,138, 90,144, 52, 21,184, 43,239,156, 60, 4, 0,193,162,102, 1, 73,183,242, 60, 68, 61, 93, 8, 2, 83, - 32,254,147, 10,237, 16, 39,249, 98,217,177,122, 50,240,117, 5,161,204,112, 9,224, 16, 59,140,250,123, 75,165,175,219, 57,196, -229, 9, 48,191,129,203,171, 21,167,211,140,243,210,240,179,247,254,134,150,195, 93,194,123, 64,144, 4, 1, 39, 50,222, 10,172, -208,235,225,161, 10,244,227, 15,161,135,142,183, 83,140,220,221,147,186,212, 14,233, 78,252,156, 74, 17, 20,174,100, 35, 69, 19, -252,233,190, 61,132,128,144, 34, 21,159, 2,175,136, 41, 81,201,158,217,113, 75, 32, 77,171,162, 92,207,155,240,255, 69, 8, 39, -159,131, 87,120,140, 15,162, 64,109,227,229,119, 78, 64, 64,203,249, 6, 64,192,190, 3, 63,250,235, 87,120,250,248,145, 92, 76, - 51, 25,211,236,226, 36,118, 55, 98,153, 35,166,228, 81,114, 5,220, 4, 92, 45,120,245,252, 5,154,115,136,222,227,245,215, 30, -161,150,138, 23,159,126,142,118,138,184,121,227, 53,132,229,140, 72, 21,176,111, 50, 50,189,172,114, 96,183,218,224,110, 95,192, -221,158,101, 31,212, 10,178, 11,200,151,130,237, 82, 17,231, 25,211,193, 1,162,160, 37,229,147,203, 5, 36,118, 27, 85, 76, 59, -210, 16, 61,237,108, 14, 34, 56,132, 35, 99, 95,119,138,220,249,105,158,180,119,226,243, 14, 56, 0, 59, 74,193, 52,205, 44, 88, - 15,202,121,123,125,100, 44,235, 56, 50,212, 32,149, 82, 68,125,109,105,103,144, 80,141, 16, 3, 34,173, 73, 34,204, 82, 74,227, - 24, 97,150, 86,144,210,132,109, 43, 72, 83, 68,201,149, 40,216, 60,146,197,246,140,105, 94, 40, 80, 21,102,185,136,237,226, 80, - 74, 59,103, 99,251, 48,123,100,250,196,173, 17, 97,145, 45,250, 0,143,141,171,179,214, 28,138, 31, 5,249,188,204,114,185, 51, -122, 89, 87,145,211, 36, 98, 54,116, 96, 89, 22,211,195,212, 90,113,185,187, 24, 49, 82,198,238, 94,194,113,104,231, 83,119, 77, -156,146,173,129, 58,188, 16, 3,139,140,236,247,125,231,248, 61, 90,225, 16,104, 55,189,191, 95, 5,212,164,153, 1,165, 96,189, - 92,104,127,237, 44,240, 4, 23,188,109,235, 88,153,114,140,123, 58, 45, 38,182, 82, 60,171, 62, 51,129, 80, 23,101,183,131, 29, -186, 8,213,156,217,186,148,252, 41,113,216,170, 30, 23, 91,233, 96,155,200, 57,100,145,198,100,205,139, 29,110, 71,222, 87,220, -223,241,223,243, 65,226,123, 67,128,115,103,132,224,113,186, 58,225,116,154,112,117,181, 32,120,224,179,143,127,193, 9,175, 51, -177,178,138,238,250,193,162,102, 5, 31,239,128,194, 51, 3, 7, 43,219,176, 57,214,131,178,253, 16, 97,221,221, 33,202,218,217, -186, 85, 11,201,110,113,172,236,218, 31,160,125, 15,151, 62, 63,151,110, 54, 59, 21,175,194,208,200, 90,244,168, 46, 70, 87,108, - 77, 69,235,186, 30, 32,139, 94,254,190, 35,230, 85, 52, 20, 5, 81,113,140, 1,144, 4, 46,130, 61,212,207,217, 27,140,236,166, -123, 21,221, 51,104,181, 22, 98, 96,152, 64,196, 94,154,133,145,212,218,224,226, 80,228,138, 20, 95,210,153, 2,189,153,186, 79, -210,238, 66,246,223,205,254,144,232,206,190,228, 16, 3, 69,214,205,254,115,185,191, 96,219, 54, 70, 23, 54,170, 74, 37, 5, 44, - 37, 1,102,192, 1, 37,111, 40, 69, 21,236,131,251, 45,214, 53, 73,157,210,142, 81,193, 22,219,186, 90, 69,165, 35, 45,207,116, -168,214,170,229, 71,171,130,223,133, 96, 73, 66,218,197, 40,138, 81,226, 89,195,131,184,192, 52, 79,246, 80,129,163, 40,171,178, - 41, 34,115, 0, 98,242,168, 85,198,234, 82, 40, 72,246,124, 99, 87, 15,227,244,219, 49, 11,117,162,122,231, 80,209,128, 48,225, -234,205,223,192,243, 23, 27, 0,224,241,147, 19, 62,124,239, 79,176, 93, 46, 68,114, 70, 86,177,206, 44, 74, 33, 70, 57,128, 56, - 98,242,220,231, 75, 62,177, 80, 7, 3,161, 36,141, 97, 19, 18,156,211,185, 30, 25,127, 55, 85, 71, 43, 2, 83,243,173, 29, 58, - 15, 0,249,156,167, 57,241,215, 97,162, 93, 16,117,176, 42,147,113,112, 56, 40,165,176,228,130,188,175,244,157,179, 42, 15, 51, - 73,153,178,214, 9, 41, 1,221,193, 37,125,150, 19,186,115,152,151, 51,124,156, 0,159,240, 55, 63,252, 10, 87,144, 53, 79,111, - 29, 19,100,212, 30,146, 36,233,165,232,184,195,231,247, 66,129,212,190,109,120,121,187,138,127, 58, 4,196,224, 49, 77, 30,168, - 64,243, 17,219, 94,113,251,234,130,240,248, 10,173, 20,204, 75, 68,221, 11, 10,227, 47,239,239, 87,212,109,131, 43, 59, 28, 3, - 54,242, 94,113,119,233,112, 46, 33, 63,121, 12,239, 63,166, 72,168, 25,200, 71, 19,160, 58, 15,230, 82,186, 5,244, 88,222,124, - 27,135,150,172, 88,120,232, 49,238,210,124,186,196, 34, 27,144,134, 16, 18, 77,103, 43,181, 32, 52,178,209, 29,200, 50, 8, 20, -157,241, 98, 8, 17,190,101,238,178, 51, 17,157, 59,166,121,226,158,180,154,176, 54, 80, 15,209, 49, 68, 75,219,150, 49, 47, 44, - 96, 41,236, 84,231,139,115,178,203, 85,192, 85, 41,149,128,171,110, 36,175,121,153,133, 55, 80, 42, 82, 8,104,149, 23, 84,140, -242,115, 27,208, 98, 71,168, 13, 62, 57,219,103, 43, 44,166,247, 97,173,170, 69, 86, 27, 49, 6,158, 37,201, 4,184, 34,158,170, -204, 47,151, 95,123,154, 23, 44,167, 5,128, 71,222, 43,110, 95,222,153,120,235,254,118,181, 6, 69, 14,108,201, 84, 79,243,108, -135,184, 94, 64, 34,192, 45,140, 41,173,150, 54,166, 24,217, 16, 34,246,189, 48, 21,210,141, 40, 79, 22,181,189, 87, 22, 4,149, -127,143,130, 92,118, 22,211,222,236, 84,145, 77,219, 60,207,163,248,161, 24, 43, 19, 12, 20,162, 7,138,164, 69, 11,184,171, 50, -128,138, 16, 32,222, 19, 50,133,109,150,178, 25, 98, 36, 95,126,168,204,189,174,109, 52,210, 85, 61,242,219,206, 85,179, 56, 58, -122, 43,104, 85,180, 3,151,251,151, 56,157,175,240,228,233,119,240,228,217, 19,113,227,160,225,246,213,215,184,125,249,181,156, - 73,212,122,106,174,251, 3,238, 0,207,148, 35,159,161,217, 52, 87,158, 47,229, 61,116,104, 60,234, 1, 58,115,252,111,149,166, -181, 81,120, 90, 23,222,241, 64, 9,175, 54,240,222,199,229,174,147, 66,117,102, 29,108, 99, 44, 22, 88,164, 48,173,109, 88,222, -134, 45, 47,240,159, 5,229, 5,144, 25, 2, 64, 86, 62,173, 99, 74, 19,162,133, 22, 48, 34, 79,125,223,208,108, 87, 50,212,199, - 37, 8,187, 76, 90,151, 11,223,194, 9, 52, 8,166,139, 13, 38, 78, 9,189, 57,162, 67,133, 8,164,137,103,145, 4, 28,253, 2, -212, 26,161,202,123,193,203, 70, 44,103,166, 31,205, 42, 56,147, 16, 21, 57, 12, 47,216,182,221,200, 90, 18, 65, 39,145,172, 33, - 6,233,200,171,178,115, 97, 41, 63,154, 76,164,190, 65,209, 7,236,220, 25,171, 85, 6, 28,111, 73,193, 16,252,200,175, 85,116, -163,115,170,224,142,156,110,116,204, 28, 57,229,156,197, 83,175, 65, 36,164, 42,169, 39, 93, 57,230,242,103, 22,255,126, 97,202, -155,136,158, 34, 98,242,128, 8,131, 49, 77,193, 60,186,173,117,120, 39,251, 30, 13, 1, 57, 6,236,121, 47, 29,149, 83, 28,170, -115,184,249,198, 15,112,119, 47,149,251,227,103,215,216, 95,126,136,151, 95,126, 98,235, 15,231, 27, 90, 21,235, 79, 76, 1,173, -209,219,218,187,196,212,118, 24,109,172, 51, 40, 33,120,143,238, 10, 25,225,146,157,172,127,119,239, 37,215,124, 95, 55,233,254, - 56, 38,111,252, 67, 26, 26,152, 47,193,196,110, 37, 16, 8,164, 62,233, 16,163,105, 34, 98,208, 34, 77,116, 13,101,223, 80,246, -203, 24, 51, 54,118, 67,132,251,128, 2, 42,231,147,236,223,188,106, 28,228, 37,153,150, 5,243,233,140,238, 60,126,250,254, 29, -246,151, 13,207, 30, 45,232, 81, 8, 79,167,105,225,136, 20,232,251,138, 9, 29, 49,157, 1, 82,216, 82, 12,184, 92, 54,124,244, -209, 23,114, 33,205,226,115, 14, 78,236, 81,126,185,150, 84,165,151, 47,208,251, 25,219,156, 68, 36,231, 37,170,120, 91, 51, 46, -235,134, 90, 27, 78, 75,194, 60,121,236, 89,244, 10,107, 14, 88, 91,199,253,158,209, 47, 95, 99,191,100, 56, 55,219, 97,208, 40, -230, 1, 1, 23,153,185, 4, 58, 45,129, 37, 57, 85, 59,128,164,136,174, 40,133,186, 5, 28,187, 8,189,236, 29, 28, 42,100,195, -162,232,216,227,206,177,155,165,201, 57, 25,137,235,174,184, 86, 79,103, 73, 61,128, 57, 24,102, 18, 24, 32,210, 59,178, 83, 43, -151,103,150,116, 51, 86, 68,201,217,198,210, 93, 3, 99,232,230,240, 60, 39,124,169,240,228, 56,236,219,142,121,158,113,190,230, -161, 22, 38, 99,101, 52, 22,117, 26, 90,210, 65, 70,125,109, 38,138, 82,173,134,185, 81, 14,201,105, 34,204,140,152,151,249,129, -174, 35, 38,209,153,104,247, 14, 4,220, 60,186,182, 92,247,109,221,144,247, 66,251,223,142, 76,182,123,103,134,131,171,157,133, - 78,103,195,226, 40,100, 99,144, 17, 26,188,107,135, 9,145,231,148, 48, 18, 58,195,174,178,201,143,175,151,213,206,169,146,171, - 65,132, 58, 21,227, 82,228, 6,198, 7, 59,164, 32,235,148,105, 74, 54, 10, 14,228,224, 75,196,169, 67,174, 21,165,116, 67,191, -234,186,160,150, 54,232,131,116, 13,181,131,197, 74,109,191,141, 65, 34,186, 34,212, 34, 83,113,170,181,102, 4, 31,228,210, 34, -150, 91,161, 56,158,223,127,107, 21,121,187, 71,154, 60, 78,231, 25, 29,205, 82,232,238,134, 55,218, 98,215, 53, 64, 75,149,235, - 99,216,127,216, 75,179,201, 16,114,167, 34, 96, 7,109,240,120,145,183,118,248,247, 15,226, 54,192, 61,236,214,255,127,254,123, - 48, 94,168, 84,111,132,205,244, 35, 23, 6,230,240,209,226, 86,239, 18,135,195,142,221,178,213,253,136,135,117, 64,244,209,214, - 76,145,161, 70, 81,129, 15,250, 71,239, 22, 10, 65, 53,117,224, 11,198,206,192, 57,102,102, 55, 65,224,117,102,155,119,227,107, -123, 56,200,254,105,207, 98,117,241, 32,206,144, 73, 59,158,130, 41,133, 34,216, 62,214, 57,179, 96,169, 63, 47, 4,121,121,196, -230,225, 44,178,114,223,119,212, 34,138,207,117,221, 41, 82,145,203,113, 91, 43, 98,170, 56,157, 38,230, 82,119, 67, 24,154,199, -146,120, 68, 29, 25, 5, 67, 90,202, 5,189,173, 82,249, 53,241,117, 13,202, 86, 63,242,239, 11, 46, 23,241, 70,251, 16,112, 62, -159,208, 93,226, 88,145,135, 5, 53, 2, 58, 74,118,102,219, 2, 63,175, 40,100, 41, 13,198, 49,193,219,225, 18,162, 88,201, 49, - 29, 45,112,180, 42,157,151, 23, 82,153,249, 20,157,137,222,208, 29, 90,169,152,111,222, 65, 11, 79,177,173,183, 72,115,194, 18, - 55,124,240,215, 63, 20, 85,188,227,195,205,138,175, 22, 81,156, 10,109, 79, 48,144, 37, 87,211, 34,104,101,238,204,238,193,231, -163,119,212, 61, 91, 70,114,239,192,190, 74, 32,132, 10,141,228,207, 69, 77,193, 33, 22, 85, 84,159, 36,252, 57,135, 24, 39,249, - 57,209, 15,157, 1, 45,105,141, 73,124,173,100, 1,199,212,108,187, 81,165,241,193, 7, 19,150, 40,240, 6, 78, 46,119,141,107, - 92, 78,139,236,138, 93,192, 23, 95,238,248,240,103,119,120,251,230,132,214, 61, 92, 8, 88,150, 5,240, 30,190,101, 96,223,224, - 29, 1, 70,193,195, 39, 57,132,214,187, 11, 62,252,240,115,108,219,142,211,146,240,226,229, 61, 30,159,103,120,116, 76,179, 76, - 31, 82,244, 8,139,144,237, 90,105,104,185,224,246,174, 99, 74, 30,175, 94,221,227,229,139,123,204,115,194,180,221,227,244,242, -107,248,173, 97,131, 71,116, 18,219, 90,187,195,118,159,197,107,110,221,200, 32,191, 73,103,226, 77,136,212, 9,166, 64, 31, 64, - 13, 41,194,178,141,192, 91,171,232, 33,201,207, 51,190,128,226,134,221, 16,122,226,184,203, 27,151, 93,140, 30,222, 69,155,148, - 72,250,153, 60,243,121, 31,112, 25, 67,208, 18,205, 89,107,166,114,122,128,157,142, 30,123,209,125,200, 69,170,171, 61,121, 79, -234, 67,218, 37,115,219, 91, 3,166, 89, 14,241, 90,154,117,254,231,171, 9,235,101, 67,245,141,133,120,151,117,130,119, 64,103, - 0, 76,230, 94, 56,140,238,249,184,107,118, 94, 10, 4, 65, 82, 7,195,219, 58, 47, 86, 47,177, 87,138,104,238,234,230,108,207, -219,182,237,216, 46,187, 20, 0,150, 69, 14,196, 41,209,149,227, 41,212,149,232,101,163,234,169, 30, 39,103,122,162, 71, 71, 57, - 77, 9, 62,242,249,233, 13,222,119, 97,129, 87,141, 6,222,185,122, 27,116, 49, 17,202, 30, 46, 26,126, 31,186,194,177,241,180, -233, 43,156, 33,108,149, 72,168, 86,229,135, 20, 62,177, 17,235, 89, 84,235, 1, 84,198,243, 83,253,210,224,121, 94,155,172,196, - 96,193, 56, 14, 49, 36,228,146,205,118,172,197,203,128, 77,137,206,227,155,239,188,131,243,245, 25,240,146, 16,231,204,225, 65, -193, 93, 31,103,114,240,162, 36, 87,144,217,209,201,245,144,243,223, 77, 69,175,227, 20,235,196,109,140,175, 32,171, 99,230,201, - 40, 16, 84, 93,255,176, 59,199,255,215,187,110, 81,221,180,240,161, 30, 46,115,111,161, 75, 29, 78, 82, 38,253,136, 53,215, 73, -167,179, 98, 41, 18,206, 54,138,107,189,232, 85,188, 78,161,156,202,252, 61,189,231,157, 10,237,110, 10, 80,165, 74,153, 48,193, - 75,182,172, 19, 92,130,133,135,196,168,251, 49,169, 16, 3, 69,120,150, 80,212,187,141, 13,101, 60, 61, 4, 61,226, 87,100,229, -198,189,121,140,163, 74,158,231,249, 65,108,159,120, 62,139, 88, 42,216,129,171, 77,140,147, 31, 27,167, 29,125,239,186,119,212, - 3,206,211,171, 43,108,225,106,201,107,178,191, 43,244,105, 38,243, 95,118,251,239,129,178, 45,200,146,109,157,197,246,214, 9, -158, 41,165, 34, 76,114, 64, 53,141,176,180,207, 81, 96, 58,194, 83,239,134, 6,236,112,136,211, 68, 48, 75, 50, 79,187,142,217, -188, 39,221,141,225, 48,162, 61,232, 20, 77, 56,212, 44,136, 68,193,196, 86,132,233, 26,215,111,253, 0, 95,124,126, 7, 31, 60, -158, 61, 93,240,203, 31,255, 7,180,186,163,230, 77,136,179, 78,186, 23, 31,162,196,236, 54, 33,209,138,216,110,188, 96, 21,149, -162,192, 72,189,133, 55, 74,151, 4, 57, 4, 98, 93,251,160, 16,106, 22,125,229, 40,157,251,163, 70, 1, 87,111, 21,241, 52,145, -155, 47, 54, 40, 77, 36, 82,177, 98,111, 21,123,173,252, 46, 11,214,251, 59,160, 23,234, 12, 38,102,111, 23, 68, 85,207,154,221, -201, 11, 99,129,227,225,202, 84, 60,239, 3,210,188,192,249,136,203,165,225, 39, 63,122,142,111, 61,185,146,203, 44, 4,248, 57, - 1, 81,138, 57,119,217,225, 60,163, 70,231, 51,194,114, 66,222, 51,182,117,199,103, 31,126,130,175,190,190,199, 91,175, 63,194, - 60, 69,124,249,229, 75, 60,125,250, 58,208, 59,214,203,110,158,216, 28, 2, 90, 46,112, 37,163,220, 53,204, 83,194,253,101,197, - 95,254,205, 7,184,180,142,215,174,174,240,116,142, 8,165, 1,181, 97,158, 49,198, 14,213, 0, 0, 32, 0, 73, 68, 65, 84, 3, -158,221, 76,120,121,151,113, 1,112,183, 55, 52, 31,109,191, 38,133, 95,183, 3,185,210,113,161,188,238, 78,239,106,107, 35,116, - 66, 3,119,244,240,105, 53,195, 35,193, 71,111,160,150, 16,188, 92, 28,117,131, 11, 66,214, 19, 79,249,100, 35,243, 49,246, 31, - 10,116, 31, 2,182,117, 69,239,162, 40,223, 55,209,212, 56, 23, 1,106, 32, 58, 71,178,189, 85, 84, 22, 28,219,186, 98,158,103, -179, 71, 85,218, 96, 51,173, 89, 50, 50,111,198, 30, 7, 65, 56,194, 93,223, 45, 65, 78, 15, 77,157,100,245, 46,161, 58,151,251, -157,107, 1,127,152, 4, 84,235,200,163,242,211, 1,250,127,189,105, 94, 58, 99,124,231,121,162,162, 61, 97, 90,102,139,144, 13, - 49, 97, 57, 45, 88,206,139, 21, 4,121,207, 67, 72,218, 28,246, 77, 52, 19,122,177,164, 41, 89, 64,144,188, 63,206,132, 97,106, -207, 29, 83, 24, 9, 49, 18,113,160,128, 94,228,172,131,128,144,246,140,222,138, 37, 71,230, 93,120, 27,189, 53, 91,145,198, 24, -225, 88, 8,169,176, 78, 19,210,122,235, 12,214,114, 36,133,102, 43, 24,123, 29, 9,107,154,100, 40,133, 65,179,174, 60,231,108, - 29,126,225,164, 84, 55,216, 50,189, 85, 24, 88, 53, 62,186,179, 46, 94, 16,185, 41, 77, 22, 59,172,237,113, 76,137,130,216, 5, -111,127,243, 27,248,198,219,111,193,251,136, 87, 47, 94, 81,223,148,113,185,220, 83,124, 7,203, 31, 23, 38,191, 20,222, 48,109, - 24,197,162,246,185, 10,149,242,144,157, 50, 38,224, 54,158,199,131, 98, 8,253,193, 79,131,238, 81,234,225, 18, 63,118,247, 15, -152,241, 15,254,153,195, 1,210,205,179,190,202, 74,208, 15,253,151, 18, 67, 37,117,209,153, 11, 75,213,238,234,150, 2, 57, 4, - 66,104, 61,188,195, 62, 32,234,190, 65,253,226,194,174,173, 67, 89,202, 75,168,181,253, 1,135,214, 42, 32, 30, 46, 49,140, 36, - 54, 21,113, 85,166, 45,149,194,104, 72, 30, 66, 49, 37,236,140, 13, 85,146,144,247, 50,214,218,182, 34,234,122,118,233,145, 17, -125, 90,181,106,119, 94,107, 21,116,106,201, 38, 54, 80,213,187,134,118,104, 42,146,247,142, 7,158, 51,149,184,122,208, 59,125, -127, 58,195, 9,138, 63,228,229, 85, 25,250, 17,117,245,208, 8,185, 64, 29, 35, 35,114,141,117,188, 84, 72, 61, 82,104,142,143, -145, 35, 64,170,187,167,201, 82,146,188, 37, 20,137,133, 48,250, 52,192, 6, 29,146,145, 78,133,116, 87,246,123,243,198,205,223, -247,140,152,252, 24, 47,249,145, 77,239,188,195,163, 95,249,109, 60,127,190,162,183,134,155, 39,103, 60,255,240,199,184,127,249, -229, 1, 59,216, 45,156, 64, 30,248, 96,127,182, 34, 55, 62,133, 57,213, 32, 54,242,107,119,179, 66,193,193,178,145,107, 25, 49, -160,232, 21,205, 2, 27, 4, 72,212,123, 16, 5, 60,169,131, 49,141,204,238, 64, 28,162, 87,100,111, 87, 15,110, 33, 10,120, 19, - 1, 92, 43,182,254, 8, 65, 94, 68, 31, 35,224,130,113, 19, 2, 87, 26, 42,250,172, 21,166,225, 72,203, 9,189, 75,164,240, 15, -255,252,115,188,123,115,194,213,121, 6,130, 71,117, 78,132, 95, 16, 60,102, 83, 43, 71,136,112,105,194,118, 17, 20,240,139,219, - 11,190,120,181, 97, 74, 1,111,191,253, 58, 62,250,240,115, 92, 46, 59,130, 15,216, 46,187,236,243,122, 71, 15, 30, 49, 84,192, - 3,209, 59, 4, 15,180, 2,124,242,233, 75,124, 81,238,176,162,224,229,171, 59,252,228,253,207,241,205, 71,239,224, 38,122,184, - 30,240,181,243,120,181, 55, 56, 70,248, 46,231,249,193,136,120,120,102,157,140,244,234,248, 62, 5, 28, 51,142, 19, 29, 55,247, - 17, 25,192,253, 96,177,189,179, 22,210,138, 29, 5,253,210, 42,166, 83,183,128,216, 20, 7, 45, 81,192, 36,100,148,187, 14,239, - 21,222, 36,151, 74, 46,217,158, 13,233, 4, 55,156,206, 87,134,132,149, 14, 48,144, 31, 14, 22,230, 99, 87, 43,131,132, 78, 26, -100, 98, 23, 40,156,127,245, 76, 59, 78,122,212, 65, 17,163,136,188, 12, 14,227, 37, 85,109,223,171, 37,143,201, 88, 24,199, 83, - 29,121,207,184,191,187,136,111,155,160,163,121,158,144,166,153, 76,247,132,171,171,179,113, 50,180, 8,112,222, 35,103,238,178, -171,126, 38, 14,247,119, 23,118,207,210,212,152, 5,142,144,151,105, 73,216, 46, 2,129,241, 14, 40,117,140,186, 3,211, 4, 67, -140,130,180,102, 39,143, 38, 23, 86,240,178, 31,150, 96,160,102, 33, 52, 90,200,121,254,153,170, 61, 47,162,205,225,224, 81,220, - 70,185, 96,154, 18,246, 61, 91,166,186,196, 11, 23, 91, 77,206,179,124,230,114,222,139,253, 78,254,140,206,252,211, 38,120, 52, -127,182,118,228, 35,253, 78,153, 9,114, 86, 70, 84,198,163, 46,167,197, 4,198,106,151, 60,159, 31,225,217,107,207,240,248,201, - 35,177,199,114,103,191,109, 59, 62,254,232, 99,249,188,124,176,245,176, 67,176, 38, 75,137,149, 96,241,169, 24,101, 5,207,140, -201, 19,237,233,118,129, 59,155, 48,142,148, 54, 60, 16, 83,247,127, 52,114, 55,213,123, 31,151,126, 59,142,241, 77,248,134, 7, - 29,247,131,217, 59,116,237, 66,129,121, 5,130,166, 28,187, 17,254,162, 90, 20, 3,192, 41, 1, 51,138,216,183,213,198, 59,200, - 33, 42, 92, 66,247, 30, 33,170, 88, 68, 58, 45,253,162, 68,253,156, 77,180, 81,107,149,164, 44,122,150, 85,205,172,149,181, 50, -220,139,198,115,122,111, 23,160,218,227,148,211,220, 85, 88, 87, 36,122, 84,196, 61, 30,105,154, 48,205,179, 41, 51,181,163, 45, -165, 96, 91, 87,238,212,133, 85, 28, 16,237,114,212,194, 71, 95,222, 86, 15, 57,192,135, 46, 91,190,103,170,101, 75,195,190,102, -194, 53, 34,186,111,198,216,213,240, 10, 73,254,138,168,156, 64,232, 72,103,154, 38, 76,147, 6, 74, 52,250, 74,189, 0, 29, 48, - 46, 91, 25,137,118, 19,251,216, 3, 65,136, 72,175, 98,141,211,131, 85,254,236, 90,149,131,121,235,253, 96, 33,226, 24,156, 81, -179, 62, 36, 50,215,165, 10,124,252,214,111, 98,205, 51,182,203, 61,174,174, 23, 96,255, 18, 47,191,248, 7,132, 56,193,183,138, - 82,181,163, 82,236, 43, 67,112, 58,198,248,223,199, 17,214,192, 82,214,199, 64,106, 91, 69,115,213, 18,188,100, 95,214,200,124, -231, 84,131, 43, 19,112,236, 45,206, 7,173, 93,163, 64,130,186, 40,159,133,160,229, 81,246, 85,114,218,153,175,222,106,182, 98, - 65,208,165,139,197,119,182, 46, 54, 37,121,142,101,218,160,171, 1, 64, 10, 77,110,103, 17,227,132,144, 38,234, 55, 28,222,251, -219,175,240, 43,167, 19,190,241,244, 6,185,119,116,239,249, 82, 22, 76,222,163,247, 29,253, 36,194, 36,132,132,198, 11,246,238, -238,130,143, 63,250, 28,247,247, 43,190,255,107,239,192,135,128, 79, 62,125, 46,150,201,222,176,174, 25, 30,157, 4,125, 15,135, - 0,212,138,187,187,138, 57, 56, 4,191,227,197,151, 47,177,162,160,161,225, 5,118,252, 79,255,254, 61,252,179,111, 63,195, 27, - 79,207, 88,150, 25,207,174,100,255,254, 55, 47,118,124,121,183,225,219,239, 46,136,177,218, 1, 62, 84,178,237, 97, 0,132, 90, -130,208,108,236,168, 29,224,145,188,165, 40,223,222, 10,186, 75, 82, 72,115,135,238, 41, 96,108,173,195, 71, 41, 10, 34,121, 1, -154,207,160,239,152, 38, 68,137,239,217, 25,234, 57,166,137, 98, 58, 47,234, 92,237,230,168, 95, 57, 90, 50,211,196, 21,128, 27, -201,128,154,240,168, 80,144, 72, 90,165,104, 44,165,243, 60,157, 38,204,167,201, 50, 3, 6,230, 90, 14,206, 52, 37,203,155, 22, -190, 5,108,220,157,247,204,110, 93,254, 14,226,231,222,233,203,239,152,167,136, 56, 69,164, 24,145,216,173,159,174, 78, 7,134, -194, 68, 26,162, 27, 25,229, 45,216,190,243,238,246,222,210,185,146,151,252,137, 72, 96,205,188,204,204,135,168, 98, 15,227,237, -209, 14,137,104,242,156,143, 11, 93,167,154,133,129, 68, 56,112,197, 91,173,216,182,125,216,137,187,116,124,106,235, 75, 83,160, -200,212, 25,230,186,214,134,105, 26, 4, 59,160,161, 86,119,112, 33,117,201,181,231,223, 1,132,193,148, 90,237, 51, 61,218,188, - 90, 27, 5,201,136,130, 29,249, 15, 58, 98,214,207,204,181, 97, 73,148,231,160, 99, 89, 22, 60,121,242, 24,167, 43,121, 7,124, -240,184, 92, 86, 4, 15,236,251,142,175,190,248, 18,175, 94,190,176,125,185, 62,215,218,209,194, 34,187, 3,121, 12, 3, 34, 51, -110, 94,247,160, 75,239,255, 88, 20,231, 48,240,201,135,159,163,255,231,216,229,247,195, 91,213,143, 12,123,224,193,250,239,232, -149,255, 71, 18,185, 67,103,223,236,223, 86,236,182,166,130,170,157,215,126,117, 54, 86,138, 25, 15, 1,180,198, 82,168, 91,109, - 95,234, 80,217,161,169,104,166,213,106,105, 78,106,121,201, 76,240,138,211, 68, 53, 56,247,114, 52,227,203,232,169,161,119,111, -126,186, 97,145, 51, 15, 9, 15, 34, 57, 44,154,229, 63, 7, 27,141,203,200, 43, 90,197,172, 73, 55, 42,206,216,182,157,135,131, -216, 74,106,169, 82,229, 80,209, 90,139,160, 89, 5, 67, 57,114,134,115,206,220,229, 74,161, 81, 74, 19,106, 84, 17,127,168,138, -192,244,129,155,166,153, 47, 85, 49, 37,113,136,105, 8,149, 32, 98,151, 99,180,168, 98, 29, 61, 1,251, 37,139,154, 61,166,136, - 64,207,170,118, 59, 80,161, 70,147, 96,151, 78, 91,144, 70,136,246, 94,153, 61,191, 91,102,125,136,254, 48, 18, 18,177, 92,208, - 46,142,227,184,235,215,222, 69,155,222,196,203,207, 94, 72,103,147, 50,190,120,255,175, 81, 43,237, 79, 76,156,115, 83,224, 72, - 31, 40, 16,164,111, 80, 22, 49, 11,156, 68,246,181,163, 60,183, 55, 17,125,168,157, 74,188,175, 13, 49,200, 88,183,183, 10, 15, - 41,194, 90, 45,112,221, 67, 85,113, 21, 35,106,182, 22,185,112,211, 60, 27, 98,178,150,141,113,148, 82, 16,238,219,166,172, 91, -137,233, 44, 25,141, 7, 65,175, 69, 42,108,118,130, 71, 49,139,116,252,144,233,192, 49,197,138, 94,233,143, 62,218,225,110,129, -111,126,235, 70, 52, 17,181, 35,206, 18,218,179,255,191,124,189,201,179,101,215,121,229,183,118,123,206,189,239,189,236, 1, 36, - 0,162, 33, 1,144,128, 36,146, 18,169,170, 82,201, 97,107, 80,161,145,135,246,196, 99, 15,253,151,217, 30,217, 81,170,112,184, - 34, 60,144,100,135, 74, 46,135, 90,146, 2, 8, 18,109, 38,178,125, 47, 95,119,239, 57,103,119, 30,124,205, 62, 55, 1, 22, 71, - 32,144,249,218,115,246,254,154,181,126, 43, 21,192, 20, 44,137, 10,159,182, 95, 16, 91, 65,137, 27, 44,112,248,228,147,175,176, -219,207, 56,222, 14, 56, 30, 35, 46, 79, 47,241,229,151,143,177,241, 6,184, 56,199, 50,140,112,155,141, 90, 85,114, 74, 64,153, -225,246,231,216, 47, 51,242,156,241,151,255,207,111, 49,131,158, 69, 15,131,255,156, 95,224,111,127,245, 24,255,245,207,222,193, -208, 50,154,113,248,224,181, 35,140, 22,248,139,223,204,152,103, 17, 62,210,170,164,212,198, 59,191,214,211, 18,219, 74,228, 37, - 93,133,238, 16, 87,225,124, 13, 43,148,111, 69, 69, 2, 16, 84,172, 90, 43,219, 5,107, 33, 32,140, 78, 8, 42,239, 43, 41, 79, - 64, 68,173, 57, 51,101,146,189,214,116, 16, 97,165, 95, 1,114, 77, 8, 54,178,254,162,103,116,151,156,212,101,209,216,219, 43, -123,231, 34,121,246, 92, 85,167,196,130,201, 24,225, 74,101,183, 73,207,118, 23, 10, 92, 45, 13,195, 16,217,197, 65, 33, 72,203, -156,216, 81,209,214, 33,133,186, 31, 45,156, 11, 81, 56, 69,207,249,192, 34,185,136, 24, 35,177,222, 3, 21,190,195,102,212,212, - 63,217,255, 75,184, 77, 75,133, 11,126,172,172,147, 22,199,199, 35, 31,214,100, 13,150,100, 76, 84, 94, 49, 53,234,164,235, 92, -116,247, 45, 65, 78,114,118,241,124, 81,183,191, 68,238,204,216,237,246,188, 34,115,204,151, 16,112, 10,219,146, 89, 51,100, 87, -103,175, 82,206, 90, 31,217,183,131,200,209,170,107,133, 82, 8,221, 93, 91,183, 38,210, 61,209, 3,167,196, 33,208,217,232,130, -131,229,209, 63,131,137,100, 2,228,131,215,206, 50,198,128, 27, 55, 78,176, 61, 58,194,246,104, 75,105,139,173, 97,158, 22,238, -210, 27, 46, 47, 46,241,228,241, 55, 90,116,148,146,168,249,224,166, 80,158, 69,180,134, 92, 22,110,160,202, 33,160,109, 29, 4, -246,242,229,252, 82,103, 78,223,230, 33,112, 6,223,218,173,119,191,122,123,249,131, 98,253,121,215,139,117, 28, 92,238,235,120, -227, 67,191,186,164,140,242,212,156, 27, 45, 90, 79, 67, 51,225,101,207,174,105,136,181,194, 91,233,142, 18, 11, 24,188, 65,206, - 43, 53,188, 16, 42, 26, 14,133, 54,165, 40, 25,167,213,194, 51,126,142, 91, 69,183, 49, 72,245,152,185, 0,168, 60, 26, 50,134, - 98, 92, 75, 33, 80,138,105,125,111, 67, 68,163, 64,234,210, 49,194, 26, 82,180,231,210,224,189,101,134, 55,239,211,121,103,110, -120,119, 38, 76,107,233,204,187,255,153, 20,166, 78,118,118,150,252, 11, 42,208,107, 56,136,128, 21, 16, 5, 17,167, 60, 33, 38, - 1, 5, 68, 16, 16,197, 34,114,197, 78, 33, 43, 94,125,150,134,169, 97,116,211, 85, 22,173, 17, 68, 67,184,205, 62,120, 58,240, - 27,119,232, 96, 97,156,115,188,107,151,248,213, 2,235,131,130, 52,100, 63, 74, 17,175, 77, 47, 49,170, 96, 13,134,227,187,216, -220,125, 15,207,158, 92,194, 89,139,147,147,136,139,135,255,132,101,158, 20,151,235, 25, 49, 88, 42,253, 29, 99, 45,252, 16,217, - 75,107, 20, 26,195,165, 63,199,197,130, 59,113,168,189, 8, 85,190,246, 78,118,170, 92, 33,211,104,210,113,246,121,229, 93,101, - 31, 97, 81,209,206,202,120,211, 15, 10,226, 10,164, 21,114,215, 41,227, 93,198,192,242,220,146, 87, 62,107,144,140,140,239,181, - 50,150,209,159,115, 24, 54, 91,184, 16,113,122, 58,227,203, 47, 39,252,240,213,155, 40, 48, 24,189, 69,220,120,216,224, 48, 47, - 25,155, 49, 96, 89, 10, 2,135,201, 68,103, 16, 76,131,157,175,241,197,211, 61,174,175, 39,212, 82,113,255,149,219,152,150,130, - 39,143,207,112,118,126,141,237,205, 17,118,190, 6,120,133, 83, 76, 67,219, 37,216,235, 51,212,121,135, 92, 50,174,246, 9,127, -249,143, 15,241,127, 77, 79, 0, 0,127,234,239, 98, 87, 27, 62,171,123,252,135,127,124,128, 31,189,115, 23, 71, 71, 35,230,185, -162, 26,131, 59,219,128, 63,127,251, 6,254,230,209, 21, 30,214,140, 87,238, 57, 24, 75, 94,118,249,121,172, 61,174,235,147,201, -172,196,175,221, 70,211, 14, 60,230,141, 65,228,181,102,152,210,148, 90, 88,106,134,107, 65, 59,141,200,161, 37, 26, 96,196, 5, -132,119,142, 16,207, 76,157, 75, 60, 34,244, 33,178, 56,175,160, 53,193, 24, 19,103, 60,132,168,235, 20,177, 22, 89,158,208, 9, - 68, 69,198,240,116,214, 0, 33, 90,165, 63,162, 25,248, 24,148,145, 77, 59,121,199, 74,236,166,171, 50,235, 28,156, 23,218, 24, - 93,118,180, 10,172, 88,150,196,180,201,218,215, 15,134, 26, 4, 73, 91,243,129, 4,114,227,118,163, 30,117, 51,176, 15,223, 91, -108, 70,162, 0,230, 92,123,246,129,165, 2, 98,158, 72,200, 43,174, 14, 24,139, 48, 56,246, 48, 23, 21,234,201, 37,149, 83, 34, - 59, 48,107,109,176,162,226,181, 10,254,254,200,170,152,150, 2,152,134,105, 90,180,217,138,172,195,161,233,106,101,103,130, 67, - 45,141,155, 34,116,107,241,138,240, 38, 2,219, 36,145,176,171,169, 14, 89, 52,121, 21,130,166,162, 85, 18,255, 73, 28,179,211, -209, 59,173, 97,253,129, 64, 77,254,190,172, 43,214, 4,187,237,118,131,147,147, 19, 28,159, 28, 35,142, 17, 67,140,156,250,151, -121,199,111,144,151,140,103, 79,158,224,252,197, 41,173, 84,188,103, 52, 50, 61,203,146,184, 39, 54,215, 90,179, 94,221, 70, 7, - 88, 29, 48, 99,190,181, 31, 63,220,153,191,172, 96, 55, 42,156,123,233,207,190, 52,130, 95,239,213,213,131,254,210,104,236,192, -201,246, 82,215, 46,227,121,114,186, 91, 46, 84,140,226, 98, 53, 41,142,139,120,107, 45,114, 73, 42, 40, 47,133,215,189,104,240, - 70, 46, 66,235, 80, 82, 66, 3, 85, 79, 61,210, 77,148,128, 22, 46, 68, 14,162,175,250, 75,164,203, 90, 22, 20, 78,155, 79,201, -112,150, 7, 86,162, 18,141,236, 2, 77,213,144,122,169, 92, 5,251, 71,223,135, 83, 81,137, 2,110,106,195,245,126,198,238,122, -162, 10, 54, 23,189,204, 83, 74,234,233, 36,152,139, 91, 97, 31,173, 86,158,132, 80,133,174, 8,200,203, 9, 13,110, 80,129,155, -235,163,167, 86, 42,226, 48,240,152,107, 62, 72,108, 11, 49,114,236, 33,253,160,135, 72,170,226, 24, 3, 77, 58,106, 57,124,177, -106, 67, 42, 11,237,195,231,121,245,184,241, 8,210, 81,188, 45,117,248,236, 45, 54, 44,232, 22,197, 57,143, 63,229,251,107, 45, -243,126,168, 34,140, 71, 56,185,255, 17,158, 62,190, 68, 90, 18,110,222,222, 34,159,255, 6,251,171, 51, 18, 97,112, 32, 11, 93, -116,158,158, 23,227, 57, 14, 52,114, 97,212,180, 80, 17,106,149, 28, 16,214, 25, 52,203,145,157, 6,128, 64, 78,196, 35, 90, 13, -143,247,196, 38,222, 69, 43,165, 54,212,156, 16,152, 91, 76,249,176,164,171, 40, 44, 66, 44,181, 41, 76, 70, 60,211,164,187,224, - 30,165, 9,137,140, 5, 47,205,232, 62, 74,198,134,228,249, 4,167,180, 21,248, 16, 21,241,154, 82,195, 47, 63,222, 97,123,116, -130,179, 57, 3,209,163, 6, 96,219, 26,236,146,225, 0,148,148,129, 37,193, 91,139,205,134, 20,202,121, 94,240,240,217, 37,126, -253,217,115, 76,211,130,215,238, 28,227,230,201, 6,203, 82,241,245,131, 39,152,150, 5, 71, 55, 94, 65,185,113, 15,126, 28,144, - 51, 61, 87,241,226, 25,236,114,133,101,169,120,118,182,195, 95,252,250, 11,124,130,107,220,192,128, 31,187, 27,248,111,255,248, - 7,120,126, 57,227,127,249,197,231,248,228,242, 10,159, 61,186,196,107,119,233,197,245, 28,136,116,103,180,248,239,126,120,130, -255,240,201, 57, 30,213,140,215,238, 17,245,144,200, 88,157, 39,109,180,136,105,186,175, 38,155,223,225,129,180,102,123, 41, 18, -182,102, 84, 99, 96, 87, 25,209, 36, 36, 53,157, 78,104, 45,123,145,171,170,239,141, 21,122,159, 57,176,187, 97, 21,197, 12, 14, -135,129,231,203,218,210, 84,174,228,132,121,182,138, 57, 14,108, 7, 5,143,230,117,181,192,171,149,186,178,165, 58,158,136, 45, -115, 66,240,192, 50, 39, 12, 35, 21,211,203,146, 48,110, 28, 79,209, 40,199, 28,236, 54,161,131,170, 34, 14,129, 71,255, 30,243, -180,104,182,182,243, 52,153,242,129,232,149,199, 39, 71,196, 37,143, 97, 5, 59,129,146, 40,133,163, 81, 74,197,156,102, 26,131, -243,249,145,109,134,133,101,134,123, 85, 2,103, 45, 21, 37,149, 21,123,157,120, 3,100,143,131,170,187,133,184, 38,171,182,131, - 36,177,146,117,138, 39,129, 43,210,205, 16, 47,222,161,228,138, 56,196, 46, 2,171, 5,165,242, 26,179, 18,163,191,228,194, 59, -117,114, 31, 8,155, 96, 78,137,195, 94, 90, 79,119,171, 64,225,253, 47,229,125,116,123,101,159, 2, 53,253,253,135,224, 84,141, - 47, 41,140,149,167, 48,183,110,222,194,173,219, 55, 89,183, 48, 32, 68,113, 29,205,204,152,207,152,246, 9,167,207,158,225,242, -242, 5,113, 46, 76, 83, 54, 67,169, 69,167, 17,228,242, 40,189, 99,127,233, 25,111,171,125,118,107,223,186, 87,187, 72,121,213, -173, 31,248,208,191,221,220,119, 11, 49,214, 23,122, 59,216,189, 31, 20, 22,191,163, 75, 63,252,184,135,125,187,164,221,209,231, -145, 41, 7,175, 74, 42,241,223, 69,139, 64, 95, 51, 11,214, 75,150, 40,207, 0, 15, 3,235, 29, 7, 3,244,246, 31,134, 0, 14, -105, 89,244, 50,168, 92, 21,211, 24,138,170, 79,235,186, 32, 73,178,129, 37, 63, 87,126,177,146,138, 99,157,165, 16,121,126,136, -164,227,144,125, 92, 12, 1,113,232,254, 80,181, 48,176,141, 35,229,172, 65, 42,173,210, 56,157, 94,120, 22,196,201,174,138,211, -207,114,206, 60, 54, 46, 60,113,160,138,136, 46, 51,199,193, 8,149,129, 26,116, 48, 56,141,221,235, 49,160, 20,112,144, 16,130, - 87, 86,177,143, 1,227, 16,153,215,139,213,126,143,195, 66,100, 55,197,156,103,199, 93,183,116,167,142, 69, 59, 50, 49,200, 44, -234,179,140, 88,148,152,190,102,235,161,151, 82,190, 63,129,134,248, 1,119,222,250, 49, 78, 95, 36, 44, 75, 66, 28, 2,230,243, -175,113,241,232, 11,237,230, 13,219,113,106, 17,254, 48, 19,183,184,232,114,222,195,182, 70, 99,124,231,153, 18,232,120,252, 13, - 24,166, 67, 97, 85, 49, 90, 70,129, 90,231,209, 80, 84,163,225, 66,100,232, 12,125,173,235,173, 82,109, 0, 88,161, 47,170, 86, - 41, 4,105,228, 71, 95,107, 97,104,134,234, 12, 44,115,161, 11, 9,237, 12, 35, 18,201,235,159, 21,164,210,120,125,226,124,192, -230,228, 6, 98, 28, 96,156,199, 47,255,229, 2,113,188,129,241,100,139, 90,102,156, 78, 21, 87,203,140,109,116,112,181, 98,176, -192,224, 45,198,232, 96, 98, 68, 25, 55,200, 41, 99, 87, 2,126,241,229, 87, 56, 59,189,132, 1,240,238, 31,190,143, 33, 4, 44, -211, 14,223, 60, 62,131, 65,195, 59,111,191, 6, 27, 7, 94,113, 84,180,221, 21,112,117,137,150, 51, 30, 60,185,196,255,241,245, -215,120,138,132,239,225, 8,255,238,205, 55,113,239,198, 6,173, 1, 55,183, 3,238,251, 1, 95,229, 9,191,122,240, 2,112, 30, - 49,120, 68,103,209, 92, 0,150, 9, 49,101,252,209,107, 35,254,207,211, 29, 99,150,237,225, 8,181,245,220,115,193,118,182, 90, - 86,243,246,195, 99,164, 27,120,250,134,182,150,133,132,141, 32,158, 2, 37, 46,123,253, 61,155,213, 32, 64, 66,121,132, 87,144, -114, 81,245,181, 81, 47,173,103, 20,178, 3, 76, 85, 97, 83, 85,119, 73, 97,222,192,162,232, 85, 48, 62,182,178, 95, 87,194,171, - 26, 26,156,233, 99, 74,154,186, 25,108,182, 27, 94, 73, 81,177, 1, 22, 93,166, 37,233,187, 76,108,244,181,245, 74, 20,242, 94, -167, 3, 21, 21,209, 70,181,144,141,155, 72, 32, 28,107, 59,113,141,133,186,141,167, 21, 46, 16, 98,117,222, 39,157, 0,164, 57, -169,152, 81, 68,194,198, 0,227, 54, 34, 47,153,254, 28, 91,105,133,195,111,189,135,231, 29,170, 88,179,150,148,117, 90, 42,186, - 25,234,220,105,170,210, 84, 36, 9,134, 66, 53,190,132, 25,216, 99, 13, 76, 48,202,157, 23, 43, 94,173, 5, 11,235,144, 42, 59, - 1, 68, 72, 76, 0,175,204, 19,141,172, 14, 20,199, 54,101, 82,153,187, 21,181,173, 29,228, 12,120, 47, 52,209,170, 58, 7,153, - 24,120, 78,201,220,110,143,176,217,142, 56,185,113, 76, 83, 77,239, 84,192, 58,237, 39, 45,104,246,187, 61,158, 62,126,140,121, -222, 51,173,142,238,146,222, 21,247, 92,115, 1,206,200, 74,101, 93,196,154,131, 43,252,219, 79,125, 95,183,115, 71,254,173, 33, -250,234, 13,105, 43, 23,216,119,205,241, 33,231, 28,193,157, 76,251,150, 0,254,176,160,126,249,159, 87, 19,250,134,254,185,136, -155,105,117,106, 32,162,214,218, 10, 28, 11,189,169,177,161,194,201, 67, 21,208,134, 15, 85, 6, 60, 48,165,136, 8, 14, 92, 29, -251,128, 82, 37,237,140, 98, 10, 43,239, 72,105, 44,148, 16,199,141,238,190, 41,133,173,104, 2, 13,169,189, 41, 96,161,180,140, - 16, 7,222,161,247, 17,161,144,204,198,205, 72,187,242,194, 84, 29, 75, 15,236, 60,205,152,246, 51, 67, 77, 44,230, 57,227,232, -104, 64, 75,132, 1,116,204,117,151, 23, 97,220, 12, 10,247,151,159,162,101, 97,135, 53,116, 32, 46,169,118,107, 0,103,176,139, -200,164, 72,116, 35, 87, 98, 5, 29, 28, 99, 88,140, 67,121,235,128,183,142, 58,118,241,109,215, 10,195, 63, 71,203, 59,184, 6, -192,106,158,110,239,114,101,124, 60,207, 73,211,118,168,170,182,170,100,165, 29,117,225,167,144, 60,189, 68,252, 34,193,223,173, -215, 63,196,197,149,193,213,197, 53,140,179,216,248, 29,158,125,253, 27,194,198,242,239,131,239, 0, 14, 93,225, 81, 42,172,134, -237,200,122,164,153, 74, 49,161,141, 14,230,214,152, 4,199,211, 6,107, 72, 73, 43,191, 63,195,182, 50, 58, 0, 28, 80, 45, 11, - 31, 29,114,170, 40, 53, 3,181,194,135,129, 1, 51,244,240, 22, 22, 14, 10,128,199,112, 36, 43,173,117, 58,101,169, 50,236,133, -126,111,196, 77, 64,163, 0,158, 16,163, 70, 76, 58,197, 3,211,250, 99,123,116,131,105, 75,192,195,111,246,184,220,121, 28,223, -220, 32, 12, 30,117,105,168,105,198,229, 62,225,217,179, 43,132, 96,177, 29, 60,110, 29, 69,140, 48, 20,199,105, 2,246,185,226, -175,254,211,199,248,242,193, 51,204,211,130,127,245,147,247,240,234, 43,183, 80,114,193,139,211,115,188,184,222,161,181,138,237, -232, 17,189, 65,202,172, 62,190,190,196,110,183,224,227, 47,159,227,255,190,120,138, 2,139, 15,112, 3,127,246,222, 27,120,227, -206, 49, 21, 39,148, 96,131,239,191,122, 11, 15, 30, 62,193,131,211, 61,222,121,189, 98,202, 84, 56, 14,150,208,179,187, 84,113, - 52, 58,196,214, 71,114,140,141, 65,213,248,235,151, 46,116, 57,170,204,170,250,111,223,181,211,235, 61, 2,165,220, 69,142,186, - 13,218,213, 73, 34,154, 18, 22, 43,239,245,217,197,176,238, 46, 26,147,216, 90, 35,130, 36, 88,189,108, 28, 86,127,159,253,207, -185, 32, 91,194,143, 6, 88,216,232,180, 83,111,149,221, 53,168,122,240,235, 37,210,122,128,133,172, 12,140, 17,123, 45, 65, 82, - 54, 71, 86, 5,119, 20, 31,219, 79, 77,183,202, 66,246,206, 33, 55,192, 71,143, 24,105,143,238, 3,105, 12, 44,251, 99, 41,120, - 38,235,231, 83, 14,133,248,137, 89, 61, 47,226, 85,199,226, 47,141,178, 93,157,113,198, 2,105,159,244,223, 53,238,196, 50, 79, -180,114,106, 76,179,243,172, 3,202,218, 73,146,199, 31, 42,112,155, 38,182,176,214,138,121,201, 4, 64,226,189,245, 60, 37,141, -144, 94,230,164,231, 82,173, 89,189,254,133, 5,167, 37,151,149,234,189,162,228, 74,216,106,239,213, 6, 40,194, 67,121, 15,251, -244,211,112, 28, 47,212,245,195, 81, 23,240,158,154,159,227,147, 35,118, 16,144, 77,153, 46,121,175,176,179,221,245, 30, 97, 32, -109,212,233,243,231,184,188,184, 80,126,125, 79, 57, 19,120, 77, 82,219,180, 42,218, 87, 93,120,143, 67, 48,135, 93,187,162, 97, - 15,247,233, 7,227,243,223,101, 83,107, 56, 8, 87,249,157,183,243, 1,127,238,165,105, 88, 51,122, 13,225,191, 52, 53,195, 97, - 28,172, 88,135, 9, 9, 44, 43,102,190,228, 91, 81,174,126,229,169,156,111,124,168, 36, 81,169, 27,242,192, 26,217,135,218,198, -176,127,182, 8, 48,129, 13,165, 87,172,100,132, 3, 71, 65,102,238,170, 86,223, 32,251,238,106,235,158, 97, 25,203,234, 72,139, - 31,184,192,187, 50,178,131, 17, 22, 85, 20,183, 57,103,194,194, 78, 51, 18, 87,150,227, 16,232,194, 67, 39,253,132, 16,104,170, -192,121,235,195, 16, 96, 89, 36, 39,156,122,185,116, 75,173,172, 82,119,152,167, 5,195, 16,104,159, 29,131, 62, 72, 98,241, 19, -101, 45,161, 64, 29,188, 15, 36,178,178, 22,195, 24, 86, 73, 87, 44,188, 81,223,107,103,251,170,168,193,209, 8,185, 11, 28,154, -142,144,151,121,225, 67, 27,252,249, 69,225,222, 93, 10,193,211, 47,125,225,151,250,238,247, 62, 68,182, 55,113,126,118,142, 6, -131,147, 77,195,243, 47,255,153, 46,221, 70,137, 73,178,111,174,156,190,229, 88,184,104,173,135,113,134,139, 3, 42, 18, 68,169, - 91,153,149, 94,101,247,183, 42,114,172,117,168,121, 33, 15,123, 74,176, 94, 44,101, 22,198, 81, 34, 12, 41,214, 1, 3,170,200, -193,144,147, 42,221,159,161, 98, 72,148,158,180, 35,228,128, 27, 78, 85, 36,245, 45, 9,102,228,235, 18, 7, 3, 21, 68,232,145, -184,186, 79,182,216, 28,111, 81, 17,240,213,215, 51,158, 60,111,168, 38,224,214,221, 91,202,253, 47,176,216,103,135,154,102,186, - 32,172,197, 30, 30, 87,167,123,184, 97,131,227,101,194, 24, 22,252,253,223,255, 26, 95,126,253, 20,203,146,112,180,137,248,224, -189,215,176, 29, 12,166, 90,241,235, 79, 31,224, 58,237,113,228, 34,142,182,131, 38, 90,153,180, 67,154,174,241, 15,191,125,134, -191,219,157,163,193,227, 30, 34,254,252,195,183,113,188,137, 58,214, 35, 26, 31, 48, 6,135,130,138, 71,151, 19,174,246, 25, 67, -160,164,172,106, 12, 96, 27, 82, 51,192,237,155, 24,158, 36,228, 60,171, 23,216, 40,229, 13,170,116,151, 14,230,119, 15,250,240, -157,255, 78, 68,173,206,121,182, 46,246,212,171,146,147,146,249,122, 26, 92,211, 76, 0, 81, 30,135, 16, 40,122,215,246,156, 6, - 43,197,100,171,136,113, 64,173,164,149, 0,231,150,215, 70,209,184,228,147, 14, 48,206, 96,158, 22,222, 71,147, 56, 48,179,165, -139,166, 76, 93, 43,225,216,237, 32, 19, 52, 41,158, 97, 12,166,253,130,205,118, 64, 28, 34,237,163,115, 34,251,101, 32,100,172, - 97, 65,104,136, 20,242, 19, 35,117,222,113,136,140,132,117,122, 46, 73,115, 98,120,197,211, 69,144, 44, 86,187,222,227,250,114, -199,157, 61,137, 89,151,153, 59,113,206, 59, 39,190,125, 86,151,129, 15, 14,211,190,192, 88, 10,176,114,158, 67, 93, 50,119,214, -158,180, 55,134,119,199, 18,179, 74,235,127,171,221,186, 0,134, 98,244,152,103, 74,117, 52, 86, 10, 39,168,250, 59, 51,252, 41, -165,110, 79, 22,171,156,184, 24,150,148, 97,173, 71,136, 13,134, 73,154,149, 39, 33,148,150, 39,144, 32,240, 36,102,125, 30, 64, -159,143,113, 28, 49,142, 35,142,142, 55,170, 59,178,124,214,209,154,133,206,255,101,102,182,189,119,184,186,184,198,249,139, 51, - 76,211, 68,241,162, 14, 74,196, 76, 75,103,206,147, 78,163,232,106,182, 29,236,164, 87, 23,188,161,200,111,172,152, 37,125,252, -190,222,149,155,213, 71, 89,101,130,172,222,145,111,221,239, 47,253,139,223,245,150,201, 68,195, 28,220,230,173,143, 21, 86,187, -118, 25,168,153,245,148,193,116,228,183, 20,238,118,149,240, 38,122, 13, 35, 56, 94, 99,225, 11, 11, 23,168,155,236,170, 75,197, - 37, 26, 67, 23, 59,231, 53, 75, 71, 41, 20, 40, 18,126, 84,205,115,238,251, 77,199,188,112, 7,227,208,201, 67, 42,216, 96, 49, -149,113,170,160,108,172,112,221, 28,145,186,158,130, 26, 76, 23,102,148,130, 92, 50,251, 20, 13,103, 12,103,237,142, 73, 85,221, - 35, 9,205,234, 97, 92,199, 82,106,170, 80,165,151, 33,241,184, 91, 66, 12,228,107,145,236,109,241, 63, 82,113,227,244, 1,245, -158, 3, 86,152,118, 71, 35,118,195,161, 43,100,223,106,154,219, 78, 85,175, 60,164, 36, 76,164, 23,209, 24,131,121, 74,212,197, -191, 84,198,169,135,221, 16, 1, 79,136, 75, 64,215, 44,188,242,246, 15, 97,198, 87,241,228,225, 25, 74,109, 56, 62,242, 56,251, -250, 31,137, 5,189,122,200, 29, 87,199,228,253, 52,170, 33,128, 97, 1, 32,119,183, 20,191,104,120,148,103,122, 55,100, 44, 2, - 31,106,132, 18,134,170,251, 91,237,224,100,139,213, 37, 35, 30, 17, 67, 66, 69, 63, 68, 88,239,225,196,118,102,232,149, 34,102, -127, 90,141,245, 29, 76, 96,204, 45,168,176,148,177,187, 80,161, 66,116,200,252,205, 73,162, 88,173, 64, 28, 7,148,226,240,224, -137,195,249,121,197,107,183,182,248,209,251,119,113,113, 57,227,122,191,192, 56,143,121, 63, 99, 73,133,246,254,113,128,143, 1, -197, 56,236, 83, 65,105, 1,117, 95,112,122,121,129,199, 95,127,131, 71,143,158,177, 2,184,224,199, 63,125, 15,119,238,220, 4, -202,140, 80, 23, 60,126,250, 2, 0,240,222,155,175,226,248,100,139, 60,147,120, 51,149,140,191,250,229, 35,124, 60, 95, 97, 68, -164,248, 92, 0,159, 62,190,192, 71,111,221,213,238,214, 57,135, 92,155, 30,208,251, 82,176,155,137,234, 85, 1,156, 28, 69, 56, -111, 96,110,222,129,187,113, 19, 75,126, 66, 69,166,103,234,151,161,103, 70, 10,110, 81, 51,155,245,152,177, 29,142,255,100,123, -215, 86,167,138,179, 78, 29, 6, 70, 15,105,171,204,110, 82,190, 55, 52,219,122,208, 18,119,236, 96,177, 85,173,164,252,166, 67, - 39,175,214, 1, 92,102, 25,203, 23, 10,217, 72, 5, 82,100, 86,212,175,204,202,113,177, 91,225, 37,239,111,173,149,105,135,162, -205, 17,228,109, 23, 26,145,221,209, 97,220, 68, 22,198,210,225, 71,157,102, 97,209,158, 20, 36,149, 63,159, 71,140, 17, 71,199, - 27,250,218,120, 10, 86, 11, 93,250, 57, 87,237,242, 67, 12,216,108, 73,205,190,223, 77,216, 95,239, 49,237,233, 93,243,174, 71, -127,202, 4, 83,246,160,242,253,214, 90,225,163,195,245,229, 30,195, 38,162,148,130, 16,105, 7,158,248,156, 36, 49, 45,137,210, -214,129, 56,222,123,204, 11,171,187,249,207, 78,251, 69,253,241, 68,175,164,201,158,116,167, 66,133, 43, 53,163, 21,233,196, 23, -213, 44,244,115,145,216,225, 2,157, 17, 66, 89, 8, 94, 53, 1, 34, 94,164, 41, 95,215, 56, 80, 65,232,177,217,140, 56, 58,218, - 34, 68,102,140, 4,207, 25,239,212,232,133, 64,190,248,148, 18, 34,243,244,175,175,119,184,186,188,196,180,223,233,196,173,159, - 89, 30, 57,207,204,119, 79, 76,177, 75,171, 84,181,151, 54, 76, 56,188, 59, 37,136,101,253,191,158, 26,183, 22,139,126,123,220, -254,187,202,223,239,222,135,127,199,158,126,213,181, 31, 4, 32,173,147,225,214,119,189,249,246,162,224, 32,203, 67, 92,105,181, - 80,230,130,145, 59,184,168,205,173, 25, 11,111,172,120, 45, 3, 67, 58, 50, 17,195,248, 43,145,232, 60,162, 8,209, 24, 76, 0, - 46,162,175,165,145, 58,135,193, 88,176,221,134, 9,101,188,199,165, 92,227,194, 47, 28,195, 83,162, 83,188, 97, 67,211,234,216, -128, 95,122, 57,176,141, 65,105, 21,211,126,210,189, 75,211,172,231, 78,135,163, 95, 44, 29,148,203,146,245,176, 32,177, 72,233, -172,226, 34, 89,203, 86, 9, 72, 41,101,165, 63,153, 85,198, 52, 9,218, 50,195, 99, 68,237, 25, 56,142, 17, 42,230, 43, 26, 30, -208, 52,125,135,192, 42, 20,142, 16, 98,212,138,173,213, 30,185, 42,251, 65, 9, 39,167, 81, 51, 91,202,248,215,154,211,130, 56, - 4, 45,138,136,249, 78, 33, 13,119,223,254, 16,241,198, 91,120,244,224,140,162, 42,183, 30,215, 79,127,137,253,213, 11, 22, 37, -209,215, 77,159,159, 60,195,196,175, 14,188, 94,168, 12,158, 16, 32,135,131,229, 92,119, 74,186,227, 74, 87,189,152, 70,199,145, -149, 41,110,211,190, 71, 76, 54, 82, 29,146,178, 89,115,177,169,170, 28, 54, 27,250,222,216,133,208,106,134,113,150, 87, 1,101, -149, 23,110, 25, 85, 89, 0,227,212,226, 97,228,239, 88, 18,225, 21,222,215,151, 68, 89,210,198,123, 88, 31,241,236,204,225,209, -115,143,187,247,238,224, 15,126,239, 46,134,253, 57,114,153, 81, 48,163,185,134, 93,154, 81,150,190,171,183,198, 98, 94, 72, 56, - 84, 27, 80,115,193, 60,103,156,191,184,192,151, 95, 61, 82,190,193,107,119,111,227,245, 55, 94,197,213,110,198,232, 45, 78,175, - 10,206,118, 19,172,177,120,227,245,219, 56, 62, 25,145, 56, 9, 16,103, 19,126,250,131,215,240,226,147,138, 93,109, 40,172,245, -248,213,139,107, 52, 99,240,147,119,238,194,178, 21,175, 54,131,108, 44, 70, 19, 81,140, 69,174,192,156, 10,106,107,136,131, 67, - 24, 35,204,230, 8,205, 24,236,231, 25,104,221, 94,217,106, 93, 49,166,153,129,112,224,100,238, 2,166, 67,181,111,223,135, 58, - 31,213, 46,103,120, 21, 36, 23, 57,106, 69,230, 81, 48,133, 95,116,216, 82,206,101, 69,121, 44,202,232,135,224,144, 25,194, 98, -100,239,103, 29, 44, 43,174,165, 88,173,105, 33, 1, 94, 4,246,187, 29,142, 79,110,144, 31, 90,116, 37,206,160,176,134,133, 46, -228,200,103,142,101, 62, 2,117,136, 52,213, 3,150,133, 46, 97, 82, 16, 55,245,195,103, 14,156, 10,145,222,103,217,147,251,192, -162,174, 24,177, 57, 26,201,109, 35, 42,127, 71, 78, 3,195, 96, 44,137, 78, 13, 49, 96,158,200, 78,187,187,158, 48,239,103,182, -225, 6,126, 86, 12, 7, 97,145, 95, 92,166,140,162, 30,111,141,208,203, 20, 94, 85,212,138,151, 27,133, 62, 53, 85,233, 23,166, -225,137,154, 93,210,108, 73, 3, 48,207, 11,143,197, 61,188,184,147,184,137,105, 44, 24, 37, 91, 31, 9,110,197, 93,146,217,162, - 38,147, 8, 82,163, 51,218, 57, 17, 19, 67, 69,138,166,175, 76, 26, 55, 67, 18,236, 69,105,149, 1,227, 56, 32,132,136,237,209, - 8, 3,112,248,141, 85, 77,209,250,172,219,239, 40,171, 33, 14, 17,105,201,216,239,174,113,113,113,169,100, 74,185,196, 28,219, -214,200,225, 83, 20, 45, 44, 49,224, 82,178,174,167,233,114,195,183,111,217,197, 14, 54,227, 93,236, 88, 87, 87,166,238,192,219, - 33, 5,238, 96, 95,245,187,246,233,223,190,232, 15,254,232,203, 11,243,213,136,125,125,153, 27,201, 99,127,233, 99,202,239,191, -187, 78, 8,209, 46,103,160,129, 1, 44,152,244,105,224, 21, 86, 98, 68, 61,204,150, 41, 25, 27, 48,147,183,144,244, 20,210,107, -135,249,172, 0, 0, 32, 0, 73, 68, 65, 84,217, 75, 50,143, 94,254,214, 34,120,171, 74, 83,163,170,119,175,226, 52,107, 29, 82, -154, 97,189,209, 29, 84,136, 81,127, 51,181, 84,184,209,227,232,120,171, 93,122,229, 39, 43, 39,242, 99, 46,243,130,105,191,192, - 58, 3,192, 43,239,152,212,171, 25,126,140,156, 24,231,212, 46,146, 82, 86,235, 27,217,223,168,194, 92,230, 25,206,121, 76,172, -126, 21,225, 79, 87,149, 87, 44, 75, 85, 27,213, 56, 14,188, 35, 18, 66,156,196,182, 50,246,113,173,254,100,142,178, 15, 18, 51, -217, 69,238, 37, 21,174, 90, 61,195, 81,214,160,141,190, 47, 45,124, 33, 10,248, 71,254, 28,137, 73, 42,238,188,254, 30,142, 95, -253, 0,223,124,125,138,121, 90, 48,142, 30,215, 79,126,133,171,179, 71, 92, 2, 90, 62,252, 2,199,156,130,167, 50, 21,181, 38, - 5,226, 88, 24, 88,207, 99,227, 6,238,194,237,202,103,203,137,197,181,162, 24,163,190,218, 92, 27,108,227, 61, 96,206,180,227, -151, 21, 12,243,192,117, 31, 62,140,204, 95, 39,223,113, 99, 84,174,177, 28,188, 35,126, 76,235,212, 81, 97,156,215,181,129,119, -178,179, 7,106,110,156,188, 71, 98, 70,231, 3,170,137,184,188,182,120,118, 30, 49,110,111,225,189,247,111,225,198,201, 64,160, -145, 84, 97, 7, 7, 95, 11,134,154,225,188,193,134,163,110,231,235, 29, 18, 28, 0,139, 82,102,164,185, 96, 41, 22, 23, 23,215, -120,248,224, 17,125, 94, 67,145,169,111,191,253, 26,246,251, 9,222, 86,180,205, 6,191,252,151,175,144, 91, 65,180, 30,239,188, -253, 26,142, 54, 1, 37, 88, 44,169, 34,188,243, 14,126, 8, 32,160,225, 47, 62,254, 6,222, 6,148, 86,113, 39, 4,252,224,254, - 45,166,254, 1,197, 80, 81,183, 75,156, 33,222,128, 41, 23,178,247, 4,160,109, 6,204, 55,110,163,204, 51, 48,101, 92, 92,237, -241,182,245,186, 0, 92,103, 48, 87, 1,110,188, 84,235, 31,134, 66,137,136,211,145, 96,147,237,126, 48,142, 59,222, 30, 11,105, - 26,197,127,186,224,153, 86, 86, 52,182,178, 37,113,218, 52,228,133,162,112,235, 74,211, 80, 74,101, 1, 95,211, 85,141, 66,159, - 88, 7, 16,124, 64,109, 36,124,117,133,214, 89,203,178, 80,242,153,243, 12,164, 98,178, 99,109,172,160,238,218, 0,235, 44, 91, - 51,141,134, 13,209,234,176,177, 42,220, 51,228,165,174, 38, 95, 93,100,104,157,131, 15, 86,113,177,210,205, 47,115, 90, 93,174, -124,161,242,218, 39,167, 78,165, 43, 12,193, 90,230, 69, 17,176, 34,208,171,166,170, 73, 42,165,164, 93,186, 88,248,132,194, 38, -157,218,188, 36,178, 0,231,238, 23,151,117,159,172, 31, 1,211,149,234,204,186, 16, 58,157,120,217, 37,114,217, 58, 96,153,179, -166, 73, 54, 86,141, 91,182,157, 73, 4,169, 1, 14, 32, 86,218, 61,114, 50,151,248,196,131,232, 43,184,179,223,108, 40,104, 43, -198, 8,103, 45, 55, 78, 85,197,195,210,148,181, 38,150, 57,138,204, 29, 55, 35, 90,107,184,188,184, 66, 90,200, 45, 96,217, 69, - 69,161, 64,125,196, 15,222, 25,235, 26,129, 63, 86, 39,130,214, 85, 78,187,233, 59,104,131,131,172,116,250,186,205,106,247,222, -190,205,108,104,135, 32,154,245,248, 28,178, 42, 91,137,125, 15, 59,233,246, 93, 45,250,183, 90,111,115,112,227, 31,138,226,116, - 84,175,223, 73,111,224,122,133, 80,213, 54,217, 71,243, 70,157, 99, 50,161,246,134, 85,157,181,210,168,199,135,168,159,134,198, - 48, 43, 66, 91,174, 26,234, 97,157, 3,172, 83, 69,188, 60,188, 13,224,232, 86,232,200,220,135,128, 34, 4, 52,121,168,141, 69, - 8,125, 7,221,120,239,139, 38, 0, 23,122, 33, 13,239, 70,106, 35,226,211,110,183,231,203,195,173, 4,118, 61, 66,114, 89,250, -248, 92,108, 32,145,243,152,233,165,245,180,223, 7, 84,133, 78,187,227,172,203, 18,137, 15, 44,165,169,232,200,251, 64,209,167, - 60,114,151,200,198,245,126,132, 58, 9,175,163,169, 24,195,202,151,111, 97, 3,103,127,243,138,131,118, 84, 88,197, 71, 26,216, - 64,100,189, 86,197, 39, 95,244, 55, 47,233, 62,173, 85,220,124,229,123,184,243,189,223,195, 55, 15,206, 48,237, 23,248,224,112, -253,244, 95,112,125,250,144,126,185,206,193, 51,163,189, 50,191,208, 51,249, 43,196,168,235, 9,233, 28, 76, 99, 37,179, 39,155, - 30,117,240, 70,247, 71,165, 86, 29,229,121,239, 48,237, 38, 6,200, 20,173, 66,137, 48,183,114, 85,153,206,182,166, 93, 35, 41, -156, 13,115,181,107,171,112, 16,197, 59,115,165, 13,193, 69, 26, 43,125,105,251,190, 74, 85, 42,210,157, 22, 88,191,193,213,180, -197,249,179,134,203, 93,195,107,175,221,195, 91,239,222,230,162, 20,184,158, 43,108,171, 48,197,194, 44, 6,152, 22,184, 74,182, -188,209, 83,254,182, 55, 13, 41,103,164, 6,248,205, 6,209, 55, 60,252,230, 12, 15,190,122,192,150, 71,122, 23,126,255,163, 31, - 32, 90,131,221,195,135,104,183,110, 32,223,189,135,199,207,206,177,141, 35,182, 67,192, 43,175,220, 0,140,197, 48, 56, 12, 3, - 48, 15, 30,227,247,223,194,110, 90, 48,124,250, 12, 75,173,184, 21, 7,252,217, 71,175,227,120,140,186,250, 41,141,190,158,194, -240,166,165, 22,248, 96, 49, 28, 5,224,230, 29,180,163, 45, 8, 9,111, 53,141,173, 20,161, 61, 50,138,151, 5, 84,135, 84,153, -118,208, 49,168, 50,216, 58, 13, 45,170,205,116,171, 41,123, 97,141,170,155,185,163,110, 5,166, 82, 14, 56, 93,118, 77, 39, 82, - 20,101,204,244, 58,244,192, 12,225,137,151,182, 62, 20,137,160, 33, 81,156,134, 51,212, 37, 90, 53,231, 2, 99,169,155,175,188, -191, 38,224,145,225, 75,197,233,207, 44,215,194,163, 96,195,226,200,192,218,159,198,201,111, 70, 21,251, 36,188,165,168,209,214, - 26, 54,219, 1,243,180,176,102, 7,202,134, 15,129,118,233,243,156,224,189, 93,141,187,173,174, 54,168,201,225, 64,169,121,193, -126,183,231, 20, 59,207, 22, 88,201,111, 7,159, 61,141, 93, 46,134, 18,186,248,119, 96,189,133,131,227,204,243,138,105,154,233, - 44,105, 64, 8,100,187,148, 53,162, 16,220,228, 76,241,158,149,253,188, 58, 43,165,135,175, 88,107,225,108,161, 41,229, 10, 89, -237,156, 35,203,104,169, 26, 14, 69,246,167,166, 69,117, 91,119,227, 88,173,115,152,205,222, 42, 17,232,198,113,224,200, 89,203, -113,196, 78, 1, 65, 50,217,148, 75,115,154,102,154,208, 13,196,201, 47,185,224,242,226, 10,243, 52,235, 10,181,213,214, 65, 68, -188, 90,148, 38,141, 86, 84,158,207,134, 66, 34,237, 90, 14,242, 29, 52,147,220,116,212, 43,141,219, 13,240,210,126,189,181, 67, - 45,188, 52,207,245, 59, 90,122,209, 64,173,199,251,230,191, 36, 81,121,201,148,134,239,198, 66,124,167, 95,125,189,227, 63,252, -211, 13,223,245,183,157,245, 74,241,147, 85,153,126,141,198,192,183, 42, 59, 50,195,191, 96, 48,222,147,236, 64,200, 89, 71,203, - 2,219,151, 46,163,213,172, 37, 8,229,133, 7,221,127,171, 13,134, 59, 53,152, 85,198,108,165, 56, 79, 26, 71, 25, 77, 0,243, -252, 98, 17,243,221, 41, 94, 86, 96, 14,211,126, 70, 90,104,244,239, 69,113,107, 13, 95, 56,212,133, 14,209,245,228, 27,246,181, -230,204,185,211,172,212,150,221,119,101,187,148,232,171, 72,253, 9,190, 76,171, 50,229, 53,110,145,193, 48,206,133,149,160, 16, -171, 64, 8,154,122, 88,239, 24,160, 70,168, 87, 18,112,161,195, 81,172,209, 67, 35, 45,164,182,151,120,189,148,232, 69, 36,126, - 53,237,208,101, 10, 94,107, 65,205, 25,183, 94,125, 11,247,223,251, 25,190,250,226, 57,133, 86, 56,139,229,252,183,184, 62,123, - 0,112, 0,135,117, 30,206, 5, 37, 91,137,130, 84,186,115,168,114,190,227, 36,133, 27,111,173,133,141,180,111, 4,163, 33, 27, -239,240,106,173,216, 93,207,122, 0, 24, 11, 82,183,115,236,109,101, 95,190,252,110, 90,225, 14, 52,211, 51, 69, 17,190,130,143, -164,103,160,164,212, 19, 2,121,172,100,172,163,200, 56,116,145,160, 0,108,156,115,152,150, 17, 95,127,229,113, 61, 21,220,186, -113,132,143, 62,186,143, 6,135,203,235, 9,105,201,176, 62,192,185, 66,153,229, 75,130,157, 95, 96,235, 26,188, 49,136, 14, 88, -174,103, 88,227,224, 13,239,164, 82, 65, 13, 35,190,248,230, 41, 62,251,226, 17,114, 33, 33,102, 45, 21,239,188,249, 10, 94,189, -119,130, 58, 47,112,241, 6,106, 60,194,217,139, 43, 60, 61,187,130,115, 6,247,110, 31, 99,227, 1,247,236, 27,212,163, 27, 8, -183,110, 99, 19, 2,178,181,248,248,209, 21, 18, 31,236,163,119, 8, 43,176, 79,230, 64,140,138,134,125, 46, 56,138, 3, 6,111, -177,185,125, 19,230,238,109, 42,114,157, 67,154, 38,160, 21,213, 86,104, 54,180,138,156,202, 75, 29,198,106, 27,199, 90, 23,203, -226, 55,210,196,200, 20,167, 7,178, 84, 30,169, 11,178, 57,165,140,224, 35,231,213, 19,149,141, 58, 73,122,124, 6, 23, 97, 12, - 93,244, 18, 50, 67,239,142,209,142, 94,124,243, 69,169,118, 61,226, 85,138, 75,233, 50, 37,121,176,241,142, 94,166, 84,228, 71, -183, 12,139,225, 44,118,182, 65,149, 92, 96, 2,159, 47,178,166, 3,141,190,199,109,224,209,181,209, 78, 61,242,120,220,135,160, -151,143, 15, 30,195, 24, 0, 80,199, 46, 57, 4,178,135, 78, 75, 65, 28,169,209,201,165,240, 25,194, 46, 3,110,198,125,112, 72, - 75, 86, 96, 38,113, 55,160,250,143,204,188, 10,112,102, 56, 90, 67, 53, 13,198,176,189, 13,125,194, 87, 74, 23,155, 73,136, 14, - 26, 96, 57,223,129,222, 35,206,215,246, 30,165, 36,253,253, 9, 24,198, 57, 2,224, 16, 91, 66,194,182, 40, 67,131,154, 27,195, - 34, 55,163, 83, 76,112,241,237,188,227, 21,169,129, 9,158, 19, 40,233, 12, 27,199,145, 33, 60, 86,149,249, 29, 72,100,153, 56, -154, 21,101, 75,218, 4,250,250,175, 46,175,112,125,181, 83,216,145,211,212, 61, 97,134,208,187, 93,107, 86,253,143,156, 63,234, -148, 41,249, 96,207,172,190,116,211, 47, 97,243,146,161,173,245,168,131,111, 9,212,218,119,169,222, 94, 34, 47, 30, 92,232,120, -105,150,223,190,141,166, 51, 47, 45,214,205,119,136, 81, 15,196,112,166,171, 92,204,193,215,184,186,151,101,106,106, 44,156,177, - 26,134,101, 29, 71,174,250,192,211, 31,122,191,188,196, 84, 58,190, 88,169,154,143,189,210,183, 61,153,201,172,196, 72,212, 13, -145,144, 70, 94, 68, 33, 12,201, 40, 86,198,201,212,181, 70,160,177, 0,136, 15,107, 25, 63,136,216, 38,196, 17,155, 35,242, 49, -202, 56, 34, 45,153, 61,230, 69, 31, 22, 42, 40, 56,231,153,195,226,115, 46, 42, 50,171, 43,235, 85, 78, 5,227, 38, 34,167,134, -220, 10, 39,204, 89, 29, 21,150, 92, 85,245,171,174,192,218,147,141,208,154, 86,242, 50,162,151, 74,210,177,144, 75, 33, 56, 60, -197,160,136, 61,242, 80,143,145, 64, 36,132, 90, 77,124,208,113, 48, 2, 43,244, 69,171, 80,149, 48,101, 20,248, 34,244, 42,160, -162,149,138, 59,175,191,131,215,223,251, 35,124,254,217, 51, 92, 93, 78,180,139,187,252, 28, 87,207,191,224,228, 39,207,163,169, -142,154,117, 62,176,218,158,194,199,106,173,112, 13,170,196,181,214,193,134, 0, 86, 49,240,104,145, 33, 15,185,243,255, 91, 45, - 90, 24, 25,208, 14, 90,148, 21,194,180,167,226,144, 10, 30, 43,110,138, 90,224,173,231, 98, 10,148, 2,197, 90, 13, 83, 41,150, - 54, 45, 73,145,135,203,188,240,104,162,234, 32,170,100,210, 53, 84, 4, 60,122,106,241,248,105,195,184,241,248,209, 59,183,113, -107,235,145,231, 61,150,102, 81,175,119, 72, 83,194,126,202,200, 54, 2,214, 96,180, 21, 67,201,184,118, 6,105, 90,176, 29, 35, -129, 49,150,130, 58, 47,200,115,194,217,213, 30, 31,255,234, 33,158, 95, 77,220, 65, 53, 4,231,240, 71, 63,125, 31,239,189,247, - 6,173,113,152,232, 85, 26,240,205,195,103, 4, 61,202, 25,209, 2,249,201, 35, 92,165, 2, 95, 61,142,238,191,134,214, 42,174, - 94, 92,224,211, 7,167,136,158, 50,170,207,230,132,255,248,203, 71,120,239,238, 17, 62,184,127,147,125,189,192,156, 42,206,103, -209,124, 0,102,123,140, 6, 7,235,232,144,164, 60, 4,207, 88,100, 10,197,233,163,196,210,151,131,107, 18,128,161,201, 8, 21, -204,108,115, 50, 92,180, 99, 29,241, 72,133,170, 85, 43, 26,165, 0, 42, 82, 85,196,154, 37,161, 54, 7,203,202,239,101,154, 85, - 63,210,216,150, 36, 94,113,153,148,137, 69, 75,115,160, 87,203, 1,231,132,123, 1,117,192, 72, 1, 74, 2, 77,210, 10, 56, 71, - 23,124, 28,130, 50, 12, 80, 42,251,186, 59,100, 71,236, 90, 94,199,190, 12, 65,226,145,178,208, 17,157, 37,184, 83,229, 60,113, -130, 68, 85,226,207,243,233, 47, 23, 99,206,100,133,147,119, 66, 5,153,176,152,118, 11,127,223, 13,214, 82, 78,121, 99,112,145, -128,115, 36,174,214, 90,131,198,144,160,146, 10,191,243,137,180, 73,156,177, 46,113,168,210, 92,200, 10,207, 90,135,198, 28,138, -101, 73, 40,133,206,106, 74, 70,236,171, 47,242, 42,247, 11,210, 57,139, 92,114, 31,203,114, 49, 47, 41,105, 75,202,140,141,237, - 17,160,114,102,198, 24, 25, 52,212,125,251,146,236, 70, 2,193,202,112, 25,175,250,166,253,110,102,247, 1, 16, 98,196, 48, 16, -244,167,214, 66,184,215,154, 87, 89, 4,128,243, 70,167,162, 20, 73,187,186,172,107, 81,103, 75,149,239, 37,247,203,186,181,223, -225,230,248, 14,240,139,121,249, 46,110,135, 23,127, 59,228, 53,117,128,234, 75,171,244,181,240,237, 16, 96,211,190,227,207,125, - 87,135,221,199,237,230, 32, 71,157,167, 55, 60, 25,235, 58, 53,171,117,131,119, 20, 73, 77,211,236,214,109,148, 10,253,170, 92, - 48,242, 4, 57, 11, 14, 21,132, 73,172,188,115,166, 14, 41,179,213, 72,186,102, 67,193, 41, 77,226, 29,105,132,158,150,153,128, - 52, 18, 75,138, 62,235, 39, 11, 22,237,120,172,179, 8, 8,186, 55,117, 54, 40,118, 82, 58,245,113, 24,116, 36, 40,170,120, 99, -129,121,158,105, 55,212,250, 72, 12,133, 70,109,228,167,230, 28,104,198,147,210,218, 64,212,239,135, 15,137,236, 30,172, 92, 62, - 98,255, 48,194,202, 54, 58, 58,118,252, 49,196,170,148, 83,193, 48, 68, 30,199,145,112,200,121,242,102,203,136,218, 49, 76, 71, - 20,243,226, 57, 44,108, 73,241,158, 84,251, 36, 36,226, 93,117,206, 40,185,113,183, 64,135,142, 32,118, 37,223,248,222,235,239, -226,213,119,127,140,207,127,251, 20, 23,231,100,159,201, 87, 95,225,250,244, 51, 56, 31,120, 4,104,216, 95,236, 20, 52,147,115, - 33, 37,126,149,100, 52,175,176, 24,107,156,250, 32,141,117,132,139, 20, 31,191,117, 40,144, 36, 36,114, 9,172,179,188, 37,151, -190, 72, 50, 83,237, 94, 75,121,240,164, 75,170,234,105, 6,172,113, 60, 37, 40,196, 62,200,139, 70,227, 54, 86,111,203,203, 75, - 12,242, 6,227, 6,156, 94, 56, 60,120, 68,185, 0, 63,248,254, 93,220,185,115,130,176, 59, 71, 40, 25,182, 52,192,122, 12, 37, - 97,218,239, 97,151,140,227, 49,195,134, 45,192,140,237,232, 29,182, 71,244,187, 43,251, 5,187,235, 25,121, 73,248,242,233, 5, -190, 58,223, 99,102,178,161,116,158, 63,251,241,187,248,209,135,111,177,179,194,118,124,176,109,248,229,217,185, 38,141,189,118, -123,139, 52, 39,204, 75,195,113, 3, 23, 40, 14,127,245, 55, 31,227,116,191,192, 51,211,223, 89,139,235,156,241,247,223,156,225, - 55,207,175,241,123,247,111,224,189,251, 39,216, 47, 11, 46,231, 5,185, 86,108,135, 65, 69,145, 2, 51,217,140, 30, 14,192,156, -120, 77, 4,219,253,232,109,117, 48,177,247, 64, 20,236,198, 56, 21, 55, 18, 0,198,234,232, 91, 38, 51,116,160, 85, 88, 46, 32, -215,158,221,218, 24, 71,203, 8, 85,211, 50, 9,223,172,193,178,244,132, 54, 99,109,199, 6,163,209,101,134,166,202,232, 53,198, - 86, 58,187,222,105, 22,118,148,172,182,163,130,143,118, 65, 47,236,180,228,222,209,177,235,101,176, 30, 41,101, 12,227,160, 23, - 60,105,109,172,226, 73,141, 5, 12, 91, 52, 9, 49, 93, 49,110,122,183,233, 2,197,147, 18,226,153,104,137,181,102,204,115,209, -162, 75, 3,102,216,243, 78, 78, 22,139,156, 27,108,108,108,115,229,113,185, 68,100, 58,154,116,201, 5, 95,146,172, 49, 11,246, -251,153,215, 22, 84, 88, 88,166,119,106,119,174,185, 25,204,249,168,141, 47,116, 18, 35, 39,214,180,244, 88, 84, 86,214,243,207, -220, 24, 18,158,218,106,209,108,131,117, 65,149,224,214, 2,181,145, 24, 89,138, 46, 99,168,144,217,110,183,156,124, 72, 68, 61, -207,103,138, 20,123,214,246, 8, 87, 99, 12,166,105,198, 50, 47,168,181, 32, 4,135, 97,140,234, 32, 58, 63,191,228, 11, 59,245, - 81, 58,159,141,228, 36,201,236, 53, 23,141,147, 71,206, 11,159,247, 70,131,183,202,234, 57,151,100, 54, 34,233,117,117, 59,117, -235,230, 59,172,227,237, 91,106,243, 53,126,198,152,151,130, 93,240,237,139, 92, 47,240,213,252,125,157,165,240, 59, 33, 52,223, - 49,114, 55, 42, 62,151,118,189,169,223,188,231, 55,172, 7,241,134, 67,116,178, 18, 94,157,160,214, 93,231,199, 88, 22,182,202, -187,235,165, 2,211, 63,104,197, 19, 71, 68, 48,219, 68,213,222,147,118,250, 40,158,108, 18, 48,148,234, 36,137, 59,158,125,133, -125, 42, 97,120, 95, 66,194, 39,203, 86,133, 53, 14,210,249,136,113, 28,117, 63,213, 86,227,234,156, 50,179,148, 83, 87,187,115, -118,158, 99,204,173,229,192, 2,203,184, 67, 41, 84, 36, 62,176,143,153, 68,173,207, 70,125, 47, 59,196,222,221, 83,250, 40, 77, - 29,188,239,190, 93,199, 99, 40,218,245, 26, 5,200, 72, 53,220,233,113, 84,244,120,182,130, 8,207,184,173,248,211,244,189, 25, - 37, 40,209, 62,168,178,213,173,234,190, 90, 14,139, 55,190,255, 67,220,126,227, 71,248,252,183, 79,112,241, 98, 15,231, 45, 48, - 61,192,245,233,103,244,242,231, 10, 99, 2, 91,207,156, 30,180, 2,252, 33, 75, 72, 65,240, 36,100,233, 7,161,208,195,236, 42, - 98,145,243,161,211, 66,163,108,205,162,239, 59, 60,226,122,215,149, 45,169,123,241,197,106, 37,135,141, 36,124, 81, 28,163,101, -130,160,163, 17,247, 66,193, 60,148,224, 74, 85,186,216, 43, 91, 45,168, 8,120,122, 10, 92, 92, 57,108,134, 17,127,248, 7,247, -113,124,114,132,148, 42,202, 50, 35,101,250, 92,176, 30,213,143, 8,184,196,205,209,193,222, 28,105, 13,176,137,152,206,247,180, -110,224, 41, 65, 93, 50, 92,107,176, 45,227,151, 95, 61,199,211,125, 82, 58, 34,248,160,125,255,221,251,120,255,131,183,201, 42, - 34, 57, 6,165,194, 89, 42,182,158, 60, 59,231, 2,211,225,181, 55,238, 1, 71, 17,102,211, 96, 78, 78,136,115, 16, 26,238,221, - 61,193,157,147, 35, 92,236, 38,230,163,211,197, 30,172,195, 46, 23,252,127, 15,206,240,249,233, 53,137,241,106,133, 99, 54,129, - 15,158,163, 91,171, 18,193,188,203, 48,231, 79, 57,159, 58,117,182,182, 15, 42,104,132,177,218,237, 90,235,251,120,111,205,169, - 22, 8, 17, 26,156, 11, 61,137,177, 84, 14,116,169,108, 23,163,119,189,182,190, 42,147,103,168,105,150, 58, 23, 15, 13,104,153, -131, 96,120,114, 39,150, 85,121,135,214,201, 94,107,116,108,107, 13,214, 83, 34, 99, 41, 21, 78, 17,169, 85, 63, 47,237,212,189, -138, 79,107,109, 24,198,129,161, 46, 52, 85, 26,134,168,248,234, 24,189,198,161, 58, 43, 59, 97,102,216,143, 65,129, 40, 66,170, -180,209,115, 83, 96,184,136,181, 28, 48, 68, 33, 43, 82,160,138,200, 52,205, 43,130, 89, 37,162,227,146, 88, 40, 42,145,196, 60, -117, 42, 44,250, 44,185, 32,183,202,172,140,194,192, 22, 18, 43,138,126, 73,168,119,222, 7, 20, 14,150,106, 13,216,239,103,202, - 71, 96,235,177, 8,219,228,231, 73, 19, 50,217, 45, 27, 77,206, 20,189, 14,120,253, 37, 26, 4,225,191,147,163,129, 68,109,155, - 13,173, 58,157,117, 36,118, 99,239, 63,173, 19,138, 22,100, 41, 81, 81, 34,194,201, 16, 61,198,205, 70,109,112, 87,151, 87,200, -133,166,171,242,113,232, 44,102,157,150,164, 88,150,170, 54, 63,177,105,117,251, 46,248,206, 49, 48, 5,244,142,243,197, 78,144, - 42,116, 77,128,121, 73,229,190, 26, 93,155, 3, 76,108,191,220,215, 16,166,111,253, 51,176,178,116,175,132,117, 6,223,234,238, - 91, 59, 84,185,183,117, 84, 27,186,118,164, 11,227,214, 23,186,233,191, 15,126,111,193,144,182,134,254,193,233,253,226,233,128, - 5, 55,173, 78,163,195,165,121, 12, 62, 32,243,115,225,141, 49,138,212, 68, 51,136,195,160, 47, 18,141,115, 28,106,174,186,175, -240,222, 99, 89, 22,141,121, 68,115, 12, 23, 33,245, 57,141, 82, 28,123, 75, 43,226,176,161,224, 21,219, 73, 71, 82, 93,200,159, -243,156,194,230,125,192,102,187, 65,140,129,247, 81, 77,115,211,231,105, 86,116,164,236,189, 68,174, 40,176,137, 2, 3,239,161, - 30,216,106,232, 2, 77,139, 89,229, 73,179, 90,189, 57,237,204, 69, 13, 44, 9, 95,133, 69, 33, 98,217,208,125, 58,143, 55, 12, -160, 85,149, 28,112,128,193, 48,120,237,222, 36,211,188,241,254, 92,210,226,192, 24, 88,199,251, 46,233, 96,215,246,163, 90, 25, - 12,200,234,216, 55,191,255, 33,110,190,246, 30, 62,251,244, 49, 46, 47,246, 84,245, 78, 95, 99,127,254,128,127,174, 20, 44, 67, - 93,148,231,145, 94, 80, 26, 30, 97, 88, 11,130,188,172,108,103,179, 14, 10, 47,160,137, 69,208,176, 24,121,152,201,118, 69,120, - 86, 58,216, 9,181, 11, 86,193,171,211,129,199,227,226,195, 21,232, 14, 9,174, 56,208,199,121,101, 65, 75, 18, 91,205,164,216, -174,133,195, 38, 56, 10,214, 7,143,243,115,139, 79, 63,175,248,254,247,238,225,103,255,246, 77,220, 56,217,162, 89,139,221, 62, -225,178,206,168, 32, 39,193,156, 50, 42, 50,252,237, 13,112,114, 3,219,253, 21,114, 42, 88,114, 69,219,239,113,180, 25,208, 74, -198,178,159,169,227,107,192,179,171, 9,191,120,240, 2,215, 75,193,209,118, 80, 59, 99,173, 13, 31,189,247, 6, 62,252,232, 29, - 98,122,243,229,154,178, 81, 93,194,139, 23,215,152, 88,133,108, 12, 48,158,156, 32,111, 71,120,103,176,203, 13,152, 43, 76, 89, -240, 39, 63,121, 27,127,252,193, 43,248,229, 87,167,248,171,191,249, 4,159, 61, 58,163, 81,175,243,234,159,125,122, 77, 99,108, -199,185, 7,222, 25,140,209,161,193, 97,153, 18, 80, 18,112,113,138,146,103,164,179, 43, 70, 98,246,238,206, 57,207,196,184, 30, -129,217,154, 81, 70, 68,107, 6, 70,153, 9, 50,106,109, 28,188,209, 58,254, 87, 20,239,134, 25,254,173,209, 72,215, 5,141, 25, -174,181,162,162,114, 26, 33, 61,155,222,211,180,173,153,166,253,133,181, 36, 88,181,250, 49, 37, 27,157, 51,217,171,225,194,142, -118,187,173, 1,243,188, 32,198, 65,255, 89, 46, 10, 25, 47,230, 82, 96,138,225,213, 1,209, 43, 91,131,254,185,101, 33,154, 97, - 8, 94, 41,140,206, 17,255,193,123,135,205, 17, 53, 12, 49,122,142,101,245,172,142,151,119,195,115,212,178, 65,205, 85,187, 82, - 74, 43,108, 88,230,194, 34, 91, 33, 59, 82,227, 80,109,211,213,159,136,203,100, 39, 47, 83,170,121, 90, 72,107, 36,209,196,173, - 97, 24, 54,172, 85,130,146,234, 8,159, 77,231, 69, 98, 86,193,126,183, 71, 74,153,155, 16,163,132, 1, 42, 20,106,167,170,193, -234,129, 47, 69,159,117, 84, 36,166,156, 17, 60, 77, 18, 93,160, 41, 80,140,195,106,212, 76, 44,125,199,162, 55,171,150,198, 30, -243,156, 82,198,245,213, 78,119,194,228,245,167,157,252, 60,205,152,166, 73,117, 1,214,146,194,158,116, 17,172,157, 66,211,204, -137, 42,207, 68,237, 51,232,198,121, 19,194,160, 32, 47,125, 65, 45, 73, 69,161, 34,186,181,214,247,248,234, 21,189,205,172, 72, - 48,166,225, 59,100,103, 93, 83,126, 56, 82, 63, 36,209,181,122,232, 62,107,171,150, 94,138,228,190,254, 50, 7, 54, 57, 99,205, - 1, 82,214,174, 45,106,102, 53, 33, 19,228,171,117, 61,122, 85,210, 57, 87,249,237, 85, 89,251, 93,209,223,239, 28, 17,166,122, - 30,203,115,198,122,227,151,188,112,210, 81,225, 44,115, 31,140,218, 54,124, 12, 42, 88, 42,156,130, 4,219,171, 63,195, 41,102, -198, 88, 88,206, 69, 7, 23, 0,243, 60, 99,220,140, 84,237,137,141,132, 15,207, 37, 81, 53,103,140,163, 76,242, 97,224, 61,141, - 84, 47,228, 43,191,190,218, 97, 89,102,253, 6,199,113,192,178, 36,133, 52,136,239,213,178,151,207,242,222,172, 85,122,112,114, -206,136, 67,196,180,103,197,101,147,223,122, 83,207, 37,165,251, 24,181, 99, 24,217, 71,115,241, 32,113,134, 49,146,248,172,149, - 10,231, 37, 9,137,170,202, 82, 24, 63, 41, 21, 19, 31, 92,185, 20,254,239,244,160, 90, 14, 75,169, 43, 81, 70,109,171,136, 91, - 73,192,242, 22,239,252,240,247,177,185,245, 22, 62,251,205, 99, 92, 94, 76, 52, 9,216,125,137,253,229, 35, 22, 64, 57, 30,183, - 25,134,202, 64,187,110, 25,175, 18,113, 43,246, 97, 20,243,164, 13,239, 54,168,179, 54, 10,228,145, 53,134,243, 52,246, 21,192, - 79,109,134,237,120,108, 65,172, 20,176, 82, 51,141,195,230,253, 68, 64, 10, 71,190,119,193,252, 90,103,105,135, 87, 58,128, 71, - 0, 54,148,149,158, 97,217, 82,233,156,229,132,190, 17,229, 69,193,135,239,221,198, 31,253,248,109, 88,107,113,189, 79,234,189, - 63,222, 68, 36,111,177, 76, 51,242,254, 28,246,198, 9,117, 74, 33, 32, 93, 55,180, 76, 93,245,120,247, 54,114, 3,230,243, 11, - 88,236,209, 90,197,111, 30, 93,226,243,103, 87, 72,165, 96, 28, 35,117, 30,173, 33, 6,143,255,234, 95,127,136,239,191,123, 31, -165, 84, 26,159, 26, 58,108,114,202,168,185,194, 71,143,175, 31, 62, 67, 46,164, 57,184,119,243, 8,155, 33,112,209, 72, 47,235, -254,252, 5,202,233, 99, 4,222,219,254,201,207,127,132, 63,253, 55, 31,226, 31,254,233, 51,252,175,255,254, 63,227,244,114,191, -130, 36,153,158,121,110, 12,198, 33,224,104,160,177, 50,205,220, 95, 96,191,223,227,242, 58, 33, 85,131,237,102,131, 48,140,221, -178,163, 73,138, 70, 3,157,154,210, 90,232, 57,215, 76, 3, 21,172,246, 3,168, 86,114,188,138,128,212,114,226,150, 28,232, 98, - 95,172, 18,244,194,197,124,169, 21, 53,209,132, 79,236, 96,244, 25, 11,170,174, 95,232,194,169, 43,156,151,119, 94,181, 54, 82, - 40, 11, 87,189, 11,229, 72,148,233,184, 35, 25,198,129,217,231,125,245, 67,162,172, 10, 31, 50, 28,251,204,197,227,171, 89, 17, - 48,216, 30,109,144,115,225,192, 16,143,113, 51,244, 46, 73,124,250,206, 41, 42,149, 86, 95,194,157, 55, 12, 94,105,216,108,253, - 42,123,156,126,186, 89, 17,216,244,204, 91, 16,153,179,212,138,101, 90, 96,184,169,168,106, 67,165,119, 97,216,140,220,141,173, - 67,112,232,125, 39,136, 77,229,124,116,102,202,231,172,154, 24,185,200,122,161, 37,172,117,199, 5, 67, 7,109,209,193,111, 49, -140,163,218,223,164,128,144, 49, 48,173, 51, 28,229,198, 51, 6,150,166,116,133,163, 93,233,103, 66,238,128,160, 2,183,153, 19, -226,118,187, 93, 7,234,112, 81, 32, 93,189,232,105,228,210, 92, 68,181,207, 5, 94,105,156, 50, 86, 87,151,162, 49,250,179,114, -214, 34,177,155,233, 80,157,222,232, 34, 99,244,180, 54,139, 47,161,144,205, 1,149,193,176, 15,188, 7,188,152,213,199,108,173, -155,222, 69, 73,111,165,225,125,121,148,110,215,127,238, 80, 23, 38,243, 0,163,218, 43,123,192,131,183, 7, 1, 76,102, 53, 9, -176,250, 76, 74,247, 46, 16, 8,211,119, 13,250, 51,202, 37,147, 85, 89,226,120,141, 1,192,148, 83, 18, 94,200, 47,128,171, 9, - 86, 37, 83,180,101, 84, 27,129,227,104, 55, 25,129, 83, 90, 22,129, 37,194, 48,112,110,116, 65, 99, 81, 74,225, 11,130,108, 34, -158, 32, 25,149, 70, 40, 57, 23, 4,111, 85,217,231,125,196, 48,142,132,137,181,142, 59,218,204,223, 63,145,170,164,147,170,149, - 46,140,202,123,164,156, 73, 69, 12,131, 3,228,170,252,214,156, 39,209, 70, 8, 44, 20,226,213,128,238,219,213, 72, 72,126, 75, -195, 99,208, 56, 4,173,118, 37,243, 92,245, 1,150,112,170,203, 34, 96, 26,163, 22, 58,241,104,166,148,185,242,207, 43,125,128, -248, 74,139,102,183,235,190,209, 52,173,228,188,115,248,224,167,127, 12,184,155,248,236,211, 71,184,186,154,137, 95,125,253, 5, -150,221, 83,182, 6, 2,141, 65,255, 6, 13,141,237,131, 20, 86, 67, 54, 20, 27, 7, 26,131,134,192,251,174,202, 93,118, 83,165, - 43,133,163, 88,158,206,208, 69, 65,157,126, 86, 36,100, 46, 61,144, 35,113, 36,106,229, 81,108,225,221,191,215, 74, 27,154,152, - 86,114, 70,171,244, 32, 55, 78,230, 18,220, 35,253, 55, 18,248,128,179,206,195, 16,169,251, 99, 33, 93,136, 17, 23, 87, 51,156, - 49, 48,206,146, 30, 97, 78,200,165, 96,153, 18,142, 78,182, 56, 58, 30, 81,141,195, 52, 45, 36,144,171, 30, 33, 24,140,183,110, - 98, 98,156,102, 29,183, 56,125,126,129,127,254,228, 9,118,153,138, 24,239,232,239,160, 53, 28,111, 7,252,201,207,127,132,251, -111,220, 35, 96, 14, 26, 2,167,138,229,148,217,165,224, 48, 77, 51,190,254,230, 84,131,120, 78,182,131, 2, 66, 82, 42,112, 21, -200, 79,158, 34, 47, 19, 90, 6,134,152,209,190,122,140, 27,223,123, 29, 63,255,217, 7,248,224,253, 55,240,191,255,251,255, 23, -127,253,247,159,169,167,219,192, 34,179, 30,229,149,187, 39,184,119,123,131,235,253,130,197, 85,212,157, 67,216, 12,216, 21,131, -253, 85,193,176, 25,216, 83,110, 85,120, 36,122, 23,234, 52, 69, 21,187, 18,230, 88,171,255,194, 24, 42,216,100, 84,175, 74,120, -121,246, 12, 69, 58,166,156,145,139,252,127, 38, 46,122,219, 3, 93,235,202, 79,220, 26,163, 68, 61, 95,188, 18,178,209,185,220, -214,244, 78,178,119, 45,189,192,148,131,177,148, 2, 87,233, 82,179,206,193, 54, 71,197,178,119, 48, 28,138,148,139,104, 9, 8, -174, 98, 12,217,188, 98,140, 12,149,113, 60, 9,160, 85,198,198,145, 16, 45,142, 17, 13, 70, 11,113,201,118, 40,133,172,149, 34, -250, 18,119, 2, 21, 27,180,230, 27,198,128,221,245,172,130, 44, 17,204, 73, 24, 83,102, 61, 2,249,208,179, 30,252,146, 29,111, -141,225, 46,153, 46, 95,177,111,229, 84,148,115, 47, 22,176,196,209,163,178,186, 19,152, 15, 17, 37,187, 79, 94, 46, 83, 0,172, - 55,234,171, 46,239, 37, 2,218,232,247,148,115,102, 7,129, 88,215, 12, 89,205, 10, 93, 70,203,156, 84,189, 46,252,122,231,168, -137, 18, 23,204,213,229,142, 44,105,203, 76,205,155, 49,112,142,222, 37,217,151, 3,253,236,246,222,107, 4,182, 97,157,150,243, - 86, 69,207,149,207,158,202,234,247, 82,136,121,208, 0,204, 83, 87,203, 31, 32,227, 84, 4,199, 77,201,203,227,117,115,104, 21, -147, 98, 8, 47,255,251,151, 8,111,162,255, 18,102, 75,171,135, 33, 84, 26,100,179,182,211,241,197,109,209, 39,121,130, 70, 23, -189,152,196,145, 91, 99, 15,132,124,142,139,227, 46, 20,109, 42,164, 62, 20,144, 86,190, 19,107, 23,159, 43, 32,205,177,240,218, - 35,132, 1, 33, 70,248,117, 52, 31,125,128,194, 15, 11, 71,186,177, 2,190,171, 90,187,146, 64, 0, 16,209,143,200, 11,209, 40, -228,192, 32,152,128,231, 37,191,215,157,157, 42, 49, 13,169,215, 83, 74, 24, 55, 3,134,113, 32,213, 59,255, 70, 50,167, 18,165, -133,162, 12,155, 86,201,189,202,182,130,109,244,110,245, 53,113, 32,205,202,187,217, 69, 52,107, 32, 77,210, 42, 93, 2, 87, 66, - 12,154,205, 43,226, 5, 18, 61, 89,237,222,125, 96,177, 29, 67, 18,214,170,221, 16,250,206,164,178,223,115,217,207,202,232,213, -140,241,117,224,170,248, 12, 25,200,239,189, 69, 28, 6,124,240,147,127,133,253, 28,241,245,111,159,224,242, 98,194, 48, 58,204, -231,191, 65,218,159,106, 21,215,140,225, 73,121,101, 10, 32,141,201,198, 49,104, 49, 99,172,129,101, 93,123,145,209, 0, 40,176, -133,246,118,232, 99,102, 46,101,213,182,195, 35,193,156, 73,143, 32,118, 66,177,182,201,255,134,205,160,108,120,231,233,162, 73, -203, 66,176, 16, 67,137,108,206, 90,212,146, 56, 46,145,105,121,181,168,168,208,135, 8, 63, 12,236,192, 48,188, 43,109,216,167, -138,103,103,123,220,187,115, 4,111, 28,210, 50,211,139,151, 59,233, 43, 23,131, 96, 29,204, 38, 98,140, 14, 87,206,160, 2,184, -220, 45, 72,153,190,254, 79, 63,253, 10,223, 60, 57, 83, 54, 64,206, 85,139,144,155,199, 91,252,155, 63,254, 16,119,239,222,212, -195,197,240, 30, 82, 69,149, 44, 76,249,230,225,115,156, 95,237,180,136,187,117,235,132, 18,237, 4, 18, 52,207,104,121, 70, 46, - 5,181, 88,180, 12,184, 84,145,207,118,152, 83,193, 56, 6,252, 15,255,253,159,226, 79,255,245,251,248,159,255,183,191,197,103, -143,206,104,143,207, 72,205,247,223,190,139,215, 95,191,133,221,245,132,253,133, 67,157, 79,177,179, 6,203, 64, 94, 99,159,174, -212, 75, 46, 69, 51,184,163,232,158,115, 3,138, 90,162, 46, 93,230,114, 70,196,167,202,133, 0, 11, 42,141, 90,178,202,188,144, -142, 37,103, 36, 6,175, 52,190,124, 75,173,186,191,215,220,103,198,178, 90,103, 81, 42,113, 26, 12,228,128,166, 34,208,113,178, -163,109,102, 69,197, 2,235, 62, 4,108, 67,157,106, 3, 77,217, 98,164,174,146, 14, 43,191,130, 87,101,132, 64, 68, 55, 10,242, - 33, 33, 31, 77,128,160, 29,152,115, 14,195, 72,221,229, 50, 39,238,186,105,101, 49,239, 23, 77, 78, 44, 44,144, 21,182,251,192, -145,172, 57, 23, 42,240, 1,132, 13, 81,232,196, 37, 19,130,165, 92,119, 97,113, 48,222,186, 49,177,178, 49, 11, 97,158,178, 6, - 30,129, 15,116, 97,179,139, 37,174,182,138,178, 80,211, 34, 89,235,211,148,120, 68, 78,157, 51, 21,178, 75,207,212,174, 77,127, -151, 50,102, 39,145,154,215, 11, 77, 10,120,107,193, 63, 71, 71, 63, 71,177,206,101,106,174, 42, 11, 59,247,251, 9,181, 54,140, - 99,212, 12,248,194,235,132,253,126,194, 60, 47,152,167, 25, 75, 74, 84, 28,240,217, 66, 2, 46, 18,224,102, 94,211,138,107,167, - 25, 42, 54, 68,136,108, 45,227,136,249,210,147,194, 48,132, 1,203, 66,188,119, 25,201, 87,214, 79,201,148,180,169,195,163,169, -127,222, 50,238, 26, 85,232,151,135,233,113,253,194, 62, 84,196,137, 43, 71,129, 95,181,117, 62,188, 53,250,126,136, 7,188,113, - 51, 35,106, 55,153,178,233,223, 93,249,204, 73, 95,149,117,117, 93,106,159,178, 72, 7, 46,133, 65,237, 9, 69, 93,160,186, 90, - 6,116, 24, 13, 61, 47,142,223, 29,153,182,121,231,233,220,244,145,217, 1, 4,108,242,122, 17, 58,199,106, 67,195,233, 99, 78, -115,181, 41, 38,147,163, 49,115,209, 48,118,160, 40,188, 69, 34, 59,141, 37,218, 17,177,140, 11, 98, 28,104,231,196, 59, 29,122, -201, 50,188,115, 72,185,240, 47,153, 42, 70, 18,110, 8,201,172,104, 14,241,180,159,180, 26, 11, 12,116,209,221,184,100,131,219, -126,153, 58, 33,239,176,189, 74, 94, 70, 82,140, 86, 69, 76,210,247, 7, 78, 30,242,100,115,210,157, 63,133, 43,200,104, 75, 84, -198, 11, 43,155,173, 53, 92,245,123, 29, 25,130, 65, 25,146,251, 43,191,240,174,218,132,190, 8, 82, 36, 89,223, 3, 18,208,128, - 56, 30,225,163,159,255, 91, 60,127,190,224,209,195,167,164,242, 29, 26,234,245,111, 96,234,165,238, 82,117, 23, 67,244,114, 61, - 44,135,129, 68, 66, 52,113,224,148, 55, 33, 53, 25, 11,235,233, 65,145, 68, 37,128, 14,154, 97, 28,200,179,238,201,106, 87,120, -199,157, 82, 34,177, 28,239,199, 41,128,163,233, 97,130,214, 5,148,210, 57,144,215, 89,190, 71, 17, 51, 45,202,210,119, 22,156, -103, 77,227, 85,207, 83, 4,178,239,241, 85, 81, 43, 66, 48,184,190,158,177, 44, 5,231, 87, 11,198, 96,177, 29, 28, 78, 78, 54, -112,195,128, 96,216,185,176, 79, 72,185, 98, 24, 35,106,169, 24, 51,127,206, 37,225,139,175, 31,227,171,135,207,113,181,155,180, -184,107,204, 10, 88,150,132, 87,238,222,192,159,252,252,135,184,121,235, 68, 71, 95,104, 92,116, 58,192, 27, 67,128, 24, 3, 44, -243,130,143, 63,125,160, 7,198,173,147, 13,190,255,238,107,200,133,105,103,198, 2, 33,162,109, 78,128,122, 14,211, 26, 76,176, -104,195,128, 92, 27,246, 83,162,223,167, 55,120,227,245,187,248,159,254,199, 63,199,211,211, 43,252,195, 63,126,129,191,253,231, - 47, 80, 27,240,193,219,119,241,202,189, 35,236,183, 30,211,198, 35,205, 39,216,219,107, 76,209,227,203,103,123,108,143, 2,119, -205, 14,214,117, 49,143,117,140,232, 21,222,128, 49,171,192, 7,195,106,231,172,157,185, 91,225,157,115,106,252,140,100, 69, 41, - 75,130,151,117, 70,237,104, 61, 13,106,197,157,144,177,103, 45,164,113,200,137, 99, 55, 57,143,129,211,204, 12,119,242,114, 72, -107, 49,194, 2, 83,205,132,230,206, 37,165,207,235,114, 52, 0, 0, 32, 0, 73, 68, 65, 84, 76,239,219, 76,122, 15, 31,131,174, -223, 42, 3, 95,100, 85, 32, 59,247,148, 10,226, 40, 44,137,238,165, 30, 54, 3,172,161, 93, 61, 26,224,188,213,179,141, 50,199, - 9,173,234, 71,183, 34,210, 89, 14,152,138,106,253, 75, 83,214,212, 51,129, 91,137,197,181, 73,236, 44,141, 37,116, 50,135,118, -152, 50,166,211, 44,158, 68,101, 38, 9,122,239,176,223,113, 3, 96,160,206,130,101, 89,212,141, 34,209,171, 49,138,207, 30,154, -154, 38,103,165,168,204,197,130,215, 42,120,194,210,243, 60,150, 37,163,228,138,253,126, 81,110, 70, 8,158, 19, 39, 61, 11, 88, - 19,246,251, 25, 57, 23, 76,211,172,133,189,236,216, 75,173,202,117, 87,203, 31,191, 63, 50, 89, 81,164,105, 21, 4,117, 95,187, -120, 7, 36, 86,249,207,243,158,197,193, 6,185, 85,125,182, 68, 4,166, 46,142, 86, 97,109, 64,179, 85, 47,121, 83, 43,165, 69, -114,195,164, 72,233, 53,101,141,119,223, 93, 11,213, 84,192,221,173, 35,125,207,222,148, 70, 99,180,219,110, 60,242,151,224,162, -158,113, 98, 14,210, 3,233, 46,229,117, 28, 41, 64, 58,197,145,129, 40, 7, 76,119,211,109,118, 77,146,229,196, 49, 98,176, 90, -207, 8, 60,202, 50, 59,192, 35,198, 17,206, 7,120, 31, 16,130,216, 16,121,252, 46,130,145,218,232,194, 33, 22,187, 81, 65,148, - 70, 9, 90, 7, 19,250, 30,200, 57,131,165,204,156, 81, 76, 35,130, 16, 2, 77, 75,208, 35, 57,105, 92,237, 52, 20,194, 8,254, -208, 24, 84, 70,182,134, 56, 80,167,236, 28,141,218,121, 60,187, 44,179,122, 48, 3, 35, 8, 29,219, 42, 42, 43, 57, 87,136, 1, -181, 92,248, 96,120,127,196, 74, 74, 67,156,103,231, 44,102, 86,115, 58,142,249, 28,199, 81, 65, 13,133,153,239,162, 16,149, 93, -161, 53,188,183, 19,109, 7,119,249,214, 90, 24, 14,120,209,145, 94,202, 60, 30, 35, 13, 66, 8, 52, 14,164,145,148,213, 75, 92, -248,202,181, 20, 52, 99,112,231,222,171,120,239,199, 63,199,215, 95,190,192,233,243, 75,236,247, 9,193, 37, 44, 23,191, 69, 73, -179, 94,222, 70,246,177,214,195,170, 87, 81,252,165,134, 85,167,236, 73, 45,132,182,172, 60, 85, 49,142, 2, 32,188,243,236,199, - 38, 95,105,202,148,109, 94,138, 81,255,115,206, 5, 75,162,159,253, 60, 47, 26,196, 51, 12, 17,243, 68,138,245,156,178,142,200, - 74,149, 92, 87,104, 48,142,128, 71,122, 44, 35,161, 61, 3,127,173,224,143, 41,130,193,212, 42, 41,150, 99,132,243, 13,251,139, -132,218, 12,174,175,175,224,156,197,253, 87, 79, 96, 99, 67, 28, 0, 83, 9,222, 33, 32,156,253,190, 33, 45, 25,211,110,198,167, -159,126,141,211,243,107, 60, 61,187, 90,185, 13,232, 99,207, 75, 70, 12, 22,119,110,157,224,103,127,248, 35,248, 24,201,202,103, - 9,207,235,172, 69, 93, 22,114,126,248, 0,239, 44, 98,240,184,188,184,198,233,249,181, 22,134,223,187,127, 7,145,129, 75,213, - 68,128, 59, 35,187, 61, 65, 59,190, 9, 87, 22,196,237,136,102, 3,255, 12, 9,107, 91,155,195, 92,169, 96,120,235,173,251,120, -239, 7,175,227,205, 55,239,224, 63,254,229, 47,240,253,247,223,192, 38,122,108,134,128,116,188,193,126,185, 66,216,239, 17,173, -193,220, 26,134,193, 0, 28,150,132,182, 18, 10,213,170,123, 57,210,136,148, 85,120, 18,217,244,106, 17, 76, 43, 57, 67,212,186, - 90, 42, 90, 38,215, 65,169, 69,133,167, 50,181,129,237, 23,185, 30,102,102,133,213,108, 21, 21, 6,104,137,153,235, 6,214,208, -115, 69,110,153,126,160, 67, 69,178, 12,187,226,253,127, 97, 11,165,227, 46, 57, 4, 46, 68,216,255, 46,220, 8,153,188,213, 10, -164,165, 96, 24,233, 57,150,139,172,148,170, 69,182,116,231,109,181,202,171,149,164, 10, 98,189, 13,209,234,174,190,177,110,198, - 25,135, 16, 57, 61,145, 57,237, 37, 23,120,103,176,148,238,101, 10,129,222,101, 25,185,246,124, 4, 18, 62, 46, 53,235, 52, 69, -138,252,162,171, 75,139,194, 56,107, 26,121,139,104, 22,156, 68, 71, 63,239,192,136,222, 56, 16, 50, 87, 98, 75,181,120, 83, 78, -134,209,241,119,226,241,185,100, 91,180, 66,223, 63,217,226,154,238,215, 55,155,129, 29, 29, 78, 25,239,251,105,194,180,159,121, - 21,192, 33, 82,173, 11,220,188,119, 7,206, 45,175,151,119, 15,126, 89, 75,211, 72,173,158,217,210, 75, 63, 35,209, 41,208,249, -212, 85,236,194,251, 79,203,220,137,137,192, 74, 3, 96, 87, 30,242, 85,250,153, 92,188, 44, 26,163, 34,171,112, 67, 70,226,101, -237,204, 1, 93,175,174, 19,236, 84, 95, 96, 44, 33,174, 57, 73, 79,180, 93,208, 9, 85,183,104,202,101,143, 70,235, 60,211,253, -111,170,189, 48, 2, 50, 91,189,139,198,172,195,101,192,123,118, 28,252,236, 36, 5, 81,157, 23,198,194, 26,139, 56,140,136,113, -128,115,129,186,244, 16,224, 44,199,216,130,166, 3,222, 58, 75,249,214,181,161,181,172,121,230, 18, 99,168,213, 48,167,152,213, - 74, 52,183,121, 94, 52,166,177,178, 90,188, 7,165,116,245, 36,154, 97,251, 90,235, 23, 41, 95, 74,214,209,131,109, 29,117,201, - 96, 6,176,247, 14, 19,143,173,209,170, 10, 54,188,183,136,209,235, 40, 52,165,110, 36,164, 88,208,218,105,109,221, 73, 64,233, - 67,131, 99,193, 15, 41, 76, 73,212, 36, 32,142,195,177,189, 40, 24, 11, 11,224, 90,173,176,129,168, 61,150,247,113, 84, 25,117, -251,136, 42, 42, 88,100, 68, 29,189,225,209, 9, 84, 73, 79,225, 47,153, 31,206,158,212,245,250, 59,239,226,205, 31,124,132, 47, - 63,123,138, 39,143,207,201,198,227, 38,164,171, 47, 81,203,194,194, 11,167,100, 33, 26, 48,175, 41,112,142, 15, 63, 30,231, 84, -131,153,247,190, 96, 21,102, 74, 5,109,166,120,219,181,178, 85,170,217, 82,233,176,174, 13, 60,178,236, 93,160,172, 29, 90, 35, -191,186, 11,180,199,172,124, 41, 11,217, 73, 68, 78,173, 85, 30, 75,211,158,207, 59,122, 14,132,145, 45,170,124,177, 84,145,198, -193,234, 97,212,106, 65,205, 51,114, 14,176, 28,170, 49,110, 34,174,246, 9, 46, 82,254, 54,150, 25, 25, 14, 67,164, 67,191,230, - 5, 79,158,158,227, 31,254,233, 51, 92, 79, 51,166, 41, 97,224,137,145,247,150,139, 79,250,122,239,222, 58,193,239,127,244, 3, - 12, 3, 21,138, 75,170,176,174, 17,241, 13, 36,184, 51,180, 72,132,177, 52,242,123,248,232,185, 86,217,181, 20,188,245,189, 87, -121,215, 90,117,215,153, 18, 16,188,129,241, 14,110, 60, 65, 54, 13,166, 2, 1,148, 63, 79, 56, 97,154,248,212, 82,176,219, 39, -196,232,240,195, 15,222,196,171,175,222, 66, 8, 30,167,207, 47, 16, 6,206,236,206, 25,129,211,199, 30, 93, 37,140,175, 17, 92, - 8, 76, 86, 19, 2,164,216,129,100,127,106, 12,131,144, 12,217, 43,133, 18, 38, 34, 36,152, 66,156,127, 5, 71,149,213,142,222, -173,114,190, 1,163, 23,187,129, 53,140,117,134,236,140,165,240,109, 29, 82,101, 44, 44,199,170, 58, 23,248, 29,160,201,135,248, -137, 73,216, 42, 62,110,192,201,193, 38,180, 60,230,124,203,182,180, 53, 82,108, 55, 62,232,156,119, 24,199, 65,249, 22,206, 83, - 78,119,101, 81, 42,133,186,208,154, 37,231,196,177,189, 22, 3, 79,176,104,175, 91, 72,151,210, 58,174, 57, 70,202, 1,240,190, -175,237, 12,179,212,211, 34,201,142,244, 94, 9,113, 80,127,246, 60, 78, 71, 51,152, 57,155,220,240,101, 40,221,186,186, 8,100, - 44, 15,225,201,211,133, 73,238, 21,154, 22, 24,214, 49,201,179, 21, 3,187, 6,120,212, 76, 54, 93,163,192,175, 90,123,104, 85, -201, 92, 92,167,172,116, 79, 31, 60,182, 71, 81, 11, 51,185,228, 82,206,104,149,112,181,251,253, 68,211, 27, 46, 12, 66, 8,138, - 38, 38,225,107, 85,225,154, 93,165,249,145, 20,203,194,122,187,178, 60, 26, 94,233,201, 36,145,248, 15, 98, 53,108, 10, 73,162, -208, 42,231, 44,230, 37,105, 7, 92,107,101,198,131,225, 40, 86,167,150, 75, 17, 23, 66,211,203,136,114,214, 51,200, 29, 92,147, - 12,117, 62,107, 44,116,116, 46,229,128,124,157, 13,253, 44,196, 10, 80,211,208,180, 40,173,171, 40,226, 53,150, 85, 56,234,109, -197,144, 23, 75,154, 85, 34,129,170,236, 86,169,149,185,211, 0, 69,240,103,176,226,204,247, 41,236, 48,110,169, 51,119,158, 39, -155,158,105,139,172,157,224, 9,150,181,150, 2, 93,136, 76,196, 22,179, 74,225, 30, 30,157,254, 35, 29,165, 40, 17, 43, 3,254, -115,206, 36,192,226,200, 68, 81, 99,247,168, 81,199,151,111, 81,219, 68,230,151, 64,208,133,196,162,166, 74,195, 59,122, 65,151, - 37,233, 65,179,223, 77, 60,178,117,170,246, 36, 90, 29, 16, 3, 69, 41,150, 90, 52,138, 85, 82,211,156,183,200,198, 48,228,197, -118, 86, 46,132, 64,199,217,202, 43,168,130,243,172,116, 87,190,240,106,223,209, 64,182,157, 74, 69,143,170, 26,249,101, 33,155, - 29, 65, 93,114, 41, 42,160,169,170, 87,232,213,112,109,146,252, 75,151,229,123, 31,253, 62,182, 55, 94,193,111, 63,121,132,179, -179,107,178,249,153, 11,212,253, 99,160, 21,120, 31,213, 17, 64, 2, 45,163, 62,124, 37, 79, 57,187, 82,180,178,183,184, 74, 74, - 84,165, 41, 71, 41,176,177,211,200, 28,195, 56, 4,132, 39, 47,248, 50, 83, 96, 78, 45, 21,227, 56,112, 26, 84, 83,209, 80,145, - 46, 60,103, 46, 22, 18,115,156, 11, 9,225,248, 82, 22, 1, 33,165,112, 69,130,246,136,213, 70, 67,132, 9, 11,219, 84, 84,213, -144, 89,244,211, 90,198, 56, 4,108,142, 6,148,218,144, 43,161, 20, 47, 46,246, 56,218, 4, 26,135,213,134,105,166, 61,230,215, - 95, 63,193, 63,255,234,115,204, 11,253,140,130, 39, 10, 92,169, 21, 45, 53,141,194,252,225, 59,175,226,207,254,155,159,192,123, -135,203,171, 5,215,187, 5, 46, 58,160, 20, 20, 88,100, 94, 61, 12,129,178, 2,140, 1,246,251, 5,159,125,241, 84, 41, 94, 55, -182, 35,222,184,127,139, 66,126,172, 37,219,166,115, 88, 82, 65, 42,228,142,168, 75,194, 38, 58,152, 70,194, 40,103, 45, 39,157, - 1,206,210,237,126,113,118,197,135,140,197, 38, 90,124,252,215,127,135, 99, 87,113,252,214,235,184,249,234, 93,184,203, 29,114, -105, 56,155, 50,158, 76, 51,222,181,125, 63, 88, 43,117, 62,181,244, 93,183,138, 68,209,159, 99,233,220,235,234, 82, 65,169, 4, - 37, 49,134, 67,131,172,174,136, 10, 67,147, 68, 76,215, 12,173, 68,172, 6, 14, 97, 21,145,107, 15,130,141, 36,156, 39, 37,214, -121,128, 68, 66, 33,132,149,158,134,247,132, 28, 75,186,206,154, 22, 68,168, 93, 5, 74, 25, 14,239,161, 38,195,179, 91,134,153, - 12, 32,251,163,115, 30,113,136,240,193,169,192, 77,118,250,148,171, 62,174,172, 72,189,179, 52,177, 39,204,165, 36,225, 37,166, - 63,239, 60, 46,157,167,164, 93,153, 56,103, 44,139,252, 90, 46, 44,216, 51,236,182, 41,250, 57, 10, 39, 87,138,186, 90, 0, 63, -148,149,158, 0,239, 52, 25, 78,199,242,181,175,177, 26, 79, 17,192,214, 95,195,182, 46, 65,227, 46,105,230,208,150,164,121, 9, -210, 48, 58,239,177,217,110,116,202, 33,133,133,136, 63, 97, 12,174,175,246, 52,157, 97,193,160,120,224,181, 43,230,139, 55,120, -182,165,114, 49, 78, 26, 8,167, 35,231, 82, 42,224,173, 98,156,151, 37, 49,159,160,112,195, 85, 86,138,124,126, 7,156, 67,229, -244, 76,154,208, 46, 52, 37,211, 73, 40, 7,242,212,166,150, 99,231, 2,188,231,179,134,237,124,204,239,212, 38,100, 77,123,171, -171,155,214,172, 56, 14, 52,190,127,169, 11,111,141, 32,106,194,101, 41,245, 64, 84, 39, 23, 58, 86,240, 25,105, 18, 14,214, 96, -171, 72,225, 90,215,239, 38,123,243,209, 39, 86,135,196,120, 14, 6, 99, 16, 24,233,180, 6, 12,227, 6, 33, 12, 44,130,244, 92, -204, 27,196, 16, 14, 82, 51, 45,120,181,172, 22, 47,126,226, 43,197,111,145, 21, 73,204,239, 6,176,193,116, 80, 64,105,106,133, -104,172,152,151,221,217,126, 55,117,201,191,165, 46,137,108,106,125,207, 76, 35, 14,171,223,200, 48,142, 42,214,178,204, 85,174, -173, 98,222,207,164,144,110, 34,162, 33,241, 30, 93, 26,156, 3,237, 45, 76, 37,212,170,147, 93,150,181,112, 43,220, 30, 49,156, - 89, 44, 18, 61,137,108, 66,224, 21, 0, 61, 92,106,109,121,137,126,149,115,134,231, 95, 84, 78, 5,155,237, 8,239,237, 1,118, - 81, 94,154, 90,233,229,215, 8, 76, 57,232, 26,186,178, 22,253,161,218, 30,111,241,225, 31,254, 12,251,201,224, 55,159,124,131, -171, 43,202, 13,246,245, 57,234, 66, 93,161,143,131,218,224,156, 51,240, 49,104,130, 17, 21, 14,150, 5, 64,208, 17,167,181,238, - 32, 64,194,112, 46,118,107,142,139,148,170,144, 6, 99,161,126,246,214,138,102,155, 75, 2,223, 60, 47, 12,219, 1,219,138, 72, -184, 51, 77,115,127, 28, 45,141,204,164,203,118,214,210,224,194,146, 56,199,123,175,121,236,237, 96, 60, 7, 61,164,188,167,130, -136, 14,170, 4, 3,131,113,140,104,150,214, 50,187, 61,185, 23, 74,109,152,115,198,178, 20, 68,111,224, 13,237, 91, 81, 42,230, - 57, 33,241,129,186, 44, 69,247,179, 98,171,114,214,225, 15,126,244, 54,254,224,247,222,134,115, 22, 67,244, 24,238, 4,220,184, - 49, 98,154, 18, 22, 94, 83, 80,144, 15, 65,143,198,145,168, 90,159,125,246, 8, 47,174,247,136,209,195, 89,139,119,190,119, 15, - 71,219, 1,198, 91, 68, 68,202, 29,135,193, 16, 88,131,194, 72,214, 92, 10, 70, 79,222, 96,103, 13, 12, 44,218,178, 32, 47, 9, -203,126,194, 38,122, 44, 25,200,243,140,203,175, 30,163,238,102, 92,123,139,103,167,159,227,248,238, 41, 94,189,127,130, 0,131, -127,122,112,137,241, 8, 8, 67,208,131,183, 11, 92,173,186, 61,196,210, 36,116,178,202,208,142, 34,227,245, 66,151,147, 31,142, - 56, 52,200, 29, 8, 92, 5,242, 1,201, 74, 55,178,138, 34,112, 15, 69, 35, 67, 99, 99,165, 99,171, 28, 44, 99,180,176, 44,122, - 96, 69,222,247, 54, 0,110, 5,212, 38, 2, 98, 81,154, 22,217, 75,171,198,151, 2, 21,214, 54, 94, 59, 12, 88,230,132, 56, 90, -118,188, 20,132,208,224, 24,223, 28,162, 95, 49,221,141,102, 42,148,131,139,168,123,133, 61, 59, 95,156, 51, 74,149,140,209, 43, - 14,213, 49, 16,136, 70,239, 25, 33, 88, 76,123, 81,181,247,192,151,202,214, 71,234,150,165, 97, 97,204, 50, 95,178,142,119,194, -180,102, 12, 12,199,114, 24, 54,163, 82,238,140, 53, 74,194, 52,166,168, 29, 45,142, 68,119,155,167,133,214,104,153,178,200,107, -201, 88,230,180,178,246, 90, 14, 20, 34,174, 70,136, 3, 77, 78,121, 10, 71, 33, 47, 84,224, 79, 19, 65,165, 72, 97,223,244, 89, -161,143, 19,176,164,140, 16, 60, 18, 23, 42,206,137,122,220, 43,233, 48, 70,163, 57, 25, 69,178,220,249,114, 35,224,213, 33, 77, -208,241,244,150, 46, 97,187,138,161,109, 10,255,146, 96, 26, 99, 56, 13,148,159,107,141,183, 46,101, 69, 26,101,205, 83, 43, 48, - 21,186, 42, 57, 96,191, 27, 3,167, 29,181,237,194, 81, 0,173, 57, 62, 7,125,183, 10,178, 80,216, 57,219,195,110, 90, 61,136, - 96,237,163,127,113,114,208,125, 99, 86,151,183,218, 30, 91, 15, 57,106,170,136, 95,121,230,185,200, 49,104, 26, 55, 13, 22,149, -142,227, 6,222, 15, 24,134, 1, 62, 68, 86,185,155,190, 83,231, 92, 21, 97,175,136, 13,181,214, 12,111,157,103, 17, 4, 39, 54, -101,242, 95, 59,231,184, 98, 47,138,128,244, 44,184,114,193, 33, 39,254, 34, 45, 86, 48,121,202,201, 45,133,136, 65,212,253,146, -141, 65, 70,239, 82,181, 18,167,217,193, 27,143,113, 35, 36, 57,207, 93,166,195,180,167,177,217,180,159,244,112, 50, 98,229,209, -212, 47,186,204,169,211, 22,159,119,133,231,253,152,179,182,143,140, 60,117, 3, 85,162, 85,105,104,174, 93,122,169, 21,145, 81, -183,166, 90,173, 74,187,170,150, 40,108,210,241, 59,111,216,242,103,148,136, 84, 50,123, 92,185, 80,144,248,196,182, 30, 1,241, - 3,242,202,253,251,248,224,199, 63,198, 55, 15, 46,240,232,225, 25, 95,212, 5, 54, 63, 69,201,215,196,220,175,108, 93, 17,149, -113,115,224, 33, 5,143,220,141,218,227,192, 99, 44, 70,166,243,154,193,178,143,191, 39, 21, 9, 43,160,214, 30, 67, 75, 93, 67, -230,203,157, 3,109, 26, 9,168,164,170,167,106,184,251, 49, 27,219,217,100, 45, 34,196, 65, 81, 56, 12,227,134, 63,191,215,160, - 23, 24,232, 88,148,112,171,204, 29,119, 52,202, 47, 37,163,149,140, 97, 24, 96,141,193,146, 44,246, 51,197,174, 6, 78,218,195, - 74,105,124,149, 42,198,104, 49, 14, 21,193, 91, 21,238, 8,209,204, 27, 96, 97,228,238, 56, 4,252,236,167,239,227,221,183,239, -163, 90,224,252, 98,194,149,157,176,221, 12, 24, 55, 1,199,219,128,156, 28,230, 76,163,116, 58,127, 88,141,189, 44,248,197,167, - 15,177,217, 12,188,151,183,120,235,173, 87,169,112,225,145, 45, 93,124,149, 89,224, 68,246, 41,203, 2,164, 5,109,160, 84,182, -105,183,135,171, 20,144,212,114,129, 31, 2,130,179, 8,206, 34,239,174, 81,230, 25,115,169,152,115, 67, 78,192, 89,187,198,105, - 5,218,229, 21,126,241,236, 26,183,239,121,141,230,236, 43,162,172,227, 87, 69, 19,151, 46,102, 92,150,153, 5,112,185,103,100, -163,193,175, 28, 24,114,152, 8,213,171,241,184,188, 19,234,232, 89, 19,120, 16,117,210,224,152,214,254,247,105,252,158,245,226, - 44, 44,220,211,247,223, 19,104, 70, 98,177,122, 78,116,247,169,175,243, 32,132,151, 96,154,197,126, 63, 97, 24, 6,164,133,196, - 64,162, 83, 9,222, 97, 24, 7,125,223, 8,160,226, 84, 72, 22, 98, 64,157, 22, 44,115, 70, 28,131,238,109,125,164, 6, 33, 39, -201, 33,160, 38,220,179,147,160,115,202, 91,119, 7,112, 4, 52,173, 12,120,111,234, 27,176,116,234,154,230, 70,240,152,188,175, - 45, 43,210, 82, 49,140, 1,227,134,247,227, 44,208, 51, 60, 65,162,206,159,246,194, 62, 24,245,169,239,174, 39, 24,211,176,223, - 77,180, 51, 79, 11, 26,107,117,198, 13,173, 32,136,184,103,123,214, 72,109,100,253,227,194, 66,172,106, 57,101,162,185,173,196, -174, 26,173, 45,232,217,149,131, 64, 46, 50,129,234, 84,222, 51,147, 45, 57,171, 30, 65, 71,241,102,165,167,226,241,189, 76,141, -132,199, 33,209,202,146, 16, 41,163,107,199,226,233, 16, 34,114, 78, 7,222,111, 25,243, 31, 98,135, 89,239,101, 61, 26, 42,156, - 13, 42, 14,149, 73, 79, 59,184,200, 1, 99, 59,100,200, 52,187,202,140,239, 84, 76, 29,171,211, 83, 77, 23,186, 61,204,131,177, -198,105, 66, 31,197,145, 59, 21,125, 98,117, 89,195, 64, 87,216, 26,242, 98, 59,163,194, 88,195, 43, 95, 10,151,114, 62, 96, 24, - 54,136,195, 8,239,131,174, 85, 67,136,135,153,110,214, 42,196, 77,222,125,177,115,122, 17, 32, 72, 53, 27,135,240, 18,120,159, -118,201, 26, 45,200, 59, 32,177,167, 73,183, 70, 9, 76,244, 0,133, 16,116,183, 64,135,185,213,228, 37,241,165,202, 40,125, 28, - 3, 54,155,145,136, 78,188, 47, 73,243,172,187,161,198, 81, 72,194,188, 37,239,183, 67,224, 84, 39,103,165,131, 23,200, 10,253, - 16,156,181,148,247,205, 80, 24,177,204, 20,206,248, 54, 26, 98, 67, 39,201,102, 51,232,215, 78, 26,129,176,170,182,170, 50,167, - 7, 62,160, 13,243,158, 19,227, 33, 75,238, 25,201,242,226, 59, 86,200,211,184,205,178,159,222,224,237,247,223,199,171,111,190, -139,207,127,243, 12,103,167, 87, 76,223, 90, 96,210, 35, 21, 5, 86,217,243, 8, 78, 87, 44,113,206,161, 84,135,146,232,224, 22, -219,139, 5,237,209,197, 38,100, 33,105,115,141, 61,241,134,169, 89,149, 43,253,194,122, 8,186,160,209,138, 10, 82,114, 46,152, -247,179,134,180, 24,219,208, 56,228,132,196, 51,137, 53, 3, 50, 5, 73,154,170, 39, 1, 16, 97,136, 93, 20, 98, 13,172,241,170, -150,182,214,194,242,248, 51,231,130, 92,168,115,117,206, 34,140, 35,134,113,164, 19,214, 2,184,172,136,129, 88, 7,214,208,168, - 61,115, 18,160, 5, 48,205, 52, 85,218,142, 30,251,253, 2,163,235,162,134, 31,190,113, 11,159, 61,190,196, 62,101,164, 84, 48, -207, 25,187, 41,209,250,164, 17,138,183,154,140,210, 12, 66, 48, 8, 14, 24, 96,208, 66, 84, 1, 90, 45, 21, 15,158, 93, 81,152, -203, 74,135,112,251,246, 13,174,150,169,140,137, 30,100,173, 27,131, 70,143,238, 77,192,139,165,226,250,244, 18,131, 7,124, 43, -216, 68,131, 60, 47,204, 91, 15, 40, 67, 64, 43, 25,121,218,227, 60, 37, 60,153, 19,246, 12,131, 50,245, 28,126, 54, 48,166,226, -214, 27,130, 46,229,136, 90, 25,215, 53, 40,195, 97, 89, 22,221,141,231, 76,221, 28,233, 55,186,232,168,234, 36,167,194,219,174, - 2,151,247,145,222, 85,186,144,170,116, 23,132, 58, 99,184, 75, 99, 29,133,213,189, 61,157,127, 2,167,177,108,139,229,140,238, -146, 81, 91,195,104, 54, 12, 49,137, 10,140,178, 28,242, 35, 98,209,181, 71,183,105,184, 80,161, 76,117, 31, 48, 47, 11, 9,120, -115,233, 7,190,233, 29,112, 28, 60,246,187, 25,219,163, 13,156,167, 34, 37,250, 64, 54, 59,211, 20, 11,173, 35,108,153, 30, 24, -254, 94, 45,212,237, 82,185, 75, 23, 16,148, 0,109,140,137,122,232,147,184, 13,188,162, 97,122, 93,140, 36, 46,171, 89,207, 75, -225,219,135,104, 87,211, 52, 90, 13,202,153, 81, 43, 49,190, 75,174, 61,189,144,179, 16,168,216, 42,204, 88,247,136,131, 87, 61, -147, 40,252,231, 57,241, 68, 17,168, 57,179,123,160,169,138, 93,113,175,173,155,189,100,125, 67, 17,205, 21, 41,167,213,184,124, -109, 33,230, 85,112,163,189,122,230, 41,132, 83, 53,183, 56,144, 58, 97, 83, 5,117,132,160, 96,180, 43, 84,233, 47, 93,181,129, - 69,169,153, 69,115, 77, 83,249, 76,173, 36, 66,229, 80,152, 46, 24, 51, 42, 44, 3, 23,222,224, 40,110, 81,178,215,182, 22,196, - 85, 56,190,200, 69,216, 70,120,228,118, 96,211,182, 43,160,140,136, 80, 41,195,224,165,117,184,138,221, 44,154, 41,234, 68,146, -181, 34,212,214, 86,149,150,167,155,198,202,145,229,104,108, 65,102,177, 97, 12,112,142, 20,236,162,102,143,195,160,238, 42,209, -148, 88,199,192, 34,209,123, 25,179,154, 8,203,115,221,224, 83, 42, 26,144, 66, 22,151, 76, 35,162,148, 21,148, 34,204, 99, 33, -184, 25,205, 26,150,192,136,130,138, 76, 89,232,141,195, 58, 86,251, 5,121, 1,214,213,133,176,214,157,247,154,128, 38,246,139, -204, 22,145,101, 94,116,188,219,152, 70,229,130, 99,120, 66, 83, 1,130, 96, 25,101, 23, 86, 75, 69, 81, 64,144, 81,229, 99, 63, -192, 86, 9, 78, 13,240,220, 45, 82,231, 75,163, 96,242,193, 58,180, 82,145,115,197, 48,112, 96,138,190,224,230,160, 58,135, 1, -230,169,135, 23,144, 34,215, 40,137, 45,231,130,163,227, 35,252,232,167, 63,129, 15,199,248,237,175, 31,225,226,197,142,159,162, - 75,164,233, 25,156, 39,175, 60,237,170,105,172,226, 56, 56, 66, 42,210,204,163,242,106,233, 48,169, 92,136,228,210, 52,203, 93, -156, 5, 50,242,183,134, 38, 38,114,136, 24,211,187,117, 72,160,135, 53,172, 40, 78,164,232,229, 41,131, 88, 99,140, 53,220,205, -147, 35,193,240,184, 75,248,208,173, 53,238, 26, 60,103, 95,211,222,207, 75,250,148,120,152,141,209,131,107,158, 39,228,133,138, - 24,218,135, 18, 39, 64,212,170, 37, 87,212,156,145,167, 25,182, 21,148, 37,163, 36,177, 21,145,178, 84,178,140,200, 30, 73,187, - 59, 81, 18,159,220,185,133,159,191,249, 6,254,250, 63,253, 2,198, 0, 95,124,249, 8,183,238,220,196,201,201,182,231,203, 87, - 0,169, 32,229,134,113, 28,200, 90, 85, 41,137,205, 25,131,139,139,107,252,237,223,253, 90,127, 30,181, 52,220, 56, 30,177,221, - 6,204, 11,193, 60,130,179,128, 51,112,141, 99, 39,157,131, 65,197, 29,151,112, 35,238,241,252,234, 18,159, 63,206,152,138,193, -141,173, 71,222, 95,225,249,229, 41, 54, 27,135,134, 2, 88, 22, 31,109, 26,236,145,197, 70,154,217,149,224, 38,243, 26, 74,220, - 29,133,217,217,100, 61,203,122,248,211,120,157,131, 95,248, 2, 17, 63,186, 20, 59, 48,158, 58, 22, 30,109,202,127,183, 12,131, - 66,181, 40,173, 80, 14, 4,167, 32, 30,216, 71, 69, 85,189,202,134, 22, 73,144, 6,241, 88,138, 5,149,113,253,178, 76,172,219, -233, 30, 95,222,209,241,101,235, 85,191,178, 70,109, 75,174,123,206, 9,131, 27,176, 44, 51,150, 52, 32,164,140, 56, 52,221,219, -138,119,204, 57, 96,153,103,253, 56,214, 38,254,122, 43,124,112, 10,225,107,181, 11,197,106,147,188,118,168,136,109,173, 79,209, -213, 97, 19, 75, 88,209, 81,115, 41, 4,191, 74, 75,226,194,179,147, 54,107,101,107, 87, 21,110, 57, 77, 58,197,187,109, 12, 56, - 34,213,106, 88,203, 52,205, 58, 78,151, 17,181,229,196,180, 24, 7,214, 21,208, 33,158, 19, 93,244,162, 71, 89,230,132, 6,234, -232,115,202,140,135,245, 36, 20, 13, 1,227,224,137,118,183, 20, 38, 1,250,222,105,243,101,105,184, 89,178, 44, 20,244,222,253, -255,100,189, 73,147, 36,215,189,221,121,238,232, 30,145,145,153,149, 89, 3,166, 7, 2,143, 32, 65, 82,124, 67, 83,175,219,100, -109,210,166,205,122, 39,211,162, 23,250, 52,189,225,119,235,109, 47,212,207, 36, 25, 9,129, 32, 64,176, 48, 87,229, 24,225,195, -157,122,241, 31,174, 39, 69, 51, 26, 73,176,134,204, 72,247,123,255,195, 57,191,195,157, 61,148, 56, 41,204, 11,131, 70,235, 80, - 17, 62,243,253, 32,176, 25,185, 51,160,233,127, 77,133,216, 70,233,119,124,207, 48,218, 88,138, 69,103, 27,130,247,244,207,107, -209,103, 42,165,188, 17, 98,115, 50,167,228, 76, 24,192, 62, 97,186,119, 59,152,243, 34, 6, 47, 58,142,119,182,135,181,202, 51, -169, 59,112,165,203,113, 17, 43, 26, 42,131, 13, 88,198,232,136,221,232,120,157,245, 11, 72, 44,108,110, 42, 40, 53,222,108, 50, -220, 89,212,230, 3, 11,223,232, 34, 31,134, 65,133,168,222,210, 59, 41,196, 61, 33, 65,202,136,159, 62,111,175, 77,181, 68,133, -123,202, 24,230,136, 69, 38,215,104,236, 40, 87, 95,148, 30, 22, 72,101,171,105, 95, 86,237, 35,222, 59,164,106, 55,234, 75,211, - 95, 82, 39,201,103,221, 30, 7, 85,176,146, 98, 53,142, 81,161, 35,242, 97, 81,156, 32,141,132, 67,244, 26, 39,104,216,163, 75, -255,156,241,181, 85,130, 79,248,242,227,174, 49,167,196, 15, 23, 89,220,228, 32, 18,207, 36,125,239,130,144,164, 29,205,186,214, - 39,161, 2,173, 53,134,219,208,139,228, 88,192, 32,212, 36,108, 81,127, 32,127,109,140,129,158, 46, 6,175,132,224,240,252,213, - 43,252,250,159,255, 9, 63,253,240,136,215,159,125,141,121, 78,128, 5, 76,121, 11, 91, 31, 97,130, 87, 54, 60,140,219, 64, 29, - 28,156,231, 49, 56,175, 57,200,167, 44,214, 31,143, 6,203,121,212,134, 3,104,108,167,241,241, 65,180,204,180,151, 79, 43,193, -126, 40,245,138,148,209,165, 84,172, 75,214,207,176,113,184,207,186, 36, 86,235, 23,212, 84,153,163,159, 53,222, 82,188,235,227, - 24,181,114, 23,214,187, 15, 65,167, 44, 0, 16,134,129,119,220,108,151, 91,137,235, 76, 7,150,103, 75, 97, 6,248,249,171,156, -103,110,177, 71, 91, 39,148,165,194, 25, 15,111, 65, 89, 4,173,251,113, 67,244,202, 75, 88, 20, 22,100,225,199, 61, 46,159,157, -227, 23, 63,127, 31, 95,126,245, 61,230,148,240, 95,254,191, 63,226, 31,255,225, 19, 92, 95, 93,170,168, 51, 87,131,181, 84,148, - 70,187,211,232, 45, 28,143,228,254,244,213,143,152,215,172,235, 2, 99, 12,254,254,195, 23, 24, 57, 10, 52,167,194,159, 19,173, - 63, 44, 26,144, 19,214,159,190, 87, 7,201,176,206,248,232,114,135,219,226,240,175,159,125,139,215, 63,222,225,197,115,131,119, - 71,131, 24, 58, 1,177, 85, 40, 39,162, 50, 24, 67, 1,152,146, 25,224, 26,219,140, 88,181, 94, 10,106, 43,252,110, 86, 29,107, -107,225,187, 17,205, 9,104,198,250, 17, 4, 4,176, 20,176,100, 29, 39, 48,242,255, 54, 6,182,113, 7,165, 73,101, 18, 94, 4, - 5,199,136,178, 89,172,130,116, 54, 20, 78,214,235,168,203,170,240, 14, 67, 98, 40,231,184, 75,183,128,161,137,209,202,159,149, -115, 94, 15,104, 85, 5,243,216, 59,231,130, 97, 24,122,113,185,172, 56, 89, 26,191,123,239,177, 46, 25,227,126,228, 48, 41, 67, -207,121,202,112,205, 97,220,121, 44, 75,214,176, 24,177,188, 73,132,243, 54,211, 92, 50, 25,104,245,213, 84, 51, 4, 52, 22,150, -210, 30,157, 10,220,140,172, 66, 96,171, 77, 6, 0,141, 27, 21,117,124, 90,147,186,105,248,199, 11, 99,154,250,231,173, 51,252, - 46, 53, 68,230, 77,108, 17,165, 66,128, 92,151, 68, 40, 94,142,135, 21,186,220,214,134,102,140,193, 48, 68,130,232,176,215, 94, - 2, 63,232,235, 43,155, 0, 18,202,188, 23, 93,212, 22,226, 66,170,247, 64, 26,150,232, 57, 32,203, 50,252,168, 50, 0,172,105, - 14,130,224,193,183, 19, 15,225, 16,212, 82, 0, 30, 23,115,120,184,166,107,182, 90,225, 5,158, 35, 77,135,116,230,206,111, 2, - 93, 54,197, 1,119,220,202, 9,128, 48, 73, 12,219,139,155,250,219,157,181, 40,141, 19,225, 84,131,210,243, 67,172,161,233,129, - 85,119, 17, 39,119,130,132,188,116,150, 75, 19,200, 77,155, 20,163,216, 40,227,249,239,118, 46,118, 94, 59,127,125,180,154,101, -253,136, 33, 55,135, 15,145, 73,112,129,197,227,145,147, 34,155,230, 56,200,100, 75, 10, 31, 73, 12, 5, 23,157,116, 23, 23,110, -136, 26, 5,186,148,146, 85,109, 72,213, 63,143,165, 88,165,220, 28,239,134, 69, 33, 56,120, 14, 53, 48, 88,151,202,246, 39,203, - 42,103,163, 21,154, 84,183,165, 84,142, 25,109, 79, 96,247, 80,209,138,127,114,128,213, 82,176,242, 8, 94, 18,194, 42, 67, 43, - 12,149,199,154,128,102,248, 50, 54,214,233, 15,193, 40,102,207,194, 7,171,202,206,156, 51,206, 14,123, 21, 59,136, 72,199,114, - 2, 27,189,176, 84, 1,199,129,166, 21,226,169, 20,241, 67,169, 13,196, 25,177, 24, 68, 25,206,187,105, 2,166, 4,254,126,189, -190, 64,191,254,199,127,131,139,231,175,240,197,231, 63,224,225,110, 34,111,168,171,104,137,130, 58, 68,100,147,249,176,241, 33, -240,222, 5, 10,234,111,205,110,236, 23,116,193,109,163, 93,121, 58, 10, 99,105, 28,107, 25,224, 33, 65, 19,134,149,183,214, 26, -204,211, 2,103, 41,117,204,123, 11,148,198,148,181,220, 21,210, 34,244, 97, 53,191,208,240,198, 93, 84,150,184, 80,246,172,149, -252, 95,163, 62,205,117, 93, 17, 7,254,181,214, 18,188,165,100, 44, 51,141,133,157, 53, 24,134, 1,113,136,228,113,103,168,209, -186,172,212, 53,149,140, 86, 10,230,135, 35,194,224, 96,141, 71, 13, 30, 67,244,136,193, 33, 39, 98,166,193, 91,245, 95,239, 15, -123, 92, 95,157,147,123,194, 24,148, 74,234,215, 15,222,127,133, 31,126,188, 5, 12, 9,134,190,248,226, 53,206,255,151, 3, 28, - 19,198,168, 35, 50,180,203, 46, 9, 37,122, 4, 83,241,248, 56,227,139,175,190,131, 76,179,168,107, 53,120,249,226, 74,109, 52, - 22, 84, 72, 24, 23,144,151, 5,246,238, 13, 60, 10,234, 90,200,174, 25, 60, 30,239, 19,154,205,136, 47,158,227, 87, 31,191,194, - 97,140,120,253,211, 3, 62,255,114,193, 7,239, 26,156,237, 91,135,100,176,231,220,112,208, 14, 52,250,147,220, 32,180,103, 93, -181,216,234,108,235,246, 36,190,147,198,131, 80,141, 3,159,148, 68,118,243, 3,156, 15, 12,128,225,170,223, 57,148,210, 51,155, - 75,133,146,235,176,205,119,222, 8,134,250, 69,214,189,215, 77, 25,238, 61,213, 77, 61,187,198,116, 42, 90,219,170,187,141,134, - 95,200, 89, 68, 34, 52,246, 72,171,194, 25,228, 90, 97,246,185, 15,145,167, 19, 5,243, 52, 35,196, 1,235,178,194, 24, 75,228, - 54, 99, 49,238,162,198,164, 26, 78, 25, 20,187,152,105,125,154, 40, 83,183,156, 10,133,149,160,171,155,173,170,214,161,147,192, -180, 22,181,142,201, 10, 65, 38,134,141,241,167, 33, 58,141,140, 53, 6, 88, 83,129,133,229,139,189,232, 57,228,189, 35, 26,156, - 53,132,186,229, 75,195,139,109,180, 54,181,220, 53,246,177,147,157,142,198,236,105,205, 42,220,243,236,204,145, 21, 67,136, 81, -191,102, 90,203, 84, 56, 71,147, 9,154, 40,244, 4, 54,243, 55, 17,164,149,133,112,181, 80, 46, 66,101,224, 12, 37,176,121,216, -218,161, 45,181, 62, 37,142,246,130,194,179, 32,143,158, 39,105,218, 40,161, 82, 66,160, 42, 50,175, 67, 28, 11,139, 41, 16,134, - 66,160,132,234,153,153,252, 73, 24, 98, 38,184,137, 86,137, 59,105,197,187, 90, 79, 19, 72,198,124,183,214,224, 77,251,159,162, -116,133,124,104,173, 3,228, 89,213,189,127,208,123, 76, 32, 56,134,173,139,242, 62,200, 59,106,173, 87,109,139, 15,129, 21,244, - 27, 40,145,177, 27,219,228, 8,235, 28,134,161, 91,212,188, 15,125,170,198,212,207, 24,153,131, 32,232, 39, 71, 56, 90, 69,161, -139,200,145, 87, 38, 50,138,247,243,188, 62, 21, 92,113, 85, 31, 66,208,223,108, 29,117,189,222,123,234,236,114,229,177,114, 67, -136, 30,235,146,180, 82,144, 31,170,116,214,104,128, 9,134, 3, 70,250, 56,183, 54,131,253, 46,176,186,207,243,104,138, 46, 3, -241, 92, 22, 30, 99, 89,103, 17,140,213, 8,121,194, 67, 22, 61,100, 41,238,177, 41,209,136,194, 68,162, 10,196, 68,248, 51,178, -160, 70,192, 14, 21, 44,174,226,234,186, 85, 22,138,240,131, 35, 2,158,224,141, 42, 48,189,167, 17,150,149, 8,213, 6,206, 64, -175, 26, 2,129, 70, 2,187,195,249, 1,191,249,221, 63, 97,158,129, 63,255,143,239,112, 58, 46,244,162, 96, 66, 41,119, 88,215, - 69,137,125,118,227, 6,144, 56, 90,218, 35, 49,117,139,163, 32,101,185, 35, 47,182, 32,114,101, 12, 90, 57, 2,113,149,200,199, -141, 37,145, 70,168,178,135,205, 42,134,179,155,206,144,246,136,149,139,140,204, 65, 21,108, 71,100,170,148,139, 65,173,106, 96, -136, 71,227,226,131,132,135,212, 9, 56,231,144,121,135,159, 88,141, 94, 75,198, 48,208, 65, 43, 54, 56, 57,144, 72, 79,208,176, - 46, 11, 12, 40,169,106, 58, 2, 67,141, 48, 94,248,217,145,166, 31,251,161, 83,189,156, 1,140,195, 60, 77, 28, 8, 67, 66,169, -196, 84,180, 97, 28,240,226,249, 37,126,248,241, 6,198, 90,220, 61, 28,241,167,207,191,198,167,159,126,196, 17,147, 52, 46,207, -137, 70,231,203, 90,176,162,225, 15,159,191,198,196,227, 81,207,157,195,232, 12,230,251,123,188,110,100,211, 26, 7, 15,148,134, -211,241,132,188, 44, 40, 55,143,112,140,197,141,214, 34,160, 98, 56,219,195, 94, 95, 97, 89, 19,206,246, 3, 62,254,240, 5,158, - 95,159,227,203,111,239,240,249,151,111,113,182,207,120,255, 29,139, 33, 54,205,147, 22,140,177,240,208,181,235,110, 77, 57, 7, -242, 51,104,173,118,235, 14,156,238, 21,141,221,112,177,121,223,106, 93,132,143, 35,125,150, 78,222,111,143,194,120, 78,195, 0, -158, 46,122,100, 78,127,109, 27, 65,155,172,120,122,241,188,245,185,131,119,234,194,164,246, 62, 48,126, 19, 61,225,175, 85,180, -156, 88,174, 74, 19,175,234,158,194, 70, 36, 92, 73,138, 93,114, 71,208,138,136,162,159,169, 91,111,205, 32,156, 7, 22, 4,210, -249,224, 60,137,235,140, 21,228,107, 96, 12,110,198,110, 79, 10,244, 16,157,194, 21, 8,114,227,245, 98,183,220,200,164,181,162, -114,190, 4, 26,241, 5,104,167, 95, 24, 34,197, 90,149,210, 54,201, 92, 22,205,242, 4,135,241,161, 50,221, 40, 28, 11, 13,181, -223, 66, 25,237,130,118, 37,173, 78,209, 46, 87, 58,230,146,139, 78, 48,107,173, 12,128,178,204,197,183, 8,134,154, 35, 87,248, -121,112,178, 91,166,213, 37,117,127,235,230,179,165,159, 79, 74,153, 18, 38, 53, 74,153,190,214,186,172,106,149, 34,220, 52, 20, - 6,180,166,194,147,197,170,197,142,184,102,172, 19, 62, 63,180,187,150,194,175,150,170,201,126, 49, 4, 22,151,102, 56, 7,213, - 50, 37,190, 43, 44,231, 87,196, 24,121,239,238,121,197,211, 21,234, 34,154,147, 92,121, 3, 11, 23,232,130,115, 62,114,230, 64, -161,213, 46,107,160,208,168,201,144, 28, 12,217,255,211, 25,151, 24,172, 22, 58, 45, 81,154, 62,190,168,173,115, 26,169, 43, 5, -148, 56, 11,196, 21, 37, 8, 89, 18, 24, 6,206, 66,176,164,247,112, 30,113,160,119,208,135,216,193, 76, 34,176,227,191,175, 54, -240,148, 69, 80,185,134,181, 17,153,255, 94,108,144,184, 77, 11, 51, 47,213,125,143,202, 4, 89, 54, 74,209,212, 49, 82,170,179, -138,177,213, 13, 70, 15, 79,136,115,138, 41,172, 93,214, 47, 47,127,223,173,178, 77,134, 63, 8,231,221,147,164, 27,231,136,115, -188,240, 40,201,109, 70, 66, 82, 41,202, 15,191, 53,249, 6,125,183,206,242,191,107,227,151, 7,134,241,175, 77, 3, 39, 28,239, -182,188, 35, 76,105,140,129,187,186,214,133, 33,172,252,165, 81,110,120, 98,107,144,245,132, 19,171,128,207, 0, 0, 32, 0, 73, - 68, 65, 84,140,172, 83,202, 12,218,112,140,234,115,248,229,111, 63,197,187,127,247, 51,188,254,203, 27,220,221, 30, 49, 77,116, - 97,181,245, 6, 41, 79,155,168, 82,170,196, 36, 84, 71,126, 68,194,109, 54,155, 84, 33, 23, 44, 11,217,232, 97,166,106,155, 48, -145,109, 3,233,177,198, 32,215,138,102, 28,251,234, 45, 31, 72,153, 39, 28,165,239,126,152,152, 37,196, 49, 81,180,147,150,194, - 41,111, 64,178,228,173,226, 60,153,190,197,149,172,136,102,228,231,106,157,195, 50, 51,109,176, 36,180, 86, 48, 12, 17,118, 8, -253, 66, 41,148, 49, 13, 80,188,169, 32, 37, 5, 56,100, 93,195,227,154, 17,134,136,161, 26, 28,108, 69, 43, 11,108, 24, 81, 29, -217,217,106, 93,145,171,135, 9,236, 93,118, 22,185,208, 88,106, 89, 18, 33, 94, 1,188,247,222, 11,188,189,121,160, 3, 3, 6, -175,191,249, 17, 47,174, 47,240,236,250, 18,165, 53,162, 72, 49,121,173,149,134,239,190,125,131,175, 95,255,168, 57, 8, 11, 43, -185,127,243,238, 51, 92,180, 5,109,126,192,177,156,227,254, 56,195,151,132, 56,142,132, 50,117, 30,199, 57, 99,201, 25,103,227, -128,203,203, 11,156, 95,157, 83,238,244, 58,227,244, 56, 51,224, 39,226,147,143, 94,225,213,203,103,248,235,235, 31,240, 95,255, -240, 19,222,121, 1,188,122, 81,213, 18, 73,133,178,221,140,208,229,249,112,202,161,110, 48,104,178,187,227,119, 82, 83,209,120, - 87,218, 4, 81,105, 28, 92, 28, 20,127, 76,187,245, 30,135,209, 32, 52,186, 46,114,149,113,167,236, 49, 53,195,186, 1,153,187, -113, 73,137,170,173,231, 99,135, 32,211,128,190,103,109,220,165, 89, 67,201,133, 82,252, 9,131,161,182,250,132, 10, 73,251,235, -117,163, 20,230, 24,225,156,116, 4, 95, 61,209,250,214, 53,209,222, 84,227,100, 9, 68, 51,157, 22,154, 46,193, 32,240,251,179, - 44, 89, 41,147,146, 76,233,125, 96,158, 61,233,106,150,185, 42,186, 86,186,195, 92,196,199, 79,207, 68, 8, 94, 67,174, 74,102, - 39,136, 88,175, 76, 67, 12, 35,101, 0,112,183, 22,130, 71,243,224, 9, 66,208,238,222,123,139,148,171,254,156, 41, 5,109,225, -213, 71,227,110, 60,169,246, 73,136,148,158,191,119,250,249, 64,155, 32,137,179,174, 27,228,174, 76, 53, 37,181, 78, 10, 18,199, -221,253, 60,175,220, 45,246,159, 47,237,119, 59,195, 63, 21,130,120,209,121,156,148,208,231,131,131, 85,189, 18, 52, 58,148,109, -216, 26,252, 67,187,109,249,253, 85, 21,247,158,115, 15,228,126,160,243,150,159, 41,113, 71,100,131,230,106,215,219,148,218,131, - 83,140,164, 20,118,107,181, 20,172,205, 84, 5,213,100, 46, 40,132, 94, 23,188, 85, 48,144,124,207, 62, 16, 68,205,122,211,105, -139, 16, 62, 73,212,149, 19, 77,137,200,169, 32, 58, 17,249,121,161, 85,130, 41,161, 11,247, 66,136,136, 60,102, 15,113, 96,253, - 26,219,247, 42, 97,202, 5, 1, 78,217, 11,133,158,103,141,219,237,182,115,157,120, 85,104, 17,190,181, 17,122,241, 47, 75, 55, -103,116, 71, 98, 17,120, 28, 42, 88, 84, 9, 61, 41,185,104, 62,120,101,143,113, 31,141,144, 20, 93,133, 12,214,168,224, 3,155, - 88, 68, 1,222,232, 62,149, 97, 15,101, 45,188,131, 19,186, 89,207, 25,119,156,182, 36, 24, 82, 31,130, 50,206,197,122, 34, 35, -114,201, 4,150,157, 28, 85,246,196, 70,151, 23,149, 66, 79, 24, 7,201,226, 48, 99,193,126,217,140,113, 63,108,148,231, 84, 20, -120, 79, 96, 5, 17,254,229,210,233, 73, 21, 13,207, 46, 47,240,143,255,235, 63, 35,103,143,207,255,248, 13,142, 15, 51,201,135, -234,130,117,122,131,156, 87,245, 24, 38,169,118,165,160,241, 14,105,233,190,211, 45, 30,209, 5,203,150, 19, 2,203,108, 69,108, - 66,175, 43,153,170,222, 34,185,109, 27, 59,139, 40, 82,201,158,102,224,157,168,119, 51,123,206, 13,182, 89,132,214, 89, 26, 79, - 6, 71, 99,192, 84,186,192,168,201,225,236,121,228, 5,190,132,157,166, 28,229,180, 18, 92,131,149,255,227,110,212,244, 54,131, -198,123, 63, 48, 27,158, 10,132,202,191,222, 90,131,102, 44,134,193, 2,222, 96,134,131, 3, 5,100,216, 24, 81, 42,129, 97,156, -247,104, 41,193,249,136, 52, 79,200,137,201,115, 67,196,154, 50, 30, 30, 79,184, 78,207,200, 18,231, 3, 66,160,221,109,229,206, -231,171,175,191,199,249,229, 57,127, 93, 70, 47,206,148, 18,254,244,197,107,204, 75,210,159, 77,173, 13, 67,244,184, 62,219,195, -186,128,118,241, 12, 23,129,132,138,211,100,241,230, 97,161, 3,106,124,134, 22, 43, 60, 26,166,218, 80,178,195,114,115,196,203, - 23,231, 24,118, 59,236,198, 1,203, 60,225, 44, 85,204, 75,193,213, 33,224,157,203, 15, 17,208,240,245,247, 95,226,234,210,115, - 71,203,187,100,238,152,173, 13,155, 3,138, 14,110,122,254, 10,123,138, 83,199, 86,162,241,126,144,195,116,156,131,113,145, 14, -207, 40,163, 62,166,204, 89,162, 68, 54, 88, 29, 51, 82,195,198, 42,222,214,199,250, 52,202,124,138,100,174,133,199,213,220,137, -196, 24, 81,107,210, 51,196,216, 30, 8, 83,121,180, 46,194,174,190, 95,183, 40,101, 85,210,100,183,167,241, 37,205, 28, 13, 89, - 37,209,197,150,250,122, 47, 23, 46, 14,192,233,130,188,119,102,231, 74, 98, 90, 96, 90, 57, 2,185, 26, 45,136,233, 32,183,172, - 20,175,154, 13, 64, 63,119, 78,105, 51,134,201,115, 12,249, 48, 36,140,148,115,108,183, 11, 0, 67,158, 4,141, 45,123, 49, 73, - 76, 35, 95,124,213,117,158,132,117,212, 90, 49,207, 25, 0, 21, 5, 6,204,168,135,193,124, 90,158, 40,252,201,206,216,244, 89, - 21, 8,215,186,100,205,210, 46, 60, 61, 20,189,143, 54, 40,156, 60, 86,152,113, 17,249, 28, 55,214,160, 26,138,168, 93,150,132, - 33,146, 63,157,114, 59,130, 66,181,106, 45,136,135,208,213,252,134, 47, 53, 67,207,153, 9, 78, 47, 98,209, 3, 73,156,173, 76, - 9, 37, 68, 73,248,248,222, 56,178,238, 90, 42, 60, 56,249, 9,168,194, 86, 55,122, 7,208,228,222,193,243,126,221,218,214,215, - 63,146, 96, 87, 55,204, 6, 88, 21, 99,155,237,196, 73, 86,195, 18,236,130,190, 27,239,112,157,210,249,249, 60, 45, 34,140,180, -121,178,138,245,124, 31,136, 75, 44,231,196, 5,179,164,178,113,250,164,115, 24,199,145,173,138, 94,223,225,221, 46,240,221,100, -212, 89, 35, 19,178, 32, 29,122, 41,186,166,174,149,252,202, 91,237,147, 52,218, 50,126,207, 57,195,253, 95,255,199,191,251,189, - 30,210, 60, 78, 13,161,219,218,196,107, 44, 22, 18,211,249,247,170,156,236,142,250,166,136, 60,233, 2, 5, 92, 34, 41, 55,149, -149,148,206,147, 63,253,236,252,128,221,217,158, 96, 29,173,162,150,132,227,195, 35, 78,199,147,118,137,173,161, 11, 85,244,165, -103, 47,168,181, 93,120,231,136,163, 44, 48, 11, 65,231,201,142, 78, 67, 35, 90,231, 42,123,183, 77,113,163,203, 93, 86,195,154, - 19,189, 17,104,144,104,167,104,104, 6,105, 13,200,195,249,233, 63,252, 10,191,252,237,111,241,230,199, 19,190,251,230, 45,166, -211,138,101, 73, 48,237, 17,121,190, 81, 18,147,248,218, 37,130, 84,160, 19, 0, 16,163,231,142,166,231, 70,147, 5, 4, 26,115, -168,180,170,156,137, 9, 93, 50,171,214, 51,167, 20, 22,245,144,182,218,119, 50,107, 42, 79,246,174,206, 25, 44, 75,162,145, 88, - 12,172,164,119, 90, 81,123,206,186, 87, 6,113,173, 28,144,195, 98, 68, 17,166,152,174, 81, 88,151, 5,133,237, 84,180, 91, 11, -136, 49,106, 58,147,112,229,193,130,185,198,158,209,154,187,112,199,216,158,204,117,115,211,168, 19,151, 10, 53, 14,176, 62,114, - 42, 88, 3,156,167, 32,147,105, 66, 78, 43,126,188, 57,234,133, 40,154, 2, 41,124, 74, 41,120,120,156, 52,192, 40,165,140,146, - 10,174,159, 95, 18, 1,174, 82,177,241,199,207,190,194, 15, 63,221,232,179,180,205,103,246,214,224,253, 95,126,132,243,235,103, - 36,172, 76,212,105,158,159, 69, 56,239,112, 60,173, 56, 46, 5,143,115,193,244,120,194,242,112,143, 99,106, 88, 50,253, 20,188, - 51,136, 40,216, 69,139,193,145,205,237,176,115,120,253,205, 13,236,112,143,221,222,179,173,203,195,249, 64,187, 65, 22,239,200, -136,174, 25,153,162,128, 51, 5, 68,177, 43, 29, 57, 77,126, 72, 80, 73,145,140,148,230,228,213,191,171,105,120, 13,156,249, 96, - 53, 58, 56, 51,171, 91, 67, 73,180,232,169, 10, 84,146,231,214, 7,175,144,170,200,161, 43,242,247,234, 59,226,236,147, 61,188, - 60, 43, 91,173, 0,133,155,172,202,159,151,216,222,109,222,181,176, 39, 0, 80, 94, 67, 8,188, 91, 37,165, 57,109, 15,123,178, -164,240,202,141,225, 28,113,208,186,144,240,176, 77, 5, 72,130,173,205,153,247,159,214,161, 39, 55, 27,190,144, 26,211,230, 40, - 51,220, 5,130,246,200,122,128,220, 23,252,217,112, 65,227, 3,141,247, 61,195,183,200, 82, 10,238, 20,171, 98,139,165,251,204, - 41,211, 72, 93, 68,101, 34,142,171,155, 11,172,245,190, 77,214, 97, 34, 68, 51,154, 43, 14, 29,225, 74,238,129,132,170,136, 35, - 98,139,136,150,239, 85,214,165,214,116,155,150, 60, 51,206,219,190,175, 54, 93,105,237,172,131, 15,158,139, 13, 14, 18,226,251, -196,104, 81, 97, 56, 69,206,233,186, 83,254, 44,105, 18,212,174,198,231,184, 8, 14, 27, 71, 89, 27, 22, 12,169, 94,137, 93, 0, -186,178,100,225,181,172, 63,132,102, 42,133,186, 8,228,250, 3,213,221, 21,248, 27,173,136,217,188, 35,134, 47,114,253,103,130, -228,118, 60, 37, 97, 13,151,128,213,140,104,195, 12, 16, 60, 57,122,198,113,143, 16, 40, 82,218, 49, 53, 53,196,200,246,210, 30, -129, 28, 56, 29,207,108,214,225, 58,218,175, 61, 94,188, 42,226,119,139, 28, 38,171,113, 78, 25,126, 27, 83,183, 77,224,161,221, -148,231, 31, 82, 85,192, 64, 45, 4,163,113,252,131, 41,188, 99, 65,166,109,135,247, 22,235,188, 62,169,184, 21, 95, 89,133, 66, - 71, 86, 9,121, 32,232, 67,239, 73, 88,180,175,234, 88, 65,218, 47, 52, 29,197,203, 15, 86, 30,116, 10, 41,160,174, 89,132, 39, -178,119, 33, 33, 68,101,129, 66,120, 50,145,144, 48, 2,233, 58, 82,206,138,187, 44, 60, 46,164, 2,132, 70,116, 82, 33, 5, 86, -129,138,178,125,183,223,227,183,191,251, 71, 24, 59,224,203,207,191,199,178,144, 45,204,154,140,150,126, 68,181, 96, 69,101,211, - 61, 76, 41, 25,222,137,130,145, 4, 27,198,178,146,181, 54,192, 83,156, 98, 78,130,236,132,138, 91, 84,169,107, 45,150,105, 70, - 67,223,187, 74, 5,175,145,179, 27,214,176, 76, 82,132,142,183,174, 61,186,209,160, 33, 12,129,253,251,172, 66, 70, 3,204,198, - 71, 44,160,157,210, 89,231,212, 53, 17,137,110, 93, 87,180, 74, 99, 45, 31,168, 51,118,210, 85, 88,192, 26,222, 89,169, 61,140, - 38, 28,121, 93,225,120,151, 28,152,143, 15,182, 0, 93, 28, 86,148,182,224,108,231,144,203,136,106, 61, 76,107, 72, 28,164, 97, - 26,193,105,170, 37,188,171, 42,122,185,128,250,230,187,159,250,174, 23, 6,145, 15, 21,114, 19, 84,124,253,205,143, 24,199,136, -151, 47,175, 0, 0, 15, 15, 71,124,245,151,239,117,228,213,197, 69, 6, 25,192,127,251,235, 91,220,150,207,240,191,253,203,175, -112,113, 24,176, 27, 3,188, 51,120,124,152, 97,106,193, 59,215, 59,164, 84,112,255,184,224,135,219, 19,150,227, 17,102, 74,184, -185, 95,240,221, 16,112,125,112,120,177, 51,120,113,189,199,225, 44,226,124, 28,113, 92, 43,126,184,191,193,123,127,119, 64, 5, -117, 90,198,145, 11, 66,102,156,181, 54, 24,231, 53,226, 81, 52, 16,114,224, 72,247,208,227, 28, 29, 83,203,118, 90,212,218, 13, - 35, 66,214, 77,141,199,150, 41, 17, 20, 39,103,194,111, 10,153, 16,108, 91,106,252, 12, 57,239,217,202,100,117,151, 71,103,101, -225,115, 66,118,200, 77,197,176,138, 60,101,104,134, 90,235,248, 10,202, 57, 81, 3, 80, 73,125, 92, 75,226,253,105, 87,165,139, -117,135, 44, 77,129,243,191, 51, 92, 33,123,172, 49,132,230,117,142,158,217, 24, 27,154, 1,188, 37, 26,219,184,139,152, 25,245, -234,156, 67,110,188, 58,224,238,213, 7,186, 60, 99,244, 61, 64,195, 18,101,172, 22,106, 0, 4,134, 99,189,133,105,244, 94, 73, -209, 83,114,213,189,174,117, 30, 48,155,108, 6,235, 0,111, 54,208, 20,106, 48,116, 44,110,128,233,180,112,163, 98, 52,133, 79, - 58, 92,177, 50,146, 53,205,195,114,209, 51, 24, 78, 19, 84,188, 43, 96,188, 67,128, 81,142,132,115, 3, 82, 42, 24,134,192,223, - 63, 84,244, 41, 13,131,172,251,228, 44,165, 71,169,146, 66,154,159, 53, 29,237, 6,175, 14, 24,209,253,208, 56,154, 47, 80,112, - 18, 93, 41, 92,204, 73, 74, 95,247,250,211, 52,167,106,186,166, 76,135,115,202,202,228,247,188,250,163, 64, 30, 18,165,134, 96, -250,250, 38,103,250,179,109,239,197,107,165,159, 35,229,188,131, 73,155,109,243,188, 1,141,139,107, 89,105,202, 69, 45,217,240, -164, 92, 39,254, 63, 24,137, 46,147, 49,203,130,108, 33, 46, 26, 67,120,115, 34, 14, 70, 20, 91, 52,197, 45,176, 85, 59, 14, 3, - 35,108,173,166,123, 90,102,190, 8,140,169, 55,155, 29, 30,230,189, 81, 69,124,229,208, 29,231,232,231,186,213,218, 72, 12,118, - 46, 52, 61,159,167, 19,220,127,252,223,127,247,251, 14, 14, 49,204, 78,182,221, 38,192,212,167,200,241,152, 61,126,145,252,221, -216,196,233, 9, 59, 93,211,148,248,226, 33,204,169,211,133,183, 84, 96,135,243, 3,226,184,195,176, 27, 57, 68,100, 37,213,123, - 73,152, 78,179,142,115, 4,136, 32,151,186,247, 94, 11, 2, 57,172, 74,105,154,241, 43, 30, 76, 57,204, 40,248,161, 83,160,228, - 5, 21,207, 55, 9,173,192, 17,163,150,187, 85,203,127,167, 60,232,252, 33, 87,217, 27, 83, 69,245,209, 39, 31,227,211,127,250, - 7,188,125,115,194,235,191,252,132,121, 78, 52,242, 94,110, 81,214,187,205,174,198,179, 0,199,178, 13,164,103,175, 91,103,144, -214, 2, 52,178,238,104,130, 25, 92, 79,168,226,149, 3,219, 62,159,194, 41, 10,129, 84,200, 19,219, 39, 19,226,189,239,163, 29, -232, 5, 45, 15,130, 88, 18,229,192,183,108, 85,244,161,143,214,219, 38, 42,178,199,201, 26,166, 84, 37,130, 93,228,164,145,170, -148,201, 76,249,206,194,225, 22, 47,171, 40, 81, 11, 17,129,128, 86,116,180,234, 57,181,201,113,119,128, 86,241,236,210,225,217, -101,197,217, 89,197,215, 95, 79,128,137,216,159,237, 54,250, 6, 32, 45, 43,144, 19,210,154,112,243,184,244,244,176,141,103,184, - 20, 2, 29, 45,108,211, 91, 57, 78,182,148,130,239,127,184,193, 24, 60, 46, 47, 15,240,222, 97,136, 30,111,111, 30,116,229, 51, - 50, 49,174,176,246,228, 52,205,248,252, 79,223,160,228,138,139,203,115, 88, 31,129, 86,176,174, 5,165, 1,231,187,128, 23,229, - 30, 87, 54,195, 22,201,125,247,152, 83,198,237,195,132,219, 83,198, 52,103,196,224, 48,236, 6,252,225,243,239,240,246,244, 35, -118,103,148,133, 64, 10,109,199, 99,112,240,104,188,109, 0, 80, 77,149,196, 26,155,204, 87,172, 15, 17,206, 71,132, 97, 71, 7, - 10,143, 67,229,215,168,106, 23,146, 71, 13, 21,174,233,248,120, 3, 19, 81,157, 72, 12,186,235,220,170,230,181,123,100,152,143, -236,100,233,107,241, 79,186, 32,235, 68,171,147,153, 93,145, 84,205, 46, 66,187, 90,178, 22,169,212,209,231, 77,172, 39,141, 57, -233, 48, 29, 24,112,228,144, 75,227,184, 92,195, 42,126, 25, 75, 23, 45, 12, 74,237,234,111, 65, 46,131, 27, 6,114,216,108, 11, - 21,251, 4,241,188,172,148, 99,208, 41, 34, 70, 39,143,146, 4, 41, 96, 17,107, 45,196, 38, 44, 99, 86,180,166, 29,186,100,199, -151, 34, 40,217,242,100, 26, 34,251, 95,233,134,229,130, 18, 2,167, 48, 10,228,103, 42, 29,170,236,147, 5,207, 45,194, 94,122, -110,168,179, 29,134,160,231,181, 20, 13,162, 23,210,125, 56,255,255,137,181, 57, 78, 66,189,148,133, 15,237,162,221, 70,103, 33, - 92, 12,233, 50,131,239, 63,123,185,248, 37, 29, 78, 57,246,102,251,247,218, 77,131,230, 53,146,187, 71,131, 91, 93, 47, 25,118, -182,200,231,133, 77,154,166,174, 44,237, 86,196,217,116,109, 98, 45, 51, 73,140,237,150,203,210, 87, 26, 98,239,243,142, 86,149, -244, 14, 89,165,232, 25, 93,169,112, 54, 61, 79,161, 75,233, 88,106,239, 29,134,145,222, 63,185, 11,133,197, 2,112,145, 39, 4, - 67,207, 19, 55,177, 21,110, 66,212, 4,136,195, 92, 60,205, 14,161,149,234,170, 54,207,101, 89,144,214, 21,243, 52,209, 10,224, - 63,253,135,127,249,125,230,209, 17, 12,158, 84,242, 20,147, 71,221,155,136, 68,104,148, 84,186, 39,220,117,145,142,124, 33,234, -101, 55,125,252, 34, 76,100, 45, 30,124,192,254,112,134,253,225, 12,214, 5,238, 0, 19,230,105,194,116, 60,177, 32,175, 63,236, - 82,181, 8,208,222,108,144,129,134, 21,160,149,121,188,148, 33,110, 53, 87, 92,138, 10,185,224, 12,191,120, 29,221,138,190,106, -240, 76, 54,242, 86, 31,200, 56, 4,142, 56,108,234,113,191,184,188,196, 63,255,187,127,139, 56,158,227,155,191,190,193,221,205, - 17,185, 52, 88,155, 81,211, 45, 90, 89, 20,123,219,179,132,155,194,105,232, 0,171, 61,229,138, 53, 1,195, 16,153,131,205, 34, - 35,142,132,149,145,170, 40, 84,193, 65, 30, 10, 2,105, 82, 60, 56, 70,244,114, 5,206,214,152,218,216,211, 92, 68,213, 78,127, - 23,172, 97, 68,175, 35,244,230,102, 95,215,106,101,181,104, 83, 90,145,198, 76,182, 70,225, 45,188,138, 31, 98, 64,140, 68, 7, -180, 28,229,216,116,125, 66,137, 91, 84,145, 74, 84,104, 34,229, 44, 23, 36,157, 94, 37,138, 90,225, 56,211,248,118, 93, 13, 94, -127,103,113,125,125,213,167, 16,155, 41, 83,157,103, 56,103,113,127, 90,186, 21,167,246,181, 82,173,141,152,215,236, 41,110,181, -113,167, 68,118, 29, 3,224,157, 87,207,225,172,197,179,171, 3,110,111, 30,144, 75,213, 68,169, 79,222, 37, 27,219,227,156,176, -172,212,213,126,251,253, 13,190,250,234, 7, 60,187, 60,199,225,226, 28,185, 20, 76,247, 15,184,249,254, 45,230,187, 7, 92, 12, - 1,239, 62,219,225,114,116, 48,243,132, 22, 3,224, 60,110,239, 38,124,253,221, 91,252,229,219,183,120,253,221, 91,124,246,245, - 55,184,122,110,117,204,172, 11, 82, 81, 82,111, 32, 62,219,142,187,178,101,137,132,167, 14,158,197,105, 46, 4,114, 69,240, 37, -228,172,211, 14, 67, 15, 63, 64, 39,114,244,156, 84, 26,187,243,216,145,242,218,253,166,147,226,231,139, 11, 64, 17,214,138, 8, -140,214, 69,229, 9, 91,189,255,190,250, 36,230,178, 54, 10,254,145,112,139,158, 94,198,228, 52,201,125,231, 49,182,236, 40,131, - 31,200,199,107,105, 45,225,125,164,174,152, 51,226, 27,140,158, 25, 50,146, 20,200, 82, 45,141,139,118,163, 19, 68,233,216, 10, -211,211, 66,244,228, 11,230,230, 68, 50, 22, 42,107, 87,164,155,173,165, 7,167, 72,177, 34,135,183,211, 29,107,223,157,211,106, -173,105, 16, 18,208,176, 44,153,166, 87,182, 7,128, 56, 71,123,231, 90,170,198, 87, 91, 99, 85,252, 85, 10,137,163, 66,240,218, -245, 9, 40, 71, 46, 26,203, 52, 77,203,150,216, 97,140,155, 36, 74,240,153,226, 85,160,214, 54, 41,151,146,166, 39, 13, 77,201, -133,206, 52,137,222,102, 27,165,116,220, 93, 96,109, 85,184,187, 45, 16, 84,244,182,129,192,168,231,158,115, 43, 10,171,219,155, - 98,101,187,240,204, 74,225, 34,251,117,254, 26,122,195,229, 54,147, 15,167,127,175,147,180,182, 77,236,175,172, 5,104, 39, 15, -157, 58, 90,231,217, 18,109,251,215,197,191,111, 24, 7, 22,179, 25,109, 40,123, 40, 77, 7, 36,201,185,238, 57, 53,141,226, 81, -131,134,150,201, 89,188,253, 51, 36,111, 94,255, 44,211,109,159,194, 70, 16,171,110, 90,201,241, 64, 5, 36, 21,188,203,178, 32, -151,140,121,158, 48,207,243,230,125, 50,112,255,241,223,255,238,247, 82, 5,201,142, 71,108, 9,210,197,210,195,212,244,131, 16, - 27,141, 36, 8,201, 15, 76, 30, 28,129,129,200,126,161,109,190,113, 17, 2,140,187, 29,118,103,103, 8,113, 32,155, 82,109, 72, -235,130,180, 44, 88,230,153, 83,126, 8, 29, 43,222,113,101,230,242, 72, 75, 58, 75,113,184, 71, 70,184,170, 77,137, 3, 14,228, - 96,146, 23, 79,126, 28,242, 80,232,195,238,122,119, 46, 31, 62,117, 27, 70,171,167, 16, 3, 62,253,135, 95,225,103,191,248,132, - 64, 50,127,249, 9,243,180,162,212, 2, 83, 31,145,151, 59, 46,114,232,207, 24, 71, 26,127,201,138, 64, 14, 81, 65,200, 86, 14, -224, 16, 75,155,227, 23, 86, 94, 98,241,207, 55,209, 52, 24, 9,231, 40,170,248, 23,181, 43,209,170, 82, 71, 8,242, 97,187, 44, - 9,105, 93,121, 36,214,167, 49, 77,117, 3, 68,139,147,221,166,225,164, 58, 65,119,138,149, 74, 8, 78, 57, 37,212, 74, 9,109, -222, 89,236,198,129,196, 64,178,251,130, 81, 75,160, 0,137,104,247,152,144, 87, 18,208, 53,238,218,173,231, 17, 61,103,162,123, - 79,209,162, 82, 81,139,130,247,135, 31, 42,230, 57,226,226,226,160, 89,222, 82,112,120,111,225, 76, 65, 53, 22, 63,188,121,160, -206, 77, 81,138,192, 3, 43,206, 73, 36, 67,190,242,221,224,241,226,234,128,143,127,246, 46,126,241,201, 7,120,255,253,151,156, -126, 68, 83,131,253,110,192,235,111,223,208, 36, 32, 87, 92,158, 69,252,226,253,231, 24, 7,143,183, 15, 19, 61,175,185,224, 56, - 45,248,252,139,191,226,244, 56,225,252,108,192, 89, 58,193,181,130, 92, 43,222, 78, 25,183,143, 9,209, 2,239,156, 7,188,250, -224, 26,247,199, 21,127,252,242, 43,188,243,110,198,225,178,160,186, 9,135, 11, 3,235,249, 93,105, 61, 37, 75, 14, 36,162,193, -113,127,205,187, 78,218,205,141,244,249,249,168,104, 73,121,214, 73,212,233,187,208,175,209, 8, 47,179,214, 1, 74,173, 99, 36, -105,237,132, 71, 93,213,216,254,115,160,206,155, 49,155,214,104,142,122, 46,153, 11, 14,209,206,180,158, 11,109,122, 7, 34, 99, -208,148,215, 13,216, 3,170,120,151,213, 28,121,211,139,162,102,213,194,233, 7, 24,227, 97, 93, 64,173, 22, 67, 28, 73,176,216, - 28, 39, 17, 54, 38,223,245, 85,162, 60,183,141,109,106,162, 29, 50, 12,212, 34, 34, 34,169,207, 67,244, 26, 70,211,152, 0, 41, -211, 60,161,117,213, 90, 56, 74,117, 75,158,131,226,170, 59,135, 99,115, 40,163,103, 68, 57, 47, 86,175,166, 74,117,225,165, 59, -239, 48,157, 40,180,200, 88, 65,110, 55, 12, 99,196,202,226,217, 30,250, 34, 97, 61,208,194, 74, 10, 87, 13,113, 98,207,127,103, -133, 27,221,123,247,240, 21,241,211,123, 94, 31,152, 39, 34,172, 97, 8, 12,197,177, 12,190,162, 66,200,234, 69,212, 5, 92, 50, - 17,139, 49, 32,165, 14,168,162,241, 53, 52, 50, 87,139, 31,231, 84, 0, 40,121, 20, 98, 95,150,247,159,108,213, 86, 57, 10, 82, -108, 58,134,114,216, 77,194,167, 32,104, 45, 95,238,181, 54,189,220, 69,215,161,133,190,216,207, 76, 47, 98,244,207,116,142,243, -202, 61, 79, 56, 28,130, 15,122, 95,200,121,180,253, 87, 23,112, 27,156,157,157,241,154,151, 26, 96,103,123,216,150,232, 59, 26, -136,139, 96, 88,148,217,116,218,252, 84, 20,151,185,233, 16,103,146,208, 35,167,105, 66, 90, 23,172,203,204,241,228, 80,174, 9, - 26,224,254,211,127,248,183,191, 23,208, 76, 46, 89,171, 48, 33,104, 9, 56,166, 87, 21,237,137,197, 77,118,102,242,205,118, 33, -196,255,236,185,150,241, 13,117, 1, 84,209,236, 15,103,186, 31,111, 53, 99, 58, 30,241,248,112,212, 42,197, 40, 51,215, 62,169, -240,104, 28, 38,170, 70, 9,101,233,187,211, 97,140,106, 47, 35, 53,123,211,162,131,252,234,246, 73, 58,209, 54, 43,119,251, 32, -201,238, 3, 13,120,249,222, 43,252,246,119,255,132, 82, 60,254,242,231, 31,112,123,115,228,241,208,130,154,110, 80,107,194, 56, - 70, 86,181, 59,245,111, 58, 70,253,129, 31,166,156, 50,219, 98,170, 90, 57,156, 51,172,196,183,156,107,110,181,203, 17,114, 31, -133, 66,100, 85, 59,110,139,149,204,163,248, 45, 12,164, 53,250,245, 96, 49,154,247,114, 33,208,180,195, 57,171, 35, 83,199,226, - 39,217,129, 75, 68,103,211, 52,173,218, 73, 78,150,104,124,250,159, 82,129, 42,136,162,168,181,133,132,146,252, 61,151,204,204, -121,171,187, 44, 31,156,242,161,251,171, 34,113,183,141, 47, 99,224,179,207, 23,188,124,241, 2,135,243, 51, 30,215, 27, 45,222, -104,166,100,177,100,131, 31,223,220,177,170,185,242,104, 42,243,190,141,118,239,251,232,241,235,143, 95,226,215, 31, 94,225,131, - 15, 94,225,250,229,115,242, 53,243, 75, 15,134, 48, 13, 67,192,244,120,194,227, 68,214,202,183,247, 19,222,127,113,192,123, 47, - 46, 48, 88,224,187,183,199,141,128, 12,184,185,123,196,215,175,127,196,224, 44,222,121,126,142, 64, 17,136,168, 48,248,233, 97, -198,237,113, 69,116,192,213,203, 75,220,221, 46,184,159, 86, 92, 92, 26,182, 45, 26,189,224,200, 82,211, 87, 60,149,241,152,206, - 7,132, 48,162,193, 96, 24,247, 76, 26, 36, 75, 85, 96, 21,174, 28,116, 98,103,234, 93, 61,141,250,200,161,226, 84, 15, 34,138, - 80, 17,161,201,223,169,147, 35, 24,189, 88, 5, 91,172,177,189,174, 91, 80, 9,164, 82, 40,116,168,148, 62,202,228,200,217,198, -255,217,195, 57,122, 6,132,168,180,104, 37,148,181,232,104,155,232, 99,239, 71,120, 63,192,135, 1,150,187,244, 90, 41,252,130, - 44,171,161, 39,193,192,108, 28, 11,149,175,161,206,224,176,174, 23, 25, 60,209,124, 18,157, 76, 93, 58,237,209,141, 53,148, 12, - 23,189,138,246,100, 66, 68, 66,190,162, 74,106,193,255, 72, 48, 11, 1,114,114,247, 81,243, 51, 77, 40,105, 97, 2, 8,162, 20, -236,163,166,134,105, 97,171,108, 8, 30,243,180,106,247,223, 42, 77,221, 74, 45,108,129, 53,106,205,203,185,168,190,197,110, 98, -103,229,178, 69,235, 63, 59, 69,155,154,190,175, 23,140,182,216,120,123, 30,186, 81,132,248,182, 83,173, 27, 11,155,196,216, 74, - 76,234,211, 4, 65,163, 23,174,144,212,107, 41,155,102,138, 46, 51,207,159,187, 76,161,100,106, 44,207,176,168,211, 61,175, 88, -201, 9, 36, 20, 60, 46, 4,248, 94,161, 20,185,176, 65, 22,247,175, 83, 62, 3, 65,160,123,207,163,120,142, 30, 23,145, 53, 53, - 38,142,131,206,172,122,192, 45,175,163,100, 85, 35, 20, 61,107, 40,117,207,178,200, 50, 14, 65,139, 68,209, 72, 84, 45,110, 91, - 31,179,111, 2,140, 68, 72,158,115,209,169,215,186,172, 72, 44,128,155,231, 25,235,186, 48,219,131,206, 70,249,254,229,190,240, - 62,192,203, 23, 70, 34, 5,167, 49,159, 62,122, 86,101,154, 30,220,194, 35,144,154, 73,109, 77, 21, 30,225, 90,211,146,224,188, -237, 57,196, 70,112,129, 69,171, 19,189,208, 45,129, 94,100, 68, 33, 69, 4,117, 94,149, 15,126,122,249, 58,162, 17, 58,106,210, -157,222, 70, 40,164,222,243, 40, 33, 37, 12, 66, 81,104, 0, 61,212, 99, 28,180,210,213, 63, 11, 13,158,233, 65,173, 86,237, 56, - 37,140,102,183,223,225,151,191,253, 20,113, 56,224,251,111,222,226,225,254,132,105,162, 93, 96,203, 15, 0,164,146,166,253,200, -110, 63, 34,231, 6,235,218, 38,120,194,176,165,167, 99, 3,125,240, 27,191, 58,143,111, 44, 7, 9, 40,103,185,233,238, 92,196, - 28, 70, 15, 15,177,181, 85,205, 22, 46, 76,180, 82,112,143, 53, 48,150, 43,113,231, 17, 44, 29,160,173,242,126,223,110,220, 10, - 27,136,140, 28, 14,181, 2, 37,175, 58, 93,216, 78, 60, 36,250,207, 90,203, 62, 90,143,204,221,189,145,168, 75, 86,233, 74,114, -154,132, 87, 72,197, 93, 75,161, 32,138,218,152,207,204,221, 16,175, 25, 72, 89,155, 17, 60,133,186, 12,193,161, 41,105,139,159, - 25,146,129, 35,151,132,148, 72,168, 7,102, 39, 95,156, 57, 12, 49,224, 48, 90, 92, 95, 95, 98, 55,120,196,154,224,163, 67, 25, - 56, 73,142,139, 45,209, 78,231,101,134,113, 30, 31,189,251, 12,127,253,246, 45, 86, 38, 99,125,241,205, 13,126,119, 62,226,131, - 87,151,248,236,245, 13,214,218,158,100,152,151,218,240, 95,190,250, 9, 0,240,219,143, 95, 32,175, 22,193,103,152, 66, 81,177, -223,252,120,194,222,237,241,171, 95,190,135,255,231,255, 61,226,238,174,224,250,121, 84,141, 4, 9,172, 44,226,110,208,174, 47, - 48,159,219,178, 31,215,113, 49, 45, 5,154, 84,233,173,118, 49,164, 6,118, 52,194, 0, 91,239,224,130,129,173, 36, 6,165, 72, -210,166,129, 61,127,171, 62,150,131,176,139, 93,123,192,147, 76, 84, 90, 37, 33, 90, 77, 5,214,210,159,227, 56,208, 35,241,243, -106,116,175,222,250,239, 3,169,144, 11, 79,112, 42, 79,128,182,123,111,169,238,172,139, 8,126, 68,140, 59, 52, 56,138,201, 52, - 14,214, 6, 0,142, 89, 14,228,108,160,179, 73,196,155,116, 9, 36,225, 45,136,246,162,138,195,132, 50, 29,204, 0,172, 68,104, -165, 73, 82, 42,216,237,119,170,100,159,166, 76,197,221,105, 81,229,113, 73,116,177, 52, 78,195,155,213, 6, 5,214, 19, 25,141, -122,150,162, 86,248,244,142,167, 89, 48, 68,165, 20,132,172,243,244, 14,146, 6,150,115,222, 13,217, 87,165,161,218, 66,174, 12, - 7,238,100,161,224,113,132,108,206, 77,227, 96,165,169,170, 53,233,100, 75, 81,208, 76, 82,171,133, 68,184,105, 35,132, 3,175, - 90,229,107,151,198, 65, 38, 41,242,141,138,178,222, 50, 76,131,104,112, 78,133,110,206,202,180, 3, 61,143,130,255,187, 97, 58, - 41,229, 59,208,196,111, 93,147, 6, 60, 41,153,206, 25, 21, 70, 91, 91, 57, 59,128,104,116,214, 89, 12, 46,114, 71,155,122, 12, -169, 33, 26, 93, 45, 77,223,167,214, 26,220,166, 84, 52, 32, 78,130,172, 29,122,134,124,111,144,130,247, 28, 94,100, 52, 95,157, - 10,134, 30, 63, 44, 58, 10, 90, 93,134, 13, 77,111,208,207, 48,179,109, 16, 5, 58,161,208,179,198, 24, 22,119,246,179,215, 56, -163, 83,160,196,193, 60, 98,225, 44, 57,179,200, 55,179,227,196,235,244,150,238, 65,114,100,248, 82, 11, 80,193,120, 83, 30, 81, -177,165,194, 72,213,210, 26,198,195, 5,210,244,168, 99,117,225, 50, 27, 99,145,150,196, 72,195,172,202,243,198, 23, 38,141,150, -232,146, 17,191, 99, 3,176,219,141, 79, 72, 60,222, 91, 36, 3,172, 41,179, 34, 86,226, 68,237, 38,159,182,234, 78, 10,141, 30, - 62,167,227,150,170,187, 48, 18,247, 80, 49, 32,151, 14, 77, 21,217,103, 42,170, 95,206,246,173, 76,200, 51,108, 23,210,135,195, - 7,252,236,231, 63,195,171,247,223,199,155,159, 30,241,229, 23,127,165,124,229, 82,225,221,138,117,126, 96, 43,137,131,245,148, -168, 70, 25,198,156,202,198,113,141,141,149,138, 37,247,125,110,227,140,227, 24,189,142,158,182, 99, 44, 9,169,208, 68, 50,166, -121, 89, 43,130, 62, 86,108,242,131, 67,223, 9,177, 47, 43,199, 57,146,128,197,170,104,201,123,250,121,192,121, 10, 88,217, 88, - 92,104,180, 10,218,213,164,140, 86,203,147, 64,134, 16,156,238,120,133,150,100, 56,130,147, 40, 81, 93, 56,162,158,201,180, 42, -161, 43, 4,171, 68,164, 16,157,174, 19,104,231, 86, 97, 36,111,153,187, 54, 73,152,155,167, 9,222, 59,188,251,170,225,171,191, -222,227,253,247,159, 19, 43,193,177, 54,195, 89, 52, 22, 8,238,207,118,248,244,211,143,176, 27,130, 86,210, 49,122, 68,100,152, -180, 32,231, 6,199,212,177,234, 71, 77, 4,171, 37,163,112, 38,182, 1, 16,199, 1,165, 0,151,175, 94,226,147, 15,239,240,217, -215,111,224,172,193, 15, 15, 51,254,242,253, 45,206, 71,178,163,196,224,177,166,140, 33,122,181,114, 14,193,225,234,114,143,221, - 97,135,214,118,188, 54,114,152,167,149, 21,183, 21,213, 69,252,230,211,159,225,203,215,223,225,250, 69,160, 3,203,243, 33,193, -222,112,239, 69,123,129,190,215,230,169, 10,137,186,156, 10,147,156,181,104,210, 93, 85,102,114, 51,118,116, 27,143, 41, 66, 40, -209,114,148,210,105,126,253, 93,204, 60,101,170, 58, 6,166, 51,160,207, 81,196, 94, 67,233,126,149, 29, 13, 77,197, 85,165,210, - 72, 94, 56,234, 98,205, 50,204,215, 46,124,137,111, 59,216, 82, 41,235, 93, 14, 93,231, 6,248, 64,153,210,214, 70,138, 29, 54, - 30,242, 91,189,167,239, 53,231, 74,159, 21, 7,195,136, 16,210, 57, 10,254, 88,150,166,254,227, 56, 4,204,211,130,156, 37,147, - 26, 42, 14, 36,175,181,193,233, 56,211,164, 3, 84, 24,136,160, 50,115,128, 78,107,141, 82,207,184, 11, 51,173, 17,118,217, 73, - 65, 68, 19,207,202, 23,114,228, 88, 99,239, 29,141,209, 29, 37,147, 97, 35, 68,150, 46, 95, 66,166,228,231,174, 86,210,214,116, -135, 79, 77,142,209,172,115, 98,179, 71,164,148,116, 47, 77,158,106,171,227,109, 99,229,140,102,107, 95,107,200,173, 95,204, 50, -162, 46,165,219,203, 10,239,210,115,110, 60,161,168,112,250, 28, 53,157,210, 72,227,161, 52,207, 53,171, 87,188, 85,122,175,187, - 0, 17, 48,168, 90,252, 56,239, 80, 0,157, 88, 2,228, 62, 16, 23, 4, 21, 54,133, 61,254, 69, 97, 93,130, 92,149,105, 68,136, -145,238, 43,103,116, 45, 49,140,156, 7,129,142, 83, 21,140,171, 49, 64,116, 94,181, 98,222,246, 52, 75,178,104,146,171,128,224, - 46, 44,242, 45, 69,191,151,148, 50,156,181, 8, 49,146, 91, 71,214, 9, 82,244,110, 50,224,157,111,218,136,137,128, 87,206,218, -202, 46, 46,137, 60,150,105,232,178,172,112,206, 98, 89, 22,172,235,202,196, 61,167,197, 85, 8,145,133,169, 61,119,222,123,163, -239,180, 90,218,186,197,192,118, 1,151,179,168, 9,170, 6,223,254, 75, 34, 90,115,162,145,115, 22,209,150,193, 38,183, 25, 42, -226, 32,193, 73, 81, 11,141, 11,164,200,132,122,242, 88, 8,192, 23, 30,173, 1,172,126, 93, 42,226,227, 10, 18,166,239, 30,213, -226,166, 73,115, 85, 85,227,198,138,111,208, 40, 88, 66,246, 54,153, 71,132, 54, 90,254,128, 29, 28,168, 26, 60, 59, 28,240,171, -127,252, 53,230,169,226,203, 63,125,143,187,219, 35,143, 14, 19,202,250, 0,184,174,124, 20,213,166,100,147,123, 99, 49, 79, 43, - 29,170,137, 81,150,220,149, 96, 19,227, 40,130,154,190, 95, 19, 6, 56, 99, 41, 55, 35,170, 42,157,120,235, 42, 98, 73,112, 74, - 41, 83, 81,196, 69,206,150,228, 68,113,178, 94, 21,244,231,215,207,113,186,191,133,129,231,208, 26, 18, 17,166, 68, 92,113, 26, -175,211, 30, 57, 48,228,198,218,200,145,149,142, 47, 21,250,204,196, 94,167, 34,196, 68,211,154,180,174, 72,235,202,221,155,229, -135,184, 51,224,189,179,104, 70,124,207,116,136,215, 82,129, 77, 40,143, 8,255, 36,140,226,229,203,128,215,223,174,152,231, 85, - 69,125,181, 80,122, 94, 74, 69,159,139,171,171,115,157,252, 8,221,108,153, 19,253, 57,235,132,106, 44, 76,116,168, 54,168,215, -222,123,162,209,229, 84, 17,247, 35, 85,235,107, 66,131,193,175,127,245, 33,238,231,132,105,165, 23,249,245,237,140,221,144,113, -184, 56, 67,109, 21,231,231,123,172, 92,120, 57,107,240,207,159,188,194,223,191,123, 5, 31, 40,173,238,241,113,134, 29, 6,152, - 66, 80,145,129, 15,129,171,103,103,248,254,205,136,146, 11,198, 61,139,119,188,225,145,105,230, 41, 87,235,162,202, 74, 59, 99, -201, 82,111,155,124,242,218,160, 94, 89,171,232,222,166, 59, 84,205,149,150, 78, 76,121,254,125, 20,104,120, 66,100, 56,184,194, -128, 46,237,210, 26,108,115,172, 1, 1,235, 57, 50,170, 53, 20,220, 82, 86,194,194,162,106,209,237,125, 96, 40, 83,219, 36, 13, -102,221,121, 82,247,104, 57,192, 38, 35,231, 85, 47,116,218,159,143,112,126, 32,205,128, 13, 48, 54, 34,186, 8,107, 35, 12, 19, -188,100,156, 42,233,117,206, 57,172,137,104,129, 33, 4,238, 18,201,202, 85,114, 65, 8, 14,199,148,104,223, 89, 0, 51, 2,203, - 12,196, 49,162, 85,122, 95, 7,110, 8,150, 90,113,126,190,227,228, 52,138, 45,118,206,113, 68,114,103,209, 11,117, 63, 4, 42, -136,228,194,244, 44, 24,163,105,166, 8,245, 88,196,202,248, 87,105, 34,250,179, 94,245,242,209,226,169, 52,206,167,239, 59, 86, - 25,223,234, 74, 15,192, 60, 47,186,174,162,166,202, 17,144,198,245, 32, 28, 90, 41, 24,229,158,139, 40,145,172,111, 30,165,117, -140,171,164, 76,150, 77, 49, 33,128,176,206,253,160,255, 78,197, 5,244, 89, 19,254,132,229, 28,241,148, 18,134,129,226,187, 91, -223,168,208,159,195,151, 46, 77,142, 40, 88, 11, 28,152, 34,153,240, 62,244, 12, 14,203,177,214,141,155, 20,171,130, 56,160,178, -206,203, 24, 3, 27,169,232,241,220,168,202,101, 47,130, 55,201,147,111,220,172,168,122,159,167, 47, 21, 18, 11,219, 54,234,123, -167, 43, 9,103,157, 66,156, 2, 67,205,232, 78,115,172, 65, 2,239,213,155,226,211,101, 13,189, 93, 77,136, 59,167,181,186,201, - 73,161,159,101,214, 20,195, 0, 0, 32, 0, 73, 68, 65, 84,213,241,241,136,156,147,138,236, 36,182,218,176,173,220, 74,216,199, -102, 85, 41,171, 38,247,127,254,203,111,127, 47,221, 96, 8,182,167, 81, 9, 61,135,173, 76, 62, 70,148,180,234,229, 40, 35, 4, -218,117,116, 72,140, 99, 31,250,214,202, 32, 86,143,109,130,209,197,245, 75, 28, 46,159, 33,142, 7,196,113, 64,171, 13,211,233, - 17, 57, 45,170,246, 83, 17,131, 68,185,170,234,214,110,178,102,193, 0,150,254, 65,201, 40, 92, 4, 61, 34, 48, 33, 59,133,209, - 31,104,247,192,146, 0, 99,140, 1,207,159, 95,224,213,171, 23,248,217, 47,127,129,183, 63, 61,226,219,215,111, 48, 77,204,163, -207, 71, 88, 76,168,181, 98,127,126,137,214,178,122,216, 61,103, 42,207, 39, 34, 89,173, 43, 85,206, 36, 82, 75,250, 80, 56,238, - 48,157,119, 24,207, 46, 16,135,136,188, 65, 97,234,120, 43,238, 48,238,247, 88,166, 73, 87, 23, 86, 67, 89,172, 62, 0,194, 35, - 46, 85, 44,125,244,121,133, 24,112,118,121,133,154,147,170,218,173,243, 40,105,209, 93,166,120,131,165,219, 42,137,160, 49,198, -118, 27, 20,169, 55,187,253, 67, 92, 14,102,179,211,214,100,176, 90,177, 46,139, 66,138, 66, 12,218,177,197, 24, 16,188,213,172, -123, 17,102, 82, 50, 19,219,145,120,141, 98,141, 83, 65, 79, 8, 65,169, 92, 67,244,184, 63, 58,156, 95, 28,250,133, 87,187,251, -161,177,237, 79,246,109,178,191,107,153,139, 69, 67,122, 5,227, 44,154,143, 12,217,161,180, 50,231, 60,124,164,236,237, 16, 61, - 12,219,158,226, 24, 17,172,195,253,227,204,238, 8,143, 10,154, 54,200,232,113,183, 27,224,157,197, 47, 63,124,129,223,124,252, -146,118,220,142,166, 8,178, 43, 44,165,194,143, 3, 48, 14, 40, 21,248,241,205, 29,118,135, 21,187, 51,251, 55,187,224,166, 22, -205,214,176, 73,127,178,155, 95, 70,211,171,204,251, 91,153,146, 72, 65,109, 55,133, 0, 56,255, 92, 73,108,165, 32,229,164,158, -118,113, 79,200,115, 39,187,116, 93, 25,233, 30, 80, 20,235,141,221, 9,133,215, 50,148, 75,160,191, 79,192, 74,156, 86,101,173, -164,197,241,136, 61, 39, 46,226, 19, 82, 94,144,210,210, 59,116,227, 16,226, 30, 33,238,224,220, 8, 31,104,244,238,252, 0, 24, -175, 33, 52,100, 73, 50,106,113, 42, 28,143,220, 88,228, 75, 34, 79,186, 48,214, 37,169, 88,211, 52, 25,135, 98, 83,208,244, 73, - 97,227,164, 52, 9,126, 41, 27, 2, 92,225, 34,165,233,174, 30, 28,142,148, 24, 84,101,159, 68,160, 22, 94, 75,172,156, 12, 39, -110, 30, 31,172, 94,178,212,101,245, 21, 72,218,216, 45, 69, 23,211, 1, 50, 77,187, 68,195,163,115,154,104,230, 30,214,194,194, - 80,129,217, 60,201, 14,104, 20,130, 35,174, 60,209, 17, 73,214, 71,206,165, 19,230,182, 12,120,165,217,101, 21,183,150, 90,148, - 86, 89,248,239,178, 60,213, 17, 65,173,120,246, 75,206,204,176, 72, 8,222,169,182, 65,166, 74, 74,235,116, 29, 22,211, 49,198, -208,213,169, 53, 61,139, 94,184, 37, 66,167,115,155,137,172, 8,128,101,130,213,211, 70,157, 38,200, 57,158,168,250, 16, 52, 14, -216,108,214, 86, 98,121,107,219,128, 28,141, 28, 54, 24,198, 17,198, 58,229,178,199, 97, 80, 61,139,209,231, 82, 24, 14, 93, 35, -224,157, 83,221,130, 52, 68,216, 8,145,115, 46,152,166,137, 47,246,170,239,172,181,142,167, 99, 78,155, 84,209, 21,200,231, 39, -137,118,181, 53,120,108, 70,218,243,180, 48, 33, 44,242,238,155,198,185,150, 69, 63,137,219, 75,221, 65,108, 60,205, 2, 63, 89, -115,210,113,139,168, 54,157, 55, 29,157,231, 28,141, 45,130,199,233,225, 30, 33,173, 24,198, 29,219,231, 40, 86, 81, 70, 44,180, - 67,106,234,223,147, 67,202, 7, 7, 8, 28,134,213,245,226, 59, 21, 6,176, 68,144,138,229,164,100,153, 36,176, 78,128,173, 10, -251,253,136,203,243, 61,158, 95, 63, 67, 12, 30, 57, 55, 60,156, 18,254,252,249,119, 56, 29,103,170, 78,243,140,150, 79,244, 89, - 56, 66,150, 58,223, 31, 50,130,196,176,205,207, 82,224,132, 80,204, 52, 97,136, 95, 76, 17,152,120,166, 52, 85, 14,146, 40,235, -170, 21,151,225,241,143,140,160, 40,227,187,123, 48, 5, 23, 41,140, 99,217, 39, 57,241,121, 59, 7,239, 44,134,232, 81,119, 81, -127, 95,171,133,195,108,120, 37,144, 51,175, 5,146,130,122, 98, 28,244, 98, 17,111,179, 18,200,184, 64,146, 89,174, 76, 42,114, -226,189, 93,173,156,204, 86, 40,122, 80,128, 16,158,208,142, 82,237,243,218, 81,121,247,118, 51,166,237,163,218,166, 1, 48,214, -122,180,150,113,125,237,240,230,246, 17,167,211, 57, 14,135,145, 44,134,124,105,164, 92,212,106, 84, 75,219,136,184, 42, 76, 5, - 90,136,188,207, 93,177,204, 51,130, 39, 63,247,241,241,136, 92, 23,180, 22,240,222,123,175, 54, 7,135, 71,179, 21, 13, 30, 31, -126,242, 17,190,249,241, 22,143,199, 89, 95,124, 18, 94, 58, 21,146,253,252,227,247,240,155, 95,188,143,161,156,224, 55, 66, 49, -103, 12,246,151,123,132,195,136,228, 71,220,220, 29,241,205,247, 63,194, 12, 39,140,177,119, 60, 26, 4, 33, 34, 71, 16,252, 69, -216,237,226,229, 53,204,164,177,214, 10,169,148, 14, 92, 64,199,141,168,221, 70, 38,251,204,156, 18, 74, 45,170,136, 22,213,177, -140,254,172,237,217, 7,222, 65,247,237,154, 33, 45,133, 66,206,154,180, 69, 16,187,166, 69,156,112,175, 13,191,171, 13, 13, 89, - 83,215, 26,139,230, 68,208,181,234, 56,155, 14,194,128, 16,118, 8,129, 46,115,231,200,186,102,109, 4, 12, 77, 82, 26,123,196, -183,185, 18, 36, 0,227, 51, 9,125, 4,233, 44,117,137,142,211,231,114,218,190,179, 17,173, 20,248, 51,131,180, 44,200, 76,179, -220,159,237, 48,215,166, 89, 16,222, 57,172,117,209,231,190,108, 46,215,233, 52, 51,221,177,162, 54,131,121,234,162, 56, 52,154, -202,205, 83,210, 73, 89, 99,245,123,107, 86,145,163,130,126, 45, 44,114,115,140,113, 54,108, 99,146, 11, 90, 10, 88, 9,223, 42, -185,144, 70, 70,149,239,242,235, 13,150,165,168,144,207,242,164,176,182,206, 51, 88,151, 85, 1, 55, 50,222, 86,242,155,237,217, -226,105, 45,122, 17, 21, 46,146, 42, 12, 96, 58,170, 86, 66, 92, 4, 25,222,195, 85, 88, 15,197,224,162,194,226, 73,202,138,231, - 0,162,106,159,124, 6,206,245,100,185,202, 98,104,200,101,207, 98, 97,111, 28,143,233,161,130, 54,207, 23,158,209, 41, 16, 91, -100, 5,124,196, 77,138, 97,136,147,181,142, 19,254,130,174, 37,169, 96,165, 66, 53, 12, 81,225, 90, 62, 68,172,235, 74,130,222, - 24, 9,201, 28,237, 19,230, 9,236, 38, 35,157, 45,124,181,110,163,104,177, 9,172, 42,189,152,150,159, 61, 79,136,151,180, 34, -167,164,193, 69,242,254, 26,121, 87,225, 58, 6,189, 85, 88, 22, 78, 74,241,162, 43, 18,107,225, 75,206,108, 37,233,135,234, 92, -103, 88, 99, 16, 7, 66,251, 85, 20, 84, 22,202,249, 97, 68,176, 22, 37,173, 26,199,233,252,128, 90, 23, 98, 40, 75, 87, 18, 60, -252,217, 14,211,227,253,134, 67,108,121,103, 76,216,203, 16, 77,199,117,150, 4,227, 68,252, 66,148, 40,203,221,147,117,129,228, -251,204,214, 13,195, 14,105, 93, 89, 92,229, 84, 65,123,113,117,133,219,183,183,240,214, 96, 60, 59, 71, 94,103,196,113,199,135, - 64,197, 58,205,236, 39,116,120,231,229, 5, 94, 60,191,198, 48,142,120,120, 92,112,154, 22,124,255,253, 45,121,147,115,197,112, -113,197,211,192, 21, 62, 54,248, 48,162,242,135,125,184,188, 4,140,193,254,226, 25,140, 49,120,188,189,101,129, 5,189,224, 54, - 68, 18, 40,149, 6, 32,113, 39, 65, 98,171, 97,228,135,137,187,141,121, 89, 96,125,232,187,222, 90, 49,236,247,200,235,218, 67, - 13, 74,131,245,196, 61,142,123,122,137,208, 10,210,186,160,150,130, 96, 3,206, 46, 47,177,158, 78,136,135, 1, 62,122,173,134, -227,238, 0,231, 28, 78,247,183,164, 10,221, 29,176, 78, 15, 20,166,146, 18,206,175,174,177, 78,143, 20, 72, 18, 2,225,102,215, -153,253,231,180,179, 9,195, 14, 62, 70, 26,245, 47, 51,242,186,176,146,191, 32,238,206, 17,119, 69,191, 86,107, 12, 78,247, 55, -250,153,187,230, 52, 7,154,192, 12, 70, 69,122,173,208,232,173,114,167,100, 5,100, 34, 43, 23,107,225,229,226, 52, 1,222, 54, -124,248,126,198,215,223,222,192,186,231,176, 0,134, 49,160,128,146,193, 44,239,174,156,183,176,181, 31, 22,118,220,241, 36, 0, - 72,115, 70, 75, 5,190, 22,220,220,220,225,226, 48,227,226, 34,227,207, 95, 85, 60,187,186,196,225,226,128, 16, 35,173, 36,150, -149, 42,223,224,241,209,199, 31,224,179,255,241,149, 34, 69,101,210,227,172,199,167, 31,191,194,207,127,245,247, 24,163, 7,142, - 5,168, 25,222, 2,171,221,161,186,136, 33, 6,248,146, 81, 79, 43,190,249,254, 47,104,225, 17,113, 20,152, 80,239, 18,100,164, - 46,240, 11,245, 65, 27, 18, 44, 86,101, 98, 55, 29,249,201, 69,147, 75,210,105,143,221, 88, 4,115,102,215, 65,235, 32,169,218, - 40,180, 69, 96, 54, 34, 10, 45, 44,106,205,173,104, 28,165,120,165,155,138,101, 37, 86,153, 16,188,148,158,101,181,163,183, 44, -196, 52,118, 27,179,154, 55, 88,216,190,155, 22,127,174,181, 30, 49,238,121,143, 62,194,152, 0, 31, 70, 52, 88,210, 6,176, 0, -104,219,157, 43,127, 94, 66,109, 90, 86, 31,124, 74, 21,201,200,104,220,233,175, 35,120, 11,115, 16,106,128,117, 36,170, 26,198, -136,146, 41,146,120,220, 13, 40,197,192,193,195, 6, 1, 0, 85,228,181, 42,191, 33,165,170, 44,115,205, 9,111,164,223,152, 39, -106,100, 44,187,134,233,239,175,124,113, 91,208,176,211, 32, 51, 11,163,234,196,211, 81,140,115,233, 76, 13,199,187,243, 45, 21, - 83, 61,218, 3,173, 52,220, 38,114, 19, 6,180, 54,226,230, 96, 97,209,179, 6,187,172, 69, 69, 88, 2,112, 17,218,155,105,100, - 63,131,109, 58,177,104,181,209,106,105,195,253,207,252,103,102,214, 7,145, 6,195, 82, 49,193,118, 80,181,207, 57,179,233,194, -251,232,189,100, 14, 63,169,150,167, 8, 64,107, 14,198,208, 78, 91,237,145,150,109, 27, 66,190,227, 40, 95,177,171,245,231,221, -194,132,174,188, 23,171,111,201,137, 38,131, 12,153,180,155,156,247, 14, 45,171, 26,227, 26, 66, 64,169,180,187, 95,217, 15, 46, - 25, 34, 68, 15,141, 58, 29, 86,209, 96,147,244,196,158,215,225, 88, 24, 89,153, 81, 34, 63,131, 82,171,254,122,181, 92, 26,131, -105,154,233, 62, 99,235,154,225,103,218, 57,223, 99, 99,189,225, 34,213,178, 78, 41,235, 84, 92,190,167,198, 65, 80,190,212,194, - 47,131,213, 15,209,242, 75, 84, 10,141,193, 61, 31,112,198, 57,164,229, 68,182,176,253, 25,106,201, 88,231,132,218, 38,132, 97, -135,146, 38,133,162,196,241,140, 70, 47,134, 31, 62,174,190,200, 95,235,121,167, 36,157,153,133, 11, 35,242,186,232,129, 20,135, - 29,124,136,120,184,191, 35, 63, 98, 24, 96,157,197,114,154, 97,230, 9,187,195, 57, 33, 56,121, 23, 49,158, 29, 48,159,102, 29, - 61,146,128, 98, 64, 94, 23, 52, 52, 28, 14, 7,188,252,224, 93,140,129, 0,251,169, 56,188,189, 57, 97,158,110,144, 56,177,106, - 89, 27,214,121, 37,204,100,157, 80,203, 17,121,165,248,198, 48,140,136,187, 29,242, 58, 99, 62, 61, 98,220,159,227,241,238, 86, -233,120, 41, 23,178,162, 57,143,229,116,194,178, 38,196, 97, 64, 28, 6,164,117, 38,228, 46,143,122, 74, 46, 40,166, 74, 2, 54, -198,113,192,195, 60, 17,193,104, 28,248,176, 78,104,113,164,231,198, 24,248, 72,159, 79, 89, 41,249, 44, 12, 3,226, 48,162,178, - 50,157, 4, 94, 17,181,172,152, 31, 78,104, 48,216,157, 95, 98, 62, 62, 80, 84,226, 74, 98,166, 16, 28,214, 19, 85,179,227, 46, - 98, 24, 3,188, 59, 71, 78, 51,210,156, 16,134, 17, 67,188, 64, 78,180,167, 11, 59,218,107,150,188, 32,167, 70, 36, 47, 99, 48, - 29,143,228,249,126,188,225,151,184, 34, 12, 35,176,161, 89,181, 74,145,159,186,118,105,149,159, 47,238,244,197, 94,197,163, 37, -233, 48,250,250, 70, 10, 11,238, 6, 91,197,126, 15,156,141,143,120,184, 27,112,249,236, 92, 61,195, 70,120,253,214,162,242,136, -208,114, 12,107, 74,180,227, 75, 41,193,194, 32,163, 97, 77,183,120,231, 69,134,181, 5,214,120,188,122, 81,112,115,115, 15,148, -130,221,217, 14, 46,142, 68,182,227,175,233,221,247, 94,224,245,235, 31, 48, 77,211, 19,107,204, 47,255,238, 26,127,255,243, 15, -104,247,151, 11,220,238,128,101,158,209,130, 67,220, 81, 49,177,206, 43,242,154,241,223,255,251,159,176,212, 27, 12, 59, 66, 3, - 27,227, 0,238,142,196, 91,102,172,133, 51,118,227, 59, 54,154,112, 38,191, 76, 18,170,182,168, 72, 93, 59,241,175, 79,204, 29, -104, 27, 32, 12, 29, 78,124, 24,215,130, 82,243,102,167,219, 35, 50, 69, 44,219,132,242,166, 33,148, 60,122,175, 6, 13,221,219, - 78, 69, 59, 84,152,199, 49,137, 40, 53,241,180,166,176,163,163,251,168,101,116,232, 92, 68, 8, 59,162,224,133, 29,156,139,176, - 46, 18, 77,209,121,246, 34,123,221, 31,246,220,245,218, 59, 99, 97,145,155,134,133,217, 5,153,147, 19,211,218,185,232, 46, 9, - 21,172,194,154,134,180, 90, 32, 52, 96,193, 19, 7, 64,107, 13,197, 86,118, 2, 61,133,141,136, 88, 85, 14, 85,201, 80,108,104, -152, 78, 75, 23, 17, 55,179,193,208,146, 67, 72,160, 93,138, 45,206,189, 56,156,231,196, 81,166,221, 34,108, 57, 21, 81,114,230, - 5, 19, 45,194,217, 30, 0, 34, 7, 59, 61, 75,235,218,195,182,176, 81, 96,211,142, 63,108, 70,223,244,249,165, 76,223,193, 86, - 54,229,156, 69, 53,141, 74, 19,231,177, 44, 43,103, 85,152,141, 46, 9, 79, 48,175,150,197,147, 20,249, 92, 20, 35,222, 54, 46, -135,156, 24, 38,149,170,254,121,222,123,190,128, 61,171,203,187, 80, 77, 72,156,145,191,110, 77,103,131, 99,170,156,213, 4, 79, -249, 33, 85, 6,247,200,250, 72, 38, 56,114,137, 10,251, 99,147, 28,207, 43, 7,168,139, 42,248,160, 98,101,112, 35, 72,107,230, -173,101,155,166, 14,158, 39,165,181,108,132,208,173,105,113, 83, 54, 89,243,242,243, 46,185, 80, 36,117,226,216,114,118, 28, 81, - 65, 80,225,172,127,146,149,208, 56,233,141, 88, 33, 22, 96,112,145,240,255, 83, 74,250, 92,249, 86, 11, 86, 22, 90, 17, 26, 20, -104, 45,195, 6,135,188,146,120, 65,246, 84,121,157, 88,197,238,176, 76, 39, 24, 71, 98,163,148, 18, 92, 24, 40,148,165,100, 24, - 71,190,191,229,248, 64, 7, 69, 54, 44, 10,200, 27, 11,129,133, 31,123, 7,184, 46, 51,214,121,214,125,111, 28, 7, 28, 31,232, -247, 47,203, 74, 48,130,113, 68,141, 25,181,144,248,195,199,128,117, 89, 49,238, 70,192, 56, 44,211,145,173, 7, 84,160, 68,107, -112,241,236, 25, 14,135, 61, 1,108,106,192,237,219, 27,164, 92,136, 10,198,196, 48, 10,194,160,170,206,250,132, 86, 11,150,101, - 70,206, 75, 23,254,149,130,176,223,211, 37,207, 7, 76,136,196, 65, 46,165,114,208, 12,165,133,173,235, 74, 31,244,186, 96, 28, -119, 40, 57,241, 97, 96, 20, 96,211,106,211, 16,141,211,241,136, 48,238, 97,204, 9,113, 24, 41,201,141,199, 81, 36, 50,170, 40, -105,214, 49, 86, 45, 13,166,101,196,221, 14,243, 99,130, 99,189,192,178, 16,165, 13,188,131,234,228, 57,230,204,243,154,194,128, -128, 45,178,151,105, 53,115,142,122, 3,204,138,253,197, 21,210, 58, 83,241,229, 7,164,101,194,186,172, 50, 75, 66,225,140,119, - 57,212,197, 35,227, 67,196,252,120,215,245, 20, 60,142,133, 86,221, 50,102,238,187, 86,242,127, 58, 21,207,160, 9, 74,182,194, - 52,178,228, 84,206, 46,110, 60,210,126,255, 93,135,207,190,120,192, 37, 14,212,189,177, 5,200,152, 2, 24,178,197,216,129, 86, - 41,202,180,102, 45, 66, 74, 11, 94,189,147,176,219,211,120,176,100,234, 62,119, 35,112,255,120,131,220, 14,120, 60,174,112,115, -129,227, 36, 43,207, 7,202, 71, 31,125,128,127,253,215, 63,242, 75,239,240,222, 59, 87,120,239,227,159,161,249,145,242, 14, 24, -149, 91,214, 4, 88, 7, 44, 43,124, 12, 88,150, 21,255,237, 15,127,194,106,239, 48,158,121,254, 58,146,234, 80,100,202,209, 96, -117,125, 34,211,173, 14, 82,225, 60,239,121,166,253, 40,251,166,173,235,170,244,148,132,161, 94,216,226, 38, 91,128,162,187,211, - 62, 22,108, 29, 65, 41,232,205,210, 63,231, 86, 58,134,151,190,198,170,197,147, 0,147,106, 43, 26,176, 2, 22, 23,145,160,147, - 60,231,109,195, 70,223,230, 75, 24, 78,175, 10, 97, 7, 31, 70,132, 48, 34,132, 29,143, 24, 61, 96, 60,124,136, 26, 42, 34,151, -182,149, 48, 35,116,129,153,138, 95, 25, 91,108,208,144,171,164, 15, 78,176,182, 41, 80,202, 90,139,253,110,196, 50,101, 10, 3, - 43, 14,130,226,161,244,197, 12,107, 87, 69, 89,103, 43, 88,234, 78,251,138,198,235, 85, 32, 29,178, 92,106,222, 19,164,197,130, -214, 74,153, 57, 11,134, 89, 10, 68, 41,115,124,134, 82,247,182, 44, 43,175,178, 88, 15,176,137, 63, 22,216, 77,230, 9,136,247, -100,231,162, 34, 96,229,245, 28, 21, 96,166,116,103, 2,217, 8,235,134,181,238,249,239, 15,106,143, 19,177, 29,173,208,184,168, -102, 29,130,210,227, 74,210,157,240, 56, 68,157,194,210,121, 88, 55,118, 51, 46, 68, 74,121,114,121,213, 34,226,224,186,193,135, -155,205,174,222,234, 4, 9, 27,240,146,188,179, 0,176,206, 11, 39, 90,174,234, 12, 17, 7, 86,171,149,226,127, 55, 92, 2,153, -102, 60,241,144, 11,216,133,187,222,233, 68, 86, 69,142,250, 80, 52,120, 90,217,189, 33, 43,102,187, 41,178, 44,157,219,162,253, - 33,113, 31, 41,209,177,177,255, 73,161,101, 89,244, 75,176,180,198,246,195,166, 69,214,188,204,124,177,211,207,191,241,247, 75, -171,163,190, 82,168, 98, 85, 53, 93, 8, 40,224, 30,177,141,139, 85,180,177,158,198, 11,135, 89, 56,196,226,149,110, 12,243, 23, -139, 85,173, 5,203, 60,161,150, 30,140,178, 59, 27,112,124,152,216, 94,181, 96, 24,247,120,188, 61, 97,119, 56, 32, 45,139,130, - 46, 4, 21,106, 55, 99, 15, 88,131,146, 38, 22,206, 88,248,232,148,132, 68, 66,173,128,113,127, 1,227, 44,198, 67, 99,170, 86, - 69, 41,143, 84, 32, 44, 19,198,179, 11,184,156,225,195,128,180,204, 8,193,225,242,226, 28,215, 87,231,120,246,226, 21, 30,111, -239,145,114,197,219,155,137, 20,143,126,196,195,237,137,119, 81,128, 13, 30, 97, 31, 65, 19,149,202,153,196, 64, 53,108,147,147, - 68, 44,221, 9,202,104,202,178,159,144, 46,169,202,123, 49,231, 45,140,143, 24,207,162,194,102, 72,253,154,144, 83,247, 38, 74, -103, 37, 15, 78,205, 25,158, 59, 67, 24, 10,105, 65,171,112, 49,243, 3,218,179,144,125, 12,138, 71,181,206, 32,179,118,192, 88, - 25,199,109,212,211,173, 91,210,168,226,167, 11,213,251, 78, 43,179,206,179,149, 35,232, 1, 41, 99,173,117, 73,216,133, 29,194, -238, 12, 62,142, 44, 62, 2, 92,205, 72,147,248,200,105,149, 50,236,246, 88, 79,143,122, 0, 98,131,208, 52,130,101, 84, 56,141, -237, 59,184,214, 0, 39,233,125,242,114,115,149,207,144, 13, 81,169,215, 66, 88,212,188, 38,188,184,170, 56, 30, 39,236,118,180, - 3,243,214,194,120,234, 32, 91,227,125,220,208,253,231,104, 5,131,127,196,229,243, 5, 62, 24,180, 70, 93,132,120, 79,209, 26, -206,207, 78,152, 78, 84,172,182, 90, 57,102,184, 34,238,207,248, 98,240, 24, 99,192,237,253, 17, 47, 94, 92,227,163, 79, 62, 70, -181, 1,211,146,209,214,153, 39, 1,141,125,193, 11,210,106,241,248,195, 29,254,244,213, 95,144,237, 3,226,208, 19,183,250, 24, -189, 42,159, 90,190,239,101, 73,170, 63, 72, 41,177,142, 34,107,198,122, 15,161,200, 48,213,232, 63, 83,129, 90, 45, 76,106,107, -155,108,242, 78, 11, 20, 39,137, 88,214, 58, 20,134, 62, 59, 26,229, 54, 13,184, 48,182, 23,103,212, 17, 85,137,107, 71, 46, 73, - 69, 81, 45, 37,237, 91, 37,233,176,199,182,244,110,215,218, 0,239, 7,222,161, 15,112,126,228,156,131, 72, 23,186, 15, 42,204, - 36, 64, 82,183, 81,130,173, 87,102, 11,190,146,139,134, 33, 55, 57,173, 88,230, 9, 41, 45,104,141,198,169, 49, 4,192, 91,204, -115,215,120,160, 1, 33, 22,140, 24, 80,162,135, 19, 15,112, 54,236, 40,161,110,169,176,170, 89,227,154, 25, 84,164,128,166,202, -144, 31,167, 70, 29,233,119, 85,221,221, 26, 80, 76,238,212, 52, 94, 7, 88, 55,242,154,164, 48,147, 34,107, 40,143,136,248, 74, -202,128,119, 88, 87,201, 71, 47, 24,135,160,144, 26,201,198, 40,133, 86,124,212,169, 59,212,146, 52,115,163, 85,218,207, 18,110, -187,193, 90,118, 8,193, 96,220, 57,140, 99, 84, 33,236,184,139,172, 25,177, 60,241,168,184,191,123,196,241,241,164,185,225,149, - 11,144, 53, 37, 22, 25,214, 46,170, 91,133, 51, 66, 23,111,181,189,187,207,169,243,209, 37,134,186, 86,163,151,107,215, 65,244, -207, 64, 28, 80, 82, 36, 88,107, 40, 60,138, 47,120,209, 60,208, 62,221, 0,182, 23, 21, 98, 29,116,190,175, 36,131,183, 58,217, - 17, 38,134,116,243,243,178,112, 90,101, 64, 94,179,254,172, 20,246, 83, 27,115, 7, 54, 12, 1,136,253,208,117,202,101,112,188, - 62, 73, 72,107,183, 24,231,148,217, 54,156,168,217,227,201,142,164,188, 81,250,100, 85,173,131, 20, 55,146,126,168, 23, 59,175, - 37,139, 18, 74, 29, 11, 83, 29,252,186,172, 92, 5,122,180, 2,246, 13,246,131, 85,148,235,149,119, 15, 82,177, 91, 67,221,117, -171, 5,198, 89,204,199, 35,156, 15,136,187, 17, 46, 4, 44,211,157,126, 8, 84,197,122,245,219,137, 82,176,150, 4, 88,202, 60, - 94, 78, 51,226,184, 71,195, 91, 78, 76, 75,200,105, 65,157,201,128, 31, 98,192, 50, 23,221,207, 82,101,150,177, 59, 59,224,213, -171,107, 28, 6,143, 24, 34,114, 1,166, 57,227,205,155, 35,238,110, 30, 81, 91, 83,203,211,238,224, 81,249,208,141,187,128,218, - 18, 74, 90, 81, 82,227,149,194,129, 5, 62, 76, 17,242, 91,102, 47, 93,162,100, 19, 41,136, 60,206, 33, 61, 0,117,252,214, 39, - 76,167, 19, 42,131, 91,156,119, 40, 43,244,197,139,145,124,186,158, 59,116,234,242, 73, 76,130,154, 17,247,103,152,143, 39,141, -225,139, 49,162,172, 19,130,241, 24,198, 29, 74,201, 88,231, 35, 10,167, 25,237, 14, 23,212,161,173, 9,113,207, 16,154, 2,197, - 64, 58,215,243,136, 99,244,250, 67,151,196, 43,225,230, 67,210,175, 56,241,168,150,172,211,134,117,153,144,150,169,123, 37,217, - 42,229,196,137,224, 44,118,103,231, 88,166, 71, 70,243,242, 88, 40,117, 59,145,118,234,218, 85, 17,158, 82, 81,195, 44,254,145, - 81, 99,102,130, 30, 17,195,154, 30, 24,149,121,220,181, 1, 87,207,128, 63,255,245, 17,105,217,113,128,133,165, 9,145,233,209, -150,214,128,246,136,229,136,171,139, 9,103,123,240,133,207,221, 49,103, 51, 27,235,128, 90,176, 27, 27,110,238,110,128,246, 2, -121, 77,152,166, 5,113, 24, 49,223, 29, 53,141,233,234,250, 25,113,226,223,123, 7,107, 42, 72,169,160,166, 5,168, 69,157, 13, -196, 13, 95,241,211,155, 91,124,251,211,119, 56,123, 70,105,114,116, 49, 87, 69,239,138,216,166,214,181,239,200, 75, 81,177,151, -188, 63,125, 15,202, 54,174, 82, 96, 18, 84, 0,213, 26,255,218, 86,225, 26,117, 63,164, 8,110, 42,164, 34, 6,188,225, 11,163, -109, 58, 77,190,116, 91,209, 72, 84,176,205, 80,212,208,132,104, 23, 32, 82, 23,207,149,154,249,247, 53,221,167,226,111, 58,243, -142, 73, 21, 65,156,103, 85,251, 30,214,122, 88, 55,192,121,182,170,109, 21,238,214,246, 14,133, 39, 68, 13,228, 11, 23,171,145, -140, 30, 11,219, 59, 41, 32,134, 47,244,188,160,148,149, 38, 61,213,160,213,128, 80, 9,100,100, 48,192, 89,242, 1,251,224,177, -174,148,229, 62, 12, 77, 63,243,110, 21,229, 44,241,232,177, 46, 52, 46, 37,219,158,215,142, 51, 68,143,117, 45,170, 78,223,159, -197,110, 11, 86,177,150,132,153, 84,205,164,167,239,147,232,117,178,187, 45, 62,192, 57, 48,141,142,154,170,236, 51,159, 63,244, - 94, 73,172,169,228,177,203, 69, 93,231,138, 24,189,114, 58,182,142, 27,161, 85, 6,198, 94,203, 24,126,183, 27,158,216,107,155, -138,184, 54, 33, 58,206,226,234,197, 21,222,254,116,135, 31,191,251, 1,211, 52,235, 78, 56, 4,199,235, 51,163, 5, 14,193, 80, -208,133,144,205,104, 48,148, 92, 80,235, 90,213,107,238, 28, 11, 47, 83, 71,116,111,105,141,142, 83, 51,229, 25, 34, 70, 73,238, - 57, 18,173,145, 5,147, 29, 0,224,134,133, 4,138, 13,134,125,238, 6, 64,225, 53, 83,226,103, 71,160, 74,228,128, 96,126, 70, -163,228,192,202, 83, 15, 89,255,136,149, 82, 68,173,226, 87,167,207,218, 43, 10,183,129,220, 87, 36, 82,164,207, 53,229, 76, 19, - 87,118, 12, 56,103, 80,114, 71,207, 90,198,134,171,242, 95,194,211, 56, 41,142,166,131, 30, 77, 50,224, 13,101, 97, 9, 61,178, -148,130, 97, 32,206,191, 55, 32, 15, 37,184,250,234,204,110,167, 10,233, 16, 61, 82, 74, 8,195,128,202, 49,137,214, 7,148,188, -234,190,207, 88,131,117,158, 48,236,206, 48, 61, 62, 42,223,184,143,240,168,203,203, 57,195,135,168, 7,155,103, 33,193,180,208, -254,207,179,177,190,230,140, 16,119,200,121,102,185,190,195,249,213, 57, 30,239,238,176,219,141,120,126,117,129,119, 94,189,194, -229,245,115, 60,222, 31,241,240,112,196, 79,111,238, 81,106, 67, 46, 13, 97,215, 48,157,102, 85,178,134,232, 96, 93,131,243,116, - 0,132, 33, 98,153,120,244, 99, 44,134,221, 64,226, 13,102, 27,247,132, 54,186,176, 99,116,202, 50, 22,123, 8,189,140, 34,148, -105, 88,166, 9, 33,142,104, 62, 35,175,137,196,128,195,136,178,206, 24, 70, 30,125,177, 5,171,172, 5, 99, 12,240, 43,217,181, - 74,166, 2,163,150,130,113, 71,144,140, 17,173,143,234, 56,144,165,100, 82,214,135,184,211,131, 86,146,178,164, 82,118,222,118, -150,115,240,168, 60,226,211, 49,215, 70, 37, 76,137, 76, 93, 41,238, 60,137,147, 36,117, 41,205, 19,206, 46, 46,144,230, 25, 57, - 45,100, 59,218,141, 72,243, 9,206, 91,248,184, 35,107,147,198, 80,209,190, 72, 88,244,210,174, 9,128, 71,128, 35, 85,178,177, - 45, 95, 8,140,173,173,165, 50,212,134, 65, 69,210,201,182, 30,206, 97,172,131,119, 6,231,251, 5,199,211,140,103,151, 52,134, -175,220, 77,197,104,208,106,194, 52,157, 16,221, 29, 46, 46,243, 38,151, 90, 98,100,177, 73,174,227,136, 90, 52, 28, 14, 19, 30, - 78, 73,109,101,133,125,225, 41,145,111,221,143,103,184,126, 53,224,238,254,136,187,251, 19, 74, 78,240,166, 98, 8, 30,251, 93, -160, 0,161,148,241,240,240,136,111,126,248, 26, 23,215, 64,201, 70,109, 43,137,137, 89,178,103,125,124, 60,110, 88,255,165,231, -142, 51,120,200, 26,199, 23, 73,247,176, 11,204,162,212,222,141, 11, 64,100, 59,126, 4,122,124,170,250, 92,101,156, 46,223,188, -129,142,250,244, 61, 21, 23, 6,239, 72, 75,237,182, 44, 26, 19, 39,141,195,148,162, 64, 24, 18, 79,187,243,167,119,188,247, 3, - 98,216, 33, 68, 82,183,123, 63, 80, 56,139,161,112, 22, 99,156, 30,198,133,125,249, 41,103,242, 81,203,247, 42, 19,142,210,145, -180,148,228,150,177,174, 11,210,186, 32,231, 5, 37, 47,168, 53,161,148,196, 32,173, 8,107, 6,254,245,158,109,125,134,113,172, - 3,131,102,168, 51,222,237, 7, 84,161,127,165,132,194, 66,193, 90, 43,198, 49,160, 20,160, 22,234, 20,119,251,129,115, 21, 26, -114,166,247,239,248, 48,179, 54, 8,234,109,174,121,213, 75,198,106, 39,201,172,111, 99,148, 69, 17,135,158,184, 70, 66,224,130, - 56, 68, 88, 67,207, 32,197,150, 50,155,157,139, 41,241,207,239,207,118, 60, 49, 36,208,205,225, 16, 52, 7, 93, 38,166,134, 93, - 55, 20,192,226,213, 49, 2, 0,235,105,162,162,100, 79,184,211,113, 63,192, 26, 75, 80, 33,231,176, 63,203, 8,113,196,195,253, -163,186, 75, 40, 55,220,245,216,221,214,148,154,166,158,108, 35,254,234, 62,173,180, 90, 1, 50,207,128,131,123, 72, 24, 72, 93, -110,229, 36, 76,153,102, 57,187, 93, 25,210,247,147, 57,115,188,242, 89,102,248, 60,174, 10, 69,178, 27, 90,158,233,239,178,114, -251,141, 90, 54,231, 57, 61, 73,150,115, 76,164,171, 76,164,147,157,117,226,248,211, 56, 4,222,118,246,239,179,129, 92, 19,164, - 65,232, 89,232, 66,141, 36,248, 13, 21,101,113, 28, 41, 18, 92, 86,211, 76, 81, 37,216, 13, 1,139,106, 33,198, 2, 9,194,171, -178,244,183,172, 0,233,212,229,188,245, 57,173, 36, 70, 74, 34,234, 72,122, 56, 26,182,212,228,149, 18,185,166,121,198,217,197, - 5, 89,136,150, 19, 10,131, 0,218,204, 10,199, 64,106,200,117,153,249,130,225, 60, 91,174, 52, 8, 77,104, 68,114,163,232,214, -101, 94, 97,172,197,186, 30, 17,198, 29,210,186,208, 68,160,172,136,113,196,176, 59,131, 51, 22, 87, 23,103, 56,124,248, 14, 14, -103,103,152,167,140,227, 41,227,230,254, 39,220,221,222, 34,113, 7, 87,106, 35,238,110,164,238, 38,151,132, 97,180, 0, 86, 24, - 59,192, 7,131,156,128,156, 22, 88, 79,221,125, 43, 5,203,188,162,193, 17, 66, 82,109, 75,149,217,210, 86,187, 34, 99, 13, 76, - 51, 88, 78, 51,252, 16,177,174, 21, 41,157,244, 18, 51,166, 34,238,118,136,227,158,190,247,156,104,229, 44,160, 26,111, 52,147, - 93, 36, 82, 34, 52,146,195,119, 93,146,190, 48,181, 85,160, 20,228, 83,198,184,223, 97,220,147,242,127, 93, 23,245, 69,194,144, -216, 48,196,160,187,117,231, 12,210,124,194, 56,238,176, 59, 59,224,116,119, 75,228, 58,103, 20, 44, 4,211, 11, 43,218,221, 88, - 77, 97, 35, 23, 5, 83,186, 78, 71,248, 56, 96,207,214,195, 52,157,244, 98, 26,246,228, 37, 15,195, 8,107,104,167,152, 78,247, - 60, 54,134,238,191, 84,184,195,237,141, 36, 90, 45,115, 81, 14,193,186,102, 13,117,145,139,140, 96, 15, 44, 42,107, 18,145, 72, - 7,250,229, 69,195, 23, 95,221,224,217,197, 25, 93, 44, 92,184, 44,203,138,156, 30,240,236,226,136,224, 36,210, 51,117,174, 60, - 63,147,102,147, 91,208, 84, 77, 93,129,246, 6,181, 61, 39,123,158, 49, 90,156, 54, 30,167,206,185,114, 17,150, 96, 77,195, 84, - 27, 30,141,193,221,163,195,126, 23,113,188,191, 71,198, 61,174, 95, 9, 34,149,116, 7,162, 94,149,221, 52,237,176,169, 75, 22, - 78,184, 66, 40, 88, 60,152, 91,209,168,227, 45,133,173,176,226, 85,236,111,236,100,163,175,210, 26,221,211, 3,181,171,233,177, - 17, 86, 9,175, 92, 81,183,156,135,174, 43,236,198,254,254,194,163,191,170,207,198,223,182,225,205,244,175,171,239, 50,183,255, - 50,136,145,236,106,206, 13, 12,151,137,108, 91,243,112,214,195,160,175,145,232, 96,183,250, 25,232,104,114, 67, 87,147,233, 64, -206,133,186,243,101, 65, 90,103,164, 76,209,205,212,161,175, 48, 40, 0, 40, 80,169, 56,135,182,210,179,228,125,224,142,145,118, -181,194,197,112,187, 81,151,255,235,146,148, 98, 38,240, 24, 81,161, 75,113, 54, 79,237, 9,102, 84, 46,178,113, 36,225, 36, 15, - 54,248,247, 22, 69, 41, 91,211, 35, 59,165,120, 10,209,245,125, 52,127,191,187, 33, 80,126, 3,120,125,217,186,138, 90,118,207, -222,247,236,121,183,167,179,234,252,226,208, 21,243, 60,129, 17,112, 75, 90,105,220, 63, 12, 17, 11,219,142, 97, 44,246,251,145, - 69,204, 22,203,188,224,246,230, 30,243, 52, 99,158,201,118,108,109, 64,202, 85,173,140,165, 18,236,167, 42, 36, 11,155, 24, 85, -210,104,200, 26,176,150, 94,234,105, 49, 93,187, 48, 12, 60, 6,167,128, 41,217,145, 23, 53, 45, 27, 75,235, 80,141, 30, 54,196, -200,215,104,110,214,205, 40, 76,137,195,195, 72, 48,219,119,227, 50,209, 82,133,124,233,107, 8, 89,177, 90, 93, 77,118, 31,124, -213,192, 35,167, 52, 71, 65,105,167,212,116, 50,230,172,229, 66,212,105,130,225,178,172,154,174, 6,190,244,231,121,229, 75,155, -190,231, 97,116,124, 38, 85,157, 80,200, 62,189,255, 28,123, 48, 12, 74,213, 66, 72,139,122, 33, 18,254,223,255,249,223, 55,242, - 66,123, 13,112, 55,155,100, 33, 18, 90, 4,205,115,150,208,135,192, 68, 56,203,134,120,231, 3,118,103,231, 84,181,230,172, 25, -188,158,171,211,170,252,117, 11,239, 35,174, 95, 94,195,199, 1, 46, 70,164, 53, 35, 45, 51,230,211, 17,211,241,164, 40,191,221, - 56,224,234,242, 18, 87,207, 46,224, 92,196,178, 20, 60,220, 79, 56, 77, 43, 93,226, 54,224,248,120,162, 23,187, 84, 13,228,240, -193,194,218,138,113, 71,151,180, 8, 0,125,112,218,173, 40,217,201, 82,103,158,216,114,150, 57,134,209, 57,139,101, 78, 60,202, -222,238, 52,232, 67, 89,230,164,149, 18,241,214,161, 99, 49,195,187, 55, 17,131, 41,158, 83,160, 14,219,131,153,247,154,228, 61, -175, 93, 25,203,191,191,176,154,216, 24,244, 75,141, 69, 67,206,154, 13,172,164,234,190,104, 93,215, 77, 85,203,227,237, 84, 57, -105,174,169, 34, 83, 84,231, 70,241,163,153,233, 80,108,171,225, 7, 65,236, 74,129, 31,194,162,161, 29, 76,151,115,244,115, 85, -181,116,235, 97, 15,114, 73,200,129,166,212, 51,174,154,197,163,107,141,217,124, 70,146,136, 5,189,192, 5,182, 65,225, 5, 85, -121,248,223,126,223,224,252, 75, 60,191,186,192,237,237, 3, 30,142, 15,184,122,182,226,226,156,190, 15,221,229, 51, 18, 82,197, -103,149, 43,124, 30,139, 11,249,176, 54, 96, 77,192, 15, 63,158,225,112,184, 68,169,224,128, 29,154,104,164, 92,144,115,165,236, -226,148, 16, 25, 78, 34, 7,201,221,221, 45,206, 46, 18,206,206,141,134,147, 72,225,176,229,172, 83, 49,151, 54,207, 86,223,209, -146,197,180,118,176, 38, 39, 19, 54, 30,131,151,218, 54, 25,220,142, 15, 63,137,103,229,120, 27, 43,226,212,196,214, 23,206, 10, -216,228,119,203,243, 79,226,163,162,147, 31,152,246, 4, 97,218,239,239,214, 59,239,206,167, 17, 97,250, 38,189, 11, 79,190,190, - 24,119,240, 46,194,249, 17,145,211,213,156,139,236, 6, 97, 76, 50,243,204,101,236,174, 35, 85, 97, 59,240,179,174, 9,101,149, - 10,161,156, 87,164,180, 96,153, 39,180,150,145,185, 67,111, 53,211,127,114,218, 27,157, 89,103,212, 36, 12,180,203,143,195, 14, -222, 5,132, 24, 17,227,136,113, 55, 80,129,202,163,233, 16,131, 38,136,137, 21, 41,198, 64, 80,162, 33, 98, 93,211,147,131, 82, - 10,227, 24,189, 66, 94,100,245, 38,144, 38, 99,240, 55,180, 75,232,106, 69,131,116,184,184,150,177, 58, 52,147,157, 8,158,242, -191,149,203,222,122,224, 21,237,145,141,186,108,196, 63,157, 89,109,189,157,230, 16, 37,146,119,213, 28, 69,124,124, 60,225,248, -120,194, 52, 77,152, 78, 51, 23, 59, 21,173, 57, 60,123,254, 46, 78,199, 71,164,229, 78,145,215,214, 89,122, 7, 88,128,215, 3, -127,140, 90,197, 68, 4, 40,147, 32, 81,215,203,138,169,181,110, 51, 67,235,171, 58,121,223,181, 43,229,239,205, 8,148,102,115, -166, 10,203, 68,166,145,242, 32, 54,126,119,132,175,226, 92,207,171, 16,129,104, 78,165,255, 76, 96, 25,169, 29,224, 67,208, 53, -139, 99, 20,117,136, 65,209,223,178,166,210,115,149,167, 1, 82,152,175,107, 70,201, 25, 41, 37, 44,203,162,163,117,249,187, 58, -205,181,105,206, 10,176, 81,200, 11,154,184,210,202,205,179,128, 86, 3,121,176, 41, 84,106,213, 53,157,151,177,157, 38,107,109, - 30, 54, 17, 25,208, 88,201,233, 33,228,125, 64, 54, 77,125,116,165, 0, 46, 12, 72, 57, 99, 62,157,224, 67, 64,203, 69,199,133, - 70,160,255,220,173, 91,233, 38, 35, 65, 91, 4, 90, 95, 50,169,180,159, 63,123,142, 87,175, 94,192, 57,143,105, 74,184,189, 95, -113, 58, 30,145,107,195,233,180,226,248,184,192,248,128, 56, 0, 15, 15, 19,137, 18,188, 5, 76,134,117,181,239,179, 75,163,175, -141,247, 73, 89,125,155,141,145,141,204, 74,111, 61,104, 68, 46,238,170, 56,206, 46, 98,160,157, 34,212, 75, 88, 53,128,130,249, -219,181, 17, 42,112, 19,159,183, 77, 70,146, 93,149,140,174,156,165, 41,133, 88, 82,100,172,178, 46, 9, 33,144,237, 3,173, 98, - 24,189, 30,236,166, 81,144, 70,201, 5,205,118, 62,178, 84,137,181, 85, 70, 31, 66, 85,174,222, 89, 88, 47,251, 56, 43, 75, 84, - 6, 37,212, 30, 58,163, 15, 38,137,255, 42,251,114,185, 54, 32,188,168,118,224,230,201,131,108, 93,213,140,110,203, 47,158,184, - 4,192,240,154,194, 5,144, 15,244,146, 9,228,145,108, 83, 20,150, 65, 69, 22,120,220,201,104, 73,174, 70, 9,126, 87,200,106, -195,136,224,151, 47, 12,254,240,249, 91, 76,243,140,232, 31,241,225, 7, 86,199,155,180,183,244, 10, 35, 49,155,238,200,122,175, -226, 36,186,240,179, 94,114, 6, 5, 49,172,184,189, 49, 24, 3,181, 81, 51, 0, 0, 15,117, 73, 68, 65, 84,134, 65, 85,227,196, -253,167, 12,131,182,174, 8,214, 34,179, 43, 96, 45, 21,211,250,136,243,203, 21, 97, 52,200,197,233,197, 35,202,254,182, 9, 47, -217,190,188, 66,212, 51,205, 60, 1, 91, 84,197,134,242,200, 17, 85,187, 32, 18, 13,109, 40,132, 60,222, 19,107,155, 92,212, 6, -146,154,199,216, 88, 94,101, 72, 33,208, 74,235,255,187,117,133,174,217,220,222,230,111, 47,116, 60,129,224,109,238,248, 13,141, -142,125,182,129,249,237, 33,208,101, 78, 96,153, 64,121, 9,214,169,239, 90,148,238,212, 60,208,138, 72, 4, 96,102,147,143,190, -221,159,175,235, 74, 4,202,188,176, 46,129,186,243, 90, 18,249,214,217,190,215,211, 14, 87,148, 66, 17,192,198, 56,132, 80, 80, - 96,224,170,195,233,116, 82, 1, 92, 74, 96, 33, 18,189, 35,105, 77,234, 53, 78,107, 67,225,221,185, 36,147,137, 69, 73, 88, 20, -153,197, 94,130, 9,149,213,147,196, 84,251, 90, 53, 24, 68,146,185, 2,239,194,101,151,236,156,225,208,162,166,169,107, 50,186, -118,150,196,114,173,153, 30,155,202,204, 14, 10, 52, 34, 32,148, 36,247,201,115, 47,255,166, 88,107,139,227,241,132,101, 94,112, - 58, 78, 72, 41, 97, 58, 45,180, 86,228, 34,160,243, 7, 40,242,247,248,120,194,186, 76,204, 40,105,154,174, 56, 77,243, 19, 17, -161,142,152, 89, 41,110,108, 63, 11,169, 1,226, 11,152,207, 88,176,166,131, 86,201, 22,173, 64, 27, 13,171, 49,223,178, 38,107, - 42,152,148,144, 43, 17,210, 78, 75, 82, 87,132,156, 61,221,114,215,167,175,212, 76,249,206,172,231, 59,140,158, 89,104,128, 76, -173, 21,235,178, 34, 12,145,244, 21,206, 49, 91,194,116, 91,166,193, 19,180, 47,221, 99, 69,173,106,203, 66,159,169,172, 87,140, -181, 88,151,117,147,244,102, 54, 86,188,170,231,129,198, 14,115,194, 27,173, 99,184, 49,226,245,130,156,191,164,115,233, 5,181, -231, 12, 35,162,240, 88,203,248,199,158,125, 43,187,207,156, 87, 86,165,210, 14, 11,153,237, 23,193,227,240,236, 57, 90, 51,152, -143, 15, 12,245, 23,241, 6, 80, 83,131,247,161,123,123, 45, 61,200, 68,161,107,240,129,190,152,253,126,196,203,103,231, 8,206, - 35,165,134,159,222, 76,152,166, 21,243,156,144, 75, 35, 81, 18,167,148,237,175,158, 33,173, 9,211, 60, 33, 12, 22, 33, 22,180, - 58,179,157,141,148,205, 90,237,212,202, 15, 85, 85,171, 27,212, 71, 8, 77, 18, 43,165,193,251, 30,195,186,204, 36, 70, 19,111, - 44, 76,235, 47,112,237, 30,234, 90,179, 90, 34,114,238, 54, 34, 99, 13, 26, 67, 56,100, 76, 35,221,156, 40, 26, 73,100,199,151, -220, 38,178,144, 88,210,244,194, 72, 80,128, 88,196, 52, 0, 0, 82,156, 88, 13, 64, 49,242,119,240,195,101,184,184,201,185,106, -177, 86, 56, 58,146,198,202, 89, 89,208,208,206, 12, 76,113,227, 52, 35, 21,148, 84,189, 60,156,119,172,115,128,194, 99, 68, 45, - 43, 43, 23, 65,153,166, 53, 49,121,176,176,250,150,212,235,150,191, 46,137,148,108,173,160,149,138,102,232,247, 56,239, 0,107, -209, 74,225,189, 22, 58, 74,183,117, 69,117, 8, 13,239,190,172, 56, 28, 38,140, 99,208,226,141, 72, 95, 13,144, 46,191, 86,254, - 51,250, 56,187,177, 32, 70,190,175,156, 23, 10,229,169, 5,187,161,226,246,230, 45,156,189,166, 29, 42,167, 36, 89,107, 17,157, -193,249, 97,135,148, 18,230,156,240,211,219,123,184, 97,194,243,119,156, 2, 78,138,178,249,205,223,132, 95, 72, 4,234,255,223, -214,181,237,216,109, 28,193,154, 11,201, 93, 57, 78,236,135, 0, 9, 96, 63,228,255, 63, 43, 15, 14, 16, 59,182,172, 61,231,144, -115,233,201, 67, 87,247, 12,109, 9, 16, 4, 44, 36,237,146,135,156,238,174,174, 75, 92, 34, 87,181, 83, 79,132,129,199,178, 11, -159, 40,204,156,218,215, 73,217,236, 52,173,249,180,230,199,190, 30,252,239,117,202,172, 26,167, 78,251,179,227, 38, 87,192, 36, - 35, 33,172,243,121,184, 23,246,101, 37, 57,198, 82,227,131,197,119,110, 94,208,247, 67,161,219,141,153,232,192, 44,232,112, 98, - 26,156,209,222,250,156,220, 76,114, 55, 29, 25, 59,122,107, 40,245,242,130,174,158, 10, 85,207,165, 81, 1, 84, 90,191,172, 77, - 53,208,165, 18,185,216,144, 82, 67,109, 21, 57,155, 90,100,195,121, 94, 8, 81, 27,185,109,219,200,124,166,206,155,205,106,135, -224,245, 58, 85,158,118,108, 14,211,170, 15,133, 65,231,112,207,246, 45, 37, 8, 39, 84, 51,100,114, 75,107, 78, 97, 58, 81,235, -174,214,154, 2, 35, 40, 91,163, 16, 34,152,205,173, 15,255,182,103, 95,147, 25,167,166, 92, 5,163,171,252,106, 14, 29,211, 6, - 22, 67, 11,240,235,169, 83,248,227,241,100,222,195,148, 90, 53,114, 24,148,209, 62,188,129,120,251,116,208, 0,168, 65,216,156, -152,237,172, 41, 45,134, 8, 98,200,158, 97,111,143,145,197,209,118,242, 65,114,202,254, 46,169,194, 69,125,243, 83, 74,142, 32, - 26,170, 97,201,115, 49, 76, 94,138, 77,234,118, 63, 12,221, 51, 91,104,227,121,105, 61, 91, 99,136,103, 86,155, 57,245, 37,222, -103,115,228, 84, 4, 35,123,100,177,237,235,117, 55,222,177,167,233,187, 98, 60, 29,131,253,205,213, 80,155,121, 54,157,173,222, -204,162,208,187,171, 78,212, 13, 86,207,233,110,140,251,218, 16,227, 68, 61, 76,249,209, 91,115,228,213,243,215,137, 42, 91,212, -116,167, 9, 82, 6, 4,209,187, 22, 97,197,159,187,179,141,249,189, 70,167,183, 27, 97,111,118,111, 13, 95,126,253, 89, 15,235, -214, 61,151, 86, 53,233,137, 58,214,177,236,194, 42, 90,219,244, 34, 14,229,112,126,251,118, 32, 33,224,247,207, 23, 94,175, 7, -158,175,130,243,210, 29,215,117, 53,196,108, 83,139, 78,142,143, 47,191, 33, 39,193,113,116, 79, 19,179,125,181,194, 53,209, 39, -229, 28,130,134, 27,208,223,215,166,108,125,209,231,174, 55,165,192, 0, 2,157,110,246, 35, 47,153,226,184,153, 10,120,210, 34, -221,198,202,213, 72, 72, 81,105, 96, 38, 81, 77,117,160, 1, 49, 42,179,242, 60,139, 63,148, 66,223,246,108, 4, 69,179, 11, 13, -240,140,112,149, 92,204,137, 78,247,159,253,118, 0,175, 48,220,236, 22, 53, 24, 99,176,235, 11,113,129, 80, 57, 1, 91, 62,180, - 70, 54,138,107,218, 3,244,250, 58,253,169,253,112, 29, 97,153, 2,131,119,218,154,122, 74,171, 69,139, 37,140,137,135, 48, 83, -228, 74, 33, 66, 48,240,122, 40,255,160, 94,250,176,231,180,234,118, 59, 66, 87,184, 83, 95,242,232, 5,195,156,182, 52,242,176, -249,164,222, 91,197,247,223, 1, 67, 42,202, 53,227,125,253, 90,237,112,176,156,110, 55, 24, 17,111,106,220, 95, 61, 48, 87,122, -232,117,126,247,221,137, 95,254,243, 63,236,251,155, 42, 29, 74,197,219,177, 97,223,222,241,122,105,206,241, 79,255,253, 5,127, -253,190,226,239,255,248,228, 76,122,157, 20, 4, 0, 19,157,114,102, 97, 45, 12,199,208, 67, 77,245,228,118,176, 36,247,111,182, -104, 82,135,249, 48,247,182,198,202,118,184,117, 76, 57,142,174, 62,132,205,100, 92, 32,117, 42, 13, 32,186, 34,185,193,232,227, -207,108,245,177, 74,179,194, 77,243,107,187, 61, 47,232,127, 34,188, 7, 45,228,187,234,207,119,146,226, 98, 82,103,200, 85,125, - 97,202, 11,243,235,246, 92,239, 46,124,180,105, 98,211,245,231,174, 77, 61, 42,106, 43,184,174, 23, 73,112, 69,239,171, 84,200, -104, 24,210,110, 43, 14,191, 30,207,119, 47, 16,217,209,187,146, 83,115,214,176, 17,164,140, 24, 6,141, 78, 56,169,146,236,123, - 28,135,146,157, 24,245,171, 13,250,180,216, 77, 35, 57,241,209, 62, 43,203, 67,183, 70,206, 66,139, 34, 77, 96,212,149, 13, 44, - 14,244,163,168,170, 58, 17, 1,114, 86,228,107,223,178, 26, 71, 5, 96,132,225,196,177,141,214,220,103,189, 92, 1,227,106,163, - 23,220,203,222, 62,251,215,243,196,243,161, 30, 26,154,160,216, 60,186,216, 10,184,145, 36,173,209, 53,180, 40,229, 12, 25, 17, - 32, 26,226,166, 39,214,188,218,170,144,239,175,177,254, 91,155,235, 66, 55,127,177,240,120, 26, 33,217,207,108,146, 47,251,173, - 4,228,230,141,159,121, 47,140,133,133, 89, 59,179, 72,168,134, 82, 2,174, 44,171,161,224, 82,199,225, 68,225,137,154,165,148, -200, 63, 74, 72,121,195,182,101,198,135,139, 15,129, 54,100, 89,146, 95,163,228,176, 93, 21,177, 69, 59,130,253, 68,190,248, 89, - 61, 30, 31,254,238,205,204,140,238, 36, 97,107,240, 60, 69,174,119, 52,147,116,135,225, 28, 46,243, 2, 25, 67, 0,161, 14, 94, -132,110,232, 51,115,161,209, 99, 66,186, 32, 43, 52,216,233, 81, 25, 49,122,115,253,157, 38, 43,233,161,157, 24,252,224,105, 80, - 8, 24, 65,148,192, 68,219,186,169,123,141, 40,103, 81,157,175,177, 89,217,157,138, 31, 62, 3,173, 40,228,255,251,243,194,199, -163,224,186, 42,174, 83,205,107,122,159, 26,188, 64, 88,116,223,129, 24, 27, 54, 90, 2,106,241, 75, 64, 83, 15,232,193, 34,165, - 7,134,249, 82, 79,215,186,152,166, 17,193, 16,154, 89, 12,133,232,243,198, 29,148, 77, 71,116, 54,203, 57,210,148, 66,221,209, -214,221,186,133, 97,236, 71, 90, 36, 24,113,198, 40,118,225,126, 95, 67, 26, 18,111,250,220,151, 40,249, 37, 68, 64,218,240,220, -229,200, 66, 27, 72,210,210,105,187, 57,236, 35, 93,176, 31, 27, 68,135, 45,221, 77,166,200, 16,137,224, 76,104,113,105, 84, 92, -162, 84, 65,102, 60, 31,170,129,197, 12,134,161, 44,181,187, 29,162,176,176,216,122, 34, 48,105,205,188,244, 45,169, 47,249,100, -161,100, 65, 44, 80,179,244, 14,105,102,132,211, 81, 37,120,131, 84, 45, 71,221,247, 91,205,119, 78,181, 54, 63,140, 53,245,170, -112,111,107, 47, 69,243,233,221, 88,234,154, 96,215,252,165,193, 8, 51, 60, 33, 40, 10, 97,134, 47,182,106,176,207, 67,247,201, -180,100, 29, 3,219,214, 17,143, 7,202, 83,229,111,182,167, 46,231,133,231,243,196,207,159, 63,227,159, 63, 2,223,124,251, 78, -120, 54,122, 97, 14, 49, 83, 18,179,249,228,145,199,174,205,133, 5, 48, 64, 53,181,102, 44, 19, 98,210,249, 82,204,219, 31,115, - 90, 48, 40,190,247,165,160,136, 79,115,129, 72,210, 48,167, 44,169,108, 12,198,173, 73, 95,208,250, 63, 34,232,203, 58, 96, 45, -213,227,214, 48,134,233, 70, 51, 27, 36,135,221,163, 23,114, 43,236, 41,239,202,108,143,137,190,237,201,119,156,195, 67, 67,104, -136, 50, 58,119,152,147, 12,103,147,102,151, 6,145,134, 82, 78,148,122, 82,121, 67,184, 93, 10, 27,152,254,199,125,192, 87, 26, -150,134, 90, 47,228,188, 19,145, 59,241,246,246,134,171, 48, 36, 35, 68, 92, 87, 65, 41, 13,239,239,111, 44,190, 21,159,190,121, - 87, 50,173, 7, 41,117,103, 49,219,103,116,190,206, 25,133,203,213,156,249, 54,104,200, 76,167,223,120,242,116, 46, 64,225, 84, -133,218,251,242, 30,168,193,201,179, 84,151,142,198,212, 81, 95,138,184, 60, 62,228,230,185,191, 6,132, 32, 0, 31, 95, 26,191, -223, 32, 81,107, 62,243,142,246, 12, 37,236,218,212, 58,205,193,244,140, 83,152, 62, 33,196, 93,223,137,246,244, 0, 26, 13,124, - 2,174,243,226,215,194,189, 32, 27, 95,163,155,253,112,192,190,169, 18,105,176, 17,101,210, 1, 17,129,228,177,191, 51, 20, 38, -112, 85, 18,248,190, 12,247, 84,241,253,240, 98, 21,219,249,110, 27, 39,105,140,232, 36,100,123, 70, 45,120,198, 16, 1,125,156, -233,158,200,179, 10, 92, 45,235,125,152, 6, 74, 93,186,174, 44, 23, 75,117,247,197,103, 3, 88,107, 65,171,141,114,207,153,199, - 17,226, 76,158,244, 21, 32, 21, 22, 78,160, 37,105,185,113,226,182,208,172,110,242, 61,139, 86, 77,202,250,247, 53,240, 48, 88, - 94,239, 95,158, 89,173,220, 17,164,232, 55, 53,111,219,116, 97,228, 69,107, 6, 55,167,170, 16, 17,146, 48,118, 84,157,193,108, -130,200,140,180,203, 57,161,182, 37, 88,158,211, 68,171, 13,191,254,124,225, 58, 59,206,171,206,130, 16, 3, 6, 37, 20,105,139, - 80,235,230,130,253,128, 67, 30,215, 89, 84, 83, 9, 22,151, 56, 89,163, 86, 80, 21,101,176,131, 53,121, 71,169,132, 25, 26,235, - 84,241, 78,108, 64,211,187,114, 12,144, 1,228, 40,232,157,142, 73,180,138,236,109,166,225,204, 93,221,212,114,186, 7, 51,179, -222,205, 62,213,246, 98, 0,208,139,120, 98,156, 25, 88, 96, 4,106, 68,133,102, 17,193,225,170, 96,228,138,184, 88, 52, 6, 96, -116,241,110,218,174,215,194, 86, 6,134,103, 42, 15, 12, 72, 45,206,196,148,160,159,141, 30, 34, 10, 75,135, 8, 84,178, 96, 21, -137,201,252,127,130, 67,162, 10,175, 51, 62,151,102, 22,182,223, 82, 61,120, 33, 2, 33, 19,118,238,157,241,129,209, 15,142, 24, -163,202,250, 0,102, 84, 7,196, 33,144, 22,110,187, 67,219,167,201, 50, 97,199,104,251,114, 78,161, 11, 36,109, 36, 45, 33, 76, -107, 18,164,177,144,212,172,152, 56,215,131,147,166, 50,237,163, 91,122,202,152,101,240,219,191, 13,252,244,185, 34,149,134, 79, -223,188,227,237,200,248,229,215, 15, 60,234,239,248,225, 95,154,234,166,132,187,160, 13, 49, 89,219,198, 42, 55,152,217, 8, 50, - 49, 69,156,116, 78, 12,105,166, 86,137,116, 90,171, 10,155,183,177,192,167,114,131,234, 21, 77, 80, 6,111, 37,204,175, 48,250, -202, 80,159, 6, 48,171, 17,140, 23,102,140,251, 20, 27,190,166, 45, 95,254,237, 88,216,247, 94,215,131,223,207, 16, 18, 73,104, -159, 56,157,111,234, 10,151, 54,132,168, 74,143,152, 19,229,148, 51, 81,107, 70,121,234, 90, 75, 74,245,230,163,213,206, 67,147, -150,154,237, 68, 41, 23,164,147, 12, 55,218,178, 63,191,147,250, 2,166,202,230, 94,212,133,108,249,147,172,124,125, 22,246, 35, - 59,186,168, 43,167, 0, 57, 54,222,130,142,243,188,148,109, 30,117, 2,237, 77,220, 8,196, 11, 70,210,172, 2,219, 73,103, 73, -232, 61, 78, 43, 83, 66,228,225,164, 67,220,150, 81,174,203, 87, 99, 38,209,179,201, 47,156,156,238, 45,223,158,223,195, 73, 98, - 93, 9,194,147,201,221,150, 20,197, 53,249,111,146, 83,205,218,182,241,156,108,189,163,131,222, 17,146,110,201,110,145,104, 88, -222,222,112,157, 47, 64, 46, 95, 37, 90, 66,156,173,155,134, 8,210,150,153,248,216,221,100,106,208,157, 79,152, 67, 16,194, 92, -137, 6, 68,198,252, 6, 72, 24, 75,192,204,112,249,179,213, 38,105,226,123,100, 31, 46,185, 91,206, 41,163, 19,121, 8,182,131, -103, 13, 75, 41,163,212,194,230,139,198, 69,190, 94, 18,162, 34, 74,244, 54,196,110,163,153, 78,107,182,254,154,104,146, 38,154, -106,243, 95, 94,197,239,111, 35, 33,238, 60, 95,238, 13, 17,104,181,174, 15,119,184, 37,210, 13,183,196, 54,190,139, 54, 27,231, -171, 56, 58,106,232, 67, 92,185, 13, 33,176,160,119,111,126,245,243,238,254, 12,100, 37, 30, 97, 18, 18, 8,191,167,152, 8,193, -194,139,146,233,133, 71,183,167, 70,208,155, 22,116, 61,212, 35, 82,222,144, 55,211,253, 6,159,182,221,199,186, 11, 18,229,103, - 31,207,130,215,147,121,200,153,105,112, 91, 68,171, 5,239,239, 3, 57,107,182,247,160, 14, 79,243,201, 5,199,219,225,249,217, -105, 83,130, 73,165,251,143, 57,115,101, 66, 95, 6,181,244, 62,144, 6,176,237,145,153,220,145, 76,245, 37,237, 9,129,241,133, -129, 93,221, 64, 19, 62,252,117, 66, 85, 33, 4, 71,193, 99, 28,126, 95, 76, 94,166,222, 4,193,139, 36,220, 35, 25, 56,222,119, -151, 72, 25,121, 6, 49,176, 72, 83,243, 30,151,132, 34,204,134,192, 58, 68, 55,195, 33,100,156,114, 68, 41,213,201, 70,246,255, - 90,167, 94, 75,157, 59,114,122,192,247, 46, 12,228, 80, 59, 86, 45, 24,129, 49,174,130, 8, 30, 68,152, 49,173,138,134, 76,252, -171,209, 64, 66, 72, 34,155, 70, 49, 76,149,147,249,252,128, 6, 47, 6, 69,137,241, 3,250,204,153, 71, 72, 68, 95,112,243,115, -246, 78,185,117,205, 92, 31, 36,128,153, 11,215, 26,231,104, 80,155,177,189,187, 44,126,203,141,205,253,152,161, 8, 57,121,202, -221,180,190, 37,209, 12, 1, 57, 3,251,123,199,245,219, 64,137,192,191,191,124,224, 47,223,119,252,248,131,134,190, 88,150,121, - 24, 3,199,219,161,135,249, 18,150, 97,135,136,125, 46,205, 15,238,137,124,129, 84, 19, 89,243,207,205,108, 37, 96,129,208,225, -225, 44, 70,210,148, 49,225, 76, 44, 5, 28, 52,133, 27,203,159,179,136,143, 91,192, 6,238, 95,162,106, 97,122,170,143,123,169, - 95, 10,188, 69, 29,103,108,251, 59,142,227, 19,182,125,215, 44,244,188,185,127,187,241, 43,220, 33,142, 7,228,140,149,158,141, -153, 77,232,181, 84, 93, 65, 54, 13,123,186,202, 11,173,158,110, 40, 51,134, 22,115,127, 17,195, 87,213,118, 95,181,168, 53,150, - 60,160, 90,228,148,148,208,116, 28,193,119,204, 41, 51,147, 61,137, 15, 6,198,109,177, 56, 96,159, 2, 69,136,226,137,107,213, -227,162,236, 88,149, 40,118,109,186,207,143, 68, 12, 35, 7, 39,113, 4, 80,145,185,232,241,198,138,132, 90, 35, 36,222,240,153, -191,192,141, 80, 6, 99,208, 51, 52, 40,154, 55,131, 66,252,182,215, 54,132, 54,209,132, 41,198,190, 12, 32,148, 94, 70,101,249, -247,246, 64,239,215,228,125,112,144,241,226, 52, 4,113, 76,206, 80,107, 21,206,120,115,120, 94,207,156, 25, 49, 60,161,100, 29, -118, 22,130,152,173,250, 40,181, 84,114,156,102, 22, 4,128, 92, 27, 61,139,106, 43,110,108, 3,227,149, 18,210, 47,181,249, 26, -201, 26, 81, 67, 34, 66, 0,101,150,217,163,166,109, 64, 90,127,117,219,211,143, 85, 6, 59,110,202, 2,243, 72, 48,189,122,171, -226, 74, 14, 43,208,238,183, 80,245,231,219,182,221, 27,228,169, 40, 10,168, 36, 34,218, 36,127,158, 39,182,156,209,153,116, 89, -174,230,211,191, 17, 50, 53, 35, 68, 47,254,255,159,208,210,246, 3,165,114,118, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130, +137, 80, 78, 71, 13, + 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 1,245, 0, 0, 1, 26, 8, 6, 0, 0, 0, 8, 90,206, 70, 0, 0, 10, 79, +105, 67, 67, 80, 80,104,111,116,111,115,104,111,112, 32, 73, 67, 67, 32,112,114,111,102,105,108,101, 0, 0,120,218,157, 83,103, + 84, 83,233, 22, 61,247,222,244, 66, 75,136,128,148, 75,111, 82, 21, 8, 32, 82, 66,139,128, 20,145, 38, 42, 33, 9, 16, 74,136, + 33,161,217, 21, 81,193, 17, 69, 69, 4, 27,200,160,136, 3,142,142,128,140, 21, 81, 44, 12,138, 10,216, 7,228, 33,162,142,131, +163,136,138,202,251,225,123,163,107,214,188,247,230,205,254,181,215, 62,231,172,243,157,179,207, 7,192, 8, 12,150, 72, 51, 81, + 53,128, 12,169, 66, 30, 17,224,131,199,196,198,225,228, 46, 64,129, 10, 36,112, 0, 16, 8,179,100, 33,115,253, 35, 1, 0,248, +126, 60, 60, 43, 34,192, 7,190, 0, 1,120,211, 11, 8, 0,192, 77,155,192, 48, 28,135,255, 15,234, 66,153, 92, 1,128,132, 1, +192,116,145, 56, 75, 8,128, 20, 0, 64,122,142, 66,166, 0, 64, 70, 1,128,157,152, 38, 83, 0,160, 4, 0, 96,203, 99, 98,227, + 0, 80, 45, 0, 96, 39,127,230,211, 0,128,157,248,153,123, 1, 0, 91,148, 33, 21, 1,160,145, 0, 32, 19,101,136, 68, 0,104, + 59, 0,172,207, 86,138, 69, 0, 88, 48, 0, 20,102, 75,196, 57, 0,216, 45, 0, 48, 73, 87,102, 72, 0,176,183, 0,192,206, 16, + 11,178, 0, 8, 12, 0, 48, 81,136,133, 41, 0, 4,123, 0, 96,200, 35, 35,120, 0,132,153, 0, 20, 70,242, 87, 60,241, 43,174, + 16,231, 42, 0, 0,120,153,178, 60,185, 36, 57, 69,129, 91, 8, 45,113, 7, 87, 87, 46, 30, 40,206, 73, 23, 43, 20, 54, 97, 2, + 97,154, 64, 46,194,121,153, 25, 50,129, 52, 15,224,243,204, 0, 0,160,145, 21, 17,224,131,243,253,120,206, 14,174,206,206, 54, +142,182, 14, 95, 45,234,191, 6,255, 34, 98, 98,227,254,229,207,171,112, 64, 0, 0,225,116,126,209,254, 44, 47,179, 26,128, 59, + 6,128,109,254,162, 37,238, 4,104, 94, 11,160,117,247,139,102,178, 15, 64,181, 0,160,233,218, 87,243,112,248,126, 60, 60, 69, +161,144,185,217,217,229,228,228,216, 74,196, 66, 91, 97,202, 87,125,254,103,194, 95,192, 87,253,108,249,126, 60,252,247,245,224, +190,226, 36,129, 50, 93,129, 71, 4,248,224,194,204,244, 76,165, 28,207,146, 9,132, 98,220,230,143, 71,252,183, 11,255,252, 29, +211, 34,196, 73, 98,185, 88, 42, 20,227, 81, 18,113,142, 68,154,140,243, 50,165, 34,137, 66,146, 41,197, 37,210,255,100,226,223, + 44,251, 3, 62,223, 53, 0,176,106, 62, 1,123,145, 45,168, 93, 99, 3,246, 75, 39, 16, 88,116,192,226,247, 0, 0,242,187,111, +193,212, 40, 8, 3,128,104,131,225,207,119,255,239, 63,253, 71,160, 37, 0,128,102, 73,146,113, 0, 0, 94, 68, 36, 46, 84,202, +179, 63,199, 8, 0, 0, 68,160,129, 42,176, 65, 27,244,193, 24, 44,192, 6, 28,193, 5,220,193, 11,252, 96, 54,132, 66, 36,196, +194, 66, 16, 66, 10,100,128, 28,114, 96, 41,172,130, 66, 40,134,205,176, 29, 42, 96, 47,212, 64, 29, 52,192, 81,104,134,147,112, + 14, 46,194, 85,184, 14, 61,112, 15,250, 97, 8,158,193, 40,188,129, 9, 4, 65,200, 8, 19, 97, 33,218,136, 1, 98,138, 88, 35, +142, 8, 23,153,133,248, 33,193, 72, 4, 18,139, 36, 32,201,136, 20, 81, 34, 75,145, 53, 72, 49, 82,138, 84, 32, 85, 72, 29,242, + 61,114, 2, 57,135, 92, 70,186,145, 59,200, 0, 50,130,252,134,188, 71, 49,148,129,178, 81, 61,212, 12,181, 67,185,168, 55, 26, +132, 70,162, 11,208,100,116, 49,154,143, 22,160,155,208,114,180, 26, 61,140, 54,161,231,208,171,104, 15,218,143, 62, 67,199, 48, +192,232, 24, 7, 51,196,108, 48, 46,198,195, 66,177, 56, 44, 9,147, 99,203,177, 34,172, 12,171,198, 26,176, 86,172, 3,187,137, +245, 99,207,177,119, 4, 18,129, 69,192, 9, 54, 4,119, 66, 32, 97, 30, 65, 72, 88, 76, 88, 78,216, 72,168, 32, 28, 36, 52, 17, +218, 9, 55, 9, 3,132, 81,194, 39, 34,147,168, 75,180, 38,186, 17,249,196, 24, 98, 50, 49,135, 88, 72, 44, 35,214, 18,143, 19, + 47, 16,123,136, 67,196, 55, 36, 18,137, 67, 50, 39,185,144, 2, 73,177,164, 84,210, 18,210, 70,210,110, 82, 35,233, 44,169,155, + 52, 72, 26, 35,147,201,218,100,107,178, 7, 57,148, 44, 32, 43,200,133,228,157,228,195,228, 51,228, 27,228, 33,242, 91, 10,157, + 98, 64,113,164,248, 83,226, 40, 82,202,106, 74, 25,229, 16,229, 52,229, 6,101,152, 50, 65, 85,163,154, 82,221,168,161, 84, 17, + 53,143, 90, 66,173,161,182, 82,175, 81,135,168, 19, 52,117,154, 57,205,131, 22, 73, 75,165,173,162,149,211, 26,104, 23,104,247, +105,175,232,116,186, 17,221,149, 30, 78,151,208, 87,210,203,233, 71,232,151,232, 3,244,119, 12, 13,134, 21,131,199,136,103, 40, + 25,155, 24, 7, 24,103, 25,119, 24,175,152, 76,166, 25,211,139, 25,199, 84, 48, 55, 49,235,152,231,153, 15,153,111, 85, 88, 42, +182, 42,124, 21,145,202, 10,149, 74,149, 38,149, 27, 42, 47, 84,169,170,166,170,222,170, 11, 85,243, 85,203, 84,143,169, 94, 83, +125,174, 70, 85, 51, 83,227,169, 9,212,150,171, 85,170,157, 80,235, 83, 27, 83,103,169, 59,168,135,170,103,168,111, 84, 63,164, +126, 89,253,137, 6, 89,195, 76,195, 79, 67,164, 81,160,177, 95,227,188,198, 32, 11, 99, 25,179,120, 44, 33,107, 13,171,134,117, +129, 53,196, 38,177,205,217,124,118, 42,187,152,253, 29,187,139, 61,170,169,161, 57, 67, 51, 74, 51, 87,179, 82,243,148,102, 63, + 7,227,152,113,248,156,116, 78, 9,231, 40,167,151,243,126,138,222, 20,239, 41,226, 41, 27,166, 52, 76,185, 49,101, 92,107,170, +150,151,150, 88,171, 72,171, 81,171, 71,235,189, 54,174,237,167,157,166,189, 69,187, 89,251,129, 14, 65,199, 74, 39, 92, 39, 71, +103,143,206, 5,157,231, 83,217, 83,221,167, 10,167, 22, 77, 61, 58,245,174, 46,170,107,165, 27,161,187, 68,119,191,110,167,238, +152,158,190, 94,128,158, 76,111,167,222,121,189,231,250, 28,125, 47,253, 84,253,109,250,167,245, 71, 12, 88, 6,179, 12, 36, 6, +219, 12,206, 24, 60,197, 53,113,111, 60, 29, 47,199,219,241, 81, 67, 93,195, 64, 67,165, 97,149, 97,151,225,132,145,185,209, 60, +163,213, 70,141, 70, 15,140,105,198, 92,227, 36,227,109,198,109,198,163, 38, 6, 38, 33, 38, 75, 77,234, 77,238,154, 82, 77,185, +166, 41,166, 59, 76, 59, 76,199,205,204,205,162,205,214,153, 53,155, 61, 49,215, 50,231,155,231,155,215,155,223,183, 96, 90,120, + 90, 44,182,168,182,184,101, 73,178,228, 90,166, 89,238,182,188,110,133, 90, 57, 89,165, 88, 85, 90, 93,179, 70,173,157,173, 37, +214,187,173,187,167, 17,167,185, 78,147, 78,171,158,214,103,195,176,241,182,201,182,169,183, 25,176,229,216, 6,219,174,182,109, +182,125, 97,103, 98, 23,103,183,197,174,195,238,147,189,147,125,186,125,141,253, 61, 7, 13,135,217, 14,171, 29, 90, 29,126,115, +180,114, 20, 58, 86, 58,222,154,206,156,238, 63,125,197,244,150,233, 47,103, 88,207, 16,207,216, 51,227,182, 19,203, 41,196,105, +157, 83,155,211, 71,103, 23,103,185,115,131,243,136,139,137, 75,130,203, 46,151, 62, 46,155, 27,198,221,200,189,228, 74,116,245, +113, 93,225,122,210,245,157,155,179,155,194,237,168,219,175,238, 54,238,105,238,135,220,159,204, 52,159, 41,158, 89, 51,115,208, +195,200, 67,224, 81,229,209, 63, 11,159,149, 48,107,223,172,126, 79, 67, 79,129,103,181,231, 35, 47, 99, 47,145, 87,173,215,176, +183,165,119,170,247, 97,239, 23, 62,246, 62,114,159,227, 62,227, 60, 55,222, 50,222, 89, 95,204, 55,192,183,200,183,203, 79,195, +111,158, 95,133,223, 67,127, 35,255,100,255,122,255,209, 0,167,128, 37, 1,103, 3,137,129, 65,129, 91, 2,251,248,122,124, 33, +191,142, 63, 58,219,101,246,178,217,237, 65,140,160,185, 65, 21, 65,143,130,173,130,229,193,173, 33,104,200,236,144,173, 33,247, +231,152,206,145,206,105, 14,133, 80,126,232,214,208, 7, 97,230, 97,139,195,126, 12, 39,133,135,133, 87,134, 63,142,112,136, 88, + 26,209, 49,151, 53,119,209,220, 67,115,223, 68,250, 68,150, 68,222,155,103, 49, 79, 57,175, 45, 74, 53, 42, 62,170, 46,106, 60, +218, 55,186, 52,186, 63,198, 46,102, 89,204,213, 88,157, 88, 73,108, 75, 28, 57, 46, 42,174, 54,110,108,190,223,252,237,243,135, +226,157,226, 11,227,123, 23,152, 47,200, 93,112,121,161,206,194,244,133,167, 22,169, 46, 18, 44, 58,150, 64, 76,136, 78, 56,148, +240, 65, 16, 42,168, 22,140, 37,242, 19,119, 37,142, 10,121,194, 29,194,103, 34, 47,209, 54,209,136,216, 67, 92, 42, 30, 78,242, + 72, 42, 77,122,146,236,145,188, 53,121, 36,197, 51,165, 44,229,185,132, 39,169,144,188, 76, 13, 76,221,155, 58,158, 22,154,118, + 32,109, 50, 61, 58,189, 49,131,146,145,144,113, 66,170, 33, 77,147,182,103,234,103,230,102,118,203,172,101,133,178,254,197,110, +139,183, 47, 30,149, 7,201,107,179,144,172, 5, 89, 45, 10,182, 66,166,232, 84, 90, 40,215, 42, 7,178,103,101, 87,102,191,205, +137,202, 57,150,171,158, 43,205,237,204,179,202,219,144, 55,156,239,159,255,237, 18,194, 18,225,146,182,165,134, 75, 87, 45, 29, + 88,230,189,172,106, 57,178, 60,113,121,219, 10,227, 21, 5, 43,134, 86, 6,172, 60,184,138,182, 42,109,213, 79,171,237, 87,151, +174,126,189, 38,122, 77,107,129, 94,193,202,130,193,181, 1,107,235, 11, 85, 10,229,133,125,235,220,215,237, 93, 79, 88, 47, 89, +223,181, 97,250,134,157, 27, 62, 21,137,138,174, 20,219, 23,151, 21,127,216, 40,220,120,229, 27,135,111,202,191,153,220,148,180, +169,171,196,185,100,207,102,210,102,233,230,222, 45,158, 91, 14,150,170,151,230,151, 14,110, 13,217,218,180, 13,223, 86,180,237, +245,246, 69,219, 47,151,205, 40,219,187,131,182, 67,185,163,191, 60,184,188,101,167,201,206,205, 59, 63, 84,164, 84,244, 84,250, + 84, 54,238,210,221,181, 97,215,248,110,209,238, 27,123,188,246, 52,236,213,219, 91,188,247,253, 62,201,190,219, 85, 1, 85, 77, +213,102,213,101,251, 73,251,179,247, 63,174,137,170,233,248,150,251,109, 93,173, 78,109,113,237,199, 3,210, 3,253, 7, 35, 14, +182,215,185,212,213, 29,210, 61, 84, 82,143,214, 43,235, 71, 14,199, 31,190,254,157,239,119, 45, 13, 54, 13, 85,141,156,198,226, + 35,112, 68,121,228,233,247, 9,223,247, 30, 13, 58,218,118,140,123,172,225, 7,211, 31,118, 29,103, 29, 47,106, 66,154,242,154, + 70,155, 83,154,251, 91, 98, 91,186, 79,204, 62,209,214,234,222,122,252, 71,219, 31, 15,156, 52, 60, 89,121, 74,243, 84,201,105, +218,233,130,211,147,103,242,207,140,157,149,157,125,126, 46,249,220, 96,219,162,182,123,231, 99,206,223,106, 15,111,239,186, 16, +116,225,210, 69,255,139,231, 59,188, 59,206, 92,242,184,116,242,178,219,229, 19, 87,184, 87,154,175, 58, 95,109,234,116,234, 60, +254,147,211, 79,199,187,156,187,154,174,185, 92,107,185,238,122,189,181,123,102,247,233, 27,158, 55,206,221,244,189,121,241, 22, +255,214,213,158, 57, 61,221,189,243,122,111,247,197,247,245,223, 22,221,126,114, 39,253,206,203,187,217,119, 39,238,173,188, 79, +188, 95,244, 64,237, 65,217, 67,221,135,213, 63, 91,254,220,216,239,220,127,106,192,119,160,243,209,220, 71,247, 6,133,131,207, +254,145,245,143, 15, 67, 5,143,153,143,203,134, 13,134,235,158, 56, 62, 57, 57,226, 63,114,253,233,252,167, 67,207,100,207, 38, +158, 23,254,162,254,203,174, 23, 22, 47,126,248,213,235,215,206,209,152,209,161,151,242,151,147,191,109,124,165,253,234,192,235, + 25,175,219,198,194,198, 30,190,201,120, 51, 49, 94,244, 86,251,237,193,119,220,119, 29,239,163,223, 15, 79,228,124, 32,127, 40, +255,104,249,177,245, 83,208,167,251,147, 25,147,147,255, 4, 3,152,243,252, 99, 51, 45,219, 0, 0, 0, 6, 98, 75, 71, 68, 0, + 0, 0, 0, 0, 0,249, 67,187,127, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 11, 19, 0, 0, 11, 19, 1, 0,154,156, 24, 0, 0, + 0, 7,116, 73, 77, 69, 7,220, 2, 15, 16, 38, 41, 22,193,141,250, 0, 0, 32, 0, 73, 68, 65, 84,120,218,236,189,121,220,101, + 87, 85,231,253, 93,123,159, 59, 60,207, 83,115, 85,170, 50,146,137,132,132, 81, 8,208, 54, 40, 70, 9, 32, 40, 42, 72,130,208, +138, 10, 10,221, 14,221,106, 55,130,173,253,170,175,162, 4, 7,212, 87,232, 38,109,191,190,106,171, 40,210, 14,216, 56, 16, 20, + 25, 84,196,200, 76,152, 50, 48,101,170,212,252, 12,247,222,115,246, 94,239, 31,123,237,115,246,189,169, 74, 42, 69,134,170,244, + 89,245,121, 62,245, 12,247,158,123,134,189,247,111,173,223,250,173,181,161,183,222,122,235,173,183,222,122,235,173,183,222,122, +235,173,183,222,122,235,173,183,222,122,235,173,183,222,122,235,173,183,222,122,235,173,183,222,122,235,173,183,222,122,235,173, +183,222,122,235,173,183,222,122,235,173,183,222,122,235,173,183,222,122,235,173,183,222, 30, 16,243, 15,240,231,137,125,141,129, + 11,156,227, 52, 85,214,129,218,126,223, 91,111,189,245,214, 91,111,189,157, 2, 38,128,115, 78, 30,254,227, 87, 62,238,205, 31, +250,197,111,185,227, 99,191,242,188,125, 63,247,237, 79,248,211, 97,229, 46, 43, 94,211, 91,111,189,245,214, 91,111,189,157,228, +145,186, 0,195,239,123,246, 35, 94,243,139, 47,184,228, 37,123,234,141,149,211,182,172, 44,125,245,191,186,232, 17, 95,117,201, +105, 87,188,247,250,219,110, 59,176, 58,251, 52,160, 61,184,247,214, 91,111,189,245,214,219,201, 13,234, 14, 88,254,154,243,150, +190,245,153,187,155, 71,111,236,221, 79,125, 96, 31,205,198,148,139, 47, 62,119,251, 11,190,234,194,231,126,234, 75, 7,252,103, +110, 57,252, 97, 96,163, 7,246,222,122,235,173,183,222,122, 59,185, 35,245,209,251,111, 62,124,219,206,173,195,199, 62,245,194, + 45,167,107,163,132, 35,135,105,142, 28, 97,251,238,221,213,139,158,254,200,175, 9,177,185,232,189,159,184,237,131,192,190, 30, +216,123,235,173,183,222,122,235,237,228, 4,117, 0, 81,229,200,219, 63,113,232, 67,183,111,132,157,207,184,116,219,197, 99, 95, + 81,111,108, 16, 14,238,135,209, 50,207,120,234, 35, 47,125,236,185, 91, 47,255,187,143,221,114,243,234,164,185,177,127, 68,189, +245,214, 91,111,189,245,118,252,209,243, 3,253,121, 99, 96, 43,112,246, 87, 61,124,243,119,254,207, 23, 93,240, 61,231, 46, 85, +227,245,245, 26,188,199,157,121, 30,227,115,206,225,134, 91,246, 29,126,197,175,191,235,231,223,249,161, 47,189, 17, 56, 98,239, +215,147,249,102,170,234,101,192,118,251,241, 70, 17,121, 72, 59, 37,255,167, 93,111,111,189,245,214, 91, 15,234, 71, 55, 7,108, + 1,246,156,190,165,250,166, 63,248,206, 11,127,228,171, 78, 95, 57,125,178, 17,128,136,236, 57,155,165,135,157,207, 76, 35,255, +233, 55,223,247,219,255,207,159,126,244, 39,128, 47,216,249,126,217,192,174,170, 23, 0, 23, 28,231,203, 15,136,200,117,199,121, +220,119, 0, 87,216,143,175, 22,145,171, 31,226,160,254,127,212,245,246,214, 91,111,189,157,236, 86,125, 25,160, 28,129,205, 59, + 55, 13, 30,179,115,165,218, 25, 85,100,206, 83, 16, 16, 17,209,252, 27,201,191,111,255, 90, 1,203,117,208,141, 31,126,251, 29, +127,249, 43,223,114,206,183, 60,101,247,202,182, 89,173,112, 96, 31,147,229, 77, 12,118,238,225,215, 94,113,249, 75, 46,123,248, +158, 71,252,208,155,222,253,202,131,171,179,247,222, 71,192,126, 37,240,218,123, 1, 94, 0,111, 1,174, 21,145,107,250, 97,243, +144,117, 82, 60,240,175,128,175, 3,158, 4, 60, 10,216, 3,140,128,131,192,231,128,127, 4,126, 79, 68,254,225,126, 58,135, 39, + 3, 87, 1, 95, 11,156, 5,236, 4,214,237,179, 63, 2,188, 7,120,187,136,124,225,100,189,134,222,122,235,237,212,138,212, 5, +112, 43, 35,255, 21, 63,251,236,115,127,238, 69,143,219,125,249,214,165,193, 48,138, 75,128,237, 92,250, 18, 65, 42, 63,247, 51, +206, 33,222,119, 63, 75,250, 91, 68,180, 86,137,227,170,242,148,199,241, 30,135, 48, 88, 25,243,145,155,110,223,251,178,215, 95, +251,147,255,252,233,189,191, 9, 76,191, 28, 96, 87,213, 87,221, 27, 80, 95,176,107,129,171, 68,228, 64, 31,169, 63,116,174, 87, + 85,255, 43,240,124, 96,247,113,190,229, 93,192, 75, 69,228,166,251,232,243,207, 2,222, 0,124,243,113,188,252,157, 34,114,197, +201,118, 13,189,245,214,219,169, 27,169,159,246,186,231,158,255,250,239,123,202, 89, 95, 61, 91,143,104, 20,188,147, 20,192,171, +164, 47, 28, 18, 37, 65,175, 2, 78, 82,108, 31, 21, 60,136, 72,138,247, 21,188,136, 84, 78,188, 69,196, 9,212, 21, 80, 37,138, + 48, 93,159,241,216,115,119,159,246,142,159,123,254,175,127,223, 27,255,246,162,223,255,155, 79,255, 60,176,247, 62,138,218, 51, + 80, 31,203,174, 56,202,207,239, 80,213,103, 28, 13,216,123, 59,101,237,223, 30,229,119,251, 44,178, 61,104, 17,243,163,233,196, +165,151, 3,255,172,170, 95, 35, 34, 31,251, 50, 1,253, 81, 6,176,187,138, 95, 31, 2,110, 4, 14, 0,155,129,139, 73, 90,148, +147,242, 26,122,235,173,183, 83, 23,212,101, 52,112, 23,124,227,165,219,159,164,107, 53,245,100, 10, 49, 38,144,110,153,117,131, + 91,145, 14,119,189,195,237,220,109,224, 30, 17, 7, 68, 99,241, 5, 90,132,119, 49, 1,191,115, 16,108,249, 17,152, 77,107,182, + 14,135,238,247,126,244, 57, 63,252,164, 71,156,254,152, 31,251,141,247,253,232,180, 14, 31,186, 47,128, 93, 68,158,113, 15,139, +110,166,235,115, 30,254, 50,224,229, 64,159, 67,126,232,217, 39,129,223, 4,254, 92, 68, 62,177, 48, 14,118, 0,255, 17,120,149, +141,204, 29,192,219, 84,245, 82, 17,153,156, 32,160,159, 15,188,179, 0,244, 15, 2, 63,102,209,120,179,240,218, 71, 3,207, 3, +206, 63,153,174,161,183,222,122, 59,121,204,157,192,123,252,172,142,251,222,252,145,189,239, 23, 55,101,101, 24, 88, 89,130,229, +177,218, 87,236,190, 31, 69,198,110, 6,161, 70, 70,203, 9,228, 99,132, 24,105,163,114, 0,102, 16, 39, 16, 55, 64, 39,192, 52, +253,172, 51,123,189,162, 26,169, 67,164,153, 6,126,248, 91,159,116,197, 59, 94,247,173,127,114,222,158, 45,207,183,133,201,221, +159, 55, 73, 68,222, 2, 60,195,162,166,108, 87,246,195,231, 33,101,239, 7,158, 35, 34,151,138,200,235, 22,193,208,198,193,126, + 17,249,113,224, 37,197,175,207, 59, 70,132,124,188,246,223, 73, 57,111,128, 63, 0,158, 36, 34,127,181, 8,232,246,249, 31, 19, +145,159, 17,145,151,158,100,215,208, 91,111,189,157, 36,118, 34, 57,245, 1,137, 6,124,212,215, 92,184,233,249,151,158,190,116, +174,128,139,170, 49, 31, 50,106,130,236,245, 89,116,143,127,216,230, 71,126,239,211, 30,126,193,184, 26,187, 8,144,115,234, 8, + 52,235,136, 23,220, 57,143,195,157,246,112,100,203,233,200,120, 11, 52, 83,226,218, 94,244,200,173,196,189,159,134,102, 2,126, +201,114,237, 30,193, 49, 92, 25,241,233, 91,246, 29,250,250, 87,255,175,151,223,116,235,161,183, 90,180, 30,143, 51, 58,154,203, +169,139,136, 28,231,251,222,100, 17,250, 81,223,119, 34, 57,102, 85,221,110,145,127,182,235,238, 11, 90,127, 65,225,127, 66,229, +102,247,116,140,147,229,122, 23,206,243,186, 7, 34, 45,162,170,127, 9, 60,203,126,124,143,136, 60,237, 4,142,241, 34,224,247, +236,199,143, 3,143, 23,145,250,129,154,252,247,197, 53,244,214, 91,111, 39,151,157, 8,253, 30,128, 53,224,250,191,187, 97,245, +245,127,119,195,234, 18, 71,111, 98,179,243,217,143,221,253,178,231, 63,241,252, 51,150,221,208, 53, 81, 19,245, 62,153,160,211, + 53, 8,107,248,139,191,154,234,137, 47,198,159,255,149,199,164, 16,116,255,205, 52, 55,188,147,240,185,247, 33,126, 8,170,168, +192,108,125,198,197,103,238,220,250, 39, 63,253,205,111,120,250, 43,255,112,255,157,135, 38,127,195,125,151, 99, 63,150,221, 39, +117,216, 6,108, 47,183,104,255,178,163,252,253, 70,224, 26,224,154, 99, 1,148,170,190,182,120,239, 91, 68,228,154,226,184, 47, +103,161,100,207,142,121,245,241,168,247, 85,245,229, 36,122,246,130,123,123, 94,247,199,245,222,205,181,190,202,142,187,189,120, +249,181,198,170,220,223,246,103, 5, 32, 94,122,130,199,248,247,197,247,175,122, 32, 1,253, 62,188,134,222,122,235,237, 20, 7, +245, 8, 76,128,134,212, 20,198,178,222,109,212,175, 34, 60,242,234, 23, 92,252, 83,175,188,252,188,203,195, 12,102, 33,160,245, + 20,157,172, 67, 51,133, 74, 25, 61,231,199,168,158,248,162,123,166, 18,118,156,199, 96,199,203,112,167, 63,150,230, 3,191, 1, + 46, 36,200, 23, 97,182, 94,243,216,139,206,216,245,250,127,119,249,235,190,227,181,127,249,124,224,243,247, 51,168,151,224,113, + 66,209,160,170, 94, 1,252,225,194,177, 22,237, 2, 99, 18, 94,174,170, 87, 29,163, 78,254,178, 34, 74,190,214, 26,193,188,233, +104,160, 89, 28,243, 77,170,122,153,136,188,226,110,192,247, 77, 28, 59,181,144,207,235, 74, 85,125,198, 3,120,189, 71,187,214, +119,220,195, 49,239,111,219, 87,124,191,229, 4,198,193, 35,129,236,205,222, 1,252,229,169,118, 13,189,245,214,219, 67, 3,212, + 49,224,172,237,139, 2,208,253,185,187,198,207,125,211,139, 46,185,250, 89, 23,239,186,104,186, 17, 9,161,134,233, 6, 52, 53, +136, 34, 3, 24, 61,239,231,241,143,254,134,246, 96,135, 55,166,252,213,135,110,230,175, 62,124, 51,251, 87, 55, 24,120,225,210, + 51,119,240, 77, 79,124, 56, 79,184,240,140,116,224,115,158,132, 12, 55, 83,191,247,151, 96, 88,165, 83,112, 66,179, 58,229,219, +159,254,232,199,255,207,119,126,242,101,127,245,129,155, 95,195,151, 89,238,118, 15,209,230,149, 11, 17,225,189, 61,198,149, 6, +112,165, 93,103,199,202, 78, 66, 25,205, 94, 64,167,180,191,238, 30,156,141, 63, 44, 34,235,183,216,113, 51, 32,150,231,253,114, + 85,189,241, 24, 84,249,107,143, 2,232,229,177,242,185, 93,118,148,235,120,160,174,119,251, 2,160, 31, 40,206,239,130, 7,112, +238,156, 87,124,191,247, 4,222, 95, 58, 69,239, 22,145,240, 32,204,255, 47,247, 26,122,235,173,183,135, 8,168,207, 5,211, 6, +162, 91,159,253,232, 29, 63,124,205, 85,143,248,209,179, 55, 45, 45,109,172, 5, 52, 76,161,158,218, 39,121,164, 89, 99,240,212, +239,153, 3,244,127,252,204,173,188,242,119,223,195,141,119, 30, 97, 60, 26, 48,168, 28, 78,225,195, 95,216,207, 31,253,195, 39, +121,238, 19, 47,228,191, 92,249,213, 44,143, 6,184, 61,151, 80, 61,250, 42,154, 15,254, 38,108,222, 3,104, 74,162,171,240,211, + 47,121,202,247,252,245, 63,223,252, 71,170,124,140,148, 34,184,175, 1,253, 77, 11,160,113,205,189, 60,198, 5,118,140,108, 55, + 2,175, 16,145, 69,231,224,234,133,232, 54,127,246, 19,239,230,240,175, 42, 0,248, 21,139, 20,182,125,246, 31, 22,224,249, 42, + 85,157,163,186,141,114,127,249, 2,248, 94,181,144, 71, 47,207,237,138, 7,233,122, 95, 85, 28,239,213, 38, 98, 92,124, 86, 15, +132,189,160,248,254,253, 39,240,254, 39, 21,223,127,196,206,125, 39,240, 50, 59,246,133,192,178,129,237,191,144,168,242,223,185, +143, 41,250, 47,247, 26,122,235,173,183,135, 24,168,103, 64, 63,255,135,190,238,172,159,121,237,179,207,251, 55, 85,172, 88,159, +214, 16,102, 16,154,148, 71, 23, 64, 3,178,235, 28,170, 39,119,162,219,207,220,118,128,151,188,225,175,184, 99,163, 97,121,101, +137,218,123, 6, 3,207,208, 11, 94,135, 72,104,120,235,251, 63,139,119,142,159,125,241,229, 41, 98,127,248,215, 18, 62,245,151, + 16, 86,161, 90, 74,122,187, 89,205,227, 47,220,125,250,147, 47, 61,253, 89,239,255,196,109,215,147, 82, 4,199, 29,173,155,112, +238, 88,118,197, 81, 0,236,104,224,116, 79,246,166,133,232,242,137,199,202, 75,139,200,181, 70,111,231,136,244, 50, 85,125,249, + 61,228,195,175, 21,145,171,142,113,188, 27, 85,245,213,118,188, 28,237, 94, 97, 78,192, 34, 88,102,192, 60,106, 29,126,113,110, +255,252, 32, 94,239,141,199, 58,222, 3, 36,146,123,198,130,211,241,251, 39,112,152,199, 22,223,223,170,170,207, 4,126, 11, 56, +125,225,117,231,216,215, 55, 3, 63,174,170, 47, 20,145,127, 62, 73,174,161,183,222,122, 59,201,236,203, 41, 5, 19, 64,118,172, + 84, 87,188,249,187, 30,241,199,175,255,198,243,254, 13, 53, 76, 99,157,202,209, 36,192,192, 65, 37, 80, 9,202, 12,127,241,211, +144, 77, 93,127,141, 87,255,238,251,248,204, 23, 15,113,168, 17,110, 93,109,248,194,161, 25,159,189,115,131, 27,239,220,224,192, + 36,160, 85,197,214,173,155,248,147,127,250, 12,215,126,216,154, 94,249, 10,127,193,211,208,195,123,193, 59, 16, 37, 10, 12,151, +134,188,240,242, 71, 92, 65,202, 13,222, 91, 85,255,107,239,230,235,138,133,232,252, 25,247,182, 85,172,229,128,203,227,188,250, +158,192,199,232,231,107, 22,156,139,187,179, 87,220,195,241,174,165,163,169, 41, 89, 7,163,201, 75, 22,226,234,187, 59,191,163, +156,219, 3,125,189, 87, 63, 88,141,127, 84,117,235, 2, 3,241, 65,224,173, 39,112,168,157,197,247,143,179, 72, 60, 3,250, 29, +164,118,176,255, 0, 28, 94,120,102,127,167,170, 79, 57, 73,174,161,183,222,122,123, 8,128,122, 22,197,109,250,234, 11, 55,255, +200,251,190,255, 81,127,244,194, 75,119, 60,110,125, 61, 16, 8, 16,235,116, 84, 47,136, 23,164, 18,196, 59,164, 18,220,153,143, +110, 15,114,211,237, 7,249,139, 15,125, 30,150,151,186, 50, 55,239, 9, 56,142, 76, 3, 55,237, 93,231,198, 59,214,169, 85,136, +222,243,206,143,126,174, 59,129, 93, 15, 71, 55, 14, 3,141,157,141, 66, 19,185,228,236, 29, 23, 2,103,112,255,109, 84,115,165, + 69,145,247,150,226, 45, 1,234,192,189,112, 10,174, 93,248,236, 99,217,117,199, 89,178,118,221, 49,206,233,138, 5,128, 61,158, +243,123,203,131,116,189, 55, 62, 88,253,247, 85,213, 89, 52,157,155,191,204,128,151,181, 91, 28,220, 59, 43,187,195,253, 0,169, + 55,251,237,164,230, 50,167,139,200,211, 68,228, 41,192,105,192,247,147,196,169,144, 40,249, 55,171,234,150,147,224, 26,122,235, +173,183,147,204,238, 45,253,158,233,246, 51, 95,250,149,167,253,212, 27,159,123,238,247, 14,162,103,125, 22,193, 43,104, 68, 20, + 36, 10,234,197,168,247,244, 22,169,134,184,237, 15,107, 15,116,243,222,195,108,172,215,176,101,212,249, 9,121, 89,113, 14, 84, + 57,184, 90, 83,207, 26,206,222, 90,113,100,210,165, 18,101,243, 30,192,195,116, 29, 89,218,140,162,208, 52,156,191,103,243,238, +209,208,159, 62,157,133,235,239,229,117,189,250,110,254,118,129,129,212, 5, 36,106,184, 85,127,223,139,104,241,138, 99, 0, 43, +247, 20, 93,151, 77,122, 76,185,126,221, 61,128,225,221,217,141,119,115,141,247,234, 88,139,231,246, 0, 94,239,117, 15,226,124, +249, 37,230,123,179,191, 82, 68, 62,120,130,199, 26, 47,252,188, 6,124,173,136, 92,191,112, 79,102,192, 27, 85,245,115,192,159, +219,175,207, 1,254, 29, 39,214,209,240,190,188,134,222,122,235,237, 20, 6,117, 1,216, 60,246, 79,249,133,111, 56,251,117,175, +184,236,180,167,206,102, 48, 25,164,150,175, 26, 20,169, 35,195,161,227, 80, 8,113, 9,231,168,124, 91,193, 46, 0,218, 53,201, +218,189,117, 25, 63, 28, 16, 34,214, 47, 94, 13,212,237,127, 21,240,142,181,245,154,207, 77, 38,140, 30, 87,156,170, 6,208, 58, + 53,165,113, 91, 16,141,104,140,236, 88, 25, 44,111, 93, 30,110,191, 99,182,113,175, 24,136,227,108,154,242, 42, 82,222, 57, 55, + 79,121, 7,119, 47, 94, 43,173, 44, 51,187,192,154,182,156,136, 29,139, 33,248,114,169,232, 19, 2, 97,123,237,101, 15,240,245, + 62, 40,160,174,170,255, 23,240, 67,197,175,222, 32, 34,191,246,101, 28,114,157,212,211, 61,219,213,139,128,190, 48, 70,255,183, +170,190,165, 96, 48,190,251,222,130,250,253,112, 13,189,245,214,219, 41, 8,234,153,202, 30, 92,178,103,252,226,223,125,225,249, + 87, 63, 97,247,242,238,141, 89,132, 81,149, 0,189,142, 84,117,100,184,228,249,241,119,126,233,195,231,110, 27,110,251,222,203, + 78, 59,119,162, 32, 57, 90,175,107,226,157,159,197,157,147, 68,191,151,158,181,147,127,117,209,110,254,254,250,189, 80, 85, 9, +196,157,206,247,133,139,233,189,147,253,107, 92,116,122,183,190,235,225, 91, 96,122, 24,157,110, 67,108,199, 24,141,217, 41,192, +113, 63,208,239, 34,114,181, 69,145,185, 19,221,241,136,215,142, 6, 78,247,102, 47,247, 7,195, 14,220, 7,175, 61,149,174,247, +120,192,240, 63, 1, 63, 93,252,234,119,129, 31,252, 50, 15,187,186, 0,234,191,125, 28,239,249,173, 2,212, 31,161,170,187, 69, +228,142, 7,241, 26,122,235,173,183, 83, 12,212, 51,221,190,251,170,175,216,241,202, 95,125,206,217,255,254,244,241, 96,184, 30, + 5, 89, 78, 33,184,206, 34,227,168, 76,134,240,131,111,251,220,219,174,121,223, 29,127,252, 63,174, 58,239, 71, 69,141,121,247, +166,126,175, 28,122,123,183, 17,148,115,194, 79, 60,239,137, 60,231, 19,127, 14,147, 26, 70, 67,219,221,205, 64, 61, 2, 26, 97, +117,157,199, 63,242, 44,190,227,107, 30,213,190, 55,222,113, 61,170, 53, 18,102,233,133,170, 56, 81,246,175, 78, 54, 14,175,207, +142,220, 95, 55,203,128,189,220,178,245, 74,238,101,105, 27,137, 2, 63,209,206,116,167,226,174,112,167,244,245,170,234, 15, 0, +191, 80,252,234,143,129,239,186, 15,114,208,119,146,244, 31, 0,251, 68,228,115,199,201,140,176,224, 48,221,241, 32, 94, 67,111, +189,245,118, 10,129,186, 0, 82,121,185,248, 53, 95,127,230,175,190,242, 95,159,254,172,166,129,245,202, 33, 35,135, 70, 69, 55, + 2, 43,149,112,243,180,153,124,247,255,188,233, 55,222,245,233,195,191, 11,196,207, 31,170,111, 71,244, 18,109, 35,117, 96,188, + 76,184,249,189, 84, 7,110, 70,182,159, 7,192,179, 31,127, 30,215,252,187,175,229,135,254,199,123, 88, 63, 56,133,241, 40, 41, +218, 85, 97, 86,195,250, 6, 79,184,100, 15,127,244,202,111, 96,101, 60, 72,103, 85,111, 16, 62,241, 86,100, 56, 74, 10,123,141, +104, 12,224, 28, 55,220,118,112,239,100, 22,246,114,255, 9,229, 32,229,156, 51, 93,125,197, 9,188,255,154,135,250, 62,235, 15, +149,235,181,218,253,146,158,254,107,224,219,142,182,217,202, 9,216, 39,129,199,100, 80, 63,206,247,236,187, 27, 70,228,193,184, +134,222,122,235,237, 36, 51,119, 15,160,190,251,181,207, 57,235, 13, 63,250,212,211,159, 53,105,160, 94,174,144, 37,143, 70, 96, + 61,176, 50,246,252,237, 45,107,183, 95,254,198, 79,254,228,187, 62,125,248,191, 2, 55, 3, 95,250,212,157,147, 79,225, 4,130, + 5, 2,222, 37,138,189, 89,165,126,239,235,231, 62,228,123,159,254, 40,254,225,231, 95,192, 15,125,227, 99, 56,127,199,136,177, +214,108,114,129,167, 92,180,139, 95,255,190,175,227,221,175,185,146,243,247,116, 66,225,230, 3,191,129, 30,188, 25, 6, 35,212, + 68,120, 52, 1,156,240,169, 47, 30,248, 28,169, 89, 71, 60,201,238,243,177, 84,231,167,250,249, 93,113,138, 94,239,241, 0,250, +119, 3,255,173,112, 16,223, 13,124,139, 9,215,238, 11,251,120,241,253,232, 56,223,179, 40,174,155, 60,200,215,208, 91,111,189, +157, 66,145, 58,231,108, 31, 94,254,221,143,217,241,244,217, 36,194,166, 1, 50, 20,116,166,248, 73,195,104,197,243, 59, 31,222, +247,201, 31,248,163,155,127,225,240, 70,120,143, 69, 17,107,192,248,221, 55, 28,249,167, 91,143,212, 47,221,181, 60,168,130,106, + 87, 4,183,180, 76,252,252,187,105,222,247, 43, 84, 79,237,244, 58,143, 61,119, 23,175,127,233,211,248,249,239,104,184,109,255, + 26,195, 65,197,153, 59, 86,238,114, 62,225, 19,127, 74,243,145,223,129,241,114,242, 58,156, 71, 67, 68, 66,164,158, 76,121,235, +123,110,120, 31,169, 31,253,253, 9,234, 39,146, 31, 46, 5,101, 87,168,234,246, 7,171,206,250, 24,118, 99,113,126,151, 29, 39, +232, 93,118, 10, 95,239, 61, 93,219,139,129,223, 40,192,240,253,192, 55,138,200,198,125,248, 49,239, 46,190, 63, 83, 85,199,199, +177,159,249,226, 62,234,183, 63,200,215,208, 91,111,189,157, 66,145,122,117,222,142,209, 69,219, 71,158, 38, 38,117,187,174, 7, +134,179,128,140,132, 87,254,213, 23,174,125,201,239,220,240, 31, 15,111,132,119,218,226,114,136, 84,243, 90,223,114,112,246, 79, +111,189,254,192,135, 6, 21,232, 36, 0,138, 56, 82,189,250,242,102,194, 71,126,155,250,218,159, 64,215,239,156, 15, 67, 6, 21, +231,237,217,122, 87, 64,175, 55, 8,239,127, 35,205,123, 94,131,140,134,136,247, 41, 95, 63, 24, 65,221, 48,112,240,143,159,186, +245,182,191,255,196,237,215,146,122,191,223, 47,160,190,176,197,231, 98, 68,122,119,182, 88, 38,246,242,147,108, 28,148,231,183, +221,218,182,158,104,148,126, 42, 92,239,221, 61,227,111, 37,137,214,242,220,248, 32,240,245, 34,114, 95,107, 53,222, 77, 71,167, + 15,128,203,143,227, 61,207, 42,190, 63, 72,162,240, 31,204,107,232,173,183,222, 78, 33, 80,247,159,184,125,227,211, 95,156,133, +102,121,217,179, 92, 7,150, 61,172,250,168,223,254,135, 55,254,254, 47,190,227,214,159, 2, 62, 76, 18,252,172,145,250,173,231, +141, 94,110,255,213,191,187,253, 45,135,234, 64, 85, 7,168,163,237,133, 78, 18,206,173,108, 38,222,240, 23,204,222,250, 18,194, +199,223,138, 30,254,210,209, 23,216,181,189,196, 27,174,101,246,199, 47,165,249,224,127,135,241, 24,124,149,154,205,136, 32,110, +128, 76,106,240,202,207,190,249,131,127, 12,124,214, 62,255, 62, 7,117,107, 56,179,184, 57,201, 91,142,231,189,214,159,188, 20, +139,189,234, 30, 34,221, 7,218,222,194,188, 40,237, 85,199,113, 47, 94,117, 10, 95,239,177,174,235,185,164,118,169,121, 43,225, +143, 3,207, 20,145,131,247,245,103,217, 6, 46,165,226,253,199, 84, 85,238,230,220, 54, 51,175, 86,127,187,136,196, 7,243, 26, +122,235,173,183,147,207,238,150,126,223,183,218,124,224,133,191,127,211,213, 63,244,180, 61, 87,238, 92,174,182, 94,127,231,228, +139,255,237,189,119,188,237,227,183,172,255, 25,112,171, 69, 11,179, 5, 16, 13,192,198,103,247, 78,254,226, 53,127,115,219, 21, +175,251,134,115,158,209,172, 54, 80, 57,100,228, 59, 50,112,121, 11, 52,135,168,223,251,115,200,112, 19,178,243, 18,220,142, 11, +161, 26, 67,172,137, 7, 63,143,238,253, 56, 76, 14,194, 96, 0, 43, 69, 3, 46, 5,162, 67,167,194,112,147,227,183,174,253,212, + 39,254,250, 95,190,244,251, 36,234,253, 62,221,147,218,162,243, 43,184,235,254,226, 7,184,119,202,247, 87, 48,223,123,253, 29, +182,205,232,181,199,241,249, 87, 26, 16,220, 47,130, 51, 17, 57,160,170, 87,211,149,235, 93,161,170,111, 58,218, 22,173, 6,232, +199,179,237,233, 73,123,189,199,248,220,103,154,115, 99,138, 76, 62, 13, 92, 33, 34,119,126, 25,199, 44,213,229,207, 19,145, 63, + 89,120,201,207, 3,223, 67, 42,109,123, 26,240,122, 85,253,145, 69,176, 86,213,101,224,205,164,166, 51,216,124,187,250,129,184, +134,222,122,235,237,161, 3,234, 53,176,255, 31,110, 60,242,255,254,195,141, 71,222, 97, 11,207, 62,224, 54, 18,213,190,106,175, + 89, 44,139,201,251,173,223,246, 75,239,188,245,245,143, 63,103,249,252, 23, 61,110,231,195, 55, 14,207,144, 45, 67, 24,185,212, +105, 14,133,193, 0, 25, 12,146,130,125,223,135,105,238,184,174, 61,156,184, 10,170, 33,172,108, 90, 88,185,128, 89, 64,227, 18, +227,209,144,235, 62,115,251,129,255,240,223,223,255, 58,139,210, 55, 56,129, 29,218,244,110, 90,163,221, 29,104,221,155, 60,177, +117, 75,123, 5, 93,207,237, 12,116,215,146,232,234,197,190,236,217,153,200, 17,238,171,239,231,177,112, 13,243,219,160,190,220, +104,248,107,138,115,187,130, 68,165,111,183, 72,252, 0,199,200,193,159, 2,215,187,104,127,194,188, 96,109, 29,248,255,142,119, +104,136,200,215,159,128, 51,181,215,202,205,126,203,126,245, 31,128,167,169,234,111, 0,215,219,252,124, 2,169,123,220,185,197, + 91,255,111, 17,249,200,201,112, 13,189,245,214,219,169, 3,234,193,128,187, 49, 16,119,246,187,169,125, 5,142,189, 19, 90, 3, +172, 70,213,143,254,219, 55,223,244,179, 59, 87,170,215, 60,243,225, 91,207,154, 28,154,193,230, 1, 50,246, 93,253,122, 66,112, + 24,142,239,190, 14, 77,129,168, 48, 13,196,195, 51,150,206,216,195,245,183, 30, 88,189,234,234,191,187,250,208, 90,253,158,194, +201,184,191,237, 58, 3,244,123,221,217, 76, 68,174, 41, 26,216,108, 47,128,242, 65, 87,136, 91,180,126,149, 69,215, 23, 20, 96, +251,218,163,188,252, 0,112,213, 49,254,118, 74, 92,239, 81,108,105,225,231,175,120,128,238,251,111,171,234, 25,192,207,217, 28, +123, 60,240,134,187,121,203,175, 0, 63,115, 50, 93, 67,111,189,245,118,242,152,187, 7, 24,109, 72,249,242, 3,192,126, 18,221, +190,110,191,215,123,120,239, 20, 56,116,120, 35,188,235,121,215,124,250, 63,255,206, 7,247,125,114, 60,116, 12, 14,215,196, 67, + 53, 76, 98,123, 20, 65, 16, 57,202,151,253, 35, 0,179,136, 30,110,144, 3, 83,150,182,111,227, 93, 55, 30,186,237, 89, 63,121, +237, 79,222,120,251,234,255,178,115, 91,231,254, 83,189, 95,107, 17,235, 85, 34,242,196, 19, 1,244, 18,232, 72,237,101,175,225, +248,154,171,188,133, 68,101,223,239,155,152,216,166, 48, 79,188,135,207,186,150,180,237,233,117,167,250,245,158, 44,102,105,134, +203,129,127,186,155,151,125, 4,248, 38, 17,249,225,163,229,210,123,235,173,183,222,224,254,109,210, 2, 73,172,179,108, 81,218, +163,190,251, 41,187,191,231,103,158,125,214, 55,157,181,117, 88, 53, 83,165,169, 4,198, 30,169, 92,138,220, 93,113, 58,170, 16, + 64,155, 8,147,128,175, 35,131,129,112, 56,192,207,189,103,255,223,254,242,219,110,120, 83, 29,226, 7,232, 74,233, 78,201,102, + 26, 70,113, 47, 82,216, 55,146,118, 55,187,246, 65, 60,175, 76,135,151,123,162, 95,123,156,187,193,157,114,215,123, 18,141,135, +139,128, 39, 1,103,218,252,188, 13,248, 71, 17,249, 76,191, 92,245,214, 91,111, 15, 54,168,103, 96, 31,147,182,154, 60,253, 97, + 59, 70, 95,247,242,175,222,253, 45,223,121,217,174, 39,159,189,121, 48, 64, 5, 85, 37,138, 16,139,179,113, 10, 78, 53,149,174, + 9,236,155,132,248, 7, 31,222,255,209, 55,189,239,142,183,125,228, 11,107,111, 7,190,104,204,193,198,169, 10,232,189,245,214, + 91,111,189,245,118,170,129,122,254,156, 33,176, 2,108, 1, 78,223,177,169,250,138, 39,159,183,233,201, 47,120,220,142, 39, 61, +238,172,229, 51,182,143,252,202, 74, 37,195,202,137,107, 34,186, 30,226,236,208, 44,174,127,230,142,141,189,111,249,208,254,127, +249,251, 27, 87,255,233,150,131,179,235,128, 47, 1,135, 73, 57,244,251,173, 38,189,183,222,122,235,173,183,222,122, 80,191,251, +207,114, 36,117,238,178,125,109, 6,118, 0,123,150, 71,110,231,184,114, 91, 6, 94,134, 77,212,102,210,232,145,245,105,216,167, +202, 29, 36,138,253, 48, 41,111,190,198, 61, 11,245,122,235,173,183,222,122,235,173, 7,245, 7, 16,220, 7, 22,189,231,175,138, +174, 97, 6, 22,129,215,246, 53, 51, 32,111,122, 48,239,173,183,222,122,235,173,183,147, 7,212, 23, 63, 63,131,124,254,191, 4, +117, 45,254,239,129,188,183,222,122,235,173,183,222, 78, 98, 80,191,187,243,233, 65,188,183,222,122,235,173,183,222,122,235,173, +183,222,122,235,173,183,222,122,235,173,183,222,122,235,173,183,222,122,235,173,183,222,122,235,173,183,222,122,235,173,183,222, +122,235,173,183,222,122,235,173,183,222,122,235,173,183,222,122,235,173,183,222,122,235,173,183,222,122,235,173,183,222,122,235, +173,183,222,122,235,173,183,222,122,235,237,126, 50,185,236,180, 93,170,128, 56, 16, 60, 14,240,206, 33, 78, 82, 39, 24,201,173, +222, 28, 34,224, 36,245,135,241,222,225,108, 31,116,239, 82, 35, 56, 5,188, 19,196, 9,131,252,122, 0, 17,236,109,120, 71,251, + 62, 39,224, 17,162,166, 93, 87,157, 19,124,126, 33,138, 23,193,171, 18, 81,156,203,251,174, 87,136, 6, 28,130, 31, 8, 62, 4, + 70, 78,240, 40, 30, 80,167, 16, 97,136, 50, 85, 37,160,108, 21, 88,169, 28,195, 42,245,163,165,242, 92, 60,155,240,132, 11, 4, +249,198, 11,224, 43,214,144, 29,207,131,241, 51, 96,184, 2,178, 9,100, 37, 93,188,206, 64, 87,161,190, 29,142,188, 14,253,244, + 77,240,143, 99,226, 71,239, 96,114,243, 97, 14, 15,132,102,101,204,157,107,240,169, 53,144, 8, 91, 6,176,105,224,112, 46, 82, + 71, 88,171,133,105,128,129,128,162, 4, 32, 58, 65, 67, 32, 70,104, 52,221, 59, 81,235,190,163,160, 2, 66,218,165, 78, 28,169, + 57,110,126,104,154,254,182,216, 83,183,253,187,245,237,145,246,169,104,123,255,219,215,216,126,245,115,191, 3, 84, 28, 98, 71, + 83,181, 70,126, 66,219, 10, 72, 36,245,242,245,214, 11, 80, 4, 42, 15, 81, 29, 81, 99,215, 49, 72, 23,143,156,118,211,109,255, +164,224,237, 69, 51,210, 56,113, 2, 3, 7,227, 42, 29,171,137, 16, 3, 72, 37, 12, 61,108, 95,169,216,188,175,230,172, 93, 75, + 84,223,117, 22, 60, 50,192,142,139, 96,211, 85, 48,126,108,250,128,250, 19,176,246,103, 48,109, 64, 46,128,112,115, 58,250, 48, +192,182, 43, 97,240,104, 82, 71,226, 85, 88,127, 39,124,238,191,193, 39, 60,251,174,190,137, 27, 42,229,208,192, 81, 7, 88,118, +214,203, 88, 32,186,244, 92,163,192, 76, 29,177, 14,204, 80, 98,128,105,132,160, 16, 4, 66, 80,102, 81, 17, 32,106,250,125,190, +110, 5,156, 83,198,164,107,209,152,126, 31, 21, 26,148,202,158,231, 84, 96, 26,210, 51, 70,211,120, 73,131, 99,126,140, 84, 54, +142, 28,218,182, 98,172, 28, 12, 68, 24, 58,216,228, 97,164,202, 29,181,114,103,147, 78, 98,164, 80, 9,172, 6,216, 80,109,231, +221, 88, 96, 87, 5, 35,129, 89,132,101,129,109, 14,238, 12,202,135,167,112, 48, 40,162,202, 52, 20,231,148,199, 93,241,115,110, +255, 88, 14,153,114, 24,196,252,224, 17, 68,180, 29,125,206,190,198,164,243,139,105, 10, 19,237,218,134,164,251,155,199,123, 69, +234, 49,173, 54,130, 29,202,200,254, 94,147,238,187, 22,195, 48,146,174,119, 18,187,115,245,246,229,138,249,147,223,211,144,239, +143,180, 45, 47, 21,165, 18, 88,178,175,129, 77, 73, 87,206, 51, 73,107,219, 80, 96, 69,210, 39,205, 20,234,252,252,237, 61,209, +198,132,147,180, 17,198, 72, 28, 94,210,239, 39,170, 76,219,215,203,220,156,174,128,136, 16,236,247,145,124,108,101,136,176,221, + 41, 75,192,134,194,106, 76,115,113, 93,149,219,163,114, 32,166,223, 47,139,112,182, 75,235,239, 94, 85, 86, 53,125,102, 19,243, +241,148, 90,161, 70,105,138, 49,156,103,177,179,103,148,231,171,144,215,175,180, 80, 69,164,125, 6, 51,148,105, 84,136, 17,161, +235,239, 93,142,137, 60, 36,212,174, 81,224, 46,227, 34,127,137, 20,231,144, 23,163, 98,237,155, 91, 95, 22,142,131,192,192,121, +156,147, 22,195, 70, 26,113,162,108, 68,152,218,170,231,129, 74,187, 57,165,118,222, 1,233,182, 2, 21,193, 11, 12, 92,197,168, +170, 24,120, 79,227, 61,235,245,140,122, 54, 67, 99, 64, 5,230, 27,164,118,239,165, 56,175,104, 63,167,239,243,249,187,118, 13, +135,132,185,222, 87, 68,160, 81,197,197,200,226,162,172,237,189, 77,227, 20, 85, 69, 52, 29, 72,109, 11, 84, 81,219,226, 92,139, +187, 99,223, 56, 17, 68,237,160, 78,218, 1,235,178, 23,160, 66,144,180, 72, 57,215,157,158, 72,247,254,116,234,206, 62, 43,218, +244,180,133, 6, 1,231,210, 77,117,180,206,133, 83, 69,109, 53, 20,177,197, 33,223, 16,192,185,118,229, 64,129, 74, 4,111, 94, +137,243, 48,208, 4,144, 3, 34, 1, 73,103, 16, 3, 90, 76,205,110,186,147, 30,167, 12, 64, 54, 67,165, 48,126, 1,114,246, 47, +161,151, 68,220,193,237,140,238,156,178,114,100,131,189,190,225,112, 28,224,156, 50,240,201,121, 24,136,226,241, 68,133,202,219, + 57, 69, 5, 17, 6,164,133, 60, 22,231,174, 24,144,219,205,116,206,208,132,136,196, 60,197, 99, 58, 51,129,136, 75,131,217, 97, +175, 41, 39, 95, 66,128,202, 29,107, 11, 59,215, 78,160,114, 2, 36,160, 79,231, 40,136, 57, 22,121,193,138,243,147,206, 0, 61, +109,141,235, 24, 58,101,214,164,201,157, 23,210, 60,233,165,123, 44, 54, 86,180, 3,128,242,243, 21,115,222, 34,106,231,226,134, +130, 87, 24, 58,112,123, 39,236,172, 61,213,183,236,129,199, 4,216,122, 38, 44, 93, 1,163, 75,210, 50, 31,111,129,141, 15,193, +250, 45, 32,231,147,118,230, 5,164, 2,105,138,229, 33,164,101,193,237,132,241, 18,108,153, 49, 64, 88, 82, 69, 42, 24, 84,224, +196, 17, 52, 18, 98, 2, 58,196,158, 31,218, 62,180,236,103,229,169, 32, 2, 35, 73,139, 67, 99, 99,185,156, 62, 18,211,177,199, + 62, 57, 50,117, 76,227,219,197,244,158, 1,105, 81,198,165,191, 57,233, 6,197,220,115,178,181, 97,104,192,224, 13, 76, 42,215, + 57,132,211, 38,237,124,180, 63,164, 5, 54,131,144, 23, 24,219,235,130,129,231,192,198,221,192, 9, 42,105, 54,228,215, 45, 11, + 28,178, 25, 49, 20, 3, 37,251,140,202,156,153,238,153, 43,206,238, 67, 67, 90, 59,202, 5,220,139,206,129, 67, 40,158,200,178, + 36, 80,143, 6,110, 83, 45,150, 29, 77,159,237,153,239, 29,157,207, 91,165,115,192, 26,187,166,198, 0,222,171, 50, 64,216,148, +150, 20, 54, 52,189, 70, 10, 80,145,226,222, 6, 32,168,166,177,216,190, 70,147, 19, 75,218,128, 2, 77,199, 31, 73,186,255,106, + 7, 25,230,115,162, 3,241, 65, 1, 42,106,159, 91,231,207, 85, 69,196, 17, 36,129,115,176,187,181,100, 19, 76,237, 94, 52, 10, +162, 9,136, 43, 3,180, 96,231, 80, 9, 8,142,101,129, 37, 17, 20,101,162,145,198,230, 83, 0,106, 21, 14, 3, 51, 85, 60,202, + 70, 84, 84,160, 65,136, 54,162,156,164,135, 53, 18, 97, 44, 74,208,132, 3,141, 57,143,216,243,172,138,235,105,180,187,150,228, +128, 69, 60, 14, 17,161, 22, 80, 21,162,179,207,137, 58,119,159, 99, 17,160,116,200,210, 61,149,242,181,249,222, 75,225,212, 57, +145,185, 77, 64, 90, 80, 84,230, 28, 3,230, 86,245,136,199, 83, 1,155,156, 48,148,138,195, 54, 94,199,121, 12,199,128, 67, 65, +149,218,214,232, 88, 2,122,123,254, 66,144, 52,143, 91,108,243, 3,130, 11,136,166, 59,226,142,178,198,249, 34, 62,139,249,170, +139, 49,172,133, 91,226,128,177,243, 44, 47, 47,227, 70, 99,234,160,204, 66, 77,168,107, 66,140, 52, 33,164,232,160,112,145, 68, +161,138,237, 66, 33,173, 71, 40,154,135,178,164, 69, 7,105,189, 36,177, 40, 27,115, 0,164, 13,187,156, 69,245, 98,139,185,189, + 63,135, 23,237, 49, 12,204,180, 59,249,204, 10,136,218,205, 17,177,133, 95,108, 48,119,222,178, 35,180,171,154,152,135,216,104, +158,116, 58, 7, 16,222,188, 37,181,133,111,232, 34, 34, 46,121, 50, 2,113, 45,224,107,187, 41, 98,199,197,131,248, 98,184,196, + 52,140,252,102, 24, 61, 1, 54,127, 29,114,209,219,209,195,219,112,251,182, 48,254,212, 12, 38, 13,181,171, 24, 8,108,114,145, + 37,192,139,208,152, 71,229, 21,212, 67, 84, 37,218,125,112, 34, 56,169,168,189,226, 66, 36,154,119,136, 43, 34,118, 27,220, 62, + 33, 10,209,158, 79,200,215,234,238, 58,136,219,255,157,177, 31,230, 32,229,209, 21, 53,226,237, 25, 32,221,164,202, 32,221, 29, + 36, 13, 74,113,198, 20,196, 4, 74,190, 93,196, 28, 34, 49,129,138, 70,212,238,119,142,212, 18, 56, 59,134, 30, 26, 34, 46, 64, +140,218,122,230,184, 52,144, 99, 72, 3, 93,204, 9,112,146,198,128,139, 9, 48, 6,164,232,125,115,173,156,113, 40,176,233,249, +103,194, 83,129,173,123, 96,252, 20, 88,186, 12,220,102,208,195, 48,253, 16,172,127, 18,166,147,132, 16, 58, 3,183, 12,126, 25, + 6,203, 32,203, 54,173,166,246, 76,183,193,210, 54,216,117, 59,195,229, 1,123,102,235,204,150, 29,179, 0,235,117,100, 18, 32, + 24,120,103, 70, 37,196, 4,244, 33, 58, 52, 51, 19, 58,207,152, 68,187,137, 78,230,129, 61, 47,232, 85,147,174,221,107,154, 7, +193,165,215, 52, 81, 24, 59,101, 57,194,204,117,142, 80,158,163,217,113,136, 54,126, 70,249,158, 21,127,247, 46,157,235,106,132, +181, 90,187, 69,199, 94, 27,237, 57,143,108,236,212,161, 3,193, 28,169, 4,151, 22,171, 1, 9,216,110, 13, 65, 13, 0, 0, 32, + 0, 73, 68, 65, 84, 43, 1,167,233,122,102,115, 32, 93, 70,235,105,177,109,138,107,141,210,177, 20, 57,174,174,200, 44, 83,199, +174, 5,123,223,212, 0, 44, 59, 0,211,194,241,240,154, 64,116, 84, 56,149,100,167, 66,161,145, 14,112, 92,187, 6, 40, 51,133, + 41,202, 8, 88, 17, 88, 66, 88,151, 20,141,182,247, 83,187, 8, 50, 44, 68,148, 33, 3,140,118,247,186,124,206,121,157, 89, 18, +216, 36,146,152, 16,133,117, 77, 78,151, 20, 14, 94,158,203, 30,152,153, 51, 84, 91, 52, 95, 58, 59, 67, 18, 83, 20,237,158,172, + 27,224,136, 8, 67,187,155,181,157, 55,118, 95,182,122, 71,133,178, 30,148, 96, 75,195, 58,112, 40, 10, 19,251,124,204, 89,186, +131,116,110,209,220,177,236,148,169, 64, 84,105, 29, 85, 81,101,217,214,250,166, 24,135,195, 5, 86, 35,154,147,225, 84,113,162, +157,147,105, 78,206,196, 57, 26, 18, 43, 25, 11, 71, 42,127,102, 11,108, 5, 22, 57, 41,162,236,133,144, 75,237,115, 97,158, 17, +114,204,163,185,204,133, 49,105, 77,246, 34, 44, 9,140, 69, 88, 5, 38,230, 60,165, 64, 85, 17, 39,104, 84, 84, 59, 64,159,139, +139,165,163, 12,242,216,142, 22, 68, 69,186,193, 41,234,138,160,136,121,224, 45, 93, 74,157,103, 50,165,192, 78, 15, 12,125,133, + 27,140,136, 49, 82, 57, 7,126, 68, 13, 56,141, 72,240, 52,245, 12,140,149,201, 8, 94, 73, 62, 82, 11, 6, 29,233, 35, 70, 23, + 43, 98, 19, 37, 17, 3,233, 14, 10, 34, 41,226, 75,236,123,114, 55,196, 37,170,206, 25, 37,159,192, 74, 18,230,171, 38,208, 54, +207, 36,104, 76,224,134,107,207, 33, 15,108,143,162, 6,246, 94, 44,142,183,155, 46,133,135,227,236,116, 84,211, 93, 21, 39,184, +168,105, 80, 8,204, 52, 34,234,104, 66, 36, 0,163, 33, 12,124,132,224,136,107,147,196,159,102, 36,109,151,181, 50,162,163,139, +236, 6, 59, 96,211,139, 33,126, 14,185,248,227,112,235, 38,170,189,107,108,254,194, 42,131, 81,205,166,225,144, 97, 52,170,187, +136, 82, 43,187, 61,181, 72,235,237, 2,212, 26, 91,146, 77,132, 20,198,133,136,132, 8, 81,169,156, 35,198,216, 69,228, 2, 33, + 96, 76, 5,109,116,158, 28,161,244, 88, 93,177,224,198,121,222,179, 29,233,145, 69, 0,119, 93, 40,217, 78, 2,181,129, 14, 18, +204, 55, 21,240,226, 16,151,134,123, 57,216, 69, 36, 57, 18,193,174,221, 39, 6,166,202, 3, 95,192,121, 65, 85,237,245,142, 58, + 68, 99,110,186,153, 87,217, 98,130, 64,133, 48, 18,216,236,148, 93,119,204,216,122,217, 14,120,233, 16,182,157, 13,163,231,192, +248, 9,224, 79, 79, 80, 57,187, 17, 86,255, 9, 38,251,147,167, 16,107,155, 33,219,192, 85, 9,220,197,205, 47, 1,126, 59,140, +118,192,150,219,169,182, 13,217,186, 62, 97,125,160, 76,106, 97,221,168,245,236, 96, 69,163,171,243, 68,110,136,115, 52, 71,122, +157,125, 19,211,152, 47, 41,188, 28,107,199,152, 22,100,209, 14, 0, 7,230,236, 4,187, 23,227, 10,124, 20,154,168,212,230,236, +249, 60,225,205,225,117,146, 35,186,110,133,205,167, 51, 85,152,198,152,156, 34,205, 35, 90,168, 68, 25,155,227,148, 1,211,134, + 19, 83,133, 42,106, 98, 69,128,245,144,206,125, 11,176,226,146,147,144,253,200,188, 64,184, 12, 90, 54, 7, 51,112,197,133, 5, +183,164, 90, 27, 59,151, 96,224,144, 23,249, 90,231, 29,130,146,201,201, 79,172, 46,162,223, 80,240,235, 82,208,175,195,246, 51, + 58,208, 9,230, 44, 52,154,128,125, 51, 48,201, 81,150,205,211, 90,139,221,163,180, 59,215, 88,210,176,246,252,189, 43,159,107, + 74,245,173, 24,224,175,197, 68,121,207,232, 28, 35,236,220, 59, 96,207,169, 53,153, 75,163, 5, 59,199, 13, 99,133,198, 22, 36, +169,118, 84,120, 14,128, 26, 77,115, 52, 81,253, 48,176, 52,101,142,246, 55, 20, 14, 42,236,183,239, 7, 70,245,214, 10,107,182, +126,108,146,148,198,153,229, 96, 3,193,139,182,142, 57, 34, 4,115,192, 42,160, 54,103,104,163, 24, 59,161, 24,123,129, 60,231, + 93,139, 25, 67,115,110,107,113,212, 46, 57,255, 65, 59,167,168,100,245, 88, 96,163, 50,205, 94,178, 41, 81,230,157,228, 98,105, + 76, 1, 71, 1,254, 37, 53, 95, 89,170,119, 44, 48,114, 9,208, 55, 16,162,116,243,116, 36,137,101,216, 0, 38,182,238,106,166, +183,219,220, 87,183,112,230,111, 27,148, 24, 26, 52,198,196, 78,101, 86, 70,239,194,184,183,209, 57, 28, 13,240,101, 46, 56, 19, + 28,181, 0,205,140,161,171, 24, 12, 61,222,251,196, 88,169, 50,211,136,162,196,186, 78, 44,182, 57,103, 85,233,253,228,153,145, +105,114,140,134,202, 51,121,145,118,117, 54,163,180,205,121,100, 34, 91,230, 40, 93,231,186,139,203, 78, 68, 75,247,138,180,224, +157,239,153,119,201, 99,116, 46,141,154,104, 81,130, 20,185,123,215,185, 53,237,194,155, 40,119,135,151,148, 43, 25,186, 20,128, + 55,196,228,113,169, 34,150,219,198, 59,130, 42,172,213, 72,227, 33,206,204, 61, 21,208,169, 1, 92,181,176,180, 12, 97,112, 38, +172,252, 32,156,253,147,112,217, 94,228,200, 78,182,220,182,193,174,245, 25,119,110,246, 12,156,183, 72, 56, 45,236,138, 18, 37, +233, 6, 90,180, 39, 22,212, 81,108,239, 81,212,128,134,142,122,137, 26,237, 94,217, 42, 18, 99,231, 44,104,231,222, 75,155, 51, +207, 83, 41,182,209,226, 92, 4,142,182,212,144, 55,250, 62, 77,144,208, 29,215,242, 51, 30, 73,192, 28, 19, 29,158, 39,140, 72, +196, 57, 71,140, 57,221,145,216, 15,103, 90, 6,181, 8,195, 41, 12,109, 96,121,213, 54,234,143, 33, 13,184, 38,216, 34, 39, 93, +228, 53,176,232,222,161,233, 25, 57,216,132,178,235, 64,205,182, 51,151,113, 63,189, 27,118,157, 15,195, 23,193,232, 49, 41, 45, +130, 66,216, 11,147, 15,192,198, 29, 48, 91, 55, 26, 32,130,140,192,173, 44,196, 95, 5, 76,184, 61,176,244, 66,216,118, 13,114, +254, 1,248,176,167,158, 42,235, 33, 69,176,190,160,100, 23,193,169, 90,136, 68,195, 28,252, 24,195, 17, 22, 83, 95, 50, 15,126, +246,127, 48, 71, 43, 42, 52, 17,182, 84, 48, 26,192,122, 16,134,209,232,109, 3,247, 68,177, 11, 99, 20,231,211, 34,225, 84,209, +144,162, 58, 53,154,115, 32, 66, 20,157, 75,129, 12, 93,202,247, 86,162,212, 77, 90,156,113, 41,189,160, 49, 13,175, 97,118,134, + 73, 57,244, 32,176, 25,161,118,202,186,118,115,173,140,144,114,110, 94,138, 84,196,188, 80,131, 57,178, 59,211,146,181,148, 26, +129,238, 94,138,116,121,241, 18,220,109,136, 49, 43, 86,195,234, 40,121,241,146, 61, 41,211, 63, 27, 36,176, 93, 49, 29,193,192, + 34,225,104,128,144, 29,156,166,252,204, 5,112, 8, 22, 89,139,165, 31, 42, 27,188,171, 6,200, 13, 41, 82,206,251, 69, 7,186, +207,106, 36, 81,251,217,185, 79,243, 34, 57,174, 10, 76,236,164,167,118, 44,117,194,192, 64,191,182,200,186,142,210,134, 27, 3, + 18,115, 81, 17, 9,154,158,207, 17, 21, 99, 39, 36,233, 8, 52,209,223, 57, 39,159, 89,145,153,129, 50, 45,251,145,214,172,136, +165, 61,165, 99, 22, 70,118, 94,119,198,196, 66, 76, 99, 58, 31, 41,243,225,118, 13, 30, 24, 69,165,114, 90,168,123, 82, 36, 60, +192, 37,214,110, 65,103,145,103,167, 44, 12,155, 57, 64, 47,242,233,177,136,106, 89, 0,118, 41,194,178, 88,230,211, 69, 88,118, +233,107, 34,194, 70, 76,201,196,161,116,250,162, 37,129, 70, 18,243,219,136,107,169,109, 45,128,217, 21,224,235, 77, 67, 22,112, +104,108,210, 4,106,255,106, 17,249,162,150,233, 40,233,245,204, 76,148,227, 87,236,238,141,157,103,105, 52,102, 88, 13,113,206, +211, 8,224, 60,206, 57, 54,204,201,156,134,136,196,208, 6, 79,149,138, 16,164,136,136, 45, 47, 35, 5,240, 58,243,192,112,174, +163, 8, 52, 3,124,167,224,113, 20, 33,170, 57, 7,206,120, 9,231,100, 30,132, 72,130, 58, 41,126, 70,210,255,193, 0, 67,131, +154,152, 78, 11,106, 66, 58, 82, 68, 93,235,116,180,185, 70,141,168, 1, 86,144, 72, 37,201, 49,169, 13, 4,189, 40, 3, 39,184, + 10,154,153,192,145, 26,234,204, 47, 23,183, 93, 39, 73, 48, 55, 71,172,218, 84, 26, 61, 2,182,252,103,228,226,255,130, 78,214, + 24,125,118, 43,103,127,124, 31,113, 58,101, 99,105, 41,129,156, 68, 26, 81, 84,197,162,180,124,220, 72,204, 98, 52, 11,107, 6, +106,116, 46,193,174,209,181,217,174,214,191,139, 54, 69, 92,151, 51,239, 22, 54, 37,250,124, 9,177, 29,125, 34,106,193,183,107, + 35,237,110,216,107, 55,185,164,244, 16, 93, 98, 63, 92,196,101, 70, 64, 58,141, 67, 90,121, 35, 85,166,225, 93, 90,234,188,166, + 72, 61,143,139, 44, 2, 10,222,232,197,144,120,225, 0,196, 6,154, 16, 91, 33,101, 6,246,161,131,177,139,109,158,184, 18,216, + 58, 13,137,214,124,213, 30, 56,237,124,168, 94, 12,227,199,219,114,166,105,233,156,124, 0, 86, 63, 6,211, 35, 48,155, 66,181, +100, 87, 51, 52, 90, 34, 64, 92, 77,116,124, 27, 15, 54,105,217, 24,158, 13,205, 89,200,198,117,212, 7,103,172, 15, 6,132,152, + 62,187,141,220,196, 0,154,121,103,182,133,241, 76,101,186,196,106,136,104,151,234, 42, 28, 23, 41,132, 69,229,236,110,138, 8, +119,102,145,213, 54,159,206, 97,170, 66,200, 14,144, 9,246, 6, 62, 69, 64, 98, 81,149,152,246, 4, 77,116,162, 15, 74,229, 82, +158, 48, 90,142, 56, 83,178,170,202,134,194, 68,133,169, 42, 49,182,119,177, 91,128, 67, 58,215,195, 49,229,246, 71, 22,173, 55, + 81,152,233,130,192,205,156,198, 16, 19,179,163,134,168,177, 88,104, 23,183, 91, 12,133,170,169,196,251,170, 20,145, 37,101, 69, + 33, 0,234,156,167, 65, 17, 61, 75, 41,220, 42,192,193, 27, 75,161,210, 1, 88,206, 79,175,106,146,171,140,109, 20, 53,210, 69, +202, 72,231,172, 21,153,162,185, 8,176,164,142, 21,101, 2,166, 49,154, 95,180, 35, 73,112, 54, 44, 34,199, 60,135,242,241,134, +162,140, 16,214,201, 57,110, 12, 92,211,154, 53,176,235,173,109,213,115, 6,242, 21,176,100, 26, 12, 85,101, 29,216, 31,147,232, + 77, 16,166,118,157, 65,231, 29,160,148, 11, 23,102, 40,107, 70,195, 15,115,158,190,125,114,243,201, 60, 65, 88, 35,165, 20,102, +106, 84,188, 46,228,139,181,123,182, 65,149,129, 42, 3, 7, 42,182,186, 27, 62, 8,142, 72,180,244,107, 10,176, 6, 44, 56,112, + 69,144,182, 64, 70,205,253,174, 20,144,198, 34,186,239,158, 77, 55,174,150, 36,105, 70,214, 17,166,154, 65, 89, 25, 26,230, 69, + 96,146,157,157, 28,181,170,131, 66, 87,228, 76, 48, 30,165,116, 36,164,197, 52, 39,166,131,144,133,188,254, 81, 88, 8, 22,116, + 2,165, 19,169, 54, 70, 86, 6, 21,219, 55,111,193, 47, 45, 35, 49,226, 92, 69,101,236, 73,211,164,232,220, 13, 42,240,130,134, +180, 78,251,148,134,210,206,187, 40, 78,166, 20, 76,181,143,184, 64,116,165, 3, 89,147,156,117, 17,164,204,107,175,165, 77, 24, +228, 92,141, 44,136, 36,180,163,126,213,117,209,162, 40, 78, 92, 7,250,154, 40,226,246,115,181,115, 62,202, 69,214,145,162, 71, +212, 49,112,129, 42,118,169,139, 74, 28,222, 69,124, 37, 52,235, 2,119,212,232,116,104, 82, 8,223,221,122, 61,156, 68,114,140, +138, 24,192,150, 6, 25,166, 72,113,235,171,145, 71,252, 56,250,244, 49,155, 14,110,229, 97,183, 31,226,118, 55, 97,178, 52, 78, + 2,194,168,166, 81,144,118,145,104, 31, 97, 76, 30,151,198,144, 68, 37,196,116, 63,188, 51, 47, 85,146,226,186,205,155,107,118, +121, 83,116,163, 14, 79, 82, 83,133, 16,230,133,114,153,154,207,207,211,199,130, 54, 77, 30,168, 6,185, 75, 46, 93, 76,116,135, +229,122, 93,142,214, 53, 61, 87, 87, 16,201,106,142,155, 51, 47,179, 18,197,187, 52, 57,242, 34,171,249,177, 42, 68, 23, 83,148, +158,159,131,239, 34,222,156, 87,243,146, 34,197,170, 74, 81,208,146,135,205,107,202,224, 41,219,224,162,211, 65,254, 53, 12, 31, +105,207,164, 78,255, 55,119,192,250,251, 97, 99, 63, 76,102, 80, 15, 83,200,175, 83,144,237, 73, 32, 23, 39, 48,219, 7,203,107, +197, 50,221,101,191,241, 91, 96,155, 75,169, 3,215,229, 79, 75,138,215, 89, 14,188,157,176, 85,138,230, 93,236,198,241, 44, 22, + 30, 77,232,132,161,170,138,120,215, 58,102, 90,140,253,210, 6,133,194, 91, 20,150, 28, 84, 33,249,156,117,166, 95, 37,127, 22, + 45,128,102, 2,168,105,186, 8,119,104, 90,136, 38, 38,149,190,179, 8,112, 18,104, 41,208, 28, 81, 54,154, 41, 96,139, 2, 21, +106, 99,182,166,116,170,251, 37,201, 57,108,155,243,210, 69, 69, 51,151,216, 4, 47,194,212,216, 3, 89, 88,104, 83,174,177,212, +138,148,162,161,206,221,170,142, 34,237,212, 66, 88,151,165,158,194,188,142, 70, 23, 22,198,202,126, 25,237,134, 74,235, 96,195, +196,158,229,184,112,172,114,164,185,178, 16,197,151,145, 96, 22, 17,102, 5,254,192,128, 54, 85,218, 36, 17,172, 20,224,239, 74, +138,121,225,153,143, 12,108, 2,202, 84,165,213,204, 84,139, 14, 80, 91, 21,160,140,115,228,111, 58,162, 0,172,199, 68,181, 79, + 45,114, 11, 40, 7, 45,106, 63,150, 34,124,102,207,119, 36,137,245, 41,215,106,135, 82,107,202,197,231,156,255,196, 28,133, 70, +165,173,120,136, 11,122,146,188,198,100,209, 95,140, 80, 57, 65,165, 67, 88, 21, 65, 53, 69,236,165,115, 88, 21,168,151, 83,135, +193,158, 81,208,121, 0, 47,211, 51,190, 76, 9,105,231,100,182,207,173, 8,150,167, 69,165,205,208, 38, 77,134,180,172,112,143, + 8,149, 19,164, 74,235,106,204,194,108, 5,231, 92,155,214,117, 6,252,222,156,150, 38,139, 13, 77,128, 20,109,157,206, 58,140, +120, 23, 2, 75,138,212,169, 51,109,135, 90,197, 81, 98, 72, 42, 95,225,171, 4,228,226, 43,188, 23,106, 28,135,102, 83, 38,235, +135, 25,185, 1,163,225,144,102, 56,166,137, 19,203,173,155,250,221, 75,151,211,142, 54, 49, 59, 79, 35,166, 73,236, 76,177,190, + 16,165,119, 96,161,173,158,186, 19,188,217, 68,201, 37,109, 11,131,218,201,252,136,203,185, 97, 17,109,193,189,144, 64, 24,173, +221, 81, 31,106,220,157, 47,156, 3,113, 9,236,209,208,130, 68,109, 74, 77, 39, 32, 46,178,105,217,177,115,139, 32,107, 2,235, + 1,153, 68,139,204, 93,151, 1,211,181,132,168,238,140,163, 80,183,211, 68,237,142,191, 18,118,255, 40,124,205, 47,226,116, 51, +155,255,188, 98,240,197,253, 28,116, 19,142, 44, 47,209,136,152, 74,191,243,247,197, 70,153, 11,130,196,216, 10,117,208,164, 30, + 21,205, 17,109,102, 72,192,123, 73,164, 85, 8, 45,161, 32, 57,215,174,225,174,138,244, 54,162, 52,117,181, 82, 76,192,142, 33, +192,165,170, 0, 23,211,100,203,185,119,103, 30, 31,150, 46,145,214,205, 11,243,229, 45, 98,142,151, 79, 66,170,236, 97, 71, 59, +126,180,114, 30,138,212,138,179,103, 23,165, 91,252,242,128,247, 70,193,143, 92, 2,184,165, 38, 48, 82,143,123,248, 10, 34, 35, +240, 59,192,143, 76, 85,227,147,111, 61,253, 24, 76, 14, 66,152, 66,157, 22, 12,209, 8,113,154,158, 97, 16, 83,190, 71, 8, 7, + 97,176, 1, 44,207,187,250,238, 52,228, 49,203,200,255, 62,140,175,187,136, 56,171,183,157, 81, 18,222, 60,167,218,137,229, 55, +211,133, 36,226,178,211,118,168,206,235,121, 37, 59, 98,133, 18, 82,140, 5,169,116,158,118,171,108, 5,170, 99,114,124, 6, 46, +221, 23, 9,105,241,214,152,233, 83,109, 35,120,236, 51, 51,107, 48, 52,237,133,138, 50, 11,105,177,143, 64, 29,147, 58,125, 96, + 11,119,166, 63,115,148, 91, 23,165,113, 85, 76, 63, 79,141,229, 26, 91,117,201,160, 85,253, 91,212,104, 74,247,129, 69, 56, 81, +211,179,115, 72, 82,145, 23,202,111, 45,227,192, 5,102,178,140,182,178, 35,225,139,212, 96,118,104,114,154, 34, 22,116,108,233, + 60,100,189, 72, 25, 9, 38,109, 77, 87,106,213, 42,221, 77,104, 55, 44,114,246, 13,221,245, 45,205,187,126, 45,152,123, 3,253, +145,192,216, 68,100,171, 6,100, 94, 74,250, 87,231,104,228, 88,204,155,202, 4,110, 41, 45, 96, 37,135,210,229, 99, 7,197,121, +137,221, 95, 44, 50, 95,178, 99, 76, 45, 58,207, 57,238,124,239, 14,107,202,237, 75, 1,214,186,144, 50,105, 10, 13, 65, 64, 24, + 74,186,142,105, 78, 63, 88, 30,191, 54, 6,161, 49,182, 39, 75,235, 18, 80,207, 59, 3,177,248, 33,144,242,239,121,253,136,115, +225,170,182, 65, 89,171, 89, 40,216,150, 12,196, 57,229, 23,115,153, 99,145,146, 41,211,174,229,161,245,104, 37,109, 54, 70, 99, + 72,250,175,202, 74,250,130,233, 12, 2, 88,181, 77, 2,105,135, 80, 59, 95,212,235,165, 40,124, 32,157, 38,196,105, 2,127,111, +215,227, 92,170,150,193,214, 2, 87,232, 4, 92,113,127,180, 43, 16,179, 74, 17,135, 56,151,212,252,170,169, 44, 56, 42, 65,148, + 67,117,205,198,129,253, 44,143,134,108, 26, 47,195,112,196,106,211,176,177,177,198,146, 10, 75,227, 33, 50, 28,227,196,179, 46, + 66, 51,155,161, 49, 82, 85,222,163, 69, 60, 46, 5,229, 85, 10,230, 22,201, 37, 89, 16, 73, 81, 68,233,106, 94, 96,101, 81,156, +162,230,141, 40,206,120, 66, 39,157,194,175, 84,213,231,168,222,187,124,209,230, 40,152, 71,227,219, 76,180,182,245,134,185,224, +171,242, 41,194,117, 46, 57, 0, 34, 48,240, 14,135,209,197, 70,157, 74,136,172, 29, 22,198, 81,208, 89,128,141,136,232,106, 17, +238, 55,160, 53,232, 45, 32, 59, 44, 98,159, 46,144, 65,211, 20,177,143,159,137,236,110,208,203,127, 25, 25,140, 25,191,125, 7, +167,125,254, 32,195,141, 9,245,112,204,186, 13, 72, 23, 35,161, 74,209,183,134, 60, 1,186,154, 31,135,164, 18,184,185, 28,190, + 24,239,160, 29, 93,239, 58, 30, 80, 26,157,207,207,148,160, 89,148,200,205,179,189, 46,157,128,221,120,137, 93,153, 89,118, 10, +156, 83,163, 64,179,126, 34, 73,191,115,121,161,216,162, 22,189,121,186, 81,231, 40, 39,141,185,254,218,142,151,129, 74,141,190, + 82, 24,104,164,170,186,219,237, 36, 45,114,198,244, 51, 20,101,105, 18,169, 70, 35,228,172,101, 88, 94,129,225,206,228,133,228, + 24,175,249, 34,108,252, 11, 52, 19,168, 29,218,116,206, 41,177, 78, 58, 9, 89, 7,153, 89, 8,179, 6,113, 13,220,210,188,204, + 70,119, 32,103, 47,227, 70, 73,100,169, 46, 57, 53, 90, 0,135,203,207, 37,231,117, 53, 69,198,141,198,148, 59, 21,136, 49,141, +251,236,228,102, 70,170,117, 56, 77,172, 22,138,249, 83,121, 73,202,122,186, 82, 50, 33,249,147,177, 0,118, 33,229, 50,215,173, +196,174,142, 41,194,174, 45, 15,239, 10,138,117, 10, 12, 93,226,156,115,137, 87, 44,114,255,121,190, 13, 11, 49, 74,206,141,175, + 91, 73, 76, 6,142,153,192,154,166,235,205,181,213,162,243,226,166, 17, 93,165,194, 44, 11,232,114,132,146,197,120, 34,212,170, +237,226, 13, 66, 83, 36,166,100, 65,219, 35, 71,139,190,115,228, 70,238,113, 32,115, 85, 1,101,224,144, 34, 94,105,131,129, 12, +182,205, 66, 89,149, 73, 96,169, 92,138,222, 91, 7, 40,215, 44, 27,184, 74,177, 80,187, 34,159, 61, 22, 97,127, 84,142, 20,218, +128, 97,113,237,163,226,190,180, 14,183, 22, 12,135, 57, 3,149, 69,253, 81, 18,101, 47, 69,105,168, 24, 77,159,105,228, 92,143, +191, 17,211,251,243,156,159,216,243,219, 80,230,202,101, 41, 34,225,122, 65,160,134,166,103,156,203,170,178,168, 48, 26,160,215, +154, 0, 62,208,105, 59, 40,198, 80,180,126, 3,178,208,131, 34,139,172,155, 24,147,246,166, 88,171,219,212, 76, 33, 20,244,139, + 37,176,116, 41,188,172, 59,169,181, 19, 28,230,178,202, 50,192, 88,172,101,207,247,174,177,241, 59,144,200, 88,133,202, 22,203, +152,233,242,150, 11, 79,192, 29,140, 89, 16,231, 58,221,150,253,189, 50,119, 56, 87, 93,164,190, 46, 21, 65, 26,211,165, 68,123, +182,137,101, 78,142,174,118, 2,225, 18, 71, 11, 38, 47, 90, 9,118, 16, 79,144,136,134, 72,136,129,213,201, 6,235,211, 13, 14, +173,173, 83, 13,135,248,170, 98, 92, 85,248,106, 64,140,145, 81,140,140, 70, 35, 54,166, 27,192, 52, 57,140,177,200,145,137,116, + 37,102,217,207, 19, 91,233,133, 46, 47,158, 20,160, 9,173,212,114,188, 71,243,142,200,234,110,171, 85, 79,107, 72,202,153,106, + 22,157,123, 3,106, 21, 84,211,136,205, 84, 71, 37, 86,156,159, 75,157,180,149,186, 91, 46, 63,226,189,239,234, 26, 69, 76, 77, + 31, 77,237,152, 38,229,104, 40,104,132,145, 75,147,123, 54,205, 34, 35,208,105, 68,214, 3,196, 3, 54,229, 77,247,170, 13,196, +125,224,110, 5, 57,183,144, 76,149,196,225, 20,100, 12, 75, 95,143,236,174,225,105,111,132,173, 99,170,183,239, 97,219,245,119, +194,234, 6,245,120, 76,172,160, 9, 66,136, 41,199,158,242,134, 93,238, 42,149,237, 5,139,186,164,168, 95, 82,188, 26,109,237, +181, 40, 65, 75,130, 56,113, 57,158,215,246, 9,120,107,108, 50, 95,255,201,188,236,199,128, 39, 77,134, 46,223,158, 91, 30,100, + 92,234, 74,131,140, 47,111,153, 1, 37,122,103,244,123, 90,176,221,130,184,165, 89,200, 33, 55,161,203,253,182, 3,191,144, 59, +139,229,144, 43,159, 0,105,105, 26, 25,132, 10,247, 85, 59,145, 39,109,135,173,103,193,224, 92,139, 83, 2,196, 47,193,218,251, + 97,122, 16,226, 12,157, 6,152,249,212,100, 38, 24,113,169, 13,200,106, 2,120, 87, 37, 10,126,180, 31,220, 22,107,117,146,117, + 20, 35, 56,109, 51, 50,116,248, 89, 96,176,228, 83, 62,215, 82, 12,106,233,181, 12,146, 77,209, 92,166,182,200, 53,196,110,193, +235,228,175, 11, 10, 93, 19,146,182,213, 2,246,152, 71,149, 48,200,148,182,129,123, 29,140, 30,142,176,201,209,214,160, 79,162, + 50,177, 8,125,166, 41,151,157,129,211, 39, 85, 70, 74, 76,196,142, 2,246,101,196,233,210,177, 71,185, 54,220,193, 52,216,115, +119,169,241,205, 84,161,246,233,239, 75, 10, 27, 34, 73,183,145,243,255,190,203, 57,123,132,113, 33, 10, 27, 26,128,110,100,149, +127, 33,136, 26,216, 98,233,173, 84, 44,150, 81, 56, 29, 56,233, 49,213,193,243,130, 56,183,176,160,231,232, 19,101,142,154,207, +141,109,198, 93,102,132, 13,237, 42, 0,102, 2, 99, 77,209,112, 44,152,199,137, 69,188, 67,129,205, 38,174,243, 69, 9,225,200, + 30,245, 17, 3,155, 97,209, 92,102, 0, 44, 91, 83,172, 18, 72,157, 57, 70,195, 5,128,115, 6, 4,193,214,184,144,157, 63, 77, +140,193, 38,103,206,135,116, 32, 21,115, 74, 72,231, 25, 5,218,230, 68,157,227,228,143,114, 55,131,233, 22, 66,225, 4,228,231, +218, 20, 77,124, 90,165,186,106, 91, 65,222,222,247, 5,133,247, 93,250, 41,228,242, 43,113, 45,111,224, 45,135,237, 76,111, 80, + 54,152,169,164,211, 86,148,140, 99,118, 20, 43, 19, 88,230,117,170,233, 42,123,231,203, 59,237,222, 52,116,172,115, 80,101, 18, + 3, 85, 72,248,149, 75,248, 52,139,229, 12,208,165,168, 0,234,202,109, 19,197, 46, 22,140,138,233,163, 68, 18,147,234,226, 0, + 37,208,208, 20,138, 4, 77,213, 66,222, 19, 98, 76,245,177,229, 56,176, 26,222, 84, 85, 19, 83,245,152, 56,188, 56,130, 79,245, +190,222,198, 88,211,212, 12, 52,178,105,105, 39,245,210,152, 3, 7, 15,224,166, 19, 54,111,218,140, 46,175, 16, 66,131,134, 72, + 52,231,175, 16, 30,104, 91, 50,225,164,204, 99,148,253,109,116, 94,244, 38,119,109,225,224,140,194, 72,199, 43, 84,239, 86, 19, +168,153,198,207, 3, 65,170, 68,225, 34,214, 85,174,163,113,165,168,111, 79,145,173, 22,170,193, 20,245,121,103, 74,197, 8, 90, +229,154, 90, 97,224,146,168,104,105, 32,196, 58, 82,185, 20, 41,229,142,104, 51, 95, 17, 39, 83,170,181,149, 36,176,210,198, 70, +245,204,142,183,150, 58,148, 13,119, 89,141,243, 17,136,251,193,237,182, 41, 92, 39, 10, 88, 70, 48,126, 46,236,220,130, 92,246, +107,232,150, 35,248,183,157,198,142,143, 30,196, 31,152,242,249, 65,197,161,145, 16,131,213,199,230,188,118,214, 35,228,112,218, +123,187, 79,161,229,145,162, 81, 85, 41,125,222,117,123, 75, 13,156,124,155,131,213,216, 32,174, 3,100, 22,196, 26,221, 19, 10, +214,225, 47, 87, 42,116, 93,224,212,101,181,123, 26,196,149,151,142,177, 23,235,134, 18,115,159,129,104,147, 80,230, 22, 88,236, + 28,106, 27,195,209,190,111, 98,202,145, 59, 19,200,229, 6, 37,222, 74,132, 6,214, 32,104, 73, 96,101, 18, 25,174, 58,252, 37, +219,144, 23,238,130, 51,207,129,193,183, 1, 15,179,176,242,150,212, 53,110,245, 75,208,172,195,108, 2,117,101,209,184,107,117, + 1,105,182,248,244, 60,101, 9,102, 95,132,233,118,112,219,193, 13, 58, 24,145, 1,108, 94,198,109,245, 12,246, 5,134,155, 96, +214, 24,253,151,187,139, 24,120,139, 69,208,161, 33, 9,205,172, 40, 65, 85,231,230, 72,219,123, 33,211,167, 5,245,230,139,116, + 68,101,236,209,216,244, 8,141, 74, 91, 23, 95,219, 61,170,130, 81,234,182,152, 55,157, 94, 49, 57,192, 69, 90,171,113, 73, 28, + 57, 49, 10,119,224,210,189,111, 29,116, 59,207,154, 84,218, 83,209, 41,228,107, 59,159,117, 77,140,192, 88,146, 96,175,209,212, +200, 38,218,245, 7, 59,118,165, 93, 62, 52, 47,196, 19,186,198, 44, 25, 28,114,115,150,236, 96,148,206,160,106,234,187, 16,138, +104, 47, 71,196,113, 81,201, 94,140,233,160, 41,245,147,197,159,161,204,173, 23,236,131,155,203,195,167,241, 42,170,173,211, 95, +219,178, 50,147, 78, 92,229,205, 1,153, 88,249,215, 33,133, 85, 96,139,192, 78,103, 0,107,192,220, 81,212,243,181, 50, 43, 46, +141,229,181,216,229,126, 75, 86, 34, 20, 76,129,180, 37, 87, 41,173,226,138,206,129,222,114,164, 89, 33, 94,118,167, 91,182,244, +194, 42, 73,249,238,109, 85, 26,219,177, 6, 40,107,154,158,137, 90, 57,242,144,178, 97, 76,210, 71,228, 58,116,191, 72, 19, 23, +234,246,174, 10,161, 77,178,182,209,182, 71,231,196,132, 37, 21,238, 77,203, 80,229,124, 58,169, 75,168,183, 52,105, 62, 78,217, + 25, 81,100,222, 17,213,194, 17, 10,208,150,201, 6,201, 93, 58, 11,177,158, 20,142,146, 72, 18, 75, 22,247, 58, 68,101,166,129, +202, 41,195,170, 66,156, 7, 39, 22, 51, 73,219,212, 6,115,152,213, 20,237,218,130,189,173,193,177,171,123,247, 86,105,146,115, +236,177, 76,109,169, 50, 16,135,120, 71,144,144,142, 87, 8,172,114,119,208, 44,182, 77,125, 88, 92,170, 48,178,106,165, 28,235, +213, 49,114, 96,245, 48,205,250, 42, 97, 58, 65, 84,169, 15, 31, 66, 87,143, 88,218,156, 36,166,115,237, 35,234,162, 7,209, 46, + 78,111, 35,110,233, 34,119, 41,101,189, 38,150,202,171, 84,110, 32,130, 22,224,159,219,238,229, 34,127,203, 33, 56, 39, 56,151, + 98,147,172, 42,118,210, 29, 63, 55, 52, 17,237,142,167, 42,109, 45, 96, 9, 86,137, 42, 49, 1,142, 79, 20, 75,101,229,113, 46, + 42,226,133,145, 79,142,192, 76, 3,218, 40, 99, 7, 58,137,169, 48,180,153, 38,186,150,104,229,109, 27,105,101,157,125, 22,220, +185, 48,184, 40,249,230, 58,129,230, 35,224, 47, 73,234,120, 53,137,143, 27,193,210,229, 32,155,144, 71,190, 1,182,125, 30, 62, +184,157,109,239,158, 48,248,232, 17,110,154,212,236,223, 50,192,161,204, 98,164,206, 15,213, 91, 94,166,209,244, 96,136,105, 80, + 72, 87, 11,233,178, 42,221,165,156,177,203,250,216,162, 69,231,124,221,250, 66,196,147,251, 0, 19,239,162,118,159, 43,173, 48, +167,206,137,195, 59, 77, 30,182,189,181, 66,105, 52,206, 45,206,226,230, 83,244,181,130,183,104, 54,104,162,137,163,137,179, 70, + 30, 42,151, 38,132, 51,111, 61,216,108, 21, 15, 3,167, 44, 57, 88,170, 35,163,137,163,122,204, 22,220,203,182,193,249,103,194, +224, 74,224, 18,251,212, 47,194,198, 91,224,240,199, 82,135,150,112,208,138,142,165, 11,151,188,128, 27, 90,211,157,218, 34,246, + 38,157,216,228,147, 48, 56, 3,134,155,128, 21, 3,245, 37, 24,109, 66,206, 24, 81,237,157,225, 53, 38, 1,140, 38,218, 51, 88, +198,162,141,204, 67,162,190,179,239, 80,138, 32,157,148,229,156, 93,169,150, 95,232, 15,224,114,231, 54, 39,140,124,215, 95,128, +144, 88,141,118, 33, 13,169, 70,124, 40,194, 52,198,182,181,108,249,153,101, 30, 49,218,138,156, 85,200, 49, 88, 78,223,106,231, +115, 75,134, 72,114,186,188, 1,112,180, 38, 63, 81, 82,117,194, 6,137,118,223,229, 96, 91,149,110,225,204,198, 82,147,117, 44, + 22,113,229,226,165,202, 58,146,121,133,169, 40, 78,211,130,159,137,139, 78,180, 54,175,105,118,243, 18,213,246, 94,229,181, 73, + 23,114,147, 20, 45, 53,187,158,111,243, 29,185,114,133, 78, 85,170,232,164, 43, 95, 27, 22, 93,209,196,238, 65,101, 17,252,154, + 74, 91,235, 62, 48,103,106,221,190, 14, 42,108, 86,216, 33,176,213,132,131,185, 21,108, 46,115, 92,145,228, 0, 76, 76, 41, 94, +149,138,108,187, 15,117,241,204, 42,211,254,168,206, 63, 75, 45, 20,251, 19, 77, 99, 43,106,138,110, 51,115,176,106,192,236,138, +161,239,117, 94, 96,231,108, 61, 31,146,244, 42,179,104,105, 6, 45, 1, 60,165, 71,186,246,185,185, 99,219,188, 32, 78,138,231, +157,157, 36,103,141,132, 68,230,149,240,173,248, 83, 82,137,170,138,164,158, 6, 42,109,251,240,204,110, 13,138,138,131,178,215, + 65, 60, 74,207,129,129,165,234, 26,233, 28,214,185, 54,171,218,117,155, 83,233, 82, 64,177,240, 84,166, 49, 18,155,134,202,167, +117, 79,173,189, 50,209,225,188, 3, 26, 66, 12, 38, 60, 75, 35,207, 75,234, 34, 39, 86, 98, 93, 57, 97,224, 28,149, 56,106, 9, + 56, 13,105,188,183,159,157,114,228, 18, 2,131,193, 0,231, 61, 33, 4, 66, 12, 72, 91,254,166,115, 42,249,220,208, 45, 5,123, + 62, 21, 63,155,224, 58, 0,245,108,210, 9,197,157,233, 27, 66,176, 57,145,220,197, 74,117, 62,151,145, 85,230, 74, 7,206,210, +130,168,116, 53,236, 57, 19,111,139,159, 20, 57, 17,213, 12,206,157,104,206,185,228,125, 56,111,255,163,133, 48, 43, 90,111,249, +121, 69,171,107,203,234,204,163, 12,214,169,204, 46,220, 57,105,197,113, 73, 20,230, 82, 71, 35, 7,203,190, 19,214,205, 80,134, +214,120,164, 65,169, 53,189, 14, 95,161,177, 78, 97, 73, 51,161,109,250,167,117, 2,239, 16, 97,118, 8,252, 7,192,239, 78, 17, +158,236,129,240, 73,208, 59,193,127, 37,200,206, 20,159,104, 99, 17,251,147,193,239,130,193,239, 35,187,222, 15,143, 13,108,122, +215, 54, 46,252,189,131,184,253, 51,142,236, 28,160, 78,152, 54,166,230,205,194, 35,187, 95,161,200,191,122,159, 35,239, 68,203, + 26,166,162, 69,223,108,114,207,251, 28,229,120, 91, 51, 11,245,181,148,110,236, 92,121,219,124,219, 81, 17,143,115,145, 74, 99, +187, 56,100,189,123,202,163, 75,145,234, 0,141, 89,108,162,233,123, 91,220,156, 75,183, 78,213,165, 22,150, 46, 80, 85,150,231, + 5,124,236, 90, 2, 84, 30,198, 78,216,228,149, 77, 77, 96,188,230,168, 46,221,140,123,217,102,184,224, 76, 88,190, 10,120,172, +141,137, 59, 96,253,191,194,129, 15,145,187,123,232,172, 73,180,187, 77,146,212,109,101, 4,110,156,150, 83,157,153, 91, 31,146, +218,108,114, 0,170,191, 79,207,200, 95,144,116, 17, 84, 73,206,190,107, 96,148, 89, 74, 99,228, 14, 88, 3, 81, 26, 99, 45, 98, + 80, 26,235, 52, 55, 47,202,145, 98,220,206, 51, 36,217,183, 29, 59, 65,188,166,146, 57,151,169,201,121, 26, 86, 13, 68,172, 2, + 48, 49, 29, 62, 69,235, 51, 21,243,230,173,165,232, 81,196,167,149,149,104, 57,237,212,195,169,185,205,124, 62, 52,152, 40, 42, +183, 53,117, 22,125, 46,217,128, 8, 22,225,109,196, 4, 4,155,156,112, 36,106,218,179,160, 21, 3,130,119,106, 98,193, 68, 93, + 86, 5,149,155,243,164, 90, 54,118, 41, 96,184, 76, 17,137,204, 83,182,190, 80, 83,119,244,176,180,139, 96,197, 93, 36, 38,201, + 25,208, 78,153, 55,199, 88, 45, 28, 63, 11,241,196, 0,126, 40, 93, 84,216,180,101,134,106, 45,157,187,250,238,117,133,181, 0, +123,173,223, 60,153, 77,177, 24,103,139,192, 14,235, 16,152,115,219,173,232,107, 17, 24,237, 57,141,236, 58,214,179,118,161,232, +212,151, 89,158, 65,161,151, 25,200, 93,234, 55,230, 58,174,229, 28,126, 83, 8,232,218, 64, 41,166,116,201, 90, 25,189,218,184, +194,156,176, 28,253,134,130,162,143,119,109,128,214, 82,212, 3,235,139,144, 53, 26, 25, 60,171,133,250,108,103, 79,177,145,252, +124,114, 9,150,182,109,169, 85,117,174,221,107,181, 80,178, 86, 21,101,148,190,232,192,153, 91,166,213,185, 74, 66,187,231, 25, +203,118,197, 69, 61, 92,136,145, 72,211,122, 3, 42, 14,231, 60, 33, 8, 33, 6, 92,140,109, 13,187, 43, 74,213, 48,103,102,224, + 28, 3,163,237, 69, 60, 34, 77, 81, 64,175, 93,173, 80,108,112,141, 48, 24, 14,113,131, 1,174,113,168, 75, 81,187,138, 9,123, +115,185,118,218,132, 5,109, 27,168, 57,162,116,209,125, 46,155,155, 99, 96,139,214,196, 49, 70, 42,181, 22,130,222,149,141, 64, +202,198,142, 50, 7,248,206,205, 55, 28,144,210,219,208, 34, 10,148,148,124,243,222,225,157,199,121,105, 85,192, 20,253,114, 83, + 84,216,149,212, 37, 47, 78,186,182,175, 69,157, 99,110,125,154,107,227,197, 34, 29,103,185, 43,113,169,148,102,224,187,235, 73, + 93,235, 60,149,213, 63, 27,105,159,110, 14,145, 32, 30, 93,141, 72,109,138,119,197,208, 98,218,209,183,179,155, 97,116, 59,184, +173,169,225,137,127, 52,132,143, 66,248, 48,248, 71,128,236,162,221,252,133, 33, 12, 31, 14,254, 7, 97,244, 44,216,242,110, 56, +235, 93, 44,159,215,112,225,107,215,248,194,254,154,176, 99,192,164,130, 80,203, 92, 61,111,119, 95, 6,133, 7, 23, 91, 97,160, + 20,202,209,114,186, 68,163, 19, 51,117,216, 57, 97, 58, 39, 51,158,107, 66, 99,157,162, 84,138,188,149,164,218,244,202, 38, 93, + 44, 22,124,172,169,143,134, 46,130,204, 10, 4,181,222,229, 41,130, 76,139,124,229, 18,159,238, 61, 12, 27,207, 82,149,192, 31, + 13,169,217,144,165, 77,150, 92,100, 84, 69, 54,133,200,120, 29,170,115, 87,112,255,118, 59,114,225,165,176,252,221,224, 31, 99, + 25,209,195,176,241, 39,112,231,223,167, 29, 73,214, 6,104, 93, 37, 69, 89, 19, 90, 23, 94,134, 77, 42, 81,195,106,213,115, 83, + 33,167,198,196, 8,108,220, 4,163,207,129, 63,183,203,226,250, 49,178,213, 83,225,169,172,254, 59,228,197, 45, 74,167,232,151, +174,251,153, 22,250,145,156,109,148,130,135,204,185, 64,135,105, 5,124,242,242,107,235, 37,148,231, 66, 44, 74,233,234,144,212, +230,161,145,156,109, 74,254,136,104,171, 84, 15,139,125,168, 10, 65,100,152,235, 51, 45,212,134, 12, 3, 73, 77,144, 92,212, 86, +164, 89, 42,171, 53, 66, 99,105,144,145,135, 81,147, 64,127,205,186,176, 45,249,178,139,152, 24,157,155,158,125,219,109,173,165, + 97,165,141,132,103, 22,149,249, 66, 79, 80,219, 25,122,233, 68, 66,101,254,191,141,168, 23,218,237,150,101,116, 25,196, 93,217, + 11,159,252,124,148, 70, 58, 70,195, 47,168,237,197, 40,248, 80,232, 63,102, 22,137,175,197, 34,197,145,169, 97, 43,225,245, 11, +145,244,204,126,183, 34,176,197,193, 86, 7,187,114,103, 57,157,103, 15, 22,235,172,115,254,119,104,121,250,213, 96, 81,119,209, + 1,186, 44,161,203,116,250,208,198,228, 97,163,146,181, 0,180,220,122,216,119, 29, 28,218,220,117,119,207,148,173, 8, 19, 7, + 7, 98,231,184,102, 96,159,153,224,174, 44, 27, 91,100,134, 68,231,203,197,114, 95, 9,111,218,139,156, 78,105, 59, 22,182, 84, +116, 94, 75,186,115,173,172,204, 88,172, 13,246, 64, 82, 47,132, 88, 56, 7,200,252,198, 47,142, 5, 81,158, 93,127, 85, 86, 48, + 20,226, 79, 93, 16,124,199,133, 40, 62,177,173,202, 58,129, 97,140,224, 93,219,236, 9,107,252,165, 20, 37,106,222,155,248,210, +208, 81, 5,245, 66, 12,190, 91, 3,231, 74,239,148, 89,104, 24,212, 80, 25,176,107,244,196, 24, 76, 68,151, 78,180,109,198, 38, +146, 54, 38,107,215, 20,103,167, 24,139,206,149,101, 40,161, 93,185,168,152, 16,112, 49,239,218,121,192,106, 98, 56,215,129,119, +209, 2, 76,139,182,164, 45,237,104,162, 8,113, 21,174,242,214,109, 44,183, 19,143,150,103,113,115,191,111,213,247,185,182, 90, +156, 85,151, 41,206,249,162, 17, 14,182,139,155,229, 6,179,154,214,169,149, 97,165,186,111,103,194,166, 76, 47, 13,173,215,117, +162,144, 21, 85,215,230,243, 98,180, 36, 98, 19, 19,168,103,129, 85,140, 86,235,188, 53, 21, 78,179,110, 15, 95,192, 89,110, 55, +126, 30,194, 13,224,215, 65,206,164,173,110,213,202,202,175,158, 12,225,177, 48,124, 38, 60,253,151, 25,251,235,121,216,207,110, + 16, 14,215, 76, 54,109,164, 86, 87, 0, 0, 32, 0, 73, 68, 65, 84, 13,208, 40,204,172,172, 13,117, 86, 74, 21, 16,141,120,201, +145,121,209, 47, 64,244,232,125,222,181, 83,190,107,177,106,204,111,242,146,115,222,182,249,139,116,212,190, 3,196,107,218,240, + 38, 59, 14,174, 75,173,136,183, 62,251,182, 0,135, 8,117, 78,158, 23,249,202, 88,212, 58, 59, 67,180, 61, 59, 6,156,254,228, +205,204,110,217,224,246,235, 55,208,232, 80,137,120,107,240, 50,116,202, 74,163,140, 86,149,106,251, 50,238,223,239, 68, 46,126, + 6,172,124, 27,248,179,211, 61,141, 7, 97,227, 47, 96,223, 31,194,190, 25, 28, 89, 70, 39,210,133, 63,217, 59, 30, 89,171, 93, + 89, 74, 83,187,217, 72,165,109,177, 6,181,120, 72,150, 32, 12,160, 57,104,101,140,227,244,188,137,200,138,107, 55,239,112, 8, + 98,247,170,178, 46, 6, 98,224,215,138,154,178, 76, 81,230,119, 8,201,142,144,196, 98,247, 52,159,247, 52,176,232, 35, 42,234, +147,130, 94, 85,137, 77,162, 1,235,188,235, 91, 73,227,105, 18, 80, 13, 13,212,146,198, 65, 90,125, 73, 17, 28,204,139, 85,233, + 20,204, 57, 63,235, 45,146,207,115, 35, 88, 4, 95, 73, 98, 80,106,159, 82, 40,174, 16,126,173, 6, 83, 93, 91,241,126, 46, 11, +171,173,244,105,174, 65,140,129,187, 47, 34, 77,151,233, 92,203,217,143,236, 30, 4, 43,221, 35, 90, 35, 36, 55,191,209, 71,217, + 11, 60,231,156,231,183, 93,234, 26, 40,185, 98, 83,140,170,136,238,181,248,123, 25,132,100,186,119,106,117,222, 89, 0,217,230, +174,139, 50,182,177,149,190,197,185, 8, 53,117,130,219, 36,202, 22,139,208,243, 6, 51,235,154, 90,149, 12,164,235,170, 22, 84, +219,136, 87,205,145,202,180,251,145,152, 54,205, 81, 91, 65,202, 46,121,180,245,240,176,100, 13, 92, 98, 1,218, 27,218, 53,228, +177,154,156, 54, 90,141,197,255,174,232,172, 55, 20,216, 41, 41,107,181,186, 64,251,151, 84,123,174, 47, 47,219, 28,151,243, 61, +235, 41,188, 9,243,252, 28, 91,107,247,172,108, 74, 99,205,110, 6,237, 30, 33,202,216, 54,169,137,226,152,105, 74, 75,206, 49, + 42, 11, 93, 39,243,248, 9,116,142,151, 22,165,144,181,118, 44, 90, 60, 74,137, 91,236,218, 82,165, 29, 66,173,169, 79,118,202, +157, 53, 43, 11, 70, 73,136,235,182,151,105, 53, 25, 62, 9,175,243, 53,121, 47,109,247,208,178,226,168,235,157,146, 38,103,221, + 52,104, 84,134,131, 1, 50, 24,128,247, 52, 26,105,130,109,239, 37, 69,251,115, 75, 53,231, 52,135, 58, 33, 70,215,130,186, 22, +122, 55, 10,167, 46,179, 27,173,242,175,108,229,160,133,104,161,108,174,172,161, 19,191,209,182, 88, 44, 55, 40, 20, 42,239,169, + 6, 3,219,116, 69,219, 19,240, 57,143, 46,105, 55,143,174,239,124, 74,196, 59, 21,156, 79, 91,185,138,184,164, 42, 52,241, 66, +234, 45, 46,157,112, 46,154,208, 76, 18, 5,152, 23,142,129,171,210,131,144,180,229, 95,202,245, 40,131, 65,100, 36,145,213, 25, +168,183, 93,192,170,172,116, 17, 43,129,154, 90,136,107, 84, 45, 13,140,182,194,240, 76,235, 46, 55,235,166,143, 59,195, 92,199, +195, 73, 57, 47, 51,112,103, 89,158, 54,231,113, 43,240, 43,224,159, 0,254,106,248,218, 31, 99,116,240,163,156,251, 11,107,108, + 12,132,125,227, 1, 97,102, 37,110, 14, 42,141, 86,163,191,176,125,170, 83, 19,164, 56,212,182, 49,108,159,141,115,136, 79,187, +215,137,179,146,108,149, 86,240,182,216,162, 80,212, 33, 46, 9, 50, 68,230,235,102, 41,104, 45, 53,192,240, 89,160,232,160, 14, +210, 46,226,174,227, 14,238,210, 21, 52, 90,165,196,146, 8, 59,207, 24,176,233,235,246,176,241,215, 95,164,250, 72,164,118,169, +191,184,143,138,175, 34, 35, 7,163, 41, 84,155,150,144, 23,111, 69, 46,185, 28,150,191, 29,252, 25,166,186,219,128,213,191,133, + 35,127, 4, 7,215,208, 91,151,173,152, 54,116, 53,112, 89,181, 84,169,209,238, 46, 37,134,227,134,129,183,218,243,200, 59,223, + 53, 16, 15,147, 50,199,131,228,132,229,221, 51,170, 28, 81, 88,149,134,164,252,185, 20,125,165,130, 21,193,184,146, 82,141,166, +148, 53, 79, 41,198, 46,130, 25,121,211, 78,132,142,122,174, 85,209,186, 83,209,151,189,229,203,157,208,162,213, 38,138,149,222, +168,237, 45,208, 53, 54, 41, 34, 89,235, 6,169, 11, 27,193,248,162, 31,122,110, 88,130, 36, 86,139,130,117,136,164,241,147,155, +224,212, 69,243,150,105, 76,206,243,192,162,200,188, 11, 90,166, 77,115,143,139, 44,228,202, 98,215,156, 14,240, 2,155, 69,152, +137, 48,139, 16,102, 41, 91,181,236,148,218,218,156, 46,164,191,231, 42,105,124,177, 80, 58,165,213,207, 80, 68,236,177,232,242, + 85, 89,202,168,235,248,215, 1, 90,217,113,174,234,146,110, 93,202,160, 43, 54,201, 11,100, 91,149, 80, 2,217, 72,186,146,181, + 97,225, 80,143,172,246, 56, 59,103,153,101,136,196,174, 63,129,209,232, 19,203,211, 79,138, 8, 59, 2, 35, 73,187,203, 73,219, + 66, 54, 57, 93, 91, 92,102,210, 18,104, 30,116,112,208,154, 30,141,173,252,176, 46,168,247,134, 46,135, 31,179, 0,205,156,184, + 45,214,195, 35, 26, 72,104, 17,249,181, 75,254,209, 90, 2, 46, 52,173,202, 14,195,176, 45,111,236,214,137,220,242, 55,167, 66, + 93, 78, 45,154,192,174,220, 68, 39,231,216,115, 91, 91, 45,158,213,162,163,154,230,136,180,192,159, 5,154,117,209,130,185,116, + 54,145,249, 84, 69,238,117,223, 54,190,210,174, 26, 37,111, 98, 86, 70,195,101,202, 39, 20, 27,190,232,194,118,177,185,147,100, + 87,226,215, 61, 67, 80,154,216,160,179, 72, 21, 35,126, 52,196,251, 10,156, 35, 74,147, 34,124, 85,156,119,120, 95, 17, 68,168, + 67, 64,235,218, 82,216,243,169,175, 50, 13, 94, 74,213, 43, 76, 81, 45, 90,182,113,237,132,106,226, 92,231, 33, 47,108,186,146, + 85,172,105,115,151, 20, 85,123,231, 16, 95,181,106,245,188, 53,167, 56,151, 64, 61,119, 5,114, 98,226,175, 20,174, 59,231, 24, + 84,149, 9,232, 82,225,191,119,130,183, 99, 58, 17,196,167,200, 31,180,109,220, 34,206,227, 84,241, 18,210,228,210,152, 60, 41, + 81, 70,218, 88,119,180, 6, 95, 69, 42,175, 12, 53,166, 14, 90, 62,166,156,143, 75,139,107,218, 68,229,136,221, 22, 43,210, 25, +140,210, 78, 94,126, 79, 2,104, 61,146,186,148,101,223, 88,150, 82, 52, 79,128,184, 14,220, 4,178, 59,213,182, 35, 41, 55, 47, + 86,224,226,207,129,229,159,130,231,124, 63, 75,255,252, 37, 46,120,199, 42,205,110, 33, 12, 43,166,117,154,236, 81, 99, 90,140, +124,161, 98,199,132,126,178, 56,217,180,235,113,158,127, 31, 45,154, 95,216, 3, 89,138,189,207, 93,238,223, 94, 76,150,178,113, + 77, 37,243, 11,107, 91,106, 29,157,245,162,183,221,152,108,177,206,173, 98, 67,148,118,235, 94,205,251, 21, 19,217,248,226, 12, +255,219,159, 99,237, 11, 83,178, 94,207, 71,197,123,101,105, 0,203,179,200, 64, 60,238,210, 49,242,148, 11, 97,229,155,147,126, + 33,235, 95,103,159,129,181,191,134,201, 26,122,104, 9, 14,154,148, 62,187,255, 3, 91,106, 7,214, 66, 77, 12, 25,227, 97, 8, + 71, 18,113, 2,200,104,106, 66,199, 17,232, 56,109,240,162, 70,216,233, 65,104,214,208, 91,103,201,121,114,138,107,253,248,172, +120,215,162,191,123,177, 64,200,194,150,138, 11, 17,115,219, 89, 47, 40,193, 9, 33,104, 42, 67, 11,133,128, 39,206,111,112,145, +201,135, 58, 80,180,230,237,162,199,178, 43,149, 22, 98,179,118,175,112,233, 22,115,219, 80,217,132,109, 93,139, 90,231, 32, 6, +105,119, 33, 11,182,169, 71, 6, 22,111, 73,201,124, 94, 83, 75, 19,148, 61,217, 61,221,126,208, 89, 37, 92, 21,170,245, 96,224, + 53, 44, 6,227,118,149,255,159,175, 55, 15,182,109,187,202,251,190, 49,230, 92,123,239,115,238,185,247,190, 70, 79,122, 79, 72, +168, 65, 2, 44, 4, 18,141, 19, 11,132, 93,136, 96,226, 34,193, 21, 87,108,210,144, 30, 87, 58, 10, 59,142,157, 96,167, 41, 39, + 16, 92,130, 74,140, 93,216, 36, 85,164, 82, 41, 39,184,202,105, 42, 78,170, 82,128,177, 33,216, 70,142,145, 82, 70, 52, 22,168, + 1,233, 73, 79,175,185,253,105,246,222,107,173, 57, 70,254, 24, 99,204, 57,215, 58,231,137,170,139,164,251,238,187,231,156,189, +247,154,115, 52,223,247,251,240, 13,207,111,240,238,127,250, 20,191,250, 51,151,248,229,151, 71, 12, 94,140,172,179,187,155, 37, +170, 5, 55, 37,180, 11,125,109,125, 91,252,158, 23, 45,117,204,234, 7,173,233, 12, 26, 79, 32, 32, 48, 65, 16,228, 21, 14,150, + 59,202,220, 83,108, 69, 65,176,217,137,150,239,130, 58, 9,114,195,214,128, 76,106,159,155, 8, 66, 98, 5,178, 79, 18, 35, 10, +247, 92,180, 75,108,232,138, 37,165, 26, 55,139,238,243,181, 87,224, 68, 91, 88,244, 9, 89,105,122,207,185,240, 99,160, 95,125, + 0, 41,107, 59, 29, 90, 44, 46,193,196,126, 76,134,140,141, 11, 73,137,174, 91, 8, 87,177,166,180,230, 99,116, 36,183, 89, 67, +121,174, 85,192,166, 93,163, 18,120, 86,168,125,254,250, 53, 72,192,109,242,130,218,215, 19,225,168,119,229,214, 9,203, 81,151, + 19, 30,244,144,154, 27, 26,143,122,182,117, 5, 72, 16, 46, 89, 21,224,212,245,178,237,153, 39,177,210,132, 58,142, 5, 0,204, + 46,188,235,197,200, 88,217, 4,209,225,136,117,158,236,188,223,108,145,242, 0, 30, 54,182, 99, 71,100,105,152,181, 45,229, 1, + 99, 74, 40,211,100,192, 49,135,128,232,226, 51,175,221, 24, 30,200,188,130,185, 48,150, 59, 91,234,212, 62,177, 51,172,249,230, + 61,182,134, 19, 56,101, 83,155,147, 81,232, 82, 74, 32, 50,188, 93,100,168,163,238, 85,172, 99,207, 41, 25, 2, 47, 15, 24,134, + 12, 38,118,242, 27,213,164, 26,114,149,124, 70, 67,242,162,248,241, 19, 2, 41, 78, 38,192, 98,182, 52, 54,178, 23, 95,164,216, +238, 35,145,217, 40,252, 82, 25,152, 76,229,152, 25,213,195,160,126,108,146,195, 30,105,107,177,158,228,131, 72,189,112,107,219, + 73,231,247,187,242, 93,237, 96,255,153, 30,248,205,249, 92,231, 16,118, 86, 23,191, 3,184,251,131,192,159,252,115,184,243,153, + 25,239,248,212, 5,248,141,183,112,127, 59, 96, 62, 26, 69,206, 94, 23, 93, 10,125,180,239,140,109,174,107,111,100, 89,172, 75, + 40,185, 11,192,137, 35,245,208,241,247,132,185, 57, 27,210,106,150,198, 43,128,141,118,188,205, 4,211, 38, 12, 84,236, 98,170, + 23, 6, 67,252,240, 39, 7,240,219, 56, 90, 92,129,201,184, 60, 31,113,249, 91, 19,116, 86, 80, 86,100,143,103,220, 50,176,157, + 20,121, 2,248,214, 6,244,221, 79,129,222,240, 33, 32,191,195,156, 4,162,192,241, 55,128,199, 63, 6, 92,190, 6,125,204,192, + 61, 0,151,179,181,141, 89,141,159, 26,105,170,224,118,178,232, 19, 96, 26,161,135,226,179,208,160,125, 28,172, 56,147, 51,212, + 17, 9,200, 71, 37, 19,176, 87,240,134, 45,104,131,151,193, 19,157,147,176, 98,124,165,178,178, 13,196,211,175, 59,120, 85, 80, + 9, 89,232,138,136,182, 56,215,174,139,212,110,119,169,175,211, 28,173,125,192,137, 26, 47, 92, 59, 44,171,118, 95, 91,169, 57, +252, 42,191,220, 21,236,228, 73,120,232,226, 81,197,219, 51,233,144,170,179,171,254,143, 26,194, 62,237,186, 74,237,180, 52,203, +232, 99,234,118,207, 91, 50, 94,253, 11, 74,120,255, 31, 60,197,233,191,121, 7,219,159,189,170,214, 53,238, 18,227,184,187, 48, +146, 94, 79,227,162,142,140,113, 83, 42, 87, 15,138,209,213,161, 26,123,216,210, 21, 38, 49, 54, 47, 21,108,211,237,163,187,253, +118,118, 91,219, 72,192, 99,233,149,217,129,252,180, 17,230,232,113,203,226,191, 71,110, 55, 82,191,240, 7, 87,197,239,213, 46, +208,193,223,176, 9,237,163, 26, 52,181,216,229, 39,143, 52,141,124,128,212,105, 41,118,190, 34, 56,135,141,242,147,183, 37,167, +158,135, 62,106,103,159,243,226,176,207, 40, 63,243, 21,229, 57,155, 48, 82,174, 73, 63,175, 99, 78,251,157,255,224, 95,239,110, +108, 50,189, 43, 15,145,221, 50, 19, 93, 61,164,198,181, 30,221,180,111,215, 67,179, 16,104,106, 15,209,137, 85, 81,247,204, 4, +211,127,238,192, 72,181, 19,167, 37, 65, 79, 87, 52,123, 44,120, 42,161,159,208, 58,238, 78,126,206,217,100, 84,155,211,136,130, + 43, 98, 55,231, 92, 10,142,211,132,195, 60,161, 76, 99,181,160, 1,203,253,127,191,223,142,226, 71,165,128,230,201,154,221,148, + 81,105, 92,206, 49, 97, 21,156,230, 13,238,156,222,194, 40,130,253,120,196,241,112,133, 50, 78, 62,169,190, 62,137, 85, 27, 88, + 54, 59,219, 98,180,162, 77,125, 30, 98,170,200, 48,143, 87,141,252, 93, 53,101,123,170, 34, 8,179,172, 49, 56,101,100, 78,181, +155,108,188, 94,139, 98,205, 57, 33,109,118,200,195, 96,127,142,185,238, 10,153, 21, 36, 77, 46,166,101,114,236,100,100,114,183, + 15, 93, 82, 49,161, 15,181, 29,196,204,130,193,173, 20, 3,169,119,187,193,231, 85, 83, 54, 66,124, 47,191,241,169,122, 36,146, +240,162,118,180, 83, 81,157, 35, 30, 62,117,106,219,175,249, 69, 64,146, 21, 1,229, 4,200,123,159,213, 60,239,221,224,108,227, +121,218,218,158,253,203,254,109,208,135,127, 2,207,254, 25,194,240,233, 43,108,158,222,226,254,201, 22,147, 88,138,121, 17, 65, +138,220,120,132,117, 40,222,167,226,247,122,248,139,169,225, 52,125, 44,100,183,120, 0,101,196, 20,241, 10,176,219,225, 8,166, +255,163,149,107,129,186, 93, 89, 28,126,169,250,147,217, 94, 67, 16,144, 61,148,193, 25,176,197, 17,183, 85,105, 81, 59, 24, 65, +113,101,188,178, 93,150, 67, 17, 12,131,133, 61, 12,163, 32, 99, 0,127,231, 25,240,190,247, 2,187,239, 48,135,129, 42,112,249, +191, 1, 79,126, 10,120,248, 4,122,121,215,230,140,231, 19, 48,205, 14, 62,247, 10, 98,172,251, 2,159,245,205,192, 60, 67,247, + 98, 39,220,193,143,164, 13, 3,233,224,116,158, 51,160, 92,180,121,169,138,193,105, 78, 18,176,201,224, 50,129,187, 21,211,130, +234,129, 46,165, 80,219, 62, 14,162,203, 0,130,190,227,171,216, 92,109,160,144,213, 5,190, 16,244,116,118, 42,155, 37,120,103, +121,195,154, 35, 50,204, 37, 89,107, 28,104, 12,174,208,145, 54, 81,209,110, 12,207, 97,241,210,118,145, 9,154,165, 38, 58,138, +112, 52, 76,142, 13,141, 75, 44, 84,248,245, 66,247, 14, 56,124,232,115, 80, 7, 97,105,100,145, 66,246,185,164,248,153,255,245, + 28,227, 79,159,227, 69, 8,118,201,192, 76, 2,198,134,212,138, 31, 93,122,164, 99,146,128, 46,103, 59,105,135, 17,213,102,117, +138,215, 54, 16,212,140,101,154,215, 90,115, 48,160,157,117,234,175,217,220,145,200,212,161, 65,147, 11,200,230, 78,123, 42, 29, + 72, 72, 17,161, 71, 46,248,165, 38, 51, 30,200, 45, 73,218, 0, 50,123,255,187,178, 11, 86,135, 14,113,155, 86,106,247,173,167, +140,165, 46,177,237,177,127,223, 33,180,123,150, 45, 29,237, 1, 3, 79, 92,184,122,219,133,199,231,164,139, 80,155, 30,248, 19, +175,195, 22,150, 53,176,247,130,101,132,122,182,122,179, 7,246,250,171, 30, 78,149, 3,236,211,239,186,125,242, 19, 58,129,109, +247,239, 14,174,152,135, 11,155, 79, 42,165,143,112, 80,197,168, 38,150,139,145,249,184,198, 46,175,172,110, 3, 53,138,223, 76, +141, 58, 55,119,197,219,210, 47,212, 79, 40,173,233, 65,209,133,126,131,137,171,223, 92, 59, 38,187,177, 86,212,166, 64,100, 90, +155, 89,108, 68, 30,233, 72,175, 59, 25,168, 5,166,103,147,184, 90,157,138,149, 64,137, 25, 41,155, 23,160, 68,234,155,152,120, +249,108,179, 67,202, 3, 84, 21,135,162, 80,153, 22,200,183,102, 51,180,239,223, 47,111, 90, 82,243,251, 31,154, 86,187,245,168, +112,220,119,206,204,200,236,187,111,207, 89,207,105,112,197,238, 12,242, 2, 32,172,103,214, 88, 15,200,219, 19,228, 97, 99, 94, +117, 17,171, 62, 2, 74,224, 47,114,242, 7, 69,157,186, 67,162,213,187,170,126,177, 23, 53,166,245, 76, 82,247, 53, 2, 69, 73, +126,121,176,237,233, 21,230, 63, 54, 86,175, 29, 16,137,213,194, 77,152,124, 20,171,109, 96,232,227,123, 83,172,133,173,224,137, +237,107,233,204, 21,242, 5, 24, 95, 3,142,143, 77,117, 77, 3,144, 79,129,225, 37, 96,243,110, 19,123,213,180, 55,191, 60,242, + 63, 3,188,227, 17,232, 47,254, 52,238,254, 88,198, 87,254,202, 37,238,239,103,124,241,108,131,139, 77,178,145,148,174, 19,162, + 18,136,220, 55, 46,182,163,141,189,121,140, 58,219,174,181,184,163,192,239, 62,170,102,132,166,204,142, 29, 30, 45, 85,182,253, +199,159,107,209,228,108,113,127,255, 6, 17, 28, 99,100,235,133, 87, 32,130, 99, 95,184,113, 31,103, 17,134,170,243,195, 60, 24, + 60, 51,176,133, 98, 56, 0,252,230, 45,248, 59,159, 5,206,254, 89,128,223, 98,213,198,254,231,129,123, 31, 6, 30,110,161, 47, +223, 54,176,246,254,104, 34,185, 67,177, 83,109,195,141,249,121,226, 55,176, 8,116,242, 69,225, 69, 1,206,221,112,157, 0, 61, +177,211,148,240,196, 94,136,233, 41, 19,224,165,231,171, 12,150,178,128, 88,145,242, 42,124,163,187,175, 67,112, 54,251,115,195, +222,209, 74, 71, 73,161, 46, 59, 65,168, 89,213, 84,174,119,225,235, 78,162, 14,209,220,221, 82, 96,242,142, 5,134,243,134, 61, + 39, 9,181,177, 52, 53, 25,188, 80,243,169, 43,150,118,163, 45, 90,166,120, 14,237,138,103,106,143,254,158,151,174,224,224, 27, +138, 0,234,244, 24,236, 68,174, 89, 9, 39,158,247, 61,193, 41,138,218,152,245,191,182,159, 77,254,192, 54,234, 20, 81,100,106, +251,253, 25,203,144,142,254,181, 41,171, 66, 40,198,253,209, 54,164,232,230,176, 76, 87,171,129, 31, 61,228,100,161,134,239,132, + 79,104,169,101,232,196,169,163, 51,222,115, 55, 42,159, 53,244, 39,132,141,104,197, 11,247, 69, 90,114,187, 84, 38,251,185,199, + 96, 58,132, 86,128,218,196,115,232,206, 86,233,128, 50,240,139,153,187,215,124,116,145, 95, 15, 56,186,235,108,142, 43, 69,229, +196,159,184, 90,254, 42, 58, 94, 93, 70,218,198, 69, 60,120, 98,219, 93,182,221,252,209, 19,221, 84,151,112,153,133,245,208, 95, +196, 43,255,126,230,110, 85, 64, 93,191,223, 79, 78,102, 88,138, 91,134, 37,132, 62,113, 61, 74,248,248,237,245,233,199,226,180, +184,136,123,234,101, 20,159,135,206, 9,145, 58,152, 79,193,114,101,164,253,247, 83,159, 81,178,152, 15,245, 32, 21, 78,224,100, +234,244, 41, 10,148, 88,121,116,141, 45,251,152, 28, 85,241,174,139, 78,125,237,179, 39,220,140, 91, 87,111, 74, 33,132,132, 12, +164,228,162, 59,182,130,250,176, 7,246, 87, 72, 57, 99, 59,108, 32,219,217, 52, 57,101, 94, 17, 20,151,249, 17,139,228,152, 20, + 80,128, 62,193,171,114,225, 27,175,157,153,145, 82, 66, 78,102, 93, 35,230,186, 67, 87, 82,187,128, 69, 64,201,246,157,236,248, +215,180, 25,144,182, 39,200,121,176, 10, 89,102,219, 19,248,195, 81,105,176,158,116, 86,197, 10,209,129, 42,217, 11, 17,112,148, +216, 93,177,248,152, 73, 43, 31, 24,126, 72, 19,139,189,185,190,231,103, 5,242, 64,224, 29, 65, 95, 30,129,105,219, 41, 50,182, +166,138,198, 19,127, 12,142, 62,154, 15,193,149, 63, 30,202,192,124,110, 59,222,241,137,185, 63,105,231, 23,251,203,192,240, 89, + 96,120, 43,176,121, 59, 48, 60,239, 99,124, 15, 10,200,255, 18,240,229,111,133,254,240,127,139,237, 71, 30,226,133,191,126,196, + 83,159, 58,224,181,243, 9,247,239,102, 92,109,178,117,238,218,209, 76,209, 68, 54, 73, 58,251, 18,213,230,220,170,181, 14,161, +197,196,190, 79,181, 27,197, 68,216,126,136, 72, 53, 67, 88,145,227,153,188,218,169, 54, 99,247,234,120,187,107,176, 21,237,233, + 72, 93, 32,200, 54,163,138, 36,139,171,182, 51, 3,155,172, 56, 17, 96,251, 64,144,110,157,128,255,253, 59,192,243, 31, 0,248, +247,218,235,115,252, 40,240,218, 15, 66,191,144,128,151,110, 1,175, 78, 54,114, 31,103,232,249, 84,151,163,116, 39,219,141, 53, +251,109, 73,126, 85,205, 98,180,150,203,217, 10,128,139, 14,202,141,193,103,172,175, 0,121, 0, 78, 63, 1,156,190,217,199,253, +163,189,206,131,171,253, 75, 7,192,232,162, 87,209,141,109,227,105,234, 93, 32,125, 55,223, 79, 61,194, 47, 43,235,157,223,181, +225, 89, 7, 93,238,196, 97,182, 54,234,108,132,221, 94,176,103,124,235, 13,136,218,190,227, 85, 90, 18,218, 34,164, 36, 98,149, +231, 98,147,129,156,196,189,238, 77,181,189,130, 13, 47,190, 15, 38, 67, 62,159, 49,225, 93, 91, 35, 61,126,238,114,198,232,239, +151,168,249,251,137,237, 48,159, 96,228,187,212, 89, 98, 3,122,146,169,187,188,169,167, 36, 82,229, 96,160, 83,119,215,239, 75, +163,203,210,133, 40, 74,209,209,145,125, 13,216, 3,159,137, 60,167, 66,155, 16,107,232,132,192,221,219,129, 43,116,240, 30,109, + 44,117, 82,235,222, 12, 8,146,172, 8,246, 96, 36,203,194, 16,100,111, 72,198,107,121, 12, 81, 88,153,204,118,203,158,168, 23, + 95,211, 39, 60, 83,199,220,231, 94, 0,136,118, 25,238,221,134,120,161,209,225, 42, 6, 34,156,145,105,115,174,168,249,231,165, +251, 28,104,199,133, 39,239,188,181, 75,129, 41, 55,116,185, 11,203,157, 95,138,167,141,179,233,226, 64, 90,132,200,132,248,110, + 82,193, 78,200,160, 74,176,201,192,149, 90,240, 75,113,186,154,212,166,237,250,180, 37,246,231,165,251,140,207,139,123,170, 75, +246,139,238,153,172, 96,141, 2, 42, 43, 28, 40,195,152,181, 88,195,226,205,105,143,157, 21, 98, 71,221,182, 37,125,242, 63,171, + 76,208, 34,142,121,189,174,245,160,245,115,210, 63,131, 53, 54,220,102, 68, 42, 2, 41,214,177,111, 56, 65, 61, 56,106,158,103, + 20,153, 49, 31, 38,228,205, 22,219, 97,107, 63,239, 4,232, 44, 46,193,108, 95,120, 49,126, 15,255,166, 89,201,120, 17,124,223, +103,199,134,162,143,185,243,160, 83,219,129, 51, 86, 51, 47, 38, 91,250, 19,192,121, 64,222,238,144, 55,131,125, 40, 75, 1,100, +246, 7,183,137,223, 64,228,227,100,187,220,137, 77, 49,207,108, 30, 66, 22,174, 84,181,218,223,104, 40,241,125, 20, 77,246,145, +202, 68, 6, 26, 16,123,240, 6, 88,103,192, 16, 28, 68, 48,188,116, 64,126,114, 2, 26,238,248, 13, 58, 0,252,148,177,223,213, +163, 59,245,178, 13,126,244,202, 46,124,221, 1,227,203,246,234,150, 2, 76,159,243,131,126, 0,242, 22, 56, 14, 64,254, 28,144, + 62,106,185,221,249,141, 54,186,207, 79, 1,252, 12,144,190, 21,244,244, 87, 0,223,241,215, 64,223,244, 81,156,254,163,115,188, +245,127, 24,241,244,111, 30,112,255, 86,193,195,167, 7, 92, 73,131, 49,196, 97, 22,196,164,152,160, 80, 93,151,232, 34, 24,131, + 28,239, 26, 7, 63,177, 19,235, 4,117,124, 26, 81,139, 89,165,217, 49,252, 2, 33,191,200,227,214, 96, 47, 42, 70, 89,101, 18, +248,200, 95, 33, 72,108,100,166, 20,104, 95,182,247,104,195,138, 13, 91,215,176,125, 44,200, 60, 32,253, 71,119, 65,239,251, 61, +192,246, 95, 4,210,179,192,252, 24,120,244, 95, 65,239, 29,129,151,223, 4,188, 54, 2,247,142,208,227,108,254,118, 47,254,128, + 4, 28, 5,148, 5,216,165, 38, 4, 40,197, 78,178,189, 71,154, 61,118,144,121, 2,112, 96, 96, 18,232,209,210,241,112,122, 31, + 24,239, 1,167,129, 4, 46,192,156,128,109, 2,205, 51,136,172,235, 27,177,236,106,226, 69,147,213, 94,177, 79,161,142,124,229, +196, 22,214,194,115,120,103,253,105,211, 37,136,164,183,101,205,235,253,111,252, 79,159, 96,241,170,203,234,133, 97,189, 24,105, + 13,111, 70,103,219,193,106, 47, 31,207,238, 9, 24,111,123, 46, 99, 36,197,103,238,205, 40, 52,215,142,149,186,125,183,220, 84, +192, 16,225, 14, 17,190,249,185, 13,222,242,238, 1, 31,255,196,136,223,186,156, 23,135, 92,216,220,142,176,231, 48,173,232,135, +189,176,176,247,227, 19, 53,171,228, 90,145,189,176, 63,145, 39,131, 81,103, 81,234, 68, 98, 21,221, 73,109, 7,171, 93,144, 85, +172, 29,135,174,235, 27,125,215, 30,218,128,177,155,116, 72, 71,216,204, 68, 70,211, 99,219, 37, 83,213, 24,152, 48, 18, 82, 64, + 40, 85,161,173, 94, 8,164,238, 82, 61,141,203, 52,112,168, 20,175,151,141,163,117,229, 99,239,187,231,210, 93,202, 2,197, 1, +132,135,254,209,223, 46, 86, 43,218, 32, 61,125, 52,173, 23, 84,115,215,197,110, 98, 50, 67,203,247,191,191,147,194,182,120,226, +187,253, 30,235, 90,250,245,201,162, 51,181,239,245, 74, 4, 59,102,100, 88, 10,224, 93, 40, 46, 65,120, 66,192,209,223,100,233, + 86, 65,252, 58, 83,174, 88, 77,245, 89, 0,189,182, 34, 92, 83,235,209,219, 64,192, 9, 39,204,153,113, 80,215,103, 69, 8,139, + 20, 72, 41,134, 20, 6, 32,204,139,203,152,217,246,224, 51, 39,232,100,202,245, 30,115, 44,175, 35,226,148,192,110, 71,222,168, +168,107,161,172, 16, 44, 34, 32, 21,155, 2, 56, 53,142, 55, 3,198,194,152,143, 71,148,113, 66,222,110,176,217,108,189, 56,157, +236,140, 81, 99,170,132,179,161,238, 35,123,242, 82,148,247,139, 93,187,118,123,105, 31, 81,112, 78, 45,137,173,194, 26,218, 40, + 79, 89,145,192,246,103, 19, 35,101,147,241,179, 20,148,105,118, 48,130,250, 37,220, 14,175, 70, 10,234, 87, 0,236,255, 92,220, +180, 47,104, 39,164,141,236, 75,114,159, 33, 21,187,252, 85, 65, 69,161, 78,242,178, 58, 90, 48, 36,197,113, 82, 60, 24,129,187, + 7,193,201,253, 2,228, 59,221, 41,117,199, 61,204,238, 87, 47,143, 93, 16,183,113, 97,213, 3,239,212, 15,246,159,170,192,241, + 2,120,164, 80,246,233,196, 86, 45,171,114, 24,128,225, 55,129,124, 2,164, 51, 32,191,201,114,193,183,239,183, 78,126,251,131, +192,155, 62, 11,124,251,223, 4,127,211, 47,226,206,207, 61,193,233, 95, 61,226,238, 23,143,184,247,108,194,227, 13, 99, 82, 66, +145, 22, 40,172,218,239, 5, 61, 88, 71,189, 93,151,149,240, 45,172,105,210, 82,189, 50,195, 17,137, 45,134, 51,117, 99,124,237, +132, 58,209, 8,167,254, 50, 17,223, 67,106,105, 65, 47,108,169, 99,153, 26,108,132,201, 84,188, 57, 1,187, 34, 56,217, 3, 89, + 50,210,127,124, 23,244, 45, 31, 0, 54,127, 28,200,239,178,111,244,248, 17,224,252, 37,224,252, 25,224,188, 0,143, 39,232,126, +130,202,232,227, 41, 95,242,110,124, 32, 71,158, 69, 26,163,163, 25,192,113,178, 86,229, 48,155,124,124, 95,108,143,126,167, 24, +166,173, 36,168, 38,208,120,116, 15,251,209,233,129, 78,218,219,154,234,149,198,229, 72, 43,186,162, 88,121,228, 58, 10, 39,204, + 22,140,187,184, 64, 99, 76, 23,175,225,228,251,119,238,133,112,157,112, 38,119,187, 92,237, 68,106,253, 57, 36,180, 68,243,162, +131,111, 68, 68, 37, 24,160, 98, 5,150, 82,191,139, 84, 27,165,118, 23,251, 12, 96,235, 87,226, 83,204,248,125, 31, 60,195, 27, +254,194, 11,120,245,207,126, 1,159,250, 59,179,243,174, 27,226,185, 87, 29,235, 74,152,182, 35,224,133,129,145, 7,224, 31,127, +102,194,199, 30,140, 53,250, 56,246,185, 17,229,155, 86,153, 4,165,195,124,246, 73,112, 88, 81,211,214, 34, 65,209,101,244, 42, +212, 25,220,157, 35, 64,186, 17,113, 19,124,209, 34,231,156,176, 20, 90,201,234,130,232, 33, 42, 49,209, 52, 75,150,239,248,201, + 58,206, 1,166,235, 17, 87, 29,176, 42,164,216, 33,157,124, 58, 80,193, 40,145,201,237,123,242, 1,141,230, 55,118, 98,193,209, + 87, 22,235,238,111,125,185,150,134, 21, 89,188, 94, 83, 23, 85, 29, 84,190,129, 90, 19, 36,212,118,178,218,141,203,201,245, 17, + 73,151,118,193,254,125, 15, 1,219,222,139,166,125,199,250, 23,234, 47,179, 54,133, 58, 70,178, 96, 8, 51,197, 46,161,157, 11, +229, 50,247,206,141,246,179, 73, 87, 12,233, 74,216,169, 93,166, 58,187,250, 63,185, 45, 45, 7,228,104, 85, 8, 36, 0, 39, 76, +216,229,132, 43, 78, 96, 50, 31, 72,124,174, 98,242, 34,218,214,204,228, 5, 68,114, 33, 93, 78, 70, 7, 5,180,114, 18,250,162, +171, 47,172,117,241,153,215, 14, 17,219,141,245,189, 24,157,139,233,189,192,132, 76,140, 97,216, 32,109, 7, 28, 64,152,199, 3, +100,182,142, 93, 55,155, 54,110,137,194, 70,125,149,101, 85,101,199,238,236,128, 38, 1,156,169,149,180,170, 5,137,228,140, 60, + 12,246,207,164,212,200,204, 32,190,241,144,253,211, 27, 73, 54, 9,156, 51, 56, 49,168, 20,136,204, 80, 41, 80, 7,232,179, 42, +152,115,165,197,177,123,131, 99,164,111, 19, 4,139,164,171, 47,150, 10,164,204,181,116, 47, 69, 48,137, 88, 55, 79,254,248,178, +121,134, 38, 81, 20,255,129, 51,219,155,240,104, 86,156, 23,197, 41, 19,228,179,151, 72, 28, 53,237,224,244, 56, 87,189,203, 4, +140,143,128,233,220, 99, 59,189,143,144,217, 41, 55,197, 61,209, 9,250,144,128,203,226, 86, 47, 1,210, 0,108, 4,184,117, 4, + 54, 87,160, 91,175, 1, 39,191, 3,156,126, 12, 56,249, 8,112,250, 71,129,221,215, 2,249,107,140, 39,255,220,191, 0,252,177, +255, 14,249, 3,191,140,167,127,232, 10,183, 62,122,196,131,167, 20,175,158, 38, 92,177,145,205,180,248, 69,236,243,161,226, 43, +127,144,127,201, 24,203,166,198,191, 14,241,202,228,116,179,129, 66,217,171,222,173, 53,219,143, 22, 44, 4, 24, 97,245,176,192, + 24, 66,164, 32,155, 99, 91,235, 1,149, 56, 33,195, 94, 95, 26, 8, 36,100,126, 76, 98, 12, 40,216, 22, 32, 29, 18,210,119,237, + 64, 31,250, 32,176,253, 1, 32,189,221,118,220,227, 39,129,199,127, 21,250, 88,129,171, 1,184, 56, 64,175, 70,232, 60,154, 80, + 37,164,215,147,135,203,108, 59,226, 78, 96, 14,103, 7,148, 31,102, 99,121,206,165,209, 40,164, 3,214, 87, 14,190, 99, 44, 40, + 25, 41,240,105, 6, 31, 7, 80, 73, 72,251,185, 93, 2,106, 21, 60,121, 81,107, 35, 59,191,156,184, 49,224,129,101,152,206,181, +145,181, 46, 53, 41,178,218,189,133,240,148, 58,185, 49,173, 56,225,241, 32, 14,238,102,156,252,247,178,239,249, 69,218, 51,203, +170,182,250,208, 22,214, 3,237, 44, 88,158, 6,118,139, 8,207,159, 18, 18, 4, 95,248, 51, 95,196, 71,255,193, 30,133, 21,236, +227,126,137, 14,182,142, 78,237,178, 72, 30, 25, 26, 0,143, 7,170,248,200, 43, 19, 62, 63,154, 62,102,227, 99,213,190,211,207, +206, 20,239, 23,129,125,209,180,238,114,210, 74,115, 16, 59,113,193, 82,231, 16,228,183,212,133,187, 20,119, 41,172,199,160, 10, + 93, 30,178, 29, 42, 91,169, 53, 19,145, 11,111, 54, 48,138, 0,100, 36,143,232,132, 11,179,226, 16,159,213, 71,168,106,196,244, +172, 97,205,210, 90,115, 22,109,182, 81, 90, 41,200,185, 35,233,237, 60,253,237,194,247, 47,195,202,170, 90, 47,225,213, 37,222, + 10,126, 59, 63,139, 39,191,197,180, 35, 57,211, 32,146,210,160,171, 41, 19,150,176,149,158, 37,191,166,226, 21,135,247,204, 30, +120, 67, 14,224, 25,130, 82,184,176, 72,155,197, 47,166, 29,213, 89, 64,138,137, 25,163, 2,231, 80, 15,227, 2,230,110, 79, 21, +133,100,233, 26,144, 21,173,182, 70,232, 82,151, 46,154,233,186,206, 85, 59, 24, 82,160,203,137,184,174,155,227,253,158, 92, 38, + 71,157,118,172,196, 63, 39,152,176,155,236,206,113, 38,118, 43, 98,110, 0, 65,233, 13, 66, 77,237, 94,237,228, 43,106, 35, 88, +218,132, 32, 30, 90, 34, 32,243, 14, 39,187, 45,142, 4,200, 52, 65, 75,193,144, 7,232,206,182,195, 82,196,159,123,110,121, 7, +113, 96,145,106,173,240, 35, 48,190, 39,186, 41, 28,147, 55,100,195,215, 21, 35,104,176,251,208,137, 25,196, 9, 57, 15, 64, 82, + 87,109,251,229,222,147,234,136, 77,225, 94, 49,131, 92,177,177,213, 35, 79,214, 1,234,108,150, 32,134,123,160, 41, 24,244,228, +251,245,134, 80,181,221,165, 56,145,139,192, 62,119, 19,241,205,131, 10,114,178,136,201,215, 14, 86, 60,104, 82,232,111, 78,192, +120,101,101, 30, 50,192,103, 64,122, 26, 40, 7,187,212,203, 30,152, 30, 57,100,102,107, 74,118,157, 60,233,131, 91,194, 91,114, +162,196, 49,146, 77, 74, 4, 34, 3, 57, 65,135,236, 92,201, 9,244,220, 63, 2,158,251, 12, 80,254, 40,112,251,187,205, 19,143, +175, 4,248,135,128,119,254, 50,232, 39,254, 10, 54,255,211,103,241,220, 79, 29,112, 50, 77,120,229,169, 1, 23,196,152,185,133, +185, 80, 63, 10, 15,166,187,239,175,147,154,248,222, 4, 90,140, 82, 74, 99, 53, 39, 31,189,138,221,105, 34,203, 11, 41, 18,245, +170, 8, 63,217,133, 62, 73, 49, 37,178, 74, 23,180, 97, 43,152,224, 70,167, 68,160,217, 71,172,172,200, 52, 99, 43, 64, 86, 70, +122, 62,129,191,231,221,192,233,127, 0,208, 91, 92,180,246, 10,240,248, 47, 0,247, 94, 4, 30, 63,227,212,140, 2, 29, 71,211, + 78, 68,168,135,167,149,144,114,123, 42,134, 8,188, 38,139, 86,219, 23,127,237, 11,112,144,142, 21,170, 30, 31,235,129,225,105, +103,235, 16, 20, 63,213, 19,240,116, 2, 61, 86,240,101, 6,243, 92,245, 28,236,187, 81,113, 5,114,176,159,227,196, 9, 60,230, +216,133, 93, 4,226,180,160,209,225,174,169,175,169, 89,152,250,188,106,213,165,102, 53,210,192,164,235,145,139,119, 35, 73,218, +133, 24,137,108,203,195, 89,187, 3,180,253,190, 84,184,135, 66, 50,240,138, 42,190,248,145, 61,238,237, 5, 83, 82,108, 32,158, + 40,104,170,100, 66, 88,149, 26, 47, 94, 59,223,242,164,138, 7, 99,241,245, 65, 88,225,186,159, 69, 91,161, 67,157, 82,189,199, +127,234,170,147, 90,239,204,141, 11,222,132, 78, 11,237,174, 71, 78,198,229, 92,148, 42,199, 29,221,142,188, 6,165,116,214,205, + 38,226,178,247,121, 88,121,182, 75, 8,183,186, 78,171,238,125,197,138,166, 66,234, 10,125,109,130, 55, 52,164,109,255,222,231, +110,108, 28,246, 53, 80,243, 90,199, 24,251, 82, 2,220,210, 8,108,201,223,199, 64,217, 82,119,233, 6, 24,103, 19,100, 58, 23, +215, 77,213, 57,160,173, 83,247,115,190,172, 71,195,218,108,204,158,132,189,152,156, 96, 53,161,137,220,245,192, 30, 23,103, 36, +204,126,193,111,220,140, 51,122,212,237,232,231,117,116,224,234, 32,170, 72, 65, 99,109,226, 54,234, 71,146, 55,234, 67, 91,193, + 86,145,181,126,233, 6,207,127,234, 86, 4,189,120,143, 18, 67,136, 49,139, 66,146,175,146,161,102,211, 37,245,213,101,139, 30, + 55, 0,145, 9, 7,136,109, 28, 95, 68,204,159, 46,101,241,157,209, 77,147,165,149, 45,176, 29, 31, 38,174,219,228, 1, 24, 6, +204,211, 12,153,103,168,171,222,145, 18,138, 40,104, 30,145,242,128,147,237, 14, 37, 15, 40,101,178, 36,205,221, 45, 28, 41,161, +140, 71,228,196,160,156, 77,184, 10,255, 97,250, 47,198, 62, 99,165,152,237,251, 1,192, 41, 33, 15, 22, 89, 39, 50, 87,191, 28, +197,222,155,204,255,205,137, 45,205,102, 16, 96,158, 33,197, 54, 62, 84,188, 91,135,237, 54,197,103,137,196,201,253,228,210, 20, +125,222,101, 19,168,146,212, 64, 4, 77,230,103, 7, 19, 56,251, 94,190,113,243,236, 34,240,138, 84,139,225, 56,171,193,221,187, +254, 39,147,226, 98, 84,220, 25, 20,178, 97,148,207, 95, 33,239,127,221, 70,226,128, 73, 86,248, 13,128,190, 2, 76,143,237,114, +150,131,117,228,124,102, 23,112,192, 75, 72,218,163,234, 19, 5,236,103,191,156, 86,165,116, 34, 83,110,111, 19,244,139,103,192, + 91, 47, 64,111,255,239, 1,122, 8,220,250, 94, 32, 63, 7,240, 45,128,190, 29, 56,251, 58,208,247,253,215, 72, 95,243,243,184, +243,159,141,216, 62,152,241,224,142,224,225,134,112, 84,170,137, 92, 49, 46,227, 16, 84,105, 39,162,153,151,202,146,193, 71, 92, + 21, 70,227, 39, 91,136, 66,226, 19, 41, 62,128,168,158,209, 4,140,163,160,136, 89,155, 2,153, 26,127,145,138, 5,233, 36, 38, + 36,175, 16,152, 20, 3, 41, 54, 89,145,103,182, 66,240,219,111, 3,207,255,187,230, 10,208, 1, 56,252, 58,240,232,135,160,175, +252, 14,240,210,109,123, 29, 47,246,144,151, 14,144,199, 19, 52,140,202,170,203,116, 20,245,211,119,203,253,242,209,118,233, 87, + 5,216,139,165, 23, 41, 64,194,109, 30,216, 51, 64,137,219,220, 62, 13,192,150, 64, 91, 6,157, 16,240,200, 34, 35,169,227,235, + 71, 81, 73, 36, 94, 44, 82, 45, 62,133, 0, 46,253,104, 48,240,174,173,133,162,200, 84,184, 97, 31,220,119,165,133,250,188,114, + 63,176, 57,108,113,221,191, 35,254,169,163,118, 64, 14, 68, 40,172, 77, 83,161, 84,187, 83,238,118,156,169, 59, 4,199, 89, 48, +122, 81,183,205,246,231,132,218,216,151,161,181, 91,231,149, 15, 62,193,106, 90,246,213, 78,212, 79,226, 57,226,169, 59,196,122, +191,248,188,210, 35,160,219, 7, 43,150,151, 77,191, 46, 96,213,133, 91,148,234,240, 0, 0, 32, 0, 73, 68, 65, 84, 31,153,171, +160,137, 22,250,132,232,152,230, 8, 25,234, 68,129, 61, 9, 49, 44,128,201,171,217,158, 63,111,151,191,165,207,165, 46,128, 90, +220,222, 55,118, 94,106,214,182, 99, 15,250, 92,162,165,127,126, 61,186, 14, 24, 80,234, 70,203, 59,255,217,206,213, 4,109,141, +139,160,109,229,163,215, 3, 61,178,182, 92, 2,114, 90, 94,228,220,119, 91,187,133, 58,188,116,195, 46,233, 68,108,125, 71, 43, +120,253,255, 91, 43,210,129, 38,230,155,123, 39,129, 54,215,132, 86, 44,107, 87, 32,213,167,172,217, 10,171,127,124, 45,144, 83, +186,214,165,175, 59,223,254,178, 79,139, 41,143,143,228,217,194, 65, 4, 97,131, 22,156, 16, 35,167,140,189, 42,138, 76, 94,116, +115,253,160, 55,122,139, 57,169,192,108, 22,213, 18,197,255,117,225,227, 53,135,202,235, 88, 43,225, 1, 90,156,135,246,249,242, +149, 52, 68,193,217, 34, 85, 45,161, 84,176,201, 25,154,179,253, 60,121,192,201,102, 3, 85,193,164,132,253,113,223,212,239,210, +129,100,184,243,123,163,235,226, 65, 14,148, 73, 9, 36,197,147, 40,154,104,160,134,191,248,172,196,160, 49, 25,154, 0,153, 39, +232, 52,161,232, 17,154,146, 81,227,180, 89,112, 36, 9, 56, 9, 4,201,210,215,220,234, 66, 29,175,176,248,131, 69,170, 16,110, + 94, 63,234,248,124, 97, 47, 10,111,225,236,220,236,224,117, 15,217, 42,239,131, 0,156,252,128,216, 50,244,162, 0,247,190, 8, + 60, 51,187,101,109,107,160, 25, 69,227,135,207, 7, 79,109, 59,119,198,228,109,179, 96,233, 33,228,191,230,101,175,234, 21,241, +244,143,150,203, 11, 2,232,130,129, 29, 3,151, 9,120,116, 2,125,124, 0,126,207,223, 0,189,241, 51,192,217,159, 0,134,119, + 24, 36,133,223, 4, 12,127, 30,244, 45, 95, 5,252,228, 79, 97,247,103, 47,240,198,151,102,236,238, 20,220,219, 38, 28, 8, 40, +243,210,165, 96, 9,104,188,176,255,176, 15,226,114, 28,230,188, 76, 7, 51,235,224,242, 1, 10,208, 16, 59, 83, 64, 38, 64,102, +241, 0,132,110, 84,111,177, 56,182, 99,100, 32,177,212,170, 62,145, 98, 96, 27,191, 51, 18,240,108, 6,222,247, 14, 96,251, 94, +123,220,198,223, 1,126,231, 95,129,126,122, 2,246,207, 1,219, 45,128, 9,250,185, 3,228,254,222,166, 64, 91,110, 65,237,125, +203, 23,144,239, 80,229,205,197,160, 52,163,119,233,197, 59,245, 32,251, 30,139,143,239,197,166, 43,228,156, 52,190,101,171,150, +156,157,194,145,129,204,245, 66,239,205, 52, 33, 46,148, 30, 16,210,227,231,147,125, 89,237, 60,193,232,186,247,222,242,214,187, + 8, 4, 43,223,115,167,158,143,253, 98, 86, 11, 92, 49, 7,130, 46, 4, 78,150, 87, 99,250,149,112, 95,134,178, 93,253,210, 45, +165,161, 55,163,181, 81, 81, 92,138, 59, 65, 68, 43,100, 67, 96,227, 79,118, 62,118,189,216,123,114, 94,191,203, 21,173, 65, 26, +220,113,201, 55, 88,166, 0, 78,139,198,139, 58,116, 15, 86,199,177, 94, 83, 12, 23,159,142,104, 71,244, 91,231,104,211,194, 66, +214, 52, 62, 49, 82, 7,173, 70,237,126,193,136,175, 46,106,209,210,141, 82,161,186,140,129,173,107,132,182,142,208,149,152,146, + 87,204,135, 78,146,116,237, 64, 79, 93,238,124,164,177, 21, 31, 81, 71,120,205, 41, 20,183,253,243, 48, 5, 32,199,183, 81,243, + 10,180, 19, 93,238,142, 34,169,205, 68,115, 12, 43, 82, 65, 13,169,189, 24,101,251, 65, 44, 43,161,165,126,137, 75,125,125,161, +235,106, 45, 16, 59,119, 46,173,158, 94, 90, 20,151,214,217,254,127,151,174,164, 75,189,149, 51,180, 94,175,243,189,197,251, 51, +117,133, 78, 95,128, 36, 88,211, 41, 68, 85, 60, 73,106,211, 69, 73, 12, 45,115, 13, 70,169,207,106,112,209, 35, 66,220, 87,194, +179,216,106,111,137,214,165,165, 72,149,174,179, 37,214,203, 3, 17, 69,153, 38,228,141,218, 72,221,197, 20, 5, 5,165, 20,164, +153, 64,121, 3,100,155,182,202, 60,130, 83, 54, 16,216, 52, 34,113,130,228,140,195,126,143,195,229,185,133,105,181, 13, 76,111, + 89,105,221,121,123,184,200,127, 32,179, 17,113,189,208, 19,200, 43,151, 33, 0, 12, 82, 32, 58,131, 99,172,206, 12, 42, 30, 16, +163, 5,202,106, 98,178, 24,135,184, 15, 75,165, 88,133,162,178,176,183, 85, 43,128, 16,180, 20, 15,183, 79,190,119, 12,232,138, +214, 75, 93,138, 66,216, 20,199,179, 42, 54,170,102,103, 80,224, 40, 6, 56, 32, 47, 7,101, 3,232,213, 0,253,236,167, 65,239, +126, 4,224,118, 67, 50,200,149,209,199,202, 8,204,151,192,116,207,163, 62, 47, 0,253,114, 71,197,138,225, 71, 7,110,237, 64, +148,223,179, 64,167,210, 78,126, 88,178, 21, 10, 3,251, 25,196, 19,240, 56, 3,143, 79,161, 95,243, 43,160, 47,255, 83,192,237, +239, 3,182,127, 0, 72,119,157, 96,247,189,160,175,122, 30,250, 87,126, 4,233,135,174,112,231,227, 71, 12, 34,120,176, 83,156, + 15,102, 69, 34, 37, 83,251, 43, 32, 65, 74,243, 90,155,179, 64,103, 79,184,242,198,214, 25, 60,237,225,236,198,248,204, 12,113, +144, 2,147, 32,185, 85, 70,168, 29,118, 34,189,216,203, 58,242,228,226, 26, 37, 32,179, 98, 67,138,129,216,130,125, 52,129,222, +117, 10,126,203, 31,180,176,155,178, 7, 30,254,151,208,127,188, 7,238,125, 25,240, 6, 31, 80,221, 63, 64, 62,123, 5,221,143, + 16,182, 27,135, 6,251,188, 17,183,153, 45, 81, 76, 60,178,203,148,139,253, 58, 22, 96, 20,232, 36, 70,148, 3, 64, 51,217,133, + 63,139,181,193, 19,128,105, 50,159, 58,109,129,244,156,121,214, 6, 1, 78, 0, 26, 60, 57, 80,101,161, 95, 13,209, 79,100, 84, +179,243, 14,138, 24,135,154, 85, 65,137, 48,206,122,227, 1,174,235,173,165,243,224, 75, 47,156,235,109,138, 93, 80, 75, 20, 81, +212,117,204, 49,112, 24,188,165,154,117, 53,218,235,148,223, 68,215, 3, 78,230, 58,248,112,133,118,236, 12,125, 44,220, 46, 68, + 47,109,146,231,179,119, 93,207, 28,157,181,182, 80,145, 96,181,247,227,234,170, 58,167,235, 63, 43, 58,210,157,160, 21,169,113, +121,246,226, 53,185, 14,249, 91,136,146,184,147,101,149, 21, 88,169, 31,157,231, 85, 97,162,171,108,119,238,222,177,132,150, 43, + 94,180,233, 31, 56,236,177,253,165,175, 75,121, 24,173,144,194, 33,234, 26,186, 21, 66, 4, 3,109,124,248, 52,249, 5,127,230, + 29,250, 25,128, 51,127,255,142,218,166, 16, 19, 34, 60,198,143, 27,180,176,156,106, 81,163,102, 11, 3, 53,253, 3,117, 94,252, +121, 81, 72,182, 43, 42,246,204,210,165,178, 21, 93, 94,196,114,205,131,221,245, 52,218, 38,125,210, 77, 51,214,228,114,245,196, +179, 62,222,149, 52, 46,116,189,214,168,243,202,167,142, 85, 40,153,116,108,133, 76,141,237, 15, 23,184,153,147,202,126, 70,113, +120,135,166,140,189, 10,202, 60,219,116, 33, 37,204,254,190, 16,147,173,146, 0, 48, 25,182,124, 38,134,200,100,174, 6,106,226, +214,158,170,184,198,237,106,231,115,215, 14,205, 13, 85, 31,185, 23, 80, 26,144,136, 33, 57,153, 99, 75, 11,166, 2,224,120,192, + 70, 5,105,216, 96, 82,193, 56, 30,204, 77, 35, 70,232,204,195, 6,137, 19,182,155, 77,219,169,115, 61,176,233,154,215,214, 64, +243, 62, 86, 55,181, 84,181,193, 69,224,138, 93,242,212,160, 39, 62, 27, 86, 42,149, 4, 69,185, 11,170, 86,181, 68, 55, 78, 72, +193,138,247,203, 92, 59,245,138,129, 15,108,103, 47,253,195,162, 82,231,158,245,107,121,153,166,110, 3,155, 3, 19,206, 97,225, + 50, 16,198, 56, 43,166, 2,191,136, 60, 77, 40, 15,208,223,126, 13,244,173, 47, 1,155,231,125,215,234, 53,180,122,223, 37,151, +192,213, 4, 61, 20,208,217, 43,192, 89, 1,134, 55,199,163,100,221,245,137, 95, 14,137,237, 73, 59,250,210,243, 40, 45,210,182, +192,236, 88,179, 53,250, 64, 1,253, 86, 2, 30,156, 65,223,115, 31,120,215,143,130,158,253, 57,224,244,251,129,225,157, 0, 15, + 0,190, 3,244,194, 51,160, 31,249, 79,129,255,230, 33, 78, 63, 34, 24,142,123,236,146,224,113,102,204, 81, 99, 83,120, 54, 61, +180, 69, 21, 50,181,195, 45,187,126,143,104, 57, 26, 69, 87,188,133,255,159,147,137,165, 36, 89, 7, 88, 5,116,140,133,119, 37, +113,140, 64,141, 33,192, 76, 78,242, 19,208,176, 1,113, 2,109, 19,248,253, 47, 0,111,248, 22, 59,178, 14,191, 12,124,241,227, +192,195,103, 13,125, 37, 51,240,242, 12,249,212, 99,200,147,189,173,101, 60,198, 75,149,237,179, 67,190, 23, 96, 79,210, 56, 73, +174,129,240,214,102, 47,214,137, 79, 98, 30,117, 87,198,171, 8,104, 44, 13, 17,118, 36,155,186,200,185,105, 33,120,103,199,226, +142,129,147, 12, 26,134,101,228,176,118, 93, 54, 80, 81,190, 91,183,145, 49,181,112, 19, 89, 41,100,200,145,161,177, 87,207,104, +151,120,221,219,173,227, 33,125, 15,162, 98,175,191,114,235,126, 8,141, 98,151, 82,187,160,145, 76,143,169,190, 79,174,239,103, +231,243,142, 9, 65,137,238,147, 90,215,143,106,103,212, 26,158, 18,161, 39, 53, 6, 51, 34,108,163,211, 45,214,249, 0, 90, 71, +126, 85,157, 28,196, 61,106, 7,119,191,179,213,238, 20,174,217,224,157,231, 62,190,247,121, 61,205,236, 33, 60,157,238, 64,226, +251,236, 70,174,172,205,224,220,239,238,235,184, 95,219,115, 64, 43, 53,124,234, 58,109,234,126,134, 56,172, 99,243,148,180, 93, +134,212,173, 88,218,110, 88, 23,197, 84,124,173,141,255,125, 83,247,251,161,130,151,149,223,122, 14,154, 29,217,134,105, 77, 30, +148,142,234, 22, 16,107, 14, 34, 32,181, 96, 23,238,160,213, 82,109,144,122,173, 99,174, 13, 30,209, 66, 23,113,205, 91,127, 77, + 96,119,253,159, 75,245,137,199,179,177, 44,120,150,221, 62, 45,154,200,155,106,191,254, 25,187,169, 19,110,133, 27, 97, 36,197, + 73,133, 41, 89,134, 9, 59, 30,156,138,235,192,216,216,139,133, 25,101, 26, 49,139, 32,147,171,206,115,134, 50, 99, 42, 5, 92, +138,221,119,137, 64,100,165, 70, 93,239,213,103, 9, 43, 13,128,118, 63, 87, 23, 53,215,137, 30,201,167,228,115,153, 49, 29, 15, +200,158, 76,202,238,141, 87, 78, 80,102,140,243,140, 34, 5,105,158, 77,112, 78,108, 22,230,204, 21, 19, 13, 15, 57,203,232, 16, +177, 11, 95, 39,173,153,203,218,240,152,104, 18,255, 42,178, 67, 75, 92, 35,239,152,217, 59,104,142,191,197,133, 7, 20, 10,121, + 47, 18, 44,230,211,195,125, 85,186, 8,184,174,234,241,175, 17,226, 5, 18, 1, 58,175,122,248,220, 65, 14,203, 80, 27,143,216, +197,110,254,105,187,248, 5,123,117,248,129, 51,214, 11, 51,202,150,161,191, 53, 2,231,191, 4, 60,251,181,150,141, 78,228,227, +117, 31,189,207, 7,232, 21, 1,143, 1,189,100, 80,185, 15,220,153,157, 74,150,205,155,126,114,176,203,102, 59, 55,115,236,209, +245,190,165,235,214, 67,133, 50, 2,152, 14,192,158,129,203, 25,116,127, 11,124, 94,172,107,127,219, 15, 0,119,255, 29, 96,247, + 33,179,216,165,127, 2,120,234, 47,129,255,212,159, 6,253,181,251,224, 95, 24,240,236,241, 2, 67, 41,120,156,146, 5, 56, 84, +212,185, 86,145,119,168, 49, 19,181,216,208,165,224, 69,151,229,156,127,143, 73, 60,204,164,120, 33, 18, 15,153,120, 32, 8, 89, + 4,161,104, 27, 80, 68,225,144,161,224,221, 0, 30, 50,104, 47,224,175,221, 2,239,255, 16,176,123,155, 37,167, 61,248, 9,232, + 23, 21,216,238,236,111,125, 52, 67, 62,123,137,242,202, 17, 50,205,174,139, 48, 5,189,169,182,115,149,225, 83,180,167, 91,246, + 16,237,226,221,183,120,151, 94,172, 83,159,172,112, 34,153,129,139,193, 63, 95,108,100,140,177, 0,122,191, 49,176,248,204,200, +116,187,198,188, 12, 17,210, 84,109,126,228,105,108,126,128,179,177,236,139, 18,148,237,175,172,130, 67,255,156,195,167, 77,220, +173, 45,146,179,191,225, 34,186,250,103,227,223,139,132, 43,183,117,198,229,115, 45,192,164,235,154, 74,168,116,213,234,158, 96, + 89, 67,201,133, 92,209, 37,234, 34,196, 98,173,214, 13,187, 28, 51, 48,148, 62,110, 52, 80,181, 13,168, 94,237, 63,180,170,245, +176,204,171, 22,186, 14,221,161, 53,237,173,126,121,186, 6,241,192, 74, 60,183, 24,109,118,182, 64, 90, 29,165,225,222, 17,159, + 52,244,157,182,116,171, 69,172, 88,235,164,109, 28,222, 2,123, 26,245,172,248,235, 90, 22,133,136,253,128, 57, 66,171,220,125, + 64,221,197,222,143,220, 77,100, 70,181,120,161, 14, 41, 60,250,190, 94, 61,242,183, 0, 56,248,229, 58,118,212,189,202, 84,138, + 49,183,195, 95,158,234, 84,232,201,153, 20,199,176, 1,162,165,145,149, 27, 58,109,237,214, 69,253,235, 5,186, 33, 44,101,245, + 62,210, 13,124,245, 5, 9,113,133,122,229, 53,195, 0,221,103,120,169,145, 91,237,166, 91,236,240, 77,133, 69,241, 38,117, 14, + 42, 29, 25,172, 44, 19, 99,224,108,239, 13,145, 37,164,145,193,101,138,223, 5, 33, 12, 79, 76,216, 12,131,199,199,218,250, 52, + 56, 17, 66,134,119,133,136, 7, 38,117,174, 10, 98,183, 90, 99, 5,166, 69,213,173, 45,220, 6,241,108,139, 69,179,218,186, 88, + 77,124, 39,218, 77, 21,128, 82, 20,162, 35,118, 68,216,158,156, 66,136, 48,205, 35,166,105,198, 60, 30,237,240, 73,169,237,212, +171,200,164, 83,186, 47, 72, 97, 17,207, 74, 93,200, 11, 5,217, 45,132, 33,161,108, 12,133,178,120,242,140,214, 72, 81, 21,139, + 8,101, 54, 54,124, 74,185, 70,141,154,202,158,171,240,139,216,170,149,102,174, 66,151, 59,174,208,185,248,126, 4, 32, 45,158, +177,142,234, 39,156, 84,205,202, 38, 90, 5, 56,179,239, 66,138, 63,229,156,128, 9,138,137, 1,253, 93, 64, 63,253,113,208,221, +207,187,119, 58, 74,123, 87, 87,149,163, 33,165,174, 12,219,164, 2,144, 94, 0,119, 94, 4,248, 57,128, 78, 64,187, 43,232,110, +242, 16,237,220,186,246,163,137,247, 80,252, 45,157,165, 43,181, 21, 50,205,160,195, 12, 58,206,160,243, 1,244,210, 41,244, 61, + 87,160,175,251, 81,224, 77,127, 31, 56,249,126, 32,125, 25,192, 95, 13,220,249, 49,208,247,254,135,192, 83, 79,192, 63,115, 23, +119,206,207,177,153, 38, 60, 32,198,101,183,227, 21,105,220,113, 67,235, 19, 56,149,133,127,154,208,129, 25,116,185,231,171,226, + 37,233, 56, 6,221,135, 49,188,153, 22,213, 73,200,201, 14,250,172,130,156, 9,124, 58,128,246, 9,124, 10,208, 31,126, 55,232, +249,239,177, 77,235,254,231,128,151, 62, 5, 92,221,178, 47,118,255, 8,125,188,135,220, 59, 66,198, 9, 74,226, 43,152, 80, 75, +118, 27, 87, 98,208,134,173,112, 58,165,166,206,185,154,235,232, 29,147,216, 26,103,246,196,187, 89,129,139, 2,154,197,190,222, +158,160, 71, 6, 77,151,174, 36,212,198,211,221, 36,208,192,181,253,150,212, 29,198,206, 52, 39,136,211,225,200, 87, 75,142, 46, +136,206, 36,244, 39,126, 99, 30, 21, 72,217, 45,102, 98,240,159, 24,115,135, 95, 55, 87,145, 92,179, 19, 13, 93,240,138,250,215, +168,209, 11,245,242, 51, 22,117,236,140,197,117, 16,209,246, 43,135, 51,166,165,174,113,103, 73,234,121,214,138,118,112,215, 98, + 70,187,213, 87,127, 72,135, 31,219, 9, 93, 27,168,213, 87,126, 64,204, 46, 38,139,144,148,210,217,167,180, 3,183, 96,213,153, +221, 52,150,167,107,102,171, 78,248,212,109,187,214,141,200, 66,105,172, 13,101, 32, 55,136,188,168,175, 87, 86,170,251,212, 77, + 50,218,101,164,238,185,167,174, 30,210, 10, 24,210,110,146, 25,241,197, 65,204, 76,126, 97, 30,187, 75, 46, 20,249, 19,150,185, +238,203, 85,131, 46, 0, 56,232, 46,247, 40, 66, 70,191, 20, 7, 50,100,172,120, 12,240,163,206,243, 31, 49,189,220, 1,129,168, + 31, 25,251,231,202,178,217,245,154, 56,239,245,132,106,215,183,219,184, 1,140,186,116,101, 80, 21, 42,182,152,214,235,255,166, + 94, 95, 99,241,106,194,213,125, 51, 92, 11,102,194, 94, 20, 3,171,195,207, 12,206,161, 72,208,164,216,176, 81, 80, 15,176, 56, + 85,168, 34,229,100,246,235,148,170,195, 59, 51,163, 48,219,120,156,201,154,153, 50,251,122, 46,132,116,104, 73,167, 55,124,207, +235, 19, 55,190,249, 90,172,171, 57,147,200,145,233, 38, 8,247,180, 54,166, 10,100, 19,215, 73,148,253, 21, 52, 37, 76,211,132, +121,158,236,123,131, 77,246, 50, 86, 99,166,122,185, 6,201,205, 71, 88, 28,163,118, 52, 1, 81, 29,108, 57,169, 45, 81, 83, 48, + 88, 68, 67, 83,164,104,153,187,248, 86, 63, 12,105, 65, 40,240, 44,106,235,134, 56, 25,129,142, 52, 50,164,217, 47,150,138,218, +240,139,124,185, 80, 9,197,170,192,192, 15,147, 43, 76, 69, 4, 5,130, 50,199, 14, 52, 4, 48, 30, 54,145,129, 91, 23, 10,254, +123,175,128,190,234, 23,129, 59,111,111, 57,220,234,137,198,243, 4,140,108,179, 48,135, 89,107, 33,227,142,157,221, 7,210,214, + 46,243, 91, 4,220, 98,235,190,175,162,210,114,112,138,175, 7,234, 55,155,162,108, 86, 40,102,232, 56,131,198, 17,180,223,128, + 95,219, 64, 63,191, 5,190,233,239,130,222,253,219,174,142,255, 0,128,119, 2,183,127, 28,244, 93,127, 26,188,125, 0,250,249, +187, 56,185,119,137,231,174,246,216, 64,113,158,147, 77, 40,188,155,216,100, 96, 67,197,222, 15,181, 29,209,226, 41,147,118,240, +193,243,119,152, 29,237,233,127, 79, 79,125,168,200,222,142, 60, 53,184, 61, 49,147, 32, 11,192,155, 12, 26, 18,120, 18,208,191, +250,229,160,175,254, 97,179,144, 29, 62, 15,156,255,117,232, 33,219,160,176,204,208,139, 35,228,229, 3,100, 63, 26,114,177, 75, + 61, 81, 85,208,224,175, 27, 17,184,144,237,216, 79, 96, 52, 57,130,141,218,227, 50, 63, 20,232, 97,130, 30,213,254, 46,144, 5, +209,236, 39, 27,207,159,101, 63,193,213,198,239, 50,218, 62, 93, 11,144,196, 2,250, 78,179,127,210,123,241,168,223,251,174,125, + 84, 53,145, 98,248,127,165,227,164,167, 80, 90, 51,131,148,113,247,132,112, 85, 4,227,108,233,133,161, 70,150,213, 97,217,139, +104, 66,237,108, 69,167,213,149, 57, 89, 45, 24,187,194,226,234,123,235,238,219,206, 81,113,125,241, 76,137,160, 73, 77, 3,170, +173, 59, 87, 63,144, 42, 57,204,219,163,121,117, 57,114, 47, 10,211, 54,221, 73,222, 25, 7,232,131, 60,115, 29, 76,166, 83,244, +203,125, 34, 50,146, 92,119, 41,177, 46,155,132,178,154, 34, 93, 3,193,248, 68,162,223,165,167,149,117,172, 23,168,201,234, 53, +150,149,152,171,223, 11, 75, 55,254,214,206,134,168,238, 43,143,113,122,179,240,217,235,223,127,189, 16,244,197, 20, 4, 98,201, +151, 27,102, 20, 85, 76, 46,170,154,171,213,177, 37,218, 77,190, 21,106,161, 59, 84,139, 12,215,194, 86, 52,113,207,240,143,215, + 40,182, 83,123,109,252,117,192,142,162,128, 27, 61,118,236,111, 10,109, 72,216, 27,227,118, 36,174,166, 18,134,122,232, 76, 11, + 51,145, 27,212,105,175, 55,146,215, 27, 13,104,215,231,234,109,205, 69, 43, 80, 11,181,159,150,218,223, 88, 73,131, 66,184, 41, +167,162, 95,207, 20,143,152,102,181,228,207,156, 24,153, 50,100, 48, 43,219,196, 70, 1, 36, 40, 68, 76,129, 62,164,140, 33,103, + 36,206, 85,171, 52,112, 2, 13, 4, 21,103,194, 3, 75,155, 75,157, 30, 52,188,172,122,209,173,215, 94,147,206,218, 73,237,103, + 21, 81,232, 60, 99,216,236,176,221,109,160,100,186,166,226,150,185, 82,138,163,150, 11, 74,153,129, 34, 86,124,108, 54,200, 57, +163, 20,179,151, 75, 41, 72,239, 56,187,245,231,205,137, 70,117, 55,196,157,242,175,250,255,124,255,192,201, 43,153,110,251, 18, + 72, 77, 78,185,118,116,129, 20,141,249,161,237,204, 75,133,202,176, 87, 73, 86,253,219,238,151,201,202,134, 72,208, 76,253,104, + 40,152,229,180, 34, 45,244, 10, 20,127, 10, 9, 10,214, 82, 59,166, 45, 19, 78, 72,107,215, 31,154,169,129, 20, 39, 25,216, 56, + 54,118, 11, 65,126, 66,224,247, 93, 1,207,124,192,112,175,243,203,192,116, 1, 76,175, 2,151,247, 45, 45,108,111,150, 41,131, + 56,251, 9,153, 21,196,197,151,203,206, 82, 29, 21, 56, 40,104, 22,131,167,140,106,221,122,168,148,180,193,156,181,204,174,204, + 86,232, 52, 3,165, 64,231, 25,116,159, 64,159,219, 1,251, 75, 96,243, 17, 80,250, 37, 35, 80,211,123,129,221,119,129,222,254, + 27,160, 23, 94, 3, 94, 59, 65,158, 18,118,165, 96,152,102, 72, 34,136, 71,160, 14,201,134, 6,213,254,163, 30,134,163,205,191, + 92, 71,128,172,245, 53, 44, 74,152,103,187,220, 69,220, 85,224, 0, 14,142,145, 36, 41,134,164,216,102,181,120,205,164, 24, 50, +131, 79, 18,210, 4,240, 63,117, 6,250, 67,127, 17,216,125, 53,112,252, 93,224,201,143, 2,247, 63, 9,220, 59,181,225,225,213, + 12,125,233, 10,229,222, 1,114, 28,109,100, 94,167, 61, 54,102,167,236,191, 6,251,197,183, 55,192,243, 27,224,118,182, 19,239, + 73, 49, 11,225,161, 0, 87, 5, 58, 10,244, 24, 68, 30,107, 73,185, 48,232, 77, 3,112, 39,219,172,242,153, 2,186,157,129,211, +111,177,144,157,195,111,128, 30,126, 6, 56,156, 24,205,238, 11,151,152, 15, 5, 83,166,214,193,114, 23, 18,231,194,180, 18, 20, + 47, 87,165, 39,127,110,114, 98,156,164,140,247,126,215, 29,188,245,159,187,141, 71, 31, 59,226,226, 74,124,240,160,215,198,152, + 90, 47, 56, 90,248,216,193,109,175, 13,191, 96,226,114, 37,130,237,248,194,230, 67,171, 95,171, 86,138, 92,244, 19,115,206,220, + 92,158,246, 76, 58,148, 36,209,138,128,213,119,233,188,162,153,117, 24, 85, 1, 33,251, 25,188,241,205, 72, 36,142,197,207,153, +253, 87, 20, 62,220,229, 77, 36, 90, 94,146,253,127,207,221, 21, 64,171,253,116,164,128, 13,180, 92, 3,193, 71,220,189,141,236, + 38, 97, 23,110,224,117, 99,177, 79,191,190, 39,174,105,100, 43,213,117, 47,220,170,222,119,120,129,151,216, 38, 24, 43, 27, 95, +241,127, 65,170, 45,140,170,238,162,116,151,156,184,240,173, 39,182, 97,133,211,149,181,109, 14,246, 94,156,144,109,157,142, 17, +216, 76,109, 69,100,188,125,187,224,238,144, 21, 2, 7, 0,247, 69, 13, 9,221,105, 28,150,190, 44,194,186, 63, 88,119,229,181, + 9,164,213, 31, 12,234,168, 79,249, 18, 59,220,103, 61,115,167,133, 35,183,141,220,233,102,123, 27,174,173, 57,184,114, 10,110, + 13, 3,118,219, 29,178,231,161, 19, 51,132,185,146, 9, 55,156,144, 83, 70, 98, 83,199,199, 36, 33,249,142,125,195, 12,164,100, + 97, 42,243,220, 61,164,180,200,230, 96,231,173, 16,249,167,187, 54,164, 55,121, 7,154,126,161, 20,197, 56, 30, 49,143, 71, 72, + 49, 30,200, 52, 77,152,198, 17,243, 52,162,204,118, 47, 4,149, 42, 86, 2,182,202, 78,190,102,208,198,208,168, 25,200, 76,139, + 14,133,152,151,239, 69, 39, 26,130, 54,219,155,104, 71,213,169,135,178,172,126,152,104, 15,156,181, 93,216,159, 86,109, 56, 74, +182, 17, 60, 57,149,137,164, 83,222, 71,118,181,167,190,233,194, 95,133,154,233,220,122,121, 96, 46,138, 35, 3,147,135, 54, 20, +175, 60,149,236,111, 27,103,197, 46,153,176,174,108, 8,250, 8,208, 79,188, 4,122,251,167,129,147,247,251, 9, 58,219,142,189, +192, 78,244,131, 24,130,116, 22,160,116, 25,184,207, 2,116, 58, 88,168,195, 45,182, 29,237, 9, 3, 83, 2,237,109,239,171,179, +223, 2,220,117,234,226,221, 41,164,234,242,136, 10,104, 44,208, 97, 6,149, 1,252,247, 78, 64,159, 28,160, 95,113, 15,248,138, +255, 17,244,182,159, 1,206,254, 36,176,251, 17,224, 27,255,103,208,151,253, 95,192,255, 1,228, 79,220,198,217,189, 43, 12,151, +123,156, 51, 99,220,248,107,210, 89,121,224, 9,111,186, 48, 96,248, 1, 86, 20,196,166,114, 62,198,154, 34,198,129,254,239, 15, +138, 38, 8,226,214,201,108, 54,192, 80, 8,148, 19, 72, 18,232,180,128, 62,244,109,192,201,123,128,249, 8, 28, 63, 6, 92,124, + 2,122,145,129,121, 0, 46,103,232, 75, 23,144,151,246,144,171, 9, 58, 22,155,178,132,128, 41, 62, 92,153,107, 41, 78,204,192, +169,191,174,228,114,224, 41,110, 88, 65,173, 84, 42,145, 67,161, 76, 86,137,239, 61,206,144,220, 31,118,188, 0,202, 19, 96,120, +155,177,231,115,178, 44,159,129,145,134, 45,118,105,194, 33,219, 65, 83, 68, 33,174,193,235,247,195,125, 22,121, 53,173,251, 66, +121,115, 66, 72, 73,113,239, 23, 14,184, 58,159, 49, 36, 3,129, 68, 23,167, 43, 79, 53, 86, 66, 58,248,164,172,248,197, 85,168, + 29,148,138,198,145,175,103, 52, 55,132,175, 58,175,160, 72,159, 85,238,145,172, 3, 97,154, 27,148,166, 66,132, 40, 58,205,134, + 18, 61,160,137,193,208,133, 0,245,240,150, 16,166,205,106,129, 33, 59, 47,200, 51, 3, 91,167,222,157, 1,216,129,112,128,173, + 48,194,167,109, 96, 36,127,250,107,254,128,217, 87,117,181, 84, 79, 93,253, 94, 86, 52,182,109,175,114,167,101, 23,216,194, 75, +150,105, 99, 61, 18,168,116, 23, 97,174,240,160,213,168,191,147, 18,111, 29,226,164, 95,162, 48, 96,191,136, 73, 45, 91, 97,195, + 9,156, 50,174,202,140, 89,154, 8, 78,160, 53, 38, 52,190,207,138, 71,213,165, 34, 29, 30,142,148,180, 17, 97,162,209, 46,184, +206, 89, 23,175,202, 6,178,245, 8,135, 54, 64, 35,205,203,206,210,141,203,125, 39, 0, 47, 43,225,190, 40, 14,210, 94,163,202, +171,232,214, 37,129, 52, 94,160,249,190,132,237,109,209,105,247,184, 91,186,121, 71,175,164, 43,239, 55,117, 97, 74, 54,145,125, + 61, 39, 69,109,166,201,137,134,100,225, 99,179,154, 67,104,203, 38,232, 53, 43, 42,129, 57,161,116,154, 39,230, 54, 78,175,250, + 22,226, 54,117, 86, 1, 51, 53,189,139,116, 19, 51,234, 19, 24,216, 38,202,224,197, 74, 65, 8, 85, 59,130,138,234, 21,136,144, +113, 87,166,169, 85,231, 85, 41,207,157,254,198,218,106, 17, 1,198, 17,188,129,117,236,228, 36,189,107,204,247,106,103,235, 62, +160,126,217,135,106, 29, 30, 59, 9, 87,149, 67,109,127,206, 76,203,203,187,251,230,217, 31,216, 22,186, 82, 64,147, 56,185, 51, + 85, 85,113, 10,200,135,219,212, 82,133, 94, 80,141, 7,213,240, 84,137,161, 58,137,185, 82,137, 52, 14, 30, 17, 76, 80, 92, 78, +132,219,108,161, 34, 86,123,152,114,103,138, 29, 22,187,200, 65,197, 42,225, 79, 78,160, 15,254, 42,176,123,175,117,235,228, 60, +173, 34,246,135,131, 65, 94,212, 58, 68,214,170, 10, 86, 37,208,105,178,147,237,118,182,142,126, 78,160, 67,134, 78,198,129, 86, + 4, 90,212,231,110, 3, 87,181,125, 20, 42, 26,154, 65, 85,208, 36,208,113, 2,141, 3,248,181, 29,232,227, 59,232,215,221, 3, +125,243,127, 1, 60,251, 3, 64,250,215, 65,111,253, 86,224, 95,251, 73,224,111,255, 42,210, 47,158, 98,247,128, 49, 60,217, 99, + 47,130,227, 96,241, 1,145, 36, 43,165, 75, 3, 35,172, 6, 95, 2, 8, 97,238, 18,197, 18,128, 13,123,230,179, 46,211,157, 2, +131, 57, 40,144,102, 5,239, 50,104,147,192, 71, 1,255,145, 51,224,249,127,163,121,249,203, 99, 15,189,219,218,229,250,240,128, +242,187, 7,148, 39, 35,100,154,141, 88,150, 90,129,201, 66, 70,234,181,120, 63,251,223, 39,108,221,246, 46, 53,236,214,104,163, + 23, 45,190, 27, 46, 46,146,235, 25, 51, 83, 49, 61, 68,118, 61,195,165,152,176, 49, 61, 5,240, 41,144, 78,129, 84,128,179, 4, +204, 9,124,220,225,116, 16,204,116,196,145,197,196,159,165,143,254,164,154, 66,215,123, 90, 99,215, 39, 16, 92,237, 11,126,245, +111,158,227,106, 82, 36,167, 43,182,245, 75,187,196,231,213,164, 50,252,228,197, 1, 34, 83,183, 39,148,186,255,165,202, 23, 40, + 62, 63, 86, 23, 6, 17,181,162,109,147,154,254, 84, 73,235, 46, 62,101, 23, 64,106,195, 63,151, 88,187, 69, 86, 0, 19, 82,209, +186,118, 72, 29,161,171,142,174,185, 6, 0,250,190,207,138,210,201,121,222, 17,141,218, 51, 18,102,105, 52, 62,138, 61,161,147, + 49,138,218, 52, 43,185,202, 57, 46,169,238, 14,115,183,141,214, 11,253,196, 11,203,212, 37,187, 69, 36,170,174,224, 35, 88,129, +109,176,126, 93, 97,231,130,118, 66, 52,238,148,219,235,221,109, 15,188,145,222,254,213, 93, 82,197,207,164, 13, 10, 78, 57, 65, +152,113,161, 82, 51,234, 75,183, 31,159,110,240,136, 23,175, 28, 7, 86,231, 4,144,231,149, 47, 39, 16,218,209,221,114, 39,112, +102, 31,181, 55,127,122,179, 25, 26,144,209, 78,128,199, 0, 30,137, 73,134,142,226, 93,179, 94,119, 31,132, 72,186,237,218, 59, +181, 34,186,203,170,187,140, 9, 55, 49,208,123,141, 2, 93,179,197,209,235,208,227,168, 83,239,115,111,181, 93,173,115, 66,188, +150,136,161, 41,225,137, 40,112, 56, 32, 19,176, 29, 54, 22, 38,227,223,179, 20, 19, 33, 13, 62, 81, 41,228,235, 55,215,205,100, +183,191, 77, 90,204, 82,189,246,138,177,137,122,149,100,241,154,217,100,165, 37,192, 47,168,157,220,135, 20,217, 8, 46,132,172, +125, 97,208,239,229, 21, 46, 28,134, 39, 2,186, 78, 71,199,209,176,205,105,176,159,169,230,109,243,242,133, 11,197, 85,140, 17, +226,247,168, 42,184,165,137,234, 20,144, 50, 27,255,189,203,152,165, 34,141,103,221,115,121,136, 22, 35, 66,173,227,122,123,242, +205, 58, 71, 32,157,125,239, 45,245,210,163, 0,237,163,117,161, 65,116,214,142,191, 12, 21,211, 59,169,226, 48, 3,187,141,117, +251, 90, 45, 63,161, 52,140,142,206,171,172, 47, 42,240,228, 69,224,153,209,201,113,212, 44,110,117, 58,160,214,177, 7,237,172, +104, 69,117,105,180, 41,183, 1, 28,179,141,235,111, 3, 60, 22,136, 8,116, 95, 34, 53,160,181, 86, 9,158,181,168,245,235,232, +172, 85, 78,194, 51,108,255, 60, 23,240, 52,129, 63,178,129, 30, 11,232,219,254, 18,240,134, 13, 64,127, 0,120,230,199, 65,223, +253,211,192,237,159, 66,250,153, 29,240,244,128,147,151, 47,145, 14,214,113,206,153,106, 81, 67, 43,236, 71, 5,173, 36, 50,120, + 30, 90, 46,111, 13,236, 33,243,216, 75,119, 88,102,242,241, 62, 41, 82,102,208,105, 6, 31, 51,248, 61, 71,224, 67,223, 15,228, +175, 52,111,255,229,255, 9,156,255, 44,244, 0,211, 37,220, 63, 66, 62,117, 9,121,184, 71, 57,142,152,146, 39,207, 45,173,225, +118, 33, 39,139, 67, 5, 49,104,151,128, 51,239,220,143,197,230,225,174,114,199, 44, 38, 72, 60,106,139,117, 10, 68, 64, 81,224, + 56,251,114, 26,192, 3, 1,142, 71,160, 60, 2,232,237, 22,178,147, 29, 74,243, 85, 39,192,191,245,118,240,167,239, 99,251,159, +124,194,243,227,169,142, 78, 85,177, 82, 88, 59, 50, 65,188,147,245,207,156,206,197,222,189,100,212,172, 34, 29, 54,181,239,164, + 56,232,111,232,236, 58, 85, 14,103,124,117,242,194, 90,116,201, 49,247,131,185, 56, 76, 38,147,197,154,194,191,159, 57, 14,186, +108, 53,203,132,182,122, 73, 41, 46, 62,203,147,214, 16, 68,170,237, 27, 55,162,216,184, 82,126,138,105, 12,145,241,220,181,165, +198,193, 57,244,113,209,141, 93, 52,105,246, 17,173,248,165,155,188,179,179,177, 61,213, 75, 43,220,134,228, 65, 41,113,225,103, +159, 2,206,157, 24, 45, 70,171,201,187,205, 74,110,163,200,124,167, 69, 31, 94,133,190,218, 18, 15,165,187,170,116,161,252,182, +175, 61,119,226, 58,116,196,186,155,118,201,165,147, 69, 69, 63, 45,218,164,205,177,203, 47,162,216,161, 96, 67,140, 45, 19,198, +210,237,238,129,197,174,188,215, 13,100, 10, 20,113, 23,204, 66,228,193, 40,246,153, 60,174,246,236, 92, 73, 27,214,165, 87, 21, +187,251,244,137, 76,220,184,245,253,254, 61, 0,143,197,222,215,176, 72,233, 10,125,218,226,111,123,156,146, 94,123, 69,214, 94, +236,165, 5,143, 32, 43, 69, 36,117, 83,162, 40, 24,230,110, 31,157,110,208, 65,244, 19,174, 30, 97,219,131,106, 42, 85,142, 13, + 9, 59, 22,243,229, 18, 49,212,183,112, 19,137,157,119, 78, 44, 45, 12,104, 17, 91, 31,167,132, 6,149, 51,252,185,138, 63,211, + 74, 38,248,166,150, 92,170, 20,205,218,242, 98, 7, 39,168,175,152,209, 9, 97,117, 33,216, 20, 40,241,170,168,161,102,253,236, + 65,107, 61,140, 34,138, 18,181,142, 93,147, 70,167, 78,139,252,103, 68,230,108,163,228,181,157, 29, 4,162, 2, 71,204, 88,231, +169, 49, 14, 47,208,194, 43,197,163, 46,146,226,137,227,239,215,142,182,228, 46, 79,223,183,131,217,133,121, 12, 85, 6,102, 15, +159, 23, 75, 94, 35, 54,123, 0, 81,251,112,136, 95,142, 42, 98,112,155,216, 59,168, 98, 6,225,232, 19,243, 74,165,242,177,102, +137, 20, 41, 34, 80,178, 75, 77,207, 1,189,184, 15,210, 3,144,159,182,116,181,254, 21,157,252, 66,159, 66, 53, 86,154,148, 56, + 24,156,119,178,117,235, 79, 39, 83,225,137, 2, 99, 6, 29, 4,196,147, 21, 16,197, 31,138,136,101,202,214,150, 69, 54,175,138, +212,215,173, 76, 0,207,130,114, 44,208, 91, 5,186,153,145, 62,126, 6,189, 53, 1,191,255, 39, 65,249,205,192,240, 53,192,233, +247,129,190,253,105, 40,127, 24,233,111,109,129,183,222,193,246, 11, 15,129,125,193,145, 24, 19, 45, 33, 9,220, 89,127,168,243, + 9,101,138,247,169,117, 17,234, 36,147,250, 96,137, 54, 81, 24, 0,222, 37, 32, 37,240,197, 30,244, 47,191, 7,184,251,199,128, +249, 33,112,254, 55,128,139, 95, 2,174, 30, 0,151, 59,224,209, 12,125,105,143,114,239, 10,229,106,196, 68,132,105,110,121, 66, +236, 12,159, 96,233, 19,179, 49,232,111, 39,224, 78, 2,110,123, 59, 95,196, 39, 33, 98, 58,132,105,134, 28,102,219,119, 85, 75, + 12,129,166,226,197,140, 27,122, 54, 0, 94, 81,232,227,115,208,151,125, 30,192, 55,154,123, 33,121, 5,240,252,206,190,137, 95, + 59,183,207, 91,118, 4,172,239,252,168,223, 49,118,227,207,208,153,132, 91,192, 14, 92, 66,210, 54, 38,212,174,139,169,123,113, +189,174, 38,170, 99, 58, 24,208,134, 92,187, 17,164,184, 56,164,181,223, 62,101,199,245,106,119,169,244,107,130,232,102,195,137, +226, 58,129, 8,129, 89, 36,177, 69,225, 70,118, 49,195, 47, 68,113,200, 76, 47,156,210,213,161, 10, 63,160,143, 65,112, 80, 11, +195,200,220, 44, 86,210,237,140,103,255,251,185,139, 17,206,104,148,154, 68,140,172, 10, 33,131, 70, 73,116,159,164,139,196,178, +133,137,163,107,197,121,117, 25,243, 77, 10,124, 93, 93, 77,206,218, 31,195, 3,238,132,188,224, 75,197,198, 71, 23, 69, 30, 85, +164,104,115, 1,117,150, 69,119,227, 36, 54,158,254, 38,153, 13, 50,148,241,218,169,182, 5,205,126,154,213,116, 63, 3,181,131, + 62,121, 69, 56,249,170, 98,175, 77, 80,135,174, 91, 23,255,172,156,116,175, 83,234,126, 29, 84,241,138, 90,150,249,236,159,239, +242, 37, 72,114,180,250,255, 92, 87, 64, 90,145,187, 75, 32, 12, 93,227, 42,210, 13, 4, 57,138, 41,172, 51, 25, 88, 90, 48,205, +154, 98,136,133,112,146,170, 51, 69,187, 9, 75,205, 68,247,206,160,248,116,119, 67, 6,160,217, 36,127,117, 37,238, 2, 53,108, +249,236, 78,174,148,157, 24,105,234,243,136,150,102,192, 8,110,241, 13,106,203,136, 18,110, 31, 62,237,155, 94,152, 98,158, 97, +147, 96,136,214,134, 86,107, 84, 48, 45, 8, 5,181,163,119, 97,185,174, 38, 16,132,229, 33, 84, 73,170,101, 70, 14,127, 57,199, + 24,165,219,129,215, 15, 72,120,196,131,105,236,151, 57, 85,108,171,137,229,200, 2,210,155,194, 39,150,248, 98,241,167, 97,205, + 73,220,213,189,106, 2,182,228,251, 67, 21, 63,196,216, 92,125,154,146,231,167,219, 97,164, 14,174, 97,136,135,191, 16,138, 6, + 73,141, 42,234,140,176, 4, 83, 76,210,236, 18, 61,157, 74,252,110,158,196,246,200, 56,245,147,236,225,104, 52,185,205,155,129, +237,155,129,139, 19, 16, 43,180, 26, 90, 75,179,168, 93,145, 43,180, 99,166,234, 18,210, 51, 54, 21,252, 27,146,123,168, 7,208, + 85, 1,149, 12, 61,204, 45, 98,169,151, 41,160, 59, 41, 82,167,255, 35, 7,232,140, 5,170, 71,232,169, 2,233, 18,252,177, 83, +208, 83,247,129,175,255, 49,128,254,156,193,106,182,127, 24,244,251,175,160,227,143, 35,253,194, 14,120,219, 83,216,188,120, 1, +156,143,192,174,225,211,235, 67,230,151, 53,137, 85,172,236, 7,188,118,163, 51,168,235, 17,164, 13, 23,200,249, 58, 25, 64, 26, + 8, 56, 77,224,251, 10,250, 32, 3, 95,254,239, 89,197,180,255,187,192,254, 87,128,195, 5,244, 49,123,164,234, 8,185,191,135, + 92,142,214,104,231,214,237,176, 15, 48, 34,104,134,114,140, 90, 13, 96,131, 59,185, 37, 98, 60,113,182,193,100, 23,187,204,102, + 99, 67, 20,110,226,104, 7,245,145,213,222, 85, 93, 91, 0,123, 2, 46,142,246, 30, 3, 54,126,247, 21, 16,254,223,199,192, 95, +254, 60,228,165, 39, 24,183,179,219,219,155, 88, 16,171,195,113,132,253,189,235,240,145, 69,103,161,122,109,229,184,228, 23, 70, +255, 0, 0, 32, 0, 73, 68, 65, 84,210, 28, 53,188,174, 31,198,228, 2,178,226,133,142,189,230, 14,165,209,230,129, 71,231,135, +166, 4, 80,105, 94,247,232, 32,147,182, 61,229, 28,180,176, 32, 14,122, 92,113,158, 61, 63,158, 9,217,255,174, 65, 98,251, 65, +152,252, 48, 18,215, 85,136,175, 14, 68,151,235,129,120,125, 6,247, 69, 31, 0,100, 31, 53,199,222,177,231,160,199, 81, 48,107, + 20, 29,230,168, 40,220,104,135,117,127,219, 11,166,186,101,108,251,175,122,163,176,109,209,119,174,186, 59,186,246,158,208, 2, + 64,147,212,125,251, 78,118, 75, 4,236,153,141,119,209, 29,208,241, 51,196,212,177, 21,129, 90, 31,117, 19, 85,218,243,181,117, +197,251, 33, 50, 4, 86,176, 81,238,148,253, 67, 39, 28,142, 93,252, 12,155,202,140,221,239, 45, 94,255,174, 74,233,245, 15, 17, +166,243, 68,129,123,170,216,135, 26,223, 63,163,250, 58, 54, 53, 90,119,228, 43, 47,217,235,241,216, 35,224, 72, 87,234,131,182, +250, 37, 95,195,104,189,180,248, 6,193,223,250,217,161,170, 47,137,142, 61,168,111, 29,220,217,255,160, 72, 8,112, 25, 74,102, + 81, 99,255, 84,132, 29, 59, 98, 45,227,162, 79,196, 78, 61,181,215,121,158,205,118,150,114,118,203,108,105,239,189,195, 96,140, +131, 86, 58, 27,101,148, 58,220, 10, 29,234,167, 26, 95,130, 60, 25, 84,108,238, 45, 98, 90,227,150, 65,214,120,139,118, 43, 48, +181, 34,176, 62,240,203, 49, 75, 83, 55, 50, 47, 9, 75,236, 8,215, 16, 77, 84,146, 88,236,193, 61,110,149, 72, 91,167, 47,221, +222,163, 26,168,169,250, 37,169,250,209,109, 52,204,148,192,100,161,239,148, 76, 17, 15, 9,207,180,174, 34,248, 26, 25,169,207, +170, 69,103,221,241,115, 31, 91,238, 42,156, 48,245,147,217,220,230, 42,178, 74,192,227,189,237,129,177, 3, 54, 47, 0,155,167, +236,132, 67, 19, 66, 97,114,218, 72,113, 83,143,120,185, 28, 49,105, 57, 3,167, 25,184,179,113, 44, 20,128,125, 2, 29,179, 41, +226,103,105,158, 27, 88,187,107,232,248,118, 4, 41,122, 97,150,161,111,249, 80,204, 51,239,115,242,244,247, 79,161,233,211,160, +175,253,207,129,179, 31, 0,182,239, 3, 78,190, 7,244, 29,167, 80,124, 24,233, 23, 6,224, 45,183,176,249, 60,192, 87, 35,166, +220,235, 8,204,134, 36, 21,233,168, 93, 74, 19, 53,208, 3,199,235,140,154,154, 22, 67,137, 4, 69,218, 24, 14,152,166, 25,244, +237,111, 5,242, 55, 2,227,139,192,213,175, 3,101, 52,100,235, 67, 6, 30, 78,208,251, 7,200,131, 3,230,253,140, 9,240,238, +171,225, 76,107, 81,182,105,196, 54,218, 50,232,204, 69,114, 57, 59,231,125,110,239, 65,180, 78,208, 74, 44,212,248,240,219,220, + 23,122, 33,160,113, 2,182, 27,203, 38, 56,122,229, 16,175,127, 41, 64,154, 1, 18,232,217,140,233,214,132,227,209, 68,114,234, +124,115,197, 82,253, 61,105,111,172,209,107,192,137,133,249,121, 65,205, 90, 30,157,212, 61,124,210,205, 24,109,108,109,159,175, +112, 46,148,234, 71,215,182,183,243,216,202, 48, 29, 7,121,203, 3,139, 45, 97,206,215, 86, 97,227,108, 59,118,170,149,212,160, +190,223,238,242,190,217,119,212,129, 9, 21, 34, 47,114,122,149,247, 50,168,102,205,110, 23,109,160,163,222, 11,158,252,210, 22, +183,232,137,175, 32,102,255,253,224,207,199, 8,223,128, 86,228,151,152,214,157,125, 43,212, 59,122, 93,255,234,170, 46,198,227, + 1,128, 41,175,115,129,101,183,106,134, 90,127,232,214, 81,170,234, 4, 55, 67, 77, 79, 98,235,149,126, 28,221, 94,143,126, 88, +221, 10, 60,248, 56,253,212,191,255,201, 73, 81,125,144, 79,138, 98, 32,240,172, 85,248,101,133,210, 92, 37,198,126, 33,119,219, + 59, 10,173, 6, 26,195, 96,246, 63,187, 7,240, 80,129, 71,218,255,189,215, 89,239,132,215,191,224, 95,239,207,172,135,241,180, + 50,183,105,231,247,167,170,181,160,234,143, 15,189, 17,223,112,153,247,205,102,234,247,240,125,113,135, 6,250,169,236, 20,159, + 42, 82, 88,118, 65, 22, 96,196, 98, 16, 26, 0, 27, 7,208,204,197,226,189,133,138,219,160,129, 73, 4,179,122,196,170, 79,145, +173, 91,215, 58,245,181,123, 55, 1,172, 16,245,130,129,185,174,107,105,245,106, 69,209,135,222,214, 74, 84,109,214, 93,181,224, + 32,169, 30, 55,188, 68,254, 80,247,185, 38, 32,216,239, 90, 35, 79,227, 33,173,118, 3,114, 74, 82, 8,229, 86,102,156,228, 25, +174,232,222, 68, 20, 11,207,224,148,186, 93, 45,183,144, 16,138, 78,159, 91, 64,188,143, 22, 73, 45, 93, 75,217, 98,228, 56,101, + 59,164,217,105, 63,153,189,244, 22, 55,233,115, 87,241,105,203, 94,215,235, 21,228,236, 42,217, 56,100, 40,246,122,234, 90,171, +248, 36,109, 9,250,234, 37, 80,206,253, 82,120, 14,216,189, 27,216,254,127,192,110,182, 11, 59,212, 92, 97,107, 67,129,102,155, + 72,224,145,119,252,187, 64, 59,145,249,163,239, 20,224, 50,217, 5,181, 79,166,138,244,184, 88, 83,110,251, 46,254, 40, 77,197, + 92, 71, 46,237, 48,228,108, 16,159,116, 57, 3,229, 18,152,128,244,183, 78,160,227, 75,160,247,127, 24,184,243, 39,128,221, 7, +129,147,127, 30,244, 29, 27,104,249, 97,164,255,103, 11,188,229, 20,244, 26,128,199,118, 61,149,193,119,205,125, 37, 77, 77,196, + 13,182,175,197,196, 38,126,202, 90,197, 85, 82, 98,114,227, 93,227,134, 65,143, 1,122,129,128,183,189,207,110,187,253,111, 2, +211,139,208,195, 99,224, 66,172,179,190,152,161, 15, 14, 40,231, 35, 38, 17, 28, 19, 87,142,188, 82,168, 76,131, 80,152,252,251, +240,185,236, 54,128, 51, 98,251,241,209,198, 44,122,112,214,251,140,234,115, 15, 33,165,198, 84,104,240, 41,206,229, 12,236, 12, +198,105,159,177, 55,250,233, 62,185,248,209,170, 92,161, 25,101,158,172,242,166,138,241,175,106,221,224, 88,151,197, 1,214,230, +241, 13,230, 97, 2,190, 27,189, 81, 55,128, 51, 8,180,216,199,153, 24,145,205,123, 76, 75, 13,109,196,103, 82,143, 94,101,191, + 68, 74, 99,100,115, 87, 38,146,155,189, 19, 90, 87,102,202,117, 66, 97, 31, 13,250,205, 82,164,185, 34,184,227,120, 7,195, 98, + 16,131,147,192, 71,211,165,235, 24,215, 7,126,245,197, 67, 59,150,120,235,178,226,128, 86,106, 69,122, 4,174,204,157,143, 89, +253, 57,239, 3,137, 34,140,101,115, 67,142,125, 37,238,173, 73,115,218, 46,236,254,222,231, 78,212, 23, 93,114,252, 57,162,150, + 95,111,235, 10, 83, 26, 23,166, 26,121,203, 93,199, 40, 55, 20, 55,138,158, 30, 71,216,185, 82,241,138,129, 25,140,209, 95,127, +170,226, 65,155,112,136,119,246, 45, 85,147,106,145, 39,157,215,190, 63,161,171,162, 62, 34, 80,253,159, 93,194,114,218,195,142, +217, 7, 8, 9,214,162,205,155,193, 50,116,173,111,199,151,180,151,181,255,161, 11, 61, 73,205,102, 15, 61,148, 59,107, 4,215, +227, 94,105,229, 56, 33, 90,105, 33,186,162, 58,194, 91, 90,120,146,214, 0,170, 40, 52, 98,180, 45,201, 62, 37,165,204,254, 76, + 16,198, 34,152,167, 17, 74, 84, 1, 63, 80,159, 56,167,100,141,166,154,151, 92, 35,124,140, 93,127, 70,221, 78,202, 71,108, 53, +208,139,121,241, 26,104, 47,213, 15, 26, 97, 21, 19,117,233,134,212, 86, 69, 11,240,167, 58, 88,170,211,166,229,240, 46,199, 87, + 73,213,103,167,254,159,173, 51,177,228,170,230, 79,175, 94,244,240,165,219,156, 3,234,163, 13, 94,236, 8,219,135, 85,212,246, + 39, 49,214,215, 58,191,243, 31, 68, 92, 62, 11,216,168, 35,101, 19,220,185,255, 79,184,249,187,235,115,170,237, 0, 66,135, 17, +228, 10,152, 33,204,162, 30, 17, 75,208, 98, 30,107,174, 74, 99, 69,137, 52,181, 93, 6, 94, 62,130,246,159, 5,110,253,147,150, +159,190,251, 10,224,244, 14,112,242,170,207,133,219,108, 95, 75, 76, 33,164,138, 37,232, 53,106,151,250,157,108,145, 65,183,217, +124,238,167, 9, 56, 20, 80, 33,232,145,150, 80,106,114,245,207,212,118,117, 90,137,101,214,165, 20,239,188, 84, 10,112,225,162, +187,164, 72,191,116, 10,197, 67,208,215,255,101,227,153, 15,223, 0,108,190, 19,244,161,223,134,158,255,239,224, 95,219, 0, 47, + 40,114, 1,112, 57, 90, 44, 45, 58,225,106, 66, 85,200, 27,205, 34, 16,190,246,189,133,186,184, 72, 4, 62,152,243, 32,101,247, + 15,159, 43,232,143,156, 0,219,119, 1,135, 87,129,253, 47, 2,135,207, 0, 15, 20,184,175,192,197, 4,125,124, 68,121,120, 68, +185,156,113,100,178,176,130,154, 2,232, 81,150,108, 54,147,214, 78,145, 81,222,110, 51, 48, 12,118,195,158,187, 64, 78, 44,200, + 69,103,255, 85,252, 1,146,149, 1,124,240, 35,100, 15,187,216, 15,197, 57,160,113,242, 91,149,173, 83,105, 34, 59, 47,182, 52, + 19,102, 49,247,128,176, 29,144,202,192, 60, 95,199, 37,172,113,169,212,237,176, 67,173, 91,104,181,119,212,235,104,179,122, 96, +121,117,144, 83, 51, 89,244, 24,214,216, 59, 6, 52, 8,157, 64,201,146,216, 90,119, 25,206, 5, 74,181, 46, 94,170,144,137,161, + 89,236,115,233, 44, 5,245,228,185, 74,189,227,118,123,115, 38,112, 49, 81,224, 20, 24, 82, 93,130, 88, 24,138,169,187,176, 43, + 69, 43,114, 26,170, 56,110, 89, 32,233, 13,157, 31,176,236,202,121,213,189, 17,154, 7, 92,213,133, 75,234,144, 36,146,250, 81, +136,203, 55,225, 6,198,187, 23, 65, 76, 75,202, 98,241,169, 76,234,136,126,161,141,141,215,165, 72, 28,200, 13,163,219,176,180, +198, 32, 79,186, 84,183, 39, 38,220,242, 29,242, 35,109,221,218,164,150,133,174, 62, 37, 8, 81, 96,181,175, 81,123,189,162,219, +157,189, 64, 80, 16, 70, 63, 91, 83,119, 21,132, 93,242,216,197,160,214, 60,249,174,104, 91, 20,138,175,211,161,235, 13, 94,127, +220,208,233,211,181, 97,187, 94,143, 26, 14,212,184,234,245,231,103, 69,252,187,105,100, 93,187,122, 63,147,215, 95, 87,187, 48, + 45, 84,189,137, 88,130,104,232, 82, 72,234,180, 3,228,224, 53,191, 92,179,163, 98,197,157, 95, 44,230,111, 87,103, 6,216,103, + 89, 22, 47, 70,124,190,169,118,156,188,180,223,233, 53,174,174,255,252, 22,235,170,244,250,133, 82,235,202,169, 90,161, 67,107, + 65,213,170,232, 24,215,228,151,120,186,198,120,215,106,172,143,202, 32,229,228, 99,135, 14, 66,227,112,139,154,214, 85,230,110, + 71,175,149,248, 73, 53,161,200,235, 53,181, 3,147,108, 25,224, 86,161, 25, 50,155, 23, 39,229,236,140,173,226,233, 98,102,123, + 9, 4,106,132, 99, 48,181, 55,172,127,225,194,234,102,135,154, 98, 96,211, 0,212, 45,128,218, 3, 95,216,158, 92, 58, 77,192, +200,208,251,191, 9,122,174, 0,186, 1,134, 23,140, 91,126,251,229, 70,114,153,220, 62, 87,164, 58,248, 56,249, 71,236,156,128, +151,124,129,149,217,189, 35,100,161, 33, 91, 6,109,200,172,110,147, 88,106, 27,100,233,163,153, 1, 34,113,162, 30,170,152, 39, +224, 12,147, 43, 90,139, 0,155,253,209,194, 86,102, 65,250,133, 91,208,227, 35,208, 55,252, 48,112,247,219, 0,254, 67, 64,254, + 46,208,135,126, 21,184,255, 34,248,213, 13,228,169, 17,188, 7,134,163,162,108, 60,132, 34,160, 38,131, 5,210,105,169,128,106, +228, 29, 97,251,149, 59, 28,239, 77, 56,124, 97, 90,104, 2,205,172, 64,254,186,101,224,221,103, 64,121, 14,152, 62, 9, 28, 62, + 1,125,181, 0, 15, 8,120, 92,160,143, 39,200,171, 87, 40, 15,143,166, 51,164,198,170,103,136, 11,198,188, 0, 36, 11,113,161, + 68,224, 76,118,161,223,102, 32,139,181, 26, 71,231,188,239,197, 46,115, 9,230,123,105, 40, 94,238,144,199,148,236,247,231, 98, + 28,121, 36,128,199, 46, 89, 36,162,115, 93, 13,229,102,107,114, 70,168,248,231, 99,227,197,246, 88, 86,251,207, 21, 91, 35, 45, + 84,209,173,189,144,110,151, 86, 15,172,132,101,128,117, 20,210, 97, 91,235, 97, 76,113, 33,178,143,154, 67, 13,223,157,128, 86, + 7,233,226, 84, 84,223,191, 65,154, 46,130,250,175,231,207,143,106,194, 20, 11,224, 4,179,180,117,231, 0,119, 17,166,129, 27, + 29,224,184,104, 44,233,120,212, 93,192,189, 99, 32, 14,244, 41, 70,240,145, 59, 79,215, 47,134,168,245,103, 89,238, 80,231,238, +114, 56,106,203, 7,143, 93,115,133,163,116, 59,199,212,177, 0, 66,246,146,180,159,128,180, 81,119,175,157,239, 83,191,234,100, + 35,132,166,161, 27,242, 3,211,234, 73,170,230,101,238, 24,230,179, 3,127,224,227,114,192,206, 74, 86,197,142,128, 19, 53,113, +225, 72,228,197,128,113,235, 51, 20,165,203,160, 47,129, 10, 69,248,182, 9, 59,163,122,184,189, 45,240,195, 84,115, 51,162,144, +236,127,159,171, 96,177,195,151,214,158,183,157,249,170, 95,202,106,246,165,187,116, 93,119,248,215, 19, 90, 42, 91, 93,181,125, +237,228, 94,110, 93,105, 38,234, 46, 61, 46,103,194,194,129,181, 96, 5, 4,218, 92,122, 24, 81,151,200, 39,237, 25, 13,103, 74, +157, 70,145,193,209,214, 69,138,101,142, 21, 16, 89, 50, 41,177,180,221,183, 83, 47,137,150,133,235,178,217,108,254,121,186, 9, +162,235,119, 48, 92, 92, 87, 95,199,170,121,107,163,122,187,234,186, 72,111,255, 90, 57,178,203,147, 87,167,138,181,120,199,241, +156,107,178, 91,221,230,184, 80,142, 9,156,125,156, 94,189,184,113, 97,248, 91, 85, 12,255, 74,145, 58,133,142,235, 30, 94,246, +154,194, 6,191, 44, 45, 83,136,216, 70, 30, 80,177,177, 7, 90,162, 91, 36,224,196, 36, 96,157,207, 87,247,138, 94,161, 14,209, + 53,177,118,234, 68,135, 98,136, 34,179,128,230, 12,124,246,147,192,187, 30, 0,252,188,197,160,238,190, 26,116,251,163,208, 77, +105, 39,175,103,202,235,104,136, 81,241,253,138,238,253,199,126,149, 13,233,116, 55,217,105,114,151,129,243, 12,202, 51,148, 11, +104,199,160,131, 93,236,117, 27, 68,189,242, 81, 59,179,107,219,213, 73,176,198, 61, 88,101,115, 60, 2, 15, 11,100,156,145,127, +254, 22,240,202, 30,120,255,255, 13,122,203, 63,180, 81,252,237,111, 6, 62,248,179,160,255,229, 33,210,110, 7,188, 65,128,135, + 19,184, 20,168,159, 60, 82,108, 2, 80, 52, 68, 87,118,136, 83, 1,240, 96,194,197,171, 51,246,179,214, 92,241, 29,155, 6,128, + 78, 9,116,197,160,223,123, 10,122,211,115, 64,153,129,227,223,129,190,118, 1,124, 97, 11, 60, 60, 2,143, 39,219,163,191,188, +199,248,100,196, 33, 51,142,165,211,123, 6,175, 94,235, 56,192,192,235,202,160, 77, 2,221,202,198,123, 87, 24,231,125,223,161, + 97, 39,133, 30, 20,178,159,161, 71,159, 92, 12,238,107, 47, 0,111, 24,180,181,255,110,144,108,182, 89, 38,147,125,190,212,175, +153,228, 33,204, 27, 24,193,142, 24, 12, 27,201, 77,197, 95, 11,183,252,181,209, 52,215, 49,109, 85,179,251,134,136, 74, 11, 71, +146, 14,206, 17, 54,152,224,110,107, 99, 57,213,200,207,184,208,213,112,244,214, 33,122, 93, 34,253,254,218, 5, 70, 77, 60,230, +138,245,210, 35, 99,125,231, 22, 30,250,200,206, 22, 93,100,141,199, 62, 47,226, 63,213,191, 86, 78,230, 79, 19,135, 66,145,235, + 40,138,134,168, 79,107,177, 82,191,218, 42,121,142,125, 42, 35,157, 91,101, 88,236,223,181,139,221, 92,238, 96, 85,232, 90,135, + 24,245,200,216,133,213,100,162,150, 72,215,253, 26,252, 57, 65,135,130,221,186,143, 62, 0, 71,225, 34,152, 98,255,172, 75,197, +117, 79,145,107, 99,234,200, 97,111,183, 75, 80,242,138, 87, 77,228,137,145,165, 27, 19,251,233, 85, 35,107, 99,228,127,215,139, +151,135, 98,255,174,185, 4, 4, 7,109,154,218, 40,238,234, 20,175,131,199, 8,140, 96, 93,188, 5,210, 5, 8,199,125,237, 74, +216,185, 56,175, 26,129,253, 80, 9, 20,114,209,155,179,210,251,223,227, 27, 58,243,215,219,127,119,181,227,226, 47,109, 84, 66, + 93, 68,223, 74,115,100,131,169, 81,230,250, 32, 35,189, 1,108,163,171,194,154,233,186, 48,175, 77,103,216,255,191, 96,170,249, + 36, 49,225,113,142,191, 68, 81,214,126, 26,209, 2, 42, 38,236,206, 41,119,107,170, 46,106, 55,180, 72,221,228, 64, 87,118,221, +197, 40,189,183,151,241, 42,238,208,149,114,150,235, 66, 45, 33, 49,214, 73,125, 94,124,104, 53,226,133,163,107,240,186, 62,102, + 18, 21, 71,151, 22,194, 54, 50,100, 44,115,243, 47,182,214,203,109,106, 84, 95, 48,174, 23,184,184,247,189, 75,237,241,194, 2, +157,168,164,150, 86, 53,196, 55,217,158,149, 77, 20,164,197,222,148, 89, 5,204,169,218,178,156, 33,212, 69,225,105,221,141,204, + 98, 37,123,124,128,171, 29, 95, 60,221, 74, 92,128,117,107, 7,252,206, 19,224,240, 41,224,244,121,251, 40,108,222, 9,108,111, + 1,219,243,142,105, 79,208,217,119,227, 14,233, 22,144,169,182, 47,103,208,189, 88,160, 13,192,217,198,160, 41,103, 0,206, 25, +116, 72,141, 55,234,185,145, 90, 74,135,124,212, 5, 70, 84,187,241, 81,104,162, 10,128, 34,100, 98,191,177, 96, 83,174, 0,153, +145,254,193, 41,232,119,183,192,251, 30, 2,239,249, 89,208,155,222, 14,122,231,155,161,223, 86,192,127,251, 2,120, 14,192,238, + 0,121, 56, 65,142,179, 63,165,234,182,111,155, 98,176, 40,230, 4, 28,175, 20,227,163,201,124,181,126,184,108, 7,155, 36,164, +228,134,196,153, 65,239,223, 0,195, 91,140,210,118,249,162, 9,227,206,103,224,201,136,242,218, 30,229,229, 61,166,251, 19,206, +137,219,223,165, 38,118,138,181,115,188,221,217,127, 88, 74, 0,221, 74,192, 29,159,118,204, 98, 43,135,163,216,216,125,180,238, + 92,199,201,225, 64,102, 95, 35, 1, 56,101,228,103,119,224,119,238, 32,159, 57,122, 96,183,199,178,130, 12, 64, 51,189,232,175, +240, 96,183,102, 78, 86,245,109,168,222,212,226, 39, 68,114,175, 88, 47,142, 99,191,128,235, 33,195, 90,179,234,235, 46,122, 33, + 62,181, 98, 41,245, 9, 93,171,118,128,169,169,176, 77, 32,166,216,116, 11,217,234, 20,224,128,129,116,118, 50,191,108,213, 11, + 66,113, 74, 96, 5,135,112,219,163, 22,174,102,145,197,197,198, 93, 33, 18, 10,238, 56, 3,184,179, 10, 38,210, 5,155, 93, 52, + 18, 26,215, 97,154,141, 2,201,193,148, 32,120, 16, 20, 85,186, 28,186, 61, 42,117,211,128,198,255,198, 53, 31,111,188, 30, 7, + 7, 32, 69,178, 30,119, 99,107,243,122,219,139,181,131,226,148, 2,186,226,151,152, 56,173,175, 19,106,114, 71,123,211,174, 91, + 95,159,143,189,129, 37,206,179,236,197, 86,129, 11, 10,125, 18,161,218, 60,239,189, 55, 41,200,113, 3, 1,119,200, 20,241, 79, +212, 10, 70, 37,198, 36,197, 24,224,110,173,227, 53, 14, 53,192, 92,176,142, 63,107,155, 90,246,249,242,179,127,135,183, 59,245, + 59,200,215,121,205, 86,191, 24,171, 7,140,136, 86, 30,248,215, 27,201,223,212,177,215,224, 22,255,220, 44, 46,249, 40, 45, 92, + 83, 37,184,249,235,172,217,238,139,187,131,156,113,177, 2, 56,209, 10, 14,132, 78,115, 33, 90, 0, 98,204,165,120,231,205, 85, + 67, 22, 5,170,168,184, 12,220,222, 67,213, 98, 54, 53,181,116,198, 33, 39, 28, 60,128, 69,231,210,105,211,204,115, 30,214,237, + 94, 23,181, 12,198,105, 33,105,186,250,112,171,234, 2, 8, 23, 86,239, 5, 67,160,183,215,118,226,136,220, 95,222, 11, 43, 69, +215,181,171,239,108,134,196, 93,229,205, 72,217, 46,116, 18,133, 56,101,103, 65,161,163,190, 3,247, 23,183,120, 71, 47, 22, 29, + 70, 29,216,161, 97, 8,189, 43,170,163,127,243,252,177,179, 41,153, 18,204,212,102, 3,168,172,108, 59, 67, 54,145, 2,117,187, +196,120,136,106,101, 44,132,145, 21, 3, 45, 71, 65, 10, 96, 2, 97, 26, 5,219, 39, 51,244, 41, 0, 47, 23,208,131,127, 8,156, +125,192, 46,221,252, 20,112,114, 23, 56,125,140,106,226, 71,228,216,250,104,100, 38, 43, 42, 84,173, 8,185,240,241,244,206, 23, +163, 27, 0,119, 1, 92,100,208,149, 9,188,120, 16, 72, 41, 54,242,214,235,130,105,149,182, 63,237, 33, 21,161,143, 40,158,168, + 53,123, 58,214,246,201, 1,121, 63, 33, 29,182,200, 15, 79, 64, 47, 19,244,247,125, 1,244,182,167, 65,223,240, 12,244,188,128, +127, 67, 65, 59,167,123,157, 43,228,114, 70, 81, 96,156, 20,199, 66, 11,143,173, 56,228, 98,164, 38,100,225,122, 88, 2,184, 2, +248, 93,183,128,183,109, 1,121, 6,192,185,155,104,147,229,207,191, 58,162,124,113,143,233,254, 1, 79, 70, 96,239,194,162,210, +209, 85, 19, 55,114,176,166, 21,248,154,201, 4,114,196,192,147, 17, 56,159, 0,177,203, 92,198,217, 58,245, 89,128, 99,177,131, + 83,140,194,151,158,201,224, 63,254, 38,224,168,160, 79,222, 51,237,195, 35, 1,222,154,128,111,217, 1,211, 30,184,250,152,249, +233,161,150,124,115,178, 74,238,112,227,108,124,126, 39, 68,148,102, 75,150,170, 33, 72, 21,226,228, 69,133,218,207, 34,101,181, +251,149,128,213,248,123,156,154,102, 65,168,159,136, 53, 23, 71, 4,118,204,107,100, 42, 26, 99, 54,249, 8, 54,190, 7, 13, 27, + 39,119,151, 15,147,137, 28,181, 41,164,251, 28,241,224,138,135,144,172,196,254,152, 21, 92,150, 59, 76,210,166, 56, 7,217, 0, +100, 46, 77,137, 22, 48, 29,234, 24,227,234, 99,228, 44,237,178,184,150,138,230,226, 51,146, 54,129, 8, 82, 94,205, 15,143, 38, + 65,123, 14,185,214, 21,197, 16,138,245,216,128, 57,249,112, 19,170,246, 14, 66, 51,119, 84,182, 62, 87,189, 58, 79,168,105, 40, +215, 23,133, 84, 94,128,221,164, 19, 8, 91,106, 66, 56, 37,211, 25, 69,220,110,184, 8, 82, 45,128,216,255, 14,155,184,100, 54, +254,250,222, 33, 81,129,150,157,203,140, 89,230, 58,246, 79,157,238,172,208,178, 43,182,129,147,107, 10, 58,249, 88,238,126,182, +187,254,135,207,197,146,221,116,101,125,147,158, 97,161,171,120, 94,220,156,163,190,206, 26,232,221, 16,116,237,146,239,189,236, + 88,169,185,151,127, 22,171, 34,224,154,181, 78,227,190,106,109, 49,215,176,161,229, 61, 0, 38, 23,126, 39,204,170,152, 74, 65, + 82,173,233, 66,169, 91, 55, 36, 15,226,153,165, 56,103,189,205, 23, 44,122, 85,145, 83, 66, 73, 25,101, 46,109,246, 17, 14,176, +133, 37,184, 41, 41,235,190,189,254,115,170,218,153,126, 53, 87,109,145, 62,247, 87, 18, 44,205,200,254,222, 74,139, 62, 87,102, +243,169, 83,181,174, 81, 21,140,244,187,194,196,140,156,216,187, 8, 70,206, 25,156,147,121,104,231,217, 41, 87, 33, 46,241, 81, +187, 56,218,115, 81,165,249, 7, 93,164,230,206,114,141,175,236, 55, 12, 90,191, 31,138, 25, 98,177,165, 95, 8,221,108, 20,202, + 0,101, 16, 44,197,134, 96, 33, 46, 66, 12,114, 97, 76,237, 44, 84,160,106,160,254, 18,177,137,157, 30,138,184,137, 72,110, 93, + 58,121,108,206,208, 23,127, 13,244,214,189,213,200,124, 98,214,182,211,207,181, 36, 20, 54,130,144, 42, 42,250,149,130,245,152, + 93, 29,127, 14,208,203, 62,235,123,118,107,229,246,211,217,196,114,158, 1,142, 98, 99, 29,157,157, 15,223,193, 9,122,152, 70, +139,150,109, 67,145,232,231,139,211,190, 70, 34,108, 39,193,246,201, 30,122,156,145, 14,179,135,116,100,208,219,206, 64, 31,184, + 11, 61, 8,232, 11, 64,122,214, 22,142,186, 47, 40,123,207,114, 22, 64,192, 21, 0,163, 2,140,213,163,109, 16, 12, 48, 76,104, +152, 0, 62, 2,252,245, 59,208, 16,201,107, 23,118, 67,157, 37, 96,231, 76,247,243, 25,135,163,224, 64, 9,135, 82, 3,235,236, +107,144,219,154,130,192, 43,106, 23,123, 60,184, 91,216,132, 67, 11,112, 25,204,125,177, 14,116, 20, 72,237,216,255,127,198,222, + 45,214,186, 44,187,239,250,141, 49,231, 90,123,159,115,190,239,171, 75,119,117,117,181,187,221,118,219,177, 29,108, 18, 59,177, +157,155, 29,146, 16, 64, 40, 79, 33, 68, 81,128,135, 4,164, 16, 9,129,120, 8,239, 65, 32, 16,215, 7,224, 33, 40,188,192, 19, + 10, 2, 9, 41, 70, 74, 32,196, 36, 16,133, 64, 18, 39,142,113,220,238,118,187,219, 93,221,213,117,253,110,231,156,189,215,154, +115, 14, 30,198,152,107,205,125,170, 58,144,168,228,170,254, 46,103, 95,214, 90, 99,142, 49,254,255,223,191,109,118, 48, 81,113, + 83,241, 87,239,176,191,125, 71,187, 45,126, 45, 93, 37,248,210,236,175,237, 27, 2,245,180, 47,182,147,238,214,136,117,168,176, + 38, 81,119,119,160,133, 12,234,104, 19,208,100,100,243, 3, 16,205, 46, 70,110,250, 32, 80, 37,169,132,170,222,208, 7, 39, 97, +189,160, 45,246,233,152,109,154,193,126,198,209, 7, 15,212, 20, 98, 45,237,215,160,250, 24, 86, 59, 76,100, 56, 8, 20,113,112, +203, 50, 82,204,228,210, 55,222,163,100, 83,116,212,246,160, 93,147,173,127,240, 14,217, 2,232, 39,189, 57, 48,127,166,148,113, + 4, 31, 98,188, 50, 48,222,215, 22, 98,213, 33, 93,172,201,206,208,238,191, 38,131, 24,118, 76, 69,235, 5,186, 79,249,242, 48, + 57,232,221,120,119,188,108,170,246,193,130,215,226,160, 86, 54, 62,254, 94,236,107, 28,244,237, 98,159,126,105, 53, 45,131, 54, + 64, 90, 80,136, 17,159, 6,244,160, 22, 81,154,212,109,220,190,154,119, 83,115,208, 51,251, 99,115, 59, 88, 8, 28,195,215,239, + 78,164,180, 1, 76, 74, 93,247,156,140, 88,125, 20,219, 73,110, 53,254,220, 14,247,186, 68,180, 90,199,246,138,175, 89,102,133, +167,230,124,130, 58,236,228,245, 1, 32,233,130, 14,103,151, 99,239, 81, 32,122, 81,184,135,206, 83,185,204,101, 31,133,114, 31, +215,212,127,130,189,250, 19,211,225, 46,251,125, 29,212,152,194,190,126,234,255,187,108, 33, 50, 26,250, 7, 15, 24,219,109,134, +157, 70,232,127, 71,109, 70,109,213,181, 97,145, 23, 66, 36,128,214, 90,161, 86, 14, 57, 83,115,166, 46,203,160, 84,237,141,222, + 30,191,219, 68, 55,163,229, 37, 88,134, 45, 36,201, 66,173, 63,102, 65,192,238, 65,255,216,126, 62,180, 44,194,110, 87,218, 26, +173,126, 52, 72,114,121, 10,245,184,186, 68,206,126,230,201, 41,145,167,217,111,242, 90,247, 93,222,166,164,216,227, 88, 85,186, +221,109, 15,214, 27, 71, 86, 4,172,166, 35, 94,251,254,184,159,198, 71,101,171, 10,113,106,175, 36, 75, 30,105, 24,163,246,166, +234,224,148,174,174,143,211, 47, 10,137, 11, 79,216, 32,104,150, 93, 0, 56, 4,157,136,193, 57, 65,185,171,232,243, 21,121,116, +128,175,188, 11, 63,249, 54, 76, 63, 4,233, 10,242,247,192,205, 47,186,133, 11, 13,143,164,186, 95, 90,109,112, 74,198, 72, 41, + 27,122,231,186, 3, 14,103,127, 10, 61, 14,255,250,107, 13, 57, 53,184,173,232, 57,209,104, 97,135,169, 99,102,142,255,109, 50, +140,220,251,248,125,195, 58,198,124,163,249, 94,113, 85, 71, 32, 22,140,235,187, 51, 83, 49,248, 7, 74, 58, 42,150, 64,190,231, + 6,126,215, 19,248, 95, 27,170,110, 33,108, 31,158,177,231,141,146,166,136,165,245,207,116, 83, 76,203, 62, 82, 22,133,137, 40, + 52, 77, 32,207,240,197, 43, 44,221, 32,245, 29, 40,223,118,208, 75, 82, 47,172, 55,254,225, 23, 81,135, 56, 52,134, 14,172,143, +133,119,247,182, 89,196,156, 87, 65,102, 69, 30, 37,111, 3,215,230,187,244, 90,177,197,104,119, 43,237,222,211,236,108,173,251, + 67, 49,108,113,235,251,247,216,127,191, 4, 60, 61,161,175, 95,195,143,100,228,149, 43,176,199,208,190, 1,211,167, 65,174, 92, + 52, 39, 2,231, 21, 78,234, 35,253,184,198, 71, 79,121,227,242,115,232,187,241,238,215,215,161,155,126,136,193,244,149,153,109, +194,183, 54,140,194, 68, 46, 28, 63, 91,244,166,138,175, 39,242, 32,255, 61, 74,247, 32, 59,161,173,231, 37,148, 16,122,109,106, +225,100,212,234, 93, 91, 11,141, 73, 7,185,172,178,147,238, 76,119,110,120,181, 93, 65, 91, 6,156,170, 60,200, 50,207,178,191, +207,113,199,175,195,238,216,134,226,144,128, 41, 41,214, 4, 93,140, 22, 81,176, 23, 29,157,141,107,132,253, 64,128,108,209, 10, +241,235,126, 40,185, 22,119,142,106,240,203,117, 40,238,189,240,204,161, 79,245,113,188, 31,232,235,112, 95,149, 65, 81, 95,135, +169, 65, 31,183,143, 92,117,196,134, 60,123,255,188, 78,241,185,245,201,100,137,239,193, 26, 28,213, 2,147,171, 17,107,219,182, +238,235, 62, 14, 12,115,136,138, 25, 28, 8, 34,112,101,198, 25,227, 44, 29,203,236,182,133,148,140,220,124, 12,156, 98, 28,255, +188, 99, 98, 7,240,237, 39, 97, 85, 71, 69,249, 20,248,216, 3,240,170,248,159,127,106,254,119,209,184, 16,104,217, 39,116,216, +246, 96, 74,242, 73, 49,171,227,218,169, 31, 42,251,225, 32,125,146, 16,220, 46, 27,202, 11,246,195,240, 35, 26,123,124, 44,193, +126,239,153,236,109, 16,152,118, 91,143, 88,136,102,187,112, 78, 28,217, 44, 67,168, 82, 11,187,154,201,110, 23,221,142,114, 54, +116,202,219,228,162, 81, 91, 37,155,215,200, 53,197, 51,163, 61,220,255, 71,231,190, 5,178,216,158, 99, 60, 28, 93, 68,190,139, +129,208, 62,225,127, 29,214,107, 61, 81,179,119, 4,210,105,160,200,104,235,136, 81,158,122,234, 75,202, 19, 42, 48,165,228,169, + 52,165, 96,181,184,234, 54,167, 61,166,117, 16,248,104,223,187, 15, 86,158,189, 11,217, 25,243,180,134, 73, 10,200,130,207,227, +198,174,158,190,235,232,179,159,152, 8,152,164, 77, 49, 44,177, 92, 76,129, 13,109,214, 80,177,205,111,232,210,199, 97,227,101, +182,185,118, 91,220,173,146,252,102, 95, 13,150, 38,172,107, 99,250,112,197, 94, 57,194, 55,238,145, 15,255, 38,188,245, 35, 80, +103, 56,252, 38,228,201, 95,193,166, 53,210,195, 4, 73, 13, 59,143, 75, 40,245,180, 51, 51,172,130,205, 70,187, 19,244,125,129, +195,226, 10,179, 43,133, 87,147,251,214, 75, 70,175, 93,189, 45,197,144, 82, 47, 18,212, 90, 40,224,123,129,237,227,223,106,178, + 41,117,187,181,105,141, 12,224,170,208, 84, 48, 21,110,150,130,124,248, 18,249, 37, 65,143,134, 77,138,188, 57, 99, 63,253, 4, +254, 90, 69,175, 27,114,179, 48,127,180,146,172,208,204, 85,195,155,176,164,139,103,162,203,153,155,243,222,147,250,232, 61,253, +200, 12,175,205, 72,170,176,126, 21,158, 47,216,123, 13,238, 23, 56,175,113, 98,110,152,122,145,217, 60,170,109, 31, 51,183, 7, +196, 53,233,208,161, 89,124,159,158, 92, 65,207,157,139,227,218,253, 74,187, 43, 78,118, 90, 43,245,108,145,179,220,173, 66, 70, + 43,149, 85,141,212, 38,242,205, 1,126,230, 0, 63, 32,112,252, 45,206,231,124,244,127,186, 93,177,171,219,106,241,133,230,210, +176,151,149,182,238,126,217, 58, 88, 62, 91,218,187,207, 52,176,199,183,180, 51,251,132, 16,146, 17, 12,209,117, 4, 35,254, 49, +108,139, 93, 68,170, 98,155,105, 98,138,207, 93,163,221,153,227,254,220,167,113, 29,149,233,226, 79,171, 67, 16, 96, 12, 56,212, + 70,110,183, 95,186,107, 40,171,187,205,205,234,142,141,221,114,161,183, 7,169,108, 29,222,106,195,238,115, 0, 97, 72, 29,112, +208,114, 25, 69, 74, 20,222, 47,228,196, 15,253,233,215, 56,253,218,202,207,255, 79, 47, 88,180,110,185,240, 34,187, 55,125,204, +207,110, 31, 43, 25,141, 73,125, 35,115,140, 29,250, 33, 58,246,195,224, 61, 47,195, 33, 97, 14,183, 76,141,233,192,194,254, 93, +241, 9,133, 47,109, 5,209,182,247, 62,160,187,221, 34,187,117,233, 62,182,173,155, 23,168,139,224,124, 20,223,209,164, 30, 88, +211, 11,155,110, 19,130,110,255,237,105,135, 26,118, 56, 84, 67, 87,208,168,230, 35,252,132,112,147,179,143,119, 91,221, 2,160, + 22,115,241,219,102, 53, 30, 62,187,244, 64, 96,120,148,125,125,145,250,103, 38,240,174, 25, 95,110,178,225,127,215,161, 32,247, +107,185,125, 12,129, 40,223, 85,241,254,208, 87,126, 97,249,250, 46, 52,191,209,197,253,208,223,223,203,192,212,143, 46, 50,122, +210,173, 27,187, 46,184,240, 12, 53,173, 79,138, 26,144, 74,101, 74, 74,155, 18,101,141, 48,175,176,172, 89,232,197, 58,201,109, +139, 56,189, 96, 68, 64,173,149, 82, 11,146, 60,103,189,172,235, 62,102,231, 50,215,100,131,196,116,191,185,236,159,128,141, 29, +248, 54, 95,177,253,122,219,141, 72,241,190,122,188, 97,219,185, 21,131, 48, 47, 51, 60,152, 70,116, 93, 74,137,249,112,140,204, +102,239,212,235,178,108,180,174,113, 28,214,187,100, 21,245,135,141,237,227, 57, 29,200,114,189,208,111,167, 50,147,176,132,196, +120, 36, 58,119,207,136,238,127,191, 99, 62, 83,192,107, 90, 51, 68, 42,154, 52,190,196,120, 88,137,239,213,173, 4,127,217,243, + 75,221, 46, 23,199,202,142, 63, 85,118, 85,124,231,199,247, 81,218, 25,225,100,141,171,219, 51,172, 87, 32, 87,216,215,254, 26, +242,214, 31,243, 39,223,244, 37,120,244, 58, 60,249, 22,124, 71,246,150, 77,234,222,210,230,234, 92,247,136,254,172, 40, 58, 23, +228, 37,200,119, 98, 4,252,153,131,255,223, 79,185,239, 90,106, 67,215,176,117, 88,130,243,128,100,221, 66,225,194,198, 22, 94, +245, 58,140, 10,155,237,161,136,219,174, 51, 32, 33, 96,112, 90,224, 91,183,228,100,232,141, 96,250, 8, 62,115,132, 31,187, 70, +254,247,149,244,202,204,244,209,137, 71,207, 43, 77,109,139,214,236, 87, 69,177,184,217,197,200, 41, 56,222,193,193,151,159,188, +114,170,222,169,120,200,202,211, 21, 62, 90,225,105,161,125,176,210,158,158,169,167,194, 34,187,224, 40,244,128, 27,112, 38,201, +131,174, 44, 43, 50,137,115,222,175,162,226,220, 45,112, 46,212, 82,105,167, 74, 91,156,202,103,167,230, 73, 69,253,230,173,248, +159,157, 4,121,169,164,215, 15,200,207, 94, 33,191, 45,193,107,223, 15,135,159, 5,251,187,240,248, 10, 30,253, 33, 79, 59, 97, +129,245, 12,207,103, 56,249,123,105,193,106,110,131,235, 35,133,229,176,213, 88, 89,109,247,207, 78,112,179,225,193,218,134, 29, +120,191,207, 90,252, 55,131,208,173,197,110,116,251, 59,163,160, 31,196, 41,136,185, 19,228, 34, 67,189,239,254,182, 60,244,200, + 56, 0,241, 49,188,121,241,213,176,207,140, 99,250,115,172,138,114, 40,249,123, 71,166, 49,146,181, 40,248,173,249,195,114,137, +247,144,135,177,234, 22,192,216,125,230,106, 14,111,106, 59,161,178, 92, 76,232, 4, 45,198,231,127,112,230, 83,127,234,179,124, +231,223,125, 59, 44,100,186, 17, 40,221,158,231,175,127,244,208, 39,118,133,123,127,228,215, 10,171, 6,139, 61, 62,199, 28,121, +240,121,155, 20, 94, 10,255,186,176, 49,197,251, 28,133,124,187,132,218, 6,145,217,131, 76,249, 49,161, 79, 60,181,176,170,231, + 74,180,177,131,141, 66,127, 6,212,132,169, 55, 58,106, 78,245,139,233, 94,137,213,200, 58, 0,121,196,218,246,185, 46, 64,221, +158,183,190,210,172,145, 24, 54,171, 70,132,109,227,208,140,123,115,189, 64,137, 9, 0,230,107,178,113, 85,209, 15, 61,115, 92, + 87, 19,194, 1,227,213, 16,170,126, 20,135,236,105,216,239, 86,219,225, 64, 29, 73,108, 3,195,236, 99,180,188, 79,240,168, 63, +220,185,203, 39, 2,107,228,193,129, 96,224, 52, 6,169, 84,135, 73,212, 40,251, 22,121,200, 55,176, 75,229,189,236, 1, 65, 18, +153,227,158,175,145, 72, 8, 53,188,109,210,247,225,253, 61,181, 29,242, 42,195,200,193,164,139, 63, 43,173, 22, 44,133, 83, 70, +118,135,217,199,135, 23, 97, 27, 31,222,153,116,177,182,141,244,184, 75,101,193,197,103,170, 67,117, 31, 79,204,162,177,234, 22, +154, 53,239,212,181, 83,225,162, 70, 77, 41, 49, 29, 15,190, 55, 87,197, 90,161, 45,107,100, 53,142,175,115,143,147, 75,227,130, +127,179, 39,200, 38,102,209, 62,254,136, 27,184,191, 72, 29, 80, 12,210,153,238, 12, 62, 19, 11, 96,140, 73, 88,218,162,179,219, +104,114,187,186, 64, 52,147,181,120,102,238,134, 55, 77,180,230, 9, 57,157,102,183,239, 88, 90,252,247,136,118,244,132,170,114, +106,200,179, 21,125,243, 6,254,254,219,200, 79,124, 21, 14, 63, 10,211,235,112,253,121,120,229,155,142, 43,213,206,236, 12,238, +120, 53,247,160, 7, 75,222,215, 48, 70, 43, 6,147,145,146, 56,152,230, 74,225,149, 12,175,206,126, 92,191,173,200,148,144, 67, + 69,170, 98, 75, 95,137,184, 0,168,218, 3,161, 92,221,213,193, 45,212,146, 59,220,223,127, 61,137,231, 97, 91, 92, 12,122,119, +130,183,141,233, 23, 50,146,179, 43,137,126,248, 10,222, 61,145,254,110,193,222,186,230, 81,121, 9,247,198,253, 72,136,136,182, +167, 4, 24, 38,107, 24, 17, 42,104,155,224,211, 71,191,251,159, 23,231,203,191, 40,240,188, 97, 79,207,180,119,238,168,239,156, + 57,173, 94, 76, 74,187, 84, 92,111,240, 37,219, 39, 47,106,230,142,138,163, 34, 61, 24,103,109,240, 34,138,248, 82,177,123,215, + 61, 88,169,212,210,252, 80, 19,123,232, 52, 59,121, 80, 94, 10,249,250,128,254,204, 53,242, 59, 21, 94,255, 18, 28,127, 7, 60, +250, 97,104,191,232, 18,254,252,134,115, 72, 85, 93, 0, 0, 32, 0, 73, 68, 65, 84,223,250,245, 4,167, 2, 47, 38,184, 95,105, +247,171,103,168,199, 94,183, 67,153, 44, 68,130, 45, 78,220, 73,205, 31,218,195,216,118,203,188,139, 40,223, 60, 20, 17,141, 81, + 92, 69, 46,246,145, 41,212,236,155,142, 37, 30,188,199,188, 25, 19,252, 48, 5,148,102, 14, 58,209,216, 1,246,131,127,219,145, +171, 23, 65, 50,253,220,105,126,224,233,211,191,201,220,221,176, 70, 92,234, 20, 42,226,142, 65, 61,197,132, 70,101,232,214, 69, + 54, 55, 74,221,198,235,182, 17, 26, 77, 46, 19,198,198, 17,235, 57, 11,191,248,246,153,175,252,142, 47,243,206,169, 81,242,160, +180,111,123, 23,165, 54,132,214,236,228,219,173, 67, 86,204,187,210,104, 2, 90,136, 46,171,250,123,201, 15, 8,115, 41,246,215, +141,198, 57, 26,146,212,181, 41, 24, 41,104,149,107, 32,114,203, 16, 94,147,135, 17,189, 61, 40, 64, 61,188,165, 13, 10,103, 17, + 15, 70,233,175, 97, 17, 35, 53, 97,214, 93, 44,136, 53,154,213, 77, 85,191,142, 97, 44, 18,223,175,217,214,165, 75,240,188,187, +206, 66, 27,220,168,176,138,146,178,178,214,198,201,154, 31,228, 6,157, 71,126,160,148,159, 6, 58,222, 97,136,170,189, 53,191, + 55,207,248, 65, 69,255, 81,133,119,176,120,201,102,177,147, 61,206,214,246,231,127, 26, 86, 40,233, 19,236,111, 23, 42,240,255, +207,162,127,169,253,224, 31,137,175, 29,138,228, 32,156, 67,253,117,106,107,241,217, 23,212, 52, 82, 22, 53, 38,101,117, 72, 82, +220,201,115, 26,240, 24,179, 65,148,230, 32,127,102, 81, 74,210,143, 71,250,142, 25, 5, 49,126, 55,227, 1, 65,199,235, 27, 49, +173,186, 32, 1, 92,188, 87,217, 18, 4,205, 46,231, 28, 35,243,130, 62, 13, 84,118,110,123, 18, 97, 58, 30,200,121,114,243,253, +186,210,150,101, 51,196,143,126,112,137,211,189,198,194, 80, 6, 99,188,196,155, 87,235,102,122,219, 82,216,186,165, 67,182,227, +190,108,226, 56,137, 83,148, 14,129, 48, 18, 66, 55,105,145,187,206, 78, 31,186,200,207, 85,104,154,209,182,110, 97, 36,116,113, + 68, 43,174,218, 86,139, 8,203,222, 17,201, 54, 89,232,236,229, 5, 88,170,146,111,213, 49, 8,223, 17,236,237,255, 14,249,193, +223, 28, 32,154,239, 67, 30,255,173,128, 85, 93,178, 41, 77,125,207,220,106, 48,225,107,116, 32,217,104,201,124, 92,253, 29, 65, +166,228,119,217,227, 12,175, 39,120, 49, 35,165,185,111,124,109,200, 65,161, 42,170,141,244, 80,144,189,183, 12, 91, 81,111, 35, + 55,112,120, 0,166,234,163,185,151, 49, 98,189,185, 59,163, 95,123, 65, 62, 38, 56, 26,252,224, 53,252,212,171,240,110, 33,189, +231, 21,247,250,237, 91,210,226,147,232,206,121,111,125, 12,220, 15, 70,102,112,111,232,167, 50,242,102,134,251,213, 69,108,239, +173,240,108,197, 94, 20,234,123,247,180,119,110, 57, 61,175,188,192,155,248, 90,247,211,127,239, 96, 71, 94,245, 22, 5, 60, 43, +122,157,145, 39, 49,143,190,109,112, 50,218,185, 98,119,149,182, 84, 90,105,180,210,188,139,139,167,134, 22, 33, 29, 18,106, 9, +101, 34,253,236, 19,228,167,129, 79,125, 1,110,254, 41,184,250, 41, 79,222, 75, 97, 97,179,219,120, 1,247,216,121,133,187, 35, +237,174,210,238, 43, 69,246,232,210,222,221,173,163, 88, 77, 26, 71, 21,166,201, 11,156, 68, 18,108, 22,219,114,177, 51,123,199, + 36,195,200,119, 79,180,178,205,186,214, 39,104, 89,118,254,205,228,146, 17,166, 8, 20,233,157,185,198,153,186, 14,237,144,137, +109,215,159, 14,254,172,120,246, 92,104, 1,164,237,153,240, 50, 20,209,222,149,118,139,149,170,176,110,129, 49,251, 3,210,226, +243,104,195, 92, 52, 17,168,229, 46, 26, 77, 46,220,235, 35,102, 17,227,221, 72,204, 35,251,103, 35,173,131, 82,246, 70,160,155, +226,114,116,251, 15, 65, 58,189,251,190,183, 61,142,225, 44,126,125,245,177,249, 33, 10,215,213, 54, 94,222,119,179, 59,244,134, + 77, 23,116,148,189,211, 61, 5, 22, 56, 43,204,205, 29, 37, 13, 15,214,185,136, 92, 21,219,184, 1,237,129, 13,171, 14, 44,250, +210,237,117,157, 5,208, 44, 4, 90,126, 72,234,180,178, 46,158,244, 8,137, 78, 48,219,249, 29, 19,178,137,239, 92,160,232,211, +200, 87, 85,169,147,240,172, 26,169,213, 13,125,173, 92, 38, 2,110,126,123, 51,238,205, 11, 92,143,201,205,230,177, 10,175,170, +112,107, 54,232, 34, 46, 15,102, 15,197,108,124, 2,150,119,196,192,238,184,100,249,255, 5,173,185, 40,238,221, 49,241, 96,124, +255,241, 0,158,125,226, 85,135,189,143,134,199,123,211, 3,217,160, 12,176,248,118,154, 55,180,118, 33,110,145,139,156,248,174, +117, 32,116, 76, 94,136,117, 83,181, 39,129,156, 50, 69, 19,180,117,143,151, 29, 87,205, 92, 38, 59, 94, 88, 56,101,176,183,198, +184,199, 62, 86,172, 71, 55,201, 78, 46, 20,233, 41,111,251,100, 55,239,187,239,230,113,134,135,153,124,188, 34,231, 68, 59,159, +105,181, 92,188, 16,177, 75,190,110, 47,212,105,195, 70,201,198,235,238,170,248,144, 21,122, 40,252,118,234,105, 23, 56, 6, 98, +143,216, 57,242,253, 82, 81,188,107,115, 50, 80,195, 84, 54, 46, 61,244, 3,133, 51,120, 83,200,117, 37,130, 96,104, 1,212, 81, + 37,137, 71,178,118, 84,167,199,123,122,130,156, 13,240,189, 42,194,170,202,189,192,225,233, 9,125,166,112,117,196,254,254,223, + 65,190,248, 27, 32,111,130,188, 10, 87, 25,142,134,204,186,181, 82, 22,119,178,117,175, 82, 11, 90, 92,143,131, 43,134, 93, 11, +237,110, 33,189,167,112, 35,158,226,118,152, 28, 6,115,154,144,165,160,167,134, 29,156, 97, 46, 39,127, 95,170,251,133,121, 73, + 80,218, 31, 10,151,227,155,253, 33,223,173,240, 32, 72, 49,210,135,247,240,171, 66,190,137,133,223,247, 63,130,223,243, 24,249, +249, 70,154, 3, 10,242,173, 91,244, 92, 57,171, 68,142, 65, 15,249,136,194, 30, 64, 54,253,109, 87, 48, 37,120,247, 4,239, 23, +248,176, 98, 79, 23,234, 71, 39,202, 59,119,156,158, 87,158, 54,120, 81, 61, 63,186,180, 61,193,204,199, 97,187, 74,215,245,141, +222,137,104, 86,228, 70, 93,165, 46, 2,119,133,118,183, 14, 54,182,234,187,245, 98,155, 42, 61, 37,225,240,138, 34,166,232, 71, +202,244,123,158,192,239, 86,120,227, 51,112,243, 71,225,250,183, 67,122,205,203,133,253, 26, 76,143,156, 31, 64,117, 8,205,189, + 23, 40, 91, 10,182,182, 13,194, 65,108, 87, 84,108, 27,231,117,240,220, 85,246,215,188,244, 2, 43,206,197,239,132, 51, 77,254, + 17,155, 93,210,209,210, 0,183,238,153, 5,157, 1, 49,169,187,235,166, 96,170,107,222, 59, 44, 27, 70,244, 77,217,196, 62, 22, +124,239,162,157, 26,108,172,131, 72, 85,185,132,126,116,216, 76, 71, 63,183,225,129, 57,169,123,115,171,117, 47,249, 46,166,235, + 22,170,132, 68,199,214,194,110, 25,159, 73,243,137,142, 4, 70, 53,133,210,184, 63, 88,167,176, 71,166, 16, 76,246, 14, 63,133, +114, 59,162,145, 28,207,178,141, 93,119, 17, 37,114, 41,202,187,141, 67,120,239, 58,167,240,105, 47,195,196, 96, 18, 23,118,246, +248,212,145,145,158,250,225, 50, 10,246, 42, 67, 42,156,176,129, 99,232,124,252, 14,113,161, 99, 97, 47, 11,155, 92,252,251, 62, + 34,214,136, 92,213,176, 95,245,103, 99,194,152,172, 81,194, 93,178, 91,233,236, 99,214,174,106, 70,193, 56, 53, 97, 73,209, 85, + 55, 99,166,241, 24,223,217, 44, 42, 44, 45,128, 42, 67,183,105,155,109,215, 63, 47, 98, 10,213, 15, 79,136,235, 14, 94, 65,120, + 79,132,151,151,219,243,139,240,145,203, 49,187,241,113, 42,249, 88, 47, 2, 64,246, 9, 44,130, 11, 42,229, 39, 40,222,101,236, + 94, 47,244, 12,131,148, 99,176,226, 61, 44,244, 91,126,187,236,113,214,163,134,204, 34,196,203,137, 2,186,231, 55,116,146, 92, + 36, 22, 73,136, 29, 77,221,181,142,133, 91,203,246,231,109,202, 57, 26,206,117,211, 76,140,209,213,221,171, 79, 28, 6,250, 74, +120, 44,174, 54, 40,227, 62, 17,191, 59,172,102, 68, 46,167, 39,163,184, 47,239, 66, 55, 15, 96,153,175,174, 56,222, 60, 66, 13, +214, 82, 49, 89, 54, 30, 50, 54,224, 96,199,209,206,112, 44,219, 22,251,125,116, 46, 50,124,113, 93, 16, 23, 31,148, 10,153,206, +185, 13,220,234,166,126,207,155,100, 6,243,215,230, 22,161, 72,136,139, 14,187, 43,130, 84,117, 51,247,183,148,227, 20, 94, 7, + 64,155,143,239, 69,133, 89,125, 84,149, 69, 93,104, 21,187, 61, 83,165,102,199,100,158,109, 97, 61, 11,249, 37,216,103, 30,193, + 55,159, 97, 31,252, 37,228,181, 63, 14,114,240,167,114,210,253,248, 61, 68, 36,153,183, 75,126,114,138,163,188, 53,193,146,250, +136,183, 1,207,238, 73,239,167, 24,193, 11, 60,158,224,117, 67,238,162,168,227,105, 65, 84, 69,215,186,141, 41,229, 99, 8, 82, +219, 18,201,218, 5,220,146, 13,133,216,247,160,247,236,170,183,199,239,222, 33,191,148, 72,143,131,212,246,249, 43,248,241,138, +252,125,200,159,143, 86,229,131, 59,218,125,243,142, 43,126,198, 5, 73,234, 4,242,165,217, 91,164,119, 87,120,231, 76,187, 47, +212, 15, 78,212,247,238,185,127, 86,121, 86,133,167,213,184, 47,134, 85,185, 16,196,169,218,118, 0,236, 74,105,237,236,247, 89, +209, 87, 39,127, 10,159, 10, 60,107,216, 18, 97, 63,231,138,157, 42,165, 52,106,140,196,105, 62, 10,151, 44,200,251,144, 62,117, +133,252,222, 25,222,184,134,171, 63, 0, 55, 63, 13, 50,131, 62,130,122, 15,167, 95,129,116, 19,173,223, 45,172, 95,246, 15,232, + 84,225, 84,169,181, 5, 19,168,167,145,237,174,140,254,136,243, 61,185,109, 58,146, 37, 62,235,154,246,128,162, 67,238,122,221, + 93, 24,168, 92, 38,177,233,224, 62,201, 2,179, 26, 7,132, 89, 93,144,168,182,187, 53, 82,188, 38,213,157, 61,190, 67, 90,188, +160, 53, 31,161,237,116,190, 40,138, 73,135, 84,174, 7, 10,101, 29,198, 94,169,249,123,104,197,167, 52,105,219, 37,126,188,235, +235,157, 84, 27, 12, 59,221, 51,124,165, 78,194,234,118,157, 37, 14, 9,217,130,129,207,158,220,216,215, 14,125,228, 93, 59,107, +162, 55, 78,245,242, 64,178, 29, 12,163,219,236, 31,231,201,188, 51, 31, 5, 98, 41, 62,156, 49,109,210, 6,165,180, 70,150, 68, +199,176,118,238,144,176, 49,161,252,121, 40,193,178, 24,124,245, 50, 88, 12,235,224, 20,105, 3,176,166,110, 10,106,247, 72,247, +200,212,214, 53, 68,253, 61,119,101,181,217, 37,183,195,220,239,222,197,188, 69,140,181,117, 26,158, 95, 23,199,232,252, 23, 81, +214,156, 57,181,198, 82, 43, 45,136,151,122,129,184,253, 56, 91,125, 9,173, 78, 18,225,177, 24,207,251, 65,244, 1, 31,227,227, +133,134,125,138,123,241,252,145,193,138, 43,219,161,201, 46,214,225,114, 33,132,227, 19,121,242,118, 17,169, 59,162,130, 31,172, +214, 47,166,182,163, 83, 52,199,180,100,200,117,219,242,206,205,122,236,170,215,170,108,221, 85,149,176, 0,203,140, 2,242,237, +136, 35,234, 17,225, 49, 73,158, 82, 34,205, 19,165, 44,113, 61, 63,160, 42,110,127, 71, 28,114,205,134,116,188,161,155, 55,185, +108,205,226, 90,223,119, 15,163,221, 80,246, 67, 65,219,185, 34, 89, 6, 27,219,124, 60,114,245,248, 21,242,225,192,249,131,247, + 40,167,123, 31, 51,200,195, 14,209, 30,124,248, 59, 61,106,159, 96,200, 0,222, 31,113,173,251,254, 93,163, 43,239,161, 43,158, +165,221, 16,139,164,155, 36, 23, 9, 52, 26, 65, 49, 27, 86,182, 43, 50,107,137,240,145, 20, 10, 97,143,198,147,240,195,170,169, +147,207,180,109,235,130, 89, 93,156, 86, 55, 98,195,228, 96,142,174,140,159,175, 89, 21,230, 23, 2,247,130,220, 63,193,126,225, +231,145,159,253,253,160,175, 70,250, 78, 60, 77,102,245,153,221, 54, 19,143, 95, 43,182, 17,177,164, 25, 90, 26,173,234,230,151, +209, 15,207,200,147,104,229,110, 50,188, 38,240,114, 66, 78, 21,213, 70,171,174,136,215,185,146,150, 30, 77,250,144,216, 53,192, +106,236, 65, 0,134,109, 3,146,109,223,182,169, 66,139,241,248, 91, 47,145,127,144,208, 39, 17,105,250,155,174,225,100,200,215, + 32,127,111,131, 12,243,219,183,222, 13,203,112, 93,137, 63, 61,229,160,232, 15, 93,193,211, 5,222, 59, 83,223, 61, 83,159,157, +168, 79, 23,238,111, 43,207, 26, 60, 43,198,237,234, 15,229, 58,100,124,107,116, 68,132, 31,125,180, 81,106, 22,228, 38, 33,143, +226,105,185, 86,236, 28, 59,244,147,239,212,203,218, 28, 26, 18,226,161, 41,246, 38,246,162,162,118, 36,253,190,107,248,172,192, +213,143,195,227, 63, 18,237,193, 11,224,173, 40,224,207,224,250, 71,233,137,232,180,251,120,106,155,179,228, 67, 36,103, 38, 23, + 29, 79,191,137, 59, 73,174,131, 80, 38,221, 69,244,214,132,163, 42,143, 94,203,220,222, 22,238, 79, 49, 94,237,154,152, 1, 82, +211, 49,159, 83,116,234, 7,109, 28,146,112,200,198,193,134, 34,221, 25,240, 93,203,208,115,160, 85, 28,112, 19,123,129,181,237, +248,224,169,238, 59,238, 62,157,234, 32,156,180,209,235,252,201, 82, 91, 15,156, 9, 10, 93, 27,138, 94, 20, 12,135,203,216, 86, +252, 54, 46,184,236,140,241,237, 59, 84,245, 12,136,197, 56,100,119, 49,220, 53, 99,109,126, 8,107,181,243,187, 45, 16,175,187, + 53,172, 61,120,176, 79,230, 22,188, 49,253, 76,147,131,110,182,247, 38,123,102,121, 25,196,109, 26,157,105,223,163,223,196,247, +181, 12,200,229,126, 48, 40, 15, 15,196,241,123,231, 88, 33,230,152,108, 60, 84,201,111,106,247, 11, 38,254, 30,122,196,246,222, +124,196,111, 3, 6,116,140,123,232,222,248, 62, 66,110, 23,196,181, 29,155,112, 68,220,166, 55, 92,151, 77, 60,179,126,109,198, + 65,132, 43, 77, 44, 41,113, 42,133, 86,203,118,253,245,255,215, 39, 25, 45, 80, 26,121,179, 5, 10,111, 8,220,137,240, 65,172, + 61,234,128,223,181, 7, 48,154,109,170,208,131,187,100,111,252, 54,193,219, 39,140,222,117, 80,183,203, 3,240,144, 12,204,253, +139, 38,197,134, 12, 4,216, 84,250, 99,226,218,229, 78,122,239,126, 45,116, 27,253,154, 32, 56, 39, 93,159,165, 61,153, 16,113, +155, 90,132,176,116,228,107, 74,137, 98, 30,250,226, 35,123,191,198,179, 42, 73,149,148,148, 60,205,212,116,218,109,108,181,125, +204,137,223,177,234,150, 98, 12,212,227,202,217,195,159, 44,104,130, 66,231,226,219,197,228, 99,163,181,246,207,224, 1,109, 47, +111, 31,164, 8, 87,175, 60,225,240,232, 17,119,239,190,203,249,233, 71,126,114, 57,206,190,119,174,109, 43,232, 23,123,141, 22, + 30,242,180,199,220,165, 17, 26, 32,125,252,210, 87,253,178,117,253,180,126,243, 15, 75,255, 48,238, 75,210,125,236, 30,106,211, + 36,138, 78, 93, 26,235, 93,188,106,192,108,226, 68,154,114, 70,146, 4, 75,221, 89,213, 41, 37,180, 70,152, 97, 50, 82,242, 81, + 19,154,144, 57, 83, 83, 70, 34,124, 70, 85,209, 57, 33,182, 82,234, 74, 57, 41,250, 66,145,207,222, 96, 95,121, 15,251,241,191, +130, 92,255, 65,152, 31,131,125,228,130,172, 28,147,131,214, 47,246,186,157,194,182,116,159,184, 33, 82, 11,161, 87, 18,218, 82, +208,119,206,254, 69,125, 17,143, 22,253, 28,176, 22,228,157,134,166,134,205, 9, 43,149, 92, 42,107,227, 19,191, 3,121,168, 54, + 29,191,225,158,191, 45,193,139, 55,243, 60, 19,133,116, 46,200,215,111,153, 63, 61, 35,175,101, 47,236, 63,114, 5,181, 32, 7, + 23,231,180,251,194,244,238,125, 32, 47,135,179,243,169, 34,143,102,239,242,191,118, 79,123,127,165,190,127,166, 60, 63,113,186, +107, 60, 67,120,182, 56,166,125, 41, 59, 79,154, 65,255,240, 48,141, 84, 35,220, 67,115, 70, 31,101, 15,112, 49,188, 75,127,233, +222, 92,107,141,118,170,148, 98,172, 58, 28,109, 36,114, 5,238,148,252,133,107,248, 97,156,254,119,243, 47,248, 33,108,253, 57, +200, 63, 1,182,192,179, 63, 31,145, 91,223, 27,109, 85,129,250,190,119,233,173, 97,165,243,176, 47, 52,184,254, 80,172, 46,108, +209,208, 27,180,120,210,206,201, 5, 81,147,249,195,241,205, 63,242, 58,135,127,252,154,119,254,163,111,177,158,171,119, 97,109, + 87,185,247,142, 61,199, 67,112, 22, 99, 82,227,144, 60, 25,246,208,131, 94,218, 37, 58, 53,137, 96, 57,206,147, 53,214, 46, 45, +196,144,177,166, 41, 65,146, 43, 33,172,147, 0,140, 39, 49, 86,241,137, 86, 23,191,101,213, 96,102,216,214, 33, 62, 20, 55,141, + 15,194, 44,123,183, 39,109,119,143,244, 7,177,178,231,185,191,218, 18, 63,250,251,175,121,252, 86,230,151,255,226, 75,168,149, +151,129,140,197, 42, 41,251, 52,128, 56,108,168,143, 5,250,237,189,117, 44, 45,124,233,133,125,167,223, 6,192, 79, 29, 56, 20, + 58,168,221,115,220, 11,157,228,150,187,147,128,125, 35,216,133,141, 43,182,137,213,212, 46, 9,115, 58, 48, 5,186,127,127,212, +243,104,216,172,250,129, 98,215,136,236,133,162, 35,114,243, 54, 29,240, 61,137,217, 64,223, 28,145,189,177,107, 87,118, 16,209, +136, 14, 85,196, 85,234,236,233,207,253,190, 55, 51,180, 25, 7, 77, 72, 78,156, 85,184,175,149, 18, 66,231,142,165,173, 49,144, +219, 33, 74,254, 30,102,224,179, 98,220,197,116,207, 98,218, 32, 23,134, 43, 63,108, 62,124,175,250, 93, 68,108,198,101, 70,250, + 5,156,230,193,234, 34,141, 43, 12,217,247,206,227,248, 93, 47,208,203,253, 51,116,155, 47,210,182, 67,131,154, 11, 89,221,158, + 45,204,121, 98, 78,153,148, 53,108,133,198,221,186,114, 94,150, 40,236,141, 82, 93,232,168, 41,109, 7, 8,149,152, 42,167,180, +117,206,190, 89,210,168, 97,137, 41,103,214, 52, 97, 1,181, 25, 11,178,116,135, 86, 63,204, 4,241,172,239,195,183,137, 68,172, +140,233,124,130,152, 76,143,228,169, 77,159,208, 63,144, 90,183,160,165,102, 70,206,170,136, 53,166,121,230,250,149,215,169,203, +202,249,217, 71,187, 24,160,214, 77, 36, 48, 18, 9, 58, 36,134,192,178,118,159,142, 14,251, 14,137,238, 96, 19, 27,168, 70,135, + 32, 91, 40,132, 14,251,133,125,180,153, 3, 54,177,211,230,146,166, 0, 51, 40,170, 57, 10,167,111, 83,147,122,102,168, 89,133, +214, 85,240,182,229, 75,251,168, 36, 88, 96,234, 10,244, 60, 37,208,188,133,209, 88,155,252,131,233,106,131,249,136,233, 53,205, + 42,237, 30,100,173,112,186,194,222,254, 91,200, 15,253, 62,120,242, 57,184,249, 0,158, 38,223,171,231,184,251,171,245,133,233, + 86, 0, 91, 0, 16, 90,216, 82,178, 85, 90, 21,184, 95,247,143,245, 70,225,179,147,231,174,191,113, 64,150,134,182,138,181,236, + 40,217, 83, 35, 75,243,157,223, 56, 14, 26, 10, 4, 23, 65, 15,195,141,110,123,158,112, 75, 65,194, 74,110,105,202, 47, 78,164, + 47,191, 32,191, 49,195,147, 9,222,186,130, 31,186,129, 89,144, 73,200,167, 66,123, 94, 40, 47, 22,202,188,255, 32, 59, 27,250, +195, 19,162, 9,251,176,210, 94,172,212,211,194,122,106,188,140,100,212,251, 2,167, 98, 30, 91,218, 46, 79,243, 26, 0, 5,123, + 16,252,160, 13, 15,185,121, 53,121,146,201,185,193,139,117,207, 73, 95, 10,237,220, 92,224, 19, 95,149,171,151, 45,212,248, 25, +249,169, 4,159, 1,174,255, 0, 28,126, 4,150,255, 27,110,255, 2,188,242,187,225,252, 53,248,234,207,193,147,207,134,210,172, +184, 56, 96,253, 0,206, 96,119,254,148,148, 42,164,201, 79,237,162, 66, 43,254,218,214,236,135,157,164, 61,242,120,239,192, 83, +246,209,242, 49, 11,105, 53,206,127,249, 41,229,220,200, 17,105,219,185,235,157,212, 54, 73,223, 97,155,239,209,213,199,245,199, +208, 44,108,216,220, 58, 78,191,100, 19,150,238, 88,207,248,255, 25, 82,141,123,173,117, 27, 82,240,243,155, 23,211,221,222, 37, +177, 87,180,109, 55, 44,234, 66,198,109, 79,152,118,235, 97,211, 30, 80, 35,219,100,173,127,111,235,192,138, 63, 35, 28,129,207, +136,240,227, 63,113,228,213, 63,251, 22,207,255,139, 15,184, 93,140, 41, 11, 95,122, 34, 92, 63, 86,190,252,109,227,229,185, 49, +137,120,134,184,244,195,254,195, 88, 89,118,201, 86,127, 13, 3,167,189, 63,204,100, 24,185, 78, 33,142,139,212, 94,150,232, 94, +206,192,157,193,213,131, 29,120,177, 29,130,212,199,237,149, 49, 54,245, 1, 36, 37,186,197,142,142,237, 57, 64,109, 3,246,216, +133, 90,191,178,107,141, 82,128, 95, 68, 19,102,141,181,219,218,108,199,213,122,190,189,109,175,227, 48,192,136, 42,198,179,102, +172,102,220,136,112, 80,223,245,223,197,251,235,175,249,100, 70,181, 66,149,152,233,164,140,137, 58,106,182,218, 86,208,235, 48, + 46,239,253,244,106, 14,181,121, 75,224,237, 33,108,187, 12,123,155,135,246,181,110,137,188,212,180, 95, 98, 95,237, 1,135,221, + 30,144, 9,101,224,216,203,240,186,218,131, 70,230,227, 94,120, 25,208,170,241, 89,199,207,154, 68,152,231, 25, 81,229,160,202, + 33,254,189,198, 84, 35, 11, 60, 57, 30,184, 21,225,188, 44, 1,156,106,172,197,208, 86,201,154, 72, 57, 83,171, 11, 60, 53,128, +103, 42,194, 60, 77,204,121,242,102, 34,108,224,170,234,161, 47,146,144,109, 39, 31,112, 53,213,203,168,191, 56,208,111, 66,185, +168,185,200, 16, 23, 59, 0,115,250, 73, 92, 58,251,165,167, 46, 90,187,248,172,115, 47, 16,211,213, 53, 34,202,249,195,247,177, + 86, 73, 49,234,182,230, 1, 20,219,152,183,141,187, 45,187,136,147,235,129, 15, 50,228,225, 89,219,173, 58, 59, 80,120,143, 94, + 53,177, 75, 11, 69,196,112,138,166, 16, 4,197, 62, 49,101, 68,213,243,129,251, 95,106,178,143,101, 84,125, 92, 29,159,152,166, +228, 16, 22,171,219,233,162,219, 45,242,148, 73,243,140,106, 34,139,255,156, 86,154,103,229,138,208,242, 68, 17,104,234, 65,142, +182, 86,236,121, 65, 30, 77,216, 47, 60,133, 47,254, 26, 60,250, 61,240,195,255, 0,222, 87,164, 30,144,171,130,220, 23,135,208, +212,225, 65,180,141,193,219, 32,234, 48,244, 84,177,164,148, 21,210,210, 72, 61,180,228, 83,192, 27, 9,214,140,190,172,216,109, +197, 84,105, 42,228,192, 80,246, 24,198,214, 62, 94,212,251, 15,113, 79,187,109,206,195,174,158, 95,171, 63,128,170,193, 11,132, + 9, 99,122,247, 30,253,198, 75,244,205, 9, 30, 39,228,213, 35,246, 5, 71,215,166,231, 71,242,119,206, 76,183, 11,231, 26, 98, + 30,241, 39, 72,250,173, 71, 79, 73, 59, 87,108, 41,212,219,194, 73,125,197,126,110, 91, 58, 42,181,250,131, 43,119,110,252,176, + 23,221, 31,226, 94,236,179,129, 94, 37,164,199,172, 62, 55,236, 46,118,233,203, 74,123, 89, 57,135, 29, 30,237, 15, 84,191, 57, +245,165,146,127,246, 10,249, 25,131,199, 95,132,155,127, 30,218,115,120,250,231,160, 28,225,230,125,248,234,191,135,253,124, 67, +254,153, 21,202,119,160,188,112,107,226,122,139,156, 58,223,160,145,102,229, 40,153,169, 56,194, 94,196, 56,215,202, 20,136,226, +121,240,214,247,110, 37,197,237, 80, 90,229,163,255,229, 67,172, 64,206,198, 77, 51,206,145, 69,211, 98,164, 62, 77,151,178,140, + 94,208,181,119,101,113, 16,242,137,211, 80,180, 58,119,160,236, 11, 68, 17,217, 3,157,194,251,170,125,160, 21,254,121,146,175, + 42,188,232,105,164,159, 93,238,253,146,169,131,117,194,179,219, 6, 38,168, 12, 55,104, 31,101,143, 93,171, 13,251,232,163, 40, +143,111, 18,203, 2,191,242, 47,125,131, 95,255,230, 25,142, 62,193,120,114,149, 88,171,112,223,217,255,227,142, 48,152,237,231, + 17,244,210, 71,188,136, 71,101,110, 9,145,251,186,198, 6,176, 84, 30,186,245, 14,140, 89,227, 78, 60, 15,196,191,137, 97,234, +240, 32,103,162,171,215, 11,151,118,186,135, 10,237, 49,100, 68,113, 29,196,210, 99, 79,195,106,184, 69,208,198,250, 43,111,207, + 71,161,104,102,105,133, 37,210, 38,235, 64,181,235, 5, 61,110,181,120, 95, 18, 44, 13, 47,250, 39, 51,142,182, 79, 78, 12,184, + 55,225,212,191,187, 77,136, 90,157,133, 46, 66,211, 41,172, 9,118, 49,254, 39, 2,175,122,242, 92,197,157, 3,111, 0,223, 30, +150,214, 77,118, 17, 95,226,227, 80, 25,249, 46,126,245,241, 23,210, 72,103,124, 16,190,178,233,133,162,144,183,225,226,146,143, +129,110,236,162,248,251, 33,207,127, 80,238,135,224,128, 24,204,170, 78,126,179,176,154, 86,219,234, 11, 8,215,243,140,136,176, +156,207, 62,245,141,212,202,181, 57,248, 71,123, 81,166, 23,244,204, 52,249, 1, 33,135,114, 85,194,182,184, 29, 56,181,139, 73, +251,159, 29, 35, 89, 7,173,205, 40, 69, 84, 15,241,233,246,241,109, 58, 34, 26,153, 12,109,111,134,154,131,202,198,252,217,200, +108,240, 14,238,112, 56, 96,101,101,185,125,177,239, 55, 25, 58,146,202,150,235,189, 73, 13, 98,124,176,157, 73,173,133, 77,104, + 80,207,137, 12, 40,200, 22, 2,162,174, 53,220, 97, 15,253, 43, 75,236,130, 58,149,180,219,232,196, 51,220,181,245, 55, 57, 90, + 23, 64,152,104,211,238,239, 52, 81, 87,104, 71,106,154,166,196,156,148, 89, 3, 76,146,149,164, 25,116,242,177,208,212, 3, 89, + 10,181, 54, 86,171, 84,170,127,192,171, 97, 47,110,189,139,126, 87,176,111,253, 60,242,165,127, 21,249,210,247, 97, 31,126, 29, +249,135, 9, 93,103,236, 84,145,114,142,194,240,192,110, 55,140,157, 22,224, 80, 27,237, 92,208,212,124,207,249,222, 9,189, 81, + 56, 28,225, 58,160, 52, 47,162,248, 83,177, 50,161, 47, 27, 89, 93, 36, 19, 43,159, 13, 50,163,253, 59,130,216,199,199, 13,210, + 6, 97, 83,183,204,244,221, 82,133,231,147,112,188,175,164,175,220, 50,127,238, 8,111,100, 56, 36,228,181, 71,190,199,126, 94, + 73,111, 29,152,158,159,152, 63, 44,156,230,254,176, 85,228, 11, 51,118, 42,216,203, 70,123, 89,176,106, 59, 71,187, 26,107,101, + 75, 99, 75,195, 67,106, 76,127,178,237, 70, 15, 22,127, 18,244, 73,114,232, 12,158,116,215,238, 35,137,237,222, 71,239,139, 25, + 75,235,211,159,184,129,138,248, 65,244, 79,190, 1,159,250,157, 48,255, 49,152,222,128,167,127, 30,158,253, 58,188,242,187,224, +254, 47,194,127,242, 11,112,243, 4,251,104, 69,222,248, 8,202, 45,200, 17,150,123, 88, 61,156, 72, 87, 33,201,196,141, 78,164, +183,142, 44,182,242,193,251,103, 82,114, 30,180, 6,216,163,167, 74, 69,102, 7, 53, 84,214,102,198,169,143,188, 67, 89,125,115, +244,110,189, 87, 9,213,125,188,154,197,187,216,237,144,208, 15, 79,246,128,110,221,175,169, 18,197,221,100,115,121,244, 15, 56, +137,119,236,210,161, 50, 33, 0,235, 93,134,163,228,216,216,195, 45,130, 43,208,228, 15,175, 22,105,137,114,233,155,149,102,212, +136,218,181,145,229, 30, 34,186,202, 14, 46,153, 50,124, 88,225,221, 95, 57,113, 90, 43,105,246,142,250, 84,141,191,247,237,133, +115,219,229, 40,213, 46,109, 98,163,112,175, 7,232,200,199,210,186,100,139, 18,221,195,235,108, 75,173,235,136,217, 50,226,119, +101,136,106, 53, 47, 88,155, 56, 45,174,191,177, 19,111,118,121, 96,233,130,177, 54, 92,191, 57, 38, 22,123, 96,138,127,118,182, + 89, 80,213, 15, 14, 97, 31,107, 6,247,213,173,173, 41, 92, 57,146, 18, 82,108, 83,213,111, 49,209, 92, 54,117,155,252,164,147, +253,226,247, 85,235,148, 63,225,206,224, 30,219,112,191,102, 59, 68, 42,137, 33, 45,214,152,120,150, 71,193, 40,165,239,219,133, + 81,164,222, 51,233, 39,241, 80,201,219,176, 65, 54, 60, 59,160,223,184,163,120,242,187,121,204,211,102, 69,148, 77,227, 49,254, +190,244, 64,180, 55,198,139,242, 0, 79, 60,166, 26,118,123,180,245, 70, 9,221, 82, 14,251, 10,163,103, 53,168,250,180,130,208, + 55,229, 16, 91,247,224, 50, 21, 31,205,183, 90,169,107, 27, 54,224, 30,222,226,186, 1, 69,163, 27, 79,154,226, 30,236,209,227, +138, 53,219,130,135,182, 87,168,186,217,207,122, 82,219,229,218,177,141,121,115,113, 16,145,224, 54,196,113, 53,103,255,253,181, +110,212, 57, 19,243, 70,180,121,103, 48,240,107, 28, 41, 45, 2,109, 93, 56, 61,251, 0, 43, 5, 85,137,209, 96, 87,221,202,102, +146,183,118,233,127, 28, 61,130,221,226,214,195, 26,122,164,107, 31,207,247, 81,225, 22,231, 55, 96,253, 44,126,221, 85,237,213, +197,114,216, 46,204,107, 30,120,226,187,246,200,217,238,118,163, 96, 90, 39,149, 45,173,216, 68,156, 20,166, 57, 0, 19, 19,135, + 57,197, 14,113, 9, 42, 93,242, 49,137, 37,207,124, 43, 11, 22,178,228,138,112,110,194, 25, 35,151,123,148, 10,247, 7,228,201, + 12, 95,254, 50,124,113,133, 87,254, 36,252,214,255, 24,202, 61,250, 75, 51,118, 88,177,121,193,206, 50,140, 78,108,195,229,142, +118,156,130,145,207,197,217,245, 87,130,188, 80,228,189, 16,206, 29, 20, 30, 77,240, 61, 13, 89,103,244, 93,207,162,183, 86,153, +111, 87,150,136,195,237,157,146,251, 51,219, 38,212,234, 57,222,163,136,194,194, 74,214,113,175, 29, 17,128,192, 85, 54, 14, 31, +156,200,255,240, 5,250,169, 25,187, 81,100,158,145,215,174,177, 79,175,232,103,102,210,251, 71, 14,207,111, 61, 59,120, 49,166, + 89,145,207, 29,225, 89,241, 36,182,115,219,198,145, 37, 52, 34,173,123,148, 35,183,219, 70,229,170, 93,166, 56,117,149,178, 94, + 41,242, 56,195, 44,216,125,133,151, 5, 91,188,123,110,119,133,117, 53, 78,230, 83,128, 20, 15, 29, 5,228, 30,210,111,203,240, +250, 15,193,213,159,130,252, 38, 44, 95,133,167,255, 35, 76,103,120,235, 26,254,231,191, 12,255,143, 32,127, 80,177, 91,243, 42, + 91, 79,174, 40, 91, 94,192,115, 65,238,253, 53,206,249,136,254,137,183,224,247,126, 31,249,231,126,149, 23,255,237,219, 76, 89, +209,115,221, 73,120, 3,247,157, 1,188,210,177,174,125,132,234,144, 65,225,224, 27,159, 56, 4,244,220, 1,127,192, 75, 44,239, +172,140,236,244, 93, 81,188,249,247,211, 94,137,100, 82,180,122,213,238,124,233,150,118,149,188, 5, 27,190,197, 31,105,170,123, +209,139,184, 97,205,137,154,179,119, 46,141,141,165,173, 13,215,125,152, 7, 47,245,112, 26,217, 73,200,126, 24,141, 80,154, 20, + 29, 82, 1,150,210, 40,197,255, 93,147,113,182,240,171,211, 3, 51,188,163, 95, 30,200,169, 55, 88,201,246, 44,113, 62,121, 25, + 14,197, 91, 7, 46,186,177, 48, 54, 1,227,144, 52, 82, 7,245, 80,142,239,105,142, 29,193, 26,180,189,218, 97, 44,225,135,110, + 1, 25, 42,109, 31, 77,143, 68,180, 78,163, 76,182, 91,236, 26, 66,141,168, 77, 53,227, 96,141,151,205,239,111,217, 52, 69,193, +127,143,235, 33, 85, 95, 1,170,184,128,215, 90, 76,162,182,130,238, 33, 45, 54,132,109,141, 14,174, 26,123,250, 37, 38, 14,218, +140, 59,220,123,190, 6,222,181, 4,227,126,233, 62,104,219,227,173,175, 5, 30,137, 32, 41,145,179,178,182, 18, 78,137,221, 27, +159, 7,183,213,163,248,236,239,245,242,128,110,195, 52,164,141,106,182, 40,224, 50,136, 73, 63,201,186,246, 73, 88,217, 49,126, +102, 51,100, 14,146,246,190,251,135, 75,102, 65,138,233, 71, 26,232,124,125,159, 62,231,204,164,153,166,123,250,103,214, 20,159, +181,120, 97,196,255,183,148, 18,117, 29,243, 24, 36, 4,143, 14, 12,114, 30,195, 52,172, 29,188,232,175,165,112, 62,159,246,125, + 85, 47,214,162, 81,216, 99, 50, 50,178,225,187, 63,222,218,112,205,219,230,145, 23, 77,144,252,184,105, 53,186,234,176,202, 89, + 4,202,108,235,240, 97, 39,149,189,219, 19,150, 23,207, 99,148,199, 94,140, 67, 41,222, 51, 75,164,237, 84,254,109, 7,208,125, +176,155, 2, 54,132,115,106, 23, 35,117, 25,114,217,181, 95, 5, 18,103,238,142,146,181,253,103,123,235,211,144, 41,145,196,247, +254, 82,107,188,158,136,124, 29,148, 22,162,126,186,202,105,194, 52,251,216, 35, 79,126, 58,107,141, 84, 11,185,174,126, 27,204, +215, 30,202, 37, 13,105, 37, 50,217,129,150,168, 65,189,195,217, 42,104,105,204,210, 72, 77,105,119,134,188, 34,200,251, 43,220, +253, 29,120,245,159, 67, 62,253, 39,176, 31,251,243,240, 62,200,203, 9, 57, 77,200,121, 55,151,105,218, 71,167,125,159,170, 3, +232, 99, 90, 26,118,172,212, 86,144,143, 22,210, 87,194, 59,254,217, 25, 94,157,224,243,134,174,206, 59, 55,105,112, 94,209,123, +219, 44, 80,163,250,180,200,101,190, 51,219,110,210, 46, 58,157,190, 59, 92,155,239,161,159,171,112, 93,141,249,155,247,204, 95, +191,131, 79, 37,184,190,135,199,215,200,167, 39,236,245,153,252,217, 35,237, 69,225,234,195,123,202,210,200, 79, 38,228,149, 9, +222,190,195,110, 27,173,122, 44,100,107,194,186, 70, 65, 11,121,109,103,138,247, 19,170, 93,156, 84,101,219,181, 37,112,224,204, +167, 34,211,252,133, 97,119, 94,208,157, 34, 87,125,180, 95,221,186, 52, 53,227,216,161, 51,162,200, 19,131,114, 15,122,140, 27, +224, 8,239,124, 7,126,236, 7,224,244, 62,252,185,167,158,208,118, 29, 0,236, 52,197, 7,120, 11,235,135, 91, 59,167,139,194, +143, 92,195,111,255, 52,188,253, 33,203, 95,253,144, 90, 27, 89,140, 26, 64,149,238, 21, 31,133, 89, 58,236, 10,219, 39,196, 83, + 54,131, 41,137,199,174, 86,187, 12,158,216, 86, 41, 35, 53, 97,223, 25,106,216,245, 46,158,136, 37,148,180,178,175,195, 52, 78, +114, 54, 27,156,186,141, 75, 40, 37, 30,180,213, 88, 66,237, 62,205,217,173, 59,165,110,215, 77,149,232,127,196,187,153,146,161, +157,135,196, 52, 25, 14, 24, 23, 22, 57,219,216,244, 75, 8, 58, 20, 99,137,174,186,198,137, 39,165,192,108,118, 69,222,158, 31, +187,117,163,235,134,247,188, 28,195,187,168,183, 3,129,188,251,221, 35, 72,109, 19,234,245,168,212, 78,238,115,112,203, 30,109, +171,120,150,248,135, 13, 14,209,181, 31, 4,110, 68,184, 18,227,118, 16,198,173,157,138, 57,116,229,105, 56,110,173,131, 23,165, +231,157, 79,248, 65, 70,104, 84,243,226, 57,245,149, 99,196,177,182, 45, 53,206,187, 63,107,142,136,110, 56,236,167,109,233,116, +131, 15,124, 83,209,239,249,225,125,219,183,154, 31, 86,150, 88, 1,172,155, 32,206,226, 85,235, 6, 46,170, 13, 42, 53, 98,105, +133, 67,154,168,102, 44,173,114, 54,219,120,248, 50, 28,108,110,100,136, 30, 30, 58,244, 98,151,161, 56,123,167, 61,136, 0, 31, +104, 24, 46, 16,174, 99, 71,223,181, 41, 67, 34,226, 30,246,181, 23,253, 61,238,119,228,188, 15, 52,205,254,247,105, 98,202, 19, + 57, 79,126,152,214, 60,208,233,108, 43,252,253, 26, 81,140,115, 74,225,168,104, 33,232,213,193,162,183,199,170,246,105,192,106, +141,211,233,158,245,174, 81, 75,217,236, 20, 93, 8, 71, 76, 4, 58, 79,196,185, 18, 3,191,101,176, 1, 42,130,230, 20,161, 84, +234,148, 76,139, 3,159, 57,120,173, 9,180, 18,201,113, 99,131, 20,112, 39, 33,117,248,204,238,237, 16,217,115,162, 53, 4, 1, +163, 54, 81, 31, 36,202,136,250, 30, 67, 30,230, 59, 52, 11,172,171, 93, 38,191,117, 53,109,236, 6,205,218, 54, 42,212,129,190, +211, 3, 11,114,139,145, 7,169,115,122,182, 81,155,198, 29,111,146, 34,130, 53, 78, 63, 41,185, 48,196,124,207, 46, 20,178, 52, + 38, 51,180,174, 8,179,183, 76,156,125,239, 81, 28,142,223, 90,115,111,123, 92,158, 42,226, 44,248,166, 28,214,226, 9, 97,103, + 64, 50,246,141,191,130,124,250, 15,195,213, 63,129,188,249,247,176,239,255,235,232, 59, 19,237,148,144, 91,193,206, 27,135,242, +130,122,100,131,250,187,198,193, 43,175, 21,206, 66,109, 62,122,209,183,197,213, 60,175, 31,225,205,217, 47,162,197,125,198,118, + 87,152, 94,156, 72, 27,242,112, 87,188, 39,221,253,188, 29, 70, 48, 2, 50, 30,142,178, 44,150,135,103,133,231, 9,142,207, 22, +244,107,119,228,207,206,216,107, 25,153, 19,188,126, 3,159, 62, 33,119, 7,242, 93,113, 63,231,243, 19,250, 36,111,214, 54, 43, + 45, 28,124,110, 89, 90,205, 40,205, 73,118,173,231,139,219,254, 96,218, 78,171,186,143,231, 82,115,224, 74,122, 37, 33,143, 34, + 7,247,105,120,211,173,209,150, 70, 57, 25,103,224, 92,124, 63, 76, 26, 85,245, 2,223, 94,160, 78,238, 71,151, 5, 94,252, 60, + 60, 21, 56, 37,236,143,255,111,176, 20,228, 39,175,176,215, 20, 94, 83,208, 79, 7, 45,232,153,179,241,107,168,211, 14, 10,185, +210,254,203,175,176,252,157, 91,158, 47,103,150,107,176, 83, 40,214,181,143,184, 98, 74, 16, 32,163, 1, 70,181,237, 43, 85,118, + 97,153,246,144, 8,193,221, 34,179,250,205, 95,119, 22,170,204,138,148,134, 84,223,233,181, 16, 22,166,126, 3,173, 33,122, 20, +193,170, 57,164,103,245, 20, 22, 75, 46,197, 54,240,140,121,226,231,212,128,230,152,177, 6,149,108,186,154, 96, 62, 80,207,197, +247,129,214,227,131,157, 31, 42,109,191, 88, 53,117, 49,142,108,157,122,178, 93, 4, 11,161, 79,159, 0, 0, 32, 0, 73, 68, 65, + 84,218,119,254,181,107, 86,226, 33,185,118,190, 69,127, 24, 70, 65,219,125,207,187, 53,213,198,209,178,237, 22, 88, 27,188,185, +186,141,194,101, 19, 65,141,224,151,141,182, 21,146, 3, 29, 20,213,182, 29,190,132, 89,225,101,137, 0,167, 16,207,245,115,222, + 85,124, 4, 79,217,227, 90,123,166,250,238,248,191, 92, 7, 48,216,166, 68,140, 99,168,198,155,249, 88,157,234,197, 65, 3,195, +186, 39, 91,249,148,102, 78,217, 57,240,107,217, 26,164, 17, 62, 83,227,103,106, 76, 74,138,236,170,253, 14,254,177, 56, 20, 45, +113,160, 40,246, 48,153,173, 33,161,207, 40,192, 18, 14,130, 85, 96,150,198,181, 42,105,154, 41,235,194,210,124,234,214,115,225, +123,209, 62,196,189, 90, 6,145, 96,150, 62,129, 12, 48,143, 13,140,128,161,208,202, 39,224, 93,199,181,203,244,224,247, 43,151, +180, 68,100,183,113, 93, 10,233,252, 59, 77, 26,246,179,152, 20, 95,105,230,230,120,224,120, 56,122,224,138,106,236,184, 97, 41, + 37,226,191,247,134, 32,247,196,197,136, 22,111,117,136, 81, 29,174,196,205, 18, 88, 27,118, 62,179,134,101,176,139, 88, 69,117, + 56,148,135, 35, 76, 6, 72,140, 74, 88,221,118,207,177, 4, 66, 86, 83,222,190,251, 62, 29,176, 90,220,205,160,201,233,131,181, + 68, 65,127,160,242, 80, 54, 91,119,102,243,141,239,234,204, 78,153, 75,125,116,228,179, 27, 87,192,142,128,123,145,109, 44,181, +205,228, 6, 70, 49, 22, 96, 14, 46,253,133, 58,140,215, 82, 20,231, 62,218,218,176,136,219,127,183, 24,153,168,143,222,123,146, + 81,107, 27,222, 79,106,245, 17,191,102,127,120,148,213, 95,163, 18, 7, 17,223,129, 38,205, 62,156, 47, 11,102, 5,180, 4,121, +203, 93, 77, 37,212,138,104,194,154, 80,214, 91, 88,207,220, 82,184, 90, 23,174,164, 96, 79, 10,246,228, 6,249,229,223,128, 31, +250, 27,240,232,159,134,249,119,192,155,127, 19, 30,173,200, 71, 17, 95,214, 60,158,207, 58,115, 59,152,220,125, 18,223, 6,238, +171, 86, 67,239, 42,109,242,116, 53,126, 67,209,171,236,187,245, 39,179, 7,175,220, 6, 94,242,118, 98,154,207, 28,151,253, 20, + 45,131, 95,115,156, 83,118, 38, 54, 17, 6,115, 97, 3,209,126, 34,246,145,252,189,192, 93, 53,230,111,223,145,190,126,240, 14, +253, 42, 35, 79,110,144,239,123,140,157, 26,169,197,204,251,215, 43,233, 7,143, 94,205, 22,159,168,180,210, 35, 45, 29,186, 83, +154,251,136,229, 34, 69, 40, 30, 46, 50, 90, 81,188, 64, 77,106,228,172,232, 43,147,199,111, 85,131,219, 16, 41, 90,195,238,220, +210,231,255, 56,178,115,238,118,156,102,200,169, 32,127,248, 77,120,245,223,244, 61,121,249,171,240,115,255, 1,188,249, 58,245, +223,254, 85,202,219,207,209,159,188, 33, 29, 28, 8, 40,175, 92,185,165, 77,143,192,215,225,105,241, 39,188, 25, 77, 10,235, 87, +110, 41,119, 43,119, 90,185,191, 17, 87,175, 75,115, 48, 73,132,218,244,107, 61, 39,182,160,142,141, 3, 80,217,114, 5,246, 52, + 55,223,107, 70, 14,104,252,225,120, 82,174, 97,231, 82, 55, 17,123, 86,129,197,131, 60,190,176,138,199,243, 70,197,115, 55, 73, + 66, 14, 19,124, 54,211, 62, 58, 83,111, 87, 90,169,206,173,239, 37,167,249,131, 34,153,184, 82,247,234,138, 38, 19,117,219,209, +249,225, 33, 73,218, 50,163,201, 96,107, 37,181,134,170, 58, 9,144, 22,211,180, 80, 1, 87,217,166, 19,157,110,231, 69, 32, 94, +165, 92,174, 89,250, 8,191,239,172,107,140,150,183,220, 2, 51, 46,229, 80,182, 69,212, 78, 61,111, 60, 40, 94, 83,172, 57,122, +209, 47, 12, 76,242, 56,155,117, 2,224,180, 41,184,109,235, 78, 83, 20,164,147,121, 33,186, 13, 10, 93,223,177,107, 0,100,166, + 0,218,116,159,255,204, 62,222,183,129,251, 96, 3, 24,234,198,195, 11,185,239,244,185, 64, 92, 39,205, 91, 16, 72,128, 55, 16, +224, 32, 66, 77,153, 22, 99,248,174,110,182,209,150, 58, 20,232, 98, 22, 62,123,219,194, 98,170, 8,103,219,229, 18,123, 65,183, +139, 67, 61, 3,111,190,191,238, 53,124,218, 51,120, 80, 76, 82,106,109, 44, 49,225, 24,133,129, 83,232, 15,214, 97,218,168,155, + 94, 38, 14,182,182,163,143,219,131, 88, 54,249, 46,136,216,198,152, 6,103,152,126,188,128, 63, 60, 8,140,133,212,226,161,146, + 36,113,147, 18, 55,243,236, 58,177, 16, 84,211, 26, 21,165,212, 74, 45,101,215, 44, 52,115, 59,170, 78, 20,145,184, 79,213, 65, + 97,181,238, 19, 79,219,167,103, 77, 60,104,167, 69, 4,249, 38,250, 86, 63,104,123,131,154, 6, 75,119, 76, 83,205,127, 79,132, + 54, 68,234,232,222,209,183,230,225,101,173,131,216, 58, 5,175,119, 63,165, 68,248,145,108,107,157,126,212,208, 24,243,107,206, +100, 25,136,114,253,100, 65,236,201, 68,245,162, 16,168, 61, 32,247,200, 62,154,178,139,184, 68,217,184,184,210,197, 11,129,141, +237, 85, 77,104, 36,113,139,155, 36,221, 72,113,238, 49, 84, 87, 18,183, 26,233,109,186,193, 62, 82,206,254, 6, 54, 75, 79,247, +181, 68,146,145,102,191,149, 90, 69,242, 76,158, 31,147,165,160,231, 91,223,127,154, 33,231,151, 52, 10, 54, 79, 88,154,105,154, +105,214,147,223,192,202,194,114,186, 71,207,119, 52, 86,212, 10,119,245,196,177,173,216,115,131, 55,142, 80,143,240,171,255, 53, +252,150,159, 6,249, 28,204, 71, 56, 84,247,172,207,193, 9, 94,161,101, 48,181,205, 91,216,253,205, 99, 84,111,105,144, 82, 35, +173, 43,245, 62, 30,108,223, 16,228, 21,245, 68,143, 27,133, 47, 28,144, 83, 67,239, 87,242,107, 7,174, 62, 56, 81,240, 98,211, +207, 34,205,188,112,248,158,168,143,180,109, 27,249,111,135,165,100, 27,139, 58, 69,210, 21, 17,184,177,222,173,228,111,158,200, +223,211, 69,115, 10,143, 30,193,231,207,174, 10,111,192,113, 69,191, 24, 33, 46,107,236,251,235,206, 34,239,225, 51,136,219,109, + 50,184,165,176, 93, 10,127,186,208, 45,137,113, 48, 35, 29, 5,121, 45,121,149,252,168,210,206, 22,251, 70, 79, 98, 91, 49, 22, + 83,106, 28, 72,114, 18, 14,147,161,103, 67,222,173,200, 23,127, 4,236, 10,218,207,195, 95,255, 79,177,191, 1,235,250, 17,167, +255,235, 41,233,173, 76,174, 43,201, 14,158,241,158,143,120,127,150,252, 17,252,124,141,236,119,197,158,195,242,116,225, 20, 94, +221,186,218,150,158,149,115,212,188,208,221,244,207, 89, 99,175, 33, 9, 74, 17, 90,218,235,182,141,163,249,108, 72,100,197,155, + 52, 44,123,113, 14, 89, 52, 29, 26,191,241,218,133, 11,120,135, 54,221, 1, 47,147, 32, 83,134,127,229, 83,240,217, 3,250, 31, +126,155, 90,206,209, 33,250,248,142, 16, 75, 9, 74,158, 50,109, 58,210, 52, 99,203,234,121, 8,230, 10,221,174, 34,119, 34, 76, +220, 95, 73, 60,199, 64,149,140, 4, 86,179,186,194, 56, 64, 25, 93, 9,223,237,163, 27,246,181,119,120, 50,186,216,227, 97,148, +148,220,252,190,232, 59, 92,186, 14,166, 23,180,232,224,147, 5,146,182,107, 24,108, 23, 85,150,232, 30,189,122, 72,164,209,185, +224,203,109,142,251,216, 60, 61, 56, 0,116,133,119,138,193,106,142,115,213, 93,180,111,147,200,214,141,246,131,207,129,221, 5, +176,196,159,207,221,246, 54, 8,149,166,112,100,200, 24,211, 73, 35, 91,219, 58,185, 53,158,119, 41,190, 91, 47,166, 57, 24,240, + 53, 58, 94,217,180, 18,140, 89,239, 3,225,173, 4, 95,160,138,196,107,186,156, 37, 92,166,125,217, 22, 37,219,189,215,206, 45, + 40,220, 33,156,106, 29, 92, 58,145, 11, 63, 56, 10,122,241, 61,117,221,204, 96,161,179, 49,196, 75,228, 65,158,123, 80, 31,237, +227, 43, 41, 99,156,184, 94,234,108, 24,179, 46,198,157,251,198, 60,215,141,141, 34,102, 28, 82,226, 38,103, 14,243,129,150,148, +165,181, 93, 81, 30, 7, 38, 66, 24,106,102,155,202,125, 19, 99,143, 8, 86,213, 13, 45,251,177,180,181,139,148,180, 33,252,165, +219, 78,194,107, 43,131, 13, 45,245,218,106,230,254,254,222,221,105,119,174,236,194,195, 86,155,119,153,189,224, 3,181,182, 13, + 3,155, 84,145,148, 99, 50,177,187,170, 36, 80,222, 89, 31,208,124,210, 86, 0,132,172,222, 49,212, 56,161,203,192,187, 87,185, + 68,245,245,140, 88,221, 0, 51,177, 87,136,108,224, 52, 18,132,122,129, 27, 99, 25, 69, 34, 69, 77,162,115,151, 29, 43, 27, 69, + 90,215,197,127,125,158, 64, 83,172, 2,116,179, 26, 32, 62, 98, 17, 19,106,109,176,158,152,144, 24,173, 24,106,133,105, 58,160, +201,123,212,146, 19, 77, 60,197,205, 90,117, 98,217,249,142,118,127,199,178, 44,110,255,201,141,180, 20,238,109,101,181,194,225, +217,138,125,180, 32,159,187,194,126,225, 61,228, 11,255, 3, 60,250,189,254,180,111,241,137,206, 62, 70,103,245, 44,116,170, 92, + 38,235,244,200,189,182,231,138, 87,115,134,115, 58, 25, 53, 36,193,249,107, 33, 26,251,236, 1, 94,205,240,189, 7,210,237,138, +189, 92,201,167,202,241,197,202, 26,184,208, 62,230,222, 34,108, 59,113,108,244,135,198,200,184, 19,208,146,185, 23,121,246,151, +140,102,163, 90,163,189, 56, 99,223, 57, 33,159,155,176, 71,138,228,140,124,230, 53,236,124,134, 50,163,175, 77,200,103, 15,108, + 56, 53, 1,157,140, 52,240, 51, 83,191,184, 2,166,160,241,179,219, 40, 78,138,127, 38, 60, 69, 75, 94,155,224,117,215, 64,240, +188, 97, 47,156,245,110, 75,165, 46,141,181,121,130,149,138,211,205, 14,201,121,222,233,235,149,233, 95,255, 34,124,223,207,192, +242,239,211,254,143, 95,164,252,217,247, 40,175, 43, 79,223, 95,169,175, 43,143,154,145,238,171,183, 40, 93,236,208,112, 47, 66, +249, 22,156, 86,120,114,128,183, 23,206,207, 10,167,218, 56,103,161, 54,227, 92,155, 31, 62,205,109,102, 26,216,210, 22,130,208, +139, 67, 83, 88,201, 44,198,148, 26, 63,202, 74, 8, 23, 75,207, 65,119, 37,189,220, 25,121, 54,183, 52,166,228, 54,190,178, 35, + 35, 21,115, 71, 64,168, 98,233, 43, 42, 9,107,202,181,194,219, 39,248,171,183,180,231, 43, 45, 9,182, 70,215, 26,160,120, 83, + 33, 77, 9,201, 19,150, 39,214,197, 71,143, 85, 50, 83,134,156,101,179,175,105, 41, 20,109,216,234, 7,195, 22, 49,200, 22,113, +198, 34, 50,196,146,238,225, 43,227,126,148, 36,180,234, 83, 9, 85, 33, 37,161, 52,143,133,244, 7, 72,194,164,109, 90,147, 26, +220,130,145,142,168,177,219,223, 16,210, 67,129,157,162, 8,183,182,139,167, 82,138,243, 80,181, 11, 17,203,212,113,190, 67,151, + 55,133,108,133,225,191,143, 93, 91,100,123,179, 98,145, 83, 94,204,187,123, 17, 23, 16, 55,177,109, 95,205,192,228,144,200,152, + 72, 50, 52, 72,157,157, 47,194, 74,115, 61, 70, 74,174,254, 15,118, 68,127, 50, 76,154,104,201,182,233, 99,217,112,179,118,177, +179,174,131,118,102, 51, 50, 68,113,242,169,171,186,216,113,179,208,170,251,210, 99,111,223, 45,164, 85, 52,182, 62,254,190, 59, +224,166,181,182,163,110, 5, 22,179, 77,148, 86,135, 3,145,217,199,107, 94, 79, 48,235,135,137, 29, 56, 35,151,108,118,123,160, +104,223,101,113,251,245,100,151,201,124,219, 36, 64,252,154,106, 65, 42,154,128, 67,158,152,210,228,147, 7,129,108,131,191,123, +195, 17,251,169, 80,209, 13,180, 84, 99,105,211,237,191,147, 40, 45,103, 50,194, 89,148, 90, 86,135,161,141, 19,199, 49,224, 53, + 10,184,201, 16, 39,168,186,143,222,187, 58, 90, 34,123, 52,224, 53,214, 6,213, 77, 76,114,144, 20, 43,176, 26, 71, 47,191,203, + 90, 43,219,129, 88, 73,190, 70, 32, 72,170, 61, 41, 53,154,113,171,149,156,162,235,117, 1,155,108, 2,183,142,235,179, 45,224, +192,250,148, 0, 21,121,128, 83,220,232,234, 67,231,190, 71, 62,105,156,110,250, 27,149, 7,194,162,174,114,223, 79,226,123, 70, +187, 52, 23,179,137, 26, 82, 26,180, 21, 59,199,206,124,158,144, 52,185,135, 93, 4,210, 76,210, 41,252,183, 11,186, 44,100,169, +232,225, 49,114,120, 66,182,194,148, 82, 88,105, 86,150,218, 72,117, 37, 89,193,202,153,118,190,141,194, 85,200, 42,152, 40, 38, +141,214, 10, 43,141,251,214,152, 94,156,225,163,123,228,205, 25,185, 61, 98,191,246,151,145, 31,123, 29, 14,175,192,244,220, 47, +199,236,237,175, 46,126,145, 86,147, 45,219,220,189,199,131,191,179,251,143,155,209, 84,152,107, 35,175,171,239,226,191,149,200, +175, 6,233,237,149,201,211,220,190,112,133,190, 88, 73,231,194,241,180,178,172, 70,233, 93,200,168, 6,102,207,229,182,234, 15, +206, 45, 80,174, 7,188,196,119,187, 11,215,124,236,213,206, 70,123,111, 37,125,112,118,209,220,225, 57,204, 95,128, 79, 63,135, +151,207,145, 31,156,225,115,115, 60, 69,187, 23,180,187, 16,100,251,185, 7,219, 89,233,157,105,172,145,230,149, 98,122,147,122, +146,214, 81, 72,159,202, 14,225, 41,134,189,112, 52,172,105, 11,101,189,133,136,203,233,109,135,100, 92, 41,228,175, 22, 14,191, +249, 9,250,167,255, 48,180,175,194, 55,127,149,243,191,241,117,238,175, 26,207,158, 43,167, 43, 33, 39, 56, 84, 56,158,138,175, + 11,172, 47,250, 15, 96, 79,225,244, 45,120, 23,248,112,165,252,234,137,178, 86,202, 12, 53, 11,247, 47,161,172, 46,193,184,146, + 80, 82,235, 5,253, 56,210,155, 66, 56,180, 4,186,118, 0, 65, 72,140,226, 39,221,169,114,152, 79, 49, 76, 64, 86, 67,151,230, + 26, 6,113,211,186,158,131,152,152, 18,122, 76,129, 72,139,252, 85, 9,156,237,210,176,251, 5,249,159, 10,237,206,168,186,250, +212, 36, 46, 46,205,208, 44,199, 62, 46,147,166, 76, 42,161, 27, 17, 65, 38, 31, 77, 90,144,180,106, 35,198,142,141,166, 33, 30, + 13, 30,128,180,182,175, 55,119,251,202,238,100,217,144, 21, 97,141,154,148,137, 68,163, 97,166,148, 13,228, 62,144,187,123, 48, + 14, 26,116, 50,127,148,229,224,117, 71, 3, 78, 9, 22,108, 70, 73, 52, 50, 70,177,230,163,112,177, 16, 28,183, 45, 54,180,196, +129, 9, 60, 91,125,142,103,203, 93,140,241,175, 4,158,168,112,109,112, 10,246,195, 49, 58,236,243, 70,161,243,251,170,167,152, +117,113,218, 36, 66, 22,183,175,217,208, 53,215,216,199, 79, 2, 47,251,245,109,187,245, 20,122, 42,154, 59,117,178, 8,107,140, + 53,250,190,217,175, 17,165, 90,114,107,110,107,219,238,124, 3,226,244, 2,223,187, 97,187, 84,232, 35,158,223,110, 81,176,251, +110,126, 22,193,242, 52,240,224,123,112,137,108,164,185,190, 43,209,141,208,231, 95,106, 21, 7,207,108, 93,185, 13, 69,157,143, + 91,218,122, 83,214,223,243, 88, 4,229, 65, 72,184, 92, 68,109,126, 18,152,102,215,163,116,252,240,134, 46,111, 45,154, 79,223, +131,123,168,147, 50, 69,195,215, 84, 88, 90,193,106,219,159,137,150,182, 58, 54,133,102,204, 6,209,165, 69,125, 75, 57, 51, 29, +103,238,238,149,243,253,125,104, 67,100, 23, 46,198, 33,175,141, 17,225, 67, 78,137, 6,156,101,231, 39,117, 55,148,110, 78, 13, +209, 20,182,187, 18,127, 69, 36, 24, 70,184, 26,170,174,155,137, 21, 67, 39,212,149, 97, 45,208,231, 39,170, 1, 2,243, 64,151, +125, 95, 34, 3, 31, 62,233, 30, 63,183, 77,238,101,207, 72,239,191,177,251, 4,183, 40, 86,141,168,209, 17, 27,185, 65, 38, 98, +200, 31, 97,241, 27,242, 48, 50,211,117, 80,179, 74, 23,119,152, 43,180, 37,132, 14,130,159, 54,165, 84,172, 45, 52,156,248, 35, + 57, 35,185, 32, 92,193,116,100,150, 35,201, 26,233,248, 10,114, 56,162,173,162,166,225,217,172, 44,171,113, 62,159, 56,148,133, +163,174,200,122, 66,150, 83, 60,235, 51, 18, 74, 19,169,133,110,250, 94, 69, 56,175,149,227,187,103,236,205, 5,121,114, 5,191, +112, 7, 95,252, 75,200,117,198,222,152,145, 95, 59, 35, 77,221,110, 52,123, 24, 75,137, 56,197, 14,251, 96, 80,128, 91,140,207, + 20,217, 92, 1,102,198,116,191, 80, 95, 42,242, 53, 37, 61,202,222, 78, 31, 21, 62, 51,161, 31, 30, 73,207, 86,218,205,196,213, +243, 53,132, 49, 62,102, 29, 17,164, 91,162, 26,251, 73,187, 71,157,174,198, 22,182,209, 85,164,214,101, 17,147, 97,119,158,184, +198,109,133, 87, 23,247, 72, 62,250, 65,236, 83,191, 8,223,223, 60,136,166,196,245,177,198,202, 37,137, 39,202,201,174,221,216, +188,215,116,254,121,140, 89,213,152,213, 56, 38,113, 33,250,213,132,126,102,242, 23,248,180,209, 94, 44,180, 82,105, 75,195,238, + 43,181,238,190,227, 99, 96,126, 15,239, 84,142, 73,200,255,213, 63,235, 67,193,242,235,172,127,230, 55,184, 79,133,219, 55, 39, + 78,109,128,135,116,195,248,105,204,172, 45, 94,212, 95,188, 3,239, 24,237,246, 76, 89, 79, 44,217,184, 59, 9,119, 75,163, 86, +139,117,133, 79,124, 14,129, 25,222, 66, 94, 82, 0, 98,100,127,208,117,156,175,196,238,178,117,184, 76, 40,198,123, 75,219, 25, +205,210, 97, 32,173,185, 54, 36,118, 34, 58, 41,114, 29,106,192,106,187, 90, 60, 78,206,118,223,168, 90,209,121,162,229, 74, 91, +188,123,151, 52,163,150,162, 7,201, 17, 97,170, 78,148,107,177, 3, 76,130,213,234,133, 42, 9,199,199,137,229,108,220,190,104, +126,244,146, 26,221,183,161,213, 15,244,190,207, 86,215,165, 12,166, 98, 25, 14, 43, 18,213, 93,213, 61,191,107,243, 81,163, 63, +227,211, 54,195,109, 67,186, 84,138,110,178,137,143,122, 19,251,222,162,197,206,210,129, 63,141,220, 26,171, 53, 23,211,185, 88, + 36, 28, 29,230, 59,116, 97,219,251, 75,168,209,231, 7, 42,109, 17, 56,102,225, 81,172, 0,102, 92,245, 62,197,234,232,212, 59, +217, 22,118,181, 65, 92, 54, 13,141, 72,143,144,238,135,180, 24,210,109,187,126,217,226, 86,117, 43,106, 5,139,231, 73,242,236, +117,107, 36, 75,219,110,187,196,206,197,215,136, 21,107, 45,120,240,145,106,215,131, 98, 46,118,230,114, 49,206,150,176,114,105, +206,172, 49, 86,151, 86,185, 81, 37, 77,137,186,174,100, 85,102, 77,241,153, 8,117, 72, 49, 83, 27,211,230,108,171, 0, 93,127, + 83,237, 19, 40,123,246,176,235,230, 19, 98, 91, 47,169,114,194, 3, 58,230,229,241,100, 3, 5,117, 91,181, 38,231,172,247, 6, + 70,163, 19, 46,214,208, 90,120, 52, 31,152,231,153, 36,194, 9, 56, 45, 43,247,235,226,171,220,172,204, 6,115,118,194,129, 70, +231,155, 85, 31,184,112,196,153, 13,165,144, 74,229, 56,207,212, 90,105,203,178,249, 86,229, 65, 83,187,129,198,182,131, 81, 26, + 98, 87, 29, 99, 46,195,193,165,131,108,188,187,175,219, 24, 94,100,248,189,234,135,119, 77, 62,234,107,197, 17,217,182, 37,214, +201,230,164,144, 97,125, 64, 10,161, 92, 22,241, 34,187,169,145,247,124,116, 6,128, 67, 15,161,232,153,204, 61,178,112,200,146, +243,223,151,186, 96,192, 6,245,124,139,241,248, 14, 15,216, 24,190, 49,122, 79, 15,144,143,186, 61,191, 26,201, 90,144,233, 52, + 14, 13, 1,178, 49, 67,214,157, 5, 47,226,172,247,252,248, 13,180, 9,106, 5,106,217, 78,143,102,149, 82, 87,218,114,166,214, +133,181,173,174,138,111, 5, 53, 39,217,137, 42, 45,180,164, 82, 87, 18,174, 64, 92, 12,238, 17,242,237,138, 62, 93,177,199, 19, +242,109,195,126,249, 41,242, 91, 95,133, 47, 92, 33,255,240,228, 7,132, 99, 66,107, 65,138, 56, 75,124,176, 58, 49,142,150, 58, + 6, 63,188,193, 77,216,176,136,114,187, 80,179, 32, 95,141, 76,250,239, 61, 56, 31,254,123,103,244,249, 76,186, 47,228,251,202, + 85,171,180, 96,126, 91,172,116, 82,236,238, 37,254,219,162,136,212,193,118,210, 71, 79,253, 6,110,221,184, 43, 6, 7,195, 78, + 5,121,214,176,215, 22,100,126, 10,250,143, 33,175,127, 14,251,220,215,144,227, 17,206, 11, 76, 9,185, 6, 61, 10,243, 29,187, + 48,178,231,144, 91,143,163, 29,252,232,106, 27, 69,237, 42,195, 85,138, 46,253,181,236, 79,148, 23, 94,200,237,212,176, 82, 89, +207,141,115,236,146,115,130,131, 26,215,207,141,235,247, 27,135,191,240, 59,225,181,239,131,250,183,105,255,205,175,115,255,203, +207,185,251,129,196,125,136,245, 54, 81, 38, 3, 46,183,198,206,163,189, 15,229,171,216,183,111,225,214,168,207, 23,214, 83,229, + 14,225,188, 6,253, 45,118,179, 73, 96,158,247,245,212,164, 67, 38,250,228,154,130,108,226, 33, 35,137, 13,130, 68, 4, 68, 28, +212,161, 44, 86,119, 52,103,210, 56,133, 75,132,252, 20,131, 99,114,172,235,117,232, 25, 68,161,149,184,103,186, 90,222,224, 62, +188,197,139, 33,147, 97,211,236, 31,206,148,193, 20, 61,133,143,176, 21,106, 43, 36,102,144,138,152,211,197, 74, 13,161, 79, 60, +137,143,215, 74, 89, 45,242,220, 91, 20,141, 22, 22, 59, 11, 62,133, 23, 46,107, 59,155,194,146,132,227, 98, 39, 40, 90, 18,106, +171,155,109,104, 23,110,218, 6,157,234,249,237,210, 31, 32,205, 59,118,149,202, 18,226, 50, 34,184,166, 90,115,239,127, 51,154, +181,173,251,222,233,109,238, 65,151,104, 40, 52,200, 90, 41, 50,213, 43, 66, 49, 99,138,208,154, 42,158,147,254, 40, 68, 66, 55, + 24,143, 66, 76,123, 14,245,253,125,147,109, 59, 93,163, 43, 94,204,191, 99,141,226,118, 97,233,165,179,225, 29, 38,212,243,229, +109,244, 85,119,220,170, 25, 90, 11,154,178, 71,211, 70, 87,219, 66,112, 88, 91,159,138,250, 29, 91, 91,163,152, 79, 14, 90, 95, + 67, 12,225, 54,109, 40,132, 98, 70, 13, 79,188,150,178,117,181,103,132, 84, 11,211, 52,123, 23, 26, 64, 22,217,152,239, 35, 25, +225,178, 88,239, 98,187,189, 32,136,109, 81, 50,151,177,170, 23,249,114, 50, 28, 57,118, 70,133, 13,107,215, 20, 35,242, 50,116, +187, 35, 17, 80,251,103,170,238,169,239, 19,177,141,170, 22,211,201, 89,132, 73,149,220, 29, 75,235, 66, 41, 43,143, 83,246, 64, + 33, 77,155, 48, 17,221,179, 70, 69, 98,234, 17,171,146, 20,130,183,165, 53, 78,203, 25, 13,203, 97, 75,142, 76,255, 88,186,172, +202,142,243,147,135, 0, 30,217, 14, 9, 61, 21,110, 43,200, 41,111, 68, 77,215,175, 57, 79, 69,165, 33, 41, 15,127,198,175,121, + 11,143,188,196,122,101, 19, 30,251,206,218,127, 95, 88,190,115,146, 94,196, 7,191, 92, 87, 21,142, 24,190, 30,152, 16, 70,122, +177,221,155,238,169, 52,122,153,166,163,151,244, 48,185,176, 53, 92,142, 91,236, 65, 84, 94, 15,150,215,126,160, 48,115,163,125, + 50, 52, 77,152,212,232,110,186,186,216, 80,107,104, 91,209,150, 72,229, 68, 62,223,146,174, 95,113, 59, 79, 4,206, 52,204, 85, +218,205, 48, 10,218,140,165, 24, 42, 43, 55, 52,116,242,113, 72, 46,133, 66,245, 29,162, 85, 68,252,193,178,152,144, 84, 40, 84, +166,151, 11,118,154,125,156,248, 43, 11,246,249, 59,248,204, 4, 95, 58, 34,207, 3, 66,160,201, 17,141,186,147,179,236,129,208, +133, 14,153, 8,167, 67,233,227,204,228, 76,215,249,197, 61,124, 27,242, 98,232, 1,223,175,223,100,228,139, 87,164,143, 86,210, +237,202,213,234,194,154, 83, 20,102,139,170, 58, 69,231, 94,213, 17,231,171,236, 69,174,119, 24,107, 53,230, 0,162,228,201,255, + 33,187, 77,141,219,234, 2,178,115,134,250, 2,202,123, 48,127, 30,121,243, 27, 48,205,158,212,114,173,164,155,153, 41, 47,208, +224,145, 54, 78, 83,140, 10,207, 70, 75, 59,225,169,169,167,169,165,216, 97,206, 73,184, 50, 72,179,122,151,126, 61,249,232,253, +174, 96, 75, 88, 6,106,165,174,230,123, 61, 17,142,201,184,169,112,245, 27, 43,215,255,214,247, 34, 63,245,135,160,254, 93,248, +165,239,176,252,103,223,102,249,158,196,162,176,174,238,147, 79, 41, 20,173,253, 3, 63,168,135,208,144, 97,253,154,255,243, 94, +197, 14,126, 83,148,210, 40,230, 55,125,138,148, 45, 11,237,129,180, 16, 29, 70,173,213, 14, 0,103,183,118,164, 9,210,226,221, +122, 45,126, 17, 79, 73,252, 51,142,162, 30,231, 91,159,148, 76, 61, 20, 41,238,185,158, 66,146, 35,189,239,190, 33,209, 36,200, + 33, 78,104,247,133,214,247,230,243, 68,187,186, 70,152,253,128,107, 32,101,161, 74,133, 86, 60, 92, 34,207, 80,205,173, 55,161, + 83,217,227, 33,149,151,167,198,139,175,159, 41,171,145,115,127, 16,245,123,175,109,185, 1,169, 99, 69,101, 55,151, 98,227,248, + 56, 96, 53,109,223, 53,118, 85,187, 53,118,165,182,238, 34,192,109,108,169,196,129, 59,236,164,205, 11,167, 2, 55, 98,204, 41, +108,178, 81, 80,196, 60,141,108,238,252,252,120,170, 46,209,121, 37, 13, 81,108, 56, 64,102,220, 50,121, 37,198,141, 65,214, 70, + 50, 15, 28,138,109, 89, 60, 23,124,152,115, 14, 54,184, 19,121, 53,148,213,221,183,174, 91, 23, 75,216,169, 82,232,130,146, 40, +215,129, 45,182, 45,122, 90, 6, 94,157, 11,165, 22, 51,164,214, 16, 11,123, 33,209, 13,124,101,219,107,233, 98,186, 66,172,238, + 34,205,178, 62,200,133, 87,131, 41, 5, 25, 48,246,253,165,249,207,152,187,176,170, 85,178,121, 76,117, 63, 20, 16,116, 53,213, +208, 22, 89,123,144,189,185, 79, 5,182, 67,224, 69,124,237,174, 81,223,145,166, 18, 62,243,113, 29, 40,157,155, 18, 94,255,189, + 32, 84,187,204, 87,235, 5, 49,117,141, 85,242,155,171, 95, 82,125,197,210, 35,193, 15, 41,115, 61, 31,152,166,137, 69,132,181, + 84, 82, 51,174,231,153, 73,117, 32,245,133,117, 46,234,193,214,188,118, 33, 95,252,251,100, 80, 83, 98,137,157,186,104, 66,163, + 8,167,160,196,245, 28,143,113,207,190, 43,229,189,187, 74,219, 97, 45,242,220,219, 30,236,226, 3,183, 70,211,208,141,116,209, +185, 78,238,226,194,168, 45,212,199,107, 25,178,212,195,198,217,239, 75, 42, 86,195, 21, 54,101,242,116,240,162, 46,221, 99, 25, + 93,250, 88, 84,115,156, 3,251,169, 96,227,229,110,233, 51, 67,118,174, 61, 0,250,199,131,163,143,242,253,130,244, 11,127, 31, + 89,200,198,148, 47, 33,154,146,160,206, 73, 31,247, 7,227, 84,106, 65,114, 70,167,201, 71,167, 33, 96,240,177,125, 35,203,180, + 37, 89,229,186,144,150, 19, 58, 77, 33,250,240,130,190,134,247, 55, 77, 71, 82,169,148,213, 56, 47,149, 99,134,156, 39,214,101, +197, 20,180, 86, 39,204,217, 46, 5,170,166, 20,171,126, 48,123,185, 96,167,234, 47,248,195,130,188, 91,224,179, 71,248,129, 43, +244,155, 39,236,219,133,118,181,146,238, 61,220, 99, 29, 68, 37,109, 96, 70,111,105,193, 67,144, 70, 1,172, 68, 26,215,189,113, +144,123,184,111,228,217,208,171, 87,225, 21,133,215, 51,250,197, 35,233,101,161, 45,149,235,211, 26,116,171, 62,234,222, 39, 41, + 83,160, 93, 79, 65,249,202,189,195,244,160, 58,146,121, 50,216,156,118, 50,154,157, 27,246,172, 33,183, 6,207, 43, 60,186, 7, +249, 22,200, 91,240,228,245, 8, 66, 89,163,147, 20,178,206,232, 79, 28,121,242,141, 59,206, 31, 22, 22, 51, 7,158,196,107,104, +178,239,232,102, 53, 30,101,229, 38,195,181, 24,249,241,132,190, 53,123,165,127, 81,220,227, 31, 48,161, 13, 35, 43,238,150, 56, + 34,220,124, 99,229,234,159,252, 20,250,167,254, 69,168, 95,129,167,191,193,250,175,125,149,245,181,198,250, 88, 40, 75,140, 89, +213, 34,159, 28,242, 44,232, 49, 35,175, 39,143,185, 77, 25,234,219,216,203, 2,183,130, 61, 50,135,251,100,183,202,117,228,173, +245,135, 11, 46, 96,156,122,104, 81,236, 24, 58,201,184,143,157, 36, 41, 51, 70,142,208,140,102, 30,216,162,215, 26,137,107, 70, +214,240,143, 7,171, 65, 82,140,190, 38,233,150,129, 56,208,164, 93,169, 98, 65,144, 58,227, 91,229, 99,114, 61,246, 60,251, 53, + 88, 22,228,182,248,228,100, 58, 96,156,225,254, 76, 59, 36, 40, 46, 18,213,161, 19, 18,141, 71,238, 82,188,152,171,112,152, 92, +136,216, 12,114,147,144,234, 4, 9, 43, 86, 60,151, 15, 95,183,224,136, 64,233,194, 67,149,205,122,227,173,243, 8, 81,209, 45, +106,150, 80,206,203, 64, 50,171,190,163,218, 82,186,174, 98, 61,116, 29, 98,189,206,166, 80,243, 85,207, 78,147,219,131, 89, 52, +108,115, 41, 32, 87,130,241, 72,140,163,134,157, 13,120, 36,198, 85,242,209,252, 83,217, 61,237,247, 1,156,186, 53, 47,236,247, +225, 99,239,212,198, 98, 18, 49,165, 18, 65, 41,225,194,136,231, 91,147, 68, 82,229, 17,112, 85,205, 25,236,209,173,237,132,224, + 40,120, 98, 44,120,104,136, 84, 65,226, 73,219, 6,149,187,197,201,167, 99,181,183, 92,141, 78, 66, 27, 60,222,143, 82,226,234, +112,160, 73,226,108,141,218, 92,135, 82,204,208,214,200,234,150,224, 28, 66,197,132,175, 19,155,213,173, 67, 77,193, 23,175,173, +109,220,117, 25,236,102, 15, 49,176,250,192,189,173, 97,173,234,148, 61, 25,208,182, 91,212,234, 32,163,223,119,242,151, 60,127, + 17,225,144,156,213,222, 15, 7,205,204, 41,125,182,103, 6,136,193,181, 40,143,230, 3,215,199,153, 98,110, 11, 43,117,197,172, +113, 94,171,167,204,137, 79,129,114, 82, 74,206,254, 51,154, 81,117,159, 73,244,235,184,198,122, 55,139,135,191,156,154, 91,203, +146, 42,150,220,121, 69, 78, 46,196,142, 52,209,206, 16,222,210,215,182, 32, 50,221, 14,161, 61,144,193,194,217,225,159, 19, 33, +248,219,237,141, 93, 4, 87,171,255, 76,119, 65, 52,184, 8,180, 29,184, 39,157,114,152,103,242, 97,118, 74,160, 88, 88, 87,122, +250,146, 74,248, 95,141, 36,251,120, 96,191,184, 2,201, 23, 71, 53, 13,244,100,139,236,114,122,135, 30,194,168,141,248,164, 67, + 18,141,236,169, 64,187, 27,113, 23,120, 73, 87,253,234,238, 99, 86, 12, 41, 11, 36, 69, 15, 71, 36,103, 39,206,181,182,137,175, + 84,253, 20, 53,165,196,148, 5,105,103,100,173, 52,157, 41,129,237,236, 76,102, 13, 63, 87,170, 43,181, 44,156, 16,174,167, 22, +239,185,251, 4,125,132,216,237, 62,221, 67, 89, 68,169,119, 13,121, 94, 92,149,254,116, 69,190,181,192, 77, 48,203,191,255, 26, +121,122,130, 37, 35,199, 66, 90, 27, 97,123,220,160, 16, 18,113,134,102,251,158,189,217, 16, 9, 41,134, 85,113,255,239,217,200, + 47, 78,208, 26,249, 58,161, 63,250,200,237, 87,111, 29,200, 31,172,216,217, 35, 67,231,165, 58, 73,106,208, 70, 72, 4,136, 28, + 38, 31, 91,175,129,146, 76,120,129,186, 74,177, 3,236, 93,123, 63,168, 95,137, 63,245,238, 11,188,200,216,203,132, 76,207,189, + 21,205,175,130,156, 65,110,247,157,204,191,252, 26,250,227,143, 56,252, 59,223, 68,191,245,130, 44, 70,202,205, 87, 32, 98, 17, +239, 27,254,226, 4,215,185,241, 24, 99, 62, 78,164,207,207,240,218,236, 77,221, 51,224,189,234,106,163,190, 14,154,225,170,130, +170, 49,127,171, 49,191,117,133,254,231,127, 20,236, 67, 40, 95,165,254,153, 95,163,220,159, 56,125,175,112, 90, 59, 10,221, 59, +144,131,250,168, 54, 29, 18,250, 74, 70,222,200, 94,212,173,193,253, 61, 60, 51,120,182,208,158, 47,212,151,197, 21,237,177,255, +206,225, 97,238,158,230,156,136,247,165,200, 33,102,165,159,196,186,188,241, 56,225,180, 24,118, 10,171,207,148,134,104,225,160, +100,217,126, 51,115,136, 49,252, 41,204,248,115, 66, 87,131,165, 33, 57,193,245,140,149,105,131,247, 52,245, 17, 29,107,129,219, + 6,215,205, 11,181,202,255, 75,215,187,198,218,150,101,247, 93,191, 49,230, 92,107,239,125,206,185,239,186,245,174,174,174,114, + 87,187, 95,238,216,198,118, 28, 36, 68, 94, 8, 41, 33, 65, 68, 40, 49, 8,137, 15, 17,144, 8,129,136,248, 18, 66, 4,124, 32, + 10,124,228, 67,132, 0, 5, 41, 34, 18,137, 18, 18, 57, 74, 8, 81,162, 32,199,177, 99, 76,251, 17,219,221,233,118, 63,171,186, +222,117,235,190,206, 99,239,189,214,154,115,240, 97,140,185,214, 58,213,198, 82,169,219,213,247,158,199,222,123,205, 57, 30,255, +255,239,143,217,132, 92, 29, 66,104,174,238,161, 47, 70, 74,134, 78, 26,100,171,224, 11, 4,154,204, 45,116,186, 36,194,133,237, +180,145,227, 28,227,108, 51, 19, 93,215, 99,223, 48, 36,123, 70, 68, 93, 44, 98, 81, 16,215, 54, 41,105,207,127,112,251,179,250, +207,165,113, 96,167,168,228, 45, 70,224,187, 16,176, 53, 36,114, 31, 45,253, 28,247,218, 20,228,213, 24,196,187,251,109, 53, 54, + 24,155,152,225,102, 51,127, 47,155, 67,193, 55, 28,108,146,143,201,235,136,175,106, 90,202, 92,187,200, 87,148,179, 41, 38, 19, + 37,136,110, 53,110, 39, 93,197,225, 74,179,147, 69,150,249,221, 84,216, 35, 12,243, 9,167,179,127,123, 46, 98, 48,174,106, 97, + 50,119,113,136, 38,191,116,155,128,173,117,210,234, 40,235, 36, 53, 16,178,161,188,143,247,225, 68,133, 27,253, 22, 82,102, 31, + 10,247,100, 70,175, 9, 83,165,212, 8,171,210, 37, 58,203,163, 3, 92, 40,214, 4,120, 77,185,174,162,113, 54,213, 89, 39,114, +141, 24,247,137,139,220, 86, 24,216, 18,107, 27,189, 6,230, 89,121,188,171,204,208, 33, 93,197,250,182,198,177, 71, 56, 73,137, + 77,191,225, 40,194, 52, 77,115,119, 95,205,102, 17,117, 1, 78, 68,184,185,221,176,219,245, 20,131,171, 50,113,113, 56, 80,198, + 66,210,134, 28,110, 59,231, 74, 53,245, 53, 13,194,104, 21, 43, 50,147, 78, 97,137, 52,157, 67, 90, 36, 99,253,134, 50,142, 62, + 49,233, 58, 76,149,161, 20,108, 58,206,238,134,182, 14,152, 87,198, 49,189,105, 59,255,164,134,106,142,149,156,107,138,106,153, +144, 41,244, 69,184,189,206,112,215, 86,109,191,115, 78,212,113,188,238,156, 90, 79,211, 53,185, 29,188,235,125,239,110,134, 78, + 35,185,209,110,146, 88,252, 48, 13,251,186,188, 41,105, 22,207,173, 2, 88,108, 81,175, 54,118,132, 10,171,172,216, 54,198, 95, +109, 90,196,171,108, 23, 4,233,108, 99, 19,107,187,188, 37, 36, 97,238, 98,194,139,167, 81,226,217,112,240,175,189, 57,129,148, + 17, 70,143,112, 77, 41,236, 41, 70,103, 5,173, 6, 82,220,246, 33, 27,175, 74,169,241,245, 12,246, 7,216, 95,160, 86, 48, 77, + 28, 20,100,156, 56,209, 26,118, 17, 39, 48,165,198,171,196,211,142, 42, 49,206, 54, 72, 79,134, 24,147, 42,245, 27, 71,244,165, +141, 43,213, 63,181, 65,223,222, 98, 99,161,142, 19,249, 48,146, 71, 99,140,162,168,169,207,215,226,145, 89,197, 26, 7, 76,198, +119,144,213,252, 98,207, 90,217, 61, 60,194,215, 47,232,118,130,124,118, 7, 39, 9,121,109, 67, 26, 38,236, 56,209, 31, 11, 35, + 49,102, 15, 98,157,197,195,211,169,199, 52, 86, 60, 16,166,226,108,155, 77,110, 41,110,174, 36,146,236,163,127,233,241,194, 33, +197, 50,113, 12,227,116,154, 32,221,129,238, 4,248,216, 47,127,128, 95, 61,192, 47, 92,113,124,115,160,244,126, 66,246,147,143, +242,187,184,212, 53,116, 19,189,192, 89,129, 93,175,164,155, 29,122,167, 71, 78, 51,100,144, 27, 9,249,209, 45,250, 0,236,109, +239, 76, 21, 79, 53,211,143, 42,221,101,162,251,235, 63, 1,105, 15,229,155,212,255,249,251, 28,126,233, 49, 23,175, 43, 23, 71, + 31,167,150, 54,161,104,187,251, 4,218,169, 83,240,158,237,252, 84,183, 61,118, 81,224,195, 3,245,205, 3,211, 59,123,142, 79, + 39,246,189, 95, 66,225, 6, 35,169,197, 78, 47,190,102,167,232,205,206, 33, 49,182, 36,136, 72, 9, 91,209,228,221,187, 24, 88, +175,115, 39, 47,185,241,130, 99, 15,110,235,232, 92, 9, 79,120,109,202, 32,215,139,140,130,222,190, 9, 63,114, 11, 6,165,126, +235, 10, 27, 14, 78, 80,196,224,120, 5,135, 1,203,201,139,220,228, 11,111,187, 26, 40, 67,133,109,239,232,200, 18, 62, 58,131, +100, 19,211,116,221,127,155,128,105,138, 52,198,134,100,166, 6, 79,123, 57,112,167,249, 32, 95,248,218, 9, 15,238,105,235, 54, + 31, 41,250,225, 45, 17, 67,170,248, 33,183, 22,221,106,251,194,169, 93,226,204, 77, 67, 75, 60,219, 38,143,178, 77, 10,155,176, +137,165, 86, 8,151, 74,103,117,158, 62, 72,117,161,220,214, 99, 3,226,185,181,217,249,215,244, 13, 38, 53,104,150,139,157,237, + 18,175,165, 26,188,133, 85, 62, 56,234,249, 16,230,179, 15,199,235,134,160,175, 29,178, 85,220,254,155, 76, 24,129, 93, 82,238, + 3, 15, 98,234,209, 37, 15,185, 26,163,123,254,100,146,217,100,149, 99,153,232, 85, 81, 73,116, 98,177,178, 75, 76,181,206,235, +201,169,250,153, 80, 26,247, 82,124, 34,209, 73, 98, 82,229,106, 26, 25,166,137,222,224,164,235,208,156, 29, 37,145, 36,194,184, +116,241,130,199, 51,178,209, 68, 73,142, 10, 46,120, 1,208, 70,176,134,206,226,214,235, 29, 98,109, 50,102,111,220, 86,184,227, + 58, 47,102,214,177,202,205, 41, 16,103,122,156, 73,149,235,107,215,132,115,218,181,239,184, 52,152,166, 17,177, 58,143,248, 83, + 43,136,128, 83, 21,238,108, 54,156,156,156,112,196,216, 15, 19,231,227,145, 50,142, 97,135, 91,241, 87, 26, 15,164,184,214, 67, + 83,132,126,155,145, 34, 12, 5, 19,114, 78, 46,198,171,222,201,214,184,179,186,156,200, 57,163, 57,177,159, 38,234,126,152,195, +142, 70, 98, 12, 82, 0, 0, 32, 0, 73, 68, 65, 84,100, 61,177,142,238, 60,229, 20,223, 35, 68,109,154,130, 0, 89,252, 66, 87, +161,142, 81,148,118,201, 87, 33, 17, 6,227, 90, 52,241,206, 39,172,214, 51,223, 97, 94,109, 11,218,117,104,234,144,228, 36, 61, +139, 17,143,249, 61, 26,129, 12,113,161,187,197,173,141, 82,108,222,165,251, 47,111,115, 50,206,236,213, 8,218, 92, 90,177,198, +175,133, 74,173,197,117,171,218,205,137, 89, 30,163,144, 84,220,163, 45,159, 64,206,174,162, 25,197, 19, 38,252,191,143, 7,191, +156,251, 29, 41,119,179,192, 45,165, 52, 71,238,121, 84, 93, 98, 40, 19,133, 35,208, 35,177,208,116, 64,254, 68, 46,197, 83,209, +106, 97,154, 38, 46,199,209,173, 75, 86,232,196, 40,105,237,173,176, 25, 5, 89, 13,166, 82,232,175, 10,182, 29,253, 34,255,184, + 98,223, 72,200, 23,207,252, 20,121,227, 12,189, 24,168,135, 14,221, 78, 1, 62,241,241,102,147, 20,213,232,210,235, 10, 29,219, +130, 23,166,128, 79,148,160, 17, 13,225,191,188,245,209, 21,124, 85,232, 78, 4,249,212, 9, 60,211,161,251, 13,250,100,162,187, + 42,236,246, 19, 99,136,230,202,234, 61, 81,241,105, 65, 19,109,137,192, 73,246,142,170,101,147,159,116,208, 63,151, 73,187, 4, +123,195,158, 76, 88, 82,100,175,112, 72, 80, 50,108,134, 88,153,220, 3,253, 62,236, 70,143,140,253,213,115,234,229,196,208, 85, +232, 96,115,244, 2, 33,137,103,133,111,213, 65, 33, 93,251,172,117, 74,186,223,147, 94,219, 33, 63,116,226,254,244,139, 10,187, +138,222,239, 96, 55, 81,190,191, 28,190,250,212,208,183, 10,253, 95,124, 13, 94,126, 17,134,223,134,175,124,204,241, 47,189,199, +229, 11,194, 83,131, 97, 50,134, 41, 54,124,137,217,146,101,120,112,137,220,202,112,214, 33,155,228,183,255,177,194,199, 3,245, +225,192,244,112,100,175,206, 21, 47,171, 24,211, 28,192,152, 90,133,205, 70, 72, 55,178,239,223, 6,107, 33,210,126,116,180,185, +105,245, 86,207,250,152, 67,237,146, 87,104,166,158,112,150, 13,180, 32, 99,228,131,155, 3,101,100, 20,164, 38,140, 66,213, 4, +121,139,228, 45,242,133,219,240,233, 29,124,237, 17,114, 12,242,119, 49, 24,143,179, 87, 78,108, 5, 81,221, 79,110,253,236, 58, +167, 87,237, 27,133,202,144,105,154, 45,140,204,211, 52,127,230, 58, 13, 57,148, 22,116,114,177, 85,242,164, 24,223, 97,202, 90, +229, 28,227,230, 16,177, 57,110, 88, 22, 16, 77,219,237,199, 65,221, 5,230, 54,205,200,100,175,152, 70,241,237,180, 0, 82,204, + 99,109, 81,122, 42,167,169,210,155,119, 57, 89,133,190,198,184, 51,198,201,106,190, 71,239,108, 97, 34, 52,199, 9, 26,137,120, +106, 43, 86,108, 3, 37, 41, 83,177, 25,161, 60, 69,177, 50,196, 20,111,190,104, 37,113, 72,137,130,172,228,164, 50, 59,128,150, +151,161,169,194, 23, 38,185,161,220,204,194,157, 82,157,172, 40,145,135,209, 32, 56,226,239,117,155,110,182,250,106, 50,159, 86, +172, 87,154, 35, 30,229,123, 52,207, 80, 47, 33, 22,172, 43,127,122, 1,134, 90,217, 79, 19,157, 21, 54,185, 39,165,124,221, 78, + 53,131,197, 90,231, 93, 99, 21, 36,228,148,221,243, 95, 67, 46, 87, 22,176, 87, 35,141, 54, 16,139,217,114, 46,175, 19,211,248, + 4,179,192, 86, 75,121,227, 19, 57,186,171,228,187,101,223,238,121,231,169,203,238,131, 95,173, 87, 45,206,221,214,160,108, 85, +185,209,247,244,253,142,139,105,226,106,154,152,202,228,116,183,150,146,214,242,215, 87,191,179,198, 24,159, 82,189,240, 22, 13, +202,160,206,113,164, 54, 67,149,108,229, 76,114, 96,205, 4,179,230, 67, 86, 48, 47,211,180,248,243,163,186, 45,181,132, 30, 34, + 45,235,138, 0,218,248, 42, 73,208,212,161, 93,231,133,218, 52,185, 69, 47,231,248,125,149, 58,121, 46, 59,215, 0, 84,113,161, +119,157,107, 13, 34,166,181, 80,103,222, 74,150,192, 87, 58,136, 36,199, 51, 16,192,144,160, 57,181,156, 88, 89, 91, 22,164,117, +210,139,162,213,154, 78, 82,100,137,212, 91,147,122,140, 25,153,233, 85,185, 95,228,206, 24,110,227,169, 37,115,220, 43,240, 69, +149,223, 10, 16, 49, 96, 60,186,122,180,219, 32,217,129, 50, 93, 74, 33,126, 80, 38,212,195, 7, 74,129,114, 9,226, 57,185,146, +178,123,177, 49, 87,130, 6,129,173,214,137, 90, 43,135,201, 15,146, 19,117,161, 84,153,194, 75, 58,115,152,226,124, 16,168,211, +132,158, 39,108,116, 89,182,253, 11, 69, 62,123,234,106,181,187, 9,121,225, 4,189, 26,169,251,145,124, 53,145,165, 48,182,137, + 67,120,114,219,254,219,194,233,178,142, 34,156, 9, 82, 85,226,242, 53,108,130, 59,239, 94,162, 95, 85,242, 89,130,231, 54,200, +243, 27,210,147,138, 93, 76,228,177,176, 25, 11, 99, 8, 52, 90, 70,114,139,222,148,128,151,109, 49,118, 59, 65,122, 33, 63,246, +110,160, 59, 83,244, 70, 66, 78, 19, 92,196,110,247,178,192, 69,129,167, 19,118, 43, 33,155, 61,228,167,192, 13,255, 66,201, 96, +107,112, 35,118, 67,131,119, 76, 57,138,177, 28,126,245, 19, 96,115,166,200,221,140,156, 40, 88, 38,223,233,209, 31, 62,129,231, + 59,159,109, 94, 84,236,219, 71,234,135, 71,170, 76, 62,134,142, 0, 21,222, 44,244,191,247, 30,250,199,222,128,195,155,240,232, +192,240,103,222, 97,184, 47,140,119, 18,245,202, 69,143,174, 19,104,192,155, 80,218, 91, 66,183, 29,242, 92, 7, 55, 60, 97,201, + 46, 39, 24, 10,118, 94,195, 15,236,227, 17, 53, 15,186,105, 62,254, 17, 97,168,222, 1,230,248, 25, 37,132, 17, 94,176, 46,237, +174,133,220, 94,178, 46, 97, 14,130,143, 67,170, 11, 39, 92,121,175, 81,164, 86, 82,205,232,233, 22,254,216, 11,254, 26,252,181, + 39, 72, 45,216,118, 3,247, 51,182,221,195,215,174,176, 55, 71,108,179, 65,108, 32, 93, 14, 62,109, 32,251,154,104,147,225, 94, +239, 54, 68, 5,170,162, 71, 79, 94,180,134,163,148, 58, 91, 28,115,245, 75,168,117, 76, 62,154,140, 67,170,113,133, 67,189,222, +114,213,211, 42, 6, 85, 34,202, 19,107, 44, 31,187,198,165,104,149,112,167,174,153,192, 92,132, 54,177, 32,217,124, 12, 95, 60, + 57,204,140, 94,161,163,178,203,198,137, 25,189, 88,232,100, 42,105,178, 57, 18,182,171,204,154, 4, 77,126,137,203,182,141,249, +252, 61, 52,109, 56,218,216, 21, 92, 78,112, 48,198,193, 24,173, 54, 66, 39, 67,248,212, 75, 60,103, 87, 6, 7, 83,174, 52, 81, + 77,200,237, 54, 88, 97, 79,155,248,169,185,127,170,197, 68, 35,132,114,168,114,196,232, 49,238,102,227,114,132, 75, 81,178, 86, +166,178,116, 90,110,255,108, 81,164,110, 87,115, 81, 86, 9,237,146,206,112,152,169,165,167,205,177,157, 45,242,211, 47,222, 81, +148, 82, 38,183,239,229,206, 99, 65,215,128, 48, 91, 58,234, 34, 11,156,162, 70,115,213,139, 96, 17,100, 66, 89,244, 85,173, 67, + 87,105,132,137, 5, 94, 51,195,195, 68, 87,138,246,197,143,110, 43,118,189,179, 11,236,218,212,246,147,220,246,134, 85,157,170, +133,240,122,217,119,183,180,201, 12,108, 83,162,203,153,162,153,115, 43,236,199, 1,105,226,202,217, 42,108,139, 18,223, 22, 4, +250,218,251,222, 52, 26,196, 5, 43,171,253,125,219,217,183, 66,189,121,196,169, 49,117,233,250, 85,120,139,251,230,153, 3, 86, +154,138, 95,230,132, 57, 23,171,118, 94, 96,148,202, 38, 37, 58,221,206,130,200,105, 28, 40,165,248,179, 92, 11,168,250,125, 84, +166,216,213,199, 94, 62,185, 18,223,125,227,205, 38, 61, 49,141, 35,101,114, 81,172,133,181,114,166, 33,229, 80, 69,206, 56,213, +230,121, 14,165,110, 83,232,206,113,111, 49, 64,153,247, 42, 81,249,172, 7, 76,178,234,216,219,161,226, 74,209, 22,137, 56,167, +179,207,204,248,197,202,182, 88, 30, 48,255, 59,218, 2,235,235,228,221,138,129,110,149,156, 55,164,228, 7,246, 84, 43,227, 56, + 96,157, 7,223,215,241,136,217, 49,126,164, 62, 58, 27,255, 32,187, 98,126, 36, 89, 13, 5,100, 88, 96,170,209,213, 66,166, 50, +181,204,160,216,145,212, 16,205,236,199,194,166,236, 73, 99,134, 83,168,211, 17,249,246, 21,242,229, 19,120,111,132,151, 54,232, +199, 61,118,121, 68,247,137,124,152, 72,161,130,100, 78,253, 89,108, 42,165, 46,108,225,107, 49, 58,141,126, 36,158, 46,149, 71, + 35,189,123,133,124, 51,147, 78, 4, 78, 59,244, 83, 27,242,121,161,150,194,201, 71,133,146,124, 95,105,173, 0, 97, 41,168, 54, +163,113,114, 91, 73, 47,119,176,201,232,217, 72,125, 80,208, 93,242, 67, 82, 4,185, 25,149,107, 50,120, 92,145,179, 2,119,138, + 19, 54, 78, 30, 67,221,185,120,107, 10,185,240,165,161, 7, 71, 24, 38,169,140, 42, 36, 42, 39, 25, 78,179,120,177,112,183, 39, + 61,223, 33,197,105, 7,114,175,131, 27, 25,134,248, 4, 13, 30,179,106, 67,161,166,226,118,207, 78,168,111, 87,186,215,110,208, +253,165,207,195,241, 28, 46, 6,234,127,248, 38,165, 76,112,187, 35, 87, 69, 58, 63,168,164, 84,180,214,153,148,183,153,140,116, + 75,209, 23, 58,120,182,119, 66, 95,173,126,154, 31, 10,236,253,123, 73, 31, 58, 53,112,236,108, 13,113,147,152,211,208,162, 72, +234, 70,159, 44,117, 40,253,105,162, 30, 42,146,234,117, 74, 86,246,238, 55, 50, 61,253, 54,220,184,216, 65,102,242, 12, 72,238, +161,219,193,139,183,224,245, 23,224,159, 63, 66,166,228, 10,248,103, 43,246,170, 97, 39,138,188,237,251, 53, 59, 76,144,139,175, + 60,162,210, 21, 83,172, 83, 56, 53,184,161,112,186,243, 61,252,211, 3,105, 16,236, 32, 14,223, 48,168,154, 72,181,132, 47,220, +174, 81, 31,101,197, 19,104, 71,159,202,146,106,214,148,224, 22,241,157,115, 50,151, 44, 97, 46,237, 83,157,212, 45, 99,205,250, +213,148,218,199,226, 57, 7, 41, 45, 7,110,159, 96, 23,174,134,173,193,137, 86,250, 90,232,173,178,105,221,109, 76, 20,146,170, + 11, 14,183,201,157, 0,219, 16, 27,206, 4, 35,159, 81,203,177, 98, 79, 39,120, 50, 49, 94, 85,142, 67,229, 88,224, 74, 96,180, + 37,139,189, 21,211,163,193, 30,229, 42,176,169, 73,213, 83, 45,219,142,117,150,123, 89,136,192,154, 45,207, 60,101, 77,117, 53, +176, 55,143, 16, 16,225,166, 8,119,181, 50, 33, 84, 81, 58,113,212,113,138,253,249, 36, 30, 34,229,144,150,130, 21,167,185,169, + 36, 84,109, 41, 78, 85,209, 90,231,233,145,138,239,132,107, 49,122, 21,186,228, 23,107,142,152, 81, 85,117,133,124,248,224,137, + 51, 83, 26,146,148, 21,136,170, 17,228,204, 47,253,172,194, 72,195, 34, 54, 94,191,175, 63, 77,212,145,215, 86,127, 64, 74,194, +117,211,219,181, 0,151,181,224,100, 33,136, 6,124, 74,163, 96,152, 39,150,203,184,191,157,133,105, 30,205, 43,170,221,236,245, + 31,135, 8, 55,177, 69,127,211,172,105,242,131,230,179,101,119,222,194,127, 44,144,171, 45,241,115,149,133, 94,106,101, 42,197, + 31,225, 6,146,105, 59,253,190, 99, 76,202,116, 28,194,206,162, 75, 60, 50, 66,210, 24,191,207,150,209, 64,218,154, 83, 30,114, +151, 57,212,202,120,181,103, 26, 71,191, 7,106,197,198, 33,166,193, 29,101, 26, 34, 90, 85, 80,241,221,185, 38,127,111,253, 18, + 77,212, 50, 57,199,190, 70,151, 94,252,147,153, 9,155, 73, 10,149,184,136, 43,127,173,145,191, 84, 2,189, 26,151,130,206,193, +216,177,167,105,241,172,109, 76, 35,243, 88,121,237, 57, 71,150, 74,183,141,161,116,133, 14,154,185,207, 51,140, 98,153,240,203, +106,151,183,142, 90,148, 50,130, 36,180, 78,174,168,239,182, 76,213,152, 38,183, 2,204,222,222, 90, 60, 98, 85, 20,155, 92,241, + 36,145,189,158, 39,131, 50, 33, 86, 73, 41,194, 1,202,196, 97,172, 94,120, 40,228, 18,225,133, 77, 19,148, 18,135, 82, 41,166, +212,108,236, 14,131,167, 21,221, 76,212,175, 94,145,222,216,121,107,122, 41,200, 43, 59,228, 98, 64, 46, 71,186, 99,242, 7, 91, +130,240, 22,192,142,186, 60, 67,115, 23, 33, 1, 25,145,186,160, 37, 90, 19,116,149,133,221,213,132,126,231, 10, 57, 83,244,135, + 21,110,103,228,141, 45,121, 63, 98,151,133,211,203, 17,203, 45,213, 43,124,234,201, 19,164, 54, 9,244,153, 14,189,215,185,215, +103,183, 65,243,136, 13,206,112,145,157, 34,219,132, 29, 98,199,123,172,240,164,132,167,100, 3,117,128,242,158,127,160,115,246, +101,228,105, 70,255,232, 13,182,191,126,201,254, 55, 39, 14, 81,180,157,221, 16,210,203, 61,122,163, 35,221,238,144,187, 91,111, +137, 30, 84,164,207, 1,106,136,209,223,227, 56,140,183,113,201,236, 5,222,129, 60,109,232,255,242,103,137,136, 37,234,127,249, + 38,211,119,174,232, 62,123, 66,255,217,158,124, 20,158,126,247, 10,100,244, 11, 55,246,158, 59,131,126,147, 72,119, 55,232,203, + 61,220,237, 97, 11,118, 89,124, 63,241,120,164, 62, 25,176, 99,133,228,233, 98, 0,150,161,143,145,171, 69, 17, 46, 57,176,161, + 8,118, 5,247,222,232,217,124, 97,199,254,231,159, 80,167, 64,228,138, 63, 43,154, 19,100,245,142, 61,133,176,235,170,169,177, +212,211,224,250,140,229, 30,235, 51,246,209,132,252,247,223,130,243, 17,187,161,216,231,123,184,215,193,243, 59,120,167, 82, 47, + 46,224,252,232,109,180,134,242,177,165,170, 5, 85,197,206,179,155,254,115,245, 64,163,222,176,152, 6,200, 20,203, 98,117,165, +151,172, 58, 45,141,164, 53,109, 34,190, 40,100,218,122, 72, 89, 58,217, 18, 49,158, 35,194,168,161,208,229,122, 28,172, 70,151, +172,226, 23,250,184, 2, 91,101, 93,254, 96, 39,198, 38, 9,155,208, 62,156, 88,229, 84, 10, 39,165,210, 71, 66,216, 76,224,234, + 19,178, 75, 62,225,185,145,144, 27,177,210,216, 5,252,189, 55,108, 50,120,107,194,222, 29,168, 79, 38,134, 67,225,105, 49, 46, +204, 47,243,171,234,255, 84, 96, 23,215,180,138,112, 18, 15,245, 52, 45,250,161,106, 50,243, 52, 52,110, 11,155, 67,170, 36,138, +238,184,238,213,173, 81,173, 64,119, 21,188,139,207,182, 34,220, 87,184, 50, 99,164,250,235, 28, 13,129, 91,148,108,190,100, 85, +132, 73,112, 76,179,249,233,155,227,210, 81, 81,191,228,235,146,227,222,137, 3,107, 54, 97, 71,107,194, 38, 51,119, 36, 76,248, +160,107, 95, 10,105, 26,233,187, 46, 84,248,118, 77,212,217, 4,104,196,165,110,113,224, 78, 97,205,146,153,201, 31,246, 61,145, +134,110,153,187,241,202, 15, 78, 99,249,129,156,116,215, 95, 88,216,185, 18,171,188, 1, 91,220, 24, 51, 78,103, 21, 22,211,183, +194, 73, 96,180,137,132, 50, 74,165,150, 50,143,217,181,202,170, 63,151,235, 13,101,184,186,108, 21,243, 75, 8,149, 83,245, 34, +162,125, 30,108,165,254,207, 81, 80,185,112,145, 69,204, 29,147,156, 34, 19, 86,167, 57,132,172,169,215, 83,140,197, 91,164,146, +198,228, 36,171,159, 7, 19,194,112, 28, 92,128,215, 30,154,176,155,146,242,226,227,207,157,127,254,115, 10,248, 90, 66,179,199, +131, 79,199, 1,155, 70,127,207, 91, 80, 68,220,179,158,114, 24,135,145, 69, 58,140, 71, 58, 58,105, 74, 98, 12,175, 43,171,219, + 92,193, 53, 81, 93,243,237,198, 11, 53, 67,246, 35, 86,206,116, 5,176, 97,149, 4,183, 6,246,155,255, 12, 57,118,100,109, 60, +178,192, 8,108,222,193,164, 32, 90,165,248,185, 5,163,150, 49, 2, 69, 90, 32,125, 69,166,227, 76, 88,210, 90,150,111,222, 76, +217, 5, 7,203,120, 2, 68, 76,218,108,222,221,141, 82,103, 21, 62, 1, 32, 27,195, 83, 97,146,232,204,144, 58,209,245,160, 99, + 65,143, 19,232,145,250,115, 79,208, 63,116, 23,158, 94,193, 89,135, 62,183,193,158,140,164, 99,161,191, 58, 50,168,112,108,187, +205,182,227,250,132,143,125,102, 82,196,135,176,173, 8,179,186,170,248, 28,208, 15,247,240, 53,200, 55, 21,253,244, 9,114,191, + 35,253,240, 14,187, 42,216, 59,149,147,171, 9, 73,194, 73, 32,162,114,245, 67, 32,223, 75,190,183, 22,133,167,174,182,150,109, +116,136, 17,106, 36, 2,210,139,251,122,106,129,190,243,150,166, 4, 98,178, 14,222,161,159, 36,152, 20,126, 87, 15, 63,117, 74, +250,202,185, 71,135, 70,151, 55, 94, 26,185,130, 62,147,145,179,141,163, 73,159, 3, 78, 59, 55,127,111,212, 47,219,247, 15,158, + 15,222,131,157,155, 7, 56, 95, 26,242, 64,216,252,229,215,224,246, 22,142, 21,251,251,239, 51,252,210, 83,242,167,119,228,127, +231, 89,248, 55, 63,207,238,255,250, 22,219,111,126,207, 39, 18, 82,233, 58,255,157,183, 34,116, 55, 18,233,165, 13,188,184, 69, +110, 6,159,255,220,253,239, 60, 41,216,197,132,237,189,186, 50, 53,196,148, 62, 53, 97,186, 95,244,150,108, 86,246, 14,230, 25, +227,251,247, 6,134,119,221,144,222,249, 0, 8,233,196, 81,175,125,246,223, 83, 98, 60, 60, 40,212, 30, 54,209, 41,245, 57,212, +226,142,166,179,113,240, 23,252,133,140,125,241, 20, 94,238,225,214, 41, 60, 29,224,205, 71,240,120,239, 0,154,182,147, 55,139, +156,231,234,221,251,113,114,150,192,137,139, 41,204, 12,142,145,112, 87, 66, 45, 63, 57, 39,160, 61,116,205,102,152,231, 85, 87, +179,246, 48, 91,217, 36, 69,112, 73,105, 25,218, 50, 71,107,106,203,176, 15,241,171,204,193, 28, 1, 80, 10, 65,237,166,105,112, + 48,138, 46, 0,155, 77,130,157, 85,122, 42, 39,165,112,130,171,221, 19,226, 36,189,118,153,223,202,200,115, 25,158, 81,228, 86, +176, 88,123,223,254, 48, 26,246,208,224,205, 1,190, 53, 80, 62, 24,184, 58, 20, 30, 2, 79,170, 3, 87, 46,205, 56,196, 20,126, +108,207, 89, 82,182, 34, 76,193,165, 79,209, 29, 78,215,206,167,166, 16,111,231,154,204, 59,230, 54, 50, 47, 1, 58, 73, 22,218, + 11,149, 25, 12, 83,112,209,220,137,192, 93, 17,246, 38,179,232,109,161, 44, 74,232,150,150,166,129,152, 18,106,173,212, 44, 36, +171,228,232,146, 81, 91, 49,213,101,209, 14,181, 38,167, 77, 18, 67,200, 38,225, 24,200, 41,209,137, 50, 97,241,191,217,181, 0, + 46, 2, 62, 67,235, 68,213,139,207,162,182,226,187, 47, 9,154,105,165, 22,175,181, 46, 17, 50,171, 81,177,201,239, 20,204,210, +104,106,139,162,254, 90,216, 78,243,115,179,172, 33,179, 38, 36,137,163,130,131,148, 39, 34,140,165, 46, 23,250, 39,114,217,215, +223, 91, 90,134,192,234,207, 53, 71,189, 6,136, 72,107,197,212,139,154,186, 74,224,211,176,158,205,162,184,249,103, 12, 17,109, +151,168, 99, 13,101,241,114,169,207,150,182, 6,163,176,133, 89,128,122, 46,130, 85,135,164,213,185,120, 82,180,235,145,174,167, +212, 66,210, 76, 74, 46,128,149,118, 17,168,227,131,203,225,128, 77, 83, 36,254, 69,113,223,118,238, 34,100,139,209, 80,169, 1, +123, 41, 94, 37,117,234, 30,186,214,105,119, 73,219, 86,197,243,150,227,135,112, 16,240,212,244,114, 94, 17,181,238, 91, 29, 9, +219,120,186,106, 62,146,101,221,109,135,247,212,253,196,238,159,108,255,158, 21, 85, 46,107, 27,217,217, 50,234,176, 16, 64, 37, +165, 76, 19,101,216, 35,221, 54,118,105,163,239,213, 52,207, 98, 0,207,151, 14, 73,159,116, 80, 70,176,137, 46, 57, 40,191,148, + 33, 0, 12, 54,231, 82, 79,213,149,174,197,188, 97, 45, 53,188,221,201, 75,210, 99,245, 81, 99, 46, 21, 61,140,176,203,216,135, +123,248,104,128,151,119,240,141, 61,114,239, 4,125,118, 4, 70,186,177,208, 29, 10,189, 44, 34,157, 57,189, 96,101, 29, 97,242, +110,103,253,137,173, 97,169, 27, 90, 65, 96,194,157,119,246,200,111,248, 30, 92,158,221, 32,207,246,228,207,237, 96, 52,228,163, + 61, 93,173,206, 11, 6,236, 10,100, 43,164,103, 59,127,253,223, 45,243, 2, 95,182,138,188,164,158, 66,119,238,193, 0,114, 51, + 33,183,179, 99,182, 0,246, 96,147,249,133,165,119, 96,247,216, 97,231,207,103,248,205, 11,120,255, 67,202, 55,247, 88, 54,202, + 16, 98,164, 17,234,247, 39, 84, 38,236,108, 64,110,119,200,235, 59,248,236,206, 47,160,168,224,108,244,184, 79, 94,234,144,239, + 87,228,201, 4, 95, 55,242,127,246, 2,124,241, 25, 56, 31,176,255,247,125, 14,127,225, 29,236,126, 70,191,176,133, 63,248, 18, + 92, 12,140,255,231, 3,135,148,244, 48,142,142,144, 61, 21,232, 79, 18,122,127,135,126,106, 7,119, 59, 56,203,161, 10,244,177, +187, 61, 29,177,125, 13, 48,132, 5,170,209, 72, 49, 47, 86,133,148,205, 21,170,157, 98,147,177,153,194,223,186,119, 21,117,218, + 40,218,139, 23, 69,189,248,244,161,207, 72,151, 80, 50,169,116,158,180,119, 67, 60,119, 62,197,129, 90, 28, 17, 41,150,144,103, +182,240,194, 6,123,101, 11,247, 54,200, 78,252,178,254,214, 83,120,116,128,174, 66,111,212, 41,194,129,178, 32, 83,197,246,174, +106, 55, 4,174, 6,159,202, 84,111,209,172, 84, 10,149,105,117,101, 91,169,254, 92,233,178, 63,151, 25,146,210, 84,110, 97, 95, +139,145,186, 7,100,248,243,137,185,247,190, 68,102, 58,218,226, 87,151,231,181, 29,120,173,123,203,210,164,169, 65,229, 83, 99, +107,213, 49,191,165,114,106,198, 46, 59, 96, 68, 52,185,149,111,151,144,251, 29,242, 74,134, 79,101,184,105,193,123,141, 31,234, + 80,225,253,130,253,214,128,125,123,160, 60, 30,185,220, 23, 30,152,241,200,101, 15,222,149,135, 61,173, 90,195, 89,235,162, 82, + 14,193,207, 80,195, 42, 23,254, 97, 11,220,177,152,143,176,107, 16,189, 90, 22,252,250,154, 26,173,101,168, 11, 59,243, 61,186, + 69,248, 77,193,139,111, 5, 54, 42,156, 90, 98, 84, 95, 3, 24, 45,252, 69, 81,173,140,101, 90, 40,154, 40, 69,234,188,211,157, + 68,230,102,166, 9,227, 82, 28,140,170, 50,251,157,139,234,188,251,183, 88,137,102,220, 14,151, 2, 57, 58, 89,120,223,109,105, +167, 91,138, 96, 13, 40, 75,155, 26,116,113,177,215,182,150,156,247,226,178,140,185,227, 18,171,149,165,163,255, 68, 94,186,173, + 98, 91, 85,210, 2, 35, 90, 69, 66,219,130,123,156, 47,233, 36,206,112,183,184,192, 75,208, 1, 69, 18,147,249, 51,107,115,144, +205,226,180, 90, 3, 90,180, 17,215,104,201,127,139,219,164, 89,183, 85, 21,117, 91, 87, 56, 11,162,128,137,104,111,230,100,205, + 40,120, 99,223,239,171,204, 20, 32, 52,115,125,215,204,221,158,131, 16,102, 65,120,139,220, 85, 73,241,247,253, 65,209,200,155, +149,216,151, 23,195,207, 94, 85, 82,246,188, 6, 11,253, 67,173,149, 50,140,254, 53,115,166, 78, 83, 76, 75,234, 42, 44,206,200, + 37, 46,117, 68, 80,243,110, 54,169, 99, 23,243, 60, 54,243, 11,221,218, 14,124,101, 79,149, 85,133,104, 44, 17,138, 18, 35,245, +198,166,109,221,118, 35, 25,249, 7,210, 47,174,142,240,255, 6,251, 90,114,176,125,103, 40,194, 53,164, 77, 64,108, 28, 2,144, +146, 98,184,117,195,198,176,187,229,157,255, 18,101,136, 49,142,181,156, 69,183,190,168, 91, 21,132, 9, 43,230,223, 59, 65,169, + 66, 77,254,230, 54,226,218,241, 8, 23, 19,212, 28,168, 73,129, 13, 5,180,167,152,143,210, 71,107, 49,140, 2,163,239, 60,235, +207, 63, 70,255,232,125,120, 33,195,247, 38,228,217, 13, 92,140,232,105, 97, 51, 78,140,147, 19,182,138,254, 78,214, 54, 79, 13, + 74,182,140, 68,155, 99, 96,148,101, 28,106, 49,210,186,245,214, 21,178, 17,210, 79, 10,114,179,131,151,183,228,131,191,150, 42, + 19,245, 48,145,206,139,191,127,247, 50,122, 47,183, 40, 35,183,145,245,130,220, 76,110, 97,219, 23,175,254, 46,194,163,156,197, +133, 88, 27, 89, 90, 54, 49,176, 27, 94,249,109,222,133, 47,108,225,231,207,169,239,236, 49,171,116,251,194,174, 86,183,180,103, +153, 81, 78,114, 55, 68, 37, 99,208,134,212,145,168, 54, 24, 92, 21,167,167,221, 21,120,166, 67,126,126, 32,253,225, 59,232,191, +253, 18,156, 31,224,131,115,246,127,238,109,134,155, 5,238,119,116,119, 13,249,197,119, 25,254,214, 19, 46, 63,184, 32,109, 11, +194, 68,234,220,171,156, 59, 37,221,234, 72, 47,237,224,197, 30,185,157, 32,157,225, 6,166, 10, 15, 39,236,131,129,122,238,241, +105, 18, 99,123,201,130,156,168,163,151, 53, 98,116,147,179,252, 91,214,164,181, 92, 0,109,234,246, 60, 79,128,164, 79, 72,159, +145, 41,163,251, 30, 94, 61,133, 63,246, 34,188,187, 71,254,206,199,112, 3, 76,139,219, 92,110,119,200,167,122,120,105, 3,253, + 14,145,201,129, 67, 71,224,235, 23,240,230, 1, 58, 67,212, 99,104,209, 58,167,251, 89, 68,131, 89, 54, 56, 19,108, 76, 48, 77, +126, 48, 23, 11, 91,153,215, 47, 85,108, 6, 19, 73, 89, 2,132,214, 86, 47, 13, 17,150, 7, 82, 44,161, 29, 50, 45, 98,170,150, +161, 93,139,135,228,156,152,115,251,109,171, 60, 25, 61, 0,166,206, 17,155, 66, 63,119, 97,174, 84,223,137,145,205,232,171,179, + 3, 54, 93,116,227, 57, 33, 93, 70,111, 37,127, 61,190,160,240, 98,242,105,205,104,208, 69,139,189, 7,222,169,216,175, 12,216, + 55, 14,148, 71, 3, 87, 67,225, 67,131,119,128, 39,109, 63, 85,151,226,184,160, 51, 57,172,161,146, 83, 76, 26,146,194,161,250, +101,222,197, 78,250, 72,140, 22,211, 10,230, 47,173,107,111,140,109,157,247,182, 38,194, 33, 10, 6,204,216, 97,215,252,236, 41, +254,220, 86, 92, 59,128,250, 62,127,170, 54,251,151, 83, 8,122, 45, 4,113,109,171,146,107, 33, 39, 79,252,234,197,129, 53, 14, +147,177,136,183, 14,122,158,180,203,221,226,156, 93, 64, 21,235,168,227, 74, 93,159,210, 43, 38, 72,200,186, 66, 48, 89, 98,202, +210,194, 78,174, 57,155,214,209,168,179,170,126,161,211,124,210,174,167, 43, 40, 77,155,114,204, 65, 72,107,117,252,108,199, 18, +122, 77,104, 86,166,226, 42,114,157,131,116, 52,222,146, 37, 76, 71, 87,169,159,203, 42,168,217,209,100,165,196, 95, 46,255,164, + 66, 78, 77,156, 39, 51, 32,166,173,152,234, 42, 31, 65, 85,231,157,185, 89, 89,105,171,124,215,158,115,246, 53, 76, 78, 46,112, + 4,186,156, 33,103,198,105,140, 70,215, 39, 45,174, 78,111,154, 4,185,246, 90,182, 76,248, 50, 28, 61,199, 93,148,113,156, 24, +142,199, 57, 82,188,148,137, 58, 77,115,218,165, 77,211, 53, 4,241,172,141,227, 90, 12,170, 63,208, 27,117, 95,179,243,129,151, +168, 71, 89,237, 97, 18,130, 78,227, 42,169, 42,198, 42, 43,187, 86, 90,193,253,155,114,147,153,145, 28,197,195, 60,138, 55, 71, +178, 18, 59,164,248,160,165,213,135, 69,172, 85,212, 45,102, 85, 65,210, 66, 60, 42, 5,134, 3,104, 70,180,199,202, 56,239,210, +125,102,228,227,114,145,142,206, 38,170,133,130, 49, 9, 41, 11,221, 84, 93, 4,167, 78, 64, 61, 31,220, 34,117, 12, 28,212,105, + 32, 79, 83,112,187,173,122, 14,251,100,133, 50, 85, 63,172, 81,172,102,100, 28,177,175, 60, 65,126,223, 61,120, 90,145,143, 38, +244,185, 45, 28, 70,186,195, 64,127, 89, 24, 5, 6,177,136,226, 92,176,139,141,192, 85,108,141,218,181,107,174, 16,137,240,140, +243, 44,164,253,196,205,111, 95,193,153,146,126,228,204,197, 96,111,156,144,206, 18,242,222,145,250, 80,169, 54, 33,157,160,207, +119,232, 46,218,243,187,218,192, 0,200, 29,193,158, 26, 54, 86,232,139,199,119, 62, 42,216, 78,209, 19,129, 59,217,125,105,147, + 57,243,125,243, 49,112, 6, 39, 27,248,148,193,239, 59,129, 95,157,144, 42,236,222,133, 77, 41, 62,182,238,133,244,122, 66,118, +134,108, 99, 15,170, 5, 30, 76, 46,238,186,211,195,126,116, 37,250, 69,241, 66,227, 59, 35,250,165, 83,244,207,188, 22,240,155, +129,225, 79,125,151, 3, 19,251,103, 51,106,198,241, 55, 47,201,191,116, 69, 46, 35,249,212, 11,210, 82,220, 55,218,137,144,182, +153,244,236, 6,121,165,135,103,179, 11,200,234, 9,240,216,223,243,125,133, 98,200, 86,208,211,212,160,176, 62,177, 72, 26, 59, +113,153,217,186,218, 39,183,250,152,239,220, 37,105,116,253,241,217, 74,206,120,214,146,225,216, 35,187,130,188, 54,194,143,157, +195,115,223,133,116,132,159, 25,131,207, 16,211,142,231,182,112,231, 5,247,122, 93, 61,134,203, 91,238, 52,248,245,167,240,207, +158, 98,251, 35,232,136, 93, 14,212, 67,137, 46,186,186, 54, 39, 69,199, 99,134,102, 79, 17,145,179,228, 35,105, 41,200,224,221, +118,138,176,115,139, 92,251,166, 82, 78,234, 97, 38,109, 45,169,107,113, 83, 84,151, 57, 78,101, 7, 24, 5, 80, 38,102,239, 61, +194,253, 62,113,251,191,120, 1,123,103,224,251,255,227,135, 92,198,100,201, 98,237,223,114,197,251,208, 55,228,166,137,233,179, + 79, 55,250, 30,217,101,244, 94, 15, 95,204,240,133, 4,207, 69,202,161,212,224,135, 86,159, 20,125,187, 96,255,244,136,125,109, +207,244,240,200,213, 88,120, 32,240,145, 9, 31, 1, 23, 53, 34,139,195,173,179, 19,137, 61,180,255, 74, 35, 11, 11, 62,205,222, +123, 97, 34,197,142,186,178, 9, 5,124, 11,159,146, 85, 67,226,137,141,203, 69,213,180, 72,109,236,123,136, 21,229, 54, 0, 75, + 67,216, 82,197,218, 42,194,245, 3,110, 91, 21,246, 8, 99,117, 27, 83, 82,165, 79, 57, 40,130, 53,136,143,144,172, 9,223,210, +194, 59,111,209,169,159, 24, 57,167,182,155,101,161,119,206, 58, 8, 51,142,102, 28,235,132, 20,167,203,169,164,121,181,103,171, +150, 76,126, 32,198,117,233,112,203, 44,238,189,238, 53,215, 8,173, 17,179,107, 87,122, 3,149,201, 44, 36,180, 31,184,208, 63, +121, 39,100, 81,247,113, 87,155,119,246,142, 1,150,101,154, 18,255, 62,175,130,115,218,123, 97, 13, 5,187, 66,220,182,213, 68, + 19, 29,118,177,159,174,226,154,153,180,122, 77,231, 46, 93, 3,115, 19,159,247,246,171,173,247,245,170, 74,146,206, 99,189, 53, +251,164, 47,116, 38, 41,231,160, 37, 70,212,238, 10,197, 46,230, 63,199, 84, 74, 4,184,120, 16,203, 20, 83, 20, 19,160, 76,140, +227, 24, 25,240,190,139,182,208,180,216, 60,145, 89,154, 62,105,200, 91, 21,178, 56, 46, 42,118, 72,254,224,122, 85, 36,116,129, + 1,107,223, 56,233,122, 81,226,187, 52,139, 93, 55,186, 84, 91,179, 9, 49,142,202, 82, 87,190, 62,245,175, 19,134,156, 85,252, +234,178,151,107,187,140,217, 98,186, 66, 8,154, 53,177, 74,162,180, 89, 98,163,182, 80,145,209,117,185,218,157, 69,252, 96,137, +241, 96, 19,165, 20,146, 9, 88, 70, 74,241, 3, 81,179, 79, 9,178, 3,186, 46, 38,184, 60,194, 16,120, 87, 34, 55,187,148, 74, +205, 62,166, 76,211,132,100, 65, 45,251, 79,168, 17,124, 79,124, 8, 78, 18,242,120,132,183, 14,240,198, 41,236, 7,228,208, 35, +183, 55,164,171,194,118,184,100, 28, 35,121, 41, 86, 12,195, 39,196,162,182,210,117, 92, 11,193, 41, 94,120,136,194,161, 24, 23, + 42,116,151, 19,187,111, 92,162,183, 19,242,185, 27,112, 43, 47, 36,190,206, 17,169,220, 84,116,167,126, 2, 25,126, 73, 39,247, +255,114, 20,236,162, 80,175,138,135,169,236,131,154,181, 55,120, 65,225,182,194,141,222,253,235,143, 65,110, 63,129,211,201,119, + 17, 93,129,159, 56, 67,198,129,244,124,239,135,224,113,164,252,220, 30,123,234, 35,254,250,107, 3,233,142,192,191,183,131, 91, + 27,151,241,183, 10,169,138, 91,231, 30, 86,248,229, 9,121,189, 71,255,252, 15,121,145,182, 63, 50,253,119,223,167,158, 15,232, +179, 14, 34, 58, 28, 11,114, 89, 56, 21, 33,159,248,129, 89,139,239,238,169,130, 72, 66,251,140,222,222,192,253, 62,148,252,119, +160, 30,177, 97,242, 11, 29, 67,238, 37,100,215,147,164, 58,154,182, 4,152, 72,213,209,173, 57, 4, 90,157,193, 86,231,100, 36, +114,236, 78, 34,115,211, 16,100, 76,112,165,240, 76, 65,126,252, 17,188,190,131,103,159,135,221,179,144, 94,131, 87,110,194, 75, +226, 43, 31, 20,210,109,232,182,192,235,192, 57,116,191, 0,242,219,240,181, 75,236, 23, 31, 98, 79, 15, 14,154,153, 70, 31,167, + 31, 29, 79, 60, 8, 30, 26, 83,150,241, 56, 21, 78,122,216,245,161,141,184,153,224, 10,244, 98,241, 13,231,100,243, 7,202,204, +199,240,141, 30,183,160, 58, 27,167,223,230, 56,213, 28,155,130,174, 50,143,170, 37, 40,182,218, 65,253,198,145,253, 47, 94, 32, + 98,108,179, 69, 30,144, 79,153, 54,209,145,247,169,229, 96,119,190,150, 56,235,144, 91, 61, 60, 47,240,147, 25, 94, 79,240,140, + 11,131,168,145, 59, 80,213, 89, 2,239, 21,248,133, 9,251,197, 11,166,247,143, 92,150,145,135, 10, 31, 36,225,178,192, 57,112, + 48,135, 52,109,114, 98,241,228, 64,103, 70,149, 58,139,180, 90,163,160,225, 5, 79, 49,145,155, 16,182, 73,185, 97,198,121,129, + 99,156,109,218, 46,238,192,128, 74,220, 96, 75, 40,211, 50, 46, 54, 17,174,226, 24,220, 90,116,221, 24,135,213,110, 55,137,178, +177, 58,167,107, 77, 85, 40,181,210, 25,244,169, 35,145, 16,117,239,191, 52, 43,214, 60, 74,110,103,175,206,158,118, 93, 34,133, + 98, 77,233, 14, 13,247,205,123, 87,111,230,103,216,222, 42,135,113,164,175,149,148, 59,191,104,155, 66,190,214,200,247, 94,243, + 69,150,139,176,196,101,154,227, 83, 82,100,249,243,218, 32, 52,178,104, 50,218,103, 41, 53,129,218, 15,156,225, 92,211,112,180, + 75, 57,171, 99,145,215,145,174, 26, 49,188,104,186,126,161,207,220,249, 69,155,213, 46,245,209,150, 48,157, 6, 65, 75,226, 2, +214,164,201, 95, 75,241,187,166,214,128, 77, 69,154,226,188,158,136,117, 64,109,130,230, 90,103, 98, 65,109, 43, 4, 3, 77, 77, +189, 31, 64,169,107, 97, 43, 14, 60, 86,105,160, 30,157,253,242, 57,103, 95,103, 69,242, 98,181,234, 15,118,131, 36,197,207, 48, +103,167,183,132,182, 85,174,187,243,175,116,145, 7, 70, 68,107,214,121,100, 83,231, 11,189, 23,101,163,158,122, 83,130,152, 51, + 43,220,237, 19,113,115, 49, 70,159, 13,242,178,140, 71, 90,153,223,242,179,197,156,147,156, 98,245,208,198, 5, 18, 33, 5,109, + 7, 65, 41,136, 26, 41,118, 42,106,139, 26,114, 78,251, 74, 14,151,241,113,186,147,165, 44,128,194, 58, 1, 92, 65,248,214,117, + 93,177,213, 58, 51, 35, 85,253, 82,150, 90, 24, 74, 97, 42,198, 85, 17, 46,139, 50,212, 26,249,238, 54,103, 24, 23,188,130,172, + 5, 76, 43,185, 22, 82,246,194,101, 38,200,180, 56,205,155,201,105, 89,191,113,142, 60,211,193,231,110, 34,191,252, 8, 57,235, +144,155, 29,221,126,195,174, 28, 40, 89, 60,252,195, 66,184,220,198, 99,178, 90, 51,217, 50,106, 42,109,236,212, 64, 16, 49,149, +212, 4,250,232,136,254,198, 37,249, 76,209, 23, 78,188,114,188,179,245,255,236,131, 83,127, 47,185, 56, 78,162,109,153, 12,158, +184, 40,205,198,138,125, 20,194,177, 27, 17, 32,241,116,130,115,139,181, 66,124,240,158, 52,139,230,165,171, 53, 15, 6, 83,165, +190, 85,177,243, 2,159,205, 78,178,217, 28,224,188, 96,239, 87,100,111,212,103, 50,105,112,224, 11,131,192,125,239,130,165, 86, +172, 40,156, 11,242, 76,143,254,231,175,248, 7,230, 98,162,254,215,239, 97, 95,185, 32,255, 27,167,200, 55,143,216,187, 3,185, + 51,250, 36,244,183, 28, 96, 99,183, 4,125, 28, 32,150, 62,161,154, 72, 93,143,188,188,113, 81,222,230, 6,200, 45,168,223,241, +125,236,211, 40, 92, 38,127, 16,109, 12,133,122, 23, 98, 80,151, 21, 35,103,217,167, 11,237, 56,186, 12, 43,154,198, 85,217, 59, + 71, 94, 70,129, 50,192,231, 31,192, 31,184, 13, 47,252,105,232,254, 45,224,121,207,108,151, 46, 88,232, 65,228,171, 71,144, 3, +212,115,159,111,151,103,225,240,119,177,175,125,140,253,147,131,179,211,111,185, 19,129,171, 52, 23,118, 58, 86,210, 80, 29,130, + 17,248,210,166, 93,188,186, 18, 54,135,202,217,101,229,244, 78,135,158,184, 66, 87,198,176,128,154,204,147, 6, 49,135, 96, 88, +117,139, 25,230,132, 71,196,150,223,127, 21,201, 75,195, 22, 71,167, 94, 42,140,201,184,184, 26,185,250, 43, 31,120, 80,207,198, +216, 82,201,117,233,210,211, 54, 35, 39, 49, 5, 49, 69, 78, 50,242,106, 7, 95, 20,248,172,192,203,138,156,158, 65,218,250, 37, + 94, 47,161,142,238, 14,120, 48,193, 47,143,216, 63,186,160,188,189,231,184, 31,120,164,240,113, 39, 60,173,254, 18,141,209,193, +245, 41, 99,125,239,170,226,232, 70, 59,170, 79, 26,155,247, 56,246,235, 45,206,115, 11,140,234,191,191,171, 93,156, 5,113, 43, + 25,143, 45,128, 49, 22,135,102,195,123,198,218, 79, 67, 16,103,230, 22, 91, 68,231,177,243,227,226, 86,216, 83,140, 46, 41,163, +233, 34,100,138,127,250, 56,124,173, 10,135,201, 41,233, 83,224, 98, 27,125,111, 18, 97, 50,119,156, 44,216,209,153,160, 30,124, +124,185, 70,101,211,101,250, 76, 49,153,181, 34,237, 76,174, 86,153,226,159, 84,151,203,166, 52,113,240, 58, 88,132,101,154,193, + 58,109, 79,150,181,131,205,222,121,167,233, 89,114,166, 6, 53, 76,127,162,215,246,236,242,131, 46,179,153,125,146,219,159,181, + 31,156,225,155,224,175,197,234,252,159, 0,147, 70,213,134,169,213, 0, 0, 32, 0, 73, 68, 65, 84,219,243,216, 94,230,232,156, +229,117, 81, 34,189, 45, 37, 71,169,182,163,186,169,145, 87, 29, 58,161,189,160,121,193,215,197,155,217,181, 21,115,173,205, 29, +226,186,136, 38,244,158,181, 91,179, 15, 62,220, 9,145,116,216, 88, 46, 42,194, 38,103,106,238, 56, 76, 19,101,127, 21, 94,247, +186,160, 17, 26, 44,103, 70,168,235, 98, 9,211,104, 64, 98, 37, 33,171,220,149,156,212, 33, 48,126, 57,250,222,162,235, 28,126, +239, 31, 88, 91,184,239,114,253, 47, 55,193, 1,107, 5,109,187,212, 91,118,114, 68,166,170,168,219,227,176, 89, 37, 43,241, 48, +172,195,219,136,110, 61,215,226,187, 48,117,170,211,252, 1, 66,230,136,171, 42,110, 87,107,244,187,166,184,165, 86,106, 25, 16, +237,253,227,159, 82, 68,109, 78, 48, 77,232,102,231,220,209, 38,224,195, 56, 86,115, 6,116,129, 94, 42, 53,169, 11, 22, 98,196, +227, 85,177,131, 98,199,234,232, 83,195,133, 15,218,210,214,170,127,218,228, 52,193,105,194,246,193,227,254,229,167,200,191,122, + 7, 62,127,130,124,101, 66,238, 22,228, 80,216, 49, 81, 47, 29,242, 81,164, 37,131,213,107, 84, 62, 20,234,180, 8, 75, 52, 38, +224, 98,254,193, 98, 21, 0, 1,130,188,179,103,251,255, 64,254,145,138,222,223, 64,206,200,105, 12,244, 6,115, 92,233,189, 4, + 27, 23, 78,241,113,136,128,202,228, 2,200, 27,234,218,131, 59,138, 22,151,194,219,183, 71,228, 94,204,181,178,250,133,124,225, +151, 34,125,137,156,242, 9,180, 80,127,241, 10,121,148,144,151, 51,114, 38,212,201, 24, 62,172,164,141, 32, 54,192,207, 61, 65, +106,135,220,223,248,248, 59, 11,156, 40,242,108,143,252,161, 14,249,201, 59,112,214,123, 58,220,111, 60, 69,191, 62,160,255,238, + 61,236,203, 25,185,115,197,201,223, 59,199,198,130,126,170, 67, 94,223,192,171, 9,123,175, 80, 59,245, 58,110,147,157, 82,119, +127, 7, 47,103,184,221, 65,126, 45,218,218,163,119,233, 79,221,162,103,143,152,215, 47,162, 32, 39,177,227,109,227,244, 11,131, +239, 71, 20,236, 16, 64,147,123, 61,220,203,112,191,131,103, 50, 60,179,129,179, 11,184, 11,188,242, 71,224,230,159, 3,121, 41, + 14, 35, 69, 2, 40,106,172, 96,216,186,195,108,239,119,230,240, 45,184,250,111,224, 43,223,130,191,123, 3,121,207,224, 86, 20, +158,210,193,198, 47, 92,219, 86,247,224, 95, 78,116, 67,101, 26, 3, 90, 34,194,216, 30, 53, 19,198,201,168, 79, 99,196,218,132, +129,173, 74, 28,205, 63,224, 18, 2, 86,107,201, 26,159, 56, 72, 87, 49,202,243,129, 30, 0,163,126,170,148, 99,245,120,119, 51, +172,103,129, 13,149,184,244,118, 29,122,218, 33,157, 11, 6,229,134,194, 27, 10, 63, 90,225,211,138,220, 62,133,254, 14,216, 45, + 40, 91,183, 23,118, 31,131,156, 99, 15, 43,252,194,128,253,131, 75,234,119,174, 24, 14, 3,231, 98,124,156,133, 39,184,244,162, + 70, 55,147, 82, 34,145, 24,147,131,166,106,241,255, 49, 5,204, 42,169, 81,138, 70, 81, 94, 87, 23,137,132,146, 60,176,201, 6, + 99, 21, 87,234,139,113, 10, 92,218,178, 59,157,130,209,191,140,225,101,161,101, 70,130,155, 2, 67,169, 12,101,138,125,185,175, + 47, 83,114, 16, 22, 34,228, 16, 3,154,248,104,189, 72,165,168,139,245, 26, 60,101,136, 8,205,150,206,134, 46, 23,185,172,246, +199,204, 96,153, 6,178, 90,198,204,178, 18,167, 21, 26, 94,215, 71,225, 89,252,220,172,113,190, 90,112,171,173, 69, 89,207,231, + 78,203,244, 88,160, 50, 33, 77, 91,130, 71, 90,228,174, 45,194, 48,239, 30,211, 53,122,220,245,224, 89, 89,208,200, 43,104,143, +173, 26,198,182,178,224,154, 59,106, 65,202,216, 74,104, 87,131, 23, 48,179, 81,218, 20, 64,150, 11, 93,147,219,192, 26,114,213, + 77, 3, 41,138,159,152,254, 94, 83,175,199,253,210, 22,247,171, 95,100,206, 82,151,181,189,122,121,110, 26,174, 28,187, 94,185, + 52, 16,205,172,197,104,147, 24, 77,216, 56, 56,132,172,148,120, 31, 63, 25,128,187, 48,219,219,152,189, 70, 6,132,181, 98, 39, +214, 1,104, 34,167, 80, 26, 54, 79,122,206,201, 89,183, 86,188,203,142, 28,227, 6,167,111, 54, 54,154,146,180, 77,156,117, 5, + 21,142, 56, 57,135, 22, 52,128,194,194,149, 95,239,240,172,182,177,150,205, 74,195, 20, 44,232,218, 80,123, 44, 94,238, 22,205, +218,144,126,181, 86, 23,195,232,226,221, 53, 83,204, 70,175,108,251, 46,194,232,189,197, 80,138, 31,218,147, 43, 35,154, 69, 35, +169,144, 10, 76, 84,127,248,114,199,200, 68,157,196,163, 91,101, 17, 15,149,234, 85,254,134,234, 36,188, 36,238, 5,158,189, 24, +201, 91, 26,137, 95,228,195, 43,236, 31, 22,228, 95,123, 6,249,124, 69,127,163,192,179,133, 42,198, 73,189, 66,174,202,156,226, +116, 40, 62, 13,152,234,242,192,174,247, 67, 83, 89,141,252,108, 53,162, 7,158, 4, 30,243,254,247, 92, 48,216,253, 46,224,150, +231,243,202,253,236, 63,188, 6, 5,110,140, 11,253,227,137,250,212,187, 72,233, 4,189,149, 32, 11,178, 83,244, 52, 56,233,147, +186,244,255,129,193,157,120, 17, 46,195, 51,125,244,139,222,142, 21,158, 23,236,215, 39,236,235, 35,122,123,139, 60,231,201, 40, +195,165, 79, 59, 78,223, 26,217, 94, 8,246,156, 33, 87, 6,255,124, 66,222, 29,208, 55, 78,144,207,236,224,133,157,139,239,206, + 71,120,114,240,116,184, 63,255, 60,156, 10, 98,133,252,147, 91,244,133, 51,236,241,136,156, 41,220, 21,236,124, 96,250,222, 17, +206,139,207,137,239,246, 72,233,225,197, 14, 94, 76, 72,247, 50,112, 31,236, 55,176,195,209,131, 98,246,147, 95,108, 55, 64,246, + 41,172, 13,130,140,234,209, 96, 59,117,144,203, 11, 9, 94, 2,121,190, 67,238,168, 71,217,157, 37,231, 50,119, 29,108, 59, 36, +159,123, 64,204,201,223,132,252, 67, 96, 7,252,155,156,198,144,112,189, 59, 92,119, 60, 27,255,185,116, 15,246, 25,236, 70, 15, +191,255, 33,236,207,145,247, 11,242,254, 1,222, 29,176,144,114,219, 20,123,201, 65,177, 81,200, 17,220,225, 68, 59,239,226, 40, +201, 57, 12, 71,247,111,201,109,215, 66, 72, 17, 56,138,171,199,219, 65, 81, 2, 19, 55,185,223,203,142,129, 2,157,220,179, 63, + 35, 86,187,198,202,117,103, 12, 83, 37,111, 42,233,106,162, 55, 9, 33,159,139, 8,165,203,200, 89,143,222,200,200,221, 14, 94, +168,240, 70, 69, 62, 83, 93, 63,176,187, 7,250, 50,216, 11,174,199,168,151,160, 79, 97,251,109,216,127,136,253,218, 8,255,251, +129,250, 91, 79, 25, 46,143, 60, 81,120,148,224, 41,202,165,197,206, 92,124,245,102,125,162,144, 24,131, 6, 88,235, 98, 11,173, +225,199,238, 90,160, 71,235,192,102, 11,149,119,229, 86, 23, 36, 74,141,189,120,138, 67, 63, 71,215,213,198,224,211, 42,199,187, + 1,119, 8,251,108,173,149,169, 86, 74, 83,177,171, 50,168,114,133, 43,220,219, 4, 51,209,130, 95,252, 60, 57, 11, 86,198, 85, +236,171, 75,228, 82, 28,195,177,210,226, 74, 91, 90,187,239, 83,151,152,207, 54,181,107,151, 89, 35,200,217, 28, 44,162,115,126, +117, 70,217,197,200,119,140,179,217, 21,252, 49,250,173, 17,101,208,162,117, 87,163,110,107,251,234, 21, 77,206, 47, 70,153,109, +192,173,246,107, 54, 64, 51, 89,165,170,203,130, 9,151,117,244,248, 66,140, 55, 18, 41,186,254,250,137, 26, 83, 35,164,234, 90, +108,227,156, 75, 34,171, 8, 95,153, 47,230, 44, 74,151,148, 28,107,218, 98,117,190,115,154,160,173,113,248, 87,154,181,184,124, +101,101, 17,188, 62, 89,208, 54, 94,215, 8,253,194,174, 79,176,195,182,214,146,229,148,235,174, 16,107,247,104,236,162,199, 82, +152,198, 1,155,202,220,184, 54,123,159, 3,215, 22,225,223,124,130,212, 58,175,162,175,197,165,167, 72,226,203,186,228, 9,103, +241,127,145,196, 51,151,211,156, 90, 35,159, 24,191,200,146,161, 28,168, 88,105,114,248,168, 74, 93,108,192,188,155,202, 45,155, +121,189, 7,170,126,216,183,230,123, 86,165, 54,250, 25,209, 93, 7, 66,176,174, 94, 12, 52, 33,165, 98, 26,138,219, 98, 75,254, + 37, 62,147, 76, 12,152, 36, 76,195,122, 87,195, 2,100, 78,164,107,193, 49,105,138,208,135, 24,111, 53, 59, 72,171, 82,221,169, +224,113,130,181,217,122, 66, 76,100, 54,162, 83,136,240, 84,252, 66,200,213, 41,105, 10,182,137, 41,193,175, 63,129,187, 32, 63, +253, 44,114, 57, 34,223, 50,228,190,223,255, 39, 15,174,176,125,153,157, 1,173,198,169, 43, 38,192,114,193, 7, 56, 33, 14,150, +186,202,103,239, 12,158, 36, 72, 86,185,247,206, 21,114, 75,201,159,109, 28,222,236,106,226,171,234, 62,237,161,192, 59, 19,246, +177,143,248,228, 52,222,183,187, 29,114, 43,102, 92,247,123, 7,125, 28, 35, 21,227,213,173, 47, 86, 63,246, 17, 54, 59,247,228, +217,195, 1,182, 21,238,184, 80,171,124, 52,192,183, 5,253,169, 45,233, 86,162,255,120,226, 88, 52,154,229,130,156,184, 69, 73, + 48,236,171, 71,234, 87, 38,244,207,158,249, 7,241,209,232, 85,214, 51, 27,248,153, 31, 3,158,194,111,127,215,147,200, 78, 39, +244,139, 91,224, 20,123,162,240,193, 17,251,213, 3,188,239, 2, 59,189,211,145,158,239,224,229,206,119,180,155,231,192,222,136, +177,238, 3, 56,132,223,233, 2,120,108,200,211, 16,152, 61,215,195,171,217,157, 10,207,116,176,235,130, 5, 29, 50,234,193,124, + 18, 49, 21,255,221,199, 2,169, 64,189,194,110,191,139,124,225,207, 2,207,192,248,115,241,193,253,162, 91, 41, 63,153,147,136, + 93,199,206, 49,184,114,176,255, 79,144, 47, 30,224, 71, 0,221,196, 31, 63,135,242, 17, 82,222,134,171,127, 1, 79, 63,134,143, +223,135, 15, 62,194,158, 94,194,135, 35,246,142, 33, 79, 42,156,251,186,138,223, 43,240,211, 55,224,191,189,192,222, 44, 88,144, +241,216,182,168,173,234,130,140, 62,140,219,146,252,193, 63, 77, 46, 97,235,182,110, 49,212,248, 20,214,240,113,182,104, 54, 19, +191,244,179, 91, 30, 73,113,161,107, 8, 11, 95,234,144, 47, 41,188,106,240, 66, 65,110, 3, 55,110, 67,255, 58,232,143, 1, 47, +248,243, 57,137,175,199, 54,191, 9,245,171,240,214,199,216, 95, 27,176,255,251,130,233,225,129, 39, 76, 60,232,132,199, 8,251, +234,186,145, 42,226,199,126,206, 78,167,171, 44,155,218, 18,211,123, 91, 68,165,251,144,217,108, 88,118,211, 54, 71,207,198,152, + 27,239,134, 55,205,162, 21,193, 39, 21,241, 12,114, 81,247, 19,199,122,171,145,228,166,150, 32, 97, 48,213, 41, 18, 29,189, 88, +232, 82,162,170, 35, 71, 47,195, 37,152,163,113,232,162, 70, 42, 65,121, 20,132,211,152, 0, 28, 35,209,205,226, 28, 25,165,197, + 39,219, 34,101, 51, 16,169,215, 46, 29, 89,141,143,107,236,227,230,169,158, 56,146,184,134,251, 32,167,224,170,151, 50, 55, 86, +172,144,172,149, 5, 22,182, 14,209, 54,187,174,110, 23,214,105, 44,114,237,251,137, 74, 32,135,109,190, 64,215, 95,207,184, 62, +150,149,185, 75,142, 56,217, 38, 20, 91, 53,140,245,255,199, 40, 39,235, 78, 89,184,246,253,100,134, 38,249,138, 36,205,190,126, +153,199,243,105,245,107,148, 64,233, 74, 48, 22, 26, 66,215,102, 77,153,223, 45,147,212, 89,135, 50, 77, 5, 49,111, 2,105, 4, +185, 90,175,249,247, 85, 82,120,221,203, 60, 97,105,130,231,169, 26,195,112,164, 14, 67,228, 51,172,108,119,117, 73, 73,186,206, +240, 95, 23, 25, 50,223, 25, 77,151,160,170,228, 20, 21,109, 78,121,190,208, 83,140,143,242,250,235,124, 2, 93,170, 18,152,201, +150,139,220,162,234, 0,173, 83,112,221,151, 61,131, 4,100,161, 37, 55, 49, 91,178,196,141,255, 45,123,221,150,168,214,212, 0, +251,177,255,209, 24,125,153,102,175,174,109,106,132, 93,175, 44,219,104,205,138,243,179, 11,212, 58, 33, 37,249,215, 8,238,165, +213, 35, 73,179, 71, 75,214, 37, 80, 48,135,221, 36, 69,151,162,171,143, 81, 99,209,143,204, 25, 54,222,236,104,117,130, 86, 96, +114, 57,137, 8,183, 41, 72, 49, 49,190,177, 51,193,126,238, 9,250,220, 22,249,242, 61,116, 4,190,103,216, 29,255,218,167, 31, + 95, 81,169,243, 95,173, 6, 71, 91, 72, 8,117,165, 26, 45,174,247,155, 43,225,118,230,246,234,213,231,195, 14,242,193,184,243, +157, 75,228, 76, 73,175,135,134, 55,103,207, 90,109, 85,193, 14, 23,139, 73,134,251,234, 93,232,211, 58, 47,231,164,198,222,248, +134,122, 65,240,194,214,255,238,253,226,127,110, 35, 62, 38,255,230,232,251,241, 91, 61,250,233, 13,245, 43, 3,246,173, 9, 94, + 49,228,249,158,221,135,149,109,137, 4,184, 27, 14,102, 17,245, 5,173,124,191, 32, 63,115, 11,238,237,224,209,224, 47,228, 78, +225,254, 77,191,112, 14,111,195,221,143,225, 62,208,191, 8,249,167, 64, 7,100,247,107,216,163,131, 35,108, 79,157, 89,159, 62, +117,130,124,238, 4, 62,147,144,155, 55,193, 94, 3,185, 15,246, 43, 46,190,186, 48,120, 88, 96, 20,228, 51, 91,120,181,247, 2, +224,102, 92,226, 67,117,113,214,249,224, 58,130,171, 10, 23, 99, 24,159,109,102,237, 26, 9,217, 11,156, 61, 66,254,196,151,160, +255, 9,168, 63, 11,233, 11,144,190, 12,114,242, 59, 34, 50,103, 57, 79,189,128,242, 16,198,223,134,195,223,131,171,127, 14,199, +209,197,115,253,103, 97,247,123,225,236, 71, 97,247,101,191,120,111, 43,188,216, 76, 90, 83,132,114,142, 72,189, 4,123, 4,245, + 41,232, 99, 72, 39,192,247,225,175,254, 77,228,195,115,228,234, 42,242,110, 55,144,183,254,143,246,208,159, 46,237, 86, 29,192, + 46,144,178,135,195, 17,251,184,194, 91,192,219, 21, 62, 44, 62, 1, 25,218, 92, 53,136,116,187,166,234, 44,112, 91,224,229, 10, +159, 6, 94, 50,184, 9,108, 79,160,127, 30,242,151, 32,255, 75,144,158,245, 3,170, 28, 96, 58, 64,247, 4,228, 31,195,197,215, +176,127,120,133,253,111, 71,234,187, 87,236,199,129, 7, 73,248, 72,213, 35, 80, 43, 92, 85,191, 40, 69,124,207,108,205, 63,111, +174, 63, 73, 11, 31,116, 57, 20,227,130, 24, 34,213,173,111,209,152,178, 64,176, 8, 81, 83, 22,245, 51, 72, 22,232,158,219,139, + 82,116,114,161,201,145,121,152,232,234,246, 72, 87,163, 46,212,183, 44,206, 16,159, 86, 97, 77,197, 96, 66,231,232,217, 13,149, +141,250,247, 26, 2, 41,187, 77,126,214,106, 93,198,219,134, 56, 27, 28, 23,135,174, 47, 66,189,182,111,150,217, 10,219, 34,117, + 77,100, 86,180,139,174, 24,255, 77,241,175,138,153,135,141,232,202,119,110, 51, 8, 37, 56,246,232,204, 50, 95, 39,167,219, 39, +138,213, 70, 98, 99,181,151, 22, 89, 26,191, 38,140,187, 14,139, 93,161,101,101, 9,225, 86, 22, 21,251,156,238, 38,215, 87, 65, +178, 90, 69, 40, 77,200,184, 32,237,106, 60, 33,217,152,117, 3,105,206,118, 95,170,139,102,243, 43,198,108, 53,107, 99,255,164, +193, 77, 88,133,206,172,147,210,220,250,173, 43, 55, 82, 3,245, 84, 74,248, 73,125, 61, 29, 94,126,147,153,217,223,190,196,100, +238, 59,111,169,165, 86, 27,159,192, 63, 87, 42, 21, 82,154,153,249,213, 86, 32,231,185, 88, 10,215,152, 36, 84, 59, 82,238,200, + 77,114,191,217,116, 51,198, 85,165,144,195, 24,191,238,173, 53,164,234,201,236, 26,237, 77,108, 5,143,152, 6,239,244,105,227, + 31, 89,249, 4, 67,121,186, 94,213,173,108, 34,178,178,112, 37, 93,254,255,118,105,163,130,229,140,165,236, 47,112, 90,152,187, + 85,193,138, 82,169, 81, 93,199,200,172, 20,180, 20,114, 25,155,219,208,253,188,125,118,241, 95,169,136, 84,103, 98, 87,247,239, + 26,197, 61,164,210,242,205,109,245,102,187, 38,170, 82, 41, 90,177, 24, 36, 36, 85,116,171, 72,191,202, 80,149, 4, 79, 35,246, +242,134,131, 91,234, 95,255,128,244,167, 55,240,163,119,208, 82,169,111,181, 7,195,184,241,193,149, 19,138,146,240, 52,128,253, +199,218, 42, 73,155, 31,222,107,235,150,102, 27,143,232,207, 18,202,232,143, 54,160, 15, 43,183,127,235, 10,233,149,244, 25, 7, +123,112,171,135, 33, 67, 55,120, 44,232, 24, 48,143, 83,117, 64,203, 11,241,130,190, 95,225,142,194,153,250, 30,250,253, 10, 87, +151,158,166,118, 43,193,115,157, 75,174,159,139,247,243,209,209, 11,141, 47,111, 73,223, 60,192,169,162, 47,111,225, 83, 91,228, + 75, 3,250, 96,130,183, 39,159,146,220, 72,216,133, 98,239, 86,244, 79,222, 67,126,207,125,248,248, 16,193, 27, 46,160,226,248, + 1, 12, 95,117,255,216,157, 87, 64,254, 21,168, 63,237,225, 60,245,171,254, 75, 63, 28,224, 82,208, 91,189, 19,242,126,104, 7, +175,109,145,123, 10,242, 58,232, 75, 80, 63,242,203,115,127,132,205, 9,242,211, 59,184,165,176, 81, 31,191, 30, 10,156, 79,177, +103, 31,253,253,122, 28,246,186, 67,157,105,115,140,192,133, 33, 31, 2,151, 21,235, 14,200, 95,248, 44, 60,247, 23,221,179,159, +255, 4,232, 41,252, 14,204,233, 69,109,246, 1,140,127, 23,246,255, 0,198, 39, 48,156, 71,215, 93,225, 34,123, 80,206,243,223, + 71,238,252, 54,240, 71,224,236,247, 67,122,198, 71,245, 54, 45,125,133,244, 46,245,210, 91,192, 43,145, 51,202, 34, 3, 59,253, +227,240,218, 99, 15,167, 47, 87, 32,167, 32,103,113, 27,111, 99, 74, 16, 26, 3,187,128,241,187,112,245, 79,192,126, 5,185,253, + 33,232, 30,187, 1,188, 26,168,222, 42, 78,204,219,154, 35,210,110, 87,184, 49,132,158, 98,227, 63, 79,222,130, 62, 11,221,231, + 33,255, 36,228, 79,129,222, 92,174,128,186, 7,219,131,126, 13,166,191, 15,223,120,143,250, 63, 13,216,175,236, 25,247, 7,158, + 36,227, 65, 47, 60, 9,242,155, 43,251,149,174,239,226,130,115,124,117, 13, 33, 81,105,112, 72, 42, 57,185, 87,120,196, 60, 19, + 30,155,213,238,132, 0, 46,199,136, 59, 1, 91, 49, 54, 89, 49,201, 8,137,177,194,113,154,188,171,195,249,252, 85, 28, 0, 34, +171, 11, 67,227,119,153, 98,154,151,196,133,116, 26,170,237, 38,188,202, 77, 88, 43,115,204, 3, 5, 97, 31,159,135,147, 0,210, +244, 38, 12, 6, 23, 49, 2, 63,137, 61,237,133,153,239,214,155,165,107,181,127, 94,152,237,204, 29,246, 58,137,172, 89,162,106, +227,124,132,205,184,138,255, 35, 86,233,196, 39,119,226,109,233,210,237,175,244, 19,237, 27,213,149, 51, 98,181,225, 93, 21, 14, +173,249,209,217,253, 35,200, 53, 1,154,172,110,210,165, 52,168,215, 60,109, 77,112, 55, 95,160,216, 15, 20, 0,242,137, 11, 86, +227,194,111, 34,226,220, 20,244,234,197,154,139,184,151, 75, 93, 34,160,169,214, 74,169,133, 49, 84,255, 98,139,255, 35,169,144, + 82, 14,225, 40,139,142, 34,252,235,165,150, 80,200,175,130,107, 12, 82, 78,244,125, 79,206,137,220,229,121,229, 43,179, 71, 63, + 18,240,172,204, 83, 93,141,232,230,165,131, 15,100,111,245, 59,183,189, 95, 13, 85, 44,154, 22,188,112,107,188,204,167, 49, 41, + 39,210,166, 67, 82, 34,119, 73,217,110, 55,164, 44,104,141,144, 2, 77,193, 62, 46,238,243,156,133,109,204, 41,105, 26,242,177, +132,146,146, 6, 78,182,196,108,191, 71,202, 20, 99,148,136, 97, 76, 33,112,168,203,104,217, 52,154,194, 57,175, 60,186,119,149, + 57,242,117, 22,125, 88,165,162, 88, 74, 30, 7, 90, 42,166, 1,125,152, 21,131,193, 39,142,159,173,138,161,117,242,157,240, 84, +124, 23,170, 2,195,209, 63,132,147, 87,103,201, 10,181, 76, 14,206, 39, 4, 73, 76, 51,206, 17, 98, 77, 16,227,255,212,185,210, +190,134, 40,252, 84,253, 16,113,144,117, 14,127,173,192, 73,113,218,222,100, 46, 6,163, 96,111, 23,202, 95,125,139,244, 31,125, + 26,126,252,182,215,165,239,184, 30, 64,171,113,147, 3,245,178, 56, 38, 60,158,140,163, 57,244,100, 8, 94, 12,182,140,227, 89, + 9, 70,172, 5, 27, 84, 79,135,122,144, 32,127, 60,114,243,235, 87,200, 46,161,157, 58,158,245,102,130,220, 59, 36, 96, 95,151, +123,231,194,124, 87,252, 98,246,221,185,138,119,170, 35,126,233,215,138,189,125, 68,190, 93, 96,151,176,231, 21,121,238, 12, 94, + 59, 69, 94,216, 33, 31, 94, 82,119,134,254,112,128,180,207,122, 36,101,244,217, 4, 47, 11, 60, 59, 34, 79, 38,108, 35,112,150, +208,223,183, 67, 94, 63,131, 15, 47,189, 27,124, 55,148,246, 55, 30,194,243,103,208,253, 97,144,223, 13,124, 17,236,204, 47, 33, +121, 31,236, 39,160,252, 83,236,106,132,219, 29,122, 59,195,203, 27,244,213, 13, 60, 43,208,191, 12,188, 28, 47,222,175,129,222, + 68,238,124, 10,158,185, 2,121, 2,199, 11,236,145, 7,126,240,120,132,199,145, 68,247,168, 96,231, 5, 27, 70,191,239,142, 14, +225,225,129, 33, 15, 42,178, 73,200,231, 78,144, 63,117, 23,249,242,151,224,238,127, 12,233,243, 33,115,109,186,234,244,137, 75, +125, 0,123, 27, 14,255, 11,246,224,103,145,183, 46,176,243, 14,116, 7, 99, 7, 79, 51, 60, 10, 54,124,238,224, 92,177,215,223, + 70,244,103,125, 68,189,251, 61,208,189, 24, 23,115, 23, 66,138, 97, 37,112,107,160, 17, 93, 57,150, 51,240, 44,200,243,110, 89, + 92, 59,155,109,117,160,178,241,175,219, 63, 3,233, 21,232,222,128,252,243,176,123, 31,185,255, 16,198, 67, 44,158, 99,234,180, + 81,159,244,156,108,160,251, 12,240, 98,168,213, 95,134,242, 10,200,203,160,119,125, 36, 51,127,191,201, 39, 19,211,155, 96, 63, + 11,143,190,130,253, 31, 23,216,223,152, 40, 15,247, 92,216,196,195, 14, 30,198,168,125, 40, 62,178,164,235, 24, 45, 5,203,220, +102, 72, 14, 56,154,182,159,247,137,158,185, 46,201,123,188, 17,193,202, 34, 78, 34,216, 27,189, 72, 64,165, 92, 96, 39,157, 82, +138, 48, 77,222,169,149, 22,153,105,203, 94,121,238, 32,163,211,213,224,209,180, 81,115, 86, 31,181,175, 59,191,166, 25, 90, 70, +217,203,158,212, 48,246,209,185,159, 86,225, 44,106,102,173,198,211,234,112,171,141,192, 72,101, 95, 38, 95,157, 70, 97,161,145, +220,134,234,236, 61,111,180,178, 58,239,210, 35, 33, 44, 84,244, 22,194,230, 28, 76,247, 49, 2, 38,100,222, 93,203,156,188, 6, +215,115,222,235,138, 84,246, 59,148,167,222,169, 26,115, 26, 89,224,219,174, 21, 27, 63,168,119,151, 31,184,218,215, 93,119,138, +174, 91, 44,118,212, 65, 17, 77,235,192, 47,145, 85, 42,104,176,225,213,129, 53,224,107,160,100,174,253, 42, 2, 67, 41,243, 26, +163, 90,101,170,230,233,103, 13,218, 19,129, 46,235, 88,221, 38,134,115,213,187,119,239, 99, 45,158,132, 86,150, 53,105,179,144, + 9, 66, 29, 38,255, 89,250,126, 22,139,207,138, 1, 51,166, 90, 3,209,235, 36, 58, 82,192,162, 98,100,127,125,125, 93,231,160, +165,106,174,242,119,242, 93, 76,195, 67,227, 85,103, 65, 96,135,118, 27,239,246,173,146,187,205,134,254,244,148,178,223, 71, 46, +121,144,114,146, 5, 38,176,128,133,241, 93, 90,101,225,123,105, 69,209, 46,121,188,101,236,149, 60,141,166,206,170,120,153, 63, + 13,178,132,146,204,232,189,182,149,247,175, 55,103,236,202, 2, 87,153,213,134,104, 88, 39,194, 35,217,186,104,153, 69,246, 49, +222,119,155,193,236, 25, 47, 21,177,209, 45, 0,154,124, 12, 59,140,200,166,247, 85,253,228,157,122, 91,213,251, 7,172,186,146, +151, 69, 89, 58, 91, 51, 42,115,158,252,228,161, 80,254,160,116,145,165, 91, 88, 80,129, 13,234, 62,198,133,127,154, 97,119,196, + 30, 12,148,191,242,125,210,159,124, 21,249,242,109,127,131,222,241, 7, 33, 77,198, 45,142,110,185, 10, 53, 76, 73,144,171, 43, +201, 11,203, 36,116,109,121,107,123,174, 41, 42, 90, 45,190, 58,126,154, 97,251,224,136,124,219,119,153, 42, 2,175,158,192,173, +236, 0,238,227,232,139,190,193,224, 81,248, 36,139,186, 17,121, 8,206,251, 78,225, 86,196,124, 62,184,164,126,247,128,189, 83, +176,193,208, 47, 63, 65,126,215, 25, 60,187, 69, 94,217, 34,210, 35, 39, 9,123,127,132, 62, 33,231, 81,157, 28, 60,130,212,196, +176, 11,144,159, 56, 67,158,219,192,219, 71, 31,251,107,130, 77,129,231, 30,194,107, 2,249,223, 7,253, 67,113, 73,156, 70,226, +205, 30,228, 6,148,247, 97, 56,247, 46,227,115,157, 19,232, 94,232, 29, 92,114,186,133,250,252,210, 53,111,126, 36, 12,168,223, +133,241,125,184, 24,177, 71, 5, 30,140,240,104,194, 30,150,185, 91,175, 87,158, 71,108, 79, 11,246,110,133,135, 46, 50,212,151, +183,232,159,185,131,254,158,123,240,236, 43,208,189,228, 29,175,253, 44,156,255, 53,236,209,119,224,193, 19,120,174, 67,238,220, +133,252, 47,131,117,254, 61,247,191,130,189,243, 93,248,202, 21,252,218,142,122, 56,117,225,223,109, 3, 29,176,209,176,115, 63, +108,117,167,112,209,193,101,194,222,120, 23,121,254,111,192,254,159,193,230,115,190,151,238,223,128,252, 42,200,205, 21,181, 67, + 86,216,207,166,174, 28,227, 63,235,234, 2,255,228,241,188, 62,120, 51,164,231,225,228, 95,135,237,143, 67,121, 23,166, 15,192, + 46,221,126, 71,129,116, 3,250,155,144,111,129,190, 30,109, 60,160, 23,110, 88,239,108,245, 61,197,255, 94,189,132,250, 8,134, +127, 12,195,223,134,223,122, 23,251, 31, 10,245,171, 7, 46,167,129,135, 25, 62,238,148,167,213,152, 38, 95, 44,164,212, 65,191, +137,156,104, 67, 73,145, 65,109,115,112,133,103, 96,183,209, 54, 84,153, 72,116, 75,102,130, 45, 29,223,132,123,193,253, 92,203, + 88,206, 76, 98,140,165, 64,241,115,167,152,139, 93,205,165,212,243,206,213, 59, 50,157,169,159,197,100,241, 91, 95, 19,166, 53, +255,155,205, 35,210,165,131,149,107, 29,107,109, 10,247, 8, 92, 57,195,216, 70, 20,235,185, 9,131, 85, 54,110, 8, 9,136,158, +231,127,155,120,113, 50, 75,254, 86,137, 99,115,119,221,190,191,249,122,212,240, 66,129,153, 53,183,232,232,155, 64,120,134,150, +204,187,217,213,213,109,215, 69,100,215, 18,207, 2,168, 51, 39,191,253, 78, 68, 57, 91,186,235, 31,252, 63,157, 99,188,117,102, +194,235, 66,128,139,247,177,217,249,186, 70, 45, 85, 13, 81,100,241, 34, 45, 2, 88,142,213, 47,190,110,140,194,103,170, 46,162, +140, 66,166,129,208, 84,160, 15,122, 27,179, 7,220,155, 59, 13,150,190, 52,143,122,116,244,165, 86,191, 7,139, 93,195,225, 46, + 58, 21,159, 25,149, 90,152,166, 9, 82,231,151,171,248, 4,123,178, 74, 45,109,164,238, 77,240, 8, 28,143, 7,108,104,201,108, + 54, 23,157,182,210,172,181,119,172,154,161,165,248, 68,188,115,224,154, 76,174,230,215,148,253,125, 8, 1, 93,238, 54, 27, 44, + 5,253, 70, 12, 73,222,202, 99,101,246, 45, 90,178,101, 31,216, 36,215,226, 41, 84, 57, 41, 93, 45,241,176, 69,151,172, 75,162, + 13, 51,153, 41, 70, 54,213, 13,251,213, 42,165,122,199, 43,193,137,111,185,191, 13,229,170,115,122, 20,148,172, 94,225, 76,213, + 19,197,114, 63,143,113,102,128, 65,168,243,173, 44,161, 36,169, 20,218, 64,174, 69, 12, 82, 6, 24, 58,196,170, 11,250, 40,241, +168,232,252,115,107, 27,225,229, 32,137,133,245,133, 85, 53,222, 62,189,131,193,201,100,110,153,168, 5,114,242, 39,250,104,238, +225,110,138,197,211, 4,167,138, 29, 6,236, 27,231,240,191,190, 69,250, 15, 94,133, 47,223, 65, 53, 83,223,242,215, 39, 99,220, + 26, 15,243,244, 66,134,120,102, 90,246,115, 89, 18,172,109,245, 51,213,120, 16,199, 58, 3,254, 56, 23, 56, 25, 13,253,254, 1, +106, 66, 78, 5,185,147,224,238, 14, 78,178, 43,137,174,226, 50,191, 29,202,110, 12,246,129, 26,203, 9,187, 28,124,215,220, 9, +246,193,145,250,205, 3,118, 82,160,135,250,235, 71,248,165, 11,120,117,131,124,170, 71, 94, 76, 46, 54,123, 53, 35, 99, 14, 48, +139,193,183, 6,255,248, 92, 84,228,139, 59,228, 78,143,189,115,112,213,249, 85, 0,244,127,248, 9,188,120, 3,186,255, 10,244, + 15,196,229,213, 55,229, 72,140,161, 5,234, 55,225,248, 0,166, 12,187,206, 35, 92,159,243,177, 62,242, 67, 32, 47, 68, 33,240, + 0,244, 28,236, 91,112,120, 12, 31, 11,124, 84,144,183, 7,236,193,232,124,117, 49,234,177, 96, 15, 11,246,222,136,125, 80,144, +154,208,251, 27,210,127,122, 11,249,221,183,144, 23,206, 96,211, 65,237,224,240, 33,188,247, 13,234,191,120, 76,253,123,143,225, +235, 7,236,194,227, 31,229,134, 34,247, 19,188,252,143,252,198,233, 5,222, 83,236, 42, 83,199, 12,249,128,157, 30, 97,175, 46, +210,155,119,236,161,112,189,236,208,203,130, 78, 29, 92,244,216,167, 15,240,252, 55,145,179, 55, 97,123, 6,221,125,216,126, 22, +250, 31,135,252,162,119,251,146, 22, 3,147, 18, 35,246, 28,169, 39,233,250,168,243, 19, 6,163,235,189, 87, 1,217,122,209,144, + 94, 9, 32,122,157,243,207, 67,232, 50,227, 64,150, 80,130,109, 40, 77, 74,196, 80,118,241, 30, 29,160,188, 5,227, 95,198, 62, +252, 37,248,219, 7,236,111, 21,134, 15,175,120, 40,149,247, 54,194, 5,190, 55, 79,197, 87,128, 57,119,254,137,175,149, 74,245, + 67, 78,149, 12, 76,146,168, 9, 36,249,250,172,214,226,218, 61, 96, 44, 70,169,147,159, 33,101, 57,152, 27, 68,101, 68,153,178, +146, 52, 81,106, 97, 63, 20,178,154, 83,202, 88,180, 58, 37,197,247,142, 67, 88,100,189, 31,118,213,123,173,182, 34,139,249, 37, +209,246,231,134,163, 92, 91,145,221,118,193,237,252,171, 43,155, 96,169,198, 85, 32,101,219,197,126,150,224,188, 58,163,253, 68, +132,162,198, 80, 74, 48,230,109, 57,161, 86, 2,185, 53,239,189,174,222,235,201,184,166,188,110,231,236, 18,111, 18,201,141, 97, +251, 42,164,217,143,125, 93, 15,178,254, 94,204, 28,122,137, 11,253,218,118,221,214,187,112, 91,177,165,116, 14,198,177,133,112, +194,122,190,180, 14,252,106, 59,232,182,183, 78, 73,188,128,171, 54,171,196, 91,240,203,156, 64, 41,202, 70,124, 21, 82, 98,231, +172,234,175,121, 10,167, 66,109, 34,233,153, 96,186, 56, 17,210,252, 57,119,200, 88,177,226,220,251, 32,184,105,117,138,100, 69, +174,241,243,125, 58, 82,188,161, 11,171,113, 78,186,228, 13,168, 80, 75,241,152,232, 40,102, 38, 51,142,227,192, 52, 28,195, 54, + 29, 13,225, 28,147, 27, 39,255, 39, 8,125,213, 28,104,162, 34,142, 86,206,105,150,213,207,179, 32, 19,114,234,187,200, 19,169, +164,156,200,187, 29, 89,171, 39,142,197, 40,220,125,141,214,138, 81, 87,170, 39,175,158,196,204,125,153, 45, 47, 61, 40, 51,201, +150, 48, 24,109, 96, 26,243,164,205,106, 94,133,205, 9, 64,178,108, 97,196, 22,122,146, 52, 17, 70, 82,239,190,109,194,180,247, +170,170, 76, 88,118,248, 76,173, 37, 42,191, 28, 63, 92,248, 85, 17,196, 38,116,170,164,188,161,150,228,219,185, 58, 33,195, 33, +126,166, 18, 74, 75, 91, 60,245,197,189,242,189, 24, 35, 30,191,170, 1,115,104,108,235,130, 6,204, 33,128, 28,147, 57,210, 54, +235,210, 53,197, 7,147,205, 18, 12, 44,119, 50,246,209, 1,186, 66,253,234, 83,228,175,191,131,254,204,203,240,165, 51,164, 55, +210,119,124,172,223, 85,184,245,241, 62,188,220, 54,251, 98,143,133,120,205,155, 55,125,113, 37,180,236, 97, 86, 89,209, 37,214, +181,253, 97, 66,222,219, 35, 91, 37,223, 8, 97,216,189,141,175, 11,186, 50,123, 51,103,101,222,105,130,171,201, 67, 67, 30, 77, +240, 65,133, 23, 5,158, 73, 62, 69,120, 58, 96,155, 8, 54,153,128,223,218, 99,223,240, 16,115, 41,226, 17,174,127,248, 22,250, + 83, 55,177,179, 30,126, 8,120,119, 68, 63,123,138,221,234,176,119,246,254,195,137,250,222,246,228,145,219,158,182,127,213,199, +237,178,249,132,218,181,149,239,125, 92,234, 7,144, 91, 72,151,224,134, 32,103, 29,228, 31,243, 17,112, 25,192,190,231,151,249, +244,158, 71,118,189, 43,240,193, 4, 31,141,240,209, 64,189, 56, 82,135, 9,158, 26,246,176, 32,143,196, 73,103,127,252, 14,250, + 7,239,192, 43,103, 17, 13,171,176, 63, 96,111, 62,161,254,220, 35,166,127,112,206,240,189, 43, 31,205,111,160,222, 16,210,173, +140,116,160,147,160, 31,128,188, 55,198,231, 80,188, 88,233,253,194,177,106,240, 36, 56,248,125, 94, 70, 46, 18, 62,249,174, 96, +214, 97,181,146,174, 12,206,123,248,190, 96,119, 39,184,255, 8,185,253, 24, 78,222,130,237,255, 71,215,187,198,106,150,165,119, +125,191,103,173,181,247,251,158,107, 85, 87, 85,223,123, 60, 61,211,227, 25, 27, 15, 54, 54, 54, 25,108, 19, 18, 8, 96, 72, 72, + 36,164, 68, 10,136, 64, 72, 66, 4, 81, 34,132, 20, 69,185, 8, 72, 20, 62, 68,202, 7, 4, 9, 81, 66, 20, 43, 16, 66, 32, 22, +118,226, 27, 96, 99, 25, 12,182, 99,123,152,177,103, 60,198,115,233,238,153,158,190, 85,117,215,237,156,243, 94,246, 94,107, 61, +249,240, 60,107,239,253,158,106,143,212, 83,125,169, 58,239,109,191,123, 61,151,255,255,247,255,167,198,177,143, 71,254,217, 39, +187,200,194, 17,116,223, 0,171,143, 67,255, 50,200, 51,254, 62,118, 79,190,143,135,136,145, 73,132, 55,237,112, 14,212,182, 58, + 83, 63, 36, 47, 96,156,145, 37, 37,193, 14,244, 0,229, 17,228,127, 4, 87,255, 3,250,185,183,224,251,133,250,217, 29, 87,187, + 61,111, 39,184, 27,133, 93,101,186, 89,210,245,118,176, 86,181,239,184,107, 72,178, 66, 40,194,190,157, 53, 49,152,255, 62,118, + 12, 49, 81,115, 65, 60, 53,176, 58,241, 45, 37,247, 87,187,216, 72, 5,134,152,216, 81,185,145, 71, 11, 73,241,123, 78,144, 64, +212, 72,145, 72, 13,230, 99,206,181,113,115,195,180,175, 69,196, 89, 25, 62, 49,208, 22,254,195,148, 92,214,102, 34,205,219,220, + 68,196,180,113,177,204, 59, 80, 21,161,136,129,143,182,110,213,203,190,103, 63, 10, 80,106,160, 70, 56,166, 80, 84,184, 82,235, +238,135,146, 73,181, 90, 40, 85,179,202, 45,242,193, 85,235,181,132,243, 25,119, 59,128,117,139,112, 96,227, 10,158,237, 33, 64, +174,101,242,187, 79,179,133, 73, 11, 53,215,128,211, 21, 83, 23, 2,188, 57, 32,122, 78,145, 91,136,217,104,215,255,181, 57, 81, +219,133, 91,148, 77, 99,220, 91,214,188,197,208, 86,106,153, 31,184,221,161,218,121,146, 4, 82, 72,102,167, 84,139,180,174, 30, + 29, 94,125,223, 45, 11,101,252,196,196,247,207,177, 86, 27,203,207, 72,218,121,252, 78, 99,178,187,109, 17,130,219,254, 22,200, +238,182, 82, 14, 30,214,228,164, 63,137,209,138, 24, 85,198,156, 41,206, 60, 9,193,222,183,113, 24,166,206, 90, 26,120, 71,220, +103,169,243,185, 87,235, 92, 2, 77,218, 10,159,136, 55,212,104, 75,162, 19,183,153,167, 20,162,251,201,133,110,125, 76, 58,127, + 10,125,252,158, 37,132, 77, 21,154, 93, 60, 69,213, 32,247,206, 49, 22,172,170,201, 30, 48,144, 68, 38, 25, 78, 20, 27, 41, 77, + 52,184, 22, 54,239, 29,250, 20, 67, 55,117,189, 45, 36, 99,190,232, 68,162, 39,189,225,162, 3,235,216,170, 68,163, 22,101,143, +203, 43,217,246,141,169,237, 70, 34,168,101,221,106,181,200,173, 82, 11, 50, 14, 19, 30, 48,120,240,223,228,131, 81,243,176,167, +166,184,196,200,119,169,216, 7,152, 61, 91, 89,167, 11,192, 84,150,163,170, 5, 15, 56,204, 67, 58,177, 55,160, 89,128,206, 60, +160,251,162, 88,172,232,237,104,163,248,113,132,115,165,126,246, 33,114, 43, 33,127,224,121,228,155, 3,122, 20, 9,175, 61,166, + 70,161,139,112,243,254,142,180, 41,246,146, 4,210,104,249,208, 82, 32,143, 30, 13,233, 23, 89, 55, 97,120,125,189, 81,108,146, +158,139,146,163,165,132,213,109, 70, 95,219, 25, 39,252, 36,153,189, 41, 70,179,108, 61, 54,245,185,118,174,224,127,223,148,153, + 12, 35,250, 86, 49, 53,250, 43, 61,242,114,100,252,185,145,253,202,154,215,110,173,196, 34, 68, 41,176, 55, 77, 20,119, 43,221, +223, 28,173,113,252,228, 77,187, 48,111,218,161,207,221, 45,250,230, 8,199,150, 44, 71,205,240,209, 12, 71,255, 29,200,183, 58, +250,119,176,207,244, 16, 94,105, 59,218,242, 89,180, 70,228, 41, 87,243,223, 9, 54,158,150, 15,217,243,149, 43,208, 79,195,238, + 17,220, 15,240,134,192,251, 5, 86,142, 34,123, 48,194, 87,246,232,123,133,240, 76, 79,248,246,155,132, 63,120, 3,190,225, 24, + 78, 58,227, 38,108, 50,250,234,125,202, 79, 61,102,251, 19, 23,108,223,216, 49,230, 74, 57,129,122, 35, 80,142,226,212, 94,180, + 36,193,216, 43,253,202,109,153,110,125,145,216, 12,197,109,125, 35, 22,170,178,203,182, 7,246, 60,111, 55,247,130,100,235,252, + 70, 37,142, 5,185,136,112, 47,193, 59, 9,189, 17,224,198, 8,231, 91, 75,200,235,189, 24,238,177, 9, 75, 60,182,128,157,237, +171,176,126, 1,142,126, 51,164,151,125,133,225, 59,116,130,137,227, 24,141,104, 87,223,135,242,190,141,218,117, 99, 7,115, 88, +249,190,253, 24,194,218,121,178, 30, 15,155,206,205,107,206,173, 5,152, 83,236, 73,168,152, 48,113, 74, 85,137,214, 0, 0, 32, + 0, 73, 68, 65, 84,255, 87,224,238, 15,162, 63, 94,224,239, 66,126,251,138,251,101,228,173, 20,184, 47, 86,203, 37,223, 99,203, + 58, 81,107,245,137,154,211, 18, 3, 19, 78,115,234, 68, 69,201,165, 80,139, 97,128, 99,234, 88,117, 29,165, 51,226,158,142,197, +239, 45, 75,232, 71, 35,110, 85,114,182, 14,232, 40, 9,151,213,240,168,125,138,116, 4,114,181,100, 44,114,177,251,158, 52,111, +182, 44, 60, 83,122,144,113,113,120,128,169,219,152,102,107,152, 58, 42,183, 97,101,157, 11,104, 16, 20,236, 64, 47,254,218, 10, +138, 22,163,222,117,162, 28,185, 55,189,212,202,137, 59, 43, 55, 24,190,182,104,177,166, 35,122, 55, 39,184, 56,184, 30, 98, 16, +166,243,120,182, 16, 79,180, 79,153,253,252,209, 3, 71,144,121,172,172, 79, 56,201,213,139, 7,153,136,104, 77,207,163,194, 36, + 72,148,197,129, 57,163,191,229, 96,148, 47,173, 3,151,131,176, 56, 86,190,255,180, 18,209,116, 14,162, 70,229,211, 16,208,106, +199,249, 88,125,130, 35, 54,105, 73,193,198,209,197,155, 59, 69,167, 91,122,112, 87,150, 65,118,132, 82,148,170,217,227, 74,109, +157, 83, 23, 30,251, 24,230,233,195,236, 81,183,247,182,162,158,170,120, 61, 44,126, 30,197, 55,143,251, 80,172,216, 92,117,189, +189, 39, 46,156,110, 51,146,146,139, 33,199,181, 78,227,123,185,174, 89,240,107, 36,132, 89, 77, 62,137, 38, 39,218,221, 44,206, +108, 92, 2,149, 64, 18, 2,165, 22, 82,234, 73, 71, 39, 86, 97, 20,219, 7, 52, 75,198, 36, 16, 75,238,131,243, 71, 31,106, 37, +151,106, 95,206, 0,189,170, 69,183,166, 72,138,129, 72, 37, 77, 81,117,118,200, 83, 26,186,199,199, 31, 85, 80,169, 7,246, 6, + 22, 99,251, 16,131,141,181,101, 65, 83,242,192, 2,243,157,207,240, 3,145, 4,201, 14,175, 32,214,205,139, 58, 75, 89,138, 69, +236,169,229,231, 74, 35, 37,249,222, 81,171,113, 90,197,171,254,214,238, 6, 26,186, 85,102,107,129,255,251, 34,144,213,170,238, + 92,171, 97, 71,219,217, 83,176, 36,152,149,192, 90,109,167, 92,197,169,161, 9, 61, 90,155, 82, 62, 6,234,231,175, 8,183,223, + 67,126,251,179,200, 55, 10,172,133,208, 39,106, 23,136, 41,112,254,222,134,112, 89, 8, 98, 58, 50,196,148,190,120,218, 19,190, +163, 11,139,207,187, 49, 67, 86, 73, 89, 91,104,144, 77,164, 99,165,190,157, 9,221,222, 14,156, 19, 23, 95, 93,101,120, 35, 83, + 31,100,184,169,246,156, 95,207,104, 15,242, 82, 7, 55, 61,164,250,162, 32,223,210,193, 63,177,178,134,181, 48, 22, 24, 81,116, +132, 97,180, 26,166,127, 70, 56,189,200,132, 97,132,215, 55,222,198, 4,184,187,131,207,239,209,207,108,145,151, 87,200, 31,234, +224,198, 5,220,252, 70, 8,191,207,133,101, 23, 30,152,221, 63, 97,160,161, 60,128,242,203,166,224,191,221, 35, 47,172,224,104, + 15,229,194, 70,237,225, 4,198, 95,134,203, 7,112,127, 13, 15,170,105, 2,190,239,134,165,189,253,133,119,224,125, 37,124,252, +140,240,199,215,240,219,111,194,233,202,238,156,187,130,188,254,144,242, 11,143, 25,126,248, 49, 23,191,190,225,241, 88,184, 60, + 18,120, 42, 26,115, 96,122, 30,158, 17, 36, 86, 75, 38, 79,233, 43,105, 17, 23,172, 86,124, 33,115,210, 96, 8,205, 54,165, 7, + 52, 59, 79,191,176,235, 48,248, 1,181, 85, 66,169,200,182, 32,219, 12, 15, 83, 75, 91,178,241,248, 26,243,149, 31,251, 53,118, +126,137,220,186,128,211,135,144, 31,195,254, 49,172,191, 12,253, 43,144,110, 59,216,224,161, 29,188,245,109,216,191, 14,195,149, + 21, 80,165, 90, 17, 21,125,164, 31,130, 29,252,169,154, 5, 46,125, 7,196,223, 14,188,232, 93,122,235, 77,131, 21, 0, 53,155, + 91, 97,251,231,208, 47,255, 26,252, 47,137,250,207, 6,118,155, 29,119, 69,121, 43, 5,182, 14,110, 10,222, 1, 73,144,137,119, +221, 20,237, 97,233, 97,246, 27,107, 84,166,213,158,162,228, 98,223,200,174, 91,147, 98,178, 14,186,139,140,197,110,216,115, 55, +198,140,244,172,160,157,176, 74,129,203, 12, 67, 16,207, 22, 42,104, 41,118,159, 11, 62,221,155,212,226, 30,117,231,145,210,165, +161, 57,107, 59,216,120, 98,140, 76,163, 90,186,104,104, 82,166, 47, 50, 38,101,193, 59,173, 14, 25,217,250, 72,254, 72,140,151, +191, 14, 66,142,129,162,133,163, 86,247, 85, 27,221,182, 26,176,121,210,203,116,208,201, 19,163,240,209,133,126, 77,133, 95,151, +178, 7,108,109, 17,167,164,206,234,246, 57, 57,184, 31,107,187, 39, 30, 80,222,174, 67, 89,230, 61,120,153, 10, 3,109,137,198, + 51,244,101,209,109, 90,113,209, 80,187, 38, 96, 28,171, 33,191, 87, 33,206, 60,246,162, 20,205,182,223,246,142,186,199, 8,125, +218, 37,114, 81, 74,105,170,242, 38,101,170, 19,191, 99,116, 22,190, 44,232,112,243,218, 82,166,102, 50,132,198,100,145,137, 9, + 82,139,250,132,134,195,132,185,197, 27, 49,233,190,252,156,171, 77,251, 17,170,139, 38, 93,192,232,212,211,234,170,120,209, 37, +172,134,131,194, 76, 61,210,220,180, 96,179,181,112, 38,177,232,129,252, 80,196,192,113,164,142, 84, 74, 53,177, 91, 58,178, 23, + 50,152,226, 85,101, 6,243,182,157, 19,110, 21, 72,162,236, 75, 97,168, 58,171, 69,181, 13,108, 44,135, 56, 33,116,174, 84,149, +160, 68,204,207, 93, 99, 68,181,152, 48, 78,116,254,248,165,153,233,195,252, 3, 29, 97, 40,117, 54,237, 91,122,145,250,248,202, + 51,112,213, 58,184, 32,160,161, 35,116,130,196, 4,219,209, 46,198, 82, 76,252, 86,153, 47,220,106,129,217,177,165,165,120, 5, +179,220, 76, 77,158, 88, 89, 38,243,224,254,119,183,222, 86,200, 85, 24, 58,229,120, 83,224,225, 96,202,241,170,176,117,224,244, + 38,152, 61,234,212, 99,154,206,162, 77, 69,215,193, 82,193, 66,128, 47, 95,161,199,247,144,239,184, 13,175,156, 88,252,231,113, + 64, 58,187,193,156,197, 13,242, 56, 19, 86, 74, 26,109, 98,157, 60, 77,110, 26,251,133,153,177,191, 10,112,220, 41, 55,215,202, + 81,132,116,105,231,165,244,126, 34, 93,101,120,144, 12,163,229,222,122,189, 40,212,207, 95,152,232,233,165, 96,122,171, 71, 66, + 88, 87,219,147,191, 89,224,173, 17,190,183,163,255,151,142, 24,254,241, 21,229, 68,173,176,241,102,180, 4, 19,233,140,254,133, + 36, 96, 9, 57, 95,119,170,208,195, 10,247, 50,225, 60, 34, 87,152,234,252,197, 29,172,254,109, 59,213,202, 23, 77, 12, 23,158, +126,242,206,161, 3,148,207,192,238,158,237,127, 95, 88,217, 11,213, 8, 97, 15,241, 10,242,231,224,254, 59,240,110,178,105,200, +163, 0, 31,235,224,108, 5, 63,251, 0,126,239, 25,252,214, 99,228,153,181,137,162,134, 17,222,126,140,126,105, 67,249,193, 7, +236,126,101,195,230,114,100,119, 36, 92,222, 20,182,125,100, 91,124,127,154,231, 27, 84, 18,166,152,226,137,236,167,138, 22,153, + 50,170,139,123,138, 37, 96, 59,209, 22, 58,238,142, 15,233,197, 60,251,218,162,255,100,214,187, 69,108,210,164,106,218,129,157, + 65,111,100, 31,204,205,177,242,234,160, 11, 38,120,116, 71,129,222, 23,184,115,129,220,217,194,241, 21,228, 75, 67,176,246,183, + 77,224, 23, 86,110,146,117, 5,102, 13, 86,133, 21, 19,196, 50,110,237, 48,151,199,208, 93, 65,255,109,208,255, 81, 72,223,228, +163,252,236,217,176,109, 68,176, 54,117,251,246,111,193,213,255,140,254,202, 5,250,191,246,228, 47, 92,113, 57,236,120,167, 19, +238,138,161, 80,131, 19,219,136, 66, 9, 54,109, 91, 78,189, 90, 79,104,105, 85,243,184,177, 70,163,217,185,127,196,187, 60, 37, +103,115,162, 83,125,101, 23,163,133,201,184, 56,137,226, 55,201, 40, 12, 17,118,158, 75, 20, 5,246,165,146, 61,212, 37,250,148, +209, 10,119, 3, 91,101,135, 67,136,139,242,170,159, 22, 65,155, 19,230, 80, 86,118, 16, 12, 93, 77,149, 62,161,181, 91,239,171, + 79, 26,189,213, 79,223,236, 43,135, 73, 92,230, 81,173, 33, 38,118, 82, 9,197, 82, 29,119, 49,204, 96,148,133,194,125,210,249, + 44,159,153,204,121,240,178,160,235,181,195,182, 0, 99,173, 6,215,241,108,113,173,213,195, 89,194,194,230,182, 56,208,101,238, + 84,151, 56,107,117, 17,113, 59,100, 2,115, 86, 19,141, 90, 26,194, 92, 32,248,123,213,137, 16, 67, 7, 98, 41,101,117,114, 50, +217,189,219,168,109, 50, 29,230, 77,209, 17, 67, 36, 36,139,220, 46,101, 36,123,220, 96, 97,206,197,152,217, 42,115, 17,177, 76, +116, 91, 12, 16,102,222,160,206, 58,173,234,202,116, 14, 96, 56, 75,246,237,181,207,223,213,244,234,128,159,125, 25, 97, 15, 37, +231,197,246,171,253, 76,153,200,112,184,141,186,217,235,218,148, 69,155,208, 27, 19,220,233,129, 95,126, 94,219,197,224,147,171, +126,141,166,142,164, 81, 8,235, 35,200, 35,227, 48, 16,171, 93,140,237, 34,175,137, 57,227, 72,132, 40, 86, 81,218, 95, 21,245, + 69,110,179,156, 24,147,194,126, 95, 23,102, 36, 99,154,198, 79, 17, 77,130, 76, 86, 3, 27, 35, 53,219,129, 52,177,137,127, 25, +164,206, 22, 10, 7,220,122, 0,140,237, 30, 76, 85,232,240,131, 97, 11,169, 35,134, 8,171, 19,180,236,208,113,239, 39,141,137, +216,196, 43, 91, 25, 71,155, 48,250, 14,172,224, 55, 53, 15, 42, 40,234, 57,242, 90, 33, 55,251,136,241,173, 91,193,209, 38,236, + 99, 85,219,177,239, 43,225,190, 9,202,164,183, 19, 95, 7,117,143,113, 65, 30,244,126,242, 97,255,253, 78,135,164, 0,217, 88, +236,188,182, 69,211, 67,228,219,206,225, 27, 78, 44,171,251, 36, 16,142, 34,117, 21, 56,150, 13,225,241,224, 56, 69,187,120,227, +202,198,240,227,130, 60,215, 46,186, 20,149,152,160,223, 64,119,212,209,255,235, 55, 8, 47,244,118,243, 59,139,118, 24, 94,218, + 88, 93,111, 39, 27, 79,127, 45, 82,191,188,131, 13,134,121, 61, 14,232,133,227, 72,215,130,190, 54, 32,191, 10,225,251,206, 88, +127,110,224,242,225,136,158, 47,214,178,193,242,182, 79, 43,172,190,115,101,213,241, 47,109,225,249,158,240,189, 39, 70,127, 59, + 57, 50,159, 94,142,240,209, 4, 31,138, 16,191, 27,234, 93,168, 95,128,248,123, 22,160,244,197,222,183,188, 11,229, 47, 89, 55, +123,243,204,184,244,187,140,116,157, 29, 64,229,211,112,111, 15, 95, 19,120,119,240,215,182,182, 47,207,166,192,119,220, 48, 15, +145,102,184,220, 81,191,116, 65,249,233, 11,234, 47, 94,146,223,221,145, 99,229,209,177,176,187, 25, 24, 68,184,242,201,195, 80, +204, 23, 26,213,166,220, 41, 64,109, 43,241, 57, 57, 98, 50, 59, 20,153,101,100,141,179, 48,223,213,125, 2,213, 5, 66, 10, 83, +178,147,116,174, 45, 73, 62,229,161,117, 98, 21,173, 35,146,221,198,153, 61,124, 70,220, 75,219,196, 19,163,152,234,108,140, 48, + 88,200,142, 60,243, 46,156,108, 32,191, 8,101, 15,249, 2,186,231,236,175,244, 52,196, 79,192,234, 33,212, 71,246,222, 14, 95, + 51,135, 64,200,112,252,109,112,252,199,160,255,164,143,227,247,254, 87, 27,108,250,162,109,124, 13,182,255, 13,188,247,243,232, + 63, 9,232,143,118,148,215, 46,184, 40,123,222, 88, 5, 30,170,189,245,125,152,245,122,134,134, 46, 19,205,172,248,158,145,197, +120,183,101,190,183,155,103,136, 66, 41,198,116, 87,135, 52,170, 91,130, 36, 89,100,161, 20, 83, 40, 87,169,132, 24,109,160, 0, +164, 24,169, 57,179,203, 5, 77,214,249,151, 42,140, 81,233,146, 16, 75,160, 83,179, 83, 21,204,250,213, 40,113, 38,176, 2,117, + 86,122,110,222,101,157,221, 60,237,239, 99,179,133,133,198,135,119,174,249, 53,117,184, 89,231,116,154, 36,204,191, 26,140,166, +115,175,123,115,201, 70,255,121,235,162,142, 76,144,169,104,172, 94, 24, 45, 0,163,115,113,225, 75,198, 41,174, 85,219, 64, 89, + 60,205,172, 82,106,165, 80, 73, 26,233, 66, 36,164,206,114,187,151, 34, 45,213,107,135,215,225,252, 76,125,226,217, 94,179,133, +104,133,131, 88, 85, 59,152,151,172,120, 91,103,166, 96,247,220, 65,149, 82,203,100,251,154, 44,130,238,163,143,194, 98,223,111, +151,253,144, 51,185,152, 14, 66,155,142, 97,217, 68, 59, 14,182, 86,253, 64,137,232, 18,207,222,220, 90,234, 69,217,100,169,114, +241,153, 4, 62,200, 6,176,240,217, 7,155, 4, 59, 58, 56, 52, 70,123,153, 19,237,138,206, 63, 91,181,186, 61,110,241,100,106, +225, 9,173, 98, 59,252, 91,209,218, 8,142,106,194,108,243,133, 71, 86,125,207,106,125,196,160,149, 36, 33, 17,251, 35, 40,197, + 98,248,114, 54, 24, 75,106, 21,135, 78, 72, 84, 99, 92, 84,178, 4, 50, 62, 54,147, 73,103,106,157,179,139, 75,134,170,236, 67, +160, 23,103,238,186,113, 51,136,139,206, 38,168,131,206,201,107,237,255,155,130,180, 46,144,133,218,152,242,234, 54,181,234,123, + 20,245, 16, 7,161, 14, 35,116,123, 88, 37, 40,163,249,218, 67, 7,169,186, 7, 93, 9,193,199,103,121, 36,116,238,128, 12, 30, +203, 68,157, 5, 20,170, 84, 9,147, 82, 20,148, 80,149,197,196,196,118, 30,213, 88,202, 89,109,204, 19, 47, 71, 11,113,121,170, +243,145,110,181,187,116, 20,116, 55, 90, 73,142, 98, 51,113,151,132, 6,231,150,135, 2, 95,186,180,113,207,111,190, 1,207,244, + 72, 58, 71, 86, 1, 89, 9,146,132,163,183,149,244, 96, 36,105,229,162, 51,208,153,168, 29,236,197, 89, 50,102, 43,174,108, 71, +187, 95, 31, 21, 88,253,137,155,132,223,122, 3,222,202,232,107, 91,234,107,174, 50,201,198,110,151,151, 87,112,179, 35,254,171, +103,240, 51, 80,191,180,131,175,102,116,173,240,114,111,202,238,231, 18,114, 21,169,159,222,193, 42,209,255,190, 35, 86, 63, 80, +216,239, 21, 93, 51,141, 74,143, 3,156,127, 44, 34, 79, 7,248,197,193,172,110,191,255, 12,118, 22,201, 74, 16,228,102,178,209, +255,109,133,243,155, 16, 62,100, 93,120,184, 9,225,169, 39,187,244,122, 1,187, 63, 13, 15,190,108,190,232, 22, 26, 81,253, 96, + 31,130, 57, 10,190,224, 5, 73, 4, 62,126, 4,223,116, 2, 55, 79, 92,184, 56,194,171, 87,212,127,252,144,252, 19, 23,148,247, +246, 20, 10,122, 44, 12,207, 89, 23,180, 27,224,170, 8, 67, 54, 81, 98, 46, 77, 79,161,211,152, 76,174,145,226, 68,231,239,221, +193,223,135, 89, 43,201, 98, 52, 27,212, 86, 81,210, 71,226, 81, 34,220,233,168,247,178, 21,168,209, 44,161,166, 65, 83,116,112, +193,165,135,233, 72,115,123,104,157,226, 81, 29,131,232, 24, 66, 87,217,150,132,230,136, 60,243, 24, 78, 71,123,237,106, 28, 51, + 83, 71, 61,111, 35,249,240,146, 11,220,178,145,233, 16,251, 44,186,151,252,240,222, 64,189, 15,225,212, 14,113,241, 3,189,238, + 97,255,147,112,249, 23,209, 87,239,194,223,233,208, 95,175,148, 71, 27,246,101,207, 59,125,224,113, 49, 81, 90, 87,175,225,114, +181,137,184, 28,208, 82, 57,200,179,182,173,196, 98,188,216, 68,117,141, 75, 46,193, 18,186,130,143, 73,115,165, 76,119,199, 98, +252, 12, 17, 74, 8, 83, 20,166,196,142, 81,173, 64, 75,177,253,206, 74, 47,144,162, 48,146,168, 90, 25,198,226,147,130,106,102, +219, 73,143, 36,104,148,137,120,214,196, 82,234, 2, 91, 59,204,108,175,153,105,163,247, 67,251,211,212, 37,234,236, 5,111,112, +175,176,112, 39,142, 13,156, 35, 70,136, 11,170,142,180,181,217,136,184,112,175,168,146,107,246,149,103, 90,246,155,214, 43,235, +204,254, 40,205,119,221, 60,245,142, 63,181, 32, 23, 83, 2,152,191, 59, 80, 67,128,146,231, 0,173, 32, 7, 81,179,211, 89,182, +152,248, 79, 13,133,180,199,156,191, 43,213,133,216, 77,119, 21, 38, 40, 76,164,138,237,207,171,251,193, 39,128, 14,115, 74,153, + 46,166, 16, 19,112,198, 47,154,170,117, 18, 43,206,135,185, 28, 60, 47,185, 22, 19, 87, 93,144,221,180, 3,246,124,226, 12, 25, +107, 98, 72,173,211,107, 21,157, 3, 89, 38,157,153,179,118, 67, 48,103, 69,234,122, 98, 50,129,156,113,209,195,204,207,247, 21, +128,230,106,159, 69,206, 72,201,147,126, 99,186, 40, 22,232,220,131, 59, 77,173,132, 24, 38, 66,107,173, 94,120,186,142, 64,244, +152,152, 18,117,216,147, 82, 3,184,172, 86,200,214, 56,198,213,241,129,181, 56,131, 41, 4,106,173, 36, 42, 42,129, 18, 18,140, +197,184,234,178,172, 13,235,116,200, 23,183,122, 13, 26, 72,216,126,221,186,203, 74, 10,209, 88,187, 62, 22,210,108, 35,159,118, +129,183, 40,195, 57,185,196,165, 26,165,221, 49, 77,113,152,125, 60, 46,126,217,170,102, 24,118,232,234, 24, 66, 79, 25,242,132, + 45, 52,171,157, 3,105,220,207, 30,125, 7, 84,149,201,167,217, 10, 13, 27,171, 23,215,222, 69,255,146,251,151, 99,106,206,108, + 95,167,193,178,145,199, 4, 93,173,132,199,158, 6, 20, 65,119,131,141,184,143, 76,157,104, 82,122,236,228,243, 73,166, 4, 80, + 87,236, 75,172,240,203,143,208,199, 35,242,157,231, 70,112,147, 35,100, 5, 97,149, 44, 73,236,141, 13, 79,221,223,147,174, 70, + 86, 21,182,193,190,240,187, 98,194,190, 16,117, 2,101,108, 54, 74, 60, 75,132, 23,123,248,218,158,242,115, 27,234,171, 91,234, +222,118, 80,225,220,158, 83,120,184, 34,252,166, 99, 56, 10,132,223,113,138,124,234, 4,253,245, 45,250, 83, 87,232,175, 15,240, +116,178, 3,231, 27, 87,132,123, 10, 63,159,145,127,173,231,248,183,174, 24,126, 97,203,110, 29,136, 1,214, 43,225,164,171,232, +166,194, 47,110,145,231,142,144,239, 89,193,195, 66,109,201,110, 27, 69,198,140, 60, 4,121, 74, 29,170,178,247, 89,245,167,230, + 15,125,146,219,142,144,255, 11,244,205,159, 65,127,254, 41,216, 95,193, 75, 9,249,200,218, 90,192,161, 82, 63,243, 24,253,145, + 75,228,155, 59,228,119,156,193, 51,189, 21, 13,162,240,254, 99,120,235,138,250,163, 15, 25,254,209, 35,198,253,200,120,164,212, + 27,198,197, 47, 62, 97,106, 19, 15,116,206,176,143,190, 82,104, 73, 84, 50,225,141,231, 52,168, 70,172,122, 18, 11, 59, 31,232, + 77, 15, 39, 56,211, 32, 89,101,159,190,235,196, 24, 0, 63,125,105, 75,248,149,218, 3,150,122,200,239,144, 15,192,128,204,200, +197, 89,208, 94, 22, 23,233, 94,209,171,132,172, 55,144,238, 67, 93,249, 29,246,129, 29,210,113,109, 22,184,240, 28,112,195, 85, +244,209,160, 2,229,211, 80,223,128,240,113, 8, 31,118,209, 98,111, 7,123,125, 7,182,127, 17,222,255, 41,248,172,194,223,238, + 41,239, 12, 84,221, 83,135,145,247, 84,120, 80, 12,204, 20, 38,244,154, 78, 55,218,162, 51,155,187,202,161,227,174, 69,151, 4, + 87, 92,151, 3,221,190,225, 84,107,181,158,180,180,213, 71,227, 40,199, 64,223,117,212,216,145,165, 30,120,248, 99, 16, 84,122, +118, 73,145,154,161, 20, 6,133, 53, 66,167,176,209,226, 26,154,138,113, 41, 27, 62,180,250,152,211,198,199,227,242, 0,209,150, +222,216,196,124,206,218,104,236,240, 41,172,190,241, 54, 60, 75,162, 69,167, 10, 7, 8,214, 54,114,173, 30,117, 59,205, 45,170, + 31,136,106, 26,158, 70, 36,203,126, 31, 99,234,148,195,100,223,106,241,172, 58, 1,117,234,244, 24,149,153, 86,215, 16,185, 85, +109, 20, 47,238,215,174, 33, 24,154, 82, 14,125,246,211, 52, 64,229,112,188,189,236,128,213, 58,178,160, 97, 66,133, 79,238, 40, +153, 81,174,109, 74, 81,180, 26, 55, 96,194,204,206,241,163,117,242,207,207,128,247,150,174,215,212,231,162, 79, 82, 24,194, 18, +157, 35,215, 88,246,117,246,228, 91,164,184, 77, 52, 74, 91, 85,120,192,205, 65, 17, 26, 22,253,125, 43,102,166,244,210, 72,234, +123,186,174,119, 49,184, 18, 98, 71, 70,168,227,222, 14, 95,127, 14, 99,173,228, 60, 82,134,189,185,184, 66,242,247,184,248, 22, +120,214,115, 89,140, 74,123,205, 97,242,185,183,198,146, 20,209,156, 41,165,178,221, 94,145, 67, 96, 63, 12,164, 20, 59,111,241, +213,186,219,106,177,163,141,117,156,146, 1, 28, 98,176, 14, 66, 99, 68,170,197,217,213, 54,162,152, 30, 37,216, 27, 28,231, 10, +174,138,121, 32,155, 80,200,130, 94, 44,231,188,186,221, 65,163, 3,245, 75,157, 50,117, 39,133,102,157,191, 64,211, 93,209,237, + 46, 89,231,184,213,218, 72, 45,227,136,110, 47,225,252, 54,116, 61,100,131,229,215, 92,201, 49,146,212,137, 83, 65, 39,157,187, +150, 58,101,210,106,177,113, 75,117,197,163, 42,196, 46,162,163,117, 51, 86, 95,206,233,110,197, 59,175,236, 35,251,146,188,170, +186, 28,124,122,227,126,255, 65,141,202,214, 88,179,155,106,255,174,130, 30, 69,219,191,203, 96, 35,172, 46, 33, 95,188, 68,223, + 31,144,239,189, 1,183,122,171,218,215,230, 51,231, 40, 17,222,220,112,254,254,150,245, 85,102,179,169, 36,179,148, 51,250, 55, +180, 97, 52,143, 69,233, 95, 76, 48, 8,250,238, 72,189, 59, 80,182,153,242,104,160,236, 43,188, 5, 41, 6,210, 88,208,167, 42, + 18, 58,164,235,144,103, 34,225,251,158, 34,124,104,133,254,245, 7,232,207,239,145, 99, 75,253,138,223,217, 67,237,209, 87, 71, +194, 55,175,184,241, 78,134,119, 10,199, 47,219,106,100,247, 0,106, 81,228,161,114,186, 26,205, 74,182,142, 86,133,237, 44,204, + 69, 87,126,210,237, 18, 50,220,133,245,175, 64,252,148, 29, 46, 7, 55,138, 45,228,255, 26,238,253,159,240,206, 29, 8, 17,253, +226, 6,126, 13,228,247, 43,188,176, 66,223, 25,224, 65, 65,254,189,115,228,165, 35,187,216,135, 17,253,220, 35,244, 11, 27,244, +231,183,232,227,129,124, 57,176, 61, 86,118,119,132, 18, 13, 35, 28, 93,184,217,186,197, 36,126, 67, 13, 66,245, 21, 75,194,166, +219,105,113,107, 8,213,133,155, 81,231,200,202,131, 96,137,197, 89,219, 20,242, 78, 86,164, 11, 72,242, 17,234,231,183, 6, 24, +106, 15, 62,122,135,144,117, 78, 71,235, 13,156, 68,100,202, 61,111, 48, 37,250, 86, 40, 70, 88,123,194,220, 58,192, 13,129,155, +138,156, 84, 72,199,190, 15, 31, 93,252,182,130,248, 60,196,143,184,138, 29,251,247,186,247,101,254,235,160,239, 64,248, 46, 8, + 47,248,201,220,217, 62,189,252,125,120,240, 23,224,213,247,224, 31, 28,161, 63, 87, 40,247, 47,201, 12, 16,225, 74, 42, 27, 17, +122,175,100, 10,106,156,139, 50,231, 23,132,133,204,110,178,194,251,141, 50, 46,118,181,130,121,131,181,250,132,162,141,140, 29, +253, 42,205, 99,238,225, 43, 72, 36, 83,205,226, 26, 93,240, 80,237,251,152,213, 52, 29,251, 34, 28, 33,244, 65, 24, 71, 43,202, + 59,143,131, 78, 10,217,105,150,118,178,130,134,234,158,103,123,156,224, 66, 39, 60,189, 18, 9,212, 58, 31, 32, 19,208,117,154, +234,232,188,187,157,176,172, 58,105,121,116, 17,200, 52, 1,165, 60,123,155,150,139,238,247,196,222,239,153,123,135,158, 36,148, + 85, 8, 38, 82, 93, 36,142,225, 65, 38,202, 50, 3,124, 81, 28, 9, 7, 33, 46,147, 31,218,237,149,145, 22,121,141,211,206,230, + 63, 39, 58,239,150,155,186,125, 74, 86,211,217, 15, 97,112, 26, 83,124,183, 69, 90,157, 86, 17, 76, 35,166,230,181,111,106,248, +166, 15,154, 18,206,196, 83, 60, 23, 95, 48,245,184,213,170,242,129, 96, 27, 89,144,255,166,195,119, 9,196,241,209,188, 44, 2, +105, 74, 45,102, 9,212,185,234,156,106, 50,239,236, 9,130,106, 88, 92,180,243,234, 97,154, 34, 85, 53, 42,107, 12,204,177, 34, + 58,177,218,171, 86,234, 56,160,197, 10,181,144,226, 20, 26,163,186,180,142,250,160,192,195,196, 66,180,230,187,122,113, 28, 36, + 26,136,199, 63,151,113,204,236, 31, 61,162,106, 37,133,245, 17, 73, 34, 82, 50,101, 40, 86, 37,165, 96,254,237,104, 4, 31,138, +120, 60,106, 68, 37, 34, 82, 92,153,222,217, 94,203, 69, 64, 97,162,192, 57,213, 73,109,247, 93, 5,118, 85, 8, 42,244,209, 76, + 28, 34,145,168,193, 4, 2,190,139, 41,193, 71,253, 50,239,154,236, 12,143, 19,127, 94, 91, 23,189,192, 57,106,219,211,212,130, +146,209, 97,131, 12, 71,196,245,154,186,223, 88,112, 72,187,216,171, 17,228,168,205, 63, 25, 27, 56,221,110, 28,174, 19, 8, 14, +147,146,166,156, 12, 2, 53, 17, 53, 19,220,151, 27,131,117,233, 19, 39,190,141,140, 4,106,118,191,161,231,212,139,131,119, 44, + 30, 15, 24, 10,186,115, 11,156, 67,189,216,153,168, 79,131,143, 97,223, 82,244,199,222, 71,190,247, 28, 62,180,182,223,179, 62, + 37,156,119,200,121, 71,120,167, 35,222,221,177,186,187,101,253,190,169,100,183, 29,228, 44,148,193,178,175,207,179, 18,146,193, + 31,180,250,234, 98, 13,108,148, 77,134,161,135,117,174,156,189,177,183,130,225,134, 34,231,106,153,231,177, 67, 62,245, 52,116, +145,252,191,221, 71, 63, 55, 32, 47, 20,248,214, 53, 60,219, 35,143, 20,121, 92, 8,223,220,115,246,238,142,205,219,202, 24,141, + 91, 0,214, 8,174,223, 43,196, 95,218,192, 55,120,138,155,122,235,219,251,183,248,235,247,225,165, 45,220,124,121,113,160,183, +255,189, 11,143,126, 47,250,107,175,195,163, 59,104,238,225,217,130,252,174, 53, 60, 2,189, 28,225, 45,247,125,127,247, 49,218, + 43,245,253, 45,124,246,146,250, 75, 87,212,207, 95, 81,114, 65,215,166,252,223, 63, 5, 67,177,195,188, 22, 79, 5,140,246,249, + 44,181,220,173, 99, 10,206, 16,138,101,246,212, 78,117,165,216,181, 30,220,130,213,156, 78, 97,177, 71,159,226, 62,197,214,212, +161, 11,200, 73, 64, 86,173,184, 83,202,206, 15,160,233, 64,159,184,200,118,129, 37,207,183, 79,214,221,131, 32,235,232,225, 8, + 1,142,146, 77,125, 78, 35, 28, 3, 55, 4, 57, 83, 56, 21, 88, 29,217, 11, 79,183,236,195,232,111,154,205,173,255,152,113,218, + 57,245, 7,219, 45,138,168,106,214,192,248,145,197,171,233, 64,239,195,240, 87,224,241,223,129, 71, 61,124,246, 57,248,177,251, +148,225,130,139, 50,146, 83,165, 11,194, 85,181, 55,232,200,183, 79,251,114, 56, 60, 96,138, 71,101,130,184,168, 23,230,178, 56, + 56,166,184, 73, 13,196, 24, 45,118,213, 3, 84,130, 31,246, 34,129, 46, 68,136,137,189,239, 50,181,206, 4, 58,123, 45,205,141, + 34,148, 97,100, 19,224,184, 15,172,251,142, 34,133,172,133,149, 42,125,234,216,102, 83,194,219, 87,221,233,147,174,249,105, 54, +174, 66, 99,168,227,205, 4, 51,231,162,221,228, 61,134, 90,117, 30, 5,215, 41, 52,196, 44,104, 85,213, 59, 67, 31, 84, 47, 98, + 83,179,119,167,145,246, 62, 68,178, 39, 97,118, 46, 18, 30,171, 34,165,208,123,183, 57,122,217,179,220,173, 87, 14, 19,185,194, +193,129,207, 4,227, 82, 14, 61,218,226,186, 77,117, 59,224,148,131,206,161,248, 76, 88,118,146,203,213,138, 29,215,185, 90,166, + 69, 84, 87,170, 95,147, 23,182,169,193,116,152, 45, 60,255, 45,144, 85,150,113,109,141,132,215, 20,234, 11, 1, 31, 83, 97, 40, +147,198,225,218,208,108,154,194, 46, 48,250, 11,144,216, 34,179, 67, 23,133,166, 78,193,163,243,195,180,157,182,200,140, 43,111, +239,163,235, 27,198, 90, 25,114, 70,179,175, 49, 66, 56, 76,152,243,224, 32, 98, 68,115, 49,161,234,193,194, 64,124, 13,189,120, +237,237,222, 83,235, 36,142,211,206,184, 22,101,204, 30, 61,174,164,213,241, 9,186,189, 66,179, 7, 10, 6,191,168,170,219, 78, +166, 91,147,221,217, 74,173,232, 88, 38,104, 12, 33, 32,181, 26,115, 69,131,193, 94,124, 76,144,164, 41, 59,133, 93, 49, 59,217, +105, 80, 86,238,225, 84,196,246, 15, 98, 34,138,152,140, 24,167, 11,196,160, 86,183, 72,136, 39,224, 76, 41,102,117, 38, 55,233, +194,154, 80,179, 65,102, 54, 87,132,227, 99,143, 83,181, 74,168, 22,179, 60,164,201, 59, 99,193, 6, 85,198,137,241,107,182, 59, +199,220, 98, 17,136, 97,204, 62, 94, 51,156,100, 40, 77,188, 3, 71, 94,117, 71,247,139, 51,248, 23,187,200,196,218, 22, 92, 97, + 37, 9, 57, 78,230, 55,219,169,101,176, 55, 37,180, 10,172, 34,122,229,169, 88,158,217,203,152,209, 31,122, 96, 35,229, 79, 30, + 91,152, 74,232,224,230, 41,225, 78,143,124,245, 10,237, 18,221,217,192,201,253,145,171,135, 35,195, 94, 73, 43,161,127,161, 35, + 92, 65, 60,239, 77,160,246,110,153,124, 67,233,169,192,106, 95,216, 1, 67,103,112,139,248,245, 61, 50,122, 91,121,222, 89, 2, +218, 94,224, 83,183, 9,111, 12,232, 63,124,136, 94,140,212, 55, 6,194, 55,245,240,114, 7, 87, 2,151,145,213, 11, 9,121,144, + 25, 70,216,111,236, 61,232,147,216,254,114,155, 33, 20,180, 75,150,226,117,100,221,147,254,210,125,228,119,141,112,231, 71, 64, + 62,230, 95,231, 2, 92, 65,253, 73,120,244,159, 81,255,222, 61,244, 87,206,224,163, 32, 71, 14,188, 81,191,229, 5,177,160,132, +168,232,151,175,208,127,190, 67, 63,125, 69,253,250,158,172,149,253, 49,228, 83,161,246,126, 30,148, 25, 96, 17,188,190,136, 1, +186, 84,173, 35, 84,123,235,139,206,169,171,147,216,181, 66, 8, 11,210,161,219, 7,251,100,162, 80,170,219,214,220,131, 27,162, +185, 52,162,143,140,195, 81, 64,250, 72, 88,205,211, 44, 13, 62,150,109,126, 46, 89, 94,151,157,237,221, 99, 64, 66,180,239, 97, +114,241,215, 73,103,234,247,211, 8,103,201,186,242, 27,138,156, 0,235, 35, 72,103,166, 77,144, 51,243,153,167, 59,144,158,131, +245,135, 76, 5, 79, 0,125,108,246, 54, 81, 59,248, 57, 95, 20, 83, 14,162,105, 98,184,225,215, 96,243,231,224,237, 47,192,120, + 11, 62,249, 73,120,248, 14,250, 63,189,205,101, 44,188,151, 44,161,172, 43,202,174,161,226,125,147,144, 69,200, 69, 15,184, 55, +115, 7,211, 50, 31,116,194,216,212, 41, 0, 67,124, 59, 14, 65,170, 89,191, 8,196,100, 83,195,210,226,152,221,121,209, 2, 87, +138,183, 87,181,180, 67, 66,167, 81,116,136,145, 81,148, 44,182,211,237, 98,162,184, 37, 53,185, 79, 61, 54,215, 2, 66,141,201, + 83,207,124, 52, 91,171,169,224,253,167,230,101, 60,137, 28,118,235, 65,130,143,185,231, 40,147, 38, 62,171,126, 48,239,171,122, + 6,187,122, 34,152, 28,168,218,167,219,131,107,101,178, 90,119,110, 93, 95,157,126, 22, 46, 98,230,218, 39,200, 98,245,211,108, +175,109, 47,222, 92, 7, 34, 76, 74,247, 54, 54,168, 54, 82, 93,104,159,154,208, 78,184,182,158,158, 15,201,133,146,159,105, 74, +128, 35,198, 93,189,238,135,110, 8,243, 61, 92, 39,106,155,167,116,186,247,218,104,110,243,251, 49, 5,186,136,240, 27,129,103, +101,202, 65,208, 3,235,153,180,201,192,162,112,106,235, 52,245, 85, 7, 77, 27,225,110,149,133,202,117, 46,104,244, 80, 92,215, +188,255, 33, 70, 27,187,187,123,160,164, 72, 25, 51,227, 56, 82,115,182,255, 86, 50, 99,206,118,128, 79, 79,172,165,144,150,249, +249, 74,120, 34,158,182, 58, 69, 44,196,100, 76, 17,181,213,120,208,138, 44,180, 0, 37,103,219,169,215, 16, 32,143, 84, 7,181, +104, 72,211,158,202,200, 69, 62,250, 86,235, 94,165, 24, 11, 87, 9, 14,173,113,177,128,122,118,172,218,191,139, 2,201,131, 5, +134, 10,151,106, 30,203, 49, 11,103,181,114,220, 85, 58, 23,178,168, 86, 98, 52,251, 66,116,158,123, 45,150,201,158, 21, 36,216, + 7, 92,171,179,158,235, 60,158, 16,175,226,202, 34,115, 92, 90, 84,217,110,103,245,158, 68, 6,132, 84, 44,220, 64,156,158, 38, + 30,213, 18,180,237,173,156,192, 68, 0, 49,117,126,168,115,110,124,213, 66,209, 98,227,247,160,116, 10,171,160,164,150,149, 92, + 43,177,120,142,118,182,238, 42,164, 0,103, 9, 89,247,200, 89, 79,184,213,219, 73,242,200, 15,216,206,191,182, 33, 66, 18,164, +207, 86, 16, 36,133, 99,144,236,111,200, 23,247,246,154,190,249,196,232,105,157,125,192,210, 41,242,237,103,240,172, 16,254,242, +187,156,111,182,212,111,239,144,111,137,112, 30,208,183, 33,156,247,200,211, 43, 27,251,190, 57, 34,111, 14,240,116,199,209, 83, + 80,238,154, 85,102, 92, 65,218, 42,221,151,118,132, 43,129,103, 87, 30,107, 84,225,228,148,240, 61,167,148, 31,127,159,225, 94, +102, 4,250,183, 6, 86,159,236,145,111, 95,193,135, 35,220, 57,162,191,165,244,247, 10, 71,239,142, 48, 40,225, 56, 33, 47,184, + 5, 43, 86,194,169,199, 27,254,244, 30,254,233, 37,225, 63,137,200,239,249, 25,139,232,212,183,160,252,143,112,241,195,176,191, +132, 55, 31, 81, 95, 59, 66,223,191,141,202, 0, 95,221,216,238, 57, 26, 61,150,155, 25,221, 43,250,245,130,126,102,143,190,177, + 7, 45,232, 80, 24,110, 91,248,205, 85, 17, 6,231,166,148,169,203, 54, 81, 37,165,241,188,253, 35,192, 10,186, 58, 90, 45,213, + 71, 87,189, 86,216, 50, 31,214, 49,120,135,239, 81,183, 93,139,237,141, 11,158, 67,243,173, 7, 63,216,215, 17, 57,142, 72, 10, +150,111, 30,197,161, 29, 77, 5, 38, 83, 28,174, 4,239,196,171,255,254, 46,152, 83,226,168,141,215,163,225,112,111, 36, 11,230, +185, 89,145,227,206,186,112,185,227,201,109,167, 86,248,201,202,118,231, 97,109, 95,152,253,219,144,191,104,246,191,238,196,120, +239,241,195, 24,132, 64,175,233, 1,142,237, 34,222,254, 67,184,252,139,112,247, 61,248,251,103,240,106,129,151,127, 21,126,242, + 33,251,163,145,141, 10,161,216,186,103,159, 29, 81,188,192,133, 73,157, 53, 64,149, 3,151, 25,193, 15,152, 16, 26, 81,140,105, +181,213, 66,149,113, 59,109,139, 16,213, 24,168, 14,165,114,123,243,116,191,202, 42,140,213,116, 52,105, 33,178,147, 48,231,190, +103,132, 1,101,237,196,185,145, 96,156, 1,129,148, 28, 93, 45, 70,147,179, 78, 35,206,168,212,169,251,151,233,218, 97, 81,140, +232,162,167, 93, 56,162,167,169, 99, 11,129,106, 74,119, 93,140,127,171,205,250, 29, 84,237, 13, 99, 75,100, 19, 35,206, 53, 38, +134, 53, 40,149,229, 64, 90,150,121, 26, 11,205, 66, 83,113,215,101, 51,218, 16,178,110, 49,107,216, 85,213, 37, 36,102,142, 85, + 21,117,209,180,204, 14,165, 89,229,160,211, 6,246, 58,102,118, 58, 99,219,136, 58,196, 41, 30,183,141,155,117, 10,192,209, 73, +151, 34,110, 13,107,153,241,217,223, 12,113,168,153,203, 0,103, 24, 16, 51,235,126,122,253,122,189,250,144, 39,116, 27,211,140, +125,249,201,181,169,192,245,156,214,169,188, 10,215, 52, 4, 78,114, 11,134, 33,111,159, 75, 46,133, 60,142,144, 51, 37, 6,242, + 80,125,170, 45,211, 25, 37, 49,249,103,173, 31,152,204,176, 84,232,171,182, 41,114,227,196, 87,234,110,231,127,222,194,102,106, +206,214, 96,151,171, 43, 34, 80,134,189, 85,167,109, 23, 24, 45,103,120,168,130, 72, 66,130, 82, 69,209,209,222,224, 16,150, 11, +177, 64,168, 38,143, 75, 33,210, 7,165,147, 74,114, 17,218, 14, 97, 32, 80, 37,240,184,140,140,217,110,106,103,189,154,162, 47, + 87,131, 86, 77,193, 8,139, 16,248, 86, 14, 21,157, 2, 21,108,121,163,147, 14,198,200, 64, 50,121, 12,147,102,235,216, 71, 69, + 71, 47, 86,154,154,180,120,209,182,234, 8, 65, 72, 37,179,119, 37, 97,237, 92, 27,226, 31,125,169,133, 36, 74, 23,231,125, 79, + 42,150, 96,154, 4, 86,162, 28, 85,123,157, 93, 7,233,104,109,157,184, 84, 24,253,210,139, 17,233, 59,194,113,135,220, 94,193, +211, 61,220,116, 96,198, 17,112,190,114, 82,140,211, 74,210, 76,194,146,222,239,130, 21, 83, 39,143,126,154,172, 86,112,162,112, + 30,108, 79,159, 43,124,105, 15,223,120, 78,248,195,183, 8, 73,169,191,112, 65,249,185, 29,114, 59, 33,191,169,135, 59, 61,236, + 32,172,123,232, 71,116, 45,196, 79, 68,206,227, 72,125, 63, 83, 51,232,168,112,165,132,103, 10, 60,151,204,219, 93, 48,218, 92, + 16,234,174, 50,174, 97, 60,134,237, 80,233,126,105,207,234, 11, 35,171, 23, 35,225,153, 72, 40, 86, 69,134,103, 18,108, 10,114, + 81,208, 87, 43,250,213, 10,239, 85,194, 43, 91,120,170,135, 31,187, 36,252, 91, 71,200, 31,251, 69, 8, 47, 3,159,135,171, 63, + 3,175,125, 22,174,214,112,117,130,126,253,182, 17,212, 62, 86,224,215,246,102,200, 47,198,170,215, 17,244,211, 25,125, 59, 79, + 86, 16,206, 93,224, 56, 42, 57, 43, 67,129,161, 10,251,106, 10,246,216,108,103,136,173,161,219,247,182, 65, 95, 80,198, 97,206, +166,206,121, 70, 34,247,190,102,235,130,155, 59,163, 76,171,236,118,208, 55, 2, 99,240,206, 60, 85,136, 71,226,233,120,177, 45, +235,231, 4,176,150, 12,213,130, 45,130,229,204,227, 35,122,186, 56, 31,230,199,190, 39, 63,241,148,189,227, 0,103, 1, 57, 77, + 54, 90, 15, 47, 66,184,227, 29,119, 48,235,153, 14,160, 15, 77, 20,167, 91,211, 38,232, 8,113,231,123,248,223, 6,225,121,195, +234, 82,175, 29,232,103, 70,151,219,252, 8, 92,254, 85,120,253, 33,252,196, 26,253,149, 29,188,183,163,252,220, 72, 62, 42,108, +162, 82,139, 77, 48,182,197, 14,244,206,117, 90,131,241,115, 60, 35,188,137,102, 27, 22,148, 73,196, 5,134,156, 22,119, 17,132, + 96,123,100,170,131,155,238,211,161, 0, 0, 32, 0, 73, 68, 65, 84, 64,162,141, 83, 99, 20, 74, 13,211, 1, 32,110,239, 82, 31, + 25,183, 3, 52,250, 77, 62,133,214, 65, 51,219,145,252, 16, 41, 85, 61,167, 69,201,181, 48,168,208, 5, 33,117, 29,195, 62,219, +222, 59,248,190,179,206, 24,214,134,146, 86,149,169,145, 99,146,191,233, 34,203,125,217,214,233,148, 92, 86, 23, 89,218, 58, 69, +212,203, 19, 19,226,218,124,251,202,193,161,215,242,219,155,128,108, 57, 25, 72,162,140, 42, 19,244,165, 49,224,218,204,165, 89, +196,240,206,183,137,249,106,117, 13,194,188, 61,246,131, 59, 76, 66,191,233, 39, 42,215,152,103, 76,107,137,235,147,238,230, 4, +104,192,176,105,182,208,136,156,122,216,250,198,107,195,231, 40, 1,124, 29, 43, 83,244,173, 16,157, 35,175,147,150, 74, 38,106, + 30,215,222,247, 67,233,187, 30, 88,197,130, 44,156, 17,238, 94,208, 3,164,203, 82,137, 62,199,243,204,187,125, 47,112, 66, 32, +197, 8, 41,146,139,149,162, 20, 15,134,114, 7, 65, 85,165, 14,123, 7, 75, 89, 19, 27, 16, 72,105, 70,251,202,147,150,185, 58, +137,242,100,222,253, 23, 75, 20,109,137,164, 90,236,139,214,108,115,150,149, 48,108, 8, 88, 43,175, 97, 49,191,143,193,176,162, + 68,232, 19,253, 88, 24,181, 46,170, 47,231, 39, 43, 22,192, 42,133, 24,132, 30,101,133,135, 37, 68,171, 94, 70, 21,207, 50,182, + 96,149, 29,133, 71, 85,144, 26, 56,150, 66,172,206,203,245,177,199, 18,141, 23,189, 34,158,173,158,179, 88, 78,252,102, 91,180, +117, 0, 58, 5,179,212,113, 68, 58, 87,212,215, 98, 69,135,180,189,164, 95,196,238,151,213,226,226,151,209,146,233,218, 27, 29, +155,213,164, 42, 41, 84,122, 79,216, 89,229,194,170, 22,142,214,145,208,175,144, 62, 34, 39,157, 47, 18,131,135,198, 8,114, 35, + 34, 31,238,145,143,218, 14,154,147, 14, 57,238, 97, 45, 77,160,234,207, 35, 88,132,101,219, 1, 54, 16, 72, 12,254,247,213,246, +154,102,206,132,205,222,198,175,201,199,252,247, 7,120, 54,193,119, 61, 11, 99,134, 47,220, 71, 63,159, 77,124,119,183,160,191, +186, 71,190,123,109, 29,224, 71,143,136,157, 93, 12,102, 87,235,136, 31,170,200,251, 25,222,203,132,167, 35,242, 45,107,116, 23, +224, 67,182, 38,208, 55, 46,237,231, 70,227, 55, 23, 49,152,199,246,168, 18,179, 34, 95,206,244, 95,177,241,115,106, 14, 89,129, + 85,179,125,136,216, 77,246, 11, 35,250,222, 64,248,115, 79, 33,127,252,103,129,167,129, 31,128, 87,255, 43,248,220, 37,244, 47, + 66,159, 44,251,124,191, 71,190,190, 71,191,184,135,127,190, 67,206, 61,254,187,171,232,215,246,148, 77, 38,244, 98,182,185,211, + 96,231,216,227, 98,167,117,117,173,217,168,236,139,117,116, 37,205,234,172,208, 34, 2,188, 30, 24,124,250,211,196,114, 45, 94, +184,237,197, 59,177,115, 80,130,144,130,176,118,125, 90,195, 93, 6,207,155, 9,170,196,206, 22, 86,210, 7,130,195,133, 32,248, + 90, 71, 17, 49,163,123, 8, 29,114,228,122,149,147,104,127,127, 28,237, 16, 95,118,230,235,100,191,246,254, 36, 82,132, 35,207, +109,145,115,144,167, 45, 43,157, 0,122,215, 44,104,229, 93, 35,236,141,123,179,158, 9, 70, 29,234,206, 29, 88,243, 10,116,159, +130,240,177,165,100,205,111, 92, 39,230,131,188,252,126,184,250,187,232,219, 27,248,241, 21,245, 51,151,212,171, 29,101, 28, 25, +206, 96, 95,117,234,204, 7,204,194,154,125,234,209,182,180, 3,230,187,214,121, 51, 63,127,125,151, 93, 73, 85, 71,116, 54,157, +210,116,131,177, 34, 92, 22,126,104,177, 79,133,224, 98, 50, 79,121,100, 49, 30,174, 46, 20,109,123,226,168,129, 18,116,138, 11, +221,187,106,189, 96,130,224, 65,173,169, 72, 65,144,148,108, 69, 71,240,192, 24,235,142,100, 33,222, 42, 7,254,109,249, 13,204, +207,135, 29,151, 52,250, 91, 59,168,219,222,240, 3,216,233, 19,203,125,250,213, 10,145,166, 4, 87, 79,245,106,247, 67, 93,184, +113,116,214,185, 79, 63,190,177, 63,196,225, 44,142,120,153, 49,165, 28,250,184,229,122,152, 75, 19,184, 29, 72,238,158, 92, 87, +135,246,126,136,175,168,130,184,206,170,229,189,215,137,229,160, 7, 73,237,135, 23, 68, 59,135,163, 55,117, 65,227, 68, 26,204, + 45, 65,109, 49,234,111, 34, 23, 93, 76, 10,130, 3, 44, 89, 20, 36, 83, 16, 77, 43, 54,124, 69, 98,133,210,252,103,117, 17, 46, +131, 28, 34,129,151,239, 82, 16,211, 10,196,190,183,207, 40, 23,186, 46, 77,175,173,113,254,107,201, 76, 80, 22, 92,135,147,108, +106, 81,115, 93, 88,216,150, 27,141,230,168,104,246, 88,243,168, 87, 85,231, 51,148,195, 93,192,226,127,169,147, 64,221,109, 64, +173, 43, 13, 25, 74,159,108, 20, 93, 70,250,213, 26, 77, 9,169,153, 16,162,209,217, 16,247,202,154,242,155,104, 57,234, 17,179, +137,105,157, 43,194,170,129, 82,125,119, 62, 85,169,194, 88, 3, 23,163,237,195,142,129, 35,153, 25,241, 56, 74, 82, 83,176,189, +243,193, 84,199, 15, 99, 17, 23,154, 96,143, 97,206, 77,243, 62, 86, 8, 20,116, 8, 83,158,123,208,106, 86, 22, 77,118, 65,228, +108,157,145,152,167,187,226,226, 19, 45, 19, 23, 56,106,229, 40, 20, 86, 10,235, 82, 89, 69,219,159,166, 8,225,244, 24,185,177, +134,216, 25,187,247,118,130, 91, 43,228, 27, 18,242, 98,111,232,170,179,118,247,247, 86,193, 99, 35,101,111,109,160,142, 62,163, + 44,121,142,241,139, 97,170,215, 37,233, 34,218, 40, 79,156, 95,146,251,145,239,123, 23,255, 77,231, 70, 21,123,123, 3,111,109, +225,205,108,135,202, 55,174,224,202,231,199,167, 9,158, 62, 65, 62, 60,192, 93,179,152, 73, 86,244, 42, 19,200, 6,250,120,144, +237,241, 54, 88, 90,217,203,138,110, 7,216,102,120, 46, 18,110, 37,194,189,236,196, 44, 33, 38,140,227,223,195, 46, 40, 65,133, +152,161, 31,132, 94,160,123, 54, 18,110,122, 96,203,187,138,190, 85,144,191,252, 2,242, 7,126,220, 78,232,242,167,208,191,253, + 15,224,255,222, 35,127,248, 25,243,233, 63, 30,224,113, 65, 94, 29, 96,159,145, 80, 96, 45,240,187,142,209,143, 71,234, 95,123, +200,120, 53, 50,220, 48, 50,213,209,101, 33,186, 60, 93,179, 82,163,227,234,221,250, 63,125, 41, 42,132,100,116,178,236,133, 99, +241,183,122,159,231, 47,241,164,187,137,134,120, 21,119, 32, 70, 21,250, 40, 28,175,236,233,180, 80,165,246,179, 37, 6,130, 31, +188, 33, 69, 36,137,117,219, 94,156,137,128, 28, 91, 55, 46, 55,146, 21,151,167, 6, 23, 98, 21,225,212, 59,240,174,253, 21,109, +197,210,166, 55,147, 95,205,219,207,173, 64,122, 12,241,210, 57,237, 21,202, 6,198, 1, 46, 10,186, 43, 48,216, 40, 65,206,139, +105,226, 66,129,227,151,224,228,143, 64,252,168,247,112,121,113, 99, 56, 50, 46,252,229,247,195,197, 15,160, 95,223,195, 47,246, +232,215, 55,148,205,150,188, 29,216,139,133,177,236,178,125,246, 89,241,112, 33, 59, 72,246, 62,161,204, 24,191,161,168,255, 55, +209, 39, 18,185,166,219,165, 26,164, 35, 53,160,138, 50,167,162,249,216,181, 28,160, 85,156,161, 63,221,106,101, 78,134,244,174, + 94,170, 78,129, 32, 18, 70, 68, 83, 91,128, 50, 38,181,131, 34,152,226,187, 58,164,101,138, 34, 85,223,161, 59, 66,118,138, 95, +246,155,108,156,116,219, 50,251,167,221,115,190, 28,115,139, 28, 18,161,102,240,204,108, 93,178,135, 91,236,170, 23, 10,242,210, +188,205,181, 58, 55, 67,158,136, 56,106,244, 66,157,212,232, 44, 14, 54,239,240, 68,166,209,122,235,206,181,221,111,166,177,183, + 28,216,191,116,138,138, 17, 22,121,130,139,254,188, 77,170,101, 33, 5,145, 73, 48, 58,133,221, 72,176,176,156,101, 62, 56,122, +173, 45, 93,140,205, 49,113,157,106, 91,193,120,129,224, 13,133, 77,108,245,144,238,230,159,203,162,138, 57, 40, 20,230,195, 92, + 28, 85,235,100, 59, 42, 37,143,211, 7,166, 7, 66,192,112,232,115,215,229, 13,194, 95,103, 8,164,174, 7,223,161, 7, 47,168, + 74,173,148,113,116,189,128, 80,243, 56, 75,241, 91,113,209,220, 99, 13, 25,187,136,232, 93, 86, 19,203,231,222, 86, 41,234,186, +138, 22, 44, 52, 27, 24,212, 53,215,170,212,253, 30,138,146, 66, 64, 83, 48, 14,139, 42,132, 72, 8, 43, 56,185, 67,208,187,148, + 97, 55, 17,126,218,147,193,169,111, 33,136, 21, 5,142,127,173, 46,182,219, 18,201,152,133, 77, 69,193, 51, 96,107, 8, 12, 88, + 20, 98, 27,254,172,181,177,151,153, 42,203,118,187, 13,139,100, 28,255, 4, 91,160,141, 61,213,106,119,226,226,234,210,128, 16, +194, 72, 80, 3,200,180,162, 67, 74, 38,104,165, 75,133,168,149,160,149, 30,165,196,202,152,149,162,129,132,178, 14,149,163, 92, +184, 81, 43,171,163, 72, 56, 90, 33,171,222,158, 93,151,144,167, 79,145,231, 86,240,145,136, 60,223,153,159,252, 52,218, 77,184, + 6, 59, 41, 46, 10, 20,219, 47, 51,142,222,145, 59,250,176,168,117,151,142, 18,108, 74, 33,233,252, 74,236, 20,237,189, 67,139, + 98, 45,144, 20, 7,214,248, 88,190, 84,228,169,149,253,243, 59, 87,240,206,222,126,239,135, 87,182,211,127,127,128,247, 28, 9, +250,176,194, 29, 65,110,223,132,103, 51, 60,222,193, 38, 35,123, 69,182,197,114,213, 95, 24,225,178,160, 27,144, 91,105, 98, 2, +176,182,195, 33,124,228,152,254,245, 29,117,173, 28,221, 14,236, 71,243,193,135,106,231,146, 65, 67,149,254,165,142,240,241,206, +146,222,110,116,240,154,194, 29, 69,254,210, 43,240, 45,255, 57,232,143,194,246,111, 80,255,252,235,232,255,181,129,111, 91, 17, +175, 54,176,141,112,175,216, 57,115,166, 22,179,121,187,131,239,232,225,118, 15,175,218,245,151, 49,166, 79,241,208,176,147, 17, + 75,106,219, 11,236,117,194,184, 30,119,106, 43, 81, 13,104,181, 3, 61, 70,157, 10,204,232,137,128, 34,243,232, 52, 6, 19,109, +166, 22, 95,235,149,230,186,192,185, 40,199,119, 58,195,156, 62,214,217, 99, 29,133,176,142,200, 42, 90, 23,208,251,232,220,173, + 86,178,142,214,177,159, 5,179,246,157, 68, 43,178,250, 8,235,222,244,104, 93,178, 41,131, 0,213,145,105,237,203, 61,248,139, +205, 62, 77,106,157, 83,103,215, 9, 97, 99,187,250,171, 10, 15, 76,204, 46,131,133, 59,112, 11,184, 37,176, 90,195,233,199,224, +236, 79,248, 30,125, 92, 28,232, 13,249, 90, 96,247,163,112,245, 35,232,215,118,240,211, 61,188,177,163,198, 17, 58,235,242,118, + 98, 5, 83,187, 65, 55,193,126,112,223,145,122,209, 81, 23, 55, 74, 93, 8,182,162, 46, 51,162,231,214, 68,157,160,156, 75, 75, +205, 50,252,175,136,154,112,183,221,216,196,108,162, 45, 61, 45, 80, 41,132,201,113, 33,109,108, 93,161,235, 44,172, 74, 67, 52, +139,153,119,139,121,180,123, 88, 23,152, 20,214,131,206, 1,166,170, 24,178, 84,237,177,169,213,247,236, 54, 14,142,186, 84, 96, +205, 42,106, 89,208,219,100, 1,213,154,125, 92, 58, 17,213,230,103, 59,171,210,235, 98,124,111, 41,117,117, 26, 87, 47, 69,155, +186, 80, 67,183, 20,184,122, 45,204,101,182, 5, 55,220, 45,147,186,187,237,208, 91,228,168, 54, 36,236, 2, 12,212,120,231, 13, + 62, 19,100,217, 88,201,148,228, 46, 44,214, 0, 45, 42,155, 5, 77, 79,196,155, 52,109,154, 96,158,192,166,201,226, 39,202,100, +116, 59,140,133,115, 54, 65,144,249,196,174,203,179, 91,159,156, 30, 28,132, 18, 78, 5,100,157,130,116,170,187,158,224, 16,121, +123,192,232,127, 98,172, 63,251,243, 83, 8,132,174, 51,110, 66,173,134, 38,111,171, 17,143, 90, 53,135,129, 57, 9, 38, 5,125, + 8,166, 87, 27,243, 34, 58, 87, 63,176,235, 22, 79,113, 19,241,235,183, 44,102, 37, 97,177, 0,210,185, 34, 75,101,183, 53, 37, + 93,176,202, 72, 17,142, 17,164, 10, 49, 38,234,249, 29, 88,223, 66, 30,223,179,145,168,195, 9,230, 74,211,252,157,161, 88,104, + 72, 12, 66, 45,202, 88,237,195, 25, 67, 48,223,115,181,185,127,104, 87, 92, 8,212, 40,176, 11, 92,234,124,137,172,211, 92,245, + 81,236,201, 70, 53, 76,167, 20,187, 33, 87, 22, 42,197,210,206,121,177, 17, 85, 81, 74,178,157, 81, 95, 42, 81,140,200,148, 68, + 45,155,151,202, 42, 64,143,141,222, 67,201,160,153, 85, 54, 59,217,145, 22, 11, 84,168, 74,191, 74,132, 91, 29,114,163, 71, 82, + 15, 39, 17,121,182, 67, 94, 57,134,151,143,204,129,181, 42, 54,219,221, 87,120,188,135,203,106, 92,245,109,129,139,108, 54,181, +156,189, 43, 87,216, 87,116, 91,231, 32,153, 93, 99, 84,187, 2,218, 85, 88,178,138,102,119, 91,187, 80,106,237,203,221,163,100, + 11,195,155, 9,110,119, 22,141,250,181, 43, 27,193,159, 4,184,217,193,170, 71, 86, 1,125,216,193,173,193,238,196,185,218,172, + 52,121,238,117,178,139, 66,212,161,220, 69, 32, 71,116, 95,236,181,108,178,165,184,157,118,246,252, 70,144,223,125,131,244,197, + 29,199,239,239,204,191,175,176,206,208,157, 11,221,179,129, 48, 6,228, 78,130,127,249,200,112,165, 95,169,240, 83, 25,126,199, + 57,252,201,239, 50,228,104,249,235,112,239, 11,212,127,255, 77,244,215,182,240, 50, 68, 6,248,210, 6,237,162, 93,156,125, 64, +143, 3,178, 86,244,178, 32, 95, 85, 88,101,228, 41, 69,190,169,163,191, 28,185, 26,149,156,218,238, 91,145,143,175,144,231, 43, +241, 51, 91,130,216,217,153,196,182, 20,217, 45, 98,181,218,205, 47, 10,238, 88, 16, 63,244,103,146,161, 49, 7,230, 6,171,238, +148,190,194,250, 36,210, 63,211, 17,158,237,168, 91, 8,217, 87, 51,209,132,109,114,154, 76, 12,231,159,149, 28,119,118,232, 30, +123, 8,203, 81,176,131,187,247, 78,188,217,213,130,216,225, 94, 60, 82,175, 41,206, 6,181,195, 60, 55, 72,183,211,255,170,139, + 58,214, 30,109, 53,184,152,242,145,194, 99, 95,252,223,173,246,223,110, 40,156,101, 56, 57,133,227, 79,192,249, 31,181,212, 54, +221, 93,215, 71,219,120,126,124, 29,174,254, 95,120,255, 1,252,114, 7, 95,217, 81,134, 1, 93, 87,116, 45,112, 97, 69, 78,240, + 46, 90,101,166,189, 37, 21,130,216,193, 63,137,249,195,242, 97,230,206,218,172,164, 11,131,182, 51,172,115,209, 9, 97,170,158, + 15, 95,107,157,178,194, 67,240,124, 6,223, 47, 74,245,238, 85,172, 25,168,254,178, 63,242,220,138,155,159, 92,241,198,103,246, +188,127, 81,124,124, 94, 45, 79,187, 40,187, 90,217,150,204,154,202,202,173,113, 85,210,180,188,157, 4,103,190,174,211, 18,230, +116,178,234, 25,220,254,138,150,203, 11, 75, 74, 20, 70,173,243, 14, 30,174,165,148, 57, 37,206,111,238, 85,231, 48, 16,220,206, + 86, 23,157,189,253,252, 25, 56,210,196, 98,211,143, 13,139,181,228,181, 49,246,172, 70,247,240, 22, 85,191,127, 51, 1,190, 84, +100, 10, 25, 65,231,144,154, 73,211,196,161,157,140, 15, 96, 32, 5, 93, 28,172,142, 5,151,224, 42,246,197,107,251,128, 13,197, +204,117,208,182,226, 14,211,163,197,246,222, 46, 55, 28, 65, 8,213,223,121,109, 2,105,157,131,104,132, 5,253, 78, 38,139,234, +245,157,143,106,153,247,208,215,153, 81,139, 85, 67,235,138,175, 63,251,136, 16, 83,111,231, 88,206,166,217,137,174,218, 47,254, +179,131, 57,169, 90,246,188,101,164, 87, 23, 11, 54,204,235,172, 73, 16, 62,112,181,110,254,248,166,220,215,107, 80,170,195,122, + 6, 69, 73,101,220, 59, 30, 85, 38,123,129,136,197,126,118, 93, 79, 89,157, 0, 3, 50, 92, 17,114,153,222,184,192,124, 17, 88, + 32,130,195, 26, 84, 60,179,216, 20,242, 69,172, 51,149, 24,145,148,208,253,206,170,174, 90, 93,228, 96, 4,151,189,127,217, 85, +108, 20, 31,124, 44,215,234,152,160,173,153, 85, 31, 66,250, 56,175, 6, 68, 44,114,177,182, 84, 31,111, 78, 35,133,236, 48,145, +136, 16,170, 29,242,157, 84, 2,137,144, 51,253,104,214,141, 85,115,237,118,145,176,138, 70,111, 59, 75,240, 82,143, 60,219,219, + 65,254, 97,239,176,130,139,211,246, 5, 30, 20,184,220, 91, 39,124,127, 64, 31,143,240, 40,163,155,193, 14,111,247, 71,105,167, + 70,225,219,120,183,229,162, 29,180,162, 67, 70, 51, 19,164, 67,146,141, 9, 37,185,128,185,239,144, 51, 59, 4, 36, 5,228,212, +199,253,247,147,253,172,205, 8,131, 88,112,204,152, 77,140,118,106,138,107,238,172,236,141, 73,192,123, 25, 61,222,120,124,152, +115,199, 31, 87, 19, 63, 14, 94,132, 60,168,232, 87, 6,155,196,124, 34,195,183,158,218, 52, 64, 45,247, 35,252,233,167, 9,119, +119,144, 11,233, 34, 35, 59,243,129, 51, 2, 23,216,110,127,155, 44, 72,229,103, 51,172, 87,240,239,124,204, 38, 14,227, 79,195, +151,222,166,254,145,175,145, 47,183,140, 31, 9,232,169,176, 74, 74,247,246, 30,142, 34, 37, 6,203,108,223,248,205,110, 47,200, +168,132,167, 34,218, 7,116, 29, 73,207, 70,214,111,101,198, 98, 89, 39,245, 82,137,239, 90,148,107,240, 14,156,208,232, 85, 83, +138,131,237,205,247, 54,110,236,188, 99, 8,213,173,152,174,242,149, 98,213,112, 21,144,226,129, 9, 79,247,132,143,174, 9,119, + 86, 48,184, 32,250,134, 21, 31,156, 70,228, 36,218,161,125,106,212, 61,214,193, 42,220,206,219, 65,137, 11,127,204,194, 0, 91, + 21,246, 2,143, 71,247, 45,101,251,231,173,211,104,246, 83,204,148,147,113, 34,122, 22,108,218,190,242,169,208,101,133,187,217, + 96, 70,191,239,150,237,226,127,240,158,221,237,142, 11,114,187,194,241,211,112,246,125,144, 62,234,168,216,114,237,174,177,182, +117,200,246, 39, 96,243, 58,250,149, 14,190, 92,168,251,129,186,217,163,151,197, 44, 53,189, 16,139,103,160, 79, 70,173, 69, 42, +152,207, 97, 61,120,109,178,159, 54, 66,156,223,211,236,209,235, 44, 52, 86,171,212, 61, 60,201,186,154, 32,209, 59, 42,166,177, +178,137,113,173,101, 44,141,196,166, 50,229, 81,139,194,153, 4, 94,248,109, 43,226, 55,119,232, 47,108,169, 46, 86,106,229, 68, +187,125,238,213, 92, 46,189,219, 19,107, 40, 38,236,155,218,225,105, 14,237, 29,126, 59,216,235, 2, 58,194,129, 72,172,163,237, +234,231, 68,180, 57,192,211,254, 62,105,153,192,176, 7,242, 46,209,153,142,183,232,136,131,101,172, 30,218,168,218,125,238,186, +183, 95, 15,201,124,237, 94, 89,166,108,113,157,189,206,174, 69,170, 75,222,122,235,254,245, 73, 96,203, 12, 99,145,107,112,242, +107,105,103,115, 30,209,244,249, 76, 96, 63,230, 64,149,214,113, 87,153, 1, 54,210, 68, 84,117, 97, 61, 91, 38,238,137, 89,161, +171, 51,152, 13,161, 59,139,196,102, 8,217, 60, 46,175, 11, 7,128,180, 66,209,181, 4,242,100,190,206, 44, 76,107, 54, 73,105, +161, 57,126, 22,121,210, 92, 76, 29,161, 75, 94, 12, 85, 66,234, 38, 91, 95,235,210, 45,140,102,142,169,211,170, 72,169,208,165, + 73,201,190,124,252, 15, 68,203, 79,168, 99,215,140,232,194, 74, 34, 79,212,140,150, 49, 79,169,179,136,204,195, 15,146, 8,146, + 51,244,107, 98,201,144,214, 54, 50,240, 10,211,198,200,214,117, 55,178,154,165,176,153, 63,189,168,101,215,142, 84, 74, 53, 22, + 58, 37, 32,235, 21, 49,196,105, 52, 31, 22,251,188,172,129,193, 22, 41, 20, 81,207,107,159, 63,160, 56,141,232,132,218, 62,244, + 92,168,152, 53, 76, 39,133,169,221,148,109, 66,109, 55,207,147,104,142,177,158, 74, 71, 97, 85, 42,235,146,233, 99, 34,158,175, +144, 35, 11,253,178,120, 98,223,195, 63,171,200,119,174,225,195, 39,200,173, 35, 59,112,107,133,109,133,171, 61, 60, 84,120,111, +128, 7, 3,250,238,136,222,219,163,155,209, 14,243,161, 88,190,115,219, 93,165,134,215, 86,234, 88, 93,128,232, 23,187, 24,164, + 97,142,185,117,251, 20, 3, 49, 57, 77,168, 31, 8, 15, 77,124, 37,235, 64,216, 36,194,174,131, 55, 92, 46,140,237, 79,229, 44, + 34,251, 8,143, 21,185, 25,204,107,126,171,179,195,231, 81,134, 55,119,112,158,224, 70, 68, 78,131,117,225, 87, 25,222,202,112, + 97,156,113,233, 42,242,162,160, 23,138,222, 43,200, 91, 35,220, 62,130, 27, 29,242,160,162,253, 10,158,143,208, 41,242,104,132, + 7,131,141,250, 69,145, 91,197,172, 86, 23,192,223,218,194,247,158,194,127,249,113, 56,238, 97,115, 23,254,201,219,212,255,248, + 53,134, 52,178,125, 37, 48, 6,161,238, 97,119,161, 60, 69,241,179, 79,169, 95,119,245,218,157,136,222,138,132,211,128,174,133, +186, 41,232, 69, 57,232, 38,170,147, 5,211,253,138,110,108,215,223,149,198,233, 23, 66,178,200, 96,201,134, 61,175, 98,201,119, + 33,137,229,198, 71,103, 49, 4, 69,114, 32,156,118,200,211,137,250,110, 65, 99, 48,161,227, 75,107,228,233,206, 30,244,210,119, +220, 61,232,177,143, 3,130, 75,224,167,229, 98,103,191, 14, 98, 73,104,185,204,244,149,236,183,153,226,135,198,142,217,144,156, + 77,241,169, 69,172, 83,223, 57,223, 64, 43,114,218, 27,163,224, 76,140,236,151, 58,120,184,133,175,239,109,101,209, 9,188,185, +135,247,178, 5, 2,220, 8,246,121,156, 29,193,241,119,194,234,183,248,215,126,184,118,219, 88, 89,209,177,255, 60,236,126, 24, +189,183,135, 47,247,232,227, 29,249,222,150,178, 25, 28,126, 99, 45, 89,170, 48,202,194,251,221, 82, 11, 91,184,201, 2,202,165, + 11,130,220,146,197,221,178,210, 61,203,102, 49,142,158,168, 62, 62, 22,159,187,219,232,247, 26, 79, 8, 37,121,234, 99,113, 84, +165,136,109, 45, 54, 65,249,220,143, 95,176,251, 97,101, 47,141,141,109,227,236,136, 80,156, 64,215, 55,221,105, 16,142,164,161, + 67, 27,169,114,150,172,181,196,177, 6,108,105,217,202,193, 59,223, 50,185,188,197, 34,158,157, 35,149,181,129, 58,101, 49,250, + 85,146, 67, 69, 6,223, 11,183,177,118,110,141,138,204, 80,155,165, 27,235,176, 27, 91,132,253, 77, 52,186,121,188, 20, 16,167, +109, 46,138,132,198,253,152,148,224,117, 10,194, 20, 39,149, 29,100,177, 47,133,126,186, 32,104,126, 0,146, 85, 69,174, 53,239, +166,149,146,197,206,160, 97,113,163,139,218,170,151, 1, 9,139,145,150,134, 79, 43,115,241,193, 34,213,112,210,112,205,212,148, + 39, 78,194, 57,132, 38,120, 12, 44, 79, 8,251, 84,117, 1, 10,250,141,242, 89,218, 53,117,125, 57,223, 86, 17, 66,236,187,137, + 4, 23,155, 71, 93,157, 76,151,179,221,163, 92,143,129,204,133,141,189,223,209, 14,254,246,124, 15, 88, 57, 11,106,229,114,151, +222,214, 84, 58,123,250,209, 15, 24,216, 7, 33,229,106,136, 81, 45, 74,215, 7, 82, 76, 4, 81, 36,117,196,184, 66,227, 26, 73, +167,212,106, 67,176, 78, 93,109,170, 25,145,206,144,120,248,151,172, 24, 41,174,198,196,128, 65, 39, 2,197,224, 32, 68,194,144, +160,139,118, 64, 59,109,173, 46, 88,202,170,106, 80, 53,236,198,209,252,223,193,239, 14, 73, 60,159,183, 26,174, 47, 16,209, 80, +217,143,197, 94,100,246,225, 94, 47,136, 22,118, 57,179, 18, 56, 78,194, 73,138,172,168, 28,111, 11,125, 8,196, 27, 61,242,244, + 9,242, 66,111, 2,226,126, 68,184,132,167,247,200, 43, 43,184,243, 50,156,220, 52, 37,240,110,111,251,241,135,213,242,192,223, + 26,208,119,246,232,251, 25,221,236,169,155, 17,174, 70,234,174, 80,107, 33,123, 61, 95, 69,169, 81,144,193,191, 40,193,242,207, + 75,145, 86, 23, 77,228,172,226, 49,182, 13,157,153, 4,194, 8, 49, 40,105, 83,232,163, 18,163,146, 58, 33, 62, 20, 66,181,238, + 36, 28, 91,150,189,238,132,112, 20, 9, 47,174,144,211,106,104,185,149, 32,187, 8,131,162,143, 70,216, 23,164, 56,121,250,162, +192, 90,209, 62,194,105, 64, 7, 65, 71,179, 44,134,181,117,152, 82,176, 63,247,222,206,166, 22,231,107,232, 7,248,106,133, 51, +144,149,131,116,246, 3,218, 85,228,158,194, 15,111,224,215, 51,252,201,231,224,207,124,163, 93,113,239, 95,192,223,120,157,242, + 87,223,102,123, 86,216, 61, 39,236,131, 82,243,172, 31,169, 10, 49, 87, 52,249,170,119, 91,225, 45, 11,196,209,231, 19,117,175, +104, 22,100, 87, 25,223,203,108, 42,142, 23,182,115, 83,179, 39,149,157, 68,194, 0, 97,167, 48,186, 53,243,164, 67,142, 18, 58, + 66,237, 5, 61,241, 74,223,149,232,146, 32,196,222,246,222, 47,246,240,220,138,240,176,192,205,104, 83,143,243,100,171,139, 77, +134,219,106,207, 81,152, 91,129, 81,237,191,143,222, 31,141,217, 66,101,176,184, 84, 70,172, 3,223,249, 33,159,220,215,165,213, +146,234, 66,227, 75, 87,215, 99,248,216,105,133,209,231,238,244, 6,153, 89, 97, 34,187,130, 21, 98,175, 22,227, 29, 72,129, 13, +240,247, 30,216,168,255, 70,132,155, 5,238, 20, 88,191, 0,235,239, 54,255,250, 20,153,186, 16,198, 73,130,241, 85,184,250,239, +209,247,222,132,207,173,168, 95,186, 34,127,233,130,113,200,140,209, 1, 49,101,182,232,118,209,110,160,163,251,169, 7,153, 91, +211,202, 33,242,244,131,136, 40,181,109,224,220,139, 29, 43,139,108,182, 54,182,159,163, 50,147, 52,142,185,186,154,218,111,184, +157,117,199, 77, 17, 95,220,158,245,184,100,187, 79,232, 60, 5,168, 40, 35,202,190, 40,161,113, 47, 48,186, 32, 49,248,110, 94, +167,149,158,248,159,159, 32, 40,211,227,232,204,255,215,249,144,111, 62,237,226, 19,196,212,148,232,139,110, 81,197, 64, 44,201, +195, 88, 28, 9, 62, 29,226, 97, 41, 34,116,229,116, 89, 88,225,174,183,117,203,230, 92,171, 78,157,112, 27,179,183, 69,177, 30, +236,241,117,145,186,118,168,112, 23,102, 11,222, 97,116,209,172,111,138,174,164,215,133, 72,238, 48,241, 76, 14, 70,216, 19, 64, +133, 58,101,120,180, 71,175,174,113,152, 64, 79,190, 86,109,227,109, 9,205,214, 53,139,246,170, 43,166,150,225, 46, 70,146,170, +211,115, 84, 89, 18,224, 90,142,192,108,169, 19,253,128,116, 6,209, 67,181,192, 53, 82,157, 46, 44,110, 41,153, 56,186, 17,249, + 66, 76,102,171, 22,168,227,136, 22,215, 65,212,178,152, 50,184,222,160,235, 92, 18, 86, 93,171,113,232,226,230,137,207,101, 46, + 52,108,244, 94, 15,162,111, 15, 28, 11,126, 1,165, 90, 43, 59,131,252,210, 75, 79, 82,165,171, 35, 93,215, 19,211,218,190,171, +187,135,176,223,210, 21, 83,152, 27, 39,221,198,239, 41, 26,116,165,115,161,204, 94,139,147,210, 58,243,211, 73,165,247,175,122, +148,129,152, 86,212, 16,209, 82,166,106, 75,252,159,115,197,253,168,179, 32, 69,131,144,130,135,176,160, 88,238,201,108,107, 16, +194,172, 84, 22,151, 79,104,177,253, 92,133, 16, 42,235, 16,184, 81, 51,235, 42,164,243, 21,242,194, 25,242,202, 41,242,225, 0, +207,111,145, 27, 27,100,157,225,244, 14, 60,245,135, 32,126,151,205,117,203, 15,161,151, 95,133,215, 42,188,150,209,175,110,225, +253,129,122, 49, 82,119,131,249, 17,135, 66, 29, 70,114,174,100, 17, 70, 85, 70,103, 94,215, 98, 35,223,214,200,105,181,213,233, +232,107,244, 54, 85,240,168,102,178,152,158, 78,147,107,226, 26, 45, 84, 44,153, 53, 22,136, 89,137, 87, 74, 79,161,235,160,219, +184,216, 37, 4,180,239,224, 1,132, 75,181,113,253,168,232,101,134,119, 70, 83,182,223, 72,118, 51,236, 93, 3,240,254, 0,167, + 61,188,208,217,225,241, 32,160, 95, 46,232,221, 1,217,251,158,255,182,160,249,210,202,238,151, 78, 44, 87, 61, 87,203,247, 88, + 5, 56,173,200,235, 5,126,122, 15,255,223, 22,206,122,248,177,239,129, 79, 60, 13,219,119,225,157,135,240,231, 95, 99,248,199, +247,217, 62, 15,155, 51, 75, 64,171,213,181, 3,206, 60,144,216, 70,123,158, 80,118,132,141,148,239, 86,116,175,240,116,231,232, +211, 66,206,238, 63,246,223, 94, 70,195,222, 18, 2,114,158,108, 20,174, 1,185, 2, 25, 20,110,246,240,145, 53,114, 18, 9, 93, +107, 67,220, 54,214,153,151,156,211,222,185,233,213, 86, 5, 31, 63,118, 5,122,180, 67,249,129,143,173,163, 34, 67,245,192, 51, +117,237,132,162,123,191,137, 94, 96, 69,208,191, 48, 88,164,108,135, 31,248,106, 93,254,214,171, 16,162,117,219,219,206, 84,234, + 53, 33,197,219,139,216,153, 31,253,142,147,227,250, 96,202,189, 62, 34, 87, 5, 94, 31,225, 81,181,247,232, 65, 99,131, 87,251, + 61,157, 88,193,245,210, 0, 55,111,194,201,239,134,254,227,126,103, 41,179,185, 76, 86,246,103,246,191, 12,155,255, 22,238,189, + 10,191,208, 81,126,228, 49,227,155, 23,140,146, 25,250, 48,121,156,227, 33, 97,133, 62, 78, 43,195,233, 95, 47,119,232,203,236, +107, 28,158,210,254, 23, 15, 90,205,235,120, 81,143, 92,117, 6,123, 4,122,105,192,151, 89,108, 84, 93, 96, 22,220,165, 82, 68, +167,169, 65, 20, 83,223,151,228,221,147,119,168, 90, 33, 68, 63,132,253,126,178, 87, 8,165,176, 90,220,219, 83,180, 90,204,183, + 97,126,168, 86,115, 50, 48,243, 14,116, 49, 73, 92,246,170, 77,168, 89,188,121, 17,213, 5,144,198, 68,127, 9,241,235, 95, 23, + 99,105,251,190, 79,197,145,206, 86,171,249,140, 20,174,199,122, 31,168,225, 85,167, 67, 34,120, 19,164, 85, 39, 49,149, 48, 79, + 5, 88, 4,180,132, 5, 56, 39,200,108, 15, 92, 6,185,206,217,107, 79,214, 24,237,185,196,133,214, 96,145,240,242, 1, 61,177, +206, 37,129, 44,130, 96,154,102, 56,204,222,255, 6, 9,159, 34, 95,117, 54,238, 5,105,118,189,176, 88, 35, 60,177,246,159, 67, +109,244,240, 61,147,131,229,129, 78,123,235,105, 2,225,142,165, 22,170,210, 73, 32,244,189, 79,134,235,148,154,214, 68,113,154, +203, 4,138,145,133, 28, 82, 29,190, 19, 66,116, 33,168, 78, 83,168, 67, 73,158, 28,136, 13, 38,226,100,176,231,178, 32,230,114, + 61, 13,182,189,158, 20,125,238, 63,168,144,115, 33,239,246,116,235, 68,212, 64, 24,246,112, 60, 32,247,223, 36,212,140,132, 58, + 89,188,149, 74,162,176, 86, 33,105,153,112,138,150,164,102, 28,204, 20,196,141,241,150,126, 36, 8, 26, 19,132, 68, 13, 13,198, + 81,208, 96, 92,120, 10, 84, 15,187, 15, 94,225,110, 75,165,171, 74,239,222, 71, 81, 27,243,131,141,241,115, 41, 86, 45, 17, 12, +227, 89,139,165,203,185, 10,127, 45,112,179, 84,206, 82, 15,207,172,145, 79,156, 34,159,236,145,143, 14,200,237, 45,172,143, 97, +253, 59,161,251, 30,232,127, 27,132,103,161,108, 97,248,155,232, 59,255, 16,126,174,194,167, 51,245, 98, 75,221,143, 6,179,201, + 35,117,167,104,168,148, 82,173, 81, 11, 66,198,179,142,139,255,234,254,249, 36,190,135,108,122, 52,191,246,134, 10,181,202,228, + 40,104,118,158, 60,216,205,101,240,155,131,136,105,167, 58,177,149,104,136,112, 20,133,149, 42, 43,133,163,160, 68, 41, 72, 53, +197,179,158, 20,244,204, 10, 3, 94,223,161,247, 71, 99,221,223, 74,112,220, 77,221, 5, 67,133,221, 96,144,153,231, 59, 27,223, +247, 5,238, 68,228,237, 1,189,168,112, 92,209,251, 21,253,244, 99,100,183,183,131, 47, 10,250,214,158, 48, 84, 59, 48, 69,144, +109,132,255,232, 89,248, 15,255, 77, 88,127, 28,234,143,194,107,239,195,127,240, 37,118,239, 94,177,125, 89, 24, 79,204,113, 85, + 23,128,138, 62, 90, 82, 46,216,181, 99, 69,142,141,159, 21,172,123,206,106,218,133,125, 37,191, 58,178, 27,205, 15,142,219,139, +210, 70, 45,158,246,230, 10,238,244,246,235,145, 69,219,202,168,230,233,126,190,131, 91,106,246,174,228,115,227, 32, 51, 13,101, + 53,218,254, 63, 62, 99, 97,233,187, 75,123,162, 23, 21, 94,191,178, 2,104, 83, 97,168,232,174,160,219, 98,255,156, 21,221,121, + 39, 55, 8,220,221, 33,127,106,141,124,235,191, 11,235, 63, 52, 7,169,232, 61,224, 43, 80,190, 0,229, 61,208, 43,168, 27,243, +147,215,141, 85, 38, 57,216, 56, 60, 90,102,171,210, 65,233,124,108,175,200,155, 91,248,213,157, 49, 15,126,247, 45,248,226, 3, +120, 99,107,223,171, 36,246, 70,222, 22,248,196, 22, 94, 88,195,201,247,192,250,123,124,183, 52,206,135, 57, 21,202, 61,216,253, + 24,108,255,119,244,205, 7,232,255, 35,148,127,244,128,252, 96,203,238, 8,118, 41, 48, 44, 52, 57,141, 63, 16,253, 0,232,252, + 62, 51, 78, 22,214,153, 22,215,249,239, 25,125,239, 91, 29, 27,123,144,204, 22,150,221,251,162,111,108,128, 23,204, 46,155,130, +229, 69,104,139,171,245,181,156,184,141, 78,131, 77,185,130, 90,132,106,243,118,143, 10,251, 50,135, 50,129,216, 58,133,176, 80, +221,155,112, 50, 3,235, 96,163,241, 82,237, 16, 25,125,159, 27,131, 21,222,197,195, 56,100, 98,110,133, 5,252,253,154, 57,253, + 32,215,124,145,212,230, 97, 46,237, 30,221, 47,198,200, 73, 22, 30,246,230,197,174, 58,143,215, 15,211,203, 15,142,197,101,235, +214,186,253,220, 20,241,234,169,115, 50, 75, 21,101,241,185,134,131,194, 96,113, 8, 45,215, 37,139,193,112,253,141,230,214,204, + 84,185, 72, 53, 76,110,235,196,157, 12,215, 44,111,185, 33,106,213,227, 94,130,120,238,185, 23, 72, 65, 38,248, 78, 27,181, 7, + 76,196, 90,189, 18,140, 62,201,136, 11, 86,190, 4, 99,132,148,122,200,132, 87,157,139, 26,189,166,116, 95,190,155,141,250,231, +172,226,201, 41,208, 20,232, 1, 72, 93,239,104, 86, 59,180, 99, 76,190,110, 80,202,176,119,216,197, 98,247, 68, 43,186, 23, 25, + 32,238, 60, 88, 36,198, 60, 9,189,145, 57,215,100,161,244,152, 16,138,242, 65, 48, 4, 47,120, 82, 41,149, 40,202, 81, 17,143, +223,195,130, 60,134,129,176,238, 96,191, 37, 94,220,155,200, 67, 73, 76, 29,220, 41, 28,147, 73, 19, 53, 74,141,241, 92,133, 81, +161,200, 72, 12,105, 26, 11,165, 10,149,140, 14, 3, 28, 37, 59,124, 68,145,236, 59,228, 34,179, 2, 83, 32,212, 58,125, 0, 89, + 45,215, 56,149, 58, 67, 31, 52, 19, 67,180, 70,106,172, 68,242, 84, 37, 15, 62, 79, 56, 11,240, 66, 45,156,173,123,248,232, 41, +225,149, 53,242, 91, 64, 94,217,192,217, 57,116,255, 10,172,254, 32,164,143,248, 30, 52, 66,185, 11,251,191,134,190,254, 67,240, + 35, 17,253, 98,166,236,246,134,209,221, 13,212,161, 76,192,155,138,218, 33, 29,230,220,237,234,135,181, 78, 98, 20,133, 69,192, + 92,109,187,161,214,157,235,225, 40,173,197,248, 14,238,145,110, 97, 2, 69, 13,230,209,196, 16, 67,133, 85,134,163,106,137,154, +199, 40,221,163,193, 46,220,167, 2,172, 50,245,205, 75,184,178,116,183,112, 35, 33, 47,174, 12, 45,106,112,108,123,240,187,163, + 61,169, 23,214,112,123,109, 10,250, 59, 3,188,176, 69,182, 5,237, 11,220,219,193, 63,219, 82,127,230,190,237,128,111, 37,179, +225, 17, 8,191,121,109,177,156,127,246, 89,248,238,223,105, 63,123,252, 65,248,217,215,225, 63,253, 42,101,183, 97,248,136,144, +147, 50,248, 67, 5,177,142,169,247, 72,121,170,157,107, 65, 43,146,155, 13, 7,100,109,209,168,147,129,229,189,202,240,168,162, + 29, 30, 12,100,124,241,245, 51, 29,242,145, 99,228,229, 19,228,217, 53,242,204, 10,158, 2, 78,119,230, 78,232, 5,122,133,238, + 41, 72,207, 24,180, 69,143,156, 82, 19, 33,158, 66,119, 11,228, 55, 1, 47, 0,127, 7,134, 95,178, 9,199,167,175, 96, 63,192, +219, 35,188, 61,152, 23,121,168,168,157, 42,104, 39, 22,165,122, 63, 34,175,109, 8,127, 54, 34,159,250, 1,224, 21, 7, 10,173, + 32,172, 64, 62, 14,252,139,243, 11,214,193, 72,111,186,113,133,225, 99,144,199,246,247,245, 17,148, 47, 35,250,171,176, 11,232, +189, 17,253,252, 35,228,115, 27,187, 70, 63,220,193,151, 31,193,175,236, 32, 6,244, 52,152,150,225, 86,133, 15,239,144, 91, 79, +193,233,167,224,244,223,128,244,226,162,103, 22, 40, 15, 97,248, 89,216,253, 31,240,232,255,167,235, 93,131,109,203,174,251,174, +223,152,115,174,181,247,121,221,103,119,223,238, 86,235,237,150,228,182,172,216,178, 99, 89,118, 98, 59,113, 98,226, 56,113, 66, +133, 24, 19, 82, 36, 69, 2, 5, 36, 80, 20, 85, 64, 97, 10,202, 64,133, 47, 64, 65, 21, 36, 85,144,144,132, 36, 80, 9,224,138, +147, 24,236, 56,196,137,223,145, 45, 63,164, 88, 45,181, 30, 45,169, 91,253,186,239,199, 57,103,239,189,214,156,115,240, 97,140, +185,214,218,231,182, 63,180,125,213,125,239, 57,231,238,189,246, 28,115,140,241,255,255,254, 47,161,159,174,212,191, 93,109,220, + 46,133,237,229,192,166, 24,151,188,137,218,162, 90,231,219,162, 80, 87,113, 46,192, 93,180,188,244, 77,245, 14,205,211, 10,117, + 70, 60, 77,241, 28,121, 49,122, 37,136,173,223, 90,231,219,160, 1, 77, 71, 88,108,200,154,170,249,206,163, 71,144, 70,102,221, + 97,174, 70, 81,107,157,100,205,190,247,247,201, 69,198,200,130,101, 54,151, 91,132,102, 93,236,159, 5, 6, 21,182, 62,110, 15, +226,145,164,193, 32, 53,181,234,148, 30, 23, 69, 38,209,153,161, 87, 93,240, 37,139, 84,177,139,225,187, 50,235, 0,194, 98, 50, + 61,179,206,231,223, 29, 91,167,190, 76, 19,107,197, 91,116,143,233, 23, 91, 21, 98, 0, 0, 32, 0, 73, 68, 65, 84,190,196,195, +182, 60,131,122,129,136,166,203,142,118, 65,167,211, 54,106,214,165, 57,109,169,187,210, 69,239,186, 47,190,171,250,152,248,122, +175,227,213,169, 43,222,247,232,135,197, 42,162, 57, 7,194,197,191, 79,144,125,207,252,133,184,227,226,127,151, 37,217,174,168, + 62,230,126, 3,125, 12, 28, 35,139,164,188,139,194,184, 9, 56,113,113,234,162, 30, 76, 38,102,217,238, 83, 34,244, 43,203,134, + 87, 37, 46,128, 48,181,100,223,165,235,212,133,207,193, 44, 76, 40,217,101,118,250,194,133,246,182, 23, 37,109, 95,195, 3, 99, +168,245,241, 49,196, 66,111,208,236,135,137,146,233,162,129, 68, 14, 99, 79, 9,129, 97, 55, 80,210,142,116,114, 29, 57,191, 75, + 28, 55,150, 39, 60, 20, 83,101, 75, 32,105,225,160,190, 29, 61,201,104,114,165, 84, 6,231,170,183, 14, 53,146,169, 99,128, 52, + 66,114,239,104, 48,251, 28,238, 15,157, 2,239, 27,160,193,189,150,141, 24,215,169, 34,193,197, 2,213,148,235,113,113,112, 0, +116,162,156, 8, 60, 83, 50, 55, 18,196, 27, 7,200,251, 58,228, 91, 10,242, 65, 96,253, 65,232,254, 37, 56,248, 78,136,151, 13, +161, 57,126, 14,182, 63, 5,143,254, 17,250,153, 91,240, 83, 61,229,141,145, 58,238,168,187, 1,221,101,178, 26,139,190,248,144, +161,104,139,237,243,125,184,131, 56, 20,223,247, 90,108, 51, 33, 76,205,151,233,167,176,241, 94,219, 45, 54,108,101, 45,251,118, +200,106,182,126,107, 42,219,135,195, 79,142, 33, 67, 78,166, 91,208, 29, 12, 17, 14,138,114, 92, 6,226, 77,168,159, 24,225, 53, +181, 92,241, 15, 28,154, 5,174, 98, 10,247, 36, 45, 81, 1,185,181, 65, 95,181,220,119,121,246,208,105,120,246,131,232,249, 0, +255,228, 33,229,179, 91,134,123,153, 92, 13,179,123,184,141,132,143,172,209, 91,138,254,250,136,252,240, 9,188,255, 18, 60,122, +209,252,239,127,247, 77,248, 95,111,194,149, 29,229,105, 35,124, 85,103, 60,196,101,182,177,143,222, 87, 71,129,238,122, 52,152, + 78,176, 14,133, 65,205,210,135,160, 81,172, 48,103,241,113,172, 83,254,182,176, 74, 17,121,223, 17,242,190, 99,228,125,135,200, +179, 7,112,253, 12, 57,201,208,191, 7,194,135, 65, 62, 12,188, 27,228,138,207,245,197,230,180,205,171, 29,139, 23,214, 10,124, + 26,118,191, 97, 54,193, 31,127, 8, 95,222,194, 7,162, 81,236,238,143,212,228,118,152, 13,200, 70,144,115,236,226, 68, 38,252, + 87, 87,145,223,251,163,192, 19, 80, 63, 15,245, 31,128, 60, 3,250,141, 16,158, 3,185,106, 33, 43,178, 54, 11, 25,199,246,115, +200,214, 72,112, 13, 88, 16,111, 1, 95,129,123, 27,244,197, 17,253,212, 41,124,121,103,135,201, 73,130, 79, 84,123,208, 14, 4, +158,234,224,201, 12,207, 13,198,247, 63,124, 15,172,191, 7, 14,190, 7,186,119,187,255, 92, 65, 31,217,238,124,247,183,224,244, + 23,208,151, 7,248,105,161,124, 98, 36,223, 63,103, 88, 43,103, 49,176, 41, 86,228,218, 4,169,157, 53, 69,188, 59,119, 87,221, +232,207, 98,244,206,124, 43, 76, 99,226,226,191,191,214,185, 75,106, 26,246,169,168,142, 83,182,144, 77,232, 90,240,138, 39,230, + 5,148, 88,253,247, 47,246,173,117,218,117, 47,247,185,222,161,183, 17, 64, 16,170, 36,250,232,246,200,226,231,135, 40,181, 56, +223,162, 61,133,238, 1,223,170, 19, 17, 3,172,170,146, 92,218,208,192, 54,161, 46,213,209,179,216, 47,180,127,225, 44,250,134, + 47,157,124,217, 62,126, 15, 11, 62,123,245, 51, 68, 22,180, 23,161, 5, 0, 49, 9,250,130,171,189, 77, 4, 38,123, 19, 0,157, + 66, 89, 22,197,118, 9,167,209,102,134,147,233,156,105,187,249,160,251, 72,218,134,113,189, 56, 88,175, 23,108, 86,243,152,126, +191,207, 13, 11,200,186,250,109, 33, 92, 48, 77, 46,227,201,219,152,190,178, 39, 32,152, 11,174,200,111, 19,217, 50, 55,192,181, + 49,225,223,142,108,215, 58,166,197, 94, 95,228,241,145,251,108, 89,147,233,245,108,118,235, 37,204, 69, 98, 48, 59,116,191,114, +151,140,131,182,186,206,129, 67,234,176,153,165,192,110,201,149, 55, 45, 66,104, 81,169,191,221,168,131, 69,138,249,146,208,164, + 50,185,165,116, 41,242,211,249, 66,215,114, 4,140, 77,150, 11, 42,145, 85, 8,172,164, 50,212,145, 48, 22,186,206,226, 29,227, +253,123,132, 98, 10,238,164, 74,172,133,181, 64, 39,117, 98, 98, 91, 28, 29,148,234,177,119,181,206, 64, 24, 12,187, 90,105,182, +128, 2,187, 45, 34, 43,247, 74,218, 7,183,214, 72,168,131,139,137,171, 79,230,189, 27, 10, 45, 34, 47, 24,170,214,199, 88, 65, +237,103, 82, 15,189,140, 56,219,131,194,181,237,142, 75, 73,137, 79, 29, 35,239, 89,195,183,123, 16, 88,247,173, 16,127, 8, 86, + 31, 50,145, 80,254, 28,108,255, 50,220,254, 57,244,229, 13,252, 90, 68, 95,138,148, 71, 91,106, 25,208, 49, 83,182,153, 34,134, +188,108,190,212,218,232, 76, 52,170, 29,251,170,236,210, 62,104, 23,198, 86,109,183, 62,237, 34,237, 80, 40, 89,167,215,114,185, +159,242,201,171, 37,149,250,175, 59,139,228,118,175,163, 11,149,212, 50, 60, 34, 74,248,242,142,113, 7,241, 84, 57,122,125, 71, +220, 40, 74, 66,174, 41,196,100,222,189,147, 14,206, 6,120,121,139,126,173,194,173, 1,190, 97, 68,179,192, 39,207,209,223,122, + 4,111,109, 25, 67,102,123, 41, 80,174, 26, 48, 93, 70, 69, 15,125, 31,126, 41,194, 15, 93,129, 23,142,225,214, 41,220,189, 7, +175,141,240, 19,247,224,201,140, 30,214,153, 66,185, 80,245,234, 34, 75, 33,136,208, 63,159,144, 99,129,251, 62, 38,172, 13, 16, +238,135,250,177,195,218, 79, 18,221, 93, 69, 94, 29,140,152,119, 57, 66, 72,200,213, 53,242,145, 19,228,106, 7, 79,222, 70,142, + 46, 65,252,211, 16,255, 32,196,119,128, 28, 46,108,101,186, 56,102,182,214, 21,203, 93, 7,237,108, 32,255, 56,124,254, 45,248, + 63,182,148, 23, 79,169, 97,132, 95, 80, 27,185,111,173,128,235,185,105, 57,194,229, 68,120, 97,141,252,190, 43,200,199, 62,132, +188,247, 47,122, 56, 74,129,244, 46, 40, 87, 29, 77,247,140,113, 93, 37, 61,158, 48, 37,173, 44, 30,248,255,255, 44,236,126, 20, + 94,188,137,254,114,164,254,243,141, 1,155,142,237, 57,169, 67,181,232,226, 85, 68,159,142,240,174,140,188,171,192,229,231,160, +255, 56, 28,124, 28,210,243,126, 89,141, 80, 55, 54,125,218,254, 18,236,126, 12,189,245, 10,252, 42,232,255,171,228, 91,231,212, + 58,176, 61, 80, 30, 97,242,128, 93,101, 82,216,198, 6, 81,145,137,141,100,201,235,237, 96,246, 11,103,146,121, 39, 27, 29, 13, + 91,242,190,250, 71,226,140,239,149, 11,157,108, 83,167,155,199, 87,246, 98, 38, 39, 37,245,212, 37,202,156,112,229,197,116,130, +160,120,174,249, 56, 81,191,204,213,208, 43,156, 47,236, 96, 34, 1,209,185,175, 13,213,109, 78, 46,124,212, 54, 98,111, 2, 51, +157, 47, 1,193,187,238,185, 24,153, 40, 46, 54,179,195,124,125, 33,182, 68,182,229, 16,251, 66, 71, 47,147,168,176, 78, 10,243, +206, 19,234,170,202,133,210,184,152,234,121, 1, 42, 94,124,157,158,239,103, 83,157, 18,199,150, 99,241,165,214,161, 94,228,178, +188,205, 36,119,249,221,101, 31,163,126,161, 67,159, 27,221, 37, 61, 79,246, 44, 15,115, 65,111, 23,131, 40,226, 92, 2,153,255, +124,203, 3,240,236,120, 93, 88,241,166, 39, 66,218, 4, 73,166,221,114,101,145, 95, 47,238, 98,242,103,106,185, 10,145, 6,156, + 10, 50,171,235,125,188,174, 11, 76,175,182,149,129, 79, 20, 82,138,132,152,236,189, 84, 69, 82,178, 66, 91, 43,185, 20, 75, 95, +163,238,241,230,247,200,121, 33, 80, 67,160,148,108,161, 47, 19, 23,192, 52, 22, 42, 51,251,128, 69,158,193,164,198,208,178,135, +136, 23,185,128, 21, 92, 68,224, 38, 36, 52, 14, 10,161, 84,214,100, 86,154, 81, 57,129,221,134,114,250, 8,137, 38,213,142, 8, +157, 40, 93, 44,244,197, 30,223, 34, 66, 8, 38, 56, 41, 85,208, 26,201,213, 68,106,181,152, 77, 41,104,157,124,126,218,104, 49, + 91, 65,250,222, 14, 71,140,252, 37,163,119,164,181,129,115,117,142,189, 68, 40,154,247, 62, 72, 45,172, 33,214, 74,162,114, 88, + 11, 87, 74,225, 40, 64, 58,234,145, 43,107,228, 15,172,224,119,101,228,137, 75,208,125, 63,196,239,134,110,132,221,223,129,237, + 47,192,253,151,208,207,111,224,147, 9,125,185,167,158,141,212, 60,160,117,152, 72, 65, 53,217, 77,191,150,166,216,100,102, 24, +203,227,162,140, 61,239, 14,139,192,130,197,248,105,250,196, 92,136, 4, 94, 94, 71,155,186,177,113,140,165,206, 47, 75,251, 80, + 4,119, 9,172,215,118,184,158, 15,240, 96,103, 93,213,245,104,183, 76,182,160,103,138, 94, 18,228, 60,195, 67,108,102,250,176, +192, 65, 52,141,194,203, 5,121, 54,163,215, 59,248, 72,135, 92, 91,195,111, 41,241, 13, 88, 7, 33,171,192,202, 82,136,234,231, +171,169,142,255,253,235,200,147, 7,112,115, 99, 41,114,193,242,188,249,222,158,242,226,128,190, 57, 34, 81, 89,128,114,231,196, + 46,103,169, 4,224,252,165, 76, 95,252,113,182, 58,141, 30, 7, 83,187, 99,241,187,168, 88,113,255,112,164,187,218,193,135,123, +163,205,189, 41,200,251, 15,144, 67,224,224, 85,228,232, 67,208,253, 37,232, 62, 48,167,147,253,182,215,226,100, 72,186, 18,108, +215,156,255, 2,124,238, 37,248,107, 35,229,139,103,148,211,108, 81,184,143, 42, 82,132,112,220, 35, 31, 58, 38,252, 11,151,144, +111,190,140,188,243,253,112,244, 97, 72,223, 9,114,205, 11,248, 8, 53, 67,121,217,119, 39, 79,248,252, 53,188,253,207,162, 25, +228, 30,232, 79,194,238,111,194, 27,175,192,207,117,240,203, 1,221,157,195, 42, 27,227, 32, 6, 36,118,118,187, 91, 5,244, 70, +130,247,239,144,247, 6, 56,254, 14, 56,248,227,208,127, 3,132,195,197,237,241, 12,242, 87,224,252,255,134,243,159, 69,191,250, + 16,126,178,163,190,184,163, 12,231,148,152, 25, 68, 57, 43,182,238, 25, 90, 68,230, 66,223,212,208,205, 77, 76, 93, 44,112,207, + 30, 93,119,167, 36,148, 94,132, 97,121, 25, 93,136,154,132,101,178,214, 92,224,202, 66,225, 27, 38,234,153, 46,210, 18,141,174, +146, 11,148, 32, 70,236,242,206, 10,215,228,168, 23,232,246, 76, 21, 85, 52, 43, 69,139,243, 54,132, 21, 66,205,202, 80,235, 4, +231,147, 11, 99, 78,241, 11, 67,213,249, 66, 17,188,235, 44, 58,255, 90,177,207, 91,179, 35,137, 24,221, 55, 8,220, 45,243,120, + 58,136,208, 97,208,171,176,176,173,114, 65,212,214, 76,230,170, 50,141,211,219,247, 14,139,130,222, 14,241,186,136, 29,217,191, + 28,201,228,162,215, 61, 21,157, 46,211, 81,253,125,219,167,239,201,194,192,215,158,210, 42,179,149,109, 89,136,117, 49, 29,145, +199, 85,130,254,188,204,153,236,149,101, 22,138, 78, 32,161, 25,198, 42, 83,246, 89,149,253,142, 63, 46, 4,145,186,140, 87, 69, +167, 92,245, 54, 53,105, 77, 99, 27,225, 7,177, 73,176,248,229, 46, 68,235,148, 69,162,173, 76,130,236,121,224,165,121,231,221, + 19, 30, 93, 85,175,110,119, 20,135,244,140, 30,214, 18, 83,242,177,123, 65,199,209, 34,127,107,181, 41,227,130,224,143,175,109, +164,235,205,202, 93,234,196,154, 87,239,242,219, 67, 35, 81, 30,163,236, 77,160,154,162, 51,161,175, 77, 40,218, 11, 35,251, 50, +248,164,197,126,176, 65, 18, 53, 23,250, 80,233, 36, 32,169, 39,156, 62, 98,172,149, 34,145, 64,101,229,194,179,180, 8,125, 79, +193, 60,143,187,106, 34, 19, 3,203,204,190,235, 80,203, 20,191, 23, 53,184, 88,166, 16,242, 56,101, 68,119,238,223,212,152,168, +227,232,188,118,127,108,106,157,185, 29,117,113,227, 13, 16,171,221, 84,187, 90,185, 92, 50, 87, 68,232,143,215,200,165, 21,242, + 97,133,239, 79,200, 7,158,128,248, 93, 16,126, 31,240, 0,118,255, 19,188,246, 34,250,250, 25,124, 13,120, 41,162,175,245,212, +243, 76,213,173,169, 23,107,153, 33, 19, 50, 71, 11,234,226, 1,154,212,186,139,235,108, 27,211,237,125,136, 10,110,153,154, 3, +197,216, 67, 62,202,219,166,244,168, 94,184,132, 45,254, 99,235,148, 86, 81,233, 59, 39,200, 10,156,111,109,186,222,101,120, 74, +225,248,133, 3,248,214, 35,194,234, 0,174, 29,216,174,121,147, 93,142, 47,150,189,221, 85,228,219,119,112, 71,225,134,203,161, +142, 42,242,206, 35,248,214,142,244,185, 45,233,179, 35,171,175, 95, 81,127,229,156,241,203, 3,233,195,135,200,191,251,132,133, +141,124,225, 1,124,126, 11,175, 43,124,104, 5,215,122,244,201, 14,125,119,111,236,246,251,195,188, 55,146, 25,122, 33, 69, 41, +209,124,198, 53, 43,185,179,184,211, 85,198,210,231,214, 1,118,126,196,100, 39,183,109,130,217,204,158, 92, 25,237,238,174, 34, +151, 59,131,177,231,183,144, 39,191, 9,214,127, 11,210,117, 27,171,235,153,183,136,235,183,217, 2,250, 13, 66, 15, 64, 30,192, +240, 31,193, 47,255, 58,245,191,129,250,234,150, 58, 22,184,220, 19,223,125, 68,248,174, 35,228,187,174, 32,207, 29,195,225, 26, +186, 99,251,115,163,192,163, 79,160, 55,255, 30,250,217,219,232, 43, 3,225,247, 95, 67,158,255, 51,176,250, 30, 39,227,108,108, +132,194,193,133,154,126, 6,250, 5,216,253,117,184,255, 51,240,210,125,187, 88,254, 86,143,106, 70,201,212,206,189,141,213, 93, +225, 93, 48,160,208, 51, 17, 62,176, 67,222, 25,225,232,123,224,232, 79, 65,255,254, 57,161,205,114, 23, 97,252, 26,156,253,117, +120,248, 75,232,103, 51,250,143,123,244,230, 72,233,183,212,243,204, 80, 42,103,152, 32, 63,123, 62,120,104,123,215, 38, 46, 11, + 30,173, 60, 59,105,102,138,151,103, 15, 73,128,174,170, 91,219,108,224, 47,161, 49,225,103,222,187,138,238, 57,157,130,234,162, + 27,217,183,116,165,230,237, 13, 80, 26,160,164, 84,235,148,177,241,125, 13, 22,136, 81,151,118,173, 90,173,243,118,161,211, 80, +237,188, 90,251,104, 91, 20,206,202,156,115,158, 23, 99,255, 6,250, 16, 92,221,175,115,136, 72,155, 7,182,103, 39, 47,125,199, +218,252,237,226,150, 54, 59, 20,218,190,183, 42,123, 69, 78, 23,175, 95, 93, 4,175, 84,199,255, 46,127,239, 52, 90,175,139,221, +244, 36,121,171,123,103,200,236, 75,223,135, 2,161, 60,150, 63, 22,216, 23,141,181, 64, 24, 97, 57,109,120,188,147, 23,246,173, + 84,203,189,241,148, 64,216,150,161,178,223,157,207,246,182,139, 73,100,138,134,102, 44,191, 72,133,123,108,233,224,147, 15,217, +215, 45, 41,116, 49, 16, 83,164, 15,137, 24, 19, 33, 70,243,144,203, 68,206,113,226,161, 78,255, 84,173,190,218,173, 19, 43,191, +169,234, 83,215,209,197,142,212,119,196, 16, 38, 33, 94, 74,157, 79, 11,132,243, 97,199,176, 90, 51,148, 66,206, 35,165, 20, 74, + 85,198, 50, 82,198,129,154, 71, 68, 13,139,174,165,236, 65,111,150,186, 9, 9, 50,191,234, 77,192,235,211,134, 41,201,237,237, +116,253,178, 39,201, 68,204, 89,161, 84, 9, 12, 33,178, 11,129, 94, 34, 93,239, 55,233, 97, 75, 8,129, 24, 18, 41, 70,122,170, +225, 86,147,249, 58, 27,222,180, 86, 33,103,101, 91, 96,168, 25,213, 56,177,161,139, 42,181, 75, 70,254, 41,101,242,148,138,102, +187, 28,168, 5,204,135, 46,145, 83, 66,106,153, 70, 19, 97, 82,130,122, 8,135,191,201, 61, 66,168,153, 64,101,157, 43, 87, 75, +229,136, 68,184,118,128,124, 52, 16,126, 0,248,134, 15,192,193, 15,130,126, 39,212, 35, 24,127, 2,125,253,175,193, 47,158,193, + 75, 29, 60, 90,161,231,153,186,115,129, 67, 53,119,185, 58,111,185,169, 33,107, 35,213,213,253,220,228,233, 17, 43,115,236,227, + 18,210,208, 58, 25, 60,158,179,237,215,162, 52,177, 78,179,177,232, 20, 69,168, 11,161, 76,149, 9, 68, 52,141,169,219, 39,196, +223,255,233,235, 14, 21, 78,207,224,108, 52,149,241,115, 1,142,159, 95, 33,223,127,213,138,208, 46, 26,188,100,157,204,239,220, + 24,170,138, 21,196,163,222,198,229,219,130,190,248, 8,253,201,251, 4, 45,200,147, 98, 20,189, 63,127,221,114, 0,126,106,199, +234,251,143,224, 7, 47, 25,124,253,215,239,194, 63, 60,133,251, 5,190,227, 0, 46,245,182, 31, 88, 11,114,163, 55,143,251,205, +209,118,153, 46, 38, 44,101, 74, 32, 53,203, 80, 81,182,126,217,137, 10,114, 37, 32, 43,161, 12,190,115, 56,138, 70,165,234,163, + 41,218,123,215, 6,124,169, 90,168,201,251,128,243,219,200, 7,190, 17, 46,253, 24,232, 3,208,191,231, 84,151,111, 4,158,127, +251,130,222,110, 24,245, 77,184,247,175,162,127,251,139,212,191,210, 91,134,253,247, 95, 35,253,192, 37,194, 7, 46,193,165, 67, + 91,180,138, 39,228, 61, 56, 69, 95,121,131,250, 43, 15,169, 63,123, 74,125,109,139,222, 43, 6,175, 73, 80,255,230, 45,194,135, +126, 4,249,143, 63, 66,120,225, 47, 64,247,188,127,191, 7, 46,130,251, 77,216,254, 19,120,248,179,232,171,111,161,159,170,240, + 27,107,244,245, 14, 98,166,166,115,232, 21,237,188, 53,206,201, 58,140,131,136, 92,234,224,217, 21,242,117, 91,120,199,122, 46, +232,221,123, 93, 31,176,155,180,234,228, 91, 48,252, 61,120,244,139,232,175, 84,244,147, 9,221,141, 20,217,160,247,182,236,182, +112,234, 17,169,109,125, 20,151, 49,162,190,227, 93,238, 68,219,180,178, 4,115, 86, 68,204,157, 23,247,104, 97,179,184,142,104, +248,232,182,136,174,194,222,165, 92,203,133, 69, 41,182, 62,178,253,180, 81, 46, 41,173,147,174, 22,187,233, 23,133, 16,125, 87, +238,116, 57,251, 18,117, 6,212,104,219,237,234, 36, 66,139,106,160,191,222,141, 31, 59,223, 95,123, 42,182,239, 37,117,218, 47, + 71, 95, 5,166,226, 89, 22, 30,241, 89,246,118,195, 86,208,207,213,132,123, 54,222,173,123,148,175,101,231,220, 4,107,114,161, + 73,104, 83,172,246, 26, 38,167,198, 5,229,226,198,122,138,173, 21,239,229,151, 17,168,123,211,238, 58,219,196,248,109, 24,112, +178, 40,242,203, 79, 73, 81,221,179,123,233,126, 9, 95, 76,153,229, 49, 42,218, 98, 8,137, 59, 87,169, 75, 11,123, 99, 83, 52, +107,180,159,109, 77, 9,175, 11,191,127,184,168,190, 95,236,186,155,250,109, 21, 34,253,170,167, 79,189, 77, 38,101, 86,139,103, +247,139, 55,193,246,228,252,241,155,102,148,232,150,226, 64,173,126, 17,107,209,187, 37,163,209,242, 3, 36, 70,183,112,167, 41, +108,104,204,133, 92,202, 76, 11, 76,137, 46, 38, 42, 74, 87,123,198,213, 26,205,227,164,142,207, 11,161,247,180,142, 16, 22,163, +243,233,176,159,169, 63,211, 62,136,189, 36, 57, 31, 29,237,121,218,155,195, 32,165,100, 30,113,201,202, 86, 11,171,160, 22, 4, + 49,236, 40,187,115, 98, 54, 86,112, 18,251,144, 75, 4, 73, 29, 33, 85, 59,228, 20, 80, 27, 85,103,215,239, 84, 45, 83, 96,131, +229,164,103, 98,138,136, 99, 3, 82, 3, 17, 20,179,186,105, 13,140,181, 24, 35, 94,162,129,109, 88,176,139, 77,209,231, 99,124, + 37, 81,233,107,229, 68, 11,199,187, 64,234,214,132,247,118,200,159, 0,249,248,187,225,202,191, 6,225,247, 64,184,102,150,161, +179,191,128,126,225,167,225,199, 59,120, 45, 81,115, 54, 48, 64, 41,104,205,118,192, 4, 75, 77,211,176,175,236,208,197,195,180, + 55, 62,126, 27,143,160, 46, 88,198,161, 50,133,216,180, 67, 44,121,151,170,222, 44,215, 11,176, 34,163,183, 90,210, 93,187, 68, +168,103,186,136,168,177, 77, 60,200, 45,186,205,109,244, 67, 96,200,246,231,159, 70,185,244,142, 30,190,249,192,178,220, 31,130, +156,103,219, 1, 5, 87,191, 71, 93, 40,128,189, 19,222,217, 7, 76,207,171,161, 71,213, 41,104, 47, 13,240, 98,182,246,235, 15, +172,225, 27,162,113,218,255,241,134,242,202,104,241,173, 69,233, 62,179,133, 39, 2,188,223,101,233, 59,224, 41,231,161,223,207, +148,245, 62,199, 89, 27, 9,206,195,128,114, 86,202, 65, 64, 46, 1,119,213,186,232,203,193, 72,110, 87,123, 51,234,171,229, 22, + 79, 57,158,183, 10,242,234, 93,228,187, 34, 92,249,159,173,251,149, 53,240, 61,192,203,192, 7,125, 87,253, 54,142, 90,205, 48, +252, 99,120,240,231,208, 79, 63,128,235,207, 16,254,198, 49,188,243, 18,172,220, 15,189, 27,224,193, 67,244,107,231,212, 95,124, + 64,254,249,115,202,171, 27,242,131,209, 48,200, 43,208,163,136, 62, 3,161, 19, 58, 17,186, 26,136, 95, 1,249,215,127, 3,253, +221, 63,136,252,145,107,200,213,222,214, 29,247, 6,120,237, 12,125, 69,224,206, 1,122,247, 16, 54,138,134,140, 94,221, 77,221, +152,133,183, 40,172, 44, 8, 70,106, 68,142, 59,228,157, 9,190,225, 28,158,186, 12,135, 63, 0, 7,127, 12,210,115,166,164,183, +113,134,245,201,186,131,252, 51,112,231,239,163,191,148,209,127,190, 70,183, 91,202,253,115,202, 27, 27,206,179,114, 38, 98,153, +231, 42,115, 54,119,219, 31,239,229, 99,207, 71,186, 22,235, 80, 69,103,145, 21,227,140, 40, 77, 14,207, 11,139, 2, 86,131, 23, + 38,173, 38,158,243,162, 91,124, 15,149,252, 89,239,253, 86, 43,110, 81,203, 77,205,173,179,245,172,226,220,236,246, 51,121, 72, + 75, 93,164, 55, 6,143, 9,147,170,150,237,238,227, 93, 31,246, 76,135,121,138, 50, 55, 30, 4,106, 10,116, 77, 47, 83,161,102, + 27,116, 31, 68, 37,138,173, 19,243, 20,184, 34,123,126,251, 81,149, 17, 49, 79,126, 19,244, 77, 34,172, 38,172,155, 63,232,177, +101,128,235, 50,249,108,150,198,139, 66,148,234,129, 67, 77, 7,208,188,227,117,178,131, 70,183,208, 22,213,125, 4,220, 82,198, +182,224,179,215, 11,133,120, 41,154,187,168,100,159,123, 8, 93,128,105,228, 49,192,218,227, 10,248,133, 50,223, 45,118,211, 14, +152,118,249,114,174,251, 34, 14, 53, 74, 36,122,114,217, 88,171,101, 9,132, 54, 22,183, 12,245,177, 20,155,160,185,107, 33, 74, +160, 75, 29,169,235, 9, 41, 78,176, 30, 45,121, 47,223, 94, 38,207,119,152, 50,222, 67,176,175,107, 35,121,219,223,103,119,120, +149,106, 23,187, 20,125, 9, 36, 98,235, 28, 21, 6,169, 72, 45,140,170,108,135, 29, 99, 46, 20,167,195, 45,133,138,168, 61,127, +177, 95, 17,186,158, 93, 30,145, 16, 41,195, 72, 45, 6,168,153,128, 57, 23,111, 68, 58,135,181, 40, 51,183, 96,207,202,118,193, +235, 63, 9, 1,171,146,242, 80, 44,236, 32, 12,236, 42,156, 82,169, 49, 81,119,149,176,217, 17,164, 78,232, 84,170,239, 22,197, +195, 41,142,123, 24, 10,186,117,116,107,105,162, 49,117,209, 76,180, 34,165,149,190, 40,169, 55,254,186, 37, 48,153, 37, 68, 85, +169,238, 47, 55,250, 92,103,187,206, 90,136,213,110,223,154, 71,208, 74,196,194, 86, 86, 89,185, 50, 42,171,176, 34, 60,181, 34, +252,145,138,252,192,101,120,250,207, 66,247,135,129,107, 62,255,251, 10, 60,250, 81,244, 51,191, 9,255,160, 71, 95, 55,108,173, + 82,156,244,229, 4,179,184, 8, 83, 17,157,176,179,109,103, 94,203,252,122,199,199,200,217,186, 76,213,155, 62,148,102,127, 94, +140,213,235, 28, 92, 16,124,156, 25, 23, 23,129,230, 16, 16,223,147,247,189, 71,136,186,202,120,229,128,157, 92,140, 69,146,157, +123,146, 92, 28,184, 78,194, 81, 81,174,157, 4,228,235,122, 56, 11,240,178,229,163,211,139, 41,203,215,217,150,237, 71,222,174, +164, 96,150,177, 85,178, 47,184, 29,145, 15,154,255, 90,223,218, 34,247, 71,144, 1, 94, 29,224,155, 86,182, 43,254,177, 45,249, +179, 59, 54,219,204,112,100, 83,154,213,137, 32,247, 11,233,231,206,205, 7,255, 76, 15,135, 22, 16, 35,223,216,211,253, 82, 65, +182, 22,209,186, 87, 90,117,246,145,170, 8,227, 80, 25,190, 4,105, 29,225,122,176,164,184, 75, 78,125, 83,144, 65,224,190,213, +118,182,231, 72,127,142,124,223, 21,120,225,199, 49, 91, 67, 92,124,117,119, 53,224,222,239,229,199,161,110, 96,252, 77, 24,254, + 50,244,151,145,111,123, 7,196, 3,187,205,111,118,232,171,143, 40,191,250,128,242, 51,143,216,125,246,156,241,225,200, 80, 43, +185, 19,198, 99, 65,159, 17, 74,151, 88,202, 63, 66,177,184,217,117,172,172,175, 10,171, 49,194,175, 1,191,118,215, 46, 9,135, + 46, 22, 8,107,155, 58, 60, 33,112,185,160, 93, 65,183,217, 81,109,205,180, 12, 72, 66, 46, 37,194, 81, 71,168,157,141,220, 63, + 50,192,179,239,134,195, 63, 6,253,239, 51,149, 61,163,167,170, 36,187,208,232, 22, 54,127, 7,253,234, 95,132,159, 29,208,155, +135,212, 7,103,148, 55,207, 24,239, 13, 54,110, 23, 97,172,236,199, 97,182,255,221,198,204,139, 73, 80,172, 83, 48,226, 36, 26, + 83,109,177,165,115,164,106, 90, 36,131,181, 32,141,184, 88,253, 37,255,156,100,221,135,173, 20,153, 85,230,109, 93, 88, 23,163, +222,226,251,199,204, 92, 36,140,157, 45,143,133,119, 68, 22,185,234, 64,231,208,142, 34,182,182, 42, 42,148, 96,157, 86, 41,118, + 96,135,208,236,188,179,176, 73,189,226, 14, 84,122, 49, 61, 17,226,198, 89,245, 64, 40,255,187,108,105, 10,119,231, 74, 0,131, +234, 98,251,189,124,230,213, 35, 89,101, 66,207, 46, 3, 61,130, 95,122,218,142,125, 18,215, 79,141,132, 76,231,203, 76,135,243, +124,246,197, 94,126,207,211,188,112, 88,201,219,164,128, 45,235, 73,148, 89, 4,172,178,180,202,201, 50, 47,101,138, 62,213,133, + 61, 45,184,235, 97,210,134,225,129, 59, 58, 19,239,218, 42,184,177,223, 45,125,204, 60,237,181,214,133,216,205,117, 24,205,102, + 40, 17,237,172, 3,143,197,128,101,171,148, 8, 93, 15, 18,200,254,103,155,134, 35,180,191,140,119,105,109,188,173,126, 45,211, +150, 36, 40,197, 38,197, 33,152,102, 44, 38,194, 42, 18,137,211,100, 73, 28, 24, 19, 68,168,181, 48,162,108,119, 59, 74,206,211, +168,158, 16, 93,147,225,147, 94,199, 18,167,212,161, 33,208,197,104,206,142,110, 69,209, 66, 41,133, 90,178, 93,168,115,165,120, +161,159, 58,238, 16,125,151,206, 30,197,144, 32,147,166, 33, 44, 40, 52,138, 76,226,201, 68, 49, 2,206,224,235,187,141, 84,164, + 10, 33, 27, 10, 54, 52,177, 69,117,144,129, 8, 34,217, 89,215,214, 50, 86, 2, 37, 4, 98,200,172,198,106, 33, 42,192,202,183, + 31,198,136,175,200,232, 31, 10, 41,147,194,143, 26,220,152,143, 37,153,213, 64,151,162,141,195,199, 1,212,242,187, 87, 94,127, +142,134,202,241, 86,232, 47, 29, 34,223, 25, 8,127, 50,194,251,191, 23, 14,255, 67,144,119,216,155, 88,111,193,238,239,194,157, +191,129,254,198, 67,248,153, 21,245, 86,246, 27,146,119,232,158,184, 68, 85,164, 10,218,114, 19,202,156,198,212,110,237,203, 29, +121,184,144,142,163,236,135, 45, 44,133,113,234, 31,242,118,104,182,209,121, 10,179,216, 46,182, 81,188,119, 52, 77, 19,214, 69, + 56,232,108, 60, 58,250,215, 57, 58,180,236, 22,173, 48,238,102,110, 74,136,230, 20,184,210, 41,253, 19,189, 21,141, 51, 69, 98, +133,119,121, 46, 55, 61,220, 88, 27,228,100,187, 80, 63,117,142,171,235,128,212, 33,207, 95,182,221,251,237,173,177,196,239,110, +224,214,104, 56,210,223,170,112, 69,144, 94,201, 89, 25,130, 61,112,171, 67,168, 61,232,205,140,124,226, 12,126,175, 88, 49, 46, +192, 90,233,158,207, 28,189, 56, 24,116, 71, 22,169, 73,126, 44,212, 98, 44,237, 20, 33,174, 34, 60,149,224,106, 66,142, 2,156, + 11,122,223, 46,150, 6, 54,218, 32,223,164,240,245, 79,192, 59,127, 4,142,254, 48,112,228,163,129,193, 59,243,222,186,118, 10, +112,105,255, 2, 86,238, 67,249,103,192,255, 5,241, 14,148, 3, 11,177,249,226,215,168, 63,255,128,252,243,143,216,125,109,199, +102, 24,217,246,129,124, 24, 40, 55,160,244,145,170, 22,209,105,171,169, 89, 77, 29,130,144,212,120, 5, 69, 97, 68,201,177,208, + 95, 18, 18,129,208,249, 62,185,203, 72,231, 91,230, 18,141, 36,215, 18, 80,155,223,175,243, 78,179,139,132,117, 36, 28,216,202, + 68, 62, 88,224,153,103,225,210,159,131,240,113,143, 31,202,126,212,247, 86,208,235, 91,112,255, 63, 69,127,227,167,209, 79,159, +192,157, 3,234,171,143,200,175,159,115,186,203, 60, 20,177, 32,184, 58,219, 76,169,179,103, 90,155,142,197,171, 70, 83,129, 19, + 76, 68, 91, 36, 76,151,221, 41,251,154, 11, 4,185, 69,140,104,150, 5,240, 99, 49,197,234, 74,155, 43,168,101,109, 87,101, 25, +135,141,175,165,162,119,217,226, 29,105,235,216, 91, 33,105,187,116,243,146,219,119, 25,140, 45,138, 4, 83,144,219,175,211, 12, +180,114,235, 89,245, 27,122, 85, 65,181, 80,135,106,127,231, 69,251, 89, 34,108,137, 32,193,158, 77,183,175,138, 51, 93, 27,103, + 66, 84,167,184,231, 56, 81,217,116, 47, 55,125,222,161,234,100,169, 43, 83,131,224,182, 50,159, 75, 23,140,245, 81,117,129,133, +209,185, 36, 5,143, 91, 45,203,216,211,133,104,109, 46,184,179,200,172,157,195,203,166, 94,222, 38, 57,109,201,211,152,146,218, +150, 65, 11, 75,113,225,158,147,158, 61, 79,249,146, 31, 63, 71, 27, 47,244, 21,139, 75, 70, 20,153, 28, 69,139,235,220,100,235, + 85,239,156,251, 24, 72,171, 21, 99, 46,172, 17,250,126,133, 6,115, 68,209, 44,142,139,231,175, 46,198,221, 90,152, 46,225,203, + 85, 66, 16, 38, 12,112, 12, 66,138,137,149,246,196, 78,136, 18,168, 18, 76,221, 14, 20, 50, 21, 97, 44,153, 50,142,243, 36,203, +187,126,131,168, 25,217,174, 74,182, 29,189,197, 64, 18, 37, 16,131,173, 61,149,206,214,210,165, 80,171, 82,180,146, 75,166, 44, + 20,244, 85, 21, 29,199,169, 80, 52,128, 79, 99, 22, 72, 11,158,241, 55, 88, 23,102,247, 84,203,104, 35, 0,177, 15,206,161,152, + 0,173, 25,221, 27,106, 85,170, 16,131, 18,163,237, 60,109,214, 84, 97,151,237, 3, 65, 96,157,162,229, 18, 47,136, 62, 59, 23, +118,153,138,221,225,247, 45,161, 76,236,107, 35,193,114,216,181, 82,243,134,113, 51, 18,138,133,204,119, 33, 88, 24, 86, 80, 14, + 55,149,131,146,136,239, 57, 36,252,153,138,252,174,167,225,234,143, 64,252,221,216, 44,244, 28,134, 95,129, 71,255, 29,124,249, + 43,232, 63,235,225, 83, 7,212,179, 29,165,238, 12,155, 58, 65,246, 27, 1,102,225, 89,109, 81,174, 77,225,209, 48,143, 45,136, +128, 69,103, 22,108, 95,152,219,110,204, 79,181,198, 49,174, 11,192, 76,155,168,182, 93,159, 52,253,147, 43,137, 71,247,189,167, +133, 26, 37, 2, 71, 7,150,156,121, 54,216, 23, 57,232,172, 89, 62,117,131,111, 10,182, 38,239, 20, 46,103, 56,186,222, 89,238, +248,198, 69, 63, 87,147,125,147, 46,192,183, 94,131, 43,199,240,202, 29,187, 61,244, 2,125, 54,122, 75,116,108,108,131, 81, 95, + 90,219,254,250,114, 7,183, 18, 60,177, 67,223,218,193,121, 65,174, 42,241, 61,129,227,255,231,140,250, 96,164,174,172,209,143, +107,195,147,242, 32,195,231,183,132,119,173,108,157, 49, 40,250,129,158,131,219,153,237,173,202, 89,191, 63, 10, 20,236,185,143, +206,153, 9,215, 44,137, 77, 82, 64,118, 1,198, 64,184, 19,224, 16,248, 24,240, 29, 31,132,167,254, 51,144,223,225, 87,167, 87, + 97,247, 15,224, 19,127, 5, 62,247, 38,124,236,221,240,142, 63, 12, 39,223, 4,171,239, 53,168, 11, 5,244, 33,148, 95,135,252, +191,193,246, 11,232,131, 13,250, 98, 64,127,106,195,248,243, 15, 25,238,237,216, 69,101, 56, 20,118,215,133,177, 75, 12, 34,174, + 11,241,100, 84, 15, 79,107, 63,255, 44,236,178, 15, 92,244,223,155, 11,108,131,125, 48,147, 40,105,204, 46,168, 10, 72,177, 7, + 37,244, 78, 56,233, 60,237,173, 90, 90,161, 68,131, 84, 72, 31, 9, 99,176,142,253,134,194, 13,129,163, 63,228, 5,253, 10,243, + 83,117,226,192,159, 95, 67,191,244, 39,225, 87, 79,225,245, 39,208, 91,149,242,133,123,108,239,110,121, 20,148,211, 96,132,184, + 80, 61,217, 76,205, 18,170, 50,135,141,236, 73, 55,235, 60, 70,204,158, 73, 52,169,214,253,247,166, 69,119,231,122,251,137, 56, + 87, 2, 72,149,105,132,222, 10,203,116,206,138,135,207, 85,157, 71,249, 14,230,208,133,136, 42, 6,136,181,169,148, 43,227,172, +180,153,172, 90,211,168, 85, 26, 29, 28, 79, 7,243,160,146,226,121,214, 49, 46,186,233,202,206, 5, 51, 90,150,183,117,153, 80, +172, 21,211,130,156, 41,164, 81, 89, 75,157, 88,226,203, 0,166,224, 93,178,250,152, 46,136, 93,242, 26, 25,207,118,196, 46,109, +107,217, 22, 23, 35, 78, 23,211,190,234, 65, 49,117, 26,174,154,130,126, 18,221, 53,237, 64,235,116,167,232, 96,153,243,205,247, +242,213,231,225,121,185, 80,208,151,232,243,165, 30,232, 49,239,186, 46,236,119,111,115, 33,104, 25, 30,123, 49,167,178, 15, 78, +159,158,149,230, 4,241,213,155, 44, 64, 53,210, 28,242,238,150,106,148,247,166,198, 63, 73, 61, 97,157, 16, 2,185, 22,134, 90, + 38, 37, 57, 90,167, 75,128, 46, 0,183, 75,146,253,242,181,144,197, 37,132,134,107,245,207,118, 41,133, 56,137, 38, 35,136, 48, +214,202,152, 51,121, 28,231, 63, 31, 2, 81,194, 4, 16,209, 96,126,174, 64, 71,140,102,187,204,165, 64, 80, 15,126,137,182,106, +206, 6, 79, 91,247, 9, 73,145, 49, 23,198, 82, 24,134,157, 53,157, 2,163,215,167,170,185,233,228,155, 1, 16, 87,140, 78, 60, +151,229,223, 51,137,223, 22,186, 20, 72, 98, 56,214,136, 49,205,197,193,229,198, 85,175,182,127, 9,126, 8,197, 54,139,174,118, +163,144, 72,144, 72, 31,109,100, 98, 67,238,234,160,136, 6,139,176,244,182, 16,133, 80, 33, 68,143, 87,205, 35, 99, 19,210, 53, +202, 82,176,155,217, 90,148,147, 12,199, 69,233,226, 1,225,219, 86,132, 63, 39,240,254, 31,132,245,127, 0,242,164, 47,251,190, + 10,155,255, 1,222,250, 89,244,211, 25, 62,121,136,190, 81,168,155,115,223,159, 87,106,174,179,191,116, 17,125,164,137,249,218, +173,123, 27,242, 89,160,230,173,119,235,166,171,206, 69,122,138,140, 92, 20,171,184,192, 65,206,171,210,197,247,244, 59,132,191, +111,243, 77, 57, 48,141,178,250, 0,235, 35,123, 61, 74,113,140,120, 50,146,220,218, 79,212, 67,224,210, 78, 57,188,158,144, 27, +107, 88,117, 22,237,167, 66, 56, 15,134, 87, 93,117,240,214, 6,238,109,173,152, 95,139, 54, 30,239,122, 8, 79,128, 94,133,248, +121,200, 91,139,251,108,137, 98,193,178,192,245, 48, 82,159,235,145,179, 98,162,176, 35,161,251,174, 67,174,254,211,115,106, 41, +164,147, 54, 94, 16, 56, 16,228, 97,133,215, 70,228,190,137,139,234, 13, 33,188,167,231,202,102,135, 14,202,249,194, 31, 35,126, +152, 30, 6,232, 14,131,161, 60, 75, 64,206, 5,222,244,232,210,111, 63,128,223,127, 3,158,253, 62,144, 63,226,127,248,239,194, +253,255, 29,126,227, 37,248,171,103,240,115, 25,214, 61,172,191, 6, 31,251,139,240,111,119,240,194, 85,208, 39, 13, 87,183,219, +192,221, 51,120, 69,168,255, 60, 82,127,102,160,190,114, 78,201, 3, 15, 66,229,193, 59, 2,181, 11,214,105, 23, 19, 64, 86,103, +212,140,139,160,157,234,177,231,173,164, 38,241,226, 37,179,192,177, 86,203,121,151,232, 59, 95,177,125,115,200,214, 45, 74, 0, +221, 41,178,170,150,197,126,152,144, 28,145,222, 4,129, 82,130,253,129, 62,194,141, 10,239,221,194,209,215, 67,250, 54,239,208, + 23, 9,107,188, 1,183,255, 29,120,241, 19,240,171, 7,232,163, 27,212,219, 91,234,151, 79,217, 62,216,113,191, 19,118, 68,131, + 32, 45, 46,140,193,185,211,206,129,153,149,208,178,192,117, 98,197,223, 36, 50, 66, 23,236,215,203,238, 92, 22, 32, 56, 9, 74, +167,208, 5,101, 20,119,247, 85,123,189,180,204,119, 70,125, 27,241,147, 46,163,183,150,194, 94,181,110,115,237, 44,110, 93, 60, +158,178,176,137, 52,118,154,103,238, 89, 71,174,226, 54, 41, 11,161, 42,163, 53, 48,113,234, 98, 61, 17, 46,137,255, 61,100, 82, +196, 55,145,153,250,185,145, 17,106,132,181, 71,113, 54,162,164,250, 40,221, 86, 9,182,130, 9,173, 59,109,241,167, 50,143,245, +138,143,236,203,210, 98,172,115,215,186,180,247, 7, 47,230, 81,247, 98,233,109, 21, 48,249,206,245,130,162, 93,246, 34, 90,245, +194,170,182, 29,103,225, 2, 51,126, 63,135,116,182,138, 61,150,209,242,219,140,238,213,187,109, 89,196,172,182, 61,179,232,172, + 79, 91, 50,229,219,191,171,186, 79,152,175, 62,253, 8, 8, 41, 69,186,148, 72, 33,178,142,137,163,131, 3, 82,234,184, 95, 10, +219, 51, 27,129,215,150, 29,208, 38, 62,139,215, 69,101,150, 42,234,196,252,247, 61,254,130,250, 30,146,117,233, 49,118,123,183, +158,160, 74,234,146,231,206, 7,116, 28,253, 89, 45,134,169, 85,165,198,197, 7, 72,148, 16, 3,171, 16, 72,253,202,206,136, 80, + 40,181,184,246,161,210,135,136,174, 18,104,165,139, 9,237, 58, 42, 59, 74, 45,134,215, 85, 91,199,245, 93, 79, 77,206, 54, 16, +198, 0, 0, 32, 0, 73, 68, 65, 84, 29,121, 28, 40,195, 48, 17, 87,223, 86,247, 59, 73, 24, 43, 73,125,199,211,169,178, 70, 56, + 10, 16,171,221, 44, 2,115,192,253, 4, 0,104,172,140, 86, 8,147,189, 44, 53, 23,178,103, 9, 38, 7,209,107, 85, 6,212, 16, +167,158,234, 20, 68, 9,197, 68, 16, 49, 59,141,162, 40,154,236,192, 91,185, 40,111, 37,202, 97, 86,142, 11,172, 74, 36, 94, 57, + 32,252, 81, 65,126,232, 50, 60,253, 35, 16,191,207,126, 24,125, 0,219,159,134,135,127, 25,125,249, 13,248,100, 15, 47, 29,162, +219,145,146, 71, 84,109, 17, 93, 27,237, 37,212, 11,128,221,201,231, 96, 66,165, 9,123,102, 35,143, 24,230, 32, 1,149,249, 1, + 23,153,120,136,118, 3,150, 61,198,130,143, 44,231, 47, 23, 88, 48,165, 23,187, 43,113,144,204, 84,232, 23,142, 6,201,144, 78, + 2, 71,201,138, 64, 12,246, 62, 29,172,129,157,210,141,202, 74,132,116,117,133,124,203, 17, 28,186,250,243,106, 50, 31, 93, 39, +166, 72,127,114,101, 66,173, 85,180,157,247,170,194,106, 13,188, 7,248, 93, 32,191,229,239,107,178,255, 22,139,189, 47,181,122, + 14,112, 64, 66,135, 30, 5,216, 6,100, 20,184, 46,132,239, 14,132,135,174,208,219, 85,120,171,218,173,164,157,108,217, 46,132, +225, 77,168,125, 36, 62, 17, 57,188, 93, 24,243,226,254,228, 69,166, 79, 32, 7,222,169,222, 7,110, 3,223,122, 8,127,234, 89, +120,223,101, 72,239,180,181, 74,249,207, 97,247, 26,188,120, 19, 62,149,225,142,239,168,255,141, 30, 62,118, 12,239, 62,178,226, +206, 8, 95, 62,131, 7,119,224,213, 17,190, 34,112,119,109,240,152,113,160,202, 14,189,156, 57,143,112,175, 6, 30,141, 50,167, +146,234,140,181, 44, 45,255,219,253,170, 5,177,176,161,133,191,185, 11,211,144,103,154,232, 88,241,145,169, 3,170,213,138,158, +102, 87, 68, 38,139,210, 13, 41, 17, 14,220,153,112, 20,225,138,192,129,218,251,112, 56, 90, 30,250,181,119,155, 15, 61,220,240, +217, 87, 48, 2,221,248, 99,240,202,127, 13,191,242,144,250,202,147,232, 78,208,219, 27,202,203,167,108,206, 70, 30,174, 2, 91, +181,159,151,216, 58,107, 33, 6,123, 95,203,232, 89,219, 11,223,115,173,112, 33,146,122, 38,144,233,204, 91, 40,173,184,214,249, + 18, 90,171,109, 20, 90, 7,223,123, 67,182,115,119, 67, 90, 98, 66,167,184, 81,220,194, 42,147,127, 26,157,133, 63,182, 79,182, +162,107,176, 43,247, 53,123,145, 84,113, 53,122,176,228, 70,141, 97,206,234,198,184, 10,170,150, 25,190,155, 80,176, 22, 49, 29, + 68,232,163,208, 41,236, 90, 96, 72,211,211,212, 58,185,190, 9, 86, 34, 6, 31,139,118,190,131,159, 39, 27, 86, 52, 82, 16,122, + 95, 73, 13,101,145, 88,119, 65, 81, 43, 45, 6, 86,247,181, 58, 77, 0,183,212, 38, 72,109,107, 14,157,188,219,226, 10,124, 93, + 20, 66, 46,248,199, 3,198,173,175,174,123,216, 3,191,200, 99,246,242,125,182,251,194,163,190, 52, 39,232,219,216,219,150,202, +121,149,253, 92,111,120, 92, 80,215, 8,161,178, 72,190,155, 57, 62,246, 85, 83,128,195,144,136, 93, 71, 8,209,168,163, 34,100, +132, 77, 46, 83,180,172, 77,208,202,130, 90,184,164,234, 53, 87,124,251, 94, 97,159,196, 38,251, 34,197,189, 85, 66,245, 64,153, + 90, 33, 69,114,181,124,143, 97,216,161, 37, 19, 68, 40, 49,162, 57,147,107,133, 60, 58,232, 40, 16, 66, 36,106, 96, 72, 66,201, +163, 93, 50, 67, 32,164,206,197,129,117, 62,248, 67, 34, 11, 12,187, 29,195,176,163,148,108,245, 37,165,201,254, 22, 99, 32,172, +215,148,174,243, 41,115,245, 61,188,101,156, 32,198,128, 89, 86,248, 20,177,236,242, 75, 65, 57, 8,112, 37, 64,231,180,182,233, + 54, 40, 86,144, 68, 22,254, 44, 49,159,153,186,132, 81,213,118, 3,177, 6, 52, 65, 31, 13,138, 94,170,221, 52,211,146,216, 34, + 74,240,204,243,160, 74,151,108,148,124,160,202,186,192, 65,169,172,178,176, 42,129,120,184, 34,188,144,144, 63, 29,145,223,249, +117,112,252, 95, 66,248,128,237, 70,199, 79,193,249, 95, 69,111,125, 6, 62, 23,224,215, 14,225,150, 26,163,189,100, 83,150,213, +249,103,244,128,223,185, 42,199,253,228,169,105, 39,213, 12, 22,113,126, 80,100,162,255,204, 15,112, 88,136, 65,227,226, 80, 87, +157,199,241,141, 47, 66,116,129,141,204, 15, 84,239, 19,128, 84,109, 47,222,110,183, 73,236,223,165, 12,117, 35,196,171,201, 86, +195,143, 42,171, 92,233, 59, 67,229,134,152,144,247, 31, 34, 47,184, 15,253,176,183, 3,241,114,156,130, 87, 88, 39, 43,230,177, +206,109,228, 14, 72,231,208,191,110, 33, 35,250, 34,156,122,242, 87, 91,189,236, 42,228, 98,171,136,195, 54, 47, 13,240,132,162, + 15, 19,104, 68,222,233,121,236,247,138, 49,214,215,213,105,167,193,248,228,207, 39,248,212, 6,185, 7,210,249,216,119,227,163, +250,182,147,173,118, 71,140, 91,144,187, 1,217, 9, 60,119, 0, 63,250, 52,124,211,211,176,234, 45, 96,231,214,167,224,183,238, +194,235, 91,232, 59, 56,237,160, 91,193,135, 4, 62,186, 54,209, 38, 61,188, 54, 88, 34,206, 70,225, 81,128, 39,175,194,199,158, +133,119,221,134,127,244,150,241,209, 79, 21,118, 88,129,221,250,161, 84,103, 4,116, 85, 40, 65, 39,187,162, 52, 66, 32,243,238, + 79,253,240, 69, 46,228, 79, 87, 23, 60,122, 1,200, 75,120,134,216,100,194, 70,236,129,208,173, 8,151, 87,240, 68,180, 15,222, + 51,138, 60, 81,225,104, 13,209,255,233,190, 14,214,191, 23,186, 23, 76,184, 16, 6,168, 95,132,219,127, 22, 94,122, 21, 62,123, + 21,189,115, 3,125,144,169,119,118,228,215, 55,108, 54,133,211, 46,184,226,219,217,213, 58,219, 54,106,133,162,230,106, 9, 65, +137,121,127,215, 24, 22,182,166,101, 38, 1,133, 69, 39,180,176, 97, 57,251,124, 84,251, 62,237,210, 19,221,207, 77,158, 11, 87, +179, 40, 73,115,120,248,202, 74, 23, 59, 84,130,141,101,163,226,249,227, 54,245, 72, 2,169, 88, 49, 44, 65,125,183, 40, 11, 38, +121, 37,151,106, 1, 31, 69,167,156,113, 69, 24, 49,119, 66,136, 54,134, 23,153, 3, 59,130,127, 22,179,170,253,188,117, 46, 60, + 83, 76,168,143, 28,139,218, 14,223, 46,233,230,230,105,231, 64,223,246,250,106,178,149,140,238, 37,130,237, 45, 56, 26,148,103, +223, 43,102, 41,113, 50, 91,202,218,254,116, 54,146,249,120, 93,116,186,112,133, 61,106,165,206, 53, 3,153, 48,174, 75, 17,100, +185, 16,102,178,159, 0, 39,123, 5,253,109,140,160,139,209,251, 98,180,125,161,123,156,196, 92,141,131,180, 92, 53,248,207, 19, +131, 77, 66,131, 43,211,145, 64, 10,129, 36, 1, 77,137, 90, 43, 35,118,110,137, 42, 49, 70,134, 90,232,179,178,234, 87,108, 98, +152, 18,231,116, 47, 79, 46, 60,134,189,155,167, 14, 98,246, 83,153,125,238, 34,139, 14,163,148,233,123, 75, 20,106,169,148, 90, +217,141, 3, 37,231,105, 26, 16, 66, 64, 99,164,150,226,170,121, 99, 40,132, 16, 72, 53,161,170, 12, 46,164,107,187,250,148, 58, +186,104,226,140, 25,152,163,116, 34, 72,191, 34,151, 72, 41,133, 33,143,166, 31, 41, 54, 9,111, 96, 28,141, 9,173, 22, 96, 38, + 93,240,226,159,173,216,151,249, 54,158,174,138,114, 18,133, 46, 41,235, 8, 39, 46, 8, 9,117,126,203,165, 46,246,193,107,191, +242,143, 5,189,107, 25,154, 34, 86,168,179,143,233, 83, 21,186, 20, 73, 43, 99,126,111,115, 53,175,159,199, 42,118,190, 15,238, + 5,214,170, 28,231,202,122,132,131, 26,232, 37, 16, 82,143, 92, 23,228, 27, 2,242, 7, 35,242,209,103,224,218,159,128,240, 3, +182, 35,222,252,127,176,251, 63,225,193,231,208, 87,182,240,210, 26,190, 18,224,254, 72,221, 20,187,153,227,243,190,160,115,241, +110, 50,210, 86,185,235, 66,125,158, 4, 41,113,126,247,187,246,201,240,150,162,180,194,236, 99,245,186,255,228,215, 89, 56, 63, +143,222,252, 97, 78,209,126,236, 62,186,168,173,206,208, 47,201,222,165,122, 71, 79,163, 34, 37, 11, 10, 9, 93, 48,161,207, 81, +176, 14,206,211,138,100,140, 86,208,127,231,101,228, 82,111,127,137, 85,244, 46,208,179, 76,197,196, 22,242, 32,219, 15, 54,120, + 27,114,210, 89, 40,203,213, 71, 16,126,218, 68,226, 15,131,209,107, 54,174, 55,216,121, 83,120, 90,224, 97,177, 46, 42, 84,216, + 96,182,183,195,232,241,171, 98, 94,247,195, 8,231,254,154,175, 34,124,244,216, 78,167, 87, 11,156,237, 8, 7, 2,199,149, 85, +168, 12, 3, 72, 82,250, 32,164, 67,136,103, 32, 55, 5,186, 14,126,228, 25,248,222,119,194,149, 39, 96, 56,133, 55,239,192, 75, + 15,208,159,188, 71,189, 89,144, 39, 35,225,253, 10,215,253, 85, 63, 3,238,136,197,191,173, 51, 60, 29, 97,221,153,247,254, 93, + 21, 62,244, 78, 88,191, 31, 54,183,224, 36,192,189,140,222, 83,179,218, 61,145, 88,191, 81, 57, 42,202, 46,193,214,223,103,149, +121,160,211,194, 56,150,194, 72,145,153,188, 37,111,131,219,156,173, 40, 50, 29,248,161, 5, 46,244,193, 4,112,235, 72,184,214, +195,123,123,120, 78,145, 39, 43, 28,158,192,193, 11,208,127,135,165,197,133, 4, 28, 66,247, 36,200, 17,108,191, 2,103,255, 45, +188,246, 73,248,226, 10,253,210, 13,244, 65, 65,135, 29,245,246,142,242,198,150,237,160,156, 39, 60, 81, 45,184,178, 91,124,252, +183, 24,225, 78,228, 56,155,144,141,126,200,137,182,216, 79,155, 52, 4,157, 57,224,131,238, 39,123,197,198,205, 14,179,224,110, +172,179, 10, 90,196,185, 4, 75,218, 73,181,189, 39, 85, 38,222,185, 15,117, 76,175,224,175, 87, 82,245, 61,190,191,206, 69, 73, + 81, 88, 43, 12, 45,183, 96, 74, 64,210,249,148, 12,243, 56,120, 9,117,232,130, 32, 18, 73, 98,162, 54, 45,213,133,108, 86,156, +181,218,254, 94,125, 26, 48,248,152,123, 17, 75,190, 7, 78,137,173,115,246,170,157,100, 22,197,142,126,174,164, 22,106,179, 16, +135,202,130, 93,174,139,184,209,198,110,151,118, 17,241,135,109,154,130,200, 82, 59, 48,187, 11,154, 20,168,125,175,221, 66, 62, +201,222,158,219,214, 18,210,152,252,162,251, 68, 57,153,145,189,242, 54,204,119,189,160,168,147,133, 80,238, 34, 94,182,157,177, + 23,237,114,181, 9, 9,221,166, 22, 83, 98, 21, 19, 33, 90,134,103,241,142,123,212, 74, 29,243,100,228, 86,170,217, 19, 67, 71, + 46,133,206, 87, 40, 65,228,130, 13, 79, 46, 44, 36,246,163, 90, 13, 44,228, 83,161,133,114, 63,138, 93,180,181, 86, 52,206, 14, +154,234, 2,200,237,144, 25,119,219,233,245, 12,205,187, 30,130,191, 63, 70, 30,181, 21, 83,182, 77,174, 79, 57, 81, 53,242,103, +140,164,152,233,186, 68, 74,137, 24, 35, 41, 70,143,250,141, 38,142, 44,182,111,239, 82,154,160, 58,185, 20, 70,135,216,104, 67, +203, 54, 76,186, 8, 53, 38, 67,220, 6, 91, 95,215, 90, 73, 79,118,214,153,131, 5, 89,181,136,196,138, 78,196, 39, 17,143, 7, +237, 39,207, 8,250,198, 14, 61,205,200,165, 72, 76, 74, 26,117,250, 48, 73,173,196, 92, 57,192, 2, 20, 30,102,101,231,123,167, + 20,224, 48, 42,199, 69,185,146,149,163, 18,233,250, 21,225, 70, 36,188, 67,225,163, 32, 31, 89,193,251,142,224,218,215,193,193, + 15, 64,248, 54,168,199, 70,200, 58,255, 49,216,254, 18,122,235, 20,190,216,193, 87, 78,224, 86,134, 71,163,129,100,234,136, 90, + 48,251,158,164,115,202,199, 85,157, 37,189,109,165, 32,179,135,167,197, 24,180,225, 13,213, 80,183, 68,255,119, 90,237,146, 83, +152, 70, 98,101,202, 36,152,139,249,164,242,144, 57,117, 44,137, 53,204,211,135,194, 11,183,244, 16, 86,201, 14,124,196,210, 49, +143, 18,114,220,217,165,234, 56, 34, 81, 45, 87,252, 78,177, 91,194,183, 31, 19,190,254, 4,158, 58,180,219,209,232, 97,237,197, +105, 52, 99,134,156,209,187, 3,122,223,119,229, 77,104,113, 28, 97,179,130, 77,239, 9, 51, 10,167, 25,182,163,123,232,252,214, + 94, 21,238,143,150, 86,166,254, 23,192, 10,190,108, 60, 11,118,231,151,159, 85,176, 19,229,216,151,198,159,222,217,107,253, 84, +103, 39,206,195, 12, 55,160, 63,173, 92,121, 45, 83,171,144, 18,200, 46,160, 33,194,191,114, 5,249,163, 55,224,169, 19,107,139, +111,223,129, 79,191, 5,191,249,200,186,239, 71,217, 60,240, 7, 6,129,209,151, 3,108, 21,185,158,224,125, 43,120,102, 5,207, + 94,130,171, 55, 96,243, 0,238,158, 27, 32,231,139,111, 66,249, 42,220, 42,118,145, 57,207,200, 58, 65, 81,228,178, 16,179,114, +242,198,192, 78,149, 44, 98,186, 66,239, 88, 90,120,136,122, 39, 95, 23,251,191,165,159, 55, 44,243, 27, 26, 52, 40,216,243, 30, + 81,186, 2, 49, 10, 97, 21,237,159,190, 35,172,122,184, 17,225,131, 35,242,244, 19,134,181,237,191, 17,214, 31,183, 85,131, 68, +159, 5, 87, 40, 3,122,250,223,195,221,191, 15,111, 10,188,114, 21,190, 12,245,230, 14,221,141,212,243,145,114,115,100, 87,148, + 97,229,221,158,206,151,204,230,177, 22,223, 91, 75, 50,171,143, 97,121, 61, 18,116, 82, 77,203, 98, 15,204, 84, 88, 27,241,172, +237,225,219,122, 66,208, 9, 27,187,164, 31,139,143,178,167, 76, 4,167,118, 93,180, 84,103,239,116,163, 71,173, 78, 23, 0, 49, +238, 69, 66,167,240, 22, 29,173, 0, 31, 40,156, 45, 50, 33, 22,227, 68, 19, 88,201, 62,105, 43, 6,131,207, 72, 45,174, 82,103, + 10,143,106,130, 60,173, 70,156, 91,251, 69,163, 20,139, 83, 94,246,167, 45, 53, 75, 85, 41, 11, 69,119,139, 71,142, 11,245,120, +184, 64, 94,147,230,253, 95, 50,232,117, 63,169,188, 17,207,178, 95, 86, 38,143,250, 66,133, 80,153,125,235,178,184, 80,244, 23, + 80,224,117, 65,190, 92,150, 58,245,115,184,121,237,117,154,198,202, 62,199, 93, 23,248,220,197, 20,129, 11, 56,119, 46, 92,106, + 91,162,228,172,146,183,131, 48,138,176, 10,198, 79,183,145,122, 32,186, 85,122,172,202,160,133, 96, 59, 42, 63,167,179,117,239, +126,233,138, 93,111,147,163, 90,140,149, 80,205,138, 70, 8,179,250,114,159,209,249,182,113,102, 42, 51,196, 69,104,197, 54,122, + 7, 47,132,148,246,124,254,187, 97,100,216,237,208,156,125,210, 22,140, 18,234, 59, 87, 21, 72, 33, 16, 82,240,159,175,101,114, +148,105,169,213,106,105, 46,149,161,100, 82,140,116,169,163,235, 58, 43,242, 49,209,133,200, 65,223, 35,190, 78,218,229, 76, 46, +217,156, 78,181,112,190, 57,183,241,127, 54, 5, 76,169,197, 58,244,102, 3,116,197,113,136,145, 68,176,145, 82,187, 21,166,133, +218,116,218,195,184, 88, 67,220, 66,206,253,129,205,157, 29,131, 8, 39, 91,123, 17,123,143, 62,220, 72,129, 80, 57,146, 22,143, + 41,156,169,176,243,204,220,203, 90,185, 49, 84, 46,145, 72,215,214,132,143, 4,228,123, 10,124,211, 17, 60,249, 33, 56,248, 54, +232,126, 39,200,123, 77,229, 91, 43,212,155,176,249, 57, 56,255,135,176,249, 60,250,250, 8, 95, 57,132, 55, 42,220, 25,225,180, + 80,115,158,110, 75,230, 25,115,187,214,162, 64, 91,151, 45,237, 52,152,176,109,210,205,159, 70,209,184, 31, 62, 88,227,158, 2, +180,133, 71, 75,110,170,225,106,129, 55,237, 81,170, 70,135, 17,153,205,185,234, 17,126,225, 32,248,161,111, 99, 10,233, 2,178, +138,200,229,128, 28, 37,228, 48, 88, 7,124, 24,152, 60,124,125,176,127, 78, 43,188,178,179,177,248,123,122,228,119, 92,129,167, + 14,102, 19,189,170,177,220, 31,142,232,121,134, 71,150, 44,199,221, 29,250,208, 59,244, 3,219, 45,201,221,132,108, 42,114,154, +225,216, 47, 63, 15, 43, 58,229, 79,122, 20,154,211, 67,204, 74,102,251,242,240,116,176,238,120, 0,206,133,122,154,209,123,133, +112, 46,200,161,204,185,156,111,100,235,224,175, 38,120,223, 33,220,207,240,230, 22,158,128,248,206, 74,124, 54,194,175, 91,244, +169,252, 91, 79,193,251,175,217,101,228,141, 71,240,218, 22, 62,183,129,219,131,189,222,151, 10,114, 89, 9, 15, 10,250, 85,165, + 62, 97,165, 67,158, 95,193,187, 86,240,196, 26,222,117, 4,215,158,182,240,150,221, 93,139,200,187,189,131,135,213, 30,196, 36, +134,159,125,111, 71,120,103, 64,239, 6,184, 63,160,215, 43,235,161,114,245,110, 49, 74,148,111, 32,202,130, 38, 72,181, 86, 40, +102,243,221,182,238, 41,122,250, 94, 59, 91,146,107, 5,251, 96, 98,177,228, 35,250, 24, 35,241, 48, 18,214,129, 16, 58, 98, 88, + 33, 79,172,224,249, 1,121,250, 89, 56,250, 55,173, 67, 15,151, 32, 28, 65,184,108,223,161, 60,130,205, 63, 68, 31,253,143,112, +231, 54,220,185, 2,183, 34,122,115, 68, 31,110,169, 12,232,249, 64,189, 59, 48,170, 80, 86,182,143,148,234,244, 62,194,228,189, + 14, 18, 45, 37, 49,202, 36, 18, 8, 75,236,113,176, 85, 72, 89,236,120,165,169,185,151,140, 6, 23,136,181,244, 47,169,243, 65, +186, 36,137, 73, 89, 70,140,218,184,127,137, 46, 45,158, 83,222, 20,241,163, 31,127,193, 45,105,154,196,121,219, 13,231, 58,111, + 63, 87,201,198,228,131, 66,149, 48, 33,165,117,193,112,105,251,246, 78,103,188, 52, 50,119,180,109, 12,155,139,175,213,194,156, + 69,176,138, 86,200,238,251, 1, 45, 11, 49,158, 76,252,237,150, 60,201, 20, 55, 90,177, 44,241, 4,108,116, 86,228, 79,212,184, +198,151, 95, 12,190,195,162,195,180,100, 59,159, 36,176,100, 93,232, 94,108,123,123, 93,155,254, 38, 46,196,108,157, 31, 67, 89, +247,169,110,203,108,244,198, 28,176, 49,178,236, 69,127,234,226, 82, 22,189,160, 23, 30,239,202,121,187,252,239, 11,191, 39,197, +104, 5, 47, 68,159, 28,138, 71,149, 54,133,191, 21, 45,245, 15, 89,157,198,167, 30, 78, 35,106,131,199,148,208, 24,168,217, 26, +170, 28, 64, 71,195,121, 7,145, 9,143, 59,229,192, 47, 0, 73,179,185, 79,247, 35, 78,171, 78,202,117, 9,166,175,144, 69,151, +174,170,140,217,212,232, 53,103,150, 15,175,249,220, 61, 43,222, 39, 64, 13,104, 99,211, 53,220,175,238, 60, 5,132,170, 78,157, +244, 53,245,168,149, 84, 70,226,104,157,123,159, 58,250,190,103,213,117,244,169, 35,166,196,110, 28,201,121, 52,183,212,241, 9, + 67, 57,100, 55,236,236,223,229,209, 70,254, 45,149, 78,194,116, 65, 75,237,234, 23, 69, 56,112,245,251, 52,214, 90,160,250, 66, +244,236,232, 90,209,123, 35,111,102, 91,157,214, 77,229,168, 55,177,144,160,236,138,141,200, 82,128,117, 23, 56,140, 29,135, 39, +145,235,231,153,124, 54,112, 37,195,250,228,128,240,194, 33,242,167, 10,124,248, 26,156,252, 48,244,255, 34,132,103, 45,146,178, + 69, 57,149, 83,208,155,176,251, 36,156,253, 12, 12,175,160,183, 10,188,210, 91,231,245, 48, 27, 40,133,130,250, 41,210, 0, 39, +226,170, 13,117, 35,120,227,224,139,170, 47,250,124,116,188, 18,199,144,202,158,170, 69,116,161,153, 92, 46,203, 9, 11,150,121, +107,133, 22,114, 82, 89, 64, 30,130, 76, 93,126,232, 5, 14, 34,116, 66, 88, 71,147,123, 31, 4,228,146,167,166,173, 34, 28, 38, + 59,117,218,213,191,217, 22, 2,112, 82,225, 56, 34, 71, 9,110,172,145,203,107,211,233,158,102, 99, 84,142, 25,125,115, 64,239, +156,193,131, 1,189,183, 67,111,102, 67,252, 13, 10, 71, 32,151, 34,218, 69, 84, 11, 50, 84, 36, 41,194,202, 94,179,131, 41,255, +113,206,212,212, 96,133,112, 19, 9, 59, 63, 17, 91,129,116,165,148,228, 96, 95,127, 61, 23,191,233,228,126, 4,220,170,214, 73, +191,183,183,204,239,195, 17,182,110,190,255,161, 67,248,208, 85,251,190,175,159,195,107,231,232,103,182,240,112,132,203, 10,183, + 54,200,189,140,174,162,125,173, 43, 61,242,237,107,120,225,192,108,120,103,213,104,176,247,119, 38, 8,188,247,101,187,168,245, +201,126,254, 19,191,124,180, 7,114, 21,237,181,122, 40,200,218, 35, 69,182,129,122,216,177,122, 88,185, 52,154,247,126,231, 7, + 71,245, 38, 32, 72,179, 32, 9, 73,103,149,111,231,110,193,117,116,167,130, 88,176,137,233, 72,197,242,150, 87,209,196,112,135, + 29,225,160, 35, 92,238,225,125, 17, 62, 84,144,247, 62, 9,135,255, 50, 28,125, 28,194, 21, 79,113, 11,150,195,190,253,101,244, +225,127, 1,119, 94,133, 91,135,240,224, 58,220, 83,244,246,128,222,222,162,155, 17, 61, 31,209, 71,153, 58,130,244, 74, 10, 50, + 91, 44,125, 38, 62, 33, 79,163,225, 89,162, 39, 38, 78,197,175,122,224, 72, 89,110,168,236,112, 13, 77,228, 41,179,133, 83,147, + 71, 10, 55,206,131,119,160, 41,206, 54,184,166, 43,104, 7, 97, 81,221,203, 75,104, 60,136,165, 80,108,250,189,110,251,138,227, + 12, 33,145, 32,147,170,187,250,101, 42, 53, 98,165,226,201,110, 30,186, 49,173, 14,230, 96,153,214,245, 38,111,111, 67,235,198, + 61,110,181,182,247,119, 18,243, 10,125,180, 59,233,110, 17,135, 28,218, 97, 77, 91,151, 9, 33, 90,103,154, 17,134,106,163,220, +118,110,102,220,221,163, 58,165,136,233, 34,229,177,173, 53,226, 36, 22, 83,127,207, 46, 20,216,182, 91, 95, 22, 85,149, 61,121, +208, 18,126,213,108,123,121, 97, 85,219,243,103, 47,134, 27, 23,131,224,154, 78, 34, 94,132,144,234,190,253,109,143,207,161,109, + 37, 97,207, 60,206, 73,143, 33, 78,138,254, 38, 59,172,165,184,213,111,174,188, 51, 31, 97, 47,228,140,168, 66, 10, 1,233, 18, + 37,207,152,241,162, 74,206, 35, 57,231, 41, 98, 86, 22,160, 16,213,199,111, 30,109,202,210, 94,103, 9,129,228,163,127,183,225, +236, 41, 26,179, 8,195,104,141,162,104,155,212,186,221,109, 10,100,169, 86, 27, 48,126, 75,219,155, 75,140, 19, 52, 41,151, 66, + 41,251,130,203, 82,109,245,147, 67, 37,213,202, 88, 10,197, 45,109,187, 49,211,117,153, 46, 6,142,186,142,176, 62, 96, 40,133, + 49,143, 28,212, 74, 56, 58, 50, 42, 94, 8,164, 24, 72,126, 97, 42, 90, 25, 75,102, 44,133, 84, 29,215,113, 20,204, 7, 29,167, +187,141,206,226, 22,117,145, 92, 18, 56, 47,156,109, 10,111, 84, 24,138,249, 41,111, 4,187, 33, 30, 69,216,121,202, 65, 95, 33, +105, 36,252,240,117,210, 31,186,194,193,159,127,141,114,167, 34,207, 28, 34,127, 48, 33, 63, 88,224, 93,223, 2,235, 31,181,168, + 72,137,134,183,212,211, 57, 65, 75, 31, 65,254, 34,156,254, 18, 12, 95, 67, 31,156,193, 87, 19,220, 46,112,199, 11,186,227, 28, + 77, 30,107,169, 78,226, 45,133,214,133,239,166, 42,146, 23,243,164, 3, 65, 86, 9, 89, 41,212, 56, 49, 92, 85,231, 2, 45,117, + 65,153,155, 76,162,134, 48, 21, 89, 48, 28,179, 71,249,245, 45, 50,212,126, 22,233,196,187,110,111,223,150,191, 62,104, 62, 39, +117,131,182, 7,174, 55,234, 13, 46, 86, 27,125, 30,167, 98, 81,167,207, 88, 48,136,222,223,217,226,119, 87,225,171, 91,234,173, + 45,220,223,160,183,119,214,225, 62, 28,144, 71, 70, 44,146, 8, 60, 10,232,198,216,233,114,201, 95,147,243,130, 30,102,219,177, +119,254,243, 81,231,211,112,180,221, 57,199,157,245, 55, 67,129,135,234,168, 89,191,237,106, 50,165,219,206,215, 3, 62, 27,212, + 67, 65, 86, 98, 93,126,174,112,176,130,167, 59,184,148,173,240,199, 4,215,122, 27,239,223,220,218, 68,225,229,209, 2,117,142, + 20,190, 52,160,159, 26,144, 33,195,211, 61,242, 29,199,200, 55, 31, 33,151, 86,112,210, 91, 17, 7,155,195,238, 92,229,118,234, +235,135, 52,218,195,248,238, 35,184,190,131,211,157,193, 0,206, 2,108, 35,114,167,162, 37, 18, 46,117,112,211, 91,202, 19,229, +104, 59,176, 14,198,240,182,131,200,138,228,232,155,133,157,103,222,139, 23,150, 54, 76, 89,161,244, 85,233, 86,209,114, 17, 82, + 32,116, 29, 97,149,144,147,158,112, 45,193,211, 9,121, 26,219,249, 63,217, 33,151,159,131,254,247,192,250,219, 12,103, 44, 43, +200,111,193,246, 23,225,236,127, 65,239,127, 1,238, 31,193,221,167,225,243, 25, 61,223, 64, 45,212,135, 5,125, 56,162, 37,219, +251,131, 32, 7,166,116,158, 66, 12,235,156,127,149,196,144,171, 76,157,163, 76, 98,181,234, 85, 49,103, 3, 0,181, 1, 93,112, + 97, 93,240,207,117,151,246,193, 2, 37,248,134, 71,102, 85,245,162, 25,158,212,213,170,109, 47,121,129, 73,190,215,185,250,224, +204, 63, 98, 59,223,165,199,101,162, 89, 89, 72,204,196, 34, 11,251,153,197,106, 30,244, 16,166, 40, 21,161,238,171,175, 9,211, +238,187,122,170, 92, 23,196, 35,139,133,224,121, 19, 13, 22,147,253,163,221,139,253,236,121,143, 12,167,251,202,113, 21, 6, 23, +212,141,174,162, 46,139,224,245, 82,155, 70,193, 59,201,176,240,124,233,108,143, 83, 23, 37, 44,139,116, 93, 92,130,150,170,245, +186,192, 49, 46, 11,189, 94, 96,199,183, 21,201, 99,133,120,249,218,214,121,188,177, 92,141, 60,102, 93, 91,224,200,151, 28,247, + 32,145, 24,141,152,150,156,170,150,157,123,144,181, 78,234,251,170, 13,170,226,110, 10,153,121, 0,147,234, 88,102,128, 76,240, + 93,119,232,146,167,126,150, 89,197, 95,242, 4,207,178,137,145, 92, 64,216, 94,208,233,203,227,126,254, 20,162, 21,223,182,122, +154, 64,236,206, 17, 24,182,104,246, 85, 77, 10,251,126,125,103, 17,132, 96,194, 55, 17, 39,198,117,157,237,219, 9,126, 17,197, +179, 2,116,226,202,171, 95,162, 67,136,196, 16,173, 48,167,206,112,183, 49,210,117, 29,171,152,232,251,158, 46,173, 88,165,142, +216,173,204,255,224,235,221, 90, 70,170,119,251,155, 97,112, 17,159, 78, 65, 72,105,141,218,200, 80,148, 88,230,107,115,171, 89, + 77, 93,105,137,116, 5,125, 88,185, 51,216,104,170, 96,100, 51, 85,120,106,109, 34,187, 90,205, 71,125, 16, 64, 98, 15,111, 5, +248, 75,103,112, 51, 18, 63,122, 12, 63,156,225,163,192,181,239,131,245,127, 2,233,134,217,143,244,209,226,241, 77, 80, 31,194, +248, 69,120,244,179,176,123, 29, 78, 31,192,215,146,117,126,247, 42,156, 59, 44,165, 57, 84,163, 76,234, 77, 19,186,217,216, 77, +170,162,217,219, 12,193, 10, 77, 23,144,131, 48, 69, 49, 73, 83,175,101,108, 31, 31,188,144,166,105,113,104,191, 14,243,126,158, +206,137, 52,205,222,119,236, 92,242,132, 1, 93,186,246,245,235,204,142,140,179, 38, 97,154, 59, 14, 10,167, 64, 29,172,139,108, + 59,234,109, 70,207,189,125, 90, 99,132,151, 23, 21, 62, 60, 34, 87, 15,172,155, 61,233, 96,237,233, 63,159, 62, 71,207,183, 48, +142,112,111, 71, 61, 31, 25, 93, 36,152,178, 18,118,209,170, 83,103,218, 43, 80,244,188, 34,187,106,151,154,149,120,156,156, 78, + 28,109,162, 26,128,102,240, 57,244,166,152,114,188,175, 30, 67,233,151,219, 46, 65, 42,246,218,157,154,149, 90,170, 95,104,250, +100, 15,202,170,115,158,185,216, 68,226,238, 8, 47,159,218,123,121, 54,162, 59, 69, 87, 38, 76,226, 65,181,215,246, 59, 14,224, +134, 32,207,246,112,121,101,175,197,198,115,130,235,104,151,144,203,157, 59, 50, 28,162,147,177,231,233, 32, 66,249, 48, 28, 62, +130,131, 55, 97,216,192,209,153, 89,197, 14, 18,114, 22,145,183, 4,222, 97,225, 68,218,239, 8, 93,135,102, 69,118,197,242,192, +179,162,185,144, 11, 12,131, 78,184, 82, 17,179,109,198, 32,116, 17,219,147,175, 35,225,176, 71, 14, 59,194, 73,132,107, 9,121, + 42,192, 51, 1,185, 33,232,241, 10, 57, 56,130,254, 25, 8,207,155,131, 35, 60, 9,165,131,225,117,216,254, 4, 60,250, 27,112, +126, 31,189,119, 0, 55,159, 49,245,254,189, 17,125,101, 75,205,197,133,151,117,142, 2, 12,254,156,103,166,100,196,170,222,113, + 72,153, 96, 8,161, 21, 88,215,130, 84, 79,167,170, 85, 38, 24, 74,113,149,184,101,163,155,223, 60,186, 61, 45,234,140, 49, 54, + 21,174,123,189,235,220, 1,230,133,181,205, 38,252,173, 19,223,111,153, 90, 65,207,162,123,227,218,246,171,213, 98, 39,186, 23, + 28, 66,157, 62, 58, 80,109,173,209,236,110, 90,124,221,208, 44,120,115, 78,183,138, 19,184,196,188,235,179, 61, 53,144,168, 4, +181,149,138,132, 64,168,213, 1, 67,246, 94, 7,173,211,223,105,162,148,181, 24, 21, 23,168,237,234,140,175, 13, 33,208, 7, 33, +187, 80, 76, 22,110, 10,157,186,200,186,232, 30,101, 22,201,181,245,132, 79, 89, 42, 74, 21, 23, 4, 46, 80,188, 75,246,254, 84, +108,125,130,209,172,176,181,217,246,218,126,254,226,220, 92, 46, 48,222,127,187, 28,139,139,127, 76,141,140,214,133,232, 9,104, +113, 26, 61,131, 21, 25,173,118, 17,106, 1, 86,197, 83,198,180,182,149,143,236, 69,133,202,254,255,153, 96, 51, 81,132,174, 51, +203,151,230,178,184, 8,185,245,216,127,240,224,152,217, 9, 20,118, 81,173,191,200, 25,111,207, 88,112, 7, 74, 35, 15, 70,119, +163,168, 24, 13,110, 24,179,141,250,155, 29,198, 29, 36,136,184,248,212, 84,250, 49,218,197,160,234,130, 44,160, 70, 3,237, 82, + 71,231,130, 56, 66,176, 90,153, 71, 7,159,205,170,196,198,160,111, 17,171,187,113,228,108,183,163,158,157, 82, 9,214,125,143, + 35, 73,132,227,131, 67,174, 28,159,112,114,114,153,148, 58,106, 45,108,117,199,237,179, 71,108,206, 78, 45,161, 48, 4,210, 90, +172,168, 71,117,107,145, 46,253,216,182,103,115,160, 14,100,216,237, 42, 55, 71,211, 32,137,216, 25,127,123,180,179,245, 10,202, + 73, 85, 98, 22,250,245, 1,242,220, 9,124,139,192,229,115,248, 3,131,141, 29,175, 61, 15,235,127,207, 20,190,225,200,252,182, +228,230,108,117,117,205, 61, 24, 63, 15,167, 63, 1,231, 95,131,221, 45,244, 86,133, 55,131, 37,130,109, 11, 19,175, 51,129,236, +162,169,213, 61, 77,115,105,142,212,162, 38, 72, 91, 89, 4,159,172, 93,118,223,219, 40,220,138,181, 63,100,217, 17,144,203, 20, +151,126,241,105, 73, 94,168,215, 10, 43, 7,167,116,237,228,115,219,124,148, 61,136, 3, 89,173, 40,102, 71,141, 85, 31, 9,231, +140,110, 20,182, 21, 61,171,112, 58, 26,125,173, 40,210, 41,117, 83,172, 11,149,128, 92,139,200,213, 8, 95, 46,200,155, 91,248, +253,106, 47,219, 87,182,240,142, 14, 93, 21,248, 64,128, 23, 49,198,187, 84,180, 91,120, 72,187,104,157,235,229,100, 33,235, 4, +116,107,205, 33, 35, 54, 79,173,189, 95,124,218,172, 85,145,218,193,218, 46, 15, 42,190,231,124,100, 63,147,198,246,112, 22,223, + 59, 10,210, 11,122,172,237, 84,183,145,249,213, 96, 5,246,161,139,221, 6,239,168, 71, 95,127,132,130, 30,131,246,160,135,192, +224,131,191, 43,157,145, 11,139,162,111,129,188,145,209, 67,208,227, 74, 56,200,246,247, 9, 1,142, 58,184, 22, 76,237, 94,157, +153,149, 4,210,161,125, 65,201,150,105,126,114,217, 2,103,158,123, 19,206,223,128,187, 59,120,135, 34,103,192, 61,144, 27,137, +112,174,232,206,184, 9,241,180,218, 5, 98, 80,250,179,202,193,166,152, 86,193,187, 43, 57, 8, 70,182, 58, 12,200, 73, 15, 79, + 36,228,138,192,147, 1,185,134,175, 26,214,144, 86,208, 61,137,196,119,131, 60, 15,122,205,247,134,175,195,248,105,216,124,198, +166, 80,103, 91, 56, 63,132, 7, 79,195, 77,181, 91,243,217, 72, 61, 29,208, 33, 83,123,157,165,213, 83,232,203,156,148, 88,212, + 34, 74,235,130, 21, 94, 28,129,169, 98,111,113,174, 58, 19,183,188,202,235,194, 31,221,238,157,201, 89,217, 73,204,122,214,184, + 11,237, 66, 16,252,190,171, 23,124,216, 85, 76,116, 43,238,155,202,173,179,214,253, 98,161, 64,168,246,115,197,133,240, 75, 39, + 64,192, 34,193, 74, 27,121,114,177, 7,158,228,172,208, 69, 33, 84,243, 45, 15, 42,211,238,157,118,169,152,130,224,253,107,180, +110, 76, 42,157,204,194, 41,105,176, 29, 55,192, 72,109,107, 11,157, 4, 99, 65, 91,130, 91, 48, 64,150,204, 83,157, 32,176,241, + 73,222, 70,101,242,211,215, 69,186,246,126,124,169,211,223, 60,168,166,238, 13, 2,234, 66, 25,175,123, 94,239,233,124, 94, 0, + 98,170,238,211, 96,150, 2,190, 36,251,214,195, 73, 27,176,176,157, 93,244,159,179,200,132,151,104,215, 26, 17, 33,134, 64, 8, +201,119,228, 70, 88,203, 90, 39,130,168, 76,171, 5,247, 82,235,156, 17,176,140,145, 94, 18,109,116, 1,187,105,118,147, 40, 66, + 23, 12,192,164, 62, 2,175, 19,125,176,145, 16,103,214,185, 44, 5,172,186,152,232, 72,216,251, 59,181, 75, 76, 10, 97,234,166, + 99,138,142,120, 53,250,224, 56,142,118,129,110, 29,188,204,121,236,180,204, 63, 17,138, 8,165, 20,164,100, 31,187, 39,223,109, +219,186, 97,187,219, 48,158,219,232,189,186, 98, 32,231, 66,169,213,190, 71,201,115,170, 94,251, 60, 6, 65, 67,176, 63, 83,178, +217,235,166,232, 85,108, 34,144, 58, 78, 46, 93,226,210,149,171,164,213, 1, 15,199,145,123,183,222, 36,159,157,186, 61, 48,144, +142,188,182,173,130,137, 50,228,194,195,215, 53,197,118, 18,100, 20,242,185,157, 37,135, 97,254, 48, 94,170,202,225, 89,229,100, +157, 8,151,215,200, 65,135,188,119, 5,127, 98, 7,223,185,133,120, 5,134,239,134,244,199, 33,124,179, 23,243, 17,107,235,154, +249, 35, 65, 61,133,242, 50,148,183,172, 67, 63,191, 9,195, 93, 19, 60,189,150,108,135, 94, 93, 5,178,178,226, 40,209, 70,233, +211,211,218,162,150,188, 59,150, 86,144, 87, 94,128,219,239, 95, 57,241,164,243,125,107,242,147,171,225,180, 84,231,147,164,181, + 31,157,125, 13,209, 22,190,209,174,253,206,139,173, 94,192,183,213,186,218,161,218,136,251, 44,195,166,154, 48,168, 42,186,173, +134, 80, 61, 27,209,179, 98,162,143,188,240,208, 39,199,171, 14, 62,230,201,145,112,210, 89,135,253,106, 33,126, 26,120,225, 4, +190,186,129, 87, 54,240,177, 21,188,175, 67, 46,117,232,203, 10, 95,174,196, 7, 74, 24,108, 5,160, 39, 9,174,118,112,185,179, +124,164,131,104,133,190, 93, 88, 54,192,186,216,114,184,154, 34,122,154, 78,104,130, 67, 69,162, 32,199, 17, 61,173,176, 45,246, +117,165,162,155, 2,143,252,232, 73,246,250,132,236,151, 43, 21,184,151,109, 60, 30,125, 18, 81, 5,174, 9, 92,141,176, 41,232, +105,181,191,107,239,239,209,145,243,115,183,192, 93, 15,151,201,190,228, 59, 23,228,161,247, 99, 7,110,219, 59,216,185, 22,225, +220,253,222, 43,180, 7, 57, 28, 64, 62, 5,219, 83, 15,159,191, 14,253, 31, 7, 62, 4,233,111, 67,121, 19,142, 30, 34,249, 33, + 58,238,160, 14, 72, 30,144,172,134, 19, 30,124,106,178, 3,182, 2, 15, 20,206,100,158,111,246,254, 51, 92, 22,155, 76,156, 68, +207, 90, 95, 67, 56,129,244, 52,196,103,160,255,152,197,175,202,145, 65,115,182,191, 0,187,127, 2,103,111,160,167,231,176, 9, +112,218,195,233,161, 77, 40,182, 59, 56,171,212,157,101,155,214, 97, 68,163,175, 97,134,108, 58,130,232,113,241, 91,179,102,101, +156, 23,238,235, 2,173,144,139,237,121,219,199,165,137,182,106, 85, 87,176,235, 36,134,106,141, 82, 66, 77, 56, 85,101, 66,223, +138, 40,161, 92, 40, 28,117, 14, 9,209, 37, 65, 12, 93,116, 91,214, 44, 84,239,240,171,119,196,180,244, 46,159,254,165,186, 36, +165,205,240,147, 42,115,100,153,248,208, 40,133,121,223, 25,171, 19, 26, 69,232, 4,196,247,139, 89,149,161,154, 69, 74, 68,109, + 61, 39, 58, 29,248,161,249,239, 85,201, 85,167, 29,190,234,156,107,142, 83,240,204,210,103, 95,191,138,237,197, 11,179,230,104, +244,206, 93, 93, 77,254,160,194,153,119,214,213,167,134,121,207, 6,215, 84,230,205, 91,191,132,166, 56,224,107, 15,127, 43,123, + 24,141, 37,252,103,233,127, 47,178, 63,117,174,139, 83,117,229,125, 69, 88, 36,121, 77, 5,126,210, 10, 44,246, 46,222, 77, 39, +137, 19, 76, 69,188, 88,205,137,101, 54, 14,207,165,236,101,183,139,187, 8,204,229,160, 11,177,181,139, 50, 69, 22,153,240,243, +127,219,139,131, 21,136, 90, 9,105, 53,143,221, 23,184, 93,212,192, 48, 83,218,156, 78,115,129,125,200,207,226,134,163,170,211, +235, 30, 93, 28,103, 64,152, 52,113, 35,170, 10,195, 56, 80, 70,243,150,167, 24, 32,122,168, 75,169, 83,145,159, 12, 17, 90, 13, + 56, 35,129,172,202,102,187,101, 28, 71,219,151,215, 74,201,153,210, 2, 90,166,105, 64, 68, 67, 52,101,124, 41,211,206,106, 10, +232,145, 96, 62,244, 92, 60,240,204, 39,131, 97,246, 63,140,227,142, 59,183,111,114,251,206, 45,255,254, 22,146,214,210,244, 10, +144,142,124, 85,190,198, 98, 48,151, 47,113,112,177, 66, 12,129,176,238,136, 53,114,242, 76,199, 11,119,183, 60, 58, 43, 72, 85, +214, 69, 57, 14,129,213,122, 77,124,231, 17,242,241, 8,223,188, 67,222,119, 6,215,159,131,250, 39, 33,254, 33, 56,120,202, 31, +235,193,247,230, 46,101,209,222,162, 35,235,151, 96,248, 5,168,107,216,126, 1, 54,119, 96,120, 4,103,143,208,183,162, 29,102, +163, 23,215, 67, 31, 49,186, 61,219, 72, 96,213,119,213,177, 93,171,103,193, 87,114, 84, 93, 31,109,239,126,232,162,169, 3,143, + 56,235, 13,206, 98,113,155,243, 50, 79,229,235, 21, 0, 0, 32, 0, 73, 68, 65, 84,203, 94,120,223,123,231,226,190,166, 96,183, +154, 51,179, 45,144, 49,111,247,121,177, 34,117, 94, 77,196,244,168, 90, 62,249,198,195, 34,212, 14, 96, 69,169, 67,165,110, 43, +117, 44, 12, 62, 34,181,189,162,117,233,186,243,124,241,149, 5,105,116,119, 11,125,180,245, 0, 15, 10,252,211,129,248,117, 43, +248,150,206,162, 81,191,116,110, 80,150,156,225, 3,157,177,219, 63, 23,144, 71,126,251,186,150,224,160,179,163,164, 15,200,245, +149, 41,244,175, 36,228,200, 25, 85,186,152, 58,244, 14, 18,168,254, 54, 5,177, 36, 25, 2,114,160,232,105, 65,135,236, 80,145, +104,251, 93,166,214,201, 46, 31, 21,120, 75,225, 74,130,119,245,240,153, 17,174, 68, 3,197,188,190,133,109,161,158, 85,184,239, + 2,152, 43,209,225, 70,209,110,166, 99,133, 65,108,154,161,158,233, 43, 17,185,226, 33, 40,215, 77,223,193, 23,183,182, 75, 94, +169,173, 64,174,244,232,229, 4, 47,100,164,127, 96,227,253,163, 4,221,155,176,250,113,195, 10,111,158, 2,253, 48,132, 83, 72, + 61, 18,119, 46, 74,116,235,158, 12,136,110,161,110,161, 62, 2, 61,131,225, 28,134,193, 82, 62,196, 95,167,110, 13,105,109, 59, +241,248, 14,144,167,161,123, 15,252,255,116,189,217,179, 37,217,117,222,247, 91,123,239,204,115,238, 84,115, 79,213,232, 9, 3, + 1,130, 0, 65,144, 20,105,138,146,104,153,150, 44, 59,100, 59, 68,234,193,118,132,195, 47,140,144,159,236, 71,251,145, 79,142, +240, 63,224, 7,135, 31,236, 7, 7, 67,180, 77,155, 14,153, 14,112, 16, 1, 73, 4, 45,145, 24, 9,128, 32,134,106,116, 55,170, +199,154,110,213,189,247,156,147,153,123, 47, 63,172,181, 51,247,185,213, 68, 68,161,167,170,123,239, 57, 39, 51,215, 94,107,125, +223,239,235, 94,132,254, 54,196, 43,182,210,200, 23,176,253, 38,108,126, 11,206,191,130,222, 27,225,199, 61,188,219,163,239,140, +232,147,115,116,227, 15,194,232,235, 17,197, 14, 13,131,191,246,161,160,143,252,239,163, 77,160,114,182,113,241, 38, 91,244,231, +164, 74,206,194,152,153, 99, 78, 75,171,100,111, 10,110, 77, 76,139, 77, 44,104,213,101,182,222,252,200, 62,194,147,178,124, 93, + 65,231,196,192,210,242, 26, 92, 48,215,137, 43,149,115, 45, 50, 46,150,194,236, 99,169, 10,213,130, 21,237, 88,143, 6,209,191, +102, 97, 14,176,232,130, 33, 88,167, 98,197,180, 22,198, 92, 20, 13, 66, 87,247,150, 89,231,196, 46,117,113, 82,231,173,190,186, + 10, 63,212,221,183, 46, 61,180, 22,157, 87, 24, 26, 23,181,121, 86,246,250,217,208,164,170, 21, 89, 68,107, 45,238, 86,102, 22, +221,146,191,158,170, 0,209, 99, 68, 67,179, 95, 69,108, 85,168,243, 60, 93,247,226, 90,139,239,221, 91,188,233, 83, 10,244,230, + 51, 8, 18,102,225, 88,231, 27,175,209, 59,226, 82,121, 24,178,172, 43, 77,212, 27,231,144,173,218,157, 70,177, 80, 19,196,210, +199,114,241,247,184, 24,246,180, 22,203, 42,118, 43, 37,207,211,135,118,188,190,100,249,233,124, 48,144, 38, 22,119, 65, 14,155, +183, 61,198, 8, 49, 81,198,237,178,150,104,198,231,178,151,235,254,148,155,126, 6,203,208, 70,175,170, 21, 71, 43,234,102,101, + 19,183,162, 77,192,110, 55,146,199,145,104,121,228, 16, 2, 99, 49, 46,116,125, 79, 98,144, 57, 26,118,114,232, 75, 81,236,112, +227, 7, 98, 9,193,215, 20, 70,146, 83, 89, 88, 10,190, 16, 34,166,158, 41, 38,202,176,243,231, 90, 35,116,172,168, 91,177,206, +188,157,166, 89, 62,140, 52, 89,236,186, 63,206,247,201, 66,186,174, 74, 18, 33,244,193,229,249, 13, 5,194,239,250,176,238,136, + 71, 43,228, 87, 14, 72, 31,239,184,245,223, 63,224,250,110, 7, 71,145,112,146,144,231, 58,248, 88,129, 95,222,193, 39, 35, 92, +125, 21, 14,127, 3, 86,255,192, 30,108, 6, 89,180,228,172,121,167,212,129,118,134,254, 28,190, 12,219,223, 6,249, 12, 76,135, +176,125,207,150,245,195, 35,235, 94, 54, 30, 70,126,226, 82,213,226, 79,172,202,153,172,209, 80, 61,115,202,213,140,122,234,101, +201, 39,141,106,146,214, 85,180, 56,204,149, 43,185, 43,222,170,238,145,119,184,183,201,118,219,140,217, 67,192, 50, 92,140,232, +214,139,206, 70,209,205,132,158, 43, 58,140,148, 33, 91, 33, 31, 10,101,107, 31,116,201, 19, 90, 28,118, 80, 76,116,179,155, 96, + 40, 66, 78, 97, 30, 23,197, 58,234,241, 12,122,141,234,196, 50,219, 51,119,111, 79,196,104,163,167,254,209,150,245, 63,187, 71, +250,175, 95,132, 79,118, 76,255,237,143,217,190,126,129,156, 4,250,111, 6,226,223, 63, 54,133,248,143, 10,220,140,200, 58, 89, +218,115, 15,114,165, 67,158,237, 44,176,229, 40,186,109,193,223,219, 19,247,192, 31, 38, 27, 91,151,206,170,195,129,218, 88,252, + 34,195,217,136, 76, 5,178, 23,223, 67, 31,196, 62, 25, 77, 13,127, 88, 76, 76,247,221, 9, 94,238,224, 87,175,194,149, 43,240, +234,198,138,238,153,117,162,170, 10,157,162,189,239,113, 58, 49,181,102, 31,144,209, 42,140,198,209,234,236,125, 69, 79,139,233, + 32,126, 42,217, 19,234,206, 14, 61,157,224,137,229, 31,235,104,137,110, 60, 24, 9, 93,132,183,182,232,161,141,214,120,121,101, + 7,149,221, 27,208,191, 3,252,164,117,236, 60, 99,226, 76,142, 65, 94,104,198,130,238,250,141,197,100,216,229, 20,226, 27,112, +252,142, 21,120, 70,151,198,247,150, 2, 23, 94,130,240, 41, 43,236,233,196, 21, 95, 63, 0, 30, 65,254,190,141,217,119,119,208, +211,199,112, 55,192, 15, 18,122,231, 9,249,221, 29,229, 34,163, 58,217, 61, 87, 39, 73, 79,236,193, 64, 4,189,240,202,226, 92, + 97, 45,120,225,114,177, 90,182, 75,116,114, 81, 87, 41, 97, 78, 16, 19, 47,158, 45, 57, 69,212, 30,156, 41,176,128, 73,252,236, +150,177, 48,167,122,235,212, 4, 65,109,182,171, 53, 38,119, 70,119, 20,155,240,101,153,221,158,115,145,150, 96, 95,175, 22,192, +212, 60,236, 67,133, 51,121,200, 76,146,101, 88, 54, 5,165, 27,189, 19,159, 67, 50,124,116, 42,246, 26,166,166, 43, 37, 87,132, +234,100,156,244,102,191, 46, 69,205,185,154,189, 11,244,148,182,169, 22, 34,153, 13, 45,246,221,130, 29,112,151,124,234, 50,119, +147, 21,223, 58, 79, 62,154, 66,187,148, 21,117,248, 8,115,116, 39, 51, 20,165,150,161,128,136,206,202,123,113,117,254, 2,183, +209,197, 10,216,216,207,234,231,116,121,223, 61,199,170, 74, 64, 36,217,126, 88,133,108,126, 49,146,139, 36,237,177,238,207, 59, +106, 78,121,240,246, 51,204, 69,189,102,140,215, 46, 87,243, 52,235, 12,236,176,101, 63,133,237,165, 13,188, 98,221,180, 31, 17, +100,137,146, 85,105, 57,245,251,232,185,210,202, 0, 93,192,153, 68,136,221,138, 73, 39,178,157,234,104,178,223,102, 20,109,237, +150, 91, 59,157,162,151,130,102,116,222, 53, 4, 9,214,156,138, 32, 49, 33,209,186,245,130, 48,110,119,228,113,156,201,118, 89, + 76,165,111, 27,215, 52,103,173, 15,227,192, 48, 77, 76,195, 96,247,167,239,195,163,251,239, 13, 85, 92,220, 38, 88,102,166, 64, +153, 39, 36,101, 6,185, 69, 9,208,117,228, 50, 44, 20, 64, 93,130,149,102,199, 66,251,254,233,165, 36, 29,223,245,107,105, 93, + 87,144,214,171, 30,214, 1,233,236,195,149, 38,231,150,226, 10,241,171, 9,185, 17,225,137,194,239,236,224,153,158,248,185, 21, +252, 68,129, 79,140,240,242, 57, 92, 63,128,195, 95,130,213,127, 5,221,103, 33, 28, 47, 35,118,205,151,242,199,221,182,150,255, + 18,118,191, 3,143,255, 21,164,159,130,248, 60,236,190,106,224,148,178,181,113, 99,167,240,108,182, 14,105,151,247,153,131, 49, + 46,225,229,181,237,136,141,197, 76,196,196, 83,161, 52,187,243,228, 79, 28,187, 24,101,240, 39,203, 96,123,122, 61,155, 12,125, + 58,170,237, 84, 47, 28,125,186,153,236,191,159, 91,209,214,193,140,255,101, 44, 54, 78, 25, 51,186, 41, 22,167,151,133, 82,138, +125,152,193, 0, 12, 25,101, 64, 24,178,113,240,139,231,180,215, 83,119,244, 31, 57, 86,107,145, 10,121, 92, 48,157,231, 34,116, + 42, 68, 41,164, 35, 97,247,141,115,174,252,143,119,137, 63,145, 56, 63,221,241,248,186,208, 29,194,225,227,137,195, 63, 62, 39, +252,167, 55,144,163, 3, 24, 2,114,179,135,171, 61,114,128,169, 25,143, 35,164,236, 29,167,195,110, 86, 9,186,107,208, 29,248, +211,117,131,205,192, 19, 28,190,104,209,158,247,190, 7,231,131,219,195,140, 28,167, 33, 27,169,237,208, 64,233, 26, 10,124, 97, + 99,133,249,205, 12, 31, 57,135, 79,249,154,163, 38,135,244, 2,143, 65,199,226,147,145, 98, 95, 79,146, 23, 54,111, 21,119, 85, +255, 96, 85, 66, 94,142,102,155,122,103,164,188,185, 51, 31,254, 88, 40, 27, 53,126, 66,176, 74, 82,142, 34,114, 22,145, 20, 41, +187, 64,124, 48, 34,155, 12, 47,172,225,240, 12,174,127, 29,142,238,129,126, 20,228,154, 77,142,198,239, 65,186,109,133, 89,189, +191, 13, 35,240, 30,240,151,176,121, 11, 30,159,195,195, 11,244,113,237,164,125, 98,112,242, 45,100,245, 69,136, 7,158,231,185, +177,226, 95,118,118, 0,188, 24,225,126,132,183, 3,122,103, 71,254,241,134,252,120,231,240, 8, 55,123,199,138,250,170,211, 34, +187,196,183,155, 76, 9,145, 16, 5,137, 50,251,231, 39, 63,211,214,181,250, 20,116,217, 9, 55, 69, 64, 90,216, 73, 37,160,133, + 96,153, 8,193, 11,162, 23, 22,187,240,194,188,183,150,134, 39,190, 87,218,179,119,171, 42,123, 57,224,115,180,101, 54,107, 88, +108, 54, 87,194,165,224,110, 23, 94,101, 89,178,148, 10, 66, 44, 58,191, 13,201,247,243,147,235, 2, 43, 91, 73,157, 93, 95, 67, +149,150,157,100,125,141,102, 87,171,221,118,169,145,199,106,116, 76,130, 61, 18,202,236, 34,107,147,228,196,105,124, 50,143,229, +103,107,171, 39,241, 85,191,254, 50, 54,213,198, 21, 38, 53, 74, 98, 22, 80, 85,159,189,241,173,100, 14,211,169, 54, 53,109,130, +118,148,194,174, 48, 35,176,130, 67,173, 44, 72,106,233,123,103,137, 97,112,205,127, 21,173,133, 84,223, 20,130, 83,176,212, 43, +122,237,146, 17, 83,169, 75,176, 78, 92,137,179,182, 64,221,173, 80,166, 76, 41,217, 86, 50,254,232, 44,222, 91, 91,137,240,134, +164, 20, 15,145,125, 42, 97,100,158,244,148,102,153, 31,100, 57,236,204,217,240,213,174,167, 74,215,117, 16, 3,121, 24,104, 94, +226, 66,229,187, 28,198,213, 28, 76,219, 67,170,206,185, 37,203, 65, 37,132, 90,128,109, 42,168, 2,227, 48, 50, 57,115,221, 14, + 77, 54, 13, 75, 18,136, 93,162,168,178, 29, 7,118,219, 45,211, 56,248, 68, 33, 56,164,198,167, 26, 33, 46,185, 5,179, 52,192, +131,133,106,170, 95,179,239,215, 82,124,148, 31, 41,174, 27,168, 7, 57,213, 75,200,156, 75,228, 65,116, 95, 55,177,255,123, 29, +181,155, 94,187, 2,135,139,159,154,236,136,212, 2, 28, 41, 92, 87,184, 61,194, 11,163,253,251,159, 83,184,154, 45,120,226,106, + 15,183, 94,129,254,215,129,127, 0,188,228,155,156, 13,232,195,167, 53,149, 51,141, 97, 11,229, 59, 48,254, 30, 60,254, 35,144, +235,176,254, 28, 12, 95,179,110, 94,176,217,243,225, 51,176,218, 32, 87,119, 46,160,187,180, 27,104,149, 23,101,223,250, 66, 14, + 78,150, 19, 27,161, 79, 30, 58, 50,248,150, 43,251, 94, 82,189,229,185, 80,171, 99,231,101, 17,115,109,138, 21,240,157,147,123, +138,218, 63, 79,254, 75,138,141,135,182, 25,157,148, 60,186,191, 89,116,206,103,175,153,236, 99, 17, 46,178,107,229, 26,209,198, +212, 36, 27,213, 56,214, 41, 47, 15,140,186, 51, 59,159,124, 77, 18, 44, 2,247,236, 40,112,250,111, 46,232,255, 28,166, 3, 40, + 43,235,238,166,117, 64,223,157, 76,221,253,111, 93,135,215,109,162, 34,175,174,225, 70,135,244,157, 83,132,138,141,150, 67,129, +120, 19,120,222, 2, 67,226,123,192,199,129,191, 9,252, 79,192,251, 32,207, 66,121,100,135, 42, 73,112,100, 25,164,250,230, 57, +122,103,135,190, 51,160,119,183, 86,164,175, 11,233,113,177, 41,192,127,126, 3, 94, 78,176, 27,173, 64, 31,123,215,114,210,161, +103, 25, 57, 72,232, 65, 54,109, 68,151,108, 4, 24, 93,206, 59, 21,179,156, 92,235,237, 49,217, 7,251,154, 27, 40,167,153,114, +238,113,132, 67, 97,218, 21,166,179, 74,236,202,132, 7,163, 97,118, 49, 85,122,217, 21,210, 90, 9,103,230,245,231, 86,129, 23, +126, 0, 71,239,129,124, 4,228,138,143,199,255, 16, 86,207,195,193, 85, 43,208,225, 28, 46,238,193,143,206,225, 7, 5,222,119, +241,156,170,241, 15,174, 39,228,102,132,213, 14, 13, 79,172,200, 31,122, 21,121,162, 86,156,239,187,177,227,108,160,108, 38,202, +253,145,252,112, 71, 25, 39, 52,249, 41,222, 15,120, 18,218,129,165,144, 11,108, 82,180,226,148, 21, 53, 19,181,123,160,253, 35, +204,150, 73, 62, 15, 38, 75,227, 93,110,144,174,245, 65, 76, 40,104,246,189,110,169, 44,241, 86,101, 46,115, 33, 14,205,190,180, + 90,207,114,110,138,159, 44,133,139,178,140, 58,101,143, 47,190,144,214,170,204,162,212, 29,178, 83,156,167,217, 78,165,140,109, + 87,231, 95, 55,120,129, 28, 93,132,148,115, 67, 72,203, 51, 30,142,146,171,119, 70,200, 18,216,130, 41,152, 61,246, 57, 87, 17, + 96,185,172,200,215,133, 2,199, 50,118,151,153,144,102,133, 71, 85, 61, 7,190,109,152,132,168, 50,239, 61,139, 44,185, 6, 50, +251,243,117,137,231, 37,120,119,181, 47,158, 91, 34, 97,101,222,240, 45, 7, 49, 89, 70,253, 92,202, 38,119, 17, 27, 33, 80,138, + 26, 34,187,242,193,125,100, 44, 8,177, 75, 36, 76, 92, 90, 36,250,180,197,222,159, 49, 23,198,113,154,119,215, 53,142,122,246, +203,123, 71,234,196, 21, 3,190,224,187,102,205,123, 62,120,213,125, 69,187,238,241,217, 22, 44,109,165, 19,138,123,198,241,240, + 44, 73,157,173, 79,234, 68, 87,151,233,199,124,152,209, 38,113,174,201,117,173, 0,162,253,158,221, 38, 35,193,247,232,196,104, +127, 46, 8,211, 84,152,198,113, 17,172, 85,146, 95,176,124,128,237,148,173,152, 15, 91,212, 99,195, 67,140,206, 62,241, 72,154, + 16,230,201,196,158, 88,193,125,248,226,171,144, 90,152, 85,139,175, 41, 10,164,132,196,100,220,246,236,235,205,198, 58,184,231, +146,104,171,184,238,255,181,138, 38, 43,188, 58,201, 63, 62, 52,208,199, 65,177,241,117,180,189, 46, 73,205,170, 36,209, 66, 53, +250,235,144,174, 90, 7,222,189, 2,233,147,208,127,210,198,142,230,145,114,185,243,105, 51, 98,111, 11,122, 89,110,241,242, 14, +148,183, 61, 59,244, 53, 88,255,134, 35,187, 86, 22, 12,178,187, 7,195, 7, 16, 55,126,215, 14,190,176,154,230, 11,203, 78, 33, + 14, 87,209, 12, 97, 7,113, 7,211,102,177,166,141,117,215,173, 70, 22,219,168, 21,166,209,121,238, 59,111, 17,182, 5,182,166, +124, 86,177,147,154, 58,102,175,100,155,213,105, 54,246,185, 37,185,249,184,105, 82,139,116, 45,197,132, 74,201, 82,145,102, 8, + 7, 58,127,249,157, 15, 3,170, 10,119,239,124,162, 54,178, 42, 14, 56, 25,155, 17,104, 22,115,169,109, 70,119,204,245, 78,128, +205,102,207,139,110,121,239, 39,223,201,109, 20,121,182,183, 11,230,160,135,151, 12,167,106, 16,143, 12,225,121,123,175,195, 45, + 63,209,191, 7,121, 13, 97,107,138,236,153, 32,253, 29,215, 63, 76,176,253,115,123,255, 70,183,215,125,245,148,242,187,143, 40, +111,109,209,149, 89,172,166,179,145, 41, 90,206,142,136,176,186, 40,244,255,230,140,144, 3,242,145, 43,118, 13,141,238, 30,184, +218, 35,155,130,238, 38,228, 57, 63,201, 28, 56,201,101,240,207,183,179,193,177,172,124, 14,252,234,202, 46,179, 31,238,224,145, + 82, 30,219, 46,126, 10,133,173, 42, 91,135, 92, 68,135,197,164, 65,233,243,196, 74,139, 77, 17,222, 85,226, 54,219,250, 97,219, +193,174,135,151, 47,144,171, 31,128, 30, 64,255,243,160,223,135, 15,222,128,241,161,173,107,206, 4,126,152,225, 13,224,141, 9, + 29,118,140, 97, 52,246,149, 68,228, 40, 18, 14,147, 29, 74,114, 64,142,147, 5,179,100, 76,224,183, 85, 83,239,110,139, 77,108, +130, 31, 4,187, 50, 83,213,138, 66,118,107,153, 78,205,131, 59,152,130,122,204, 53, 28,198,108, 98,102, 80, 88, 34, 72, 53, 44, +236,239,150,132, 45, 65,141,214,167,152,195,160, 52, 97, 7,158,180, 82,233,120,104,153,147,172,106, 65,183, 97,201,126, 39,201, +164,205,238,216, 30, 52,129, 42,192, 23,155, 38, 96,123,242,132, 37,157, 85,200, 74,100, 9, 45,178, 64,153,197,101, 19,106, 7, +222, 6,140, 84, 57, 7, 11, 49,109,172, 67,255,214,143,229,202,107, 27,165, 7,138, 4, 82,178,123, 40,229,194,228, 95,173, 20, +245,115,188,206,118, 47,230, 14,116,177,141,105,179,159,108,219, 64,109,254, 93,161,233,246,165,142,235,195,204,115,175,231, 39, +209, 50,175, 33,230,174, 43, 84,100,172,238,237,137,235, 88, 57, 58, 0,108,210,133,159,223,226,138,231, 3, 81,171,126,114, 37, +184, 52, 92,240,162, 75,108, 90, 81,161, 72,161, 72, 38,187,136, 48, 35,228, 58, 54,111,242, 89,219,169,204, 2, 83, 12, 51, 67, + 61,180,147,155, 89,192,182,175, 48,111, 55,224,250, 84, 37,104,200,110, 77,247, 25, 80, 98,236,153, 80,166,113,154,129, 65, 69, +100, 86,210,239,101,193,238,215,243,249, 51,179,243, 65, 43,244,132, 16, 29, 21, 28,163,239,211,147,101,151,143, 59, 74,153,154, + 61,191, 29, 48, 74,136,236,198,129,113,187,165,140,163,237,169, 59,159,128,200, 18, 53,104, 59,244, 56,159, 50,102, 17, 98, 67, + 31,172, 2,189,122,125, 76,121,178,248, 86, 85, 68, 38, 36, 70, 66, 12,100,141,115, 50,168, 54,239,226,135, 89, 11, 91,187,158, +162, 75, 65,151,154,167,254,169,104,118,160,238,186,117,204,241,196,112,149,114,197,254, 62, 29,251,174,240,153, 5, 97, 41, 7, + 16,250,198, 0, 51,184, 53,109,247, 33,177, 22,122, 9,241, 83,172, 35, 12, 47, 64,252, 85, 43,226, 26,172,187,143,207, 67, 62, +135,112, 10,241, 45, 8, 63,182,140,239,105,235,187, 77, 7, 64,171, 64,153,188,224,143, 62,234, 28, 96, 28, 77, 88,181, 43, 86, +176, 55,174,160,126, 48,153,213,171,130, 80, 38, 69, 39, 87,152, 79,182, 31, 87,241,130, 93,199, 85,142,119,157,159, 34,163,239, + 56,165,194,251,189,107, 47,197,236, 13,149,249, 62, 85,166,181, 48,168, 48,100,101,240,145, 98, 29, 16,168, 7, 10,180, 17,128, + 41, 56,164, 32,251,122,191, 14, 78,196, 10,248,197,104,231,174,177,179,214, 97,167,246,210,123, 79, 88, 77,209, 30,142,235,171, +145,240,211, 7,139,234,233,102, 63, 11,224,116, 83,144,225, 14, 28,156,128,220,116,130,217, 43,160,223,128,242, 99,200, 55, 96, +250, 52,164,191, 2,254,149, 41,150,206,183,240,208,216,240,250,112, 64,191,244,128,242,127, 61, 2, 70,228, 25, 65,111,249,120, +252,205,128,134,133, 18,166,219,130,126,225, 9,253, 31,110,144,191, 53, 16,126,253, 25, 23,232,169, 41,223,233,145,251,226,150, +163, 26,154, 99,254, 73, 89, 1,169,216,190, 47,129,172, 19,218,129, 60,155,204, 50,248,254, 0, 63, 8,228, 71, 3, 79,164,176, +233,226,194,220,143,190,207, 12, 22,114, 54,105,161,159, 70,242,123,133,114,145,137, 79, 38,194, 7, 35,242,206,132, 12, 7,232, +107,167,200,245, 31, 3, 47,194,225,103,224,246, 49,220,185, 3,111, 2,253, 26,126,229, 16,110,159,192,255,240, 67,242,239, 63, + 97, 76, 19, 37, 23,164,159, 8, 99, 36, 12,147, 39, 38, 5,100,154,224,253, 96,206,138,173, 11,175,178,171,175,179, 35,140,179, +209,247, 36, 9, 97,231, 7,185,236,202, 85, 93,196, 86,129,194,164,193,245, 24,203,142, 88,231,251, 41,204,161, 34, 82, 71,124, + 90, 22, 27, 79, 85,172, 5,157, 71,236, 85,136,150,103,101,142,117,233, 65,133,236,227, 84,109, 18,229,146, 44,201,131,101, 98, +239,241, 98, 80, 22,103, 21,169, 61,188, 82, 22,250,209, 15, 33,107, 97,138, 48, 77,166,159, 72, 85, 64,215,216,148,117, 6,229, +232,135,242,196,235,195, 63, 70, 51,155, 76,121,217,125, 87, 14,212,108,183, 11,113,182,145,137, 22, 66, 85,249,123,209,175,126, +252,122, 88, 86,151,113, 72,131,193, 85, 31,233, 7,127,143,181,237,154,154,154, 50, 71,151,122, 33,152,227,249,170, 12,177, 9, +254,217,235, 85,125,244, 60, 71, 60, 95,202, 37,175,169,110, 53, 35, 35,233,194,134, 9, 21,219,218,172, 82,104, 2, 77,170,184, + 78,102,190,154,197, 4,211,100,155,139, 71,237,105,147,230, 86,230, 96, 31, 63,214,204, 98, 1,247,222,123, 33,203, 78, 80, 11, +206,102, 47, 57,207, 70, 60,253,235,208,177,151,171,210,222,239, 93,142, 53, 69, 11, 41, 38, 74, 76,142,251,206,205,238,200,231, + 39,186,140, 56,171,221,186, 6,210, 46,171, 38, 27,169,231,106,177, 19, 8, 33,121,135,157, 12,246,146, 18,163, 42,187,209,147, + 60, 93, 33, 42,238,118, 42,192,110,183,101,220,237, 16,205,196,202,128,166, 10, 2,125, 49, 50,227,111,109,213,218, 28, 45, 22, + 25, 69,123,204,246, 67, 64, 36,154,123, 96,154, 16,103,214,139, 79, 66, 74,153,154,251,251, 82,102,125, 8,243,195, 97,209, 80, +212,116, 59,177, 41, 77,153,252,128, 95,128,178,130,233, 25,136,215,125, 28,121, 27,250,107,176,242,206, 60, 28,154, 37, 39, 30, +215,244,112,208, 11,104, 73, 62,243, 81, 47, 95,218,230, 95,254,184,131, 29, 10, 72,149, 83, 9,229, 30,148,115,203, 70, 47,239, +194,248, 46,140,239,121,177,158, 42, 93,195, 63,216,201,118,150,249,137,169,138,199, 29, 12, 25, 29,188, 35, 61,247,104,209,199, + 19,220, 87,120,127,132,243,236,156,105,179,146,217,238,215,119,186,217, 69, 91, 46,248,208,170,124, 15, 11,107, 82, 91,212, 82, +108,242,215, 29,185,169,141, 35,100,242,134,118,235,107,249,154,225,172,165,197, 14,235,254,122, 81,108,140, 58, 23, 68,149, 25, +114,178, 27,149,141,219,199, 71,181,174, 93,154,189, 74,246, 73, 0, 59,120,110, 5,171,143,118,139,240, 44, 4, 88,247,166,251, +162, 88,100, 41, 43,152, 30, 66,186, 11,225,115,222,141, 71, 40, 55, 64, 62, 6,211, 21, 59, 88,233, 53,251, 92,182,192, 54,163, +111, 94, 80,190,240,152,242,149, 51, 67,172, 30, 36,251,168, 55, 1, 58, 37,158,153,117, 45, 36, 31, 37,215,125,230,227, 9,249, +127, 78,145,103, 87,200, 63,188,229, 99,133,100,157,198,160,240,100, 50,111,120,244,125,110,125, 98,119, 17, 73,142,159, 13, 1, +121,111, 64,223, 24,224, 16,194, 47,246,164,219, 10, 95,132,131,239,238,200,231,138,118,182,250,216, 70, 65,163,208, 37, 27, 10, + 76, 65,152, 78, 21,221,140,244,253, 68,186, 58, 33, 33,146, 78, 38,235, 70, 59,208,248, 16, 57, 81, 79,152,251, 4,252,228, 21, +120,243,155,246,207,183, 86,240,246, 19,248,218,134,210,153, 21, 82, 39,108,106,147, 60, 29,169, 19,130, 20,239,104,155, 15, 61, + 96, 69, 61,248,228, 40,251, 3, 61,213, 66,228, 15,168,178,128, 4,107,206,124,240,223, 59, 11,171,124, 65, 89,229, 41, 81,150, +188,110,209,118,140, 91, 40,181,124,171,169,198,172,147, 10,203, 38,214,199,207, 26,196, 84,244,190, 71,175, 26,111, 13,150,138, +166, 49, 32,217,192, 33, 14, 91, 94,236, 72,179,127, 37, 32, 1,142,187,196,213,103,122, 14,126,233, 4,121,109,205,240,187, 15, +120,239,251,231,168, 40,147, 83,197,122, 12,101,187,228,138, 87, 63,244,126, 0, 9,245,128, 86,106,176,155, 41,139,251,106,141, +107,159, 44,209,211,198,213,239, 95,239,218,187, 96, 15,247,220, 28,136,132,229,251,212, 40,151,168, 85, 91,235,100, 50,241,110, +119, 38,239,177,167,108, 95,188,226, 50,219,239,180, 1,200,212,113,104, 96, 9,150, 17,247,246,207,193, 46, 46,122,144,230,160, + 49, 43,222,101, 89,153,204,123,246, 37,128,110,182,180, 61,181,193,150, 5, 17,107, 67,148,138,171,149,166,136,102,251,140, 29, + 93, 27,244,175,249, 58, 44, 0,178, 89, 60, 93,178,119,156,181, 33, 41, 79, 63,218,165, 57,189, 92, 70,201,206,129, 56,251,157, + 44,238,255,143,169,243, 85,165,121,185,237,163, 8, 51,108,168,253, 98, 90,202,126,104,187, 67, 92,234, 74,167,106, 21,130, 4, + 35,172,185,143, 60,197, 72, 22, 97,179,219, 82,166,209,223, 99,239,112, 69,152,114,102, 26, 71,114,158,252,125, 14, 75, 16, 76, + 61,132,120,247, 29,176,113, 86, 29, 64,235, 37,204,210,222,132,171,174,120,138, 57, 47, 44,201, 10,202, 48, 17,198, 9,233, 19, +154,162,231,120,232,165, 9,135, 23,124,196,234, 32,245, 58,169, 33, 67,126,152,111,116, 22, 73,223, 47,200,179,167,176,254, 62, +164, 27, 6,126,209,183, 64,111,129, 62, 15,253,203,208,221,114,140,235,129,119,119,218,242, 40,155,113,136,254, 53,233,187,149, + 20, 87,247, 50,247,161,220,133,252, 77,144,143,218,109, 87,222,134,233, 3,200, 15, 44, 70,115,154,108,217, 86, 38,163,135,149, +108, 69,127, 60, 51,123,209, 46, 27,113,109,235, 12,207,237,104, 5,104,147,173,176, 63,200,112,207, 4,109,133,105, 22,247,204, +180,180,236, 35,245, 97,241, 85, 86, 91, 75,173,174,179, 68,166,217, 45, 34, 11,224, 70, 69,140,102, 59, 45, 33,105, 59,183,167, +239,170,218,180, 57,185,207,172,234, 75, 55,102,244,206,190,126, 48,117,159, 55,154,163,130,169,134,167, 9,116,147, 79,166,213, +186,243, 24,204,105,117,178, 18, 78,142,109, 3,162, 90,144,215, 55,232,107, 23,200,141,130, 62,216, 25,180,231, 90, 7, 55, 54, +200,245, 11,232, 63,106,221, 41,175,131,188,228,199,255, 27, 80, 94, 3,254, 22,200,191,128,233,174,185, 15,222, 53,139, 30,159, + 91, 17,126,121,133, 92,241,192,232, 71, 62,126, 27, 51,218, 95, 16, 30, 78,164,149, 63, 69, 79, 4, 89, 11,242, 40, 32,234, 14, +137,179, 12, 39,201, 60, 54,169,131, 81,145,139, 26,143,107,159,195,172,230, 74,106, 19,128, 85,231, 6,221, 17,254,242, 2,253, +241, 68,201, 35,124, 92,232,126,227, 42,105, 55,113,248,207, 55,148,119,204, 34,183,253,160,176, 27,236, 97,190, 58,176,209,215, +147,173,146,163,144,178,178,126, 48,210,203,132, 14, 5, 78,132,120,226,160,145,143, 60, 52,237, 6, 64,255, 34,188, 38,240,206, +183,225, 15,222,133, 31,143,112,162,232, 99,115, 72, 72,175,243,168, 75, 5,100, 40,104,231,139, 80, 48, 92,110, 46, 54, 78,111, + 1,231,131,117,235, 50, 45, 18,112,201,251,137, 91, 97, 14,212,104, 78,254,149, 31, 81,230, 77,158,141,178,117,177,152,205,164, +176, 16,144,121,212, 94,246,133, 69,178, 63, 69, 51,177,152,143, 30,181,198,123,186, 34,189, 65,103,214,192, 20,105,250, 44, 81, +232, 29, 6, 18, 99,228,224, 36,112,244,179,199,132,255,236, 57,152, 70,244,119,238,205, 72, 41,113,111,248, 80, 51,189,221,186, +148,231, 7,145,238,137,156,234,248,170,218,239, 42,120, 36, 52, 60,247, 50, 43,174,212, 44,145,234, 74,255,102,199, 95,209, 18, +161,186, 94,117,153,250, 78, 46,239, 90, 53,124,251, 57, 90, 83,108,220, 28,154, 3,132,204, 36, 55,153,117, 16,212,127,174,152, +215,153,135,198,172, 85, 48, 13, 68,196,229,104,182,219,247,162,222, 98, 95,133, 5, 36, 99, 12,251,101,207,223,242,172,230, 0, +158,218,173,106,237, 89, 27, 90, 30,213,203, 45,151,176,182,178,112,220, 29,117,188, 72,157, 26,227,186, 44,241,181, 13,175,103, +217,221,150,210,214,211, 15, 65,209, 85, 36,238,126,177,111,231, 22,203,250,160,144, 66, 66, 82, 50,111,183,175, 4,130, 23,111, +213,167, 73,120,203, 7, 41,123,125,101, 21, 76,202,101,113, 92,140, 22,189, 27, 35,187,221,142, 60, 14,246,186, 66,244, 21,131, +146,115, 38, 15, 35, 37,231,185, 33, 89, 70, 74, 45,157, 46,248, 72, 63,204, 65, 45, 13, 33,127,111, 68, 94,119,251,165, 89,111, +137,107, 18, 36, 38,198, 14,116, 24,144,169, 16,186, 68,137,145, 50, 57, 33,181,221,197, 87, 56,143, 68,135, 22, 55,181, 76, 23, +123, 31, 85, 40,199,251,217, 22,255, 87,207,145,227,157,141,190,245, 42,228,251,176,125, 23,242,219,144, 95, 53,255,109,218, 24, + 88, 67,142,188,219,246, 25,176, 78,205, 6,236,242,167,236,223, 76, 19,148,251, 80,238,128,254, 24,198,191,130,221,215, 33,189, + 6,221,175,249, 92,170,131,114, 2,229,194,108, 68,101,176, 95,195, 19,152, 30,195,197, 57,122,110,176, 19, 6,177, 59,117,151, + 29, 18,162,139, 98,253, 81,182,228,182,209, 21,234,243,145,223, 59,242,188,112,222,231,211,189,255, 55,202, 62,151,218, 8, 73, +126, 58,149,125,177,125,241,130, 58,142,214, 97,141, 62,249,207,174,216, 76, 77,148,239, 30, 68,162,241,162,218, 84,192, 47,239, +178,236,165, 70,181,232,211,204,140, 57,158, 31,184,163,219, 70, 68,237,236,115, 24,225,133,171, 16,186,128,246,166,146,230,222, +132,254,193, 67, 27,191,175,221,223,125, 52,194,250, 28,142,255, 49,132,255, 0,184,135, 5,147, 43,112,100,135, 56, 62, 9,225, +143, 96,247, 47,225,237, 29,250,230,132,158,142,144, 51,114, 45,161,201,222,107, 57,138,240, 66, 66,146,160,187, 12,159, 58,182, + 11,109,114, 69,223,129, 93, 96, 33, 8,226, 33, 42,156, 21,120, 82,204, 86, 24, 28, 65,123,225,171, 17, 5,217,150,101,163, 83, + 71, 94,100,123,226,158, 36, 27,219,223, 29, 40,111,141,148,239,142,200,183,182,132,159,233,136,191,188, 38, 93, 51,144,196,250, +237,145,252,229, 29,249, 71, 35,225,102, 68,142,133,241,207, 71,206, 86,202, 32, 86, 88,226,164, 28, 61,154, 56,124,125, 3, 35, +196, 11, 69,206, 15,208, 79,108,144,107,119,204,175, 30, 95,132,231, 62, 13,219,111,187,102,163, 67,182, 9,189,231, 63, 79,242, + 61,104,189, 32,134,236,162, 45,153,201,128,182,238,105,242, 75,107,180,105,158,159, 73,148,236,201,129, 13, 89, 45,200,194,113, +183,219,167,241,157,137,122,215,141,237,201,181, 54, 44,106,171,137, 98,187, 58,234, 3,177, 29, 11,178,204,114,151,253,189,204, +137,107,120,231, 94, 84, 81, 49,124,110,110, 84,240,161,238, 29, 27,245,182,170,237,175, 31, 61,158, 24,126,255,148,254,247, 79, + 25, 55,133,115, 50,155,152,201,121, 25,127, 87,146, 92,168, 35,110,191,134,235,121, 35,205, 29,187, 54, 51,238,198,111,239,208, +145, 25,219,234,185,232, 45, 54, 85,230, 87,106,249,232,120,166,123,152, 97, 57,234, 60,114,102, 13,198, 28,190,164,203, 1,170, +138, 4,163, 44, 93,178, 94, 10,101,169,194, 47,101,127, 15, 42,174,158,175,202,232, 24, 28,114,162, 25,134,237, 37,251,218, 2, + 84,175,215, 68, 93,231,213,132, 60,154,228, 52,209,125,181,119, 22,230, 33,244, 76,116,171, 74,232,214, 83,191, 23,224,186,252, +249,232,135,143, 86,114,161,173, 35,220,253,253,226, 7,133,122,192, 42,151,188,225,237,212, 56,248,148,241, 67,255, 87,199,198, + 24,146, 53, 9,164,174,159,125,238,179,240,178, 90, 39, 75,251, 19,237, 23,205,102,232,227,216,227, 37,219, 32, 4, 99,199, 71, +239,208, 67,234,184,152, 38,118,195,206,255,123,116,165, 63, 76, 99, 38, 79,147, 89,245,218, 81,186,163, 25,149,229, 64, 39, 40, + 49, 36, 23, 38, 22, 27,163,123, 66,219, 83,236,155, 70,112,160,174, 93,209,121, 74,101, 59,254,210,117,110,155,132,144, 58,159, + 22, 47,201,125, 79,191,125,242,212,103,104,211,131, 56,139, 55, 18,127, 57,192,195,100, 36,175,103, 39,184,122, 10,199,143,224, +224, 46,172, 86, 80, 14, 96,188, 5,253,107,150,249, 28,175, 67,188,225, 59,241,155, 16, 14,172,200,235,232, 54, 40,125,122,145, + 50, 31,213,162,251,128,158,129, 48, 25,184, 99,248, 54,148, 47, 65,247,139, 54, 5,144,119, 32,223,243, 14,125,107, 94,245,139, + 7,112, 54,160, 15, 4,206,130, 11,221,116,153,111,111,124,116,186,117,239,248,153,117, 98,138,157,250,108, 89,105,150, 33,173, + 65, 47, 85,205, 94,253, 51,165,238,153, 90,138, 83,123, 10, 95, 94,130, 58, 56,174,178, 3,134, 98, 33, 6, 53,179, 58,250,239, +147, 92, 19,156,116, 62, 40,212,241,223, 76,134,218,187,153, 60, 31,166,117,229, 5,219,151, 20,255, 67, 5,232,130, 1, 40,198, + 73, 89, 37,120,233,170, 53,181, 42,193, 72,113,135,193,128, 43,193,176,181,114, 43,193,237, 2,183, 55,200,245,127, 4,241, 63, +180,137,140,161,214,128,231, 64,126,210, 98, 75,229, 15,225,201,111,161,223, 5,222, 75, 40, 35,250,100,180,177,193,219, 59,195, +151, 30, 6,244,165, 14,169,249,233,197,218, 39,217, 22,152,196, 14, 94, 15,118, 6,167,121, 49, 89,248, 74, 12,150,173,254,252, +161, 61,185,118, 59, 15,190, 9,203,211,188,171,106,161, 88, 23,158,120, 96,177, 81,240,158,237,209,231, 6,228,129, 21,206,221, +215,183,236,190,182, 37,246, 66,186,153, 88, 61, 31,233,126,101, 69,252, 76, 71,136, 66, 88,117,132,207, 38,142,223, 63,103,120, +125, 96,119,100,194,179,139, 34,236,128,252,112,226,100,216,160,163,146, 6, 63, 89,191, 40,200, 51, 63,130,131, 71, 16, 62, 10, + 47,191, 6,219, 59,240,104, 34,190,182, 34,142, 35,211,227,178, 56,138, 7, 31,133,201, 37,220,101,237,214, 28,129, 32, 77,122, +148,178, 20,185, 82,100, 86,138, 27, 77,203,174,207,169,237,212,155, 10, 96,177,201,165,137,144, 14,139,176, 43, 96,123,186,210, +230, 74, 75,227,111,181,199, 82, 41, 62,101, 42,204,158,233, 69,250,189, 32, 32, 82, 16,130,219,231, 52,168,119, 17,203, 53, 94, + 83,213,152,148, 11, 10,187,113, 55, 15,239, 74, 80, 74,182, 12,233,185,171, 11,194, 80, 92, 3, 80,133, 70,186, 31,237,186,236, +140,181,153,100, 73, 99,133,178,123, 87,212,138,118,209,203,221,209,172,179,158,173,113, 21,224, 82, 42, 40, 70,150,103,212, 84, +215, 97,106,218, 0, 11, 18, 49, 43, 93,214,253,192, 20, 9,115, 50,232,222,100,178, 13, 21,145, 75,237,171,221,223,147,185, 22, +131,218,232, 85,131, 97,162, 85,231,144, 71,105, 19,212,180,216,202,162, 73, 88,147,102,164,155,116,113, 23,132,134, 48,151,129, +209,117, 18, 53,236,100,105, 76,116,239, 32, 34,173,214,176,174, 5,154, 52,158,224,100,185, 34, 62,238,110,148,232,121, 79,161, +214,248,168,165, 85,228,115,169, 43,151,249, 16, 41,141, 85, 45,197, 14,237, 18,101,202, 75,240,204,124,176, 43, 79,229,187,138, + 95,207, 82, 49,179,205,156, 95,154, 81,124, 10,209, 58,116,207, 45,223,169,178,219,110, 9,197, 24,253, 38, 80, 45,214,161,231, + 66, 46,227, 12,126,177,209,250,194,140, 87,173,153, 31, 46,188, 11,129,130,237,192,161, 32, 33,205, 7,166, 42,116,171, 90,152, +138,127,149,134,253,191, 56, 4,140, 57, 95, 60,178, 59,166,132,166, 14,157,166,230,117,201,226,120,208,188,119, 44,171, 48, 35, +156,248, 87,155,211, 84,190,113,134,188,190, 34,116,201,210,183,142, 48,150,246,141, 17, 78, 54,232,141,135,200,173,187,112,244, + 29, 88,253,190,229,197,166, 99,136,183, 32,222, 54,127,121,255, 11,208,125,204,115,160,139, 89,214,102, 83,114,125,199,179, 9, +241,136,144, 15, 33,118, 32,190,179, 31,191, 14,211, 19, 8, 63, 13,225, 89,232, 78, 13, 25,187, 23, 25, 36,182,251, 13, 78,142, +216,120, 87, 62, 86,210,195,130,104, 85, 87,164,171,150,134, 83,153, 41,141, 18,105,191,160,107, 67,202,210,197,178,211,138, 45, +195,146,163, 49,102, 59, 63,100, 53,171, 90, 5, 97, 36, 22,238,118,237,172,179,159,146,217,123, 72, 85, 31,163,182,168,107, 2, +203,225, 64, 29,237,168,254,128, 65,157,104,235, 12,157,226, 40,250, 87,175,194,209,202, 66, 32, 36, 69, 75,169, 19, 87,153, 95, +233,145,219, 29,242, 82,129, 23,118,200,201,223,135,240,107, 80, 30,248, 46, 93, 13,188, 18, 20,194,187, 80,126, 7,253,224, 91, +240, 77, 69,223, 14,112,115,128, 39, 25,253,192,115,205, 71,243,221,201,218, 22,252,250,246,206, 62,159, 67,247,147,171,154, 78, +225,193,136,190, 49,153, 20,226,123, 35,242,194, 8,207,117,246,125,122,223,245,247, 30,115,118,144,144,110, 64,163, 19,254,206, +213,152,247,167, 88,236,235, 73,231,184,177, 2,215, 2,225,163, 43,148,137, 32,153,124, 58,241, 24, 24,139, 18,223, 25,232,222, + 20, 14,191, 53,112,248,108,224,224,118, 79,248,116,130, 65, 88,253,195, 3,174,252,211,145,199, 23,202, 32, 54, 28,216,185,211, + 81, 54, 19,199,239,110, 97, 5, 41, 43,178, 21,116, 44,200,205,251,112,184,131,195,103,225, 99,183,208,205, 7,132,243, 66,186, +182,166, 60,217,144, 55, 19,154,202,124, 58,171,162, 40,237, 4, 73, 46, 66,211,197, 47, 45,141,119,121,190,182,180, 94,111,179, +242,170,121,142, 45,227,220, 69, 41, 44,203, 44,172, 25,117,214, 69,172,212, 81,255,135,200,150,202, 76,240,210,153,141, 86,217, +234,185,105, 7, 13,109, 26,216,136,113,230, 67,168,157,160,175, 74,231, 75, 57,216, 79,162, 33,217, 0, 0, 32, 0, 73, 68, 65, + 84,232,209, 71,217, 33,219,225,183, 56,103,190,222,122,161,146,219,116, 17,161, 73, 48,224, 76,112, 27,103,221,202, 21, 93,238, +143, 58,208,180, 53,131, 16, 66, 85,117,251,180,173,181,234,105,155,105,206, 82,172,217,223, 58,168,103,116,171,238,171,187, 69, +197,197,131,174,102, 15,166, 21, 40, 33, 16, 84, 44,174,214, 81,156, 33,248,104,188,242,185, 92, 73,254, 97,225, 36, 51,141, 47, + 40, 33, 23,195,127,122, 82,155, 86, 85,119, 21,180, 73, 99, 97,213,229,185,177,247,243,203,135, 9, 10,101, 22, 56,230,166,128, +207, 82, 52, 49, 97,228,130,154,213, 61, 27,157,206, 93,189,238,229,209, 75,163,170,215,218,109,214, 21,101,101,215,107,139,184, +101, 46,130,251,251,117, 26,234,217,190,247, 58,138,144,250,222,126,238,146,151,239, 53,143, 55,195, 94,183, 90,213,236,104, 45, +182,251, 25,233,117,236, 30,131, 69,192,246,221,138, 85,151,152,128,237,102,235,129, 39, 66,145,192,148, 39,242, 56,249, 14, 63, +207,238, 1,145,125,171,180,250,158, 98, 81,177, 27,159,189, 30,154, 69,154,159,209,179,211, 85,150,227,101,104,118,234,186,143, +197,153,245,103,130,225, 97,201,133, 24, 35, 83,113,248,132, 44, 26,171,118,116, 23,100,241,164, 51,243,255,139,119, 15, 66,252, +111,142,195,111,134,179, 1, 30,101,164, 15,240, 83, 29,252,233, 0, 95,221,161,223, 86,244, 91,130,188, 21,224, 97, 48, 95,213, +110,128,199,143, 97,251, 14,240, 38,232,159,193,240,251,144,191,106,136,215,112,213,199,243, 71, 70,230,178, 28,212,230, 82,140, +214,222,208, 65, 88, 67,186, 9,241, 99,150, 46,162,247,188, 91,191,238, 68,179, 39,246, 53, 66, 15,253,100, 56,207, 81,236,215, +224,221,122, 85, 20,111,176,253,248, 69, 54,145, 91,171,110, 81, 83, 33,207,127, 95, 22, 79,226,114,204, 95, 64, 47, 34,139, 90, + 81, 60,233,172,102, 68,143,234,150,178, 57, 43, 90,230, 7, 80,239, 77,101,181, 27, 77,186,255,160,129, 37, 47, 37,122,236,183, +238,199, 25,251,120,107,223, 99, 92, 85,179,171, 74,180,245,227,249, 43,215,224,250, 33, 4,141,132,163,206, 64, 65, 7, 29,241, +164, 67,174,174, 9, 47,175,144, 87, 10,242, 66, 65, 14,255, 14,132,255, 4,244,129, 59, 21,220, 8, 27,254, 2, 46,254, 55, 56, +253, 3,244,141,247,208,255,119, 64,191, 61,161,219, 1,213, 17,221, 12,240, 32, 83, 78, 71,235,144,130, 53,247,146,252,226,125, + 99, 68,191,185,177, 19,207,218, 77,189,131, 91, 9,119,197, 82,196,114, 65,222, 26,225,139, 23,240,141, 11, 31,189, 39,123, 65, +170,232, 27, 91,248, 96, 50, 17,221,177, 24, 69,237,194,131, 34, 38,103,199,111,178,135, 14,128,188,150,224,176, 80,238,140, 76, +217, 68,114,244,130,174,133, 45,194,249, 6,134,251,133,248,195,129, 48, 22,244,134, 50,124,127,228, 98, 43,156, 15,194,217, 96, + 35,217,209,207,123,113, 87,232,118,197, 39,253,138,236, 28, 69, 75, 70,194,185,217, 3,111, 69,120, 50, 33,239, 41,114,108,128, + 1,189,176,107, 74,147,204,133,122,238,126,178,146, 75, 99,113,172,100,169,250,176,208,165,208,104, 83, 97,100,217, 18,205,254, +235,160,203,206, 57,184, 66,123, 63, 36, 59, 92,138,157, 44,243,195,158,189,225,165,236, 35,221, 42,157,165,202,193, 43,189, 37, +120,209,206,193,199,159, 94,252, 43, 31,199,159,254, 86,116,170, 86, 95, 93,189,175, 51, 50,162,222,126, 85,252,151,231,235, 91, + 23, 97, 92,176, 2, 60,186,184, 42,121, 54,123, 5, 97, 69, 49, 58, 87,167, 74, 39, 54,177,218, 53, 1, 50,226, 4,187,106,160, + 48, 83,251,146, 89, 94,191, 79,174,187,211,246, 93,144,202, 37, 23,183,149,182,122,172, 74,212,140,144,186,166,251,109,193, 62, +254,249,248,222,164,130, 73, 44, 9, 44, 16,146,131, 78, 80, 68, 11, 82,178, 27,112,124, 34, 24, 2, 26,163,233, 32,136,116, 49, +178,238, 87, 72,119, 64, 73, 43, 52,246, 16, 19,154,146, 49, 27, 66,104,120,242, 50, 11,188,234, 20, 98,182,177, 53,107, 1,219, +126, 52,106, 8,109,136, 4,149, 25,224, 34,202, 89,225, 80, 89,233,158,192, 54,167,149, 53, 67,205,176,167, 95, 95,198, 5, 81, +246, 73,119, 34, 77,225, 19,220, 47,110, 86,203, 46, 38,194,170, 39, 79,217, 20,225, 90,109,114,186,168,251, 61,129,173,238,199, +231,217,137,234, 62,208,197,197,164, 49,134, 37,194,180,235, 32, 37, 46,118,131,129, 99,196,223,191,105,162, 76, 19,228,137,201, +241,221, 85,177,110,159,223, 66,107, 19, 49,207,122,168,246,180,104,197,180, 74,231,230,215, 55, 7,204,216,215,144, 69,193,176, +151, 74,183,136, 0,154, 57,134,184,200, 79,157,205, 65,205, 34,112, 85, 87, 89, 14, 16, 50,131,115, 76, 32, 87,180,204,147, 20, +179,147, 6,210, 91, 91,225,250,182,112, 24, 54, 28, 94, 7,249,202, 68,121, 99, 67, 25,242,172,166,208,187, 29,242,221, 21,225, +217,222,236, 95,231, 10, 55, 34,242,241, 12, 31,153,224,246, 6,174,255, 49, 92,251, 18, 28,220,132,245,207, 66,252,183,161,251, +121,235,188,195, 85, 87,204, 15, 86,172,227,179,160,143, 93,241,126, 0,241,208,126,143,158, 65,190, 11,242,216,118,154,161, 51, +100,108, 92,217,168, 62,222, 71, 14, 30,161, 7,152, 77,235, 84,108, 71,171, 1,210,100,133, 61,136,133,114, 20,167, 39,209,180, +219,173, 76,248, 67,148,155,243,190,188, 34, 44, 85,109, 60, 90,149,233, 85, 57,235, 99, 67,101,201,130,137,193, 58,143,202,193, +174,162,184,188, 23, 33,185, 88, 50, 82,180, 67,195, 84,149,200,205, 46,191,158,238,196, 9, 84,189, 71, 99, 38, 89,116, 99,207, +118,112, 99, 5, 65,140,223, 46, 87,122,194, 81, 71,184,218, 35, 47, 30,160, 47, 68,120,121, 68,110,158, 64,247, 43, 16,255,174, + 23,243, 17,244, 24,194, 35,224,159,161,239,126, 29,253,215, 59,202,151, 7,244,225,100,148,182, 94,209,164,200,155, 62,157,247, +145,163, 14,130,116,222,113,108, 20,185, 42,104,202,198,126,255,171,201, 34, 69,174,121,162,206, 21,187,195, 53, 66, 94, 43,225, + 72,225, 64,145, 7, 19,242,222,214, 44, 99, 69, 61,192,165,160,255,252, 9,122, 91,144,191,125,136, 60,159,140, 32,248,126,182, + 64,152, 39, 5,253,222,136,158,102, 88, 25,122, 55, 51,145, 58, 97,221, 57, 85, 13,211,222, 73, 48,248,223,233,160,232,166,208, +127,107,203,244, 53,229,113, 22,198, 32,108,179,178,205, 86, 16,214, 2,154,157,153,252, 56,115,172, 91,232, 32, 5, 69,206,122, +120,152,209, 23,129,103, 50,114,114, 0, 63,123, 21,121,172,164,215, 33, 92, 23,194,235,129,233,193,232, 34,115,157, 9,198,140, + 62, 2,109, 14,101,115,189, 13,127,141,255,231,178,222, 72,155,249,106,217, 79,161,122, 58, 50,186,217, 65, 95,234,227, 22,172, +171,236, 5,166,204,160,166,121,228, 26,125,199,237,249,215, 25,207,193,110,236, 89, 25, 31, 87,137,255,113,153,195, 52,108, 50, + 97,193, 24,153,154,208, 85,187,127,157,213,236,168, 46,123, 95,223,160, 85,139,210, 65,128,181,143,124, 75,195, 99,175,204,236, +196, 2, 27,116, 92,196, 28, 51,154,125,151,123,153,180,165,151,252,113,210, 68,158,202,165,128,149, 54,202,116,242,206, 71, 85, +200, 49, 89, 16,199, 52, 34, 20,231,122,123, 58,219, 28, 20, 99, 16,160, 34, 22, 50, 21,252,207,148, 26,252, 65,178, 81,175, 84, +170,155,139, 5,253,161,108,151,134, 15,204, 75, 54,239,123,140, 75,200,135, 24,226, 20, 53,118,134,150,105,254,115,165,105, 72, +234, 97, 35,184,117, 81,155,157,255,236,181,247, 17,246,158,189, 76, 47,137,216,170,186,124,182,249, 86,172,171,159, 1, 89, 94, +123, 45, 76, 79, 73,231,154,108,215,250,255,209,161, 97, 81,160,235,123, 63,252,149,167, 48,105,218,138, 69,133,253, 29,125, 83, +208,101, 94,142, 58, 10,214,177,173,125, 74,132,148,184,152, 38,242, 52, 16,130,101,219, 79,211, 72,241,253,121,174,205, 94,115, +144, 43,141, 27, 97,182,167,248, 61,180,231,138,151, 89,178,106,214,219,138,205,189,164,236, 88, 16,185, 6, 40,162, 10, 45,103, + 44,236,146, 42,103,209,200,230,206, 97,246,184,251, 10,182,177,140, 20,103,240,183,148,199,202,251,151, 24, 72,155, 16,136,209, +166,158,135,119,118,240,189, 13,131, 51, 31,147,192, 90, 11,235,221, 72,218,108, 41,119, 35,101, 99,167,154,116,144,224, 47,146, +137,117, 14, 34,114, 34,240,209, 2,159,126, 23,249,248,255, 13, 47,252, 30, 92, 63,134,245,199,160,251, 71,144,254,166, 97, 56, +195,145, 63,132,214,134,225, 84,247,155,151, 83,147,110,135,107,134,150, 45, 24,228,102,245, 14,108,191,103,243,238,248, 2,244, + 71,200,250,125, 56, 26,208,247,177,214,245,188, 24,217,194,125,172,236,196,200, 98, 23, 66, 41,226,207,171, 96,138,228,232, 99, + 74,105,118, 99,178, 8,142,196, 33,207,101,242,110,174,168, 71, 90,170,227, 29,217, 3,103, 38,207,140,209,232, 23, 77,222, 87, + 35,199, 70,221, 90,253,166, 53,167, 62,151, 75,138,120,239,196,170, 37, 67,188,107, 73, 98,138,233, 46, 40,135, 1, 14, 11, 60, +119, 69, 72, 71, 9, 89,119,132, 3, 67,249,198, 27,107,120,177,135,151, 34,225,118,129,147, 23, 32,253,187, 16, 63,235,140,243, + 96,254,244,248, 87,112,241, 63,163,223,249,128,242,123, 91,242, 55, 47,200,247,119, 22,125,218,155, 6, 82,122,177, 36, 57,127, +250,202, 42,216,123,124,205,212,235, 82, 10,186,197,186,249,152,209,247, 39,228, 98, 66, 62, 62, 33,107,167, 54, 93,241,207, 38, + 42,217, 74, 4, 92, 40,241,125,179,108, 49, 40,252,196, 33, 92, 13,232,170, 48,253,127, 27,248,242, 99,194,171, 29,225,167, 59, + 75, 69, 27, 60,151,253,182, 32, 69, 40,119, 70,202,189, 17,174, 65,217, 8,105,172,126,106,241,248, 96, 37, 37,235,192,183, 69, +121,112, 1,219, 81, 24,124, 92, 56,184, 75, 33,123, 51,158, 60, 2, 30, 32, 63,201, 92,121,115,107,209,171, 87, 11,114,154, 77, + 39, 48,246,232,173, 0, 55, 59,248,187,215,144, 17,194,131, 72,247,217, 14,185,179,101,122, 48,218, 65,103,212,121, 26,222, 42, + 98,247,206,150,165,217, 13,183, 81,151,141, 7,186,236,141,110,132,210,108,141,235, 42, 71, 84,246,145, 30, 66,227, 70,113,239, +251, 37,187,105, 21, 67,201,222, 30,186, 1, 93, 56, 32, 99,102,126,235,228,254,238, 64,167,197,114,196,235, 20, 41,152,162,189, + 0, 57,139,175, 26,172, 8,150, 25,177,202,220,209,236,145, 68,159, 82,123,195, 58, 64,103, 35, 40,138, 42, 67,118,191,185, 23, + 40,117,211, 77,251,222,168,238,167,151,213,226,158, 91,139, 92,245,221, 4, 8, 26, 22, 79,127,147, 10, 38, 31,162,109,194,187, +167, 73, 77, 12, 53, 54,121,221, 73, 76,105, 95, 37, 32,197, 31,190, 65,132, 18, 35, 18, 59, 99,136,171, 71, 57,251, 33,103,244, + 78, 81,220, 75, 95, 60,127, 92, 93, 87, 80,161,244,165, 2, 99,114,178,102,162,212,180, 46, 43,251, 29, 32, 18,153,130,123,188, +103,130,159,237,187,231,241, 56,151,140, 15,218,252,172,212,173,141,173, 15,164, 1, 96,181,160,206, 60, 43,172,151,104,213,125, + 91, 90, 43,144,171,144, 30,109,248, 48,178,160, 90, 29, 81, 43, 10,177, 75, 72,234,200,211,248,148, 35,142,189, 78,223, 39, 6, + 65,230,216, 96,217, 27,100,215, 57, 85,245,142,139,229,152,119, 29,131, 22,198,237,214,176,190, 18,200,101, 32, 79, 19,154, 39, +255, 90,101,175, 99,174,133,214,137, 77,243, 72,190,226, 99, 5, 63,216,214, 48,156,217,211,175,174,196,119,182,124, 21,205,169, + 77,166,171,160,148,102,205,146,203,178, 72, 81,215, 8,132,228,236,120, 64,250,142, 60,142, 38,164, 21, 3,109,233,222, 33,129, + 61,176,141, 89, 15, 45,174, 54,254,147,231, 15,127,179,115,201,237, 16,132,243, 24, 56,147,192,185, 8,103, 8,231, 42,148, 96, + 23,213,249,144, 57, 45,133, 33, 22,138, 20,134, 97, 96, 60, 31,152, 30,111, 41, 31,236,208, 59, 35,124, 5,248, 82, 68,255, 84, +224,173, 1, 57,127, 7,228,139, 32,191, 11,250,117, 43,230,114,203,189,239,189, 23,154,232,197,254, 25,235,236,229, 69, 43,224, +225, 58,196,231,160,123,198,232,118,156, 58,147,251, 10, 28,128,156,236, 96, 93, 22,190,106, 87, 79, 56, 97, 70,248,121, 12,149, + 91,115,150, 43, 81, 90, 26, 66,176, 44,240,250,123,203,180, 48,181, 43,163,125,102, 16,248,205, 16, 5, 82, 20, 58,119,234,229, + 73,103, 82, 86,185,116,209,215, 67,111,244, 8,240,206,215, 33,227,162,105,154,213,173,193, 85,190,177, 89, 61, 31,116,194,202, +199,238,215, 50, 60,251, 92,164,127,110, 69, 56,233, 9, 39, 43,226,173, 53,225,246, 1,124,180,135,143, 9,242, 66, 15,135, 31, + 55,184, 15, 47,219, 45, 47,226,170,174,127,138,190,247,127,192, 31, 63, 36,255,175, 23, 76, 95,127,204,227,237,192,233, 90,121, +146, 96, 80, 37, 4, 11,111, 56,223, 40, 59,207,139,150, 11, 53, 61,198,181, 68,184,209, 67,143,165,181,157, 78,232,131,209,176, +173, 23,217,146,225,178,218, 52,229, 8, 75,169,187,155, 41, 63, 28,209, 15, 50,122,191, 32, 71, 1,249, 72,132, 51, 69,142,109, + 26,160,113,162, 92, 12,236, 94,223,112,246,198,142,139,191,216, 81,222,218, 33, 79, 38,228,186, 16,126, 97,141,124,126, 77,120, +181, 39,124,106, 69,120,177, 51,209, 75, 54,122,220,202,109,248,235, 35, 97,213, 43,195, 4,167, 91, 97, 82, 97,235,197, 96, 48, + 83, 4,131, 86, 2,155, 80,130, 44, 78,135, 8, 97, 80,210, 46, 47,214,133,173,189,118, 75, 35, 1, 78,122,120,121,133,188, 63, + 64, 17,226,115, 29,193,151,160, 53,221,172, 6,243, 8,210, 6, 40, 45, 69,254, 82,138,149, 94,162,115, 20,246,187,241,189,223, +223,196, 35, 7,167,183,153,114, 59, 46,192, 87,185,100, 60,158, 83,187,100,190,208,164,249, 1,130,167,101, 77,197, 56, 19,234, +243,253, 18,116,246, 52,151,185,251,150, 89,147, 82,153,236,197,185,237,243,175, 6,129,106,126,110,153,247,193,210,116,109,201, + 15,197,125,130, 85, 12, 36, 49,215,192,144, 97, 82,221,167, 46, 58,133,113,200, 31,190,210, 74, 1, 58, 31,163,103, 17,247,198, +203, 98, 41,144,250, 90,131,143, 59, 3, 53,149, 57, 86, 8,141,180,130,172,101,149, 48,185, 37,111,116,212,108, 85, 94, 71, 87, + 61,219,180,219, 16,164, 65,162,107,106,220, 83, 92, 20, 77,201, 15, 58,117,159, 95,156, 74,233, 3, 19, 17,186, 40,164, 32, 75, + 4,172,199,228, 22,138, 13,199,213,156, 8,234,175, 33, 5, 33,164,206,198,210,212,247, 95,103,172,108, 16, 89,160, 53,254,179, +170,200,211,158,242,102, 20, 95,199,136,245,181,137, 29,227,150,126, 94, 91,234,159,238, 7,139,104,227,125,170, 30,106, 93, 4, + 73, 22,181,107,201,104, 81, 32,174, 14,252, 64, 56,205,187,116,109, 2, 77,236, 32, 22,136, 30, 1,171, 85, 32,217,220, 52,218, + 72,239,140,235, 30,232, 82,207,122,213, 83, 98, 98,179,221, 32, 37, 67,180, 41,137,141,221, 7, 11,128,210,203,200, 28,153,223, +131,138,221, 53,247, 66,216,211, 47,204, 83, 3,145,189,110,219,244, 6,121,185,113,253,123,180,160,229,197, 37, 33,203,184,195, + 79,216, 85, 64, 87,170, 69, 83,156,248, 55,141, 14,227,105,217,184,230, 93, 15, 18, 45,152, 70, 76, 20, 40, 41,154,219,226,191, +124,246,240, 55,147, 27, 53, 11,194, 64, 96, 7, 70,179,242, 4, 31,137, 48,168, 24, 88, 76,132,173, 8,155,108,182,240,199, 17, +206,162,112, 30,149, 49, 20,114,158, 40,155, 1,121, 48,193,157,130,126,165, 67,190,209,193,102, 68,210, 29, 83, 87,151, 63,176, + 81,187,220,246, 29,188, 35, 95,101,106,150, 93, 14,169, 9,215, 76,148,151,110, 67,255, 12,132, 11,131,105,107,130,238, 0, 57, + 84,228,218, 0, 87, 11, 28, 57,219,187,143,150,246,229,209,122, 18,237, 36, 99,170,156,138, 76,117,193, 69,146, 69,125, 61,184, + 98,183,217,197,213,247, 63,213,164, 40, 23,107, 71, 49, 21,122,113,210, 85,181,140,176,247, 16, 95, 38, 80, 33,154,170,182, 51, + 81,186,237, 17,235,206,181,209,102,204,130,112, 63,163, 28, 4,179,172, 29, 71, 56,217, 40,215,111,116,244, 31, 63, 32,244, 43, +226,141, 3,194,237,181,101,215,127, 60, 32,175, 4,228,218,179,176,250, 60,196,159, 55, 42,160, 76,222,230, 60,130,241,127, 65, +223,254, 38,124,185,144,255,112,195,238,205, 51,238,167,204,253,149,112,166,182,107, 62,203,246, 64, 60,219, 9,143,118,194,102, +244,144,176, 2, 93, 22,194,245,104, 35,118, 1,253, 96,162,220, 29,152, 30, 78, 51, 46, 32,111, 50,242, 36, 19,206,213,114,228, +223,203,148,187, 19,250,129, 89, 15,195,115, 9,249, 72, 71,120,161,179,234,250,110,134,105,160,188,189, 65, 31, 14,156,159, 21, +222,139,118,173,157,110,149,241, 97, 38,252,104, 36,190, 51, 18,158,137,200,107, 7,200,203,107,228,246,138,248, 82, 32,220,140, +196, 40,164, 67,232,110, 5,226,181,128,158, 41,167, 79,224, 34,135,121,165, 49, 78,230,126,156,178,237, 24, 83,172, 39,106,153, +187,178,236,159,163,168, 18, 55,254, 48,149,154, 75, 84,233, 97, 10,215,123,120,190, 71,238, 26, 66, 82,158, 75,200,198,191, 81, +242,192,135,184, 60,232, 68,247,211,169,246,241,150, 11, 35, 91, 26,161, 84,227,128,219, 91,197, 5, 22,123, 86,106,246,241, 33, +232,158,233, 68,218,125,186,196,249,139,213, 68,171,217,102,227, 86,174,162,178, 32,152,235,175, 36,243, 20,161, 52, 83, 37,196, + 19,187,128, 66, 88,246,231,218, 60,238,157,119, 94, 2,205,247,182, 78, 38,122, 88, 75, 77, 74, 78,224,185,240,202, 38, 11,219, + 22,246, 82, 41,113, 52,224,193,150,218, 86,197,167,158,174,140,109, 63, 24,170,149,203,119,229,177, 41,216,234, 93,117,240, 2, + 22,188, 16, 90,199, 83,215, 95, 58, 11,217,212,225, 31, 90,242,114,152,168,138,230, 70,164, 92, 21,202, 82,227, 58,125,250,161, + 49,153,142,160,100,119,228,152, 45,169, 52,184,240,250,115, 76,237, 7, 30, 22, 37,248,172, 76,247, 3, 9, 41,206,251,233, 16, + 59,223,175,218, 26,160,175,190,123,177,178,220,137,165,159,153, 37,177,204,182, 50,221,187,246,164, 25,149,219,243, 81, 69,246, +124,225,101,239,242,213,189,195,128, 60,125, 78,152,133,101,181,232, 74,140, 4,132,212,245,214,165,231,105, 57,232,180,250, 38, +239, 66,103, 94,187,132, 69, 8, 22,132,167, 96,180, 62,114, 79,201, 52, 9,113,213,179, 25, 71,166,221,206, 72,131, 37, 51,229, +201,196,210,165, 44,163,107,221, 79, 61,146, 86,101, 31,130,255,114, 17,170,255, 60, 93, 76,116, 93, 79,136,209, 14, 89, 94,128, +149, 96,160,167,185,235,215,217,103, 95, 49,183,165, 2,206, 40,174, 43, 89,126,158,146,173,139,148,102,255,102,105,123,186,103, + 69,173, 48,160,224,201,112, 82,181, 6, 62, 33, 10, 18,136,255,228,249,227,223, 76,110, 13,153,138,237, 27,183,165, 42, 69,157, +103, 21, 2, 59, 21,206,179, 48, 98,234,234, 18,133, 93, 17,182, 69,217,169, 37,144, 93,136,176, 11,194, 38, 9, 83, 80,162,102, +194, 52, 89,123,116, 39,194, 55, 58,120, 91,225,226, 62,116, 95, 70,226, 23,172,157,139,175,120, 1, 58, 48,196, 23,161,153, 1, +137,137,232,194, 53,203,173,238, 94,128,238, 42,244,147, 37,141,165,222,232, 99,199,130, 92,203,200,245, 1,174,103, 56,193,212, +213,201,192, 6,210,133,229,131, 74, 11,171, 82,130,123, 33, 39,245,128, 23,165,234, 66,234,141,218,121, 49, 78,209,111,190,232, + 65, 15,197, 44, 73,237,184, 61,200, 37,212,165, 44,112,139,152,236,225, 49,233, 62, 37, 74,196, 58,254,228,162,245,181,135,158, + 29, 39, 51, 35, 28, 5, 88, 35, 28, 61,211,179,250,236, 49,225,228,144,240,194, 10,121,173,135, 79, 4,120, 45, 34, 55,175,195, +193,103,172,152,199,143, 2,174, 99,144, 96,106,247,233,183,209, 7,119,225, 59,145,252,197, 51,118,175,159,242, 65, 46,124,224, + 7,180, 41, 91,214,205,206,245,104,231,158, 6, 42,193, 58,136,149,194,250, 40, 18, 95, 94, 17,110,116,246, 30,110, 76, 64,183, +221, 42,143, 51,108, 85,216,170,112, 49,193,230, 65, 97,120, 47, 19,207,149,120, 40,200,237,100,221,245, 47, 31, 32,183, 18,250, +142, 41,158,202,247,183,148,247, 7,166, 63,185, 96,251,112,226,145,103,166, 76,110,118,216, 69,216, 78, 74,185, 59, 18,191,186, + 69,238, 77,179, 93,144, 46, 34,193,198,251, 37, 23,244, 73,161, 60, 42,236, 46,148,179, 81,216,101,153, 95,211, 99,255,107,138, + 86,208,131, 68,255,188,150, 66, 23,196,172,100, 89,108,142,155, 54,101,230,105,115, 86,144, 51, 69, 14,253, 3,189,209,195,205, + 4, 63,154,144,117, 64,142, 2,250, 32,155,171, 33, 25, 54, 54,164,104,145,198,200, 94,199,189,116,244,117,124,185, 60,164, 90, + 77,198,194, 16, 95, 58,220, 24, 27,206,251,188,107, 92,148,187,114, 57,193, 41,132, 26,206,108,191, 55, 93,154,161,138, 93,195, +243,232, 81, 91,162,152,236, 9, 56, 39, 87,186,151, 25,194, 18,108, 53, 85,154,189,174,119,219,203,136, 93, 23, 37, 59,150, 85, +208, 71,235,112,131,207,115,173, 11,134, 11, 21, 70, 31,249,106, 67,155, 75,254,217,132, 70, 16,215, 24, 2,230,131, 77,242,221, +124,141,118,152, 27,116,135,208,172,130,160,151, 86, 14,117,102, 17,252,160, 31, 28, 98, 83,154,221, 63, 78, 81,107,243,205,235, +103, 90, 90, 15,121, 51,117,169,185,221, 26, 92,217,172,217, 4,103,170, 51,102, 87, 47, 77, 27,180, 10,179,106,161,245,221,115, +253,123,149,128,132, 72,137,201,139,126,130,212,161,211, 96, 62,237, 70,253, 62,239,164,133,134,199,111,141,197,222,126,189,249, + 61, 75, 38,183,189, 31, 42, 97,111,135,141, 11, 61,151,117,146, 46, 63,248,229,162,126,185,171, 76, 70,145, 76, 18, 72,171,181, +173,110,178,189, 11,165,148, 61,155, 66,181,172,133,154,128,134,161, 88, 45, 0, 70, 46,145, 76,237,189, 78, 49,178,234, 87,172, + 86, 43,134,162,236,182,155,217, 89,148,167,201,173,205,121,129, 70,181,247, 73,179,187,183, 2,153, 22,145, 99,213, 63, 4,119, + 21,185,242, 93,221, 26, 87,113,177, 18,189, 1,110, 24, 1,141,126,112,161, 9,126,152,164,203,237, 11,179,170, 61,134,246, 6, + 95,152, 38, 78,178, 11,226, 93,121, 12,132, 24,188, 67, 79,243,247, 73,193, 97, 7, 8,236,138,199,130,170,123, 17, 85, 40,158, +220, 54,170, 48, 86, 11,150, 58, 71, 58, 70,198,146, 9,110,247,144, 82,216,169, 18, 35,108, 5,182,162, 28, 78,153, 62,103,186, +243, 29,221,251,145,240,122, 79,248,227,158,240,249, 53,250, 31,223, 67, 62,241,223,193,201,111, 67,255,239, 67,250,101, 27,205, +203,161, 21,114,137,205,192, 78, 32, 30, 89, 97, 15, 47,195,234,151, 12, 85,171, 27,243,181,231, 7, 6,180, 25,127,132,108,238, +194,246, 33,156,239,208,135, 1,222, 11,112, 47, 34,167, 9,121,164, 48,140,200,110,162,236, 2, 58,100, 66, 54,180,168,246,138, +140, 98,224,137,156, 73,106, 83, 10, 89, 7, 27,207, 79,214,201,215,241,162, 20,217, 75,196,154,109, 12,141, 66, 84,154, 28,104, + 84,108, 55,231,191,127,229,250,164,212, 80,244, 87,106, 39,109, 27,183, 7,226,145, 16, 83, 71, 56,234,136,159, 61, 68,174,247, + 22,247,249,140, 88, 86,250,209, 53,136, 47, 65,120,205, 98, 68, 37,154,131, 64, 31,185,100,127, 7,211, 23,209, 39,239,194,247, + 2,229, 95, 63,102,124,253, 9,247, 39,248, 64, 2,231,147,204, 86,161,177,250,168, 39,251,153, 87,126,245, 69, 85, 86, 2,225, + 70, 34,220,234, 9,199,201,146,235,130, 61,233, 71,204,230, 55, 84,125, 73,177, 7,228,245, 91,166,115, 8, 31,237, 8,159, 62, + 48,128,119, 14,232,159,109,209, 15,132,248, 55,122,228, 35, 9,125, 50, 50,141,133,109,191,116,211, 67, 94,114, 93,114, 7,186, + 10,148, 60,113,237,171,103,116, 15, 39,226, 11, 61,178,142,148,123, 19,211,219, 3,211,253,129, 39, 99, 97, 27, 33,135, 96, 63, + 79,134,179,193,214,250,227, 84,117, 47,118, 83,104,130, 62,218, 40,112,187,181,113,123,116,111,233, 78,224,113, 50,146,223,241, +253,137,245,227, 76, 60,152,208, 65, 73,189, 89,160,136, 1,158, 59,128,191, 1,124,245, 2,185, 46,196,155,153,252,227,193,140, + 31,149,233, 62,170, 45,238, 55,153, 32,197,212,250, 90,133,152,142,106, 45, 11,251,189, 37, 60,148,176,175,237, 20,177,183, 80, + 23, 25,200,242,192,111, 81,150, 94,237,212,219,254,121, 72, 16,170, 4, 95,125,255, 44, 85,227,118, 89, 81, 54, 63,108, 66,168, + 63, 87,125,192, 4, 38,191,186,117,198,182, 26,247,191,140,101,166,178, 73, 85,189,207,216, 83,211, 88, 7,159,134, 20,241,174, + 84, 27,229,186,238,143,122,235,215,233, 92,155, 66, 83,208,105,242, 92,234,136, 92,138,199, 28, 8,172, 28,224, 82, 71,245, 49, + 88, 81, 47,126, 24,183,189,166, 54,244,252,133,254, 84, 59,251,209,127,134,224,239, 67,104,172,167,200, 94, 56,157, 77, 4, 2, + 77,167,102, 74,108,153, 70,235,192, 42,221, 46, 5,239,218, 23,171, 88,104, 68, 97,170, 75,135, 44,168,237,239, 3,236, 84,102, +174,123, 8,201, 4,120, 10,196, 14,101,103, 36, 52,255,190, 83, 61,172,168,204, 92,179, 73, 13,101, 28,129,222,223,155,249,240, +243, 33, 12,208,162,151,131, 67,234,103,210,232, 54, 46,195, 81,218,110,215,167, 96,162,190, 6, 21, 33,170,210,245, 43, 8, 17, +245,104, 85, 81,221, 79,117,243,247, 68, 90, 7,130,182,234,144,197,119, 87, 61,229, 97, 46,234, 61, 37, 4,134,205,150, 80, 89, +238,117, 26, 48, 90, 28, 80,144,200, 42, 5, 52,216,103,150, 27, 52,171, 93,226,145,152, 18, 93,215,205,240,155,226,160,163,162, + 22, 82,148, 27, 75,164,173, 21,146,173, 60, 82, 90,186,110,221,223,251,235, 37,191,253,190, 32,209, 68, 86,245,112, 95, 17,225, +162, 32, 41,218,100,106,154,252,144,211, 30, 34,236,160, 17,194, 2, 26, 50, 7, 73,144,121, 31, 51, 2,147,216, 15, 61,185,106, +117, 66,216,249, 15, 49,250,155,222,213, 27,215,119, 73, 18, 29,171, 88,160, 99, 66,180, 48, 40,236,180,112,234, 76,145, 21,112, +156, 39, 14,207, 38,186, 39, 23,164, 63,236,145, 63,235, 9,175,101,228,231,190, 14, 31,251, 6,242, 98,128,171, 7, 22,125,217, +157,216,158, 61,173, 65, 78, 32,253, 12,164,159,131,240,138,237,218,229, 25, 22,163, 76,163, 52, 42,231,214,153, 14,223,132,205, + 23,144,231,190, 7, 47, 61,130, 39, 91,244,161,192,155, 17,222, 78,132,123, 29, 34, 35,154, 50,165,207,115, 50,155,157,170, 27, +245, 71, 7,244, 1, 29, 45,130, 53,228,209,139,185, 86,247, 12,157,143,210,170, 69,106,142, 81,172, 55,108,116, 17,203, 76,176, +242, 29,125,180,140,231,228,251,246, 20,133, 24, 3, 97,109,145,161,225, 56, 17,174,116,200, 65, 66, 62,217,195, 11, 17,174,129, + 92, 89,195,250,186, 79, 56, 94,114,113,161,130,108,236,223,229, 55,161, 60,182,201, 71,249, 62,236,222,128,215, 3,229, 79,207, +152,190,245,152,199, 67,230, 65, 20,158, 56, 13,175,158,188, 39,167,140,197,149,189,236,226,163,200, 94,160,235, 3,225,102,103, +163,247, 20,188,245, 85,202,206, 10,250,136, 21, 78,124,191,121,120, 37,178, 62, 14,132, 11, 67,193,234,195, 9,221,128,126,175, + 32, 93, 36,254,108,135,220,240,216,200, 81,225, 43, 66,159,148,131, 4,103, 59, 22,102,183, 26,129,237, 2, 40,209, 72, 46,215, +222,219,161, 39, 66, 58, 84, 3,226, 93, 4, 56,181,135,245,105, 14, 84,237, 77,241, 88,207,106,149,138, 53, 6, 52, 66,223, 5, + 62,254,249, 67,158,220, 31,249,209, 95,110, 76, 97, 30,173,238,141, 46,234, 26,197, 14, 25, 7,131,114,117, 26,231, 27, 48,173, +163,217, 63, 99,132,151, 14,108,180,240,253, 45,225,213, 53,114, 14,122, 62, 17, 79,108,119,146,207, 38,244,116, 48,225, 97, 49, +152, 75, 81,157, 33, 70,165,232, 2, 86,201,203,228,187, 92, 66, 94, 87, 81,230, 44,116,247,247,134,230,159,159,222, 18,178,191, +255,204,151,214, 0, 82,139,188, 49, 85,181,185,157,172,234,235, 66,156,115,229,242,232,226,174, 50,103,144, 7, 51,138, 85,161, +206, 12, 60,241, 0, 16,196,174,117,223,101,217,110,190,236,231,151, 87,250,153,180, 80,168, 37,200,101, 22,153, 46,176,233, 5, +222,211, 12, 30, 70, 42, 93,216,246,199,187,106, 19, 84, 37,168,204,247,229,194, 90,175, 83,135,101, 4, 92,194,114, 88,216, 91, +159,205,135,243,101, 87, 93,119,217, 58, 79,124,100, 22, 10,106, 76,150, 12, 87, 44, 61,174,166,122,197,152,172, 56,228,130, 78, + 19, 57, 27, 85, 45, 72,211, 61, 42,179, 66, 94, 27,229,191,109,127, 50, 90, 70, 8,201,222,247,225,194, 24, 26,213, 49, 80, 61, +220,190,225,174,247, 80, 13,242, 25,253, 32, 21,155,149, 68,110,196,126,168,208, 14,230,231,228, 57,173,154, 3,105, 20,219, 50, +179, 22,120,170,104,201,156, 82,134,239,253, 87,171, 21,221,106,205,118,156, 90,103,221,194, 96,111, 38, 47,115, 44,235,158, 52, + 68,246,200,199, 53,208, 36, 5, 43,232,146, 18,227, 52, 89, 80,139, 59, 15,114,182,168, 83, 45, 21,237, 92,220, 30,231,137,109, + 68, 7,208,100, 23, 38, 71,250,149, 29, 60, 74,158,252,221, 95,246,230,168, 54,215,110,153, 25,250, 22, 24, 19,144,148,128,201, +244, 13, 69,247,209, 59,210,236,211,139,101, 0, 84,237, 87,169, 86,194,246,186, 11,158, 84,217, 89,250, 32,174, 51, 8, 33, 44, + 59,127,191,182,202,124, 24, 86, 82, 41,206,124, 22,179,162, 84,207,232, 6,191, 17,138, 25,226, 17,153,173, 67, 89,101, 30, 31, + 34,193, 34, 6, 93,241, 90,196,198, 78, 5,227,227,166, 98, 93,255,128,146,131, 48,117, 74, 15, 28,234, 72, 58, 29, 9, 95,139, +200,215,163,239,188, 3,114,248, 24,185,254, 24,110, 1, 30, 28,199, 21,133, 27,191,135,188, 18,224,197, 99,184,246, 73, 56,252, + 47,160,251, 5, 8, 55, 61, 74,212, 91,159,152,140,122,215,189, 6,135,255,158,117,241,227, 29,216,253, 57,178,251, 50,188,250, + 6,122,111, 11,175, 71,228,135, 9,121,208, 17,114,221,215,248,227, 47,251, 77, 85,178, 49,201,139,129,110, 74,202,104, 74,168, +102, 98, 81,210,228, 98,136,201,118,105,165,152, 98,188,120,236, 34,201,131, 56, 74,158,115,168,235,222, 60, 6,155, 14,196, 40, +150,240,117, 20, 9,171,100, 83,129,227,132, 92,239,144, 43,201,222,135,219,192, 51, 43,164, 63, 49, 93,129,124,196,243,207, 87, +214,163,148,187,192, 99,136,159, 48,178,223,244, 61, 43,246,211,219,160,223, 69,223, 41,232,183,183, 76,223, 57,229,236,108,228, + 81, 18,182, 59,131,132,100,160, 83, 27,135, 74,103,157, 75,242, 61,126,240,189,126, 63, 9,241, 70, 34,220, 92, 33,199,209, 42, +227, 35, 12,135, 90, 44, 59, 62,142, 16,163, 5,118,172, 18,200, 88, 56,255,192,104,190,221,157,204,234, 71,153,120, 18,137,215, + 58,226,231,123, 68, 35, 92, 24, 30, 75, 78, 18,161,143,232, 38,179, 58, 22, 11,133,217,249, 65,210,249, 0,243, 3, 47, 26,110, +246,218,155, 59,228, 68,136, 47,117,164, 85,135,110, 38,142,222, 29,216, 1, 15,139, 5,234,132, 58, 13, 9,206,206,247, 14, 34, +250, 40,229,237, 31,108, 57, 63,205, 11,145,214, 7,159,163,175,206,147, 56,172, 16,115, 31, 92, 57,157, 64, 46,144,215,133,212, +249,174,164, 83,248,216,177, 9,234,238,239,144, 79, 31,192,191,184,128,151,123,248,123,107,194,151,158,160,239, 41,218,179, 71, +242, 82,109,243,178, 23, 52,106,171,232,110,133,150,179,142,206, 71,247, 84, 45, 6,218,128,167,116,217,151,151,253,209, 40, 13, +103, 93,171,184,206,164,213,196,138, 37, 45, 77, 50,161, 87,181,146,173,123, 33, 66, 16,207,146,207,130,134,122,221,123,239, 60, + 93, 66, 87, 6, 33, 21,153, 83,199, 74,168, 28,124,157, 11, 73,165,112,133, 69, 85,199, 20,162, 63, 0, 77,249, 94,167, 10,179, +189,190,138,192,252, 1, 22,154,201,151,248, 78,186, 23,232,171, 71,155, 5, 30, 80,234,193,192,109, 65,193, 5,114,185,161,174, + 40,206,178,154,173,136, 50, 91, 75,235, 62,179, 30, 90,234, 55,158,115,189,213,173,174, 33,154,255, 60,103, 74,140, 51,105,178, + 79,137, 28, 34, 69, 18, 49, 41, 41,140, 72,182,144, 42,113,127,118, 3,255,195, 66,167,131,231,183, 23, 71,235, 66, 41, 22, 70, + 82, 98, 50,124, 51,173, 51,103,102,141,241, 52,138, 67,246,121, 94, 77, 54,124, 17, 59,130, 21, 95, 7,137, 86,246,187,204, 57, +242,251, 35,118,153, 35, 94,165,237,166,165, 25, 29, 35,115,146, 89, 23, 18,221,234,208,237,142, 77,158,176, 54, 0, 46,183, 84, + 46, 98, 60,217,203,173,159,109,201,243,244,199, 33, 51,169, 35,246, 61,147, 42,227, 48, 56, 62, 87,152, 38, 11,135,209,113,156, + 89,219,138,185,148,132, 60, 35,137,139,179,236, 83,234,232,250,149,105, 40,114,158, 39,214,185,174, 7,244, 50,202,169,174,230, + 29, 78, 36,246, 44, 15, 49, 94, 10,121,113, 28,114,104,167, 30,101,241,181,187, 38,160,136,160,121,108, 88,238,246,223, 82, 12, +224, 40,221, 86,115, 80,149,157,170, 75, 6, 0, 64,146,104, 29,206,232,136,193,209, 97,109,163, 95, 0, 81, 5, 25, 50, 18, 35, +147, 8,145,192, 40,236,219, 10, 84,232, 66, 32,198, 64, 25, 97,146,108, 54,175, 92,201,105, 54,194,202, 82, 49,167, 86,228, 87, + 65, 89,147, 9,100,207, 76,142,200, 20,145, 15, 4,238, 86,207,133,239,192, 83, 32, 28, 7,228,246, 22,126,241, 43,200,231,190, + 14,207,223,132,107,159,129,245,175, 88,190,123,188, 5,242,156,121,223,137, 6,192, 73,135,144, 94,130,131,191, 13,229, 55,224, +234, 29,228,198,111,193,179,127,130,126,236, 49,188, 5,220, 79, 48, 90, 91, 32, 71,190,199, 28, 50,108,221, 86,245, 16,232, 51, + 97,116, 10, 29,101,137, 79, 84, 39, 61,121, 48, 12, 59, 79,130,171,109,161, 47, 35,235, 72, 91, 86,130,116, 98,160,152,181, 64, + 31,145, 99,219,201,154, 95, 45, 26,227,252, 42,214,149, 31,175,224,224,182,197,213,202,243, 70,128, 67,141, 8,151,239, 25,176, + 71, 51,164, 23, 32,188, 4,195, 31, 66,233,205, 22,168,223, 67, 31, 94,192,119, 38,242, 55,207, 24, 78,119, 60, 10,194,227,209, +120,221,197, 39,178, 93,178, 61, 62,190,239, 79, 1,214,201, 16,180, 43,224, 64,132,120,163, 39, 92, 79, 8,209, 0, 63, 15, 21, +206,204,207, 28, 4, 86,201,234, 91,181,118, 14, 19, 60, 25,237,198, 93, 71,229,170, 22,142, 21,226,173, 14,185,217, 35,215, 87, +240,126, 49, 10,224,113, 38, 30, 7,219, 24,172, 23, 1, 98,110,146,188,166, 98, 41,108,165,152, 31,189,127,152, 57,121,125, 68, +186, 64,120,161,163,123,237, 0, 57, 83,202,163, 76,174,215,244,100, 7,168,164, 21,175, 45, 51,212, 37, 79,133,247,223,207,172, + 68,109, 44,234,237, 88,197,243, 22,199,163, 86, 21,214,217, 36, 4, 81,174,156, 22,132, 45,225, 71,102, 65, 33, 4,248,104, 66, + 62,125, 8, 95, 43,112, 18,225, 51, 5,190,191, 67,255, 56, 51,125,111,135, 70,157,103,157,243, 16, 72,246,163,122,171, 2, 61, +243, 52,144,104, 22,212,150, 57,102,126,121, 92, 4,246, 58, 2,109,177, 96,123,187, 60,239, 40,213, 24,241,245,125,144,182,147, + 47,251,129, 40,245,235,148,217, 43,223, 88,211,138,223,224,186, 48,142, 23,113, 94, 65,220,148,162, 46,246,145, 58,234,246,231, +114,186, 52, 69,168, 73,107, 50, 22, 52, 6, 98, 74,243, 8,201, 24, 13, 54, 73,180, 28,246, 68,233, 35,162,153, 48, 88,216, 83, +156, 11,251, 82, 24,163, 79, 91,234,208, 88,125, 95, 30,103,135, 65,217,243, 93, 47,226, 68,239, 86,181,217,183, 59,217,177,168, + 65,133,148, 50, 43,215, 43, 60, 68, 53, 83, 52, 52,194,155,138,180, 30, 17, 85, 70,205,140, 26, 40,253,218,154,131, 90, 44, 66, + 50,142, 61, 54,202, 13,165, 64,153,102,120,149,250, 78,151, 82, 76, 92,133,144,243, 56,115,171,107, 49, 85, 45,179,112,109,137, +240,253, 16,112,183,180, 81, 91,203,161, 37,212,174,189,233,152,107,120,141, 92, 78, 93,155,197,143,186, 76, 44,184,188,159,183, +247, 34,137,176, 90,175, 33, 36,166,113,240, 34, 84,201,119, 31, 22, 21,199,156, 64, 86,156,146,182,183,175,175,163,119,137, 6, +154, 89,245, 72,136, 76,195,206, 56,234, 33,144,199,113,206, 46,159,111,234,122, 76,168, 7,179,146,253, 62, 40, 86,208, 87, 43, + 99,221,187,221,176,134,203, 80,218, 57,216,211, 60,118,117, 37,105,113,230,124, 8, 1,141,117, 54,226,138,247, 57, 1,168,198, + 77,215,207,201,225, 82, 98,235, 86,149,110, 78, 13, 69,148, 24, 3, 49,245, 75,178, 91,158,236,240,221,120,247,139,195,105,172, + 55,205,164, 18, 3, 90, 44,127,184, 4,231, 66,123,199, 30, 84,152,234, 3,207,223,172, 89,150, 95,253,142,193,253,195,106,230, +123,213, 72,206, 16,181, 48,170,141,221,234,232, 33, 20,171,145,235, 40, 28,196,192, 65, 40, 28, 38,165, 67, 89,171,113,169,196, +247, 32, 98, 71, 63, 0, 0, 32, 0, 73, 68, 65, 84, 17,117,175, 20, 74, 33,102,135, 55,156, 9,225, 78, 71,248, 97,135,252,239, + 32,215,238,193, 39,255, 8,174,255, 17, 92, 87,228,165, 14, 94,125, 14,110,190, 12,135,191,102, 60,249,240,188, 39,203, 37, 43, +250,235, 27,208,127, 10, 14,223, 66,174,253,115,184,253, 39, 70,199, 27,183,118,165,118, 9,210,202,115, 84,207,208,211, 45,188, +157,225,110, 68, 30,138,241,206,119,178,204,115,235,174,114,106, 18, 89,166,198,198, 80, 47,254,149, 35, 82, 87,174,204, 63, 12, +232,145,121,252,103,100,234,177,255,245,176, 67,250,171,166, 43, 72, 31,177, 86,189,170,166,202,133,237,203,203,153,179,246, 11, +132, 91,144, 62, 7,195,159, 65,126, 8,225, 19,160,175, 27, 55,255,174, 82,190,127,206,244,254, 5,103, 5, 78, 85,216, 78, 14, +228,243, 44,156, 50, 25,181,183,143,152,142, 96,182,111, 20,214, 2,171,103, 18,225, 51,107,228,181, 53, 28,116,200,189,193,230, +162, 43, 8,189,176,246,177,237,144,173,144,154, 37, 9,114, 46,230, 86, 84,216, 37, 56,212, 98, 63,242, 22, 19,153, 29,216, 75, +144,126, 36,220,236,137, 63,222, 65,150,217,164, 48,168,165,104,209, 32, 74, 69,160, 36,216, 5, 88,223,155,144,195, 68,124,182, + 71, 62,218,145, 56,224,248,219, 27,244,126, 38, 39, 99, 19, 73,150,153,165, 31,171, 23, 56, 7, 36, 40,125, 92,198,170, 18, 27, + 78,193,222, 67, 38, 88,142,119,130,243,108,239,205,201,249,132,156, 14,116,119,109, 77,194, 42,193, 43, 7,240,147, 71,240, 87, + 23,240,153, 3,244,206,192,248,229,115,244, 89, 95, 10, 95, 84, 28,234, 50, 95,107,159,105,161, 17, 90,181,236, 2,105,188,192, + 21, 0, 39,205,181,101,197,210,193, 7,109,182,118, 19,108,210,166, 98,105, 51, 10,176,125,161,167,105, 53, 86,162, 82,187,214, +218,217, 21, 32, 22,202,232,232,229,169, 32,197, 12,239,218, 20,115,145,253, 20,183, 42, 37, 11,165, 85, 52,219,142, 56, 54,114, +106,117,133,251,232,130,184,145, 70, 37, 23, 18,218,217,115,104,202,117,135, 47, 22, 66, 69, 68, 53,144,198, 45,157,102, 43,206, +237,250,162,174, 14,230, 17,123, 29,191,107,131, 44,185,148,149,217,172,205,140,200,230,227, 85, 89, 2, 30,231, 2, 92,173,112, +158,250, 50,205,225, 76, 58,251,254, 53, 38, 86, 34,196, 82, 24, 52, 27,217, 12, 5, 57,176, 46, 50, 79, 11,107,189,235,136, 39, + 55,172,176,108,206,208,237,214, 70, 37,117,205, 16, 2,185,136,251,219,179, 9,122,163,146, 99,164,196, 30,213, 97, 1,185, 52, +188,250, 57, 6,185,233,206, 67, 93, 21, 72,141,212, 21,211, 73,201,178,126,144,214,245,123, 41, 76,165, 85,201,163,234,201,128, +245,144, 80,199,204, 54, 34,238,251, 53,177, 91, 49,148, 50, 35, 89, 89,230, 29, 79, 37, 97, 70, 26,186,159,234, 30,133, 77, 36, +122,138, 25,196, 24, 89,117,189,121,210,243, 68,158, 76, 56, 51,150, 98,144,153,108,212,184,122, 3,205,234,125,167,200, 21,191, +206, 82, 8,196,212,249, 26, 89,153,138,241,224, 43,205,173,213,121, 32,173,192,209,199,102,213,146,230, 10, 87,165,248, 33,112, + 57,220,168, 51,244,115,201, 75,160, 83,187, 94, 40,217, 5,133, 29, 37,218,164, 64,167,201, 2,105, 58, 83,185,171,136, 9,121, + 93,143,176,172, 44,202,162,182, 47,153, 84,219,145, 82,187,147, 58,114,172,185,196, 13, 13, 77, 84,233, 28,196,210, 38, 56, 91, +174,236,228,162,136,142,162,194, 46,143, 78, 71,178,145, 88, 93,215,173,130, 61,168,143,114,225, 56, 10,185,192, 65, 20,203,164, +214,224,249,193,101, 62, 92,168, 70,186,169,176, 26, 71, 82, 20,244, 8,242,129, 18,186, 68, 24, 58,228,251, 7,232, 7, 35,229, +189, 29, 12, 59,194,141, 55,144,159,120, 11,254,222,159, 34, 63,125, 2,207,127, 12,142,127, 21,186,207, 67,120,198,232, 42, 56, +158,246,248,215,225,224, 63,130,233,212,109,114,163,101,198,167,107,134,166, 45,143,144,107, 95,134,231,190, 4,159,120, 7,125, +114, 97,168,220,236, 94,215,154,141, 93,124,247, 49, 86,168,127,244, 89, 96, 66,164, 44,102,216,222, 21,115, 49, 65, 95,153,152, + 62,251, 77,226,193, 26, 29,228, 53,156, 95, 88,235,187,254,121, 3,243,200, 19,251, 57,203,153, 85, 69,221,185,186,125, 13,233, + 19, 48,189, 5,155, 63,131,254,103,140, 28,167,239,161,247, 7,248,238,150,233,238,134,237, 38,243, 40, 8,231, 91, 35,184,106, +150, 25,215,185, 43, 86,208,241,169, 88,196, 14, 95, 69, 3,199,100,116, 27,144, 28, 23, 21,146, 5,131,219,235,247,220,249,177, + 30, 18, 10,156, 15,176, 43, 38,152,236, 93,188, 84,218,124,130,173,167,211, 4,177,223,112,210, 19,158,235,232, 86, 22, 77,216, + 39,179,131,159, 95, 24, 20,169,243,183, 45, 68,123,240, 15, 25, 70, 31,155,234, 54,163,143, 50,225,181, 21,241, 39, 15,144,152, + 56,249,230, 25,250, 96, 66, 69, 56,171,249,129,137,153, 10,168, 98,187,222,232,226,166, 32, 6,174, 9, 77,220,165, 52, 33,154, +248, 41,216,241, 61,164, 65, 9, 15, 7, 83,182,175, 34,114, 16,209,131,128,124,100, 13,175,172,225,157, 29,242,239, 28, 33,255, +167,117,145,210, 21, 52,137, 39, 3,250,251, 80, 22,122,153, 40,104, 84,226, 36, 51,142,184,137,181,110, 73,198, 76,126, 15,149, +204,252,222,207,221, 64,190, 36,120, 43,151, 30,142,181,197,217,115,244, 52, 44, 87, 31,242,206, 45, 91, 21,131,105, 65,166,134, +214,230, 28,118, 90, 86,184,239,168,231, 26, 25, 92,164,231, 95, 39,214,209,119, 12, 30, 65,106, 45,179, 56, 9,174,184, 35,187, +119, 12,236,136,233, 91, 68,237,223, 79, 49,146,177, 73, 82, 41,217,210,217, 98, 32,249,153,169,111,152,239, 89, 13, 54, 82, 26, +149,246,194,221,119,193,158,191, 93,213,111,220,202,197,130, 86,220,169, 94, 2,221, 44, 19,143,250,185,197,176, 64,129,212, 21, +227, 69, 11,108,207,209, 16,221, 59, 29, 73,177,179,243,126,183,140,128,139, 19,234,138, 39,126,201, 48, 80, 54,103,196,245, 49, +101,117,108, 87,219,230,204, 94,175,216, 94,213,114,183, 11,185, 12, 22, 40,162,246,122,136, 61, 26, 59,131, 65,185, 70,160,204, +130,185,198,126,230,175, 53, 87,178, 89, 61,122,105, 67, 9,110, 69,152,232, 94, 0,139, 74,104,116,255,141, 66, 59, 52,113,170, +179,141, 77,232,186, 21,253,122,141, 6,241, 36, 52, 43,166,218,232, 42,158,202,110,173, 2,185, 82,156,179, 94,173,151,139,253, +174, 82,227,186, 85,111, 7, 66, 15,132, 81, 17,198,113, 36,103, 87,220,214,105,211,124,168,113,237,212, 12, 45,183,180,180,144, +162,127, 46, 94,208,125,154, 48, 67,119,116, 57, 16,171, 79,110,184,196,114,159,189,246,132,185, 27, 23,191,230, 67,116,144, 80, + 30, 80,151,154,154, 78,193, 52,105, 85,252,166, 51,227, 2, 98,234,172, 75, 15, 97, 33, 52, 58, 50, 87, 36, 88,106,158,235, 79, + 74,206,115, 4,113,138, 30, 72,145, 51,108,199,194,182,216, 8,222,186, 0,102,225, 72,168,105, 79, 30,176, 16, 93,249, 74,201, +110, 17,139, 20,133,190, 79, 4,141,140, 27,101, 44,153,186, 41,170, 34,141,169, 40, 35,197, 70,169, 2, 57, 8,121,178,209,255, + 81, 18,186,100, 98, 49,123,130,217, 60, 55, 28, 69, 79, 78, 10, 14,157, 73,246, 32, 61, 12,112, 8,220, 78,200,185,119,207, 41, +217,213,249,197,130,126, 97, 7, 71, 95,135,231,191, 14,159, 16,228,213, 53, 28, 31,195,122,237,124,215, 99,232, 79,160,191, 5, +233, 21,232, 62, 9,221, 21, 72, 87, 92,129,255,140,141,238,251,191, 3,235, 31, 35, 55,223,128,252, 30,228, 45,232,128,144, 23, + 34,158, 15, 79, 69,182, 32,131,181,160,165,238,114,234, 5, 22,102,106, 20, 83, 54,156,237,198, 44,127, 70,103,115, 21,221,238, +255,167,235,221, 98,109,203,210,251,174,223, 55,198,152,115,174,125, 57,183, 58,117,239,174,238,118,119,187,219, 54, 77,219,177, +163, 36, 68,113, 68, 98, 19,130,148, 60, 32, 2,146,133,184, 8, 9,161, 32, 33, 4, 88, 8,241,128,242,196, 59, 32,241,130, 16, +138, 20,204, 67, 0, 33, 8, 82, 2,137,130,131, 37,156,142,113,140,237,166,239,238, 91, 85,117,117,213,185,238,203, 90,107,206, + 57,198,248,120,248,190, 49,231, 92,187,154,150,142,186,251,212,169,179,247, 94,107,174, 49,190,203,255,255,251, 63,129,233, 57, +242,199,127,213,125,230, 31, 88,193, 81,247,118,153,215,131,119,233,201, 58,249,154, 97,255,119, 64, 46,173,107,215,111,194,248, + 2,222,171,148,111, 31,200, 63, 62,242,162, 40, 47,179,112,200, 22, 61, 31,150,247, 84,137,222, 5, 73,176, 6,188,197, 77,118, + 64, 39,129,240, 48, 33,103,193,100,228, 31, 29,169,223, 58,146,255,104,100,254,225,204,109,132,253, 12, 71,159,196,198, 8, 23, +189,185, 13,115,241, 31, 93,160, 70, 89, 94, 2,223,245,216, 31,246,223, 11,143,122,239, 22, 12,114,115, 57,192,163, 12, 79, 71, +219,171,231,128,233, 0, 20,138,243, 88,135, 51,232,174, 11,241, 73, 33,124, 2,228,245,158,240,165, 68, 55, 85,238,253,254,158, +114,157, 41,157, 29, 52,199, 54, 80,217,238,178, 67, 19, 96,233, 50, 14, 94, 60,205, 34,167,227, 62,255, 76, 28,139, 23, 25,199, + 74,120, 49, 33,103,137,244, 94,132, 20,236, 98,127,109,176,215,233, 50,144,254,108, 37,255,239, 47,145,215, 65,250,106, 76,251, +122, 26,118, 17, 60,189,164,206,246, 58,116,237,194,150, 19, 11,237,210, 41,213,226,216,129, 40, 72,169,166,253,208, 59, 84,186, +147,237,103,221,228, 88,175, 56,217, 69,248, 67,155,105,111, 71, 2,178, 97,210,235,250,251,106,221,135,212,181, 67, 89,214,168, + 42,196,160,107,124,176,174, 48, 23,113,113, 34,149,197, 57,162,110,194,182,241,173,137, 69, 37, 84,134,100,218,157,118, 14,217, +247,215, 56,105,118,184,205,213,206,133,164, 74,212, 74,143, 46,106,245,217, 59,254,122,167,171,172,170, 76,181,122,238, 66,203, +115,223,164,223,169, 46, 74,253,229,215, 18, 20,104,175, 65,110,161, 42,186,138, 93,219,235, 88,253, 66, 47, 77,139,147,109,222, + 89,163, 59,136, 82,180,166,167, 6,170,199,126,134,197,238,230, 96,153,170,228,253, 53,189, 42, 12,231, 72, 76, 72,215,163,135, + 91,170,102,170, 68,123, 33, 99, 34, 12,103,232, 60,219, 8, 57, 23,168, 19, 53, 68,155,108,108,138, 23,105, 35, 32,116,137,147, +173, 63, 65,149,221,152, 0,193,233, 72,210,246,205, 13, 72,163,235,101, 27, 54, 41,150,237,217, 10, 75, 58,158,137,183,162, 4, + 98, 55,208, 13, 3, 33, 38,198,108,157,180,120,193,161,101, 21,152, 44,206, 13,109,223,115, 88, 38, 46, 13,214,228, 8,248, 5, +150,100,130,182, 30, 77,137,105,154,236,117,148,192, 92, 50,101,158,109,181, 81,170,137,235, 54, 72, 92,221, 96, 12,131, 64,138, +137,152, 58, 23,214,153, 96,174,117,219, 39,101,221,118,159,237,235,172, 32,186,174,118, 54, 41,109, 34, 66,149,232,145,223,234, +137,130,174, 92, 79, 59,106, 42,246,231, 66, 36,196,224, 4,193, 74,205,198, 55, 8, 49, 34, 77,125,175, 74,206,197, 39, 1,246, +169, 12,209,179, 0,156,149, 95,171, 17,231,162, 8, 97, 56, 35,229,106,118, 13,149, 96, 35,200, 90,233,124,127,165, 45,234, 83, +214, 56, 68,169,129,144,172,210,108, 63, 96,108, 10,207, 32,132,110,176,221,210, 56,115,116,196, 93, 16,243,180,207, 42, 36,205, + 4,133,189,143, 88, 74,182, 70,247,178, 6,204,114, 44,156, 11,244,157,165,129,233,101, 66, 30,236,208, 65, 32,216,155, 36,231, +189,167,130,121,213, 60,184,118,255, 38, 91, 39,125,168,214,142, 22,224,105, 71,252, 97, 64,190,209,161,159, 15,240,240,104, 54, +184,177, 66,254, 49, 92,249, 73,253, 90, 68, 62,135,137,158,222,122, 19,206,238, 91,196,172,244,118,129,206, 71, 63,248, 58, 59, + 85,195,153,135,208,236,124,190,117,180,246,102,206,232,126,143,236,175,205,236, 45,193, 47,113,151, 85, 87, 59,121,116, 95,236, +251,172, 30, 86,210,139, 5,154, 68,129,239, 30,224, 79,191, 10,151,127, 2,230, 31,122,190,124,177, 40,218, 58,217,197, 46,172, + 17,184,227, 87, 96,124, 9,247,126, 17,184, 5,253, 33,250,116, 66,191,115,164,124,112,224,230, 86,121,166,129,253,108,251,192, +236,135,217,208, 0, 38, 98, 62, 97,153,221,250,218, 0, 59, 10, 41, 6,194,227,132, 60,238,236, 95,120, 94,169,207, 50,249,233, +204, 62, 87, 94,102,235,204, 75, 59, 25,252, 71,142,254,247, 84,255,224, 22, 86,196, 46, 55,126,250, 62, 22,184,181,165,183, 60, + 48,111,168, 76, 21,233, 97,232,225, 85, 87,188, 30,102,181,177,163, 23, 31, 45, 87, 62, 6, 19,228, 61,248,250,145,112, 30,137, + 15, 58,228,149, 68,248,249, 11,186,163,114,255,171,123,242,177, 90,224,139,152,210, 63,248,158,119, 59,102, 95,156, 10,178, 73, +145, 58,101,128, 44,159,235, 42,112,244,196,188,238, 54, 19,158, 79,200, 46, 18,207, 45,242, 86,135,132,188,115,134,254,224, 22, +126,225,156,240,245, 35,245,199,123, 99,220, 15, 66, 56,110, 14,214,176,233,216,189,232, 24,156, 19, 51, 42, 39,225, 33,213,221, + 37,217,104,199,164,168,222,137,182,236,128, 37,208,215,179, 11,182,180, 16, 87,177, 47,191,181,166,173, 84,255, 92,171,132, 83, +139,146,239, 70,181,165, 82,149,214,197,213, 69, 64, 37,226,148, 65, 93, 39,145, 49,232, 18,164,104, 77,191, 44,219,235,224,234, +229,172,186, 6,164, 86, 59,107, 26,118, 53,169, 57, 66, 6, 10, 41, 4,195, 52,251,159,151,176, 58, 75, 16,232,180,218,216,221, + 69,113,147,218,133, 94,100,221, 41, 27,190,214,252,245,145,192,188, 88,197, 86,204,109, 92,176,170,237, 82,210,147, 12,243,232, +254,117, 9, 86,148,196, 77, 39,187, 4,162,196,132,226,226,184, 82,125,132,236, 1, 37,197, 59, 64,173, 72,181,208,141, 26, 58, + 66,151,176,102,219,160, 35, 18,173, 59,173,227,222,153, 26,137, 20, 19, 12, 3,117, 60, 90,199,158, 11, 85,102, 36,117,132,212, +129,118,212,108,151,154, 53, 5,137, 24, 59,223,233,250,165, 18, 76,175,100, 5, 85, 65,213, 46,233, 37,145, 82,215,212,175,234, + 43,207,181, 99,151, 37, 12,163,234,221,100,239,187,197,129,141,222,219, 56, 59,165,142, 16,123, 38,167,185,209, 24, 7, 14, 96, +161, 5,205,184, 18,156, 37,166,212, 39, 23, 65,238,176, 28,154,155, 34,210,197,142,216,245,182,247, 46, 54,162,202,192, 60,205, + 94,228,172,147,132,186,201, 34,208,205, 52, 46,132,104,254,249,152,236, 57, 41,229, 14, 5,174,126, 92,144, 80, 55,188,252, 13, + 97, 78, 54, 43,131,208,188,234,162, 11,114, 57, 0,187,126, 48, 97,121,173,116,201, 96, 49, 99, 45, 28,166,145, 50,142, 14,189, +113,198, 65,215, 45, 69, 74,174,166,226,215, 90,156, 56,106,161, 47,185, 20,242,116, 68,170, 18, 37,216,212, 34, 37, 82,242, 61, + 66,212,194,121, 4,145,196,160,133,169,216, 11, 33, 46, 46,201, 62,126,145, 32, 20, 73, 84,169, 11, 53,202,192,133,182,223,203, +125,100,154, 10,211, 92,104, 5, 67,169, 48, 23, 37, 72,229, 92,108,135,129, 7,173,133, 98,190,236,131, 79,117, 45,197, 72,184, +168, 74, 31,148,184, 87,139,184, 44,222,229, 14,246,193,209, 32, 75, 26,132,238,149,250, 66,169,199, 64,157, 50, 76,147,137,104, + 34,132, 93, 68,207,123,226,107,129,240,112,103,221,252,177,218, 92,247, 38, 83, 63,152,209, 39, 5,190, 94,145,223,141,200,195, + 61,132,175,195,179,201, 78,188, 93,180,121,103,136,200, 89, 7, 15, 2,124, 50,193,219,157,159, 46, 56,197, 78,225, 70,224, 71, + 25,158, 9,122, 13, 60, 10,240,122, 92, 85,155, 13, 85,151,196, 4, 98,183,110,200,153, 10, 92,249,102,224,137,130,142,200,151, +126, 5,202, 45,148, 23,158, 45,127,176, 75, 93,111,253,239,115, 1, 96,253, 8,230,119,161,123,211,126, 79,191,142,222,188,128, +239,102,234, 31,237,153, 94, 78, 60, 15,112, 61, 25,100,166, 20,139,189,204,108,172, 81, 69,204,218,222,146,182, 16, 82, 80, 6, +133,238,126, 36,188,218, 27, 1, 39, 11,245, 42, 83,158,204,228,219,204,173, 26, 87,125,159,173, 88,104,147, 91, 41,107,199,219, + 59, 75, 97,241,102,103, 63, 69,167,138,244,209,170,226,164,200,189, 72,188,215,209,189,200,164,170,140,213, 44, 96,187, 4, 53, + 8,251,227, 74, 85, 44,197, 10,193,171,201,182, 21,114,149,121,248,213, 3,114, 63, 18,126,225, 18,121, 99, 32,126, 25,250, 27, +229,225,119,247,212,162, 92, 1, 7, 17, 39,202,157,100,165, 16, 88,106, 68, 31,175,174, 76,240,120, 39, 0, 72, 93,188,116, 84, +232, 50,214,173,239, 2,210, 7,194, 16,224,222, 17, 62,115,137,124, 98,135,190,156, 8,127,225, 62,241,191,158, 96,151,221,116, +111,185,228,155,245,243,230,114, 48,109,195,208, 40,133,171,190,103, 25,249, 90, 97,161, 39,252,244, 59,167,237,154, 64,184,137, + 29, 19, 86, 20,106, 46, 91,229,173,189,206,167, 35,119, 57, 9,150, 17,223,187,139, 10,162, 1, 77, 66,210,178,184, 38, 40,117, +241,131, 47, 26, 32,100, 9, 41,218, 42,203,181,165,134, 45,113,158,235, 48,183, 20,124, 82, 35, 72,138, 4, 85, 82, 45,118, 54, + 86, 83, 35,119, 18,108,100, 25,212,249, 9,149, 36,202,173,130,207,206, 78,134,185,230, 97,111,113,183,186, 92,202,141, 11, 81, +165, 69, 28,183, 97,133, 46,187,249,246, 60, 71,239,202,113,151, 95,216,108, 44,172,153, 73, 62,114, 45, 70, 21,243, 73, 87, 43, + 32, 45, 90,180, 50,249,206,190, 11, 21,173, 35,185, 36,159,134,219,154, 51, 68,199, 91,215,130,206, 35,117,151,168, 2, 93,215, +219, 69, 55,103,114, 41,134, 14,157, 70, 66,204,132,212,147,186,193, 5,124,246,208,212, 50,251,207,100, 78,129, 20, 2, 85, 12, + 35,172,165, 16, 81,119, 40,201, 42, 6,245, 11,253,132, 98,232,107, 8,245,243, 95, 54,197,207,106,199,112, 17, 97, 35,244,133, + 72, 12, 61,161,235,144,216, 83,180,146, 75, 89,162, 99, 43,117, 51,122,111,104,216,182,191,174,104, 72, 75, 17,215, 16,179,150, + 79, 94, 23, 56, 76,138,137,212,119, 16,133, 60,102, 11,101, 17,131,204,148,121,242,142,185,110,188,255,107,112,202,154,198,102, +190,242, 16,147,209, 36,107,246,148, 56,255,190,234, 70,212,162,219,156,144, 85, 28,217,170,254,224,250,129,182,222,169,181, 16, + 98, 34,164, 14, 81,216,197,200,253,251,247,144,110, 96,154, 38, 74,173,204,170,148, 60, 49,231, 66,153, 51, 81,108, 45, 91,169, +148,108, 1, 62, 49,217,106, 32,249,190,188,106, 37, 16,208, 16,188,179,159, 77,232, 60,236, 8, 93, 34, 87,101, 60, 28, 72,103, +154, 73, 49,114,214, 65, 41,202, 49, 22,139, 24, 45,190,191,114, 49,213, 81,125, 21, 90,149,218, 71,178, 4, 68,103, 84,133, 33, + 24, 26, 83,231,130, 20, 72,233,140, 24,111, 57, 23,245, 61, 88,165, 6, 56, 19,229,204, 61,185, 81,108,212,154,130,125,160, 26, +184,100,170,166,156,190, 81, 97,168,112, 62, 41,195, 97,166, 83, 37, 14,160, 15, 88,103,161,213,104, 28,122, 93,201, 7,101, 76, + 1, 21, 37,244,129, 46,122,108, 67, 12,118, 74,158,187, 89,118,244, 98, 32, 84,106, 84,116, 7,245, 21, 19, 2,113, 25, 76,189, +254, 12,244,104,102, 15,153,252, 65,232, 33, 12,138,148, 64,232,147, 77,191,251, 96,151,249, 92,225,170,160, 79,170,157,198,103, + 98, 13,254,212,153,167,171,110, 20,197,183, 10,151,222,114, 30,109, 70,173, 30,251, 41, 47,129,111,140,240,239,189, 1,195,167, + 97,255,129, 95,230, 51,212,209, 60,248, 76, 38,209, 15,175, 64,184, 7,183,191, 9,211, 75,184,252, 83,160, 63, 66,231, 31,194, + 7, 25,253,214,145,242,254,129,155, 12, 47,171, 48,218,121,195, 84,151, 4,223,165, 19, 45,155, 14,181,177,162,135, 0,103, 10, +241,161,199,142,122,252,153, 62, 49,206,251,177, 8,147,192,232,253, 77, 81,187,172, 60,216,207,238,136, 96,250,207,157,172,246, + 40,252,245,180,150, 41,192,224, 2,204, 7, 61,225,237,129, 97,154,185,189,205,220,102, 27,195, 86, 3,198, 49, 58, 16,170,115, +156,255,236, 31,176,235, 0, 93, 23,232,159,102,228,247,142,244,247, 58,228, 11,103,200, 39,122,210, 47, 94, 48, 28, 42, 15,222, + 59,154,128, 73, 12, 65,154,235,218, 1,167, 53, 55,229,164, 51,113, 30,132,141, 88,239, 28,116,234, 59,246, 3,144, 70,219,175, +203, 16,237, 87, 23,209,157, 32,239, 60, 66,138,160,159,129,240,103,238, 81,127,235, 37,242, 72, 33, 7,100,170, 54,170,222,100, +137,107, 93, 55, 53, 49,194,176,137, 24, 61, 73,103,243,248,209, 37,116,124,129, 92,164,211, 97,106, 27,157,120,229, 18,217,116, +246, 85, 79, 76,110,178,165,172, 53,122,218,242,255,195,186, 50,113,129, 85,148,202,224, 48, 21,203,241, 86, 36, 52,120,145,120, + 84,100,195,160,174,214, 31,226, 70,168,231, 54,170, 22, 13, 26,124, 50,100,182,159, 0, 69, 73,126, 25,196, 54, 2,199, 58,224, +157, 27,187, 67,206,156, 73,165,136,145,232, 50,171,216,173,141,198,131, 26,146,182,222, 65,165,136, 95,236, 81, 54, 89,230,178, +138,234,216,224, 99,131,172,100,191,197,219,173, 44,172,247,186,132, 90,215,165,219, 87,169,174, 36,151, 69,127,144,117,229, 62, + 12, 1, 83,103,235,186, 94,137,213, 61,212,162, 84,157, 45, 42, 54, 68, 66,133, 97,119, 78, 77,133,227, 60, 34,206, 50,215,106, + 88,238,160,213, 0, 40, 33, 57,134, 86, 23,236,109,140,105, 65,222, 74, 8, 22,108, 85, 11,193,195,119,216,234, 10,228, 84,192, +185,237,146,131,216,243, 19,116, 77, 12, 83, 9,171,114, 94,162,237,133,131, 5,181,132,216,249,229,104, 41,117, 21,239,130,203, +230, 66,119,253, 84, 91,234,139,248,216, 61,207, 70, 77,107, 19, 51, 87, 99,218,235, 31,232, 59,183,176, 21, 37,231,188, 52, 35, +243, 60,129,110, 80,171, 34,190,191, 95,217,235,226, 46,171, 16,147,217,237, 98,240, 46,120,237,191, 91,110,124,115, 18,168,224, +168,241,184,136,219,194,170,100,217,192,130,236, 12, 61,239,122,206,207, 47, 8, 41,129, 42,187,174,163,219,237,184,158, 38, 14, + 57, 51,205, 19,243, 60, 51,231, 12, 57, 47, 59,247,230,188,176, 58,185, 56, 16, 52,210,133, 72, 28,118, 75, 94,122, 6,234, 52, + 50,132, 72,127,126,142,246, 3,251,227,145,227,237, 21,121, 28, 73,247,165,144,212, 62, 60,115,176, 17,121, 86,165, 68, 33, 19, + 32,218,135,245,166, 40, 47,139, 85,249,147,135,193,207,193,132, 42, 69, 33, 82,173, 59,158, 71,226,249,125, 46,206,118,212, 82, +108,151, 50, 91,135,126,233,190,245,234, 56,189,132, 44, 73, 71,147,218,225, 16, 16,166, 42,116,106,168,212, 89, 34,247, 66, 34, + 74,161,237,255,169,213, 46,230, 93,183,158,178,157, 11, 18,212, 41, 67,168, 69, 23,166, 72,184,223, 17, 30,196,133,239,222,210, +180, 24,128,135, 54,230,210, 92,208, 23, 51,229, 69, 70,231,106,115,192, 24, 8, 93, 48,241,252, 25,232, 99,129, 71, 98,176,154, + 25,184, 26,209,155,138,126, 56,163, 71,181,244,178,123, 29,225, 97,176, 19,111, 44,200, 21,107,200,112,241, 54,175,141, 37,230, + 66,125,153,209,209,124, 97,225, 3, 37,124, 54,194,151,127, 30,142, 87,144,111,188, 18, 24,237, 82,215,217, 78,189,152,160,251, +164,117,241,227,247,253,146,239, 97,254, 14,124,116,128,111, 78,148,111, 31, 56,222,204,188,116,225,218,177,192, 92,215, 28,226, + 70,245,138,209,212,189,169,241,230,253,215,160,102, 45,147,203,132, 92,118,118, 88,238,161, 94, 21,242, 77,101, 18, 49, 72,203, + 98,225, 20, 74, 59, 36,106,165, 74, 32,121, 16, 78, 39,246,126,196,212, 22,246,109, 73, 29, 44,156, 39,221,192, 43,129,240,169, + 68,124, 47,210,213, 98,121, 3,115,195, 30,194,121, 7,215, 94,148,132,141, 45, 44,136,112, 19,220,180,240,193,145,240,187,145, +116,158,144,119,122,228,157,129,244,229,202,110, 84, 30,124, 52,217,197, 30,173,174,219,118,201,203, 1, 16,100,109,153,101,131, +254,188,147, 42,169, 62,205, 40,246,206,144,110, 10,242, 98, 38,116,126,176,221, 75,232,195, 91,228,254, 99, 36, 62,133, 95,189, + 71,252,135,123,184, 81,116, 23,168, 59, 69,167, 53, 41,203,101,249, 39,221,118, 23, 45,246,119,210,211, 38, 58,108,114,202, 79, +149,250,121, 99,199, 88, 11,145,213, 66,237,226, 52,221, 50, 26, 87,119, 6,213,231,218,245, 39, 68,101,121,196,231, 22,185,186, + 11, 91, 37,248,218,217,108, 7, 82,186,217, 0, 44,246,101,133, 16, 43, 90, 44,221,173,253,153,234, 0,148, 66, 64, 84, 8,222, +253,203,182,252, 16, 67, 54, 95,116,173,211,183, 68,171,189,174, 98,220, 37,161,178,145,224,196,214,137, 56,136, 40,159,136,251, +172,139, 23, 2,157, 88, 26, 99, 27,217,139,174,221,185,178, 30, 57,181,217,183, 60, 72, 67, 92,100,105, 1, 45,234,239, 64,117, +120,146, 80,125,212,189, 20, 50, 21,102,207,119, 24,188,151,208,101,108,219,178,100, 3, 90, 10,146, 71,164, 63, 71,131, 9,185, +134,152, 80, 44, 99, 67, 84,140,150, 86,138, 65, 82,202,228,108,245,176,174, 41,162, 77, 88,230,227,100, 26,202,152,252, 11, 5, + 19,234,233,102, 97,125, 34, 12,213, 77, 0,143,108,162, 86, 29,162, 83, 27, 48,200,226, 97, 67, 76,254,111, 6,231,145, 71,143, +252,245,253,184, 83, 56, 75, 46,182, 38,104,232,217, 86, 96,106,181,233, 71, 23,169,217, 60,251, 18,172, 35,181,101,122, 93, 24, + 18, 11, 28, 38, 6,202, 56,217, 62,217, 71,209,117,206, 62,206,175,190, 82, 98,237,250,217, 16,232, 98, 48,113, 92,140,214, 89, +107,221, 68,208,110,199,244,226, 48,173,136,196,184, 38, 24,214,109,145,184,134, 35,197, 20, 57, 31,118,220,191,184, 36,118,157, + 23, 60,129, 26, 19,207, 14, 7,174,110,110, 25,199,163,237,156,155,215, 60, 69, 74,173, 76,227,209,206,200,216, 17,186,110, 89, + 83,132,109,108,107,203, 90,207,217,113,187,145, 57, 4, 14, 55, 87, 76,251,189, 71, 3, 67,186,223, 53, 69,189,146,188, 18,110, + 69,126,145, 98,163,143, 40,156,163,220, 19,225, 16,148,105, 80,142, 53,112, 28,179,225, 11, 43,196,208, 89, 10, 79, 85,130, 22, +186, 24,152,242, 68, 71,129,104,147,229,179, 8,179,151,127, 70,251, 82,180, 90,230,118,231,251,176,200, 42,242, 40,130, 9, 6, + 58,251, 97,232,234, 26, 47,185,235,224, 44, 89,121,191, 87, 66,174,244,101,178,197, 94,159,144, 92,145,162, 72, 19, 47, 61, 76, +182,187,174,117, 25,167, 72,239,158,210, 51,129,235,136, 30,142, 86, 8, 4, 1,177, 7, 43, 92,118,200,131,132,184,221, 76,231, +140,238, 21,189, 42,232,211,140, 30,124,192,248, 48, 32,143, 58,120, 45,192, 78,208,235, 10,123,108,196,124,230,153,239,197,243, + 86,247,118,250,105, 1, 61,216, 56, 74,178,192,139, 10,191,254, 25,224, 21,152, 95,216, 37, 46, 25,242,232, 72,220, 98,187,252, +248,134,141,218,143,255, 0,174, 95,192, 43,159, 3, 62,128,155, 23,240,157, 76,253,218,158,249,201,129,171,201,226,230, 75,105, + 89,189,235, 5,149,252, 12,239, 69, 40, 98,187,208,222,119,233, 22,247, 42,196, 62, 16, 94,237, 44, 66, 21,165,190,156,169,207, +179,141,143,196,189,227,109,116,186, 81,117,215, 24, 76,112, 23, 86,213,122,140,178,162, 31, 27, 98, 80, 34,240, 22,232, 75,228, +124,132, 55, 7,226,227,145,243,155,153,123,179,114,136, 54,181,153,171, 29,130,247, 59,184,153, 87,207, 58,213,104,115, 41,155, +122,127, 80, 37,254,224,136,252, 65, 36,222,143,200,163,142,240,133, 51,186, 91,133,223,171,232,203,153, 26,101, 73,200,107,187, +224,185,248, 7,243, 20,125,110,135,153,108,206, 21, 93,183,137,234, 2,153, 89, 77,233, 31,174, 39,194,185,165, 36,201,187, 9, + 94, 13, 6,238,223,125, 26, 57,255, 22,225, 95,187, 64,255,179,153,250, 86, 68,118,192,148,215,233, 94,105, 4, 41, 7,187, 84, + 27, 15,246,193, 62, 31,249,206,126, 93,151,148, 85,189, 99,241,221, 64, 49, 62,166,132,210, 69,214,108,219, 32,239, 40,117, 19, + 68,180, 32,189, 78,151,136, 90, 87,201, 80, 69,233,162, 9,190,212, 69, 69,232, 10,173, 89,194, 86,188,208,219, 2, 62,107, 86, +162, 47, 37,117,113,180,123,113,224, 23,140, 84,231,108, 55,160,138, 4, 39,194,217,175, 42, 74, 46,149, 94, 76,244, 54, 85, 56, +186,154,123,141, 10,117, 15,185,251,182,163,197, 4,120,126,185,189,247,139, 82,190,178, 56, 84,194,230, 53, 43, 62, 89,138,209, + 62,186,115, 11,180,145,200,236, 29,170,111,209, 9, 81, 72, 90,209,160, 11,100,170,250,131, 19,212, 60,246, 85, 54,238,172, 70, + 55, 12,230,163,111,113,187,165, 90, 16, 77, 46,222, 13, 78, 19,210, 13,132, 52,160, 33, 33, 90,232, 98, 36,207,147,123,155, 35, +210, 37,136,113, 21,135, 57,114, 48, 68, 43,254,141,123, 94,124, 29, 82,150, 56, 88,139,122,209, 37, 73,254, 84, 52, 39, 27,217, +219,122, 29,158,228,159, 72, 32,132,100,217, 26,186, 78,117,212,187,254,208,246,248, 40, 85,220, 10,233,223, 71, 27, 59, 45, 95, +165,130,116,209,237,224,237,235,234, 29,235,122,219,215, 71,250,174,183, 88,213,108,194,182,138,146,231,121,121,129,151,213,142, +171, 71, 23,200, 17, 45, 8, 37, 46,232,218,186, 86,142,171,213,110, 99, 53, 51,117,122, 92, 86, 0,237,239,194,119,254, 45,252, + 37, 70, 11,148, 73,169,115, 52, 65, 38,134,200, 49, 20,174,110,111,217,223,222,216,174,223,197,116, 33,218,251, 54,151,108,241, +179,197, 61,243,213, 86, 25,169, 23,162,116,166,154,175,149, 60,207,238, 54,146, 37, 66,247,118, 28, 25, 15, 7,234, 60, 45,254, +123, 17, 33, 37,130, 31, 88,149,168,106,202,203, 32,203, 62,170,248,135,182, 79, 66,170, 74, 95,172, 58, 63, 14, 61,251, 25, 38, +175,234,164, 15,104, 13,110,150, 55,196, 30,243, 68, 9, 22, 43, 56,136, 24,215,188,147,101, 47, 89, 16,106, 88, 67, 19,162,239, +180, 58,169, 12,213, 71, 99,231, 59, 87,147, 58,147, 60,138,181,101, 93,242, 79,106, 65,206, 35,177, 8,122,125, 52, 97,138, 70, +179,149, 5, 65, 30, 13,200, 59, 59,163, 36, 29, 42, 39,124, 66, 13, 32,197,254,206,203, 72,144, 1,121, 92,151,110, 77,186,128, +188, 18,145,251,166, 24,172, 31, 77,232,203,217, 46,245,209,253,244,247, 13, 38, 99, 94, 61, 27,171,215,131,192,222, 81,160,169, + 34, 93,112,159,142,127,114,179,218,218, 96,116, 27, 66, 47,240, 3, 69,126,177,135,207,254, 52,220,222,154, 32,142, 12,249, 96, +106,251,166, 64, 11,103,144,222,132,227,223,133,247,191,141, 78, 3,242,166,192,248,125,244,195,138,254, 96, 36,191,119,228,112, + 83,121,137,112,204,106,233,105,173, 32, 95, 1, 91,110,171, 88, 3, 28,108,108,105, 68,185,190, 64,119, 47, 33,175, 59, 22,246, + 80,225, 89, 70,111,138,121,209, 89,248, 8, 11,155,193,215, 66, 86, 20,248,230, 67,219,133,152, 86, 48, 13, 17,211, 42,196,100, +150, 60,122,216, 61,133,183,247,132,215, 7,250, 39, 19, 23, 47, 38, 6,177,172,243,105, 90,239, 36,113, 75,101,213, 53, 26,119, + 44,112, 59,155,103,190, 27, 11,241,155, 71, 43,198,254, 88,128,139,142,248,115,103,112, 44,156,125,109, 79,190,202, 75, 67,107, + 59,107,219,207, 22,189, 75,223, 58, 85,169,109,108,204,171,213,204,245,126, 33, 8,221, 94,137, 47,102,106, 23,145, 15, 39,228, +135, 17,125,253, 71,200,163, 63, 7,220, 71,126,249,155,132,223,219, 19,254,254, 1, 62, 19,169,103, 21,142,198,147,214, 98, 93, + 69,187,208, 93, 19, 68,236,132,110,182,139, 46,111, 78,184,186,193, 85,126,124,153,126,138,120, 93, 67, 90,196,135, 69, 13,253, +186,118,164,139,159,189, 52,199,154,218,229,220,198,222,245, 4,143,109,105, 85, 94,128,176, 92,168,235, 14,191, 29,124,213,213, +127, 90, 65,114, 93,121, 3,181, 41,134,117,179,247,182,231, 36, 44,186,123, 89, 28, 26, 22, 27,106,127,235,132, 85,147, 41, 42, +193, 71,145,121, 93,214, 47,108,238, 6, 78,105,100,192, 90, 79,147,222,178,158,178,219, 41, 75, 40,157,123,230,253,242, 85,187, +139,138, 4,183,149,217,235,150,212,222,119, 75,108,172, 20,255,203, 27,222,216,194, 61,236, 66, 79,205,109,232,120,233, 40,167, +233,114,213, 15,105, 91, 35,136,115,218, 65, 74, 38, 78, 19, 33, 14, 22, 33,234, 62,237, 24, 34,101, 26, 77, 56,215, 50,161,187, +100,168,235, 90,150,213,135,230, 66,205,121,157,203,108, 39, 6,109,236, 46, 97, 9, 2,218, 22,181,117,219,183,183,128, 23,115, +178, 59,127, 60, 25, 53, 79, 45, 97,143,208,138, 49, 35,170, 25, 73,206, 59,104, 79, 39,115, 37,182,147,221,116,241,129, 75,244, + 46,116,154, 86, 37,253,162,184,247,207, 93, 85,179,120,117, 29, 69,132,113,154, 55, 23,185, 46, 28, 21, 90,240,139,132,211,120, + 94, 23,175, 53,251,152,169,221,117, 25,255, 47,118,181,229, 51, 97, 85,158, 46, 1, 48,155, 88, 88, 17,251,123,220,206, 29, 61, + 41, 47, 5, 11,175,169, 34,140,121,102,158,247, 76,165, 80,202,140,180, 4, 54,199,230,206,165, 80,219,186, 96,153,154, 52, 40, + 78,165,228,138,138,141, 38,139,255, 76,120, 12,108,174,133,105, 26,169,211, 4,181, 18,150,131,213, 83, 68,195,152,208, 82, 9, + 85,156, 0,101,214, 48, 5,106,168,134,134,213,134,206,244, 39,176, 20,186,243,196,174,235, 72,197, 46, 69,213, 76,150, 64,191, +235, 41, 65,232,181,208, 7, 27,105, 73, 48, 42,153, 0,169,197, 57,122,151,158, 55,163,224, 22,127, 73,123, 44,165, 67,134, 51, +228,184, 55,156, 98, 3,169, 15,131,221, 28,209, 80,172, 60, 8, 72,202,118, 84,185,162, 72,187,136,220,235, 9, 63,117,102,135, +220, 17,187,236,131,213,232,198, 20, 87,191,157, 76, 40, 38,175,247,107,254,250,253, 96, 93,126, 48, 23,173,126, 48,219,197, 92, + 4, 46, 20,238,153,141, 79,162,237, 14,234,161, 34,135,201, 70,246, 23, 62, 65, 8,174,108, 45, 98,130,132,169,174,126,170, 32, +118,217,139,129, 1,228,165, 34,255,210, 39,160, 94, 66,190,246, 55,224, 96,151,123,157,124,197,144, 44,165,174,124, 27, 62,250, + 38,250,141, 10, 95,126, 8,241, 37,250,209, 1,222,203,212,247, 70,202,237,200, 53,112,157,197, 59, 82,179,108,205,254, 97, 73, + 11,210,209,209,153,193,208,153, 45, 98,118, 0,118, 9,226,163,142,240,176, 55, 95,227,237, 76,125, 81,168, 83,101, 18, 28,130, +209, 44,246, 74,104, 0, 48,223, 13, 23, 63,231, 67,241, 76,122,245,203,189,108, 88,167,109,236, 39, 15, 32, 62,128,183,174, 8, + 63,125, 78,120, 58,114,126,152,185,172,202, 53,194,209,239, 40,241, 75,167,147,213, 91,219,169,173, 21,142, 5, 98,134,151, 9, +210,205,140,124,125, 79,255, 56, 34, 95, 56,131, 87,122,226,207, 92,210, 29,149,139,111,236,157,144,104,113,194,234,167,191,108, +156,183, 69, 87, 15,121,106, 69, 73,219,173, 53,225, 88,219,195,183,172,118,132,116, 91,144,243,153, 48,116,200,147, 10,207,110, +225,149,167,208,253, 37,232,190, 68,248, 55,254,123,194,223,251, 67,244,208, 33, 59, 19,205,233,180,138,204,234,221, 64,151, 2, + 93,244, 47,146, 27, 43,109, 67, 50,228, 99,121, 26,126, 80,182, 36,173,211, 63,113,194,232, 14, 62,185, 89,212,240,101, 3,249, + 88,185,227, 84, 57, 77, 29,116, 1,220, 26,116,177,218,156,138,114,199, 15,109, 63, 84,208,181,103,207, 91, 49,150,174,175,163, + 58,162, 54,251, 20,161,101,116, 71,183,154, 37, 87,191,183,159, 67,151,236,241,246,122,212, 13, 15, 94, 22,101,123,243, 24,207, +155,188,239,178,185,180, 54,132,224,213,246,180,233, 92,149,150,196,229,197,100, 41, 36,196,158, 11,132, 81, 5,157, 43,147,159, +145, 89,197,206, 80, 17, 7,244,216,103,174, 84, 22,164,234,150, 77,166,136,229,107, 96,128, 29,109,197,112, 43,218,188, 35, 52, +165,183, 18, 36,179,243,177,244, 56,207, 11,194, 52, 72,132,190, 51, 65, 97,206,238, 44,240,229,200, 38, 66, 85,182,188, 8,217, +128, 98,238,132, 4,109, 83,208, 44,209, 48, 44,144,154,144,210, 26, 68,228, 59,242,160, 38, 96,140,169,179,221,184, 8,115, 41, +140,243, 76,158, 70,247,214,215, 69,240,216, 62,104, 33, 8,244,189, 23, 31,171, 40,205, 10,206,234, 3,115, 75, 86,236,251,158, +216,155,154,126,154,102, 71,242,138, 49, 11,220,163,170, 57,175, 29, 64, 91, 47,137,119,220,206,124, 15, 33, 46, 48, 24,221,236, +224,106,243,150,139,239,252, 84, 54,150, 59,143, 60,197,252,153,109, 36,110, 26, 8, 97, 8,194,217,238,140, 28, 34, 55,227,200, + 52, 30,172,216,241,203, 95,162,189,118, 5,152,243,236,142, 5, 93, 53,184, 27,203, 96, 69,125,165,146,109, 4, 47, 6, 38,210, +220, 50,225,179,157,213,169,115,241,236, 54,171, 93, 73,242,231, 3,242, 52,192,147,100,203,198,138,161,245,230, 76, 61, 40, 53, +154, 82,122,210,150,188, 38,148, 98,172,217,185, 63,163,140, 7,179, 64,212, 66,223, 71, 66, 85,152, 71,170,147,150,196,167,219, +182,254,142,116, 81,136,234, 24,217,224,187,176, 16,172, 63,143,220, 0, 0, 32, 0, 73, 68, 65, 84,152, 84, 56,150, 74,214, 74, + 23,236,247,228,124, 71,236,122,226,237, 11, 95,222,218, 44, 76,187, 1, 57, 23, 68, 39,123,241,207, 34, 50, 84, 56,219,217, 15, + 54, 43, 66, 36,188,209, 35,175,245,254, 41,206,112, 17,209,210, 33,227,228,251,233, 22,150,110,249,166,114,105,114,109,149, 98, + 41, 56,179, 80,111,205,132, 93,159,101,171,234,206,253, 22, 60,100,116,159,151,169, 6,135,138, 78,106, 10,167,206, 25,208, 55, +138,220, 55,101, 44,147,117,238, 4, 65,179, 34,179, 34, 15, 2, 97,223,193, 31, 78,132,159,233,225,157,119,224,230,104, 35,137, + 90,237, 50, 47,163, 83,227, 58, 11,184, 9, 17,174,127, 31,253,110,133,235,132, 60, 78,176,127, 1, 31,205,232,251, 19,245,106, +102,174,166,143,200, 77,168, 83,237,210, 78,219, 76,233,134, 14,246, 66, 63,138, 29, 84,125,128, 65,148,212, 7,194, 27,157, 97, + 79, 85,109,250,127, 85, 40,199, 74,222,120, 51, 83,180,131, 42,103,150, 72, 89,201,141,254,102, 21,232, 92, 44, 44, 38,119,172, +105, 88, 85, 86,153,154, 36,208, 55,145,139, 39,232,167, 50,241,123, 59,250,167, 51, 23,243, 72, 95,109,106,112, 88,224, 78,171, +162,167, 29,216, 30, 69,204, 88,132,235, 0, 59,148,238,233, 68,248,131, 61,221, 89, 7,159, 78,240, 86, 71,204,231,244,183, 10, +239, 29,144,169,176, 15,107, 8,143, 21,175,174,120,175, 27,160,217, 73, 96,138,156,164, 81,137,223, 26, 85, 97,138,208,205, 74, +188, 45,212,243,140,220,102,228, 22,208,143,140,125,208,125, 30,222,122,139,240,107,255, 62,250,223,222,194,207, 38, 35,180, 29, + 42, 57,183,253,235,170,118,223, 66, 93, 6,177,209,252,220,146,189,234,157,192,150,192,194,180, 61,193,190,254, 36,252,166,167, + 46,182,220,162,182,207, 44, 62, 54, 21,223,109,223,197, 97,110,215, 18,150,165, 46, 75,236,235, 6,127,115, 2,159, 49, 58,164, + 15,119,253,114, 54,122,156,250,200, 93, 28,122,181,118,236,139,210, 88,194,162, 36, 95,173,242,118,168,246,254,231,230,170, 76, + 85, 40,190, 19,173,122, 39,232,165,178,229,161, 46, 5, 69,217,118,160, 77,216, 25,214, 11,173,180,247, 58,250,238, 72,155,207, +219,173, 94,193,236,113,147,194, 88, 42,217, 3,176,114,179,104, 57,146,205,239, 36, 99, 53,180, 68, 52,245,239, 95,130, 11,197, +132, 89,124,188, 95,219,254,222, 5,167,209, 51, 49,170,249,154,205, 52,148,172,187, 78, 25,205,213,163, 93, 87,177, 89, 8,137, + 48,116,238,106,169,126, 49,182, 66, 84,209,208,118,197,193,131, 86,100,249,122, 43, 70,214,254,121, 11, 27, 65,130, 79,250, 92, +208,165, 74,205,117,141,153, 77,182, 87,143, 41,217, 36, 13,152, 75, 49,165,247, 52,218, 69, 94,171,231,139, 87,247,129,251,192, +172,235,237,253,119, 81,100,187,216,150,139,212,239,231, 46,245, 12,195, 14, 66,100, 30,109, 74, 33,209, 21,231,117,182,239,211, +211, 53, 55, 50, 96,179,197,185,125, 13, 49, 13, 0, 14, 14,211,141, 57,109, 83,197, 45,222,214,214,241,171,200,114,226,180,255, + 21,163, 1, 96, 68, 96,151, 18,195,238,140, 41, 4,174,111,175,169,243, 76,148, 96, 40, 96, 47, 17,171, 4, 74,201,228,226,190, +114, 79,124,195, 67, 93, 8,193,190,108, 12, 27, 82,156,117,231,179, 86,166,155,107,202,120, 68,106,117, 77, 64,178,245, 71, 12, + 14, 4,210,101,133,150,194,127,244, 6,204,123,216,223,160, 31,102,248,221, 11,248, 63, 59,120,119, 34,228,137,110, 63, 26,138, + 50, 86,166, 16,184, 21,203, 74,215,121,166, 74, 71, 14,137, 58,103,186, 24,169,177, 67,166,105,121,177,178, 38,227, 94, 43,164, + 82, 9,169, 50, 96,251,167, 40, 32, 73, 40, 33, 80,106, 37,182,180,162,222, 71, 79, 53,210,237, 6,250,121,164,203,217,121,186, + 9,238,157,193,189,206, 72,100,231,103, 72,159, 45,212, 96, 82,120,212, 59,201,202, 78, 99,217, 5,179,139,197,100,251,119,173, +182, 5, 75, 59,100, 31,144,161,160, 23,238,113, 74, 88, 18,219,117,134,155, 74,185,202,112,116,142,187,248, 40,221,253,148,122, + 44,102,163,107,106,197,132, 93,246,131,239, 18,198, 66,185,205, 72,141,132,183, 58,240, 8, 82, 28,154, 98,164, 23, 59, 96,195, + 89,130,144,145,127,253, 19, 80,238,155, 56, 78,171,217,215,202,108,197, 7, 45, 93,229, 77,235,183,175,247,240, 61, 53,107,221, +160,232,143,103,248, 81, 70,127, 52, 81,110,103,227,186,155,110,143, 17,155,190,132,118, 99,232,234,201, 78, 54,245, 50,123, 79, +187,220, 3,116, 5,186,243, 72,120,173,131,157,183,201, 79,103,234,209,187,202, 96, 69, 75,112, 27,210,178,131,212,187,233, 86, +126,104,139, 43,225,179,154,160,112,242,253,139, 84, 83,246,235,193,120,253,225, 53,120,188, 39,188,181, 35,188,123,228,252,122, +226,126, 54, 93,225, 81, 78,119,180,114, 71,188, 86,212,132,123, 83,128,171, 32,116,185, 18, 62,152, 8, 95,187, 37,158, 9,188, +181, 67,222,222,145,126,193,235,130, 15,143,200, 33,115, 76, 54,205,136, 97,221,142,212,176, 65,183,202,102,191,168, 39, 13,204, +199, 46,188, 18,160,238, 51,117, 95,136,185,192, 62, 65,126,110,175,123,247, 26,200,125,194, 95,249,139,232,255,250, 55,209, 23, +230, 91,215, 98, 22,206,188,181,216,137,251,165, 27,229,207,217,250,169, 42, 83,222,172, 49,218,250,187,222,233,142, 27, 99,122, + 51,126, 80, 62, 14,147,183, 67, 95, 92, 21,191,134,175,148,176,109,242,117, 81,114,181,215, 60, 87,159,232,213,109,215,189,190, +102, 77, 45,215,184, 4,205, 51, 95, 89,215,122, 45, 52,165, 46,157,241, 93,125,128, 3,173, 48,166, 58,190,167, 77, 94,232, 76, +165, 50,185, 60,165, 16, 9,162,116,161, 82,171,186, 15,126, 19, 12,162,235,183,216,194,129,182,239, 99,227, 19, 76, 77,112,231, + 35,210,165,106, 68,137,181, 34,161,105, 6,132, 89,132,169,218,247,209,178,230, 23,207,122, 93, 71,181, 13,151,159, 17,170, 8, +157, 88,160, 80,221,168,186,181,182,181,139, 3,108,157,120,102,117,141, 17,206, 12,230, 99,223,108, 37, 64,234,145,100, 80,147, +128, 43,184, 53,155, 39,218, 71,229, 75, 64,149,119,151,161,133, 1,249,104,186,170,175, 53, 54,249,231, 77, 24,183, 92,236,222, + 0, 68, 49,176, 77, 3,142, 5,223, 51, 75,176,241, 51, 33, 81,197,246,197, 69, 33,231,153, 60, 79, 80,243,130, 48, 93,119, 56, +130,148,130,164,100,148, 60,103,128,200, 73,218, 81, 88, 70,241, 73, 2,195,176, 35, 14, 61,199, 92,200,121, 38, 4,219,215,235, + 60,155,142, 43, 37,234, 56,218, 62, 60,218,121, 41, 77,119,224, 48,155,232,239,107,169, 45, 29, 45,218,179,181, 88, 26,101,137, +222, 93, 32, 5,219,108,244,118,161, 7,103,178, 32, 12, 41, 17,186,142,155,156, 57, 28, 15,224,104, 87,137,209, 83,250, 10, 37, + 59, 30,214,167, 17, 18,215,231, 90,189,112,176,232,214,206,128, 67,110, 91, 45,185, 50,229,137, 50,142,148,146,237, 30, 86,161, +150, 66,150, 98,144, 51, 57, 77,198, 11, 64,226,193,111, 26, 56,165,190,135,188,249,159,195,103,254, 30,252,177, 9,190, 61, 32, + 95,191, 64,190,115, 78,250,104,102,120, 54,115,185, 31,185,159, 11,207,146,114,211, 23, 74,151,208,216,145,210,206, 59, 22,179, + 99,148, 90,201,146, 40,209, 84, 90, 85,102, 38, 81, 58,181,125,131,198,134,218, 19, 68, 51,177, 88,114, 91,223,153, 40, 33, 6, + 65, 14, 19,253,229, 64, 87, 38,122,177, 86, 95, 46,206,145,221,206, 60,206, 82,140,253,156, 3,114,123, 64, 59,123, 72, 92,253, +101, 7, 74,209,149,136, 82,163,237,159,230, 10, 41,161, 15, 6, 27, 29, 93,143,232, 7,123,235,186,167,140,142,149,122,171,246, + 6, 84, 19,204,145, 2,225,194, 2, 39,202,213,108, 7,211,130, 35,179, 17,101, 80,108,122,208, 69,187,244, 71,251, 59,234,211, +137,240,102, 66, 30, 69,120,233,115,192,217, 31,215,234, 30,248,127,177,131,207,188, 3,123,167,211,213,217, 58,116, 29,157,177, +217, 65,234,161,255, 50,148,223,131,169, 32,207, 20,254,244,206,138,150,167, 51,250,124,164,220,204,228, 99,177, 45,129,159, 73, + 73, 76,140, 83,155,224, 40,216,222, 50,134,213,122,214,162, 31,131,119,234,157, 96,138,247,123,201, 94,131,171, 66,125, 62, 83, +246,133, 41,251, 78,178,200,178,119, 92, 15, 79, 59, 72, 75,221,144, 30,117,211, 77,183, 25,237,114,177, 31,237,245, 45,183, 16, +118,160, 15,225,242, 3,120, 59, 19,238,247,244,221,145,243, 99,161,235, 44, 55,160,212,230,180,216, 40,184,155,237,164, 29,218, + 5,142, 1,110,147, 48,236, 11,225,253, 3,242,176, 39,156, 39,120,144,144,207, 12,116,163,243,170, 63,130, 48, 22, 38,191,216, +131,216,248,183,137,232, 66, 16, 82, 16, 75,223,219,142,141,221,222,180, 37, 69,182, 93,106, 41, 16,143,217,224, 71, 55,189, 65, +129,242, 55,129, 47, 26,180,232,209, 63, 71,248,245,255,131,250,215,158, 89,246, 80, 88,193, 45, 86,114,110,152,156,117,213,175, +137,191, 95,125, 88,117,202,101,227,183, 95, 92, 85,156, 70,188,173,223,183, 95,116,133,213, 67,231,174,208,149, 60, 23,169,193, + 10,211,192,202,133, 95, 44, 65,155,113,100,105,169,101,117,189,247, 91, 33, 39,185,145,181, 60,168,198,119,226,213, 47,219,186, + 20,129,250, 19,139,164,101,197, 32,178, 8,238,106, 27,138,251,251, 61, 58,230,193, 87,245, 4,132,206, 59,183,105, 73,118, 51, + 78,122,254,216,110,245,227, 49,181,230,217, 14,248, 18,111,243, 26, 42, 9, 93,236,123,206,141,244,208,159,122, 2,161, 41,205, + 23, 93, 54,187,224, 38,249,242, 53,100, 64, 93, 3,176,186, 40, 52, 8, 73, 2,153, 96, 17,160,178, 38,159,213,106,211, 75,235, +194,237, 97,201,190,126,144, 54, 98, 14, 98,163, 48, 23, 88,202,202, 39,181,188,245, 90,214, 78, 83,130,167, 72,174,130, 79,196, +199,224, 33, 46,113,170,108,166, 53, 65, 44,102,184,233,180, 36,246,246, 62,214, 21, 41,216,210,246,170, 4,230,121, 98,158, 39, +239,208,213, 3, 82,140,254,103, 49,163, 38, 20,211,152,124,175,172, 39,122,149,101, 22,231, 98,206,174, 55, 50,157,198,200,124, + 56,218,186,184,235,200,174,254,151,198, 2,152,103,223,119,219, 97, 22,155,171, 69, 65,106, 65,186,206, 59,251, 66, 12, 22,149, + 90,169, 86, 68,181,168, 87,239,108,108, 66, 32, 43,163,221, 9,112, 54,149,240, 85, 67, 8,212, 24,217, 79, 35,101,158, 22, 33, +158,196,232,133, 77,166,228,201, 5,114,155, 41, 37,235, 24,201,196,127,137,110, 24,144,126,160,148,194,148, 39,230,105, 50,207, +125,201,110,163,147,211,216,228, 45,143,162, 37, 44,250, 89,156,136, 59,224, 30,240, 42,196,255, 18, 30,252, 16,249,242,223,129, +159,251,159,225,159,121, 23, 94,222,194, 7, 17,249,127, 7,194, 87, 47,121,229,247,247, 60,248,241,145,219,219,145,167,103,145, +151,231,231,148,148, 12, 8,147,122,251,248,141, 35,104,101,154, 45, 90, 48, 71, 53,152,134, 31, 21, 83,181, 75, 37, 69, 19, 42, +149,224, 10,108,236,197,175, 83,165, 83, 69,135, 1,158, 31,153, 52, 64, 55, 64,183, 67, 94,102,226,152, 9,181, 32,146, 9,211, +104,240,146,115, 80,153,225, 92,144, 55,122, 52, 5, 36, 76, 54,206,232,173, 75,151,108,187,118, 8,232,141,162, 31,102,234,187, + 35,243,213, 76, 61,102, 51,253, 91, 0, 51,210,131, 68, 27, 77, 74,173,212,234, 7,154,143,181,151, 64, 7, 31, 71,114,163,132, + 2,225,205,206,148,242, 25,234,143,103,202,251, 19, 97,215, 17,191, 28, 76,129,127,163,200,220, 66, 97, 34,188, 3,242, 39,223, +128,124,223,118,233,181,218,101, 87, 71,155, 99,203,224, 51,187, 47, 65,255, 69, 56,252,109,120, 89,224,162,131, 55, 7,184,154, +145, 39, 25,125,154,169,215,153, 50, 25, 29,174, 41,124, 61,209,150,226,137,123, 65, 44,246,213,138,126, 37,185, 48, 46, 5,207, + 77, 23,232, 37, 16, 31,154, 53, 11, 5,189,206,212,103,133,114,240, 4, 52, 87,164,235,162, 8,150, 53,132,196, 59, 62,241,139, + 60,250,101,210, 58,249, 50, 41, 58, 42, 50,123,142,183, 96,220,253,250, 4,226,219, 72,255, 0,125,109, 36,188,217, 19,223,235, + 56,223, 23, 46, 10, 28, 61,121, 77, 54,130,182, 46, 8, 26,117,201, 1, 87,177,130, 99,246, 3,255, 44, 40,233,101, 37,124,255, + 64,191, 19,248,210, 37,114,127,128,207, 7,186,217, 23,184,207,143,132,177, 18,211,218,177, 53,203, 92,240,177, 91, 12, 45, 45, +107,205,239,145,141,141,187, 93,172,110, 85,166, 30, 42,229,118, 38,125, 56,160, 31, 78,200,197,223,130,248, 73, 24,190, 0,115, +143,124,233, 83,200,163, 23,232,143, 39,100,103, 54, 45,241, 48,165,150,134,189, 44,125,151,221,116,181,194, 75,238,112,244,117, +147,154,229,157, 82,235, 60,150,162, 64, 86,187, 14,117, 19,238, 34,156,192,105,116,177,116,121,184,146, 3, 74,244,174,225,169, +229, 90,215,182,115, 85,138, 46, 81,110,158,251,108,239,111,192,226, 52,139,174,113,146,170,119,109,115,178, 57,175, 90,191,212, +246, 3, 77,205,111,234,229,193,247, 19,147, 23,121,109, 39,154,125,218, 96, 25,236,235,197, 89,221,251, 92, 89, 95, 63,217,236, +206,219, 89, 89, 8, 11,114,247, 36,217, 66, 21,159,220, 26,132,178,138,235, 82,170,191, 30,234,154, 32, 49, 16, 77,169,203, 8, + 62,122,204,111,241, 28,139,224,133,109,241,244, 74, 75, 59, 50, 91,110,168,153,144,231, 37, 30, 88,154,189, 82,140,117, 63, 78, + 6, 26,145,104,239, 9, 33, 17,130, 41,167,181, 89,190,100,179, 8, 49, 68, 29,177,235, 61, 93,175,248,206,216,157, 56,110, 71, + 19, 54,158,205,102, 33,107,115,142,170, 11,217,206, 46,110,123, 40,151,240, 16,116, 29,107,187,232,121,158,102,230,105,180,251, +192,199,237, 91,241,157,180,226, 36, 37,202,220,192, 49,110, 21, 91,132,188,222,240,133, 64,215,117,244,253, 64,232, 59,142, 57, +147,231,217,186,218, 16,208, 89,109,245,219,245, 6,228,241,137,174,249,245,173,144,180, 26,182, 24,122,188,165,190,121, 65,169, +234,152,229,166,149, 73,209, 4,123, 13, 34,227, 1, 80, 1, 83,221,199,174,183, 2, 10, 37,249,250, 98,156,103,131,192, 56,120, + 71, 60,198,120,158,103,242, 60, 90,227,184, 20,169, 97,227,172, 49, 28,108,140,137,216, 15,182,130,158, 38,166,227,129,121, 58, +218, 26, 65,218,132, 76, 78, 48,208,252, 68,190,196,106,255, 76,242,225,159,128,123, 95,128,238,179, 16,223, 66,229, 13, 8,191, + 4,225, 87,161, 87,228,193, 15,224, 19,127, 11,190,244,219,112,245, 28,253,214, 5,241,127, 59,231,254, 63,158, 57,127,145,120, + 92, 18, 55, 73,216,239, 6,198,190,163, 28,143,148, 58, 19,242,100,111,172,216, 88,201, 66, 20,140,232,149, 69,136, 18,173,163, +204,133, 73,205, 82, 39,126, 1,132,169,112,126,121,193,144,206,209,253, 51, 36, 14,132,112, 15, 61, 84,166, 81,169, 7,165, 79, +129,238,246, 64, 55, 30, 56, 79, 66, 26, 18, 81,133, 24, 10,225,195, 9,162,169,214,229,237,138,124,242, 12, 46,146, 29,120,199, +138, 94, 85,202,211, 76,253,254,129,195,213,145, 43, 9,148,110, 71,234, 33, 81,232, 37, 19, 45, 93,216,171, 88, 91,136, 73, 10, +132,251, 3,220, 90,199,154, 58,150, 28, 99,201,106,182,180,217,214, 10,225, 81,103,252,231,171, 66,254,222,209,168,125,159, 31, + 8,175,184, 12,252,104, 45,177,124,241, 12,238,189, 99, 70,114, 81, 23,197, 29, 13, 50,163,254,161, 79, 3, 12,127, 6,234,143, +225,240, 3,248,102,129, 79, 14,166,254,127,126,139,190,152,168, 55,153,114,156, 25,139,217, 6,219,126, 46,184,192, 40,109, 46, +159,118,113, 5,223,163,167, 32,116,161,218,255, 86, 8,187,128,220,235,221,107,175,150,122,118,147,201, 69, 77, 36,215,118,161, +106, 32,148,176,209, 87, 45,143, 92,109, 51, 18,161, 95, 38,106, 62, 82,174, 78,213,205, 25,210,193, 14,154,239,127, 3, 62,247, + 16,194, 99,184,124,134,188,209, 17,239,119,156,189, 24, 57,175,112, 83, 76,108, 52, 97,187,212,182,251,236,116, 69, 73, 46,121, + 37, 30, 29,124, 91, 97,151, 11,241,106, 38,127,127, 34, 61,152,224, 51,150, 29,192, 23,206,237, 98,255,142,194,139,153,144,179, +141,118, 13,118,215,226,182,236,188, 9, 38,248, 59,129,114,132,245,210,148,205, 69, 81, 34,212, 92,168, 87, 51,250,116, 66,190, +113,134, 94,124, 15,145,255, 10,230, 95,131,240, 0,250, 55, 8,127,225, 12,254,139, 35,241,211,174,206, 86,221,216,202,238,254, +167, 46, 4, 58,145, 21,152,115,162, 92, 63, 13,173,244,234, 62,178,196,180, 4,124,236,104,130, 39,238,140,188, 33,248, 72,189, + 46,138,246, 86, 64,157,100,160,123, 14,145, 44,186, 10, 79,227,162,154, 86,164,157, 93,101, 5,116,108, 25,246, 77,172, 28,219, +107,187,116, 67, 27,241, 88, 19,118,105,245,194, 74, 23, 11,230,174,237,211,117,189,208, 75, 53,198,211,194,199,103, 85, 44,175, +119,214, 38,176, 69, 88, 44,137, 34,107, 87, 42, 85, 23,186,156,184,111, 60,122,161,155,213, 92, 22, 89,149, 94, 42, 29,149,178, +241, 60,154,157,183,122,168,203, 10,180,105, 1,142,109, 29, 82,138,241, 52,250, 70,137, 43,153, 90,178, 91,248,100, 17, 4, 6, +177, 46, 80, 67,103,202,123,218, 14, 54,227,158, 37, 98, 10,148, 26, 29, 61, 26, 60, 25, 44,184,157, 78,168, 46, 98,147, 16,109, +207, 92,178,237,212, 67, 92,133, 95, 98,221,191, 46,194,200, 86,166,132,197, 43,174, 34,148,146,109,132, 92,117, 5, 85, 5, 79, + 15,115, 79,250, 60,102,166,241,136,214, 76, 45,142,111,221, 20,107, 11,197, 48,117,246,207,180, 56,211,221,139, 61,223, 53,203, + 18,150,147,232, 58, 19,199, 21, 96, 26,237,146, 76,187,222, 38, 76,213, 34, 83,107,223,145,247,123,175, 75,130, 79, 3, 32, 23, + 11,205,137,193, 20,249,101, 89,139,232, 34, 26, 53, 58,173, 39,241,165,232,238, 12,221, 20,178,129, 46, 70, 82, 99,177,187,112, +173, 8, 20, 87,223,199, 16,189,216, 10,228,134,117,157, 39, 23, 17,234,146, 64,103,231, 70, 88, 66, 39, 36,216, 10, 96, 42,133, +121,191,247,232,216,188,234, 26,126,146, 53,117, 51,210,210, 45, 85,114, 19,178,147,202, 47,127,141,240,137,175, 33, 95, 72,240, +115, 17,249,147, 3,188,125,142, 62,122, 0,221,231, 64,126, 5,228, 95,129,240, 87,225,236,219,200,227,191, 1,159,251, 26,250, +143,119,196,175, 92,112,249,245,204,249,115, 24,199,204,129, 61,199, 62,112,211,247, 4,157,157,225, 43, 12, 82, 25,164, 46,123, +233, 54, 82,202,197,132, 38,227,146, 71,108,135, 73, 42, 74,188,247, 10, 90, 59,142, 53, 18, 46, 31, 34, 50, 80,247, 7, 38,141, +148,144, 97,156, 97,154,185, 8,194, 69, 12,156,107,165, 11,137, 46, 36,250,155, 66,156, 15,196,151,145, 48, 59, 13,227, 97, 71, +221, 11,220, 84,244, 22,244,166,146, 75,101,127,185,227, 56, 43,181,206, 70, 22, 14,137,210, 91,186, 90,157, 51,177,181, 36,206, +108, 15, 40,177,183, 17,229, 33, 55, 88,139, 34, 73,136, 41,160, 89,225, 96,173, 93,120,188,131,203,153,242,193, 76,249,246,193, +108, 97,159, 30, 8,111, 12,240, 40, 34,143, 35,188,246, 10, 76,131,117,171, 57,175, 4, 57,205, 6,148, 9,201,194,102,244, 5, + 28,255, 71,120,118,133,126, 15,228, 47,247, 86, 8, 60,155,225,186, 82,246,153, 50,155, 10,187,141,146,183,108,243, 70, 66,146, + 85,139, 98, 58,160, 69, 32, 23,216, 73,101,168, 74,188,236,144, 55,147,157,188, 71, 69, 95, 22,244,214,172,108,217, 51,215,205, +230,100,251,216,237, 90, 71,188,149,213,184, 9, 24,241,139,183,110,119,189, 69,208, 89,145,238, 96, 99,214,255,103, 68, 30,125, + 23, 94,255, 60,114,126,134,190, 62, 19, 94, 31,232, 62, 24,185, 87,102,110,146,121,214, 75,216, 72,149, 55,177,144, 33,108,146, +192,144,101, 58, 48, 2,105,159, 9, 47, 39,226,247,142,112, 25,144, 55, 35,188, 50, 32, 63,171,164, 12,212, 35, 50, 9, 33, 87, + 56, 22, 66,217,140,182,195,186, 58,168,245, 52, 79, 90, 54,169, 86, 49,174,246,190, 82,149,112, 51, 17,158, 38,210,144,224,172, + 67,245, 91,200,107,255, 3,236,126, 13,244,179,132, 95,253, 3,226, 95,191,161,222,204,164, 11,239, 52,239, 36, 54, 75, 93, 69, + 60,218,118,232,213, 61,206,149,141,222,117,211,180,111,130, 48, 52,152, 7,120,233,218,117,133,206,212, 37,166,204, 21,222,146, +144,133,179,238,107,113, 49,210, 97,109,136, 54, 87,168,171,235,120,162, 4,230,160,230,131,174,167,249,237, 45, 49,107,123, 16, + 45, 7,229, 86,125,200, 42, 54, 92, 47,223,150,203,237, 62,240, 22,190,225,226,170,162,106,251, 96,214,189,252,228, 54,199,186, +233,245,215,194, 69, 61,160,101,197,213,202, 29,174,190,110,230,242,226, 33, 63, 17, 39, 24,218,199,192, 72,132, 33,218, 69, 31, + 33, 87, 11, 46,169,139, 48, 78, 79,173, 97,178,249,187,219,168, 61,117, 72,215, 33, 82,137,197,199,171, 45,254, 86,172,120,137, +254, 1,205, 93, 79,137,253,226,102, 56,177,164,210,242,187,157,104, 23,182,209,167, 38,158, 82, 49, 30,124,168,230, 52,145,212, +249,106, 33, 44, 19, 23, 33,248,106, 32, 26,132, 69, 51, 90,149, 89, 29, 37, 44, 45,215,188, 44, 83, 24, 17,199,102,167,184,136, + 2,231, 82,152,199,131, 39,232, 21,143,148,245,120,215, 38, 8, 83,247,163,151, 12,185, 88,183,141,241, 58, 44,148, 68,151, 91, + 74, 82, 36,245,157,197,142,118,137,113, 46,204,243, 76,151, 34,221,112,198,205,225, 96, 13,202,176,227, 56,155, 32, 47,248,133, +169, 33, 88, 65, 83,138, 17, 16, 99, 90, 43,254,150,190, 38, 44,151,110,155, 24, 46, 84,101,145, 69,195, 16,188,176,153,107,117, +251,157, 21,197,154,243,210,157, 35,230, 92,152, 91,192, 78,105,197,207, 50, 66, 91,246,221, 49, 69,170,123,207, 75, 41,148,105, + 50,198, 64,206,139,117, 72,183, 46,146, 45, 77,242,206,133,126, 2,196,218, 8, 85,227,191,124,214,253,181,253,135,194,248,213, + 74,254, 7, 21,253,155,153,240, 55, 70,248,219, 55,132, 63,252, 33,114,241, 91,112,254,191, 64,255,155,144,246,144,190, 12,231, + 63,134,199, 19,250,250, 61,244,205, 14,121,116, 78,247,226,150,179,195,200,133,118,236, 36,209,213, 66,212, 66, 39,149,115,102, +118,193, 60,155, 65,203,134,102,101, 97, 14, 83,179,198,248, 8,169,203,149,203,159,254, 34,212,217,146,125, 30, 63,164, 30,142, + 86,105,157, 13,132,156,153, 15,183,140,227,136, 6,167,210, 53,188,101, 12,212, 46, 49,135,200, 52,103,226,205, 12, 47, 50,250, +222, 4, 79, 38,180, 56,209, 36,155,177, 37,136, 61,104, 34,221,134,117,239,248,131, 46,185,183, 50, 34, 73,168, 53,112,123,176, + 74,173,195, 86,224, 22,174, 97, 84,169, 24,132,112,110,190,110,125,225, 73, 64,175,245, 11, 20,142, 99, 69, 62, 40,132, 93,135, +124,170,135,159,234,225,222, 39,236,123, 41,142,130,229, 22,230,201, 91,178, 1,226, 61,232, 94,129,233, 43,176,255, 54,124,173, +194,187,138,252,211,247,225,102, 66,127, 56,162, 31, 29, 41, 31,140,204,135,204,193,116,122,107, 46,247, 86,179,233,159,253,216, +118,232,126, 25,117,209,224, 45,231, 65, 57,139,145,254,237, 29,241,139,231,200,121, 66, 95,102,202,119,143,204, 79, 38, 14, 69, + 57, 98,107,252,169,220, 25,221,222,137,122,144,150,209,236, 54,144, 62,153,150,240, 60, 5,210,235, 59,194, 39,118,240, 40, 25, + 79,127, 62,194,255,125, 3,243, 1,249,236, 3,255, 91, 70,228,186,160, 79, 11,220,102, 70,207, 10,216,122,226,171,255, 44,166, + 94, 54, 1, 75, 39,226,187,240,166,236, 55, 58, 97, 44,237,176, 14,112, 30,225,178,243,220,122, 65, 70,204, 86,216,155,205, 43, +228, 6,131,193, 5, 49, 43, 30,180,110, 70,244,219, 32,152,200,218,125, 74,109, 35,122,227, 97, 75,142,182, 63,120,244, 17,114, +246, 24,194, 47,192,229,119,144,219,103,212,223, 25,225,210,109, 93, 91,173,192,146,131,173,167,203,198,205, 88, 88,183,222,121, + 95,178,159,144,230,116,165,214,217,153,180, 22, 59,117, 19,195, 41,193,118,128,181, 49,184,197,133, 91,126, 25,182, 65,115,101, + 13, 61,137, 81, 72, 98,182,163,166,230,109, 49,160,178,137, 42, 69,215,174,120,171, 75,216, 90,234,195,102, 52,111,227,124,241, +233,145, 65,144,186,205,115, 27,197, 40,112,163,174,107,129,236, 19,161,217, 11,170,178, 93, 79,248,247,211,254, 93,145,141,247, +184,129, 30, 37, 80, 52, 80,176, 14, 76,252,189, 77, 98,151, 58, 2,163, 10,179, 36, 52, 6,186, 32,164,100,244,187, 73,132,217, +247,180,219, 52,210,224,207,101,117,192,141,138,160,169,183, 15, 92,158,144, 50, 47,214, 46,189,251,249, 12, 54,206,183,149,165, +141,132, 99,240,113,121,136,214,141, 46, 22, 62, 89, 46,166,208, 28, 9, 62, 46,175, 62,122,246,212, 30,227,178,123,110, 56, 30, +186, 18, 83, 90,226, 98, 45,143,219,186,236,198, 39, 81, 86, 32, 74, 16, 83,124,135,212,209, 13, 59, 19,124,149, 74,174,153,121, +154,108,234, 80, 11, 90,102, 47,222,101,233,140, 5, 75,208, 84,112,251,154, 11, 41,131, 56, 47,189,158, 68, 1,119,253,192,217, +249, 5,221,238,140, 18, 2,227,241,136,214,194,249,238, 12,217, 13, 76,135, 91, 82,236, 24, 67,224,240,242, 5,226,188,117,137, +201,138, 16,143, 33,141,169, 35, 72,112, 77,199,170,111, 88, 29, 45, 94,244, 5, 7,210,176, 22, 46,203, 51,169, 77, 20,111,212, + 73,205,133,228, 54, 67, 21,152,181, 26,228,199,247,223,141, 9,176,157, 60,181,247, 86, 99,103,240,174,105, 34,143, 71,243,154, + 55,229,255,102,213,117,114,161,235, 54, 34,152,143, 29,186,119, 49, 61,233,183, 6, 56,219, 9,247, 68, 56, 87,184, 95, 42,151, +165,114,249,213,137,139,223,135,179,223,136,116, 15,247,132, 47,190, 64,254,249,111,193, 63,117,137,190,254, 0,118,103,200,107, + 9, 36,161,111, 2, 63,117, 6,239, 38,194,243,129,203, 31, 84,206,191,119,203,195,227,200, 94, 51,210,139,117, 60,162, 76,174, +200,156,189, 27,152, 49, 33,123,219, 97, 76,185, 48,164,142,238,141, 55, 56,252,224, 93,194,163,199, 48, 41,229, 56,154, 29, 32, +194,116, 56,144,143, 35, 85,101,209,157, 69,169,198, 53,158,179,193, 45, 98, 71, 25,206,152,242,204,238, 56,123,164,104, 50, 97, + 79,136,104, 12, 72, 10,236,114, 37,234,145,177, 31,152,217,185, 15,117, 66,234,178,168,179,195,172,219, 81, 66,101, 63, 39,142, +115,230,181,243,202,227,168,220, 28,108,151, 30,147, 32, 67,103,252,204,226,169, 89,123, 65,111, 33, 60,238,209,108, 62,119, 57, +239,221, 79, 89,145,123,151, 80,122,219,161,151, 17,244,165, 93,232, 57, 26,167,149,100, 49,176,249,143, 96,255, 61,248, 64,209, +111, 84,228,103,122, 83,243,127,255, 22, 14,230,117,174, 83,179, 70,173,193, 31, 91,212,105,220,220, 12,193,243,128,163,119,183, + 73,236, 82,239, 9,164,203, 68,124,189, 67,238,123, 95,116,101,182,171,130,154, 42,218,187, 88,217, 88,133,164,169,106,239, 76, +142,151, 29,102,216,252,163,246,185,137,234, 56,173, 3,204,217, 2,109,190, 53,195, 47,188, 15,175,188,137,220,127,129,190,221, + 19,223, 28, 24,158, 31,121,176,207,236, 59,155, 18,136, 31,148,113,233,252,214,226, 97,123,169,169,243,126,246, 64,154, 11,114, + 59, 35, 31, 77,164,206, 9, 57,175, 38,139,107,205,144,138, 82,158,143,112, 95, 16,157,145, 81, 41,162,139,122, 95, 93,121, 29, +116,229,180,155,237,104,211, 1,183, 51, 32,249,126,125, 46,148,219, 9,185,138,200,251, 59,120,179,192,131,223,129,244,167, 64, +254, 34,225,215,222, 35,253, 79,123,234,245, 76,119,223,161, 76,242, 19, 6,108, 46, 36,106, 29,116,101,195, 1,192,213,250,126, +249, 55, 74,158,129, 92, 92,237,189,128, 20,149, 26,124, 87, 88,183,170,112, 19,148,181, 75,166,182, 49,165, 10, 53,250,101,173, + 43,132,164, 74, 96,212, 66,170, 78,199,114, 33, 27,155, 68,182,197,239, 45, 56,146, 84,204,230,234, 26, 20, 81, 61, 25,187, 23, +239,234,140,151, 96, 34,164, 78, 3,209, 81,176,101, 97, 8,152,186, 93,151,140,116,219,135,151,230, 79,119,108,109, 92,214, 76, + 62,210,110,194,185, 77,119,223, 64, 63, 85,221,254,185, 28,246,234,194, 57, 43, 48,134, 40, 36, 17,131,237,108,172,121, 57, 8, +115,118, 87,135,199,249, 53,237, 88,243, 90, 55,200, 22, 24,214, 53, 22, 43,113, 74,104,234,110, 89, 96, 52,219, 40,207,162, 30, + 80, 82,143, 36, 31, 31,175, 33, 59,117, 17, 2,106,195,183, 53,209, 74, 16,148, 98,221,164,154,187, 65,156,160, 38,226,192,148, +100,227,248, 42, 88,183,216,246,242,186,146, 7, 91,118,250,106,177,180,142, 62, 4, 33,246,118,161,231,121, 54,149,187, 11,214, + 74,173,214,113,150,246, 76,110,166, 51, 41,217, 51,208, 58,248, 38,156,172, 80, 75,221,100, 24,120, 86,122, 63,208,167, 14, 73, +157,137,198,242, 76, 31, 2,221,217, 25,251,105, 34, 84,165,238, 18,135,171, 43,116,158,221,226,101,163,247,226,246,185,246,255, +115,219, 69,202,221,181,150,158, 88,213, 84,117, 97,111, 44,102,183,170, 14, 65,138,190,158,114,210,161, 7,184, 76, 37, 91, 2, + 93, 93, 71,100, 75,158,253, 70,241, 47, 98,207, 83, 29,143, 20, 95,185,232,182,112,186,139,118,102,227,187,228, 14,228, 81,185, +195,169, 56, 61,120, 83, 44, 48,162, 28,189, 34,254,192,197, 29, 23, 59,191,228,115,229,222,126,228,193,111, 31,185,248,191, 2, +187,179, 91,226, 63,121, 69,248, 87, 47,209,159,127,132,190,253, 8,189, 22,244,252, 1,124,186,194,225, 0, 63,170,132,223,191, +224,242,155,133,139,143,110,169,115, 65, 43,204, 81,152, 98, 37, 39,187,140, 83, 88,105, 82,165,218,161, 54,228, 66,119,255, 33, +250,240, 85,228, 71, 31, 65,223, 51,125,244, 1,211,113, 68, 83, 64,111,111, 40,135, 3, 69, 10,125, 39, 11,215,153, 12,218, 57, + 7,184, 66,208, 74, 37, 48,165,142, 46, 5,130,206, 22,231, 55, 77,208,117, 4, 49,251, 0,131,144,242,140,212,217, 24,248, 65, + 8,201, 44,104,246,154,187,192,166,228, 13,157, 42, 48,206,194,197,195,200,131, 7, 21,125,110,126, 80,233, 65,118,129,250, 36, + 55,101,154,165,126,160,200,121,103,241,160, 95,216,193,167, 6,248,116,132,238, 1,228, 9,116, 2,110,236, 98,159,226,218,170, +197, 11,208, 27, 24,223,135, 15, 3,188,155,225,122,134, 63,123,110,139,223, 27,171,104, 52,219,127,215,182,235,194,201, 86, 27, +117,116, 59,144, 9,206,170, 22, 76, 36,215, 58, 18, 49,144, 75,188,236,144,183, 7,203, 0,205,106, 57,239,179, 90,166,140,195, + 90, 90, 12, 98,139, 37,213,159,176, 6,222,142,249, 83,104, 93,172,156,206, 61,125, 88,174,207,179,217, 41,223, 8,240,213,151, +200,159,125, 8,195, 61,228,205, 76,248,116, 38,125, 52,114,241,254,158,251, 69,153, 35, 28,252,176,109,227,193,184,233,226,156, +254,184,156, 79,179,147, 41,227, 12,247,174, 51, 97,152,145,120, 36,246, 64,119,110, 62,252,183,123,194, 92,224, 91,192,149,141, +165, 19,153, 48, 87, 27,189,183,213,169,172,151,168,110, 88,236,225, 78,135, 29,218, 94,238, 88, 41,177, 16,110, 38, 98,223,193, +203, 8,211, 19,184, 60, 64,252, 37,120,237, 93,210,191,243, 27,148,255,244, 37,220,247, 11,174, 29, 40,245,227, 94,115,101, 19, +213, 26, 54, 99,185, 59, 5,213, 66, 79, 91,118,134,235, 31,169,158, 95,223,130, 75,140,127,190,170,115,219, 78,113,251,245, 84, + 54,142,204,106,201,138,133, 74, 9,234,240,186,181,227,180, 2, 65, 23, 56, 80,113,116,235, 18,146,177,249,118,215,128,185, 53, +159, 58,168,144,168,116, 42, 30,184,178, 22,111,217,157,144,213, 23, 44, 45, 36,165,104, 93, 5,125, 75,161,105,190,223,206,122, + 93, 8,155,120, 96,214,215, 36,251,246, 60,139,172, 61,115,144, 37,173, 48,110, 10,168, 45,160,101,150,192, 92, 12, 89,171, 75, + 97,228, 5,141,174, 5, 85,241, 76,132,198,170,239, 93, 64, 55, 59, 98,185, 77, 3, 82,155, 54,182,159,177,218,249,181, 20,230, +213, 11,178,205,164,115, 29,157, 55,117,189, 91,228, 84, 23,193,106,187, 80,196,149,243,165, 22,164, 40, 26, 13, 26, 97, 99,239, +108,175, 89,140,132,254,204, 41,147,141, 33, 80, 55,163,228,149, 65,158,115,161, 78,147,137,205, 74, 65,107, 70,107, 94,126,120, + 89, 86,126,178,140,172,107,201,235,110,185, 61, 3,165,249,215,213,221, 80, 66, 55,244,116, 67, 79,232,122, 99,164, 56,188,102, +119,118, 14,169, 99,186,185, 97, 2,198,171, 43,234,254,150,232, 22, 54,109,130,187, 86,117, 71,187,224,107, 45,238, 99,151, 83, + 8,132, 63, 8,182,174, 96, 41,108,218,132, 65,181,161,138,163, 23,101,149, 24, 3, 41, 36,106,136,140,243, 68,157,166,229, 25, + 22,183,204, 89,162,154, 46,145,186, 16, 60, 62, 53, 59, 89,111,187,255,145, 77, 65,115,183,230,144, 19,202,229,233, 34,125,251, + 27,119, 46,245,229, 60,168,202,232,202, 61,193,194, 51,130,171,189,207, 6,225,114,128,135,192,195,121,230,149,127, 52,242,224, + 31, 93,113,246,234, 71,196,191,124, 15,249, 23, 30,162,159,120,149, 58, 93, 34,207, 4,186, 35,188, 38,240, 37, 65,190, 54, 16, +159, 76,240,188, 16,159, 22,250,253,209,162, 88, 35, 28,130, 46,163,137,189,167,145,134,185,112,241,230, 91,196,183,223, 34,124, +243, 27, 76,251, 43,242,225,214, 0,145, 37, 65,153,232,165, 48,196,232,251, 54, 99,196,103, 31,177,198,206, 71,102,170, 46, 9, +154,137,146, 44,231,125,178,139, 93,231, 76,149,142, 16,171,137, 72,250,129, 64,161,159, 50,193,217,146,218, 8, 82,234,202, 46, +177,216,187, 33, 21,230, 16,153,107,101,190, 86,250,207,158,195, 91, 21,253,238,232, 73, 62,254, 33,235,212, 40,117,209,238,235, +120,191, 35,124, 98,128, 79, 15,240,185, 8,143, 31, 64, 57,179, 11, 93,247,118,161, 31,227,102,110, 58,152, 72,110,254,177, 49, +225,175, 20,125, 81,204,102,246,120,128,235,108, 59,122, 15,138,209, 90,151,131,190,113,204,131,172,137, 83,178, 29,233,184, 80, + 40, 96, 35,212, 20,161, 43, 74,220, 5,194,195, 14,121,165,183,155,248, 88, 96,175, 14,185,112,138,220,194,102,112, 25,148,119, + 95, 4, 54, 1, 28, 91,164,232,230, 87, 48, 37,180,164, 22, 79,230, 63,235, 71, 35,220, 22, 27,139,127, 43,195,103,158,192, 59, + 15,225,209, 25,124,166, 16,223, 63, 50, 60, 27,185, 63, 23, 14, 81,150,241,106, 59,200,219,238,115, 89, 45,202, 50,113,180,130, +113,118,189,225, 65,137,215, 51,165, 19,228,195, 64, 56,143,232, 39,119,200,101,132,119,206, 44,207,253, 91,178,100,239,176, 47, +200, 92,220,225,192, 73, 94,178,174,247,235, 58, 46,151,205, 47,127,108,116,172,232,141,194,195,106, 19,152,154, 65,158,194,217, +151,161,254, 21,228, 47,125,155,244,215,255, 46,122,101, 67,153,234, 80,149,117,220,177,225,122,182,139,120,115,161, 47,227,185, + 13,120, 69, 55, 93,109, 3,188, 44,235, 24,117, 95,180, 24, 28,165, 40,139,128,201,192, 72,156,176,217,173,128, 51, 27,149,248, +173, 88, 75,182, 93,186,108, 46,105,101,193,247, 54, 66, 86,241,174,127,205,178,118, 0,204, 9,235, 67, 87, 65,231,146, 2,135, +227, 85,133,206, 79,176,124, 23, 44,227,211,190,153, 53, 35, 94,253, 32, 79,209,236, 74, 73,103,162, 26, 21,179, 46, 29,145,219, +209,252,224,182,112,150,184,120,234, 67,114,123,170, 86, 43, 50,216, 68,148,182,233, 66, 16,230, 90,201, 89,151, 66,172, 52,180, +238, 86, 61,239, 26, 33,245,175, 23,177, 78, 87,100, 9,220, 90, 4,136, 45,237,172, 81,242,138, 43,246,163,239,132,107, 53,207, +186,116, 61,226,209,165,102, 63,247,224,147, 48, 19,139,159,167,218,168,124,237,162,171, 4,103, 93, 20,140, 49, 94,107,241,239, +177, 58,210, 54,152, 71, 58, 88,160, 14, 34, 68, 85, 66,138,150,194,167, 94,168,182,238,126,158, 44, 69,206, 41,113, 11, 0, 39, +156,100,148, 46,187,250,234,133, 67,216,232, 38,212,178,219, 78,170,214,152, 18,221,176, 35,117, 61, 53, 4, 3,205,228,153, 33, + 68, 98, 63, 48,205, 19,135,105,226,120,115, 13,121,118,187, 93, 58,185,148,109, 58,225, 96,154,210,186,225,186,168,247, 37,108, +180, 61,173, 24,212,149,150,160,117,213,149, 7,127, 13, 75, 53, 96, 90,215, 37,164,235, 56, 78, 35,121, 28, 87,241,223,146,167, +238, 54,193,150,173,128, 90,103, 94,243,162,188, 23,130,231,173,215,117, 92,223,166, 73,155,144,169, 53,198,248,244, 30,215,143, + 67, 39, 78, 6, 17, 41,109, 42,231,217, 31,204,134, 79,188,174,150,149, 29, 49, 42,220,135, 17,206,147,112,255, 65,228,126, 85, + 30,223, 76,188,246,223, 60,225,222,111,188, 96,248,165, 15,137,255,246, 99,244,243,143,209,113, 7, 79,177,236,206,135,192,190, +179,125,242,183, 43,241,187,137,248,209, 76,186,206,116,204,164, 14,134,100,129, 49,215,147, 85,164,203,244,181, 98, 0, 0, 32, + 0, 73, 68, 65, 84,221, 91,159, 66, 47,206, 8,199, 3,245,230, 6,166,145, 46,218, 40,174,148, 9,237,130,251,150,237, 69, 42, + 85,201,193,188,238, 45,218, 48,182,189, 97, 45, 6,190, 33,160,169, 51,250,212,156,209,227, 30,173, 29, 49, 38,228,124,135,116, +103,200, 48, 33, 58,195, 14,100, 84,194,172, 54,202,154,109, 87, 18, 99, 36, 45,104,213, 64, 29, 43,245,163,137,244,197,115,248, + 66,103,129, 49,147,121, 49,101, 23,144,179,232, 17,145,129,240,184,135, 47,236,224, 51, 1, 30,222, 71,242, 67,247,104, 31,160, +236, 77, 88,208,102,140,187, 8,221, 25,240, 18,158,237,225,185, 67,113,114,134,199, 14,210,121,182, 55,207,113,239, 31,182,186, + 17, 88, 56, 98, 57,212, 38, 86, 82, 79,254,114,199,156,179,220, 98, 83,190, 11,244, 81, 9,151, 29,225,149, 14,206, 19, 34, 17, + 61,204,166, 6, 44,186, 68,104, 86, 86, 16,159,186, 25,119, 85, 96,234,169, 2, 94,252, 18,111,251, 66, 85, 36, 53, 35,124,179, +207, 8, 60, 47,232, 84,108,219,219, 5,244, 43, 55,200,235,231,112,150,144, 55,123,194, 39, 7,226, 7, 59, 46, 14, 7, 30, 70, +251, 89, 14,229, 84, 49,205,102,239,218,158,231,226,109, 65,244,125,252, 65,148,120, 93,216,133, 25, 25, 2,242,131,128,116, 1, + 13, 3,114,153,224,173,128, 28,109,167,169, 85,208, 50, 81, 35,164, 99, 69, 68, 23,156,107, 83,162, 7, 61, 45, 94,100, 99,153, +146,165,110,177,125,171, 30, 43,210,124, 86, 18,128, 29,132,183,225,254,127, 72,252, 79,190, 74,253,171,239,161,175, 36, 82, 46, +228, 77, 90,239,137, 0,109,243, 1,174, 62,147, 94,185,212,171, 80,238, 46, 99,189,234, 41, 76,166,229,129, 47, 23,157,202,202, +240,223, 72,110,164,173, 30,164,218,122,197, 47,180, 54,246,157,138,109,155, 90, 87, 94, 79, 46,120,150, 11,234, 36,137,109,251, +117, 54,151,123,251,217,162, 40, 73, 34, 41, 8,103,174,135, 24, 91, 16, 75, 83, 80,187, 45,203,124,229,120,220,168,189,240,177, +229, 88,251,110,175, 86, 7,191,232,194,123,114,194,152, 31,254,238,193,110,145,157, 65,117,137, 88,109,148,185,185,108,132,120, + 98,201,121,177,174,170,230,186, 76, 16, 62, 62, 12, 93, 11, 45, 89,180, 44,202,250,223, 45,163, 61, 34, 39,130,168, 22,205,147, +130,123,196,171,225, 65,187,126, 48,238,186, 90, 38, 0, 21, 3,193,164,206, 58,229, 5,103,106, 23,112, 21, 89, 38, 73,170,149, + 16,162,189, 30, 57, 47, 42,137, 16,251, 37,171,214,196,114,193,149,238,213, 88,243, 46,136, 83, 87, 62,169, 43,197,107,198,172, +100, 43,191,109,117, 18,184,202,212,178, 13,202, 70, 48, 18,214,204,242, 69,216,160, 30,220, 3, 49,117,116, 93, 71,140, 29,115, +206,140,199,189,189, 39, 67,207, 62,103,110,166, 35,199,219, 27,152, 39, 83,241, 75,216,116,186,174, 42, 23,243,159,183, 9,192, +214,215, 45,178,126, 77,221,120,245,101, 11,171,212,117,196,185, 29,137,247, 18,136,195, 25,183,243,196,180, 63,152,237, 44, 24, + 91, 69,116,179, 14,241, 47, 84,188,152,105,251,253,187,134,180, 86, 70,180,194,118,219, 16,233, 6,207, 44,119,133,239,250,241, +177,251,246, 31,165, 45,180, 63,249,131,159, 48,142,241,190, 42, 99,181, 81,204, 40,112, 85,225, 50, 40, 87, 98, 77,213,179,157, +240,254, 46,240,106,174,188,241,219,215, 60,252,135,183,236,126,246, 35,194,191,251, 10,250, 79, 60, 66,231, 30, 25, 20,198,108, + 63,240, 27,192,207, 36,248,163,137,240,189, 76,255,195, 91,226,205,204, 89, 52,132,232,189,122,164, 92,222, 99,250,229, 63,199, +252, 59, 95, 33, 93, 61,103, 56, 94,147, 58, 83, 53,206,215, 47, 12, 20,224,166,127, 98,132, 26,208,154,153, 8,236,220,130, 98, + 9, 72, 66, 23,253,192, 18,181,109, 91, 85,144,132,244,157,189, 33, 37, 35,121,134,121, 68,206,207,145,139, 29,114,110,164, 38, + 66,133, 51,123, 48,120,105, 59,240, 42, 25, 81,203, 36, 14, 82,145,206,148,238,245,187, 71,226, 39,123,120, 61,193,179, 98,243, +255,115, 65,206, 4, 25,133,240,102, 7,159, 31,224,179, 10,143, 30, 35,229,129, 75,155,179, 41,232,114,134,209, 88,244,210,230, +225, 65,225,197, 21, 60, 81, 27,185,239, 13,151, 38, 63,229,113,179,123,239,210,123, 95, 61,232,122, 52, 54,180, 98,108,241,152, + 85, 12,149, 47, 6,159,105,162,174,222, 89, 1,157,168, 1, 21,118, 9,121,212, 35,131,169, 82,153, 42,117, 86,223,177,110,210, +165,124,252,203,169, 99,229,228,177,148,141,237,169, 46, 23,222, 50,103,116,147,187, 93, 24, 92,249,148,225,201, 68,124, 39,194, + 77,134,175,189,132, 47, 63,130,123, 59,228,115, 23,164,247,103,234,237,204,189,167, 51, 57,185, 39,189,174, 43,134,200, 10, 7, +217,126, 56, 74, 49,226, 95, 85, 24,197, 66,137,186,171, 66, 56,203, 72,154, 73,239,187,223, 47, 6,184, 76,240,233,193,120, 67, +163,207,118,247, 80,123, 33,206,149,160,117, 25,197,159,168, 82,125, 92, 25,101,221,221,138, 99, 70,165,237,168,199,138, 76,213, + 15,202, 25,164,115, 60,238,167,145, 63,254, 31, 16, 63,255,235,212,143, 42,241,190,109,109, 26,180, 71, 78, 62,176,178, 77,162, + 89, 49,240,122, 39, 49, 85,148, 90,228,206,101,190,190, 81, 85,215,239, 89,116, 51, 6, 87,167,191, 21, 69,213,118,190, 82,170, + 67, 85,252, 0,114,229,244,236,119,107,239,172,242, 82,218, 37, 87,239, 36,181,157,130,113, 22, 86,245,230,123,107,127, 38,160, +110, 35,139,182, 63,245,189,209, 92,170,247, 89, 43,240, 68,169, 75,108,108,195,100,138, 8,146, 58,251,251,231,201,104, 94, 11, + 68,199,113,199,106,254, 95,203,151,143,144, 44, 32,100,137,245,118,245,190,162, 75, 44,106, 70,236, 89, 19,235,247,230,172,158, + 38,185, 94,216,139,179,195,159,122, 65,108,237,224,162,188,212,166, 73, 27, 18,105,245,106,180,122,241, 19,218, 5,179,196,156, + 43,177, 51, 58, 89,172,166, 22,111,217,233,235,196,194, 59,209,208,161,204, 54, 93,104,138,248, 90,137, 81, 60,254, 51, 82,138, + 79,111,234, 76,157, 45,166, 83, 99,178,179,174,174, 43,146,170,101, 93, 3,105, 37, 87,179,251, 45, 91,161,176,226, 12,197,253, +218,134,103,149,117, 4, 45,193, 56,229, 37, 47,153, 9, 77,160, 38,158,179,222,232,109,213, 63, 80, 49, 90, 86,122,151,122, 52, + 4,142,211,200, 60, 78,116, 49,114,156,102,170,142,204,165, 90, 14,200, 38,167,160,226,201,115, 18,189, 67,175,148,121, 51, 1, + 16, 57,249,124,156,208,146, 56, 53, 98,180, 3,212,125, 1, 92,132,196,197,227, 87,217, 31, 15, 72,169, 28, 85, 57,222,222, 82, +243,140,104, 37,134,206,233,122, 86, 52, 45, 22, 54,177, 98,166, 93,232,167,133,158,219,183, 55, 72,220, 19,231, 90,189,155, 15, +240,255,131,124,190,171, 33, 90,118,234,232, 66, 55,109,217,205, 90, 12,222, 49, 55, 21,175,239,138, 50,240,172, 10,103,230, 12, +227,182, 24,224,227, 42, 10, 79, 31, 8, 15,179,242,214,215,111,121,244,111,237,217,125,225, 25,225,215, 95,181,192,145,177,179, +127,225, 76,224,126, 15,143, 19,250,217, 10,223, 72,196, 63, 56, 16, 95,140,116,185, 48,236, 97,254,103,127,133,253,171, 63, 69, +247,238,127,199,120,251,220,236, 81,221,142,241,214, 4, 17,196,176, 16, 70, 69,226, 18, 13, 86,131, 82, 36, 27, 80, 37,177, 40, + 65,205,167,109,150, 17,201, 74, 96,166,106, 64,163, 47, 63,107, 37,104, 33,220, 92, 67, 25,145,116, 9,151, 61, 18,138, 9,184, + 10,132,123,138,206,150, 84, 22,102,165, 75,217,160, 42,179,209,230, 68, 2,250, 34, 35,169, 67, 94, 9, 80, 18, 18, 5,233,212, +212,213,159,218,193, 79, 43,188,250, 73,136,127, 30,246, 95,241, 18,254, 0,249,104,108,211, 92,215, 37,109, 47, 48,223,194,147, + 25,110, 51,154,189,109, 24, 20,222, 26,236, 38, 27,125,124,114, 8,182,146,199,224, 13, 97, 35,218, 90, 58,131, 54,250,246,189, + 37, 77,221,219,242,211, 85,108,236,120,225, 44,249, 62,216, 5,244, 66,215, 56,171,237, 72,125,211,157,182, 29, 89,240, 72,239, + 19,123,155,172,162,147,182, 83,151, 22,133, 21,163,141,193,178,249,224,245,210, 98,104,121, 50, 17,223, 24,208, 63, 56, 32,159, + 56,131,199, 59,120,125,135,124,254,130,244, 60, 51, 28,111,184,184, 46,228, 4,199,236, 95,183,174, 10,226,213,206, 41, 39, 43, +135,182, 27,206, 81, 56, 86, 8, 47,230, 37,208, 34,118, 1,237, 2,116, 88,204,236, 59, 3, 50, 85,226,204, 2,179,183,173,140, + 16,167,122,130,112,219, 6, 66, 44, 62, 84,185,139,199,242, 27,250, 38,192,116,132,249,187,190,210,217, 25,147,224,236, 87, 9, +255,241,231, 9,255,230, 55, 9,247,226,226, 36,111,251,241, 69,108,168,171, 53,113,113,133,149,143,119,136,181,174, 48, 69,253, + 56, 29,246,132, 14,215,250,155, 18, 54, 75,112,191, 50,150, 8, 81,173, 70, 39, 67, 86, 4,170, 11,214,174,171,114,230,227,243, +181,251, 98,131,221,244,142,184, 17,225,238,132,209,156,128, 94,196,189,214, 53, 35, 21,178, 68,102, 17,230, 54,194, 21,181,188, +245,205,208,150,182,139,181, 54,157, 26, 34,101,158, 44,104, 74,252, 66,151,176,137,243,148,165,192,140, 41, 57, 65,175,174, 32, +169,186, 6,216, 22,167, 11, 21,247,154, 87,133,172,213,186,255,205, 68, 42, 46,121,240,186, 92, 94,117,171,106,247, 41, 89, 23, + 87,113,162,108,100, 90,237, 98, 95,157, 12,178, 64,130,226,112,238,157, 96, 98,206,133,233,112, 67, 9,137, 34,137, 34,222,169, + 58, 36,166, 96,220,143,144, 44,133, 76, 61, 53,172, 8, 11,115,124,206, 51,250,255,209,245,118,177,182,101,217,125,215,111,140, + 57,215, 90,123,159,143,251, 85,117,235,163,171,219, 93,238,110,219,109,119, 28, 39,178, 19,199, 73, 72, 8,249, 80,148, 32,100, +132, 64,188, 16,161,136, 8,158, 64,138,120, 0, 5,162, 86,224,129, 7,144, 16,136, 7, 4, 15, 72, 8, 33,148, 40, 65, 74,136, + 66,136,132, 29, 59,182,227,182,211,137,237, 78,140,251,195,238,118, 87,119, 87,215,199,173,251,113,206,222,123,173, 57,231,224, + 97,140,185,214,190,183,170, 31,142,238,173, 91, 71,103,159,189,246, 90,115,206, 49,198,255,255,251,215,226, 7,151, 96,160,139, + 26, 58,100, 68, 60,136, 74, 35,124,165,135,209,208, 43,205,200, 73,167,149,104, 15,199, 28, 89, 18, 41,197,231, 16,170,251,178, +204, 33,138,123, 30, 99,138,177,118,111, 94, 84,135,169, 38,242, 56,145,198, 49,226, 75,103,196, 26, 85,178,231,137,164, 68,237, +162,180, 56, 2,174,121, 68, 13, 52,249, 90, 79,192,125,214,145,128,157, 89, 75,122, 39,202, 54,253,196,122,152, 91,215, 12,191, +110,123, 17, 94,185,127,143,116,125,205, 92, 27,207, 88,184,125,250,100, 37,189,233,121,141,220,147,221, 66,211, 80, 75,161,126, +196,134,126, 78, 76, 20,145, 23,192, 75, 47, 90,216, 94,168,149, 94,216,221,237, 67,186,247,168,212,135, 14,236,232, 2,156,234, + 21,249, 51,123, 17, 71, 23, 92,232,102,220,138,144, 35,211,250,164, 48, 55,227,166, 10,207,146,240,232,174,240,114,133, 87,191, +122,195,131,255,224,192,248,185, 71,200, 95,121, 25, 62,117,215,191,249,113, 2, 93, 28,167, 58, 9, 92, 42,124,125, 68,191,254, + 20, 30,188, 9,127,242, 47,178,251,250,111,162,239,189,199,188, 28, 25, 46, 39,110, 91,225,180, 84, 52,249,147, 87,173,173,228, +172, 38, 41, 78,249,130,234,192,160,238, 45, 23, 1, 29, 98, 51,204, 18,152,191, 16,100, 52,219,136, 85,234, 22, 16,217, 73, 36, + 87, 29,253,163,218,141, 78,170, 43,234,161, 44,167,134,188, 7,195,179, 19,106, 66, 27, 96, 89,140, 60, 20,164, 39,153, 61,170, +200,107, 3,242,178, 15,251,164,138,171,200, 63, 1,188,114, 1,187,191, 16, 60,247, 91,151, 72,183, 19,204, 21, 59,133, 40, 32, + 16,183,104,130,175, 62,243,168,211, 78, 93,155, 4,185,140,235,117,138,118,211,164,216, 77,243,254,160, 60, 47, 80,123, 78,117, +190,218,171,156, 72,165,230,212,173, 20,155,122, 78,130,238, 7,244, 58,123,181,170,130,157,188, 27, 96,139, 11,101,200,241,126, +100,155,136,173,155,121,220, 55, 61,224, 78,206,110,196,243,198, 67, 10, 26,135, 12,177, 8, 15,217, 75,190, 39,160, 15, 18,245, + 4,237,189,130,236, 18,122, 55,218,240,127,106,132,187, 35,242,201, 61,233,131,133,241, 84,185, 58,221,120,199, 38,195,161, 42, +170,182, 37,107,197,254,153,251, 24,226,133, 57,127,109, 1,243, 59, 25,211,211,133,146,207, 84,193, 73,145,151, 51,220, 25,176, + 55, 65,231,216, 61, 31,187, 79,208,250, 14,219,236,204,188,199, 11, 97, 16, 81,150,117,254,106,239, 59,151,234, 57,178,239, 27, + 60,252, 53,104,239, 64,186, 10,213,218, 53,242,123,255, 93,244,211,255, 25,242, 54,164,139,173,197,223,171,232, 62,207, 62,119, +185, 61, 39, 88, 78,120,117, 30,149,120, 61, 39,192,173,161, 21, 27,161,202,100, 75,109,107,141,115,133,222, 58, 82, 89, 49,177, +205, 43,139, 22,115,120, 83, 89, 19,243, 14, 65,118,155,158,179,167,157,221, 3, 38,129, 37,149, 51, 31, 93, 59,179,231,185, 70, + 32,197, 76,151,168,173,231, 86, 60,181, 77, 51, 53, 57, 10,202,196,217,238,218,122, 69, 84,163, 77,105, 48,140,200,180,119,123, + 86,109, 30, 46,164,225,249, 24,188, 85,211, 74,115,114, 28, 48,134, 61,236, 60,231,198,197,109,182,126,188, 37,198, 67,173, 54, +170,184,135,191,213,237,222,110,173, 51, 18, 92,112, 90,250, 26, 26,182,185, 30, 89,148, 4,246,131,249, 89,189,109, 35,136,117, +131,215,205, 1,144, 2, 72, 50,152,161,251,107,116,218, 83,159, 61,102, 62,222,114,210,129,197, 18, 85, 26,164, 70,149,228,126, +119, 4, 77,153,166, 25,202,226,226,219,228, 85,120, 69,168, 75,161,116, 65, 91, 93, 34,213, 76, 67, 57, 47, 27, 75, 66,125, 51, + 84,201,161, 78,143,123,190, 89, 79,110, 90,103,245,213,106,220,107,254, 89,166, 52,160, 57,252,215,243, 49, 54,212,231, 21,134, + 98,207, 71,152,114, 54, 62, 19, 17,242, 48,145,199, 9,178, 50,207, 11,182,204, 1,183,113, 72,112,109,205,223, 95,216,229,120, +206,186, 41, 43,202,214, 58, 96, 34, 54,117,211, 51, 4,232,139, 21,202,202, 17, 8, 47,130,120,152, 88,183,216,157, 16,242,241, +136, 13,153,195,211,199,212,211, 41, 52, 4,172,209,172, 61, 81, 46,165,193,181, 21,181,248,200, 33,174,177,189,208, 38, 63,255, + 85, 92,164,215,214, 81,206,139,169,136, 47,110,232,219, 4,254, 35,143, 10,190,230,150, 26,148, 46,188, 80,233,175, 58,116,235, +107, 84,232,141,115,230,180, 81,205,103, 75,214, 28, 97, 94,154,255,219,209,224, 86,225,131, 43,229,165, 6,175,127,233, 9,247, +254,194, 45,249,143,221, 69,254,227, 87,224, 99, 23,240,193, 8,143, 60, 71,220, 38,224,165, 4,156,104,175,127, 6,218, 7,164, +250,187, 12,237,134, 97, 20,198, 1,242,237, 1, 83, 35,153, 80, 37, 78,202, 6, 86, 23, 52, 85,100, 26,208,164,238,131,151,140, +100, 67, 99,246, 42, 23,206, 93,183, 15,234,154, 53, 44, 65, 17, 90,123,183, 99, 80,177, 6, 69,174, 51,146,129,203,134,212, 29, + 28,103,207,139, 31, 20,203,194, 48, 87,228,253,133,121,134, 97,167, 94,121, 46, 5,118,226, 74,241, 15, 10,114, 63,123, 91,234, + 22,184,151,224,161, 57,177, 79, 94, 66,150,191, 19,106,119,131,122,139, 45,226,171, 98,204,160,109, 55, 34, 79,102,236,231,159, +193, 93,129,135,193,135,159,129, 59, 25,246, 9,222, 15,144,255, 78,182, 15,168,190, 72,205,242,177, 67,183, 55,201, 25,214, 86, +113,244,101, 82, 23, 23,234, 40,232, 69, 70,238,142, 1, 23,151,213, 42,103,181, 33,203, 38, 0, 17,233, 41, 85,178,230, 67, 59, +251,252,172,210, 56,243,114,247,155, 82,165,111, 50,201,211, 73, 58,110,235,212, 96, 39,232,189, 1,110,149,246,205,133,246,157, + 5, 25, 19, 82, 11,124,233, 25,252,216, 53, 60,156,224, 83, 59,210,227,202,176, 24, 87,223, 57,120, 43, 54,193, 28, 49,176,233, + 5, 59,223,249, 6,115, 46, 66, 49, 7,255,145, 15, 13, 25,139,115,204, 39, 69,190,157,176, 4,242,242,132,220, 25,177, 79, 53, + 15,194, 41,128,204,180,217, 51,142,173,182, 15,141, 27, 76,195,159, 25,188,239, 85,178,221, 95,183, 26, 60,169,240,158,194,241, + 29, 56,125, 17,242, 39,232, 3, 47,166, 63,140,254,107,215,232,127,253,152,124, 87, 73,173,177,156,209, 98, 95,172,186,251,230, +210,133,144, 17,183,189,158,242,245, 92,127,164,231,221,132, 16, 26, 38, 11, 14,188,173, 94,103,107,219, 74, 82,123,245,216,147, +219,218,182, 2,184,134,163,174,227,199, 67,176, 38, 70, 83,199,167,246, 10,207,124, 35,236, 98, 50,117,133,154,211,210,186,143, +189, 67, 57, 6,223, 20, 82,241,150,110,193, 88,162, 98,172,154,144,148, 73,106,206,170,104, 53, 72,118,189, 37, 53, 96,187, 11, +191, 30,167, 83,108,228, 3, 77, 19, 58,184,106,168, 30, 15,171, 47,186,105,162, 36,159, 19,151,184, 6,169,139, 36,218, 54, 38, +144, 32,185,149, 56,147,181, 51, 48, 79, 63, 44,182, 23,132,154, 53, 64, 75,189,165, 59,132, 93,116, 10,177,199,218, 85, 57, 19, + 65,244,182,123, 83, 33,103, 39, 99,234,197, 30,189,186, 71, 59, 29, 88,230, 19,183,115, 97, 81,165,132,210,187, 83,224, 2,108, + 14,106,232,180,243,207,165, 69, 78,119, 39,214,244,239,139, 86,180, 68,139, 77, 52,193,144, 17,205,254,247, 94,169,170,103,120, +180,226,164,123,205,201,197,104,209,246,182,214,168,165, 3,102,188, 58,214,148, 93, 76,187,148,176,153,186,176,167,133,119,240, +195,176,148,179,229, 74, 97,208,196, 48,238, 72,121,160, 24,204,243, 28,209,165,217,157, 0, 34,148, 82,227,119,248,176,219, 70, +147, 99, 87,171, 61,159, 54,103, 29,123, 43,182,229, 34,124,168, 52,246,103,182,131,102,106,173, 80, 11, 7, 73,220, 62,125,202, + 43,151,151,124,208,140,229,224,244,203, 86,125, 92,184,234, 34,162, 80,108, 89,168,181, 98,165, 70, 39, 64,183,238,152,124,184, +242, 22,209,179,124, 67,215, 31, 61,135,165,144,239,221,114,127,177,245,126,254,255,210,191,122, 55,127, 30, 44,172, 63,178,198, +115,234,121,252,227, 11,189,253,118, 22, 34, 49,135,192,227,196,166,186, 94,162, 82,184, 81,225,118,231, 15,232,248,229, 91,242, +223,185,241,121,226,143, 14,158,168, 54,203,202, 89, 39,123, 28,167,237, 4,145,119, 73,239,127, 29,185, 63,145, 7, 97,119,156, +217,165, 16,115,201,134, 83,145,206, 4,181,202, 96,141,125, 86,174,166,204,176, 27,144, 65,209, 41, 33,151, 9,238, 13,126, 74, + 60,201,122, 44,119,129, 67, 40,213,155, 7,128,203,253, 1,125,121,132, 33, 98,245,118, 78, 51,146,218,252,160,112,145,144,187, +153,116, 87,201,248,130,111,197,189, 43,122, 1, 50,186, 21,206,145,237, 78, 91,145,151, 6,248,152,194,213, 15,128, 93, 32,135, + 95,136, 39,251, 0,243, 18, 43, 98,103,103, 38,184,163,240,179, 79,224,183, 79,216,163, 25,153, 27,188,146, 96, 81,228,245, 9, + 94,157,224,241,226, 23,120, 18,248,214, 66,251,237, 3,229,184, 56,247, 28,161, 54, 13, 21,177, 57, 36, 33, 52,105,201,186, 10, + 93, 72, 89,124,206,103,158,200,150, 31, 76,164, 55,119,200, 43,147,223, 77,223,157,177,111, 30, 41,143,102,202,161,113, 60, 19, + 3,153,109,160,160,222,194,110,182, 41,232, 58,236, 38,169, 48,168, 48, 38, 97, 63, 56,124,102,184, 59,144, 94,223, 35,175,141, +112,223,145,187,124,115,134,251, 2, 23, 81,178, 28, 13, 57,128,220, 17,248,160, 34,175,100,184,183, 11, 16,140,162,181, 33,179, +145,159, 45,171, 24,200,100, 19, 65,157,143, 8, 68,182,104, 77, 61, 19,211,145,194, 46, 85,226,126,200,126,205, 48,144, 81,224, + 50,251, 97,106, 48,228,132,179,234,101, 27,136,174,247,207,224, 35, 5, 73,157, 87, 29,179,116,141,255,238,127, 31, 61,135,154, +203, 4,175, 85,100, 47, 48,253, 4,200,126, 45,239,229,213, 95,194,254,250,239, 98, 57,129,182,231,230,234,231,170, 87,225,249, +127,176,182, 9, 41, 42,231, 62, 86, 57,107,185, 75, 84, 22,182,169,249,215, 74,127, 83,173,251, 89,119,179,166,173,115, 62,219, + 4, 69, 45, 42,229,206,198,239,249,229,213,132,114,230,205,174, 43,245,109,179, 5, 72,120,174, 53,123, 40,134,224, 30,240, 33, + 39,210,144,201, 17,252, 81, 3,114,180, 52,143,173,148, 97,244,192,166,174, 38, 31, 6,218, 48,193,184,195,166,157,255,174,243, +236,213,249,144, 33,143, 94, 49,151,133,118, 58,122, 12,108,242,182, 52,170,222,166, 87, 13,116,104, 91,149,207,117, 77, 2,220, +188,145,174, 77,168,155, 29,171,139, 32,251,225,241,236,222,146,149,134,231,107,233, 46,206,176, 41,124,202,179, 41, 53,152,250, + 93,196,217,131, 67,194, 45,237,133,241,229, 53, 88, 99,153,143, 28,151,202, 44,137,170,153,150, 39, 76,242, 6,118,233,136,218, + 46, 16,196, 60,199,189,139,192,130,119,222,172,110, 48, 35,186, 64, 48,163, 17,225,169,113, 93, 92, 91,236, 48,149,243,239,105, +214,176,226,213,121,181,141,152,166,241,218,152,209, 22,239, 2,108, 29,247,180, 97, 23,217,238, 53,206,245,104,226, 51,255,113, + 24,153, 46, 46,200,227,196,220,140,211,225,198,127,102, 31,249,136,227,151,169,109,165, 43, 34, 91, 85,155, 66, 99,213, 98,166, +221, 3,128,164, 39, 87,225, 86, 51,105,182,126, 96, 61, 86, 85, 67, 96,105,170, 72,171,228,148, 72,195, 68, 85, 23, 20, 30, 69, +121,252,244, 9,229,116,136,238, 69,116, 67, 35,138, 86,196,159,237, 98, 80, 79,135, 24, 81,180, 45, 66,248,133,137, 62, 1, 65, + 18,217, 6,109, 98, 91,128,147,124, 4, 96,230,121,157,187,125, 20,131,102,171,212, 69, 2,135,152, 66,225,217, 96,136,190,170, +198,236,168,179,175,123,229,222,236,188,114,119,101,244,100,112,140,212,139,169, 91,108,212,125,197,199, 65,184, 25,149, 87, 14, + 71, 30,252,247,111, 51,252,223, 55,200, 95,125, 25, 62,117, 15, 25, 34,239,252, 13,133,227,128,236, 27,242,206,251,200,165,186, +180,246,100,228, 60,113,241,184, 50,206, 11, 83,105, 12, 5,230,106, 28,171,119,244,181,129,148,138,230,130,214,140, 12,151,176, +223,251, 65, 97, 39,176, 31,189,229,127, 58, 65,137,184, 65,196, 45, 91, 39, 67,170,231,148,234,117, 70, 46,242, 26,130, 41, 26, + 54,171,253,232, 37,237,212, 72, 53, 99,195,136,126, 48, 81,254,233, 13,203,239, 30,105, 55, 13,189, 82,184,219, 96, 17,172, 8, +146, 11, 60,220,249, 83, 45,226, 41, 40,243, 63,246, 63,205,160,156,176, 99,196,176,246, 82,230, 66, 92,204,240, 79, 14,212,188, +208, 78, 11,250,181,133,244,125,131,255, 30,151,161,124, 43,226,136,182,177,121,117, 72, 7, 36,244,116, 33, 11,245,238, 38, 44, + 82, 54, 24, 77,138, 13,190, 11, 10,117, 76,232, 85,134,171,209,191,225,216,224, 81,165, 30, 10,118, 44, 44, 37, 40, 93,161,185, + 72,201,219,237,125,243, 44,109, 83,153, 55,182,106, 53,197,220, 62,171,127, 20,178,243,205, 83,122,111, 60,121, 70, 59,173,151, +123, 13,189, 74,216, 32,200, 28, 24, 89,105,216, 23,110,144, 63,185, 67,238,239,176, 55, 26,114,218, 51,136,103,212,223,121,231, +128,101, 33, 69,247,230,140, 32,187,158,100,211,115,170,244, 13, 65,218, 4, 90, 49,100,110,180,165,210,142, 5,125,164, 88,255, +165,239,140,200,171,187, 21,228,194,187,190, 33,182, 82,177, 98,235,125,228,130,163,173,156,150,190,211,174,146,235, 16,173, 44, + 13,158,137,219, 17, 31,188, 5,237,125,208, 7,241, 84, 93,193,195,127,157,244,211,191, 74,251, 27,133,244,170,146, 91,101, 89, + 67, 70,236, 57,226, 92, 39, 99, 57,237,139,109,241,235,115,194,118, 54,202,236, 77,169,216,112, 83, 84,236,231, 0,151, 53, 13, +109, 85,116, 7, 31,123, 5,164,123, 62,173,213, 45,204,163,243,225,107,156, 73,157,199,238,180, 51,225,121, 98, 28,161, 52, 95, + 15, 59,221, 87,237,242, 55,114,171, 12, 36,116, 72,216,169,156,217,181,146, 39, 34,214, 22,228,197,130,106,194,198, 17,149, 33, +238,203,160,171, 13, 67,216,155, 20,155,143,216,124,112,190, 4,184,109, 45, 37,183,241,105,194,146, 15,184,235, 25,194, 84,195, + 86,166, 57,109,222,242,224,230, 23,220,226,213,120, 94,200, 45,103,225, 89,221,138,215,100,155,209, 14, 41, 86, 19,243,188,117, + 98,115, 39, 18, 18, 53,230, 44, 93,171, 96,102, 48, 78,180,101,102, 89, 22, 78,167, 19, 75, 53,150,136,231, 21,150,128,199, 68, +117,151, 61,246,212, 84,221, 82, 59,237,189, 13, 94,230, 21, 23,219, 22,239,135,104, 18,134, 97,242,120,217, 62,211,213, 28, 65, + 39,230, 52,184,142,130,213,158,211, 29,235,125, 41, 17, 21, 26,237,102, 17,199,196, 34, 78, 83, 91,102, 95, 20,206,139, 63,219, +196,140,222,138,174,207, 69,225,246,153,114, 82, 37,143, 99,240,213,149, 82,143,107, 87,224, 57, 32, 82,171, 27,237,149, 13,202, +162,113, 88,108,103,140, 56,255,124,210,154, 6,106,210,226, 61,217,218,193, 16,112,119, 65,140, 97,146, 8,105,156,200, 73,253, +154,150,133,211, 60,115,120,252,129,163, 92, 45, 58,110,107,203,223, 15, 11,170, 66,213,196,114,184,197,150,226,225, 76,145, 89, + 96,234,194,234,205,237, 17,249, 8,210, 43,117, 63,144,183,243,230,250, 11,221, 4,251, 8, 64,172,125, 68,213,222,255,146,239, +134,120,163,136,123,211, 23,235, 73, 93,158, 97,125, 48,215,103,153,179, 72, 86,235,139,196,134, 63,190,208,205, 56,154,197,220, +200,219,124,217, 60, 4,225,152,132,155,189,240,116,223,120,245, 43, 79,184,250, 75, 39,228,223,188, 69,254,226, 67,216, 11,150, + 95,162,181, 55,145,227,140, 62,125, 31,153,129, 71,126,242,179,212,144, 1,116, 86,198,164, 92,139,249,102, 46,158, 60,214,250, +195, 85, 64,150,226,182,180, 36,112,121, 9,247, 38,120, 9, 56, 10,242, 94,195,180, 33, 86,177,185,177, 6, 12,223,201,232,195, +201,103,227,163, 64, 83,175,214,198, 16, 9,141, 97, 65, 58,156,224,105,245,104,191, 34,164, 87, 7,236, 73,161, 62,105,180, 15, +140,180,107,222,182,190, 82,236, 8,178, 68,168,185, 42,212,103,200,252, 36,230, 60, 7,236, 20, 23,187, 68,127,111, 23,153,236, +191,248,140,118, 40,216, 93,195,230, 74,125,180,160, 95, 62, 33, 63, 49, 5,173, 46, 46,248, 69, 88,163, 98, 39,147, 41,147,150, +230,155,117,242, 89,104,171,207,159,250, 68,108,173, 84,221, 89, 38,164,164,232, 69,246,121,250,165,130, 41,118, 91,176,219,138, + 29, 42, 45,162, 86,103,219,216,231, 22,221,229,210, 89,235,201, 63,231, 30,233,184,194,110,116, 99,178,187,129, 65,144,203, 12, +187,193,231, 59, 57,195, 55,102,236, 59, 5, 94, 51,236,169,159, 28,229, 42,146,245,212,165, 7,242,126,195,126,227, 9,242,227, +247,224,229,201,237,145, 18,234,232, 95, 51,238,190,127,226,105, 22,199, 13,159,181,172,107,188,251,132,121, 32, 86,131, 23,249, + 55, 45,153, 47,214,115,163, 29, 61,249, 79, 6,133,189,122,231,101, 63,192,107,178,198,123,202, 7,254, 96,180,217,129, 67, 22, +220, 90, 29, 4, 75,194,122,250,105, 94, 25,172,195,109, 11, 22,251,193,224, 3,224,245,247, 97,121, 7,134, 31,136, 82,123,128, +244, 39,208,127,231,147,232,223,248, 50,169, 36, 70,169, 20,188, 2,174,103,208,148,142, 50,213,248, 71,167,198,217,214,146,238, +226,186, 51, 25, 90,138, 10,176, 87,214, 43,199,253, 76,168,100,237, 69, 4,134,156,197,148,250,168,199,108, 99,161,154,232, 74, +217, 90, 35, 54, 61,154,100, 83,238,214,136,173,140,217,185,160,158, 94, 38, 91,183, 71,226,144,144, 74, 65,166, 29,101,151, 54, + 28,109,139,132,177,197,193, 25, 41,103,100,156,124,174, 27,164,196, 86,253,103,212,214,176,229,228,239,107,153,209, 90,124,212, + 52, 12,174,126,111, 46, 14,107,187,168,194, 14,199,141,212, 19, 95,131, 24, 73,140, 83, 28,136, 37,198, 23, 82,206,104,113,241, +231,144,182, 71,176,156,193, 94, 82, 56, 16,186,208,208, 35,131,109,245,172,247, 36,182, 28, 7,155,117, 20, 97,193,104,215,204, + 92, 10,199,121, 94,237, 96, 22,209,188,114,170, 46, 92, 27, 6, 48,113, 92,112,110,212,154,160,229,141, 30, 41,201, 5,113, 73, +145, 97,192,138,195,120,114,242, 77,166,210,199, 46, 78,191,244,106,126,243,153, 91,173, 88, 89, 34,156, 38,173, 51,103, 19,167, +131,246, 19,163,213,182,206,126,252,254,178,231,157, 26, 91,196,208,246,239, 93,183, 32, 78,143,211,148,209, 60,146, 82,162,224, + 8, 85,179,237, 48,233,152,227,182, 34,103,109, 67, 33, 70, 17, 33,235,166,184, 10,117, 53, 61,215, 89, 94,117, 14, 81,161,123, +154,155,119, 34,104,182,134,185,148, 82, 67, 36,232, 98,205, 60,140, 44,165, 4,163,190,108, 58,128,232, 20,104, 10,204,114,107, +212, 50,211, 37,153, 46,148,136, 92, 82,145, 77, 99,176,110,150,186,186, 2, 52,242, 3,186, 50,168,107, 94,158,171,210, 87, 90, +221,247, 20,194,111,240,153, 31,105,198, 44,194, 81,224,113,134, 91,115,194, 92, 50, 97, 15, 92,246, 8,112, 92,159, 53, 27,236, +194,175, 89,207, 5,179,103, 51,248, 19,190,145,239,154, 39,116,213, 80, 60, 46, 10, 55,131,242,236, 14,188,118,156,121,233,127, +253, 46,227, 23, 79,240, 87,239,195,103, 62, 6,111, 63, 68,228, 9,122,231, 6,174,197,171,154, 91,127,168, 41,213, 31,174,136, + 87, 28, 13,106,242, 5,163,103, 42, 39,241,133, 27,245, 42, 74, 70,241, 22,106, 18,184,186,194,246, 9,110,158,249, 83,218, 43, +167,221,136,126,242, 18,185,151, 97,111, 1, 38,136,147, 77,242,157, 64, 84, 48, 43,176, 27,125, 99, 63, 85,152, 13,185, 72,164, + 31,186, 66,190,189,248, 5, 42,225, 11,156,207,230,221, 6,164,201, 67, 90,218,201,167,143,167,234, 23,105,142, 50, 71,195,155, +190, 24,246, 43, 7,236, 42, 34, 11, 23,127, 47,237, 91, 51,233, 88,131,242,214, 96,183,248, 97,229, 80, 92,220, 53, 37,164, 41, + 67,107, 76, 33, 88,111,210, 61,198, 18, 9,121, 33,130, 49, 86,224, 76,198, 21,239, 58,102,184, 55, 34, 23, 41, 84,218,134, 61, + 45,216,220,168, 39,227, 84,124,131, 44,214, 33, 13, 27, 26,182,179,216, 85, 55, 26,203,185, 88,111,101,118, 35,232, 62,163, 83, +134,189,122,200, 9, 96,223,152,177,103, 11, 60,115, 31,172, 51, 93, 5,185, 56, 83,121,142, 5,249,154, 97, 15, 15,200,247, 93, + 97, 15,155, 43,150, 71,101,104, 2,191,246, 24,158,156, 56,170,112, 74, 17, 52, 19, 93,164, 62,232,215,152,187,245, 89,155,134, +229, 71, 82, 44,218,213,104,135,134,228, 70,122, 90, 96, 76,216,197,236, 7,184, 75,133,215,247, 80,253,100,157,222,181,213,223, +218, 78,113, 82,104, 32,201,252,251,163,106, 94, 87,252,236,195, 85, 91, 26,114,106,240, 52,193,233, 6,230, 95,135,253, 31, 96, +195,228,188, 2,175,255,123,164,159,254,207,177,191, 93,176,215, 19,195, 77,165,157, 55,222,206,132,136,171,136,110, 37,198,121, +217,173,104,232, 30,206,221, 43,222, 81, 91,146,231,134,175,191, 99,237,109,204,120,208,215,104,213,168, 76,187, 55,146,236,149, + 86,245,195, 33,205,144, 97,196,134, 17, 41, 5,155,103,154, 44, 97,137,218,184,239,172,249, 3,129,157,109,254,251,228, 30, 37, +107,198,128,178,164,204,148, 35,222, 50,101,234,241,136,150,194, 14, 40,121, 96, 25, 19, 53,170,112,103,206, 87,199,207, 54, 67, +171,145, 90,128, 80,186,157,104,157,181,102,210,144, 2, 40,100,180, 20,190,226,182,101,109,232, 89,130,156,103,214,251,207, 40, +209,245,170, 97, 37,169,145, 51,207, 25,251,191,207,220, 91,219,186, 84,122,150,133,217, 66,107,100, 17, 93,168,146, 24,101, 99, + 58,116,148,174,164,240, 7, 4,206,245, 84, 11,181,132, 42, 31, 89,175,149,147,217,150, 46,247,166,213,130,150,130,230,193,173, +100,170,180,230,207,182,107,135, 22, 52, 42, 63, 77,105,229,246,155,165,109,179,169,109,157,235, 90,115,161, 23,165,110,246,180, +216, 50, 85, 19, 41,185,248,171,118, 79,123, 7,170,164,240,185,247, 36,213,179, 80, 30,139,200, 85, 86,225,165,110,164,187, 24, + 63,164,148,104,146, 56, 85,143, 87, 61, 55,243,187,149,113,123,173,243, 70, 88, 23, 38, 86, 51, 31,135, 18,121,234,113,223,119, +193,162,157,209, 0,147, 8, 57,229, 85, 88,231,143,105,163,205, 14,136,169,173,145,172,177,155,118, 88,158,176,101,241,215, 54, + 91,109,124, 93,123, 64,140, 82,106, 93,156,229,208, 71, 2,129,212,150,102,207,181,115, 36,184, 1,136,110,221,178, 78, 6,236, + 7,225,100,103,176, 41,158, 63, 38,189,208,141,252, 80,158,163, 25,233,191,249,254,221,231,239, 53, 87,172,191, 92,225, 65,133, + 7,102, 92, 38,184, 80,225, 78,242, 49,224,164, 49, 98, 92,163, 58,125,223, 26,116, 75,201,210,179,164,155,110, 3, 89, 45, 36, + 81, 97,148,234,234,227,195, 78,169, 25,166,239, 28, 25,254,254, 9,253,216, 45,242,123,158, 66, 73,232,242, 12, 30, 0, 59,117, + 25, 77,193, 91,229,161,100,180, 64,138,117,110,242, 16, 27,199,148, 96, 18, 37, 93,102,184, 28,225,206, 21,220,191,240,139,113, + 92,188, 21,209,212, 91,165, 55, 62,195,214,143, 95, 32, 63,180,131,169, 70,208, 65,184,247, 53, 16,119, 41, 57, 25,206, 12, 73, +230, 39,187,222, 94,108,234, 89,203,123,133,197, 49,132, 50,102, 84, 20,189,227,170,121, 30, 42, 60,188, 3,166, 72,121, 10, 86, +176, 83,139, 19, 82,172, 8, 67,136, 5,191,122,130, 95,189,193, 94,194, 85,231, 53, 20,241, 71, 72,115, 66,126,226,210,239,148, +233, 26, 46,127, 20,210, 35,228,155, 79,225,155,197,213,252,165,158, 59, 55,214,148, 49,141, 96,145,245,122, 41, 12, 73, 72, 99, + 66,167, 76,126,105, 66,190,111,135,220,223,123,155,243,221,153,246,246,137,250,184, 80,231,194,161,201,170,147,232, 51,199,172, +178, 10, 76,123, 80,130,200, 71,224, 97,197, 89, 57, 87, 10,195,253,145,244,112,135,188, 49,193,203,163, 71,141,253,253, 39,180, +182, 96, 41, 42,166, 28,243,234, 11,221, 86, 73, 83,215, 60, 60, 51,120, 53, 35,119,198,240, 95, 26,114, 61,160,187,132,190,219, +208,147,199,167,106, 98,101, 99,247,170, 48,105,132,144,196,172, 51,169,111,242, 57,185,157, 79, 34, 25,198, 15, 43, 26, 11, 67, +140, 11, 38, 31,140,202, 20,243,242, 57,126,126, 55, 32,219, 6, 14,146,236, 17, 94,114,198,106,151, 20,115,119,146,119, 1,166, +132,188,210,224,226, 8,187,159,132,244,160, 75,205, 64, 95, 67, 62,243, 51,216,223,122, 23, 27, 93,148, 86,187,158,225, 12,247, +138, 88,180, 74,159,167, 81,105,100,216, 39,241, 38,209,144,146,207,162,199, 17,153,118,232, 56, 58, 57,175, 72, 48,217, 59,188, +104,219,140, 87,255, 55, 96, 73, 49,205,129, 3, 13, 46,184, 14,136,186, 40, 72,202, 66,171,254, 44, 89,180, 73,251,205,215,206, +185,214,218, 55,145,104,249,139,147,220, 44, 15,222, 74, 31, 6,210,224, 63, 99,110, 66,209, 76, 30, 6,210, 56,146,134, 1,146, +122, 94,185, 53,134,230, 26,246,214, 60,222, 83, 59,218,181,197,225,165, 89,180,233,149, 60, 13, 30,189, 25,106,209, 78,207,236, +204,244,180, 6,208, 88,176, 6,162,149,219,182,234,176, 91,241, 52,200,207,221, 99, 92,240,160,151, 99,245,231,163,244,103,164, +111, 68,241, 48,166,222,214,143, 13, 63,197, 65,187,173,109,101, 54, 17,106, 30, 48, 29, 56, 45,133, 82,106,244, 61,226,231,134, +192,215,234,102, 43,108,165,120, 91, 58, 70, 16, 12,227, 26,231, 38,113,250,118, 86, 69, 8,218,162,125, 86,154, 81,231, 25, 74, + 4,203, 68,152, 79,247,255,107,140, 74, 58,119,185,123,192,123, 56,208,138,100,109,219,252,166,199,181,174,219,168,200,166, 0, +183,118,134, 3,118,178,158,226,175,145,135,137, 97,218, 65, 26, 56,205,142, 94, 85,137,216,215, 24,145,180, 37, 14, 50,102,207, +153, 77, 36, 14, 4, 73,213, 5,125,145, 12,234,113,195, 62,190,241, 2,191,110, 4,200, 30,222, 18,173,249,218,204, 5,110,173, + 82,154,185, 0,219, 64,114,136,255,138, 19,244,182,153,179,191,166, 14, 99, 56, 23,132, 90,150,104,141,202,115, 41,169, 26,185, +245,253,181, 36, 58, 84,170,186,142,128, 86, 44,109,173,107, 74,155,125,175, 93,251,133,192,151,243,178, 61, 50,222, 72,159,255, + 31, 95,250,124,250,131, 19,249,135, 71,118, 15, 71,238, 92, 38,238, 37,229,193, 34,188, 92,140, 7, 5, 94,170,198, 3,117, 56, +220,117, 18,174,146, 48,169,119,167, 99, 13, 99,140,205,117,212,205,194,148,227,212,175,122, 86,189,245,177,176,249, 60,188,142, +202,112, 88, 24,126,110, 70,143, 7,244, 15,206, 94, 49,138, 7,110,144, 4, 57,186,145, 86,150,176,198,196,160, 71, 85, 24, 84, + 25,212, 24, 21, 38,245,216, 86,189,235,100, 52,219, 93,120, 14,250,225, 0, 99, 67,110,193,170,248,140,195, 20,121, 56,160, 31, + 27,224,218,243,189, 58, 12,119,167, 0, 0, 32, 0, 73, 68, 65, 84,101,182, 51, 5, 71,243,141,195, 12,217,165,181,135, 42,234, + 27,187,244,214, 64,176,141,201, 62,255,215,203,140,220,155,144, 73, 60,183,251, 19, 25,238, 61, 64,150, 91, 40,183, 30, 98,114, +140, 77,189,167,147,236, 20,174, 18,252,236, 51, 63, 53,143,134,157,236, 57,196,171, 62, 85,228, 15, 93, 64, 46,112,241, 3,112, +249,103, 33,127, 3, 62,248, 22,252, 78, 11, 79,100, 64, 36, 94,196,179,190, 88, 53, 43, 12, 89,145, 81, 73, 23, 3,233,149, 9, +190,111,239,191,239,161,193,219, 11,246,238, 76,187,153, 89,142,198,225,172, 74,108,108,237,123, 51,159, 15,202,121, 54, 91,236, +232, 26, 27,127,138, 80,180,253,164,228,251,147,191,214,235, 59, 23,252, 61, 91,224,103,159,210,172,210, 74,195,110,154,111,126, +147,250, 6, 56, 70, 6,123,197,239, 1,113,188,152,188, 26, 4,184,197,231, 0,242, 32,147, 6, 69,159, 9, 90,141,220,162,141, + 74, 95, 60, 58,169, 76, 72,121,187, 6, 41,197, 67, 55,196, 38, 46,172, 68, 46,201,253, 1, 52, 24,241, 13,125, 28, 98,156, 18, + 54,243,178,209,169,104,125, 45, 13,107,228, 62, 26,161,226,118, 52, 25, 4, 25, 82,220, 47, 25,238,128,220,185,133,225, 30, 12, +159, 13,174,172, 1,123, 31,195, 60,250, 71,180, 47, 20,236,194,162,189,187,217,160, 56,163,218,157, 7,231,164,216,116,178, 12, +232,180, 67, 46, 46,225,226, 26,219,141, 14, 39,137,236,131, 84, 22,172,213, 72,213,234,161, 53,103, 18, 67,217,238,109,107, 17, +151,236, 50,113,127,221,181, 34,142,110, 93,173,216,178, 32,121,240,205,189,148, 77, 48,213, 89,218,189, 26, 73,217,121, 14, 81, +145, 19,249,223, 18, 29,160,170,137,162,138,229, 28,112, 41, 79, 14,147,230,182, 33, 48,114,246, 22,190,136, 39,165, 57, 30,217, + 92,200,213,140,214,138,183, 62, 7, 7,131, 72,107, 33,148,143,254, 74,140, 16, 68,206,208,219, 34, 46, 80, 76, 9,211,204,146, + 7,106, 30,176, 60,161,211,222, 81,210,105, 8,134,186,135,165, 44,230, 7,144,115, 98,158,157,105, 74,250,193,118, 58, 3, 98, + 73, 23, 69,245,192,151,102,190,145,152,145,205, 5, 87, 51,153,121, 94, 40, 22, 41,127,178, 89, 53, 27,155, 35,193, 86,125,200, + 70, 46, 84,201,174, 78, 95, 22, 74, 51,202,178, 80,235,178,110, 20,162,222,249, 44,157,146, 25, 66,182,182, 58, 32,218,217,125, + 21, 54,195,158,185,110,117,203,139,183,134, 68, 94,251, 74,148,139, 3,195, 42,100,238,248,214, 86,195, 73, 16, 80,171,179,180, + 41, 17, 33,229,145, 97,154,144, 52,176,148, 5,169, 21, 19, 87,161,151, 90, 86,165,189,217, 25,237, 80,117,205, 91,207, 57,147, +199,232,240,196, 1,167, 31, 94,218, 26,254, 19,202,255,176, 41,186, 88, 54,173,128,156, 46,112,236,188,118,213,228, 33, 58,170, +148,184,191,207,249, 23, 67, 30, 96, 24,144, 82,177,236,160, 29,106,217,210,236,226,224,224,243,254,188, 50, 1,122, 10,161,179, + 4,212,159,147,110,219,171,171,165,229, 67,184,237, 15,129,102, 94, 64,202,158,135, 64,100,251, 95,110,209, 79, 13,240, 35, 10, +159, 28,224,206,132,102,152, 30, 87,198,111, 26,252,118,131,175, 20,236,187,149,250,164, 82, 22,227,184, 52, 14, 2, 55, 98,220, +100,225,169, 9, 79,163, 61,191, 84, 56, 70,225, 90, 59,211, 57,102, 30, 37, 66, 67, 36, 42,246,163, 8,239, 42,212, 11,229,181, +121,225,238, 95,127, 76,250,142,192, 95,126, 9,125,115, 71,251,170,194,103, 34,244,113, 20,248,182, 32,143, 10,217,132,148, 42, +150, 98,209, 89,161, 21,134,142,186,149, 81, 30,216, 14,169, 98,247,119,112,167,193,147,131, 11,178,118, 6,247, 19,220,205,113, +196,238, 84,164,110,253, 48, 56,198, 21, 27,170,251,183, 35,217, 65,174, 67, 16,228, 41, 8,112, 87,209,107,131,161, 56, 98,118, +223,160,166,120,162,163,165, 93,159,122,151,224, 20,135,133,158, 35,154,204,219,187,223, 45,240,157,130,221,139,240,230,174,104, +147,234, 20,187,139, 56, 53,169,192,248, 38, 92,254, 24, 28,190, 2, 15,254, 9,161,228,193,102,247,209,134, 6,109, 5,179,240, +220,201, 17, 82,235, 85,168,207,179,184, 51,184, 64, 48, 80,145,148,182, 86, 84,245,156,101,189, 86, 26,231,173,172,176, 76,181, +109,211, 57,167, 45, 38,245,137, 68, 30,252, 16,193,148, 99,160,159,225,157, 91, 23, 93,197, 33,134,102,180,103,138, 94,248, 2, +205, 73,145,189,109, 38,104, 12,222, 45,216,151,158, 33,191,239, 14,242,112,244, 7,101,159,224, 39, 7,242,195,145,244,207, 14, +180, 71,179, 3, 72, 78,149,214, 10,197,220, 46,132,198,181, 89,129, 46,174, 74,239, 30, 36,105,206,185,111,181, 33, 82,145, 97, + 99,191, 90, 82,228,110, 70,174, 6,120,216, 28, 8, 4,200, 83,208, 91,176,157, 31, 76, 56,198,155,159, 21, 25,122,171,177,133, + 42, 62, 62,239, 83,133,111,103,120,229, 22,118,127, 15,118, 63, 14,195,143,132,177,116, 4,253,113,244,223,120, 5,253,155,111, +145,170,145, 66,113, 91,207,221,241, 1,186, 17, 4, 53, 63, 84,170, 38,223, 88,243,224, 21, 75, 53, 56,204, 62,103, 94,202,154, +238,226, 52, 70, 37, 15, 3,165, 41,181,154,191,103, 26, 90, 60, 65, 76, 37, 81, 83,138, 46,132, 99,114,125, 61, 86,239,172,168, + 98, 38, 88,202,232,110,196,106, 11, 54,249,128,236, 46,208,211, 28,156,116,175,222,172, 91,119, 36, 44,113,181, 34,230,130, 34, +143, 54,245,251, 37, 91,137,170,213,157, 13, 38,142, 65,117,108,157, 87, 80, 41,194,160,176, 70,138, 67, 73,130,160,167,137,251, +181, 25,144,113,128, 50, 99,102, 43, 44,198, 69,147, 78,152, 44,113, 0,110, 8, 45,101, 44, 57,236,166, 38, 65,135, 1,134,201, +237,142,154, 17,140, 82, 10, 66, 37,215, 25, 93, 78,228,200,193, 46,102, 31,130,118,166,228,143,107, 94, 89, 14,178,218,244,123, + 39,171,111,180, 53, 54,122, 81,111,197, 46,243,137,101, 41,158, 63, 17,113,167,137, 70,194,168,174,116, 12,171,152,109,163,147, +230,237, 34,107, 5,116, 88, 49,189,180, 74, 91,142,142,123, 77,121,125, 72,107,139,208, 39,210, 74,189,107,181, 63, 24,105,157, +237,183, 32,165,245,214,178,136,167,233,121,229,160,113, 64, 74,171,134,192,194,218, 74, 0,127, 86, 6,250, 89,122,217,106, 83, + 55, 99, 84, 71,225,142,195, 72, 27, 51, 50,187, 31,189, 90,163,198, 61,213, 90,228,194,155,160, 73,221,254,152,178, 87,203, 41, +187,112,143, 22, 9,106,178, 10,223,170,157,157,124, 3, 67, 75,116, 45, 45,249, 28,188, 44,209, 21,160,173,182,205,164,137, 33, +103, 52, 37,183,149, 6, 21,111, 85,218, 35,200, 48,208,106,139, 67,164,249,136,163,179, 15,122,167,164,235, 20,154,231,186,119, + 39, 64,159,235,183, 53,144, 74, 86,126,194, 71,123,207,237, 35,133,113,242,156,211,101,123,175,249,173, 95, 57,176,255,213, 35, +187, 44, 12, 59, 37, 93, 41,250, 70, 70,126,104, 64, 62,151,224,115, 19,118,255, 2,185, 49,134, 15, 26,249,171,198,238,139, 51, +247,126,103,161,189, 91, 89, 78,149, 83,109,220, 42, 60, 81,120, 60, 10, 55, 56, 64,238, 96, 27, 42,180,131, 72, 36,170,249, 73, +182, 40,203, 69,224,209, 36,164, 90,185,254,133, 15,188,205,250,151, 95, 66, 62, 57,193,215, 20,126,112,143,237, 78,160,234,130, +164, 99,246,211,193,209, 91,217,214,156,184,137,122,149,231, 67, 18,175, 74, 44,141,212, 87, 63,141,221,221,161,239,126,211,209, +176, 47, 53,184,111,174,176,175, 53, 72, 37,190,209,154,216, 25,146, 43,200, 68, 39, 67,238,157, 97,218,196,144,187,209, 70, 61, + 53,216, 3, 69,177,219, 80,185, 87, 28, 53,123, 87,195,166,117,240,121,249,162,222,210,239,189, 58,100, 83, 37,254,230,236, 21, + 90,242, 84, 52, 43, 21, 59, 86, 56, 84,218,169, 97,178,243,159, 41,234,116,146,225, 14,212,207,194,149, 87,145, 82,156,221,185, +212, 21,216, 70, 50,176, 49, 22,146, 53,111,193, 23, 28,153, 18, 58, 38, 31, 17,220,201, 46, 8, 19,117,181, 91, 87,154, 5, 62, +179,139,223, 90,124,102,185, 67, 93,162,149,111,155, 69,123, 75, 32,236,220,159, 8,141, 97, 23, 39,223, 41,124, 62, 9,248, 86, +193,114, 16,244,202, 86,229,154,121,117,110,179,107, 15,228, 94,246,141,189,199,174,189, 53, 99,251,103,200, 15,223,133,151,197, + 43,254,151, 12, 62,113, 23,249, 49, 33,125, 61,145,126,125, 71,125,107,161,220, 28,209,227,236, 24, 83,193,187, 61,153,205,206, +216,227,215,206,134, 85, 86, 27,237, 84,225, 54,218,149, 79,226, 90, 20, 69, 30, 36,236, 94,218,218,237,136,171, 72, 14, 29, 80, +232,159,175, 73, 67,170, 56, 0, 41,192, 29,235,124,162, 25, 60, 73,216,187, 5,185,122, 11,118,255, 39,220,249, 56,232,101,128, + 89, 30,192,195,215,208, 63,252, 54,252, 92, 35,221,137,241, 64,235,157, 18, 57,131, 9, 13,228, 72,168,210, 52,132,162,181, 66, + 93,226, 96, 86,189, 66, 26, 70, 44,169,111, 13, 18, 76,182, 82,144, 82,144,101, 33, 45,149,166,153,186,219,187,128,177, 95,151, +192, 68,163, 94,181,153, 66,121,250, 20, 59, 28, 28, 70, 19,212, 48, 29, 70,116,119,129, 13,131, 71, 94, 86,163,148, 5,171,213, + 23,215,210,182, 20,175,243,182,108, 84,110, 75,245,246,111, 27, 92,196,212, 59, 1,100, 69,107, 88,153, 52,121, 35,122, 89,200, +218,188, 29,175,130,204,133, 33,185, 34,190,106, 10,235, 21, 72,241, 64,151,108,142,186,173,103, 93, 14,149,234, 41,145,226, 17, +164, 86, 11,165,186, 32, 74, 69,208,211,193,253,239,217,173,115,102, 80,155, 35, 12,115, 31,160,231,201, 23,241, 84,145,214, 60, + 80, 37, 78,209,238, 93,223, 28, 33, 37,112, 20,205,188, 98,231,140,182,104, 18,207,106, 84,115,101, 89,162, 34, 55,106, 83,119, +143, 12,217, 63,218,210,104,197,239,175,231,225, 96, 45, 42,244,153, 52, 76, 43,163, 2, 29,161, 85,172, 26,181, 85,180,182, 53, +240,200, 34, 52,102,131,156,185, 34,218,219,236, 70,137, 16, 18,159, 84, 68,181, 94,159,239, 32, 18, 4,183,115, 76,234,154,216, +103,109, 85,215,182,126, 47,174, 9,114,230,241,186,211,158,105,127, 65, 26, 7,150,102,204,167,133,121,153,253, 94, 48,243, 42, +189, 85, 4,101,152,198,128,211,228,200, 56,240,251,184,181, 26,174, 28,215,126, 52,241,206,229,218,205,224, 57, 55,170,231,192, + 75,162, 45,243, 42,120,179, 56,240,174,227,195,148,104,170,110,237, 67, 72,121, 88,253,232,195, 48, 58,142,120, 89,214,131, 5, +185, 98, 53,196,163,182, 29, 36, 52,197,134,156,124,134,238,163,219, 45,111,221,171,110,221,170, 46,219,234,113,251, 30,114, 56, + 59,211,128,240, 34,175, 30,200,255, 56,114,212,247,139,177,171,149,171,167,133,235,183,102, 46,190,160, 92, 12,194,116,157,200, +175, 39,228, 71, 70,248,241, 17,249, 3, 3,246,167, 38,168,144,222,174,164,255,175,176,251,197,133,235,175,157,120,248,184, 49, +159, 42, 71, 26,143, 19, 60,201,194, 77, 8,130,139, 60,143, 16,237,164,177,169,251,134, 21,110, 51,140, 75,101,250,205, 39,240, + 95, 53,228, 47, 63,128, 31,188,128,127,161,200,247, 79,216,157, 1,222,159,144,247, 23,248,160, 97,143, 23,100,158,145, 42,207, + 39,107, 36,133, 57, 86,240,131,120, 40,202,245, 53,246,240,190,223,140,119, 26,236,139, 51,233,137,152,212,229, 12,145, 89, 3, +138, 82,193,118,138, 44,134,221,152, 87,179, 45, 54,253,172,176,111, 94,121,162,136, 85,159,141,223,198,162,253,122,242, 57,249, +238, 2, 78,199,144,144, 23,182, 94,106, 28,225,167, 16,212,189, 95,224, 37,241, 54,135,129, 29, 13, 59,248, 65,163, 29,219, 54, +235, 40,129, 23,179,147,127,117,168,192,168, 48, 38,210,220, 56,213,152,143, 6,231, 93,187,115,165, 17,115,178,132,236,146, 87, +234, 87, 25,121, 48,192,206, 33, 29, 54,183,141,140, 22,121,155,154,125,108,145,226, 20,174,230,228,178,174,161,168,109,227,204, +159,223,116,189,217, 48,164, 24, 81,140,201, 7,236,147,250,245,254,157, 19,114, 33,200,168,232,232,239, 77,162,180,177, 86,253, + 26, 29,154, 47,154,215,209, 55,183,120,177,175,159,176,252, 20,249,204, 93,208, 2,186,135,235, 31,133,151,175,225,205, 95,195, + 62,247, 91,164, 47, 8,250,203,153,242,254, 45, 44,139, 87,255, 1,190,247, 46, 92, 28, 0,149,231, 66,223,173,199, 87,222, 54, + 76,221, 18,213,129,230,214, 6,184, 55,194,125,117,187,157, 76,222,214, 93, 60,130, 81, 39,176,108,216, 98,125, 5,247,241,205, +178, 69, 82,130,193,105,129,119, 19, 60, 60,193,238,215, 97,255, 79, 97,250, 41, 23, 88,200, 29,224, 14,250,231, 39,210,207, 85, + 82,115, 14,195, 18, 84, 20,141,177, 65, 78,222, 45, 82,107,164,148, 2,140, 83,250,240,149,170, 25,147,236, 29, 4,107, 1,155, +153, 93, 77, 94,155,227, 62,155,243, 33,116, 24,104,227, 62, 14, 47, 33,205, 83, 9, 13,137, 87,236,173, 6, 31, 33,135,109,172, + 86,154, 86,207,208, 62, 29,145, 60,146,246,123,200,147, 87,152,116,178,154, 56, 76, 72,166, 16, 57, 85, 15, 2, 41, 37,102,185, +174,153, 47, 34, 17,237, 90, 17, 51,170, 10,102,213,231,155, 49,147, 7, 99, 10,198,190,228, 76,198, 96, 26, 97,186,164, 78, 59, +210,188,128, 46, 44,117,113, 44,180,120, 37, 88, 17, 71,165,246,172,117,105,254,115,211, 6,153, 49,171,110,229, 19,208, 38,206, +167,168,149, 90,107,204,191,235,154, 24,111,117,107, 69,155, 38, 39,218, 37,159,229,167, 86, 25,164,173, 27,250,233,140,229,223, +187, 91,216, 25, 93, 44,100, 60,162,202,177, 20,150, 90, 87,202, 91,177,198,128,144, 98, 99,211,148, 61,195, 94, 92, 83, 96, 18, +204,249,200,168, 71,132,188,191,164, 28, 15, 80,139,119, 20,243, 68,107, 39,170,249,238,155, 87,216,225,166, 77, 50, 9,197,184, +166,216,224,219, 25,101, 48,116, 10,210,206,136,112,182, 30, 4, 86,237, 68,216,197,172,143,116,154, 87,217, 91, 76, 96, 88, 93, +115,246,224,157, 33,147, 52, 57, 79,127, 41,204,165, 82,202,236, 7,227,206, 68, 23,111,117,167,113,242,141, 53,190,223, 67,124, +188,171,150, 12, 36,167,117,102,237,159, 83,132,211, 6, 55,163,213, 18,173,117, 89,113,183,198, 86, 65,119,114,167, 11,106,147, +243, 22,102, 31, 93, 16,116, 56, 17,101, 24,132, 52,142,222,180,237, 17,198, 61,165,206,156,210, 41,105,235,112,184, 83,172,190, + 48, 35,119,167, 76,171,171, 49,207,133,216,108,162, 82, 59,115,160,219, 71,196, 90,159,195,225, 95,252,174,252,229,197,188,106, + 22,200,205, 5, 69, 89,225,130,198,117,129, 7,239, 23, 30,190, 7,119,190,116,224,234,111, 37,198,187,137,225, 83, 35,242, 71, + 38,236,247,143,216,159,184,128, 63, 45,200,163, 70,250,157,194,197, 47, 47,236,127,253,196,189,239,158, 88,142,149,185, 54,110, + 7,113, 33,187,186,237,104, 6,154,186,144,164,198,252,189,152, 48,155,113, 51,129, 46, 30,246, 98,255,109, 66,255, 35,129, 31, +190,192,126, 59, 33,159, 29,177, 35,240,237, 25,190, 60, 35, 39,193,170,120,123, 60,157,209,213, 74,108, 16,178, 64,109,232,119, +223,130,203,167,240,202,222,231,162,185,249,124, 32,141, 62,172,173, 17,174,210, 43,137,106,216, 28, 11,127,113,178,154, 28,138, +179,214, 59,236,185,246, 40,167,120, 90, 71,133,151,212,155, 51,115, 12,146,175, 7, 63, 68,156,138,183,193,151, 80, 24, 31,227, +233,206,226,173,227,155, 6, 79,189, 36,182, 83,156,118,187, 42, 71, 67, 29,216,177, 98, 43,255,245, 25, 44,191,238,135,151, 69, +125,244,144, 29,166,146,130, 91,189, 52,176,131,145, 6,143,164,213, 20,200,220,193, 55, 89,149,128,172,236, 6,239, 73,159,218, +243, 97,215,230,194,136, 20,196, 52, 11,244,169, 74,231, 39,199,223,117,243,176,219, 70, 7,101, 8,221,133,230,128,198,236,146, +107, 7, 46, 7, 23, 62,190, 91, 87,224,140,180,230, 35, 14,195,243,225,155, 34,131, 97,218,252,134,121, 26,194,201,148,253,115, +154,178, 3,122, 46,158, 32,111,188, 12,135, 35,180, 59,176,255,183, 32,255, 37,228,226,239,193,197,127, 7,211,129,252,143,174, +144, 15, 14, 94, 57,186, 36,117,179,151,232,153,194, 79,227, 51, 9,152,139,149,134,221,198, 98, 36, 6,143,226, 48, 86, 4, 30, + 12,216,189,209, 53, 14,217, 63, 91,185, 1,158, 9,146,131, 60, 23, 7, 67,159, 67, 4,146,167, 11, 78, 26,206,237,255,160, 32, +151,239,194,205,207,195,240,105,247,173,235, 4,250, 83,200, 27,191,140,190,158,209,239,156,152, 46, 61,195,187,246,200,220, 36, +228, 88,220, 68, 70, 68, 51, 84,159, 71, 10,174,242,182, 90,124,243,172, 62,255,108,226, 42,255, 26,149, 73,141, 42, 76,114, 70, +242,228, 85,123,199, 47, 71, 6, 4, 75,217,136,115,181, 4,246, 85,176, 97, 8, 50,153, 83,199, 90, 53, 88,102,172, 84,116, 60, + 65,158,220, 74,150,167,245,126,160,248, 1, 96,141,192, 76,201,253,254,134,255,190,209,146, 84, 77, 94,205, 90, 99,142, 10, 44, +229,236,135, 9, 19, 74, 54,234,168,107,117, 92,135, 29,146, 71, 70, 17, 74, 30, 97, 62,209,110,235,218,113,104, 98, 43,168,197, + 90,245,138, 61,208,183, 26, 50,120, 85, 65, 99, 4,211,158, 19, 35, 57, 78, 90, 52,121,219,182, 86,172, 45,219, 92, 75,148, 20, +248, 64, 77, 3, 50,141, 36, 42, 99, 89,160,250, 6, 93, 59, 82,180, 19,131,215, 42, 51,110,195,216,188,172, 25, 75, 93,188,179, + 97,193,221, 15, 65, 94,238,177,162,109, 19,164, 33, 9,197, 91,233,162, 33, 34,107,133,122, 60,160,227, 68, 61, 25,182,212,136, + 27,245,158,125, 13,162,166,132, 69,211,226, 61, 16,221, 17,135,166,132,229, 81, 66,240,169, 1,117,169,177, 70, 69, 43,187, 61, + 23,155, 26, 91,139,181, 16,117,122,152,137,133, 45, 80,146,146,243,232,225, 39,225,139, 47,165, 96, 82,215,177,145,157,253, 28, + 49, 97, 76, 35, 50,106,204,164, 99,105,106,117, 61, 84,136, 36,134,232,122,216, 89,220,116, 78,201, 9,143,177, 73,214,142, 85, + 12, 18,161,196,193,196,171,253, 20,156, 15,141, 66,197, 29, 8, 37, 0, 60,173, 5,231,192, 42, 25,193,210, 64,105,222,125,106, +165,197,178,108, 43, 80, 38,169,250, 1,163, 69,236,113,173, 33, 48, 13,205, 65,117,193,162,167, 94,182,176,152,198,181, 93, 67, +185,228,123, 10,228,214, 42, 93, 94,228,208,108,147,247,124, 91,225,131, 56,189,105,204, 69,122,108,233,133,194, 78, 60,154,243, +158,192,131,218,120,240,110,229,213,119,103,238,127,225,150,139, 75,101,248,248,132,254,145, 29,246,199,247,240,123, 6,236, 39, + 46,224,105, 67,190, 50, 51,254,226,194,248, 47,142, 92,126,119,230,193,161,112, 59, 55,158, 42, 60, 27,133,219, 24, 43, 31,101, +139,143,208, 32, 53,230, 1,212, 10,249,219,207,104,255,131,160,255, 62,200,103,175,176,247, 12,185,239,155,177, 29,131, 2,247, +182,250,238, 53, 5,147,177,212, 77,205,181, 23,111,181, 78, 21,238,220, 64, 59, 98,179, 35, 15,209,140, 77, 13,169,147, 63,184, + 41,146,217, 78,165,251,128, 66, 3, 21, 96,148, 20, 54,183, 59,195,115,209,124, 44, 49,184, 22, 65,238, 77, 62, 87, 47,192,221, +228,135,128,229,128,149, 32,163,244, 77,221,226,130,167, 64,212,254,230, 1,150,134, 93,130, 29, 10,246,172,110,225,228,241, 64, +112, 39,210, 90,108,128,241, 83,193,164,252,142, 19,217, 58, 35, 85,188,221,155, 22,235, 33,104, 20, 17,108,113, 27,155,142, 49, +251, 24, 18, 58,170,207, 13,175,146, 75,211,163,213,202, 77,141,124,118,127,111,238,108,144,181, 5,223, 21,245,253, 32,143,201, +202,124,239,205, 7,139, 42,126, 80, 15,145, 75,131,122,151,227,110, 14,139, 66,130,223,121,134, 61, 94,176,215,187, 39, 40, 4, + 23,139,159,250,156,135, 28,106,242,165,109,171,225, 16,194,201, 33, 98,125,127,235,128, 77,143,145,151,238,194,241, 31, 66,249, + 41,216,255, 17,200, 63, 13,118,131,252,161,255, 9,134, 35,249,103,119,200,141, 80,106,241,214,250, 25, 67, 86,244,108,115,175, +125, 1,118, 95,117,107,134,158,234,154,220, 68, 57,185,205, 82,128, 7, 25,185,202, 30, 14, 36,138,188, 29,179,224, 67, 13, 59, + 78,111,109, 38, 79, 43,236, 89, 3, 57,200,110, 75,131,167, 10,203, 2,243, 91, 80,223, 1,153, 64,238,193,248,167,225,206,255, +140,254,177, 70,254, 63, 38, 76, 11, 23, 97, 23,109,173,249, 25, 52,103,200, 59,191, 79, 79,199,128,123,120,123,166,206,133,186, + 84,154,149, 21, 41,155,186,234, 60,178, 19, 90,180,254,210, 48,122,136, 71,100, 38,180, 26,149,189,197, 40,164,127,175, 66,109, +226,155,189,132,206, 0,127, 14,181,187,108, 69, 98, 62,191, 68,186, 91,168,239, 99, 67,110,167, 19,173,206,171,189,135, 14,250, +104, 94,117,169, 40,150, 50, 77,189,147,196, 52, 98,201,171,116,137,236,238, 74,117,122,153, 25, 69, 71,218, 82, 24, 14, 55, 78, +248, 34,193, 82,208, 90, 86,183,192,210,124, 62, 75, 11, 24, 72, 87, 74, 18,224,153,240, 53, 73,191,215,215,249,127,143,104, 45, + 46,188,142,182, 45, 75,241,217,126, 2,165,117, 84,149,199, 66,227,179,107,221, 93, 80, 85, 97, 62,193,241,228,149, 98,124,223, +220, 54, 22,122, 86, 33, 27, 40,149,210, 95, 39,150,251,190,102,151,160,252,229, 96, 46, 44, 86,157,185, 46,190,142,121, 0,157, + 5,190,181, 32,183, 79, 25,199, 29,146, 7,218,241, 22,149,192,188,182,138,217,226, 51,231,228,130, 97,103,192,119,165,127, 13, +104,239,246,254, 45, 41,174, 61,235,163, 5, 57,195,156,186,213,108,181, 94,181,182,165,243, 53,223,176, 82, 14,177,162, 38, 74, +107, 44, 37, 44,107,205, 28, 11,156, 61,148,198,186, 54, 64,132,156, 7,114,118, 66,158, 9, 46, 84,171,171, 12,209,109,205, 57, + 99, 42,148,165,132, 3, 34,236,139, 34, 12, 73,227,250,137, 87,243,173,249,216, 49,126,151,166, 10, 75,241,131, 78,192,107,170, +128,182,186, 6,252,132,247,114, 21,203,250, 60,222, 29, 24, 22,179,114,107, 45, 28, 51,234,203, 73,159, 73,226,163,189,222, 33, +235,182,189,166,186, 10, 29,215, 89,154, 74, 64,127,218, 11, 1,172, 31, 81,165,191,152, 42, 39,231, 2,185,109,204,144,254,192, + 94, 63,223,139,200,163,193,108,226,130,183, 22, 73,108, 45,144,213, 38,188,103,240, 45, 17,190,153,132,239, 40,188,127,106,156, +222, 91,224,139, 71,210, 63, 56,146,126,225,132, 62,110,240, 70,130, 31, 24,225, 39, 39,248, 67,123,228,205, 29, 58, 12, 76, 71, +229,242, 88,185, 92,140,203, 30,240,209,125,123,177,182, 75, 4, 66, 37, 13, 81,221, 98,216,111, 25,242, 3, 9,121, 35,195,219, +230, 22,178,251,142,108,229,158,248, 6, 58, 70,117,124,111,128,171,193,255,173,207,111,115,194, 87,196,134,220, 46,126, 50, 46, + 11,210, 15, 0, 75,236, 84,199, 88,236,107,136,153,196, 85,234, 82, 28, 94, 66,210,168, 22,117,203,249,124,142,210, 31,253,238, +189,122,238,249,157,228,172,203, 18, 39,152, 83, 92,228,110, 85,187, 8, 31,253,223,125,134,205,197, 5, 99,207, 10,237,209, 18, +254,231,104,127,215, 68,122,243, 18,249,253,123,144, 17,174,127, 26,242, 67,223,196,126,247,171,216,111, 66, 45, 75, 84,184,182, +182,250, 56,219,132, 83,204,210, 73,138, 94,103, 23,155, 92,142,240,241, 61,242,210,206,223,219, 51,131,247, 78,240,120,161, 61, +153,169,207, 22, 63,117,203,115, 41,134, 94, 69,233, 38,154,227, 5,230, 58, 34,140, 34,236,146, 31, 12,243,229, 64,126,117,143, +188,186,131,215,246,240,242, 0, 95,124, 74,251,242, 45,118, 41, 91, 37, 59,168,123, 75, 3,122, 46,221, 42, 22, 10,236, 62, 64, +236,137,181, 82, 5,116,240, 46,199,117, 69,174, 39,120,246, 15, 97,124, 3,134,215, 32,127, 26,166,215,145,135,191, 1, 23, 71, +244, 59, 25, 89,100,141,141,117, 11,154, 70, 91, 92, 86, 64,189,104, 90, 57,201,231,246, 64, 66,113,237, 76,228,248, 12,119, 26, +163,143,205,168, 44,221,188,172,226,153,215, 35,200,190,219,220,196,131,140,114,228, 6,236, 19,114,183,193,120, 5,187, 79, 65, +254,184,163, 99,211, 61,224, 55,144,139, 47, 99,191, 58, 96,183, 46,222,179,218,168,166,200,176, 67,246,147, 87,142,203, 66,173, +149,138, 82,154, 58, 64,163,122,151,234,124,218,211,149,178, 45, 54,105, 65,169, 50,210, 36, 69,104,134, 87, 12, 93, 84,103,182, +109, 88, 22, 45, 88, 59,135,128,212, 13, 71,234,239,103, 64,198, 93,159,109,108,243,204, 97,192, 82,222,146,163, 67,216, 83,197, +253,209, 18,149,176,228, 33,190,124, 83,148,253,133, 91,169,140, 32, 49,122, 53,163,101,102,160, 81, 82,102,174,149,118, 56, 58, +220, 72,140,211,233,200, 50, 31,161,245, 48,164,110,212, 98,157,211, 98,205, 59,146,201,159,229, 6,212, 26,232,219,213,193,177, +129, 86, 4, 23,160,182,148, 61,215,178,121, 68,236, 16,238, 14,119, 63,170,171,229, 53,185,166, 96,220, 33,215,247,176,253, 61, +170, 36,183, 69,213,122,230,179,246,194, 33, 99,164,228,135,196,197,132, 83, 21, 90,228,244,249, 51,213,179,201,187, 56,181,115, +243,195, 82, 22, 15,157,230,140,232,232,127,166,228, 42,111, 17,202,233,224,155,117,202,190,177,135, 77, 46,231, 17,212, 69,102, +173,213,149, 69,222,211,248, 68, 4, 13,123, 92,171,238, 73,151,190, 0,196,252,255,220, 98,166,225,175, 23, 81, 7,202,228,236, +155,168,166,168,202, 23,202,105,166, 84,199,213,106,210,192,254,194,144, 51,211,232, 97, 46,118,174, 60,151, 62, 51,119,225,174, +158,165, 32, 54, 51,106,109,212,110,201,107, 27,139, 67, 84, 73,162,228,193, 35, 92,171, 53,218, 82, 72,154,200,195, 16, 29,155, +182, 22,146,162,178,206,213,205, 44, 28, 33,222,181,144,184, 46, 73,125, 92,160, 42, 36, 52, 68,143, 45, 14, 44, 26,174, 44,167, +203,137, 38,135,251, 68, 40, 76,199, 71, 91,160,106,183,232, 97,255,236,106, 41, 62, 26, 92,119,194,239, 81,165,235,139,161,235, +155,100, 78,206,182,245,244, 83, 23,250,121,214, 28,245,152,127,219, 86, 88,206,205, 79,150,135,232, 16, 63,109,240,212,132,247, + 27,124, 71,132,111, 37,225,219, 34, 60, 58, 85,234,123, 11,250,207, 14,164,127,112, 75,250,245,130, 92, 24,188, 49,194,103, 71, +228, 39,247,240, 99,123,244,114,100,168,153,221,177,113,117,104, 92,182,240,126,246,152,164,190, 87, 42,100,179, 80,185, 26,246, + 85, 67, 62,149,145, 55, 6,236,253, 6,151,134,220,207,112, 21, 39,250, 34,222,166,189, 12,113, 90,247,171,140,177,240, 7, 5, +142,147,192,222,206,200, 95, 45, 44, 58, 46, 18,243,232,190, 32,183,168,251,163, 93,169,146,145,166,112, 61,250, 70,220,129, 10, +242,194,160, 67,146, 31, 42,238, 69,148,231, 28, 28,213,131,249,151,157, 33,137,238, 13,112, 91,177,127,126,194,172, 80, 31, 23, +152,227, 67, 63, 86, 23, 9, 13,137,100,137,244,169, 61,242,185,236,232,185,235, 63, 3,249, 62, 28,255, 31,248,157,111, 96, 95, +129,182, 20,183, 29, 45, 22,194,159, 77,237,174, 94,156,175,158, 73, 29,148,116, 53, 32, 15, 70,228,245, 29, 60,112,118, 51,143, +102, 87,151,223, 46,212, 39, 11,237, 89,241, 86,165,156, 89,169,206, 38, 16, 93, 28,109, 47,228,103, 39, 96, 76,226,103,170,172, +228, 59, 19,249,149, 11,248,248, 14, 94, 27, 97,202,216,223,124,159,118, 90,176,125,119, 16, 90, 8,204, 92,197,207, 18, 91, 64, + 63,116,133,135,157,232, 26, 88,232,211, 56, 52, 79, 12,123,188,192,125, 65, 46, 47,225,217,207,195,248, 50,140,159,134,225,115, +176,251,125,112,239, 23, 64,110,208,183, 50,178,180,192, 71,134, 96, 78,116, 75,156,145,228, 78,138,236,178,126, 57,179,185,117, + 90,137,172, 89,156,145,228,177, 87, 63, 60,142,186,217, 94, 10,235, 34,168,200,234,113, 39, 71,252,108, 22,100,231,240, 7,185, +223, 96,186, 11,187, 55, 97,252,193, 24,244, 78, 32, 63, 0,227,255,133,164, 19,246,203, 13,180,208, 82,102,217, 95, 99,121, 68, +151,197, 63,247,158, 53,222, 51,156, 91,136,228, 58,205, 74,207, 5, 85, 97,137, 18,165,229,193,231,238,230,243, 61,234,130,198, +102,184, 5, 79,184,218,121,197,134, 55, 91, 15,121,182,210,202,163, 89, 21,222,111,207, 62,238, 66, 14, 69,198,201,133, 71, 61, +100, 36, 84,213, 68,101,168,195,228, 22,188,156,145,156, 93,232, 53, 14,206, 14,215,204,134,142, 87, 20, 35, 91,245,199,217,224, + 52, 23, 76, 51,121,183, 39,103,165, 56, 72, 53,126,126, 67,107, 69,251, 98, 77,119,148,184,120, 51, 7,115,176,169,210, 52, 14, +148, 91,244,218,218,154,150,168, 66,155, 38,167,217,117, 95,187,217, 74,228,157,205, 81,178,164,236,139,188,184,138,123, 54,133, + 60,110, 96,156, 90, 86, 11,220, 42, 52,239, 26,208,230,108,248,118, 78,241, 59,247, 99,139,146,212, 86,232, 80, 99,131,188, 88, +231,185,231, 33,220, 17,190,185,149,101,246,247, 20,155,156, 14, 83,164,254, 21, 90, 93,188, 61,220,159, 39,250,198, 44,225,162, + 72,190, 89,245,226, 75,210, 58, 54,241,239, 75, 46, 20,203,206,142,239,110, 12, 19,168,214,220, 78, 87,252,192,217,149,229, 26, +188,248,156, 7,134, 97, 96,202, 35, 87, 87,215, 92, 93,221, 97, 24,119, 44,101,161,149,226,153,232,177,161, 75, 44, 64, 61, 96, +168,197,140,186,243,231, 83, 74,228,148,200, 67, 38,231,129,148, 51, 57,126,159, 82,235,115,155,117, 39, 50, 82,155,111,208,209, + 5,178,208, 77,208,186,126, 98,115, 0,117,208,140, 35, 95, 59, 66, 55,186, 23, 42,107, 40,210,134,166,141, 67,155,109, 82, 90, +215,132,168,199,209,174,174, 65,191, 38, 53, 68,173,172,225,192, 31, 45,142,227, 12, 58,213, 13, 90,124, 68,168, 75,250,227, 23, +250,249,116,118, 70, 72,231, 85, 89,220, 80, 35,155,183,188, 70,245,126,219,188,176,125,210,124,212,248,190, 10,223, 76,240, 78, + 18,110,231,138,124,253, 68,254, 71, 7,242,207, 31,145,167, 1, 13,121,115, 68,126,255, 30,249,189, 35,242,241, 29,169,100,166, + 34, 92,206,149,203, 98,140,157,250,117, 38, 22,206, 61,202,185, 24,246,117, 67,190, 63, 35,223, 63,194,141,227, 68,229,101, 65, +174,171,111,238, 67,248,232, 58,111,187,111, 57,115,180,119,251,134, 93,226,196,153, 3,204,108,134, 52, 87,176, 58, 38,237,140, +176,221, 89,144,139, 67, 73,184,159, 87,178,155,156,103,123,118, 26,192, 36,112,119,240,116, 54,139,120,167, 78,143, 59,181,205, +155, 62,136,207,144,223, 94,144,155,234,169, 89, 55,197, 55, 52,154,255,169,130,238,188,165,168,159,186, 64,126,104,242,138,229, +242, 95, 2,189,128,155,191, 3, 95,121, 27,251,186,209,202,236,179,255,110, 43,209, 51, 5,186,194,144, 61, 46, 74,114, 66,115, + 66,119,163,167,145,189, 58,186,242,253, 84,177,183, 79,142,230,125,186,208,110, 10,237,166, 6,210, 81, 54,255,118, 88, 48,180, +135,151,172,139,190,172, 30,204,172,206,188,222, 53,152,118,153,244,112,135,126,108, 15,175, 15,240,234, 30,110, 10,252,253, 71, +180,177, 98,251,104,231,214, 56,136,244, 21,235,133, 59,216, 96,107,155,198,120,193,154, 95, 83,185,169,254,217, 60, 43,225,106, +184, 7,207,126,201,199, 20,227,247,129,126, 12,201,111,194,245,207,195, 7, 11,250,118, 66, 6, 54,133,102, 15,161,201, 26,194, +108,137,185,229,243, 38,112, 89,229,202, 81,217,247,194,107,192, 15,122, 23,217, 31,150,238,146,168,108,200,200, 28, 66,193, 28, + 85,206, 20, 80,138, 75, 65, 30, 8,236,238,193,229,167, 97,248,161,240,172, 23,200,175,130, 86,228, 99, 95,128, 95, 22,218, 7, +123,236,222, 21,173, 37, 90, 57, 33,181,250,226, 46,157, 67,219,168,225, 61, 79, 49, 62,168,125, 97, 9, 74, 26,189,189,171,147, +255, 25,240,141,182,156,192, 42,231,241, 19, 22, 7,133,126,232, 49,149, 51,175,176,108, 56,203,179, 46,142, 87,184, 81,237,229, + 17,221,237,124, 35,204,131, 87, 37,125,129, 15,191,183,230, 1,166, 41,116, 34, 1, 30, 10, 59,144, 87,139,121, 93, 24, 53, 37, +134,105,199,184,223, 49, 12,131,207,160,155,209, 46,174, 24,118, 59,111, 77,207, 39,230, 16,224,181,214,220, 86, 22,141, 19,123, +206,153,225,170,114,111,165,198,248, 44, 15,126,160,227, 60,224,101, 83, 37, 55, 51,135,153, 12,147, 91,250,226,126,240,184,205, + 46,238, 12,181,183,192, 82, 42,203,241, 72,149,112, 31, 72, 70, 8,145, 32,178, 6, 13,245,235,183,152,135,224,212,224, 6,120, + 14,189,172,248,223, 14, 81,146, 72,131,179, 46,244,236, 33, 55,214, 66,247, 96,107,215, 99, 37, 72,228, 1, 29, 6,100,152, 64, +149, 58, 31,195, 15,206,170,196,182, 94,241, 70,184, 75,175, 38,219, 89, 72,139,177,205,126,207,193, 41,173, 85, 90,113, 97, 92, + 53, 91,253,222,221,175, 45,154, 24,242,192, 52,237,152,118,123,118,251, 11,198,221, 5,121, 28, 25,226, 96, 80, 69, 56,205, 51, +243, 50,111,155,113,101, 3,208,148,186,122,212, 29, 96,163, 12, 57, 51, 78, 35,121, 28, 72, 41,123,213,159, 28, 92,116,106,141, +211,233,232, 87, 71, 29, 80,147,146,227,134,172, 22, 15, 22, 10,203,101,105,174,152, 95,187, 80,237,172,117,190,242,225, 67,140, +152, 18,165, 54,164,109,241,170, 61,160,197, 98,195, 95,115,145, 59,201, 46, 66,175,172,148, 51, 12,108,243,217,252, 82, 34, 48, +233,249,198,175,189,152,233,242, 28,223,250,195, 62,246,117, 83,255, 87, 46,245,243,221, 75,201,202, 4, 63, 19, 5, 71,129, 59, +156, 1, 76,242,198, 12, 98,110,193, 82,105,198,147, 38, 60, 70,120, 79,132,119, 70,225, 89,107,148, 71, 11,195, 23,111, 25,126, +230,128,188, 83,225,245, 12, 31, 31,145, 31,220, 33, 63,234, 16, 18, 33, 49,204,202,238,212,216,151,198,132, 48,196, 60,163, 31, + 56,100,114, 1,156,125,179, 33,159,136, 86,124,141, 56,210,187, 47, 35,247,223, 69,174, 12,230,209, 45, 72, 68,203,251,253,230, +170,243,254,238,151,186, 65,202,119, 17,126,221,179, 42,171,251, 58,233, 74,210, 98, 62, 3, 40, 13,230,134, 92,171,119, 2,166, +141, 47, 28, 12, 84,175, 34,171,248, 2,255, 90, 68,164, 30, 98, 54,222,249,186,199,182,109, 2,187,152,185,255,179,163,171, 74, +123,158,108,109, 88,177,104, 9, 25,210,212, 83,148, 62,121,137,124,106,130,227, 9,246,159,241,159,243,228,239, 98,191,113,139, +125,123,161, 30,150,149, 52,117,238,120, 92, 63,175, 93, 90,147,235,210, 46,163,187, 1,121,121, 68, 94, 25,124,179,121, 86,224, +237, 5,110, 10,237,102,161, 61, 41, 62,131,169,103,172,136, 51,115, 65,143,162,238,247,110,183,143,244,255, 63, 70, 30,207,112, +119, 34,191,182, 67, 62,177,115,161,226,131, 9,126,251,150,246,171, 79,104,151,177,226, 86,217, 4,101, 97,167,179,210,177,136, +242, 33,210,130, 21, 91, 45, 21, 86,170, 7,128,156, 26,178,100, 63,117,222,175,200,197, 61,184,249, 5,200,247,124, 84, 33, 15, +125,211,126,233, 75,240,172,161,143, 60,234, 83, 7,117,234, 94, 74, 17,131,217,103,174, 65,152, 27,206,218,159,189,101,177,248, +109,227, 51,246,184, 40, 23,129, 88,220, 7,215,126, 58,123, 96, 36,136, 76,187, 51,219, 71, 7, 97, 92, 11,114, 23,216, 95, 59, + 84,104,248,108,248, 51,139, 31,167,211,143,192,248, 27,200, 75,223,160,254,191, 23,200, 48,187, 78, 35, 88,219, 45,176,158,181, +122, 44,101,179, 80,218,170,160,155, 51,115,157,123,150,230, 25,229, 69,148, 22,115,213,186,204,190, 32,191,176, 94,116,104,204, + 26,195,186,130, 79,116,253,255,235,124,181, 15,160,243,132,236,246,174,204, 28, 28,120,211,230,217,171, 20, 51,218,233, 16, 7, +136, 0,132, 12,227, 10,142, 89,169, 99,181,184, 2,190,206,104,168,143,181, 44,100, 53,134,120,196,114, 74,180,221,158,101,127, +151, 50,236, 17, 49,210,241, 25,203,233,224,222,226,160,228,229,112, 95,244,228,184, 94, 89,245, 67, 73,141,153,105,194,153,239, + 41,103, 76, 18,165,249, 38,222,191, 44,132, 80,158, 49,159,145,193,121, 0,222, 6,174,103, 78, 36,223, 32,139,102,170, 37, 74, + 53, 74,153,177,148, 72,227, 30, 77, 3,182,156,188,136, 72, 66, 90,129, 53, 74, 21,165,116,109, 37,186,197,230,198,161,179,187, + 77,232, 48,159, 8, 49,105, 43,124,198, 86, 97, 27,154,125,116,209, 59, 71, 42,171, 77, 81, 82, 38,143, 59,119, 72,212,176, 14, + 70,229,173,154,221,186,184,230, 1,120,181,124,150,250,179,181,231,213, 19,208, 52, 90,253, 73, 93, 79,144,243, 72, 26, 38,210, + 48,248,124,124,220, 49,140, 19,105, 24, 73, 99,142, 72, 84, 71,187,150,226, 85,170, 6,168,102, 41,133,101,153, 93, 68,215, 2, + 69, 27,179,124, 81, 37,167,196, 48,100,118,211,196,126,191, 99, 26,167,240,148,103, 6, 85,246, 67,230, 42, 14,126, 39, 51,150, +121,118,199,131,193, 24,223, 87,154,235,144,114,206, 62,235, 22, 88,150, 18, 35,158,179,248, 98,117,144, 12, 41,175, 89,242, 43, +212,166, 99, 99,131,159,161,189,245, 30, 29, 64,108, 27, 21,244,103, 44,117,167,242, 0, 0, 32, 0, 73, 68, 65, 84,213, 2,117, +107, 42,235,251,106,181,185, 11,228, 67, 91,249,134,131, 94,207,149, 31,218,208, 95, 76,107,243, 93, 63,253,153, 43,253,252,208, + 23,224, 88,123,186,117,122,138,117,104,165,197, 1,163, 74,108, 20,209,221,142, 53, 45,120, 59,204,205, 71,179, 39,132, 15, 68, +120,127, 16, 30, 39, 40,183,133,225, 75,183, 12, 63,115,139,188, 85,176,215, 18,242,137, 29,242,233, 9,249,236, 8,175, 15, 8, +153, 52, 39,198, 5, 6, 19, 6, 2,152,159,226,166,235, 66,170,247, 64, 94, 85,120, 21,183,119,229, 63, 15,211,159,130,253, 23, + 16,169,112,155, 92, 16,112,219, 98,134,221,251, 91,241,165,241, 97, 76, 93,201,206,166, 72,182, 13,170,237,192, 13,231,121,203, + 24, 15,198, 40,200,133,183,234, 66,214,186, 17,184,150, 96,162,190, 26, 61,181, 67,164,222,116,224,204,201,182, 54,242,117,246, +139,245, 43, 71,108,140, 14,193,114,150,252,165,226, 27, 78,206, 36,201,200, 39,247,200,247,141,112,123, 11,151,159,112,213,254, +119,126, 17,190, 80,104, 79,139,183,164, 74, 91, 3, 95,186,152, 59, 53,208,125, 66,246, 25, 25, 18, 58, 37,116,151,209,171, 1, + 94, 30,144,251,147,223,200,143, 11,188,183, 96, 55,133,118, 91,176,165, 98,179, 69, 71,218,182,112, 22,221,114,217,123,219,175, +173,247,153,172,212,186,157,194,152,149,252,210,158,244,230, 5,124,108,231, 27,250, 85,194,254,238, 35,236,189, 35,118,135,149, +173,105,241,160,117, 69,241,230, 1, 58,123, 72,122,128,117,243,246,153, 45,109,107,213, 47, 21, 57,178, 34, 25,185, 94, 96,119, + 31,185,249, 85,168,223,138,159,251, 25,184,184,143,188,241,101,184, 56,109,145,149, 54,120, 59,113,136,154, 71, 53,108,111,178, +126, 22,146,211,246, 16,213,232, 38,245, 3, 71,104, 31,188, 13, 63,120, 39,103, 12,233,255,160, 91,103,102, 12,147,127,207,181, + 22,137, 74,221, 96,186, 15,251,143,195,248, 57,188,141, 16,237, 11,189, 2,249, 17,228,213,127,136,252,220,219,180,223,109,112, +173,180,192,180,174, 95,173, 82,173,198,218,235,236,246, 30,149, 91, 99,173,232,183, 71,147,180, 85,233, 1,247, 96,157,120,111, + 49,160,125,145,168, 56, 34,182,217, 89,115,176,123,107, 37,230, 59,226, 56, 89,157, 70,167,197,105,162,206, 39,150,195, 13,237, +120,235, 18,148, 90, 87,242, 25,165, 56, 93,110,218,249,134, 88, 74, 55,139, 97,197,199, 0, 98, 37, 58,104, 11, 58, 31, 25, 78, +183, 12,243,145,100,190,218,212, 52,178, 92,222,167, 93,222,117, 94,247,211,119, 93,113, 46,137, 66,168,219, 99, 39, 92, 44,180, +198, 42,219,134,165, 94,241,246,251,214, 85,232,158,223, 62,147,125,182, 26, 85,108, 86,103,175,215,230,115, 39, 49,200,121,192, +134,145,182, 44, 94,221,139, 31,120, 28,245,224, 64,155,138, 98,173, 80,170,183,115,251,136, 65, 74, 40,232, 37,226,118, 98, 86, + 93, 16,138,157, 41,160,109,203, 68,239, 81,198, 26,213,121, 51,191,150,222, 86, 14,154,155,122, 26, 29,154,183, 16,144,110,241, +138, 78,130,198,198, 43,195,206, 55, 44,156, 11,159,134,157,207,209,163,157,238,115,242,228, 7, 33, 81,114,192,170, 82,136,216, + 28, 2,227,204,121, 37, 88,230,113,208,243, 42, 56,251,198, 57,100, 42, 49, 87, 47,133,218, 42,165, 86,230, 90, 88,230,197, 45, +104,162,193,201, 55,150,226, 92,127,139,238, 76,206,153,253, 56,113,121,113,193,213,126,199,157,139, 43,246, 23, 23, 12,195,176, +250,196,251, 60,125, 20,225,238,110,199,245,229, 53,170,202,220,169,137,205, 65, 49, 22, 68,193, 20,162, 58, 82, 98,110,141, 58, +159, 34, 72, 65, 54, 34,167,186,242,190, 59, 3, 92,248, 23,234,253,200,117, 95,219,238, 18,136,220,222,129, 18, 65,114,246, 74, +188, 91, 20,251,159,226,118, 73, 19,175,220, 91, 35, 14,155,124, 40,143,205,206, 82,128, 55, 91,160,125,207, 60,117, 17, 33,239, + 98,156, 56,200, 22,171,106,103, 80,132,115,182,119, 23, 63,118, 10, 82, 87,102,250,201,116,203, 98, 55,131,178, 24, 79,178,219, + 49, 14, 9,222, 25,132, 87,128, 55, 30,159,120,237,111,207, 92,253,226, 51,228,207,221,135,159,190, 3,175, 79,200, 43, 35,242, +131, 23,216,151, 14,240,107, 39,244,173,147, 43,209, 91,219, 74,206,226,234,116,251,221, 19,252,140, 32,195, 53,188,121,132,246, + 15, 64,254, 11,152,254, 83,120,237,191,132, 71, 2,143, 5,158,225, 27,247, 7,177,185,166, 51, 79,192,208, 23,164,216, 76, 52, +193,212,223, 96, 72,187,171,108, 45,216,212,103,237, 81, 81,119,209, 66,238,161,212,234,149,247,189,104,179,222,148,168, 38, 3, + 54,115,178,179,244,147, 80,161,127,115,113, 40,199, 33,178,119,147,111,192, 54, 24, 66, 70, 46, 61, 45, 78,158,102,184,138, 28, +243, 19, 72,123,236,132,186,239,206,238,215, 95,249,173,177,209,196,124, 70, 76,220, 7,126,145,145, 49,123, 82,217, 20, 26,132, +189,250, 76, 87,195, 61,240,180,248,193,227,118,139,219,148,157,211,191, 82, 85, 39,119,149,104,133,169,208, 74,216,107, 86,159, +164,172, 33, 46, 3, 48, 52, 35, 93, 78,232,189, 17,238,143,174, 69,184, 84,127,157,127,126,192,174,252,100,104,183, 56,183,222, +218, 89,160,119, 59,195, 38, 57, 60,197, 85,186,113,253, 59,119,186,198,134,110,230, 93,147,249, 8, 95, 7, 85,243, 95,226,211, +111,195,229,235,112,251, 53, 56,124,205, 45, 99,211, 31,132, 87, 63,137,252,209,255, 29, 62,248, 26,246,206, 12,111, 41,242,141, + 17,121, 63, 97, 83,245,174, 76, 87,174, 43,235,136,102,221,200, 70,159,169, 59, 96, 70,253,240,246,168,248, 38,158,178,131,137, +242,128, 13, 33,154,188, 80, 23,163,132, 26,150,146, 2, 94,210, 47, 94, 8, 47,237,212,229,162,241,136, 86,176,163, 11,254, 46, +255, 67,210,127,242, 87,208,191,120, 32,213,196, 40, 71, 74,243, 5,178,214, 74, 89, 91,168,189, 96,220, 62,155,174,135,104,125, + 70,222,154,183, 9, 67,248, 70,108,128,125,230,222, 34, 73, 75,206, 89, 86,113,111,245,141,190, 43,117,155,177,250,163, 77,156, +153, 46, 75, 13,155, 91,197,202,236,226,187,195, 77, 84, 1, 46,132, 19,240,107,212,231,144, 67, 14,255,122,129,121, 38, 81, 25, +178,231, 42,139, 24,218,170,219,248,218, 66,187, 57, 80,110,158, 81,244, 3,218,229, 13,109,186,164, 45, 51,167,106,228,164,100, +131,165,134,135,124,229, 26,133, 27, 94,212,157, 21,130,207,175,123,130, 92, 8,210, 82,245, 89,184,138,103,174,183,182, 97, 77, +147,224,214,192,178,144, 38, 33,219, 66, 29, 47,105,211,222,187,114,209,102,117, 37,122, 60,134,121,240, 13, 69,220,219,159, 4, +210,180,195,202, 5,237,246, 25,205, 36,114, 10, 88, 85,210,170,189, 94,136,145, 68, 92,243,214, 29, 57,193,215, 79,254,228,196, + 97,162,219,177, 28,177,189, 30,158,204,231,197, 57, 43, 12, 3,229,120,242, 96,152, 60,162, 73,209, 97,231, 26,135,101,137,181, + 41,252,222,177,193, 73,143,142, 13,103,148,158,121,169, 65,220, 62, 38, 25,203,254,134, 19,194,110,154,184,184,186,195,126,127, +197, 48, 58,221,110, 46,133,121, 62, 80,230,197, 29, 40,213, 55,238, 82, 11,212,202, 48,122, 74, 27, 34, 92,239, 47, 92,209,222, + 26, 57,132,127,217,220,218, 88,173,113, 44,149,185, 44,204,161,164,175,103,226,179,103,214,184, 61, 30,121,101, 89,184,184,186, +230,122,183,135, 86, 93,103, 17,252,126, 75, 3,132, 35,185, 38, 63,124,154,181, 53,161, 78, 99, 12,164, 41,249,115, 82, 93,119, +181,162, 93,123,122, 95,210,237, 58,197,103,219, 31, 58, 77,234,220,133, 16,120,246, 20,182, 85, 19,212,221, 2, 61, 32,160, 61, + 95,165,219, 89, 31, 94,206,106, 77,249, 30,212,185, 30,101,107, 64,222,197,232,247, 58,109,137,107, 75, 4, 67,244, 10,227, 28, + 53,186, 86,101,103, 48,133,174,101,234,248,108, 11,203, 83,111,235,151,234,133,115,201,240,120,167,124,215,224,227,143,142,188, +250,191,125,151,221,207, 61,131,127,251, 1,242, 47, 95,193,103,118,200,199, 50,124,118, 7, 95,154,225, 75, 71,236,157,197,127, + 64,178,213, 67,206, 50,195,111,131,253, 66, 66,228, 2,222,252, 6,240,215,192,254, 44,236, 94, 69, 94,122,132,189, 51,248,139, +206,230, 11,235,108,225, 60, 59, 19, 11,204,192,253,120,130,250, 70,146,237,204, 4, 24, 87,114,136, 25,234, 62,218, 41,183,213, +231,247,187,104, 89,156,226,110,191, 86, 87,227,167, 64,189,118, 27,214,210, 21,239,108, 20, 57, 12, 30, 53,184, 19,141,147, 18, +100,161, 36,232,221,120,189, 18,191,198,189, 20,237,125, 54, 25,179, 29, 60,148,102, 62, 59,120,136, 99,101, 9,198, 52, 41, 56, +234,125, 67, 31,146,243,199,199, 72,232,233,130,194, 83, 8,249,150,176,142, 20, 59,131, 52,132, 37, 1, 67,181,209,154,172, 26, +168,185,196, 60,252, 44, 82, 50,197,121,105, 24,149,116,103, 68, 95,217,193, 75,131,111,232,151, 3,252,218, 99,236, 88,176, 87, + 60,181,204,240,195,207,243,112, 6,123, 62,254,211,154, 39, 23, 21, 86,203,217,122, 56, 82,207,148,239,226,174,242,228, 22,253, +226, 66,122, 82,253, 52,252,153,111, 34,119,222,132,229,101,152,191,230,134,247,203, 63, 7,247,254, 26,220,249, 10,242,218,207, +193,247,255, 18,246,214, 35,248,173,140,124,125, 66,134,138,105,133, 99,243,101,179,143, 88, 74, 31, 67,232,230,107,151,230, 29, +154, 67,129, 71, 10,227, 9,155, 60,241, 78,134, 12,187,132, 93, 21,223,212,159, 84,184,109,200,208,182, 78, 91, 98,227,235,150, +199, 96,203, 11,105, 13,115,196,178,254,113,228,135,255, 40,195, 79,254, 61,236,151, 43,246, 96, 38, 91, 69,205, 34,158,181, 55, + 58,252,126,232,173,247,149, 35,212,206, 44, 49,171,210,189,167,188,245, 25,185,157, 97, 10,122,230,180,174,179, 57, 43,178,206, + 94,237, 44,131,180,245,138,208, 34,235, 92,195,166, 20,203,127, 19, 79, 22, 19, 18,114, 50,100,183, 71,247,151,209,190,116, 53, +183,180, 68,109, 93, 80,229,135, 42,173,174,117,113,123, 96, 97,152, 38,114, 30, 56,156, 78,148, 22,175,187,156, 60, 33,110, 62, + 49,179,101,235,182, 88, 9,251, 28,189, 4,146,182,231,208,247,181,174,153,172,169,126,162,234,209,197, 2,201, 26, 85,101, 93, +204,106,168,164, 77,204, 55,245,189,231,127, 55, 77,232,254,138,122,186,245,116, 51,245,113, 14,106,171,173,170, 58, 38, 49,174, +171,162,163,251,234,151,186, 56,194, 87,220, 35,223,219,228,106,222,250,245,243, 86,195, 66, 32,216, 66, 67,144,194,190, 37,227, + 64,139,170,150,134, 83,212,210, 16,202,244, 77, 96,103, 64, 9,250, 89,218,237,169,203,236, 27,126, 40,214,117, 24,124,180, 16, + 29, 31,143,203,141, 20,184,206,246, 23, 11,209,156,174,161, 36, 52,243, 90,104, 55,177,155,246, 30,204, 50, 12,140,195,158,113, +116,229,187,207,195, 43, 41,121,107, 92, 46, 4, 21,111, 99,247,124,123,107,109, 85,204,215, 86, 41,167, 35,135,249,200,241,112, +160,212,194, 82, 27,183,117, 97, 57, 45,156,150,194,113,153, 61,223,188,235, 46, 82, 90,215,141, 90,141,199,225, 6,185, 79,176, + 57, 98, 32, 89,227, 57, 81, 51,146, 10, 69,149,219,211,137,122, 58,173,150, 53, 86, 93,151, 67,110, 90,140, 1,178,248,207,106, + 34, 52, 43,126,222, 34, 57,198, 59, 90,239, 62,194,243,142, 67, 19,241, 17, 66,117,251,232,234,227, 23,239,152, 52,129,186, 20, +111,191,159, 19, 45, 95, 88, 6,251,120,126, 3, 87,109, 40, 17,125,190, 81,191,118,119,254,127,190,222, 52,214,178,236,186,239, +251,173,189,247, 57,231,222, 55,213,171,170,174,158,216,221,108,138, 83,115,146,168,209,177,100, 89,146, 37,197,178, 29,197,145, +129,216,138,157,216,136,157, 1, 65,226, 0, 14, 2, 88,249, 96, 68, 64, 2,196, 8,224, 15, 73,156,192, 8,144, 15,129, 97, 4, + 6,236, 0, 65, 2,120, 72, 96, 73,182, 18, 75, 20, 69,154, 17, 73, 73, 20,155,100,119,147, 61,212,208, 85,245,166,123,207, 57, +123,239,149, 15,107,237,115,239,171,110, 69, 68,161,212, 53,188,186,239, 14,123,237,181,214,255,255,251,167, 35,191,137,173, 61, +133,237,202,111,152, 33,236,216, 28, 53,236,246,169, 45,254,187, 21,244,160,242, 30,194,221,222,170,141,236, 77, 72,242,127,122, +204,112, 63,193,246, 32,240,184, 86, 94,120,237,156, 27,255,205, 68,252,220, 9,252,165, 91,200,135, 14,224,149,132,220, 73,232, + 11, 61,242,219, 91, 99,162, 63,158,124,198,111,222, 64,173, 21,121, 99, 68, 63, 23, 16, 89,193,139,223,128,252, 63,129, 28,161, + 7, 29,242,148,152,130, 28,239,218, 46,170,101, 89, 87,143, 69,109,163,135, 18,140,252,246,216, 11, 91, 8, 54,179,110, 87,163, +236,114,201,149,255,104,106,199,177, 94, 59,240, 88, 39,184,105,163, 81, 88, 91,215, 85,196, 45, 4, 94,164,178,238, 82,111,198, + 2,111,204,232, 74, 17,141,104,170, 72, 49,208, 13,151,190,243, 47,102,133, 66,131, 25,250,131, 26, 63, 93, 86,118,216,135,118, + 9, 49, 47,187,204,141,151,229,157,213, 96,221,184, 56, 62, 87,162,237, 88,164,119, 81,215,186,119,241, 96,195,214,178, 87,172, +236, 96,146, 10,218,249, 27,161, 4, 36,215,157,150,176,238, 38,230, 13, 1,156, 68,232,181, 18, 14, 7,226,157, 1,158,233,225, +180, 67,142, 59,160, 71,127,115,131,174,212,146,242, 54,234,194, 64,189,134, 71, 92,222,224, 98,124, 0,205, 78,210,217,223, 15, + 6,183,149,197, 86, 24,119,187,191,122,150,209, 47,103,210,168,200,168,240,201,175,155,211, 64, 63, 12,249,117, 24,255, 55, 24, +254, 2, 12, 63, 1,235, 63, 2,135,223, 70,142,255, 22,220,249,101,244,185, 9, 94, 93, 33,119, 19, 28,102, 36,251,165, 86,252, +125,180, 47, 48,104,170,210,226,239,145,171, 2,143,130,177, 10,158, 1, 14, 6, 8, 3, 50,140,112,176, 69, 15, 20, 30, 72,203, + 38,222,165,176,180,208,238,114, 14,229, 93, 3,208, 44,146,181, 10,108,204,187, 62,252,123,196,191,242, 5,226,159,126,157, 58, + 87,146, 15,203,219,190,184, 5, 88, 4,175,230,139,238,176, 54,238,182,117,224,198,238, 94, 64, 3, 86,104,252,146,164,101,255, + 58, 21, 44,105,177,134, 93,112,205,123, 90, 8, 19, 7,225,163,204,230, 55,110,235, 20,233,250,101,212,172,126,139,208,121, 50, + 2,155, 19,194, 90,140, 40, 49, 17,242, 12, 49, 17, 17,162,203,123,141, 85, 63, 32,125, 2,157,169, 18,152,165,177, 36, 20, 26, + 16, 36, 27, 54, 39, 55, 22,182,152,136, 45,171, 90,170,236,146, 90, 86,119, 35, 13,217,155, 68,106,243,222, 23, 75,159,172,187, +125,115,222, 11, 53, 72, 40, 50,110,161, 27,168,146,168, 41,248, 74,163, 32, 90,156,109,212, 65, 23,173, 43,140, 62,161,153,183, +148,188,133, 20, 73,135, 71,212,203, 3,242, 52,210, 48, 36,133,157,106, 58,180,124,242, 69, 40,170,139, 82, 63,184, 67, 64, 83, + 71,154, 38,138,231, 21,104,205,198,121, 71,108,180,238,123, 91,139, 10, 53,225, 90,183, 58,160, 14, 86,216, 77,156, 85, 81, 2, + 49, 25, 17, 79,203, 68, 41,211,226, 66,210,101,167,237, 78,128, 16,136, 62,114, 79, 33, 48,116, 43, 14, 86,135,172,214, 7,196, +126, 69, 13,129,237,102,195,102,115,225,152,105,235,128,231, 82,152,199,201,128, 46,174,251, 88, 38, 72,142,121, 77,253, 0, 40, +185, 20,174,166,145,203,237,150,121,154,188,129, 44,174,132, 55, 54,123, 8, 98, 93,188, 35,146, 91,231, 95,181,146,181,114, 57, +207,232,249, 25, 67,191,162,247,203,130,230,236,169,149,246,190,222, 76, 19,211,118,227,151,131,157,106,209,226, 14,170, 43,213, +237,226, 32,177, 3,137,206,121,119, 61,149,191, 33,154, 0, 79,124, 66, 82,197,196,133,185,228, 37, 15,222,240,186, 45,187,222, +109,132, 45,150,245,125,218, 25,145, 61,182,140, 62,185, 71,223,173, 36,117, 95,141,215, 52,226,127,241,118,248,197,222,155,206, + 27,205,214,237, 63,119,190,103, 95, 5,225,160,179,198,238, 56,152,253,250, 56, 90,243,181,142,112, 16,133,195,100,117,226, 32, +218,143,195, 8,171, 40, 12,254,223,107,223,219, 55,238,113,242, 74,176, 29, 2,181, 20,134,111,108,137,159, 31, 97,165,200,179, +214,221,201,157,136,220, 73,230, 73,143,193,124,201, 77,217,158, 92, 36, 60, 41,140,130, 28,174,237, 1,220,243,241,230,224, 55, +203,236,114,253, 73, 29,106,162,230, 77,238,217, 9, 8, 86, 46,126,203, 45,227,124,127,215,238,136,211, 33, 58,248,220, 31, 67, +113,222,250,198, 23,110,119, 34,220,153,225,224, 19,118,147,185,120,199, 70, 19,155, 98, 35,237,185,122, 78,173,251,234, 31, 84, +248,173, 43,247, 59, 59,248,166,136, 83,193,220,131,125, 96, 2,183, 22, 12, 35, 31, 76,118, 64, 28,253,176,237,194,222,253, 42, +188,169,230,229, 47,238,185, 79,150, 8, 22,134, 72, 56,244,231, 45, 6,187,177,118, 22, 79, 40,125, 7, 79,155,165,141, 8,250, +184,192,187,179, 41,224,231, 74,157,219,242,213, 71,128, 77,189,227, 83,130,134,116,222,239,174,155,136,103, 85,148,190,139,164, + 91, 7,196, 15, 31,192,203,135,112,123,141, 28,245,232,197,136,254,189,251,212,131, 98, 23,133,209,169,107,237,192,220, 27,117, + 94,203, 87,204, 38, 30,212,201, 46, 62,173,160,154,127,121, 95, 65,130,233, 10,170,123,168, 47, 50,225, 93, 19, 37,202,201, 67, + 56, 56,132,238,251, 33,127, 27,194, 59,102,119, 11,167,102, 15, 28,126, 20,214, 47, 33, 39, 95, 65, 78, 31,217, 40,125,238,161, + 70,179,167,197,125,225, 91,243,195,202,110, 60,209,148, 44,201, 63, 96,157, 24,112, 38,221, 4,185,233, 69, 73,145,131,209, 19, + 73,124,247, 63, 84, 11,173,233,143,161, 95,193,240, 65, 72,207, 63,129,139,242, 23,150, 3, 56,250, 14,124,241, 43,212, 87, 11, +249, 16,143,253, 12,168, 54, 5, 47,139,125,107,153,236, 47,157,181,175,255, 61,222, 17,207,239,110,179,150,214,181, 46,123, 7, + 15, 98,146, 39,149,184,178, 99, 86,171, 23,231,230, 51,103,112, 43, 90,234, 80,209, 37, 97,203, 91, 50, 40, 5,209,106,201,105, + 93,111,190, 72, 88,124,236, 34, 66,208, 74, 71, 49,113,110, 74,212,213, 26,141,145,213,188, 33,205, 35,147, 86, 70,215, 12, 16, + 34,181,239,109,168, 85,139,137,144, 22,157,135,238, 69, 64,251,250,202,127, 95, 61,254,115, 1,159,248,143,234, 2, 41,252,174, + 91,252,207,238, 44,157, 66, 23,133, 78,109,237, 49, 13, 71,148,126,133,110, 47,108,119,234,164,178, 44,145,178, 58,180,206,110, +158,172, 3, 23, 39,211,149, 76,208, 66,153, 38,234, 60, 46,232,224, 90,118,105,124,237,158, 43,169,167, 59,190, 97,123,227, 24, +136,195, 1, 49,173,252,207, 91,218,158,150, 22, 78,227,128,152,108,238,130,176, 90,219,172,100, 79,165, 93,242,108,246,170, 82, + 40,243,108, 99,230,176,147,214,198,152,232,250,129,174, 27,124,117, 80, 22,183, 71, 8,145,224,222,243, 24,205,150, 86, 69, 24, +231,145,205,213, 21,211,184,101,154, 38,174, 54,151,108,175,174,200, 57,147, 75,113,146,163, 41,216, 55,211,150,205,118,203,229, +246,138,203,171, 43, 46,175, 46,217,110,174,152,166,201, 64, 49,202,210,157,183, 66,142, 86, 82, 8,116, 33,209,167,142, 62, 37, + 82, 76,214, 13,151,194,156,231,101, 28, 63,207, 51, 37,151,229, 8,169,236,160, 57,205,110, 55, 22,229,114,220,144,199,173, 93, + 60,119, 35, 44,227, 39, 56, 71, 95, 80, 87,218, 71, 82,138, 22, 21, 92,170,133,148,185, 82, 56,136,113,249, 13,211,236, 78,136, + 70,203,203,101,153,208,180,244, 76,117,171,158, 77, 26,174,227, 96,159,236,212,245,189,107,246,107,190, 98,217,151,197,203,242, + 93, 16,255,243, 59,225, 23,111,154, 8,151,155, 17, 78,147,193,203, 14, 35, 28,138,112,146,132, 67, 47,228, 71, 94,172,111,138, + 89,155, 79, 19,220,140,194, 13, 81,110, 6,225,166, 23,251, 3,129,195, 78, 56,242,191,119,226,100,208,163, 32, 28,251,215, 89, + 11, 68, 21, 52,194,220, 25,250, 49, 61, 24, 73, 95, 24,145, 7,213,148,222,183, 58,235,242, 78, 3,226,183, 6,233, 3, 82, 93, +100,148, 60,145,103,170,214,204,156, 56,140,230, 65,177, 98,125,224,158, 98,215, 28, 33,193, 2, 95,218, 51,181,114, 43, 82,181, +219,138,156, 36,235,162,219, 62, 33, 25,151,124,241,157,172, 45,231, 91,146, 5,142,144, 61,201,173, 11,240, 82,134,155,199, 48, +252, 25,200,223,132, 71,111,193,148,118, 49,171, 13, 17,218,251,205,232,205, 12,247,178,239,241, 13, 74,163, 23,197,206,210,228, +233, 97, 67,180,164,176, 24,225, 56, 33, 47, 70,232, 19, 28,253, 56,164, 27,144,255, 57,188,173,112,102,197, 24,245,136, 79, 87, +186,139,135, 8, 72, 12,222,169, 59,212,225, 56, 33, 79, 15,112,210, 27, 28,231,172,192,121,182,201,198, 84,157,128,183, 19,164, + 45, 69, 87, 91,119,110, 51,202, 93, 14,180,233,161,251, 2,131, 8,233,104, 69,122,238, 16,249,248, 17,124, 96,141, 28,251,173, +238,119,206,209,207, 93,160, 79, 97, 56,220,217,247,231,181,197,121, 94, 55,189,139, 91,108,150,124,157, 22, 48, 83, 93,206, 85, +119,111,228, 5, 6,212,216, 1,222, 92,242,104, 38, 60, 0,142, 58,228,232,109, 99,254,167, 31,135,250, 16,226,100,182,177, 86, +153,187, 87, 96,245,227,112,248, 0,185,245, 38,156,108,160,116, 22, 74,144, 89,132, 80, 75, 76,107,116,197,119,191,199,110,108, +147,131,212, 18,230, 58, 8,183,205,190, 17,123,235, 80,135,140,244,217, 61,235,216,133,177, 59,130,110, 5,195,211, 14,160, 89, +177, 43, 71, 13,103,153,128,137,240,202, 23,169,127,239, 2, 68,153, 58,216, 22, 37,231,189,227,161, 41,213, 69,118, 81,157,117, + 15, 64,179,103, 23, 84,127,238,100,113,180,200,242,163,186,149,170,250,239, 87, 31,165, 47,250,130, 16, 9,195,129, 89,214, 66, +112, 20,164,169,174,233, 7,131,157,148,130,150,217,241,179,182,127,143, 82, 9, 53,155,211, 36, 36,180, 89,175,180, 90,200, 71, + 8, 4,170, 81, 16,187,206, 10,216,118, 67, 87, 38,227, 86, 72, 96, 86,203, 48, 87,100, 73,166, 83,183, 36,105,240,236,117,143, +134, 85,215, 18, 52, 14, 56, 18, 60,216,200, 99,112, 99,220,123,238,100,249,251, 69,219,243, 39,110, 85, 82,162, 8,131,199, 73, +231,156, 25, 75,133,131, 19, 83,204, 95, 89, 97, 47, 18,208,216, 81,250, 3,202,184,161,110, 46, 97, 30,237,217,237,122,215, 20, + 4,106,158,168,121, 90, 70,228,138,236,249,211,237, 53,144,110,205,193,211, 31,176,206,188,186,112,102,222, 82,167, 43,211, 31, +136, 88, 0,145,234,210,208, 53,156,106,138, 61,253,193,145, 41,235,115,166,230,108,232, 94, 39,173,229, 82, 28, 70, 99,192,151, +216, 15, 38, 32, 75,201, 98,107, 83,231,224, 20, 99,206,235, 94,241, 43,165, 48,151,204, 52,141,204,211,200, 56,141,204,211, 68, +158, 70,166,217, 66, 89,230,105,164, 56, 69,174,204,217, 19,208,236,185, 79, 18,233,146,137,241, 66, 48, 21,122, 20, 33,245, 38, + 90, 77,238,139, 15, 41, 44,208,180, 6,189,156,107, 49, 50, 93, 41, 75, 81,175,217, 93, 7,213, 47,142, 14,161, 81, 9, 76,181, +178,205,153, 49,207,108,166,153,237,118,187,236,209,171,238,101,211,187,131,160,221,224,130,236, 10,122,236,122, 95,123,151,101, +204, 30, 84,233,162, 65,118, 26, 73,177,233, 4,170, 95, 94, 85,246, 4,114,109,240,187, 60,222,221,100,242, 73, 52,236, 34,146, +171,187,226,189, 68,220,182,232,229,253,247,137,236, 46, 39,241,191,190, 19,127,241, 84,132, 91, 65,184,145,132, 27, 81,184,161, +194, 77, 17,110,181, 2,142, 21,239,155, 34,156,138,112, 28,132, 35, 9,156,136,253,249,211, 40,156,248,143, 27, 34,220, 12,194, +173,160,246,251,190,102,190, 33,112, 67,132,227,160,220, 8,194,113,216, 1,213,140,178, 41,148, 1,226,148,137, 95,159,224, 27, + 5, 94,232,144,219,201,110, 10,199,130,156,116, 54, 66, 56,114,176, 75,136, 59,131,125, 21,184,172,200, 41,200,179,157,177,194, + 69,224, 72,118,144,152, 82,173,128,175,147, 7,131, 0,135,178,120,205,165, 19,228, 48,186,156, 95, 97, 37, 59,210,216, 81, 66, + 78,124,124, 17,131,237,161,213, 59,245, 65,224,197,140,156,126, 22, 89,253, 44,242,248,239,194,197, 37,140,221,174,168,171, 35, + 97,215,174,136,126,148,225,162,216,147,208,177,131,225, 68, 89, 8, 68,168, 88,182,252, 42,217, 4,227,165,100,249,219,167, 63, +101,221,156,254, 51,228,193, 5,220,139, 59,118,112, 47, 72,151,172,240,184, 13,164,185, 7,108,167,110, 62,122,121,186,223, 5, +171, 60,202, 38, 96, 27, 11, 58,249, 5, 33,239,167, 80,248,162,209, 79,140,150, 77,220, 0, 8,226, 8,210, 65,148,238,160, 39, + 61,117, 72,120,229, 8, 62, 50,216, 52, 96, 56,178,231,254,239,223, 55,246,247,145,160,219,106, 41,108,121,159,176,180,211,139, + 44,163, 57,159,206,150,186,119,107, 13,123,150, 77,109,246, 50, 53,222,115,221,203,155, 13, 30,206,114,127, 34, 60, 4, 86, 61, + 12,111, 34,235,119, 32,126, 55,212, 43,143,179,187,237, 95, 45,219,255, 63,252, 33, 88,125, 10, 57,120, 3,185,121,215, 46, 2, + 87,157,173,183,147,236,192, 70, 14,147,129,189, 46,190,129,133,122,123, 82,100,141, 41,216, 99, 15, 97,101,164,184,120, 8, 73, +145,222, 98,129, 9, 3,244, 7, 16, 87, 48, 28, 67,250,128,253,157,107,218, 2,247, 36, 79,111,193,209,111, 35, 95,191, 79,249, +221,145,121,112,190,145,238,128, 36,236, 29, 21,212,150, 70,119,253,247,218, 33,138, 91,122, 26, 72, 6,177,241, 98, 89,146,182, +118,133,254,122,244,227,206, 6, 69, 72, 4,228,154,207,177, 22, 71,226, 36,231, 60,212,217, 70,172, 49,144,162,137,138, 52,103, + 52,207,158,189, 29,237,206, 27, 3, 93,223,155,245, 43, 8,186,189,162,142,219, 5,120,147,124, 74, 98,247,116,211, 91, 4,137, +164, 97, 77, 23, 45, 37,209,194,140,124,255,233,223,131,132,214,169, 57,124, 38, 8, 93,136,212,152,124, 48,221, 14,210, 93,215, +190,140,228,155,207,216, 1, 47, 93,216,109,211,230,121,178,143,199,241,169,133,128,108,174,204,174,213,173, 44, 58,116,220, 88, + 86, 65,240, 56, 87, 47, 34, 50,172, 44,154, 51,103,167,218,201, 53, 4,171, 29,105, 70,166, 43,243, 76, 25,175, 80,223,193,147, +199,165, 3,148, 16,150, 53,138,236, 3,107, 28,116, 19, 82, 79,119,116,195,116, 14,101, 38,196,222,117, 1, 6,117, 73,195,138, +180, 90,145,134,181,105,104,124, 25,111, 96, 23,118,113,161, 13,110,227,220,244,170, 74, 45, 6,137,209,236,222,110, 7,238,228, + 82, 40,217,252,248,165,100,114,206, 76,243,188,216,215,218,153, 81, 29, 8, 99,124,126, 27, 77,167, 96,231,111,110,169,125,222, +249,182,110,124,204, 51,227, 52, 89, 71, 94,118,226,196,234, 86,228, 20,157,104, 23, 77, 15, 80,114, 89, 32, 54,165,148, 37, 63, + 93,247,114,214,245,218, 85, 87,174, 43,201,163,197,176,106,136,212,146, 45,118, 53, 38, 15,225, 17, 98,215,163, 18,252,235, 22, +114,245,201,212, 94,224, 13,206,101, 48,158,193, 76,157,235,222, 68,189, 94, 19,199,237, 79,195, 68,127, 63,149, 81, 43,123,118, + 6, 73,104,186, 24,239, 29,251, 79, 30,152, 7, 77,217,121,216,102,167,159, 53,207, 48,251, 65, 38,114,109, 62, 32,253,254, 94, +211,131,145,197,119,180,163,171,132,155,168, 38, 58, 45, 44,251, 97, 27,236,133,213, 89,169,157,223, 66,214, 66,221,100,228,139, +143,224,191,154,225, 47,220, 66,254,240,177, 33, 97, 7,133, 67,224,169,104, 66,184,135,197, 84,199,147,119, 15,231, 25,190, 22, +224,149, 98,130,187,251, 62,114,251, 64,135, 36, 31, 45, 94, 84,168,131,181, 46,219,201, 8,115, 39, 17,201,106, 98,166, 67, 69, +142, 48,232,204, 70,119,123,143,149,223,167,170, 63, 7,226, 2,184, 22, 18,127, 80, 33,125,175,221,156,198, 7,150,167,222,210, +223,148,107,163, 91, 83, 1, 71, 99,135,215,138,110,117, 71,191,155,247,148,136, 45, 29, 76,124, 49, 90, 35,172,110, 66,247, 12, +132, 19,179, 64, 61,245,142, 89, 80, 82,132, 97,199, 95, 94, 72, 80,109, 15, 93,188, 24,117,238,161, 79,113, 39,228,203,117, 39, +146,208,253, 24,198, 22,251, 19,216, 95,130, 5, 44,144, 33, 4, 33, 36, 11,191,137,170,164,190, 35,157,172,136, 47,174,225,101, +115, 52,208,221, 54,238,247, 91, 15,209,239,204,232, 45, 65, 71, 19,144,180,128, 24,221, 11,209,104,133, 92, 60, 80,164, 77,109, +117, 47,171,189, 61,198,208,132,143, 51,232,176,255, 24, 29, 48,164,230, 9, 45, 2,242,230, 21,233,171, 29,178, 93,163, 31,125, + 21,158,191, 11,235, 15, 33,250,174,189,118,253, 39,140,214,167, 87, 38, 76, 91,253, 40,244,159,132,245,223, 71, 14,255, 54,122, +120, 1,191, 51,192, 3,236,144,238,195, 46,212,103, 9,175,247,238, 61, 99, 26,141,195,100,236,239,244, 16,120,193,200,134,210, + 65, 60,242,194,254, 16,210,185,249, 99,131,123,211,235, 5,212, 71,182, 87,151, 97,175, 91,247, 99, 64, 11,100, 8, 63,127, 72, +252,229, 13,105,206,196,110,119, 20,233,158, 14,212,198,237, 74,173,114,141, 36, 29, 68, 40,209,215, 40,190, 83, 39,154,152, 76, +179,119,244,126,200, 62, 89,204,131, 23,155,165,132,148,226,182,210, 72, 12,214, 41,217, 97,157,169,115,203,185,174,206,156, 80, + 58, 17,122,183,245, 77,185, 50,215,153,176, 61, 35, 72, 37, 29, 28, 17,125,228, 91, 83,164, 22, 23,220,249, 90, 96,235,145,157, +157,216, 99, 78,193, 53,156,243,134, 88, 86,196,131, 3,122, 81,174,198,137,169,218,254,217,238,228,118, 27, 45,197, 82,216, 66, +234,232, 67,187,187,203,254,179,187,244, 66,230, 79,111,197,166, 45, 43,141, 62, 86, 66, 37,138,135,233, 0,243,197, 35,106,234, +137,167, 79,219,101,102,187,177,254,161, 78, 54, 98,245,203, 79, 93,220, 47,198,215,151,217, 50,231,107,176,125,108,197, 56,244, +193,149,250,241,224,152,154, 6, 74,158, 60, 44,199,188,212, 17,167,172, 9, 6,100,145,184,216,175,180, 88,167,106,159,155,194, +120,113,198, 60,207,196, 97, 77, 90, 31,218,216, 55,171,137,230,250,129,126,117,176,187, 84,227,246,171, 82,150, 85,129, 21,144, +232,199,126, 94, 70,241,210, 80,177,218,108,184, 97,185, 76, 52,116,176, 74, 52, 77, 78,132, 92, 11,185, 88, 81, 22, 7,235,104, +131,185, 52,139, 30,182, 30, 72, 41,121, 76,105, 3,162, 5,136,145,226,150, 56,234,142,159,174,150, 22, 99,174, 1, 17, 59, 7, +125, 18,177, 80, 21,231,226,217,231,181,129,138, 23,172,181,190, 39, 14,165, 57, 29,204, 19, 31,251,100,152,223, 50,123,170, 95, + 90,244,173,209, 53, 36, 54, 41, 48,232, 78,241,238, 95,170, 46,132,199,224,177,191,213, 59,120,125, 34, 39, 93,246, 69,114,123, + 72, 14,105, 19,199,186, 19,165,202, 19, 64, 26, 89,106, 11, 11,214, 54,201,159, 57,177,110,115,220,139, 20, 93,137, 21,250,141, + 31, 18, 90, 77, 53,221, 36,237,121,207,163,122,225, 75,171,196, 78, 16,134,141,175,245,202, 35, 12, 54,190,223, 86,179, 76,233, +214, 47, 2,213, 18,184,100,178, 81,172,122,166, 57, 43,207, 54,127,115,131,254,183,247, 8,175,101, 83,200, 63,213, 33,183, 65, +215, 30, 16,114, 50,195, 73,183,228,142,147, 3,122, 89,145,111,122, 36,233,211,130,156,217,139,172,207,116, 72, 23,208,251, 46, + 68,219,244, 22, 94,178, 5,142,246,118,229,163, 35,244,214,193, 46, 17,217,121,238,115,113,161,158,238,102, 65, 67,176,231,237, +150,194,193,128,198, 15, 34,245,109,184, 58,131,122,219,139,190,143,132, 27, 6, 23, 39,179,156, 4,184, 8,240,184,192,153,137, +176,164, 19,116,242,240,152,214,237,225,143,233,184, 21,216, 59, 86, 20,100,101, 86,167,147,223,116,113, 94,178,137,196,204, 46, + 12,102, 73, 23,245,199, 58,196, 29,206, 52,237, 21,160, 73,159, 72,103,107,170,217,230,121,119, 92,107,139, 10, 20, 33,184,238, + 64, 92, 69, 25,250, 72, 58, 93, 17,159, 61,130, 87, 6,228,165, 8,235, 15, 64,125, 26,228, 53,248,173,115,203,157, 63, 4,222, +245,203,157,243, 41,155,245, 72, 91,198,124,221,249, 51,117,190, 94,208, 5, 22,101,175,202,206,113,193,182, 58,132,123,239, 55, +240,139, 87, 18, 74,202,132,199, 91,226,183,129,199, 43,248,224, 4, 47,126, 25,189,249, 59, 48,254, 26,114,244, 39, 97,253,199, + 32,158, 88, 60,169, 94, 66,184, 9, 71,127, 17,186, 87,144,244,215,209,195,239,192,239, 14,112,127,176,149, 79, 44, 11,186,150, +196,226,148, 88, 46, 97,231, 21,189, 81,144,254, 49,164,167,108,127,207,104,157,121,124, 10,234,202, 46,103,245,204,247, 26,226, +223,240, 6,123, 99, 14, 79, 44,211,170,253,250, 56,195, 83,145,248,177, 3,210,171,103,244,201, 18,134,213,231,114, 82,119,130, +250, 39,243, 32,116,145, 70,136,167,129,217, 68, 65, 85,144,234,130,187, 54,134,220, 27, 9,239,168,113, 78,224,171, 24, 19,188, + 78,132, 96,192,150,230,199, 93, 40,122,154, 45, 67, 61,103, 98,201, 36, 81,151,175,236, 44,156,166, 31,153, 8, 87,103,132, 58, + 65, 50,159,180,122,196,102,238,214,150,125, 93,205, 67,158, 75, 38,186, 20, 38,137,144,162, 26,110,118,123, 70, 92,245,200,250, +144,174, 86,166,113,166, 54, 50,100,234,118, 97, 55, 77,229,222, 5, 27, 89,186,137,191,168,137,201, 8,182, 34, 48,124,194,110, +130,212, 46,218, 53,154,143,220, 38, 31,142,116, 85,200,103,247, 9,177,167,123,250, 37,242,249, 67,202,217, 67,148,108,154,133, +234,207,111,232,150, 52,178,178,185,128,209, 32, 66,161, 52,159,115, 52,145,149, 22,232,215,132,213,161,141,137,125,124,173,101, +182,243,187, 27,136,221,218,244, 6,181, 82,242, 68,215,173,145,126, 32, 76, 35,108, 54,104,193,161, 65, 48, 95,156, 17, 54, 23, +172,110,220, 54,130, 95, 81,194, 48, 16, 98,103,220,113, 79, 62, 83,137,246,245,102,139, 63,221, 23,233,181, 98,109, 2,200,226, + 52,205,176,211,146,180, 34, 89, 91,130, 90,112,253,231, 46, 66, 85,171,248,200, 91, 22,187,100,241, 14,187,122,163,176, 29, 71, +250,156,145,148, 22,174, 65,206,230,175,111, 48, 23, 80,139,115, 14,201,199,247, 38,218, 83, 17,230,106,239,145,154,235, 66,133, +171,194, 46,231,221,171,165, 44, 4,204,157,243, 38, 56,130, 51, 58,122, 86, 82, 52,151, 68,153, 13, 78,228,211, 35, 99,152, 88, + 64,203, 92,173,251,183,132,188,253,108, 3, 22,170, 94, 65,204,233, 80,202,110,229,245,196, 39,243,189, 81, 46,215,241,219,242, +158, 92, 23,217,233, 85,155,191,222,247,234, 73, 62, 59,236,172, 83,165, 9,127,194,174, 61,178,100, 69, 36,121,128, 69,183,231, +101,155,177, 78,119, 18,244, 74,204,198,213,174, 18, 91,255,199,139, 23,154,217,113, 86, 37,152,192,172,197,164, 94,250,210,160, +169,211,139,154, 4,255,188,160, 15, 43,220,155,169,255,203,187,132,111, 21,248,143,111, 27,176,230,164, 64, 15,122,146,224,150, + 34,103,201, 46, 23,219,178, 3,204,188,153, 65, 18,114, 71,208, 53,200,198,119,232,235,136, 62, 2, 30, 7,163, 94,181, 66,222, +169, 9,216,130,139,212, 98, 48, 15, 58,109, 58,225, 62,161,150, 6, 82,176,139,196, 36,214,233,197, 53,196, 59,232,230,171,246, +248,115, 52,160, 70, 51,242, 39,150,132, 46, 14,125, 10,208,205,240,182, 47,140, 7, 31, 17,174, 89,248,174, 18,247,140,255,205, + 62, 21, 79,119,163,216,244,156,141,243, 79, 4, 25, 13, 93,107,118, 20,221, 19,147, 7, 15,219,136, 86,220,163, 91,243,146,123, +190,103, 87,110,203,245,162,126,237,255, 74,176, 76, 97,143, 99,107,158, 72,131, 93, 8, 66, 36, 30, 13,164,103, 14,225,123,123, +248,184,192,141, 15,129,188, 2,221, 21, 92,158,195,151, 71, 56,182,168,220,154,125,158,190, 23, 62, 99,159,109,185,142,209,175, +215,169,177,251,221,232,190,182,206,132, 43, 62, 97,122, 82,120, 18,247, 72,116,165,160,219,217, 82,222, 30, 38,120, 45,194,119, +101,120,225, 53,244,198,127, 7, 71,255, 4, 57,253, 79,237,178, 36,157, 23,215, 4,171, 31,134, 91,255, 5, 18,254, 6, 28,252, + 30,250,214, 4, 15,123,184, 18,123,110, 26,145,176, 83, 27, 51,224,162,199, 9,179,185,173, 55,208,157, 65,255, 52,132, 99,243, +158,135,104, 35,246,144,236,107,212, 43,203,133,103,107,111,200,122, 14,241, 96,207,243, 86,221, 91,105,121,233,114,161,196,207, +174, 72, 95, 63, 39,170,237,122,155,235,174,236,239,228,124, 87, 29, 90, 8, 69, 27,165, 47,226,119,135,255, 4, 93,162, 62,197, + 85,209,203,110, 30, 75, 97,171, 94, 36,170,175,138,212,193, 40, 53,136,191,158, 5,149,184,219,145,135,106,190,245, 58, 19,169, +244, 2, 61, 74, 71,117,113,150,239,245, 85, 16,157,209,205, 76,145, 64, 9, 29,165, 95, 83,186,158,210,117,148,212,251,168,126, +178, 78, 46, 91, 84,171,173, 93,252,125, 48,142,212,199, 15, 72,167,119, 72,135, 39, 48, 63,244,125,241, 78, 11,160,112,205,247, + 6, 0, 0, 32, 0, 73, 68, 65, 84, 49,184, 97,162, 18,155,103, 29, 69,197, 30,143,120, 91, 84,170,169,151,235,222, 56,219, 38, + 67, 74,165,146, 3,100,148,185,216,207,234, 96,145,122,118,223,178,194, 79,110,145, 85,169,103, 15,145, 16,137,233,208,138, 65, +236,168,211,104,222,125, 42,193,241,162,180, 81,182,136,121,227, 99, 36, 29, 28, 83, 98, 79, 45, 27, 43,188,158,154, 23, 14, 79, +137,199,167, 22, 76,130, 16,181, 18, 75, 70,130, 21,248,164, 64,236,169,219,209,140, 66,221, 64,108, 62,236, 90,144,212, 35,125, + 71,201,133,105,123,102,148,180,174,115, 91, 86,211,140, 36,160,144,167,201, 46,101,173,140,168, 49,228, 21, 35, 57, 74,104,143, +223,223,155,254,121, 44,234, 98,200,230,111,246, 66, 95, 90, 90,158,191,171,170,178, 20,236, 37,248,196, 45,116,195,106,101, 98, + 63,133, 46, 26,226,181, 79,137,218,245,104,177, 48,157,206, 31,119,174,117,241,170,199, 16,152, 68,152, 37,163, 69,252,189,213, + 86,123,123,250,160, 16, 23, 85,191, 44,133,222,207, 53,215, 98, 52, 32, 82, 20,139,141, 53,164,114,113, 75, 97, 36,139,144,167, +217, 50, 13,212,166,207,237,123, 85,143, 57, 86,127,124,213,237,109,139, 64,245,154, 9,141, 39, 6,241,123,213,123,111,106, 43, + 79,136, 86,101, 15, 21, 41,158, 68,135, 4,146, 60,221,153,141,197,115, 51,101, 25,230,199, 37, 35,214,254, 59,129, 30, 1, 39, +246,123, 58,250,225,179, 5, 29,205, 78,181,241, 39,172,184, 98, 90,154,183,215,111,238,181, 56,204,195, 37,212,165, 66,238,224, + 42, 34,179,154,239,250, 74,208, 51, 51,182,203,187, 25,125, 56,195,215, 11,250,235,151,240, 11, 21,126,225,150,225,101, 15,214, + 72, 63,195,225, 6,110, 22,155,154, 94,120,203,178,241,162,123, 63,163, 29,200,237, 14, 93,137,217,194,186, 96,138,242,181, 90, +231,186, 31,113,218,186,111,221, 69,232,217,124,109,143,238,148,189,187, 25,129,183, 50,108, 29,144, 17, 86, 16,159,134,205,255, +128,206, 62,122,111,233,108, 77, 17,221, 40, 63,135,105,201, 80,215,199, 25,110,123,224, 71,241,189,123,220, 75,121, 80, 87,160, +143, 5,202,100,130,170, 32,222,226,216, 88, 74, 86,160, 41, 64,182, 34,187, 36, 59, 53,145,156,103,168, 19,204,174, 32, 43, 3, + 81, 48,101, 19,197,201,222, 69, 45, 63, 33,187,148,189,229, 78,139,180,117, 17, 10,157,137, 92,210,170, 35,124,224, 8, 62, 43, +200, 71, 20, 78, 62, 9,225, 15,184,253,240, 30,250,237,135,246,220,159, 84,244,194, 32, 55, 90,212, 17,148, 62, 5,216,219,163, + 47,238,169, 6,228, 41, 92,187,225,134,228, 5,223,255, 76, 81, 8,179,238, 30,110,244,174, 95,174,243,218, 85, 43, 53, 43,161, +155,141,104,246,122,128, 7, 17,222, 90,193,199, 20,110,127, 14,182,255, 17,220,250,203, 86,200,227,205,221, 88,160,255, 44,220, +252,107,208,253, 93,228,224,215,225,242,161, 93,222,198,176,176,235, 81, 7,249,204,205,203,105, 23, 66, 61,155,172, 91,239,174, + 32,173, 33, 29,237,177,118,111, 67,126, 8,122,207,108,138,201, 63, 95,136, 77, 11,228,198,222, 71, 57,154, 93, 50, 12,232,168, +200, 58,210,221,233, 73,143, 70, 82, 15,163, 24, 14, 51,239,157, 5,178,175,112,108, 59,111,159,180,148,182,142,173,234, 93,173, +109,214,203, 34,182,243,159,107,165,196,128, 70, 7, 0,249,254, 61,164,206, 46,198, 45, 69, 13,252,207,212,229, 82, 25, 82, 71, +210, 66,151, 71,250, 96,235,146,166,113,237,130,216, 40, 63,196, 69, 68, 84,137, 76, 69,153,166,145, 50,207,132,110, 64,250, 21, +161, 79, 30, 48, 50,195, 60, 81, 74, 97,148,200,236, 54, 62,213,194,106,115, 69, 12,239, 18,110, 62,139, 28,222, 64,207, 30,249, +229,195,188,222,109,159, 37,216, 69,163,230,138, 22, 49,223,178,183, 67,217,193, 58, 45, 83,220,161,243,246,171,254,121,210, 96, + 94,227,226,225, 42, 38, 26,180,196,179,242,238,219,164,227, 76, 92, 29, 19,179, 41,211,101, 24,208,121,164,206,147,249,245, 61, + 79, 60, 58,104,166,165,158,137,211,199,218,229, 54, 12, 3,113,107,241,169, 5,156,165,127,100,150,190,162, 80, 50, 41, 40, 49, +246,166, 28,247,120, 87, 9,193, 84,234, 85, 45, 92,135, 96,189,218,106,229,120, 86,150,180,176, 82, 10, 93, 48,203,214,226,135, +142,201,102, 26,253, 64,201,209,148,224,186, 19,181, 72,112,231,134,219,229, 52, 25,207,162, 20, 3, 14, 89, 18,155,186,207,126, + 39, 18,171,222,205,182,122,208,222, 95,210,200,161,178, 75, 41,139,170, 12,253,202,178,208, 75,118, 62,187,169,252, 39, 41,156, + 79, 19,211,102, 99,123,245, 90,220,183, 45,116, 41, 18, 83, 67,209,122, 38, 61,123, 99,119,246, 14,153, 86, 22, 27,255, 94,119, +227,112,123,109,146, 81,244, 60,117,173, 22, 43,232,125,215, 81, 99,100,158, 51,197, 83,239,212,147,227, 26,209,211,190,121, 49, +157, 69,158, 22, 32,216,251,152,215,118,112, 88,121,162,159, 82,150, 38,234,122,173,151,107,182,113, 43, 19,150,126, 39, 26, 72, +245, 31,159,155, 16,109, 91, 97, 16,244,212,228,233,114, 18,173,243,233, 61,194,180,207, 72, 26, 33,140,102,173,225, 96, 17, 81, +216,193,151,145,195,214,241,123,135, 88,247,158,188,136,143, 19,147,197,135,134, 54,186, 25,237,199, 60,219,223,155, 42, 92, 5, +203,153,190, 0, 57, 83,244,251, 11,188, 54,195,175,110,209,191,246, 46,252, 39,167,200, 31, 22,232, 94,178,127, 48,157, 33,135, + 87,112,115, 3, 23, 51,250,168,179, 11,194, 12, 60, 82, 52,101,228,116, 13, 71, 61,112,233,197,162,183,199,182,153,151, 17,180, +190, 91,144,219,158,186, 85,253, 29,222, 21,223,153,186,119, 92,124,153,187,194, 2, 74,186, 0, 79, 77, 16,191, 11,164, 71,207, + 95,133, 50,120,204,170,143,182, 27,133,167,224, 69,181, 71,211,108, 22, 59,181,189,187, 32,230,253,107,251,145,171,186, 40,189, +161,120, 12,212,108, 65, 46,116,126,177,138,215, 32,253, 18,108,220, 37, 26,118, 92,213,228,193, 53, 41,236, 86, 43,235,180,187, +234,205,205,163, 46, 59,145, 53,187,188,120,209,104, 32,150,186, 67,158, 74, 76, 72,114,180,228,193, 64,248,240, 33,124, 47,200, +203, 43, 88,127, 22,134,159,118,110,202,219, 80, 30,192,107, 19,218, 91, 46, 51, 89, 77,136, 87,119, 31, 34,220,130,116, 77, 44, +178,183, 62,160,218,122, 34,204,123,159,197,180,123,235,209,226, 97,219,174,189,161,101,221,195,101,225, 82,230,137,183,220,110, + 63,164, 99, 69,182,130,188,158,161, 30,192,139,207,160,183, 30,195,244,215,145,211, 31,128,131,159,131,254, 51, 54, 34,151, 0, +221,119,193,141,255, 16,214, 63, 10,235,127, 0,243, 91, 48, 95, 88, 46, 88,197, 46, 93,185,216,123,121, 59,249,180,198,191,177, +241, 17,116,247,161, 27, 96,248,184, 69,173,214,251,246, 89, 24,110, 67,125,206,186,240,120,195, 19,218,130,117,244, 76, 32, 79, +237, 41,220,142,253,239, 36,200, 51,233,217,142,225,225,184, 36, 26,102,125, 18, 99,177, 11, 38,145, 38, 40, 13,166, 97, 8,197, +186,240,220,254,148,238,124,186,186, 11,155, 55, 1,169, 68, 43,135, 49, 44, 16,146,216,175,220,222, 88,172, 8,122, 86,117,221, +110,108, 30,144, 58, 98,136,116,235, 21,253, 38, 35, 90, 41, 34,100,148,132,208,249,228, 54, 7, 33, 99, 95, 63, 87,101,150,202, + 84, 21,242, 68,205,153, 88, 10,105,181, 38,118, 29,162, 7,150,152, 88, 38, 74, 46,100, 13,126, 21, 9,118,151,218, 94, 17, 31, +223, 39,222,120,150,120, 18,200,103,143,208,146, 17,241,228,185,154,109,199,238, 69, 77,202, 46,183,160, 74, 34, 19, 12, 58, 35, +134,105,182,105, 84,103, 69,147, 93, 23,134,184,232, 84,227,178,139,182,240,147,153,233,241, 61,226,173,142,238,246, 51,212,237, + 72,222,156, 81,167, 9,165,216, 22,190, 20, 42, 74,242,240, 26,245,118,177,248,197, 83, 42,232, 52,162,235,186, 64,160,240,100, +178, 50,141,214, 37,214,108, 35,225, 52,216,152,221,249,225,161, 27,200,115,134,216, 25,242,214, 97, 62,161, 31,144,110,112, 21, +252,214,142,153, 97,181, 84,147,138,141,221,197,147, 38,237,130,160,132, 20,209, 26,208,146, 23,222,185,248,254,187,161, 79, 53, + 4,106,158, 45, 98, 85,213, 97, 97,102, 85, 22,183, 41,182,247,148, 56, 12, 70, 28, 0, 84,197, 46, 93,161,121,174,221,189,176, +153, 38,143,151,236, 25,231,217, 94,175, 61,198, 64,138,129,185, 70,247,146,183, 21,138,229, 32,196,217,108,123,178, 48,237, 27, + 48, 74,247,151,212,187,222,141, 29,205, 15, 60, 11,194, 49,185,134, 24, 54, 24, 79, 39,145,174,239, 40, 65,216,142, 51,121,158, +141,239, 32, 98,221,120, 41, 75, 51,166,106,180,191,156,103, 3,208,236,237,191,244,218, 86,253,253,202,188, 59,125,244, 58,219, + 93,126,255, 80,214,221,146, 76, 42, 41,255,103,247, 60, 64,163,101, 64, 67,186,217, 81, 63,177, 66, 38, 65, 31,168, 21,248,151, + 35,242,153, 11,120,230, 1, 60,229,251,245, 77,112,252,170, 23,255,222, 81,169, 7,209,160, 41,238, 5,151,232, 59,199,208,192, + 44,183, 64,111,130, 62,211,124, 71, 16, 51,112, 5,199, 35,114,235,161,117, 47,211,140, 94, 9,114,149,224,211,135,240,195, 25, +253,194, 22,253, 59,151,112,145,145,159,121, 3,134,207,194,252, 97,144,115,232, 30,195,233,183,144,225, 2,125, 24,224,210, 59, +230, 51, 69,229, 28,185,113, 12,199,199, 32,143, 64, 59,100, 18,152, 12, 79,201,161,143, 75, 71,239,128,211, 19,177,117,189, 79, + 27,162,154,130,254, 57,255,243, 67,128,213, 22,226, 7,161,220,131,135,111,128,222,112, 52,108,221,189, 18,157,123, 11, 79, 6, + 91,226,135,115,227,126, 39,168, 91,211, 3, 72,106,109, 86,241,152, 86,105, 50, 81,167,168,101,144, 35,175,116,157,141,111,147, +123,236, 7,215, 58,204,123,240,156,230,177, 79,126,129,234,124,175,222,187,107,160,205,106,103,174,239,212, 61,209,110, 9,143, + 40,209, 97, 75,123,232,200, 20,136, 7, 61,225,249, 3,248, 76, 64, 62,124, 4,199,255,186, 21, 60, 57,130,252, 22,212,119,208, + 71,111,195, 93, 67,168,106,246,247,153,115, 85,212,189,179,251, 26, 61,226,130,196,182,207,192,188, 71,215,107,111, 97,223,237, + 47,172,246,253, 27,174, 68,170, 68, 66,153,177,134, 98,199, 21, 96,107,118, 61,137,123,144,149, 4,108,183,240, 14, 72, 60,128, +139, 27,112,121,129,222,248,127,144, 91, 95,128,211, 79,195,240, 51, 38,164,139,183,237, 57, 95,253, 65, 19,209,213,183, 96,126, +219,196,109,122, 14,211, 59, 48,127, 7,166, 71,112,112, 9,121,130, 58,185, 88,114, 54,229,250,112,234,227,247,151, 33,222, 1, +189,239, 1, 46,207,239,101, 41,174,188,192, 42,232, 99, 83,205,203,137, 95, 40,159,130,176, 70,142, 2,122, 27,194, 65,164, 63, + 10,116,219, 74, 31,217, 9,224,124, 28,216,108,130, 97, 25,189,123,104,144,143,126, 85,212, 5,105,174,157,144,182,183,140, 22, + 43,234,163, 15,109,123, 12,159,128,132, 16,157,149,110, 89,222, 57, 8, 69,130,113,222,183, 27,159,230, 8,177, 42,131, 88,120, + 70,113,165,120, 16, 33,123,238,124,160, 90,104,139, 56, 49,109, 54,143,114,219,173,148, 32,200, 54, 35,117, 36, 12, 43,211, 80, +116, 61, 26, 35, 57,206, 72,217,141, 80, 53, 8, 85, 42,108,206, 9,161, 39,157, 60,109,249,227,103,239, 82,203,180,236,118, 89, +122,182,246,191, 64, 14,145, 18,123,136,206, 51,119,223,124,157,204, 99, 78,173,232, 60,249,228,171, 67, 67,178, 66, 59,141,228, +105,180, 49,181, 8, 26, 7,100, 56,176, 20,180, 16,145,254, 0,166,129, 82,206,208,249,138,234, 23,167,216, 2, 37,117,145,152, + 45, 22,166, 32, 66, 26, 6,223,250, 25,129,174, 19,219, 33,211, 69,139, 83, 45,149, 90, 11, 41, 4,210,224,118,179, 96, 49,183, + 90, 3,121,218,144,231,201, 67, 90,140, 67,222, 50,226, 91, 87, 45, 82,141,225, 30, 58,132,106,151,164,217,152,251,203,100,209, + 39, 10,213, 45,109,197,129, 44,173,211, 7, 40,217,126, 45, 40,196, 62, 89,134,185, 79,110,234,222,250,162,185, 11,218,122,176, +250, 78,189,214,234,162, 87,215, 22, 84, 53,130,228,102,195,161, 8, 93, 63,176,189,186, 34,133,106,222,120,148, 84, 42, 93, 76, +108, 82,100,154, 60, 66,182,148,107, 35,234, 90, 42, 34,213,243,213, 77,131, 81, 99,244,238,190, 46,103, 71, 88, 70,124,190, 78, +108,137,107, 46,252, 75, 2, 93,234, 33, 38,182,165, 48,141,166,115, 16,159, 52,213, 82, 22, 69,189,131, 33,188,160, 79, 80,178, + 71,184,202,251, 84,101,225,247,255,149,157,224,240, 61, 37, 95,158,164,206, 57,254, 86,236, 93,157,222, 28, 10,131,128,172,132, +203,217, 68, 54, 39, 23,149,227,175,101,228, 78, 68,223, 41,240,166, 16,222, 73,200,107,157,249,193,159,235,172,155,125, 75,209, + 11,181,238, 90,156,175, 94,197,154,248,163,100, 93,225,179, 29,124,184, 67,158,143,240, 92, 64,110, 95,192,241,125, 56, 92, 33, +253,202,196, 72, 50, 0,167, 80,111, 65,237, 44, 71, 58, 61,128,248, 22,178, 62,135,211, 11, 19, 94, 62, 51, 32, 47, 13,240, 67, + 35,252,230,140,254,195,251,200, 79,253, 6, 28,253, 33,152,111,251,119,245,105, 88,127, 19,137,111,193,186,162,151,189, 21,132, +179, 8,114,142,220,232,144,227, 15,160,188, 9,115,132,210,217,190,189,100,180,137,157, 26,101,173, 41,142, 22, 84,143,207,136, + 59,221, 65,193,181, 56,236,225, 37,216,190, 13,151,179,121,155,103,103,169, 87,221,243, 96,249,248, 93,231, 29,224,166,119,123, +215, 69, 70, 52,217,161,179,113, 26, 87, 10,168, 70,139,132,173,225,122, 36, 41,186, 43,234,235,178,203,234, 22,139, 76, 52, 56, +143, 88, 87, 19, 92,193,222, 57,239,189,139,150, 12,215, 42,105,218,217, 96, 22, 38,121,149,221,247, 55,237, 50,224, 37,186, 77, +174, 75,132,163, 30, 94,136,230,159, 63,252, 19,112,248,175, 65,184, 97, 62,191,250, 8,228, 46,188,117, 31,238, 71, 52,206, 54, + 21,169,142,222,100,207, 50,164, 59, 83, 73, 45,239,129, 44, 45, 67,135, 29,212,204, 61,242,169, 13, 20,148,128,184,163,162, 99, + 39,139,182,142, 65, 60,177, 75,167,138, 92, 41,154,108,215, 74,149,197,147, 47,219,201, 4,148, 53,193,213, 10,222, 88,161,113, + 11, 47,127, 14,121,233,203,176,126, 9,186,239,134,245, 79,193,240, 49, 43,200,241, 25, 72,243,110, 23, 80,183, 86,220,243,235, + 48,125, 9,174,190, 2,243,185, 93,180,106,181,223,159,223,128,122, 10,242,125,150, 32,135, 23,118,237, 77,161, 41,105,231, 75, +215, 75,223,235,191, 11,241,216, 39,240,207, 67,247,148,249,192,111, 77, 72,151,232,110,116, 12,155,145,173,191,204,197,239,127, +181, 81,192, 84,233, 16,215,183,170,125,207,170,230,195,142,178,224, 92, 9, 22,202, 98,171, 50, 64, 50, 82, 92,184, 21,213,161, + 50,209, 64, 49, 62,202,111, 65, 23, 69, 3, 58, 95,161, 87, 23,246, 34,198,158,160,217,146,207,242, 12,142, 47, 21,204, 53, 49, + 19, 23,145, 25,218, 64, 35,251,157,139, 46,137,181,137, 10,121,164,214,108,250,137, 24, 45, 5, 45, 68, 98,138, 36,191,184, 69, +157,161,206,204, 85,201,231, 15, 17, 2,221,173,231,209,212, 49, 61,124,199,172, 96, 13,154,227,139,214,140, 48,213,106,217,226, + 82,173,185,232, 43,148,108, 17,162, 37, 35, 49, 18,251, 21,169, 95, 19,251,142,128, 50, 79, 51,101,187,161,204,141, 27, 30,237, + 60,235,143,237,251,217, 92, 50, 94, 94, 16, 14, 79,208,148, 8,235, 3, 19,222, 77,163,119,130,118,177, 41,110,175,139,146,144, +186,139,133,141,253,202,146,156, 15,143, 77,161, 94,103,219, 86,250,202,138, 24,168, 57, 51,109, 46,145,228, 23,144,121,182,203, + 86,180,124,249,198, 20, 8,221,128,196,222,137,139,133, 24,211,178, 94, 80, 96, 46, 70,109,139, 41, 17, 83,191,139,143,109, 43, +171,146,151,110, 51,165,222, 0, 42,165, 16, 90, 65, 22,183, 16,214,234,107,181,234,142, 22,251,108,135,150, 59, 46,215, 5, 50, + 18,133,168,137,216, 60, 24,173,168, 7, 3,221, 32, 1, 41,133,227,213, 1,225,240,144,237,102, 67,170,149,213,208,147, 99,101, +202,133,131,216,177, 90, 37,178, 86,166,108,105,133, 82, 93,133,142, 93,124,164,212,197,142, 24,163, 77, 72,170,211,238,100,223, +162,201,110,220,237,238,111, 82, 52,246,252, 12, 76,211,104, 19, 17,173,182,230, 36, 44,217, 11,162,126, 33,118,164,112,206, 51, + 58,103, 87,247,239,119,233,240,126, 82,185,247, 5,186,235,123, 75,190,136, 92,203, 91, 87,103, 17,214,189,110, 62,189, 21,196, +132,209, 1,102, 17,206, 29, 73,254,114,169,156,204, 48, 31, 42,227,182,178, 46, 74,216, 86,228,204, 88,175,225,227, 29,156,128, +110, 10,234,150, 17, 38,181,157,229, 28,144,115, 23,101,189, 29,144, 47,119,104, 67,213,137,249,188,229,102, 64, 94,137,240,241, +183,144,167, 3,220,234,225,228,208,201,109,135,182,163, 14,213, 14,186,116, 12,221,165,249,122, 87, 9, 61, 94,193,139, 3,188, + 58,162,255,252, 2,249,254, 95,129,211, 31,135,242, 28,132,183, 64, 95, 48, 58, 87,119, 23, 89,159,163, 23, 9,198, 1,221, 36, + 36, 62, 52, 16,201,241,135,208,252, 13,184,244, 14,182,136, 21,175,206, 5,125, 97, 15,180,139,238,197,127, 6, 91,242,186,133, +128,185, 9,217,158,131,241,243,150, 16,215, 72,119,237,235, 37,255, 58, 3,206, 48,159,109, 60, 63, 66,221, 20,139, 25,157, 42, + 28, 90,161, 85, 15,131,145,117,176, 17, 96,239, 58, 5, 85,208,139, 93, 91, 29,143,161, 91,195,209,165, 21,234, 80,156,164,231, +175,120,111,227, 61,243, 98,123,236, 94, 31,247,114, 56, 23, 0,246,162,118, 38,201, 50, 94,213,108,121,198, 82,117,207, 35,110, +185,227, 97,136,166, 13,184, 9, 28,156, 88, 80, 74, 60,222, 61, 79,245, 18,174, 62, 15, 95, 25,161,118, 22,162,145, 45,129,139, +154,109,247,218, 40, 88,173,160,191,143,206,141,125,171,214, 94, 97,183,200, 86,159, 36,184,157, 50,136,189,150, 58,244,134,108, +173,101, 15,163,232,254,117,203, 30, 53,162, 93,181,110, 83,163,119, 15, 83,177,204,249,171, 10,155,138, 94,116,240,234, 0, 31, +201,240,241, 87,145, 27,175,194,225,175,192,241,207,192,225,207, 65,252,192, 46, 0,136, 96,171, 17, 57,134,248, 28, 12,159,129, +245, 59, 48,126, 1,166,175,192,252,200, 47,128,231,192, 55,129,135, 16, 62,224,182,134,167, 65, 31,250,184, 61,238,201,214, 71, +208,119,172,219, 15,207,218, 30, 33, 28, 64,255,221,208,125, 1,110,157,193, 97, 34,174, 35,235, 36, 92, 86,101,148, 29,156,208, +242,201,189, 19,209, 93, 90,147,237,132,155, 90,217,118,164,154, 2,237, 86,219, 12,134,185, 85,221, 96, 91, 89,149, 72,110, 40, + 88,221,241, 0, 10, 66,221,110,209,121,235,124,116, 43,248, 93,205, 12,209,192, 24,165, 76, 8,193,212,234, 18,152, 37, 90, 38, +184, 35, 67,231,118,181, 8, 46,102,107, 20,221, 96,157,162, 77,116,204, 54, 84,107, 33, 75,166,120,158,120,236,204,158,213,165, + 53,154,131, 21,220,170,212,243,119,141,188,120,243,121, 11, 49,121,248, 54,184, 47, 30,129,210,224, 60,190,239, 45, 45, 71,123, +220,186,165,205, 60,149, 49, 25, 52, 40,228, 12,213, 98,100,179, 88,174,186,148, 98, 26, 33,247,187,151,243,135, 6,149,113,145, +161,204, 91, 66,191,166, 59, 56,130,213,177,165,143,229,173, 61,247, 5,178, 4, 75,108, 22,217,189, 68, 53, 48,111,206,169, 85, +136,199,167,132,131, 3,168,106,202,238, 75, 3,217, 72,103,233, 97,217, 73,209, 18,237, 82, 48,231, 76, 17,179,237,117, 26, 40, + 90, 92, 75,225,153,236,177, 51,112,148,119,119, 45, 92, 71, 20, 7,204,224,130,174,157,117,172, 98,132,180,226,204,245, 90, 89, +138, 93,187,216,213, 90,125,252, 93,201,222,249,198,101, 50,178,163,185, 73,179, 89,138, 21,214,144,170,175, 48,118,161, 52, 49, + 37, 91, 35,186, 0,174,215, 74,127,116,196, 35,181,243, 35, 41,244, 93, 79,144,204,228,197, 57,170, 16, 16,102, 9,228,154, 77, +252, 89,138, 9,232,156,183, 27, 36,144,107, 48, 0, 78,140, 22,218,211, 40, 12, 98,176,153,184,100,181,219,132,163, 32,140, 45, +218,184,113, 1,170,173, 11,179,103,200,155,117, 54,184,138,223,136,120,117,158,237,220,148,253,204, 5,253,125, 67, 89,158, 20, +194,233, 30,146, 70, 91,216,177, 92, 23,212,233, 94, 14,235,110,199, 46,164, 92,119, 13,153, 79,136, 57, 87,184, 8,202,113,168, +200,161,145,155,250, 78, 9, 87,246,141, 49, 43,186, 13,200,105,178,189,113,169,232,166, 48, 7,101,219, 97, 99, 18, 12,110, 17, +178,216, 14,171,120, 49, 31, 77,224,171,239, 8,250, 53, 49,212,220, 65, 68,142,183,240,252, 6,189,115,128,222, 1,185,117,134, +156,142,200,177, 32, 55, 58,184, 97,200, 83,214,213,146, 41, 59,224,123,214,232,163, 30,125,227, 2, 41,255, 4,110,253, 36,240, + 33,224,235,118, 80,202, 51,112,112, 23,233, 94,131,241, 18,221,174, 97,234, 96,188,107,135,247,233,243,232,230,219,240, 86,179, +118,249,104, 55,184,173,173, 5,165,180,133,173,250,220,120,222,185,139, 12,243, 26,140, 57,191,253, 26, 20, 27,203, 49,122,167, +184, 0, 57,246, 98,239,166, 43,120, 87,225,145,101,160,163,216,158,121,107,193, 9,250,112,164, 62,206,200,105, 79,172,106,227, +177, 41,160,155,138,148, 7, 94,225,162, 21,144,238, 24,250, 75,239,212, 3, 18, 20,205,123,243,232,125,188,105,220, 89,217,180, +229,188,143,102, 43,220,221, 12, 93,229, 63,202,110,223, 94,118,153,206,162, 30,239,216, 59,136,103,104,170,108,113, 81, 76,133, +242, 8,242, 23,209, 55, 95,131, 55, 58,180, 47,158,205,222, 2,121,212,187,106, 27,131,235,123, 60,154,186, 3,203,236,143,214, + 91, 97,247,193,135, 54, 97,120,217, 9, 94, 68, 4, 73,189,105, 63,212,187,113,247, 6, 83, 48,116, 99,113, 75, 75,240,238, 93, +130, 57, 36,122, 19,124,105,142,246,189, 20,129, 81,208,175,173,224, 98,128,211, 13,220,120, 27,249,174,191, 13,183,127, 3, 78, +254, 42,244,175,248,251, 98,222,137,234, 8,118,131,235,190,203, 64, 50,235,127, 9,242,183,160,220,117,241,219, 5,112,215,191, +145,198,146,127,202,226,116,235, 3,127,160, 29,148,183,160,190, 10,241, 19, 54, 1, 48,107, 4,244,159,134,120,108,193, 69,167, + 25,190, 19,233,214, 66,188,220,187,208,181,240, 10,183,169,213, 61,158,123, 91,173,171,236,104,105, 82,132,162,217, 46,116, 41, +162, 41, 81,114, 37,116, 16,164, 67,163,197,103,106,158,151, 93, 59, 85,169,157, 91,143,218,175, 71, 59,220, 18,149, 21,202,160, +194, 40, 66,173,149, 46, 84,130,122,182,185, 43,200, 43, 38,168,170, 62,154, 13, 65,232, 37,120,114,154,113,212, 3,214, 81, 55, +135, 90,240, 81,166,184, 90,160,150, 74,183,205,196,213, 10, 82,231,154,146,217,198,204,103, 15, 64, 18,233,198,211,228, 24,168, + 15,223,129, 50,154, 64,207,159,131, 42,106, 90,128,118, 79,172,217,239,175,226,112,157,104, 54,172, 60, 81,199,201, 30, 75,191, +118, 61,139, 32,193,214, 1, 58,110,209, 98, 43, 6, 13, 54,233,210,108,162, 62,219, 21, 71, 66,234,157,193, 48,146, 75, 38,107, + 37, 68, 49,145, 56,129,185, 42,105,181,182, 46,143,128, 76, 19, 33,246,206, 49,168,132,213,218,117,198,197,209,179, 9, 73, 61, + 49, 36,106,176,132,187,185, 20,230,185, 16,253, 57, 43, 87, 23,196,212, 19,250, 97,161, 1, 6, 32, 13, 43,214, 7,199,244,131, + 41,205,203, 92,216,110, 47,152,234, 22,212,108, 93,177, 75,206, 52, 55,113, 93, 94, 10,187,217,197,196, 85,236,181, 20,211,171, + 56, 44,166,214, 76,206,101, 25,211, 43, 59,177,106,219,203,183,233, 95,104,113,184, 94,212, 67, 8,134, 82,173,106, 96,165,121, +230, 36, 38,230,213,138,203, 77,101, 44,133,224, 29,241, 14,233,106, 96, 35, 9, 16,138, 16,164, 16, 66,160, 22,115, 5,152,229, + 78,246,118,222,118,132,166, 96,197, 61,133,176,192,163,218, 78,187,248,101,165,199,244, 7,147,154,128,211,148,251,213, 60,232, +152,123,160, 46,148,189, 74,158, 38, 19, 41, 62, 9,130,218,211,189,255,126,241, 85,215,164,240,203, 17,168,123,244,184, 61,107, + 94,219,165,239,123,219,137,164,140, 18,171, 44,225, 45, 7, 2,227,158,248, 58,246, 74, 10,234,249,205, 14,175,152, 11,122, 47, + 35,183, 34,242, 84, 64,167,128, 94, 22,255,160,122, 98,155, 71, 3, 70,160,155,149, 48,219,184, 69,171, 80,170, 34,197,139,126, +157, 9, 36,170, 36,228, 91, 19,252,238, 21,178,186, 64,159,126,138,154, 14,225,236, 10, 25, 39,136, 21,121, 94,144, 31,238, 9, + 31, 79,200,109,139, 74,149,161,135, 27, 39,232,163, 11,228,221,127, 4,183,126, 2,228,135,128,239, 88, 34,151,222, 54,250, 90, +250, 58,210,223,181, 46,185, 14,144,223,134,238,121,228,185,231,168,211, 91, 22,215,170,150,181,110,241,134,123, 50,236,165,178, +236, 5, 65,204, 30,206,178, 6, 89, 31,217,179,250,240, 45,208,149, 23, 75,221,129,122,100,143,244, 57, 1,239, 22,184, 59, 81, +239,205,118, 24,138, 53,105,234,254,174, 58, 86,242,182, 16,238,111, 76, 97,189, 82,226, 16,144, 71, 64,249,246, 94, 92,216,129, +119,110,174,218,223,216,165, 67, 34, 59, 21,166,236,217, 21,147,119,234, 45, 70, 54, 59,108,122, 73,255, 48, 85,175,110,117, 23, + 49,235, 93,141, 68, 47,234, 67,176,130, 46,201,218,229, 62,219,250, 68, 39,179, 97,213,115, 24,191, 12,231,255, 7,124,181,122, + 22,113,177, 21, 67,118,213,187, 96,170,247, 37,157,109,135, 31,109, 42,214,253,205, 39,123,247,147, 86, 51,165,114, 45,124, 4, +113,238,123,114,127,109,112, 33,225,126,120, 71,195,200, 78,160,189,151,186,224, 47,118, 27, 13,150,106, 23,159,236, 43,141,222, + 11,252,121,133, 71, 17,206, 87,232,183,102,248,190, 47, 33, 47,255, 2,156,254,151, 48,124,175, 79, 40,182,123,159, 72, 23,128, +146,172,203,238,239, 88, 97,214,251, 54,134,103, 6,238, 3, 47,238,169, 75, 87, 86,184,235, 99,123,204,227, 47,217,107, 29, 94, +114, 40,142,211,136,210,203, 48,124, 8,142,222, 36,188, 88,224,247, 18,129, 64,175, 13, 60,180,203, 94,217, 57, 10,196,176,204, + 93,135,206,121, 73,255,106,118,180, 37, 26,178,218,123, 67,165,218,158,174,216,231, 90,243,236, 93,181,227, 96, 5,180, 75, 54, +222,205, 51, 69,108,252,184,184, 38, 69, 22,115, 73,213,221, 24,189, 74,100,174,118, 0, 22, 95, 21,181,184, 82,212,236, 67, 49, + 37, 75,124, 43, 21,130, 46,217,218, 79,180, 36, 14,231, 16,146, 40, 93, 80,164,108, 33, 24,141, 78,114, 89,102, 14,245,241, 61, +163,131,221,124,142, 26, 2,250,240, 77,170, 23,118,162,175,109,234,206,175,220,128,155,193,179,209, 21, 65,156,158, 70,205, 38, + 24,172,149, 48, 12,148,170,148,237,149, 23,243, 22,108,211,140,136,254,252,170, 50,111, 46,156,238,216, 91,135, 27, 7,234, 28, +209,121, 7,168, 81, 42, 50, 28, 18,143,111, 83,183, 87, 11,194, 54, 87, 69,231,173,237,200,135, 53, 97, 88,163,211,214, 10,181, +199,215,230,121,180,221,174,135,178,162,222, 93, 74, 52, 1,158,139,186,114,173,104,169,190,113,179, 51, 98,154, 70, 66, 76, 84, + 53,177, 92,243,194, 39, 9, 38, 78,108,179, 27,223, 99,151,190, 50, 59, 30,182,228,217,128, 62, 34,164,212,177,228,200,186, 82, + 61,123,242,155,209,220, 10, 82,101,209,115,180,136,224,253,177,251,114,220,170,193,131,156, 89,198, 58, 70,182,195,138,113, 59, + 82,146,178,157,103, 74, 53,197,119, 3,207,224, 83,170,152, 2,189,167,201,217,197,204,186,248,224,164, 78,117,204,116, 23, 2, + 41, 24, 80,104,246,149, 66,174, 74,214,106,184,217,170,164,104,175,205,182, 86,166,105,132,106,159,149,166, 53, 8,126,217,205, +165, 50,151,153, 50,206,203, 90, 67,222,131,137,227, 90,108,241,255,255,244, 93,223,143, 6,239,161,183,122, 77, 72,247,100, 54, + 67,202,106,246, 1, 92, 59,181,138,194,202, 39,182, 90,236,236,142,193,254,145,217,155,214,132,208,159, 27, 47,156,219, 29,114, + 51, 16,206, 3,105, 83,204, 82,227,206,175,169,133,170,181,129, 65,221, 75, 33,141, 74, 47,202, 80, 43,195, 69, 33,229,130, 30, + 4,131,153, 48, 33,103, 19,220,184, 65,205, 9,238,206,112, 57,193,215, 20,253,229,142,186, 78,200,103, 2,225,103, 6,228,149, + 1,185,145,144,131, 99, 56,223,192,227,127, 4,199, 23, 16,255, 21,235,134,228, 29,224,131,160, 31,131,238,235, 16,191,100,135, +102,237,188,176, 63, 67,120,233, 14,250,232, 30,250, 45,127, 90, 98, 53, 79,171,132,235,166,104,217,251,113, 96, 99, 24,142,170, +237, 70,235,119,224,209,235,118, 97,104,223,228,210, 45, 7, 59,195, 59, 15,152,185, 63,193,131,209,198,236,106,123, 17, 29, 43, +122, 81,151,119, 66,233, 76, 40, 21, 74,166,142, 16,106, 68, 30, 70, 75,241,210,173, 89,157,164, 55,144,137, 56, 20, 40, 98, 79, +190,232,142, 94, 39, 59, 56,138,237,211,221, 58, 55, 22,227, 10,140,126, 1, 96,207,210,150, 29,150,211, 9, 82, 93, 8,217, 70, +185, 93,178, 76,246,152,224,164, 26, 68, 39, 60,103,197,107,190, 11,243,215, 97,252, 71,232,215,223,129,111,117,104,200, 38, 80, +115,145, 90,187, 23, 45, 22,182,125, 24,195,242, 65,223,137,188,158,244,113,162,120, 76,237,245,203,146,186,237,205,132, 71,158, + 72, 87,154,229, 96, 9,232,178,127,116,202, 86,240, 15, 35,210, 86, 66, 88,106,156,133,235,120,136, 76,241,231, 45, 57,235,158, +106,169,111,191, 19,224,221, 1,253, 3,175, 35,159,250, 43,112,235,111,192,240,131,254,141,108,159,248,120,238, 41, 80,229,196, +138,182,220, 7,238, 1,103,192, 99, 12,196,236,170, 69,185,101,157,252,230,127,134,243,175,194,250,123, 32,157, 65,124, 23,240, +113,127, 56,130,245, 31,132,139, 47,193,203, 35,114, 59, 17,239, 37, 86,151,153, 74, 32, 39,155, 60,197,234,239, 45,191, 51,100, + 81, 84,178, 25,156, 90, 39,233, 89,246, 90,240, 84, 49, 7,180, 84, 47,166,101,246,199,229,172,247,152,208,212,147, 5,243, 91, +207,121, 73,247, 17,177, 78,125, 21,132,163, 40,196, 46, 50,230, 74,204,153,222, 95,132, 82,161, 96,200,204,186,151,198, 39, 46, +160, 18,117,107,142, 43,200,236, 82,224,118,161,234,151,203,246,150, 84,107, 26,146, 88,162,155,212, 66,157, 38,232,147,241,232, +167,201, 87, 48, 21,125,120, 23, 81, 33,221,126,150,148, 6,120,248, 29,202,120,229, 39,147, 34,209,120,228,197,253,243,193, 25, + 12,100, 83,125,167, 16, 44,128, 6, 59,200,101,125,140, 14, 3,170,151,212,121,182, 29,117,158,140,191,230,133, 4, 9,166, 14, +247,231, 39,231,130,150, 45, 93,234, 12,217, 28, 59,130,154, 98,181,184, 7,188, 63,126,202, 82,225,106,165, 27, 44, 47,160,186, + 98, 58, 68,131,161, 72,201, 84, 9,244,195, 26, 73,145, 92,148,162,230, 43,159,171, 82, 66, 90, 46,182,226, 66,179,154,231, 37, + 39,158,100, 2,213,113,156, 24,183, 38,232,139,157,103,140,135, 64, 74, 29,161,249,192, 29, 2, 20,170,177, 32,146, 11, 21,195, +106, 77, 85,101,158,103,230,121, 98,154, 39,242, 60, 51, 23,131,228, 52, 34,220, 16,141,155,110,200,146,202, 84, 10,197,197, 99, +141,250,182,104, 51, 60, 88,166,122,119,159,130,112, 35,118,220, 57,185,193,176, 58, 64, 46,206, 65,212, 26,199, 82, 40,185, 77, + 84,204,102, 56,187,159,191, 93,208,163,152,183,189, 11,145, 16,133,136, 16,196, 44,190,234,232,216,109, 41,100,173,204,213,126, +100,199,220, 26,144,199,214, 51,185, 90, 4,171,197,118,135,197, 5,160,130, 69,197,214,194, 60,153, 83,131,170,239,201, 57,223, +157,117,250,190,181, 92,121, 66, 71,212,178, 45,174, 65,107,119, 54,211, 38,254,181,231,184,219, 35, 83,216,229, 40, 77,186,151, +183,220,153,144,186,129,123,202,236, 60, 13, 49,224,132,224,184,187,168,196, 92,145,123,133,176, 22,228, 52,162, 87,149,244, 78, + 37,141,186,131, 95, 40, 20, 21,182,218,130,190,236,131, 28, 69,232,170, 48, 5, 97, 20, 88,169,178,218,206,164,109, 32,117,130, + 92, 5,228,234, 2,185,191, 37,164, 3,234,233, 9,156,246,176,157,237,240, 43,138,126,169,162,159,191,180,130,254, 99, 3,242, +199, 15, 9, 47, 28, 89,177,222,254,223,208,223,133,238,207,249,206,242, 45,235,106,229, 71, 64, 94, 6,249,191,172,216,215, 9, +230,123,144,158, 66, 62,125,104, 35,250,111,121,129,156, 20,142,117, 81,128,238, 60, 94,123,210,236,206, 70,222,196, 3, 24,127, + 13,222,245,217,112,206, 22,148,210, 2, 62, 74,181, 91,210,141, 30,206,172,168,235,189,217, 20,179,157,171,145,175, 10,122,149, + 45,196,229, 72,232, 6,161,230, 54,181,247,248,195,139, 4,211, 99,239, 0, 39,239,142,247, 96,192,109,204,238,182,165,133,247, + 73, 48, 11,212,202, 15,243,234,214,193,246,194,204,186,151,161,234, 74,250,162,206,149,110,194, 57,219,239,135,163, 1, 57, 30, +224, 52,192,199,102,228,230,243, 48,252,128,189,121,198,175,192,244, 91,112,247,171,240,197,104, 35,119,205, 6, 73,107, 30,206, +246, 33,174,126,107,189, 38,150, 50,145, 16,125,114,112,200, 94, 65,126, 2,169,212, 36, 46,193,209,189, 34,230,145,150,220, 38, +140,201,199, 34,126,201,137,178,227, 35, 87,215, 77,108,130,241, 10,210,222, 5, 97,244,223,155,125,138, 17,162, 77, 95, 92,163, +160, 43,167,142,223,235,224,159, 30,160,243, 93,228,123,254, 50,220,254,239,189, 99, 15, 30, 8,240,164, 89,165,209,150, 34,200, + 29,175,112,175, 66,253,135, 16, 62, 1,241,211,254,228,251, 56,103,254, 85, 19,207,233,224,153,222,231,246,186,139,133,166, 48, +124, 10,142,239,192, 7,207,144,143, 9,233,141,158,213,227,137,195, 45, 92,134,224, 73, 99,106, 20, 47,236,114,110, 22,225, 4, +201,248,223, 58,109, 13, 42,212,202,123, 21, 52, 68, 99,194,199,232,185,230,189, 21,172, 96,254,223, 18, 18, 37, 23,230,121,132, + 92,155, 81,194,144,193,173, 75,239,132,222,157, 77, 33, 4,250,176,131,251, 21,177,139, 70,245,241,121,179, 59, 5, 85, 7, 25, + 41, 81, 77,197,156, 21,230,178,231, 31, 14, 59,228,126,140,248, 24,217,132,102,226,241,129, 90, 11, 58,110, 32,249, 40, 62, 27, + 52,165,212, 74,126,124,151, 33, 6,134, 59, 47, 66,215,163,239,124,147,122,117,101, 95, 39, 38,235,220, 21, 35,208, 5,183, 62, +133, 74,234, 6, 82, 55, 32, 90,169,209, 86, 77, 26,204,179, 31,135, 3, 27, 55, 79,227,114,122,167,208, 48,204,182, 72,170, 82, +209,160, 11, 14,185,250,123,182, 32,132,174, 39,106,180,116,198,216, 33,195,154,105,220, 26,192,167, 27,168,106,232,211, 42, 70, +124, 11,254, 53, 66,111, 48,148, 80,246,146,192,250,222,222,183,165,154,250, 92,133,152, 58, 66, 63,120, 8,137,249,209,107, 41, + 30, 42, 98,153,228,193, 59,203, 24,109,205,144,231,217, 62, 50, 49,185,115, 66,137, 24, 23,126,118, 12,109,244,213, 68, 31, 19, +235,174, 67, 56, 98,170,133,105,158,153,199, 43, 74,174,204, 53,147,231,201,198,209, 98,192,150,117, 76,164,174,167, 11,150, 79, + 81,213, 10,120,192,179,228,177,245, 94,215, 69,142,250, 21, 7,253,138,208,117, 92,109,174, 88, 9,140,195,138,237,118,227,211, + 1,131, 7,141, 90, 25,199,140,186,143,188,105, 38, 50,202, 84,202, 50,221,169,110,163,221,239,122,131,135,117, 53,183, 72,109, + 83,164,182, 54,208,166, 44, 23,183,236,205,136, 71,181, 26,193,174, 24,129,111,206,239,203,106, 23,185, 38,102,127, 95,167,250, +147, 96,173,221,172,104, 79, 14,228,220,108,105,178, 96,221,249,213,209,110,207,237, 14,241,207,223,137,191,216, 7, 97,149,132, + 30, 33,133,221, 4, 37,185, 78,126, 42, 70,101,202,123,177,174,162, 98,109,126,117, 91, 87,167,200,133,137,195,178, 55,131,185, +194,168, 98, 31, 78,245, 4,210,197, 2,189, 75,128,202,200,222,206,204,189,196, 27,133, 77, 65, 98,129, 35, 69,110,172, 97, 53, + 88,251,209, 85,184,217, 33,199,197,118,160,191, 51,193, 63, 30,209, 71, 17, 94, 88, 35, 55,215, 16,222,132,250, 37,144, 79,130, + 60, 15,114,233,190,250,103,205, 62,196,125,144, 51,107,241,106,129, 97,128,167, 19,220, 47,240,157,178, 83,104,118,114,157,140, + 18,247, 82,193,146,219,247,110, 36,244,242, 46,252,222,149,253,165, 11, 47,148, 1, 47,164,158, 81,251,204, 0,239,108,225,219, + 35,250,206,214,195, 12,116, 23,160,162,246,231, 91, 55,194,228,225, 7,158,161, 28,110,245,200, 39,176,148,182,112,106,226,170, +139, 95,134,179,199,240,174, 39,194,213,186,167,214,247, 19,119,101, 20, 59, 57,237,209,181,195, 66,206,178, 97,114, 47, 76,168, +183,248,202,252, 16,221,117,249,118,179,141,177, 35,220, 92, 33,119, 14,224,165, 8,159,152,145, 23,143,224,232,167, 97,253,125, + 80, 46, 96,250, 50, 92,253, 26,250,169,114,251, 17, 0, 0, 32, 0, 73, 68, 65, 84,107, 27,120, 75, 80,201,232, 88,168, 91,191, +228,108,138,223,208,237,178,167,123, 84, 87,109, 35,180, 61, 32,133,244,105,137, 56, 92,118, 71,254,184, 44,149,104, 23,188, 32, +205,237,174, 1, 14, 79, 32, 87, 36,111,175, 97, 21, 5, 75,192, 67,157,177, 31,205,174,101, 95,203,158, 3,105, 56, 76, 45,254, + 92,218,141, 97,137,235,221,248, 42, 97, 16,184, 12,200, 55, 18, 12,231,200,237, 95,130,244, 65, 27,141, 91,138,203, 19, 81,137, +126,243, 88, 62, 65, 39, 16,158,183, 63, 91,254, 25,212,175, 65,248,144,173, 50,194, 83,144, 62, 11,252, 6,232, 35, 72, 47,218, +154, 37,220, 48,187, 32, 2,233, 0,134,111,131,124, 19,206, 70,248, 54,232,121, 70,199,153,243, 86, 12,171,239,138, 37, 80,131, +197,161,198,104,169,104, 90,157, 97,239,183,123,195,178, 58,239, 59,244,150, 15, 30,130, 23,115,203,238, 46,170,228,113, 36, 79, +219, 37,175, 92,154,205,209, 59,135,149, 8, 7,193, 21,241, 53,147,176,168,202, 73, 97,110,137,126, 33,238,184,222, 65, 12,247, + 42, 74,223, 80, 8,126, 47,173, 40, 99,109,124, 40,117,210,178,253,108,130,166, 96, 50,145, 40, 22, 45, 28,130,195,136,204, 98, +100,128,164, 97,103, 49, 82, 53,159, 55,133,238,240,148,178, 62,102,206,179,115, 16, 58,163,225,121, 54, 55,121,178, 93,109,236, +124, 20,109, 83,136,130, 51,188, 85,208,144,108,199,188,185, 68,203,228, 81,157,178,224, 70,139,154,184,144, 16,173,227, 13,174, + 71,113, 70,135,166,158,212,175,232, 87, 43, 66,236, 72,135, 39,164,147,167,200,170, 70,130,235,250,229,220, 41,213,226, 58, 67, + 12, 72,215, 67,232,150,176, 41,155,100, 24, 33, 79,252,223,104, 83, 21,130,115,209, 99,180, 11,198,108, 29,187, 41,213, 11,129, + 64,236,122,186, 24, 57, 60, 57,229, 71,127,254,207, 50,172, 15,120,116,247, 29,138,136,165,175,213,194, 39,127,234,143,240,185, + 95,250, 63,185,247,224, 46,119,239,190,205,219,119,223,226,157,187,111,114,247,193, 93,238, 61,188,207,221,119,239,114,255,193, + 61,206,206, 30,113,181,217, 50,205, 54,170,142, 98, 52, 56,245,154, 48,123,168,138,122, 34, 95, 31, 34,171,212,177,238,122, 14, +251, 21,167,195,138, 59,199,167,220, 58,189,197, 48,172, 44,222,118,115, 73,158, 70,219,159,107, 69, 84, 57, 61, 62,225,199,255, +220,159,229,213, 47,127,197, 59,244,178,156, 31,226,147, 18,107, 70,171,103,163,151, 61, 84,172,122, 70, 59,187,145,123,105, 49, +177,197, 71,239,117, 7, 31,114,146,162,106, 93,152,248, 5,152,243, 68, 25, 39,211,233,236, 21,230, 39,169,112,186, 31,210,242, + 62,230,181,182,250, 86,239,118,228,201, 77,186, 88,189, 21,194, 14,138,166, 21,149,226,188,196,221, 24, 89,130,144, 14, 61, 57, +178,209,185,216,195,186,103,255, 64,181,228,208,236, 93, 97,135, 9, 59,194,172, 12,239,100, 27, 91,222,244,177, 93, 18, 27,213, +136,144,189, 25,212,165, 25, 18,206,171,237,237, 69, 76, 68,227,182, 87, 70, 31,215,231, 96, 92, 23, 91,219, 9,177, 40,146, 55, +232,168,232,234, 20, 14, 14,108,204, 94, 42, 58,116,136,142,246,111,231,130,254,250, 25,250,165, 45,252,200,128,252,203, 55,145, +103,206,161,252, 77,208,159, 7,249, 12,240,192,138,123,120, 14,248, 9, 40,255, 0,120,219,104, 88,219, 13,178,234,145, 31, 89, + 25,138,251,181,209, 58,236,117,128,126,159,110,178, 36, 97,120,135, 28, 80,221,194,131,201, 70,186,115,221,117,191,157,236, 58, +227, 67,127,146, 31, 87,244,188, 80,183, 21, 58, 93, 70,210,210, 57,237,110, 72,190,151,171,132, 42, 30,219,231,212,178,123, 1, +206, 46,225,206,107, 86, 64,242, 35, 3,158,148,189,180,141,208,172,111,123,124,250, 46,182, 48,123, 15,219,241,123,226,236, 35, +235,232,168,206,104,143, 63,212,134,165,245, 98,152, 2,161, 27,224,233, 21,124, 12,120, 57, 35,199,119,224,240,143,195,250,199, +236, 11,108,127, 11,166, 47,163,191,253, 8, 94,239,160, 27,225,170,152, 16, 45,219, 30, 79,252, 18, 83,159, 12,104,121,226,131, + 32,186, 23, 10,148,146, 69,107,182,240, 16,252, 2, 20,158,128, 37,183, 55,123, 23, 27,208,244,186,114, 30, 15,142, 40,123, 41, +166, 62, 61,208,236,170,255,192, 46,143,122,210,189,165,216, 8, 99,112,156,170,203, 83,174, 50,162, 51,114, 25, 8,255,251, 33, + 90, 30, 33, 63,240, 11,112,243,207,195,240,115,198,122,151,190,209,115,124,106,224,214,207,234, 59,119, 18,132, 87, 44,160,167, +252, 42,148, 95,129,244,211,182, 91,239, 62, 3,199,127, 21,182,127,211,213,242,207,216,100,198, 4, 29,198,123,168,159,133,241, + 55,224,233, 51,228,131,137,244,118,199,193,163,137,195,154,217, 22, 89, 6, 18, 82,131,183,182, 74,165, 16, 82, 93,178,196,171, +159,110, 26,219, 94, 82,172,227,147, 72, 80,139,230, 44,192, 56,110,209,121,244,104, 83,217,177,173, 91, 78,128,182,139,153, 79, + 93, 36,208, 73, 32,105, 97,171,187, 97, 80,231,251,239, 33, 6,211,214, 44,251,241,176,100,193, 77,234, 69,172,217, 20,219, 39, + 79,219, 68, 1,178, 86,186, 8, 67, 8,203,251, 85, 37, 18, 82,164,211, 66,168, 74,174, 19,193, 5, 86,121,154,137, 85, 81,205, + 76, 15,239,153, 92,226,246, 75,172, 63,240, 41, 54,247, 95, 39,159,221, 71,197,233,107,193, 32,254, 18, 19,178, 58, 48, 11, 87, +181,116,175, 50, 57,195, 91,146, 61, 31,243, 72,168,217, 27,146,232,145,174, 30, 39,171, 97, 81,123,107,173,182, 74,243,209,110, +198, 86, 27, 21,208, 48,208,157,220, 38, 29,223, 68,227, 64,127, 96,194,194,178,189, 68,199, 43,164, 91,161,253, 26, 21,243,127, + 75,177,195,188, 74,235, 52, 27,107,223,172,117,209, 97, 84,115,182, 84,183, 34, 24, 49, 14,155, 58,118,222,185,183, 61,120, 5, +234, 60,115,231, 67, 31,226,222,183,223,224,198,179,207,112,118,126, 70,201, 51,115, 54, 75,223,118,115,193,246,226,140, 32,214, +241,215,146, 45,143, 93,240, 75, 68, 0, 13, 11,141, 79,213, 82,248, 68,108,114,145,186,142, 33,245,196,100, 89,236, 83,136, 92, +205, 35, 41, 68,250, 24,137,203,215, 80,130, 60, 32, 73, 96,136,145,148,204, 31,191,201,153,139,105,107, 32,154,156, 73,195, 64, + 86,184, 28,183,182,235,102,183,117,212, 70, 8,109,110,138,134,123,209,221,123,169,161,101,151, 81, 58,187, 11,234,114, 14,133, +176, 20,226, 36,130, 74,178, 49,125,206,228,236,197,188, 33,110,247, 36,112,239,217,152,251,170,104,247,165,229,125,187,244,107, +169, 86,187,227,215,173,108,238,244,105, 99, 78, 41,123,171,250,188, 56, 12,170,118,196,191,248,108,252,197, 5, 12,231,147,214, + 46,226,111, 12, 24,171,176, 45,215, 19, 68, 77, 16, 45,254,228, 9, 97,171,132,173, 46,208,139, 17, 97,204, 62,110,115,203, 75, +138,118,200, 92,150, 93, 10,105, 23,109,156, 63, 86, 97,198,240,166,234,170,249, 78, 28,112,226, 34, 48,161,194, 52,219,205,187, +239, 29, 18,131,225, 85, 59,103,167, 31,250,112,235,247, 38,248,167, 19,156,156, 34,207, 22, 24,126,211,111,188, 63,232, 42,162, + 11,199,111, 86, 19,212,213, 45,148,222,254,123,165,240, 76,130,111, 84, 56,159,144, 99, 15,151,175,251,123,117, 31,171, 15, 98, +187,245, 62,193, 55, 71,239,208,205, 14,101,194, 1,177, 98, 90, 5,158,239,172, 48,124,107, 68, 31,249, 62, 29,221,169,194,241, +224,149, 24, 60,103, 59, 32, 67,180,159,147,221,192, 67, 72,240,145,138,220,121,202, 70,189,243, 59,112,249,107,240,232, 18,185, +240,130, 85,116,201,243, 54,216,182,141,221,229, 32, 89,142,186,143,214,185, 40,240,200, 11, 88,187,117, 21, 89, 30, 11,209, 31, + 67, 76,132, 97,128,103, 87,240,169,138,124, 12,228,244,135,224,244,223,135,131, 63,108,225, 50,229, 62, 76,191, 14,111,126, 1, +190, 96,139, 83,205, 5,221, 90,148,171, 69,186,170,223,154, 93, 4,255, 62,206, 53,217,171,205, 44, 59,214,106, 62,125, 28,160, +145,134, 38,242,240, 27,185,143,113,147,253,121,243, 11,175,145, 57,195,188,181, 61,152,143,121, 23,108,108,240,215, 47,201,146, + 75,108,100,228,128, 36,208,209,237,136, 52, 53,121, 53,229,108, 8,203,250,135, 90,209, 41,163,204,212,115,144,175,172,145, 56, + 33,183,190, 8,252,115, 35,233,213, 51, 8, 87,166,123,224,166, 91, 42,216, 79,189,246,125,245, 33,132,143,218,239,235, 35,239, +198,171, 89,222,226,167,128,215,124,236,126,211,185, 14,106, 23, 6,141, 48,253,142,237,232,231, 25,222, 86,228,108, 70,230,202, +165, 68, 54, 26,125, 5,100, 7,166, 86, 93,118,189,209,139,186, 6,179, 50, 73, 50, 21,181,136, 41,223, 69,132, 50,110, 41,243, +104,176,147, 58, 47,128, 20,133, 37,230,182,229,109, 55, 15,173,101, 5,217, 62,180, 75, 70,227,218, 54,243,131,143,183,187, 0, + 67, 74, 38,158,107,217, 59,162,118,166, 99, 54,162,162, 59,105, 74,117,161, 86, 11,193, 67, 96,242, 27, 97, 75, 91,171,109,194, +226,224, 16, 66,192,254, 87,221, 38,213,155, 77,169,157,179,121, 50,192,206,250, 24, 57,186, 77,206, 35,249,234,177,189,231,146, + 21,116,186,149, 89,213,230,217,244, 3,139,247,210,214,105, 33,245,198, 77, 7, 98,234,209, 52,144,250,193,214, 20, 68,106,195, +202, 56,196, 71,177,177, 61,146, 60, 1, 77,136, 53,219,158,247,232,212,148,241,213, 34, 75,231,201,166, 76,105, 88, 17,134, 3, + 52,152,205,171,230,108, 43,147,102, 41,116, 91, 95,241, 34, 37,213,147,241,180, 46,113,163,165, 84,166,105, 75,222,110,141, 35, +239,244,183,121,158,184,188, 60,231,226,236, 17,151,151,231,124,215,247,125, 47, 95,250,229, 95,166, 91, 13, 76,219, 13,143,238, +221,163,230, 76, 74,137,151, 62,249, 41,190,241,197, 47,129,192,234, 96,205,103,127,226, 39,249,232, 15,254, 0, 47,127,242,187, +121,250,165,151,120,240,250, 27,148, 60,115,122,251, 54, 63,241,243,255, 6,111,127,235, 91,228,113,228,163,223,255,253,188,240, +202, 39,120,245,171, 95,225,114,179, 37,163,124,236,135,127,132, 23, 62,253, 41,158,254,232, 71, 56,122,230, 25,222,126,253,117, +202, 60,241,194,167, 63,197, 83, 47,191,204,219,111,188,193,166,100,230, 24,248,238,159,253, 89,190,246,255,126,137,243,237,150, +139,105,203,229, 56, 50, 78, 19,164,200,243,159,120,133,223,250,220,111, 56,163,222,214, 16,171,195, 67,126,250,223,252,183,248, +237,223,252, 60, 90, 43,253,225, 1, 63,249,103,255, 28, 95,249,252,231,153,114,230,248,246, 45,254,224,207,254, 44, 31,248,232, + 71, 88, 31, 29,241, 67,127,244,143,242,213,207,255, 6,170,149,211, 59,119,248, 67, 63,251,175,242,145,239,249, 30, 94,248,240, + 71,185,247,198,235,104, 41,188,242,131, 63,196, 51, 31,122,153,215, 94,125,149,113, 28,137, 49,240, 39,255,237,127,135,175,125, +241,139,104,173,220,124,250,105,126,236,231,254, 20, 31,251,222,207,242,226, 71, 63,202,155,223,252, 22,121,158,249,228, 15,254, + 32, 31,250,196, 39,248,246, 55,190,137, 96,143,237, 79,254,165,127,151,223,253, 23,255,194,116, 22,123,133,123, 73, 50,117,171, + 97, 59, 21,131,236, 5,194,198,232,239,193,249, 9,202,220,110,127, 40, 18, 73,165,168,147,152, 92, 20,109,124, 2,170, 43, 87, +199,106, 2,236,169, 81, 71, 27, 67,165,205,253,147,141,156, 58,103,156, 23,129,109, 22, 11,125, 51, 70, 2, 81,149, 80,205, 76, +211,183, 20,209,176,171, 37,179,154,253,102,242,244,167,161,229,167,208, 40,116, 94,100,100,134,237, 35, 52, 29, 64,191,182, 67, + 38, 21,100,188, 50,113, 91,113, 21,213,105,178,162,255, 63,222,167,126,254, 24,249, 83, 7,200, 7,127,201, 44, 67,250,167,125, + 60,122, 31,194, 7,129,143, 64,250, 42,228, 45,228, 21, 16,145, 91, 21,254,196,128,254,157, 9,125,187, 88,142,123,220, 59,135, +219,146, 35,248,188,112, 84, 43,144,213,139,116,131,181, 68,159, 57,117, 30,229,250,218,136,190, 53,161,103, 5, 93,155, 93, 10, +164,189, 70, 46,110, 46,118, 82, 13,150, 14, 39, 93,103,227,248, 34,168, 6,228,221, 10,243, 55,160, 92,238,120,169,169, 29,220, + 46, 51,214,186, 3,221,236, 61, 86, 93, 38, 7, 62, 73, 16, 7, 7,101,191,101,121, 11, 45, 37, 44, 1, 52, 97,232,224,176,183, +203,196, 7,129, 27, 63, 6,199,255,129,165,197,169, 47,161,235, 25,108,190,136,190, 54,195,198,149,240,179,123, 56,103,143, 64, +156, 43,185,168, 79,127,246,111,181,187,118,125,129, 46,197,134,199,109,169, 74,106, 24, 98,143,153, 36, 13,176, 26,108,143, 62, + 79, 80,231, 37, 34, 87,106,240,184, 96,221,237,180, 90, 37,106,226,187,102,122, 15,126, 9,242,236,102,185, 84,116,112,159,248, + 16, 96,170,214,197,119,134,182,211,130, 93,146,250,201,112,183, 83,166, 94,100,216,206,166, 21,249, 95,123,226, 55, 11,242,211, +175, 34, 79,127, 27,214, 71,112,122, 8, 39,127, 12,248, 99,254,133,254,191,186,222, 45,214,178,235, 58,207,252,198,156,107,173, +189,247,185, 86, 21, 89,188, 20,201, 98, 21, 69, 21, 73,241, 38, 81,150,168, 72,109,155,146,124,105,201,185, 57,134,221,128,186, +129,142,131,110,244, 67, 39, 8, 16, 32, 15,121,243, 67, 16, 32, 15,121, 72,128,228, 45,221, 9,130,238,192,157,216, 29,199,136, +218,138, 36, 43,113,219, 84,100,138,142, 69,145,180, 68,177,138, 34,171,120,169,219,185,159,125, 89,107,206, 57,242, 48,198, 90, +123,159, 18, 93,130, 64,137, 85,117,206, 62,231,236, 53,231,184,252,255,247,223,107,130, 57, 61,230,164, 55, 50,248,251,209,119, +179,253,239,197,139,192, 47, 67,121,217,232,114,218,250,199, 73,182,130,105,158,128,230, 42, 92,188,140, 60, 82, 19,174,143,216, +152,103, 78,119,202, 60, 86,148, 90, 73, 26,157,144,149, 76, 35, 32,209,166,110,154,157,228,102,187,232, 92, 58,219,119,183,166, +188,214,156,145, 98,138,119,237, 61,183,254, 83,139,197, 29, 11, 30,140,210, 79, 70,250, 85, 74,244,125,126, 43, 13,109,132,226, +227,164,133, 66, 72, 86,240, 86,177, 70, 82, 59,188, 71, 75, 81, 22,142,229,108,197, 34,115, 85, 44,136, 38,123,182,118, 12, 80, + 7, 75, 54,235, 9, 90,201,149,230, 22,214,178,116, 84, 12,164,219,188,160,202,137, 80,143,232, 70,149,137,223,114,135, 30, 94, + 39, 86,145,209,250,221,196,115,151, 56, 30,111,208,221,252,177, 41,220, 43,227,142,247,121,232,161,167,140,149,132, 84,145, 56, +217, 68, 70, 19, 11, 73,233,230,180,139, 25, 93,107, 14,129, 76,241,248, 9, 25,224, 35,254, 54,243,206,214, 19,198, 98,244,130, +170,161,180,115,114,136,132,102, 50,236,190,213, 85, 37,154, 18,185, 36,114,182,137, 87, 73, 29, 85, 93, 19,234, 49, 85, 61, 54, +138, 98, 76,195, 52,128,156,137, 33, 18, 37,146,154, 17, 26, 42,142, 14,118,153,207, 14, 17,137, 44,102,199, 94,152,197,129,132, +182,125,215,221,160,176,243,193,251,140,214,198, 60,112,233,113,174,190,241, 3,162, 10,113,109,157,170,170,104,214,214,200, 41, +241,220,207,253, 34,111,189,250, 42,239,189,117,133,110, 49,227,220, 35, 31,225,153,207,127,129,151,190,250, 31, 56,220,221,225, +181, 23, 95,228,147, 95,252, 34,111,190,252, 50, 23,159,124,138,255,255,183,126,139,201,218, 58,109, 78,124,242,191,255, 18, 63, +250,147, 63,225,221,203, 87, 40,100, 30,190,244, 56,143,124,252, 89, 94,254,143,255,145, 27, 47,190,200,207,127,229, 43,236, 77, +167,212,170, 60,240,177,143,113,237, 71, 63, 98, 54,159,179, 40, 5,205,137,113, 8,104, 29, 76,136,157, 50,109,215, 90,110,188, +136, 71, 47, 20, 83,241,123, 30,124,202,133,236,202,118, 84,249,228, 23,127,142,239,191,248, 71,188,119,249, 10, 79,124,234, 83, + 54,173,136,145, 40,129,207,126,233,151,248,225, 75, 47,241,238,149, 43, 60,241,252,167,121,250,167,127,154, 23,127,239,247,120, +253,123,127,202, 23,127,245, 87,105,231, 54, 33,190,240,228, 83,188,119,249,178, 21, 72,192,103,190,244, 37, 94,121,241, 69,174, +253,232, 71, 60,243, 23, 62,199,115, 47,188,192,183,191,250, 85, 46,191,242, 10,191,244,235,191, 78,252,207,127, 64,234, 22,124, +228,233,167,249,241, 15, 94, 39,185,192,111,245,204,147,161,103,148,225,200,150,213,229, 97,127, 94,149,229, 92, 64, 48, 59,158, +196, 56,152,179, 80,165, 42,120, 44,170, 91,181, 23, 62, 46, 24,251,244, 49,123,211,146, 28, 8,145, 87, 48,230, 5, 15, 70,203, + 30,189,238, 49,153,237,114, 61, 11,197,167,208,193,238,219, 94, 76, 67, 92,222,143,149, 96,251, 58,215,160, 45,130, 75,164,150, + 12,197, 37,102, 53,117, 72,119,132, 78, 64,227, 6, 28,131,182, 53,194,194, 42, 16, 85, 24, 39,116, 18,225,158,132, 94, 62, 64, +254,143, 9,242,215,198,132,167,191, 13,117,130,252, 63, 88,144, 6,173,141, 63,117, 10,241,170,115,232, 39,208,173, 33,231, 90, +248,139,235,232,239, 30,193, 65,134,237,149, 60,244, 30,126, 82,123,149, 51, 93,185, 36,211,170,242,221,193, 36,181, 5,125,232, +213,150,114,203, 61,158,163, 62,170, 83, 76,141,153,250,200,213, 94, 44,237,179,164,144,173, 2,170,163, 93,248,183, 35,204,111, + 66,153, 25, 78, 52,142,140,128, 85,121,164,107, 81, 55,112,251, 62,165,128, 76, 2,172, 85, 54,241,136,149,245, 61,125,136, 79, +101, 88, 89, 19,154, 69,164,246,207,215, 91,215, 38, 13, 92,140,200,133, 14, 78, 61, 9,155,255, 43,212,247,184,101,203, 79,205, +124, 5,110,127, 0, 59,166,196,215,146, 41,157,243,181, 83,166, 28, 38,186, 69,166, 11, 70, 30, 43,170,119,136, 69,164, 39,188, +218, 94, 59, 47,203, 80,233, 25,239, 14,201, 65, 18,116, 5,201, 17,105, 70,230,122,104,231, 72, 59,245, 34, 83, 44,124,130,100, +223,207, 85,164,131, 56, 5,168, 91,193,133, 54,203,149,133,246, 35, 41, 17,100,156,125, 93,209, 71, 13,123, 78, 65,235,158,252, +218, 58, 36,157,250, 90,170,206,196, 80,136,127, 84,168,174, 84,196,231, 21, 57,119, 0, 15, 28,194,163,255, 10,214,254,173,147, +228,190, 4,205,151, 45, 97,143,145, 19,227,122, 94,111,190, 67, 66,147, 13,157, 28, 31,128,176, 14,229, 74, 31, 41,104, 84, 66, +198,208,156, 55, 47,252,230, 13,120,100,143,120,101, 68,115,212,113,122,127,193, 94,154,179,183,112, 44,104, 31,214,225,151,176, + 89,253,178,119,239,234, 35, 73, 89, 42,227, 83,231, 63,222,176, 92,229,244,188,217,149,104,223,210, 79, 83,252,105, 14, 82, 17, +130, 41,234, 51, 74,194,247,249,161,178,174,180,168,213,176,185, 80, 99, 35,219,156,178, 1, 19, 17,186, 12,173, 7, 97, 20, 39, +174,225, 32, 18,139,173,112,113,179,119,249,125, 8,203,188,152, 22,101,210,199,162, 6, 43, 46,178, 8,170,166,224, 46,139,169, +233, 3,154,145, 1, 86,114, 71,218,123,159,160,133, 90,206,178,121,250,126,218,166, 97,113,251,154,141,142, 83,231,171, 18, 75, + 24, 11, 36, 66, 51, 38,174,159,178,216,208,249, 33,101,118, 76,119,180,107,246,174, 30, 30, 41, 50,132,178,104,233, 69, 86, 12, + 92,115,113, 34, 98, 41, 74,110, 2,180, 11,255,250, 2,218,182,228,146,173, 95, 11, 1, 98,133,212, 99, 36, 7, 98,207,189,232, + 83,213, 98, 99, 5,151,139,205, 52, 39, 35,224, 41, 3,252,198,232,139,153, 24, 2,245,120, 98,233,217,205,200, 39,131,145,140, +249,170, 31,126,242,105,222,191,252, 38,177,110,184,126,245, 93,158,252,220,207, 48,158,172,209,205,230,158, 22,105, 69,205,104, + 50,225,236,131, 15, 50, 90, 95,227,177,231,159, 39,251, 74,161, 20, 19, 65,171, 42, 63,126,237, 53,238,186,239, 62,158,251,133, + 95,224,197,223,249,119, 38,252, 3,154,209,152,123,207, 63,196,120, 60,230,169,207,126,118, 56,163, 66, 12,204, 75,226,120,119, +151, 55, 95,123,157,241,189,247,240,246,235,175,243,204, 3,231,248,246,239,254, 46,243,163, 35, 34, 66, 21, 45,227, 92, 36, 80, +151, 66, 37,194,233,201, 4, 29,143,135,248,214,241,120,194,168,170, 89, 27,217,191, 27, 53, 35,154,170, 98, 99, 52,166, 26, 53, +156,189,251, 44,179,235, 55,217,222,216, 96,255,221,247, 24,127,234,211,108, 78,214,169, 70, 35,182,238,186,139,119,174, 92,102, +145, 18,127,246,202, 43,252,244, 95,250, 75, 28, 31, 31,161, 7, 7,236, 93,191,193, 3, 15, 95,224,189, 43,111,241,200,147, 79, +242,221,255,244, 45, 10, 74, 61,106,216, 58,125,134,171,111,252, 8,128, 31,191,241, 3, 62,255,203,191, 98,209, 23,139, 5, 87, + 47, 95,230,226,199, 30,231,205, 87, 94,225, 35, 79, 63,195, 55,255,237,191, 57, 49,154, 15, 39,158,120, 93,225,116,200, 9,171, + 90,191,110, 12, 49, 64,170,135,181, 71, 47, 30,237,105, 70, 90, 18,149,246, 0, 8,135, 66,244, 54, 52,245, 70, 47,137,178, 80, + 25,104, 95,209,127, 63, 9,236, 36,223,133, 23,243, 41,110, 87,246,185,107,241,148,163, 21, 24, 91,238,201, 93,253,125,181, 18, +104, 83,121,128, 91,167, 58,160,233,219, 98, 92,147,152, 10,212,213,202,168,201,159,148,217,145,117,100, 97,211, 14,230,131, 5, +210,167,179, 29, 36,168, 5, 61,213,152,113,241, 22,240, 59, 35,202,124,130, 60,251, 50,178,190, 3,229, 43,230, 97,103, 14,241, + 89, 59, 40,203, 21,179,139,149, 49,116,155,200, 37,129, 47,102,120, 57, 25, 61,173, 89,129,180, 52,193, 70, 10, 85,128,195,206, +170,155,232, 21, 80, 15,117,214,108,161, 30,141,123,252, 14, 91,116,209,218,186,160,117, 65, 88, 16,116,179, 70, 22,217,246,235, + 43, 63, 64, 67,109,249,188, 58,250,232,228, 38,144,102,118,184,199, 53, 11,248, 88, 27,193,150, 26,160,166,213,101, 54,119,194, + 46,159,245, 8, 19,243,152, 59,205, 99,153, 31, 95,123,124,168,152,149, 15,169, 96,228,127,118,173,134,115, 17, 30, 93,192,246, +189,176,245,235, 80,159,243,253,112,178,139, 38,239,195,236,235,232, 78, 54,175,127, 40,104,167, 30,228,167,148,189, 68,187, 40, +119, 92,232,186, 28, 50,137,220, 17, 51,200, 48, 46,151,168,195,221, 38, 39,242, 6,253, 13,218, 46,236,123, 61, 26,153,182,160, +237,236,235, 45, 62,158,119,105,118,112, 43,138,136, 85,182,182, 28,119, 87, 66, 27, 93,124,233, 69,155, 65,155,205, 96,112,106, +130,108,143, 12,243, 58,243, 50, 86, 58, 35, 48,116, 17,138, 41, 81,187,166,161, 85, 33,146,105, 54, 43,154,219,145,234,155, 45, +241, 66, 38,110,213, 48, 73,240,192, 46, 92,216,133, 7,255, 57,172,127,221,194, 98, 38,191, 8,241,140,119,223,126,185,175,202, +252,135,242,187,179,117, 81,124,108,153,184,134,216,220, 43,156, 50,209, 92,125, 31,242,208, 1,156,171,136,183, 27,214,102,137, +179,154, 57,204,234,186, 21,165, 45,203,172, 55,165,143,209,237,147, 0,123,126, 80,111,116,183, 29,156,250, 8, 79,122,142,129, + 8,145,228, 53,150,107, 75, 98, 52,176, 74,172,136,149, 80,185, 13,104,142,208,246,133,173,216,239,143, 67,178, 21, 93, 81,166, + 40,157, 6,203, 74,215, 94,226,144,201,206,239,183, 37, 69,241,145,186, 37, 83, 23, 9,182, 25,113,112, 76, 31, 2, 51, 47, 74, + 69, 96, 96,147, 21,122,124,153, 91,147,132, 76, 36,183,115,155,238, 52,107, 72, 61,182,139,245,120,215,212,247,245, 58,147, 83, +247, 19,183,238, 35, 95,253, 30,229,248,144, 48,218,160, 84, 35, 52,181,212,107, 27,200,250, 22,237,238, 7,164,131,219,196, 30, + 96, 83,213, 70,170, 83, 37,137, 89,167,162, 31,186,134,225,237, 87, 60, 38, 62, 52,149,127, 64, 99,101, 66,183, 98, 81,176,185, +100,210,124, 74,187,152, 19, 84, 9,205, 4,169, 71, 72,157, 8, 85,141,132,202,134,110, 33, 24,128,167, 20,180,180,214, 71, 56, +193, 71, 17,138,102, 82,215,145,146, 93,184,226,209,165,177,174,141,135,142,129,188,138,143,235, 65,184,255,226, 35, 20, 85, 30, +122,226, 99,131,214,225,129, 75,143,243,206,107,223, 55,226,160,170,179,228, 27, 20,248,246,239,252,123, 74, 49,149,120,215,195, +104,234,134,146, 77,176,182,121,247, 89, 22,139, 5,213,104, 68,151,179, 77, 89, 60, 13,242, 91,191,249,155, 75,209, 90, 16, 98, + 12,142,183, 21,174,188,246, 42,159,254,249, 95, 96, 49,155,114,251,198, 13, 62,120,255, 93,155,112, 12, 34, 53, 43, 46,214, 23, + 91,204,231,115,142,142,142,136, 49, 16, 99,101,221,122, 49,132,107,116,106, 98, 83, 87,182,206,173, 34, 77, 85,185,150, 68, 76, +157,159, 51,109,201, 28,204,103,144, 90,166,243, 25, 59,251,123, 20, 85, 42,135, 42,145,109,137,242,214,107,175,114,241,169,167, + 56, 62, 56,160, 30,141,184,113,237,218, 9,189,199, 29, 75,240,225, 40,251,225,127,253, 19, 62,247,229, 47, 51,155, 78, 57,216, +185,205,209,222,222,114,156, 46, 63, 25,163,170, 3,138, 97,121, 70, 14,186,160,212,111, 91, 60,191,190,116,148, 54,163,234,193, + 57,254,193,170, 62, 11,186, 56,169,169,117, 65,123,113,182,118,239,224,202,197, 8,174,136, 13, 11,167,157, 53, 53,123, 30, 98, +118,166, 86,102, 89,140,184, 26,150,152,199,192, 74,152, 91, 30, 72,163, 52, 50,232, 34,136,186,172,186, 43,143,193,107,139, 9, +166, 99, 87, 8,199,201,226, 79,163,154, 85,132, 98, 23, 56,251, 48, 81,116,109, 11,109, 54, 96,182,139,134,108,232,233,133, 34, +251, 45, 52, 53, 90,101,184, 90,224,183, 18,188,211,192,207, 92, 65,238,251,167, 16,255, 6,228,243,214, 49, 5,239, 72,202,187, +118,177,231,117,208, 45,228,217,128,238, 31, 88,234,219,186,227,100,139,239,211,215, 21,198,121, 57,114, 15, 43,182,173,122,165, + 20, 27, 11,236,122,130, 87, 40,131,175, 87,181,216, 30, 55,138,117,210, 51,247, 99,213, 50,132,158, 80, 44, 7, 90,251, 64,149, +164,118,129,233, 28,170, 51,208,156,131,230,199,134,138, 61,170, 60, 79,158, 97, 68, 34, 19, 87,222, 79,188,219,119,100, 34,125, +208, 75, 21,236,117, 39,123, 24,192,255,252,168,130,123,106,120,116,129,156,217,130,237,191, 98,232, 83, 60,148,135,177,253,239, +238, 7,112,252, 14,124, 48,182,105, 68,127, 58, 31, 36,216,107, 73,243, 76, 23,196, 56,227, 3,220, 35,252,185,236, 5,237,249, +198,125, 74,104,210, 15,205, 62, 16,108,156, 38,101,102,130,166,186, 70,218, 14,105,154, 21,213,126, 24,234, 93,211,128,217,229, + 98,223,131,176,236, 60, 75,180,247,215,154, 87,165, 71,166,166,229, 32, 89, 97,116,255, 22,108,174,193,222, 20, 22,115,116,102, +246,162, 50,222,134,109,235,116, 75, 46, 44, 82,102, 33,133, 73,187,203,104,119, 78,220, 47, 84,167,107,194,164, 65,190, 95, 17, +238,169,225,217, 57, 60,245, 6,114,246,159,192,228,119, 97,227,127,129,241,231, 44, 9,142,185,173,136,250, 75, 91,100,168,192, +151,123,156,213, 75, 93, 44,238,119,125,211,145,193,155,200,227,251,196,107, 13,213, 97,199,233, 46,115,186,134, 15,186,101,184, +224,176,233, 9, 22,211,154, 89,126, 72,193,222,123,170,142, 23, 30, 58,114, 67,103,230, 42,130,227, 64,251,102, 32, 98,234,117, +154, 53, 68, 51, 81,109,106,212,166, 68,171, 66, 23,204,122, 36, 34,228, 80, 51,207,230, 69, 87,167,196,165,178, 76,145, 54,134, +249,114, 63,172, 20, 15,141, 49,117, 62, 30, 0,212, 39, 93,149, 96,112,151, 84, 10,173, 71,196,214, 30, 36,131,132,161, 46,182, +241,189,160,177, 70,101,196,162, 93, 80,230, 51, 98, 46,196,181, 45,104, 38,174, 10,159, 18,118,174, 81,159, 57,207,246, 71,127, +150,246,120,135,249,254, 7, 38, 0, 28,109, 16,183,239,231,232,250, 27,164,131, 93,123, 7, 86,181, 77, 58,162, 19, 12,179,119, +216, 18,237,162, 18,161, 83,233, 33,234, 75, 15,134, 7,233, 80, 10,217,213,225, 82, 85,142, 91, 53,159,126,145, 72, 46,201,242, + 18, 22,115, 83, 14,171, 9, 30, 99, 48,129,220,224, 32, 50,111,128, 89,228,202,138,109,180,255, 79, 74,102,193,115,155, 86,151, + 23,230, 74,113, 30,193,125, 23, 31,225,248, 96,159,151,126,239,255,179,221,127, 46,108,157, 57,205,199, 63,255, 5,222,251,225, + 15,134, 85, 70,140,145,156, 50,183,223,123,159,139,207, 62,203,155, 47,127,151,128, 48,170, 71,172,157,218,102,239,246,109, 82, +215,241,228,103, 63,203,238,205,155, 92,254,250,215,248,220, 95,254,203,236,253,246,111, 51, 59, 62, 38, 45, 90,110,190,123,141, + 75,159,254, 52,175,127,231,191, 16,138, 82, 85, 53,219,103,239, 97,127,103, 23, 68, 56,222,223,167,109, 23,124,252,103,126,150, +151,126,255, 27, 14, 36, 98,136,101,205, 69, 41,218, 17,218, 57,139,174,101,255,248,136, 16,123, 71, 1,132,227, 35,142,231,115, +102, 34, 28,238,239,114,246,177, 75, 28,205,102,220, 58,216, 7,224,250,141, 27,212,119,159,225,250,155,151,121,252,177,143, 50, +157,207,217, 63,180, 92,249,189,155, 55,121,240,194, 69,174, 94,126,147,243,151, 30,227,198,181,171, 67,223,124,245,205, 55,120, +238, 11,159,231,241, 79,253, 20,151, 95,125,213,126,126,222,141, 31,222,222,225,193, 71, 31,229,218,229, 55, 57,127,233, 18,215, +223,189, 54,156, 83,123,183,110,179,152,205,248,169,207,127,129,151,190,249,141,159,244,158,175, 68,172,246,239,143,176, 18,132, + 51,140,233,139, 82, 74,187,100,202,101,203,101,248, 9, 85,158, 64,252,159,207,202,111,200, 0, 21,147,165,181,217, 59,234,165, + 69,192,206,187,185,159,215,187, 25,142,146,189,128,181,101,250,231,240,162,131,255,157,190, 1, 18,159, 80, 39, 12, 96, 48,142, +125, 67,234, 36,160,126,141,235,127,183,239, 40, 34,182,131,211,185, 45,248,165, 95,242, 47,178,169,161,103,157,121,113, 39,155, +254,244,154, 93, 34,140,100,136, 17, 52, 52,107, 7, 55, 90,120,179, 69,119,199,112,230, 24, 57,253, 26,132, 79,128,222,239,115, +222,202,198,157,204,236, 51,151, 13, 8, 99,228,108, 11,187,157, 47,123,197,170,155,211, 25,182, 55,145,250, 44, 92,191, 5, 31, +184,244,107,102,228, 52,233,179,211, 43, 79,174,123,171, 93,114,242,143, 12,190,208, 11,219,164, 10,198,108,239,245, 3,213,138, + 48,175,216, 44, 81, 42, 49,166,254,153,136, 60,211,192,246,207, 65,117, 47,200, 20,218,183,108,133,208, 9,210,133,229, 52,161, + 10,200,164,130,237, 10, 78, 69,168, 93,100,213,181,230, 47,156,103, 15, 35, 95,138,188,169,131,253,112,238,169,225, 98, 65,206, +173,193,246, 47,192,214,175,153,160,203,140,236,254,207, 3, 56,250,199,232,251, 87,225,213,218, 71, 50, 11,116,127, 65,185, 62, +163, 59,232,232, 68, 78, 96, 74, 7,251,211, 10,237,108, 53,254, 80,124,228, 27, 60,130,146, 85, 27,199,202,155,190, 7,213, 72, +233,119,148,193, 10,128,245, 45, 19,247,165,185,125,140,222,230, 35,158, 41, 95, 87, 78,157,115, 59, 91,175, 49,232,127, 30, 56, + 77,174, 3,102,115,216,107, 97,154,208,173,109,116,115, 11, 93, 84,104, 25,153, 96,179, 82, 56, 94, 80, 22,135,148,249, 33,233, +240,128,197,209, 49,157,118,148,144,208,160,148,131,142,178,200,232,108, 78,185,221,193, 85, 8,239,215, 48,202, 72,184, 9,229, + 15, 32,127,207, 82,254,234,251,188, 96, 10, 12, 34, 14, 89, 29,199,223,145,242, 32,209,216,230,205, 12, 38,235,176, 89,193,232, + 26,114, 53, 32,183, 11,210,218,131,191,147,127,114,176, 95, 92,145,219,111,241, 42,177, 78, 86, 9,253,118,156, 74,139, 89,161, +212, 70,232, 18, 45,105, 45,231,228,148,174, 96,197, 84, 51, 70,169,168, 52, 49,198, 20,193, 93, 81, 19,198,185,120,135,170,161, + 84,145, 46, 21,218,146,232, 52,120, 71, 30, 28, 60, 82, 67, 61, 54, 38,124, 78, 3,152, 70,135,253,162,119,235,110, 13,235, 11, +141, 24, 2, 29,193,115,208, 25, 44,115,161,106,208,102, 76,142, 21, 89, 42, 24,109, 18,214,182,144,102, 66, 71,164, 45,133,174, +109, 45,164,195, 5,115, 97,253, 52, 52, 91,166,234,143, 53,245,169,243,132,241,182,197,110,174,159, 69, 54,207,177, 56,248, 0, +157,238, 33,213,200, 44,128,174,207,208, 1, 88,184, 98, 73,213, 62,216,100,185,142,147,170, 34,122,193,145,179,137,226,200, 9, + 66, 69,219,117,180,211, 3,180,155,123, 62,183, 27, 53, 67,244,160, 20, 67,159,246, 96,151,148, 18,109,219,210, 45, 22,204,167, +199,180,243, 25, 41, 27, 4,165,148, 52,124,191, 76,156,106,122,148, 80,213, 4,137, 75,218, 90, 8, 60,254,153,207,240,254, 59, +239,176,119,253, 58, 82,148, 24, 43,186,197,130,139, 79, 61,195,225,206, 46,139,249,156,135,159,120,130, 43,223,123, 5, 68,185, +241,246, 59,156,123,228, 35,124,244,211,159,230,252, 19, 79,112,254, 99, 31,163,107, 23,236,124,240, 1,247, 94,184,200,131,143, + 61,102, 99,243,233, 49,169, 77, 60,254,252,243,188,243,250,235, 20, 85, 62,248,241, 91, 60,116,233, 18, 79,126,246,115, 92,124, +234, 41, 62,242,236,179,148,212,113,251,250,141, 33,212,165,168,114,246,193, 7,248,211,255,244,159, 17,145,161,136,233,173,106, + 34,194,104, 60,230, 99,159,126,158, 71,159,121,134, 75,159,252, 36, 31,253,196,115,220,119,225, 2,111,189,246, 26,179,227, 41, + 63,245,197, 47,242,192, 71, 30,101,127,103,135,211,247,222,203,171,223,249, 14,165, 20,110,223,184,193, 39, 95,120,129, 11, 79, + 60,206, 98, 58, 99,227,212, 54, 63,248,238,203,136, 8, 55,223,123,159,231, 94,120,129,199, 63,241, 28,163,241,152,151,190,241, +117,243,236,139, 33,114, 55, 79,159,225,226, 19, 79,242,226,215,126,143,206, 21,247, 0, 55,223,123,143,231,126,246, 5, 30,123, +238, 19, 52,163, 9,127,252,245,111,144,187,165, 80,170,148,196,125,231, 31,246, 75,125,229, 90,239,247,230,186, 44,212,205, 94, + 43, 67,218, 27, 20,180, 24,208, 71,115, 70,115,177,233, 65, 89, 30,139,119,198,178,202,215,158, 8,238,100, 19, 55, 2,217, 27, +114,236,211,229, 24,237,110, 42, 42, 28,103, 99,167,180,142, 54, 79,197,124,166,107, 22, 0, 70, 19, 44,152,160,241,255, 95, 71, +131, 80,244,217, 40,243, 2, 71,157,208,212, 54,205,150,225, 11,179, 14, 95,188,147, 16,167,119, 54,149,176, 30,237,227,244, 71, +122, 40, 86, 93, 88,225, 30, 28, 12, 48, 34,159, 61, 11,227, 13,194,205,219,132, 60,181,139,169, 75, 54,199,111, 92, 25, 62,183, +110, 84,198, 53,124,124, 11,249, 53, 37, 92,216,130,240,119,161,108, 3, 87, 65,255, 12,202,159, 65,158,131,158,178,220,248, 42, +163, 7,111,195, 27, 83,219,185,111, 70,184,119,134,172, 63, 15,213, 58,250,221,175,193, 15,124,113,121,208,162, 11, 65,198,254, + 77,220,176,177,189,190, 62,183,113,205, 88, 41,215, 22,232, 97,235,223, 36,183, 78,172,185,229,236,184,179,241,117,113,108,172, + 11,107, 66,172,137, 90, 33,207, 52,200,175,222, 5,231,254,161,121,162,211,251,176,247,127,195,193,107,176,187, 7, 55, 28,112, +211, 57, 68,103,171,130,123, 35,108,175, 25, 11,159, 29,216,219, 71, 63, 72,182, 63,233,220,166,208, 22,175,101,196,138,128,243, + 1,185,168,112,230, 83,112,234,111, 65,125,214, 5, 93, 35,255,175, 64,247, 13,184,254, 15,208,239,204,224,135, 53, 58,202,148, +119, 15, 41,239, 77, 73,211,100, 30,227,158, 10,118, 7,140,161, 47, 78,195,157,118,110,207, 62, 14,189, 7, 90,203,137,183,108, + 16,245,221,187,215, 96, 26,236,144, 10, 35, 27,185,111,157,182,143, 49, 59,132,118,134, 52,209,240,251,157,207,174,106, 43,242, + 36,228, 37, 19,134, 98,107, 11, 95,230,155, 11, 67,209,206,225, 45, 97, 12,219,247, 16,238,218, 68, 70, 29,204, 14,225,248, 24, +142,230,232,180,163,107, 23,204,115,199,188,133,105,142,164, 16,105,164, 48, 10,197, 38, 82,165, 16,179, 18, 90,165,150, 64,179, +209, 80, 93, 92, 71, 46,141,224,241,130,220,159, 77, 80,119,215, 23, 97,243,239, 0,231,253,133,237,184,118,161,156, 4,224,175, + 94,234, 18,252,207,101,224,107,176,243,127,193, 31, 28,192,127,152,211,190,115,204,124,119,198,149,185,114,173, 27,190, 84, 27, +115,159, 48,215,136,193, 8,253,132, 80, 15, 85, 9,170,212,177, 2,137,116, 85, 67,201,234, 74,248, 68,168, 27, 15, 3, 9,238, +193,174,153,148,150,237,104,153, 81,139, 46, 81,122, 68,103,168, 13,246, 34,193, 97, 29, 11,180, 88, 7, 79,221,216, 69, 93,212, + 88,240, 69, 93,188, 85, 6,104,136, 12, 19, 28, 83,145, 23,191, 32,131,152,194, 62, 75,164,195, 70,196, 81, 19, 35,148,170, 54, + 94,189, 18, 40,213,136,220, 76,204,187,156,230, 44,102,199,204,230, 51,139, 12,117, 1, 92, 61, 89,103,114,247, 67,212,247, 92, +178, 61,243,108,207,244, 1,107,103,144,102, 29,169,215, 8,163, 45, 22,121,202,222,229, 63, 98,250,254, 27,148,174, 51, 17,112, + 20, 82,202, 44,146,141,188,163,168,193, 85,130,251,178,251,176, 71,223,167, 7,255, 58, 59,195,167, 81,215, 13, 97,125,155,174, +107,209,197,220, 79,105,219,165,211,140,237,176, 31, 82,238,252,231,158, 90, 52,183,110,227, 54, 73, 0, 0, 20,143, 73, 68, 65, + 84,148, 34, 36, 45,228,118, 97, 3,168, 88,217, 88, 62,119,182,202,236, 35, 68, 9, 38,104,172,226,114, 18, 83, 12, 27,155,181, + 80,138, 18, 84,137, 85, 53,248,157, 87, 5,172,154,242, 96, 9, 43,217,241,172, 49,184,118, 74, 45, 72,166,109, 17,132,132,105, +105,144, 37,185,173,248,170,199, 92,192,209, 95, 87, 15,128,137,131, 13, 13,129,103, 95,248, 89, 14,119,118,121,227,229,151, 93, +223,106,187,250,226, 83, 92, 99, 93,232,128, 1,238, 33, 49, 61, 96, 94, 7,130, 91, 30,158,152, 8,182,134,168, 27, 23,184, 41, +143,125,226, 57,238, 58,247, 0,223,250,119,191,181,130, 34, 81,183,101,174,184,114,188,161, 69,101,128, 7,157,200,164, 24, 2, +167,194, 74, 28,234,242,215,243, 63,255,115, 28,237,239,241,250, 75,127,220,211, 50, 78, 92,234, 22,152, 85, 78,116,229,246,204, +151,165,239,183,156, 28,213, 7,249,240, 0, 87, 1,226,255,116,143,252, 70, 41, 75, 55, 84,235, 65,247,189,158,181,232, 50, 64, +126, 0,130,233, 82, 5,223,219,207,154, 21, 1, 93, 29,100,240,165, 87, 97,136,170, 53,155,138,255,249, 53, 15,109,235, 59,243, +232,175,200, 39,103, 78,181,147, 97,132,100,144, 26, 75,115,106,135, 41,183, 29,186,228, 14,230, 29, 58, 30, 19, 70, 19,100, 92, +112,181,136,141, 27,212, 42,104,197,225, 34,109, 66,110, 39,104,182,144,251, 91,100,242, 18,196,159, 54, 92,167,140,150, 57,214, +154, 65,215,160, 84,200,218,189, 80,239,218,152, 98, 35,192,166, 32,213, 11,168, 28,192,229, 55,224,182,197,107,234, 84,151,190, +243, 70,150,222,240,219,254,141, 27,121,103, 56,205,195,190,161,135, 72, 12,251,136,185, 99, 59,251,216,214,108, 15, 68, 40, 53, +242,164, 32, 79,220, 11,155,127,213, 45, 78,107, 14, 33,123, 7, 56,178,203, 57,123,183, 62, 10, 86,128,108, 41, 52,150,195, 13, +115, 11,148, 57,102,176,109,245,168,114, 68, 60,121, 45,194,195, 9, 57,117, 31,156,250,235,208, 92,242, 11,221,125,214, 52,144, +175,194,254, 63, 66,175,222,130, 63,173,161, 18,244,120,134, 94, 61, 38, 29,182, 6, 29,186,227, 66,239, 15,136, 62,136,236,206, + 11, 29,196,196,111,245,200,197,129, 50,168,224,135,200,227,254,177,232,167, 73, 18, 9, 82, 76, 52, 50,217,128,122,205,108, 61, + 17, 83,204, 7,223, 53,245,203, 42, 7,114,144,210, 82,124, 71,131, 6,235, 36,181, 4,114, 87, 76,103, 18, 27,186,102, 68, 75, + 36, 29, 29, 34,239,189, 79,220,187,137,132, 57, 18, 19,228,130,116, 9,237, 90, 27,129, 22,161, 43,202,162,179,177,170,132,138, + 80,217,116, 39, 99,153, 10, 11, 32, 31,117,132,253, 22,217, 83,228, 70, 5,135,149, 9, 61,229,135,150, 2, 23,239, 7, 57,229, + 93,123,239, 67,253,144, 8, 8,193, 83,104, 4,248, 17,116, 95, 51,102, 68,125, 8, 83,129, 27, 25, 89,100,154, 82, 56, 54,150, +211, 16, 71,176, 90, 35,244, 65, 38, 1, 37,107,191,223, 86,167,136,171,139,178,106,138, 56,227, 59, 54, 84,163, 53, 74,172,124, +215, 25,168, 66, 69, 29, 3,212, 53,139,148,200,169, 91, 78, 6,197, 72,101, 37, 4,114,168, 76, 65,174,106, 35,228, 80, 65, 51, +182, 11,189, 51, 31,190,198,106, 96,193,179,146,117,173, 3,188, 37,250, 22, 44, 24, 18,194,187, 89,234, 6,173,199,150, 92,216, +152, 29, 45, 52, 35,114,181, 70,231, 72, 92, 45,230,175, 78, 57, 15,212,182, 28, 43, 82,206, 44,142,118, 72,135, 55,200,221,212, +215, 1,141,189,230,233, 1, 90, 18,117, 51,102,114,234, 33,214,238,255, 24,163,237,123,104,182,238,162,222, 58, 99,144,152, 24, + 73, 18,141,111,158, 18,161,182,253, 81,155, 50,201, 67, 84,204,198,102, 93, 95,246,139,169,138,129, 48, 94, 3,177,215, 64,207, + 50,175, 71, 84,155,167,237,235, 8,113, 24,207,171, 90,166,121,106,103,134,110,142, 21,197, 45,108, 18, 42, 19, 36, 74, 48,255, +122, 8, 67, 76,170, 41,194, 77, 13,158, 82,103,162,186,254, 76,207,217,190,197,209,177,182,170, 43,113,200,206,114, 24,152, 1, +118,134,246,187,237, 97,134, 52, 68, 40,171,107,133, 60,226,214, 71, 45, 85, 8,196, 24,169,171,134,170,170,137, 49,154,234, 60, + 70,215,189, 8,147,141,117,126,230, 87,126,133,170,174,120,229, 15,255, 16, 41,101,136, 96,101, 69, 21,190,234, 55, 31, 94,171, + 95, 76, 58, 92,236,197,255,185, 12, 61,137, 34,220,251,240, 69, 62,251,229, 95,226,177, 79,124,130,245,237,109,190,243,251, 95, +167,157,205,221,147,174, 39,102, 98,220, 65, 6, 63,113,125,202, 79, 70,172,157, 80,171, 3,147,245, 9,191,248,149,175, 80,215, + 53,223,253,214, 55, 61,120,102,229,163, 13,225, 50, 38, 90, 45,165,184, 93, 49, 19,244, 36,251, 93,244,142,215, 35, 39,197,118, + 43, 71, 41, 85,151, 78, 98,236,122,126,118,111,182, 81,215,120,173, 69,165, 66,152, 88, 68, 55,173, 66, 85,150,152,240,232,123, +244,210, 87, 26,209, 84,183,197, 73,155, 82,150,128,179,222,127, 87,245,182,181,232,184,144,180, 92, 37,247,138,191,164, 98, 66, + 9, 79,240,201, 78,154, 66,133, 88,148,177,100,154, 32,196,197, 20,185,117, 11,125,244, 33,202,214, 25,194,219, 59, 80,101,251, + 36,211, 76, 41, 9,245,240,134,144,149, 48, 93, 32, 95,223, 65, 55,238,129, 47, 28, 32,155,127, 31,194, 63,128,112,193, 20, 9, +113,102,177,151,150,254, 97,130,183,187,158,131,197, 31,155, 80, 45,110,219,158, 91,111,218, 40, 27, 93,222, 96,125, 85,149, 87, +102,157, 99, 96, 38,118,153,175, 87, 70,201,155, 39, 47,187, 92, 4,167, 5,105, 34, 26,141, 90,102,251,119, 29, 86, 20,140, 3, +220, 93, 96,116,214,132, 83,106,144, 12,234,103, 97,237, 53, 88,236,193,214, 14,180,161,143, 32, 50,210, 79,179,102, 59,240,176, + 6,229, 86,239, 59, 90,122, 7,219,108, 55,236, 72, 96, 43,194,217,130,108, 52,176,246,180,167,144,173, 42,179, 71,198,206,223, +255,167,176,243, 22,252,176,178,172,251, 73, 66,119, 22,164,221,150, 69, 22, 22,142, 37, 45,189,170, 61, 47, 7, 79,154, 79, 18, +147,134,177,124, 83, 27,212, 35,119, 4, 77, 72,231,127, 34,248, 28, 73,117,233, 53, 95,189,226,138, 26,132, 40,156,177, 13, 73, +231, 3,255, 92,160, 88,199,130, 84,198,131,239,171, 10, 26, 84, 91, 83,205,106,182,148,173,106,141, 44, 53,121,148, 41,243, 57, +105, 49,165,235, 22,104,155, 16, 45, 36, 85,210,190, 50,234, 10,213,182,225,114,117,180, 70,216, 89,163,242, 31,255,184, 4,242, +162,208,118,137, 46, 4, 66,105,169, 82,242,247,117,160, 4,165, 27, 5,186, 89,102,237,234, 1,163,157, 57,213,187, 19,226,187, + 99,228, 17,129, 91,151,225,252,255, 6, 27, 79,195,250,223,134,209,199, 65, 55,176, 42,236, 14, 58,133,170, 23, 89, 11, 96, 27, +218, 11, 48, 63,182, 81,252,227,251,200, 59, 19,226,113,102,179, 43, 60,144, 50,135,153,161, 32, 22,129,174,232, 18,144, 24, 92, +197,175,106, 26,115, 9, 67,170,116, 6,130, 11, 85,173,129,243, 4,171,156, 76,208, 85, 27,149, 44,136,146,170,134,188,104, 79, +226, 56, 52,147,169, 40,120,184, 8,110,195,241,189,179, 21,183, 35, 7,195,231, 19,159,183,191,228, 76,104,214,239,163,173, 96, + 42,106,130,188, 92,212,108,141,201, 68, 97,165,170, 81, 34, 85,176,174, 56,229,153, 51,231, 11,162,201,212,229, 65,236,245,100, +179,183, 81,236,235, 91,236,188,143,222,122,151,166, 25, 51,185,231, 97,226,221, 23,236,210,235,166,148,116, 68, 61, 63, 96,180, +253, 0,167, 31,120, 10, 46,126,202, 72,155,199, 59,164,233,174,101,122, 75,225,224,237,239,113,240,250, 31, 80,186,185,125,189, +214,222,158, 8, 60,200, 67, 46,196,200, 58,249, 60,243,247,113, 70,170, 17,113,188, 14, 33, 14, 9,134,169,107,237,185,241,221, +106, 46,197,207,201,228,243, 85,179,253,169,154, 69,173,228,100, 53,184, 66, 8, 53, 69,194,176,186,210, 82,252,251, 40,148,148, + 41, 41, 13, 16,155,226, 9,112, 20, 87,218, 59, 6, 68, 42,139,173, 84,205,195,179, 91, 74,182,199,169, 40, 33, 88,170, 27,197, + 86, 12,217, 9,108,125, 7, 29,253,243, 13,187,254, 21,112,145, 96, 78,128,249,241, 49,223,252,215,255,122, 73, 41,140,113,165, +192,232, 19,253,138, 39,179,249,191,115,244,107, 63, 9, 24,136,113,220,193, 96,247, 49,224, 7,239,188,205,187, 63,126,203,240, +180,168,137,225, 60,183,160,172, 38,175,200,114, 3,234, 42,174,225,212, 9,238,250,232,215, 46,114,167,151, 71,140,123, 49, 63, + 62,230,171,255,242, 95,220,153, 67,228,103,142, 39, 82,149,178,178, 79,255,201,174, 91, 62, 36,141, 90, 62,164,182, 88,157, 26, +196, 95, 59, 35,191,177,114, 23, 81, 84, 92, 76,179,252, 48, 69,122,138,233, 82,189, 46,158, 83, 82,123,167, 93,133, 59,232,164, + 14,248, 80, 21,162, 95,222,115,160, 51,232,243, 32, 28, 23, 31,129,170,202,224, 93,199,181, 91, 61,220,102,136,253,246,138, 80, + 4,114, 49,241, 85,231,189, 91, 29,148,208, 38,100,123,140,158,218,132,133, 32, 83, 27, 47,167, 89,161, 45, 74, 30, 2,125,149, +208, 58, 77,231,106, 7,247,157, 70,206,237, 64,248,190, 7,193,172,219, 65, 41,135,160, 9,180,241,113,224, 3, 48,234,160,188, + 13,163,187, 44, 18,179,251, 51,248,254, 45,243,156, 39,139, 79,181,149,168,152, 0,174, 14, 48, 9, 72,171,182,107,207,138,172, +245,249,237,101,105,143, 11,190,243,141, 1, 90, 69, 23,101,217, 70,169, 18,186, 72,220, 30,193,103, 4,121,240,203,208,124,198, + 15,243,108, 1, 31, 36,104,223, 48,171, 83,206,144, 42,216,176,179,158,234,148,239,211, 11,148, 35, 88,204,236,116,239, 60,118, +117,225, 42,248,141, 10, 78, 87,112,182, 67, 54,239,134,237, 95,134,230,209, 21,239,180,235, 14,142,254, 61,236,255, 14,122, 5, +248, 81,132, 81, 70,119,231,148,183,166,204,167,137,105, 37,203,159,151,172, 20,140, 75,178,204,201,203, 92, 34, 52,181,189, 23, +218,185,141,199, 87, 43, 96, 31,201, 15,221,252, 48,167,247,199, 45, 23, 83,186,111,157,177,215,167, 45, 34,174,202, 76,221,160, +150,215,226, 57,226,145, 65, 16,148, 67, 69, 38,208,117,129,182, 8,139, 54,209,150,138, 69, 28,145,230, 29,186,232,108,215, 92, +143,161, 94, 35,175,175, 3, 19, 36,172,193,230,105,244,244, 22,170,181, 69,238,142, 54,208,209,216,136, 97,237,140, 46,181, 14, + 45,233,195, 78,150, 99,188,206, 81, 10,165,205,232,222, 2,217,203,200, 13, 8,183, 26, 91,135,196,235,208,125,219,116, 11,245, + 37,115, 57, 12,155, 91, 61, 57,250, 80, 32, 31,128,174,195,252, 6,164, 41, 84,135,246,189,154, 67, 56, 86, 38,179, 66, 46,194, +129,211,177,196,159,231,158,221,222, 63,119,253, 92, 81,252,251,171, 30, 4,161, 37, 19, 37,208,169, 69,157,230,212,145,125,132, +155, 85, 77, 36, 86, 50,165, 30, 89, 49, 95,140,245, 93,213, 13,161, 30, 91, 65,147,179, 75, 68, 26, 67,120,106,191, 47, 78,246, +214, 12,209,108,112,197,188,216,214,228,219,251, 67, 98,133,198, 6,141, 53, 37, 68, 47, 24,151,196,107, 27,231, 6,183,197, 25, +115, 92,157,168, 86,210,130,182, 93,176,104, 59, 82,215, 13,103, 93,231, 84,180, 92,242,137,227,209,104,190,166,234,158, 30,239, +113,188,251, 62,237,241, 46,121, 49, 37,205, 15,232, 22, 7,148,197, 1,165, 77, 4, 10,213,218, 54,213,218, 22,218, 76, 88,164, +150,195,119, 94,165,189,125,205, 18,189,220,150,167, 43,151,141,122,152,141,132,218, 46,170,236,225, 38, 10, 18, 26,194,100,157, +148,149,118,122, 76,110, 91,114,106,173,160,141,145,210, 45,204, 99,175,253,152,214,169,127, 69, 45,246,115,177, 48, 22,121,234, +134,175, 45, 97,244,190, 16,140,113, 79, 63,133,237, 89,232,197,155, 42,199,169, 90,181, 96,111,138, 80,138, 9, 81, 67, 88, 42, + 58,180, 12,123, 95,213,158, 15,178, 18, 19, 26,130,107, 54,204, 47, 31,162, 79, 86, 92, 32,105, 95,235,146, 22,104,218,190, 66, + 46,217, 63,127, 89, 82,215,202,178,251, 46, 62,234, 79, 57,155, 13,210, 39, 16, 69,203,201,203,109, 40,254,151,180,194, 62,210, +117, 16, 80, 34, 38,200,212, 37,222, 82, 87,135, 96,194,159,219, 26,175,102, 22,220,121,177,202, 48, 75, 60,121, 9,171, 23, 57, + 57,123,131,233,209,181,171,221,182,252, 57, 23,251,234, 72, 63,172, 20, 8,114, 39,184,171,183,136, 39,189, 67,127,227,173,114, +118,133,169,122,188,118, 39, 66, 22,165,113,147, 63,197, 47,247,136, 43, 84,197, 85,155, 12,123, 16, 16,114,112,223,186,199,109, + 15,239, 23,150,222, 89,252,135, 85,178,244,233,167,148, 96,132,179, 94,204, 45, 62,205, 54,152,196, 73, 42, 89, 31,215,185, 22, + 10,241,189, 91,150,115, 50,222, 64,171, 9,180,153, 84, 23,102,179, 98,163,216, 74,204,150, 92, 67,140, 5, 61, 90,192,191,217, + 71, 31,186, 11,121,248, 77,232,254, 25,212,127,199,160, 52,122, 8,114, 21,149,100,157,110,190, 5,213, 83,176,113,205, 58, 3, +237,108,244, 63,235,145,163, 50, 92,194,140,117,169, 54, 92,175,160, 46, 72, 93,108, 93, 48, 23,194,134, 80,180, 50,178, 92,244, + 93,166, 4,100,108,195, 1, 57, 84, 74,107, 99,248, 16, 60, 93,109, 29,228,116,128,250,169, 21, 31,179,223,152,245, 5, 27,177, + 87,199, 48,105,173,192, 88,199,242,214,171, 45, 8, 99,175,158,202,242, 93, 91, 28,124,211, 99,185, 54, 35,156, 74,200,198, 24, + 38, 15, 65,243,209,147,254,233, 48,134,242, 30,204,127, 27, 14, 18,114,121,100,157, 65,238, 40,239,206,232, 14, 59,142,235, 48, +144, 7,195,138,223,242,206,234,178, 63, 0, 52,212, 48, 89, 71, 84, 41,243,163,161,122, 47, 62,153, 17,239,110,150,251,196, 21, +193,167,167,179,105, 12,150,161, 45,238,251, 72,153,178,232, 92,116, 98,193, 27, 84,160,173, 65, 98,148,198,212,192, 57,163, 33, +144, 52,210,230,204, 98,158,205,227,158,167,134, 35,158,108,194,246, 61,200,120,203,246, 94, 85,160,180, 29,139,212, 82, 4,154, +157, 41,213,193, 28, 25, 67,104, 2, 85,183, 32, 79,143,168,167,199,196,156,233,146, 37, 27,106, 48, 28,107,232,148,170, 95, 51, + 33,148, 90, 56,208,194, 34, 41,107,187, 83,198,199, 45,205,126,162, 62, 90,135,182,130, 75,183,161,252, 38,164,107,112,234,127, +135,234, 60,203,242,120,101, 80,216, 43,172,217,132,250, 60, 76,119,160,190, 9,247, 76, 9, 15,140, 8,199, 74,245, 72,228,163, + 63,110, 57,124,187,227,182, 31, 74,181,152, 54,134, 30,215,186, 18, 23, 53,236,238,176,233,152,148, 66,206, 45,226,113,162,214, +176, 25, 87,190,170,215, 41,117, 77, 14,134, 72,149,201, 6, 50, 50,123, 83,234,195, 90,202, 2, 41, 74, 53, 26, 51,143, 21,121, +145,125,100,107, 84,181, 72,182, 68, 50, 44,228,163,223,153,139, 11,134, 76,197, 30,220,239,157, 78,112,244,251,189,238,208,145, +133,202,172,110,209,146,219, 52,103, 83,224,135, 72,215,119,177, 57,123, 66,157, 34, 33,218, 26,167,105, 28,153, 57, 67, 36, 82, + 98,197,124,122, 64, 59, 63,182, 67,245,246,117,234,102,196,120,227, 20,245,218,186, 89,204, 98,133,134,138,249,236,136,195,253, + 29,186,195,219, 72,106,105,234,106, 56,248,251, 17,116, 63,186, 78, 30, 16,130,191,182,130, 9,224, 66,109, 43,141,110, 62,179, +167, 46,171,165,186, 53, 35,194,168, 38, 39, 79, 15, 43,198, 43, 86, 31,177, 11,129,210, 45, 12, 22, 20, 2,129, 72, 81,191,240, +130,217, 72, 11,153,180, 48, 80, 72,239,147,215, 21,252,168, 1,136, 12, 31, 44,190, 50, 34,103,219,209,135,224,151,231, 10, 26, +216,135, 94, 41,217,247, 56,136, 5, 1,101,177, 68,189, 12, 6,202, 81, 23, 73,245,190,121,197,109,103, 1, 41, 66,161,144,197, +236,124, 37, 89, 78, 64, 22, 49, 12,110, 63,154,246, 19,163,167, 71, 87,206,224,207,217, 47, 21,231,172,232,202, 9, 51,116,251, +125, 80,140,120,234,166,163,145,139, 90,250, 30,197, 3,118,134,221, 32, 39, 46,119, 86, 39,199,171,207,133,234, 9,152,187,172, +172, 3,150,151,188, 23, 28, 89, 7,209,164, 14,207,127,127,225,203,106,146,203,135, 95,232, 39, 38,154, 39,163, 86,249,144,110, +190, 18,150, 88,115, 5,162,119,180,125,135,149,220,157, 85, 84,153,187, 21, 35,246, 49,156, 43, 1,102,161,156,172, 88, 50, 56, +245,201, 35,234,130, 12, 49,135,165, 8,217, 65,104, 41,247, 1, 50, 66,206,253,110,207, 71, 30,193, 35,191,157,203,210,174,252, + 94,171, 38,130,239,173,112,227,190, 16,208, 5,178,183, 71,184, 59,192,233,177,229, 49,239,103, 22, 36, 42, 85,195, 91, 74, 48, +241,155, 22,164, 42,112,245,136,242,255,212,196,191,117, 14,214,126, 31,218, 39,160,254,239,128,123,209,176,239,249,215, 78,133, +209, 5,132,207, 66,249, 19, 68, 94, 71,231, 71, 62,238, 54,117,106,207,106,151,226, 34,133,224,227, 12,140,246, 38,168,143,209, + 2,225,116,176,177,111,242, 78, 7,207,173,245,232,178, 92,220,209,157, 10,210, 4, 56, 19, 96,173,177,137,193,157,144,146,224, +246,182,120, 3, 70,199,214,161, 78,214, 32,222,109, 40, 87,169,122,138,143, 67,110, 86, 60,132,184,200, 97, 91,145, 83, 1,154, +187, 96,252,156, 5,136,244, 69,128, 7,171, 16, 94,130,173, 15,224,242,196, 26,248,168,148,119,231,228,155, 51,142,138, 50,147, + 64,209, 64, 20, 99, 83, 87,206, 30, 64, 7,186,171, 63,128,246,160,105,255,186,114,242, 17,154, 12, 35,225,101, 66,156,117,168, + 69,252,101,228, 21,255,122,191,112,106,156,128,150, 11, 26, 4, 73, 29, 37,116,214, 97,228, 76,153,183,100, 21, 91,231,164,150, + 92, 53, 38,200, 91, 36,148,108,151, 69,168,208, 18,173, 88,235, 90, 27, 76,164,117,239,246, 35,154, 10,218,182, 16,133,197,236, +136,210,205,105,214, 55,168, 51, 4,233,136, 58,165, 74, 51, 66, 84,234, 98, 19,166,226,180, 68, 77,182,159, 46, 98,212, 51,196, + 38, 83, 37, 11,243,168,116, 33,144,187, 12,183,142, 8,149, 18,159, 62, 5,111,143, 96,122, 12,247,253, 33,164, 93, 56,243, 55, +161,126,220,160, 67,204, 86,142, 28,119, 36,200, 1, 52,103, 96,116, 14,202,109,228,204, 85, 19, 73, 86, 35,184, 84, 51,254,127, + 11,231,175,117, 28,182,194,169,173,200,250,134,240,246,245,196,113, 42,196,149, 89, 99,208,129, 91, 73,150,229,161, 26, 17, 74, +172,109, 50, 82, 7,170, 56, 34,132, 10, 25, 79,172, 72, 41,153, 60,157, 65,233,108,215, 94, 58,178, 66, 83, 69, 66, 53, 34,212, + 35,114,206, 70, 6,172, 70,230, 17, 87, 99,251, 84,165,163, 42, 86, 52, 8,193,133,117, 14,157, 9, 66,171, 22,127, 73,172, 16, +137, 68,205,132, 98,151, 70, 17,177,132, 53,239, 38,135,208,152, 24, 40,146,172, 83, 11,193, 20,254,173,141,223,251,130, 79,170, + 96,187,249, 30,255,170, 74,116,140,107, 81, 69,114,231,163, 99,243,130, 47,186, 57,233,224, 22,245,254,117, 82,234, 92,100, 86, + 28,184,229, 86,186,186,182, 66, 72,151,125,146,138, 69, 2, 19,107, 75, 99, 19,147, 39, 22,130,249,218, 39, 19,138, 6,186,249, + 20, 41, 9,234,145, 63,162, 54, 34,238,186,133,235,153,116,105, 79,114,190,123, 94, 76, 13,149,234,168,227, 32,134, 7,206, 33, + 90,177,163,105,165,243,237, 63, 70, 25, 86, 44, 5, 99,185, 15,200, 81, 53, 49, 27, 85, 88, 78, 24, 68,150,184,229, 40, 22,203, + 91,242,112,111,100, 31,147,103,247,164,211, 39, 46, 14, 86,186, 94, 72,230, 22, 69,207, 15, 89,105,148, 79, 76,135,251,177,123, +242, 98,163,191, 44, 69,130,133,249,212,129, 42, 42,165, 24,195, 68,125,242, 80,252,230,151, 21,229,109, 20, 59,107, 66, 8, 30, + 52,150,141,139,191,210, 41,235,170, 79,124,229,198,236,179,173,202,170, 13, 93,197,166, 84,114,114, 19,102, 76, 4, 91,211, 81, +124, 93,184,114,201,243, 19,161, 46, 44,167,120,119, 52, 60,171,191,130,124,152,165,247, 67,215,250,214,169, 31, 55, 99,143,171, +243, 75,156,147, 6,122, 17, 12,168,224,202,211, 62, 15, 35, 4, 60,159,246,164,149,173, 31, 17,228,202, 15,135, 21, 1,156, 6, +232,212,254,206, 34,152, 15,126, 53,124,171, 13,134,151,173,221, 13, 86,130,208, 58,192,170, 79, 21, 13, 46, 69, 76, 89,152,149, + 62,213, 73,152, 71, 24,141,204,110, 86,102, 25,142,167,118,209, 54, 99,142, 42, 56,168,231,108,199, 68,138,197,194, 43,114,182, + 73, 67, 21,140,137,254,189, 5,242, 85, 8, 63,127, 6,194,255, 9,245, 8,229,148,197,110,102, 44,166, 85, 1,221, 1, 61,131, +148,123,160, 92, 69,247, 61, 18,117,226,106,233, 54,192,196, 30, 88,201, 1, 98, 99, 29,124, 29, 96, 35,217,174,156,226,104, 62, + 65,199, 54, 62,211,206, 61,127,199, 70,246, 73, 90,152, 42,132,160,140,163, 81,160,170, 51, 35,132, 13,131,161,228,206,161, 37, + 44,243,174,203, 5,208,183,109,252, 94, 31,129,222, 13,229, 44,228, 26,178,115,192, 91,160,173, 44, 43, 92,176,203,188, 17, 24, +215,176, 85,144,250, 12,132, 75, 32, 79, 56,236,127,230,212,131, 9,112, 13,184, 2,225, 65,152, 30,193,180, 51,108,254,187,133, + 89, 27,217, 13, 21,173,135, 6, 84, 10, 18, 77,225, 91,245,218, 12, 89, 42, 55, 75,191, 43, 15,181, 29,242,173,239,240,134, 14, +205,246,116, 34, 86, 56,200,170, 58,190,146,165, 13, 78, 21, 73, 9,105, 54,109,140, 15, 38, 8, 28,103, 72,115,138, 38, 83, 51, +231,134, 86,160, 75,138,230,128, 38, 19,205, 5, 41, 86, 68, 4,123, 42, 83,172,209, 81,131,106, 68,170, 9, 18,199, 72,137,132, +186,166,228, 22,169,106, 66,108, 16,153,210,141, 55, 56,102,196,248,104,202, 72, 23,132, 74, 41,163, 26,109, 43, 19,126, 5, 60, +198,177,191,122,237, 98,143, 81,135, 17, 83, 9,234,227,111, 37, 53,208,102,101,235,160,208,124,107, 1,177,134,251, 38,240,241, + 22, 46,188, 2, 71,127, 15,238,254, 31, 97,244, 5, 23,200,245,130,152, 9,148,202,222, 19,237, 28,242, 6,232, 57,136,187,112, +166,131,131, 0,223, 92,160,135, 35, 54,239, 19,206,239, 22,170,179, 53,177,142,108,205, 91,230,199, 38, 26, 12, 94,108,228,232, +157,156,101,225, 26,180,135,128,214, 53, 42, 53, 49,103,234,209, 58, 57, 86, 6,173,242,100, 52, 45,157,129,167, 42,161,202, 32, +213,136,166, 25, 33,227, 53, 74,168, 77,156,149,210, 32,172, 11,193,170,246,162, 62,146,212, 66, 83, 5,106,137,110,135, 19,239, + 2,173,174, 75, 89,145,186, 49, 21,179, 91,238,106,181,168,214,164, 86,241,169, 55, 36,189,163,102, 92, 85,148, 24, 72,177,177, +140,237,197,145,169,235,251, 17,188, 8, 41,249,197,225,107, 6, 81,235, 80, 67, 85, 67, 12, 84,185, 16,163,216,123, 32, 84, 20, + 45,132,212, 50, 86,163,227,117, 41, 83,123,176,199,137, 5,170, 10,181, 79, 60,113,156, 39,161, 50, 77, 64,172,236,140, 81,140, + 24, 87,215,104,206,228,182,163,116,115,155, 86,169, 35,124, 83, 50, 59, 90, 93, 13,153, 8, 37, 23,218,156,144,197,140, 74,198, + 52,205,216,214, 17,210, 43,215,109,141, 58, 68,145,170, 12, 98,189,129,209,224, 19, 48, 45,106,130,212,176,220, 17, 7, 49, 55, + 78,201,166,235,137,209,255,174,150,225,239, 20, 45, 52,120,170,157,247,187, 37, 91,145, 19,156,126, 22,252,153,214,254,107,241, + 75,183,191, 4,203, 80,248, 26, 2,119,200, 84, 17,251, 59,157, 22, 74,178,113,181,222, 57, 98,247, 88,212, 97, 53,224,171, 89, +237, 87, 40,234,119,146,219,225,138, 64,151, 11, 33,117, 52,121,252,231,129, 50,126,162, 61,150, 21,206, 91, 24,174,127, 25, 46, +255,129,232,231,106,117,209, 1,200,177,154,139, 53, 12,213,238,188,140,131, 79, 10,250,187, 83, 79,216,207,181,223, 24, 15,161, +113,194, 10, 6, 91, 87, 9, 31,246,235,191, 1, 3, 19, 63,235,194,153, 66, 72, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130, 0}; diff -Nru blender-2.61/source/blender/editors/gpencil/gpencil_buttons.c blender-2.62/source/blender/editors/gpencil/gpencil_buttons.c --- blender-2.61/source/blender/editors/gpencil/gpencil_buttons.c 2011-12-13 19:51:37.000000000 +0000 +++ blender-2.62/source/blender/editors/gpencil/gpencil_buttons.c 2012-02-15 19:36:22.000000000 +0000 @@ -143,9 +143,9 @@ /* name */ if (gpl->flag & GP_LAYER_HIDE) - sprintf(name, "%s (Hidden)", gpl->info); + BLI_snprintf(name, sizeof(name), "%s (Hidden)", gpl->info); else - sprintf(name, "%s (Locked)", gpl->info); + BLI_snprintf(name, sizeof(name), "%s (Locked)", gpl->info); uiItemL(sub, name, ICON_NONE); /* delete button (only if hidden but not locked!) */ diff -Nru blender-2.61/source/blender/editors/gpencil/gpencil_ops.c blender-2.62/source/blender/editors/gpencil/gpencil_ops.c --- blender-2.61/source/blender/editors/gpencil/gpencil_ops.c 2011-12-13 19:51:37.000000000 +0000 +++ blender-2.62/source/blender/editors/gpencil/gpencil_ops.c 2012-02-15 19:36:22.000000000 +0000 @@ -55,7 +55,8 @@ /* Draw */ /* draw */ - WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, 0, DKEY); + kmi=WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, 0, DKEY); + RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW); /* draw - straight lines */ kmi=WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, KM_CTRL, DKEY); RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW_STRAIGHT); diff -Nru blender-2.61/source/blender/editors/gpencil/gpencil_paint.c blender-2.62/source/blender/editors/gpencil/gpencil_paint.c --- blender-2.61/source/blender/editors/gpencil/gpencil_paint.c 2011-12-13 19:51:37.000000000 +0000 +++ blender-2.62/source/blender/editors/gpencil/gpencil_paint.c 2012-02-15 19:36:22.000000000 +0000 @@ -1117,14 +1117,6 @@ p->custom_color[1]= 0.0f; p->custom_color[2]= 0.5f; p->custom_color[3]= 0.9f; - - /* check that gpencil data is allowed to be drawn */ - if ((sc->flag & SC_SHOW_GPENCIL)==0) { - p->status= GP_STATUS_ERROR; - if (G.f & G_DEBUG) - printf("Error: In active view, Grease Pencil not shown \n"); - return 0; - } } break; diff -Nru blender-2.61/source/blender/editors/include/BIF_glutil.h blender-2.62/source/blender/editors/include/BIF_glutil.h --- blender-2.61/source/blender/editors/include/BIF_glutil.h 2011-12-13 19:52:45.000000000 +0000 +++ blender-2.62/source/blender/editors/include/BIF_glutil.h 2012-02-15 19:37:15.000000000 +0000 @@ -136,13 +136,8 @@ * is expected to be in RGBA byte or float format, and the * modelview and projection matrices are assumed to define a * 1-to-1 mapping to screen space. - * @param gamma_correct Optionally gamma correct float sources to sRGB for display */ - /* only for float rects, converts to 32 bits and draws */ -void glaDrawPixelsSafe_to32(float fx, float fy, int img_w, int img_h, int row_w, float *rectf, int gamma_correct); - - void glaDrawPixelsTex (float x, float y, int img_w, int img_h, int format, void *rect); void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format, void *rect, float scaleX, float scaleY); diff -Nru blender-2.61/source/blender/editors/include/ED_armature.h blender-2.62/source/blender/editors/include/ED_armature.h --- blender-2.61/source/blender/editors/include/ED_armature.h 2011-12-13 19:52:45.000000000 +0000 +++ blender-2.62/source/blender/editors/include/ED_armature.h 2012-02-15 19:37:15.000000000 +0000 @@ -62,7 +62,7 @@ normal bones when leaving editmode. */ void *temp; /* Used to store temporary data */ - char name[32]; + char name[64]; /* MAX_NAME */ float roll; /* Roll along axis. We'll ultimately use the axis/angle method for determining the transformation matrix of the bone. The axis is tail-head while roll provides the angle. Refer to Graphics diff -Nru blender-2.61/source/blender/editors/include/ED_curve.h blender-2.62/source/blender/editors/include/ED_curve.h --- blender-2.61/source/blender/editors/include/ED_curve.h 2011-12-13 19:52:45.000000000 +0000 +++ blender-2.62/source/blender/editors/include/ED_curve.h 2012-02-15 19:37:15.000000000 +0000 @@ -47,6 +47,7 @@ /* curve_ops.c */ void ED_operatortypes_curve(void); +void ED_operatormacros_curve(void); void ED_keymap_curve (struct wmKeyConfig *keyconf); /* editcurve.c */ diff -Nru blender-2.61/source/blender/editors/include/ED_image.h blender-2.62/source/blender/editors/include/ED_image.h --- blender-2.61/source/blender/editors/include/ED_image.h 2011-12-13 19:52:45.000000000 +0000 +++ blender-2.62/source/blender/editors/include/ED_image.h 2012-02-15 19:37:15.000000000 +0000 @@ -53,6 +53,7 @@ void ED_space_image_uv_aspect(struct SpaceImage *sima, float *aspx, float *aspy); void ED_space_image_paint_update(struct wmWindowManager *wm, struct ToolSettings *settings); +void ED_space_image_uv_sculpt_update(struct wmWindowManager *wm, struct ToolSettings *settings); void ED_image_size(struct Image *ima, int *width, int *height); void ED_image_aspect(struct Image *ima, float *aspx, float *aspy); @@ -66,5 +67,8 @@ /* UI level image (texture) updating... render calls own stuff (too) */ void ED_image_update_frame(const struct Main *mainp, int cfra); +void ED_image_draw_info(struct ARegion *ar, int color_manage, int channels, int x, int y, + const unsigned char cp[4], const float fp[4], int *zp, float *zpf); + #endif /* ED_IMAGE_H */ diff -Nru blender-2.61/source/blender/editors/include/ED_mesh.h blender-2.62/source/blender/editors/include/ED_mesh.h --- blender-2.61/source/blender/editors/include/ED_mesh.h 2011-12-13 19:52:45.000000000 +0000 +++ blender-2.62/source/blender/editors/include/ED_mesh.h 2012-02-15 19:37:15.000000000 +0000 @@ -87,8 +87,8 @@ /* meshtools.c */ -intptr_t mesh_octree_table(struct Object *ob, struct EditMesh *em, float *co, char mode); -long mesh_mirrtopo_table(struct Object *ob, char mode); +intptr_t mesh_octree_table(struct Object *ob, struct EditMesh *em, float *co, char mode); +int mesh_mirrtopo_table(struct Object *ob, char mode); struct EditVert *editmesh_get_x_mirror_vert(struct Object *ob, struct EditMesh *em, struct EditVert *eve, float *co, int index); int mesh_get_x_mirror_vert(struct Object *ob, int index); @@ -155,6 +155,9 @@ struct UvMapVert *EM_get_uv_map_vert(struct UvVertMap *vmap, unsigned int v); void EM_free_uv_vert_map(struct UvVertMap *vmap); +struct UvElementMap *EM_make_uv_element_map(struct EditMesh *em, int selected, int doIslands); +void EM_free_uv_element_map(struct UvElementMap *vmap); + void EM_add_data_layer(struct EditMesh *em, struct CustomData *data, int type, const char *name); void EM_free_data_layer(struct EditMesh *em, struct CustomData *data, int type); @@ -232,6 +235,10 @@ void ED_mesh_edges_add(struct Mesh *mesh, struct ReportList *reports, int count); void ED_mesh_vertices_add(struct Mesh *mesh, struct ReportList *reports, int count); +void ED_mesh_faces_remove(struct Mesh *mesh, struct ReportList *reports, int count); +void ED_mesh_edges_remove(struct Mesh *mesh, struct ReportList *reports, int count); +void ED_mesh_vertices_remove(struct Mesh *mesh, struct ReportList *reports, int count); + void ED_mesh_transform(struct Mesh *me, float *mat); void ED_mesh_calc_normals(struct Mesh *me); void ED_mesh_material_link(struct Mesh *me, struct Material *ma); @@ -243,6 +250,20 @@ int ED_mesh_color_remove(struct bContext *C, struct Object *ob, struct Mesh *me); int ED_mesh_color_remove_named(struct bContext *C, struct Object *ob, struct Mesh *me, const char *name); + +/* mirrtopo */ +typedef struct MirrTopoStore_t { + intptr_t *index_lookup; + int prev_vert_tot; + int prev_edge_tot; + int prev_ob_mode; +} MirrTopoStore_t; + +int ED_mesh_mirrtopo_recalc_check(struct Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_topo_store); +void ED_mesh_mirrtopo_init(struct Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_topo_store, + const short skip_em_vert_array_init); +void ED_mesh_mirrtopo_free(MirrTopoStore_t *mesh_topo_store); + #ifdef __cplusplus } #endif diff -Nru blender-2.61/source/blender/editors/include/ED_object.h blender-2.62/source/blender/editors/include/ED_object.h --- blender-2.61/source/blender/editors/include/ED_object.h 2011-12-13 19:52:45.000000000 +0000 +++ blender-2.62/source/blender/editors/include/ED_object.h 2012-02-15 19:37:15.000000000 +0000 @@ -40,6 +40,7 @@ struct bContext; struct bPoseChannel; struct Curve; +struct EnumPropertyItem; struct KeyBlock; struct Lattice; struct Main; @@ -56,13 +57,37 @@ struct wmOperatorType; /* object_edit.c */ -struct Object *ED_object_active_context(struct bContext *C); +struct Object *ED_object_context(struct bContext *C); /* context.object */ +struct Object *ED_object_active_context(struct bContext *C); /* context.object or context.active_object */ /* object_ops.c */ void ED_operatortypes_object(void); void ED_operatormacros_object(void); void ED_keymap_object(struct wmKeyConfig *keyconf); +/* object_relations.c */ +typedef enum eParentType { + PAR_OBJECT, + PAR_ARMATURE, + PAR_ARMATURE_NAME, + PAR_ARMATURE_ENVELOPE, + PAR_ARMATURE_AUTO, + PAR_BONE, + PAR_CURVE, + PAR_FOLLOW, + PAR_PATH_CONST, + PAR_LATTICE, + PAR_VERTEX, + PAR_TRIA +} eParentType; + +extern struct EnumPropertyItem prop_clear_parent_types[]; +extern struct EnumPropertyItem prop_make_parent_types[]; + +int ED_object_parent_set(struct bContext *C, struct wmOperator *op, struct Object *par, int partype); +void ED_object_parent_clear(struct bContext *C, int type); + + /* generic editmode keys like pet * do_pet * 0: No diff -Nru blender-2.61/source/blender/editors/include/ED_uvedit.h blender-2.62/source/blender/editors/include/ED_uvedit.h --- blender-2.61/source/blender/editors/include/ED_uvedit.h 2011-12-13 19:52:45.000000000 +0000 +++ blender-2.62/source/blender/editors/include/ED_uvedit.h 2012-02-15 19:37:15.000000000 +0000 @@ -81,7 +81,7 @@ void ED_unwrap_lscm(struct Scene *scene, struct Object *obedit, const short sel); /* uvedit_draw.c */ -void draw_uvedit_main(struct SpaceImage *sima, struct ARegion *ar, struct Scene *scene, struct Object *obedit); +void draw_uvedit_main(struct SpaceImage *sima, struct ARegion *ar, struct Scene *scene, struct Object *obedit, struct Object *obact); /* uvedit_buttons.c */ void ED_uvedit_buttons_register(struct ARegionType *art); diff -Nru blender-2.61/source/blender/editors/include/ED_view3d.h blender-2.62/source/blender/editors/include/ED_view3d.h --- blender-2.61/source/blender/editors/include/ED_view3d.h 2011-12-13 19:52:45.000000000 +0000 +++ blender-2.62/source/blender/editors/include/ED_view3d.h 2012-02-15 19:37:15.000000000 +0000 @@ -52,7 +52,8 @@ struct ViewContext; struct wmWindow; struct MVert; - +struct wmOperatorType; +struct wmOperator; /* for derivedmesh drawing callbacks, for view3d_select, .... */ typedef struct ViewContext { @@ -201,7 +202,7 @@ /* Projection */ #define IS_CLIPPED 12000 -void ED_view3d_calc_clipping(struct BoundBox *bb, float planes[4][4], struct bglMats *mats, struct rcti *rect); +void ED_view3d_calc_clipping(struct BoundBox *bb, float planes[4][4], struct bglMats *mats, const struct rcti *rect); void project_short(struct ARegion *ar, const float vec[3], short adr[2]); void project_short_noclip(struct ARegion *ar, const float vec[3], short adr[2]); @@ -209,13 +210,14 @@ void project_int(struct ARegion *ar, const float vec[3], int adr[2]); void project_int_noclip(struct ARegion *ar, const float vec[3], int adr[2]); +void apply_project_float(float persmat[4][4], int winx, int winy, const float vec[], float adr[2]); void project_float(struct ARegion *ar, const float vec[3], float adr[2]); void project_float_noclip(struct ARegion *ar, const float vec[3], float adr[2]); int ED_view3d_clip_range_get(struct View3D *v3d, struct RegionView3D *rv3d, float *clipsta, float *clipend); int ED_view3d_viewplane_get(struct View3D *v3d, struct RegionView3D *rv3d, int winxi, int winyi, struct rctf *viewplane, float *clipsta, float *clipend); void ED_view3d_ob_project_mat_get(struct RegionView3D *v3d, struct Object *ob, float pmat[4][4]); -void ED_view3d_project_float(struct ARegion *a, const float vec[3], float adr[2], float mat[4][4]); +void ED_view3d_project_float(const struct ARegion *a, const float vec[3], float adr[2], float mat[4][4]); void ED_view3d_calc_camera_border(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct RegionView3D *rv3d, struct rctf *viewborder_r, short no_shift); void ED_view3d_calc_camera_border_size(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct RegionView3D *rv3d, float size_r[2]); @@ -257,7 +259,7 @@ void view3d_operator_needs_opengl(const struct bContext *C); void view3d_region_operator_needs_opengl(struct wmWindow *win, struct ARegion *ar); int view3d_get_view_aligned_coordinate(struct ViewContext *vc, float fp[3], const int mval[2], const short do_fallback); -void view3d_get_transformation(struct ARegion *ar, struct RegionView3D *rv3d, struct Object *ob, struct bglMats *mats); +void view3d_get_transformation(const struct ARegion *ar, struct RegionView3D *rv3d, struct Object *ob, struct bglMats *mats); /* XXX should move to BLI_math */ int edge_inside_circle(short centx, short centy, short rad, short x1, short y1, short x2, short y2); @@ -266,8 +268,8 @@ /* get 3d region from context, also if mouse is in header or toolbar */ struct RegionView3D *ED_view3d_context_rv3d(struct bContext *C); -struct ARegion *ED_view3d_context_region_unlock(struct bContext *C); -int ED_operator_rv3d_unlock_poll(struct bContext *C); +int ED_view3d_context_user_region(struct bContext *C, struct View3D **v3d_r, struct ARegion **ar_r); +int ED_operator_rv3d_user_region_poll(struct bContext *C); void ED_view3d_init_mats_rv3d(struct Object *ob, struct RegionView3D *rv3d); void ED_view3d_init_mats_rv3d_gl(struct Object *ob, struct RegionView3D *rv3d); @@ -279,15 +281,16 @@ int winx, int winy, float viewmat[][4], float winmat[][4]); struct ImBuf *ED_view3d_draw_offscreen_imbuf(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, int sizex, int sizey, unsigned int flag, char err_out[256]); -struct ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, struct Object *camera, int width, int height, unsigned int flag, int drawtype, char err_out[256]); +struct ImBuf *ED_view3d_draw_offscreen_imbuf_simple(struct Scene *scene, struct Object *camera, int width, int height, unsigned int flag, int drawtype, char err_out[256]); -Base *ED_view3d_give_base_under_cursor(struct bContext *C, const int mval[2]); +struct Base *ED_view3d_give_base_under_cursor(struct bContext *C, const int mval[2]); void ED_view3d_quadview_update(struct ScrArea *sa, struct ARegion *ar, short do_clip); int ED_view3d_lock(struct RegionView3D *rv3d); -unsigned int ED_view3d_datamask(struct Scene *scene, struct View3D *v3d); -unsigned int ED_viewedit_datamask(struct bScreen *screen); +uint64_t ED_view3d_datamask(struct Scene *scene, struct View3D *v3d); +uint64_t ED_view3d_screen_datamask(struct bScreen *screen); +uint64_t ED_view3d_object_datamask(struct Scene *scene); /* camera lock functions */ int ED_view3d_camera_lock_check(struct View3D *v3d, struct RegionView3D *rv3d); @@ -300,4 +303,9 @@ void ED_view3D_background_image_remove(struct View3D *v3d, struct BGpic *bgpic); void ED_view3D_background_image_clear(struct View3D *v3d); +/* view matrix properties utilities */ +void ED_view3d_operator_properties_viewmat(struct wmOperatorType *ot); +void ED_view3d_operator_properties_viewmat_set(struct bContext *C, struct wmOperator *op); +void ED_view3d_operator_properties_viewmat_get(struct wmOperator *op, int *winx, int *winy, float persmat[4][4]); + #endif /* ED_VIEW3D_H */ diff -Nru blender-2.61/source/blender/editors/include/UI_icons.h blender-2.62/source/blender/editors/include/UI_icons.h --- blender-2.61/source/blender/editors/include/UI_icons.h 2011-12-13 19:52:45.000000000 +0000 +++ blender-2.62/source/blender/editors/include/UI_icons.h 2012-02-15 19:37:15.000000000 +0000 @@ -589,10 +589,10 @@ DEF_ICON(MOD_SCREW) DEF_ICON(MOD_VERTEX_WEIGHT) DEF_ICON(MOD_DYNAMICPAINT) +DEF_ICON(MOD_REMESH) +DEF_ICON(MOD_OCEAN) +DEF_ICON(MOD_WARP) #ifndef DEF_ICON_BLANK_SKIP - DEF_ICON(BLANK162) - DEF_ICON(BLANK163) - DEF_ICON(BLANK164) DEF_ICON(BLANK165) DEF_ICON(BLANK166) DEF_ICON(BLANK167) diff -Nru blender-2.61/source/blender/editors/include/UI_interface.h blender-2.62/source/blender/editors/include/UI_interface.h --- blender-2.61/source/blender/editors/include/UI_interface.h 2011-12-13 19:52:45.000000000 +0000 +++ blender-2.62/source/blender/editors/include/UI_interface.h 2012-02-15 19:37:15.000000000 +0000 @@ -62,6 +62,7 @@ struct CurveMapping; struct Image; struct ImageUser; +struct wmOperatorType; struct uiWidgetColors; struct Tex; struct MTex; @@ -446,6 +447,7 @@ uiBut *uiDefButR(uiBlock *block, int type, int retval, const char *str, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefButR_prop(uiBlock *block, int type, int retval, const char *str, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefButO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, const char *tip); +uiBut *uiDefButO_ptr(uiBlock *block, int type, struct wmOperatorType *ot, int opcontext, const char *str, int x1, int y1, short x2, short y2, const char *tip); uiBut *uiDefButTextO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefIconBut(uiBlock *block, @@ -466,6 +468,7 @@ uiBut *uiDefIconButR(uiBlock *block, int type, int retval, int icon, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefIconButR_prop(uiBlock *block, int type, int retval, int icon, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefIconButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, int x1, int y1, short x2, short y2, const char *tip); +uiBut *uiDefIconButO_ptr(uiBlock *block, int type, struct wmOperatorType *ot, int opcontext, int icon, int x1, int y1, short x2, short y2, const char *tip); uiBut *uiDefIconTextBut(uiBlock *block, int type, int retval, int icon, const char *str, @@ -485,6 +488,7 @@ uiBut *uiDefIconTextButR(uiBlock *block, int type, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefIconTextButR_prop(uiBlock *block, int type, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefIconTextButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, const char *str, int x1, int y1, short x2, short y2, const char *tip); +uiBut *uiDefIconTextButO_ptr(uiBlock *block, int type, struct wmOperatorType *ot, int opcontext, int icon, const char *str, int x1, int y1, short x2, short y2, const char *tip); /* for passing inputs to ButO buttons */ struct PointerRNA *uiButGetOperatorPtrRNA(uiBut *but); @@ -773,6 +777,7 @@ /* items */ void uiItemO(uiLayout *layout, const char *name, int icon, const char *opname); +void uiItemEnumO_ptr(uiLayout *layout, struct wmOperatorType *ot, const char *name, int icon, const char *propname, int value); void uiItemEnumO(uiLayout *layout, const char *opname, const char *name, int icon, const char *propname, int value); void uiItemEnumO_value(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, int value); void uiItemEnumO_string(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, const char *value); @@ -781,6 +786,8 @@ void uiItemIntO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, int value); void uiItemFloatO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, float value); void uiItemStringO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, const char *value); + +PointerRNA uiItemFullO_ptr(uiLayout *layout, struct wmOperatorType *ot, const char *name, int icon, IDProperty *properties, int context, int flag); PointerRNA uiItemFullO(uiLayout *layout, const char *idname, const char *name, int icon, struct IDProperty *properties, int context, int flag); void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon); diff -Nru blender-2.61/source/blender/editors/include/UI_interface_icons.h blender-2.62/source/blender/editors/include/UI_interface_icons.h --- blender-2.61/source/blender/editors/include/UI_interface_icons.h 2011-12-13 19:52:45.000000000 +0000 +++ blender-2.62/source/blender/editors/include/UI_interface_icons.h 2012-02-15 19:37:15.000000000 +0000 @@ -41,7 +41,7 @@ typedef struct IconFile { struct IconFile *next, *prev; - char filename[80]; // FILE_MAXFILE size + char filename[256]; // FILE_MAXFILE size int index; } IconFile; diff -Nru blender-2.61/source/blender/editors/include/UI_resources.h blender-2.62/source/blender/editors/include/UI_resources.h --- blender-2.61/source/blender/editors/include/UI_resources.h 2011-12-13 19:52:45.000000000 +0000 +++ blender-2.62/source/blender/editors/include/UI_resources.h 2012-02-15 19:37:15.000000000 +0000 @@ -45,79 +45,10 @@ } BIFIconID; #define BIFICONID_FIRST (ICON_NONE) -#define BIFNICONIDS (BIFICONID_LAST-BIFICONID_FIRST + 1) #undef DEF_ICON #undef DEF_VICO - -typedef enum { -#define BIFCOLORSHADE_FIRST (COLORSHADE_DARK) - COLORSHADE_DARK, - COLORSHADE_GREY, - COLORSHADE_MEDIUM, - COLORSHADE_HILITE, - COLORSHADE_LIGHT, - COLORSHADE_WHITE -#define BIFCOLORSHADE_LAST (COLORSHADE_WHITE) -#define BIFNCOLORSHADES (BIFCOLORSHADE_LAST-BIFCOLORSHADE_FIRST + 1) -} BIFColorShade; - -typedef enum { -#define BIFCOLORID_FIRST (BUTGREY) - BUTGREY = 0, - BUTGREEN, - BUTBLUE, - BUTSALMON, - MIDGREY, - BUTPURPLE, - BUTYELLOW, - REDALERT, - BUTRUST, - BUTWHITE, - BUTDBLUE, - BUTPINK, - BUTDPINK, - BUTMACTIVE, - - BUTIPO, - BUTAUDIO, - BUTCAMERA, - BUTRANDOM, - BUTEDITOBJECT, - BUTPROPERTY, - BUTSCENE, - BUTMOTION, - BUTMESSAGE, - BUTACTION, - BUTCD, - BUTGAME, - BUTVISIBILITY, - BUTYUCK, - BUTSEASICK, - BUTCHOKE, - BUTIMPERIAL, - - BUTTEXTCOLOR, - BUTTEXTPRESSED, - BUTSBACKGROUND, - - VIEWPORTBACKCOLOR, - VIEWPORTGRIDCOLOR, - VIEWPORTACTIVECOLOR, - VIEWPORTSELECTEDCOLOR, - VIEWPORTUNSELCOLOR, - - EDITVERTSEL, - EDITVERTUNSEL, - EDITEDGESEL, - EDITEDGEUNSEL - -#define BIFCOLORID_LAST (EDITEDGEUNSEL) -#define BIFNCOLORIDS (BIFCOLORID_LAST-BIFCOLORID_FIRST + 1) - -} BIFColorID; - enum { TH_REDALERT, @@ -255,7 +186,17 @@ TH_PATH_BEFORE, TH_PATH_AFTER, TH_CAMERA_PATH, - TH_LOCK_MARKER + TH_LOCK_MARKER, + + TH_STITCH_PREVIEW_FACE, + TH_STITCH_PREVIEW_EDGE, + TH_STITCH_PREVIEW_VERT, + TH_STITCH_PREVIEW_STITCHABLE, + TH_STITCH_PREVIEW_UNSTITCHABLE, + TH_STITCH_PREVIEW_ACTIVE, + + TH_MATCH, /* highlight color for search matches */ + TH_SELECT_HIGHLIGHT /* highlight color for selected outliner item */ }; /* XXX WARNING: previous is saved in file, so do not change order! */ diff -Nru blender-2.61/source/blender/editors/interface/interface.c blender-2.62/source/blender/editors/interface/interface.c --- blender-2.61/source/blender/editors/interface/interface.c 2011-12-13 19:54:27.000000000 +0000 +++ blender-2.62/source/blender/editors/interface/interface.c 2012-02-15 19:38:34.000000000 +0000 @@ -800,11 +800,43 @@ } } +/* XXX, this code will shorten any allocated string to 'UI_MAX_NAME_STR' + * since this is really long its unlikely to be an issue, + * but this could be supported */ +void ui_but_add_shortcut(uiBut *but, const char *shortcut_str, const short do_strip) +{ + + if (do_strip) { + char *cpoin= strchr(but->str, '|'); + if(cpoin) { + *cpoin= '\0'; + } + } + + /* without this, just allow stripping of the shortcut */ + if (shortcut_str) { + char *butstr_orig; + + if (but->str != but->strdata) { + butstr_orig = but->str; /* free after using as source buffer */ + } + else { + butstr_orig = BLI_strdup(but->str); + } + BLI_snprintf(but->strdata, + sizeof(but->strdata), + "%s|%s", + butstr_orig, shortcut_str); + MEM_freeN(butstr_orig); + but->str = but->strdata; + ui_check_but(but); + } +} static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block) { uiBut *but; - char buf[512]; + char buf[128]; /* for menu's */ MenuType *mt; @@ -815,24 +847,14 @@ if(block->minx != block->maxx) return; - -#define UI_MENU_KEY_STR_CAT \ - char *butstr_orig= BLI_strdup(but->str); \ - BLI_snprintf(but->strdata, \ - sizeof(but->strdata), \ - "%s|%s", \ - butstr_orig, buf); \ - MEM_freeN(butstr_orig); \ - but->str= but->strdata; \ - ui_check_but(but); \ - - for(but=block->buttons.first; but; but=but->next) { if(but->optype) { IDProperty *prop= (but->opptr)? but->opptr->data: NULL; - if(WM_key_event_operator_string(C, but->optype->idname, but->opcontext, prop, TRUE, buf, sizeof(buf))) { - UI_MENU_KEY_STR_CAT + if(WM_key_event_operator_string(C, but->optype->idname, but->opcontext, prop, TRUE, + buf, sizeof(buf))) + { + ui_but_add_shortcut(but, buf, FALSE); } } else if ((mt= uiButGetMenuType(but))) { @@ -846,8 +868,10 @@ IDP_AssignString(prop_menu_name, mt->idname, sizeof(mt->idname)); - if(WM_key_event_operator_string(C, "WM_OT_call_menu", WM_OP_INVOKE_REGION_WIN, prop_menu, FALSE, buf, sizeof(buf))) { - UI_MENU_KEY_STR_CAT + if(WM_key_event_operator_string(C, "WM_OT_call_menu", WM_OP_INVOKE_REGION_WIN, prop_menu, FALSE, + buf, sizeof(buf))) + { + ui_but_add_shortcut(but, buf, FALSE); } } } @@ -904,7 +928,9 @@ /* handle pending stuff */ if(block->layouts.first) uiBlockLayoutResolve(block, NULL, NULL); ui_block_do_align(block); - if((block->flag & UI_BLOCK_LOOP) && (block->flag & UI_BLOCK_NUMSELECT)) ui_menu_block_set_keyaccels(block); /* could use a different flag to check */ + if((block->flag & UI_BLOCK_LOOP) && (block->flag & UI_BLOCK_NUMSELECT)) { + ui_menu_block_set_keyaccels(block); /* could use a different flag to check */ + } if(block->flag & UI_BLOCK_LOOP) ui_menu_block_set_keymaps(C, block); /* after keymaps! */ @@ -1687,10 +1713,15 @@ return (BPY_button_exec(C, str_unit_convert, value, TRUE) != -1); } -static int ui_set_but_string_eval_num(bContext *C, uiBut *but, const char *str, double *value) +#endif /* WITH_PYTHON */ + + +int ui_set_but_string_eval_num(bContext *C, uiBut *but, const char *str, double *value) { int ok= FALSE; +#ifdef WITH_PYTHON + if(str[0] != '\0') { int is_unit_but= ui_is_but_unit(but); /* only enable verbose if we won't run again with units */ @@ -1712,10 +1743,16 @@ } } +#else /* WITH_PYTHON */ + + value= atof(str); + ok = TRUE; + +#endif /* WITH_PYTHON */ + return ok; } -#endif // WITH_PYTHON int ui_set_but_string(bContext *C, uiBut *but, const char *str) { @@ -1782,13 +1819,9 @@ /* number editing */ double value; -#ifdef WITH_PYTHON if(ui_set_but_string_eval_num(C, but, str, &value) == FALSE) { return 0; } -#else - value= atof(str); -#endif // WITH_PYTHON if(!ui_is_but_float(but)) value= (int)floor(value + 0.5); if(but->type==NUMABS) value= fabs(value); @@ -1901,7 +1934,7 @@ if(softmin < (double)but->hardmin) softmin= (double)but->hardmin; } - else if(value_max-1e-10 > softmax) { + if(value_max-1e-10 > softmax) { if(value_max < 0.0) softmax= -soft_range_round_down(-value_max, -softmax); else @@ -1933,21 +1966,32 @@ WM_operator_properties_free(but->opptr); MEM_freeN(but->opptr); } - if(but->func_argN) MEM_freeN(but->func_argN); + + if(but->func_argN) { + MEM_freeN(but->func_argN); + } + if(but->active) { /* XXX solve later, buttons should be free-able without context ideally, * however they may have open tooltips or popup windows, which need to * be closed using a context pointer */ - if(C) + if (C) { ui_button_active_free(C, but); - else - if(but->active) + } + else { + if(but->active) { MEM_freeN(but->active); + } + } + } + if (but->str && but->str != but->strdata) { + MEM_freeN(but->str); } - if(but->str && but->str != but->strdata) MEM_freeN(but->str); ui_free_link(but->link); - if((but->type == BUT_IMAGE) && but->poin) IMB_freeImBuf((struct ImBuf *)but->poin); + if ((but->type == BUT_IMAGE) && but->poin) { + IMB_freeImBuf((struct ImBuf *)but->poin); + } MEM_freeN(but); } @@ -1962,11 +2006,13 @@ ui_free_but(C, but); } - if(block->unit) + if (block->unit) { MEM_freeN(block->unit); + } - if(block->func_argN) + if (block->func_argN) { MEM_freeN(block->func_argN); + } CTX_store_free_list(&block->contexts); @@ -2633,8 +2679,9 @@ str= BLI_dynstr_get_cstring(dynstr); BLI_dynstr_free(dynstr); - if(free) + if (free) { MEM_freeN(item); + } freestr= 1; } @@ -2650,10 +2697,12 @@ } } - if(!str) - str= RNA_property_ui_name(prop); - if(free) + if (!str) { + str = RNA_property_ui_name(prop); + } + if (free) { MEM_freeN(item); + } } else { str= RNA_property_ui_name(prop); @@ -2733,9 +2782,10 @@ but->a1= ui_get_but_step_unit(but, but->a1); } - if(freestr) + if (freestr) { MEM_freeN((void *)str); - + } + return but; } @@ -2756,16 +2806,12 @@ return but; } -static uiBut *ui_def_but_operator(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, const char *tip) +static uiBut *ui_def_but_operator_ptr(uiBlock *block, int type, wmOperatorType *ot, int opcontext, const char *str, int x1, int y1, short x2, short y2, const char *tip) { uiBut *but; - wmOperatorType *ot; - - ot= WM_operatortype_find(opname, 0); if(!str) { - if(ot) str= ot->name; - else str= opname; + if(ot) str = ot->name; } if ((!tip || tip[0]=='\0') && ot && ot->description) { @@ -2787,6 +2833,12 @@ return but; } +static uiBut *UNUSED_FUNCTION(ui_def_but_operator)(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, const char *tip) +{ + wmOperatorType *ot = WM_operatortype_find(opname, 0); + if (str == NULL && ot == NULL) str = opname; + return ui_def_but_operator_ptr(block, type, ot, opcontext, str, x1, y1, x2, y2, tip); +} static uiBut *ui_def_but_operator_text(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip) { @@ -2833,7 +2885,7 @@ */ static int findBitIndex(unsigned int x) { - if (!x || (x&(x-1))!=0) { /* x&(x-1) strips lowest bit */ + if (!x || !is_power_of_2_i(x)) { /* is_power_of_2_i(x) strips lowest bit */ return -1; } else { int idx= 0; @@ -2918,7 +2970,7 @@ /* search if str matches the beginning of an ID struct */ if(str[0]) { - AutoComplete *autocpl= autocomplete_begin(str, 22); + AutoComplete *autocpl= autocomplete_begin(str, MAX_ID_NAME-2); ID *id; for(id= listb->first; id; id= id->next) @@ -2993,13 +3045,20 @@ ui_check_but(but); return but; } -uiBut *uiDefButO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, const char *tip) + +uiBut *uiDefButO_ptr(uiBlock *block, int type, wmOperatorType *ot, int opcontext, const char *str, int x1, int y1, short x2, short y2, const char *tip) { uiBut *but; - but= ui_def_but_operator(block, type, opname, opcontext, str, x1, y1, x2, y2, tip); + but= ui_def_but_operator_ptr(block, type, ot, opcontext, str, x1, y1, x2, y2, tip); ui_check_but(but); return but; } +uiBut *uiDefButO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, const char *tip) +{ + wmOperatorType *ot = WM_operatortype_find(opname, 0); + if (str == NULL && ot == NULL) str = opname; + return uiDefButO_ptr(block, type, ot, opcontext, str, x1, y1, x2, y2, tip); +} uiBut *uiDefButTextO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip) { @@ -3071,13 +3130,19 @@ ui_check_but_and_iconize(but, icon); return but; } -uiBut *uiDefIconButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, int x1, int y1, short x2, short y2, const char *tip) + +uiBut *uiDefIconButO_ptr(uiBlock *block, int type, wmOperatorType *ot, int opcontext, int icon, int x1, int y1, short x2, short y2, const char *tip) { uiBut *but; - but= ui_def_but_operator(block, type, opname, opcontext, "", x1, y1, x2, y2, tip); + but= ui_def_but_operator_ptr(block, type, ot, opcontext, "", x1, y1, x2, y2, tip); ui_check_but_and_iconize(but, icon); return but; } +uiBut *uiDefIconButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, int x1, int y1, short x2, short y2, const char *tip) +{ + wmOperatorType *ot = WM_operatortype_find(opname, 0); + return uiDefIconButO_ptr(block, type, ot, opcontext, icon, x1, y1, x2, y2, tip); +} /* Button containing both string label and icon */ uiBut *uiDefIconTextBut(uiBlock *block, int type, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip) @@ -3145,14 +3210,19 @@ but->flag|= UI_ICON_LEFT; return but; } -uiBut *uiDefIconTextButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, const char *str, int x1, int y1, short x2, short y2, const char *tip) +uiBut *uiDefIconTextButO_ptr(uiBlock *block, int type, wmOperatorType *ot, int opcontext, int icon, const char *str, int x1, int y1, short x2, short y2, const char *tip) { uiBut *but; - but= ui_def_but_operator(block, type, opname, opcontext, str, x1, y1, x2, y2, tip); + but= ui_def_but_operator_ptr(block, type, ot, opcontext, str, x1, y1, x2, y2, tip); ui_check_but_and_iconize(but, icon); but->flag|= UI_ICON_LEFT; return but; } +uiBut *uiDefIconTextButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, const char *str, int x1, int y1, short x2, short y2, const char *tip) +{ + wmOperatorType *ot = WM_operatortype_find(opname, 0); + return uiDefIconTextButO_ptr(block, type, ot, opcontext, icon, str, x1, y1, x2, y2, tip); +} /* END Button containing both string label and icon */ @@ -3347,8 +3417,9 @@ void uiBlockSetNFunc(uiBlock *block, uiButHandleFunc func, void *argN, void *arg2) { - if(block->func_argN) + if (block->func_argN) { MEM_freeN(block->func_argN); + } block->funcN= func; block->func_argN= argN; @@ -3377,8 +3448,9 @@ void uiButSetNFunc(uiBut *but, uiButHandleNFunc funcN, void *argN, void *arg2) { - if(but->func_argN) + if (but->func_argN) { MEM_freeN(but->func_argN); + } but->funcN= funcN; but->func_argN= argN; @@ -3416,8 +3488,9 @@ { uiBut *but= ui_def_but(block, BLOCK, 0, str, x1, y1, x2, y2, NULL, 0.0, 0.0, 0.0, 0.0, tip); but->block_create_func= func; - if(but->func_argN) + if (but->func_argN) { MEM_freeN(but->func_argN); + } but->func_argN= argN; ui_check_but(but); return but; diff -Nru blender-2.61/source/blender/editors/interface/interface_draw.c blender-2.62/source/blender/editors/interface/interface_draw.c --- blender-2.61/source/blender/editors/interface/interface_draw.c 2011-12-13 19:54:27.000000000 +0000 +++ blender-2.62/source/blender/editors/interface/interface_draw.c 2012-02-15 19:38:34.000000000 +0000 @@ -389,17 +389,7 @@ glEnable( GL_BLEND ); } - /* solid part */ - uiDrawBox(GL_POLYGON, minx, miny, maxx, maxy, rad); - - /* set antialias line */ - glEnable( GL_LINE_SMOOTH ); - glEnable( GL_BLEND ); - - uiDrawBox(GL_LINE_LOOP, minx, miny, maxx, maxy, rad); - - glDisable( GL_BLEND ); - glDisable( GL_LINE_SMOOTH ); + ui_draw_anti_roundbox(GL_POLYGON, minx, miny, maxx, maxy, rad); } @@ -1471,26 +1461,23 @@ fdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax); } -static ImBuf *scale_trackpreview_ibuf(ImBuf *ibuf, float zoomx, float zoomy) +static ImBuf *scale_trackpreview_ibuf(ImBuf *ibuf, float track_pos[2], int width, float height, int margin) { ImBuf *scaleibuf; - int x, y, w= ibuf->x*zoomx, h= ibuf->y*zoomy; - const float scalex= 1.0f/zoomx; - const float scaley= 1.0f/zoomy; - - scaleibuf= IMB_allocImBuf(w, h, 32, IB_rect); - - for(y= 0; yy; y++) { - for (x= 0; xx; x++) { - int pixel= scaleibuf->x*y + x; - int orig_pixel= ibuf->x*(int)(scaley*(float)y) + (int)(scalex*(float)x); - char *rrgb= (char*)scaleibuf->rect + pixel*4; - char *orig_rrgb= (char*)ibuf->rect + orig_pixel*4; - - rrgb[0]= orig_rrgb[0]; - rrgb[1]= orig_rrgb[1]; - rrgb[2]= orig_rrgb[2]; - rrgb[3]= orig_rrgb[3]; + const float scalex= ((float)ibuf->x-2*margin) / width; + const float scaley= ((float)ibuf->y-2*margin) / height; + float off_x= (int)track_pos[0]-track_pos[0]+0.5f; + float off_y= (int)track_pos[1]-track_pos[1]+0.5f; + int x, y; + + scaleibuf= IMB_allocImBuf(width, height, 32, IB_rect); + + for(y= 0; ytrack_disabled) { glColor4f(0.7f, 0.3f, 0.3f, 0.3f); uiSetRoundBox(15); - uiDrawBox(GL_POLYGON, rect.xmin-1, rect.ymin-1, rect.xmax+1, rect.ymax+1, 3.0f); + uiDrawBox(GL_POLYGON, rect.xmin-1, rect.ymin, rect.xmax+1, rect.ymax+1, 3.0f); ok= 1; } else if(scopes->track_preview) { - int a, off_x, off_y; - float zoomx, zoomy; + /* additional margin around image */ + /* NOTE: should be kept in sync with value from BKE_movieclip_update_scopes */ + const int margin= 3; + float zoomx, zoomy, track_pos[2], off_x, off_y; + int a, width, height; ImBuf *drawibuf; glPushMatrix(); + track_pos[0]= scopes->track_pos[0]-margin; + track_pos[1]= scopes->track_pos[1]-margin; + /* draw content of pattern area */ glScissor(ar->winrct.xmin+rect.xmin, ar->winrct.ymin+rect.ymin, scissor[2], scissor[3]); - zoomx= (rect.xmax-rect.xmin) / (scopes->track_preview->x-2.0f); - zoomy= (rect.ymax-rect.ymin) / (scopes->track_preview->y-2.0f); + width= rect.xmax-rect.xmin+1; + height = rect.ymax-rect.ymin; - off_x= ((int)scopes->track_pos[0]-scopes->track_pos[0]-0.5f)*zoomx; - off_y= ((int)scopes->track_pos[1]-scopes->track_pos[1]-0.5f)*zoomy; - - drawibuf= scale_trackpreview_ibuf(scopes->track_preview, zoomx, zoomy); - glaDrawPixelsSafe(off_x+rect.xmin, off_y+rect.ymin, rect.xmax-rect.xmin+1.f-off_x, rect.ymax-rect.ymin+1.f-off_y, drawibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, drawibuf->rect); + if(width > 0 && height > 0) { + zoomx= (float)width / (scopes->track_preview->x-2*margin); + zoomy= (float)height / (scopes->track_preview->y-2*margin); + + off_x= ((int)track_pos[0]-track_pos[0]+0.5f)*zoomx; + off_y= ((int)track_pos[1]-track_pos[1]+0.5f)*zoomy; + + drawibuf= scale_trackpreview_ibuf(scopes->track_preview, track_pos, width, height, margin); + + glaDrawPixelsSafe(rect.xmin, rect.ymin+1, drawibuf->x, drawibuf->y, + drawibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, drawibuf->rect); + IMB_freeImBuf(drawibuf); + + /* draw cross for pizel position */ + glTranslatef(off_x+rect.xmin+track_pos[0]*zoomx, off_y+rect.ymin+track_pos[1]*zoomy, 0.f); + glScissor(ar->winrct.xmin + rect.xmin, ar->winrct.ymin+rect.ymin, rect.xmax-rect.xmin, rect.ymax-rect.ymin); + + for(a= 0; a< 2; a++) { + if(a==1) { + glLineStipple(3, 0xaaaa); + glEnable(GL_LINE_STIPPLE); + UI_ThemeColor(TH_SEL_MARKER); + } + else { + UI_ThemeColor(TH_MARKER_OUTLINE); + } - IMB_freeImBuf(drawibuf); - - /* draw cross for pizel position */ - glTranslatef(off_x+rect.xmin+scopes->track_pos[0]*zoomx, off_y+rect.ymin+scopes->track_pos[1]*zoomy, 0.f); - glScissor(ar->winrct.xmin + rect.xmin, ar->winrct.ymin+rect.ymin, rect.xmax-rect.xmin, rect.ymax-rect.ymin); - - for(a= 0; a< 2; a++) { - if(a==1) { - glLineStipple(3, 0xaaaa); - glEnable(GL_LINE_STIPPLE); - UI_ThemeColor(TH_SEL_MARKER); - } - else { - UI_ThemeColor(TH_MARKER_OUTLINE); + glBegin(GL_LINES); + glVertex2f(-10.0f, 0.0f); + glVertex2f(10.0f, 0.0f); + glVertex2f(0.0f, -10.0f); + glVertex2f(0.0f, 10.0f); + glEnd(); } - - glBegin(GL_LINES); - glVertex2f(-10.0f, 0.0f); - glVertex2f(10.0f, 0.0f); - glVertex2f(0.0f, -10.0f); - glVertex2f(0.0f, 10.0f); - glEnd(); } glDisable(GL_LINE_STIPPLE); @@ -1575,7 +1574,7 @@ if(!ok) { glColor4f(0.f, 0.f, 0.f, 0.3f); uiSetRoundBox(15); - uiDrawBox(GL_POLYGON, rect.xmin-1, rect.ymin-1, rect.xmax+1, rect.ymax+1, 3.0f); + uiDrawBox(GL_POLYGON, rect.xmin-1, rect.ymin, rect.xmax+1, rect.ymax+1, 3.0f); } /* outline, scale gripper */ diff -Nru blender-2.61/source/blender/editors/interface/interface_handlers.c blender-2.62/source/blender/editors/interface/interface_handlers.c --- blender-2.61/source/blender/editors/interface/interface_handlers.c 2011-12-13 19:54:27.000000000 +0000 +++ blender-2.62/source/blender/editors/interface/interface_handlers.c 2012-02-15 19:38:34.000000000 +0000 @@ -114,6 +114,17 @@ BUTTON_EDIT_JUMP_ALL } uiButtonJumpType; +typedef enum uiButtonDelimType { + BUTTON_DELIM_NONE, + BUTTON_DELIM_ALPHA, + BUTTON_DELIM_PUNCT, + BUTTON_DELIM_BRACE, + BUTTON_DELIM_OPERATOR, + BUTTON_DELIM_QUOTE, + BUTTON_DELIM_WHITESPACE, + BUTTON_DELIM_OTHER +} uiButtonDelimType; + typedef struct uiHandleButtonData { wmWindowManager *wm; wmWindow *window; @@ -1104,8 +1115,7 @@ { static ColorBand but_copypaste_coba = {0}; char buf[UI_MAX_DRAW_STR+1]= {0}; - double val; - + if(mode=='v' && but->lock) return; @@ -1129,17 +1139,16 @@ if(but->poin==NULL && but->rnapoin.data==NULL); else if(mode=='c') { - if(ui_is_but_float(but)) - BLI_snprintf(buf, sizeof(buf), "%f", ui_get_but_val(but)); - else - BLI_snprintf(buf, sizeof(buf), "%d", (int)ui_get_but_val(but)); - + ui_get_but_string(but, buf, sizeof(buf)); WM_clipboard_text_set(buf, 0); } else { - if (sscanf(buf, " %lf ", &val) == 1) { + double val; + + if (ui_set_but_string_eval_num(C, but, buf, &val)) { button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); data->value= val; + ui_set_but_string(C, but, buf); button_activate_state(C, but, BUTTON_STATE_EXIT); } } @@ -1230,46 +1239,60 @@ /* ************* in-button text selection/editing ************* */ /* return 1 if char ch is special character, otherwise return 0 */ -static short test_special_char(char ch) +static uiButtonDelimType test_special_char(const char ch) { + if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) { + return BUTTON_DELIM_ALPHA; + } + switch(ch) { - case '\\': - case '/': + case ',': + case '.': + return BUTTON_DELIM_PUNCT; + + case '{': + case '}': + case '[': + case ']': + case '(': + case ')': + return BUTTON_DELIM_BRACE; + + case '+': + case '-': + case '=': case '~': + case '%': + case '/': + case '<': + case '>': + case '^': + case '*': + case '&': + return BUTTON_DELIM_OPERATOR; + + case '\'': + case '\"': // " - an extra closing one for Aligorith's text editor + return BUTTON_DELIM_QUOTE; + + case ' ': + return BUTTON_DELIM_WHITESPACE; + + case '\\': case '!': case '@': case '#': case '$': - case '%': - case '^': - case '&': - case '*': - case '(': - case ')': - case '+': - case '=': - case '{': - case '}': - case '[': - case ']': case ':': case ';': - case '\'': - case '\"': // " - an extra closing one for Aligorith's text editor - case '<': - case '>': - case ',': - case '.': case '?': case '_': - case '-': - case ' ': - return 1; - break; + return BUTTON_DELIM_OTHER; + default: break; } - return 0; + return BUTTON_DELIM_NONE; } static int ui_textedit_step_next_utf8(const char *str, size_t maxlen, short *pos) @@ -1308,12 +1331,13 @@ if(direction) { /* right*/ if(jump != BUTTON_EDIT_JUMP_NONE) { + const uiButtonDelimType is_special= (*pos) < maxlen ? test_special_char(str[(*pos)]) : BUTTON_DELIM_NONE; /* jump between special characters (/,\,_,-, etc.), * look at function test_special_char() for complete * list of special character, ctr -> */ while((*pos) < maxlen) { if (ui_textedit_step_next_utf8(str, maxlen, pos)) { - if((jump != BUTTON_EDIT_JUMP_ALL) && test_special_char(str[(*pos)])) break; + if((jump != BUTTON_EDIT_JUMP_ALL) && (is_special != test_special_char(str[(*pos)]))) break; } else { break; /* unlikely but just incase */ @@ -1326,6 +1350,7 @@ } else { /* left */ if(jump != BUTTON_EDIT_JUMP_NONE) { + const uiButtonDelimType is_special= (*pos) > 1 ? test_special_char(str[(*pos) - 1]) : BUTTON_DELIM_NONE; /* left only: compensate for index/change in direction */ ui_textedit_step_prev_utf8(str, maxlen, pos); @@ -1334,7 +1359,7 @@ * list of special character, ctr -> */ while ((*pos) > 0) { if (ui_textedit_step_prev_utf8(str, maxlen, pos)) { - if((jump != BUTTON_EDIT_JUMP_ALL) && test_special_char(str[(*pos)])) break; + if((jump != BUTTON_EDIT_JUMP_ALL) && (is_special != test_special_char(str[(*pos)]))) break; } else { break; @@ -1502,6 +1527,8 @@ const int pos_prev= but->pos; const int has_sel= (but->selend - but->selsta) > 0; + ui_check_but(but); + /* special case, quit selection and set cursor */ if (has_sel && !select) { if (jump == BUTTON_EDIT_JUMP_ALL) { @@ -1676,8 +1703,9 @@ changed= 1; } - if(pbuf) + if (pbuf) { MEM_freeN(pbuf); + } } /* cut & copy */ else if (copy || cut) { @@ -3004,12 +3032,28 @@ data->value= ui_step_name_menu(but, -1); button_activate_state(C, but, BUTTON_STATE_EXIT); ui_apply_button(C, but->block, but, data, 1); + + /* button's state need to be changed to EXIT so moving mouse away from this mouse wouldn't lead + * to cancel changes made to this button, but shanging state to EXIT also makes no button active for + * a while which leads to triggering operator when doing fast scrolling mouse wheel. + * using post activate stuff from button allows to make button be active again after checking for all + * all that mouse leave and cancel stuff, so wuick scrool wouldnt't be an issue anumore. + * same goes for scrolling wheel in another direction below (sergey) + */ + data->postbut= but; + data->posttype= BUTTON_ACTIVATE_OVER; + return WM_UI_HANDLER_BREAK; } else if(event->type == WHEELUPMOUSE && event->alt) { data->value= ui_step_name_menu(but, 1); button_activate_state(C, but, BUTTON_STATE_EXIT); ui_apply_button(C, but->block, but, data, 1); + + /* why this is needed described above */ + data->postbut= but; + data->posttype= BUTTON_ACTIVATE_OVER; + return WM_UI_HANDLER_BREAK; } } @@ -3563,31 +3607,6 @@ } -static int verg_colorband(const void *a1, const void *a2) -{ - const CBData *x1=a1, *x2=a2; - - if( x1->pos > x2->pos ) return 1; - else if( x1->pos < x2->pos) return -1; - return WM_UI_HANDLER_CONTINUE; -} - -static void ui_colorband_update(ColorBand *coba) -{ - int a; - - if(coba->tot<2) return; - - for(a=0; atot; a++) coba->data[a].cur= a; - qsort(coba->data, coba->tot, sizeof(CBData), verg_colorband); - for(a=0; atot; a++) { - if(coba->data[a].cur==coba->cur) { - coba->cur= a; - break; - } - } -} - static int ui_numedit_but_COLORBAND(uiBut *but, uiHandleButtonData *data, int mx) { float dx; @@ -3600,7 +3619,7 @@ data->dragcbd->pos += dx; CLAMP(data->dragcbd->pos, 0.0f, 1.0f); - ui_colorband_update(data->coba); + colorband_update_sort(data->coba); data->dragcbd= data->coba->data + data->coba->cur; /* because qsort */ data->draglastx= mx; @@ -4356,29 +4375,19 @@ uiBut *but = (uiBut *)arg1; if (but->optype) { - char buf[512], *cpoin; + char shortcut_str[128]; IDProperty *prop= (but->opptr)? but->opptr->data: NULL; /* complex code to change name of button */ - if(WM_key_event_operator_string(C, but->optype->idname, but->opcontext, prop, TRUE, buf, sizeof(buf))) { - char *butstr_orig; - - // XXX but->str changed... should not, remove the hotkey from it - cpoin= strchr(but->str, '|'); - if(cpoin) *cpoin= 0; - - butstr_orig= BLI_strdup(but->str); - BLI_snprintf(but->strdata, sizeof(but->strdata), "%s|%s", butstr_orig, buf); - MEM_freeN(butstr_orig); - but->str= but->strdata; - - ui_check_but(but); + if(WM_key_event_operator_string(C, but->optype->idname, but->opcontext, prop, TRUE, + shortcut_str, sizeof(shortcut_str))) + { + ui_but_add_shortcut(but, shortcut_str, TRUE); } else { - /* shortcut was removed */ - cpoin= strchr(but->str, '|'); - if(cpoin) *cpoin= 0; + /* simply strip the shortcut */ + ui_but_add_shortcut(but, NULL, TRUE); } } } @@ -5247,7 +5256,7 @@ highlight when not in a popup menu, we remove because data used in button below popup might have been removed by action of popup. Needs a more reliable solution... */ - if(state != BUTTON_STATE_HIGHLIGHT || but->block->handle) + if(state != BUTTON_STATE_HIGHLIGHT || (but->block->flag & UI_BLOCK_LOOP)) ui_check_but(but); } @@ -5850,15 +5859,17 @@ retval= WM_UI_HANDLER_BREAK; } else if(ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE)) { - /* list template will clamp */ - if(event->type == WHEELUPMOUSE) - pa->list_scroll--; - else - pa->list_scroll++; + if(pa->list_last_len > pa->list_size) { + /* list template will clamp */ + if(event->type == WHEELUPMOUSE) + pa->list_scroll--; + else + pa->list_scroll++; - ED_region_tag_redraw(ar); + ED_region_tag_redraw(ar); - retval= WM_UI_HANDLER_BREAK; + retval= WM_UI_HANDLER_BREAK; + } } } diff -Nru blender-2.61/source/blender/editors/interface/interface_icons.c blender-2.62/source/blender/editors/interface/interface_icons.c --- blender-2.61/source/blender/editors/interface/interface_icons.c 2011-12-13 19:54:27.000000000 +0000 +++ blender-2.62/source/blender/editors/interface/interface_icons.c 2012-02-15 19:38:34.000000000 +0000 @@ -665,7 +665,9 @@ for(; i>=0; i--){ MEM_freeN(dir[i].relname); MEM_freeN(dir[i].path); - if (dir[i].string) MEM_freeN(dir[i].string); + if (dir[i].string) { + MEM_freeN(dir[i].string); + } } free(dir); dir= NULL; diff -Nru blender-2.61/source/blender/editors/interface/interface_intern.h blender-2.62/source/blender/editors/interface/interface_intern.h --- blender-2.61/source/blender/editors/interface/interface_intern.h 2011-12-13 19:54:27.000000000 +0000 +++ blender-2.62/source/blender/editors/interface/interface_intern.h 2012-02-15 19:38:34.000000000 +0000 @@ -163,7 +163,7 @@ float hardmin, hardmax, softmin, softmax; float a1, a2; float aspect; - char col[4]; + unsigned char col[4]; uiButHandleFunc func; void *func_arg1; @@ -356,6 +356,7 @@ extern void ui_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen); extern int ui_set_but_string(struct bContext *C, uiBut *but, const char *str); extern int ui_get_but_string_max_length(uiBut *but); +extern int ui_set_but_string_eval_num(struct bContext *C, uiBut *but, const char *str, double *value); extern void ui_set_but_default(struct bContext *C, short all); @@ -444,7 +445,7 @@ /* interface_draw.c */ extern void ui_dropshadow(rctf *rct, float radius, float aspect, int select); -void ui_draw_gradient(rcti *rect, float *hsv, int type, float alpha); +void ui_draw_gradient(rcti *rect, const float hsv[3], int type, float alpha); void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, rcti *rect); void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, rcti *rect); @@ -462,6 +463,7 @@ /* interface_widgets.c */ void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3); +void ui_draw_anti_roundbox(int mode, float minx, float miny, float maxx, float maxy, float rad); void ui_draw_menu_back(struct uiStyle *style, uiBlock *block, rcti *rect); void ui_draw_search_back(struct uiStyle *style, uiBlock *block, rcti *rect); int ui_link_bezier_points(rcti *rect, float coord_array[][2], int resol); @@ -496,6 +498,7 @@ void ui_layout_add_but(uiLayout *layout, uiBut *but); int ui_but_can_align(uiBut *but); void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *searchptr, PropertyRNA *searchprop); +void ui_but_add_shortcut(uiBut *but, const char *key_str, const short do_strip); /* interface_anim.c */ void ui_but_anim_flag(uiBut *but, float cfra); diff -Nru blender-2.61/source/blender/editors/interface/interface_layout.c blender-2.62/source/blender/editors/interface/interface_layout.c --- blender-2.61/source/blender/editors/interface/interface_layout.c 2011-12-13 19:54:27.000000000 +0000 +++ blender-2.62/source/blender/editors/interface/interface_layout.c 2012-02-15 19:38:34.000000000 +0000 @@ -66,6 +66,14 @@ #define EM_SEPR_X 6 #define EM_SEPR_Y 6 +#define UI_OPERATOR_ERROR_RET(_ot, _opname, return_statement) \ + if (ot == NULL) { \ + ui_item_disabled(layout, _opname); \ + RNA_warning("'%s' unknown operator", _opname); \ + return_statement; \ + } (void)0 \ + + /* uiLayoutRoot */ typedef struct uiLayoutRoot { @@ -320,7 +328,7 @@ int len= RNA_property_array_length(ptr, prop); if(!shift) { - RNA_property_boolean_set_index(ptr, prop, index, 1); + RNA_property_boolean_set_index(ptr, prop, index, TRUE); for(i=0; iroot->block; - wmOperatorType *ot= WM_operatortype_find(opname, 1); uiBut *but; int w; - if(!ot) { - ui_item_disabled(layout, opname); - RNA_warning("unknown operator '%s'", opname); - return PointerRNA_NULL; - } - if(!name) { name= IFACE_(ot->name); } @@ -649,12 +651,18 @@ if (flag & UI_ITEM_R_NO_BG) uiBlockSetEmboss(block, UI_EMBOSSN); - if(icon && name[0]) - but= uiDefIconTextButO(block, BUT, ot->idname, context, icon, name, 0, 0, w, UI_UNIT_Y, NULL); - else if(icon) - but= uiDefIconButO(block, BUT, ot->idname, context, icon, 0, 0, w, UI_UNIT_Y, NULL); - else - but= uiDefButO(block, BUT, ot->idname, context, name, 0, 0, w, UI_UNIT_Y, NULL); + /* create the button */ + if(icon) { + if (name[0]) { + but = uiDefIconTextButO_ptr(block, BUT, ot, context, icon, name, 0, 0, w, UI_UNIT_Y, NULL); + } + else { + but = uiDefIconButO_ptr(block, BUT, ot, context, icon, 0, 0, w, UI_UNIT_Y, NULL); + } + } + else { + but= uiDefButO_ptr(block, BUT, ot, context, name, 0, 0, w, UI_UNIT_Y, NULL); + } assert(but->optype != NULL); @@ -686,52 +694,85 @@ return PointerRNA_NULL; } -static const char *ui_menu_enumpropname(uiLayout *layout, const char *opname, const char *propname, int retval) +PointerRNA uiItemFullO(uiLayout *layout, const char *opname, const char *name, int icon, IDProperty *properties, int context, int flag) { - wmOperatorType *ot= WM_operatortype_find(opname, 0); - PointerRNA ptr; - PropertyRNA *prop; + wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */ - if(!ot || !ot->srna) - return ""; + UI_OPERATOR_ERROR_RET(ot, opname, return PointerRNA_NULL); - RNA_pointer_create(NULL, ot->srna, NULL, &ptr); - prop= RNA_struct_find_property(&ptr, propname); + return uiItemFullO_ptr(layout, ot, name, icon, properties, context, flag); +} - if(prop) { - EnumPropertyItem *item; - int totitem, free; - const char *name; +static const char *ui_menu_enumpropname(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int retval) +{ + EnumPropertyItem *item; + int totitem, free; + const char *name; - RNA_property_enum_items_gettexted(layout->root->block->evil_C, &ptr, prop, &item, &totitem, &free); - if(RNA_enum_name(item, retval, &name)) { - if(free) MEM_freeN(item); - return name; - } - - if(free) - MEM_freeN(item); + RNA_property_enum_items_gettexted(layout->root->block->evil_C, ptr, prop, &item, &totitem, &free); + if (RNA_enum_name(item, retval, &name) == 0) { + name = ""; + } + + if (free) { + MEM_freeN(item); } - return ""; + return name; } -void uiItemEnumO(uiLayout *layout, const char *opname, const char *name, int icon, const char *propname, int value) +/* same as below but 'prop' is already known */ +static void uiItemEnumO_ptr__internal(uiLayout *layout, wmOperatorType *ot, const char *name, int icon, PropertyRNA *prop, int value) +{ + PointerRNA ptr; + WM_operator_properties_create_ptr(&ptr, ot); + RNA_property_enum_set(&ptr, prop, value); + + if(!name) + name = ui_menu_enumpropname(layout, &ptr, prop, value); + + uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0); +} +void uiItemEnumO_ptr(uiLayout *layout, wmOperatorType *ot, const char *name, int icon, const char *propname, int value) { PointerRNA ptr; + PropertyRNA *prop; + + WM_operator_properties_create_ptr(&ptr, ot); + + if ((prop = RNA_struct_find_property(&ptr, propname))) { + /* pass */ + } + else { + RNA_warning("%s.%s not found", RNA_struct_identifier(ptr.type), propname); + return; + } - WM_operator_properties_create(&ptr, opname); - RNA_enum_set(&ptr, propname, value); + RNA_property_enum_set(&ptr, prop, value); if(!name) - name= ui_menu_enumpropname(layout, opname, propname, value); + name = ui_menu_enumpropname(layout, &ptr, prop, value); + + uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0); +} +void uiItemEnumO(uiLayout *layout, const char *opname, const char *name, int icon, const char *propname, int value) +{ + wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */ + + if(ot) { + uiItemEnumO_ptr(layout, ot, name, icon, propname, value); + } + else { + ui_item_disabled(layout, opname); + RNA_warning("unknown operator '%s'", opname); + } - uiItemFullO(layout, opname, name, icon, ptr.data, layout->root->opcontext, 0); } void uiItemsFullEnumO(uiLayout *layout, const char *opname, const char *propname, IDProperty *properties, int context, int flag) { - wmOperatorType *ot= WM_operatortype_find(opname, 1); + wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */ + PointerRNA ptr; PropertyRNA *prop; uiBut *bt; @@ -744,7 +785,7 @@ } RNA_pointer_create(NULL, ot->srna, NULL, &ptr); - prop= RNA_struct_find_property(&ptr, propname); + prop = RNA_struct_find_property(&ptr, propname); /* don't let bad properties slip through */ BLI_assert((prop == NULL) || (RNA_property_type(prop) == PROP_ENUM)); @@ -768,12 +809,13 @@ MEM_freeN(tptr.data); } tptr.data= IDP_CopyProperty(properties); - RNA_enum_set(&tptr, propname, item[i].value); + RNA_property_enum_set(&tptr, prop, item[i].value); - uiItemFullO(column, opname, item[i].name, item[i].icon, tptr.data, context, flag); + uiItemFullO_ptr(column, ot, item[i].name, item[i].icon, tptr.data, context, flag); + } + else { + uiItemEnumO_ptr__internal(column, ot, item[i].name, item[i].icon, prop, item[i].value); } - else - uiItemEnumO(column, opname, item[i].name, item[i].icon, propname, item[i].value); } else { if(item[i].name) { @@ -792,8 +834,9 @@ } } - if(free) + if (free) { MEM_freeN(item); + } } } @@ -805,15 +848,16 @@ /* for use in cases where we have */ void uiItemEnumO_value(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, int value) { + wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */ PointerRNA ptr; - - /* for getting the enum */ PropertyRNA *prop; - WM_operator_properties_create(&ptr, opname); + UI_OPERATOR_ERROR_RET(ot, opname, return); + + WM_operator_properties_create_ptr(&ptr, ot); /* enum lookup */ - if((prop= RNA_struct_find_property(&ptr, propname))) { + if ((prop = RNA_struct_find_property(&ptr, propname))) { /* pass */ } else { @@ -825,33 +869,38 @@ /* same as uiItemEnumO */ if(!name) - name= ui_menu_enumpropname(layout, opname, propname, value); + name = ui_menu_enumpropname(layout, &ptr, prop, value); - uiItemFullO(layout, opname, name, icon, ptr.data, layout->root->opcontext, 0); + uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0); } void uiItemEnumO_string(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, const char *value_str) { + wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */ PointerRNA ptr; - - /* for getting the enum */ PropertyRNA *prop; + EnumPropertyItem *item; int value, free; - WM_operator_properties_create(&ptr, opname); + UI_OPERATOR_ERROR_RET(ot, opname, return); + + WM_operator_properties_create_ptr(&ptr, ot); /* enum lookup */ if((prop= RNA_struct_find_property(&ptr, propname))) { RNA_property_enum_items_gettexted(layout->root->block->evil_C, &ptr, prop, &item, NULL, &free); if(item==NULL || RNA_enum_value_from_id(item, value_str, &value)==0) { - if(free) MEM_freeN(item); + if(free) { + MEM_freeN(item); + } RNA_warning("%s.%s, enum %s not found", RNA_struct_identifier(ptr.type), propname, value_str); return; } - if(free) + if (free) { MEM_freeN(item); + } } else { RNA_warning("%s.%s not found", RNA_struct_identifier(ptr.type), propname); @@ -862,49 +911,61 @@ /* same as uiItemEnumO */ if(!name) - name= ui_menu_enumpropname(layout, opname, propname, value); + name = ui_menu_enumpropname(layout, &ptr, prop, value); - uiItemFullO(layout, opname, name, icon, ptr.data, layout->root->opcontext, 0); + uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0); } void uiItemBooleanO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, int value) { + wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */ PointerRNA ptr; - WM_operator_properties_create(&ptr, opname); + UI_OPERATOR_ERROR_RET(ot, opname, return); + + WM_operator_properties_create_ptr(&ptr, ot); RNA_boolean_set(&ptr, propname, value); - uiItemFullO(layout, opname, name, icon, ptr.data, layout->root->opcontext, 0); + uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0); } void uiItemIntO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, int value) { + wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */ PointerRNA ptr; - WM_operator_properties_create(&ptr, opname); + UI_OPERATOR_ERROR_RET(ot, opname, return); + + WM_operator_properties_create_ptr(&ptr, ot); RNA_int_set(&ptr, propname, value); - uiItemFullO(layout, opname, name, icon, ptr.data, layout->root->opcontext, 0); + uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0); } void uiItemFloatO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, float value) { + wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */ PointerRNA ptr; - WM_operator_properties_create(&ptr, opname); + UI_OPERATOR_ERROR_RET(ot, opname, return); + + WM_operator_properties_create_ptr(&ptr, ot); RNA_float_set(&ptr, propname, value); - uiItemFullO(layout, opname, name, icon, ptr.data, layout->root->opcontext, 0); + uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0); } void uiItemStringO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, const char *value) { + wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */ PointerRNA ptr; - WM_operator_properties_create(&ptr, opname); + UI_OPERATOR_ERROR_RET(ot, opname, return); + + WM_operator_properties_create_ptr(&ptr, ot); RNA_string_set(&ptr, propname, value); - uiItemFullO(layout, opname, name, icon, ptr.data, layout->root->opcontext, 0); + uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0); } void uiItemO(uiLayout *layout, const char *name, int icon, const char *opname) @@ -1096,7 +1157,9 @@ RNA_property_enum_items_gettexted(layout->root->block->evil_C, ptr, prop, &item, NULL, &free); if(!RNA_enum_value_from_id(item, value, &ivalue)) { - if(free) MEM_freeN(item); + if (free) { + MEM_freeN(item); + } ui_item_disabled(layout, propname); RNA_warning("enum property value not found: %s", value); return; @@ -1109,8 +1172,9 @@ } } - if(free) + if (free) { MEM_freeN(item); + } } void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propname) @@ -1160,8 +1224,9 @@ } } - if(free) + if (free) { MEM_freeN(item); + } } } @@ -1208,7 +1273,7 @@ if(itemptr.type && RNA_struct_is_ID(itemptr.type)) { ID *id= itemptr.data; - char name_ui[32]; + char name_ui[MAX_ID_NAME]; #if 0 /* this name is used for a string comparison and can't be modified, TODO */ name_uiprefix_id(name_ui, id); @@ -1536,14 +1601,11 @@ void uiItemMenuEnumO(uiLayout *layout, const char *opname, const char *propname, const char *name, int icon) { - wmOperatorType *ot= WM_operatortype_find(opname, 1); + wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */ MenuItemLevel *lvl; - if(!ot) { - ui_item_disabled(layout, opname); - RNA_warning("unknown operator '%s'", opname); - return; - } + UI_OPERATOR_ERROR_RET(ot, opname, return); + if(!ot->srna) { ui_item_disabled(layout, opname); RNA_warning("operator missing srna '%s'", opname); @@ -2731,8 +2793,9 @@ { DynStr *ds= BLI_dynstr_new(); - if(str) + if (str) { MEM_freeN(str); + } ui_intro_uiLayout(ds, layout); @@ -2742,6 +2805,11 @@ return str; } +static void ui_layout_operator_buts__reset_cb(bContext *UNUSED(C), void *op_pt, void *UNUSED(arg_dummy2)) +{ + WM_operator_properties_reset((wmOperator *)op_pt); +} + /* this function does not initialize the layout, functions can be called on the layout before and after */ void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op,int (*check_prop)(struct PointerRNA *, struct PropertyRNA *), const char label_align, const short flag) { @@ -2778,7 +2846,7 @@ WM_operator_properties_create(&op_ptr, "WM_OT_operator_preset_add"); RNA_string_set(&op_ptr, "operator", op->type->idname); - RNA_boolean_set(&op_ptr, "remove_active", 1); + RNA_boolean_set(&op_ptr, "remove_active", TRUE); op_ptr= uiItemFullO(row, "WM_OT_operator_preset_add", "", ICON_ZOOMOUT, op_ptr.data, WM_OP_INVOKE_DEFAULT, 0); } @@ -2803,7 +2871,22 @@ uiItemL(layout, IFACE_("No Properties"), ICON_NONE); } } - + + /* its possible that reset can do nothing if all have PROP_SKIP_SAVE enabled + * but this is not so important if this button is drawn in those cases + * (which isn't all that likely anyway) - campbell */ + if (op->properties->len) { + uiBlock *block; + uiBut *but; + uiLayout *col; /* needed to avoid alignment errors with previous buttons */ + + col= uiLayoutColumn(layout, 0); + block= uiLayoutGetBlock(col); + but = uiDefIconTextBut(block , BUT, 0, ICON_FILE_REFRESH, "Reset", 0, 0, 18, 20, NULL, 0.0, 0.0, 0.0, 0.0, + "Reset operator defaults"); + uiButSetFunc(but, ui_layout_operator_buts__reset_cb, op, NULL); + } + /* set various special settings for buttons */ { uiBut *but; diff -Nru blender-2.61/source/blender/editors/interface/interface_ops.c blender-2.62/source/blender/editors/interface/interface_ops.c --- blender-2.61/source/blender/editors/interface/interface_ops.c 2011-12-13 19:54:27.000000000 +0000 +++ blender-2.62/source/blender/editors/interface/interface_ops.c 2012-02-15 19:38:34.000000000 +0000 @@ -103,7 +103,8 @@ static void eyedropper_sample(bContext *C, Eyedropper *eye, int mx, int my) { if(RNA_property_type(eye->prop) == PROP_FLOAT) { - const int color_manage = CTX_data_scene(C)->r.color_mgt_flag & R_COLOR_MANAGEMENT; + Scene *scene = CTX_data_scene(C); + const int color_manage = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT; float col[4]; RNA_property_float_get_array(&eye->ptr, eye->prop, col); @@ -494,7 +495,7 @@ } uiEditSourceStore; struct uiEditSourceButStore { - char py_dbg_fn[240]; + char py_dbg_fn[FILE_MAX]; int py_dbg_ln; } uiEditSourceButStore; @@ -584,7 +585,7 @@ /* editsource operator component */ static int editsource_text_edit(bContext *C, wmOperator *op, - char filepath[240], int line) + char filepath[FILE_MAX], int line) { struct Main *bmain= CTX_data_main(C); Text *text; diff -Nru blender-2.61/source/blender/editors/interface/interface_panel.c blender-2.62/source/blender/editors/interface/interface_panel.c --- blender-2.61/source/blender/editors/interface/interface_panel.c 2011-12-13 19:54:27.000000000 +0000 +++ blender-2.62/source/blender/editors/interface/interface_panel.c 2012-02-15 19:38:34.000000000 +0000 @@ -330,7 +330,6 @@ #endif /* triangle 'icon' for panel header */ -/* NOTE - this seems to be only used for hiding nodes now */ void UI_DrawTriIcon(float x, float y, char dir) { if(dir=='h') { @@ -773,8 +772,9 @@ ui_panel_copy_offset(pa, pa->paneltab); /* free panelsort array */ - for(ps= panelsort, a=0; apa); + } MEM_freeN(panelsort); return done; diff -Nru blender-2.61/source/blender/editors/interface/interface_regions.c blender-2.62/source/blender/editors/interface/interface_regions.c --- blender-2.61/source/blender/editors/interface/interface_regions.c 2011-12-13 19:54:27.000000000 +0000 +++ blender-2.62/source/blender/editors/interface/interface_regions.c 2012-02-15 19:38:34.000000000 +0000 @@ -138,8 +138,9 @@ static void menudata_free(MenuData *md) { MEM_freeN((void *)md->instr); - if (md->items) + if (md->items) { MEM_freeN(md->items); + } MEM_freeN(md); } @@ -394,8 +395,9 @@ } } - if(free) + if (free) { MEM_freeN(item); + } } } @@ -409,7 +411,9 @@ /* operator keymap (not menus, they already have it) */ prop= (but->opptr)? but->opptr->data: NULL; - if(WM_key_event_operator_string(C, but->optype->idname, but->opcontext, prop, TRUE, buf, sizeof(buf))) { + if(WM_key_event_operator_string(C, but->optype->idname, but->opcontext, prop, TRUE, + buf, sizeof(buf))) + { BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Shortcut: %s"), buf); data->color[data->totline]= 0x888888; data->totline++; @@ -980,8 +984,9 @@ int a; /* free search data */ - for(a=0; aitems.maxitem; a++) + for (a = 0; a < data->items.maxitem; a++) { MEM_freeN(data->items.names[a]); + } MEM_freeN(data->items.names); MEM_freeN(data->items.pointers); MEM_freeN(data->items.icons); @@ -1071,18 +1076,16 @@ /* copy to int, gets projected if possible too */ x1= x1f; y1= y1f; x2= x2f; y2= y2f; - if(butregion) { - if(butregion->v2d.cur.xmin != butregion->v2d.cur.xmax) { - UI_view2d_to_region_no_clip(&butregion->v2d, x1f, y1f, &x1, &y1); - UI_view2d_to_region_no_clip(&butregion->v2d, x2f, y2f, &x2, &y2); - } - - x1 += butregion->winrct.xmin; - x2 += butregion->winrct.xmin; - y1 += butregion->winrct.ymin; - y2 += butregion->winrct.ymin; + if(butregion->v2d.cur.xmin != butregion->v2d.cur.xmax) { + UI_view2d_to_region_no_clip(&butregion->v2d, x1f, y1f, &x1, &y1); + UI_view2d_to_region_no_clip(&butregion->v2d, x2f, y2f, &x2, &y2); } - + + x1 += butregion->winrct.xmin; + x2 += butregion->winrct.xmin; + y1 += butregion->winrct.ymin; + y2 += butregion->winrct.ymin; + wm_window_get_size(CTX_wm_window(C), &winx, &winy); if(x2 > winx) { @@ -1096,7 +1099,8 @@ x2= winx; } } - if(y1 < 0) { /* XXX butregion NULL check?, there is one above */ + + if(y1 < 0) { int newy1; UI_view2d_to_region_no_clip(&butregion->v2d, 0, but->y2 + ofsy, NULL, &newy1); newy1 += butregion->winrct.ymin; @@ -1181,8 +1185,9 @@ uiButSetFlag(but, UI_BUT_REDALERT); } - for(x1=0; x1maxitem; x1++) + for (x1 = 0; x1 < items->maxitem; x1++) { MEM_freeN(items->names[x1]); + } MEM_freeN(items->names); MEM_freeN(items); } @@ -1536,6 +1541,8 @@ if(ELEM(but->type, BLOCK, PULLDOWN)) block->xofs = -2; /* for proper alignment */ + block->aspect = but->block->aspect; + ui_block_position(window, butregion, but, block); } else { @@ -1610,6 +1617,7 @@ MenuEntry *entry; const char *instr= arg_str; int columns, rows, a, b; + int column_start= 0, column_end= 0; uiBlockSetFlag(block, UI_BLOCK_MOVEMOUSE_QUIT); @@ -1653,17 +1661,30 @@ /* create items */ split= uiLayoutSplit(layout, 0, 0); - for(a=0, b=0; anitems; a++, b++) { + for(a=0; anitems; a++) { + if(a == column_end) { + /* start new column, and find out where it ends in advance, so we + can flip the order of items properly per column */ + column_start= a; + column_end= md->nitems; + + for(b=a+1; bnitems; b++) { + entry= &md->items[b]; + + /* new column on N rows or on separation label */ + if(((b-a) % rows == 0) || (entry->sepr && entry->str[0])) { + column_end = b; + break; + } + } + + column= uiLayoutColumn(split, 0); + } + if(block->flag & UI_BLOCK_NO_FLIP) entry= &md->items[a]; else - entry= &md->items[md->nitems-a-1]; - - /* new column on N rows or on separation label */ - if((b % rows == 0) || (entry->sepr && entry->str[0])) { - column= uiLayoutColumn(split, 0); - b= 0; - } + entry= &md->items[column_start + column_end-1-a]; if(entry->sepr) { uiItemL(column, entry->str, entry->icon); @@ -2110,7 +2131,7 @@ uiBut *but= arg_but; uiBlock *block; - block= uiBeginBlock(C, handle->region, "colorpicker", UI_EMBOSS); + block= uiBeginBlock(C, handle->region, __func__, UI_EMBOSS); if (but->rnaprop) { if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) { @@ -2300,8 +2321,8 @@ uiStyle *style= UI_GetStyle(); uiPopupBlockHandle *handle; uiPopupMenu *pup; - pup= MEM_callocN(sizeof(uiPopupMenu), "menu dummy"); - pup->block= uiBeginBlock(C, NULL, "ui_button_menu_create", UI_EMBOSSP); + pup= MEM_callocN(sizeof(uiPopupMenu), __func__); + pup->block= uiBeginBlock(C, NULL, __func__, UI_EMBOSSP); pup->layout= uiBlockLayout(pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, style); pup->slideout= (but && (but->block->flag & UI_BLOCK_LOOP)); pup->but= but; @@ -2362,7 +2383,7 @@ uiPopupMenu *pup= MEM_callocN(sizeof(uiPopupMenu), "popup menu"); uiBut *but; - pup->block= uiBeginBlock(C, NULL, "uiPupMenuBegin", UI_EMBOSSP); + pup->block= uiBeginBlock(C, NULL, __func__, UI_EMBOSSP); pup->block->flag |= UI_BLOCK_POPUP_MEMORY; pup->block->puphash= ui_popup_menu_hash(title); pup->layout= uiBlockLayout(pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, style); @@ -2459,7 +2480,7 @@ char *s, buf[512]; s= buf; - if (title) s+= sprintf(s, "%s%%t|%s", title, item); + if (title) s+= BLI_snprintf(s, sizeof(buf), "%s%%t|%s", title, item); (void)s; handle= ui_popup_menu_create(C, NULL, NULL, NULL, NULL, buf); @@ -2636,8 +2657,13 @@ void uiPupBlockClose(bContext *C, uiBlock *block) { if(block->handle) { - UI_remove_popup_handlers(&CTX_wm_window(C)->modalhandlers, block->handle); - ui_popup_block_free(C, block->handle); + wmWindow *win = CTX_wm_window(C); + + /* if loading new .blend while popup is open, window will be NULL */ + if(win) { + UI_remove_popup_handlers(&win->modalhandlers, block->handle); + ui_popup_block_free(C, block->handle); + } } } diff -Nru blender-2.61/source/blender/editors/interface/interface_style.c blender-2.62/source/blender/editors/interface/interface_style.c --- blender-2.61/source/blender/editors/interface/interface_style.c 2011-12-13 19:54:27.000000000 +0000 +++ blender-2.62/source/blender/editors/interface/interface_style.c 2012-02-15 19:38:34.000000000 +0000 @@ -180,7 +180,7 @@ if (fs->kerning == 1) BLF_enable(fs->uifont_id, BLF_KERNING_DEFAULT); - BLF_draw(fs->uifont_id, str, 65535); /* XXX, use real length */ + BLF_draw(fs->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX); BLF_disable(fs->uifont_id, BLF_CLIPPING); if (fs->shadow) BLF_disable(fs->uifont_id, BLF_SHADOW); @@ -243,7 +243,7 @@ if (fs->kerning == 1) BLF_enable(fs->uifont_id, BLF_KERNING_DEFAULT); - BLF_draw(fs->uifont_id, str, 65535); /* XXX, use real length */ + BLF_draw(fs->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX); BLF_disable(fs->uifont_id, BLF_ROTATION); BLF_disable(fs->uifont_id, BLF_CLIPPING); if (fs->shadow) @@ -291,7 +291,7 @@ uiStyleFontSet(&style->widget); BLF_position(style->widget.uifont_id, x, y, 0.0f); - BLF_draw(style->widget.uifont_id, str, 65535); /* XXX, use real length */ + BLF_draw(style->widget.uifont_id, str, BLF_DRAW_STR_DUMMY_MAX); if (style->widget.kerning == 1) BLF_disable(style->widget.uifont_id, BLF_KERNING_DEFAULT); diff -Nru blender-2.61/source/blender/editors/interface/interface_templates.c blender-2.62/source/blender/editors/interface/interface_templates.c --- blender-2.61/source/blender/editors/interface/interface_templates.c 2011-12-13 19:54:27.000000000 +0000 +++ blender-2.62/source/blender/editors/interface/interface_templates.c 2012-02-15 19:38:34.000000000 +0000 @@ -55,6 +55,7 @@ #include "BKE_texture.h" #include "BKE_report.h" #include "BKE_displist.h" +#include "BKE_scene.h" #include "ED_screen.h" #include "ED_object.h" @@ -139,7 +140,7 @@ continue; if(BLI_strcasestr(id->name+2, str)) { - char name_ui[32]; + char name_ui[MAX_ID_NAME]; name_uiprefix_id(name_ui, id); iconid= ui_id_icon_get((bContext*)C, id, 1); @@ -180,7 +181,7 @@ /* fake button, it holds space for search items */ uiDefBut(block, LABEL, 0, "", 10, 15, w, h, NULL, 0, 0, 0, 0, NULL); - but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 0, w, 19, template.prv_rows, template.prv_cols, ""); + but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, w, 19, template.prv_rows, template.prv_cols, ""); uiButSetSearchFunc(but, id_search_cb, &template, id_search_call_cb, idptr.data); } /* list view */ @@ -188,7 +189,7 @@ /* fake button, it holds space for search items */ uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL); - but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 0, 150, 19, 0, 0, ""); + but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, 150, 19, 0, 0, ""); uiButSetSearchFunc(but, id_search_cb, &template, id_search_call_cb, idptr.data); } @@ -412,11 +413,11 @@ } if(id->us > 1) { - char str[32]; + char numstr[32]; - BLI_snprintf(str, sizeof(str), "%d", id->us); + BLI_snprintf(numstr, sizeof(numstr), "%d", id->us); - but= uiDefBut(block, BUT, 0, str, 0,0,UI_UNIT_X + ((id->us < 10) ? 0:10), UI_UNIT_Y, NULL, 0, 0, 0, 0, + but= uiDefBut(block, BUT, 0, numstr, 0,0,UI_UNIT_X + ((id->us < 10) ? 0:10), UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Display number of users of this data (click to make a single-user copy)")); uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ALONE)); @@ -681,7 +682,7 @@ static int modifier_can_delete(ModifierData *md) { - // fluid particle modifier can't be deleted here + /* fluid particle modifier can't be deleted here */ if(md->type == eModifierType_ParticleSystem) if(((ParticleSystemModifierData *)md)->psys->part->type == PART_FLUID) return 0; @@ -689,14 +690,16 @@ return 1; } -// Check wheter Modifier is a simulation or not, this is used for switching to the physics/particles context tab +/* Check wheter Modifier is a simulation or not, this is used for switching to the physics/particles context tab */ static int modifier_is_simulation(ModifierData *md) { - // Physic Tab - if(ELEM7(md->type, eModifierType_Cloth, eModifierType_Collision, eModifierType_Fluidsim, eModifierType_Smoke, eModifierType_Softbody, eModifierType_Surface, eModifierType_DynamicPaint)) { + /* Physic Tab */ + if (ELEM7(md->type, eModifierType_Cloth, eModifierType_Collision, eModifierType_Fluidsim, eModifierType_Smoke, + eModifierType_Softbody, eModifierType_Surface, eModifierType_DynamicPaint)) + { return 1; } - // Particle Tab + /* Particle Tab */ else if (md->type == eModifierType_ParticleSystem) { return 2; } @@ -705,7 +708,8 @@ } } -static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob, ModifierData *md, int index, int cageIndex, int lastCageIndex) +static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob, + ModifierData *md, int index, int cageIndex, int lastCageIndex) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); PointerRNA ptr; @@ -845,15 +849,15 @@ uiLayoutSetOperatorContext(row, WM_OP_INVOKE_DEFAULT); uiItemEnumO(row, "OBJECT_OT_modifier_apply", IFACE_("Apply"), 0, "apply_as", MODIFIER_APPLY_DATA); - if (modifier_sameTopology(md)) - uiItemEnumO(row, "OBJECT_OT_modifier_apply", IFACE_("Apply as Shape"), 0, "apply_as", MODIFIER_APPLY_SHAPE); + if (modifier_sameTopology(md) && !modifier_nonGeometrical(md)) + uiItemEnumO(row, "OBJECT_OT_modifier_apply", IFACE_("Apply as Shape Key"), 0, "apply_as", MODIFIER_APPLY_SHAPE); } uiBlockClearButLock(block); uiBlockSetButLock(block, ob && ob->id.lib, ERROR_LIBDATA_MESSAGE); if (!ELEM5(md->type, eModifierType_Fluidsim, eModifierType_Softbody, eModifierType_ParticleSystem, eModifierType_Cloth, eModifierType_Smoke)) - uiItemO(row, TIP_("Copy"), ICON_NONE, "OBJECT_OT_modifier_copy"); + uiItemO(row, IFACE_("Copy"), ICON_NONE, "OBJECT_OT_modifier_copy"); } /* result is the layout block inside the box, that we return so that modifier settings can be drawn */ @@ -1301,6 +1305,16 @@ rna_update_cb(C, cb_v, NULL); } +static void colorband_update_cb(bContext *UNUSED(C), void *bt_v, void *coba_v) +{ + uiBut *bt= bt_v; + ColorBand *coba= coba_v; + + /* sneaky update here, we need to sort the colorband points to be in order, + however the RNA pointer then is wrong, so we update it */ + colorband_update_sort(coba); + bt->rnapoin.data = coba->data + coba->cur; +} /* offset aligns from bottom, standard width 300, height 115 */ static void colorband_buttons_large(uiLayout *layout, uiBlock *block, ColorBand *coba, int xoffs, int yoffs, RNAUpdateCb *cb) @@ -1344,7 +1358,11 @@ PointerRNA ptr; RNA_pointer_create(cb->ptr.id.data, &RNA_ColorRampElement, cbd, &ptr); row= uiLayoutRow(layout, 0); + uiItemR(row, &ptr, "position", 0, "Pos", ICON_NONE); + bt= block->buttons.last; + uiButSetFunc(bt, colorband_update_cb, bt, coba); + uiItemR(row, &ptr, "color", 0, "", ICON_NONE); } @@ -1617,7 +1635,7 @@ uiBut *bt; float width= 8*UI_UNIT_X; - block= uiBeginBlock(C, ar, "curvemap_clipping_func", UI_EMBOSS); + block = uiBeginBlock(C, ar, __func__, UI_EMBOSS); /* use this for a fake extra empy space around the buttons */ uiDefBut(block, LABEL, 0, "", -4, 16, width+8, 6*UI_UNIT_Y, NULL, 0, 0, 0, 0, ""); @@ -1676,7 +1694,7 @@ uiBlock *block; short yco= 0, menuwidth=10*UI_UNIT_X; - block= uiBeginBlock(C, ar, "curvemap_tools_func", UI_EMBOSS); + block= uiBeginBlock(C, ar, __func__, UI_EMBOSS); uiBlockSetButmFunc(block, curvemap_tools_dofunc, cumap_v); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Reset View"), 0, yco-=UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 1, ""); @@ -1698,7 +1716,7 @@ uiBlock *block; short yco= 0, menuwidth=10*UI_UNIT_X; - block= uiBeginBlock(C, ar, "curvemap_tools_func", UI_EMBOSS); + block= uiBeginBlock(C, ar, __func__, UI_EMBOSS); uiBlockSetButmFunc(block, curvemap_tools_dofunc, cumap_v); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Reset View"), 0, yco-=UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 1, ""); @@ -1953,10 +1971,10 @@ tot= RNA_property_array_length(&but->rnapoin, but->rnaprop); /* Normally clicking only selects one layer */ - RNA_property_boolean_set_index(&but->rnapoin, but->rnaprop, cur, 1); + RNA_property_boolean_set_index(&but->rnapoin, but->rnaprop, cur, TRUE); for(i = 0; i < tot; ++i) { if(i != cur) - RNA_property_boolean_set_index(&but->rnapoin, but->rnaprop, i, 0); + RNA_property_boolean_set_index(&but->rnapoin, but->rnaprop, i, FALSE); } } @@ -2122,6 +2140,7 @@ else if(RNA_struct_is_a(itemptr->type, &RNA_MaterialSlot)) { /* provision to draw active node name */ Material *ma, *manode; + Scene *scene= CTX_data_scene(C); Object *ob= (Object*)ptr->id.data; int index= (Material**)itemptr->data - ob->mat; @@ -2129,7 +2148,7 @@ uiItemL(sub, name, icon); ma= give_current_material(ob, index+1); - if(ma) { + if (ma && !scene_use_new_shading_nodes(scene)){ manode= give_node_material(ma); if(manode) { char str[MAX_ID_NAME + 12]; @@ -2145,7 +2164,7 @@ Object *ob= (Object*)activeptr->data; Key *key= (Key*)itemptr->id.data; - split= uiLayoutSplit(sub, 0.75f, 0); + split= uiLayoutSplit(sub, 0.66f, 0); uiItemL(split, name, icon); @@ -2153,10 +2172,13 @@ row= uiLayoutRow(split, 1); if(i == 0 || (key->type != KEY_RELATIVE)) uiItemL(row, "", ICON_NONE); else uiItemR(row, itemptr, "value", 0, "", ICON_NONE); + uiItemR(row, itemptr, "mute", 0, "", 0); - if(ob->mode == OB_MODE_EDIT && !((ob->shapeflag & OB_SHAPE_EDIT_MODE) && ob->type == OB_MESH)) + if( (key->flag & KEYBLOCK_MUTE) || + (ob->mode == OB_MODE_EDIT && !((ob->shapeflag & OB_SHAPE_EDIT_MODE) && ob->type == OB_MESH)) ) + { uiLayoutSetActive(row, 0); - //uiItemR(row, itemptr, "mute", 0, "", ICON_MUTE_IPO_OFF); + } uiBlockSetEmboss(block, UI_EMBOSS); } else if(itemptr->type == &RNA_VertexGroup) { @@ -2198,6 +2220,17 @@ } uiDefButR(block, OPTION, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, itemptr, "is_active", i, 0, 0, 0, 0, NULL); } + else if(itemptr->type == &RNA_MovieTrackingObject) { + MovieTrackingObject *tracking_object= (MovieTrackingObject*)itemptr->data; + + split= uiLayoutSplit(sub, 0.75f, 0); + if(tracking_object->flag&TRACKING_OBJECT_CAMERA) { + uiItemL(split, name, ICON_CAMERA_DATA); + } + else { + uiItemL(split, name, ICON_OBJECT_DATA); + } + } /* There is a last chance to display custom controls (in addition to the name/label): * If the given item property group features a string property named as prop_list, @@ -2251,8 +2284,9 @@ uiItemL(sub, name, icon); /* fails, backdrop LISTROW... */ /* free name */ - if(namebuf) + if (namebuf) { MEM_freeN(namebuf); + } } void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, PointerRNA *activeptr, const char *activepropname, const char *prop_list, int rows, int maxrows, int listtype) @@ -2265,7 +2299,8 @@ uiBlock *block; uiBut *but; Panel *pa; - char *name, str[32]; + const char *name; + char numstr[32]; int rnaicon=0, icon=0, i= 0, activei= 0, len= 0, items, found, min, max; /* validate arguments */ @@ -2355,8 +2390,9 @@ icon= list_item_icon_get(C, &itemptr, rnaicon, 0); uiItemL(row, (name)? name: "", icon); - if(name) - MEM_freeN(name); + if (name) { + MEM_freeN((void *)name); + } } i++; @@ -2369,8 +2405,8 @@ uiItemL(row, "", ICON_NONE); /* next/prev button */ - BLI_snprintf(str, sizeof(str), "%d :", i); - but= uiDefIconTextButR_prop(block, NUM, 0, 0, str, 0,0,UI_UNIT_X*5,UI_UNIT_Y, activeptr, activeprop, 0, 0, 0, 0, 0, ""); + BLI_snprintf(numstr, sizeof(numstr), "%d :", i); + but= uiDefIconTextButR_prop(block, NUM, 0, 0, numstr, 0,0,UI_UNIT_X*5,UI_UNIT_Y, activeptr, activeprop, 0, 0, 0, 0, 0, ""); if(i == 0) uiButSetFlag(but, UI_BUT_DISABLED); } @@ -2454,12 +2490,15 @@ int len= strlen(ot->name); /* display name for menu, can hold hotkey */ - BLI_strncpy(name, ot->name, 256); + BLI_strncpy(name, ot->name, sizeof(name)); /* check for hotkey */ - if(len < 256-6) { - if(WM_key_event_operator_string(C, ot->idname, WM_OP_EXEC_DEFAULT, NULL, TRUE, &name[len+1], 256-len-1)) + if(len < sizeof(name)-6) { + if (WM_key_event_operator_string(C, ot->idname, WM_OP_EXEC_DEFAULT, NULL, TRUE, + &name[len+1], sizeof(name)-len-1)) + { name[len]= '|'; + } } if(0==uiSearchItemAdd(items, name, ot, 0)) @@ -2606,9 +2645,7 @@ uiBlockBeginAlign(block); but= uiDefBut(block, ROUNDBOX, 0, "", 0, 0, UI_UNIT_X+10, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, ""); /* set the report's bg color in but->col - ROUNDBOX feature */ - but->col[0]= FTOCHAR(rti->col[0]); - but->col[1]= FTOCHAR(rti->col[1]); - but->col[2]= FTOCHAR(rti->col[2]); + rgb_float_to_uchar(but->col, rti->col); but->col[3]= 255; but= uiDefBut(block, ROUNDBOX, 0, "", UI_UNIT_X+10, 0, UI_UNIT_X+width, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, ""); diff -Nru blender-2.61/source/blender/editors/interface/interface_widgets.c blender-2.62/source/blender/editors/interface/interface_widgets.c --- blender-2.61/source/blender/editors/interface/interface_widgets.c 2011-12-13 19:54:27.000000000 +0000 +++ blender-2.62/source/blender/editors/interface/interface_widgets.c 2012-02-15 19:38:34.000000000 +0000 @@ -130,9 +130,12 @@ static float cornervec[WIDGET_CURVE_RESOLU][2]= {{0.0, 0.0}, {0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293}, {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}, {1.0, 1.0}}; -static float jit[8][2]= {{0.468813 , -0.481430}, {-0.155755 , -0.352820}, -{0.219306 , -0.238501}, {-0.393286 , -0.110949}, {-0.024699 , 0.013908}, -{0.343805 , 0.147431}, {-0.272855 , 0.269918}, {0.095909 , 0.388710}}; +#define WIDGET_AA_JITTER 8 +static float jit[WIDGET_AA_JITTER][2]= { + { 0.468813 , -0.481430}, {-0.155755 , -0.352820}, + { 0.219306 , -0.238501}, {-0.393286 , -0.110949}, + {-0.024699 , 0.013908}, { 0.343805 , 0.147431}, + {-0.272855 , 0.269918}, { 0.095909 , 0.388710}}; static float num_tria_vert[3][2]= { {-0.352077, 0.532607}, {-0.352077, -0.549313}, {0.330000, -0.008353}}; @@ -165,14 +168,14 @@ GLubyte checker_stipple_sml[32*32/8] = { - 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \ - 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \ - 0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \ - 0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \ - 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \ - 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \ - 0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \ - 0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \ + 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, + 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, + 0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, + 0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, + 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, + 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, + 0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, + 0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, }; /* ************************************************* */ @@ -192,7 +195,7 @@ glVertexPointer(2, GL_FLOAT, 0, tri_arr); /* for each AA step */ - for(j=0; j<8; j++) { + for (j = 0; j < WIDGET_AA_JITTER; j++) { glTranslatef(1.0f * jit[j][0], 1.0f * jit[j][1], 0.0f); glDrawArrays(GL_TRIANGLES, 0, 3); glTranslatef(-1.0f * jit[j][0], -1.0f * jit[j][1], 0.0f); @@ -200,7 +203,25 @@ glDisableClientState(GL_VERTEX_ARRAY); glDisable(GL_BLEND); +} + +void ui_draw_anti_roundbox(int mode, float minx, float miny, float maxx, float maxy, float rad) +{ + float color[4]; + int j; + + glEnable(GL_BLEND); + glGetFloatv(GL_CURRENT_COLOR, color); + color[3] *= 0.125f; + glColor4fv(color); + for (j = 0; j < WIDGET_AA_JITTER; j++) { + glTranslatef(1.0f * jit[j][0], 1.0f * jit[j][1], 0.0f); + uiDrawBox(mode, minx, miny, maxx, maxy, rad); + glTranslatef(-1.0f * jit[j][0], -1.0f * jit[j][1], 0.0f); + } + + glDisable(GL_BLEND); } static void widget_init(uiWidgetBase *wtb) @@ -731,6 +752,11 @@ float quad_strip[WIDGET_SIZE_MAX*2+2][2]; /* + 2 because the last pair is wrapped */ float quad_strip_emboss[WIDGET_SIZE_MAX*2][2]; /* only for emboss */ + const unsigned char tcol[4] = {wcol->outline[0], + wcol->outline[1], + wcol->outline[2], + UCHAR_MAX / WIDGET_AA_JITTER}; + widget_verts_to_quad_strip(wtb, wtb->totvert, quad_strip); if(wtb->emboss) { @@ -739,11 +765,11 @@ glEnableClientState(GL_VERTEX_ARRAY); - for(j=0; j<8; j++) { + for (j = 0; j < WIDGET_AA_JITTER; j++) { glTranslatef(1.0f * jit[j][0], 1.0f * jit[j][1], 0.0f); /* outline */ - glColor4ub(wcol->outline[0], wcol->outline[1], wcol->outline[2], 32); + glColor4ubv(tcol); glVertexPointer(2, GL_FLOAT, 0, quad_strip); glDrawArrays(GL_QUAD_STRIP, 0, wtb->totvert*2 + 2); @@ -764,16 +790,20 @@ /* decoration */ if(wtb->tria1.tot || wtb->tria2.tot) { + const unsigned char tcol[4] = {wcol->item[0], + wcol->item[1], + wcol->item[2], + (unsigned char)((float)wcol->item[3] / WIDGET_AA_JITTER)}; /* for each AA step */ - for(j=0; j<8; j++) { + for (j = 0; j < WIDGET_AA_JITTER; j++) { glTranslatef(1.0f * jit[j][0], 1.0f * jit[j][1], 0.0f); if(wtb->tria1.tot) { - glColor4ub(wcol->item[0], wcol->item[1], wcol->item[2], 32); + glColor4ubv(tcol); widget_trias_draw(&wtb->tria1); } if(wtb->tria2.tot) { - glColor4ub(wcol->item[0], wcol->item[1], wcol->item[2], 32); + glColor4ubv(tcol); widget_trias_draw(&wtb->tria2); } @@ -922,6 +952,9 @@ if(but->editstr && but->pos >= 0) { if(but->ofs > but->pos) but->ofs= but->pos; + + if(BLF_width(fstyle->uifont_id, but->drawstr) <= okwidth) + but->ofs = 0; } else but->ofs= 0; @@ -1777,7 +1810,7 @@ { /* gouraud triangle fan */ float radstep, ang= 0.0f; - float centx, centy, radius; + float centx, centy, radius, cursor_radius; float rgb[3], hsvo[3], hsv[3], col[3], colcent[3]; int a, tot= 32; int color_profile = but->block->color_profile; @@ -1846,18 +1879,18 @@ ang= 2.0f*(float)M_PI*hsvo[0] + 0.5f*(float)M_PI; if(but->flag & UI_BUT_COLOR_CUBIC) - radius= (1.0f - powf(1.0f - hsvo[1], 3.0f)) *radius; + cursor_radius = (1.0f - powf(1.0f - hsvo[1], 3.0f)); else - radius= hsvo[1] * radius; + cursor_radius = hsvo[1]; + radius= CLAMPIS(cursor_radius, 0.0f, 1.0f) * radius; ui_hsv_cursor(centx + cosf(-ang)*radius, centy + sinf(-ang)*radius); - } /* ************ custom buttons, old stuff ************** */ /* draws in resolution of 20x4 colors */ -void ui_draw_gradient(rcti *rect, float *hsv, int type, float alpha) +void ui_draw_gradient(rcti *rect, const float hsv[3], int type, float alpha) { int a; float h= hsv[0], s= hsv[1], v= hsv[2]; @@ -2471,10 +2504,8 @@ if (color_profile) linearrgb_to_srgb_v3_v3(col, col); - wcol->inner[0]= FTOCHAR(col[0]); - wcol->inner[1]= FTOCHAR(col[1]); - wcol->inner[2]= FTOCHAR(col[2]); - wcol->inner[3]= FTOCHAR(col[3]); + rgba_float_to_uchar((unsigned char *)wcol->inner, col); + wcol->shaded = 0; wcol->alpha_check = (wcol->inner[3] < 255); @@ -3246,7 +3277,7 @@ void ui_draw_preview_item(uiFontStyle *fstyle, rcti *rect, const char *name, int iconid, int state) { rcti trect = *rect; - + float font_dims[2] = {0.0f, 0.0f}; uiWidgetType *wt= widget_type(UI_WTYPE_MENU_ITEM); wt->state(wt, state); @@ -3258,10 +3289,12 @@ glColor3ubv((unsigned char*)wt->wcol.text); else glColor3ubv((unsigned char*)wt->wcol.text_sel); - + + BLF_width_and_height(fstyle->uifont_id, name, &font_dims[0], &font_dims[1]); + trect.xmin += 0; - trect.xmax = trect.xmin + BLF_width(fstyle->uifont_id, name) + 10; + trect.xmax = trect.xmin + font_dims[0] + 10; trect.ymin += 10; - trect.ymax = trect.ymin + BLF_height(fstyle->uifont_id, name); + trect.ymax = trect.ymin + font_dims[1]; uiStyleFontDraw(fstyle, &trect, name); } diff -Nru blender-2.61/source/blender/editors/interface/resources.c blender-2.62/source/blender/editors/interface/resources.c --- blender-2.61/source/blender/editors/interface/resources.c 2011-12-13 19:54:27.000000000 +0000 +++ blender-2.62/source/blender/editors/interface/resources.c 2012-02-15 19:38:34.000000000 +0000 @@ -410,6 +410,28 @@ cp= ts->preview_back; break; + case TH_STITCH_PREVIEW_FACE: + cp = ts->preview_stitch_face; + break; + + case TH_STITCH_PREVIEW_EDGE: + cp = ts->preview_stitch_edge; + break; + + case TH_STITCH_PREVIEW_VERT: + cp = ts->preview_stitch_vert; + break; + + case TH_STITCH_PREVIEW_STITCHABLE: + cp = ts->preview_stitch_stitchable; + break; + + case TH_STITCH_PREVIEW_UNSTITCHABLE: + cp = ts->preview_stitch_unstitchable; + break; + case TH_STITCH_PREVIEW_ACTIVE: + cp = ts->preview_stitch_active; + break; case TH_MARKER_OUTLINE: cp= ts->marker_outline; break; case TH_MARKER: @@ -430,6 +452,14 @@ cp= ts->camera_path; break; case TH_LOCK_MARKER: cp= ts->lock_marker; break; + + case TH_MATCH: + cp= ts->match; + break; + + case TH_SELECT_HIGHLIGHT: + cp= ts->selected_highlight; + break; } } } @@ -560,9 +590,9 @@ /* initialize default theme - Note: when you add new colors, created & saved themes need initialized - use function below, init_userdef_do_versions() -*/ + * Note: when you add new colors, created & saved themes need initialized + * use function below, init_userdef_do_versions() + */ void ui_theme_init_default(void) { bTheme *btheme; @@ -583,7 +613,9 @@ /* UI buttons */ ui_widget_color_init(&btheme->tui); btheme->tui.iconfile[0]= 0; - + btheme->tui.panel.show_header = FALSE; + SETCOL(btheme->tui.panel.header, 0, 0, 0, 25); + /* Bone Color Sets */ ui_theme_init_boneColorSets(btheme); @@ -746,6 +778,11 @@ SETCOL(btheme->tima.face_select, 255, 133, 0, 60); SETCOL(btheme->tima.editmesh_active, 255, 255, 255, 128); SETCOLF(btheme->tima.preview_back, 0.45, 0.45, 0.45, 1.0); + SETCOLF(btheme->tima.preview_stitch_face, 0.5, 0.5, 0.0, 0.2); + SETCOLF(btheme->tima.preview_stitch_edge, 1.0, 0.0, 1.0, 0.2); + SETCOLF(btheme->tima.preview_stitch_vert, 0.0, 0.0, 1.0, 0.2); + SETCOLF(btheme->tima.preview_stitch_stitchable, 0.0, 1.0, 0.0, 1.0); + SETCOLF(btheme->tima.preview_stitch_unstitchable, 1.0, 0.0, 0.0, 1.0); /* space text */ btheme->text= btheme->tv3d; @@ -765,6 +802,9 @@ btheme->toops= btheme->tv3d; SETCOLF(btheme->toops.back, 0.45, 0.45, 0.45, 1.0); + SETCOLF(btheme->toops.match, 0.2, 0.5, 0.2, 0.3); /* highlighting search match - soft green*/ + SETCOLF(btheme->toops.selected_highlight, 0.51, 0.53, 0.55, 0.3); + /* space info */ btheme->tinfo= btheme->tv3d; SETCOLF(btheme->tinfo.back, 0.45, 0.45, 0.45, 1.0); @@ -1669,15 +1709,32 @@ BLI_addtail(&U.addons, baddon); } } - + if (bmain->versionfile < 260 || (bmain->versionfile == 260 && bmain->subversionfile < 5)) { bTheme *btheme; - + for(btheme= U.themes.first; btheme; btheme= btheme->next) { SETCOL(btheme->tui.panel.header, 0, 0, 0, 25); btheme->tui.icon_alpha= 1.0; } } + + if (bmain->versionfile < 261 || (bmain->versionfile == 261 && bmain->subversionfile < 4)) { + bTheme *btheme; + for(btheme= U.themes.first; btheme; btheme= btheme->next) { + SETCOLF(btheme->tima.preview_stitch_face, 0.071, 0.259, 0.694, 0.150); + SETCOLF(btheme->tima.preview_stitch_edge, 1.0, 0.522, 0.0, 0.7); + SETCOLF(btheme->tima.preview_stitch_vert, 1.0, 0.522, 0.0, 0.5); + SETCOLF(btheme->tima.preview_stitch_stitchable, 0.0, 1.0, 0.0, 1.0); + SETCOLF(btheme->tima.preview_stitch_unstitchable, 1.0, 0.0, 0.0, 1.0); + SETCOLF(btheme->tima.preview_stitch_active, 0.886, 0.824, 0.765, 0.140); + + SETCOLF(btheme->toops.match, 0.2, 0.5, 0.2, 0.3); + SETCOLF(btheme->toops.selected_highlight, 0.51, 0.53, 0.55, 0.3); + } + + U.use_16bit_textures = 1; + } /* GL Texture Garbage Collection (variable abused above!) */ if (U.textimeout == 0) { diff -Nru blender-2.61/source/blender/editors/interface/view2d.c blender-2.62/source/blender/editors/interface/view2d.c --- blender-2.61/source/blender/editors/interface/view2d.c 2011-12-13 19:54:27.000000000 +0000 +++ blender-2.62/source/blender/editors/interface/view2d.c 2012-02-15 19:38:34.000000000 +0000 @@ -177,7 +177,8 @@ /* see eView2D_CommonViewTypes in UI_view2d.h for available view presets */ switch (type) { - /* 'standard view' - optimum setup for 'standard' view behaviour, that should be used new views as basis for their + /* 'standard view' - optimum setup for 'standard' view behaviour, + * that should be used new views as basis for their * own unique View2D settings, which should be used instead of this in most cases... */ case V2D_COMMONVIEW_STANDARD: @@ -1338,8 +1339,9 @@ void UI_view2d_grid_free(View2DGrid *grid) { /* only free if there's a grid */ - if (grid) + if (grid) { MEM_freeN(grid); + } } /* *********************************************************************** */ @@ -1506,7 +1508,7 @@ static void scroll_printstr(Scene *scene, float x, float y, float val, int power, short unit, char dir) { int len; - char str[32]; + char timecode_str[32]; /* adjust the scale unit to work ok */ if (dir == 'v') { @@ -1521,10 +1523,10 @@ } /* get string to print */ - ANIM_timecode_string_from_frame(str, scene, power, (unit == V2D_UNIT_SECONDS), val); + ANIM_timecode_string_from_frame(timecode_str, scene, power, (unit == V2D_UNIT_SECONDS), val); /* get length of string, and adjust printing location to fit it into the horizontal scrollbar */ - len= strlen(str); + len= strlen(timecode_str); if (dir == 'h') { /* seconds/timecode display has slightly longer strings... */ if (unit == V2D_UNIT_SECONDS) @@ -1535,12 +1537,12 @@ /* Add degree sympbol to end of string for vertical scrollbar? */ if ((dir == 'v') && (unit == V2D_UNIT_DEGREES)) { - str[len]= 186; - str[len+1]= 0; + timecode_str[len]= 186; + timecode_str[len+1]= 0; } /* draw it */ - BLF_draw_default_ascii(x, y, 0.0f, str, sizeof(str)-1); + BLF_draw_default_ascii(x, y, 0.0f, timecode_str, sizeof(timecode_str)); } /* Draw scrollbars in the given 2d-region */ @@ -1753,7 +1755,9 @@ void UI_view2d_scrollers_free(View2DScrollers *scrollers) { /* need to free grid as well... */ - if (scrollers->grid) MEM_freeN(scrollers->grid); + if (scrollers->grid) { + MEM_freeN(scrollers->grid); + } MEM_freeN(scrollers); } @@ -2092,11 +2096,11 @@ } if(v2s->rect.xmin >= v2s->rect.xmax) - BLF_draw_default((float)v2s->mval[0]+xofs, (float)v2s->mval[1]+yofs, 0.0, str, 65535); + BLF_draw_default((float)v2s->mval[0]+xofs, (float)v2s->mval[1]+yofs, 0.0, str, BLF_DRAW_STR_DUMMY_MAX); else { BLF_clipping_default(v2s->rect.xmin-4, v2s->rect.ymin-4, v2s->rect.xmax+4, v2s->rect.ymax+4); BLF_enable_default(BLF_CLIPPING); - BLF_draw_default(v2s->rect.xmin+xofs, v2s->rect.ymin+yofs, 0.0f, str, 65535); + BLF_draw_default(v2s->rect.xmin+xofs, v2s->rect.ymin+yofs, 0.0f, str, BLF_DRAW_STR_DUMMY_MAX); BLF_disable_default(BLF_CLIPPING); } } diff -Nru blender-2.61/source/blender/editors/interface/view2d_ops.c blender-2.62/source/blender/editors/interface/view2d_ops.c --- blender-2.61/source/blender/editors/interface/view2d_ops.c 2011-12-13 19:54:27.000000000 +0000 +++ blender-2.62/source/blender/editors/interface/view2d_ops.c 2012-02-15 19:38:34.000000000 +0000 @@ -248,20 +248,19 @@ view_pan_apply(op); } break; - + /* XXX - Mode switching isn't implemented. See comments in 36818. + * switch to zoom * case LEFTMOUSE: - /* switch to zoom */ if (event->val==KM_PRESS) { - /* calculate overall delta mouse-movement for redo */ + * calculate overall delta mouse-movement for redo * RNA_int_set(op->ptr, "deltax", (vpd->startx - vpd->lastx)); RNA_int_set(op->ptr, "deltay", (vpd->starty - vpd->lasty)); view_pan_exit(op); WM_cursor_restore(CTX_wm_window(C)); - WM_operator_name_call(C, "VIEW2D_OT_zoom", WM_OP_INVOKE_DEFAULT, NULL); return OPERATOR_FINISHED; - } + }*/ default: if (event->type == vpd->invoke_event || event->type==ESCKEY) { @@ -1208,6 +1207,7 @@ float delta; /* amount moved by mouse on axis of interest */ float scrollbarwidth; /* width of the scrollbar itself, used for page up/down clicks */ + int scrollbar_orig; /* initial location of scrollbar x/y, mouse relative */ int lastx, lasty; /* previous mouse coordinates (in screen coordinates) for determining movement */ } v2dScrollerMove; @@ -1303,15 +1303,16 @@ vsm->v2d= v2d; vsm->ar= ar; vsm->scroller= in_scroller; - + /* store mouse-coordinates, and convert mouse/screen coordinates to region coordinates */ vsm->lastx = event->x; vsm->lasty = event->y; - /* 'zone' depends on where mouse is relative to bubble * - zooming must be allowed on this axis, otherwise, default to pan */ scrollers= UI_view2d_scrollers_calc(C, v2d, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY); + + if (in_scroller == 'h') { /* horizontal scroller - calculate adjustment factor first */ mask_size= (float)(v2d->hor.xmax - v2d->hor.xmin); @@ -1326,6 +1327,7 @@ } vsm->scrollbarwidth = scrollers->hor_max - scrollers->hor_min; + vsm->scrollbar_orig = ((scrollers->hor_max + scrollers->hor_min) / 2) + ar->winrct.xmin; } else { /* vertical scroller - calculate adjustment factor first */ @@ -1341,6 +1343,7 @@ } vsm->scrollbarwidth = scrollers->vert_max - scrollers->vert_min; + vsm->scrollbar_orig = ((scrollers->vert_max + scrollers->vert_min) / 2) + + ar->winrct.ymin; } UI_view2d_scrollers_free(scrollers); @@ -1465,6 +1468,7 @@ break; case LEFTMOUSE: + case MIDDLEMOUSE: if (event->val==KM_RELEASE) { /* single-click was in empty space outside bubble, so scroll by 1 'page' */ if (ELEM(vsm->zone, SCROLLHANDLE_MIN_OUTSIDE, SCROLLHANDLE_MAX_OUTSIDE)) { @@ -1485,6 +1489,7 @@ } } break; + } return OPERATOR_RUNNING_MODAL; @@ -1509,6 +1514,21 @@ scroller_activate_init(C, op, event, in_scroller); vsm= (v2dScrollerMove *)op->customdata; + /* support for quick jump to location - gtk and qt do this on linux */ + if (event->type == MIDDLEMOUSE) { + switch (vsm->scroller) { + case 'h': /* horizontal scroller - so only horizontal movement ('cur' moves opposite to mouse) */ + vsm->delta= (float)(event->x - vsm->scrollbar_orig); + break; + case 'v': /* vertical scroller - so only vertical movement ('cur' moves opposite to mouse) */ + vsm->delta= (float)(event->y - vsm->scrollbar_orig); + break; + } + scroller_activate_apply(C, op); + + vsm->zone= SCROLLHANDLE_BAR; + } + /* check if zoom zones are inappropriate (i.e. zoom widgets not shown), so cannot continue * NOTE: see view2d.c for latest conditions, and keep this in sync with that */ @@ -1669,7 +1689,12 @@ void UI_view2d_keymap(wmKeyConfig *keyconf) { wmKeyMap *keymap= WM_keymap_find(keyconf, "View2D", 0, 0); - + wmKeyMapItem *kmi; + + /* scrollers */ + WM_keymap_add_item(keymap, "VIEW2D_OT_scroller_activate", LEFTMOUSE, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "VIEW2D_OT_scroller_activate", MIDDLEMOUSE, KM_PRESS, 0, 0); + /* pan/scroll */ WM_keymap_add_item(keymap, "VIEW2D_OT_pan", MIDDLEMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "VIEW2D_OT_pan", MIDDLEMOUSE, KM_PRESS, KM_SHIFT, 0); @@ -1714,25 +1739,27 @@ /* borderzoom - drag */ WM_keymap_add_item(keymap, "VIEW2D_OT_zoom_border", BKEY, KM_PRESS, KM_SHIFT, 0); - - /* scrollers */ - WM_keymap_add_item(keymap, "VIEW2D_OT_scroller_activate", LEFTMOUSE, KM_PRESS, 0, 0); /* Alternative keymap for buttons listview */ keymap= WM_keymap_find(keyconf, "View2D Buttons List", 0, 0); + + WM_keymap_add_item(keymap, "VIEW2D_OT_scroller_activate", LEFTMOUSE, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "VIEW2D_OT_scroller_activate", MIDDLEMOUSE, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "VIEW2D_OT_pan", MIDDLEMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "VIEW2D_OT_pan", MOUSEPAN, 0, 0, 0); WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_down", WHEELDOWNMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_up", WHEELUPMOUSE, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_down", PAGEDOWNKEY, KM_PRESS, 0, 0)->ptr, "page", 1); - RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_up", PAGEUPKEY, KM_PRESS, 0, 0)->ptr, "page", 1); + kmi = WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_down", PAGEDOWNKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "page", TRUE); + kmi = WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_up", PAGEUPKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "page", TRUE); WM_keymap_add_item(keymap, "VIEW2D_OT_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "VIEW2D_OT_zoom", MOUSEZOOM, 0, 0, 0); WM_keymap_add_item(keymap, "VIEW2D_OT_zoom_out", PADMINUS, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "VIEW2D_OT_zoom_in", PADPLUSKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "VIEW2D_OT_reset", HOMEKEY, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "VIEW2D_OT_scroller_activate", LEFTMOUSE, KM_PRESS, 0, 0); } diff -Nru blender-2.61/source/blender/editors/mesh/editface.c blender-2.62/source/blender/editors/mesh/editface.c --- blender-2.61/source/blender/editors/mesh/editface.c 2011-12-13 19:52:57.000000000 +0000 +++ blender-2.62/source/blender/editors/mesh/editface.c 2012-02-15 19:37:25.000000000 +0000 @@ -815,3 +815,241 @@ return OPERATOR_FINISHED; } + + +/* ********************* MESH VERTEX MIRR TOPO LOOKUP *************** */ +/* note, this is not the best place for the function to be but moved + * here to for the purpose of syncing with bmesh */ + +typedef int MirrTopoHash_t; + +typedef struct MirrTopoVert_t { + MirrTopoHash_t hash; + int v_index; +} MirrTopoVert_t; + +static int mirrtopo_hash_sort(const void *l1, const void *l2) +{ + if ((MirrTopoHash_t)(intptr_t)l1 > (MirrTopoHash_t)(intptr_t)l2 ) return 1; + else if ((MirrTopoHash_t)(intptr_t)l1 < (MirrTopoHash_t)(intptr_t)l2 ) return -1; + return 0; +} + +static int mirrtopo_vert_sort(const void *v1, const void *v2) +{ + if (((MirrTopoVert_t *)v1)->hash > ((MirrTopoVert_t *)v2)->hash ) return 1; + else if (((MirrTopoVert_t *)v1)->hash < ((MirrTopoVert_t *)v2)->hash ) return -1; + return 0; +} + +int ED_mesh_mirrtopo_recalc_check(Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_topo_store) +{ + int totvert; + int totedge; + + if (me->edit_mesh) { + totvert = me->edit_mesh->totvert; + totedge = me->edit_mesh->totedge; + } + else { + totvert = me->totvert; + totedge = me->totedge; + } + + if( (mesh_topo_store->index_lookup==NULL) || + (mesh_topo_store->prev_ob_mode != ob_mode) || + (totvert != mesh_topo_store->prev_vert_tot) || + (totedge != mesh_topo_store->prev_edge_tot)) + { + return TRUE; + } + else { + return FALSE; + } + +} + +void ED_mesh_mirrtopo_init(Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_topo_store, + const short skip_em_vert_array_init) +{ + MEdge *medge; + EditMesh *em = me->edit_mesh; + void **eve_tmp_back = NULL; /* some of the callers are using eve->tmp so restore after */ + + /* editmode*/ + EditEdge *eed; + + int a, last; + int totvert, totedge; + int tot_unique = -1, tot_unique_prev = -1; + + MirrTopoHash_t *topo_hash = NULL; + MirrTopoHash_t *topo_hash_prev = NULL; + MirrTopoVert_t *topo_pairs; + + intptr_t *index_lookup; /* direct access to mesh_topo_store->index_lookup */ + + /* reallocate if needed */ + ED_mesh_mirrtopo_free(mesh_topo_store); + + mesh_topo_store->prev_ob_mode = ob_mode; + + if(em) { + EditVert *eve; + totvert = 0; + eve_tmp_back = MEM_mallocN(em->totvert * sizeof(void *), "TopoMirr"); + for(eve = em->verts.first; eve; eve = eve->next) { + eve_tmp_back[totvert]= eve->tmp.p; + eve->tmp.l = totvert++; + } + } + else { + totvert = me->totvert; + } + + topo_hash = MEM_callocN(totvert * sizeof(MirrTopoHash_t), "TopoMirr"); + + /* Initialize the vert-edge-user counts used to detect unique topology */ + if(em) { + totedge = 0; + + for(eed=em->edges.first; eed; eed = eed->next, totedge++) { + topo_hash[eed->v1->tmp.l]++; + topo_hash[eed->v2->tmp.l]++; + } + } + else { + totedge = me->totedge; + + for(a=0, medge=me->medge; a < me->totedge; a++, medge++) { + topo_hash[medge->v1]++; + topo_hash[medge->v2]++; + } + } + + topo_hash_prev = MEM_dupallocN(topo_hash); + + tot_unique_prev = -1; + while(1) { + /* use the number of edges per vert to give verts unique topology IDs */ + + if(em) { + for(eed=em->edges.first; eed; eed = eed->next) { + topo_hash[eed->v1->tmp.l] += topo_hash_prev[eed->v2->tmp.l]; + topo_hash[eed->v2->tmp.l] += topo_hash_prev[eed->v1->tmp.l]; + } + } + else { + for(a=0, medge=me->medge; atotedge; a++, medge++) { + /* This can make really big numbers, wrapping around here is fine */ + topo_hash[medge->v1] += topo_hash_prev[medge->v2]; + topo_hash[medge->v2] += topo_hash_prev[medge->v1]; + } + } + memcpy(topo_hash_prev, topo_hash, sizeof(MirrTopoHash_t) * totvert); + + /* sort so we can count unique values */ + qsort(topo_hash_prev, totvert, sizeof(MirrTopoHash_t), mirrtopo_hash_sort); + + tot_unique = 1; /* account for skiping the first value */ + for(a=1; atmp.* */ + if(eve_tmp_back) { + EditVert *eve; + totvert = 0; + for(eve = em->verts.first; eve; eve = eve->next) { + eve->tmp.p = eve_tmp_back[totvert++]; + } + + MEM_freeN(eve_tmp_back); + eve_tmp_back = NULL; + } + + + /* Hash/Index pairs are needed for sorting to find index pairs */ + topo_pairs = MEM_callocN( sizeof(MirrTopoVert_t) * totvert, "MirrTopoPairs"); + + /* since we are looping through verts, initialize these values here too */ + index_lookup = MEM_mallocN(totvert * sizeof(*index_lookup), "mesh_topo_lookup"); + + if(em) { + if (skip_em_vert_array_init == FALSE) { + EM_init_index_arrays(em, 1, 0, 0); + } + } + + + for(a=0; a= 2) && (topo_pairs[0].hash == topo_pairs[1].hash)) ? 0 : 1; + + /* Get the pairs out of the sorted hashes, note, totvert+1 means we can use the previous 2, + * but you cant ever access the last 'a' index of MirrTopoPairs */ + for(a=2; a <= totvert; a++) { + /* printf("I %d %ld %d\n", (a-last), MirrTopoPairs[a ].hash, MirrTopoPairs[a ].vIndex ); */ + if ((a==totvert) || (topo_pairs[a-1].hash != topo_pairs[a].hash)) { + if (a-last==2) { + if(em) { + index_lookup[topo_pairs[a-1].v_index] = (intptr_t)EM_get_vert_for_index(topo_pairs[a-2].v_index); + index_lookup[topo_pairs[a-2].v_index] = (intptr_t)EM_get_vert_for_index(topo_pairs[a-1].v_index); + } + else { + index_lookup[topo_pairs[a-1].v_index] = topo_pairs[a-2].v_index; + index_lookup[topo_pairs[a-2].v_index] = topo_pairs[a-1].v_index; + } + } + last = a; + } + } + if(em) { + if (skip_em_vert_array_init == FALSE) { + EM_free_index_arrays(); + } + } + + MEM_freeN(topo_pairs); + topo_pairs = NULL; + + MEM_freeN(topo_hash); + MEM_freeN(topo_hash_prev); + + mesh_topo_store->index_lookup = index_lookup; + mesh_topo_store->prev_vert_tot = totvert; + mesh_topo_store->prev_edge_tot = totedge; +} + +void ED_mesh_mirrtopo_free(MirrTopoStore_t *mesh_topo_store) +{ + if (mesh_topo_store->index_lookup) { + MEM_freeN(mesh_topo_store->index_lookup); + } + mesh_topo_store->index_lookup = NULL; + mesh_topo_store->prev_vert_tot = -1; + mesh_topo_store->prev_edge_tot = -1; +} diff -Nru blender-2.61/source/blender/editors/mesh/editmesh_add.c blender-2.62/source/blender/editors/mesh/editmesh_add.c --- blender-2.61/source/blender/editors/mesh/editmesh_add.c 2011-12-13 19:52:57.000000000 +0000 +++ blender-2.62/source/blender/editors/mesh/editmesh_add.c 2012-02-15 19:37:25.000000000 +0000 @@ -1036,6 +1036,7 @@ float phi, phid, vec[3]; float q[4], cmat[3][3], nor[3]= {0.0, 0.0, 0.0}; short a, b; + float len, len2, vec2[3]; EM_clear_flag_all(em, SELECT); @@ -1117,7 +1118,19 @@ rotateflag(em, 2, v1->co, cmat); } - removedoublesflag(em, 4, 0, 0.0001); + /* length of one segment on meridian */ + len= 2*dia*sinf(phid / 2.0f); + + /* length of one segment in shortest parallen */ + vec[0]= dia*sinf(phid); + vec[1]= 0.0; + vec[2]= dia*cosf(phid); + + mul_v3_m3v3(vec2, cmat, vec); + len2= len_v3v3(vec, vec2); + + /* use shortest segment length divided by 3 as merge threshold */ + removedoublesflag(em, 4, 0, MIN2(len, len2) / 3.0f); /* and now do imat */ eve= em->verts.first; diff -Nru blender-2.61/source/blender/editors/mesh/editmesh.c blender-2.62/source/blender/editors/mesh/editmesh.c --- blender-2.61/source/blender/editors/mesh/editmesh.c 2011-12-13 19:52:57.000000000 +0000 +++ blender-2.62/source/blender/editors/mesh/editmesh.c 2012-02-15 19:37:25.000000000 +0000 @@ -564,8 +564,6 @@ em->totvert= em->totedge= em->totface= 0; -// XXX if(em->retopo_paint_data) retopo_free_paint_data(em->retopo_paint_data); - em->retopo_paint_data= NULL; em->act_face = NULL; } @@ -922,7 +920,10 @@ for(a=0; atotselect; a++, mselect++){ /*check if recorded selection is still valid, if so copy into editmesh*/ - if( (mselect->type == EDITVERT && me->mvert[mselect->index].flag & SELECT) || (mselect->type == EDITEDGE && me->medge[mselect->index].flag & SELECT) || (mselect->type == EDITFACE && me->mface[mselect->index].flag & ME_FACE_SEL) ){ + if ( (mselect->type == EDITVERT && me->mvert[mselect->index].flag & SELECT) || + (mselect->type == EDITEDGE && me->medge[mselect->index].flag & SELECT) || + (mselect->type == EDITFACE && me->mface[mselect->index].flag & ME_FACE_SEL) ) + { ese = MEM_callocN(sizeof(EditSelection), "Edit Selection"); ese->type = mselect->type; if(ese->type == EDITVERT) ese->data = EM_get_vert_for_index(mselect->index); else @@ -1626,7 +1627,6 @@ EditSelectionC *selected; int totvert, totedge, totface, totsel; int selectmode, shapenr; - char retopo_mode; CustomData vdata, edata, fdata; } UndoMesh; @@ -1640,7 +1640,6 @@ if(um->edges) MEM_freeN(um->edges); if(um->faces) MEM_freeN(um->faces); if(um->selected) MEM_freeN(um->selected); -// XXX if(um->retopo_paint_data) retopo_free_paint_data(um->retopo_paint_data); CustomData_free(&um->vdata, um->totvert); CustomData_free(&um->edata, um->totedge); CustomData_free(&um->fdata, um->totface); @@ -1741,9 +1740,6 @@ else if(ese->type == EDITFACE) a = esec->index = ((EditFace*)ese->data)->tmp.l; } -// XXX um->retopo_paint_data= retopo_paint_data_copy(em->retopo_paint_data); -// um->retopo_mode= scene->toolsettings->retopo_mode; - return um; } @@ -1849,16 +1845,6 @@ EM_nvertices_selected(em); EM_nedges_selected(em); EM_nfaces_selected(em); - -// XXX retopo_free_paint(); -// em->retopo_paint_data= retopo_paint_data_copy(um->retopo_paint_data); -// scene->toolsettings->retopo_mode= um->retopo_mode; -// if(scene->toolsettings->retopo_mode) { -// XXX if(G.vd->depths) G.vd->depths->damaged= 1; -// retopo_queue_updates(G.vd); -// retopo_paint_view_update(G.vd); -// } - } static void *getEditMesh(bContext *C) diff -Nru blender-2.61/source/blender/editors/mesh/editmesh_lib.c blender-2.62/source/blender/editors/mesh/editmesh_lib.c --- blender-2.61/source/blender/editors/mesh/editmesh_lib.c 2011-12-13 19:52:57.000000000 +0000 +++ blender-2.62/source/blender/editors/mesh/editmesh_lib.c 2012-02-15 19:37:25.000000000 +0000 @@ -1316,7 +1316,7 @@ if (mmd->mirror_ob) { float imtx[4][4]; invert_m4_m4(imtx, mmd->mirror_ob->obmat); - mul_m4_m4m4(mtx, obedit->obmat, imtx); + mult_m4_m4m4(mtx, imtx, obedit->obmat); } for (eed= em->edges.first; eed; eed= eed->next) { @@ -1603,7 +1603,7 @@ if (mmd->mirror_ob) { float imtx[4][4]; invert_m4_m4(imtx, mmd->mirror_ob->obmat); - mul_m4_m4m4(mtx, obedit->obmat, imtx); + mult_m4_m4m4(mtx, imtx, obedit->obmat); } for (eed= em->edges.first; eed; eed= eed->next) { @@ -2322,7 +2322,7 @@ for(a=0, ev=em->verts.first; ev; a++, ev= ev->next) { UvMapVert *newvlist= NULL, *vlist=vmap->vert[a]; UvMapVert *iterv, *v, *lastv, *next; - float *uv, *uv2, uvdiff[2]; + float *uv, *uv2; while(vlist) { v= vlist; @@ -2332,8 +2332,8 @@ efa = EM_get_face_for_index(v->f); tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - uv = tf->uv[v->tfindex]; - + uv = tf->uv[v->tfindex]; + lastv= NULL; iterv= vlist; @@ -2342,8 +2342,6 @@ efa = EM_get_face_for_index(iterv->f); tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); uv2 = tf->uv[iterv->tfindex]; - - sub_v2_v2v2(uvdiff, uv2, uv); if(fabsf(uv[0]-uv2[0]) < limit[0] && fabsf(uv[1]-uv2[1]) < limit[1]) { if(lastv) lastv->next= next; @@ -2353,22 +2351,224 @@ } else lastv=iterv; - iterv= next; } - newvlist->separate = 1; } - vmap->vert[a]= newvlist; } - + + if (do_face_idx_array) EM_free_index_arrays(); - + return vmap; } +/* A specialized vert map used by stitch operator */ +UvElementMap *EM_make_uv_element_map(EditMesh *em, int selected, int do_islands) +{ + EditVert *ev; + EditFace *efa; + + /* vars from original func */ + UvElementMap *vmap; + UvElement *buf; + UvElement *islandbuf; + MTFace *tf; + unsigned int a; + int i,j, totuv, nverts, nislands = 0, islandbufsize = 0; + unsigned int *map; + /* for uv island creation */ + EditFace **stack; + int stacksize = 0; + + /* we need the vert */ + for(ev = em->verts.first, i = 0; ev; ev = ev->next, i++) + ev->tmp.l = i; + + totuv = 0; + + for(efa = em->faces.first; efa; efa = efa->next) + if(!selected || ((!efa->h) && (efa->f & SELECT))) + totuv += (efa->v4)? 4: 3; + + if(totuv == 0) + return NULL; + + vmap = (UvElementMap *)MEM_callocN(sizeof(*vmap), "UvVertElementMap"); + if(!vmap) + return NULL; + + vmap->vert = (UvElement**)MEM_callocN(sizeof(*vmap->vert)*em->totvert, "UvElementVerts"); + buf = vmap->buf = (UvElement*)MEM_callocN(sizeof(*vmap->buf)*totuv, "UvElement"); + + if(!vmap->vert || !vmap->buf) { + EM_free_uv_element_map(vmap); + return NULL; + } + + vmap->totalUVs = totuv; + + for(efa = em->faces.first; efa; a++, efa = efa->next) { + if(!selected || ((!efa->h) && (efa->f & SELECT))) { + nverts = (efa->v4)? 4: 3; + + for(i = 0; itfindex = i; + buf->face = efa; + buf->separate = 0; + buf->island = INVALID_ISLAND; + + buf->next = vmap->vert[(*(&efa->v1 + i))->tmp.l]; + vmap->vert[(*(&efa->v1 + i))->tmp.l] = buf; + + buf++; + } + } + + efa->tmp.l = INVALID_ISLAND; + } + + /* sort individual uvs for each vert */ + for(a = 0, ev = em->verts.first; ev; a++, ev = ev->next) { + UvElement *newvlist = NULL, *vlist = vmap->vert[a]; + UvElement *iterv, *v, *lastv, *next; + float *uv, *uv2; + + while(vlist) { + v= vlist; + vlist= vlist->next; + v->next= newvlist; + newvlist= v; + + efa = v->face; + tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + uv = tf->uv[v->tfindex]; + + lastv= NULL; + iterv= vlist; + + while(iterv) { + next= iterv->next; + efa = iterv->face; + tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + uv2 = tf->uv[iterv->tfindex]; + + if(fabsf(uv[0]-uv2[0]) < STD_UV_CONNECT_LIMIT && fabsf(uv[1]-uv2[1]) < STD_UV_CONNECT_LIMIT) { + if(lastv) lastv->next = next; + else vlist = next; + iterv->next = newvlist; + newvlist = iterv; + } + else + lastv = iterv; + + iterv = next; + } + + newvlist->separate = 1; + } + + vmap->vert[a] = newvlist; + } + + if(do_islands) { + /* at this point, every UvElement in vert points to a UvElement sharing the same vertex. Now we should sort uv's in islands. */ + + /* map holds the map from current vmap->buf to the new, sorted map*/ + map = MEM_mallocN(sizeof(*map)*totuv, "uvelement_remap"); + stack = MEM_mallocN(sizeof(*stack)*em->totface, "uv_island_face_stack"); + islandbuf = MEM_callocN(sizeof(*islandbuf)*totuv, "uvelement_island_buffer"); + + for(i = 0; i < totuv; i++) { + if(vmap->buf[i].island == INVALID_ISLAND) { + vmap->buf[i].island = nislands; + stack[0] = vmap->buf[i].face; + stack[0]->tmp.l = nislands; + stacksize=1; + + while(stacksize > 0) { + efa = stack[--stacksize]; + nverts = efa->v4? 4 : 3; + + for(j = 0; j < nverts; j++) { + UvElement *element, *initelement = vmap->vert[(*(&efa->v1 + j))->tmp.l]; + + for(element = initelement; element; element = element->next) { + if(element->separate) + initelement = element; + + if(element->face == efa) { + /* found the uv corresponding to our face and vertex. Now fill it to the buffer */ + element->island = nislands; + map[element - vmap->buf] = islandbufsize; + islandbuf[islandbufsize].tfindex = element->tfindex; + islandbuf[islandbufsize].face = element->face; + islandbuf[islandbufsize].separate = element->separate; + islandbuf[islandbufsize].island = nislands; + islandbufsize++; + + for(element = initelement; element; element = element->next) { + if(element->separate && element != initelement) + break; + + if(element->face->tmp.l == INVALID_ISLAND) { + stack[stacksize++] = element->face; + element->face->tmp.l = nislands; + } + } + break; + } + } + } + } + + nislands++; + } + } + + /* remap */ + for(i = 0; i < em->totvert; i++) { + /* important since we may do selection only. Some of these may be NULL */ + if(vmap->vert[i]) + vmap->vert[i] = &islandbuf[map[vmap->vert[i] - vmap->buf]]; + } + + vmap->islandIndices = MEM_callocN(sizeof(*vmap->islandIndices)*nislands,"UvVertMap2_island_indices"); + if(!vmap->islandIndices) { + MEM_freeN(islandbuf); + MEM_freeN(stack); + MEM_freeN(map); + EM_free_uv_element_map(vmap); + } + + j = 0; + for(i = 0; i < totuv; i++) { + UvElement *element = vmap->buf[i].next; + if(element == NULL) + islandbuf[map[i]].next = NULL; + else + islandbuf[map[i]].next = &islandbuf[map[element - vmap->buf]]; + + if(islandbuf[i].island != j) { + j++; + vmap->islandIndices[j] = i; + } + } + + MEM_freeN(vmap->buf); + + vmap->buf = islandbuf; + vmap->totalIslands = nislands; + MEM_freeN(stack); + MEM_freeN(map); + } + + return vmap; +} + + UvMapVert *EM_get_uv_map_vert(UvVertMap *vmap, unsigned int v) { return vmap->vert[v]; @@ -2383,6 +2583,16 @@ } } +void EM_free_uv_element_map(UvElementMap *vmap) +{ + if (vmap) { + if (vmap->vert) MEM_freeN(vmap->vert); + if (vmap->buf) MEM_freeN(vmap->buf); + if (vmap->islandIndices) MEM_freeN(vmap->islandIndices); + MEM_freeN(vmap); + } +} + /* poll call for mesh operators requiring a view3d context */ int EM_view3d_poll(bContext *C) { @@ -2412,7 +2622,7 @@ EdgeHash *edge_hash = BLI_edgehash_new(); EdgeHashIterator *edge_iter; int edge_ref_count = 0; - int ed_v1, ed_v2; /* use when getting the key */ + unsigned int ed_v1, ed_v2; /* use when getting the key */ EdgeFaceRef *edge_ref_array = MEM_callocN(em->totedge * sizeof(EdgeFaceRef), "Edge Connectivity"); EdgeFaceRef *edge_ref; float edge_normal[3]; @@ -2426,15 +2636,20 @@ /* This function adds an edge hash if its not there, and adds the face index */ #define NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(EDV1, EDV2); \ - edge_ref = (EdgeFaceRef *)BLI_edgehash_lookup(edge_hash, EDV1, EDV2); \ + { \ + const unsigned int mf_v1 = EDV1; \ + const unsigned int mf_v2 = EDV2; \ + edge_ref = (EdgeFaceRef *)BLI_edgehash_lookup(edge_hash, mf_v1, mf_v2); \ if (!edge_ref) { \ edge_ref = &edge_ref_array[edge_ref_count]; edge_ref_count++; \ - edge_ref->f1=i; \ - edge_ref->f2=-1; \ - BLI_edgehash_insert(edge_hash, EDV1, EDV2, edge_ref); \ - } else { \ - edge_ref->f2=i; \ - } + edge_ref->f1 = i; \ + edge_ref->f2 = -1; \ + BLI_edgehash_insert(edge_hash, mf_v1, mf_v2, edge_ref); \ + } \ + else { \ + edge_ref->f2 = i; \ + } \ + } efa= em->faces.first; @@ -2456,7 +2671,7 @@ for(edge_iter = BLI_edgehashIterator_new(edge_hash); !BLI_edgehashIterator_isDone(edge_iter); BLI_edgehashIterator_step(edge_iter)) { /* Get the edge vert indices, and edge value (the face indices that use it)*/ - BLI_edgehashIterator_getKey(edge_iter, (int*)&ed_v1, (int*)&ed_v2); + BLI_edgehashIterator_getKey(edge_iter, &ed_v1, &ed_v2); edge_ref = BLI_edgehashIterator_getValue(edge_iter); if (edge_ref->f2 != -1) { diff -Nru blender-2.61/source/blender/editors/mesh/editmesh_loop.c blender-2.62/source/blender/editors/mesh/editmesh_loop.c --- blender-2.61/source/blender/editors/mesh/editmesh_loop.c 2011-12-13 19:52:57.000000000 +0000 +++ blender-2.62/source/blender/editors/mesh/editmesh_loop.c 2012-02-15 19:37:25.000000000 +0000 @@ -56,7 +56,6 @@ #include "BKE_context.h" #include "BKE_depsgraph.h" #include "BKE_mesh.h" -#include "BKE_array_mallocn.h" #include "PIL_time.h" @@ -77,329 +76,6 @@ static void error(const char *UNUSED(arg)) {} /* **** XXX ******** */ -#if 0 /* UNUSED 2.5 */ -static void edgering_sel(EditMesh *em, EditEdge *startedge, int select, int previewlines) -{ - EditEdge *eed; - EditFace *efa; - EditVert *v[2][2]; - float co[2][3]; - int looking= 1,i; - - /* in eed->f1 we put the valence (amount of faces in edge) */ - /* in eed->f2 we put tagged flag as correct loop */ - /* in efa->f1 we put tagged flag as correct to select */ - - for(eed= em->edges.first; eed; eed= eed->next) { - eed->f1= 0; - eed->f2= 0; - } - for(efa= em->faces.first; efa; efa= efa->next) { - efa->f1= 0; - if(efa->h==0) { - efa->e1->f1++; - efa->e2->f1++; - efa->e3->f1++; - if(efa->e4) efa->e4->f1++; - } - } - - // tag startedge OK - startedge->f2= 1; - - while(looking) { - looking= 0; - - for(efa= em->faces.first; efa; efa= efa->next) { - if(efa->e4 && efa->f1==0 && efa->h == 0) { // not done quad - if(efa->e1->f1<=2 && efa->e2->f1<=2 && efa->e3->f1<=2 && efa->e4->f1<=2) { // valence ok - - // if edge tagged, select opposing edge and mark face ok - if(efa->e1->f2) { - efa->e3->f2= 1; - efa->f1= 1; - looking= 1; - } - else if(efa->e2->f2) { - efa->e4->f2= 1; - efa->f1= 1; - looking= 1; - } - if(efa->e3->f2) { - efa->e1->f2= 1; - efa->f1= 1; - looking= 1; - } - if(efa->e4->f2) { - efa->e2->f2= 1; - efa->f1= 1; - looking= 1; - } - } - } - } - } - - if(previewlines > 0 && select == 0){ -// XXX persp(PERSP_VIEW); -// XXX glPushMatrix(); -// XXX mymultmatrix(obedit->obmat); - - for(efa= em->faces.first; efa; efa= efa->next) { - if(efa->v4 == NULL) { continue; } - if(efa->h == 0){ - if(efa->e1->f2 == 1){ - if(efa->e1->h == 1 || efa->e3->h == 1 ) - continue; - - v[0][0] = efa->v1; - v[0][1] = efa->v2; - v[1][0] = efa->v4; - v[1][1] = efa->v3; - } else if(efa->e2->f2 == 1){ - if(efa->e2->h == 1 || efa->e4->h == 1) - continue; - v[0][0] = efa->v2; - v[0][1] = efa->v3; - v[1][0] = efa->v1; - v[1][1] = efa->v4; - } else { continue; } - - for(i=1;i<=previewlines;i++){ - co[0][0] = (v[0][1]->co[0] - v[0][0]->co[0])*(i/((float)previewlines+1))+v[0][0]->co[0]; - co[0][1] = (v[0][1]->co[1] - v[0][0]->co[1])*(i/((float)previewlines+1))+v[0][0]->co[1]; - co[0][2] = (v[0][1]->co[2] - v[0][0]->co[2])*(i/((float)previewlines+1))+v[0][0]->co[2]; - - co[1][0] = (v[1][1]->co[0] - v[1][0]->co[0])*(i/((float)previewlines+1))+v[1][0]->co[0]; - co[1][1] = (v[1][1]->co[1] - v[1][0]->co[1])*(i/((float)previewlines+1))+v[1][0]->co[1]; - co[1][2] = (v[1][1]->co[2] - v[1][0]->co[2])*(i/((float)previewlines+1))+v[1][0]->co[2]; - glColor3ub(255, 0, 255); - glBegin(GL_LINES); - glVertex3f(co[0][0],co[0][1],co[0][2]); - glVertex3f(co[1][0],co[1][1],co[1][2]); - glEnd(); - } - } - } - glPopMatrix(); - } else { - - /* (de)select the edges */ - for(eed= em->edges.first; eed; eed= eed->next) { - if(eed->f2) EM_select_edge(eed, select); - } - } -} - -static void CutEdgeloop(Object *obedit, wmOperator *op, EditMesh *em, int numcuts) -{ - ViewContext vc; // XXX - EditEdge *nearest=NULL, *eed; - float fac; - int keys = 0, holdnum=0, selectmode, dist; - int mvalo[2] = {0, 0}, mval[2] = {0, 0}; - short event=0, val, choosing=1, cancel=0, cuthalf = 0, smooth=0; - short hasHidden = 0; - char msg[128]; - - selectmode = em->selectmode; - - if(em->selectmode & SCE_SELECT_FACE){ - em->selectmode = SCE_SELECT_EDGE; - EM_selectmode_set(em); - } - - - BIF_undo_push("Loopcut Begin"); - while(choosing && !cancel){ -// XXX getmouseco_areawin(mval); - if (mval[0] != mvalo[0] || mval[1] != mvalo[1]) { - mvalo[0] = mval[0]; - mvalo[1] = mval[1]; - dist= 50; - nearest = findnearestedge(&vc, &dist); // returns actual distance in dist -// scrarea_do_windraw(curarea); // after findnearestedge, backbuf! - - BLI_snprintf(msg, sizeof(msg),"Number of Cuts: %d (S)mooth: %s", numcuts, smooth ? "on":"off"); - -// headerprint(msg); - /* Need to figure preview */ - if(nearest){ - edgering_sel(em, nearest, 0, numcuts); - } -// XXX screen_swapbuffers(); - - /* backbuffer refresh for non-apples (no aux) */ -#ifndef __APPLE__ -// XXX if(G.vd->drawtype>OB_WIRE && (G.vd->flag & V3D_ZBUF_SELECT)) { -// backdrawview3d(0); -// } -#endif - } - else PIL_sleep_ms(10); // idle - - - while(qtest()) - { - val=0; -// XXX event= extern_qread(&val); - if(val && (event == MOUSEX || event == MOUSEY)){ ; } - else if(val && ((event==LEFTMOUSE || event==RETKEY) || (event == MIDDLEMOUSE || event==PADENTER))) - { - if(event == MIDDLEMOUSE){ - cuthalf = 1; - } - if (nearest==NULL) - cancel = 1; - choosing=0; - mvalo[0] = -1; - } - else if(val && (event==ESCKEY || event==RIGHTMOUSE )) - { - choosing=0; - cancel = 1; - mvalo[0] = -1; - } - else if(val && (event==PADPLUSKEY || event==WHEELUPMOUSE)) - { - numcuts++; - mvalo[0] = -1; - } - else if(val && (event==PADMINUS || event==WHEELDOWNMOUSE)) - { - if(numcuts > 1){ - numcuts--; - mvalo[0] = -1; - } - } - else if(val && event==SKEY) - { - if(smooth){smooth=0;} - else { smooth=1; } - mvalo[0] = -1; - } - - else if(val){ - holdnum = -1; - switch(event){ - case PAD9: - case NINEKEY: - holdnum = 9; break; - case PAD8: - case EIGHTKEY: - holdnum = 8;break; - case PAD7: - case SEVENKEY: - holdnum = 7;break; - case PAD6: - case SIXKEY: - holdnum = 6;break; - case PAD5: - case FIVEKEY: - holdnum = 5;break; - case PAD4: - case FOURKEY: - holdnum = 4;break; - case PAD3: - case THREEKEY: - holdnum = 3; break; - case PAD2: - case TWOKEY: - holdnum = 2;break; - case PAD1: - case ONEKEY: - holdnum = 1; break; - case PAD0: - case ZEROKEY: - holdnum = 0;break; - case BACKSPACEKEY: - holdnum = -2;break; - } - if(holdnum >= 0 && numcuts*10 < 130){ - if(keys == 0){ // first level numeric entry - if(holdnum > 0){ - numcuts = holdnum; - keys++; - } - } else if(keys > 0){//highrt level numeric entry - numcuts *= 10; - numcuts += holdnum; - keys++; - } - } else if (holdnum == -2){// backspace - if (keys > 1){ - numcuts /= 10; - keys--; - } else { - numcuts=1; - keys = 0; - } - } - mvalo[0] = -1; - break; - } // End Numeric Entry - } //End while(qtest()) - } // End Choosing - - if(cancel){ - return; - } - /* clean selection */ - for(eed=em->edges.first; eed; eed = eed->next){ - EM_select_edge(eed,0); - } - /* select edge ring */ - edgering_sel(em, nearest, 1, 0); - - /* now cut the loops */ - if(smooth){ - fac= 1.0f; -// XXX if(fbutton(&fac, 0.0f, 5.0f, 10, 10, "Smooth:")==0) return; - fac= 0.292f*fac; - esubdivideflag(obedit, em, SELECT,fac,0,B_SMOOTH,numcuts, SUBDIV_CORNER_PATH, SUBDIV_SELECT_LOOPCUT); - } else { - esubdivideflag(obedit, em, SELECT,0,0,0,numcuts,SUBDIV_CORNER_PATH, SUBDIV_SELECT_LOOPCUT); - } - /* if this was a single cut, enter edgeslide mode */ - if(numcuts == 1 && hasHidden == 0){ - if(cuthalf) - EdgeSlide(em, op, 1,0.0); - else { - if(EdgeSlide(em, op, 0,0.0) == -1){ - BIF_undo(); - } - } - } - - if(em->selectmode != selectmode){ - em->selectmode = selectmode; - EM_selectmode_set(em); - } - -// DAG_id_tag_update(obedit->data, 0); - return; -} -#endif - -/* *************** LOOP SELECT ************* */ -#if 0 -static short edgeFaces(EditMesh *em, EditEdge *e) -{ - EditFace *search=NULL; - short count = 0; - - search = em->faces.first; - while(search){ - if((search->e1 == e || search->e2 == e) || (search->e3 == e || search->e4 == e)) - count++; - search = search->next; - } - return count; -} -#endif - - - /* ***************** TRAIL ************************ Read a trail of mouse coords and return them as an array of CutCurve structs @@ -612,11 +288,17 @@ /* for amount of edges */ #define MAX_CUT_EDGES 1024 +static int knife_cut_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + ED_view3d_operator_properties_viewmat_set(C, op); + + return WM_gesture_lines_invoke(C, op, event); +} + static int knife_cut_exec(bContext *C, wmOperator *op) { Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data)); - ARegion *ar= CTX_wm_region(C); EditEdge *eed; EditVert *eve; CutCurve curve[MAX_CUT_EDGES]; @@ -626,10 +308,12 @@ int len=0; short numcuts= RNA_int_get(op->ptr, "num_cuts"); short mode= RNA_enum_get(op->ptr, "type"); + int winx, winy; + float persmat[4][4]; // int corner_cut_pattern= RNA_enum_get(op->ptr,"corner_cut_pattern"); /* edit-object needed for matrix, and ar->regiondata for projections to work */ - if (ELEM3(NULL, obedit, ar, ar->regiondata)) + if (obedit == NULL) return OPERATOR_CANCELLED; if (EM_nvertices_selected(em) < 2) { @@ -652,6 +336,8 @@ return OPERATOR_CANCELLED; } + ED_view3d_operator_properties_viewmat_get(op, &winx, &winy, persmat); + /*store percentage of edge cut for KNIFE_EXACT here.*/ for(eed=em->edges.first; eed; eed= eed->next) eed->tmp.fp = 0.0; @@ -663,7 +349,7 @@ VECCOPY(co, eve->co); co[3]= 1.0; mul_m4_v4(obedit->obmat, co); - project_float(ar, co, scr); + apply_project_float(persmat, winx, winy, co, scr); BLI_ghash_insert(gh, eve, scr); eve->f1 = 0; /*store vertex intersection flag here*/ @@ -714,7 +400,7 @@ ot->description= "Cut selected edges and faces into parts"; ot->idname= "MESH_OT_knife_cut"; - ot->invoke= WM_gesture_lines_invoke; + ot->invoke= knife_cut_invoke; ot->modal= WM_gesture_lines_modal; ot->exec= knife_cut_exec; ot->cancel= WM_gesture_lines_cancel; @@ -731,7 +417,10 @@ // doesn't work atm.. RNA_def_enum(ot->srna, "corner_cut_pattern", corner_type_items, SUBDIV_CORNER_INNERVERT, "Corner Cut Pattern", "Topology pattern to use to fill a face after cutting across its corner"); /* internal */ - RNA_def_int(ot->srna, "cursor", BC_KNIFECURSOR, 0, INT_MAX, "Cursor", "", 0, INT_MAX); + prop = RNA_def_int(ot->srna, "cursor", BC_KNIFECURSOR, 0, INT_MAX, "Cursor", "", 0, INT_MAX); + RNA_def_property_flag(prop, PROP_HIDDEN); + + ED_view3d_operator_properties_viewmat(ot); } /* ******************************************************* */ diff -Nru blender-2.61/source/blender/editors/mesh/editmesh_mods.c blender-2.62/source/blender/editors/mesh/editmesh_mods.c --- blender-2.61/source/blender/editors/mesh/editmesh_mods.c 2011-12-13 19:52:57.000000000 +0000 +++ blender-2.62/source/blender/editors/mesh/editmesh_mods.c 2012-02-15 19:37:25.000000000 +0000 @@ -1336,7 +1336,8 @@ } } -int mesh_layers_menu(CustomData *data, int type) { +int mesh_layers_menu(CustomData *data, int type) +{ int ret; char *str_pt, *str; @@ -2455,12 +2456,15 @@ #undef is_face_tag #undef face_tag -static void linked_limit_default(bContext *C, wmOperator *op) { - if(!RNA_property_is_set(op->ptr, "limit")) { +static void linked_limit_default(bContext *C, wmOperator *op) +{ + if(!RNA_struct_property_is_set(op->ptr, "limit")) { Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh(obedit->data); if(em->selectmode == SCE_SELECT_FACE) RNA_boolean_set(op->ptr, "limit", TRUE); + else + RNA_boolean_set(op->ptr, "limit", FALSE); } } @@ -3380,34 +3384,6 @@ // if (EM_texFaceCheck()) } - -static int select_inverse_mesh_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Object *obedit= CTX_data_edit_object(C); - EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data)); - - EM_select_swap(em); - - WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); - - BKE_mesh_end_editmesh(obedit->data, em); - return OPERATOR_FINISHED; -} - -void MESH_OT_select_inverse(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Select Inverse"; - ot->description= "Select inverse of (un)selected vertices, edges or faces"; - ot->idname= "MESH_OT_select_inverse"; - - /* api callbacks */ - ot->exec= select_inverse_mesh_exec; - ot->poll= ED_operator_editmesh; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} /* ******************** (de)select all operator **************** */ diff -Nru blender-2.61/source/blender/editors/mesh/editmesh_tools.c blender-2.62/source/blender/editors/mesh/editmesh_tools.c --- blender-2.61/source/blender/editors/mesh/editmesh_tools.c 2011-12-13 19:52:57.000000000 +0000 +++ blender-2.62/source/blender/editors/mesh/editmesh_tools.c 2012-02-15 19:37:25.000000000 +0000 @@ -3943,808 +3943,6 @@ return 0; } -#if 0 - -typedef struct SlideUv { - float origuv[2]; - float *uv_up, *uv_down; - //float *fuv[4]; - LinkNode *fuv_list; -} SlideUv; - -typedef struct SlideVert { - EditEdge *up,*down; - EditVert origvert; -} SlideVert; - -int EdgeSlide(EditMesh *em, wmOperator *op, short immediate, float imperc) -{ - return 0; -/* XXX REFACTOR - #if 0'd for now, otherwise can't make 64bit windows builds on 64bit machine */ -useless: - goto useless // because it doesn't do anything right now - -// NumInput num; XXX - Mesh *me= NULL; // XXX - EditFace *efa; - EditEdge *eed,*first=NULL,*last=NULL, *temp = NULL; - EditVert *ev, *nearest; - LinkNode *edgelist = NULL, *vertlist=NULL, *look; - GHash *vertgh; - - SlideVert *tempsv; - float perc = 0, percp = 0,vertdist; // XXX, projectMat[4][4]; - float shiftlabda= 0.0f,len = 0.0f; - int i = 0,j, numsel, numadded=0, timesthrough = 0, vertsel=0, prop=1, cancel = 0,flip=0; - int wasshift = 0; - - /* UV correction vars */ - GHash **uvarray= NULL; - int uvlay_tot= CustomData_number_of_layers(&em->fdata, CD_MTFACE); - int uvlay_idx; - SlideUv *slideuvs=NULL, *suv=NULL, *suv_last=NULL; - float uv_tmp[2]; - LinkNode *fuv_link; - - short event, draw=1; - int mval[2], mvalo[2]; - char str[128]; - float labda = 0.0f; - -// initNumInput(&num); - -// view3d_get_object_project_mat(curarea, obedit, projectMat); - - mvalo[0] = -1; mvalo[1] = -1; - numsel =0; - - // Get number of selected edges and clear some flags - for(eed=em->edges.first;eed;eed=eed->next) { - eed->f1 = 0; - eed->f2 = 0; - if(eed->f & SELECT) numsel++; - } - - for(ev=em->verts.first;ev;ev=ev->next) { - ev->f1 = 0; - } - - //Make sure each edge only has 2 faces - // make sure loop doesn't cross face - for(efa=em->faces.first;efa;efa=efa->next) { - int ct = 0; - if(efa->e1->f & SELECT) { - ct++; - efa->e1->f1++; - if(efa->e1->f1 > 2) { - BKE_report(op->reports, RPT_ERROR, "3+ face edge"); - return 0; - } - } - if(efa->e2->f & SELECT) { - ct++; - efa->e2->f1++; - if(efa->e2->f1 > 2) { - BKE_report(op->reports, RPT_ERROR, "3+ face edge"); - return 0; - } - } - if(efa->e3->f & SELECT) { - ct++; - efa->e3->f1++; - if(efa->e3->f1 > 2) { - BKE_report(op->reports, RPT_ERROR, "3+ face edge"); - return 0; - } - } - if(efa->e4 && efa->e4->f & SELECT) { - ct++; - efa->e4->f1++; - if(efa->e4->f1 > 2) { - BKE_report(op->reports, RPT_ERROR, "3+ face edge"); - return 0; - } - } - // Make sure loop is not 2 edges of same face - if(ct > 1) { - BKE_report(op->reports, RPT_ERROR, "Loop crosses itself"); - return 0; - } - } - // Get # of selected verts - for(ev=em->verts.first;ev;ev=ev->next) { - if(ev->f & SELECT) vertsel++; - } - - // Test for multiple segments - if(vertsel > numsel+1) { - BKE_report(op->reports, RPT_ERROR, "Please choose a single edge loop"); - return 0; - } - - // Get the edgeloop in order - mark f1 with SELECT once added - for(eed=em->edges.first;eed;eed=eed->next) { - if((eed->f & SELECT) && !(eed->f1 & SELECT)) { - // If this is the first edge added, just put it in - if(!edgelist) { - BLI_linklist_prepend(&edgelist,eed); - numadded++; - first = eed; - last = eed; - eed->f1 = SELECT; - } else { - if(editedge_getSharedVert(eed, last)) { - BLI_linklist_append(&edgelist,eed); - eed->f1 = SELECT; - numadded++; - last = eed; - } else if(editedge_getSharedVert(eed, first)) { - BLI_linklist_prepend(&edgelist,eed); - eed->f1 = SELECT; - numadded++; - first = eed; - } - } - } - if(eed->next == NULL && numadded != numsel) { - eed=em->edges.first; - timesthrough++; - } - - // It looks like there was an unexpected case - Hopefully should not happen - if(timesthrough >= numsel*2) { - BLI_linklist_free(edgelist,NULL); - BKE_report(op->reports, RPT_ERROR, "Could not order loop"); - return 0; - } - } - - // Put the verts in order in a linklist - look = edgelist; - while(look) { - eed = look->link; - if(!vertlist) { - if(look->next) { - temp = look->next->link; - - //This is the first entry takes care of extra vert - if(eed->v1 != temp->v1 && eed->v1 != temp->v2) { - BLI_linklist_append(&vertlist,eed->v1); - eed->v1->f1 = 1; - } else { - BLI_linklist_append(&vertlist,eed->v2); - eed->v2->f1 = 1; - } - } else { - //This is the case that we only have 1 edge - BLI_linklist_append(&vertlist,eed->v1); - eed->v1->f1 = 1; - } - } - // for all the entries - if(eed->v1->f1 != 1) { - BLI_linklist_append(&vertlist,eed->v1); - eed->v1->f1 = 1; - } else if(eed->v2->f1 != 1) { - BLI_linklist_append(&vertlist,eed->v2); - eed->v2->f1 = 1; - } - look = look->next; - } - - // populate the SlideVerts - - vertgh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "EdgeSlide gh"); - look = vertlist; - while(look) { - i=0; - j=0; - ev = look->link; - tempsv = (struct SlideVert*)MEM_mallocN(sizeof(struct SlideVert),"SlideVert"); - tempsv->up = NULL; - tempsv->down = NULL; - tempsv->origvert.co[0] = ev->co[0]; - tempsv->origvert.co[1] = ev->co[1]; - tempsv->origvert.co[2] = ev->co[2]; - tempsv->origvert.no[0] = ev->no[0]; - tempsv->origvert.no[1] = ev->no[1]; - tempsv->origvert.no[2] = ev->no[2]; - // i is total edges that vert is on - // j is total selected edges that vert is on - - for(eed=em->edges.first;eed;eed=eed->next) { - if(eed->v1 == ev || eed->v2 == ev) { - i++; - if(eed->f & SELECT) { - j++; - } - } - } - // If the vert is in the middle of an edge loop, it touches 2 selected edges and 2 unselected edges - if(i == 4 && j == 2) { - for(eed=em->edges.first;eed;eed=eed->next) { - if(editedge_containsVert(eed, ev)) { - if(!(eed->f & SELECT)) { - if(!tempsv->up) { - tempsv->up = eed; - } else if (!(tempsv->down)) { - tempsv->down = eed; - } - } - } - } - } - // If it is on the end of the loop, it touches 1 selected and as least 2 more unselected - if(i >= 3 && j == 1) { - for(eed=em->edges.first;eed;eed=eed->next) { - if(editedge_containsVert(eed, ev) && eed->f & SELECT) { - for(efa = em->faces.first;efa;efa=efa->next) { - if(editface_containsEdge(efa, eed)) { - if(editedge_containsVert(efa->e1, ev) && efa->e1 != eed) { - if(!tempsv->up) { - tempsv->up = efa->e1; - } else if (!(tempsv->down)) { - tempsv->down = efa->e1; - } - } - if(editedge_containsVert(efa->e2, ev) && efa->e2 != eed) { - if(!tempsv->up) { - tempsv->up = efa->e2; - } else if (!(tempsv->down)) { - tempsv->down = efa->e2; - } - } - if(editedge_containsVert(efa->e3, ev) && efa->e3 != eed) { - if(!tempsv->up) { - tempsv->up = efa->e3; - } else if (!(tempsv->down)) { - tempsv->down = efa->e3; - } - } - if(efa->e4) { - if(editedge_containsVert(efa->e4, ev) && efa->e4 != eed) { - if(!tempsv->up) { - tempsv->up = efa->e4; - } else if (!(tempsv->down)) { - tempsv->down = efa->e4; - } - } - } - - } - } - } - } - } - if(i > 4 && j == 2) { - BLI_ghash_free(vertgh, NULL, (GHashValFreeFP)MEM_freeN); - BLI_linklist_free(vertlist,NULL); - BLI_linklist_free(edgelist,NULL); - return 0; - } - BLI_ghash_insert(vertgh,ev,tempsv); - - look = look->next; - } - - // make sure the UPs nad DOWNs are 'faceloops' - // Also find the nearest slidevert to the cursor -// XXX getmouseco_areawin(mval); - look = vertlist; - nearest = NULL; - vertdist = -1; - while(look) { - tempsv = BLI_ghash_lookup(vertgh,(EditVert*)look->link); - - if(!tempsv->up || !tempsv->down) { - BKE_report(op->reports, RPT_ERROR, "Missing rails"); - BLI_ghash_free(vertgh, NULL, (GHashValFreeFP)MEM_freeN); - BLI_linklist_free(vertlist,NULL); - BLI_linklist_free(edgelist,NULL); - return 0; - } - - if(me->drawflag & ME_DRAWEXTRA_EDGELEN) { - if(!(tempsv->up->f & SELECT)) { - tempsv->up->f |= SELECT; - tempsv->up->f2 |= 16; - } else { - tempsv->up->f2 |= ~16; - } - if(!(tempsv->down->f & SELECT)) { - tempsv->down->f |= SELECT; - tempsv->down->f2 |= 16; - } else { - tempsv->down->f2 |= ~16; - } - } - - if(look->next != NULL) { - SlideVert *sv; - - sv = BLI_ghash_lookup(vertgh,(EditVert*)look->next->link); - - if(sv) { - float tempdist, co[2]; - - if(!sharesFace(em, tempsv->up,sv->up)) { - EditEdge *swap; - swap = sv->up; - sv->up = sv->down; - sv->down = swap; - } - -// view3d_project_float(curarea, tempsv->origvert.co, co, projectMat); - - tempdist = sqrt(pow(co[0] - mval[0],2)+pow(co[1] - mval[1],2)); - - if(vertdist < 0) { - vertdist = tempdist; - nearest = (EditVert*)look->link; - } else if ( tempdist < vertdist ) { - vertdist = tempdist; - nearest = (EditVert*)look->link; - } - } - } - - - - look = look->next; - } - - - if (uvlay_tot) { // XXX && (scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT)) { - int maxnum = 0; - uvarray = MEM_callocN( uvlay_tot * sizeof(GHash *), "SlideUVs Array"); - suv_last = slideuvs = MEM_callocN( uvlay_tot * (numadded+1) * sizeof(SlideUv), "SlideUVs"); /* uvLayers * verts */ - suv = NULL; - - for (uvlay_idx=0; uvlay_idxverts.first;ev;ev=ev->next) { - ev->tmp.l = 0; - } - look = vertlist; - while(look) { - float *uv_new; - tempsv = BLI_ghash_lookup(vertgh,(EditVert*)look->link); - - ev = look->link; - suv = NULL; - for(efa = em->faces.first;efa;efa=efa->next) { - if (ev->tmp.l != -1) { /* test for self, in this case its invalid */ - int k=-1; /* face corner */ - - /* Is this vert in the faces corner? */ - if (efa->v1==ev) k=0; - else if (efa->v2==ev) k=1; - else if (efa->v3==ev) k=2; - else if (efa->v4 && efa->v4==ev) k=3; - - if (k != -1) { - MTFace *tf = CustomData_em_get_n(&em->fdata, efa->data, CD_MTFACE, uvlay_idx); - EditVert *ev_up, *ev_down; - - uv_new = tf->uv[k]; - - if (ev->tmp.l) { - if (fabs(suv->origuv[0]-uv_new[0]) > 0.0001 || fabs(suv->origuv[1]-uv_new[1])) { - ev->tmp.l = -1; /* Tag as invalid */ - BLI_linklist_free(suv->fuv_list,NULL); - suv->fuv_list = NULL; - BLI_ghash_remove(uvarray[uvlay_idx],ev, NULL, NULL); - suv = NULL; - break; - } - } else { - ev->tmp.l = 1; - suv = suv_last; - - suv->fuv_list = NULL; - suv->uv_up = suv->uv_down = NULL; - suv->origuv[0] = uv_new[0]; - suv->origuv[1] = uv_new[1]; - - BLI_linklist_prepend(&suv->fuv_list, uv_new); - BLI_ghash_insert(uvarray[uvlay_idx],ev,suv); - - suv_last++; /* advance to next slide UV */ - maxnum++; - } - - /* Now get the uvs along the up or down edge if we can */ - if (suv) { - if (!suv->uv_up) { - ev_up = editedge_getOtherVert(tempsv->up,ev); - if (efa->v1==ev_up) suv->uv_up = tf->uv[0]; - else if (efa->v2==ev_up) suv->uv_up = tf->uv[1]; - else if (efa->v3==ev_up) suv->uv_up = tf->uv[2]; - else if (efa->v4 && efa->v4==ev_up) suv->uv_up = tf->uv[3]; - } - if (!suv->uv_down) { /* if the first face was apart of the up edge, it cant be apart of the down edge */ - ev_down = editedge_getOtherVert(tempsv->down,ev); - if (efa->v1==ev_down) suv->uv_down = tf->uv[0]; - else if (efa->v2==ev_down) suv->uv_down = tf->uv[1]; - else if (efa->v3==ev_down) suv->uv_down = tf->uv[2]; - else if (efa->v4 && efa->v4==ev_down) suv->uv_down = tf->uv[3]; - } - - /* Copy the pointers to the face UV's */ - BLI_linklist_prepend(&suv->fuv_list, uv_new); - } - } - } - } - look = look->next; - } - } /* end uv map loop */ - } /* end uvlay_tot */ - - - - // we should have enough info now to slide - - len = 0.0f; - - percp = -1; - while(draw) { - /* For the % calculation */ - int mval[2]; - float rc[2]; - float v2[2], v3[2]; - EditVert *centerVert, *upVert, *downVert; - -// XXX getmouseco_areawin(mval); - - if (!immediate && (mval[0] == mvalo[0] && mval[1] == mvalo[1])) { - PIL_sleep_ms(10); - } else { - char *p = str; - int ctrl= 0, shift= 0; // XXX - - mvalo[0] = mval[0]; - mvalo[1] = mval[1]; - - - tempsv = BLI_ghash_lookup(vertgh,nearest); - - centerVert = editedge_getSharedVert(tempsv->up, tempsv->down); - upVert = editedge_getOtherVert(tempsv->up, centerVert); - downVert = editedge_getOtherVert(tempsv->down, centerVert); - -// view3d_project_float(curarea, upVert->co, v2, projectMat); -// view3d_project_float(curarea, downVert->co, v3, projectMat); - - /* Determine the % on which the loop should be cut */ - - rc[0]= v3[0]-v2[0]; - rc[1]= v3[1]-v2[1]; - len= rc[0]*rc[0]+ rc[1]*rc[1]; - if (len==0) {len = 0.0001;} - - if (shift) { - wasshift = 0; - labda= ( rc[0]*((mval[0]-v2[0])) + rc[1]*((mval[1]-v2[1])) )/len; - } - else { - if (wasshift==0) { - wasshift = 1; - shiftlabda = labda; - } - labda= ( rc[0]*((mval[0]-v2[0])) + rc[1]*((mval[1]-v2[1])) )/len / 10.0 + shiftlabda; - } - - - if(labda<=0.0) labda=0.0; - else if(labda>=1.0)labda=1.0; - - perc=((1-labda)*2)-1; - - if(shift == 0 && ctrl==0) { - perc *= 100; - perc = floor(perc); - perc /= 100; - } else if (ctrl) { - perc *= 10; - perc = floor(perc); - perc /= 10; - } - - if(prop == 0) { - len = len_v3v3(upVert->co,downVert->co)*((perc+1)/2); - if(flip == 1) { - len = len_v3v3(upVert->co,downVert->co) - len; - } - } - - if (0) // XXX hasNumInput(&num)) - { -// XXX applyNumInput(&num, &perc); - - if (prop) - { - perc = MIN2(perc, 1); - perc = MAX2(perc, -1); - } - else - { - len = MIN2(perc, len_v3v3(upVert->co,downVert->co)); - len = MAX2(len, 0); - } - } - - //Adjust Edgeloop - if(immediate) { - perc = imperc; - } - percp = perc; - if(prop) { - look = vertlist; - while(look) { - EditVert *tempev; - ev = look->link; - tempsv = BLI_ghash_lookup(vertgh,ev); - - tempev = editedge_getOtherVert((perc>=0)?tempsv->up:tempsv->down, ev); - interp_v3_v3v3(ev->co, tempsv->origvert.co, tempev->co, fabs(perc)); - - if (0) { // XXX scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) { - for (uvlay_idx=0; uvlay_idxfuv_list && suv->uv_up && suv->uv_down) { - interp_v2_v2v2(uv_tmp, suv->origuv, (perc>=0)?suv->uv_up:suv->uv_down, fabs(perc)); - fuv_link = suv->fuv_list; - while (fuv_link) { - VECCOPY2D(((float *)fuv_link->link), uv_tmp); - fuv_link = fuv_link->next; - } - } - } - } - - look = look->next; - } - } - else { - //Non prop code - look = vertlist; - while(look) { - float newlen; - ev = look->link; - tempsv = BLI_ghash_lookup(vertgh,ev); - newlen = (len / len_v3v3(editedge_getOtherVert(tempsv->up,ev)->co,editedge_getOtherVert(tempsv->down,ev)->co)); - if(newlen > 1.0) {newlen = 1.0;} - if(newlen < 0.0) {newlen = 0.0;} - if(flip == 0) { - interp_v3_v3v3(ev->co, editedge_getOtherVert(tempsv->down,ev)->co, editedge_getOtherVert(tempsv->up,ev)->co, fabs(newlen)); - if (0) { // XXX scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) { - /* dont do anything if no UVs */ - for (uvlay_idx=0; uvlay_idxfuv_list && suv->uv_up && suv->uv_down) { - interp_v2_v2v2(uv_tmp, suv->uv_down, suv->uv_up, fabs(newlen)); - fuv_link = suv->fuv_list; - while (fuv_link) { - VECCOPY2D(((float *)fuv_link->link), uv_tmp); - fuv_link = fuv_link->next; - } - } - } - } - } else{ - interp_v3_v3v3(ev->co, editedge_getOtherVert(tempsv->up,ev)->co, editedge_getOtherVert(tempsv->down,ev)->co, fabs(newlen)); - - if (0) { // XXX scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) { - /* dont do anything if no UVs */ - for (uvlay_idx=0; uvlay_idxfuv_list && suv->uv_up && suv->uv_down) { - interp_v2_v2v2(uv_tmp, suv->uv_up, suv->uv_down, fabs(newlen)); - fuv_link = suv->fuv_list; - while (fuv_link) { - VECCOPY2D(((float *)fuv_link->link), uv_tmp); - fuv_link = fuv_link->next; - } - } - } - } - } - look = look->next; - } - - } - - // Highlight the Control Edges -// scrarea_do_windraw(curarea); -// persp(PERSP_VIEW); -// glPushMatrix(); -// mymultmatrix(obedit->obmat); - - glColor3ub(0, 255, 0); - glBegin(GL_LINES); - glVertex3fv(upVert->co); - glVertex3fv(downVert->co); - glEnd(); - - if(prop == 0) { - // draw start edge for non-prop - glPointSize(5); - glBegin(GL_POINTS); - glColor3ub(255,0,255); - if(flip) { - glVertex3fv(upVert->co); - } else { - glVertex3fv(downVert->co); - } - glEnd(); - } - - - glPopMatrix(); - - if(prop) { - p += sprintf(str, "(P)ercentage: "); - } else { - p += sprintf(str, "Non (P)rop Length: "); - } - - if (0) // XXX hasNumInput(&num)) - { - char num_str[20]; - - // XX outputNumInput(&num, num_str); - p += sprintf(p, "%s", num_str); - } - else - { - if (prop) - { - p += sprintf(p, "%f", perc); - } - else - { - p += sprintf(p, "%f", len); - } - } - - - if (prop == 0) { - p += sprintf(p, ", Press (F) to flip control side"); - } - -// headerprint(str); -// screen_swapbuffers(); - } - if(!immediate) { - while(qtest()) { - short val=0; - event= extern_qread(&val); // extern_qread stores important events for the mainloop to handle - - /* val==0 on key-release event */ - if (val) { - if(ELEM(event, ESCKEY, RIGHTMOUSE)) { - prop = 1; // Go back to prop mode - imperc = 0; // This is the % that gets set for immediate - immediate = 1; //Run through eval code 1 more time - cancel = 1; // Return -1 - mvalo[0] = -1; - } else if(ELEM3(event, PADENTER, LEFTMOUSE, RETKEY)) { - draw = 0; // End looping now - } else if(event==MIDDLEMOUSE) { - perc = 0; - immediate = 1; - } else if(event==PKEY) { -// XXX initNumInput(&num); /* reset num input */ - if (prop) { - prop = 0; -// XXX num.flag |= NUM_NO_NEGATIVE; - } - else { - prop = 1; - } - mvalo[0] = -1; - } else if(event==FKEY) { - (flip == 1) ? (flip = 0):(flip = 1); - mvalo[0] = -1; - } else if(ELEM(event, RIGHTARROWKEY, WHEELUPMOUSE)) { // Scroll through Control Edges - look = vertlist; - while(look) { - if(nearest == (EditVert*)look->link) { - if(look->next == NULL) { - nearest = (EditVert*)vertlist->link; - } else { - nearest = (EditVert*)look->next->link; - } - mvalo[0] = -1; - break; - } - look = look->next; - } - } else if(ELEM(event, LEFTARROWKEY, WHEELDOWNMOUSE)) { // Scroll through Control Edges - look = vertlist; - while(look) { - if(look->next) { - if(look->next->link == nearest) { - nearest = (EditVert*)look->link; - mvalo[0] = -1; - break; - } - } else { - if((EditVert*)vertlist->link == nearest) { - nearest = look->link; - mvalo[0] = -1; - break; - } - } - look = look->next; - } - } - -// XXX if (handleNumInput(&num, event)) - { - mvalo[0] = -1; /* NEED A BETTER WAY TO TRIGGER REDRAW */ - } - } - - } - } else { - draw = 0; - } -// DAG_id_tag_update(obedit->data, 0); - } - - - if(me->drawflag & ME_DRAWEXTRA_EDGELEN) { - look = vertlist; - while(look) { - tempsv = BLI_ghash_lookup(vertgh,(EditVert*)look->link); - if(tempsv != NULL) { - tempsv->up->f &= !SELECT; - tempsv->down->f &= !SELECT; - } - look = look->next; - } - } - -// force_draw(0); - - if(!immediate) - EM_automerge(0); -// DAG_id_tag_update(obedit->data, 0); -// scrarea_queue_winredraw(curarea); - - //BLI_ghash_free(edgesgh, freeGHash, NULL); - BLI_ghash_free(vertgh, NULL, (GHashValFreeFP)MEM_freeN); - BLI_linklist_free(vertlist,NULL); - BLI_linklist_free(edgelist,NULL); - - if (uvlay_tot) { // XXX && (scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT)) { - for (uvlay_idx=0; uvlay_idx= slideuvs) { - if (suv->fuv_list) { - BLI_linklist_free(suv->fuv_list,NULL); - } - suv--; - } - } - - if(cancel == 1) { - return -1; - } - - return 1; -} -#endif // END OF XXX - int EdgeLoopDelete(EditMesh *UNUSED(em), wmOperator *UNUSED(op)) { #if 0 //XXX won't work with new edgeslide @@ -5080,7 +4278,7 @@ BKE_mesh_end_editmesh(obedit->data, em); // RNA_enum_set(op->ptr, "proportional", 0); -// RNA_boolean_set(op->ptr, "mirror", 0); +// RNA_boolean_set(op->ptr, "mirror", FALSE); // WM_operator_name_call(C, "TRANSFORM_OT_translate", WM_OP_INVOKE_REGION_WIN, op->ptr); return OPERATOR_FINISHED; @@ -6308,8 +5506,8 @@ return(1); } -static int loop_bisect(EditMesh *em, Collection *edgecollection){ - +static int loop_bisect(EditMesh *em, Collection *edgecollection) +{ EditFace *efa, *sf1, *sf2; EditEdge *eed, *sed; CollectedEdge *curredge; @@ -7246,7 +6444,7 @@ float cur[3]; if (event == 1) - mul_m4_m4m4(mat, OBACT->obmat, rv3d->viewmat); /* apply the view matrix to the object matrix */ + mult_m4_m4m4(mat, rv3d->viewmat, OBACT->obmat); /* apply the view matrix to the object matrix */ else if (event == 2) { /* sort from cursor */ if( v3d && v3d->localvd ) { VECCOPY(cur, v3d->cursor); diff -Nru blender-2.61/source/blender/editors/mesh/loopcut.c blender-2.62/source/blender/editors/mesh/loopcut.c --- blender-2.61/source/blender/editors/mesh/loopcut.c 2011-12-13 19:52:57.000000000 +0000 +++ blender-2.62/source/blender/editors/mesh/loopcut.c 2012-02-15 19:37:25.000000000 +0000 @@ -45,6 +45,7 @@ #include "PIL_time.h" +#include "BLI_array.h" #include "BLI_blenlib.h" #include "BLI_dynstr.h" /*for WM_operator_pystring */ #include "BLI_editVert.h" @@ -58,7 +59,6 @@ #include "BKE_modifier.h" #include "BKE_report.h" #include "BKE_scene.h" -#include "BKE_array_mallocn.h" #include "BIF_gl.h" #include "BIF_glutil.h" /* for paint cursor */ @@ -138,7 +138,7 @@ EditFace *efa; EditVert *v[2][2]; float (*edges)[2][3] = NULL; - V_DYNDECLARE(edges); + BLI_array_declare(edges); float co[2][3]; int looking=1, i, tot=0; @@ -240,9 +240,9 @@ co[1][1] = (v[1][1]->co[1] - v[1][0]->co[1])*(i/((float)previewlines+1))+v[1][0]->co[1]; co[1][2] = (v[1][1]->co[2] - v[1][0]->co[2])*(i/((float)previewlines+1))+v[1][0]->co[2]; - V_GROW(edges); - VECCOPY(edges[tot][0], co[0]); - VECCOPY(edges[tot][1], co[1]); + BLI_array_growone(edges); + copy_v3_v3(edges[tot][0], co[0]); + copy_v3_v3(edges[tot][1], co[1]); tot++; } } @@ -380,8 +380,16 @@ lcd = op->customdata; if (lcd->em->selectmode == SCE_SELECT_FACE) { + PointerRNA props_ptr; + int extend = RNA_boolean_get(op->ptr, "extend"); + ringsel_exit(op); - WM_operator_name_call(C, "MESH_OT_loop_select", WM_OP_INVOKE_REGION_WIN, NULL); + + WM_operator_properties_create(&props_ptr, "MESH_OT_loop_select"); + RNA_boolean_set(&props_ptr, "extend", extend); + WM_operator_name_call(C, "MESH_OT_loop_select", WM_OP_INVOKE_REGION_WIN, &props_ptr); + WM_operator_properties_free(&props_ptr); + return OPERATOR_CANCELLED; } diff -Nru blender-2.61/source/blender/editors/mesh/mesh_data.c blender-2.62/source/blender/editors/mesh/mesh_data.c --- blender-2.61/source/blender/editors/mesh/mesh_data.c 2011-12-13 19:52:57.000000000 +0000 +++ blender-2.62/source/blender/editors/mesh/mesh_data.c 2012-02-15 19:37:25.000000000 +0000 @@ -183,7 +183,7 @@ layernum= CustomData_number_of_layers(&em->fdata, CD_MTFACE); if(layernum >= MAX_MTFACE) - return 0; + return -1; EM_add_data_layer(em, &em->fdata, CD_MTFACE, name); @@ -196,7 +196,7 @@ else { layernum= CustomData_number_of_layers(&me->fdata, CD_MTFACE); if(layernum >= MAX_MTFACE) - return 0; + return -1; if(me->mtface) CustomData_add_layer_named(&me->fdata, CD_MTFACE, CD_DUPLICATE, me->mtface, me->totface, name); @@ -212,7 +212,7 @@ DAG_id_tag_update(&me->id, 0); WM_event_add_notifier(C, NC_GEOM|ND_DATA, me); - return 1; + return layernum; } int ED_mesh_uv_texture_remove(bContext *C, Object *ob, Mesh *me) @@ -244,7 +244,7 @@ layernum= CustomData_number_of_layers(&em->fdata, CD_MCOL); if(layernum >= MAX_MCOL) - return 0; + return -1; EM_add_data_layer(em, &em->fdata, CD_MCOL, name); @@ -257,7 +257,7 @@ else { layernum= CustomData_number_of_layers(&me->fdata, CD_MCOL); if(layernum >= MAX_MCOL) - return 0; + return -1; if(me->mcol) CustomData_add_layer_named(&me->fdata, CD_MCOL, CD_DUPLICATE, me->mcol, me->totface, name); @@ -273,7 +273,7 @@ DAG_id_tag_update(&me->id, 0); WM_event_add_notifier(C, NC_GEOM|ND_DATA, me); - return 1; + return layernum; } int ED_mesh_color_remove(bContext *C, Object *ob, Mesh *me) @@ -318,17 +318,17 @@ static int layers_poll(bContext *C) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); ID *data= (ob)? ob->data: NULL; return (ob && !ob->id.lib && ob->type==OB_MESH && data && !data->lib); } static int uv_texture_add_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); Mesh *me= ob->data; - if(!ED_mesh_uv_texture_add(C, me, NULL, TRUE)) + if(ED_mesh_uv_texture_add(C, me, NULL, TRUE) == -1) return OPERATOR_CANCELLED; return OPERATOR_FINISHED; @@ -359,7 +359,7 @@ Mesh *me; Object *obedit; int exitmode= 0; - char name[32]; + char name[MAX_ID_NAME-2]; /* Check context */ if(base==NULL || base->object->type!=OB_MESH) { @@ -368,7 +368,7 @@ } /* check input variables */ - if(RNA_property_is_set(op->ptr, "filepath")) { + if(RNA_struct_property_is_set(op->ptr, "filepath")) { char path[FILE_MAX]; RNA_string_get(op->ptr, "filepath", path); @@ -403,6 +403,10 @@ free_editMesh(me->edit_mesh); MEM_freeN(me->edit_mesh); me->edit_mesh= NULL; + + /* load_editMesh free's pointers used by CustomData layers which might be used by DerivedMesh too, + * so signal to re-create DerivedMesh here (sergey) */ + DAG_id_tag_update(&me->id, 0); } /* dummie drop support; ensure view shows a result :) */ @@ -429,13 +433,13 @@ ot->flag= OPTYPE_UNDO; /* properties */ - RNA_def_string(ot->srna, "name", "Image", 24, "Name", "Image name to assign"); + RNA_def_string(ot->srna, "name", "Image", MAX_ID_NAME-2, "Name", "Image name to assign"); RNA_def_string(ot->srna, "filepath", "Path", FILE_MAX, "Filepath", "Path to image file"); } static int uv_texture_remove_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); Mesh *me= ob->data; if(!ED_mesh_uv_texture_remove(C, ob, me)) @@ -464,10 +468,10 @@ static int vertex_color_add_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); Mesh *me= ob->data; - if(!ED_mesh_color_add(C, scene, ob, me, NULL, TRUE)) + if(ED_mesh_color_add(C, scene, ob, me, NULL, TRUE) == -1) return OPERATOR_CANCELLED; return OPERATOR_FINISHED; @@ -490,7 +494,7 @@ static int vertex_color_remove_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); Mesh *me= ob->data; if(!ED_mesh_color_remove(C, ob, me)) @@ -520,7 +524,7 @@ { Scene *scene= CTX_data_scene(C); View3D *v3d= CTX_wm_view3d(C); - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); Mesh *me= ob->data; /*if(me->msticky) @@ -551,7 +555,7 @@ static int sticky_remove_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); Mesh *me= ob->data; if(!me->msticky) @@ -695,6 +699,46 @@ mesh->totface= totface; } +static void mesh_remove_verts(Mesh *mesh, int len) +{ + int totvert; + + if(len == 0) + return; + + totvert= mesh->totvert - len; + CustomData_free_elem(&mesh->vdata, totvert, len); + + /* set final vertex list size */ + mesh->totvert= totvert; +} + +static void mesh_remove_edges(Mesh *mesh, int len) +{ + int totedge; + + if(len == 0) + return; + + totedge= mesh->totedge - len; + CustomData_free_elem(&mesh->edata, totedge, len); + + mesh->totedge= totedge; +} + +static void mesh_remove_faces(Mesh *mesh, int len) +{ + int totface; + + if(len == 0) + return; + + totface= mesh->totface - len; /* new face count */ + CustomData_free_elem(&mesh->fdata, totface, len); + + mesh->totface= totface; +} + /* void ED_mesh_geometry_add(Mesh *mesh, ReportList *reports, int verts, int edges, int faces) { @@ -742,6 +786,48 @@ mesh_add_verts(mesh, count); } +void ED_mesh_faces_remove(Mesh *mesh, ReportList *reports, int count) +{ + if(mesh->edit_mesh) { + BKE_report(reports, RPT_ERROR, "Can't remove faces in edit mode"); + return; + } + else if(count > mesh->totface) { + BKE_report(reports, RPT_ERROR, "Can't remove more faces than the mesh contains"); + return; + } + + mesh_remove_faces(mesh, count); +} + +void ED_mesh_edges_remove(Mesh *mesh, ReportList *reports, int count) +{ + if(mesh->edit_mesh) { + BKE_report(reports, RPT_ERROR, "Can't remove edges in edit mode"); + return; + } + else if(count > mesh->totedge) { + BKE_report(reports, RPT_ERROR, "Can't remove more edges than the mesh contains"); + return; + } + + mesh_remove_edges(mesh, count); +} + +void ED_mesh_vertices_remove(Mesh *mesh, ReportList *reports, int count) +{ + if(mesh->edit_mesh) { + BKE_report(reports, RPT_ERROR, "Can't remove vertices in edit mode"); + return; + } + else if(count > mesh->totvert) { + BKE_report(reports, RPT_ERROR, "Can't remove more vertices than the mesh contains"); + return; + } + + mesh_remove_verts(mesh, count); +} + void ED_mesh_calc_normals(Mesh *me) { mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL); diff -Nru blender-2.61/source/blender/editors/mesh/mesh_intern.h blender-2.62/source/blender/editors/mesh/mesh_intern.h --- blender-2.61/source/blender/editors/mesh/mesh_intern.h 2011-12-13 19:52:57.000000000 +0000 +++ blender-2.62/source/blender/editors/mesh/mesh_intern.h 2012-02-15 19:37:25.000000000 +0000 @@ -144,7 +144,6 @@ void MESH_OT_select_all(struct wmOperatorType *ot); void MESH_OT_select_more(struct wmOperatorType *ot); void MESH_OT_select_less(struct wmOperatorType *ot); -void MESH_OT_select_inverse(struct wmOperatorType *ot); void MESH_OT_select_non_manifold(struct wmOperatorType *ot); void MESH_OT_select_linked(struct wmOperatorType *ot); void MESH_OT_select_linked_pick(struct wmOperatorType *ot); diff -Nru blender-2.61/source/blender/editors/mesh/mesh_navmesh.c blender-2.62/source/blender/editors/mesh/mesh_navmesh.c --- blender-2.61/source/blender/editors/mesh/mesh_navmesh.c 2011-12-13 19:52:57.000000000 +0000 +++ blender-2.62/source/blender/editors/mesh/mesh_navmesh.c 2012-02-15 19:37:25.000000000 +0000 @@ -534,7 +534,8 @@ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } -static int compare(const void * a, const void * b){ +static int compare(const void * a, const void * b) +{ return ( *(int*)a - *(int*)b ); } diff -Nru blender-2.61/source/blender/editors/mesh/mesh_ops.c blender-2.62/source/blender/editors/mesh/mesh_ops.c --- blender-2.61/source/blender/editors/mesh/mesh_ops.c 2011-12-13 19:52:57.000000000 +0000 +++ blender-2.62/source/blender/editors/mesh/mesh_ops.c 2012-02-15 19:37:25.000000000 +0000 @@ -62,7 +62,6 @@ WM_operatortype_append(MESH_OT_select_all); WM_operatortype_append(MESH_OT_select_more); WM_operatortype_append(MESH_OT_select_less); - WM_operatortype_append(MESH_OT_select_inverse); WM_operatortype_append(MESH_OT_select_non_manifold); WM_operatortype_append(MESH_OT_select_linked); WM_operatortype_append(MESH_OT_select_linked_pick); @@ -189,14 +188,14 @@ WM_operatortype_macro_define(ot, "MESH_OT_duplicate"); otmacro= WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); RNA_enum_set(otmacro->ptr, "proportional", 0); - RNA_boolean_set(otmacro->ptr, "mirror", 0); + RNA_boolean_set(otmacro->ptr, "mirror", FALSE); ot= WM_operatortype_append_macro("MESH_OT_rip_move", "Rip", OPTYPE_UNDO|OPTYPE_REGISTER); ot->description = "Rip polygons and move the result"; WM_operatortype_macro_define(ot, "MESH_OT_rip"); otmacro= WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); RNA_enum_set(otmacro->ptr, "proportional", 0); - RNA_boolean_set(otmacro->ptr, "mirror", 0); + RNA_boolean_set(otmacro->ptr, "mirror", FALSE); ot= WM_operatortype_append_macro("MESH_OT_extrude_region_move", "Extrude Region and Move", OPTYPE_UNDO|OPTYPE_REGISTER); ot->description = "Extrude region and move result"; @@ -204,7 +203,7 @@ RNA_enum_set(otmacro->ptr, "type", 1); otmacro= WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); RNA_enum_set(otmacro->ptr, "proportional", 0); - RNA_boolean_set(otmacro->ptr, "mirror", 0); + RNA_boolean_set(otmacro->ptr, "mirror", FALSE); ot= WM_operatortype_append_macro("MESH_OT_extrude_faces_move", "Extrude Individual Faces and Move", OPTYPE_UNDO|OPTYPE_REGISTER); ot->description = "Extrude faces and move result"; @@ -212,7 +211,7 @@ RNA_enum_set(otmacro->ptr, "type", 2); otmacro= WM_operatortype_macro_define(ot, "TRANSFORM_OT_shrink_fatten"); RNA_enum_set(otmacro->ptr, "proportional", 0); - RNA_boolean_set(otmacro->ptr, "mirror", 0); + RNA_boolean_set(otmacro->ptr, "mirror", FALSE); ot= WM_operatortype_append_macro("MESH_OT_extrude_edges_move", "Extrude Only Edges and Move", OPTYPE_UNDO|OPTYPE_REGISTER); ot->description = "Extrude edges and move result"; @@ -220,7 +219,7 @@ RNA_enum_set(otmacro->ptr, "type", 3); otmacro= WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); RNA_enum_set(otmacro->ptr, "proportional", 0); - RNA_boolean_set(otmacro->ptr, "mirror", 0); + RNA_boolean_set(otmacro->ptr, "mirror", FALSE); ot= WM_operatortype_append_macro("MESH_OT_extrude_vertices_move", "Extrude Only Vertices and Move", OPTYPE_UNDO|OPTYPE_REGISTER); ot->description = "Extrude vertices and move result"; @@ -228,7 +227,7 @@ RNA_enum_set(otmacro->ptr, "type", 4); otmacro= WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); RNA_enum_set(otmacro->ptr, "proportional", 0); - RNA_boolean_set(otmacro->ptr, "mirror", 0); + RNA_boolean_set(otmacro->ptr, "mirror", FALSE); } /* note mesh keymap also for other space? */ @@ -245,25 +244,32 @@ /* selecting */ /* standard mouse selection goes via space_view3d */ - WM_keymap_add_item(keymap, "MESH_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0); - kmi= WM_keymap_add_item(keymap, "MESH_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_ALT, 0); - RNA_boolean_set(kmi->ptr, "extend", 1); - - WM_keymap_add_item(keymap, "MESH_OT_edgering_select", SELECTMOUSE, KM_PRESS, KM_ALT|KM_CTRL, 0); - kmi= WM_keymap_add_item(keymap, "MESH_OT_edgering_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_ALT|KM_CTRL, 0); - RNA_boolean_set(kmi->ptr, "extend", 1); + kmi = WM_keymap_add_item(keymap, "MESH_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + kmi = WM_keymap_add_item(keymap, "MESH_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_ALT, 0); + RNA_boolean_set(kmi->ptr, "extend", TRUE); + + kmi = WM_keymap_add_item(keymap, "MESH_OT_edgering_select", SELECTMOUSE, KM_PRESS, KM_ALT|KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + kmi = WM_keymap_add_item(keymap, "MESH_OT_edgering_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_ALT|KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "extend", TRUE); WM_keymap_add_item(keymap, "MESH_OT_select_shortest_path", SELECTMOUSE, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "MESH_OT_select_all", AKEY, KM_PRESS, 0, 0); + kmi = WM_keymap_add_item(keymap, "MESH_OT_select_all", AKEY, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE); + kmi = WM_keymap_add_item(keymap, "MESH_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0); + RNA_enum_set(kmi->ptr, "action", SEL_INVERT); + WM_keymap_add_item(keymap, "MESH_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "MESH_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "MESH_OT_select_inverse", IKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "MESH_OT_select_non_manifold", MKEY, KM_PRESS, (KM_CTRL|KM_SHIFT|KM_ALT), 0); WM_keymap_add_item(keymap, "MESH_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "MESH_OT_select_linked_pick", LKEY, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "MESH_OT_select_linked_pick", LKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "deselect", 1); + kmi = WM_keymap_add_item(keymap, "MESH_OT_select_linked_pick", LKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "deselect", FALSE); + kmi = WM_keymap_add_item(keymap, "MESH_OT_select_linked_pick", LKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "deselect", TRUE); WM_keymap_add_item(keymap, "MESH_OT_faces_select_linked_flat", FKEY, KM_PRESS, (KM_CTRL|KM_SHIFT|KM_ALT), 0); @@ -273,13 +279,17 @@ WM_keymap_add_menu(keymap, "VIEW3D_MT_edit_mesh_select_mode", TABKEY, KM_PRESS, KM_CTRL, 0); /* hide */ - WM_keymap_add_item(keymap, "MESH_OT_hide", HKEY, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "MESH_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "unselected", 1); + kmi = WM_keymap_add_item(keymap, "MESH_OT_hide", HKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "unselected", FALSE); + kmi = WM_keymap_add_item(keymap, "MESH_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "unselected", TRUE); WM_keymap_add_item(keymap, "MESH_OT_reveal", HKEY, KM_PRESS, KM_ALT, 0); /* tools */ - WM_keymap_add_item(keymap, "MESH_OT_normals_make_consistent", NKEY, KM_PRESS, KM_CTRL, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "MESH_OT_normals_make_consistent", NKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0)->ptr, "inside", 1); + kmi = WM_keymap_add_item(keymap, "MESH_OT_normals_make_consistent", NKEY, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "inside", FALSE); + kmi = WM_keymap_add_item(keymap, "MESH_OT_normals_make_consistent", NKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "inside", TRUE); WM_keymap_add_item(keymap, "VIEW3D_OT_edit_mesh_extrude_move_normal", EKEY, KM_PRESS, 0, 0); /* python operator */ WM_keymap_add_menu(keymap, "VIEW3D_MT_edit_mesh_extrude", EKEY, KM_PRESS, KM_ALT, 0); @@ -290,6 +300,7 @@ WM_keymap_add_item(keymap, "MESH_OT_fill", FKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "MESH_OT_beautify_fill", FKEY, KM_PRESS, KM_SHIFT|KM_ALT, 0); + WM_keymap_add_item(keymap, "MESH_OT_quads_convert_to_tris", TKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "MESH_OT_tris_convert_to_quads", JKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "MESH_OT_edge_flip", FKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0); @@ -310,8 +321,10 @@ WM_keymap_add_item(keymap, "MESH_OT_split", YKEY, KM_PRESS, 0, 0); /* use KM_CLICK because same key is used for tweaks */ - WM_keymap_add_item(keymap, "MESH_OT_dupli_extrude_cursor", ACTIONMOUSE, KM_CLICK, KM_CTRL, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "MESH_OT_dupli_extrude_cursor", ACTIONMOUSE, KM_CLICK, KM_SHIFT|KM_CTRL, 0)->ptr, "rotate_source", 0); + kmi = WM_keymap_add_item(keymap, "MESH_OT_dupli_extrude_cursor", ACTIONMOUSE, KM_CLICK, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "rotate_source", TRUE); + kmi = WM_keymap_add_item(keymap, "MESH_OT_dupli_extrude_cursor", ACTIONMOUSE, KM_CLICK, KM_SHIFT|KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "rotate_source", FALSE); WM_keymap_add_item(keymap, "MESH_OT_delete", XKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "MESH_OT_delete", DELKEY, KM_PRESS, 0, 0); diff -Nru blender-2.61/source/blender/editors/mesh/meshtools.c blender-2.62/source/blender/editors/mesh/meshtools.c --- blender-2.61/source/blender/editors/mesh/meshtools.c 2011-12-13 19:52:57.000000000 +0000 +++ blender-2.62/source/blender/editors/mesh/meshtools.c 2012-02-15 19:37:25.000000000 +0000 @@ -327,7 +327,7 @@ /* if this is the object we're merging into, no need to do anything */ if(base->object != ob) { /* watch this: switch matmul order really goes wrong */ - mul_m4_m4m4(cmat, base->object->obmat, imat); + mult_m4_m4m4(cmat, imat, base->object->obmat); /* transform vertex coordinates into new space */ for(a=0, mv=mvert; a < me->totvert; a++, mv++) { @@ -671,17 +671,17 @@ /* temporal define, just to make nicer code below */ -#define MOC_ADDNODE(vx, vy, vz) mesh_octree_add_node(basetable + ((vx)*MOC_RES*MOC_RES) + (vy)*MOC_RES + (vz), index) +#define MOC_INDEX(vx, vy, vz) (((vx)*MOC_RES*MOC_RES) + (vy)*MOC_RES + (vz)) static void mesh_octree_add_nodes(MocNode **basetable, float *co, float *offs, float *div, intptr_t index) { float fx, fy, fz; int vx, vy, vz; - if (!finite(co[0]) || - !finite(co[1]) || - !finite(co[2]) - ) { + if ( !finite(co[0]) || + !finite(co[1]) || + !finite(co[2])) + { return; } @@ -692,33 +692,33 @@ CLAMP(fy, 0.0f, MOC_RES-MOC_THRESH); CLAMP(fz, 0.0f, MOC_RES-MOC_THRESH); - vx= floor(fx); - vy= floor(fy); - vz= floor(fz); - - MOC_ADDNODE(vx, vy, vz); - - if( vx>0 ) - if( fx-((float)vx)-MOC_THRESH < 0.0f) - MOC_ADDNODE(vx-1, vy, vz); - if( vx 1.0f) - MOC_ADDNODE(vx+1, vy, vz); - - if( vy>0 ) - if( fy-((float)vy)-MOC_THRESH < 0.0f) - MOC_ADDNODE(vx, vy-1, vz); - if( vy 1.0f) - MOC_ADDNODE(vx, vy+1, vz); - - if( vz>0 ) - if( fz-((float)vz)-MOC_THRESH < 0.0f) - MOC_ADDNODE(vx, vy, vz-1); - if( vz 1.0f) - MOC_ADDNODE(vx, vy, vz+1); - + vx= (int)floorf(fx); + vy= (int)floorf(fy); + vz= (int)floorf(fz); + + mesh_octree_add_node(basetable + MOC_INDEX(vx, vy, vz), index); + + if (vx > 0) + if (fx-((float)vx)-MOC_THRESH < 0.0f) + mesh_octree_add_node(basetable + MOC_INDEX(vx - 1, vy, vz), index); + if (vx < MOC_RES - 2) + if (fx-((float)vx)+MOC_THRESH > 1.0f) + mesh_octree_add_node(basetable + MOC_INDEX(vx + 1, vy, vz), index); + + if (vy > 0) + if (fy-((float)vy)-MOC_THRESH < 0.0f) + mesh_octree_add_node(basetable + MOC_INDEX(vx, vy - 1, vz), index); + if (vy < MOC_RES - 2) + if (fy-((float)vy)+MOC_THRESH > 1.0f) + mesh_octree_add_node(basetable + MOC_INDEX(vx, vy + 1, vz), index); + + if (vz > 0) + if (fz-((float)vz)-MOC_THRESH < 0.0f) + mesh_octree_add_node(basetable + MOC_INDEX(vx, vy, vz - 1), index); + if (vz 1.0f) + mesh_octree_add_node(basetable + MOC_INDEX(vx, vy, vz + 1), index); + } static intptr_t mesh_octree_find_index(MocNode **bt, MVert *mvert, float *co) @@ -765,7 +765,7 @@ if(mode=='u') { /* use table */ if(MeshOctree.table==NULL) mesh_octree_table(ob, em, NULL, 's'); - + if(MeshOctree.table) { Mesh *me= ob->data; bt= MeshOctree.table + mesh_octree_get_base_offs(co, MeshOctree.offs, MeshOctree.div); @@ -848,212 +848,23 @@ return 0; } - -/* ********************* MESH VERTEX MIRR TOPO LOOKUP *************** */ - -#define MIRRHASH_TYPE int - -typedef struct MirrTopoPair { - long hash; - int vIndex; -} MirrTopoPair; - -static int MirrTopo_long_sort(const void *l1, const void *l2) -{ - if( (MIRRHASH_TYPE)(intptr_t)l1 > (MIRRHASH_TYPE)(intptr_t)l2 ) return 1; - else if( (MIRRHASH_TYPE)(intptr_t)l1 < (MIRRHASH_TYPE)(intptr_t)l2 ) return -1; - return 0; -} - -static int MirrTopo_item_sort(const void *v1, const void *v2) -{ - if( ((MirrTopoPair *)v1)->hash > ((MirrTopoPair *)v2)->hash ) return 1; - else if( ((MirrTopoPair *)v1)->hash < ((MirrTopoPair *)v2)->hash ) return -1; - return 0; -} - -static long *mesh_topo_lookup = NULL; -static int mesh_topo_lookup_tot = -1; -static int mesh_topo_lookup_mode = -1; +MirrTopoStore_t mesh_topo_store= {NULL, -1. -1, -1}; /* mode is 's' start, or 'e' end, or 'u' use */ /* if end, ob can be NULL */ -long mesh_mirrtopo_table(Object *ob, char mode) +/* note, is supposed return -1 on error, which callers are currently checking for, but is not used so far */ +int mesh_mirrtopo_table(Object *ob, char mode) { if(mode=='u') { /* use table */ - Mesh *me= ob->data; - if( (mesh_topo_lookup==NULL) || - (mesh_topo_lookup_mode != ob->mode) || - (me->edit_mesh && me->edit_mesh->totvert != mesh_topo_lookup_tot) || - (me->edit_mesh==NULL && me->totvert != mesh_topo_lookup_tot) - ) { + if (ED_mesh_mirrtopo_recalc_check(ob->data, ob->mode, &mesh_topo_store)) { mesh_mirrtopo_table(ob, 's'); } - } else if(mode=='s') { /* start table */ - Mesh *me= ob->data; - MEdge *medge; - EditMesh *em= me->edit_mesh; - void **eve_tmp_back= NULL; /* some of the callers are using eve->tmp so restore after */ - - - /* editmode*/ - EditEdge *eed; - - int a, last, totvert; - int totUnique= -1, totUniqueOld= -1; - - MIRRHASH_TYPE *MirrTopoHash = NULL; - MIRRHASH_TYPE *MirrTopoHash_Prev = NULL; - MirrTopoPair *MirrTopoPairs; - mesh_topo_lookup_mode= ob->mode; - - /* reallocate if needed */ - if (mesh_topo_lookup) { - MEM_freeN(mesh_topo_lookup); - mesh_topo_lookup = NULL; - } - - if(em) { - EditVert *eve; - totvert= 0; - eve_tmp_back= MEM_callocN( em->totvert * sizeof(void *), "TopoMirr" ); - for(eve= em->verts.first; eve; eve= eve->next) { - eve_tmp_back[totvert]= eve->tmp.p; - eve->tmp.l = totvert++; - } - } - else { - totvert = me->totvert; - } - - MirrTopoHash = MEM_callocN( totvert * sizeof(MIRRHASH_TYPE), "TopoMirr" ); - - /* Initialize the vert-edge-user counts used to detect unique topology */ - if(em) { - for(eed=em->edges.first; eed; eed= eed->next) { - MirrTopoHash[eed->v1->tmp.l]++; - MirrTopoHash[eed->v2->tmp.l]++; - } - } else { - for(a=0, medge=me->medge; atotedge; a++, medge++) { - MirrTopoHash[medge->v1]++; - MirrTopoHash[medge->v2]++; - } - } - - MirrTopoHash_Prev = MEM_dupallocN( MirrTopoHash ); - - totUniqueOld = -1; - while(1) { - /* use the number of edges per vert to give verts unique topology IDs */ - - if(em) { - for(eed=em->edges.first; eed; eed= eed->next) { - MirrTopoHash[eed->v1->tmp.l] += MirrTopoHash_Prev[eed->v2->tmp.l]; - MirrTopoHash[eed->v2->tmp.l] += MirrTopoHash_Prev[eed->v1->tmp.l]; - } - } else { - for(a=0, medge=me->medge; atotedge; a++, medge++) { - /* This can make really big numbers, wrapping around here is fine */ - MirrTopoHash[medge->v1] += MirrTopoHash_Prev[medge->v2]; - MirrTopoHash[medge->v2] += MirrTopoHash_Prev[medge->v1]; - } - } - memcpy(MirrTopoHash_Prev, MirrTopoHash, sizeof(MIRRHASH_TYPE) * totvert); - - /* sort so we can count unique values */ - qsort(MirrTopoHash_Prev, totvert, sizeof(MIRRHASH_TYPE), MirrTopo_long_sort); - - totUnique = 1; /* account for skiping the first value */ - for(a=1; atmp.* */ - if(eve_tmp_back) { - EditVert *eve; - totvert= 0; - for(eve= em->verts.first; eve; eve= eve->next) { - eve->tmp.p= eve_tmp_back[totvert++]; - } - - MEM_freeN(eve_tmp_back); - eve_tmp_back= NULL; - } - - - /* Hash/Index pairs are needed for sorting to find index pairs */ - MirrTopoPairs= MEM_callocN( sizeof(MirrTopoPair) * totvert, "MirrTopoPairs"); - - /* since we are looping through verts, initialize these values here too */ - mesh_topo_lookup = MEM_mallocN( totvert * sizeof(long), "mesh_topo_lookup" ); - - if(em) { - EM_init_index_arrays(em,1,0,0); - } - - - for(a=0; a= 2) && (MirrTopoPairs[0].hash == MirrTopoPairs[1].hash)) ? 0 : 1; - - /* Get the pairs out of the sorted hashes, note, totvert+1 means we can use the previous 2, - * but you cant ever access the last 'a' index of MirrTopoPairs */ - for(a=2; a < totvert+1; a++) { - /* printf("I %d %ld %d\n", (a-last), MirrTopoPairs[a ].hash, MirrTopoPairs[a ].vIndex ); */ - if ((a==totvert) || (MirrTopoPairs[a-1].hash != MirrTopoPairs[a].hash)) { - if (a-last==2) { - if(em) { - mesh_topo_lookup[MirrTopoPairs[a-1].vIndex] = (long)EM_get_vert_for_index(MirrTopoPairs[a-2].vIndex); - mesh_topo_lookup[MirrTopoPairs[a-2].vIndex] = (long)EM_get_vert_for_index(MirrTopoPairs[a-1].vIndex); - } else { - mesh_topo_lookup[MirrTopoPairs[a-1].vIndex] = MirrTopoPairs[a-2].vIndex; - mesh_topo_lookup[MirrTopoPairs[a-2].vIndex] = MirrTopoPairs[a-1].vIndex; - } - } - last= a; - } - } - if(em) { - EM_free_index_arrays(); - } - - MEM_freeN( MirrTopoPairs ); - MirrTopoPairs = NULL; - - MEM_freeN( MirrTopoHash ); - MEM_freeN( MirrTopoHash_Prev ); - - mesh_topo_lookup_tot = totvert; - - } else if(mode=='e') { /* end table */ - if (mesh_topo_lookup) { - MEM_freeN(mesh_topo_lookup); - } - mesh_topo_lookup = NULL; - mesh_topo_lookup_tot= -1; + } + else if(mode=='s') { /* start table */ + ED_mesh_mirrtopo_init(ob->data, ob->mode, &mesh_topo_store, FALSE); + } + else if(mode=='e') { /* end table */ + ED_mesh_mirrtopo_free(&mesh_topo_store); } return 0; } @@ -1077,7 +888,7 @@ if (mesh_mirrtopo_table(ob, 'u')==-1) return -1; - return mesh_topo_lookup[index]; + return mesh_topo_store.index_lookup[index]; } int mesh_get_x_mirror_vert(Object *ob, int index) @@ -1113,7 +924,7 @@ static EditVert *editmesh_get_x_mirror_vert_topo(Object *ob, struct EditMesh *em, EditVert *eve, int index) { - long poinval; + intptr_t poinval; if (mesh_mirrtopo_table(ob, 'u')==-1) return NULL; @@ -1125,7 +936,7 @@ } } - poinval= mesh_topo_lookup[ index ]; + poinval= mesh_topo_store.index_lookup[index]; if(poinval != -1) return (EditVert *)(poinval); @@ -1269,8 +1080,8 @@ /* make sure v4 is not 0 if a quad */ if(mf->v4 && mirrormf.v4==0) { - SWAP(int, mirrormf.v1, mirrormf.v3); - SWAP(int, mirrormf.v2, mirrormf.v4); + SWAP(unsigned int, mirrormf.v1, mirrormf.v3); + SWAP(unsigned int, mirrormf.v2, mirrormf.v4); } hashmf= BLI_ghash_lookup(fhash, &mirrormf); diff -Nru blender-2.61/source/blender/editors/metaball/mball_edit.c blender-2.62/source/blender/editors/metaball/mball_edit.c --- blender-2.61/source/blender/editors/metaball/mball_edit.c 2011-12-13 19:52:38.000000000 +0000 +++ blender-2.62/source/blender/editors/metaball/mball_edit.c 2012-02-15 19:37:13.000000000 +0000 @@ -181,45 +181,6 @@ WM_operator_properties_select_all(ot); } -/***************************** Select inverse operator *****************************/ - -/* Invert metaball selection */ -static int select_inverse_metaelems_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Object *obedit= CTX_data_edit_object(C); - MetaBall *mb = (MetaBall*)obedit->data; - MetaElem *ml; - - ml= mb->editelems->first; - if(ml) { - while(ml) { - if(ml->flag & SELECT) - ml->flag &= ~SELECT; - else - ml->flag |= SELECT; - ml= ml->next; - } - WM_event_add_notifier(C, NC_GEOM|ND_SELECT, mb); - } - - return OPERATOR_FINISHED; -} - -void MBALL_OT_select_inverse_metaelems(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Inverse"; - ot->description= "Select inverse of (un)selected metaelements"; - ot->idname= "MBALL_OT_select_inverse_metaelems"; - - /* callback functions */ - ot->exec= select_inverse_metaelems_exec; - ot->poll= ED_operator_editmball; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - /***************************** Select random operator *****************************/ /* Random metaball selection */ diff -Nru blender-2.61/source/blender/editors/metaball/mball_intern.h blender-2.62/source/blender/editors/metaball/mball_intern.h --- blender-2.61/source/blender/editors/metaball/mball_intern.h 2011-12-13 19:52:38.000000000 +0000 +++ blender-2.62/source/blender/editors/metaball/mball_intern.h 2012-02-15 19:37:13.000000000 +0000 @@ -43,7 +43,6 @@ void MBALL_OT_duplicate_metaelems(struct wmOperatorType *ot); void MBALL_OT_select_all(struct wmOperatorType *ot); -void MBALL_OT_select_inverse_metaelems(struct wmOperatorType *ot); void MBALL_OT_select_random_metaelems(struct wmOperatorType *ot); #endif diff -Nru blender-2.61/source/blender/editors/metaball/mball_ops.c blender-2.62/source/blender/editors/metaball/mball_ops.c --- blender-2.61/source/blender/editors/metaball/mball_ops.c 2011-12-13 19:52:38.000000000 +0000 +++ blender-2.62/source/blender/editors/metaball/mball_ops.c 2012-02-15 19:37:13.000000000 +0000 @@ -36,6 +36,9 @@ #include "ED_mball.h" #include "ED_screen.h" +#include "ED_object.h" + +#include "BLI_utildefines.h" #include "mball_intern.h" @@ -48,13 +51,13 @@ WM_operatortype_append(MBALL_OT_reveal_metaelems); WM_operatortype_append(MBALL_OT_select_all); - WM_operatortype_append(MBALL_OT_select_inverse_metaelems); WM_operatortype_append(MBALL_OT_select_random_metaelems); } void ED_keymap_metaball(wmKeyConfig *keyconf) { wmKeyMap *keymap; + wmKeyMapItem *kmi; keymap= WM_keymap_find(keyconf, "Metaball", 0, 0); keymap->poll= ED_operator_editmball; @@ -62,14 +65,20 @@ WM_keymap_add_item(keymap, "OBJECT_OT_metaball_add", AKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "MBALL_OT_reveal_metaelems", HKEY, KM_PRESS, KM_ALT, 0); - WM_keymap_add_item(keymap, "MBALL_OT_hide_metaelems", HKEY, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "MBALL_OT_hide_metaelems", HKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "unselected", 1); + kmi = WM_keymap_add_item(keymap, "MBALL_OT_hide_metaelems", HKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "unselected", FALSE); + kmi = WM_keymap_add_item(keymap, "MBALL_OT_hide_metaelems", HKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "unselected", TRUE); WM_keymap_add_item(keymap, "MBALL_OT_delete_metaelems", XKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "MBALL_OT_delete_metaelems", DELKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "MBALL_OT_duplicate_metaelems", DKEY, KM_PRESS, KM_SHIFT, 0); - WM_keymap_add_item(keymap, "MBALL_OT_select_all", AKEY, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "MBALL_OT_select_inverse_metaelems", IKEY, KM_PRESS, KM_CTRL, 0); + kmi = WM_keymap_add_item(keymap, "MBALL_OT_select_all", AKEY, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE); + kmi = WM_keymap_add_item(keymap, "MBALL_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0); + RNA_enum_set(kmi->ptr, "action", SEL_INVERT); + + ED_object_generic_keymap(keyconf, keymap, 3); } diff -Nru blender-2.61/source/blender/editors/object/object_add.c blender-2.62/source/blender/editors/object/object_add.c --- blender-2.61/source/blender/editors/object/object_add.c 2011-12-13 19:54:35.000000000 +0000 +++ blender-2.62/source/blender/editors/object/object_add.c 2012-02-15 19:38:48.000000000 +0000 @@ -46,10 +46,12 @@ #include "DNA_scene_types.h" #include "DNA_speaker_types.h" #include "DNA_vfont_types.h" +#include "DNA_actuator_types.h" +#include "BLI_ghash.h" +#include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_string.h" -#include "BLI_listbase.h" #include "BLI_utildefines.h" #include "BKE_anim.h" @@ -188,52 +190,55 @@ PropertyRNA *prop; /* note: this property gets hidden for add-camera operator */ - prop= RNA_def_boolean(ot->srna, "view_align", 0, "Align to View", "Align the new object to the view"); + prop = RNA_def_boolean(ot->srna, "view_align", 0, "Align to View", "Align the new object to the view"); RNA_def_property_update_runtime(prop, view_align_update); if(do_editmode) { - prop= RNA_def_boolean(ot->srna, "enter_editmode", 0, "Enter Editmode", "Enter editmode when adding this object"); - RNA_def_property_flag(prop, PROP_HIDDEN); + prop = RNA_def_boolean(ot->srna, "enter_editmode", 0, "Enter Editmode", + "Enter editmode when adding this object"); + RNA_def_property_flag(prop, PROP_HIDDEN|PROP_SKIP_SAVE); } - RNA_def_float_vector_xyz(ot->srna, "location", 3, NULL, -FLT_MAX, FLT_MAX, "Location", "Location for the newly added object", -FLT_MAX, FLT_MAX); - RNA_def_float_rotation(ot->srna, "rotation", 3, NULL, -FLT_MAX, FLT_MAX, "Rotation", "Rotation for the newly added object", (float)-M_PI * 2.0f, (float)M_PI * 2.0f); + prop = RNA_def_float_vector_xyz(ot->srna, "location", 3, NULL, -FLT_MAX, FLT_MAX, "Location", + "Location for the newly added object", -FLT_MAX, FLT_MAX); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + prop = RNA_def_float_rotation(ot->srna, "rotation", 3, NULL, -FLT_MAX, FLT_MAX, "Rotation", + "Rotation for the newly added object", (float)-M_PI * 2.0f, (float)M_PI * 2.0f); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); prop = RNA_def_boolean_layer_member(ot->srna, "layers", 20, NULL, "Layer", ""); - RNA_def_property_flag(prop, PROP_HIDDEN); + RNA_def_property_flag(prop, PROP_HIDDEN|PROP_SKIP_SAVE); } static void object_add_generic_invoke_options(bContext *C, wmOperator *op) { if(RNA_struct_find_property(op->ptr, "enter_editmode")) /* optional */ - if (!RNA_property_is_set(op->ptr, "enter_editmode")) + if (!RNA_struct_property_is_set(op->ptr, "enter_editmode")) RNA_boolean_set(op->ptr, "enter_editmode", U.flag & USER_ADD_EDITMODE); - if(!RNA_property_is_set(op->ptr, "location")) { + if(!RNA_struct_property_is_set(op->ptr, "location")) { float loc[3]; ED_object_location_from_view(C, loc); RNA_float_set_array(op->ptr, "location", loc); } - if(!RNA_property_is_set(op->ptr, "layers")) { + if(!RNA_struct_property_is_set(op->ptr, "layers")) { View3D *v3d = CTX_wm_view3d(C); Scene *scene = CTX_data_scene(C); int a, values[20], layer; - + if(v3d) { layer = (v3d->scenelock && !v3d->localvd)? scene->layact: v3d->layact; - - for(a=0; a<20; a++) - values[a]= (layer & (1<layact; + } - for(a=0; a<20; a++) - values[a]= (layer & (1<ptr, "layers", values); } } @@ -256,7 +261,7 @@ *enter_editmode = TRUE; } - if(RNA_property_is_set(op->ptr, "layers")) { + if(RNA_struct_property_is_set(op->ptr, "layers")) { RNA_boolean_get_array(op->ptr, "layers", layer_values); *layer= 0; for(a=0; a<20; a++) { @@ -277,9 +282,9 @@ if(v3d && v3d->localvd) *layer |= v3d->lay; - if(RNA_property_is_set(op->ptr, "rotation")) + if(RNA_struct_property_is_set(op->ptr, "rotation")) view_align = FALSE; - else if (RNA_property_is_set(op->ptr, "view_align")) + else if (RNA_struct_property_is_set(op->ptr, "view_align")) view_align = RNA_boolean_get(op->ptr, "view_align"); else { view_align = U.flag & USER_ADD_VIEWALIGNED; @@ -480,7 +485,7 @@ float loc[3], rot[3]; /* force view align for cameras */ - RNA_boolean_set(op->ptr, "view_align", 1); + RNA_boolean_set(op->ptr, "view_align", TRUE); object_add_generic_invoke_options(C, op); @@ -1050,11 +1055,17 @@ { ListBase *lb; DupliObject *dob; - + GHash *dupli_gh= NULL, *parent_gh= NULL; + if(!(base->object->transflag & OB_DUPLI)) return; lb= object_duplilist(scene, base->object); + + if(use_hierarchy || use_base_parent) { + dupli_gh= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "make_object_duplilist_real dupli_gh"); + parent_gh= BLI_ghash_new(BLI_ghashutil_pairhash, BLI_ghashutil_paircmp, "make_object_duplilist_real parent_gh"); + } for(dob= lb->first; dob; dob= dob->next) { Base *basen; @@ -1083,6 +1094,11 @@ copy_m4_m4(ob->obmat, dob->mat); object_apply_mat4(ob, ob->obmat, FALSE, FALSE); + + if(dupli_gh) + BLI_ghash_insert(dupli_gh, dob, ob); + if(parent_gh) + BLI_ghash_insert(parent_gh, BLI_ghashutil_pairalloc(dob->ob, dob->index), ob); } if (use_hierarchy) { @@ -1091,12 +1107,17 @@ Object *ob_src= dob->ob; Object *ob_src_par= ob_src->parent; - Object *ob_dst= (Object *)ob_src->id.newid; + Object *ob_dst= BLI_ghash_lookup(dupli_gh, dob); + Object *ob_dst_par= NULL; - if (ob_src_par && ob_src_par->id.newid) { - /* the parent was also made real, parent newly real duplis */ - Object *ob_dst_par= (Object *)ob_src_par->id.newid; + /* find parent that was also made real */ + if(ob_src_par) { + GHashPair *pair = BLI_ghashutil_pairalloc(ob_src_par, dob->index); + ob_dst_par = BLI_ghash_lookup(parent_gh, pair); + BLI_ghashutil_pairfree(pair); + } + if (ob_dst_par) { /* allow for all possible parent types */ ob_dst->partype= ob_src->partype; BLI_strncpy(ob_dst->parsubstr, ob_src->parsubstr, sizeof(ob_dst->parsubstr)); @@ -1130,8 +1151,7 @@ * base object */ for(dob= lb->first; dob; dob= dob->next) { /* original parents */ - Object *ob_src= dob->ob; - Object *ob_dst= (Object *)ob_src->id.newid; + Object *ob_dst= BLI_ghash_lookup(dupli_gh, dob); ob_dst->parent= base->object; ob_dst->partype= PAROBJECT; @@ -1145,6 +1165,11 @@ } } + if(dupli_gh) + BLI_ghash_free(dupli_gh, NULL, NULL); + if(parent_gh) + BLI_ghash_free(parent_gh, BLI_ghashutil_pairfree, NULL); + copy_object_set_idnew(C, 0); free_object_duplilist(lb); @@ -1767,8 +1792,22 @@ Key *key = ob_get_key(obn); if(dupflag & USER_DUP_ACT) { + bActuator *act; + BKE_copy_animdata_id_action((ID *)obn->data); - if(key) BKE_copy_animdata_id_action((ID*)key); + if(key) { + BKE_copy_animdata_id_action((ID*)key); + } + + /* Update the duplicated action in the action actuators */ + for (act = obn->actuators.first; act; act = act->next) { + if(act->type == ACT_ACTION) { + bActionActuator* actact = (bActionActuator*) act->data; + if(actact->act == ob->adt->action) { + actact->act = obn->adt->action; + } + } + } } if(dupflag & USER_DUP_MAT) { @@ -1895,7 +1934,7 @@ Object *ob; int linked= RNA_boolean_get(op->ptr, "linked"); int dupflag= (linked)? 0: U.dupflag; - char name[32]; + char name[MAX_ID_NAME-2]; /* find object, create fake base */ RNA_string_get(op->ptr, "name", name); @@ -1950,7 +1989,7 @@ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; RNA_def_boolean(ot->srna, "linked", 0, "Linked", "Duplicate object but not object data, linking to the original data"); - RNA_def_string(ot->srna, "name", "Cube", 24, "Name", "Object name to add"); + RNA_def_string(ot->srna, "name", "Cube", MAX_ID_NAME-2, "Name", "Object name to add"); } diff -Nru blender-2.61/source/blender/editors/object/object_bake.c blender-2.62/source/blender/editors/object/object_bake.c --- blender-2.61/source/blender/editors/object/object_bake.c 2011-12-13 19:54:35.000000000 +0000 +++ blender-2.62/source/blender/editors/object/object_bake.c 2012-02-15 19:38:48.000000000 +0000 @@ -807,10 +807,8 @@ ibuf->userflags= IB_RECT_INVALID; } else { - char *rrgb= (char*)ibuf->rect + pixel*4; - rrgb[0]= FTOCHAR(vec[0]); - rrgb[1]= FTOCHAR(vec[1]); - rrgb[2]= FTOCHAR(vec[2]); + unsigned char *rrgb= (unsigned char *)ibuf->rect + pixel*4; + rgb_float_to_uchar(rrgb, vec); rrgb[3]= 255; } } @@ -997,14 +995,13 @@ *lvl= mmd->lvl; if(*lvl==0) { - DerivedMesh *tmp_dm= CDDM_from_mesh(me, ob); - dm= CDDM_copy(tmp_dm); - tmp_dm->release(tmp_dm); + return NULL; } else { MultiresModifierData tmp_mmd= *mmd; DerivedMesh *cddm= CDDM_from_mesh(me, ob); tmp_mmd.lvl= *lvl; + tmp_mmd.sculptlvl= *lvl; dm= multires_dm_create_from_derived(&tmp_mmd, 1, cddm, ob, 0, 0); cddm->release(cddm); } @@ -1059,6 +1056,7 @@ { Object *ob; Scene *scene= CTX_data_scene(C); + int objects_baked= 0; if(!multiresbake_check(C, op)) return OPERATOR_CANCELLED; @@ -1089,6 +1087,10 @@ /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */ bkr.lores_dm= multiresbake_create_loresdm(scene, ob, &bkr.lvl); + + if(!bkr.lores_dm) + continue; + bkr.hires_dm= multiresbake_create_hiresdm(scene, ob, &bkr.tot_lvl, &bkr.simple); multiresbake_start(&bkr); @@ -1097,9 +1099,14 @@ bkr.lores_dm->release(bkr.lores_dm); bkr.hires_dm->release(bkr.hires_dm); + + objects_baked++; } CTX_DATA_END; + if(!objects_baked) + BKE_report(op->reports, RPT_ERROR, "No objects found to bake from"); + return OPERATOR_FINISHED; } @@ -1117,13 +1124,21 @@ CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { MultiresBakerJobData *data; + DerivedMesh *lores_dm; + int lvl; ob= base->object; multires_force_update(ob); + lores_dm = multiresbake_create_loresdm(scene, ob, &lvl); + if(!lores_dm) + continue; + data= MEM_callocN(sizeof(MultiresBakerJobData), "multiresBaker derivedMesh_data"); - data->lores_dm = multiresbake_create_loresdm(scene, ob, &data->lvl); + data->lores_dm = lores_dm; + data->lvl = lvl; data->hires_dm = multiresbake_create_hiresdm(scene, ob, &data->tot_lvl, &data->simple); + BLI_addtail(&bkj->data, data); } CTX_DATA_END; @@ -1206,6 +1221,11 @@ bkr= MEM_callocN(sizeof(MultiresBakeJob), "MultiresBakeJob data"); init_multiresbake_job(C, bkr); + if(!bkr->data.first) { + BKE_report(op->reports, RPT_ERROR, "No objects found to bake from"); + return OPERATOR_CANCELLED; + } + /* setup job */ steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Multires Bake", WM_JOB_EXCL_RENDER|WM_JOB_PRIORITY|WM_JOB_PROGRESS); WM_jobs_customdata(steve, bkr, multiresbake_freejob); @@ -1236,7 +1256,7 @@ Main *main; Scene *scene; struct Object *actob; - int tot, ready; + int result, ready; ReportList *reports; @@ -1309,7 +1329,7 @@ if(bkr->prev_r_raytrace == 0) bkr->scene->r.mode &= ~R_RAYTRACE; - if(bkr->tot) { + if(bkr->result==BAKE_RESULT_OK) { Image *ima; /* force OpenGL reload and mipmap recalc */ for(ima= G.main->image.first; ima; ima= ima->id.next) { @@ -1336,7 +1356,7 @@ { BakeRender *bkr= bake_v; - bkr->tot= RE_bake_shade_all_selected(bkr->re, bkr->scene->r.bake_mode, bkr->actob, NULL, bkr->progress); + bkr->result= RE_bake_shade_all_selected(bkr->re, bkr->scene->r.bake_mode, bkr->actob, NULL, bkr->progress); bkr->ready= 1; return NULL; @@ -1358,7 +1378,7 @@ RE_Database_Baking(bkr->re, bmain, scene, scene->lay, scene->r.bake_mode, bkr->actob); /* baking itself is threaded, cannot use test_break in threads. we also update optional imagewindow */ - bkr->tot= RE_bake_shade_all_selected(bkr->re, scene->r.bake_mode, bkr->actob, bkr->do_update, bkr->progress); + bkr->result= RE_bake_shade_all_selected(bkr->re, scene->r.bake_mode, bkr->actob, bkr->do_update, bkr->progress); } static void bake_update(void *bkv) @@ -1377,7 +1397,11 @@ BakeRender *bkr= bkv; finish_bake_internal(bkr); - if(bkr->tot==0) BKE_report(bkr->reports, RPT_ERROR, "No objects or images found to bake to"); + if(bkr->result==BAKE_RESULT_NO_OBJECTS) + BKE_report(bkr->reports, RPT_ERROR, "No objects or images found to bake to"); + else if(bkr->result==BAKE_RESULT_FEEDBACK_LOOP) + BKE_report(bkr->reports, RPT_WARNING, "Feedback loop detected"); + MEM_freeN(bkr); G.rendering = 0; } @@ -1494,7 +1518,10 @@ } BLI_end_threads(&threads); - if(bkr.tot==0) BKE_report(op->reports, RPT_ERROR, "No valid images found to bake to"); + if(bkr.result==BAKE_RESULT_NO_OBJECTS) + BKE_report(op->reports, RPT_ERROR, "No valid images found to bake to"); + else if(bkr.result==BAKE_RESULT_FEEDBACK_LOOP) + BKE_report(op->reports, RPT_ERROR, "Feedback loop detected"); finish_bake_internal(&bkr); diff -Nru blender-2.61/source/blender/editors/object/object_constraint.c blender-2.62/source/blender/editors/object/object_constraint.c --- blender-2.61/source/blender/editors/object/object_constraint.c 2011-12-13 19:54:35.000000000 +0000 +++ blender-2.62/source/blender/editors/object/object_constraint.c 2012-02-15 19:38:48.000000000 +0000 @@ -408,8 +408,21 @@ if((data->flag&CAMERASOLVER_ACTIVECLIP)==0) { if(data->clip != NULL && data->track[0]) { - if (!BKE_tracking_named_track(&data->clip->tracking, data->track)) + MovieTracking *tracking= &data->clip->tracking; + MovieTrackingObject *tracking_object; + + if(data->object[0]) + tracking_object= BKE_tracking_named_object(tracking, data->object); + else + tracking_object= BKE_tracking_get_camera_object(tracking); + + if(!tracking_object) { curcon->flag |= CONSTRAINT_DISABLE; + } + else { + if (!BKE_tracking_named_track(tracking, tracking_object, data->track)) + curcon->flag |= CONSTRAINT_DISABLE; + } } else curcon->flag |= CONSTRAINT_DISABLE; } @@ -420,6 +433,12 @@ if((data->flag&CAMERASOLVER_ACTIVECLIP)==0 && data->clip == NULL) curcon->flag |= CONSTRAINT_DISABLE; } + else if (curcon->type == CONSTRAINT_TYPE_OBJECTSOLVER) { + bObjectSolverConstraint *data = curcon->data; + + if((data->flag&CAMERASOLVER_ACTIVECLIP)==0 && data->clip == NULL) + curcon->flag |= CONSTRAINT_DISABLE; + } /* Check targets for constraints */ if (cti && cti->get_constraint_targets) { @@ -523,7 +542,7 @@ static void edit_constraint_properties(wmOperatorType *ot) { - RNA_def_string(ot->srna, "constraint", "", 32, "Constraint", "Name of the constraint to edit"); + RNA_def_string(ot->srna, "constraint", "", MAX_NAME, "Constraint", "Name of the constraint to edit"); RNA_def_enum(ot->srna, "owner", constraint_owner_items, 0, "Owner", "The owner of this constraint"); } @@ -534,7 +553,7 @@ bConstraint *con; ListBase *list; - if (RNA_property_is_set(op->ptr, "constraint") && RNA_property_is_set(op->ptr, "owner")) + if (RNA_struct_property_is_set(op->ptr, "constraint") && RNA_struct_property_is_set(op->ptr, "owner")) return 1; if (ptr.data) { @@ -556,7 +575,7 @@ static bConstraint *edit_constraint_property_get(wmOperator *op, Object *ob, int type) { - char constraint_name[32]; + char constraint_name[MAX_NAME]; int owner = RNA_enum_get(op->ptr, "owner"); bConstraint *con; ListBase *list=NULL; @@ -684,25 +703,13 @@ /* ------------- Child-Of Constraint ------------------ */ -/* ChildOf Constraint - set inverse callback */ -static int childof_set_inverse_exec (bContext *C, wmOperator *op) +static void child_get_inverse_matrix (Scene *scene, Object *ob, bConstraint *con, float invmat[4][4]) { - Scene *scene= CTX_data_scene(C); - Object *ob = ED_object_active_context(C); - bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_CHILDOF); - bChildOfConstraint *data= (con) ? (bChildOfConstraint *)con->data : NULL; bConstraint *lastcon = NULL; bPoseChannel *pchan= NULL; - /* despite 3 layers of checks, we may still not be able to find a constraint */ - if (data == NULL) { - printf("DEBUG: Child-Of Set Inverse - object = '%s'\n", (ob)? ob->id.name+2 : ""); - BKE_report(op->reports, RPT_ERROR, "Couldn't find constraint data for Child-Of Set Inverse"); - return OPERATOR_CANCELLED; - } - /* nullify inverse matrix first */ - unit_m4(data->invmat); + unit_m4(invmat); /* try to find a pose channel - assume that this is the constraint owner */ // TODO: get from context instead? @@ -747,8 +754,8 @@ * the effect of the constraint */ invert_m4_m4(imat, pchan->pose_mat); - mul_m4_m4m4(tmat, imat, pmat); - invert_m4_m4(data->invmat, tmat); + mult_m4_m4m4(tmat, pmat, imat); + invert_m4_m4(invmat, tmat); /* 5. restore constraints */ pchan->constraints.last = lastcon; @@ -770,9 +777,27 @@ /* use what_does_parent to find inverse - just like for normal parenting */ what_does_parent(scene, ob, &workob); - invert_m4_m4(data->invmat, workob.obmat); + invert_m4_m4(invmat, workob.obmat); + } +} + +/* ChildOf Constraint - set inverse callback */ +static int childof_set_inverse_exec (bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Object *ob = ED_object_active_context(C); + bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_CHILDOF); + bChildOfConstraint *data= (con) ? (bChildOfConstraint *)con->data : NULL; + + /* despite 3 layers of checks, we may still not be able to find a constraint */ + if (data == NULL) { + printf("DEBUG: Child-Of Set Inverse - object = '%s'\n", (ob)? ob->id.name+2 : ""); + BKE_report(op->reports, RPT_ERROR, "Couldn't find constraint data for Child-Of Set Inverse"); + return OPERATOR_CANCELLED; } + child_get_inverse_matrix(scene, ob, con, data->invmat); + WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob); return OPERATOR_FINISHED; @@ -846,6 +871,96 @@ edit_constraint_properties(ot); } +/* ------------- Object Solver Constraint ------------------ */ + +static int objectsolver_set_inverse_exec (bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Object *ob = ED_object_active_context(C); + bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_OBJECTSOLVER); + bObjectSolverConstraint *data= (con) ? (bObjectSolverConstraint *)con->data : NULL; + + /* despite 3 layers of checks, we may still not be able to find a constraint */ + if (data == NULL) { + printf("DEBUG: Child-Of Set Inverse - object = '%s'\n", (ob)? ob->id.name+2 : ""); + BKE_report(op->reports, RPT_ERROR, "Couldn't find constraint data for Child-Of Set Inverse"); + return OPERATOR_CANCELLED; + } + + child_get_inverse_matrix(scene, ob, con, data->invmat); + + WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob); + + return OPERATOR_FINISHED; +} + +static int objectsolver_set_inverse_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) +{ + if (edit_constraint_invoke_properties(C, op)) + return objectsolver_set_inverse_exec(C, op); + else + return OPERATOR_CANCELLED; +} + +void CONSTRAINT_OT_objectsolver_set_inverse (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Set Inverse"; + ot->idname= "CONSTRAINT_OT_objectsolver_set_inverse"; + ot->description= "Set inverse correction for ObjectSolver constraint"; + + ot->exec= objectsolver_set_inverse_exec; + ot->invoke= objectsolver_set_inverse_invoke; + ot->poll= edit_constraint_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + edit_constraint_properties(ot); +} + +static int objectsolver_clear_inverse_exec (bContext *C, wmOperator *op) +{ + Object *ob = ED_object_active_context(C); + bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_OBJECTSOLVER); + bObjectSolverConstraint *data= (con) ? (bObjectSolverConstraint *)con->data : NULL; + + if(data==NULL) { + BKE_report(op->reports, RPT_ERROR, "Childof constraint not found"); + return OPERATOR_CANCELLED; + } + + /* simply clear the matrix */ + unit_m4(data->invmat); + + WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob); + + return OPERATOR_FINISHED; +} + +static int objectsolver_clear_inverse_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) +{ + if (edit_constraint_invoke_properties(C, op)) + return objectsolver_clear_inverse_exec(C, op); + else + return OPERATOR_CANCELLED; +} + +void CONSTRAINT_OT_objectsolver_clear_inverse (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Clear Inverse"; + ot->idname= "CONSTRAINT_OT_objectsolver_clear_inverse"; + ot->description= "Clear inverse correction for ObjectSolver constraint"; + + ot->exec= objectsolver_clear_inverse_exec; + ot->invoke= objectsolver_clear_inverse_invoke; + ot->poll= edit_constraint_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + edit_constraint_properties(ot); +} + /***************************** BUTTONS ****************************/ void ED_object_constraint_set_active(Object *ob, bConstraint *con) diff -Nru blender-2.61/source/blender/editors/object/object_edit.c blender-2.62/source/blender/editors/object/object_edit.c --- blender-2.61/source/blender/editors/object/object_edit.c 2011-12-13 19:54:35.000000000 +0000 +++ blender-2.62/source/blender/editors/object/object_edit.c 2012-02-15 19:38:48.000000000 +0000 @@ -88,7 +88,7 @@ #include "ED_object.h" #include "ED_screen.h" #include "ED_util.h" - +#include "ED_image.h" #include "RNA_access.h" #include "RNA_define.h" @@ -108,9 +108,12 @@ static int pupmenu(const char *UNUSED(msg)) {return 0;} /* port over here */ -static bContext *evil_C; static void error_libdata(void) {} +Object *ED_object_context(bContext *C) +{ + return CTX_data_pointer_get_type(C, "object", &RNA_Object).data; +} /* find the correct active object per context * note: context can be NULL when called from a enum with PROP_ENUM_NO_CONTEXT */ @@ -118,7 +121,7 @@ { Object *ob= NULL; if(C) { - ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + ob= ED_object_context(C); if (!ob) ob= CTX_data_active_object(C); } return ob; @@ -318,9 +321,6 @@ // if(EM_texFaceCheck()) -// if(retopo_mesh_paint_check()) -// retopo_end_okee(); - if(me->edit_mesh->totvert>MESH_MAX_VERTS) { error("Too many vertices"); return; @@ -513,11 +513,15 @@ static int editmode_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { + ToolSettings *toolsettings = CTX_data_tool_settings(C); + if(!CTX_data_edit_object(C)) ED_object_enter_editmode(C, EM_WAITCURSOR); else ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* had EM_DO_UNDO but op flag calls undo too [#24685] */ + ED_space_image_uv_sculpt_update(CTX_wm_manager(C), toolsettings); + return OPERATOR_FINISHED; } @@ -592,366 +596,6 @@ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } -/* *********************** */ - -#if 0 -// XXX should be in view3d? - -/* context: ob = lamp */ -/* code should be replaced with proper (custom) transform handles for lamp properties */ -static void spot_interactive(Object *ob, int mode) -{ - Lamp *la= ob->data; - float transfac, dx, dy, ratio, origval; - int keep_running= 1, center2d[2]; - int mval[2], mvalo[2]; - -// getmouseco_areawin(mval); -// getmouseco_areawin(mvalo); - - project_int(ob->obmat[3], center2d); - if( center2d[0] > 100000 ) { /* behind camera */ -// center2d[0]= curarea->winx/2; -// center2d[1]= curarea->winy/2; - } - -// helpline(mval, center2d); - - /* ratio is like scaling */ - dx = (float)(center2d[0] - mval[0]); - dy = (float)(center2d[1] - mval[1]); - transfac = (float)sqrt( dx*dx + dy*dy); - if(transfac==0.0f) transfac= 1.0f; - - if(mode==1) - origval= la->spotsize; - else if(mode==2) - origval= la->dist; - else if(mode==3) - origval= la->clipsta; - else - origval= la->clipend; - - while (keep_running>0) { - -// getmouseco_areawin(mval); - - /* essential for idling subloop */ - if(mval[0]==mvalo[0] && mval[1]==mvalo[1]) { - PIL_sleep_ms(2); - } - else { - char str[32]; - - dx = (float)(center2d[0] - mval[0]); - dy = (float)(center2d[1] - mval[1]); - ratio = (float)(sqrt( dx*dx + dy*dy))/transfac; - - /* do the trick */ - - if(mode==1) { /* spot */ - la->spotsize = ratio*origval; - CLAMP(la->spotsize, 1.0f, 180.0f); - sprintf(str, "Spot size %.2f\n", la->spotsize); - } - else if(mode==2) { /* dist */ - la->dist = ratio*origval; - CLAMP(la->dist, 0.01f, 5000.0f); - sprintf(str, "Distance %.2f\n", la->dist); - } - else if(mode==3) { /* sta */ - la->clipsta = ratio*origval; - CLAMP(la->clipsta, 0.001f, 5000.0f); - sprintf(str, "Distance %.2f\n", la->clipsta); - } - else if(mode==4) { /* end */ - la->clipend = ratio*origval; - CLAMP(la->clipend, 0.1f, 5000.0f); - sprintf(str, "Clip End %.2f\n", la->clipend); - } - - /* cleanup */ - mvalo[0]= mval[0]; - mvalo[1]= mval[1]; - - /* handle shaded mode */ -// XXX shade_buttons_change_3d(); - - /* DRAW */ - headerprint(str); - force_draw_plus(SPACE_BUTS, 0); - -// helpline(mval, center2d); - } - - while( qtest() ) { - short val; - unsigned short event= extern_qread(&val); - - switch (event){ - case ESCKEY: - case RIGHTMOUSE: - keep_running= 0; - break; - case LEFTMOUSE: - case SPACEKEY: - case PADENTER: - case RETKEY: - if(val) - keep_running= -1; - break; - } - } - } - - if(keep_running==0) { - if(mode==1) - la->spotsize= origval; - else if(mode==2) - la->dist= origval; - else if(mode==3) - la->clipsta= origval; - else - la->clipend= origval; - } - -} -#endif - -static void UNUSED_FUNCTION(special_editmenu)(Scene *scene, View3D *v3d) -{ -// XXX static short numcuts= 2; - Object *ob= OBACT; - Object *obedit= NULL; // XXX - int nr,ret=0; - - if(ob==NULL) return; - - if(obedit==NULL) { - - if(ob->mode & OB_MODE_POSE) { -// XXX pose_special_editmenu(); - } - else if(paint_facesel_test(ob)) { - Mesh *me= get_mesh(ob); - MTFace *tface; - MFace *mface; - int a; - - if(me==NULL || me->mtface==NULL) return; - - nr= pupmenu("Specials%t|Set Tex%x1| Shared%x2| Light%x3| Invisible%x4| Collision%x5| TwoSide%x6|Clr Tex%x7| Shared%x8| Light%x9| Invisible%x10| Collision%x11| TwoSide%x12"); - - tface= me->mtface; - mface= me->mface; - for(a=me->totface; a>0; a--, tface++, mface++) { - if(mface->flag & ME_FACE_SEL) { - switch(nr) { - case 1: - tface->mode |= TF_TEX; break; - case 2: - tface->mode |= TF_SHAREDCOL; break; - case 3: - tface->mode |= TF_LIGHT; break; - case 4: - tface->mode |= TF_INVISIBLE; break; - case 5: - tface->mode |= TF_DYNAMIC; break; - case 6: - tface->mode |= TF_TWOSIDE; break; - case 7: - tface->mode &= ~TF_TEX; - tface->tpage= NULL; - break; - case 8: - tface->mode &= ~TF_SHAREDCOL; break; - case 9: - tface->mode &= ~TF_LIGHT; break; - case 10: - tface->mode &= ~TF_INVISIBLE; break; - case 11: - tface->mode &= ~TF_DYNAMIC; break; - case 12: - tface->mode &= ~TF_TWOSIDE; break; - } - } - } - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); - } - else if(ob->mode & OB_MODE_VERTEX_PAINT) { - Mesh *me= get_mesh(ob); - - if(me==NULL || (me->mcol==NULL && me->mtface==NULL) ) return; - - nr= pupmenu("Specials%t|Shared VertexCol%x1"); - if(nr==1) { - -// XXX do_shared_vertexcol(me); - - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); - } - } - else if(ob->mode & OB_MODE_WEIGHT_PAINT) { - Object *par= modifiers_isDeformedByArmature(ob); - - if(par && (par->mode & OB_MODE_POSE)) { -// XXX nr= pupmenu("Specials%t|Apply Bone Envelopes to Vertex Groups %x1|Apply Bone Heat Weights to Vertex Groups %x2"); - -// XXX if(nr==1 || nr==2) -// XXX pose_adds_vgroups(ob, (nr == 2)); - } - } - else if(ob->mode & OB_MODE_PARTICLE_EDIT) { -#if 0 - // XXX - ParticleSystem *psys = PE_get_current(ob); - ParticleEditSettings *pset = PE_settings(); - - if(!psys) - return; - - if(pset->selectmode & SCE_SELECT_POINT) - nr= pupmenu("Specials%t|Rekey%x1|Subdivide%x2|Select First%x3|Select Last%x4|Remove Doubles%x5"); - else - nr= pupmenu("Specials%t|Rekey%x1|Remove Doubles%x5"); - - switch(nr) { - case 1: -// XXX if(button(&pset->totrekey, 2, 100, "Number of Keys:")==0) return; - waitcursor(1); - PE_rekey(); - break; - case 2: - PE_subdivide(); - break; - case 3: - PE_select_root(); - break; - case 4: - PE_select_tip(); - break; - case 5: - PE_remove_doubles(); - break; - } - - DAG_id_tag_update(&obedit->id, OB_RECALC_DATA); - - if(nr>0) waitcursor(0); -#endif - } - else { - Base *base, *base_select= NULL; - - /* Get the active object mesh. */ - Mesh *me= get_mesh(ob); - - /* Booleans, if the active object is a mesh... */ - if (me && ob->id.lib==NULL) { - - /* Bring up a little menu with the boolean operation choices on. */ - nr= pupmenu("Boolean Tools%t|Intersect%x1|Union%x2|Difference%x3|Add Intersect Modifier%x4|Add Union Modifier%x5|Add Difference Modifier%x6"); - - if (nr > 0) { - /* user has made a choice of a menu element. - All of the boolean functions require 2 mesh objects - we search through the object list to find the other - selected item and make sure it is distinct and a mesh. */ - - for(base= FIRSTBASE; base; base= base->next) { - if(TESTBASELIB(v3d, base)) { - if(base->object != ob) base_select= base; - } - } - - if (base_select) { - if (get_mesh(base_select->object)) { - if(nr <= 3){ - waitcursor(1); -// XXX ret = NewBooleanMesh(BASACT,base_select,nr); - if (ret==0) { - error("An internal error occurred"); - } else if(ret==-1) { - error("Selected meshes must have faces to perform boolean operations"); - } else if (ret==-2) { - error("Both meshes must be a closed mesh"); - } - waitcursor(0); - } else { - BooleanModifierData *bmd = NULL; - bmd = (BooleanModifierData *)modifier_new(eModifierType_Boolean); - BLI_addtail(&ob->modifiers, bmd); - modifier_unique_name(&ob->modifiers, (ModifierData*)bmd); - bmd->object = base_select->object; - bmd->modifier.mode |= eModifierMode_Realtime; - switch(nr){ - case 4: bmd->operation = eBooleanModifierOp_Intersect; break; - case 5: bmd->operation = eBooleanModifierOp_Union; break; - case 6: bmd->operation = eBooleanModifierOp_Difference; break; - } -// XXX do_common_editbuts(B_CHANGEDEP); - } - } else { - error("Please select 2 meshes"); - } - } else { - error("Please select 2 meshes"); - } - } - - } - else if (ob->type == OB_FONT) { - /* removed until this gets a decent implementation (ton) */ -/* nr= pupmenu("Split %t|Characters%x1"); - if (nr > 0) { - switch(nr) { - case 1: split_font(); - } - } -*/ - } - } - } - else if(obedit->type==OB_MESH) { - } - else if(ELEM(obedit->type, OB_CURVE, OB_SURF)) { - } - else if(obedit->type==OB_ARMATURE) { - nr= pupmenu("Specials%t|Subdivide %x1|Subdivide Multi%x2|Switch Direction%x7|Flip Left-Right Names%x3|%l|AutoName Left-Right%x4|AutoName Front-Back%x5|AutoName Top-Bottom%x6"); -// if(nr==1) -// XXX subdivide_armature(1); - if(nr==2) { -// XXX if(button(&numcuts, 1, 128, "Number of Cuts:")==0) return; - waitcursor(1); -// XXX subdivide_armature(numcuts); - } -// else if(nr==3) -// XXX armature_flip_names(); - else if(ELEM3(nr, 4, 5, 6)) { -// XXX armature_autoside_names(nr-4); - } -// else if(nr == 7) -// XXX switch_direction_armature(); - } - else if(obedit->type==OB_LATTICE) { - Lattice *lt= obedit->data; - static float weight= 1.0f; - { // XXX -// XXX if(fbutton(&weight, 0.0f, 1.0f, 10, 10, "Set Weight")) { - Lattice *editlt= lt->editlatt->latt; - int a= editlt->pntsu*editlt->pntsv*editlt->pntsw; - BPoint *bp= editlt->def; - - while(a--) { - if(bp->f1 & SELECT) - bp->weight= weight; - bp++; - } - } - } - -} - static void copymenu_properties(Scene *scene, View3D *v3d, Object *ob) { //XXX no longer used - to be removed - replaced by game_properties_copy_exec @@ -1674,102 +1318,6 @@ } -static int vergbaseco(const void *a1, const void *a2) -{ - Base **x1, **x2; - - x1= (Base **) a1; - x2= (Base **) a2; - - if( (*x1)->sy > (*x2)->sy ) return 1; - else if( (*x1)->sy < (*x2)->sy) return -1; - else if( (*x1)->sx > (*x2)->sx ) return 1; - else if( (*x1)->sx < (*x2)->sx ) return -1; - - return 0; -} - - -static void UNUSED_FUNCTION(auto_timeoffs)(Scene *scene, View3D *v3d) -{ - Base *base, **basesort, **bs; - float start, delta; - int tot=0, a; - short offset=25; - - if(BASACT==NULL || v3d==NULL) return; -// XXX if(button(&offset, 0, 1000,"Total time")==0) return; - - /* make array of all bases, xco yco (screen) */ - for(base= FIRSTBASE; base; base= base->next) { - if(TESTBASELIB(v3d, base)) { - tot++; - } - } - - delta= (float)offset/(float)tot; - start= OBACT->sf; - - bs= basesort= MEM_mallocN(sizeof(void *)*tot,"autotimeoffs"); - for(base= FIRSTBASE; base; base= base->next) { - if(TESTBASELIB(v3d, base)) { - *bs= base; - bs++; - } - } - qsort(basesort, tot, sizeof(void *), vergbaseco); - - bs= basesort; - for(a=0; aobject->sf= start; - start+= delta; - - bs++; - } - MEM_freeN(basesort); - -} - -static void UNUSED_FUNCTION(ofs_timeoffs)(Scene *scene, View3D *v3d) -{ - float offset=0.0f; - - if(BASACT==NULL || v3d==NULL) return; - -// XXX if(fbutton(&offset, -10000.0f, 10000.0f, 10, 10, "Offset")==0) return; - - /* make array of all bases, xco yco (screen) */ - CTX_DATA_BEGIN(evil_C, Object*, ob, selected_editable_objects) { - ob->sf += offset; - if (ob->sf < -MAXFRAMEF) ob->sf = -MAXFRAMEF; - else if (ob->sf > MAXFRAMEF) ob->sf = MAXFRAMEF; - } - CTX_DATA_END; - -} - - -static void UNUSED_FUNCTION(rand_timeoffs)(Scene *scene, View3D *v3d) -{ - Base *base; - float rand_ofs=0.0f; - - if(BASACT==NULL || v3d==NULL) return; - -// XXX if(fbutton(&rand_ofs, 0.0f, 10000.0f, 10, 10, "Randomize")==0) return; - - rand_ofs *= 2; - - for(base= FIRSTBASE; base; base= base->next) { - if(TESTBASELIB(v3d, base)) { - base->object->sf += ((float)BLI_drand()-0.5f) * rand_ofs; - if (base->object->sf < -MAXFRAMEF) base->object->sf = -MAXFRAMEF; - else if (base->object->sf > MAXFRAMEF) base->object->sf = MAXFRAMEF; - } - } - -} static EnumPropertyItem *object_mode_set_itemsf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free) { @@ -1932,16 +1480,21 @@ /************************ Game Properties ***********************/ -static int game_property_new(bContext *C, wmOperator *UNUSED(op)) +static int game_property_new(bContext *C, wmOperator *op) { Object *ob= CTX_data_active_object(C); bProperty *prop; + char name[MAX_NAME]; + int type= RNA_enum_get(op->ptr, "type"); - if(!ob) - return OPERATOR_CANCELLED; - - prop= new_property(PROP_FLOAT); + prop= new_property(type); BLI_addtail(&ob->prop, prop); + + RNA_string_get(op->ptr, "name", name); + if (name[0] != '\0') { + BLI_strncpy(prop->name, name, sizeof(prop->name)); + } + unique_property(NULL, prop, 0); // make_unique_prop_names(prop->name); WM_event_add_notifier(C, NC_LOGIC, NULL); @@ -1962,6 +1515,9 @@ /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_enum(ot->srna, "type", gameproperty_type_items, GPROP_FLOAT, "Type", "Type of game property to add"); + RNA_def_string(ot->srna, "name", "", MAX_NAME, "Name", "Name of the game property to add"); } static int game_property_remove(bContext *C, wmOperator *op) @@ -2178,3 +1734,51 @@ /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } + +static int game_physics_copy_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *ob=ED_object_active_context(C); + + CTX_DATA_BEGIN(C, Object*, ob_iter, selected_editable_objects) { + if(ob != ob_iter) { + ob_iter->gameflag = ob->gameflag; + ob_iter->gameflag2 = ob->gameflag2; + ob_iter->inertia = ob->inertia; + ob_iter->formfactor = ob->formfactor;; + ob_iter->damping = ob->damping; + ob_iter->rdamping = ob->rdamping; + ob_iter->min_vel = ob->min_vel; + ob_iter->max_vel = ob->max_vel; + ob_iter->obstacleRad = ob->obstacleRad; + ob_iter->mass = ob->mass; + ob_iter->anisotropicFriction[0] = ob->anisotropicFriction[0]; + ob_iter->anisotropicFriction[1] = ob->anisotropicFriction[1]; + ob_iter->anisotropicFriction[2] = ob->anisotropicFriction[2]; + ob_iter->collision_boundtype = ob->collision_boundtype; + ob_iter->margin = ob->margin; + ob_iter->bsoft = copy_bulletsoftbody(ob->bsoft); + if(ob->restrictflag & OB_RESTRICT_RENDER) + ob_iter->restrictflag |= OB_RESTRICT_RENDER; + else + ob_iter->restrictflag &= ~OB_RESTRICT_RENDER; + } + } + CTX_DATA_END; + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_game_physics_copy(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Copy Game Physics Properties to Selected"; + ot->description = "Copy game physics properties to other selected objects"; + ot->idname= "OBJECT_OT_game_physics_copy"; + + /* api callbacks */ + ot->exec= game_physics_copy_exec; + ot->poll= ED_operator_object_active_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} diff -Nru blender-2.61/source/blender/editors/object/object_group.c blender-2.62/source/blender/editors/object/object_group.c --- blender-2.61/source/blender/editors/object/object_group.c 2011-12-13 19:54:35.000000000 +0000 +++ blender-2.62/source/blender/editors/object/object_group.c 2012-02-15 19:38:48.000000000 +0000 @@ -46,6 +46,7 @@ #include "BKE_report.h" #include "ED_screen.h" +#include "ED_object.h" #include "WM_api.h" #include "WM_types.h" @@ -191,7 +192,7 @@ Main *bmain= CTX_data_main(C); Scene *scene= CTX_data_scene(C); Group *group= NULL; - char name[32]; /* id name */ + char name[MAX_ID_NAME-2]; /* id name */ RNA_string_get(op->ptr, "name", name); @@ -222,7 +223,7 @@ /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - RNA_def_string(ot->srna, "name", "Group", 32, "Name", "Name of the new group"); + RNA_def_string(ot->srna, "name", "Group", MAX_ID_NAME-2, "Name", "Name of the new group"); } /****************** properties window operators *********************/ @@ -230,7 +231,7 @@ static int group_add_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); Group *group; if(ob == NULL) @@ -261,7 +262,7 @@ static int group_link_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); Group *group= BLI_findlink(&CTX_data_main(C)->group, RNA_enum_get(op->ptr, "group")); if(ELEM(NULL, ob, group)) @@ -299,7 +300,7 @@ static int group_remove_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); Group *group= CTX_data_pointer_get_type(C, "group", &RNA_Group).data; if(!ob || !group) diff -Nru blender-2.61/source/blender/editors/object/object_hook.c blender-2.62/source/blender/editors/object/object_hook.c --- blender-2.61/source/blender/editors/object/object_hook.c 2011-12-13 19:54:35.000000000 +0000 +++ blender-2.62/source/blender/editors/object/object_hook.c 2012-02-15 19:38:48.000000000 +0000 @@ -428,7 +428,7 @@ HookModifierData *hmd = NULL; float cent[3]; int tot, ok, *indexar; - char name[32]; + char name[MAX_NAME]; ok = object_hook_index_array(scene, obedit, &tot, &indexar, name, cent); @@ -646,7 +646,7 @@ float imat[4][4], mat[4][4]; /* calculate the world-space matrix for the pose-channel target first, then carry on as usual */ - mul_m4_m4m4(mat, pchan->pose_mat, hmd->object->obmat); + mult_m4_m4m4(mat, hmd->object->obmat, pchan->pose_mat); invert_m4_m4(imat, mat); mul_serie_m4(hmd->parentinv, imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL); @@ -747,7 +747,7 @@ Object *ob=NULL; HookModifierData *hmd=NULL; float cent[3]; - char name[32]; + char name[MAX_NAME]; int *indexar, tot; if (ptr.data) { /* if modifier context is available, use that */ diff -Nru blender-2.61/source/blender/editors/object/object_intern.h blender-2.62/source/blender/editors/object/object_intern.h --- blender-2.61/source/blender/editors/object/object_intern.h 2011-12-13 19:54:35.000000000 +0000 +++ blender-2.62/source/blender/editors/object/object_intern.h 2012-02-15 19:38:48.000000000 +0000 @@ -92,17 +92,16 @@ void OBJECT_OT_game_property_copy(struct wmOperatorType *ot); void OBJECT_OT_game_property_clear(struct wmOperatorType *ot); void OBJECT_OT_logic_bricks_copy(struct wmOperatorType *ot); +void OBJECT_OT_game_physics_copy(struct wmOperatorType *ot); /* object_select.c */ void OBJECT_OT_select_all(struct wmOperatorType *ot); -void OBJECT_OT_select_inverse(struct wmOperatorType *ot); void OBJECT_OT_select_random(struct wmOperatorType *ot); void OBJECT_OT_select_by_type(struct wmOperatorType *ot); void OBJECT_OT_select_by_layer(struct wmOperatorType *ot); void OBJECT_OT_select_linked(struct wmOperatorType *ot); void OBJECT_OT_select_grouped(struct wmOperatorType *ot); void OBJECT_OT_select_mirror(struct wmOperatorType *ot); -void OBJECT_OT_select_name(struct wmOperatorType *ot); void OBJECT_OT_select_same_group(struct wmOperatorType *ot); /* object_add.c */ @@ -185,6 +184,8 @@ void CONSTRAINT_OT_limitdistance_reset(struct wmOperatorType *ot); void CONSTRAINT_OT_childof_set_inverse(struct wmOperatorType *ot); void CONSTRAINT_OT_childof_clear_inverse(struct wmOperatorType *ot); +void CONSTRAINT_OT_objectsolver_set_inverse(struct wmOperatorType *ot); +void CONSTRAINT_OT_objectsolver_clear_inverse (struct wmOperatorType *ot); /* object_vgroup.c */ void OBJECT_OT_vertex_group_add(struct wmOperatorType *ot); diff -Nru blender-2.61/source/blender/editors/object/object_modifier.c blender-2.62/source/blender/editors/object/object_modifier.c --- blender-2.61/source/blender/editors/object/object_modifier.c 2011-12-13 19:54:35.000000000 +0000 +++ blender-2.62/source/blender/editors/object/object_modifier.c 2012-02-15 19:38:48.000000000 +0000 @@ -452,7 +452,7 @@ Key *key=me->key; KeyBlock *kb; - if(!modifier_sameTopology(md)) { + if(!modifier_sameTopology(md) || mti->type == eModifierTypeType_NonGeometrical) { BKE_report(reports, RPT_ERROR, "Only deforming modifiers can be applied to Shapes"); return 0; } @@ -500,7 +500,7 @@ Mesh *me = ob->data; MultiresModifierData *mmd= find_multires_modifier_before(scene, md); - if( me->key) { + if(me->key && mti->type != eModifierTypeType_NonGeometrical) { BKE_report(reports, RPT_ERROR, "Modifier cannot be applied to Mesh with Shape Keys"); return 0; } @@ -536,7 +536,7 @@ int numVerts; float (*vertexCos)[3]; - if (mti->type==eModifierTypeType_Constructive) { + if (ELEM(mti->type, eModifierTypeType_Constructive, eModifierTypeType_Nonconstructive)) { BKE_report(reports, RPT_ERROR, "Cannot apply constructive modifiers on curve"); return 0; } @@ -643,7 +643,7 @@ static EnumPropertyItem *modifier_add_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free) { Object *ob= ED_object_active_context(C); - EnumPropertyItem *item= NULL, *md_item; + EnumPropertyItem *item= NULL, *md_item, *group_item= NULL; ModifierTypeInfo *mti; int totitem= 0, a; @@ -663,6 +663,17 @@ (ob->type==OB_MESH && (mti->flags & eModifierTypeFlag_AcceptsMesh)))) continue; } + else { + group_item= md_item; + md_item= NULL; + + continue; + } + + if(group_item) { + RNA_enum_item_add(&item, &totitem, group_item); + group_item= NULL; + } RNA_enum_item_add(&item, &totitem, md_item); } @@ -717,7 +728,7 @@ static void edit_modifier_properties(wmOperatorType *ot) { - RNA_def_string(ot->srna, "modifier", "", 32, "Modifier", "Name of the modifier to edit"); + RNA_def_string(ot->srna, "modifier", "", MAX_NAME, "Modifier", "Name of the modifier to edit"); } static int edit_modifier_invoke_properties(bContext *C, wmOperator *op) @@ -725,7 +736,7 @@ PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier); ModifierData *md; - if (RNA_property_is_set(op->ptr, "modifier")) + if (RNA_struct_property_is_set(op->ptr, "modifier")) return 1; if (ptr.data) { @@ -739,7 +750,7 @@ static ModifierData *edit_modifier_property_get(wmOperator *op, Object *ob, int type) { - char modifier_name[32]; + char modifier_name[MAX_NAME]; ModifierData *md; RNA_string_get(op->ptr, "modifier", modifier_name); @@ -1198,7 +1209,7 @@ if(CustomData_external_test(&me->fdata, CD_MDISPS)) return OPERATOR_CANCELLED; - if(RNA_property_is_set(op->ptr, "filepath")) + if(RNA_struct_property_is_set(op->ptr, "filepath")) return multires_external_save_exec(C, op); op->customdata= me; @@ -1225,7 +1236,7 @@ /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - WM_operator_properties_filesel(ot, FOLDERFILE|BTXFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH); + WM_operator_properties_filesel(ot, FOLDERFILE|BTXFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); edit_modifier_properties(ot); } diff -Nru blender-2.61/source/blender/editors/object/object_ops.c blender-2.62/source/blender/editors/object/object_ops.c --- blender-2.61/source/blender/editors/object/object_ops.c 2011-12-13 19:54:35.000000000 +0000 +++ blender-2.62/source/blender/editors/object/object_ops.c 2012-02-15 19:38:48.000000000 +0000 @@ -94,7 +94,6 @@ WM_operatortype_append(OBJECT_OT_make_links_data); WM_operatortype_append(OBJECT_OT_move_to_layer); - WM_operatortype_append(OBJECT_OT_select_inverse); WM_operatortype_append(OBJECT_OT_select_random); WM_operatortype_append(OBJECT_OT_select_all); WM_operatortype_append(OBJECT_OT_select_same_group); @@ -103,7 +102,6 @@ WM_operatortype_append(OBJECT_OT_select_linked); WM_operatortype_append(OBJECT_OT_select_grouped); WM_operatortype_append(OBJECT_OT_select_mirror); - WM_operatortype_append(OBJECT_OT_select_name); /* XXX - weak, not compat with linked objects */ WM_operatortype_append(GROUP_OT_create); WM_operatortype_append(GROUP_OT_objects_remove); @@ -161,6 +159,8 @@ WM_operatortype_append(CONSTRAINT_OT_limitdistance_reset); WM_operatortype_append(CONSTRAINT_OT_childof_set_inverse); WM_operatortype_append(CONSTRAINT_OT_childof_clear_inverse); + WM_operatortype_append(CONSTRAINT_OT_objectsolver_set_inverse); + WM_operatortype_append(CONSTRAINT_OT_objectsolver_clear_inverse); WM_operatortype_append(OBJECT_OT_vertex_group_add); WM_operatortype_append(OBJECT_OT_vertex_group_remove); @@ -189,6 +189,7 @@ WM_operatortype_append(OBJECT_OT_game_property_copy); WM_operatortype_append(OBJECT_OT_game_property_clear); WM_operatortype_append(OBJECT_OT_logic_bricks_copy); + WM_operatortype_append(OBJECT_OT_game_physics_copy); WM_operatortype_append(OBJECT_OT_shape_key_add); WM_operatortype_append(OBJECT_OT_shape_key_remove); @@ -234,7 +235,7 @@ if(ot) { ot->description = "Duplicate selected objects and move them"; otmacro= WM_operatortype_macro_define(ot, "OBJECT_OT_duplicate"); - RNA_boolean_set(otmacro->ptr, "linked", 1); + RNA_boolean_set(otmacro->ptr, "linked", TRUE); otmacro= WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); RNA_enum_set(otmacro->ptr, "proportional", PROP_EDIT_OFF); } @@ -243,7 +244,7 @@ ot= WM_operatortype_append_macro("OBJECT_OT_add_named_cursor", "Add named object at cursor", OPTYPE_UNDO|OPTYPE_REGISTER); if(ot) { ot->description = "Add named object at cursor"; - RNA_def_string(ot->srna, "name", "Cube", 24, "Name", "Object name to add"); + RNA_def_string(ot->srna, "name", "Cube", MAX_ID_NAME-2, "Name", "Object name to add"); WM_operatortype_macro_define(ot, "VIEW3D_OT_cursor3d"); WM_operatortype_macro_define(ot, "OBJECT_OT_add_named"); @@ -267,20 +268,20 @@ /* Note: this keymap works disregarding mode */ kmi = WM_keymap_add_item(keymap, "OBJECT_OT_mode_set", TABKEY, KM_PRESS, 0, 0); - RNA_enum_set(kmi->ptr, "mode", OB_MODE_EDIT); - RNA_boolean_set(kmi->ptr, "toggle", 1); + RNA_enum_set(kmi->ptr, "mode", OB_MODE_EDIT); + RNA_boolean_set(kmi->ptr, "toggle", TRUE); kmi = WM_keymap_add_item(keymap, "OBJECT_OT_mode_set", TABKEY, KM_PRESS, KM_CTRL, 0); - RNA_enum_set(kmi->ptr, "mode", OB_MODE_POSE); - RNA_boolean_set(kmi->ptr, "toggle", 1); + RNA_enum_set(kmi->ptr, "mode", OB_MODE_POSE); + RNA_boolean_set(kmi->ptr, "toggle", TRUE); kmi = WM_keymap_add_item(keymap, "OBJECT_OT_mode_set", VKEY, KM_PRESS, 0, 0); - RNA_enum_set(kmi->ptr, "mode", OB_MODE_VERTEX_PAINT); - RNA_boolean_set(kmi->ptr, "toggle", 1); + RNA_enum_set(kmi->ptr, "mode", OB_MODE_VERTEX_PAINT); + RNA_boolean_set(kmi->ptr, "toggle", TRUE); kmi = WM_keymap_add_item(keymap, "OBJECT_OT_mode_set", TABKEY, KM_PRESS, KM_CTRL, 0); - RNA_enum_set(kmi->ptr, "mode", OB_MODE_WEIGHT_PAINT); - RNA_boolean_set(kmi->ptr, "toggle", 1); + RNA_enum_set(kmi->ptr, "mode", OB_MODE_WEIGHT_PAINT); + RNA_boolean_set(kmi->ptr, "toggle", TRUE); WM_keymap_add_item(keymap, "OBJECT_OT_origin_set", CKEY, KM_PRESS, KM_ALT|KM_SHIFT|KM_CTRL, 0); @@ -294,23 +295,30 @@ WM_keymap_add_item(keymap, "VIEW3D_OT_game_start", PKEY, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "OBJECT_OT_select_all", AKEY, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "OBJECT_OT_select_inverse", IKEY, KM_PRESS, KM_CTRL, 0); + kmi = WM_keymap_add_item(keymap, "OBJECT_OT_select_all", AKEY, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE); + kmi = WM_keymap_add_item(keymap, "OBJECT_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0); + RNA_enum_set(kmi->ptr, "action", SEL_INVERT); + WM_keymap_add_item(keymap, "OBJECT_OT_select_linked", LKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "OBJECT_OT_select_grouped", GKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "OBJECT_OT_select_mirror", MKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0); - kmi= WM_keymap_add_item(keymap, "OBJECT_OT_select_hierarchy", LEFTBRACKETKEY, KM_PRESS, 0, 0); - RNA_enum_set_identifier(kmi->ptr, "direction", "PARENT"); - kmi= WM_keymap_add_item(keymap, "OBJECT_OT_select_hierarchy", LEFTBRACKETKEY, KM_PRESS, KM_SHIFT, 0); - RNA_enum_set_identifier(kmi->ptr, "direction", "PARENT"); - RNA_boolean_set(kmi->ptr, "extend", 1); - - kmi= WM_keymap_add_item(keymap, "OBJECT_OT_select_hierarchy", RIGHTBRACKETKEY, KM_PRESS, 0, 0); - RNA_enum_set_identifier(kmi->ptr, "direction", "CHILD"); - kmi= WM_keymap_add_item(keymap, "OBJECT_OT_select_hierarchy", RIGHTBRACKETKEY, KM_PRESS, KM_SHIFT, 0); - RNA_enum_set_identifier(kmi->ptr, "direction", "CHILD"); - RNA_boolean_set(kmi->ptr, "extend", 1); + kmi = WM_keymap_add_item(keymap, "OBJECT_OT_select_hierarchy", LEFTBRACKETKEY, KM_PRESS, 0, 0); + RNA_enum_set_identifier(kmi->ptr, "direction", "PARENT"); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + + kmi = WM_keymap_add_item(keymap, "OBJECT_OT_select_hierarchy", LEFTBRACKETKEY, KM_PRESS, KM_SHIFT, 0); + RNA_enum_set_identifier(kmi->ptr, "direction", "PARENT"); + RNA_boolean_set(kmi->ptr, "extend", TRUE); + + kmi = WM_keymap_add_item(keymap, "OBJECT_OT_select_hierarchy", RIGHTBRACKETKEY, KM_PRESS, 0, 0); + RNA_enum_set_identifier(kmi->ptr, "direction", "CHILD"); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + + kmi = WM_keymap_add_item(keymap, "OBJECT_OT_select_hierarchy", RIGHTBRACKETKEY, KM_PRESS, KM_SHIFT, 0); + RNA_enum_set_identifier(kmi->ptr, "direction", "CHILD"); + RNA_boolean_set(kmi->ptr, "extend", TRUE); WM_keymap_verify_item(keymap, "OBJECT_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_verify_item(keymap, "OBJECT_OT_parent_no_inverse_set", PKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0); @@ -327,20 +335,34 @@ WM_keymap_verify_item(keymap, "OBJECT_OT_origin_clear", OKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_clear", HKEY, KM_PRESS, KM_ALT, 0); - WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_set", HKEY, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_set", HKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "unselected", 1); + kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_set", HKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "unselected", FALSE); + + kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_set", HKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "unselected", TRUE); /* same as above but for rendering */ WM_keymap_add_item(keymap, "OBJECT_OT_hide_render_clear", HKEY, KM_PRESS, KM_ALT|KM_CTRL, 0); WM_keymap_add_item(keymap, "OBJECT_OT_hide_render_set", HKEY, KM_PRESS, KM_CTRL, 0); -// RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_hide_render_set", HKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0)->ptr, "unselected", 1); // conflicts, removing + + /* conflicts, removing */ +#if 0 + kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_render_set", HKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0) + RNA_boolean_set(kmi->ptr, "unselected", TRUE); +#endif WM_keymap_add_item(keymap, "OBJECT_OT_move_to_layer", MKEY, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "OBJECT_OT_delete", XKEY, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_delete", XKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "use_global", TRUE); + kmi = WM_keymap_add_item(keymap, "OBJECT_OT_delete", XKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "use_global", FALSE); + + kmi = WM_keymap_add_item(keymap, "OBJECT_OT_delete", XKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "use_global", TRUE); + WM_keymap_add_item(keymap, "OBJECT_OT_delete", DELKEY, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_delete", DELKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "use_global", TRUE); + RNA_boolean_set(kmi->ptr, "use_global", FALSE); + kmi = WM_keymap_add_item(keymap, "OBJECT_OT_delete", DELKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "use_global", TRUE); WM_keymap_add_menu(keymap, "INFO_MT_add", AKEY, KM_PRESS, KM_SHIFT, 0); @@ -386,7 +408,7 @@ WM_keymap_add_item(keymap, "OBJECT_OT_vertex_parent_set", PKEY, KM_PRESS, KM_CTRL, 0); - /* menus */ + /* menus */ WM_keymap_add_menu(keymap, "VIEW3D_MT_hook", HKEY, KM_PRESS, KM_CTRL, 0); ED_object_generic_keymap(keyconf, keymap, 2); diff -Nru blender-2.61/source/blender/editors/object/object_relations.c blender-2.62/source/blender/editors/object/object_relations.c --- blender-2.61/source/blender/editors/object/object_relations.c 2011-12-13 19:54:35.000000000 +0000 +++ blender-2.62/source/blender/editors/object/object_relations.c 2012-02-15 19:38:48.000000000 +0000 @@ -300,7 +300,7 @@ uiLayout *layout= uiPupMenuLayout(pup); /* create operator menu item with relevant properties filled in */ - uiItemFullO(layout, op->idname, op->type->name, ICON_NONE, NULL, WM_OP_EXEC_REGION_WIN, UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr(layout, op->type, op->type->name, ICON_NONE, NULL, WM_OP_EXEC_REGION_WIN, UI_ITEM_O_RETURN_PROPS); /* present the menu and be done... */ uiPupMenuEnd(C, pup); @@ -335,7 +335,7 @@ if (ob) { Object *newob; Base *newbase, *oldbase= BASACT; - char name[32]; + char name[MAX_ID_NAME+4]; /* Add new object for the proxy */ newob= add_object(scene, OB_EMPTY); @@ -421,43 +421,47 @@ /********************** Clear Parent Operator ******************* */ -static EnumPropertyItem prop_clear_parent_types[] = { +EnumPropertyItem prop_clear_parent_types[] = { {0, "CLEAR", 0, "Clear Parent", ""}, {1, "CLEAR_KEEP_TRANSFORM", 0, "Clear and Keep Transformation", ""}, {2, "CLEAR_INVERSE", 0, "Clear Parent Inverse", ""}, {0, NULL, 0, NULL, NULL} }; -/* note, poll should check for editable scene */ -static int parent_clear_exec(bContext *C, wmOperator *op) +void ED_object_parent_clear(bContext *C, int type) { Main *bmain= CTX_data_main(C); Scene *scene= CTX_data_scene(C); - int type= RNA_enum_get(op->ptr, "type"); - - CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { + CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) + { if(ob->parent == NULL) continue; if(type == 0) { ob->parent= NULL; - } + } else if(type == 1) { ob->parent= NULL; object_apply_mat4(ob, ob->obmat, TRUE, FALSE); } else if(type == 2) unit_m4(ob->parentinv); - + ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME; } CTX_DATA_END; - + DAG_scene_sort(bmain, scene); DAG_ids_flush_update(bmain, 0); WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); WM_event_add_notifier(C, NC_OBJECT|ND_PARENT, NULL); +} + +/* note, poll should check for editable scene */ +static int parent_clear_exec(bContext *C, wmOperator *op) +{ + ED_object_parent_clear(C, RNA_enum_get(op->ptr, "type")); return OPERATOR_FINISHED; } @@ -483,48 +487,9 @@ /* ******************** Make Parent Operator *********************** */ -#define PAR_OBJECT 0 -#define PAR_ARMATURE 1 -#define PAR_ARMATURE_NAME 2 -#define PAR_ARMATURE_ENVELOPE 3 -#define PAR_ARMATURE_AUTO 4 -#define PAR_BONE 5 -#define PAR_CURVE 6 -#define PAR_FOLLOW 7 -#define PAR_PATH_CONST 8 -#define PAR_LATTICE 9 -#define PAR_VERTEX 10 -#define PAR_TRIA 11 - -static EnumPropertyItem prop_make_parent_types[] = { - {PAR_OBJECT, "OBJECT", 0, "Object", ""}, - {PAR_ARMATURE, "ARMATURE", 0, "Armature Deform", ""}, - {PAR_ARMATURE_NAME, "ARMATURE_NAME", 0, " With Empty Groups", ""}, - {PAR_ARMATURE_AUTO, "ARMATURE_AUTO", 0, " With Automatic Weights", ""}, - {PAR_ARMATURE_ENVELOPE, "ARMATURE_ENVELOPE", 0, " With Envelope Weights", ""}, - {PAR_BONE, "BONE", 0, "Bone", ""}, - {PAR_CURVE, "CURVE", 0, "Curve Deform", ""}, - {PAR_FOLLOW, "FOLLOW", 0, "Follow Path", ""}, - {PAR_PATH_CONST, "PATH_CONST", 0, "Path Constraint", ""}, - {PAR_LATTICE, "LATTICE", 0, "Lattice Deform", ""}, - {PAR_VERTEX, "VERTEX", 0, "Vertex", ""}, - {PAR_TRIA, "TRIA", 0, "Triangle", ""}, - {0, NULL, 0, NULL, NULL} -}; - -static int test_parent_loop(Object *par, Object *ob) -{ - /* test if 'ob' is a parent somewhere in par's parents */ - - if(par == NULL) return 0; - if(ob == par) return 1; - - return test_parent_loop(par->parent, ob); -} - void ED_object_parent(Object *ob, Object *par, int type, const char *substr) { - if(!par || test_parent_loop(par, ob)) { + if (!par || BKE_object_parent_loop_check(par, ob)) { ob->parent= NULL; ob->partype= PAROBJECT; ob->parsubstr[0]= 0; @@ -539,13 +504,28 @@ BLI_strncpy(ob->parsubstr, substr, sizeof(ob->parsubstr)); } -static int parent_set_exec(bContext *C, wmOperator *op) +/* Operator Property */ +EnumPropertyItem prop_make_parent_types[] = { + {PAR_OBJECT, "OBJECT", 0, "Object", ""}, + {PAR_ARMATURE, "ARMATURE", 0, "Armature Deform", ""}, + {PAR_ARMATURE_NAME, "ARMATURE_NAME", 0, " With Empty Groups", ""}, + {PAR_ARMATURE_AUTO, "ARMATURE_AUTO", 0, " With Automatic Weights", ""}, + {PAR_ARMATURE_ENVELOPE, "ARMATURE_ENVELOPE", 0, " With Envelope Weights", ""}, + {PAR_BONE, "BONE", 0, "Bone", ""}, + {PAR_CURVE, "CURVE", 0, "Curve Deform", ""}, + {PAR_FOLLOW, "FOLLOW", 0, "Follow Path", ""}, + {PAR_PATH_CONST, "PATH_CONST", 0, "Path Constraint", ""}, + {PAR_LATTICE, "LATTICE", 0, "Lattice Deform", ""}, + {PAR_VERTEX, "VERTEX", 0, "Vertex", ""}, + {PAR_TRIA, "TRIA", 0, "Triangle", ""}, + {0, NULL, 0, NULL, NULL} +}; + +int ED_object_parent_set(bContext *C, wmOperator *op, Object *par, int partype) { Main *bmain= CTX_data_main(C); Scene *scene= CTX_data_scene(C); - Object *par= ED_object_active_context(C); bPoseChannel *pchan= NULL; - int partype= RNA_enum_get(op->ptr, "type"); int pararm= ELEM4(partype, PAR_ARMATURE, PAR_ARMATURE_NAME, PAR_ARMATURE_ENVELOPE, PAR_ARMATURE_AUTO); par->recalc |= OB_RECALC_OB; @@ -553,7 +533,7 @@ /* preconditions */ if(partype==PAR_FOLLOW || partype==PAR_PATH_CONST) { if(par->type!=OB_CURVE) - return OPERATOR_CANCELLED; + return 0; else { Curve *cu= par->data; @@ -584,16 +564,15 @@ if(pchan==NULL) { BKE_report(op->reports, RPT_ERROR, "No active Bone"); - return OPERATOR_CANCELLED; + return 0; } } /* context iterator */ - CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { - - if(ob!=par) { - - if( test_parent_loop(par, ob) ) { + CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) + { + if (ob!=par) { + if (BKE_object_parent_loop_check(par, ob)) { BKE_report(op->reports, RPT_ERROR, "Loop in parents"); } else { @@ -601,10 +580,11 @@ /* apply transformation of previous parenting */ /* object_apply_mat4(ob, ob->obmat); */ /* removed because of bug [#23577] */ - + /* set the parent (except for follow-path constraint option) */ - if(partype != PAR_PATH_CONST) + if (partype != PAR_PATH_CONST) { ob->parent= par; + } /* handle types */ if (pchan) @@ -612,9 +592,10 @@ else ob->parsubstr[0]= 0; - if(partype == PAR_PATH_CONST) - ; /* don't do anything here, since this is not technically "parenting" */ - else if( ELEM(partype, PAR_CURVE, PAR_LATTICE) || pararm ) + if (partype == PAR_PATH_CONST) { + /* don't do anything here, since this is not technically "parenting" */ + } + else if (ELEM(partype, PAR_CURVE, PAR_LATTICE) || (pararm)) { /* partype is now set to PAROBJECT so that invisible 'virtual' modifiers don't need to be created * NOTE: the old (2.4x) method was to set ob->partype = PARSKEL, creating the virtual modifiers @@ -624,10 +605,10 @@ /* BUT, to keep the deforms, we need a modifier, and then we need to set the object that it uses */ // XXX currently this should only happen for meshes, curves, surfaces, and lattices - this stuff isn't available for metas yet - if (ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) + if (ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) { ModifierData *md; - + switch (partype) { case PAR_CURVE: /* curve deform */ md= ED_object_modifier_add(op->reports, bmain, scene, ob, NULL, eModifierType_Curve); @@ -694,15 +675,27 @@ } } CTX_DATA_END; - + DAG_scene_sort(bmain, scene); DAG_ids_flush_update(bmain, 0); WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); WM_event_add_notifier(C, NC_OBJECT|ND_PARENT, NULL); - - return OPERATOR_FINISHED; + + return 1; +} + +static int parent_set_exec(bContext *C, wmOperator *op) +{ + Object *par= ED_object_active_context(C); + int partype= RNA_enum_get(op->ptr, "type"); + + if(ED_object_parent_set(C, op, par, partype)) + return OPERATOR_FINISHED; + else + return OPERATOR_CANCELLED; } + static int parent_set_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event)) { Object *ob= ED_object_active_context(C); @@ -766,7 +759,7 @@ /* context iterator */ CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { if (ob != par) { - if (test_parent_loop(par, ob)) { + if (BKE_object_parent_loop_check(par, ob)) { BKE_report(op->reports, RPT_ERROR, "Loop in parents"); } else { @@ -1066,7 +1059,7 @@ int values[20], a; unsigned int lay= 0; - if(!RNA_property_is_set(op->ptr, "layers")) { + if(!RNA_struct_property_is_set(op->ptr, "layers")) { /* note: layers are set in bases, library objects work for this */ CTX_DATA_BEGIN(C, Base*, base, selected_bases) { lay |= base->lay; @@ -1900,7 +1893,7 @@ Main *bmain= CTX_data_main(C); Base *base= ED_view3d_give_base_under_cursor(C, event->mval); Material *ma; - char name[32]; + char name[MAX_ID_NAME-2]; RNA_string_get(op->ptr, "name", name); ma= (Material *)find_id("MA", name); @@ -1933,5 +1926,5 @@ ot->flag= OPTYPE_UNDO; /* properties */ - RNA_def_string(ot->srna, "name", "Material", 24, "Name", "Material name to assign"); + RNA_def_string(ot->srna, "name", "Material", MAX_ID_NAME-2, "Name", "Material name to assign"); } diff -Nru blender-2.61/source/blender/editors/object/object_select.c blender-2.62/source/blender/editors/object/object_select.c --- blender-2.61/source/blender/editors/object/object_select.c 2011-12-13 19:54:35.000000000 +0000 +++ blender-2.62/source/blender/editors/object/object_select.c 2012-02-15 19:38:48.000000000 +0000 @@ -739,41 +739,6 @@ RNA_def_int(ot->srna, "layers", 1, 1, 20, "Layer", "", 1, 20); } -/************************** Select Inverse *************************/ - -static int object_select_inverse_exec(bContext *C, wmOperator *UNUSED(op)) -{ - CTX_DATA_BEGIN(C, Base*, base, visible_bases) { - if (base->flag & SELECT) - ED_base_object_select(base, BA_DESELECT); - else - ED_base_object_select(base, BA_SELECT); - } - CTX_DATA_END; - - /* undo? */ - WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C)); - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_select_inverse(wmOperatorType *ot) -{ - - /* identifiers */ - ot->name= "Select Inverse"; - ot->description = "Invert selection of all visible objects"; - ot->idname= "OBJECT_OT_select_inverse"; - - /* api callbacks */ - ot->exec= object_select_inverse_exec; - ot->poll= objects_selectable_poll; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - -} - /**************************** (De)select All ****************************/ static int object_select_all_exec(bContext *C, wmOperator *op) @@ -841,7 +806,7 @@ static int object_select_same_group_exec(bContext *C, wmOperator *op) { Group *group; - char group_name[32]; + char group_name[MAX_ID_NAME]; /* passthrough if no objects are visible */ if (CTX_DATA_COUNT(C, visible_bases) == 0) return OPERATOR_PASS_THROUGH; @@ -882,7 +847,7 @@ /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - RNA_def_string(ot->srna, "group", "", 32, "Group", "Name of the group to select"); + RNA_def_string(ot->srna, "group", "", MAX_ID_NAME, "Group", "Name of the group to select"); } /**************************** Select Mirror ****************************/ @@ -939,63 +904,6 @@ } -static int object_select_name_exec(bContext *C, wmOperator *op) -{ - char *name= RNA_string_get_alloc(op->ptr, "name", NULL, 0); - short extend= RNA_boolean_get(op->ptr, "extend"); - short changed = 0; - - if(!extend) { - CTX_DATA_BEGIN(C, Base*, base, selectable_bases) { - if(base->flag & SELECT) { - ED_base_object_select(base, BA_DESELECT); - changed= 1; - } - } - CTX_DATA_END; - } - - CTX_DATA_BEGIN(C, Base*, base, selectable_bases) { - /* this is a bit dodjy, there should only be ONE object with this name, but library objects can mess this up */ - if(strcmp(name, base->object->id.name+2)==0) { - ED_base_object_activate(C, base); - ED_base_object_select(base, BA_SELECT); - changed= 1; - } - } - CTX_DATA_END; - - MEM_freeN(name); - - /* undo? */ - if(changed) { - WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C)); - return OPERATOR_FINISHED; - } - else { - return OPERATOR_CANCELLED; - } -} - -void OBJECT_OT_select_name(wmOperatorType *ot) -{ - - /* identifiers */ - ot->name= "Select Name"; - ot->description = "Select an object with this name"; - ot->idname= "OBJECT_OT_select_name"; - - /* api callbacks */ - ot->exec= object_select_name_exec; - ot->poll= objects_selectable_poll; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - RNA_def_string(ot->srna, "name", "", 0, "Name", "Object name to select"); - RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend selection instead of deselecting everything first"); -} - /**************************** Select Random ****************************/ static int object_select_random_exec(bContext *C, wmOperator *op) diff -Nru blender-2.61/source/blender/editors/object/object_shapekey.c blender-2.62/source/blender/editors/object/object_shapekey.c --- blender-2.61/source/blender/editors/object/object_shapekey.c 2011-12-13 19:54:35.000000000 +0000 +++ blender-2.62/source/blender/editors/object/object_shapekey.c 2012-02-15 19:38:48.000000000 +0000 @@ -61,6 +61,7 @@ #include "BLO_sys_types.h" // for intptr_t support +#include "ED_object.h" #include "ED_mesh.h" #include "RNA_access.h" @@ -269,14 +270,14 @@ static int shape_key_mode_poll(bContext *C) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); ID *data= (ob)? ob->data: NULL; return (ob && !ob->id.lib && data && !data->lib && ob->mode != OB_MODE_EDIT); } static int shape_key_poll(bContext *C) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); ID *data= (ob)? ob->data: NULL; return (ob && !ob->id.lib && data && !data->lib); } @@ -284,7 +285,7 @@ static int shape_key_add_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); int from_mix = RNA_boolean_get(op->ptr, "from_mix"); ED_object_shape_key_add(C, scene, ob, from_mix); @@ -312,7 +313,7 @@ static int shape_key_remove_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); if(!ED_object_shape_key_remove(C, ob)) return OPERATOR_CANCELLED; @@ -337,7 +338,7 @@ static int shape_key_clear_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); Key *key= ob_get_key(ob); KeyBlock *kb= ob_get_keyblock(ob); @@ -370,7 +371,7 @@ static int shape_key_mirror_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); if(!object_shape_key_mirror(C, ob)) return OPERATOR_CANCELLED; @@ -395,7 +396,7 @@ static int shape_key_move_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); int type= RNA_enum_get(op->ptr, "type"); Key *key= ob_get_key(ob); diff -Nru blender-2.61/source/blender/editors/object/object_transform.c blender-2.62/source/blender/editors/object/object_transform.c --- blender-2.61/source/blender/editors/object/object_transform.c 2011-12-13 19:54:35.000000000 +0000 +++ blender-2.62/source/blender/editors/object/object_transform.c 2012-02-15 19:38:48.000000000 +0000 @@ -645,7 +645,7 @@ /* get the view settings if 'around' isnt set and the view is available */ View3D *v3d= CTX_wm_view3d(C); copy_v3_v3(cursor, give_cursor(scene, v3d)); - if(v3d && !RNA_property_is_set(op->ptr, "center")) + if(v3d && !RNA_struct_property_is_set(op->ptr, "center")) around= v3d->around; } diff -Nru blender-2.61/source/blender/editors/object/object_vgroup.c blender-2.62/source/blender/editors/object/object_vgroup.c --- blender-2.61/source/blender/editors/object/object_vgroup.c 2011-12-13 19:54:35.000000000 +0000 +++ blender-2.62/source/blender/editors/object/object_vgroup.c 2012-02-15 19:38:48.000000000 +0000 @@ -67,6 +67,7 @@ #include "WM_api.h" #include "WM_types.h" +#include "ED_object.h" #include "ED_mesh.h" #include "UI_resources.h" @@ -175,7 +176,7 @@ } } -static int ED_vgroup_give_parray(ID *id, MDeformVert ***dvert_arr, int *dvert_tot) +static int ED_vgroup_give_parray(ID *id, MDeformVert ***dvert_arr, int *dvert_tot, const short use_vert_sel) { *dvert_tot = 0; *dvert_arr = NULL; @@ -201,20 +202,39 @@ *dvert_tot = i; i = 0; - for (eve=em->verts.first; eve; eve=eve->next, i++) { - (*dvert_arr)[i] = CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); + + if (use_vert_sel) { + for (eve=em->verts.first; eve; eve=eve->next, i++) { + (*dvert_arr)[i] = (eve->f & SELECT) ? + CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT) : NULL; + } + } + else { + for (eve=em->verts.first; eve; eve=eve->next, i++) { + (*dvert_arr)[i] = CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); + } } return 1; } else if(me->dvert) { + MVert *mvert= me->mvert; + MDeformVert *dvert= me->dvert; int i; *dvert_tot= me->totvert; *dvert_arr= MEM_mallocN(sizeof(void*)*me->totvert, "vgroup parray from me"); - for (i=0; itotvert; i++) { - (*dvert_arr)[i] = me->dvert + i; + if (use_vert_sel) { + for (i=0; itotvert; i++) { + (*dvert_arr)[i] = (mvert[i].flag & SELECT) ? + &dvert[i] : NULL; + } + } + else { + for (i=0; itotvert; i++) { + (*dvert_arr)[i] = me->dvert + i; + } } return 1; @@ -231,11 +251,20 @@ lt= (lt->editlatt)? lt->editlatt->latt: lt; if(lt->dvert) { + BPoint *def= lt->def; *dvert_tot= lt->pntsu*lt->pntsv*lt->pntsw; *dvert_arr= MEM_mallocN(sizeof(void*)*(*dvert_tot), "vgroup parray from me"); - for (i=0; i<*dvert_tot; i++) { - (*dvert_arr)[i] = lt->dvert + i; + if (use_vert_sel) { + for (i=0; i<*dvert_tot; i++) { + (*dvert_arr)[i] = (def->f1 & SELECT) ? + <->dvert[i] : NULL; + } + } + else { + for (i=0; i<*dvert_tot; i++) { + (*dvert_arr)[i] = lt->dvert + i; + } } return 1; @@ -290,11 +319,11 @@ int defbase_tot= BLI_countlist(&ob->defbase); short new_vgroup= FALSE; - ED_vgroup_give_parray(ob_from->data, &dvert_array_from, &dvert_tot_from); - ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot); + ED_vgroup_give_parray(ob_from->data, &dvert_array_from, &dvert_tot_from, FALSE); + ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot, FALSE); if((dvert_array == NULL) && (dvert_array_from != NULL) && ED_vgroup_data_create(ob->data)) { - ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot); + ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot, FALSE); new_vgroup= TRUE; } @@ -316,7 +345,7 @@ if(defbase_tot_from < defbase_tot) { /* correct vgroup indices because the number of vgroups is being reduced. */ - int *remap= MEM_mallocN(sizeof(int) * (defbase_tot + 1), "ED_vgroup_copy_array"); + int *remap= MEM_mallocN(sizeof(int) * (defbase_tot + 1), __func__); for(i=0; i<=defbase_tot_from; i++) remap[i]= i; for(; i<=defbase_tot; i++) remap[i]= 0; /* can't use these, so disable */ @@ -343,160 +372,84 @@ return 1; } -/* for mesh in object mode - lattice can be in editmode */ -static void ED_vgroup_nr_vert_remove(Object *ob, int def_nr, int vertnum) -{ - /* This routine removes the vertex from the deform - * group with number def_nr. - * - * This routine is meant to be fast, so it is the - * responsibility of the calling routine to: - * a) test whether ob is non-NULL - * b) test whether ob is a mesh - * c) calculate def_nr - */ - - MDeformWeight *newdw; - MDeformVert *dvert= NULL; - int i, tot; - - /* get the deform vertices corresponding to the - * vertnum - */ - ED_vgroup_give_array(ob->data, &dvert, &tot); - - if(dvert==NULL) - return; - - dvert+= vertnum; - - /* for all of the deform weights in the - * deform vert - */ - for(i=dvert->totweight - 1 ; i>=0 ; i--){ - - /* if the def_nr is the same as the one - * for our weight group then remove it - * from this deform vert. - */ - if(dvert->dw[i].def_nr == def_nr) { - dvert->totweight--; - - /* if there are still other deform weights - * attached to this vert then remove this - * deform weight, and reshuffle the others - */ - if(dvert->totweight) { - newdw = MEM_mallocN(sizeof(MDeformWeight)*(dvert->totweight), - "deformWeight"); - if(dvert->dw){ - memcpy(newdw, dvert->dw, sizeof(MDeformWeight)*i); - memcpy(newdw+i, dvert->dw+i+1, - sizeof(MDeformWeight)*(dvert->totweight-i)); - MEM_freeN(dvert->dw); - } - dvert->dw=newdw; - } - /* if there are no other deform weights - * left then just remove the deform weight - */ - else { - MEM_freeN(dvert->dw); - dvert->dw = NULL; - break; - } - } - } - -} /* for Mesh in Object mode */ /* allows editmode for Lattice */ -static void ED_vgroup_nr_vert_add(Object *ob, int def_nr, int vertnum, float weight, int assignmode) +static void ED_vgroup_nr_vert_add(Object *ob, + const int def_nr, const int vertnum, + const float weight, const int assignmode) { /* add the vert to the deform group with the * specified number */ - MDeformVert *dv= NULL; - MDeformWeight *newdw; - int i, tot; + MDeformVert *dvert= NULL; + int tot; /* get the vert */ - ED_vgroup_give_array(ob->data, &dv, &tot); + ED_vgroup_give_array(ob->data, &dvert, &tot); - if(dv==NULL) + if(dvert==NULL) return; - + /* check that vertnum is valid before trying to get the relevant dvert */ if ((vertnum < 0) || (vertnum >= tot)) return; - else - dv += vertnum; - /* Lets first check to see if this vert is - * already in the weight group -- if so - * lets update it - */ - for(i=0; itotweight; i++){ - - /* if this weight cooresponds to the - * deform group, then add it using - * the assign mode provided + + if (dvert) { + MDeformVert *dv= &dvert[vertnum]; + MDeformWeight *dw; + + /* Lets first check to see if this vert is + * already in the weight group -- if so + * lets update it */ - if(dv->dw[i].def_nr == def_nr){ - + + dw= defvert_find_index(dv, def_nr); + + if (dw) { switch(assignmode) { case WEIGHT_REPLACE: - dv->dw[i].weight=weight; + dw->weight = weight; break; case WEIGHT_ADD: - dv->dw[i].weight+=weight; - if(dv->dw[i].weight >= 1.0f) - dv->dw[i].weight = 1.0f; + dw->weight += weight; + if(dw->weight >= 1.0f) + dw->weight = 1.0f; break; case WEIGHT_SUBTRACT: - dv->dw[i].weight-=weight; + dw->weight -= weight; /* if the weight is zero or less then * remove the vert from the deform group */ - if(dv->dw[i].weight <= 0.0f) - ED_vgroup_nr_vert_remove(ob, def_nr, vertnum); + if(dw->weight <= 0.0f) { + defvert_remove_group(dv, dw); + } break; } - return; } - } + else { + /* if the vert wasn't in the deform group then + * we must take a different form of action ... + */ - /* if the vert wasn't in the deform group then - * we must take a different form of action ... - */ + switch(assignmode) { + case WEIGHT_SUBTRACT: + /* if we are subtracting then we don't + * need to do anything + */ + return; - switch(assignmode) { - case WEIGHT_SUBTRACT: - /* if we are subtracting then we don't - * need to do anything - */ - return; + case WEIGHT_REPLACE: + case WEIGHT_ADD: + /* if we are doing an additive assignment, then + * we need to create the deform weight + */ - case WEIGHT_REPLACE: - case WEIGHT_ADD: - /* if we are doing an additive assignment, then - * we need to create the deform weight - */ - newdw = MEM_callocN(sizeof(MDeformWeight)*(dv->totweight+1), - "deformWeight"); - if(dv->dw){ - memcpy(newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight); - MEM_freeN(dv->dw); + /* we checked if the vertex was added before so no need to test again, simply add */ + defvert_add_index_notest(dv, def_nr, weight); + } } - dv->dw=newdw; - - dv->dw[dv->totweight].weight=weight; - dv->dw[dv->totweight].def_nr=def_nr; - - dv->totweight++; - break; } } @@ -506,7 +459,7 @@ /* add the vert to the deform group with the * specified assign mode */ - int def_nr; + const int def_nr= BLI_findindex(&ob->defbase, dg); MDeformVert *dv= NULL; int tot; @@ -514,7 +467,6 @@ /* get the deform group number, exit if * it can't be found */ - def_nr = defgroup_find_index(ob, dg); if(def_nr < 0) return; /* if there's no deform verts then create some, @@ -533,19 +485,34 @@ /* This routine removes the vertex from the specified * deform group. */ - const int def_nr= defgroup_find_index(ob, dg); - if(def_nr < 0) - return; - ED_vgroup_nr_vert_remove(ob, def_nr, vertnum); + /* TODO, this is slow in a loop, better pass def_nr directly, but leave for later... - campbell */ + const int def_nr= BLI_findindex(&ob->defbase, dg); + + if(def_nr != -1) { + MDeformVert *dvert= NULL; + int tot; + + /* get the deform vertices corresponding to the + * vertnum + */ + ED_vgroup_give_array(ob->data, &dvert, &tot); + + if(dvert) { + MDeformVert *dv= &dvert[vertnum]; + MDeformWeight *dw; + + dw= defvert_find_index(dv, def_nr); + defvert_remove_group(dv, dw); /* dw can be NULL */ + } + } } -static float get_vert_def_nr(Object *ob, int def_nr, int vertnum) +static float get_vert_def_nr(Object *ob, const int def_nr, const int vertnum) { - MDeformVert *dvert= NULL; + MDeformVert *dv= NULL; EditVert *eve; Mesh *me; - int i; /* get the deform vertices corresponding to the vertnum */ if(ob->type==OB_MESH) { @@ -556,14 +523,13 @@ if(!eve) { return 0.0f; } - dvert= CustomData_em_get(&me->edit_mesh->vdata, eve->data, CD_MDEFORMVERT); - vertnum= 0; + dv= CustomData_em_get(&me->edit_mesh->vdata, eve->data, CD_MDEFORMVERT); } else { if(vertnum >= me->totvert) { return 0.0f; } - dvert = me->dvert; + dv = &me->dvert[vertnum]; } } else if(ob->type==OB_LATTICE) { @@ -573,30 +539,27 @@ if(vertnum >= lt->pntsu*lt->pntsv*lt->pntsw) { return 0.0f; } - dvert = lt->dvert; + dv = <->dvert[vertnum]; } } - if(dvert==NULL) - return -1; - - dvert += vertnum; - - for(i=dvert->totweight-1 ; i>=0 ; i--) - if(dvert->dw[i].def_nr == def_nr) - return dvert->dw[i].weight; + if (dv) { + MDeformWeight *dw= defvert_find_index(dv, def_nr); + if (dw) { + return dw->weight; + } + } return -1; } float ED_vgroup_vert_weight(Object *ob, bDeformGroup *dg, int vertnum) { - int def_nr; + const int def_nr= BLI_findindex(&ob->defbase, dg); - if(!ob) return -1; - - def_nr = defgroup_find_index(ob, dg); - if(def_nr < 0) return -1; + if(def_nr == -1) { + return -1; + } return get_vert_def_nr(ob, def_nr, vertnum); } @@ -611,34 +574,56 @@ /* only in editmode */ static void vgroup_select_verts(Object *ob, int select) { - EditVert *eve; - MDeformVert *dvert; - int i; + const int def_nr= ob->actdef-1; + MDeformVert *dv; + + if (!BLI_findlink(&ob->defbase, def_nr)) { + return; + } if(ob->type == OB_MESH) { Mesh *me= ob->data; - EditMesh *em = BKE_mesh_get_editmesh(me); - for(eve=em->verts.first; eve; eve=eve->next){ - dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); + if (me->edit_mesh) { + EditMesh *em = BKE_mesh_get_editmesh(me); + EditVert *eve; - if(dvert && dvert->totweight){ - for(i=0; itotweight; i++){ - if(dvert->dw[i].def_nr == (ob->actdef-1)){ - if(!eve->h) { - if(select) eve->f |= SELECT; - else eve->f &= ~SELECT; - } - break; + for (eve=em->verts.first; eve; eve=eve->next) { + if (!eve->h) { + dv= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); + if (defvert_find_index(dv, def_nr)) { + if (select) eve->f |= SELECT; + else eve->f &= ~SELECT; } } } + /* this has to be called, because this function operates on vertices only */ + if(select) EM_select_flush(em); // vertices to edges/faces + else EM_deselect_flush(em); + + BKE_mesh_end_editmesh(me, em); } - /* this has to be called, because this function operates on vertices only */ - if(select) EM_select_flush(em); // vertices to edges/faces - else EM_deselect_flush(em); + else { + if (me->dvert) { + MVert *mv; + MDeformVert *dv; + int i; + + mv = me->mvert; + dv = me->dvert; + + for (i=0; itotvert; i++, mv++, dv++) { + if (!(mv->flag & ME_HIDE)) { + if (defvert_find_index(dv, def_nr)) { + if (select) mv->flag |= SELECT; + else mv->flag &= ~SELECT; + } + } + } - BKE_mesh_end_editmesh(me, em); + paintvert_flush_flags(ob); + } + } } else if(ob->type == OB_LATTICE) { Lattice *lt= vgroup_edit_lattice(ob); @@ -647,17 +632,13 @@ BPoint *bp; int a, tot; - dvert= lt->dvert; + dv= lt->dvert; tot= lt->pntsu*lt->pntsv*lt->pntsw; - for(a=0, bp= lt->def; atotweight; i++){ - if(dvert->dw[i].def_nr == (ob->actdef-1)) { - if(select) bp->f1 |= SELECT; - else bp->f1 &= ~SELECT; - - break; - } + for(a=0, bp= lt->def; af1 |= SELECT; + else bp->f1 &= ~SELECT; } } } @@ -668,8 +649,8 @@ { bDeformGroup *dg, *cdg; char name[sizeof(dg->name)]; - MDeformWeight *org, *cpy; - MDeformVert *dvert, **dvert_array=NULL; + MDeformWeight *dw_org, *dw_cpy; + MDeformVert **dvert_array=NULL; int i, idg, icdg, dvert_tot=0; dg = BLI_findlink(&ob->defbase, (ob->actdef-1)); @@ -693,53 +674,51 @@ ob->actdef = BLI_countlist(&ob->defbase); icdg = (ob->actdef-1); - ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot); - - if(!dvert_array) - return; + /* TODO, we might want to allow only copy selected verts here? - campbell */ + ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot, FALSE); - for(i = 0; i < dvert_tot; i++) { - dvert = dvert_array[i]; - org = defvert_find_index(dvert, idg); - if(org) { - float weight = org->weight; - /* defvert_verify_index re-allocs org so need to store the weight first */ - cpy = defvert_verify_index(dvert, icdg); - cpy->weight = weight; + if (dvert_array) { + for(i = 0; i < dvert_tot; i++) { + MDeformVert *dv= dvert_array[i]; + dw_org = defvert_find_index(dv, idg); + if(dw_org) { + /* defvert_verify_index re-allocs org so need to store the weight first */ + dw_cpy = defvert_verify_index(dv, icdg); + dw_cpy->weight = dw_org->weight; + } } - } - MEM_freeN(dvert_array); + MEM_freeN(dvert_array); + } } static void vgroup_normalize(Object *ob) { - bDeformGroup *dg; MDeformWeight *dw; - MDeformVert *dvert, **dvert_array=NULL; - int i, def_nr, dvert_tot=0; - + MDeformVert *dv, **dvert_array=NULL; + int i, dvert_tot=0; + const int def_nr= ob->actdef-1; + Mesh *me = ob->data; - MVert *mvert = me->mvert; const int use_vert_sel= (me->editflag & ME_EDIT_VERT_SEL) != 0; - ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot); + if (!BLI_findlink(&ob->defbase, def_nr)) { + return; + } - dg = BLI_findlink(&ob->defbase, (ob->actdef-1)); + ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot, use_vert_sel); - if(dg) { + if (dvert_array) { float weight_max = 0.0f; - def_nr= ob->actdef-1; - for(i = 0; i < dvert_tot; i++) { - - if(use_vert_sel && !(mvert[i].flag & SELECT)) { + + /* incase its not selected */ + if (!(dv = dvert_array[i])) { continue; } - dvert = dvert_array[i]; - dw = defvert_find_index(dvert, def_nr); + dw = defvert_find_index(dv, def_nr); if(dw) { weight_max = MAX2(dw->weight, weight_max); } @@ -748,12 +727,12 @@ if(weight_max > 0.0f) { for(i = 0; i < dvert_tot; i++) { - if(use_vert_sel && !(mvert[i].flag & SELECT)) { + /* incase its not selected */ + if (!(dv = dvert_array[i])) { continue; } - dvert = dvert_array[i]; - dw = defvert_find_index(dvert, def_nr); + dw = defvert_find_index(dv, def_nr); if(dw) { dw->weight /= weight_max; @@ -762,9 +741,9 @@ } } } - } - if (dvert_array) MEM_freeN(dvert_array); + MEM_freeN(dvert_array); + } } /* This adds the indices of vertices to a list if they are not already present @@ -875,55 +854,28 @@ mul_v3_fl(coord, 1.0f/count); } -/* find the closest point on a plane to another point and store it in dst */ -/* coord is a point on the plane */ -/* point is the point that you want the nearest of */ -/* norm is the plane's normal, and d is the last number in the plane equation 0 = ax + by + cz + d */ -static void getNearestPointOnPlane(const float norm[3], const float coord[3], const float point[3], float dst_r[3]) -{ - float temp[3]; - float dotprod; - - sub_v3_v3v3(temp, point, coord); - dotprod= dot_v3v3(temp, norm); - - dst_r[0] = point[0] - (norm[0] * dotprod); - dst_r[1] = point[1] - (norm[1] * dotprod); - dst_r[2] = point[2] - (norm[2] * dotprod); -} - -/* distance of two vectors a and b of size length */ -static float distance(float* a, float *b, int length) -{ - int i; - float sum = 0; - for(i = 0; i < length; i++) { - sum += (b[i]-a[i])*(b[i]-a[i]); - } - return sqrt(sum); -} - /* given a plane and a start and end position, compute the amount of vertical distance relative to the plane and store it in dists, then get the horizontal and vertical change and store them in changes */ -static void getVerticalAndHorizontalChange(float *norm, float d, float *coord, float *start, float distToStart, +static void getVerticalAndHorizontalChange(const float norm[3], float d, const float coord[3], + const float start[3], float distToStart, float *end, float (*changes)[2], float *dists, int index) { // A=Q-((Q-P).N)N // D = (a*x0 + b*y0 +c*z0 +d) - float projA[3] = {0}, projB[3] = {0}; + float projA[3], projB[3]; - getNearestPointOnPlane(norm, coord, start, projA); - getNearestPointOnPlane(norm, coord, end, projB); + closest_to_plane_v3(projA, coord, norm, start); + closest_to_plane_v3(projB, coord, norm, end); // (vertical and horizontal refer to the plane's y and xz respectively) // vertical distance - dists[index] = norm[0]*end[0] + norm[1]*end[1] + norm[2]*end[2] + d; + dists[index] = dot_v3v3(norm, end) + d; // vertical change changes[index][0] = dists[index] - distToStart; //printf("vc %f %f\n", distance(end, projB, 3)-distance(start, projA, 3), changes[index][0]); // horizontal change - changes[index][1] = distance(projA, projB, 3); + changes[index][1] = len_v3v3(projA, projB); } // I need the derived mesh to be forgotten so the positions are recalculated with weight changes (see dm_deform_recalc) @@ -965,11 +917,14 @@ int totweight = dvert->totweight; float oldw = 0; float oldPos[3] = {0}; - float vc, hc, dist = 0.0f /* Not necessary, but quites down gcc warnings! */; + float vc, hc, dist = 0.0f; int i, k; float (*changes)[2] = MEM_mallocN(sizeof(float *)*totweight*2, "vertHorzChange"); float *dists = MEM_mallocN(sizeof(float)*totweight, "distance"); - int *upDown = MEM_callocN(sizeof(int)*totweight, "upDownTracker");// track if up or down moved it closer for each bone + + /* track if up or down moved it closer for each bone */ + int *upDown = MEM_callocN(sizeof(int)*totweight, "upDownTracker"); + int *dwIndices = MEM_callocN(sizeof(int)*totweight, "dwIndexTracker"); float distToStart; int bestIndex = 0; @@ -1156,7 +1111,7 @@ mag= normalize_v3(norm); if(mag) { /* zeros fix */ d = -dot_v3v3(norm, coord); - /* dist = (norm[0]*m.co[0] + norm[1]*m.co[1] + norm[2]*m.co[2] + d); */ /* UNUSED */ + /* dist = (dot_v3v3(norm, m.co) + d); */ /* UNUSED */ moveCloserToDistanceFromPlane(scene, ob, me, i, norm, coord, d, distToBe, strength, cp); } } @@ -1170,136 +1125,82 @@ static void vgroup_levels(Object *ob, float offset, float gain) { - bDeformGroup *dg; MDeformWeight *dw; - MDeformVert *dvert, **dvert_array=NULL; - int i, def_nr, dvert_tot=0; - + MDeformVert *dv, **dvert_array=NULL; + int i, dvert_tot=0; + const int def_nr= ob->actdef-1; + Mesh *me = ob->data; - MVert *mvert = me->mvert; const int use_vert_sel= (me->editflag & ME_EDIT_VERT_SEL) != 0; - ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot); - - dg = BLI_findlink(&ob->defbase, (ob->actdef-1)); - - if(dg) { - def_nr= ob->actdef-1; - + if (!BLI_findlink(&ob->defbase, def_nr)) { + return; + } + + ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot, use_vert_sel); + + if (dvert_array) { for(i = 0; i < dvert_tot; i++) { - - if(use_vert_sel && !(mvert[i].flag & SELECT)) { + + /* incase its not selected */ + if (!(dv = dvert_array[i])) { continue; } - dvert = dvert_array[i]; - dw = defvert_find_index(dvert, def_nr); + dw = defvert_find_index(dv, def_nr); if(dw) { dw->weight = gain * (dw->weight + offset); - + CLAMP(dw->weight, 0.0f, 1.0f); } } - } - if (dvert_array) MEM_freeN(dvert_array); + MEM_freeN(dvert_array); + } } /* TODO - select between groups */ static void vgroup_normalize_all(Object *ob, int lock_active) { - MDeformWeight *dw, *dw_act; - MDeformVert *dvert, **dvert_array=NULL; + MDeformVert *dv, **dvert_array=NULL; int i, dvert_tot=0; - float tot_weight; + const int def_nr= ob->actdef-1; - Mesh *me = ob->data; - MVert *mvert = me->mvert; const int use_vert_sel= (me->editflag & ME_EDIT_VERT_SEL) != 0; - ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot); + if (lock_active && !BLI_findlink(&ob->defbase, def_nr)) { + return; + } + + ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot, use_vert_sel); - if(dvert_array) { + if (dvert_array) { if(lock_active) { - int def_nr= ob->actdef-1; for(i = 0; i < dvert_tot; i++) { - float lock_iweight= 1.0f; - int j; - - if(use_vert_sel && !(mvert[i].flag & SELECT)) { + /* incase its not selected */ + if (!(dv = dvert_array[i])) { continue; } - tot_weight= 0.0f; - dw_act= NULL; - dvert = dvert_array[i]; - - j= dvert->totweight; - while(j--) { - dw= dvert->dw + j; - - if(dw->def_nr==def_nr) { - dw_act= dw; - lock_iweight = (1.0f - dw_act->weight); - } - else { - tot_weight += dw->weight; - } - } - - if(tot_weight) { - j= dvert->totweight; - while(j--) { - dw= dvert->dw + j; - if(dw == dw_act) { - if (dvert->totweight==1) { - dw_act->weight= 1.0f; /* no other weights, set to 1.0 */ - } - } else { - if(dw->weight > 0.0f) - dw->weight = (dw->weight / tot_weight) * lock_iweight; - } - - /* incase of division errors with very low weights */ - CLAMP(dw->weight, 0.0f, 1.0f); - } - } + defvert_normalize_lock(dv, def_nr); } } else { for(i = 0; i < dvert_tot; i++) { - int j; - - if(use_vert_sel && !(mvert[i].flag & SELECT)) { + + /* incase its not selected */ + if (!(dv = dvert_array[i])) { continue; } - tot_weight= 0.0f; - dvert = dvert_array[i]; - - j= dvert->totweight; - while(j--) { - dw= dvert->dw + j; - tot_weight += dw->weight; - } - - if(tot_weight) { - j= dvert->totweight; - while(j--) { - dw= dvert->dw + j; - dw->weight /= tot_weight; - - /* incase of division errors with very low weights */ - CLAMP(dw->weight, 0.0f, 1.0f); - } - } + defvert_normalize(dv); } } - } - if (dvert_array) MEM_freeN(dvert_array); + MEM_freeN(dvert_array); + } } @@ -1332,68 +1233,64 @@ } } -static void vgroup_invert(Object *ob, int auto_assign, int auto_remove) +static void vgroup_invert(Object *ob, const short auto_assign, const short auto_remove) { - bDeformGroup *dg; MDeformWeight *dw; - MDeformVert *dvert, **dvert_array=NULL; - int i, def_nr, dvert_tot=0; + MDeformVert *dv, **dvert_array=NULL; + int i, dvert_tot=0; + const int def_nr= ob->actdef-1; Mesh *me = ob->data; - MVert *mvert = me->mvert; const int use_vert_sel= (me->editflag & ME_EDIT_VERT_SEL) != 0; - ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot); - - dg = BLI_findlink(&ob->defbase, (ob->actdef-1)); - - if(dg) { - def_nr= ob->actdef-1; + if (!BLI_findlink(&ob->defbase, def_nr)) { + return; + } + ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot, use_vert_sel); + if (dvert_array) { for(i = 0; i < dvert_tot; i++) { - - if(use_vert_sel && !(mvert[i].flag & SELECT)) { + + /* incase its not selected */ + if (!(dv = dvert_array[i])) { continue; } - dvert = dvert_array[i]; - if(auto_assign) { - dw= defvert_verify_index(dvert, def_nr); - } else { - dw= defvert_find_index(dvert, def_nr); + if (auto_assign) { + dw= defvert_verify_index(dv, def_nr); + } + else { + dw= defvert_find_index(dv, def_nr); } if(dw) { - dw->weight = 1.0f-dw->weight; + dw->weight = 1.0f - dw->weight; if(auto_remove && dw->weight <= 0.0f) { - /* could have a faster function for this */ - ED_vgroup_nr_vert_remove(ob, def_nr, i); + defvert_remove_group(dv, dw); } } } - } - if (dvert_array) MEM_freeN(dvert_array); + MEM_freeN(dvert_array); + } } static void vgroup_blend(Object *ob) { - bDeformGroup *dg; MDeformWeight *dw; MDeformVert *dvert_array=NULL, *dvert; - int i, def_nr, dvert_tot=0; + int i, dvert_tot=0; + const int def_nr= ob->actdef-1; EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)ob->data)); // ED_vgroup_give_array(ob->data, &dvert_array, &dvert_tot); - if(em==NULL) + if (em==NULL) return; - dg = BLI_findlink(&ob->defbase, (ob->actdef-1)); - - if(dg) { + if (BLI_findlink(&ob->defbase, def_nr)) { int sel1, sel2; int i1, i2; @@ -1402,8 +1299,6 @@ float *vg_weights; float *vg_users; - def_nr= ob->actdef-1; - i= 0; for(eve= em->verts.first; eve; eve= eve->next) eve->tmp.l= i++; @@ -1453,6 +1348,9 @@ dw= defvert_verify_index(dvert, def_nr); dw->weight= vg_weights[i] / (float)vg_users[i]; + + /* incase of division errors */ + CLAMP(dw->weight, 0.0f, 1.0f); } i++; @@ -1462,83 +1360,85 @@ } } -static void vgroup_clean(Object *ob, float eul, int keep_single) +static void vgroup_clean(Object *ob, const float epsilon, int keep_single) { - bDeformGroup *dg; MDeformWeight *dw; - MDeformVert *dvert, **dvert_array=NULL; - int i, def_nr, dvert_tot=0; + MDeformVert *dv, **dvert_array=NULL; + int i, dvert_tot=0; + const int def_nr= ob->actdef-1; Mesh *me = ob->data; - MVert *mvert = me->mvert; const int use_vert_sel= (me->editflag & ME_EDIT_VERT_SEL) != 0; - ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot); + if (!BLI_findlink(&ob->defbase, def_nr)) { + return; + } - /* only the active group */ - dg = BLI_findlink(&ob->defbase, (ob->actdef-1)); - if(dg) { - def_nr= ob->actdef-1; + ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot, use_vert_sel); + if (dvert_array) { + /* only the active group */ for(i = 0; i < dvert_tot; i++) { - - if(use_vert_sel && !(mvert[i].flag & SELECT)) { + + /* incase its not selected */ + if (!(dv = dvert_array[i])) { continue; } - dvert = dvert_array[i]; - dw= defvert_find_index(dvert, def_nr); + dw= defvert_find_index(dv, def_nr); - if(dw) { - if(dw->weight <= eul) - if(keep_single==FALSE || dvert->totweight > 1) - ED_vgroup_nr_vert_remove(ob, def_nr, i); + if (dw) { + if (dw->weight <= epsilon) { + if(keep_single==FALSE || dv->totweight > 1) { + defvert_remove_group(dv, dw); /* dw can be NULL */ + } + } } } - } - if (dvert_array) MEM_freeN(dvert_array); + MEM_freeN(dvert_array); + } } -static void vgroup_clean_all(Object *ob, float eul, int keep_single) +static void vgroup_clean_all(Object *ob, const float epsilon, const int keep_single) { - - MDeformWeight *dw; - MDeformVert *dvert, **dvert_array=NULL; + MDeformVert **dvert_array=NULL; int i, dvert_tot=0; Mesh *me = ob->data; - MVert *mvert = me->mvert; const int use_vert_sel= (me->editflag & ME_EDIT_VERT_SEL) != 0; - ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot); + ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot, use_vert_sel); + + if (dvert_array) { + MDeformVert *dv; + MDeformWeight *dw; - if(dvert_array) { for(i = 0; i < dvert_tot; i++) { int j; - - if(use_vert_sel && !(mvert[i].flag & SELECT)) { + + /* incase its not selected */ + if (!(dv = dvert_array[i])) { continue; } - dvert = dvert_array[i]; - j= dvert->totweight; + j= dv->totweight; while(j--) { - if(keep_single && dvert->totweight == 1) + if(keep_single && dv->totweight == 1) break; - dw= dvert->dw + j; - - if(dw->weight <= eul) - ED_vgroup_nr_vert_remove(ob, dw->def_nr, i); + dw= dv->dw + j; + if(dw->weight <= epsilon) { + defvert_remove_group(dv, dw); + } } } - } - if (dvert_array) MEM_freeN(dvert_array); + MEM_freeN(dvert_array); + } } @@ -1716,14 +1616,12 @@ } } else if (ob->type == OB_LATTICE) { - Lattice *lt= ob->data; + Lattice *lt= vgroup_edit_lattice(ob); int i1, i2; int u, v, w; int pntsu_half; /* half but found up odd value */ - if(lt->editlatt) lt= lt->editlatt->latt; - if(lt->pntsu == 1 || lt->dvert == NULL) { goto cleanup; } @@ -1824,35 +1722,39 @@ static void vgroup_delete_object_mode(Object *ob, bDeformGroup *dg) { MDeformVert *dvert_array=NULL; - int i, e, dvert_tot=0; - const int dg_index= BLI_findindex(&ob->defbase, dg); + int dvert_tot=0; + const int def_nr= BLI_findindex(&ob->defbase, dg); + + assert(def_nr > -1); - assert(dg_index > -1); - ED_vgroup_give_array(ob->data, &dvert_array, &dvert_tot); if(dvert_array) { - MDeformVert *dvert; - for(i= 0, dvert= dvert_array; i < dvert_tot; i++, dvert++) { - ED_vgroup_vert_remove(ob, dg, i); /* ok if the dg isnt in this dvert, will continue silently */ - } + int i, j; + MDeformVert *dv; + for(i= 0, dv= dvert_array; i < dvert_tot; i++, dv++) { + MDeformWeight *dw; - for(i= 0, dvert= dvert_array; i < dvert_tot; i++, dvert++) { - for(e = 0; e < dvert->totweight; e++) { - if(dvert->dw[e].def_nr > dg_index) { - dvert->dw[e].def_nr--; + dw= defvert_find_index(dv, def_nr); + defvert_remove_group(dv, dw); /* dw can be NULL */ + + /* inline, make into a function if anything else needs to do this */ + for(j = 0; j < dv->totweight; j++) { + if(dv->dw[j].def_nr > def_nr) { + dv->dw[j].def_nr--; } } + /* done */ } } - vgroup_delete_update_users(ob, dg_index + 1); + vgroup_delete_update_users(ob, def_nr + 1); /* Remove the group */ BLI_freelinkN(&ob->defbase, dg); /* Update the active deform index if necessary */ - if(ob->actdef > dg_index) + if(ob->actdef > def_nr) ob->actdef--; if(ob->actdef < 1 && ob->defbase.first) ob->actdef= 1; @@ -1863,56 +1765,64 @@ /* removes from active defgroup, if allverts==0 only selected vertices */ static void vgroup_active_remove_verts(Object *ob, const int allverts, bDeformGroup *dg) { - EditVert *eve; - MDeformVert *dvert; - MDeformWeight *newdw; - bDeformGroup *eg; - int i; + MDeformVert *dv; + const int def_nr= BLI_findindex(&ob->defbase, dg); if(ob->type == OB_MESH) { Mesh *me= ob->data; - EditMesh *em = BKE_mesh_get_editmesh(me); - for(eve=em->verts.first; eve; eve=eve->next){ - dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); - - if(dvert && dvert->dw && ((eve->f & SELECT) || allverts)){ - for(i=0; itotweight; i++){ - /* Find group */ - eg = BLI_findlink(&ob->defbase, dvert->dw[i].def_nr); - if(eg == dg){ - dvert->totweight--; - if(dvert->totweight){ - newdw = MEM_mallocN(sizeof(MDeformWeight)*(dvert->totweight), "deformWeight"); - - if(dvert->dw){ - memcpy(newdw, dvert->dw, sizeof(MDeformWeight)*i); - memcpy(newdw+i, dvert->dw+i+1, sizeof(MDeformWeight)*(dvert->totweight-i)); - MEM_freeN(dvert->dw); - } - dvert->dw=newdw; - } - else{ - MEM_freeN(dvert->dw); - dvert->dw=NULL; - break; - } + if (me->edit_mesh) { + EditVert *eve; + EditMesh *em = BKE_mesh_get_editmesh(me); + + for (eve=em->verts.first; eve; eve=eve->next) { + dv= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); + + if (dv && dv->dw && (allverts || (eve->f & SELECT))) { + MDeformWeight *dw = defvert_find_index(dv, def_nr); + defvert_remove_group(dv, dw); /* dw can be NULL */ + } + } + BKE_mesh_end_editmesh(me, em); + } + else { + MVert *mv; + MDeformVert *dv; + int i; + + if (!me->dvert) { + ED_vgroup_data_create(&me->id); + } + + mv = me->mvert; + dv = me->dvert; + + for (i=0; itotvert; i++, mv++, dv++) { + if (mv->flag & SELECT) { + if (dv->dw && (allverts || (mv->flag & SELECT))) { + MDeformWeight *dw = defvert_find_index(dv, def_nr); + defvert_remove_group(dv, dw); /* dw can be NULL */ } } } } - BKE_mesh_end_editmesh(me, em); } else if(ob->type == OB_LATTICE) { Lattice *lt= vgroup_edit_lattice(ob); if(lt->dvert) { BPoint *bp; - int a, tot= lt->pntsu*lt->pntsv*lt->pntsw; + int i, tot= lt->pntsu*lt->pntsv*lt->pntsw; - for(a=0, bp= lt->def; af1 & SELECT)) - ED_vgroup_vert_remove(ob, dg, a); + for(i=0, bp= lt->def; if1 & SELECT)) { + MDeformWeight *dw; + + dv= <->dvert[i]; + + dw = defvert_find_index(dv, def_nr); + defvert_remove_group(dv, dw); /* dw can be NULL */ + } } } } @@ -2000,6 +1910,18 @@ return 0; } +static int vgroup_object_in_wpaint_vert_select(Object *ob) +{ + if (ob->type == OB_MESH) { + Mesh *me = ob->data; + return ( (ob->mode & OB_MODE_WEIGHT_PAINT) && + (me->edit_mesh == NULL) && + (ME_EDIT_PAINT_SEL_MODE(me) == SCE_SELECT_VERTEX) ); + } + + return 0; +} + static void vgroup_delete(Object *ob) { bDeformGroup *dg = BLI_findlink(&ob->defbase, ob->actdef-1); @@ -2036,73 +1958,79 @@ } /* only in editmode */ -static void vgroup_assign_verts(Object *ob, float weight) +static void vgroup_assign_verts(Object *ob, const float weight) { - EditVert *eve; - bDeformGroup *dg, *eg; - MDeformWeight *newdw; - MDeformVert *dvert; - int i, done; + MDeformVert *dv; + const int def_nr= ob->actdef-1; - dg=BLI_findlink(&ob->defbase, ob->actdef-1); - if(!dg) + if(!BLI_findlink(&ob->defbase, def_nr)) return; if(ob->type == OB_MESH) { Mesh *me= ob->data; - EditMesh *em = BKE_mesh_get_editmesh(me); - - if(!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT)) - EM_add_data_layer(em, &em->vdata, CD_MDEFORMVERT, NULL); + if (me->edit_mesh) { + EditMesh *em = BKE_mesh_get_editmesh(me); + EditVert *eve; - /* Go through the list of editverts and assign them */ - for(eve=em->verts.first; eve; eve=eve->next){ - dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); + if(!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT)) + EM_add_data_layer(em, &em->vdata, CD_MDEFORMVERT, NULL); - if(dvert && (eve->f & SELECT)){ - /* See if this vert already has a reference to this group */ - /* If so: Change its weight */ - done=0; - for(i=0; itotweight; i++){ - eg = BLI_findlink(&ob->defbase, dvert->dw[i].def_nr); - /* Find the actual group */ - if(eg==dg){ - dvert->dw[i].weight= weight; - done=1; - break; + /* Go through the list of editverts and assign them */ + for (eve=em->verts.first; eve; eve=eve->next) { + if (eve->f & SELECT) { + MDeformWeight *dw; + dv= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); /* can be NULL */ + dw= defvert_verify_index(dv, def_nr); + if (dw) { + dw->weight= weight; } - } - /* If not: Add the group and set its weight */ - if(!done){ - newdw = MEM_callocN(sizeof(MDeformWeight)*(dvert->totweight+1), "deformWeight"); - if(dvert->dw){ - memcpy(newdw, dvert->dw, sizeof(MDeformWeight)*dvert->totweight); - MEM_freeN(dvert->dw); + } + } + BKE_mesh_end_editmesh(me, em); + } + else { + MVert *mv; + MDeformVert *dv; + int i; + + if (!me->dvert) { + ED_vgroup_data_create(&me->id); + } + + mv = me->mvert; + dv = me->dvert; + + for (i=0; itotvert; i++, mv++, dv++) { + if (mv->flag & SELECT) { + MDeformWeight *dw; + dw= defvert_verify_index(dv, def_nr); + if (dw) { + dw->weight= weight; } - dvert->dw=newdw; - - dvert->dw[dvert->totweight].weight= weight; - dvert->dw[dvert->totweight].def_nr= ob->actdef-1; - - dvert->totweight++; - } } } - BKE_mesh_end_editmesh(me, em); } else if(ob->type == OB_LATTICE) { Lattice *lt= vgroup_edit_lattice(ob); BPoint *bp; int a, tot; - + if(lt->dvert==NULL) ED_vgroup_data_create(<->id); - + + dv= lt->dvert; + tot= lt->pntsu*lt->pntsv*lt->pntsw; - for(a=0, bp= lt->def; af1 & SELECT) - ED_vgroup_nr_vert_add(ob, ob->actdef-1, a, weight, WEIGHT_REPLACE); + for(a=0, bp= lt->def; af1 & SELECT) { + MDeformWeight *dw; + + dw= defvert_verify_index(dv, def_nr); + if (dw) { + dw->weight= weight; + } + } } } } @@ -2125,14 +2053,14 @@ static int vertex_group_poll(bContext *C) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); ID *data= (ob)? ob->data: NULL; return (ob && !ob->id.lib && OB_TYPE_SUPPORT_VGROUP(ob->type) && data && !data->lib); } -static int vertex_group_poll_edit(bContext *C) +static int UNUSED_FUNCTION(vertex_group_poll_edit)(bContext *C) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); ID *data= (ob)? ob->data: NULL; if(!(ob && !ob->id.lib && data && !data->lib)) @@ -2141,9 +2069,22 @@ return vgroup_object_in_edit_mode(ob); } +/* editmode _or_ weight paint vertex sel */ +static int vertex_group_poll_edit_or_wpaint_vert_select(bContext *C) +{ + Object *ob= ED_object_context(C); + ID *data= (ob)? ob->data: NULL; + + if(!(ob && !ob->id.lib && data && !data->lib)) + return 0; + + return ( vgroup_object_in_edit_mode(ob) || + vgroup_object_in_wpaint_vert_select(ob) ); +} + static int vertex_group_add_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); ED_vgroup_add(ob); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); @@ -2169,7 +2110,7 @@ static int vertex_group_remove_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); if(RNA_boolean_get(op->ptr, "all")) vgroup_delete_all(ob); @@ -2206,7 +2147,7 @@ static int vertex_group_assign_exec(bContext *C, wmOperator *op) { ToolSettings *ts= CTX_data_tool_settings(C); - Object *ob= CTX_data_edit_object(C); + Object *ob= ED_object_context(C); if(RNA_boolean_get(op->ptr, "new")) ED_vgroup_add(ob); @@ -2225,7 +2166,7 @@ ot->idname= "OBJECT_OT_vertex_group_assign"; /* api callbacks */ - ot->poll= vertex_group_poll_edit; + ot->poll= vertex_group_poll_edit_or_wpaint_vert_select; ot->exec= vertex_group_assign_exec; /* flags */ @@ -2240,7 +2181,7 @@ static int vertex_group_remove_from_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_edit_object(C); + Object *ob= ED_object_context(C); if(RNA_boolean_get(op->ptr, "all")) vgroup_remove_verts(ob, 0); @@ -2267,7 +2208,7 @@ ot->idname= "OBJECT_OT_vertex_group_remove_from"; /* api callbacks */ - ot->poll= vertex_group_poll_edit; + ot->poll= vertex_group_poll_edit_or_wpaint_vert_select; ot->exec= vertex_group_remove_from_exec; /* flags */ @@ -2282,7 +2223,7 @@ static int vertex_group_select_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_edit_object(C); + Object *ob= ED_object_context(C); if(!ob || ob->id.lib) return OPERATOR_CANCELLED; @@ -2300,7 +2241,7 @@ ot->idname= "OBJECT_OT_vertex_group_select"; /* api callbacks */ - ot->poll= vertex_group_poll_edit; + ot->poll= vertex_group_poll_edit_or_wpaint_vert_select; ot->exec= vertex_group_select_exec; /* flags */ @@ -2309,7 +2250,7 @@ static int vertex_group_deselect_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_edit_object(C); + Object *ob= ED_object_context(C); vgroup_select_verts(ob, 0); WM_event_add_notifier(C, NC_GEOM|ND_SELECT, ob->data); @@ -2324,7 +2265,7 @@ ot->idname= "OBJECT_OT_vertex_group_deselect"; /* api callbacks */ - ot->poll= vertex_group_poll_edit; + ot->poll= vertex_group_poll_edit_or_wpaint_vert_select; ot->exec= vertex_group_deselect_exec; /* flags */ @@ -2333,7 +2274,7 @@ static int vertex_group_copy_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); vgroup_duplicate(ob); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); @@ -2359,7 +2300,7 @@ static int vertex_group_levels_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); float offset= RNA_float_get(op->ptr,"offset"); float gain= RNA_float_get(op->ptr,"gain"); @@ -2392,7 +2333,7 @@ static int vertex_group_normalize_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); vgroup_normalize(ob); @@ -2419,7 +2360,7 @@ static int vertex_group_normalize_all_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); int lock_active= RNA_boolean_get(op->ptr,"lock_active"); vgroup_normalize_all(ob, lock_active); @@ -2529,7 +2470,7 @@ static int vertex_group_invert_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); int auto_assign= RNA_boolean_get(op->ptr,"auto_assign"); int auto_remove= RNA_boolean_get(op->ptr,"auto_remove"); @@ -2563,7 +2504,7 @@ static int vertex_group_blend_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); vgroup_blend(ob); @@ -2592,7 +2533,7 @@ static int vertex_group_clean_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); float limit= RNA_float_get(op->ptr,"limit"); int all_groups= RNA_boolean_get(op->ptr,"all_groups"); @@ -2624,13 +2565,14 @@ RNA_def_float(ot->srna, "limit", 0.01f, 0.0f, 1.0, "Limit", "Remove weights under this limit", 0.001f, 0.99f); RNA_def_boolean(ot->srna, "all_groups", FALSE, "All Groups", "Clean all vertex groups"); - RNA_def_boolean(ot->srna, "keep_single", FALSE, "Keep Single", "Keep verts assigned to at least one group when cleaning"); + RNA_def_boolean(ot->srna, "keep_single", FALSE, "Keep Single", + "Keep verts assigned to at least one group when cleaning"); } static int vertex_group_mirror_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); ED_vgroup_mirror(ob, RNA_boolean_get(op->ptr,"mirror_weights"), @@ -2669,7 +2611,7 @@ static int vertex_group_copy_to_linked_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); Base *base; int retval= OPERATOR_CANCELLED; @@ -2709,7 +2651,7 @@ static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *op) { - Object *obact= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *obact= ED_object_context(C); int change= 0; int fail= 0; @@ -2752,11 +2694,11 @@ static int set_active_group_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); int nr= RNA_enum_get(op->ptr, "group"); + BLI_assert(nr+1 >= 0); ob->actdef= nr+1; - BLI_assert(ob->actdef >= 0); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob); @@ -2766,7 +2708,7 @@ static EnumPropertyItem *vgroup_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); EnumPropertyItem tmp = {0, "", 0, "", ""}; EnumPropertyItem *item= NULL; bDeformGroup *def; @@ -2835,8 +2777,11 @@ MDeformVert *dvert= NULL; bDeformGroup *def; int defbase_tot = BLI_countlist(&ob->defbase); - int *sort_map_update= MEM_mallocN(sizeof(int) * (defbase_tot + 1), "sort vgroups"); /* needs a dummy index at the start*/ + + /* needs a dummy index at the start*/ + int *sort_map_update= MEM_mallocN(sizeof(int) * (defbase_tot + 1), "sort vgroups"); int *sort_map= sort_map_update + 1; + char *name; int i; @@ -2886,8 +2831,8 @@ sort_map_update[0]= 0; vgroup_remap_update_users(ob, sort_map_update); + BLI_assert(sort_map_update[ob->actdef] >= 0); ob->actdef= sort_map_update[ob->actdef]; - BLI_assert(ob->actdef >= 0); MEM_freeN(sort_map_update); @@ -2904,7 +2849,7 @@ static int vertex_group_sort_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); char *name_array; int ret; @@ -2943,7 +2888,7 @@ static int vgroup_move_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); bDeformGroup *def; char *name_array; int dir= RNA_enum_get(op->ptr, "direction"), ret; diff -Nru blender-2.61/source/blender/editors/physics/dynamicpaint_ops.c blender-2.62/source/blender/editors/physics/dynamicpaint_ops.c --- blender-2.61/source/blender/editors/physics/dynamicpaint_ops.c 2011-12-13 19:51:38.000000000 +0000 +++ blender-2.62/source/blender/editors/physics/dynamicpaint_ops.c 2012-02-15 19:36:24.000000000 +0000 @@ -42,6 +42,7 @@ #include "ED_mesh.h" #include "ED_screen.h" +#include "ED_object.h" #include "RNA_access.h" #include "RNA_define.h" @@ -58,7 +59,7 @@ static int surface_slot_add_exec(bContext *C, wmOperator *UNUSED(op)) { DynamicPaintModifierData *pmd = NULL; - Object *cObject = CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *cObject = ED_object_context(C); DynamicPaintCanvasSettings *canvas; DynamicPaintSurface *surface; @@ -100,7 +101,7 @@ static int surface_slot_remove_exec(bContext *C, wmOperator *UNUSED(op)) { DynamicPaintModifierData *pmd = NULL; - Object *cObject = CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *cObject = ED_object_context(C); DynamicPaintCanvasSettings *canvas; DynamicPaintSurface *surface; int id=0; @@ -148,7 +149,7 @@ static int type_toggle_exec(bContext *C, wmOperator *op) { - Object *cObject = CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *cObject = ED_object_context(C); Scene *scene = CTX_data_scene(C); DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)modifiers_findByType(cObject, eModifierType_DynamicPaint); int type= RNA_enum_get(op->ptr, "type"); @@ -199,7 +200,7 @@ static int output_toggle_exec(bContext *C, wmOperator *op) { - Object *ob = CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob = ED_object_context(C); Scene *scene = CTX_data_scene(C); DynamicPaintSurface *surface; DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)modifiers_findByType(ob, eModifierType_DynamicPaint); @@ -344,7 +345,7 @@ { DynamicPaintModifierData *pmd = NULL; DynamicPaintCanvasSettings *canvas; - Object *ob = CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob = ED_object_context(C); int status = 0; double timer = PIL_check_seconds_timer(); char result_str[80]; diff -Nru blender-2.61/source/blender/editors/physics/particle_edit.c blender-2.62/source/blender/editors/physics/particle_edit.c --- blender-2.61/source/blender/editors/physics/particle_edit.c 2011-12-13 19:51:38.000000000 +0000 +++ blender-2.62/source/blender/editors/physics/particle_edit.c 2012-02-15 19:36:24.000000000 +0000 @@ -254,13 +254,21 @@ } else if(pset->edittype == PE_TYPE_SOFTBODY && pid->type == PTCACHE_TYPE_SOFTBODY) { if(create && pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit) + { + pset->flag |= PE_FADE_TIME; + // NICE TO HAVE but doesn't work: pset->brushtype = PE_BRUSH_COMB; PE_create_particle_edit(scene, ob, pid->cache, NULL); + } edit = pid->cache->edit; break; } else if(pset->edittype == PE_TYPE_CLOTH && pid->type == PTCACHE_TYPE_CLOTH) { if(create && pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit) + { + pset->flag |= PE_FADE_TIME; + // NICE TO HAVE but doesn't work: pset->brushtype = PE_BRUSH_COMB; PE_create_particle_edit(scene, ob, pid->cache, NULL); + } edit = pid->cache->edit; break; } @@ -1872,43 +1880,6 @@ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } -static int select_inverse_exec(bContext *C, wmOperator *UNUSED(op)) -{ - PEData data; - PTCacheEdit *edit; - POINT_P; KEY_K; - - PE_set_data(C, &data); - - edit= PE_get_current(data.scene, data.ob); - - LOOP_VISIBLE_POINTS { - LOOP_KEYS { - key->flag ^= PEK_SELECT; - point->flag |= PEP_EDIT_RECALC; /* redraw selection only */ - } - } - - PE_update_selection(data.scene, data.ob, 1); - WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob); - - return OPERATOR_FINISHED; -} - -void PARTICLE_OT_select_inverse(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Select Inverse"; - ot->idname= "PARTICLE_OT_select_inverse"; - - /* api callbacks */ - ot->exec= select_inverse_exec; - ot->poll= PE_poll; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - /************************ rekey operator ************************/ static void rekey_particle(PEData *data, int pa_index) @@ -3659,8 +3630,14 @@ PE_update_object(scene, ob, 1); } - WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob); - + if(edit->psys) + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob); + else + { + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); + } + bedit->lastmouse[0]= mouse[0]; bedit->lastmouse[1]= mouse[1]; bedit->first= 0; diff -Nru blender-2.61/source/blender/editors/physics/particle_object.c blender-2.62/source/blender/editors/physics/particle_object.c --- blender-2.61/source/blender/editors/physics/particle_object.c 2011-12-13 19:51:38.000000000 +0000 +++ blender-2.62/source/blender/editors/physics/particle_object.c 2012-02-15 19:36:24.000000000 +0000 @@ -59,6 +59,7 @@ #include "ED_particle.h" #include "ED_screen.h" +#include "ED_object.h" #include "physics_intern.h" @@ -66,7 +67,7 @@ static int particle_system_add_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); Scene *scene = CTX_data_scene(C); if(!scene || !ob) @@ -97,7 +98,7 @@ static int particle_system_remove_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); Scene *scene = CTX_data_scene(C); int mode_orig = ob->mode; if(!scene || !ob) @@ -581,7 +582,7 @@ static int disconnect_hair_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); ParticleSystem *psys= NULL; int all = RNA_boolean_get(op->ptr, "all"); @@ -719,7 +720,7 @@ static int connect_hair_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); ParticleSystem *psys= NULL; int all = RNA_boolean_get(op->ptr, "all"); diff -Nru blender-2.61/source/blender/editors/physics/physics_fluid.c blender-2.62/source/blender/editors/physics/physics_fluid.c --- blender-2.61/source/blender/editors/physics/physics_fluid.c 2011-12-13 19:51:38.000000000 +0000 +++ blender-2.62/source/blender/editors/physics/physics_fluid.c 2012-02-15 19:36:24.000000000 +0000 @@ -109,10 +109,22 @@ return 2.0e-3; case 1: /* manual */ default: - return (1.0/pow(10.0, settings->viscosityExponent)) * settings->viscosityValue; + return (1.0f/powf(10.0f, settings->viscosityExponent)) * settings->viscosityValue; } } +static float get_fluid_rate(FluidsimSettings *settings) +{ + float rate = 1.0f; /* default rate if not animated... */ + + rate = settings->animRate; + + if (rate < 0.0f) + rate = 0.0f; + + return rate; +} + static void get_fluid_gravity(float *gravity, Scene *scene, FluidsimSettings *fss) { if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) { @@ -146,7 +158,8 @@ #if 0 /* helper function */ -void fluidsimGetGeometryObjFilename(Object *ob, char *dst) { //, char *srcname) { +void fluidsimGetGeometryObjFilename(Object *ob, char *dst) { //, char *srcname) +{ //BLI_snprintf(dst,FILE_MAXFILE, "%s_cfgdata_%s.bobj.gz", srcname, ob->id.name); BLI_snprintf(dst,FILE_MAXFILE, "fluidcfgdata_%s.bobj.gz", ob->id.name); } @@ -242,7 +255,7 @@ channels->timeAtFrame[0] = channels->timeAtFrame[1] = domainSettings->animStart; // start at index 1 - for(i=2; i<=channels->length; i++) { + for (i=2; i <= channels->length; i++) { channels->timeAtFrame[i] = channels->timeAtFrame[i-1] + channels->aniFrameTime; } } @@ -304,6 +317,8 @@ channels->DomainGravity = NULL; MEM_freeN(channels->DomainViscosity); channels->DomainViscosity = NULL; + MEM_freeN(channels->DomainTime); + channels->DomainTime = NULL; } static void free_all_fluidobject_channels(ListBase *fobjects) @@ -350,14 +365,13 @@ int length = channels->length; float eval_time; - /* XXX: first init time channel - temporary for now */ - /* init time values (should be done after evaluating animated time curve) */ + /* init time values (assuming that time moves at a constant speed; may be overridden later) */ init_time(domainSettings, channels); /* allocate domain animation channels */ channels->DomainGravity = MEM_callocN( length * (CHANNEL_VEC+1) * sizeof(float), "channel DomainGravity"); channels->DomainViscosity = MEM_callocN( length * (CHANNEL_FLOAT+1) * sizeof(float), "channel DomainViscosity"); - //channels->DomainTime = MEM_callocN( length * (CHANNEL_FLOAT+1) * sizeof(float), "channel DomainTime"); + channels->DomainTime = MEM_callocN( length * (CHANNEL_FLOAT+1) * sizeof(float), "channel DomainTime"); /* allocate fluid objects */ for (base=scene->base.first; base; base= base->next) { @@ -405,10 +419,9 @@ for (i=0; ilength; i++) { FluidObject *fobj; float viscosity, gravity[3]; - float timeAtFrame; + float timeAtFrame, time; eval_time = domainSettings->bakeStart + i; - timeAtFrame = channels->timeAtFrame[i+1]; /* XXX: This can't be used due to an anim sys optimisation that ignores recalc object animation, * leaving it for the depgraph (this ignores object animation such as modifier properties though... :/ ) @@ -424,12 +437,24 @@ /* now scene data should be current according to animation system, so we fill the channels */ - /* Domain properties - gravity/viscosity/time */ + /* Domain time */ + // TODO: have option for not running sim, time mangling, in which case second case comes in handy + if (channels->DomainTime) { + time = get_fluid_rate(domainSettings) * channels->aniFrameTime; + timeAtFrame = channels->timeAtFrame[i] + time; + + channels->timeAtFrame[i+1] = timeAtFrame; + set_channel(channels->DomainTime, i, &time, i, CHANNEL_FLOAT); + } + else { + timeAtFrame = channels->timeAtFrame[i+1]; + } + + /* Domain properties - gravity/viscosity */ get_fluid_gravity(gravity, scene, domainSettings); set_channel(channels->DomainGravity, timeAtFrame, gravity, i, CHANNEL_VEC); viscosity = get_fluid_viscosity(domainSettings); set_channel(channels->DomainViscosity, timeAtFrame, &viscosity, i, CHANNEL_FLOAT); - // XXX : set_channel(channels->DomainTime, timeAtFrame, &time, i, CHANNEL_VEC); /* object movement */ for (fobj=fobjects->first; fobj; fobj=fobj->next) { @@ -769,7 +794,8 @@ } } -int runSimulationCallback(void *data, int status, int frame) { +int runSimulationCallback(void *data, int status, int frame) +{ FluidBakeJob *fb = (FluidBakeJob *)data; elbeemSimulationSettings *settings = fb->settings; @@ -882,7 +908,7 @@ if(getenv(strEnvName)) { int dlevel = atoi(getenv(strEnvName)); elbeemSetDebugLevel(dlevel); - BLI_snprintf(debugStrBuffer,256,"fluidsimBake::msg: Debug messages activated due to envvar '%s'\n",strEnvName); + BLI_snprintf(debugStrBuffer, sizeof(debugStrBuffer),"fluidsimBake::msg: Debug messages activated due to envvar '%s'\n",strEnvName); elbeemDebugOut(debugStrBuffer); } @@ -919,7 +945,7 @@ /* rough check of settings... */ if(domainSettings->previewresxyz > domainSettings->resolutionxyz) { - BLI_snprintf(debugStrBuffer,256,"fluidsimBake::warning - Preview (%d) >= Resolution (%d)... setting equal.\n", domainSettings->previewresxyz , domainSettings->resolutionxyz); + BLI_snprintf(debugStrBuffer,sizeof(debugStrBuffer),"fluidsimBake::warning - Preview (%d) >= Resolution (%d)... setting equal.\n", domainSettings->previewresxyz , domainSettings->resolutionxyz); elbeemDebugOut(debugStrBuffer); domainSettings->previewresxyz = domainSettings->resolutionxyz; } @@ -939,7 +965,7 @@ } else { gridlevels = domainSettings->maxRefine; } - BLI_snprintf(debugStrBuffer,256,"fluidsimBake::msg: Baking %s, refine: %d\n", fsDomain->id.name , gridlevels ); + BLI_snprintf(debugStrBuffer,sizeof(debugStrBuffer),"fluidsimBake::msg: Baking %s, refine: %d\n", fsDomain->id.name , gridlevels ); elbeemDebugOut(debugStrBuffer); @@ -955,43 +981,11 @@ /* reset to original current frame */ scene->r.cfra = origFrame; ED_update_for_newframe(CTX_data_main(C), scene, CTX_wm_screen(C), 1); - - - /* ---- XXX: No Time animation curve for now, leaving this code here for reference - - { int timeIcu[1] = { FLUIDSIM_TIME }; - float timeDef[1] = { 1. }; - - // time channel is a bit special, init by hand... - timeAtIndex = MEM_callocN( (allchannelSize+1)*1*sizeof(float), "fluidsiminit_timeatindex"); - for(i=0; i<=scene->r.efra; i++) { - timeAtIndex[i] = (float)(i-startFrame); - } - fluidsimInitChannel(scene, &channelDomainTime, allchannelSize, timeAtIndex, timeIcu,timeDef, domainSettings->ipo, CHANNEL_FLOAT ); // NDEB - // time channel is a multiplicator for - if(channelDomainTime) { - for(i=0; ianimStart; // start at index 1 - if(channelDomainTime) { - for(i=2; i<=allchannelSize; i++) { - timeAtFrame[i] = timeAtFrame[i-1]+channelDomainTime[(i-1)*2+0]; - } - fsset->} else { - for(i=2; i<=allchannelSize; i++) { timeAtFrame[i] = timeAtFrame[i-1]+aniFrameTime; } - } - - } // domain channel init - */ /* ******** init domain object's matrix ******** */ copy_m4_m4(domainMat, fsDomain->obmat); if(!invert_m4_m4(invDomMat, domainMat)) { - BLI_snprintf(debugStrBuffer,256,"fluidsimBake::error - Invalid obj matrix?\n"); + BLI_snprintf(debugStrBuffer,sizeof(debugStrBuffer),"fluidsimBake::error - Invalid obj matrix?\n"); elbeemDebugOut(debugStrBuffer); BKE_report(reports, RPT_ERROR, "Invalid object matrix"); @@ -1040,7 +1034,7 @@ fsset->surfaceSmoothing = domainSettings->surfaceSmoothing; fsset->surfaceSubdivs = domainSettings->surfaceSubdivs; fsset->farFieldSize = domainSettings->farFieldSize; - BLI_strncpy(fsset->outputPath, targetFile, 240); + BLI_strncpy(fsset->outputPath, targetFile, sizeof(fsset->outputPath)); // domain channels fsset->channelSizeFrameTime = diff -Nru blender-2.61/source/blender/editors/physics/physics_intern.h blender-2.62/source/blender/editors/physics/physics_intern.h --- blender-2.61/source/blender/editors/physics/physics_intern.h 2011-12-13 19:51:38.000000000 +0000 +++ blender-2.62/source/blender/editors/physics/physics_intern.h 2012-02-15 19:36:24.000000000 +0000 @@ -42,7 +42,6 @@ void PARTICLE_OT_select_linked(struct wmOperatorType *ot); void PARTICLE_OT_select_less(struct wmOperatorType *ot); void PARTICLE_OT_select_more(struct wmOperatorType *ot); -void PARTICLE_OT_select_inverse(struct wmOperatorType *ot); void PARTICLE_OT_hide(struct wmOperatorType *ot); void PARTICLE_OT_reveal(struct wmOperatorType *ot); diff -Nru blender-2.61/source/blender/editors/physics/physics_ops.c blender-2.62/source/blender/editors/physics/physics_ops.c --- blender-2.61/source/blender/editors/physics/physics_ops.c 2011-12-13 19:51:38.000000000 +0000 +++ blender-2.62/source/blender/editors/physics/physics_ops.c 2012-02-15 19:36:24.000000000 +0000 @@ -39,8 +39,11 @@ #include "ED_physics.h" #include "ED_object.h" +#include "BLI_utildefines.h" + #include "physics_intern.h" // own include + /***************************** particles ***********************************/ static void operatortypes_particle(void) @@ -51,7 +54,6 @@ WM_operatortype_append(PARTICLE_OT_select_linked); WM_operatortype_append(PARTICLE_OT_select_less); WM_operatortype_append(PARTICLE_OT_select_more); - WM_operatortype_append(PARTICLE_OT_select_inverse); WM_operatortype_append(PARTICLE_OT_hide); WM_operatortype_append(PARTICLE_OT_reveal); @@ -94,33 +96,41 @@ keymap= WM_keymap_find(keyconf, "Particle", 0, 0); keymap->poll= PE_poll; - WM_keymap_add_item(keymap, "PARTICLE_OT_select_all", AKEY, KM_PRESS, 0, 0); + kmi = WM_keymap_add_item(keymap, "PARTICLE_OT_select_all", AKEY, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE); + kmi = WM_keymap_add_item(keymap, "PARTICLE_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0); + RNA_enum_set(kmi->ptr, "action", SEL_INVERT); + WM_keymap_add_item(keymap, "PARTICLE_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "PARTICLE_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "PARTICLE_OT_select_linked", LKEY, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "PARTICLE_OT_select_linked", LKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "deselect", 1); - WM_keymap_add_item(keymap, "PARTICLE_OT_select_inverse", IKEY, KM_PRESS, KM_CTRL, 0); + + kmi = WM_keymap_add_item(keymap, "PARTICLE_OT_select_linked", LKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "deselect", FALSE); + kmi = WM_keymap_add_item(keymap, "PARTICLE_OT_select_linked", LKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "deselect", TRUE); WM_keymap_add_item(keymap, "PARTICLE_OT_delete", XKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "PARTICLE_OT_delete", DELKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "PARTICLE_OT_reveal", HKEY, KM_PRESS, KM_ALT, 0); - WM_keymap_add_item(keymap, "PARTICLE_OT_hide", HKEY, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "PARTICLE_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "unselected", 1); + kmi = WM_keymap_add_item(keymap, "PARTICLE_OT_hide", HKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "unselected", FALSE); + kmi = WM_keymap_add_item(keymap, "PARTICLE_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "unselected", TRUE); kmi = WM_keymap_verify_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_ANY, 0); - RNA_boolean_set(kmi->ptr, "release_confirm", 1); + RNA_boolean_set(kmi->ptr, "release_confirm", TRUE); WM_keymap_add_item(keymap, "PARTICLE_OT_brush_edit", LEFTMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "PARTICLE_OT_brush_edit", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0); /* size radial control */ kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, 0, 0); - RNA_string_set(kmi->ptr, "data_path", "tool_settings.particle_edit.brush.size"); + RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.particle_edit.brush.size"); /* size radial control */ kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0); - RNA_string_set(kmi->ptr, "data_path", "tool_settings.particle_edit.brush.strength"); + RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.particle_edit.brush.strength"); WM_keymap_add_menu(keymap, "VIEW3D_MT_particle_specials", WKEY, KM_PRESS, 0, 0); diff -Nru blender-2.61/source/blender/editors/physics/physics_pointcache.c blender-2.62/source/blender/editors/physics/physics_pointcache.c --- blender-2.61/source/blender/editors/physics/physics_pointcache.c 2011-12-13 19:51:38.000000000 +0000 +++ blender-2.62/source/blender/editors/physics/physics_pointcache.c 2012-02-15 19:36:24.000000000 +0000 @@ -59,7 +59,8 @@ #include "physics_intern.h" -static int cache_break_test(void *UNUSED(cbd)) { +static int cache_break_test(void *UNUSED(cbd)) +{ return G.afbreek==1; } static int ptcache_bake_all_poll(bContext *C) diff -Nru blender-2.61/source/blender/editors/render/render_internal.c blender-2.62/source/blender/editors/render/render_internal.c --- blender-2.61/source/blender/editors/render/render_internal.c 2011-12-13 19:52:30.000000000 +0000 +++ blender-2.62/source/blender/editors/render/render_internal.c 2012-02-15 19:37:05.000000000 +0000 @@ -76,10 +76,10 @@ /* called inside thread! */ void image_buffer_rect_update(Scene *scene, RenderResult *rr, ImBuf *ibuf, volatile rcti *renrect) { - float x1, y1, *rectf= NULL; + float *rectf= NULL; int ymin, ymax, xmin, xmax; - int rymin, rxmin, do_color_management; - char *rectc; + int rymin, rxmin, predivide, profile_from; + unsigned char *rectc; /* if renrect argument, we only refresh scanlines */ if(renrect) { @@ -136,50 +136,20 @@ imb_addrectImBuf(ibuf); rectf+= 4*(rr->rectx*ymin + xmin); - rectc= (char *)(ibuf->rect + ibuf->x*rymin + rxmin); + rectc= (unsigned char*)(ibuf->rect + ibuf->x*rymin + rxmin); - do_color_management = (scene && (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT)); - - /* XXX make nice consistent functions for this */ - for(y1= 0; y1dither / 255.0f; - - /* XXX temp. because crop offset */ - if(rectc >= (char *)(ibuf->rect)) { - for(x1= 0; x1rectx; - rectc += 4*ibuf->x; + if(scene && (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT)) { + profile_from= IB_PROFILE_LINEAR_RGB; + predivide= (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE); } + else { + profile_from= IB_PROFILE_SRGB; + predivide= 0; + } + + IMB_buffer_byte_from_float(rectc, rectf, + 4, ibuf->dither, IB_PROFILE_SRGB, profile_from, predivide, + xmax, ymax, ibuf->x, rr->rectx); } /* ****************************** render invoking ***************** */ @@ -190,7 +160,7 @@ static void screen_render_scene_layer_set(wmOperator *op, Main *mainp, Scene **scene, SceneRenderLayer **srl) { /* single layer re-render */ - if(RNA_property_is_set(op->ptr, "scene")) { + if(RNA_struct_property_is_set(op->ptr, "scene")) { Scene *scn; char scene_name[MAX_ID_NAME-2]; @@ -206,7 +176,7 @@ } } - if(RNA_property_is_set(op->ptr, "layer")) { + if(RNA_struct_property_is_set(op->ptr, "layer")) { SceneRenderLayer *rl; char rl_name[RE_MAXNAME]; @@ -567,7 +537,7 @@ /* custom scene and single layer re-render */ screen_render_scene_layer_set(op, mainp, &scene, &srl); - if(RNA_property_is_set(op->ptr, "layer")) + if(RNA_struct_property_is_set(op->ptr, "layer")) jobflag |= WM_JOB_SUSPEND; /* job custom data */ diff -Nru blender-2.61/source/blender/editors/render/render_opengl.c blender-2.62/source/blender/editors/render/render_opengl.c --- blender-2.61/source/blender/editors/render/render_opengl.c 2011-12-13 19:52:30.000000000 +0000 +++ blender-2.62/source/blender/editors/render/render_opengl.c 2012-02-15 19:37:05.000000000 +0000 @@ -40,11 +40,13 @@ #include "BLI_editVert.h" #include "BLI_dlrbTree.h" #include "BLI_utildefines.h" +#include "BLI_jitter.h" #include "DNA_scene_types.h" #include "DNA_object_types.h" #include "BKE_context.h" +#include "BKE_global.h" #include "BKE_image.h" #include "BKE_main.h" #include "BKE_report.h" @@ -81,6 +83,11 @@ RegionView3D *rv3d; ARegion *ar; + ScrArea *prevsa; + ARegion *prevar; + + short obcenter_dia_back; /* temp overwrite */ + Image *ima; ImageUser iuser; @@ -148,28 +155,31 @@ } else { /* simple accumulation, less hassle then FSAA FBO's */ -# define SAMPLES 5 /* fixed, easy to have more but for now this is ok */ - const float jit_ofs[SAMPLES][2] = {{0, 0}, {0.5f, 0.5f}, {-0.5f,-0.5f}, {-0.5f, 0.5f}, {0.5f, -0.5f}}; + static float jit_ofs[32][2]; float winmat_jitter[4][4]; float *accum_buffer= MEM_mallocN(sizex * sizey * sizeof(float) * 4, "accum1"); float *accum_tmp= MEM_mallocN(sizex * sizey * sizeof(float) * 4, "accum2"); int j; + BLI_initjit(jit_ofs[0], scene->r.osa); + /* first sample buffer, also initializes 'rv3d->persmat' */ ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat); GPU_offscreen_read_pixels(oglrender->ofs, GL_FLOAT, accum_buffer); /* skip the first sample */ - for(j=1; j < SAMPLES; j++) { + for(j=1; j < scene->r.osa; j++) { copy_m4_m4(winmat_jitter, winmat); - window_translate_m4(winmat_jitter, rv3d->persmat, jit_ofs[j][0] / sizex, jit_ofs[j][1] / sizey); + window_translate_m4(winmat_jitter, rv3d->persmat, + (jit_ofs[j][0] * 2.0f) / sizex, + (jit_ofs[j][1] * 2.0f) / sizey); ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat_jitter); GPU_offscreen_read_pixels(oglrender->ofs, GL_FLOAT, accum_tmp); add_vn_vn(accum_buffer, accum_tmp, sizex*sizey*sizeof(float)); } - mul_vn_vn_fl(rr->rectf, accum_buffer, sizex*sizey*sizeof(float), 1.0/SAMPLES); + mul_vn_vn_fl(rr->rectf, accum_buffer, sizex*sizey*sizeof(float), 1.0f / scene->r.osa); MEM_freeN(accum_buffer); MEM_freeN(accum_tmp); @@ -206,14 +216,11 @@ * float buffer. */ if(oglrender->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) { - float *rctf = rr->rectf; - int i; + int predivide= 0; /* no alpha */ - for (i = oglrender->sizex * oglrender->sizey; i > 0; i--, rctf+=4) { - rctf[0]= srgb_to_linearrgb(rctf[0]); - rctf[1]= srgb_to_linearrgb(rctf[1]); - rctf[2]= srgb_to_linearrgb(rctf[2]); - } + IMB_buffer_float_from_float(rr->rectf, rr->rectf, + 4, IB_PROFILE_LINEAR_RGB, IB_PROFILE_SRGB, predivide, + oglrender->sizex, oglrender->sizey, oglrender->sizex, oglrender->sizex); } RE_ReleaseResult(oglrender->re); @@ -233,7 +240,7 @@ } BKE_makepicstring(name, scene->r.pic, oglrender->bmain->name, scene->r.cfra, scene->r.im_format.imtype, scene->r.scemode & R_EXTENSION, FALSE); - ok= BKE_write_ibuf(ibuf, name, &scene->r.im_format); /* no need to stamp here */ + ok= BKE_write_ibuf_as(ibuf, name, &scene->r.im_format, TRUE); /* no need to stamp here */ if(ok) printf("OpenGL Render written to '%s'\n", name); else printf("OpenGL Render failed to write '%s'\n", name); } @@ -246,6 +253,8 @@ { /* new render clears all callbacks */ Scene *scene= CTX_data_scene(C); + ScrArea *prevsa= CTX_wm_area(C); + ARegion *prevar= CTX_wm_region(C); RenderResult *rr; GPUOffScreen *ofs; OGLRender *oglrender; @@ -255,11 +264,16 @@ const short is_write_still= RNA_boolean_get(op->ptr, "write_still"); char err_out[256]= "unknown"; + if(G.background) { + BKE_report(op->reports, RPT_ERROR, "Can't use OpenGL render in background mode (no opengl context)"); + return 0; + } + /* ensure we have a 3d view */ if(!ED_view3d_context_activate(C)) { - RNA_boolean_set(op->ptr, "view_context", 0); - is_view_context= 0; + RNA_boolean_set(op->ptr, "view_context", FALSE); + is_view_context = 0; } /* only one render job at a time */ @@ -306,13 +320,24 @@ oglrender->write_still= is_write_still && !is_animation; + oglrender->obcenter_dia_back = U.obcenter_dia; + U.obcenter_dia = 0; + + oglrender->prevsa= prevsa; + oglrender->prevar= prevar; + if(is_view_context) { - oglrender->v3d= CTX_wm_view3d(C); - oglrender->ar= CTX_wm_region(C); - oglrender->rv3d= CTX_wm_region_view3d(C); + ED_view3d_context_user_region(C, &oglrender->v3d, &oglrender->ar); /* so quad view renders camera */ + oglrender->rv3d= oglrender->ar->regiondata; /* MUST be cleared on exit */ - oglrender->scene->customdata_mask_modal= ED_view3d_datamask(oglrender->scene, oglrender->v3d); + oglrender->scene->customdata_mask_modal = (ED_view3d_datamask(oglrender->scene, oglrender->v3d) | + ED_view3d_object_datamask(oglrender->scene) ); + + /* apply immediately incase we're rendeing from a script, + * running notifiers again will overwrite */ + oglrender->scene->customdata_mask |= oglrender->scene->customdata_mask_modal; + } /* create render */ @@ -357,10 +382,15 @@ WM_cursor_wait(0); WM_event_add_notifier(C, NC_SCENE|ND_RENDER_RESULT, oglrender->scene); + U.obcenter_dia = oglrender->obcenter_dia_back; + GPU_offscreen_free(oglrender->ofs); oglrender->scene->customdata_mask_modal= 0; + CTX_wm_area_set(C, oglrender->prevsa); + CTX_wm_region_set(C, oglrender->prevar); + MEM_freeN(oglrender); } @@ -468,7 +498,8 @@ } if(BKE_imtype_is_movie(scene->r.im_format.imtype)) { - ok= oglrender->mh->append_movie(&scene->r, CFRA, (int*)ibuf->rect, oglrender->sizex, oglrender->sizey, oglrender->reports); + ok= oglrender->mh->append_movie(&scene->r, SFRA, CFRA, (int*)ibuf->rect, + oglrender->sizex, oglrender->sizey, oglrender->reports); if(ok) { printf("Append frame %d", scene->r.cfra); BKE_reportf(op->reports, RPT_INFO, "Appended frame: %d", scene->r.cfra); diff -Nru blender-2.61/source/blender/editors/render/render_preview.c blender-2.62/source/blender/editors/render/render_preview.c --- blender-2.61/source/blender/editors/render/render_preview.c 2011-12-13 19:52:30.000000000 +0000 +++ blender-2.62/source/blender/editors/render/render_preview.c 2012-02-15 19:37:05.000000000 +0000 @@ -104,7 +104,7 @@ { static const int flags = IB_rect|IB_multilayer|IB_metadata; - char path[240]; + char path[FILE_MAX]; char *folder; if (!(brush->icon_imbuf)) { @@ -460,12 +460,15 @@ Render *re; RenderResult rres; char name[32]; - int do_gamma_correct=0; + int do_gamma_correct=0, do_predivide=0; int offx=0, newx= rect->xmax-rect->xmin, newy= rect->ymax-rect->ymin; if (id && GS(id->name) != ID_TE) { /* exception: don't color manage texture previews - show the raw values */ - if (sce) do_gamma_correct = sce->r.color_mgt_flag & R_COLOR_MANAGEMENT; + if (sce) { + do_gamma_correct = sce->r.color_mgt_flag & R_COLOR_MANAGEMENT; + do_predivide = sce->r.color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE; + } } if(!split || first) sprintf(name, "Preview %p", (void *)sa); @@ -488,10 +491,28 @@ if(rres.rectf) { if(ABS(rres.rectx-newx)<2 && ABS(rres.recty-newy)<2) { + newrect->xmax= MAX2(newrect->xmax, rect->xmin + rres.rectx + offx); newrect->ymax= MAX2(newrect->ymax, rect->ymin + rres.recty); - glaDrawPixelsSafe_to32(rect->xmin+offx, rect->ymin, rres.rectx, rres.recty, rres.rectx, rres.rectf, do_gamma_correct); + if(rres.rectx && rres.recty) { + /* temporary conversion to byte for drawing */ + float fx= rect->xmin + offx; + float fy= rect->ymin; + int profile_from= (do_gamma_correct)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB; + int dither= 0; + unsigned char *rect_byte; + + rect_byte= MEM_mallocN(rres.rectx*rres.recty*sizeof(int), "ed_preview_draw_rect"); + + IMB_buffer_byte_from_float(rect_byte, rres.rectf, + 4, dither, IB_PROFILE_SRGB, profile_from, do_predivide, + rres.rectx, rres.recty, rres.rectx, rres.rectx); + + glaDrawPixelsSafe(fx, fy, rres.rectx, rres.recty, rres.rectx, GL_RGBA, GL_UNSIGNED_BYTE, rect_byte); + + MEM_freeN(rect_byte); + } RE_ReleaseResultImage(re); return 1; diff -Nru blender-2.61/source/blender/editors/render/render_shading.c blender-2.62/source/blender/editors/render/render_shading.c --- blender-2.61/source/blender/editors/render/render_shading.c 2011-12-13 19:52:30.000000000 +0000 +++ blender-2.62/source/blender/editors/render/render_shading.c 2012-02-15 19:37:05.000000000 +0000 @@ -73,6 +73,7 @@ #include "WM_api.h" #include "WM_types.h" +#include "ED_object.h" #include "ED_curve.h" #include "ED_mesh.h" #include "ED_node.h" @@ -91,7 +92,7 @@ static int material_slot_add_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); if(!ob) return OPERATOR_CANCELLED; @@ -120,7 +121,7 @@ static int material_slot_remove_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); if(!ob) return OPERATOR_CANCELLED; @@ -156,7 +157,7 @@ static int material_slot_assign_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); if(!ob) return OPERATOR_CANCELLED; @@ -216,7 +217,7 @@ static int material_slot_de_select(bContext *C, int select) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); if(!ob) return OPERATOR_CANCELLED; @@ -322,7 +323,7 @@ static int material_slot_copy_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); Material ***matar; if(!ob || !(matar= give_matarar(ob))) @@ -704,7 +705,7 @@ { //Scene *scene= CTX_data_scene(C); - if(RNA_property_is_set(op->ptr, "filepath")) + if(RNA_struct_property_is_set(op->ptr, "filepath")) return envmap_save_exec(C, op); //RNA_enum_set(op->ptr, "file_type", scene->r.im_format.imtype); @@ -748,7 +749,7 @@ prop= RNA_def_float_array(ot->srna, "layout", 12, default_envmap_layout, 0.0f, 0.0f, "File layout", "Flat array describing the X,Y position of each cube face in the output image, where 1 is the size of a face - order is [+Z -Z +Y -X -Y +X] (use -1 to skip a face)", 0.0f, 0.0f); RNA_def_property_flag(prop, PROP_HIDDEN); - WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH); + WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); } static int envmap_clear_exec(bContext *C, wmOperator *UNUSED(op)) diff -Nru blender-2.61/source/blender/editors/screen/area.c blender-2.62/source/blender/editors/screen/area.c --- blender-2.61/source/blender/editors/screen/area.c 2011-12-13 19:51:35.000000000 +0000 +++ blender-2.62/source/blender/editors/screen/area.c 2012-02-15 19:36:19.000000000 +0000 @@ -478,7 +478,7 @@ glClear(GL_COLOR_BUFFER_BIT); UI_ThemeColor(TH_TEXT); - BLF_draw_default(20, 8, 0.0f, ar->headerstr, 65535); /* XXX, use real length */ + BLF_draw_default(20, 8, 0.0f, ar->headerstr, BLF_DRAW_STR_DUMMY_MAX); } else if(at->draw) { at->draw(C, ar); @@ -1809,5 +1809,5 @@ /* text */ UI_ThemeColor(TH_TEXT_HI); BLF_position(fontid, 12, rect.ymin + 5, 0.0f); - BLF_draw(fontid, text, strlen(text)); + BLF_draw(fontid, text, BLF_DRAW_STR_DUMMY_MAX); } diff -Nru blender-2.61/source/blender/editors/screen/glutil.c blender-2.62/source/blender/editors/screen/glutil.c --- blender-2.61/source/blender/editors/screen/glutil.c 2011-12-13 19:51:35.000000000 +0000 +++ blender-2.62/source/blender/editors/screen/glutil.c 2012-02-15 19:36:19.000000000 +0000 @@ -559,27 +559,6 @@ glaDrawPixelsTexScaled(x, y, img_w, img_h, format, rect, 1.0f, 1.0f); } -/* row_w is unused but kept for completeness */ -void glaDrawPixelsSafe_to32(float fx, float fy, int img_w, int img_h, int UNUSED(row_w), float *rectf, int do_gamma_correct) -{ - unsigned char *rect32; - - /* copy imgw-imgh to a temporal 32 bits rect */ - if(img_w<1 || img_h<1) return; - - rect32= MEM_mallocN(img_w*img_h*sizeof(int), "temp 32 bits"); - - if (do_gamma_correct) { - floatbuf_to_srgb_byte(rectf, rect32, 0, img_w, 0, img_h, img_w); - } else { - floatbuf_to_byte(rectf, rect32, 0, img_w, 0, img_h, img_w); - } - - glaDrawPixelsSafe(fx, fy, img_w, img_h, img_w, GL_RGBA, GL_UNSIGNED_BYTE, rect32); - - MEM_freeN(rect32); -} - void glaDrawPixelsSafe(float x, float y, int img_w, int img_h, int row_w, int format, int type, void *rect) { float xzoom= glaGetOneFloat(GL_ZOOM_X); diff -Nru blender-2.61/source/blender/editors/screen/screendump.c blender-2.62/source/blender/editors/screen/screendump.c --- blender-2.61/source/blender/editors/screen/screendump.c 2011-12-13 19:51:35.000000000 +0000 +++ blender-2.62/source/blender/editors/screen/screendump.c 2012-02-15 19:36:19.000000000 +0000 @@ -198,7 +198,7 @@ static int screenshot_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { if(screenshot_data_create(C, op)) { - if(RNA_property_is_set(op->ptr, "filepath")) + if(RNA_struct_property_is_set(op->ptr, "filepath")) return screenshot_exec(C, op); RNA_string_set(op->ptr, "filepath", G.ima); @@ -228,7 +228,7 @@ ot->flag= 0; - WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH); + WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); RNA_def_boolean(ot->srna, "full", 1, "Full Screen", ""); } @@ -278,7 +278,6 @@ ScreenshotJob *sj= sjv; RenderData rd= sj->scene->r; bMovieHandle *mh= BKE_get_movie_handle(sj->scene->r.im_format.imtype); - int cfra= 1; /* we need this as local variables for renderdata */ rd.frs_sec= U.scrcastfps; @@ -303,9 +302,11 @@ if(sj->dumprect) { if(mh) { - if(mh->append_movie(&rd, cfra, (int *)sj->dumprect, sj->dumpsx, sj->dumpsy, &sj->reports)) { - BKE_reportf(&sj->reports, RPT_INFO, "Appended frame: %d", cfra); - printf("Appended frame %d\n", cfra); + if(mh->append_movie(&rd, rd.sfra, rd.cfra, (int *)sj->dumprect, + sj->dumpsx, sj->dumpsy, &sj->reports)) + { + BKE_reportf(&sj->reports, RPT_INFO, "Appended frame: %d", rd.cfra); + printf("Appended frame %d\n", rd.cfra); } else break; } @@ -314,7 +315,7 @@ char name[FILE_MAX]; int ok; - BKE_makepicstring(name, rd.pic, sj->bmain->name, cfra, rd.im_format.imtype, rd.scemode & R_EXTENSION, TRUE); + BKE_makepicstring(name, rd.pic, sj->bmain->name, rd.cfra, rd.im_format.imtype, rd.scemode & R_EXTENSION, TRUE); ibuf->rect= sj->dumprect; ok= BKE_write_ibuf(ibuf, name, &rd.im_format); @@ -338,7 +339,7 @@ *do_update= 1; - cfra++; + rd.cfra++; } else diff -Nru blender-2.61/source/blender/editors/screen/screen_edit.c blender-2.62/source/blender/editors/screen/screen_edit.c --- blender-2.61/source/blender/editors/screen/screen_edit.c 2011-12-13 19:51:35.000000000 +0000 +++ blender-2.62/source/blender/editors/screen/screen_edit.c 2012-02-15 19:36:19.000000000 +0000 @@ -1689,8 +1689,6 @@ /* XXX bad code: setscreen() ends with first area active. fullscreen render assumes this too */ CTX_wm_area_set(C, sc->areabase.first); - /* XXX retopo_force_update(); */ - return sc->areabase.first; } diff -Nru blender-2.61/source/blender/editors/screen/screen_ops.c blender-2.62/source/blender/editors/screen/screen_ops.c --- blender-2.61/source/blender/editors/screen/screen_ops.c 2011-12-13 19:51:35.000000000 +0000 +++ blender-2.62/source/blender/editors/screen/screen_ops.c 2012-02-15 19:36:19.000000000 +0000 @@ -44,6 +44,7 @@ #include "DNA_curve_types.h" #include "DNA_scene_types.h" #include "DNA_meta_types.h" +#include "DNA_userdef_types.h" #include "BKE_context.h" #include "BKE_customdata.h" @@ -1293,6 +1294,7 @@ op->customdata = NULL; } + WM_cursor_restore(CTX_wm_window(C)); WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL); /* this makes sure aligned edges will result in aligned grabbing */ @@ -1347,12 +1349,12 @@ int x, y; /* retrieve initial mouse coord, so we can find the active edge */ - if(RNA_property_is_set(op->ptr, "mouse_x")) + if(RNA_struct_property_is_set(op->ptr, "mouse_x")) x= RNA_int_get(op->ptr, "mouse_x"); else x= event->x; - if(RNA_property_is_set(op->ptr, "mouse_y")) + if(RNA_struct_property_is_set(op->ptr, "mouse_y")) y= RNA_int_get(op->ptr, "mouse_y"); else y= event->x; @@ -1491,6 +1493,37 @@ } } break; + + case MIDDLEMOUSE: + case TABKEY: + if (sd->previewmode==0){ + } + else{ + dir = RNA_enum_get(op->ptr, "direction"); + + if(event->val==KM_PRESS){ + if (sd->sarea){ + sd->sarea->flag &= ~(AREA_FLAG_DRAWSPLIT_H|AREA_FLAG_DRAWSPLIT_V); + ED_area_tag_redraw(sd->sarea); + + if (dir=='v'){ + RNA_enum_set(op->ptr, "direction", 'h'); + sd->sarea->flag |= AREA_FLAG_DRAWSPLIT_H; + + WM_cursor_set(CTX_wm_window(C),CURSOR_X_MOVE); + } + else{ + RNA_enum_set(op->ptr, "direction", 'v'); + sd->sarea->flag |= AREA_FLAG_DRAWSPLIT_V; + + WM_cursor_set(CTX_wm_window(C),CURSOR_Y_MOVE); + } + } + } + } + + break; + case RIGHTMOUSE: /* cancel operation */ case ESCKEY: return area_split_cancel(C, op); @@ -1634,6 +1667,47 @@ return OPERATOR_FINISHED; } +static int region_scale_get_maxsize(RegionMoveData *rmd) +{ + int maxsize= 0; + + if(rmd->edge==AE_LEFT_TO_TOPRIGHT || rmd->edge==AE_RIGHT_TO_TOPLEFT) { + return rmd->sa->winx - UI_UNIT_X; + } + + if(rmd->ar->regiontype == RGN_TYPE_TOOL_PROPS) { + /* this calculation seems overly verbose + * can someone explain why this method is necessary? - campbell */ + maxsize = rmd->maxsize - ((rmd->sa->headertype==HEADERTOP)?UI_UNIT_Y*2:UI_UNIT_Y) - (UI_UNIT_Y/4); + } + + return maxsize; +} + +static void region_scale_validate_size(RegionMoveData *rmd) +{ + if((rmd->ar->flag & RGN_FLAG_HIDDEN)==0) { + short *size, maxsize= -1; + + + if(rmd->edge==AE_LEFT_TO_TOPRIGHT || rmd->edge==AE_RIGHT_TO_TOPLEFT) + size= &rmd->ar->sizex; + else + size= &rmd->ar->sizey; + + maxsize= region_scale_get_maxsize(rmd); + + if(*size > maxsize && maxsize > 0) + *size= maxsize; + } +} + +static void region_scale_toggle_hidden(bContext *C, RegionMoveData *rmd) +{ + ED_region_toggle_hidden(C, rmd->ar); + region_scale_validate_size(rmd); +} + static int region_scale_modal(bContext *C, wmOperator *op, wmEvent *event) { RegionMoveData *rmd= op->customdata; @@ -1653,35 +1727,31 @@ if(rmd->ar->sizex < UI_UNIT_X) { rmd->ar->sizex= rmd->origval; if(!(rmd->ar->flag & RGN_FLAG_HIDDEN)) - ED_region_toggle_hidden(C, rmd->ar); + region_scale_toggle_hidden(C, rmd); } else if(rmd->ar->flag & RGN_FLAG_HIDDEN) - ED_region_toggle_hidden(C, rmd->ar); + region_scale_toggle_hidden(C, rmd); } else { - int maxsize=0; + int maxsize= region_scale_get_maxsize(rmd); delta= event->y - rmd->origy; if(rmd->edge==AE_BOTTOM_TO_TOPLEFT) delta= -delta; rmd->ar->sizey= rmd->origval + delta; CLAMP(rmd->ar->sizey, 0, rmd->maxsize); - if(rmd->ar->regiontype == RGN_TYPE_TOOL_PROPS) { - /* this calculation seems overly verbose - * can someone explain why this method is necessary? - campbell */ - maxsize = rmd->maxsize - ((rmd->sa->headertype==HEADERTOP)?UI_UNIT_Y*2:UI_UNIT_Y) - (UI_UNIT_Y/4); - } - /* note, 'UI_UNIT_Y/4' means you need to drag the header almost * all the way down for it to become hidden, this is done * otherwise its too easy to do this by accident */ - if(rmd->ar->sizey < UI_UNIT_Y/4 || (maxsize > 0 && (rmd->ar->sizey > maxsize)) ) { + if(rmd->ar->sizey < UI_UNIT_Y/4) { rmd->ar->sizey= rmd->origval; if(!(rmd->ar->flag & RGN_FLAG_HIDDEN)) - ED_region_toggle_hidden(C, rmd->ar); + region_scale_toggle_hidden(C, rmd); } + else if(maxsize > 0 && (rmd->ar->sizey > maxsize)) + rmd->ar->sizey= maxsize; else if(rmd->ar->flag & RGN_FLAG_HIDDEN) - ED_region_toggle_hidden(C, rmd->ar); + region_scale_toggle_hidden(C, rmd); } ED_area_tag_redraw(rmd->sa); WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL); @@ -1693,10 +1763,14 @@ if(ABS(event->x - rmd->origx) < 2 && ABS(event->y - rmd->origy) < 2) { if(rmd->ar->flag & RGN_FLAG_HIDDEN) { - ED_region_toggle_hidden(C, rmd->ar); - ED_area_tag_redraw(rmd->sa); - WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL); + region_scale_toggle_hidden(C, rmd); } + else if(rmd->ar->flag & RGN_FLAG_TOO_SMALL) { + region_scale_validate_size(rmd); + } + + ED_area_tag_redraw(rmd->sa); + WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL); } MEM_freeN(op->customdata); op->customdata = NULL; @@ -1748,8 +1822,9 @@ delta = RNA_int_get(op->ptr, "delta"); - scene->r.cfra += delta; - scene->r.subframe = 0.f; + CFRA += delta; + FRAMENUMBER_MIN_CLAMP(CFRA); + SUBFRA = 0.f; sound_seek_scene(bmain, scene); @@ -2989,7 +3064,7 @@ int mode= (RNA_boolean_get(op->ptr, "reverse")) ? -1 : 1; int sync= -1; - if (RNA_property_is_set(op->ptr, "sync")) + if (RNA_struct_property_is_set(op->ptr, "sync")) sync= (RNA_boolean_get(op->ptr, "sync")); return ED_screen_animation_play(C, sync, mode); @@ -3236,7 +3311,6 @@ static int scene_new_exec(bContext *C, wmOperator *op) { Scene *newscene, *scene= CTX_data_scene(C); - bScreen *screen= CTX_wm_screen(C); Main *bmain= CTX_data_main(C); int type= RNA_enum_get(op->ptr, "type"); @@ -3255,11 +3329,9 @@ } } - /* this notifier calls ED_screen_set_scene, doing a lot of UI stuff, not for inside event loops */ - WM_event_add_notifier(C, NC_SCENE|ND_SCENEBROWSE, newscene); + ED_screen_set_scene(C, newscene); - if(screen) - screen->scene= newscene; + WM_event_add_notifier(C, NC_SCENE|ND_SCENEBROWSE, newscene); return OPERATOR_FINISHED; } @@ -3295,9 +3367,14 @@ static int scene_delete_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene= CTX_data_scene(C); - + + ED_screen_delete_scene(C, scene); + + if(G.f & G_DEBUG) + printf("scene delete %p\n", scene); + WM_event_add_notifier(C, NC_SCENE|NA_REMOVED, scene); - + return OPERATOR_FINISHED; } @@ -3417,7 +3494,7 @@ { ListBase *lb; wmKeyMap *keymap; - //wmKeyMapItem *kmi; + wmKeyMapItem *kmi; /* Screen Editing ------------------------------------------------ */ keymap= WM_keymap_find(keyconf, "Screen Editing", 0, 0); @@ -3484,7 +3561,8 @@ /* render */ WM_keymap_add_item(keymap, "RENDER_OT_render", F12KEY, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "RENDER_OT_render", F12KEY, KM_PRESS, KM_CTRL, 0)->ptr, "animation", 1); + kmi = WM_keymap_add_item(keymap, "RENDER_OT_render", F12KEY, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "animation", TRUE); WM_keymap_add_item(keymap, "RENDER_OT_view_cancel", ESCKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "RENDER_OT_view_show", F11KEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "RENDER_OT_play_rendered_anim", F11KEY, KM_PRESS, KM_CTRL, 0); @@ -3508,20 +3586,21 @@ RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", WHEELDOWNMOUSE, KM_PRESS, KM_ALT, 0)->ptr, "delta", 1); RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", WHEELUPMOUSE, KM_PRESS, KM_ALT, 0)->ptr, "delta", -1); - RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", UPARROWKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "end", 1); - RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", DOWNARROWKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "end", 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", RIGHTARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "end", 1); - RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", LEFTARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "end", 0); + RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", UPARROWKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "end", TRUE); + RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", DOWNARROWKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "end", FALSE); + RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", RIGHTARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "end", TRUE); + RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", LEFTARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "end", FALSE); WM_keymap_add_item(keymap, "SCREEN_OT_keyframe_jump", UPARROWKEY, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_keyframe_jump", DOWNARROWKEY, KM_PRESS, 0, 0)->ptr, "next", 0); + RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_keyframe_jump", DOWNARROWKEY, KM_PRESS, 0, 0)->ptr, "next", FALSE); WM_keymap_add_item(keymap, "SCREEN_OT_keyframe_jump", MEDIALAST, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_keyframe_jump", MEDIAFIRST, KM_PRESS, 0, 0)->ptr, "next", 0); + kmi = WM_keymap_add_item(keymap, "SCREEN_OT_keyframe_jump", MEDIAFIRST, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "next", FALSE); /* play (forward and backwards) */ WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", AKEY, KM_PRESS, KM_ALT, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", AKEY, KM_PRESS, KM_ALT|KM_SHIFT, 0)->ptr, "reverse", 1); + RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", AKEY, KM_PRESS, KM_ALT|KM_SHIFT, 0)->ptr, "reverse", TRUE); WM_keymap_add_item(keymap, "SCREEN_OT_animation_cancel", ESCKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", MEDIAPLAY, KM_PRESS, 0, 0); @@ -3531,11 +3610,11 @@ #if 0 // XXX: disabled for restoring later... bad implementation keymap= WM_keymap_find(keyconf, "Frames", 0, 0); kmi = WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", RIGHTARROWKEY, KM_PRESS, KM_ALT, 0); - RNA_boolean_set(kmi->ptr, "cycle_speed", 1); + RNA_boolean_set(kmi->ptr, "cycle_speed", TRUE); kmi = WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", LEFTARROWKEY, KM_PRESS, KM_ALT, 0); - RNA_boolean_set(kmi->ptr, "reverse", 1); - RNA_boolean_set(kmi->ptr, "cycle_speed", 1); + RNA_boolean_set(kmi->ptr, "reverse", TRUE); + RNA_boolean_set(kmi->ptr, "cycle_speed", TRUE); WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", DOWNARROWKEY, KM_PRESS, KM_ALT, 0); #endif diff -Nru blender-2.61/source/blender/editors/sculpt_paint/CMakeLists.txt blender-2.62/source/blender/editors/sculpt_paint/CMakeLists.txt --- blender-2.61/source/blender/editors/sculpt_paint/CMakeLists.txt 2011-12-13 19:52:00.000000000 +0000 +++ blender-2.62/source/blender/editors/sculpt_paint/CMakeLists.txt 2012-02-15 19:36:40.000000000 +0000 @@ -27,6 +27,7 @@ ../../imbuf ../../makesdna ../../makesrna + ../uvedit ../../render/extern/include ../../windowmanager ../../../../intern/guardedalloc @@ -37,6 +38,7 @@ ) set(SRC + paint_cursor.c paint_image.c paint_ops.c paint_stroke.c @@ -45,6 +47,7 @@ paint_vertex.c sculpt.c sculpt_undo.c + sculpt_uv.c paint_intern.h sculpt_intern.h diff -Nru blender-2.61/source/blender/editors/sculpt_paint/paint_cursor.c blender-2.62/source/blender/editors/sculpt_paint/paint_cursor.c --- blender-2.61/source/blender/editors/sculpt_paint/paint_cursor.c 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/source/blender/editors/sculpt_paint/paint_cursor.c 2012-02-15 19:36:40.000000000 +0000 @@ -0,0 +1,607 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + * The Original Code is Copyright (C) 2009 by Nicholas Bishop + * All rights reserved. + * + * Contributor(s): Jason Wilkins, Tom Musgrove. + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/editors/sculpt_paint/paint_cursor.c + * \ingroup edsculpt + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_math.h" +#include "BLI_utildefines.h" + +#include "DNA_brush_types.h" +#include "DNA_color_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_userdef_types.h" + +#include "BKE_brush.h" +#include "BKE_context.h" +#include "BKE_paint.h" + +#include "WM_api.h" + +#include "BIF_gl.h" +#include "BIF_glutil.h" + +#include "ED_view3d.h" + +#include "paint_intern.h" +/* still needed for sculpt_stroke_get_location, should be + removed eventually (TODO) */ +#include "sculpt_intern.h" + +/* TODOs: + + Some of the cursor drawing code is doing non-draw stuff + (e.g. updating the brush rake angle). This should be cleaned up + still. + + There is also some ugliness with sculpt-specific code. + */ + +typedef struct Snapshot { + float size[3]; + float ofs[3]; + float rot; + int brush_size; + int winx; + int winy; + int brush_map_mode; + int curve_changed_timestamp; +} Snapshot; + +static int same_snap(Snapshot* snap, Brush* brush, ViewContext* vc) +{ + MTex* mtex = &brush->mtex; + + return (((mtex->tex) && + equals_v3v3(mtex->ofs, snap->ofs) && + equals_v3v3(mtex->size, snap->size) && + mtex->rot == snap->rot) && + + /* make brush smaller shouldn't cause a resample */ + ((mtex->brush_map_mode == MTEX_MAP_MODE_FIXED && + (brush_size(vc->scene, brush) <= snap->brush_size)) || + (brush_size(vc->scene, brush) == snap->brush_size)) && + + (mtex->brush_map_mode == snap->brush_map_mode) && + (vc->ar->winx == snap->winx) && + (vc->ar->winy == snap->winy)); +} + +static void make_snap(Snapshot* snap, Brush* brush, ViewContext* vc) +{ + if (brush->mtex.tex) { + snap->brush_map_mode = brush->mtex.brush_map_mode; + copy_v3_v3(snap->ofs, brush->mtex.ofs); + copy_v3_v3(snap->size, brush->mtex.size); + snap->rot = brush->mtex.rot; + } + else { + snap->brush_map_mode = -1; + snap->ofs[0]= snap->ofs[1]= snap->ofs[2]= -1; + snap->size[0]= snap->size[1]= snap->size[2]= -1; + snap->rot = -1; + } + + snap->brush_size = brush_size(vc->scene, brush); + snap->winx = vc->ar->winx; + snap->winy = vc->ar->winy; +} + +static int load_tex(Sculpt *sd, Brush* br, ViewContext* vc) +{ + static GLuint overlay_texture = 0; + static int init = 0; + static int tex_changed_timestamp = -1; + static int curve_changed_timestamp = -1; + static Snapshot snap; + static int old_size = -1; + + GLubyte* buffer = NULL; + + int size; + int j; + int refresh; + +#ifndef _OPENMP + (void)sd; /* quied unused warning */ +#endif + + if (br->mtex.brush_map_mode == MTEX_MAP_MODE_TILED && !br->mtex.tex) return 0; + + refresh = + !overlay_texture || + (br->mtex.tex && + (!br->mtex.tex->preview || + br->mtex.tex->preview->changed_timestamp[0] != tex_changed_timestamp)) || + !br->curve || + br->curve->changed_timestamp != curve_changed_timestamp || + !same_snap(&snap, br, vc); + + if (refresh) { + if (br->mtex.tex && br->mtex.tex->preview) + tex_changed_timestamp = br->mtex.tex->preview->changed_timestamp[0]; + + if (br->curve) + curve_changed_timestamp = br->curve->changed_timestamp; + + make_snap(&snap, br, vc); + + if (br->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED) { + int s = brush_size(vc->scene, br); + int r = 1; + + for (s >>= 1; s > 0; s >>= 1) + r++; + + size = (1<flags & SCULPT_USE_OPENMP) + for (j= 0; j < size; j++) { + int i; + float y; + float len; + + for (i= 0; i < size; i++) { + + // largely duplicated from tex_strength + + const float rotation = -br->mtex.rot; + float radius = brush_size(vc->scene, br); + int index = j*size + i; + float x; + float avg; + + x = (float)i/size; + y = (float)j/size; + + x -= 0.5f; + y -= 0.5f; + + if (br->mtex.brush_map_mode == MTEX_MAP_MODE_TILED) { + x *= vc->ar->winx / radius; + y *= vc->ar->winy / radius; + } + else { + x *= 2; + y *= 2; + } + + len = sqrtf(x*x + y*y); + + if ((br->mtex.brush_map_mode == MTEX_MAP_MODE_TILED) || len <= 1) { + /* it is probably worth optimizing for those cases where + the texture is not rotated by skipping the calls to + atan2, sqrtf, sin, and cos. */ + if (br->mtex.tex && (rotation > 0.001f || rotation < -0.001f)) { + const float angle = atan2f(y, x) + rotation; + + x = len * cosf(angle); + y = len * sinf(angle); + } + + x *= br->mtex.size[0]; + y *= br->mtex.size[1]; + + x += br->mtex.ofs[0]; + y += br->mtex.ofs[1]; + + avg = br->mtex.tex ? paint_get_tex_pixel(br, x, y) : 1; + + avg += br->texture_sample_bias; + + if (br->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED) + avg *= brush_curve_strength(br, len, 1); /* Falloff curve */ + + buffer[index] = 255 - (GLubyte)(255*avg); + } + else { + buffer[index] = 0; + } + } + } + + if (!overlay_texture) + glGenTextures(1, &overlay_texture); + } + else { + size= old_size; + } + + glBindTexture(GL_TEXTURE_2D, overlay_texture); + + if (refresh) { + if (!init) { + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, size, size, 0, GL_ALPHA, GL_UNSIGNED_BYTE, buffer); + init = 1; + } + else { + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size, size, GL_ALPHA, GL_UNSIGNED_BYTE, buffer); + } + + if (buffer) + MEM_freeN(buffer); + } + + glEnable(GL_TEXTURE_2D); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + if (br->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + } + + return 1; +} + +static int project_brush_radius(ViewContext *vc, + float radius, + const float location[3]) +{ + float view[3], nonortho[3], ortho[3], offset[3], p1[2], p2[2]; + + ED_view3d_global_to_vector(vc->rv3d, location, view); + + // create a vector that is not orthogonal to view + + if (fabsf(view[0]) < 0.1f) { + nonortho[0] = view[0] + 1.0f; + nonortho[1] = view[1]; + nonortho[2] = view[2]; + } + else if (fabsf(view[1]) < 0.1f) { + nonortho[0] = view[0]; + nonortho[1] = view[1] + 1.0f; + nonortho[2] = view[2]; + } + else { + nonortho[0] = view[0]; + nonortho[1] = view[1]; + nonortho[2] = view[2] + 1.0f; + } + + // get a vector in the plane of the view + cross_v3_v3v3(ortho, nonortho, view); + normalize_v3(ortho); + + // make a point on the surface of the brush tagent to the view + mul_v3_fl(ortho, radius); + add_v3_v3v3(offset, location, ortho); + + // project the center of the brush, and the tangent point to the view onto the screen + project_float(vc->ar, location, p1); + project_float(vc->ar, offset, p2); + + // the distance between these points is the size of the projected brush in pixels + return len_v2v2(p1, p2); +} + +static int sculpt_get_brush_geometry(bContext* C, ViewContext *vc, + int x, int y, int* pixel_radius, + float location[3]) +{ + Scene *scene = CTX_data_scene(C); + Paint *paint = paint_get_active(scene); + Brush *brush = paint_brush(paint); + float window[2]; + int hit; + + window[0] = x + vc->ar->winrct.xmin; + window[1] = y + vc->ar->winrct.ymin; + + if(vc->obact->sculpt && vc->obact->sculpt->pbvh && + sculpt_stroke_get_location(C, location, window)) { + *pixel_radius = + project_brush_radius(vc, + brush_unprojected_radius(scene, brush), + location); + + if (*pixel_radius == 0) + *pixel_radius = brush_size(scene, brush); + + mul_m4_v3(vc->obact->obmat, location); + + hit = 1; + } + else { + Sculpt* sd = CTX_data_tool_settings(C)->sculpt; + Brush* brush = paint_brush(&sd->paint); + + *pixel_radius = brush_size(scene, brush); + hit = 0; + } + + return hit; +} + +/* Draw an overlay that shows what effect the brush's texture will + have on brush strength */ +/* TODO: sculpt only for now */ +static void paint_draw_alpha_overlay(Sculpt *sd, Brush *brush, + ViewContext *vc, int x, int y) +{ + rctf quad; + + /* check for overlay mode */ + if(!(brush->flag & BRUSH_TEXTURE_OVERLAY) || + !(ELEM(brush->mtex.brush_map_mode, MTEX_MAP_MODE_FIXED, MTEX_MAP_MODE_TILED))) + return; + + /* save lots of GL state + TODO: check on whether all of these are needed? */ + glPushAttrib(GL_COLOR_BUFFER_BIT| + GL_CURRENT_BIT| + GL_DEPTH_BUFFER_BIT| + GL_ENABLE_BIT| + GL_LINE_BIT| + GL_POLYGON_BIT| + GL_STENCIL_BUFFER_BIT| + GL_TRANSFORM_BIT| + GL_VIEWPORT_BIT| + GL_TEXTURE_BIT); + + if(load_tex(sd, brush, vc)) { + glEnable(GL_BLEND); + + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glDepthMask(GL_FALSE); + glDepthFunc(GL_ALWAYS); + + glMatrixMode(GL_TEXTURE); + glPushMatrix(); + glLoadIdentity(); + + if(brush->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED) { + /* brush rotation */ + glTranslatef(0.5, 0.5, 0); + glRotatef((double)RAD2DEGF((brush->flag & BRUSH_RAKE) ? + sd->last_angle : sd->special_rotation), + 0.0, 0.0, 1.0); + glTranslatef(-0.5f, -0.5f, 0); + + /* scale based on tablet pressure */ + if(sd->draw_pressure && brush_use_size_pressure(vc->scene, brush)) { + glTranslatef(0.5f, 0.5f, 0); + glScalef(1.0f/sd->pressure_value, 1.0f/sd->pressure_value, 1); + glTranslatef(-0.5f, -0.5f, 0); + } + + if(sd->draw_anchored) { + const float *aim = sd->anchored_initial_mouse; + const rcti *win = &vc->ar->winrct; + quad.xmin = aim[0]-sd->anchored_size - win->xmin; + quad.ymin = aim[1]-sd->anchored_size - win->ymin; + quad.xmax = aim[0]+sd->anchored_size - win->xmin; + quad.ymax = aim[1]+sd->anchored_size - win->ymin; + } + else { + const int radius= brush_size(vc->scene, brush); + quad.xmin = x - radius; + quad.ymin = y - radius; + quad.xmax = x + radius; + quad.ymax = y + radius; + } + } + else { + quad.xmin = 0; + quad.ymin = 0; + quad.xmax = vc->ar->winrct.xmax - vc->ar->winrct.xmin; + quad.ymax = vc->ar->winrct.ymax - vc->ar->winrct.ymin; + } + + /* set quad color */ + glColor4f(U.sculpt_paint_overlay_col[0], + U.sculpt_paint_overlay_col[1], + U.sculpt_paint_overlay_col[2], + brush->texture_overlay_alpha / 100.0f); + + /* draw textured quad */ + glBegin(GL_QUADS); + glTexCoord2f(0, 0); + glVertex2f(quad.xmin, quad.ymin); + glTexCoord2f(1, 0); + glVertex2f(quad.xmax, quad.ymin); + glTexCoord2f(1, 1); + glVertex2f(quad.xmax, quad.ymax); + glTexCoord2f(0, 1); + glVertex2f(quad.xmin, quad.ymax); + glEnd(); + + glPopMatrix(); + } + + glPopAttrib(); +} + +/* Special actions taken when paint cursor goes over mesh */ +/* TODO: sculpt only for now */ +static void paint_cursor_on_hit(Sculpt *sd, Brush *brush, ViewContext *vc, + const float location[3]) +{ + float unprojected_radius, projected_radius; + + /* update the brush's cached 3D radius */ + if(!brush_use_locked_size(vc->scene, brush)) { + /* get 2D brush radius */ + if(sd->draw_anchored) + projected_radius = sd->anchored_size; + else { + if(brush->flag & BRUSH_ANCHORED) + projected_radius = 8; + else + projected_radius = brush_size(vc->scene, brush); + } + + /* convert brush radius from 2D to 3D */ + unprojected_radius = paint_calc_object_space_radius(vc, location, + projected_radius); + + /* scale 3D brush radius by pressure */ + if(sd->draw_pressure && brush_use_size_pressure(vc->scene, brush)) + unprojected_radius *= sd->pressure_value; + + /* set cached value in either Brush or UnifiedPaintSettings */ + brush_set_unprojected_radius(vc->scene, brush, unprojected_radius); + } +} + +static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) +{ + Scene *scene = CTX_data_scene(C); + Paint *paint = paint_get_active(scene); + Brush *brush = paint_brush(paint); + ViewContext vc; + float final_radius; + float translation[2]; + float outline_alpha, *outline_col; + + /* set various defaults */ + translation[0] = x; + translation[1] = y; + outline_alpha = 0.5; + outline_col = brush->add_col; + final_radius = brush_size(scene, brush); + + /* check that brush drawing is enabled */ + if(!(paint->flags & PAINT_SHOW_BRUSH)) + return; + + /* can't use stroke vc here because this will be called during + mouse over too, not just during a stroke */ + view3d_set_viewcontext(C, &vc); + + /* TODO: as sculpt and other paint modes are unified, this + special mode of drawing will go away */ + if(vc.obact->sculpt) { + Sculpt *sd = CTX_data_tool_settings(C)->sculpt; + float location[3]; + int pixel_radius, hit; + + /* this is probably here so that rake takes into + account the brush movements before the stroke + starts, but this doesn't really belong in draw code + (TODO) */ + { + const float u = 0.5f; + const float v = 1 - u; + const float r = 20; + + const float dx = sd->last_x - x; + const float dy = sd->last_y - y; + + if(dx*dx + dy*dy >= r*r) { + sd->last_angle = atan2(dx, dy); + + sd->last_x = u*sd->last_x + v*x; + sd->last_y = u*sd->last_y + v*y; + } + } + + /* test if brush is over the mesh */ + hit = sculpt_get_brush_geometry(C, &vc, x, y, &pixel_radius, location); + + /* draw overlay */ + paint_draw_alpha_overlay(sd, brush, &vc, x, y); + + if(brush_use_locked_size(scene, brush)) + brush_set_size(scene, brush, pixel_radius); + + /* check if brush is subtracting, use different color then */ + /* TODO: no way currently to know state of pen flip or + invert key modifier without starting a stroke */ + if((!(brush->flag & BRUSH_INVERTED) ^ + !(brush->flag & BRUSH_DIR_IN)) && + ELEM5(brush->sculpt_tool, SCULPT_TOOL_DRAW, + SCULPT_TOOL_INFLATE, SCULPT_TOOL_CLAY, + SCULPT_TOOL_PINCH, SCULPT_TOOL_CREASE)) + outline_col = brush->sub_col; + + /* only do if brush is over the mesh */ + if(hit) + paint_cursor_on_hit(sd, brush, &vc, location); + + if(sd->draw_anchored) { + final_radius = sd->anchored_size; + translation[0] = sd->anchored_initial_mouse[0] - vc.ar->winrct.xmin; + translation[1] = sd->anchored_initial_mouse[1] - vc.ar->winrct.ymin; + } + } + + /* make lines pretty */ + glEnable(GL_BLEND); + glEnable(GL_LINE_SMOOTH); + + /* set brush color */ + glColor4f(outline_col[0], outline_col[1], outline_col[2], outline_alpha); + + /* draw brush outline */ + glTranslatef(translation[0], translation[1], 0); + glutil_draw_lined_arc(0.0, M_PI*2.0, final_radius, 40); + glTranslatef(-translation[0], -translation[1], 0); + + /* restore GL state */ + glDisable(GL_BLEND); + glDisable(GL_LINE_SMOOTH); +} + +/* Public API */ + +void paint_cursor_start(bContext *C, int (*poll)(bContext *C)) +{ + Paint *p = paint_get_active(CTX_data_scene(C)); + + if(p && !p->paint_cursor) + p->paint_cursor = WM_paint_cursor_activate(CTX_wm_manager(C), poll, paint_draw_cursor, NULL); +} diff -Nru blender-2.61/source/blender/editors/sculpt_paint/paint_image.c blender-2.62/source/blender/editors/sculpt_paint/paint_image.c --- blender-2.61/source/blender/editors/sculpt_paint/paint_image.c 2011-12-13 19:52:00.000000000 +0000 +++ blender-2.62/source/blender/editors/sculpt_paint/paint_image.c 2012-02-15 19:36:40.000000000 +0000 @@ -50,6 +50,7 @@ #include "BLI_memarena.h" #include "BLI_threads.h" #include "BLI_utildefines.h" +#include "BLI_editVert.h" #include "PIL_time.h" @@ -80,6 +81,8 @@ #include "BKE_paint.h" #include "BKE_report.h" #include "BKE_scene.h" +#include "BKE_global.h" +#include "BKE_deform.h" #include "BIF_gl.h" #include "BIF_glutil.h" @@ -91,6 +94,7 @@ #include "ED_sculpt.h" #include "ED_uvedit.h" #include "ED_view3d.h" +#include "ED_mesh.h" #include "WM_api.h" #include "WM_types.h" @@ -100,6 +104,7 @@ #include "RNA_enum_types.h" #include "GPU_draw.h" +#include "GPU_extensions.h" #include "paint_intern.h" @@ -383,7 +388,7 @@ void *rect; int x, y; - short source; + short source, use_float; char gen_type; } UndoImageTile; @@ -413,11 +418,13 @@ ListBase *lb= undo_paint_push_get_list(UNDO_PAINT_IMAGE); UndoImageTile *tile; int allocsize; + short use_float = ibuf->rect_float ? 1 : 0; for(tile=lb->first; tile; tile=tile->next) if(tile->x == x_tile && tile->y == y_tile && ima->gen_type == tile->gen_type && ima->source == tile->source) - if(strcmp(tile->idname, ima->id.name)==0 && strcmp(tile->ibufname, ibuf->name)==0) - return tile->rect; + if(tile->use_float == use_float) + if(strcmp(tile->idname, ima->id.name)==0 && strcmp(tile->ibufname, ibuf->name)==0) + return tile->rect; if (*tmpibuf==NULL) *tmpibuf = IMB_allocImBuf(IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, 32, IB_rectfloat|IB_rect); @@ -435,6 +442,7 @@ tile->gen_type= ima->gen_type; tile->source= ima->source; + tile->use_float= use_float; undo_copy_tile(tile, *tmpibuf, ibuf, 0); undo_paint_push_count_alloc(UNDO_PAINT_IMAGE, allocsize); @@ -455,6 +463,8 @@ IB_rectfloat|IB_rect); for(tile=lb->first; tile; tile=tile->next) { + short use_float; + /* find image based on name, pointer becomes invalid with global undo */ if(ima && strcmp(tile->idname, ima->id.name)==0) { /* ima is valid */ @@ -480,6 +490,11 @@ if (ima->gen_type != tile->gen_type || ima->source != tile->source) continue; + use_float = ibuf->rect_float ? 1 : 0; + + if (use_float != tile->use_float) + continue; + undo_copy_tile(tile, tmpibuf, ibuf, 1); GPU_free_image(ima); /* force OpenGL reload */ @@ -1775,16 +1790,7 @@ } #endif //PROJ_DEBUG_NOSEAMBLEED -static float Vec2Lenf_nosqrt(const float *v1, const float *v2) -{ - float x, y; - - x = v1[0]-v2[0]; - y = v1[1]-v2[1]; - return x*x+y*y; -} - -static float Vec2Lenf_nosqrt_other(const float *v1, const float v2_1, const float v2_2) +static float len_squared_v2v2_alt(const float *v1, const float v2_1, const float v2_2) { float x, y; @@ -1793,7 +1799,7 @@ return x*x+y*y; } -/* note, use a squared value so we can use Vec2Lenf_nosqrt +/* note, use a squared value so we can use len_squared_v2v2 * be sure that you have done a bounds check first or this may fail */ /* only give bucket_bounds as an arg because we need it elsewhere */ static int project_bucket_isect_circle(const float cent[2], const float radius_squared, rctf *bucket_bounds) @@ -1807,7 +1813,9 @@ return 1; */ - if((bucket_bounds->xmin <= cent[0] && bucket_bounds->xmax >= cent[0]) || (bucket_bounds->ymin <= cent[1] && bucket_bounds->ymax >= cent[1]) ) { + if ( (bucket_bounds->xmin <= cent[0] && bucket_bounds->xmax >= cent[0]) || + (bucket_bounds->ymin <= cent[1] && bucket_bounds->ymax >= cent[1]) ) + { return 1; } @@ -1815,21 +1823,21 @@ if (cent[0] < bucket_bounds->xmin) { /* lower left out of radius test */ if (cent[1] < bucket_bounds->ymin) { - return (Vec2Lenf_nosqrt_other(cent, bucket_bounds->xmin, bucket_bounds->ymin) < radius_squared) ? 1 : 0; + return (len_squared_v2v2_alt(cent, bucket_bounds->xmin, bucket_bounds->ymin) < radius_squared) ? 1 : 0; } /* top left test */ else if (cent[1] > bucket_bounds->ymax) { - return (Vec2Lenf_nosqrt_other(cent, bucket_bounds->xmin, bucket_bounds->ymax) < radius_squared) ? 1 : 0; + return (len_squared_v2v2_alt(cent, bucket_bounds->xmin, bucket_bounds->ymax) < radius_squared) ? 1 : 0; } } else if (cent[0] > bucket_bounds->xmax) { /* lower right out of radius test */ if (cent[1] < bucket_bounds->ymin) { - return (Vec2Lenf_nosqrt_other(cent, bucket_bounds->xmax, bucket_bounds->ymin) < radius_squared) ? 1 : 0; + return (len_squared_v2v2_alt(cent, bucket_bounds->xmax, bucket_bounds->ymin) < radius_squared) ? 1 : 0; } /* top right test */ else if (cent[1] > bucket_bounds->ymax) { - return (Vec2Lenf_nosqrt_other(cent, bucket_bounds->xmax, bucket_bounds->ymax) < radius_squared) ? 1 : 0; + return (len_squared_v2v2_alt(cent, bucket_bounds->xmax, bucket_bounds->ymax) < radius_squared) ? 1 : 0; } } @@ -2807,7 +2815,11 @@ p4[0] = bucket_bounds.xmax; p4[1] = bucket_bounds.ymin; if (mf->v4) { - if( isect_point_quad_v2(p1, v1, v2, v3, v4) || isect_point_quad_v2(p2, v1, v2, v3, v4) || isect_point_quad_v2(p3, v1, v2, v3, v4) || isect_point_quad_v2(p4, v1, v2, v3, v4) || + if ( isect_point_quad_v2(p1, v1, v2, v3, v4) || + isect_point_quad_v2(p2, v1, v2, v3, v4) || + isect_point_quad_v2(p3, v1, v2, v3, v4) || + isect_point_quad_v2(p4, v1, v2, v3, v4) || + /* we can avoid testing v3,v1 because another intersection MUST exist if this intersects */ (isect_line_line_v2(p1, p2, v1, v2) || isect_line_line_v2(p1, p2, v2, v3) || isect_line_line_v2(p1, p2, v3, v4)) || (isect_line_line_v2(p2, p3, v1, v2) || isect_line_line_v2(p2, p3, v2, v3) || isect_line_line_v2(p2, p3, v3, v4)) || @@ -2818,7 +2830,10 @@ } } else { - if( isect_point_tri_v2(p1, v1, v2, v3) || isect_point_tri_v2(p2, v1, v2, v3) || isect_point_tri_v2(p3, v1, v2, v3) || isect_point_tri_v2(p4, v1, v2, v3) || + if ( isect_point_tri_v2(p1, v1, v2, v3) || + isect_point_tri_v2(p2, v1, v2, v3) || + isect_point_tri_v2(p3, v1, v2, v3) || + isect_point_tri_v2(p4, v1, v2, v3) || /* we can avoid testing v3,v1 because another intersection MUST exist if this intersects */ (isect_line_line_v2(p1, p2, v1, v2) || isect_line_line_v2(p1, p2, v2, v3)) || (isect_line_line_v2(p2, p3, v1, v2) || isect_line_line_v2(p2, p3, v2, v3)) || @@ -2928,7 +2943,7 @@ MemArena *arena; /* at the moment this is just ps->arena_mt[0], but use this to show were not multithreading */ - const int diameter= 2*brush_size(ps->brush); + const int diameter= 2*brush_size(ps->scene, ps->brush); /* ---- end defines ---- */ @@ -3078,8 +3093,8 @@ } /* same as view3d_get_object_project_mat */ - mul_m4_m4m4(vmat, ps->ob->obmat, viewmat); - mul_m4_m4m4(ps->projectMat, vmat, winmat); + mult_m4_m4m4(vmat, viewmat, ps->ob->obmat); + mult_m4_m4m4(ps->projectMat, winmat, vmat); } @@ -3571,7 +3586,7 @@ { if(ps->source==PROJ_SRC_VIEW) { float min_brush[2], max_brush[2]; - const float radius = (float)brush_size(ps->brush); + const float radius = (float)brush_size(ps->scene, ps->brush); /* so we dont have a bucket bounds that is way too small to paint into */ // if (radius < 1.0f) radius = 1.0f; // this doesn't work yet :/ @@ -3609,7 +3624,7 @@ static int project_bucket_iter_next(ProjPaintState *ps, int *bucket_index, rctf *bucket_bounds, const float mval[2]) { - const int diameter= 2*brush_size(ps->brush); + const int diameter= 2*brush_size(ps->scene, ps->brush); if (ps->thread_tot > 1) BLI_lock_thread(LOCK_CUSTOM1); @@ -3733,15 +3748,13 @@ static void do_projectpaint_smear_f(ProjPaintState *ps, ProjPixel *projPixel, float alpha, float mask, MemArena *smearArena, LinkNode **smearPixels_f, float co[2]) { - unsigned char rgba_ub[4]; - unsigned char rgba_smear[4]; + float rgba[4]; - if (project_paint_PickColor(ps, co, NULL, rgba_ub, 1)==0) + if (project_paint_PickColor(ps, co, rgba, NULL, 1)==0) return; - IMAPAINT_FLOAT_RGBA_TO_CHAR(rgba_smear, projPixel->pixel.f_pt); /* (ProjPixelClone *)projPixel)->clonepx.uint = IMB_blend_color(*((unsigned int *)rgba_smear), *((unsigned int *)rgba_ub), (int)(alpha*mask*255), ps->blend); */ - blend_color_mix(((ProjPixelClone *)projPixel)->clonepx.ch, rgba_smear, (rgba_ub), (int)(alpha*mask*255)); + blend_color_mix_float(((ProjPixelClone *)projPixel)->clonepx.f, projPixel->pixel.f_pt, rgba, alpha*mask); BLI_linklist_prepend_arena(smearPixels_f, (void *)projPixel, smearArena); } @@ -3773,8 +3786,8 @@ { if (ps->is_texbrush) { /* rgba already holds a texture result here from higher level function */ - float rgba_br[3]; if(use_color_correction){ + float rgba_br[3]; srgb_to_linearrgb_v3_v3(rgba_br, ps->brush->rgb); mul_v3_v3(rgba, rgba_br); } @@ -3835,7 +3848,7 @@ float co[2]; float mask = 1.0f; /* airbrush wont use mask */ unsigned short mask_short; - const float radius= (float)brush_size(ps->brush); + const float radius= (float)brush_size(ps->scene, ps->brush); const float radius_squared= radius*radius; /* avoid a square root with every dist comparison */ short lock_alpha= ELEM(ps->brush->blend, IMB_BLEND_ERASE_ALPHA, IMB_BLEND_ADD_ALPHA) ? 0 : ps->brush->flag & BRUSH_LOCK_ALPHA; @@ -3883,8 +3896,7 @@ projPixel = (ProjPixel *)node->link; - /*dist = len_v2v2(projPixel->projCoSS, pos);*/ /* correct but uses a sqrtf */ - dist_nosqrt = Vec2Lenf_nosqrt(projPixel->projCoSS, pos); + dist_nosqrt = len_squared_v2v2(projPixel->projCoSS, pos); /*if (dist < radius) {*/ /* correct but uses a sqrtf */ if (dist_nosqrt <= radius_squared) { @@ -3895,7 +3907,7 @@ if (falloff > 0.0f) { if (ps->is_texbrush) { /* note, for clone and smear, we only use the alpha, could be a special function */ - brush_sample_tex(ps->brush, projPixel->projCoSS, rgba, thread_index); + brush_sample_tex(ps->scene, ps->brush, projPixel->projCoSS, rgba, thread_index); alpha = rgba[3]; } else { alpha = 1.0f; @@ -3903,7 +3915,7 @@ if (ps->is_airbrush) { /* for an aurbrush there is no real mask, so just multiply the alpha by it */ - alpha *= falloff * brush_alpha(ps->brush); + alpha *= falloff * brush_alpha(ps->scene, ps->brush); mask = ((float)projPixel->mask)/65535.0f; } else { @@ -3911,7 +3923,7 @@ falloff = 1.0f - falloff; falloff = 1.0f - (falloff * falloff); - mask_short = (unsigned short)(projPixel->mask * (brush_alpha(ps->brush) * falloff)); + mask_short = (unsigned short)(projPixel->mask * (brush_alpha(ps->scene, ps->brush) * falloff)); if (mask_short > projPixel->mask_max) { mask = ((float)mask_short)/65535.0f; projPixel->mask_max = mask_short; @@ -3991,7 +4003,7 @@ for (node= smearPixels_f; node; node= node->next) { projPixel = node->link; - IMAPAINT_CHAR_RGBA_TO_FLOAT(projPixel->pixel.f_pt, ((ProjPixelClone *)projPixel)->clonepx.ch); + copy_v4_v4(projPixel->pixel.f_pt, ((ProjPixelClone *)projPixel)->clonepx.f); } BLI_memarena_free(smearArena); @@ -4159,7 +4171,8 @@ if(texpaint || (sima && sima->lock)) { int w = imapaintpartial.x2 - imapaintpartial.x1; int h = imapaintpartial.y2 - imapaintpartial.y1; - GPU_paint_update_image(image, imapaintpartial.x1, imapaintpartial.y1, w, h, !texpaint); + /* Testing with partial update in uv editor too */ + GPU_paint_update_image(image, imapaintpartial.x1, imapaintpartial.y1, w, h, 0);//!texpaint); } } @@ -4598,6 +4611,16 @@ return paint_brush(&settings->imapaint.paint); } +static Brush *uv_sculpt_brush(bContext *C) +{ + Scene *scene= CTX_data_scene(C); + ToolSettings *settings= scene->toolsettings; + + if(!settings->uvsculpt) + return NULL; + return paint_brush(&settings->uvsculpt->paint); +} + static int image_paint_poll(bContext *C) { Object *obact = CTX_data_active_object(C); @@ -4622,6 +4645,31 @@ return 0; } +static int uv_sculpt_brush_poll(bContext *C) +{ + EditMesh *em; + int ret; + Object *obedit = CTX_data_edit_object(C); + SpaceImage *sima= CTX_wm_space_image(C); + Scene *scene = CTX_data_scene(C); + ToolSettings *toolsettings = scene->toolsettings; + + if(!uv_sculpt_brush(C) || !obedit || obedit->type != OB_MESH) + return 0; + + em = BKE_mesh_get_editmesh(obedit->data); + ret = EM_texFaceCheck(em); + BKE_mesh_end_editmesh(obedit->data, em); + + if(ret && sima) { + ARegion *ar= CTX_wm_region(C); + if((toolsettings->use_uv_sculpt) && ar->regiontype==RGN_TYPE_WINDOW) + return 1; + } + + return 0; +} + static int image_paint_3d_poll(bContext *C) { if(CTX_wm_region_view3d(C)) @@ -4793,7 +4841,7 @@ if(pop->mode == PAINT_MODE_3D && (pop->s.tool == PAINT_TOOL_CLONE)) pop->s.tool = PAINT_TOOL_DRAW; pop->s.blend = brush->blend; - pop->orig_brush_size= brush_size(brush); + pop->orig_brush_size= brush_size(scene, brush); if(pop->mode != PAINT_MODE_2D) { pop->s.ob = OBACT; @@ -4829,8 +4877,8 @@ return 0; /* Dont allow brush size below 2 */ - if (brush_size(brush) < 2) - brush_set_size(brush, 2); + if (brush_size(scene, brush) < 2) + brush_set_size(scene, brush, 2); /* allocate and initialize spacial data structures */ project_paint_begin(&pop->ps); @@ -4844,7 +4892,7 @@ image_undo_restore, image_undo_free); /* create painter */ - pop->painter= brush_painter_new(pop->s.brush); + pop->painter= brush_painter_new(scene, pop->s.brush); return 1; } @@ -4914,7 +4962,7 @@ brush_painter_free(pop->painter); if(pop->mode == PAINT_MODE_3D_PROJECT) { - brush_set_size(pop->ps.brush, pop->orig_brush_size); + brush_set_size(scene, pop->ps.brush, pop->orig_brush_size); paint_brush_exit_tex(pop->ps.brush); project_paint_end(&pop->ps); @@ -4950,6 +4998,7 @@ static void paint_apply_event(bContext *C, wmOperator *op, wmEvent *event) { + const Scene *scene = CTX_data_scene(C); PaintOperation *pop= op->customdata; wmTabletData *wmtab; PointerRNA itemptr; @@ -4981,13 +5030,13 @@ /* special exception here for too high pressure values on first touch in windows for some tablets, then we just skip first touch .. */ - if (tablet && (pressure >= 0.99f) && ((pop->s.brush->flag & BRUSH_SPACING_PRESSURE) || brush_use_alpha_pressure(pop->s.brush) || brush_use_size_pressure(pop->s.brush))) + if (tablet && (pressure >= 0.99f) && ((pop->s.brush->flag & BRUSH_SPACING_PRESSURE) || brush_use_alpha_pressure(scene, pop->s.brush) || brush_use_size_pressure(scene, pop->s.brush))) return; /* This can be removed once fixed properly in brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, double time, float pressure, void *user) at zero pressure we should do nothing 1/2^12 is .0002 which is the sensitivity of the most sensitive pen tablet available*/ - if (tablet && (pressure < .0002f) && ((pop->s.brush->flag & BRUSH_SPACING_PRESSURE) || brush_use_alpha_pressure(pop->s.brush) || brush_use_size_pressure(pop->s.brush))) + if (tablet && (pressure < .0002f) && ((pop->s.brush->flag & BRUSH_SPACING_PRESSURE) || brush_use_alpha_pressure(scene, pop->s.brush) || brush_use_size_pressure(scene, pop->s.brush))) return; } @@ -5077,7 +5126,7 @@ RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", ""); } -static int get_imapaint_zoom(bContext *C, float *zoomx, float *zoomy) +int get_imapaint_zoom(bContext *C, float *zoomx, float *zoomy) { RegionView3D *rv3d= CTX_wm_region_view3d(C); @@ -5102,16 +5151,28 @@ #define PX_SIZE_FADE_MAX 12.0f #define PX_SIZE_FADE_MIN 4.0f - Brush *brush= image_paint_brush(C); - Paint *paint= paint_get_active(CTX_data_scene(C)); + Scene *scene= CTX_data_scene(C); + //Brush *brush= image_paint_brush(C); + Paint *paint= paint_get_active(scene); + Brush *brush= paint_brush(paint); if(paint && brush && paint->flags & PAINT_SHOW_BRUSH) { + ToolSettings *ts; float zoomx, zoomy; - const float size= (float)brush_size(brush); + const float size= (float)brush_size(scene, brush); const short use_zoom= get_imapaint_zoom(C, &zoomx, &zoomy); - const float pixel_size= MAX2(size * zoomx, size * zoomy); + float pixel_size; float alpha= 0.5f; + ts = scene->toolsettings; + + if(use_zoom && !ts->use_uv_sculpt){ + pixel_size = MAX2(size * zoomx, size * zoomy); + } + else { + pixel_size = size; + } + /* fade out the brush (cheap trick to work around brush interfearing with sampling [#])*/ if(pixel_size < PX_SIZE_FADE_MIN) { return; @@ -5124,7 +5185,8 @@ glTranslatef((float)x, (float)y, 0.0f); - if(use_zoom) + /* No need to scale for uv sculpting, on the contrary it might be useful to keep unscaled */ + if(use_zoom && !ts->use_uv_sculpt) glScalef(zoomx, zoomy, 1.0f); glColor4f(brush->add_col[0], brush->add_col[1], brush->add_col[2], alpha); @@ -5142,14 +5204,16 @@ static void toggle_paint_cursor(bContext *C, int enable) { - ToolSettings *settings= CTX_data_scene(C)->toolsettings; + wmWindowManager *wm= CTX_wm_manager(C); + Scene *scene = CTX_data_scene(C); + ToolSettings *settings= scene->toolsettings; if(settings->imapaint.paintcursor && !enable) { - WM_paint_cursor_end(CTX_wm_manager(C), settings->imapaint.paintcursor); + WM_paint_cursor_end(wm, settings->imapaint.paintcursor); settings->imapaint.paintcursor = NULL; } else if(enable) - settings->imapaint.paintcursor= WM_paint_cursor_activate(CTX_wm_manager(C), image_paint_poll, brush_drawcursor, NULL); + settings->imapaint.paintcursor= WM_paint_cursor_activate(wm, image_paint_poll, brush_drawcursor, NULL); } /* enable the paint cursor if it isn't already. @@ -5168,6 +5232,27 @@ } } + +void ED_space_image_uv_sculpt_update(wmWindowManager *wm, ToolSettings *settings) +{ + if(settings->use_uv_sculpt) { + if(!settings->uvsculpt) { + settings->uvsculpt = MEM_callocN(sizeof(*settings->uvsculpt), "UV Smooth paint"); + settings->uv_sculpt_tool = UV_SCULPT_TOOL_GRAB; + settings->uv_sculpt_settings = UV_SCULPT_LOCK_BORDERS | UV_SCULPT_ALL_ISLANDS; + settings->uv_relax_method = UV_SCULPT_TOOL_RELAX_LAPLACIAN; + } + + paint_init(&settings->uvsculpt->paint, PAINT_CURSOR_SCULPT); + + WM_paint_cursor_activate(wm, uv_sculpt_brush_poll, + brush_drawcursor, NULL); + } + else { + if(settings->uvsculpt) + settings->uvsculpt->paint.flags &= ~PAINT_SHOW_BRUSH; + } +} /************************ grab clone operator ************************/ typedef struct GrabClone { @@ -5489,6 +5574,11 @@ return (texture_paint_poll(C) || image_paint_poll(C)); } +int uv_sculpt_poll(bContext *C) +{ + return uv_sculpt_brush_poll(C); +} + int facemask_paint_poll(bContext *C) { return paint_facesel_test(CTX_data_active_object(C)); @@ -5561,8 +5651,8 @@ /* override */ ps.is_texbrush= 0; ps.is_airbrush= 1; - orig_brush_size= brush_size(ps.brush); - brush_set_size(ps.brush, 32); /* cover the whole image */ + orig_brush_size= brush_size(scene, ps.brush); + brush_set_size(scene, ps.brush, 32); /* cover the whole image */ ps.tool= PAINT_TOOL_DRAW; /* so pixels are initialized with minimal info */ @@ -5575,7 +5665,7 @@ project_paint_begin(&ps); if(ps.dm==NULL) { - brush_set_size(ps.brush, orig_brush_size); + brush_set_size(scene, ps.brush, orig_brush_size); return OPERATOR_CANCELLED; } else { @@ -5599,7 +5689,7 @@ project_paint_end(&ps); scene->toolsettings->imapaint.flag &= ~IMAGEPAINT_DRAWING; - brush_set_size(ps.brush, orig_brush_size); + brush_set_size(scene, ps.brush, orig_brush_size); return OPERATOR_FINISHED; } diff -Nru blender-2.61/source/blender/editors/sculpt_paint/paint_intern.h blender-2.62/source/blender/editors/sculpt_paint/paint_intern.h --- blender-2.61/source/blender/editors/sculpt_paint/paint_intern.h 2011-12-13 19:52:00.000000000 +0000 +++ blender-2.62/source/blender/editors/sculpt_paint/paint_intern.h 2012-02-15 19:36:40.000000000 +0000 @@ -41,6 +41,7 @@ struct Object; struct PaintStroke; struct PointerRNA; +struct rcti; struct Scene; struct VPaint; struct ViewContext; @@ -49,7 +50,7 @@ struct wmOperatorType; /* paint_stroke.c */ -typedef int (*StrokeGetLocation)(struct bContext *C, struct PaintStroke *stroke, float location[3], float mouse[2]); +typedef int (*StrokeGetLocation)(struct bContext *C, float location[3], float mouse[2]); typedef int (*StrokeTestStart)(struct bContext *C, struct wmOperator *op, struct wmEvent *event); typedef void (*StrokeUpdateStep)(struct bContext *C, struct PaintStroke *stroke, struct PointerRNA *itemptr); typedef void (*StrokeDone)(struct bContext *C, struct PaintStroke *stroke); @@ -102,10 +103,34 @@ void PAINT_OT_project_image(struct wmOperatorType *ot); void PAINT_OT_image_from_view(struct wmOperatorType *ot); +/* uv sculpting */ +int uv_sculpt_poll(struct bContext *C); + +void SCULPT_OT_uv_sculpt_stroke(struct wmOperatorType *ot); /* paint_utils.c */ + +/* Convert the object-space axis-aligned bounding box (expressed as + its minimum and maximum corners) into a screen-space rectangle, + returns zero if the result is empty */ +int paint_convert_bb_to_rect(struct rcti *rect, + const float bb_min[3], + const float bb_max[3], + const struct ARegion *ar, + struct RegionView3D *rv3d, + struct Object *ob); + +/* Get four planes in object-space that describe the projection of + screen_rect from screen into object-space (essentially converting a + 2D screens-space bounding box into four 3D planes) */ +void paint_calc_redraw_planes(float planes[4][4], + const struct ARegion *ar, + struct RegionView3D *rv3d, + struct Object *ob, + const struct rcti *screen_rect); + void projectf(struct bglMats *mats, const float v[3], float p[2]); -float paint_calc_object_space_radius(struct ViewContext *vc, float center[3], float pixel_radius); +float paint_calc_object_space_radius(struct ViewContext *vc, const float center[3], float pixel_radius); float paint_get_tex_pixel(struct Brush* br, float u, float v); int imapaint_pick_face(struct ViewContext *vc, struct Mesh *me, const int mval[2], unsigned int *index); void imapaint_pick_uv(struct Scene *scene, struct Object *ob, unsigned int faceindex, const int xy[2], float uv[2]); diff -Nru blender-2.61/source/blender/editors/sculpt_paint/paint_ops.c blender-2.62/source/blender/editors/sculpt_paint/paint_ops.c --- blender-2.61/source/blender/editors/sculpt_paint/paint_ops.c 2011-12-13 19:52:00.000000000 +0000 +++ blender-2.62/source/blender/editors/sculpt_paint/paint_ops.c 2012-02-15 19:36:40.000000000 +0000 @@ -89,7 +89,8 @@ static int brush_scale_size_exec(bContext *C, wmOperator *op) { - Paint *paint= paint_get_active(CTX_data_scene(C)); + Scene *scene = CTX_data_scene(C); + Paint *paint= paint_get_active(scene); struct Brush *brush= paint_brush(paint); // Object *ob= CTX_data_active_object(C); float scalar= RNA_float_get(op->ptr, "scalar"); @@ -97,7 +98,7 @@ if (brush) { // pixel radius { - const int old_size= brush_size(brush); + const int old_size= brush_size(scene, brush); int size= (int)(scalar*old_size); if (old_size == size) { @@ -110,17 +111,17 @@ } CLAMP(size, 1, 2000); // XXX magic number - brush_set_size(brush, size); + brush_set_size(scene, brush, size); } // unprojected radius { - float unprojected_radius= scalar*brush_unprojected_radius(brush); + float unprojected_radius= scalar*brush_unprojected_radius(scene, brush); if (unprojected_radius < 0.001f) // XXX magic number unprojected_radius= 0.001f; - brush_set_unprojected_radius(brush, unprojected_radius); + brush_set_unprojected_radius(scene, brush, unprojected_radius); } } @@ -339,6 +340,39 @@ } +static int brush_uv_sculpt_tool_set_exec(bContext *C, wmOperator *op) +{ + Brush *brush; + Scene *scene= CTX_data_scene(C); + ToolSettings *ts = scene->toolsettings; + ts->uv_sculpt_tool = RNA_enum_get(op->ptr, "tool"); + brush = ts->uvsculpt->paint.brush; + /* To update toolshelf */ + WM_event_add_notifier(C, NC_BRUSH|NA_EDITED, brush); + + return OPERATOR_FINISHED; +} + +static void BRUSH_OT_uv_sculpt_tool_set(wmOperatorType *ot) +{ + /* from rna_scene.c */ + extern EnumPropertyItem uv_sculpt_tool_items[]; + /* identifiers */ + ot->name = "UV Sculpt Tool Set"; + ot->description = "Set the UV sculpt tool"; + ot->idname = "BRUSH_OT_uv_sculpt_tool_set"; + + /* api callbacks */ + ot->exec = brush_uv_sculpt_tool_set_exec; + ot->poll = uv_sculpt_poll; + + /* flags */ + ot->flag = 0; + + /* props */ + ot->prop = RNA_def_enum(ot->srna, "tool", uv_sculpt_tool_items, 0, "Tool", ""); +} + /**************************** registration **********************************/ void ED_operatortypes_paint(void) @@ -354,6 +388,7 @@ WM_operatortype_append(BRUSH_OT_vertex_tool_set); WM_operatortype_append(BRUSH_OT_weight_tool_set); WM_operatortype_append(BRUSH_OT_image_tool_set); + WM_operatortype_append(BRUSH_OT_uv_sculpt_tool_set); /* image */ WM_operatortype_append(PAINT_OT_texture_paint_toggle); @@ -372,6 +407,9 @@ WM_operatortype_append(PAINT_OT_weight_sample); WM_operatortype_append(PAINT_OT_weight_sample_group); + /* uv */ + WM_operatortype_append(SCULPT_OT_uv_sculpt_stroke); + /* vertex selection */ WM_operatortype_append(PAINT_OT_vert_select_all); WM_operatortype_append(PAINT_OT_vert_select_inverse); @@ -394,67 +432,14 @@ static void ed_keymap_paint_brush_switch(wmKeyMap *keymap, const char *mode) { wmKeyMapItem *kmi; - - kmi= WM_keymap_add_item(keymap, "BRUSH_OT_active_index_set", ONEKEY, KM_PRESS, 0, 0); - RNA_string_set(kmi->ptr, "mode", mode); - RNA_int_set(kmi->ptr, "index", 0); - kmi= WM_keymap_add_item(keymap, "BRUSH_OT_active_index_set", TWOKEY, KM_PRESS, 0, 0); - RNA_string_set(kmi->ptr, "mode", mode); - RNA_int_set(kmi->ptr, "index", 1); - kmi= WM_keymap_add_item(keymap, "BRUSH_OT_active_index_set", THREEKEY, KM_PRESS, 0, 0); - RNA_string_set(kmi->ptr, "mode", mode); - RNA_int_set(kmi->ptr, "index", 2); - kmi= WM_keymap_add_item(keymap, "BRUSH_OT_active_index_set", FOURKEY, KM_PRESS, 0, 0); - RNA_string_set(kmi->ptr, "mode", mode); - RNA_int_set(kmi->ptr, "index", 3); - kmi= WM_keymap_add_item(keymap, "BRUSH_OT_active_index_set", FIVEKEY, KM_PRESS, 0, 0); - RNA_string_set(kmi->ptr, "mode", mode); - RNA_int_set(kmi->ptr, "index", 4); - kmi= WM_keymap_add_item(keymap, "BRUSH_OT_active_index_set", SIXKEY, KM_PRESS, 0, 0); - RNA_string_set(kmi->ptr, "mode", mode); - RNA_int_set(kmi->ptr, "index", 5); - kmi= WM_keymap_add_item(keymap, "BRUSH_OT_active_index_set", SEVENKEY, KM_PRESS, 0, 0); - RNA_string_set(kmi->ptr, "mode", mode); - RNA_int_set(kmi->ptr, "index", 6); - kmi= WM_keymap_add_item(keymap, "BRUSH_OT_active_index_set", EIGHTKEY, KM_PRESS, 0, 0); - RNA_string_set(kmi->ptr, "mode", mode); - RNA_int_set(kmi->ptr, "index", 7); - kmi= WM_keymap_add_item(keymap, "BRUSH_OT_active_index_set", NINEKEY, KM_PRESS, 0, 0); - RNA_string_set(kmi->ptr, "mode", mode); - RNA_int_set(kmi->ptr, "index", 8); - kmi= WM_keymap_add_item(keymap, "BRUSH_OT_active_index_set", ZEROKEY, KM_PRESS, 0, 0); - RNA_string_set(kmi->ptr, "mode", mode); - RNA_int_set(kmi->ptr, "index", 9); - kmi= WM_keymap_add_item(keymap, "BRUSH_OT_active_index_set", ONEKEY, KM_PRESS, KM_SHIFT, 0); - RNA_string_set(kmi->ptr, "mode", mode); - RNA_int_set(kmi->ptr, "index", 10); - kmi= WM_keymap_add_item(keymap, "BRUSH_OT_active_index_set", TWOKEY, KM_PRESS, KM_SHIFT, 0); - RNA_string_set(kmi->ptr, "mode", mode); - RNA_int_set(kmi->ptr, "index", 11); - kmi= WM_keymap_add_item(keymap, "BRUSH_OT_active_index_set", THREEKEY, KM_PRESS, KM_SHIFT, 0); - RNA_string_set(kmi->ptr, "mode", mode); - RNA_int_set(kmi->ptr, "index", 12); - kmi= WM_keymap_add_item(keymap, "BRUSH_OT_active_index_set", FOURKEY, KM_PRESS, KM_SHIFT, 0); - RNA_string_set(kmi->ptr, "mode", mode); - RNA_int_set(kmi->ptr, "index", 13); - kmi= WM_keymap_add_item(keymap, "BRUSH_OT_active_index_set", FIVEKEY, KM_PRESS, KM_SHIFT, 0); - RNA_string_set(kmi->ptr, "mode", mode); - RNA_int_set(kmi->ptr, "index", 14); - kmi= WM_keymap_add_item(keymap, "BRUSH_OT_active_index_set", SIXKEY, KM_PRESS, KM_SHIFT, 0); - RNA_string_set(kmi->ptr, "mode", mode); - RNA_int_set(kmi->ptr, "index", 15); - kmi= WM_keymap_add_item(keymap, "BRUSH_OT_active_index_set", SEVENKEY, KM_PRESS, KM_SHIFT, 0); - RNA_string_set(kmi->ptr, "mode", mode); - RNA_int_set(kmi->ptr, "index", 16); - kmi= WM_keymap_add_item(keymap, "BRUSH_OT_active_index_set", EIGHTKEY, KM_PRESS, KM_SHIFT, 0); - RNA_string_set(kmi->ptr, "mode", mode); - RNA_int_set(kmi->ptr, "index", 17); - kmi= WM_keymap_add_item(keymap, "BRUSH_OT_active_index_set", NINEKEY, KM_PRESS, KM_SHIFT, 0); - RNA_string_set(kmi->ptr, "mode", mode); - RNA_int_set(kmi->ptr, "index", 18); - kmi= WM_keymap_add_item(keymap, "BRUSH_OT_active_index_set", ZEROKEY, KM_PRESS, KM_SHIFT, 0); - RNA_string_set(kmi->ptr, "mode", mode); - RNA_int_set(kmi->ptr, "index", 19); + int i; + /* index 0-9 (zero key is tenth), shift key for index 10-19 */ + for (i = 0; i < 20; i++) { + kmi= WM_keymap_add_item(keymap, "BRUSH_OT_active_index_set", + ZEROKEY + ((i + 1) % 10), KM_PRESS, i < 10 ? 0 : KM_SHIFT, 0); + RNA_string_set(kmi->ptr, "mode", mode); + RNA_int_set(kmi->ptr, "index", i); + } } static void ed_keymap_paint_brush_size(wmKeyMap *keymap, const char *UNUSED(path)) @@ -475,7 +460,7 @@ } RCFlags; static void set_brush_rc_path(PointerRNA *ptr, const char *brush_path, - const char *output_name, const char *input_name) + const char *output_name, const char *input_name) { char *path; @@ -485,21 +470,35 @@ } static void set_brush_rc_props(PointerRNA *ptr, const char *paint, - const char *prop, RCFlags flags) + const char *prop, const char *secondary_prop, + RCFlags flags) { + const char *ups_path = "tool_settings.unified_paint_settings"; char *brush_path; brush_path = BLI_sprintfN("tool_settings.%s.brush", paint); - set_brush_rc_path(ptr, brush_path, "data_path", prop); + set_brush_rc_path(ptr, brush_path, "data_path_primary", prop); + if(secondary_prop) { + set_brush_rc_path(ptr, ups_path, "use_secondary", secondary_prop); + set_brush_rc_path(ptr, ups_path, "data_path_secondary", prop); + } + else { + RNA_string_set(ptr, "use_secondary", ""); + RNA_string_set(ptr, "data_path_secondary", ""); + } set_brush_rc_path(ptr, brush_path, "color_path", "cursor_color_add"); set_brush_rc_path(ptr, brush_path, "rotation_path", "texture_slot.angle"); RNA_string_set(ptr, "image_id", brush_path); if(flags & RC_COLOR) set_brush_rc_path(ptr, brush_path, "fill_color_path", "color"); + else + RNA_string_set(ptr, "fill_color_path", ""); if(flags & RC_ZOOM) RNA_string_set(ptr, "zoom_path", "space_data.zoom"); + else + RNA_string_set(ptr, "zoom_path", ""); MEM_freeN(brush_path); } @@ -510,14 +509,14 @@ wmKeyMapItem *kmi; kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, 0, 0); - set_brush_rc_props(kmi->ptr, paint, "size", flags); + set_brush_rc_props(kmi->ptr, paint, "size", "use_unified_size", flags); kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0); - set_brush_rc_props(kmi->ptr, paint, "strength", flags); + set_brush_rc_props(kmi->ptr, paint, "strength", "use_unified_strength", flags); if(flags & RC_ROTATION) { kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, KM_CTRL, 0); - set_brush_rc_props(kmi->ptr, paint, "texture_slot.angle", flags); + set_brush_rc_props(kmi->ptr, paint, "texture_slot.angle", NULL, flags); } } @@ -541,11 +540,11 @@ /* multires switch */ kmi= WM_keymap_add_item(keymap, "OBJECT_OT_subdivision_set", PAGEUPKEY, KM_PRESS, 0, 0); RNA_int_set(kmi->ptr, "level", 1); - RNA_boolean_set(kmi->ptr, "relative", 1); + RNA_boolean_set(kmi->ptr, "relative", TRUE); kmi= WM_keymap_add_item(keymap, "OBJECT_OT_subdivision_set", PAGEDOWNKEY, KM_PRESS, 0, 0); RNA_int_set(kmi->ptr, "level", -1); - RNA_boolean_set(kmi->ptr, "relative", 1); + RNA_boolean_set(kmi->ptr, "relative", TRUE); ed_keymap_paint_brush_switch(keymap, "sculpt"); ed_keymap_paint_brush_size(keymap, "tool_settings.sculpt.brush.size"); @@ -605,9 +604,13 @@ ed_keymap_paint_brush_size(keymap, "tool_settings.weight_paint.brush.size"); ed_keymap_paint_brush_radial_control(keymap, "weight_paint", 0); - kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", MKEY, KM_PRESS, 0, 0); /* mask toggle */ + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", MKEY, KM_PRESS, 0, 0); /* face mask toggle */ RNA_string_set(kmi->ptr, "data_path", "weight_paint_object.data.use_paint_mask"); + /* note, conflicts with vertex paint, but this is more useful */ + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", VKEY, KM_PRESS, 0, 0); /* vert mask toggle */ + RNA_string_set(kmi->ptr, "data_path", "weight_paint_object.data.use_paint_mask_vertex"); + WM_keymap_verify_item(keymap, "PAINT_OT_weight_from_bones", WKEY, KM_PRESS, 0, 0); @@ -617,8 +620,10 @@ WM_keymap_add_item(keymap, "PAINT_OT_vert_select_all", AKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "PAINT_OT_vert_select_inverse", IKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_select_border", BKEY, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "VIEW3D_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_SHIFT|KM_CTRL, 0)->ptr, "deselect", 1); + kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "deselect", FALSE); + kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_SHIFT|KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "deselect", TRUE); WM_keymap_add_item(keymap, "VIEW3D_OT_select_circle", CKEY, KM_PRESS, 0, 0); /* Image/Texture Paint mode */ @@ -643,10 +648,30 @@ WM_keymap_add_item(keymap, "PAINT_OT_face_select_all", AKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "PAINT_OT_face_select_inverse", IKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "PAINT_OT_face_select_hide", HKEY, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "PAINT_OT_face_select_hide", HKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "unselected", 1); + kmi = WM_keymap_add_item(keymap, "PAINT_OT_face_select_hide", HKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "unselected", FALSE); + kmi = WM_keymap_add_item(keymap, "PAINT_OT_face_select_hide", HKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "unselected", TRUE); WM_keymap_add_item(keymap, "PAINT_OT_face_select_reveal", HKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "PAINT_OT_face_select_linked", LKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "PAINT_OT_face_select_linked_pick", LKEY, KM_PRESS, 0, 0); + + keymap= WM_keymap_find(keyconf, "UV Sculpt", 0, 0); + keymap->poll= uv_sculpt_poll; + + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", QKEY, KM_PRESS, 0, 0); + RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_uv_sculpt"); + + RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_uv_sculpt_stroke", LEFTMOUSE, KM_PRESS, 0, 0)->ptr, "mode", BRUSH_STROKE_NORMAL); + RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_uv_sculpt_stroke", LEFTMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "mode", BRUSH_STROKE_INVERT); + RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_uv_sculpt_stroke", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", BRUSH_STROKE_SMOOTH); + + ed_keymap_paint_brush_size(keymap, "tool_settings.uv_sculpt.brush.size"); + ed_keymap_paint_brush_radial_control(keymap, "uv_sculpt", 0); + + RNA_enum_set(WM_keymap_add_item(keymap, "BRUSH_OT_uv_sculpt_tool_set", SKEY, KM_PRESS, 0, 0)->ptr, "tool", UV_SCULPT_TOOL_RELAX); + RNA_enum_set(WM_keymap_add_item(keymap, "BRUSH_OT_uv_sculpt_tool_set", PKEY, KM_PRESS, 0, 0)->ptr, "tool", UV_SCULPT_TOOL_PINCH); + RNA_enum_set(WM_keymap_add_item(keymap, "BRUSH_OT_uv_sculpt_tool_set", GKEY, KM_PRESS, 0, 0)->ptr, "tool", UV_SCULPT_TOOL_GRAB); + } diff -Nru blender-2.61/source/blender/editors/sculpt_paint/paint_stroke.c blender-2.62/source/blender/editors/sculpt_paint/paint_stroke.c --- blender-2.61/source/blender/editors/sculpt_paint/paint_stroke.c 2011-12-13 19:52:00.000000000 +0000 +++ blender-2.62/source/blender/editors/sculpt_paint/paint_stroke.c 2012-02-15 19:36:40.000000000 +0000 @@ -56,9 +56,6 @@ #include "ED_view3d.h" #include "paint_intern.h" -/* still needed for sculpt_stroke_get_location, should be - removed eventually (TODO) */ -#include "sculpt_intern.h" #include #include @@ -108,543 +105,6 @@ glDisable(GL_LINE_SMOOTH); } -typedef struct Snapshot { - float size[3]; - float ofs[3]; - float rot; - int brush_size; - int winx; - int winy; - int brush_map_mode; - int curve_changed_timestamp; -} Snapshot; - -static int same_snap(Snapshot* snap, Brush* brush, ViewContext* vc) -{ - MTex* mtex = &brush->mtex; - - return - (mtex->tex && - mtex->ofs[0] == snap->ofs[0] && - mtex->ofs[1] == snap->ofs[1] && - mtex->ofs[2] == snap->ofs[2] && - mtex->size[0] == snap->size[0] && - mtex->size[1] == snap->size[1] && - mtex->size[2] == snap->size[2] && - mtex->rot == snap->rot) && - ((mtex->brush_map_mode == MTEX_MAP_MODE_FIXED && brush_size(brush) <= snap->brush_size) || (brush_size(brush) == snap->brush_size)) && // make brush smaller shouldn't cause a resample - mtex->brush_map_mode == snap->brush_map_mode && - vc->ar->winx == snap->winx && - vc->ar->winy == snap->winy; -} - -static void make_snap(Snapshot* snap, Brush* brush, ViewContext* vc) -{ - if (brush->mtex.tex) { - snap->brush_map_mode = brush->mtex.brush_map_mode; - copy_v3_v3(snap->ofs, brush->mtex.ofs); - copy_v3_v3(snap->size, brush->mtex.size); - snap->rot = brush->mtex.rot; - } - else { - snap->brush_map_mode = -1; - snap->ofs[0]= snap->ofs[1]= snap->ofs[2]= -1; - snap->size[0]= snap->size[1]= snap->size[2]= -1; - snap->rot = -1; - } - - snap->brush_size = brush_size(brush); - snap->winx = vc->ar->winx; - snap->winy = vc->ar->winy; -} - -static int load_tex(Sculpt *sd, Brush* br, ViewContext* vc) -{ - static GLuint overlay_texture = 0; - static int init = 0; - static int tex_changed_timestamp = -1; - static int curve_changed_timestamp = -1; - static Snapshot snap; - static int old_size = -1; - - GLubyte* buffer = NULL; - - int size; - int j; - int refresh; - -#ifndef _OPENMP - (void)sd; /* quied unused warning */ -#endif - - if (br->mtex.brush_map_mode == MTEX_MAP_MODE_TILED && !br->mtex.tex) return 0; - - refresh = - !overlay_texture || - (br->mtex.tex && - (!br->mtex.tex->preview || - br->mtex.tex->preview->changed_timestamp[0] != tex_changed_timestamp)) || - !br->curve || - br->curve->changed_timestamp != curve_changed_timestamp || - !same_snap(&snap, br, vc); - - if (refresh) { - if (br->mtex.tex && br->mtex.tex->preview) - tex_changed_timestamp = br->mtex.tex->preview->changed_timestamp[0]; - - if (br->curve) - curve_changed_timestamp = br->curve->changed_timestamp; - - make_snap(&snap, br, vc); - - if (br->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED) { - int s = brush_size(br); - int r = 1; - - for (s >>= 1; s > 0; s >>= 1) - r++; - - size = (1<flags & SCULPT_USE_OPENMP) - for (j= 0; j < size; j++) { - int i; - float y; - float len; - - for (i= 0; i < size; i++) { - - // largely duplicated from tex_strength - - const float rotation = -br->mtex.rot; - float radius = brush_size(br); - int index = j*size + i; - float x; - float avg; - - x = (float)i/size; - y = (float)j/size; - - x -= 0.5f; - y -= 0.5f; - - if (br->mtex.brush_map_mode == MTEX_MAP_MODE_TILED) { - x *= vc->ar->winx / radius; - y *= vc->ar->winy / radius; - } - else { - x *= 2; - y *= 2; - } - - len = sqrtf(x*x + y*y); - - if ((br->mtex.brush_map_mode == MTEX_MAP_MODE_TILED) || len <= 1) { - /* it is probably worth optimizing for those cases where - the texture is not rotated by skipping the calls to - atan2, sqrtf, sin, and cos. */ - if (br->mtex.tex && (rotation > 0.001f || rotation < -0.001f)) { - const float angle = atan2f(y, x) + rotation; - - x = len * cosf(angle); - y = len * sinf(angle); - } - - x *= br->mtex.size[0]; - y *= br->mtex.size[1]; - - x += br->mtex.ofs[0]; - y += br->mtex.ofs[1]; - - avg = br->mtex.tex ? paint_get_tex_pixel(br, x, y) : 1; - - avg += br->texture_sample_bias; - - if (br->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED) - avg *= brush_curve_strength(br, len, 1); /* Falloff curve */ - - buffer[index] = 255 - (GLubyte)(255*avg); - } - else { - buffer[index] = 0; - } - } - } - - if (!overlay_texture) - glGenTextures(1, &overlay_texture); - } - else { - size= old_size; - } - - glBindTexture(GL_TEXTURE_2D, overlay_texture); - - if (refresh) { - if (!init) { - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, size, size, 0, GL_ALPHA, GL_UNSIGNED_BYTE, buffer); - init = 1; - } - else { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size, size, GL_ALPHA, GL_UNSIGNED_BYTE, buffer); - } - - if (buffer) - MEM_freeN(buffer); - } - - glEnable(GL_TEXTURE_2D); - - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - if (br->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - } - - return 1; -} - -static int project_brush_radius(RegionView3D* rv3d, float radius, float location[3], bglMats* mats) -{ - float view[3], nonortho[3], ortho[3], offset[3], p1[2], p2[2]; - - ED_view3d_global_to_vector(rv3d, location, view); - - // create a vector that is not orthogonal to view - - if (fabsf(view[0]) < 0.1f) { - nonortho[0] = view[0] + 1.0f; - nonortho[1] = view[1]; - nonortho[2] = view[2]; - } - else if (fabsf(view[1]) < 0.1f) { - nonortho[0] = view[0]; - nonortho[1] = view[1] + 1.0f; - nonortho[2] = view[2]; - } - else { - nonortho[0] = view[0]; - nonortho[1] = view[1]; - nonortho[2] = view[2] + 1.0f; - } - - // get a vector in the plane of the view - cross_v3_v3v3(ortho, nonortho, view); - normalize_v3(ortho); - - // make a point on the surface of the brush tagent to the view - mul_v3_fl(ortho, radius); - add_v3_v3v3(offset, location, ortho); - - // project the center of the brush, and the tagent point to the view onto the screen - projectf(mats, location, p1); - projectf(mats, offset, p2); - - // the distance between these points is the size of the projected brush in pixels - return len_v2v2(p1, p2); -} - -static int sculpt_get_brush_geometry(bContext* C, int x, int y, int* pixel_radius, - float location[3]) -{ - struct PaintStroke *stroke; - float window[2]; - int hit; - - stroke = paint_stroke_new(C, NULL, NULL, NULL, NULL, 0); - - window[0] = x + stroke->vc.ar->winrct.xmin; - window[1] = y + stroke->vc.ar->winrct.ymin; - - if(stroke->vc.obact->sculpt && stroke->vc.obact->sculpt->pbvh && - sculpt_stroke_get_location(C, stroke, location, window)) { - *pixel_radius = project_brush_radius(stroke->vc.rv3d, - brush_unprojected_radius(stroke->brush), - location, &stroke->mats); - - if (*pixel_radius == 0) - *pixel_radius = brush_size(stroke->brush); - - mul_m4_v3(stroke->vc.obact->obmat, location); - - hit = 1; - } - else { - Sculpt* sd = CTX_data_tool_settings(C)->sculpt; - Brush* brush = paint_brush(&sd->paint); - - *pixel_radius = brush_size(brush); - hit = 0; - } - - paint_stroke_free(stroke); - - return hit; -} - -/* Draw an overlay that shows what effect the brush's texture will - have on brush strength */ -/* TODO: sculpt only for now */ -static void paint_draw_alpha_overlay(Sculpt *sd, Brush *brush, - ViewContext *vc, int x, int y) -{ - rctf quad; - - /* check for overlay mode */ - if(!(brush->flag & BRUSH_TEXTURE_OVERLAY) || - !(ELEM(brush->mtex.brush_map_mode, MTEX_MAP_MODE_FIXED, MTEX_MAP_MODE_TILED))) - return; - - /* save lots of GL state - TODO: check on whether all of these are needed? */ - glPushAttrib(GL_COLOR_BUFFER_BIT| - GL_CURRENT_BIT| - GL_DEPTH_BUFFER_BIT| - GL_ENABLE_BIT| - GL_LINE_BIT| - GL_POLYGON_BIT| - GL_STENCIL_BUFFER_BIT| - GL_TRANSFORM_BIT| - GL_VIEWPORT_BIT| - GL_TEXTURE_BIT); - - if(load_tex(sd, brush, vc)) { - glEnable(GL_BLEND); - - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glDepthMask(GL_FALSE); - glDepthFunc(GL_ALWAYS); - - glMatrixMode(GL_TEXTURE); - glPushMatrix(); - glLoadIdentity(); - - if(brush->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED) { - /* brush rotation */ - glTranslatef(0.5, 0.5, 0); - glRotatef((double)RAD2DEGF((brush->flag & BRUSH_RAKE) ? - sd->last_angle : sd->special_rotation), - 0.0, 0.0, 1.0); - glTranslatef(-0.5f, -0.5f, 0); - - /* scale based on tablet pressure */ - if(sd->draw_pressure && brush_use_size_pressure(brush)) { - glTranslatef(0.5f, 0.5f, 0); - glScalef(1.0f/sd->pressure_value, 1.0f/sd->pressure_value, 1); - glTranslatef(-0.5f, -0.5f, 0); - } - - if(sd->draw_anchored) { - const float *aim = sd->anchored_initial_mouse; - const rcti *win = &vc->ar->winrct; - quad.xmin = aim[0]-sd->anchored_size - win->xmin; - quad.ymin = aim[1]-sd->anchored_size - win->ymin; - quad.xmax = aim[0]+sd->anchored_size - win->xmin; - quad.ymax = aim[1]+sd->anchored_size - win->ymin; - } - else { - const int radius= brush_size(brush); - quad.xmin = x - radius; - quad.ymin = y - radius; - quad.xmax = x + radius; - quad.ymax = y + radius; - } - } - else { - quad.xmin = 0; - quad.ymin = 0; - quad.xmax = vc->ar->winrct.xmax - vc->ar->winrct.xmin; - quad.ymax = vc->ar->winrct.ymax - vc->ar->winrct.ymin; - } - - /* set quad color */ - glColor4f(U.sculpt_paint_overlay_col[0], - U.sculpt_paint_overlay_col[1], - U.sculpt_paint_overlay_col[2], - brush->texture_overlay_alpha / 100.0f); - - /* draw textured quad */ - glBegin(GL_QUADS); - glTexCoord2f(0, 0); - glVertex2f(quad.xmin, quad.ymin); - glTexCoord2f(1, 0); - glVertex2f(quad.xmax, quad.ymin); - glTexCoord2f(1, 1); - glVertex2f(quad.xmax, quad.ymax); - glTexCoord2f(0, 1); - glVertex2f(quad.xmin, quad.ymax); - glEnd(); - - glPopMatrix(); - } - - glPopAttrib(); -} - -/* Special actions taken when paint cursor goes over mesh */ -/* TODO: sculpt only for now */ -static void paint_cursor_on_hit(Sculpt *sd, Brush *brush, ViewContext *vc, - float location[3], float *visual_strength) -{ - float unprojected_radius, projected_radius; - - /* TODO: check whether this should really only be done when - brush is over mesh? */ - if(sd->draw_pressure && brush_use_alpha_pressure(brush)) - (*visual_strength) *= sd->pressure_value; - - if(sd->draw_anchored) - projected_radius = sd->anchored_size; - else { - if(brush->flag & BRUSH_ANCHORED) - projected_radius = 8; - else - projected_radius = brush_size(brush); - } - unprojected_radius = paint_calc_object_space_radius(vc, location, - projected_radius); - - if(sd->draw_pressure && brush_use_size_pressure(brush)) - unprojected_radius *= sd->pressure_value; - - if(!brush_use_locked_size(brush)) - brush_set_unprojected_radius(brush, unprojected_radius); -} - -static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) -{ - Paint *paint = paint_get_active(CTX_data_scene(C)); - Brush *brush = paint_brush(paint); - ViewContext vc; - float final_radius; - float translation[2]; - float outline_alpha, *outline_col; - - /* set various defaults */ - translation[0] = x; - translation[1] = y; - outline_alpha = 0.5; - outline_col = brush->add_col; - final_radius = brush_size(brush); - - /* check that brush drawing is enabled */ - if(!(paint->flags & PAINT_SHOW_BRUSH)) - return; - - /* can't use stroke vc here because this will be called during - mouse over too, not just during a stroke */ - view3d_set_viewcontext(C, &vc); - - /* TODO: as sculpt and other paint modes are unified, this - special mode of drawing will go away */ - if(vc.obact->sculpt) { - Sculpt *sd = CTX_data_tool_settings(C)->sculpt; - float location[3]; - int pixel_radius, hit; - const float root_alpha = brush_alpha(brush); - float visual_strength = root_alpha*root_alpha; - const float min_alpha = 0.20f; - const float max_alpha = 0.80f; - - /* this is probably here so that rake takes into - account the brush movements before the stroke - starts, but this doesn't really belong in draw code - (TODO) */ - { - const float u = 0.5f; - const float v = 1 - u; - const float r = 20; - - const float dx = sd->last_x - x; - const float dy = sd->last_y - y; - - if(dx*dx + dy*dy >= r*r) { - sd->last_angle = atan2(dx, dy); - - sd->last_x = u*sd->last_x + v*x; - sd->last_y = u*sd->last_y + v*y; - } - } - - /* test if brush is over the mesh */ - hit = sculpt_get_brush_geometry(C, x, y, &pixel_radius, location); - - /* draw overlay */ - paint_draw_alpha_overlay(sd, brush, &vc, x, y); - - if(brush_use_locked_size(brush)) - brush_set_size(brush, pixel_radius); - - /* check if brush is subtracting, use different color then */ - /* TODO: no way currently to know state of pen flip or - invert key modifier without starting a stroke */ - if((!(brush->flag & BRUSH_INVERTED) ^ - !(brush->flag & BRUSH_DIR_IN)) && - ELEM5(brush->sculpt_tool, SCULPT_TOOL_DRAW, - SCULPT_TOOL_INFLATE, SCULPT_TOOL_CLAY, - SCULPT_TOOL_PINCH, SCULPT_TOOL_CREASE)) - outline_col = brush->sub_col; - - /* only do if brush is over the mesh */ - if(hit) - paint_cursor_on_hit(sd, brush, &vc, location, &visual_strength); - - /* don't show effect of strength past the soft limit */ - if(visual_strength > 1) - visual_strength = 1; - - outline_alpha = ((paint->flags & PAINT_SHOW_BRUSH_ON_SURFACE) ? - min_alpha + (visual_strength*(max_alpha-min_alpha)) : 0.50f); - - if(sd->draw_anchored) { - final_radius = sd->anchored_size; - translation[0] = sd->anchored_initial_mouse[0] - vc.ar->winrct.xmin; - translation[1] = sd->anchored_initial_mouse[1] - vc.ar->winrct.ymin; - } - } - - /* make lines pretty */ - glEnable(GL_BLEND); - glEnable(GL_LINE_SMOOTH); - - /* set brush color */ - glColor4f(outline_col[0], outline_col[1], outline_col[2], outline_alpha); - - /* draw brush outline */ - glTranslatef(translation[0], translation[1], 0); - glutil_draw_lined_arc(0.0, M_PI*2.0, final_radius, 40); - glTranslatef(-translation[0], -translation[1], 0); - - /* restore GL state */ - glDisable(GL_BLEND); - glDisable(GL_LINE_SMOOTH); -} - /* if this is a tablet event, return tablet pressure and set *pen_flip to 1 if the eraser tool is being used, 0 otherwise */ static float event_tablet_data(wmEvent *event, int *pen_flip) @@ -668,7 +128,8 @@ /* Put the location of the next stroke dot into the stroke RNA and apply it to the mesh */ static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *event, float mouse_in[2]) { - Paint *paint = paint_get_active(CTX_data_scene(C)); + Scene *scene = CTX_data_scene(C); + Paint *paint = paint_get_active(scene); Brush *brush = paint_brush(paint); PaintStroke *stroke = op->customdata; float mouse[3]; @@ -685,7 +146,7 @@ if(stroke->vc.obact->sculpt) { float delta[2]; - brush_jitter_pos(brush, mouse_in, mouse); + brush_jitter_pos(scene, brush, mouse_in, mouse); /* XXX: meh, this is round about because brush_jitter_pos isn't written in the best way to @@ -702,7 +163,7 @@ /* TODO: can remove the if statement once all modes have this */ if(stroke->get_location) - stroke->get_location(C, stroke, location, mouse); + stroke->get_location(C, location, mouse); else zero_v3(location); @@ -764,16 +225,17 @@ length = len_v2(vec); if(length > FLT_EPSILON) { + const Scene *scene = CTX_data_scene(C); int steps; int i; float pressure= 1.0f; /* XXX mysterious :) what has 'use size' do with this here... if you don't check for it, pressure fails */ - if(brush_use_size_pressure(stroke->brush)) + if(brush_use_size_pressure(scene, stroke->brush)) pressure = event_tablet_data(event, NULL); if(pressure > FLT_EPSILON) { - scale = (brush_size(stroke->brush)*pressure*stroke->brush->spacing/50.0f) / length; + scale = (brush_size(scene, stroke->brush)*pressure*stroke->brush->spacing/50.0f) / length; if(scale > FLT_EPSILON) { mul_v2_fl(vec, scale); @@ -869,7 +331,10 @@ MEM_freeN(stroke); return OPERATOR_FINISHED; } - else if(first || ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE) || (event->type == TIMER && (event->customdata == stroke->timer))) { + else if( (first) || + (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) || + (event->type == TIMER && (event->customdata == stroke->timer)) ) + { if(stroke->stroke_started) { if(paint_smooth_stroke(stroke, mouse, event)) { if(paint_space_stroke_enabled(stroke->brush)) { @@ -887,7 +352,8 @@ } } - /* we want the stroke to have the first daub at the start location instead of waiting till we have moved the space distance */ + /* we want the stroke to have the first daub at the start location + * instead of waiting till we have moved the space distance */ if(first && stroke->stroke_started && paint_space_stroke_enabled(stroke->brush) && @@ -961,12 +427,3 @@ CTX_wm_area(C)->spacetype == SPACE_VIEW3D && CTX_wm_region(C)->regiontype == RGN_TYPE_WINDOW; } - -void paint_cursor_start(bContext *C, int (*poll)(bContext *C)) -{ - Paint *p = paint_get_active(CTX_data_scene(C)); - - if(p && !p->paint_cursor) - p->paint_cursor = WM_paint_cursor_activate(CTX_wm_manager(C), poll, paint_draw_cursor, NULL); -} - diff -Nru blender-2.61/source/blender/editors/sculpt_paint/paint_utils.c blender-2.62/source/blender/editors/sculpt_paint/paint_utils.c --- blender-2.61/source/blender/editors/sculpt_paint/paint_utils.c 2011-12-13 19:52:00.000000000 +0000 +++ blender-2.62/source/blender/editors/sculpt_paint/paint_utils.c 2012-02-15 19:36:40.000000000 +0000 @@ -67,6 +67,78 @@ #include "paint_intern.h" +/* Convert the object-space axis-aligned bounding box (expressed as + its minimum and maximum corners) into a screen-space rectangle, + returns zero if the result is empty */ +int paint_convert_bb_to_rect(rcti *rect, + const float bb_min[3], + const float bb_max[3], + const ARegion *ar, + RegionView3D *rv3d, + Object *ob) +{ + float projection_mat[4][4]; + int i, j, k; + + rect->xmin = rect->ymin = INT_MAX; + rect->xmax = rect->ymax = INT_MIN; + + /* return zero if the bounding box has non-positive volume */ + if(bb_min[0] > bb_max[0] || bb_min[1] > bb_max[1] || bb_min[2] > bb_max[2]) + return 0; + + ED_view3d_ob_project_mat_get(rv3d, ob, projection_mat); + + for(i = 0; i < 2; ++i) { + for(j = 0; j < 2; ++j) { + for(k = 0; k < 2; ++k) { + float vec[3], proj[2]; + vec[0] = i ? bb_min[0] : bb_max[0]; + vec[1] = j ? bb_min[1] : bb_max[1]; + vec[2] = k ? bb_min[2] : bb_max[2]; + /* convert corner to screen space */ + ED_view3d_project_float(ar, vec, proj, + projection_mat); + /* expand 2D rectangle */ + rect->xmin = MIN2(rect->xmin, proj[0]); + rect->xmax = MAX2(rect->xmax, proj[0]); + rect->ymin = MIN2(rect->ymin, proj[1]); + rect->ymax = MAX2(rect->ymax, proj[1]); + } + } + } + + /* return false if the rectangle has non-positive area */ + return rect->xmin < rect->xmax && rect->ymin < rect->ymax; +} + +/* Get four planes in object-space that describe the projection of + screen_rect from screen into object-space (essentially converting a + 2D screens-space bounding box into four 3D planes) */ +void paint_calc_redraw_planes(float planes[4][4], + const ARegion *ar, + RegionView3D *rv3d, + Object *ob, + const rcti *screen_rect) +{ + BoundBox bb; + bglMats mats; + rcti rect; + + memset(&bb, 0, sizeof(BoundBox)); + view3d_get_transformation(ar, rv3d, ob, &mats); + + /* use some extra space just in case */ + rect = *screen_rect; + rect.xmin -= 2; + rect.xmax += 2; + rect.ymin -= 2; + rect.ymax += 2; + + ED_view3d_calc_clipping(&bb, planes, &mats, &rect); + mul_m4_fl(planes, -1.0f); +} + /* convert a point in model coordinates to 2D screen coordinates */ /* TODO: can be deleted once all calls are replaced with view3d_project_float() */ @@ -80,7 +152,7 @@ p[1]= uy; } -float paint_calc_object_space_radius(ViewContext *vc, float center[3], +float paint_calc_object_space_radius(ViewContext *vc, const float center[3], float pixel_radius) { Object *ob = vc->obact; diff -Nru blender-2.61/source/blender/editors/sculpt_paint/paint_vertex.c blender-2.62/source/blender/editors/sculpt_paint/paint_vertex.c --- blender-2.61/source/blender/editors/sculpt_paint/paint_vertex.c 2011-12-13 19:52:00.000000000 +0000 +++ blender-2.62/source/blender/editors/sculpt_paint/paint_vertex.c 2012-02-15 19:36:40.000000000 +0000 @@ -85,15 +85,6 @@ #include "paint_intern.h" -/* brush->vertexpaint_tool */ -#define VP_MIX 0 -#define VP_ADD 1 -#define VP_SUB 2 -#define VP_MUL 3 -#define VP_BLUR 4 -#define VP_LIGHTEN 5 -#define VP_DARKEN 6 - /* polling - retrieve whether cursor should be set or operator should be done */ @@ -288,9 +279,9 @@ } /* mirror_vgroup is set to -1 when invalid */ -static int wpaint_mirror_vgroup_ensure(Object *ob) +static int wpaint_mirror_vgroup_ensure(Object *ob, const int vgroup_active) { - bDeformGroup *defgroup= BLI_findlink(&ob->defbase, ob->actdef - 1); + bDeformGroup *defgroup= BLI_findlink(&ob->defbase, vgroup_active); if(defgroup) { bDeformGroup *curdef; @@ -390,8 +381,8 @@ { Mesh *me= ob->data; MFace *mf; - MDeformWeight *dw, *uw; - int vgroup, vgroup_mirror= -1; + MDeformWeight *dw, *dw_prev; + int vgroup_active, vgroup_mirror= -1; unsigned int index; /* mutually exclusive, could be made into a */ @@ -399,11 +390,11 @@ if(me->totface==0 || me->dvert==NULL || !me->mface) return; - vgroup= ob->actdef-1; + vgroup_active = ob->actdef - 1; /* if mirror painting, find the other group */ if(me->editflag & ME_EDIT_MIRROR_X) { - vgroup_mirror= wpaint_mirror_vgroup_ensure(ob); + vgroup_mirror= wpaint_mirror_vgroup_ensure(ob, vgroup_active); } copy_wpaint_prev(wp, me->dvert, me->totvert); @@ -423,10 +414,10 @@ continue; } - dw= defvert_verify_index(&me->dvert[vidx], vgroup); + dw= defvert_verify_index(&me->dvert[vidx], vgroup_active); if(dw) { - uw= defvert_verify_index(wp->wpaint_prev+vidx, vgroup); - uw->weight= dw->weight; /* set the undo weight */ + dw_prev= defvert_verify_index(wp->wpaint_prev+vidx, vgroup_active); + dw_prev->weight= dw->weight; /* set the undo weight */ dw->weight= paintweight; if(me->editflag & ME_EDIT_MIRROR_X) { /* x mirror painting */ @@ -435,12 +426,12 @@ /* copy, not paint again */ if(vgroup_mirror != -1) { dw= defvert_verify_index(me->dvert+j, vgroup_mirror); - uw= defvert_verify_index(wp->wpaint_prev+j, vgroup_mirror); + dw_prev= defvert_verify_index(wp->wpaint_prev+j, vgroup_mirror); } else { - dw= defvert_verify_index(me->dvert+j, vgroup); - uw= defvert_verify_index(wp->wpaint_prev+j, vgroup); + dw= defvert_verify_index(me->dvert+j, vgroup_active); + dw_prev= defvert_verify_index(wp->wpaint_prev+j, vgroup_active); } - uw->weight= dw->weight; /* set the undo weight */ + dw_prev->weight= dw->weight; /* set the undo weight */ dw->weight= paintweight; } } @@ -506,7 +497,7 @@ } */ -static unsigned int mcol_blend(unsigned int col1, unsigned int col2, int fac) +BM_INLINE unsigned int mcol_blend(unsigned int col1, unsigned int col2, int fac) { char *cp1, *cp2, *cp; int mfac; @@ -529,7 +520,7 @@ return col; } -static unsigned int mcol_add(unsigned int col1, unsigned int col2, int fac) +BM_INLINE unsigned int mcol_add(unsigned int col1, unsigned int col2, int fac) { char *cp1, *cp2, *cp; int temp; @@ -552,7 +543,7 @@ return col; } -static unsigned int mcol_sub(unsigned int col1, unsigned int col2, int fac) +BM_INLINE unsigned int mcol_sub(unsigned int col1, unsigned int col2, int fac) { char *cp1, *cp2, *cp; int temp; @@ -575,7 +566,7 @@ return col; } -static unsigned int mcol_mul(unsigned int col1, unsigned int col2, int fac) +BM_INLINE unsigned int mcol_mul(unsigned int col1, unsigned int col2, int fac) { char *cp1, *cp2, *cp; int mfac; @@ -599,7 +590,7 @@ return col; } -static unsigned int mcol_lighten(unsigned int col1, unsigned int col2, int fac) +BM_INLINE unsigned int mcol_lighten(unsigned int col1, unsigned int col2, int fac) { char *cp1, *cp2, *cp; int mfac; @@ -627,7 +618,7 @@ return col; } -static unsigned int mcol_darken(unsigned int col1, unsigned int col2, int fac) +BM_INLINE unsigned int mcol_darken(unsigned int col1, unsigned int col2, int fac) { char *cp1, *cp2, *cp; int mfac; @@ -654,34 +645,45 @@ return col; } -static void vpaint_blend(VPaint *vp, unsigned int *col, unsigned int *colorig, unsigned int paintcol, int alpha) +/* wpaint has 'wpaint_blend_tool' */ +static unsigned int vpaint_blend_tool(const int tool, const unsigned int col, + const unsigned int paintcol, const int alpha_i) +{ + switch (tool) { + case PAINT_BLEND_MIX: + case PAINT_BLEND_BLUR: return mcol_blend(col, paintcol, alpha_i); + case PAINT_BLEND_ADD: return mcol_add(col, paintcol, alpha_i); + case PAINT_BLEND_SUB: return mcol_sub(col, paintcol, alpha_i); + case PAINT_BLEND_MUL: return mcol_mul(col, paintcol, alpha_i); + case PAINT_BLEND_LIGHTEN: return mcol_lighten(col, paintcol, alpha_i); + case PAINT_BLEND_DARKEN: return mcol_darken(col, paintcol, alpha_i); + default: + BLI_assert(0); + return 0; + } +} + +/* wpaint has 'wpaint_blend' */ +static unsigned int vpaint_blend(VPaint *vp, unsigned int col, unsigned int colorig, const + unsigned int paintcol, const int alpha_i, + /* pre scaled from [0-1] --> [0-255] */ + const int brush_alpha_value_i) { Brush *brush = paint_brush(&vp->paint); + const int tool = brush->vertexpaint_tool; + + col = vpaint_blend_tool(tool, col, paintcol, alpha_i); - if(brush->vertexpaint_tool==VP_MIX || brush->vertexpaint_tool==VP_BLUR) *col= mcol_blend( *col, paintcol, alpha); - else if(brush->vertexpaint_tool==VP_ADD) *col= mcol_add( *col, paintcol, alpha); - else if(brush->vertexpaint_tool==VP_SUB) *col= mcol_sub( *col, paintcol, alpha); - else if(brush->vertexpaint_tool==VP_MUL) *col= mcol_mul( *col, paintcol, alpha); - else if(brush->vertexpaint_tool==VP_LIGHTEN) *col= mcol_lighten( *col, paintcol, alpha); - else if(brush->vertexpaint_tool==VP_DARKEN) *col= mcol_darken( *col, paintcol, alpha); - /* if no spray, clip color adding with colorig & orig alpha */ if((vp->flag & VP_SPRAY)==0) { - unsigned int testcol=0, a; + unsigned int testcol, a; char *cp, *ct, *co; - alpha= (int)(255.0f*brush_alpha(brush)); - - if(brush->vertexpaint_tool==VP_MIX || brush->vertexpaint_tool==VP_BLUR) testcol= mcol_blend( *colorig, paintcol, alpha); - else if(brush->vertexpaint_tool==VP_ADD) testcol= mcol_add( *colorig, paintcol, alpha); - else if(brush->vertexpaint_tool==VP_SUB) testcol= mcol_sub( *colorig, paintcol, alpha); - else if(brush->vertexpaint_tool==VP_MUL) testcol= mcol_mul( *colorig, paintcol, alpha); - else if(brush->vertexpaint_tool==VP_LIGHTEN) testcol= mcol_lighten( *colorig, paintcol, alpha); - else if(brush->vertexpaint_tool==VP_DARKEN) testcol= mcol_darken( *colorig, paintcol, alpha); + testcol = vpaint_blend_tool(tool, colorig, paintcol, brush_alpha_value_i); - cp= (char *)col; + cp= (char *)&col; ct= (char *)&testcol; - co= (char *)colorig; + co= (char *)&colorig; for(a=0; a<4; a++) { if( ct[a]paint); - float fac, fac_2, size, dx, dy; - float alpha; - int vertco[2]; - const int radius= brush_size(brush); + float dist_squared; + float vertco[2], delta[2]; - project_int_noclip(vc->ar, vert_nor, vertco); - dx= mval[0]-vertco[0]; - dy= mval[1]-vertco[1]; - - if (brush_use_size_pressure(brush)) - size = pressure * radius; - else - size = radius; - - fac_2= dx*dx + dy*dy; - if(fac_2 > size*size) return 0.f; - fac = sqrtf(fac_2); - - alpha= brush_alpha(brush) * brush_curve_strength_clamp(brush, fac, size); - - if (brush_use_alpha_pressure(brush)) - alpha *= pressure; - - if(vp->flag & VP_NORMALS) { - float *no= vert_nor+3; - - /* transpose ! */ - fac= vpimat[2][0]*no[0]+vpimat[2][1]*no[1]+vpimat[2][2]*no[2]; - if(fac > 0.0f) { - dx= vpimat[0][0]*no[0]+vpimat[0][1]*no[1]+vpimat[0][2]*no[2]; - dy= vpimat[1][0]*no[0]+vpimat[1][1]*no[1]+vpimat[1][2]*no[2]; - - alpha*= fac/sqrtf(dx*dx + dy*dy + fac*fac); + project_float_noclip(vc->ar, vert_nor, vertco); + sub_v2_v2v2(delta, mval, vertco); + dist_squared= dot_v2v2(delta, delta); /* len squared */ + if (dist_squared > brush_size_pressure * brush_size_pressure) { + return 0.0f; + } + else { + const float dist = sqrtf(dist_squared); + return brush_curve_strength_clamp(brush, dist, brush_size_pressure); + } +} + +static float calc_vp_alpha_dl(VPaint *vp, ViewContext *vc, + float vpimat[][3], const float *vert_nor, + const float mval[2], + const float brush_size_pressure, const float brush_alpha_pressure) +{ + float strength = calc_vp_strength_dl(vp, vc, vert_nor, mval, brush_size_pressure); + + if (strength > 0.0f) { + float alpha= brush_alpha_pressure * strength; + + if(vp->flag & VP_NORMALS) { + float dvec[3]; + const float *no= vert_nor + 3; + + /* transpose ! */ + dvec[2] = dot_v3v3(vpimat[2], no); + if (dvec[2] > 0.0f) { + dvec[0] = dot_v3v3(vpimat[0], no); + dvec[1] = dot_v3v3(vpimat[1], no); + + alpha *= dvec[2] / len_v3(dvec); + } + else { + return 0.0f; + } } - else return 0.f; + + return alpha; } - - return alpha; + + return 0.0f; } -static void wpaint_blend(VPaint *wp, MDeformWeight *dw, MDeformWeight *uw, float alpha, float paintval, int flip, int multipaint) + +BM_INLINE float wval_blend(const float weight, const float paintval, const float alpha) +{ + return (paintval * alpha) + (weight * (1.0f - alpha)); +} +BM_INLINE float wval_add(const float weight, const float paintval, const float alpha) +{ + return weight + (paintval * alpha); +} +BM_INLINE float wval_sub(const float weight, const float paintval, const float alpha) +{ + return weight - (paintval * alpha); +} +BM_INLINE float wval_mul(const float weight, const float paintval, const float alpha) +{ /* first mul, then blend the fac */ + return ((1.0f - alpha) + (alpha * paintval)) * weight; +} +BM_INLINE float wval_lighten(const float weight, const float paintval, const float alpha) +{ + return (weight < paintval) ? wval_blend(weight, paintval, alpha) : weight; +} +BM_INLINE float wval_darken(const float weight, const float paintval, const float alpha) +{ + return (weight > paintval) ? wval_blend(weight, paintval, alpha) : weight; +} + + +/* vpaint has 'vpaint_blend_tool' */ +/* result is not clamped from [0-1] */ +static float wpaint_blend_tool(const int tool, + /* dw->weight */ + const float weight, + const float paintval, const float alpha) +{ + switch (tool) { + case PAINT_BLEND_MIX: + case PAINT_BLEND_BLUR: return wval_blend(weight, paintval, alpha); + case PAINT_BLEND_ADD: return wval_add(weight, paintval, alpha); + case PAINT_BLEND_SUB: return wval_sub(weight, paintval, alpha); + case PAINT_BLEND_MUL: return wval_mul(weight, paintval, alpha); + case PAINT_BLEND_LIGHTEN: return wval_lighten(weight, paintval, alpha); + case PAINT_BLEND_DARKEN: return wval_darken(weight, paintval, alpha); + default: + BLI_assert(0); + return 0.0f; + } +} + +/* vpaint has 'vpaint_blend' */ +static float wpaint_blend(VPaint *wp, float weight, float weight_prev, + const float alpha, float paintval, + const float brush_alpha_value, + const short do_flip, const short do_multipaint_totsel) { Brush *brush = paint_brush(&wp->paint); int tool = brush->vertexpaint_tool; - - if(dw==NULL || uw==NULL) return; - - if (flip) { + + if (do_flip) { switch(tool) { - case VP_MIX: + case PAINT_BLEND_MIX: paintval = 1.f - paintval; break; - case VP_ADD: - tool= VP_SUB; break; - case VP_SUB: - tool= VP_ADD; break; - case VP_LIGHTEN: - tool= VP_DARKEN; break; - case VP_DARKEN: - tool= VP_LIGHTEN; break; + case PAINT_BLEND_ADD: + tool= PAINT_BLEND_SUB; break; + case PAINT_BLEND_SUB: + tool= PAINT_BLEND_ADD; break; + case PAINT_BLEND_LIGHTEN: + tool= PAINT_BLEND_DARKEN; break; + case PAINT_BLEND_DARKEN: + tool= PAINT_BLEND_LIGHTEN; break; } } - if(tool==VP_MIX || tool==VP_BLUR) - dw->weight = paintval*alpha + dw->weight*(1.0f-alpha); - else if(tool==VP_ADD) - dw->weight += paintval*alpha; - else if(tool==VP_SUB) - dw->weight -= paintval*alpha; - else if(tool==VP_MUL) - /* first mul, then blend the fac */ - dw->weight = ((1.0f-alpha) + alpha*paintval)*dw->weight; - else if(tool==VP_LIGHTEN) { - if (dw->weight < paintval) - dw->weight = paintval*alpha + dw->weight*(1.0f-alpha); - } else if(tool==VP_DARKEN) { - if (dw->weight > paintval) - dw->weight = paintval*alpha + dw->weight*(1.0f-alpha); - } - /* delay clamping until the end so multi-paint can function when the active group is at the limits */ - if(multipaint == FALSE) { - CLAMP(dw->weight, 0.0f, 1.0f); + weight = wpaint_blend_tool(tool, weight, paintval, alpha); + + /* delay clamping until the end so multi-paint can function when the active group is at the limits */ + if(do_multipaint_totsel == FALSE) { + CLAMP(weight, 0.0f, 1.0f); } /* if no spray, clip result with orig weight & orig alpha */ - if((wp->flag & VP_SPRAY)==0) { - float testw=0.0f; - - alpha= brush_alpha(brush); - if(tool==VP_MIX || tool==VP_BLUR) - testw = paintval*alpha + uw->weight*(1.0f-alpha); - else if(tool==VP_ADD) - testw = uw->weight + paintval*alpha; - else if(tool==VP_SUB) - testw = uw->weight - paintval*alpha; - else if(tool==VP_MUL) - /* first mul, then blend the fac */ - testw = ((1.0f-alpha) + alpha*paintval)*uw->weight; - else if(tool==VP_LIGHTEN) { - if (uw->weight < paintval) - testw = paintval*alpha + uw->weight*(1.0f-alpha); - else - testw = uw->weight; - } else if(tool==VP_DARKEN) { - if (uw->weight > paintval) - testw = paintval*alpha + uw->weight*(1.0f-alpha); - else - testw = uw->weight; - } + if ((wp->flag & VP_SPRAY) == 0) { + if(do_multipaint_totsel == FALSE) { + float testw = wpaint_blend_tool(tool, weight_prev, paintval, brush_alpha_value); - if(multipaint == FALSE) { CLAMP(testw, 0.0f, 1.0f); - if( testwweight ) { - if(dw->weight < testw) dw->weight= testw; - else if(dw->weight > uw->weight) dw->weight= uw->weight; + if (testw < weight_prev) { + if(weight < testw) weight = testw; + else if(weight > weight_prev) weight = weight_prev; } else { - if(dw->weight > testw) dw->weight= testw; - else if(dw->weight < uw->weight) dw->weight= uw->weight; + if (weight > testw) weight = testw; + else if (weight < weight_prev) weight = weight_prev; } } } - + + return weight; } /* ----------------------------------------------------- */ @@ -890,7 +919,7 @@ } else { MFace *mf= ((MFace *)me->mface) + index-1; - const int vgroup= vc.obact->actdef - 1; + const int vgroup_active= vc.obact->actdef - 1; ToolSettings *ts= vc.scene->toolsettings; float mval_f[2]; int v_idx_best= -1; @@ -914,7 +943,7 @@ } while (fidx--); if(v_idx_best != -1) { /* should always be valid */ - ts->vgroup_weight= defvert_find_weight(&me->dvert[v_idx_best], vgroup); + ts->vgroup_weight= defvert_find_weight(&me->dvert[v_idx_best], vgroup_active); change= TRUE; } } @@ -1023,8 +1052,8 @@ ViewContext vc; view3d_set_viewcontext(C, &vc); + BLI_assert(type + 1 >= 0); vc.obact->actdef= type + 1; - BLI_assert(vc.obact->actdef >= 0); DAG_id_tag_update(&vc.obact->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, vc.obact); @@ -1054,75 +1083,99 @@ ot->prop= prop; } - -#if 0 /* UNUSED */ -static void do_weight_paint_auto_normalize(MDeformVert *dvert, - int paint_nr, char *map) +static void do_weight_paint_normalize_all(MDeformVert *dvert, const int defbase_tot, const char *vgroup_validmap) { -// MDeformWeight *dw = dvert->dw; - float sum=0.0f, fac=0.0f, paintw=0.0f; - int i, tot=0; + float sum= 0.0f, fac; + unsigned int i, tot=0; + MDeformWeight *dw; + + for (i= dvert->totweight, dw= dvert->dw; i != 0; i--, dw++) { + if (dw->def_nr < defbase_tot && vgroup_validmap[dw->def_nr]) { + tot++; + sum += dw->weight; + } + } - if (!map) + if ((tot == 0) || (sum == 1.0f)) { return; + } - for (i=0; itotweight; i++) { - if (dvert->dw[i].def_nr == paint_nr) - paintw = dvert->dw[i].weight; + if (sum != 0.0f) { + fac= 1.0f / sum; - if (map[dvert->dw[i].def_nr]) { - tot += 1; - if (dvert->dw[i].def_nr != paint_nr) - sum += dvert->dw[i].weight; + for (i= dvert->totweight, dw= dvert->dw; i != 0; i--, dw++) { + if (dw->def_nr < defbase_tot && vgroup_validmap[dw->def_nr]) { + dw->weight *= fac; + } } } - - if (!tot || sum <= (1.0f - paintw)) - return; - - fac = sum / (1.0f - paintw); - fac = fac==0.0f ? 1.0f : 1.0f / fac; + else { + /* hrmf, not a factor in this case */ + fac = 1.0f / tot; - for (i=0; itotweight; i++) { - if (map[dvert->dw[i].def_nr]) { - if (dvert->dw[i].def_nr != paint_nr) - dvert->dw[i].weight *= fac; + for (i= dvert->totweight, dw= dvert->dw; i != 0; i--, dw++) { + if (dw->def_nr < defbase_tot && vgroup_validmap[dw->def_nr]) { + dw->weight = fac; + } } } } -#endif -/* the active group should be involved in auto normalize */ -static void do_weight_paint_auto_normalize_all_groups(MDeformVert *dvert, const int defbase_tot, - const char *vgroup_validmap, char do_auto_normalize) +/* same as function above except it normalizes against the active vgroup which remains unchanged + * + * note that the active is just the group which is unchanged, it can be any, + * can also be -1 to normalize all but in that case call 'do_weight_paint_normalize_all' */ +static void do_weight_paint_normalize_all_active(MDeformVert *dvert, const int defbase_tot, const char *vgroup_validmap, + const int vgroup_active) { - if (do_auto_normalize == FALSE) { + float sum= 0.0f, fac; + unsigned int i, tot=0; + MDeformWeight *dw; + float act_weight = 0.0f; + + for (i= dvert->totweight, dw= dvert->dw; i != 0; i--, dw++) { + if (dw->def_nr < defbase_tot && vgroup_validmap[dw->def_nr]) { + if (dw->def_nr != vgroup_active) { + sum += dw->weight; + tot++; + } + else { + act_weight = dw->weight; + } + } + } + + if ((tot == 0) || (sum + act_weight == 1.0f)) { return; } - else { - float sum= 0.0f, fac; - unsigned int i, tot=0; - MDeformWeight *dw; + + if (sum != 0.0f) { + fac = (1.0f / sum) * (1.0f - act_weight); for (i= dvert->totweight, dw= dvert->dw; i != 0; i--, dw++) { - if (dw->def_nr < defbase_tot) { - if (vgroup_validmap[dw->def_nr]) { - tot++; - sum += dw->weight; + if (dw->def_nr < defbase_tot && vgroup_validmap[dw->def_nr]) { + if (dw->def_nr != vgroup_active) { + dw->weight *= fac; + + /* paranoid but possibly with float error */ + CLAMP(dw->weight, 0.0f, 1.0f); } } } + } + else { + /* corner case where we need to scale all weights evenly because they're all zero */ - if ((tot == 0) || (sum == 1.0f) || (sum == 0.0f)) { - return; - } + /* hrmf, not a factor in this case */ + fac = (1.0f - act_weight) / tot; - fac= 1.0f / sum; + /* paranoid but possibly with float error */ + CLAMP(fac, 0.0f, 1.0f); for (i= dvert->totweight, dw= dvert->dw; i != 0; i--, dw++) { - if (dw->def_nr < defbase_tot) { - if (vgroup_validmap[dw->def_nr]) { - dw->weight *= fac; + if (dw->def_nr < defbase_tot && vgroup_validmap[dw->def_nr]) { + if (dw->def_nr != vgroup_active) { + dw->weight = fac; } } } @@ -1133,14 +1186,14 @@ See if the current deform vertex has a locked group */ static char has_locked_group(MDeformVert *dvert, const int defbase_tot, - const char *lock_flags) + const char *bone_groups, const char *lock_flags) { int i; MDeformWeight *dw; for (i= dvert->totweight, dw= dvert->dw; i != 0; i--, dw++) { if (dw->def_nr < defbase_tot) { - if (lock_flags[dw->def_nr] && dw->weight > 0.0f) { + if (bone_groups[dw->def_nr] && lock_flags[dw->def_nr] && dw->weight > 0.0f) { return TRUE; } } @@ -1317,7 +1370,7 @@ char *change_status; - if(!lock_flags || !has_locked_group(ndv, defbase_tot, lock_flags)) { + if(!lock_flags || !has_locked_group(ndv, defbase_tot, vgroup_validmap, lock_flags)) { return; } /* record if a group was changed, unlocked and not changed, or locked */ @@ -1432,15 +1485,15 @@ /* change the weights back to the wv's weights * it assumes you already have the correct pointer index */ -static void reset_to_prev(MDeformVert *wv, MDeformVert *dvert) +static void defvert_reset_to_prev(MDeformVert *dv_prev, MDeformVert *dv) { - MDeformWeight *dw= dvert->dw; - MDeformWeight *w; + MDeformWeight *dw= dv->dw; + MDeformWeight *dw_prev; unsigned int i; - for (i= dvert->totweight; i != 0; i--, dw++) { - w= defvert_find_index(wv, dw->def_nr); + for (i= dv->totweight; i != 0; i--, dw++) { + dw_prev= defvert_find_index(dv_prev, dw->def_nr); /* if there was no w when there is a d, then the old weight was 0 */ - dw->weight = w ? w->weight : 0.0f; + dw->weight = dw_prev ? dw_prev->weight : 0.0f; } } @@ -1465,6 +1518,7 @@ int defbase_tot_sel; int defbase_tot_unsel; + int vgroup_active; /* (ob->actdef - 1) */ int vgroup_mirror; /* mirror group or -1 */ const char *lock_flags; /* boolean array for locked bones, @@ -1478,6 +1532,8 @@ char do_flip; char do_multipaint; char do_auto_normalize; + + float brush_alpha_value; /* result of brush_alpha() */ } WeightPaintInfo; /* fresh start to make multi-paint and locking modular */ @@ -1517,7 +1573,10 @@ enforce_locks(&dv_test, dv, wpi->defbase_tot, wpi->defbase_sel, wpi->lock_flags, wpi->vgroup_validmap, wpi->do_auto_normalize, wpi->do_multipaint); - do_weight_paint_auto_normalize_all_groups(dv, wpi->defbase_tot, wpi->vgroup_validmap, wpi->do_auto_normalize); + if (wpi->do_auto_normalize) { + /* XXX - should we pass the active group? - currently '-1' */ + do_weight_paint_normalize_all(dv, wpi->defbase_tot, wpi->vgroup_validmap); + } if(oldChange && wpi->do_multipaint && wpi->defbase_tot_sel > 1) { if(tdw->weight != oldw) { @@ -1559,56 +1618,151 @@ static char *wpaint_make_validmap(Object *ob); -static void do_weight_paint_vertex( /* vars which remain the same for every vert */ +static void do_weight_paint_vertex(/* vars which remain the same for every vert */ VPaint *wp, Object *ob, const WeightPaintInfo *wpi, - /* vars which change on each stroke */ + /* vars which change on each stroke */ const unsigned int index, float alpha, float paintweight ) { Mesh *me= ob->data; MDeformVert *dv= &me->dvert[index]; - MDeformWeight *dw, *uw; - int vgroup= ob->actdef-1; + MDeformWeight *dw, *dw_prev; + + /* mirror vars */ + int index_mirr; + int vgroup_mirr; + + MDeformVert *dv_mirr; + MDeformWeight *dw_mirr; + + const short do_multipaint_totsel = (wpi->do_multipaint && wpi->defbase_tot_sel > 1); if(wp->flag & VP_ONLYVGROUP) { - dw= defvert_find_index(dv, vgroup); - uw= defvert_find_index(wp->wpaint_prev+index, vgroup); + dw= defvert_find_index(dv, wpi->vgroup_active); + dw_prev= defvert_find_index(wp->wpaint_prev+index, wpi->vgroup_active); } else { - dw= defvert_verify_index(dv, vgroup); - uw= defvert_verify_index(wp->wpaint_prev+index, vgroup); + dw= defvert_verify_index(dv, wpi->vgroup_active); + dw_prev= defvert_verify_index(wp->wpaint_prev+index, wpi->vgroup_active); } - if(dw==NULL || uw==NULL) { + if(dw==NULL || dw_prev==NULL) { return; } + + /* from now on we can check if mirrors enabled if this var is -1 and not bother with the flag */ + if (me->editflag & ME_EDIT_MIRROR_X) { + index_mirr = mesh_get_x_mirror_vert(ob, index); + vgroup_mirr = (wpi->vgroup_mirror != -1) ? wpi->vgroup_mirror : wpi->vgroup_active; + + /* another possible error - mirror group _and_ active group are the same (which is fine), + * but we also are painting onto a center vertex - this would paint the same weight twice */ + if (index_mirr == index && vgroup_mirr == wpi->vgroup_active) { + index_mirr = vgroup_mirr = -1; + } + } + else { + index_mirr = vgroup_mirr = -1; + } + + + /* get the mirror def vars */ + if (index_mirr != -1) { + dv_mirr = &me->dvert[index_mirr]; + if (wp->flag & VP_ONLYVGROUP) { + dw_mirr = defvert_find_index(dv_mirr, vgroup_mirr); + + if (dw_mirr == NULL) { + index_mirr = vgroup_mirr = -1; + dv_mirr = NULL; + } + } + else { + if (index != index_mirr) { + dw_mirr = defvert_verify_index(dv_mirr, vgroup_mirr); + } + else { + /* dv and dv_mirr are the same */ + int totweight_prev = dv_mirr->totweight; + int dw_offset = (int)(dw - dv_mirr->dw); + dw_mirr = defvert_verify_index(dv_mirr, vgroup_mirr); + + /* if we added another, get our old one back */ + if (totweight_prev != dv_mirr->totweight) { + dw = &dv_mirr->dw[dw_offset]; + } + } + } + } + else { + dv_mirr = NULL; + dw_mirr = NULL; + } + + /* TODO: De-duplicate the simple weight paint - jason */ /* ... or not, since its <10 SLOC - campbell */ /* If there are no locks or multipaint, * then there is no need to run the more complicated checks */ - if ( (wpi->do_multipaint == FALSE || wpi->defbase_tot_sel <= 1) && - (wpi->lock_flags == NULL || has_locked_group(dv, wpi->defbase_tot, wpi->lock_flags) == FALSE)) + if ( (do_multipaint_totsel == FALSE) && + (wpi->lock_flags == NULL || has_locked_group(dv, wpi->defbase_tot, wpi->vgroup_validmap, wpi->lock_flags) == FALSE)) { - wpaint_blend(wp, dw, uw, alpha, paintweight, wpi->do_flip, FALSE); + dw->weight = wpaint_blend(wp, dw->weight, dw_prev->weight, alpha, paintweight, + wpi->brush_alpha_value, wpi->do_flip, FALSE); + + /* WATCH IT: take care of the ordering of applying mirror -> normalize, + * can give wrong results [#26193], least confusing if normalize is done last */ - if(me->editflag & ME_EDIT_MIRROR_X) { /* x mirror painting */ - int index_mirr= mesh_get_x_mirror_vert(ob, index); - if(index_mirr != -1) { - MDeformVert *dv_mirr= &me->dvert[index_mirr]; - /* copy, not paint again */ - uw= defvert_verify_index(dv_mirr, (wpi->vgroup_mirror != -1) ? wpi->vgroup_mirror : vgroup); - uw->weight= dw->weight; + /* apply mirror */ + if(index_mirr != -1) { + /* copy, not paint again */ + dw_mirr->weight = dw->weight; + } + + /* apply normalize */ + if (wpi->do_auto_normalize) { + /* note on normalize - this used to be applied after painting and normalize all weights, + * in some ways this is good because there is feedback where the more weights involved would + * 'risist' so you couldn't instantly zero out other weights by painting 1.0 on the active. + * + * However this gave a problem since applying mirror, then normalize both verts + * the resulting weight wont match on both sides. + * + * If this 'resisting', slower normalize is nicer, we could call + * do_weight_paint_normalize_all() and only use... + * do_weight_paint_normalize_all_active() when normalizing the mirror vertex. + * - campbell + */ + do_weight_paint_normalize_all_active(dv, wpi->defbase_tot, wpi->vgroup_validmap, wpi->vgroup_active); + + if (index_mirr != -1) { + /* only normalize if this is not a center vertex, else we get a conflict, normalizing twice */ + if (index != index_mirr) { + do_weight_paint_normalize_all_active(dv_mirr, wpi->defbase_tot, wpi->vgroup_validmap, vgroup_mirr); + } + else { + /* this case accounts for... + * - painting onto a center vertex of a mesh + * - x mirror is enabled + * - auto normalize is enabled + * - the group you are painting onto has a L / R version + * + * We wan't L/R vgroups to have the same weight but this cant be if both are over 0.5, + * We _could_ have special check for that, but this would need its own normalize function which + * holds 2 groups from changing at once. + * + * So! just balance out the 2 weights, it keeps them equal and everything normalized. + * + * While it wont hit the desired weight immediatelty as the user waggles their mouse, + * constant painting and re-normalizing will get there. this is also just simpler logic. + * - campbell */ + dw_mirr->weight = dw->weight = (dw_mirr->weight + dw->weight) * 0.5f; + } } } - - /* important to normalize after mirror, otherwise mirror gets weight - * which has already been scaled down in relation to other weights, - * then scales a second time [#26193]. Tricky multi-paint code doesn't - * suffer from this problem - campbell */ - do_weight_paint_auto_normalize_all_groups(dv, wpi->defbase_tot, wpi->vgroup_validmap, wpi->do_auto_normalize); } else { /* use locks and/or multipaint */ @@ -1618,41 +1772,40 @@ float change = 0; float oldChange = 0; int i; - MDeformWeight *tdw = NULL, *tuw; + MDeformWeight *tdw = NULL, *tdw_prev; MDeformVert dv_copy= {NULL}; oldw = dw->weight; - wpaint_blend(wp, dw, uw, alpha, paintweight, wpi->do_flip, wpi->do_multipaint && wpi->defbase_tot_sel >1); - neww = dw->weight; - dw->weight = oldw; + neww = wpaint_blend(wp, dw->weight, dw_prev->weight, alpha, paintweight, + wpi->brush_alpha_value, wpi->do_flip, do_multipaint_totsel); /* setup multi-paint */ - if(wpi->defbase_tot_sel > 1 && wpi->do_multipaint) { + if (do_multipaint_totsel) { dv_copy.dw= MEM_dupallocN(dv->dw); dv_copy.flag = dv->flag; dv_copy.totweight = dv->totweight; tdw = dw; - tuw = uw; + tdw_prev = dw_prev; change = get_mp_change(&wp->wpaint_prev[index], wpi->defbase_tot, wpi->defbase_sel, neww - oldw); if(change) { if(!tdw->weight) { i = get_first_selected_nonzero_weight(dv, wpi->defbase_tot, wpi->defbase_sel); if(i>=0) { tdw = &(dv->dw[i]); - tuw = defvert_verify_index(&wp->wpaint_prev[index], tdw->def_nr); + tdw_prev = defvert_verify_index(&wp->wpaint_prev[index], tdw->def_nr); } else { change = 0; } } - if(change && tuw->weight && tuw->weight * change) { - if(tdw->weight != tuw->weight) { - oldChange = tdw->weight/tuw->weight; - testw = tuw->weight*change; - if( testw > tuw->weight ) { + if(change && tdw_prev->weight && tdw_prev->weight * change) { + if(tdw->weight != tdw_prev->weight) { + oldChange = tdw->weight/tdw_prev->weight; + testw = tdw_prev->weight*change; + if( testw > tdw_prev->weight ) { if(change > oldChange) { /* reset the weights and use the new change */ - reset_to_prev(wp->wpaint_prev+index, dv); + defvert_reset_to_prev(wp->wpaint_prev+index, dv); } else { /* the old change was more significant, so set @@ -1662,7 +1815,7 @@ } else { if(change < oldChange) { - reset_to_prev(wp->wpaint_prev+index, dv); + defvert_reset_to_prev(wp->wpaint_prev+index, dv); } else { change = 0; @@ -1677,7 +1830,7 @@ } if(apply_mp_locks_normalize(me, wpi, index, dw, tdw, change, oldChange, oldw, neww)) { - reset_to_prev(&dv_copy, dv); + defvert_reset_to_prev(&dv_copy, dv); change = 0; oldChange = 0; } @@ -1693,15 +1846,12 @@ (void)dw; /* quiet warnigns */ #endif - if(me->editflag & ME_EDIT_MIRROR_X) { /* x mirror painting */ - int index_mirr= mesh_get_x_mirror_vert(ob, index); - if(index_mirr != -1) { - MDeformVert *dv_mirr= &me->dvert[index_mirr]; - /* copy, not paint again */ - uw= defvert_verify_index(dv_mirr, (wpi->vgroup_mirror != -1) ? wpi->vgroup_mirror : vgroup); - //uw->weight= dw->weight; - apply_mp_locks_normalize(me, wpi, index_mirr, uw, tdw, change, oldChange, oldw, neww); - } + /* x mirror painting */ + if(index_mirr != -1) { + /* copy, not paint again */ + + /* dw_mirr->weight = dw->weight; */ /* TODO, explain the logic in not assigning weight! - campbell */ + apply_mp_locks_normalize(me, wpi, index_mirr, dw_mirr, tdw, change, oldChange, oldw, neww); } } } @@ -1794,6 +1944,7 @@ struct WPaintData { ViewContext vc; int *indexar; + int vgroup_active; int vgroup_mirror; float *vertexcosnos; float wpimat[3][3]; @@ -1866,14 +2017,18 @@ { Scene *scene= CTX_data_scene(C); struct PaintStroke *stroke = op->customdata; - ToolSettings *ts= CTX_data_tool_settings(C); + ToolSettings *ts= scene->toolsettings; VPaint *wp= ts->wpaint; Object *ob= CTX_data_active_object(C); struct WPaintData *wpd; Mesh *me; + bDeformGroup *dg; + float mat[4][4], imat[4][4]; - if(scene->obedit) return OPERATOR_CANCELLED; + if(scene->obedit) { + return FALSE; + } me= get_mesh(ob); if(me==NULL || me->totface==0) return OPERATOR_PASS_THROUGH; @@ -1883,29 +2038,9 @@ ED_vgroup_data_create(&me->id); WM_event_add_notifier(C, NC_GEOM|ND_DATA, me); } - - /* make mode data storage */ - wpd= MEM_callocN(sizeof(struct WPaintData), "WPaintData"); - paint_stroke_set_mode_data(stroke, wpd); - view3d_set_viewcontext(C, &wpd->vc); - wpd->vgroup_mirror= -1; - - /*set up auto-normalize, and generate map for detecting which - vgroups affect deform bones*/ - wpd->defbase_tot = BLI_countlist(&ob->defbase); - wpd->lock_flags = gen_lock_flags(ob, wpd->defbase_tot); - if (ts->auto_normalize || ts->multipaint || wpd->lock_flags) { - wpd->vgroup_validmap = wpaint_make_validmap(ob); - } - /* ALLOCATIONS! no return after this line */ - /* painting on subsurfs should give correct points too, this returns me->totvert amount */ - wpd->vertexcosnos= mesh_get_mapped_verts_nors(scene, ob); - wpd->indexar= get_indexarray(me); - copy_wpaint_prev(wp, me->dvert, me->totvert); - /* this happens on a Bone select, when no vgroup existed yet */ - if(ob->actdef<=0) { + if (ob->actdef <= 0) { Object *modob; if((modob = modifiers_isDeformedByArmature(ob))) { Bone *actbone= ((bArmature *)modob->data)->act_bone; @@ -1918,8 +2053,9 @@ dg= ED_vgroup_add_name(ob, pchan->name); /* sets actdef */ } else { - ob->actdef= 1 + defgroup_find_index(ob, dg); - BLI_assert(ob->actdef >= 0); + int actdef = 1 + BLI_findindex(&ob->defbase, dg); + BLI_assert(actdef >= 0); + ob->actdef= actdef; } } } @@ -1929,21 +2065,58 @@ ED_vgroup_add(ob); } + /* ensure we dont try paint onto an invalid group */ + if (ob->actdef <= 0) { + BKE_report(op->reports, RPT_WARNING, "No active vertex group for painting, aborting"); + return FALSE; + } + + /* check if we are attempting to paint onto a locked vertex group, + * and other options disallow it from doing anything useful */ + dg = BLI_findlink(&ob->defbase, (ob->actdef-1)); + if (dg->flag & DG_LOCK_WEIGHT) { + BKE_report(op->reports, RPT_WARNING, "Active group is locked, aborting"); + return FALSE; + } + + /* ALLOCATIONS! no return after this line */ + /* make mode data storage */ + wpd= MEM_callocN(sizeof(struct WPaintData), "WPaintData"); + paint_stroke_set_mode_data(stroke, wpd); + view3d_set_viewcontext(C, &wpd->vc); + + wpd->vgroup_active = ob->actdef - 1; + wpd->vgroup_mirror = -1; + + /* set up auto-normalize, and generate map for detecting which + * vgroups affect deform bones*/ + wpd->defbase_tot = BLI_countlist(&ob->defbase); + wpd->lock_flags = gen_lock_flags(ob, wpd->defbase_tot); + if (ts->auto_normalize || ts->multipaint || wpd->lock_flags) { + wpd->vgroup_validmap = wpaint_make_validmap(ob); + } + + /* painting on subsurfs should give correct points too, this returns me->totvert amount */ + wpd->vertexcosnos= mesh_get_mapped_verts_nors(scene, ob); + wpd->indexar= get_indexarray(me); + copy_wpaint_prev(wp, me->dvert, me->totvert); + /* imat for normals */ - mul_m4_m4m4(mat, ob->obmat, wpd->vc.rv3d->viewmat); + mult_m4_m4m4(mat, wpd->vc.rv3d->viewmat, ob->obmat); invert_m4_m4(imat, mat); copy_m3_m4(wpd->wpimat, imat); - + /* if mirror painting, find the other group */ if(me->editflag & ME_EDIT_MIRROR_X) { - wpd->vgroup_mirror= wpaint_mirror_vgroup_ensure(ob); + wpd->vgroup_mirror = wpaint_mirror_vgroup_ensure(ob, wpd->vgroup_active); } - return 1; + return TRUE; } static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, PointerRNA *itemptr) { + Scene *scene= CTX_data_scene(C); ToolSettings *ts= CTX_data_tool_settings(C); VPaint *wp= ts->wpaint; Brush *brush = paint_brush(&wp->paint); @@ -1954,13 +2127,18 @@ float mat[4][4]; float paintweight; int *indexar; - int totw; + float totw; unsigned int index, totindex; float alpha; - float mval[2], pressure; + float mval[2]; int use_vert_sel; char *defbase_sel; + const float pressure = RNA_float_get(itemptr, "pressure"); + const float brush_size_pressure = brush_size(scene, brush) * (brush_use_size_pressure(scene, brush) ? pressure : 1.0f); + const float brush_alpha_value = brush_alpha(scene, brush); + const float brush_alpha_pressure = brush_alpha_value * (brush_use_alpha_pressure(scene, brush) ? pressure : 1.0f); + /* intentionally dont initialize as NULL, make sure we initialize all members below */ WeightPaintInfo wpi; @@ -1980,9 +2158,8 @@ view3d_operator_needs_opengl(C); /* load projection matrix */ - mul_m4_m4m4(mat, ob->obmat, vc->rv3d->persmat); + mult_m4_m4m4(mat, vc->rv3d->persmat, ob->obmat); - pressure = RNA_float_get(itemptr, "pressure"); RNA_float_get_array(itemptr, "mouse", mval); mval[0]-= vc->ar->winrct.xmin; mval[1]-= vc->ar->winrct.ymin; @@ -1997,12 +2174,14 @@ if(wpi.defbase_tot_sel == 0 && ob->actdef > 0) wpi.defbase_tot_sel = 1; wpi.defbase_tot_unsel= wpi.defbase_tot - wpi.defbase_tot_sel; + wpi.vgroup_active= wpd->vgroup_active; wpi.vgroup_mirror= wpd->vgroup_mirror; wpi.lock_flags= wpd->lock_flags; wpi.vgroup_validmap= wpd->vgroup_validmap; wpi.do_flip= RNA_boolean_get(itemptr, "pen_flip"); wpi.do_multipaint= (ts->multipaint != 0); wpi.do_auto_normalize= ((ts->auto_normalize != 0) && (wpi.vgroup_validmap != NULL)); + wpi.brush_alpha_value= brush_alpha_value; /* *** done setting up WeightPaintInfo *** */ @@ -2015,7 +2194,7 @@ if(wp->flag & VP_AREA) { /* Ugly hack, to avoid drawing vertex index when getting the face index buffer - campbell */ me->editflag &= ~ME_EDIT_VERT_SEL; - totindex= sample_backbuf_area(vc, indexar, me->totface, mval[0], mval[1], brush_size(brush)); + totindex= sample_backbuf_area(vc, indexar, me->totface, mval[0], mval[1], brush_size_pressure); me->editflag |= use_vert_sel ? ME_EDIT_VERT_SEL : 0; } else { @@ -2050,8 +2229,8 @@ /* make sure each vertex gets treated only once */ /* and calculate filter weight */ - totw= 0; - if(brush->vertexpaint_tool==VP_BLUR) + totw= 0.0f; + if (brush->vertexpaint_tool == PAINT_BLEND_BLUR) paintweight= 0.0f; else paintweight= ts->vgroup_weight; @@ -2073,7 +2252,7 @@ if(mface->v4) me->dvert[mface->v4].flag= 1; } - if(brush->vertexpaint_tool==VP_BLUR) { + if (brush->vertexpaint_tool == PAINT_BLEND_BLUR) { MDeformWeight *dw, *(*dw_func)(MDeformVert *, const int); unsigned int fidx= mface->v4 ? 3:2; @@ -2084,11 +2263,11 @@ do { unsigned int vidx= *(&mface->v1 + fidx); - - dw= dw_func(me->dvert+vidx, ob->actdef-1); - if(dw) { - paintweight+= dw->weight; - totw++; + const float fac = calc_vp_strength_dl(wp, vc, wpd->vertexcosnos+6*vidx, mval, brush_size_pressure); + if (fac > 0.0f) { + dw = dw_func(&me->dvert[vidx], wpi.vgroup_active); + paintweight += dw ? (dw->weight * fac) : 0.0f; + totw += fac; } } while (fidx--); @@ -2097,9 +2276,10 @@ } } - if(brush->vertexpaint_tool==VP_BLUR) - paintweight/= (float)totw; - + if (brush->vertexpaint_tool == PAINT_BLEND_BLUR) { + paintweight /= totw; + } + for(index=0; indextotface) { @@ -2109,7 +2289,8 @@ unsigned int vidx= *(&mf->v1 + fidx); if(me->dvert[vidx].flag) { - alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*vidx, mval, pressure); + alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*vidx, + mval, brush_size_pressure, brush_alpha_pressure); if(alpha) { do_weight_paint_vertex(wp, ob, &wpi, vidx, alpha, paintweight); } @@ -2361,14 +2542,17 @@ copy_vpaint_prev(vp, (unsigned int *)me->mcol, me->totface); /* some old cruft to sort out later */ - mul_m4_m4m4(mat, ob->obmat, vpd->vc.rv3d->viewmat); + mult_m4_m4m4(mat, vpd->vc.rv3d->viewmat, ob->obmat); invert_m4_m4(imat, mat); copy_m3_m4(vpd->vpimat, imat); return 1; } -static void vpaint_paint_face(VPaint *vp, VPaintData *vpd, Object *ob, const unsigned int index, const float mval[2], float pressure, int UNUSED(flip)) +static void vpaint_paint_face(VPaint *vp, VPaintData *vpd, Object *ob, + const unsigned int index, const float mval[2], + const float brush_size_pressure, const float brush_alpha_pressure, + int UNUSED(flip)) { ViewContext *vc = &vpd->vc; Brush *brush = paint_brush(&vp->paint); @@ -2378,12 +2562,14 @@ unsigned int *mcolorig= ((unsigned int*)vp->vpaint_prev) + 4*index; float alpha; int i; + + int brush_alpha_pressure_i; if((vp->flag & VP_COLINDEX && mface->mat_nr!=ob->actcol-1) || ((me->editflag & ME_EDIT_PAINT_MASK) && !(mface->flag & ME_FACE_SEL))) return; - if(brush->vertexpaint_tool==VP_BLUR) { + if (brush->vertexpaint_tool == PAINT_BLEND_BLUR) { unsigned int fcol1= mcol_blend( mcol[0], mcol[1], 128); if(mface->v4) { unsigned int fcol2= mcol_blend( mcol[2], mcol[3], 128); @@ -2392,18 +2578,23 @@ else { vpd->paintcol= mcol_blend( mcol[2], fcol1, 170); } - } + brush_alpha_pressure_i = (int)(brush_alpha_pressure*255.0f); + for(i = 0; i < (mface->v4 ? 4 : 3); ++i) { - alpha= calc_vp_alpha_dl(vp, vc, vpd->vpimat, vpd->vertexcosnos+6*(&mface->v1)[i], mval, pressure); - if(alpha) - vpaint_blend(vp, mcol+i, mcolorig+i, vpd->paintcol, (int)(alpha*255.0f)); + alpha = calc_vp_alpha_dl(vp, vc, vpd->vpimat, vpd->vertexcosnos+6*(&mface->v1)[i], + mval, brush_size_pressure, brush_alpha_pressure); + if (alpha) { + const int alpha_i = (int)(alpha*255.0f); + mcol[i] = vpaint_blend(vp, mcol[i], mcolorig[i], vpd->paintcol, alpha_i, brush_alpha_pressure_i); + } } } static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, PointerRNA *itemptr) { + Scene *scene= CTX_data_scene(C); ToolSettings *ts= CTX_data_tool_settings(C); struct VPaintData *vpd = paint_stroke_mode_data(stroke); VPaint *vp= ts->vpaint; @@ -2414,16 +2605,19 @@ float mat[4][4]; int *indexar= vpd->indexar; int totindex, index, flip; - float pressure, mval[2]; + float mval[2]; + + const float pressure = RNA_float_get(itemptr, "pressure"); + const float brush_size_pressure = brush_size(scene, brush) * (brush_use_size_pressure(scene, brush) ? pressure : 1.0f); + const float brush_alpha_pressure = brush_alpha(scene, brush) * (brush_use_alpha_pressure(scene, brush) ? pressure : 1.0f); RNA_float_get_array(itemptr, "mouse", mval); flip = RNA_boolean_get(itemptr, "pen_flip"); - pressure = RNA_float_get(itemptr, "pressure"); view3d_operator_needs_opengl(C); /* load projection matrix */ - mul_m4_m4m4(mat, ob->obmat, vc->rv3d->persmat); + mult_m4_m4m4(mat, vc->rv3d->persmat, ob->obmat); mval[0]-= vc->ar->winrct.xmin; mval[1]-= vc->ar->winrct.ymin; @@ -2431,7 +2625,7 @@ /* which faces are involved */ if(vp->flag & VP_AREA) { - totindex= sample_backbuf_area(vc, indexar, me->totface, mval[0], mval[1], brush_size(brush)); + totindex= sample_backbuf_area(vc, indexar, me->totface, mval[0], mval[1], brush_size_pressure); } else { indexar[0]= view3d_sample_backbuf(vc, mval[0], mval[1]); @@ -2442,14 +2636,15 @@ swap_m4m4(vc->rv3d->persmat, mat); for(index=0; indextotface) - vpaint_paint_face(vp, vpd, ob, indexar[index]-1, mval, pressure, flip); + if (indexar[index] && indexar[index]<=me->totface) { + vpaint_paint_face(vp, vpd, ob, indexar[index]-1, mval, brush_size_pressure, brush_alpha_pressure, flip); + } } swap_m4m4(vc->rv3d->persmat, mat); /* was disabled because it is slow, but necessary for blur */ - if(brush->vertexpaint_tool == VP_BLUR) + if (brush->vertexpaint_tool == PAINT_BLEND_BLUR) do_shared_vertexcol(me); ED_region_tag_redraw(vc->ar); diff -Nru blender-2.61/source/blender/editors/sculpt_paint/SConscript blender-2.62/source/blender/editors/sculpt_paint/SConscript --- blender-2.61/source/blender/editors/sculpt_paint/SConscript 2011-12-13 19:52:00.000000000 +0000 +++ blender-2.62/source/blender/editors/sculpt_paint/SConscript 2012-02-15 19:36:40.000000000 +0000 @@ -8,7 +8,7 @@ incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf' incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include' incs += ' ../../render/extern/include' -incs += ' ../../gpu ../../makesrna ../../blenloader' +incs += ' ../../gpu ../../makesrna ../../blenloader ../uvedit' if env['OURPLATFORM'] == 'linux': cflags='-pthread' diff -Nru blender-2.61/source/blender/editors/sculpt_paint/sculpt.c blender-2.62/source/blender/editors/sculpt_paint/sculpt.c --- blender-2.61/source/blender/editors/sculpt_paint/sculpt.c 2011-12-13 19:52:00.000000000 +0000 +++ blender-2.62/source/blender/editors/sculpt_paint/sculpt.c 2012-02-15 19:36:40.000000000 +0000 @@ -236,7 +236,7 @@ float vertex_rotation; - char saved_active_brush_name[24]; + char saved_active_brush_name[MAX_ID_NAME]; int alt_smooth; float plane_trim_squared; @@ -248,90 +248,51 @@ /* Get a screen-space rectangle of the modified area */ static int sculpt_get_redraw_rect(ARegion *ar, RegionView3D *rv3d, - Object *ob, rcti *rect) + Object *ob, rcti *rect) { + SculptSession *ss; PBVH *pbvh= ob->sculpt->pbvh; - float bb_min[3], bb_max[3], pmat[4][4]; - int i, j, k; - - ED_view3d_ob_project_mat_get(rv3d, ob, pmat); + float bb_min[3], bb_max[3]; if(!pbvh) return 0; BLI_pbvh_redraw_BB(pbvh, bb_min, bb_max); - rect->xmin = rect->ymin = INT_MAX; - rect->xmax = rect->ymax = INT_MIN; - - if(bb_min[0] > bb_max[0] || bb_min[1] > bb_max[1] || bb_min[2] > bb_max[2]) + /* convert 3D bounding box to screen space */ + if(!paint_convert_bb_to_rect(rect, + bb_min, + bb_max, + ar, + rv3d, + ob)) { return 0; - - for(i = 0; i < 2; ++i) { - for(j = 0; j < 2; ++j) { - for(k = 0; k < 2; ++k) { - float vec[3], proj[2]; - vec[0] = i ? bb_min[0] : bb_max[0]; - vec[1] = j ? bb_min[1] : bb_max[1]; - vec[2] = k ? bb_min[2] : bb_max[2]; - ED_view3d_project_float(ar, vec, proj, pmat); - rect->xmin = MIN2(rect->xmin, proj[0]); - rect->xmax = MAX2(rect->xmax, proj[0]); - rect->ymin = MIN2(rect->ymin, proj[1]); - rect->ymax = MAX2(rect->ymax, proj[1]); - } - } } - - if (rect->xmin < rect->xmax && rect->ymin < rect->ymax) { - /* expand redraw rect with redraw rect from previous step to prevent - partial-redraw issues caused by fast strokes. This is needed here (not in sculpt_flush_update) - as it was before because redraw rectangle should be the same in both of - optimized PBVH draw function and 3d view redraw (if not -- some mesh parts could - disapper from screen (sergey) */ - SculptSession *ss = ob->sculpt; - - if (ss->cache) { - if (!BLI_rcti_is_empty(&ss->cache->previous_r)) - BLI_union_rcti(rect, &ss->cache->previous_r); - } - return 1; + /* expand redraw rect with redraw rect from previous step to + prevent partial-redraw issues caused by fast strokes. This is + needed here (not in sculpt_flush_update) as it was before + because redraw rectangle should be the same in both of + optimized PBVH draw function and 3d view redraw (if not -- some + mesh parts could disapper from screen (sergey) */ + ss = ob->sculpt; + if(ss->cache) { + if(!BLI_rcti_is_empty(&ss->cache->previous_r)) + BLI_union_rcti(rect, &ss->cache->previous_r); } - return 0; + return 1; } void sculpt_get_redraw_planes(float planes[4][4], ARegion *ar, RegionView3D *rv3d, Object *ob) { PBVH *pbvh= ob->sculpt->pbvh; - BoundBox bb; - bglMats mats; rcti rect; - memset(&bb, 0, sizeof(BoundBox)); + sculpt_get_redraw_rect(ar, rv3d, ob, &rect); - view3d_get_transformation(ar, rv3d, ob, &mats); - sculpt_get_redraw_rect(ar, rv3d,ob, &rect); - -#if 1 - /* use some extra space just in case */ - rect.xmin -= 2; - rect.xmax += 2; - rect.ymin -= 2; - rect.ymax += 2; -#else - /* it was doing this before, allows to redraw a smaller - part of the screen but also gives artifaces .. */ - rect.xmin += 2; - rect.xmax -= 2; - rect.ymin += 2; - rect.ymax -= 2; -#endif - - ED_view3d_calc_clipping(&bb, planes, &mats, &rect); - mul_m4_fl(planes, -1.0f); + paint_calc_redraw_planes(planes, ar, rv3d, ob, &rect); /* clear redraw flag from nodes */ if(pbvh) @@ -582,17 +543,23 @@ special multiplier found experimentally to scale the strength factor. */ static float brush_strength(Sculpt *sd, StrokeCache *cache, float feather) { + const Scene *scene = cache->vc->scene; Brush *brush = paint_brush(&sd->paint); /* Primary strength input; square it to make lower values more sensitive */ - const float root_alpha = brush_alpha(brush); + const float root_alpha = brush_alpha(scene, brush); float alpha = root_alpha*root_alpha; float dir = brush->flag & BRUSH_DIR_IN ? -1 : 1; - float pressure = brush_use_alpha_pressure(brush) ? cache->pressure : 1; + float pressure = brush_use_alpha_pressure(scene, brush) ? cache->pressure : 1; float pen_flip = cache->pen_flip ? -1 : 1; float invert = cache->invert ? -1 : 1; float accum = integrate_overlap(brush); - float overlap = (brush->flag & BRUSH_SPACE_ATTEN && brush->flag & BRUSH_SPACE && !(brush->flag & BRUSH_ANCHORED)) && (brush->spacing < 100) ? 1.0f/accum : 1; // spacing is integer percentage of radius, divide by 50 to get normalized diameter + /* spacing is integer percentage of radius, divide by 50 to get + normalized diameter */ + float overlap = (brush->flag & BRUSH_SPACE_ATTEN && + brush->flag & BRUSH_SPACE && + !(brush->flag & BRUSH_ANCHORED) && + (brush->spacing < 100)) ? 1.0f/accum : 1; float flip = dir * invert * pen_flip; switch(brush->sculpt_tool){ @@ -707,16 +674,16 @@ radius = ss->cache->pixel_radius; // use pressure adjusted size for fixed mode - x = point_2d[0]; - y = point_2d[1]; + x = point_2d[0] + ss->cache->vc->ar->winrct.xmin; + y = point_2d[1] + ss->cache->vc->ar->winrct.ymin; } else /* else (mtex->brush_map_mode == MTEX_MAP_MODE_TILED), leave the coordinates relative to the screen */ { - radius = brush_size(br); // use unadjusted size for tiled mode + radius = brush_size(ss->cache->vc->scene, br); // use unadjusted size for tiled mode - x = point_2d[0] - ss->cache->vc->ar->winrct.xmin; - y = point_2d[1] - ss->cache->vc->ar->winrct.ymin; + x = point_2d[0]; + y = point_2d[1]; } x /= ss->cache->vc->ar->winx; @@ -1201,6 +1168,7 @@ static void do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) { SculptSession *ss = ob->sculpt; + const Scene *scene = ss->cache->vc->scene; Brush *brush = paint_brush(&sd->paint); float offset[3], area_normal[3]; float bstrength= ss->cache->bstrength; @@ -1216,8 +1184,8 @@ /* we divide out the squared alpha and multiply by the squared crease to give us the pinch strength */ - if(brush_alpha(brush) > 0.0f) - crease_correction = brush->crease_pinch_factor*brush->crease_pinch_factor/(brush_alpha(brush)*brush_alpha(brush)); + if(brush_alpha(scene, brush) > 0.0f) + crease_correction = brush->crease_pinch_factor*brush->crease_pinch_factor/(brush_alpha(scene, brush)*brush_alpha(scene, brush)); else crease_correction = brush->crease_pinch_factor*brush->crease_pinch_factor; @@ -1688,7 +1656,7 @@ if(ss->cache->original) { BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { if(sculpt_brush_test_fast(&test, unode->co[vd.i])) { - add_v3_v3(private_fc, vd.co); + add_v3_v3(private_fc, unode->co[vd.i]); private_count++; } } @@ -1716,7 +1684,9 @@ /* this calculates flatten center and area normal together, amortizing the memory bandwidth and loop overhead to calculate both at the same time */ -static void calc_area_normal_and_flatten_center(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float an[3], float fc[3]) +static void calc_area_normal_and_flatten_center(Sculpt *sd, Object *ob, + PBVHNode **nodes, int totnode, + float an[3], float fc[3]) { SculptSession *ss = ob->sculpt; int n; @@ -1758,7 +1728,7 @@ add_norm_if(ss->cache->view_normal, private_an, private_out_flip, fno); // fc - add_v3_v3(private_fc, vd.co); + add_v3_v3(private_fc, unode->co[vd.i]); private_count++; } } @@ -2121,7 +2091,7 @@ copy_v3_v3(mat[3], ss->cache->location); mat[3][3] = 1; normalize_m4(mat); scale_m4_fl(scale, ss->cache->radius); - mul_m4_m4m4(tmat, scale, mat); + mult_m4_m4m4(tmat, mat, scale); invert_m4_m4(mat, tmat); #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) @@ -2588,7 +2558,9 @@ /* Flip all the editdata across the axis/axes specified by symm. Used to calculate multiple modifications to the mesh when symmetry is enabled. */ -static void calc_brushdata_symm(Sculpt *sd, StrokeCache *cache, const char symm, const char axis, const float angle, const float UNUSED(feather)) +static void calc_brushdata_symm(Sculpt *sd, StrokeCache *cache, const char symm, + const char axis, const float angle, + const float UNUSED(feather)) { (void)sd; /* unused */ @@ -2620,7 +2592,9 @@ mul_m4_v3(cache->symm_rot_mat, cache->grab_delta_symmetry); } -static void do_radial_symmetry(Sculpt *sd, Object *ob, Brush *brush, const char symm, const int axis, const float feather) +static void do_radial_symmetry(Sculpt *sd, Object *ob, Brush *brush, + const char symm, const int axis, + const float feather) { SculptSession *ss = ob->sculpt; int i; @@ -2686,10 +2660,10 @@ cache->first_time= 0; } -static void sculpt_update_tex(Sculpt *sd, SculptSession *ss) +static void sculpt_update_tex(const Scene *scene, Sculpt *sd, SculptSession *ss) { Brush *brush = paint_brush(&sd->paint); - const int radius= brush_size(brush); + const int radius= brush_size(scene, brush); if(ss->texcache) { MEM_freeN(ss->texcache); @@ -2954,7 +2928,10 @@ cache->original = 1; } - if(ELEM8(brush->sculpt_tool, SCULPT_TOOL_DRAW, SCULPT_TOOL_CREASE, SCULPT_TOOL_BLOB, SCULPT_TOOL_LAYER, SCULPT_TOOL_INFLATE, SCULPT_TOOL_CLAY, SCULPT_TOOL_CLAY_TUBES, SCULPT_TOOL_ROTATE)) + if(ELEM8(brush->sculpt_tool, + SCULPT_TOOL_DRAW, SCULPT_TOOL_CREASE, SCULPT_TOOL_BLOB, + SCULPT_TOOL_LAYER, SCULPT_TOOL_INFLATE, SCULPT_TOOL_CLAY, + SCULPT_TOOL_CLAY_TUBES, SCULPT_TOOL_ROTATE)) if(!(brush->flag & BRUSH_ACCUMULATE)) cache->original = 1; @@ -3038,8 +3015,11 @@ } /* Initialize the stroke cache variants from operator properties */ -static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, struct PaintStroke *stroke, PointerRNA *ptr) +static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, + struct PaintStroke *stroke, + PointerRNA *ptr) { + Scene *scene = CTX_data_scene(C); SculptSession *ss = ob->sculpt; StrokeCache *cache = ss->cache; Brush *brush = paint_brush(&sd->paint); @@ -3074,19 +3054,19 @@ sd->pressure_value= cache->pressure; cache->previous_pixel_radius = cache->pixel_radius; - cache->pixel_radius = brush_size(brush); + cache->pixel_radius = brush_size(scene, brush); if(cache->first_time) { - if (!brush_use_locked_size(brush)) { - cache->initial_radius= paint_calc_object_space_radius(cache->vc, cache->true_location, brush_size(brush)); - brush_set_unprojected_radius(brush, cache->initial_radius); + if (!brush_use_locked_size(scene, brush)) { + cache->initial_radius= paint_calc_object_space_radius(cache->vc, cache->true_location, brush_size(scene, brush)); + brush_set_unprojected_radius(scene, brush, cache->initial_radius); } else { - cache->initial_radius= brush_unprojected_radius(brush); + cache->initial_radius= brush_unprojected_radius(scene, brush); } } - if(brush_use_size_pressure(brush)) { + if(brush_use_size_pressure(scene, brush)) { cache->pixel_radius *= cache->pressure; cache->radius= cache->initial_radius * cache->pressure; } @@ -3095,7 +3075,9 @@ cache->radius_squared = cache->radius*cache->radius; - if(!(brush->flag & BRUSH_ANCHORED || ELEM4(brush->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_SNAKE_HOOK, SCULPT_TOOL_THUMB, SCULPT_TOOL_ROTATE))) { + if(!(brush->flag & BRUSH_ANCHORED || + ELEM4(brush->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_SNAKE_HOOK, + SCULPT_TOOL_THUMB, SCULPT_TOOL_ROTATE))) { copy_v2_v2(cache->tex_mouse, cache->mouse); if ( (brush->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED) && @@ -3123,7 +3105,7 @@ halfway[0] = (float)dx * 0.5f + cache->initial_mouse[0]; halfway[1] = (float)dy * 0.5f + cache->initial_mouse[1]; - if (sculpt_stroke_get_location(C, stroke, out, halfway)) { + if (sculpt_stroke_get_location(C, out, halfway)) { copy_v3_v3(sd->anchored_location, out); copy_v2_v2(sd->anchored_initial_mouse, halfway); copy_v2_v2(cache->tex_mouse, halfway); @@ -3137,7 +3119,9 @@ if (!hit) copy_v2_v2(sd->anchored_initial_mouse, cache->initial_mouse); - cache->radius= paint_calc_object_space_radius(paint_stroke_view_context(stroke), cache->true_location, cache->pixel_radius); + cache->radius= paint_calc_object_space_radius(paint_stroke_view_context(stroke), + cache->true_location, + cache->pixel_radius); cache->radius_squared = cache->radius*cache->radius; copy_v3_v3(sd->anchored_location, cache->true_location); @@ -3169,7 +3153,7 @@ dx = cache->mouse[0] - cache->initial_mouse[0]; dy = cache->mouse[1] - cache->initial_mouse[1]; - cache->vertex_rotation = -atan2(dx, dy) * cache->bstrength; + cache->vertex_rotation = -atan2f(dx, dy) * cache->bstrength; sd->draw_anchored = 1; copy_v2_v2(sd->anchored_initial_mouse, cache->initial_mouse); @@ -3223,23 +3207,29 @@ (This allows us to ignore the GL depth buffer) Returns 0 if the ray doesn't hit the mesh, non-zero otherwise */ -int sculpt_stroke_get_location(bContext *C, struct PaintStroke *stroke, float out[3], float mouse[2]) +int sculpt_stroke_get_location(bContext *C, float out[3], float mouse[2]) { - ViewContext *vc = paint_stroke_view_context(stroke); - Object *ob = vc->obact; - SculptSession *ss= ob->sculpt; - StrokeCache *cache= ss->cache; + ViewContext vc; + Object *ob; + SculptSession *ss; + StrokeCache *cache; float ray_start[3], ray_end[3], ray_normal[3], dist; float obimat[4][4]; float mval[2]; SculptRaycastData srd; - mval[0] = mouse[0] - vc->ar->winrct.xmin; - mval[1] = mouse[1] - vc->ar->winrct.ymin; + view3d_set_viewcontext(C, &vc); + + ob = vc.obact; + ss = ob->sculpt; + cache = ss->cache; sculpt_stroke_modifiers_check(C, ob); - ED_view3d_win_to_segment_clip(vc->ar, vc->v3d, mval, ray_start, ray_end); + mval[0] = mouse[0] - vc.ar->winrct.xmin; + mval[1] = mouse[1] - vc.ar->winrct.ymin; + + ED_view3d_win_to_segment_clip(vc.ar, vc.v3d, mval, ray_start, ray_end); invert_m4_m4(obimat, ob->obmat); mul_m4_v3(obimat, ray_start); @@ -3248,7 +3238,7 @@ sub_v3_v3v3(ray_normal, ray_end, ray_start); dist= normalize_v3(ray_normal); - srd.ss = vc->obact->sculpt; + srd.ss = vc.obact->sculpt; srd.ray_start = ray_start; srd.ray_normal = ray_normal; srd.dist = dist; @@ -3264,7 +3254,7 @@ return srd.hit; } -static void sculpt_brush_init_tex(Sculpt *sd, SculptSession *ss) +static void sculpt_brush_init_tex(const Scene *scene, Sculpt *sd, SculptSession *ss) { Brush *brush = paint_brush(&sd->paint); MTex *mtex= &brush->mtex; @@ -3276,7 +3266,7 @@ /* TODO: Shouldn't really have to do this at the start of every stroke, but sculpt would need some sort of notification when changes are made to the texture. */ - sculpt_update_tex(sd, ss); + sculpt_update_tex(scene, sd, ss); } static int sculpt_brush_stroke_init(bContext *C, wmOperator *op) @@ -3290,7 +3280,7 @@ int is_smooth= 0; view3d_operator_needs_opengl(C); - sculpt_brush_init_tex(sd, ss); + sculpt_brush_init_tex(scene, sd, ss); is_smooth|= mode == BRUSH_STROKE_SMOOTH; is_smooth|= brush->sculpt_tool == SCULPT_TOOL_SMOOTH; @@ -3306,7 +3296,8 @@ /* Restore the mesh before continuing with anchored stroke */ if((brush->flag & BRUSH_ANCHORED) || - (brush->sculpt_tool == SCULPT_TOOL_GRAB && brush_use_size_pressure(brush)) || + (brush->sculpt_tool == SCULPT_TOOL_GRAB && + brush_use_size_pressure(ss->cache->vc->scene, brush)) || (brush->flag & BRUSH_RESTORE_MESH)) { StrokeCache *cache = ss->cache; @@ -3386,14 +3377,14 @@ /* Returns whether the mouse/stylus is over the mesh (1) or over the background (0) */ -static int over_mesh(bContext *C, struct wmOperator *op, float x, float y) +static int over_mesh(bContext *C, struct wmOperator *UNUSED(op), float x, float y) { float mouse[2], co[3]; mouse[0] = x; mouse[1] = y; - return sculpt_stroke_get_location(C, op->customdata, co, mouse); + return sculpt_stroke_get_location(C, co, mouse); } static int sculpt_stroke_test_start(bContext *C, struct wmOperator *op, diff -Nru blender-2.61/source/blender/editors/sculpt_paint/sculpt_intern.h blender-2.62/source/blender/editors/sculpt_paint/sculpt_intern.h --- blender-2.61/source/blender/editors/sculpt_paint/sculpt_intern.h 2011-12-13 19:52:00.000000000 +0000 +++ blender-2.62/source/blender/editors/sculpt_paint/sculpt_intern.h 2012-02-15 19:36:40.000000000 +0000 @@ -73,7 +73,7 @@ void sculpt_stroke_add_point(struct SculptStroke *, const short x, const short y); void sculpt_stroke_apply(struct Sculpt *sd, struct SculptStroke *); void sculpt_stroke_apply_all(struct Sculpt *sd, struct SculptStroke *); -int sculpt_stroke_get_location(bContext *C, struct PaintStroke *stroke, float out[3], float mouse[2]); +int sculpt_stroke_get_location(bContext *C, float out[3], float mouse[2]); /* Undo */ diff -Nru blender-2.61/source/blender/editors/sculpt_paint/sculpt_uv.c blender-2.62/source/blender/editors/sculpt_paint/sculpt_uv.c --- blender-2.61/source/blender/editors/sculpt_paint/sculpt_uv.c 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/source/blender/editors/sculpt_paint/sculpt_uv.c 2012-02-15 19:36:40.000000000 +0000 @@ -0,0 +1,780 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + * The Original Code is Copyright (C) Blender Foundation, 2002-2009 + * All rights reserved. + * + * Contributor(s): Antony Riakiotakis + * + * ***** END GPL LICENSE BLOCK ***** + * + * UV Sculpt tools + * + */ + +/** \file blender/editors/sculpt_paint/sculpt_uv.c + * \ingroup edsculpt + */ + + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" +#include "BLI_editVert.h" +#include "BLI_math.h" +#include "BLI_ghash.h" + +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_brush_types.h" +#include "DNA_meshdata_types.h" + +#include "BKE_brush.h" +#include "BKE_paint.h" +#include "BKE_context.h" +#include "BKE_main.h" +#include "BKE_depsgraph.h" +#include "BKE_mesh.h" +#include "BKE_customdata.h" + +#include "ED_screen.h" +#include "ED_image.h" +#include "ED_mesh.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "RNA_access.h" +#include "RNA_define.h" +#include "RNA_enum_types.h" + +#include "paint_intern.h" +#include "uvedit_intern.h" + +#include "UI_view2d.h" + +#define MARK_BOUNDARY 1 + +typedef struct UvAdjacencyElement { + /* pointer to original uvelement */ + UvElement *element; + /* uv pointer for convenience. Caution, this points to the original UVs! */ + float *uv; + /* general use flag (Used to check if Element is boundary here) */ + char flag; +} UvAdjacencyElement; + +typedef struct UvEdge { + unsigned int uv1; + unsigned int uv2; + /* general use flag (Used to check if edge is boundary here, and propagates to adjacency elements) */ + char flag; +}UvEdge; + +typedef struct UVInitialStrokeElement{ + /* index to unique uv */ + int uv; + + /* strength of brush on initial position */ + float strength; + + /* initial uv position */ + float initial_uv[2]; +}UVInitialStrokeElement; + +typedef struct UVInitialStroke{ + /* Initial Selection,for grab brushes for instance */ + UVInitialStrokeElement *initialSelection; + + /* total initially selected UVs*/ + int totalInitialSelected; + + /* initial mouse coordinates */ + float init_coord[2]; +}UVInitialStroke; + + +/* custom data for uv smoothing brush */ +typedef struct UvSculptData{ + /* Contains the first of each set of coincident uvs. + * These will be used to perform smoothing on and propagate the changes + * to their coincident uvs */ + UvAdjacencyElement *uv; + + /* ...Is what it says */ + int totalUniqueUvs; + + /* Edges used for adjacency info, used with laplacian smoothing */ + UvEdge *uvedges; + + /* need I say more? */ + int totalUvEdges; + + /* data for initial stroke, used by tools like grab */ + UVInitialStroke *initial_stroke; + + /* timer to be used for airbrush-type brush */ + wmTimer *timer; + + /* to determine quickly adjacent uvs */ + UvElementMap *elementMap; + + /* uvsmooth Paint for fast reference */ + Paint *uvsculpt; + + /* tool to use. duplicating here to change if modifier keys are pressed */ + char tool; + + /* store invert flag here */ + char invert; +}UvSculptData; + +/*********** Improved Laplacian Relaxation Operator ************************/ +/* original code by Raul Fernandez Hernandez "farsthary" * + * adapted to uv smoothing by Antony Riakiatakis * + ***************************************************************************/ + +typedef struct Temp_UvData{ + float sum_co[2], p[2], b[2], sum_b[2]; + int ncounter; +}Temp_UVData; + + + +void HC_relaxation_iteration_uv(EditMesh *em, UvSculptData *sculptdata, float mouse_coord[2], float alpha, float radius, float aspectRatio){ + Temp_UVData *tmp_uvdata; + float diff[2]; + int i; + float radius_root = sqrt(radius); + Brush *brush = paint_brush(sculptdata->uvsculpt); + + tmp_uvdata = (Temp_UVData *)MEM_callocN(sculptdata->totalUniqueUvs * sizeof(Temp_UVData), "Temporal data"); + + /* counting neighbors */ + for (i = 0; i < sculptdata->totalUvEdges; i++){ + UvEdge *tmpedge = sculptdata->uvedges+i; + tmp_uvdata[tmpedge->uv1].ncounter++; + tmp_uvdata[tmpedge->uv2].ncounter++; + + add_v2_v2(tmp_uvdata[tmpedge->uv2].sum_co, sculptdata->uv[tmpedge->uv1].uv); + add_v2_v2(tmp_uvdata[tmpedge->uv1].sum_co, sculptdata->uv[tmpedge->uv2].uv); + } + + for (i = 0; i < sculptdata->totalUniqueUvs; i++){ + copy_v2_v2(diff,tmp_uvdata[i].sum_co); + mul_v2_fl(diff,1.f/tmp_uvdata[i].ncounter); + copy_v2_v2(tmp_uvdata[i].p,diff); + + tmp_uvdata[i].b[0] = diff[0] - sculptdata->uv[i].uv[0]; + tmp_uvdata[i].b[1] = diff[1] - sculptdata->uv[i].uv[1]; + } + + for (i = 0; i < sculptdata->totalUvEdges; i++){ + UvEdge *tmpedge = sculptdata->uvedges+i; + add_v2_v2(tmp_uvdata[tmpedge->uv1].sum_b, tmp_uvdata[tmpedge->uv2].b); + add_v2_v2(tmp_uvdata[tmpedge->uv2].sum_b, tmp_uvdata[tmpedge->uv1].b); + } + + for (i = 0; i < sculptdata->totalUniqueUvs; i++){ + float dist; + /* This is supposed to happen only if "Pin Edges" is on, since we have initialization on stroke start + * If ever uv brushes get their own mode we should check for toolsettings option too */ + if((sculptdata->uv[i].flag & MARK_BOUNDARY)){ + continue; + } + + sub_v2_v2v2(diff, sculptdata->uv[i].uv, mouse_coord); + diff[1] /= aspectRatio; + if((dist = dot_v2v2(diff, diff)) <= radius){ + UvElement *element; + float strength; + strength = alpha*brush_curve_strength(brush, sqrt(dist), radius_root); + + sculptdata->uv[i].uv[0] = (1.0-strength)*sculptdata->uv[i].uv[0] + strength*(tmp_uvdata[i].p[0] - 0.5f*(tmp_uvdata[i].b[0] + tmp_uvdata[i].sum_b[0]/tmp_uvdata[i].ncounter)); + sculptdata->uv[i].uv[1] = (1.0-strength)*sculptdata->uv[i].uv[1] + strength*(tmp_uvdata[i].p[1] - 0.5f*(tmp_uvdata[i].b[1] + tmp_uvdata[i].sum_b[1]/tmp_uvdata[i].ncounter)); + + for(element = sculptdata->uv[i].element; element; element = element->next){ + MTFace *mt; + if(element->separate && element != sculptdata->uv[i].element) + break; + mt = CustomData_em_get(&em->fdata, element->face->data, CD_MTFACE); + copy_v2_v2(mt->uv[element->tfindex], sculptdata->uv[i].uv); + } + } + } + + MEM_freeN(tmp_uvdata); + + return; +} + +static void laplacian_relaxation_iteration_uv(EditMesh *em, UvSculptData *sculptdata, float mouse_coord[2], float alpha, float radius, float aspectRatio) +{ + Temp_UVData *tmp_uvdata; + float diff[2]; + int i; + float radius_root = sqrt(radius); + Brush *brush = paint_brush(sculptdata->uvsculpt); + + tmp_uvdata = (Temp_UVData *)MEM_callocN(sculptdata->totalUniqueUvs * sizeof(Temp_UVData), "Temporal data"); + + /* counting neighbors */ + for (i = 0; i < sculptdata->totalUvEdges; i++){ + UvEdge *tmpedge = sculptdata->uvedges+i; + tmp_uvdata[tmpedge->uv1].ncounter++; + tmp_uvdata[tmpedge->uv2].ncounter++; + + add_v2_v2(tmp_uvdata[tmpedge->uv2].sum_co, sculptdata->uv[tmpedge->uv1].uv); + add_v2_v2(tmp_uvdata[tmpedge->uv1].sum_co, sculptdata->uv[tmpedge->uv2].uv); + } + + /* Original Lacplacian algorithm included removal of normal component of translation. here it is not + * needed since we translate along the UV plane always.*/ + for (i = 0; i < sculptdata->totalUniqueUvs; i++){ + copy_v2_v2(tmp_uvdata[i].p, tmp_uvdata[i].sum_co); + mul_v2_fl(tmp_uvdata[i].p, 1.f/tmp_uvdata[i].ncounter); + } + + for (i = 0; i < sculptdata->totalUniqueUvs; i++){ + float dist; + /* This is supposed to happen only if "Pin Edges" is on, since we have initialization on stroke start + * If ever uv brushes get their own mode we should check for toolsettings option too */ + if((sculptdata->uv[i].flag & MARK_BOUNDARY)){ + continue; + } + + sub_v2_v2v2(diff, sculptdata->uv[i].uv, mouse_coord); + diff[1] /= aspectRatio; + if((dist = dot_v2v2(diff, diff)) <= radius){ + UvElement *element; + float strength; + strength = alpha*brush_curve_strength(brush, sqrt(dist), radius_root); + + sculptdata->uv[i].uv[0] = (1.0-strength)*sculptdata->uv[i].uv[0] + strength*tmp_uvdata[i].p[0]; + sculptdata->uv[i].uv[1] = (1.0-strength)*sculptdata->uv[i].uv[1] + strength*tmp_uvdata[i].p[1]; + + for(element = sculptdata->uv[i].element; element; element = element->next){ + MTFace *mt; + if(element->separate && element != sculptdata->uv[i].element) + break; + mt = CustomData_em_get(&em->fdata, element->face->data, CD_MTFACE); + copy_v2_v2(mt->uv[element->tfindex], sculptdata->uv[i].uv); + } + } + } + + MEM_freeN(tmp_uvdata); + + return; +} + + +static void uv_sculpt_stroke_apply(bContext *C, wmOperator *op, wmEvent *event, Object *obedit) +{ + float co[2], radius, radius_root; + Scene *scene = CTX_data_scene(C); + ARegion *ar = CTX_wm_region(C); + EditMesh *em = BKE_mesh_get_editmesh(obedit->data); + unsigned int tool; + UvSculptData *sculptdata = (UvSculptData *)op->customdata; + SpaceImage *sima; + int invert; + int width, height; + float aspectRatio; + float alpha, zoomx, zoomy; + Brush *brush = paint_brush(sculptdata->uvsculpt); + ToolSettings *toolsettings = CTX_data_tool_settings(C); + tool = sculptdata->tool; + invert = sculptdata->invert? -1 : 1; + alpha = brush_alpha(scene, brush); + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]); + + sima = CTX_wm_space_image(C); + ED_space_image_size(sima, &width, &height); + ED_space_image_zoom(sima, ar, &zoomx, &zoomy); + + radius = brush_size(scene, brush)/(width*zoomx); + aspectRatio = width/(float)height; + + /* We will compare squares to save some computation */ + radius = radius*radius; + radius_root = sqrt(radius); + + /* + * Pinch Tool + */ + if(tool == UV_SCULPT_TOOL_PINCH){ + int i; + alpha *= invert; + for (i = 0; i < sculptdata->totalUniqueUvs; i++){ + float dist, diff[2]; + /* This is supposed to happen only if "Lock Borders" is on, since we have initialization on stroke start + * If ever uv brushes get their own mode we should check for toolsettings option too */ + if(sculptdata->uv[i].flag & MARK_BOUNDARY){ + continue; + } + + sub_v2_v2v2(diff, sculptdata->uv[i].uv, co); + diff[1] /= aspectRatio; + if((dist = dot_v2v2(diff, diff)) <= radius){ + UvElement *element; + float strength; + strength = alpha*brush_curve_strength(brush, sqrt(dist), radius_root); + normalize_v2(diff); + + sculptdata->uv[i].uv[0] -= strength*diff[0]*0.001; + sculptdata->uv[i].uv[1] -= strength*diff[1]*0.001; + + for(element = sculptdata->uv[i].element; element; element = element->next){ + MTFace *mt; + if(element->separate && element != sculptdata->uv[i].element) + break; + mt = CustomData_em_get(&em->fdata, element->face->data, CD_MTFACE); + copy_v2_v2(mt->uv[element->tfindex], sculptdata->uv[i].uv); + } + } + } + } + + /* + * Smooth Tool + */ + else if(tool == UV_SCULPT_TOOL_RELAX){ + unsigned int method = toolsettings->uv_relax_method; + if(method == UV_SCULPT_TOOL_RELAX_HC){ + HC_relaxation_iteration_uv(em, sculptdata, co, alpha, radius, aspectRatio); + }else{ + laplacian_relaxation_iteration_uv(em, sculptdata, co, alpha, radius, aspectRatio); + } + } + + /* + * Grab Tool + */ + else if(tool == UV_SCULPT_TOOL_GRAB){ + int i; + float diff[2]; + sub_v2_v2v2(diff, co, sculptdata->initial_stroke->init_coord); + + for(i = 0; i < sculptdata->initial_stroke->totalInitialSelected; i++ ){ + UvElement *element; + int uvindex = sculptdata->initial_stroke->initialSelection[i].uv; + float strength = sculptdata->initial_stroke->initialSelection[i].strength; + sculptdata->uv[uvindex].uv[0] = sculptdata->initial_stroke->initialSelection[i].initial_uv[0] + strength*diff[0]; + sculptdata->uv[uvindex].uv[1] = sculptdata->initial_stroke->initialSelection[i].initial_uv[1] + strength*diff[1]; + + for(element = sculptdata->uv[uvindex].element; element; element = element->next){ + MTFace *mt; + if(element->separate && element != sculptdata->uv[uvindex].element) + break; + mt = CustomData_em_get(&em->fdata, element->face->data, CD_MTFACE); + copy_v2_v2(mt->uv[element->tfindex], sculptdata->uv[uvindex].uv); + } + } + } + + BKE_mesh_end_editmesh(obedit->data, em); +} + + +static void uv_sculpt_stroke_exit(bContext *C, wmOperator *op) +{ + UvSculptData *data = op->customdata; + if(data->timer){ + WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), data->timer); + } + if(data->elementMap) + { + EM_free_uv_element_map(data->elementMap); + } + if(data->uv){ + MEM_freeN(data->uv); + } + if(data->uvedges){ + MEM_freeN(data->uvedges); + } + if(data->initial_stroke){ + if(data->initial_stroke->initialSelection){ + MEM_freeN(data->initial_stroke->initialSelection); + } + MEM_freeN(data->initial_stroke); + } + + MEM_freeN(data); + op->customdata = NULL; +} + +static int get_uv_element_offset_from_face(UvElementMap *map, EditFace *efa, int index, int island_index, int doIslands){ + UvElement *element = ED_get_uv_element(map, efa, index); + if(!element || (doIslands && element->island != island_index)){ + return -1; + } + return element - map->buf; +} + + +static unsigned int uv_edge_hash(const void *key){ + UvEdge *edge = (UvEdge *)key; + return + BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv2)) + + BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv1)); +} + +static int uv_edge_compare(const void *a, const void *b){ + UvEdge *edge1 = (UvEdge *)a; + UvEdge *edge2 = (UvEdge *)b; + + if((edge1->uv1 == edge2->uv1) && (edge1->uv2 == edge2->uv2)){ + return 0; + } + return 1; +} + + +static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, wmEvent *event) +{ + Scene *scene = CTX_data_scene(C); + Object *obedit = CTX_data_edit_object(C); + ToolSettings *ts = scene->toolsettings; + UvSculptData *data = MEM_callocN(sizeof(*data), "UV Smooth Brush Data"); + EditMesh *em = BKE_mesh_get_editmesh(obedit->data); + + op->customdata = data; + + if(data){ + int counter = 0, i; + ARegion *ar= CTX_wm_region(C); + float co[2]; + EditFace *efa; + UvEdge *edges; + GHash *edgeHash; + GHashIterator* ghi; + MTFace *mt; + int do_island_optimization = !(ts->uv_sculpt_settings & UV_SCULPT_ALL_ISLANDS); + int island_index = 0; + /* Holds, for each UvElement in elementMap, a pointer to its unique uv.*/ + int *uniqueUv; + data->tool = (RNA_enum_get(op->ptr, "mode") == BRUSH_STROKE_SMOOTH)? UV_SCULPT_TOOL_RELAX : ts->uv_sculpt_tool; + data->invert = (RNA_enum_get(op->ptr, "mode") == BRUSH_STROKE_INVERT)? 1 : 0; + + data->uvsculpt = &ts->uvsculpt->paint; + + if(do_island_optimization){ + /* We will need island information */ + if(ts->uv_flag & UV_SYNC_SELECTION){ + data->elementMap = EM_make_uv_element_map(em, 0, 1); + }else{ + data->elementMap = EM_make_uv_element_map(em, 1, 1); + } + }else { + if(ts->uv_flag & UV_SYNC_SELECTION){ + data->elementMap = EM_make_uv_element_map(em, 0, 0); + }else{ + data->elementMap = EM_make_uv_element_map(em, 1, 0); + } + } + + if(!data->elementMap){ + uv_sculpt_stroke_exit(C, op); + return NULL; + } + + /* Mouse coordinates, useful for some functions like grab and sculpt all islands */ + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]); + + /* we need to find the active island here */ + if(do_island_optimization){ + UvElement *element; + NearestHit hit; + Image *ima= CTX_data_edit_image(C); + uv_find_nearest_vert(scene, ima, em, co, NULL, &hit); + + element = ED_get_uv_element(data->elementMap, hit.efa, hit.uv); + island_index = element->island; + } + + + /* Count 'unique' uvs */ + for(i = 0; i < data->elementMap->totalUVs; i++){ + if(data->elementMap->buf[i].separate + && (!do_island_optimization || data->elementMap->buf[i].island == island_index)){ + counter++; + } + } + + /* Allocate the unique uv buffers */ + data->uv = MEM_mallocN(sizeof(*data->uv)*counter, "uv_brush_unique_uvs"); + uniqueUv = MEM_mallocN(sizeof(*uniqueUv)*data->elementMap->totalUVs, "uv_brush_unique_uv_map"); + edgeHash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "uv_brush_edge_hash"); + /* we have at most totalUVs edges */ + edges = MEM_mallocN(sizeof(*edges)*data->elementMap->totalUVs, "uv_brush_all_edges"); + if(!data->uv || !uniqueUv || !edgeHash || !edges){ + if(edges){ + MEM_freeN(edges); + } + if(uniqueUv){ + MEM_freeN(uniqueUv); + } + if(edgeHash){ + MEM_freeN(edgeHash); + } + uv_sculpt_stroke_exit(C, op); + return NULL; + } + + data->totalUniqueUvs = counter; + /* So that we can use this as index for the UvElements */ + counter = -1; + /* initialize the unique UVs */ + for(i = 0; i < em->totvert; i++){ + UvElement *element = data->elementMap->vert[i]; + for(; element; element = element->next){ + if(element->separate){ + if(do_island_optimization && (element->island != island_index)){ + /* skip this uv if not on the active island */ + for(; element->next && !(element->next->separate); element = element->next) + ; + continue; + } + efa = element->face; + mt = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + + counter++; + data->uv[counter].element = element; + data->uv[counter].flag = 0; + data->uv[counter].uv = mt->uv[element->tfindex]; + } + /* pointer arithmetic to the rescue, as always :)*/ + uniqueUv[element - data->elementMap->buf] = counter; + } + } + + /* Now, on to generate our uv connectivity data */ + for(efa = em->faces.first, counter = 0; efa; efa = efa->next){ + int nverts = efa->v4 ? 4 : 3; + for(i = 0; i < nverts; i++){ + int offset1, itmp1 = get_uv_element_offset_from_face(data->elementMap, efa, i, island_index, do_island_optimization); + int offset2, itmp2 = get_uv_element_offset_from_face(data->elementMap, efa, (i+1)%nverts, island_index, do_island_optimization); + + /* Skip edge if not found(unlikely) or not on valid island */ + if(itmp1 == -1 || itmp2 == -1) + continue; + + offset1 = uniqueUv[itmp1]; + offset2 = uniqueUv[itmp2]; + + edges[counter].flag = 0; + /* using an order policy, sort uvs according to address space. This avoids + * Having two different UvEdges with the same uvs on different positions */ + if(offset1 < offset2){ + edges[counter].uv1 = offset1; + edges[counter].uv2 = offset2; + } + else{ + edges[counter].uv1 = offset2; + edges[counter].uv2 = offset1; + } + /* Hack! Set the value of the key to its flag. Now we can set the flag when an edge exists twice :) */ + if(BLI_ghash_haskey(edgeHash, &edges[counter])){ + char *flag = BLI_ghash_lookup(edgeHash, &edges[counter]); + *flag = 1; + } + else{ + /* Hack mentioned */ + BLI_ghash_insert(edgeHash, &edges[counter], &edges[counter].flag); + } + counter++; + } + } + MEM_freeN(uniqueUv); + + /* Allocate connectivity data, we allocate edges once */ + data->uvedges = MEM_mallocN(sizeof(*data->uvedges)*BLI_ghash_size(edgeHash), "uv_brush_edge_connectivity_data"); + if(!data->uvedges){ + BLI_ghash_free(edgeHash, NULL, NULL); + MEM_freeN(edges); + uv_sculpt_stroke_exit(C, op); + return NULL; + } + ghi = BLI_ghashIterator_new(edgeHash); + if(!ghi){ + BLI_ghash_free(edgeHash, NULL, NULL); + MEM_freeN(edges); + uv_sculpt_stroke_exit(C, op); + return NULL; + } + /* fill the edges with data */ + for(i = 0; !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi)){ + data->uvedges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(ghi)); + } + data->totalUvEdges = BLI_ghash_size(edgeHash); + + /* cleanup temporary stuff */ + BLI_ghashIterator_free(ghi); + BLI_ghash_free(edgeHash, NULL, NULL); + MEM_freeN(edges); + + /* transfer boundary edge property to uvs */ + if(ts->uv_sculpt_settings & UV_SCULPT_LOCK_BORDERS){ + for(i = 0; i < data->totalUvEdges; i++){ + if(!data->uvedges[i].flag){ + data->uv[data->uvedges[i].uv1].flag |= MARK_BOUNDARY; + data->uv[data->uvedges[i].uv2].flag |= MARK_BOUNDARY; + } + } + } + + /* Allocate initial selection for grab tool */ + if(data->tool){ + float radius, radius_root; + UvSculptData *sculptdata = (UvSculptData *)op->customdata; + SpaceImage *sima; + int width, height; + float aspectRatio; + float alpha, zoomx, zoomy; + Brush *brush = paint_brush(sculptdata->uvsculpt); + + alpha = brush_alpha(scene, brush); + + radius = brush_size(scene, brush); + sima = CTX_wm_space_image(C); + ED_space_image_size(sima, &width, &height); + ED_space_image_zoom(sima, ar, &zoomx, &zoomy); + + aspectRatio = width/(float)height; + radius /= (width*zoomx); + radius = radius*radius; + radius_root = sqrt(radius); + + /* Allocate selection stack */ + data->initial_stroke = MEM_mallocN(sizeof(*data->initial_stroke), "uv_sculpt_initial_stroke"); + if(!data->initial_stroke){ + uv_sculpt_stroke_exit(C, op); + } + data->initial_stroke->initialSelection = MEM_mallocN(sizeof(*data->initial_stroke->initialSelection)*data->totalUniqueUvs, "uv_sculpt_initial_selection"); + if(!data->initial_stroke->initialSelection){ + uv_sculpt_stroke_exit(C, op); + } + + copy_v2_v2(data->initial_stroke->init_coord, co); + + counter = 0; + + for(i = 0; i < data->totalUniqueUvs; i++){ + float dist, diff[2]; + if(data->uv[i].flag & MARK_BOUNDARY){ + continue; + } + + sub_v2_v2v2(diff, data->uv[i].uv, co); + diff[1] /= aspectRatio; + if((dist = dot_v2v2(diff, diff)) <= radius){ + float strength; + strength = alpha*brush_curve_strength(brush, sqrt(dist), radius_root); + + data->initial_stroke->initialSelection[counter].uv = i; + data->initial_stroke->initialSelection[counter].strength = strength; + copy_v2_v2(data->initial_stroke->initialSelection[counter].initial_uv, data->uv[i].uv); + counter++; + } + } + + data->initial_stroke->totalInitialSelected = counter; + } + } + + return op->customdata; +} + +static int uv_sculpt_stroke_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + UvSculptData *data; + Object *obedit = CTX_data_edit_object(C); + + if(!(data = uv_sculpt_stroke_init(C, op, event))) { + return OPERATOR_CANCELLED; + } + + uv_sculpt_stroke_apply(C, op, event, obedit); + + data->timer= WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.001f); + + if(!data->timer){ + uv_sculpt_stroke_exit(C, op); + return OPERATOR_CANCELLED; + } + WM_event_add_modal_handler(C, op); + + return OPERATOR_RUNNING_MODAL; +} + + +static int uv_sculpt_stroke_modal(bContext *C, wmOperator *op, wmEvent *event) +{ + UvSculptData *data = (UvSculptData *)op->customdata; + Object *obedit = CTX_data_edit_object(C); + + switch(event->type) { + case LEFTMOUSE: + case MIDDLEMOUSE: + case RIGHTMOUSE: + uv_sculpt_stroke_exit(C, op); + return OPERATOR_FINISHED; + + case MOUSEMOVE: + case INBETWEEN_MOUSEMOVE: + uv_sculpt_stroke_apply(C, op, event, obedit); + break; + case TIMER: + if(event->customdata == data->timer) + uv_sculpt_stroke_apply(C, op, event, obedit); + break; + default: + return OPERATOR_RUNNING_MODAL; + } + + ED_region_tag_redraw(CTX_wm_region(C)); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + DAG_id_tag_update(obedit->data, 0); + return OPERATOR_RUNNING_MODAL; +} + +void SCULPT_OT_uv_sculpt_stroke(wmOperatorType *ot) +{ + static EnumPropertyItem stroke_mode_items[] = { + {BRUSH_STROKE_NORMAL, "NORMAL", 0, "Normal", "Apply brush normally"}, + {BRUSH_STROKE_INVERT, "INVERT", 0, "Invert", "Invert action of brush for duration of stroke"}, + {BRUSH_STROKE_SMOOTH, "RELAX", 0, "Relax", "Switch brush to relax mode for duration of stroke"}, + {0} + }; + + /* identifiers */ + ot->name = "Sculpt UVs"; + ot->description = "Sculpt UVs using a brush"; + ot->idname = "SCULPT_OT_uv_sculpt_stroke"; + + /* api callbacks */ + ot->invoke = uv_sculpt_stroke_invoke; + ot->modal = uv_sculpt_stroke_modal; + ot->poll = uv_sculpt_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + + /* props */ + RNA_def_enum(ot->srna, "mode", stroke_mode_items, BRUSH_STROKE_NORMAL, "Mode", "Stroke Mode"); +} diff -Nru blender-2.61/source/blender/editors/sound/sound_ops.c blender-2.62/source/blender/editors/sound/sound_ops.c --- blender-2.61/source/blender/editors/sound/sound_ops.c 2011-12-13 19:51:48.000000000 +0000 +++ blender-2.62/source/blender/editors/sound/sound_ops.c 2012-02-15 19:36:28.000000000 +0000 @@ -162,7 +162,7 @@ static int sound_open_invoke(bContext *C, wmOperator *op, wmEvent *event) { - if(RNA_property_is_set(op->ptr, "filepath")) + if(RNA_struct_property_is_set(op->ptr, "filepath")) return sound_open_exec(C, op); sound_open_init(C, op); @@ -186,7 +186,7 @@ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH); + WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); RNA_def_boolean(ot->srna, "cache", FALSE, "Cache", "Cache the sound in memory"); RNA_def_boolean(ot->srna, "mono", FALSE, "Mono", "Mixdown the sound to mono"); } @@ -207,11 +207,109 @@ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH); + WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); RNA_def_boolean(ot->srna, "cache", FALSE, "Cache", "Cache the sound in memory"); RNA_def_boolean(ot->srna, "mono", TRUE, "Mono", "Mixdown the sound to mono"); } +/* ******************************************************* */ + +static int sound_update_animation_flags_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Sequence* seq; + Scene* scene = CTX_data_scene(C); + struct FCurve* fcu; + char driven; + + SEQ_BEGIN(scene->ed, seq) { + fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "volume", 0, &driven); + if(fcu || driven) + seq->flag |= SEQ_AUDIO_VOLUME_ANIMATED; + else + seq->flag &= ~SEQ_AUDIO_VOLUME_ANIMATED; + + fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "pitch", 0, &driven); + if(fcu || driven) + seq->flag |= SEQ_AUDIO_PITCH_ANIMATED; + else + seq->flag &= ~SEQ_AUDIO_PITCH_ANIMATED; + + fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "pan", 0, &driven); + if(fcu || driven) + seq->flag |= SEQ_AUDIO_PAN_ANIMATED; + else + seq->flag &= ~SEQ_AUDIO_PAN_ANIMATED; + } + SEQ_END + + fcu = id_data_find_fcurve(&scene->id, scene, &RNA_Scene, "audio_volume", 0, &driven); + if(fcu || driven) + scene->audio.flag |= AUDIO_VOLUME_ANIMATED; + else + scene->audio.flag &= ~AUDIO_VOLUME_ANIMATED; + + return OPERATOR_FINISHED; +} + +static void SOUND_OT_update_animation_flags(wmOperatorType *ot) +{ + /* + This operator is needed to set a correct state of the sound animation + System. Unfortunately there's no really correct place to call the exec + function, that's why I made it an operator that's only visible in the + search menu. Apart from that the bake animation operator calls it too. + */ + + /* identifiers */ + ot->name= "Update animation"; + ot->description= "Update animation flags"; + ot->idname= "SOUND_OT_update_animation_flags"; + + /* api callbacks */ + ot->exec= sound_update_animation_flags_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER; +} + +/* ******************************************************* */ + +static int sound_bake_animation_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Main* bmain = CTX_data_main(C); + Scene* scene = CTX_data_scene(C); + int oldfra = scene->r.cfra; + int cfra; + + sound_update_animation_flags_exec(C, NULL); + + for(cfra = scene->r.sfra > 0 ? scene->r.sfra - 1 : 0; cfra <= scene->r.efra + 1; cfra++) + { + scene->r.cfra = cfra; + scene_update_for_newframe(bmain, scene, scene->lay); + } + + scene->r.cfra = oldfra; + scene_update_for_newframe(bmain, scene, scene->lay); + + return OPERATOR_FINISHED; +} + +static void SOUND_OT_bake_animation(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Update animation cache"; + ot->description= "Updates the audio animation cache so that it's up to date"; + ot->idname= "SOUND_OT_bake_animation"; + + /* api callbacks */ + ot->exec= sound_bake_animation_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER; +} + + /******************** mixdown operator ********************/ static int sound_mixdown_exec(bContext *C, wmOperator *op) @@ -228,6 +326,8 @@ AUD_Codec codec; const char* result; + sound_bake_animation_exec(C, op); + RNA_string_get(op->ptr, "filepath", path); bitrate = RNA_int_get(op->ptr, "bitrate") * 1000; accuracy = RNA_int_get(op->ptr, "accuracy"); @@ -259,12 +359,14 @@ static int sound_mixdown_invoke(bContext *C, wmOperator *op, wmEvent *event) { - if(RNA_property_is_set(op->ptr, "filepath")) + if(RNA_struct_property_is_set(op->ptr, "filepath")) return sound_mixdown_exec(C, op); return WM_operator_filesel(C, op, event); } +#ifdef WITH_AUDASPACE + static int sound_mixdown_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop) { const char *prop_id= RNA_property_identifier(prop); @@ -274,7 +376,6 @@ ); } -#ifdef WITH_AUDASPACE static void sound_mixdown_draw(bContext *C, wmOperator *op) { static EnumPropertyItem pcm_format_items[] = { @@ -486,7 +587,7 @@ ot->flag= OPTYPE_REGISTER; /* properties */ - WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH); + WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); #ifdef WITH_AUDASPACE RNA_def_int(ot->srna, "accuracy", 1024, 1, 16777216, "Accuracy", "Sample accuracy, important for animation data (the lower the value, the more accurate)", 1, 16777216); RNA_def_enum(ot->srna, "container", container_items, AUD_CONTAINER_FLAC, "Container", "File format"); @@ -552,7 +653,7 @@ bSound* sound= NULL; /* find the suppplied image by name */ - if (RNA_property_is_set(op->ptr, "id")) { + if (RNA_struct_property_is_set(op->ptr, "id")) { char sndname[MAX_ID_NAME-2]; RNA_string_get(op->ptr, "id", sndname); sound = BLI_findstring(&CTX_data_main(C)->sound, sndname, offsetof(ID, name) + 2); @@ -574,7 +675,7 @@ Editing* ed = CTX_data_scene(C)->ed; bSound* sound; - if(RNA_property_is_set(op->ptr, "id")) + if(RNA_struct_property_is_set(op->ptr, "id")) return sound_unpack_exec(C, op); if(!ed || !ed->act_seq || ed->act_seq->type != SEQ_SOUND) @@ -615,104 +716,6 @@ /* ******************************************************* */ -static int sound_update_animation_flags_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Sequence* seq; - Scene* scene = CTX_data_scene(C); - struct FCurve* fcu; - char driven; - - SEQ_BEGIN(scene->ed, seq) { - fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "volume", 0, &driven); - if(fcu || driven) - seq->flag |= SEQ_AUDIO_VOLUME_ANIMATED; - else - seq->flag &= ~SEQ_AUDIO_VOLUME_ANIMATED; - - fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "pitch", 0, &driven); - if(fcu || driven) - seq->flag |= SEQ_AUDIO_PITCH_ANIMATED; - else - seq->flag &= ~SEQ_AUDIO_PITCH_ANIMATED; - - fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "pan", 0, &driven); - if(fcu || driven) - seq->flag |= SEQ_AUDIO_PAN_ANIMATED; - else - seq->flag &= ~SEQ_AUDIO_PAN_ANIMATED; - } - SEQ_END - - fcu = id_data_find_fcurve(&scene->id, scene, &RNA_Scene, "audio_volume", 0, &driven); - if(fcu || driven) - scene->audio.flag |= AUDIO_VOLUME_ANIMATED; - else - scene->audio.flag &= ~AUDIO_VOLUME_ANIMATED; - - return OPERATOR_FINISHED; -} - -static void SOUND_OT_update_animation_flags(wmOperatorType *ot) -{ - /* - This operator is needed to set a correct state of the sound animation - System. Unfortunately there's no really correct place to call the exec - function, that's why I made it an operator that's only visible in the - search menu. Apart from that the bake animation operator calls it too. - */ - - /* identifiers */ - ot->name= "Update animation"; - ot->description= "Update animation flags"; - ot->idname= "SOUND_OT_update_animation_flags"; - - /* api callbacks */ - ot->exec= sound_update_animation_flags_exec; - - /* flags */ - ot->flag= OPTYPE_REGISTER; -} - -/* ******************************************************* */ - -static int sound_bake_animation_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Main* bmain = CTX_data_main(C); - Scene* scene = CTX_data_scene(C); - int oldfra = scene->r.cfra; - int cfra; - - sound_update_animation_flags_exec(C, NULL); - - for(cfra = scene->r.sfra > 0 ? scene->r.sfra - 1 : 0; cfra <= scene->r.efra + 1; cfra++) - { - scene->r.cfra = cfra; - scene_update_for_newframe(bmain, scene, scene->lay); - } - - scene->r.cfra = oldfra; - scene_update_for_newframe(bmain, scene, scene->lay); - - return OPERATOR_FINISHED; -} - -static void SOUND_OT_bake_animation(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Update animation cache"; - ot->description= "Updates the audio animation cache so that it's up to date"; - ot->idname= "SOUND_OT_bake_animation"; - - /* api callbacks */ - ot->exec= sound_bake_animation_exec; - - /* flags */ - ot->flag= OPTYPE_REGISTER; -} - - -/* ******************************************************* */ - void ED_operatortypes_sound(void) { WM_operatortype_append(SOUND_OT_open); diff -Nru blender-2.61/source/blender/editors/space_action/action_draw.c blender-2.62/source/blender/editors/space_action/action_draw.c --- blender-2.61/source/blender/editors/space_action/action_draw.c 2011-12-13 19:51:48.000000000 +0000 +++ blender-2.62/source/blender/editors/space_action/action_draw.c 2012-02-15 19:36:28.000000000 +0000 @@ -119,7 +119,7 @@ } } { /* second pass: widgets */ - uiBlock *block= uiBeginBlock(C, ar, "dopesheet channel buttons", UI_EMBOSS); + uiBlock *block= uiBeginBlock(C, ar, __func__, UI_EMBOSS); size_t channel_index = 0; y= (float)ACHANNEL_FIRST; diff -Nru blender-2.61/source/blender/editors/space_action/action_ops.c blender-2.62/source/blender/editors/space_action/action_ops.c --- blender-2.61/source/blender/editors/space_action/action_ops.c 2011-12-13 19:51:48.000000000 +0000 +++ blender-2.62/source/blender/editors/space_action/action_ops.c 2012-02-15 19:36:28.000000000 +0000 @@ -36,6 +36,7 @@ #include "DNA_space_types.h" #include "BLI_blenlib.h" +#include "BLI_utildefines.h" #include "ED_anim_api.h" #include "ED_markers.h" @@ -110,32 +111,45 @@ /* action_select.c - selection tools */ /* click-select */ - WM_keymap_add_item(keymap, "ACTION_OT_clickselect", SELECTMOUSE, KM_PRESS, 0, 0); + kmi = WM_keymap_add_item(keymap, "ACTION_OT_clickselect", SELECTMOUSE, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + RNA_boolean_set(kmi->ptr, "column", FALSE); kmi= WM_keymap_add_item(keymap, "ACTION_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_ALT, 0); - RNA_boolean_set(kmi->ptr, "column", 1); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + RNA_boolean_set(kmi->ptr, "column", TRUE); kmi= WM_keymap_add_item(keymap, "ACTION_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0); - RNA_boolean_set(kmi->ptr, "extend", 1); + RNA_boolean_set(kmi->ptr, "extend", TRUE); + RNA_boolean_set(kmi->ptr, "column", FALSE); kmi= WM_keymap_add_item(keymap, "ACTION_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_ALT|KM_SHIFT, 0); - RNA_boolean_set(kmi->ptr, "extend", 1); - RNA_boolean_set(kmi->ptr, "column", 1); + RNA_boolean_set(kmi->ptr, "extend", TRUE); + RNA_boolean_set(kmi->ptr, "column", TRUE); /* select left/right */ - WM_keymap_add_item(keymap, "ACTION_OT_select_leftright", SELECTMOUSE, KM_PRESS, KM_CTRL, 0); + kmi = WM_keymap_add_item(keymap, "ACTION_OT_select_leftright", SELECTMOUSE, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + RNA_enum_set(kmi->ptr, "mode", ACTKEYS_LRSEL_TEST); kmi= WM_keymap_add_item(keymap, "ACTION_OT_select_leftright", SELECTMOUSE, KM_PRESS, KM_CTRL|KM_SHIFT, 0); - RNA_boolean_set(kmi->ptr, "extend", 1); + RNA_boolean_set(kmi->ptr, "extend", TRUE); + RNA_enum_set(kmi->ptr, "mode", ACTKEYS_LRSEL_TEST); kmi= WM_keymap_add_item(keymap, "ACTION_OT_select_leftright", LEFTBRACKETKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); RNA_enum_set(kmi->ptr, "mode", ACTKEYS_LRSEL_LEFT); kmi= WM_keymap_add_item(keymap, "ACTION_OT_select_leftright", RIGHTBRACKETKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); RNA_enum_set(kmi->ptr, "mode", ACTKEYS_LRSEL_RIGHT); /* deselect all */ - WM_keymap_add_item(keymap, "ACTION_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "ACTION_OT_select_all_toggle", IKEY, KM_PRESS, KM_CTRL, 0)->ptr, "invert", 1); + kmi = WM_keymap_add_item(keymap, "ACTION_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "invert", FALSE); + kmi = WM_keymap_add_item(keymap, "ACTION_OT_select_all_toggle", IKEY, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "invert", TRUE); /* borderselect */ - WM_keymap_add_item(keymap, "ACTION_OT_select_border", BKEY, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "ACTION_OT_select_border", BKEY, KM_PRESS, KM_ALT, 0)->ptr, "axis_range", 1); + kmi = WM_keymap_add_item(keymap, "ACTION_OT_select_border", BKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "axis_range", FALSE); + kmi = WM_keymap_add_item(keymap, "ACTION_OT_select_border", BKEY, KM_PRESS, KM_ALT, 0); + RNA_boolean_set(kmi->ptr, "axis_range", TRUE); /* column select */ RNA_enum_set(WM_keymap_add_item(keymap, "ACTION_OT_select_column", KKEY, KM_PRESS, 0, 0)->ptr, "mode", ACTKEYS_COLUMNSEL_KEYS); diff -Nru blender-2.61/source/blender/editors/space_action/action_select.c blender-2.62/source/blender/editors/space_action/action_select.c --- blender-2.61/source/blender/editors/space_action/action_select.c 2011-12-13 19:51:48.000000000 +0000 +++ blender-2.62/source/blender/editors/space_action/action_select.c 2012-02-15 19:36:28.000000000 +0000 @@ -360,6 +360,8 @@ /* ------------------- */ /* Selects all visible keyframes between the specified markers */ +/* TODO, this is almost an _exact_ duplicate of a function of the same name in graph_select.c + * should de-duplicate - campbell */ static void markers_selectkeys_between (bAnimContext *ac) { ListBase anim_data = {NULL, NULL}; diff -Nru blender-2.61/source/blender/editors/space_api/spacetypes.c blender-2.62/source/blender/editors/space_api/spacetypes.c --- blender-2.61/source/blender/editors/space_api/spacetypes.c 2011-12-13 19:52:46.000000000 +0000 +++ blender-2.62/source/blender/editors/space_api/spacetypes.c 2012-02-15 19:37:15.000000000 +0000 @@ -132,6 +132,7 @@ ED_operatormacros_graph(); ED_operatormacros_action(); ED_operatormacros_clip(); + ED_operatormacros_curve(); /* register dropboxes (can use macros) */ spacetypes = BKE_spacetypes_list(); diff -Nru blender-2.61/source/blender/editors/space_buttons/buttons_context.c blender-2.62/source/blender/editors/space_buttons/buttons_context.c --- blender-2.61/source/blender/editors/space_buttons/buttons_context.c 2011-12-13 19:52:03.000000000 +0000 +++ blender-2.62/source/blender/editors/space_buttons/buttons_context.c 2012-02-15 19:36:43.000000000 +0000 @@ -1061,7 +1061,6 @@ if(ptr->id.data) { return ptr->id.data; - break; } } } diff -Nru blender-2.61/source/blender/editors/space_buttons/buttons_header.c blender-2.62/source/blender/editors/space_buttons/buttons_header.c --- blender-2.61/source/blender/editors/space_buttons/buttons_header.c 2011-12-13 19:52:03.000000000 +0000 +++ blender-2.62/source/blender/editors/space_buttons/buttons_header.c 2012-02-15 19:36:43.000000000 +0000 @@ -108,7 +108,7 @@ buttons_context_compute(C, sbuts); - block= uiBeginBlock(C, ar, "header buttons", UI_EMBOSS); + block= uiBeginBlock(C, ar, __func__, UI_EMBOSS); uiBlockSetHandleFunc(block, do_buttons_buttons, NULL); xco= ED_area_header_switchbutton(C, block, yco); diff -Nru blender-2.61/source/blender/editors/space_buttons/buttons_ops.c blender-2.62/source/blender/editors/space_buttons/buttons_ops.c --- blender-2.61/source/blender/editors/space_buttons/buttons_ops.c 2011-12-13 19:52:03.000000000 +0000 +++ blender-2.62/source/blender/editors/space_buttons/buttons_ops.c 2012-02-15 19:36:43.000000000 +0000 @@ -43,6 +43,7 @@ #include "BKE_context.h" #include "BKE_global.h" #include "BKE_main.h" +#include "BKE_report.h" #include "WM_api.h" #include "WM_types.h" @@ -103,7 +104,7 @@ char *str, path[FILE_MAX]; const char *path_prop= RNA_struct_find_property(op->ptr, "directory") ? "directory" : "filepath"; - if (RNA_property_is_set(op->ptr, path_prop)==0 || fbo==NULL) + if (RNA_struct_property_is_set(op->ptr, path_prop)==0 || fbo==NULL) return OPERATOR_CANCELLED; str= RNA_string_get_alloc(op->ptr, path_prop, NULL, 0); @@ -160,6 +161,11 @@ FileBrowseOp *fbo; char *str; + if (CTX_wm_space_file(C)) { + BKE_report(op->reports, RPT_ERROR, "Can't activate a file selector, one already open"); + return OPERATOR_CANCELLED; + } + uiFileBrowseContextProperty(C, &ptr, &prop); if(!prop) @@ -200,7 +206,7 @@ /* normally ED_fileselect_get_params would handle this but we need to because of stupid * user-prefs exception - campbell */ if(RNA_struct_find_property(op->ptr, "relative_path")) { - if(!RNA_property_is_set(op->ptr, "relative_path")) { + if(!RNA_struct_property_is_set(op->ptr, "relative_path")) { /* annoying exception!, if were dealign with the user prefs, default relative to be off */ RNA_boolean_set(op->ptr, "relative_path", U.flag & USER_RELPATHS && (ptr.data != &U)); } @@ -224,7 +230,7 @@ ot->cancel= file_browse_cancel; /* properties */ - WM_operator_properties_filesel(ot, 0, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH); + WM_operator_properties_filesel(ot, 0, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); } /* second operator, only difference from BUTTONS_OT_file_browse is WM_FILESEL_DIRECTORY */ @@ -241,5 +247,5 @@ ot->cancel= file_browse_cancel; /* properties */ - WM_operator_properties_filesel(ot, 0, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_DIRECTORY|WM_FILESEL_RELPATH); + WM_operator_properties_filesel(ot, 0, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_DIRECTORY|WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); } diff -Nru blender-2.61/source/blender/editors/space_buttons/buttons_texture.c blender-2.62/source/blender/editors/space_buttons/buttons_texture.c --- blender-2.61/source/blender/editors/space_buttons/buttons_texture.c 2011-12-13 19:52:03.000000000 +0000 +++ blender-2.62/source/blender/editors/space_buttons/buttons_texture.c 2012-02-15 19:36:43.000000000 +0000 @@ -1,6 +1,4 @@ /* - * $Id$ - * * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or diff -Nru blender-2.61/source/blender/editors/space_buttons/space_buttons.c blender-2.62/source/blender/editors/space_buttons/space_buttons.c --- blender-2.61/source/blender/editors/space_buttons/space_buttons.c 2011-12-13 19:52:03.000000000 +0000 +++ blender-2.62/source/blender/editors/space_buttons/space_buttons.c 2012-02-15 19:36:43.000000000 +0000 @@ -96,11 +96,6 @@ static void buttons_free(SpaceLink *sl) { SpaceButs *sbuts= (SpaceButs*) sl; - - if(sbuts->ri) { - if (sbuts->ri->rect) MEM_freeN(sbuts->ri->rect); - MEM_freeN(sbuts->ri); - } if(sbuts->path) MEM_freeN(sbuts->path); @@ -131,7 +126,6 @@ SpaceButs *sbutsn= MEM_dupallocN(sl); /* clear or remove stuff from old */ - sbutsn->ri= NULL; sbutsn->path= NULL; sbutsn->texuser= NULL; diff -Nru blender-2.61/source/blender/editors/space_clip/clip_draw.c blender-2.62/source/blender/editors/space_clip/clip_draw.c --- blender-2.61/source/blender/editors/space_clip/clip_draw.c 2011-12-13 19:54:33.000000000 +0000 +++ blender-2.62/source/blender/editors/space_clip/clip_draw.c 2012-02-15 19:38:40.000000000 +0000 @@ -75,20 +75,20 @@ { uiStyle *style= UI_GetStyle(); int fontid= style->widget.uifont_id; - char str[32]; - float fontsize, fontwidth; + char numstr[32]; + float font_dims[2] = {0.0f, 0.0f}; /* frame number */ BLF_size(fontid, 11.0f, U.dpi); - BLI_snprintf(str, sizeof(str), "%d", sc->user.framenr); - fontsize= BLF_height(fontid, str); - fontwidth= BLF_width(fontid, str); + BLI_snprintf(numstr, sizeof(numstr), "%d", sc->user.framenr); - glRecti(x, y, x+fontwidth+6, y+fontsize+4); + BLF_width_and_height(fontid, numstr, &font_dims[0], &font_dims[1]); + + glRecti(x, y, x + font_dims[0] + 6.0f, y + font_dims[1] + 4.0f); UI_ThemeColor(TH_TEXT); BLF_position(fontid, x+2.0f, y+2.0f, 0.0f); - BLF_draw(fontid, str, strlen(str)); + BLF_draw(fontid, numstr, sizeof(numstr)); } static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Scene *scene) @@ -96,6 +96,8 @@ float x; int *points, totseg, i, a; float sfra= SFRA, efra= EFRA, framelen= ar->winx/(efra-sfra+1); + MovieTrackingTrack *act_track= BKE_tracking_active_track(&clip->tracking); + MovieTrackingReconstruction *reconstruction= BKE_tracking_get_reconstruction(&clip->tracking); glEnable(GL_BLEND); @@ -119,8 +121,8 @@ } /* track */ - if(clip->tracking.act_track) { - MovieTrackingTrack *track= clip->tracking.act_track; + if(act_track) { + MovieTrackingTrack *track= act_track; for(i= sfra, a= 0; i <= efra; i++) { int framenr; @@ -152,9 +154,9 @@ } /* failed frames */ - if(clip->tracking.reconstruction.flag&TRACKING_RECONSTRUCTED) { - int n= clip->tracking.reconstruction.camnr; - MovieReconstructedCamera *cameras= clip->tracking.reconstruction.cameras; + if(reconstruction->flag&TRACKING_RECONSTRUCTED) { + int n= reconstruction->camnr; + MovieReconstructedCamera *cameras= reconstruction->cameras; glColor4ub(255, 0, 0, 96); @@ -248,9 +250,9 @@ glBegin(GL_LINE_LOOP); glVertex2f(0.0f, 0.0f); - glVertex2f(ibuf->x, 0.0f); - glVertex2f(ibuf->x, ibuf->y); - glVertex2f(0.0f, ibuf->y); + glVertex2f(width, 0.0f); + glVertex2f(width, height); + glVertex2f(0.0f, height); glEnd(); glPopMatrix(); @@ -584,7 +586,7 @@ } /* pyramid */ - if(sel && TRACK_SELECTED(track) && (sc->flag&SC_SHOW_PYRAMID_LEVELS) && (track->tracker==TRACKER_KLT) && (marker->flag&MARKER_DISABLED)==0) { + if(sel && TRACK_SELECTED(track) && (track->tracker==TRACKER_KLT) && (marker->flag&MARKER_DISABLED)==0) { if(track->flag&TRACK_LOCKED) { if(act) UI_ThemeColor(TH_ACT_MARKER); else if(track->pat_flag&SELECT) UI_ThemeColorShade(TH_LOCK_MARKER, 64); @@ -775,7 +777,9 @@ else UI_ThemeColor(TH_SEL_MARKER); } - if(sc->flag&SC_SHOW_MARKER_SEARCH) { + if((sc->flag&SC_SHOW_MARKER_SEARCH) && + ((marker->flag&MARKER_DISABLED)==0 || (sc->flag&SC_SHOW_MARKER_PATTERN)==0)) + { dx= track->search_min[0]; dy= track->search_min[1]; } else if(sc->flag&SC_SHOW_MARKER_PATTERN) { @@ -803,13 +807,13 @@ BLI_snprintf(str, sizeof(str), "%s", track->name); BLF_position(fontid, pos[0], pos[1], 0.0f); - BLF_draw(fontid, str, strlen(str)); + BLF_draw(fontid, str, sizeof(str)); pos[1]-= fontsize; if(track->flag&TRACK_HAS_BUNDLE) { BLI_snprintf(str, sizeof(str), "Average error: %.3f", track->error); BLF_position(fontid, pos[0], pos[1], 0.0f); - BLF_draw(fontid, str, strlen(str)); + BLF_draw(fontid, str, sizeof(str)); pos[1]-= fontsize; } @@ -835,8 +839,9 @@ { float x, y; MovieTracking* tracking= &clip->tracking; - MovieTrackingMarker *marker; + ListBase *tracksbase= BKE_tracking_get_tracks(tracking); MovieTrackingTrack *track, *act_track; + MovieTrackingMarker *marker; int framenr= sc->user.framenr; int undistort= sc->user.render_flag&MCLIP_PROXY_RENDER_UNDISTORT; float *marker_pos= NULL, *fp, *active_pos= NULL, cur_pos[2]; @@ -858,13 +863,13 @@ glMultMatrixf(sc->stabmat); glScalef(width, height, 0); - act_track= clip->tracking.act_track; + act_track= BKE_tracking_active_track(tracking); if(sc->user.render_flag&MCLIP_PROXY_RENDER_UNDISTORT) { int count= 0; /* count */ - track= tracking->tracks.first; + track= tracksbase->first; while(track) { if((track->flag&TRACK_HIDDEN)==0) { marker= BKE_tracking_get_marker(track, framenr); @@ -880,7 +885,7 @@ if(count) { marker_pos= MEM_callocN(2*sizeof(float)*count, "draw_tracking_tracks marker_pos"); - track= tracking->tracks.first; + track= tracksbase->first; fp= marker_pos; while(track) { if((track->flag&TRACK_HIDDEN)==0) { @@ -902,7 +907,7 @@ } if(sc->flag&SC_SHOW_TRACK_PATH) { - track= tracking->tracks.first; + track= tracksbase->first; while(track) { if((track->flag&TRACK_HIDDEN)==0) draw_track_path(sc, clip, track); @@ -912,7 +917,7 @@ } /* markers outline and non-selected areas */ - track= tracking->tracks.first; + track= tracksbase->first; fp= marker_pos; while(track) { if((track->flag&TRACK_HIDDEN)==0) { @@ -936,7 +941,7 @@ /* selected areas only, so selection wouldn't be overlapped by non-selected areas */ - track= tracking->tracks.first; + track= tracksbase->first; fp= marker_pos; while(track) { if((track->flag&TRACK_HIDDEN)==0) { @@ -974,15 +979,16 @@ } if(sc->flag&SC_SHOW_BUNDLES) { + MovieTrackingObject *object= BKE_tracking_active_object(tracking); float pos[4], vec[4], mat[4][4], aspy; glEnable(GL_POINT_SMOOTH); glPointSize(3.0f); aspy= 1.0f/clip->tracking.camera.pixel_aspect; - BKE_tracking_projection_matrix(tracking, framenr, width, height, mat); + BKE_tracking_projection_matrix(tracking, object, framenr, width, height, mat); - track= tracking->tracks.first; + track= tracksbase->first; while(track) { if((track->flag&TRACK_HIDDEN)==0 && track->flag&TRACK_HAS_BUNDLE) { marker= BKE_tracking_get_marker(track, framenr); @@ -1027,7 +1033,7 @@ if(sc->flag&SC_SHOW_NAMES) { /* scaling should be cleared before drawing texts, otherwise font would also be scaled */ - track= tracking->tracks.first; + track= tracksbase->first; fp= marker_pos; while(track) { if((track->flag&TRACK_HIDDEN)==0) { @@ -1172,6 +1178,11 @@ while(layer) { bGPDframe *frame= layer->frames.first; + if(layer->flag & GP_LAYER_HIDE) { + layer= layer->next; + continue; + } + glColor4fv(layer->color); glLineWidth(layer->thickness); glPointSize((float)(layer->thickness + 2)); @@ -1255,14 +1266,24 @@ float smat[4][4], ismat[4][4]; ibuf= ED_space_clip_get_stable_buffer(sc, sc->loc, &sc->scale, &sc->angle); - BKE_tracking_stabdata_to_mat4(width, height, sc->loc, sc->scale, sc->angle, sc->stabmat); - unit_m4(smat); - smat[0][0]= 1.0f/width; - smat[1][1]= 1.0f/height; - invert_m4_m4(ismat, smat); + if(ibuf) { + float loc[2]; + + if(width != ibuf->x) + mul_v2_v2fl(loc, sc->loc, (float)width / ibuf->x); + else + copy_v2_v2(loc, sc->loc); + + BKE_tracking_stabdata_to_mat4(width, height, loc, sc->scale, sc->angle, sc->stabmat); + + unit_m4(smat); + smat[0][0]= 1.0f/width; + smat[1][1]= 1.0f/height; + invert_m4_m4(ismat, smat); - mul_serie_m4(sc->unistabmat, smat, sc->stabmat, ismat, NULL, NULL, NULL, NULL, NULL); + mul_serie_m4(sc->unistabmat, smat, sc->stabmat, ismat, NULL, NULL, NULL, NULL, NULL); + } } else { ibuf= ED_space_clip_get_buffer(sc); @@ -1291,7 +1312,7 @@ MovieClip *clip= ED_space_clip(sc); ImBuf *ibuf; - if((sc->flag&SC_SHOW_GPENCIL)==0 || !clip) + if(!clip) return; if(onlyv2d) { diff -Nru blender-2.61/source/blender/editors/space_clip/clip_editor.c blender-2.62/source/blender/editors/space_clip/clip_editor.c --- blender-2.61/source/blender/editors/space_clip/clip_editor.c 2011-12-13 19:54:33.000000000 +0000 +++ blender-2.62/source/blender/editors/space_clip/clip_editor.c 2012-02-15 19:38:40.000000000 +0000 @@ -86,7 +86,7 @@ if(sc->clip) { ImBuf *ibuf; - ibuf= BKE_movieclip_get_ibuf(sc->clip, &sc->user); + ibuf= BKE_movieclip_get_postprocessed_ibuf(sc->clip, &sc->user, sc->postproc_flag); if(ibuf && (ibuf->rect || ibuf->rect_float)) return ibuf; @@ -103,7 +103,7 @@ if(sc->clip) { ImBuf *ibuf; - ibuf= BKE_movieclip_get_stable_ibuf(sc->clip, &sc->user, loc, scale, angle); + ibuf= BKE_movieclip_get_stable_ibuf(sc->clip, &sc->user, loc, scale, angle, sc->postproc_flag); if(ibuf && (ibuf->rect || ibuf->rect_float)) return ibuf; @@ -171,12 +171,13 @@ MovieClip *clip= ED_space_clip(sc); MovieTrackingTrack *track; int width, height, ok= 0; + ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking); INIT_MINMAX2(min, max); ED_space_clip_size(sc, &width, &height); - track= clip->tracking.tracks.first; + track= tracksbase->first; while(track) { if(TRACK_VIEW_SELECTED(sc, track)) { MovieTrackingMarker *marker= BKE_tracking_get_marker(track, sc->user.framenr); diff -Nru blender-2.61/source/blender/editors/space_clip/clip_graph_draw.c blender-2.62/source/blender/editors/space_clip/clip_graph_draw.c --- blender-2.61/source/blender/editors/space_clip/clip_graph_draw.c 2011-12-13 19:54:33.000000000 +0000 +++ blender-2.62/source/blender/editors/space_clip/clip_graph_draw.c 2012-02-15 19:38:40.000000000 +0000 @@ -47,6 +47,7 @@ #include "ED_clip.h" #include "BIF_gl.h" +#include "BIF_glutil.h" #include "WM_types.h" @@ -120,6 +121,26 @@ glScalef(xscale, 1.0, 1.0); } +static void draw_graph_sfra_efra(Scene *scene, View2D *v2d) +{ + UI_view2d_view_ortho(v2d); + + /* currently clip editor supposes that editing clip length is equal to scene frame range */ + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + glColor4f(0.0f, 0.0f, 0.0f, 0.4f); + + glRectf(v2d->cur.xmin, v2d->cur.ymin, (float)SFRA, v2d->cur.ymax); + glRectf((float)EFRA, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax); + glDisable(GL_BLEND); + + UI_ThemeColorShade(TH_BACK, -60); + + /* thin lines where the actual frames are */ + fdrawline((float)SFRA, v2d->cur.ymin, (float)SFRA, v2d->cur.ymax); + fdrawline((float)EFRA, v2d->cur.ymin, (float)EFRA, v2d->cur.ymax); +} + static void tracking_segment_point_cb(void *UNUSED(userdata), MovieTrackingTrack *UNUSED(track), MovieTrackingMarker *marker, int UNUSED(coord), float val) { @@ -155,15 +176,16 @@ } static void tracking_segment_knot_cb(void *userdata, MovieTrackingTrack *track, - MovieTrackingMarker *marker, int UNUSED(coord), float val) + MovieTrackingMarker *marker, int coord, float val) { struct { MovieTrackingTrack *act_track; int sel; float xscale, yscale, hsize; } *data = userdata; - int sel= 0; + int sel= 0, sel_flag; if(track!=data->act_track) return; - sel= (marker->flag&MARKER_GRAPH_SEL) ? 1 : 0; + sel_flag= coord == 0 ? MARKER_GRAPH_SEL_X : MARKER_GRAPH_SEL_Y; + sel= (marker->flag & sel_flag) ? 1 : 0; if(sel == data->sel) { if(sel) UI_ThemeColor(TH_HANDLE_VERTEX_SELECT); @@ -177,6 +199,7 @@ { MovieClip *clip= ED_space_clip(sc); MovieTracking *tracking= &clip->tracking; + MovieTrackingTrack *act_track= BKE_tracking_active_track(tracking); int width, height; struct { MovieTrackingTrack *act_track; int sel; float xscale, yscale, hsize; } userdata; @@ -188,13 +211,13 @@ /* non-selected knot handles */ userdata.hsize= UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE); userdata.sel= 0; - userdata.act_track= clip->tracking.act_track; + userdata.act_track= act_track; UI_view2d_getscale(v2d, &userdata.xscale, &userdata.yscale); clip_graph_tracking_values_iterate(sc, &userdata, tracking_segment_knot_cb, NULL, NULL); /* draw graph lines */ glEnable(GL_BLEND); - clip_graph_tracking_values_iterate(sc, tracking->act_track, tracking_segment_point_cb, tracking_segment_start_cb, tracking_segment_end_cb); + clip_graph_tracking_values_iterate(sc, act_track, tracking_segment_point_cb, tracking_segment_start_cb, tracking_segment_end_cb); glDisable(GL_BLEND); /* selected knot handles on top of curves */ @@ -206,7 +229,7 @@ { MovieClip *clip= ED_space_clip(sc); MovieTracking *tracking= &clip->tracking; - MovieTrackingReconstruction *reconstruction= &tracking->reconstruction; + MovieTrackingReconstruction *reconstruction= BKE_tracking_get_reconstruction(tracking); int i, lines= 0, prevfra= 0; glColor3f(0.0f, 0.0f, 1.0f); @@ -253,6 +276,9 @@ draw_frame_curves(sc); } + /* frame range */ + draw_graph_sfra_efra(scene, v2d); + /* current frame */ draw_graph_cfra(sc, ar, scene); } diff -Nru blender-2.61/source/blender/editors/space_clip/clip_graph_ops.c blender-2.62/source/blender/editors/space_clip/clip_graph_ops.c --- blender-2.61/source/blender/editors/space_clip/clip_graph_ops.c 2011-12-13 19:54:33.000000000 +0000 +++ blender-2.62/source/blender/editors/space_clip/clip_graph_ops.c 2012-02-15 19:38:40.000000000 +0000 @@ -30,6 +30,7 @@ */ #include "DNA_object_types.h" /* SELECT */ +#include "DNA_scene_types.h" #include "MEM_guardedalloc.h" @@ -58,6 +59,19 @@ /******************** common graph-editing utilities ********************/ +static int ED_space_clip_graph_poll(bContext *C) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + + if(sc && sc->clip) { + ARegion *ar = CTX_wm_region(C); + + return ar->regiontype == RGN_TYPE_PREVIEW; + } + + return 0; +} + typedef struct { int action; } SelectUserData; @@ -68,13 +82,13 @@ switch(data->action) { case SEL_SELECT: - marker->flag|= MARKER_GRAPH_SEL; + marker->flag|= (MARKER_GRAPH_SEL_X|MARKER_GRAPH_SEL_Y); break; case SEL_DESELECT: - marker->flag&= ~MARKER_GRAPH_SEL; + marker->flag&= ~(MARKER_GRAPH_SEL_X|MARKER_GRAPH_SEL_Y); break; case SEL_INVERT: - marker->flag^= MARKER_GRAPH_SEL; + marker->flag^= (MARKER_GRAPH_SEL_X|MARKER_GRAPH_SEL_Y); break; } } @@ -155,13 +169,14 @@ ARegion *ar= CTX_wm_region(C); View2D *v2d= &ar->v2d; MovieTracking *tracking= &clip->tracking; + MovieTrackingTrack *act_track= BKE_tracking_active_track(tracking); static const int delta= 6; - if(tracking->act_track) { + if(act_track) { MouseSelectUserData userdata; mouse_select_init_data(&userdata, co); - clip_graph_tracking_values_iterate_track(sc, tracking->act_track, + clip_graph_tracking_values_iterate_track(sc, act_track, &userdata, find_nearest_tracking_knot_cb, NULL, NULL); if(userdata.marker) { @@ -176,7 +191,10 @@ clip_graph_tracking_iterate(sc, &selectdata, toggle_selection_cb); } - userdata.marker->flag|= MARKER_GRAPH_SEL; + if(userdata.coord==0) + userdata.marker->flag|= MARKER_GRAPH_SEL_X; + else + userdata.marker->flag|= MARKER_GRAPH_SEL_Y; return 1; } @@ -191,6 +209,7 @@ SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= ED_space_clip(sc); MovieTracking *tracking= &clip->tracking; + MovieTrackingTrack *act_track= BKE_tracking_active_track(tracking); MouseSelectUserData userdata; mouse_select_init_data(&userdata, co); @@ -198,12 +217,12 @@ if(userdata.track) { if(extend) { - if(tracking->act_track==userdata.track) { + if(act_track==userdata.track) { /* currently only single curve can be selected (selected curve represents active track) */ - tracking->act_track= NULL; + act_track= NULL; } } - else if(tracking->act_track!=userdata.track) { + else if(act_track!=userdata.track) { MovieTrackingMarker *marker; SelectUserData selectdata = {SEL_DESELECT}; @@ -273,7 +292,7 @@ /* api callbacks */ ot->exec= select_exec; ot->invoke= select_invoke; - ot->poll= ED_space_clip_poll; + ot->poll= ED_space_clip_graph_poll; /* flags */ ot->flag= OPTYPE_UNDO; @@ -292,9 +311,11 @@ SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= ED_space_clip(sc); MovieTracking *tracking= &clip->tracking; + ListBase *tracksbase= BKE_tracking_get_tracks(tracking); + MovieTrackingTrack *act_track= BKE_tracking_active_track(tracking); - if(tracking->act_track) - clip_delete_track(C, clip, tracking->act_track); + if(act_track) + clip_delete_track(C, clip, tracksbase, act_track); return OPERATOR_FINISHED; } @@ -322,16 +343,17 @@ SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= ED_space_clip(sc); MovieTracking *tracking= &clip->tracking; + ListBase *tracksbase= BKE_tracking_get_tracks(tracking); + MovieTrackingTrack *act_track= BKE_tracking_active_track(tracking); - if(tracking->act_track) { + if(act_track) { int a= 0; - MovieTrackingTrack *track= tracking->act_track; - while(amarkersnr) { - MovieTrackingMarker *marker= &track->markers[a]; + while(amarkersnr) { + MovieTrackingMarker *marker= &act_track->markers[a]; - if(marker->flag&MARKER_GRAPH_SEL) - clip_delete_marker(C, clip, track, marker); + if(marker->flag & (MARKER_GRAPH_SEL_X|MARKER_GRAPH_SEL_Y)) + clip_delete_marker(C, clip, tracksbase, act_track, marker); else a++; } @@ -349,8 +371,112 @@ /* api callbacks */ ot->exec= delete_knot_exec; - ot->poll= ED_space_clip_poll; + ot->poll= ED_space_clip_graph_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } + +/******************** view all operator ********************/ + +typedef struct { + float min, max; +} ViewAllUserData; + +static void view_all_cb(void *userdata, MovieTrackingTrack *UNUSED(track), MovieTrackingMarker *UNUSED(marker), + int UNUSED(coord), float val) +{ + ViewAllUserData *data = (ViewAllUserData *)userdata; + + if(val < data->min) data->min = val; + if(val > data->max) data->max = val; +} + +static int view_all_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Scene *scene = CTX_data_scene(C); + ARegion *ar = CTX_wm_region(C); + SpaceClip *sc = CTX_wm_space_clip(C); + View2D *v2d = &ar->v2d; + ViewAllUserData userdata; + float extra; + + userdata.max = -FLT_MAX; + userdata.min = FLT_MAX; + + clip_graph_tracking_values_iterate(sc, &userdata, view_all_cb, NULL, NULL); + + /* set extents of view to start/end frames */ + v2d->cur.xmin = (float)SFRA; + v2d->cur.xmax = (float)EFRA; + + if (userdata.min < userdata.max) { + v2d->cur.ymin = userdata.min; + v2d->cur.ymax = userdata.max; + } + else { + v2d->cur.ymin = -10; + v2d->cur.ymax = 10; + } + + /* we need an extra "buffer" factor on either side so that the endpoints are visible */ + extra= 0.01f * (v2d->cur.xmax - v2d->cur.xmin); + v2d->cur.xmin -= extra; + v2d->cur.xmax += extra; + + extra= 0.01f * (v2d->cur.ymax - v2d->cur.ymin); + v2d->cur.ymin -= extra; + v2d->cur.ymax += extra; + + ED_region_tag_redraw(ar); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_graph_view_all(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "View All"; + ot->description = "View all curves in editor"; + ot->idname = "CLIP_OT_graph_view_all"; + + /* api callbacks */ + ot->exec = view_all_exec; + ot->poll = ED_space_clip_graph_poll; +} + +/******************** jump to current frame operator ********************/ + +void ED_clip_graph_center_current_frame(Scene *scene, ARegion *ar) +{ + View2D *v2d = &ar->v2d; + float extra = (v2d->cur.xmax - v2d->cur.xmin) / 2.0f; + + /* set extents of view to start/end frames */ + v2d->cur.xmin = (float)CFRA - extra; + v2d->cur.xmax = (float)CFRA + extra; +} + +static int center_current_frame_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Scene *scene = CTX_data_scene(C); + ARegion *ar = CTX_wm_region(C); + + ED_clip_graph_center_current_frame(scene, ar); + + ED_region_tag_redraw(ar); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_graph_center_current_frame(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Center Current Frame"; + ot->description = "Scroll view so current frame would be centered"; + ot->idname = "CLIP_OT_graph_center_current_frame"; + + /* api callbacks */ + ot->exec = center_current_frame_exec; + ot->poll = ED_space_clip_graph_poll; +} diff -Nru blender-2.61/source/blender/editors/space_clip/clip_intern.h blender-2.62/source/blender/editors/space_clip/clip_intern.h --- blender-2.61/source/blender/editors/space_clip/clip_intern.h 2011-12-13 19:54:33.000000000 +0000 +++ blender-2.62/source/blender/editors/space_clip/clip_intern.h 2012-02-15 19:38:40.000000000 +0000 @@ -55,9 +55,13 @@ void clip_draw_graph(struct SpaceClip *sc, struct ARegion *ar, struct Scene *scene); /* clip_graph_ops.c */ +void ED_clip_graph_center_current_frame(struct Scene *scene, struct ARegion *ar); + void CLIP_OT_graph_select(struct wmOperatorType *ot); void CLIP_OT_graph_delete_curve(struct wmOperatorType *ot); void CLIP_OT_graph_delete_knot(struct wmOperatorType *ot); +void CLIP_OT_graph_view_all(struct wmOperatorType *ot); +void CLIP_OT_graph_center_current_frame(struct wmOperatorType *ot); /* clip_ops.c */ void CLIP_OT_open(struct wmOperatorType *ot); @@ -92,8 +96,8 @@ void clip_graph_tracking_iterate(struct SpaceClip *sc, void *userdata, void (*func) (void *userdata, struct MovieTrackingMarker *marker)); -void clip_delete_track(struct bContext *C, struct MovieClip *clip, struct MovieTrackingTrack *track); -void clip_delete_marker(struct bContext *C, struct MovieClip *clip, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker); +void clip_delete_track(struct bContext *C, struct MovieClip *clip, struct ListBase *tracksbase, struct MovieTrackingTrack *track); +void clip_delete_marker(struct bContext *C, struct MovieClip *clip, struct ListBase *tracksbase, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker); void clip_view_center_to_point(struct SpaceClip *sc, float x, float y); @@ -124,6 +128,7 @@ void CLIP_OT_set_floor(struct wmOperatorType *ot); void CLIP_OT_set_axis(struct wmOperatorType *ot); void CLIP_OT_set_scale(struct wmOperatorType *ot); +void CLIP_OT_set_solution_scale(struct wmOperatorType *ot); void CLIP_OT_set_center_principal(struct wmOperatorType *ot); @@ -139,6 +144,12 @@ void CLIP_OT_stabilize_2d_select(struct wmOperatorType *ot); void CLIP_OT_stabilize_2d_set_rotation(struct wmOperatorType *ot); -void CLIP_OT_clean_tracks(wmOperatorType *ot); +void CLIP_OT_clean_tracks(struct wmOperatorType *ot); + +void CLIP_OT_tracking_object_new(struct wmOperatorType *ot); +void CLIP_OT_tracking_object_remove(struct wmOperatorType *ot); + +void CLIP_OT_copy_tracks(struct wmOperatorType *ot); +void CLIP_OT_paste_tracks(struct wmOperatorType *ot); #endif /* ED_CLIP_INTERN_H */ diff -Nru blender-2.61/source/blender/editors/space_clip/clip_ops.c blender-2.62/source/blender/editors/space_clip/clip_ops.c --- blender-2.61/source/blender/editors/space_clip/clip_ops.c 2011-12-13 20:14:33.000000000 +0000 +++ blender-2.62/source/blender/editors/space_clip/clip_ops.c 2012-02-15 19:38:40.000000000 +0000 @@ -184,10 +184,10 @@ if(clip) path= clip->name; - if(!RNA_property_is_set(op->ptr, "relative_path")) + if(!RNA_struct_property_is_set(op->ptr, "relative_path")) RNA_boolean_set(op->ptr, "relative_path", U.flag & USER_RELPATHS); - if(RNA_property_is_set(op->ptr, "filepath")) + if(RNA_struct_property_is_set(op->ptr, "filepath")) return open_exec(C, op); open_init(C, op); @@ -213,21 +213,18 @@ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH); + WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); } /******************* reload clip operator *********************/ static int reload_exec(bContext *C, wmOperator *UNUSED(op)) { - SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= CTX_data_edit_movieclip(C); if(!clip) return OPERATOR_CANCELLED; - sc->scopes.ok= 0; - BKE_movieclip_reload(clip); WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip); @@ -827,6 +824,7 @@ Scene *scene; struct Main *main; MovieClip *clip; + int clip_flag; } ProxyJob; static void proxy_freejob(void *pjv) @@ -836,6 +834,27 @@ MEM_freeN(pj); } +static int proxy_bitflag_to_array(int size_flag, int build_sizes[4], int undistort) +{ + int build_count = 0; + int size_flags[2][4] = {{MCLIP_PROXY_SIZE_25, + MCLIP_PROXY_SIZE_50, + MCLIP_PROXY_SIZE_75, + MCLIP_PROXY_SIZE_100}, + {MCLIP_PROXY_UNDISTORTED_SIZE_25, + MCLIP_PROXY_UNDISTORTED_SIZE_50, + MCLIP_PROXY_UNDISTORTED_SIZE_75, + MCLIP_PROXY_UNDISTORTED_SIZE_100}}; + int size_nr = undistort ? 1 : 0; + + if(size_flag & size_flags[size_nr][0]) build_sizes[build_count++]= MCLIP_PROXY_RENDER_SIZE_25; + if(size_flag & size_flags[size_nr][1]) build_sizes[build_count++]= MCLIP_PROXY_RENDER_SIZE_50; + if(size_flag & size_flags[size_nr][2]) build_sizes[build_count++]= MCLIP_PROXY_RENDER_SIZE_75; + if(size_flag & size_flags[size_nr][3]) build_sizes[build_count++]= MCLIP_PROXY_RENDER_SIZE_100; + + return build_count; +} + /* only this runs inside thread */ static void proxy_startjob(void *pjv, short *stop, short *do_update, float *progress) { @@ -843,22 +862,23 @@ Scene *scene=pj->scene; MovieClip *clip= pj->clip; struct MovieDistortion *distortion= NULL; - int cfra, undistort; - short tc_flag, size_flag, quality, build_flag; - int sfra= SFRA, efra= EFRA; + short tc_flag, size_flag, quality; + int cfra, sfra= SFRA, efra= EFRA; int build_sizes[4], build_count= 0; + int build_undistort_sizes[4], build_undistort_count= 0; tc_flag= clip->proxy.build_tc_flag; size_flag= clip->proxy.build_size_flag; quality= clip->proxy.quality; - build_flag= clip->proxy.build_flag; - undistort= build_flag&MCLIP_PROXY_RENDER_UNDISTORT; + + build_count= proxy_bitflag_to_array(size_flag, build_sizes, 0); + build_undistort_count= proxy_bitflag_to_array(size_flag, build_undistort_sizes, 1); if(clip->source == MCLIP_SRC_MOVIE) { if(clip->anim) IMB_anim_index_rebuild(clip->anim, tc_flag, size_flag, quality, stop, do_update, progress); - if(!undistort) { + if(!build_undistort_count) { return; } else { @@ -867,20 +887,14 @@ } } - if(size_flag&IMB_PROXY_25) build_sizes[build_count++]= MCLIP_PROXY_RENDER_SIZE_25; - if(size_flag&IMB_PROXY_50) build_sizes[build_count++]= MCLIP_PROXY_RENDER_SIZE_50; - if(size_flag&IMB_PROXY_75) build_sizes[build_count++]= MCLIP_PROXY_RENDER_SIZE_75; - if(size_flag&IMB_PROXY_100) build_sizes[build_count++]= MCLIP_PROXY_RENDER_SIZE_100; - - if(undistort) + if(build_undistort_count) distortion= BKE_tracking_distortion_create(); for(cfra= sfra; cfra<=efra; cfra++) { if(clip->source != MCLIP_SRC_MOVIE) - BKE_movieclip_build_proxy_frame(clip, NULL, cfra, build_sizes, build_count, 0); + BKE_movieclip_build_proxy_frame(clip, pj->clip_flag, NULL, cfra, build_sizes, build_count, 0); - if(undistort) - BKE_movieclip_build_proxy_frame(clip, distortion, cfra, build_sizes, build_count, 1); + BKE_movieclip_build_proxy_frame(clip, pj->clip_flag, distortion, cfra, build_undistort_sizes, build_undistort_count, 1); if(*stop || G.afbreek) break; @@ -911,6 +925,7 @@ pj->scene= scene; pj->main= CTX_data_main(C); pj->clip= clip; + pj->clip_flag= clip->flag&MCLIP_TIMECODE_FLAGS; WM_jobs_customdata(steve, pj, proxy_freejob); WM_jobs_timer(steve, 0.2, NC_MOVIECLIP|ND_DISPLAY, 0); @@ -1000,5 +1015,5 @@ ot->description = "Add new marker and slide it with mouse until mouse button release"; WM_operatortype_macro_define(ot, "CLIP_OT_add_marker"); otmacro= WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); - RNA_boolean_set(otmacro->ptr, "release_confirm", 1); + RNA_boolean_set(otmacro->ptr, "release_confirm", TRUE); } diff -Nru blender-2.61/source/blender/editors/space_clip/clip_utils.c blender-2.62/source/blender/editors/space_clip/clip_utils.c --- blender-2.61/source/blender/editors/space_clip/clip_utils.c 2011-12-13 19:54:33.000000000 +0000 +++ blender-2.62/source/blender/editors/space_clip/clip_utils.c 2012-02-15 19:38:40.000000000 +0000 @@ -95,7 +95,7 @@ } /* value is a pixels per frame speed */ - val= (marker->pos[coord] - prevval) * ((i==0) ? (width) : (height)); + val= (marker->pos[coord] - prevval) * ((coord==0) ? (width) : (height)); val/= marker->framenr-prevfra; if(func) @@ -119,9 +119,10 @@ { MovieClip *clip= ED_space_clip(sc); MovieTracking *tracking= &clip->tracking; + ListBase *tracksbase= BKE_tracking_get_tracks(tracking); MovieTrackingTrack *track; - track= tracking->tracks.first; + track= tracksbase->first; while(track) { if(TRACK_VIEW_SELECTED(sc, track)) { clip_graph_tracking_values_iterate_track(sc, track, userdata, func, segment_start, segment_end); @@ -136,9 +137,10 @@ { MovieClip *clip= ED_space_clip(sc); MovieTracking *tracking= &clip->tracking; + ListBase *tracksbase= BKE_tracking_get_tracks(tracking); MovieTrackingTrack *track; - track= tracking->tracks.first; + track= tracksbase->first; while(track) { if(TRACK_VIEW_SELECTED(sc, track)) { int i; @@ -158,14 +160,15 @@ } } -void clip_delete_track(bContext *C, MovieClip *clip, MovieTrackingTrack *track) +void clip_delete_track(bContext *C, MovieClip *clip, ListBase *tracksbase, MovieTrackingTrack *track) { MovieTracking *tracking= &clip->tracking; MovieTrackingStabilization *stab= &tracking->stabilization; + MovieTrackingTrack *act_track= BKE_tracking_active_track(tracking); int has_bundle= 0, update_stab= 0; - if(track==tracking->act_track) + if(track==act_track) tracking->act_track= NULL; if(track==stab->rot_track) { @@ -179,7 +182,7 @@ has_bundle= 1; BKE_tracking_free_track(track); - BLI_freelinkN(&tracking->tracks, track); + BLI_freelinkN(tracksbase, track); WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip); @@ -194,10 +197,10 @@ WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, NULL); } -void clip_delete_marker(bContext *C, MovieClip *clip, MovieTrackingTrack *track, MovieTrackingMarker *marker) +void clip_delete_marker(bContext *C, MovieClip *clip, ListBase *tracksbase, MovieTrackingTrack *track, MovieTrackingMarker *marker) { if(track->markersnr==1) { - clip_delete_track(C, clip, track); + clip_delete_track(C, clip, tracksbase, track); } else { BKE_tracking_delete_marker(track, marker->framenr); diff -Nru blender-2.61/source/blender/editors/space_clip/space_clip.c blender-2.62/source/blender/editors/space_clip/space_clip.c --- blender-2.61/source/blender/editors/space_clip/space_clip.c 2011-12-13 19:54:33.000000000 +0000 +++ blender-2.62/source/blender/editors/space_clip/space_clip.c 2012-02-15 19:38:40.000000000 +0000 @@ -78,7 +78,7 @@ ar->flag|= RGN_FLAG_HIDDEN; ar->v2d.tot.xmin= 0.0f; - ar->v2d.tot.ymin= (float)scene->r.sfra - 10.0f; + ar->v2d.tot.ymin= -10.0f; ar->v2d.tot.xmax= (float)scene->r.efra; ar->v2d.tot.ymax= 10.0f; @@ -157,7 +157,7 @@ sc= MEM_callocN(sizeof(SpaceClip), "initclip"); sc->spacetype= SPACE_CLIP; - sc->flag= SC_SHOW_MARKER_PATTERN|SC_SHOW_TRACK_PATH|SC_SHOW_GPENCIL|SC_MANUAL_CALIBRATION|SC_SHOW_GRAPH_TRACKS|SC_SHOW_GRAPH_FRAMES; + sc->flag= SC_SHOW_MARKER_PATTERN|SC_SHOW_TRACK_PATH|SC_MANUAL_CALIBRATION|SC_SHOW_GRAPH_TRACKS|SC_SHOW_GRAPH_FRAMES; sc->zoom= 1.0f; sc->path_length= 20; sc->scopes.track_preview_height= 120; @@ -351,6 +351,7 @@ WM_operatortype_append(CLIP_OT_set_floor); WM_operatortype_append(CLIP_OT_set_axis); WM_operatortype_append(CLIP_OT_set_scale); + WM_operatortype_append(CLIP_OT_set_solution_scale); /* detect */ WM_operatortype_append(CLIP_OT_detect_features); @@ -372,6 +373,16 @@ WM_operatortype_append(CLIP_OT_graph_select); WM_operatortype_append(CLIP_OT_graph_delete_curve); WM_operatortype_append(CLIP_OT_graph_delete_knot); + WM_operatortype_append(CLIP_OT_graph_view_all); + WM_operatortype_append(CLIP_OT_graph_center_current_frame); + + /* object tracking */ + WM_operatortype_append(CLIP_OT_tracking_object_new); + WM_operatortype_append(CLIP_OT_tracking_object_remove); + + /* clipboard */ + WM_operatortype_append(CLIP_OT_copy_tracks); + WM_operatortype_append(CLIP_OT_paste_tracks); } static void clip_keymap(struct wmKeyConfig *keyconf) @@ -390,22 +401,31 @@ /* 2d tracking */ kmi= WM_keymap_add_item(keymap, "CLIP_OT_track_markers", LEFTARROWKEY, KM_PRESS, KM_ALT, 0); - RNA_boolean_set(kmi->ptr, "backwards", 1); + RNA_boolean_set(kmi->ptr, "backwards", TRUE); + RNA_boolean_set(kmi->ptr, "sequence", FALSE); WM_keymap_add_item(keymap, "CLIP_OT_track_markers", RIGHTARROWKEY, KM_PRESS, KM_ALT, 0); kmi= WM_keymap_add_item(keymap, "CLIP_OT_track_markers", TKEY, KM_PRESS, KM_CTRL, 0); - RNA_boolean_set(kmi->ptr, "sequence", 1); + RNA_boolean_set(kmi->ptr, "backwards", FALSE); + RNA_boolean_set(kmi->ptr, "sequence", TRUE); kmi= WM_keymap_add_item(keymap, "CLIP_OT_track_markers", TKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0); - RNA_boolean_set(kmi->ptr, "backwards", 1); - RNA_boolean_set(kmi->ptr, "sequence", 1); + RNA_boolean_set(kmi->ptr, "backwards", TRUE); + RNA_boolean_set(kmi->ptr, "sequence", TRUE); /* mode */ kmi= WM_keymap_add_item(keymap, "CLIP_OT_mode_set", TABKEY, KM_PRESS, 0, 0); RNA_enum_set(kmi->ptr, "mode", SC_MODE_RECONSTRUCTION); - RNA_boolean_set(kmi->ptr, "toggle", 1); + RNA_boolean_set(kmi->ptr, "toggle", TRUE); kmi= WM_keymap_add_item(keymap, "CLIP_OT_mode_set", TABKEY, KM_PRESS, KM_CTRL, 0); RNA_enum_set(kmi->ptr, "mode", SC_MODE_DISTORTION); - RNA_boolean_set(kmi->ptr, "toggle", 1); + RNA_boolean_set(kmi->ptr, "toggle", TRUE); + + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle_enum", ZKEY, KM_PRESS, 0, 0); + RNA_string_set(kmi->ptr, "data_path", "space_data.view"); + RNA_string_set(kmi->ptr, "value_1", "CLIP"); + RNA_string_set(kmi->ptr, "value_2", "GRAPH"); + + WM_keymap_add_item(keymap, "CLIP_OT_solve_camera", SKEY, KM_PRESS, KM_SHIFT, 0); /* ******** Hotkeys avalaible for main region only ******** */ @@ -452,10 +472,14 @@ WM_keymap_add_item(keymap, "CLIP_OT_change_frame", LEFTMOUSE, KM_PRESS, 0, 0); /* selection */ - WM_keymap_add_item(keymap, "CLIP_OT_select", SELECTMOUSE, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "CLIP_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", 1); - WM_keymap_add_item(keymap, "CLIP_OT_select_all", AKEY, KM_PRESS, 0, 0); - RNA_enum_set(WM_keymap_add_item(keymap, "CLIP_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0)->ptr, "action", SEL_INVERT); + kmi = WM_keymap_add_item(keymap, "CLIP_OT_select", SELECTMOUSE, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + kmi = WM_keymap_add_item(keymap, "CLIP_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "extend", TRUE); + kmi = WM_keymap_add_item(keymap, "CLIP_OT_select_all", AKEY, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE); + kmi = WM_keymap_add_item(keymap, "CLIP_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0); + RNA_enum_set(kmi->ptr, "action", SEL_INVERT); WM_keymap_add_item(keymap, "CLIP_OT_select_border", BKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "CLIP_OT_select_circle", CKEY, KM_PRESS, 0, 0); WM_keymap_add_menu(keymap, "CLIP_MT_select_grouped", GKEY, KM_PRESS, KM_SHIFT, 0); @@ -481,10 +505,11 @@ kmi= WM_keymap_add_item(keymap, "CLIP_OT_lock_tracks", LKEY, KM_PRESS, KM_ALT, 0); RNA_enum_set(kmi->ptr, "action", 1); /* unlock */ - WM_keymap_add_item(keymap, "CLIP_OT_hide_tracks", HKEY, KM_PRESS, 0, 0); + kmi= WM_keymap_add_item(keymap, "CLIP_OT_hide_tracks", HKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "unselected", FALSE); kmi= WM_keymap_add_item(keymap, "CLIP_OT_hide_tracks", HKEY, KM_PRESS, KM_SHIFT, 0); - RNA_boolean_set(kmi->ptr, "unselected", 1); + RNA_boolean_set(kmi->ptr, "unselected", TRUE); WM_keymap_add_item(keymap, "CLIP_OT_hide_tracks_clear", HKEY, KM_PRESS, KM_ALT, 0); @@ -505,6 +530,12 @@ kmi= WM_keymap_add_item(keymap, "WM_OT_context_toggle", LKEY, KM_PRESS, 0, 0); RNA_string_set(kmi->ptr, "data_path", "space_data.lock_selection"); + kmi= WM_keymap_add_item(keymap, "WM_OT_context_toggle", DKEY, KM_PRESS, KM_ALT, 0); + RNA_string_set(kmi->ptr, "data_path", "space_data.show_disabled"); + + kmi= WM_keymap_add_item(keymap, "WM_OT_context_toggle", SKEY, KM_PRESS, KM_ALT, 0); + RNA_string_set(kmi->ptr, "data_path", "space_data.show_marker_search"); + kmi= WM_keymap_add_item(keymap, "WM_OT_context_toggle", MKEY, KM_PRESS, 0, 0); RNA_string_set(kmi->ptr, "data_path", "space_data.use_mute_footage"); @@ -518,8 +549,10 @@ WM_keymap_add_item(keymap, "CLIP_OT_change_frame", ACTIONMOUSE, KM_PRESS, 0, 0); /* selection */ - WM_keymap_add_item(keymap, "CLIP_OT_graph_select", SELECTMOUSE, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "CLIP_OT_graph_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", 1); + kmi = WM_keymap_add_item(keymap, "CLIP_OT_graph_select", SELECTMOUSE, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + kmi = WM_keymap_add_item(keymap, "CLIP_OT_graph_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "extend", TRUE); /* delete */ WM_keymap_add_item(keymap, "CLIP_OT_graph_delete_curve", DELKEY, KM_PRESS, 0, 0); @@ -527,6 +560,15 @@ WM_keymap_add_item(keymap, "CLIP_OT_graph_delete_knot", DELKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "CLIP_OT_graph_delete_knot", XKEY, KM_PRESS, KM_SHIFT, 0); + + /* view */ + WM_keymap_add_item(keymap, "CLIP_OT_graph_view_all", HOMEKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "CLIP_OT_graph_center_current_frame", PADPERIOD, KM_PRESS, 0, 0); + + kmi= WM_keymap_add_item(keymap, "WM_OT_context_toggle", LKEY, KM_PRESS, 0, 0); + RNA_string_set(kmi->ptr, "data_path", "space_data.lock_time_cursor"); + + transform_keymap_for_space(keyconf, keymap, SPACE_CLIP); } const char *clip_context_dir[]= {"edit_movieclip", NULL}; @@ -551,6 +593,7 @@ { wmWindowManager *wm= CTX_wm_manager(C); wmWindow *window= CTX_wm_window(C); + Scene *scene = CTX_data_scene(C); SpaceClip *sc= (SpaceClip *)sa->spacedata.first; ARegion *ar_main= BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); ARegion *ar_preview= clip_has_preview_region(C, sa); @@ -568,10 +611,6 @@ ar_main->alignment= RGN_ALIGN_NONE; view_changed= 1; } - if (ar_preview && ar_preview->alignment != RGN_ALIGN_NONE) { - ar_preview->alignment= RGN_ALIGN_NONE; - view_changed= 1; - } break; case SC_VIEW_GRAPH: if (ar_preview && (ar_preview->flag & RGN_FLAG_HIDDEN)) { @@ -584,7 +623,7 @@ ar_main->alignment= RGN_ALIGN_NONE; view_changed= 1; } - if (ar_preview && ar_preview->alignment != RGN_ALIGN_TOP) { + if (ar_preview && !ELEM(ar_preview->alignment, RGN_ALIGN_TOP, RGN_ALIGN_BOTTOM)) { ar_preview->alignment= RGN_ALIGN_TOP; view_changed= 1; } @@ -596,7 +635,7 @@ ED_area_tag_redraw(sa); } - BKE_movieclip_user_set_frame(&sc->user, CTX_data_scene(C)->r.cfra); + BKE_movieclip_user_set_frame(&sc->user, scene->r.cfra); } /********************* main region ********************/ @@ -747,6 +786,9 @@ Scene *scene= CTX_data_scene(C); short unitx= V2D_UNIT_FRAMESCALE, unity= V2D_UNIT_VALUES; + if(sc->flag & SC_LOCK_TIMECURSOR) + ED_clip_graph_center_current_frame(scene, ar); + /* clear and setup matrix */ UI_ThemeClearColor(TH_BACK); glClear(GL_COLOR_BUFFER_BIT); diff -Nru blender-2.61/source/blender/editors/space_clip/tracking_ops.c blender-2.62/source/blender/editors/space_clip/tracking_ops.c --- blender-2.61/source/blender/editors/space_clip/tracking_ops.c 2011-12-13 19:54:33.000000000 +0000 +++ blender-2.62/source/blender/editors/space_clip/tracking_ops.c 2012-02-15 19:38:40.000000000 +0000 @@ -32,6 +32,7 @@ #include "MEM_guardedalloc.h" #include "DNA_camera_types.h" +#include "DNA_constraint_types.h" #include "DNA_gpencil_types.h" #include "DNA_movieclip_types.h" #include "DNA_object_types.h" /* SELECT */ @@ -45,6 +46,7 @@ #include "BKE_main.h" #include "BKE_context.h" +#include "BKE_constraint.h" #include "BKE_movieclip.h" #include "BKE_tracking.h" #include "BKE_global.h" @@ -90,41 +92,21 @@ return 0; } -static int space_clip_frame_camera_poll(bContext *C) -{ - Scene *scene= CTX_data_scene(C); - - if(space_clip_frame_poll(C)) { - return scene->camera != NULL; - } - - return 0; -} - -static int space_clip_camera_poll(bContext *C) -{ - SpaceClip *sc= CTX_wm_space_clip(C); - Scene *scene= CTX_data_scene(C); - - if(sc && sc->clip && scene->camera) - return 1; - - return 0; -} - /********************** add marker operator *********************/ static void add_marker(SpaceClip *sc, float x, float y) { MovieClip *clip= ED_space_clip(sc); + MovieTracking *tracking= &clip->tracking; + ListBase *tracksbase= BKE_tracking_get_tracks(tracking); MovieTrackingTrack *track; int width, height; ED_space_clip_size(sc, &width, &height); - track= BKE_tracking_add_track(&clip->tracking, x, y, sc->user.framenr, width, height); + track= BKE_tracking_add_track(tracking, tracksbase, x, y, sc->user.framenr, width, height); - BKE_tracking_select_track(&clip->tracking, track, TRACK_AREA_ALL, 0); + BKE_tracking_select_track(tracksbase, track, TRACK_AREA_ALL, 0); clip->tracking.act_track= track; } @@ -191,13 +173,14 @@ SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= ED_space_clip(sc); MovieTracking *tracking= &clip->tracking; - MovieTrackingTrack *track= tracking->tracks.first, *next; + ListBase *tracksbase= BKE_tracking_get_tracks(tracking); + MovieTrackingTrack *track= tracksbase->first, *next; while(track) { next= track->next; if(TRACK_VIEW_SELECTED(sc, track)) - clip_delete_track(C, clip, track); + clip_delete_track(C, clip, tracksbase, track); track= next; } @@ -230,7 +213,8 @@ { SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= ED_space_clip(sc); - MovieTrackingTrack *track= clip->tracking.tracks.first, *next; + ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking); + MovieTrackingTrack *track= tracksbase->first, *next; int framenr= sc->user.framenr; int has_selection= 0; @@ -243,7 +227,7 @@ if(marker) { has_selection|= track->markersnr>1; - clip_delete_marker(C, clip, track, marker); + clip_delete_marker(C, clip, tracksbase, track, marker); } } @@ -429,6 +413,7 @@ int width, height; float co[2]; void *customdata= NULL; + ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking); ED_space_clip_size(sc, &width, &height); @@ -437,7 +422,7 @@ ED_clip_mouse_pos(C, event, co); - track= clip->tracking.tracks.first; + track= tracksbase->first; while(track) { if(TRACK_VIEW_SELECTED(sc, track) && (track->flag&TRACK_LOCKED)==0) { MovieTrackingMarker *marker= BKE_tracking_get_marker(track, sc->user.framenr); @@ -721,12 +706,12 @@ return MIN4(d1, d2, d3, d4); } -static MovieTrackingTrack *find_nearest_track(SpaceClip *sc, MovieClip *clip, float co[2]) +static MovieTrackingTrack *find_nearest_track(SpaceClip *sc, ListBase *tracksbase, float co[2]) { MovieTrackingTrack *track= NULL, *cur; float mindist= 0.0f; - cur= clip->tracking.tracks.first; + cur= tracksbase->first; while(cur) { MovieTrackingMarker *marker= BKE_tracking_get_marker(cur, sc->user.framenr); @@ -764,10 +749,11 @@ SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= ED_space_clip(sc); MovieTracking *tracking= &clip->tracking; - MovieTrackingTrack *act_track= tracking->act_track; + ListBase *tracksbase= BKE_tracking_get_tracks(tracking); + MovieTrackingTrack *act_track= BKE_tracking_active_track(tracking); MovieTrackingTrack *track= NULL; /* selected marker */ - track= find_nearest_track(sc, clip, co); + track= find_nearest_track(sc, tracksbase, co); if(track) { int area= track_mouse_area(sc, co, track); @@ -784,7 +770,7 @@ if(area==TRACK_AREA_POINT) area= TRACK_AREA_ALL; - BKE_tracking_select_track(tracking, track, area, extend); + BKE_tracking_select_track(tracksbase, track, area, extend); clip->tracking.act_track= track; } } @@ -867,6 +853,7 @@ SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= ED_space_clip(sc); MovieTrackingTrack *track; + ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking); rcti rect; rctf rectf; int change= 0, mode, extend; @@ -884,7 +871,7 @@ extend= RNA_boolean_get(op->ptr, "extend"); /* do actual selection */ - track= clip->tracking.tracks.first; + track= tracksbase->first; while(track) { if((track->flag&TRACK_HIDDEN)==0) { MovieTrackingMarker *marker= BKE_tracking_get_marker(track, sc->user.framenr); @@ -952,6 +939,7 @@ MovieClip *clip= ED_space_clip(sc); ARegion *ar= CTX_wm_region(C); MovieTrackingTrack *track; + ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking); int x, y, radius, width, height, mode, change= 0; float zoomx, zoomy, offset[2], ellipse[2]; @@ -972,7 +960,7 @@ ED_clip_point_stable_pos(C, x, y, &offset[0], &offset[1]); /* do selection */ - track= clip->tracking.tracks.first; + track= tracksbase->first; while(track) { if((track->flag&TRACK_HIDDEN)==0) { MovieTrackingMarker *marker= BKE_tracking_get_marker(track, sc->user.framenr); @@ -1026,29 +1014,35 @@ SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= ED_space_clip(sc); MovieTrackingTrack *track= NULL; /* selected track */ + MovieTrackingMarker *marker; + ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking); int action= RNA_enum_get(op->ptr, "action"); int framenr= sc->user.framenr; int has_selection= 0; if(action == SEL_TOGGLE){ action= SEL_SELECT; - track= clip->tracking.tracks.first; + track= tracksbase->first; while(track) { if(TRACK_VIEW_SELECTED(sc, track)) { - action= SEL_DESELECT; - break; + marker= BKE_tracking_get_marker(track, framenr); + + if(MARKER_VISIBLE(sc, marker)) { + action= SEL_DESELECT; + break; + } } track= track->next; } } - track= clip->tracking.tracks.first; + track= tracksbase->first; while(track) { if((track->flag&TRACK_HIDDEN)==0) { - MovieTrackingMarker *marker= BKE_tracking_get_marker(track, framenr); + marker= BKE_tracking_get_marker(track, framenr); - if(marker && MARKER_VISIBLE(sc, marker)) { + if(MARKER_VISIBLE(sc, marker)) { switch (action) { case SEL_SELECT: track->flag|= SELECT; @@ -1108,9 +1102,11 @@ MovieClip *clip= ED_space_clip(sc); MovieTrackingTrack *track; MovieTrackingMarker *marker; + MovieTracking *tracking= &clip->tracking; + ListBase *tracksbase= BKE_tracking_get_tracks(tracking); int group= RNA_enum_get(op->ptr, "group"); - track= clip->tracking.tracks.first; + track= tracksbase->first; while(track) { int ok= 0; @@ -1132,11 +1128,13 @@ ok= marker->flag&MARKER_DISABLED; } else if(group==5) { /* color */ - if(clip->tracking.act_track) { - ok= (track->flag&TRACK_CUSTOMCOLOR) == (clip->tracking.act_track->flag&TRACK_CUSTOMCOLOR); + MovieTrackingTrack *act_track= BKE_tracking_active_track(tracking); + + if(act_track) { + ok= (track->flag&TRACK_CUSTOMCOLOR) == (act_track->flag&TRACK_CUSTOMCOLOR); if(ok && track->flag&TRACK_CUSTOMCOLOR) - ok= equals_v3v3(track->color, clip->tracking.act_track->color); + ok= equals_v3v3(track->color, act_track->color); } } else if(group==6) { /* failed */ @@ -1208,13 +1206,14 @@ static int track_count_markers(SpaceClip *sc, MovieClip *clip) { int tot= 0; + ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking); MovieTrackingTrack *track; int framenr= sc->user.framenr; - track= clip->tracking.tracks.first; + track= tracksbase->first; while(track) { if(TRACK_VIEW_SELECTED(sc, track) && (track->flag&TRACK_LOCKED)==0) { - MovieTrackingMarker *marker= BKE_tracking_exact_marker(track, framenr); + MovieTrackingMarker *marker= BKE_tracking_get_marker(track, framenr); if (!marker || (marker->flag&MARKER_DISABLED) == 0) tot++; @@ -1226,20 +1225,39 @@ return tot; } +static void clear_invisible_track_selection(SpaceClip *sc, MovieClip *clip) +{ + ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking); + int hidden = 0; + + if ((sc->flag&SC_SHOW_MARKER_PATTERN)==0) + hidden |= TRACK_AREA_PAT; + + if ((sc->flag&SC_SHOW_MARKER_SEARCH)==0) + hidden |= TRACK_AREA_SEARCH; + + if (hidden) { + MovieTrackingTrack *track = tracksbase->first; + + while(track) { + BKE_tracking_track_flag(track, hidden, SELECT, 1); + + track = track->next; + } + } +} + static void track_init_markers(SpaceClip *sc, MovieClip *clip, int *frames_limit_r) { + ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking); MovieTrackingTrack *track; - int framenr= sc->user.framenr, hidden= 0; + int framenr= sc->user.framenr; int frames_limit= 0; - if((sc->flag&SC_SHOW_MARKER_PATTERN)==0) hidden|= TRACK_AREA_PAT; - if((sc->flag&SC_SHOW_MARKER_SEARCH)==0) hidden|= TRACK_AREA_SEARCH; + clear_invisible_track_selection(sc, clip); - track= clip->tracking.tracks.first; + track= tracksbase->first; while(track) { - if(hidden) - BKE_tracking_track_flag(track, hidden, SELECT, 1); - if(TRACK_SELECTED(track)) { if((track->flag&TRACK_HIDDEN)==0 && (track->flag&TRACK_LOCKED)==0) { BKE_tracking_ensure_marker(track, framenr); @@ -1302,7 +1320,7 @@ else if(settings->speed==TRACKING_SPEED_DOUBLE) tmj->delay/= 2; } - tmj->context= BKE_tracking_context_new(clip, &sc->user, backwards, 1, 1); + tmj->context= BKE_tracking_context_new(clip, &sc->user, backwards, 1); clip->tracking_context= tmj->context; @@ -1413,7 +1431,7 @@ return OPERATOR_CANCELLED; /* do not disable tracks due to threshold when tracking frame-by-frame */ - context= BKE_tracking_context_new(clip, &sc->user, backwards, sequence, sequence); + context= BKE_tracking_context_new(clip, &sc->user, backwards, sequence); while(framenr != efra) { if(!BKE_tracking_next(context)) @@ -1448,6 +1466,11 @@ int backwards= RNA_boolean_get(op->ptr, "backwards"); int sequence= RNA_boolean_get(op->ptr, "sequence"); + if(WM_jobs_test(CTX_wm_manager(C), CTX_wm_area(C))) { + /* only one tracking is allowed at a time */ + return OPERATOR_CANCELLED; + } + if(clip->tracking_context) return OPERATOR_CANCELLED; @@ -1546,9 +1569,10 @@ Scene *scene= CTX_data_scene(C); MovieTracking *tracking= &clip->tracking; MovieTrackingSettings *settings= &clip->tracking.settings; + MovieTrackingObject *object= BKE_tracking_active_object(tracking); int width, height; - if(!BKE_tracking_can_reconstruct(tracking, error_msg, max_error)) + if(!BKE_tracking_can_reconstruct(tracking, object, error_msg, max_error)) return 0; /* could fail if footage uses images with different sizes */ @@ -1559,7 +1583,7 @@ scj->reports= op->reports; scj->user= sc->user; - scj->context= BKE_tracking_reconstruction_context_new(tracking, + scj->context= BKE_tracking_reconstruction_context_new(tracking, object, settings->keyframe1, settings->keyframe2, width, height); tracking->stats= MEM_callocN(sizeof(MovieTrackingStats), "solve camera stats"); @@ -1612,9 +1636,6 @@ id_us_plus(&clip->id); /* set blender camera focal length so result would look fine there */ - if(!scene->camera) - scene->camera= scene_find_camera(scene); - if(scene->camera) { Camera *camera= (Camera*)scene->camera->data; int width, height; @@ -1670,9 +1691,15 @@ SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= ED_space_clip(sc); MovieTracking *tracking= &clip->tracking; + MovieTrackingReconstruction *reconstruction= BKE_tracking_get_reconstruction(tracking); wmJob *steve; char error_msg[256]= "\0"; + if(WM_jobs_test(CTX_wm_manager(C), CTX_wm_area(C))) { + /* only one solve is allowed at a time */ + return OPERATOR_CANCELLED; + } + scj= MEM_callocN(sizeof(SolveCameraJob), "SolveCameraJob data"); if(!solve_camera_initjob(C, scj, op, error_msg, sizeof(error_msg))) { if(error_msg[0]) @@ -1686,7 +1713,7 @@ BLI_strncpy(tracking->stats->message, "Solving camera | Preparing solve", sizeof(tracking->stats->message)); /* hide reconstruction statistics from previous solve */ - clip->tracking.reconstruction.flag&= ~TRACKING_RECONSTRUCTED; + reconstruction->flag&= ~TRACKING_RECONSTRUCTED; WM_event_add_notifier(C, NC_MOVIECLIP|NA_EVALUATED, clip); /* setup job */ @@ -1746,7 +1773,9 @@ SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= ED_space_clip(sc); MovieTracking *tracking= &clip->tracking; - MovieTrackingTrack *track= tracking->tracks.first; + ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking); + MovieTrackingReconstruction *reconstruction= BKE_tracking_get_reconstruction(tracking); + MovieTrackingTrack *track= tracksbase->first; while(track) { track->flag&= ~TRACK_HAS_BUNDLE; @@ -1754,13 +1783,13 @@ track= track->next; } - if(tracking->reconstruction.cameras) - MEM_freeN(tracking->reconstruction.cameras); + if(reconstruction->cameras) + MEM_freeN(reconstruction->cameras); - tracking->reconstruction.cameras= NULL; - tracking->reconstruction.camnr= 0; + reconstruction->cameras= NULL; + reconstruction->camnr= 0; - tracking->reconstruction.flag&= ~TRACKING_RECONSTRUCTED; + reconstruction->flag&= ~TRACKING_RECONSTRUCTED; DAG_id_tag_update(&clip->id, 0); @@ -1792,9 +1821,10 @@ SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= ED_space_clip(sc); MovieTrackingTrack *track; + ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking); int action= RNA_enum_get(op->ptr, "action"); - track= clip->tracking.tracks.first; + track= tracksbase->first; while(track) { if(TRACK_VIEW_SELECTED(sc, track)) BKE_tracking_clear_path(track, sc->user.framenr, action); @@ -1839,7 +1869,8 @@ SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= ED_space_clip(sc); MovieTracking *tracking= &clip->tracking; - MovieTrackingTrack *track= tracking->tracks.first; + ListBase *tracksbase= BKE_tracking_get_tracks(tracking); + MovieTrackingTrack *track= tracksbase->first; int action= RNA_enum_get(op->ptr, "action"); while(track) { @@ -1888,14 +1919,80 @@ /********************** set origin operator *********************/ +static Object *get_camera_with_movieclip(Scene *scene, MovieClip *clip) +{ + Object *camera= scene->camera; + Base *base; + + if(camera && object_get_movieclip(scene, camera, 0)==clip) + return camera; + + base= scene->base.first; + while(base) { + if(base->object->type == OB_CAMERA) { + if(object_get_movieclip(scene, base->object, 0)==clip) { + camera= base->object; + break; + } + } + + base= base->next; + } + + return camera; +} + +static Object *get_orientation_object(bContext *C) +{ + Scene *scene= CTX_data_scene(C); + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTracking *tracking= &clip->tracking; + MovieTrackingObject *tracking_object= BKE_tracking_active_object(tracking); + Object *object= NULL; + + if(tracking_object->flag&TRACKING_OBJECT_CAMERA) { + object= get_camera_with_movieclip(scene, clip); + } + else { + object= OBACT; + } + + if(object && object->parent) + object= object->parent; + + return object; +} + +static int set_orientation_poll(bContext *C) +{ + if(space_clip_frame_poll(C)) { + Scene *scene= CTX_data_scene(C); + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTracking *tracking= &clip->tracking; + MovieTrackingObject *tracking_object= BKE_tracking_active_object(tracking); + + if(tracking_object->flag&TRACKING_OBJECT_CAMERA) { + return 1; + } + else { + return OBACT != NULL; + } + } + + return 0; +} + static int count_selected_bundles(bContext *C) { SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= ED_space_clip(sc); + ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking); MovieTrackingTrack *track; int tot= 0; - track= clip->tracking.tracks.first; + track= tracksbase->first; while(track) { if(TRACK_VIEW_SELECTED(sc, track) && (track->flag&TRACK_HAS_BUNDLE)) tot++; @@ -1906,38 +2003,115 @@ return tot; } +static void object_solver_inverted_matrix(Scene *scene, Object *ob, float invmat[4][4]) +{ + bConstraint *con; + int found= 0; + + for (con= ob->constraints.first; con; con=con->next) { + bConstraintTypeInfo *cti= constraint_get_typeinfo(con); + + if(!cti) + continue; + + if(cti->type==CONSTRAINT_TYPE_OBJECTSOLVER) { + bObjectSolverConstraint *data= (bObjectSolverConstraint *)con->data; + + if(!found) { + Object *cam= data->camera ? data->camera : scene->camera; + + where_is_object_mat(scene, cam, invmat); + } + + mult_m4_m4m4(invmat, invmat, data->invmat); + + found= 1; + } + } + + if(found) + invert_m4(invmat); + else + unit_m4(invmat); +} + +static Object *object_solver_camera(Scene *scene, Object *ob) +{ + bConstraint *con; + + for (con= ob->constraints.first; con; con=con->next) { + bConstraintTypeInfo *cti= constraint_get_typeinfo(con); + + if(!cti) + continue; + + if(cti->type==CONSTRAINT_TYPE_OBJECTSOLVER) { + bObjectSolverConstraint *data= (bObjectSolverConstraint *)con->data; + + return data->camera ? data->camera : scene->camera; + } + } + + return NULL; +} + static int set_origin_exec(bContext *C, wmOperator *op) { SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= ED_space_clip(sc); + MovieTracking *tracking= &clip->tracking; MovieTrackingTrack *track; + MovieTrackingObject *tracking_object; Scene *scene= CTX_data_scene(C); - Object *parent= scene->camera; - float mat[4][4], vec[3]; + Object *object; + Object *camera= get_camera_with_movieclip(scene, clip); + ListBase *tracksbase; + float mat[4][4], vec[3], median[3]; + int selected_count= count_selected_bundles(C); + + if(selected_count==0) { + BKE_report(op->reports, RPT_ERROR, "At least one track with bundle should be selected to define origin position"); + + return OPERATOR_CANCELLED; + } + + object= get_orientation_object(C); + if(!object) { + BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on"); - if(count_selected_bundles(C)!=1) { - BKE_report(op->reports, RPT_ERROR, "Track with bundle should be selected to define origin position"); return OPERATOR_CANCELLED; } - if(scene->camera->parent) - parent= scene->camera->parent; + tracking_object= BKE_tracking_active_object(tracking); - track= clip->tracking.tracks.first; + tracksbase= BKE_tracking_object_tracks(tracking, tracking_object); + + track= tracksbase->first; + zero_v3(median); while(track) { - if(TRACK_VIEW_SELECTED(sc, track)) - break; + if(TRACK_VIEW_SELECTED(sc, track) && (track->flag&TRACK_HAS_BUNDLE)) { + add_v3_v3(median, track->bundle_pos); + } track= track->next; } + mul_v3_fl(median, 1.0f/selected_count); - BKE_get_tracking_mat(scene, NULL, mat); - mul_v3_m4v3(vec, mat, track->bundle_pos); + BKE_get_tracking_mat(scene, camera, mat); - sub_v3_v3(parent->loc, vec); + mul_v3_m4v3(vec, mat, median); + + if(tracking_object->flag&TRACKING_OBJECT_CAMERA) { + sub_v3_v3(object->loc, vec); + } + else { + object_solver_inverted_matrix(scene, object, mat); + mul_v3_m4v3(vec, mat, vec); + copy_v3_v3(object->loc, vec); + } DAG_id_tag_update(&clip->id, 0); - DAG_id_tag_update(&parent->id, OB_RECALC_OB); + DAG_id_tag_update(&object->id, OB_RECALC_OB); WM_event_add_notifier(C, NC_MOVIECLIP|NA_EVALUATED, clip); WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); @@ -1954,20 +2128,42 @@ /* api callbacks */ ot->exec= set_origin_exec; - ot->poll= space_clip_frame_camera_poll; + ot->poll= set_orientation_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_boolean(ot->srna, "use_median", 0, "Use Median", "Set origin to median point of selected bundles"); } /********************** set floor operator *********************/ -static void set_axis(Scene *scene, Object *ob, MovieTrackingTrack *track, char axis) +static void set_axis(Scene *scene, Object *ob, MovieClip *clip, MovieTrackingObject *tracking_object, + MovieTrackingTrack *track, char axis) { - float mat[4][4], vec[3], obmat[4][4]; + Object *camera= get_camera_with_movieclip(scene, clip); + int is_camera= tracking_object->flag&TRACKING_OBJECT_CAMERA; + int flip= 0; + float mat[4][4], vec[3], obmat[4][4], dvec[3]; + + object_to_mat4(ob, obmat); - BKE_get_tracking_mat(scene, NULL, mat); + BKE_get_tracking_mat(scene, camera, mat); mul_v3_m4v3(vec, mat, track->bundle_pos); + copy_v3_v3(dvec, vec); + + if(!is_camera) { + float imat[4][4]; + + object_solver_inverted_matrix(scene, ob, imat); + mul_v3_m4v3(vec, imat, vec); + + invert_m4_m4(imat, obmat); + mul_v3_m4v3(dvec, imat, vec); + + sub_v3_v3(vec, obmat[3]); + } if(len_v2(vec) < 1e-3f) return; @@ -1975,26 +2171,48 @@ unit_m4(mat); if(axis=='X') { - if(fabsf(vec[1])<1e-3f) { + if(fabsf(dvec[1])<1e-3f) { + flip= 1; + mat[0][0]= -1.0f; mat[0][1]= 0.0f; mat[0][2]= 0.0f; mat[1][0]= 0.0f; mat[1][1]= -1.0f; mat[1][2]= 0.0f; mat[2][0]= 0.0f; mat[2][1]= 0.0f; mat[2][2]= 1.0f; } else { copy_v3_v3(mat[0], vec); - mat[0][2]= 0.0f; - mat[2][0]= 0.0f; mat[2][1]= 0.0f; mat[2][2]= 1.0f; - cross_v3_v3v3(mat[1], mat[2], mat[0]); + + if(is_camera || fabsf(vec[2])<1e-3f) { + mat[0][2]= 0.0f; + mat[2][0]= 0.0f; mat[2][1]= 0.0f; mat[2][2]= 1.0f; + cross_v3_v3v3(mat[1], mat[2], mat[0]); + } + else { + vec[2]= 0.0f; + + cross_v3_v3v3(mat[1], mat[0], vec); + cross_v3_v3v3(mat[2], mat[0], mat[1]); + } } } else { - if(fabsf(vec[0])<1e-3f) { + if(fabsf(dvec[0])<1e-3f) { + flip= 1; + mat[0][0]= -1.0f; mat[0][1]= 0.0f; mat[0][2]= 0.0f; mat[1][0]= 0.0f; mat[1][1]= -1.0f; mat[1][2]= 0.0f; mat[2][0]= 0.0f; mat[2][1]= 0.0f; mat[2][2]= 1.0f; } else { copy_v3_v3(mat[1], vec); - mat[1][2]= 0.0f; - mat[2][0]= 0.0f; mat[2][1]= 0.0f; mat[2][2]= 1.0f; - cross_v3_v3v3(mat[0], mat[1], mat[2]); + + if(is_camera || fabsf(vec[2])<1e-3f) { + mat[1][2]= 0.0f; + mat[2][0]= 0.0f; mat[2][1]= 0.0f; mat[2][2]= 1.0f; + cross_v3_v3v3(mat[0], mat[1], mat[2]); + } + else { + vec[2]= 0.0f; + + cross_v3_v3v3(mat[0], vec, mat[1]); + cross_v3_v3v3(mat[2], mat[0], mat[1]); + } } } @@ -2002,10 +2220,30 @@ normalize_v3(mat[1]); normalize_v3(mat[2]); - invert_m4(mat); + if(is_camera) { + invert_m4(mat); + + mult_m4_m4m4(mat, mat, obmat); + } + else { + if(!flip) { + float lmat[4][4], ilmat[4][4], rmat[3][3]; + + object_rot_to_mat3(ob, rmat); + invert_m3(rmat); + mul_m4_m4m3(mat, mat, rmat); + + unit_m4(lmat); + copy_v3_v3(lmat[3], obmat[3]); + invert_m4_m4(ilmat, lmat); + + mul_serie_m4(mat, lmat, mat, ilmat, obmat, NULL, NULL, NULL, NULL); + } + else { + mult_m4_m4m4(mat, obmat, mat); + } + } - object_to_mat4(ob, obmat); - mul_m4_m4m4(mat, obmat, mat); object_apply_mat4(ob, mat, 0, 0); } @@ -2014,9 +2252,12 @@ SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= ED_space_clip(sc); Scene *scene= CTX_data_scene(C); - MovieTrackingTrack *track, *axis_track= NULL; - Object *camera= scene->camera; - Object *parent= camera; + MovieTracking *tracking= &clip->tracking; + MovieTrackingObject *tracking_object; + MovieTrackingTrack *track, *axis_track= NULL, *act_track; + ListBase *tracksbase; + Object *object; + Object *camera= get_camera_with_movieclip(scene, clip); int tot= 0; float vec[3][3], mat[4][4], obmat[4][4], newmat[4][4], orig[3]= {0.0f, 0.0f, 0.0f}; float rot[4][4]={{0.0f, 0.0f, -1.0f, 0.0f}, @@ -2026,21 +2267,30 @@ if(count_selected_bundles(C)!=3) { BKE_report(op->reports, RPT_ERROR, "Three tracks with bundles are needed to orient the floor"); + return OPERATOR_CANCELLED; } - if(scene->camera->parent) - parent= scene->camera->parent; + tracking_object= BKE_tracking_active_object(tracking); + tracksbase= BKE_tracking_object_tracks(tracking, tracking_object); + act_track= BKE_tracking_active_track(tracking); + + object= get_orientation_object(C); + if(!object) { + BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on"); + + return OPERATOR_CANCELLED; + } - BKE_get_tracking_mat(scene, NULL, mat); + BKE_get_tracking_mat(scene, camera, mat); /* get 3 bundles to use as reference */ - track= clip->tracking.tracks.first; + track= tracksbase->first; while(track && tot<3) { if(track->flag&TRACK_HAS_BUNDLE && TRACK_VIEW_SELECTED(sc, track)) { mul_v3_m4v3(vec[tot], mat, track->bundle_pos); - if(tot==0 || track==clip->tracking.act_track) + if(tot==0 || track==act_track) copy_v3_v3(orig, vec[tot]); else axis_track= track; @@ -2070,25 +2320,30 @@ mat[3][1]= orig[1]; mat[3][2]= orig[2]; - invert_m4(mat); + if(tracking_object->flag&TRACKING_OBJECT_CAMERA) { + invert_m4(mat); - object_to_mat4(parent, obmat); - mul_m4_m4m4(mat, obmat, mat); - mul_m4_m4m4(newmat, mat, rot); - object_apply_mat4(parent, newmat, 0, 0); - - /* make camera have positive z-coordinate */ - if(parent->loc[2]<0) { - invert_m4(rot); - mul_m4_m4m4(newmat, mat, rot); - object_apply_mat4(parent, newmat, 0, 0); + object_to_mat4(object, obmat); + mult_m4_m4m4(mat, mat, obmat); + mult_m4_m4m4(newmat, rot, mat); + object_apply_mat4(object, newmat, 0, 0); + + /* make camera have positive z-coordinate */ + if(object->loc[2]<0) { + invert_m4(rot); + mult_m4_m4m4(newmat, rot, mat); + object_apply_mat4(object, newmat, 0, 0); + } + } + else { + object_apply_mat4(object, mat, 0, 0); } - where_is_object(scene, parent); - set_axis(scene, parent, axis_track, 'X'); + where_is_object(scene, object); + set_axis(scene, object, clip, tracking_object, axis_track, 'X'); DAG_id_tag_update(&clip->id, 0); - DAG_id_tag_update(&parent->id, OB_RECALC_OB); + DAG_id_tag_update(&object->id, OB_RECALC_OB); WM_event_add_notifier(C, NC_MOVIECLIP|NA_EVALUATED, clip); WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); @@ -2105,7 +2360,7 @@ /* api callbacks */ ot->exec= set_floor_exec; - ot->poll= space_clip_camera_poll; + ot->poll= set_orientation_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -2117,9 +2372,12 @@ { SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= ED_space_clip(sc); + MovieTracking *tracking= &clip->tracking; + MovieTrackingObject *tracking_object= BKE_tracking_active_object(tracking); MovieTrackingTrack *track; Scene *scene= CTX_data_scene(C); - Object *parent= scene->camera; + Object *object; + ListBase *tracksbase; int axis= RNA_enum_get(op->ptr, "axis"); if(count_selected_bundles(C)!=1) { @@ -2128,10 +2386,16 @@ return OPERATOR_CANCELLED; } - if(scene->camera->parent) - parent= scene->camera->parent; + object= get_orientation_object(C); + if(!object) { + BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on"); - track= clip->tracking.tracks.first; + return OPERATOR_CANCELLED; + } + + tracksbase= BKE_tracking_object_tracks(tracking, tracking_object); + + track=tracksbase->first; while(track) { if(TRACK_VIEW_SELECTED(sc, track)) break; @@ -2139,10 +2403,10 @@ track= track->next; } - set_axis(scene, parent, track, axis==0?'X':'Y'); + set_axis(scene, object, clip, tracking_object, track, axis==0?'X':'Y'); DAG_id_tag_update(&clip->id, 0); - DAG_id_tag_update(&parent->id, OB_RECALC_OB); + DAG_id_tag_update(&object->id, OB_RECALC_OB); WM_event_add_notifier(C, NC_MOVIECLIP|NA_EVALUATED, clip); WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); @@ -2165,7 +2429,7 @@ /* api callbacks */ ot->exec= set_axis_exec; - ot->poll= space_clip_frame_camera_poll; + ot->poll= set_orientation_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -2176,29 +2440,37 @@ /********************** set scale operator *********************/ -static int set_scale_exec(bContext *C, wmOperator *op) +static int do_set_scale(bContext *C, wmOperator *op, int scale_solution) { SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= ED_space_clip(sc); + MovieTracking *tracking= &clip->tracking; + MovieTrackingObject *tracking_object= BKE_tracking_active_object(tracking); MovieTrackingTrack *track; Scene *scene= CTX_data_scene(C); - Object *parent= scene->camera; + Object *object= NULL; + Object *camera= get_camera_with_movieclip(scene, clip); + ListBase *tracksbase= BKE_tracking_get_tracks(tracking); int tot= 0; float vec[2][3], mat[4][4], scale; float dist= RNA_float_get(op->ptr, "distance"); if(count_selected_bundles(C)!=2) { - BKE_report(op->reports, RPT_ERROR, "Two tracks with bundles should be selected to scale scene"); + BKE_report(op->reports, RPT_ERROR, "Two tracks with bundles should be selected to set scale"); return OPERATOR_CANCELLED; } - if(scene->camera->parent) - parent= scene->camera->parent; + object= get_orientation_object(C); + if(!object) { + BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on"); - BKE_get_tracking_mat(scene, NULL, mat); + return OPERATOR_CANCELLED; + } + + BKE_get_tracking_mat(scene, camera, mat); - track= clip->tracking.tracks.first; + track= tracksbase->first; while(track) { if(TRACK_VIEW_SELECTED(sc, track)) { mul_v3_m4v3(vec[tot], mat, track->bundle_pos); @@ -2213,11 +2485,29 @@ if(len_v3(vec[0])>1e-5f) { scale= dist / len_v3(vec[0]); - mul_v3_fl(parent->size, scale); - mul_v3_fl(parent->loc, scale); + if(tracking_object->flag&TRACKING_OBJECT_CAMERA) { + mul_v3_fl(object->size, scale); + mul_v3_fl(object->loc, scale); + } + else if(!scale_solution){ + Object *solver_camera= object_solver_camera(scene, object); + + object->size[0]= object->size[1]= object->size[2]= 1.0f/scale; + + if(solver_camera) { + object->size[0]/= solver_camera->size[0]; + object->size[1]/= solver_camera->size[1]; + object->size[2]/= solver_camera->size[2]; + } + } + else { + tracking_object->scale= scale; + } DAG_id_tag_update(&clip->id, 0); - DAG_id_tag_update(&parent->id, OB_RECALC_OB); + + if(object) + DAG_id_tag_update(&object->id, OB_RECALC_OB); WM_event_add_notifier(C, NC_MOVIECLIP|NA_EVALUATED, clip); WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); @@ -2226,13 +2516,17 @@ return OPERATOR_FINISHED; } +static int set_scale_exec(bContext *C, wmOperator *op) +{ + return do_set_scale(C, op, 0); +} + static int set_scale_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= ED_space_clip(sc); - float dist= RNA_float_get(op->ptr, "distance"); - if(dist==0.0f) + if(!RNA_struct_property_is_set(op->ptr, "distance")) RNA_float_set(op->ptr, "distance", clip->tracking.settings.dist); return set_scale_exec(C, op); @@ -2248,7 +2542,59 @@ /* api callbacks */ ot->exec= set_scale_exec; ot->invoke= set_scale_invoke; - ot->poll= space_clip_frame_camera_poll; + ot->poll= set_orientation_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_float(ot->srna, "distance", 0.0f, -FLT_MAX, FLT_MAX, + "Distance", "Distance between selected tracks", -100.0f, 100.0f); +} + +/********************** set solution scale operator *********************/ + +static int set_solution_scale_poll(bContext *C) +{ + if(space_clip_frame_poll(C)) { + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTracking *tracking= &clip->tracking; + MovieTrackingObject *tracking_object= BKE_tracking_active_object(tracking); + + return (tracking_object->flag&TRACKING_OBJECT_CAMERA) == 0; + } + + return 0; +} + +static int set_solution_scale_exec(bContext *C, wmOperator *op) +{ + return do_set_scale(C, op, 1); +} + +static int set_solution_scale_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + + if(!RNA_struct_property_is_set(op->ptr, "distance")) + RNA_float_set(op->ptr, "distance", clip->tracking.settings.object_distance); + + return set_solution_scale_exec(C, op); +} + +void CLIP_OT_set_solution_scale(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Set Solution Scale"; + ot->description= "Set object solution scale using distance between two selected tracks"; + ot->idname= "CLIP_OT_set_solution_scale"; + + /* api callbacks */ + ot->exec= set_solution_scale_exec; + ot->invoke= set_solution_scale_invoke; + ot->poll= set_solution_scale_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -2301,11 +2647,14 @@ SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= ED_space_clip(sc); MovieTrackingTrack *track; + MovieTracking *tracking= &clip->tracking; + ListBase *tracksbase= BKE_tracking_get_tracks(tracking); + MovieTrackingTrack *act_track= BKE_tracking_active_track(tracking); int unselected; unselected= RNA_boolean_get(op->ptr, "unselected"); - track= clip->tracking.tracks.first; + track= tracksbase->first; while(track) { if(unselected==0 && TRACK_VIEW_SELECTED(sc, track)) { track->flag|= TRACK_HIDDEN; @@ -2316,7 +2665,7 @@ track= track->next; } - if(clip->tracking.act_track && clip->tracking.act_track->flag&TRACK_HIDDEN) + if(act_track && act_track->flag&TRACK_HIDDEN) clip->tracking.act_track= NULL; if(unselected==0) { @@ -2353,9 +2702,10 @@ { SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= ED_space_clip(sc); + ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking); MovieTrackingTrack *track; - track= clip->tracking.tracks.first; + track= tracksbase->first; while(track) { track->flag&= ~TRACK_HIDDEN; @@ -2406,8 +2756,11 @@ { SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= ED_space_clip(sc); - ImBuf *ibuf= BKE_movieclip_get_ibuf_flag(clip, &sc->user, 0); - MovieTrackingTrack *track= clip->tracking.tracks.first; + int clip_flag= clip->flag&MCLIP_TIMECODE_FLAGS; + ImBuf *ibuf= BKE_movieclip_get_ibuf_flag(clip, &sc->user, clip_flag, MOVIECLIP_CACHE_SKIP); + MovieTracking *tracking= &clip->tracking; + ListBase *tracksbase= BKE_tracking_get_tracks(tracking); + MovieTrackingTrack *track= tracksbase->first; int placement= RNA_enum_get(op->ptr, "placement"); int margin= RNA_int_get(op->ptr, "margin"); int min_trackability= RNA_int_get(op->ptr, "min_trackability"); @@ -2429,7 +2782,8 @@ track= track->next; } - BKE_tracking_detect_fast(&clip->tracking, ibuf, sc->user.framenr, margin, min_trackability, min_distance, layer, place_outside_layer); + BKE_tracking_detect_fast(tracking, tracksbase, ibuf, sc->user.framenr, margin, + min_trackability, min_distance, layer, place_outside_layer); IMB_freeImBuf(ibuf); @@ -2478,7 +2832,7 @@ int delta; if(pos<=1) { /* jump to path */ - track= clip->tracking.act_track; + track= BKE_tracking_active_track(&clip->tracking); if(!track) return OPERATOR_CANCELLED; @@ -2498,13 +2852,16 @@ if(clip->tracking.reconstruction.flag&TRACKING_RECONSTRUCTED) { int a= sc->user.framenr; MovieTracking *tracking= &clip->tracking; + MovieTrackingObject *object= BKE_tracking_active_object(tracking); delta= pos == 3 ? 1 : -1; a+= delta; while(a+delta >= SFRA && a+delta <= EFRA) { - MovieReconstructedCamera *cam= BKE_tracking_get_reconstructed_camera(tracking, a); + MovieReconstructedCamera *cam; + + cam= BKE_tracking_get_reconstructed_camera(tracking, object, a); if(!cam) { sc->user.framenr= a; @@ -2561,16 +2918,18 @@ { SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= ED_space_clip(sc); + MovieTracking *tracking= &clip->tracking; + ListBase *tracksbase= BKE_tracking_get_tracks(tracking); MovieTrackingTrack *act_track, *track, *next; - act_track= clip->tracking.act_track; + act_track= BKE_tracking_active_track(tracking); if(!act_track) { BKE_report(op->reports, RPT_ERROR, "No active track to join to"); return OPERATOR_CANCELLED; } - track= clip->tracking.tracks.first; + track= tracksbase->first; while(track) { if(TRACK_VIEW_SELECTED(sc, track) && track!=act_track) { if(!BKE_tracking_test_join_tracks(act_track, track)) { @@ -2582,7 +2941,7 @@ track= track->next; } - track= clip->tracking.tracks.first; + track= tracksbase->first; while(track) { next= track->next; @@ -2590,7 +2949,7 @@ BKE_tracking_join_tracks(act_track, track); BKE_tracking_free_track(track); - BLI_freelinkN(&clip->tracking.tracks, track); + BLI_freelinkN(tracksbase, track); } track= next; @@ -2623,7 +2982,8 @@ SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= ED_space_clip(sc); MovieTracking *tracking= &clip->tracking; - MovieTrackingTrack *track= tracking->tracks.first; + ListBase *tracksbase= BKE_tracking_get_tracks(tracking); + MovieTrackingTrack *track= tracksbase->first; int action= RNA_enum_get(op->ptr, "action"); while(track) { @@ -2672,12 +3032,14 @@ { SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= ED_space_clip(sc); - MovieTrackingTrack *track, *act_track= clip->tracking.act_track; + MovieTracking *tracking= &clip->tracking; + ListBase *tracksbase= BKE_tracking_get_tracks(tracking); + MovieTrackingTrack *track, *act_track= BKE_tracking_active_track(tracking); if(!act_track) return OPERATOR_CANCELLED; - track= clip->tracking.tracks.first; + track= tracksbase->first; while(track) { if(TRACK_VIEW_SELECTED(sc, track) && track!=act_track) { track->flag&= ~TRACK_CUSTOMCOLOR; @@ -2718,11 +3080,12 @@ SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= ED_space_clip(sc); MovieTracking *tracking= &clip->tracking; + ListBase *tracksbase= BKE_tracking_get_tracks(tracking); MovieTrackingTrack *track; MovieTrackingStabilization *stab= &tracking->stabilization; int update= 0; - track= tracking->tracks.first; + track= tracksbase->first; while(track) { if(TRACK_VIEW_SELECTED(sc, track) && (track->flag&TRACK_USE_2D_STAB)==0) { track->flag|= TRACK_USE_2D_STAB; @@ -2767,10 +3130,11 @@ MovieClip *clip= ED_space_clip(sc); MovieTracking *tracking= &clip->tracking; MovieTrackingStabilization *stab= &tracking->stabilization; + ListBase *tracksbase= BKE_tracking_get_tracks(tracking); MovieTrackingTrack *track; int a= 0, update= 0; - track= tracking->tracks.first; + track= tracksbase->first; while(track) { if(track->flag&TRACK_USE_2D_STAB) { if(a==stab->act_track) { @@ -2825,10 +3189,11 @@ SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= ED_space_clip(sc); MovieTracking *tracking= &clip->tracking; + ListBase *tracksbase= BKE_tracking_get_tracks(tracking); MovieTrackingTrack *track; int update= 0; - track= tracking->tracks.first; + track= tracksbase->first; while(track) { if(track->flag&TRACK_USE_2D_STAB) { BKE_tracking_track_flag(track, TRACK_AREA_ALL, SELECT, 0); @@ -2867,11 +3232,12 @@ SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= ED_space_clip(sc); MovieTracking *tracking= &clip->tracking; + MovieTrackingTrack *act_track= BKE_tracking_active_track(tracking); - if(tracking->act_track) { + if(act_track) { MovieTrackingStabilization *stab= &tracking->stabilization; - stab->rot_track= tracking->act_track; + stab->rot_track= act_track; stab->ok= 0; DAG_id_tag_update(&clip->id, 0); @@ -2996,7 +3362,8 @@ SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= ED_space_clip(sc); MovieTracking *tracking= &clip->tracking; - MovieTrackingTrack *track, *next, *act_track= clip->tracking.act_track; + ListBase *tracksbase= BKE_tracking_get_tracks(tracking); + MovieTrackingTrack *track, *next, *act_track= BKE_tracking_active_track(tracking); int frames= RNA_int_get(op->ptr, "frames"); int action= RNA_enum_get(op->ptr, "action"); float error= RNA_float_get(op->ptr, "error"); @@ -3004,7 +3371,7 @@ if(error && action==TRACKING_CLEAN_DELETE_SEGMENT) action= TRACKING_CLEAN_DELETE_TRACK; - track= tracking->tracks.first; + track= tracksbase->first; while(track) { next= track->next; @@ -3023,7 +3390,7 @@ clip->tracking.act_track= NULL; BKE_tracking_free_track(track); - BLI_freelinkN(&clip->tracking.tracks, track); + BLI_freelinkN(tracksbase, track); track= NULL; } @@ -3033,7 +3400,7 @@ clip->tracking.act_track= NULL; BKE_tracking_free_track(track); - BLI_freelinkN(&clip->tracking.tracks, track); + BLI_freelinkN(tracksbase, track); } } } @@ -3050,15 +3417,15 @@ { SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= ED_space_clip(sc); - int frames= RNA_int_get(op->ptr, "frames"); - float error= RNA_float_get(op->ptr, "error"); - int action= RNA_enum_get(op->ptr, "action"); - if(frames==0 && error==0 && action==0) { + if(!RNA_struct_property_is_set(op->ptr, "frames")) RNA_int_set(op->ptr, "frames", clip->tracking.settings.clean_frames); + + if(!RNA_struct_property_is_set(op->ptr, "error")) RNA_float_set(op->ptr, "error", clip->tracking.settings.clean_error); + + if(!RNA_struct_property_is_set(op->ptr, "action")) RNA_enum_set(op->ptr, "action", clip->tracking.settings.clean_action); - } return clean_tracks_exec(C, op); } @@ -3090,3 +3457,142 @@ RNA_def_float(ot->srna, "error", 0.0f, 0.0f, FLT_MAX, "Reprojection Error", "Effect on tracks with have got larger reprojection error", 0.0f, 100.0f); RNA_def_enum(ot->srna, "action", actions_items, 0, "Action", "Cleanup action to execute"); } + +/********************** add tracking object *********************/ + +static int tracking_object_new_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTracking *tracking= &clip->tracking; + + BKE_tracking_new_object(tracking, "Object"); + + WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_tracking_object_new(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Add Tracking Object"; + ot->description= "Add new object for tracking"; + ot->idname= "CLIP_OT_tracking_object_new"; + + /* api callbacks */ + ot->exec= tracking_object_new_exec; + ot->poll= ED_space_clip_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/********************** remove tracking object *********************/ + +static int tracking_object_remove_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTracking *tracking= &clip->tracking; + MovieTrackingObject *object; + + object= BKE_tracking_active_object(tracking); + + if(object->flag&TRACKING_OBJECT_CAMERA) { + BKE_report(op->reports, RPT_WARNING, "Object used for camera tracking can't be deleted"); + return OPERATOR_CANCELLED; + } + + BKE_tracking_remove_object(tracking, object); + + WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_tracking_object_remove(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Movie Tracking Object"; + ot->description= "Remove object for tracking"; + ot->idname= "CLIP_OT_tracking_object_remove"; + + /* api callbacks */ + ot->exec= tracking_object_remove_exec; + ot->poll= ED_space_clip_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/********************** copy tracks to clipboard operator *********************/ + +static int copy_tracks_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + MovieClip *clip = ED_space_clip(sc); + MovieTracking *tracking = &clip->tracking; + MovieTrackingObject *object = BKE_tracking_active_object(tracking); + + clear_invisible_track_selection(sc, clip); + + BKE_tracking_clipboard_copy_tracks(tracking, object); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_copy_tracks(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Copy Tracks"; + ot->description = "Copy selected tracks to clipboard"; + ot->idname = "CLIP_OT_copy_tracks"; + + /* api callbacks */ + ot->exec = copy_tracks_exec; + ot->poll = ED_space_clip_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER; +} + +/********************** paste tracks from clipboard operator *********************/ + +static int paste_tracks_poll(bContext *C) +{ + if (ED_space_clip_poll(C)) { + return BKE_tracking_clipboard_has_tracks(); + } + + return 0; +} + +static int paste_tracks_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + MovieClip *clip = ED_space_clip(sc); + MovieTracking *tracking = &clip->tracking; + MovieTrackingObject *object = BKE_tracking_active_object(tracking); + + BKE_tracking_clipboard_paste_tracks(tracking, object); + + WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_paste_tracks(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Paste Tracks"; + ot->description = "Paste tracks from clipboard"; + ot->idname = "CLIP_OT_paste_tracks"; + + /* api callbacks */ + ot->exec = paste_tracks_exec; + ot->poll = paste_tracks_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} diff -Nru blender-2.61/source/blender/editors/space_console/console_ops.c blender-2.62/source/blender/editors/space_console/console_ops.c --- blender-2.61/source/blender/editors/space_console/console_ops.c 2011-12-13 19:52:29.000000000 +0000 +++ blender-2.62/source/blender/editors/space_console/console_ops.c 2012-02-15 19:37:03.000000000 +0000 @@ -410,7 +410,7 @@ static int console_insert_invoke(bContext *C, wmOperator *op, wmEvent *event) { - // if(!RNA_property_is_set(op->ptr, "text")) { /* always set from keymap XXX */ + // if(!RNA_struct_property_is_set(op->ptr, "text")) { /* always set from keymap XXX */ if(!RNA_string_length(op->ptr, "text")) { /* if alt/ctrl/super are pressed pass through */ if(event->ctrl || event->oskey) { @@ -655,7 +655,11 @@ ED_area_tag_redraw(sa); - console_scroll_bottom(ar); + /* when calling render modally this can be NULL when calling: + * bpy.ops.render.render('INVOKE_DEFAULT') */ + if (ar) { + console_scroll_bottom(ar); + } return OPERATOR_FINISHED; } diff -Nru blender-2.61/source/blender/editors/space_console/space_console.c blender-2.62/source/blender/editors/space_console/space_console.c --- blender-2.61/source/blender/editors/space_console/space_console.c 2011-12-13 19:52:29.000000000 +0000 +++ blender-2.62/source/blender/editors/space_console/space_console.c 2012-02-15 19:37:03.000000000 +0000 @@ -276,24 +276,25 @@ kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", WHEELUPMOUSE, KM_PRESS, KM_CTRL, 0); RNA_string_set(kmi->ptr, "data_path", "space_data.font_size"); - RNA_boolean_set(kmi->ptr, "reverse", 0); + RNA_boolean_set(kmi->ptr, "reverse", FALSE); kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", WHEELDOWNMOUSE, KM_PRESS, KM_CTRL, 0); RNA_string_set(kmi->ptr, "data_path", "space_data.font_size"); - RNA_boolean_set(kmi->ptr, "reverse", 1); + RNA_boolean_set(kmi->ptr, "reverse", TRUE); kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", PADPLUSKEY, KM_PRESS, KM_CTRL, 0); RNA_string_set(kmi->ptr, "data_path", "space_data.font_size"); - RNA_boolean_set(kmi->ptr, "reverse", 0); + RNA_boolean_set(kmi->ptr, "reverse", FALSE); kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", PADMINUS, KM_PRESS, KM_CTRL, 0); RNA_string_set(kmi->ptr, "data_path", "space_data.font_size"); - RNA_boolean_set(kmi->ptr, "reverse", 1); + RNA_boolean_set(kmi->ptr, "reverse", TRUE); RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", LEFTARROWKEY, KM_PRESS, 0, 0)->ptr, "type", PREV_CHAR); RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", RIGHTARROWKEY, KM_PRESS, 0, 0)->ptr, "type", NEXT_CHAR); - RNA_boolean_set(WM_keymap_add_item(keymap, "CONSOLE_OT_history_cycle", UPARROWKEY, KM_PRESS, 0, 0)->ptr, "reverse", 1); + kmi = WM_keymap_add_item(keymap, "CONSOLE_OT_history_cycle", UPARROWKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "reverse", TRUE); WM_keymap_add_item(keymap, "CONSOLE_OT_history_cycle", DOWNARROWKEY, KM_PRESS, 0, 0); /* diff -Nru blender-2.61/source/blender/editors/space_file/file_draw.c blender-2.62/source/blender/editors/space_file/file_draw.c --- blender-2.61/source/blender/editors/space_file/file_draw.c 2011-12-13 19:52:52.000000000 +0000 +++ blender-2.62/source/blender/editors/space_file/file_draw.c 2012-02-15 19:37:19.000000000 +0000 @@ -118,7 +118,7 @@ const int separator = 4; /* Additional locals. */ - char name[32]; + char uiblockstr[32]; int loadbutton; int fnumbuttons; int min_x = 10; @@ -134,8 +134,8 @@ ARegion* artmp; /* Initialize UI block. */ - sprintf(name, "win %p", (void *)ar); - block = uiBeginBlock(C, ar, name, UI_EMBOSS); + BLI_snprintf(uiblockstr, sizeof(uiblockstr), "win %p", (void *)ar); + block = uiBeginBlock(C, ar, uiblockstr, UI_EMBOSS); uiBlockSetHandleFunc(block, do_file_buttons, NULL); /* exception to make space for collapsed region icon */ @@ -450,7 +450,7 @@ struct FileList* files = sfile->files; struct direntry *file; ImBuf *imb; - uiBlock *block = uiBeginBlock(C, ar, "FileNames", UI_EMBOSS); + uiBlock *block = uiBeginBlock(C, ar, __func__, UI_EMBOSS); int numfiles; int numfiles_layout; int sx, sy; diff -Nru blender-2.61/source/blender/editors/space_file/filelist.c blender-2.62/source/blender/editors/space_file/filelist.c --- blender-2.61/source/blender/editors/space_file/filelist.c 2011-12-13 19:52:52.000000000 +0000 +++ blender-2.62/source/blender/editors/space_file/filelist.c 2012-02-15 19:37:19.000000000 +0000 @@ -586,7 +586,7 @@ void filelist_setdir(struct FileList* filelist, const char *dir) { - BLI_strncpy(filelist->dir, dir, FILE_MAX); + BLI_strncpy(filelist->dir, dir, sizeof(filelist->dir)); } void filelist_imgsize(struct FileList* filelist, short w, short h) @@ -853,10 +853,9 @@ for(num=0; numnumfiles; num++, file++) { if(BLO_has_bfile_extension(file->relname)) { char name[FILE_MAX]; - - BLI_strncpy(name, filelist->dir, sizeof(name)); - strcat(name, file->relname); - + + BLI_join_dirfile(name, sizeof(name), filelist->dir, file->relname); + /* prevent current file being used as acceptable dir */ if (BLI_path_cmp(G.main->name, name) != 0) { file->type &= ~S_IFMT; @@ -970,7 +969,7 @@ return BLO_is_a_library(filelist->dir, dir, group); } -static int groupname_to_code(char *group) +static int groupname_to_code(const char *group) { char buf[32]; char *lslash; @@ -1199,10 +1198,10 @@ if(idcode == ID_MA || idcode == ID_TE || idcode == ID_LA || idcode == ID_WO || idcode == ID_IM) { files->flags |= IMAGEFILE; } - if(id->lib && fake) sprintf(files->extra, "LF %d", id->us); - else if(id->lib) sprintf(files->extra, "L %d", id->us); - else if(fake) sprintf(files->extra, "F %d", id->us); - else sprintf(files->extra, " %d", id->us); + if(id->lib && fake) BLI_snprintf(files->extra, sizeof(files->extra), "LF %d", id->us); + else if(id->lib) BLI_snprintf(files->extra, sizeof(files->extra), "L %d", id->us); + else if(fake) BLI_snprintf(files->extra, sizeof(files->extra), "F %d", id->us); + else BLI_snprintf(files->extra, sizeof(files->extra), " %d", id->us); if(id->lib) { if(totlib==0) firstlib= files; diff -Nru blender-2.61/source/blender/editors/space_file/file_ops.c blender-2.62/source/blender/editors/space_file/file_ops.c --- blender-2.61/source/blender/editors/space_file/file_ops.c 2011-12-13 19:52:52.000000000 +0000 +++ blender-2.62/source/blender/editors/space_file/file_ops.c 2012-02-15 19:37:19.000000000 +0000 @@ -1096,8 +1096,14 @@ BLI_join_dirfile(sfile->params->dir, sizeof(sfile->params->dir), BLI_getDefaultDocumentFolder(), tmpstr); } -#ifdef WIN32 - if (sfile->params->dir[0] == '\0') { + else if (sfile->params->dir[0] == '\0') +#ifndef WIN32 + { + sfile->params->dir[0] = '/'; + sfile->params->dir[1] = '\0'; + } +#else + { get_default_root(sfile->params->dir); } /* change "C:" --> "C:\", [#28102] */ diff -Nru blender-2.61/source/blender/editors/space_file/filesel.c blender-2.62/source/blender/editors/space_file/filesel.c --- blender-2.61/source/blender/editors/space_file/filesel.c 2011-12-13 19:52:52.000000000 +0000 +++ blender-2.62/source/blender/editors/space_file/filesel.c 2012-02-15 19:37:19.000000000 +0000 @@ -130,7 +130,7 @@ else params->type = FILE_SPECIAL; - if (is_filepath && RNA_property_is_set(op->ptr, "filepath")) { + if (is_filepath && RNA_struct_property_is_set(op->ptr, "filepath")) { char name[FILE_MAX]; RNA_string_get(op->ptr, "filepath", name); if (params->type == FILE_LOADLIB) { @@ -142,12 +142,12 @@ } } else { - if (is_directory && RNA_property_is_set(op->ptr, "directory")) { + if (is_directory && RNA_struct_property_is_set(op->ptr, "directory")) { RNA_string_get(op->ptr, "directory", params->dir); sfile->params->file[0]= '\0'; } - if (is_filename && RNA_property_is_set(op->ptr, "filename")) { + if (is_filename && RNA_struct_property_is_set(op->ptr, "filename")) { RNA_string_get(op->ptr, "filename", params->file); } } @@ -215,18 +215,23 @@ params->flag |= RNA_boolean_get(op->ptr, "autoselect") ? FILE_AUTOSELECT : 0; params->flag |= RNA_boolean_get(op->ptr, "active_layer") ? FILE_ACTIVELAY : 0; } - - if (U.uiflag & USER_SHOW_THUMBNAILS) { - if(params->filter & (IMAGEFILE|MOVIEFILE)) - params->display= FILE_IMGDISPLAY; - else + + if(RNA_struct_find_property(op->ptr, "display_type")) + params->display= RNA_enum_get(op->ptr, "display_type"); + + if(params->display==FILE_DEFAULTDISPLAY) { + if (U.uiflag & USER_SHOW_THUMBNAILS) { + if(params->filter & (IMAGEFILE|MOVIEFILE)) + params->display= FILE_IMGDISPLAY; + else + params->display= FILE_SHORTDISPLAY; + } else { params->display= FILE_SHORTDISPLAY; - } else { - params->display= FILE_SHORTDISPLAY; + } } if (is_relative_path) { - if (!RNA_property_is_set(op->ptr, "relative_path")) { + if (!RNA_struct_property_is_set(op->ptr, "relative_path")) { RNA_boolean_set(op->ptr, "relative_path", U.flag & USER_RELPATHS); } } @@ -667,9 +672,13 @@ void ED_fileselect_clear(struct bContext *C, struct SpaceFile *sfile) { - thumbnails_stop(sfile->files, C); - filelist_freelib(sfile->files); - filelist_free(sfile->files); + /* only NULL in rare cases - [#29734] */ + if (sfile->files) { + thumbnails_stop(sfile->files, C); + filelist_freelib(sfile->files); + filelist_free(sfile->files); + } + sfile->params->active_file = -1; WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); } diff -Nru blender-2.61/source/blender/editors/space_file/space_file.c blender-2.62/source/blender/editors/space_file/space_file.c --- blender-2.61/source/blender/editors/space_file/space_file.c 2011-12-13 19:52:52.000000000 +0000 +++ blender-2.62/source/blender/editors/space_file/space_file.c 2012-02-15 19:37:19.000000000 +0000 @@ -410,13 +410,13 @@ /* keys for main area */ keymap= WM_keymap_find(keyconf, "File Browser Main", SPACE_FILE, 0); kmi= WM_keymap_add_item(keymap, "FILE_OT_execute", LEFTMOUSE, KM_DBL_CLICK, 0, 0); - RNA_boolean_set(kmi->ptr, "need_active", 1); + RNA_boolean_set(kmi->ptr, "need_active", TRUE); WM_keymap_add_item(keymap, "FILE_OT_select", LEFTMOUSE, KM_CLICK, 0, 0); kmi = WM_keymap_add_item(keymap, "FILE_OT_select", LEFTMOUSE, KM_CLICK, KM_SHIFT, 0); - RNA_boolean_set(kmi->ptr, "extend", 1); + RNA_boolean_set(kmi->ptr, "extend", TRUE); kmi = WM_keymap_add_item(keymap, "FILE_OT_select", LEFTMOUSE, KM_CLICK, KM_ALT, 0); - RNA_boolean_set(kmi->ptr, "extend", 1); - RNA_boolean_set(kmi->ptr, "fill", 1); + RNA_boolean_set(kmi->ptr, "extend", TRUE); + RNA_boolean_set(kmi->ptr, "fill", TRUE); WM_keymap_add_item(keymap, "FILE_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "FILE_OT_refresh", PADPERIOD, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "FILE_OT_select_border", BKEY, KM_PRESS, 0, 0); diff -Nru blender-2.61/source/blender/editors/space_graph/graph_buttons.c blender-2.62/source/blender/editors/space_graph/graph_buttons.c --- blender-2.61/source/blender/editors/space_graph/graph_buttons.c 2011-12-13 19:54:39.000000000 +0000 +++ blender-2.62/source/blender/editors/space_graph/graph_buttons.c 2012-02-15 19:38:53.000000000 +0000 @@ -647,7 +647,7 @@ uiItemL(row, "Driver Value:", ICON_NONE); - sprintf(valBuf, "%.3f", driver->curval); + BLI_snprintf(valBuf, sizeof(valBuf), "%.3f", driver->curval); uiItemL(row, valBuf, ICON_NONE); } @@ -702,18 +702,18 @@ graph_panel_driverVar__transChan(box, ale->id, dvar); break; } - - /* value of variable */ - if (driver->flag & DRIVER_FLAG_SHOWDEBUG) { - char valBuf[32]; - - box= uiLayoutBox(col); - row= uiLayoutRow(box, 1); + + /* value of variable */ + if (driver->flag & DRIVER_FLAG_SHOWDEBUG) { + char valBuf[32]; + + box= uiLayoutBox(col); + row= uiLayoutRow(box, 1); uiItemL(row, "Value:", ICON_NONE); - sprintf(valBuf, "%.3f", dvar->curval); + BLI_snprintf(valBuf, sizeof(valBuf), "%.3f", dvar->curval); uiItemL(row, valBuf, ICON_NONE); - } + } } /* cleanup */ diff -Nru blender-2.61/source/blender/editors/space_graph/graph_draw.c blender-2.62/source/blender/editors/space_graph/graph_draw.c --- blender-2.61/source/blender/editors/space_graph/graph_draw.c 2011-12-13 19:54:39.000000000 +0000 +++ blender-2.62/source/blender/editors/space_graph/graph_draw.c 2012-02-15 19:38:53.000000000 +0000 @@ -1003,7 +1003,7 @@ } } { /* second pass: widgets */ - uiBlock *block= uiBeginBlock(C, ar, "graph channel buttons", UI_EMBOSS); + uiBlock *block= uiBeginBlock(C, ar, __func__, UI_EMBOSS); size_t channel_index = 0; y= (float)ACHANNEL_FIRST; diff -Nru blender-2.61/source/blender/editors/space_graph/graph_edit.c blender-2.62/source/blender/editors/space_graph/graph_edit.c --- blender-2.61/source/blender/editors/space_graph/graph_edit.c 2011-12-13 19:54:39.000000000 +0000 +++ blender-2.62/source/blender/editors/space_graph/graph_edit.c 2012-02-15 19:38:53.000000000 +0000 @@ -1046,6 +1046,8 @@ // todo: add props for start/end frames } +#ifdef WITH_AUDASPACE + /* ******************** Sound Bake F-Curve Operator *********************** */ /* This operator bakes the given sound to the selected F-Curves */ @@ -1078,7 +1080,6 @@ /* ------------------- */ -#ifdef WITH_AUDASPACE static int graphkeys_sound_bake_exec(bContext *C, wmOperator *op) { bAnimContext ac; @@ -1187,7 +1188,7 @@ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH); + WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); RNA_def_float(ot->srna, "low", 0.0f, 0.0, 100000.0, "Lowest frequency", "", 0.1, 1000.00); RNA_def_float(ot->srna, "high", 100000.0, 0.0, 100000.0, "Highest frequency", "", 0.1, 1000.00); RNA_def_float(ot->srna, "attack", 0.005, 0.0, 2.0, "Attack time", "", 0.01, 0.1); @@ -2068,6 +2069,7 @@ /* present a special customised popup menu for this, with some filtering */ static int graph_fmodifier_add_invoke (bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { + wmOperatorType *ot = WM_operatortype_find("GRAPH_OT_fmodifier_add", 1); uiPopupMenu *pup; uiLayout *layout; int i; @@ -2085,7 +2087,7 @@ continue; /* create operator menu item with relevant properties filled in */ - props_ptr= uiItemFullO(layout, "GRAPH_OT_fmodifier_add", fmi->name, ICON_NONE, NULL, WM_OP_EXEC_REGION_WIN, UI_ITEM_O_RETURN_PROPS); + props_ptr= uiItemFullO_ptr(layout, ot, fmi->name, ICON_NONE, NULL, WM_OP_EXEC_REGION_WIN, UI_ITEM_O_RETURN_PROPS); /* the only thing that gets set from the menu is the type of F-Modifier to add */ RNA_enum_set(&props_ptr, "type", i); /* the following properties are just repeats of existing ones... */ diff -Nru blender-2.61/source/blender/editors/space_graph/graph_ops.c blender-2.62/source/blender/editors/space_graph/graph_ops.c --- blender-2.61/source/blender/editors/space_graph/graph_ops.c 2011-12-13 19:54:39.000000000 +0000 +++ blender-2.62/source/blender/editors/space_graph/graph_ops.c 2012-02-15 19:38:53.000000000 +0000 @@ -182,43 +182,11 @@ RNA_def_float(ot->srna, "value", 0, FLT_MIN, FLT_MAX, "Value", "", -100.0f, 100.0f); } -/* Toggle Handles ----------------------------------------------------------------- */ - -static int view_toggle_handles_exec (bContext *C, wmOperator *UNUSED(op)) -{ - SpaceIpo *sipo= CTX_wm_space_graph(C); - ARegion *ar= CTX_wm_region(C); - - if (sipo == NULL) - return OPERATOR_CANCELLED; - - /* toggle flag to hide handles */ - sipo->flag ^= SIPO_NOHANDLES; - - /* request refresh of keys area */ - ED_region_tag_redraw(ar); - - return OPERATOR_FINISHED; -} - -static void GRAPH_OT_view_togglehandles (wmOperatorType *ot) -{ - /* identification */ - ot->name= "Show/Hide All Handles"; - ot->idname= "GRAPH_OT_handles_view_toggle"; - ot->description= "Toggle whether handles are drawn on all keyframes that need them"; - - /* callbacks */ - ot->exec= view_toggle_handles_exec; - ot->poll= ED_operator_graphedit_active; -} - /* ************************** registration - operator types **********************************/ void graphedit_operatortypes(void) { /* view */ - WM_operatortype_append(GRAPH_OT_view_togglehandles); WM_operatortype_append(GRAPH_OT_cursor_set); WM_operatortype_append(GRAPH_OT_previewrange_set); @@ -290,7 +258,9 @@ wmKeyMapItem *kmi; /* view */ - WM_keymap_add_item(keymap, "GRAPH_OT_handles_view_toggle", HKEY, KM_PRESS, KM_CTRL, 0); + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", HKEY, KM_PRESS, KM_CTRL, 0); + RNA_string_set(kmi->ptr, "data_path", "space_data.show_handles"); + /* NOTE: 'ACTIONMOUSE' not 'LEFTMOUSE', as user may have swapped mouse-buttons * This keymap is supposed to override ANIM_OT_change_frame, which does the same except it doesn't do y-values */ @@ -299,44 +269,66 @@ /* graph_select.c - selection tools */ /* click-select */ - WM_keymap_add_item(keymap, "GRAPH_OT_clickselect", SELECTMOUSE, KM_PRESS, 0, 0); + kmi = WM_keymap_add_item(keymap, "GRAPH_OT_clickselect", SELECTMOUSE, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + RNA_boolean_set(kmi->ptr, "curves", FALSE); + RNA_boolean_set(kmi->ptr, "column", FALSE); kmi= WM_keymap_add_item(keymap, "GRAPH_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_ALT, 0); - RNA_boolean_set(kmi->ptr, "column", 1); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + RNA_boolean_set(kmi->ptr, "curves", FALSE); + RNA_boolean_set(kmi->ptr, "column", TRUE); kmi= WM_keymap_add_item(keymap, "GRAPH_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0); - RNA_boolean_set(kmi->ptr, "extend", 1); + RNA_boolean_set(kmi->ptr, "extend", TRUE); + RNA_boolean_set(kmi->ptr, "curves", FALSE); + RNA_boolean_set(kmi->ptr, "column", FALSE); kmi= WM_keymap_add_item(keymap, "GRAPH_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_ALT|KM_SHIFT, 0); - RNA_boolean_set(kmi->ptr, "extend", 1); - RNA_boolean_set(kmi->ptr, "column", 1); + RNA_boolean_set(kmi->ptr, "extend", TRUE); + RNA_boolean_set(kmi->ptr, "curves", FALSE); + RNA_boolean_set(kmi->ptr, "column", TRUE); kmi= WM_keymap_add_item(keymap, "GRAPH_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_CTRL|KM_ALT, 0); - RNA_boolean_set(kmi->ptr, "curves", 1); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + RNA_boolean_set(kmi->ptr, "curves", TRUE); + RNA_boolean_set(kmi->ptr, "column", FALSE); kmi= WM_keymap_add_item(keymap, "GRAPH_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_CTRL|KM_ALT|KM_SHIFT, 0); - RNA_boolean_set(kmi->ptr, "curves", 1); - RNA_boolean_set(kmi->ptr, "extend", 1); + RNA_boolean_set(kmi->ptr, "extend", TRUE); + RNA_boolean_set(kmi->ptr, "curves", TRUE); + RNA_boolean_set(kmi->ptr, "column", FALSE); /* select left/right */ - WM_keymap_add_item(keymap, "GRAPH_OT_select_leftright", SELECTMOUSE, KM_PRESS, KM_CTRL, 0); + kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_leftright", SELECTMOUSE, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + RNA_enum_set(kmi->ptr, "mode", GRAPHKEYS_LRSEL_TEST); kmi= WM_keymap_add_item(keymap, "GRAPH_OT_select_leftright", SELECTMOUSE, KM_PRESS, KM_CTRL|KM_SHIFT, 0); - RNA_boolean_set(kmi->ptr, "extend", 1); + RNA_boolean_set(kmi->ptr, "extend", TRUE); + RNA_enum_set(kmi->ptr, "mode", GRAPHKEYS_LRSEL_TEST); kmi= WM_keymap_add_item(keymap, "GRAPH_OT_select_leftright", LEFTBRACKETKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); RNA_enum_set(kmi->ptr, "mode", GRAPHKEYS_LRSEL_LEFT); kmi= WM_keymap_add_item(keymap, "GRAPH_OT_select_leftright", RIGHTBRACKETKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); RNA_enum_set(kmi->ptr, "mode", GRAPHKEYS_LRSEL_RIGHT); /* deselect all */ - WM_keymap_add_item(keymap, "GRAPH_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "GRAPH_OT_select_all_toggle", IKEY, KM_PRESS, KM_CTRL, 0)->ptr, "invert", 1); + kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "invert", FALSE); + kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_all_toggle", IKEY, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "invert", TRUE); /* borderselect */ - WM_keymap_add_item(keymap, "GRAPH_OT_select_border", BKEY, KM_PRESS, 0, 0); + kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_border", BKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "axis_range", FALSE); + RNA_boolean_set(kmi->ptr, "include_handles", FALSE); kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_border", BKEY, KM_PRESS, KM_ALT, 0); - RNA_boolean_set(kmi->ptr, "axis_range", 1); + RNA_boolean_set(kmi->ptr, "axis_range", TRUE); + RNA_boolean_set(kmi->ptr, "include_handles", FALSE); kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_border", BKEY, KM_PRESS, KM_CTRL, 0); - RNA_boolean_set(kmi->ptr, "include_handles", 1); + RNA_boolean_set(kmi->ptr, "axis_range", FALSE); + RNA_boolean_set(kmi->ptr, "include_handles", TRUE); kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_border", BKEY, KM_PRESS, KM_CTRL|KM_ALT, 0); - RNA_boolean_set(kmi->ptr, "axis_range", 1); - RNA_boolean_set(kmi->ptr, "include_handles", 1); + RNA_boolean_set(kmi->ptr, "axis_range", TRUE); + RNA_boolean_set(kmi->ptr, "include_handles", TRUE); /* column select */ RNA_enum_set(WM_keymap_add_item(keymap, "GRAPH_OT_select_column", KKEY, KM_PRESS, 0, 0)->ptr, "mode", GRAPHKEYS_COLUMNSEL_KEYS); @@ -391,7 +383,8 @@ WM_keymap_add_item(keymap, "GRAPH_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0); /* F-Modifiers */ - RNA_boolean_set(WM_keymap_add_item(keymap, "GRAPH_OT_fmodifier_add", MKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "only_active", 0); + kmi = WM_keymap_add_item(keymap, "GRAPH_OT_fmodifier_add", MKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "only_active", FALSE); /* animation module */ /* channels list diff -Nru blender-2.61/source/blender/editors/space_graph/graph_select.c blender-2.62/source/blender/editors/space_graph/graph_select.c --- blender-2.61/source/blender/editors/space_graph/graph_select.c 2011-12-13 19:54:39.000000000 +0000 +++ blender-2.62/source/blender/editors/space_graph/graph_select.c 2012-02-15 19:38:53.000000000 +0000 @@ -201,7 +201,7 @@ { ListBase anim_data = {NULL, NULL}; bAnimListElem *ale; - int filter; + int filter, mapping_flag; SpaceIpo *sipo= (SpaceIpo *)ac->sl; KeyframeEditData ked; @@ -226,8 +226,12 @@ ked.data= &rectf; /* treat handles separately? */ - if (incl_handles) + if (incl_handles) { ked.iterflags |= KEYFRAME_ITER_INCL_HANDLES; + mapping_flag= 0; + } + else + mapping_flag= ANIM_UNITCONV_ONLYKEYS; /* loop over data, doing border select */ for (ale= anim_data.first; ale; ale= ale->next) { @@ -235,7 +239,7 @@ FCurve *fcu= (FCurve *)ale->key_data; /* apply unit corrections */ - ANIM_unit_mapping_apply_fcurve(ac->scene, ale->id, ale->key_data, ANIM_UNITCONV_ONLYKEYS); + ANIM_unit_mapping_apply_fcurve(ac->scene, ale->id, ale->key_data, mapping_flag); /* apply NLA mapping to all the keyframes, since it's easier than trying to * guess when a callback might use something different @@ -274,7 +278,7 @@ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, incl_handles==0); /* unapply unit corrections */ - ANIM_unit_mapping_apply_fcurve(ac->scene, ale->id, ale->key_data, ANIM_UNITCONV_RESTORE|ANIM_UNITCONV_ONLYKEYS); + ANIM_unit_mapping_apply_fcurve(ac->scene, ale->id, ale->key_data, ANIM_UNITCONV_RESTORE|mapping_flag); } /* cleanup */ @@ -386,6 +390,8 @@ /* ------------------- */ /* Selects all visible keyframes between the specified markers */ +/* TODO, this is almost an _exact_ duplicate of a function of the same name in action_select.c + * should de-duplicate - campbell */ static void markers_selectkeys_between (bAnimContext *ac) { ListBase anim_data = {NULL, NULL}; @@ -393,7 +399,7 @@ int filter; KeyframeEditFunc ok_cb, select_cb; - KeyframeEditData ked; + KeyframeEditData ked= {{NULL}}; float min, max; /* get extreme markers */ @@ -404,9 +410,8 @@ /* get editing funcs + data */ ok_cb= ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE); select_cb= ANIM_editkeyframes_select(SELECT_ADD); - - memset(&ked, 0, sizeof(KeyframeEditData)); - ked.f1= min; + + ked.f1= min; ked.f2= max; /* filter data */ @@ -416,8 +421,8 @@ /* select keys in-between */ for (ale= anim_data.first; ale; ale= ale->next) { AnimData *adt= ANIM_nla_mapping_get(ac, ale); - - if (adt) { + + if (adt) { ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1); ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL); ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1); diff -Nru blender-2.61/source/blender/editors/space_image/image_buttons.c blender-2.62/source/blender/editors/space_image/image_buttons.c --- blender-2.61/source/blender/editors/space_image/image_buttons.c 2011-12-13 19:54:11.000000000 +0000 +++ blender-2.62/source/blender/editors/space_image/image_buttons.c 2012-02-15 19:38:24.000000000 +0000 @@ -335,7 +335,7 @@ return; } - block= uiBeginBlock(C, ar, "image_panel_preview", UI_EMBOSS); + block= uiBeginBlock(C, ar, __func__, UI_EMBOSS); uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | UI_PNL_SCALE | cntrl); uiSetPanelHandler(IMAGE_HANDLER_PREVIEW); // for close and esc @@ -682,7 +682,7 @@ uiButSetFunc(but, image_freecache_cb, ima, NULL); if(iuser->frames) - sprintf(str, "(%d) Frames:", iuser->framenr); + BLI_snprintf(str, sizeof(str), "(%d) Frames:", iuser->framenr); else strcpy(str, "Frames:"); uiBlockBeginAlign(block); uiDefButI(block, NUM, imagechanged, str, 10, 90,150, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Number of images of a movie to use"); @@ -750,7 +750,9 @@ uiLayoutSetActive(row, RNA_boolean_get(&imaptr, "use_fields")); uiItemR(row, &imaptr, "field_order", UI_ITEM_R_EXPAND, NULL, ICON_NONE); - uiItemR(split, &imaptr, "use_premultiply", 0, NULL, ICON_NONE); + row= uiLayoutRow(layout, 0); + uiItemR(row, &imaptr, "use_premultiply", 0, NULL, ICON_NONE); + uiItemR(row, &imaptr, "use_color_unpremultiply", 0, NULL, ICON_NONE); } } @@ -761,7 +763,7 @@ col= uiLayoutColumn(split, 0); - sprintf(str, "(%d) Frames", iuser->framenr); + BLI_snprintf(str, sizeof(str), "(%d) Frames", iuser->framenr); uiItemR(col, userptr, "frame_duration", 0, str, ICON_NONE); if(ima->anim) { block= uiLayoutGetBlock(col); diff -Nru blender-2.61/source/blender/editors/space_image/image_draw.c blender-2.62/source/blender/editors/space_image/image_draw.c --- blender-2.61/source/blender/editors/space_image/image_draw.c 2011-12-13 19:54:11.000000000 +0000 +++ blender-2.62/source/blender/editors/space_image/image_draw.c 2012-02-15 19:38:24.000000000 +0000 @@ -110,7 +110,9 @@ BKE_image_release_renderresult(scene, ima); } -void draw_image_info(ARegion *ar, int color_manage, int channels, int x, int y, const char cp[4], const float fp[4], int *zp, float *zpf) +/* used by node view too */ +void ED_image_draw_info(ARegion *ar, int color_manage, int channels, int x, int y, + const unsigned char cp[4], const float fp[4], int *zp, float *zpf) { char str[256]; float dx= 6; @@ -139,7 +141,7 @@ BLF_size(blf_mono_font, 11, 72); glColor3ub(255, 255, 255); - sprintf(str, "X:%-4d Y:%-4d |", x, y); + BLI_snprintf(str, sizeof(str), "X:%-4d Y:%-4d |", x, y); // UI_DrawString(6, 6, str); // works ok but fixed width is nicer. BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); @@ -147,14 +149,14 @@ if(zp) { glColor3ub(255, 255, 255); - sprintf(str, " Z:%-.4f |", 0.5f+0.5f*(((float)*zp)/(float)0x7fffffff)); + BLI_snprintf(str, sizeof(str), " Z:%-.4f |", 0.5f+0.5f*(((float)*zp)/(float)0x7fffffff)); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); } if(zpf) { glColor3ub(255, 255, 255); - sprintf(str, " Z:%-.3f |", *zpf); + BLI_snprintf(str, sizeof(str), " Z:%-.3f |", *zpf); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); @@ -163,33 +165,33 @@ if(channels >= 3) { glColor3ubv(red); if (fp) - sprintf(str, " R:%-.4f", fp[0]); + BLI_snprintf(str, sizeof(str), " R:%-.4f", fp[0]); else if (cp) - sprintf(str, " R:%-3d", cp[0]); + BLI_snprintf(str, sizeof(str), " R:%-3d", cp[0]); else - sprintf(str, " R:-"); + BLI_snprintf(str, sizeof(str), " R:-"); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); glColor3ubv(green); if (fp) - sprintf(str, " G:%-.4f", fp[1]); + BLI_snprintf(str, sizeof(str), " G:%-.4f", fp[1]); else if (cp) - sprintf(str, " G:%-3d", cp[1]); + BLI_snprintf(str, sizeof(str), " G:%-3d", cp[1]); else - sprintf(str, " G:-"); + BLI_snprintf(str, sizeof(str), " G:-"); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); glColor3ubv(blue); if (fp) - sprintf(str, " B:%-.4f", fp[2]); + BLI_snprintf(str, sizeof(str), " B:%-.4f", fp[2]); else if (cp) - sprintf(str, " B:%-3d", cp[2]); + BLI_snprintf(str, sizeof(str), " B:%-3d", cp[2]); else - sprintf(str, " B:-"); + BLI_snprintf(str, sizeof(str), " B:-"); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); @@ -197,11 +199,11 @@ if(channels == 4) { glColor3ub(255, 255, 255); if (fp) - sprintf(str, " A:%-.4f", fp[3]); + BLI_snprintf(str, sizeof(str), " A:%-.4f", fp[3]); else if (cp) - sprintf(str, " A:%-3d", cp[3]); + BLI_snprintf(str, sizeof(str), " A:%-3d", cp[3]); else - sprintf(str, "- "); + BLI_snprintf(str, sizeof(str), "- "); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); @@ -210,39 +212,46 @@ /* color rectangle */ if (channels==1) { - if (fp) + if (fp) { col[0] = col[1] = col[2] = fp[0]; - else if (cp) + } + else if (cp) { col[0] = col[1] = col[2] = (float)cp[0]/255.0f; - else + } + else { col[0] = col[1] = col[2] = 0.0f; + } + col[3] = 1.0f; } else if (channels==3) { - if (fp) + if (fp) { copy_v3_v3(col, fp); + } else if (cp) { - col[0] = (float)cp[0]/255.0f; - col[1] = (float)cp[1]/255.0f; - col[2] = (float)cp[2]/255.0f; + rgb_uchar_to_float(col, cp); } - else + else { zero_v3(col); + } + col[3] = 1.0f; } else if (channels==4) { if (fp) copy_v4_v4(col, fp); else if (cp) { - col[0] = (float)cp[0]/255.0f; - col[1] = (float)cp[1]/255.0f; - col[2] = (float)cp[2]/255.0f; - col[3] = (float)cp[3]/255.0f; + rgba_uchar_to_float(col, cp); } - else + else { zero_v4(col); + } } + else { + BLI_assert(0); + zero_v4(col); + } + if (color_manage) { - linearrgb_to_srgb_v3_v3(finalcol, col); - finalcol[3] = col[3]; + linearrgb_to_srgb_v4(finalcol, col); } else { copy_v4_v4(finalcol, col); @@ -269,12 +278,12 @@ rgb_to_yuv((float)cp[0]/255.0f, (float)cp[0]/255.0f, (float)cp[0]/255.0f, &lum, &u, &v); } - sprintf(str, "V:%-.4f", val); + BLI_snprintf(str, sizeof(str), "V:%-.4f", val); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); - sprintf(str, " L:%-.4f", lum); + BLI_snprintf(str, sizeof(str), " L:%-.4f", lum); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); @@ -289,22 +298,22 @@ rgb_to_yuv((float)cp[0]/255.0f, (float)cp[1]/255.0f, (float)cp[2]/255.0f, &lum, &u, &v); } - sprintf(str, "H:%-.4f", hue); + BLI_snprintf(str, sizeof(str), "H:%-.4f", hue); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); - sprintf(str, " S:%-.4f", sat); + BLI_snprintf(str, sizeof(str), " S:%-.4f", sat); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); - sprintf(str, " V:%-.4f", val); + BLI_snprintf(str, sizeof(str), " V:%-.4f", val); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); - sprintf(str, " L:%-.4f", lum); + BLI_snprintf(str, sizeof(str), " L:%-.4f", lum); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); @@ -378,14 +387,14 @@ { GLubyte checker_stipple[32*32/8] = { - 255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0, \ - 255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0, \ - 255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0, \ - 255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0, \ - 0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255, \ - 0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255, \ - 0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255, \ - 0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255, \ + 255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0, + 255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0, + 255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0, + 255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0, + 0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255, + 0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255, + 0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255, + 0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255, }; glColor3ubv(col1); diff -Nru blender-2.61/source/blender/editors/space_image/image_intern.h blender-2.62/source/blender/editors/space_image/image_intern.h --- blender-2.61/source/blender/editors/space_image/image_intern.h 2011-12-13 19:54:11.000000000 +0000 +++ blender-2.62/source/blender/editors/space_image/image_intern.h 2012-02-15 19:38:24.000000000 +0000 @@ -55,7 +55,6 @@ /* image_draw.c */ void draw_image_main(struct SpaceImage *sima, struct ARegion *ar, struct Scene *scene); -void draw_image_info(struct ARegion *ar, int color_manage, int channels, int x, int y, const char cp[4], const float fp[4], int *zp, float *zpf); void draw_image_grease_pencil(struct bContext *C, short onlyv2d); /* image_ops.c */ diff -Nru blender-2.61/source/blender/editors/space_image/image_ops.c blender-2.62/source/blender/editors/space_image/image_ops.c --- blender-2.61/source/blender/editors/space_image/image_ops.c 2011-12-13 19:54:11.000000000 +0000 +++ blender-2.62/source/blender/editors/space_image/image_ops.c 2012-02-15 19:38:24.000000000 +0000 @@ -178,6 +178,30 @@ return 0; } +/* For IMAGE_OT_curves_point_set to avoid sampling when in uv smooth mode */ +int space_image_main_area_not_uv_brush_poll(bContext *C) +{ + SpaceImage *sima= CTX_wm_space_image(C); + + ToolSettings *toolsettings = CTX_data_scene(C)->toolsettings; + if(sima && !toolsettings->uvsculpt) + return 1; + + return 0; +} + +static int space_image_image_sample_poll(bContext *C) +{ + SpaceImage *sima= CTX_wm_space_image(C); + Object *obedit= CTX_data_edit_object(C); + ToolSettings *toolsettings = CTX_data_scene(C)->toolsettings; + + if(obedit){ + if(ED_space_image_show_uvedit(sima, obedit) && (toolsettings->use_uv_sculpt)) + return 0; + } + return space_image_main_area_poll(C); +} /********************** view pan operator *********************/ typedef struct ViewPanData { @@ -570,7 +594,7 @@ /* retrieve state */ sima= CTX_wm_space_image(C); ar= CTX_wm_region(C); - scene= (Scene*)CTX_data_scene(C); + scene= CTX_data_scene(C); obedit= CTX_data_edit_object(C); ima= ED_space_image(sima); @@ -817,7 +841,7 @@ if(ima) path= ima->name; - if(RNA_property_is_set(op->ptr, "filepath")) + if(RNA_struct_property_is_set(op->ptr, "filepath")) return image_open_exec(C, op); image_open_init(C, op); @@ -844,7 +868,7 @@ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH); + WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); } /******************** replace image operator ********************/ @@ -858,7 +882,9 @@ return OPERATOR_CANCELLED; RNA_string_get(op->ptr, "filepath", str); - BLI_strncpy(sima->image->name, str, sizeof(sima->image->name)); /* we cant do much if the str is longer then 240 :/ */ + + /* we cant do much if the str is longer then FILE_MAX :/ */ + BLI_strncpy(sima->image->name, str, sizeof(sima->image->name)); /* XXX unpackImage frees image buffers */ ED_preview_kill_jobs(C); @@ -876,10 +902,10 @@ if(!sima->image) return OPERATOR_CANCELLED; - if(RNA_property_is_set(op->ptr, "filepath")) + if(RNA_struct_property_is_set(op->ptr, "filepath")) return image_replace_exec(C, op); - if(!RNA_property_is_set(op->ptr, "relative_path")) + if(!RNA_struct_property_is_set(op->ptr, "relative_path")) RNA_boolean_set(op->ptr, "relative_path", (strncmp(sima->image->name, "//", 2))==0); image_filesel(C, op, sima->image->name); @@ -902,7 +928,7 @@ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH); + WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); } /******************** save image as operator ********************/ @@ -1011,7 +1037,7 @@ simopts->im_format= *(ImageFormatData *)op->customdata; } - if (RNA_property_is_set(op->ptr, "filepath")) { + if (RNA_struct_property_is_set(op->ptr, "filepath")) { RNA_string_get(op->ptr, "filepath", simopts->filepath); BLI_path_abs(simopts->filepath, G.main->name); } @@ -1176,7 +1202,7 @@ Scene *scene= CTX_data_scene(C); SaveImageOptions simopts; - if(RNA_property_is_set(op->ptr, "filepath")) + if(RNA_struct_property_is_set(op->ptr, "filepath")) return image_save_as_exec(C, op); if (save_image_options_init(&simopts, sima, scene, TRUE) == 0) @@ -1184,7 +1210,7 @@ save_image_options_to_op(&simopts, op); /* enable save_copy by default for render results */ - if(ELEM(ima->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE) && !RNA_property_is_set(op->ptr, "copy")) { + if(ELEM(ima->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE) && !RNA_struct_property_is_set(op->ptr, "copy")) { RNA_boolean_set(op->ptr, "copy", TRUE); } @@ -1252,7 +1278,7 @@ /* properties */ RNA_def_boolean(ot->srna, "copy", 0, "Copy", "Create a new image file without modifying the current image in blender"); - WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH); + WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); } /******************** save image operator ********************/ @@ -1419,7 +1445,7 @@ /* retrieve state */ sima= CTX_wm_space_image(C); - scene= (Scene*)CTX_data_scene(C); + scene= CTX_data_scene(C); obedit= CTX_data_edit_object(C); RNA_string_get(op->ptr, "name", name); @@ -1676,7 +1702,7 @@ int method= RNA_enum_get(op->ptr, "method"); /* find the suppplied image by name */ - if (RNA_property_is_set(op->ptr, "id")) { + if (RNA_struct_property_is_set(op->ptr, "id")) { char imaname[MAX_ID_NAME-2]; RNA_string_get(op->ptr, "id", imaname); ima = BLI_findstring(&CTX_data_main(C)->image, imaname, offsetof(ID, name) + 2); @@ -1708,7 +1734,7 @@ { Image *ima= CTX_data_edit_image(C); - if(RNA_property_is_set(op->ptr, "id")) + if(RNA_struct_property_is_set(op->ptr, "id")) return image_unpack_exec(C, op); if(!ima || !ima->packedfile) @@ -1754,12 +1780,12 @@ int x, y; int channels; - char col[4]; + unsigned char col[4]; float colf[4]; int z; float zf; - char *colp; + unsigned char *colp; float *colfp; int *zp; float *zfp; @@ -1772,7 +1798,7 @@ ImageSampleInfo *info= arg_info; if(info->draw) { /* no color management needed for images (color_manage=0) */ - draw_image_info(ar, 0, info->channels, info->x, info->y, info->colp, info->colfp, info->zp, info->zfp); + ED_image_draw_info(ar, 0, info->channels, info->x, info->y, info->colp, info->colfp, info->zp, info->zfp); } } @@ -1794,7 +1820,7 @@ if(fx>=0.0f && fy>=0.0f && fx<1.0f && fy<1.0f) { float *fp; - char *cp; + unsigned char *cp; int x= (int)(fx*ibuf->x), y= (int)(fy*ibuf->y); CLAMP(x, 0, ibuf->x-1); @@ -1811,7 +1837,7 @@ info->zfp= NULL; if(ibuf->rect) { - cp= (char *)(ibuf->rect + y*ibuf->x + x); + cp= (unsigned char *)(ibuf->rect + y*ibuf->x + x); info->col[0]= cp[0]; info->col[1]= cp[1]; @@ -1947,7 +1973,7 @@ ot->invoke= image_sample_invoke; ot->modal= image_sample_modal; ot->cancel= image_sample_cancel; - ot->poll= space_image_main_area_poll; + ot->poll= space_image_image_sample_poll; /* flags */ ot->flag= OPTYPE_BLOCKING; @@ -2016,14 +2042,14 @@ hist->data_r[i] = rgb[0]; hist->data_g[i] = rgb[1]; hist->data_b[i] = rgb[2]; - hist->data_luma[i] = (0.299f*rgb[0] + 0.587f*rgb[1] + 0.114f*rgb[2]); + hist->data_luma[i] = rgb_to_luma(rgb); } else if (ibuf->rect) { cp= (unsigned char *)(ibuf->rect + y*ibuf->x + x); hist->data_r[i] = (float)cp[0]/255.0f; hist->data_g[i] = (float)cp[1]/255.0f; hist->data_b[i] = (float)cp[2]/255.0f; - hist->data_luma[i] = (0.299f*cp[0] + 0.587f*cp[1] + 0.114f*cp[2])/255; + hist->data_luma[i] = (float)rgb_to_luma_byte(cp)/255.0f; } } } @@ -2084,7 +2110,7 @@ ot->invoke= image_sample_invoke; ot->modal= image_sample_modal; ot->cancel= image_sample_cancel; - ot->poll= space_image_main_area_poll; + ot->poll= space_image_main_area_not_uv_brush_poll; /* properties */ RNA_def_enum(ot->srna, "point", point_items, 0, "Point", "Set black point or white point for curves"); diff -Nru blender-2.61/source/blender/editors/space_image/space_image.c blender-2.62/source/blender/editors/space_image/space_image.c --- blender-2.61/source/blender/editors/space_image/space_image.c 2011-12-13 19:54:11.000000000 +0000 +++ blender-2.62/source/blender/editors/space_image/space_image.c 2012-02-15 19:38:24.000000000 +0000 @@ -543,7 +543,7 @@ /* toggle editmode is handy to have while UV unwrapping */ kmi= WM_keymap_add_item(keymap, "OBJECT_OT_mode_set", TABKEY, KM_PRESS, 0, 0); RNA_enum_set(kmi->ptr, "mode", OB_MODE_EDIT); - RNA_boolean_set(kmi->ptr, "toggle", 1); + RNA_boolean_set(kmi->ptr, "toggle", TRUE); } /* dropboxes */ @@ -581,7 +581,7 @@ ima= ED_space_image(sima); if(sima->iuser.flag & IMA_ANIM_ALWAYS) - BKE_image_user_calc_frame(&sima->iuser, CTX_data_scene(C)->r.cfra, 0); + BKE_image_user_calc_frame(&sima->iuser, scene->r.cfra, 0); /* check if we have to set the image from the editmesh */ if(ima && (ima->source==IMA_SRC_VIEWER || sima->pin)); @@ -594,8 +594,13 @@ /* new shading system, get image from material */ EditFace *efa= EM_get_actFace(em, sloppy); - if(efa) - ED_object_get_active_image(obedit, efa->mat_nr, &sima->image, NULL, NULL); + if(efa) { + Image *node_ima; + ED_object_get_active_image(obedit, efa->mat_nr, &node_ima, NULL, NULL); + + if(node_ima) + sima->image= node_ima; + } } else { /* old shading system, we set texface */ @@ -768,6 +773,9 @@ keymap= WM_keymap_find(wm->defaultconf, "UV Editor", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); + keymap= WM_keymap_find(wm->defaultconf, "UV Sculpt", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + /* own keymaps */ keymap= WM_keymap_find(wm->defaultconf, "Image Generic", SPACE_IMAGE, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); @@ -780,6 +788,7 @@ { /* draw entirely, view changes should be handled here */ SpaceImage *sima= CTX_wm_space_image(C); + Object *obact= CTX_data_active_object(C); Object *obedit= CTX_data_edit_object(C); Scene *scene= CTX_data_scene(C); View2D *v2d= &ar->v2d; @@ -805,7 +814,7 @@ /* and uvs in 0.0-1.0 space */ UI_view2d_view_ortho(v2d); - draw_uvedit_main(sima, ar, scene, obedit); + draw_uvedit_main(sima, ar, scene, obedit, obact); ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW); diff -Nru blender-2.61/source/blender/editors/space_info/info_ops.c blender-2.62/source/blender/editors/space_info/info_ops.c --- blender-2.61/source/blender/editors/space_info/info_ops.c 2011-12-13 19:52:01.000000000 +0000 +++ blender-2.62/source/blender/editors/space_info/info_ops.c 2012-02-15 19:36:41.000000000 +0000 @@ -124,7 +124,7 @@ {PF_USE_ORIGINAL, "USE_ORIGINAL", 0, "Use files in original location (create when necessary)", ""}, {PF_WRITE_ORIGINAL, "WRITE_ORIGINAL", 0, "Write files to original location (overwrite existing files)", ""}, {PF_KEEP, "KEEP", 0, "Disable AutoPack, keep all packed files", ""}, - {PF_ASK, "ASK", 0, "Ask for each file", ""}, + /* {PF_ASK, "ASK", 0, "Ask for each file", ""}, */ {0, NULL, 0, NULL, NULL}}; static int unpack_all_exec(bContext *C, wmOperator *op) @@ -143,7 +143,7 @@ Main *bmain= CTX_data_main(C); uiPopupMenu *pup; uiLayout *layout; - char title[128]; + char title[64]; int count = 0; count = countPackedFiles(bmain); @@ -155,9 +155,9 @@ } if(count == 1) - sprintf(title, "Unpack 1 file"); + strcpy(title, "Unpack 1 file"); else - sprintf(title, "Unpack %d files", count); + BLI_snprintf(title, sizeof(title), "Unpack %d files", count); pup= uiPupMenuBegin(C, title, ICON_NONE); layout= uiPupMenuLayout(pup); @@ -309,7 +309,7 @@ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - WM_operator_properties_filesel(ot, 0, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH); + WM_operator_properties_filesel(ot, 0, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); } /********************* report box operator *********************/ diff -Nru blender-2.61/source/blender/editors/space_logic/logic_ops.c blender-2.62/source/blender/editors/space_logic/logic_ops.c --- blender-2.61/source/blender/editors/space_logic/logic_ops.c 2011-12-13 19:54:36.000000000 +0000 +++ blender-2.62/source/blender/editors/space_logic/logic_ops.c 2012-02-15 19:38:50.000000000 +0000 @@ -88,15 +88,15 @@ static void edit_sensor_properties(wmOperatorType *ot) { - RNA_def_string(ot->srna, "sensor", "", 32, "Sensor", "Name of the sensor to edit"); - RNA_def_string(ot->srna, "object", "", 32, "Object", "Name of the object the sensor belongs to"); + RNA_def_string(ot->srna, "sensor", "", MAX_NAME, "Sensor", "Name of the sensor to edit"); + RNA_def_string(ot->srna, "object", "", MAX_NAME, "Object", "Name of the object the sensor belongs to"); } static int edit_sensor_invoke_properties(bContext *C, wmOperator *op) { PointerRNA ptr= CTX_data_pointer_get_type(C, "sensor", &RNA_Sensor); - if (RNA_property_is_set(op->ptr, "sensor") && RNA_property_is_set(op->ptr, "object") ) + if (RNA_struct_property_is_set(op->ptr, "sensor") && RNA_struct_property_is_set(op->ptr, "object") ) return 1; if (ptr.data) { @@ -113,14 +113,14 @@ static Object *edit_object_property_get(bContext *C, wmOperator *op) { - char ob_name[32]; + char ob_name[MAX_NAME]; Object *ob; RNA_string_get(op->ptr, "object", ob_name); /* if ob_name is valid try to find the object with this name otherwise gets the active object */ - if (BLI_strnlen(ob_name, 32) > 0) + if (BLI_strnlen(ob_name, MAX_NAME) > 0) ob = BLI_findstring(&(CTX_data_main(C)->object), ob_name, offsetof(ID, name) + 2); else ob= ED_object_active_context(C); @@ -130,7 +130,7 @@ static bSensor *edit_sensor_property_get(bContext *C, wmOperator *op, Object **ob) { - char sensor_name[32]; + char sensor_name[MAX_NAME]; bSensor *sens; RNA_string_get(op->ptr, "sensor", sensor_name); @@ -144,15 +144,15 @@ static void edit_controller_properties(wmOperatorType *ot) { - RNA_def_string(ot->srna, "controller", "", 32, "Controller", "Name of the controller to edit"); - RNA_def_string(ot->srna, "object", "", 32, "Object", "Name of the object the controller belongs to"); + RNA_def_string(ot->srna, "controller", "", MAX_NAME, "Controller", "Name of the controller to edit"); + RNA_def_string(ot->srna, "object", "", MAX_NAME, "Object", "Name of the object the controller belongs to"); } static int edit_controller_invoke_properties(bContext *C, wmOperator *op) { PointerRNA ptr= CTX_data_pointer_get_type(C, "controller", &RNA_Controller); - if (RNA_property_is_set(op->ptr, "controller") && RNA_property_is_set(op->ptr, "object") ) + if (RNA_struct_property_is_set(op->ptr, "controller") && RNA_struct_property_is_set(op->ptr, "object") ) return 1; if (ptr.data) { @@ -169,7 +169,7 @@ static bController *edit_controller_property_get(bContext *C, wmOperator *op, Object **ob) { - char controller_name[32]; + char controller_name[MAX_NAME]; bController *cont; RNA_string_get(op->ptr, "controller", controller_name); @@ -183,15 +183,15 @@ static void edit_actuator_properties(wmOperatorType *ot) { - RNA_def_string(ot->srna, "actuator", "", 32, "Actuator", "Name of the actuator to edit"); - RNA_def_string(ot->srna, "object", "", 32, "Object", "Name of the object the actuator belongs to"); + RNA_def_string(ot->srna, "actuator", "", MAX_NAME, "Actuator", "Name of the actuator to edit"); + RNA_def_string(ot->srna, "object", "", MAX_NAME, "Object", "Name of the object the actuator belongs to"); } static int edit_actuator_invoke_properties(bContext *C, wmOperator *op) { PointerRNA ptr= CTX_data_pointer_get_type(C, "actuator", &RNA_Actuator); - if (RNA_property_is_set(op->ptr, "actuator") && RNA_property_is_set(op->ptr, "object") ) + if (RNA_struct_property_is_set(op->ptr, "actuator") && RNA_struct_property_is_set(op->ptr, "object") ) return 1; if (ptr.data) { @@ -208,7 +208,7 @@ static bActuator *edit_actuator_property_get(bContext *C, wmOperator *op, Object **ob) { - char actuator_name[32]; + char actuator_name[MAX_NAME]; bActuator *act; RNA_string_get(op->ptr, "actuator", actuator_name); @@ -278,7 +278,7 @@ PointerRNA sens_ptr; PropertyRNA *prop; const char *sens_name; - char name[32]; + char name[MAX_NAME]; int type= RNA_enum_get(op->ptr, "type"); ob= edit_object_property_get(C, op); @@ -293,7 +293,7 @@ prop = RNA_struct_find_property(&sens_ptr, "type"); RNA_string_get(op->ptr, "name", name); - if(BLI_strnlen(name, 32) < 1){ + if(BLI_strnlen(name, MAX_NAME) < 1){ RNA_property_enum_name(C, &sens_ptr, prop, RNA_property_enum_get(&sens_ptr, prop), &sens_name); BLI_strncpy(sens->name, sens_name, sizeof(sens->name)); } @@ -328,8 +328,8 @@ /* properties */ ot->prop= prop= RNA_def_enum(ot->srna, "type", DummyRNA_NULL_items, SENS_ALWAYS, "Type", "Type of sensor to add"); RNA_def_enum_funcs(prop, rna_Sensor_type_itemf); - RNA_def_string(ot->srna, "name", "", 32, "Name", "Name of the Sensor to add"); - RNA_def_string(ot->srna, "object", "", 32, "Object", "Name of the Object to add the Sensor to"); + RNA_def_string(ot->srna, "name", "", MAX_NAME, "Name", "Name of the Sensor to add"); + RNA_def_string(ot->srna, "object", "", MAX_NAME, "Object", "Name of the Object to add the Sensor to"); } /* ************* Add/Remove Controller Operator ************* */ @@ -382,7 +382,7 @@ PropertyRNA *prop; const char *cont_name; int bit; - char name[32]; + char name[MAX_NAME]; int type= RNA_enum_get(op->ptr, "type"); ob= edit_object_property_get(C, op); @@ -397,7 +397,7 @@ prop = RNA_struct_find_property(&cont_ptr, "type"); RNA_string_get(op->ptr, "name", name); - if(BLI_strnlen(name, 32) < 1){ + if(BLI_strnlen(name, MAX_NAME) < 1){ RNA_property_enum_name(C, &cont_ptr, prop, RNA_property_enum_get(&cont_ptr, prop), &cont_name); BLI_strncpy(cont->name, cont_name, sizeof(cont->name)); } @@ -442,8 +442,8 @@ /* properties */ ot->prop= RNA_def_enum(ot->srna, "type", controller_type_items, CONT_LOGIC_AND, "Type", "Type of controller to add"); - RNA_def_string(ot->srna, "name", "", 32, "Name", "Name of the Controller to add"); - RNA_def_string(ot->srna, "object", "", 32, "Object", "Name of the Object to add the Controller to"); + RNA_def_string(ot->srna, "name", "", MAX_NAME, "Name", "Name of the Controller to add"); + RNA_def_string(ot->srna, "object", "", MAX_NAME, "Object", "Name of the Object to add the Controller to"); } /* ************* Add/Remove Actuator Operator ************* */ @@ -495,7 +495,7 @@ PointerRNA act_ptr; PropertyRNA *prop; const char *act_name; - char name[32]; + char name[MAX_NAME]; int type= RNA_enum_get(op->ptr, "type"); ob= edit_object_property_get(C, op); @@ -510,7 +510,7 @@ prop = RNA_struct_find_property(&act_ptr, "type"); RNA_string_get(op->ptr, "name", name); - if (BLI_strnlen(name, 32) < 1){ + if (BLI_strnlen(name, MAX_NAME) < 1){ RNA_property_enum_name(C, &act_ptr, prop, RNA_property_enum_get(&act_ptr, prop), &act_name); BLI_strncpy(act->name, act_name, sizeof(act->name)); } @@ -545,8 +545,8 @@ /* properties */ ot->prop= prop= RNA_def_enum(ot->srna, "type", DummyRNA_NULL_items, CONT_LOGIC_AND, "Type", "Type of actuator to add"); RNA_def_enum_funcs(prop, rna_Actuator_type_itemf); - RNA_def_string(ot->srna, "name", "", 32, "Name", "Name of the Actuator to add"); - RNA_def_string(ot->srna, "object", "", 32, "Object", "Name of the Object to add the Actuator to"); + RNA_def_string(ot->srna, "name", "", MAX_NAME, "Name", "Name of the Actuator to add"); + RNA_def_string(ot->srna, "object", "", MAX_NAME, "Object", "Name of the Object to add the Actuator to"); } /* ************* Move Logic Bricks Operator ************* */ diff -Nru blender-2.61/source/blender/editors/space_logic/logic_window.c blender-2.62/source/blender/editors/space_logic/logic_window.c --- blender-2.61/source/blender/editors/space_logic/logic_window.c 2011-12-13 19:54:36.000000000 +0000 +++ blender-2.62/source/blender/editors/space_logic/logic_window.c 2012-02-15 19:38:50.000000000 +0000 @@ -1187,7 +1187,7 @@ ts= sens->data; - /* uiDefBut(block, TEX, 1, "Property:", xco,yco-22,width, 19, &ts->name, 0, 31, 0, 0, "Only look for Objects with this property"); */ + /* uiDefBut(block, TEX, 1, "Property:", xco,yco-22,width, 19, &ts->name, 0, MAX_NAME, 0, 0, "Only look for Objects with this property"); */ uiDefIDPoinBut(block, test_matpoin_but, ID_MA, 1, "MA:",(short)(xco + 10),(short)(yco-44), (short)(width - 20), 19, &ts->ma, "Only look for floors with this Material"); ///* uiDefButF(block, NUM, 1, "Margin:", xco+width/2,yco-44,width/2, 19, &ts->dist, 0.0, 10.0, 100, 0, "Extra margin (distance) for larger sensitivity"); yco-= ysize; @@ -1216,11 +1216,11 @@ if (cs->mode & SENS_COLLISION_MATERIAL) { uiDefBut(block, TEX, 1, "Material:", (short)(xco + 10 + 0.40 * (width-20)), - (short)(yco-44), (short)(0.6*(width-20)), 19, &cs->materialName, 0, 31, 0, 0, + (short)(yco-44), (short)(0.6*(width-20)), 19, &cs->materialName, 0, MAX_NAME, 0, 0, "Only look for Objects with this material"); } else { uiDefBut(block, TEX, 1, "Property:", (short)(xco + 10 + 0.40 * (width-20)), (short)(yco-44), - (short)(0.6*(width-20)), 19, &cs->name, 0, 31, 0, 0, + (short)(0.6*(width-20)), 19, &cs->name, 0, MAX_NAME, 0, 0, "Only look for Objects with this property"); } @@ -1240,7 +1240,7 @@ ns= sens->data; uiDefBut(block, TEX, 1, "Property:",(short)(10+xco),(short)(yco-44), (short)(width-20), 19, - &ns->name, 0, 31, 0, 0, "Only look for Objects with this property"); + &ns->name, 0, MAX_NAME, 0, 0, "Only look for Objects with this property"); uiDefButF(block, NUM, 1, "Dist",(short)(10+xco),(short)(yco-68),(short)((width-22)/2), 19, &ns->dist, 0.0, 1000.0, 1000, 0, "Trigger distance"); uiDefButF(block, NUM, 1, "Reset",(short)(10+xco+(width-22)/2), (short)(yco-68), (short)((width-22)/2), 19, @@ -1261,7 +1261,7 @@ uiDefBut(block, TEX, 1, "Prop:", (short)(10+xco),(short)(yco-44), (short)(0.7 * (width-20)), 19, - &rs->name, 0, 31, 0, 0, + &rs->name, 0, MAX_NAME, 0, 0, "Only look for Objects with this property"); str = "Type %t|+X axis %x0|+Y axis %x1|+Z axis %x2|-X axis %x3|-Y axis %x4|-Z axis %x5"; @@ -1316,14 +1316,14 @@ /* line 4: toggle property for string logging mode */ uiDefBut(block, TEX, 1, "LogToggle: ", xco+10, yco-((ks->type&1) ? 68:92), (width-20), 19, - ks->toggleName, 0, 31, 0, 0, + ks->toggleName, 0, MAX_NAME, 0, 0, "Property that indicates whether to log " "keystrokes as a string"); /* line 5: target property for string logging mode */ uiDefBut(block, TEX, 1, "Target: ", xco+10, yco-((ks->type&1) ? 92:116), (width-20), 19, - ks->targetName, 0, 31, 0, 0, + ks->targetName, 0, MAX_NAME, 0, 0, "Property that receives the keystrokes in case " "a string is logged"); @@ -1349,21 +1349,21 @@ if (ps->type != SENS_PROP_EXPRESSION) { uiDefBut(block, TEX, 1, "Prop: ", xco+30,yco-68,width-60, 19, - ps->name, 0, 31, 0, 0, "Property name"); + ps->name, 0, MAX_NAME, 0, 0, "Property name"); } if(ps->type == SENS_PROP_INTERVAL) { uiDefBut(block, TEX, 1, "Min: ", xco,yco-92,width/2, 19, - ps->value, 0, 31, 0, 0, "check for min value"); + ps->value, 0, MAX_NAME, 0, 0, "check for min value"); uiDefBut(block, TEX, 1, "Max: ", xco+width/2,yco-92,width/2, 19, - ps->maxvalue, 0, 31, 0, 0, "check for max value"); + ps->maxvalue, 0, MAX_NAME, 0, 0, "check for max value"); } else if(ps->type == SENS_PROP_CHANGED); else { uiDefBut(block, TEX, 1, "Value: ", xco+30,yco-92,width-60, 19, - ps->value, 0, 31, 0, 0, "check for value"); + ps->value, 0, MAX_NAME, 0, 0, "check for value"); } yco-= ysize; @@ -1384,12 +1384,12 @@ uiBlockBeginAlign(block); but = uiDefBut(block, TEX, 1, "Bone: ", (xco+10), (yco-44), (width-20)/2, 19, - arm->posechannel, 0, 31, 0, 0, + arm->posechannel, 0, MAX_NAME, 0, 0, "Bone on which you want to check a constraint"); uiButSetFunc(but, check_armature_sensor, but, arm); but = uiDefBut(block, TEX, 1, "Cons: ", (xco+10)+(width-20)/2, (yco-44), (width-20)/2, 19, - arm->constraint, 0, 31, 0, 0, + arm->constraint, 0, MAX_NAME, 0, 0, "Name of the constraint you want to control"); uiButSetFunc(but, check_armature_sensor, but, arm); uiBlockEndAlign(block); @@ -1420,7 +1420,7 @@ as= sens->data; uiDefBut(block, TEX, 1, "Act: ", xco+30,yco-44,width-60, 19, - as->name, 0, 31, 0, 0, "Actuator name, actuator active state modifications will be detected"); + as->name, 0, MAX_NAME, 0, 0, "Actuator name, actuator active state modifications will be detected"); yco-= ysize; break; } @@ -1513,13 +1513,13 @@ if (raySens->mode & SENS_COLLISION_MATERIAL) { uiDefBut(block, TEX, 1, "Material:", xco + 10 + 0.20 * (width-20), yco-44, 0.8*(width-20), 19, - &raySens->matname, 0, 31, 0, 0, + &raySens->matname, 0, MAX_NAME, 0, 0, "Only look for Objects with this material"); } else { uiDefBut(block, TEX, 1, "Property:", xco + 10 + 0.20 * (width-20), yco-44, 0.8*(width-20), 19, - &raySens->propname, 0, 31, 0, 0, + &raySens->propname, 0, MAX_NAME, 0, 0, "Only look for Objects with this property"); } @@ -1557,7 +1557,7 @@ /* line 2: Subject filter */ uiDefBut(block, TEX, 1, "Subject: ", (xco+10), (yco-44), (width-20), 19, - mes->subject, 0, 31, 0, 0, + mes->subject, 0, MAX_NAME, 0, 0, "Optional subject filter: only accept messages with this subject" ", or empty for all"); @@ -1683,7 +1683,7 @@ ec= cont->data; /* uiDefBut(block, BUT, 1, "Variables", xco,yco-24,80, 19, NULL, 0, 0, 0, 0, "Available variables for expression"); */ uiDefBut(block, TEX, 1, "Exp:", xco + 10 , yco-21, width-20, 19, - ec->str, 0, 127, 0, 0, + ec->str, 0, sizeof(ec->str), 0, 0, "Expression"); yco-= ysize; @@ -1704,7 +1704,7 @@ if(pc->mode==0) uiDefIDPoinBut(block, test_scriptpoin_but, ID_TXT, 1, "", xco+70,yco-23,width-74, 19, &pc->text, "Blender textblock to run as a script"); else { - uiDefBut(block, TEX, 1, "", xco+70,yco-23,(width-70)-25, 19, pc->module, 0, 63, 0, 0, "Module name and function to run e.g. \"someModule.main\". Internal texts and external python files can be used"); + uiDefBut(block, TEX, 1, "", xco+70,yco-23,(width-70)-25, 19, pc->module, 0, sizeof(pc->module), 0, 0, "Module name and function to run e.g. \"someModule.main\". Internal texts and external python files can be used"); uiDefButBitI(block, TOG, CONT_PY_DEBUG, B_REDR, "D", (xco+width)-25, yco-23, 19, 19, &pc->flag, 0, 0, 0, 0, "Continuously reload the module from disk for editing external modules without restarting"); } uiBlockEndAlign(block); @@ -2032,7 +2032,7 @@ if(aa->type == ACT_ACTION_FROM_PROP) { - uiDefBut(block, TEX, 0, "Prop: ",xco+10, yco-44, width-20, 19, aa->name, 0.0, 31.0, 0, 0, "Use this property to define the Action position"); + uiDefBut(block, TEX, 0, "Prop: ",xco+10, yco-44, width-20, 19, aa->name, 0.0, MAX_NAME, 0, 0, "Use this property to define the Action position"); } else { @@ -2043,7 +2043,7 @@ uiDefButS(block, NUM, 0, "Blendin: ", xco+10, yco-64, (width-20)/2, 19, &aa->blendin, 0.0, 32767, 0.0, 0.0, "Number of frames of motion blending"); uiDefButS(block, NUM, 0, "Priority: ", xco+10+(width-20)/2, yco-64, (width-20)/2, 19, &aa->priority, 0.0, 100.0, 0.0, 0.0, "Execution priority - lower numbers will override actions with higher numbers, With 2 or more actions at once, the overriding channels must be lower in the stack"); - uiDefBut(block, TEX, 0, "FrameProp: ",xco+10, yco-84, width-20, 19, aa->frameProp, 0.0, 31.0, 0, 0, "Assign the action's current frame number to this property"); + uiDefBut(block, TEX, 0, "FrameProp: ",xco+10, yco-84, width-20, 19, aa->frameProp, 0.0, MAX_NAME, 0, 0, "Assign the action's current frame number to this property"); #ifdef __NLA_ACTION_BY_MOTION_ACTUATOR @@ -2094,7 +2094,7 @@ if(ia->type==ACT_IPO_FROM_PROP) { uiDefBut(block, TEX, 0, "Prop: ", xco+10, yco-44, width-80, 19, - ia->name, 0.0, 31.0, 0, 0, + ia->name, 0.0, MAX_NAME, 0, 0, "Use this property to define the Ipo position"); } else { @@ -2113,7 +2113,7 @@ "Update IPO on all children Objects as well"); uiDefBut(block, TEX, 0, "FrameProp: ", xco+10, yco-64, width-20, 19, - ia->frameProp, 0.0, 31.0, 0, 0, + ia->frameProp, 0.0, MAX_NAME, 0, 0, "Assign the action's current frame number to this property"); yco-= ysize; @@ -2131,7 +2131,7 @@ str= "Type%t|Assign%x0|Add %x1|Copy %x2|Toggle (bool/int/float/timer)%x3"; uiDefButI(block, MENU, B_REDR, str, xco+30,yco-24,width-60, 19, &pa->type, 0, 31, 0, 0, "Type"); - uiDefBut(block, TEX, 1, "Prop: ", xco+30,yco-44,width-60, 19, pa->name, 0, 31, 0, 0, "Property name"); + uiDefBut(block, TEX, 1, "Prop: ", xco+30,yco-44,width-60, 19, pa->name, 0, MAX_NAME, 0, 0, "Property name"); if(pa->type==ACT_PROP_TOGGLE) { @@ -2140,10 +2140,10 @@ } else if(pa->type==ACT_PROP_COPY) { uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+10, yco-64, (width-20)/2, 19, &(pa->ob), "Copy from this Object"); - uiDefBut(block, TEX, 1, "Prop: ", xco+10+(width-20)/2, yco-64, (width-20)/2, 19, pa->value, 0, 31, 0, 0, "Copy this property"); + uiDefBut(block, TEX, 1, "Prop: ", xco+10+(width-20)/2, yco-64, (width-20)/2, 19, pa->value, 0, MAX_NAME, 0, 0, "Copy this property"); } else { - uiDefBut(block, TEX, 1, "Value: ", xco+30,yco-64,width-60, 19, pa->value, 0, 31, 0, 0, "change with this value, use \"\" around strings"); + uiDefBut(block, TEX, 1, "Value: ", xco+30,yco-64,width-60, 19, pa->value, 0, MAX_NAME, 0, 0, "change with this value, use \"\" around strings"); } yco-= ysize; @@ -2175,7 +2175,7 @@ char dummy_str[] = "Sound mode %t|Play Stop %x0|Play End %x1|Loop Stop %x2|" "Loop End %x3|Loop Ping Pong Stop %x5|Loop Ping Pong %x4"; uiDefBut(block, TEX, B_IDNAME, "SO:",xco+30,yco-22,wval-20,19, - ((ID *)sa->sound)->name+2, 0.0, 21.0, 0, 0, ""); + ((ID *)sa->sound)->name+2, 0.0, MAX_ID_NAME-2, 0, 0, ""); uiDefButS(block, MENU, 1, dummy_str,xco+10,yco-44,width-20, 19, &sa->type, 0.0, 0.0, 0, 0, ""); uiDefButF(block, NUM, 0, "Volume:", xco+10,yco-66,wval, 19, &sa->volume, @@ -2397,13 +2397,13 @@ if (coa->flag & ACT_CONST_MATERIAL) { uiDefBut(block, TEX, 1, "Material:", xco + 50, yco-84, (width-60), 19, - coa->matprop, 0, 31, 0, 0, + coa->matprop, 0, MAX_NAME, 0, 0, "Ray detects only Objects with this material"); } else { uiDefBut(block, TEX, 1, "Property:", xco + 50, yco-84, (width-60), 19, - coa->matprop, 0, 31, 0, 0, + coa->matprop, 0, MAX_NAME, 0, 0, "Ray detect only Objects with this property"); } uiDefButBitS(block, TOG, ACT_CONST_PERMANENT, 0, "PER", xco+10, yco-103, 40, 19, @@ -2456,13 +2456,13 @@ if (coa->flag & ACT_CONST_MATERIAL) { uiDefBut(block, TEX, 1, "Material:", xco + 50, yco-84, (width-60), 19, - coa->matprop, 0, 31, 0, 0, + coa->matprop, 0, MAX_NAME, 0, 0, "Ray detects only Objects with this material"); } else { uiDefBut(block, TEX, 1, "Property:", xco + 50, yco-84, (width-60), 19, - coa->matprop, 0, 31, 0, 0, + coa->matprop, 0, MAX_NAME, 0, 0, "Ray detect only Objects with this property"); } uiDefButBitS(block, TOG, ACT_CONST_PERMANENT, 0, "PER", xco+10, yco-103, 40, 19, @@ -2554,8 +2554,8 @@ ysize = 48; glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - uiDefBut(block, TEX, 1, "File: ", xco+10, yco-44,width-20,19, &(gma->filename), 0, 63, 0, 0, "Load this blend file, use the \"//\" prefix for a path relative to the current blend file"); -// uiDefBut(block, TEX, 1, "Anim: ", xco+10, yco-64,width-20,19, &(gma->loadaniname), 0, 63, 0, 0, "Use this loadinganimation"); + uiDefBut(block, TEX, 1, "File: ", xco+10, yco-44,width-20,19, &(gma->filename), 0, sizeof(gma->filename), 0, 0, "Load this blend file, use the \"//\" prefix for a path relative to the current blend file"); +// uiDefBut(block, TEX, 1, "Anim: ", xco+10, yco-64,width-20,19, &(gma->loadaniname), 0, sizeof(gma->loadaniname), 0, 0, "Use this loadinganimation"); } /* else if (gma->type == ACT_GAME_START) { @@ -2563,8 +2563,8 @@ glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - uiDefBut(block, TEX, 1, "File: ", xco+10, yco-44,width-20,19, &(gma->filename), 0, 63, 0, 0, "Load this file"); - uiDefBut(block, TEX, 1, "Anim: ", xco+10, yco-64,width-20,19, &(gma->loadaniname), 0, 63, 0, 0, "Use this loadinganimation"); + uiDefBut(block, TEX, 1, "File: ", xco+10, yco-44,width-20,19, &(gma->filename), 0, sizeof(gma->filename), 0, 0, "Load this file"); + uiDefBut(block, TEX, 1, "Anim: ", xco+10, yco-64,width-20,19, &(gma->loadaniname), 0, sizeof(gma->loadaniname), 0, 0, "Use this loadinganimation"); } */ else if (ELEM4(gma->type, ACT_GAME_RESTART, ACT_GAME_QUIT, ACT_GAME_SAVECFG, ACT_GAME_LOADCFG)) { @@ -2592,11 +2592,11 @@ uiDefButS(block, MENU, 1, str, xco+20, yco-24, width-40, 19, &ga->type, 0, 0, 0, 0, ""); if(ga->type==ACT_GROUP_SET) { - uiDefBut(block, TEX, 0, "Key: ", xco+20, yco-44, (width-10)/2, 19, ga->name, 0.0, 31.0, 0, 0, "This name defines groupkey to be set"); + uiDefBut(block, TEX, 0, "Key: ", xco+20, yco-44, (width-10)/2, 19, ga->name, 0.0, MAX_NAME, 0, 0, "This name defines groupkey to be set"); uiDefButI(block, NUM, 0, "Frame:", xco+20+(width-10)/2, yco-44, (width-70)/2, 19, &ga->sta, 0.0, 2500.0, 0, 0, "Set this frame"); } else if(ga->type==ACT_GROUP_FROM_PROP) { - uiDefBut(block, TEX, 0, "Prop: ", xco+20, yco-44, width-40, 19, ga->name, 0.0, 31.0, 0, 0, "Use this property to define the Group position"); + uiDefBut(block, TEX, 0, "Prop: ", xco+20, yco-44, width-40, 19, ga->name, 0.0, MAX_NAME, 0, 0, "Use this property to define the Group position"); } else { uiDefButI(block, NUM, 0, "State", xco+20, yco-44, (width-40)/2, 19, &ga->sta, 0.0, 2500.0, 0, 0, "Start frame"); @@ -2698,7 +2698,7 @@ /* 3. property */ uiDefBut(block, TEX, 1, "Property:", (xco+10), yco-44, (width-20), 19, - &randAct->propname, 0, 31, 0, 0, + &randAct->propname, 0, MAX_NAME, 0, 0, "Assign the random value to this property"); /*4. and 5. arguments for the distribution*/ @@ -2789,13 +2789,13 @@ /* line 1: To */ uiDefBut(block, TEX, 1, "To: ", (xco+10), (yco-(myline++*24)), (width-20), 19, - &ma->toPropName, 0, 31, 0, 0, + &ma->toPropName, 0, MAX_NAME, 0, 0, "Optional send message to objects with this name only, or empty to broadcast"); /* line 2: Message Subject */ uiDefBut(block, TEX, 1, "Subject: ", (xco+10), (yco-(myline++*24)), (width-20), 19, - &ma->subject, 0, 31, 0, 0, + &ma->subject, 0, MAX_NAME, 0, 0, "Optional message subject. This is what can be filtered on"); /* line 3: Text/Property */ @@ -2809,14 +2809,14 @@ /* line 3: Message Body */ uiDefBut(block, TEX, 1, "Body: ", (xco+10+(0.20*(width-20))),(yco-(myline++*24)),(0.8*(width-20)),19, - &ma->body, 0, 31, 0, 0, + &ma->body, 0, MAX_NAME, 0, 0, "Optional message body Text"); } else { /* line 3: Property body (set by property) */ uiDefBut(block, TEX, 1, "Propname: ", (xco+10+(0.20*(width-20))),(yco-(myline++*24)),(0.8*(width-20)),19, - &ma->body, 0, 31, 0, 0, + &ma->body, 0, MAX_NAME, 0, 0, "The message body will be set by the Property Value"); } @@ -2923,12 +2923,12 @@ uiBlockBeginAlign(block); but = uiDefBut(block, TEX, 1, "Bone: ", (xco+5), (yco-44), (width-10)/2, 19, - armAct->posechannel, 0, 31, 0, 0, + armAct->posechannel, 0, MAX_NAME, 0, 0, "Bone on which the constraint is defined"); uiButSetFunc(but, check_armature_actuator, but, armAct); but = uiDefBut(block, TEX, 1, "Cons: ", (xco+5)+(width-10)/2, (yco-44), (width-10)/2, 19, - armAct->constraint, 0, 31, 0, 0, + armAct->constraint, 0, MAX_NAME, 0, 0, "Name of the constraint you want to control"); uiButSetFunc(but, check_armature_actuator, but, armAct); uiBlockEndAlign(block); @@ -2999,7 +2999,7 @@ uiBlock *block; int yco=0; - block= uiBeginBlock(C, ar, "filemenu", UI_EMBOSSP); + block= uiBeginBlock(C, ar, __func__, UI_EMBOSSP); uiBlockSetButmFunc(block, do_sensor_menu, NULL); uiDefBut(block, BUTM, 1, "Show Objects", 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, ""); @@ -3048,7 +3048,7 @@ uiBlock *block; int yco=0; - block= uiBeginBlock(C, ar, "filemenu", UI_EMBOSSP); + block= uiBeginBlock(C, ar, __func__, UI_EMBOSSP); uiBlockSetButmFunc(block, do_controller_menu, NULL); uiDefBut(block, BUTM, 1, "Show Objects", 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, ""); @@ -3097,7 +3097,7 @@ uiBlock *block; int xco=0; - block= uiBeginBlock(C, ar, "filemenu", UI_EMBOSSP); + block= uiBeginBlock(C, ar, __func__, UI_EMBOSSP); uiBlockSetButmFunc(block, do_actuator_menu, NULL); uiDefBut(block, BUTM, 1, "Show Objects", 0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, ""); @@ -3143,7 +3143,7 @@ short yco = 12, xco = 0, stbit, offset; - block= uiBeginBlock(C, ar, "Controller state mask", UI_EMBOSS); + block= uiBeginBlock(C, ar, __func__, UI_EMBOSS); /* use this for a fake extra empy space around the buttons */ uiDefBut(block, LABEL, 0, "", -5, -5, 200, 34, NULL, 0, 0, 0, 0, ""); @@ -3191,7 +3191,7 @@ uiBlock *block; short xco = 0; - block= uiBeginBlock(C, ar, "obstatemenu", UI_EMBOSSP); + block= uiBeginBlock(C, ar, __func__, UI_EMBOSSP); uiBlockSetButmFunc(block, do_object_state_menu, arg_obj); uiDefBut(block, BUTM, 1, "Set all bits", 0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, ""); @@ -3580,7 +3580,7 @@ bController *cont= (bController *)ptr->data; char state[3]; - sprintf(state, "%d", RNA_int_get(ptr, "states")); + BLI_snprintf(state, sizeof(state), "%d", RNA_int_get(ptr, "states")); box= uiLayoutBox(layout); row= uiLayoutRow(box, 0); @@ -4488,7 +4488,7 @@ uiLayout *layout, *row, *box; uiBlock *block; uiBut *but; - char name[32]; + char uiblockstr[32]; short a, count; int xco, yco, width; @@ -4497,8 +4497,8 @@ RNA_pointer_create(NULL, &RNA_SpaceLogicEditor, slogic, &logic_ptr); idar= get_selected_and_linked_obs(C, &count, slogic->scaflag); - sprintf(name, "buttonswin %p", (void *)ar); - block= uiBeginBlock(C, ar, name, UI_EMBOSS); + BLI_snprintf(uiblockstr, sizeof(uiblockstr), "buttonswin %p", (void *)ar); + block= uiBeginBlock(C, ar, uiblockstr, UI_EMBOSS); uiBlockSetHandleFunc(block, do_logic_buts, NULL); /* loop over all objects and set visible/linked flags for the logic bricks */ @@ -4802,7 +4802,7 @@ int a, iact, stbit, offset; int xco, yco, width, ycoo; short count; - char name[32]; + char numstr[32]; /* pin is a bool used for actuator and sensor drawing with states * pin so changing states dosnt hide the logic brick */ char pin; @@ -4815,8 +4815,8 @@ if(ob==NULL) return; // uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE); - sprintf(name, "buttonswin %p", (void *)ar); - block= uiBeginBlock(C, ar, name, UI_EMBOSS); + BLI_snprintf(numstr, sizeof(numstr), "buttonswin %p", (void *)ar); + block= uiBeginBlock(C, ar, numstr, UI_EMBOSS); uiBlockSetHandleFunc(block, do_logic_buts, NULL); RNA_pointer_create(NULL, &RNA_SpaceLogicEditor, slogic, &logic_ptr); @@ -4932,13 +4932,13 @@ uiDefIconButBitS(block, ICONTOG, CONT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, UI_UNIT_Y, &cont->flag, 0, 0, 0, 0, "Controller settings"); uiDefIconButBitS(block, TOG, CONT_PRIO, B_REDR, ICON_BOOKMARKS, (short)(xco+width-66), yco, 22, UI_UNIT_Y, &cont->flag, 0, 0, 0, 0, "Mark controller for execution before all non-marked controllers (good for startup scripts)"); - sprintf(name, "%d", first_bit(cont->state_mask)+1); - uiDefBlockBut(block, controller_state_mask_menu, cont, name, (short)(xco+width-44), yco, 22, UI_UNIT_Y, "Set controller state index (from 1 to 30)"); + sprintf(numstr, "%d", first_bit(cont->state_mask)+1); + uiDefBlockBut(block, controller_state_mask_menu, cont, numstr, (short)(xco+width-44), yco, 22, UI_UNIT_Y, "Set controller state index (from 1 to 30)"); if(cont->flag & CONT_SHOW) { cont->otype= cont->type; uiDefButS(block, MENU, B_CHANGE_CONT, controller_pup(),(short)(xco+22), yco, 70, UI_UNIT_Y, &cont->type, 0, 0, 0, 0, "Controller type"); - but= uiDefBut(block, TEX, 1, "", (short)(xco+92), yco, (short)(width-158), UI_UNIT_Y, cont->name, 0, 31, 0, 0, "Controller name"); + but= uiDefBut(block, TEX, 1, "", (short)(xco+92), yco, (short)(width-158), UI_UNIT_Y, cont->name, 0, MAX_NAME, 0, 0, "Controller name"); uiButSetFunc(but, make_unique_prop_names_cb, cont->name, (void*) 0); ycoo= yco; @@ -5030,7 +5030,7 @@ if(sens->flag & SENS_SHOW) { uiDefButS(block, MENU, B_CHANGE_SENS, sensor_pup(), (short)(xco+22), yco, 80, UI_UNIT_Y, &sens->type, 0, 0, 0, 0, "Sensor type"); - but= uiDefBut(block, TEX, 1, "", (short)(xco+102), yco, (short)(width-(pin?146:124)), UI_UNIT_Y, sens->name, 0, 31, 0, 0, "Sensor name"); + but= uiDefBut(block, TEX, 1, "", (short)(xco+102), yco, (short)(width-(pin?146:124)), UI_UNIT_Y, sens->name, 0, MAX_NAME, 0, 0, "Sensor name"); uiButSetFunc(but, make_unique_prop_names_cb, sens->name, (void*) 0); sens->otype= sens->type; @@ -5042,7 +5042,7 @@ glRecti(xco+22, yco, xco+width-22,yco+19); but= uiDefBut(block, LABEL, 0, sensor_name(sens->type), (short)(xco+22), yco, 80, UI_UNIT_Y, sens, 0, 0, 0, 0, ""); //uiButSetFunc(but, old_sca_move_sensor, sens, NULL); - but= uiDefBut(block, LABEL, 0, sens->name, (short)(xco+102), yco, (short)(width-(pin?146:124)), UI_UNIT_Y, sens, 0, 31, 0, 0, ""); + but= uiDefBut(block, LABEL, 0, sens->name, (short)(xco+102), yco, (short)(width-(pin?146:124)), UI_UNIT_Y, sens, 0, MAX_NAME, 0, 0, ""); //uiButSetFunc(but, old_sca_move_sensor, sens, NULL); uiBlockBeginAlign(block); @@ -5108,7 +5108,7 @@ if(act->flag & ACT_SHOW) { act->otype= act->type; uiDefButS(block, MENU, B_CHANGE_ACT, actuator_pup(ob), (short)(xco+22), yco, 90, UI_UNIT_Y, &act->type, 0, 0, 0, 0, "Actuator type"); - but= uiDefBut(block, TEX, 1, "", (short)(xco+112), yco, (short)(width-(pin?156:134)), UI_UNIT_Y, act->name, 0, 31, 0, 0, "Actuator name"); + but= uiDefBut(block, TEX, 1, "", (short)(xco+112), yco, (short)(width-(pin?156:134)), UI_UNIT_Y, act->name, 0, MAX_NAME, 0, 0, "Actuator name"); uiButSetFunc(but, make_unique_prop_names_cb, act->name, (void*) 0); ycoo= yco; diff -Nru blender-2.61/source/blender/editors/space_nla/nla_draw.c blender-2.62/source/blender/editors/space_nla/nla_draw.c --- blender-2.61/source/blender/editors/space_nla/nla_draw.c 2011-12-13 19:52:49.000000000 +0000 +++ blender-2.62/source/blender/editors/space_nla/nla_draw.c 2012-02-15 19:37:17.000000000 +0000 @@ -514,7 +514,7 @@ { const float ytol = 1.0f; /* small offset to vertical positioning of text, for legibility */ const char col[4] = {220, 220, 220, 255}; /* light grey */ - char str[32] = ""; + char numstr[32] = ""; /* Always draw times above the strip, whereas sequencer drew below + above. @@ -524,12 +524,12 @@ * while also preserving some accuracy, since we do use floats */ /* start frame */ - BLI_snprintf(str, sizeof(str), "%.1f", strip->start); - UI_view2d_text_cache_add(v2d, strip->start-1.0f, ymaxc+ytol, str, col); + BLI_snprintf(numstr, sizeof(numstr), "%.1f", strip->start); + UI_view2d_text_cache_add(v2d, strip->start-1.0f, ymaxc+ytol, numstr, col); /* end frame */ - BLI_snprintf(str, sizeof(str), "%.1f", strip->end); - UI_view2d_text_cache_add(v2d, strip->end, ymaxc+ytol, str, col); + BLI_snprintf(numstr, sizeof(numstr), "%.1f", strip->end); + UI_view2d_text_cache_add(v2d, strip->end, ymaxc+ytol, numstr, col); } /* ---------------------- */ @@ -715,7 +715,7 @@ } sel = SEL_NLT(nlt); - strcpy(name, nlt->name); + BLI_strncpy(name, nlt->name, sizeof(name)); // draw manually still doDraw= 1; @@ -958,7 +958,7 @@ draw_nla_channel_list_gl(ac, &anim_data, v2d, y); } { /* second pass: UI widgets */ - uiBlock *block= uiBeginBlock(C, ar, "NLA channel buttons", UI_EMBOSS); + uiBlock *block= uiBeginBlock(C, ar, __func__, UI_EMBOSS); size_t channel_index = 0; y= (float)(-NLACHANNEL_HEIGHT(snla)); diff -Nru blender-2.61/source/blender/editors/space_nla/nla_ops.c blender-2.62/source/blender/editors/space_nla/nla_ops.c --- blender-2.61/source/blender/editors/space_nla/nla_ops.c 2011-12-13 19:52:49.000000000 +0000 +++ blender-2.62/source/blender/editors/space_nla/nla_ops.c 2012-02-15 19:37:17.000000000 +0000 @@ -169,17 +169,23 @@ static void nla_keymap_channels(wmKeyMap *keymap) { + wmKeyMapItem *kmi; + /* NLA-specific (different to standard channels keymap) -------------------------- */ /* selection */ /* click-select */ // XXX for now, only leftmouse.... - WM_keymap_add_item(keymap, "NLA_OT_channels_click", LEFTMOUSE, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "NLA_OT_channels_click", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", 1); + kmi = WM_keymap_add_item(keymap, "NLA_OT_channels_click", LEFTMOUSE, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + kmi = WM_keymap_add_item(keymap, "NLA_OT_channels_click", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "extend", TRUE); /* channel operations */ /* add tracks */ - WM_keymap_add_item(keymap, "NLA_OT_tracks_add", AKEY, KM_PRESS, KM_SHIFT, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "NLA_OT_tracks_add", AKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "above_selected", 1); + kmi = WM_keymap_add_item(keymap, "NLA_OT_tracks_add", AKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "above_selected", FALSE); + kmi = WM_keymap_add_item(keymap, "NLA_OT_tracks_add", AKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "above_selected", TRUE); /* delete tracks */ WM_keymap_add_item(keymap, "NLA_OT_delete_tracks", XKEY, KM_PRESS, 0, 0); @@ -192,28 +198,39 @@ /* selection */ /* click select */ - WM_keymap_add_item(keymap, "NLA_OT_click_select", SELECTMOUSE, KM_PRESS, 0, 0); + kmi = WM_keymap_add_item(keymap, "NLA_OT_click_select", SELECTMOUSE, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); kmi= WM_keymap_add_item(keymap, "NLA_OT_click_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0); - RNA_boolean_set(kmi->ptr, "extend", 1); + RNA_boolean_set(kmi->ptr, "extend", TRUE); /* select left/right */ - WM_keymap_add_item(keymap, "NLA_OT_select_leftright", SELECTMOUSE, KM_PRESS, KM_CTRL, 0); + kmi = WM_keymap_add_item(keymap, "NLA_OT_select_leftright", SELECTMOUSE, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + RNA_enum_set(kmi->ptr, "mode", NLAEDIT_LRSEL_TEST); kmi= WM_keymap_add_item(keymap, "NLA_OT_select_leftright", SELECTMOUSE, KM_PRESS, KM_CTRL|KM_SHIFT, 0); - RNA_boolean_set(kmi->ptr, "extend", 1); + RNA_boolean_set(kmi->ptr, "extend", TRUE); + RNA_enum_set(kmi->ptr, "mode", NLAEDIT_LRSEL_TEST); kmi= WM_keymap_add_item(keymap, "NLA_OT_select_leftright", LEFTBRACKETKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); RNA_enum_set(kmi->ptr, "mode", NLAEDIT_LRSEL_LEFT); kmi= WM_keymap_add_item(keymap, "NLA_OT_select_leftright", RIGHTBRACKETKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); RNA_enum_set(kmi->ptr, "mode", NLAEDIT_LRSEL_RIGHT); /* deselect all */ - WM_keymap_add_item(keymap, "NLA_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "NLA_OT_select_all_toggle", IKEY, KM_PRESS, KM_CTRL, 0)->ptr, "invert", 1); + /* TODO: uniformize with other select_all ops? */ + kmi = WM_keymap_add_item(keymap, "NLA_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "invert", FALSE); + kmi = WM_keymap_add_item(keymap, "NLA_OT_select_all_toggle", IKEY, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "invert", TRUE); /* borderselect */ - WM_keymap_add_item(keymap, "NLA_OT_select_border", BKEY, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "NLA_OT_select_border", BKEY, KM_PRESS, KM_ALT, 0)->ptr, "axis_range", 1); + kmi = WM_keymap_add_item(keymap, "NLA_OT_select_border", BKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "axis_range", FALSE); + kmi = WM_keymap_add_item(keymap, "NLA_OT_select_border", BKEY, KM_PRESS, KM_ALT, 0); + RNA_boolean_set(kmi->ptr, "axis_range", TRUE); /* view*/ /* auto-set range */ diff -Nru blender-2.61/source/blender/editors/space_node/drawnode.c blender-2.62/source/blender/editors/space_node/drawnode.c --- blender-2.61/source/blender/editors/space_node/drawnode.c 2011-12-13 19:54:16.000000000 +0000 +++ blender-2.62/source/blender/editors/space_node/drawnode.c 2012-02-15 19:38:25.000000000 +0000 @@ -132,7 +132,7 @@ uiBlock *block; uiLayout *layout; - block= uiBeginBlock(C, ar, "socket menu", UI_EMBOSS); + block= uiBeginBlock(C, ar, __func__, UI_EMBOSS); uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN); layout= uiLayoutColumn(uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, args->x, args->y+2, args->width, NODE_DY, UI_GetStyle()), 0); @@ -631,7 +631,7 @@ if (sock->flag & SOCK_DYNAMIC) { bt = uiDefBut(gnode->block, TEX, 0, "", sock->locx+xoffset, sock->locy+1+yoffset, 72, NODE_DY, - sock->name, 0, 31, 0, 0, ""); + sock->name, 0, sizeof(sock->name), 0, 0, ""); if (in_out==SOCK_IN) uiButSetFunc(bt, update_group_input_cb, snode, ngroup); else @@ -640,7 +640,7 @@ else { uiDefBut(gnode->block, LABEL, 0, sock->name, sock->locx+xoffset, sock->locy+1+yoffset, 72, NODE_DY, - NULL, 0, 31, 0, 0, ""); + NULL, 0, sizeof(sock->name), 0, 0, ""); } } @@ -1203,10 +1203,10 @@ /* don't use iuser->framenr directly because it may not be updated if auto-refresh is off */ Scene *scene= CTX_data_scene(C); ImageUser *iuser= node->storage; - char tstr[32]; + char numstr[32]; const int framenr= BKE_image_user_get_frame(iuser, CFRA, 0); - BLI_snprintf(tstr, sizeof(tstr), "Frame: %d", framenr); - uiItemL(layout, tstr, ICON_NONE); + BLI_snprintf(numstr, sizeof(numstr), "Frame: %d", framenr); + uiItemL(layout, numstr, ICON_NONE); } if (ELEM(source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE)) { @@ -1233,7 +1233,10 @@ PropertyRNA *prop; const char *layer_name; char scene_name[MAX_ID_NAME-2]; - + wmOperatorType *ot = WM_operatortype_find("RENDER_OT_render", 1); + + BLI_assert(ot != 0); + uiTemplateID(layout, C, ptr, "scene", NULL, NULL, NULL); if(!node->id) return; @@ -1249,10 +1252,10 @@ scn_ptr = RNA_pointer_get(ptr, "scene"); RNA_string_get(&scn_ptr, "name", scene_name); - WM_operator_properties_create(&op_ptr, "RENDER_OT_render"); + WM_operator_properties_create_ptr(&op_ptr, ot); RNA_string_set(&op_ptr, "layer", layer_name); RNA_string_set(&op_ptr, "scene", scene_name); - uiItemFullO(row, "RENDER_OT_render", "", ICON_RENDER_STILL, op_ptr.data, WM_OP_INVOKE_DEFAULT, 0); + uiItemFullO_ptr(row, ot, "", ICON_RENDER_STILL, op_ptr.data, WM_OP_INVOKE_DEFAULT, 0); } @@ -1472,6 +1475,18 @@ uiItemR(col, ptr, "factor", 0, NULL, ICON_NONE); } +static void node_composit_buts_double_edge_mask(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + uiLayout *col; + + col= uiLayoutColumn(layout, 0); + + uiItemL(col, "Inner Edge:", ICON_NONE); + uiItemR(col, ptr, "inner_mode", 0, "", ICON_NONE); + uiItemL(col, "Buffer Edge:", ICON_NONE); + uiItemR(col, ptr, "edge_mode", 0, "", ICON_NONE); +} + static void node_composit_buts_map_value(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { uiLayout *sub, *col; @@ -1926,6 +1941,9 @@ case CMP_NODE_ID_MASK: ntype->uifunc= node_composit_buts_id_mask; break; + case CMP_NODE_DOUBLEEDGEMASK: + ntype->uifunc= node_composit_buts_double_edge_mask; + break; case CMP_NODE_MATH: ntype->uifunc= node_buts_math; break; @@ -2264,211 +2282,6 @@ } } -void draw_nodespace_color_info(ARegion *ar, int color_manage, int channels, int x, int y, const char cp[4], const float fp[4]) -{ - char str[256]; - float dx= 6; - /* text colors */ - /* XXX colored text not allowed in Blender UI */ - #if 0 - unsigned char red[3] = {255, 50, 50}; - unsigned char green[3] = {0, 255, 0}; - unsigned char blue[3] = {100, 100, 255}; - #else - unsigned char red[3] = {255, 255, 255}; - unsigned char green[3] = {255, 255, 255}; - unsigned char blue[3] = {255, 255, 255}; - #endif - float hue=0, sat=0, val=0, lum=0, u=0, v=0; - float col[4], finalcol[4]; - - glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - - /* noisy, high contrast make impossible to read if lower alpha is used. */ - glColor4ub(0, 0, 0, 190); - glRecti(0.0, 0.0, ar->winrct.xmax - ar->winrct.xmin + 1, 20); - glDisable(GL_BLEND); - - BLF_size(blf_mono_font, 11, 72); - - glColor3ub(255, 255, 255); - sprintf(str, "X:%-4d Y:%-4d |", x, y); - // UI_DrawString(6, 6, str); // works ok but fixed width is nicer. - BLF_position(blf_mono_font, dx, 6, 0); - BLF_draw_ascii(blf_mono_font, str, sizeof(str)); - dx += BLF_width(blf_mono_font, str); - - #if 0 /* XXX no Z value in compo backdrop atm */ - if(zp) { - glColor3ub(255, 255, 255); - sprintf(str, " Z:%-.4f |", 0.5f+0.5f*(((float)*zp)/(float)0x7fffffff)); - BLF_position(blf_mono_font, dx, 6, 0); - BLF_draw_ascii(blf_mono_font, str, sizeof(str)); - dx += BLF_width(blf_mono_font, str); - } - if(zpf) { - glColor3ub(255, 255, 255); - sprintf(str, " Z:%-.3f |", *zpf); - BLF_position(blf_mono_font, dx, 6, 0); - BLF_draw_ascii(blf_mono_font, str, sizeof(str)); - dx += BLF_width(blf_mono_font, str); - } - #endif - - if(channels >= 3) { - glColor3ubv(red); - if (fp) - sprintf(str, " R:%-.4f", fp[0]); - else if (cp) - sprintf(str, " R:%-3d", cp[0]); - else - sprintf(str, " R:-"); - BLF_position(blf_mono_font, dx, 6, 0); - BLF_draw_ascii(blf_mono_font, str, sizeof(str)); - dx += BLF_width(blf_mono_font, str); - - glColor3ubv(green); - if (fp) - sprintf(str, " G:%-.4f", fp[1]); - else if (cp) - sprintf(str, " G:%-3d", cp[1]); - else - sprintf(str, " G:-"); - BLF_position(blf_mono_font, dx, 6, 0); - BLF_draw_ascii(blf_mono_font, str, sizeof(str)); - dx += BLF_width(blf_mono_font, str); - - glColor3ubv(blue); - if (fp) - sprintf(str, " B:%-.4f", fp[2]); - else if (cp) - sprintf(str, " B:%-3d", cp[2]); - else - sprintf(str, " B:-"); - BLF_position(blf_mono_font, dx, 6, 0); - BLF_draw_ascii(blf_mono_font, str, sizeof(str)); - dx += BLF_width(blf_mono_font, str); - - if(channels == 4) { - glColor3ub(255, 255, 255); - if (fp) - sprintf(str, " A:%-.4f", fp[3]); - else if (cp) - sprintf(str, " A:%-3d", cp[3]); - else - sprintf(str, "- "); - BLF_position(blf_mono_font, dx, 6, 0); - BLF_draw_ascii(blf_mono_font, str, sizeof(str)); - dx += BLF_width(blf_mono_font, str); - } - } - - /* color rectangle */ - if (channels==1) { - if (fp) - col[0] = col[1] = col[2] = fp[0]; - else if (cp) - col[0] = col[1] = col[2] = (float)cp[0]/255.0f; - else - col[0] = col[1] = col[2] = 0.0f; - } - else if (channels==3) { - if (fp) - copy_v3_v3(col, fp); - else if (cp) { - col[0] = (float)cp[0]/255.0f; - col[1] = (float)cp[1]/255.0f; - col[2] = (float)cp[2]/255.0f; - } - else - zero_v3(col); - } - else if (channels==4) { - if (fp) - copy_v4_v4(col, fp); - else if (cp) { - col[0] = (float)cp[0]/255.0f; - col[1] = (float)cp[1]/255.0f; - col[2] = (float)cp[2]/255.0f; - col[3] = (float)cp[3]/255.0f; - } - else - zero_v4(col); - } - if (color_manage) { - linearrgb_to_srgb_v3_v3(finalcol, col); - finalcol[3] = col[3]; - } - else { - copy_v4_v4(finalcol, col); - } - glDisable(GL_BLEND); - glColor3fv(finalcol); - dx += 5; - glBegin(GL_QUADS); - glVertex2f(dx, 3); - glVertex2f(dx, 17); - glVertex2f(dx+30, 17); - glVertex2f(dx+30, 3); - glEnd(); - dx += 35; - - glColor3ub(255, 255, 255); - if(channels == 1) { - if (fp) { - rgb_to_hsv(fp[0], fp[0], fp[0], &hue, &sat, &val); - rgb_to_yuv(fp[0], fp[0], fp[0], &lum, &u, &v); - } - else if (cp) { - rgb_to_hsv((float)cp[0]/255.0f, (float)cp[0]/255.0f, (float)cp[0]/255.0f, &hue, &sat, &val); - rgb_to_yuv((float)cp[0]/255.0f, (float)cp[0]/255.0f, (float)cp[0]/255.0f, &lum, &u, &v); - } - - sprintf(str, "V:%-.4f", val); - BLF_position(blf_mono_font, dx, 6, 0); - BLF_draw_ascii(blf_mono_font, str, sizeof(str)); - dx += BLF_width(blf_mono_font, str); - - sprintf(str, " L:%-.4f", lum); - BLF_position(blf_mono_font, dx, 6, 0); - BLF_draw_ascii(blf_mono_font, str, sizeof(str)); - dx += BLF_width(blf_mono_font, str); - } - else if(channels >= 3) { - if (fp) { - rgb_to_hsv(fp[0], fp[1], fp[2], &hue, &sat, &val); - rgb_to_yuv(fp[0], fp[1], fp[2], &lum, &u, &v); - } - else if (cp) { - rgb_to_hsv((float)cp[0]/255.0f, (float)cp[1]/255.0f, (float)cp[2]/255.0f, &hue, &sat, &val); - rgb_to_yuv((float)cp[0]/255.0f, (float)cp[1]/255.0f, (float)cp[2]/255.0f, &lum, &u, &v); - } - - sprintf(str, "H:%-.4f", hue); - BLF_position(blf_mono_font, dx, 6, 0); - BLF_draw_ascii(blf_mono_font, str, sizeof(str)); - dx += BLF_width(blf_mono_font, str); - - sprintf(str, " S:%-.4f", sat); - BLF_position(blf_mono_font, dx, 6, 0); - BLF_draw_ascii(blf_mono_font, str, sizeof(str)); - dx += BLF_width(blf_mono_font, str); - - sprintf(str, " V:%-.4f", val); - BLF_position(blf_mono_font, dx, 6, 0); - BLF_draw_ascii(blf_mono_font, str, sizeof(str)); - dx += BLF_width(blf_mono_font, str); - - sprintf(str, " L:%-.4f", lum); - BLF_position(blf_mono_font, dx, 6, 0); - BLF_draw_ascii(blf_mono_font, str, sizeof(str)); - dx += BLF_width(blf_mono_font, str); - } - - (void)dx; -} - #if 0 /* note: needs to be userpref or opengl profile option */ static void draw_nodespace_back_tex(ScrArea *sa, SpaceNode *snode) diff -Nru blender-2.61/source/blender/editors/space_node/node_buttons.c blender-2.62/source/blender/editors/space_node/node_buttons.c --- blender-2.61/source/blender/editors/space_node/node_buttons.c 2011-12-13 19:54:16.000000000 +0000 +++ blender-2.62/source/blender/editors/space_node/node_buttons.c 2012-02-15 19:38:25.000000000 +0000 @@ -115,6 +115,9 @@ uiItemS(layout); uiItemR(layout, &ptr, "name", 0, NULL, ICON_NODE); uiItemS(layout); + + uiItemO(layout, NULL, 0, "NODE_OT_hide_socket_toggle"); + uiItemS(layout); /* draw this node's settings */ if (node->typeinfo && node->typeinfo->uifuncbut) diff -Nru blender-2.61/source/blender/editors/space_node/node_draw.c blender-2.62/source/blender/editors/space_node/node_draw.c --- blender-2.61/source/blender/editors/space_node/node_draw.c 2011-12-13 19:54:16.000000000 +0000 +++ blender-2.62/source/blender/editors/space_node/node_draw.c 2012-02-15 19:38:25.000000000 +0000 @@ -195,18 +195,18 @@ static void node_uiblocks_init(const bContext *C, bNodeTree *ntree) { bNode *node; - char str[32]; + char uiblockstr[32]; /* add node uiBlocks in drawing order - prevents events going to overlapping nodes */ - for(node= ntree->nodes.first; node; node=node->next) { - /* ui block */ - sprintf(str, "node buttons %p", (void *)node); - node->block= uiBeginBlock(C, CTX_wm_region(C), str, UI_EMBOSS); - uiBlockSetHandleFunc(node->block, do_node_internal_buttons, node); - - /* this cancels events for background nodes */ - uiBlockSetFlag(node->block, UI_BLOCK_CLIP_EVENTS); + for (node= ntree->nodes.first; node; node= node->next) { + /* ui block */ + BLI_snprintf(uiblockstr, sizeof(uiblockstr), "node buttons %p", (void *)node); + node->block= uiBeginBlock(C, CTX_wm_region(C), uiblockstr, UI_EMBOSS); + uiBlockSetHandleFunc(node->block, do_node_internal_buttons, node); + + /* this cancels events for background nodes */ + uiBlockSetFlag(node->block, UI_BLOCK_CLIP_EVENTS); } } @@ -233,7 +233,7 @@ /* output sockets */ for(nsock= node->outputs.first; nsock; nsock= nsock->next) { - if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) { + if(!nodeSocketIsHidden(nsock)) { nsock->locx= locx + node->width; nsock->locy= dy - NODE_DYS; dy-= NODE_DY; @@ -312,7 +312,7 @@ /* input sockets */ for(nsock= node->inputs.first; nsock; nsock= nsock->next) { - if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) { + if(!nodeSocketIsHidden(nsock)) { nsock->locx= locx; nsock->locy= dy - NODE_DYS; dy-= NODE_DY; @@ -351,10 +351,10 @@ /* calculate minimal radius */ for(nsock= node->inputs.first; nsock; nsock= nsock->next) - if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) + if(!nodeSocketIsHidden(nsock)) totin++; for(nsock= node->outputs.first; nsock; nsock= nsock->next) - if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) + if(!nodeSocketIsHidden(nsock)) totout++; tot= MAX2(totin, totout); @@ -371,7 +371,7 @@ rad=drad= (float)M_PI/(1.0f + (float)totout); for(nsock= node->outputs.first; nsock; nsock= nsock->next) { - if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) { + if(!nodeSocketIsHidden(nsock)) { nsock->locx= node->totr.xmax - hiddenrad + (float)sin(rad)*hiddenrad; nsock->locy= node->totr.ymin + hiddenrad + (float)cos(rad)*hiddenrad; rad+= drad; @@ -382,7 +382,7 @@ rad=drad= - (float)M_PI/(1.0f + (float)totin); for(nsock= node->inputs.first; nsock; nsock= nsock->next) { - if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) { + if(!nodeSocketIsHidden(nsock)) { nsock->locx= node->totr.xmin + hiddenrad + (float)sin(rad)*hiddenrad; nsock->locy= node->totr.ymin + hiddenrad + (float)cos(rad)*hiddenrad; rad+= drad; @@ -562,6 +562,18 @@ } +/* common handle function for operator buttons that need to select the node first */ +static void node_toggle_button_cb(struct bContext *C, void *node_argv, void *op_argv) +{ + bNode *node = (bNode*)node_argv; + const char *opname = (const char *)op_argv; + + /* select & activate only the button's node */ + node_select_single(C, node); + + WM_operator_name_call(C, opname, WM_OP_INVOKE_DEFAULT, NULL); +} + static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTree *ntree, bNode *node) { bNodeSocket *sock; @@ -601,39 +613,34 @@ uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT); uiRoundBox(rct->xmin, rct->ymax-NODE_DY, rct->xmax, rct->ymax, BASIS_RAD); - /* show/hide icons, note this sequence is copied in do_header_node() node_state.c */ + /* show/hide icons */ iconofs= rct->xmax - 7.0f; + /* preview */ if(node->typeinfo->flag & NODE_PREVIEW) { - float alpha = (node->flag & (NODE_ACTIVE_ID|NODE_DO_OUTPUT))? 1.0f: 0.5f; - + uiBut *but; iconofs-=iconbutw; - uiDefIconBut(node->block, LABEL, B_REDR, ICON_MATERIAL, iconofs, rct->ymax-NODE_DY, - iconbutw, UI_UNIT_Y, NULL, 0.0, 0.0, 1.0, alpha, ""); + uiBlockSetEmboss(node->block, UI_EMBOSSN); + but = uiDefIconBut(node->block, TOGBUT, B_REDR, ICON_MATERIAL, + iconofs, rct->ymax-NODE_DY, iconbutw, UI_UNIT_Y, NULL, 0, 0, 0, 0, ""); + uiButSetFunc(but, node_toggle_button_cb, node, (void*)"NODE_OT_preview_toggle"); + /* XXX this does not work when node is activated and the operator called right afterwards, + * since active ID is not updated yet (needs to process the notifier). + * This can only work as visual indicator! + */ +// if (!(node->flag & (NODE_ACTIVE_ID|NODE_DO_OUTPUT))) +// uiButSetFlag(but, UI_BUT_DISABLED); + uiBlockSetEmboss(node->block, UI_EMBOSS); } + /* group edit */ if(node->type == NODE_GROUP) { - + uiBut *but; iconofs-=iconbutw; - uiDefIconBut(node->block, LABEL, B_REDR, ICON_NODETREE, iconofs, rct->ymax-NODE_DY, - iconbutw, UI_UNIT_Y, NULL, 0.0, 0.0, 1.0, 0.5, ""); - } - if(node->typeinfo->flag & NODE_OPTIONS) { - iconofs-=iconbutw; - uiDefIconBut(node->block, LABEL, B_REDR, ICON_BUTS, iconofs, rct->ymax-NODE_DY, - iconbutw, UI_UNIT_Y, NULL, 0.0, 0.0, 1.0, 0.5, ""); - } - { /* always hide/reveal unused sockets */ - // XXX re-enable - /* int shade; - if(node_has_hidden_sockets(node)) - shade= -40; - else - shade= -90; */ - - iconofs-=iconbutw; - - uiDefIconBut(node->block, LABEL, B_REDR, ICON_PLUS, iconofs, rct->ymax-NODE_DY, - iconbutw, UI_UNIT_Y, NULL, 0.0, 0.0, 1.0, 0.5, ""); + uiBlockSetEmboss(node->block, UI_EMBOSSN); + but = uiDefIconBut(node->block, TOGBUT, B_REDR, ICON_NODETREE, + iconofs, rct->ymax-NODE_DY, iconbutw, UI_UNIT_Y, NULL, 0, 0, 0, 0, ""); + uiButSetFunc(but, node_toggle_button_cb, node, (void*)"NODE_OT_group_edit"); + uiBlockSetEmboss(node->block, UI_EMBOSS); } /* title */ @@ -643,7 +650,19 @@ UI_ThemeColorBlendShade(TH_TEXT, color_id, 0.4f, 10); /* open/close entirely? */ - UI_DrawTriIcon(rct->xmin+10.0f, rct->ymax-NODE_DY/2.0f, 'v'); + { + uiBut *but; + int but_size = UI_UNIT_X *0.6f; + /* XXX button uses a custom triangle draw below, so make it invisible without icon */ + uiBlockSetEmboss(node->block, UI_EMBOSSN); + but = uiDefBut(node->block, TOGBUT, B_REDR, "", + rct->xmin+10.0f-but_size/2, rct->ymax-NODE_DY/2.0f-but_size/2, but_size, but_size, NULL, 0, 0, 0, 0, ""); + uiButSetFunc(but, node_toggle_button_cb, node, (void*)"NODE_OT_hide_toggle"); + uiBlockSetEmboss(node->block, UI_EMBOSS); + + /* custom draw function for this button */ + UI_DrawTriIcon(rct->xmin+10.0f, rct->ymax-NODE_DY/2.0f, 'v'); + } /* this isn't doing anything for the label, so commenting out if(node->flag & SELECT) @@ -654,7 +673,7 @@ BLI_strncpy(showname, nodeLabel(node), sizeof(showname)); //if(node->flag & NODE_MUTED) - // sprintf(showname, "[%s]", showname); + // BLI_snprintf(showname, sizeof(showname), "[%s]", showname); // XXX - dont print into self! uiDefBut(node->block, LABEL, 0, showname, (short)(rct->xmin+15), (short)(rct->ymax-NODE_DY), (int)(iconofs - rct->xmin-18.0f), NODE_DY, NULL, 0, 0, 0, 0, ""); @@ -694,7 +713,7 @@ for(sock= node->inputs.first; sock; sock= sock->next) { bNodeSocketType *stype= ntreeGetSocketType(sock->type); - if(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)) + if(nodeSocketIsHidden(sock)) continue; node_socket_circle_draw(ntree, sock, NODE_SOCKSIZE); @@ -717,7 +736,7 @@ RNA_pointer_create((ID*)ntree, &RNA_NodeSocket, sock, &sockptr); - if(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)) + if(nodeSocketIsHidden(sock)) continue; node_socket_circle_draw(ntree, sock, NODE_SOCKSIZE); @@ -789,7 +808,19 @@ UI_ThemeColorBlendShade(TH_TEXT, color_id, 0.4f, 10); /* open entirely icon */ - UI_DrawTriIcon(rct->xmin+10.0f, centy, 'h'); + { + uiBut *but; + int but_size = UI_UNIT_X *0.6f; + /* XXX button uses a custom triangle draw below, so make it invisible without icon */ + uiBlockSetEmboss(node->block, UI_EMBOSSN); + but = uiDefBut(node->block, TOGBUT, B_REDR, "", + rct->xmin+10.0f-but_size/2, centy-but_size/2, but_size, but_size, NULL, 0, 0, 0, 0, ""); + uiButSetFunc(but, node_toggle_button_cb, node, (void*)"NODE_OT_hide_toggle"); + uiBlockSetEmboss(node->block, UI_EMBOSS); + + /* custom draw function for this button */ + UI_DrawTriIcon(rct->xmin+10.0f, centy, 'h'); + } /* disable lines */ if(node->flag & NODE_MUTED) @@ -804,7 +835,7 @@ BLI_strncpy(showname, nodeLabel(node), sizeof(showname)); //if(node->flag & NODE_MUTED) - // sprintf(showname, "[%s]", showname); + // BLI_snprintf(showname, sizeof(showname), "[%s]", showname); // XXX - dont print into self! uiDefBut(node->block, LABEL, 0, showname, (short)(rct->xmin+15), (short)(centy-10), (int)(rct->xmax - rct->xmin-18.0f -12.0f), NODE_DY, NULL, 0, 0, 0, 0, ""); @@ -823,12 +854,12 @@ /* sockets */ for(sock= node->inputs.first; sock; sock= sock->next) { - if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) + if(!nodeSocketIsHidden(sock)) node_socket_circle_draw(snode->nodetree, sock, socket_size); } for(sock= node->outputs.first; sock; sock= sock->next) { - if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) + if(!nodeSocketIsHidden(sock)) node_socket_circle_draw(snode->nodetree, sock, socket_size); } diff -Nru blender-2.61/source/blender/editors/space_node/node_edit.c blender-2.62/source/blender/editors/space_node/node_edit.c --- blender-2.61/source/blender/editors/space_node/node_edit.c 2011-12-13 19:54:16.000000000 +0000 +++ blender-2.62/source/blender/editors/space_node/node_edit.c 2012-02-15 19:38:25.000000000 +0000 @@ -71,6 +71,7 @@ #include "IMB_imbuf_types.h" #include "ED_node.h" +#include "ED_image.h" #include "ED_screen.h" #include "ED_space_api.h" #include "ED_render.h" @@ -690,108 +691,6 @@ } } -static int compare_nodes(bNode *a, bNode *b) -{ - bNode *parent; - /* These tell if either the node or any of the parent nodes is selected. - * A selected parent means an unselected node is also in foreground! - */ - int a_select=(a->flag & NODE_SELECT), b_select=(b->flag & NODE_SELECT); - int a_active=(a->flag & NODE_ACTIVE), b_active=(b->flag & NODE_ACTIVE); - - /* if one is an ancestor of the other */ - /* XXX there might be a better sorting algorithm for stable topological sort, this is O(n^2) worst case */ - for (parent = a->parent; parent; parent=parent->parent) { - /* if b is an ancestor, it is always behind a */ - if (parent==b) - return 1; - /* any selected ancestor moves the node forward */ - if (parent->flag & NODE_ACTIVE) - a_active = 1; - if (parent->flag & NODE_SELECT) - a_select = 1; - } - for (parent = b->parent; parent; parent=parent->parent) { - /* if a is an ancestor, it is always behind b */ - if (parent==a) - return 0; - /* any selected ancestor moves the node forward */ - if (parent->flag & NODE_ACTIVE) - b_active = 1; - if (parent->flag & NODE_SELECT) - b_select = 1; - } - - /* if one of the nodes is in the background and the other not */ - if ((a->flag & NODE_BACKGROUND) && !(b->flag & NODE_BACKGROUND)) - return 0; - else if (!(a->flag & NODE_BACKGROUND) && (b->flag & NODE_BACKGROUND)) - return 1; - - /* if one has a higher selection state (active > selected > nothing) */ - if (!b_active && a_active) - return 1; - else if (!b_select && (a_active || a_select)) - return 1; - - return 0; -} -/* Sorts nodes by selection: unselected nodes first, then selected, - * then the active node at the very end. Relative order is kept intact! - */ -void node_sort(bNodeTree *ntree) -{ - /* merge sort is the algorithm of choice here */ - bNode *first_a, *first_b, *node_a, *node_b, *tmp; - int totnodes= BLI_countlist(&ntree->nodes); - int k, a, b; - - k = 1; - while (k < totnodes) { - first_a = first_b = ntree->nodes.first; - - do { - /* setup first_b pointer */ - for (b=0; b < k && first_b; ++b) { - first_b = first_b->next; - } - /* all batches merged? */ - if (first_b==NULL) - break; - - /* merge batches */ - node_a = first_a; - node_b = first_b; - a = b = 0; - while (a < k && b < k && node_b) { - if (compare_nodes(node_a, node_b)==0) { - node_a = node_a->next; - ++a; - } - else { - tmp = node_b; - node_b = node_b->next; - ++b; - BLI_remlink(&ntree->nodes, tmp); - BLI_insertlinkbefore(&ntree->nodes, node_a, tmp); - } - } - - /* setup first pointers for next batch */ - first_b = node_b; - for (; b < k; ++b) { - /* all nodes sorted? */ - if (first_b==NULL) - break; - first_b = first_b->next; - } - first_a = first_b; - } while (first_b); - - k = k << 1; - } -} - static int inside_rctf(rctf *bounds, rctf *rect) { return (bounds->xmin <= rect->xmin && bounds->xmax >= rect->xmax @@ -853,14 +752,14 @@ static void edit_node_properties(wmOperatorType *ot) { /* XXX could node be a context pointer? */ - RNA_def_string(ot->srna, "node", "", 32, "Node", ""); + RNA_def_string(ot->srna, "node", "", MAX_NAME, "Node", ""); RNA_def_int(ot->srna, "socket", 0, 0, MAX_SOCKET, "Socket", "", 0, MAX_SOCKET); RNA_def_enum(ot->srna, "in_out", socket_in_out_items, SOCK_IN, "Socket Side", ""); } static int edit_node_invoke_properties(bContext *C, wmOperator *op) { - if (!RNA_property_is_set(op->ptr, "node")) { + if (!RNA_struct_property_is_set(op->ptr, "node")) { bNode *node= CTX_data_pointer_get_type(C, "node", &RNA_Node).data; if (!node) return 0; @@ -868,10 +767,10 @@ RNA_string_set(op->ptr, "node", node->name); } - if (!RNA_property_is_set(op->ptr, "in_out")) + if (!RNA_struct_property_is_set(op->ptr, "in_out")) RNA_enum_set(op->ptr, "in_out", SOCK_IN); - if (!RNA_property_is_set(op->ptr, "socket")) + if (!RNA_struct_property_is_set(op->ptr, "socket")) RNA_int_set(op->ptr, "socket", 0); return 1; @@ -881,7 +780,7 @@ { bNode *node; bNodeSocket *sock=NULL; - char nodename[32]; + char nodename[MAX_NAME]; int sockindex; int in_out; @@ -940,7 +839,7 @@ ED_preview_kill_jobs(C); if (snode->nodetree==snode->edittree) { - bNode *gnode= nodeGetActive(snode->nodetree); + bNode *gnode = nodeGetActive(snode->edittree); snode_make_group_editable(snode, gnode); } else @@ -955,12 +854,14 @@ { SpaceNode *snode = CTX_wm_space_node(C); bNode *gnode; - - gnode= nodeGetActive(snode->edittree); + /* XXX callback? */ - if(gnode && gnode->id && GS(gnode->id->name)==ID_NT && gnode->id->lib) { - uiPupMenuOkee(C, op->type->idname, "Make group local?"); - return OPERATOR_CANCELLED; + if (snode->nodetree==snode->edittree) { + gnode = nodeGetActive(snode->edittree); + if(gnode && gnode->id && GS(gnode->id->name)==ID_NT && gnode->id->lib) { + uiPupMenuOkee(C, op->type->idname, "Make group local?"); + return OPERATOR_CANCELLED; + } } return node_group_edit_exec(C, op); @@ -988,20 +889,20 @@ { SpaceNode *snode = CTX_wm_space_node(C); int in_out= -1; - char name[32]= ""; + char name[MAX_NAME]= ""; int type= SOCK_FLOAT; bNodeTree *ngroup= snode->edittree; /* bNodeSocket *sock; */ /* UNUSED */ ED_preview_kill_jobs(C); - if (RNA_property_is_set(op->ptr, "name")) + if (RNA_struct_property_is_set(op->ptr, "name")) RNA_string_get(op->ptr, "name", name); - if (RNA_property_is_set(op->ptr, "type")) + if (RNA_struct_property_is_set(op->ptr, "type")) type = RNA_enum_get(op->ptr, "type"); - if (RNA_property_is_set(op->ptr, "in_out")) + if (RNA_struct_property_is_set(op->ptr, "in_out")) in_out = RNA_enum_get(op->ptr, "in_out"); else return OPERATOR_CANCELLED; @@ -1031,7 +932,7 @@ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; RNA_def_enum(ot->srna, "in_out", socket_in_out_items, SOCK_IN, "Socket Type", "Input or Output"); - RNA_def_string(ot->srna, "name", "", 32, "Name", "Group socket name"); + RNA_def_string(ot->srna, "name", "", MAX_NAME, "Name", "Group socket name"); RNA_def_enum(ot->srna, "type", node_socket_type_items, SOCK_FLOAT, "Type", "Type of the group socket"); } @@ -1047,12 +948,12 @@ ED_preview_kill_jobs(C); - if (RNA_property_is_set(op->ptr, "index")) + if (RNA_struct_property_is_set(op->ptr, "index")) index = RNA_int_get(op->ptr, "index"); else return OPERATOR_CANCELLED; - if (RNA_property_is_set(op->ptr, "in_out")) + if (RNA_struct_property_is_set(op->ptr, "in_out")) in_out = RNA_enum_get(op->ptr, "in_out"); else return OPERATOR_CANCELLED; @@ -1098,12 +999,12 @@ ED_preview_kill_jobs(C); - if (RNA_property_is_set(op->ptr, "index")) + if (RNA_struct_property_is_set(op->ptr, "index")) index = RNA_int_get(op->ptr, "index"); else return OPERATOR_CANCELLED; - if (RNA_property_is_set(op->ptr, "in_out")) + if (RNA_struct_property_is_set(op->ptr, "in_out")) in_out = RNA_enum_get(op->ptr, "in_out"); else return OPERATOR_CANCELLED; @@ -1168,12 +1069,12 @@ ED_preview_kill_jobs(C); - if (RNA_property_is_set(op->ptr, "index")) + if (RNA_struct_property_is_set(op->ptr, "index")) index = RNA_int_get(op->ptr, "index"); else return OPERATOR_CANCELLED; - if (RNA_property_is_set(op->ptr, "in_out")) + if (RNA_struct_property_is_set(op->ptr, "in_out")) in_out = RNA_enum_get(op->ptr, "in_out"); else return OPERATOR_CANCELLED; @@ -1432,7 +1333,7 @@ int channels; int color_manage; - char col[4]; + unsigned char col[4]; float colf[4]; int draw; @@ -1440,10 +1341,13 @@ static void sample_draw(const bContext *C, ARegion *ar, void *arg_info) { + Scene *scene = CTX_data_scene(C); ImageSampleInfo *info= arg_info; - draw_nodespace_color_info(ar, (CTX_data_scene(C)->r.color_mgt_flag & R_COLOR_MANAGEMENT), info->channels, - info->x, info->y, info->col, info->colf); + ED_image_draw_info(ar, (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT), info->channels, + info->x, info->y, info->col, info->colf, + NULL, NULL /* zbuf - unused for nodes */ + ); } static void sample_apply(bContext *C, wmOperator *op, wmEvent *event) @@ -1696,102 +1600,43 @@ ot->flag= OPTYPE_BLOCKING; } -/* ********************** select ******************** */ +/* ********************** hidden sockets ******************** */ -/* no undo here! */ -void node_deselectall(SpaceNode *snode) +int node_has_hidden_sockets(bNode *node, short flag) { - bNode *node; + bNodeSocket *sock; - for(node= snode->edittree->nodes.first; node; node= node->next) - node->flag &= ~SELECT; + for(sock= node->inputs.first; sock; sock= sock->next) + if(sock->flag & flag) + return 1; + for(sock= node->outputs.first; sock; sock= sock->next) + if(sock->flag & flag) + return 1; + return 0; } -/* return 1 if we need redraw otherwise zero. */ -int node_select_same_type(SpaceNode *snode) -{ - bNode *nac, *p; - int redraw; +void node_set_hidden_sockets(SpaceNode *snode, bNode *node, short flag, int set) +{ + bNodeSocket *sock; - /* search for the active node. */ - for (nac= snode->edittree->nodes.first; nac; nac= nac->next) { - if (nac->flag & SELECT) - break; + if(set==0) { + for(sock= node->inputs.first; sock; sock= sock->next) + sock->flag &= ~flag; + for(sock= node->outputs.first; sock; sock= sock->next) + sock->flag &= ~flag; } - - /* no active node, return. */ - if (!nac) - return(0); - - redraw= 0; - for (p= snode->edittree->nodes.first; p; p= p->next) { - if (p->type != nac->type && p->flag & SELECT) { - /* if it's selected but different type, unselect */ - redraw= 1; - p->flag &= ~SELECT; + else { + /* hide unused sockets */ + for(sock= node->inputs.first; sock; sock= sock->next) { + if(sock->link==NULL) + sock->flag |= flag; } - else if (p->type == nac->type && (!(p->flag & SELECT))) { - /* if it's the same type and is not selected, select! */ - redraw= 1; - p->flag |= SELECT; + for(sock= node->outputs.first; sock; sock= sock->next) { + if(nodeCountSocketLinks(snode->edittree, sock)==0) + sock->flag |= flag; } } - return(redraw); -} - -/* return 1 if we need redraw, otherwise zero. - * dir can be 0 == next or 0 != prev. - */ -int node_select_same_type_np(SpaceNode *snode, int dir) -{ - bNode *nac, *p; - - /* search the active one. */ - for (nac= snode->edittree->nodes.first; nac; nac= nac->next) { - if (nac->flag & SELECT) - break; - } - - /* no active node, return. */ - if (!nac) - return(0); - - if (dir == 0) - p= nac->next; - else - p= nac->prev; - - while (p) { - /* Now search the next with the same type. */ - if (p->type == nac->type) - break; - - if (dir == 0) - p= p->next; - else - p= p->prev; - } - - if (p) { - node_deselectall(snode); - p->flag |= SELECT; - return(1); - } - return(0); -} - -int node_has_hidden_sockets(bNode *node) -{ - bNodeSocket *sock; - - for(sock= node->inputs.first; sock; sock= sock->next) - if(sock->flag & SOCK_HIDDEN) - return 1; - for(sock= node->outputs.first; sock; sock= sock->next) - if(sock->flag & SOCK_HIDDEN) - return 1; - return 0; } static void node_link_viewer(SpaceNode *snode, bNode *tonode) @@ -1836,14 +1681,14 @@ /* find a socket after the previously connected socket */ for(sock=sock->next; sock; sock= sock->next) - if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) + if(!nodeSocketIsHidden(sock)) break; } /* find a socket starting from the first socket */ if(!sock) { for(sock= tonode->outputs.first; sock; sock= sock->next) - if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) + if(!nodeSocketIsHidden(sock)) break; } @@ -1961,7 +1806,7 @@ if(in_out & SOCK_IN) { for(sock= node->inputs.first; sock; sock= sock->next) { - if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) { + if(!nodeSocketIsHidden(sock)) { if(BLI_in_rctf(&rect, sock->locx, sock->locy)) { if(node == visible_node(snode, &rect)) { *nodep= node; @@ -1974,7 +1819,7 @@ } if(in_out & SOCK_OUT) { for(sock= node->outputs.first; sock; sock= sock->next) { - if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) { + if(!nodeSocketIsHidden(sock)) { if(BLI_in_rctf(&rect, sock->locx, sock->locy)) { if(node == visible_node(snode, &rect)) { *nodep= node; @@ -1992,7 +1837,7 @@ */ if(in_out & SOCK_IN) { for(sock= snode->edittree->outputs.first; sock; sock= sock->next) { - if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) { + if(!nodeSocketIsHidden(sock)) { if(BLI_in_rctf(&rect, sock->locx, sock->locy)) { *nodep= NULL; /* NULL node pointer indicates group socket */ *sockp= sock; @@ -2003,7 +1848,7 @@ } if(in_out & SOCK_OUT) { for(sock= snode->edittree->inputs.first; sock; sock= sock->next) { - if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) { + if(!nodeSocketIsHidden(sock)) { if(BLI_in_rctf(&rect, sock->locx, sock->locy)) { *nodep= NULL; /* NULL node pointer indicates group socket */ *sockp= sock; @@ -2084,15 +1929,14 @@ return 0; } -static int socket_is_available(bNodeTree *ntree, bNodeSocket *sock, int allow_used) +static int socket_is_available(bNodeTree *UNUSED(ntree), bNodeSocket *sock, int allow_used) { - if (sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)) + if (nodeSocketIsHidden(sock)) + return 0; + + if (!allow_used && (sock->flag & SOCK_IN_USE)) return 0; - if (!allow_used) { - if (nodeCountSocketLinks(ntree, sock) > 0) - return 0; - } return 1; } @@ -2232,7 +2076,7 @@ { bNode *node= NULL, *gnode; - node_deselectall(snode); + node_deselect_all(snode); node = nodeAddNode(snode->edittree, ntemp); @@ -2402,7 +2246,7 @@ } if(sock) { tlink->tosock= sock; - sock->flag &= ~SOCK_HIDDEN; + sock->flag &= ~(SOCK_HIDDEN|SOCK_AUTO_HIDDEN); } else { nodeRemLink(snode->edittree, tlink); @@ -2800,26 +2644,26 @@ /* first, match type */ for(sock= sockets->first; sock; sock= sock->next) - if(!(sock->flag & SOCK_HIDDEN)) + if(!nodeSocketIsHidden(sock)) if(type == sock->type) return sock; /* then just use first unhidden socket */ for(sock= sockets->first; sock; sock= sock->next) - if(!(sock->flag & SOCK_HIDDEN)) + if(!nodeSocketIsHidden(sock)) return sock; /* OK, let's unhide proper one */ for(sock= sockets->first; sock; sock= sock->next) { if(type == sock->type) { - sock->flag &= ~SOCK_HIDDEN; + sock->flag &= ~(SOCK_HIDDEN|SOCK_AUTO_HIDDEN); return sock; } } /* just the first */ sock= sockets->first; - sock->flag &= ~SOCK_HIDDEN; + sock->flag &= ~(SOCK_HIDDEN|SOCK_AUTO_HIDDEN); return sockets->first; } @@ -3130,15 +2974,21 @@ static void node_flag_toggle_exec(SpaceNode *snode, int toggle_flag) { - int tot_eq= 0, tot_neq= 0; bNode *node; + int tot_eq= 0, tot_neq= 0; + /* Toggles the flag on all selected nodes. + * If the flag is set on all nodes it is unset. + * If the flag is not set on all nodes, it is set. + */ for(node= snode->edittree->nodes.first; node; node= node->next) { if(node->flag & SELECT) { - + if(toggle_flag== NODE_PREVIEW && (node->typeinfo->flag & NODE_PREVIEW)==0) continue; - + if(toggle_flag== NODE_OPTIONS && (node->typeinfo->flag & NODE_OPTIONS)==0) + continue; + if(node->flag & toggle_flag) tot_eq++; else @@ -3147,19 +2997,31 @@ } for(node= snode->edittree->nodes.first; node; node= node->next) { if(node->flag & SELECT) { - + if(toggle_flag== NODE_PREVIEW && (node->typeinfo->flag & NODE_PREVIEW)==0) continue; - - if( (tot_eq && tot_neq) || tot_eq==0) + if(toggle_flag== NODE_OPTIONS && (node->typeinfo->flag & NODE_OPTIONS)==0) + continue; + + if( (tot_eq && tot_neq) || tot_eq==0) { node->flag |= toggle_flag; - else + + /* hide/unhide node also toggles unlinked socket display */ + if (toggle_flag== NODE_HIDDEN) + node_set_hidden_sockets(snode, node, SOCK_AUTO_HIDDEN, 1); + } + else { node->flag &= ~toggle_flag; + + /* hide/unhide node also toggles unlinked socket display */ + if (toggle_flag== NODE_HIDDEN) + node_set_hidden_sockets(snode, node, SOCK_AUTO_HIDDEN, 0); + } } } } -static int node_hide_exec(bContext *C, wmOperator *UNUSED(op)) +static int node_hide_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { SpaceNode *snode= CTX_wm_space_node(C); @@ -3182,14 +3044,14 @@ ot->idname= "NODE_OT_hide_toggle"; /* callbacks */ - ot->exec= node_hide_exec; + ot->exec= node_hide_toggle_exec; ot->poll= ED_operator_node_active; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } -static int node_preview_exec(bContext *C, wmOperator *UNUSED(op)) +static int node_preview_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { SpaceNode *snode= CTX_wm_space_node(C); @@ -3214,7 +3076,37 @@ ot->idname= "NODE_OT_preview_toggle"; /* callbacks */ - ot->exec= node_preview_exec; + ot->exec= node_preview_toggle_exec; + ot->poll= ED_operator_node_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +static int node_options_toggle_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceNode *snode= CTX_wm_space_node(C); + + /* sanity checking (poll callback checks this already) */ + if((snode == NULL) || (snode->edittree == NULL)) + return OPERATOR_CANCELLED; + + node_flag_toggle_exec(snode, NODE_OPTIONS); + + snode_notify(C, snode); + + return OPERATOR_FINISHED; +} + +void NODE_OT_options_toggle(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Toggle Node Options"; + ot->description= "Toggle option buttons display for selected nodes"; + ot->idname= "NODE_OT_options_toggle"; + + /* callbacks */ + ot->exec= node_options_toggle_exec; ot->poll= ED_operator_node_active; /* flags */ @@ -3225,7 +3117,7 @@ { SpaceNode *snode= CTX_wm_space_node(C); bNode *node; - int hidden= 0; + int hidden; /* sanity checking (poll callback checks this already) */ if((snode == NULL) || (snode->edittree == NULL)) @@ -3233,18 +3125,20 @@ ED_preview_kill_jobs(C); + /* Toggle for all selected nodes */ + hidden = 0; for(node= snode->edittree->nodes.first; node; node= node->next) { if(node->flag & SELECT) { - if(node_has_hidden_sockets(node)) { + if(node_has_hidden_sockets(node, SOCK_HIDDEN)) { hidden= 1; break; } } } - + for(node= snode->edittree->nodes.first; node; node= node->next) { if(node->flag & SELECT) { - node_set_hidden_sockets(snode, node, !hidden); + node_set_hidden_sockets(snode, node, SOCK_HIDDEN, !hidden); } } @@ -3544,7 +3438,7 @@ ntemp.type = -1; /* check input variables */ - if (RNA_property_is_set(op->ptr, "filepath")) + if (RNA_struct_property_is_set(op->ptr, "filepath")) { char path[FILE_MAX]; RNA_string_get(op->ptr, "filepath", path); @@ -3558,9 +3452,9 @@ return OPERATOR_CANCELLED; } } - else if(RNA_property_is_set(op->ptr, "name")) + else if(RNA_struct_property_is_set(op->ptr, "name")) { - char name[32]; + char name[MAX_ID_NAME-2]; RNA_string_get(op->ptr, "name", name); ima= (Image *)find_id("IM", name); @@ -3570,7 +3464,7 @@ } } - node_deselectall(snode); + node_deselect_all(snode); if (snode->nodetree->type==NTREE_COMPOSIT) ntemp.type = CMP_NODE_IMAGE; @@ -3604,7 +3498,7 @@ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &snode->mx, &snode->my); - if (RNA_property_is_set(op->ptr, "filepath") || RNA_property_is_set(op->ptr, "name")) + if (RNA_struct_property_is_set(op->ptr, "filepath") || RNA_struct_property_is_set(op->ptr, "name")) return node_add_file_exec(C, op); else return WM_operator_filesel(C, op, event); @@ -3625,8 +3519,8 @@ /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH); //XXX TODO, relative_path - RNA_def_string(ot->srna, "name", "Image", 24, "Name", "Datablock name to assign"); + WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); //XXX TODO, relative_path + RNA_def_string(ot->srna, "name", "Image", MAX_ID_NAME-2, "Name", "Datablock name to assign"); } /********************** New node tree operator *********************/ @@ -3643,12 +3537,12 @@ /* retrieve state */ snode= CTX_wm_space_node(C); - if (RNA_property_is_set(op->ptr, "type")) + if (RNA_struct_property_is_set(op->ptr, "type")) treetype = RNA_enum_get(op->ptr, "type"); else treetype = snode->treetype; - if (RNA_property_is_set(op->ptr, "name")) + if (RNA_struct_property_is_set(op->ptr, "name")) RNA_string_get(op->ptr, "name", treename); ntree = ntreeAddTree(treename, treetype, 0); diff -Nru blender-2.61/source/blender/editors/space_node/node_intern.h blender-2.62/source/blender/editors/space_node/node_intern.h --- blender-2.61/source/blender/editors/space_node/node_intern.h 2011-12-13 19:54:16.000000000 +0000 +++ blender-2.62/source/blender/editors/space_node/node_intern.h 2012-02-15 19:38:25.000000000 +0000 @@ -82,17 +82,23 @@ void node_keymap(wmKeyConfig *keyconf); /* node_select.c */ +void node_deselect_all(struct SpaceNode *snode); +int node_select_same_type(struct SpaceNode *snode); +int node_select_same_type_np(struct SpaceNode *snode, int dir); +void node_select_single(struct bContext *C, struct bNode *node); + void NODE_OT_select(struct wmOperatorType *ot); void NODE_OT_select_all(wmOperatorType *ot); void NODE_OT_select_linked_to(wmOperatorType *ot); void NODE_OT_select_linked_from(wmOperatorType *ot); -void NODE_OT_visibility_toggle(struct wmOperatorType *ot); -void NODE_OT_view_all(struct wmOperatorType *ot); void NODE_OT_select_border(struct wmOperatorType *ot); void NODE_OT_select_same_type(struct wmOperatorType *ot); void NODE_OT_select_same_type_next(wmOperatorType *ot); void NODE_OT_select_same_type_prev(wmOperatorType *ot); +/* node_state.c */ +void NODE_OT_view_all(struct wmOperatorType *ot); + /* drawnode.c */ void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link); void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link, int th_col1, int do_shaded, int th_col2, int do_triple, int th_col3 ); @@ -108,16 +114,12 @@ bNode *node_add_node(struct SpaceNode *snode, struct Main *bmain, struct Scene *scene, struct bNodeTemplate *ntemp, float locx, float locy); void snode_set_context(SpaceNode *snode, Scene *scene); void snode_make_group_editable(SpaceNode *snode, bNode *gnode); -void node_sort(struct bNodeTree *ntree); -void node_deselectall(SpaceNode *snode); -int node_select_same_type(SpaceNode *snode); -int node_select_same_type_np(SpaceNode *snode, int dir); void snode_composite_job(const struct bContext *C, ScrArea *sa); bNode *node_tree_get_editgroup(bNodeTree *ntree); void node_tree_verify_groups(bNodeTree *nodetree); void snode_autoconnect(SpaceNode *snode, int allow_multiple, int replace); -int node_has_hidden_sockets(bNode *node); -void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set); +int node_has_hidden_sockets(bNode *node, short flag); +void node_set_hidden_sockets(SpaceNode *snode, bNode *node, short flag, int set); int node_render_changed_exec(bContext *, wmOperator *); void NODE_OT_duplicate(struct wmOperatorType *ot); @@ -141,6 +143,7 @@ void NODE_OT_hide_toggle(struct wmOperatorType *ot); void NODE_OT_hide_socket_toggle(struct wmOperatorType *ot); void NODE_OT_preview_toggle(struct wmOperatorType *ot); +void NODE_OT_options_toggle(struct wmOperatorType *ot); void NODE_OT_show_cyclic_dependencies(struct wmOperatorType *ot); void NODE_OT_link_viewer(struct wmOperatorType *ot); diff -Nru blender-2.61/source/blender/editors/space_node/node_ops.c blender-2.62/source/blender/editors/space_node/node_ops.c --- blender-2.61/source/blender/editors/space_node/node_ops.c 2011-12-13 19:54:16.000000000 +0000 +++ blender-2.62/source/blender/editors/space_node/node_ops.c 2012-02-15 19:38:25.000000000 +0000 @@ -34,6 +34,8 @@ #include "BKE_context.h" +#include "BLI_utildefines.h" + #include "ED_node.h" #include "ED_screen.h" #include "ED_transform.h" @@ -59,10 +61,11 @@ WM_operatortype_append(NODE_OT_select_same_type_prev); WM_operatortype_append(NODE_OT_view_all); - WM_operatortype_append(NODE_OT_visibility_toggle); + WM_operatortype_append(NODE_OT_mute_toggle); WM_operatortype_append(NODE_OT_hide_toggle); WM_operatortype_append(NODE_OT_preview_toggle); + WM_operatortype_append(NODE_OT_options_toggle); WM_operatortype_append(NODE_OT_hide_socket_toggle); WM_operatortype_append(NODE_OT_show_cyclic_dependencies); @@ -111,8 +114,10 @@ /* modified operator call for duplicating with input links */ ot= WM_operatortype_append_macro("NODE_OT_duplicate_move_keep_inputs", "Duplicate", OPTYPE_UNDO|OPTYPE_REGISTER); ot->description = "Duplicate selected nodes keeping input links and move them"; + mot = WM_operatortype_macro_define(ot, "NODE_OT_duplicate"); - RNA_boolean_set(mot->ptr, "keep_inputs", 1); + RNA_boolean_set(mot->ptr, "keep_inputs", TRUE); + WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); ot= WM_operatortype_append_macro("NODE_OT_select_link_viewer", "Link Viewer", OPTYPE_UNDO); @@ -137,18 +142,20 @@ /* mouse select in nodes used to be both keys, but perhaps this should be reduced? * NOTE: mouse-clicks on left-mouse will fall through to allow transform-tweak, but also link/resize */ - WM_keymap_add_item(keymap, "NODE_OT_select", ACTIONMOUSE, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "NODE_OT_select", SELECTMOUSE, KM_PRESS, 0, 0); - kmi= WM_keymap_add_item(keymap, "NODE_OT_select", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0); - RNA_boolean_set(kmi->ptr, "extend", 1); - kmi= WM_keymap_add_item(keymap, "NODE_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0); - RNA_boolean_set(kmi->ptr, "extend", 1); - RNA_boolean_set(WM_keymap_add_item(keymap, "NODE_OT_select_border", EVT_TWEAK_S, KM_ANY, 0, 0)->ptr, "tweak", 1); + kmi = WM_keymap_add_item(keymap, "NODE_OT_select", ACTIONMOUSE, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + kmi = WM_keymap_add_item(keymap, "NODE_OT_select", SELECTMOUSE, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + kmi = WM_keymap_add_item(keymap, "NODE_OT_select", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "extend", TRUE); + kmi = WM_keymap_add_item(keymap, "NODE_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "extend", TRUE); + kmi = WM_keymap_add_item(keymap, "NODE_OT_select_border", EVT_TWEAK_S, KM_ANY, 0, 0); + RNA_boolean_set(kmi->ptr, "tweak", TRUE); /* each of these falls through if not handled... */ WM_keymap_add_item(keymap, "NODE_OT_link", LEFTMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "NODE_OT_resize", LEFTMOUSE, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "NODE_OT_visibility_toggle", LEFTMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "NODE_OT_links_cut", LEFTMOUSE, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "NODE_OT_select_link_viewer", LEFTMOUSE, KM_PRESS, KM_SHIFT|KM_CTRL, 0); @@ -159,10 +166,12 @@ kmi= WM_keymap_add_item(keymap, "NODE_OT_backimage_zoom", VKEY, KM_PRESS, KM_ALT, 0); RNA_float_set(kmi->ptr, "factor", 1.2f); WM_keymap_add_item(keymap, "NODE_OT_backimage_sample", ACTIONMOUSE, KM_PRESS, KM_ALT, 0); - - WM_keymap_add_item(keymap, "NODE_OT_link_make", FKEY, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "NODE_OT_link_make", FKEY, KM_PRESS, KM_CTRL, 0)->ptr, "replace", 1); - + + kmi = WM_keymap_add_item(keymap, "NODE_OT_link_make", FKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "replace", FALSE); + kmi = WM_keymap_add_item(keymap, "NODE_OT_link_make", FKEY, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "replace", TRUE); + WM_keymap_add_menu(keymap, "NODE_MT_add", AKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "NODE_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0); /* modified operator call for duplicating with input links */ @@ -176,7 +185,10 @@ WM_keymap_add_item(keymap, "NODE_OT_show_cyclic_dependencies", CKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "NODE_OT_view_all", HOMEKEY, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "NODE_OT_select_border", BKEY, KM_PRESS, 0, 0); + + kmi = WM_keymap_add_item(keymap, "NODE_OT_select_border", BKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "tweak", FALSE); + WM_keymap_add_item(keymap, "NODE_OT_delete", XKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "NODE_OT_delete", DELKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "NODE_OT_delete_reconnect", XKEY, KM_PRESS, KM_CTRL, 0); diff -Nru blender-2.61/source/blender/editors/space_node/node_select.c blender-2.62/source/blender/editors/space_node/node_select.c --- blender-2.61/source/blender/editors/space_node/node_select.c 2011-12-13 19:54:16.000000000 +0000 +++ blender-2.62/source/blender/editors/space_node/node_select.c 2012-02-15 19:38:25.000000000 +0000 @@ -31,6 +31,8 @@ #include +#include "BLI_listbase.h" + #include "DNA_node_types.h" #include "DNA_scene_types.h" @@ -68,6 +70,206 @@ return NULL; } +static int compare_nodes(bNode *a, bNode *b) +{ + bNode *parent; + /* These tell if either the node or any of the parent nodes is selected. + * A selected parent means an unselected node is also in foreground! + */ + int a_select=(a->flag & NODE_SELECT), b_select=(b->flag & NODE_SELECT); + int a_active=(a->flag & NODE_ACTIVE), b_active=(b->flag & NODE_ACTIVE); + + /* if one is an ancestor of the other */ + /* XXX there might be a better sorting algorithm for stable topological sort, this is O(n^2) worst case */ + for (parent = a->parent; parent; parent=parent->parent) { + /* if b is an ancestor, it is always behind a */ + if (parent==b) + return 1; + /* any selected ancestor moves the node forward */ + if (parent->flag & NODE_ACTIVE) + a_active = 1; + if (parent->flag & NODE_SELECT) + a_select = 1; + } + for (parent = b->parent; parent; parent=parent->parent) { + /* if a is an ancestor, it is always behind b */ + if (parent==a) + return 0; + /* any selected ancestor moves the node forward */ + if (parent->flag & NODE_ACTIVE) + b_active = 1; + if (parent->flag & NODE_SELECT) + b_select = 1; + } + + /* if one of the nodes is in the background and the other not */ + if ((a->flag & NODE_BACKGROUND) && !(b->flag & NODE_BACKGROUND)) + return 0; + else if (!(a->flag & NODE_BACKGROUND) && (b->flag & NODE_BACKGROUND)) + return 1; + + /* if one has a higher selection state (active > selected > nothing) */ + if (!b_active && a_active) + return 1; + else if (!b_select && (a_active || a_select)) + return 1; + + return 0; +} + +/* Sorts nodes by selection: unselected nodes first, then selected, + * then the active node at the very end. Relative order is kept intact! + */ +static void node_sort(bNodeTree *ntree) +{ + /* merge sort is the algorithm of choice here */ + bNode *first_a, *first_b, *node_a, *node_b, *tmp; + int totnodes= BLI_countlist(&ntree->nodes); + int k, a, b; + + k = 1; + while (k < totnodes) { + first_a = first_b = ntree->nodes.first; + + do { + /* setup first_b pointer */ + for (b=0; b < k && first_b; ++b) { + first_b = first_b->next; + } + /* all batches merged? */ + if (first_b==NULL) + break; + + /* merge batches */ + node_a = first_a; + node_b = first_b; + a = b = 0; + while (a < k && b < k && node_b) { + if (compare_nodes(node_a, node_b)==0) { + node_a = node_a->next; + ++a; + } + else { + tmp = node_b; + node_b = node_b->next; + ++b; + BLI_remlink(&ntree->nodes, tmp); + BLI_insertlinkbefore(&ntree->nodes, node_a, tmp); + } + } + + /* setup first pointers for next batch */ + first_b = node_b; + for (; b < k; ++b) { + /* all nodes sorted? */ + if (first_b==NULL) + break; + first_b = first_b->next; + } + first_a = first_b; + } while (first_b); + + k = k << 1; + } +} + +/* no undo here! */ +void node_deselect_all(SpaceNode *snode) +{ + bNode *node; + + for(node= snode->edittree->nodes.first; node; node= node->next) + node->flag &= ~SELECT; +} + +/* return 1 if we need redraw otherwise zero. */ +int node_select_same_type(SpaceNode *snode) +{ + bNode *nac, *p; + int redraw; + + /* search for the active node. */ + for (nac= snode->edittree->nodes.first; nac; nac= nac->next) { + if (nac->flag & SELECT) + break; + } + + /* no active node, return. */ + if (!nac) + return(0); + + redraw= 0; + for (p= snode->edittree->nodes.first; p; p= p->next) { + if (p->type != nac->type && p->flag & SELECT) { + /* if it's selected but different type, unselect */ + redraw= 1; + p->flag &= ~SELECT; + } + else if (p->type == nac->type && (!(p->flag & SELECT))) { + /* if it's the same type and is not selected, select! */ + redraw= 1; + p->flag |= SELECT; + } + } + return(redraw); +} + +/* return 1 if we need redraw, otherwise zero. + * dir can be 0 == next or 0 != prev. + */ +int node_select_same_type_np(SpaceNode *snode, int dir) +{ + bNode *nac, *p; + + /* search the active one. */ + for (nac= snode->edittree->nodes.first; nac; nac= nac->next) { + if (nac->flag & SELECT) + break; + } + + /* no active node, return. */ + if (!nac) + return(0); + + if (dir == 0) + p= nac->next; + else + p= nac->prev; + + while (p) { + /* Now search the next with the same type. */ + if (p->type == nac->type) + break; + + if (dir == 0) + p= p->next; + else + p= p->prev; + } + + if (p) { + node_deselect_all(snode); + p->flag |= SELECT; + return(1); + } + return(0); +} + +void node_select_single(bContext *C, bNode *node) +{ + Main *bmain= CTX_data_main(C); + SpaceNode *snode= CTX_wm_space_node(C); + + node_deselect_all(snode); + node->flag |= SELECT; + + ED_node_set_active(bmain, snode->edittree, node); + + node_sort(snode->edittree); + + WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL); +} + /* ****** Click Select ****** */ static bNode *node_mouse_select(Main *bmain, SpaceNode *snode, ARegion *ar, const int mval[2], short extend) @@ -86,7 +288,7 @@ if (node) { if (extend == 0) { - node_deselectall(snode); + node_deselect_all(snode); node->flag |= SELECT; } else diff -Nru blender-2.61/source/blender/editors/space_node/node_state.c blender-2.62/source/blender/editors/space_node/node_state.c --- blender-2.61/source/blender/editors/space_node/node_state.c 2011-12-13 19:54:16.000000000 +0000 +++ blender-2.62/source/blender/editors/space_node/node_state.c 2012-02-15 19:38:25.000000000 +0000 @@ -52,160 +52,6 @@ #include "node_intern.h" -/* **************** Node Header Buttons ************** */ - -/* note: call node_tree_verify_groups(snode->nodetree) after this - */ -void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set) -{ - bNodeSocket *sock; - - if(set==0) { - for(sock= node->inputs.first; sock; sock= sock->next) - sock->flag &= ~SOCK_HIDDEN; - for(sock= node->outputs.first; sock; sock= sock->next) - sock->flag &= ~SOCK_HIDDEN; - } - else { - /* hide unused sockets */ - for(sock= node->inputs.first; sock; sock= sock->next) { - if(sock->link==NULL) - sock->flag |= SOCK_HIDDEN; - } - for(sock= node->outputs.first; sock; sock= sock->next) { - if(nodeCountSocketLinks(snode->edittree, sock)==0) - sock->flag |= SOCK_HIDDEN; - } - } -} - -static void node_hide_unhide_sockets(SpaceNode *snode, bNode *node) -{ - node_set_hidden_sockets(snode, node, !node_has_hidden_sockets(node)); - ntreeUpdateTree(snode->edittree); -} - -static int do_header_node(SpaceNode *snode, bNode *node, float mx, float my) -{ - rctf totr= node->totr; - - totr.ymin= totr.ymax-20.0f; - - totr.xmax= totr.xmin+15.0f; - if(BLI_in_rctf(&totr, mx, my)) { - node->flag |= NODE_HIDDEN; - return 1; - } - - totr.xmax= node->totr.xmax; - totr.xmin= totr.xmax-18.0f; - if(node->typeinfo->flag & NODE_PREVIEW) { - if(BLI_in_rctf(&totr, mx, my)) { - node->flag ^= NODE_PREVIEW; - return 1; - } - totr.xmin-=15.0f; - } - if(node->type == NODE_GROUP) { - if(BLI_in_rctf(&totr, mx, my)) { - snode_make_group_editable(snode, node); - return 1; - } - totr.xmin-=15.0f; - } - if(node->typeinfo->flag & NODE_OPTIONS) { - if(BLI_in_rctf(&totr, mx, my)) { - node->flag ^= NODE_OPTIONS; - return 1; - } - totr.xmin-=15.0f; - } - /* hide unused sockets */ - if(BLI_in_rctf(&totr, mx, my)) { - node_hide_unhide_sockets(snode, node); - } - - return 0; -} - -static int do_header_hidden_node(bNode *node, float mx, float my) -{ - rctf totr= node->totr; - - totr.xmax= totr.xmin+15.0f; - if(BLI_in_rctf(&totr, mx, my)) { - node->flag &= ~NODE_HIDDEN; - return 1; - } - return 0; -} - -static int node_toggle_visibility(SpaceNode *snode, ARegion *ar, const int mval[2]) -{ - bNode *node; - float mx, my; - - mx= (float)mval[0]; - my= (float)mval[1]; - - UI_view2d_region_to_view(&ar->v2d, mval[0], mval[1], &mx, &my); - - for(node=snode->edittree->nodes.last; node; node=node->prev) { - if(node->flag & NODE_HIDDEN) { - if(do_header_hidden_node(node, mx, my)) { - ED_region_tag_redraw(ar); - return 1; - } - } - else { - if(do_header_node(snode, node, mx, my)) { - ED_region_tag_redraw(ar); - return 1; - } - } - } - return 0; -} - -static int node_toggle_visibility_exec(bContext *C, wmOperator *op) -{ - SpaceNode *snode= CTX_wm_space_node(C); - ARegion *ar= CTX_wm_region(C); - int mval[2]; - - mval[0] = RNA_int_get(op->ptr, "mouse_x"); - mval[1] = RNA_int_get(op->ptr, "mouse_y"); - if(node_toggle_visibility(snode, ar, mval)) - return OPERATOR_FINISHED; - else - return OPERATOR_CANCELLED|OPERATOR_PASS_THROUGH; -} - -static int node_toggle_visibility_invoke(bContext *C, wmOperator *op, wmEvent *event) -{ - RNA_int_set(op->ptr, "mouse_x", event->mval[0]); - RNA_int_set(op->ptr, "mouse_y", event->mval[1]); - - return node_toggle_visibility_exec(C,op); -} - -void NODE_OT_visibility_toggle(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Toggle Visibility"; - ot->idname= "NODE_OT_visibility_toggle"; - ot->description= "Handle clicks on node header buttons"; - - /* api callbacks */ - ot->invoke= node_toggle_visibility_invoke; - ot->poll= ED_operator_node_active; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - RNA_def_int(ot->srna, "mouse_x", 0, INT_MIN, INT_MAX, "Mouse X", "", INT_MIN, INT_MAX); - RNA_def_int(ot->srna, "mouse_y", 0, INT_MIN, INT_MAX, "Mouse Y", "", INT_MIN, INT_MAX); -} /* **************** View All Operator ************** */ diff -Nru blender-2.61/source/blender/editors/space_node/node_templates.c blender-2.62/source/blender/editors/space_node/node_templates.c --- blender-2.61/source/blender/editors/space_node/node_templates.c 2011-12-13 19:54:16.000000000 +0000 +++ blender-2.62/source/blender/editors/space_node/node_templates.c 2012-02-15 19:38:25.000000000 +0000 @@ -1,6 +1,4 @@ /* - * $Id$ - * * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or @@ -51,6 +49,8 @@ #include "RNA_access.h" +#include "NOD_socket.h" + #include "WM_api.h" #include "WM_types.h" @@ -207,12 +207,9 @@ nodeRemLink(ntree, link); } - if(sock_prev->default_value) { - if(sock_from->default_value) - MEM_freeN(sock_from->default_value); - - sock_from->default_value = MEM_dupallocN(sock_prev->default_value); - } + node_socket_free_default_value(sock_from->type, sock_from->default_value); + sock_from->default_value = node_socket_make_default_value(sock_from->type); + node_socket_copy_default_value(sock_from->type, sock_from->default_value, sock_prev->default_value); } } } diff -Nru blender-2.61/source/blender/editors/space_node/space_node.c blender-2.62/source/blender/editors/space_node/space_node.c --- blender-2.61/source/blender/editors/space_node/space_node.c 2011-12-13 19:54:16.000000000 +0000 +++ blender-2.62/source/blender/editors/space_node/space_node.c 2012-02-15 19:38:25.000000000 +0000 @@ -169,6 +169,7 @@ /* note, ED_area_tag_refresh will re-execute compositor */ SpaceNode *snode= sa->spacedata.first; int type= snode->treetype; + short shader_type = snode->shaderfrom; /* preview renders */ switch(wmn->category) { @@ -214,6 +215,11 @@ ED_area_tag_refresh(sa); } break; + case NC_WORLD: + if(type==NTREE_SHADER && shader_type==SNODE_SHADER_WORLD) { + ED_area_tag_refresh(sa); + } + break; case NC_OBJECT: if(type==NTREE_SHADER) { if(wmn->data==ND_OB_SHADING) @@ -248,12 +254,10 @@ case NC_IMAGE: if (wmn->action == NA_EDITED) { if(type==NTREE_COMPOSIT) { - Scene *scene= wmn->window->screen->scene; - /* note that nodeUpdateID is already called by BKE_image_signal() on all * scenes so really this is just to know if the images is used in the compo else * painting on images could become very slow when the compositor is open. */ - if(nodeUpdateID(scene->nodetree, wmn->reference)) + if(nodeUpdateID(snode->nodetree, wmn->reference)) ED_area_tag_refresh(sa); } } diff -Nru blender-2.61/source/blender/editors/space_outliner/outliner_draw.c blender-2.62/source/blender/editors/space_outliner/outliner_draw.c --- blender-2.61/source/blender/editors/space_outliner/outliner_draw.c 2011-12-13 19:52:28.000000000 +0000 +++ blender-2.62/source/blender/editors/space_outliner/outliner_draw.c 2012-02-15 19:37:02.000000000 +0000 @@ -441,15 +441,15 @@ uiBlockSetEmboss(block, UI_EMBOSSN); restrict_bool= group_restrict_flag(gr, OB_RESTRICT_VIEW); - bt = uiDefIconBut(block, BUT, 0, restrict_bool ? ICON_RESTRICT_VIEW_ON : ICON_RESTRICT_VIEW_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, NULL, 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View"); + bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_VIEW_ON : ICON_RESTRICT_VIEW_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, NULL, 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View"); uiButSetFunc(bt, restrictbutton_gr_restrict_view, scene, gr); restrict_bool= group_restrict_flag(gr, OB_RESTRICT_SELECT); - bt = uiDefIconBut(block, BUT, 0, restrict_bool ? ICON_RESTRICT_SELECT_ON : ICON_RESTRICT_SELECT_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, NULL, 0, 0, 0, 0, "Restrict/Allow selection in the 3D View"); + bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_SELECT_ON : ICON_RESTRICT_SELECT_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, NULL, 0, 0, 0, 0, "Restrict/Allow selection in the 3D View"); uiButSetFunc(bt, restrictbutton_gr_restrict_select, scene, gr); restrict_bool= group_restrict_flag(gr, OB_RESTRICT_RENDER); - bt = uiDefIconBut(block, BUT, 0, restrict_bool ? ICON_RESTRICT_RENDER_ON : ICON_RESTRICT_RENDER_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, NULL, 0, 0, 0, 0, "Restrict/Allow renderability"); + bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_RENDER_ON : ICON_RESTRICT_RENDER_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, NULL, 0, 0, 0, 0, "Restrict/Allow renderability"); uiButSetFunc(bt, restrictbutton_gr_restrict_render, scene, gr); uiBlockSetEmboss(block, UI_EMBOSS); @@ -628,7 +628,7 @@ /* fake button, it holds space for search items */ uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL); - but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 0, 150, UI_UNIT_Y, 0, 0, ""); + but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, 150, UI_UNIT_Y, 0, 0, ""); uiButSetSearchFunc(but, operator_search_cb, arg_kmi, operator_call_cb, ot); uiBoundsBlock(block, 6); @@ -1014,12 +1014,18 @@ UI_icon_draw(x, y, ICON_MOD_SOLIDIFY); break; case eModifierType_Screw: UI_icon_draw(x, y, ICON_MOD_SCREW); break; + case eModifierType_Remesh: + UI_icon_draw(x, y, ICON_MOD_REMESH); break; case eModifierType_WeightVGEdit: case eModifierType_WeightVGMix: case eModifierType_WeightVGProximity: UI_icon_draw(x, y, ICON_MOD_VERTEX_WEIGHT); break; case eModifierType_DynamicPaint: UI_icon_draw(x, y, ICON_MOD_DYNAMICPAINT); break; + case eModifierType_Ocean: + UI_icon_draw(x, y, ICON_MOD_OCEAN); break; + case eModifierType_Warp: + UI_icon_draw(x, y, ICON_MOD_WARP); break; default: UI_icon_draw(x, y, ICON_DOT); break; } @@ -1256,8 +1262,10 @@ if ( (SEARCHING_OUTLINER(soops) || (soops->outlinevis==SO_DATABLOCKS && soops->search_string[0]!=0)) && (tselem->flag & TSE_SEARCHMATCH)) { - /* TODO - add search highlight color to theme? */ - glColor4f(0.2f, 0.5f, 0.2f, 0.3f); + char col[4]; + UI_GetThemeColorType4ubv(TH_MATCH, SPACE_OUTLINER, col); + col[3]=100; + glColor4ubv((GLubyte *)col); glRecti(startx, *starty+1, ar->v2d.cur.xmax, *starty+UI_UNIT_Y-1); } @@ -1511,8 +1519,8 @@ } /* always draw selection fill before hierarchy */ - UI_GetThemeColor3fv(TH_BACK, col); - glColor3f(col[0]+0.06f, col[1]+0.08f, col[2]+0.10f); + UI_GetThemeColor3fv(TH_SELECT_HIGHLIGHT, col); + glColor3fv(col); starty= (int)ar->v2d.tot.ymax-UI_UNIT_Y-OL_Y_OFFSET; outliner_draw_selection(ar, soops, &soops->tree, &starty); @@ -1647,7 +1655,7 @@ /* draw outliner stuff (background, hierachy lines and names) */ outliner_back(ar); - block= uiBeginBlock(C, ar, "outliner buttons", UI_EMBOSS); + block= uiBeginBlock(C, ar, __func__, UI_EMBOSS); outliner_draw_tree((bContext *)C, block, scene, ar, soops); if(ELEM(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF)) { diff -Nru blender-2.61/source/blender/editors/space_outliner/outliner_edit.c blender-2.62/source/blender/editors/space_outliner/outliner_edit.c --- blender-2.61/source/blender/editors/space_outliner/outliner_edit.c 2011-12-13 19:52:28.000000000 +0000 +++ blender-2.62/source/blender/editors/space_outliner/outliner_edit.c 2012-02-15 19:37:02.000000000 +0000 @@ -221,12 +221,17 @@ static void do_item_rename(ARegion *ar, TreeElement *te, TreeStoreElem *tselem, ReportList *reports) { /* can't rename rna datablocks entries */ - if(ELEM3(tselem->type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) - ; - else if(ELEM10(tselem->type, TSE_ANIM_DATA, TSE_NLA, TSE_DEFGROUP_BASE, TSE_CONSTRAINT_BASE, TSE_MODIFIER_BASE, TSE_SCRIPT_BASE, TSE_POSE_BASE, TSE_POSEGRP_BASE, TSE_R_LAYER_BASE, TSE_R_PASS)) + if(ELEM3(tselem->type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) { + /* do nothing */; + } + else if(ELEM10(tselem->type, TSE_ANIM_DATA, TSE_NLA, TSE_DEFGROUP_BASE, TSE_CONSTRAINT_BASE, TSE_MODIFIER_BASE, + TSE_SCRIPT_BASE, TSE_POSE_BASE, TSE_POSEGRP_BASE, TSE_R_LAYER_BASE, TSE_R_PASS)) + { BKE_report(reports, RPT_WARNING, "Cannot edit builtin name"); - else if(ELEM3(tselem->type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP)) + } + else if(ELEM3(tselem->type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP)) { BKE_report(reports, RPT_WARNING, "Cannot edit sequence name"); + } else if(tselem->id->lib) { // XXX error_libdata(); } @@ -491,11 +496,10 @@ { SpaceOops *soops= CTX_wm_space_outliner(C); Scene *scene= CTX_data_scene(C); - ARegion *ar= CTX_wm_region(C); outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_renderability_cb); - ED_region_tag_redraw(ar); + WM_event_add_notifier(C, NC_SCENE|ND_OB_RENDER, scene); return OPERATOR_FINISHED; } @@ -744,7 +748,7 @@ TreeElement *last_find; TreeStoreElem *tselem; int ytop, xdelta, prevFound=0; - char name[32]; + char name[sizeof(soops->search_string)]; /* get last found tree-element based on stored search_tse */ last_find= outliner_find_tse(soops, &soops->search_tse); @@ -798,7 +802,7 @@ /* store selection */ soops->search_tse= *tselem; - BLI_strncpy(soops->search_string, name, 33); + BLI_strncpy(soops->search_string, name, sizeof(soops->search_string)); soops->search_flags= flags; /* redraw */ @@ -1424,3 +1428,278 @@ /* flags */ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; } + +/* ******************** Parent Drop Operator *********************** */ + +static int parent_drop_exec(bContext *C, wmOperator *op) +{ + Object *par = NULL; + int partype = -1; + char parname[32]; + + partype= RNA_enum_get(op->ptr, "type"); + RNA_string_get(op->ptr, "parent", parname); + par= (Object *)find_id("OB", parname); + + ED_object_parent_set(C, op, par, partype); + + return OPERATOR_FINISHED; +} + +/* Used for drag and drop parenting */ +TreeElement *outliner_dropzone_parent(bContext *C, wmEvent *event, TreeElement *te, float *fmval) +{ + SpaceOops *soops= CTX_wm_space_outliner(C); + TreeStoreElem *tselem= TREESTORE(te); + + if ((fmval[1] > te->ys) && (fmval[1] < (te->ys + UI_UNIT_Y))) { + /* name and first icon */ + if ((fmval[0] > te->xs + UI_UNIT_X) && (fmval[0] < te->xend)) { + /* always makes active object */ + if (te->idcode == ID_OB) { + return te; + } + else { + return NULL; + } + } + } + + /* Not it. Let's look at its children. */ + if ((tselem->flag & TSE_CLOSED)==0 && (te->subtree.first)) { + for (te = te->subtree.first; te; te = te->next) { + TreeElement *te_valid; + te_valid= outliner_dropzone_parent(C, event, te, fmval); + if (te_valid) return te_valid; + } + } + return NULL; +} + +static int parent_drop_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + Object *par= NULL; + Object *ob= NULL; + SpaceOops *soops= CTX_wm_space_outliner(C); + ARegion *ar= CTX_wm_region(C); + Scene *scene= CTX_data_scene(C); + TreeElement *te= NULL; + TreeElement *te_found= NULL; + char childname[MAX_ID_NAME]; + char parname[MAX_ID_NAME]; + int partype= 0; + float fmval[2]; + + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); + + /* Find object hovered over */ + for (te= soops->tree.first; te; te= te->next) { + te_found= outliner_dropzone_parent(C, event, te, fmval); + if (te_found) break; + } + + if(te_found) { + RNA_string_set(op->ptr, "parent", te_found->name); + /* Identify parent and child */ + RNA_string_get(op->ptr, "child", childname); + ob= (Object *)find_id("OB", childname); + RNA_string_get(op->ptr, "parent", parname); + par= (Object *)find_id("OB", parname); + + if (ELEM(NULL, ob, par)) { + if (par == NULL) printf("par==NULL\n"); + return OPERATOR_CANCELLED; + } + if (ob == par) { + return OPERATOR_CANCELLED; + } + + /* check dragged object (child) is active */ + if (ob != CTX_data_active_object(C)) + ED_base_object_select(object_in_scene(ob, scene), BA_SELECT); + + if ((par->type != OB_ARMATURE) && (par->type != OB_CURVE) && (par->type != OB_LATTICE)) { + ED_object_parent_set(C, op, par, partype); + } + else { + /* Menu creation */ + uiPopupMenu *pup= uiPupMenuBegin(C, "Set Parent To", ICON_NONE); + uiLayout *layout= uiPupMenuLayout(pup); + + PointerRNA ptr; + + WM_operator_properties_create(&ptr, "OUTLINER_OT_parent_drop"); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_OBJECT); + /* Cannot use uiItemEnumO()... have multiple properties to set. */ + uiItemFullO(layout, "OUTLINER_OT_parent_drop", "Object", 0, ptr.data, WM_OP_EXEC_DEFAULT, 0); + + /* par becomes parent, make the associated menus */ + if (par->type==OB_ARMATURE) { + WM_operator_properties_create(&ptr, "OUTLINER_OT_parent_drop"); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_ARMATURE); + uiItemFullO(layout, "OUTLINER_OT_parent_drop", "Armature Deform", 0, ptr.data, WM_OP_EXEC_DEFAULT, 0); + + WM_operator_properties_create(&ptr, "OUTLINER_OT_parent_drop"); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_ARMATURE_NAME); + uiItemFullO(layout, "OUTLINER_OT_parent_drop", " With Empty Groups", 0, ptr.data, WM_OP_EXEC_DEFAULT, 0); + + WM_operator_properties_create(&ptr, "OUTLINER_OT_parent_drop"); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_ARMATURE_ENVELOPE); + uiItemFullO(layout, "OUTLINER_OT_parent_drop", " With Envelope Weights", 0, ptr.data, WM_OP_EXEC_DEFAULT, 0); + + WM_operator_properties_create(&ptr, "OUTLINER_OT_parent_drop"); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_ARMATURE_AUTO); + uiItemFullO(layout, "OUTLINER_OT_parent_drop", " With Automatic Weights", 0, ptr.data, WM_OP_EXEC_DEFAULT, 0); + + WM_operator_properties_create(&ptr, "OUTLINER_OT_parent_drop"); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_BONE); + uiItemFullO(layout, "OUTLINER_OT_parent_drop", "Bone", 0, ptr.data, WM_OP_EXEC_DEFAULT, 0); + } + else if (par->type==OB_CURVE) { + WM_operator_properties_create(&ptr, "OUTLINER_OT_parent_drop"); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_CURVE); + uiItemFullO(layout, "OUTLINER_OT_parent_drop", "Curve Deform", 0, ptr.data, WM_OP_EXEC_DEFAULT, 0); + + WM_operator_properties_create(&ptr, "OUTLINER_OT_parent_drop"); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_FOLLOW); + uiItemFullO(layout, "OUTLINER_OT_parent_drop", "Follow Path", 0, ptr.data, WM_OP_EXEC_DEFAULT, 0); + + WM_operator_properties_create(&ptr, "OUTLINER_OT_parent_drop"); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_PATH_CONST); + uiItemFullO(layout, "OUTLINER_OT_parent_drop", "Path Constraint", 0, ptr.data, WM_OP_EXEC_DEFAULT, 0); + } + else if (par->type == OB_LATTICE) { + WM_operator_properties_create(&ptr, "OUTLINER_OT_parent_drop"); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_LATTICE); + uiItemFullO(layout, "OUTLINER_OT_parent_drop", "Lattice Deform", 0, ptr.data, WM_OP_EXEC_DEFAULT, 0); + } + + uiPupMenuEnd(C, pup); + + return OPERATOR_CANCELLED; + } + } + else { + return OPERATOR_CANCELLED; + } + + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_parent_drop(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Drop to Set Parent"; + ot->description = "Drag to parent in Outliner"; + ot->idname= "OUTLINER_OT_parent_drop"; + + /* api callbacks */ + ot->invoke= parent_drop_invoke; + ot->exec= parent_drop_exec; + + ot->poll= ED_operator_outliner_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_string(ot->srna, "child", "Object", MAX_ID_NAME, "Child", "Child Object"); + RNA_def_string(ot->srna, "parent", "Object", MAX_ID_NAME, "Parent", "Parent Object"); + RNA_def_enum(ot->srna, "type", prop_make_parent_types, 0, "Type", ""); +} + +int outliner_dropzone_parent_clear(bContext *C, wmEvent *event, TreeElement *te, float *fmval) +{ + SpaceOops *soops= CTX_wm_space_outliner(C); + TreeStoreElem *tselem= TREESTORE(te); + + /* Check for row */ + if ((fmval[1] > te->ys) && (fmval[1] < (te->ys + UI_UNIT_Y))) { + /* Ignore drop on scene tree elements */ + if ((fmval[0] > te->xs + UI_UNIT_X) && (fmval[0] < te->xend)) { + if ((te->idcode == ID_SCE) && + !ELEM3(tselem->type, TSE_R_LAYER_BASE, TSE_R_LAYER, TSE_R_PASS)) + { + return 0; + } + // Other codes to ignore? + } + + /* Left or right of: (+), first icon, and name */ + if ((fmval[0] < (te->xs + UI_UNIT_X)) || (fmval[0] > te->xend)) { + return 1; + } + else if (te->idcode != ID_OB) { + return 1; + } + + return 0; // ID_OB, but mouse in undefined dropzone. + } + + /* Not this row. Let's look at its children. */ + if ((tselem->flag & TSE_CLOSED)==0 && (te->subtree.first)) { + for (te = te->subtree.first; te; te = te->next) { + if (outliner_dropzone_parent_clear(C, event, te, fmval)) + return 1; + } + } + return 0; +} + +static int parent_clear_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) +{ + Scene *scene= CTX_data_scene(C); + Object *ob= NULL; + char obname[MAX_ID_NAME]; + + RNA_string_get(op->ptr, "dragged_obj", obname); + ob= (Object *)find_id("OB", obname); + + /* check dragged object (child) is active */ + if (ob != CTX_data_active_object(C)) + ED_base_object_select(object_in_scene(ob, scene), BA_SELECT); + + ED_object_parent_clear(C, RNA_enum_get(op->ptr, "type")); + + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_parent_clear(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Drop to Clear Parent"; + ot->description = "Drag to clear parent in Outliner"; + ot->idname= "OUTLINER_OT_parent_clear"; + + /* api callbacks */ + ot->invoke= parent_clear_invoke; + + ot->poll= ED_operator_outliner_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_string(ot->srna, "dragged_obj", "Object", MAX_ID_NAME, "Child", "Child Object"); + RNA_def_enum(ot->srna, "type", prop_clear_parent_types, 0, "Type", ""); +} diff -Nru blender-2.61/source/blender/editors/space_outliner/outliner_intern.h blender-2.62/source/blender/editors/space_outliner/outliner_intern.h --- blender-2.61/source/blender/editors/space_outliner/outliner_intern.h 2011-12-13 19:52:28.000000000 +0000 +++ blender-2.62/source/blender/editors/space_outliner/outliner_intern.h 2012-02-15 19:37:02.000000000 +0000 @@ -188,6 +188,9 @@ void item_rename_cb(struct bContext *C, struct Scene *scene, TreeElement *te, struct TreeStoreElem *tsep, struct TreeStoreElem *tselem); +TreeElement *outliner_dropzone_parent(struct bContext *C, struct wmEvent *event, struct TreeElement *te, float *fmval); +int outliner_dropzone_parent_clear(struct bContext *C, struct wmEvent *event, struct TreeElement *te, float *fmval); + /* ...................................................... */ void OUTLINER_OT_item_activate(struct wmOperatorType *ot); @@ -198,6 +201,8 @@ void OUTLINER_OT_show_active(struct wmOperatorType *ot); void OUTLINER_OT_show_hierarchy(struct wmOperatorType *ot); +void OUTLINER_OT_select_border(struct wmOperatorType *ot); + void OUTLINER_OT_selected_toggle(struct wmOperatorType *ot); void OUTLINER_OT_expanded_toggle(struct wmOperatorType *ot); @@ -213,6 +218,9 @@ void OUTLINER_OT_drivers_add_selected(struct wmOperatorType *ot); void OUTLINER_OT_drivers_delete_selected(struct wmOperatorType *ot); +void OUTLINER_OT_parent_drop(struct wmOperatorType *ot); +void OUTLINER_OT_parent_clear(struct wmOperatorType *ot); + /* outliner_tools.c ---------------------------------------------- */ void OUTLINER_OT_operation(struct wmOperatorType *ot); diff -Nru blender-2.61/source/blender/editors/space_outliner/outliner_ops.c blender-2.62/source/blender/editors/space_outliner/outliner_ops.c --- blender-2.61/source/blender/editors/space_outliner/outliner_ops.c 2011-12-13 19:52:28.000000000 +0000 +++ blender-2.62/source/blender/editors/space_outliner/outliner_ops.c 2012-02-15 19:37:02.000000000 +0000 @@ -38,6 +38,7 @@ #include "RNA_access.h" +#include "BLI_utildefines.h" #include "outliner_intern.h" @@ -48,6 +49,7 @@ void outliner_operatortypes(void) { WM_operatortype_append(OUTLINER_OT_item_activate); + WM_operatortype_append(OUTLINER_OT_select_border); WM_operatortype_append(OUTLINER_OT_item_openclose); WM_operatortype_append(OUTLINER_OT_item_rename); WM_operatortype_append(OUTLINER_OT_operation); @@ -75,19 +77,29 @@ WM_operatortype_append(OUTLINER_OT_drivers_add_selected); WM_operatortype_append(OUTLINER_OT_drivers_delete_selected); + + WM_operatortype_append(OUTLINER_OT_parent_drop); + WM_operatortype_append(OUTLINER_OT_parent_clear); } void outliner_keymap(wmKeyConfig *keyconf) { wmKeyMap *keymap= WM_keymap_find(keyconf, "Outliner", SPACE_OUTLINER, 0); + wmKeyMapItem *kmi; WM_keymap_add_item(keymap, "OUTLINER_OT_item_rename", LEFTMOUSE, KM_DBL_CLICK, 0, 0); - - RNA_boolean_set(WM_keymap_add_item(keymap, "OUTLINER_OT_item_activate", LEFTMOUSE, KM_CLICK, 0, 0)->ptr, "extend", 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "OUTLINER_OT_item_activate", LEFTMOUSE, KM_CLICK, KM_SHIFT, 0)->ptr, "extend", 1); - - RNA_boolean_set(WM_keymap_add_item(keymap, "OUTLINER_OT_item_openclose", RETKEY, KM_PRESS, 0, 0)->ptr, "all", 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "OUTLINER_OT_item_openclose", RETKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "all", 1); + + kmi = WM_keymap_add_item(keymap, "OUTLINER_OT_item_activate", LEFTMOUSE, KM_CLICK, 0, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + kmi = WM_keymap_add_item(keymap, "OUTLINER_OT_item_activate", LEFTMOUSE, KM_CLICK, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "extend", TRUE); + + WM_keymap_add_item(keymap, "OUTLINER_OT_select_border", BKEY, KM_PRESS, 0, 0); + + kmi = WM_keymap_add_item(keymap, "OUTLINER_OT_item_openclose", RETKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "all", FALSE); + kmi = WM_keymap_add_item(keymap, "OUTLINER_OT_item_openclose", RETKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "all", TRUE); WM_keymap_add_item(keymap, "OUTLINER_OT_item_rename", LEFTMOUSE, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "OUTLINER_OT_operation", RIGHTMOUSE, KM_PRESS, 0, 0); @@ -98,10 +110,12 @@ WM_keymap_add_item(keymap, "OUTLINER_OT_show_active", PADPERIOD, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "OUTLINER_OT_scroll_page", PAGEDOWNKEY, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "OUTLINER_OT_scroll_page", PAGEUPKEY, KM_PRESS, 0, 0)->ptr, "up", 1); + kmi = WM_keymap_add_item(keymap, "OUTLINER_OT_scroll_page", PAGEUPKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "up", TRUE); WM_keymap_add_item(keymap, "OUTLINER_OT_show_one_level", PADPLUSKEY, KM_PRESS, 0, 0); /* open */ - RNA_boolean_set(WM_keymap_add_item(keymap, "OUTLINER_OT_show_one_level", PADMINUS, KM_PRESS, 0, 0)->ptr, "open", 0); /* close */ + kmi = WM_keymap_add_item(keymap, "OUTLINER_OT_show_one_level", PADMINUS, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "open", FALSE); /* close */ WM_keymap_verify_item(keymap, "OUTLINER_OT_selected_toggle", AKEY, KM_PRESS, 0, 0); WM_keymap_verify_item(keymap, "OUTLINER_OT_expanded_toggle", AKEY, KM_PRESS, KM_SHIFT, 0); diff -Nru blender-2.61/source/blender/editors/space_outliner/outliner_select.c blender-2.62/source/blender/editors/space_outliner/outliner_select.c --- blender-2.61/source/blender/editors/space_outliner/outliner_select.c 2011-12-13 19:52:28.000000000 +0000 +++ blender-2.62/source/blender/editors/space_outliner/outliner_select.c 2012-02-15 19:37:02.000000000 +0000 @@ -396,8 +396,8 @@ /* id in tselem is object */ ob= (Object *)tselem->id; if(set) { + BLI_assert(te->index+1 >= 0); ob->actdef= te->index+1; - BLI_assert(ob->actdef >= 0); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob); @@ -823,8 +823,12 @@ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], fmval, fmval+1); - if(!ELEM3(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF, SO_KEYMAP) && !(soops->flag & SO_HIDE_RESTRICTCOLS) && fmval[0] > ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX) + if ( !ELEM3(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF, SO_KEYMAP) && + !(soops->flag & SO_HIDE_RESTRICTCOLS) && + (fmval[0] > ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX)) + { return OPERATOR_CANCELLED; + } for(te= soops->tree.first; te; te= te->next) { if(do_outliner_item_activate(C, scene, ar, soops, te, extend, fmval)) break; @@ -871,3 +875,78 @@ } /* ****************************************************** */ + +/* **************** Border Select Tool ****************** */ +static void outliner_item_border_select(Scene *scene, SpaceOops *soops, rctf *rectf, TreeElement *te, int gesture_mode) +{ + TreeStoreElem *tselem= TREESTORE(te); + + if (te->ys <= rectf->ymax && te->ys + UI_UNIT_Y >= rectf->ymin) { + if (gesture_mode == GESTURE_MODAL_SELECT) { + tselem->flag |= TSE_SELECTED; + } + else { + tselem->flag &= ~TSE_SELECTED; + } + } + + /* Look at its children. */ + if ((tselem->flag & TSE_CLOSED) == 0) { + for (te = te->subtree.first; te; te = te->next) { + outliner_item_border_select(scene, soops, rectf, te, gesture_mode); + } + } + return; +} + +static int outliner_border_select_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + SpaceOops *soops= CTX_wm_space_outliner(C); + ARegion *ar= CTX_wm_region(C); + TreeElement *te; + rcti rect; + rctf rectf; + int gesture_mode= RNA_int_get(op->ptr, "gesture_mode"); + + rect.xmin= RNA_int_get(op->ptr, "xmin"); + rect.ymin= RNA_int_get(op->ptr, "ymin"); + UI_view2d_region_to_view(&ar->v2d, rect.xmin, rect.ymin, &rectf.xmin, &rectf.ymin); + + rect.xmax= RNA_int_get(op->ptr, "xmax"); + rect.ymax= RNA_int_get(op->ptr, "ymax"); + UI_view2d_region_to_view(&ar->v2d, rect.xmax, rect.ymax, &rectf.xmax, &rectf.ymax); + + for(te= soops->tree.first; te; te= te->next) { + outliner_item_border_select(scene, soops, &rectf, te, gesture_mode); + } + + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); + ED_region_tag_redraw(ar); + + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_select_border(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Border Select"; + ot->idname= "OUTLINER_OT_select_border"; + ot->description= "Use box selection to select tree elements"; + + /* api callbacks */ + ot->invoke= WM_border_select_invoke; + ot->exec= outliner_border_select_exec; + ot->modal= WM_border_select_modal; + ot->cancel= WM_border_select_cancel; + + ot->poll= ED_operator_outliner_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* rna */ + WM_operator_properties_gesture_border(ot, FALSE); +} + +/* ****************************************************** */ diff -Nru blender-2.61/source/blender/editors/space_outliner/outliner_tree.c blender-2.62/source/blender/editors/space_outliner/outliner_tree.c --- blender-2.61/source/blender/editors/space_outliner/outliner_tree.c 2011-12-13 19:52:28.000000000 +0000 +++ blender-2.62/source/blender/editors/space_outliner/outliner_tree.c 2012-02-15 19:37:02.000000000 +0000 @@ -57,7 +57,7 @@ #include "BLI_utildefines.h" #include "BLI_math_base.h" -#if defined WIN32 && !defined _LIBC +#if defined WIN32 && !defined _LIBC || defined __sun # include "BLI_fnmatch.h" /* use fnmatch included in blenlib */ #else # ifndef _GNU_SOURCE @@ -1342,7 +1342,7 @@ } else { char fn_name[sizeof(((struct SpaceOops *)NULL)->search_string) + 2]; - sprintf(fn_name, "*%s*", name); + BLI_snprintf(fn_name, sizeof(fn_name), "*%s*", name); found= fnmatch(fn_name, te->name, fn_flag)==0; } return found; diff -Nru blender-2.61/source/blender/editors/space_outliner/space_outliner.c blender-2.62/source/blender/editors/space_outliner/space_outliner.c --- blender-2.61/source/blender/editors/space_outliner/space_outliner.c 2011-12-13 19:52:28.000000000 +0000 +++ blender-2.62/source/blender/editors/space_outliner/space_outliner.c 2012-02-15 19:37:02.000000000 +0000 @@ -50,6 +50,8 @@ #include "BIF_gl.h" +#include "RNA_access.h" + #include "UI_resources.h" #include "UI_view2d.h" @@ -58,6 +60,7 @@ static void outliner_main_area_init(wmWindowManager *wm, ARegion *ar) { + ListBase *lb; wmKeyMap *keymap; UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy); @@ -66,6 +69,88 @@ keymap= WM_keymap_find(wm->defaultconf, "Outliner", SPACE_OUTLINER, 0); /* don't pass on view2d mask, it's always set with scrollbar space, hide fails */ WM_event_add_keymap_handler_bb(&ar->handlers, keymap, NULL, &ar->winrct); + + /* Add dropboxes */ + lb = WM_dropboxmap_find("Outliner", SPACE_OUTLINER, RGN_TYPE_WINDOW); + WM_event_add_dropbox_handler(&ar->handlers, lb); +} + +static int outliner_parent_drop_poll(bContext *C, wmDrag *drag, wmEvent *event) +{ + ARegion *ar= CTX_wm_region(C); + SpaceOops *soops= CTX_wm_space_outliner(C); + TreeElement *te= NULL; + float fmval[2]; + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); + + if(drag->type == WM_DRAG_ID) { + ID *id = (ID *)drag->poin; + if( GS(id->name) == ID_OB ) { + /* Ensure item under cursor is valid drop target */ + /* Find object hovered over */ + for(te= soops->tree.first; te; te= te->next) { + TreeElement *te_valid; + te_valid= outliner_dropzone_parent(C, event, te, fmval); + if(te_valid) return 1; + } + } + } + return 0; +} + +static void outliner_parent_drop_copy(wmDrag *drag, wmDropBox *drop) +{ + ID *id = (ID *)drag->poin; + + RNA_string_set(drop->ptr, "child", id->name+2); +} + +static int outliner_parent_clear_poll(bContext *C, wmDrag *drag, wmEvent *event) +{ + ARegion *ar= CTX_wm_region(C); + SpaceOops *soops= CTX_wm_space_outliner(C); + TreeElement *te= NULL; + float fmval[2]; + + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); + + if(drag->type == WM_DRAG_ID) { + ID *id = (ID *)drag->poin; + if( GS(id->name) == ID_OB ) { + //TODO: Check if no parent? + /* Ensure location under cursor is valid dropzone */ + for(te= soops->tree.first; te; te= te->next) { + if(outliner_dropzone_parent_clear(C, event, te, fmval)) return 1; + } + /* Check if mouse cursor is below the tree */ + te= soops->tree.last; + while(((te->flag & TE_LAZY_CLOSED)==0) && (te->subtree.last)) { + te= te->subtree.last; + } + if(fmval[1] < te->ys) return 1; + } + } + return 0; +} + +static void outliner_parent_clear_copy(wmDrag *drag, wmDropBox *drop) +{ + ID *id = (ID *)drag->poin; + RNA_string_set(drop->ptr, "dragged_obj", id->name+2); + + /* Set to simple parent clear type. Avoid menus for drag and drop if possible. + * If desired, user can toggle the different "Clear Parent" types in the operator + * menu on tool shelf. */ + RNA_enum_set(drop->ptr, "type", 0); +} + +/* region dropbox definition */ +static void outliner_dropboxes(void) +{ + ListBase *lb = WM_dropboxmap_find("Outliner", SPACE_OUTLINER, RGN_TYPE_WINDOW); + + WM_dropbox_add(lb, "OUTLINER_OT_parent_drop", outliner_parent_drop_poll, outliner_parent_drop_copy); + WM_dropbox_add(lb, "OUTLINER_OT_parent_clear", outliner_parent_clear_poll, outliner_parent_clear_copy); } static void outliner_main_area_draw(const bContext *C, ARegion *ar) @@ -180,6 +265,7 @@ case NC_ANIMATION: switch(wmn->data) { case ND_NLA_ACTCHANGE: + case ND_KEYFRAME: ED_region_tag_redraw(ar); break; case ND_ANIMCHAN: @@ -302,6 +388,7 @@ st->duplicate= outliner_duplicate; st->operatortypes= outliner_operatortypes; st->keymap= outliner_keymap; + st->dropboxes= outliner_dropboxes; /* regions: main window */ art= MEM_callocN(sizeof(ARegionType), "spacetype time region"); diff -Nru blender-2.61/source/blender/editors/space_script/script_edit.c blender-2.62/source/blender/editors/space_script/script_edit.c --- blender-2.61/source/blender/editors/space_script/script_edit.c 2011-12-13 19:51:23.000000000 +0000 +++ blender-2.62/source/blender/editors/space_script/script_edit.c 2012-02-15 19:36:11.000000000 +0000 @@ -96,8 +96,8 @@ return OPERATOR_FINISHED; #else (void)C; /* unused */ -#endif return OPERATOR_CANCELLED; +#endif } void SCRIPT_OT_reload(wmOperatorType *ot) diff -Nru blender-2.61/source/blender/editors/space_sequencer/sequencer_add.c blender-2.62/source/blender/editors/space_sequencer/sequencer_add.c --- blender-2.61/source/blender/editors/space_sequencer/sequencer_add.c 2011-12-13 19:51:54.000000000 +0000 +++ blender-2.62/source/blender/editors/space_sequencer/sequencer_add.c 2012-02-15 19:36:36.000000000 +0000 @@ -130,7 +130,7 @@ RNA_int_set(op->ptr, "frame_start", (int)mval_v2d[0]); - if ((flag & SEQPROP_ENDFRAME) && RNA_property_is_set(op->ptr, "frame_end")==0) + if ((flag & SEQPROP_ENDFRAME) && RNA_struct_property_is_set(op->ptr, "frame_end")==0) RNA_int_set(op->ptr, "frame_end", (int)mval_v2d[0] + 25); // XXX arbitary but ok for now. if (!(flag & SEQPROP_NOPATHS)) { @@ -264,7 +264,7 @@ return OPERATOR_CANCELLED; } - if(!RNA_property_is_set(op->ptr, "scene")) + if(!RNA_struct_property_is_set(op->ptr, "scene")) return WM_enum_search_invoke(C, op, event); sequencer_generic_invoke_xy__internal(C, op, event, 0); @@ -325,20 +325,22 @@ RNA_string_get(&itemptr, "name", file_only); BLI_join_dirfile(seq_load.path, sizeof(seq_load.path), dir_only, file_only); - seq= seq_load_func(C, ed->seqbasep, &seq_load); - - if(overlap == FALSE) { - if(seq_test_overlap(ed->seqbasep, seq)) shuffle_seq(ed->seqbasep, seq, scene); + seq = seq_load_func(C, ed->seqbasep, &seq_load); + if (seq) { + if(overlap == FALSE) { + if(seq_test_overlap(ed->seqbasep, seq)) shuffle_seq(ed->seqbasep, seq, scene); + } } } RNA_END; } else { /* single file */ - seq= seq_load_func(C, ed->seqbasep, &seq_load); - - if(overlap == FALSE) { - if(seq_test_overlap(ed->seqbasep, seq)) shuffle_seq(ed->seqbasep, seq, scene); + seq = seq_load_func(C, ed->seqbasep, &seq_load); + if (seq) { + if(overlap == FALSE) { + if(seq_test_overlap(ed->seqbasep, seq)) shuffle_seq(ed->seqbasep, seq, scene); + } } } @@ -371,7 +373,7 @@ } /* This is for drag and drop */ - if(RNA_collection_length(op->ptr, "files") || RNA_property_is_set(op->ptr, "filepath")) { + if(RNA_collection_length(op->ptr, "files") || RNA_struct_property_is_set(op->ptr, "filepath")) { sequencer_generic_invoke_xy__internal(C, op, event, SEQPROP_NOPATHS); return sequencer_add_movie_strip_exec(C, op); } @@ -402,7 +404,7 @@ /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - WM_operator_properties_filesel(ot, FOLDERFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH|WM_FILESEL_FILES); + WM_operator_properties_filesel(ot, FOLDERFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH|WM_FILESEL_FILES, FILE_DEFAULTDISPLAY); sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME); RNA_def_boolean(ot->srna, "sound", TRUE, "Sound", "Load sound with the movie"); } @@ -423,7 +425,7 @@ } /* This is for drag and drop */ - if(RNA_collection_length(op->ptr, "files") || RNA_property_is_set(op->ptr, "filepath")) { + if(RNA_collection_length(op->ptr, "files") || RNA_struct_property_is_set(op->ptr, "filepath")) { sequencer_generic_invoke_xy__internal(C, op, event, SEQPROP_NOPATHS); return sequencer_add_sound_strip_exec(C, op); } @@ -454,7 +456,7 @@ /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH|WM_FILESEL_FILES); + WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH|WM_FILESEL_FILES, FILE_DEFAULTDISPLAY); sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME); RNA_def_boolean(ot->srna, "cache", FALSE, "Cache", "Cache the sound in memory"); } @@ -558,7 +560,7 @@ /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_DIRECTORY|WM_FILESEL_RELPATH|WM_FILESEL_FILES); + WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_DIRECTORY|WM_FILESEL_RELPATH|WM_FILESEL_FILES, FILE_DEFAULTDISPLAY); sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME|SEQPROP_ENDFRAME); } @@ -650,7 +652,7 @@ /* an unset channel is a special case where we automatically go above * the other strips. */ - if(!RNA_property_is_set(op->ptr, "channel")) { + if(!RNA_struct_property_is_set(op->ptr, "channel")) { if(seq->seq1) { int chan= MAX3( seq->seq1 ? seq->seq1->machine : 0, seq->seq2 ? seq->seq2->machine : 0, @@ -686,7 +688,7 @@ /* add color */ static int sequencer_add_effect_strip_invoke(bContext *C, wmOperator *op, wmEvent *event) { - short is_type_set= RNA_property_is_set(op->ptr, "type"); + short is_type_set= RNA_struct_property_is_set(op->ptr, "type"); int type= -1; int prop_flag= SEQPROP_ENDFRAME; @@ -711,7 +713,8 @@ if (is_type_set && type==SEQ_PLUGIN) { /* only plugins need the file selector */ - return WM_operator_filesel(C, op, event); + WM_event_add_fileselect(C, op); + return OPERATOR_RUNNING_MODAL; } else { return sequencer_add_effect_strip_exec(C, op); @@ -734,7 +737,7 @@ /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - WM_operator_properties_filesel(ot, 0, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH); + WM_operator_properties_filesel(ot, 0, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME|SEQPROP_ENDFRAME); RNA_def_enum(ot->srna, "type", sequencer_prop_effect_types, SEQ_CROSS, "Type", "Sequencer effect type"); RNA_def_float_vector(ot->srna, "color", 3, NULL, 0.0f, 1.0f, "Color", "Initialize the strip with this color (only used when type='COLOR')", 0.0f, 1.0f); diff -Nru blender-2.61/source/blender/editors/space_sequencer/sequencer_draw.c blender-2.62/source/blender/editors/space_sequencer/sequencer_draw.c --- blender-2.61/source/blender/editors/space_sequencer/sequencer_draw.c 2011-12-13 19:51:54.000000000 +0000 +++ blender-2.62/source/blender/editors/space_sequencer/sequencer_draw.c 2012-02-15 19:36:36.000000000 +0000 @@ -143,7 +143,7 @@ case SEQ_COLOR: if (colvars->col) { - rgb_float_to_byte(colvars->col, col); + rgb_float_to_uchar(col, colvars->col); } else { col[0] = col[1] = col[2] = 128; } @@ -328,7 +328,7 @@ float x1, x2, y1, y2; float handsize; float minhandle, maxhandle; - char str[32]; + char numstr[32]; unsigned int whichsel=0; x1= seq->startdisp; @@ -392,15 +392,15 @@ if(G.moving || (seq->flag & whichsel)) { const char col[4]= {255, 255, 255, 255}; if (direction == SEQ_LEFTHANDLE) { - sprintf(str, "%d", seq->startdisp); + BLI_snprintf(numstr, sizeof(numstr),"%d", seq->startdisp); x1= rx1; y1 -= 0.45f; } else { - sprintf(str, "%d", seq->enddisp - 1); + BLI_snprintf(numstr, sizeof(numstr), "%d", seq->enddisp - 1); x1= x2 - handsize*0.75f; y1= y2 + 0.05f; } - UI_view2d_text_cache_add(v2d, x1, y1, str, col); + UI_view2d_text_cache_add(v2d, x1, y1, numstr, col); } } @@ -553,7 +553,10 @@ BLI_snprintf(str, sizeof(str), "%d | %s", seq->len, name); } else if (seq->type == SEQ_SOUND) { - BLI_snprintf(str, sizeof(str), "%d | %s: %s", seq->len, name, seq->sound->name); + if(seq->sound) + BLI_snprintf(str, sizeof(str), "%d | %s: %s", seq->len, name, seq->sound->name); + else + BLI_snprintf(str, sizeof(str), "%d | %s", seq->len, name); } else if (seq->type == SEQ_MOVIE) { BLI_snprintf(str, sizeof(str), "%d | %s: %s%s", seq->len, name, seq->strip->dir, seq->strip->stripdata->name); diff -Nru blender-2.61/source/blender/editors/space_sequencer/sequencer_edit.c blender-2.62/source/blender/editors/space_sequencer/sequencer_edit.c --- blender-2.61/source/blender/editors/space_sequencer/sequencer_edit.c 2011-12-13 19:51:54.000000000 +0000 +++ blender-2.62/source/blender/editors/space_sequencer/sequencer_edit.c 2012-02-15 19:36:36.000000000 +0000 @@ -2555,12 +2555,12 @@ /* properties */ } -static void seq_del_sound(Scene *scene, Sequence *seq) +static void seq_copy_del_sound(Scene *scene, Sequence *seq) { if(seq->type == SEQ_META) { Sequence *iseq; for(iseq= seq->seqbase.first; iseq; iseq= iseq->next) { - seq_del_sound(scene, iseq); + seq_copy_del_sound(scene, iseq); } } else if(seq->scene_sound) { @@ -2611,7 +2611,7 @@ /* Need to remove anything that references the current scene */ for(seq= seqbase_clipboard.first; seq; seq= seq->next) { - seq_del_sound(scene, seq); + seq_copy_del_sound(scene, seq); } return OPERATOR_FINISHED; @@ -2634,6 +2634,19 @@ /* properties */ } +static void seq_paste_add_sound(Scene *scene, Sequence *seq) +{ + if(seq->type == SEQ_META) { + Sequence *iseq; + for(iseq= seq->seqbase.first; iseq; iseq= iseq->next) { + seq_paste_add_sound(scene, iseq); + } + } + else if(seq->type == SEQ_SOUND) { + seq->scene_sound = sound_add_scene_sound_defaults(scene, seq); + } +} + static int sequencer_paste_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene= CTX_data_scene(C); @@ -2660,9 +2673,13 @@ BLI_movelisttolist(ed->seqbasep, &nseqbase); /* make sure the pasted strips have unique names between them */ - for(; iseq; iseq=iseq->next) + for(; iseq; iseq=iseq->next) { seq_recursive_apply(iseq, apply_unique_name_cb, scene); + /* restore valid sound_scene for newly added strips */ + seq_paste_add_sound(scene, iseq); + } + WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene); return OPERATOR_FINISHED; @@ -2711,8 +2728,8 @@ calc_sequence(scene, seq_act); calc_sequence(scene, seq_other); - if(seq_act->sound) sound_add_scene_sound(scene, seq_act, seq_act->startdisp, seq_act->enddisp, seq_act->startofs + seq_act->anim_startofs); - if(seq_other->sound) sound_add_scene_sound(scene, seq_other, seq_other->startdisp, seq_other->enddisp, seq_other->startofs + seq_other->anim_startofs); + if(seq_act->sound) sound_add_scene_sound_defaults(scene, seq_act); + if(seq_other->sound) sound_add_scene_sound_defaults(scene, seq_other); WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene); @@ -3034,10 +3051,10 @@ /* set default display depending on seq type */ if(seq->type == SEQ_IMAGE) { - RNA_boolean_set(op->ptr, "filter_movie", 0); + RNA_boolean_set(op->ptr, "filter_movie", FALSE); } else { - RNA_boolean_set(op->ptr, "filter_image", 0); + RNA_boolean_set(op->ptr, "filter_image", FALSE); } WM_event_add_fileselect(C, op); @@ -3060,5 +3077,5 @@ /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_DIRECTORY|WM_FILESEL_RELPATH|WM_FILESEL_FILEPATH|WM_FILESEL_FILES); + WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_DIRECTORY|WM_FILESEL_RELPATH|WM_FILESEL_FILEPATH|WM_FILESEL_FILES, FILE_DEFAULTDISPLAY); } diff -Nru blender-2.61/source/blender/editors/space_sequencer/sequencer_intern.h blender-2.62/source/blender/editors/space_sequencer/sequencer_intern.h --- blender-2.61/source/blender/editors/space_sequencer/sequencer_intern.h 2011-12-13 19:51:54.000000000 +0000 +++ blender-2.62/source/blender/editors/space_sequencer/sequencer_intern.h 2012-02-15 19:36:36.000000000 +0000 @@ -122,7 +122,7 @@ void SEQUENCER_OT_view_all_preview(struct wmOperatorType *ot); /* sequencer_select.c */ -void SEQUENCER_OT_select_all_toggle(struct wmOperatorType *ot); +void SEQUENCER_OT_select_all(struct wmOperatorType *ot); void SEQUENCER_OT_select(struct wmOperatorType *ot); void SEQUENCER_OT_select_more(struct wmOperatorType *ot); void SEQUENCER_OT_select_less(struct wmOperatorType *ot); diff -Nru blender-2.61/source/blender/editors/space_sequencer/sequencer_ops.c blender-2.62/source/blender/editors/space_sequencer/sequencer_ops.c --- blender-2.61/source/blender/editors/space_sequencer/sequencer_ops.c 2011-12-13 19:51:54.000000000 +0000 +++ blender-2.62/source/blender/editors/space_sequencer/sequencer_ops.c 2012-02-15 19:36:36.000000000 +0000 @@ -92,8 +92,7 @@ WM_operatortype_append(SEQUENCER_OT_change_path); /* sequencer_select.c */ - WM_operatortype_append(SEQUENCER_OT_select_all_toggle); - WM_operatortype_append(SEQUENCER_OT_select_inverse); + WM_operatortype_append(SEQUENCER_OT_select_all); WM_operatortype_append(SEQUENCER_OT_select); WM_operatortype_append(SEQUENCER_OT_select_more); WM_operatortype_append(SEQUENCER_OT_select_less); @@ -133,17 +132,25 @@ WM_keymap_add_item(keymap, "SEQUENCER_OT_properties", NKEY, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "SEQUENCER_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "SEQUENCER_OT_select_inverse", IKEY, KM_PRESS, KM_CTRL, 0); - - RNA_enum_set(WM_keymap_add_item(keymap, "SEQUENCER_OT_cut", KKEY, KM_PRESS, 0, 0)->ptr, "type", SEQ_CUT_SOFT); - RNA_enum_set(WM_keymap_add_item(keymap, "SEQUENCER_OT_cut", KKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", SEQ_CUT_HARD); - - WM_keymap_add_item(keymap, "SEQUENCER_OT_mute", HKEY, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "SEQUENCER_OT_mute", HKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "unselected", 1); - - WM_keymap_add_item(keymap, "SEQUENCER_OT_unmute", HKEY, KM_PRESS, KM_ALT, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "SEQUENCER_OT_unmute", HKEY, KM_PRESS, KM_ALT|KM_SHIFT, 0)->ptr, "unselected", 1); + kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_select_all", AKEY, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE); + kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0); + RNA_enum_set(kmi->ptr, "action", SEL_INVERT); + + kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_cut", KKEY, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "type", SEQ_CUT_SOFT); + kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_cut", KKEY, KM_PRESS, KM_SHIFT, 0); + RNA_enum_set(kmi->ptr, "type", SEQ_CUT_HARD); + + kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_mute", HKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "unselected", FALSE); + kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_mute", HKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "unselected", TRUE); + + kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_unmute", HKEY, KM_PRESS, KM_ALT, 0); + RNA_boolean_set(kmi->ptr, "unselected", FALSE); + kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_unmute", HKEY, KM_PRESS, KM_ALT|KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "unselected", TRUE); WM_keymap_add_item(keymap, "SEQUENCER_OT_lock", LKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "SEQUENCER_OT_unlock", LKEY, KM_PRESS, KM_SHIFT|KM_ALT, 0); @@ -193,55 +200,77 @@ } /* Mouse selection, a bit verbose :/ */ - WM_keymap_add_item(keymap, "SEQUENCER_OT_select", SELECTMOUSE, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "SEQUENCER_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", 1); + kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_select", SELECTMOUSE, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + RNA_boolean_set(kmi->ptr, "linked_handle", FALSE); + RNA_boolean_set(kmi->ptr, "left_right", FALSE); + RNA_boolean_set(kmi->ptr, "linked_time", FALSE); + kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "extend", TRUE); + RNA_boolean_set(kmi->ptr, "linked_handle", FALSE); + RNA_boolean_set(kmi->ptr, "left_right", FALSE); + RNA_boolean_set(kmi->ptr, "linked_time", FALSE); /* 2.4x method, now use Alt for handles and select the side based on which handle was selected */ /* - RNA_boolean_set(WM_keymap_add_item(keymap, "SEQUENCER_OT_select", SELECTMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "linked_left", 1); - RNA_boolean_set(WM_keymap_add_item(keymap, "SEQUENCER_OT_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0)->ptr, "linked_right", 1); + kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_select", SELECTMOUSE, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "linked_left", TRUE); + kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0); + RNA_boolean_set(kmi->ptr, "linked_right", TRUE); kmi= WM_keymap_add_item(keymap, "SEQUENCER_OT_select", SELECTMOUSE, KM_PRESS, KM_CTRL|KM_ALT, 0); - RNA_boolean_set(kmi->ptr, "linked_left", 1); - RNA_boolean_set(kmi->ptr, "linked_right", 1); + RNA_boolean_set(kmi->ptr, "linked_left", TRUE); + RNA_boolean_set(kmi->ptr, "linked_right", TRUE); kmi= WM_keymap_add_item(keymap, "SEQUENCER_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_CTRL|KM_ALT, 0); - RNA_boolean_set(kmi->ptr, "extend", 1); - RNA_boolean_set(kmi->ptr, "linked_left", 1); - RNA_boolean_set(kmi->ptr, "linked_right", 1); + RNA_boolean_set(kmi->ptr, "extend", TRUE); + RNA_boolean_set(kmi->ptr, "linked_left", TRUE); + RNA_boolean_set(kmi->ptr, "linked_right", TRUE); kmi= WM_keymap_add_item(keymap, "SEQUENCER_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_CTRL, 0); - RNA_boolean_set(kmi->ptr, "extend", 1); - RNA_boolean_set(kmi->ptr, "linked_left", 1); + RNA_boolean_set(kmi->ptr, "extend", TRUE); + RNA_boolean_set(kmi->ptr, "linked_left", TRUE); kmi= WM_keymap_add_item(keymap, "SEQUENCER_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_ALT, 0); - RNA_boolean_set(kmi->ptr, "extend", 1); - RNA_boolean_set(kmi->ptr, "linked_right", 1); + RNA_boolean_set(kmi->ptr, "extend", TRUE); + RNA_boolean_set(kmi->ptr, "linked_right", TRUE); */ /* 2.5 method, Alt and use selected handle */ - RNA_boolean_set(WM_keymap_add_item(keymap, "SEQUENCER_OT_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0)->ptr, "linked_handle", 1); + kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + RNA_boolean_set(kmi->ptr, "linked_handle", TRUE); + RNA_boolean_set(kmi->ptr, "left_right", FALSE); + RNA_boolean_set(kmi->ptr, "linked_time", FALSE); kmi= WM_keymap_add_item(keymap, "SEQUENCER_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_ALT, 0); - RNA_boolean_set(kmi->ptr, "extend", 1); - RNA_boolean_set(kmi->ptr, "linked_handle", 1); + RNA_boolean_set(kmi->ptr, "extend", TRUE); + RNA_boolean_set(kmi->ptr, "linked_handle", TRUE); + RNA_boolean_set(kmi->ptr, "left_right", FALSE); + RNA_boolean_set(kmi->ptr, "linked_time", FALSE); /* match action editor */ kmi= WM_keymap_add_item(keymap, "SEQUENCER_OT_select", SELECTMOUSE, KM_PRESS, KM_CTRL, 0); - RNA_boolean_set(kmi->ptr, "left_right", 1); /* grr, these conflict - only use left_right if not over an active seq */ - RNA_boolean_set(kmi->ptr, "linked_time", 1); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + RNA_boolean_set(kmi->ptr, "linked_handle", FALSE); + RNA_boolean_set(kmi->ptr, "left_right", TRUE); /* grr, these conflict - only use left_right if not over an active seq */ + RNA_boolean_set(kmi->ptr, "linked_time", TRUE); /* adjusted since 2.4 */ kmi= WM_keymap_add_item(keymap, "SEQUENCER_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_CTRL, 0); - RNA_boolean_set(kmi->ptr, "extend", 1); - RNA_boolean_set(kmi->ptr, "linked_time", 1); + RNA_boolean_set(kmi->ptr, "extend", TRUE); + RNA_boolean_set(kmi->ptr, "linked_handle", FALSE); + RNA_boolean_set(kmi->ptr, "left_right", FALSE); + RNA_boolean_set(kmi->ptr, "linked_time", TRUE); WM_keymap_add_item(keymap, "SEQUENCER_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "SEQUENCER_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "SEQUENCER_OT_select_linked_pick", LKEY, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "SEQUENCER_OT_select_linked_pick", LKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", 1); + kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_select_linked_pick", LKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_select_linked_pick", LKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "extend", TRUE); WM_keymap_add_item(keymap, "SEQUENCER_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0); diff -Nru blender-2.61/source/blender/editors/space_sequencer/sequencer_scopes.c blender-2.62/source/blender/editors/space_sequencer/sequencer_scopes.c --- blender-2.61/source/blender/editors/space_sequencer/sequencer_scopes.c 2011-12-13 19:51:54.000000000 +0000 +++ blender-2.62/source/blender/editors/space_sequencer/sequencer_scopes.c 2012-02-15 19:36:36.000000000 +0000 @@ -29,16 +29,17 @@ #include #include +#include "BLI_math_color.h" #include "BLI_utildefines.h" - - #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" #include "sequencer_intern.h" -static void rgb_to_yuv(float rgb[3], float yuv[3]) +/* XXX, why is this function better then BLI_math version? + * only difference is it does some normalize after, need to double check on this - campbell */ +static void rgb_to_yuv_normalized(const float rgb[3], float yuv[3]) { yuv[0]= 0.299f*rgb[0] + 0.587f*rgb[1] + 0.114f*rgb[2]; yuv[1]= 0.492f*(rgb[2] - yuv[0]); @@ -169,10 +170,7 @@ for (x = 0; x < ibuf->x; x++) { unsigned char * rgb = src + 4 * (ibuf->x * y + x); - float v = 1.0 * - ( 0.299*rgb[0] - + 0.587*rgb[1] - + 0.114*rgb[2]) / 255.0; + float v = (float)rgb_to_luma_byte(rgb) / 255.0f; unsigned char * p = tgt; p += 4 * (w * ((int) (v * (h - 3)) + 1) + x + 1); @@ -215,10 +213,7 @@ for (x = 0; x < ibuf->x; x++) { float * rgb = src + 4 * (ibuf->x * y + x); - float v = 1.0f * - ( 0.299f*rgb[0] - + 0.587f*rgb[1] - + 0.114f*rgb[2]); + float v = rgb_to_luma(rgb); unsigned char * p = tgt; CLAMP(v, 0.0f, 1.0f); @@ -583,7 +578,7 @@ rgb[0]= (float)r/255.0f; rgb[1]= (float)g/255.0f; rgb[2]= (float)b/255.0f; - rgb_to_yuv(rgb, yuv); + rgb_to_yuv_normalized(rgb, yuv); p = tgt + 4 * (w * (int) ((yuv[2] * (h - 3) + 1)) + (int) ((yuv[1] * (w - 3) + 1))); @@ -634,7 +629,7 @@ rgb[0]= (float)src1[0]/255.0f; rgb[1]= (float)src1[1]/255.0f; rgb[2]= (float)src1[2]/255.0f; - rgb_to_yuv(rgb, yuv); + rgb_to_yuv_normalized(rgb, yuv); p = tgt + 4 * (w * (int) ((yuv[2] * (h - 3) + 1)) + (int) ((yuv[1] * (w - 3) + 1))); @@ -684,7 +679,7 @@ CLAMP(rgb[1], 0.0f, 1.0f); CLAMP(rgb[2], 0.0f, 1.0f); - rgb_to_yuv(rgb, yuv); + rgb_to_yuv_normalized(rgb, yuv); p = tgt + 4 * (w * (int) ((yuv[2] * (h - 3) + 1)) + (int) ((yuv[1] * (w - 3) + 1))); diff -Nru blender-2.61/source/blender/editors/space_sequencer/sequencer_select.c blender-2.62/source/blender/editors/space_sequencer/sequencer_select.c --- blender-2.61/source/blender/editors/space_sequencer/sequencer_select.c 2011-12-13 19:51:54.000000000 +0000 +++ blender-2.62/source/blender/editors/space_sequencer/sequencer_select.c 2012-02-15 19:36:36.000000000 +0000 @@ -179,8 +179,6 @@ recurs_sel_seq(seq); } -// remove this function, replace with invert operator -//void swap_select_seq(Scene *scene) #if 0 static void select_neighbor_from_last(Scene *scene, int lr) { @@ -214,48 +212,65 @@ #endif /* (de)select operator */ -static int sequencer_deselect_exec(bContext *C, wmOperator *UNUSED(op)) +static int sequencer_de_select_all_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); - Editing *ed= seq_give_editing(scene, FALSE); + int action = RNA_enum_get(op->ptr, "action"); + + Scene *scene = CTX_data_scene(C); + Editing *ed = seq_give_editing(scene, FALSE); Sequence *seq; - int desel = 0; - for(seq= ed->seqbasep->first; seq; seq=seq->next) { - if(seq->flag & SEQ_ALLSEL) { - desel= 1; - break; + if (action == SEL_TOGGLE) { + action = SEL_SELECT; + for (seq = ed->seqbasep->first; seq; seq = seq->next) { + if (seq->flag & SEQ_ALLSEL) { + action = SEL_DESELECT; + break; + } } } - for(seq= ed->seqbasep->first; seq; seq=seq->next) { - if (desel) { - seq->flag &= ~SEQ_ALLSEL; - } - else { - seq->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL); - seq->flag |= SELECT; + for (seq = ed->seqbasep->first; seq; seq = seq->next) { + switch (action) { + case SEL_SELECT: + seq->flag &= ~(SEQ_LEFTSEL + SEQ_RIGHTSEL); + seq->flag |= SELECT; + break; + case SEL_DESELECT: + seq->flag &= ~SEQ_ALLSEL; + break; + case SEL_INVERT: + if (seq->flag & SEQ_ALLSEL) { + seq->flag &= ~SEQ_ALLSEL; + } + else { + seq->flag &= ~(SEQ_LEFTSEL + SEQ_RIGHTSEL); + seq->flag |= SELECT; + } + break; } } - WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER|NA_SELECTED, scene); - + WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene); + return OPERATOR_FINISHED; } -void SEQUENCER_OT_select_all_toggle(struct wmOperatorType *ot) +void SEQUENCER_OT_select_all(struct wmOperatorType *ot) { /* identifiers */ ot->name= "Select or Deselect All"; - ot->idname= "SEQUENCER_OT_select_all_toggle"; + ot->idname= "SEQUENCER_OT_select_all"; ot->description="Select or deselect all strips"; /* api callbacks */ - ot->exec= sequencer_deselect_exec; + ot->exec= sequencer_de_select_all_exec; ot->poll= sequencer_edit_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + WM_operator_properties_select_all(ot); } diff -Nru blender-2.61/source/blender/editors/space_text/space_text.c blender-2.62/source/blender/editors/space_text/space_text.c --- blender-2.61/source/blender/editors/space_text/space_text.c 2011-12-13 19:51:52.000000000 +0000 +++ blender-2.62/source/blender/editors/space_text/space_text.c 2012-02-15 19:36:32.000000000 +0000 @@ -268,19 +268,19 @@ kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", WHEELUPMOUSE, KM_PRESS, KM_CTRL, 0); RNA_string_set(kmi->ptr, "data_path", "space_data.font_size"); - RNA_boolean_set(kmi->ptr, "reverse", 0); + RNA_boolean_set(kmi->ptr, "reverse", FALSE); kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", WHEELDOWNMOUSE, KM_PRESS, KM_CTRL, 0); RNA_string_set(kmi->ptr, "data_path", "space_data.font_size"); - RNA_boolean_set(kmi->ptr, "reverse", 1); + RNA_boolean_set(kmi->ptr, "reverse", TRUE); kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", PADPLUSKEY, KM_PRESS, KM_CTRL, 0); RNA_string_set(kmi->ptr, "data_path", "space_data.font_size"); - RNA_boolean_set(kmi->ptr, "reverse", 0); + RNA_boolean_set(kmi->ptr, "reverse", FALSE); kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", PADMINUS, KM_PRESS, KM_CTRL, 0); RNA_string_set(kmi->ptr, "data_path", "space_data.font_size"); - RNA_boolean_set(kmi->ptr, "reverse", 1); + RNA_boolean_set(kmi->ptr, "reverse", TRUE); WM_keymap_add_item(keymap, "TEXT_OT_new", NKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "TEXT_OT_open", OKEY, KM_PRESS, KM_ALT, 0); @@ -298,8 +298,10 @@ WM_keymap_add_item(keymap, "TEXT_OT_copy", INSERTKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "TEXT_OT_paste", INSERTKEY, KM_PRESS, KM_SHIFT, 0); - if(U.uiflag & USER_MMB_PASTE) // XXX not dynamic - RNA_boolean_set(WM_keymap_add_item(keymap, "TEXT_OT_paste", MIDDLEMOUSE, KM_PRESS, 0, 0)->ptr, "selection", 1); + if(U.uiflag & USER_MMB_PASTE) { // XXX not dynamic + kmi = WM_keymap_add_item(keymap, "TEXT_OT_paste", MIDDLEMOUSE, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "selection", TRUE); + } WM_keymap_add_item(keymap, "TEXT_OT_jump", JKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "TEXT_OT_find", GKEY, KM_PRESS, KM_CTRL, 0); @@ -307,8 +309,10 @@ WM_keymap_add_item(keymap, "TEXT_OT_properties", FKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "TEXT_OT_replace", HKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "TEXT_OT_to_3d_object", MKEY, KM_PRESS, KM_ALT, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "TEXT_OT_to_3d_object", MKEY, KM_PRESS, KM_CTRL, 0)->ptr, "split_lines", 1); + kmi = WM_keymap_add_item(keymap, "TEXT_OT_to_3d_object", MKEY, KM_PRESS, KM_ALT, 0); + RNA_boolean_set(kmi->ptr, "split_lines", FALSE); + kmi = WM_keymap_add_item(keymap, "TEXT_OT_to_3d_object", MKEY, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "split_lines", TRUE); WM_keymap_add_item(keymap, "TEXT_OT_select_all", AKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "TEXT_OT_select_line", AKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0); @@ -357,12 +361,15 @@ WM_keymap_add_item(keymap, "TEXT_OT_overwrite_toggle", INSERTKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "TEXT_OT_scroll_bar", LEFTMOUSE, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "TEXT_OT_scroll_bar", MIDDLEMOUSE, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "TEXT_OT_scroll", MIDDLEMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "TEXT_OT_scroll", MOUSEPAN, 0, 0, 0); - WM_keymap_add_item(keymap, "TEXT_OT_scroll_bar", LEFTMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "TEXT_OT_selection_set", EVT_TWEAK_L, KM_ANY, 0, 0); WM_keymap_add_item(keymap, "TEXT_OT_cursor_set", LEFTMOUSE, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "TEXT_OT_selection_set", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "select", 1); + kmi = WM_keymap_add_item(keymap, "TEXT_OT_selection_set", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "select", TRUE); RNA_int_set(WM_keymap_add_item(keymap, "TEXT_OT_scroll", WHEELUPMOUSE, KM_PRESS, 0, 0)->ptr, "lines", -1); RNA_int_set(WM_keymap_add_item(keymap, "TEXT_OT_scroll", WHEELDOWNMOUSE, KM_PRESS, 0, 0)->ptr, "lines", 1); diff -Nru blender-2.61/source/blender/editors/space_text/text_draw.c blender-2.62/source/blender/editors/space_text/text_draw.c --- blender-2.61/source/blender/editors/space_text/text_draw.c 2011-12-13 19:51:52.000000000 +0000 +++ blender-2.62/source/blender/editors/space_text/text_draw.c 2012-02-15 19:36:32.000000000 +0000 @@ -72,10 +72,10 @@ { } -static int text_font_draw(SpaceText *UNUSED(st), int x, int y, char *str) +static int text_font_draw(SpaceText *UNUSED(st), int x, int y, const char *str) { BLF_position(mono, x, y, 0); - BLF_draw(mono, str, 65535); /* XXX, use real length */ + BLF_draw(mono, str, BLF_DRAW_STR_DUMMY_MAX); return BLF_width(mono, str); } @@ -92,19 +92,28 @@ return st->cwidth; } -int text_font_width(SpaceText *UNUSED(st), const char *str) +static int text_font_draw_character_utf8(SpaceText *st, int x, int y, const char *c) { - return BLF_width(mono, str); + char str[BLI_UTF8_MAX+1]; + size_t len = BLI_str_utf8_size(c); + memcpy(str, c, len); + str[len]= '\0'; + + BLF_position(mono, x, y, 0); + BLF_draw(mono, str, len); + + return st->cwidth; } /****************** flatten string **********************/ -static void flatten_string_append(FlattenString *fs, char c, int accum) +static void flatten_string_append(FlattenString *fs, const char *c, int accum, int len) { - if(fs->pos>=fs->len && fs->pos>=sizeof(fs->fixedbuf)-1) { + int i; + + if(fs->pos+len > fs->len) { char *nbuf; int *naccum; - if(fs->len) fs->len*= 2; - else fs->len= sizeof(fs->fixedbuf) * 2; + fs->len*= 2; nbuf= MEM_callocN(sizeof(*fs->buf)*fs->len, "fs->buf"); naccum= MEM_callocN(sizeof(*fs->accum)*fs->len, "fs->accum"); @@ -121,35 +130,45 @@ fs->accum= naccum; } - fs->buf[fs->pos]= c; - fs->accum[fs->pos]= accum; - - fs->pos++; + for (i = 0; i < len; i++) + { + fs->buf[fs->pos+i]= c[i]; + fs->accum[fs->pos+i]= accum; + } + + fs->pos+= len; } int flatten_string(SpaceText *st, FlattenString *fs, const char *in) { - int r = 0, i = 0; + int r, i, total = 0; memset(fs, 0, sizeof(FlattenString)); fs->buf= fs->fixedbuf; fs->accum= fs->fixedaccum; - - for(r=0, i=0; *in; r++, in++) { - if(*in=='\t') { - if(fs->pos && *(in-1)=='\t') - i= st->tabnumber; - else if(st->tabnumber > 0) - i= st->tabnumber - (fs->pos%st->tabnumber); + fs->len = sizeof(fs->fixedbuf); + for(r = 0, i = 0; *in; r++) { + if(*in=='\t') { + i= st->tabnumber - (total%st->tabnumber); + total+= i; + while(i--) - flatten_string_append(fs, ' ', r); + flatten_string_append(fs, " ", r, 1); + + in++; + } + else { + size_t len= BLI_str_utf8_size(in); + flatten_string_append(fs, in, r, len); + in += len; + total++; } - else - flatten_string_append(fs, *in, r); } + + flatten_string_append(fs, "\0", r, 1); - return fs->pos; + return total; } void flatten_string_free(FlattenString *fs) @@ -304,9 +323,8 @@ } else orig = 0xFF; - flatten_string(st, &fs, line->line); + len = flatten_string(st, &fs, line->line); str = fs.buf; - len = strlen(str); if(!text_check_format_len(line, len)) { flatten_string_free(&fs); return; @@ -318,7 +336,7 @@ if(*str == '\\') { *fmt = prev; fmt++; str++; if(*str == '\0') break; - *fmt = prev; fmt++; str++; + *fmt = prev; fmt++; str += BLI_str_utf8_size(str); continue; } /* Handle continuations */ @@ -339,14 +357,16 @@ } *fmt = 'l'; + str += BLI_str_utf8_size(str) - 1; } /* Not in a string... */ else { /* Deal with comments first */ - if(prev == '#' || *str == '#') + if(prev == '#' || *str == '#') { *fmt = '#'; - /* Strings */ - else if(*str == '"' || *str == '\'') { + str += BLI_str_utf8_size(str) - 1; + } else if(*str == '"' || *str == '\'') { + /* Strings */ find = *str; cont = (*str== '"') ? TXT_DBLQUOTSTR : TXT_SNGQUOTSTR; if(*(str+1) == find && *(str+2) == find) { @@ -371,14 +391,18 @@ } *fmt = 'n'; } - else + else { + str += BLI_str_utf8_size(str) - 1; *fmt = 'q'; + } /* Punctuation */ else if(text_check_delim(*str)) *fmt = '!'; /* Identifiers and other text (no previous ws. or delims. so text continues) */ - else if(prev == 'q') + else if(prev == 'q') { + str += BLI_str_utf8_size(str) - 1; *fmt = 'q'; + } /* Not ws, a digit, punct, or continuing text. Must be new, check for special words */ else { /* Special vars(v) or built-in keywords(b) */ @@ -395,8 +419,10 @@ } *fmt = prev; } - else + else { + str += BLI_str_utf8_size(str) - 1; *fmt = 'q'; + } } } prev = *fmt; @@ -408,14 +434,11 @@ *fmt = '\0'; fmt++; *fmt = cont; - /* Debugging */ - //print_format(st, line); - /* If continuation has changed and we're allowed, process the next line */ if(cont!=orig && do_next && line->next) { txt_format_line(st, line->next, do_next); } - + flatten_string_free(&fs); } @@ -539,13 +562,14 @@ } max= wrap_width(st, ar); + cursin = txt_utf8_offset_to_index(linein->line, cursin); while(linep) { start= 0; end= max; chop= 1; *offc= 0; - for(i=0, j=0; linep->line[j]!='\0'; j++) { + for(i=0, j=0; linep->line[j]; j+=BLI_str_utf8_size(linep->line+j)) { int chars; /* Mimic replacement of tabs */ @@ -591,6 +615,7 @@ } } +/* cursin - mem, offc - view */ void wrap_offset_in_line(SpaceText *st, ARegion *ar, TextLine *linein, int cursin, int *offl, int *offc) { int i, j, start, end, chars, max, chop; @@ -607,8 +632,9 @@ end= max; chop= 1; *offc= 0; + cursin = txt_utf8_offset_to_index(linein->line, cursin); - for(i=0, j=0; linein->line[j]!='\0'; j++) { + for(i=0, j=0; linein->line[j]; j += BLI_str_utf8_size(linein->line + j)) { /* Mimic replacement of tabs */ ch= linein->line[j]; @@ -653,7 +679,7 @@ { int a=0, i; - for(i=0; itabnumber-a%st->tabnumber; else @@ -662,54 +688,65 @@ return a; } -static int text_draw_wrapped(SpaceText *st, char *str, int x, int y, int w, char *format, int skip) +static const char *txt_utf8_get_nth(const char *str, int n) +{ + int pos= 0; + while (str[pos] && n--) { + pos+= BLI_str_utf8_size(str + pos); + } + return str + pos; +} + +static int text_draw_wrapped(SpaceText *st, const char *str, int x, int y, int w, const char *format, int skip) { FlattenString fs; - int basex, i, a, len, start, end, max, lines; + int basex, i, a, start, end, max, lines; /* view */ + int mi, ma, mstart, mend; /* mem */ - len= flatten_string(st, &fs, str); + flatten_string(st, &fs, str); str= fs.buf; max= w/st->cwidth; if(max<8) max= 8; basex= x; - lines= 1; - start= 0; - end= max; - for(i=0; i= max) { /* skip hidden part of line */ if(skip) { skip--; - start= end; - end += max; + start= end; mstart= mend; + end += max; mend= txt_utf8_get_nth(str+mend, max) - str; continue; } /* Draw the visible portion of text on the overshot line */ - for(a=start; ashowsyntax && format) format_draw_color(format[a]); - x += text_font_draw_character(st, x, y, str[a]); + x += text_font_draw_character_utf8(st, x, y, str + ma); } y -= st->lheight; x= basex; lines++; - start= end; - end += max; + start= end; mstart= mend; + end += max; mend= txt_utf8_get_nth(str+mend, max) - str; if(y<=0) break; } - else if(str[i]==' ' || str[i]=='-') { - end = i+1; + else if(str[mi]==' ' || str[mi]=='-') { + end = i+1; mend = mi+1; } } /* Draw the remaining text */ - for(a=start; a 0; a++) { + for(a=start, ma=mstart; str[ma] && y > 0; a++, ma+=BLI_str_utf8_size(str+ma)) { if(st->showsyntax && format) format_draw_color(format[a]); - x += text_font_draw_character(st, x, y, str[a]); + x += text_font_draw_character_utf8(st, x, y, str+ma); } flatten_string_free(&fs); @@ -717,45 +754,36 @@ return lines; } -static int text_draw(SpaceText *st, char *str, int cshift, int maxwidth, int draw, int x, int y, char *format) +static int text_draw(SpaceText *st, char *str, int cshift, int maxwidth, int draw, int x, int y, const char *format) { FlattenString fs; - int r=0, w= 0, amount; - int *acc; - char *in; + int *acc, r=0; + const char *in; - w= flatten_string(st, &fs, str); + int w= flatten_string(st, &fs, str); if(w < cshift) { flatten_string_free(&fs); return 0; /* String is shorter than shift */ } - in= fs.buf+cshift; + in= txt_utf8_get_nth(fs.buf, cshift); acc= fs.accum+cshift; w= w-cshift; if(draw) { + int amount = maxwidth ? MIN2(w, maxwidth) : w; + if(st->showsyntax && format) { - int a; + int a, str_shift= 0; format = format+cshift; - - amount = strlen(in); - if(maxwidth) - amount= MIN2(amount, maxwidth); - + for(a = 0; a < amount; a++) { format_draw_color(format[a]); - x += text_font_draw_character(st, x, y, in[a]); + x += text_font_draw_character_utf8(st, x, y, in + str_shift); + str_shift += BLI_str_utf8_size(in + str_shift); } } - else { - amount = strlen(in); - if(maxwidth) - amount= MIN2(amount, maxwidth); - - in[amount]= 0; - text_font_draw(st, x, y, in); - } + else text_font_draw(st, x, y, in); } else { while(w-- && *acc++ < maxwidth) @@ -976,8 +1004,8 @@ max= wrap_width(st, ar); lines= 1; start= 0; - end= max; - for(i= 0, j= 0; str[j] != '\0'; j++) { + end= max; + for(i= 0, j= 0; str[j]; j+=BLI_str_utf8_size(str+j)) { /* Mimic replacement of tabs */ ch= str[j]; if(ch=='\t') { @@ -1421,7 +1449,7 @@ BLI_strncpy(str, item->name, SUGG_LIST_WIDTH); - w = text_font_width(st, str); + w = BLF_width(mono, str); if(item == sel) { UI_ThemeColor(TH_SHADE2); @@ -1496,8 +1524,6 @@ glRecti(x-4, y, ar->winx, y-st->lheight), y-=st->lheight; glRecti(x-4, y, x+toc*st->cwidth, y-st->lheight); y-=st->lheight; - - (void)y; } } else { @@ -1569,8 +1595,9 @@ { TextLine *startl, *endl, *linep; Text *text = st->text; - int b, c, startc, endc, find, stack; - int viewc, viewl, offl, offc, x, y; + int b, fc, find, stack, viewc, viewl, offl, offc, x, y; + int startc, endc, c; + char ch; // showsyntax must be on or else the format string will be null @@ -1584,21 +1611,23 @@ linep= startl; c= startc; + fc= txt_utf8_offset_to_index(linep->line, startc); endl= NULL; endc= -1; find= -b; stack= 0; /* Dont highlight backets if syntax HL is off or bracket in string or comment. */ - if(!linep->format || linep->format[c] == 'l' || linep->format[c] == '#') + if(!linep->format || linep->format[fc] == 'l' || linep->format[fc] == '#') return; if(b>0) { /* opening bracket, search forward for close */ - c++; + fc++; + c+= BLI_str_utf8_size(linep->line+c); while(linep) { while(clen) { - if(linep->format && linep->format[c] != 'l' && linep->format[c] != '#') { + if(linep->format && linep->format[fc] != 'l' && linep->format[fc] != '#') { b= text_check_bracket(linep->line[c]); if(b==find) { if(stack==0) { @@ -1612,19 +1641,22 @@ stack++; } } - c++; + fc++; + c+= BLI_str_utf8_size(linep->line+c); } if(endl) break; linep= linep->next; c= 0; + fc= 0; } } else { /* closing bracket, search backward for open */ - c--; + fc--; + if (c>0) c -= linep->line+c-BLI_str_prev_char_utf8(linep->line+c); while(linep) { - while(c>=0) { - if(linep->format && linep->format[c] != 'l' && linep->format[c] != '#') { + while(fc>=0) { + if(linep->format && linep->format[fc] != 'l' && linep->format[fc] != '#') { b= text_check_bracket(linep->line[c]); if(b==find) { if(stack==0) { @@ -1638,11 +1670,17 @@ stack++; } } - c--; + fc--; + if (c>0) c -= linep->line+c-BLI_str_prev_char_utf8(linep->line+c); } if(endl) break; linep= linep->prev; - if(linep) c= linep->len-1; + if(linep) { + if (linep->format) fc= strlen(linep->format)-1; + else fc= -1; + if (linep->len) c= BLI_str_prev_char_utf8(linep->line+linep->len)-linep->line; + else fc= -1; + } } } @@ -1766,7 +1804,7 @@ else UI_ThemeColor(TH_TEXT); - sprintf(linenr, "%*d", st->linenrs_tot, i + linecount + 1); + BLI_snprintf(linenr, sizeof(linenr), "%*d", st->linenrs_tot, i + linecount + 1); /* itoa(i + linecount + 1, linenr, 10); */ /* not ansi-c :/ */ text_font_draw(st, TXT_OFFSET - 7, y, linenr); diff -Nru blender-2.61/source/blender/editors/space_text/text_intern.h blender-2.62/source/blender/editors/space_text/text_intern.h --- blender-2.61/source/blender/editors/space_text/text_intern.h 2011-12-13 19:51:52.000000000 +0000 +++ blender-2.62/source/blender/editors/space_text/text_intern.h 2012-02-15 19:36:32.000000000 +0000 @@ -47,9 +47,6 @@ /* text_draw.c */ void draw_text_main(struct SpaceText *st, struct ARegion *ar); -int text_font_width_character(struct SpaceText *st); -int text_font_width(struct SpaceText *st, const char *str); - void text_update_line_edited(struct TextLine *line); void text_update_edited(struct Text *text); void text_update_character_width(struct SpaceText *st); diff -Nru blender-2.61/source/blender/editors/space_text/text_ops.c blender-2.62/source/blender/editors/space_text/text_ops.c --- blender-2.61/source/blender/editors/space_text/text_ops.c 2011-12-13 19:51:52.000000000 +0000 +++ blender-2.62/source/blender/editors/space_text/text_ops.c 2012-02-15 19:36:32.000000000 +0000 @@ -195,7 +195,6 @@ ot->description= "Create a new text data block"; /* api callbacks */ - ot->invoke= WM_operator_confirm; ot->exec= text_new_exec; ot->poll= text_new_poll; @@ -277,7 +276,7 @@ Text *text= CTX_data_edit_text(C); char *path= (text && text->name)? text->name: G.main->name; - if(RNA_property_is_set(op->ptr, "filepath")) + if(RNA_struct_property_is_set(op->ptr, "filepath")) return text_open_exec(C, op); text_open_init(C, op); @@ -304,7 +303,7 @@ ot->flag= OPTYPE_UNDO; /* properties */ - WM_operator_properties_filesel(ot, FOLDERFILE|TEXTFILE|PYSCRIPTFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH); //XXX TODO, relative_path + WM_operator_properties_filesel(ot, FOLDERFILE|TEXTFILE|PYSCRIPTFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); //XXX TODO, relative_path RNA_def_boolean(ot->srna, "internal", 0, "Make internal", "Make text file internal after loading"); } @@ -535,7 +534,7 @@ Text *text= CTX_data_edit_text(C); char *str; - if(RNA_property_is_set(op->ptr, "filepath")) + if(RNA_struct_property_is_set(op->ptr, "filepath")) return text_save_as_exec(C, op); if(text->name) @@ -564,7 +563,7 @@ ot->poll= text_edit_poll; /* properties */ - WM_operator_properties_filesel(ot, FOLDERFILE|TEXTFILE|PYSCRIPTFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH); //XXX TODO, relative_path + WM_operator_properties_filesel(ot, FOLDERFILE|TEXTFILE|PYSCRIPTFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); //XXX TODO, relative_path } /******************* run script operator *********************/ @@ -1421,7 +1420,7 @@ end= max; chop= loop= 1; - for(i=0, j=0; loop; j++) { + for(i=0, j=0; loop; j+=BLI_str_utf8_size(linein->line+j)) { int chars; /* Mimic replacement of tabs */ ch= linein->line[j]; @@ -1596,7 +1595,7 @@ chop= loop= 1; *charp= 0; - for(i=0, j=0; loop; j++) { + for(i=0, j=0; loop; j+=BLI_str_utf8_size((*linep)->line+j)) { int chars; /* Mimic replacement of tabs */ ch= (*linep)->line[j]; @@ -1611,7 +1610,7 @@ *charp= endj; if(j>=oldc) { - if(ch=='\0') *charp= start; + if(ch=='\0') *charp= txt_utf8_index_to_offset((*linep)->line, start); loop= 0; break; } @@ -1624,7 +1623,7 @@ } else if(ch==' ' || ch=='-' || ch=='\0') { if(j>=oldc) { - *charp= start; + *charp= txt_utf8_index_to_offset((*linep)->line, start); loop= 0; break; } @@ -1664,7 +1663,7 @@ chop= loop= 1; *charp= 0; - for(i=0, j=0; loop; j++) { + for(i=0, j=0; loop; j+=BLI_str_utf8_size((*linep)->line+j)) { int chars; /* Mimic replacement of tabs */ ch= (*linep)->line[j]; @@ -1676,7 +1675,7 @@ while(chars--) { if(i-start>=max) { - if(chop) endj= j-1; + if(chop) endj= BLI_str_prev_char_utf8((*linep)->line+j)-(*linep)->line; if(endj>=oldc) { if(ch=='\0') *charp= (*linep)->len; @@ -2210,7 +2209,7 @@ SpaceText *st= CTX_wm_space_text(C); TextScroll *tsc; - if(RNA_property_is_set(op->ptr, "lines")) + if(RNA_struct_property_is_set(op->ptr, "lines")) return text_scroll_exec(C, op); tsc= MEM_callocN(sizeof(TextScroll), "TextScroll"); @@ -2233,8 +2232,8 @@ text_scroll_apply(C, op, event); scroll_exit(C, op); return OPERATOR_FINISHED; - } - + } + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; @@ -2290,7 +2289,7 @@ const int *mval= event->mval; int zone= -1; - if(RNA_property_is_set(op->ptr, "lines")) + if(RNA_struct_property_is_set(op->ptr, "lines")) return text_scroll_exec(C, op); /* verify we are in the right zone */ @@ -2315,9 +2314,20 @@ tsc->scrollbar= 1; tsc->zone= zone; op->customdata= tsc; - st->flags|= ST_SCROLL_SELECT; + /* jump scroll, works in v2d but needs to be added here too :S */ + if (event->type == MIDDLEMOUSE) { + tsc->old[0] = ar->winrct.xmin + (st->txtbar.xmax + st->txtbar.xmin) / 2; + tsc->old[1] = ar->winrct.ymin + (st->txtbar.ymax + st->txtbar.ymin) / 2; + + tsc->delta[0] = 0; + tsc->delta[1] = 0; + tsc->first = 0; + tsc->zone= SCROLLHANDLE_BAR; + text_scroll_apply(C, op, event); + } + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; @@ -2354,148 +2364,185 @@ short old[2]; } SetSelection; -static void text_cursor_set_to_pos(SpaceText *st, ARegion *ar, int x, int y, int sel) +static int flatten_len(SpaceText *st, const char *str) { - FlattenString fs; - Text *text= st->text; - TextLine **linep; - int *charp; - int w; - - text_update_character_width(st); + int i, total = 0; - if(sel) { linep= &text->sell; charp= &text->selc; } - else { linep= &text->curl; charp= &text->curc; } + for(i = 0; str[i]; i += BLI_str_utf8_size(str+i)) { + if(str[i]=='\t') { + total += st->tabnumber - total%st->tabnumber; + } + else total++; + } - y= (ar->winy - 2 - y)/st->lheight; - - if(st->showlinenrs) - x-= TXT_OFFSET+TEXTXLOC; - else - x-= TXT_OFFSET; + return total; +} - if(x<0) x= 0; - x = (x/st->cwidth) + st->left; +static int flatten_index_to_offset(SpaceText *st, const char *str, int index) +{ + int i, j; + for (i= 0, j= 0; i < index; j += BLI_str_utf8_size(str+j)) + if(str[j]=='\t') + i += st->tabnumber - i%st->tabnumber; + else + i++; - if(st->wordwrap) { - int i, j, endj, curs, max, chop, start, end, loop, found; - char ch; - - /* Point to first visible line */ - *linep= text->lines.first; - i= st->top; - while(i>0 && *linep) { - int lines= text_get_visible_lines(st, ar, (*linep)->line); + return j; +} - if (i-lines<0) { - y+= i; - break; - } else { - *linep= (*linep)->next; - i-= lines; - } +static TextLine *get_first_visible_line(SpaceText *st, ARegion *ar, int *y) +{ + TextLine *linep = st->text->lines.first; + int i; + for (i = st->top; i > 0 && linep; ) { + int lines = text_get_visible_lines(st, ar, linep->line); + + if (i-lines < 0) { + *y += i; + break; + } else { + linep = linep->next; + i -= lines; } + } + return linep; +} - max= wrap_width(st, ar); - - loop= 1; - found= 0; - while(loop && *linep) { - start= 0; - end= max; - chop= 1; - curs= 0; - endj= 0; - for(i=0, j=0; loop; j++) { - int chars; - - /* Mimic replacement of tabs */ - ch= (*linep)->line[j]; - if(ch=='\t') { - chars= st->tabnumber-i%st->tabnumber; - ch= ' '; - } - else - chars= 1; - - while(chars--) { - /* Gone too far, go back to last wrap point */ - if(y<0) { - *charp= endj; - loop= 0; - break; +static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, int y, int sel) +{ + Text *text = st->text; + int max = wrap_width(st, ar); /* view */ + int charp = -1; /* mem */ + int loop = 1, found = 0; /* flags */ + char ch; + + /* Point to first visible line */ + TextLine *linep = get_first_visible_line(st, ar, &y); + + while(loop && linep) { + int i = 0, start = 0, end = max; /* view */ + int j = 0, curs = 0, endj = 0; /* mem */ + int chop = 1; /* flags */ + + for (; loop; j += BLI_str_utf8_size(linep->line+j)) { + int chars; + + /* Mimic replacement of tabs */ + ch = linep->line[j]; + if(ch == '\t') { + chars = st->tabnumber - i%st->tabnumber; + ch = ' '; + } + else chars = 1; + + while (chars--) { + /* Gone too far, go back to last wrap point */ + if (y < 0) { + charp = endj; + loop = 0; + break; /* Exactly at the cursor */ - } - else if(y==0 && i-start==x) { - /* current position could be wrapped to next line */ - /* this should be checked when end of current line would be reached */ - *charp= curs= j; - found= 1; + } + else if (y == 0 && i-start == x) { + /* current position could be wrapped to next line */ + /* this should be checked when end of current line would be reached */ + charp = curs= j; + found = 1; /* Prepare curs for next wrap */ + } + else if(i - end == x) { + curs = j; + } + if (i - start >= max) { + if (found) { + /* exact cursor position was found, check if it's */ + /* still on needed line (hasn't been wrapped) */ + if (charp > endj && !chop && ch!='\0') charp = endj; + loop = 0; + break; } - else if(i-end==x) { - curs= j; + + if(chop) endj = j; + start = end; + end += max; + + if(j < linep->len) + y--; + + chop = 1; + if (y == 0 && i-start >= x) { + charp = curs; + loop = 0; + break; } - if(i-start>=max) { - if(found) { - /* exact cursor position was found, check if it's */ - /* still on needed line (hasn't been wrapped) */ - if(*charp>endj && !chop && ch!='\0') (*charp)= endj; - loop= 0; - break; - } - - if(chop) endj= j; - start= end; - end += max; - - if(j<(*linep)->len) - y--; - - chop= 1; - if(y==0 && i-start>=x) { - *charp= curs; - loop= 0; - break; - } + } + else if (ch == ' ' || ch == '-' || ch == '\0') { + if (found) { + loop = 0; + break; } - else if(ch==' ' || ch=='-' || ch=='\0') { - if(found) { - loop= 0; - break; - } - - if(y==0 && i-start>=x) { - *charp= curs; - loop= 0; - break; - } - end = i+1; - endj = j; - chop= 0; + + if(y == 0 && i-start >= x) { + charp = curs; + loop = 0; + break; } - i++; + end = i + 1; + endj = j; + chop = 0; } - if(ch=='\0') break; + i++; } - if(!loop || found) break; + + if(ch == '\0') break; + } + + if(!loop || found) break; + + if(!linep->next) { + charp = linep->len; + break; + } + + /* On correct line but didn't meet cursor, must be at end */ + if (y == 0) { + charp = linep->len; + break; + } + linep = linep->next; + + y--; + } - if(!(*linep)->next) { - *charp= (*linep)->len; - break; - } + if (linep && charp != -1) { + if(sel) { text->sell = linep; text->selc = charp; } + else { text->curl = linep; text->curc = charp; } + } +} - /* On correct line but didn't meet cursor, must be at end */ - if(y==0) { - *charp= (*linep)->len; - break; - } - *linep= (*linep)->next; - y--; - } +static void text_cursor_set_to_pos(SpaceText *st, ARegion *ar, int x, int y, int sel) +{ + Text *text= st->text; + text_update_character_width(st); + y= (ar->winy - 2 - y)/st->lheight; + + if(st->showlinenrs) x-= TXT_OFFSET+TEXTXLOC; + else x-= TXT_OFFSET; + if(x<0) x= 0; + x = (x/st->cwidth) + st->left; + + if(st->wordwrap) { + text_cursor_set_to_pos_wrapped(st, ar, x, y, sel); } else { + TextLine **linep; + int *charp; + int w; + + if(sel) { linep= &text->sell; charp= &text->selc; } + else { linep= &text->curl; charp= &text->curc; } + y-= txt_get_span(text->lines.first, *linep) - st->top; if(y>0) { @@ -2506,10 +2553,9 @@ } - w= flatten_string(st, &fs, (*linep)->line); - if(xline); + if(xline, x); else *charp= (*linep)->len; - flatten_string_free(&fs); } if(!sel) txt_pop_sel(text); } @@ -2752,19 +2798,23 @@ SpaceText *st= CTX_wm_space_text(C); Text *text= CTX_data_edit_text(C); char *str; - int done = 0, i; + int done = 0; + size_t i = 0; + unsigned int code; text_drawcache_tag_update(st, 0); str= RNA_string_get_alloc(op->ptr, "text", NULL, 0); if(st && st->overwrite) { - for(i=0; str[i]; i++) { - done |= txt_replace_char(text, str[i]); + while (str[i]) { + code = BLI_str_utf8_as_unicode_step(str, &i); + done |= txt_replace_char(text, code); } } else { - for(i=0; str[i]; i++) { - done |= txt_add_char(text, str[i]); + while (str[i]) { + code = BLI_str_utf8_as_unicode_step(str, &i); + done |= txt_add_char(text, code); } } @@ -2785,16 +2835,24 @@ { int ret; - // if(!RNA_property_is_set(op->ptr, "text")) { /* always set from keymap XXX */ + // if(!RNA_struct_property_is_set(op->ptr, "text")) { /* always set from keymap XXX */ if(!RNA_string_length(op->ptr, "text")) { /* if alt/ctrl/super are pressed pass through */ if(event->ctrl || event->oskey) { return OPERATOR_PASS_THROUGH; } else { - char str[2]; - str[0]= event->ascii; - str[1]= '\0'; + char str[BLI_UTF8_MAX+1]; + size_t len; + + if (event->utf8_buf[0]) { + len = BLI_str_utf8_size(event->utf8_buf); + memcpy(str, event->utf8_buf, len); + } else { + /* in theory, ghost can set value to extended ascii here */ + len = BLI_str_utf8_from_unicode(event->ascii, str); + } + str[len]= '\0'; RNA_string_set(op->ptr, "text", str); } } @@ -3131,25 +3189,25 @@ /* modified locally and externally, ahhh. offer more possibilites. */ pup= uiPupMenuBegin(C, "File Modified Outside and Inside Blender", ICON_NONE); layout= uiPupMenuLayout(pup); - uiItemEnumO(layout, op->type->idname, "Reload from disk (ignore local changes)", 0, "resolution", RESOLVE_RELOAD); - uiItemEnumO(layout, op->type->idname, "Save to disk (ignore outside changes)", 0, "resolution", RESOLVE_SAVE); - uiItemEnumO(layout, op->type->idname, "Make text internal (separate copy)", 0, "resolution", RESOLVE_MAKE_INTERNAL); + uiItemEnumO_ptr(layout, op->type, "Reload from disk (ignore local changes)", 0, "resolution", RESOLVE_RELOAD); + uiItemEnumO_ptr(layout, op->type, "Save to disk (ignore outside changes)", 0, "resolution", RESOLVE_SAVE); + uiItemEnumO_ptr(layout, op->type, "Make text internal (separate copy)", 0, "resolution", RESOLVE_MAKE_INTERNAL); uiPupMenuEnd(C, pup); } else { pup= uiPupMenuBegin(C, "File Modified Outside Blender", ICON_NONE); layout= uiPupMenuLayout(pup); - uiItemEnumO(layout, op->type->idname, "Reload from disk", 0, "resolution", RESOLVE_RELOAD); - uiItemEnumO(layout, op->type->idname, "Make text internal (separate copy)", 0, "resolution", RESOLVE_MAKE_INTERNAL); - uiItemEnumO(layout, op->type->idname, "Ignore", 0, "resolution", RESOLVE_IGNORE); + uiItemEnumO_ptr(layout, op->type, "Reload from disk", 0, "resolution", RESOLVE_RELOAD); + uiItemEnumO_ptr(layout, op->type, "Make text internal (separate copy)", 0, "resolution", RESOLVE_MAKE_INTERNAL); + uiItemEnumO_ptr(layout, op->type, "Ignore", 0, "resolution", RESOLVE_IGNORE); uiPupMenuEnd(C, pup); } break; case 2: pup= uiPupMenuBegin(C, "File Deleted Outside Blender", ICON_NONE); layout= uiPupMenuLayout(pup); - uiItemEnumO(layout, op->type->idname, "Make text internal", 0, "resolution", RESOLVE_MAKE_INTERNAL); - uiItemEnumO(layout, op->type->idname, "Recreate file", 0, "resolution", RESOLVE_SAVE); + uiItemEnumO_ptr(layout, op->type, "Make text internal", 0, "resolution", RESOLVE_MAKE_INTERNAL); + uiItemEnumO_ptr(layout, op->type, "Recreate file", 0, "resolution", RESOLVE_SAVE); uiPupMenuEnd(C, pup); break; } diff -Nru blender-2.61/source/blender/editors/space_time/space_time.c blender-2.62/source/blender/editors/space_time/space_time.c --- blender-2.61/source/blender/editors/space_time/space_time.c 2011-12-13 19:52:03.000000000 +0000 +++ blender-2.62/source/blender/editors/space_time/space_time.c 2012-02-15 19:36:43.000000000 +0000 @@ -193,6 +193,10 @@ col[0] = 1.0; col[1] = 0.1; col[2] = 0.75; col[3] = 0.1; break; + default: + BLI_assert(0); + col[0] = 1.0; col[1] = 0.0; col[2] = 1.0; + col[3] = 0.1; } glColor4fv(col); diff -Nru blender-2.61/source/blender/editors/space_view3d/drawanimviz.c blender-2.62/source/blender/editors/space_view3d/drawanimviz.c --- blender-2.61/source/blender/editors/space_view3d/drawanimviz.c 2011-12-13 19:52:25.000000000 +0000 +++ blender-2.62/source/blender/editors/space_view3d/drawanimviz.c 2012-02-15 19:36:59.000000000 +0000 @@ -218,23 +218,23 @@ col[3]= 255; for (i=0, mpv=mpv_start; i < len; i+=stepsize, mpv+=stepsize) { - char str[32]; + char numstr[32]; float co[3]; /* only draw framenum if several consecutive highlighted points don't occur on same point */ if (i == 0) { - sprintf(str, "%d", (i+sfra)); + sprintf(numstr, "%d", (i+sfra)); mul_v3_m4v3(co, ob->imat, mpv->co); - view3d_cached_text_draw_add(co, str, 0, V3D_CACHE_TEXT_WORLDSPACE|V3D_CACHE_TEXT_ASCII, col); + view3d_cached_text_draw_add(co, numstr, 0, V3D_CACHE_TEXT_WORLDSPACE|V3D_CACHE_TEXT_ASCII, col); } else if ((i > stepsize) && (i < len-stepsize)) { bMotionPathVert *mpvP = (mpv - stepsize); bMotionPathVert *mpvN = (mpv + stepsize); if ((equals_v3v3(mpv->co, mpvP->co)==0) || (equals_v3v3(mpv->co, mpvN->co)==0)) { - sprintf(str, "%d", (sfra+i)); + sprintf(numstr, "%d", (sfra+i)); mul_v3_m4v3(co, ob->imat, mpv->co); - view3d_cached_text_draw_add(co, str, 0, V3D_CACHE_TEXT_WORLDSPACE|V3D_CACHE_TEXT_ASCII, col); + view3d_cached_text_draw_add(co, numstr, 0, V3D_CACHE_TEXT_WORLDSPACE|V3D_CACHE_TEXT_ASCII, col); } } } @@ -293,11 +293,11 @@ float mframe= (float)(sfra + i); if (BLI_dlrbTree_search_exact(&keys, compare_ak_cfraPtr, &mframe)) { - char str[32]; + char numstr[32]; - sprintf(str, "%d", (sfra+i)); + sprintf(numstr, "%d", (sfra+i)); mul_v3_m4v3(co, ob->imat, mpv->co); - view3d_cached_text_draw_add(co, str, 0, V3D_CACHE_TEXT_WORLDSPACE|V3D_CACHE_TEXT_ASCII, col); + view3d_cached_text_draw_add(co, numstr, 0, V3D_CACHE_TEXT_WORLDSPACE|V3D_CACHE_TEXT_ASCII, col); } } } @@ -312,269 +312,3 @@ if (v3d->zbuf) glEnable(GL_DEPTH_TEST); glPopMatrix(); } - -#if 0 // XXX temp file guards - -/* ***************************** Onion Skinning (Ghosts) ******************************** */ - -#if 0 // XXX only for bones -/* helper function for ghost drawing - sets/removes flags for temporarily - * hiding unselected bones while drawing ghosts - */ -static void ghost_poses_tag_unselected(Object *ob, short unset) -{ - bArmature *arm= ob->data; - bPose *pose= ob->pose; - bPoseChannel *pchan; - - /* don't do anything if no hiding any bones */ - if ((arm->flag & ARM_GHOST_ONLYSEL)==0) - return; - - /* loop over all pchans, adding/removing tags as appropriate */ - for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) { - if ((pchan->bone) && (arm->layer & pchan->bone->layer)) { - if (unset) { - /* remove tags from all pchans if cleaning up */ - pchan->bone->flag &= ~BONE_HIDDEN_PG; - } - else { - /* set tags on unselected pchans only */ - if ((pchan->bone->flag & BONE_SELECTED)==0) - pchan->bone->flag |= BONE_HIDDEN_PG; - } - } - } -} -#endif // XXX only for bones - -/* draw ghosts that occur within a frame range - * note: object should be in posemode - */ -static void draw_ghost_poses_range(Scene *scene, View3D *v3d, ARegion *ar, Base *base) -{ - Object *ob= base->object; - AnimData *adt= BKE_animdata_from_id(&ob->id); - bArmature *arm= ob->data; - bPose *posen, *poseo; - float start, end, stepsize, range, colfac; - int cfrao, flago, ipoflago; - - start = (float)arm->ghostsf; - end = (float)arm->ghostef; - if (end <= start) - return; - - stepsize= (float)(arm->ghostsize); - range= (float)(end - start); - - /* store values */ - ob->mode &= ~OB_MODE_POSE; - cfrao= CFRA; - flago= arm->flag; - arm->flag &= ~(ARM_DRAWNAMES|ARM_DRAWAXES); - ipoflago= ob->ipoflag; - ob->ipoflag |= OB_DISABLE_PATH; - - /* copy the pose */ - poseo= ob->pose; - copy_pose(&posen, ob->pose, 1); - ob->pose= posen; - armature_rebuild_pose(ob, ob->data); /* child pointers for IK */ - ghost_poses_tag_unselected(ob, 0); /* hide unselected bones if need be */ - - glEnable(GL_BLEND); - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - - /* draw from first frame of range to last */ - for (CFRA= (int)start; CFRA < end; CFRA += (int)stepsize) { - colfac = (end - (float)CFRA) / range; - UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0*sqrt(colfac))); - - BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL); - where_is_pose(scene, ob); - draw_pose_bones(scene, v3d, ar, base, OB_WIRE); - } - glDisable(GL_BLEND); - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); - - ghost_poses_tag_unselected(ob, 1); /* unhide unselected bones if need be */ - free_pose(posen); - - /* restore */ - CFRA= cfrao; - ob->pose= poseo; - arm->flag= flago; - armature_rebuild_pose(ob, ob->data); - ob->mode |= OB_MODE_POSE; - ob->ipoflag= ipoflago; -} - -/* draw ghosts on keyframes in action within range - * - object should be in posemode - */ -static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, ARegion *ar, Base *base) -{ - Object *ob= base->object; - AnimData *adt= BKE_animdata_from_id(&ob->id); - bAction *act= (adt) ? adt->action : NULL; - bArmature *arm= ob->data; - bPose *posen, *poseo; - DLRBT_Tree keys; - ActKeyColumn *ak, *akn; - float start, end, range, colfac, i; - int cfrao, flago; - - start = (float)arm->ghostsf; - end = (float)arm->ghostef; - if (end <= start) - return; - - /* get keyframes - then clip to only within range */ - BLI_dlrbTree_init(&keys); - action_to_keylist(adt, act, &keys, NULL); - BLI_dlrbTree_linkedlist_sync(&keys); - - range= 0; - for (ak= keys.first; ak; ak= akn) { - akn= ak->next; - - if ((ak->cfra < start) || (ak->cfra > end)) - BLI_freelinkN((ListBase *)&keys, ak); - else - range++; - } - if (range == 0) return; - - /* store values */ - ob->mode &= ~OB_MODE_POSE; - cfrao= CFRA; - flago= arm->flag; - arm->flag &= ~(ARM_DRAWNAMES|ARM_DRAWAXES); - ob->ipoflag |= OB_DISABLE_PATH; - - /* copy the pose */ - poseo= ob->pose; - copy_pose(&posen, ob->pose, 1); - ob->pose= posen; - armature_rebuild_pose(ob, ob->data); /* child pointers for IK */ - ghost_poses_tag_unselected(ob, 0); /* hide unselected bones if need be */ - - glEnable(GL_BLEND); - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - - /* draw from first frame of range to last */ - for (ak=keys.first, i=0; ak; ak=ak->next, i++) { - colfac = i/range; - UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0*sqrt(colfac))); - - CFRA= (int)ak->cfra; - - BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL); - where_is_pose(scene, ob); - draw_pose_bones(scene, v3d, ar, base, OB_WIRE); - } - glDisable(GL_BLEND); - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); - - ghost_poses_tag_unselected(ob, 1); /* unhide unselected bones if need be */ - BLI_dlrbTree_free(&keys); - free_pose(posen); - - /* restore */ - CFRA= cfrao; - ob->pose= poseo; - arm->flag= flago; - armature_rebuild_pose(ob, ob->data); - ob->mode |= OB_MODE_POSE; -} - -/* draw ghosts around current frame - * - object is supposed to be armature in posemode - */ -static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base) -{ - Object *ob= base->object; - AnimData *adt= BKE_animdata_from_id(&ob->id); - bArmature *arm= ob->data; - bPose *posen, *poseo; - float cur, start, end, stepsize, range, colfac, actframe, ctime; - int cfrao, flago; - - /* pre conditions, get an action with sufficient frames */ - if ELEM(NULL, adt, adt->action) - return; - - calc_action_range(adt->action, &start, &end, 0); - if (start == end) - return; - - stepsize= (float)(arm->ghostsize); - range= (float)(arm->ghostep)*stepsize + 0.5f; /* plus half to make the for loop end correct */ - - /* store values */ - ob->mode &= ~OB_MODE_POSE; - cfrao= CFRA; - actframe= BKE_nla_tweakedit_remap(adt, (float)CFRA, 0); - flago= arm->flag; - arm->flag &= ~(ARM_DRAWNAMES|ARM_DRAWAXES); - - /* copy the pose */ - poseo= ob->pose; - copy_pose(&posen, ob->pose, 1); - ob->pose= posen; - armature_rebuild_pose(ob, ob->data); /* child pointers for IK */ - ghost_poses_tag_unselected(ob, 0); /* hide unselected bones if need be */ - - glEnable(GL_BLEND); - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - - /* draw from darkest blend to lowest */ - for(cur= stepsize; cur= start && actframe+ctime <= end) { - CFRA= (int)BKE_nla_tweakedit_remap(adt, actframe+ctime, NLATIME_CONVERT_MAP); - - if (CFRA != cfrao) { - BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL); - where_is_pose(scene, ob); - draw_pose_bones(scene, v3d, ar, base, OB_WIRE); - } - } - - ctime= cur + (float)fmod((float)cfrao, stepsize) - stepsize+1.0f; /* ensures consistent stepping */ - colfac= ctime/range; - UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0*sqrt(colfac))); - - /* only within action range */ - if ((actframe-ctime >= start) && (actframe-ctime <= end)) { - CFRA= (int)BKE_nla_tweakedit_remap(adt, actframe-ctime, NLATIME_CONVERT_MAP); - - if (CFRA != cfrao) { - BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL); - where_is_pose(scene, ob); - draw_pose_bones(scene, v3d, ar, base, OB_WIRE); - } - } - } - glDisable(GL_BLEND); - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); - - ghost_poses_tag_unselected(ob, 1); /* unhide unselected bones if need be */ - free_pose(posen); - - /* restore */ - CFRA= cfrao; - ob->pose= poseo; - arm->flag= flago; - armature_rebuild_pose(ob, ob->data); - ob->mode |= OB_MODE_POSE; -} - - - -#endif // XXX temp file guards diff -Nru blender-2.61/source/blender/editors/space_view3d/drawarmature.c blender-2.62/source/blender/editors/space_view3d/drawarmature.c --- blender-2.61/source/blender/editors/space_view3d/drawarmature.c 2011-12-13 19:52:25.000000000 +0000 +++ blender-2.62/source/blender/editors/space_view3d/drawarmature.c 2012-02-15 19:36:59.000000000 +0000 @@ -526,7 +526,8 @@ glEnableClientState(GL_VERTEX_ARRAY); glNormalPointer(GL_FLOAT, 0, bone_octahedral_solid_normals); glVertexPointer(3, GL_FLOAT, 0, bone_octahedral_verts); - glDrawElements(GL_TRIANGLES, sizeof(bone_octahedral_solid_tris)/sizeof(unsigned int), GL_UNSIGNED_INT, bone_octahedral_solid_tris); + glDrawElements(GL_TRIANGLES, sizeof(bone_octahedral_solid_tris)/sizeof(unsigned int), + GL_UNSIGNED_INT, bone_octahedral_solid_tris); glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); #endif @@ -738,7 +739,9 @@ /* smat, imat = mat & imat to draw screenaligned */ -static void draw_sphere_bone_wire(float smat[][4], float imat[][4], int armflag, int boneflag, short constflag, unsigned int id, bPoseChannel *pchan, EditBone *ebone) +static void draw_sphere_bone_wire(float smat[][4], float imat[][4], + int armflag, int boneflag, short constflag, unsigned int id, + bPoseChannel *pchan, EditBone *ebone) { float head, tail /*, length*/; float *headvec, *tailvec, dirvec[3]; @@ -843,7 +846,8 @@ } /* does wire only for outline selecting */ -static void draw_sphere_bone(int dt, int armflag, int boneflag, short constflag, unsigned int id, bPoseChannel *pchan, EditBone *ebone) +static void draw_sphere_bone(int dt, int armflag, int boneflag, short constflag, unsigned int id, + bPoseChannel *pchan, EditBone *ebone) { GLUquadricObj *qobj; float head, tail, length; @@ -973,7 +977,8 @@ static GLubyte bm_dot7[]= {0x0, 0x38, 0x7C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38}; -static void draw_line_bone(int armflag, int boneflag, short constflag, unsigned int id, bPoseChannel *pchan, EditBone *ebone) +static void draw_line_bone(int armflag, int boneflag, short constflag, unsigned int id, + bPoseChannel *pchan, EditBone *ebone) { float length; @@ -1107,7 +1112,8 @@ } } -static void draw_b_bone(int dt, int armflag, int boneflag, short constflag, unsigned int id, bPoseChannel *pchan, EditBone *ebone) +static void draw_b_bone(int dt, int armflag, int boneflag, short constflag, unsigned int id, + bPoseChannel *pchan, EditBone *ebone) { float xwidth, length, zwidth; @@ -1220,7 +1226,8 @@ } } -static void draw_wire_bone(int dt, int armflag, int boneflag, short constflag, unsigned int id, bPoseChannel *pchan, EditBone *ebone) +static void draw_wire_bone(int dt, int armflag, int boneflag, short constflag, unsigned int id, + bPoseChannel *pchan, EditBone *ebone) { Mat4 *bbones = NULL; int segments = 0; @@ -1340,7 +1347,8 @@ } } -static void draw_custom_bone(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, int dt, int armflag, int boneflag, unsigned int id, float length) +static void draw_custom_bone(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, + int dt, int armflag, int boneflag, unsigned int id, float length) { if(ob==NULL) return; @@ -1573,7 +1581,8 @@ glColor3ub(50, 50, 255); // blue, Z axis limit glBegin(GL_LINE_STRIP); for (a=-16; a<=16; a++) { - float fac= ((float)a)/16.0f * 0.5f; /* *0.5f here comes from M_PI/360.0f when rotations were still in degrees */ + /* *0.5f here comes from M_PI/360.0f when rotations were still in degrees */ + float fac= ((float)a)/16.0f * 0.5f; phi= fac * (pchan->limitmax[2] - pchan->limitmin[2]); @@ -1596,7 +1605,8 @@ glColor3ub(255, 50, 50); // Red, X axis limit glBegin(GL_LINE_STRIP); for (a=-16; a<=16; a++) { - float fac= ((float)a)/16.0f * 0.5f; /* *0.5f here comes from M_PI/360.0f when rotations were still in degrees */ + /* *0.5f here comes from M_PI/360.0f when rotations were still in degrees */ + float fac= ((float)a)/16.0f * 0.5f; phi= (float)(0.5*M_PI) + fac * (pchan->limitmax[0] - pchan->limitmin[0]); i= (a == -16) ? 2 : 3; @@ -1630,7 +1640,8 @@ } /* assumes object is Armature with pose */ -static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, const short is_ghost, const short is_outline) +static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, + const short is_ghost, const short is_outline) { RegionView3D *rv3d= ar->regiondata; Object *ob= base->object; @@ -1730,10 +1741,13 @@ if (use_custom) { /* if drawwire, don't try to draw in solid */ - if (pchan->bone->flag & BONE_DRAWWIRE) + if (pchan->bone->flag & BONE_DRAWWIRE) { draw_wire= 1; - else - draw_custom_bone(scene, v3d, rv3d, pchan->custom, OB_SOLID, arm->flag, flag, index, bone->length); + } + else { + draw_custom_bone(scene, v3d, rv3d, pchan->custom, + OB_SOLID, arm->flag, flag, index, bone->length); + } } else if (arm->drawtype==ARM_LINE) ; /* nothing in solid */ @@ -1817,7 +1831,8 @@ if (bone == arm->act_bone) flag |= BONE_DRAW_ACTIVE; - draw_custom_bone(scene, v3d, rv3d, pchan->custom, OB_WIRE, arm->flag, flag, index, bone->length); + draw_custom_bone(scene, v3d, rv3d, pchan->custom, + OB_WIRE, arm->flag, flag, index, bone->length); glPopMatrix(); } @@ -1966,7 +1981,7 @@ unsigned char col[4]; float col_f[4]; glGetFloatv(GL_CURRENT_COLOR, col_f); /* incase this is not set below */ - rgb_float_to_byte(col_f, col); + rgb_float_to_uchar(col, col_f); col[3]= 255; if (v3d->zbuf) glDisable(GL_DEPTH_TEST); @@ -2580,7 +2595,3 @@ return retval; } - -/* *************** END Armature drawing ******************* */ - - diff -Nru blender-2.61/source/blender/editors/space_view3d/drawmesh.c blender-2.62/source/blender/editors/space_view3d/drawmesh.c --- blender-2.61/source/blender/editors/space_view3d/drawmesh.c 2011-12-13 19:52:25.000000000 +0000 +++ blender-2.62/source/blender/editors/space_view3d/drawmesh.c 2012-02-15 19:36:59.000000000 +0000 @@ -70,6 +70,25 @@ #include "view3d_intern.h" // own include +/* user data structures for derived mesh callbacks */ +typedef struct drawMeshFaceSelect_userData { + Mesh *me; + EdgeHash *eh; +} drawMeshFaceSelect_userData; + +typedef struct drawEMTFMapped_userData { + EditMesh *em; + short has_mcol; + short has_mtface; + MFace *mf; + MTFace *tf; +} drawEMTFMapped_userData; + +typedef struct drawTFace_userData { + MFace *mf; + MTFace *tf; +} drawTFace_userData; + /**************************** Face Select Mode *******************************/ /* Flags for marked edges */ @@ -121,7 +140,7 @@ static int draw_mesh_face_select__setHiddenOpts(void *userData, int index) { - struct { Mesh *me; EdgeHash *eh; } *data = userData; + drawMeshFaceSelect_userData *data = userData; Mesh *me= data->me; MEdge *med = &me->medge[index]; uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2); @@ -138,7 +157,7 @@ static int draw_mesh_face_select__setSelectOpts(void *userData, int index) { - struct { Mesh *me; EdgeHash *eh; } *data = userData; + drawMeshFaceSelect_userData *data = userData; MEdge *med = &data->me->medge[index]; uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2); @@ -159,7 +178,7 @@ static void draw_mesh_face_select(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm) { - struct { Mesh *me; EdgeHash *eh; } data; + drawMeshFaceSelect_userData data; data.me = me; data.eh = get_tface_mesh_marked_edge_info(me); @@ -330,11 +349,8 @@ Gtexdraw.islit= GPU_scene_object_lights(scene, ob, v3d->lay, rv3d->viewmat, !rv3d->is_persp); } - obcol[0]= CLAMPIS(ob->col[0]*255, 0, 255); - obcol[1]= CLAMPIS(ob->col[1]*255, 0, 255); - obcol[2]= CLAMPIS(ob->col[2]*255, 0, 255); - obcol[3]= CLAMPIS(ob->col[3]*255, 0, 255); - + rgba_float_to_uchar(obcol, ob->col); + glCullFace(GL_BACK); glEnable(GL_CULL_FACE); if(solidtex || v3d->drawtype==OB_TEXTURE) istex= 1; else istex= 0; @@ -513,7 +529,7 @@ static int draw_em_tf_mapped__set_draw(void *userData, int index) { - struct {EditMesh *em; short has_mcol; short has_mtface; MFace *mf; MTFace *tf;} *data = userData; + drawEMTFMapped_userData *data = userData; EditMesh *em = data->em; EditFace *efa= EM_get_face_for_index(index); MTFace *tface; @@ -528,7 +544,7 @@ return draw_tface__set_draw_legacy(tface, data->has_mcol, matnr); } -static int wpaint__setSolidDrawOptions(void *userData, int index, int *drawSmooth_r) +static int wpaint__setSolidDrawOptions_material(void *userData, int index, int *drawSmooth_r) { Mesh *me = (Mesh*)userData; @@ -543,6 +559,16 @@ return 1; } +/* when face select is on, use face hidden flag */ +static int wpaint__setSolidDrawOptions_facemask(void *userData, int index, int *drawSmooth_r) +{ + Mesh *me = (Mesh*)userData; + MFace *mface = &me->mface[index]; + if (mface->flag & ME_HIDE) return 0; + *drawSmooth_r = 1; + return 1; +} + static void draw_mesh_text(Scene *scene, Object *ob, int glsl) { Mesh *me = ob->data; @@ -631,7 +657,7 @@ static int compareDrawOptions(void *userData, int cur_index, int next_index) { - struct { MFace *mf; MTFace *tf; } *data = userData; + drawTFace_userData *data = userData; if(data->mf && data->mf[cur_index].mat_nr != data->mf[next_index].mat_nr) return 0; @@ -644,7 +670,7 @@ static int compareDrawOptionsEm(void *userData, int cur_index, int next_index) { - struct {EditMesh *em; short has_mcol; short has_mtface; MFace *mf; MTFace *tf;} *data= userData; + drawEMTFMapped_userData *data= userData; if(data->mf && data->mf[cur_index].mat_nr != data->mf[next_index].mat_nr) return 0; @@ -669,7 +695,7 @@ glColor4f(1.0f,1.0f,1.0f,1.0f); if(ob->mode & OB_MODE_EDIT) { - struct {EditMesh *em; short has_mcol; short has_mtface; MFace *mf; MTFace *tf;} data; + drawEMTFMapped_userData data; data.em= me->edit_mesh; data.has_mcol= CustomData_has_layer(&me->edit_mesh->fdata, CD_MCOL); @@ -681,19 +707,19 @@ } else if(draw_flags & DRAW_FACE_SELECT) { if(ob->mode & OB_MODE_WEIGHT_PAINT) - dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, GPU_enable_material, NULL, me, 1); + dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions_facemask, GPU_enable_material, NULL, me, 1); else dm->drawMappedFacesTex(dm, me->mface ? draw_tface_mapped__set_draw : NULL, NULL, me); } else { if(GPU_buffer_legacy(dm)) { - if (draw_flags & DRAW_DYNAMIC_PAINT_PREVIEW) + if (draw_flags & DRAW_MODIFIERS_PREVIEW) dm->drawFacesTex(dm, draw_mcol__set_draw_legacy, NULL, NULL); else dm->drawFacesTex(dm, draw_tface__set_draw_legacy, NULL, NULL); } else { - struct { MFace *mf; MTFace *tf; } userData; + drawTFace_userData userData; if(!CustomData_has_layer(&dm->faceData,CD_TEXTURE_MCOL)) add_tface_color_layer(dm); @@ -823,7 +849,7 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int draw_flags) { - if((!scene_use_new_shading_nodes(scene)) || (draw_flags & DRAW_DYNAMIC_PAINT_PREVIEW)) { + if((!scene_use_new_shading_nodes(scene)) || (draw_flags & DRAW_MODIFIERS_PREVIEW)) { draw_mesh_textured_old(scene, v3d, rv3d, ob, dm, draw_flags); return; } @@ -838,7 +864,7 @@ /* weight paint mode exception */ int useColors= 1; - dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, + dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions_material, GPU_enable_material, NULL, ob->data, useColors); } else { diff -Nru blender-2.61/source/blender/editors/space_view3d/drawobject.c blender-2.62/source/blender/editors/space_view3d/drawobject.c --- blender-2.61/source/blender/editors/space_view3d/drawobject.c 2011-12-13 19:52:25.000000000 +0000 +++ blender-2.62/source/blender/editors/space_view3d/drawobject.c 2012-02-15 19:36:59.000000000 +0000 @@ -36,7 +36,6 @@ #include "DNA_camera_types.h" #include "DNA_curve_types.h" #include "DNA_constraint_types.h" // for drawing constraint -#include "DNA_dynamicpaint_types.h" #include "DNA_lamp_types.h" #include "DNA_lattice_types.h" #include "DNA_material_types.h" @@ -118,6 +117,52 @@ OBDRAW_WIRE_ON_DEPTH= 2 } eWireDrawMode; +/* user data structures for derived mesh callbacks */ +typedef struct foreachScreenVert_userData { + void (*func)(void *userData, EditVert *eve, int x, int y, int index); + void *userData; + ViewContext vc; + eV3DClipTest clipVerts; +} foreachScreenVert_userData; + +typedef struct foreachScreenEdge_userData { + void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); + void *userData; + ViewContext vc; + eV3DClipTest clipVerts; +} foreachScreenEdge_userData; + +typedef struct foreachScreenFace_userData { + void (*func)(void *userData, EditFace *efa, int x, int y, int index); + void *userData; + ViewContext vc; +} foreachScreenFace_userData; + +typedef struct drawDMVerts_userData { + int sel; + EditVert *eve_act; +} drawDMVerts_userData; + +typedef struct drawDMEdgesSel_userData { + unsigned char *baseCol, *selCol, *actCol; + EditEdge *eed_act; +} drawDMEdgesSel_userData; + +typedef struct drawDMFacesSel_userData { + unsigned char *cols[3]; + EditFace *efa_act; + int *orig_index; +} drawDMFacesSel_userData; + +typedef struct drawDMNormal_userData { + float normalsize; +} drawDMNormal_userData; + +typedef struct bbsObmodeMeshVerts_userData { + void *offset; + MVert *mvert; +} bbsObmodeMeshVerts_userData; + static void draw_bounding_volume(Scene *scene, Object *ob, char type); static void drawcube_size(float size); @@ -1458,48 +1503,49 @@ glCallList(displist); } -static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d, MovieClip *clip, int flag) +static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D *v3d, + MovieClip *clip, MovieTrackingObject *tracking_object, int flag, int *global_track_index) { MovieTracking *tracking= &clip->tracking; MovieTrackingTrack *track; - float mat[4][4], imat[4][4], curcol[4]; + float mat[4][4], imat[4][4]; unsigned char col[4], scol[4]; - int bundlenr= 1; - - if((v3d->flag2&V3D_SHOW_RECONSTRUCTION)==0) - return; - - if(v3d->flag2&V3D_RENDER_OVERRIDE) - return; - - glGetFloatv(GL_CURRENT_COLOR, curcol); + int tracknr= *global_track_index; + ListBase *tracksbase= BKE_tracking_object_tracks(tracking, tracking_object); UI_GetThemeColor4ubv(TH_TEXT, col); UI_GetThemeColor4ubv(TH_SELECT, scol); BKE_get_tracking_mat(scene, base->object, mat); - glEnable(GL_LIGHTING); - glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); - glEnable(GL_COLOR_MATERIAL); - glShadeModel(GL_SMOOTH); + glPushMatrix(); - /* current ogl matrix is translated in camera space, bundles should - be rendered in world space, so camera matrix should be "removed" - from current ogl matrix */ - invert_m4_m4(imat, base->object->obmat); + if(tracking_object->flag & TRACKING_OBJECT_CAMERA) { + /* current ogl matrix is translated in camera space, bundles should + be rendered in world space, so camera matrix should be "removed" + from current ogl matrix */ + invert_m4_m4(imat, base->object->obmat); - glPushMatrix(); - glMultMatrixf(imat); - glMultMatrixf(mat); + glMultMatrixf(imat); + glMultMatrixf(mat); + } + else { + float obmat[4][4]; + + BKE_tracking_get_interpolated_camera(tracking, tracking_object, scene->r.cfra, obmat); + + invert_m4_m4(imat, obmat); + glMultMatrixf(imat); + } + + for (track= tracksbase->first; track; track= track->next) { + int selected= TRACK_SELECTED(track); - for ( track= tracking->tracks.first; track; track= track->next) { - int selected= track->flag&SELECT || track->pat_flag&SELECT || track->search_flag&SELECT; if((track->flag&TRACK_HAS_BUNDLE)==0) continue; if(flag&DRAW_PICKING) - glLoadName(base->selcol + (bundlenr<<16)); + glLoadName(base->selcol + (tracknr<<16)); glPushMatrix(); glTranslatef(track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]); @@ -1507,7 +1553,6 @@ if(v3d->drawtype==OB_WIRE) { glDisable(GL_LIGHTING); - glDepthMask(0); if(selected) { if(base==BASACT) UI_ThemeColor(TH_ACTIVE); @@ -1519,7 +1564,6 @@ drawaxes(0.05f, v3d->bundle_drawtype); - glDepthMask(1); glEnable(GL_LIGHTING); } else if(v3d->drawtype>OB_WIRE) { if(v3d->bundle_drawtype==OB_EMPTY_SPHERE) { @@ -1528,7 +1572,6 @@ if(base==BASACT) UI_ThemeColor(TH_ACTIVE); else UI_ThemeColor(TH_SELECT); - glDepthMask(0); glLineWidth(2.f); glDisable(GL_LIGHTING); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); @@ -1538,7 +1581,6 @@ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glEnable(GL_LIGHTING); glLineWidth(1.f); - glDepthMask(1); } if(track->flag&TRACK_CUSTOMCOLOR) glColor3fv(track->color); @@ -1547,7 +1589,6 @@ draw_bundle_sphere(); } else { glDisable(GL_LIGHTING); - glDepthMask(0); if(selected) { if(base==BASACT) UI_ThemeColor(TH_ACTIVE); @@ -1559,7 +1600,6 @@ drawaxes(0.05f, v3d->bundle_drawtype); - glDepthMask(1); glEnable(GL_LIGHTING); } } @@ -1577,32 +1617,67 @@ view3d_cached_text_draw_add(pos, track->name, 10, V3D_CACHE_TEXT_GLOBALSPACE, tcol); } - bundlenr++; + tracknr++; } if((flag & DRAW_PICKING)==0) { - if(v3d->flag2&V3D_SHOW_CAMERAPATH && clip->tracking.reconstruction.camnr) { - int a= 0; - MovieTrackingReconstruction *reconstruction= &tracking->reconstruction; - MovieReconstructedCamera *camera= tracking->reconstruction.cameras; + if((v3d->flag2&V3D_SHOW_CAMERAPATH) && (tracking_object->flag&TRACKING_OBJECT_CAMERA)) { + MovieTrackingReconstruction *reconstruction; + reconstruction= BKE_tracking_object_reconstruction(tracking, tracking_object); + + if(reconstruction->camnr) { + MovieReconstructedCamera *camera= reconstruction->cameras; + int a= 0; - glDisable(GL_LIGHTING); - UI_ThemeColor(TH_CAMERA_PATH); - glLineWidth(2.0f); + glDisable(GL_LIGHTING); + UI_ThemeColor(TH_CAMERA_PATH); + glLineWidth(2.0f); - glBegin(GL_LINE_STRIP); - for(a= 0; acamnr; a++, camera++) { - glVertex3fv(camera->mat[3]); - } - glEnd(); + glBegin(GL_LINE_STRIP); + for(a= 0; acamnr; a++, camera++) { + glVertex3fv(camera->mat[3]); + } + glEnd(); - glLineWidth(1.0f); - glEnable(GL_LIGHTING); + glLineWidth(1.0f); + glEnable(GL_LIGHTING); + } } } glPopMatrix(); + *global_track_index= tracknr; +} + +static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d, MovieClip *clip, int flag) +{ + MovieTracking *tracking= &clip->tracking; + MovieTrackingObject *tracking_object; + float curcol[4]; + int global_track_index= 1; + + if((v3d->flag2&V3D_SHOW_RECONSTRUCTION)==0) + return; + + if(v3d->flag2&V3D_RENDER_OVERRIDE) + return; + + glGetFloatv(GL_CURRENT_COLOR, curcol); + + glEnable(GL_LIGHTING); + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + glEnable(GL_COLOR_MATERIAL); + glShadeModel(GL_SMOOTH); + + tracking_object= tracking->objects.first; + while(tracking_object) { + draw_viewport_object_reconstruction(scene, base, v3d, clip, tracking_object, + flag, &global_track_index); + + tracking_object= tracking_object->next; + } + /* restore */ glShadeModel(GL_FLAT); glDisable(GL_COLOR_MATERIAL); @@ -1914,9 +1989,7 @@ * use the object matrix in the useual way */ static void mesh_foreachScreenVert__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s)) { - struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); - void *userData; ViewContext vc; eV3DClipTest clipVerts; } *data = userData; - + foreachScreenVert_userData *data = userData; EditVert *eve = EM_get_vert_for_index(index); if (eve->h==0) { @@ -1938,9 +2011,7 @@ void (*func)(void *userData, EditVert *eve, int x, int y, int index), void *userData, eV3DClipTest clipVerts) { - struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); - void *userData; ViewContext vc; eV3DClipTest clipVerts; } data; - + foreachScreenVert_userData data; DerivedMesh *dm = editmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); data.vc= *vc; @@ -1994,8 +2065,7 @@ } static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, float *v0co, float *v1co) { - struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); - void *userData; ViewContext vc; eV3DClipTest clipVerts; } *data = userData; + foreachScreenEdge_userData *data = userData; EditEdge *eed = EM_get_edge_for_index(index); short s[2][2]; @@ -2026,8 +2096,7 @@ void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index), void *userData, eV3DClipTest clipVerts) { - struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); - void *userData; ViewContext vc; eV3DClipTest clipVerts; } data; + foreachScreenEdge_userData data; DerivedMesh *dm = editmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); data.vc= *vc; @@ -2047,7 +2116,7 @@ static void mesh_foreachScreenFace__mapFunc(void *userData, int index, float *cent, float *UNUSED(no)) { - struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; ViewContext vc; } *data = userData; + foreachScreenFace_userData *data = userData; EditFace *efa = EM_get_face_for_index(index); short s[2]; @@ -2065,7 +2134,7 @@ void (*func)(void *userData, EditFace *efa, int x, int y, int index), void *userData) { - struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; ViewContext vc; } data; + foreachScreenFace_userData data; DerivedMesh *dm = editmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); data.vc= *vc; @@ -2147,20 +2216,24 @@ static void draw_dm_face_normals__mapFunc(void *userData, int index, float *cent, float *no) { - ToolSettings *ts= ((Scene *)userData)->toolsettings; + drawDMNormal_userData *data = userData; EditFace *efa = EM_get_face_for_index(index); if (efa->h==0 && efa->fgonf!=EM_FGON) { glVertex3fv(cent); - glVertex3f( cent[0] + no[0]*ts->normalsize, - cent[1] + no[1]*ts->normalsize, - cent[2] + no[2]*ts->normalsize); + glVertex3f(cent[0] + no[0] * data->normalsize, + cent[1] + no[1] * data->normalsize, + cent[2] + no[2] * data->normalsize); } } static void draw_dm_face_normals(Scene *scene, DerivedMesh *dm) { + drawDMNormal_userData data; + + data.normalsize = scene->toolsettings->normalsize; + glBegin(GL_LINES); - dm->foreachMappedFaceCenter(dm, draw_dm_face_normals__mapFunc, scene); + dm->foreachMappedFaceCenter(dm, draw_dm_face_normals__mapFunc, &data); glEnd(); } @@ -2182,35 +2255,39 @@ static void draw_dm_vert_normals__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s) { - Scene *scene= (Scene *)userData; - ToolSettings *ts= scene->toolsettings; + drawDMNormal_userData *data = userData; EditVert *eve = EM_get_vert_for_index(index); if (eve->h==0) { glVertex3fv(co); if (no_f) { - glVertex3f( co[0] + no_f[0]*ts->normalsize, - co[1] + no_f[1]*ts->normalsize, - co[2] + no_f[2]*ts->normalsize); - } else { - glVertex3f( co[0] + no_s[0]*ts->normalsize/32767.0f, - co[1] + no_s[1]*ts->normalsize/32767.0f, - co[2] + no_s[2]*ts->normalsize/32767.0f); + glVertex3f(co[0] + no_f[0] * data->normalsize, + co[1] + no_f[1] * data->normalsize, + co[2] + no_f[2] * data->normalsize); + } + else { + glVertex3f(co[0] + no_s[0] * (data->normalsize / 32767.0f), + co[1] + no_s[1] * (data->normalsize / 32767.0f), + co[2] + no_s[2] * (data->normalsize / 32767.0f)); } } } static void draw_dm_vert_normals(Scene *scene, DerivedMesh *dm) { + drawDMNormal_userData data; + + data.normalsize = scene->toolsettings->normalsize; + glBegin(GL_LINES); - dm->foreachMappedVert(dm, draw_dm_vert_normals__mapFunc, scene); + dm->foreachMappedVert(dm, draw_dm_vert_normals__mapFunc, &data); glEnd(); } /* Draw verts with color set based on selection */ static void draw_dm_verts__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s)) { - struct { int sel; EditVert *eve_act; } * data = userData; + drawDMVerts_userData * data = userData; EditVert *eve = EM_get_vert_for_index(index); if (eve->h==0 && (eve->f&SELECT)==data->sel) { @@ -2237,7 +2314,7 @@ static void draw_dm_verts(DerivedMesh *dm, int sel, EditVert *eve_act) { - struct { int sel; EditVert *eve_act; } data; + drawDMVerts_userData data; data.sel = sel; data.eve_act = eve_act; @@ -2251,7 +2328,7 @@ { EditEdge *eed = EM_get_edge_for_index(index); //unsigned char **cols = userData, *col; - struct { unsigned char *baseCol, *selCol, *actCol; EditEdge *eed_act; } * data = userData; + drawDMEdgesSel_userData * data = userData; unsigned char *col; if (eed->h==0) { @@ -2275,7 +2352,7 @@ } static void draw_dm_edges_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol, unsigned char *actCol, EditEdge *eed_act) { - struct { unsigned char *baseCol, *selCol, *actCol; EditEdge *eed_act; } data; + drawDMEdgesSel_userData data; data.baseCol = baseCol; data.selCol = selCol; @@ -2349,7 +2426,7 @@ * return 2 for the active face so it renders with stipple enabled */ static int draw_dm_faces_sel__setDrawOptions(void *userData, int index, int *UNUSED(drawSmooth_r)) { - struct { unsigned char *cols[3]; EditFace *efa_act; int *orig_index; } * data = userData; + drawDMFacesSel_userData * data = userData; EditFace *efa = EM_get_face_for_index(index); unsigned char *col; @@ -2369,7 +2446,7 @@ static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int next_index) { - struct { unsigned char *cols[3]; EditFace *efa_act; int *orig_index; } *data = userData; + drawDMFacesSel_userData *data = userData; EditFace *efa; EditFace *next_efa; unsigned char *col, *next_col; @@ -2398,7 +2475,7 @@ /* also draws the active face */ static void draw_dm_faces_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol, unsigned char *actCol, EditFace *efa_act) { - struct { unsigned char *cols[3]; EditFace *efa_act; int *orig_index; } data; + drawDMFacesSel_userData data; data.cols[0] = baseCol; data.cols[1] = selCol; data.cols[2] = actCol; @@ -2590,15 +2667,14 @@ } } -static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, - Object *ob, EditMesh *em, UnitSettings *unit) +static void draw_em_measure_stats(View3D *v3d, Object *ob, EditMesh *em, UnitSettings *unit) { Mesh *me= ob->data; EditEdge *eed; EditFace *efa; float v1[3], v2[3], v3[3], v4[3], vmid[3]; float fvec[3]; - char val[32]; /* Stores the measurement display text here */ + char numstr[32]; /* Stores the measurement display text here */ const char *conv_float; /* Use a float conversion matching the grid size */ unsigned char col[4]= {0, 0, 0, 255}; /* color of the text to draw */ float area; /* area of the face */ @@ -2614,11 +2690,6 @@ else if (grid < 1.0f) conv_float= "%.4g"; else if (grid < 10.0f) conv_float= "%.3g"; else conv_float= "%.2g"; - - if(v3d->zbuf && (v3d->flag & V3D_ZBUF_SELECT)==0) - glDisable(GL_DEPTH_TEST); - - if(v3d->zbuf) bglPolygonOffset(rv3d->dist, 5.0f); if(me->drawflag & ME_DRAWEXTRA_EDGELEN) { UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGELEN, col); @@ -2635,18 +2706,22 @@ mul_mat3_m4_v3(ob->obmat, v1); mul_mat3_m4_v3(ob->obmat, v2); } - if(unit->system) - bUnit_AsString(val, sizeof(val), len_v3v3(v1, v2)*unit->scale_length, 3, unit->system, B_UNIT_LENGTH, do_split, FALSE); - else - sprintf(val, conv_float, len_v3v3(v1, v2)); - view3d_cached_text_draw_add(vmid, val, 0, V3D_CACHE_TEXT_ASCII, col); + if(unit->system) { + bUnit_AsString(numstr, sizeof(numstr), len_v3v3(v1, v2) * unit->scale_length, 3, + unit->system, B_UNIT_LENGTH, do_split, FALSE); + } + else { + sprintf(numstr, conv_float, len_v3v3(v1, v2)); + } + + view3d_cached_text_draw_add(vmid, numstr, 0, V3D_CACHE_TEXT_ASCII, col); } } } if(me->drawflag & ME_DRAWEXTRA_FACEAREA) { -// XXX extern int faceselectedOR(EditFace *efa, int flag); // editmesh.h shouldn't be in this file... ok for now? +// XXX extern int faceselectedOR(EditFace *efa, int flag); // editmesh.h shouldn't be in this file... ok for now? UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEAREA, col); for(efa= em->faces.first; efa; efa= efa->next) { @@ -2669,12 +2744,16 @@ else area = area_tri_v3(v1, v2, v3); - if(unit->system) - bUnit_AsString(val, sizeof(val), area*unit->scale_length, 3, unit->system, B_UNIT_LENGTH, do_split, FALSE); // XXX should be B_UNIT_AREA - else - sprintf(val, conv_float, area); + if(unit->system) { + // XXX should be B_UNIT_AREA + bUnit_AsString(numstr, sizeof(numstr), area * unit->scale_length, 3, + unit->system, B_UNIT_LENGTH, do_split, FALSE); + } + else { + sprintf(numstr, conv_float, area); + } - view3d_cached_text_draw_add(efa->cent, val, 0, V3D_CACHE_TEXT_ASCII, col); + view3d_cached_text_draw_add(efa->cent, numstr, 0, V3D_CACHE_TEXT_ASCII, col); } } } @@ -2708,52 +2787,78 @@ if( (e4->f & e1->f & SELECT) || (do_moving && (efa->v1->f & SELECT)) ) { /* Vec 1 */ - sprintf(val,"%.3g", RAD2DEGF(angle_v3v3v3(v4, v1, v2))); + sprintf(numstr,"%.3g", RAD2DEGF(angle_v3v3v3(v4, v1, v2))); interp_v3_v3v3(fvec, efa->cent, efa->v1->co, 0.8f); - view3d_cached_text_draw_add(fvec, val, 0, V3D_CACHE_TEXT_ASCII, col); + view3d_cached_text_draw_add(fvec, numstr, 0, V3D_CACHE_TEXT_ASCII, col); } if( (e1->f & e2->f & SELECT) || (do_moving && (efa->v2->f & SELECT)) ) { /* Vec 2 */ - sprintf(val,"%.3g", RAD2DEGF(angle_v3v3v3(v1, v2, v3))); + sprintf(numstr,"%.3g", RAD2DEGF(angle_v3v3v3(v1, v2, v3))); interp_v3_v3v3(fvec, efa->cent, efa->v2->co, 0.8f); - view3d_cached_text_draw_add(fvec, val, 0, V3D_CACHE_TEXT_ASCII, col); + view3d_cached_text_draw_add(fvec, numstr, 0, V3D_CACHE_TEXT_ASCII, col); } if( (e2->f & e3->f & SELECT) || (do_moving && (efa->v3->f & SELECT)) ) { /* Vec 3 */ if(efa->v4) - sprintf(val,"%.3g", RAD2DEGF(angle_v3v3v3(v2, v3, v4))); + sprintf(numstr,"%.3g", RAD2DEGF(angle_v3v3v3(v2, v3, v4))); else - sprintf(val,"%.3g", RAD2DEGF(angle_v3v3v3(v2, v3, v1))); + sprintf(numstr,"%.3g", RAD2DEGF(angle_v3v3v3(v2, v3, v1))); interp_v3_v3v3(fvec, efa->cent, efa->v3->co, 0.8f); - view3d_cached_text_draw_add(fvec, val, 0, V3D_CACHE_TEXT_ASCII, col); + view3d_cached_text_draw_add(fvec, numstr, 0, V3D_CACHE_TEXT_ASCII, col); } /* Vec 4 */ if(efa->v4) { if( (e3->f & e4->f & SELECT) || (do_moving && (efa->v4->f & SELECT)) ) { - sprintf(val,"%.3g", RAD2DEGF(angle_v3v3v3(v3, v4, v1))); + sprintf(numstr,"%.3g", RAD2DEGF(angle_v3v3v3(v3, v4, v1))); interp_v3_v3v3(fvec, efa->cent, efa->v4->co, 0.8f); - view3d_cached_text_draw_add(fvec, val, 0, V3D_CACHE_TEXT_ASCII, col); + view3d_cached_text_draw_add(fvec, numstr, 0, V3D_CACHE_TEXT_ASCII, col); } } } } +} - /* useful for debugging index vs shape key index */ -#if 0 - { - EditVert *eve; - int j; +static void draw_em_indices(EditMesh *em) +{ + EditEdge *e; + EditFace *f; + EditVert *v; + int i; + char numstr[32]; + float pos[3]; + unsigned char col[4]; + + /* For now, reuse appropriate theme colors from stats text colors */ + + if (em->selectmode & SCE_SELECT_VERTEX) { UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEANG, col); - for(eve= em->verts.first, j= 0; eve; eve= eve->next, j++) { - sprintf(val, "%d:%d", j, eve->keyindex); - view3d_cached_text_draw_add(eve->co, val, 0, V3D_CACHE_TEXT_ASCII, col); + for (v = em->verts.first, i = 0; v; v = v->next, i++) { + if (v->f & SELECT) { + sprintf(numstr, "%d", i); + view3d_cached_text_draw_add(v->co, numstr, 0, V3D_CACHE_TEXT_ASCII, col); + } + } + } + + if (em->selectmode & SCE_SELECT_EDGE) { + UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGELEN, col); + for (e = em->edges.first, i = 0; e; e = e->next, i++) { + if (e->f & SELECT) { + sprintf(numstr, "%d", i); + mid_v3_v3v3(pos, e->v1->co, e->v2->co); + view3d_cached_text_draw_add(pos, numstr, 0, V3D_CACHE_TEXT_ASCII, col); + } } } -#endif - if(v3d->zbuf) { - glEnable(GL_DEPTH_TEST); - bglPolygonOffset(rv3d->dist, 0.0f); + if (em->selectmode & SCE_SELECT_FACE) { + UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEAREA, col); + for (f = em->faces.first, i = 0; f; f = f->next, i++) { + if (f->f & SELECT) { + sprintf(numstr, "%d", i); + view3d_cached_text_draw_add(f->cent, numstr, 0, V3D_CACHE_TEXT_ASCII, col); + } + } } } @@ -2914,8 +3019,6 @@ draw_em_fancy_edges(scene, v3d, me, cageDM, 0, eed_act); } if(em) { -// XXX retopo_matrix_update(v3d); - draw_em_fancy_verts(scene, v3d, ob, cageDM, eve_act); if(me->drawflag & ME_DRAWNORMALS) { @@ -2930,7 +3033,12 @@ if ( (me->drawflag & (ME_DRAWEXTRA_EDGELEN|ME_DRAWEXTRA_FACEAREA|ME_DRAWEXTRA_FACEANG)) && !(v3d->flag2 & V3D_RENDER_OVERRIDE)) { - draw_em_measure_stats(v3d, rv3d, ob, em, &scene->unit); + draw_em_measure_stats(v3d, ob, em, &scene->unit); + } + + if ((G.f & G_DEBUG) && (me->drawflag & ME_DRAWEXTRA_INDICES) && + !(v3d->flag2 & V3D_RENDER_OVERRIDE)) { + draw_em_indices(em); } } @@ -2984,27 +3092,16 @@ eWireDrawMode draw_wire= OBDRAW_WIRE_OFF; int /* totvert,*/ totedge, totface; DerivedMesh *dm= mesh_get_derived_final(scene, ob, scene->customdata_mask); - ModifierData *md = NULL; const short is_obact= (ob == OBACT); int draw_flags = (is_obact && paint_facesel_test(ob)) ? DRAW_FACE_SELECT : 0; if(!dm) return; - /* check to draw dynamic paint colors */ - if ((md = modifiers_findByType(ob, eModifierType_DynamicPaint))) - { - /* check if target has an active dpaint modifier */ - if(md && (md->mode & eModifierMode_Realtime)) - { - DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md; - /* if canvas is ready to preview vertex colors */ - if (pmd->canvas && pmd->canvas->flags & MOD_DPAINT_PREVIEW_READY && - DM_get_face_data_layer(dm, CD_WEIGHT_MCOL)) { - draw_flags |= DRAW_DYNAMIC_PAINT_PREVIEW; - } - } - } + /* Check to draw dynamic paint colors (or weights from WeightVG modifiers). + * Note: Last "preview-active" modifier in stack will win! */ + if(DM_get_face_data_layer(dm, CD_WEIGHT_MCOL) && modifiers_isPreview(ob)) + draw_flags |= DRAW_MODIFIERS_PREVIEW; /* Unwanted combination */ if (draw_flags & DRAW_FACE_SELECT) { @@ -3045,7 +3142,7 @@ draw_mesh_object_outline(v3d, ob, dm); } - if(draw_glsl_material(scene, ob, v3d, dt) && !(draw_flags & DRAW_DYNAMIC_PAINT_PREVIEW)) { + if(draw_glsl_material(scene, ob, v3d, dt) && !(draw_flags & DRAW_MODIFIERS_PREVIEW)) { glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW); dm->drawFacesGLSL(dm, GPU_enable_material); @@ -3089,13 +3186,14 @@ bglPolygonOffset(rv3d->dist, 0.0); glDepthMask(1); glDisable(GL_LINE_STIPPLE); + glDisable(GL_BLEND); GPU_disable_material(); /* since we already draw wire as wp guide, dont draw over the top */ draw_wire= OBDRAW_WIRE_OFF; } - else if (draw_flags & DRAW_DYNAMIC_PAINT_PREVIEW) { + else if (draw_flags & DRAW_MODIFIERS_PREVIEW) { /* for object selection draws no shade */ if (flag & (DRAW_PICKING|DRAW_CONSTCOLOR)) { dm->drawFacesSolid(dm, NULL, 0, GPU_enable_material); @@ -3944,14 +4042,14 @@ ParticleDrawData *pdd = psys->pdd; Material *ma; float vel[3], imat[4][4]; - float timestep, pixsize=1.0, pa_size, r_tilt, r_length; + float timestep, pixsize_scale, pa_size, r_tilt, r_length; float pa_time, pa_birthtime, pa_dietime, pa_health, intensity; float cfra; float ma_col[3]= {0.0f, 0.0f, 0.0f}; int a, totpart, totpoint=0, totve=0, drawn, draw_as, totchild=0; int select=ob->flag&SELECT, create_cdata=0, need_v=0; GLint polygonmode[2]; - char val[32]; + char numstr[32]; unsigned char tcol[4]= {0, 0, 0, 255}; /* 1. */ @@ -4010,7 +4108,7 @@ if(v3d->zbuf) glDepthMask(1); if((ma) && (part->draw_col == PART_DRAW_COL_MAT)) { - rgb_float_to_byte(&(ma->r), tcol); + rgb_float_to_uchar(tcol, &(ma->r)); copy_v3_v3(ma_col, &ma->r); } @@ -4020,7 +4118,7 @@ if( (base->flag & OB_FROMDUPLI) && (ob->flag & OB_FROMGROUP) ) { float mat[4][4]; - mul_m4_m4m4(mat, psys->imat, ob->obmat); + mult_m4_m4m4(mat, ob->obmat, psys->imat); glMultMatrixf(mat); } @@ -4051,12 +4149,11 @@ case PART_DRAW_CROSS: case PART_DRAW_AXIS: /* lets calculate the scale: */ - pixsize= ED_view3d_pixel_size(rv3d, ob->obmat[3]); - if(part->draw_size==0.0) - pixsize *= 2.0f; + if (part->draw_size == 0.0) + pixsize_scale = 2.0f; else - pixsize*=part->draw_size; + pixsize_scale = part->draw_size; if(draw_as==PART_DRAW_AXIS) create_cdata = 1; @@ -4244,6 +4341,8 @@ ct+=dt; for(i=0; i < trail_count; i++, ct += dt) { + float pixsize; + if(part->draw & PART_ABS_PATH_TIME) { if(ct < pa_birthtime || ct > pa_dietime) continue; @@ -4277,6 +4376,8 @@ bb.time = ct; } + pixsize = ED_view3d_pixel_size(rv3d, state.co) * pixsize_scale; + draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, psys->pdd); totpoint++; @@ -4287,6 +4388,8 @@ { state.time=cfra; if(psys_get_particle_state(&sim,a,&state,0)){ + float pixsize; + if(psys->parent) mul_m4_v3(psys->parent->obmat, state.co); @@ -4310,6 +4413,8 @@ bb.time = pa_time; } + pixsize = ED_view3d_pixel_size(rv3d, state.co) * pixsize_scale; + draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, pdd); totpoint++; @@ -4339,8 +4444,8 @@ if((part->draw & PART_DRAW_NUM || part->draw & PART_DRAW_HEALTH) && (v3d->flag2 & V3D_RENDER_OVERRIDE)==0){ float vec_txt[3]; - char *val_pos= val; - val[0]= '\0'; + char *val_pos= numstr; + numstr[0]= '\0'; if(part->draw&PART_DRAW_NUM) { if(a < totpart && (part->draw & PART_DRAW_HEALTH) && (part->phystype==PART_PHYS_BOIDS)) { @@ -4359,7 +4464,7 @@ /* in path drawing state.co is the end point */ /* use worldspace beause object matrix is already applied */ mul_v3_m4v3(vec_txt, ob->imat, state.co); - view3d_cached_text_draw_add(vec_txt, val, 10, V3D_CACHE_TEXT_WORLDSPACE|V3D_CACHE_TEXT_ASCII, tcol); + view3d_cached_text_draw_add(vec_txt, numstr, 10, V3D_CACHE_TEXT_WORLDSPACE|V3D_CACHE_TEXT_ASCII, tcol); } } } @@ -4448,10 +4553,10 @@ for(a=0, pa=psys->particles; aimat, cache[a]->co); - view3d_cached_text_draw_add(vec_txt, val, 10, V3D_CACHE_TEXT_WORLDSPACE|V3D_CACHE_TEXT_ASCII, tcol); + view3d_cached_text_draw_add(vec_txt, numstr, 10, V3D_CACHE_TEXT_WORLDSPACE|V3D_CACHE_TEXT_ASCII, tcol); } } } @@ -5236,8 +5341,6 @@ short hide_handles = (cu->drawflag & CU_HIDE_HANDLES); int index; -// XXX retopo_matrix_update(v3d); - /* DispList */ UI_ThemeColor(TH_WIRE); drawDispList(scene, v3d, rv3d, base, dt); @@ -6064,7 +6167,7 @@ float curcol[4]; unsigned char tcol[4]; glGetFloatv(GL_CURRENT_COLOR, curcol); - rgb_float_to_byte(curcol, tcol); + rgb_float_to_uchar(tcol, curcol); tcol[3]= 255; eul_to_mat4(mat,&data->axX); @@ -6687,7 +6790,7 @@ float curcol[4]; unsigned char tcol[4]; glGetFloatv(GL_CURRENT_COLOR, curcol); - rgb_float_to_byte(curcol, tcol); + rgb_float_to_uchar(tcol, curcol); tcol[3]= 255; view3d_cached_text_draw_add(zero, ob->id.name+2, 10, 0, tcol); } @@ -6788,7 +6891,34 @@ ListBase targets = {NULL, NULL}; bConstraintTarget *ct; - if ((curcon->flag & CONSTRAINT_EXPAND) && (cti) && (cti->get_constraint_targets)) { + if(ELEM(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_OBJECTSOLVER)) { + /* special case for object solver and follow track constraints because they don't fill + constraint targets properly (design limitation -- scene is needed for their target + but it can't be accessed from get_targets callvack) */ + + Object *camob= NULL; + + if(cti->type==CONSTRAINT_TYPE_FOLLOWTRACK) { + bFollowTrackConstraint *data= (bFollowTrackConstraint *)curcon->data; + + camob= data->camera ? data->camera : scene->camera; + } + else if(cti->type==CONSTRAINT_TYPE_OBJECTSOLVER) { + bObjectSolverConstraint *data= (bObjectSolverConstraint *)curcon->data; + + camob= data->camera ? data->camera : scene->camera; + } + + if(camob) { + setlinestyle(3); + glBegin(GL_LINES); + glVertex3fv(camob->obmat[3]); + glVertex3fv(ob->obmat[3]); + glEnd(); + setlinestyle(0); + } + } + else if ((curcon->flag & CONSTRAINT_EXPAND) && (cti) && (cti->get_constraint_targets)) { cti->get_constraint_targets(curcon, &targets); for (ct= targets.first; ct; ct= ct->next) { @@ -6822,7 +6952,7 @@ static void bbs_obmode_mesh_verts__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s)) { - struct {void* offset; MVert *mvert;} *data = userData; + bbsObmodeMeshVerts_userData *data = userData; MVert *mv = &data->mvert[index]; int offset = (intptr_t) data->offset; @@ -6834,7 +6964,7 @@ static void bbs_obmode_mesh_verts(Object *ob, DerivedMesh *dm, int offset) { - struct {void* offset; struct MVert *mvert;} data; + bbsObmodeMeshVerts_userData data; Mesh *me = ob->data; MVert *mvert = me->mvert; data.mvert = mvert; diff -Nru blender-2.61/source/blender/editors/space_view3d/drawvolume.c blender-2.62/source/blender/editors/space_view3d/drawvolume.c --- blender-2.61/source/blender/editors/space_view3d/drawvolume.c 2011-12-13 19:52:25.000000000 +0000 +++ blender-2.62/source/blender/editors/space_view3d/drawvolume.c 2012-02-15 19:36:59.000000000 +0000 @@ -158,23 +158,6 @@ return dot_v3v3(up, tmp) >= 0; } -// copied from gpu_extension.c -static int is_pow2(int n) -{ - return ((n)&(n-1))==0; -} - -static int larger_pow2(int n) -{ - if (is_pow2(n)) - return n; - - while(!is_pow2(n)) - n= n&(n-1); - - return n*2; -} - void draw_volume(ARegion *ar, GPUTexture *tex, float *min, float *max, int res[3], float dx, GPUTexture *tex_shadow) { RegionView3D *rv3d= ar->regiondata; @@ -187,7 +170,8 @@ float cor[3] = {1.,1.,1.}; int gl_depth = 0, gl_blend = 0; - /* draw slices of smoke is adapted from c++ code authored by: Johannes Schmid and Ingemar Rask, 2006, johnny@grob.org */ + /* draw slices of smoke is adapted from c++ code authored + * by: Johannes Schmid and Ingemar Rask, 2006, johnny@grob.org */ float cv[][3] = { {1.0f, 1.0f, 1.0f}, {-1.0f, 1.0f, 1.0f}, {-1.0f, -1.0f, 1.0f}, {1.0f, -1.0f, 1.0f}, {1.0f, 1.0f, -1.0f}, {-1.0f, 1.0f, -1.0f}, {-1.0f, -1.0f, -1.0f}, {1.0f, -1.0f, -1.0f} @@ -379,9 +363,9 @@ printf("No volume shadow\n"); if (!GPU_non_power_of_two_support()) { - cor[0] = (float)res[0]/(float)larger_pow2(res[0]); - cor[1] = (float)res[1]/(float)larger_pow2(res[1]); - cor[2] = (float)res[2]/(float)larger_pow2(res[2]); + cor[0] = (float)res[0]/(float)power_of_2_max_i(res[0]); + cor[1] = (float)res[1]/(float)power_of_2_max_i(res[1]); + cor[2] = (float)res[2]/(float)power_of_2_max_i(res[2]); } // our slices are defined by the plane equation a*x + b*y +c*z + d = 0 @@ -441,7 +425,9 @@ glBegin(GL_POLYGON); glColor3f(1.0, 1.0, 1.0); for (i = 0; i < numpoints; i++) { - glTexCoord3d((points[i * 3 + 0] - min[0] )*cor[0]/size[0], (points[i * 3 + 1] - min[1])*cor[1]/size[1], (points[i * 3 + 2] - min[2])*cor[2]/size[2]); + glTexCoord3d((points[i * 3 + 0] - min[0]) * cor[0] / size[0], + (points[i * 3 + 1] - min[1]) * cor[1] / size[1], + (points[i * 3 + 2] - min[2]) * cor[2] / size[2]); glVertex3f(points[i * 3 + 0], points[i * 3 + 1], points[i * 3 + 2]); } glEnd(); diff -Nru blender-2.61/source/blender/editors/space_view3d/space_view3d.c blender-2.62/source/blender/editors/space_view3d/space_view3d.c --- blender-2.61/source/blender/editors/space_view3d/space_view3d.c 2011-12-13 19:52:25.000000000 +0000 +++ blender-2.62/source/blender/editors/space_view3d/space_view3d.c 2012-02-15 19:36:59.000000000 +0000 @@ -154,15 +154,23 @@ /* ideally would return an rv3d but in some cases the region is needed too * so return that, the caller can then access the ar->regiondata */ -ARegion *ED_view3d_context_region_unlock(bContext *C) +int ED_view3d_context_user_region(bContext *C, View3D **v3d_r, ARegion **ar_r) { ScrArea *sa= CTX_wm_area(C); + + *v3d_r = NULL; + *ar_r = NULL; + if(sa && sa->spacetype==SPACE_VIEW3D) { ARegion *ar= CTX_wm_region(C); + View3D *v3d = (View3D *)sa->spacedata.first; + if(ar) { RegionView3D *rv3d= ar->regiondata; if(rv3d && rv3d->viewlock == 0) { - return ar; + *v3d_r = v3d; + *ar_r = ar; + return 1; } else { ARegion *ar_unlock_user= NULL; @@ -182,12 +190,22 @@ } /* camera/perspective view get priority when the active region is locked */ - if(ar_unlock_user) return ar_unlock_user; - if(ar_unlock) return ar_unlock; + if(ar_unlock_user) { + *v3d_r = v3d; + *ar_r = ar_unlock_user; + return 1; + } + + if(ar_unlock) { + *v3d_r = v3d; + *ar_r = ar_unlock; + return 1; + } } } } - return NULL; + + return 0; } /* Most of the time this isn't needed since you could assume the view matrix was @@ -204,8 +222,8 @@ void ED_view3d_init_mats_rv3d(struct Object *ob, struct RegionView3D *rv3d) { /* local viewmat and persmat, to calculate projections */ - mul_m4_m4m4(rv3d->viewmatob, ob->obmat, rv3d->viewmat); - mul_m4_m4m4(rv3d->persmatob, ob->obmat, rv3d->persmat); + mult_m4_m4m4(rv3d->viewmatob, rv3d->viewmat, ob->obmat); + mult_m4_m4m4(rv3d->persmatob, rv3d->persmat, ob->obmat); /* initializes object space clipping, speeds up clip tests */ ED_view3d_local_clipping(rv3d, ob->obmat); @@ -553,7 +571,6 @@ if(rv3d->localvd) MEM_freeN(rv3d->localvd); if(rv3d->clipbb) MEM_freeN(rv3d->clipbb); - // XXX retopo_free_view_data(rv3d); if(rv3d->ri) { // XXX BIF_view3d_previewrender_free(rv3d); } @@ -1006,7 +1023,8 @@ break; } -#if 0 // removed since BKE_image_user_calc_frame is now called in draw_bgpic because screen_ops doesnt call the notifier. + // removed since BKE_image_user_calc_frame is now called in draw_bgpic because screen_ops doesnt call the notifier. +#if 0 if (wmn->category == NC_SCENE && wmn->data == ND_FRAME) { View3D *v3d = area->spacedata.first; BGpic *bgpic = v3d->bgpicbase.first; @@ -1031,7 +1049,8 @@ View3D *v3d= CTX_wm_view3d(C); Scene *scene= CTX_data_scene(C); Base *base; - unsigned int lay = v3d ? v3d->lay:scene->lay; /* fallback to the scene layer, allows duplicate and other oject operators to run outside the 3d view */ + /* fallback to the scene layer, allows duplicate and other object operators to run outside the 3d view */ + unsigned int lay = v3d ? v3d->lay:scene->lay; if(CTX_data_dir(member)) { CTX_data_dir_set(result, view3d_context_dir); diff -Nru blender-2.61/source/blender/editors/space_view3d/view3d_buttons.c blender-2.62/source/blender/editors/space_view3d/view3d_buttons.c --- blender-2.61/source/blender/editors/space_view3d/view3d_buttons.c 2011-12-13 19:52:25.000000000 +0000 +++ blender-2.62/source/blender/editors/space_view3d/view3d_buttons.c 2012-02-15 19:36:59.000000000 +0000 @@ -59,6 +59,7 @@ #include "BKE_mesh.h" #include "BKE_screen.h" #include "BKE_deform.h" +#include "BKE_object.h" #include "WM_api.h" #include "WM_types.h" @@ -187,7 +188,7 @@ dg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr); if(dg) { max+= BLI_snprintf(str, sizeof(str), "%s %%x%d|", dg->name, dvert->dw[i].def_nr); - if(max<320) strcat(defstr, str); + if (max < sizeof(str)) strcat(defstr, str); } if(tfp->curdef==dvert->dw[i].def_nr) { @@ -688,57 +689,51 @@ } } -static void vgroup_copy_active_to_sel_single(Object *ob, int def_nr) +static void vgroup_copy_active_to_sel_single(Object *ob, const int def_nr) { EditVert *eve_act; - MDeformVert *dvert_act; + MDeformVert *dv_act; - act_vert_def(ob, &eve_act, &dvert_act); + act_vert_def(ob, &eve_act, &dv_act); - if(dvert_act==NULL) { + if(dv_act==NULL) { return; } else { Mesh *me= ob->data; EditMesh *em = BKE_mesh_get_editmesh(me); EditVert *eve; - MDeformVert *dvert; + MDeformVert *dv; MDeformWeight *dw; - float act_weight = -1.0f; - int i; + float weight_act; int index= 0; - for(i=0, dw=dvert_act->dw; i < dvert_act->totweight; i++, dw++) { - if(def_nr == dw->def_nr) { - act_weight= dw->weight; - break; - } - } + dw= defvert_find_index(dv_act, def_nr); - if(act_weight < -0.5f) + if(dw == NULL) return; - for(eve= em->verts.first; eve; eve= eve->next, index++) { - if(eve->f & SELECT && eve != eve_act) { - dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); - if(dvert) { - for(i=0, dw=dvert->dw; i < dvert->totweight; i++, dw++) { - if(def_nr == dw->def_nr) { - dw->weight= act_weight; + weight_act= dw->weight; - if(me->editflag & ME_EDIT_MIRROR_X) - editvert_mirror_update(ob, eve, -1, index); + for (eve= em->verts.first; eve; eve= eve->next, index++) { + if (eve->f & SELECT && eve != eve_act) { + dv= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); + if(dv) { + dw= defvert_find_index(dv, def_nr); + if (dw) { + dw->weight= weight_act; - break; + if (me->editflag & ME_EDIT_MIRROR_X) { + editvert_mirror_update(ob, eve, -1, index); } } } } } - if(me->editflag & ME_EDIT_MIRROR_X) + if (me->editflag & ME_EDIT_MIRROR_X) { editvert_mirror_update(ob, eve_act, -1, -1); - + } } } @@ -808,14 +803,15 @@ Object *ob= OBACT; EditVert *eve; - MDeformVert *dvert; + MDeformVert *dv; - act_vert_def(ob, &eve, &dvert); + act_vert_def(ob, &eve, &dv); - if(dvert && dvert->totweight) { + if(dv && dv->totweight) { uiLayout *col; bDeformGroup *dg; - int i; + MDeformWeight *dw = dv->dw; + unsigned int i; int yco = 0; uiBlockSetHandleFunc(block, do_view3d_vgroup_buttons, NULL); @@ -825,11 +821,11 @@ uiBlockBeginAlign(block); - for (i=0; itotweight; i++){ - dg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr); + for (i= dv->totweight; i != 0; i--, dw++) { + dg = BLI_findlink (&ob->defbase, dw->def_nr); if(dg) { - uiDefButF(block, NUM, B_VGRP_PNL_EDIT_SINGLE + dvert->dw[i].def_nr, dg->name, 0, yco, 180, 20, &dvert->dw[i].weight, 0.0, 1.0, 1, 3, ""); - uiDefBut(block, BUT, B_VGRP_PNL_COPY_SINGLE + dvert->dw[i].def_nr, "C", 180,yco,20,20, NULL, 0, 0, 0, 0, "Copy this groups weight to other selected verts"); + uiDefButF(block, NUM, B_VGRP_PNL_EDIT_SINGLE + dw->def_nr, dg->name, 0, yco, 180, 20, &dw->weight, 0.0, 1.0, 1, 3, ""); + uiDefBut(block, BUT, B_VGRP_PNL_COPY_SINGLE + dw->def_nr, "C", 180,yco,20,20, NULL, 0, 0, 0, 0, "Copy this groups weight to other selected verts"); yco -= 20; } } @@ -1110,14 +1106,6 @@ } } -/* test if 'ob' is a parent somewhere in par's parents */ -static int test_parent_loop(Object *par, Object *ob) -{ - if(par == NULL) return 0; - if(ob == par) return 1; - return test_parent_loop(par->parent, ob); -} - static void do_view3d_region_buttons(bContext *C, void *UNUSED(index), int event) { Main *bmain= CTX_data_main(C); @@ -1149,7 +1137,7 @@ /* note; this case also used for parbone */ case B_OBJECTPANELPARENT: if(ob) { - if(ob->id.lib || test_parent_loop(ob->parent, ob) ) + if (ob->id.lib || BKE_object_parent_loop_check(ob->parent, ob)) ob->parent= NULL; else { DAG_scene_sort(bmain, scene); @@ -1281,7 +1269,7 @@ } /* default for now */ - WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, ob); + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, v3d); } static void view3d_panel_object(const bContext *C, Panel *pa) @@ -1346,7 +1334,7 @@ View3D *v3d= sa->spacedata.first; int ofsx, ofsy; - block= uiBeginBlock(C, ar, "view3d_panel_preview", UI_EMBOSS); + block= uiBeginBlock(C, ar, __func__, UI_EMBOSS); uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | UI_PNL_SCALE | cntrl); uiSetPanelHandler(VIEW3D_HANDLER_PREVIEW); // for close and esc diff -Nru blender-2.61/source/blender/editors/space_view3d/view3d_draw.c blender-2.62/source/blender/editors/space_view3d/view3d_draw.c --- blender-2.61/source/blender/editors/space_view3d/view3d_draw.c 2011-12-13 19:52:25.000000000 +0000 +++ blender-2.62/source/blender/editors/space_view3d/view3d_draw.c 2012-02-15 19:36:59.000000000 +0000 @@ -471,7 +471,8 @@ /* emphasise division lines lighter instead of darker, if background is darker than grid */ UI_GetColorPtrShade3ubv(col_grid, col_grid_light, 10); UI_GetColorPtrShade3ubv(col_grid, col_grid_emphasise, - (((col_grid[0]+col_grid[1]+col_grid[2])+30) > (col_bg[0]+col_bg[1]+col_bg[2])) ? 20 : -10); + (((col_grid[0]+col_grid[1]+col_grid[2])+30) > + (col_bg[0]+col_bg[1]+col_bg[2])) ? 20 : -10); /* set fixed axis */ vert[0][0]= vert[2][1]= grid; @@ -863,24 +864,24 @@ } } if(name && markern) - sprintf(info, "(%d) %s %s <%s>", CFRA, ob->id.name+2, name, markern); + BLI_snprintf(info, sizeof(info), "(%d) %s %s <%s>", CFRA, ob->id.name+2, name, markern); else if(name) - sprintf(info, "(%d) %s %s", CFRA, ob->id.name+2, name); + BLI_snprintf(info, sizeof(info), "(%d) %s %s", CFRA, ob->id.name+2, name); else - sprintf(info, "(%d) %s", CFRA, ob->id.name+2); + BLI_snprintf(info, sizeof(info), "(%d) %s", CFRA, ob->id.name+2); } else if(ELEM3(ob->type, OB_MESH, OB_LATTICE, OB_CURVE)) { Key *key= NULL; KeyBlock *kb = NULL; - char shapes[75]; + char shapes[MAX_NAME + 10]; /* try to display active shapekey too */ - shapes[0] = 0; + shapes[0] = '\0'; key = ob_get_key(ob); if(key){ kb = BLI_findlink(&key->block, ob->shapenr-1); if(kb){ - sprintf(shapes, ": %s ", kb->name); + BLI_snprintf(shapes, sizeof(shapes), ": %s ", kb->name); if(ob->shapeflag == OB_SHAPE_LOCK){ strcat(shapes, " (Pinned)"); } @@ -888,16 +889,16 @@ } if(markern) - sprintf(info, "(%d) %s %s <%s>", CFRA, ob->id.name+2, shapes, markern); + BLI_snprintf(info, sizeof(info), "(%d) %s %s <%s>", CFRA, ob->id.name+2, shapes, markern); else - sprintf(info, "(%d) %s %s", CFRA, ob->id.name+2, shapes); + BLI_snprintf(info, sizeof(info), "(%d) %s %s", CFRA, ob->id.name+2, shapes); } else { /* standard object */ if (markern) - sprintf(info, "(%d) %s <%s>", CFRA, ob->id.name+2, markern); + BLI_snprintf(info, sizeof(info), "(%d) %s <%s>", CFRA, ob->id.name+2, markern); else - sprintf(info, "(%d) %s", CFRA, ob->id.name+2); + BLI_snprintf(info, sizeof(info), "(%d) %s", CFRA, ob->id.name+2); } /* color depends on whether there is a keyframe */ @@ -909,9 +910,9 @@ else { /* no object */ if (markern) - sprintf(info, "(%d) <%s>", CFRA, markern); + BLI_snprintf(info, sizeof(info), "(%d) <%s>", CFRA, markern); else - sprintf(info, "(%d)", CFRA); + BLI_snprintf(info, sizeof(info), "(%d)", CFRA); /* color is always white */ UI_ThemeColor(TH_TEXT_HI); @@ -920,10 +921,11 @@ if (U.uiflag & USER_SHOW_ROTVIEWICON) offset = 14 + (U.rvisize * 2); - BLF_draw_default(offset, 10, 0.0f, info, sizeof(info)-1); + BLF_draw_default(offset, 10, 0.0f, info, sizeof(info)); } -static void view3d_camera_border(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, rctf *viewborder_r, short no_shift, short no_zoom) +static void view3d_camera_border(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, + rctf *viewborder_r, short no_shift, short no_zoom) { CameraParams params; rctf rect_view, rect_camera; @@ -962,7 +964,8 @@ size_r[1]= viewborder.ymax - viewborder.ymin; } -void ED_view3d_calc_camera_border(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, rctf *viewborder_r, short no_shift) +void ED_view3d_calc_camera_border(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, + rctf *viewborder_r, short no_shift) { view3d_camera_border(scene, ar, v3d, rv3d, viewborder_r, no_shift, FALSE); } @@ -1097,7 +1100,9 @@ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); setlinestyle(0); + UI_ThemeColor(TH_BACK); + glRectf(x1i, y1i, x2i, y2i); #ifdef VIEW3D_CAMERA_BORDER_HACK @@ -1109,6 +1114,13 @@ #endif setlinestyle(3); + + /* outer line not to confuse with object selecton */ + if (v3d->flag2 & V3D_LOCK_CAMERA) { + UI_ThemeColor(TH_REDALERT); + glRectf(x1i - 1, y1i - 1, x2i + 1, y2i + 1); + } + UI_ThemeColor(TH_WIRE); glRectf(x1i, y1i, x2i, y2i); @@ -1386,7 +1398,12 @@ view3d_validate_backbuf(vc); - glReadPixels(vc->ar->winrct.xmin+xminc, vc->ar->winrct.ymin+yminc, (xmaxc-xminc+1), (ymaxc-yminc+1), GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); + glReadPixels(vc->ar->winrct.xmin + xminc, + vc->ar->winrct.ymin + yminc, + (xmaxc-xminc + 1), + (ymaxc-yminc + 1), + GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); + glReadBuffer(GL_BACK); if(ENDIAN_ORDER==B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf); @@ -1521,9 +1538,6 @@ clip= NULL; if(bgpic->flag&V3D_BGPIC_CAMERACLIP) { - if(!scene->camera) - scene->camera= scene_find_camera(scene); - if(scene->camera) clip= object_get_movieclip(scene, scene->camera, 1); } else clip= bgpic->clip; @@ -1813,11 +1827,13 @@ * offset feature (used in group-duplicate.blend but no longer works in 2.5) * so for now it should be ok to - campbell */ - if( (dob_next==NULL || dob_next->ob != dob->ob) || /* if this is the last no need to make a displist */ - (dob->ob->type == OB_LAMP) || /* lamp drawing messes with matrices, could be handled smarter... but this works */ - (dob->type == OB_DUPLIGROUP && dob->animated) || - !(bb_tmp= object_get_boundbox(dob->ob)) - ) { + if ( /* if this is the last no need to make a displist */ + (dob_next==NULL || dob_next->ob != dob->ob) || + /* lamp drawing messes with matrices, could be handled smarter... but this works */ + (dob->ob->type == OB_LAMP) || + (dob->type == OB_DUPLIGROUP && dob->animated) || + !(bb_tmp= object_get_boundbox(dob->ob))) + { // printf("draw_dupli_objects_color: skipping displist for %s\n", dob->ob->id.name+2); use_displist= 0; } @@ -1993,7 +2009,7 @@ setwinmatrixview3d(ar, v3d, NULL); /* 0= no pick rect */ setviewmatrixview3d(scene, v3d, rv3d); /* note: calls where_is_object for camera... */ - mul_m4_m4m4(rv3d->persmat, rv3d->viewmat, rv3d->winmat); + mult_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat); invert_m4_m4(rv3d->persinv, rv3d->persmat); invert_m4_m4(rv3d->viewinv, rv3d->viewmat); @@ -2028,7 +2044,7 @@ setwinmatrixview3d(ar, v3d, NULL); /* 0= no pick rect */ setviewmatrixview3d(scene, v3d, rv3d); /* note: calls where_is_object for camera... */ - mul_m4_m4m4(rv3d->persmat, rv3d->viewmat, rv3d->winmat); + mult_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat); invert_m4_m4(rv3d->persinv, rv3d->persmat); invert_m4_m4(rv3d->viewinv, rv3d->viewmat); @@ -2145,7 +2161,8 @@ GPULamp *lamp; } View3DShadow; -static void gpu_render_lamp_update(Scene *scene, View3D *v3d, Object *ob, Object *par, float obmat[][4], ListBase *shadows) +static void gpu_render_lamp_update(Scene *scene, View3D *v3d, Object *ob, Object *par, + float obmat[][4], ListBase *shadows) { GPULamp *lamp; Lamp *la = (Lamp*)ob->data; @@ -2219,7 +2236,7 @@ copy_m4_m4(rv3d.winmat, winmat); copy_m4_m4(rv3d.viewmat, viewmat); invert_m4_m4(rv3d.viewinv, rv3d.viewmat); - mul_m4_m4m4(rv3d.persmat, rv3d.viewmat, rv3d.winmat); + mult_m4_m4m4(rv3d.persmat, rv3d.winmat, rv3d.viewmat); invert_m4_m4(rv3d.persinv, rv3d.viewinv); ED_view3d_draw_offscreen(scene, v3d, &ar, winsize, winsize, viewmat, winmat); @@ -2239,7 +2256,9 @@ { CustomDataMask mask= 0; - if(ELEM(v3d->drawtype, OB_TEXTURE, OB_MATERIAL) || ((v3d->drawtype == OB_SOLID) && (v3d->flag2 & V3D_SOLID_TEX))) { + if ( ELEM(v3d->drawtype, OB_TEXTURE, OB_MATERIAL) || + ((v3d->drawtype == OB_SOLID) && (v3d->flag2 & V3D_SOLID_TEX))) + { mask |= CD_MASK_MTFACE | CD_MASK_MCOL; if(scene_use_new_shading_nodes(scene)) { @@ -2254,32 +2273,46 @@ return mask; } + +CustomDataMask ED_view3d_object_datamask(Scene *scene) +{ + Object *ob= scene->basact ? scene->basact->object : NULL; + CustomDataMask mask= 0; + + if (ob) { + /* check if we need tfaces & mcols due to face select or texture paint */ + if (paint_facesel_test(ob) || (ob->mode & OB_MODE_TEXTURE_PAINT)) { + mask |= CD_MASK_MTFACE | CD_MASK_MCOL; + } + + /* check if we need mcols due to vertex paint or weightpaint */ + if (ob->mode & OB_MODE_VERTEX_PAINT) { + mask |= CD_MASK_MCOL; + } + + if (ob->mode & OB_MODE_WEIGHT_PAINT) { + mask |= CD_MASK_WEIGHT_MCOL; + } + } + + return mask; +} + /* goes over all modes and view3d settings */ -CustomDataMask ED_viewedit_datamask(bScreen *screen) +CustomDataMask ED_view3d_screen_datamask(bScreen *screen) { Scene *scene= screen->scene; - Object *ob= scene->basact ? scene->basact->object : NULL; CustomDataMask mask = CD_MASK_BAREMESH; ScrArea *sa; - /* check if we need tfaces & mcols due to face select or texture paint */ - if(paint_facesel_test(ob) || (ob && ob->mode & OB_MODE_TEXTURE_PAINT)) - mask |= CD_MASK_MTFACE | CD_MASK_MCOL; - /* check if we need tfaces & mcols due to view mode */ for(sa = screen->areabase.first; sa; sa = sa->next) { if(sa->spacetype == SPACE_VIEW3D) { mask |= ED_view3d_datamask(scene, (View3D *)sa->spacedata.first); } } - - /* check if we need mcols due to vertex paint or weightpaint */ - if(ob) { - if(ob->mode & OB_MODE_VERTEX_PAINT) - mask |= CD_MASK_MCOL; - if(ob->mode & OB_MODE_WEIGHT_PAINT) - mask |= CD_MASK_WEIGHT_MCOL; - } + + mask |= ED_view3d_object_datamask(scene); return mask; } @@ -2301,7 +2334,7 @@ setviewmatrixview3d(scene, v3d, rv3d); /* note: calls where_is_object for camera... */ /* update utilitity matrices */ - mul_m4_m4m4(rv3d->persmat, rv3d->viewmat, rv3d->winmat); + mult_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat); invert_m4_m4(rv3d->persinv, rv3d->persmat); invert_m4_m4(rv3d->viewinv, rv3d->viewmat); @@ -2333,7 +2366,8 @@ glLoadMatrixf(rv3d->viewmat); } -void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx, int winy, float viewmat[][4], float winmat[][4]) +void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, + int winx, int winy, float viewmat[][4], float winmat[][4]) { RegionView3D *rv3d= ar->regiondata; Base *base; @@ -2458,13 +2492,15 @@ glPopMatrix(); - glColor4ub(255, 255, 255, 255); // XXX, without this the sequencer flickers with opengl draw enabled, need to find out why - campbell + // XXX, without this the sequencer flickers with opengl draw enabled, need to find out why - campbell + glColor4ub(255, 255, 255, 255); G.f &= ~G_RENDER_OGL; } /* utility func for ED_view3d_draw_offscreen */ -ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, int sizex, int sizey, unsigned int flag, char err_out[256]) +ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, + int sizex, int sizey, unsigned int flag, char err_out[256]) { RegionView3D *rv3d= ar->regiondata; ImBuf *ibuf; @@ -2519,7 +2555,8 @@ } /* creates own 3d views, used by the sequencer */ -ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int width, int height, unsigned int flag, int drawtype, char err_out[256]) +ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int width, int height, + unsigned int flag, int drawtype, char err_out[256]) { View3D v3d= {NULL}; ARegion ar= {NULL}; @@ -2555,7 +2592,7 @@ v3d.lens= params.lens; } - mul_m4_m4m4(rv3d.persmat, rv3d.viewmat, rv3d.winmat); + mult_m4_m4m4(rv3d.persmat, rv3d.winmat, rv3d.viewmat); invert_m4_m4(rv3d.persinv, rv3d.viewinv); return ED_view3d_draw_offscreen_imbuf(scene, &v3d, &ar, width, height, flag, err_out); @@ -2612,7 +2649,7 @@ BLI_snprintf(printable, sizeof(printable), "fps: %i", (int)(fps+0.5f)); } - BLF_draw_default_ascii(22, ar->winy-17, 0.0f, printable, sizeof(printable)-1); + BLF_draw_default_ascii(22, ar->winy-17, 0.0f, printable, sizeof(printable)); } static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar) @@ -2878,15 +2915,17 @@ else if(U.uiflag & USER_SHOW_VIEWPORTNAME) { draw_viewport_name(ar, v3d); } + if (grid_unit) { /* draw below the viewport name */ - char tstr[32]= ""; + char numstr[32]= ""; UI_ThemeColor(TH_TEXT_HI); if(v3d->grid != 1.0f) { - BLI_snprintf(tstr, sizeof(tstr), "%s x %.4g", grid_unit, v3d->grid); + BLI_snprintf(numstr, sizeof(numstr), "%s x %.4g", grid_unit, v3d->grid); } - BLF_draw_default_ascii(22, ar->winy-(USER_SHOW_VIEWPORTNAME?40:20), 0.0f, tstr[0]?tstr : grid_unit, sizeof(tstr)); /* XXX, use real length */ + BLF_draw_default_ascii(22, ar->winy-(USER_SHOW_VIEWPORTNAME?40:20), 0.0f, + numstr[0] ? numstr : grid_unit, sizeof(numstr)); } } diff -Nru blender-2.61/source/blender/editors/space_view3d/view3d_edit.c blender-2.62/source/blender/editors/space_view3d/view3d_edit.c --- blender-2.61/source/blender/editors/space_view3d/view3d_edit.c 2011-12-13 19:52:25.000000000 +0000 +++ blender-2.62/source/blender/editors/space_view3d/view3d_edit.c 2012-02-15 19:36:59.000000000 +0000 @@ -116,9 +116,9 @@ ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist); invert_m4_m4(v3d->camera->imat, v3d->camera->obmat); - mul_m4_m4m4(diff_mat, v3d->camera->imat, view_mat); + mult_m4_m4m4(diff_mat, view_mat, v3d->camera->imat); - mul_m4_m4m4(parent_mat, root_parent->obmat, diff_mat); + mult_m4_m4m4(parent_mat, diff_mat, root_parent->obmat); object_tfm_protected_backup(root_parent, &obtfm); object_apply_mat4(root_parent, parent_mat, TRUE, FALSE); @@ -208,10 +208,9 @@ normal_tri_v3( clip[5],bb->vec[0], bb->vec[2], bb->vec[1]); /* then plane equations */ - for(val=0; val<5; val++) { - clip[val][3]= - clip[val][0]*bb->vec[val][0] - clip[val][1]*bb->vec[val][1] - clip[val][2]*bb->vec[val][2]; + for(val=0; val<6; val++) { + clip[val][3] = -dot_v3v3(clip[val], bb->vec[val % 5]); } - clip[5][3]= - clip[5][0]*bb->vec[0][0] - clip[5][1]*bb->vec[0][1] - clip[5][2]*bb->vec[0][2]; /* create bounding box */ for(ar= sa->regionbase.first; ar; ar= ar->next) { @@ -519,52 +518,54 @@ static const float thres = 0.93f; //cos(20 deg); -#define COS45 0.70710678118654746 +#define COS45 0.7071068 #define SIN45 COS45 -static float snapquats[39][5] = { +#define NUM_SNAP_QUATS 39 + +static const float snapquats[NUM_SNAP_QUATS][5] = { /*{q0, q1, q3, q4, view}*/ - {COS45, -SIN45, 0.0, 0.0, RV3D_VIEW_FRONT}, //front - {0.0, 0.0, -SIN45, -SIN45, RV3D_VIEW_BACK}, //back - {1.0, 0.0, 0.0, 0.0, RV3D_VIEW_TOP}, //top - {0.0, -1.0, 0.0, 0.0, RV3D_VIEW_BOTTOM}, //bottom - {0.5, -0.5, -0.5, -0.5, RV3D_VIEW_RIGHT}, //left - {0.5, -0.5, 0.5, 0.5, RV3D_VIEW_LEFT}, //right + {COS45, -SIN45, 0.0, 0.0, RV3D_VIEW_FRONT}, + {0.0, 0.0, -SIN45, -SIN45, RV3D_VIEW_BACK}, + {1.0, 0.0, 0.0, 0.0, RV3D_VIEW_TOP}, + {0.0, -1.0, 0.0, 0.0, RV3D_VIEW_BOTTOM}, + {0.5, -0.5, -0.5, -0.5, RV3D_VIEW_RIGHT}, + {0.5, -0.5, 0.5, 0.5, RV3D_VIEW_LEFT}, /* some more 45 deg snaps */ - {0.65328145027160645, -0.65328145027160645, 0.27059805393218994, 0.27059805393218994, 0}, - {0.92387950420379639, 0.0, 0.0, 0.38268342614173889, 0}, - {0.0, -0.92387950420379639, 0.38268342614173889, 0.0, 0}, - {0.35355335474014282, -0.85355335474014282, 0.35355338454246521, 0.14644660055637360, 0}, - {0.85355335474014282, -0.35355335474014282, 0.14644660055637360, 0.35355338454246521, 0}, - {0.49999994039535522, -0.49999994039535522, 0.49999997019767761, 0.49999997019767761, 0}, - {0.27059802412986755, -0.65328145027160645, 0.65328145027160645, 0.27059802412986755, 0}, - {0.65328145027160645, -0.27059802412986755, 0.27059802412986755, 0.65328145027160645, 0}, - {0.27059799432754517, -0.27059799432754517, 0.65328139066696167, 0.65328139066696167, 0}, - {0.38268336653709412, 0.0, 0.0, 0.92387944459915161, 0}, - {0.0, -0.38268336653709412, 0.92387944459915161, 0.0, 0}, - {0.14644658565521240, -0.35355335474014282, 0.85355335474014282, 0.35355335474014282, 0}, - {0.35355335474014282, -0.14644658565521240, 0.35355335474014282, 0.85355335474014282, 0}, - {0.0, 0.0, 0.92387944459915161, 0.38268336653709412, 0}, - {-0.0, 0.0, 0.38268336653709412, 0.92387944459915161, 0}, - {-0.27059802412986755, 0.27059802412986755, 0.65328133106231689, 0.65328133106231689, 0}, - {-0.38268339633941650, 0.0, 0.0, 0.92387938499450684, 0}, - {0.0, 0.38268339633941650, 0.92387938499450684, 0.0, 0}, - {-0.14644658565521240, 0.35355338454246521, 0.85355329513549805, 0.35355332493782043, 0}, - {-0.35355338454246521, 0.14644658565521240, 0.35355332493782043, 0.85355329513549805, 0}, - {-0.49999991059303284, 0.49999991059303284, 0.49999985098838806, 0.49999985098838806, 0}, - {-0.27059799432754517, 0.65328145027160645, 0.65328139066696167, 0.27059799432754517, 0}, - {-0.65328145027160645, 0.27059799432754517, 0.27059799432754517, 0.65328139066696167, 0}, - {-0.65328133106231689, 0.65328133106231689, 0.27059793472290039, 0.27059793472290039, 0}, - {-0.92387932538986206, 0.0, 0.0, 0.38268333673477173, 0}, - {0.0, 0.92387932538986206, 0.38268333673477173, 0.0, 0}, - {-0.35355329513549805, 0.85355329513549805, 0.35355329513549805, 0.14644657075405121, 0}, - {-0.85355329513549805, 0.35355329513549805, 0.14644657075405121, 0.35355329513549805, 0}, - {-0.38268330693244934, 0.92387938499450684, 0.0, 0.0, 0}, - {-0.92387938499450684, 0.38268330693244934, 0.0, 0.0, 0}, - {-COS45, 0.0, 0.0, SIN45, 0}, - {COS45, 0.0, 0.0, SIN45, 0}, - {0.0, 0.0, 0.0, 1.0, 0} + { 0.6532815, -0.6532815, 0.2705981, 0.2705981, 0}, + { 0.9238795, 0.0, 0.0, 0.3826834, 0}, + { 0.0, -0.9238795, 0.3826834, 0.0, 0}, + { 0.3535534, -0.8535534, 0.3535534, 0.1464466, 0}, + { 0.8535534, -0.3535534, 0.1464466, 0.3535534, 0}, + { 0.4999999, -0.4999999, 0.5, 0.5, 0}, + { 0.2705980, -0.6532815, 0.6532815, 0.2705980, 0}, + { 0.6532815, -0.2705980, 0.2705980, 0.6532815, 0}, + { 0.2705978, -0.2705980, 0.6532814, 0.6532814, 0}, + { 0.3826834, 0.0, 0.0, 0.9238794, 0}, + { 0.0, -0.3826834, 0.9238794, 0.0, 0}, + { 0.1464466, -0.3535534, 0.8535534, 0.3535534, 0}, + { 0.3535534, -0.1464466, 0.3535534, 0.8535534, 0}, + { 0.0, 0.0, 0.9238794, 0.3826834, 0}, + {-0.0, 0.0, 0.3826834, 0.9238794, 0}, + {-0.2705980, 0.2705980, 0.6532813, 0.6532813, 0}, + {-0.3826834, 0.0, 0.0, 0.9238794, 0}, + { 0.0, 0.3826834, 0.9238794, 0.0, 0}, + {-0.1464466, 0.3535534, 0.8535533, 0.3535533, 0}, + {-0.3535534, 0.1464466, 0.3535533, 0.8535533, 0}, + {-0.4999999, 0.4999999, 0.4999999, 0.4999999, 0}, + {-0.2705980, 0.6532815, 0.6532814, 0.2705980, 0}, + {-0.6532815, 0.2705980, 0.2705980, 0.6532814, 0}, + {-0.6532813, 0.6532813, 0.2705979, 0.2705979, 0}, + {-0.9238793, 0.0, 0.0, 0.3826833, 0}, + { 0.0, 0.9238793, 0.3826833, 0.0, 0}, + {-0.3535533, 0.8535533, 0.3535533, 0.1464466, 0}, + {-0.8535533, 0.3535533, 0.1464466, 0.3535533, 0}, + {-0.3826833, 0.9238794, 0.0, 0.0, 0}, + {-0.9238794, 0.3826833, 0.0, 0.0, 0}, + {-COS45, 0.0, 0.0, SIN45, 0}, + { COS45, 0.0, 0.0, SIN45, 0}, + { 0.0, 0.0, 0.0, 1.0, 0} }; enum { @@ -633,7 +634,7 @@ sub_v3_v3v3(dvec, newvec, vod->trackvec); - si= sqrt(dvec[0]*dvec[0]+ dvec[1]*dvec[1]+ dvec[2]*dvec[2]); + si = len_v3(dvec); si /= (float)(2.0 * TRACKBALLSIZE); cross_v3_v3v3(q1+1, vod->trackvec, newvec); @@ -725,7 +726,7 @@ mul_qt_v3(viewquat_inv, zaxis); - for (i = 0 ; i < 39; i++){ + for (i = 0 ; i < NUM_SNAP_QUATS; i++){ float view = (int)snapquats[i][4]; float viewquat_inv_test[4]; @@ -921,6 +922,22 @@ return 0; } +/* test for unlocked camera view in quad view */ +static int view3d_camera_user_poll(bContext *C) +{ + View3D *v3d; + ARegion *ar; + + if (ED_view3d_context_user_region(C, &v3d, &ar)) { + RegionView3D *rv3d = ar->regiondata; + if(rv3d->persp==RV3D_CAMOB) { + return 1; + } + } + + return 0; +} + static int viewrotate_cancel(bContext *C, wmOperator *op) { viewops_data_free(C, op); @@ -946,8 +963,9 @@ ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER; } -// NDOF utility functions -// (should these functions live in this file?) +/* NDOF utility functions + * (should these functions live in this file?) + */ float ndof_to_axis_angle(struct wmNDOFMotionData* ndof, float axis[3]) { return ndof->dt * normalize_v3_v3(axis, ndof->rvec); @@ -958,7 +976,7 @@ float axis[3]; float angle; - angle= ndof_to_axis_angle(ndof, axis); + angle = ndof_to_axis_angle(ndof, axis); axis_angle_to_quat(q, axis, angle); } @@ -968,69 +986,67 @@ */ static int ndof_orbit_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event) { - if (event->type != NDOF_MOTION) { + if (event->type != NDOF_MOTION) return OPERATOR_CANCELLED; - } else { - View3D *v3d= CTX_wm_view3d(C); + View3D *v3d = CTX_wm_view3d(C); RegionView3D* rv3d = CTX_wm_region_view3d(C); wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata; ED_view3d_camera_lock_init(v3d, rv3d); - rv3d->rot_angle = 0.f; // off by default, until changed later this function + rv3d->rot_angle = 0.f; /* off by default, until changed later this function */ if (ndof->progress != P_FINISHING) { const float dt = ndof->dt; - - // tune these until everything feels right + + /* tune these until everything feels right */ const float rot_sensitivity = 1.f; const float zoom_sensitivity = 1.f; const float pan_sensitivity = 1.f; - - // rather have bool, but... - int has_rotation = rv3d->viewlock != RV3D_LOCKED && !is_zero_v3(ndof->rvec); - + + const int has_rotation = rv3d->viewlock != RV3D_LOCKED && !is_zero_v3(ndof->rvec); + float view_inv[4]; invert_qt_qt(view_inv, rv3d->viewquat); - - //#define DEBUG_NDOF_MOTION + + /* #define DEBUG_NDOF_MOTION */ #ifdef DEBUG_NDOF_MOTION printf("ndof: T=(%.2f,%.2f,%.2f) R=(%.2f,%.2f,%.2f) dt=%.3f delivered to 3D view\n", ndof->tx, ndof->ty, ndof->tz, ndof->rx, ndof->ry, ndof->rz, ndof->dt); #endif - - if (ndof->tvec[2]) { - // Zoom! - // velocity should be proportional to the linear velocity attained by rotational motion of same strength - // [got that?] - // proportional to arclength = radius * angle - - float zoom_distance = zoom_sensitivity * rv3d->dist * dt * ndof->tvec[2]; + + if (ndof->tz) { + /* Zoom! + * velocity should be proportional to the linear velocity attained by rotational motion of same strength + * [got that?] + * proportional to arclength = radius * angle + */ + float zoom_distance = zoom_sensitivity * rv3d->dist * dt * ndof->tz; if (U.ndof_flag & NDOF_ZOOM_INVERT) zoom_distance = -zoom_distance; rv3d->dist += zoom_distance; } - + if (rv3d->viewlock == RV3D_LOCKED) { /* rotation not allowed -- explore panning options instead */ - float pan_vec[3] = {ndof->tvec[0], ndof->tvec[1], 0.0f}; + float pan_vec[3] = {ndof->tx, ndof->ty, 0.0f}; mul_v3_fl(pan_vec, pan_sensitivity * rv3d->dist * dt); - + /* transform motion from view to world coordinates */ invert_qt_qt(view_inv, rv3d->viewquat); mul_qt_v3(view_inv, pan_vec); - + /* move center of view opposite of hand motion (this is camera mode, not object mode) */ sub_v3_v3(rv3d->ofs, pan_vec); } - + if (has_rotation) { - + rv3d->view = RV3D_VIEW_USER; - + if (U.flag & USER_TRACKBALL) { float rot[4]; float axis[3]; @@ -1045,44 +1061,46 @@ if (U.ndof_flag & NDOF_ROTATE_INVERT_AXIS) axis[1] = -axis[1]; - // transform rotation axis from view to world coordinates + /* transform rotation axis from view to world coordinates */ mul_qt_v3(view_inv, axis); - - // update the onscreen doo-dad + + /* update the onscreen doo-dad */ rv3d->rot_angle = angle; copy_v3_v3(rv3d->rot_axis, axis); - + axis_angle_to_quat(rot, axis, angle); - // apply rotation + /* apply rotation */ mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot); + } else { + /* turntable view code by John Aughey, adapted for 3D mouse by [mce] */ float angle, rot[4]; float xvec[3] = {1,0,0}; - + /* Determine the direction of the x vector (for rotating up and down) */ mul_qt_v3(view_inv, xvec); - + /* Perform the up/down rotation */ - angle = rot_sensitivity * dt * ndof->rvec[0]; + angle = rot_sensitivity * dt * ndof->rx; if (U.ndof_flag & NDOF_TILT_INVERT_AXIS) angle = -angle; rot[0] = cos(angle); mul_v3_v3fl(rot+1, xvec, sin(angle)); mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot); - + /* Perform the orbital rotation */ - angle = rot_sensitivity * dt * ndof->rvec[1]; + angle = rot_sensitivity * dt * ndof->ry; if (U.ndof_flag & NDOF_ROTATE_INVERT_AXIS) angle = -angle; - - // update the onscreen doo-dad + + /* update the onscreen doo-dad */ rv3d->rot_angle = angle; rv3d->rot_axis[0] = 0; rv3d->rot_axis[1] = 0; rv3d->rot_axis[2] = 1; - + rot[0] = cos(angle); rot[1] = rot[2] = 0.0; rot[3] = sin(angle); @@ -1119,9 +1137,8 @@ */ static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event) { - if (event->type != NDOF_MOTION) { + if (event->type != NDOF_MOTION) return OPERATOR_CANCELLED; - } else { View3D *v3d= CTX_wm_view3d(C); RegionView3D* rv3d = CTX_wm_region_view3d(C); @@ -1129,13 +1146,13 @@ ED_view3d_camera_lock_init(v3d, rv3d); - rv3d->rot_angle = 0.f; // we're panning here! so erase any leftover rotation from other operators + rv3d->rot_angle = 0.f; /* we're panning here! so erase any leftover rotation from other operators */ if (ndof->progress != P_FINISHING) { const float dt = ndof->dt; float view_inv[4]; -#if 0 // ------------------------------------------- zoom with Z - // tune these until everything feels right +#if 0 /* ------------------------------------------- zoom with Z */ + /* tune these until everything feels right */ const float zoom_sensitivity = 1.f; const float pan_sensitivity = 1.f; @@ -1143,18 +1160,18 @@ ndof->tx, ndof->ty, 0 }; - // "zoom in" or "translate"? depends on zoom mode in user settings? + /* "zoom in" or "translate"? depends on zoom mode in user settings? */ if (ndof->tz) { float zoom_distance = zoom_sensitivity * rv3d->dist * dt * ndof->tz; rv3d->dist += zoom_distance; } - + mul_v3_fl(pan_vec, pan_sensitivity * rv3d->dist * dt); -#else // ------------------------------------------------------- dolly with Z - float speed = 10.f; // blender units per second - // ^^ this is ok for default cube scene, but should scale with.. something +#else /* ------------------------------------------------------- dolly with Z */ + float speed = 10.f; /* blender units per second */ + /* ^^ this is ok for default cube scene, but should scale with.. something */ - // tune these until everything feels right + /* tune these until everything feels right */ const float forward_sensitivity = 1.f; const float vertical_sensitivity = 0.4f; const float lateral_sensitivity = 0.6f; @@ -1585,8 +1602,8 @@ v3d= sa->spacedata.first; rv3d= ar->regiondata; - mx= RNA_property_is_set(op->ptr, "mx") ? RNA_int_get(op->ptr, "mx") : ar->winx / 2; - my= RNA_property_is_set(op->ptr, "my") ? RNA_int_get(op->ptr, "my") : ar->winy / 2; + mx= RNA_struct_property_is_set(op->ptr, "mx") ? RNA_int_get(op->ptr, "mx") : ar->winx / 2; + my= RNA_struct_property_is_set(op->ptr, "my") ? RNA_int_get(op->ptr, "my") : ar->winy / 2; use_cam_zoom= (rv3d->persp==RV3D_CAMOB) && !(rv3d->is_persp && ED_view3d_camera_lock_check(v3d, rv3d)); @@ -1667,12 +1684,12 @@ vod= op->customdata; /* if one or the other zoom position aren't set, set from event */ - if (!RNA_property_is_set(op->ptr, "mx") || !RNA_property_is_set(op->ptr, "my")) { + if (!RNA_struct_property_is_set(op->ptr, "mx") || !RNA_struct_property_is_set(op->ptr, "my")) { RNA_int_set(op->ptr, "mx", event->x); RNA_int_set(op->ptr, "my", event->y); } - if(RNA_property_is_set(op->ptr, "delta")) { + if(RNA_struct_property_is_set(op->ptr, "delta")) { viewzoom_exec(C, op); } else { @@ -1880,12 +1897,12 @@ vod= op->customdata; /* if one or the other zoom position aren't set, set from event */ - if (!RNA_property_is_set(op->ptr, "mx") || !RNA_property_is_set(op->ptr, "my")) { + if (!RNA_struct_property_is_set(op->ptr, "mx") || !RNA_struct_property_is_set(op->ptr, "my")) { RNA_int_set(op->ptr, "mx", event->x); RNA_int_set(op->ptr, "my", event->y); } - if(RNA_property_is_set(op->ptr, "delta")) { + if(RNA_struct_property_is_set(op->ptr, "delta")) { viewdolly_exec(C, op); } else { @@ -2075,8 +2092,8 @@ RNA_def_boolean(ot->srna, "center", 0, "Center", ""); } - -static int viewselected_exec(bContext *C, wmOperator *UNUSED(op)) /* like a localview without local!, was centerview() in 2.4x */ +/* like a localview without local!, was centerview() in 2.4x */ +static int viewselected_exec(bContext *C, wmOperator *UNUSED(op)) { ARegion *ar= CTX_wm_region(C); View3D *v3d = CTX_wm_view3d(C); @@ -2257,13 +2274,18 @@ static int view3d_center_camera_exec(bContext *C, wmOperator *UNUSED(op)) /* was view3d_home() in 2.4x */ { - ARegion *ar= CTX_wm_region(C); - RegionView3D *rv3d= CTX_wm_region_view3d(C); - View3D *v3d= CTX_wm_view3d(C); Scene *scene= CTX_data_scene(C); float xfac, yfac; float size[2]; + View3D *v3d; + ARegion *ar; + RegionView3D *rv3d; + + /* no NULL check is needed, poll checks */ + ED_view3d_context_user_region(C, &v3d, &ar); + rv3d = ar->regiondata; + rv3d->camdx= rv3d->camdy= 0.0f; ED_view3d_calc_camera_border_size(scene, ar, v3d, rv3d, size); @@ -2289,7 +2311,7 @@ /* api callbacks */ ot->exec= view3d_center_camera_exec; - ot->poll= view3d_camera_active_poll; + ot->poll= view3d_camera_user_poll; /* flags */ ot->flag= 0; @@ -2430,9 +2452,15 @@ return OPERATOR_CANCELLED; } /* convert border to 3d coordinates */ - if (( !gluUnProject(cent[0], cent[1], depth_close, mats.modelview, mats.projection, (GLint *)mats.viewport, &p[0], &p[1], &p[2])) || - ( !gluUnProject((double)rect.xmin, (double)rect.ymin, depth_close, mats.modelview, mats.projection, (GLint *)mats.viewport, &p_corner[0], &p_corner[1], &p_corner[2]))) + if ( (!gluUnProject(cent[0], cent[1], depth_close, + mats.modelview, mats.projection, (GLint *)mats.viewport, + &p[0], &p[1], &p[2])) || + (!gluUnProject((double)rect.xmin, (double)rect.ymin, depth_close, + mats.modelview, mats.projection, (GLint *)mats.viewport, + &p_corner[0], &p_corner[1], &p_corner[2]))) + { return OPERATOR_CANCELLED; + } dvec[0] = p[0]-p_corner[0]; dvec[1] = p[1]-p_corner[1]; @@ -2453,7 +2481,10 @@ new_dist = rv3d->dist; /* convert the drawn rectangle into 3d space */ - if (depth_close!=FLT_MAX && gluUnProject(cent[0], cent[1], depth_close, mats.modelview, mats.projection, (GLint *)mats.viewport, &p[0], &p[1], &p[2])) { + if (depth_close != FLT_MAX && gluUnProject(cent[0], cent[1], depth_close, + mats.modelview, mats.projection, (GLint *)mats.viewport, + &p[0], &p[1], &p[2])) + { new_ofs[0] = -p[0]; new_ofs[1] = -p[1]; new_ofs[2] = -p[2]; @@ -2543,11 +2574,16 @@ static int view3d_zoom_1_to_1_camera_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene= CTX_data_scene(C); - ARegion *ar= CTX_wm_region(C); - view3d_set_1_to_1_viewborder(scene, ar, CTX_wm_view3d(C)); + View3D *v3d; + ARegion *ar; + + /* no NULL check is needed, poll checks */ + ED_view3d_context_user_region(C, &v3d, &ar); - WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, CTX_wm_view3d(C)); + view3d_set_1_to_1_viewborder(scene, ar, v3d); + + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, v3d); return OPERATOR_FINISHED; } @@ -2561,7 +2597,7 @@ /* api callbacks */ ot->exec= view3d_zoom_1_to_1_camera_exec; - ot->poll= view3d_camera_active_poll; + ot->poll= view3d_camera_user_poll; /* flags */ ot->flag= 0; @@ -2582,7 +2618,9 @@ /* would like to make this a generic function - outside of transform */ -static void axis_set_view(bContext *C, View3D *v3d, ARegion *ar, float q1, float q2, float q3, float q4, short view, int perspo, int align_active) +static void axis_set_view(bContext *C, View3D *v3d, ARegion *ar, + float q1, float q2, float q3, float q4, + short view, int perspo, int align_active) { RegionView3D *rv3d= ar->regiondata; /* no NULL check is needed, poll checks */ float new_quat[4]; @@ -2653,13 +2691,17 @@ static int viewnumpad_exec(bContext *C, wmOperator *op) { - View3D *v3d = CTX_wm_view3d(C); - ARegion *ar= ED_view3d_context_region_unlock(C); - RegionView3D *rv3d= ar->regiondata; /* no NULL check is needed, poll checks */ + View3D *v3d; + ARegion *ar; + RegionView3D *rv3d; Scene *scene= CTX_data_scene(C); - static int perspo=RV3D_PERSP; + static int perspo = RV3D_PERSP; int viewnum, align_active, nextperspo; + /* no NULL check is needed, poll checks */ + ED_view3d_context_user_region(C, &v3d, &ar); + rv3d = ar->regiondata; + viewnum = RNA_enum_get(op->ptr, "type"); align_active = RNA_boolean_get(op->ptr, "align_active"); @@ -2677,27 +2719,33 @@ switch (viewnum) { case RV3D_VIEW_BOTTOM : - axis_set_view(C, v3d, ar, 0.0, -1.0, 0.0, 0.0, viewnum, nextperspo, align_active); + axis_set_view(C, v3d, ar, 0.0, -1.0, 0.0, 0.0, + viewnum, nextperspo, align_active); break; case RV3D_VIEW_BACK: - axis_set_view(C, v3d, ar, 0.0, 0.0, (float)-cos(M_PI/4.0), (float)-cos(M_PI/4.0), viewnum, nextperspo, align_active); + axis_set_view(C, v3d, ar, 0.0, 0.0, (float)-cos(M_PI/4.0), (float)-cos(M_PI/4.0), + viewnum, nextperspo, align_active); break; case RV3D_VIEW_LEFT: - axis_set_view(C, v3d, ar, 0.5, -0.5, 0.5, 0.5, viewnum, nextperspo, align_active); + axis_set_view(C, v3d, ar, 0.5, -0.5, 0.5, 0.5, + viewnum, nextperspo, align_active); break; case RV3D_VIEW_TOP: - axis_set_view(C, v3d, ar, 1.0, 0.0, 0.0, 0.0, viewnum, nextperspo, align_active); + axis_set_view(C, v3d, ar, 1.0, 0.0, 0.0, 0.0, + viewnum, nextperspo, align_active); break; case RV3D_VIEW_FRONT: - axis_set_view(C, v3d, ar, (float)cos(M_PI/4.0), (float)-sin(M_PI/4.0), 0.0, 0.0, viewnum, nextperspo, align_active); + axis_set_view(C, v3d, ar, (float)cos(M_PI/4.0), (float)-sin(M_PI/4.0), 0.0, 0.0, + viewnum, nextperspo, align_active); break; case RV3D_VIEW_RIGHT: - axis_set_view(C, v3d, ar, 0.5, -0.5, -0.5, -0.5, viewnum, nextperspo, align_active); + axis_set_view(C, v3d, ar, 0.5, -0.5, -0.5, -0.5, + viewnum, nextperspo, align_active); break; case RV3D_VIEW_CAMERA: @@ -2759,7 +2807,9 @@ else{ /* return to settings of last view */ /* does smooth_view too */ - axis_set_view(C, v3d, ar, rv3d->lviewquat[0], rv3d->lviewquat[1], rv3d->lviewquat[2], rv3d->lviewquat[3], rv3d->lview, rv3d->lpersp, 0); + axis_set_view(C, v3d, ar, + rv3d->lviewquat[0], rv3d->lviewquat[1], rv3d->lviewquat[2], rv3d->lviewquat[3], + rv3d->lview, rv3d->lpersp, 0); } } break; @@ -2783,7 +2833,7 @@ /* api callbacks */ ot->exec= viewnumpad_exec; - ot->poll= ED_operator_rv3d_unlock_poll; + ot->poll= ED_operator_rv3d_user_region_poll; /* flags */ ot->flag= 0; @@ -2801,12 +2851,16 @@ static int vieworbit_exec(bContext *C, wmOperator *op) { - View3D *v3d= CTX_wm_view3d(C); - ARegion *ar= ED_view3d_context_region_unlock(C); - RegionView3D *rv3d= ar->regiondata; /* no NULL check is needed, poll checks */ + View3D *v3d; + ARegion *ar; + RegionView3D *rv3d; float phi, q1[4], new_quat[4]; int orbitdir; + /* no NULL check is needed, poll checks */ + ED_view3d_context_user_region(C, &v3d, &ar); + rv3d = ar->regiondata; + orbitdir = RNA_enum_get(op->ptr, "type"); if(rv3d->viewlock==0) { @@ -2852,7 +2906,7 @@ /* api callbacks */ ot->exec= vieworbit_exec; - ot->poll= ED_operator_rv3d_unlock_poll; + ot->poll= ED_operator_rv3d_user_region_poll; /* flags */ ot->flag= 0; @@ -2909,8 +2963,13 @@ static int viewpersportho_exec(bContext *C, wmOperator *UNUSED(op)) { - ARegion *ar= ED_view3d_context_region_unlock(C); - RegionView3D *rv3d= ar->regiondata; /* no NULL check is needed, poll checks */ + View3D *v3d_dummy; + ARegion *ar; + RegionView3D *rv3d; + + /* no NULL check is needed, poll checks */ + ED_view3d_context_user_region(C, &v3d_dummy, &ar); + rv3d = ar->regiondata; if(rv3d->viewlock==0) { if(rv3d->persp!=RV3D_ORTHO) @@ -2932,7 +2991,7 @@ /* api callbacks */ ot->exec= viewpersportho_exec; - ot->poll= ED_operator_rv3d_unlock_poll; + ot->poll= ED_operator_rv3d_user_region_poll; /* flags */ ot->flag= 0; @@ -2960,16 +3019,16 @@ View3D *v3d= CTX_wm_view3d(C); Image *ima= NULL; BGpic *bgpic; - char name[32]; + char name[MAX_ID_NAME-2]; /* check input variables */ - if(RNA_property_is_set(op->ptr, "filepath")) { + if(RNA_struct_property_is_set(op->ptr, "filepath")) { char path[FILE_MAX]; RNA_string_get(op->ptr, "filepath", path); ima= BKE_add_image_file(path); } - else if(RNA_property_is_set(op->ptr, "name")) { + else if(RNA_struct_property_is_set(op->ptr, "name")) { RNA_string_get(op->ptr, "name", name); ima= (Image *)find_id("IM", name); } @@ -3007,7 +3066,7 @@ ot->flag = 0; /* properties */ - RNA_def_string(ot->srna, "name", "Image", 24, "Name", "Image name to assign"); + RNA_def_string(ot->srna, "name", "Image", MAX_ID_NAME-2, "Name", "Image name to assign"); RNA_def_string(ot->srna, "filepath", "Path", FILE_MAX, "Filepath", "Path to image file"); } @@ -3182,6 +3241,7 @@ /* re initialize */ project_int_noclip(ar, fp, mval); flip= initgrabz(rv3d, fp[0], fp[1], fp[2]); + (void)flip; } if(mval[0]!=IS_CLIPPED) { @@ -3346,7 +3406,7 @@ } /* XXX todo Zooms in on a border drawn by the user */ -int ED_view3d_autodist(Scene *scene, ARegion *ar, View3D *v3d, const int mval[2], float mouse_worldloc[3] ) //, float *autodist ) +int ED_view3d_autodist(Scene *scene, ARegion *ar, View3D *v3d, const int mval[2], float mouse_worldloc[3]) { bglMats mats; /* ZBuffer depth vars */ float depth_close= FLT_MAX; @@ -3364,8 +3424,11 @@ cent[0] = (double)mval[0]; cent[1] = (double)mval[1]; - if (!gluUnProject(cent[0], cent[1], depth_close, mats.modelview, mats.projection, (GLint *)mats.viewport, &p[0], &p[1], &p[2])) + if (!gluUnProject(cent[0], cent[1], depth_close, + mats.modelview, mats.projection, (GLint *)mats.viewport, &p[0], &p[1], &p[2])) + { return 0; + } mouse_worldloc[0] = (float)p[0]; mouse_worldloc[1] = (float)p[1]; @@ -3389,7 +3452,8 @@ } // no 4x4 sampling, run view_autodist_init first -int ED_view3d_autodist_simple(ARegion *ar, const int mval[2], float mouse_worldloc[3], int margin, float *force_depth) //, float *autodist ) +int ED_view3d_autodist_simple(ARegion *ar, const int mval[2], float mouse_worldloc[3], + int margin, float *force_depth) //, float *autodist ) { bglMats mats; /* ZBuffer depth vars, could cache? */ float depth; @@ -3408,8 +3472,12 @@ cent[1] = (double)mval[1]; bgl_get_mats(&mats); - if (!gluUnProject(cent[0], cent[1], depth, mats.modelview, mats.projection, (GLint *)mats.viewport, &p[0], &p[1], &p[2])) + + if (!gluUnProject(cent[0], cent[1], depth, + mats.modelview, mats.projection, (GLint *)mats.viewport, &p[0], &p[1], &p[2])) + { return 0; + } mouse_worldloc[0] = (float)p[0]; mouse_worldloc[1] = (float)p[1]; @@ -3444,7 +3512,8 @@ } } -int ED_view3d_autodist_depth_seg(struct ARegion *ar, const int mval_sta[2], const int mval_end[2], int margin, float *depth) +int ED_view3d_autodist_depth_seg(struct ARegion *ar, const int mval_sta[2], const int mval_end[2], + int margin, float *depth) { struct { struct ARegion *ar; int margin; float depth; } data = {NULL}; int p1[2]; diff -Nru blender-2.61/source/blender/editors/space_view3d/view3d_fly.c blender-2.62/source/blender/editors/space_view3d/view3d_fly.c --- blender-2.61/source/blender/editors/space_view3d/view3d_fly.c 2011-12-13 19:52:25.000000000 +0000 +++ blender-2.62/source/blender/editors/space_view3d/view3d_fly.c 2012-02-15 19:36:59.000000000 +0000 @@ -135,7 +135,8 @@ WM_modalkeymap_add_item(keymap, WHEELDOWNMOUSE, KM_PRESS, KM_ANY, 0, FLY_MODAL_DECELERATE); WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, KM_ANY, 0, FLY_MODAL_PAN_ENABLE); - WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, FLY_MODAL_PAN_DISABLE); /* XXX - Bug in the event system, middle mouse release doesnt work */ + /* XXX - Bug in the event system, middle mouse release doesnt work */ + WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, FLY_MODAL_PAN_DISABLE); /* WASD */ WM_modalkeymap_add_item(keymap, WKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_FORWARD); @@ -170,7 +171,8 @@ short state; short redraw; unsigned char use_precision; - unsigned char use_freelook; /* if the user presses shift they can look about without movinf the direction there looking */ + unsigned char use_freelook; /* if the user presses shift they can look about + * without moving the direction there looking */ int mval[2]; /* latest 2D mouse values */ wmNDOFMotionData* ndof; /* latest 3D mouse values */ @@ -195,7 +197,8 @@ /* backup values */ float dist_backup; /* backup the views distance since we use a zero dist for fly mode */ float ofs_backup[3]; /* backup the views offset incase the user cancels flying in non camera mode */ - float rot_backup[4]; /* backup the views quat incase the user cancels flying in non camera mode. (quat for view, eul for camera) */ + float rot_backup[4]; /* backup the views quat incase the user cancels flying in non camera mode. + * (quat for view, eul for camera) */ short persp_backup; /* remember if were ortho or not, only used for restoring the view if it was a ortho view */ short is_ortho_cam; /* are we flying an ortho camera in perspective view, @@ -580,7 +583,8 @@ /* impliment WASD keys */ case FLY_MODAL_DIR_FORWARD: if (fly->speed < 0.0f) fly->speed= -fly->speed; /* flip speed rather than stopping, game like motion */ - else if (fly->axis==2) fly->speed += fly->grid; /* increse like mousewheel if were already moving in that difection*/ + else if (fly->axis==2) fly->speed += fly->grid; /* increse like mousewheel if were already + * moving in that difection*/ fly->axis= 2; break; case FLY_MODAL_DIR_BACKWARD: @@ -663,8 +667,8 @@ ED_view3d_to_m4(prev_view_mat, fly->rv3d->ofs, fly->rv3d->viewquat, fly->rv3d->dist); invert_m4_m4(prev_view_imat, prev_view_mat); ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist); - mul_m4_m4m4(diff_mat, prev_view_imat, view_mat); - mul_m4_m4m4(parent_mat, fly->root_parent->obmat, diff_mat); + mult_m4_m4m4(diff_mat, view_mat, prev_view_imat); + mult_m4_m4m4(parent_mat, diff_mat, fly->root_parent->obmat); object_apply_mat4(fly->root_parent, parent_mat, TRUE, FALSE); // where_is_object(scene, fly->root_parent); @@ -738,8 +742,10 @@ xmargin, ymargin; /* x and y margin are define the safe area where the mouses movement wont rotate the view */ #ifdef NDOF_FLY_DEBUG - static unsigned int iteration = 1; - printf("fly timer %d\n", iteration++); + { + static unsigned int iteration = 1; + printf("fly timer %d\n", iteration++); + } #endif @@ -782,7 +788,11 @@ } /* Should we redraw? */ - if (fly->speed != 0.0f || moffset[0] || moffset[1] || fly->zlock || fly->xlock || dvec[0] || dvec[1] || dvec[2] ) { + if ( (fly->speed != 0.0f) || + moffset[0] || moffset[1] || + fly->zlock || fly->xlock || + dvec[0] || dvec[1] || dvec[2]) + { float dvec_tmp[3]; double time_current; /*time how fast it takes for us to redraw, this is so simple scenes dont fly too fast */ float time_redraw; @@ -792,7 +802,7 @@ #endif time_current= PIL_check_seconds_timer(); time_redraw= (float)(time_current - fly->time_lastdraw); - time_redraw_clamped= MIN2(0.05f, time_redraw); /* clamt the redraw time to avoid jitter in roll correction */ + time_redraw_clamped= MIN2(0.05f, time_redraw); /* clamp redraw time to avoid jitter in roll correction */ fly->time_lastdraw= time_current; /*fprintf(stderr, "%f\n", time_redraw);*/ /* 0.002 is a small redraw 0.02 is larger */ @@ -818,7 +828,8 @@ mul_v3_fl(dvec_tmp, time_redraw * 200.0f * fly->grid); } else { - float roll; /* similar to the angle between the camera's up and the Z-up, but its very rough so just roll*/ + float roll; /* similar to the angle between the camera's up and the Z-up, + * but its very rough so just roll*/ /* rotate about the X axis- look up/down */ if (moffset[1]) { @@ -826,7 +837,8 @@ upvec[1]=0; upvec[2]=0; mul_m3_v3(mat, upvec); - axis_angle_to_quat( tmp_quat, upvec, (float)moffset[1] * time_redraw * -FLY_ROTATE_FAC); /* Rotate about the relative up vec */ + /* Rotate about the relative up vec */ + axis_angle_to_quat( tmp_quat, upvec, (float)moffset[1] * time_redraw * -FLY_ROTATE_FAC); mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat); if (fly->xlock) fly->xlock = 2; /*check for rotation*/ @@ -859,7 +871,8 @@ mul_m3_v3(mat, upvec); } - axis_angle_to_quat(tmp_quat, upvec, (float)moffset[0] * time_redraw * FLY_ROTATE_FAC); /* Rotate about the relative up vec */ + /* Rotate about the relative up vec */ + axis_angle_to_quat(tmp_quat, upvec, (float)moffset[0] * time_redraw * FLY_ROTATE_FAC); mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat); if (fly->xlock) fly->xlock = 2;/*check for rotation*/ @@ -880,7 +893,9 @@ upvec[2]= 1.0f; mul_m3_v3(mat, upvec); - axis_angle_to_quat( tmp_quat, upvec, roll*time_redraw_clamped*fly->zlock_momentum * FLY_ZUP_CORRECT_FAC); /* Rotate about the relative up vec */ + /* Rotate about the relative up vec */ + axis_angle_to_quat(tmp_quat, upvec, + roll * time_redraw_clamped * fly->zlock_momentum * FLY_ZUP_CORRECT_FAC); mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat); fly->zlock_momentum += FLY_ZUP_CORRECT_ACCEL; @@ -906,7 +921,8 @@ mul_m3_v3(mat, upvec); - axis_angle_to_quat( tmp_quat, upvec, roll*time_redraw_clamped*fly->xlock_momentum*0.1f); /* Rotate about the relative up vec */ + /* Rotate about the relative up vec */ + axis_angle_to_quat( tmp_quat, upvec, roll*time_redraw_clamped*fly->xlock_momentum*0.1f); mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat); fly->xlock_momentum += 0.05f; @@ -949,18 +965,6 @@ add_v3_v3(rv3d->ofs, dvec); - /* todo, dynamic keys */ -#if 0 - if (fly->zlock && fly->xlock) - ED_area_headerprint(fly->ar, "FlyKeys Speed:(+/- | Wheel), Upright Axis:X on/Z on, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB"); - else if (fly->zlock) - ED_area_headerprint(fly->ar, "FlyKeys Speed:(+/- | Wheel), Upright Axis:X off/Z on, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB"); - else if (fly->xlock) - ED_area_headerprint(fly->ar, "FlyKeys Speed:(+/- | Wheel), Upright Axis:X on/Z off, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB"); - else - ED_area_headerprint(fly->ar, "FlyKeys Speed:(+/- | Wheel), Upright Axis:X off/Z off, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB"); -#endif - if (rv3d->persp==RV3D_CAMOB) move_camera(C, rv3d, fly, (fly->xlock || fly->zlock || moffset[0] || moffset[1]), fly->speed); diff -Nru blender-2.61/source/blender/editors/space_view3d/view3d_header.c blender-2.62/source/blender/editors/space_view3d/view3d_header.c --- blender-2.61/source/blender/editors/space_view3d/view3d_header.c 2011-12-13 19:52:25.000000000 +0000 +++ blender-2.62/source/blender/editors/space_view3d/view3d_header.c 2012-02-15 19:36:59.000000000 +0000 @@ -230,7 +230,9 @@ return OPERATOR_PASS_THROUGH; if(event->shift) - RNA_boolean_set(op->ptr, "extend", 1); + RNA_boolean_set(op->ptr, "extend", TRUE); + else + RNA_boolean_set(op->ptr, "extend", FALSE); if(event->alt) { int nr= RNA_int_get(op->ptr, "nr") + 10; @@ -276,7 +278,7 @@ static char *view3d_modeselect_pup(Scene *scene) { Object *ob= OBACT; - static char string[256]; + static char string[512]; const char *title= IFACE_("Mode: %t"); char *str = string; @@ -316,7 +318,10 @@ str += modeselect_addmode(str, N_("Pose Mode"), OB_MODE_POSE, ICON_POSE_HLT); } - if (ob->particlesystem.first || modifiers_findByType(ob, eModifierType_Cloth) || modifiers_findByType(ob, eModifierType_Softbody)) { + if ( ob->particlesystem.first || + modifiers_findByType(ob, eModifierType_Cloth) || + modifiers_findByType(ob, eModifierType_Softbody)) + { str += modeselect_addmode(str, N_("Particle Mode"), OB_MODE_PARTICLE_EDIT, ICON_PARTICLEMODE); } (void)str; diff -Nru blender-2.61/source/blender/editors/space_view3d/view3d_intern.h blender-2.62/source/blender/editors/space_view3d/view3d_intern.h --- blender-2.61/source/blender/editors/space_view3d/view3d_intern.h 2011-12-13 19:52:25.000000000 +0000 +++ blender-2.62/source/blender/editors/space_view3d/view3d_intern.h 2012-02-15 19:36:59.000000000 +0000 @@ -59,7 +59,7 @@ #define DRAW_SCENESET 4 /* draw_mesh_fancy/draw_mesh_textured draw_flags */ -#define DRAW_DYNAMIC_PAINT_PREVIEW 1 +#define DRAW_MODIFIERS_PREVIEW 1 #define DRAW_FACE_SELECT 2 /* view3d_header.c */ @@ -152,6 +152,7 @@ void VIEW3D_OT_select_circle(struct wmOperatorType *ot); void VIEW3D_OT_select_border(struct wmOperatorType *ot); void VIEW3D_OT_select_lasso(struct wmOperatorType *ot); +void VIEW3D_OT_select_menu(struct wmOperatorType *ot); void VIEW3D_OT_smoothview(struct wmOperatorType *ot); void VIEW3D_OT_camera_to_view(struct wmOperatorType *ot); @@ -163,7 +164,8 @@ int ED_view3d_boundbox_clip(RegionView3D *rv3d, float obmat[][4], struct BoundBox *bb); -void smooth_view(struct bContext *C, struct View3D *v3d, struct ARegion *ar, struct Object *, struct Object *, float *ofs, float *quat, float *dist, float *lens); +void smooth_view(struct bContext *C, struct View3D *v3d, struct ARegion *ar, struct Object *, struct Object *, + float *ofs, float *quat, float *dist, float *lens); void setwinmatrixview3d(ARegion *ar, View3D *v3d, rctf *rect); /* rect: for picking */ void setviewmatrixview3d(Scene *scene, View3D *v3d, RegionView3D *rv3d); diff -Nru blender-2.61/source/blender/editors/space_view3d/view3d_ops.c blender-2.62/source/blender/editors/space_view3d/view3d_ops.c --- blender-2.61/source/blender/editors/space_view3d/view3d_ops.c 2011-12-13 19:52:25.000000000 +0000 +++ blender-2.62/source/blender/editors/space_view3d/view3d_ops.c 2012-02-15 19:36:59.000000000 +0000 @@ -85,6 +85,7 @@ WM_operatortype_append(VIEW3D_OT_enable_manipulator); WM_operatortype_append(VIEW3D_OT_cursor3d); WM_operatortype_append(VIEW3D_OT_select_lasso); + WM_operatortype_append(VIEW3D_OT_select_menu); WM_operatortype_append(VIEW3D_OT_camera_to_view); WM_operatortype_append(VIEW3D_OT_camera_to_view_selected); WM_operatortype_append(VIEW3D_OT_object_as_camera); @@ -120,7 +121,7 @@ keymap= WM_keymap_find(keyconf, "3D View", SPACE_VIEW3D, 0); kmi = WM_keymap_verify_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_ANY, 0); - RNA_boolean_set(kmi->ptr, "release_confirm", 1); + RNA_boolean_set(kmi->ptr, "release_confirm", TRUE); /* * Doesn't work with KM_SHIFT, have to use KM_ANY and filter in invoke * */ @@ -159,8 +160,11 @@ WM_keymap_add_item(keymap, "VIEW3D_OT_zoom_camera_1_to_1", PADENTER, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_view_center_camera", HOMEKEY, KM_PRESS, 0, 0); /* only with camera view */ - RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", HOMEKEY, KM_PRESS, 0, 0)->ptr, "center", 0); /* only without camera view */ - RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", CKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "center", 1); + + kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", HOMEKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "center", FALSE); /* only without camera view */ + kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", CKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "center", TRUE); /* numpad view hotkeys*/ RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD0, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_CAMERA); @@ -261,33 +265,54 @@ RNA_string_set(kmi->ptr, "value_2", "SOLID"); /* selection*/ - WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, 0, 0); + kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + RNA_boolean_set(kmi->ptr, "center", FALSE); + RNA_boolean_set(kmi->ptr, "object", FALSE); + RNA_boolean_set(kmi->ptr, "enumerate", FALSE); kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0); RNA_boolean_set(kmi->ptr, "extend", TRUE); + RNA_boolean_set(kmi->ptr, "center", FALSE); + RNA_boolean_set(kmi->ptr, "object", FALSE); + RNA_boolean_set(kmi->ptr, "enumerate", FALSE); kmi= WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); RNA_boolean_set(kmi->ptr, "center", TRUE); RNA_boolean_set(kmi->ptr, "object", TRUE); /* use Ctrl+Select for 2 purposes */ + RNA_boolean_set(kmi->ptr, "enumerate", FALSE); kmi= WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + RNA_boolean_set(kmi->ptr, "center", FALSE); + RNA_boolean_set(kmi->ptr, "object", FALSE); RNA_boolean_set(kmi->ptr, "enumerate", TRUE); /* selection key-combinations */ kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_CTRL, 0); - RNA_boolean_set(kmi->ptr, "center", TRUE); RNA_boolean_set(kmi->ptr, "extend", TRUE); + RNA_boolean_set(kmi->ptr, "center", TRUE); + RNA_boolean_set(kmi->ptr, "object", FALSE); + RNA_boolean_set(kmi->ptr, "enumerate", FALSE); kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_CTRL|KM_ALT, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); RNA_boolean_set(kmi->ptr, "center", TRUE); + RNA_boolean_set(kmi->ptr, "object", FALSE); RNA_boolean_set(kmi->ptr, "enumerate", TRUE); kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_ALT, 0); RNA_boolean_set(kmi->ptr, "extend", TRUE); + RNA_boolean_set(kmi->ptr, "center", FALSE); + RNA_boolean_set(kmi->ptr, "object", FALSE); RNA_boolean_set(kmi->ptr, "enumerate", TRUE); kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_CTRL|KM_ALT, 0); - RNA_boolean_set(kmi->ptr, "center", TRUE); RNA_boolean_set(kmi->ptr, "extend", TRUE); + RNA_boolean_set(kmi->ptr, "center", TRUE); + RNA_boolean_set(kmi->ptr, "object", FALSE); RNA_boolean_set(kmi->ptr, "enumerate", TRUE); WM_keymap_add_item(keymap, "VIEW3D_OT_select_border", BKEY, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "VIEW3D_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_SHIFT|KM_CTRL, 0)->ptr, "deselect", 1); + kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "deselect", FALSE); + kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_SHIFT|KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "deselect", TRUE); WM_keymap_add_item(keymap, "VIEW3D_OT_select_circle", CKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_clip_border", BKEY, KM_PRESS, KM_ALT, 0); diff -Nru blender-2.61/source/blender/editors/space_view3d/view3d_select.c blender-2.62/source/blender/editors/space_view3d/view3d_select.c --- blender-2.61/source/blender/editors/space_view3d/view3d_select.c 2011-12-13 19:52:25.000000000 +0000 +++ blender-2.62/source/blender/editors/space_view3d/view3d_select.c 2012-02-15 19:36:59.000000000 +0000 @@ -74,6 +74,7 @@ #include "RNA_access.h" #include "RNA_define.h" +#include "RNA_enum_types.h" #include "ED_armature.h" #include "ED_curve.h" @@ -135,13 +136,13 @@ /* * ob == NULL if you want global matrices * */ -void view3d_get_transformation(ARegion *ar, RegionView3D *rv3d, Object *ob, bglMats *mats) +void view3d_get_transformation(const ARegion *ar, RegionView3D *rv3d, Object *ob, bglMats *mats) { float cpy[4][4]; int i, j; if (ob) { - mul_m4_m4m4(cpy, ob->obmat, rv3d->viewmat); + mult_m4_m4m4(cpy, rv3d->viewmat, ob->obmat); } else { copy_m4_m4(cpy, rv3d->viewmat); } @@ -239,6 +240,12 @@ /* *********************** GESTURE AND LASSO ******************* */ +typedef struct LassoSelectUserData { + ViewContext *vc; + rcti *rect; + int (*mcords)[2], moves, select, pass, done; +} LassoSelectUserData; + static int view3d_selectable_data(bContext *C) { Object *ob = CTX_data_active_object(C); @@ -256,7 +263,9 @@ if (ob->mode & OB_MODE_SCULPT) { return 0; } - if (ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT) && !paint_facesel_test(ob) && !paint_vertsel_test(ob)) { + if ((ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT)) && + !paint_facesel_test(ob) && !paint_vertsel_test(ob)) + { return 0; } } @@ -453,7 +462,7 @@ static void do_lasso_select_mesh__doSelectVert(void *userData, EditVert *eve, int x, int y, int UNUSED(index)) { - struct { ViewContext vc; rcti *rect; int (*mcords)[2], moves, select, pass, done; } *data = userData; + LassoSelectUserData *data = userData; if (BLI_in_rcti(data->rect, x, y) && lasso_inside(data->mcords, data->moves, x, y)) { eve->f = data->select?(eve->f|1):(eve->f&~1); @@ -461,7 +470,7 @@ } static void do_lasso_select_mesh__doSelectEdge(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index) { - struct { ViewContext vc; rcti *rect; int (*mcords)[2], moves, select, pass, done; } *data = userData; + LassoSelectUserData *data = userData; if (EM_check_backbuf(em_solidoffs+index)) { if (data->pass==0) { @@ -480,16 +489,16 @@ } static void do_lasso_select_mesh__doSelectFace(void *userData, EditFace *efa, int x, int y, int UNUSED(index)) { - struct { ViewContext vc; rcti *rect; int (*mcords)[2], moves, select, pass, done; } *data = userData; + LassoSelectUserData *data = userData; if (BLI_in_rcti(data->rect, x, y) && lasso_inside(data->mcords, data->moves, x, y)) { - EM_select_face_fgon(data->vc.em, efa, data->select); + EM_select_face_fgon(data->vc->em, efa, data->select); } } static void do_lasso_select_mesh(ViewContext *vc, int mcords[][2], short moves, short extend, short select) { - struct { ViewContext vc; rcti *rect; int (*mcords)[2], moves, select, pass, done; } data; + LassoSelectUserData data; ToolSettings *ts= vc->scene->toolsettings; rcti rect; int bbsel; @@ -499,7 +508,7 @@ /* set editmesh */ vc->em= ((Mesh *)vc->obedit->data)->edit_mesh; - data.vc= *vc; + data.vc= vc; data.rect = ▭ data.mcords = mcords; data.moves = moves; @@ -607,7 +616,7 @@ static void do_lasso_select_curve__doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, int x, int y) { - struct { ViewContext *vc; int (*mcords)[2]; short moves; short select; } *data = userData; + LassoSelectUserData *data = userData; Object *obedit= data->vc->obedit; Curve *cu= (Curve*)obedit->data; @@ -636,7 +645,7 @@ static void do_lasso_select_curve(ViewContext *vc, int mcords[][2], short moves, short extend, short select) { - struct { ViewContext *vc; int (*mcords)[2]; short moves; short select; } data; + LassoSelectUserData data; /* set vc->editnurb */ data.vc = vc; @@ -653,7 +662,7 @@ static void do_lasso_select_lattice__doSelect(void *userData, BPoint *bp, int x, int y) { - struct { int (*mcords)[2]; short moves; short select; } *data = userData; + LassoSelectUserData *data = userData; if (lasso_inside(data->mcords, data->moves, x, y)) { bp->f1 = data->select?(bp->f1|SELECT):(bp->f1&~SELECT); @@ -661,7 +670,7 @@ } static void do_lasso_select_lattice(ViewContext *vc, int mcords[][2], short moves, short extend, short select) { - struct { int (*mcords)[2]; short moves; short select; } data; + LassoSelectUserData data; /* set editdata in vc */ data.mcords = mcords; @@ -1045,7 +1054,104 @@ /* The max number of menu items in an object select menu */ +typedef struct SelMenuItemF { + char idname[MAX_ID_NAME-2]; + int icon; +} SelMenuItemF; + #define SEL_MENU_SIZE 22 +static SelMenuItemF object_mouse_select_menu_data[SEL_MENU_SIZE]; + +/* special (crappy) operator only for menu select */ +static EnumPropertyItem *object_select_menu_enum_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free) +{ + EnumPropertyItem *item= NULL, item_tmp= {0}; + int totitem= 0; + int i= 0; + + /* dont need context but avoid docgen using this */ + if (C == NULL || object_mouse_select_menu_data[i].idname[0] == '\0') { + return DummyRNA_NULL_items; + } + + for (; i < SEL_MENU_SIZE && object_mouse_select_menu_data[i].idname[0] != '\0'; i++) { + item_tmp.name= object_mouse_select_menu_data[i].idname; + item_tmp.identifier= object_mouse_select_menu_data[i].idname; + item_tmp.value= i; + item_tmp.icon= object_mouse_select_menu_data[i].icon; + RNA_enum_item_add(&item, &totitem, &item_tmp); + } + + RNA_enum_item_end(&item, &totitem); + *free= 1; + + return item; +} + +static int object_select_menu_exec(bContext *C, wmOperator *op) +{ + int name_index= RNA_enum_get(op->ptr, "name"); + short extend= RNA_boolean_get(op->ptr, "extend"); + short changed = 0; + const char *name= object_mouse_select_menu_data[name_index].idname; + + if(!extend) { + CTX_DATA_BEGIN(C, Base*, base, selectable_bases) { + if(base->flag & SELECT) { + ED_base_object_select(base, BA_DESELECT); + changed= 1; + } + } + CTX_DATA_END; + } + + CTX_DATA_BEGIN(C, Base*, base, selectable_bases) { + /* this is a bit dodjy, there should only be ONE object with this name, but library objects can mess this up */ + if(strcmp(name, base->object->id.name+2)==0) { + ED_base_object_activate(C, base); + ED_base_object_select(base, BA_SELECT); + changed= 1; + } + } + CTX_DATA_END; + + /* weak but ensures we activate menu again before using the enum */ + memset(object_mouse_select_menu_data, 0, sizeof(object_mouse_select_menu_data)); + + /* undo? */ + if(changed) { + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C)); + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } +} + +void VIEW3D_OT_select_menu(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name= "Select Menu"; + ot->description = "Menu object selection"; + ot->idname= "VIEW3D_OT_select_menu"; + + /* api callbacks */ + ot->invoke= WM_menu_invoke; + ot->exec= object_select_menu_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* keyingset to use (dynamic enum) */ + prop= RNA_def_enum(ot->srna, "name", DummyRNA_NULL_items, 0, "Object Name", ""); + RNA_def_enum_funcs(prop, object_select_menu_enum_itemf); + RNA_def_property_flag(prop, PROP_HIDDEN); + ot->prop= prop; + + RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend selection instead of deselecting everything first"); +} static void deselectall_except(Scene *scene, Base *b) /* deselect all except b */ { @@ -1060,7 +1166,7 @@ } } -static Base *mouse_select_menu(bContext *C, ViewContext *vc, unsigned int *buffer, int hits, const int mval[2], short extend) +static Base *object_mouse_select_menu(bContext *C, ViewContext *vc, unsigned int *buffer, int hits, const int mval[2], short extend) { short baseCount = 0; short ok; @@ -1098,9 +1204,6 @@ } CTX_DATA_END; - if(baseCount) - - if(baseCount==0) { return NULL; } @@ -1110,35 +1213,30 @@ return base; } else { - /* UI */ - uiPopupMenu *pup= uiPupMenuBegin(C, "Select Object", ICON_NONE); - uiLayout *layout= uiPupMenuLayout(pup); - uiLayout *split= uiLayoutSplit(layout, 0, 0); - uiLayout *column= uiLayoutColumn(split, 0); + /* UI, full in static array values that we later use in an enum function */ LinkNode *node; + int i; + + memset(object_mouse_select_menu_data, 0, sizeof(object_mouse_select_menu_data)); - node= linklist; - while(node) { + for (node = linklist, i = 0; node; node= node->next, i++) { Base *base=node->link; Object *ob= base->object; char *name= ob->id.name+2; - /* annoying!, since we need to set 2 props cant use this. */ - /* uiItemStringO(column, name, 0, "OBJECT_OT_select_name", "name", name); */ - { - PointerRNA ptr; + BLI_strncpy(object_mouse_select_menu_data[i].idname, name, MAX_ID_NAME-2); + object_mouse_select_menu_data[i].icon = uiIconFromID(&ob->id); + } - WM_operator_properties_create(&ptr, "OBJECT_OT_select_name"); - RNA_string_set(&ptr, "name", name); - RNA_boolean_set(&ptr, "extend", extend); - uiItemFullO(column, "OBJECT_OT_select_name", name, uiIconFromID((ID *)ob), ptr.data, WM_OP_EXEC_DEFAULT, 0); - } + { + PointerRNA ptr; - node= node->next; + WM_operator_properties_create(&ptr, "VIEW3D_OT_select_menu"); + RNA_boolean_set(&ptr, "extend", extend); + WM_operator_name_call(C, "VIEW3D_OT_select_menu", WM_OP_INVOKE_DEFAULT, &ptr); + WM_operator_properties_free(&ptr); } - uiPupMenuEnd(C, pup); - BLI_linklist_free(linklist, NULL); return NULL; } @@ -1320,6 +1418,25 @@ return basact; } +static void deselect_all_tracks(MovieTracking *tracking) +{ + MovieTrackingObject *object; + + object= tracking->objects.first; + while(object) { + ListBase *tracksbase= BKE_tracking_object_tracks(tracking, object); + MovieTrackingTrack *track= tracksbase->first; + + while(track) { + BKE_tracking_deselect_track(track, TRACK_AREA_ALL); + + track= track->next; + } + + object= object->next; + } +} + /* mval is region coords */ static int mouse_select(bContext *C, const int mval[2], short extend, short obcenter, short enumerate) { @@ -1345,7 +1462,7 @@ /* note; shift+alt goes to group-flush-selecting */ if(enumerate) { - basact= mouse_select_menu(C, &vc, NULL, 0, mval, extend); + basact= object_mouse_select_menu(C, &vc, NULL, 0, mval, extend); } else { base= startbase; while(base) { @@ -1382,7 +1499,7 @@ /* note; shift+alt goes to group-flush-selecting */ if(has_bones==0 && enumerate) { - basact= mouse_select_menu(C, &vc, buffer, hits, mval, extend); + basact= object_mouse_select_menu(C, &vc, buffer, hits, mval, extend); } else { basact= mouse_select_eval_buffer(&vc, buffer, hits, mval, startbase, has_bones); } @@ -1391,27 +1508,41 @@ if(basact->object->type==OB_CAMERA) { if(BASACT==basact) { int i, hitresult; - MovieTrackingTrack *track; + int changed= 0; for (i=0; i< hits; i++) { hitresult= buffer[3+(i*4)]; /* if there's bundles in buffer select bundles first, so non-camera elements should be ignored in buffer */ - if(basact->selcol != (hitresult & 0xFFFF)) + if(basact->selcol != (hitresult & 0xFFFF)) { continue; + } /* index of bundle is 1<<16-based. if there's no "bone" index in hight word, this buffer value belongs to camera,. not to bundle */ if(buffer[4*i+3] & 0xFFFF0000) { MovieClip *clip= object_get_movieclip(scene, basact->object, 0); - int selected; - track= BKE_tracking_indexed_track(&clip->tracking, hitresult >> 16); + MovieTracking *tracking= &clip->tracking; + ListBase *tracksbase; + MovieTrackingTrack *track; + + track= BKE_tracking_indexed_track(&clip->tracking, hitresult >> 16, &tracksbase); + + if(TRACK_SELECTED(track) && extend) { + changed= 0; + BKE_tracking_deselect_track(track, TRACK_AREA_ALL); + } + else { + int oldsel= TRACK_SELECTED(track) ? 1 : 0; + if(!extend) + deselect_all_tracks(tracking); - selected= (track->flag&SELECT) || (track->pat_flag&SELECT) || (track->search_flag&SELECT); + BKE_tracking_select_track(tracksbase, track, TRACK_AREA_ALL, extend); - if(selected && extend) BKE_tracking_deselect_track(track, TRACK_AREA_ALL); - else BKE_tracking_select_track(&clip->tracking, track, TRACK_AREA_ALL, extend); + if(oldsel!=(TRACK_SELECTED(track) ? 1 : 0)) + changed= 1; + } basact->flag|= SELECT; basact->object->flag= basact->flag; @@ -1424,6 +1555,12 @@ break; } } + + if(!changed) { + /* fallback to regular object selection if no new bundles were selected, + allows to select object parented to reconstruction object */ + basact= mouse_select_eval_buffer(&vc, buffer, hits, mval, startbase, 0); + } } } else if(ED_do_pose_selectbuffer(scene, basact, buffer, hits, extend) ) { /* then bone is found */ @@ -1493,6 +1630,11 @@ /* ******************** border and circle ************************************** */ +typedef struct BoxSelectUserData { + ViewContext *vc; + rcti *rect; + int select, pass, done; +} BoxSelectUserData; int edge_inside_circle(short centx, short centy, short rad, short x1, short y1, short x2, short y2) { @@ -1518,7 +1660,7 @@ static void do_nurbs_box_select__doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, int x, int y) { - struct { ViewContext *vc; rcti *rect; int select; } *data = userData; + BoxSelectUserData *data = userData; Object *obedit= data->vc->obedit; Curve *cu= (Curve*)obedit->data; @@ -1546,7 +1688,7 @@ } static int do_nurbs_box_select(ViewContext *vc, rcti *rect, int select, int extend) { - struct { ViewContext *vc; rcti *rect; int select; } data; + BoxSelectUserData data; data.vc = vc; data.rect = rect; @@ -1563,7 +1705,7 @@ static void do_lattice_box_select__doSelect(void *userData, BPoint *bp, int x, int y) { - struct { ViewContext vc; rcti *rect; int select; } *data = userData; + BoxSelectUserData *data = userData; if (BLI_in_rcti(data->rect, x, y)) { bp->f1 = data->select?(bp->f1|SELECT):(bp->f1&~SELECT); @@ -1571,9 +1713,9 @@ } static int do_lattice_box_select(ViewContext *vc, rcti *rect, int select, int extend) { - struct { ViewContext vc; rcti *rect; int select, pass, done; } data; + BoxSelectUserData data; - data.vc= *vc; + data.vc= vc; data.rect = rect; data.select = select; @@ -1588,7 +1730,7 @@ static void do_mesh_box_select__doSelectVert(void *userData, EditVert *eve, int x, int y, int UNUSED(index)) { - struct { ViewContext vc; rcti *rect; short select, pass, done; } *data = userData; + BoxSelectUserData *data = userData; if (BLI_in_rcti(data->rect, x, y)) { eve->f = data->select?(eve->f|1):(eve->f&~1); @@ -1596,7 +1738,7 @@ } static void do_mesh_box_select__doSelectEdge(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index) { - struct { ViewContext vc; rcti *rect; short select, pass, done; } *data = userData; + BoxSelectUserData *data = userData; if(EM_check_backbuf(em_solidoffs+index)) { if (data->pass==0) { @@ -1613,19 +1755,19 @@ } static void do_mesh_box_select__doSelectFace(void *userData, EditFace *efa, int x, int y, int UNUSED(index)) { - struct { ViewContext vc; rcti *rect; short select, pass, done; } *data = userData; + BoxSelectUserData *data = userData; if (BLI_in_rcti(data->rect, x, y)) { - EM_select_face_fgon(data->vc.em, efa, data->select); + EM_select_face_fgon(data->vc->em, efa, data->select); } } static int do_mesh_box_select(ViewContext *vc, rcti *rect, int select, int extend) { - struct { ViewContext vc; rcti *rect; short select, pass, done; } data; + BoxSelectUserData data; ToolSettings *ts= vc->scene->toolsettings; int bbsel; - data.vc= *vc; + data.vc= vc; data.rect = rect; data.select = select; data.pass = 0; @@ -2120,9 +2262,16 @@ /* -------------------- circle select --------------------------------------------- */ +typedef struct CircleSelectUserData { + ViewContext *vc; + short select; + int mval[2]; + float radius; +} CircleSelectUserData; + static void mesh_circle_doSelectVert(void *userData, EditVert *eve, int x, int y, int UNUSED(index)) { - struct {ViewContext *vc; short select; int mval[2]; float radius; } *data = userData; + CircleSelectUserData *data = userData; int mx = x - data->mval[0], my = y - data->mval[1]; float r = sqrt(mx*mx + my*my); @@ -2132,7 +2281,7 @@ } static void mesh_circle_doSelectEdge(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int UNUSED(index)) { - struct {ViewContext *vc; short select; int mval[2]; float radius; } *data = userData; + CircleSelectUserData *data = userData; if (edge_inside_circle(data->mval[0], data->mval[1], (short) data->radius, x0, y0, x1, y1)) { EM_select_edge(eed, data->select); @@ -2140,7 +2289,7 @@ } static void mesh_circle_doSelectFace(void *userData, EditFace *efa, int x, int y, int UNUSED(index)) { - struct {ViewContext *vc; short select; int mval[2]; float radius; } *data = userData; + CircleSelectUserData *data = userData; int mx = x - data->mval[0], my = y - data->mval[1]; float r = sqrt(mx*mx + my*my); @@ -2153,7 +2302,7 @@ { ToolSettings *ts= vc->scene->toolsettings; int bbsel; - struct {ViewContext *vc; short select; int mval[2]; float radius; } data; + CircleSelectUserData data; bbsel= EM_init_backbuf_circle(vc, mval[0], mval[1], (short)(rad+1.0f)); ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ @@ -2215,7 +2364,7 @@ Object *ob= vc->obact; Mesh *me = ob?ob->data:NULL; /* int bbsel; */ /* UNUSED */ - /* struct {ViewContext *vc; short select; int mval[2]; float radius; } data = {NULL}; */ /* UNUSED */ + /* CircleSelectUserData data = {NULL}; */ /* UNUSED */ if (me) { em_vertoffs= me->totvert+1; /* max index array */ @@ -2230,7 +2379,7 @@ static void nurbscurve_circle_doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, int x, int y) { - struct {ViewContext *vc; short select; int mval[2]; float radius; } *data = userData; + CircleSelectUserData *data = userData; int mx = x - data->mval[0], my = y - data->mval[1]; float r = sqrt(mx*mx + my*my); Object *obedit= data->vc->obedit; @@ -2261,7 +2410,7 @@ } static void nurbscurve_circle_select(ViewContext *vc, int select, const int mval[2], float rad) { - struct {ViewContext *vc; short select; int mval[2]; float radius; } data; + CircleSelectUserData data; /* set vc-> edit data */ @@ -2278,7 +2427,7 @@ static void latticecurve_circle_doSelect(void *userData, BPoint *bp, int x, int y) { - struct {ViewContext *vc; short select; int mval[2]; float radius; } *data = userData; + CircleSelectUserData *data = userData; int mx = x - data->mval[0], my = y - data->mval[1]; float r = sqrt(mx*mx + my*my); @@ -2288,7 +2437,7 @@ } static void lattice_circle_select(ViewContext *vc, int select, const int mval[2], float rad) { - struct {ViewContext *vc; short select; int mval[2]; float radius; } data; + CircleSelectUserData data; /* set vc-> edit data */ @@ -2305,7 +2454,7 @@ // NOTE: pose-bone case is copied from editbone case... static short pchan_circle_doSelectJoint(void *userData, bPoseChannel *pchan, int x, int y) { - struct {ViewContext *vc; short select; int mval[2]; float radius; } *data = userData; + CircleSelectUserData *data = userData; int mx = x - data->mval[0], my = y - data->mval[1]; float r = sqrt(mx*mx + my*my); @@ -2320,7 +2469,8 @@ } static void pose_circle_select(ViewContext *vc, int select, const int mval[2], float rad) { - struct {ViewContext *vc; short select; int mval[2]; float radius; } data; + CircleSelectUserData data; + bArmature *arm = vc->obact->data; bPose *pose = vc->obact->pose; bPoseChannel *pchan; int change= FALSE; @@ -2339,6 +2489,10 @@ short sco1[2], sco2[2], didpoint=0; float vec[3]; + /* skip invisible bones */ + if (PBONE_VISIBLE(arm, pchan->bone) == 0) + continue; + /* project head location to screenspace */ mul_v3_m4v3(vec, vc->obact->obmat, pchan->pose_head); project_short(vc->ar, vec, sco1); @@ -2365,7 +2519,7 @@ static short armature_circle_doSelectJoint(void *userData, EditBone *ebone, int x, int y, short head) { - struct {ViewContext *vc; short select; int mval[2]; float radius; } *data = userData; + CircleSelectUserData *data = userData; int mx = x - data->mval[0], my = y - data->mval[1]; float r = sqrt(mx*mx + my*my); @@ -2388,7 +2542,7 @@ } static void armature_circle_select(ViewContext *vc, int select, const int mval[2], float rad) { - struct {ViewContext *vc; short select, mval[2]; float radius; } data; + CircleSelectUserData data; bArmature *arm= vc->obedit->data; EditBone *ebone; int change= FALSE; diff -Nru blender-2.61/source/blender/editors/space_view3d/view3d_snap.c blender-2.62/source/blender/editors/space_view3d/view3d_snap.c --- blender-2.61/source/blender/editors/space_view3d/view3d_snap.c 2011-12-13 19:52:25.000000000 +0000 +++ blender-2.62/source/blender/editors/space_view3d/view3d_snap.c 2012-02-15 19:36:59.000000000 +0000 @@ -55,6 +55,7 @@ #include "BKE_lattice.h" #include "BKE_main.h" #include "BKE_object.h" +#include "BKE_scene.h" #include "BKE_tracking.h" #include "WM_api.h" @@ -504,7 +505,6 @@ if(pchan->bone->layer & arm->layer) { if((pchan->bone->flag & BONE_CONNECTED)==0) { float nLoc[3]; - float inv_restmat[4][4]; /* get nearest grid point to snap to */ copy_v3_v3(nLoc, pchan->pose_mat[3]); @@ -516,9 +516,8 @@ /* Back in object space... */ mul_m4_v3(ob->imat, vec); - /* get location of grid point in *rest* bone-space */ - invert_m4_m4(inv_restmat, pchan->bone->arm_mat); - mul_m4_v3(inv_restmat, vec); + /* Get location of grid point in pose space. */ + armature_loc_pose_to_bone(pchan, vec, vec); /* adjust location */ if ((pchan->protectflag & OB_LOCK_LOCX)==0) @@ -641,12 +640,9 @@ if(pchan->bone->flag & BONE_SELECTED) { if(pchan->bone->layer & arm->layer) { if((pchan->bone->flag & BONE_CONNECTED)==0) { - float inv_restmat[4][4]; - - /* get location of cursor in *rest* bone-space */ - invert_m4_m4(inv_restmat, pchan->bone->arm_mat); - mul_m4_v3(inv_restmat, vec); - + /* Get position in pchan (pose) space. */ + armature_loc_pose_to_bone(pchan, vec, vec); + /* copy new position */ if ((pchan->protectflag & OB_LOCK_LOCX)==0) pchan->loc[0]= vec[0]; @@ -756,28 +752,49 @@ static void bundle_midpoint(Scene *scene, Object *ob, float vec[3]) { - MovieTrackingTrack *track; MovieClip *clip= object_get_movieclip(scene, ob, 0); + MovieTracking *tracking; + MovieTrackingObject *object; int ok= 0; - float min[3], max[3], mat[4][4], pos[3]; + float min[3], max[3], mat[4][4], pos[3], cammat[4][4] = MAT4_UNITY; if(!clip) return; + tracking= &clip->tracking; + + copy_m4_m4(cammat, ob->obmat); + BKE_get_tracking_mat(scene, ob, mat); INIT_MINMAX(min, max); - track= clip->tracking.tracks.first; - while(track) { - int selected= (track->flag&SELECT) || (track->pat_flag&SELECT) || (track->search_flag&SELECT); - if((track->flag&TRACK_HAS_BUNDLE) && selected) { - ok= 1; - mul_v3_m4v3(pos, mat, track->bundle_pos); - DO_MINMAX(pos, min, max); + for (object= tracking->objects.first; object; object= object->next) { + ListBase *tracksbase= BKE_tracking_object_tracks(tracking, object); + MovieTrackingTrack *track= tracksbase->first; + float obmat[4][4]; + + if(object->flag & TRACKING_OBJECT_CAMERA) { + copy_m4_m4(obmat, mat); } + else { + float imat[4][4]; - track= track->next; + BKE_tracking_get_interpolated_camera(tracking, object, scene->r.cfra, imat); + invert_m4(imat); + + mult_m4_m4m4(obmat, cammat, imat); + } + + while(track) { + if((track->flag&TRACK_HAS_BUNDLE) && TRACK_SELECTED(track)) { + ok= 1; + mul_v3_m4v3(pos, obmat, track->bundle_pos); + DO_MINMAX(pos, min, max); + } + + track= track->next; + } } if(ok) { diff -Nru blender-2.61/source/blender/editors/space_view3d/view3d_toolbar.c blender-2.62/source/blender/editors/space_view3d/view3d_toolbar.c --- blender-2.61/source/blender/editors/space_view3d/view3d_toolbar.c 2011-12-13 19:52:25.000000000 +0000 +++ blender-2.62/source/blender/editors/space_view3d/view3d_toolbar.c 2012-02-15 19:36:59.000000000 +0000 @@ -177,7 +177,7 @@ /* fake button, it holds space for search items */ uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL); - but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, OP_MAX_TYPENAME, 10, 0, 150, 19, 0, 0, ""); + but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, 150, 19, 0, 0, ""); uiButSetSearchFunc(but, operator_search_cb, arg_listbase, operator_call_cb, NULL); uiBoundsBlock(block, 6); diff -Nru blender-2.61/source/blender/editors/space_view3d/view3d_view.c blender-2.62/source/blender/editors/space_view3d/view3d_view.c --- blender-2.61/source/blender/editors/space_view3d/view3d_view.c 2011-12-13 19:52:25.000000000 +0000 +++ blender-2.62/source/blender/editors/space_view3d/view3d_view.c 2012-02-15 19:36:59.000000000 +0000 @@ -68,6 +68,9 @@ #include "BL_System.h" #endif +#include "RNA_access.h" +#include "RNA_define.h" + #include "view3d_intern.h" // own include /* use this call when executing an operator, @@ -120,7 +123,8 @@ /* will start timer if appropriate */ /* the arguments are the desired situation */ -void smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera, Object *camera, float *ofs, float *quat, float *dist, float *lens) +void smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera, Object *camera, + float *ofs, float *quat, float *dist, float *lens) { wmWindowManager *wm= CTX_wm_manager(C); wmWindow *win= CTX_wm_window(C); @@ -466,13 +470,18 @@ static int view3d_setobjectascamera_exec(bContext *C, wmOperator *UNUSED(op)) -{ - View3D *v3d = CTX_wm_view3d(C); - ARegion *ar= ED_view3d_context_region_unlock(C); - RegionView3D *rv3d= ar->regiondata; /* no NULL check is needed, poll checks */ +{ + View3D *v3d; + ARegion *ar; + RegionView3D *rv3d; + Scene *scene= CTX_data_scene(C); Object *ob = CTX_data_active_object(C); + /* no NULL check is needed, poll checks */ + ED_view3d_context_user_region(C, &v3d, &ar); + rv3d = ar->regiondata; + if(ob) { Object *camera_old= (rv3d->persp == RV3D_CAMOB) ? V3D_CAMERA_SCENE(scene, v3d) : NULL; rv3d->persp= RV3D_CAMOB; @@ -489,9 +498,12 @@ return OPERATOR_FINISHED; } -int ED_operator_rv3d_unlock_poll(bContext *C) +int ED_operator_rv3d_user_region_poll(bContext *C) { - return ED_view3d_context_region_unlock(C) != NULL; + View3D *v3d_dummy; + ARegion *ar_dummy; + + return ED_view3d_context_user_region(C, &v3d_dummy, &ar_dummy); } void VIEW3D_OT_object_as_camera(wmOperatorType *ot) @@ -504,7 +516,7 @@ /* api callbacks */ ot->exec= view3d_setobjectascamera_exec; - ot->poll= ED_operator_rv3d_unlock_poll; + ot->poll= ED_operator_rv3d_user_region_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -512,7 +524,7 @@ /* ********************************** */ -void ED_view3d_calc_clipping(BoundBox *bb, float planes[4][4], bglMats *mats, rcti *rect) +void ED_view3d_calc_clipping(BoundBox *bb, float planes[4][4], bglMats *mats, const rcti *rect) { float modelview[4][4]; double xs, ys, p[3]; @@ -740,8 +752,8 @@ { float vmat[4][4]; - mul_m4_m4m4(vmat, ob->obmat, rv3d->viewmat); - mul_m4_m4m4(pmat, vmat, rv3d->winmat); + mult_m4_m4m4(vmat, rv3d->viewmat, ob->obmat); + mult_m4_m4m4(pmat, rv3d->winmat, vmat); } #if 0 @@ -760,7 +772,7 @@ #endif /* use view3d_get_object_project_mat to get projecting mat */ -void ED_view3d_project_float(ARegion *ar, const float vec[3], float adr[2], float mat[4][4]) +void ED_view3d_project_float(const ARegion *ar, const float vec[3], float adr[2], float mat[4][4]) { float vec4[4]; @@ -809,7 +821,7 @@ if(bb==NULL) return 1; if(bb->flag & OB_BB_DISABLED) return 1; - mul_m4_m4m4(mat, obmat, rv3d->persmat); + mult_m4_m4m4(mat, rv3d->persmat, obmat); for(a=0; a<8; a++) { copy_v3_v3(vec, bb->vec[a]); @@ -938,23 +950,29 @@ } } -void project_float(ARegion *ar, const float vec[3], float adr[2]) +void apply_project_float(float persmat[4][4], int winx, int winy, const float vec[3], float adr[2]) { - RegionView3D *rv3d= ar->regiondata; float vec4[4]; - + copy_v3_v3(vec4, vec); vec4[3]= 1.0; adr[0]= IS_CLIPPED; - - mul_m4_v4(rv3d->persmat, vec4); - + + mul_m4_v4(persmat, vec4); + if(vec4[3] > (float)BL_NEAR_CLIP) { - adr[0] = (float)(ar->winx/2.0f)+(ar->winx/2.0f)*vec4[0]/vec4[3]; - adr[1] = (float)(ar->winy/2.0f)+(ar->winy/2.0f)*vec4[1]/vec4[3]; + adr[0] = (float)(winx/2.0f)+(winx/2.0f)*vec4[0]/vec4[3]; + adr[1] = (float)(winy/2.0f)+(winy/2.0f)*vec4[1]/vec4[3]; } } +void project_float(ARegion *ar, const float vec[3], float adr[2]) +{ + RegionView3D *rv3d= ar->regiondata; + + apply_project_float(rv3d->persmat, ar->winx, ar->winy, vec, adr); +} + void project_float_noclip(ARegion *ar, const float vec[3], float adr[2]) { RegionView3D *rv3d= ar->regiondata; @@ -990,7 +1008,8 @@ } /* also exposed in previewrender.c */ -int ED_view3d_viewplane_get(View3D *v3d, RegionView3D *rv3d, int winx, int winy, rctf *viewplane, float *clipsta, float *clipend) +int ED_view3d_viewplane_get(View3D *v3d, RegionView3D *rv3d, int winx, int winy, + rctf *viewplane, float *clipsta, float *clipend) { CameraParams params; @@ -1015,7 +1034,12 @@ orth= ED_view3d_viewplane_get(v3d, rv3d, ar->winx, ar->winy, &viewplane, &clipsta, &clipend); rv3d->is_persp= !orth; - // printf("%d %d %f %f %f %f %f %f\n", winx, winy, viewplane.xmin, viewplane.ymin, viewplane.xmax, viewplane.ymax, clipsta, clipend); +#if 0 + printf("%s: %d %d %f %f %f %f %f %f\n", __func__, winx, winy, + viewplane.xmin, viewplane.ymin, viewplane.xmax, viewplane.ymax, + clipsta, clipend); +#endif + x1= viewplane.xmin; y1= viewplane.ymin; x2= viewplane.xmax; @@ -1196,7 +1220,7 @@ } setwinmatrixview3d(ar, v3d, &rect); - mul_m4_m4m4(vc->rv3d->persmat, vc->rv3d->viewmat, vc->rv3d->winmat); + mult_m4_m4m4(vc->rv3d->persmat, vc->rv3d->winmat, vc->rv3d->viewmat); if(v3d->drawtype > OB_WIRE) { v3d->zbuf= TRUE; @@ -1274,7 +1298,7 @@ G.f &= ~G_PICKSEL; setwinmatrixview3d(ar, v3d, NULL); - mul_m4_m4m4(vc->rv3d->persmat, vc->rv3d->viewmat, vc->rv3d->winmat); + mult_m4_m4m4(vc->rv3d->persmat, vc->rv3d->winmat, vc->rv3d->viewmat); if(v3d->drawtype > OB_WIRE) { v3d->zbuf= 0; @@ -1727,7 +1751,11 @@ game_set_commmandline_options(&startscene->gm); - if(rv3d->persp==RV3D_CAMOB && startscene->gm.framing.type == SCE_GAMEFRAMING_BARS && startscene->gm.stereoflag != STEREO_DOME) { /* Letterbox */ + if((rv3d->persp == RV3D_CAMOB) && + (startscene->gm.framing.type == SCE_GAMEFRAMING_BARS) && + (startscene->gm.stereoflag != STEREO_DOME)) + { + /* Letterbox */ rctf cam_framef; ED_view3d_calc_camera_border(startscene, ar, CTX_wm_view3d(C), rv3d, &cam_framef, FALSE); cam_frame.xmin = cam_framef.xmin + ar->winrct.xmin; @@ -1835,3 +1863,42 @@ rv3d->persmat[2][3]*co[2]) ) * rv3d->pixsize; } + +/* view matrix properties utilities */ + +void ED_view3d_operator_properties_viewmat(wmOperatorType *ot) +{ + PropertyRNA *prop; + + prop = RNA_def_int(ot->srna, "region_width", 0, 0, INT_MAX, "Region Width", "", 0, INT_MAX); + RNA_def_property_flag(prop, PROP_HIDDEN); + + prop = RNA_def_int(ot->srna, "region_height", 0, 0, INT_MAX, "Region height", "", 0, INT_MAX); + RNA_def_property_flag(prop, PROP_HIDDEN); + + prop = RNA_def_float_matrix(ot->srna, "perspective_matrix", 4, 4, NULL, 0.0f, 0.0f, "", "Perspective Matrix", 0.0f, 0.0f); + RNA_def_property_flag(prop, PROP_HIDDEN); +} + +void ED_view3d_operator_properties_viewmat_set(bContext *C, wmOperator *op) +{ + ARegion *ar= CTX_wm_region(C); + RegionView3D *rv3d= ED_view3d_context_rv3d(C); + + if(!RNA_struct_property_is_set(op->ptr, "region_width")) + RNA_int_set(op->ptr, "region_width", ar->winx); + + if(!RNA_struct_property_is_set(op->ptr, "region_height")) + RNA_int_set(op->ptr, "region_height", ar->winy); + + if(!RNA_struct_property_is_set(op->ptr, "perspective_matrix")) + RNA_float_set_array(op->ptr, "perspective_matrix", (float *)rv3d->persmat); +} + +void ED_view3d_operator_properties_viewmat_get(wmOperator *op, int *winx, int *winy, float persmat[4][4]) +{ + *winx = RNA_int_get(op->ptr, "region_width"); + *winy = RNA_int_get(op->ptr, "region_height"); + + RNA_float_get_array(op->ptr, "perspective_matrix", (float *)persmat); +} diff -Nru blender-2.61/source/blender/editors/transform/transform.c blender-2.62/source/blender/editors/transform/transform.c --- blender-2.61/source/blender/editors/transform/transform.c 2011-12-13 19:52:13.000000000 +0000 +++ blender-2.62/source/blender/editors/transform/transform.c 2012-02-15 19:36:49.000000000 +0000 @@ -376,7 +376,8 @@ /* ************************** TRANSFORMATIONS **************************** */ -void BIF_selectOrientation(void) { +void BIF_selectOrientation(void) +{ #if 0 // TRANSFORM_FIX_ME short val; char *str_menu = BIF_menustringTransformOrientation("Orientation"); @@ -584,6 +585,9 @@ } applyMouseInput(t, &t->mouse, t->mval, t->values); + + // Snapping mouse move events + t->redraw |= handleSnapping(t, event); } /* handle modal keymap first */ @@ -1026,7 +1030,7 @@ // Numerical input events t->redraw |= handleNumInput(&(t->num), event); - // Snapping events + // Snapping key events t->redraw |= handleSnapping(t, event); } @@ -1402,18 +1406,21 @@ if (t->flag & T_MODAL) { /* save settings if not set in operator */ - if (RNA_struct_find_property(op->ptr, "proportional") && !RNA_property_is_set(op->ptr, "proportional")) { + if ( (prop = RNA_struct_find_property(op->ptr, "proportional")) && !RNA_property_is_set(op->ptr, prop)) + { if (t->obedit) ts->proportional = proportional; else ts->proportional_objects = (proportional != PROP_EDIT_OFF); } - if (RNA_struct_find_property(op->ptr, "proportional_size") && !RNA_property_is_set(op->ptr, "proportional_size")) { + if ( (prop = RNA_struct_find_property(op->ptr, "proportional_size")) && !RNA_property_is_set(op->ptr, prop)) + { ts->proportional_size = t->prop_size; } - - if (RNA_struct_find_property(op->ptr, "proportional_edit_falloff") && !RNA_property_is_set(op->ptr, "proportional_edit_falloff")) { + + if ( (prop = RNA_struct_find_property(op->ptr, "proportional_edit_falloff")) && !RNA_property_is_set(op->ptr, prop)) + { ts->prop_mode = t->prop_mode; } @@ -1424,8 +1431,9 @@ ts->snap_flag &= ~SCE_SNAP; } - if(t->spacetype == SPACE_VIEW3D) { - if (RNA_struct_find_property(op->ptr, "constraint_orientation") && !RNA_property_is_set(op->ptr, "constraint_orientation")) { + if (t->spacetype == SPACE_VIEW3D) { + if ( (prop = RNA_struct_find_property(op->ptr, "constraint_orientation")) && !RNA_property_is_set(op->ptr, prop)) + { View3D *v3d = t->view; v3d->twmode = t->current_orientation; @@ -1440,17 +1448,17 @@ RNA_float_set(op->ptr, "proportional_size", t->prop_size); } - if (RNA_struct_find_property(op->ptr, "axis")) + if ((prop = RNA_struct_find_property(op->ptr, "axis"))) { - RNA_float_set_array(op->ptr, "axis", t->axis); + RNA_property_float_set_array(op->ptr, prop, t->axis); } - if (RNA_struct_find_property(op->ptr, "mirror")) + if ((prop = RNA_struct_find_property(op->ptr, "mirror"))) { - RNA_boolean_set(op->ptr, "mirror", t->flag & T_MIRROR); + RNA_property_boolean_set(op->ptr, prop, t->flag & T_MIRROR); } - if (RNA_struct_find_property(op->ptr, "constraint_axis")) + if ((prop = RNA_struct_find_property(op->ptr, "constraint_axis"))) { /* constraint orientation can be global, event if user selects something else * so use the orientation in the constraint if set @@ -1474,7 +1482,7 @@ } } - RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis); + RNA_property_boolean_set_array(op->ptr, prop, constraint_axis); } } @@ -1482,6 +1490,7 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int mode) { int options = 0; + PropertyRNA *prop; t->context = C; @@ -1489,9 +1498,12 @@ t->state = TRANS_STARTING; - if(RNA_struct_find_property(op->ptr, "texture_space")) - if(RNA_boolean_get(op->ptr, "texture_space")) + if ( (prop = RNA_struct_find_property(op->ptr, "texture_space")) && RNA_property_is_set(op->ptr, prop)) + { + if(RNA_property_boolean_get(op->ptr, prop)) { options |= CTX_TEXTURE; + } + } t->options = options; @@ -1698,10 +1710,9 @@ /* overwrite initial values if operator supplied a non-null vector */ - if (RNA_property_is_set(op->ptr, "value")) + if ( (prop = RNA_struct_find_property(op->ptr, "value")) && RNA_property_is_set(op->ptr, prop)) { float values[4]= {0}; /* incase value isn't length 4, avoid uninitialized memory */ - PropertyRNA *prop= RNA_struct_find_property(op->ptr, "value"); if(RNA_property_array_check(prop)) { RNA_float_get_array(op->ptr, "value", values); @@ -1715,19 +1726,19 @@ } /* Transformation axis from operator */ - if (RNA_struct_find_property(op->ptr, "axis") && RNA_property_is_set(op->ptr, "axis")) + if ((prop = RNA_struct_find_property(op->ptr, "axis")) && RNA_property_is_set(op->ptr, prop)) { - RNA_float_get_array(op->ptr, "axis", t->axis); + RNA_property_float_get_array(op->ptr, prop, t->axis); normalize_v3(t->axis); copy_v3_v3(t->axis_orig, t->axis); } /* Constraint init from operator */ - if (RNA_struct_find_property(op->ptr, "constraint_axis") && RNA_property_is_set(op->ptr, "constraint_axis")) + if ((prop = RNA_struct_find_property(op->ptr, "constraint_axis")) && RNA_property_is_set(op->ptr, prop)) { int constraint_axis[3]; - RNA_boolean_get_array(op->ptr, "constraint_axis", constraint_axis); + RNA_property_boolean_get_array(op->ptr, prop, constraint_axis); if (constraint_axis[0] || constraint_axis[1] || constraint_axis[2]) { @@ -2547,16 +2558,17 @@ t->num.increment = t->snap[1]; } -static void headerResize(TransInfo *t, float vec[3], char *str) { +static void headerResize(TransInfo *t, float vec[3], char *str) +{ char tvec[60]; char *spos= str; if (hasNumInput(&t->num)) { outputNumInput(&(t->num), tvec); } else { - sprintf(&tvec[0], "%.4f", vec[0]); - sprintf(&tvec[20], "%.4f", vec[1]); - sprintf(&tvec[40], "%.4f", vec[2]); + BLI_snprintf(&tvec[0], 20, "%.4f", vec[0]); + BLI_snprintf(&tvec[20], 20, "%.4f", vec[1]); + BLI_snprintf(&tvec[40], 20, "%.4f", vec[2]); } if (t->con.mode & CON_APPLY) { @@ -2607,7 +2619,8 @@ } -static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) { +static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) +{ float tmat[3][3], smat[3][3], center[3]; float vec[3]; @@ -2626,7 +2639,7 @@ /* local constraint shouldn't alter center */ if ((t->around == V3D_LOCAL) && ( (t->flag & (T_OBJECT|T_POSE)) || - ((t->flag & T_EDIT) && (t->settings->selectmode & SCE_SELECT_FACE)) || + ((t->flag & T_EDIT) && (t->settings->selectmode & (SCE_SELECT_EDGE|SCE_SELECT_FACE))) || (t->obedit && t->obedit->type == OB_ARMATURE)) ) { @@ -2904,7 +2917,8 @@ copy_v3_v3(t->axis_orig, t->axis); } -static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short around) { +static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short around) +{ float vec[3], totmat[3][3], smat[3][3]; float eul[3], fmat[3][3], quat[4]; float *center = t->center; @@ -2912,7 +2926,7 @@ /* local constraint shouldn't alter center */ if (around == V3D_LOCAL) { if ( (t->flag & (T_OBJECT|T_POSE)) || - (t->settings->selectmode & SCE_SELECT_FACE) || + (t->settings->selectmode & (SCE_SELECT_EDGE|SCE_SELECT_FACE)) || (t->obedit && t->obedit->type == OB_ARMATURE)) { center = td->center; @@ -3344,7 +3358,8 @@ t->num.increment = t->snap[1]; } -static void headerTranslation(TransInfo *t, float vec[3], char *str) { +static void headerTranslation(TransInfo *t, float vec[3], char *str) +{ char *spos= str; char tvec[60]; char distvec[20]; @@ -3418,7 +3433,8 @@ (void)spos; } -static void applyTranslation(TransInfo *t, float vec[3]) { +static void applyTranslation(TransInfo *t, float vec[3]) +{ TransData *td = t->data; float tvec[3]; int i; @@ -4099,7 +4115,8 @@ t->num.increment = t->snap[1]; } -static void headerBoneSize(TransInfo *t, float vec[3], char *str) { +static void headerBoneSize(TransInfo *t, float vec[3], char *str) +{ char tvec[60]; if (hasNumInput(&t->num)) { outputNumInput(&(t->num), tvec); @@ -5302,7 +5319,8 @@ sprintf(str, "Sequence Slide: %s%s", &tvec[0], t->con.text); } -static void applySeqSlide(TransInfo *t, float val[2]) { +static void applySeqSlide(TransInfo *t, float val[2]) +{ TransData *td = t->data; int i; @@ -5548,9 +5566,9 @@ /* apply snapping + frame->seconds conversions */ if (autosnap == SACTSNAP_STEP) { if (doTime) - val= floor((double)val/secf + 0.5f); + val= floorf((double)val/secf + 0.5f); else - val= floor(val + 0.5f); + val= floorf(val + 0.5f); } else { if (doTime) @@ -5826,7 +5844,8 @@ t->num.increment = t->snap[1]; } -static void headerTimeScale(TransInfo *t, char *str) { +static void headerTimeScale(TransInfo *t, char *str) +{ char tvec[60]; if (hasNumInput(&t->num)) @@ -5837,7 +5856,8 @@ sprintf(str, "ScaleX: %s", &tvec[0]); } -static void applyTimeScale(TransInfo *t) { +static void applyTimeScale(TransInfo *t) +{ Scene *scene = t->scene; TransData *td = t->data; TransData2D *td2d = t->data2d; diff -Nru blender-2.61/source/blender/editors/transform/transform_constraints.c blender-2.62/source/blender/editors/transform/transform_constraints.c --- blender-2.61/source/blender/editors/transform/transform_constraints.c 2011-12-13 19:52:13.000000000 +0000 +++ blender-2.62/source/blender/editors/transform/transform_constraints.c 2012-02-15 19:36:49.000000000 +0000 @@ -59,6 +59,7 @@ #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLI_string.h" //#include "blendef.h" // @@ -138,7 +139,8 @@ } } -static void postConstraintChecks(TransInfo *t, float vec[3], float pvec[3]) { +static void postConstraintChecks(TransInfo *t, float vec[3], float pvec[3]) +{ int i = 0; mul_m3_v3(t->con.imtx, vec); @@ -209,7 +211,8 @@ } } -static void axisProjection(TransInfo *t, float axis[3], float in[3], float out[3]) { +static void axisProjection(TransInfo *t, float axis[3], float in[3], float out[3]) +{ float norm[3], vec[3], factor, angle; float t_con_center[3]; @@ -284,7 +287,8 @@ } } -static void planeProjection(TransInfo *t, float in[3], float out[3]) { +static void planeProjection(TransInfo *t, float in[3], float out[3]) +{ float vec[3], factor, norm[3]; add_v3_v3v3(vec, in, t->con.center); @@ -547,8 +551,9 @@ /*--------------------- INTERNAL SETUP CALLS ------------------*/ -void setConstraint(TransInfo *t, float space[3][3], int mode, const char text[]) { - strncpy(t->con.text + 1, text, 48); +void setConstraint(TransInfo *t, float space[3][3], int mode, const char text[]) +{ + BLI_strncpy(t->con.text + 1, text, sizeof(t->con.text) - 1); copy_m3_m3(t->con.mtx, space); t->con.mode = mode; getConstraintMatrix(t); @@ -562,7 +567,8 @@ t->redraw = 1; } -void setLocalConstraint(TransInfo *t, int mode, const char text[]) { +void setLocalConstraint(TransInfo *t, int mode, const char text[]) +{ if (t->flag & T_EDIT) { float obmat[3][3]; copy_m3_m4(obmat, t->scene->obedit->obmat); @@ -574,7 +580,7 @@ setConstraint(t, t->data->axismtx, mode, text); } else { - strncpy(t->con.text + 1, text, 48); + BLI_strncpy(t->con.text + 1, text, sizeof(t->con.text) - 1); copy_m3_m3(t->con.mtx, t->data->axismtx); t->con.mode = mode; getConstraintMatrix(t); @@ -593,38 +599,39 @@ /* Set the constraint according to the user defined orientation - ftext is a format string passed to sprintf. It will add the name of + ftext is a format string passed to BLI_snprintf. It will add the name of the orientation where %s is (logically). */ -void setUserConstraint(TransInfo *t, short orientation, int mode, const char ftext[]) { +void setUserConstraint(TransInfo *t, short orientation, int mode, const char ftext[]) +{ char text[40]; switch(orientation) { case V3D_MANIP_GLOBAL: { float mtx[3][3]= MAT3_UNITY; - sprintf(text, ftext, "global"); + BLI_snprintf(text, sizeof(text), ftext, "global"); setConstraint(t, mtx, mode, text); } break; case V3D_MANIP_LOCAL: - sprintf(text, ftext, "local"); + BLI_snprintf(text, sizeof(text), ftext, "local"); setLocalConstraint(t, mode, text); break; case V3D_MANIP_NORMAL: - sprintf(text, ftext, "normal"); + BLI_snprintf(text, sizeof(text), ftext, "normal"); setConstraint(t, t->spacemtx, mode, text); break; case V3D_MANIP_VIEW: - sprintf(text, ftext, "view"); + BLI_snprintf(text, sizeof(text), ftext, "view"); setConstraint(t, t->spacemtx, mode, text); break; case V3D_MANIP_GIMBAL: - sprintf(text, ftext, "gimbal"); + BLI_snprintf(text, sizeof(text), ftext, "gimbal"); setConstraint(t, t->spacemtx, mode, text); break; default: /* V3D_MANIP_CUSTOM */ - sprintf(text, ftext, t->spacename); + BLI_snprintf(text, sizeof(text), ftext, t->spacename); setConstraint(t, t->spacemtx, mode, text); break; } @@ -744,7 +751,8 @@ } } -static void drawObjectConstraint(TransInfo *t) { +static void drawObjectConstraint(TransInfo *t) +{ int i; TransData * td = t->data; @@ -781,13 +789,15 @@ /*--------------------- START / STOP CONSTRAINTS ---------------------- */ -void startConstraint(TransInfo *t) { +void startConstraint(TransInfo *t) +{ t->con.mode |= CON_APPLY; *t->con.text = ' '; t->num.idx_max = MIN2(getConstraintSpaceDimension(t) - 1, t->idx_max); } -void stopConstraint(TransInfo *t) { +void stopConstraint(TransInfo *t) +{ t->con.mode &= ~(CON_APPLY|CON_SELECT); *t->con.text = '\0'; t->num.idx_max = t->idx_max; @@ -836,7 +846,8 @@ t->con.applyRot = applyAxisConstraintRot; } -void selectConstraint(TransInfo *t) { +void selectConstraint(TransInfo *t) +{ if (t->con.mode & CON_SELECT) { setNearestAxis(t); startConstraint(t); @@ -864,11 +875,11 @@ /* no correction needed... just use whichever one is lower */ if ( abs(t->mval[0]-t->con.imval[0]) < abs(t->mval[1]-t->con.imval[1]) ) { t->con.mode |= CON_AXIS1; - sprintf(t->con.text, " along Y axis"); + BLI_snprintf(t->con.text, sizeof(t->con.text), " along Y axis"); } else { t->con.mode |= CON_AXIS0; - sprintf(t->con.text, " along X axis"); + BLI_snprintf(t->con.text, sizeof(t->con.text), " along X axis"); } } @@ -919,31 +930,31 @@ if (len[0] <= len[1] && len[0] <= len[2]) { if (t->modifiers & MOD_CONSTRAINT_PLANE) { t->con.mode |= (CON_AXIS1|CON_AXIS2); - sprintf(t->con.text, " locking %s X axis", t->spacename); + BLI_snprintf(t->con.text, sizeof(t->con.text), " locking %s X axis", t->spacename); } else { t->con.mode |= CON_AXIS0; - sprintf(t->con.text, " along %s X axis", t->spacename); + BLI_snprintf(t->con.text, sizeof(t->con.text), " along %s X axis", t->spacename); } } else if (len[1] <= len[0] && len[1] <= len[2]) { if (t->modifiers & MOD_CONSTRAINT_PLANE) { t->con.mode |= (CON_AXIS0|CON_AXIS2); - sprintf(t->con.text, " locking %s Y axis", t->spacename); + BLI_snprintf(t->con.text, sizeof(t->con.text), " locking %s Y axis", t->spacename); } else { t->con.mode |= CON_AXIS1; - sprintf(t->con.text, " along %s Y axis", t->spacename); + BLI_snprintf(t->con.text, sizeof(t->con.text), " along %s Y axis", t->spacename); } } else if (len[2] <= len[1] && len[2] <= len[0]) { if (t->modifiers & MOD_CONSTRAINT_PLANE) { t->con.mode |= (CON_AXIS0|CON_AXIS1); - sprintf(t->con.text, " locking %s Z axis", t->spacename); + BLI_snprintf(t->con.text, sizeof(t->con.text), " locking %s Z axis", t->spacename); } else { t->con.mode |= CON_AXIS2; - sprintf(t->con.text, " along %s Z axis", t->spacename); + BLI_snprintf(t->con.text, sizeof(t->con.text), " along %s Z axis", t->spacename); } } } @@ -970,7 +981,8 @@ /*-------------- HELPER FUNCTIONS ----------------*/ -char constraintModeToChar(TransInfo *t) { +char constraintModeToChar(TransInfo *t) +{ if ((t->con.mode & CON_APPLY)==0) { return '\0'; } @@ -990,7 +1002,8 @@ } -int isLockConstraint(TransInfo *t) { +int isLockConstraint(TransInfo *t) +{ int mode = t->con.mode; if ( (mode & (CON_AXIS0|CON_AXIS1)) == (CON_AXIS0|CON_AXIS1)) diff -Nru blender-2.61/source/blender/editors/transform/transform_conversions.c blender-2.62/source/blender/editors/transform/transform_conversions.c --- blender-2.61/source/blender/editors/transform/transform_conversions.c 2011-12-13 19:52:13.000000000 +0000 +++ blender-2.62/source/blender/editors/transform/transform_conversions.c 2012-02-15 19:36:49.000000000 +0000 @@ -118,7 +118,8 @@ /* ************************** Functions *************************** */ -static void qsort_trans_data(TransInfo *t, TransData *head, TransData *tail, TransData *temp) { +static void qsort_trans_data(TransInfo *t, TransData *head, TransData *tail, TransData *temp) +{ TransData *ihead = head; TransData *itail = tail; *temp = *head; @@ -165,7 +166,8 @@ } } -void sort_trans_data_dist(TransInfo *t) { +void sort_trans_data_dist(TransInfo *t) +{ TransData temp; TransData *start = t->data; int i = 1; @@ -441,14 +443,14 @@ offs_bone[3][0]= offs_bone[3][1]= offs_bone[3][2]= 0.0f; mul_m4_v3(parchan->parent->pose_mat, rmat[3]); - mul_m4_m4m4(tmat, offs_bone, rmat); + mult_m4_m4m4(tmat, rmat, offs_bone); } else if(parchan->bone->flag & BONE_NO_SCALE) { - mul_m4_m4m4(tmat, offs_bone, parchan->parent->pose_mat); + mult_m4_m4m4(tmat, parchan->parent->pose_mat, offs_bone); normalize_m4(tmat); } else - mul_m4_m4m4(tmat, offs_bone, parchan->parent->pose_mat); + mult_m4_m4m4(tmat, parchan->parent->pose_mat, offs_bone); invert_m4_m4(imat, tmat); } @@ -459,7 +461,7 @@ invert_m4_m4(imat, tmat); } /* result matrix */ - mul_m4_m4m4(rmat, parchan->pose_mat, imat); + mult_m4_m4m4(rmat, imat, parchan->pose_mat); /* apply and decompose, doesn't work for constraints or non-uniform scale well */ { @@ -513,7 +515,7 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, TransData *td) { Bone *bone= pchan->bone; - float pmat[3][3], omat[3][3], bmat[3][3]; + float pmat[3][3], omat[3][3]; float cmat[3][3], tmat[3][3]; float vec[3]; @@ -567,39 +569,71 @@ copy_qt_qt(td->ext->iquat, pchan->quat); } td->ext->rotOrder= pchan->rotmode; - + /* proper way to get parent transform + own transform + constraints transform */ copy_m3_m4(omat, ob->obmat); + /* New code, using "generic" pchan_to_pose_mat(). */ + { + float rotscale_mat[4][4], loc_mat[4][4]; + + pchan_to_pose_mat(pchan, rotscale_mat, loc_mat); + if (t->mode == TFM_TRANSLATION) + copy_m3_m4(pmat, loc_mat); + else + copy_m3_m4(pmat, rotscale_mat); + + if (constraints_list_needinv(t, &pchan->constraints)) { + copy_m3_m4(tmat, pchan->constinv); + invert_m3_m3(cmat, tmat); + mul_serie_m3(td->mtx, pmat, omat, cmat, NULL,NULL,NULL,NULL,NULL); + } + else + mul_serie_m3(td->mtx, pmat, omat, NULL, NULL,NULL,NULL,NULL,NULL); + } + + /* XXX Old code. Will remove it later. */ +#if 0 if (ELEM(t->mode, TFM_TRANSLATION, TFM_RESIZE) && (pchan->bone->flag & BONE_NO_LOCAL_LOCATION)) unit_m3(bmat); else copy_m3_m3(bmat, pchan->bone->bone_mat); if (pchan->parent) { - if(pchan->bone->flag & BONE_HINGE) + if(pchan->bone->flag & BONE_HINGE) { copy_m3_m4(pmat, pchan->parent->bone->arm_mat); - else + if(!(pchan->bone->flag & BONE_NO_SCALE)) { + float tsize[3], tsmat[3][3]; + mat4_to_size(tsize, pchan->parent->pose_mat); + size_to_mat3(tsmat, tsize); + mul_m3_m3m3(pmat, tsmat, pmat); + } + } + else { copy_m3_m4(pmat, pchan->parent->pose_mat); + if(pchan->bone->flag & BONE_NO_SCALE) + normalize_m3(pmat); + } if (constraints_list_needinv(t, &pchan->constraints)) { copy_m3_m4(tmat, pchan->constinv); invert_m3_m3(cmat, tmat); - mul_serie_m3(td->mtx, bmat, pmat, omat, cmat, NULL,NULL,NULL,NULL); // dang mulserie swaps args + mul_serie_m3(td->mtx, bmat, pmat, omat, cmat, NULL,NULL,NULL,NULL); } else - mul_serie_m3(td->mtx, bmat, pmat, omat, NULL,NULL,NULL,NULL,NULL); // dang mulserie swaps args + mul_serie_m3(td->mtx, bmat, pmat, omat, NULL,NULL,NULL,NULL,NULL); } else { if (constraints_list_needinv(t, &pchan->constraints)) { copy_m3_m4(tmat, pchan->constinv); invert_m3_m3(cmat, tmat); - mul_serie_m3(td->mtx, bmat, omat, cmat, NULL,NULL,NULL,NULL,NULL); // dang mulserie swaps args + mul_serie_m3(td->mtx, bmat, omat, cmat, NULL,NULL,NULL,NULL,NULL); } else - mul_m3_m3m3(td->mtx, omat, bmat); // Mat3MulMat3 has swapped args! + mul_m3_m3m3(td->mtx, omat, bmat); } +# endif invert_m3_m3(td->smtx, td->mtx); @@ -1326,7 +1360,8 @@ /* ********************* curve/surface ********* */ -static void calc_distanceCurveVerts(TransData *head, TransData *tail) { +static void calc_distanceCurveVerts(TransData *head, TransData *tail) +{ TransData *td, *td_near = NULL; for (td = head; td<=tail; td++) { if (td->flag & TD_SELECTED) { @@ -1371,7 +1406,8 @@ } /* Utility function for getting the handle data from bezier's */ -static TransDataCurveHandleFlags *initTransDataCurveHandles(TransData *td, struct BezTriple *bezt) { +static TransDataCurveHandleFlags *initTransDataCurveHandles(TransData *td, struct BezTriple *bezt) +{ TransDataCurveHandleFlags *hdata; td->flag |= TD_BEZTRIPLE; hdata = td->hdata = MEM_mallocN(sizeof(TransDataCurveHandleFlags), "CuHandle Data"); @@ -1544,8 +1580,10 @@ /* TODO - in the case of tilt and radius we can also avoid allocating the initTransDataCurveHandles * but for now just dont change handle types */ - if (ELEM(t->mode, TFM_CURVE_SHRINKFATTEN, TFM_TILT) == 0) - testhandlesNurb(nu); /* sets the handles based on their selection, do this after the data is copied to the TransData */ + if (ELEM(t->mode, TFM_CURVE_SHRINKFATTEN, TFM_TILT) == 0) { + /* sets the handles based on their selection, do this after the data is copied to the TransData */ + testhandlesNurb(nu); + } } else { TransData *head, *tail; @@ -1920,6 +1958,19 @@ } } +static void get_edge_center(float *cent, EditMesh *em, EditVert *eve) +{ + EditEdge *eed; + + for(eed= em->edges.first; eed; eed= eed->next) + if(eed->f & SELECT) + if(eed->v1==eve || eed->v2==eve) + break; + if(eed) { + mid_v3_v3v3(cent, eed->v1->co, eed->v2->co); + } +} + /* way to overwrite what data is edited with transform * static void VertsToTransData(TransData *td, EditVert *eve, BakeKey *key) */ static void VertsToTransData(TransInfo *t, TransData *td, EditMesh *em, EditVert *eve) @@ -1931,8 +1982,12 @@ td->loc = eve->co; copy_v3_v3(td->center, td->loc); - if(t->around==V3D_LOCAL && (em->selectmode & SCE_SELECT_FACE)) - get_face_center(td->center, em, eve); + if(t->around==V3D_LOCAL) { + if(em->selectmode & SCE_SELECT_FACE) + get_face_center(td->center, em, eve); + else if(em->selectmode & SCE_SELECT_EDGE) + get_edge_center(td->center, em, eve); + } copy_v3_v3(td->iloc, td->loc); // Setting normals @@ -2245,6 +2300,23 @@ seq_prev= seq; } + + if (ELEM(t->mode, TFM_SEQ_SLIDE, TFM_TIME_TRANSLATE)) { /* originally TFM_TIME_EXTEND, transform changes */ + /* Special annoying case here, need to calc metas with TFM_TIME_EXTEND only */ + + /* calc all meta's then effects [#27953] */ + for (seq = seqbasep->first; seq; seq = seq->next) { + if (seq->type == SEQ_META && seq->flag & SELECT) { + calc_sequence(t->scene, seq); + } + } + for (seq = seqbasep->first; seq; seq = seq->next) { + if (seq->seq1 || seq->seq2 || seq->seq3) { + calc_sequence(t->scene, seq); + } + } + } + /* need to do the overlap check in a new loop otherwise adjacent strips * will not be updated and we'll get false positives */ seq_prev= NULL; @@ -2264,17 +2336,6 @@ } seq_prev= seq; } - - if (t->mode == TFM_SEQ_SLIDE) { /* originally TFM_TIME_EXTEND, transform changes */ - /* Special annoying case here, need to calc metas with TFM_TIME_EXTEND only */ - seq= seqbasep->first; - - while(seq) { - if (seq->type == SEQ_META && seq->flag & SELECT) - calc_sequence(t->scene, seq); - seq= seq->next; - } - } } /* ********************* UV ****************** */ @@ -3444,7 +3505,10 @@ * then check if we're using auto-handles. * - If so, change them auto-handles to aligned handles so that handles get affected too */ - if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM) && ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM) && ELEM(t->mode, TFM_ROTATION, TFM_RESIZE)) { + if ( ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM) && + ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM) && + ELEM(t->mode, TFM_ROTATION, TFM_RESIZE)) + { if (hdata && (sel1) && (sel3)) { bezt->h1= HD_ALIGN; bezt->h2= HD_ALIGN; @@ -3741,8 +3805,8 @@ Scene * scene= t->scene; int cfra= CFRA; - int left= seq_tx_get_final_left(seq, 0); - int right= seq_tx_get_final_right(seq, 0); + int left= seq_tx_get_final_left(seq, 1); + int right= seq_tx_get_final_right(seq, 1); if (seq->depth == 0 && ((seq->flag & SELECT) == 0 || (seq->flag & SEQ_LOCK))) { *recursive= 0; @@ -3842,7 +3906,7 @@ -static int SeqTransCount(TransInfo *t, ListBase *seqbase, int depth) +static int SeqTransCount(TransInfo *t, Sequence *parent, ListBase *seqbase, int depth) { Sequence *seq; int tot= 0, recursive, count, flag; @@ -3850,11 +3914,15 @@ for (seq= seqbase->first; seq; seq= seq->next) { seq->depth= depth; + /* seq->tmp is used by seq_tx_get_final_{left,right} to check sequence's range and clamp to it if needed. + * it's first place where digging into sequences tree, so store link to parent here */ + seq->tmp = parent; + SeqTransInfo(t, seq, &recursive, &count, &flag); /* ignore the flag */ tot += count; if (recursive) { - tot += SeqTransCount(t, &seq->seqbase, depth+1); + tot += SeqTransCount(t, seq, &seq->seqbase, depth+1); } } @@ -4140,7 +4208,10 @@ int i; for(i=0; i<3; i++) { seq_user= *((&seq->seq1) + i); - if (seq_user && (seq_user->flag & SELECT) && !(seq_user->flag & SEQ_LOCK) && !(seq_user->flag & (SEQ_LEFTSEL|SEQ_RIGHTSEL))) { + if ( seq_user && (seq_user->flag & SELECT) && + !(seq_user->flag & SEQ_LOCK) && + !(seq_user->flag & (SEQ_LEFTSEL|SEQ_RIGHTSEL))) + { seq->flag |= SELECT; } } @@ -4149,7 +4220,7 @@ } #endif - count = SeqTransCount(t, ed->seqbasep, 0); + count = SeqTransCount(t, NULL, ed->seqbasep, 0); /* allocate memory for data */ t->total= count; @@ -4196,6 +4267,7 @@ if (con->type == CONSTRAINT_TYPE_CHILDOF) return 1; if (con->type == CONSTRAINT_TYPE_FOLLOWPATH) return 1; if (con->type == CONSTRAINT_TYPE_CLAMPTO) return 1; + if (con->type == CONSTRAINT_TYPE_OBJECTSOLVER) return 1; /* constraints that require this only under special conditions */ if (con->type == CONSTRAINT_TYPE_ROTLIKE) { @@ -4439,7 +4511,8 @@ /* mark all children */ for (base= scene->base.first; base; base= base->next) { /* all base not already selected or marked that is editable */ - if ((base->object->flag & (SELECT|BA_TRANSFORM_CHILD|BA_TRANSFORM_PARENT)) == 0 && BASE_EDITABLE_BGMODE(v3d, scene, base)) + if ( (base->object->flag & (SELECT|BA_TRANSFORM_CHILD|BA_TRANSFORM_PARENT)) == 0 && + (BASE_EDITABLE_BGMODE(v3d, scene, base))) { mark_children(base->object); } @@ -4450,7 +4523,8 @@ Object *ob= base->object; /* if base is not selected, not a parent of selection or not a child of selection and it is editable */ - if ((ob->flag & (SELECT|BA_TRANSFORM_CHILD|BA_TRANSFORM_PARENT)) == 0 && BASE_EDITABLE_BGMODE(v3d, scene, base)) + if ( (ob->flag & (SELECT|BA_TRANSFORM_CHILD|BA_TRANSFORM_PARENT)) == 0 && + (BASE_EDITABLE_BGMODE(v3d, scene, base))) { /* used for flush, depgraph will change recalcs if needed :) */ @@ -4526,7 +4600,9 @@ if (adt && adt->action) { for (fcu= adt->action->curves.first; fcu; fcu= fcu->next) { fcu->flag &= ~FCURVE_SELECTED; - insert_keyframe(reports, id, adt->action, ((fcu->grp)?(fcu->grp->name):(NULL)), fcu->rna_path, fcu->array_index, cfra, flag); + insert_keyframe(reports, id, adt->action, + (fcu->grp ? fcu->grp->name : NULL), + fcu->rna_path, fcu->array_index, cfra, flag); } } } @@ -5044,8 +5120,12 @@ DAG_id_tag_update(&ob->id, OB_RECALC_DATA); } - else if(t->scene->basact && (ob = t->scene->basact->object) && (ob->mode & OB_MODE_PARTICLE_EDIT) && PE_get_current(t->scene, ob)) { - ; + else if ( (t->scene->basact) && + (ob = t->scene->basact->object) && + (ob->mode & OB_MODE_PARTICLE_EDIT) && + PE_get_current(t->scene, ob)) + { + /* do nothing */ ; } else { /* Objects */ int i, recalcObPaths=0; @@ -5259,7 +5339,15 @@ /* *** CLIP EDITOR *** */ +enum { + transDataTracking_ModeTracks = 0, + transDataTracking_ModeCurves = 1, +} transDataTracking_Mode; + typedef struct TransDataTracking { + int mode, flag; + + /* tracks transformation from main window */ int area; float *relative, *loc; float soffset[2], srelative[2]; @@ -5268,6 +5356,10 @@ float (*smarkers)[2]; int markersnr; MovieTrackingMarker *markers; + + /* marker transformation from curves editor */ + float *prev_pos, scale; + short coord; } TransDataTracking; static void markerToTransDataInit(TransData *td, TransData2D *td2d, @@ -5275,6 +5367,8 @@ { int anchor = area==TRACK_AREA_POINT && off; + tdt->mode = transDataTracking_ModeTracks; + if(anchor) { td2d->loc[0] = rel[0]; /* hold original location */ td2d->loc[1] = rel[1]; @@ -5329,8 +5423,7 @@ { MovieTrackingMarker *marker= BKE_tracking_ensure_marker(track, sc->user.framenr); - track->transflag= marker->flag; - + tdt->flag= marker->flag; marker->flag&= ~(MARKER_DISABLED|MARKER_TRACKED); markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_POINT, track->offset, marker->pos, track->offset); @@ -5359,37 +5452,31 @@ } } -static void createTransTrackingData(bContext *C, TransInfo *t) +static void createTransTrackingTracksData(bContext *C, TransInfo *t) { TransData *td; TransData2D *td2d; SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); + ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking); MovieTrackingTrack *track; MovieTrackingMarker *marker; TransDataTracking *tdt; int framenr = sc->user.framenr; - if(!clip || !BKE_movieclip_has_frame(clip, &sc->user)) { - t->total = 0; - return; - } - /* count */ t->total = 0; - track = clip->tracking.tracks.first; + track = tracksbase->first; while(track) { if(TRACK_VIEW_SELECTED(sc, track) && (track->flag&TRACK_LOCKED)==0) { marker= BKE_tracking_get_marker(track, framenr); - if(marker) { - t->total++; /* offset */ + t->total++; /* offset */ - if(track->flag&SELECT) t->total++; - if(track->pat_flag&SELECT) t->total+= 2; - if(track->search_flag&SELECT) t->total+= 2; - } + if(track->flag&SELECT) t->total++; + if(track->pat_flag&SELECT) t->total+= 2; + if(track->search_flag&SELECT) t->total+= 2; } track = track->next; @@ -5405,7 +5492,7 @@ t->customFree= transDataTrackingFree; /* create actual data */ - track = clip->tracking.tracks.first; + track = tracksbase->first; while(track) { if(TRACK_VIEW_SELECTED(sc, track) && (track->flag&TRACK_LOCKED)==0) { marker= BKE_tracking_get_marker(track, framenr); @@ -5439,6 +5526,197 @@ } } +static void markerToTransCurveDataInit(TransData *td, TransData2D *td2d, TransDataTracking *tdt, + MovieTrackingMarker *marker, MovieTrackingMarker *prev_marker, + short coord, float size) +{ + float frames_delta = (marker->framenr - prev_marker->framenr); + + tdt->flag = marker->flag; + marker->flag &= ~MARKER_TRACKED; + + tdt->mode = transDataTracking_ModeCurves; + tdt->coord = coord; + tdt->scale = 1.0f / size * frames_delta; + tdt->prev_pos = prev_marker->pos; + + /* calculate values depending on marker's speed */ + td2d->loc[0] = marker->framenr; + td2d->loc[1] = (marker->pos[coord] - prev_marker->pos[coord]) * size / frames_delta; + td2d->loc[2] = 0.0f; + + td2d->loc2d = marker->pos; /* current location */ + + td->flag = 0; + td->loc = td2d->loc; + VECCOPY(td->center, td->loc); + VECCOPY(td->iloc, td->loc); + + memset(td->axismtx, 0, sizeof(td->axismtx)); + td->axismtx[2][2] = 1.0f; + + td->ext= NULL; td->val= NULL; + + td->flag |= TD_SELECTED; + td->dist= 0.0; + + unit_m3(td->mtx); + unit_m3(td->smtx); +} + +static void createTransTrackingCurvesData(bContext *C, TransInfo *t) +{ + TransData *td; + TransData2D *td2d; + SpaceClip *sc = CTX_wm_space_clip(C); + MovieClip *clip = ED_space_clip(sc); + ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking); + MovieTrackingTrack *track; + MovieTrackingMarker *marker, *prev_marker; + TransDataTracking *tdt; + int i, width, height; + + BKE_movieclip_get_size(clip, &sc->user, &width, &height); + + /* count */ + t->total = 0; + + track = tracksbase->first; + while(track) { + if(TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED)==0) { + for(i = 1; i < track->markersnr; i++) { + marker = &track->markers[i]; + prev_marker = &track->markers[i-1]; + + if((marker->flag & MARKER_DISABLED) || (prev_marker->flag & MARKER_DISABLED)) + continue; + + if(marker->flag & MARKER_GRAPH_SEL_X) + t->total += 1; + + if(marker->flag & MARKER_GRAPH_SEL_Y) + t->total += 1; + } + } + + track = track->next; + } + + if(t->total==0) + return; + + td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransTracking TransData"); + td2d = t->data2d = MEM_callocN(t->total*sizeof(TransData2D), "TransTracking TransData2D"); + tdt = t->customData = MEM_callocN(t->total*sizeof(TransDataTracking), "TransTracking TransDataTracking"); + + t->customFree = transDataTrackingFree; + + /* create actual data */ + track = tracksbase->first; + while(track) { + if(TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED)==0) { + for(i = 1; i < track->markersnr; i++) { + marker = &track->markers[i]; + prev_marker = &track->markers[i-1]; + + if((marker->flag & MARKER_DISABLED) || (prev_marker->flag & MARKER_DISABLED)) + continue; + + if(marker->flag & MARKER_GRAPH_SEL_X) { + markerToTransCurveDataInit(td, td2d, tdt, marker, &track->markers[i-1], 0, width); + td += 1; + td2d += 1; + tdt += 1; + } + + if(marker->flag & MARKER_GRAPH_SEL_Y) { + markerToTransCurveDataInit(td, td2d, tdt, marker, &track->markers[i-1], 1, height); + + td += 1; + td2d += 1; + tdt += 1; + } + } + } + + track = track->next; + } +} + +static void createTransTrackingData(bContext *C, TransInfo *t) +{ + ARegion *ar = CTX_wm_region(C); + SpaceClip *sc = CTX_wm_space_clip(C); + MovieClip *clip = ED_space_clip(sc); + + t->total = 0; + + if(!clip || !BKE_movieclip_has_frame(clip, &sc->user)) + return; + + if(!ELEM(t->mode, TFM_RESIZE, TFM_TRANSLATION)) + return; + + if(ar->regiontype == RGN_TYPE_PREVIEW) { + /* transformation was called from graph editor */ + createTransTrackingCurvesData(C, t); + } + else { + createTransTrackingTracksData(C, t); + } +} + +static void cancelTransTracking(TransInfo *t) +{ + TransDataTracking *tdt = t->customData; + SpaceClip *sc= t->sa->spacedata.first; + MovieClip *clip= ED_space_clip(sc); + ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking); + MovieTrackingTrack *track; + MovieTrackingMarker *marker; + int a, framenr = sc->user.framenr; + + if(tdt->mode == transDataTracking_ModeTracks) { + track = tracksbase->first; + while(track) { + if(TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED)==0) { + marker = BKE_tracking_get_marker(track, framenr); + marker->flag = tdt->flag; + + tdt++; + + if(track->flag&SELECT) tdt++; + if(track->pat_flag&SELECT) tdt += 2; + if(track->search_flag&SELECT) tdt += 2; + } + + track = track->next; + } + } + else if(tdt->mode == transDataTracking_ModeCurves) { + MovieTrackingMarker *prev_marker; + + track = tracksbase->first; + while(track) { + if(TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED)==0) { + for(a = 1; a < track->markersnr; a++) { + marker = &track->markers[a]; + prev_marker = &track->markers[a-1]; + + if((marker->flag & MARKER_DISABLED) || (prev_marker->flag & MARKER_DISABLED)) + continue; + + if(marker->flag & (MARKER_GRAPH_SEL_X|MARKER_GRAPH_SEL_Y)) { + marker->flag = tdt->flag; + } + } + } + + track = track->next; + } + } +} + void flushTransTracking(TransInfo *t) { TransData *td; @@ -5446,36 +5724,44 @@ TransDataTracking *tdt; int a; + if(t->state == TRANS_CANCEL) + cancelTransTracking(t); + /* flush to 2d vector from internally used 3d vector */ for(a=0, td= t->data, td2d= t->data2d, tdt= t->customData; atotal; a++, td2d++, td++, tdt++) { - if(t->flag&T_ALT_TRANSFORM) { - if(tdt->area==TRACK_AREA_POINT && tdt->relative) { - float d[2], d2[2]; + if(tdt->mode == transDataTracking_ModeTracks) { + if(t->flag&T_ALT_TRANSFORM) { + if(tdt->area==TRACK_AREA_POINT && tdt->relative) { + float d[2], d2[2]; - if(!tdt->smarkers) { - tdt->smarkers= MEM_callocN(sizeof(*tdt->smarkers)*tdt->markersnr, "flushTransTracking markers"); - for(a= 0; amarkersnr; a++) - copy_v2_v2(tdt->smarkers[a], tdt->markers[a].pos); - } + if(!tdt->smarkers) { + tdt->smarkers= MEM_callocN(sizeof(*tdt->smarkers)*tdt->markersnr, "flushTransTracking markers"); + for(a= 0; amarkersnr; a++) + copy_v2_v2(tdt->smarkers[a], tdt->markers[a].pos); + } - sub_v2_v2v2(d, td2d->loc, tdt->soffset); - sub_v2_v2(d, tdt->srelative); + sub_v2_v2v2(d, td2d->loc, tdt->soffset); + sub_v2_v2(d, tdt->srelative); - sub_v2_v2v2(d2, td2d->loc, tdt->srelative); + sub_v2_v2v2(d2, td2d->loc, tdt->srelative); - for(a= 0; amarkersnr; a++) - add_v2_v2v2(tdt->markers[a].pos, tdt->smarkers[a], d2); + for(a= 0; amarkersnr; a++) + add_v2_v2v2(tdt->markers[a].pos, tdt->smarkers[a], d2); - negate_v2_v2(td2d->loc2d, d); + negate_v2_v2(td2d->loc2d, d); + } } - } - if(tdt->area!=TRACK_AREA_POINT || tdt->relative==0) { - td2d->loc2d[0] = td2d->loc[0]; - td2d->loc2d[1] = td2d->loc[1]; + if(tdt->area!=TRACK_AREA_POINT || tdt->relative==0) { + td2d->loc2d[0] = td2d->loc[0]; + td2d->loc2d[1] = td2d->loc[1]; - if(tdt->relative) - sub_v2_v2(td2d->loc2d, tdt->relative); + if(tdt->relative) + sub_v2_v2(td2d->loc2d, tdt->relative); + } + } + else if(tdt->mode == transDataTracking_ModeCurves) { + td2d->loc2d[tdt->coord] = tdt->prev_pos[tdt->coord] + td2d->loc[1] * tdt->scale; } } } diff -Nru blender-2.61/source/blender/editors/transform/transform_generics.c blender-2.62/source/blender/editors/transform/transform_generics.c --- blender-2.61/source/blender/editors/transform/transform_generics.c 2011-12-13 19:52:13.000000000 +0000 +++ blender-2.62/source/blender/editors/transform/transform_generics.c 2012-02-15 19:36:49.000000000 +0000 @@ -171,7 +171,7 @@ float obinv[4][4]; invert_m4_m4(obinv, mmd->mirror_ob->obmat); - mul_m4_m4m4(mtx, ob->obmat, obinv); + mult_m4_m4m4(mtx, obinv, ob->obmat); invert_m4_m4(imtx, mtx); } @@ -641,26 +641,14 @@ { SpaceClip *sc= t->sa->spacedata.first; MovieClip *clip= ED_space_clip(sc); + ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking); MovieTrackingTrack *track; - if(t->state == TRANS_CANCEL) { - track= clip->tracking.tracks.first; - while(track) { - if(TRACK_VIEW_SELECTED(sc, track)) { - MovieTrackingMarker *marker= BKE_tracking_ensure_marker(track, sc->user.framenr); - - marker->flag= track->transflag; - } - - track= track->next; - } - } - flushTransTracking(t); - track= clip->tracking.tracks.first; + track= tracksbase->first; while(track) { - if(TRACK_VIEW_SELECTED(sc, track)) { + if(TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED)==0) { if (t->mode == TFM_TRANSLATION) { if(TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) BKE_tracking_clamp_track(track, CLAMP_PAT_POS); @@ -1076,7 +1064,7 @@ if(v3d->flag & V3D_ALIGN) t->flag |= T_V3D_ALIGN; t->around = v3d->around; - if (op && RNA_struct_find_property(op->ptr, "constraint_orientation") && RNA_property_is_set(op->ptr, "constraint_orientation")) + if (op && RNA_struct_find_property(op->ptr, "constraint_orientation") && RNA_struct_property_is_set(op->ptr, "constraint_orientation")) { t->current_orientation = RNA_enum_get(op->ptr, "constraint_orientation"); @@ -1099,7 +1087,7 @@ /* initialize UV transform from */ if (op && RNA_struct_find_property(op->ptr, "correct_uv")) { - if(RNA_property_is_set(op->ptr, "correct_uv")) { + if(RNA_struct_property_is_set(op->ptr, "correct_uv")) { if(RNA_boolean_get(op->ptr, "correct_uv")) { t->settings->uvcalc_flag |= UVCALC_TRANSFORM_CORRECT; } @@ -1145,7 +1133,7 @@ t->around = V3D_CENTER; } - if (op && RNA_property_is_set(op->ptr, "release_confirm")) + if (op && RNA_struct_property_is_set(op->ptr, "release_confirm")) { if (RNA_boolean_get(op->ptr, "release_confirm")) { @@ -1160,7 +1148,7 @@ } } - if (op && RNA_struct_find_property(op->ptr, "mirror") && RNA_property_is_set(op->ptr, "mirror")) + if (op && RNA_struct_find_property(op->ptr, "mirror") && RNA_struct_property_is_set(op->ptr, "mirror")) { if (RNA_boolean_get(op->ptr, "mirror")) { @@ -1181,7 +1169,7 @@ /* setting PET flag only if property exist in operator. Otherwise, assume it's not supported */ if (op && RNA_struct_find_property(op->ptr, "proportional")) { - if (RNA_property_is_set(op->ptr, "proportional")) + if (RNA_struct_property_is_set(op->ptr, "proportional")) { switch(RNA_enum_get(op->ptr, "proportional")) { @@ -1214,7 +1202,7 @@ } } - if (op && RNA_struct_find_property(op->ptr, "proportional_size") && RNA_property_is_set(op->ptr, "proportional_size")) + if (op && RNA_struct_find_property(op->ptr, "proportional_size") && RNA_struct_property_is_set(op->ptr, "proportional_size")) { t->prop_size = RNA_float_get(op->ptr, "proportional_size"); } @@ -1231,7 +1219,7 @@ t->prop_size = 1.0f; } - if (op && RNA_struct_find_property(op->ptr, "proportional_edit_falloff") && RNA_property_is_set(op->ptr, "proportional_edit_falloff")) + if (op && RNA_struct_find_property(op->ptr, "proportional_edit_falloff") && RNA_struct_property_is_set(op->ptr, "proportional_edit_falloff")) { t->prop_mode = RNA_enum_get(op->ptr, "proportional_edit_falloff"); } diff -Nru blender-2.61/source/blender/editors/transform/transform.h blender-2.62/source/blender/editors/transform/transform.h --- blender-2.61/source/blender/editors/transform/transform.h 2011-12-13 19:52:13.000000000 +0000 +++ blender-2.62/source/blender/editors/transform/transform.h 2012-02-15 19:36:49.000000000 +0000 @@ -65,15 +65,6 @@ struct ARegion; struct ReportList; -/* - The ctrl value has different meaning: - 0 : No value has been typed - - otherwise, |value| - 1 is where the cursor is located after the period - Positive : number is positive - Negative : number is negative -*/ - typedef struct TransSnapPoint { struct TransSnapPoint *next,*prev; float co[3]; @@ -94,6 +85,7 @@ float snapNormal[3]; float snapTangent[3]; ListBase points; + TransSnapPoint *selectedPoint; float dist; // Distance from snapPoint to snapTarget double last; void (*applySnap)(struct TransInfo *, float *); @@ -289,7 +281,7 @@ char *undostr; /* if set, uses this string for undo */ float spacemtx[3][3]; /* orientation matrix of the current space */ - char spacename[32]; /* name of the current space */ + char spacename[64]; /* name of the current space, MAX_NAME */ struct Object *poseobj; /* if t->flag & T_POSE, this denotes pose object */ @@ -618,6 +610,7 @@ void getSnapPoint(TransInfo *t, float vec[3]); void addSnapPoint(TransInfo *t); +int updateSelectedSnapPoint(TransInfo *t); void removeSnapPoint(TransInfo *t); /********************** Mouse Input ******************************/ diff -Nru blender-2.61/source/blender/editors/transform/transform_manipulator.c blender-2.62/source/blender/editors/transform/transform_manipulator.c --- blender-2.61/source/blender/editors/transform/transform_manipulator.c 2011-12-13 19:52:13.000000000 +0000 +++ blender-2.62/source/blender/editors/transform/transform_manipulator.c 2012-02-15 19:36:49.000000000 +0000 @@ -1564,7 +1564,7 @@ rect.ymax= mval[1]+hotspot; setwinmatrixview3d(ar, v3d, &rect); - mul_m4_m4m4(rv3d->persmat, rv3d->viewmat, rv3d->winmat); + mult_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat); glSelectBuffer( 64, buffer); glRenderMode(GL_SELECT); @@ -1586,7 +1586,7 @@ G.f &= ~G_PICKSEL; setwinmatrixview3d(ar, v3d, NULL); - mul_m4_m4m4(rv3d->persmat, rv3d->viewmat, rv3d->winmat); + mult_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat); if(hits==1) return buffer[3]; else if(hits>1) { diff -Nru blender-2.61/source/blender/editors/transform/transform_ops.c blender-2.62/source/blender/editors/transform/transform_ops.c --- blender-2.61/source/blender/editors/transform/transform_ops.c 2011-12-13 19:52:13.000000000 +0000 +++ blender-2.62/source/blender/editors/transform/transform_ops.c 2012-02-15 19:36:49.000000000 +0000 @@ -268,7 +268,7 @@ static int create_orientation_exec(bContext *C, wmOperator *op) { - char name[36]; + char name[MAX_NAME]; int use = RNA_boolean_get(op->ptr, "use"); int overwrite = RNA_boolean_get(op->ptr, "overwrite"); @@ -301,7 +301,7 @@ ot->poll = ED_operator_areaactive; ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; - RNA_def_string(ot->srna, "name", "", 35, "Name", "Text to insert at the cursor position"); + RNA_def_string(ot->srna, "name", "", MAX_NAME, "Name", "Text to insert at the cursor position"); RNA_def_boolean(ot->srna, "use", 0, "Use after creation", "Select orientation after its creation"); RNA_def_boolean(ot->srna, "overwrite", 0, "Overwrite previous", "Overwrite previously created orientation with same name"); } @@ -429,7 +429,7 @@ return OPERATOR_CANCELLED; } - if(RNA_property_is_set(op->ptr, "value")) { + if(RNA_struct_property_is_set(op->ptr, "value")) { return transform_exec(C, op); } else { @@ -632,7 +632,7 @@ ot->cancel = transform_cancel; ot->poll = ED_operator_screenactive; - RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", 0, 1); + RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI*2, M_PI*2); Transform_Properties(ot, P_PROPORTIONAL|P_MIRROR|P_SNAP); // XXX Warp axis? @@ -843,7 +843,7 @@ void transform_keymap_for_space(wmKeyConfig *keyconf, wmKeyMap *keymap, int spaceid) { - wmKeyMapItem *km; + wmKeyMapItem *kmi; wmKeyMap *modalmap; /* transform.c, only adds modal map once, checks if it's there */ @@ -879,71 +879,71 @@ WM_keymap_add_item(keymap, "TRANSFORM_OT_select_orientation", SPACEKEY, KM_PRESS, KM_ALT, 0); - km = WM_keymap_add_item(keymap, "TRANSFORM_OT_create_orientation", SPACEKEY, KM_PRESS, KM_CTRL|KM_ALT, 0); - RNA_boolean_set(km->ptr, "use", 1); + kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_create_orientation", SPACEKEY, KM_PRESS, KM_CTRL|KM_ALT, 0); + RNA_boolean_set(kmi->ptr, "use", TRUE); WM_keymap_add_item(keymap, OP_MIRROR, MKEY, KM_PRESS, KM_CTRL, 0); - km = WM_keymap_add_item(keymap, "WM_OT_context_toggle", TABKEY, KM_PRESS, KM_SHIFT, 0); - RNA_string_set(km->ptr, "data_path", "tool_settings.use_snap"); + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", TABKEY, KM_PRESS, KM_SHIFT, 0); + RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_snap"); WM_keymap_add_item(keymap, "TRANSFORM_OT_snap_type", TABKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0); - km = WM_keymap_add_item(keymap, OP_TRANSLATION, TKEY, KM_PRESS, KM_SHIFT, 0); - RNA_boolean_set(km->ptr, "texture_space", 1); + kmi = WM_keymap_add_item(keymap, OP_TRANSLATION, TKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "texture_space", TRUE); - km = WM_keymap_add_item(keymap, OP_RESIZE, TKEY, KM_PRESS, KM_SHIFT|KM_ALT, 0); - RNA_boolean_set(km->ptr, "texture_space", 1); + kmi = WM_keymap_add_item(keymap, OP_RESIZE, TKEY, KM_PRESS, KM_SHIFT|KM_ALT, 0); + RNA_boolean_set(kmi->ptr, "texture_space", TRUE); break; case SPACE_ACTION: - km= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", GKEY, KM_PRESS, 0, 0); - RNA_enum_set(km->ptr, "mode", TFM_TIME_TRANSLATE); + kmi= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", GKEY, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "mode", TFM_TIME_TRANSLATE); - km= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EVT_TWEAK_S, KM_ANY, 0, 0); - RNA_enum_set(km->ptr, "mode", TFM_TIME_TRANSLATE); + kmi= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EVT_TWEAK_S, KM_ANY, 0, 0); + RNA_enum_set(kmi->ptr, "mode", TFM_TIME_TRANSLATE); - km= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EKEY, KM_PRESS, 0, 0); - RNA_enum_set(km->ptr, "mode", TFM_TIME_EXTEND); + kmi= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EKEY, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "mode", TFM_TIME_EXTEND); - km= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", SKEY, KM_PRESS, 0, 0); - RNA_enum_set(km->ptr, "mode", TFM_TIME_SCALE); + kmi= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", SKEY, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "mode", TFM_TIME_SCALE); - km= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", TKEY, KM_PRESS, KM_SHIFT, 0); - RNA_enum_set(km->ptr, "mode", TFM_TIME_SLIDE); + kmi= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", TKEY, KM_PRESS, KM_SHIFT, 0); + RNA_enum_set(kmi->ptr, "mode", TFM_TIME_SLIDE); break; case SPACE_IPO: WM_keymap_add_item(keymap, OP_TRANSLATION, GKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, OP_TRANSLATION, EVT_TWEAK_S, KM_ANY, 0, 0); - km= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EKEY, KM_PRESS, 0, 0); - RNA_enum_set(km->ptr, "mode", TFM_TIME_EXTEND); + kmi= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EKEY, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "mode", TFM_TIME_EXTEND); WM_keymap_add_item(keymap, OP_ROTATION, RKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, OP_RESIZE, SKEY, KM_PRESS, 0, 0); break; case SPACE_NLA: - km= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", GKEY, KM_PRESS, 0, 0); - RNA_enum_set(km->ptr, "mode", TFM_TRANSLATION); + kmi= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", GKEY, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "mode", TFM_TRANSLATION); - km= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EVT_TWEAK_S, KM_ANY, 0, 0); - RNA_enum_set(km->ptr, "mode", TFM_TRANSLATION); + kmi= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EVT_TWEAK_S, KM_ANY, 0, 0); + RNA_enum_set(kmi->ptr, "mode", TFM_TRANSLATION); - km= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EKEY, KM_PRESS, 0, 0); - RNA_enum_set(km->ptr, "mode", TFM_TIME_EXTEND); + kmi= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EKEY, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "mode", TFM_TIME_EXTEND); - km= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", SKEY, KM_PRESS, 0, 0); - RNA_enum_set(km->ptr, "mode", TFM_TIME_SCALE); + kmi= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", SKEY, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "mode", TFM_TIME_SCALE); break; case SPACE_NODE: WM_keymap_add_item(keymap, OP_TRANSLATION, GKEY, KM_PRESS, 0, 0); - km= WM_keymap_add_item(keymap, OP_TRANSLATION, EVT_TWEAK_A, KM_ANY, 0, 0); - RNA_boolean_set(km->ptr, "release_confirm", 1); - km= WM_keymap_add_item(keymap, OP_TRANSLATION, EVT_TWEAK_S, KM_ANY, 0, 0); - RNA_boolean_set(km->ptr, "release_confirm", 1); + kmi= WM_keymap_add_item(keymap, OP_TRANSLATION, EVT_TWEAK_A, KM_ANY, 0, 0); + RNA_boolean_set(kmi->ptr, "release_confirm", TRUE); + kmi= WM_keymap_add_item(keymap, OP_TRANSLATION, EVT_TWEAK_S, KM_ANY, 0, 0); + RNA_boolean_set(kmi->ptr, "release_confirm", TRUE); WM_keymap_add_item(keymap, OP_ROTATION, RKEY, KM_PRESS, 0, 0); @@ -954,8 +954,8 @@ WM_keymap_add_item(keymap, OP_SEQ_SLIDE, EVT_TWEAK_S, KM_ANY, 0, 0); - km= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EKEY, KM_PRESS, 0, 0); - RNA_enum_set(km->ptr, "mode", TFM_TIME_EXTEND); + kmi= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EKEY, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "mode", TFM_TIME_EXTEND); break; case SPACE_IMAGE: WM_keymap_add_item(keymap, OP_TRANSLATION, GKEY, KM_PRESS, 0, 0); @@ -970,8 +970,8 @@ WM_keymap_add_item(keymap, "TRANSFORM_OT_mirror", MKEY, KM_PRESS, KM_CTRL, 0); - km = WM_keymap_add_item(keymap, "WM_OT_context_toggle", TABKEY, KM_PRESS, KM_SHIFT, 0); - RNA_string_set(km->ptr, "data_path", "tool_settings.use_snap"); + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", TABKEY, KM_PRESS, KM_SHIFT, 0); + RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_snap"); break; case SPACE_CLIP: WM_keymap_add_item(keymap, OP_TRANSLATION, GKEY, KM_PRESS, 0, 0); diff -Nru blender-2.61/source/blender/editors/transform/transform_orientations.c blender-2.62/source/blender/editors/transform/transform_orientations.c --- blender-2.61/source/blender/editors/transform/transform_orientations.c 2011-12-13 19:52:13.000000000 +0000 +++ blender-2.62/source/blender/editors/transform/transform_orientations.c 2012-02-15 19:36:49.000000000 +0000 @@ -127,7 +127,8 @@ } } -TransformOrientation *createObjectSpace(bContext *C, ReportList *UNUSED(reports), char *name, int overwrite) { +TransformOrientation *createObjectSpace(bContext *C, ReportList *UNUSED(reports), char *name, int overwrite) +{ Base *base = CTX_data_active_base(C); Object *ob; float mat[3][3]; @@ -144,13 +145,14 @@ /* use object name if no name is given */ if (name[0] == 0) { - strncpy(name, ob->id.name+2, 35); + strncpy(name, ob->id.name+2, MAX_ID_NAME-2); } return addMatrixSpace(C, mat, name, overwrite); } -TransformOrientation *createBoneSpace(bContext *C, ReportList *reports, char *name, int overwrite) { +TransformOrientation *createBoneSpace(bContext *C, ReportList *reports, char *name, int overwrite) +{ float mat[3][3]; float normal[3], plane[3]; @@ -169,7 +171,8 @@ return addMatrixSpace(C, mat, name, overwrite); } -TransformOrientation *createMeshSpace(bContext *C, ReportList *reports, char *name, int overwrite) { +TransformOrientation *createMeshSpace(bContext *C, ReportList *reports, char *name, int overwrite) +{ float mat[3][3]; float normal[3], plane[3]; int type; @@ -267,7 +270,8 @@ return 1; } -TransformOrientation* addMatrixSpace(bContext *C, float mat[3][3], char name[], int overwrite) { +TransformOrientation* addMatrixSpace(bContext *C, float mat[3][3], char name[], int overwrite) +{ ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; TransformOrientation *ts = NULL; @@ -285,7 +289,7 @@ { ts = MEM_callocN(sizeof(TransformOrientation), "UserTransSpace from matrix"); BLI_addtail(transform_spaces, ts); - strncpy(ts->name, name, 35); + strncpy(ts->name, name, sizeof(ts->name)); } /* copy matrix into transform space */ @@ -294,7 +298,8 @@ return ts; } -void BIF_removeTransformOrientation(bContext *C, TransformOrientation *target) { +void BIF_removeTransformOrientation(bContext *C, TransformOrientation *target) +{ ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; TransformOrientation *ts; int i; @@ -321,7 +326,8 @@ } } -void BIF_removeTransformOrientationIndex(bContext *C, int index) { +void BIF_removeTransformOrientationIndex(bContext *C, int index) +{ ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; TransformOrientation *ts= BLI_findlink(transform_spaces, index); @@ -344,7 +350,8 @@ } } -void BIF_selectTransformOrientation(bContext *C, TransformOrientation *target) { +void BIF_selectTransformOrientation(bContext *C, TransformOrientation *target) +{ ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; View3D *v3d = CTX_wm_view3d(C); TransformOrientation *ts; @@ -358,7 +365,8 @@ } } -void BIF_selectTransformOrientationValue(bContext *C, int orientation) { +void BIF_selectTransformOrientationValue(bContext *C, int orientation) +{ View3D *v3d = CTX_wm_view3d(C); if(v3d) /* currently using generic poll */ v3d->twmode = orientation; @@ -407,16 +415,18 @@ return item; } -const char * BIF_menustringTransformOrientation(const bContext *C, const char *title) { +const char * BIF_menustringTransformOrientation(const bContext *C, const char *title) +{ const char* menu = IFACE_("%t|Global%x0|Local%x1|Gimbal%x4|Normal%x2|View%x3"); ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; TransformOrientation *ts; int i = V3D_MANIP_CUSTOM; char *str_menu, *p; + const int elem_size = MAX_NAME + 4; title = IFACE_(title); - str_menu = MEM_callocN(strlen(menu) + strlen(title) + 1 + 40 * BIF_countTransformOrientation(C), TIP_("UserTransSpace from matrix")); + str_menu = MEM_callocN(strlen(menu) + strlen(title) + 1 + elem_size * BIF_countTransformOrientation(C), TIP_("UserTransSpace from matrix")); p = str_menu; p += sprintf(str_menu, "%s", title); @@ -429,7 +439,8 @@ return str_menu; } -int BIF_countTransformOrientation(const bContext *C) { +int BIF_countTransformOrientation(const bContext *C) +{ ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; TransformOrientation *ts; int count = 0; @@ -441,7 +452,8 @@ return count; } -void applyTransformOrientation(const bContext *C, float mat[3][3], char *name) { +void applyTransformOrientation(const bContext *C, float mat[3][3], char *name) +{ TransformOrientation *ts; View3D *v3d = CTX_wm_view3d(C); int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM); diff -Nru blender-2.61/source/blender/editors/transform/transform_snap.c blender-2.62/source/blender/editors/transform/transform_snap.c --- blender-2.61/source/blender/editors/transform/transform_snap.c 2011-12-13 19:52:13.000000000 +0000 +++ blender-2.62/source/blender/editors/transform/transform_snap.c 2012-02-15 19:36:49.000000000 +0000 @@ -141,11 +141,16 @@ if (validSnap(t) && activeSnap(t)) { - unsigned char col[4]; + unsigned char col[4], selectedCol[4], activeCol[4]; UI_GetThemeColor3ubv(TH_TRANSFORM, col); col[3]= 128; - glColor4ubv(col); + UI_GetThemeColor3ubv(TH_SELECT, selectedCol); + selectedCol[3]= 128; + + UI_GetThemeColor3ubv(TH_ACTIVE, activeCol); + activeCol[3]= 192; + if (t->spacetype == SPACE_VIEW3D) { TransSnapPoint *p; View3D *v3d = CTX_wm_view3d(C); @@ -160,16 +165,26 @@ invert_m4_m4(imat, rv3d->viewmat); for (p = t->tsnap.points.first; p; p = p->next) { - drawcircball(GL_LINE_LOOP, p->co, ED_view3d_pixel_size(rv3d, p->co) * size, imat); + if (p == t->tsnap.selectedPoint) { + glColor4ubv(selectedCol); + } else { + glColor4ubv(col); + } + + drawcircball(GL_LINE_LOOP, p->co, ED_view3d_pixel_size(rv3d, p->co) * size * 0.75f, imat); } if (t->tsnap.status & POINT_INIT) { + glColor4ubv(activeCol); + drawcircball(GL_LINE_LOOP, t->tsnap.snapPoint, ED_view3d_pixel_size(rv3d, t->tsnap.snapPoint) * size, imat); } /* draw normal if needed */ if (usingSnappingNormal(t) && validSnappingNormal(t)) { + glColor4ubv(activeCol); + glBegin(GL_LINES); glVertex3f(t->tsnap.snapPoint[0], t->tsnap.snapPoint[1], t->tsnap.snapPoint[2]); glVertex3f( t->tsnap.snapPoint[0] + t->tsnap.snapNormal[0], @@ -219,7 +234,7 @@ } } -int handleSnapping(TransInfo *UNUSED(t), wmEvent *UNUSED(event)) +int handleSnapping(TransInfo *t, wmEvent *event) { int status = 0; @@ -232,6 +247,10 @@ status = 1; } #endif + if (event->type == MOUSEMOVE) + { + status |= updateSelectedSnapPoint(t); + } return status; } @@ -426,18 +445,18 @@ resetSnapping(t); /* if snap property exists */ - if (op && RNA_struct_find_property(op->ptr, "snap") && RNA_property_is_set(op->ptr, "snap")) + if (op && RNA_struct_find_property(op->ptr, "snap") && RNA_struct_property_is_set(op->ptr, "snap")) { if (RNA_boolean_get(op->ptr, "snap")) { t->modifiers |= MOD_SNAP; - if (RNA_property_is_set(op->ptr, "snap_target")) + if (RNA_struct_property_is_set(op->ptr, "snap_target")) { snap_target = RNA_enum_get(op->ptr, "snap_target"); } - if (RNA_property_is_set(op->ptr, "snap_point")) + if (RNA_struct_property_is_set(op->ptr, "snap_point")) { RNA_float_get_array(op->ptr, "snap_point", t->tsnap.snapPoint); t->tsnap.status |= SNAP_FORCED|POINT_INIT; @@ -541,6 +560,8 @@ if (t->tsnap.status & POINT_INIT) { TransSnapPoint *p = MEM_callocN(sizeof(TransSnapPoint), "SnapPoint"); + t->tsnap.selectedPoint = p; + copy_v3_v3(p->co, t->tsnap.snapPoint); BLI_addtail(&t->tsnap.points, p); @@ -549,13 +570,55 @@ } } +int updateSelectedSnapPoint(TransInfo *t) +{ + int status = 0; + if (t->tsnap.status & MULTI_POINTS) { + TransSnapPoint *p, *closest_p = NULL; + int closest_dist = 0; + int screen_loc[2]; + + for( p = t->tsnap.points.first; p; p = p->next ) { + int dx, dy; + int dist; + + project_int(t->ar, p->co, screen_loc); + + dx = t->mval[0] - screen_loc[0]; + dy = t->mval[1] - screen_loc[1]; + + dist = dx * dx + dy * dy; + + if (dist < 100 && (closest_p == NULL || closest_dist > dist)) { + closest_p = p; + closest_dist = dist; + } + } + + if (closest_p) { + status = t->tsnap.selectedPoint == closest_p ? 0 : 1; + t->tsnap.selectedPoint = closest_p; + } + } + + return status; +} + void removeSnapPoint(TransInfo *t) { if (t->tsnap.status & MULTI_POINTS) { - BLI_freelinkN(&t->tsnap.points, t->tsnap.points.last); + updateSelectedSnapPoint(t); + + if (t->tsnap.selectedPoint) { + BLI_freelinkN(&t->tsnap.points, t->tsnap.selectedPoint); + + if (t->tsnap.points.first == NULL) { + t->tsnap.status &= ~MULTI_POINTS; + } + + t->tsnap.selectedPoint = NULL; + } - if (t->tsnap.points.first == NULL) - t->tsnap.status &= ~MULTI_POINTS; } } @@ -680,7 +743,7 @@ static float ResizeBetween(TransInfo *t, float p1[3], float p2[3]) { - float d1[3], d2[3], center[3]; + float d1[3], d2[3], center[3], len_d1; copy_v3_v3(center, t->center); if(t->flag & (T_EDIT|T_POSE)) { @@ -696,7 +759,9 @@ mul_m3_v3(t->con.pmtx, d2); } - return len_v3(d2) / len_v3(d1); + len_d1 = len_v3(d1); + + return len_d1 != 0.0f ? len_v3(d2) / len_d1 : 1; } /********************** CALC **************************/ @@ -1622,7 +1687,12 @@ } for ( base = FIRSTBASE; base != NULL; base = base->next ) { - if ( BASE_VISIBLE(v3d, base) && (base->flag & (BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA)) == 0 && ((mode == SNAP_NOT_SELECTED && (base->flag & (SELECT|BA_WAS_SEL)) == 0) || (ELEM(mode, SNAP_ALL, SNAP_NOT_OBEDIT) && base != BASACT)) ) { + if ( (BASE_VISIBLE(v3d, base)) && + (base->flag & (BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA)) == 0 && + + ( (mode == SNAP_NOT_SELECTED && (base->flag & (SELECT|BA_WAS_SEL)) == 0) || + (ELEM(mode, SNAP_ALL, SNAP_NOT_OBEDIT) && base != BASACT)) ) + { Object *ob = base->object; if (ob->transflag & OB_DUPLI) diff -Nru blender-2.61/source/blender/editors/util/ed_util.c blender-2.62/source/blender/editors/util/ed_util.c --- blender-2.61/source/blender/editors/util/ed_util.c 2011-12-13 19:54:39.000000000 +0000 +++ blender-2.62/source/blender/editors/util/ed_util.c 2012-02-15 19:38:55.000000000 +0000 @@ -58,6 +58,7 @@ #include "UI_resources.h" #include "WM_types.h" +#include "WM_api.h" #include "RNA_access.h" @@ -165,12 +166,13 @@ uiPopupMenu *pup; uiLayout *layout; char line[FILE_MAX + 100]; + wmOperatorType *ot = WM_operatortype_find(opname, 1); pup= uiPupMenuBegin(C, "Unpack file", ICON_NONE); layout= uiPupMenuLayout(pup); strcpy(line, "Remove Pack"); - props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + props_ptr= uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); RNA_enum_set(&props_ptr, "method", PF_REMOVE); RNA_string_set(&props_ptr, "id", id_name); @@ -179,34 +181,34 @@ BLI_strncpy(local_name, abs_name, sizeof(local_name)); BLI_splitdirstring(local_name, fi); - sprintf(local_name, "//%s/%s", folder, fi); + BLI_snprintf(local_name, sizeof(local_name), "//%s/%s", folder, fi); if(strcmp(abs_name, local_name)!=0) { switch(checkPackedFile(local_name, pf)) { case PF_NOFILE: - sprintf(line, "Create %s", local_name); - props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + BLI_snprintf(line, sizeof(line), "Create %s", local_name); + props_ptr= uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); RNA_enum_set(&props_ptr, "method", PF_WRITE_LOCAL); RNA_string_set(&props_ptr, "id", id_name); break; case PF_EQUAL: - sprintf(line, "Use %s (identical)", local_name); - //uiItemEnumO(layout, opname, line, 0, "method", PF_USE_LOCAL); - props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + BLI_snprintf(line, sizeof(line), "Use %s (identical)", local_name); + //uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_USE_LOCAL); + props_ptr= uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); RNA_enum_set(&props_ptr, "method", PF_USE_LOCAL); RNA_string_set(&props_ptr, "id", id_name); break; case PF_DIFFERS: - sprintf(line, "Use %s (differs)", local_name); - //uiItemEnumO(layout, opname, line, 0, "method", PF_USE_LOCAL); - props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + BLI_snprintf(line, sizeof(line), "Use %s (differs)", local_name); + //uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_USE_LOCAL); + props_ptr= uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); RNA_enum_set(&props_ptr, "method", PF_USE_LOCAL); RNA_string_set(&props_ptr, "id", id_name); - sprintf(line, "Overwrite %s", local_name); - //uiItemEnumO(layout, opname, line, 0, "method", PF_WRITE_LOCAL); - props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + BLI_snprintf(line, sizeof(line), "Overwrite %s", local_name); + //uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_WRITE_LOCAL); + props_ptr= uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); RNA_enum_set(&props_ptr, "method", PF_WRITE_LOCAL); RNA_string_set(&props_ptr, "id", id_name); break; @@ -216,29 +218,29 @@ switch(checkPackedFile(abs_name, pf)) { case PF_NOFILE: - sprintf(line, "Create %s", abs_name); - //uiItemEnumO(layout, opname, line, 0, "method", PF_WRITE_ORIGINAL); - props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + BLI_snprintf(line, sizeof(line), "Create %s", abs_name); + //uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_WRITE_ORIGINAL); + props_ptr= uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); RNA_enum_set(&props_ptr, "method", PF_WRITE_ORIGINAL); RNA_string_set(&props_ptr, "id", id_name); break; case PF_EQUAL: - sprintf(line, "Use %s (identical)", abs_name); - //uiItemEnumO(layout, opname, line, 0, "method", PF_USE_ORIGINAL); - props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + BLI_snprintf(line, sizeof(line), "Use %s (identical)", abs_name); + //uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_USE_ORIGINAL); + props_ptr= uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); RNA_enum_set(&props_ptr, "method", PF_USE_ORIGINAL); RNA_string_set(&props_ptr, "id", id_name); break; case PF_DIFFERS: - sprintf(line, "Use %s (differs)", abs_name); - //uiItemEnumO(layout, opname, line, 0, "method", PF_USE_ORIGINAL); - props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + BLI_snprintf(line, sizeof(line), "Use %s (differs)", abs_name); + //uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_USE_ORIGINAL); + props_ptr= uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); RNA_enum_set(&props_ptr, "method", PF_USE_ORIGINAL); RNA_string_set(&props_ptr, "id", id_name); - sprintf(line, "Overwrite %s", abs_name); - //uiItemEnumO(layout, opname, line, 0, "method", PF_WRITE_ORIGINAL); - props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + BLI_snprintf(line, sizeof(line), "Overwrite %s", abs_name); + //uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_WRITE_ORIGINAL); + props_ptr= uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); RNA_enum_set(&props_ptr, "method", PF_WRITE_ORIGINAL); RNA_string_set(&props_ptr, "id", id_name); break; diff -Nru blender-2.61/source/blender/editors/util/numinput.c blender-2.62/source/blender/editors/util/numinput.c --- blender-2.61/source/blender/editors/util/numinput.c 2011-12-13 19:54:39.000000000 +0000 +++ blender-2.62/source/blender/editors/util/numinput.c 2012-02-15 19:38:55.000000000 +0000 @@ -31,9 +31,10 @@ #include /* fabs */ -#include /* for sprintf */ +#include /* for size_t */ #include "BLI_utildefines.h" +#include "BLI_string.h" #include "WM_types.h" @@ -84,34 +85,34 @@ inv[0] = 0; if( n->val[i] > 1e10f || n->val[i] < -1e10f ) - sprintf(&str[j*20], "%s%.4e%c", inv, n->val[i], cur); + BLI_snprintf(&str[j*20], 20, "%s%.4e%c", inv, n->val[i], cur); else switch (n->ctrl[i]) { case 0: - sprintf(&str[j*20], "%sNONE%c", inv, cur); + BLI_snprintf(&str[j*20], 20, "%sNONE%c", inv, cur); break; case 1: case -1: - sprintf(&str[j*20], "%s%.0f%c", inv, n->val[i], cur); + BLI_snprintf(&str[j*20], 20, "%s%.0f%c", inv, n->val[i], cur); break; case 10: case -10: - sprintf(&str[j*20], "%s%.f.%c", inv, n->val[i], cur); + BLI_snprintf(&str[j*20], 20, "%s%.f.%c", inv, n->val[i], cur); break; case 100: case -100: - sprintf(&str[j*20], "%s%.1f%c", inv, n->val[i], cur); + BLI_snprintf(&str[j*20], 20, "%s%.1f%c", inv, n->val[i], cur); break; case 1000: case -1000: - sprintf(&str[j*20], "%s%.2f%c", inv, n->val[i], cur); + BLI_snprintf(&str[j*20], 20, "%s%.2f%c", inv, n->val[i], cur); break; case 10000: case -10000: - sprintf(&str[j*20], "%s%.3f%c", inv, n->val[i], cur); + BLI_snprintf(&str[j*20], 20, "%s%.3f%c", inv, n->val[i], cur); break; default: - sprintf(&str[j*20], "%s%.4e%c", inv, n->val[i], cur); + BLI_snprintf(&str[j*20], 20, "%s%.4e%c", inv, n->val[i], cur); } } } diff -Nru blender-2.61/source/blender/editors/util/undo.c blender-2.62/source/blender/editors/util/undo.c --- blender-2.61/source/blender/editors/util/undo.c 2011-12-13 19:54:39.000000000 +0000 +++ blender-2.62/source/blender/editors/util/undo.c 2012-02-15 19:38:55.000000000 +0000 @@ -509,7 +509,7 @@ /* note: also check ed_undo_step() in top if you change notifiers */ static int undo_history_exec(bContext *C, wmOperator *op) { - if(RNA_property_is_set(op->ptr, "item")) { + if(RNA_struct_property_is_set(op->ptr, "item")) { int undosys= get_undo_system(C); int item= RNA_int_get(op->ptr, "item"); diff -Nru blender-2.61/source/blender/editors/uvedit/CMakeLists.txt blender-2.62/source/blender/editors/uvedit/CMakeLists.txt --- blender-2.61/source/blender/editors/uvedit/CMakeLists.txt 2011-12-13 19:54:28.000000000 +0000 +++ blender-2.62/source/blender/editors/uvedit/CMakeLists.txt 2012-02-15 19:38:37.000000000 +0000 @@ -39,6 +39,7 @@ uvedit_draw.c uvedit_ops.c uvedit_parametrizer.c + uvedit_smart_stitch.c uvedit_unwrap_ops.c uvedit_intern.h diff -Nru blender-2.61/source/blender/editors/uvedit/uvedit_draw.c blender-2.62/source/blender/editors/uvedit/uvedit_draw.c --- blender-2.61/source/blender/editors/uvedit/uvedit_draw.c 2011-12-13 19:54:28.000000000 +0000 +++ blender-2.62/source/blender/editors/uvedit/uvedit_draw.c 2012-02-15 19:38:37.000000000 +0000 @@ -380,12 +380,9 @@ } } -static void draw_uvs_other(Scene *scene, Object *obedit, MTFace *activetf) +static void draw_uvs_other(Scene *scene, Object *obedit, Image *curimage) { Base *base; - Image *curimage; - - curimage= (activetf)? activetf->tpage: NULL; glColor3ub(96, 96, 96); @@ -419,6 +416,34 @@ } } +static void draw_uvs_texpaint(SpaceImage *sima, Scene *scene, Object *ob) +{ + Mesh *me= ob->data; + Image *curimage = ED_space_image(sima); + + if(sima->flag & SI_DRAW_OTHER) + draw_uvs_other(scene, ob, curimage); + + glColor3ub(112, 112, 112); + + if(me->mtface) { + MFace *mface= me->mface; + MTFace *tface= me->mtface; + int a; + + for(a=me->totface; a>0; a--, tface++, mface++) { + if(tface->tpage == curimage) { + glBegin(GL_LINE_LOOP); + glVertex2fv(tface->uv[0]); + glVertex2fv(tface->uv[1]); + glVertex2fv(tface->uv[2]); + if(mface->v4) glVertex2fv(tface->uv[3]); + glEnd(); + } + } + } +} + /* draws uv's in the image space */ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) { @@ -432,6 +457,7 @@ float pointsize; int drawfaces, interpedges; Image *ima= sima->image; + StitchPreviewer *stitch_preview = uv_get_stitch_previewer(); em= BKE_mesh_get_editmesh(me); activetf= EM_get_active_mtface(em, &efa_act, NULL, 0); /* will be set to NULL if hidden */ @@ -445,8 +471,11 @@ interpedges= (ts->uv_selectmode == UV_SELECT_VERTEX); /* draw other uvs */ - if(sima->flag & SI_DRAW_OTHER) - draw_uvs_other(scene, obedit, activetf); + if(sima->flag & SI_DRAW_OTHER) { + Image *curimage= (activetf)? activetf->tpage: NULL; + + draw_uvs_other(scene, obedit, curimage); + } /* 1. draw shadow mesh */ @@ -522,7 +551,7 @@ } } - + /* 3. draw active face stippled */ if(activetf) { @@ -831,24 +860,81 @@ bglEnd(); } + /* finally draw stitch preview */ + if(stitch_preview) { + glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); + glEnableClientState(GL_VERTEX_ARRAY); + + glEnable(GL_BLEND); + + UI_ThemeColor4(TH_STITCH_PREVIEW_ACTIVE); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glVertexPointer(2, GL_FLOAT, 0, stitch_preview->static_tris); + glDrawArrays(GL_TRIANGLES, 0, stitch_preview->num_static_tris*3); + + glVertexPointer(2, GL_FLOAT, 0, stitch_preview->static_quads); + glDrawArrays(GL_QUADS, 0, stitch_preview->num_static_quads*4); + + glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_tris); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + UI_ThemeColor4(TH_STITCH_PREVIEW_FACE); + glDrawArrays(GL_TRIANGLES, 0, stitch_preview->num_tris*3); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + UI_ThemeColor4(TH_STITCH_PREVIEW_EDGE); + glDrawArrays(GL_TRIANGLES, 0, stitch_preview->num_tris*3); + glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); + /*UI_ThemeColor4(TH_STITCH_PREVIEW_VERT); + glDrawArrays(GL_TRIANGLES, 0, stitch_preview->num_tris*3);*/ + + glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_quads); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + UI_ThemeColor4(TH_STITCH_PREVIEW_FACE); + glDrawArrays(GL_QUADS, 0, stitch_preview->num_quads*4); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + UI_ThemeColor4(TH_STITCH_PREVIEW_EDGE); + glDrawArrays(GL_QUADS, 0, stitch_preview->num_quads*4); + glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); + /*UI_ThemeColor4(TH_STITCH_PREVIEW_VERT); + glDrawArrays(GL_QUADS, 0, stitch_preview->num_quads*4);*/ + + glDisable(GL_BLEND); + + /* draw vert preview */ + glPointSize(pointsize*2.0); + UI_ThemeColor4(TH_STITCH_PREVIEW_STITCHABLE); + glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_stitchable); + glDrawArrays(GL_POINTS, 0, stitch_preview->num_stitchable); + + UI_ThemeColor4(TH_STITCH_PREVIEW_UNSTITCHABLE); + glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_unstitchable); + glDrawArrays(GL_POINTS, 0, stitch_preview->num_unstitchable); + + glPopClientAttrib(); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } + glPointSize(1.0); BKE_mesh_end_editmesh(obedit->data, em); } -void draw_uvedit_main(SpaceImage *sima, ARegion *ar, Scene *scene, Object *obedit) +void draw_uvedit_main(SpaceImage *sima, ARegion *ar, Scene *scene, Object *obedit, Object *obact) { - int show_uvedit, show_uvshadow; + ToolSettings *toolsettings = scene->toolsettings; + int show_uvedit, show_uvshadow, show_texpaint_uvshadow; + show_texpaint_uvshadow = (obact && obact->type == OB_MESH && obact->mode == OB_MODE_TEXTURE_PAINT); show_uvedit= ED_space_image_show_uvedit(sima, obedit); show_uvshadow= ED_space_image_show_uvshadow(sima, obedit); - if(show_uvedit || show_uvshadow) { + if(show_uvedit || show_uvshadow || show_texpaint_uvshadow) { if(show_uvshadow) draw_uvs_shadow(obedit); - else + else if(show_uvedit) draw_uvs(sima, scene, obedit); + else + draw_uvs_texpaint(sima, scene, obact); - if(show_uvedit) + if(show_uvedit && !(toolsettings->use_uv_sculpt)) drawcursor_sima(sima, ar); } } diff -Nru blender-2.61/source/blender/editors/uvedit/uvedit_intern.h blender-2.62/source/blender/editors/uvedit/uvedit_intern.h --- blender-2.61/source/blender/editors/uvedit/uvedit_intern.h 2011-12-13 19:54:28.000000000 +0000 +++ blender-2.62/source/blender/editors/uvedit/uvedit_intern.h 2012-02-15 19:38:37.000000000 +0000 @@ -32,25 +32,74 @@ #ifndef ED_UVEDIT_INTERN_H #define ED_UVEDIT_INTERN_H -struct SpaceImage; struct EditFace; -struct MTFace; -struct Scene; +struct EditMesh; struct Image; +struct MTFace; struct Object; +struct Scene; +struct SpaceImage; +struct UvElementMap; struct wmOperatorType; /* id can be from 0 to 3 */ #define TF_PIN_MASK(id) (TF_PIN1 << id) #define TF_SEL_MASK(id) (TF_SEL1 << id) - /* geometric utilities */ + void uv_center(float uv[][2], float cent[2], int quad); float uv_area(float uv[][2], int quad); void uv_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy); +/* find nearest */ + +typedef struct NearestHit { + struct EditFace *efa; + struct MTFace *tf; + + int vert, uv; + int edge, vert2; +} NearestHit; + +void uv_find_nearest_vert(struct Scene *scene, struct Image *ima, struct EditMesh *em, float co[2], float penalty[2], struct NearestHit *hit); +void uv_find_nearest_edge(struct Scene *scene, struct Image *ima, struct EditMesh *em, float co[2], struct NearestHit *hit); + +/* utility tool functions */ + +struct UvElement *ED_get_uv_element(struct UvElementMap *map, struct EditFace *efa, int index); +void uvedit_live_unwrap_update(struct SpaceImage *sima, struct Scene *scene, struct Object *obedit); + +/* smart stitch */ + +/* object that stores display data for previewing before accepting stitching */ +typedef struct StitchPreviewer { + /* OpenGL requires different calls for Triangles and Quads. + * here we'll store the quads of the mesh */ + float *preview_quads; + /* ...and here we'll store the triangles*/ + float *preview_tris; + /* preview data. These will be either the previewed vertices or edges depending on stitch mode settings */ + float *preview_stitchable; + float *preview_unstitchable; + /* here we'll store the number of triangles and quads to be drawn */ + unsigned int num_tris; + unsigned int num_quads; + unsigned int num_stitchable; + unsigned int num_unstitchable; + + /* store static island Quads */ + float *static_quads; + /* ...and here we'll store the triangles*/ + float *static_tris; + unsigned int num_static_tris; + unsigned int num_static_quads; +} StitchPreviewer; + +StitchPreviewer *uv_get_stitch_previewer(void); + /* operators */ + void UV_OT_average_islands_scale(struct wmOperatorType *ot); void UV_OT_cube_project(struct wmOperatorType *ot); void UV_OT_cylinder_project(struct wmOperatorType *ot); @@ -60,6 +109,7 @@ void UV_OT_reset(struct wmOperatorType *ot); void UV_OT_sphere_project(struct wmOperatorType *ot); void UV_OT_unwrap(struct wmOperatorType *ot); +void UV_OT_stitch(struct wmOperatorType *ot); #endif /* ED_UVEDIT_INTERN_H */ diff -Nru blender-2.61/source/blender/editors/uvedit/uvedit_ops.c blender-2.62/source/blender/editors/uvedit/uvedit_ops.c --- blender-2.61/source/blender/editors/uvedit/uvedit_ops.c 2011-12-13 19:54:28.000000000 +0000 +++ blender-2.62/source/blender/editors/uvedit/uvedit_ops.c 2012-02-15 19:38:37.000000000 +0000 @@ -20,7 +20,7 @@ * * The Original Code is: all of this file. * - * Contributor(s): none yet. + * Contributor(s): Antony Riakiotakis. * * ***** END GPL LICENSE BLOCK ***** */ @@ -94,6 +94,28 @@ return ret; } +static int ED_operator_uvedit_can_uv_sculpt(struct bContext *C) +{ + SpaceImage *sima= CTX_wm_space_image(C); + ToolSettings *toolsettings = CTX_data_tool_settings(C); + Object *obedit= CTX_data_edit_object(C); + + return ED_space_image_show_uvedit(sima, obedit) && !(toolsettings->use_uv_sculpt); +} + +static int UNUSED_FUNCTION(ED_operator_uvmap_mesh)(bContext *C) +{ + Object *ob= CTX_data_active_object(C); + + if(ob && ob->type==OB_MESH) { + Mesh *me = ob->data; + + if(CustomData_get_layer(&me->fdata, CD_MTFACE) != NULL) + return 1; + } + + return 0; +} /**************************** object active image *****************************/ static int is_image_texture_node(bNode *node) @@ -400,7 +422,7 @@ /*********************** live unwrap utilities ***********************/ -static void uvedit_live_unwrap_update(SpaceImage *sima, Scene *scene, Object *obedit) +void uvedit_live_unwrap_update(SpaceImage *sima, Scene *scene, Object *obedit) { if(sima && (sima->flag & SI_LIVE_UNWRAP)) { ED_uvedit_live_unwrap_begin(scene, obedit); @@ -527,15 +549,7 @@ /************************** find nearest ****************************/ -typedef struct NearestHit { - EditFace *efa; - MTFace *tf; - - int vert, uv; - int edge, vert2; -} NearestHit; - -static void find_nearest_uv_edge(Scene *scene, Image *ima, EditMesh *em, float co[2], NearestHit *hit) +void uv_find_nearest_edge(Scene *scene, Image *ima, EditMesh *em, float co[2], NearestHit *hit) { MTFace *tf; EditFace *efa; @@ -590,8 +604,7 @@ cent[0]= cent[1]= 0.0f; for(i=0; iuv[i][0]; - cent[1] += tf->uv[i][1]; + add_v2_v2(cent, tf->uv[i]); } cent[0] /= nverts; @@ -634,7 +647,7 @@ return (c1*c2 >= 0.0f); } -static void find_nearest_uv_vert(Scene *scene, Image *ima, EditMesh *em, float co[2], float penalty[2], NearestHit *hit) +void uv_find_nearest_vert(Scene *scene, Image *ima, EditMesh *em, float co[2], float penalty[2], NearestHit *hit) { EditFace *efa; EditVert *eve; @@ -751,6 +764,17 @@ return NULL; } +UvElement *ED_get_uv_element(UvElementMap *map, EditFace *efa, int index) +{ + UvElement *element = map->vert[(*(&efa->v1 + index))->tmp.l]; + + for(; element; element = element->next) + if(element->face == efa) + return element; + + return NULL; +} + static int uv_edge_tag_faces(UvMapVert *first1, UvMapVert *first2, int *totface) { UvMapVert *iterv1, *iterv2; @@ -1297,197 +1321,6 @@ ot->poll= ED_operator_uvedit; } -/* ******************** stitch operator **************** */ - -/* just for averaging UVs */ -typedef struct UVVertAverage { - float uv[2]; - int count; -} UVVertAverage; - -static int stitch_exec(bContext *C, wmOperator *op) -{ - SpaceImage *sima; - Scene *scene; - Object *obedit; - EditMesh *em; - EditFace *efa; - EditVert *eve; - Image *ima; - MTFace *tf; - - scene= CTX_data_scene(C); - obedit= CTX_data_edit_object(C); - em= BKE_mesh_get_editmesh((Mesh*)obedit->data); - ima= CTX_data_edit_image(C); - sima= CTX_wm_space_image(C); - - if(RNA_boolean_get(op->ptr, "use_limit")) { - UvVertMap *vmap; - UvMapVert *vlist, *iterv; - float newuv[2], limit[2]; - int a, vtot; - - limit[0]= RNA_float_get(op->ptr, "limit"); - limit[1]= limit[0]; - - EM_init_index_arrays(em, 0, 0, 1); - vmap= EM_make_uv_vert_map(em, 1, 0, limit); - - if(vmap == NULL) { - BKE_mesh_end_editmesh(obedit->data, em); - return OPERATOR_CANCELLED; - } - - for(a=0, eve= em->verts.first; eve; a++, eve= eve->next) { - vlist= EM_get_uv_map_vert(vmap, a); - - while(vlist) { - newuv[0]= 0; newuv[1]= 0; - vtot= 0; - - for(iterv=vlist; iterv; iterv=iterv->next) { - if((iterv != vlist) && iterv->separate) - break; - - efa = EM_get_face_for_index(iterv->f); - tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - - if(uvedit_uv_selected(scene, efa, tf, iterv->tfindex)) { - newuv[0] += tf->uv[iterv->tfindex][0]; - newuv[1] += tf->uv[iterv->tfindex][1]; - vtot++; - } - } - - if(vtot > 1) { - newuv[0] /= vtot; newuv[1] /= vtot; - - for(iterv=vlist; iterv; iterv=iterv->next) { - if((iterv != vlist) && iterv->separate) - break; - - efa = EM_get_face_for_index(iterv->f); - tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - - if(uvedit_uv_selected(scene, efa, tf, iterv->tfindex)) { - tf->uv[iterv->tfindex][0]= newuv[0]; - tf->uv[iterv->tfindex][1]= newuv[1]; - } - } - } - - vlist= iterv; - } - } - - EM_free_uv_vert_map(vmap); - EM_free_index_arrays(); - } - else { - UVVertAverage *uv_average, *uvav; - int count; - - // index and count verts - for(count=0, eve=em->verts.first; eve; count++, eve= eve->next) - eve->tmp.l = count; - - uv_average= MEM_callocN(sizeof(UVVertAverage)*count, "Stitch"); - - // gather uv averages per vert - for(efa= em->faces.first; efa; efa= efa->next) { - tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - - if(uvedit_face_visible(scene, ima, efa, tf)) { - if(uvedit_uv_selected(scene, efa, tf, 0)) { - uvav = uv_average + efa->v1->tmp.l; - uvav->count++; - uvav->uv[0] += tf->uv[0][0]; - uvav->uv[1] += tf->uv[0][1]; - } - - if(uvedit_uv_selected(scene, efa, tf, 1)) { - uvav = uv_average + efa->v2->tmp.l; - uvav->count++; - uvav->uv[0] += tf->uv[1][0]; - uvav->uv[1] += tf->uv[1][1]; - } - - if(uvedit_uv_selected(scene, efa, tf, 2)) { - uvav = uv_average + efa->v3->tmp.l; - uvav->count++; - uvav->uv[0] += tf->uv[2][0]; - uvav->uv[1] += tf->uv[2][1]; - } - - if(efa->v4 && uvedit_uv_selected(scene, efa, tf, 3)) { - uvav = uv_average + efa->v4->tmp.l; - uvav->count++; - uvav->uv[0] += tf->uv[3][0]; - uvav->uv[1] += tf->uv[3][1]; - } - } - } - - // apply uv welding - for(efa= em->faces.first; efa; efa= efa->next) { - tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - - if(uvedit_face_visible(scene, ima, efa, tf)) { - if(uvedit_uv_selected(scene, efa, tf, 0)) { - uvav = uv_average + efa->v1->tmp.l; - tf->uv[0][0] = uvav->uv[0]/uvav->count; - tf->uv[0][1] = uvav->uv[1]/uvav->count; - } - - if(uvedit_uv_selected(scene, efa, tf, 1)) { - uvav = uv_average + efa->v2->tmp.l; - tf->uv[1][0] = uvav->uv[0]/uvav->count; - tf->uv[1][1] = uvav->uv[1]/uvav->count; - } - - if(uvedit_uv_selected(scene, efa, tf, 2)) { - uvav = uv_average + efa->v3->tmp.l; - tf->uv[2][0] = uvav->uv[0]/uvav->count; - tf->uv[2][1] = uvav->uv[1]/uvav->count; - } - - if(efa->v4 && uvedit_uv_selected(scene, efa, tf, 3)) { - uvav = uv_average + efa->v4->tmp.l; - tf->uv[3][0] = uvav->uv[0]/uvav->count; - tf->uv[3][1] = uvav->uv[1]/uvav->count; - } - } - } - - MEM_freeN(uv_average); - } - - uvedit_live_unwrap_update(sima, scene, obedit); - DAG_id_tag_update(obedit->data, 0); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - - BKE_mesh_end_editmesh(obedit->data, em); - return OPERATOR_FINISHED; -} - -static void UV_OT_stitch(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Stitch"; - ot->description= "Stitch selected UV vertices by proximity"; - ot->idname= "UV_OT_stitch"; - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - /* api callbacks */ - ot->exec= stitch_exec; - ot->poll= ED_operator_uvedit; - - /* properties */ - RNA_def_boolean(ot->srna, "use_limit", 1, "Use Limit", "Stitch UVs within a specified limit distance"); - RNA_def_float(ot->srna, "limit", 0.01f, 0.0f, FLT_MAX, "Limit", "Limit distance in normalized coordinates", -FLT_MAX, FLT_MAX); -} - /* ******************** (de)select all operator **************** */ static void select_all_perform(bContext *C, int action) @@ -1661,7 +1494,7 @@ /* find nearest element */ if(loop) { /* find edge */ - find_nearest_uv_edge(scene, ima, em, co, &hit); + uv_find_nearest_edge(scene, ima, em, co, &hit); if(hit.efa == NULL) { BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_CANCELLED; @@ -1669,7 +1502,7 @@ } else if(selectmode == UV_SELECT_VERTEX) { /* find vertex */ - find_nearest_uv_vert(scene, ima, em, co, penalty, &hit); + uv_find_nearest_vert(scene, ima, em, co, penalty, &hit); if(hit.efa == NULL) { BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_CANCELLED; @@ -1684,7 +1517,7 @@ } else if(selectmode == UV_SELECT_EDGE) { /* find edge */ - find_nearest_uv_edge(scene, ima, em, co, &hit); + uv_find_nearest_edge(scene, ima, em, co, &hit); if(hit.efa == NULL) { BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_CANCELLED; @@ -1724,7 +1557,7 @@ else hitv[3]= 0xFFFFFFFF; } else if(selectmode == UV_SELECT_ISLAND) { - find_nearest_uv_vert(scene, ima, em, co, NULL, &hit); + uv_find_nearest_vert(scene, ima, em, co, NULL, &hit); if(hit.efa==NULL) { BKE_mesh_end_editmesh(obedit->data, em); @@ -2016,7 +1849,7 @@ RNA_float_get_array(op->ptr, "location", co); } - find_nearest_uv_vert(scene, ima, em, co, NULL, &hit); + uv_find_nearest_vert(scene, ima, em, co, NULL, &hit); hit_p= &hit; } @@ -3313,6 +3146,180 @@ RNA_def_int_vector(ot->srna, "tile", 2, NULL, 0, INT_MAX, "Tile", "Tile coordinate", 0, 10); } + +static int seams_from_islands_exec(bContext *C, wmOperator *op) +{ + UvVertMap *vmap; + Object *ob = CTX_data_edit_object(C); + Mesh *me= (Mesh*)ob->data; + EditMesh *em; + EditEdge *editedge; + float limit[2] = {STD_UV_CONNECT_LIMIT, STD_UV_CONNECT_LIMIT}; + char mark_seams = RNA_boolean_get(op->ptr, "mark_seams"); + char mark_sharp = RNA_boolean_get(op->ptr, "mark_sharp"); + + em = BKE_mesh_get_editmesh(me); + + if(!EM_texFaceCheck(em)) { + BKE_mesh_end_editmesh(ob->data, em); + return OPERATOR_CANCELLED; + } + + /* This code sets editvert->tmp.l to the index. This will be useful later on. */ + EM_init_index_arrays(em, 0, 0, 1); + vmap = EM_make_uv_vert_map(em, 0, 0, limit); + + for(editedge = em->edges.first; editedge; editedge = editedge->next) { + /* flags to determine if we uv is separated from first editface match */ + char separated1 = 0, separated2; + /* set to denote edge must be flagged as seam */ + char faces_separated = 0; + /* flag to keep track if uv1 is disconnected from first editface match */ + char v1coincident = 1; + /* For use with v1coincident. v1coincident will change only if we've had commonFaces */ + int commonFaces = 0; + + EditFace *efa1, *efa2; + + UvMapVert *mv1, *mvinit1, *mv2, *mvinit2, *mviter; + /* mv2cache stores the first of the list of coincident uv's for later comparison + * mv2sep holds the last separator and is copied to mv2cache when a hit is first found */ + UvMapVert *mv2cache = NULL, *mv2sep = NULL; + + mvinit1 = vmap->vert[editedge->v1->tmp.l]; + if(mark_seams) + editedge->seam = 0; + + for(mv1 = mvinit1; mv1 && !faces_separated; mv1 = mv1->next) { + if(mv1->separate && commonFaces) + v1coincident = 0; + + separated2 = 0; + efa1 = EM_get_face_for_index(mv1->f); + mvinit2 = vmap->vert[editedge->v2->tmp.l]; + + for(mv2 = mvinit2; mv2; mv2 = mv2->next) { + if(mv2->separate) + mv2sep = mv2; + + efa2 = EM_get_face_for_index(mv2->f); + if(efa1 == efa2) { + /* if v1 is not coincident no point in comparing */ + if(v1coincident) { + /* have we found previously anything? */ + if(mv2cache) { + /* flag seam unless proved to be coincident with previous hit */ + separated2 = 1; + for(mviter = mv2cache; mviter; mviter = mviter->next) { + if(mviter->separate && mviter != mv2cache) + break; + /* coincident with previous hit, do not flag seam */ + if(mviter == mv2) + separated2 = 0; + } + } + /* First hit case, store the hit in the cache */ + else { + mv2cache = mv2sep; + commonFaces = 1; + } + } + else + separated1 = 1; + + if(separated1 || separated2) { + faces_separated = 1; + break; + } + } + } + } + + if(faces_separated) { + if(mark_seams) + editedge->seam = 1; + if(mark_sharp) + editedge->sharp = 1; + } + } + + me->drawflag |= ME_DRAWSEAMS; + + EM_free_uv_vert_map(vmap); + EM_free_index_arrays(); + BKE_mesh_end_editmesh(me, em); + + DAG_id_tag_update(&me->id, 0); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, me); + + return OPERATOR_FINISHED; +} + + +static void UV_OT_seams_from_islands(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Seams From Islands"; + ot->description= "Set mesh seams according to island setup in the UV editor"; + ot->idname= "UV_OT_seams_from_islands"; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* api callbacks */ + ot->exec= seams_from_islands_exec; + ot->poll= ED_operator_uvedit; + + RNA_def_boolean(ot->srna, "mark_seams", 1, "Mark Seams", "Mark boundary edges as seams"); + RNA_def_boolean(ot->srna, "mark_sharp", 0, "Mark Sharp", "Mark boundary edges as sharp"); +} + +static int mark_seam_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *ob = CTX_data_edit_object(C); + Scene *scene = CTX_data_scene(C); + Mesh *me= (Mesh*)ob->data; + EditMesh *em= BKE_mesh_get_editmesh(me); + EditFace *efa; + + for(efa = em->faces.first; efa; efa = efa->next) { + MTFace *mt = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + int i, nverts = efa->v4? 4 : 3; + + for(i = 0; i < nverts; i++) + if(uvedit_edge_selected(scene, efa, mt, i)) + (*(&efa->e1 + i))->seam = 1; + } + + me->drawflag |= ME_DRAWSEAMS; + + if(scene->toolsettings->edge_mode_live_unwrap) + ED_unwrap_lscm(scene, ob, FALSE); + + BKE_mesh_end_editmesh(me, em); + + DAG_id_tag_update(&me->id, 0); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, me); + + return OPERATOR_FINISHED; +} + +static void UV_OT_mark_seam(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Mark Seams"; + ot->description= "Mark selected UV edges as seams"; + ot->idname= "UV_OT_mark_seam"; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* api callbacks */ + ot->exec= mark_seam_exec; + ot->poll= ED_operator_uvedit; +} + + /* ************************** registration **********************************/ void ED_operatortypes_uvedit(void) @@ -3332,6 +3339,8 @@ WM_operatortype_append(UV_OT_align); WM_operatortype_append(UV_OT_stitch); + WM_operatortype_append(UV_OT_seams_from_islands); + WM_operatortype_append(UV_OT_mark_seam); WM_operatortype_append(UV_OT_weld); WM_operatortype_append(UV_OT_pin); @@ -3358,36 +3367,51 @@ wmKeyMapItem *kmi; keymap= WM_keymap_find(keyconf, "UV Editor", 0, 0); - keymap->poll= ED_operator_uvedit; + keymap->poll= ED_operator_uvedit_can_uv_sculpt; + + /* Uv sculpt toggle */ + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", QKEY, KM_PRESS, 0, 0); + RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_uv_sculpt"); + + /* Mark edge seam */ + WM_keymap_add_item(keymap, "UV_OT_mark_seam", EKEY, KM_PRESS, KM_CTRL, 0); /* pick selection */ - WM_keymap_add_item(keymap, "UV_OT_select", SELECTMOUSE, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", 1); - WM_keymap_add_item(keymap, "UV_OT_select_loop", SELECTMOUSE, KM_PRESS, KM_ALT, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select_loop", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_ALT, 0)->ptr, "extend", 1); + RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select", SELECTMOUSE, KM_PRESS, 0, 0)->ptr, "extend", FALSE); + RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", TRUE); + RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select_loop", SELECTMOUSE, KM_PRESS, KM_ALT, 0)->ptr, "extend", FALSE); + RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select_loop", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_ALT, 0)->ptr, "extend", TRUE); /* border/circle selection */ - WM_keymap_add_item(keymap, "UV_OT_select_border", BKEY, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select_border", BKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "pinned", 1); + kmi = WM_keymap_add_item(keymap, "UV_OT_select_border", BKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "pinned", FALSE); + kmi = WM_keymap_add_item(keymap, "UV_OT_select_border", BKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "pinned", TRUE); + WM_keymap_add_item(keymap, "UV_OT_circle_select", CKEY, KM_PRESS, 0, 0); /* selection manipulation */ - WM_keymap_add_item(keymap, "UV_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "UV_OT_select_linked_pick", LKEY, KM_PRESS, 0, 0); + RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0)->ptr, "extend", FALSE); + RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select_linked_pick", LKEY, KM_PRESS, 0, 0)->ptr, "extend", FALSE); RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select_linked", LKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "extend", TRUE); RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select_linked_pick", LKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", TRUE); WM_keymap_add_item(keymap, "UV_OT_unlink_selected", LKEY, KM_PRESS, KM_ALT, 0); - WM_keymap_add_item(keymap, "UV_OT_select_all", AKEY, KM_PRESS, 0, 0); - RNA_enum_set(WM_keymap_add_item(keymap, "UV_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0)->ptr, "action", SEL_INVERT); + kmi = WM_keymap_add_item(keymap, "UV_OT_select_all", AKEY, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE); + kmi = WM_keymap_add_item(keymap, "UV_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0); + RNA_enum_set(kmi->ptr, "action", SEL_INVERT); + WM_keymap_add_item(keymap, "UV_OT_select_pinned", PKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_menu(keymap, "IMAGE_MT_uvs_weldalign", WKEY, KM_PRESS, 0, 0); /* uv operations */ WM_keymap_add_item(keymap, "UV_OT_stitch", VKEY, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "UV_OT_pin", PKEY, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_pin", PKEY, KM_PRESS, KM_ALT, 0)->ptr, "clear", 1); + kmi = WM_keymap_add_item(keymap, "UV_OT_pin", PKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "clear", FALSE); + kmi = WM_keymap_add_item(keymap, "UV_OT_pin", PKEY, KM_PRESS, KM_ALT, 0); + RNA_boolean_set(kmi->ptr, "clear", TRUE); /* unwrap */ WM_keymap_add_item(keymap, "UV_OT_unwrap", EKEY, KM_PRESS, 0, 0); @@ -3396,8 +3420,11 @@ WM_keymap_add_item(keymap, "UV_OT_average_islands_scale", AKEY, KM_PRESS, KM_CTRL, 0); /* hide */ - WM_keymap_add_item(keymap, "UV_OT_hide", HKEY, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "unselected", 1); + kmi = WM_keymap_add_item(keymap, "UV_OT_hide", HKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "unselected", FALSE); + kmi = WM_keymap_add_item(keymap, "UV_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "unselected", TRUE); + WM_keymap_add_item(keymap, "UV_OT_reveal", HKEY, KM_PRESS, KM_ALT, 0); /* cursor */ diff -Nru blender-2.61/source/blender/editors/uvedit/uvedit_parametrizer.c blender-2.62/source/blender/editors/uvedit/uvedit_parametrizer.c --- blender-2.61/source/blender/editors/uvedit/uvedit_parametrizer.c 2011-12-13 19:54:28.000000000 +0000 +++ blender-2.62/source/blender/editors/uvedit/uvedit_parametrizer.c 2012-02-15 19:38:37.000000000 +0000 @@ -91,7 +91,7 @@ } u; struct PEdge *edge; - float *co; + float co[3]; float uv[2]; unsigned char flag; @@ -655,11 +655,15 @@ { PEdge *e1 = f->edge, *e2 = e1->next, *e3 = e2->next; - if (e1->orig_uv && e2->orig_uv && e3->orig_uv) { + if (e1->orig_uv) { e1->old_uv[0] = e1->orig_uv[0]; e1->old_uv[1] = e1->orig_uv[1]; + } + if (e2->orig_uv) { e2->old_uv[0] = e2->orig_uv[0]; e2->old_uv[1] = e2->orig_uv[1]; + } + if (e3->orig_uv) { e3->old_uv[0] = e3->orig_uv[0]; e3->old_uv[1] = e3->orig_uv[1]; } @@ -669,11 +673,15 @@ { PEdge *e1 = f->edge, *e2 = e1->next, *e3 = e2->next; - if (e1->orig_uv && e2->orig_uv && e3->orig_uv) { + if (e1->orig_uv) { e1->orig_uv[0] = e1->old_uv[0]; e1->orig_uv[1] = e1->old_uv[1]; + } + if (e2->orig_uv) { e2->orig_uv[0] = e2->old_uv[0]; e2->orig_uv[1] = e2->old_uv[1]; + } + if (e3->orig_uv) { e3->orig_uv[0] = e3->old_uv[0]; e3->orig_uv[1] = e3->old_uv[1]; } @@ -684,7 +692,7 @@ static PVert *p_vert_add(PHandle *handle, PHashKey key, float *co, PEdge *e) { PVert *v = (PVert*)BLI_memarena_alloc(handle->arena, sizeof *v); - v->co = co; + copy_v3_v3(v->co, co); v->u.key = key; v->edge = e; v->flag = 0; @@ -708,7 +716,7 @@ { PVert *nv = (PVert*)BLI_memarena_alloc(chart->handle->arena, sizeof *nv); - nv->co = v->co; + copy_v3_v3(nv->co, v->co); nv->uv[0] = v->uv[0]; nv->uv[1] = v->uv[1]; nv->u.key = v->u.key; diff -Nru blender-2.61/source/blender/editors/uvedit/uvedit_smart_stitch.c blender-2.62/source/blender/editors/uvedit/uvedit_smart_stitch.c --- blender-2.61/source/blender/editors/uvedit/uvedit_smart_stitch.c 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/source/blender/editors/uvedit/uvedit_smart_stitch.c 2012-02-15 19:38:37.000000000 +0000 @@ -0,0 +1,1471 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Antony Riakiotakis. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/uvedit/uvedit_stitch.c + * \ingroup eduv + */ + + +#include +#include +#include + +#include "MEM_guardedalloc.h" + +#include "DNA_object_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_scene_types.h" + +#include "BLI_editVert.h" +#include "BLI_ghash.h" +#include "BLI_math.h" +#include "BLI_math_vector.h" +#include "BLI_string.h" + +#include "BKE_context.h" +#include "BKE_customdata.h" +#include "BKE_depsgraph.h" +#include "BKE_mesh.h" + +#include "ED_mesh.h" +#include "ED_uvedit.h" +#include "ED_screen.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "UI_view2d.h" + +#include "uvedit_intern.h" + +/* ********************** smart stitch operator *********************** */ + + +struct IslandStitchData; + +/* This is a straightforward implementation, count the uv's in the island that will move and take the mean displacement/rotation and apply it to all + * elements of the island except from the stitchable */ +typedef struct IslandStitchData{ + /* rotation can be used only for edges, for vertices there is no such notion */ + float rotation; + float translation[2]; + /* Used for rotation, the island will rotate around this point */ + float medianPoint[2]; + int numOfElements; + int num_rot_elements; + /* flag to remember if island has been added for preview */ + char addedForPreview; + /* flag an island to be considered for determining static island */ + char stitchableCandidate; + /* if edge rotation is used, flag so that vertex rotation is not used */ + char use_edge_rotation; +}IslandStitchData; + +/* just for averaging UVs */ +typedef struct UVVertAverage { + float uv[2]; + unsigned short count; +} UVVertAverage; + +typedef struct UvEdge { + /* index to uv buffer */ + unsigned int uv1; + unsigned int uv2; + /* general use flag (Used to check if edge is boundary here, and propagates to adjacency elements) */ + char flag; + /* element that guarantees element->face has the face on element->tfindex and element->tfindex+1 is the second uv */ + UvElement *element; +}UvEdge; + + +/* stitch state object */ +typedef struct StitchState { + /* use limit flag */ + char use_limit; + /* limit to operator, same as original operator */ + float limit_dist; + /* snap uv islands together during stitching */ + char snap_islands; + /* stich at midpoints or at islands */ + char midpoints; + /* editmesh, cached for use in modal handler */ + EditMesh *em; + /* element map for getting info about uv connectivity */ + UvElementMap *element_map; + /* edge container */ + UvEdge *uvedges; + /* container of first of a group of coincident uvs, these will be operated upon */ + UvElement **uvs; + /* maps uvelements to their first coincident uv */ + int *map; + /* 2D normals per uv to calculate rotation for snapping */ + float *normals; + /* edge storage */ + UvEdge *edges; + + /* count of separate uvs and edges */ + int total_boundary_edges; + int total_separate_uvs; + /* hold selection related information */ + UvElement **selection_stack; + int selection_size; + /* island that stays in place */ + int static_island; + /* store number of primitives per face so that we can allocate the active island buffer later */ + unsigned int *quads_per_island; + unsigned int *tris_per_island; +} StitchState; + + +/* + * defines for UvElement flags + */ +#define STITCH_SELECTED 1 +#define STITCH_STITCHABLE 2 +#define STITCH_PROCESSED 4 +#define STITCH_BOUNDARY 8 +#define STITCH_STITCHABLE_CANDIDATE 16 + +#define STITCH_NO_PREVIEW -1 + +/* previewer stuff (see uvedit_intern.h for more info) */ +static StitchPreviewer *_stitch_preview; + +/* constructor */ +static StitchPreviewer * stitch_preview_init(void) +{ + _stitch_preview = MEM_mallocN(sizeof(StitchPreviewer), "stitch_previewer"); + _stitch_preview->preview_quads = NULL; + _stitch_preview->preview_tris = NULL; + _stitch_preview->preview_stitchable = NULL; + _stitch_preview->preview_unstitchable = NULL; + + _stitch_preview->num_quads = 0; + _stitch_preview->num_tris = 0; + _stitch_preview->num_stitchable = 0; + _stitch_preview->num_unstitchable = 0; + + _stitch_preview->static_quads = NULL; + _stitch_preview->static_tris = NULL; + + _stitch_preview->num_static_tris = 0; + _stitch_preview->num_static_quads = 0; + + return _stitch_preview; +} + +/* destructor...yeah this should be C++ :) */ +static void stitch_preview_delete(void) +{ + if(_stitch_preview) + { + if(_stitch_preview->preview_quads){ + MEM_freeN(_stitch_preview->preview_quads); + _stitch_preview->preview_quads = NULL; + } + if(_stitch_preview->preview_tris){ + MEM_freeN(_stitch_preview->preview_tris); + _stitch_preview->preview_tris = NULL; + } + if(_stitch_preview->preview_stitchable){ + MEM_freeN(_stitch_preview->preview_stitchable); + _stitch_preview->preview_stitchable = NULL; + } + if(_stitch_preview->preview_unstitchable){ + MEM_freeN(_stitch_preview->preview_unstitchable); + _stitch_preview->preview_unstitchable = NULL; + } + if(_stitch_preview->static_quads){ + MEM_freeN(_stitch_preview->static_quads); + _stitch_preview->static_quads = NULL; + } + if(_stitch_preview->static_tris){ + MEM_freeN(_stitch_preview->static_tris); + _stitch_preview->static_tris = NULL; + } + MEM_freeN(_stitch_preview); + _stitch_preview = NULL; + } +} + + +/* "getter method" */ +StitchPreviewer *uv_get_stitch_previewer(void) +{ + return _stitch_preview; +} + +#define HEADER_LENGTH 256 + +/* This function updates the header of the UV editor when the stitch tool updates its settings */ +static void stitch_update_header(StitchState *stitch_state, bContext *C) +{ + static char str[] = "(S)nap %s, (M)idpoints %s, (L)imit %.2f (Alt Wheel adjust) %s, Switch (I)sland, shift select vertices"; + + char msg[HEADER_LENGTH]; + ScrArea *sa= CTX_wm_area(C); + + if(sa) { + BLI_snprintf(msg, HEADER_LENGTH, str, + stitch_state->snap_islands? "On" : "Off", + stitch_state->midpoints? "On": "Off", + stitch_state->limit_dist, + stitch_state->use_limit? "On" : "Off"); + + ED_area_headerprint(sa, msg); + } +} + +static int getNumOfIslandUvs(UvElementMap *elementMap, int island){ + if(island == elementMap->totalIslands-1){ + return elementMap->totalUVs - elementMap->islandIndices[island]; + }else{ + return elementMap->islandIndices[island+1] - elementMap->islandIndices[island]; + } +} + +static void stitch_uv_rotate(float rotation, float medianPoint[2], float uv[2]){ + float uv_rotation_result[2]; + + uv[0] -= medianPoint[0]; + uv[1] -= medianPoint[1]; + + uv_rotation_result[0] = cos(rotation)*uv[0] - sin(rotation)*uv[1]; + uv_rotation_result[1] = sin(rotation)*uv[0] + cos(rotation)*uv[1]; + + uv[0] = uv_rotation_result[0] + medianPoint[0]; + uv[1] = uv_rotation_result[1] + medianPoint[1]; +} + +static int stitch_check_uvs_stitchable(UvElement *element, UvElement *element_iter, StitchState *state){ + float limit; + int do_limit; + + if(element_iter == element){ + return 0; + } + + limit = state->limit_dist; + do_limit = state->use_limit; + + if(do_limit){ + MTFace *mtface_orig = CustomData_em_get(&state->em->fdata, element->face->data, CD_MTFACE); + MTFace *mtface_iter = CustomData_em_get(&state->em->fdata, element_iter->face->data, CD_MTFACE); + + if(fabs(mtface_orig->uv[element->tfindex][0] - mtface_iter->uv[element_iter->tfindex][0]) < limit + && fabs(mtface_orig->uv[element->tfindex][1] - mtface_iter->uv[element_iter->tfindex][1]) < limit){ + return 1; + }else + return 0; + }else + return 1; +} + + +static int stitch_check_uvs_state_stitchable(UvElement *element, UvElement *element_iter, StitchState *state){ + if((state->snap_islands && element->island == element_iter->island) || + (!state->midpoints && element->island == element_iter->island)) + return 0; + + return stitch_check_uvs_stitchable(element, element_iter, state); +} + + +/* calculate snapping for islands */ +static void stitch_calculate_island_snapping(StitchState *state, StitchPreviewer *preview, IslandStitchData *island_stitch_data, int final){ + int i; + EditFace *efa; + MTFace *mt; + UvElement *element; + + for(i = 0; i < state->element_map->totalIslands; i++){ + if(island_stitch_data[i].addedForPreview){ + int numOfIslandUVs = 0, j; + + /* check to avoid divide by 0 */ + if(island_stitch_data[i].num_rot_elements>0){ + island_stitch_data[i].rotation /= island_stitch_data[i].num_rot_elements; + island_stitch_data[i].medianPoint[0] /= island_stitch_data[i].numOfElements; + island_stitch_data[i].medianPoint[1] /= island_stitch_data[i].numOfElements; + } + island_stitch_data[i].translation[0] /= island_stitch_data[i].numOfElements; + island_stitch_data[i].translation[1] /= island_stitch_data[i].numOfElements; + numOfIslandUVs = getNumOfIslandUvs(state->element_map, i); + element = &state->element_map->buf[state->element_map->islandIndices[i]]; + for(j = 0; j < numOfIslandUVs; j++, element++){ + /* stitchable uvs have already been processed, don't process */ + if(!(element->flag & STITCH_PROCESSED)){ + efa = element->face; + mt = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE); + if(final){ + + stitch_uv_rotate(island_stitch_data[i].rotation, island_stitch_data[i].medianPoint, mt->uv[element->tfindex]); + + mt->uv[element->tfindex][0] += island_stitch_data[i].translation[0]; + mt->uv[element->tfindex][1] += island_stitch_data[i].translation[1]; + } + else if(efa->tmp.l != STITCH_NO_PREVIEW){ + if(efa->v4){ + + stitch_uv_rotate(island_stitch_data[i].rotation, island_stitch_data[i].medianPoint, &preview->preview_quads[efa->tmp.l + 2*element->tfindex]); + + preview->preview_quads[efa->tmp.l + 2*element->tfindex] += island_stitch_data[i].translation[0]; + preview->preview_quads[efa->tmp.l + 2*element->tfindex + 1] += island_stitch_data[i].translation[1]; + } + else { + + stitch_uv_rotate(island_stitch_data[i].rotation, island_stitch_data[i].medianPoint, &preview->preview_tris[efa->tmp.l + 2*element->tfindex]); + + preview->preview_tris[efa->tmp.l + 2*element->tfindex] += island_stitch_data[i].translation[0]; + preview->preview_tris[efa->tmp.l + 2*element->tfindex + 1] += island_stitch_data[i].translation[1]; + } + } + } + /* cleanup */ + element->flag &= STITCH_SELECTED; + } + } + } +} + + + +static void stitch_island_calculate_edge_rotation(UvEdge *edge, StitchState *state, UVVertAverage *uv_average, unsigned int *uvfinal_map, IslandStitchData *island_stitch_data) +{ + UvElement *element1, *element2; + EditFace *efa1; + EditFace *efa2; + MTFace *mt1; + MTFace *mt2; + float uv1[2], uv2[2]; + float edgecos, edgesin; + int index1, index2; + float rotation; + + element1 = state->uvs[edge->uv1]; + element2 = state->uvs[edge->uv2]; + + efa1 = element1->face; + mt1 = CustomData_em_get(&state->em->fdata, efa1->data, CD_MTFACE); + efa2 = element2->face; + mt2 = CustomData_em_get(&state->em->fdata, efa2->data, CD_MTFACE); + + index1 = uvfinal_map[element1 - state->element_map->buf]; + index2 = uvfinal_map[element2 - state->element_map->buf]; + + /* the idea here is to take the directions of the edges and find the rotation between final and initial + * direction. This, using inner and outer vector products, gives the angle. Directions are differences so... */ + uv1[0] = mt2->uv[element2->tfindex][0] - mt1->uv[element1->tfindex][0]; + uv1[1] = mt2->uv[element2->tfindex][1] - mt1->uv[element1->tfindex][1]; + + uv2[0] = uv_average[index2].uv[0] - uv_average[index1].uv[0]; + uv2[1] = uv_average[index2].uv[1] - uv_average[index1].uv[1]; + + normalize_v2(uv1); + normalize_v2(uv2); + + edgecos = uv1[0]*uv2[0] + uv1[1]*uv2[1]; + edgesin = uv1[0]*uv2[1] - uv2[0]*uv1[1]; + + rotation = (edgesin > 0)? acos(MAX2(-1.0, MIN2(1.0, edgecos))): -acos(MAX2(-1.0, MIN2(1.0, edgecos))); + + island_stitch_data[element1->island].num_rot_elements++; + island_stitch_data[element1->island].rotation += rotation; +} + + +static void stitch_island_calculate_vert_rotation(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data) +{ + float edgecos = 1, edgesin = 0; + int index; + UvElement *element_iter; + float rotation = 0; + + if(element->island == state->static_island && !state->midpoints) + return; + + index = (*(&element->face->v1 + element->tfindex))->tmp.l; + + element_iter = state->element_map->vert[index]; + + for(; element_iter; element_iter = element_iter->next){ + if(element_iter->separate && stitch_check_uvs_state_stitchable(element, element_iter, state)){ + int index_tmp1, index_tmp2; + float normal[2]; + /* easily possible*/ + + index_tmp1 = element_iter - state->element_map->buf; + index_tmp1 = state->map[index_tmp1]; + index_tmp2 = element - state->element_map->buf; + index_tmp2 = state->map[index_tmp2]; + + negate_v2_v2(normal, state->normals + index_tmp2*2); + edgecos = dot_v2v2(normal, state->normals + index_tmp1*2); + edgesin = cross_v2v2(normal, state->normals + index_tmp1*2); + rotation += (edgesin > 0)? acos(edgecos): -acos(edgecos); + } + } + + if(state->midpoints) + rotation /= 2.0; + island_stitch_data[element->island].num_rot_elements++; + island_stitch_data[element->island].rotation += rotation; +} + + +static void stitch_state_delete(StitchState *stitch_state) +{ + if(stitch_state){ + if(stitch_state->element_map){ + EM_free_uv_element_map(stitch_state->element_map); + } + if(stitch_state->uvs){ + MEM_freeN(stitch_state->uvs); + } + if(stitch_state->selection_stack){ + MEM_freeN(stitch_state->selection_stack); + } + if(stitch_state->quads_per_island){ + MEM_freeN(stitch_state->quads_per_island); + } + if(stitch_state->tris_per_island){ + MEM_freeN(stitch_state->tris_per_island); + } + if(stitch_state->map){ + MEM_freeN(stitch_state->map); + } + if(stitch_state->normals){ + MEM_freeN(stitch_state->normals); + } + if(stitch_state->edges){ + MEM_freeN(stitch_state->edges); + } + MEM_freeN(stitch_state); + } +} + + + +/* checks for remote uvs that may be stitched with a certain uv, flags them if stitchable. */ +static void determine_uv_stitchability(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data){ + int vert_index; + UvElement *element_iter; + + vert_index = (*(&element->face->v1 + element->tfindex))->tmp.l; + element_iter = state->element_map->vert[vert_index]; + + for(; element_iter; element_iter = element_iter->next){ + if(element_iter->separate){ + if(element_iter == element){ + continue; + } + if(stitch_check_uvs_stitchable(element, element_iter, state)){ + island_stitch_data[element_iter->island].stitchableCandidate = 1; + island_stitch_data[element->island].stitchableCandidate = 1; + element->flag |= STITCH_STITCHABLE_CANDIDATE; + } + } + } +} + + +/* set preview buffer position of UV face in editface->tmp.l */ +static void stitch_set_face_preview_buffer_position(EditFace *efa, StitchPreviewer *preview) +{ + if(efa->tmp.l == STITCH_NO_PREVIEW) + { + if(efa->v4) + { + efa->tmp.l = preview->num_quads*8; + preview->num_quads++; + } else { + efa->tmp.l = preview->num_tris*6; + preview->num_tris++; + } + } +} + + +/* setup face preview for all coincident uvs and their faces */ +static void stitch_setup_face_preview_for_uv_group(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data){ + StitchPreviewer *preview = uv_get_stitch_previewer(); + + /* static island does not change so returning immediately */ + if(state->snap_islands && !state->midpoints && state->static_island == element->island) + return; + + if(state->snap_islands){ + island_stitch_data[element->island].addedForPreview = 1; + } + + do{ + stitch_set_face_preview_buffer_position(element->face, preview); + element = element->next; + }while(element && !element->separate); +} + + +/* checks if uvs are indeed stitchable and registers so that they can be shown in preview */ +static void stitch_validate_stichability(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data){ + UvElement *element_iter; + StitchPreviewer *preview; + + preview = uv_get_stitch_previewer(); + element_iter = state->element_map->vert[(*(&element->face->v1 + element->tfindex))->tmp.l]; + + for(; element_iter; element_iter = element_iter->next){ + if(element_iter->separate){ + if(element_iter == element) + continue; + if(stitch_check_uvs_state_stitchable(element, element_iter, state)){ + if((element_iter->island == state->static_island) || (element->island == state->static_island)){ + element->flag |= STITCH_STITCHABLE; + preview->num_stitchable++; + stitch_setup_face_preview_for_uv_group(element, state, island_stitch_data); + return; + } + } + } + } + + /* this can happen if the uvs to be stitched are not on a stitchable island */ + if(!(element->flag & STITCH_STITCHABLE)){ + preview->num_unstitchable++; + } +} + +/* main processing function. It calculates preview and final positions. */ +static int stitch_process_data(StitchState *state, Scene *scene, int final) +{ + int i; + StitchPreviewer *preview; + IslandStitchData *island_stitch_data = NULL; + int previous_island = state->static_island; + EditFace *efa; + EditVert *ev; + UVVertAverage *final_position; + char stitch_midpoints = state->midpoints; + /* used to map uv indices to uvaverage indices for selection */ + unsigned int *uvfinal_map; + + /* cleanup previous preview */ + stitch_preview_delete(); + preview = stitch_preview_init(); + if(preview == NULL) + return 0; + /* each face holds its position in the preview buffer in tmp. -1 is uninitialized */ + for(efa = state->em->faces.first; efa; efa = efa->next){ + efa->tmp.l = STITCH_NO_PREVIEW; + } + + island_stitch_data = MEM_callocN(sizeof(*island_stitch_data)*state->element_map->totalIslands, "stitch_island_data"); + if(!island_stitch_data){ + return 0; + } + + /* store indices to editVerts. */ + for(ev = state->em->verts.first, i = 0; ev; ev = ev->next, i++){ + ev->tmp.l = i; + } + + /***************************************** + * First determine stitchability of uvs * + *****************************************/ + + for(i = 0; i < state->selection_size; i++){ + UvElement *element = state->selection_stack[i]; + determine_uv_stitchability(element, state, island_stitch_data); + } + + /* set static island to one that is added for preview */ + state->static_island %= state->element_map->totalIslands; + while(!(island_stitch_data[state->static_island].stitchableCandidate)){ + state->static_island++; + state->static_island %= state->element_map->totalIslands; + /* this is entirely possible if for example limit stitching with no stitchable verts or no selection */ + if(state->static_island == previous_island) + break; + } + + for(i = 0; i < state->selection_size; i++){ + UvElement *element = state->selection_stack[i]; + if(element->flag & STITCH_STITCHABLE_CANDIDATE){ + element->flag &= ~STITCH_STITCHABLE_CANDIDATE; + stitch_validate_stichability(element, state, island_stitch_data); + }else{ + /* add to preview for unstitchable */ + preview->num_unstitchable++; + } + } + + /***************************************** + * Setup preview for stitchable islands * + *****************************************/ + if(state->snap_islands){ + for(i = 0; i < state->element_map->totalIslands; i++){ + if(island_stitch_data[i].addedForPreview){ + int numOfIslandUVs = 0, j; + UvElement *element; + numOfIslandUVs = getNumOfIslandUvs(state->element_map, i); + element = &state->element_map->buf[state->element_map->islandIndices[i]]; + for(j = 0; j < numOfIslandUVs; j++, element++){ + stitch_set_face_preview_buffer_position(element->face, preview); + } + } + } + } + + /********************************************************************* + * Setup the preview buffers and fill them with the appropriate data * + *********************************************************************/ + if(!final){ + unsigned int tricount = 0, quadcount = 0; + int stitchBufferIndex = 0, unstitchBufferIndex = 0; + /* initialize the preview buffers */ + preview->preview_quads = (float *)MEM_mallocN(preview->num_quads*sizeof(float)*8, "quad_uv_stitch_prev"); + preview->preview_tris = (float *)MEM_mallocN(preview->num_tris*sizeof(float)*6, "tri_uv_stitch_prev"); + + preview->preview_stitchable = (float *)MEM_mallocN(preview->num_stitchable*sizeof(float)*2, "stitch_preview_stichable_data"); + preview->preview_unstitchable = (float *)MEM_mallocN(preview->num_unstitchable*sizeof(float)*2, "stitch_preview_unstichable_data"); + + preview->static_quads = (float *)MEM_mallocN(state->quads_per_island[state->static_island]*sizeof(float)*8, "static_island_preview_quads"); + preview->static_tris = (float *)MEM_mallocN(state->tris_per_island[state->static_island]*sizeof(float)*6, "static_island_preview_tris"); + + preview->num_static_quads = state->quads_per_island[state->static_island]; + preview->num_static_tris = state->tris_per_island[state->static_island]; + /* will cause cancel and freeing of all data structures so OK */ + if(!preview->preview_quads || !preview->preview_tris || !preview->preview_stitchable || !preview->preview_unstitchable){ + return 0; + } + + /* copy data from MTFaces to the preview display buffers */ + for(efa = state->em->faces.first; efa; efa = efa->next){ + MTFace *mt = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE); + UvElement *element = ED_get_uv_element(state->element_map, efa, 0); + + if(element){ + if(efa->tmp.l != STITCH_NO_PREVIEW){ + if(efa->v4) { + memcpy(preview->preview_quads+efa->tmp.l, &mt->uv[0][0], 8*sizeof(float)); + } else { + memcpy(preview->preview_tris+efa->tmp.l, &mt->uv[0][0], 6*sizeof(float)); + } + } + + if(element->island == state->static_island){ + if(efa->v4) { + memcpy(preview->static_quads + quadcount*8, &mt->uv[0][0], 8*sizeof(float)); + quadcount++; + } else { + memcpy(preview->static_tris + tricount*6, &mt->uv[0][0], 6*sizeof(float)); + tricount++; + } + } + } + } + + /* fill the appropriate preview buffers */ + for(i = 0; i < state->total_separate_uvs; i++){ + UvElement *element = (UvElement *)state->uvs[i]; + if(element->flag & STITCH_STITCHABLE){ + MTFace *mt; + efa = element->face; + mt = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE); + + preview->preview_stitchable[stitchBufferIndex*2] = mt->uv[element->tfindex][0]; + preview->preview_stitchable[stitchBufferIndex*2 + 1] = mt->uv[element->tfindex][1]; + stitchBufferIndex++; + } + else if(element->flag & STITCH_SELECTED){ + MTFace *mt; + efa = element->face; + mt = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE); + + preview->preview_unstitchable[unstitchBufferIndex*2] = mt->uv[element->tfindex][0]; + preview->preview_unstitchable[unstitchBufferIndex*2 + 1] = mt->uv[element->tfindex][1]; + unstitchBufferIndex++; + } + } + } + + /****************************************************** + * Here we calculate the final coordinates of the uvs * + ******************************************************/ + + final_position = MEM_callocN(state->selection_size*sizeof(*final_position), "stitch_uv_average"); + uvfinal_map = MEM_mallocN(state->element_map->totalUVs*sizeof(*uvfinal_map), "stitch_uv_final_map"); + + /* first pass, calculate final position for stitchable uvs of the static island */ + for(i = 0; i < state->selection_size; i++){ + UvElement *element = state->selection_stack[i]; + if(element->flag & STITCH_STITCHABLE){ + MTFace *mt; + + UvElement *element_iter; + + uvfinal_map[element - state->element_map->buf] = i; + + efa = element->face; + mt = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE); + + final_position[i].uv[0] = mt->uv[element->tfindex][0]; + final_position[i].uv[1] = mt->uv[element->tfindex][1]; + final_position[i].count = 1; + + if(state->snap_islands && element->island == state->static_island && !stitch_midpoints) + continue; + + element_iter = state->element_map->vert[(*(&element->face->v1 + element->tfindex))->tmp.l]; + + for(;element_iter; element_iter = element_iter->next){ + if(element_iter->separate){ + if(stitch_check_uvs_state_stitchable(element, element_iter, state)){ + efa = element_iter->face; + mt = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE); + if(stitch_midpoints){ + final_position[i].uv[0] += mt->uv[element_iter->tfindex][0]; + final_position[i].uv[1] += mt->uv[element_iter->tfindex][1]; + final_position[i].count++; + }else if(element_iter->island == state->static_island){ + /* if multiple uvs on the static island exist, + * last checked remains. to disambiguate we need to limit or use + * edge stitch */ + final_position[i].uv[0] = mt->uv[element_iter->tfindex][0]; + final_position[i].uv[1] = mt->uv[element_iter->tfindex][1]; + } + } + } + } + } + if(stitch_midpoints){ + final_position[i].uv[0] /= final_position[i].count; + final_position[i].uv[1] /= final_position[i].count; + } + } + + /* second pass, calculate island rotation and translation before modifying any uvs */ + if(state->snap_islands){ + for(i = 0; i < state->selection_size; i++){ + UvElement *element = state->selection_stack[i]; + if(element->flag & STITCH_STITCHABLE){ + MTFace *mt; + efa = element->face; + mt = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE); + + /* accumulate each islands' translation from stitchable elements. it is important to do here + * because in final pass MTFaces get modified and result is zero. */ + island_stitch_data[element->island].translation[0] += final_position[i].uv[0] - mt->uv[element->tfindex][0]; + island_stitch_data[element->island].translation[1] += final_position[i].uv[1] - mt->uv[element->tfindex][1]; + island_stitch_data[element->island].medianPoint[0] += mt->uv[element->tfindex][0]; + island_stitch_data[element->island].medianPoint[1] += mt->uv[element->tfindex][1]; + island_stitch_data[element->island].numOfElements++; + } + } + + /* only calculate rotation when an edge has been fully selected */ + for(i = 0; i < state->total_boundary_edges; i++){ + UvEdge *edge = state->edges+i; + if((state->uvs[edge->uv1]->flag & STITCH_STITCHABLE) && (state->uvs[edge->uv2]->flag & STITCH_STITCHABLE)){ + stitch_island_calculate_edge_rotation(edge, state, final_position, uvfinal_map, island_stitch_data); + island_stitch_data[state->uvs[edge->uv1]->island].use_edge_rotation = 1; + } + } + + for(i = 0; i < state->selection_size; i++){ + UvElement *element = state->selection_stack[i]; + if(!island_stitch_data[element->island].use_edge_rotation){ + if(element->flag & STITCH_STITCHABLE){ + stitch_island_calculate_vert_rotation(element, state, island_stitch_data); + } + } + } + + } + + /* third pass, propagate changes to coincident uvs */ + for(i = 0; i < state->selection_size; i++){ + UvElement *element = state->selection_stack[i]; + if(element->flag & STITCH_STITCHABLE){ + UvElement *element_iter = element; + /* propagate to coincident uvs */ + do{ + MTFace *mt; + + efa = element_iter->face; + mt = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE); + + element_iter->flag |= STITCH_PROCESSED; + /* either flush to preview or to the MTFace, if final */ + if(final){ + mt->uv[element_iter->tfindex][0] = final_position[i].uv[0]; + mt->uv[element_iter->tfindex][1] = final_position[i].uv[1]; + + uvedit_uv_select(scene, efa, mt, element_iter->tfindex); + }else if(efa->tmp.l != STITCH_NO_PREVIEW){ + if(efa->v4){ + *(preview->preview_quads+efa->tmp.l + element_iter->tfindex*2) = final_position[i].uv[0]; + *(preview->preview_quads+efa->tmp.l + element_iter->tfindex*2 + 1) = final_position[i].uv[1]; + }else{ + *(preview->preview_tris+efa->tmp.l + element_iter->tfindex*2) = final_position[i].uv[0]; + *(preview->preview_tris+efa->tmp.l + element_iter->tfindex*2 + 1) = final_position[i].uv[1]; + } + } + + /* end of calculations, keep only the selection flag */ + if( (!state->snap_islands) || ((!stitch_midpoints) && (element_iter->island == state->static_island))) { + element_iter->flag &= STITCH_SELECTED; + } + + element_iter = element_iter->next; + }while(element_iter && !element_iter->separate); + } + } + + /* final pass, calculate Island translation/rotation if needed */ + if(state->snap_islands){ + stitch_calculate_island_snapping(state, preview, island_stitch_data, final); + } + + MEM_freeN(final_position); + MEM_freeN(uvfinal_map); + MEM_freeN(island_stitch_data); + + return 1; +} + +/* Stitch hash initialisation functions */ +static unsigned int uv_edge_hash(const void *key){ + UvEdge *edge = (UvEdge *)key; + return + BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv2)) + + BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv1)); +} + +static int uv_edge_compare(const void *a, const void *b){ + UvEdge *edge1 = (UvEdge *)a; + UvEdge *edge2 = (UvEdge *)b; + + if((edge1->uv1 == edge2->uv1) && (edge1->uv2 == edge2->uv2)){ + return 0; + } + return 1; +} + + +/* Select all common uvs */ +static void stitch_select_uv(UvElement *element, StitchState *stitch_state, int always_select) +{ + /* This works due to setting of tmp in find nearest uv vert */ + UvElement *element_iter; + UvElement **selection_stack = stitch_state->selection_stack; + + element_iter = stitch_state->element_map->vert[(*(&element->face->v1 + element->tfindex))->tmp.l]; + /* first deselect all common uvs */ + for(; element_iter; element_iter = element_iter->next){ + if(element_iter->separate){ + /* only separators go to selection */ + if(element_iter->flag & STITCH_SELECTED){ + int i; + if(always_select) + continue; + + element_iter->flag &= ~STITCH_SELECTED; + for(i = 0; i < stitch_state->selection_size; i++){ + if(selection_stack[i] == element_iter){ + (stitch_state->selection_size)--; + selection_stack[i] = selection_stack[stitch_state->selection_size]; + break; + } + } + }else{ + element_iter->flag |= STITCH_SELECTED; + selection_stack[(stitch_state->selection_size)++] = element_iter; + } + } + } +} + +static void stitch_calculate_edge_normal(EditMesh *em, UvEdge *edge, float *normal) +{ + UvElement *element = edge->element; + EditFace *efa = element->face; + MTFace *mt = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + int nverts = efa->v4?4 : 3; + int index = (element->tfindex + 2)%nverts; + float tangent[2], internal[2]; + + sub_v2_v2v2(tangent, mt->uv[(element->tfindex + 1)%nverts], mt->uv[element->tfindex]); + sub_v2_v2v2(internal, mt->uv[index], mt->uv[element->tfindex]); + + /* choose one of the normals */ + normal[0] = tangent[1]; + normal[1] = -tangent[0]; + + /* if normal points inside the face, invert */ + if(dot_v2v2(normal, internal) > 0){ + normal[0] = -tangent[1]; + normal[1] = tangent[0]; + } + + normalize_v2(normal); +} + +static int stitch_init(bContext *C, wmOperator *op) +{ + /* for fast edge lookup... */ + GHash *edgeHash; + /* ...and actual edge storage */ + UvEdge *edges; + int total_edges; + /* maps uvelements to their first coincident uv */ + int *map; + int counter = 0, i; + EditFace *efa; + EditMesh *em; + GHashIterator* ghi; + UvEdge *all_edges; + StitchState *state = MEM_mallocN(sizeof(StitchState), "stitch state"); + Scene *scene = CTX_data_scene(C); + ToolSettings *ts = scene->toolsettings; + + Object *obedit = CTX_data_edit_object(C); + + op->customdata = state; + + if(!state) + return 0; + + /* initialize state */ + state->use_limit = RNA_boolean_get(op->ptr, "use_limit"); + state->limit_dist = RNA_float_get(op->ptr, "limit"); + state->em = em = BKE_mesh_get_editmesh((Mesh*)obedit->data); + state->snap_islands = RNA_boolean_get(op->ptr, "snap_islands"); + state->static_island = RNA_int_get(op->ptr, "static_island"); + state->midpoints = RNA_boolean_get(op->ptr, "midpoint_snap"); + /* in uv synch selection, all uv's are visible */ + if(ts->uv_flag & UV_SYNC_SELECTION){ + state->element_map = EM_make_uv_element_map(state->em, 0, 1); + }else{ + state->element_map = EM_make_uv_element_map(state->em, 1, 1); + } + if(!state->element_map){ + stitch_state_delete(state); + return 0; + } + + /* Entirely possible if redoing last operator that static island is bigger than total number of islands. + * This ensures we get no hang in the island checking code in stitch_process_data. */ + state->static_island %= state->element_map->totalIslands; + + /* Count 'unique' uvs */ + for(i = 0; i < state->element_map->totalUVs; i++){ + if(state->element_map->buf[i].separate){ + counter++; + } + } + + /* Allocate the unique uv buffers */ + state->uvs = MEM_mallocN(sizeof(*state->uvs)*counter, "uv_stitch_unique_uvs"); + /* internal uvs need no normals but it is hard and slow to keep a map of + * normals only for boundary uvs, so allocating for all uvs */ + state->normals = MEM_callocN(sizeof(*state->normals)*counter*2, "uv_stitch_normals"); + state->total_separate_uvs = counter; + /* we can at most have totalUVs edges or uvs selected. Actually they are less, considering we store only + * unique uvs for processing but I am accounting for all bizarre cases, especially for edges, this way */ + state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack)*counter, "uv_stitch_selection_stack"); + state->map = map = MEM_mallocN(sizeof(*map)*state->element_map->totalUVs, "uv_stitch_unique_map"); + /* Allocate the edge stack */ + edgeHash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "stitch_edge_hash"); + all_edges = MEM_mallocN(sizeof(*all_edges)*state->element_map->totalUVs, "stitch_all_edges"); + + if(!state->selection_stack || !state->uvs || !map || !edgeHash || !all_edges){ + stitch_state_delete(state); + return 0; + } + + /* So that we can use this as index for the UvElements */ + counter = -1; + /* initialize the unique UVs and map */ + for(i = 0; i < state->em->totvert; i++){ + UvElement *element = state->element_map->vert[i]; + for(; element; element = element->next){ + if(element->separate){ + counter++; + state->uvs[counter] = element; + } + /* pointer arithmetic to the rescue, as always :)*/ + map[element - state->element_map->buf] = counter; + } + } + + /* Now, on to generate our uv connectivity data */ + for(efa = state->em->faces.first, counter = 0; efa; efa = efa->next){ + if((ts->uv_flag & UV_SYNC_SELECTION) || (!efa->h && efa->f & SELECT)){ + int nverts = efa->v4 ? 4 : 3; + + for(i = 0; i < nverts; i++){ + UvElement *element = ED_get_uv_element(state->element_map, efa, i); + int offset1, itmp1 = element - state->element_map->buf; + int offset2, itmp2 = ED_get_uv_element(state->element_map, efa, (i+1)%nverts) - state->element_map->buf; + + offset1 = map[itmp1]; + offset2 = map[itmp2]; + + all_edges[counter].flag = 0; + all_edges[counter].element = element; + /* using an order policy, sort uvs according to address space. This avoids + * Having two different UvEdges with the same uvs on different positions */ + if(offset1 < offset2){ + all_edges[counter].uv1 = offset1; + all_edges[counter].uv2 = offset2; + } + else{ + all_edges[counter].uv1 = offset2; + all_edges[counter].uv2 = offset1; + } + + if(BLI_ghash_haskey(edgeHash, &all_edges[counter])){ + char *flag = BLI_ghash_lookup(edgeHash, &all_edges[counter]); + *flag = 0; + } + else{ + BLI_ghash_insert(edgeHash, &all_edges[counter], &(all_edges[counter].flag)); + all_edges[counter].flag = STITCH_BOUNDARY; + } + counter++; + } + } + } + + + ghi = BLI_ghashIterator_new(edgeHash); + total_edges = 0; + /* fill the edges with data */ + for(; !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi)){ + UvEdge *edge = ((UvEdge *)BLI_ghashIterator_getKey(ghi)); + if(edge->flag & STITCH_BOUNDARY){ + total_edges++; + } + } + state->edges = edges = MEM_mallocN(sizeof(*edges)*total_edges, "stitch_edges"); + if(!ghi || !edges){ + MEM_freeN(all_edges); + stitch_state_delete(state); + return 0; + } + + state->total_boundary_edges = total_edges; + + /* fill the edges with data */ + for(i = 0, BLI_ghashIterator_init(ghi, edgeHash); !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi)){ + UvEdge *edge = ((UvEdge *)BLI_ghashIterator_getKey(ghi)); + if(edge->flag & STITCH_BOUNDARY){ + edges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(ghi)); + } + } + + /* cleanup temporary stuff */ + BLI_ghashIterator_free(ghi); + MEM_freeN(all_edges); + + /* refill hash with new pointers to cleanup duplicates */ + BLI_ghash_free(edgeHash, NULL, NULL); + + /***** calculate 2D normals for boundary uvs *****/ + + /* we use boundary edges to calculate 2D normals. + * to disambiguate the direction of the normal, we also need + * a point "inside" the island, that can be provided by + * the opposite uv for a quad, or the next uv for a triangle. */ + + for(i = 0; i < total_edges; i++){ + float normal[2]; + stitch_calculate_edge_normal(em, edges + i, normal); + + add_v2_v2(state->normals + edges[i].uv1*2, normal); + add_v2_v2(state->normals + edges[i].uv2*2, normal); + + normalize_v2(state->normals + edges[i].uv1*2); + normalize_v2(state->normals + edges[i].uv2*2); + } + + + /***** fill selection stack *******/ + + state->selection_size = 0; + + /* Load old selection if redoing operator with different settings */ + if(RNA_struct_property_is_set(op->ptr, "selection")){ + int faceIndex, elementIndex; + UvElement *element; + + EM_init_index_arrays(em, 0, 0, 1); + + + RNA_BEGIN(op->ptr, itemptr, "selection") { + faceIndex = RNA_int_get(&itemptr, "face_index"); + elementIndex = RNA_int_get(&itemptr, "element_index"); + efa = EM_get_face_for_index(faceIndex); + element = ED_get_uv_element(state->element_map, efa, elementIndex); + stitch_select_uv(element, state, 1); + } + RNA_END; + + EM_free_index_arrays(); + /* Clear the selection */ + RNA_collection_clear(op->ptr, "selection"); + + } else { + for(efa = state->em->faces.first ; efa; efa = efa->next){ + int numOfVerts; + MTFace *mt; + mt = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE); + numOfVerts = efa->v4 ? 4 : 3; + + for(i = 0; i < numOfVerts; i++){ + if(uvedit_uv_selected(scene, efa, mt, i)){ + UvElement *element = ED_get_uv_element(state->element_map, efa, i); + stitch_select_uv(element, state, 1); + } + } + } + } + + /***** initialise static island preview data *****/ + + state->quads_per_island = MEM_mallocN(sizeof(*state->quads_per_island)*state->element_map->totalIslands, + "stitch island quads"); + state->tris_per_island = MEM_mallocN(sizeof(*state->tris_per_island)*state->element_map->totalIslands, + "stitch island tris"); + for(i = 0; i < state->element_map->totalIslands; i++){ + state->quads_per_island[i] = 0; + state->tris_per_island[i] = 0; + } + + for(efa = state->em->faces.first; efa; efa = efa->next){ + UvElement *element = ED_get_uv_element(state->element_map, efa, 0); + + if(element){ + if(efa->v4){ + state->quads_per_island[element->island]++; + } + else { + state->tris_per_island[element->island]++; + } + } + } + + if(!stitch_process_data(state, scene, 0)){ + stitch_state_delete(state); + return 0; + } + + stitch_update_header(state, C); + return 1; +} + +static int stitch_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) +{ + Object *obedit = CTX_data_edit_object(C); + if(!stitch_init(C, op)) + return OPERATOR_CANCELLED; + + WM_event_add_modal_handler(C, op); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + return OPERATOR_RUNNING_MODAL; +} + +static void stitch_exit(bContext *C, wmOperator *op, int finished) +{ + StitchState *stitch_state; + Scene *scene; + SpaceImage *sima; + ScrArea *sa= CTX_wm_area(C); + Object *obedit; + + scene= CTX_data_scene(C); + obedit= CTX_data_edit_object(C); + sima= CTX_wm_space_image(C); + + stitch_state = (StitchState *)op->customdata; + + if(finished){ + EditFace *efa; + int i; + + RNA_float_set(op->ptr, "limit", stitch_state->limit_dist); + RNA_boolean_set(op->ptr, "use_limit", stitch_state->use_limit); + RNA_boolean_set(op->ptr, "snap_islands", stitch_state->snap_islands); + RNA_int_set(op->ptr, "static_island", stitch_state->static_island); + RNA_boolean_set(op->ptr, "midpoint_snap", stitch_state->midpoints); + + for(i = 0, efa = stitch_state->em->faces.first; efa; efa = efa->next, i++){ + efa->tmp.l = i; + } + + /* Store selection for re-execution of stitch */ + for(i = 0; i < stitch_state->selection_size; i++){ + PointerRNA itemptr; + UvElement *element = stitch_state->selection_stack[i]; + + RNA_collection_add(op->ptr, "selection", &itemptr); + + RNA_int_set(&itemptr, "face_index", element->face->tmp.l); + RNA_int_set(&itemptr, "element_index", element->tfindex); + } + + + uvedit_live_unwrap_update(sima, scene, obedit); + } + + if(sa) + ED_area_headerprint(sa, NULL); + + DAG_id_tag_update(obedit->data, 0); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + BKE_mesh_end_editmesh(obedit->data, stitch_state->em); + + stitch_state_delete(stitch_state); + op->customdata = NULL; + + stitch_preview_delete(); +} + + +static int stitch_cancel(bContext *C, wmOperator *op) +{ + stitch_exit(C, op, 0); + return OPERATOR_CANCELLED; +} + + +static int stitch_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + + if(!stitch_init(C, op)) + return OPERATOR_CANCELLED; + if(stitch_process_data((StitchState *)op->customdata, scene, 1)){ + stitch_exit(C, op, 1); + return OPERATOR_FINISHED; + }else { + return stitch_cancel(C, op); + } +} + +static void stitch_select(bContext *C, Scene *scene, wmEvent *event, StitchState *stitch_state){ + /* add uv under mouse to processed uv's */ + float co[2]; + NearestHit hit; + ARegion *ar= CTX_wm_region(C); + Image *ima= CTX_data_edit_image(C); + + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]); + uv_find_nearest_vert(scene, ima, stitch_state->em, co, NULL, &hit); + + if(hit.efa) + { + /* Add vertex to selection, deselect all common uv's of vert other + * than selected and update the preview. This behavior was decided so that + * you can do stuff like deselect the opposite stitchable vertex and the initial still gets deselected */ + + /* This works due to setting of tmp in find nearest uv vert */ + UvElement *element = ED_get_uv_element(stitch_state->element_map, hit.efa, hit.uv); + stitch_select_uv(element, stitch_state, 0); + + } +} + +static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event) +{ + StitchState *stitch_state; + Scene *scene = CTX_data_scene(C); + + stitch_state = (StitchState *)op->customdata; + + switch(event->type){ + case MIDDLEMOUSE: + return OPERATOR_PASS_THROUGH; + + /* Cancel */ + case ESCKEY: + return stitch_cancel(C, op); + + + case LEFTMOUSE: + if(event->shift && (U.flag & USER_LMOUSESELECT)){ + if(event->val == KM_RELEASE){ + stitch_select(C, scene, event, stitch_state); + + if(!stitch_process_data(stitch_state, scene, 0)){ + return stitch_cancel(C, op); + } + } + break; + } + case PADENTER: + case RETKEY: + if(stitch_process_data(stitch_state, scene, 1)){ + stitch_exit(C, op, 1); + return OPERATOR_FINISHED; + } + else { + return stitch_cancel(C, op); + } + + /* Increase limit */ + case PADPLUSKEY: + case WHEELUPMOUSE: + if(event->alt){ + stitch_state->limit_dist += 0.01; + if(!stitch_process_data(stitch_state, scene, 0)){ + return stitch_cancel(C, op); + } + break; + } + else{ + return OPERATOR_PASS_THROUGH; + } + /* Decrease limit */ + case PADMINUS: + case WHEELDOWNMOUSE: + if(event->alt){ + stitch_state->limit_dist -= 0.01; + stitch_state->limit_dist = MAX2(0.01, stitch_state->limit_dist); + if(!stitch_process_data(stitch_state, scene, 0)){ + return stitch_cancel(C, op); + } + break; + }else{ + return OPERATOR_PASS_THROUGH; + } + + /* Use Limit (Default off)*/ + case LKEY: + if(event->val == KM_PRESS){ + stitch_state->use_limit = !stitch_state->use_limit; + if(!stitch_process_data(stitch_state, scene, 0)){ + return stitch_cancel(C, op); + } + break; + } + return OPERATOR_RUNNING_MODAL; + + case IKEY: + if(event->val == KM_PRESS){ + stitch_state->static_island++; + stitch_state->static_island %= stitch_state->element_map->totalIslands; + + if(!stitch_process_data(stitch_state, scene, 0)){ + return stitch_cancel(C, op); + } + break; + } + return OPERATOR_RUNNING_MODAL; + + case MKEY: + if(event->val == KM_PRESS){ + stitch_state->midpoints = !stitch_state->midpoints; + if(!stitch_process_data(stitch_state, scene, 0)){ + return stitch_cancel(C, op); + } + } + break; + + /* Select geometry*/ + case RIGHTMOUSE: + if(!event->shift){ + return stitch_cancel(C, op); + } + if(event->val == KM_RELEASE && !(U.flag & USER_LMOUSESELECT)){ + stitch_select(C, scene, event, stitch_state); + + if(!stitch_process_data(stitch_state, scene, 0)){ + return stitch_cancel(C, op); + } + break; + } + return OPERATOR_RUNNING_MODAL; + + /* snap islands on/off */ + case SKEY: + if(event->val == KM_PRESS){ + stitch_state->snap_islands = !stitch_state->snap_islands; + if(!stitch_process_data(stitch_state, scene, 0)){ + return stitch_cancel(C, op); + } + break; + } else + return OPERATOR_RUNNING_MODAL; + + default: + return OPERATOR_RUNNING_MODAL; + } + + /* if updated settings, renew feedback message */ + stitch_update_header(stitch_state, C); + ED_region_tag_redraw(CTX_wm_region(C)); + return OPERATOR_RUNNING_MODAL; +} + +void UV_OT_stitch(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Stitch"; + ot->description = "Stitch selected UV vertices by proximity"; + ot->idname = "UV_OT_stitch"; + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + + /* api callbacks */ + ot->invoke = stitch_invoke; + ot->modal = stitch_modal; + ot->exec = stitch_exec; + ot->cancel = stitch_cancel; + ot->poll= ED_operator_uvedit; + + /* properties */ + RNA_def_boolean(ot->srna, "use_limit", 0, "Use Limit", "Stitch UVs within a specified limit distance"); + RNA_def_boolean(ot->srna, "snap_islands", 1, "Snap Islands", + "Snap islands together (on edge stitch mode, rotates the islands too)"); + + RNA_def_float(ot->srna, "limit", 0.01f, 0.0f, FLT_MAX, "Limit", + "Limit distance in normalized coordinates", 0.0, FLT_MAX); + RNA_def_int(ot->srna, "static_island", 0, 0, INT_MAX, "Static Island", + "Island that stays in place when stitching islands", 0, INT_MAX); + RNA_def_boolean(ot->srna, "midpoint_snap", 0, "Snap At Midpoint", + "UVs are stitched at midpoint instead of at static island"); + prop = RNA_def_collection_runtime(ot->srna, "selection", &RNA_SelectedUvElement, "Selection", ""); + /* Selection should not be editable or viewed in toolbar */ + RNA_def_property_flag(prop, PROP_HIDDEN); +} + + diff -Nru blender-2.61/source/blender/editors/uvedit/uvedit_unwrap_ops.c blender-2.62/source/blender/editors/uvedit/uvedit_unwrap_ops.c --- blender-2.61/source/blender/editors/uvedit/uvedit_unwrap_ops.c 2011-12-13 19:54:28.000000000 +0000 +++ blender-2.62/source/blender/editors/uvedit/uvedit_unwrap_ops.c 2012-02-15 19:38:37.000000000 +0000 @@ -40,19 +40,24 @@ #include "DNA_meshdata_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DNA_modifier_types.h" #include "BLI_math.h" #include "BLI_edgehash.h" #include "BLI_editVert.h" #include "BLI_uvproject.h" #include "BLI_utildefines.h" +#include "BLI_string.h" +#include "BKE_cdderivedmesh.h" +#include "BKE_subsurf.h" #include "BKE_context.h" #include "BKE_customdata.h" #include "BKE_depsgraph.h" #include "BKE_image.h" #include "BKE_main.h" #include "BKE_mesh.h" +#include "BKE_report.h" #include "PIL_time.h" @@ -271,6 +276,200 @@ return handle; } + +static void texface_from_original_index(EditFace *editFace, MTFace *texFace, int index, float **uv, ParamBool *pin, ParamBool *select, Scene *scene) +{ + int i, nverts = (editFace->v4)? 4: 3; + + *uv = NULL; + *pin = 0; + *select = 1; + + if(index == ORIGINDEX_NONE) + return; + + for(i = 0; i < nverts; i++) { + if((*(&editFace->v1 + i))->tmp.t == index) { + *uv = texFace->uv[i]; + *pin = ((texFace->unwrap & TF_PIN_MASK(i)) != 0); + *select = (uvedit_uv_selected(scene, editFace, texFace, i) != 0); + } + } +} + +/* unwrap handle initialization for subsurf aware-unwrapper. The many modifications required to make the original function(see above) + * work justified the existence of a new function. */ +static ParamHandle *construct_param_handle_subsurfed(Scene *scene, EditMesh *editMesh, short fill, short sel, short correct_aspect) +{ + ParamHandle *handle; + /* index pointers */ + MFace *face; + MEdge *edge; + EditVert *editVert; + EditFace *editFace, **editFaceTmp; + EditEdge *editEdge, **editEdgeTmp; + int i; + + /* modifier initialization data, will control what type of subdivision will happen*/ + SubsurfModifierData smd = {{0}}; + /* Used to hold subsurfed Mesh */ + DerivedMesh *derivedMesh, *initialDerived; + /* holds original indices for subsurfed mesh */ + int *origVertIndices, *origFaceIndices, *origEdgeIndices; + /* Holds vertices of subsurfed mesh */ + MVert *subsurfedVerts; + MEdge *subsurfedEdges; + MFace *subsurfedFaces; + /* MTFace *subsurfedTexfaces; */ /* UNUSED */ + /* number of vertices and faces for subsurfed mesh*/ + int numOfEdges, numOfFaces; + + /* holds a map to editfaces for every subsurfed MFace. These will be used to get hidden/ selected flags etc. */ + EditFace **faceMap; + /* Mini container to hold all EditFaces so that they may be indexed easily and fast. */ + EditFace **editFaceArray; + /* similar to the above, we need a way to map edges to their original ones */ + EditEdge **edgeMap; + EditEdge **editEdgeArray; + + handle = param_construct_begin(); + + if(correct_aspect) { + EditFace *eface = EM_get_actFace(editMesh, 1); + + if(eface) { + float aspx, aspy; + MTFace *texface= CustomData_em_get(&editMesh->fdata, eface->data, CD_MTFACE); + + ED_image_uv_aspect(texface->tpage, &aspx, &aspy); + + if(aspx!=aspy) + param_aspect_ratio(handle, aspx, aspy); + } + } + + /* number of subdivisions to perform */ + smd.levels = scene->toolsettings->uv_subsurf_level; + smd.subdivType = ME_CC_SUBSURF; + + initialDerived = CDDM_from_editmesh(editMesh, NULL); + derivedMesh = subsurf_make_derived_from_derived(initialDerived, &smd, + 0, NULL, 0, 0, 1); + + initialDerived->release(initialDerived); + + /* get the derived data */ + subsurfedVerts = derivedMesh->getVertArray(derivedMesh); + subsurfedEdges = derivedMesh->getEdgeArray(derivedMesh); + subsurfedFaces = derivedMesh->getFaceArray(derivedMesh); + + origVertIndices = derivedMesh->getVertDataArray(derivedMesh, CD_ORIGINDEX); + origEdgeIndices = derivedMesh->getEdgeDataArray(derivedMesh, CD_ORIGINDEX); + origFaceIndices = derivedMesh->getFaceDataArray(derivedMesh, CD_ORIGINDEX); + + /* subsurfedTexfaces = derivedMesh->getFaceDataArray(derivedMesh, CD_MTFACE); */ /* UNUSED */ + + numOfEdges = derivedMesh->getNumEdges(derivedMesh); + numOfFaces = derivedMesh->getNumFaces(derivedMesh); + + faceMap = MEM_mallocN(numOfFaces*sizeof(EditFace *), "unwrap_edit_face_map"); + editFaceArray = MEM_mallocN(editMesh->totface*sizeof(EditFace *), "unwrap_editFaceArray"); + + /* fill edit face array with edit faces */ + for(editFace = editMesh->faces.first, editFaceTmp = editFaceArray; editFace; editFace= editFace->next, editFaceTmp++) + *editFaceTmp = editFace; + + /* map subsurfed faces to original editFaces */ + for(i = 0; i < numOfFaces; i++) + faceMap[i] = editFaceArray[origFaceIndices[i]]; + + MEM_freeN(editFaceArray); + + edgeMap = MEM_mallocN(numOfEdges*sizeof(EditEdge *), "unwrap_edit_edge_map"); + editEdgeArray = MEM_mallocN(editMesh->totedge*sizeof(EditEdge *), "unwrap_editEdgeArray"); + + /* fill edit edge array with edit edges */ + for(editEdge = editMesh->edges.first, editEdgeTmp = editEdgeArray; editEdge; editEdge= editEdge->next, editEdgeTmp++) + *editEdgeTmp = editEdge; + + /* map subsurfed edges to original editEdges */ + for(i = 0; i < numOfEdges; i++) { + /* not all edges correspond to an old edge */ + edgeMap[i] = (origEdgeIndices[i] != -1)? + editEdgeArray[origEdgeIndices[i]] : NULL; + } + + MEM_freeN(editEdgeArray); + + /* we need the editvert indices too */ + for(editVert = editMesh->verts.first, i=0; editVert; editVert = editVert->next, i++) + editVert->tmp.t = i; + + /* Prepare and feed faces to the solver */ + for(i = 0; i < numOfFaces; i++) { + ParamKey key, vkeys[4]; + ParamBool pin[4], select[4]; + float *co[4]; + float *uv[4]; + EditFace *origFace = faceMap[i]; + MTFace *origtexface = (MTFace *)CustomData_em_get(&editMesh->fdata, origFace->data, CD_MTFACE); + + face = subsurfedFaces+i; + + if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) { + if(origFace->h) + continue; + } + else { + if((origFace->h) || (sel && (origFace->f & SELECT)==0)) + continue; + } + + /* Now we feed the rest of the data from the subsurfed faces */ + /* texface= subsurfedTexfaces+i; */ /* UNUSED */ + + /* We will not check for v4 here. Subsurfed mfaces always have 4 vertices. */ + key = (ParamKey)face; + vkeys[0] = (ParamKey)face->v1; + vkeys[1] = (ParamKey)face->v2; + vkeys[2] = (ParamKey)face->v3; + vkeys[3] = (ParamKey)face->v4; + + co[0] = subsurfedVerts[face->v1].co; + co[1] = subsurfedVerts[face->v2].co; + co[2] = subsurfedVerts[face->v3].co; + co[3] = subsurfedVerts[face->v4].co; + + /* This is where all the magic is done. If the vertex exists in the, we pass the original uv pointer to the solver, thus + * flushing the solution to the edit mesh. */ + texface_from_original_index(origFace, origtexface, origVertIndices[face->v1], &uv[0], &pin[0], &select[0], scene); + texface_from_original_index(origFace, origtexface, origVertIndices[face->v2], &uv[1], &pin[1], &select[1], scene); + texface_from_original_index(origFace, origtexface, origVertIndices[face->v3], &uv[2], &pin[2], &select[2], scene); + texface_from_original_index(origFace, origtexface, origVertIndices[face->v4], &uv[3], &pin[3], &select[3], scene); + + param_face_add(handle, key, 4, vkeys, co, uv, pin, select); + } + + /* these are calculated from original mesh too */ + for(edge = subsurfedEdges, i = 0; i < numOfEdges; i++, edge++) { + if((edgeMap[i] != NULL) && edgeMap[i]->seam) { + ParamKey vkeys[2]; + vkeys[0] = (ParamKey)edge->v1; + vkeys[1] = (ParamKey)edge->v2; + param_edge_set_seam(handle, vkeys); + } + } + + param_construct_end(handle, fill, 0); + + /* cleanup */ + MEM_freeN(faceMap); + MEM_freeN(edgeMap); + derivedMesh->release(derivedMesh); + + return handle; +} + /* ******************** Minimize Stretch operator **************** */ typedef struct MinStretch { @@ -334,7 +533,7 @@ param_flush(ms->handle); if(sa) { - sprintf(str, "Minimize Stretch. Blend %.2f", ms->blend); + BLI_snprintf(str, sizeof(str), "Minimize Stretch. Blend %.2f", ms->blend); ED_area_headerprint(sa, str); } @@ -498,7 +697,7 @@ return OPERATOR_CANCELLED; } - if(RNA_property_is_set(op->ptr, "margin")) { + if(RNA_struct_property_is_set(op->ptr, "margin")) { scene->toolsettings->uvcalc_margin= RNA_float_get(op->ptr, "margin"); } else { @@ -581,13 +780,17 @@ EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); short abf = scene->toolsettings->unwrapper == 0; short fillholes = scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES; + short use_subsurf = scene->toolsettings->uvcalc_flag & UVCALC_USESUBSURF; if(!ED_uvedit_test(obedit)) { BKE_mesh_end_editmesh(obedit->data, em); return; } - liveHandle = construct_param_handle(scene, em, 0, fillholes, 0, 1); + if(use_subsurf) + liveHandle = construct_param_handle_subsurfed(scene, em, fillholes, 0, 1); + else + liveHandle = construct_param_handle(scene, em, 0, fillholes, 0, 1); param_lscm_begin(liveHandle, PARAM_TRUE, abf); BKE_mesh_end_editmesh(obedit->data, em); @@ -899,14 +1102,17 @@ /* assumes UV Map is checked, doesn't run update funcs */ void ED_unwrap_lscm(Scene *scene, Object *obedit, const short sel) { - EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); ParamHandle *handle; + EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); const short fill_holes= scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES; const short correct_aspect= !(scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT); - short implicit= 0; + const short use_subsurf = scene->toolsettings->uvcalc_flag & UVCALC_USESUBSURF; - handle= construct_param_handle(scene, em, implicit, fill_holes, sel, correct_aspect); + if(use_subsurf) + handle = construct_param_handle_subsurfed(scene, em, fill_holes, sel, correct_aspect); + else + handle= construct_param_handle(scene, em, 0, fill_holes, sel, correct_aspect); param_lscm_begin(handle, PARAM_FALSE, scene->toolsettings->unwrapper == 0); param_lscm_solve(handle); @@ -929,6 +1135,9 @@ int method = RNA_enum_get(op->ptr, "method"); int fill_holes = RNA_boolean_get(op->ptr, "fill_holes"); int correct_aspect = RNA_boolean_get(op->ptr, "correct_aspect"); + int use_subsurf = RNA_boolean_get(op->ptr, "use_subsurf_data"); + int subsurf_level = RNA_int_get(op->ptr, "uv_subsurf_level"); + float obsize[3], unitsize[3] = {1.0f, 1.0f, 1.0f}; short implicit= 0; if(!uvedit_have_selection(scene, em, implicit)) { @@ -943,8 +1152,14 @@ return OPERATOR_CANCELLED; } + mat4_to_size(obsize, obedit->obmat); + if(!compare_v3v3(obsize, unitsize, 1e-4f)) + BKE_report(op->reports, RPT_INFO, "Object scale is not 1.0. Unwrap will operate on a non-scaled version of the mesh."); + /* remember last method for live unwrap */ scene->toolsettings->unwrapper = method; + + scene->toolsettings->uv_subsurf_level = subsurf_level; if(fill_holes) scene->toolsettings->uvcalc_flag |= UVCALC_FILLHOLES; else scene->toolsettings->uvcalc_flag &= ~UVCALC_FILLHOLES; @@ -952,6 +1167,9 @@ if(correct_aspect) scene->toolsettings->uvcalc_flag &= ~UVCALC_NO_ASPECT_CORRECT; else scene->toolsettings->uvcalc_flag |= UVCALC_NO_ASPECT_CORRECT; + if(use_subsurf) scene->toolsettings->uvcalc_flag |= UVCALC_USESUBSURF; + else scene->toolsettings->uvcalc_flag &= ~UVCALC_USESUBSURF; + /* execute unwrap */ ED_unwrap_lscm(scene, obedit, TRUE); @@ -985,6 +1203,10 @@ "Virtual fill holes in mesh before unwrapping, to better avoid overlaps and preserve symmetry"); RNA_def_boolean(ot->srna, "correct_aspect", 1, "Correct Aspect", "Map UVs taking image aspect ratio into account"); + RNA_def_boolean(ot->srna, "use_subsurf_data", 0, "Use Subsurf Data", + "Map UVs taking vertex position after subsurf into account"); + RNA_def_int(ot->srna, "uv_subsurf_level", 1, 1, 6, "SubSurf Target", + "Number of times to subdivide before calculating UVs", 1, 6); } /**************** Project From View operator **************/ diff -Nru blender-2.61/source/blender/gpu/GPU_buffers.h blender-2.62/source/blender/gpu/GPU_buffers.h --- blender-2.61/source/blender/gpu/GPU_buffers.h 2011-12-13 19:49:55.000000000 +0000 +++ blender-2.62/source/blender/gpu/GPU_buffers.h 2012-02-15 19:34:38.000000000 +0000 @@ -167,7 +167,7 @@ int *vert_indices, int totvert); GPU_Buffers *GPU_build_grid_buffers(struct DMGridData **grids, int *grid_indices, int totgrid, int gridsize); -void GPU_update_grid_buffers(GPU_Buffers *buffers_v, struct DMGridData **grids, +void GPU_update_grid_buffers(GPU_Buffers *buffers, struct DMGridData **grids, int *grid_indices, int totgrid, int gridsize, int smooth); void GPU_draw_buffers(GPU_Buffers *buffers); void GPU_free_buffers(GPU_Buffers *buffers); diff -Nru blender-2.61/source/blender/gpu/GPU_extensions.h blender-2.62/source/blender/gpu/GPU_extensions.h --- blender-2.61/source/blender/gpu/GPU_extensions.h 2011-12-13 19:49:55.000000000 +0000 +++ blender-2.62/source/blender/gpu/GPU_extensions.h 2012-02-15 19:34:38.000000000 +0000 @@ -61,6 +61,8 @@ int GPU_glsl_support(void); int GPU_non_power_of_two_support(void); int GPU_color_depth(void); +void GPU_code_generate_glsl_lib(void); +int GPU_bicubic_bump_support(void); /* GPU Types */ @@ -165,7 +167,7 @@ int arraysize, float *value); void GPU_shader_uniform_texture(GPUShader *shader, int location, GPUTexture *tex); -int GPU_shader_get_attribute(GPUShader *shader, char *name); +int GPU_shader_get_attribute(GPUShader *shader, const char *name); /* Vertex attributes for shaders */ @@ -177,7 +179,7 @@ int glindex; int gltexco; int attribid; - char name[32]; + char name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ } layer[GPU_MAX_ATTRIB]; int totlayer; diff -Nru blender-2.61/source/blender/gpu/intern/gpu_buffers.c blender-2.62/source/blender/gpu/intern/gpu_buffers.c --- blender-2.61/source/blender/gpu/intern/gpu_buffers.c 2011-12-13 19:49:54.000000000 +0000 +++ blender-2.62/source/blender/gpu/intern/gpu_buffers.c 2012-02-15 19:34:38.000000000 +0000 @@ -701,8 +701,8 @@ static void GPU_buffer_copy_color3(DerivedMesh *dm, float *varray_, int *index, int *mat_orig_to_new, void *user) { int i, totface; - unsigned char *varray = (unsigned char *)varray_; - unsigned char *mcol = (unsigned char *)user; + char *varray = (char *)varray_; + char *mcol = (char *)user; MFace *f = dm->getFaceArray(dm); totface= dm->getNumFaces(dm); @@ -710,16 +710,16 @@ int start = index[mat_orig_to_new[f->mat_nr]]; /* v1 v2 v3 */ - VECCOPY(&varray[start], &mcol[i*12]); - VECCOPY(&varray[start+3], &mcol[i*12+3]); - VECCOPY(&varray[start+6], &mcol[i*12+6]); + copy_v3_v3_char(&varray[start], &mcol[i*12]); + copy_v3_v3_char(&varray[start+3], &mcol[i*12+3]); + copy_v3_v3_char(&varray[start+6], &mcol[i*12+6]); index[mat_orig_to_new[f->mat_nr]] += 9; if(f->v4) { /* v3 v4 v1 */ - VECCOPY(&varray[start+9], &mcol[i*12+6]); - VECCOPY(&varray[start+12], &mcol[i*12+9]); - VECCOPY(&varray[start+15], &mcol[i*12]); + copy_v3_v3_char(&varray[start+9], &mcol[i*12+6]); + copy_v3_v3_char(&varray[start+12], &mcol[i*12+9]); + copy_v3_v3_char(&varray[start+15], &mcol[i*12]); index[mat_orig_to_new[f->mat_nr]] += 9; } } @@ -1296,10 +1296,9 @@ unsigned int tot_tri, tot_quad; }; -void GPU_update_mesh_buffers(GPU_Buffers *buffers_v, MVert *mvert, +void GPU_update_mesh_buffers(GPU_Buffers *buffers, MVert *mvert, int *vert_indices, int totvert) { - GPU_Buffers *buffers = buffers_v; VertexBufferFormat *vert_data; int i; @@ -1413,10 +1412,9 @@ return buffers; } -void GPU_update_grid_buffers(GPU_Buffers *buffers_v, DMGridData **grids, +void GPU_update_grid_buffers(GPU_Buffers *buffers, DMGridData **grids, int *grid_indices, int totgrid, int gridsize, int smooth) { - GPU_Buffers *buffers = buffers_v; DMGridData *vert_data; int i, j, k, totvert; @@ -1465,7 +1463,7 @@ buffers->totgrid = totgrid; buffers->gridsize = gridsize; - //printf("node updated %p\n", buffers_v); + //printf("node updated %p\n", buffers); } GPU_Buffers *GPU_build_grid_buffers(DMGridData **UNUSED(grids), int *UNUSED(grid_indices), @@ -1558,10 +1556,8 @@ return buffers; } -void GPU_draw_buffers(GPU_Buffers *buffers_v) +void GPU_draw_buffers(GPU_Buffers *buffers) { - GPU_Buffers *buffers = buffers_v; - if(buffers->vert_buf && buffers->index_buf) { glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); @@ -1632,11 +1628,9 @@ } } -void GPU_free_buffers(GPU_Buffers *buffers_v) +void GPU_free_buffers(GPU_Buffers *buffers) { - if(buffers_v) { - GPU_Buffers *buffers = buffers_v; - + if(buffers) { if(buffers->vert_buf) glDeleteBuffersARB(1, &buffers->vert_buf); if(buffers->index_buf) @@ -1645,4 +1639,3 @@ MEM_freeN(buffers); } } - diff -Nru blender-2.61/source/blender/gpu/intern/gpu_codegen.c blender-2.62/source/blender/gpu/intern/gpu_codegen.c --- blender-2.61/source/blender/gpu/intern/gpu_codegen.c 2011-12-13 19:49:54.000000000 +0000 +++ blender-2.62/source/blender/gpu/intern/gpu_codegen.c 2012-02-15 19:34:38.000000000 +0000 @@ -59,6 +59,10 @@ extern char datatoc_gpu_shader_material_glsl[]; extern char datatoc_gpu_shader_vertex_glsl[]; + +static char *glsl_material_library = NULL; + + /* structs and defines */ static const char* GPU_DATATYPE_STR[17] = {"", "float", "vec2", "vec3", "vec4", @@ -229,7 +233,7 @@ { if(!FUNCTION_HASH) { FUNCTION_HASH = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "GPU_lookup_function gh"); - gpu_parse_functions_string(FUNCTION_HASH, datatoc_gpu_shader_material_glsl); + gpu_parse_functions_string(FUNCTION_HASH, glsl_material_library); /*FUNCTION_PROTOTYPES = gpu_generate_function_prototyps(FUNCTION_HASH); FUNCTION_LIB = GPU_shader_create_lib(datatoc_gpu_shader_material_glsl);*/ } @@ -237,7 +241,12 @@ return (GPUFunction*)BLI_ghash_lookup(FUNCTION_HASH, (void *)name); } -void GPU_extensions_exit(void) +void GPU_codegen_init(void) +{ + GPU_code_generate_glsl_lib(); +} + +void GPU_codegen_exit(void) { extern Material defmaterial; // render module abuse... @@ -248,6 +257,12 @@ BLI_ghash_free(FUNCTION_HASH, NULL, (GHashValFreeFP)MEM_freeN); FUNCTION_HASH = NULL; } + + if(glsl_material_library) { + MEM_freeN(glsl_material_library); + glsl_material_library = NULL; + } + /*if(FUNCTION_PROTOTYPES) { MEM_freeN(FUNCTION_PROTOTYPES); FUNCTION_PROTOTYPES = NULL; @@ -531,12 +546,8 @@ BLI_dynstr_appendf(ds, ", gl_TexCoord[%d].st", input->texid); } else if (input->source == GPU_SOURCE_TEX_PIXEL) { - if (input->link && input->link->output) - codegen_convert_datatype(ds, input->link->output->type, input->type, - "tmp", input->link->output->id); - else - codegen_convert_datatype(ds, input->link->output->type, input->type, - "tex", input->texid); + codegen_convert_datatype(ds, input->link->output->type, input->type, + "tmp", input->link->output->id); } else if(input->source == GPU_SOURCE_BUILTIN) BLI_dynstr_appendf(ds, "%s", GPU_builtin_name(input->builtin)); @@ -640,6 +651,36 @@ return code; } +int GPU_bicubic_bump_support(void) +{ + return GLEW_ARB_texture_query_lod && GLEW_VERSION_3_0; +} + +void GPU_code_generate_glsl_lib(void) +{ + DynStr *ds; + + /* only initialize the library once */ + if(glsl_material_library) + return; + + ds = BLI_dynstr_new(); + + if(GPU_bicubic_bump_support()){ + BLI_dynstr_append(ds, "/* These are needed for high quality bump mapping */\n" + "#version 130\n" + "#extension GL_ARB_texture_query_lod: enable\n" + "#define BUMP_BICUBIC\n"); + } + BLI_dynstr_append(ds, datatoc_gpu_shader_material_glsl); + + + glsl_material_library = BLI_dynstr_get_cstring(ds); + + BLI_dynstr_free(ds); +} + + /* GPU pass binding/unbinding */ GPUShader *GPU_pass_shader(GPUPass *pass) @@ -1318,7 +1359,7 @@ /* generate code and compile with opengl */ fragmentcode = code_generate_fragment(nodes, outlink->output, name); vertexcode = code_generate_vertex(nodes); - shader = GPU_shader_create(vertexcode, fragmentcode, datatoc_gpu_shader_material_glsl); /*FUNCTION_LIB);*/ + shader = GPU_shader_create(vertexcode, fragmentcode, glsl_material_library); /*FUNCTION_LIB);*/ /* failed? */ if (!shader) { @@ -1335,7 +1376,7 @@ pass->shader = shader; pass->fragmentcode = fragmentcode; pass->vertexcode = vertexcode; - pass->libcode = datatoc_gpu_shader_material_glsl; + pass->libcode = glsl_material_library; /* extract dynamic inputs and throw away nodes */ GPU_nodes_extract_dynamic_inputs(pass, nodes); diff -Nru blender-2.61/source/blender/gpu/intern/gpu_codegen.h blender-2.62/source/blender/gpu/intern/gpu_codegen.h --- blender-2.61/source/blender/gpu/intern/gpu_codegen.h 2011-12-13 19:49:54.000000000 +0000 +++ blender-2.62/source/blender/gpu/intern/gpu_codegen.h 2012-02-15 19:34:38.000000000 +0000 @@ -178,6 +178,9 @@ void GPU_pass_free(GPUPass *pass); +void GPU_codegen_init(void); +void GPU_codegen_exit(void); + /* Material calls */ const char *GPU_builtin_name(GPUBuiltin builtin); diff -Nru blender-2.61/source/blender/gpu/intern/gpu_draw.c blender-2.62/source/blender/gpu/intern/gpu_draw.c --- blender-2.61/source/blender/gpu/intern/gpu_draw.c 2011-12-13 19:49:54.000000000 +0000 +++ blender-2.62/source/blender/gpu/intern/gpu_draw.c 2012-02-15 19:34:38.000000000 +0000 @@ -189,20 +189,6 @@ /* Checking powers of two for images since opengl 1.x requires it */ -static int is_pow2(int num) -{ - /* (n&(n-1)) zeros the least significant bit of n */ - return ((num)&(num-1))==0; -} - -static int smaller_pow2(int num) -{ - while (!is_pow2(num)) - num= num&(num-1); - - return num; -} - static int is_pow2_limit(int num) { /* take texture clamping into account */ @@ -214,7 +200,7 @@ if (U.glreslimit != 0 && num > U.glreslimit) return 0; - return ((num)&(num-1))==0; + return is_power_of_2_i(num); } static int smaller_pow2_limit(int num) @@ -227,7 +213,7 @@ if (U.glreslimit != 0 && num > U.glreslimit) return U.glreslimit; - return smaller_pow2(num); + return power_of_2_min_i(num); } /* Current OpenGL state caching for GPU_set_tpage */ @@ -424,9 +410,12 @@ ImBuf *ibuf = NULL; unsigned int *bind = NULL; int rectw, recth, tpx=0, tpy=0, y; - unsigned int *rectrow, *tilerectrow; unsigned int *tilerect= NULL, *scalerect= NULL, *rect= NULL; + float *ftilerect= NULL, *fscalerect = NULL, *frect = NULL; + float *srgb_frect = NULL; short texwindx, texwindy, texwinsx, texwinsy; + /* flag to determine whether high resolution format is used */ + int use_high_bit_depth = FALSE, do_color_management = FALSE; /* initialize tile mode and number of repeats */ GTS.ima = ima; @@ -476,9 +465,20 @@ if(ibuf==NULL) return 0; - /* ensure we have a char buffer and not only float */ - if ((ibuf->rect==NULL) && ibuf->rect_float) - IMB_rect_from_float(ibuf); + if(ibuf->rect_float) { + if(U.use_16bit_textures) { + /* use high precision textures. This is relatively harmless because OpenGL gives us + a high precision format only if it is available */ + use_high_bit_depth = TRUE; + } + + /* TODO unneeded when float images are correctly treated as linear always */ + if(ibuf->profile == IB_PROFILE_LINEAR_RGB) + do_color_management = TRUE; + + if(ibuf->rect==NULL) + IMB_rect_from_float(ibuf); + } /* currently, tpage refresh is used by ima sequences */ if(ima->tpageflag & IMA_TPAGE_REFRESH) { @@ -512,17 +512,43 @@ tpx= texwindx; tpy= texwindy; - rect= ibuf->rect + texwinsy*ibuf->x + texwinsx; + if(use_high_bit_depth) { + if(do_color_management) { + srgb_frect = MEM_mallocN(ibuf->x*ibuf->y*sizeof(float)*4, "floar_buf_col_cor"); + IMB_buffer_float_from_float(srgb_frect, ibuf->rect_float, + ibuf->channels, IB_PROFILE_SRGB, ibuf->profile, 0, + ibuf->x, ibuf->y, ibuf->x, ibuf->x); + /* clamp buffer colours to 1.0 to avoid artifacts due to glu for hdr images */ + IMB_buffer_float_clamp(srgb_frect, ibuf->x, ibuf->y); + frect= srgb_frect + texwinsy*ibuf->x + texwinsx; + } + else + frect= ibuf->rect_float + texwinsy*ibuf->x + texwinsx; + } + else + rect= ibuf->rect + texwinsy*ibuf->x + texwinsx; } } else { /* regular image mode */ bind= &ima->bindcode; - + if(*bind==0) { tpx= ibuf->x; tpy= ibuf->y; rect= ibuf->rect; + if(use_high_bit_depth) { + if(do_color_management) { + frect = srgb_frect = MEM_mallocN(ibuf->x*ibuf->y*sizeof(*srgb_frect)*4, "floar_buf_col_cor"); + IMB_buffer_float_from_float(srgb_frect, ibuf->rect_float, + ibuf->channels, IB_PROFILE_SRGB, ibuf->profile, 0, + ibuf->x, ibuf->y, ibuf->x, ibuf->x); + /* clamp buffer colours to 1.0 to avoid artifacts due to glu for hdr images */ + IMB_buffer_float_clamp(srgb_frect, ibuf->x, ibuf->y); + } + else + frect= ibuf->rect_float; + } } } @@ -537,26 +563,54 @@ /* for tiles, copy only part of image into buffer */ if (GTS.tilemode) { - tilerect= MEM_mallocN(rectw*recth*sizeof(*tilerect), "tilerect"); + if(use_high_bit_depth) { + float *frectrow, *ftilerectrow; - for (y=0; yx]; - tilerectrow= &tilerect[y*rectw]; - - memcpy(tilerectrow, rectrow, tpx*sizeof(*rectrow)); + ftilerect= MEM_mallocN(rectw*recth*sizeof(*ftilerect), "tilerect"); + + for (y=0; yx]; + ftilerectrow= &ftilerect[y*rectw]; + + memcpy(ftilerectrow, frectrow, tpx*sizeof(*frectrow)); + } + + frect= ftilerect; } + else { + unsigned int *rectrow, *tilerectrow; + + tilerect= MEM_mallocN(rectw*recth*sizeof(*tilerect), "tilerect"); + + for (y=0; yx]; + tilerectrow= &tilerect[y*rectw]; + + memcpy(tilerectrow, rectrow, tpx*sizeof(*rectrow)); + } - rect= tilerect; + rect= tilerect; + } } - /* scale if not a power of two */ + /* scale if not a power of two. this is not strictly necessary for newer + GPUs (OpenGL version >= 2.0) since they support non-power-of-two-textures */ if (!is_pow2_limit(rectw) || !is_pow2_limit(recth)) { rectw= smaller_pow2_limit(rectw); recth= smaller_pow2_limit(recth); - scalerect= MEM_mallocN(rectw*recth*sizeof(*scalerect), "scalerect"); - gluScaleImage(GL_RGBA, tpx, tpy, GL_UNSIGNED_BYTE, rect, rectw, recth, GL_UNSIGNED_BYTE, scalerect); - rect= scalerect; + if(use_high_bit_depth) { + fscalerect= MEM_mallocN(rectw*recth*sizeof(*fscalerect)*4, "fscalerect"); + gluScaleImage(GL_RGBA, tpx, tpy, GL_FLOAT, frect, rectw, recth, GL_FLOAT, fscalerect); + + frect = fscalerect; + } + else { + scalerect= MEM_mallocN(rectw*recth*sizeof(*scalerect), "scalerect"); + gluScaleImage(GL_RGBA, tpx, tpy, GL_UNSIGNED_BYTE, rect, rectw, recth, GL_UNSIGNED_BYTE, scalerect); + + rect= scalerect; + } } /* create image */ @@ -564,12 +618,18 @@ glBindTexture( GL_TEXTURE_2D, *bind); if (!(gpu_get_mipmap() && mipmap)) { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, rect); + if(use_high_bit_depth) + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, rectw, recth, 0, GL_RGBA, GL_FLOAT, frect); + else + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, rect); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1)); } else { - gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, rectw, recth, GL_RGBA, GL_UNSIGNED_BYTE, rect); + if(use_high_bit_depth) + gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA16, rectw, recth, GL_RGBA, GL_FLOAT, frect); + else + gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, rectw, recth, GL_RGBA, GL_UNSIGNED_BYTE, rect); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1)); @@ -584,9 +644,14 @@ /* clean up */ if (tilerect) MEM_freeN(tilerect); + if (ftilerect) + MEM_freeN(ftilerect); if (scalerect) MEM_freeN(scalerect); - + if (fscalerect) + MEM_freeN(fscalerect); + if (srgb_frect) + MEM_freeN(srgb_frect); return *bind; } @@ -671,6 +736,8 @@ else GPU_free_image(ima); } + else + ima->tpageflag &= ~IMA_MIPMAP_COMPLETE; } } @@ -681,6 +748,8 @@ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1)); } + else + ima->tpageflag &= ~IMA_MIPMAP_COMPLETE; } } } @@ -692,7 +761,7 @@ ibuf = BKE_image_get_ibuf(ima, NULL); if (ima->repbind || (gpu_get_mipmap() && mipmap) || !ima->bindcode || !ibuf || - (!is_pow2(ibuf->x) || !is_pow2(ibuf->y)) || + (!is_power_of_2_i(ibuf->x) || !is_power_of_2_i(ibuf->y)) || (w == 0) || (h == 0)) { /* these cases require full reload still */ GPU_free_image(ima); @@ -706,23 +775,21 @@ glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skip_pixels); glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skip_rows); - if (ibuf->rect_float){ - /*This case needs a whole new buffer*/ - if(ibuf->rect==NULL) { - IMB_rect_from_float(ibuf); - } - else { - /* Do partial drawing. 'buffer' holds only the changed part. Needed for color corrected result */ - float *buffer = (float *)MEM_mallocN(w*h*sizeof(float)*4, "temp_texpaint_float_buf"); - IMB_partial_rect_from_float(ibuf, buffer, x, y, w, h); - glBindTexture(GL_TEXTURE_2D, ima->bindcode); - glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, + /* if color correction is needed, we must update the part that needs updating. */ + if(ibuf->rect_float && (!U.use_16bit_textures || (ibuf->profile == IB_PROFILE_LINEAR_RGB))) { + float *buffer = MEM_mallocN(w*h*sizeof(float)*4, "temp_texpaint_float_buf"); + IMB_partial_rect_from_float(ibuf, buffer, x, y, w, h); + + glBindTexture(GL_TEXTURE_2D, ima->bindcode); + glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, GL_FLOAT, buffer); - MEM_freeN(buffer); - if(ima->tpageflag & IMA_MIPMAP_COMPLETE) - ima->tpageflag &= ~IMA_MIPMAP_COMPLETE; - return; - } + + MEM_freeN(buffer); + + if(ima->tpageflag & IMA_MIPMAP_COMPLETE) + ima->tpageflag &= ~IMA_MIPMAP_COMPLETE; + + return; } glBindTexture(GL_TEXTURE_2D, ima->bindcode); @@ -731,8 +798,12 @@ glPixelStorei(GL_UNPACK_SKIP_PIXELS, x); glPixelStorei(GL_UNPACK_SKIP_ROWS, y); - glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, - GL_UNSIGNED_BYTE, ibuf->rect); + if(ibuf->rect_float) + glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, + GL_FLOAT, ibuf->rect_float); + else + glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, + GL_UNSIGNED_BYTE, ibuf->rect); glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length); glPixelStorei(GL_UNPACK_SKIP_PIXELS, skip_pixels); @@ -876,7 +947,6 @@ if(ima->bindcode) { glDeleteTextures(1, (GLuint *)&ima->bindcode); ima->bindcode= 0; - ima->tpageflag &= ~IMA_MIPMAP_COMPLETE; } /* free glsl image binding */ @@ -891,8 +961,9 @@ MEM_freeN(ima->repbind); ima->repbind= NULL; - ima->tpageflag &= ~IMA_MIPMAP_COMPLETE; } + + ima->tpageflag &= ~IMA_MIPMAP_COMPLETE; } void GPU_free_images(void) @@ -1083,7 +1154,7 @@ /* setting do_alpha_after = 1 indicates this object needs to be * drawn in a second alpha pass for improved blending */ - if(GMS.use_alpha_pass && !GMS.is_alpha_pass) + if(do_alpha_after && !GMS.is_alpha_pass) if(ELEM3(alphablend, GPU_BLEND_ALPHA, GPU_BLEND_ADD, GPU_BLEND_ALPHA_SORT)) *do_alpha_after= 1; diff -Nru blender-2.61/source/blender/gpu/intern/gpu_extensions.c blender-2.62/source/blender/gpu/intern/gpu_extensions.c --- blender-2.61/source/blender/gpu/intern/gpu_extensions.c 2011-12-13 19:49:54.000000000 +0000 +++ blender-2.62/source/blender/gpu/intern/gpu_extensions.c 2012-02-15 19:34:38.000000000 +0000 @@ -41,9 +41,11 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" +#include "BLI_math_base.h" #include "GPU_draw.h" #include "GPU_extensions.h" +#include "gpu_codegen.h" #include #include @@ -84,6 +86,8 @@ /* GPU Extensions */ +static int gpu_extensions_init = 0; + void GPU_extensions_disable(void) { GG.extdisabled = 1; @@ -95,11 +99,11 @@ const char *vendor, *renderer; /* can't avoid calling this multiple times, see wm_window_add_ghostwindow */ - static char init= 0; - if(init) return; - init= 1; + if(gpu_extensions_init) return; + gpu_extensions_init= 1; glewInit(); + GPU_codegen_init(); /* glewIsSupported("GL_VERSION_2_0") */ @@ -122,12 +126,6 @@ if(strstr(vendor, "ATI")) { GG.device = GPU_DEVICE_ATI; GG.driver = GPU_DRIVER_OFFICIAL; - - /* ATI X1xxx cards (R500 chipset) lack full support for npot textures - * although they report the GLEW_ARB_texture_non_power_of_two extension. - */ - if(strstr(renderer, "X1")) - GG.npotdisabled = 1; } else if(strstr(vendor, "NVIDIA")) { GG.device = GPU_DEVICE_NVIDIA; @@ -143,17 +141,6 @@ else if(strstr(renderer, "Mesa DRI R") || (strstr(renderer, "Gallium ") && strstr(renderer, " on ATI "))) { GG.device = GPU_DEVICE_ATI; GG.driver = GPU_DRIVER_OPENSOURCE; - /* ATI 9500 to X2300 cards support NPoT textures poorly - * Incomplete list http://dri.freedesktop.org/wiki/ATIRadeon - * New IDs from MESA's src/gallium/drivers/r300/r300_screen.c - */ - if(strstr(renderer, "R3") || strstr(renderer, "RV3") || - strstr(renderer, "R4") || strstr(renderer, "RV4") || - strstr(renderer, "RS4") || strstr(renderer, "RC4") || - strstr(renderer, "R5") || strstr(renderer, "RV5") || - strstr(renderer, "RS600") || strstr(renderer, "RS690") || - strstr(renderer, "RS740")) - GG.npotdisabled = 1; } else if(strstr(renderer, "Nouveau") || strstr(vendor, "nouveau")) { GG.device = GPU_DEVICE_NVIDIA; @@ -176,6 +163,22 @@ GG.driver = GPU_DRIVER_ANY; } + if(GG.device == GPU_DEVICE_ATI) { + /* ATI 9500 to X2300 cards support NPoT textures poorly + * Incomplete list http://dri.freedesktop.org/wiki/ATIRadeon + * New IDs from MESA's src/gallium/drivers/r300/r300_screen.c + */ + if(strstr(renderer, "R3") || strstr(renderer, "RV3") || + strstr(renderer, "R4") || strstr(renderer, "RV4") || + strstr(renderer, "RS4") || strstr(renderer, "RC4") || + strstr(renderer, "R5") || strstr(renderer, "RV5") || + strstr(renderer, "RS600") || strstr(renderer, "RS690") || + strstr(renderer, "RS740") || strstr(renderer, "X1") || + strstr(renderer, "X2") || strstr(renderer, "Radeon 9") || + strstr(renderer, "RADEON 9")) + GG.npotdisabled = 1; + } + GG.os = GPU_OS_UNIX; #ifdef _WIN32 GG.os = GPU_OS_WIN; @@ -185,6 +188,12 @@ #endif } +void GPU_extensions_exit(void) +{ + gpu_extensions_init = 0; + GPU_codegen_exit(); +} + int GPU_glsl_support(void) { return !GG.extdisabled && GG.glslsupport; @@ -192,11 +201,6 @@ int GPU_non_power_of_two_support(void) { - /* Exception for buggy ATI/Apple driver in Mac OS X 10.5/10.6, - * they claim to support this but can cause system freeze */ - if(GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_MAC, GPU_DRIVER_OFFICIAL)) - return 0; - if(GG.npotdisabled) return 0; @@ -292,22 +296,6 @@ return pixels; } -static int is_pow2(int n) -{ - return ((n)&(n-1))==0; -} - -static int larger_pow2(int n) -{ - if (is_pow2(n)) - return n; - - while(!is_pow2(n)) - n= n&(n-1); - - return n*2; -} - static void GPU_glTexSubImageEmpty(GLenum target, GLenum format, int x, int y, int w, int h) { void *pixels = MEM_callocN(sizeof(char)*4*w*h, "GPUTextureEmptyPixels"); @@ -353,8 +341,8 @@ } if (!GPU_non_power_of_two_support()) { - tex->w = larger_pow2(tex->w); - tex->h = larger_pow2(tex->h); + tex->w = power_of_2_max_i(tex->w); + tex->h = power_of_2_max_i(tex->h); } tex->number = 0; @@ -462,9 +450,9 @@ } if (!GPU_non_power_of_two_support()) { - tex->w = larger_pow2(tex->w); - tex->h = larger_pow2(tex->h); - tex->depth = larger_pow2(tex->depth); + tex->w = power_of_2_max_i(tex->w); + tex->h = power_of_2_max_i(tex->h); + tex->depth = power_of_2_max_i(tex->depth); } tex->number = 0; @@ -1162,7 +1150,7 @@ GPU_print_error("Post Uniform Texture"); } -int GPU_shader_get_attribute(GPUShader *shader, char *name) +int GPU_shader_get_attribute(GPUShader *shader, const char *name) { int index; diff -Nru blender-2.61/source/blender/gpu/intern/gpu_material.c blender-2.62/source/blender/gpu/intern/gpu_material.c --- blender-2.61/source/blender/gpu/intern/gpu_material.c 2011-12-13 19:49:54.000000000 +0000 +++ blender-2.62/source/blender/gpu/intern/gpu_material.c 2012-02-15 19:34:38.000000000 +0000 @@ -173,7 +173,7 @@ * removed by the glsl compiler by dead code elimination */ for(a=0, b=0; atotlayer; a++) { - sprintf(name, "att%d", attribs->layer[a].attribid); + BLI_snprintf(name, sizeof(name), "att%d", attribs->layer[a].attribid); attribs->layer[a].glindex = GPU_shader_get_attribute(shader, name); if(attribs->layer[a].glindex >= 0) { @@ -321,9 +321,9 @@ } if(material->dynproperty & DYN_LAMP_IMAT) - mul_m4_m4m4(lamp->dynimat, viewinv, lamp->imat); + mult_m4_m4m4(lamp->dynimat, lamp->imat, viewinv); if(material->dynproperty & DYN_LAMP_PERSMAT) - mul_m4_m4m4(lamp->dynpersmat, viewinv, lamp->persmat); + mult_m4_m4m4(lamp->dynpersmat, lamp->persmat, viewinv); } GPU_pass_update_uniforms(material->pass); @@ -972,7 +972,6 @@ GPU_link(mat, "mtex_mapping_ofs", texco, GPU_uniform(ofs), &texco); talpha = 0; - rgbnor = 0; if(tex && tex->type == TEX_IMAGE && tex->ima) { GPU_link(mat, "mtex_image", texco, GPU_image(tex->ima, &tex->iuser), &tin, &trgb); @@ -1086,7 +1085,7 @@ GPU_link(mat, "mtex_blend_normal", tnorfac, shi->vn, newnor, &shi->vn); } - } else if( (mtex->texflag & (MTEX_3TAP_BUMP|MTEX_5TAP_BUMP)) || found_deriv_map) { + } else if( (mtex->texflag & (MTEX_3TAP_BUMP|MTEX_5TAP_BUMP|MTEX_BICUBIC_BUMP)) || found_deriv_map) { /* ntap bumpmap image */ int iBumpSpace; float ima_x, ima_y; @@ -1121,7 +1120,11 @@ // to inverting the bump map. Should this ever change // this negate must be removed. norfac = -hScale * mtex->norfac; - if(found_deriv_map) norfac /= sqrtf(ima_x*ima_y); + if(found_deriv_map) + { + float fVirtDim = sqrtf(fabsf(ima_x*mtex->size[0]*ima_y*mtex->size[1])); + norfac /= MAX2(fVirtDim, FLT_EPSILON); + } tnorfac = GPU_uniform(&norfac); @@ -1184,10 +1187,21 @@ GPU_link( mat, "mtex_bump_tap3", texco, GPU_image(tex->ima, &tex->iuser), tnorfac, &dBs, &dBt ); - else - GPU_link( mat, "mtex_bump_tap5", + else if( mtex->texflag & MTEX_5TAP_BUMP ) + GPU_link( mat, "mtex_bump_tap5", texco, GPU_image(tex->ima, &tex->iuser), tnorfac, &dBs, &dBt ); + else if( mtex->texflag & MTEX_BICUBIC_BUMP ){ + if(GPU_bicubic_bump_support()){ + GPU_link( mat, "mtex_bump_bicubic", + texco, GPU_image(tex->ima, &tex->iuser), tnorfac, + &dBs, &dBt ); + }else{ + GPU_link( mat, "mtex_bump_tap5", + texco, GPU_image(tex->ima, &tex->iuser), tnorfac, + &dBs, &dBt ); + } + } if( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) { @@ -1660,7 +1674,7 @@ normalize_v3(lamp->viewmat[2]); /* makeshadowbuf */ - mul_m4_m4m4(persmat, lamp->viewmat, lamp->winmat); + mult_m4_m4m4(persmat, lamp->winmat, lamp->viewmat); /* opengl depth buffer is range 0.0..1.0 instead of -1.0..1.0 in blender */ unit_m4(rangemat); @@ -1671,7 +1685,7 @@ rangemat[3][1] = 0.5f; rangemat[3][2] = 0.5f; - mul_m4_m4m4(lamp->persmat, persmat, rangemat); + mult_m4_m4m4(lamp->persmat, rangemat, persmat); /* opengl */ glDisable(GL_SCISSOR_TEST); diff -Nru blender-2.61/source/blender/gpu/intern/gpu_shader_material.glsl blender-2.62/source/blender/gpu/intern/gpu_shader_material.glsl --- blender-2.61/source/blender/gpu/intern/gpu_shader_material.glsl 2011-12-13 19:49:54.000000000 +0000 +++ blender-2.62/source/blender/gpu/intern/gpu_shader_material.glsl 2012-02-15 19:34:38.000000000 +0000 @@ -306,7 +306,7 @@ void normal(vec3 dir, vec3 nor, out vec3 outnor, out float outdot) { - outnor = dir; + outnor = nor; outdot = -dot(dir, nor); } @@ -1152,8 +1152,8 @@ out float fPrevMagnitude_out, out vec3 vNacc_out, out vec3 vR1, out vec3 vR2, out float fDet ) { - mat3 obj2view = to_mat3(mView * mObj); - mat3 view2obj = to_mat3(mObjInv * mViewInv); + mat3 obj2view = to_mat3(gl_ModelViewMatrix); + mat3 view2obj = to_mat3(gl_ModelViewMatrixInverse); vec3 vSigmaS = view2obj * dFdx( surf_pos ); vec3 vSigmaT = view2obj * dFdy( surf_pos ); @@ -1225,6 +1225,100 @@ dBt = hScale * (Hul - Hll); } +#ifdef BUMP_BICUBIC + +void mtex_bump_bicubic( vec3 texco, sampler2D ima, float hScale, + out float dBs, out float dBt ) +{ + float Hl; + float Hr; + float Hd; + float Hu; + + vec2 TexDx = dFdx(texco.xy); + vec2 TexDy = dFdy(texco.xy); + + vec2 STl = texco.xy - 0.5 * TexDx ; + vec2 STr = texco.xy + 0.5 * TexDx ; + vec2 STd = texco.xy - 0.5 * TexDy ; + vec2 STu = texco.xy + 0.5 * TexDy ; + + rgbtobw(texture2D(ima, STl), Hl); + rgbtobw(texture2D(ima, STr), Hr); + rgbtobw(texture2D(ima, STd), Hd); + rgbtobw(texture2D(ima, STu), Hu); + + vec2 dHdxy = vec2(Hr - Hl, Hu - Hd); + float fBlend = clamp(1.0-textureQueryLOD(ima, texco.xy).x, 0.0, 1.0); + if(fBlend!=0.0) + { + // the derivative of the bicubic sampling of level 0 + ivec2 vDim; + vDim = textureSize(ima, 0); + + // taking the fract part of the texture coordinate is a hardcoded wrap mode. + // this is acceptable as textures use wrap mode exclusively in 3D view elsewhere in blender. + // this is done so that we can still get a valid texel with uvs outside the 0,1 range + // by texelFetch below, as coordinates are clamped when using this function. + vec2 fTexLoc = vDim*fract(texco.xy) - vec2(0.5, 0.5); + ivec2 iTexLoc = ivec2(floor(fTexLoc)); + vec2 t = clamp(fTexLoc - iTexLoc, 0.0, 1.0); // sat just to be pedantic + +/******************************************************************************************* + * This block will replace the one below when one channel textures are properly supported. * + ******************************************************************************************* + vec4 vSamplesUL = textureGather(ima, (iTexLoc+ivec2(-1,-1) + vec2(0.5,0.5))/vDim ); + vec4 vSamplesUR = textureGather(ima, (iTexLoc+ivec2(1,-1) + vec2(0.5,0.5))/vDim ); + vec4 vSamplesLL = textureGather(ima, (iTexLoc+ivec2(-1,1) + vec2(0.5,0.5))/vDim ); + vec4 vSamplesLR = textureGather(ima, (iTexLoc+ivec2(1,1) + vec2(0.5,0.5))/vDim ); + + mat4 H = mat4(vSamplesUL.w, vSamplesUL.x, vSamplesLL.w, vSamplesLL.x, + vSamplesUL.z, vSamplesUL.y, vSamplesLL.z, vSamplesLL.y, + vSamplesUR.w, vSamplesUR.x, vSamplesLR.w, vSamplesLR.x, + vSamplesUR.z, vSamplesUR.y, vSamplesLR.z, vSamplesLR.y); +*/ + ivec2 iTexLocMod = iTexLoc + ivec2(-1, -1); + + mat4 H; + + for(int i = 0; i < 4; i++){ + for(int j = 0; j < 4; j++){ + ivec2 iTexTmp = iTexLocMod + ivec2(i,j); + + // wrap texture coordinates manually for texelFetch to work on uvs oitside the 0,1 range. + // this is guaranteed to work since we take the fractional part of the uv above. + iTexTmp.x = (iTexTmp.x < 0)? iTexTmp.x + vDim.x : ((iTexTmp.x >= vDim.x)? iTexTmp.x - vDim.x : iTexTmp.x); + iTexTmp.y = (iTexTmp.y < 0)? iTexTmp.y + vDim.y : ((iTexTmp.y >= vDim.y)? iTexTmp.y - vDim.y : iTexTmp.y); + + rgbtobw(texelFetch(ima, iTexTmp, 0), H[i][j]); + } + } + + float x = t.x, y = t.y; + float x2 = x * x, x3 = x2 * x, y2 = y * y, y3 = y2 * y; + + vec4 X = vec4(-0.5*(x3+x)+x2, 1.5*x3-2.5*x2+1, -1.5*x3+2*x2+0.5*x, 0.5*(x3-x2)); + vec4 Y = vec4(-0.5*(y3+y)+y2, 1.5*y3-2.5*y2+1, -1.5*y3+2*y2+0.5*y, 0.5*(y3-y2)); + vec4 dX = vec4(-1.5*x2+2*x-0.5, 4.5*x2-5*x, -4.5*x2+4*x+0.5, 1.5*x2-x); + vec4 dY = vec4(-1.5*y2+2*y-0.5, 4.5*y2-5*y, -4.5*y2+4*y+0.5, 1.5*y2-y); + + // complete derivative in normalized coordinates (mul by vDim) + vec2 dHdST = vDim * vec2(dot(Y, H * dX), dot(dY, H * X)); + + // transform derivative to screen-space + vec2 dHdxy_bicubic = vec2( dHdST.x * TexDx.x + dHdST.y * TexDx.y, + dHdST.x * TexDy.x + dHdST.y * TexDy.y ); + + // blend between the two + dHdxy = dHdxy*(1-fBlend) + dHdxy_bicubic*fBlend; + } + + dBs = hScale * dHdxy.x; + dBt = hScale * dHdxy.y; +} + +#endif + void mtex_bump_tap5( vec3 texco, sampler2D ima, float hScale, out float dBs, out float dBt ) { @@ -1983,19 +2077,21 @@ /* textures */ -void node_tex_blend(vec3 co, out float fac) +void node_tex_gradient(vec3 co, out vec4 color, out float fac) { + color = vec4(1.0); fac = 1.0; } -void node_tex_clouds(vec3 co, float size, out vec4 color, out float fac) +void node_tex_checker(vec3 co, vec4 color1, vec4 color2, float scale, out vec4 color, out float fac) { color = vec4(1.0); fac = 1.0; } -void node_tex_distnoise(vec3 co, float size, float distortion, out float fac) +void node_tex_clouds(vec3 co, float size, out vec4 color, out float fac) { + color = vec4(1.0); fac = 1.0; } @@ -2012,88 +2108,19 @@ color = texture2D(ima, co.xy); } -void node_tex_magic(vec3 p, float turbulence, float n, out vec4 color) -{ - float turb = turbulence/5.0; - - float x = sin((p.x + p.y + p.z)*5.0); - float y = cos((-p.x + p.y - p.z)*5.0); - float z = -cos((-p.x - p.y + p.z)*5.0); - - if(n > 0.0) { - x *= turb; - y *= turb; - z *= turb; - y = -cos(x-y+z); - y *= turb; - - if(n > 1.0) { - x= cos(x-y-z); - x *= turb; - - if(n > 2.0) { - z= sin(-x-y-z); - z *= turb; - - if(n > 3.0) { - x= -cos(-x+y-z); - x *= turb; - - if(n > 4.0) { - y= -sin(-x+y+z); - y *= turb; - - if(n > 5.0) { - y= -cos(-x+y+z); - y *= turb; - - if(n > 6.0) { - x= cos(x+y+z); - x *= turb; - - if(n > 7.0) { - z= sin(x+y-z); - z *= turb; - - if(n > 8.0) { - x= -cos(-x-y+z); - x *= turb; - - if(n > 9.0) { - y= -sin(x-y+z); - y *= turb; - } - } - } - } - } - } - } - } - } - } - - if(turb != 0.0) { - turb *= 2.0; - x /= turb; - y /= turb; - z /= turb; - } - - color = vec4(0.5 - x, 0.5 - y, 0.5 - z, 1.0); -} - -void node_tex_marble(vec3 co, float size, float turbulence, out float fac) +void node_tex_magic(vec3 p, float scale, float distortion, out vec4 color, out float fac) { + color = vec4(1.0); fac = 1.0; } -void node_tex_musgrave(vec3 co, float size, float dimension, float lacunarity, float octaves, float offset, float gain, out float fac) +void node_tex_musgrave(vec3 co, float scale, float detail, float dimension, float lacunarity, float offset, float gain, out vec4 color, out float fac) { + color = vec4(1.0); fac = 1.0; } -void node_tex_noise(vec3 co, out vec4 color, out float fac) +void node_tex_noise(vec3 co, float scale, float detail, float distortion, out vec4 color, out float fac) { color = vec4(1.0); fac = 1.0; @@ -2104,19 +2131,15 @@ color = vec4(1.0); } -void node_tex_stucci(vec3 co, float size, float turbulence, out float fac) -{ - fac = 1.0; -} - -void node_tex_voronoi(vec3 co, float size, float weight1, float weight2, float weight3, float weight4, float exponent, out vec4 color, out float fac) +void node_tex_voronoi(vec3 co, float scale, out vec4 color, out float fac) { color = vec4(1.0); fac = 1.0; } -void node_tex_wood(vec3 co, float size, float turbulence, out float fac) +void node_tex_wave(vec3 co, float scale, float distortion, float detail, float detail_scale, out vec4 color, out float fac) { + color = vec4(1.0); fac = 1.0; } diff -Nru blender-2.61/source/blender/gpu/intern/gpu_shader_material.glsl.c blender-2.62/source/blender/gpu/intern/gpu_shader_material.glsl.c --- blender-2.61/source/blender/gpu/intern/gpu_shader_material.glsl.c 2011-12-13 19:49:54.000000000 +0000 +++ blender-2.62/source/blender/gpu/intern/gpu_shader_material.glsl.c 2012-02-15 19:34:38.000000000 +0000 @@ -1,1457 +1,1541 @@ /* DataToC output of file */ -int datatoc_gpu_shader_material_glsl_size= 46917; +int datatoc_gpu_shader_material_glsl_size= 49606; char datatoc_gpu_shader_material_glsl[]= { - 10,102,108,111, 97, -116, 32,101,120,112, 95, 98,108,101,110,100,101,114, 40,102,108,111, 97,116, 32,102, 41, 10,123, 10, 9,114,101,116,117,114,110, - 32,112,111,119, 40, 50, 46, 55, 49, 56, 50, 56, 49, 56, 50, 56, 52, 54, 44, 32,102, 41, 59, 10,125, 10, 10,118,111,105,100, 32, -114,103, 98, 95,116,111, 95,104,115,118, 40,118,101, 99, 52, 32,114,103, 98, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117, -116, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32, 99,109, 97,120, 44, 32, 99,109,105,110, 44, 32,104, 44, 32,115, 44, - 32,118, 44, 32, 99,100,101,108,116, 97, 59, 10, 9,118,101, 99, 51, 32, 99, 59, 10, 10, 9, 99,109, 97,120, 32, 61, 32,109, 97, -120, 40,114,103, 98, 91, 48, 93, 44, 32,109, 97,120, 40,114,103, 98, 91, 49, 93, 44, 32,114,103, 98, 91, 50, 93, 41, 41, 59, 10, - 9, 99,109,105,110, 32, 61, 32,109,105,110, 40,114,103, 98, 91, 48, 93, 44, 32,109,105,110, 40,114,103, 98, 91, 49, 93, 44, 32, -114,103, 98, 91, 50, 93, 41, 41, 59, 10, 9, 99,100,101,108,116, 97, 32, 61, 32, 99,109, 97,120, 45, 99,109,105,110, 59, 10, 10, - 9,118, 32, 61, 32, 99,109, 97,120, 59, 10, 9,105,102, 32, 40, 99,109, 97,120, 33, 61, 48, 46, 48, 41, 10, 9, 9,115, 32, 61, - 32, 99,100,101,108,116, 97, 47, 99,109, 97,120, 59, 10, 9,101,108,115,101, 32,123, 10, 9, 9,115, 32, 61, 32, 48, 46, 48, 59, - 10, 9, 9,104, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 10, 9,105,102, 32, 40,115, 32, 61, 61, 32, 48, 46, 48, 41, 32,123, - 10, 9, 9,104, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9, 99, 32, 61, 32, 40,118,101, - 99, 51, 40, 99,109, 97,120, 44, 32, 99,109, 97,120, 44, 32, 99,109, 97,120, 41, 32, 45, 32,114,103, 98, 46,120,121,122, 41, 47, - 99,100,101,108,116, 97, 59, 10, 10, 9, 9,105,102, 32, 40,114,103, 98, 46,120, 61, 61, 99,109, 97,120, 41, 32,104, 32, 61, 32, - 99, 91, 50, 93, 32, 45, 32, 99, 91, 49, 93, 59, 10, 9, 9,101,108,115,101, 32,105,102, 32, 40,114,103, 98, 46,121, 61, 61, 99, -109, 97,120, 41, 32,104, 32, 61, 32, 50, 46, 48, 32, 43, 32, 99, 91, 48, 93, 32, 45, 32, 32, 99, 91, 50, 93, 59, 10, 9, 9,101, -108,115,101, 32,104, 32, 61, 32, 52, 46, 48, 32, 43, 32, 99, 91, 49, 93, 32, 45, 32, 99, 91, 48, 93, 59, 10, 10, 9, 9,104, 32, - 47, 61, 32, 54, 46, 48, 59, 10, 10, 9, 9,105,102, 32, 40,104, 60, 48, 46, 48, 41, 10, 9, 9, 9,104, 32, 43, 61, 32, 49, 46, - 48, 59, 10, 9,125, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32,118,101, 99, 52, 40,104, 44, 32,115, 44, 32,118, 44, 32,114, -103, 98, 46,119, 41, 59, 10,125, 10, 10,118,111,105,100, 32,104,115,118, 95,116,111, 95,114,103, 98, 40,118,101, 99, 52, 32,104, -115,118, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,105, 44, - 32,102, 44, 32,112, 44, 32,113, 44, 32,116, 44, 32,104, 44, 32,115, 44, 32,118, 59, 10, 9,118,101, 99, 51, 32,114,103, 98, 59, - 10, 10, 9,104, 32, 61, 32,104,115,118, 91, 48, 93, 59, 10, 9,115, 32, 61, 32,104,115,118, 91, 49, 93, 59, 10, 9,118, 32, 61, - 32,104,115,118, 91, 50, 93, 59, 10, 10, 9,105,102, 40,115, 61, 61, 48, 46, 48, 41, 32,123, 10, 9, 9,114,103, 98, 32, 61, 32, -118,101, 99, 51, 40,118, 44, 32,118, 44, 32,118, 41, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9,105,102, 40,104, - 61, 61, 49, 46, 48, 41, 10, 9, 9, 9,104, 32, 61, 32, 48, 46, 48, 59, 10, 9, 9, 10, 9, 9,104, 32, 42, 61, 32, 54, 46, 48, - 59, 10, 9, 9,105, 32, 61, 32,102,108,111,111,114, 40,104, 41, 59, 10, 9, 9,102, 32, 61, 32,104, 32, 45, 32,105, 59, 10, 9, - 9,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,102, 44, 32,102, 44, 32,102, 41, 59, 10, 9, 9,112, 32, 61, 32,118, 42, 40, 49, - 46, 48, 45,115, 41, 59, 10, 9, 9,113, 32, 61, 32,118, 42, 40, 49, 46, 48, 45, 40,115, 42,102, 41, 41, 59, 10, 9, 9,116, 32, - 61, 32,118, 42, 40, 49, 46, 48, 45, 40,115, 42, 40, 49, 46, 48, 45,102, 41, 41, 41, 59, 10, 9, 9, 10, 9, 9,105,102, 32, 40, -105, 32, 61, 61, 32, 48, 46, 48, 41, 32,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,118, 44, 32,116, 44, 32,112, 41, 59, 10, 9, - 9,101,108,115,101, 32,105,102, 32, 40,105, 32, 61, 61, 32, 49, 46, 48, 41, 32,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,113, - 44, 32,118, 44, 32,112, 41, 59, 10, 9, 9,101,108,115,101, 32,105,102, 32, 40,105, 32, 61, 61, 32, 50, 46, 48, 41, 32,114,103, - 98, 32, 61, 32,118,101, 99, 51, 40,112, 44, 32,118, 44, 32,116, 41, 59, 10, 9, 9,101,108,115,101, 32,105,102, 32, 40,105, 32, - 61, 61, 32, 51, 46, 48, 41, 32,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,112, 44, 32,113, 44, 32,118, 41, 59, 10, 9, 9,101, -108,115,101, 32,105,102, 32, 40,105, 32, 61, 61, 32, 52, 46, 48, 41, 32,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,116, 44, 32, -112, 44, 32,118, 41, 59, 10, 9, 9,101,108,115,101, 32,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,118, 44, 32,112, 44, 32,113, - 41, 59, 10, 9,125, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32,118,101, 99, 52, 40,114,103, 98, 44, 32,104,115,118, 46,119, - 41, 59, 10,125, 10, 10,102,108,111, 97,116, 32,115,114,103, 98, 95,116,111, 95,108,105,110,101, 97,114,114,103, 98, 40,102,108, -111, 97,116, 32, 99, 41, 10,123, 10, 9,105,102, 40, 99, 32, 60, 32, 48, 46, 48, 52, 48, 52, 53, 41, 10, 9, 9,114,101,116,117, -114,110, 32, 40, 99, 32, 60, 32, 48, 46, 48, 41, 63, 32, 48, 46, 48, 58, 32, 99, 32, 42, 32, 40, 49, 46, 48, 47, 49, 50, 46, 57, - 50, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,114,101,116,117,114,110, 32,112,111,119, 40, 40, 99, 32, 43, 32, 48, 46, 48, 53, - 53, 41, 42, 40, 49, 46, 48, 47, 49, 46, 48, 53, 53, 41, 44, 32, 50, 46, 52, 41, 59, 10,125, 10, 10,102,108,111, 97,116, 32,108, -105,110,101, 97,114,114,103, 98, 95,116,111, 95,115,114,103, 98, 40,102,108,111, 97,116, 32, 99, 41, 10,123, 10, 9,105,102, 40, - 99, 32, 60, 32, 48, 46, 48, 48, 51, 49, 51, 48, 56, 41, 10, 9, 9,114,101,116,117,114,110, 32, 40, 99, 32, 60, 32, 48, 46, 48, - 41, 63, 32, 48, 46, 48, 58, 32, 99, 32, 42, 32, 49, 50, 46, 57, 50, 59, 10, 9,101,108,115,101, 10, 9, 9,114,101,116,117,114, -110, 32, 49, 46, 48, 53, 53, 32, 42, 32,112,111,119, 40, 99, 44, 32, 49, 46, 48, 47, 50, 46, 52, 41, 32, 45, 32, 48, 46, 48, 53, - 53, 59, 10,125, 10, 10,118,111,105,100, 32,115,114,103, 98, 95,116,111, 95,108,105,110,101, 97,114,114,103, 98, 40,118,101, 99, - 52, 32, 99,111,108, 95,102,114,111,109, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108, 95,116,111, 41, 10,123, 10, 9, - 99,111,108, 95,116,111, 46,114, 32, 61, 32,115,114,103, 98, 95,116,111, 95,108,105,110,101, 97,114,114,103, 98, 40, 99,111,108, - 95,102,114,111,109, 46,114, 41, 59, 10, 9, 99,111,108, 95,116,111, 46,103, 32, 61, 32,115,114,103, 98, 95,116,111, 95,108,105, -110,101, 97,114,114,103, 98, 40, 99,111,108, 95,102,114,111,109, 46,103, 41, 59, 10, 9, 99,111,108, 95,116,111, 46, 98, 32, 61, - 32,115,114,103, 98, 95,116,111, 95,108,105,110,101, 97,114,114,103, 98, 40, 99,111,108, 95,102,114,111,109, 46, 98, 41, 59, 10, - 9, 99,111,108, 95,116,111, 46, 97, 32, 61, 32, 99,111,108, 95,102,114,111,109, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32, -108,105,110,101, 97,114,114,103, 98, 95,116,111, 95,115,114,103, 98, 40,118,101, 99, 52, 32, 99,111,108, 95,102,114,111,109, 44, - 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108, 95,116,111, 41, 10,123, 10, 9, 99,111,108, 95,116,111, 46,114, 32, 61, 32, -108,105,110,101, 97,114,114,103, 98, 95,116,111, 95,115,114,103, 98, 40, 99,111,108, 95,102,114,111,109, 46,114, 41, 59, 10, 9, - 99,111,108, 95,116,111, 46,103, 32, 61, 32,108,105,110,101, 97,114,114,103, 98, 95,116,111, 95,115,114,103, 98, 40, 99,111,108, - 95,102,114,111,109, 46,103, 41, 59, 10, 9, 99,111,108, 95,116,111, 46, 98, 32, 61, 32,108,105,110,101, 97,114,114,103, 98, 95, -116,111, 95,115,114,103, 98, 40, 99,111,108, 95,102,114,111,109, 46, 98, 41, 59, 10, 9, 99,111,108, 95,116,111, 46, 97, 32, 61, - 32, 99,111,108, 95,102,114,111,109, 46, 97, 59, 10,125, 10, 10, 35,100,101,102,105,110,101, 32, 77, 95, 80, 73, 32, 51, 46, 49, - 52, 49, 53, 57, 50, 54, 53, 51, 53, 56, 57, 55, 57, 51, 50, 51, 56, 52, 54, 10, 35,100,101,102,105,110,101, 32, 77, 95, 49, 95, - 80, 73, 32, 48, 46, 51, 49, 56, 51, 48, 57, 56, 56, 54, 49, 56, 51, 55, 57, 48, 54, 57, 10, 10, 47, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 32, 83, 72, 65, 68, 69, 82, 32, 78, 79, 68, 69, 83, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 47, 10, 10,118,111,105,100, 32,118, 99,111,108, 95, 97,116,116,114,105, 98,117,116,101, 40,118,101, 99, 52, 32, 97,116,116, -118, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,118, 99,111,108, 41, 10,123, 10, 9,118, 99,111,108, 32, 61, 32,118, -101, 99, 52, 40, 97,116,116,118, 99,111,108, 46,120, 47, 50, 53, 53, 46, 48, 44, 32, 97,116,116,118, 99,111,108, 46,121, 47, 50, - 53, 53, 46, 48, 44, 32, 97,116,116,118, 99,111,108, 46,122, 47, 50, 53, 53, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10,125, 10, 10, -118,111,105,100, 32,117,118, 95, 97,116,116,114,105, 98,117,116,101, 40,118,101, 99, 50, 32, 97,116,116,117,118, 44, 32,111,117, -116, 32,118,101, 99, 51, 32,117,118, 41, 10,123, 10, 9,117,118, 32, 61, 32,118,101, 99, 51, 40, 97,116,116,117,118, 42, 50, 46, - 48, 32, 45, 32,118,101, 99, 50, 40, 49, 46, 48, 44, 32, 49, 46, 48, 41, 44, 32, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105, -100, 32,103,101,111,109, 40,118,101, 99, 51, 32, 99,111, 44, 32,118,101, 99, 51, 32,110,111,114, 44, 32,109, 97,116, 52, 32,118, -105,101,119,105,110,118,109, 97,116, 44, 32,118,101, 99, 51, 32, 97,116,116,111,114, 99,111, 44, 32,118,101, 99, 50, 32, 97,116, -116,117,118, 44, 32,118,101, 99, 52, 32, 97,116,116,118, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,103,108,111, 98, - 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,108,111, 99, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118,105,101, -119, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,114, 99,111, 44, 32,111,117,116, 32,118,101, 99, 51, 32,117,118, 44, 32,111, -117,116, 32,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,118, 99,111,108, 44, 32,111, -117,116, 32,102,108,111, 97,116, 32,118, 99,111,108, 95, 97,108,112,104, 97, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102, -114,111,110,116, 98, 97, 99,107, 41, 10,123, 10, 9,108,111, 99, 97,108, 32, 61, 32, 99,111, 59, 10, 9,118,105,101,119, 32, 61, - 32,110,111,114,109, 97,108,105,122,101, 40,108,111, 99, 97,108, 41, 59, 10, 9,103,108,111, 98, 97,108, 32, 61, 32, 40,118,105, -101,119,105,110,118,109, 97,116, 42,118,101, 99, 52, 40,108,111, 99, 97,108, 44, 32, 49, 46, 48, 41, 41, 46,120,121,122, 59, 10, - 9,111,114, 99,111, 32, 61, 32, 97,116,116,111,114, 99,111, 59, 10, 9,117,118, 95, 97,116,116,114,105, 98,117,116,101, 40, 97, -116,116,117,118, 44, 32,117,118, 41, 59, 10, 9,110,111,114,109, 97,108, 32, 61, 32, 45,110,111,114,109, 97,108,105,122,101, 40, -110,111,114, 41, 59, 9, 47, 42, 32, 98,108,101,110,100,101,114, 32,114,101,110,100,101,114, 32,110,111,114,109, 97,108, 32,105, -115, 32,110,101,103, 97,116,101,100, 32, 42, 47, 10, 9,118, 99,111,108, 95, 97,116,116,114,105, 98,117,116,101, 40, 97,116,116, -118, 99,111,108, 44, 32,118, 99,111,108, 41, 59, 10, 9,118, 99,111,108, 95, 97,108,112,104, 97, 32, 61, 32, 97,116,116,118, 99, -111,108, 46, 97, 59, 10, 9,102,114,111,110,116, 98, 97, 99,107, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32, -109, 97,112,112,105,110,103, 40,118,101, 99, 51, 32,118,101, 99, 44, 32,109, 97,116, 52, 32,109, 97,116, 44, 32,118,101, 99, 51, - 32,109,105,110,118,101, 99, 44, 32,118,101, 99, 51, 32,109, 97,120,118,101, 99, 44, 32,102,108,111, 97,116, 32,100,111,109,105, -110, 44, 32,102,108,111, 97,116, 32,100,111,109, 97,120, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 41, - 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32, 40,109, 97,116, 32, 42, 32,118,101, 99, 52, 40,118,101, 99, 44, 32, 49, 46, - 48, 41, 41, 46,120,121,122, 59, 10, 9,105,102, 40,100,111,109,105,110, 32, 61, 61, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116, -118,101, 99, 32, 61, 32,109, 97,120, 40,111,117,116,118,101, 99, 44, 32,109,105,110,118,101, 99, 41, 59, 10, 9,105,102, 40,100, -111,109, 97,120, 32, 61, 61, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116,118,101, 99, 32, 61, 32,109,105,110, 40,111,117,116,118, -101, 99, 44, 32,109, 97,120,118,101, 99, 41, 59, 10,125, 10, 10,118,111,105,100, 32, 99, 97,109,101,114, 97, 40,118,101, 99, 51, - 32, 99,111, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,105,101,119, 44, 32,111,117,116, 32,102,108,111, 97,116, - 32,111,117,116,100,101,112,116,104, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,100,105,115,116, 41, 10,123, 10, - 9,111,117,116,100,101,112,116,104, 32, 61, 32, 97, 98,115, 40, 99,111, 46,122, 41, 59, 10, 9,111,117,116,100,105,115,116, 32, - 61, 32,108,101,110,103,116,104, 40, 99,111, 41, 59, 10, 9,111,117,116,118,105,101,119, 32, 61, 32,110,111,114,109, 97,108,105, -122,101, 40, 99,111, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95, 97,100,100, 40,102,108,111, 97,116, 32,118, - 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97, -108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118, 97,108, 49, 32, 43, 32,118, 97,108, 50, 59, 10,125, 10, 10,118, -111,105,100, 32,109, 97,116,104, 95,115,117, 98,116,114, 97, 99,116, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108, -111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111, -117,116,118, 97,108, 32, 61, 32,118, 97,108, 49, 32, 45, 32,118, 97,108, 50, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116, -104, 95,109,117,108,116,105,112,108,121, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, - 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, - 32,118, 97,108, 49, 32, 42, 32,118, 97,108, 50, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,100,105,118,105,100, -101, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108, -111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,105,102, 32, 40,118, 97,108, 50, 32, 61, 61, 32, 48, 46, 48, 41, 10, - 9, 9,111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,118, 97,108, 32, 61, - 32,118, 97,108, 49, 32, 47, 32,118, 97,108, 50, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,115,105,110,101, 40, -102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9, -111,117,116,118, 97,108, 32, 61, 32,115,105,110, 40,118, 97,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95, - 99,111,115,105,110,101, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, - 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 99,111,115, 40,118, 97,108, 41, 59, 10,125, 10, 10,118,111,105, -100, 32,109, 97,116,104, 95,116, 97,110,103,101,110,116, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108, -111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,116, 97,110, 40,118, 97,108, 41, - 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95, 97,115,105,110, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111, -117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,105,102, 32, 40,118, 97,108, 32, 60, 61, 32, 49, - 46, 48, 32, 38, 38, 32,118, 97,108, 32, 62, 61, 32, 45, 49, 46, 48, 41, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 97,115, -105,110, 40,118, 97,108, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10,125, - 10, 10,118,111,105,100, 32,109, 97,116,104, 95, 97, 99,111,115, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32, -102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,105,102, 32, 40,118, 97,108, 32, 60, 61, 32, 49, 46, 48, 32, - 38, 38, 32,118, 97,108, 32, 62, 61, 32, 45, 49, 46, 48, 41, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 97, 99,111,115, 40, -118, 97,108, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118, -111,105,100, 32,109, 97,116,104, 95, 97,116, 97,110, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, - 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 97,116, 97,110, 40,118, 97,108, 41, - 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,112,111,119, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102, + 10,102,108,111, 97,116, + 32,101,120,112, 95, 98,108,101,110,100,101,114, 40,102,108,111, 97,116, 32,102, 41, 10,123, 10, 9,114,101,116,117,114,110, 32, +112,111,119, 40, 50, 46, 55, 49, 56, 50, 56, 49, 56, 50, 56, 52, 54, 44, 32,102, 41, 59, 10,125, 10, 10,118,111,105,100, 32,114, +103, 98, 95,116,111, 95,104,115,118, 40,118,101, 99, 52, 32,114,103, 98, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, + 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32, 99,109, 97,120, 44, 32, 99,109,105,110, 44, 32,104, 44, 32,115, 44, 32, +118, 44, 32, 99,100,101,108,116, 97, 59, 10, 9,118,101, 99, 51, 32, 99, 59, 10, 10, 9, 99,109, 97,120, 32, 61, 32,109, 97,120, + 40,114,103, 98, 91, 48, 93, 44, 32,109, 97,120, 40,114,103, 98, 91, 49, 93, 44, 32,114,103, 98, 91, 50, 93, 41, 41, 59, 10, 9, + 99,109,105,110, 32, 61, 32,109,105,110, 40,114,103, 98, 91, 48, 93, 44, 32,109,105,110, 40,114,103, 98, 91, 49, 93, 44, 32,114, +103, 98, 91, 50, 93, 41, 41, 59, 10, 9, 99,100,101,108,116, 97, 32, 61, 32, 99,109, 97,120, 45, 99,109,105,110, 59, 10, 10, 9, +118, 32, 61, 32, 99,109, 97,120, 59, 10, 9,105,102, 32, 40, 99,109, 97,120, 33, 61, 48, 46, 48, 41, 10, 9, 9,115, 32, 61, 32, + 99,100,101,108,116, 97, 47, 99,109, 97,120, 59, 10, 9,101,108,115,101, 32,123, 10, 9, 9,115, 32, 61, 32, 48, 46, 48, 59, 10, + 9, 9,104, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 10, 9,105,102, 32, 40,115, 32, 61, 61, 32, 48, 46, 48, 41, 32,123, 10, + 9, 9,104, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9, 99, 32, 61, 32, 40,118,101, 99, + 51, 40, 99,109, 97,120, 44, 32, 99,109, 97,120, 44, 32, 99,109, 97,120, 41, 32, 45, 32,114,103, 98, 46,120,121,122, 41, 47, 99, +100,101,108,116, 97, 59, 10, 10, 9, 9,105,102, 32, 40,114,103, 98, 46,120, 61, 61, 99,109, 97,120, 41, 32,104, 32, 61, 32, 99, + 91, 50, 93, 32, 45, 32, 99, 91, 49, 93, 59, 10, 9, 9,101,108,115,101, 32,105,102, 32, 40,114,103, 98, 46,121, 61, 61, 99,109, + 97,120, 41, 32,104, 32, 61, 32, 50, 46, 48, 32, 43, 32, 99, 91, 48, 93, 32, 45, 32, 32, 99, 91, 50, 93, 59, 10, 9, 9,101,108, +115,101, 32,104, 32, 61, 32, 52, 46, 48, 32, 43, 32, 99, 91, 49, 93, 32, 45, 32, 99, 91, 48, 93, 59, 10, 10, 9, 9,104, 32, 47, + 61, 32, 54, 46, 48, 59, 10, 10, 9, 9,105,102, 32, 40,104, 60, 48, 46, 48, 41, 10, 9, 9, 9,104, 32, 43, 61, 32, 49, 46, 48, + 59, 10, 9,125, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32,118,101, 99, 52, 40,104, 44, 32,115, 44, 32,118, 44, 32,114,103, + 98, 46,119, 41, 59, 10,125, 10, 10,118,111,105,100, 32,104,115,118, 95,116,111, 95,114,103, 98, 40,118,101, 99, 52, 32,104,115, +118, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,105, 44, 32, +102, 44, 32,112, 44, 32,113, 44, 32,116, 44, 32,104, 44, 32,115, 44, 32,118, 59, 10, 9,118,101, 99, 51, 32,114,103, 98, 59, 10, + 10, 9,104, 32, 61, 32,104,115,118, 91, 48, 93, 59, 10, 9,115, 32, 61, 32,104,115,118, 91, 49, 93, 59, 10, 9,118, 32, 61, 32, +104,115,118, 91, 50, 93, 59, 10, 10, 9,105,102, 40,115, 61, 61, 48, 46, 48, 41, 32,123, 10, 9, 9,114,103, 98, 32, 61, 32,118, +101, 99, 51, 40,118, 44, 32,118, 44, 32,118, 41, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9,105,102, 40,104, 61, + 61, 49, 46, 48, 41, 10, 9, 9, 9,104, 32, 61, 32, 48, 46, 48, 59, 10, 9, 9, 10, 9, 9,104, 32, 42, 61, 32, 54, 46, 48, 59, + 10, 9, 9,105, 32, 61, 32,102,108,111,111,114, 40,104, 41, 59, 10, 9, 9,102, 32, 61, 32,104, 32, 45, 32,105, 59, 10, 9, 9, +114,103, 98, 32, 61, 32,118,101, 99, 51, 40,102, 44, 32,102, 44, 32,102, 41, 59, 10, 9, 9,112, 32, 61, 32,118, 42, 40, 49, 46, + 48, 45,115, 41, 59, 10, 9, 9,113, 32, 61, 32,118, 42, 40, 49, 46, 48, 45, 40,115, 42,102, 41, 41, 59, 10, 9, 9,116, 32, 61, + 32,118, 42, 40, 49, 46, 48, 45, 40,115, 42, 40, 49, 46, 48, 45,102, 41, 41, 41, 59, 10, 9, 9, 10, 9, 9,105,102, 32, 40,105, + 32, 61, 61, 32, 48, 46, 48, 41, 32,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,118, 44, 32,116, 44, 32,112, 41, 59, 10, 9, 9, +101,108,115,101, 32,105,102, 32, 40,105, 32, 61, 61, 32, 49, 46, 48, 41, 32,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,113, 44, + 32,118, 44, 32,112, 41, 59, 10, 9, 9,101,108,115,101, 32,105,102, 32, 40,105, 32, 61, 61, 32, 50, 46, 48, 41, 32,114,103, 98, + 32, 61, 32,118,101, 99, 51, 40,112, 44, 32,118, 44, 32,116, 41, 59, 10, 9, 9,101,108,115,101, 32,105,102, 32, 40,105, 32, 61, + 61, 32, 51, 46, 48, 41, 32,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,112, 44, 32,113, 44, 32,118, 41, 59, 10, 9, 9,101,108, +115,101, 32,105,102, 32, 40,105, 32, 61, 61, 32, 52, 46, 48, 41, 32,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,116, 44, 32,112, + 44, 32,118, 41, 59, 10, 9, 9,101,108,115,101, 32,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,118, 44, 32,112, 44, 32,113, 41, + 59, 10, 9,125, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32,118,101, 99, 52, 40,114,103, 98, 44, 32,104,115,118, 46,119, 41, + 59, 10,125, 10, 10,102,108,111, 97,116, 32,115,114,103, 98, 95,116,111, 95,108,105,110,101, 97,114,114,103, 98, 40,102,108,111, + 97,116, 32, 99, 41, 10,123, 10, 9,105,102, 40, 99, 32, 60, 32, 48, 46, 48, 52, 48, 52, 53, 41, 10, 9, 9,114,101,116,117,114, +110, 32, 40, 99, 32, 60, 32, 48, 46, 48, 41, 63, 32, 48, 46, 48, 58, 32, 99, 32, 42, 32, 40, 49, 46, 48, 47, 49, 50, 46, 57, 50, + 41, 59, 10, 9,101,108,115,101, 10, 9, 9,114,101,116,117,114,110, 32,112,111,119, 40, 40, 99, 32, 43, 32, 48, 46, 48, 53, 53, + 41, 42, 40, 49, 46, 48, 47, 49, 46, 48, 53, 53, 41, 44, 32, 50, 46, 52, 41, 59, 10,125, 10, 10,102,108,111, 97,116, 32,108,105, +110,101, 97,114,114,103, 98, 95,116,111, 95,115,114,103, 98, 40,102,108,111, 97,116, 32, 99, 41, 10,123, 10, 9,105,102, 40, 99, + 32, 60, 32, 48, 46, 48, 48, 51, 49, 51, 48, 56, 41, 10, 9, 9,114,101,116,117,114,110, 32, 40, 99, 32, 60, 32, 48, 46, 48, 41, + 63, 32, 48, 46, 48, 58, 32, 99, 32, 42, 32, 49, 50, 46, 57, 50, 59, 10, 9,101,108,115,101, 10, 9, 9,114,101,116,117,114,110, + 32, 49, 46, 48, 53, 53, 32, 42, 32,112,111,119, 40, 99, 44, 32, 49, 46, 48, 47, 50, 46, 52, 41, 32, 45, 32, 48, 46, 48, 53, 53, + 59, 10,125, 10, 10,118,111,105,100, 32,115,114,103, 98, 95,116,111, 95,108,105,110,101, 97,114,114,103, 98, 40,118,101, 99, 52, + 32, 99,111,108, 95,102,114,111,109, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108, 95,116,111, 41, 10,123, 10, 9, 99, +111,108, 95,116,111, 46,114, 32, 61, 32,115,114,103, 98, 95,116,111, 95,108,105,110,101, 97,114,114,103, 98, 40, 99,111,108, 95, +102,114,111,109, 46,114, 41, 59, 10, 9, 99,111,108, 95,116,111, 46,103, 32, 61, 32,115,114,103, 98, 95,116,111, 95,108,105,110, +101, 97,114,114,103, 98, 40, 99,111,108, 95,102,114,111,109, 46,103, 41, 59, 10, 9, 99,111,108, 95,116,111, 46, 98, 32, 61, 32, +115,114,103, 98, 95,116,111, 95,108,105,110,101, 97,114,114,103, 98, 40, 99,111,108, 95,102,114,111,109, 46, 98, 41, 59, 10, 9, + 99,111,108, 95,116,111, 46, 97, 32, 61, 32, 99,111,108, 95,102,114,111,109, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,108, +105,110,101, 97,114,114,103, 98, 95,116,111, 95,115,114,103, 98, 40,118,101, 99, 52, 32, 99,111,108, 95,102,114,111,109, 44, 32, +111,117,116, 32,118,101, 99, 52, 32, 99,111,108, 95,116,111, 41, 10,123, 10, 9, 99,111,108, 95,116,111, 46,114, 32, 61, 32,108, +105,110,101, 97,114,114,103, 98, 95,116,111, 95,115,114,103, 98, 40, 99,111,108, 95,102,114,111,109, 46,114, 41, 59, 10, 9, 99, +111,108, 95,116,111, 46,103, 32, 61, 32,108,105,110,101, 97,114,114,103, 98, 95,116,111, 95,115,114,103, 98, 40, 99,111,108, 95, +102,114,111,109, 46,103, 41, 59, 10, 9, 99,111,108, 95,116,111, 46, 98, 32, 61, 32,108,105,110,101, 97,114,114,103, 98, 95,116, +111, 95,115,114,103, 98, 40, 99,111,108, 95,102,114,111,109, 46, 98, 41, 59, 10, 9, 99,111,108, 95,116,111, 46, 97, 32, 61, 32, + 99,111,108, 95,102,114,111,109, 46, 97, 59, 10,125, 10, 10, 35,100,101,102,105,110,101, 32, 77, 95, 80, 73, 32, 51, 46, 49, 52, + 49, 53, 57, 50, 54, 53, 51, 53, 56, 57, 55, 57, 51, 50, 51, 56, 52, 54, 10, 35,100,101,102,105,110,101, 32, 77, 95, 49, 95, 80, + 73, 32, 48, 46, 51, 49, 56, 51, 48, 57, 56, 56, 54, 49, 56, 51, 55, 57, 48, 54, 57, 10, 10, 47, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 32, 83, 72, 65, 68, 69, 82, 32, 78, 79, 68, 69, 83, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 47, 10, 10,118,111,105,100, 32,118, 99,111,108, 95, 97,116,116,114,105, 98,117,116,101, 40,118,101, 99, 52, 32, 97,116,116,118, + 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,118, 99,111,108, 41, 10,123, 10, 9,118, 99,111,108, 32, 61, 32,118,101, + 99, 52, 40, 97,116,116,118, 99,111,108, 46,120, 47, 50, 53, 53, 46, 48, 44, 32, 97,116,116,118, 99,111,108, 46,121, 47, 50, 53, + 53, 46, 48, 44, 32, 97,116,116,118, 99,111,108, 46,122, 47, 50, 53, 53, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10,125, 10, 10,118, +111,105,100, 32,117,118, 95, 97,116,116,114,105, 98,117,116,101, 40,118,101, 99, 50, 32, 97,116,116,117,118, 44, 32,111,117,116, + 32,118,101, 99, 51, 32,117,118, 41, 10,123, 10, 9,117,118, 32, 61, 32,118,101, 99, 51, 40, 97,116,116,117,118, 42, 50, 46, 48, + 32, 45, 32,118,101, 99, 50, 40, 49, 46, 48, 44, 32, 49, 46, 48, 41, 44, 32, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, + 32,103,101,111,109, 40,118,101, 99, 51, 32, 99,111, 44, 32,118,101, 99, 51, 32,110,111,114, 44, 32,109, 97,116, 52, 32,118,105, +101,119,105,110,118,109, 97,116, 44, 32,118,101, 99, 51, 32, 97,116,116,111,114, 99,111, 44, 32,118,101, 99, 50, 32, 97,116,116, +117,118, 44, 32,118,101, 99, 52, 32, 97,116,116,118, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,103,108,111, 98, 97, +108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,108,111, 99, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118,105,101,119, + 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,114, 99,111, 44, 32,111,117,116, 32,118,101, 99, 51, 32,117,118, 44, 32,111,117, +116, 32,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,118, 99,111,108, 44, 32,111,117, +116, 32,102,108,111, 97,116, 32,118, 99,111,108, 95, 97,108,112,104, 97, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102,114, +111,110,116, 98, 97, 99,107, 41, 10,123, 10, 9,108,111, 99, 97,108, 32, 61, 32, 99,111, 59, 10, 9,118,105,101,119, 32, 61, 32, +110,111,114,109, 97,108,105,122,101, 40,108,111, 99, 97,108, 41, 59, 10, 9,103,108,111, 98, 97,108, 32, 61, 32, 40,118,105,101, +119,105,110,118,109, 97,116, 42,118,101, 99, 52, 40,108,111, 99, 97,108, 44, 32, 49, 46, 48, 41, 41, 46,120,121,122, 59, 10, 9, +111,114, 99,111, 32, 61, 32, 97,116,116,111,114, 99,111, 59, 10, 9,117,118, 95, 97,116,116,114,105, 98,117,116,101, 40, 97,116, +116,117,118, 44, 32,117,118, 41, 59, 10, 9,110,111,114,109, 97,108, 32, 61, 32, 45,110,111,114,109, 97,108,105,122,101, 40,110, +111,114, 41, 59, 9, 47, 42, 32, 98,108,101,110,100,101,114, 32,114,101,110,100,101,114, 32,110,111,114,109, 97,108, 32,105,115, + 32,110,101,103, 97,116,101,100, 32, 42, 47, 10, 9,118, 99,111,108, 95, 97,116,116,114,105, 98,117,116,101, 40, 97,116,116,118, + 99,111,108, 44, 32,118, 99,111,108, 41, 59, 10, 9,118, 99,111,108, 95, 97,108,112,104, 97, 32, 61, 32, 97,116,116,118, 99,111, +108, 46, 97, 59, 10, 9,102,114,111,110,116, 98, 97, 99,107, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109, + 97,112,112,105,110,103, 40,118,101, 99, 51, 32,118,101, 99, 44, 32,109, 97,116, 52, 32,109, 97,116, 44, 32,118,101, 99, 51, 32, +109,105,110,118,101, 99, 44, 32,118,101, 99, 51, 32,109, 97,120,118,101, 99, 44, 32,102,108,111, 97,116, 32,100,111,109,105,110, + 44, 32,102,108,111, 97,116, 32,100,111,109, 97,120, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 41, 10, +123, 10, 9,111,117,116,118,101, 99, 32, 61, 32, 40,109, 97,116, 32, 42, 32,118,101, 99, 52, 40,118,101, 99, 44, 32, 49, 46, 48, + 41, 41, 46,120,121,122, 59, 10, 9,105,102, 40,100,111,109,105,110, 32, 61, 61, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116,118, +101, 99, 32, 61, 32,109, 97,120, 40,111,117,116,118,101, 99, 44, 32,109,105,110,118,101, 99, 41, 59, 10, 9,105,102, 40,100,111, +109, 97,120, 32, 61, 61, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116,118,101, 99, 32, 61, 32,109,105,110, 40,111,117,116,118,101, + 99, 44, 32,109, 97,120,118,101, 99, 41, 59, 10,125, 10, 10,118,111,105,100, 32, 99, 97,109,101,114, 97, 40,118,101, 99, 51, 32, + 99,111, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,105,101,119, 44, 32,111,117,116, 32,102,108,111, 97,116, 32, +111,117,116,100,101,112,116,104, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,100,105,115,116, 41, 10,123, 10, 9, +111,117,116,100,101,112,116,104, 32, 61, 32, 97, 98,115, 40, 99,111, 46,122, 41, 59, 10, 9,111,117,116,100,105,115,116, 32, 61, + 32,108,101,110,103,116,104, 40, 99,111, 41, 59, 10, 9,111,117,116,118,105,101,119, 32, 61, 32,110,111,114,109, 97,108,105,122, +101, 40, 99,111, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95, 97,100,100, 40,102,108,111, 97,116, 32,118, 97, +108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, + 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118, 97,108, 49, 32, 43, 32,118, 97,108, 50, 59, 10,125, 10, 10,118,111, +105,100, 32,109, 97,116,104, 95,115,117, 98,116,114, 97, 99,116, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, + 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117, +116,118, 97,108, 32, 61, 32,118, 97,108, 49, 32, 45, 32,118, 97,108, 50, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, + 95,109,117,108,116,105,112,108,121, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, + 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, +118, 97,108, 49, 32, 42, 32,118, 97,108, 50, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,100,105,118,105,100,101, + 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, + 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,105,102, 32, 40,118, 97,108, 50, 32, 61, 61, 32, 48, 46, 48, 41, 10, 9, + 9,111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, +118, 97,108, 49, 32, 47, 32,118, 97,108, 50, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,115,105,110,101, 40,102, +108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111, +117,116,118, 97,108, 32, 61, 32,115,105,110, 40,118, 97,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95, 99, +111,115,105,110,101, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97, +108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 99,111,115, 40,118, 97,108, 41, 59, 10,125, 10, 10,118,111,105,100, + 32,109, 97,116,104, 95,116, 97,110,103,101,110,116, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, + 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,116, 97,110, 40,118, 97,108, 41, 59, + 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95, 97,115,105,110, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117, +116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,105,102, 32, 40,118, 97,108, 32, 60, 61, 32, 49, 46, + 48, 32, 38, 38, 32,118, 97,108, 32, 62, 61, 32, 45, 49, 46, 48, 41, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 97,115,105, +110, 40,118, 97,108, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, + 10,118,111,105,100, 32,109, 97,116,104, 95, 97, 99,111,115, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102, +108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,105,102, 32, 40,118, 97,108, 32, 60, 61, 32, 49, 46, 48, 32, 38, + 38, 32,118, 97,108, 32, 62, 61, 32, 45, 49, 46, 48, 41, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 97, 99,111,115, 40,118, + 97,108, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111, +105,100, 32,109, 97,116,104, 95, 97,116, 97,110, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97, +116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 97,116, 97,110, 40,118, 97,108, 41, 59, + 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,112,111,119, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108, +111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,105, +102, 32, 40,118, 97,108, 49, 32, 62, 61, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32,112,111,119, 40,118, + 97,108, 49, 44, 32,118, 97,108, 50, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, + 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,108,111,103, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102, 108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9, -105,102, 32, 40,118, 97,108, 49, 32, 62, 61, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32,112,111,119, 40, -118, 97,108, 49, 44, 32,118, 97,108, 50, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 48, 46, - 48, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,108,111,103, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32, -102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, - 9,105,102, 40,118, 97,108, 49, 32, 62, 32, 48, 46, 48, 32, 32, 38, 38, 32,118, 97,108, 50, 32, 62, 32, 48, 46, 48, 41, 10, 9, - 9,111,117,116,118, 97,108, 61, 32,108,111,103, 50, 40,118, 97,108, 49, 41, 32, 47, 32,108,111,103, 50, 40,118, 97,108, 50, 41, - 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,118, 97,108, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109, - 97,116,104, 95,109, 97,120, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32, -111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,109, 97, -120, 40,118, 97,108, 49, 44, 32,118, 97,108, 50, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,109,105,110, 40, -102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97, -116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,109,105,110, 40,118, 97,108, 49, 44, 32, -118, 97,108, 50, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,114,111,117,110,100, 40,102,108,111, 97,116, 32, -118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, - 61, 32,102,108,111,111,114, 40,118, 97,108, 32, 43, 32, 48, 46, 53, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, - 95,108,101,115,115, 95,116,104, 97,110, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, - 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,105,102, 40,118, 97,108, 49, 32, - 60, 32,118, 97,108, 50, 41, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 10, 9, 9, -111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,103,114,101, 97,116, -101,114, 95,116,104, 97,110, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32, -111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,105,102, 40,118, 97,108, 49, 32, 62, 32,118, - 97,108, 50, 41, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, -118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,115,113,117,101,101,122,101, 40,102,108,111, 97,116, - 32,118, 97,108, 44, 32,102,108,111, 97,116, 32,119,105,100,116,104, 44, 32,102,108,111, 97,116, 32, 99,101,110,116,101,114, 44, - 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 49, - 46, 48, 47, 40, 49, 46, 48, 32, 43, 32,112,111,119, 40, 50, 46, 55, 49, 56, 50, 56, 49, 56, 51, 44, 32, 45, 40, 40,118, 97,108, - 45, 99,101,110,116,101,114, 41, 42,119,105,100,116,104, 41, 41, 41, 59, 10,125, 10, 10,118,111,105,100, 32,118,101, 99, 95,109, - 97,116,104, 95, 97,100,100, 40,118,101, 99, 51, 32,118, 49, 44, 32,118,101, 99, 51, 32,118, 50, 44, 32,111,117,116, 32,118,101, +105,102, 40,118, 97,108, 49, 32, 62, 32, 48, 46, 48, 32, 32, 38, 38, 32,118, 97,108, 50, 32, 62, 32, 48, 46, 48, 41, 10, 9, 9, +111,117,116,118, 97,108, 61, 32,108,111,103, 50, 40,118, 97,108, 49, 41, 32, 47, 32,108,111,103, 50, 40,118, 97,108, 50, 41, 59, + 10, 9,101,108,115,101, 10, 9, 9,111,117,116,118, 97,108, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97, +116,104, 95,109, 97,120, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111, +117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,109, 97,120, + 40,118, 97,108, 49, 44, 32,118, 97,108, 50, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,109,105,110, 40,102, +108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, + 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,109,105,110, 40,118, 97,108, 49, 44, 32,118, + 97,108, 50, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,114,111,117,110,100, 40,102,108,111, 97,116, 32,118, + 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 61, + 32,102,108,111,111,114, 40,118, 97,108, 32, 43, 32, 48, 46, 53, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95, +108,101,115,115, 95,116,104, 97,110, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, + 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,105,102, 40,118, 97,108, 49, 32, 60, + 32,118, 97,108, 50, 41, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 10, 9, 9,111, +117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,103,114,101, 97,116,101, +114, 95,116,104, 97,110, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111, +117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,105,102, 40,118, 97,108, 49, 32, 62, 32,118, 97, +108, 50, 41, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,118, + 97,108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,115,113,117,101,101,122,101, 40,102,108,111, 97,116, 32, +118, 97,108, 44, 32,102,108,111, 97,116, 32,119,105,100,116,104, 44, 32,102,108,111, 97,116, 32, 99,101,110,116,101,114, 44, 32, +111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 49, 46, + 48, 47, 40, 49, 46, 48, 32, 43, 32,112,111,119, 40, 50, 46, 55, 49, 56, 50, 56, 49, 56, 51, 44, 32, 45, 40, 40,118, 97,108, 45, + 99,101,110,116,101,114, 41, 42,119,105,100,116,104, 41, 41, 41, 59, 10,125, 10, 10,118,111,105,100, 32,118,101, 99, 95,109, 97, +116,104, 95, 97,100,100, 40,118,101, 99, 51, 32,118, 49, 44, 32,118,101, 99, 51, 32,118, 50, 44, 32,111,117,116, 32,118,101, 99, + 51, 32,111,117,116,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111, +117,116,118,101, 99, 32, 61, 32,118, 49, 32, 43, 32,118, 50, 59, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 40, 97, 98,115, 40, +111,117,116,118,101, 99, 91, 48, 93, 41, 32, 43, 32, 97, 98,115, 40,111,117,116,118,101, 99, 91, 49, 93, 41, 32, 43, 32, 97, 98, +115, 40,111,117,116,118,101, 99, 91, 50, 93, 41, 41, 47, 51, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,118,101, 99, 95,109, + 97,116,104, 95,115,117, 98, 40,118,101, 99, 51, 32,118, 49, 44, 32,118,101, 99, 51, 32,118, 50, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9, -111,117,116,118,101, 99, 32, 61, 32,118, 49, 32, 43, 32,118, 50, 59, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 40, 97, 98,115, +111,117,116,118,101, 99, 32, 61, 32,118, 49, 32, 45, 32,118, 50, 59, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 40, 97, 98,115, 40,111,117,116,118,101, 99, 91, 48, 93, 41, 32, 43, 32, 97, 98,115, 40,111,117,116,118,101, 99, 91, 49, 93, 41, 32, 43, 32, 97, 98,115, 40,111,117,116,118,101, 99, 91, 50, 93, 41, 41, 47, 51, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,118,101, 99, 95, -109, 97,116,104, 95,115,117, 98, 40,118,101, 99, 51, 32,118, 49, 44, 32,118,101, 99, 51, 32,118, 50, 44, 32,111,117,116, 32,118, -101, 99, 51, 32,111,117,116,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, - 9,111,117,116,118,101, 99, 32, 61, 32,118, 49, 32, 45, 32,118, 50, 59, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 40, 97, 98, -115, 40,111,117,116,118,101, 99, 91, 48, 93, 41, 32, 43, 32, 97, 98,115, 40,111,117,116,118,101, 99, 91, 49, 93, 41, 32, 43, 32, - 97, 98,115, 40,111,117,116,118,101, 99, 91, 50, 93, 41, 41, 47, 51, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,118,101, 99, - 95,109, 97,116,104, 95, 97,118,101,114, 97,103,101, 40,118,101, 99, 51, 32,118, 49, 44, 32,118,101, 99, 51, 32,118, 50, 44, 32, -111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97, -108, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32,118, 49, 32, 43, 32,118, 50, 59, 10, 9,111,117,116,118, 97,108, 32, - 61, 32,108,101,110,103,116,104, 40,111,117,116,118,101, 99, 41, 59, 10, 9,111,117,116,118,101, 99, 32, 61, 32,110,111,114,109, - 97,108,105,122,101, 40,111,117,116,118,101, 99, 41, 59, 10,125, 10, 10,118,111,105,100, 32,118,101, 99, 95,109, 97,116,104, 95, -100,111,116, 40,118,101, 99, 51, 32,118, 49, 44, 32,118,101, 99, 51, 32,118, 50, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111, -117,116,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, -101, 99, 32, 61, 32,118,101, 99, 51, 40, 48, 44, 32, 48, 44, 32, 48, 41, 59, 10, 9,111,117,116,118, 97,108, 32, 61, 32,100,111, -116, 40,118, 49, 44, 32,118, 50, 41, 59, 10,125, 10, 10,118,111,105,100, 32,118,101, 99, 95,109, 97,116,104, 95, 99,114,111,115, -115, 40,118,101, 99, 51, 32,118, 49, 44, 32,118,101, 99, 51, 32,118, 50, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116, -118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118,101, 99, - 32, 61, 32, 99,114,111,115,115, 40,118, 49, 44, 32,118, 50, 41, 59, 10, 9,111,117,116,118, 97,108, 32, 61, 32,108,101,110,103, -116,104, 40,111,117,116,118,101, 99, 41, 59, 10,125, 10, 10,118,111,105,100, 32,118,101, 99, 95,109, 97,116,104, 95,110,111,114, -109, 97,108,105,122,101, 40,118,101, 99, 51, 32,118, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 44, 32, -111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,108,101, -110,103,116,104, 40,118, 41, 59, 10, 9,111,117,116,118,101, 99, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,118, 41, 59, - 10,125, 10, 10,118,111,105,100, 32,118,101, 99, 95,109, 97,116,104, 95,110,101,103, 97,116,101, 40,118,101, 99, 51, 32,118, 44, - 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118, 41, 10,123, 10, 9,111,117,116,118, 32, 61, 32, 45,118, 59, 10,125, 10, - 10,118,111,105,100, 32,110,111,114,109, 97,108, 40,118,101, 99, 51, 32,100,105,114, 44, 32,118,101, 99, 51, 32,110,111,114, 44, - 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,110,111,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,100, -111,116, 41, 10,123, 10, 9,111,117,116,110,111,114, 32, 61, 32,100,105,114, 59, 10, 9,111,117,116,100,111,116, 32, 61, 32, 45, -100,111,116, 40,100,105,114, 44, 32,110,111,114, 41, 59, 10,125, 10, 10,118,111,105,100, 32, 99,117,114,118,101,115, 95,118,101, - 99, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 51, 32,118,101, 99, 44, 32,115, 97,109,112,108,101,114, 50, 68, - 32, 99,117,114,118,101,109, 97,112, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 41, 10,123, 10, 9,111, -117,116,118,101, 99, 46,120, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, - 99, 50, 40, 40,118,101, 99, 46,120, 32, 43, 32, 49, 46, 48, 41, 42, 48, 46, 53, 44, 32, 48, 46, 48, 41, 41, 46,120, 59, 10, 9, -111,117,116,118,101, 99, 46,121, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118, -101, 99, 50, 40, 40,118,101, 99, 46,121, 32, 43, 32, 49, 46, 48, 41, 42, 48, 46, 53, 44, 32, 48, 46, 48, 41, 41, 46,121, 59, 10, - 9,111,117,116,118,101, 99, 46,122, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32, -118,101, 99, 50, 40, 40,118,101, 99, 46,122, 32, 43, 32, 49, 46, 48, 41, 42, 48, 46, 53, 44, 32, 48, 46, 48, 41, 41, 46,122, 59, - 10, 10, 9,105,102, 32, 40,102, 97, 99, 32, 33, 61, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116,118,101, 99, 32, 61, 32, 40,111, -117,116,118,101, 99, 42,102, 97, 99, 41, 32, 43, 32, 40,118,101, 99, 42, 40, 49, 46, 48, 45,102, 97, 99, 41, 41, 59, 10, 10,125, - 10, 10,118,111,105,100, 32, 99,117,114,118,101,115, 95,114,103, 98, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, - 52, 32, 99,111,108, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32, 99,117,114,118,101,109, 97,112, 44, 32,111,117,116, 32,118, -101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32,116,101,120,116,117,114, -101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, 50, 40,116,101,120,116,117,114,101, 50, 68, 40, 99,117,114, -118,101,109, 97,112, 44, 32,118,101, 99, 50, 40, 99,111,108, 46,114, 44, 32, 48, 46, 48, 41, 41, 46, 97, 44, 32, 48, 46, 48, 41, - 41, 46,114, 59, 10, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40, 99,117,114,118,101, -109, 97,112, 44, 32,118,101, 99, 50, 40,116,101,120,116,117,114,101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, - 99, 50, 40, 99,111,108, 46,103, 44, 32, 48, 46, 48, 41, 41, 46, 97, 44, 32, 48, 46, 48, 41, 41, 46,103, 59, 10, 9,111,117,116, - 99,111,108, 46, 98, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, 50, - 40,116,101,120,116,117,114,101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, 50, 40, 99,111,108, 46, 98, 44, - 32, 48, 46, 48, 41, 41, 46, 97, 44, 32, 48, 46, 48, 41, 41, 46, 98, 59, 10, 10, 9,105,102, 32, 40,102, 97, 99, 32, 33, 61, 32, - 49, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 32, 61, 32, 40,111,117,116, 99,111,108, 42,102, 97, 99, 41, 32, 43, 32, 40, - 99,111,108, 42, 40, 49, 46, 48, 45,102, 97, 99, 41, 41, 59, 10, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, - 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,116, 95,118, 97,108,117,101, 40,102,108,111, 97,116, 32,118, 97,108, 44, - 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118, - 97,108, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,116, 95,114,103, 98, 40,118,101, 99, 51, 32, 99,111,108, 44, 32,111,117, -116, 32,118,101, 99, 51, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 59, 10, -125, 10, 10,118,111,105,100, 32,115,101,116, 95,114,103, 98, 97, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,118, -101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 59, 10,125, 10, 10, -118,111,105,100, 32,115,101,116, 95,118, 97,108,117,101, 95,122,101,114,111, 40,111,117,116, 32,102,108,111, 97,116, 32,111,117, -116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,115, -101,116, 95,118, 97,108,117,101, 95,111,110,101, 40,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, - 10, 9,111,117,116,118, 97,108, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,116, 95,114,103, 98, 95, -122,101,114,111, 40,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, - 61, 32,118,101, 99, 51, 40, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,116, 95,114,103, 98, 97, 95,122,101, -114,111, 40,111,117,116, 32,118,101, 99, 52, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, -118,101, 99, 52, 40, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32, 99,111,112,121, 95,114, 97,119, 40,118,101, 99, 52, - 32,118, 97,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, - 32, 61, 32,118, 97,108, 59, 10,125, 10, 10,118,111,105,100, 32, 99,111,112,121, 95,114, 97,119, 40,118,101, 99, 51, 32,118, 97, -108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, -118, 97,108, 59, 10,125, 10, 10,118,111,105,100, 32, 99,111,112,121, 95,114, 97,119, 40,118,101, 99, 50, 32,118, 97,108, 44, 32, -111,117,116, 32,118,101, 99, 50, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118, 97,108, - 59, 10,125, 10, 10,118,111,105,100, 32, 99,111,112,121, 95,114, 97,119, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117, -116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118, 97,108, 59, - 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95, 98,108,101,110,100, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, - 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, - 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, - 48, 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40, 99,111,108, 49, 44, 32, 99,111,108, 50, 44, 32,102, 97, - 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32, -109,105,120, 95, 97,100,100, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, - 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, - 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, - 32, 61, 32,109,105,120, 40, 99,111,108, 49, 44, 32, 99,111,108, 49, 32, 43, 32, 99,111,108, 50, 44, 32,102, 97, 99, 41, 59, 10, - 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95, -109,117,108,116, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, - 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, - 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, 32, -109,105,120, 40, 99,111,108, 49, 44, 32, 99,111,108, 49, 32, 42, 32, 99,111,108, 50, 44, 32,102, 97, 99, 41, 59, 10, 9,111,117, -116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,115, 99,114, -101,101,110, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99, -111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99, -108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, - 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32,118,101, 99, 52, 40, 49, 46, - 48, 41, 32, 45, 32, 40,118,101, 99, 52, 40,102, 97, 99,109, 41, 32, 43, 32,102, 97, 99, 42, 40,118,101, 99, 52, 40, 49, 46, 48, - 41, 32, 45, 32, 99,111,108, 50, 41, 41, 42, 40,118,101, 99, 52, 40, 49, 46, 48, 41, 32, 45, 32, 99,111,108, 49, 41, 59, 10, 9, -111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,111, -118,101,114,108, 97,121, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, - 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, - 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, - 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, - 59, 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46,114, 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,111,117,116, 99,111,108, 46, -114, 32, 42, 61, 32,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99, 42, 99,111,108, 50, 46,114, 59, 10, 9,101,108,115, -101, 10, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, - 42,102, 97, 99, 42, 40, 49, 46, 48, 32, 45, 32, 99,111,108, 50, 46,114, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99, -111,108, 46,114, 41, 59, 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46,103, 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,111,117, -116, 99,111,108, 46,103, 32, 42, 61, 32,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99, 42, 99,111,108, 50, 46,103, 59, - 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, - 43, 32, 50, 46, 48, 42,102, 97, 99, 42, 40, 49, 46, 48, 32, 45, 32, 99,111,108, 50, 46,103, 41, 41, 42, 40, 49, 46, 48, 32, 45, - 32,111,117,116, 99,111,108, 46,103, 41, 59, 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46, 98, 32, 60, 32, 48, 46, 53, 41, - 10, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 42, 61, 32,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99, 42, 99,111, -108, 50, 46, 98, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40, -102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99, 42, 40, 49, 46, 48, 32, 45, 32, 99,111,108, 50, 46, 98, 41, 41, 42, 40, - 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46, 98, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,115,117, 98, - 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, - 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109, -112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40, - 99,111,108, 49, 44, 32, 99,111,108, 49, 32, 45, 32, 99,111,108, 50, 44, 32,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, - 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,100,105,118, 40,102,108,111, - 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117, -116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, - 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, - 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,105,102, 40, 99,111,108, - 50, 46,114, 32, 33, 61, 32, 48, 46, 48, 41, 32,111,117,116, 99,111,108, 46,114, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99, -111,108, 46,114, 32, 43, 32,102, 97, 99, 42,111,117,116, 99,111,108, 46,114, 47, 99,111,108, 50, 46,114, 59, 10, 9,105,102, 40, - 99,111,108, 50, 46,103, 32, 33, 61, 32, 48, 46, 48, 41, 32,111,117,116, 99,111,108, 46,103, 32, 61, 32,102, 97, 99,109, 42,111, -117,116, 99,111,108, 46,103, 32, 43, 32,102, 97, 99, 42,111,117,116, 99,111,108, 46,103, 47, 99,111,108, 50, 46,103, 59, 10, 9, -105,102, 40, 99,111,108, 50, 46, 98, 32, 33, 61, 32, 48, 46, 48, 41, 32,111,117,116, 99,111,108, 46, 98, 32, 61, 32,102, 97, 99, -109, 42,111,117,116, 99,111,108, 46, 98, 32, 43, 32,102, 97, 99, 42,111,117,116, 99,111,108, 46, 98, 47, 99,111,108, 50, 46, 98, - 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,100,105,102,102, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, - 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, - 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, - 48, 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40, 99,111,108, 49, 44, 32, 97, 98,115, 40, 99,111,108, 49, - 32, 45, 32, 99,111,108, 50, 41, 44, 32,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, - 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,100, 97,114,107, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32, -118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111, -117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, - 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 46,114,103, 98, 32, 61, 32,109,105,110, 40, 99,111,108, 49, 46,114,103, 98, - 44, 32, 99,111,108, 50, 46,114,103, 98, 42,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, - 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,108,105,103,104,116, 40,102,108,111, 97,116, 32,102, 97, 99, - 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, - 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, - 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 46,114,103, 98, 32, 61, 32,109, 97,120, 40, 99,111,108, 49, 46,114, -103, 98, 44, 32, 99,111,108, 50, 46,114,103, 98, 42,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99, -111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,100,111,100,103,101, 40,102,108,111, 97,116, 32,102, - 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, - 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, - 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,105,102, 40,111, -117,116, 99,111,108, 46,114, 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,102,108,111, 97,116, 32,116,109,112, 32, 61, 32, - 49, 46, 48, 32, 45, 32,102, 97, 99, 42, 99,111,108, 50, 46,114, 59, 10, 9, 9,105,102, 40,116,109,112, 32, 60, 61, 32, 48, 46, - 48, 41, 10, 9, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9,101,108,115,101, 32,105,102, 40, - 40,116,109,112, 32, 61, 32,111,117,116, 99,111,108, 46,114, 47,116,109,112, 41, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9, 9,111, -117,116, 99,111,108, 46,114, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9,101,108,115,101, 10, 9, 9, 9,111,117,116, 99,111,108, 46, -114, 32, 61, 32,116,109,112, 59, 10, 9,125, 10, 9,105,102, 40,111,117,116, 99,111,108, 46,103, 32, 33, 61, 32, 48, 46, 48, 41, - 32,123, 10, 9, 9,102,108,111, 97,116, 32,116,109,112, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 42, 99,111,108, 50, 46, -103, 59, 10, 9, 9,105,102, 40,116,109,112, 32, 60, 61, 32, 48, 46, 48, 41, 10, 9, 9, 9,111,117,116, 99,111,108, 46,103, 32, - 61, 32, 49, 46, 48, 59, 10, 9, 9,101,108,115,101, 32,105,102, 40, 40,116,109,112, 32, 61, 32,111,117,116, 99,111,108, 46,103, - 47,116,109,112, 41, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32, 49, 46, 48, 59, 10, - 9, 9,101,108,115,101, 10, 9, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32,116,109,112, 59, 10, 9,125, 10, 9,105,102, - 40,111,117,116, 99,111,108, 46, 98, 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,102,108,111, 97,116, 32,116,109,112, 32, - 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 42, 99,111,108, 50, 46, 98, 59, 10, 9, 9,105,102, 40,116,109,112, 32, 60, 61, 32, - 48, 46, 48, 41, 10, 9, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9,101,108,115,101, 32,105, -102, 40, 40,116,109,112, 32, 61, 32,111,117,116, 99,111,108, 46, 98, 47,116,109,112, 41, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9, - 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9,101,108,115,101, 10, 9, 9, 9,111,117,116, 99,111, -108, 46, 98, 32, 61, 32,116,109,112, 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95, 98,117,114,110, 40,102, -108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32, -111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40, -102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,116,109,112, 44, 32,102, 97, 99,109, - 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, - 9,116,109,112, 32, 61, 32,102, 97, 99,109, 32, 43, 32,102, 97, 99, 42, 99,111,108, 50, 46,114, 59, 10, 9,105,102, 40,116,109, -112, 32, 60, 61, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115, -101, 32,105,102, 40, 40,116,109,112, 32, 61, 32, 40, 49, 46, 48, 32, 45, 32, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, - 46,114, 41, 47,116,109,112, 41, 41, 32, 60, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32, 48, 46, - 48, 59, 10, 9,101,108,115,101, 32,105,102, 40,116,109,112, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46, -114, 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32,116,109,112, 59, - 10, 10, 9,116,109,112, 32, 61, 32,102, 97, 99,109, 32, 43, 32,102, 97, 99, 42, 99,111,108, 50, 46,103, 59, 10, 9,105,102, 40, -116,109,112, 32, 60, 61, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32, 48, 46, 48, 59, 10, 9,101, -108,115,101, 32,105,102, 40, 40,116,109,112, 32, 61, 32, 40, 49, 46, 48, 32, 45, 32, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99, -111,108, 46,103, 41, 47,116,109,112, 41, 41, 32, 60, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32, - 48, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40,116,109,112, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116, 99,111, -108, 46,103, 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32,116,109, -112, 59, 10, 10, 9,116,109,112, 32, 61, 32,102, 97, 99,109, 32, 43, 32,102, 97, 99, 42, 99,111,108, 50, 46, 98, 59, 10, 9,105, -102, 40,116,109,112, 32, 60, 61, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32, 48, 46, 48, 59, 10, - 9,101,108,115,101, 32,105,102, 40, 40,116,109,112, 32, 61, 32, 40, 49, 46, 48, 32, 45, 32, 40, 49, 46, 48, 32, 45, 32,111,117, -116, 99,111,108, 46, 98, 41, 47,116,109,112, 41, 41, 32, 60, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 32, - 61, 32, 48, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40,116,109,112, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116, - 99,111,108, 46, 98, 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32, -116,109,112, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,104,117,101, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32, -118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111, -117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, - 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, - 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,118,101, 99, 52, 32,104,115,118, 44, 32,104,115,118, 50, - 44, 32,116,109,112, 59, 10, 9,114,103, 98, 95,116,111, 95,104,115,118, 40, 99,111,108, 50, 44, 32,104,115,118, 50, 41, 59, 10, - 10, 9,105,102, 40,104,115,118, 50, 46,121, 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,114,103, 98, 95,116,111, 95,104, -115,118, 40,111,117,116, 99,111,108, 44, 32,104,115,118, 41, 59, 10, 9, 9,104,115,118, 46,120, 32, 61, 32,104,115,118, 50, 46, -120, 59, 10, 9, 9,104,115,118, 95,116,111, 95,114,103, 98, 40,104,115,118, 44, 32,116,109,112, 41, 59, 32, 10, 10, 9, 9,111, -117,116, 99,111,108, 32, 61, 32,109,105,120, 40,111,117,116, 99,111,108, 44, 32,116,109,112, 44, 32,102, 97, 99, 41, 59, 10, 9, - 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,109, -105,120, 95,115, 97,116, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, +109, 97,116,104, 95, 97,118,101,114, 97,103,101, 40,118,101, 99, 51, 32,118, 49, 44, 32,118,101, 99, 51, 32,118, 50, 44, 32,111, +117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, + 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32,118, 49, 32, 43, 32,118, 50, 59, 10, 9,111,117,116,118, 97,108, 32, 61, + 32,108,101,110,103,116,104, 40,111,117,116,118,101, 99, 41, 59, 10, 9,111,117,116,118,101, 99, 32, 61, 32,110,111,114,109, 97, +108,105,122,101, 40,111,117,116,118,101, 99, 41, 59, 10,125, 10, 10,118,111,105,100, 32,118,101, 99, 95,109, 97,116,104, 95,100, +111,116, 40,118,101, 99, 51, 32,118, 49, 44, 32,118,101, 99, 51, 32,118, 50, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117, +116,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118,101, + 99, 32, 61, 32,118,101, 99, 51, 40, 48, 44, 32, 48, 44, 32, 48, 41, 59, 10, 9,111,117,116,118, 97,108, 32, 61, 32,100,111,116, + 40,118, 49, 44, 32,118, 50, 41, 59, 10,125, 10, 10,118,111,105,100, 32,118,101, 99, 95,109, 97,116,104, 95, 99,114,111,115,115, + 40,118,101, 99, 51, 32,118, 49, 44, 32,118,101, 99, 51, 32,118, 50, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118, +101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, + 61, 32, 99,114,111,115,115, 40,118, 49, 44, 32,118, 50, 41, 59, 10, 9,111,117,116,118, 97,108, 32, 61, 32,108,101,110,103,116, +104, 40,111,117,116,118,101, 99, 41, 59, 10,125, 10, 10,118,111,105,100, 32,118,101, 99, 95,109, 97,116,104, 95,110,111,114,109, + 97,108,105,122,101, 40,118,101, 99, 51, 32,118, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 44, 32,111, +117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,108,101,110, +103,116,104, 40,118, 41, 59, 10, 9,111,117,116,118,101, 99, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,118, 41, 59, 10, +125, 10, 10,118,111,105,100, 32,118,101, 99, 95,109, 97,116,104, 95,110,101,103, 97,116,101, 40,118,101, 99, 51, 32,118, 44, 32, +111,117,116, 32,118,101, 99, 51, 32,111,117,116,118, 41, 10,123, 10, 9,111,117,116,118, 32, 61, 32, 45,118, 59, 10,125, 10, 10, +118,111,105,100, 32,110,111,114,109, 97,108, 40,118,101, 99, 51, 32,100,105,114, 44, 32,118,101, 99, 51, 32,110,111,114, 44, 32, +111,117,116, 32,118,101, 99, 51, 32,111,117,116,110,111,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,100,111, +116, 41, 10,123, 10, 9,111,117,116,110,111,114, 32, 61, 32,110,111,114, 59, 10, 9,111,117,116,100,111,116, 32, 61, 32, 45,100, +111,116, 40,100,105,114, 44, 32,110,111,114, 41, 59, 10,125, 10, 10,118,111,105,100, 32, 99,117,114,118,101,115, 95,118,101, 99, + 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 51, 32,118,101, 99, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32, + 99,117,114,118,101,109, 97,112, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 41, 10,123, 10, 9,111,117, +116,118,101, 99, 46,120, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, + 50, 40, 40,118,101, 99, 46,120, 32, 43, 32, 49, 46, 48, 41, 42, 48, 46, 53, 44, 32, 48, 46, 48, 41, 41, 46,120, 59, 10, 9,111, +117,116,118,101, 99, 46,121, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, + 99, 50, 40, 40,118,101, 99, 46,121, 32, 43, 32, 49, 46, 48, 41, 42, 48, 46, 53, 44, 32, 48, 46, 48, 41, 41, 46,121, 59, 10, 9, +111,117,116,118,101, 99, 46,122, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118, +101, 99, 50, 40, 40,118,101, 99, 46,122, 32, 43, 32, 49, 46, 48, 41, 42, 48, 46, 53, 44, 32, 48, 46, 48, 41, 41, 46,122, 59, 10, + 10, 9,105,102, 32, 40,102, 97, 99, 32, 33, 61, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116,118,101, 99, 32, 61, 32, 40,111,117, +116,118,101, 99, 42,102, 97, 99, 41, 32, 43, 32, 40,118,101, 99, 42, 40, 49, 46, 48, 45,102, 97, 99, 41, 41, 59, 10, 10,125, 10, + 10,118,111,105,100, 32, 99,117,114,118,101,115, 95,114,103, 98, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, + 32, 99,111,108, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32, 99,117,114,118,101,109, 97,112, 44, 32,111,117,116, 32,118,101, + 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32,116,101,120,116,117,114,101, + 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, 50, 40,116,101,120,116,117,114,101, 50, 68, 40, 99,117,114,118, +101,109, 97,112, 44, 32,118,101, 99, 50, 40, 99,111,108, 46,114, 44, 32, 48, 46, 48, 41, 41, 46, 97, 44, 32, 48, 46, 48, 41, 41, + 46,114, 59, 10, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40, 99,117,114,118,101,109, + 97,112, 44, 32,118,101, 99, 50, 40,116,101,120,116,117,114,101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, + 50, 40, 99,111,108, 46,103, 44, 32, 48, 46, 48, 41, 41, 46, 97, 44, 32, 48, 46, 48, 41, 41, 46,103, 59, 10, 9,111,117,116, 99, +111,108, 46, 98, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, 50, 40, +116,101,120,116,117,114,101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, 50, 40, 99,111,108, 46, 98, 44, 32, + 48, 46, 48, 41, 41, 46, 97, 44, 32, 48, 46, 48, 41, 41, 46, 98, 59, 10, 10, 9,105,102, 32, 40,102, 97, 99, 32, 33, 61, 32, 49, + 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 32, 61, 32, 40,111,117,116, 99,111,108, 42,102, 97, 99, 41, 32, 43, 32, 40, 99, +111,108, 42, 40, 49, 46, 48, 45,102, 97, 99, 41, 41, 59, 10, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 46, + 97, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,116, 95,118, 97,108,117,101, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32, +111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118, 97, +108, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,116, 95,114,103, 98, 40,118,101, 99, 51, 32, 99,111,108, 44, 32,111,117,116, + 32,118,101, 99, 51, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 59, 10,125, + 10, 10,118,111,105,100, 32,115,101,116, 95,114,103, 98, 97, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,118,101, + 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 59, 10,125, 10, 10,118, +111,105,100, 32,115,101,116, 95,118, 97,108,117,101, 95,122,101,114,111, 40,111,117,116, 32,102,108,111, 97,116, 32,111,117,116, +118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,115,101, +116, 95,118, 97,108,117,101, 95,111,110,101, 40,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, + 9,111,117,116,118, 97,108, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,116, 95,114,103, 98, 95,122, +101,114,111, 40,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, + 32,118,101, 99, 51, 40, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,116, 95,114,103, 98, 97, 95,122,101,114, +111, 40,111,117,116, 32,118,101, 99, 52, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118, +101, 99, 52, 40, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32, 99,111,112,121, 95,114, 97,119, 40,118,101, 99, 52, 32, +118, 97,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, + 61, 32,118, 97,108, 59, 10,125, 10, 10,118,111,105,100, 32, 99,111,112,121, 95,114, 97,119, 40,118,101, 99, 51, 32,118, 97,108, + 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118, + 97,108, 59, 10,125, 10, 10,118,111,105,100, 32, 99,111,112,121, 95,114, 97,119, 40,118,101, 99, 50, 32,118, 97,108, 44, 32,111, +117,116, 32,118,101, 99, 50, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118, 97,108, 59, + 10,125, 10, 10,118,111,105,100, 32, 99,111,112,121, 95,114, 97,119, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, + 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118, 97,108, 59, 10, +125, 10, 10,118,111,105,100, 32,109,105,120, 95, 98,108,101,110,100, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, + 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99, +111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, + 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40, 99,111,108, 49, 44, 32, 99,111,108, 50, 44, 32,102, 97, 99, + 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109, +105,120, 95, 97,100,100, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, - 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, - 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, - 59, 10, 10, 9,118,101, 99, 52, 32,104,115,118, 44, 32,104,115,118, 50, 59, 10, 9,114,103, 98, 95,116,111, 95,104,115,118, 40, -111,117,116, 99,111,108, 44, 32,104,115,118, 41, 59, 10, 10, 9,105,102, 40,104,115,118, 46,121, 32, 33, 61, 32, 48, 46, 48, 41, - 32,123, 10, 9, 9,114,103, 98, 95,116,111, 95,104,115,118, 40, 99,111,108, 50, 44, 32,104,115,118, 50, 41, 59, 10, 10, 9, 9, -104,115,118, 46,121, 32, 61, 32,102, 97, 99,109, 42,104,115,118, 46,121, 32, 43, 32,102, 97, 99, 42,104,115,118, 50, 46,121, 59, - 10, 9, 9,104,115,118, 95,116,111, 95,114,103, 98, 40,104,115,118, 44, 32,111,117,116, 99,111,108, 41, 59, 10, 9,125, 10,125, - 10, 10,118,111,105,100, 32,109,105,120, 95,118, 97,108, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99, + 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 32, + 61, 32,109,105,120, 40, 99,111,108, 49, 44, 32, 99,111,108, 49, 32, 43, 32, 99,111,108, 50, 44, 32,102, 97, 99, 41, 59, 10, 9, +111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,109, +117,108,116, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99, +111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99, +108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, 32,109, +105,120, 40, 99,111,108, 49, 44, 32, 99,111,108, 49, 32, 42, 32, 99,111,108, 50, 44, 32,102, 97, 99, 41, 59, 10, 9,111,117,116, + 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,115, 99,114,101, +101,110, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111, +108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, + 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 32, + 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32,118,101, 99, 52, 40, 49, 46, 48, + 41, 32, 45, 32, 40,118,101, 99, 52, 40,102, 97, 99,109, 41, 32, 43, 32,102, 97, 99, 42, 40,118,101, 99, 52, 40, 49, 46, 48, 41, + 32, 45, 32, 99,111,108, 50, 41, 41, 42, 40,118,101, 99, 52, 40, 49, 46, 48, 41, 32, 45, 32, 99,111,108, 49, 41, 59, 10, 9,111, +117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,111,118, +101,114,108, 97,121, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, + 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, + 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 97, + 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, + 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46,114, 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,111,117,116, 99,111,108, 46,114, + 32, 42, 61, 32,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99, 42, 99,111,108, 50, 46,114, 59, 10, 9,101,108,115,101, + 10, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42, +102, 97, 99, 42, 40, 49, 46, 48, 32, 45, 32, 99,111,108, 50, 46,114, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111, +108, 46,114, 41, 59, 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46,103, 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,111,117,116, + 99,111,108, 46,103, 32, 42, 61, 32,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99, 42, 99,111,108, 50, 46,103, 59, 10, + 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, + 32, 50, 46, 48, 42,102, 97, 99, 42, 40, 49, 46, 48, 32, 45, 32, 99,111,108, 50, 46,103, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32, +111,117,116, 99,111,108, 46,103, 41, 59, 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46, 98, 32, 60, 32, 48, 46, 53, 41, 10, + 9, 9,111,117,116, 99,111,108, 46, 98, 32, 42, 61, 32,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99, 42, 99,111,108, + 50, 46, 98, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, + 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99, 42, 40, 49, 46, 48, 32, 45, 32, 99,111,108, 50, 46, 98, 41, 41, 42, 40, 49, + 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46, 98, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,115,117, 98, 40, +102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, + 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, + 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40, 99, +111,108, 49, 44, 32, 99,111,108, 49, 32, 45, 32, 99,111,108, 50, 44, 32,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46, + 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,100,105,118, 40,102,108,111, 97, +116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, + 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, + 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, + 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,105,102, 40, 99,111,108, 50, + 46,114, 32, 33, 61, 32, 48, 46, 48, 41, 32,111,117,116, 99,111,108, 46,114, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111, +108, 46,114, 32, 43, 32,102, 97, 99, 42,111,117,116, 99,111,108, 46,114, 47, 99,111,108, 50, 46,114, 59, 10, 9,105,102, 40, 99, +111,108, 50, 46,103, 32, 33, 61, 32, 48, 46, 48, 41, 32,111,117,116, 99,111,108, 46,103, 32, 61, 32,102, 97, 99,109, 42,111,117, +116, 99,111,108, 46,103, 32, 43, 32,102, 97, 99, 42,111,117,116, 99,111,108, 46,103, 47, 99,111,108, 50, 46,103, 59, 10, 9,105, +102, 40, 99,111,108, 50, 46, 98, 32, 33, 61, 32, 48, 46, 48, 41, 32,111,117,116, 99,111,108, 46, 98, 32, 61, 32,102, 97, 99,109, + 42,111,117,116, 99,111,108, 46, 98, 32, 43, 32,102, 97, 99, 42,111,117,116, 99,111,108, 46, 98, 47, 99,111,108, 50, 46, 98, 59, + 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,100,105,102,102, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, + 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99, +111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, + 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40, 99,111,108, 49, 44, 32, 97, 98,115, 40, 99,111,108, 49, 32, + 45, 32, 99,111,108, 50, 41, 44, 32,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, + 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,100, 97,114,107, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118, +101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117, +116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, + 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 46,114,103, 98, 32, 61, 32,109,105,110, 40, 99,111,108, 49, 46,114,103, 98, 44, + 32, 99,111,108, 50, 46,114,103, 98, 42,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, + 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,108,105,103,104,116, 40,102,108,111, 97,116, 32,102, 97, 99, 44, + 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32, +111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, + 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 46,114,103, 98, 32, 61, 32,109, 97,120, 40, 99,111,108, 49, 46,114,103, + 98, 44, 32, 99,111,108, 50, 46,114,103, 98, 42,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111, +108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,100,111,100,103,101, 40,102,108,111, 97,116, 32,102, 97, + 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, + 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, + 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,105,102, 40,111,117, +116, 99,111,108, 46,114, 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,102,108,111, 97,116, 32,116,109,112, 32, 61, 32, 49, + 46, 48, 32, 45, 32,102, 97, 99, 42, 99,111,108, 50, 46,114, 59, 10, 9, 9,105,102, 40,116,109,112, 32, 60, 61, 32, 48, 46, 48, + 41, 10, 9, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9,101,108,115,101, 32,105,102, 40, 40, +116,109,112, 32, 61, 32,111,117,116, 99,111,108, 46,114, 47,116,109,112, 41, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9, 9,111,117, +116, 99,111,108, 46,114, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9,101,108,115,101, 10, 9, 9, 9,111,117,116, 99,111,108, 46,114, + 32, 61, 32,116,109,112, 59, 10, 9,125, 10, 9,105,102, 40,111,117,116, 99,111,108, 46,103, 32, 33, 61, 32, 48, 46, 48, 41, 32, +123, 10, 9, 9,102,108,111, 97,116, 32,116,109,112, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 42, 99,111,108, 50, 46,103, + 59, 10, 9, 9,105,102, 40,116,109,112, 32, 60, 61, 32, 48, 46, 48, 41, 10, 9, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, + 32, 49, 46, 48, 59, 10, 9, 9,101,108,115,101, 32,105,102, 40, 40,116,109,112, 32, 61, 32,111,117,116, 99,111,108, 46,103, 47, +116,109,112, 41, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32, 49, 46, 48, 59, 10, 9, + 9,101,108,115,101, 10, 9, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32,116,109,112, 59, 10, 9,125, 10, 9,105,102, 40, +111,117,116, 99,111,108, 46, 98, 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,102,108,111, 97,116, 32,116,109,112, 32, 61, + 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 42, 99,111,108, 50, 46, 98, 59, 10, 9, 9,105,102, 40,116,109,112, 32, 60, 61, 32, 48, + 46, 48, 41, 10, 9, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9,101,108,115,101, 32,105,102, + 40, 40,116,109,112, 32, 61, 32,111,117,116, 99,111,108, 46, 98, 47,116,109,112, 41, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9, 9, +111,117,116, 99,111,108, 46, 98, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9,101,108,115,101, 10, 9, 9, 9,111,117,116, 99,111,108, + 46, 98, 32, 61, 32,116,109,112, 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95, 98,117,114,110, 40,102,108, +111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111, +117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, + 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,116,109,112, 44, 32,102, 97, 99,109, 32, + 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9, +116,109,112, 32, 61, 32,102, 97, 99,109, 32, 43, 32,102, 97, 99, 42, 99,111,108, 50, 46,114, 59, 10, 9,105,102, 40,116,109,112, + 32, 60, 61, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115,101, + 32,105,102, 40, 40,116,109,112, 32, 61, 32, 40, 49, 46, 48, 32, 45, 32, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46, +114, 41, 47,116,109,112, 41, 41, 32, 60, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32, 48, 46, 48, + 59, 10, 9,101,108,115,101, 32,105,102, 40,116,109,112, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46,114, + 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32,116,109,112, 59, 10, + 10, 9,116,109,112, 32, 61, 32,102, 97, 99,109, 32, 43, 32,102, 97, 99, 42, 99,111,108, 50, 46,103, 59, 10, 9,105,102, 40,116, +109,112, 32, 60, 61, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108, +115,101, 32,105,102, 40, 40,116,109,112, 32, 61, 32, 40, 49, 46, 48, 32, 45, 32, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111, +108, 46,103, 41, 47,116,109,112, 41, 41, 32, 60, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32, 48, + 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40,116,109,112, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, + 46,103, 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32,116,109,112, + 59, 10, 10, 9,116,109,112, 32, 61, 32,102, 97, 99,109, 32, 43, 32,102, 97, 99, 42, 99,111,108, 50, 46, 98, 59, 10, 9,105,102, + 40,116,109,112, 32, 60, 61, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32, 48, 46, 48, 59, 10, 9, +101,108,115,101, 32,105,102, 40, 40,116,109,112, 32, 61, 32, 40, 49, 46, 48, 32, 45, 32, 40, 49, 46, 48, 32, 45, 32,111,117,116, + 99,111,108, 46, 98, 41, 47,116,109,112, 41, 41, 32, 60, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, + 32, 48, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40,116,109,112, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116, 99, +111,108, 46, 98, 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32,116, +109,112, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,104,117,101, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118, +101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117, +116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, + 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9, +111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,118,101, 99, 52, 32,104,115,118, 44, 32,104,115,118, 50, 44, + 32,116,109,112, 59, 10, 9,114,103, 98, 95,116,111, 95,104,115,118, 40, 99,111,108, 50, 44, 32,104,115,118, 50, 41, 59, 10, 10, + 9,105,102, 40,104,115,118, 50, 46,121, 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,114,103, 98, 95,116,111, 95,104,115, +118, 40,111,117,116, 99,111,108, 44, 32,104,115,118, 41, 59, 10, 9, 9,104,115,118, 46,120, 32, 61, 32,104,115,118, 50, 46,120, + 59, 10, 9, 9,104,115,118, 95,116,111, 95,114,103, 98, 40,104,115,118, 44, 32,116,109,112, 41, 59, 32, 10, 10, 9, 9,111,117, +116, 99,111,108, 32, 61, 32,109,105,120, 40,111,117,116, 99,111,108, 44, 32,116,109,112, 44, 32,102, 97, 99, 41, 59, 10, 9, 9, +111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,109,105, +120, 95,115, 97,116, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, + 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, + 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 97, + 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, + 10, 10, 9,118,101, 99, 52, 32,104,115,118, 44, 32,104,115,118, 50, 59, 10, 9,114,103, 98, 95,116,111, 95,104,115,118, 40,111, +117,116, 99,111,108, 44, 32,104,115,118, 41, 59, 10, 10, 9,105,102, 40,104,115,118, 46,121, 32, 33, 61, 32, 48, 46, 48, 41, 32, +123, 10, 9, 9,114,103, 98, 95,116,111, 95,104,115,118, 40, 99,111,108, 50, 44, 32,104,115,118, 50, 41, 59, 10, 10, 9, 9,104, +115,118, 46,121, 32, 61, 32,102, 97, 99,109, 42,104,115,118, 46,121, 32, 43, 32,102, 97, 99, 42,104,115,118, 50, 46,121, 59, 10, + 9, 9,104,115,118, 95,116,111, 95,114,103, 98, 40,104,115,118, 44, 32,111,117,116, 99,111,108, 41, 59, 10, 9,125, 10,125, 10, + 10,118,111,105,100, 32,109,105,120, 95,118, 97,108, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111, +108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10, +123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9, +102,108,111, 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,118,101, 99, 52, 32,104, +115,118, 44, 32,104,115,118, 50, 59, 10, 9,114,103, 98, 95,116,111, 95,104,115,118, 40, 99,111,108, 49, 44, 32,104,115,118, 41, + 59, 10, 9,114,103, 98, 95,116,111, 95,104,115,118, 40, 99,111,108, 50, 44, 32,104,115,118, 50, 41, 59, 10, 10, 9,104,115,118, + 46,122, 32, 61, 32,102, 97, 99,109, 42,104,115,118, 46,122, 32, 43, 32,102, 97, 99, 42,104,115,118, 50, 46,122, 59, 10, 9,104, +115,118, 95,116,111, 95,114,103, 98, 40,104,115,118, 44, 32,111,117,116, 99,111,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32, +109,105,120, 95, 99,111,108,111,114, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32, +118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, + 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97, +116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99, +111,108, 49, 59, 10, 10, 9,118,101, 99, 52, 32,104,115,118, 44, 32,104,115,118, 50, 44, 32,116,109,112, 59, 10, 9,114,103, 98, + 95,116,111, 95,104,115,118, 40, 99,111,108, 50, 44, 32,104,115,118, 50, 41, 59, 10, 10, 9,105,102, 40,104,115,118, 50, 46,121, + 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,114,103, 98, 95,116,111, 95,104,115,118, 40,111,117,116, 99,111,108, 44, 32, +104,115,118, 41, 59, 10, 9, 9,104,115,118, 46,120, 32, 61, 32,104,115,118, 50, 46,120, 59, 10, 9, 9,104,115,118, 46,121, 32, + 61, 32,104,115,118, 50, 46,121, 59, 10, 9, 9,104,115,118, 95,116,111, 95,114,103, 98, 40,104,115,118, 44, 32,116,109,112, 41, + 59, 32, 10, 10, 9, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40,111,117,116, 99,111,108, 44, 32,116,109,112, 44, 32, +102, 97, 99, 41, 59, 10, 9, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10, 9,125, 10,125, 10, + 10,118,111,105,100, 32,109,105,120, 95,115,111,102,116, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99, 111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,118,101, 99, 52, 32, -104,115,118, 44, 32,104,115,118, 50, 59, 10, 9,114,103, 98, 95,116,111, 95,104,115,118, 40, 99,111,108, 49, 44, 32,104,115,118, - 41, 59, 10, 9,114,103, 98, 95,116,111, 95,104,115,118, 40, 99,111,108, 50, 44, 32,104,115,118, 50, 41, 59, 10, 10, 9,104,115, -118, 46,122, 32, 61, 32,102, 97, 99,109, 42,104,115,118, 46,122, 32, 43, 32,102, 97, 99, 42,104,115,118, 50, 46,122, 59, 10, 9, -104,115,118, 95,116,111, 95,114,103, 98, 40,104,115,118, 44, 32,111,117,116, 99,111,108, 41, 59, 10,125, 10, 10,118,111,105,100, - 32,109,105,120, 95, 99,111,108,111,114, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, - 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9, -102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, - 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32, - 99,111,108, 49, 59, 10, 10, 9,118,101, 99, 52, 32,104,115,118, 44, 32,104,115,118, 50, 44, 32,116,109,112, 59, 10, 9,114,103, - 98, 95,116,111, 95,104,115,118, 40, 99,111,108, 50, 44, 32,104,115,118, 50, 41, 59, 10, 10, 9,105,102, 40,104,115,118, 50, 46, -121, 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,114,103, 98, 95,116,111, 95,104,115,118, 40,111,117,116, 99,111,108, 44, - 32,104,115,118, 41, 59, 10, 9, 9,104,115,118, 46,120, 32, 61, 32,104,115,118, 50, 46,120, 59, 10, 9, 9,104,115,118, 46,121, - 32, 61, 32,104,115,118, 50, 46,121, 59, 10, 9, 9,104,115,118, 95,116,111, 95,114,103, 98, 40,104,115,118, 44, 32,116,109,112, - 41, 59, 32, 10, 10, 9, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40,111,117,116, 99,111,108, 44, 32,116,109,112, 44, - 32,102, 97, 99, 41, 59, 10, 9, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10, 9,125, 10,125, - 10, 10,118,111,105,100, 32,109,105,120, 95,115,111,102,116, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, - 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, - 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, - 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,118,101, 99, 52, - 32,111,110,101, 61, 32,118,101, 99, 52, 40, 49, 46, 48, 41, 59, 10, 9,118,101, 99, 52, 32,115, 99,114, 61, 32,111,110,101, 32, - 45, 32, 40,111,110,101, 32, 45, 32, 99,111,108, 50, 41, 42, 40,111,110,101, 32, 45, 32, 99,111,108, 49, 41, 59, 10, 9,111,117, -116, 99,111,108, 32, 61, 32,102, 97, 99,109, 42, 99,111,108, 49, 32, 43, 32,102, 97, 99, 42, 40, 40,111,110,101, 32, 45, 32, 99, -111,108, 49, 41, 42, 99,111,108, 50, 42, 99,111,108, 49, 32, 43, 32, 99,111,108, 49, 42,115, 99,114, 41, 59, 10,125, 10, 10,118, -111,105,100, 32,109,105,120, 95,108,105,110,101, 97,114, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99, -111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, - 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, - 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,105,102, 40, 99,111,108, 50, 46,114, 32, 62, 32, 48, - 46, 53, 41, 10, 9, 9,111,117,116, 99,111,108, 46,114, 61, 32, 99,111,108, 49, 46,114, 32, 43, 32,102, 97, 99, 42, 40, 50, 46, - 48, 42, 40, 99,111,108, 50, 46,114, 32, 45, 32, 48, 46, 53, 41, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111, -108, 46,114, 61, 32, 99,111,108, 49, 46,114, 32, 43, 32,102, 97, 99, 42, 40, 50, 46, 48, 42, 40, 99,111,108, 50, 46,114, 41, 32, - 45, 32, 49, 46, 48, 41, 59, 10, 10, 9,105,102, 40, 99,111,108, 50, 46,103, 32, 62, 32, 48, 46, 53, 41, 10, 9, 9,111,117,116, - 99,111,108, 46,103, 61, 32, 99,111,108, 49, 46,103, 32, 43, 32,102, 97, 99, 42, 40, 50, 46, 48, 42, 40, 99,111,108, 50, 46,103, - 32, 45, 32, 48, 46, 53, 41, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46,103, 61, 32, 99,111,108, 49, - 46,103, 32, 43, 32,102, 97, 99, 42, 40, 50, 46, 48, 42, 40, 99,111,108, 50, 46,103, 41, 32, 45, 32, 49, 46, 48, 41, 59, 10, 10, - 9,105,102, 40, 99,111,108, 50, 46, 98, 32, 62, 32, 48, 46, 53, 41, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 61, 32, 99,111, -108, 49, 46, 98, 32, 43, 32,102, 97, 99, 42, 40, 50, 46, 48, 42, 40, 99,111,108, 50, 46, 98, 32, 45, 32, 48, 46, 53, 41, 41, 59, - 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 61, 32, 99,111,108, 49, 46, 98, 32, 43, 32,102, 97, 99, 42, - 40, 50, 46, 48, 42, 40, 99,111,108, 50, 46, 98, 41, 32, 45, 32, 49, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,118, 97, -108,116,111,114,103, 98, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32, 99,111,108,111, -114,109, 97,112, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 44, 32,111,117,116, 32,102,108,111, 97,116, - 32,111,117,116, 97,108,112,104, 97, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, - 40, 99,111,108,111,114,109, 97,112, 44, 32,118,101, 99, 50, 40,102, 97, 99, 44, 32, 48, 46, 48, 41, 41, 59, 10, 9,111,117,116, - 97,108,112,104, 97, 32, 61, 32,111,117,116, 99,111,108, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,114,103, 98,116,111, 98, -119, 40,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 32, - 32, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 99,111,108,111,114, 46,114, 42, 48, 46, 51, 53, 32, 43, 32, 99,111,108, -111,114, 46,103, 42, 48, 46, 52, 53, 32, 43, 32, 99,111,108,111,114, 46, 98, 42, 48, 46, 50, 59, 32, 47, 42, 32,107,101,101,112, - 32,116,104,101,115,101, 32,102, 97, 99,116,111,114,115, 32,105,110, 32,115,121,110, 99, 32,119,105,116,104, 32,116,101,120,116, -117,114,101, 46,104, 58, 82, 71, 66, 84, 79, 66, 87, 32, 42, 47, 10,125, 10, 10,118,111,105,100, 32,105,110,118,101,114,116, 40, -102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117, -116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 46,120,121,122, 32, 61, 32,109,105,120, 40, 99,111,108, 46,120,121, -122, 44, 32,118,101, 99, 51, 40, 49, 46, 48, 44, 32, 49, 46, 48, 44, 32, 49, 46, 48, 41, 32, 45, 32, 99,111,108, 46,120,121,122, - 44, 32,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46,119, 32, 61, 32, 99,111,108, 46,119, 59, 10,125, 10, 10,118,111, -105,100, 32,104,117,101, 95,115, 97,116, 40,102,108,111, 97,116, 32,104,117,101, 44, 32,102,108,111, 97,116, 32,115, 97,116, 44, - 32,102,108,111, 97,116, 32,118, 97,108,117,101, 44, 32,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111, -108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,118,101, 99, 52, 32,104,115,118, 59, - 10, 10, 9,114,103, 98, 95,116,111, 95,104,115,118, 40, 99,111,108, 44, 32,104,115,118, 41, 59, 10, 10, 9,104,115,118, 91, 48, - 93, 32, 43, 61, 32, 40,104,117,101, 32, 45, 32, 48, 46, 53, 41, 59, 10, 9,105,102, 40,104,115,118, 91, 48, 93, 62, 49, 46, 48, - 41, 32,104,115,118, 91, 48, 93, 45, 61, 49, 46, 48, 59, 32,101,108,115,101, 32,105,102, 40,104,115,118, 91, 48, 93, 60, 48, 46, - 48, 41, 32,104,115,118, 91, 48, 93, 43, 61, 32, 49, 46, 48, 59, 10, 9,104,115,118, 91, 49, 93, 32, 42, 61, 32,115, 97,116, 59, - 10, 9,105,102, 40,104,115,118, 91, 49, 93, 62, 49, 46, 48, 41, 32,104,115,118, 91, 49, 93, 61, 32, 49, 46, 48, 59, 32,101,108, -115,101, 32,105,102, 40,104,115,118, 91, 49, 93, 60, 48, 46, 48, 41, 32,104,115,118, 91, 49, 93, 61, 32, 48, 46, 48, 59, 10, 9, -104,115,118, 91, 50, 93, 32, 42, 61, 32,118, 97,108,117,101, 59, 10, 9,105,102, 40,104,115,118, 91, 50, 93, 62, 49, 46, 48, 41, - 32,104,115,118, 91, 50, 93, 61, 32, 49, 46, 48, 59, 32,101,108,115,101, 32,105,102, 40,104,115,118, 91, 50, 93, 60, 48, 46, 48, - 41, 32,104,115,118, 91, 50, 93, 61, 32, 48, 46, 48, 59, 10, 10, 9,104,115,118, 95,116,111, 95,114,103, 98, 40,104,115,118, 44, - 32,111,117,116, 99,111,108, 41, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40, 99,111,108, 44, 32,111,117, -116, 99,111,108, 44, 32,102, 97, 99, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,112, 97,114, 97,116,101, 95,114,103, 98, - 40,118,101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,114, 44, 32,111,117,116, 32,102,108,111, 97, -116, 32,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32, 98, 41, 10,123, 10, 9,114, 32, 61, 32, 99,111,108, 46,114, 59, 10, - 9,103, 32, 61, 32, 99,111,108, 46,103, 59, 10, 9, 98, 32, 61, 32, 99,111,108, 46, 98, 59, 10,125, 10, 10,118,111,105,100, 32, - 99,111,109, 98,105,110,101, 95,114,103, 98, 40,102,108,111, 97,116, 32,114, 44, 32,102,108,111, 97,116, 32,103, 44, 32,102,108, -111, 97,116, 32, 98, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108, 41, 10,123, 10, 9, 99,111,108, 32, 61, 32,118,101, - 99, 52, 40,114, 44, 32,103, 44, 32, 98, 44, 32, 49, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,111,117,116,112,117,116, - 95,110,111,100,101, 40,118,101, 99, 52, 32,114,103, 98, 44, 32,102,108,111, 97,116, 32, 97,108,112,104, 97, 44, 32,111,117,116, - 32,118,101, 99, 52, 32,111,117,116,114,103, 98, 41, 10,123, 10, 9,111,117,116,114,103, 98, 32, 61, 32,118,101, 99, 52, 40,114, -103, 98, 46,114,103, 98, 44, 32, 97,108,112,104, 97, 41, 59, 10,125, 10, 10, 47, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 32, - 84, 69, 88, 84, 85, 82, 69, 83, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 47, 10, 10,118,111,105,100, 32, -116,101,120,116,117,114,101, 95,102,108,105,112, 95, 98,108,101,110,100, 40,118,101, 99, 51, 32,118,101, 99, 44, 32,111,117,116, - 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32,118,101, 99, 46,121,120, -122, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120,116,117,114,101, 95, 98,108,101,110,100, 95,108,105,110, 40,118,101, 99, - 51, 32,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, - 97,108, 32, 61, 32, 40, 49, 46, 48, 43,118,101, 99, 46,120, 41, 47, 50, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,116,101, -120,116,117,114,101, 95, 98,108,101,110,100, 95,113,117, 97,100, 40,118,101, 99, 51, 32,118,101, 99, 44, 32,111,117,116, 32,102, -108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,109, 97,120, 40, 40, 49, 46, - 48, 43,118,101, 99, 46,120, 41, 47, 50, 46, 48, 44, 32, 48, 46, 48, 41, 59, 10, 9,111,117,116,118, 97,108, 32, 42, 61, 32,111, -117,116,118, 97,108, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120,116,117,114,101, 95,119,111,111,100, 95,115,105,110, 40, -118,101, 99, 51, 32,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118, 97,108,117,101, 44, 32,111,117,116, 32,118, -101, 99, 52, 32, 99,111,108,111,114, 44, 32,111,117,116, 32,118,101, 99, 51, 32,110,111,114,109, 97,108, 41, 10,123, 10, 9,102, -108,111, 97,116, 32, 97, 32, 61, 32,115,113,114,116, 40,118,101, 99, 46,120, 42,118,101, 99, 46,120, 32, 43, 32,118,101, 99, 46, -121, 42,118,101, 99, 46,121, 32, 43, 32,118,101, 99, 46,122, 42,118,101, 99, 46,122, 41, 42, 50, 48, 46, 48, 59, 10, 9,102,108, -111, 97,116, 32,119,105, 32, 61, 32, 48, 46, 53, 32, 43, 32, 48, 46, 53, 42,115,105,110, 40, 97, 41, 59, 10, 10, 9,118, 97,108, -117,101, 32, 61, 32,119,105, 59, 10, 9, 99,111,108,111,114, 32, 61, 32,118,101, 99, 52, 40,119,105, 44, 32,119,105, 44, 32,119, -105, 44, 32, 49, 46, 48, 41, 59, 10, 9,110,111,114,109, 97,108, 32, 61, 32,118,101, 99, 51, 40, 48, 46, 48, 44, 32, 48, 46, 48, - 44, 32, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120,116,117,114,101, 95,105,109, 97,103,101, 40,118,101, - 99, 51, 32,118,101, 99, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,111,117,116, 32,102,108,111, 97,116, - 32,118, 97,108,117,101, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,111,117,116, 32,118,101, 99, 51, - 32,110,111,114,109, 97,108, 41, 10,123, 10, 9, 99,111,108,111,114, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, - 97, 44, 32, 40,118,101, 99, 46,120,121, 32, 43, 32,118,101, 99, 50, 40, 49, 46, 48, 44, 32, 49, 46, 48, 41, 41, 42, 48, 46, 53, - 41, 59, 10, 9,118, 97,108,117,101, 32, 61, 32, 49, 46, 48, 59, 10, 10, 9,110,111,114,109, 97,108, 46,120, 32, 61, 32, 50, 46, - 48, 42, 40, 99,111,108,111,114, 46,114, 32, 45, 32, 48, 46, 53, 41, 59, 10, 9,110,111,114,109, 97,108, 46,121, 32, 61, 32, 50, - 46, 48, 42, 40, 48, 46, 53, 32, 45, 32, 99,111,108,111,114, 46,103, 41, 59, 10, 9,110,111,114,109, 97,108, 46,122, 32, 61, 32, - 50, 46, 48, 42, 40, 99,111,108,111,114, 46, 98, 32, 45, 32, 48, 46, 53, 41, 59, 10,125, 10, 10, 47, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 32, 77, 84, 69, 88, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 47, 10, 10, -118,111,105,100, 32,116,101,120, 99,111, 95,111,114, 99,111, 40,118,101, 99, 51, 32, 97,116,116,111,114, 99,111, 44, 32,111,117, -116, 32,118,101, 99, 51, 32,111,114, 99,111, 41, 10,123, 10, 9,111,114, 99,111, 32, 61, 32, 97,116,116,111,114, 99,111, 59, 10, -125, 10, 10,118,111,105,100, 32,116,101,120, 99,111, 95,117,118, 40,118,101, 99, 50, 32, 97,116,116,117,118, 44, 32,111,117,116, - 32,118,101, 99, 51, 32,117,118, 41, 10,123, 10, 9, 47, 42, 32,100,105,115, 97, 98,108,101,100, 32,102,111,114, 32,110,111,119, - 44, 32,119,111,114,107,115, 32,116,111,103,101,116,104,101,114, 32,119,105,116,104, 32,108,101, 97,118,105,110,103, 32,111,117, -116, 32,109,116,101,120, 95, 50,100, 95,109, 97,112,112,105,110,103, 10, 9, 32, 32, 32,117,118, 32, 61, 32,118,101, 99, 51, 40, - 97,116,116,117,118, 42, 50, 46, 48, 32, 45, 32,118,101, 99, 50, 40, 49, 46, 48, 44, 32, 49, 46, 48, 41, 44, 32, 48, 46, 48, 41, - 59, 32, 42, 47, 10, 9,117,118, 32, 61, 32,118,101, 99, 51, 40, 97,116,116,117,118, 44, 32, 48, 46, 48, 41, 59, 10,125, 10, 10, -118,111,105,100, 32,116,101,120, 99,111, 95,110,111,114,109, 40,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,111,117,116, - 32,118,101, 99, 51, 32,111,117,116,110,111,114,109, 97,108, 41, 10,123, 10, 9, 47, 42, 32, 99,111,114,114,101,115,112,111,110, -100,115, 32,116,111, 32,115,104,105, 45, 62,111,114,110, 44, 32,119,104,105, 99,104, 32,105,115, 32,110,101,103, 97,116,101,100, - 32,115,111, 32, 99, 97,110, 99,101,108,115, 10, 9, 32, 32, 32,111,117,116, 32, 98,108,101,110,100,101,114, 32,110,111,114,109, - 97,108, 32,110,101,103, 97,116,105,111,110, 32, 42, 47, 10, 9,111,117,116,110,111,114,109, 97,108, 32, 61, 32,110,111,114,109, - 97,108,105,122,101, 40,110,111,114,109, 97,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120, 99,111, 95,116, 97,110, -103,101,110,116, 40,118,101, 99, 52, 32,116, 97,110,103,101,110,116, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,116, - 97,110,103,101,110,116, 41, 10,123, 10, 9,111,117,116,116, 97,110,103,101,110,116, 32, 61, 32,110,111,114,109, 97,108,105,122, -101, 40,116, 97,110,103,101,110,116, 46,120,121,122, 41, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120, 99,111, 95,103,108, -111, 98, 97,108, 40,109, 97,116, 52, 32,118,105,101,119,105,110,118,109, 97,116, 44, 32,118,101, 99, 51, 32, 99,111, 44, 32,111, -117,116, 32,118,101, 99, 51, 32,103,108,111, 98, 97,108, 41, 10,123, 10, 9,103,108,111, 98, 97,108, 32, 61, 32, 40,118,105,101, -119,105,110,118,109, 97,116, 42,118,101, 99, 52, 40, 99,111, 44, 32, 49, 46, 48, 41, 41, 46,120,121,122, 59, 10,125, 10, 10,118, -111,105,100, 32,116,101,120, 99,111, 95,111, 98,106,101, 99,116, 40,109, 97,116, 52, 32,118,105,101,119,105,110,118,109, 97,116, - 44, 32,109, 97,116, 52, 32,111, 98,105,110,118,109, 97,116, 44, 32,118,101, 99, 51, 32, 99,111, 44, 32,111,117,116, 32,118,101, - 99, 51, 32,111, 98,106,101, 99,116, 41, 10,123, 10, 9,111, 98,106,101, 99,116, 32, 61, 32, 40,111, 98,105,110,118,109, 97,116, - 42, 40,118,105,101,119,105,110,118,109, 97,116, 42,118,101, 99, 52, 40, 99,111, 44, 32, 49, 46, 48, 41, 41, 41, 46,120,121,122, - 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120, 99,111, 95,114,101,102,108, 40,118,101, 99, 51, 32,118,110, 44, 32,118,101, - 99, 51, 32,118,105,101,119, 44, 32,111,117,116, 32,118,101, 99, 51, 32,114,101,102, 41, 10,123, 10, 9,114,101,102, 32, 61, 32, -118,105,101,119, 32, 45, 32, 50, 46, 48, 42,100,111,116, 40,118,110, 44, 32,118,105,101,119, 41, 42,118,110, 59, 10,125, 10, 10, -118,111,105,100, 32,115,104, 97,100,101, 95,110,111,114,109, 40,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,111,117,116, - 32,118,101, 99, 51, 32,111,117,116,110,111,114,109, 97,108, 41, 10,123, 10, 9, 47, 42, 32, 98,108,101,110,100,101,114, 32,114, -101,110,100,101,114, 32,110,111,114,109, 97,108, 32,105,115, 32,110,101,103, 97,116,101,100, 32, 42, 47, 10, 9,111,117,116,110, -111,114,109, 97,108, 32, 61, 32, 45,110,111,114,109, 97,108,105,122,101, 40,110,111,114,109, 97,108, 41, 59, 10,125, 10, 10,118, -111,105,100, 32,109,116,101,120, 95,114,103, 98, 95, 98,108,101,110,100, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32, -118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, - 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, - 99,109, 59, 10, 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45, -102, 97, 99,116, 59, 10, 10, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 32, 43, 32,102, 97, - 99,109, 42,111,117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,109,117,108, 40, -118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32, -102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, - 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, - 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,103, 59, 10, 10, 9,105,110, 99,111,108, 32, 61, 32, 40,102, 97, - 99,109, 32, 43, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 41, 42,111,117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105, -100, 32,109,116,101,120, 95,114,103, 98, 95,115, 99,114,101,101,110, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118, +111,110,101, 61, 32,118,101, 99, 52, 40, 49, 46, 48, 41, 59, 10, 9,118,101, 99, 52, 32,115, 99,114, 61, 32,111,110,101, 32, 45, + 32, 40,111,110,101, 32, 45, 32, 99,111,108, 50, 41, 42, 40,111,110,101, 32, 45, 32, 99,111,108, 49, 41, 59, 10, 9,111,117,116, + 99,111,108, 32, 61, 32,102, 97, 99,109, 42, 99,111,108, 49, 32, 43, 32,102, 97, 99, 42, 40, 40,111,110,101, 32, 45, 32, 99,111, +108, 49, 41, 42, 99,111,108, 50, 42, 99,111,108, 49, 32, 43, 32, 99,111,108, 49, 42,115, 99,114, 41, 59, 10,125, 10, 10,118,111, +105,100, 32,109,105,120, 95,108,105,110,101, 97,114, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111, +108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10, +123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 10, + 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,105,102, 40, 99,111,108, 50, 46,114, 32, 62, 32, 48, 46, + 53, 41, 10, 9, 9,111,117,116, 99,111,108, 46,114, 61, 32, 99,111,108, 49, 46,114, 32, 43, 32,102, 97, 99, 42, 40, 50, 46, 48, + 42, 40, 99,111,108, 50, 46,114, 32, 45, 32, 48, 46, 53, 41, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, + 46,114, 61, 32, 99,111,108, 49, 46,114, 32, 43, 32,102, 97, 99, 42, 40, 50, 46, 48, 42, 40, 99,111,108, 50, 46,114, 41, 32, 45, + 32, 49, 46, 48, 41, 59, 10, 10, 9,105,102, 40, 99,111,108, 50, 46,103, 32, 62, 32, 48, 46, 53, 41, 10, 9, 9,111,117,116, 99, +111,108, 46,103, 61, 32, 99,111,108, 49, 46,103, 32, 43, 32,102, 97, 99, 42, 40, 50, 46, 48, 42, 40, 99,111,108, 50, 46,103, 32, + 45, 32, 48, 46, 53, 41, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46,103, 61, 32, 99,111,108, 49, 46, +103, 32, 43, 32,102, 97, 99, 42, 40, 50, 46, 48, 42, 40, 99,111,108, 50, 46,103, 41, 32, 45, 32, 49, 46, 48, 41, 59, 10, 10, 9, +105,102, 40, 99,111,108, 50, 46, 98, 32, 62, 32, 48, 46, 53, 41, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 61, 32, 99,111,108, + 49, 46, 98, 32, 43, 32,102, 97, 99, 42, 40, 50, 46, 48, 42, 40, 99,111,108, 50, 46, 98, 32, 45, 32, 48, 46, 53, 41, 41, 59, 10, + 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 61, 32, 99,111,108, 49, 46, 98, 32, 43, 32,102, 97, 99, 42, 40, + 50, 46, 48, 42, 40, 99,111,108, 50, 46, 98, 41, 32, 45, 32, 49, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,118, 97,108, +116,111,114,103, 98, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32, 99,111,108,111,114, +109, 97,112, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32, +111,117,116, 97,108,112,104, 97, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40, + 99,111,108,111,114,109, 97,112, 44, 32,118,101, 99, 50, 40,102, 97, 99, 44, 32, 48, 46, 48, 41, 41, 59, 10, 9,111,117,116, 97, +108,112,104, 97, 32, 61, 32,111,117,116, 99,111,108, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,114,103, 98,116,111, 98,119, + 40,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 32, 32, + 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 99,111,108,111,114, 46,114, 42, 48, 46, 51, 53, 32, 43, 32, 99,111,108,111, +114, 46,103, 42, 48, 46, 52, 53, 32, 43, 32, 99,111,108,111,114, 46, 98, 42, 48, 46, 50, 59, 32, 47, 42, 32,107,101,101,112, 32, +116,104,101,115,101, 32,102, 97, 99,116,111,114,115, 32,105,110, 32,115,121,110, 99, 32,119,105,116,104, 32,116,101,120,116,117, +114,101, 46,104, 58, 82, 71, 66, 84, 79, 66, 87, 32, 42, 47, 10,125, 10, 10,118,111,105,100, 32,105,110,118,101,114,116, 40,102, +108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, + 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 46,120,121,122, 32, 61, 32,109,105,120, 40, 99,111,108, 46,120,121,122, + 44, 32,118,101, 99, 51, 40, 49, 46, 48, 44, 32, 49, 46, 48, 44, 32, 49, 46, 48, 41, 32, 45, 32, 99,111,108, 46,120,121,122, 44, + 32,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46,119, 32, 61, 32, 99,111,108, 46,119, 59, 10,125, 10, 10,118,111,105, +100, 32,104,117,101, 95,115, 97,116, 40,102,108,111, 97,116, 32,104,117,101, 44, 32,102,108,111, 97,116, 32,115, 97,116, 44, 32, +102,108,111, 97,116, 32,118, 97,108,117,101, 44, 32,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, + 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,118,101, 99, 52, 32,104,115,118, 59, 10, + 10, 9,114,103, 98, 95,116,111, 95,104,115,118, 40, 99,111,108, 44, 32,104,115,118, 41, 59, 10, 10, 9,104,115,118, 91, 48, 93, + 32, 43, 61, 32, 40,104,117,101, 32, 45, 32, 48, 46, 53, 41, 59, 10, 9,105,102, 40,104,115,118, 91, 48, 93, 62, 49, 46, 48, 41, + 32,104,115,118, 91, 48, 93, 45, 61, 49, 46, 48, 59, 32,101,108,115,101, 32,105,102, 40,104,115,118, 91, 48, 93, 60, 48, 46, 48, + 41, 32,104,115,118, 91, 48, 93, 43, 61, 32, 49, 46, 48, 59, 10, 9,104,115,118, 91, 49, 93, 32, 42, 61, 32,115, 97,116, 59, 10, + 9,105,102, 40,104,115,118, 91, 49, 93, 62, 49, 46, 48, 41, 32,104,115,118, 91, 49, 93, 61, 32, 49, 46, 48, 59, 32,101,108,115, +101, 32,105,102, 40,104,115,118, 91, 49, 93, 60, 48, 46, 48, 41, 32,104,115,118, 91, 49, 93, 61, 32, 48, 46, 48, 59, 10, 9,104, +115,118, 91, 50, 93, 32, 42, 61, 32,118, 97,108,117,101, 59, 10, 9,105,102, 40,104,115,118, 91, 50, 93, 62, 49, 46, 48, 41, 32, +104,115,118, 91, 50, 93, 61, 32, 49, 46, 48, 59, 32,101,108,115,101, 32,105,102, 40,104,115,118, 91, 50, 93, 60, 48, 46, 48, 41, + 32,104,115,118, 91, 50, 93, 61, 32, 48, 46, 48, 59, 10, 10, 9,104,115,118, 95,116,111, 95,114,103, 98, 40,104,115,118, 44, 32, +111,117,116, 99,111,108, 41, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40, 99,111,108, 44, 32,111,117,116, + 99,111,108, 44, 32,102, 97, 99, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,112, 97,114, 97,116,101, 95,114,103, 98, 40, +118,101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,114, 44, 32,111,117,116, 32,102,108,111, 97,116, + 32,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32, 98, 41, 10,123, 10, 9,114, 32, 61, 32, 99,111,108, 46,114, 59, 10, 9, +103, 32, 61, 32, 99,111,108, 46,103, 59, 10, 9, 98, 32, 61, 32, 99,111,108, 46, 98, 59, 10,125, 10, 10,118,111,105,100, 32, 99, +111,109, 98,105,110,101, 95,114,103, 98, 40,102,108,111, 97,116, 32,114, 44, 32,102,108,111, 97,116, 32,103, 44, 32,102,108,111, + 97,116, 32, 98, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108, 41, 10,123, 10, 9, 99,111,108, 32, 61, 32,118,101, 99, + 52, 40,114, 44, 32,103, 44, 32, 98, 44, 32, 49, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,111,117,116,112,117,116, 95, +110,111,100,101, 40,118,101, 99, 52, 32,114,103, 98, 44, 32,102,108,111, 97,116, 32, 97,108,112,104, 97, 44, 32,111,117,116, 32, +118,101, 99, 52, 32,111,117,116,114,103, 98, 41, 10,123, 10, 9,111,117,116,114,103, 98, 32, 61, 32,118,101, 99, 52, 40,114,103, + 98, 46,114,103, 98, 44, 32, 97,108,112,104, 97, 41, 59, 10,125, 10, 10, 47, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 32, 84, + 69, 88, 84, 85, 82, 69, 83, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 47, 10, 10,118,111,105,100, 32,116, +101,120,116,117,114,101, 95,102,108,105,112, 95, 98,108,101,110,100, 40,118,101, 99, 51, 32,118,101, 99, 44, 32,111,117,116, 32, +118,101, 99, 51, 32,111,117,116,118,101, 99, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32,118,101, 99, 46,121,120,122, + 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120,116,117,114,101, 95, 98,108,101,110,100, 95,108,105,110, 40,118,101, 99, 51, + 32,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97, +108, 32, 61, 32, 40, 49, 46, 48, 43,118,101, 99, 46,120, 41, 47, 50, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120, +116,117,114,101, 95, 98,108,101,110,100, 95,113,117, 97,100, 40,118,101, 99, 51, 32,118,101, 99, 44, 32,111,117,116, 32,102,108, +111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,109, 97,120, 40, 40, 49, 46, 48, + 43,118,101, 99, 46,120, 41, 47, 50, 46, 48, 44, 32, 48, 46, 48, 41, 59, 10, 9,111,117,116,118, 97,108, 32, 42, 61, 32,111,117, +116,118, 97,108, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120,116,117,114,101, 95,119,111,111,100, 95,115,105,110, 40,118, +101, 99, 51, 32,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118, 97,108,117,101, 44, 32,111,117,116, 32,118,101, + 99, 52, 32, 99,111,108,111,114, 44, 32,111,117,116, 32,118,101, 99, 51, 32,110,111,114,109, 97,108, 41, 10,123, 10, 9,102,108, +111, 97,116, 32, 97, 32, 61, 32,115,113,114,116, 40,118,101, 99, 46,120, 42,118,101, 99, 46,120, 32, 43, 32,118,101, 99, 46,121, + 42,118,101, 99, 46,121, 32, 43, 32,118,101, 99, 46,122, 42,118,101, 99, 46,122, 41, 42, 50, 48, 46, 48, 59, 10, 9,102,108,111, + 97,116, 32,119,105, 32, 61, 32, 48, 46, 53, 32, 43, 32, 48, 46, 53, 42,115,105,110, 40, 97, 41, 59, 10, 10, 9,118, 97,108,117, +101, 32, 61, 32,119,105, 59, 10, 9, 99,111,108,111,114, 32, 61, 32,118,101, 99, 52, 40,119,105, 44, 32,119,105, 44, 32,119,105, + 44, 32, 49, 46, 48, 41, 59, 10, 9,110,111,114,109, 97,108, 32, 61, 32,118,101, 99, 51, 40, 48, 46, 48, 44, 32, 48, 46, 48, 44, + 32, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120,116,117,114,101, 95,105,109, 97,103,101, 40,118,101, 99, + 51, 32,118,101, 99, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,111,117,116, 32,102,108,111, 97,116, 32, +118, 97,108,117,101, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,111,117,116, 32,118,101, 99, 51, 32, +110,111,114,109, 97,108, 41, 10,123, 10, 9, 99,111,108,111,114, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, + 44, 32, 40,118,101, 99, 46,120,121, 32, 43, 32,118,101, 99, 50, 40, 49, 46, 48, 44, 32, 49, 46, 48, 41, 41, 42, 48, 46, 53, 41, + 59, 10, 9,118, 97,108,117,101, 32, 61, 32, 49, 46, 48, 59, 10, 10, 9,110,111,114,109, 97,108, 46,120, 32, 61, 32, 50, 46, 48, + 42, 40, 99,111,108,111,114, 46,114, 32, 45, 32, 48, 46, 53, 41, 59, 10, 9,110,111,114,109, 97,108, 46,121, 32, 61, 32, 50, 46, + 48, 42, 40, 48, 46, 53, 32, 45, 32, 99,111,108,111,114, 46,103, 41, 59, 10, 9,110,111,114,109, 97,108, 46,122, 32, 61, 32, 50, + 46, 48, 42, 40, 99,111,108,111,114, 46, 98, 32, 45, 32, 48, 46, 53, 41, 59, 10,125, 10, 10, 47, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 32, 77, 84, 69, 88, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 47, 10, 10,118, +111,105,100, 32,116,101,120, 99,111, 95,111,114, 99,111, 40,118,101, 99, 51, 32, 97,116,116,111,114, 99,111, 44, 32,111,117,116, + 32,118,101, 99, 51, 32,111,114, 99,111, 41, 10,123, 10, 9,111,114, 99,111, 32, 61, 32, 97,116,116,111,114, 99,111, 59, 10,125, + 10, 10,118,111,105,100, 32,116,101,120, 99,111, 95,117,118, 40,118,101, 99, 50, 32, 97,116,116,117,118, 44, 32,111,117,116, 32, +118,101, 99, 51, 32,117,118, 41, 10,123, 10, 9, 47, 42, 32,100,105,115, 97, 98,108,101,100, 32,102,111,114, 32,110,111,119, 44, + 32,119,111,114,107,115, 32,116,111,103,101,116,104,101,114, 32,119,105,116,104, 32,108,101, 97,118,105,110,103, 32,111,117,116, + 32,109,116,101,120, 95, 50,100, 95,109, 97,112,112,105,110,103, 10, 9, 32, 32, 32,117,118, 32, 61, 32,118,101, 99, 51, 40, 97, +116,116,117,118, 42, 50, 46, 48, 32, 45, 32,118,101, 99, 50, 40, 49, 46, 48, 44, 32, 49, 46, 48, 41, 44, 32, 48, 46, 48, 41, 59, + 32, 42, 47, 10, 9,117,118, 32, 61, 32,118,101, 99, 51, 40, 97,116,116,117,118, 44, 32, 48, 46, 48, 41, 59, 10,125, 10, 10,118, +111,105,100, 32,116,101,120, 99,111, 95,110,111,114,109, 40,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,111,117,116, 32, +118,101, 99, 51, 32,111,117,116,110,111,114,109, 97,108, 41, 10,123, 10, 9, 47, 42, 32, 99,111,114,114,101,115,112,111,110,100, +115, 32,116,111, 32,115,104,105, 45, 62,111,114,110, 44, 32,119,104,105, 99,104, 32,105,115, 32,110,101,103, 97,116,101,100, 32, +115,111, 32, 99, 97,110, 99,101,108,115, 10, 9, 32, 32, 32,111,117,116, 32, 98,108,101,110,100,101,114, 32,110,111,114,109, 97, +108, 32,110,101,103, 97,116,105,111,110, 32, 42, 47, 10, 9,111,117,116,110,111,114,109, 97,108, 32, 61, 32,110,111,114,109, 97, +108,105,122,101, 40,110,111,114,109, 97,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120, 99,111, 95,116, 97,110,103, +101,110,116, 40,118,101, 99, 52, 32,116, 97,110,103,101,110,116, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,116, 97, +110,103,101,110,116, 41, 10,123, 10, 9,111,117,116,116, 97,110,103,101,110,116, 32, 61, 32,110,111,114,109, 97,108,105,122,101, + 40,116, 97,110,103,101,110,116, 46,120,121,122, 41, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120, 99,111, 95,103,108,111, + 98, 97,108, 40,109, 97,116, 52, 32,118,105,101,119,105,110,118,109, 97,116, 44, 32,118,101, 99, 51, 32, 99,111, 44, 32,111,117, +116, 32,118,101, 99, 51, 32,103,108,111, 98, 97,108, 41, 10,123, 10, 9,103,108,111, 98, 97,108, 32, 61, 32, 40,118,105,101,119, +105,110,118,109, 97,116, 42,118,101, 99, 52, 40, 99,111, 44, 32, 49, 46, 48, 41, 41, 46,120,121,122, 59, 10,125, 10, 10,118,111, +105,100, 32,116,101,120, 99,111, 95,111, 98,106,101, 99,116, 40,109, 97,116, 52, 32,118,105,101,119,105,110,118,109, 97,116, 44, + 32,109, 97,116, 52, 32,111, 98,105,110,118,109, 97,116, 44, 32,118,101, 99, 51, 32, 99,111, 44, 32,111,117,116, 32,118,101, 99, + 51, 32,111, 98,106,101, 99,116, 41, 10,123, 10, 9,111, 98,106,101, 99,116, 32, 61, 32, 40,111, 98,105,110,118,109, 97,116, 42, + 40,118,105,101,119,105,110,118,109, 97,116, 42,118,101, 99, 52, 40, 99,111, 44, 32, 49, 46, 48, 41, 41, 41, 46,120,121,122, 59, + 10,125, 10, 10,118,111,105,100, 32,116,101,120, 99,111, 95,114,101,102,108, 40,118,101, 99, 51, 32,118,110, 44, 32,118,101, 99, + 51, 32,118,105,101,119, 44, 32,111,117,116, 32,118,101, 99, 51, 32,114,101,102, 41, 10,123, 10, 9,114,101,102, 32, 61, 32,118, +105,101,119, 32, 45, 32, 50, 46, 48, 42,100,111,116, 40,118,110, 44, 32,118,105,101,119, 41, 42,118,110, 59, 10,125, 10, 10,118, +111,105,100, 32,115,104, 97,100,101, 95,110,111,114,109, 40,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,111,117,116, 32, +118,101, 99, 51, 32,111,117,116,110,111,114,109, 97,108, 41, 10,123, 10, 9, 47, 42, 32, 98,108,101,110,100,101,114, 32,114,101, +110,100,101,114, 32,110,111,114,109, 97,108, 32,105,115, 32,110,101,103, 97,116,101,100, 32, 42, 47, 10, 9,111,117,116,110,111, +114,109, 97,108, 32, 61, 32, 45,110,111,114,109, 97,108,105,122,101, 40,110,111,114,109, 97,108, 41, 59, 10,125, 10, 10,118,111, +105,100, 32,109,116,101,120, 95,114,103, 98, 95, 98,108,101,110,100, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118, 101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99, 109, 59, 10, 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, - 97, 99,103, 59, 10, 10, 9,105,110, 99,111,108, 32, 61, 32,118,101, 99, 51, 40, 49, 46, 48, 41, 32, 45, 32, 40,118,101, 99, 51, - 40,102, 97, 99,109, 41, 32, 43, 32,102, 97, 99,116, 42, 40,118,101, 99, 51, 40, 49, 46, 48, 41, 32, 45, 32,116,101,120, 99,111, -108, 41, 41, 42, 40,118,101, 99, 51, 40, 49, 46, 48, 41, 32, 45, 32,111,117,116, 99,111,108, 41, 59, 10,125, 10, 10,118,111,105, -100, 32,109,116,101,120, 95,114,103, 98, 95,111,118,101,114,108, 97,121, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32, -118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, - 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, - 99,109, 59, 10, 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45, -102, 97, 99,103, 59, 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46,114, 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,105,110, 99, -111,108, 46,114, 32, 61, 32,111,117,116, 99,111,108, 46,114, 42, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99,116, - 42,116,101,120, 99,111,108, 46,114, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,105,110, 99,111,108, 46,114, 32, 61, 32, 49, 46, - 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99,116, 42, 40, 49, 46, 48, 32, 45, 32,116,101,120, 99, -111,108, 46,114, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46,114, 41, 59, 10, 10, 9,105,102, 40,111,117, -116, 99,111,108, 46,103, 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,105,110, 99,111,108, 46,103, 32, 61, 32,111,117,116, 99,111,108, - 46,103, 42, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99,116, 42,116,101,120, 99,111,108, 46,103, 41, 59, 10, 9, -101,108,115,101, 10, 9, 9,105,110, 99,111,108, 46,103, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, 32, 50, - 46, 48, 42,102, 97, 99,116, 42, 40, 49, 46, 48, 32, 45, 32,116,101,120, 99,111,108, 46,103, 41, 41, 42, 40, 49, 46, 48, 32, 45, - 32,111,117,116, 99,111,108, 46,103, 41, 59, 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46, 98, 32, 60, 32, 48, 46, 53, 41, - 10, 9, 9,105,110, 99,111,108, 46, 98, 32, 61, 32,111,117,116, 99,111,108, 46, 98, 42, 40,102, 97, 99,109, 32, 43, 32, 50, 46, - 48, 42,102, 97, 99,116, 42,116,101,120, 99,111,108, 46, 98, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,105,110, 99,111,108, 46, - 98, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99,116, 42, 40, 49, 46, 48, 32, - 45, 32,116,101,120, 99,111,108, 46, 98, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46, 98, 41, 59, 10,125, - 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,115,117, 98, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, - 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32, -102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,105,110, 99,111,108, 32, 61, - 32, 45,102, 97, 99,116, 42,102, 97, 99,103, 42,116,101,120, 99,111,108, 32, 43, 32,111,117,116, 99,111,108, 59, 10,125, 10, 10, -118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95, 97,100,100, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118, + 97, 99,116, 59, 10, 10, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 32, 43, 32,102, 97, 99, +109, 42,111,117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,109,117,108, 40,118, +101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, + 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, + 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, + 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,103, 59, 10, 10, 9,105,110, 99,111,108, 32, 61, 32, 40,102, 97, 99, +109, 32, 43, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 41, 42,111,117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, + 32,109,116,101,120, 95,114,103, 98, 95,115, 99,114,101,101,110, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, + 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99, +103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, + 59, 10, 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, + 99,103, 59, 10, 10, 9,105,110, 99,111,108, 32, 61, 32,118,101, 99, 51, 40, 49, 46, 48, 41, 32, 45, 32, 40,118,101, 99, 51, 40, +102, 97, 99,109, 41, 32, 43, 32,102, 97, 99,116, 42, 40,118,101, 99, 51, 40, 49, 46, 48, 41, 32, 45, 32,116,101,120, 99,111,108, + 41, 41, 42, 40,118,101, 99, 51, 40, 49, 46, 48, 41, 32, 45, 32,111,117,116, 99,111,108, 41, 59, 10,125, 10, 10,118,111,105,100, + 32,109,116,101,120, 95,114,103, 98, 95,111,118,101,114,108, 97,121, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118, 101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, - 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,105,110, 99,111,108, 32, 61, 32,102, - 97, 99,116, 42,102, 97, 99,103, 42,116,101,120, 99,111,108, 32, 43, 32,111,117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105, -100, 32,109,116,101,120, 95,114,103, 98, 95,100,105,118, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, - 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, - 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, - 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,116, - 59, 10, 10, 9,105,102, 40,116,101,120, 99,111,108, 46,114, 32, 33, 61, 32, 48, 46, 48, 41, 32,105,110, 99,111,108, 46,114, 32, - 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 46,114, 32, 43, 32,102, 97, 99,116, 42,111,117,116, 99,111,108, 46,114, 47, -116,101,120, 99,111,108, 46,114, 59, 10, 9,105,102, 40,116,101,120, 99,111,108, 46,103, 32, 33, 61, 32, 48, 46, 48, 41, 32,105, -110, 99,111,108, 46,103, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 46,103, 32, 43, 32,102, 97, 99,116, 42,111,117, -116, 99,111,108, 46,103, 47,116,101,120, 99,111,108, 46,103, 59, 10, 9,105,102, 40,116,101,120, 99,111,108, 46, 98, 32, 33, 61, - 32, 48, 46, 48, 41, 32,105,110, 99,111,108, 46, 98, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 46, 98, 32, 43, 32, -102, 97, 99,116, 42,111,117,116, 99,111,108, 46, 98, 47,116,101,120, 99,111,108, 46, 98, 59, 10,125, 10, 10,118,111,105,100, 32, -109,116,101,120, 95,114,103, 98, 95,100,105,102,102, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32, + 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99, +109, 59, 10, 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, + 97, 99,103, 59, 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46,114, 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,105,110, 99,111, +108, 46,114, 32, 61, 32,111,117,116, 99,111,108, 46,114, 42, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99,116, 42, +116,101,120, 99,111,108, 46,114, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,105,110, 99,111,108, 46,114, 32, 61, 32, 49, 46, 48, + 32, 45, 32, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99,116, 42, 40, 49, 46, 48, 32, 45, 32,116,101,120, 99,111, +108, 46,114, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46,114, 41, 59, 10, 10, 9,105,102, 40,111,117,116, + 99,111,108, 46,103, 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,105,110, 99,111,108, 46,103, 32, 61, 32,111,117,116, 99,111,108, 46, +103, 42, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99,116, 42,116,101,120, 99,111,108, 46,103, 41, 59, 10, 9,101, +108,115,101, 10, 9, 9,105,110, 99,111,108, 46,103, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, 32, 50, 46, + 48, 42,102, 97, 99,116, 42, 40, 49, 46, 48, 32, 45, 32,116,101,120, 99,111,108, 46,103, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32, +111,117,116, 99,111,108, 46,103, 41, 59, 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46, 98, 32, 60, 32, 48, 46, 53, 41, 10, + 9, 9,105,110, 99,111,108, 46, 98, 32, 61, 32,111,117,116, 99,111,108, 46, 98, 42, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, + 42,102, 97, 99,116, 42,116,101,120, 99,111,108, 46, 98, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,105,110, 99,111,108, 46, 98, + 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99,116, 42, 40, 49, 46, 48, 32, 45, + 32,116,101,120, 99,111,108, 46, 98, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46, 98, 41, 59, 10,125, 10, + 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,115,117, 98, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32, +118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, + 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,105,110, 99,111,108, 32, 61, 32, + 45,102, 97, 99,116, 42,102, 97, 99,103, 42,116,101,120, 99,111,108, 32, 43, 32,111,117,116, 99,111,108, 59, 10,125, 10, 10,118, +111,105,100, 32,109,116,101,120, 95,114,103, 98, 95, 97,100,100, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, + 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99, +103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,105,110, 99,111,108, 32, 61, 32,102, 97, + 99,116, 42,102, 97, 99,103, 42,116,101,120, 99,111,108, 32, 43, 32,111,117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, + 32,109,116,101,120, 95,114,103, 98, 95,100,105,118, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32, 116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32, 111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,116, 59, - 10, 10, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 32, 43, 32,102, 97, 99,116, 42, 97, 98, -115, 40,116,101,120, 99,111,108, 32, 45, 32,111,117,116, 99,111,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, - 95,114,103, 98, 95,100, 97,114,107, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99, -111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32, -118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 44, 32, 99,111,108, 59, 10, - 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,116, - 59, 10, 10, 9, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 46,114, 59, 10, 9,105,102, 40, 99,111,108, - 32, 60, 32,111,117,116, 99,111,108, 46,114, 41, 32,105,110, 99,111,108, 46,114, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, - 32,105,110, 99,111,108, 46,114, 32, 61, 32,111,117,116, 99,111,108, 46,114, 59, 10, 9, 99,111,108, 32, 61, 32,102, 97, 99,116, - 42,116,101,120, 99,111,108, 46,103, 59, 10, 9,105,102, 40, 99,111,108, 32, 60, 32,111,117,116, 99,111,108, 46,103, 41, 32,105, -110, 99,111,108, 46,103, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 46,103, 32, 61, 32,111,117,116, - 99,111,108, 46,103, 59, 10, 9, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 46, 98, 59, 10, 9,105,102, - 40, 99,111,108, 32, 60, 32,111,117,116, 99,111,108, 46, 98, 41, 32,105,110, 99,111,108, 46, 98, 32, 61, 32, 99,111,108, 59, 32, -101,108,115,101, 32,105,110, 99,111,108, 46, 98, 32, 61, 32,111,117,116, 99,111,108, 46, 98, 59, 10,125, 10, 10,118,111,105,100, - 32,109,116,101,120, 95,114,103, 98, 95,108,105,103,104,116, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, - 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, - 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 44, - 32, 99,111,108, 59, 10, 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, - 48, 45,102, 97, 99,116, 59, 10, 10, 9, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 46,114, 59, 10, 9, -105,102, 40, 99,111,108, 32, 62, 32,111,117,116, 99,111,108, 46,114, 41, 32,105,110, 99,111,108, 46,114, 32, 61, 32, 99,111,108, - 59, 32,101,108,115,101, 32,105,110, 99,111,108, 46,114, 32, 61, 32,111,117,116, 99,111,108, 46,114, 59, 10, 9, 99,111,108, 32, - 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 46,103, 59, 10, 9,105,102, 40, 99,111,108, 32, 62, 32,111,117,116, 99,111, -108, 46,103, 41, 32,105,110, 99,111,108, 46,103, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 46,103, - 32, 61, 32,111,117,116, 99,111,108, 46,103, 59, 10, 9, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 46, - 98, 59, 10, 9,105,102, 40, 99,111,108, 32, 62, 32,111,117,116, 99,111,108, 46, 98, 41, 32,105,110, 99,111,108, 46, 98, 32, 61, - 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 46, 98, 32, 61, 32,111,117,116, 99,111,108, 46, 98, 59, 10,125, - 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,104,117,101, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, - 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32, -102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,118,101, 99, 52, 32, 99,111, -108, 59, 10, 10, 9,109,105,120, 95,104,117,101, 40,102, 97, 99,116, 42,102, 97, 99,103, 44, 32,118,101, 99, 52, 40,111,117,116, - 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32,118,101, 99, 52, 40,116,101,120, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32, 99,111, -108, 41, 59, 10, 9,105,110, 99,111,108, 46,114,103, 98, 32, 61, 32, 99,111,108, 46,114,103, 98, 59, 10,125, 10, 10,118,111,105, -100, 32,109,116,101,120, 95,114,103, 98, 95,115, 97,116, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, + 10, 10, 9,105,102, 40,116,101,120, 99,111,108, 46,114, 32, 33, 61, 32, 48, 46, 48, 41, 32,105,110, 99,111,108, 46,114, 32, 61, + 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 46,114, 32, 43, 32,102, 97, 99,116, 42,111,117,116, 99,111,108, 46,114, 47,116, +101,120, 99,111,108, 46,114, 59, 10, 9,105,102, 40,116,101,120, 99,111,108, 46,103, 32, 33, 61, 32, 48, 46, 48, 41, 32,105,110, + 99,111,108, 46,103, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 46,103, 32, 43, 32,102, 97, 99,116, 42,111,117,116, + 99,111,108, 46,103, 47,116,101,120, 99,111,108, 46,103, 59, 10, 9,105,102, 40,116,101,120, 99,111,108, 46, 98, 32, 33, 61, 32, + 48, 46, 48, 41, 32,105,110, 99,111,108, 46, 98, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 46, 98, 32, 43, 32,102, + 97, 99,116, 42,111,117,116, 99,111,108, 46, 98, 47,116,101,120, 99,111,108, 46, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109, +116,101,120, 95,114,103, 98, 95,100,105,102,102, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116, +101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111, +117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 10, 9, +102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,116, 59, 10, + 10, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 32, 43, 32,102, 97, 99,116, 42, 97, 98,115, + 40,116,101,120, 99,111,108, 32, 45, 32,111,117,116, 99,111,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, +114,103, 98, 95,100, 97,114,107, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111, +108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118, +101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 44, 32, 99,111,108, 59, 10, 10, + 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,116, 59, + 10, 10, 9, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 46,114, 59, 10, 9,105,102, 40, 99,111,108, 32, + 60, 32,111,117,116, 99,111,108, 46,114, 41, 32,105,110, 99,111,108, 46,114, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32, +105,110, 99,111,108, 46,114, 32, 61, 32,111,117,116, 99,111,108, 46,114, 59, 10, 9, 99,111,108, 32, 61, 32,102, 97, 99,116, 42, +116,101,120, 99,111,108, 46,103, 59, 10, 9,105,102, 40, 99,111,108, 32, 60, 32,111,117,116, 99,111,108, 46,103, 41, 32,105,110, + 99,111,108, 46,103, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 46,103, 32, 61, 32,111,117,116, 99, +111,108, 46,103, 59, 10, 9, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 46, 98, 59, 10, 9,105,102, 40, + 99,111,108, 32, 60, 32,111,117,116, 99,111,108, 46, 98, 41, 32,105,110, 99,111,108, 46, 98, 32, 61, 32, 99,111,108, 59, 32,101, +108,115,101, 32,105,110, 99,111,108, 46, 98, 32, 61, 32,111,117,116, 99,111,108, 46, 98, 59, 10,125, 10, 10,118,111,105,100, 32, +109,116,101,120, 95,114,103, 98, 95,108,105,103,104,116, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, - 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,118,101, 99, 52, 32, 99,111,108, 59, 10, 10, 9, -109,105,120, 95,115, 97,116, 40,102, 97, 99,116, 42,102, 97, 99,103, 44, 32,118,101, 99, 52, 40,111,117,116, 99,111,108, 44, 32, - 49, 46, 48, 41, 44, 32,118,101, 99, 52, 40,116,101,120, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32, 99,111,108, 41, 59, 10, 9, -105,110, 99,111,108, 46,114,103, 98, 32, 61, 32, 99,111,108, 46,114,103, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101, -120, 95,114,103, 98, 95,118, 97,108, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99, -111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32, -118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,118,101, 99, 52, 32, 99,111,108, 59, 10, 10, 9,109,105,120, 95,118, - 97,108, 40,102, 97, 99,116, 42,102, 97, 99,103, 44, 32,118,101, 99, 52, 40,111,117,116, 99,111,108, 44, 32, 49, 46, 48, 41, 44, - 32,118,101, 99, 52, 40,116,101,120, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32, 99,111,108, 41, 59, 10, 9,105,110, 99,111,108, - 46,114,103, 98, 32, 61, 32, 99,111,108, 46,114,103, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, - 95, 99,111,108,111,114, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, - 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, - 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,118,101, 99, 52, 32, 99,111,108, 59, 10, 10, 9,109,105,120, 95, 99,111,108,111, -114, 40,102, 97, 99,116, 42,102, 97, 99,103, 44, 32,118,101, 99, 52, 40,111,117,116, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32, + 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 44, 32, + 99,111,108, 59, 10, 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, + 45,102, 97, 99,116, 59, 10, 10, 9, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 46,114, 59, 10, 9,105, +102, 40, 99,111,108, 32, 62, 32,111,117,116, 99,111,108, 46,114, 41, 32,105,110, 99,111,108, 46,114, 32, 61, 32, 99,111,108, 59, + 32,101,108,115,101, 32,105,110, 99,111,108, 46,114, 32, 61, 32,111,117,116, 99,111,108, 46,114, 59, 10, 9, 99,111,108, 32, 61, + 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 46,103, 59, 10, 9,105,102, 40, 99,111,108, 32, 62, 32,111,117,116, 99,111,108, + 46,103, 41, 32,105,110, 99,111,108, 46,103, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 46,103, 32, + 61, 32,111,117,116, 99,111,108, 46,103, 59, 10, 9, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 46, 98, + 59, 10, 9,105,102, 40, 99,111,108, 32, 62, 32,111,117,116, 99,111,108, 46, 98, 41, 32,105,110, 99,111,108, 46, 98, 32, 61, 32, + 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 46, 98, 32, 61, 32,111,117,116, 99,111,108, 46, 98, 59, 10,125, 10, + 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,104,117,101, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32, +118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, + 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,118,101, 99, 52, 32, 99,111,108, + 59, 10, 10, 9,109,105,120, 95,104,117,101, 40,102, 97, 99,116, 42,102, 97, 99,103, 44, 32,118,101, 99, 52, 40,111,117,116, 99, +111,108, 44, 32, 49, 46, 48, 41, 44, 32,118,101, 99, 52, 40,116,101,120, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32, 99,111,108, + 41, 59, 10, 9,105,110, 99,111,108, 46,114,103, 98, 32, 61, 32, 99,111,108, 46,114,103, 98, 59, 10,125, 10, 10,118,111,105,100, + 32,109,116,101,120, 95,114,103, 98, 95,115, 97,116, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32, +116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32, +111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,118,101, 99, 52, 32, 99,111,108, 59, 10, 10, 9,109, +105,120, 95,115, 97,116, 40,102, 97, 99,116, 42,102, 97, 99,103, 44, 32,118,101, 99, 52, 40,111,117,116, 99,111,108, 44, 32, 49, + 46, 48, 41, 44, 32,118,101, 99, 52, 40,116,101,120, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32, 99,111,108, 41, 59, 10, 9,105, +110, 99,111,108, 46,114,103, 98, 32, 61, 32, 99,111,108, 46,114,103, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, + 95,114,103, 98, 95,118, 97,108, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111, +108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118, +101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,118,101, 99, 52, 32, 99,111,108, 59, 10, 10, 9,109,105,120, 95,118, 97, +108, 40,102, 97, 99,116, 42,102, 97, 99,103, 44, 32,118,101, 99, 52, 40,111,117,116, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32, 118,101, 99, 52, 40,116,101,120, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32, 99,111,108, 41, 59, 10, 9,105,110, 99,111,108, 46, -114,103, 98, 32, 61, 32, 99,111,108, 46,114,103, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117, -101, 95,118, 97,114,115, 40,105,110,111,117,116, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, - 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 97, 99,109, 41, 10,123, 10, 9,102, 97, 99,116, 32, 42, 61, 32, - 97, 98,115, 40,102, 97, 99,103, 41, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,116, 59, 10, 10, 9,105, -102, 40,102, 97, 99,103, 32, 60, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,102,108,111, 97,116, 32,116,109,112, 32, 61, 32,102, 97, - 99,116, 59, 10, 9, 9,102, 97, 99,116, 32, 61, 32,102, 97, 99,109, 59, 10, 9, 9,102, 97, 99,109, 32, 61, 32,116,109,112, 59, - 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95, 98,108,101,110,100, 40,102,108,111, +114,103, 98, 32, 61, 32, 99,111,108, 46,114,103, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95, + 99,111,108,111,114, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32, +102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, + 32,105,110, 99,111,108, 41, 10,123, 10, 9,118,101, 99, 52, 32, 99,111,108, 59, 10, 10, 9,109,105,120, 95, 99,111,108,111,114, + 40,102, 97, 99,116, 42,102, 97, 99,103, 44, 32,118,101, 99, 52, 40,111,117,116, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32,118, +101, 99, 52, 40,116,101,120, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32, 99,111,108, 41, 59, 10, 9,105,110, 99,111,108, 46,114, +103, 98, 32, 61, 32, 99,111,108, 46,114,103, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, + 95,118, 97,114,115, 40,105,110,111,117,116, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, + 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 97, 99,109, 41, 10,123, 10, 9,102, 97, 99,116, 32, 42, 61, 32, 97, + 98,115, 40,102, 97, 99,103, 41, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,116, 59, 10, 10, 9,105,102, + 40,102, 97, 99,103, 32, 60, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,102,108,111, 97,116, 32,116,109,112, 32, 61, 32,102, 97, 99, +116, 59, 10, 9, 9,102, 97, 99,116, 32, 61, 32,102, 97, 99,109, 59, 10, 9, 9,102, 97, 99,109, 32, 61, 32,116,109,112, 59, 10, + 9,125, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95, 98,108,101,110,100, 40,102,108,111, 97, +116, 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, + 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, + 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, + 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,105,110, 99,111,108, 32, 61, 32,102, 97, + 99,116, 42,116,101,120, 99,111,108, 32, 43, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, + 32,109,116,101,120, 95,118, 97,108,117,101, 95,109,117,108, 40,102,108,111, 97,116, 32,111,117,116, 99,111,108, 44, 32,102,108, +111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, + 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, + 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, + 32,102, 97, 99,109, 41, 59, 10, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99,103, 59, 10, 9,105,110, + 99,111,108, 32, 61, 32, 40,102, 97, 99,109, 32, 43, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 41, 42,111,117,116, 99,111, +108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,115, 99,114,101,101,110, 40,102,108,111, + 97,116, 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, + 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, + 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114, +115, 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, + 48, 32, 45, 32,102, 97, 99,103, 59, 10, 9,105,110, 99,111,108, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, + 32,102, 97, 99,116, 42, 40, 49, 46, 48, 32, 45, 32,116,101,120, 99,111,108, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, + 99,111,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,115,117, 98, 40,102,108,111, + 97,116, 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, + 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, + 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114, +115, 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,102, 97, 99,116, 32, 61, 32, 45,102, + 97, 99,116, 59, 10, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 32, 43, 32,111,117,116, 99, +111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95, 97,100,100, 40,102,108,111, 97,116, + 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99, +116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10, +123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40, +102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,102, 97, 99,116, 32, 61, 32,102, 97, 99,116, + 59, 10, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 32, 43, 32,111,117,116, 99,111,108, 59, + 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,100,105,118, 40,102,108,111, 97,116, 32,111,117, +116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32, +102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10,123, 10, 9, +102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,102, 97, 99, +116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,105,102, 40,116,101,120, 99,111,108, 32, 33, 61, 32, 48, + 46, 48, 41, 10, 9, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 32, 43, 32,102, 97, 99,116, + 42,111,117,116, 99,111,108, 47,116,101,120, 99,111,108, 59, 10, 9,101,108,115,101, 10, 9, 9,105,110, 99,111,108, 32, 61, 32, + 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,100,105,102,102, 40,102,108,111, 97,116, 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114, 115, 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,105,110, 99,111,108, 32, 61, 32,102, - 97, 99,116, 42,116,101,120, 99,111,108, 32, 43, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105, -100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,109,117,108, 40,102,108,111, 97,116, 32,111,117,116, 99,111,108, 44, 32,102, -108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, - 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, - 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,102, 97, 99,116, 44, 32,102, 97, 99,103, - 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99,103, 59, 10, 9,105, -110, 99,111,108, 32, 61, 32, 40,102, 97, 99,109, 32, 43, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 41, 42,111,117,116, 99, -111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,115, 99,114,101,101,110, 40,102,108, -111, 97,116, 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32, -102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111, -108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97, -114,115, 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,102, 97, 99,109, 32, 61, 32, 49, - 46, 48, 32, 45, 32,102, 97, 99,103, 59, 10, 9,105,110, 99,111,108, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, - 43, 32,102, 97, 99,116, 42, 40, 49, 46, 48, 32, 45, 32,116,101,120, 99,111,108, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117, -116, 99,111,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,115,117, 98, 40,102,108, -111, 97,116, 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32, -102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111, -108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97, -114,115, 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,102, 97, 99,116, 32, 61, 32, 45, -102, 97, 99,116, 59, 10, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 32, 43, 32,111,117,116, - 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95, 97,100,100, 40,102,108,111, 97, -116, 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, - 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, - 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, - 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,102, 97, 99,116, 32, 61, 32,102, 97, 99, -116, 59, 10, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 32, 43, 32,111,117,116, 99,111,108, - 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,100,105,118, 40,102,108,111, 97,116, 32,111, -117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, - 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10,123, 10, - 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,102, 97, - 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,105,102, 40,116,101,120, 99,111,108, 32, 33, 61, 32, - 48, 46, 48, 41, 10, 9, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 32, 43, 32,102, 97, 99, -116, 42,111,117,116, 99,111,108, 47,116,101,120, 99,111,108, 59, 10, 9,101,108,115,101, 10, 9, 9,105,110, 99,111,108, 32, 61, - 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,100,105,102,102, 40,102,108, -111, 97,116, 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32, -102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111, -108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97, -114,115, 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,105,110, 99,111,108, 32, 61, 32, -102, 97, 99,109, 42,111,117,116, 99,111,108, 32, 43, 32,102, 97, 99,116, 42, 97, 98,115, 40,116,101,120, 99,111,108, 32, 45, 32, -111,117,116, 99,111,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,100, 97,114,107, - 40,102,108,111, 97,116, 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, - 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105, -110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, - 95,118, 97,114,115, 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,102,108,111, 97,116, - 32, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 59, 10, 9,105,102, 40, 99,111,108, 32, 60, 32,111,117, -116, 99,111,108, 41, 32,105,110, 99,111,108, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 32, 61, 32, -111,117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,108,105,103,104,116, - 40,102,108,111, 97,116, 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, - 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105, -110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, - 95,118, 97,114,115, 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,102,108,111, 97,116, - 32, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 59, 10, 9,105,102, 40, 99,111,108, 32, 62, 32,111,117, -116, 99,111,108, 41, 32,105,110, 99,111,108, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 32, 61, 32, -111,117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95, 99,108, 97,109,112, - 95,112,111,115,105,116,105,118,101, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111, -117,116,102, 97, 99, 41, 10,123, 10, 9,111,117,116,102, 97, 99, 32, 61, 32,109, 97,120, 40,102, 97, 99, 44, 32, 48, 46, 48, 41, - 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95, 99,108, 97,109,112, 40,102,108,111, 97,116, - 32,102, 97, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,102, 97, 99, 41, 10,123, 10, 9,111,117,116,102, 97, - 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10,125, 10, 10,118,111,105, -100, 32,109,116,101,120, 95,104, 97,114, 95,100,105,118,105,100,101, 40,102,108,111, 97,116, 32,104, 97,114, 44, 32,111,117,116, - 32,102,108,111, 97,116, 32,111,117,116,104, 97,114, 41, 10,123, 10, 9,111,117,116,104, 97,114, 32, 61, 32,104, 97,114, 47, 49, - 50, 56, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,104, 97,114, 95,109,117,108,116,105,112,108,121, 95, - 99,108, 97,109,112, 40,102,108,111, 97,116, 32,104, 97,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,104, 97, -114, 41, 10,123, 10, 9,104, 97,114, 32, 42, 61, 32, 49, 50, 56, 46, 48, 59, 10, 10, 9,105,102, 40,104, 97,114, 32, 60, 32, 49, - 46, 48, 41, 32,111,117,116,104, 97,114, 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40,104, 97,114, 32, 62, - 32, 53, 49, 49, 46, 48, 41, 32,111,117,116,104, 97,114, 32, 61, 32, 53, 49, 49, 46, 48, 59, 10, 9,101,108,115,101, 32,111,117, -116,104, 97,114, 32, 61, 32,104, 97,114, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 97,108,112,104, 97, 95,102, -114,111,109, 95, 99,111,108, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32, 97,108,112,104, - 97, 41, 10,123, 10, 9, 97,108,112,104, 97, 32, 61, 32, 99,111,108, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101, -120, 95, 97,108,112,104, 97, 95,116,111, 95, 99,111,108, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,102,108,111, 97,116, 32, 97, -108,112,104, 97, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, - 32, 61, 32,118,101, 99, 52, 40, 99,111,108, 46,114,103, 98, 44, 32, 97,108,112,104, 97, 41, 59, 10,125, 10, 10,118,111,105,100, - 32,109,116,101,120, 95,114,103, 98,116,111,105,110,116, 40,118,101, 99, 52, 32,114,103, 98, 44, 32,111,117,116, 32,102,108,111, - 97,116, 32,105,110,116,101,110,115,105,116,121, 41, 10,123, 10, 9,105,110,116,101,110,115,105,116,121, 32, 61, 32,100,111,116, - 40,118,101, 99, 51, 40, 48, 46, 51, 53, 44, 32, 48, 46, 52, 53, 44, 32, 48, 46, 50, 41, 44, 32,114,103, 98, 46,114,103, 98, 41, - 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,105,110,118,101,114,116, 40,102,108,111, 97, -116, 32,105,110,118, 97,108,117,101, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108,117,101, 41, 10,123, - 10, 9,111,117,116,118, 97,108,117,101, 32, 61, 32, 49, 46, 48, 32, 45, 32,105,110,118, 97,108,117,101, 59, 10,125, 10, 10,118, -111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,105,110,118,101,114,116, 40,118,101, 99, 52, 32,105,110,114,103, 98, 44, 32, -111,117,116, 32,118,101, 99, 52, 32,111,117,116,114,103, 98, 41, 10,123, 10, 9,111,117,116,114,103, 98, 32, 61, 32,118,101, 99, - 52, 40,118,101, 99, 51, 40, 49, 46, 48, 41, 32, 45, 32,105,110,114,103, 98, 46,114,103, 98, 44, 32,105,110,114,103, 98, 46, 97, - 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,115,116,101,110, 99,105,108, 40,102,108, -111, 97,116, 32,115,116,101,110, 99,105,108, 44, 32,102,108,111, 97,116, 32,105,110,116,101,110,115,105,116,121, 44, 32,111,117, -116, 32,102,108,111, 97,116, 32,111,117,116,115,116,101,110, 99,105,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117, -116,105,110,116,101,110,115,105,116,121, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,116, 32, 61, 32,105,110,116,101, -110,115,105,116,121, 59, 10, 9,111,117,116,105,110,116,101,110,115,105,116,121, 32, 61, 32,105,110,116,101,110,115,105,116,121, - 42,115,116,101,110, 99,105,108, 59, 10, 9,111,117,116,115,116,101,110, 99,105,108, 32, 61, 32,115,116,101,110, 99,105,108, 42, -102, 97, 99,116, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,115,116,101,110, 99,105,108, 40,102, -108,111, 97,116, 32,115,116,101,110, 99,105,108, 44, 32,118,101, 99, 52, 32,114,103, 98, 44, 32,111,117,116, 32,102,108,111, 97, -116, 32,111,117,116,115,116,101,110, 99,105,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116,114,103, 98, 41, 10,123, - 10, 9,102,108,111, 97,116, 32,102, 97, 99,116, 32, 61, 32,114,103, 98, 46, 97, 59, 10, 9,111,117,116,114,103, 98, 32, 61, 32, -118,101, 99, 52, 40,114,103, 98, 46,114,103, 98, 44, 32,114,103, 98, 46, 97, 42,115,116,101,110, 99,105,108, 41, 59, 10, 9,111, -117,116,115,116,101,110, 99,105,108, 32, 61, 32,115,116,101,110, 99,105,108, 42,102, 97, 99,116, 59, 10,125, 10, 10,118,111,105, -100, 32,109,116,101,120, 95,109, 97,112,112,105,110,103, 95,111,102,115, 40,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,118, -101, 99, 51, 32,111,102,115, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,116,101,120, 99,111, 41, 10,123, 10, 9,111, -117,116,116,101,120, 99,111, 32, 61, 32,116,101,120, 99,111, 32, 43, 32,111,102,115, 59, 10,125, 10, 10,118,111,105,100, 32,109, -116,101,120, 95,109, 97,112,112,105,110,103, 95,115,105,122,101, 40,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,118,101, 99, - 51, 32,115,105,122,101, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,116,101,120, 99,111, 41, 10,123, 10, 9,111,117, -116,116,101,120, 99,111, 32, 61, 32,115,105,122,101, 42,116,101,120, 99,111, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101, -120, 95, 50,100, 95,109, 97,112,112,105,110,103, 40,118,101, 99, 51, 32,118,101, 99, 44, 32,111,117,116, 32,118,101, 99, 51, 32, -111,117,116,118,101, 99, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32,118,101, 99, 51, 40,118,101, 99, 46,120,121, 42, - 48, 46, 53, 32, 43, 32,118,101, 99, 50, 40, 48, 46, 53, 44, 32, 48, 46, 53, 41, 44, 32,118,101, 99, 46,122, 41, 59, 10,125, 10, - 10,118,111,105,100, 32,109,116,101,120, 95,105,109, 97,103,101, 40,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,115, 97,109, -112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118, 97,108,117,101, 44, 32,111,117,116, - 32,118,101, 99, 52, 32, 99,111,108,111,114, 41, 10,123, 10, 9, 99,111,108,111,114, 32, 61, 32,116,101,120,116,117,114,101, 50, - 68, 40,105,109, 97, 44, 32,116,101,120, 99,111, 46,120,121, 41, 59, 10, 9,118, 97,108,117,101, 32, 61, 32, 49, 46, 48, 59, 10, -125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,110,111,114,109, 97,108, 40,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32, -115, 97,109,112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,111,117,116, 32,118,101, 99, 51, 32,110,111,114,109, 97,108, 41, 10, -123, 10, 9, 47, 47, 32, 84,104,101, 32,105,110,118,101,114,116, 32,111,102, 32,116,104,101, 32,114,101,100, 32, 99,104, 97,110, -110,101,108, 32,105,115, 32,116,111, 32,109, 97,107,101, 10, 9, 47, 47, 32,116,104,101, 32,110,111,114,109, 97,108, 32,109, 97, -112, 32, 99,111,109,112,108,105, 97,110,116, 32,119,105,116,104, 32,116,104,101, 32,111,117,116,115,105,100,101, 32,119,111,114, -108,100, 46, 10, 9, 47, 47, 32, 73,116, 32,110,101,101,100,115, 32,116,111, 32, 98,101, 32,100,111,110,101, 32, 98,101, 99, 97, -117,115,101, 32,105,110, 32, 66,108,101,110,100,101,114, 10, 9, 47, 47, 32,116,104,101, 32,110,111,114,109, 97,108, 32,117,115, -101,100, 32,112,111,105,110,116,115, 32,105,110,119, 97,114,100, 46, 10, 9, 47, 47, 32, 83,104,111,117,108,100, 32,116,104,105, -115, 32,101,118,101,114, 32, 99,104, 97,110,103,101, 32,116,104,105,115, 32,110,101,103, 97,116,101, 32,109,117,115,116, 32, 98, -101, 32,114,101,109,111,118,101,100, 46, 10, 32, 32, 32, 32,118,101, 99, 52, 32, 99,111,108,111,114, 32, 61, 32,116,101,120,116, -117,114,101, 50, 68, 40,105,109, 97, 44, 32,116,101,120, 99,111, 46,120,121, 41, 59, 10, 9,110,111,114,109, 97,108, 32, 61, 32, - 50, 46, 48, 42, 40,118,101, 99, 51, 40, 45, 99,111,108,111,114, 46,114, 44, 32, 99,111,108,111,114, 46,103, 44, 32, 99,111,108, -111,114, 46, 98, 41, 32, 45, 32,118,101, 99, 51, 40, 45, 48, 46, 53, 44, 32, 48, 46, 53, 44, 32, 48, 46, 53, 41, 41, 59, 10,125, - 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,117,109,112, 95,110,111,114,109, 97,108,115, 95,105,110,105,116, 40, 32,118, -101, 99, 51, 32,118, 78, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, 78,111,114,103, 44, 32,111,117,116, 32,118,101, 99, 51, - 32,118, 78, 97, 99, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, - 32, 41, 10,123, 10, 9,118, 78,111,114,103, 32, 61, 32,118, 78, 59, 10, 9,118, 78, 97, 99, 99, 32, 61, 32,118, 78, 59, 10, 9, -102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10, 47, 42, 42, 32,104,101,108, -112,101,114, 32,109,101,116,104,111,100, 32,116,111, 32,101,120,116,114, 97, 99,116, 32,116,104,101, 32,117,112,112,101,114, 32, -108,101,102,116, 32, 51,120, 51, 32,109, 97,116,114,105,120, 32,102,114,111,109, 32, 97, 32, 52,120, 52, 32,109, 97,116,114,105, -120, 32, 42, 47, 10,109, 97,116, 51, 32,116,111, 95,109, 97,116, 51, 40,109, 97,116, 52, 32,109, 52, 41, 10,123, 10, 9,109, 97, -116, 51, 32,109, 51, 59, 10, 9,109, 51, 91, 48, 93, 32, 61, 32,109, 52, 91, 48, 93, 46,120,121,122, 59, 10, 9,109, 51, 91, 49, - 93, 32, 61, 32,109, 52, 91, 49, 93, 46,120,121,122, 59, 10, 9,109, 51, 91, 50, 93, 32, 61, 32,109, 52, 91, 50, 93, 46,120,121, -122, 59, 10, 9,114,101,116,117,114,110, 32,109, 51, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,117,109,112, - 95,105,110,105,116, 95,111, 98,106,115,112, 97, 99,101, 40, 32,118,101, 99, 51, 32,115,117,114,102, 95,112,111,115, 44, 32,118, -101, 99, 51, 32,115,117,114,102, 95,110,111,114,109, 44, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32,109, 97,116, 52, 32,109, 86,105, -101,119, 44, 32,109, 97,116, 52, 32,109, 86,105,101,119, 73,110,118, 44, 32,109, 97,116, 52, 32,109, 79, 98,106, 44, 32,109, 97, -116, 52, 32,109, 79, 98,106, 73,110,118, 44, 32, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32,102,108,111, 97,116, 32,102, 80,114,101, -118, 77, 97,103,110,105,116,117,100,101, 95,105,110, 44, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,105,110, 44, 10, 9, 9, - 9, 9, 9, 9, 9, 32, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95, -111,117,116, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,111,117,116, 44, 32, 10, 9, 9, 9, 9, 9, 9, - 9, 32, 32,111,117,116, 32,118,101, 99, 51, 32,118, 82, 49, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, 82, 50, 44, 32,111, -117,116, 32,102,108,111, 97,116, 32,102, 68,101,116, 32, 41, 32, 10,123, 10, 9,109, 97,116, 51, 32,111, 98,106, 50,118,105,101, -119, 32, 61, 32,116,111, 95,109, 97,116, 51, 40,109, 86,105,101,119, 32, 42, 32,109, 79, 98,106, 41, 59, 10, 9,109, 97,116, 51, - 32,118,105,101,119, 50,111, 98,106, 32, 61, 32,116,111, 95,109, 97,116, 51, 40,109, 79, 98,106, 73,110,118, 32, 42, 32,109, 86, -105,101,119, 73,110,118, 41, 59, 10, 9, 10, 9,118,101, 99, 51, 32,118, 83,105,103,109, 97, 83, 32, 61, 32,118,105,101,119, 50, -111, 98,106, 32, 42, 32,100, 70,100,120, 40, 32,115,117,114,102, 95,112,111,115, 32, 41, 59, 10, 9,118,101, 99, 51, 32,118, 83, -105,103,109, 97, 84, 32, 61, 32,118,105,101,119, 50,111, 98,106, 32, 42, 32,100, 70,100,121, 40, 32,115,117,114,102, 95,112,111, -115, 32, 41, 59, 10, 9,118,101, 99, 51, 32,118, 78, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 32,115,117,114,102, 95, -110,111,114,109, 32, 42, 32,111, 98,106, 50,118,105,101,119, 32, 41, 59, 10, 10, 9,118, 82, 49, 32, 61, 32, 99,114,111,115,115, - 40, 32,118, 83,105,103,109, 97, 84, 44, 32,118, 78, 32, 41, 59, 10, 9,118, 82, 50, 32, 61, 32, 99,114,111,115,115, 40, 32,118, - 78, 44, 32,118, 83,105,103,109, 97, 83, 32, 41, 32, 59, 10, 9,102, 68,101,116, 32, 61, 32,100,111,116, 32, 40, 32,118, 83,105, -103,109, 97, 83, 44, 32,118, 82, 49, 32, 41, 59, 10, 9, 10, 9, 47, 42, 32,112,114,101,116,114, 97,110,115,102,111,114,109, 32, -118, 78, 97, 99, 99, 32, 40,105,110, 32,109,116,101,120, 95, 98,117,109,112, 95, 97,112,112,108,121, 41, 32,117,115,105,110,103, - 32,116,104,101, 32,105,110,118,101,114,115,101, 32,116,114, 97,110,115,112,111,115,101,100, 32, 42, 47, 10, 9,118, 82, 49, 32, - 61, 32,118, 82, 49, 32, 42, 32,118,105,101,119, 50,111, 98,106, 59, 10, 9,118, 82, 50, 32, 61, 32,118, 82, 50, 32, 42, 32,118, -105,101,119, 50,111, 98,106, 59, 10, 9,118, 78, 32, 61, 32,118, 78, 32, 42, 32,118,105,101,119, 50,111, 98,106, 59, 10, 9, 10, - 9,102,108,111, 97,116, 32,102, 77, 97,103,110,105,116,117,100,101, 32, 61, 32, 97, 98,115, 40,102, 68,101,116, 41, 32, 42, 32, -108,101,110,103,116,104, 40,118, 78, 41, 59, 10, 9,118, 78, 97, 99, 99, 95,111,117,116, 32, 61, 32,118, 78, 97, 99, 99, 95,105, -110, 32, 42, 32, 40,102, 77, 97,103,110,105,116,117,100,101, 32, 47, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, - 95,105,110, 41, 59, 10, 9,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,111,117,116, 32, 61, 32,102, 77, 97,103, -110,105,116,117,100,101, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,117,109,112, 95,105,110,105,116, 95,116, -101,120,116,117,114,101,115,112, 97, 99,101, 40, 32,118,101, 99, 51, 32,115,117,114,102, 95,112,111,115, 44, 32,118,101, 99, 51, - 32,115,117,114,102, 95,110,111,114,109, 44, 32, 10, 9, 9, 9, 9, 9, 9, 9, 9, 32, 32,102,108,111, 97,116, 32,102, 80,114, -101,118, 77, 97,103,110,105,116,117,100,101, 95,105,110, 44, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,105,110, 44, 10, 9, - 9, 9, 9, 9, 9, 9, 9, 32, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100, -101, 95,111,117,116, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,111,117,116, 44, 32, 10, 9, 9, 9, 9, - 9, 9, 9, 9, 32, 32,111,117,116, 32,118,101, 99, 51, 32,118, 82, 49, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, 82, 50, - 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 68,101,116, 32, 41, 32, 10,123, 10, 9,118,101, 99, 51, 32,118, 83,105,103, -109, 97, 83, 32, 61, 32,100, 70,100,120, 40, 32,115,117,114,102, 95,112,111,115, 32, 41, 59, 10, 9,118,101, 99, 51, 32,118, 83, -105,103,109, 97, 84, 32, 61, 32,100, 70,100,121, 40, 32,115,117,114,102, 95,112,111,115, 32, 41, 59, 10, 9,118,101, 99, 51, 32, -118, 78, 32, 61, 32,115,117,114,102, 95,110,111,114,109, 59, 32, 47, 42, 32,110,111,114,109, 97,108,105,122,101,100, 32,105,110, -116,101,114,112,111,108, 97,116,101,100, 32,118,101,114,116,101,120, 32,110,111,114,109, 97,108, 32, 42, 47, 10, 9, 10, 9,118, - 82, 49, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 32, 99,114,111,115,115, 40, 32,118, 83,105,103,109, 97, 84, 44, 32, -118, 78, 32, 41, 32, 41, 59, 10, 9,118, 82, 50, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 32, 99,114,111,115,115, 40, - 32,118, 78, 44, 32,118, 83,105,103,109, 97, 83, 32, 41, 32, 41, 59, 10, 9,102, 68,101,116, 32, 61, 32,115,105,103,110, 40, 32, -100,111,116, 40,118, 83,105,103,109, 97, 83, 44, 32,118, 82, 49, 41, 32, 41, 59, 10, 9, 10, 9,102,108,111, 97,116, 32,102, 77, - 97,103,110,105,116,117,100,101, 32, 61, 32, 97, 98,115, 40,102, 68,101,116, 41, 59, 10, 9,118, 78, 97, 99, 99, 95,111,117,116, - 32, 61, 32,118, 78, 97, 99, 99, 95,105,110, 32, 42, 32, 40,102, 77, 97,103,110,105,116,117,100,101, 32, 47, 32,102, 80,114,101, -118, 77, 97,103,110,105,116,117,100,101, 95,105,110, 41, 59, 10, 9,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95, -111,117,116, 32, 61, 32,102, 77, 97,103,110,105,116,117,100,101, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98, -117,109,112, 95,105,110,105,116, 95,118,105,101,119,115,112, 97, 99,101, 40, 32,118,101, 99, 51, 32,115,117,114,102, 95,112,111, -115, 44, 32,118,101, 99, 51, 32,115,117,114,102, 95,110,111,114,109, 44, 32, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32, 32,102,108, -111, 97,116, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,105,110, 44, 32,118,101, 99, 51, 32,118, 78, 97, 99, - 99, 95,105,110, 44, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 80,114,101,118, 77, - 97,103,110,105,116,117,100,101, 95,111,117,116, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,111,117,116, - 44, 32, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32, 32,111,117,116, 32,118,101, 99, 51, 32,118, 82, 49, 44, 32,111,117,116, 32,118, -101, 99, 51, 32,118, 82, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 68,101,116, 32, 41, 32, 10,123, 10, 9,118,101, - 99, 51, 32,118, 83,105,103,109, 97, 83, 32, 61, 32,100, 70,100,120, 40, 32,115,117,114,102, 95,112,111,115, 32, 41, 59, 10, 9, -118,101, 99, 51, 32,118, 83,105,103,109, 97, 84, 32, 61, 32,100, 70,100,121, 40, 32,115,117,114,102, 95,112,111,115, 32, 41, 59, - 10, 9,118,101, 99, 51, 32,118, 78, 32, 61, 32,115,117,114,102, 95,110,111,114,109, 59, 32, 47, 42, 32,110,111,114,109, 97,108, -105,122,101,100, 32,105,110,116,101,114,112,111,108, 97,116,101,100, 32,118,101,114,116,101,120, 32,110,111,114,109, 97,108, 32, - 42, 47, 10, 9, 10, 9,118, 82, 49, 32, 61, 32, 99,114,111,115,115, 40, 32,118, 83,105,103,109, 97, 84, 44, 32,118, 78, 32, 41, - 59, 10, 9,118, 82, 50, 32, 61, 32, 99,114,111,115,115, 40, 32,118, 78, 44, 32,118, 83,105,103,109, 97, 83, 32, 41, 32, 59, 10, - 9,102, 68,101,116, 32, 61, 32,100,111,116, 32, 40, 32,118, 83,105,103,109, 97, 83, 44, 32,118, 82, 49, 32, 41, 59, 10, 9, 10, - 9,102,108,111, 97,116, 32,102, 77, 97,103,110,105,116,117,100,101, 32, 61, 32, 97, 98,115, 40,102, 68,101,116, 41, 59, 10, 9, -118, 78, 97, 99, 99, 95,111,117,116, 32, 61, 32,118, 78, 97, 99, 99, 95,105,110, 32, 42, 32, 40,102, 77, 97,103,110,105,116,117, -100,101, 32, 47, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,105,110, 41, 59, 10, 9,102, 80,114,101,118, 77, - 97,103,110,105,116,117,100,101, 95,111,117,116, 32, 61, 32,102, 77, 97,103,110,105,116,117,100,101, 59, 10,125, 10, 10,118,111, -105,100, 32,109,116,101,120, 95, 98,117,109,112, 95,116, 97,112, 51, 40, 32,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,115, - 97,109,112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,102,108,111, 97,116, 32,104, 83, 99, 97,108,101, 44, 32, 10, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,111,117,116, 32,102,108,111, 97,116, 32,100, 66,115, 44, - 32,111,117,116, 32,102,108,111, 97,116, 32,100, 66,116, 32, 41, 32, 10,123, 10, 9,118,101, 99, 50, 32, 83, 84,108,108, 32, 61, - 32,116,101,120, 99,111, 46,120,121, 59, 10, 9,118,101, 99, 50, 32, 83, 84,108,114, 32, 61, 32,116,101,120, 99,111, 46,120,121, - 32, 43, 32,100, 70,100,120, 40,116,101,120, 99,111, 46,120,121, 41, 32, 59, 10, 9,118,101, 99, 50, 32, 83, 84,117,108, 32, 61, - 32,116,101,120, 99,111, 46,120,121, 32, 43, 32,100, 70,100,121, 40,116,101,120, 99,111, 46,120,121, 41, 32, 59, 10, 9, 10, 9, -102,108,111, 97,116, 32, 72,108,108, 44, 72,108,114, 44, 72,117,108, 59, 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101,120, -116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,108,108, 41, 44, 32, 72,108,108, 32, 41, 59, 10, 9,114,103, 98,116,111, - 98,119, 40, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,108,114, 41, 44, 32, 72,108,114, 32, 41, 59, - 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,117,108, 41, 44, - 32, 72,117,108, 32, 41, 59, 10, 9, 10, 9,100, 66,115, 32, 61, 32,104, 83, 99, 97,108,101, 32, 42, 32, 40, 72,108,114, 32, 45, - 32, 72,108,108, 41, 59, 10, 9,100, 66,116, 32, 61, 32,104, 83, 99, 97,108,101, 32, 42, 32, 40, 72,117,108, 32, 45, 32, 72,108, -108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,117,109,112, 95,116, 97,112, 53, 40, 32,118,101, 99, 51, - 32,116,101,120, 99,111, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,102,108,111, 97,116, 32,104, 83, 99, - 97,108,101, 44, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,111,117,116, 32,102, -108,111, 97,116, 32,100, 66,115, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,100, 66,116, 32, 41, 32, 10,123, 10, 9,118,101, - 99, 50, 32, 84,101,120, 68,120, 32, 61, 32,100, 70,100,120, 40,116,101,120, 99,111, 46,120,121, 41, 59, 10, 9,118,101, 99, 50, - 32, 84,101,120, 68,121, 32, 61, 32,100, 70,100,121, 40,116,101,120, 99,111, 46,120,121, 41, 59, 10, 10, 9,118,101, 99, 50, 32, - 83, 84, 99, 32, 61, 32,116,101,120, 99,111, 46,120,121, 59, 10, 9,118,101, 99, 50, 32, 83, 84,108, 32, 61, 32,116,101,120, 99, -111, 46,120,121, 32, 45, 32, 48, 46, 53, 32, 42, 32, 84,101,120, 68,120, 32, 59, 10, 9,118,101, 99, 50, 32, 83, 84,114, 32, 61, - 32,116,101,120, 99,111, 46,120,121, 32, 43, 32, 48, 46, 53, 32, 42, 32, 84,101,120, 68,120, 32, 59, 10, 9,118,101, 99, 50, 32, - 83, 84,100, 32, 61, 32,116,101,120, 99,111, 46,120,121, 32, 45, 32, 48, 46, 53, 32, 42, 32, 84,101,120, 68,121, 32, 59, 10, 9, -118,101, 99, 50, 32, 83, 84,117, 32, 61, 32,116,101,120, 99,111, 46,120,121, 32, 43, 32, 48, 46, 53, 32, 42, 32, 84,101,120, 68, -121, 32, 59, 10, 9, 10, 9,102,108,111, 97,116, 32, 72, 99, 44, 72,108, 44, 72,114, 44, 72,100, 44, 72,117, 59, 10, 9,114,103, - 98,116,111, 98,119, 40, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84, 99, 41, 44, 32, 72, 99, 32, 41, - 59, 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,108, 41, 44, - 32, 72,108, 32, 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, - 83, 84,114, 41, 44, 32, 72,114, 32, 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101,120,116,117,114,101, 50, 68, 40, -105,109, 97, 44, 32, 83, 84,100, 41, 44, 32, 72,100, 32, 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101,120,116,117, -114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,117, 41, 44, 32, 72,117, 32, 41, 59, 10, 9, 10, 9,100, 66,115, 32, 61, 32,104, - 83, 99, 97,108,101, 32, 42, 32, 40, 72,114, 32, 45, 32, 72,108, 41, 59, 10, 9,100, 66,116, 32, 61, 32,104, 83, 99, 97,108,101, - 32, 42, 32, 40, 72,117, 32, 45, 32, 72,100, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,117,109,112, 95, -100,101,114,105,118, 40, 32,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32,105,109, 97, - 44, 32,102,108,111, 97,116, 32,105,109, 97, 95,120, 44, 32,102,108,111, 97,116, 32,105,109, 97, 95,121, 44, 32,102,108,111, 97, -116, 32,104, 83, 99, 97,108,101, 44, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, -111,117,116, 32,102,108,111, 97,116, 32,100, 66,115, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,100, 66,116, 32, 41, 32, 10, -123, 10, 9,102,108,111, 97,116, 32,115, 32, 61, 32, 49, 46, 48, 59, 9, 9, 47, 47, 32,110,101,103, 97,116,101, 32,116,104,105, -115, 32,105,102, 32,102,108,105,112,112,101,100, 32,116,101,120,116,117,114,101, 32, 99,111,111,114,100,105,110, 97,116,101, 10, - 9,118,101, 99, 50, 32, 84,101,120, 68,120, 32, 61, 32,100, 70,100,120, 40,116,101,120, 99,111, 46,120,121, 41, 59, 10, 9,118, -101, 99, 50, 32, 84,101,120, 68,121, 32, 61, 32,100, 70,100,121, 40,116,101,120, 99,111, 46,120,121, 41, 59, 10, 9, 10, 9, 47, - 47, 32,116,104,105,115, 32,118, 97,114,105, 97,110,116, 32,117,115,105,110,103, 32, 97, 32,100,101,114,105,118, 97,116,105,118, -101, 32,109, 97,112, 32,105,115, 32,100,101,115, 99,114,105, 98,101,100, 32,104,101,114,101, 10, 9, 47, 47, 32,104,116,116,112, - 58, 47, 47,109,109,105,107,107,101,108,115,101,110, 51,100, 46, 98,108,111,103,115,112,111,116, 46, 99,111,109, 47, 50, 48, 49, - 49, 47, 48, 55, 47,100,101,114,105,118, 97,116,105,118,101, 45,109, 97,112,115, 46,104,116,109,108, 10, 9,118,101, 99, 50, 32, -100,105,109, 32, 61, 32,118,101, 99, 50, 40,105,109, 97, 95,120, 44, 32,105,109, 97, 95,121, 41, 59, 10, 9,118,101, 99, 50, 32, -100, 66,100,117,118, 32, 61, 32,104, 83, 99, 97,108,101, 42,100,105,109, 42, 40, 50, 46, 48, 42,116,101,120,116,117,114,101, 50, - 68, 40,105,109, 97, 44, 32,116,101,120, 99,111, 46,120,121, 41, 46,120,121, 45, 49, 46, 48, 41, 59, 10, 9, 10, 9,100, 66,115, - 32, 61, 32,100, 66,100,117,118, 46,120, 42, 84,101,120, 68,120, 46,120, 32, 43, 32,115, 42,100, 66,100,117,118, 46,121, 42, 84, -101,120, 68,120, 46,121, 59, 10, 9,100, 66,116, 32, 61, 32,100, 66,100,117,118, 46,120, 42, 84,101,120, 68,121, 46,120, 32, 43, - 32,115, 42,100, 66,100,117,118, 46,121, 42, 84,101,120, 68,121, 46,121, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, - 95, 98,117,109,112, 95, 97,112,112,108,121, 40, 32,102,108,111, 97,116, 32,102, 68,101,116, 44, 32,102,108,111, 97,116, 32,100, - 66,115, 44, 32,102,108,111, 97,116, 32,100, 66,116, 44, 32,118,101, 99, 51, 32,118, 82, 49, 44, 32,118,101, 99, 51, 32,118, 82, - 50, 44, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,105,110, 44, 10, 9, 9, 9, 9, 9, 32, 32,111,117,116, 32,118,101, 99, - 51, 32,118, 78, 97, 99, 99, 95,111,117,116, 44, 32,111,117,116, 32,118,101, 99, 51, 32,112,101,114,116,117,114, 98,101,100, 95, -110,111,114,109, 32, 41, 32, 10,123, 10, 9,118,101, 99, 51, 32,118, 83,117,114,102, 71,114, 97,100, 32, 61, 32,115,105,103,110, - 40,102, 68,101,116, 41, 32, 42, 32, 40, 32,100, 66,115, 32, 42, 32,118, 82, 49, 32, 43, 32,100, 66,116, 32, 42, 32,118, 82, 50, - 32, 41, 59, 10, 9, 10, 9,118, 78, 97, 99, 99, 95,111,117,116, 32, 61, 32,118, 78, 97, 99, 99, 95,105,110, 32, 45, 32,118, 83, -117,114,102, 71,114, 97,100, 59, 10, 9,112,101,114,116,117,114, 98,101,100, 95,110,111,114,109, 32, 61, 32,110,111,114,109, 97, -108,105,122,101, 40, 32,118, 78, 97, 99, 99, 95,111,117,116, 32, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, - 98,117,109,112, 95, 97,112,112,108,121, 95,116,101,120,115,112, 97, 99,101, 40, 32,102,108,111, 97,116, 32,102, 68,101,116, 44, - 32,102,108,111, 97,116, 32,100, 66,115, 44, 32,102,108,111, 97,116, 32,100, 66,116, 44, 32,118,101, 99, 51, 32,118, 82, 49, 44, - 32,118,101, 99, 51, 32,118, 82, 50, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115, 97,109,112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,118,101, 99, 51, 32,116,101, -120, 99,111, 44, 32,102,108,111, 97,116, 32,105,109, 97, 95,120, 44, 32,102,108,111, 97,116, 32,105,109, 97, 95,121, 44, 32,118, -101, 99, 51, 32,118, 78, 97, 99, 99, 95,105,110, 44, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32, 32,111,117,116, 32,118,101, 99, 51, - 32,118, 78, 97, 99, 99, 95,111,117,116, 44, 32,111,117,116, 32,118,101, 99, 51, 32,112,101,114,116,117,114, 98,101,100, 95,110, -111,114,109, 32, 41, 32, 10,123, 10, 9,118,101, 99, 50, 32, 84,101,120, 68,120, 32, 61, 32,100, 70,100,120, 40,116,101,120, 99, -111, 46,120,121, 41, 59, 10, 9,118,101, 99, 50, 32, 84,101,120, 68,121, 32, 61, 32,100, 70,100,121, 40,116,101,120, 99,111, 46, -120,121, 41, 59, 10, 10, 9,118,101, 99, 51, 32,118, 83,117,114,102, 71,114, 97,100, 32, 61, 32,115,105,103,110, 40,102, 68,101, -116, 41, 32, 42, 32, 40, 32, 10, 9, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,100, 66,115, 32, 47, 32,108,101,110,103,116, -104, 40, 32,118,101, 99, 50, 40,105,109, 97, 95,120, 42, 84,101,120, 68,120, 46,120, 44, 32,105,109, 97, 95,121, 42, 84,101,120, - 68,120, 46,121, 41, 32, 41, 32, 42, 32,118, 82, 49, 32, 43, 32, 10, 9, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,100, 66, -116, 32, 47, 32,108,101,110,103,116,104, 40, 32,118,101, 99, 50, 40,105,109, 97, 95,120, 42, 84,101,120, 68,121, 46,120, 44, 32, -105,109, 97, 95,121, 42, 84,101,120, 68,121, 46,121, 41, 32, 41, 32, 42, 32,118, 82, 50, 32, 41, 59, 10, 9, 9, 9, 9, 10, 9, -118, 78, 97, 99, 99, 95,111,117,116, 32, 61, 32,118, 78, 97, 99, 99, 95,105,110, 32, 45, 32,118, 83,117,114,102, 71,114, 97,100, - 59, 10, 9,112,101,114,116,117,114, 98,101,100, 95,110,111,114,109, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 32,118, - 78, 97, 99, 99, 95,111,117,116, 32, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,110,101,103, 97,116,101, 95, -116,101,120,110,111,114,109, 97,108, 40,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32, -111,117,116,110,111,114,109, 97,108, 41, 10,123, 10, 9,111,117,116,110,111,114,109, 97,108, 32, 61, 32,118,101, 99, 51, 40, 45, -110,111,114,109, 97,108, 46,120, 44, 32, 45,110,111,114,109, 97,108, 46,121, 44, 32,110,111,114,109, 97,108, 46,122, 41, 59, 10, -125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,110,115,112, 97, 99,101, 95,116, 97,110,103,101,110,116, 40,118,101, 99, 52, - 32,116, 97,110,103,101,110,116, 44, 32,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,118,101, 99, 51, 32,116,101,120,110, -111,114,109, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,110,111,114,109, 97,108, 41, 10,123, 10, 9,118,101, - 99, 51, 32, 66, 32, 61, 32,116, 97,110,103,101,110,116, 46,119, 32, 42, 32, 99,114,111,115,115, 40,110,111,114,109, 97,108, 44, - 32,116, 97,110,103,101,110,116, 46,120,121,122, 41, 59, 10, 10, 9,111,117,116,110,111,114,109, 97,108, 32, 61, 32,116,101,120, -110,111,114,109, 97,108, 46,120, 42,116, 97,110,103,101,110,116, 46,120,121,122, 32, 43, 32,116,101,120,110,111,114,109, 97,108, - 46,121, 42, 66, 32, 43, 32,116,101,120,110,111,114,109, 97,108, 46,122, 42,110,111,114,109, 97,108, 59, 10, 9,111,117,116,110, + 97, 99,109, 42,111,117,116, 99,111,108, 32, 43, 32,102, 97, 99,116, 42, 97, 98,115, 40,116,101,120, 99,111,108, 32, 45, 32,111, +117,116, 99,111,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,100, 97,114,107, 40, +102,108,111, 97,116, 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97, +116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, + 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95, +118, 97,114,115, 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,102,108,111, 97,116, 32, + 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 59, 10, 9,105,102, 40, 99,111,108, 32, 60, 32,111,117,116, + 99,111,108, 41, 32,105,110, 99,111,108, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 32, 61, 32,111, +117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,108,105,103,104,116, 40, +102,108,111, 97,116, 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97, +116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, + 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95, +118, 97,114,115, 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,102,108,111, 97,116, 32, + 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 59, 10, 9,105,102, 40, 99,111,108, 32, 62, 32,111,117,116, + 99,111,108, 41, 32,105,110, 99,111,108, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 32, 61, 32,111, +117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95, 99,108, 97,109,112, 95, +112,111,115,105,116,105,118,101, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117, +116,102, 97, 99, 41, 10,123, 10, 9,111,117,116,102, 97, 99, 32, 61, 32,109, 97,120, 40,102, 97, 99, 44, 32, 48, 46, 48, 41, 59, + 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95, 99,108, 97,109,112, 40,102,108,111, 97,116, 32, +102, 97, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,102, 97, 99, 41, 10,123, 10, 9,111,117,116,102, 97, 99, + 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, + 32,109,116,101,120, 95,104, 97,114, 95,100,105,118,105,100,101, 40,102,108,111, 97,116, 32,104, 97,114, 44, 32,111,117,116, 32, +102,108,111, 97,116, 32,111,117,116,104, 97,114, 41, 10,123, 10, 9,111,117,116,104, 97,114, 32, 61, 32,104, 97,114, 47, 49, 50, + 56, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,104, 97,114, 95,109,117,108,116,105,112,108,121, 95, 99, +108, 97,109,112, 40,102,108,111, 97,116, 32,104, 97,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,104, 97,114, + 41, 10,123, 10, 9,104, 97,114, 32, 42, 61, 32, 49, 50, 56, 46, 48, 59, 10, 10, 9,105,102, 40,104, 97,114, 32, 60, 32, 49, 46, + 48, 41, 32,111,117,116,104, 97,114, 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40,104, 97,114, 32, 62, 32, + 53, 49, 49, 46, 48, 41, 32,111,117,116,104, 97,114, 32, 61, 32, 53, 49, 49, 46, 48, 59, 10, 9,101,108,115,101, 32,111,117,116, +104, 97,114, 32, 61, 32,104, 97,114, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 97,108,112,104, 97, 95,102,114, +111,109, 95, 99,111,108, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32, 97,108,112,104, 97, + 41, 10,123, 10, 9, 97,108,112,104, 97, 32, 61, 32, 99,111,108, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, + 95, 97,108,112,104, 97, 95,116,111, 95, 99,111,108, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,102,108,111, 97,116, 32, 97,108, +112,104, 97, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, + 61, 32,118,101, 99, 52, 40, 99,111,108, 46,114,103, 98, 44, 32, 97,108,112,104, 97, 41, 59, 10,125, 10, 10,118,111,105,100, 32, +109,116,101,120, 95,114,103, 98,116,111,105,110,116, 40,118,101, 99, 52, 32,114,103, 98, 44, 32,111,117,116, 32,102,108,111, 97, +116, 32,105,110,116,101,110,115,105,116,121, 41, 10,123, 10, 9,105,110,116,101,110,115,105,116,121, 32, 61, 32,100,111,116, 40, +118,101, 99, 51, 40, 48, 46, 51, 53, 44, 32, 48, 46, 52, 53, 44, 32, 48, 46, 50, 41, 44, 32,114,103, 98, 46,114,103, 98, 41, 59, + 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,105,110,118,101,114,116, 40,102,108,111, 97,116, + 32,105,110,118, 97,108,117,101, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108,117,101, 41, 10,123, 10, + 9,111,117,116,118, 97,108,117,101, 32, 61, 32, 49, 46, 48, 32, 45, 32,105,110,118, 97,108,117,101, 59, 10,125, 10, 10,118,111, +105,100, 32,109,116,101,120, 95,114,103, 98, 95,105,110,118,101,114,116, 40,118,101, 99, 52, 32,105,110,114,103, 98, 44, 32,111, +117,116, 32,118,101, 99, 52, 32,111,117,116,114,103, 98, 41, 10,123, 10, 9,111,117,116,114,103, 98, 32, 61, 32,118,101, 99, 52, + 40,118,101, 99, 51, 40, 49, 46, 48, 41, 32, 45, 32,105,110,114,103, 98, 46,114,103, 98, 44, 32,105,110,114,103, 98, 46, 97, 41, + 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,115,116,101,110, 99,105,108, 40,102,108,111, + 97,116, 32,115,116,101,110, 99,105,108, 44, 32,102,108,111, 97,116, 32,105,110,116,101,110,115,105,116,121, 44, 32,111,117,116, + 32,102,108,111, 97,116, 32,111,117,116,115,116,101,110, 99,105,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116, +105,110,116,101,110,115,105,116,121, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,116, 32, 61, 32,105,110,116,101,110, +115,105,116,121, 59, 10, 9,111,117,116,105,110,116,101,110,115,105,116,121, 32, 61, 32,105,110,116,101,110,115,105,116,121, 42, +115,116,101,110, 99,105,108, 59, 10, 9,111,117,116,115,116,101,110, 99,105,108, 32, 61, 32,115,116,101,110, 99,105,108, 42,102, + 97, 99,116, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,115,116,101,110, 99,105,108, 40,102,108, +111, 97,116, 32,115,116,101,110, 99,105,108, 44, 32,118,101, 99, 52, 32,114,103, 98, 44, 32,111,117,116, 32,102,108,111, 97,116, + 32,111,117,116,115,116,101,110, 99,105,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116,114,103, 98, 41, 10,123, 10, + 9,102,108,111, 97,116, 32,102, 97, 99,116, 32, 61, 32,114,103, 98, 46, 97, 59, 10, 9,111,117,116,114,103, 98, 32, 61, 32,118, +101, 99, 52, 40,114,103, 98, 46,114,103, 98, 44, 32,114,103, 98, 46, 97, 42,115,116,101,110, 99,105,108, 41, 59, 10, 9,111,117, +116,115,116,101,110, 99,105,108, 32, 61, 32,115,116,101,110, 99,105,108, 42,102, 97, 99,116, 59, 10,125, 10, 10,118,111,105,100, + 32,109,116,101,120, 95,109, 97,112,112,105,110,103, 95,111,102,115, 40,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,118,101, + 99, 51, 32,111,102,115, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,116,101,120, 99,111, 41, 10,123, 10, 9,111,117, +116,116,101,120, 99,111, 32, 61, 32,116,101,120, 99,111, 32, 43, 32,111,102,115, 59, 10,125, 10, 10,118,111,105,100, 32,109,116, +101,120, 95,109, 97,112,112,105,110,103, 95,115,105,122,101, 40,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,118,101, 99, 51, + 32,115,105,122,101, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,116,101,120, 99,111, 41, 10,123, 10, 9,111,117,116, +116,101,120, 99,111, 32, 61, 32,115,105,122,101, 42,116,101,120, 99,111, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, + 95, 50,100, 95,109, 97,112,112,105,110,103, 40,118,101, 99, 51, 32,118,101, 99, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111, +117,116,118,101, 99, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32,118,101, 99, 51, 40,118,101, 99, 46,120,121, 42, 48, + 46, 53, 32, 43, 32,118,101, 99, 50, 40, 48, 46, 53, 44, 32, 48, 46, 53, 41, 44, 32,118,101, 99, 46,122, 41, 59, 10,125, 10, 10, +118,111,105,100, 32,109,116,101,120, 95,105,109, 97,103,101, 40,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,115, 97,109,112, +108,101,114, 50, 68, 32,105,109, 97, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118, 97,108,117,101, 44, 32,111,117,116, 32, +118,101, 99, 52, 32, 99,111,108,111,114, 41, 10,123, 10, 9, 99,111,108,111,114, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, + 40,105,109, 97, 44, 32,116,101,120, 99,111, 46,120,121, 41, 59, 10, 9,118, 97,108,117,101, 32, 61, 32, 49, 46, 48, 59, 10,125, + 10, 10,118,111,105,100, 32,109,116,101,120, 95,110,111,114,109, 97,108, 40,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,115, + 97,109,112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,111,117,116, 32,118,101, 99, 51, 32,110,111,114,109, 97,108, 41, 10,123, + 10, 9, 47, 47, 32, 84,104,101, 32,105,110,118,101,114,116, 32,111,102, 32,116,104,101, 32,114,101,100, 32, 99,104, 97,110,110, +101,108, 32,105,115, 32,116,111, 32,109, 97,107,101, 10, 9, 47, 47, 32,116,104,101, 32,110,111,114,109, 97,108, 32,109, 97,112, + 32, 99,111,109,112,108,105, 97,110,116, 32,119,105,116,104, 32,116,104,101, 32,111,117,116,115,105,100,101, 32,119,111,114,108, +100, 46, 10, 9, 47, 47, 32, 73,116, 32,110,101,101,100,115, 32,116,111, 32, 98,101, 32,100,111,110,101, 32, 98,101, 99, 97,117, +115,101, 32,105,110, 32, 66,108,101,110,100,101,114, 10, 9, 47, 47, 32,116,104,101, 32,110,111,114,109, 97,108, 32,117,115,101, +100, 32,112,111,105,110,116,115, 32,105,110,119, 97,114,100, 46, 10, 9, 47, 47, 32, 83,104,111,117,108,100, 32,116,104,105,115, + 32,101,118,101,114, 32, 99,104, 97,110,103,101, 32,116,104,105,115, 32,110,101,103, 97,116,101, 32,109,117,115,116, 32, 98,101, + 32,114,101,109,111,118,101,100, 46, 10, 32, 32, 32, 32,118,101, 99, 52, 32, 99,111,108,111,114, 32, 61, 32,116,101,120,116,117, +114,101, 50, 68, 40,105,109, 97, 44, 32,116,101,120, 99,111, 46,120,121, 41, 59, 10, 9,110,111,114,109, 97,108, 32, 61, 32, 50, + 46, 48, 42, 40,118,101, 99, 51, 40, 45, 99,111,108,111,114, 46,114, 44, 32, 99,111,108,111,114, 46,103, 44, 32, 99,111,108,111, +114, 46, 98, 41, 32, 45, 32,118,101, 99, 51, 40, 45, 48, 46, 53, 44, 32, 48, 46, 53, 44, 32, 48, 46, 53, 41, 41, 59, 10,125, 10, + 10,118,111,105,100, 32,109,116,101,120, 95, 98,117,109,112, 95,110,111,114,109, 97,108,115, 95,105,110,105,116, 40, 32,118,101, + 99, 51, 32,118, 78, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, 78,111,114,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32, +118, 78, 97, 99, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 32, + 41, 10,123, 10, 9,118, 78,111,114,103, 32, 61, 32,118, 78, 59, 10, 9,118, 78, 97, 99, 99, 32, 61, 32,118, 78, 59, 10, 9,102, + 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10, 47, 42, 42, 32,104,101,108,112, +101,114, 32,109,101,116,104,111,100, 32,116,111, 32,101,120,116,114, 97, 99,116, 32,116,104,101, 32,117,112,112,101,114, 32,108, +101,102,116, 32, 51,120, 51, 32,109, 97,116,114,105,120, 32,102,114,111,109, 32, 97, 32, 52,120, 52, 32,109, 97,116,114,105,120, + 32, 42, 47, 10,109, 97,116, 51, 32,116,111, 95,109, 97,116, 51, 40,109, 97,116, 52, 32,109, 52, 41, 10,123, 10, 9,109, 97,116, + 51, 32,109, 51, 59, 10, 9,109, 51, 91, 48, 93, 32, 61, 32,109, 52, 91, 48, 93, 46,120,121,122, 59, 10, 9,109, 51, 91, 49, 93, + 32, 61, 32,109, 52, 91, 49, 93, 46,120,121,122, 59, 10, 9,109, 51, 91, 50, 93, 32, 61, 32,109, 52, 91, 50, 93, 46,120,121,122, + 59, 10, 9,114,101,116,117,114,110, 32,109, 51, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,117,109,112, 95, +105,110,105,116, 95,111, 98,106,115,112, 97, 99,101, 40, 32,118,101, 99, 51, 32,115,117,114,102, 95,112,111,115, 44, 32,118,101, + 99, 51, 32,115,117,114,102, 95,110,111,114,109, 44, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32,109, 97,116, 52, 32,109, 86,105,101, +119, 44, 32,109, 97,116, 52, 32,109, 86,105,101,119, 73,110,118, 44, 32,109, 97,116, 52, 32,109, 79, 98,106, 44, 32,109, 97,116, + 52, 32,109, 79, 98,106, 73,110,118, 44, 32, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32,102,108,111, 97,116, 32,102, 80,114,101,118, + 77, 97,103,110,105,116,117,100,101, 95,105,110, 44, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,105,110, 44, 10, 9, 9, 9, + 9, 9, 9, 9, 32, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,111, +117,116, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,111,117,116, 44, 32, 10, 9, 9, 9, 9, 9, 9, 9, + 32, 32,111,117,116, 32,118,101, 99, 51, 32,118, 82, 49, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, 82, 50, 44, 32,111,117, +116, 32,102,108,111, 97,116, 32,102, 68,101,116, 32, 41, 32, 10,123, 10, 9,109, 97,116, 51, 32,111, 98,106, 50,118,105,101,119, + 32, 61, 32,116,111, 95,109, 97,116, 51, 40,103,108, 95, 77,111,100,101,108, 86,105,101,119, 77, 97,116,114,105,120, 41, 59, 10, + 9,109, 97,116, 51, 32,118,105,101,119, 50,111, 98,106, 32, 61, 32,116,111, 95,109, 97,116, 51, 40,103,108, 95, 77,111,100,101, +108, 86,105,101,119, 77, 97,116,114,105,120, 73,110,118,101,114,115,101, 41, 59, 10, 9, 10, 9,118,101, 99, 51, 32,118, 83,105, +103,109, 97, 83, 32, 61, 32,118,105,101,119, 50,111, 98,106, 32, 42, 32,100, 70,100,120, 40, 32,115,117,114,102, 95,112,111,115, + 32, 41, 59, 10, 9,118,101, 99, 51, 32,118, 83,105,103,109, 97, 84, 32, 61, 32,118,105,101,119, 50,111, 98,106, 32, 42, 32,100, + 70,100,121, 40, 32,115,117,114,102, 95,112,111,115, 32, 41, 59, 10, 9,118,101, 99, 51, 32,118, 78, 32, 61, 32,110,111,114,109, + 97,108,105,122,101, 40, 32,115,117,114,102, 95,110,111,114,109, 32, 42, 32,111, 98,106, 50,118,105,101,119, 32, 41, 59, 10, 10, + 9,118, 82, 49, 32, 61, 32, 99,114,111,115,115, 40, 32,118, 83,105,103,109, 97, 84, 44, 32,118, 78, 32, 41, 59, 10, 9,118, 82, + 50, 32, 61, 32, 99,114,111,115,115, 40, 32,118, 78, 44, 32,118, 83,105,103,109, 97, 83, 32, 41, 32, 59, 10, 9,102, 68,101,116, + 32, 61, 32,100,111,116, 32, 40, 32,118, 83,105,103,109, 97, 83, 44, 32,118, 82, 49, 32, 41, 59, 10, 9, 10, 9, 47, 42, 32,112, +114,101,116,114, 97,110,115,102,111,114,109, 32,118, 78, 97, 99, 99, 32, 40,105,110, 32,109,116,101,120, 95, 98,117,109,112, 95, + 97,112,112,108,121, 41, 32,117,115,105,110,103, 32,116,104,101, 32,105,110,118,101,114,115,101, 32,116,114, 97,110,115,112,111, +115,101,100, 32, 42, 47, 10, 9,118, 82, 49, 32, 61, 32,118, 82, 49, 32, 42, 32,118,105,101,119, 50,111, 98,106, 59, 10, 9,118, + 82, 50, 32, 61, 32,118, 82, 50, 32, 42, 32,118,105,101,119, 50,111, 98,106, 59, 10, 9,118, 78, 32, 61, 32,118, 78, 32, 42, 32, +118,105,101,119, 50,111, 98,106, 59, 10, 9, 10, 9,102,108,111, 97,116, 32,102, 77, 97,103,110,105,116,117,100,101, 32, 61, 32, + 97, 98,115, 40,102, 68,101,116, 41, 32, 42, 32,108,101,110,103,116,104, 40,118, 78, 41, 59, 10, 9,118, 78, 97, 99, 99, 95,111, +117,116, 32, 61, 32,118, 78, 97, 99, 99, 95,105,110, 32, 42, 32, 40,102, 77, 97,103,110,105,116,117,100,101, 32, 47, 32,102, 80, +114,101,118, 77, 97,103,110,105,116,117,100,101, 95,105,110, 41, 59, 10, 9,102, 80,114,101,118, 77, 97,103,110,105,116,117,100, +101, 95,111,117,116, 32, 61, 32,102, 77, 97,103,110,105,116,117,100,101, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, + 95, 98,117,109,112, 95,105,110,105,116, 95,116,101,120,116,117,114,101,115,112, 97, 99,101, 40, 32,118,101, 99, 51, 32,115,117, +114,102, 95,112,111,115, 44, 32,118,101, 99, 51, 32,115,117,114,102, 95,110,111,114,109, 44, 32, 10, 9, 9, 9, 9, 9, 9, 9, + 9, 32, 32,102,108,111, 97,116, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,105,110, 44, 32,118,101, 99, 51, + 32,118, 78, 97, 99, 99, 95,105,110, 44, 10, 9, 9, 9, 9, 9, 9, 9, 9, 32, 32,111,117,116, 32,102,108,111, 97,116, 32,102, + 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,111,117,116, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, 78, 97, 99, + 99, 95,111,117,116, 44, 32, 10, 9, 9, 9, 9, 9, 9, 9, 9, 32, 32,111,117,116, 32,118,101, 99, 51, 32,118, 82, 49, 44, 32, +111,117,116, 32,118,101, 99, 51, 32,118, 82, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 68,101,116, 32, 41, 32, 10, +123, 10, 9,118,101, 99, 51, 32,118, 83,105,103,109, 97, 83, 32, 61, 32,100, 70,100,120, 40, 32,115,117,114,102, 95,112,111,115, + 32, 41, 59, 10, 9,118,101, 99, 51, 32,118, 83,105,103,109, 97, 84, 32, 61, 32,100, 70,100,121, 40, 32,115,117,114,102, 95,112, +111,115, 32, 41, 59, 10, 9,118,101, 99, 51, 32,118, 78, 32, 61, 32,115,117,114,102, 95,110,111,114,109, 59, 32, 47, 42, 32,110, +111,114,109, 97,108,105,122,101,100, 32,105,110,116,101,114,112,111,108, 97,116,101,100, 32,118,101,114,116,101,120, 32,110,111, +114,109, 97,108, 32, 42, 47, 10, 9, 10, 9,118, 82, 49, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 32, 99,114,111,115, +115, 40, 32,118, 83,105,103,109, 97, 84, 44, 32,118, 78, 32, 41, 32, 41, 59, 10, 9,118, 82, 50, 32, 61, 32,110,111,114,109, 97, +108,105,122,101, 40, 32, 99,114,111,115,115, 40, 32,118, 78, 44, 32,118, 83,105,103,109, 97, 83, 32, 41, 32, 41, 59, 10, 9,102, + 68,101,116, 32, 61, 32,115,105,103,110, 40, 32,100,111,116, 40,118, 83,105,103,109, 97, 83, 44, 32,118, 82, 49, 41, 32, 41, 59, + 10, 9, 10, 9,102,108,111, 97,116, 32,102, 77, 97,103,110,105,116,117,100,101, 32, 61, 32, 97, 98,115, 40,102, 68,101,116, 41, + 59, 10, 9,118, 78, 97, 99, 99, 95,111,117,116, 32, 61, 32,118, 78, 97, 99, 99, 95,105,110, 32, 42, 32, 40,102, 77, 97,103,110, +105,116,117,100,101, 32, 47, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,105,110, 41, 59, 10, 9,102, 80,114, +101,118, 77, 97,103,110,105,116,117,100,101, 95,111,117,116, 32, 61, 32,102, 77, 97,103,110,105,116,117,100,101, 59, 10,125, 10, + 10,118,111,105,100, 32,109,116,101,120, 95, 98,117,109,112, 95,105,110,105,116, 95,118,105,101,119,115,112, 97, 99,101, 40, 32, +118,101, 99, 51, 32,115,117,114,102, 95,112,111,115, 44, 32,118,101, 99, 51, 32,115,117,114,102, 95,110,111,114,109, 44, 32, 10, + 9, 9, 9, 9, 9, 9, 9, 32, 32, 32,102,108,111, 97,116, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,105, +110, 44, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,105,110, 44, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32, 32,111,117,116, 32, +102,108,111, 97,116, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,111,117,116, 44, 32,111,117,116, 32,118,101, + 99, 51, 32,118, 78, 97, 99, 99, 95,111,117,116, 44, 32, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32, 32,111,117,116, 32,118,101, 99, + 51, 32,118, 82, 49, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, 82, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102, + 68,101,116, 32, 41, 32, 10,123, 10, 9,118,101, 99, 51, 32,118, 83,105,103,109, 97, 83, 32, 61, 32,100, 70,100,120, 40, 32,115, +117,114,102, 95,112,111,115, 32, 41, 59, 10, 9,118,101, 99, 51, 32,118, 83,105,103,109, 97, 84, 32, 61, 32,100, 70,100,121, 40, + 32,115,117,114,102, 95,112,111,115, 32, 41, 59, 10, 9,118,101, 99, 51, 32,118, 78, 32, 61, 32,115,117,114,102, 95,110,111,114, +109, 59, 32, 47, 42, 32,110,111,114,109, 97,108,105,122,101,100, 32,105,110,116,101,114,112,111,108, 97,116,101,100, 32,118,101, +114,116,101,120, 32,110,111,114,109, 97,108, 32, 42, 47, 10, 9, 10, 9,118, 82, 49, 32, 61, 32, 99,114,111,115,115, 40, 32,118, + 83,105,103,109, 97, 84, 44, 32,118, 78, 32, 41, 59, 10, 9,118, 82, 50, 32, 61, 32, 99,114,111,115,115, 40, 32,118, 78, 44, 32, +118, 83,105,103,109, 97, 83, 32, 41, 32, 59, 10, 9,102, 68,101,116, 32, 61, 32,100,111,116, 32, 40, 32,118, 83,105,103,109, 97, + 83, 44, 32,118, 82, 49, 32, 41, 59, 10, 9, 10, 9,102,108,111, 97,116, 32,102, 77, 97,103,110,105,116,117,100,101, 32, 61, 32, + 97, 98,115, 40,102, 68,101,116, 41, 59, 10, 9,118, 78, 97, 99, 99, 95,111,117,116, 32, 61, 32,118, 78, 97, 99, 99, 95,105,110, + 32, 42, 32, 40,102, 77, 97,103,110,105,116,117,100,101, 32, 47, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95, +105,110, 41, 59, 10, 9,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,111,117,116, 32, 61, 32,102, 77, 97,103,110, +105,116,117,100,101, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,117,109,112, 95,116, 97,112, 51, 40, 32,118, +101, 99, 51, 32,116,101,120, 99,111, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,102,108,111, 97,116, 32, +104, 83, 99, 97,108,101, 44, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,111,117, +116, 32,102,108,111, 97,116, 32,100, 66,115, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,100, 66,116, 32, 41, 32, 10,123, 10, + 9,118,101, 99, 50, 32, 83, 84,108,108, 32, 61, 32,116,101,120, 99,111, 46,120,121, 59, 10, 9,118,101, 99, 50, 32, 83, 84,108, +114, 32, 61, 32,116,101,120, 99,111, 46,120,121, 32, 43, 32,100, 70,100,120, 40,116,101,120, 99,111, 46,120,121, 41, 32, 59, 10, + 9,118,101, 99, 50, 32, 83, 84,117,108, 32, 61, 32,116,101,120, 99,111, 46,120,121, 32, 43, 32,100, 70,100,121, 40,116,101,120, + 99,111, 46,120,121, 41, 32, 59, 10, 9, 10, 9,102,108,111, 97,116, 32, 72,108,108, 44, 72,108,114, 44, 72,117,108, 59, 10, 9, +114,103, 98,116,111, 98,119, 40, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,108,108, 41, 44, 32, 72, +108,108, 32, 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, + 84,108,114, 41, 44, 32, 72,108,114, 32, 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101,120,116,117,114,101, 50, 68, + 40,105,109, 97, 44, 32, 83, 84,117,108, 41, 44, 32, 72,117,108, 32, 41, 59, 10, 9, 10, 9,100, 66,115, 32, 61, 32,104, 83, 99, + 97,108,101, 32, 42, 32, 40, 72,108,114, 32, 45, 32, 72,108,108, 41, 59, 10, 9,100, 66,116, 32, 61, 32,104, 83, 99, 97,108,101, + 32, 42, 32, 40, 72,117,108, 32, 45, 32, 72,108,108, 41, 59, 10,125, 10, 10, 35,105,102,100,101,102, 32, 66, 85, 77, 80, 95, 66, + 73, 67, 85, 66, 73, 67, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,117,109,112, 95, 98,105, 99,117, 98,105, 99, 40, 32, +118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,102,108,111, 97,116, + 32,104, 83, 99, 97,108,101, 44, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,111, +117,116, 32,102,108,111, 97,116, 32,100, 66,115, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,100, 66,116, 32, 41, 32, 10,123, + 10, 9,102,108,111, 97,116, 32, 72,108, 59, 10, 9,102,108,111, 97,116, 32, 72,114, 59, 10, 9,102,108,111, 97,116, 32, 72,100, + 59, 10, 9,102,108,111, 97,116, 32, 72,117, 59, 10, 9, 10, 9,118,101, 99, 50, 32, 84,101,120, 68,120, 32, 61, 32,100, 70,100, +120, 40,116,101,120, 99,111, 46,120,121, 41, 59, 10, 9,118,101, 99, 50, 32, 84,101,120, 68,121, 32, 61, 32,100, 70,100,121, 40, +116,101,120, 99,111, 46,120,121, 41, 59, 10, 32, 10, 9,118,101, 99, 50, 32, 83, 84,108, 32, 61, 32,116,101,120, 99,111, 46,120, +121, 32, 45, 32, 48, 46, 53, 32, 42, 32, 84,101,120, 68,120, 32, 59, 10, 9,118,101, 99, 50, 32, 83, 84,114, 32, 61, 32,116,101, +120, 99,111, 46,120,121, 32, 43, 32, 48, 46, 53, 32, 42, 32, 84,101,120, 68,120, 32, 59, 10, 9,118,101, 99, 50, 32, 83, 84,100, + 32, 61, 32,116,101,120, 99,111, 46,120,121, 32, 45, 32, 48, 46, 53, 32, 42, 32, 84,101,120, 68,121, 32, 59, 10, 9,118,101, 99, + 50, 32, 83, 84,117, 32, 61, 32,116,101,120, 99,111, 46,120,121, 32, 43, 32, 48, 46, 53, 32, 42, 32, 84,101,120, 68,121, 32, 59, + 10, 9, 10, 9,114,103, 98,116,111, 98,119, 40,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,108, 41, 44, + 32, 72,108, 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84, +114, 41, 44, 32, 72,114, 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, + 32, 83, 84,100, 41, 44, 32, 72,100, 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40,116,101,120,116,117,114,101, 50, 68, 40,105, +109, 97, 44, 32, 83, 84,117, 41, 44, 32, 72,117, 41, 59, 10, 9, 10, 9,118,101, 99, 50, 32,100, 72,100,120,121, 32, 61, 32,118, +101, 99, 50, 40, 72,114, 32, 45, 32, 72,108, 44, 32, 72,117, 32, 45, 32, 72,100, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 66, +108,101,110,100, 32, 61, 32, 99,108, 97,109,112, 40, 49, 46, 48, 45,116,101,120,116,117,114,101, 81,117,101,114,121, 76, 79, 68, + 40,105,109, 97, 44, 32,116,101,120, 99,111, 46,120,121, 41, 46,120, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,105, +102, 40,102, 66,108,101,110,100, 33, 61, 48, 46, 48, 41, 10, 9,123, 10, 9, 9, 47, 47, 32,116,104,101, 32,100,101,114,105,118, + 97,116,105,118,101, 32,111,102, 32,116,104,101, 32, 98,105, 99,117, 98,105, 99, 32,115, 97,109,112,108,105,110,103, 32,111,102, + 32,108,101,118,101,108, 32, 48, 10, 9, 9,105,118,101, 99, 50, 32,118, 68,105,109, 59, 10, 9, 9,118, 68,105,109, 32, 61, 32, +116,101,120,116,117,114,101, 83,105,122,101, 40,105,109, 97, 44, 32, 48, 41, 59, 10, 10, 9, 9, 47, 47, 32,116, 97,107,105,110, +103, 32,116,104,101, 32,102,114, 97, 99,116, 32,112, 97,114,116, 32,111,102, 32,116,104,101, 32,116,101,120,116,117,114,101, 32, + 99,111,111,114,100,105,110, 97,116,101, 32,105,115, 32, 97, 32,104, 97,114,100, 99,111,100,101,100, 32,119,114, 97,112, 32,109, +111,100,101, 46, 10, 9, 9, 47, 47, 32,116,104,105,115, 32,105,115, 32, 97, 99, 99,101,112,116, 97, 98,108,101, 32, 97,115, 32, +116,101,120,116,117,114,101,115, 32,117,115,101, 32,119,114, 97,112, 32,109,111,100,101, 32,101,120, 99,108,117,115,105,118,101, +108,121, 32,105,110, 32, 51, 68, 32,118,105,101,119, 32,101,108,115,101,119,104,101,114,101, 32,105,110, 32, 98,108,101,110,100, +101,114, 46, 32, 10, 9, 9, 47, 47, 32,116,104,105,115, 32,105,115, 32,100,111,110,101, 32,115,111, 32,116,104, 97,116, 32,119, +101, 32, 99, 97,110, 32,115,116,105,108,108, 32,103,101,116, 32, 97, 32,118, 97,108,105,100, 32,116,101,120,101,108, 32,119,105, +116,104, 32,117,118,115, 32,111,117,116,115,105,100,101, 32,116,104,101, 32, 48, 44, 49, 32,114, 97,110,103,101, 10, 9, 9, 47, + 47, 32, 98,121, 32,116,101,120,101,108, 70,101,116, 99,104, 32, 98,101,108,111,119, 44, 32, 97,115, 32, 99,111,111,114,100,105, +110, 97,116,101,115, 32, 97,114,101, 32, 99,108, 97,109,112,101,100, 32,119,104,101,110, 32,117,115,105,110,103, 32,116,104,105, +115, 32,102,117,110, 99,116,105,111,110, 46, 10, 9, 9,118,101, 99, 50, 32,102, 84,101,120, 76,111, 99, 32, 61, 32,118, 68,105, +109, 42,102,114, 97, 99,116, 40,116,101,120, 99,111, 46,120,121, 41, 32, 45, 32,118,101, 99, 50, 40, 48, 46, 53, 44, 32, 48, 46, + 53, 41, 59, 10, 9, 9,105,118,101, 99, 50, 32,105, 84,101,120, 76,111, 99, 32, 61, 32,105,118,101, 99, 50, 40,102,108,111,111, +114, 40,102, 84,101,120, 76,111, 99, 41, 41, 59, 10, 9, 9,118,101, 99, 50, 32,116, 32, 61, 32, 99,108, 97,109,112, 40,102, 84, +101,120, 76,111, 99, 32, 45, 32,105, 84,101,120, 76,111, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 9, 9, 47, 47, 32, +115, 97,116, 32,106,117,115,116, 32,116,111, 32, 98,101, 32,112,101,100, 97,110,116,105, 99, 10, 10, 47, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 10, 32, 42, 32, 84,104,105,115, 32, 98,108, +111, 99,107, 32,119,105,108,108, 32,114,101,112,108, 97, 99,101, 32,116,104,101, 32,111,110,101, 32, 98,101,108,111,119, 32,119, +104,101,110, 32,111,110,101, 32, 99,104, 97,110,110,101,108, 32,116,101,120,116,117,114,101,115, 32, 97,114,101, 32,112,114,111, +112,101,114,108,121, 32,115,117,112,112,111,114,116,101,100, 46, 32, 42, 10, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 10, 9, 9,118,101, 99, 52, 32,118, 83, 97,109,112,108,101,115, 85, + 76, 32, 61, 32,116,101,120,116,117,114,101, 71, 97,116,104,101,114, 40,105,109, 97, 44, 32, 40,105, 84,101,120, 76,111, 99, 43, +105,118,101, 99, 50, 40, 45, 49, 44, 45, 49, 41, 32, 43, 32,118,101, 99, 50, 40, 48, 46, 53, 44, 48, 46, 53, 41, 41, 47,118, 68, +105,109, 32, 41, 59, 10, 9, 9,118,101, 99, 52, 32,118, 83, 97,109,112,108,101,115, 85, 82, 32, 61, 32,116,101,120,116,117,114, +101, 71, 97,116,104,101,114, 40,105,109, 97, 44, 32, 40,105, 84,101,120, 76,111, 99, 43,105,118,101, 99, 50, 40, 49, 44, 45, 49, + 41, 32, 43, 32,118,101, 99, 50, 40, 48, 46, 53, 44, 48, 46, 53, 41, 41, 47,118, 68,105,109, 32, 41, 59, 10, 9, 9,118,101, 99, + 52, 32,118, 83, 97,109,112,108,101,115, 76, 76, 32, 61, 32,116,101,120,116,117,114,101, 71, 97,116,104,101,114, 40,105,109, 97, + 44, 32, 40,105, 84,101,120, 76,111, 99, 43,105,118,101, 99, 50, 40, 45, 49, 44, 49, 41, 32, 43, 32,118,101, 99, 50, 40, 48, 46, + 53, 44, 48, 46, 53, 41, 41, 47,118, 68,105,109, 32, 41, 59, 10, 9, 9,118,101, 99, 52, 32,118, 83, 97,109,112,108,101,115, 76, + 82, 32, 61, 32,116,101,120,116,117,114,101, 71, 97,116,104,101,114, 40,105,109, 97, 44, 32, 40,105, 84,101,120, 76,111, 99, 43, +105,118,101, 99, 50, 40, 49, 44, 49, 41, 32, 43, 32,118,101, 99, 50, 40, 48, 46, 53, 44, 48, 46, 53, 41, 41, 47,118, 68,105,109, + 32, 41, 59, 10, 10, 9, 9,109, 97,116, 52, 32, 72, 32, 61, 32,109, 97,116, 52, 40,118, 83, 97,109,112,108,101,115, 85, 76, 46, +119, 44, 32,118, 83, 97,109,112,108,101,115, 85, 76, 46,120, 44, 32,118, 83, 97,109,112,108,101,115, 76, 76, 46,119, 44, 32,118, + 83, 97,109,112,108,101,115, 76, 76, 46,120, 44, 10, 9, 9, 9, 9, 9,118, 83, 97,109,112,108,101,115, 85, 76, 46,122, 44, 32, +118, 83, 97,109,112,108,101,115, 85, 76, 46,121, 44, 32,118, 83, 97,109,112,108,101,115, 76, 76, 46,122, 44, 32,118, 83, 97,109, +112,108,101,115, 76, 76, 46,121, 44, 10, 9, 9, 9, 9, 9,118, 83, 97,109,112,108,101,115, 85, 82, 46,119, 44, 32,118, 83, 97, +109,112,108,101,115, 85, 82, 46,120, 44, 32,118, 83, 97,109,112,108,101,115, 76, 82, 46,119, 44, 32,118, 83, 97,109,112,108,101, +115, 76, 82, 46,120, 44, 10, 9, 9, 9, 9, 9,118, 83, 97,109,112,108,101,115, 85, 82, 46,122, 44, 32,118, 83, 97,109,112,108, +101,115, 85, 82, 46,121, 44, 32,118, 83, 97,109,112,108,101,115, 76, 82, 46,122, 44, 32,118, 83, 97,109,112,108,101,115, 76, 82, + 46,121, 41, 59, 10, 42, 47, 9, 10, 9, 9,105,118,101, 99, 50, 32,105, 84,101,120, 76,111, 99, 77,111,100, 32, 61, 32,105, 84, +101,120, 76,111, 99, 32, 43, 32,105,118,101, 99, 50, 40, 45, 49, 44, 32, 45, 49, 41, 59, 10, 10, 9, 9,109, 97,116, 52, 32, 72, + 59, 10, 9, 9, 10, 9, 9,102,111,114, 40,105,110,116, 32,105, 32, 61, 32, 48, 59, 32,105, 32, 60, 32, 52, 59, 32,105, 43, 43, + 41,123, 10, 9, 9, 9,102,111,114, 40,105,110,116, 32,106, 32, 61, 32, 48, 59, 32,106, 32, 60, 32, 52, 59, 32,106, 43, 43, 41, +123, 10, 9, 9, 9, 9,105,118,101, 99, 50, 32,105, 84,101,120, 84,109,112, 32, 61, 32,105, 84,101,120, 76,111, 99, 77,111,100, + 32, 43, 32,105,118,101, 99, 50, 40,105, 44,106, 41, 59, 10, 9, 9, 9, 9, 10, 9, 9, 9, 9, 47, 47, 32,119,114, 97,112, 32, +116,101,120,116,117,114,101, 32, 99,111,111,114,100,105,110, 97,116,101,115, 32,109, 97,110,117, 97,108,108,121, 32,102,111,114, + 32,116,101,120,101,108, 70,101,116, 99,104, 32,116,111, 32,119,111,114,107, 32,111,110, 32,117,118,115, 32,111,105,116,115,105, +100,101, 32,116,104,101, 32, 48, 44, 49, 32,114, 97,110,103,101, 46, 10, 9, 9, 9, 9, 47, 47, 32,116,104,105,115, 32,105,115, + 32,103,117, 97,114, 97,110,116,101,101,100, 32,116,111, 32,119,111,114,107, 32,115,105,110, 99,101, 32,119,101, 32,116, 97,107, +101, 32,116,104,101, 32,102,114, 97, 99,116,105,111,110, 97,108, 32,112, 97,114,116, 32,111,102, 32,116,104,101, 32,117,118, 32, + 97, 98,111,118,101, 46, 10, 9, 9, 9, 9,105, 84,101,120, 84,109,112, 46,120, 32, 61, 32, 40,105, 84,101,120, 84,109,112, 46, +120, 32, 60, 32, 48, 41, 63, 32,105, 84,101,120, 84,109,112, 46,120, 32, 43, 32,118, 68,105,109, 46,120, 32, 58, 32, 40, 40,105, + 84,101,120, 84,109,112, 46,120, 32, 62, 61, 32,118, 68,105,109, 46,120, 41, 63, 32,105, 84,101,120, 84,109,112, 46,120, 32, 45, + 32,118, 68,105,109, 46,120, 32, 58, 32,105, 84,101,120, 84,109,112, 46,120, 41, 59, 10, 9, 9, 9, 9,105, 84,101,120, 84,109, +112, 46,121, 32, 61, 32, 40,105, 84,101,120, 84,109,112, 46,121, 32, 60, 32, 48, 41, 63, 32,105, 84,101,120, 84,109,112, 46,121, + 32, 43, 32,118, 68,105,109, 46,121, 32, 58, 32, 40, 40,105, 84,101,120, 84,109,112, 46,121, 32, 62, 61, 32,118, 68,105,109, 46, +121, 41, 63, 32,105, 84,101,120, 84,109,112, 46,121, 32, 45, 32,118, 68,105,109, 46,121, 32, 58, 32,105, 84,101,120, 84,109,112, + 46,121, 41, 59, 10, 10, 9, 9, 9, 9,114,103, 98,116,111, 98,119, 40,116,101,120,101,108, 70,101,116, 99,104, 40,105,109, 97, + 44, 32,105, 84,101,120, 84,109,112, 44, 32, 48, 41, 44, 32, 72, 91,105, 93, 91,106, 93, 41, 59, 10, 9, 9, 9,125, 10, 9, 9, +125, 10, 9, 9, 10, 9, 9,102,108,111, 97,116, 32,120, 32, 61, 32,116, 46,120, 44, 32,121, 32, 61, 32,116, 46,121, 59, 10, 9, + 9,102,108,111, 97,116, 32,120, 50, 32, 61, 32,120, 32, 42, 32,120, 44, 32,120, 51, 32, 61, 32,120, 50, 32, 42, 32,120, 44, 32, +121, 50, 32, 61, 32,121, 32, 42, 32,121, 44, 32,121, 51, 32, 61, 32,121, 50, 32, 42, 32,121, 59, 10, 10, 9, 9,118,101, 99, 52, + 32, 88, 32, 61, 32,118,101, 99, 52, 40, 45, 48, 46, 53, 42, 40,120, 51, 43,120, 41, 43,120, 50, 44, 9, 9, 49, 46, 53, 42,120, + 51, 45, 50, 46, 53, 42,120, 50, 43, 49, 44, 9, 45, 49, 46, 53, 42,120, 51, 43, 50, 42,120, 50, 43, 48, 46, 53, 42,120, 44, 9, + 9, 48, 46, 53, 42, 40,120, 51, 45,120, 50, 41, 41, 59, 10, 9, 9,118,101, 99, 52, 32, 89, 32, 61, 32,118,101, 99, 52, 40, 45, + 48, 46, 53, 42, 40,121, 51, 43,121, 41, 43,121, 50, 44, 9, 9, 49, 46, 53, 42,121, 51, 45, 50, 46, 53, 42,121, 50, 43, 49, 44, + 9, 45, 49, 46, 53, 42,121, 51, 43, 50, 42,121, 50, 43, 48, 46, 53, 42,121, 44, 9, 9, 48, 46, 53, 42, 40,121, 51, 45,121, 50, + 41, 41, 59, 10, 9, 9,118,101, 99, 52, 32,100, 88, 32, 61, 32,118,101, 99, 52, 40, 45, 49, 46, 53, 42,120, 50, 43, 50, 42,120, + 45, 48, 46, 53, 44, 9, 9, 52, 46, 53, 42,120, 50, 45, 53, 42,120, 44, 9, 9, 9, 45, 52, 46, 53, 42,120, 50, 43, 52, 42,120, + 43, 48, 46, 53, 44, 9, 9, 49, 46, 53, 42,120, 50, 45,120, 41, 59, 10, 9, 9,118,101, 99, 52, 32,100, 89, 32, 61, 32,118,101, + 99, 52, 40, 45, 49, 46, 53, 42,121, 50, 43, 50, 42,121, 45, 48, 46, 53, 44, 9, 9, 52, 46, 53, 42,121, 50, 45, 53, 42,121, 44, + 9, 9, 9, 45, 52, 46, 53, 42,121, 50, 43, 52, 42,121, 43, 48, 46, 53, 44, 9, 9, 49, 46, 53, 42,121, 50, 45,121, 41, 59, 10, + 9, 10, 9, 9, 47, 47, 32, 99,111,109,112,108,101,116,101, 32,100,101,114,105,118, 97,116,105,118,101, 32,105,110, 32,110,111, +114,109, 97,108,105,122,101,100, 32, 99,111,111,114,100,105,110, 97,116,101,115, 32, 40,109,117,108, 32, 98,121, 32,118, 68,105, +109, 41, 10, 9, 9,118,101, 99, 50, 32,100, 72,100, 83, 84, 32, 61, 32,118, 68,105,109, 32, 42, 32,118,101, 99, 50, 40,100,111, +116, 40, 89, 44, 32, 72, 32, 42, 32,100, 88, 41, 44, 32,100,111,116, 40,100, 89, 44, 32, 72, 32, 42, 32, 88, 41, 41, 59, 10, 10, + 9, 9, 47, 47, 32,116,114, 97,110,115,102,111,114,109, 32,100,101,114,105,118, 97,116,105,118,101, 32,116,111, 32,115, 99,114, +101,101,110, 45,115,112, 97, 99,101, 10, 9, 9,118,101, 99, 50, 32,100, 72,100,120,121, 95, 98,105, 99,117, 98,105, 99, 32, 61, + 32,118,101, 99, 50, 40, 32,100, 72,100, 83, 84, 46,120, 32, 42, 32, 84,101,120, 68,120, 46,120, 32, 43, 32,100, 72,100, 83, 84, + 46,121, 32, 42, 32, 84,101,120, 68,120, 46,121, 44, 10, 9, 9, 9, 9, 9, 9, 9, 9, 32, 32, 32,100, 72,100, 83, 84, 46,120, + 32, 42, 32, 84,101,120, 68,121, 46,120, 32, 43, 32,100, 72,100, 83, 84, 46,121, 32, 42, 32, 84,101,120, 68,121, 46,121, 32, 41, + 59, 10, 10, 9, 9, 47, 47, 32, 98,108,101,110,100, 32, 98,101,116,119,101,101,110, 32,116,104,101, 32,116,119,111, 10, 9, 9, +100, 72,100,120,121, 32, 61, 32,100, 72,100,120,121, 42, 40, 49, 45,102, 66,108,101,110,100, 41, 32, 43, 32,100, 72,100,120,121, + 95, 98,105, 99,117, 98,105, 99, 42,102, 66,108,101,110,100, 59, 10, 9,125, 10, 10, 9,100, 66,115, 32, 61, 32,104, 83, 99, 97, +108,101, 32, 42, 32,100, 72,100,120,121, 46,120, 59, 10, 9,100, 66,116, 32, 61, 32,104, 83, 99, 97,108,101, 32, 42, 32,100, 72, +100,120,121, 46,121, 59, 10,125, 10, 10, 35,101,110,100,105,102, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,117,109,112, + 95,116, 97,112, 53, 40, 32,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32,105,109, 97, + 44, 32,102,108,111, 97,116, 32,104, 83, 99, 97,108,101, 44, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32,111,117,116, 32,102,108,111, 97,116, 32,100, 66,115, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,100, + 66,116, 32, 41, 32, 10,123, 10, 9,118,101, 99, 50, 32, 84,101,120, 68,120, 32, 61, 32,100, 70,100,120, 40,116,101,120, 99,111, + 46,120,121, 41, 59, 10, 9,118,101, 99, 50, 32, 84,101,120, 68,121, 32, 61, 32,100, 70,100,121, 40,116,101,120, 99,111, 46,120, +121, 41, 59, 10, 10, 9,118,101, 99, 50, 32, 83, 84, 99, 32, 61, 32,116,101,120, 99,111, 46,120,121, 59, 10, 9,118,101, 99, 50, + 32, 83, 84,108, 32, 61, 32,116,101,120, 99,111, 46,120,121, 32, 45, 32, 48, 46, 53, 32, 42, 32, 84,101,120, 68,120, 32, 59, 10, + 9,118,101, 99, 50, 32, 83, 84,114, 32, 61, 32,116,101,120, 99,111, 46,120,121, 32, 43, 32, 48, 46, 53, 32, 42, 32, 84,101,120, + 68,120, 32, 59, 10, 9,118,101, 99, 50, 32, 83, 84,100, 32, 61, 32,116,101,120, 99,111, 46,120,121, 32, 45, 32, 48, 46, 53, 32, + 42, 32, 84,101,120, 68,121, 32, 59, 10, 9,118,101, 99, 50, 32, 83, 84,117, 32, 61, 32,116,101,120, 99,111, 46,120,121, 32, 43, + 32, 48, 46, 53, 32, 42, 32, 84,101,120, 68,121, 32, 59, 10, 9, 10, 9,102,108,111, 97,116, 32, 72, 99, 44, 72,108, 44, 72,114, + 44, 72,100, 44, 72,117, 59, 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, + 32, 83, 84, 99, 41, 44, 32, 72, 99, 32, 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101,120,116,117,114,101, 50, 68, + 40,105,109, 97, 44, 32, 83, 84,108, 41, 44, 32, 72,108, 32, 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101,120,116, +117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,114, 41, 44, 32, 72,114, 32, 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40, + 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,100, 41, 44, 32, 72,100, 32, 41, 59, 10, 9,114,103, 98, +116,111, 98,119, 40, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,117, 41, 44, 32, 72,117, 32, 41, 59, + 10, 9, 10, 9,100, 66,115, 32, 61, 32,104, 83, 99, 97,108,101, 32, 42, 32, 40, 72,114, 32, 45, 32, 72,108, 41, 59, 10, 9,100, + 66,116, 32, 61, 32,104, 83, 99, 97,108,101, 32, 42, 32, 40, 72,117, 32, 45, 32, 72,100, 41, 59, 10,125, 10, 10,118,111,105,100, + 32,109,116,101,120, 95, 98,117,109,112, 95,100,101,114,105,118, 40, 32,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,115, 97, +109,112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,102,108,111, 97,116, 32,105,109, 97, 95,120, 44, 32,102,108,111, 97,116, 32, +105,109, 97, 95,121, 44, 32,102,108,111, 97,116, 32,104, 83, 99, 97,108,101, 44, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,111,117,116, 32,102,108,111, 97,116, 32,100, 66,115, 44, 32,111,117,116, 32,102,108, +111, 97,116, 32,100, 66,116, 32, 41, 32, 10,123, 10, 9,102,108,111, 97,116, 32,115, 32, 61, 32, 49, 46, 48, 59, 9, 9, 47, 47, + 32,110,101,103, 97,116,101, 32,116,104,105,115, 32,105,102, 32,102,108,105,112,112,101,100, 32,116,101,120,116,117,114,101, 32, + 99,111,111,114,100,105,110, 97,116,101, 10, 9,118,101, 99, 50, 32, 84,101,120, 68,120, 32, 61, 32,100, 70,100,120, 40,116,101, +120, 99,111, 46,120,121, 41, 59, 10, 9,118,101, 99, 50, 32, 84,101,120, 68,121, 32, 61, 32,100, 70,100,121, 40,116,101,120, 99, +111, 46,120,121, 41, 59, 10, 9, 10, 9, 47, 47, 32,116,104,105,115, 32,118, 97,114,105, 97,110,116, 32,117,115,105,110,103, 32, + 97, 32,100,101,114,105,118, 97,116,105,118,101, 32,109, 97,112, 32,105,115, 32,100,101,115, 99,114,105, 98,101,100, 32,104,101, +114,101, 10, 9, 47, 47, 32,104,116,116,112, 58, 47, 47,109,109,105,107,107,101,108,115,101,110, 51,100, 46, 98,108,111,103,115, +112,111,116, 46, 99,111,109, 47, 50, 48, 49, 49, 47, 48, 55, 47,100,101,114,105,118, 97,116,105,118,101, 45,109, 97,112,115, 46, +104,116,109,108, 10, 9,118,101, 99, 50, 32,100,105,109, 32, 61, 32,118,101, 99, 50, 40,105,109, 97, 95,120, 44, 32,105,109, 97, + 95,121, 41, 59, 10, 9,118,101, 99, 50, 32,100, 66,100,117,118, 32, 61, 32,104, 83, 99, 97,108,101, 42,100,105,109, 42, 40, 50, + 46, 48, 42,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32,116,101,120, 99,111, 46,120,121, 41, 46,120,121, 45, 49, + 46, 48, 41, 59, 10, 9, 10, 9,100, 66,115, 32, 61, 32,100, 66,100,117,118, 46,120, 42, 84,101,120, 68,120, 46,120, 32, 43, 32, +115, 42,100, 66,100,117,118, 46,121, 42, 84,101,120, 68,120, 46,121, 59, 10, 9,100, 66,116, 32, 61, 32,100, 66,100,117,118, 46, +120, 42, 84,101,120, 68,121, 46,120, 32, 43, 32,115, 42,100, 66,100,117,118, 46,121, 42, 84,101,120, 68,121, 46,121, 59, 10,125, + 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,117,109,112, 95, 97,112,112,108,121, 40, 32,102,108,111, 97,116, 32,102, 68, +101,116, 44, 32,102,108,111, 97,116, 32,100, 66,115, 44, 32,102,108,111, 97,116, 32,100, 66,116, 44, 32,118,101, 99, 51, 32,118, + 82, 49, 44, 32,118,101, 99, 51, 32,118, 82, 50, 44, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,105,110, 44, 10, 9, 9, 9, + 9, 9, 32, 32,111,117,116, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,111,117,116, 44, 32,111,117,116, 32,118,101, 99, 51, + 32,112,101,114,116,117,114, 98,101,100, 95,110,111,114,109, 32, 41, 32, 10,123, 10, 9,118,101, 99, 51, 32,118, 83,117,114,102, + 71,114, 97,100, 32, 61, 32,115,105,103,110, 40,102, 68,101,116, 41, 32, 42, 32, 40, 32,100, 66,115, 32, 42, 32,118, 82, 49, 32, + 43, 32,100, 66,116, 32, 42, 32,118, 82, 50, 32, 41, 59, 10, 9, 10, 9,118, 78, 97, 99, 99, 95,111,117,116, 32, 61, 32,118, 78, + 97, 99, 99, 95,105,110, 32, 45, 32,118, 83,117,114,102, 71,114, 97,100, 59, 10, 9,112,101,114,116,117,114, 98,101,100, 95,110, +111,114,109, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 32,118, 78, 97, 99, 99, 95,111,117,116, 32, 41, 59, 10,125, 10, + 10,118,111,105,100, 32,109,116,101,120, 95, 98,117,109,112, 95, 97,112,112,108,121, 95,116,101,120,115,112, 97, 99,101, 40, 32, +102,108,111, 97,116, 32,102, 68,101,116, 44, 32,102,108,111, 97,116, 32,100, 66,115, 44, 32,102,108,111, 97,116, 32,100, 66,116, + 44, 32,118,101, 99, 51, 32,118, 82, 49, 44, 32,118,101, 99, 51, 32,118, 82, 50, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115, 97,109,112,108,101,114, 50, 68, 32,105, +109, 97, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,102,108,111, 97,116, 32,105,109, 97, 95,120, 44, 32,102,108,111, + 97,116, 32,105,109, 97, 95,121, 44, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,105,110, 44, 10, 9, 9, 9, 9, 9, 9, 9, + 32, 32, 32,111,117,116, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,111,117,116, 44, 32,111,117,116, 32,118,101, 99, 51, 32, +112,101,114,116,117,114, 98,101,100, 95,110,111,114,109, 32, 41, 32, 10,123, 10, 9,118,101, 99, 50, 32, 84,101,120, 68,120, 32, + 61, 32,100, 70,100,120, 40,116,101,120, 99,111, 46,120,121, 41, 59, 10, 9,118,101, 99, 50, 32, 84,101,120, 68,121, 32, 61, 32, +100, 70,100,121, 40,116,101,120, 99,111, 46,120,121, 41, 59, 10, 10, 9,118,101, 99, 51, 32,118, 83,117,114,102, 71,114, 97,100, + 32, 61, 32,115,105,103,110, 40,102, 68,101,116, 41, 32, 42, 32, 40, 32, 10, 9, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +100, 66,115, 32, 47, 32,108,101,110,103,116,104, 40, 32,118,101, 99, 50, 40,105,109, 97, 95,120, 42, 84,101,120, 68,120, 46,120, + 44, 32,105,109, 97, 95,121, 42, 84,101,120, 68,120, 46,121, 41, 32, 41, 32, 42, 32,118, 82, 49, 32, 43, 32, 10, 9, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32,100, 66,116, 32, 47, 32,108,101,110,103,116,104, 40, 32,118,101, 99, 50, 40,105,109, 97, 95, +120, 42, 84,101,120, 68,121, 46,120, 44, 32,105,109, 97, 95,121, 42, 84,101,120, 68,121, 46,121, 41, 32, 41, 32, 42, 32,118, 82, + 50, 32, 41, 59, 10, 9, 9, 9, 9, 10, 9,118, 78, 97, 99, 99, 95,111,117,116, 32, 61, 32,118, 78, 97, 99, 99, 95,105,110, 32, + 45, 32,118, 83,117,114,102, 71,114, 97,100, 59, 10, 9,112,101,114,116,117,114, 98,101,100, 95,110,111,114,109, 32, 61, 32,110, +111,114,109, 97,108,105,122,101, 40, 32,118, 78, 97, 99, 99, 95,111,117,116, 32, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, +116,101,120, 95,110,101,103, 97,116,101, 95,116,101,120,110,111,114,109, 97,108, 40,118,101, 99, 51, 32,110,111,114,109, 97,108, + 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,110,111,114,109, 97,108, 41, 10,123, 10, 9,111,117,116,110,111,114,109, + 97,108, 32, 61, 32,118,101, 99, 51, 40, 45,110,111,114,109, 97,108, 46,120, 44, 32, 45,110,111,114,109, 97,108, 46,121, 44, 32, +110,111,114,109, 97,108, 46,122, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,110,115,112, 97, 99,101, 95,116, + 97,110,103,101,110,116, 40,118,101, 99, 52, 32,116, 97,110,103,101,110,116, 44, 32,118,101, 99, 51, 32,110,111,114,109, 97,108, + 44, 32,118,101, 99, 51, 32,116,101,120,110,111,114,109, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,110,111, +114,109, 97,108, 41, 10,123, 10, 9,118,101, 99, 51, 32, 66, 32, 61, 32,116, 97,110,103,101,110,116, 46,119, 32, 42, 32, 99,114, +111,115,115, 40,110,111,114,109, 97,108, 44, 32,116, 97,110,103,101,110,116, 46,120,121,122, 41, 59, 10, 10, 9,111,117,116,110, +111,114,109, 97,108, 32, 61, 32,116,101,120,110,111,114,109, 97,108, 46,120, 42,116, 97,110,103,101,110,116, 46,120,121,122, 32, + 43, 32,116,101,120,110,111,114,109, 97,108, 46,121, 42, 66, 32, 43, 32,116,101,120,110,111,114,109, 97,108, 46,122, 42,110,111, +114,109, 97,108, 59, 10, 9,111,117,116,110,111,114,109, 97,108, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,111,117,116, +110,111,114,109, 97,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,108,101,110,100, 95,110,111,114,109, + 97,108, 40,102,108,111, 97,116, 32,110,111,114,102, 97, 99, 44, 32,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,118,101, + 99, 51, 32,110,101,119,110,111,114,109, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,110,111,114,109, 97,108, + 41, 10,123, 10, 9,111,117,116,110,111,114,109, 97,108, 32, 61, 32, 40, 49, 46, 48, 32, 45, 32,110,111,114,102, 97, 99, 41, 42, +110,111,114,109, 97,108, 32, 43, 32,110,111,114,102, 97, 99, 42,110,101,119,110,111,114,109, 97,108, 59, 10, 9,111,117,116,110, 111,114,109, 97,108, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,111,117,116,110,111,114,109, 97,108, 41, 59, 10,125, 10, - 10,118,111,105,100, 32,109,116,101,120, 95, 98,108,101,110,100, 95,110,111,114,109, 97,108, 40,102,108,111, 97,116, 32,110,111, -114,102, 97, 99, 44, 32,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,118,101, 99, 51, 32,110,101,119,110,111,114,109, 97, -108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,110,111,114,109, 97,108, 41, 10,123, 10, 9,111,117,116,110,111,114, -109, 97,108, 32, 61, 32, 40, 49, 46, 48, 32, 45, 32,110,111,114,102, 97, 99, 41, 42,110,111,114,109, 97,108, 32, 43, 32,110,111, -114,102, 97, 99, 42,110,101,119,110,111,114,109, 97,108, 59, 10, 9,111,117,116,110,111,114,109, 97,108, 32, 61, 32,110,111,114, -109, 97,108,105,122,101, 40,111,117,116,110,111,114,109, 97,108, 41, 59, 10,125, 10, 10, 47, 42, 42, 42, 42, 42, 42, 42, 32, 77, - 65, 84, 69, 82, 73, 65, 76, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 47, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,118,105, -115,105, 98,105,108,105,116,121, 95,115,117,110, 95,104,101,109,105, 40,118,101, 99, 51, 32,108, 97,109,112,118,101, 99, 44, 32, -111,117,116, 32,118,101, 99, 51, 32,108,118, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,100,105,115,116, 44, 32,111,117,116, - 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,108,118, 32, 61, 32,108, 97,109,112,118,101, 99, 59, - 10, 9,100,105,115,116, 32, 61, 32, 49, 46, 48, 59, 10, 9,118,105,115,105,102, 97, 99, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, - 10,118,111,105,100, 32,108, 97,109,112, 95,118,105,115,105, 98,105,108,105,116,121, 95,111,116,104,101,114, 40,118,101, 99, 51, - 32, 99,111, 44, 32,118,101, 99, 51, 32,108, 97,109,112, 99,111, 44, 32,111,117,116, 32,118,101, 99, 51, 32,108,118, 44, 32,111, -117,116, 32,102,108,111, 97,116, 32,100,105,115,116, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, - 41, 10,123, 10, 9,108,118, 32, 61, 32, 99,111, 32, 45, 32,108, 97,109,112, 99,111, 59, 10, 9,100,105,115,116, 32, 61, 32,108, -101,110,103,116,104, 40,108,118, 41, 59, 10, 9,108,118, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,108,118, 41, 59, 10, - 9,118,105,115,105,102, 97, 99, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,102, 97,108, -108,111,102,102, 95,105,110,118,108,105,110,101, 97,114, 40,102,108,111, 97,116, 32,108, 97,109,112,100,105,115,116, 44, 32,102, -108,111, 97,116, 32,100,105,115,116, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 41, 10,123, 10, - 9,118,105,115,105,102, 97, 99, 32, 61, 32,108, 97,109,112,100,105,115,116, 47, 40,108, 97,109,112,100,105,115,116, 32, 43, 32, -100,105,115,116, 41, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,102, 97,108,108,111,102,102, 95,105,110,118,115, -113,117, 97,114,101, 40,102,108,111, 97,116, 32,108, 97,109,112,100,105,115,116, 44, 32,102,108,111, 97,116, 32,100,105,115,116, - 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,118,105,115,105,102, 97, 99, 32, - 61, 32,108, 97,109,112,100,105,115,116, 47, 40,108, 97,109,112,100,105,115,116, 32, 43, 32,100,105,115,116, 42,100,105,115,116, - 41, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,102, 97,108,108,111,102,102, 95,115,108,105,100,101,114,115, 40, -102,108,111, 97,116, 32,108, 97,109,112,100,105,115,116, 44, 32,102,108,111, 97,116, 32,108,100, 49, 44, 32,102,108,111, 97,116, - 32,108,100, 50, 44, 32,102,108,111, 97,116, 32,100,105,115,116, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118,105,115,105, -102, 97, 99, 41, 10,123, 10, 9,102,108,111, 97,116, 32,108, 97,109,112,100,105,115,116,107,119, 32, 61, 32,108, 97,109,112,100, -105,115,116, 42,108, 97,109,112,100,105,115,116, 59, 10, 10, 9,118,105,115,105,102, 97, 99, 32, 61, 32,108, 97,109,112,100,105, -115,116, 47, 40,108, 97,109,112,100,105,115,116, 32, 43, 32,108,100, 49, 42,100,105,115,116, 41, 59, 10, 9,118,105,115,105,102, - 97, 99, 32, 42, 61, 32,108, 97,109,112,100,105,115,116,107,119, 47, 40,108, 97,109,112,100,105,115,116,107,119, 32, 43, 32,108, -100, 50, 42,100,105,115,116, 42,100,105,115,116, 41, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,102, 97,108,108, -111,102,102, 95, 99,117,114,118,101, 40,102,108,111, 97,116, 32,108, 97,109,112,100,105,115,116, 44, 32,115, 97,109,112,108,101, -114, 50, 68, 32, 99,117,114,118,101,109, 97,112, 44, 32,102,108,111, 97,116, 32,100,105,115,116, 44, 32,111,117,116, 32,102,108, -111, 97,116, 32,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,118,105,115,105,102, 97, 99, 32, 61, 32,116,101,120,116,117,114, -101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, 50, 40,100,105,115,116, 47,108, 97,109,112,100,105,115,116, - 44, 32, 48, 46, 48, 41, 41, 46,120, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,118,105,115,105, 98,105,108,105, -116,121, 95,115,112,104,101,114,101, 40,102,108,111, 97,116, 32,108, 97,109,112,100,105,115,116, 44, 32,102,108,111, 97,116, 32, -100,105,115,116, 44, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111, -117,116,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,102,108,111, 97,116, 32,116, 61, 32,108, 97,109,112,100,105,115,116, 32, - 45, 32,100,105,115,116, 59, 10, 10, 9,111,117,116,118,105,115,105,102, 97, 99, 61, 32,118,105,115,105,102, 97, 99, 42,109, 97, -120, 40,116, 44, 32, 48, 46, 48, 41, 47,108, 97,109,112,100,105,115,116, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, - 95,118,105,115,105, 98,105,108,105,116,121, 95,115,112,111,116, 95,115,113,117, 97,114,101, 40,118,101, 99, 51, 32,108, 97,109, -112,118,101, 99, 44, 32,109, 97,116, 52, 32,108, 97,109,112,105,109, 97,116, 44, 32,118,101, 99, 51, 32,108,118, 44, 32,111,117, -116, 32,102,108,111, 97,116, 32,105,110,112,114, 41, 10,123, 10, 9,105,102, 40,100,111,116, 40,108,118, 44, 32,108, 97,109,112, -118,101, 99, 41, 32, 62, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,118,101, 99, 51, 32,108,118,114,111,116, 32, 61, 32, 40,108, 97, -109,112,105,109, 97,116, 42,118,101, 99, 52, 40,108,118, 44, 32, 48, 46, 48, 41, 41, 46,120,121,122, 59, 10, 9, 9,102,108,111, - 97,116, 32,120, 32, 61, 32,109, 97,120, 40, 97, 98,115, 40,108,118,114,111,116, 46,120, 47,108,118,114,111,116, 46,122, 41, 44, - 32, 97, 98,115, 40,108,118,114,111,116, 46,121, 47,108,118,114,111,116, 46,122, 41, 41, 59, 10, 10, 9, 9,105,110,112,114, 32, - 61, 32, 49, 46, 48, 47,115,113,114,116, 40, 49, 46, 48, 32, 43, 32,120, 42,120, 41, 59, 10, 9,125, 10, 9,101,108,115,101, 10, - 9, 9,105,110,112,114, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,118,105,115,105, 98, -105,108,105,116,121, 95,115,112,111,116, 95, 99,105,114, 99,108,101, 40,118,101, 99, 51, 32,108, 97,109,112,118,101, 99, 44, 32, -118,101, 99, 51, 32,108,118, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110,112,114, 41, 10,123, 10, 9,105,110,112,114, - 32, 61, 32,100,111,116, 40,108,118, 44, 32,108, 97,109,112,118,101, 99, 41, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109, -112, 95,118,105,115,105, 98,105,108,105,116,121, 95,115,112,111,116, 40,102,108,111, 97,116, 32,115,112,111,116,115,105, 44, 32, -102,108,111, 97,116, 32,115,112,111,116, 98,108, 44, 32,102,108,111, 97,116, 32,105,110,112,114, 44, 32,102,108,111, 97,116, 32, -118,105,115,105,102, 97, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118,105,115,105,102, 97, 99, 41, 10,123, - 10, 9,102,108,111, 97,116, 32,116, 32, 61, 32,115,112,111,116,115,105, 59, 10, 10, 9,105,102, 40,105,110,112,114, 32, 60, 61, - 32,116, 41, 32,123, 10, 9, 9,111,117,116,118,105,115,105,102, 97, 99, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101,108, -115,101, 32,123, 10, 9, 9,116, 32, 61, 32,105,110,112,114, 32, 45, 32,116, 59, 10, 10, 9, 9, 47, 42, 32,115,111,102,116, 32, - 97,114,101, 97, 32, 42, 47, 10, 9, 9,105,102, 40,115,112,111,116, 98,108, 32, 33, 61, 32, 48, 46, 48, 41, 10, 9, 9, 9,105, -110,112,114, 32, 42, 61, 32,115,109,111,111,116,104,115,116,101,112, 40, 48, 46, 48, 44, 32, 49, 46, 48, 44, 32,116, 47,115,112, -111,116, 98,108, 41, 59, 10, 10, 9, 9,111,117,116,118,105,115,105,102, 97, 99, 32, 61, 32,118,105,115,105,102, 97, 99, 42,105, -110,112,114, 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,118,105,115,105, 98,105,108,105,116,121, 95, - 99,108, 97,109,112, 40,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111, -117,116,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,111,117,116,118,105,115,105,102, 97, 99, 32, 61, 32, 40,118,105,115,105, -102, 97, 99, 32, 60, 32, 48, 46, 48, 48, 49, 41, 63, 32, 48, 46, 48, 58, 32,118,105,115,105,102, 97, 99, 59, 10,125, 10, 10,118, -111,105,100, 32,115,104, 97,100,101, 95,118,105,101,119, 40,118,101, 99, 51, 32, 99,111, 44, 32,111,117,116, 32,118,101, 99, 51, - 32,118,105,101,119, 41, 10,123, 10, 9, 47, 42, 32,104, 97,110,100,108,101, 32,112,101,114,115,112,101, 99,116,105,118,101, 47, -111,114,116,104,111,103,114, 97,112,104,105, 99, 32, 42, 47, 10, 9,118,105,101,119, 32, 61, 32, 40,103,108, 95, 80,114,111,106, -101, 99,116,105,111,110, 77, 97,116,114,105,120, 91, 51, 93, 91, 51, 93, 32, 61, 61, 32, 48, 46, 48, 41, 63, 32,110,111,114,109, - 97,108,105,122,101, 40, 99,111, 41, 58, 32,118,101, 99, 51, 40, 48, 46, 48, 44, 32, 48, 46, 48, 44, 32, 45, 49, 46, 48, 41, 59, - 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,116, 97,110,103,101,110,116, 95,118, 40,118,101, 99, 51, 32,108,118, - 44, 32,118,101, 99, 51, 32,116, 97,110,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118,110, 41, 10,123, 10, 9,118,101, 99, - 51, 32, 99, 32, 61, 32, 99,114,111,115,115, 40,108,118, 44, 32,116, 97,110,103, 41, 59, 10, 9,118,101, 99, 51, 32,118,110,111, -114, 32, 61, 32, 99,114,111,115,115, 40, 99, 44, 32,116, 97,110,103, 41, 59, 10, 10, 9,118,110, 32, 61, 32, 45,110,111,114,109, - 97,108,105,122,101, 40,118,110,111,114, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,105,110,112, 40,118, -101, 99, 51, 32,118,110, 44, 32,118,101, 99, 51, 32,108,118, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110,112, 41, 10, -123, 10, 9,105,110,112, 32, 61, 32,100,111,116, 40,118,110, 44, 32,108,118, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, - 97,100,101, 95,105,115, 95,110,111, 95,100,105,102,102,117,115,101, 40,111,117,116, 32,102,108,111, 97,116, 32,105,115, 41, 10, -123, 10, 9,105,115, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,105,115, 95,104,101, -109,105, 40,102,108,111, 97,116, 32,105,110,112, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,115, 41, 10,123, 10, 9,105, -115, 32, 61, 32, 48, 46, 53, 42,105,110,112, 32, 43, 32, 48, 46, 53, 59, 10,125, 10, 10,102,108,111, 97,116, 32, 97,114,101, 97, - 95,108, 97,109,112, 95,101,110,101,114,103,121, 40,109, 97,116, 52, 32, 97,114,101, 97, 44, 32,118,101, 99, 51, 32, 99,111, 44, - 32,118,101, 99, 51, 32,118,110, 41, 10,123, 10, 9,118,101, 99, 51, 32,118,101, 99, 91, 52, 93, 44, 32, 99, 91, 52, 93, 59, 10, - 9,102,108,111, 97,116, 32,114, 97,100, 91, 52, 93, 44, 32,102, 97, 99, 59, 10, 9, 10, 9,118,101, 99, 91, 48, 93, 32, 61, 32, -110,111,114,109, 97,108,105,122,101, 40, 99,111, 32, 45, 32, 97,114,101, 97, 91, 48, 93, 46,120,121,122, 41, 59, 10, 9,118,101, - 99, 91, 49, 93, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 99,111, 32, 45, 32, 97,114,101, 97, 91, 49, 93, 46,120,121, -122, 41, 59, 10, 9,118,101, 99, 91, 50, 93, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 99,111, 32, 45, 32, 97,114,101, - 97, 91, 50, 93, 46,120,121,122, 41, 59, 10, 9,118,101, 99, 91, 51, 93, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 99, -111, 32, 45, 32, 97,114,101, 97, 91, 51, 93, 46,120,121,122, 41, 59, 10, 10, 9, 99, 91, 48, 93, 32, 61, 32,110,111,114,109, 97, -108,105,122,101, 40, 99,114,111,115,115, 40,118,101, 99, 91, 48, 93, 44, 32,118,101, 99, 91, 49, 93, 41, 41, 59, 10, 9, 99, 91, - 49, 93, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 99,114,111,115,115, 40,118,101, 99, 91, 49, 93, 44, 32,118,101, 99, - 91, 50, 93, 41, 41, 59, 10, 9, 99, 91, 50, 93, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 99,114,111,115,115, 40,118, -101, 99, 91, 50, 93, 44, 32,118,101, 99, 91, 51, 93, 41, 41, 59, 10, 9, 99, 91, 51, 93, 32, 61, 32,110,111,114,109, 97,108,105, -122,101, 40, 99,114,111,115,115, 40,118,101, 99, 91, 51, 93, 44, 32,118,101, 99, 91, 48, 93, 41, 41, 59, 10, 10, 9,114, 97,100, - 91, 48, 93, 32, 61, 32, 97, 99,111,115, 40,100,111,116, 40,118,101, 99, 91, 48, 93, 44, 32,118,101, 99, 91, 49, 93, 41, 41, 59, - 10, 9,114, 97,100, 91, 49, 93, 32, 61, 32, 97, 99,111,115, 40,100,111,116, 40,118,101, 99, 91, 49, 93, 44, 32,118,101, 99, 91, - 50, 93, 41, 41, 59, 10, 9,114, 97,100, 91, 50, 93, 32, 61, 32, 97, 99,111,115, 40,100,111,116, 40,118,101, 99, 91, 50, 93, 44, - 32,118,101, 99, 91, 51, 93, 41, 41, 59, 10, 9,114, 97,100, 91, 51, 93, 32, 61, 32, 97, 99,111,115, 40,100,111,116, 40,118,101, - 99, 91, 51, 93, 44, 32,118,101, 99, 91, 48, 93, 41, 41, 59, 10, 10, 9,102, 97, 99, 61, 32, 32,114, 97,100, 91, 48, 93, 42,100, -111,116, 40,118,110, 44, 32, 99, 91, 48, 93, 41, 59, 10, 9,102, 97, 99, 43, 61, 32,114, 97,100, 91, 49, 93, 42,100,111,116, 40, -118,110, 44, 32, 99, 91, 49, 93, 41, 59, 10, 9,102, 97, 99, 43, 61, 32,114, 97,100, 91, 50, 93, 42,100,111,116, 40,118,110, 44, - 32, 99, 91, 50, 93, 41, 59, 10, 9,102, 97, 99, 43, 61, 32,114, 97,100, 91, 51, 93, 42,100,111,116, 40,118,110, 44, 32, 99, 91, - 51, 93, 41, 59, 10, 10, 9,114,101,116,117,114,110, 32,109, 97,120, 40,102, 97, 99, 44, 32, 48, 46, 48, 41, 59, 10,125, 10, 10, -118,111,105,100, 32,115,104, 97,100,101, 95,105,110,112, 95, 97,114,101, 97, 40,118,101, 99, 51, 32,112,111,115,105,116,105,111, -110, 44, 32,118,101, 99, 51, 32,108, 97,109,112, 99,111, 44, 32,118,101, 99, 51, 32,108, 97,109,112,118,101, 99, 44, 32,118,101, - 99, 51, 32,118,110, 44, 32,109, 97,116, 52, 32, 97,114,101, 97, 44, 32,102,108,111, 97,116, 32, 97,114,101, 97,115,105,122,101, - 44, 32,102,108,111, 97,116, 32,107, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110,112, 41, 10,123, 10, 9,118,101, 99, - 51, 32, 99,111, 32, 61, 32,112,111,115,105,116,105,111,110, 59, 10, 9,118,101, 99, 51, 32,118,101, 99, 32, 61, 32, 99,111, 32, - 45, 32,108, 97,109,112, 99,111, 59, 10, 10, 9,105,102, 40,100,111,116, 40,118,101, 99, 44, 32,108, 97,109,112,118,101, 99, 41, - 32, 60, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,105,110,112, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32, -123, 10, 9, 9,102,108,111, 97,116, 32,105,110,116,101,110,115, 32, 61, 32, 97,114,101, 97, 95,108, 97,109,112, 95,101,110,101, -114,103,121, 40, 97,114,101, 97, 44, 32, 99,111, 44, 32,118,110, 41, 59, 10, 10, 9, 9,105,110,112, 32, 61, 32,112,111,119, 40, -105,110,116,101,110,115, 42, 97,114,101, 97,115,105,122,101, 44, 32,107, 41, 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32, -115,104, 97,100,101, 95,100,105,102,102,117,115,101, 95,111,114,101,110, 95,110, 97,121,101,114, 40,102,108,111, 97,116, 32,110, -108, 44, 32,118,101, 99, 51, 32,110, 44, 32,118,101, 99, 51, 32,108, 44, 32,118,101, 99, 51, 32,118, 44, 32,102,108,111, 97,116, - 32,114,111,117,103,104, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,115, 41, 10,123, 10, 9,118,101, 99, 51, 32,104, 32, - 61, 32,110,111,114,109, 97,108,105,122,101, 40,118, 32, 43, 32,108, 41, 59, 10, 9,102,108,111, 97,116, 32,110,104, 32, 61, 32, -109, 97,120, 40,100,111,116, 40,110, 44, 32,104, 41, 44, 32, 48, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,110,118, 32, 61, - 32,109, 97,120, 40,100,111,116, 40,110, 44, 32,118, 41, 44, 32, 48, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,114,101, 97, -108,110,108, 32, 61, 32,100,111,116, 40,110, 44, 32,108, 41, 59, 10, 10, 9,105,102, 40,114,101, 97,108,110,108, 32, 60, 32, 48, - 46, 48, 41, 32,123, 10, 9, 9,105,115, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,105,102, 40,110,108, - 32, 60, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,105,115, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, - 10, 9, 9,102,108,111, 97,116, 32,118,104, 32, 61, 32,109, 97,120, 40,100,111,116, 40,118, 44, 32,104, 41, 44, 32, 48, 46, 48, - 41, 59, 10, 9, 9,102,108,111, 97,116, 32, 76,105,116, 95, 65, 32, 61, 32, 97, 99,111,115, 40,114,101, 97,108,110,108, 41, 59, - 10, 9, 9,102,108,111, 97,116, 32, 86,105,101,119, 95, 65, 32, 61, 32, 97, 99,111,115, 40,110,118, 41, 59, 10, 10, 9, 9,118, -101, 99, 51, 32, 76,105,116, 95, 66, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,108, 32, 45, 32,114,101, 97,108,110,108, - 42,110, 41, 59, 10, 9, 9,118,101, 99, 51, 32, 86,105,101,119, 95, 66, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,118, - 32, 45, 32,110,118, 42,110, 41, 59, 10, 10, 9, 9,102,108,111, 97,116, 32,116, 32, 61, 32,109, 97,120, 40,100,111,116, 40, 76, -105,116, 95, 66, 44, 32, 86,105,101,119, 95, 66, 41, 44, 32, 48, 46, 48, 41, 59, 10, 10, 9, 9,102,108,111, 97,116, 32, 97, 44, - 32, 98, 59, 10, 10, 9, 9,105,102, 40, 76,105,116, 95, 65, 32, 62, 32, 86,105,101,119, 95, 65, 41, 32,123, 10, 9, 9, 9, 97, - 32, 61, 32, 76,105,116, 95, 65, 59, 10, 9, 9, 9, 98, 32, 61, 32, 86,105,101,119, 95, 65, 59, 10, 9, 9,125, 10, 9, 9,101, -108,115,101, 32,123, 10, 9, 9, 9, 97, 32, 61, 32, 86,105,101,119, 95, 65, 59, 10, 9, 9, 9, 98, 32, 61, 32, 76,105,116, 95, - 65, 59, 10, 9, 9,125, 10, 10, 9, 9,102,108,111, 97,116, 32, 65, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40, 48, 46, 53, 42, 40, - 40,114,111,117,103,104, 42,114,111,117,103,104, 41, 47, 40, 40,114,111,117,103,104, 42,114,111,117,103,104, 41, 32, 43, 32, 48, - 46, 51, 51, 41, 41, 41, 59, 10, 9, 9,102,108,111, 97,116, 32, 66, 32, 61, 32, 48, 46, 52, 53, 42, 40, 40,114,111,117,103,104, - 42,114,111,117,103,104, 41, 47, 40, 40,114,111,117,103,104, 42,114,111,117,103,104, 41, 32, 43, 32, 48, 46, 48, 57, 41, 41, 59, - 10, 10, 9, 9, 98, 32, 42, 61, 32, 48, 46, 57, 53, 59, 10, 9, 9,105,115, 32, 61, 32,110,108, 42, 40, 65, 32, 43, 32, 40, 66, - 32, 42, 32,116, 32, 42, 32,115,105,110, 40, 97, 41, 32, 42, 32,116, 97,110, 40, 98, 41, 41, 41, 59, 10, 9,125, 10,125, 10, 10, -118,111,105,100, 32,115,104, 97,100,101, 95,100,105,102,102,117,115,101, 95,116,111,111,110, 40,118,101, 99, 51, 32,110, 44, 32, -118,101, 99, 51, 32,108, 44, 32,118,101, 99, 51, 32,118, 44, 32,102,108,111, 97,116, 32,115,105,122,101, 44, 32,102,108,111, 97, -116, 32,116,115,109,111,111,116,104, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,115, 41, 10,123, 10, 9,102,108,111, 97, -116, 32,114,115,108,116, 32, 61, 32,100,111,116, 40,110, 44, 32,108, 41, 59, 10, 9,102,108,111, 97,116, 32, 97,110,103, 32, 61, - 32, 97, 99,111,115, 40,114,115,108,116, 41, 59, 10, 10, 9,105,102, 40, 97,110,103, 32, 60, 32,115,105,122,101, 41, 32,105,115, - 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40, 97,110,103, 32, 62, 32, 40,115,105,122,101, 32, 43, 32,116, -115,109,111,111,116,104, 41, 32,124,124, 32,116,115,109,111,111,116,104, 32, 61, 61, 32, 48, 46, 48, 41, 32,105,115, 32, 61, 32, - 48, 46, 48, 59, 10, 9,101,108,115,101, 32,105,115, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40, 40, 97,110,103, 32, 45, 32,115,105, -122,101, 41, 47,116,115,109,111,111,116,104, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,100,105,102,102, -117,115,101, 95,109,105,110,110, 97,101,114,116, 40,102,108,111, 97,116, 32,110,108, 44, 32,118,101, 99, 51, 32,110, 44, 32,118, -101, 99, 51, 32,118, 44, 32,102,108,111, 97,116, 32,100, 97,114,107,110,101,115,115, 44, 32,111,117,116, 32,102,108,111, 97,116, - 32,105,115, 41, 10,123, 10, 9,105,102, 40,110,108, 32, 60, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,105,115, 32, 61, 32, 48, - 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9,102,108,111, 97,116, 32,110,118, 32, 61, 32,109, 97,120, 40, -100,111,116, 40,110, 44, 32,118, 41, 44, 32, 48, 46, 48, 41, 59, 10, 10, 9, 9,105,102, 40,100, 97,114,107,110,101,115,115, 32, - 60, 61, 32, 49, 46, 48, 41, 10, 9, 9, 9,105,115, 32, 61, 32,110,108, 42,112,111,119, 40,109, 97,120, 40,110,118, 42,110,108, - 44, 32, 48, 46, 49, 41, 44, 32,100, 97,114,107,110,101,115,115, 32, 45, 32, 49, 46, 48, 41, 59, 10, 9, 9,101,108,115,101, 10, - 9, 9, 9,105,115, 32, 61, 32,110,108, 42,112,111,119, 40, 49, 46, 48, 48, 48, 49, 32, 45, 32,110,118, 44, 32,100, 97,114,107, -110,101,115,115, 32, 45, 32, 49, 46, 48, 41, 59, 10, 9,125, 10,125, 10, 10,102,108,111, 97,116, 32,102,114,101,115,110,101,108, - 95,102, 97, 99, 40,118,101, 99, 51, 32,118,105,101,119, 44, 32,118,101, 99, 51, 32,118,110, 44, 32,102,108,111, 97,116, 32,103, -114, 97,100, 44, 32,102,108,111, 97,116, 32,102, 97, 99, 41, 10,123, 10, 9,102,108,111, 97,116, 32,116, 49, 44, 32,116, 50, 59, - 10, 9,102,108,111, 97,116, 32,102,102, 97, 99, 59, 10, 10, 9,105,102, 40,102, 97, 99, 61, 61, 48, 46, 48, 41, 32,123, 10, 9, - 9,102,102, 97, 99, 32, 61, 32, 49, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9,116, 49, 61, 32,100,111, -116, 40,118,105,101,119, 44, 32,118,110, 41, 59, 10, 9, 9,105,102, 40,116, 49, 62, 48, 46, 48, 41, 32, 32,116, 50, 61, 32, 49, - 46, 48, 43,116, 49, 59, 10, 9, 9,101,108,115,101, 32,116, 50, 61, 32, 49, 46, 48, 45,116, 49, 59, 10, 10, 9, 9,116, 50, 61, - 32,103,114, 97,100, 32, 43, 32, 40, 49, 46, 48, 45,103,114, 97,100, 41, 42,112,111,119, 40,116, 50, 44, 32,102, 97, 99, 41, 59, - 10, 10, 9, 9,105,102, 40,116, 50, 60, 48, 46, 48, 41, 32,102,102, 97, 99, 32, 61, 32, 48, 46, 48, 59, 10, 9, 9,101,108,115, -101, 32,105,102, 40,116, 50, 62, 49, 46, 48, 41, 32,102,102, 97, 99, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9,101,108,115,101, 32, -102,102, 97, 99, 32, 61, 32,116, 50, 59, 10, 9,125, 10, 10, 9,114,101,116,117,114,110, 32,102,102, 97, 99, 59, 10,125, 10, 10, -118,111,105,100, 32,115,104, 97,100,101, 95,100,105,102,102,117,115,101, 95,102,114,101,115,110,101,108, 40,118,101, 99, 51, 32, -118,110, 44, 32,118,101, 99, 51, 32,108,118, 44, 32,118,101, 99, 51, 32,118,105,101,119, 44, 32,102,108,111, 97,116, 32,102, 97, - 99, 95,105, 44, 32,102,108,111, 97,116, 32,102, 97, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,115, 41, 10,123, 10, - 9,105,115, 32, 61, 32,102,114,101,115,110,101,108, 95,102, 97, 99, 40,108,118, 44, 32,118,110, 44, 32,102, 97, 99, 95,105, 44, - 32,102, 97, 99, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95, 99,117, 98,105, 99, 40,102,108,111, 97,116, - 32,105,115, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,105,115, 41, 10,123, 10, 9,105,102, 40,105,115, 62, 48, - 46, 48, 32, 38, 38, 32,105,115, 60, 49, 46, 48, 41, 10, 9, 9,111,117,116,105,115, 61, 32,115,109,111,111,116,104,115,116,101, -112, 40, 48, 46, 48, 44, 32, 49, 46, 48, 44, 32,105,115, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,105,115, 61, 32, -105,115, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,118,105,115,105,102, 97, 99, 40,102,108,111, 97,116, 32, -105, 44, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 44, 32,102,108,111, 97,116, 32,114,101,102,108, 44, 32,111,117, -116, 32,102,108,111, 97,116, 32,111,117,116,105, 41, 10,123, 10, 9, 47, 42,105,102, 40,105, 32, 62, 32, 48, 46, 48, 41, 42, 47, - 10, 9, 9,111,117,116,105, 32, 61, 32,109, 97,120, 40,105, 42,118,105,115,105,102, 97, 99, 42,114,101,102,108, 44, 32, 48, 46, - 48, 41, 59, 10, 9, 47, 42,101,108,115,101, 10, 9, 9,111,117,116,105, 32, 61, 32,105, 59, 42, 47, 10,125, 10, 10,118,111,105, -100, 32,115,104, 97,100,101, 95,116, 97,110,103,101,110,116, 95,118, 95,115,112,101, 99, 40,118,101, 99, 51, 32,116, 97,110,103, - 44, 32,111,117,116, 32,118,101, 99, 51, 32,118,110, 41, 10,123, 10, 9,118,110, 32, 61, 32,116, 97,110,103, 59, 10,125, 10, 10, -118,111,105,100, 32,115,104, 97,100,101, 95, 97,100,100, 95,116,111, 95,100,105,102,102,117,115,101, 40,102,108,111, 97,116, 32, -105, 44, 32,118,101, 99, 51, 32,108, 97,109,112, 99,111,108, 44, 32,118,101, 99, 51, 32, 99,111,108, 44, 32,111,117,116, 32,118, -101, 99, 51, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,105,102, 40,105, 32, 62, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, - 99,111,108, 32, 61, 32,105, 42,108, 97,109,112, 99,111,108, 42, 99,111,108, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, - 99,111,108, 32, 61, 32,118,101, 99, 51, 40, 48, 46, 48, 44, 32, 48, 46, 48, 44, 32, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111, -105,100, 32,115,104, 97,100,101, 95,104,101,109,105, 95,115,112,101, 99, 40,118,101, 99, 51, 32,118,110, 44, 32,118,101, 99, 51, - 32,108,118, 44, 32,118,101, 99, 51, 32,118,105,101,119, 44, 32,102,108,111, 97,116, 32,115,112,101, 99, 44, 32,102,108,111, 97, -116, 32,104, 97,114,100, 44, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, - 32,116, 41, 10,123, 10, 9,108,118, 32, 43, 61, 32,118,105,101,119, 59, 10, 9,108,118, 32, 61, 32,110,111,114,109, 97,108,105, -122,101, 40,108,118, 41, 59, 10, 10, 9,116, 32, 61, 32,100,111,116, 40,118,110, 44, 32,108,118, 41, 59, 10, 9,116, 32, 61, 32, - 48, 46, 53, 42,116, 32, 43, 32, 48, 46, 53, 59, 10, 10, 9,116, 32, 61, 32,118,105,115,105,102, 97, 99, 42,115,112,101, 99, 42, -112,111,119, 40,116, 44, 32,104, 97,114,100, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,112,104,111,110, -103, 95,115,112,101, 99, 40,118,101, 99, 51, 32,110, 44, 32,118,101, 99, 51, 32,108, 44, 32,118,101, 99, 51, 32,118, 44, 32,102, -108,111, 97,116, 32,104, 97,114,100, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,115,112,101, 99,102, 97, 99, 41, 10,123, 10, - 9,118,101, 99, 51, 32,104, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,108, 32, 43, 32,118, 41, 59, 10, 9,102,108,111, - 97,116, 32,114,115,108,116, 32, 61, 32,109, 97,120, 40,100,111,116, 40,104, 44, 32,110, 41, 44, 32, 48, 46, 48, 41, 59, 10, 10, - 9,115,112,101, 99,102, 97, 99, 32, 61, 32,112,111,119, 40,114,115,108,116, 44, 32,104, 97,114,100, 41, 59, 10,125, 10, 10,118, -111,105,100, 32,115,104, 97,100,101, 95, 99,111,111,107,116,111,114,114, 95,115,112,101, 99, 40,118,101, 99, 51, 32,110, 44, 32, -118,101, 99, 51, 32,108, 44, 32,118,101, 99, 51, 32,118, 44, 32,102,108,111, 97,116, 32,104, 97,114,100, 44, 32,111,117,116, 32, -102,108,111, 97,116, 32,115,112,101, 99,102, 97, 99, 41, 10,123, 10, 9,118,101, 99, 51, 32,104, 32, 61, 32,110,111,114,109, 97, -108,105,122,101, 40,118, 32, 43, 32,108, 41, 59, 10, 9,102,108,111, 97,116, 32,110,104, 32, 61, 32,100,111,116, 40,110, 44, 32, -104, 41, 59, 10, 10, 9,105,102, 40,110,104, 32, 60, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,115,112,101, 99,102, 97, 99, 32, 61, - 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9,102,108,111, 97,116, 32,110,118, 32, 61, 32,109, 97, -120, 40,100,111,116, 40,110, 44, 32,118, 41, 44, 32, 48, 46, 48, 41, 59, 10, 9, 9,102,108,111, 97,116, 32,105, 32, 61, 32,112, -111,119, 40,110,104, 44, 32,104, 97,114,100, 41, 59, 10, 10, 9, 9,105, 32, 61, 32,105, 47, 40, 48, 46, 49, 43,110,118, 41, 59, - 10, 9, 9,115,112,101, 99,102, 97, 99, 32, 61, 32,105, 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, - 95, 98,108,105,110,110, 95,115,112,101, 99, 40,118,101, 99, 51, 32,110, 44, 32,118,101, 99, 51, 32,108, 44, 32,118,101, 99, 51, - 32,118, 44, 32,102,108,111, 97,116, 32,114,101,102,114, 97, 99, 44, 32,102,108,111, 97,116, 32,115,112,101, 99, 95,112,111,119, -101,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,115,112,101, 99,102, 97, 99, 41, 10,123, 10, 9,105,102, 40,114,101,102, -114, 97, 99, 32, 60, 32, 49, 46, 48, 41, 32,123, 10, 9, 9,115,112,101, 99,102, 97, 99, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, - 10, 9,101,108,115,101, 32,105,102, 40,115,112,101, 99, 95,112,111,119,101,114, 32, 61, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, - 9,115,112,101, 99,102, 97, 99, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9,105,102, 40, -115,112,101, 99, 95,112,111,119,101,114, 60, 49, 48, 48, 46, 48, 41, 10, 9, 9, 9,115,112,101, 99, 95,112,111,119,101,114, 61, - 32,115,113,114,116, 40, 49, 46, 48, 47,115,112,101, 99, 95,112,111,119,101,114, 41, 59, 10, 9, 9,101,108,115,101, 10, 9, 9, - 9,115,112,101, 99, 95,112,111,119,101,114, 61, 32, 49, 48, 46, 48, 47,115,112,101, 99, 95,112,111,119,101,114, 59, 10, 10, 9, - 9,118,101, 99, 51, 32,104, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,118, 32, 43, 32,108, 41, 59, 10, 9, 9,102,108, -111, 97,116, 32,110,104, 32, 61, 32,100,111,116, 40,110, 44, 32,104, 41, 59, 10, 9, 9,105,102, 40,110,104, 32, 60, 32, 48, 46, - 48, 41, 32,123, 10, 9, 9, 9,115,112,101, 99,102, 97, 99, 32, 61, 32, 48, 46, 48, 59, 10, 9, 9,125, 10, 9, 9,101,108,115, -101, 32,123, 10, 9, 9, 9,102,108,111, 97,116, 32,110,118, 32, 61, 32,109, 97,120, 40,100,111,116, 40,110, 44, 32,118, 41, 44, - 32, 48, 46, 48, 49, 41, 59, 10, 9, 9, 9,102,108,111, 97,116, 32,110,108, 32, 61, 32,100,111,116, 40,110, 44, 32,108, 41, 59, - 10, 9, 9, 9,105,102, 40,110,108, 32, 60, 61, 32, 48, 46, 48, 49, 41, 32,123, 10, 9, 9, 9, 9,115,112,101, 99,102, 97, 99, - 32, 61, 32, 48, 46, 48, 59, 10, 9, 9, 9,125, 10, 9, 9, 9,101,108,115,101, 32,123, 10, 9, 9, 9, 9,102,108,111, 97,116, - 32,118,104, 32, 61, 32,109, 97,120, 40,100,111,116, 40,118, 44, 32,104, 41, 44, 32, 48, 46, 48, 49, 41, 59, 10, 10, 9, 9, 9, - 9,102,108,111, 97,116, 32, 97, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9, 9, 9,102,108,111, 97,116, 32, 98, 32, 61, 32, 40, 50, - 46, 48, 42,110,104, 42,110,118, 41, 47,118,104, 59, 10, 9, 9, 9, 9,102,108,111, 97,116, 32, 99, 32, 61, 32, 40, 50, 46, 48, - 42,110,104, 42,110,108, 41, 47,118,104, 59, 10, 10, 9, 9, 9, 9,102,108,111, 97,116, 32,103, 32, 61, 32, 48, 46, 48, 59, 10, - 10, 9, 9, 9, 9,105,102, 40, 97, 32, 60, 32, 98, 32, 38, 38, 32, 97, 32, 60, 32, 99, 41, 32,103, 32, 61, 32, 97, 59, 10, 9, - 9, 9, 9,101,108,115,101, 32,105,102, 40, 98, 32, 60, 32, 97, 32, 38, 38, 32, 98, 32, 60, 32, 99, 41, 32,103, 32, 61, 32, 98, - 59, 10, 9, 9, 9, 9,101,108,115,101, 32,105,102, 40, 99, 32, 60, 32, 97, 32, 38, 38, 32, 99, 32, 60, 32, 98, 41, 32,103, 32, - 61, 32, 99, 59, 10, 10, 9, 9, 9, 9,102,108,111, 97,116, 32,112, 32, 61, 32,115,113,114,116, 40, 40, 40,114,101,102,114, 97, - 99, 32, 42, 32,114,101,102,114, 97, 99, 41, 43, 40,118,104, 42,118,104, 41, 45, 49, 46, 48, 41, 41, 59, 10, 9, 9, 9, 9,102, -108,111, 97,116, 32,102, 32, 61, 32, 40, 40, 40,112, 45,118,104, 41, 42, 40,112, 45,118,104, 41, 41, 47, 40, 40,112, 43,118,104, - 41, 42, 40,112, 43,118,104, 41, 41, 41, 42, 40, 49, 46, 48, 43, 40, 40, 40, 40,118,104, 42, 40,112, 43,118,104, 41, 41, 45, 49, - 46, 48, 41, 42, 40, 40,118,104, 42, 40,112, 43,118,104, 41, 41, 45, 49, 46, 48, 41, 41, 47, 40, 40, 40,118,104, 42, 40,112, 45, -118,104, 41, 41, 43, 49, 46, 48, 41, 42, 40, 40,118,104, 42, 40,112, 45,118,104, 41, 41, 43, 49, 46, 48, 41, 41, 41, 41, 59, 10, - 9, 9, 9, 9,102,108,111, 97,116, 32, 97,110,103, 32, 61, 32, 97, 99,111,115, 40,110,104, 41, 59, 10, 10, 9, 9, 9, 9,115, -112,101, 99,102, 97, 99, 32, 61, 32,109, 97,120, 40,102, 42,103, 42,101,120,112, 95, 98,108,101,110,100,101,114, 40, 40, 45, 40, - 97,110,103, 42, 97,110,103, 41, 47, 40, 50, 46, 48, 42,115,112,101, 99, 95,112,111,119,101,114, 42,115,112,101, 99, 95,112,111, -119,101,114, 41, 41, 41, 44, 32, 48, 46, 48, 41, 59, 10, 9, 9, 9,125, 10, 9, 9,125, 10, 9,125, 10,125, 10, 10,118,111,105, -100, 32,115,104, 97,100,101, 95,119, 97,114,100,105,115,111, 95,115,112,101, 99, 40,118,101, 99, 51, 32,110, 44, 32,118,101, 99, - 51, 32,108, 44, 32,118,101, 99, 51, 32,118, 44, 32,102,108,111, 97,116, 32,114,109,115, 44, 32,111,117,116, 32,102,108,111, 97, -116, 32,115,112,101, 99,102, 97, 99, 41, 10,123, 10, 9,118,101, 99, 51, 32,104, 32, 61, 32,110,111,114,109, 97,108,105,122,101, - 40,108, 32, 43, 32,118, 41, 59, 10, 9,102,108,111, 97,116, 32,110,104, 32, 61, 32,109, 97,120, 40,100,111,116, 40,110, 44, 32, -104, 41, 44, 32, 48, 46, 48, 48, 49, 41, 59, 10, 9,102,108,111, 97,116, 32,110,118, 32, 61, 32,109, 97,120, 40,100,111,116, 40, -110, 44, 32,118, 41, 44, 32, 48, 46, 48, 48, 49, 41, 59, 10, 9,102,108,111, 97,116, 32,110,108, 32, 61, 32,109, 97,120, 40,100, -111,116, 40,110, 44, 32,108, 41, 44, 32, 48, 46, 48, 48, 49, 41, 59, 10, 9,102,108,111, 97,116, 32, 97,110,103,108,101, 32, 61, - 32,116, 97,110, 40, 97, 99,111,115, 40,110,104, 41, 41, 59, 10, 9,102,108,111, 97,116, 32, 97,108,112,104, 97, 32, 61, 32,109, - 97,120, 40,114,109,115, 44, 32, 48, 46, 48, 48, 49, 41, 59, 10, 10, 9,115,112,101, 99,102, 97, 99, 61, 32,110,108, 32, 42, 32, - 40, 49, 46, 48, 47, 40, 52, 46, 48, 42, 77, 95, 80, 73, 42, 97,108,112,104, 97, 42, 97,108,112,104, 97, 41, 41, 42, 40,101,120, -112, 95, 98,108,101,110,100,101,114, 40, 45, 40, 97,110,103,108,101, 42, 97,110,103,108,101, 41, 47, 40, 97,108,112,104, 97, 42, - 97,108,112,104, 97, 41, 41, 47, 40,115,113,114,116, 40,110,118, 42,110,108, 41, 41, 41, 59, 10,125, 10, 10,118,111,105,100, 32, -115,104, 97,100,101, 95,116,111,111,110, 95,115,112,101, 99, 40,118,101, 99, 51, 32,110, 44, 32,118,101, 99, 51, 32,108, 44, 32, -118,101, 99, 51, 32,118, 44, 32,102,108,111, 97,116, 32,115,105,122,101, 44, 32,102,108,111, 97,116, 32,116,115,109,111,111,116, -104, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,115,112,101, 99,102, 97, 99, 41, 10,123, 10, 9,118,101, 99, 51, 32,104, 32, - 61, 32,110,111,114,109, 97,108,105,122,101, 40,108, 32, 43, 32,118, 41, 59, 10, 9,102,108,111, 97,116, 32,114,115,108,116, 32, - 61, 32,100,111,116, 40,104, 44, 32,110, 41, 59, 10, 9,102,108,111, 97,116, 32, 97,110,103, 32, 61, 32, 97, 99,111,115, 40,114, -115,108,116, 41, 59, 10, 10, 9,105,102, 40, 97,110,103, 32, 60, 32,115,105,122,101, 41, 32,114,115,108,116, 32, 61, 32, 49, 46, - 48, 59, 10, 9,101,108,115,101, 32,105,102, 40, 97,110,103, 32, 62, 61, 32, 40,115,105,122,101, 32, 43, 32,116,115,109,111,111, -116,104, 41, 32,124,124, 32,116,115,109,111,111,116,104, 32, 61, 61, 32, 48, 46, 48, 41, 32,114,115,108,116, 32, 61, 32, 48, 46, - 48, 59, 10, 9,101,108,115,101, 32,114,115,108,116, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40, 40, 97,110,103, 32, 45, 32,115,105, -122,101, 41, 47,116,115,109,111,111,116,104, 41, 59, 10, 10, 9,115,112,101, 99,102, 97, 99, 32, 61, 32,114,115,108,116, 59, 10, -125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,115,112,101, 99, 95, 97,114,101, 97, 95,105,110,112, 40,102,108,111, 97, -116, 32,115,112,101, 99,102, 97, 99, 44, 32,102,108,111, 97,116, 32,105,110,112, 44, 32,111,117,116, 32,102,108,111, 97,116, 32, -111,117,116,115,112,101, 99,102, 97, 99, 41, 10,123, 10, 9,111,117,116,115,112,101, 99,102, 97, 99, 32, 61, 32,115,112,101, 99, -102, 97, 99, 42,105,110,112, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,115,112,101, 99, 95,116, 40,102,108, -111, 97,116, 32,115,104, 97,100,102, 97, 99, 44, 32,102,108,111, 97,116, 32,115,112,101, 99, 44, 32,102,108,111, 97,116, 32,118, -105,115,105,102, 97, 99, 44, 32,102,108,111, 97,116, 32,115,112,101, 99,102, 97, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, - 32,116, 41, 10,123, 10, 9,116, 32, 61, 32,115,104, 97,100,102, 97, 99, 42,115,112,101, 99, 42,118,105,115,105,102, 97, 99, 42, -115,112,101, 99,102, 97, 99, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95, 97,100,100, 95,115,112,101, 99, 40, -102,108,111, 97,116, 32,116, 44, 32,118,101, 99, 51, 32,108, 97,109,112, 99,111,108, 44, 32,118,101, 99, 51, 32,115,112,101, 99, - 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, - 61, 32,116, 42,108, 97,109,112, 99,111,108, 42,115,112,101, 99, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97, -100,101, 95, 97,100,100, 40,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, - 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 32, 43, - 32, 99,111,108, 50, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,109, 97,100,100, 40,118,101, 99, 52, 32, 99, -111,108, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, - 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 32, 43, 32, 99,111,108, - 49, 42, 99,111,108, 50, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95, 97,100,100, 95, 99,108, 97,109,112,101, -100, 40,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, - 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 32, 43, 32,109, 97,120, 40, - 99,111,108, 50, 44, 32,118,101, 99, 52, 40, 48, 46, 48, 44, 32, 48, 46, 48, 44, 32, 48, 46, 48, 44, 32, 48, 46, 48, 41, 41, 59, - 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,109, 97,100,100, 95, 99,108, 97,109,112,101,100, 40,118,101, 99, 52, - 32, 99,111,108, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32, -118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 32, 43, 32,109, - 97,120, 40, 99,111,108, 49, 42, 99,111,108, 50, 44, 32,118,101, 99, 52, 40, 48, 46, 48, 44, 32, 48, 46, 48, 44, 32, 48, 46, 48, - 44, 32, 48, 46, 48, 41, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,109, 97,100,100,102, 40,118,101, 99, - 52, 32, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,111,117,116, 32,118, -101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 32, 43, 32,102, 42, - 99,111,108, 49, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,109,117,108, 40,118,101, 99, 52, 32, 99,111,108, - 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, - 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 42, 99,111,108, 50, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, - 97,100,101, 95,109,117,108, 95,118, 97,108,117,101, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111, -108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32, - 99,111,108, 42,102, 97, 99, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,111, 98, 99,111,108,111,114, 40,118, -101, 99, 52, 32, 99,111,108, 44, 32,118,101, 99, 52, 32,111, 98, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117, -116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32,118,101, 99, 52, 40, 99,111,108, 46,114,103, 98, 42,111, - 98, 99,111,108, 46,114,103, 98, 44, 32, 99,111,108, 46, 97, 41, 59, 10,125, 10, 10,118,111,105,100, 32,114, 97,109,112, 95,114, -103, 98,116,111, 98,119, 40,118,101, 99, 51, 32, 99,111,108,111,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116, -118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 99,111,108,111,114, 46,114, 42, 48, 46, 51, 32, 43, 32, 99, -111,108,111,114, 46,103, 42, 48, 46, 53, 56, 32, 43, 32, 99,111,108,111,114, 46, 98, 42, 48, 46, 49, 50, 59, 10,125, 10, 10,118, -111,105,100, 32,115,104, 97,100,101, 95,111,110,108,121, 95,115,104, 97,100,111,119, 40,102,108,111, 97,116, 32,105, 44, 32,102, -108,111, 97,116, 32,115,104, 97,100,102, 97, 99, 44, 32,102,108,111, 97,116, 32,101,110,101,114,103,121, 44, 32,111,117,116, 32, -102,108,111, 97,116, 32,111,117,116,115,104, 97,100,102, 97, 99, 41, 10,123, 10, 9,111,117,116,115,104, 97,100,102, 97, 99, 32, - 61, 32,105, 42,101,110,101,114,103,121, 42, 40, 49, 46, 48, 32, 45, 32,115,104, 97,100,102, 97, 99, 41, 59, 10,125, 10, 10,118, -111,105,100, 32,115,104, 97,100,101, 95,111,110,108,121, 95,115,104, 97,100,111,119, 95,100,105,102,102,117,115,101, 40,102,108, -111, 97,116, 32,115,104, 97,100,102, 97, 99, 44, 32,118,101, 99, 51, 32,114,103, 98, 44, 32,118,101, 99, 52, 32,100,105,102,102, - 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116,100,105,102,102, 41, 10,123, 10, 9,111,117,116,100,105,102,102, 32, 61, - 32,100,105,102,102, 32, 45, 32,118,101, 99, 52, 40,114,103, 98, 42,115,104, 97,100,102, 97, 99, 44, 32, 48, 46, 48, 41, 59, 10, -125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,111,110,108,121, 95,115,104, 97,100,111,119, 95,115,112,101, 99,117,108, - 97,114, 40,102,108,111, 97,116, 32,115,104, 97,100,102, 97, 99, 44, 32,118,101, 99, 51, 32,115,112,101, 99,114,103, 98, 44, 32, -118,101, 99, 52, 32,115,112,101, 99, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116,115,112,101, 99, 41, 10,123, 10, 9, -111,117,116,115,112,101, 99, 32, 61, 32,115,112,101, 99, 32, 45, 32,118,101, 99, 52, 40,115,112,101, 99,114,103, 98, 42,115,104, - 97,100,102, 97, 99, 44, 32, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,115,116, 95,115,104, 97,100,111,119, - 98,117,102, 40,118,101, 99, 51, 32,114, 99,111, 44, 32,115, 97,109,112,108,101,114, 50, 68, 83,104, 97,100,111,119, 32,115,104, - 97,100,111,119,109, 97,112, 44, 32,109, 97,116, 52, 32,115,104, 97,100,111,119,112,101,114,115,109, 97,116, 44, 32,102,108,111, - 97,116, 32,115,104, 97,100,111,119, 98,105, 97,115, 44, 32,102,108,111, 97,116, 32,105,110,112, 44, 32,111,117,116, 32,102,108, -111, 97,116, 32,114,101,115,117,108,116, 41, 10,123, 10, 9,105,102, 40,105,110,112, 32, 60, 61, 32, 48, 46, 48, 41, 32,123, 10, - 9, 9,114,101,115,117,108,116, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9,118,101, 99, - 52, 32, 99,111, 32, 61, 32,115,104, 97,100,111,119,112,101,114,115,109, 97,116, 42,118,101, 99, 52, 40,114, 99,111, 44, 32, 49, - 46, 48, 41, 59, 10, 10, 9, 9, 47, 47,102,108,111, 97,116, 32, 98,105, 97,115, 32, 61, 32, 40, 49, 46, 53, 32, 45, 32,105,110, -112, 42,105,110,112, 41, 42,115,104, 97,100,111,119, 98,105, 97,115, 59, 10, 9, 9, 99,111, 46,122, 32, 45, 61, 32,115,104, 97, -100,111,119, 98,105, 97,115, 42, 99,111, 46,119, 59, 10, 10, 9, 9,114,101,115,117,108,116, 32, 61, 32,115,104, 97,100,111,119, - 50, 68, 80,114,111,106, 40,115,104, 97,100,111,119,109, 97,112, 44, 32, 99,111, 41, 46,120, 59, 10, 9,125, 10,125, 10, 10,118, -111,105,100, 32,115,104, 97,100,101, 95,101,120,112,111,115,117,114,101, 95, 99,111,114,114,101, 99,116, 40,118,101, 99, 51, 32, - 99,111,108, 44, 32,102,108,111, 97,116, 32,108,105,110,102, 97, 99, 44, 32,102,108,111, 97,116, 32,108,111,103,102, 97, 99, 44, - 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32,108,105, -110,102, 97, 99, 42, 40, 49, 46, 48, 32, 45, 32,101,120,112, 40, 99,111,108, 42,108,111,103,102, 97, 99, 41, 41, 59, 10,125, 10, - 10,118,111,105,100, 32,115,104, 97,100,101, 95,109,105,115,116, 95,102, 97, 99,116,111,114, 40,118,101, 99, 51, 32, 99,111, 44, - 32,102,108,111, 97,116, 32,109,105,115,116,115,116, 97, 44, 32,102,108,111, 97,116, 32,109,105,115,116,100,105,115,116, 44, 32, -102,108,111, 97,116, 32,109,105,115,116,116,121,112,101, 44, 32,102,108,111, 97,116, 32,109,105,115,105, 44, 32,111,117,116, 32, -102,108,111, 97,116, 32,111,117,116,102, 97, 99, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99, 44, 32,122, 99,111,114, - 59, 10, 10, 9,122, 99,111,114, 32, 61, 32, 40,103,108, 95, 80,114,111,106,101, 99,116,105,111,110, 77, 97,116,114,105,120, 91, - 51, 93, 91, 51, 93, 32, 61, 61, 32, 48, 46, 48, 41, 63, 32,108,101,110,103,116,104, 40, 99,111, 41, 58, 32, 45, 99,111, 91, 50, - 93, 59, 10, 9, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40, 40,122, 99,111,114, 45,109,105,115,116,115,116, 97, 41, - 47,109,105,115,116,100,105,115,116, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,105,102, 40,109,105,115,116,116,121, -112,101, 32, 61, 61, 32, 48, 46, 48, 41, 32,102, 97, 99, 32, 42, 61, 32,102, 97, 99, 59, 10, 9,101,108,115,101, 32,105,102, 40, -109,105,115,116,116,121,112,101, 32, 61, 61, 32, 49, 46, 48, 41, 59, 10, 9,101,108,115,101, 32,102, 97, 99, 32, 61, 32,115,113, -114,116, 40,102, 97, 99, 41, 59, 10, 10, 9,111,117,116,102, 97, 99, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40, 49, 46, 48, 45,102, - 97, 99, 41, 42, 40, 49, 46, 48, 45,109,105,115,105, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,119,111, -114,108,100, 95,109,105,120, 40,118,101, 99, 51, 32,104,111,114, 44, 32,118,101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32, -118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99, 32, 61, 32, 99,108, 97,109, -112, 40, 99,111,108, 46, 97, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, 32,118,101, - 99, 52, 40,109,105,120, 40,104,111,114, 44, 32, 99,111,108, 46,114,103, 98, 44, 32,102, 97, 99, 41, 44, 32, 99,111,108, 46, 97, - 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95, 97,108,112,104, 97, 95,111,112, 97,113,117,101, 40,118,101, - 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99, -111,108, 32, 61, 32,118,101, 99, 52, 40, 99,111,108, 46,114,103, 98, 44, 32, 49, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, - 32,115,104, 97,100,101, 95, 97,108,112,104, 97, 95,111, 98, 99,111,108,111,114, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,118, -101, 99, 52, 32,111, 98, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111, -117,116, 99,111,108, 32, 61, 32,118,101, 99, 52, 40, 99,111,108, 46,114,103, 98, 44, 32, 99,111,108, 46, 97, 42,111, 98, 99,111, -108, 46, 97, 41, 59, 10,125, 10, 10, 47, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 32, 78, 69, 87, 32, 83, 72, 65, 68, 69, 82, - 32, 85, 84, 73, 76, 73, 84, 73, 69, 83, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 47, 10, 10,102,108,111, 97, -116, 32,102,114,101,115,110,101,108, 95,100,105,101,108,101, 99,116,114,105, 99, 40,118,101, 99, 51, 32, 73,110, 99,111,109,105, -110,103, 44, 32,118,101, 99, 51, 32, 78,111,114,109, 97,108, 44, 32,102,108,111, 97,116, 32,101,116, 97, 41, 10,123, 10, 32, 32, - 32, 32, 47, 42, 32, 99,111,109,112,117,116,101, 32,102,114,101,115,110,101,108, 32,114,101,102,108,101, 99,116, 97,110, 99,101, - 32,119,105,116,104,111,117,116, 32,101,120,112,108,105, 99,105,116,108,121, 32, 99,111,109,112,117,116,105,110,103, 10, 32, 32, - 32, 32, 32, 32, 32,116,104,101, 32,114,101,102,114, 97, 99,116,101,100, 32,100,105,114,101, 99,116,105,111,110, 32, 42, 47, 10, - 32, 32, 32, 32,102,108,111, 97,116, 32, 99, 32, 61, 32, 97, 98,115, 40,100,111,116, 40, 73,110, 99,111,109,105,110,103, 44, 32, - 78,111,114,109, 97,108, 41, 41, 59, 10, 32, 32, 32, 32,102,108,111, 97,116, 32,103, 32, 61, 32,101,116, 97, 32, 42, 32,101,116, - 97, 32, 45, 32, 49, 46, 48, 32, 43, 32, 99, 32, 42, 32, 99, 59, 10, 32, 32, 32, 32,102,108,111, 97,116, 32,114,101,115,117,108, -116, 59, 10, 10, 32, 32, 32, 32,105,102, 40,103, 32, 62, 32, 48, 46, 48, 41, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,103, 32, - 61, 32,115,113,114,116, 40,103, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32,102,108,111, 97,116, 32, 65, 32, 61, 40,103, 32, 45, - 32, 99, 41, 47, 40,103, 32, 43, 32, 99, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32,102,108,111, 97,116, 32, 66, 32, 61, 40, 99, - 32, 42, 40,103, 32, 43, 32, 99, 41, 45, 32, 49, 46, 48, 41, 47, 40, 99, 32, 42, 40,103, 32, 45, 32, 99, 41, 43, 32, 49, 46, 48, - 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,115,117,108,116, 32, 61, 32, 48, 46, 53, 32, 42, 32, 65, 32, 42, 32, 65, 32, - 42, 40, 49, 46, 48, 32, 43, 32, 66, 32, 42, 32, 66, 41, 59, 10, 32, 32, 32, 32,125, 10, 32, 32, 32, 32,101,108,115,101, 10, 32, - 32, 32, 32, 32, 32, 32, 32,114,101,115,117,108,116, 32, 61, 32, 49, 46, 48, 59, 32, 32, 47, 42, 32, 84, 73, 82, 32, 40,110,111, - 32,114,101,102,114, 97, 99,116,101,100, 32, 99,111,109,112,111,110,101,110,116, 41, 32, 42, 47, 10, 10, 32, 32, 32, 32,114,101, -116,117,114,110, 32,114,101,115,117,108,116, 59, 10,125, 10, 10,102,108,111, 97,116, 32,104,121,112,111,116, 40,102,108,111, 97, -116, 32,120, 44, 32,102,108,111, 97,116, 32,121, 41, 10,123, 10, 9,114,101,116,117,114,110, 32,115,113,114,116, 40,120, 42,120, - 32, 43, 32,121, 42,121, 41, 59, 10,125, 10, 10, 47, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 32, 78, 69, 87, 32, 83, 72, 65, - 68, 69, 82, 32, 78, 79, 68, 69, 83, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 47, 10, 10, 35,100,101,102, -105,110,101, 32, 78, 85, 77, 95, 76, 73, 71, 72, 84, 83, 32, 51, 10, 10, 47, 42, 32, 98,115,100,102,115, 32, 42, 47, 10, 10,118, -111,105,100, 32,110,111,100,101, 95, 98,115,100,102, 95,100,105,102,102,117,115,101, 40,118,101, 99, 52, 32, 99,111,108,111,114, - 44, 32,102,108,111, 97,116, 32,114,111,117,103,104,110,101,115,115, 44, 32,118,101, 99, 51, 32, 78, 44, 32,111,117,116, 32,118, -101, 99, 52, 32,114,101,115,117,108,116, 41, 10,123, 10, 9, 47, 42, 32, 97,109, 98,105,101,110,116, 32,108,105,103,104,116, 32, - 42, 47, 10, 9,118,101, 99, 51, 32, 76, 32, 61, 32,118,101, 99, 51, 40, 48, 46, 50, 41, 59, 10, 10, 9, 47, 42, 32,100,105,114, -101, 99,116,105,111,110, 97,108, 32,108,105,103,104,116,115, 32, 42, 47, 10, 9,102,111,114, 40,105,110,116, 32,105, 32, 61, 32, - 48, 59, 32,105, 32, 60, 32, 78, 85, 77, 95, 76, 73, 71, 72, 84, 83, 59, 32,105, 43, 43, 41, 32,123, 10, 9, 9,118,101, 99, 51, - 32,108,105,103,104,116, 95,112,111,115,105,116,105,111,110, 32, 61, 32,103,108, 95, 76,105,103,104,116, 83,111,117,114, 99,101, - 91,105, 93, 46,112,111,115,105,116,105,111,110, 46,120,121,122, 59, 10, 9, 9,118,101, 99, 51, 32,108,105,103,104,116, 95,100, -105,102,102,117,115,101, 32, 61, 32,103,108, 95, 76,105,103,104,116, 83,111,117,114, 99,101, 91,105, 93, 46,100,105,102,102,117, -115,101, 46,114,103, 98, 59, 10, 10, 9, 9,102,108,111, 97,116, 32, 98,115,100,102, 32, 61, 32,109, 97,120, 40,100,111,116, 40, - 78, 44, 32,108,105,103,104,116, 95,112,111,115,105,116,105,111,110, 41, 44, 32, 48, 46, 48, 41, 59, 10, 9, 9, 76, 32, 43, 61, - 32,108,105,103,104,116, 95,100,105,102,102,117,115,101, 42, 98,115,100,102, 59, 10, 9,125, 10, 10, 9,114,101,115,117,108,116, - 32, 61, 32,118,101, 99, 52, 40, 76, 42, 99,111,108,111,114, 46,114,103, 98, 44, 32, 49, 46, 48, 41, 59, 10,125, 10, 10,118,111, -105,100, 32,110,111,100,101, 95, 98,115,100,102, 95,103,108,111,115,115,121, 40,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32, -102,108,111, 97,116, 32,114,111,117,103,104,110,101,115,115, 44, 32,118,101, 99, 51, 32, 78, 44, 32,118,101, 99, 51, 32, 73, 44, - 32,111,117,116, 32,118,101, 99, 52, 32,114,101,115,117,108,116, 41, 10,123, 10, 9, 47, 42, 32, 97,109, 98,105,101,110,116, 32, -108,105,103,104,116, 32, 42, 47, 10, 9,118,101, 99, 51, 32, 76, 32, 61, 32,118,101, 99, 51, 40, 48, 46, 50, 41, 59, 10, 10, 9, - 47, 42, 32,100,105,114,101, 99,116,105,111,110, 97,108, 32,108,105,103,104,116,115, 32, 42, 47, 10, 9,102,111,114, 40,105,110, -116, 32,105, 32, 61, 32, 48, 59, 32,105, 32, 60, 32, 78, 85, 77, 95, 76, 73, 71, 72, 84, 83, 59, 32,105, 43, 43, 41, 32,123, 10, - 9, 9,118,101, 99, 51, 32,108,105,103,104,116, 95,112,111,115,105,116,105,111,110, 32, 61, 32,103,108, 95, 76,105,103,104,116, - 83,111,117,114, 99,101, 91,105, 93, 46,112,111,115,105,116,105,111,110, 46,120,121,122, 59, 10, 9, 9,118,101, 99, 51, 32, 72, - 32, 61, 32,103,108, 95, 76,105,103,104,116, 83,111,117,114, 99,101, 91,105, 93, 46,104, 97,108,102, 86,101, 99,116,111,114, 46, -120,121,122, 59, 10, 9, 9,118,101, 99, 51, 32,108,105,103,104,116, 95,100,105,102,102,117,115,101, 32, 61, 32,103,108, 95, 76, -105,103,104,116, 83,111,117,114, 99,101, 91,105, 93, 46,100,105,102,102,117,115,101, 46,114,103, 98, 59, 10, 9, 9,118,101, 99, - 51, 32,108,105,103,104,116, 95,115,112,101, 99,117,108, 97,114, 32, 61, 32,103,108, 95, 76,105,103,104,116, 83,111,117,114, 99, -101, 91,105, 93, 46,115,112,101, 99,117,108, 97,114, 46,114,103, 98, 59, 10, 10, 9, 9, 47, 42, 32,119,101, 32,109,105,120, 32, -105,110, 32,115,111,109,101, 32,100,105,102,102,117,115,101, 32,115,111, 32,108,111,119, 32,114,111,117,103,104,110,101,115,115, - 32,115,116,105,108,108, 32,115,104,111,119,115, 32,117,112, 32, 42, 47, 10, 9, 9,102,108,111, 97,116, 32, 98,115,100,102, 32, - 61, 32, 48, 46, 53, 42,112,111,119, 40,109, 97,120, 40,100,111,116, 40, 78, 44, 32, 72, 41, 44, 32, 48, 46, 48, 41, 44, 32, 49, - 46, 48, 47,114,111,117,103,104,110,101,115,115, 41, 59, 10, 9, 9, 98,115,100,102, 32, 43, 61, 32, 48, 46, 53, 42,109, 97,120, - 40,100,111,116, 40, 78, 44, 32,108,105,103,104,116, 95,112,111,115,105,116,105,111,110, 41, 44, 32, 48, 46, 48, 41, 59, 10, 9, - 9, 76, 32, 43, 61, 32,108,105,103,104,116, 95,115,112,101, 99,117,108, 97,114, 42, 98,115,100,102, 59, 10, 9,125, 10, 10, 9, -114,101,115,117,108,116, 32, 61, 32,118,101, 99, 52, 40, 76, 42, 99,111,108,111,114, 46,114,103, 98, 44, 32, 49, 46, 48, 41, 59, - 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95, 98,115,100,102, 95, 97,110,105,115,111,116,114,111,112,105, 99, 40,118, -101, 99, 52, 32, 99,111,108,111,114, 44, 32,102,108,111, 97,116, 32,114,111,117,103,104,110,101,115,115, 85, 44, 32,102,108,111, - 97,116, 32,114,111,117,103,104,110,101,115,115, 86, 44, 32,118,101, 99, 51, 32, 78, 44, 32,118,101, 99, 51, 32, 73, 44, 32,111, -117,116, 32,118,101, 99, 52, 32,114,101,115,117,108,116, 41, 10,123, 10, 9,110,111,100,101, 95, 98,115,100,102, 95,100,105,102, -102,117,115,101, 40, 99,111,108,111,114, 44, 32, 48, 46, 48, 44, 32, 78, 44, 32,114,101,115,117,108,116, 41, 59, 10,125, 10, 10, -118,111,105,100, 32,110,111,100,101, 95, 98,115,100,102, 95,103,108, 97,115,115, 40,118,101, 99, 52, 32, 99,111,108,111,114, 44, - 32,102,108,111, 97,116, 32,114,111,117,103,104,110,101,115,115, 44, 32,102,108,111, 97,116, 32,105,111,114, 44, 32,118,101, 99, - 51, 32, 78, 44, 32,118,101, 99, 51, 32, 73, 44, 32,111,117,116, 32,118,101, 99, 52, 32,114,101,115,117,108,116, 41, 10,123, 10, - 9,110,111,100,101, 95, 98,115,100,102, 95,100,105,102,102,117,115,101, 40, 99,111,108,111,114, 44, 32, 48, 46, 48, 44, 32, 78, - 44, 32,114,101,115,117,108,116, 41, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95, 98,115,100,102, 95,116,114, 97, -110,115,108,117, 99,101,110,116, 40,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,118,101, 99, 51, 32, 78, 44, 32,111,117,116, - 32,118,101, 99, 52, 32,114,101,115,117,108,116, 41, 10,123, 10, 9,110,111,100,101, 95, 98,115,100,102, 95,100,105,102,102,117, -115,101, 40, 99,111,108,111,114, 44, 32, 48, 46, 48, 44, 32, 78, 44, 32,114,101,115,117,108,116, 41, 59, 10,125, 10, 10,118,111, -105,100, 32,110,111,100,101, 95, 98,115,100,102, 95,116,114, 97,110,115,112, 97,114,101,110,116, 40,118,101, 99, 52, 32, 99,111, -108,111,114, 44, 32,111,117,116, 32,118,101, 99, 52, 32,114,101,115,117,108,116, 41, 10,123, 10, 9, 47, 42, 32,116,104,105,115, - 32,105,115,110, 39,116, 32,114,105,103,104,116, 32, 42, 47, 10, 9,114,101,115,117,108,116, 46,114, 32, 61, 32, 99,111,108,111, -114, 46,114, 59, 10, 9,114,101,115,117,108,116, 46,103, 32, 61, 32, 99,111,108,111,114, 46,103, 59, 10, 9,114,101,115,117,108, -116, 46, 98, 32, 61, 32, 99,111,108,111,114, 46, 98, 59, 10, 9,114,101,115,117,108,116, 46, 97, 32, 61, 32, 48, 46, 48, 59, 10, -125, 10, 10,118,111,105,100, 32,110,111,100,101, 95, 98,115,100,102, 95,118,101,108,118,101,116, 40,118,101, 99, 52, 32, 99,111, -108,111,114, 44, 32,102,108,111, 97,116, 32,115,105,103,109, 97, 44, 32,118,101, 99, 51, 32, 78, 44, 32,111,117,116, 32,118,101, - 99, 52, 32,114,101,115,117,108,116, 41, 10,123, 10, 9,110,111,100,101, 95, 98,115,100,102, 95,100,105,102,102,117,115,101, 40, - 99,111,108,111,114, 44, 32, 48, 46, 48, 44, 32, 78, 44, 32,114,101,115,117,108,116, 41, 59, 10,125, 10, 10, 47, 42, 32,101,109, -105,115,115,105,111,110, 32, 42, 47, 10, 10,118,111,105,100, 32,110,111,100,101, 95,101,109,105,115,115,105,111,110, 40,118,101, - 99, 52, 32, 99,111,108,111,114, 44, 32,102,108,111, 97,116, 32,115,116,114,101,110,103,116,104, 44, 32,118,101, 99, 51, 32, 78, - 44, 32,111,117,116, 32,118,101, 99, 52, 32,114,101,115,117,108,116, 41, 10,123, 10, 9,114,101,115,117,108,116, 32, 61, 32, 99, -111,108,111,114, 42,115,116,114,101,110,103,116,104, 59, 10,125, 10, 10, 47, 42, 32, 99,108,111,115,117,114,101,115, 32, 42, 47, - 10, 10,118,111,105,100, 32,110,111,100,101, 95,109,105,120, 95,115,104, 97,100,101,114, 40,102,108,111, 97,116, 32,102, 97, 99, - 44, 32,118,101, 99, 52, 32,115,104, 97,100,101,114, 49, 44, 32,118,101, 99, 52, 32,115,104, 97,100,101,114, 50, 44, 32,111,117, -116, 32,118,101, 99, 52, 32,115,104, 97,100,101,114, 41, 10,123, 10, 9,115,104, 97,100,101,114, 32, 61, 32,109,105,120, 40,115, -104, 97,100,101,114, 49, 44, 32,115,104, 97,100,101,114, 50, 44, 32,102, 97, 99, 41, 59, 10,125, 10, 10,118,111,105,100, 32,110, -111,100,101, 95, 97,100,100, 95,115,104, 97,100,101,114, 40,118,101, 99, 52, 32,115,104, 97,100,101,114, 49, 44, 32,118,101, 99, - 52, 32,115,104, 97,100,101,114, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,115,104, 97,100,101,114, 41, 10,123, 10, 9,115, -104, 97,100,101,114, 32, 61, 32,115,104, 97,100,101,114, 49, 32, 43, 32,115,104, 97,100,101,114, 50, 59, 10,125, 10, 10, 47, 42, - 32,102,114,101,115,110,101,108, 32, 42, 47, 10, 10,118,111,105,100, 32,110,111,100,101, 95,102,114,101,115,110,101,108, 40,102, -108,111, 97,116, 32,105,111,114, 44, 32,118,101, 99, 51, 32, 78, 44, 32,118,101, 99, 51, 32, 73, 44, 32,111,117,116, 32,102,108, -111, 97,116, 32,114,101,115,117,108,116, 41, 10,123, 10, 9,102,108,111, 97,116, 32,101,116, 97, 32, 61, 32,109, 97,120, 40,105, -111,114, 44, 32, 48, 46, 48, 48, 48, 48, 49, 41, 59, 10, 9,114,101,115,117,108,116, 32, 61, 32,102,114,101,115,110,101,108, 95, -100,105,101,108,101, 99,116,114,105, 99, 40, 73, 44, 32, 78, 44, 32,101,116, 97, 41, 59, 32, 47, 47, 98, 97, 99,107,102, 97, 99, -105,110,103, 40, 41, 63, 32, 49, 46, 48, 47,101,116, 97, 58, 32,101,116, 97, 41, 59, 10,125, 10, 10, 47, 42, 32,103,101,111,109, -101,116,114,121, 32, 42, 47, 10, 10,118,111,105,100, 32,110,111,100,101, 95,103,101,111,109,101,116,114,121, 40,118,101, 99, 51, - 32, 73, 44, 32,118,101, 99, 51, 32, 78, 44, 32,109, 97,116, 52, 32,116,111,119,111,114,108,100, 44, 10, 9,111,117,116, 32,118, -101, 99, 51, 32,112,111,115,105,116,105,111,110, 44, 32,111,117,116, 32,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,111, -117,116, 32,118,101, 99, 51, 32,116, 97,110,103,101,110,116, 44, 10, 9,111,117,116, 32,118,101, 99, 51, 32,116,114,117,101, 95, -110,111,114,109, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,109,105,110,103, 44, 32,111,117,116, 32,118, -101, 99, 51, 32,112, 97,114, 97,109,101,116,114,105, 99, 44, 10, 9,111,117,116, 32,102,108,111, 97,116, 32, 98, 97, 99,107,102, - 97, 99,105,110,103, 41, 10,123, 10, 9,112,111,115,105,116,105,111,110, 32, 61, 32, 40,116,111,119,111,114,108,100, 42,118,101, - 99, 52, 40, 73, 44, 32, 49, 46, 48, 41, 41, 46,120,121,122, 59, 10, 9,110,111,114,109, 97,108, 32, 61, 32, 78, 59, 10, 9,116, - 97,110,103,101,110,116, 32, 61, 32,118,101, 99, 51, 40, 48, 46, 48, 41, 59, 10, 9,116,114,117,101, 95,110,111,114,109, 97,108, - 32, 61, 32, 78, 59, 10, 9,105,110, 99,111,109,105,110,103, 32, 61, 32, 73, 59, 10, 9,112, 97,114, 97,109,101,116,114,105, 99, - 32, 61, 32,118,101, 99, 51, 40, 48, 46, 48, 41, 59, 10, 9, 98, 97, 99,107,102, 97, 99,105,110,103, 32, 61, 32, 48, 46, 48, 59, - 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95,116,101,120, 95, 99,111,111,114,100, 40,118,101, 99, 51, 32, 73, 44, 32, -118,101, 99, 51, 32, 78, 44, 32,109, 97,116, 52, 32,116,111,119,111,114,108,100, 44, 10, 9,118,101, 99, 51, 32, 97,116,116,114, - 95,111,114, 99,111, 44, 32,118,101, 99, 51, 32, 97,116,116,114, 95,117,118, 44, 10, 9,111,117,116, 32,118,101, 99, 51, 32,103, -101,110,101,114, 97,116,101,100, 44, 32,111,117,116, 32,118,101, 99, 51, 32,117,118, 44, 32,111,117,116, 32,118,101, 99, 51, 32, -111, 98,106,101, 99,116, 44, 10, 9,111,117,116, 32,118,101, 99, 51, 32, 99, 97,109,101,114, 97, 44, 32,111,117,116, 32,118,101, - 99, 51, 32,119,105,110,100,111,119, 44, 32,111,117,116, 32,118,101, 99, 51, 32,114,101,102,108,101, 99,116,105,111,110, 41, 10, -123, 10, 9,103,101,110,101,114, 97,116,101,100, 32, 61, 32, 97,116,116,114, 95,111,114, 99,111, 59, 10, 9,117,118, 32, 61, 32, - 97,116,116,114, 95,117,118, 59, 10, 9,111, 98,106,101, 99,116, 32, 61, 32, 73, 59, 10, 9, 99, 97,109,101,114, 97, 32, 61, 32, - 73, 59, 10, 9,119,105,110,100,111,119, 32, 61, 32,103,108, 95, 70,114, 97,103, 67,111,111,114,100, 46,120,121,122, 59, 10, 9, -114,101,102,108,101, 99,116,105,111,110, 32, 61, 32,114,101,102,108,101, 99,116, 40, 78, 44, 32, 73, 41, 59, 10, 10,125, 10, 10, - 47, 42, 32,116,101,120,116,117,114,101,115, 32, 42, 47, 10, 10,118,111,105,100, 32,110,111,100,101, 95,116,101,120, 95, 98,108, -101,110,100, 40,118,101, 99, 51, 32, 99,111, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 97, 99, 41, 10,123, 10, 9,102, - 97, 99, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95,116,101,120, 95, 99,108,111,117,100, -115, 40,118,101, 99, 51, 32, 99,111, 44, 32,102,108,111, 97,116, 32,115,105,122,101, 44, 32,111,117,116, 32,118,101, 99, 52, 32, - 99,111,108,111,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 97, 99, 41, 10,123, 10, 9, 99,111,108,111,114, 32, 61, - 32,118,101, 99, 52, 40, 49, 46, 48, 41, 59, 10, 9,102, 97, 99, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32, -110,111,100,101, 95,116,101,120, 95,100,105,115,116,110,111,105,115,101, 40,118,101, 99, 51, 32, 99,111, 44, 32,102,108,111, 97, -116, 32,115,105,122,101, 44, 32,102,108,111, 97,116, 32,100,105,115,116,111,114,116,105,111,110, 44, 32,111,117,116, 32,102,108, -111, 97,116, 32,102, 97, 99, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,110, -111,100,101, 95,116,101,120, 95,101,110,118,105,114,111,110,109,101,110,116, 40,118,101, 99, 51, 32, 99,111, 44, 32,115, 97,109, -112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108,111,114, 41, 10,123, 10, 9,102, -108,111, 97,116, 32,117, 32, 61, 32, 40, 97,116, 97,110, 40, 99,111, 46,121, 44, 32, 99,111, 46,120, 41, 32, 43, 32, 77, 95, 80, - 73, 41, 47, 40, 50, 46, 48, 42, 77, 95, 80, 73, 41, 59, 10, 9,102,108,111, 97,116, 32,118, 32, 61, 32, 97,116, 97,110, 40, 99, -111, 46,122, 44, 32,104,121,112,111,116, 40, 99,111, 46,120, 44, 32, 99,111, 46,121, 41, 41, 47, 77, 95, 80, 73, 32, 43, 32, 48, - 46, 53, 59, 10, 10, 9, 99,111,108,111,114, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32,118,101, 99, - 50, 40,117, 44, 32,118, 41, 41, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95,116,101,120, 95,105,109, 97,103,101, - 40,118,101, 99, 51, 32, 99,111, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,111,117,116, 32,118,101, 99, - 52, 32, 99,111,108,111,114, 41, 10,123, 10, 9, 99,111,108,111,114, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, - 97, 44, 32, 99,111, 46,120,121, 41, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95,116,101,120, 95,109, 97,103,105, - 99, 40,118,101, 99, 51, 32,112, 44, 32,102,108,111, 97,116, 32,116,117,114, 98,117,108,101,110, 99,101, 44, 32,102,108,111, 97, -116, 32,110, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108,111,114, 41, 10,123, 10, 9,102,108,111, 97,116, 32,116,117, -114, 98, 32, 61, 32,116,117,114, 98,117,108,101,110, 99,101, 47, 53, 46, 48, 59, 10, 10, 9,102,108,111, 97,116, 32,120, 32, 61, - 32,115,105,110, 40, 40,112, 46,120, 32, 43, 32,112, 46,121, 32, 43, 32,112, 46,122, 41, 42, 53, 46, 48, 41, 59, 10, 9,102,108, -111, 97,116, 32,121, 32, 61, 32, 99,111,115, 40, 40, 45,112, 46,120, 32, 43, 32,112, 46,121, 32, 45, 32,112, 46,122, 41, 42, 53, - 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,122, 32, 61, 32, 45, 99,111,115, 40, 40, 45,112, 46,120, 32, 45, 32,112, 46,121, - 32, 43, 32,112, 46,122, 41, 42, 53, 46, 48, 41, 59, 10, 10, 9,105,102, 40,110, 32, 62, 32, 48, 46, 48, 41, 32,123, 10, 9, 9, -120, 32, 42, 61, 32,116,117,114, 98, 59, 10, 9, 9,121, 32, 42, 61, 32,116,117,114, 98, 59, 10, 9, 9,122, 32, 42, 61, 32,116, -117,114, 98, 59, 10, 9, 9,121, 32, 61, 32, 45, 99,111,115, 40,120, 45,121, 43,122, 41, 59, 10, 9, 9,121, 32, 42, 61, 32,116, -117,114, 98, 59, 10, 10, 9, 9,105,102, 40,110, 32, 62, 32, 49, 46, 48, 41, 32,123, 10, 9, 9, 9,120, 61, 32, 99,111,115, 40, -120, 45,121, 45,122, 41, 59, 10, 9, 9, 9,120, 32, 42, 61, 32,116,117,114, 98, 59, 10, 10, 9, 9, 9,105,102, 40,110, 32, 62, - 32, 50, 46, 48, 41, 32,123, 10, 9, 9, 9, 9,122, 61, 32,115,105,110, 40, 45,120, 45,121, 45,122, 41, 59, 10, 9, 9, 9, 9, -122, 32, 42, 61, 32,116,117,114, 98, 59, 10, 10, 9, 9, 9, 9,105,102, 40,110, 32, 62, 32, 51, 46, 48, 41, 32,123, 10, 9, 9, - 9, 9, 9,120, 61, 32, 45, 99,111,115, 40, 45,120, 43,121, 45,122, 41, 59, 10, 9, 9, 9, 9, 9,120, 32, 42, 61, 32,116,117, -114, 98, 59, 10, 10, 9, 9, 9, 9, 9,105,102, 40,110, 32, 62, 32, 52, 46, 48, 41, 32,123, 10, 9, 9, 9, 9, 9, 9,121, 61, - 32, 45,115,105,110, 40, 45,120, 43,121, 43,122, 41, 59, 10, 9, 9, 9, 9, 9, 9,121, 32, 42, 61, 32,116,117,114, 98, 59, 10, - 10, 9, 9, 9, 9, 9, 9,105,102, 40,110, 32, 62, 32, 53, 46, 48, 41, 32,123, 10, 9, 9, 9, 9, 9, 9, 9,121, 61, 32, 45, - 99,111,115, 40, 45,120, 43,121, 43,122, 41, 59, 10, 9, 9, 9, 9, 9, 9, 9,121, 32, 42, 61, 32,116,117,114, 98, 59, 10, 10, - 9, 9, 9, 9, 9, 9, 9,105,102, 40,110, 32, 62, 32, 54, 46, 48, 41, 32,123, 10, 9, 9, 9, 9, 9, 9, 9, 9,120, 61, 32, - 99,111,115, 40,120, 43,121, 43,122, 41, 59, 10, 9, 9, 9, 9, 9, 9, 9, 9,120, 32, 42, 61, 32,116,117,114, 98, 59, 10, 10, - 9, 9, 9, 9, 9, 9, 9, 9,105,102, 40,110, 32, 62, 32, 55, 46, 48, 41, 32,123, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9,122, - 61, 32,115,105,110, 40,120, 43,121, 45,122, 41, 59, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9,122, 32, 42, 61, 32,116,117,114, 98, - 59, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9,105,102, 40,110, 32, 62, 32, 56, 46, 48, 41, 32,123, 10, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9,120, 61, 32, 45, 99,111,115, 40, 45,120, 45,121, 43,122, 41, 59, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,120, - 32, 42, 61, 32,116,117,114, 98, 59, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,105,102, 40,110, 32, 62, 32, 57, 46, 48, 41, - 32,123, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,121, 61, 32, 45,115,105,110, 40,120, 45,121, 43,122, 41, 59, 10, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9,121, 32, 42, 61, 32,116,117,114, 98, 59, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,125, 10, - 9, 9, 9, 9, 9, 9, 9, 9, 9,125, 10, 9, 9, 9, 9, 9, 9, 9, 9,125, 10, 9, 9, 9, 9, 9, 9, 9,125, 10, 9, 9, - 9, 9, 9, 9,125, 10, 9, 9, 9, 9, 9,125, 10, 9, 9, 9, 9,125, 10, 9, 9, 9,125, 10, 9, 9,125, 10, 9,125, 10, 10, - 9,105,102, 40,116,117,114, 98, 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,116,117,114, 98, 32, 42, 61, 32, 50, 46, 48, - 59, 10, 9, 9,120, 32, 47, 61, 32,116,117,114, 98, 59, 10, 9, 9,121, 32, 47, 61, 32,116,117,114, 98, 59, 10, 9, 9,122, 32, - 47, 61, 32,116,117,114, 98, 59, 10, 9,125, 10, 10, 9, 99,111,108,111,114, 32, 61, 32,118,101, 99, 52, 40, 48, 46, 53, 32, 45, - 32,120, 44, 32, 48, 46, 53, 32, 45, 32,121, 44, 32, 48, 46, 53, 32, 45, 32,122, 44, 32, 49, 46, 48, 41, 59, 10,125, 10, 10,118, -111,105,100, 32,110,111,100,101, 95,116,101,120, 95,109, 97,114, 98,108,101, 40,118,101, 99, 51, 32, 99,111, 44, 32,102,108,111, - 97,116, 32,115,105,122,101, 44, 32,102,108,111, 97,116, 32,116,117,114, 98,117,108,101,110, 99,101, 44, 32,111,117,116, 32,102, -108,111, 97,116, 32,102, 97, 99, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32, -110,111,100,101, 95,116,101,120, 95,109,117,115,103,114, 97,118,101, 40,118,101, 99, 51, 32, 99,111, 44, 32,102,108,111, 97,116, - 32,115,105,122,101, 44, 32,102,108,111, 97,116, 32,100,105,109,101,110,115,105,111,110, 44, 32,102,108,111, 97,116, 32,108, 97, - 99,117,110, 97,114,105,116,121, 44, 32,102,108,111, 97,116, 32,111, 99,116, 97,118,101,115, 44, 32,102,108,111, 97,116, 32,111, -102,102,115,101,116, 44, 32,102,108,111, 97,116, 32,103, 97,105,110, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 97, 99, - 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95,116,101,120, - 95,110,111,105,115,101, 40,118,101, 99, 51, 32, 99,111, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32, + 10, 47, 42, 42, 42, 42, 42, 42, 42, 32, 77, 65, 84, 69, 82, 73, 65, 76, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 47, 10, 10,118, +111,105,100, 32,108, 97,109,112, 95,118,105,115,105, 98,105,108,105,116,121, 95,115,117,110, 95,104,101,109,105, 40,118,101, 99, + 51, 32,108, 97,109,112,118,101, 99, 44, 32,111,117,116, 32,118,101, 99, 51, 32,108,118, 44, 32,111,117,116, 32,102,108,111, 97, +116, 32,100,105,115,116, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,108,118, + 32, 61, 32,108, 97,109,112,118,101, 99, 59, 10, 9,100,105,115,116, 32, 61, 32, 49, 46, 48, 59, 10, 9,118,105,115,105,102, 97, + 99, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,118,105,115,105, 98,105,108,105,116,121, + 95,111,116,104,101,114, 40,118,101, 99, 51, 32, 99,111, 44, 32,118,101, 99, 51, 32,108, 97,109,112, 99,111, 44, 32,111,117,116, + 32,118,101, 99, 51, 32,108,118, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,100,105,115,116, 44, 32,111,117,116, 32,102,108, +111, 97,116, 32,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,108,118, 32, 61, 32, 99,111, 32, 45, 32,108, 97,109,112, 99,111, + 59, 10, 9,100,105,115,116, 32, 61, 32,108,101,110,103,116,104, 40,108,118, 41, 59, 10, 9,108,118, 32, 61, 32,110,111,114,109, + 97,108,105,122,101, 40,108,118, 41, 59, 10, 9,118,105,115,105,102, 97, 99, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10,118,111, +105,100, 32,108, 97,109,112, 95,102, 97,108,108,111,102,102, 95,105,110,118,108,105,110,101, 97,114, 40,102,108,111, 97,116, 32, +108, 97,109,112,100,105,115,116, 44, 32,102,108,111, 97,116, 32,100,105,115,116, 44, 32,111,117,116, 32,102,108,111, 97,116, 32, +118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,118,105,115,105,102, 97, 99, 32, 61, 32,108, 97,109,112,100,105,115,116, 47, 40, +108, 97,109,112,100,105,115,116, 32, 43, 32,100,105,115,116, 41, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,102, + 97,108,108,111,102,102, 95,105,110,118,115,113,117, 97,114,101, 40,102,108,111, 97,116, 32,108, 97,109,112,100,105,115,116, 44, + 32,102,108,111, 97,116, 32,100,105,115,116, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 41, 10, +123, 10, 9,118,105,115,105,102, 97, 99, 32, 61, 32,108, 97,109,112,100,105,115,116, 47, 40,108, 97,109,112,100,105,115,116, 32, + 43, 32,100,105,115,116, 42,100,105,115,116, 41, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,102, 97,108,108,111, +102,102, 95,115,108,105,100,101,114,115, 40,102,108,111, 97,116, 32,108, 97,109,112,100,105,115,116, 44, 32,102,108,111, 97,116, + 32,108,100, 49, 44, 32,102,108,111, 97,116, 32,108,100, 50, 44, 32,102,108,111, 97,116, 32,100,105,115,116, 44, 32,111,117,116, + 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,102,108,111, 97,116, 32,108, 97,109,112,100,105,115, +116,107,119, 32, 61, 32,108, 97,109,112,100,105,115,116, 42,108, 97,109,112,100,105,115,116, 59, 10, 10, 9,118,105,115,105,102, + 97, 99, 32, 61, 32,108, 97,109,112,100,105,115,116, 47, 40,108, 97,109,112,100,105,115,116, 32, 43, 32,108,100, 49, 42,100,105, +115,116, 41, 59, 10, 9,118,105,115,105,102, 97, 99, 32, 42, 61, 32,108, 97,109,112,100,105,115,116,107,119, 47, 40,108, 97,109, +112,100,105,115,116,107,119, 32, 43, 32,108,100, 50, 42,100,105,115,116, 42,100,105,115,116, 41, 59, 10,125, 10, 10,118,111,105, +100, 32,108, 97,109,112, 95,102, 97,108,108,111,102,102, 95, 99,117,114,118,101, 40,102,108,111, 97,116, 32,108, 97,109,112,100, +105,115,116, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32, 99,117,114,118,101,109, 97,112, 44, 32,102,108,111, 97,116, 32,100, +105,115,116, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,118,105,115,105,102, + 97, 99, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, 50, 40,100,105, +115,116, 47,108, 97,109,112,100,105,115,116, 44, 32, 48, 46, 48, 41, 41, 46,120, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97, +109,112, 95,118,105,115,105, 98,105,108,105,116,121, 95,115,112,104,101,114,101, 40,102,108,111, 97,116, 32,108, 97,109,112,100, +105,115,116, 44, 32,102,108,111, 97,116, 32,100,105,115,116, 44, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 44, 32, +111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,102,108,111, 97,116, 32,116, + 61, 32,108, 97,109,112,100,105,115,116, 32, 45, 32,100,105,115,116, 59, 10, 10, 9,111,117,116,118,105,115,105,102, 97, 99, 61, + 32,118,105,115,105,102, 97, 99, 42,109, 97,120, 40,116, 44, 32, 48, 46, 48, 41, 47,108, 97,109,112,100,105,115,116, 59, 10,125, + 10, 10,118,111,105,100, 32,108, 97,109,112, 95,118,105,115,105, 98,105,108,105,116,121, 95,115,112,111,116, 95,115,113,117, 97, +114,101, 40,118,101, 99, 51, 32,108, 97,109,112,118,101, 99, 44, 32,109, 97,116, 52, 32,108, 97,109,112,105,109, 97,116, 44, 32, +118,101, 99, 51, 32,108,118, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110,112,114, 41, 10,123, 10, 9,105,102, 40,100, +111,116, 40,108,118, 44, 32,108, 97,109,112,118,101, 99, 41, 32, 62, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,118,101, 99, 51, 32, +108,118,114,111,116, 32, 61, 32, 40,108, 97,109,112,105,109, 97,116, 42,118,101, 99, 52, 40,108,118, 44, 32, 48, 46, 48, 41, 41, + 46,120,121,122, 59, 10, 9, 9,102,108,111, 97,116, 32,120, 32, 61, 32,109, 97,120, 40, 97, 98,115, 40,108,118,114,111,116, 46, +120, 47,108,118,114,111,116, 46,122, 41, 44, 32, 97, 98,115, 40,108,118,114,111,116, 46,121, 47,108,118,114,111,116, 46,122, 41, + 41, 59, 10, 10, 9, 9,105,110,112,114, 32, 61, 32, 49, 46, 48, 47,115,113,114,116, 40, 49, 46, 48, 32, 43, 32,120, 42,120, 41, + 59, 10, 9,125, 10, 9,101,108,115,101, 10, 9, 9,105,110,112,114, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, + 32,108, 97,109,112, 95,118,105,115,105, 98,105,108,105,116,121, 95,115,112,111,116, 95, 99,105,114, 99,108,101, 40,118,101, 99, + 51, 32,108, 97,109,112,118,101, 99, 44, 32,118,101, 99, 51, 32,108,118, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, +112,114, 41, 10,123, 10, 9,105,110,112,114, 32, 61, 32,100,111,116, 40,108,118, 44, 32,108, 97,109,112,118,101, 99, 41, 59, 10, +125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,118,105,115,105, 98,105,108,105,116,121, 95,115,112,111,116, 40,102,108,111, + 97,116, 32,115,112,111,116,115,105, 44, 32,102,108,111, 97,116, 32,115,112,111,116, 98,108, 44, 32,102,108,111, 97,116, 32,105, +110,112,114, 44, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117, +116,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,102,108,111, 97,116, 32,116, 32, 61, 32,115,112,111,116,115,105, 59, 10, 10, + 9,105,102, 40,105,110,112,114, 32, 60, 61, 32,116, 41, 32,123, 10, 9, 9,111,117,116,118,105,115,105,102, 97, 99, 32, 61, 32, + 48, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9,116, 32, 61, 32,105,110,112,114, 32, 45, 32,116, 59, 10, + 10, 9, 9, 47, 42, 32,115,111,102,116, 32, 97,114,101, 97, 32, 42, 47, 10, 9, 9,105,102, 40,115,112,111,116, 98,108, 32, 33, + 61, 32, 48, 46, 48, 41, 10, 9, 9, 9,105,110,112,114, 32, 42, 61, 32,115,109,111,111,116,104,115,116,101,112, 40, 48, 46, 48, + 44, 32, 49, 46, 48, 44, 32,116, 47,115,112,111,116, 98,108, 41, 59, 10, 10, 9, 9,111,117,116,118,105,115,105,102, 97, 99, 32, + 61, 32,118,105,115,105,102, 97, 99, 42,105,110,112,114, 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95, +118,105,115,105, 98,105,108,105,116,121, 95, 99,108, 97,109,112, 40,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 44, 32, +111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,111,117,116,118,105,115,105, +102, 97, 99, 32, 61, 32, 40,118,105,115,105,102, 97, 99, 32, 60, 32, 48, 46, 48, 48, 49, 41, 63, 32, 48, 46, 48, 58, 32,118,105, +115,105,102, 97, 99, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,118,105,101,119, 40,118,101, 99, 51, 32, 99, +111, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118,105,101,119, 41, 10,123, 10, 9, 47, 42, 32,104, 97,110,100,108,101, 32,112, +101,114,115,112,101, 99,116,105,118,101, 47,111,114,116,104,111,103,114, 97,112,104,105, 99, 32, 42, 47, 10, 9,118,105,101,119, + 32, 61, 32, 40,103,108, 95, 80,114,111,106,101, 99,116,105,111,110, 77, 97,116,114,105,120, 91, 51, 93, 91, 51, 93, 32, 61, 61, + 32, 48, 46, 48, 41, 63, 32,110,111,114,109, 97,108,105,122,101, 40, 99,111, 41, 58, 32,118,101, 99, 51, 40, 48, 46, 48, 44, 32, + 48, 46, 48, 44, 32, 45, 49, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,116, 97,110,103,101,110, +116, 95,118, 40,118,101, 99, 51, 32,108,118, 44, 32,118,101, 99, 51, 32,116, 97,110,103, 44, 32,111,117,116, 32,118,101, 99, 51, + 32,118,110, 41, 10,123, 10, 9,118,101, 99, 51, 32, 99, 32, 61, 32, 99,114,111,115,115, 40,108,118, 44, 32,116, 97,110,103, 41, + 59, 10, 9,118,101, 99, 51, 32,118,110,111,114, 32, 61, 32, 99,114,111,115,115, 40, 99, 44, 32,116, 97,110,103, 41, 59, 10, 10, + 9,118,110, 32, 61, 32, 45,110,111,114,109, 97,108,105,122,101, 40,118,110,111,114, 41, 59, 10,125, 10, 10,118,111,105,100, 32, +115,104, 97,100,101, 95,105,110,112, 40,118,101, 99, 51, 32,118,110, 44, 32,118,101, 99, 51, 32,108,118, 44, 32,111,117,116, 32, +102,108,111, 97,116, 32,105,110,112, 41, 10,123, 10, 9,105,110,112, 32, 61, 32,100,111,116, 40,118,110, 44, 32,108,118, 41, 59, + 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,105,115, 95,110,111, 95,100,105,102,102,117,115,101, 40,111,117,116, + 32,102,108,111, 97,116, 32,105,115, 41, 10,123, 10, 9,105,115, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32, +115,104, 97,100,101, 95,105,115, 95,104,101,109,105, 40,102,108,111, 97,116, 32,105,110,112, 44, 32,111,117,116, 32,102,108,111, + 97,116, 32,105,115, 41, 10,123, 10, 9,105,115, 32, 61, 32, 48, 46, 53, 42,105,110,112, 32, 43, 32, 48, 46, 53, 59, 10,125, 10, + 10,102,108,111, 97,116, 32, 97,114,101, 97, 95,108, 97,109,112, 95,101,110,101,114,103,121, 40,109, 97,116, 52, 32, 97,114,101, + 97, 44, 32,118,101, 99, 51, 32, 99,111, 44, 32,118,101, 99, 51, 32,118,110, 41, 10,123, 10, 9,118,101, 99, 51, 32,118,101, 99, + 91, 52, 93, 44, 32, 99, 91, 52, 93, 59, 10, 9,102,108,111, 97,116, 32,114, 97,100, 91, 52, 93, 44, 32,102, 97, 99, 59, 10, 9, + 10, 9,118,101, 99, 91, 48, 93, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 99,111, 32, 45, 32, 97,114,101, 97, 91, 48, + 93, 46,120,121,122, 41, 59, 10, 9,118,101, 99, 91, 49, 93, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 99,111, 32, 45, + 32, 97,114,101, 97, 91, 49, 93, 46,120,121,122, 41, 59, 10, 9,118,101, 99, 91, 50, 93, 32, 61, 32,110,111,114,109, 97,108,105, +122,101, 40, 99,111, 32, 45, 32, 97,114,101, 97, 91, 50, 93, 46,120,121,122, 41, 59, 10, 9,118,101, 99, 91, 51, 93, 32, 61, 32, +110,111,114,109, 97,108,105,122,101, 40, 99,111, 32, 45, 32, 97,114,101, 97, 91, 51, 93, 46,120,121,122, 41, 59, 10, 10, 9, 99, + 91, 48, 93, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 99,114,111,115,115, 40,118,101, 99, 91, 48, 93, 44, 32,118,101, + 99, 91, 49, 93, 41, 41, 59, 10, 9, 99, 91, 49, 93, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 99,114,111,115,115, 40, +118,101, 99, 91, 49, 93, 44, 32,118,101, 99, 91, 50, 93, 41, 41, 59, 10, 9, 99, 91, 50, 93, 32, 61, 32,110,111,114,109, 97,108, +105,122,101, 40, 99,114,111,115,115, 40,118,101, 99, 91, 50, 93, 44, 32,118,101, 99, 91, 51, 93, 41, 41, 59, 10, 9, 99, 91, 51, + 93, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 99,114,111,115,115, 40,118,101, 99, 91, 51, 93, 44, 32,118,101, 99, 91, + 48, 93, 41, 41, 59, 10, 10, 9,114, 97,100, 91, 48, 93, 32, 61, 32, 97, 99,111,115, 40,100,111,116, 40,118,101, 99, 91, 48, 93, + 44, 32,118,101, 99, 91, 49, 93, 41, 41, 59, 10, 9,114, 97,100, 91, 49, 93, 32, 61, 32, 97, 99,111,115, 40,100,111,116, 40,118, +101, 99, 91, 49, 93, 44, 32,118,101, 99, 91, 50, 93, 41, 41, 59, 10, 9,114, 97,100, 91, 50, 93, 32, 61, 32, 97, 99,111,115, 40, +100,111,116, 40,118,101, 99, 91, 50, 93, 44, 32,118,101, 99, 91, 51, 93, 41, 41, 59, 10, 9,114, 97,100, 91, 51, 93, 32, 61, 32, + 97, 99,111,115, 40,100,111,116, 40,118,101, 99, 91, 51, 93, 44, 32,118,101, 99, 91, 48, 93, 41, 41, 59, 10, 10, 9,102, 97, 99, + 61, 32, 32,114, 97,100, 91, 48, 93, 42,100,111,116, 40,118,110, 44, 32, 99, 91, 48, 93, 41, 59, 10, 9,102, 97, 99, 43, 61, 32, +114, 97,100, 91, 49, 93, 42,100,111,116, 40,118,110, 44, 32, 99, 91, 49, 93, 41, 59, 10, 9,102, 97, 99, 43, 61, 32,114, 97,100, + 91, 50, 93, 42,100,111,116, 40,118,110, 44, 32, 99, 91, 50, 93, 41, 59, 10, 9,102, 97, 99, 43, 61, 32,114, 97,100, 91, 51, 93, + 42,100,111,116, 40,118,110, 44, 32, 99, 91, 51, 93, 41, 59, 10, 10, 9,114,101,116,117,114,110, 32,109, 97,120, 40,102, 97, 99, + 44, 32, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,105,110,112, 95, 97,114,101, 97, 40,118, +101, 99, 51, 32,112,111,115,105,116,105,111,110, 44, 32,118,101, 99, 51, 32,108, 97,109,112, 99,111, 44, 32,118,101, 99, 51, 32, +108, 97,109,112,118,101, 99, 44, 32,118,101, 99, 51, 32,118,110, 44, 32,109, 97,116, 52, 32, 97,114,101, 97, 44, 32,102,108,111, + 97,116, 32, 97,114,101, 97,115,105,122,101, 44, 32,102,108,111, 97,116, 32,107, 44, 32,111,117,116, 32,102,108,111, 97,116, 32, +105,110,112, 41, 10,123, 10, 9,118,101, 99, 51, 32, 99,111, 32, 61, 32,112,111,115,105,116,105,111,110, 59, 10, 9,118,101, 99, + 51, 32,118,101, 99, 32, 61, 32, 99,111, 32, 45, 32,108, 97,109,112, 99,111, 59, 10, 10, 9,105,102, 40,100,111,116, 40,118,101, + 99, 44, 32,108, 97,109,112,118,101, 99, 41, 32, 60, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,105,110,112, 32, 61, 32, 48, 46, 48, + 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9,102,108,111, 97,116, 32,105,110,116,101,110,115, 32, 61, 32, 97,114, +101, 97, 95,108, 97,109,112, 95,101,110,101,114,103,121, 40, 97,114,101, 97, 44, 32, 99,111, 44, 32,118,110, 41, 59, 10, 10, 9, + 9,105,110,112, 32, 61, 32,112,111,119, 40,105,110,116,101,110,115, 42, 97,114,101, 97,115,105,122,101, 44, 32,107, 41, 59, 10, + 9,125, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,100,105,102,102,117,115,101, 95,111,114,101,110, 95,110, 97, +121,101,114, 40,102,108,111, 97,116, 32,110,108, 44, 32,118,101, 99, 51, 32,110, 44, 32,118,101, 99, 51, 32,108, 44, 32,118,101, + 99, 51, 32,118, 44, 32,102,108,111, 97,116, 32,114,111,117,103,104, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,115, 41, + 10,123, 10, 9,118,101, 99, 51, 32,104, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,118, 32, 43, 32,108, 41, 59, 10, 9, +102,108,111, 97,116, 32,110,104, 32, 61, 32,109, 97,120, 40,100,111,116, 40,110, 44, 32,104, 41, 44, 32, 48, 46, 48, 41, 59, 10, + 9,102,108,111, 97,116, 32,110,118, 32, 61, 32,109, 97,120, 40,100,111,116, 40,110, 44, 32,118, 41, 44, 32, 48, 46, 48, 41, 59, + 10, 9,102,108,111, 97,116, 32,114,101, 97,108,110,108, 32, 61, 32,100,111,116, 40,110, 44, 32,108, 41, 59, 10, 10, 9,105,102, + 40,114,101, 97,108,110,108, 32, 60, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,105,115, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, + 9,101,108,115,101, 32,105,102, 40,110,108, 32, 60, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,105,115, 32, 61, 32, 48, 46, 48, 59, + 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9,102,108,111, 97,116, 32,118,104, 32, 61, 32,109, 97,120, 40,100,111,116, + 40,118, 44, 32,104, 41, 44, 32, 48, 46, 48, 41, 59, 10, 9, 9,102,108,111, 97,116, 32, 76,105,116, 95, 65, 32, 61, 32, 97, 99, +111,115, 40,114,101, 97,108,110,108, 41, 59, 10, 9, 9,102,108,111, 97,116, 32, 86,105,101,119, 95, 65, 32, 61, 32, 97, 99,111, +115, 40,110,118, 41, 59, 10, 10, 9, 9,118,101, 99, 51, 32, 76,105,116, 95, 66, 32, 61, 32,110,111,114,109, 97,108,105,122,101, + 40,108, 32, 45, 32,114,101, 97,108,110,108, 42,110, 41, 59, 10, 9, 9,118,101, 99, 51, 32, 86,105,101,119, 95, 66, 32, 61, 32, +110,111,114,109, 97,108,105,122,101, 40,118, 32, 45, 32,110,118, 42,110, 41, 59, 10, 10, 9, 9,102,108,111, 97,116, 32,116, 32, + 61, 32,109, 97,120, 40,100,111,116, 40, 76,105,116, 95, 66, 44, 32, 86,105,101,119, 95, 66, 41, 44, 32, 48, 46, 48, 41, 59, 10, + 10, 9, 9,102,108,111, 97,116, 32, 97, 44, 32, 98, 59, 10, 10, 9, 9,105,102, 40, 76,105,116, 95, 65, 32, 62, 32, 86,105,101, +119, 95, 65, 41, 32,123, 10, 9, 9, 9, 97, 32, 61, 32, 76,105,116, 95, 65, 59, 10, 9, 9, 9, 98, 32, 61, 32, 86,105,101,119, + 95, 65, 59, 10, 9, 9,125, 10, 9, 9,101,108,115,101, 32,123, 10, 9, 9, 9, 97, 32, 61, 32, 86,105,101,119, 95, 65, 59, 10, + 9, 9, 9, 98, 32, 61, 32, 76,105,116, 95, 65, 59, 10, 9, 9,125, 10, 10, 9, 9,102,108,111, 97,116, 32, 65, 32, 61, 32, 49, + 46, 48, 32, 45, 32, 40, 48, 46, 53, 42, 40, 40,114,111,117,103,104, 42,114,111,117,103,104, 41, 47, 40, 40,114,111,117,103,104, + 42,114,111,117,103,104, 41, 32, 43, 32, 48, 46, 51, 51, 41, 41, 41, 59, 10, 9, 9,102,108,111, 97,116, 32, 66, 32, 61, 32, 48, + 46, 52, 53, 42, 40, 40,114,111,117,103,104, 42,114,111,117,103,104, 41, 47, 40, 40,114,111,117,103,104, 42,114,111,117,103,104, + 41, 32, 43, 32, 48, 46, 48, 57, 41, 41, 59, 10, 10, 9, 9, 98, 32, 42, 61, 32, 48, 46, 57, 53, 59, 10, 9, 9,105,115, 32, 61, + 32,110,108, 42, 40, 65, 32, 43, 32, 40, 66, 32, 42, 32,116, 32, 42, 32,115,105,110, 40, 97, 41, 32, 42, 32,116, 97,110, 40, 98, + 41, 41, 41, 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,100,105,102,102,117,115,101, 95,116,111, +111,110, 40,118,101, 99, 51, 32,110, 44, 32,118,101, 99, 51, 32,108, 44, 32,118,101, 99, 51, 32,118, 44, 32,102,108,111, 97,116, + 32,115,105,122,101, 44, 32,102,108,111, 97,116, 32,116,115,109,111,111,116,104, 44, 32,111,117,116, 32,102,108,111, 97,116, 32, +105,115, 41, 10,123, 10, 9,102,108,111, 97,116, 32,114,115,108,116, 32, 61, 32,100,111,116, 40,110, 44, 32,108, 41, 59, 10, 9, +102,108,111, 97,116, 32, 97,110,103, 32, 61, 32, 97, 99,111,115, 40,114,115,108,116, 41, 59, 10, 10, 9,105,102, 40, 97,110,103, + 32, 60, 32,115,105,122,101, 41, 32,105,115, 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40, 97,110,103, 32, + 62, 32, 40,115,105,122,101, 32, 43, 32,116,115,109,111,111,116,104, 41, 32,124,124, 32,116,115,109,111,111,116,104, 32, 61, 61, + 32, 48, 46, 48, 41, 32,105,115, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115,101, 32,105,115, 32, 61, 32, 49, 46, 48, 32, 45, + 32, 40, 40, 97,110,103, 32, 45, 32,115,105,122,101, 41, 47,116,115,109,111,111,116,104, 41, 59, 10,125, 10, 10,118,111,105,100, + 32,115,104, 97,100,101, 95,100,105,102,102,117,115,101, 95,109,105,110,110, 97,101,114,116, 40,102,108,111, 97,116, 32,110,108, + 44, 32,118,101, 99, 51, 32,110, 44, 32,118,101, 99, 51, 32,118, 44, 32,102,108,111, 97,116, 32,100, 97,114,107,110,101,115,115, + 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,115, 41, 10,123, 10, 9,105,102, 40,110,108, 32, 60, 61, 32, 48, 46, 48, 41, + 32,123, 10, 9, 9,105,115, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9,102,108,111, 97, +116, 32,110,118, 32, 61, 32,109, 97,120, 40,100,111,116, 40,110, 44, 32,118, 41, 44, 32, 48, 46, 48, 41, 59, 10, 10, 9, 9,105, +102, 40,100, 97,114,107,110,101,115,115, 32, 60, 61, 32, 49, 46, 48, 41, 10, 9, 9, 9,105,115, 32, 61, 32,110,108, 42,112,111, +119, 40,109, 97,120, 40,110,118, 42,110,108, 44, 32, 48, 46, 49, 41, 44, 32,100, 97,114,107,110,101,115,115, 32, 45, 32, 49, 46, + 48, 41, 59, 10, 9, 9,101,108,115,101, 10, 9, 9, 9,105,115, 32, 61, 32,110,108, 42,112,111,119, 40, 49, 46, 48, 48, 48, 49, + 32, 45, 32,110,118, 44, 32,100, 97,114,107,110,101,115,115, 32, 45, 32, 49, 46, 48, 41, 59, 10, 9,125, 10,125, 10, 10,102,108, +111, 97,116, 32,102,114,101,115,110,101,108, 95,102, 97, 99, 40,118,101, 99, 51, 32,118,105,101,119, 44, 32,118,101, 99, 51, 32, +118,110, 44, 32,102,108,111, 97,116, 32,103,114, 97,100, 44, 32,102,108,111, 97,116, 32,102, 97, 99, 41, 10,123, 10, 9,102,108, +111, 97,116, 32,116, 49, 44, 32,116, 50, 59, 10, 9,102,108,111, 97,116, 32,102,102, 97, 99, 59, 10, 10, 9,105,102, 40,102, 97, + 99, 61, 61, 48, 46, 48, 41, 32,123, 10, 9, 9,102,102, 97, 99, 32, 61, 32, 49, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, + 32,123, 10, 9, 9,116, 49, 61, 32,100,111,116, 40,118,105,101,119, 44, 32,118,110, 41, 59, 10, 9, 9,105,102, 40,116, 49, 62, + 48, 46, 48, 41, 32, 32,116, 50, 61, 32, 49, 46, 48, 43,116, 49, 59, 10, 9, 9,101,108,115,101, 32,116, 50, 61, 32, 49, 46, 48, + 45,116, 49, 59, 10, 10, 9, 9,116, 50, 61, 32,103,114, 97,100, 32, 43, 32, 40, 49, 46, 48, 45,103,114, 97,100, 41, 42,112,111, +119, 40,116, 50, 44, 32,102, 97, 99, 41, 59, 10, 10, 9, 9,105,102, 40,116, 50, 60, 48, 46, 48, 41, 32,102,102, 97, 99, 32, 61, + 32, 48, 46, 48, 59, 10, 9, 9,101,108,115,101, 32,105,102, 40,116, 50, 62, 49, 46, 48, 41, 32,102,102, 97, 99, 32, 61, 32, 49, + 46, 48, 59, 10, 9, 9,101,108,115,101, 32,102,102, 97, 99, 32, 61, 32,116, 50, 59, 10, 9,125, 10, 10, 9,114,101,116,117,114, +110, 32,102,102, 97, 99, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,100,105,102,102,117,115,101, 95,102,114, +101,115,110,101,108, 40,118,101, 99, 51, 32,118,110, 44, 32,118,101, 99, 51, 32,108,118, 44, 32,118,101, 99, 51, 32,118,105,101, +119, 44, 32,102,108,111, 97,116, 32,102, 97, 99, 95,105, 44, 32,102,108,111, 97,116, 32,102, 97, 99, 44, 32,111,117,116, 32,102, +108,111, 97,116, 32,105,115, 41, 10,123, 10, 9,105,115, 32, 61, 32,102,114,101,115,110,101,108, 95,102, 97, 99, 40,108,118, 44, + 32,118,110, 44, 32,102, 97, 99, 95,105, 44, 32,102, 97, 99, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95, + 99,117, 98,105, 99, 40,102,108,111, 97,116, 32,105,115, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,105,115, 41, + 10,123, 10, 9,105,102, 40,105,115, 62, 48, 46, 48, 32, 38, 38, 32,105,115, 60, 49, 46, 48, 41, 10, 9, 9,111,117,116,105,115, + 61, 32,115,109,111,111,116,104,115,116,101,112, 40, 48, 46, 48, 44, 32, 49, 46, 48, 44, 32,105,115, 41, 59, 10, 9,101,108,115, +101, 10, 9, 9,111,117,116,105,115, 61, 32,105,115, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,118,105,115, +105,102, 97, 99, 40,102,108,111, 97,116, 32,105, 44, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 44, 32,102,108,111, + 97,116, 32,114,101,102,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,105, 41, 10,123, 10, 9, 47, 42,105,102, + 40,105, 32, 62, 32, 48, 46, 48, 41, 42, 47, 10, 9, 9,111,117,116,105, 32, 61, 32,109, 97,120, 40,105, 42,118,105,115,105,102, + 97, 99, 42,114,101,102,108, 44, 32, 48, 46, 48, 41, 59, 10, 9, 47, 42,101,108,115,101, 10, 9, 9,111,117,116,105, 32, 61, 32, +105, 59, 42, 47, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,116, 97,110,103,101,110,116, 95,118, 95,115,112,101, + 99, 40,118,101, 99, 51, 32,116, 97,110,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118,110, 41, 10,123, 10, 9,118,110, 32, + 61, 32,116, 97,110,103, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95, 97,100,100, 95,116,111, 95,100,105,102, +102,117,115,101, 40,102,108,111, 97,116, 32,105, 44, 32,118,101, 99, 51, 32,108, 97,109,112, 99,111,108, 44, 32,118,101, 99, 51, + 32, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,105,102, 40,105, 32, 62, + 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 32, 61, 32,105, 42,108, 97,109,112, 99,111,108, 42, 99,111,108, 59, 10, + 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 32, 61, 32,118,101, 99, 51, 40, 48, 46, 48, 44, 32, 48, 46, 48, 44, 32, + 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,104,101,109,105, 95,115,112,101, 99, 40,118,101, + 99, 51, 32,118,110, 44, 32,118,101, 99, 51, 32,108,118, 44, 32,118,101, 99, 51, 32,118,105,101,119, 44, 32,102,108,111, 97,116, + 32,115,112,101, 99, 44, 32,102,108,111, 97,116, 32,104, 97,114,100, 44, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, + 44, 32,111,117,116, 32,102,108,111, 97,116, 32,116, 41, 10,123, 10, 9,108,118, 32, 43, 61, 32,118,105,101,119, 59, 10, 9,108, +118, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,108,118, 41, 59, 10, 10, 9,116, 32, 61, 32,100,111,116, 40,118,110, 44, + 32,108,118, 41, 59, 10, 9,116, 32, 61, 32, 48, 46, 53, 42,116, 32, 43, 32, 48, 46, 53, 59, 10, 10, 9,116, 32, 61, 32,118,105, +115,105,102, 97, 99, 42,115,112,101, 99, 42,112,111,119, 40,116, 44, 32,104, 97,114,100, 41, 59, 10,125, 10, 10,118,111,105,100, + 32,115,104, 97,100,101, 95,112,104,111,110,103, 95,115,112,101, 99, 40,118,101, 99, 51, 32,110, 44, 32,118,101, 99, 51, 32,108, + 44, 32,118,101, 99, 51, 32,118, 44, 32,102,108,111, 97,116, 32,104, 97,114,100, 44, 32,111,117,116, 32,102,108,111, 97,116, 32, +115,112,101, 99,102, 97, 99, 41, 10,123, 10, 9,118,101, 99, 51, 32,104, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,108, + 32, 43, 32,118, 41, 59, 10, 9,102,108,111, 97,116, 32,114,115,108,116, 32, 61, 32,109, 97,120, 40,100,111,116, 40,104, 44, 32, +110, 41, 44, 32, 48, 46, 48, 41, 59, 10, 10, 9,115,112,101, 99,102, 97, 99, 32, 61, 32,112,111,119, 40,114,115,108,116, 44, 32, +104, 97,114,100, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95, 99,111,111,107,116,111,114,114, 95,115,112, +101, 99, 40,118,101, 99, 51, 32,110, 44, 32,118,101, 99, 51, 32,108, 44, 32,118,101, 99, 51, 32,118, 44, 32,102,108,111, 97,116, + 32,104, 97,114,100, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,115,112,101, 99,102, 97, 99, 41, 10,123, 10, 9,118,101, 99, + 51, 32,104, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,118, 32, 43, 32,108, 41, 59, 10, 9,102,108,111, 97,116, 32,110, +104, 32, 61, 32,100,111,116, 40,110, 44, 32,104, 41, 59, 10, 10, 9,105,102, 40,110,104, 32, 60, 32, 48, 46, 48, 41, 32,123, 10, + 9, 9,115,112,101, 99,102, 97, 99, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9,102,108, +111, 97,116, 32,110,118, 32, 61, 32,109, 97,120, 40,100,111,116, 40,110, 44, 32,118, 41, 44, 32, 48, 46, 48, 41, 59, 10, 9, 9, +102,108,111, 97,116, 32,105, 32, 61, 32,112,111,119, 40,110,104, 44, 32,104, 97,114,100, 41, 59, 10, 10, 9, 9,105, 32, 61, 32, +105, 47, 40, 48, 46, 49, 43,110,118, 41, 59, 10, 9, 9,115,112,101, 99,102, 97, 99, 32, 61, 32,105, 59, 10, 9,125, 10,125, 10, + 10,118,111,105,100, 32,115,104, 97,100,101, 95, 98,108,105,110,110, 95,115,112,101, 99, 40,118,101, 99, 51, 32,110, 44, 32,118, +101, 99, 51, 32,108, 44, 32,118,101, 99, 51, 32,118, 44, 32,102,108,111, 97,116, 32,114,101,102,114, 97, 99, 44, 32,102,108,111, + 97,116, 32,115,112,101, 99, 95,112,111,119,101,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,115,112,101, 99,102, 97, 99, + 41, 10,123, 10, 9,105,102, 40,114,101,102,114, 97, 99, 32, 60, 32, 49, 46, 48, 41, 32,123, 10, 9, 9,115,112,101, 99,102, 97, + 99, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,105,102, 40,115,112,101, 99, 95,112,111,119,101,114, 32, + 61, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,115,112,101, 99,102, 97, 99, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101, +108,115,101, 32,123, 10, 9, 9,105,102, 40,115,112,101, 99, 95,112,111,119,101,114, 60, 49, 48, 48, 46, 48, 41, 10, 9, 9, 9, +115,112,101, 99, 95,112,111,119,101,114, 61, 32,115,113,114,116, 40, 49, 46, 48, 47,115,112,101, 99, 95,112,111,119,101,114, 41, + 59, 10, 9, 9,101,108,115,101, 10, 9, 9, 9,115,112,101, 99, 95,112,111,119,101,114, 61, 32, 49, 48, 46, 48, 47,115,112,101, + 99, 95,112,111,119,101,114, 59, 10, 10, 9, 9,118,101, 99, 51, 32,104, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,118, + 32, 43, 32,108, 41, 59, 10, 9, 9,102,108,111, 97,116, 32,110,104, 32, 61, 32,100,111,116, 40,110, 44, 32,104, 41, 59, 10, 9, + 9,105,102, 40,110,104, 32, 60, 32, 48, 46, 48, 41, 32,123, 10, 9, 9, 9,115,112,101, 99,102, 97, 99, 32, 61, 32, 48, 46, 48, + 59, 10, 9, 9,125, 10, 9, 9,101,108,115,101, 32,123, 10, 9, 9, 9,102,108,111, 97,116, 32,110,118, 32, 61, 32,109, 97,120, + 40,100,111,116, 40,110, 44, 32,118, 41, 44, 32, 48, 46, 48, 49, 41, 59, 10, 9, 9, 9,102,108,111, 97,116, 32,110,108, 32, 61, + 32,100,111,116, 40,110, 44, 32,108, 41, 59, 10, 9, 9, 9,105,102, 40,110,108, 32, 60, 61, 32, 48, 46, 48, 49, 41, 32,123, 10, + 9, 9, 9, 9,115,112,101, 99,102, 97, 99, 32, 61, 32, 48, 46, 48, 59, 10, 9, 9, 9,125, 10, 9, 9, 9,101,108,115,101, 32, +123, 10, 9, 9, 9, 9,102,108,111, 97,116, 32,118,104, 32, 61, 32,109, 97,120, 40,100,111,116, 40,118, 44, 32,104, 41, 44, 32, + 48, 46, 48, 49, 41, 59, 10, 10, 9, 9, 9, 9,102,108,111, 97,116, 32, 97, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9, 9, 9,102, +108,111, 97,116, 32, 98, 32, 61, 32, 40, 50, 46, 48, 42,110,104, 42,110,118, 41, 47,118,104, 59, 10, 9, 9, 9, 9,102,108,111, + 97,116, 32, 99, 32, 61, 32, 40, 50, 46, 48, 42,110,104, 42,110,108, 41, 47,118,104, 59, 10, 10, 9, 9, 9, 9,102,108,111, 97, +116, 32,103, 32, 61, 32, 48, 46, 48, 59, 10, 10, 9, 9, 9, 9,105,102, 40, 97, 32, 60, 32, 98, 32, 38, 38, 32, 97, 32, 60, 32, + 99, 41, 32,103, 32, 61, 32, 97, 59, 10, 9, 9, 9, 9,101,108,115,101, 32,105,102, 40, 98, 32, 60, 32, 97, 32, 38, 38, 32, 98, + 32, 60, 32, 99, 41, 32,103, 32, 61, 32, 98, 59, 10, 9, 9, 9, 9,101,108,115,101, 32,105,102, 40, 99, 32, 60, 32, 97, 32, 38, + 38, 32, 99, 32, 60, 32, 98, 41, 32,103, 32, 61, 32, 99, 59, 10, 10, 9, 9, 9, 9,102,108,111, 97,116, 32,112, 32, 61, 32,115, +113,114,116, 40, 40, 40,114,101,102,114, 97, 99, 32, 42, 32,114,101,102,114, 97, 99, 41, 43, 40,118,104, 42,118,104, 41, 45, 49, + 46, 48, 41, 41, 59, 10, 9, 9, 9, 9,102,108,111, 97,116, 32,102, 32, 61, 32, 40, 40, 40,112, 45,118,104, 41, 42, 40,112, 45, +118,104, 41, 41, 47, 40, 40,112, 43,118,104, 41, 42, 40,112, 43,118,104, 41, 41, 41, 42, 40, 49, 46, 48, 43, 40, 40, 40, 40,118, +104, 42, 40,112, 43,118,104, 41, 41, 45, 49, 46, 48, 41, 42, 40, 40,118,104, 42, 40,112, 43,118,104, 41, 41, 45, 49, 46, 48, 41, + 41, 47, 40, 40, 40,118,104, 42, 40,112, 45,118,104, 41, 41, 43, 49, 46, 48, 41, 42, 40, 40,118,104, 42, 40,112, 45,118,104, 41, + 41, 43, 49, 46, 48, 41, 41, 41, 41, 59, 10, 9, 9, 9, 9,102,108,111, 97,116, 32, 97,110,103, 32, 61, 32, 97, 99,111,115, 40, +110,104, 41, 59, 10, 10, 9, 9, 9, 9,115,112,101, 99,102, 97, 99, 32, 61, 32,109, 97,120, 40,102, 42,103, 42,101,120,112, 95, + 98,108,101,110,100,101,114, 40, 40, 45, 40, 97,110,103, 42, 97,110,103, 41, 47, 40, 50, 46, 48, 42,115,112,101, 99, 95,112,111, +119,101,114, 42,115,112,101, 99, 95,112,111,119,101,114, 41, 41, 41, 44, 32, 48, 46, 48, 41, 59, 10, 9, 9, 9,125, 10, 9, 9, +125, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,119, 97,114,100,105,115,111, 95,115,112,101, 99, 40, +118,101, 99, 51, 32,110, 44, 32,118,101, 99, 51, 32,108, 44, 32,118,101, 99, 51, 32,118, 44, 32,102,108,111, 97,116, 32,114,109, +115, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,115,112,101, 99,102, 97, 99, 41, 10,123, 10, 9,118,101, 99, 51, 32,104, 32, + 61, 32,110,111,114,109, 97,108,105,122,101, 40,108, 32, 43, 32,118, 41, 59, 10, 9,102,108,111, 97,116, 32,110,104, 32, 61, 32, +109, 97,120, 40,100,111,116, 40,110, 44, 32,104, 41, 44, 32, 48, 46, 48, 48, 49, 41, 59, 10, 9,102,108,111, 97,116, 32,110,118, + 32, 61, 32,109, 97,120, 40,100,111,116, 40,110, 44, 32,118, 41, 44, 32, 48, 46, 48, 48, 49, 41, 59, 10, 9,102,108,111, 97,116, + 32,110,108, 32, 61, 32,109, 97,120, 40,100,111,116, 40,110, 44, 32,108, 41, 44, 32, 48, 46, 48, 48, 49, 41, 59, 10, 9,102,108, +111, 97,116, 32, 97,110,103,108,101, 32, 61, 32,116, 97,110, 40, 97, 99,111,115, 40,110,104, 41, 41, 59, 10, 9,102,108,111, 97, +116, 32, 97,108,112,104, 97, 32, 61, 32,109, 97,120, 40,114,109,115, 44, 32, 48, 46, 48, 48, 49, 41, 59, 10, 10, 9,115,112,101, + 99,102, 97, 99, 61, 32,110,108, 32, 42, 32, 40, 49, 46, 48, 47, 40, 52, 46, 48, 42, 77, 95, 80, 73, 42, 97,108,112,104, 97, 42, + 97,108,112,104, 97, 41, 41, 42, 40,101,120,112, 95, 98,108,101,110,100,101,114, 40, 45, 40, 97,110,103,108,101, 42, 97,110,103, +108,101, 41, 47, 40, 97,108,112,104, 97, 42, 97,108,112,104, 97, 41, 41, 47, 40,115,113,114,116, 40,110,118, 42,110,108, 41, 41, + 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,116,111,111,110, 95,115,112,101, 99, 40,118,101, 99, 51, 32, +110, 44, 32,118,101, 99, 51, 32,108, 44, 32,118,101, 99, 51, 32,118, 44, 32,102,108,111, 97,116, 32,115,105,122,101, 44, 32,102, +108,111, 97,116, 32,116,115,109,111,111,116,104, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,115,112,101, 99,102, 97, 99, 41, + 10,123, 10, 9,118,101, 99, 51, 32,104, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,108, 32, 43, 32,118, 41, 59, 10, 9, +102,108,111, 97,116, 32,114,115,108,116, 32, 61, 32,100,111,116, 40,104, 44, 32,110, 41, 59, 10, 9,102,108,111, 97,116, 32, 97, +110,103, 32, 61, 32, 97, 99,111,115, 40,114,115,108,116, 41, 59, 10, 10, 9,105,102, 40, 97,110,103, 32, 60, 32,115,105,122,101, + 41, 32,114,115,108,116, 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40, 97,110,103, 32, 62, 61, 32, 40,115, +105,122,101, 32, 43, 32,116,115,109,111,111,116,104, 41, 32,124,124, 32,116,115,109,111,111,116,104, 32, 61, 61, 32, 48, 46, 48, + 41, 32,114,115,108,116, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115,101, 32,114,115,108,116, 32, 61, 32, 49, 46, 48, 32, 45, + 32, 40, 40, 97,110,103, 32, 45, 32,115,105,122,101, 41, 47,116,115,109,111,111,116,104, 41, 59, 10, 10, 9,115,112,101, 99,102, + 97, 99, 32, 61, 32,114,115,108,116, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,115,112,101, 99, 95, 97,114, +101, 97, 95,105,110,112, 40,102,108,111, 97,116, 32,115,112,101, 99,102, 97, 99, 44, 32,102,108,111, 97,116, 32,105,110,112, 44, + 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,115,112,101, 99,102, 97, 99, 41, 10,123, 10, 9,111,117,116,115,112,101, + 99,102, 97, 99, 32, 61, 32,115,112,101, 99,102, 97, 99, 42,105,110,112, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100, +101, 95,115,112,101, 99, 95,116, 40,102,108,111, 97,116, 32,115,104, 97,100,102, 97, 99, 44, 32,102,108,111, 97,116, 32,115,112, +101, 99, 44, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 44, 32,102,108,111, 97,116, 32,115,112,101, 99,102, 97, 99, + 44, 32,111,117,116, 32,102,108,111, 97,116, 32,116, 41, 10,123, 10, 9,116, 32, 61, 32,115,104, 97,100,102, 97, 99, 42,115,112, +101, 99, 42,118,105,115,105,102, 97, 99, 42,115,112,101, 99,102, 97, 99, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100, +101, 95, 97,100,100, 95,115,112,101, 99, 40,102,108,111, 97,116, 32,116, 44, 32,118,101, 99, 51, 32,108, 97,109,112, 99,111,108, + 44, 32,118,101, 99, 51, 32,115,112,101, 99, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116, 99,111,108, 41, + 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32,116, 42,108, 97,109,112, 99,111,108, 42,115,112,101, 99, 99,111,108, 59, 10, +125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95, 97,100,100, 40,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, + 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99, +111,108, 32, 61, 32, 99,111,108, 49, 32, 43, 32, 99,111,108, 50, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95, +109, 97,100,100, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99, +111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, + 61, 32, 99,111,108, 32, 43, 32, 99,111,108, 49, 42, 99,111,108, 50, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, + 95, 97,100,100, 95, 99,108, 97,109,112,101,100, 40,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, + 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32, + 99,111,108, 49, 32, 43, 32,109, 97,120, 40, 99,111,108, 50, 44, 32,118,101, 99, 52, 40, 48, 46, 48, 44, 32, 48, 46, 48, 44, 32, + 48, 46, 48, 44, 32, 48, 46, 48, 41, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,109, 97,100,100, 95, 99, +108, 97,109,112,101,100, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, + 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111, +108, 32, 61, 32, 99,111,108, 32, 43, 32,109, 97,120, 40, 99,111,108, 49, 42, 99,111,108, 50, 44, 32,118,101, 99, 52, 40, 48, 46, + 48, 44, 32, 48, 46, 48, 44, 32, 48, 46, 48, 44, 32, 48, 46, 48, 41, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100, +101, 95,109, 97,100,100,102, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 44, 32,118,101, 99, 52, 32, + 99,111,108, 49, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, + 32, 61, 32, 99,111,108, 32, 43, 32,102, 42, 99,111,108, 49, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,109, +117,108, 40,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, + 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 42, 99,111,108, 50, 59, + 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,109,117,108, 95,118, 97,108,117,101, 40,102,108,111, 97,116, 32,102, + 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, + 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 42,102, 97, 99, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100, +101, 95,111, 98, 99,111,108,111,114, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,118,101, 99, 52, 32,111, 98, 99,111,108, 44, 32, +111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32,118,101, 99, + 52, 40, 99,111,108, 46,114,103, 98, 42,111, 98, 99,111,108, 46,114,103, 98, 44, 32, 99,111,108, 46, 97, 41, 59, 10,125, 10, 10, +118,111,105,100, 32,114, 97,109,112, 95,114,103, 98,116,111, 98,119, 40,118,101, 99, 51, 32, 99,111,108,111,114, 44, 32,111,117, +116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 99,111,108,111, +114, 46,114, 42, 48, 46, 51, 32, 43, 32, 99,111,108,111,114, 46,103, 42, 48, 46, 53, 56, 32, 43, 32, 99,111,108,111,114, 46, 98, + 42, 48, 46, 49, 50, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,111,110,108,121, 95,115,104, 97,100,111,119, + 40,102,108,111, 97,116, 32,105, 44, 32,102,108,111, 97,116, 32,115,104, 97,100,102, 97, 99, 44, 32,102,108,111, 97,116, 32,101, +110,101,114,103,121, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,115,104, 97,100,102, 97, 99, 41, 10,123, 10, 9, +111,117,116,115,104, 97,100,102, 97, 99, 32, 61, 32,105, 42,101,110,101,114,103,121, 42, 40, 49, 46, 48, 32, 45, 32,115,104, 97, +100,102, 97, 99, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,111,110,108,121, 95,115,104, 97,100,111,119, + 95,100,105,102,102,117,115,101, 40,102,108,111, 97,116, 32,115,104, 97,100,102, 97, 99, 44, 32,118,101, 99, 51, 32,114,103, 98, + 44, 32,118,101, 99, 52, 32,100,105,102,102, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116,100,105,102,102, 41, 10,123, + 10, 9,111,117,116,100,105,102,102, 32, 61, 32,100,105,102,102, 32, 45, 32,118,101, 99, 52, 40,114,103, 98, 42,115,104, 97,100, +102, 97, 99, 44, 32, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,111,110,108,121, 95,115,104, + 97,100,111,119, 95,115,112,101, 99,117,108, 97,114, 40,102,108,111, 97,116, 32,115,104, 97,100,102, 97, 99, 44, 32,118,101, 99, + 51, 32,115,112,101, 99,114,103, 98, 44, 32,118,101, 99, 52, 32,115,112,101, 99, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111, +117,116,115,112,101, 99, 41, 10,123, 10, 9,111,117,116,115,112,101, 99, 32, 61, 32,115,112,101, 99, 32, 45, 32,118,101, 99, 52, + 40,115,112,101, 99,114,103, 98, 42,115,104, 97,100,102, 97, 99, 44, 32, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32, +116,101,115,116, 95,115,104, 97,100,111,119, 98,117,102, 40,118,101, 99, 51, 32,114, 99,111, 44, 32,115, 97,109,112,108,101,114, + 50, 68, 83,104, 97,100,111,119, 32,115,104, 97,100,111,119,109, 97,112, 44, 32,109, 97,116, 52, 32,115,104, 97,100,111,119,112, +101,114,115,109, 97,116, 44, 32,102,108,111, 97,116, 32,115,104, 97,100,111,119, 98,105, 97,115, 44, 32,102,108,111, 97,116, 32, +105,110,112, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,114,101,115,117,108,116, 41, 10,123, 10, 9,105,102, 40,105,110,112, + 32, 60, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,114,101,115,117,108,116, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101, +108,115,101, 32,123, 10, 9, 9,118,101, 99, 52, 32, 99,111, 32, 61, 32,115,104, 97,100,111,119,112,101,114,115,109, 97,116, 42, +118,101, 99, 52, 40,114, 99,111, 44, 32, 49, 46, 48, 41, 59, 10, 10, 9, 9, 47, 47,102,108,111, 97,116, 32, 98,105, 97,115, 32, + 61, 32, 40, 49, 46, 53, 32, 45, 32,105,110,112, 42,105,110,112, 41, 42,115,104, 97,100,111,119, 98,105, 97,115, 59, 10, 9, 9, + 99,111, 46,122, 32, 45, 61, 32,115,104, 97,100,111,119, 98,105, 97,115, 42, 99,111, 46,119, 59, 10, 10, 9, 9,114,101,115,117, +108,116, 32, 61, 32,115,104, 97,100,111,119, 50, 68, 80,114,111,106, 40,115,104, 97,100,111,119,109, 97,112, 44, 32, 99,111, 41, + 46,120, 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,101,120,112,111,115,117,114,101, 95, 99,111, +114,114,101, 99,116, 40,118,101, 99, 51, 32, 99,111,108, 44, 32,102,108,111, 97,116, 32,108,105,110,102, 97, 99, 44, 32,102,108, +111, 97,116, 32,108,111,103,102, 97, 99, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9, +111,117,116, 99,111,108, 32, 61, 32,108,105,110,102, 97, 99, 42, 40, 49, 46, 48, 32, 45, 32,101,120,112, 40, 99,111,108, 42,108, +111,103,102, 97, 99, 41, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,109,105,115,116, 95,102, 97, 99,116, +111,114, 40,118,101, 99, 51, 32, 99,111, 44, 32,102,108,111, 97,116, 32,109,105,115,116,115,116, 97, 44, 32,102,108,111, 97,116, + 32,109,105,115,116,100,105,115,116, 44, 32,102,108,111, 97,116, 32,109,105,115,116,116,121,112,101, 44, 32,102,108,111, 97,116, + 32,109,105,115,105, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,102, 97, 99, 41, 10,123, 10, 9,102,108,111, 97, +116, 32,102, 97, 99, 44, 32,122, 99,111,114, 59, 10, 10, 9,122, 99,111,114, 32, 61, 32, 40,103,108, 95, 80,114,111,106,101, 99, +116,105,111,110, 77, 97,116,114,105,120, 91, 51, 93, 91, 51, 93, 32, 61, 61, 32, 48, 46, 48, 41, 63, 32,108,101,110,103,116,104, + 40, 99,111, 41, 58, 32, 45, 99,111, 91, 50, 93, 59, 10, 9, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40, 40,122, 99, +111,114, 45,109,105,115,116,115,116, 97, 41, 47,109,105,115,116,100,105,115,116, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, + 10, 9,105,102, 40,109,105,115,116,116,121,112,101, 32, 61, 61, 32, 48, 46, 48, 41, 32,102, 97, 99, 32, 42, 61, 32,102, 97, 99, + 59, 10, 9,101,108,115,101, 32,105,102, 40,109,105,115,116,116,121,112,101, 32, 61, 61, 32, 49, 46, 48, 41, 59, 10, 9,101,108, +115,101, 32,102, 97, 99, 32, 61, 32,115,113,114,116, 40,102, 97, 99, 41, 59, 10, 10, 9,111,117,116,102, 97, 99, 32, 61, 32, 49, + 46, 48, 32, 45, 32, 40, 49, 46, 48, 45,102, 97, 99, 41, 42, 40, 49, 46, 48, 45,109,105,115,105, 41, 59, 10,125, 10, 10,118,111, +105,100, 32,115,104, 97,100,101, 95,119,111,114,108,100, 95,109,105,120, 40,118,101, 99, 51, 32,104,111,114, 44, 32,118,101, 99, + 52, 32, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, + 32,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40, 99,111,108, 46, 97, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9, +111,117,116, 99,111,108, 32, 61, 32,118,101, 99, 52, 40,109,105,120, 40,104,111,114, 44, 32, 99,111,108, 46,114,103, 98, 44, 32, +102, 97, 99, 41, 44, 32, 99,111,108, 46, 97, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95, 97,108,112,104, + 97, 95,111,112, 97,113,117,101, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99, +111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32,118,101, 99, 52, 40, 99,111,108, 46,114,103, 98, 44, 32, 49, 46, + 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95, 97,108,112,104, 97, 95,111, 98, 99,111,108,111,114, 40, +118,101, 99, 52, 32, 99,111,108, 44, 32,118,101, 99, 52, 32,111, 98, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111, +117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32,118,101, 99, 52, 40, 99,111,108, 46,114,103, 98, 44, + 32, 99,111,108, 46, 97, 42,111, 98, 99,111,108, 46, 97, 41, 59, 10,125, 10, 10, 47, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 32, 78, 69, 87, 32, 83, 72, 65, 68, 69, 82, 32, 85, 84, 73, 76, 73, 84, 73, 69, 83, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 47, 10, 10,102,108,111, 97,116, 32,102,114,101,115,110,101,108, 95,100,105,101,108,101, 99,116,114,105, 99, 40, +118,101, 99, 51, 32, 73,110, 99,111,109,105,110,103, 44, 32,118,101, 99, 51, 32, 78,111,114,109, 97,108, 44, 32,102,108,111, 97, +116, 32,101,116, 97, 41, 10,123, 10, 32, 32, 32, 32, 47, 42, 32, 99,111,109,112,117,116,101, 32,102,114,101,115,110,101,108, 32, +114,101,102,108,101, 99,116, 97,110, 99,101, 32,119,105,116,104,111,117,116, 32,101,120,112,108,105, 99,105,116,108,121, 32, 99, +111,109,112,117,116,105,110,103, 10, 32, 32, 32, 32, 32, 32, 32,116,104,101, 32,114,101,102,114, 97, 99,116,101,100, 32,100,105, +114,101, 99,116,105,111,110, 32, 42, 47, 10, 32, 32, 32, 32,102,108,111, 97,116, 32, 99, 32, 61, 32, 97, 98,115, 40,100,111,116, + 40, 73,110, 99,111,109,105,110,103, 44, 32, 78,111,114,109, 97,108, 41, 41, 59, 10, 32, 32, 32, 32,102,108,111, 97,116, 32,103, + 32, 61, 32,101,116, 97, 32, 42, 32,101,116, 97, 32, 45, 32, 49, 46, 48, 32, 43, 32, 99, 32, 42, 32, 99, 59, 10, 32, 32, 32, 32, +102,108,111, 97,116, 32,114,101,115,117,108,116, 59, 10, 10, 32, 32, 32, 32,105,102, 40,103, 32, 62, 32, 48, 46, 48, 41, 32,123, + 10, 32, 32, 32, 32, 32, 32, 32, 32,103, 32, 61, 32,115,113,114,116, 40,103, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32,102,108, +111, 97,116, 32, 65, 32, 61, 40,103, 32, 45, 32, 99, 41, 47, 40,103, 32, 43, 32, 99, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, +102,108,111, 97,116, 32, 66, 32, 61, 40, 99, 32, 42, 40,103, 32, 43, 32, 99, 41, 45, 32, 49, 46, 48, 41, 47, 40, 99, 32, 42, 40, +103, 32, 45, 32, 99, 41, 43, 32, 49, 46, 48, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,115,117,108,116, 32, 61, 32, 48, + 46, 53, 32, 42, 32, 65, 32, 42, 32, 65, 32, 42, 40, 49, 46, 48, 32, 43, 32, 66, 32, 42, 32, 66, 41, 59, 10, 32, 32, 32, 32,125, + 10, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,115,117,108,116, 32, 61, 32, 49, 46, 48, 59, 32, + 32, 47, 42, 32, 84, 73, 82, 32, 40,110,111, 32,114,101,102,114, 97, 99,116,101,100, 32, 99,111,109,112,111,110,101,110,116, 41, + 32, 42, 47, 10, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,114,101,115,117,108,116, 59, 10,125, 10, 10,102,108,111, 97,116, + 32,104,121,112,111,116, 40,102,108,111, 97,116, 32,120, 44, 32,102,108,111, 97,116, 32,121, 41, 10,123, 10, 9,114,101,116,117, +114,110, 32,115,113,114,116, 40,120, 42,120, 32, 43, 32,121, 42,121, 41, 59, 10,125, 10, 10, 47, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 32, 78, 69, 87, 32, 83, 72, 65, 68, 69, 82, 32, 78, 79, 68, 69, 83, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 47, 10, 10, 35,100,101,102,105,110,101, 32, 78, 85, 77, 95, 76, 73, 71, 72, 84, 83, 32, 51, 10, 10, 47, 42, 32, + 98,115,100,102,115, 32, 42, 47, 10, 10,118,111,105,100, 32,110,111,100,101, 95, 98,115,100,102, 95,100,105,102,102,117,115,101, + 40,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,102,108,111, 97,116, 32,114,111,117,103,104,110,101,115,115, 44, 32,118,101, + 99, 51, 32, 78, 44, 32,111,117,116, 32,118,101, 99, 52, 32,114,101,115,117,108,116, 41, 10,123, 10, 9, 47, 42, 32, 97,109, 98, +105,101,110,116, 32,108,105,103,104,116, 32, 42, 47, 10, 9,118,101, 99, 51, 32, 76, 32, 61, 32,118,101, 99, 51, 40, 48, 46, 50, + 41, 59, 10, 10, 9, 47, 42, 32,100,105,114,101, 99,116,105,111,110, 97,108, 32,108,105,103,104,116,115, 32, 42, 47, 10, 9,102, +111,114, 40,105,110,116, 32,105, 32, 61, 32, 48, 59, 32,105, 32, 60, 32, 78, 85, 77, 95, 76, 73, 71, 72, 84, 83, 59, 32,105, 43, + 43, 41, 32,123, 10, 9, 9,118,101, 99, 51, 32,108,105,103,104,116, 95,112,111,115,105,116,105,111,110, 32, 61, 32,103,108, 95, + 76,105,103,104,116, 83,111,117,114, 99,101, 91,105, 93, 46,112,111,115,105,116,105,111,110, 46,120,121,122, 59, 10, 9, 9,118, +101, 99, 51, 32,108,105,103,104,116, 95,100,105,102,102,117,115,101, 32, 61, 32,103,108, 95, 76,105,103,104,116, 83,111,117,114, + 99,101, 91,105, 93, 46,100,105,102,102,117,115,101, 46,114,103, 98, 59, 10, 10, 9, 9,102,108,111, 97,116, 32, 98,115,100,102, + 32, 61, 32,109, 97,120, 40,100,111,116, 40, 78, 44, 32,108,105,103,104,116, 95,112,111,115,105,116,105,111,110, 41, 44, 32, 48, + 46, 48, 41, 59, 10, 9, 9, 76, 32, 43, 61, 32,108,105,103,104,116, 95,100,105,102,102,117,115,101, 42, 98,115,100,102, 59, 10, + 9,125, 10, 10, 9,114,101,115,117,108,116, 32, 61, 32,118,101, 99, 52, 40, 76, 42, 99,111,108,111,114, 46,114,103, 98, 44, 32, + 49, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95, 98,115,100,102, 95,103,108,111,115,115,121, 40,118, +101, 99, 52, 32, 99,111,108,111,114, 44, 32,102,108,111, 97,116, 32,114,111,117,103,104,110,101,115,115, 44, 32,118,101, 99, 51, + 32, 78, 44, 32,118,101, 99, 51, 32, 73, 44, 32,111,117,116, 32,118,101, 99, 52, 32,114,101,115,117,108,116, 41, 10,123, 10, 9, + 47, 42, 32, 97,109, 98,105,101,110,116, 32,108,105,103,104,116, 32, 42, 47, 10, 9,118,101, 99, 51, 32, 76, 32, 61, 32,118,101, + 99, 51, 40, 48, 46, 50, 41, 59, 10, 10, 9, 47, 42, 32,100,105,114,101, 99,116,105,111,110, 97,108, 32,108,105,103,104,116,115, + 32, 42, 47, 10, 9,102,111,114, 40,105,110,116, 32,105, 32, 61, 32, 48, 59, 32,105, 32, 60, 32, 78, 85, 77, 95, 76, 73, 71, 72, + 84, 83, 59, 32,105, 43, 43, 41, 32,123, 10, 9, 9,118,101, 99, 51, 32,108,105,103,104,116, 95,112,111,115,105,116,105,111,110, + 32, 61, 32,103,108, 95, 76,105,103,104,116, 83,111,117,114, 99,101, 91,105, 93, 46,112,111,115,105,116,105,111,110, 46,120,121, +122, 59, 10, 9, 9,118,101, 99, 51, 32, 72, 32, 61, 32,103,108, 95, 76,105,103,104,116, 83,111,117,114, 99,101, 91,105, 93, 46, +104, 97,108,102, 86,101, 99,116,111,114, 46,120,121,122, 59, 10, 9, 9,118,101, 99, 51, 32,108,105,103,104,116, 95,100,105,102, +102,117,115,101, 32, 61, 32,103,108, 95, 76,105,103,104,116, 83,111,117,114, 99,101, 91,105, 93, 46,100,105,102,102,117,115,101, + 46,114,103, 98, 59, 10, 9, 9,118,101, 99, 51, 32,108,105,103,104,116, 95,115,112,101, 99,117,108, 97,114, 32, 61, 32,103,108, + 95, 76,105,103,104,116, 83,111,117,114, 99,101, 91,105, 93, 46,115,112,101, 99,117,108, 97,114, 46,114,103, 98, 59, 10, 10, 9, + 9, 47, 42, 32,119,101, 32,109,105,120, 32,105,110, 32,115,111,109,101, 32,100,105,102,102,117,115,101, 32,115,111, 32,108,111, +119, 32,114,111,117,103,104,110,101,115,115, 32,115,116,105,108,108, 32,115,104,111,119,115, 32,117,112, 32, 42, 47, 10, 9, 9, +102,108,111, 97,116, 32, 98,115,100,102, 32, 61, 32, 48, 46, 53, 42,112,111,119, 40,109, 97,120, 40,100,111,116, 40, 78, 44, 32, + 72, 41, 44, 32, 48, 46, 48, 41, 44, 32, 49, 46, 48, 47,114,111,117,103,104,110,101,115,115, 41, 59, 10, 9, 9, 98,115,100,102, + 32, 43, 61, 32, 48, 46, 53, 42,109, 97,120, 40,100,111,116, 40, 78, 44, 32,108,105,103,104,116, 95,112,111,115,105,116,105,111, +110, 41, 44, 32, 48, 46, 48, 41, 59, 10, 9, 9, 76, 32, 43, 61, 32,108,105,103,104,116, 95,115,112,101, 99,117,108, 97,114, 42, + 98,115,100,102, 59, 10, 9,125, 10, 10, 9,114,101,115,117,108,116, 32, 61, 32,118,101, 99, 52, 40, 76, 42, 99,111,108,111,114, + 46,114,103, 98, 44, 32, 49, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95, 98,115,100,102, 95, 97,110, +105,115,111,116,114,111,112,105, 99, 40,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,102,108,111, 97,116, 32,114,111,117,103, +104,110,101,115,115, 85, 44, 32,102,108,111, 97,116, 32,114,111,117,103,104,110,101,115,115, 86, 44, 32,118,101, 99, 51, 32, 78, + 44, 32,118,101, 99, 51, 32, 73, 44, 32,111,117,116, 32,118,101, 99, 52, 32,114,101,115,117,108,116, 41, 10,123, 10, 9,110,111, +100,101, 95, 98,115,100,102, 95,100,105,102,102,117,115,101, 40, 99,111,108,111,114, 44, 32, 48, 46, 48, 44, 32, 78, 44, 32,114, +101,115,117,108,116, 41, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95, 98,115,100,102, 95,103,108, 97,115,115, 40, +118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,102,108,111, 97,116, 32,114,111,117,103,104,110,101,115,115, 44, 32,102,108,111, + 97,116, 32,105,111,114, 44, 32,118,101, 99, 51, 32, 78, 44, 32,118,101, 99, 51, 32, 73, 44, 32,111,117,116, 32,118,101, 99, 52, + 32,114,101,115,117,108,116, 41, 10,123, 10, 9,110,111,100,101, 95, 98,115,100,102, 95,100,105,102,102,117,115,101, 40, 99,111, +108,111,114, 44, 32, 48, 46, 48, 44, 32, 78, 44, 32,114,101,115,117,108,116, 41, 59, 10,125, 10, 10,118,111,105,100, 32,110,111, +100,101, 95, 98,115,100,102, 95,116,114, 97,110,115,108,117, 99,101,110,116, 40,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32, +118,101, 99, 51, 32, 78, 44, 32,111,117,116, 32,118,101, 99, 52, 32,114,101,115,117,108,116, 41, 10,123, 10, 9,110,111,100,101, + 95, 98,115,100,102, 95,100,105,102,102,117,115,101, 40, 99,111,108,111,114, 44, 32, 48, 46, 48, 44, 32, 78, 44, 32,114,101,115, +117,108,116, 41, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95, 98,115,100,102, 95,116,114, 97,110,115,112, 97,114, +101,110,116, 40,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,111,117,116, 32,118,101, 99, 52, 32,114,101,115,117,108,116, 41, + 10,123, 10, 9, 47, 42, 32,116,104,105,115, 32,105,115,110, 39,116, 32,114,105,103,104,116, 32, 42, 47, 10, 9,114,101,115,117, +108,116, 46,114, 32, 61, 32, 99,111,108,111,114, 46,114, 59, 10, 9,114,101,115,117,108,116, 46,103, 32, 61, 32, 99,111,108,111, +114, 46,103, 59, 10, 9,114,101,115,117,108,116, 46, 98, 32, 61, 32, 99,111,108,111,114, 46, 98, 59, 10, 9,114,101,115,117,108, +116, 46, 97, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95, 98,115,100,102, 95,118,101,108, +118,101,116, 40,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,102,108,111, 97,116, 32,115,105,103,109, 97, 44, 32,118,101, 99, + 51, 32, 78, 44, 32,111,117,116, 32,118,101, 99, 52, 32,114,101,115,117,108,116, 41, 10,123, 10, 9,110,111,100,101, 95, 98,115, +100,102, 95,100,105,102,102,117,115,101, 40, 99,111,108,111,114, 44, 32, 48, 46, 48, 44, 32, 78, 44, 32,114,101,115,117,108,116, + 41, 59, 10,125, 10, 10, 47, 42, 32,101,109,105,115,115,105,111,110, 32, 42, 47, 10, 10,118,111,105,100, 32,110,111,100,101, 95, +101,109,105,115,115,105,111,110, 40,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,102,108,111, 97,116, 32,115,116,114,101,110, +103,116,104, 44, 32,118,101, 99, 51, 32, 78, 44, 32,111,117,116, 32,118,101, 99, 52, 32,114,101,115,117,108,116, 41, 10,123, 10, + 9,114,101,115,117,108,116, 32, 61, 32, 99,111,108,111,114, 42,115,116,114,101,110,103,116,104, 59, 10,125, 10, 10, 47, 42, 32, + 99,108,111,115,117,114,101,115, 32, 42, 47, 10, 10,118,111,105,100, 32,110,111,100,101, 95,109,105,120, 95,115,104, 97,100,101, +114, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32,115,104, 97,100,101,114, 49, 44, 32,118,101, 99, 52, 32, +115,104, 97,100,101,114, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,115,104, 97,100,101,114, 41, 10,123, 10, 9,115,104, 97, +100,101,114, 32, 61, 32,109,105,120, 40,115,104, 97,100,101,114, 49, 44, 32,115,104, 97,100,101,114, 50, 44, 32,102, 97, 99, 41, + 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95, 97,100,100, 95,115,104, 97,100,101,114, 40,118,101, 99, 52, 32,115, +104, 97,100,101,114, 49, 44, 32,118,101, 99, 52, 32,115,104, 97,100,101,114, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,115, +104, 97,100,101,114, 41, 10,123, 10, 9,115,104, 97,100,101,114, 32, 61, 32,115,104, 97,100,101,114, 49, 32, 43, 32,115,104, 97, +100,101,114, 50, 59, 10,125, 10, 10, 47, 42, 32,102,114,101,115,110,101,108, 32, 42, 47, 10, 10,118,111,105,100, 32,110,111,100, +101, 95,102,114,101,115,110,101,108, 40,102,108,111, 97,116, 32,105,111,114, 44, 32,118,101, 99, 51, 32, 78, 44, 32,118,101, 99, + 51, 32, 73, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,114,101,115,117,108,116, 41, 10,123, 10, 9,102,108,111, 97,116, 32, +101,116, 97, 32, 61, 32,109, 97,120, 40,105,111,114, 44, 32, 48, 46, 48, 48, 48, 48, 49, 41, 59, 10, 9,114,101,115,117,108,116, + 32, 61, 32,102,114,101,115,110,101,108, 95,100,105,101,108,101, 99,116,114,105, 99, 40, 73, 44, 32, 78, 44, 32,101,116, 97, 41, + 59, 32, 47, 47, 98, 97, 99,107,102, 97, 99,105,110,103, 40, 41, 63, 32, 49, 46, 48, 47,101,116, 97, 58, 32,101,116, 97, 41, 59, + 10,125, 10, 10, 47, 42, 32,103,101,111,109,101,116,114,121, 32, 42, 47, 10, 10,118,111,105,100, 32,110,111,100,101, 95,103,101, +111,109,101,116,114,121, 40,118,101, 99, 51, 32, 73, 44, 32,118,101, 99, 51, 32, 78, 44, 32,109, 97,116, 52, 32,116,111,119,111, +114,108,100, 44, 10, 9,111,117,116, 32,118,101, 99, 51, 32,112,111,115,105,116,105,111,110, 44, 32,111,117,116, 32,118,101, 99, + 51, 32,110,111,114,109, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,116, 97,110,103,101,110,116, 44, 10, 9,111,117,116, + 32,118,101, 99, 51, 32,116,114,117,101, 95,110,111,114,109, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111, +109,105,110,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,112, 97,114, 97,109,101,116,114,105, 99, 44, 10, 9,111,117,116, 32, +102,108,111, 97,116, 32, 98, 97, 99,107,102, 97, 99,105,110,103, 41, 10,123, 10, 9,112,111,115,105,116,105,111,110, 32, 61, 32, + 40,116,111,119,111,114,108,100, 42,118,101, 99, 52, 40, 73, 44, 32, 49, 46, 48, 41, 41, 46,120,121,122, 59, 10, 9,110,111,114, +109, 97,108, 32, 61, 32, 78, 59, 10, 9,116, 97,110,103,101,110,116, 32, 61, 32,118,101, 99, 51, 40, 48, 46, 48, 41, 59, 10, 9, +116,114,117,101, 95,110,111,114,109, 97,108, 32, 61, 32, 78, 59, 10, 9,105,110, 99,111,109,105,110,103, 32, 61, 32, 73, 59, 10, + 9,112, 97,114, 97,109,101,116,114,105, 99, 32, 61, 32,118,101, 99, 51, 40, 48, 46, 48, 41, 59, 10, 9, 98, 97, 99,107,102, 97, + 99,105,110,103, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95,116,101,120, 95, 99,111,111, +114,100, 40,118,101, 99, 51, 32, 73, 44, 32,118,101, 99, 51, 32, 78, 44, 32,109, 97,116, 52, 32,116,111,119,111,114,108,100, 44, + 10, 9,118,101, 99, 51, 32, 97,116,116,114, 95,111,114, 99,111, 44, 32,118,101, 99, 51, 32, 97,116,116,114, 95,117,118, 44, 10, + 9,111,117,116, 32,118,101, 99, 51, 32,103,101,110,101,114, 97,116,101,100, 44, 32,111,117,116, 32,118,101, 99, 51, 32,117,118, + 44, 32,111,117,116, 32,118,101, 99, 51, 32,111, 98,106,101, 99,116, 44, 10, 9,111,117,116, 32,118,101, 99, 51, 32, 99, 97,109, +101,114, 97, 44, 32,111,117,116, 32,118,101, 99, 51, 32,119,105,110,100,111,119, 44, 32,111,117,116, 32,118,101, 99, 51, 32,114, +101,102,108,101, 99,116,105,111,110, 41, 10,123, 10, 9,103,101,110,101,114, 97,116,101,100, 32, 61, 32, 97,116,116,114, 95,111, +114, 99,111, 59, 10, 9,117,118, 32, 61, 32, 97,116,116,114, 95,117,118, 59, 10, 9,111, 98,106,101, 99,116, 32, 61, 32, 73, 59, + 10, 9, 99, 97,109,101,114, 97, 32, 61, 32, 73, 59, 10, 9,119,105,110,100,111,119, 32, 61, 32,103,108, 95, 70,114, 97,103, 67, +111,111,114,100, 46,120,121,122, 59, 10, 9,114,101,102,108,101, 99,116,105,111,110, 32, 61, 32,114,101,102,108,101, 99,116, 40, + 78, 44, 32, 73, 41, 59, 10, 10,125, 10, 10, 47, 42, 32,116,101,120,116,117,114,101,115, 32, 42, 47, 10, 10,118,111,105,100, 32, +110,111,100,101, 95,116,101,120, 95,103,114, 97,100,105,101,110,116, 40,118,101, 99, 51, 32, 99,111, 44, 32,111,117,116, 32,118, +101, 99, 52, 32, 99,111,108,111,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 97, 99, 41, 10,123, 10, 9, 99,111,108, +111,114, 32, 61, 32,118,101, 99, 52, 40, 49, 46, 48, 41, 59, 10, 9,102, 97, 99, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10,118, +111,105,100, 32,110,111,100,101, 95,116,101,120, 95, 99,104,101, 99,107,101,114, 40,118,101, 99, 51, 32, 99,111, 44, 32,118,101, + 99, 52, 32, 99,111,108,111,114, 49, 44, 32,118,101, 99, 52, 32, 99,111,108,111,114, 50, 44, 32,102,108,111, 97,116, 32,115, 99, + 97,108,101, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102, + 97, 99, 41, 10,123, 10, 9, 99,111,108,111,114, 32, 61, 32,118,101, 99, 52, 40, 49, 46, 48, 41, 59, 10, 9,102, 97, 99, 32, 61, + 32, 49, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95,116,101,120, 95, 99,108,111,117,100,115, 40,118,101, + 99, 51, 32, 99,111, 44, 32,102,108,111, 97,116, 32,115,105,122,101, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108,111, +114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 97, 99, 41, 10,123, 10, 9, 99,111,108,111,114, 32, 61, 32,118,101, 99, + 52, 40, 49, 46, 48, 41, 59, 10, 9,102, 97, 99, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, + 95,116,101,120, 95,101,110,118,105,114,111,110,109,101,110,116, 40,118,101, 99, 51, 32, 99,111, 44, 32,115, 97,109,112,108,101, +114, 50, 68, 32,105,109, 97, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108,111,114, 41, 10,123, 10, 9,102,108,111, 97, +116, 32,117, 32, 61, 32, 40, 97,116, 97,110, 40, 99,111, 46,121, 44, 32, 99,111, 46,120, 41, 32, 43, 32, 77, 95, 80, 73, 41, 47, + 40, 50, 46, 48, 42, 77, 95, 80, 73, 41, 59, 10, 9,102,108,111, 97,116, 32,118, 32, 61, 32, 97,116, 97,110, 40, 99,111, 46,122, + 44, 32,104,121,112,111,116, 40, 99,111, 46,120, 44, 32, 99,111, 46,121, 41, 41, 47, 77, 95, 80, 73, 32, 43, 32, 48, 46, 53, 59, + 10, 10, 9, 99,111,108,111,114, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32,118,101, 99, 50, 40,117, + 44, 32,118, 41, 41, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95,116,101,120, 95,105,109, 97,103,101, 40,118,101, + 99, 51, 32, 99,111, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99, +111,108,111,114, 41, 10,123, 10, 9, 99,111,108,111,114, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, + 99,111, 46,120,121, 41, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95,116,101,120, 95,109, 97,103,105, 99, 40,118, +101, 99, 51, 32,112, 44, 32,102,108,111, 97,116, 32,115, 99, 97,108,101, 44, 32,102,108,111, 97,116, 32,100,105,115,116,111,114, +116,105,111,110, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32, +102, 97, 99, 41, 10,123, 10, 9, 99,111,108,111,114, 32, 61, 32,118,101, 99, 52, 40, 49, 46, 48, 41, 59, 10, 9,102, 97, 99, 32, + 61, 32, 49, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95,116,101,120, 95,109,117,115,103,114, 97,118,101, + 40,118,101, 99, 51, 32, 99,111, 44, 32,102,108,111, 97,116, 32,115, 99, 97,108,101, 44, 32,102,108,111, 97,116, 32,100,101,116, + 97,105,108, 44, 32,102,108,111, 97,116, 32,100,105,109,101,110,115,105,111,110, 44, 32,102,108,111, 97,116, 32,108, 97, 99,117, +110, 97,114,105,116,121, 44, 32,102,108,111, 97,116, 32,111,102,102,115,101,116, 44, 32,102,108,111, 97,116, 32,103, 97,105,110, + 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 97, 99, 41, + 10,123, 10, 9, 99,111,108,111,114, 32, 61, 32,118,101, 99, 52, 40, 49, 46, 48, 41, 59, 10, 9,102, 97, 99, 32, 61, 32, 49, 46, + 48, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95,116,101,120, 95,110,111,105,115,101, 40,118,101, 99, 51, 32, 99, +111, 44, 32,102,108,111, 97,116, 32,115, 99, 97,108,101, 44, 32,102,108,111, 97,116, 32,100,101,116, 97,105,108, 44, 32,102,108, +111, 97,116, 32,100,105,115,116,111,114,116,105,111,110, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32, 111,117,116, 32,102,108,111, 97,116, 32,102, 97, 99, 41, 10,123, 10, 9, 99,111,108,111,114, 32, 61, 32,118,101, 99, 52, 40, 49, 46, 48, 41, 59, 10, 9,102, 97, 99, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95,116,101, 120, 95,115,107,121, 40,118,101, 99, 51, 32, 99,111, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108,111,114, 41, 10,123, 10, 9, 99,111,108,111,114, 32, 61, 32,118,101, 99, 52, 40, 49, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100, -101, 95,116,101,120, 95,115,116,117, 99, 99,105, 40,118,101, 99, 51, 32, 99,111, 44, 32,102,108,111, 97,116, 32,115,105,122,101, - 44, 32,102,108,111, 97,116, 32,116,117,114, 98,117,108,101,110, 99,101, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 97, - 99, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95,116,101, -120, 95,118,111,114,111,110,111,105, 40,118,101, 99, 51, 32, 99,111, 44, 32,102,108,111, 97,116, 32,115,105,122,101, 44, 32,102, -108,111, 97,116, 32,119,101,105,103,104,116, 49, 44, 32,102,108,111, 97,116, 32,119,101,105,103,104,116, 50, 44, 32,102,108,111, - 97,116, 32,119,101,105,103,104,116, 51, 44, 32,102,108,111, 97,116, 32,119,101,105,103,104,116, 52, 44, 32,102,108,111, 97,116, - 32,101,120,112,111,110,101,110,116, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,111,117,116, 32,102, -108,111, 97,116, 32,102, 97, 99, 41, 10,123, 10, 9, 99,111,108,111,114, 32, 61, 32,118,101, 99, 52, 40, 49, 46, 48, 41, 59, 10, - 9,102, 97, 99, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95,116,101,120, 95,119,111,111, -100, 40,118,101, 99, 51, 32, 99,111, 44, 32,102,108,111, 97,116, 32,115,105,122,101, 44, 32,102,108,111, 97,116, 32,116,117,114, - 98,117,108,101,110, 99,101, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 97, 99, 41, 10,123, 10, 9,102, 97, 99, 32, 61, +101, 95,116,101,120, 95,118,111,114,111,110,111,105, 40,118,101, 99, 51, 32, 99,111, 44, 32,102,108,111, 97,116, 32,115, 99, 97, +108,101, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 97, + 99, 41, 10,123, 10, 9, 99,111,108,111,114, 32, 61, 32,118,101, 99, 52, 40, 49, 46, 48, 41, 59, 10, 9,102, 97, 99, 32, 61, 32, + 49, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95,116,101,120, 95,119, 97,118,101, 40,118,101, 99, 51, 32, + 99,111, 44, 32,102,108,111, 97,116, 32,115, 99, 97,108,101, 44, 32,102,108,111, 97,116, 32,100,105,115,116,111,114,116,105,111, +110, 44, 32,102,108,111, 97,116, 32,100,101,116, 97,105,108, 44, 32,102,108,111, 97,116, 32,100,101,116, 97,105,108, 95,115, 99, + 97,108,101, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102, + 97, 99, 41, 10,123, 10, 9, 99,111,108,111,114, 32, 61, 32,118,101, 99, 52, 40, 49, 46, 48, 41, 59, 10, 9,102, 97, 99, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10, 47, 42, 32,108,105,103,104,116, 32,112, 97,116,104, 32, 42, 47, 10, 10,118,111,105,100, 32, 110,111,100,101, 95,108,105,103,104,116, 95,112, 97,116,104, 40, 10, 9,111,117,116, 32,102,108,111, 97,116, 32,105,115, 95, 99, 97,109,101,114, 97, 95,114, 97,121, 44, 10, 9,111,117,116, 32,102,108,111, 97,116, 32,105,115, 95,115,104, 97,100,111,119, 95, diff -Nru blender-2.61/source/blender/ikplugin/intern/iksolver_plugin.c blender-2.62/source/blender/ikplugin/intern/iksolver_plugin.c --- blender-2.61/source/blender/ikplugin/intern/iksolver_plugin.c 2011-12-13 19:49:30.000000000 +0000 +++ blender-2.62/source/blender/ikplugin/intern/iksolver_plugin.c 2012-02-15 19:34:19.000000000 +0000 @@ -199,7 +199,7 @@ if (pchan->parent) { float iR_parmat[4][4]; invert_m4_m4(iR_parmat, pchan->parent->pose_mat); - mul_m4_m4m4(pchan->chan_mat, pchan->pose_mat, iR_parmat); // delta mat + mult_m4_m4m4(pchan->chan_mat, iR_parmat, pchan->pose_mat); // delta mat } else copy_m4_m4(pchan->chan_mat, pchan->pose_mat); } @@ -216,7 +216,7 @@ if (pchan->parent) mul_serie_m4(pchan->pose_mat, pchan->parent->pose_mat, pchan->chan_mat, ikmat, NULL, NULL, NULL, NULL, NULL); else - mul_m4_m4m4(pchan->pose_mat, ikmat, pchan->chan_mat); + mult_m4_m4m4(pchan->pose_mat, pchan->chan_mat, ikmat); /* calculate head */ copy_v3_v3(pchan->pose_head, pchan->pose_mat[3]); @@ -356,7 +356,7 @@ unit_m4(rootmat); copy_v3_v3(rootmat[3], pchan->pose_head); - mul_m4_m4m4(imat, rootmat, ob->obmat); + mult_m4_m4m4(imat, ob->obmat, rootmat); invert_m4_m4(goalinv, imat); for (target=tree->targets.first; target; target=target->next) { @@ -371,7 +371,7 @@ get_constraint_target_matrix(scene, target->con, 0, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0); /* and set and transform goal */ - mul_m4_m4m4(goal, rootmat, goalinv); + mult_m4_m4m4(goal, goalinv, rootmat); copy_v3_v3(goalpos, goal[3]); copy_m3_m4(goalrot, goal); @@ -385,7 +385,7 @@ break; } else { - mul_m4_m4m4(goal, rootmat, goalinv); + mult_m4_m4m4(goal, goalinv, rootmat); copy_v3_v3(polepos, goal[3]); poleconstrain= 1; diff -Nru blender-2.61/source/blender/ikplugin/intern/itasc_plugin.cpp blender-2.62/source/blender/ikplugin/intern/itasc_plugin.cpp --- blender-2.61/source/blender/ikplugin/intern/itasc_plugin.cpp 2011-12-13 19:49:30.000000000 +0000 +++ blender-2.62/source/blender/ikplugin/intern/itasc_plugin.cpp 2012-02-15 19:34:19.000000000 +0000 @@ -570,7 +570,7 @@ mul_serie_m4(restmat, target->owner->obmat, chanmat, target->eeRest, NULL, NULL, NULL, NULL, NULL); } else { - mul_m4_m4m4(restmat, target->eeRest, target->owner->obmat); + mult_m4_m4m4(restmat, target->owner->obmat, target->eeRest); } // blend the target blend_m4_m4m4(tarmat, restmat, tarmat, constraint->enforce); @@ -597,7 +597,7 @@ // save the base as a frame too so that we can compute deformation // after simulation ikscene->baseFrame.setValue(&chanmat[0][0]); - mul_m4_m4m4(rootmat, chanmat, ikscene->blArmature->obmat); + mult_m4_m4m4(rootmat, ikscene->blArmature->obmat, chanmat); } else { copy_m4_m4(rootmat, ikscene->blArmature->obmat); @@ -622,11 +622,11 @@ // get polar target matrix in world space get_constraint_target_matrix(ikscene->blscene, ikscene->polarConstraint, 1, CONSTRAINT_OBTYPE_OBJECT, ikscene->blArmature, mat, 1.0); // convert to armature space - mul_m4_m4m4(polemat, mat, imat); + mult_m4_m4m4(polemat, imat, mat); // get the target in world space (was computed before as target object are defined before base object) iktarget->target->getPose().getValue(mat[0]); // convert to armature space - mul_m4_m4m4(goalmat, mat, imat); + mult_m4_m4m4(goalmat, imat, mat); // take position of target, polar target, end effector, in armature space KDL::Vector goalpos(goalmat[3]); KDL::Vector polepos(polemat[3]); @@ -1003,7 +1003,7 @@ copy_m4_m4(bmat, bone->arm_mat); } invert_m4_m4(rmat, bmat); - mul_m4_m4m4(bmat, pchan->pose_mat, rmat); + mult_m4_m4m4(bmat, rmat, pchan->pose_mat); normalize_m4(bmat); boneRot.setValue(bmat[0]); GetJointRotation(boneRot, ikchan->jointType, rot); @@ -1419,7 +1419,7 @@ copy_m4_m4(mat, pchan->bone->arm_mat); copy_v3_v3(mat[3], pchan->bone->arm_tail); // get the rest pose relative to the armature base - mul_m4_m4m4(iktarget->eeRest, mat, invBaseFrame); + mult_m4_m4m4(iktarget->eeRest, invBaseFrame, mat); iktarget->eeBlend = (!ikscene->polarConstraint && condata->type==CONSTRAINT_IK_COPYPOSE) ? true : false; // use target_callback to make sure the initPose includes enforce coefficient target_callback(iTaSC::Timestamp(), iTaSC::F_identity, initPose, iktarget); diff -Nru blender-2.61/source/blender/imbuf/CMakeLists.txt blender-2.62/source/blender/imbuf/CMakeLists.txt --- blender-2.61/source/blender/imbuf/CMakeLists.txt 2011-12-13 19:50:46.000000000 +0000 +++ blender-2.62/source/blender/imbuf/CMakeLists.txt 2012-02-15 19:35:33.000000000 +0000 @@ -53,7 +53,6 @@ intern/indexer_dv.c intern/iris.c intern/jpeg.c - intern/md5.c intern/metadata.c intern/module.c intern/moviecache.c @@ -96,7 +95,6 @@ intern/dds/Stream.h intern/dds/dds_api.h intern/imbuf.h - intern/md5.h intern/openexr/openexr_api.h intern/openexr/openexr_multi.h diff -Nru blender-2.61/source/blender/imbuf/IMB_imbuf.h blender-2.62/source/blender/imbuf/IMB_imbuf.h --- blender-2.61/source/blender/imbuf/IMB_imbuf.h 2011-12-13 19:50:46.000000000 +0000 +++ blender-2.62/source/blender/imbuf/IMB_imbuf.h 2012-02-15 19:35:33.000000000 +0000 @@ -198,7 +198,8 @@ record date and time written by recording device (*every* consumer camcorder can do that :) )*/ - IMB_TC_MAX_SLOT = 3 + IMB_TC_RECORD_RUN_NO_GAPS = 8, + IMB_TC_MAX_SLOT = 8 } IMB_Timecode_Type; typedef enum IMB_Proxy_Size { @@ -377,6 +378,21 @@ float *IMB_float_profile_ensure(struct ImBuf *ibuf, int profile, int *alloc); void IMB_color_to_bw(struct ImBuf *ibuf); +/* converting pixel buffers */ +void IMB_buffer_byte_from_float(unsigned char *rect_to, const float *rect_from, + int channels_from, float dither, int profile_to, int profile_from, int predivide, + int width, int height, int stride_to, int stride_from); +void IMB_buffer_float_from_byte(float *rect_to, const unsigned char *rect_from, + int profile_to, int profile_from, int predivide, + int width, int height, int stride_to, int stride_from); +void IMB_buffer_float_from_float(float *rect_to, const float *rect_from, + int channels_from, int profile_to, int profile_from, int predivide, + int width, int height, int stride_to, int stride_from); +void IMB_buffer_byte_from_byte(unsigned char *rect_to, const unsigned char *rect_from, + int profile_to, int profile_from, int predivide, + int width, int height, int stride_to, int stride_from); +void IMB_buffer_float_clamp(float *buf, int width, int height); + /** * Change the ordering of the color bytes pointed to by rect from * rgba to abgr. size * 4 color bytes are reordered. @@ -411,14 +427,6 @@ * @attention defined in readimage.c * @deprecated Only here for backwards compatibility of the * @deprecated plugin system. - */ -struct ImBuf *IMB_loadiffmem(int *mem, int flags); - -/** - * - * @attention defined in readimage.c - * @deprecated Only here for backwards compatibility of the - * @deprecated plugin system. */ struct ImBuf *IMB_loadifffile(int file, int flags, const char *descr); diff -Nru blender-2.61/source/blender/imbuf/IMB_imbuf_types.h blender-2.62/source/blender/imbuf/IMB_imbuf_types.h --- blender-2.61/source/blender/imbuf/IMB_imbuf_types.h 2011-12-13 19:50:46.000000000 +0000 +++ blender-2.62/source/blender/imbuf/IMB_imbuf_types.h 2012-02-15 19:35:33.000000000 +0000 @@ -50,7 +50,7 @@ struct ImMetaData; #define IB_MIPMAP_LEVELS 20 -#define IB_FILENAME_SIZE 1023 +#define IB_FILENAME_SIZE 1024 /** * \ingroup imbuf @@ -158,6 +158,7 @@ #define IB_tiles (1 << 10) #define IB_tilecache (1 << 11) #define IB_premul (1 << 12) +#define IB_cm_predivide (1 << 13) /* * The bit flag is stored in the ImBuf.ftype variable. diff -Nru blender-2.61/source/blender/imbuf/intern/anim_movie.c blender-2.62/source/blender/imbuf/intern/anim_movie.c --- blender-2.61/source/blender/imbuf/intern/anim_movie.c 2011-12-13 19:50:45.000000000 +0000 +++ blender-2.62/source/blender/imbuf/intern/anim_movie.c 2012-02-15 19:35:32.000000000 +0000 @@ -110,7 +110,8 @@ #endif #endif -int ismovie(const char *UNUSED(filepath)) { +int ismovie(const char *UNUSED(filepath)) +{ return 0; } @@ -126,7 +127,8 @@ # define PATHSEPERATOR '/' #endif -static int an_stringdec(const char *string, char* head, char *tail, unsigned short *numlen) { +static int an_stringdec(const char *string, char* head, char *tail, unsigned short *numlen) +{ unsigned short len,nume,nums=0; short i,found=FALSE; @@ -161,11 +163,13 @@ } -static void an_stringenc(char *string, const char *head, const char *tail, unsigned short numlen, int pic) { +static void an_stringenc(char *string, const char *head, const char *tail, unsigned short numlen, int pic) +{ BLI_stringenc(string, head, tail, numlen, pic); } -static void free_anim_avi (struct anim *anim) { +static void free_anim_avi (struct anim *anim) +{ #if defined(_WIN32) && !defined(FREE_WINDOWS) int i; #endif @@ -206,7 +210,8 @@ static void free_anim_redcode(struct anim * anim); #endif -void IMB_free_anim(struct anim * anim) { +void IMB_free_anim(struct anim * anim) +{ if (anim == NULL) { printf("free anim, anim == NULL\n"); return; @@ -229,14 +234,16 @@ MEM_freeN(anim); } -void IMB_close_anim(struct anim * anim) { +void IMB_close_anim(struct anim * anim) +{ if (anim == NULL) return; IMB_free_anim(anim); } -struct anim * IMB_open_anim( const char * name, int ib_flags, int streamindex) { +struct anim * IMB_open_anim( const char * name, int ib_flags, int streamindex) +{ struct anim * anim; anim = (struct anim*)MEM_callocN(sizeof(struct anim), "anim struct"); @@ -249,7 +256,8 @@ } -static int startavi (struct anim *anim) { +static int startavi (struct anim *anim) +{ AviError avierror; #if defined(_WIN32) && !defined(FREE_WINDOWS) @@ -355,7 +363,8 @@ return 0; } -static ImBuf * avi_fetchibuf (struct anim *anim, int position) { +static ImBuf * avi_fetchibuf (struct anim *anim, int position) +{ ImBuf *ibuf = NULL; int *tmp; int y; @@ -405,7 +414,8 @@ extern void do_init_ffmpeg(void); -static int startffmpeg(struct anim * anim) { +static int startffmpeg(struct anim * anim) +{ int i, videoStream; AVCodec *pCodec; @@ -693,7 +703,6 @@ int dstStride2[4] = { -dstStride[0], 0, 0, 0 }; uint8_t* dst2[4] = { dst[0] + (anim->y - 1)*dstStride[0], 0, 0, 0 }; - int i; sws_scale(anim->img_convert_ctx, (const uint8_t * const *)input->data, @@ -759,8 +768,8 @@ == AV_NOPTS_VALUE) ? -1 : (long long int)anim->pFrame->pkt_pts, (long long int)anim->next_pts); + break; } - break; } av_free_packet(&anim->next_packet); anim->next_packet.stream_index = -1; @@ -1032,7 +1041,8 @@ return anim->last_frame; } -static void free_anim_ffmpeg(struct anim * anim) { +static void free_anim_ffmpeg(struct anim * anim) +{ if (anim == NULL) return; if (anim->pCodecCtx) { @@ -1058,7 +1068,8 @@ #ifdef WITH_REDCODE -static int startredcode(struct anim * anim) { +static int startredcode(struct anim * anim) +{ anim->redcodeCtx = redcode_open(anim->name); if (!anim->redcodeCtx) { return -1; @@ -1068,7 +1079,8 @@ return 0; } -static ImBuf * redcode_fetchibuf(struct anim * anim, int position) { +static ImBuf * redcode_fetchibuf(struct anim * anim, int position) +{ struct ImBuf * ibuf; struct redcode_frame * frame; struct redcode_frame_raw * raw_frame; @@ -1099,7 +1111,8 @@ return ibuf; } -static void free_anim_redcode(struct anim * anim) { +static void free_anim_redcode(struct anim * anim) +{ if (anim->redcodeCtx) { redcode_close(anim->redcodeCtx); anim->redcodeCtx = 0; @@ -1113,7 +1126,8 @@ /* Geen plaatje, probeer dan volgende animatie te openen */ /* gelukt, haal dan eerste plaatje van animatie */ -static struct ImBuf * anim_getnew(struct anim * anim) { +static struct ImBuf * anim_getnew(struct anim * anim) +{ struct ImBuf *ibuf = NULL; if (anim == NULL) return(NULL); @@ -1175,7 +1189,8 @@ return(ibuf); } -struct ImBuf * IMB_anim_previewframe(struct anim * anim) { +struct ImBuf * IMB_anim_previewframe(struct anim * anim) +{ struct ImBuf * ibuf = NULL; int position = 0; @@ -1274,7 +1289,7 @@ if (ibuf) { if (filter_y) IMB_filtery(ibuf); - sprintf(ibuf->name, "%s.%04d", anim->name, anim->curposition + 1); + BLI_snprintf(ibuf->name, sizeof(ibuf->name), "%s.%04d", anim->name, anim->curposition + 1); } return(ibuf); @@ -1282,7 +1297,8 @@ /***/ -int IMB_anim_get_duration(struct anim *anim, IMB_Timecode_Type tc) { +int IMB_anim_get_duration(struct anim *anim, IMB_Timecode_Type tc) +{ struct anim_index * idx; if (tc == IMB_TC_NONE) { return anim->duration; diff -Nru blender-2.61/source/blender/imbuf/intern/bmp.c blender-2.62/source/blender/imbuf/intern/bmp.c --- blender-2.61/source/blender/imbuf/intern/bmp.c 2011-12-13 19:50:45.000000000 +0000 +++ blender-2.62/source/blender/imbuf/intern/bmp.c 2012-02-15 19:35:32.000000000 +0000 @@ -185,14 +185,16 @@ } /* Couple of helper functions for writing our data */ -static int putIntLSB(unsigned int ui,FILE *ofile) { +static int putIntLSB(unsigned int ui,FILE *ofile) +{ putc((ui>>0)&0xFF,ofile); putc((ui>>8)&0xFF,ofile); putc((ui>>16)&0xFF,ofile); return putc((ui>>24)&0xFF,ofile); } -static int putShortLSB(unsigned short us,FILE *ofile) { +static int putShortLSB(unsigned short us,FILE *ofile) +{ putc((us>>0)&0xFF,ofile); return putc((us>>8)&0xFF,ofile); } diff -Nru blender-2.61/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp blender-2.62/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp --- blender-2.61/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp 2011-12-13 19:50:43.000000000 +0000 +++ blender-2.62/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp 2012-02-15 19:35:31.000000000 +0000 @@ -703,11 +703,11 @@ void DDSHeader::setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask) { // Make sure the masks are correct. - if ((rmask & gmask) || \ - (rmask & bmask) || \ - (rmask & amask) || \ - (gmask & bmask) || \ - (gmask & amask) || \ + if ((rmask & gmask) || + (rmask & bmask) || + (rmask & amask) || + (gmask & bmask) || + (gmask & amask) || (bmask & amask)) { printf("DDS: bad RGBA masks, pixel format not set\n"); return; diff -Nru blender-2.61/source/blender/imbuf/intern/divers.c blender-2.62/source/blender/imbuf/intern/divers.c --- blender-2.61/source/blender/imbuf/intern/divers.c 2011-12-13 19:50:45.000000000 +0000 +++ blender-2.62/source/blender/imbuf/intern/divers.c 2012-02-15 19:35:32.000000000 +0000 @@ -42,13 +42,13 @@ #include "IMB_imbuf.h" #include "IMB_allocimbuf.h" -#include "BKE_colortools.h" - #include "MEM_guardedalloc.h" -void IMB_de_interlace(struct ImBuf *ibuf) +/**************************** Interlace/Deinterlace **************************/ + +void IMB_de_interlace(ImBuf *ibuf) { - struct ImBuf * tbuf1, * tbuf2; + ImBuf * tbuf1, * tbuf2; if (ibuf == NULL) return; if (ibuf->flags & IB_fields) return; @@ -73,9 +73,9 @@ ibuf->y /= 2; } -void IMB_interlace(struct ImBuf *ibuf) +void IMB_interlace(ImBuf *ibuf) { - struct ImBuf * tbuf1, * tbuf2; + ImBuf * tbuf1, * tbuf2; if (ibuf == NULL) return; ibuf->flags &= ~IB_fields; @@ -100,366 +100,606 @@ } } +/************************* Floyd-Steinberg dithering *************************/ -/* assume converting from linear float to sRGB byte */ -void IMB_rect_from_float(struct ImBuf *ibuf) +typedef struct DitherContext { + int *error_buf, *e; + int v[4], v0[4], v1[4]; + float f; +} DitherContext; + +DitherContext *create_dither_context(int w, float factor) { - /* quick method to convert floatbuf to byte */ - float *tof = (float *)ibuf->rect_float; -// int do_dither = ibuf->dither != 0.f; - float dither= ibuf->dither / 255.0f; - float srgb[4]; - int i, channels= ibuf->channels; - short profile= ibuf->profile; - unsigned char *to = (unsigned char *) ibuf->rect; - - if(tof==NULL) return; - if(to==NULL) { - imb_addrectImBuf(ibuf); - to = (unsigned char *) ibuf->rect; - } + DitherContext *di; + int i; - if(channels==1) { - for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof++) - to[1]= to[2]= to[3]= to[0] = FTOCHAR(tof[0]); - } - else if (profile == IB_PROFILE_LINEAR_RGB) { - if(channels == 3) { - for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof+=3) { - srgb[0]= linearrgb_to_srgb(tof[0]); - srgb[1]= linearrgb_to_srgb(tof[1]); - srgb[2]= linearrgb_to_srgb(tof[2]); - - to[0] = FTOCHAR(srgb[0]); - to[1] = FTOCHAR(srgb[1]); - to[2] = FTOCHAR(srgb[2]); - to[3] = 255; - } - } - else if (channels == 4) { - if (dither != 0.f) { - for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof+=4) { - const float d = (BLI_frand()-0.5f)*dither; - - srgb[0]= d + linearrgb_to_srgb(tof[0]); - srgb[1]= d + linearrgb_to_srgb(tof[1]); - srgb[2]= d + linearrgb_to_srgb(tof[2]); - srgb[3]= d + tof[3]; - - to[0] = FTOCHAR(srgb[0]); - to[1] = FTOCHAR(srgb[1]); - to[2] = FTOCHAR(srgb[2]); - to[3] = FTOCHAR(srgb[3]); - } - } else { - floatbuf_to_srgb_byte(tof, to, 0, ibuf->x, 0, ibuf->y, ibuf->x); + di= MEM_callocN(sizeof(DitherContext), "dithering context"); + di->f= factor / 16.0f; + di->error_buf= MEM_callocN(4*(w+1)*sizeof(int), "dithering error"); + di->e= di->error_buf; + + for(i=0; i<4; ++i) + di->v[i]= di->v0[i]= di->v1[i]= 1024.0f*(BLI_frand()-0.5f); + + return di; +} + +static void clear_dither_context(DitherContext *di) +{ + MEM_freeN(di->error_buf); + MEM_freeN(di); +} + +static void dither_finish_row(DitherContext *di) +{ + int i; + + for(i=0; i<4; i++) + di->v[i]= di->v0[i]= di->v1[i] = 0; + + di->e= di->error_buf; +} + +MINLINE unsigned char dither_value(unsigned short v_in, DitherContext *di, int i) +{ + int dv, d2; + unsigned char v_out; + + di->v[i] = v_in + (2*di->v[i] + di->e[4]) * di->f; + CLAMP(di->v[i], 0, 0xFF00); + v_out = USHORTTOUCHAR(di->v[i]); + di->v[i] -= v_out<<8; + dv = di->v[i]; + d2 = di->v[i]<<1; + di->v[i] += d2; + *(di->e++) = di->v[i] + di->v0[i]; + di->v[i] += d2; + + di->v0[i] = di->v[i] + di->v1[i]; + di->v1[i] = dv; + di->v[i] += d2; + + return v_out; +} + +/************************* Generic Buffer Conversion *************************/ + +MINLINE void ushort_to_byte_v4(uchar b[4], const unsigned short us[4]) +{ + b[0]= USHORTTOUCHAR(us[0]); + b[1]= USHORTTOUCHAR(us[1]); + b[2]= USHORTTOUCHAR(us[2]); + b[3]= USHORTTOUCHAR(us[3]); +} + +MINLINE void ushort_to_byte_dither_v4(uchar b[4], const unsigned short us[4], DitherContext *di) +{ + b[0]= dither_value(us[0], di, 0); + b[1]= dither_value(us[1], di, 1); + b[2]= dither_value(us[2], di, 2); + b[3]= dither_value(us[3], di, 3); +} + +MINLINE void float_to_byte_dither_v4(uchar b[4], const float f[4], DitherContext *di) +{ + unsigned short us[4] = {FTOUSHORT(f[0]), FTOUSHORT(f[1]), FTOUSHORT(f[2]), FTOUSHORT(f[3])}; + ushort_to_byte_dither_v4(b, us, di); +} + +/* float to byte pixels, output 4-channel RGBA */ +void IMB_buffer_byte_from_float(uchar *rect_to, const float *rect_from, + int channels_from, float dither, int profile_to, int profile_from, int predivide, + int width, int height, int stride_to, int stride_from) +{ + float tmp[4]; + int x, y; + DitherContext *di; + + /* we need valid profiles */ + BLI_assert(profile_to != IB_PROFILE_NONE); + BLI_assert(profile_from != IB_PROFILE_NONE); + + BLI_init_srgb_conversion(); + if(dither) + di= create_dither_context(width, dither); + + for(y = 0; y < height; y++) { + if(channels_from == 1) { + /* single channel input */ + const float *from = rect_from + stride_from*y; + uchar *to = rect_to + stride_to*y*4; + + for(x = 0; x < width; x++, from++, to+=4) + to[0] = to[1] = to[2] = to[3] = FTOCHAR(from[0]); + } + else if(channels_from == 3) { + /* RGB input */ + const float *from = rect_from + stride_from*y*3; + uchar *to = rect_to + stride_to*y*4; + + if(profile_to == profile_from) { + /* no color space conversion */ + for(x = 0; x < width; x++, from+=3, to+=4) { + rgb_float_to_uchar(to, from); + to[3] = 255; + } + } + else if(profile_to == IB_PROFILE_SRGB) { + /* convert from linear to sRGB */ + for(x = 0; x < width; x++, from+=3, to+=4) { + linearrgb_to_srgb_v3_v3(tmp, from); + rgb_float_to_uchar(to, tmp); + to[3] = 255; + } + } + else if(profile_to == IB_PROFILE_LINEAR_RGB) { + /* convert from sRGB to linear */ + for(x = 0; x < width; x++, from+=3, to+=4) { + srgb_to_linearrgb_v3_v3(tmp, from); + rgb_float_to_uchar(to, tmp); + to[3] = 255; + } + } + } + else if(channels_from == 4) { + /* RGBA input */ + const float *from = rect_from + stride_from*y*4; + uchar *to = rect_to + stride_to*y*4; + + if(profile_to == profile_from) { + /* no color space conversion */ + if(dither) { + for(x = 0; x < width; x++, from+=4, to+=4) + float_to_byte_dither_v4(to, from, di); + } + else { + for(x = 0; x < width; x++, from+=4, to+=4) + rgba_float_to_uchar(to, from); + } + } + else if(profile_to == IB_PROFILE_SRGB) { + /* convert from linear to sRGB */ + unsigned short us[4]; + + if(dither && predivide) { + for(x = 0; x < width; x++, from+=4, to+=4) { + linearrgb_to_srgb_ushort4_predivide(us, from); + ushort_to_byte_dither_v4(to, us, di); + } + } + else if(dither) { + for(x = 0; x < width; x++, from+=4, to+=4) { + linearrgb_to_srgb_ushort4(us, from); + ushort_to_byte_dither_v4(to, us, di); + } + } + else if(predivide) { + for(x = 0; x < width; x++, from+=4, to+=4) { + linearrgb_to_srgb_ushort4_predivide(us, from); + ushort_to_byte_v4(to, us); + } + } + else { + for(x = 0; x < width; x++, from+=4, to+=4) { + linearrgb_to_srgb_ushort4(us, from); + ushort_to_byte_v4(to, us); + } + } + } + else if(profile_to == IB_PROFILE_LINEAR_RGB) { + /* convert from sRGB to linear */ + if(dither && predivide) { + for(x = 0; x < width; x++, from+=4, to+=4) { + srgb_to_linearrgb_predivide_v4(tmp, from); + float_to_byte_dither_v4(to, tmp, di); + } + } + else if(dither) { + for(x = 0; x < width; x++, from+=4, to+=4) { + srgb_to_linearrgb_v4(tmp, from); + float_to_byte_dither_v4(to, tmp, di); + } + } + else if(predivide) { + for(x = 0; x < width; x++, from+=4, to+=4) { + srgb_to_linearrgb_predivide_v4(tmp, from); + rgba_float_to_uchar(to, tmp); + } + } + else { + for(x = 0; x < width; x++, from+=4, to+=4) { + srgb_to_linearrgb_v4(tmp, from); + rgba_float_to_uchar(to, tmp); + } + } } } + + if(dither) + dither_finish_row(di); } - else if(ELEM(profile, IB_PROFILE_NONE, IB_PROFILE_SRGB)) { - if(channels==3) { - for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof+=3) { - to[0] = FTOCHAR(tof[0]); - to[1] = FTOCHAR(tof[1]); - to[2] = FTOCHAR(tof[2]); - to[3] = 255; + + if(dither) + clear_dither_context(di); +} + +/* byte to float pixels, input and output 4-channel RGBA */ +void IMB_buffer_float_from_byte(float *rect_to, const uchar *rect_from, + int profile_to, int profile_from, int predivide, + int width, int height, int stride_to, int stride_from) +{ + float tmp[4]; + int x, y; + + /* we need valid profiles */ + BLI_assert(profile_to != IB_PROFILE_NONE); + BLI_assert(profile_from != IB_PROFILE_NONE); + + BLI_init_srgb_conversion(); + + /* RGBA input */ + for(y = 0; y < height; y++) { + const uchar *from = rect_from + stride_from*y*4; + float *to = rect_to + stride_to*y*4; + + if(profile_to == profile_from) { + /* no color space conversion */ + for(x = 0; x < width; x++, from+=4, to+=4) + rgba_uchar_to_float(to, from); + } + else if(profile_to == IB_PROFILE_LINEAR_RGB) { + /* convert sRGB to linear */ + if(predivide) { + for(x = 0; x < width; x++, from+=4, to+=4) { + srgb_to_linearrgb_uchar4_predivide(to, from); + } + } + else { + for(x = 0; x < width; x++, from+=4, to+=4) { + srgb_to_linearrgb_uchar4(to, from); + } } } - else { - if (dither != 0.f) { - for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof+=4) { - const float d = (BLI_frand()-0.5f)*dither; - float col[4]; - - col[0]= d + tof[0]; - col[1]= d + tof[1]; - col[2]= d + tof[2]; - col[3]= d + tof[3]; - - to[0] = FTOCHAR(col[0]); - to[1] = FTOCHAR(col[1]); - to[2] = FTOCHAR(col[2]); - to[3] = FTOCHAR(col[3]); - } - } else { - for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof+=4) { - to[0] = FTOCHAR(tof[0]); - to[1] = FTOCHAR(tof[1]); - to[2] = FTOCHAR(tof[2]); - to[3] = FTOCHAR(tof[3]); + else if(profile_to == IB_PROFILE_SRGB) { + /* convert linear to sRGB */ + if(predivide) { + for(x = 0; x < width; x++, from+=4, to+=4) { + rgba_uchar_to_float(tmp, from); + linearrgb_to_srgb_predivide_v4(to, tmp); + } + } + else { + for(x = 0; x < width; x++, from+=4, to+=4) { + rgba_uchar_to_float(tmp, from); + linearrgb_to_srgb_v4(to, tmp); } } } } - /* ensure user flag is reset */ - ibuf->userflags &= ~IB_RECT_INVALID; } - - -/* converts from linear float to sRGB byte for part of the texture, buffer will hold the changed part */ -void IMB_partial_rect_from_float(struct ImBuf *ibuf,float *buffer, int x, int y, int w, int h) +/* float to float pixels, output 4-channel RGBA */ +void IMB_buffer_float_from_float(float *rect_to, const float *rect_from, + int channels_from, int profile_to, int profile_from, int predivide, + int width, int height, int stride_to, int stride_from) { - /* indices to source and destination image pixels */ - float *srcFloatPxl; - unsigned char *dstBytePxl; - /* buffer index will fill buffer */ - float *bufferIndex; - - /* convenience pointers to start of image buffers */ - float *init_srcFloatPxl = (float *)ibuf->rect_float; - unsigned char *init_dstBytePxl = (unsigned char *) ibuf->rect; - - /* Dithering factor */ - float dither= ibuf->dither / 255.0f; - /* respective attributes of image */ - short profile= ibuf->profile; - int channels= ibuf->channels; - - int i, j; - - /* - if called -only- from GPU_paint_update_image this test will never fail - but leaving it here for better or worse - */ - if(init_srcFloatPxl==NULL || (buffer == NULL)){ - return; - } - if(init_dstBytePxl==NULL) { - imb_addrectImBuf(ibuf); - init_dstBytePxl = (unsigned char *) ibuf->rect; + int x, y; + + /* we need valid profiles */ + BLI_assert(profile_to != IB_PROFILE_NONE); + BLI_assert(profile_from != IB_PROFILE_NONE); + + if(channels_from==1) { + /* single channel input */ + for(y = 0; y < height; y++) { + const float *from = rect_from + stride_from*y; + float *to = rect_to + stride_to*y*4; + + for(x = 0; x < width; x++, from++, to+=4) + to[0] = to[1] = to[2] = to[3] = from[0]; + } } - if(channels==1) { - for (j = 0; j < h; j++){ - bufferIndex = buffer + w*j*4; - dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4; - srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x); - for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl++, bufferIndex+=4) { - dstBytePxl[1]= dstBytePxl[2]= dstBytePxl[3]= dstBytePxl[0] = FTOCHAR(srcFloatPxl[0]); - bufferIndex[0] = bufferIndex[1] = bufferIndex[2] = bufferIndex[3] = srcFloatPxl[0]; + else if(channels_from == 3) { + /* RGB input */ + for(y = 0; y < height; y++) { + const float *from = rect_from + stride_from*y*3; + float *to = rect_to + stride_to*y*4; + + if(profile_to == profile_from) { + /* no color space conversion */ + for(x = 0; x < width; x++, from+=3, to+=4) { + copy_v3_v3(to, from); + to[3] = 1.0f; } } - } - else if (profile == IB_PROFILE_LINEAR_RGB) { - if(channels == 3) { - for (j = 0; j < h; j++){ - bufferIndex = buffer + w*j*4; - dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4; - srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*3; - for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl+=3, bufferIndex += 4) { - linearrgb_to_srgb_v3_v3(bufferIndex, srcFloatPxl); - F3TOCHAR4(bufferIndex, dstBytePxl); - bufferIndex[3]= 1.0; + else if(profile_to == IB_PROFILE_LINEAR_RGB) { + /* convert from sRGB to linear */ + for(x = 0; x < width; x++, from+=3, to+=4) { + srgb_to_linearrgb_v3_v3(to, from); + to[3] = 1.0f; + } + } + else if(profile_to == IB_PROFILE_SRGB) { + /* convert from linear to sRGB */ + for(x = 0; x < width; x++, from+=3, to+=4) { + linearrgb_to_srgb_v3_v3(to, from); + to[3] = 1.0f; } } } - else if (channels == 4) { - if (dither != 0.f) { - for (j = 0; j < h; j++){ - bufferIndex = buffer + w*j*4; - dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4; - srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*4; - for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl+=4, bufferIndex+=4) { - const float d = (BLI_frand()-0.5f)*dither; - linearrgb_to_srgb_v3_v3(bufferIndex, srcFloatPxl); - bufferIndex[3] = srcFloatPxl[3]; - add_v4_fl(bufferIndex, d); - F4TOCHAR4(bufferIndex, dstBytePxl); - } + } + else if(channels_from == 4) { + /* RGBA input */ + for(y = 0; y < height; y++) { + const float *from = rect_from + stride_from*y*4; + float *to = rect_to + stride_to*y*4; + + if(profile_to == profile_from) { + /* same profile, copy */ + memcpy(to, from, sizeof(float)*4*width); + } + else if(profile_to == IB_PROFILE_LINEAR_RGB) { + /* convert to sRGB to linear */ + if(predivide) { + for(x = 0; x < width; x++, from+=4, to+=4) + srgb_to_linearrgb_predivide_v4(to, from); } - } else { - for (j = 0; j < h; j++){ - bufferIndex = buffer + w*j*4; - dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4; - srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*4; - for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl+=4, bufferIndex+=4) { - linearrgb_to_srgb_v3_v3(bufferIndex, srcFloatPxl); - bufferIndex[3]= srcFloatPxl[3]; - F4TOCHAR4(bufferIndex, dstBytePxl); - } + else { + for(x = 0; x < width; x++, from+=4, to+=4) + srgb_to_linearrgb_v4(to, from); + } + } + else if(profile_to == IB_PROFILE_SRGB) { + /* convert from linear to sRGB */ + if(predivide) { + for(x = 0; x < width; x++, from+=4, to+=4) + linearrgb_to_srgb_predivide_v4(to, from); + } + else { + for(x = 0; x < width; x++, from+=4, to+=4) + linearrgb_to_srgb_v4(to, from); } } } } - else if(ELEM(profile, IB_PROFILE_NONE, IB_PROFILE_SRGB)) { - if(channels==3) { - for (j = 0; j < h; j++){ - bufferIndex = buffer + w*j*4; - dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4; - srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*3; - for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl+=3, bufferIndex+=4) { - copy_v3_v3(bufferIndex, srcFloatPxl); - F3TOCHAR4(bufferIndex, dstBytePxl); - bufferIndex[3] = 1.0; +} + +/* byte to byte pixels, input and output 4-channel RGBA */ +void IMB_buffer_byte_from_byte(uchar *rect_to, const uchar *rect_from, + int profile_to, int profile_from, int predivide, + int width, int height, int stride_to, int stride_from) +{ + float tmp[4]; + int x, y; + + /* we need valid profiles */ + BLI_assert(profile_to != IB_PROFILE_NONE); + BLI_assert(profile_from != IB_PROFILE_NONE); + + /* always RGBA input */ + for(y = 0; y < height; y++) { + const uchar *from = rect_from + stride_from*y*4; + uchar *to = rect_to + stride_to*y*4; + + if(profile_to == profile_from) { + /* same profile, copy */ + memcpy(to, from, sizeof(uchar)*4*width); + } + else if(profile_to == IB_PROFILE_LINEAR_RGB) { + /* convert to sRGB to linear */ + if(predivide) { + for(x = 0; x < width; x++, from+=4, to+=4) { + rgba_uchar_to_float(tmp, from); + srgb_to_linearrgb_predivide_v4(tmp, tmp); + rgba_float_to_uchar(to, tmp); + } + } + else { + for(x = 0; x < width; x++, from+=4, to+=4) { + rgba_uchar_to_float(tmp, from); + srgb_to_linearrgb_v4(tmp, tmp); + rgba_float_to_uchar(to, tmp); } } } - else { - if (dither != 0.f) { - for (j = 0; j < h; j++){ - bufferIndex = buffer + w*j*4; - dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4; - srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*4; - for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl+=4, bufferIndex+=4) { - const float d = (BLI_frand()-0.5f)*dither; - copy_v4_v4(bufferIndex, srcFloatPxl); - add_v4_fl(bufferIndex,d); - F4TOCHAR4(bufferIndex, dstBytePxl); - } + else if(profile_to == IB_PROFILE_SRGB) { + /* convert from linear to sRGB */ + if(predivide) { + for(x = 0; x < width; x++, from+=4, to+=4) { + rgba_uchar_to_float(tmp, from); + linearrgb_to_srgb_predivide_v4(tmp, tmp); + rgba_float_to_uchar(to, tmp); } - } else { - for (j = 0; j < h; j++){ - bufferIndex = buffer + w*j*4; - dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4; - srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*4; - for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl+=4, bufferIndex+=4) { - copy_v4_v4(bufferIndex, srcFloatPxl); - F4TOCHAR4(bufferIndex, dstBytePxl); - } + } + else { + for(x = 0; x < width; x++, from+=4, to+=4) { + rgba_uchar_to_float(tmp, from); + linearrgb_to_srgb_v4(tmp, tmp); + rgba_float_to_uchar(to, tmp); } } } } +} + +/****************************** ImBuf Conversion *****************************/ + +void IMB_rect_from_float(ImBuf *ibuf) +{ + int predivide= (ibuf->flags & IB_cm_predivide); + int profile_from; + + /* verify we have a float buffer */ + if(ibuf->rect_float==NULL) + return; + + /* create byte rect if it didn't exist yet */ + if(ibuf->rect==NULL) + imb_addrectImBuf(ibuf); + + /* determine profiles */ + if(ibuf->profile == IB_PROFILE_LINEAR_RGB) + profile_from = IB_PROFILE_LINEAR_RGB; + else if(ELEM(ibuf->profile, IB_PROFILE_SRGB, IB_PROFILE_NONE)) + profile_from = IB_PROFILE_SRGB; + else + BLI_assert(0); + + /* do conversion */ + IMB_buffer_byte_from_float((uchar*)ibuf->rect, ibuf->rect_float, + ibuf->channels, ibuf->dither, IB_PROFILE_SRGB, profile_from, predivide, + ibuf->x, ibuf->y, ibuf->x, ibuf->x); + /* ensure user flag is reset */ ibuf->userflags &= ~IB_RECT_INVALID; } -static void imb_float_from_rect_nonlinear(struct ImBuf *ibuf, float *fbuf) +/* converts from linear float to sRGB byte for part of the texture, buffer will hold the changed part */ +void IMB_partial_rect_from_float(ImBuf *ibuf, float *buffer, int x, int y, int w, int h) { - float *tof = fbuf; - int i; - unsigned char *to = (unsigned char *) ibuf->rect; + float *rect_float; + uchar *rect_byte; + int predivide= (ibuf->flags & IB_cm_predivide); + int profile_from; - for (i = ibuf->x * ibuf->y; i > 0; i--) - { - tof[0] = ((float)to[0])*(1.0f/255.0f); - tof[1] = ((float)to[1])*(1.0f/255.0f); - tof[2] = ((float)to[2])*(1.0f/255.0f); - tof[3] = ((float)to[3])*(1.0f/255.0f); - to += 4; - tof += 4; - } -} + /* verify we have a float buffer */ + if(ibuf->rect_float==NULL || buffer==NULL) + return; + /* create byte rect if it didn't exist yet */ + if(ibuf->rect==NULL) + imb_addrectImBuf(ibuf); -static void imb_float_from_rect_linear(struct ImBuf *ibuf, float *fbuf) -{ - float *tof = fbuf; - int i; - unsigned char *to = (unsigned char *) ibuf->rect; + /* determine profiles */ + if(ibuf->profile == IB_PROFILE_LINEAR_RGB) + profile_from = IB_PROFILE_LINEAR_RGB; + else if(ELEM(ibuf->profile, IB_PROFILE_SRGB, IB_PROFILE_NONE)) + profile_from = IB_PROFILE_SRGB; + else + BLI_assert(0); + + /* do conversion */ + rect_float= ibuf->rect_float + (x + y*ibuf->x)*ibuf->channels; + rect_byte= (uchar*)ibuf->rect + (x + y*ibuf->x)*4; + + IMB_buffer_float_from_float(buffer, rect_float, + ibuf->channels, IB_PROFILE_SRGB, profile_from, predivide, + w, h, w, ibuf->x); + + IMB_buffer_byte_from_float(rect_byte, buffer, + 4, ibuf->dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB, 0, + w, h, ibuf->x, w); - for (i = ibuf->x * ibuf->y; i > 0; i--) - { - tof[0] = srgb_to_linearrgb(((float)to[0])*(1.0f/255.0f)); - tof[1] = srgb_to_linearrgb(((float)to[1])*(1.0f/255.0f)); - tof[2] = srgb_to_linearrgb(((float)to[2])*(1.0f/255.0f)); - tof[3] = ((float)to[3])*(1.0f/255.0f); - to += 4; - tof += 4; - } + /* ensure user flag is reset */ + ibuf->userflags &= ~IB_RECT_INVALID; } -void IMB_float_from_rect(struct ImBuf *ibuf) +void IMB_float_from_rect(ImBuf *ibuf) { - /* quick method to convert byte to floatbuf */ - if(ibuf->rect==NULL) return; - if(ibuf->rect_float==NULL) { - if (imb_addrectfloatImBuf(ibuf) == 0) return; - } - - /* Float bufs should be stored linear */ + int predivide= (ibuf->flags & IB_cm_predivide); + int profile_from; - if (ibuf->profile != IB_PROFILE_NONE) { - /* if the image has been given a profile then we're working - * with color management in mind, so convert it to linear space */ - imb_float_from_rect_linear(ibuf, ibuf->rect_float); - } else { - imb_float_from_rect_nonlinear(ibuf, ibuf->rect_float); - } + /* verify if we byte and float buffers */ + if(ibuf->rect==NULL) + return; + + if(ibuf->rect_float==NULL) + if(imb_addrectfloatImBuf(ibuf) == 0) + return; + + /* determine profiles */ + if(ibuf->profile == IB_PROFILE_NONE) + profile_from = IB_PROFILE_LINEAR_RGB; + else + profile_from = IB_PROFILE_SRGB; + + /* do conversion */ + IMB_buffer_float_from_byte(ibuf->rect_float, (uchar*)ibuf->rect, + IB_PROFILE_LINEAR_RGB, profile_from, predivide, + ibuf->x, ibuf->y, ibuf->x, ibuf->x); } /* no profile conversion */ -void IMB_float_from_rect_simple(struct ImBuf *ibuf) +void IMB_float_from_rect_simple(ImBuf *ibuf) { + int predivide= (ibuf->flags & IB_cm_predivide); + if(ibuf->rect_float==NULL) imb_addrectfloatImBuf(ibuf); - imb_float_from_rect_nonlinear(ibuf, ibuf->rect_float); + + IMB_buffer_float_from_byte(ibuf->rect_float, (uchar*)ibuf->rect, + IB_PROFILE_SRGB, IB_PROFILE_SRGB, predivide, + ibuf->x, ibuf->y, ibuf->x, ibuf->x); } -void IMB_convert_profile(struct ImBuf *ibuf, int profile) +void IMB_convert_profile(ImBuf *ibuf, int profile) { - int ok= FALSE; - int i; - - unsigned char *rct= (unsigned char *)ibuf->rect; - float *rctf= ibuf->rect_float; + int predivide= (ibuf->flags & IB_cm_predivide); + int profile_from, profile_to; if(ibuf->profile == profile) return; - if(ELEM(ibuf->profile, IB_PROFILE_NONE, IB_PROFILE_SRGB)) { /* from */ - if(profile == IB_PROFILE_LINEAR_RGB) { /* to */ - if(ibuf->rect_float) { - for (i = ibuf->x * ibuf->y; i > 0; i--, rctf+=4) { - rctf[0]= srgb_to_linearrgb(rctf[0]); - rctf[1]= srgb_to_linearrgb(rctf[1]); - rctf[2]= srgb_to_linearrgb(rctf[2]); - } - } - if(ibuf->rect) { - for (i = ibuf->x * ibuf->y; i > 0; i--, rct+=4) { - rct[0]= (unsigned char)((srgb_to_linearrgb((float)rct[0]/255.0f) * 255.0f) + 0.5f); - rct[1]= (unsigned char)((srgb_to_linearrgb((float)rct[1]/255.0f) * 255.0f) + 0.5f); - rct[2]= (unsigned char)((srgb_to_linearrgb((float)rct[2]/255.0f) * 255.0f) + 0.5f); - } - } - ok= TRUE; - } + /* determine profiles */ + if(ibuf->profile == IB_PROFILE_LINEAR_RGB) + profile_from = IB_PROFILE_LINEAR_RGB; + else if(ELEM(ibuf->profile, IB_PROFILE_SRGB, IB_PROFILE_NONE)) + profile_from = IB_PROFILE_SRGB; + else { + BLI_assert(0); + profile_from = IB_PROFILE_SRGB; /* dummy, should never happen */ } - else if (ibuf->profile == IB_PROFILE_LINEAR_RGB) { /* from */ - if(ELEM(profile, IB_PROFILE_NONE, IB_PROFILE_SRGB)) { /* to */ - if(ibuf->rect_float) { - for (i = ibuf->x * ibuf->y; i > 0; i--, rctf+=4) { - rctf[0]= linearrgb_to_srgb(rctf[0]); - rctf[1]= linearrgb_to_srgb(rctf[1]); - rctf[2]= linearrgb_to_srgb(rctf[2]); - } - } - if(ibuf->rect) { - for (i = ibuf->x * ibuf->y; i > 0; i--, rct+=4) { - rct[0]= (unsigned char)((linearrgb_to_srgb((float)rct[0]/255.0f) * 255.0f) + 0.5f); - rct[1]= (unsigned char)((linearrgb_to_srgb((float)rct[1]/255.0f) * 255.0f) + 0.5f); - rct[2]= (unsigned char)((linearrgb_to_srgb((float)rct[2]/255.0f) * 255.0f) + 0.5f); - } - } - ok= TRUE; - } + + if(profile == IB_PROFILE_LINEAR_RGB) + profile_to = IB_PROFILE_LINEAR_RGB; + else if(ELEM(profile, IB_PROFILE_SRGB, IB_PROFILE_NONE)) + profile_to = IB_PROFILE_SRGB; + else { + BLI_assert(0); + profile_to = IB_PROFILE_SRGB; /* dummy, should never happen */ + } + + /* do conversion */ + if(ibuf->rect_float) { + IMB_buffer_float_from_float(ibuf->rect_float, ibuf->rect_float, + 4, profile_to, profile_from, predivide, + ibuf->x, ibuf->y, ibuf->x, ibuf->x); } - if(ok==FALSE){ - printf("IMB_convert_profile: failed profile conversion %d -> %d\n", ibuf->profile, profile); - return; + if(ibuf->rect) { + IMB_buffer_byte_from_byte((uchar*)ibuf->rect, (uchar*)ibuf->rect, + profile_to, profile_from, predivide, + ibuf->x, ibuf->y, ibuf->x, ibuf->x); } + /* set new profile */ ibuf->profile= profile; } /* use when you need to get a buffer with a certain profile * if the return */ -float *IMB_float_profile_ensure(struct ImBuf *ibuf, int profile, int *alloc) +float *IMB_float_profile_ensure(ImBuf *ibuf, int profile, int *alloc) { - /* stupid but it works like this everywhere now */ - const short is_lin_from= (ibuf->profile != IB_PROFILE_NONE); - const short is_lin_to= (profile != IB_PROFILE_NONE); + int predivide= (ibuf->flags & IB_cm_predivide); + int profile_from, profile_to; + /* determine profiles */ + if(ibuf->profile == IB_PROFILE_NONE) + profile_from = IB_PROFILE_LINEAR_RGB; + else + profile_from = IB_PROFILE_SRGB; + + if(profile == IB_PROFILE_NONE) + profile_to = IB_PROFILE_LINEAR_RGB; + else + profile_to = IB_PROFILE_SRGB; - if(is_lin_from == is_lin_to) { + if(profile_from == profile_to) { + /* simple case, just allocate the buffer and return */ *alloc= 0; - /* simple case, just allocate the buffer and return */ - if(ibuf->rect_float == NULL) { + if(ibuf->rect_float == NULL) IMB_float_from_rect(ibuf); - } return ibuf->rect_float; } @@ -469,42 +709,43 @@ *alloc= 1; if(ibuf->rect_float == NULL) { - if(is_lin_to) { - imb_float_from_rect_linear(ibuf, fbuf); - } - else { - imb_float_from_rect_nonlinear(ibuf, fbuf); - } + IMB_buffer_float_from_byte(fbuf, (uchar*)ibuf->rect, + profile_to, profile_from, predivide, + ibuf->x, ibuf->y, ibuf->x, ibuf->x); } else { - if(is_lin_to) { /* lin -> nonlin */ - linearrgb_to_srgb_rgba_rgba_buf(fbuf, ibuf->rect_float, ibuf->x * ibuf->y); - } - else { /* nonlin -> lin */ - srgb_to_linearrgb_rgba_rgba_buf(fbuf, ibuf->rect_float, ibuf->x * ibuf->y); - } + IMB_buffer_float_from_float(fbuf, ibuf->rect_float, + 4, profile_to, profile_from, predivide, + ibuf->x, ibuf->y, ibuf->x, ibuf->x); } return fbuf; } } +/**************************** Color to Grayscale *****************************/ /* no profile conversion */ -void IMB_color_to_bw(struct ImBuf *ibuf) +void IMB_color_to_bw(ImBuf *ibuf) { float *rctf= ibuf->rect_float; - unsigned char *rct= (unsigned char *)ibuf->rect; + uchar *rct= (uchar*)ibuf->rect; int i; + if(rctf) { - for (i = ibuf->x * ibuf->y; i > 0; i--, rctf+=4) { + for(i = ibuf->x * ibuf->y; i > 0; i--, rctf+=4) rctf[0]= rctf[1]= rctf[2]= rgb_to_grayscale(rctf); - } } if(rct) { - for (i = ibuf->x * ibuf->y; i > 0; i--, rct+=4) { + for(i = ibuf->x * ibuf->y; i > 0; i--, rct+=4) rct[0]= rct[1]= rct[2]= rgb_to_grayscale_byte(rct); - } + } +} + +void IMB_buffer_float_clamp(float *buf, int width, int height){ + int i, total = width*height*4; + for(i = 0; i < total; i++){ + buf[i] = MIN2(1.0, buf[i]); } } diff -Nru blender-2.61/source/blender/imbuf/intern/IMB_anim.h blender-2.62/source/blender/imbuf/intern/IMB_anim.h --- blender-2.61/source/blender/imbuf/intern/IMB_anim.h 2011-12-13 19:50:45.000000000 +0000 +++ blender-2.62/source/blender/imbuf/intern/IMB_anim.h 2012-02-15 19:35:32.000000000 +0000 @@ -136,9 +136,9 @@ int x, y; /* voor op nummer */ - char name[256]; + char name[1024]; /* voor sequence */ - char first[256]; + char first[1024]; /* movie */ void *movie; @@ -189,7 +189,7 @@ struct redcode_handle * redcodeCtx; #endif - char index_dir[256]; + char index_dir[768]; int proxies_tried; int indices_tried; diff -Nru blender-2.61/source/blender/imbuf/intern/IMB_indexer.h blender-2.62/source/blender/imbuf/intern/IMB_indexer.h --- blender-2.61/source/blender/imbuf/intern/IMB_indexer.h 2011-12-13 19:50:45.000000000 +0000 +++ blender-2.62/source/blender/imbuf/intern/IMB_indexer.h 2012-02-15 19:35:32.000000000 +0000 @@ -62,7 +62,7 @@ } anim_index_entry; struct anim_index { - char name[256]; + char name[1024]; int num_entries; struct anim_index_entry * entries; diff -Nru blender-2.61/source/blender/imbuf/intern/indexer.c blender-2.62/source/blender/imbuf/intern/indexer.c --- blender-2.61/source/blender/imbuf/intern/indexer.c 2011-12-13 19:50:45.000000000 +0000 +++ blender-2.62/source/blender/imbuf/intern/indexer.c 2012-02-15 19:35:32.000000000 +0000 @@ -52,8 +52,11 @@ static float proxy_fac[] = { 0.25, 0.50, 0.75, 1.00 }; #ifdef WITH_FFMPEG -static int tc_types[] = { IMB_TC_RECORD_RUN, IMB_TC_FREE_RUN, - IMB_TC_INTERPOLATED_REC_DATE_FREE_RUN }; +static int tc_types[] = { IMB_TC_RECORD_RUN, + IMB_TC_FREE_RUN, + IMB_TC_INTERPOLATED_REC_DATE_FREE_RUN, + IMB_TC_RECORD_RUN_NO_GAPS, + }; #endif #define INDEX_FILE_VERSION 1 @@ -102,7 +105,7 @@ } void IMB_index_builder_add_entry(anim_index_builder * fp, - int frameno,unsigned long long seek_pos, + int frameno, unsigned long long seek_pos, unsigned long long seek_pos_dts, unsigned long long pts) { @@ -344,6 +347,8 @@ return 1; case IMB_TC_INTERPOLATED_REC_DATE_FREE_RUN: return 2; + case IMB_TC_RECORD_RUN_NO_GAPS: + return 3; default: return 0; }; @@ -381,12 +386,12 @@ stream_suffix[0] = 0; if (anim->streamindex > 0) { - BLI_snprintf(stream_suffix, 20, "_st%d", anim->streamindex); + BLI_snprintf(stream_suffix, sizeof(stream_suffix), "_st%d", anim->streamindex); } - BLI_snprintf(proxy_name, 256, "proxy_%d%s.avi", + BLI_snprintf(proxy_name, sizeof(proxy_name), "proxy_%d%s.avi", (int) (proxy_fac[i] * 100), stream_suffix); - BLI_snprintf(proxy_temp_name, 256, "proxy_%d%s_part.avi", + BLI_snprintf(proxy_temp_name, sizeof(proxy_temp_name), "proxy_%d%s_part.avi", (int) (proxy_fac[i] * 100), stream_suffix); get_index_dir(anim, index_dir); @@ -401,8 +406,10 @@ char index_dir[FILE_MAXDIR]; int i = IMB_timecode_to_array_index(tc); const char * index_names[] = { - "record_run%s.blen_tc", "free_run%s.blen_tc", - "interp_free_run%s.blen_tc" }; + "record_run%s.blen_tc", + "free_run%s.blen_tc", + "interp_free_run%s.blen_tc", + "record_run_no_gaps%s.blen_tc"}; char stream_suffix[20]; char index_name[256]; @@ -696,7 +703,7 @@ unsigned long long start_pts = 0; double frame_rate; double pts_time_base; - int frameno = 0; + int frameno = 0, frameno_gapless = 0; int start_pts_set = FALSE; AVFormatContext *iFormatCtx; @@ -858,13 +865,21 @@ for (i = 0; i < num_indexers; i++) { if (tcs_in_use & tc_types[i]) { + int tc_frameno = frameno; + + if(tc_types[i] == IMB_TC_RECORD_RUN_NO_GAPS) + tc_frameno = frameno_gapless; + IMB_index_builder_proc_frame( indexer[i], next_packet.data, next_packet.size, - frameno, s_pos, s_dts, pts); + tc_frameno, + s_pos, s_dts, pts); } } + + frameno_gapless++; } av_free_packet(&next_packet); } diff -Nru blender-2.61/source/blender/imbuf/intern/jp2.c blender-2.62/source/blender/imbuf/intern/jp2.c --- blender-2.61/source/blender/imbuf/intern/jp2.c 2011-12-13 19:50:45.000000000 +0000 +++ blender-2.62/source/blender/imbuf/intern/jp2.c 2012-02-15 19:35:32.000000000 +0000 @@ -70,21 +70,24 @@ /** sample error callback expecting a FILE* client object */ -static void error_callback(const char *msg, void *client_data) { +static void error_callback(const char *msg, void *client_data) +{ FILE *stream = (FILE*)client_data; fprintf(stream, "[ERROR] %s", msg); } /** sample warning callback expecting a FILE* client object */ -static void warning_callback(const char *msg, void *client_data) { +static void warning_callback(const char *msg, void *client_data) +{ FILE *stream = (FILE*)client_data; fprintf(stream, "[WARNING] %s", msg); } /** sample debug callback expecting no client object */ -static void info_callback(const char *msg, void *client_data) { +static void info_callback(const char *msg, void *client_data) +{ (void)client_data; fprintf(stdout, "[INFO] %s", msg); } @@ -305,7 +308,8 @@ #define COMP_48_CS 520833 /*Maximum size per color component for 2K @ 48fps*/ -static int initialise_4K_poc(opj_poc_t *POC, int numres){ +static int initialise_4K_poc(opj_poc_t *POC, int numres) +{ POC[0].tile = 1; POC[0].resno0 = 0; POC[0].compno0 = 0; @@ -323,7 +327,8 @@ return 2; } -static void cinema_parameters(opj_cparameters_t *parameters){ +static void cinema_parameters(opj_cparameters_t *parameters) +{ parameters->tile_size_on = false; parameters->cp_tdx=1; parameters->cp_tdy=1; @@ -356,7 +361,8 @@ } -static void cinema_setup_encoder(opj_cparameters_t *parameters,opj_image_t *image, img_fol_t *img_fol){ +static void cinema_setup_encoder(opj_cparameters_t *parameters,opj_image_t *image, img_fol_t *img_fol) +{ int i; float temp_rate; @@ -442,8 +448,8 @@ } -static opj_image_t* ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters) { - +static opj_image_t* ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters) +{ unsigned char *rect; float *rect_float; @@ -662,8 +668,8 @@ /* Found write info at http://users.ece.gatech.edu/~slabaugh/personal/c/bitmapUnix.c */ -int imb_savejp2(struct ImBuf *ibuf, const char *name, int flags) { - +int imb_savejp2(struct ImBuf *ibuf, const char *name, int flags) +{ int quality = ibuf->ftype & 0xff; int bSuccess; diff -Nru blender-2.61/source/blender/imbuf/intern/md5.c blender-2.62/source/blender/imbuf/intern/md5.c --- blender-2.61/source/blender/imbuf/intern/md5.c 2011-12-13 19:50:45.000000000 +0000 +++ blender-2.62/source/blender/imbuf/intern/md5.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,360 +0,0 @@ -/** \file blender/imbuf/intern/md5.c - * \ingroup imbuf - */ -/* md5.c - Functions to compute MD5 message digest of files or memory blocks - according to the definition of MD5 in RFC 1321 from April 1992. - Copyright (C) 1995 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* Written by Ulrich Drepper . */ - -#include - -# include -# include - -#include "md5.h" - -#ifdef __BIG_ENDIAN__ -# define SWAP(n) \ - (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) -#else -# define SWAP(n) (n) -#endif - - -/* This array contains the bytes used to pad the buffer to the next - 64-byte boundary. (RFC 1321, 3.1: Step 1) */ -static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; - - -/* Initialize structure containing state of computation. - (RFC 1321, 3.3: Step 3) */ -void -md5_init_ctx (ctx) - struct md5_ctx *ctx; -{ - ctx->A = 0x67452301; - ctx->B = 0xefcdab89; - ctx->C = 0x98badcfe; - ctx->D = 0x10325476; -} - -/* Put result from CTX in first 16 bytes following RESBUF. The result must - be in little endian byte order. */ -void * -md5_read_ctx (ctx, resbuf) - const struct md5_ctx *ctx; - void *resbuf; -{ - ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A); - ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B); - ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C); - ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D); - - return resbuf; -} - -/* Compute MD5 message digest for bytes read from STREAM. The - resulting message digest number will be written into the 16 bytes - beginning at RESBLOCK. */ -int -md5_stream (stream, resblock) - FILE *stream; - void *resblock; -{ - /* Important: BLOCKSIZE must be a multiple of 64. */ -#define BLOCKSIZE 4096 - struct md5_ctx ctx; - md5_uint32 len[2]; - char buffer[BLOCKSIZE + 72]; - size_t pad, sum; - - /* Initialize the computation context. */ - md5_init_ctx (&ctx); - - len[0] = 0; - len[1] = 0; - - /* Iterate over full file contents. */ - while (1) - { - /* We read the file in blocks of BLOCKSIZE bytes. One call of the - computation function processes the whole buffer so that with the - next round of the loop another block can be read. */ - size_t n; - sum = 0; - - /* Read block. Take care for partial reads. */ - do - { - n = fread (buffer, 1, BLOCKSIZE - sum, stream); - - sum += n; - } - while (sum < BLOCKSIZE && n != 0); - if (n == 0 && ferror (stream)) - return 1; - - /* RFC 1321 specifies the possible length of the file up to 2^64 bits. - Here we only compute the number of bytes. Do a double word - increment. */ - len[0] += sum; - if (len[0] < sum) - ++len[1]; - - /* If end of file is reached, end the loop. */ - if (n == 0) - break; - - /* Process buffer with BLOCKSIZE bytes. Note that - BLOCKSIZE % 64 == 0 - */ - md5_process_block (buffer, BLOCKSIZE, &ctx); - } - - /* We can copy 64 byte because the buffer is always big enough. FILLBUF - contains the needed bits. */ - memcpy (&buffer[sum], fillbuf, 64); - - /* Compute amount of padding bytes needed. Alignment is done to - (N + PAD) % 64 == 56 - There is always at least one byte padded. I.e. even the alignment - is correctly aligned 64 padding bytes are added. */ - pad = sum & 63; - pad = pad >= 56 ? 64 + 56 - pad : 56 - pad; - - /* Put the 64-bit file length in *bits* at the end of the buffer. */ - *(md5_uint32 *) &buffer[sum + pad] = SWAP (len[0] << 3); - *(md5_uint32 *) &buffer[sum + pad + 4] = SWAP ((len[1] << 3) - | (len[0] >> 29)); - - /* Process last bytes. */ - md5_process_block (buffer, sum + pad + 8, &ctx); - - /* Construct result in desired memory. */ - md5_read_ctx (&ctx, resblock); - return 0; -} - -/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The - result is always in little endian byte order, so that a byte-wise - output yields to the wanted ASCII representation of the message - digest. */ -void * -md5_buffer (buffer, len, resblock) - const char *buffer; - size_t len; - void *resblock; -{ - struct md5_ctx ctx; - char restbuf[64 + 72]; - size_t blocks = len & ~63; - size_t pad, rest; - - /* Initialize the computation context. */ - md5_init_ctx (&ctx); - - /* Process whole buffer but last len % 64 bytes. */ - md5_process_block (buffer, blocks, &ctx); - - /* REST bytes are not processed yet. */ - rest = len - blocks; - /* Copy to own buffer. */ - memcpy (restbuf, &buffer[blocks], rest); - /* Append needed fill bytes at end of buffer. We can copy 64 byte - because the buffer is always big enough. */ - memcpy (&restbuf[rest], fillbuf, 64); - - /* PAD bytes are used for padding to correct alignment. Note that - always at least one byte is padded. */ - pad = rest >= 56 ? 64 + 56 - rest : 56 - rest; - - /* Put length of buffer in *bits* in last eight bytes. */ - *(md5_uint32 *) &restbuf[rest + pad] = (md5_uint32) SWAP (len << 3); - *(md5_uint32 *) &restbuf[rest + pad + 4] = (md5_uint32) SWAP (len >> 29); - - /* Process last bytes. */ - md5_process_block (restbuf, rest + pad + 8, &ctx); - - /* Put result in desired memory area. */ - return md5_read_ctx (&ctx, resblock); -} - - -/* These are the four functions used in the four steps of the MD5 algorithm - and defined in the RFC 1321. The first function is a little bit optimized - (as found in Colin Plumbs public domain implementation). */ -/* #define FF(b, c, d) ((b & c) | (~b & d)) */ -#define FF(b, c, d) (d ^ (b & (c ^ d))) -#define FG(b, c, d) FF (d, b, c) -#define FH(b, c, d) (b ^ c ^ d) -#define FI(b, c, d) (c ^ (b | ~d)) - -/* Process LEN bytes of BUFFER, accumulating context into CTX. - It is assumed that LEN % 64 == 0. */ - -void -md5_process_block (buffer, len, ctx) - const void *buffer; - size_t len; - struct md5_ctx *ctx; -{ - md5_uint32 correct_words[16]; - const md5_uint32 *words = buffer; - size_t nwords = len / sizeof (md5_uint32); - const md5_uint32 *endp = words + nwords; - md5_uint32 A = ctx->A; - md5_uint32 B = ctx->B; - md5_uint32 C = ctx->C; - md5_uint32 D = ctx->D; - - /* Process all bytes in the buffer with 64 bytes in each round of - the loop. */ - while (words < endp) - { - md5_uint32 *cwp = correct_words; - md5_uint32 A_save = A; - md5_uint32 B_save = B; - md5_uint32 C_save = C; - md5_uint32 D_save = D; - - /* First round: using the given function, the context and a constant - the next context is computed. Because the algorithms processing - unit is a 32-bit word and it is determined to work on words in - little endian byte order we perhaps have to change the byte order - before the computation. To reduce the work for the next steps - we store the swapped words in the array CORRECT_WORDS. */ - -#define OP(a, b, c, d, s, T) \ - do \ - { \ - a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \ - ++words; \ - CYCLIC (a, s); \ - a += b; \ - } \ - while (0) - - /* It is unfortunate that C does not provide an operator for - cyclic rotation. Hope the C compiler is smart enough. */ -#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s))) - - /* Before we start, one word to the strange constants. - They are defined in RFC 1321 as - - T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64 - */ - - /* Round 1. */ - OP (A, B, C, D, 7, 0xd76aa478); - OP (D, A, B, C, 12, 0xe8c7b756); - OP (C, D, A, B, 17, 0x242070db); - OP (B, C, D, A, 22, 0xc1bdceee); - OP (A, B, C, D, 7, 0xf57c0faf); - OP (D, A, B, C, 12, 0x4787c62a); - OP (C, D, A, B, 17, 0xa8304613); - OP (B, C, D, A, 22, 0xfd469501); - OP (A, B, C, D, 7, 0x698098d8); - OP (D, A, B, C, 12, 0x8b44f7af); - OP (C, D, A, B, 17, 0xffff5bb1); - OP (B, C, D, A, 22, 0x895cd7be); - OP (A, B, C, D, 7, 0x6b901122); - OP (D, A, B, C, 12, 0xfd987193); - OP (C, D, A, B, 17, 0xa679438e); - OP (B, C, D, A, 22, 0x49b40821); - - /* For the second to fourth round we have the possibly swapped words - in CORRECT_WORDS. Redefine the macro to take an additional first - argument specifying the function to use. */ -#undef OP -#define OP(f, a, b, c, d, k, s, T) \ - do \ - { \ - a += f (b, c, d) + correct_words[k] + T; \ - CYCLIC (a, s); \ - a += b; \ - } \ - while (0) - - /* Round 2. */ - OP (FG, A, B, C, D, 1, 5, 0xf61e2562); - OP (FG, D, A, B, C, 6, 9, 0xc040b340); - OP (FG, C, D, A, B, 11, 14, 0x265e5a51); - OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa); - OP (FG, A, B, C, D, 5, 5, 0xd62f105d); - OP (FG, D, A, B, C, 10, 9, 0x02441453); - OP (FG, C, D, A, B, 15, 14, 0xd8a1e681); - OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8); - OP (FG, A, B, C, D, 9, 5, 0x21e1cde6); - OP (FG, D, A, B, C, 14, 9, 0xc33707d6); - OP (FG, C, D, A, B, 3, 14, 0xf4d50d87); - OP (FG, B, C, D, A, 8, 20, 0x455a14ed); - OP (FG, A, B, C, D, 13, 5, 0xa9e3e905); - OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8); - OP (FG, C, D, A, B, 7, 14, 0x676f02d9); - OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a); - - /* Round 3. */ - OP (FH, A, B, C, D, 5, 4, 0xfffa3942); - OP (FH, D, A, B, C, 8, 11, 0x8771f681); - OP (FH, C, D, A, B, 11, 16, 0x6d9d6122); - OP (FH, B, C, D, A, 14, 23, 0xfde5380c); - OP (FH, A, B, C, D, 1, 4, 0xa4beea44); - OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9); - OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60); - OP (FH, B, C, D, A, 10, 23, 0xbebfbc70); - OP (FH, A, B, C, D, 13, 4, 0x289b7ec6); - OP (FH, D, A, B, C, 0, 11, 0xeaa127fa); - OP (FH, C, D, A, B, 3, 16, 0xd4ef3085); - OP (FH, B, C, D, A, 6, 23, 0x04881d05); - OP (FH, A, B, C, D, 9, 4, 0xd9d4d039); - OP (FH, D, A, B, C, 12, 11, 0xe6db99e5); - OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8); - OP (FH, B, C, D, A, 2, 23, 0xc4ac5665); - - /* Round 4. */ - OP (FI, A, B, C, D, 0, 6, 0xf4292244); - OP (FI, D, A, B, C, 7, 10, 0x432aff97); - OP (FI, C, D, A, B, 14, 15, 0xab9423a7); - OP (FI, B, C, D, A, 5, 21, 0xfc93a039); - OP (FI, A, B, C, D, 12, 6, 0x655b59c3); - OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92); - OP (FI, C, D, A, B, 10, 15, 0xffeff47d); - OP (FI, B, C, D, A, 1, 21, 0x85845dd1); - OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f); - OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0); - OP (FI, C, D, A, B, 6, 15, 0xa3014314); - OP (FI, B, C, D, A, 13, 21, 0x4e0811a1); - OP (FI, A, B, C, D, 4, 6, 0xf7537e82); - OP (FI, D, A, B, C, 11, 10, 0xbd3af235); - OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb); - OP (FI, B, C, D, A, 9, 21, 0xeb86d391); - - /* Add the starting values of the context. */ - A += A_save; - B += B_save; - C += C_save; - D += D_save; - } - - /* Put checksum in context given as argument. */ - ctx->A = A; - ctx->B = B; - ctx->C = C; - ctx->D = D; -} - diff -Nru blender-2.61/source/blender/imbuf/intern/md5.h blender-2.62/source/blender/imbuf/intern/md5.h --- blender-2.61/source/blender/imbuf/intern/md5.h 2011-12-13 19:50:45.000000000 +0000 +++ blender-2.62/source/blender/imbuf/intern/md5.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,119 +0,0 @@ -/** \file blender/imbuf/intern/md5.h - * \ingroup imbuf - */ -/* md5.h - Declaration of functions and data types used for MD5 sum - computing library functions. - Copyright (C) 1995 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. */ - -#ifndef _MD5_H -#define _MD5_H - -#include - -#if defined HAVE_LIMITS_H || defined _LIBC -# include -#endif - -/* The following contortions are an attempt to use the C preprocessor - to determine an unsigned integral type that is 32 bits wide. An - alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but - doing that would require that the configure script compile and *run* - the resulting executable. Locally running cross-compiled executables - is usually not possible. */ - -#if defined __STDC__ && __STDC__ -# define UINT_MAX_32_BITS 4294967295U -#else -# define UINT_MAX_32_BITS 0xFFFFFFFF -#endif - -/* If UINT_MAX isn't defined, assume it's a 32-bit type. - This should be valid for all systems GNU cares about because - that doesn't include 16-bit systems, and only modern systems - (that certainly have ) have 64+-bit integral types. */ - -#ifndef UINT_MAX -# define UINT_MAX UINT_MAX_32_BITS -#endif - -#if UINT_MAX == UINT_MAX_32_BITS - typedef unsigned int md5_uint32; -#else -# if USHRT_MAX == UINT_MAX_32_BITS - typedef unsigned short md5_uint32; -# else -# if ULONG_MAX == UINT_MAX_32_BITS - typedef unsigned long md5_uint32; -# else - /* The following line is intended to evoke an error. - Using #error is not portable enough. */ - "Cannot determine unsigned 32-bit data type." -# endif -# endif -#endif - -#undef __P -#if defined (__STDC__) && __STDC__ -#define __P(x) x -#else -#define __P(x) () -#endif - -/* Structure to save state of computation between the single steps. */ -struct md5_ctx -{ - md5_uint32 A; - md5_uint32 B; - md5_uint32 C; - md5_uint32 D; -}; - -/* - * The following three functions are build up the low level used in - * the functions `md5_stream' and `md5_buffer'. - */ - -/* Initialize structure containing state of computation. - (RFC 1321, 3.3: Step 3) */ -void md5_init_ctx __P ((struct md5_ctx *ctx)); - -/* Starting with the result of former calls of this function (or the - initialzation function update the context for the next LEN bytes - starting at BUFFER. - It is necessary that LEN is a multiple of 64!!! */ -void md5_process_block __P ((const void *buffer, size_t len, - struct md5_ctx *ctx)); - -/* Put result from CTX in first 16 bytes following RESBUF. The result is - always in little endian byte order, so that a byte-wise output yields - to the wanted ASCII representation of the message digest. */ -void *md5_read_ctx __P ((const struct md5_ctx *ctx, void *resbuf)); - - -/* Compute MD5 message digest for bytes read from STREAM. The - resulting message digest number will be written into the 16 bytes - beginning at RESBLOCK. */ -int md5_stream __P ((FILE *stream, void *resblock)); - -/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The - result is always in little endian byte order, so that a byte-wise - output yields to the wanted ASCII representation of the message - digest. */ -void *md5_buffer __P ((const char *buffer, size_t len, void *resblock)); - -#endif - diff -Nru blender-2.61/source/blender/imbuf/intern/moviecache.c blender-2.62/source/blender/imbuf/intern/moviecache.c --- blender-2.61/source/blender/imbuf/intern/moviecache.c 2011-12-13 19:50:45.000000000 +0000 +++ blender-2.62/source/blender/imbuf/intern/moviecache.c 2012-02-15 19:35:32.000000000 +0000 @@ -147,10 +147,10 @@ } /* approximate size of ImBuf in memory */ -static intptr_t IMB_get_size_in_memory(ImBuf *ibuf) +static size_t IMB_get_size_in_memory(ImBuf *ibuf) { int a; - intptr_t size= 0, channel_size= 0; + size_t size= 0, channel_size= 0; size+= sizeof(ImBuf); @@ -176,9 +176,9 @@ return size; } -static intptr_t get_item_size (void *p) +static size_t get_item_size (void *p) { - intptr_t size= sizeof(MovieCacheItem); + size_t size= sizeof(MovieCacheItem); MovieCacheItem *item= (MovieCacheItem *) p; if(item->ibuf) diff -Nru blender-2.61/source/blender/imbuf/intern/thumbs.c blender-2.62/source/blender/imbuf/intern/thumbs.c --- blender-2.61/source/blender/imbuf/intern/thumbs.c 2011-12-13 19:50:45.000000000 +0000 +++ blender-2.62/source/blender/imbuf/intern/thumbs.c 2012-02-15 19:35:32.000000000 +0000 @@ -32,17 +32,18 @@ #include -#include "BKE_utildefines.h" -#include "BLI_blenlib.h" #include "MEM_guardedalloc.h" +#include "BLI_blenlib.h" +#include "BLI_md5.h" + +#include "BKE_utildefines.h" + #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" #include "IMB_thumbs.h" #include "IMB_metadata.h" -#include "md5.h" - #include #include #include diff -Nru blender-2.61/source/blender/imbuf/intern/tiff.c blender-2.62/source/blender/imbuf/intern/tiff.c --- blender-2.61/source/blender/imbuf/intern/tiff.c 2011-12-13 19:50:45.000000000 +0000 +++ blender-2.62/source/blender/imbuf/intern/tiff.c 2012-02-15 19:35:32.000000000 +0000 @@ -541,7 +541,7 @@ } else { fprintf(stderr, - "imb_loadtiff: could not allocate memory for TIFF " \ + "imb_loadtiff: could not allocate memory for TIFF " "image.\n"); TIFFClose(image); return NULL; diff -Nru blender-2.61/source/blender/imbuf/intern/util.c blender-2.62/source/blender/imbuf/intern/util.c --- blender-2.61/source/blender/imbuf/intern/util.c 2011-12-13 19:50:45.000000000 +0000 +++ blender-2.62/source/blender/imbuf/intern/util.c 2012-02-15 19:35:32.000000000 +0000 @@ -199,12 +199,14 @@ -static int isavi (const char *name) { +static int isavi (const char *name) +{ return AVI_is_avi (name); } #ifdef WITH_QUICKTIME -static int isqtime (const char *name) { +static int isqtime (const char *name) +{ return anim_is_quicktime (name); } #endif @@ -240,7 +242,8 @@ } } -static int isffmpeg (const char *filename) { +static int isffmpeg (const char *filename) +{ AVFormatContext *pFormatCtx; unsigned int i; int videoStream; @@ -323,7 +326,8 @@ #endif -int imb_get_anim_type(const char * name) { +int imb_get_anim_type(const char * name) +{ int type; struct stat st; @@ -364,7 +368,8 @@ return(0); } -int IMB_isanim(const char *filename) { +int IMB_isanim(const char *filename) +{ int type; if(U.uiflag & USER_FILTERFILEEXTS) { diff -Nru blender-2.61/source/blender/makesdna/DNA_action_types.h blender-2.62/source/blender/makesdna/DNA_action_types.h --- blender-2.61/source/blender/makesdna/DNA_action_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_action_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -1,4 +1,4 @@ -/* +/* * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or @@ -29,7 +29,6 @@ * \ingroup DNA */ - #ifndef DNA_ACTION_TYPES_H #define DNA_ACTION_TYPES_H @@ -185,7 +184,7 @@ IDProperty *prop; /* User-Defined Properties on this PoseChannel */ ListBase constraints;/* Constraints that act on this PoseChannel */ - char name[32]; /* Channels need longer names than normal blender objects */ + char name[64]; /* need to match bone name length: MAXBONENAME */ short flag; /* dynamic, for detecting transform changes */ short ikflag; /* settings for IK bones */ @@ -204,7 +203,9 @@ bMotionPath *mpath; /* motion path cache for this bone */ struct Object *custom; /* draws custom object instead of default bone shape */ - struct bPoseChannel *custom_tx; /* odd feature, display with another bones transform. needed in rare cases for advanced rigs, since the alternative is highly complicated - campbell */ + struct bPoseChannel *custom_tx; /* odd feature, display with another bones transform. + * needed in rare cases for advanced rigs, + * since the alternative is highly complicated - campbell */ /* transforms - written in by actions or transform */ float loc[3]; @@ -219,7 +220,8 @@ float chan_mat[4][4]; /* matrix result of loc/quat/size , and where we put deform in, see next line */ float pose_mat[4][4]; /* constraints accumulate here. in the end, pose_mat = bone->arm_mat * chan_mat */ - float constinv[4][4]; /* inverse result of constraints. doesn't include effect of restposition, parent, and local transform*/ + float constinv[4][4]; /* inverse result of constraints. + * doesn't include effect of restposition, parent, and local transform*/ float pose_head[3]; /* actually pose_mat[3] */ float pose_tail[3]; /* also used for drawing help lines... */ @@ -343,7 +345,7 @@ void *ikparam; /* IK solver parameters, structure depends on iksolver */ bAnimVizSettings avs; /* settings for visualization of bone animation */ - char proxy_act_bone[32]; /* proxy active bone name*/ + char proxy_act_bone[64]; /* proxy active bone name, MAXBONENAME */ } bPose; @@ -667,7 +669,7 @@ ListBase constraintChannels; /* Constraint Channels (when Action Channel represents an Object or Bone) */ int flag; /* settings accessed via bitmapping */ - char name[32]; /* channel name */ + char name[64]; /* channel name, MAX_NAME */ int temp; /* temporary setting - may be used to indicate group that channel belongs to during syncing */ } bActionChannel; diff -Nru blender-2.61/source/blender/makesdna/DNA_actuator_types.h blender-2.62/source/blender/makesdna/DNA_actuator_types.h --- blender-2.61/source/blender/makesdna/DNA_actuator_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_actuator_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -50,8 +50,8 @@ struct bAction *act; /* Pointer to action */ short type, flag; /* Playback type */ // not in use float sta, end; /* Start & End frames */ - char name[32]; /* For property-driven playback */ - char frameProp[32]; /* Set this property to the actions current frame */ + char name[64]; /* For property-driven playback, MAX_NAME */ + char frameProp[64]; /* Set this property to the actions current frame, MAX_NAME */ short blendin; /* Number of frames of blending */ short priority; /* Execution priority */ short layer; /* Animation layer */ @@ -90,7 +90,7 @@ short type, flag; struct Object *ob; struct Mesh *me; - char name[32]; + char name[64]; /* MAX_NAME */ float linVelocity[3]; /* initial lin. velocity on creation */ float angVelocity[3]; /* initial ang. velocity on creation */ float mass; @@ -107,7 +107,7 @@ typedef struct bPropertyActuator { int pad, type; - char name[32], value[32]; + char name[64], value[64]; /* MAX_NAME */ struct Object *ob; } bPropertyActuator; @@ -125,8 +125,8 @@ typedef struct bIpoActuator { short flag, type; float sta, end; - char name[32]; - char frameProp[32]; /* Set this property to the actions current frame */ + char name[64]; /* MAX_NAME */ + char frameProp[64]; /* Set this property to the actions current frame, MAX_NAME */ short pad1, pad2, pad3, pad4; @@ -147,13 +147,13 @@ int pad; float minloc[3], maxloc[3]; float minrot[3], maxrot[3]; - char matprop[32]; + char matprop[64]; /* MAX_NAME */ } bConstraintActuator; typedef struct bGroupActuator { short flag, type; int sta, end; - char name[32]; /* property or groupkey */ + char name[64]; /* property or groupkey, MAX_NAME */ short pad[3], cur, butsta, butend;/* not referenced, can remove? */ /* struct Group *group; not used, remove */ @@ -168,16 +168,16 @@ int int_arg_2; float float_arg_1; float float_arg_2; - char propname[32]; + char propname[64]; /* MAX_NAME */ } bRandomActuator; typedef struct bMessageActuator { - char toPropName[32]; /* Send to all objects with this propertyname. Empty to broadcast. */ + char toPropName[64]; /* Send to all objects with this propertyname. Empty to broadcast. MAX_NAME. */ struct Object *toObject;/* (Possible future use) pointer to a single destination object. */ - char subject[32]; /* Message Subject to send. */ + char subject[64]; /* Message Subject to send. MAX_NAME. */ short bodyType, pad1; /* bodyType is either 'User defined text' or PropName */ int pad2; - char body[32]; /* Either User Defined Text or our PropName to send value of */ + char body[64]; /* Either User Defined Text or our PropName to send value of, MAX_NAME */ } bMessageActuator; typedef struct bGameActuator { @@ -194,7 +194,7 @@ int flag; } bVisibilityActuator; -typedef struct bTwoDFilterActuator{ +typedef struct bTwoDFilterActuator { char pad[4]; /* Tells what type of 2D Filter */ short type; @@ -205,7 +205,7 @@ /* a float argument */ float float_arg; struct Text *text; -}bTwoDFilterActuator; +} bTwoDFilterActuator; typedef struct bParentActuator { char pad[2]; @@ -220,8 +220,8 @@ } bStateActuator; typedef struct bArmatureActuator { - char posechannel[32]; - char constraint[32]; + char posechannel[64]; /* MAX_NAME */ + char constraint[64]; /* MAX_NAME */ int type; /* 0=run, 1=enable, 2=disable, 3=set target, 4=set weight */ float weight; struct Object *target; @@ -250,7 +250,7 @@ */ short flag; short otype, go; - char name[32]; + char name[64]; /* MAX_NAME */ /** * data must point to an object actuator type struct. @@ -520,10 +520,6 @@ #define ACT_STATE_REMOVE 2 #define ACT_STATE_CHANGE 3 -/* cameraactuator->axis */ -#define ACT_CAMERA_X (float)'x' -#define ACT_CAMERA_Y (float)'y' - /* steeringactuator->type */ #define ACT_STEERING_SEEK 0 #define ACT_STEERING_FLEE 1 diff -Nru blender-2.61/source/blender/makesdna/DNA_anim_types.h blender-2.62/source/blender/makesdna/DNA_anim_types.h --- blender-2.61/source/blender/makesdna/DNA_anim_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_anim_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -23,13 +23,13 @@ * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_ANIM_TYPES_H -#define DNA_ANIM_TYPES_H - /** \file DNA_anim_types.h * \ingroup DNA */ +#ifndef DNA_ANIM_TYPES_H +#define DNA_ANIM_TYPES_H + #ifdef __cplusplus extern "C" { #endif diff -Nru blender-2.61/source/blender/makesdna/DNA_armature_types.h blender-2.62/source/blender/makesdna/DNA_armature_types.h --- blender-2.61/source/blender/makesdna/DNA_armature_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_armature_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -23,13 +23,13 @@ * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_ARMATURE_TYPES_H -#define DNA_ARMATURE_TYPES_H - /** \file DNA_armature_types.h * \ingroup DNA */ +#ifndef DNA_ARMATURE_TYPES_H +#define DNA_ARMATURE_TYPES_H + #include "DNA_listBase.h" #include "DNA_ID.h" @@ -49,7 +49,7 @@ IDProperty *prop; /* User-Defined Properties on this Bone */ struct Bone *parent; /* Parent (ik parent if appropriate flag is set */ ListBase childbase; /* Children */ - char name[32]; /* Name of the bone - must be unique within the armature */ + char name[64]; /* Name of the bone - must be unique within the armature, MAXBONENAME */ float roll; /* roll is input for editmode, length calculated */ float head[3]; @@ -200,6 +200,6 @@ BONE_NO_LOCAL_LOCATION = (1<<22) /* bone location is in armature space */ } eBone_Flag; -#define MAXBONENAME 32 +#define MAXBONENAME 64 #endif diff -Nru blender-2.61/source/blender/makesdna/DNA_boid_types.h blender-2.62/source/blender/makesdna/DNA_boid_types.h --- blender-2.61/source/blender/makesdna/DNA_boid_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_boid_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -26,13 +26,13 @@ * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_BOID_TYPES_H -#define DNA_BOID_TYPES_H - /** \file DNA_boid_types.h * \ingroup DNA */ +#ifndef DNA_BOID_TYPES_H +#define DNA_BOID_TYPES_H + #include "DNA_listBase.h" typedef enum BoidRuleType { diff -Nru blender-2.61/source/blender/makesdna/DNA_brush_types.h blender-2.62/source/blender/makesdna/DNA_brush_types.h --- blender-2.61/source/blender/makesdna/DNA_brush_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_brush_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -25,13 +25,13 @@ * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_BRUSH_TYPES_H -#define DNA_BRUSH_TYPES_H - /** \file DNA_brush_types.h * \ingroup DNA */ +#ifndef DNA_BRUSH_TYPES_H +#define DNA_BRUSH_TYPES_H + #include "DNA_ID.h" #include "DNA_texture_types.h" /* for MTex */ @@ -59,7 +59,7 @@ struct ImBuf *icon_imbuf; PreviewImage *preview; - char icon_filepath[240]; + char icon_filepath[1024]; /* 1024 = FILE_MAX */ float normal_weight; @@ -81,7 +81,7 @@ float plane_offset; /* offset for plane brushes (clay, flatten, fill, scrape) */ char sculpt_tool; /* active sculpt tool */ - char vertexpaint_tool; /* active vertex/weight paint tool/blend mode */ + char vertexpaint_tool; /* active vertex/weight paint blend mode (poorly named) */ char imagepaint_tool; /* active image paint tool */ char pad3[5]; @@ -132,7 +132,7 @@ #define BRUSH_CUSTOM_ICON (1<<28) /* temporary flag which sets up autmatically for correct - brush drawing when inverted modal operator is running */ + * brush drawing when inverted modal operator is running */ #define BRUSH_INVERTED (1<<29) /* Brush.sculpt_tool */ @@ -167,9 +167,20 @@ SCULPT_DISP_DIR_VIEW, SCULPT_DISP_DIR_X, SCULPT_DISP_DIR_Y, - SCULPT_DISP_DIR_Z, + SCULPT_DISP_DIR_Z }; +enum { + PAINT_BLEND_MIX, + PAINT_BLEND_ADD, + PAINT_BLEND_SUB, + PAINT_BLEND_MUL, + PAINT_BLEND_BLUR, + PAINT_BLEND_LIGHTEN, + PAINT_BLEND_DARKEN +}; + + #define MAX_BRUSH_PIXEL_RADIUS 200 #endif diff -Nru blender-2.61/source/blender/makesdna/DNA_camera_types.h blender-2.62/source/blender/makesdna/DNA_camera_types.h --- blender-2.61/source/blender/makesdna/DNA_camera_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_camera_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -24,13 +24,14 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_CAMERA_TYPES_H -#define DNA_CAMERA_TYPES_H /** \file DNA_camera_types.h * \ingroup DNA */ +#ifndef DNA_CAMERA_TYPES_H +#define DNA_CAMERA_TYPES_H + #include "DNA_defs.h" #include "DNA_ID.h" diff -Nru blender-2.61/source/blender/makesdna/DNA_cloth_types.h blender-2.62/source/blender/makesdna/DNA_cloth_types.h --- blender-2.61/source/blender/makesdna/DNA_cloth_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_cloth_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -24,13 +24,14 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_CLOTH_TYPES_H -#define DNA_CLOTH_TYPES_H /** \file DNA_cloth_types.h * \ingroup DNA */ +#ifndef DNA_CLOTH_TYPES_H +#define DNA_CLOTH_TYPES_H + /** * This struct contains all the global data required to run a simulation. * At the time of this writing, this structure contains data appropriate @@ -69,6 +70,7 @@ float goalfrict; float velocity_smooth; /* smoothing of velocities for hair */ float collider_friction; /* friction with colliders */ + float vel_damping; /* damp the velocity to speed up getting to the resting position */ int stepsPerFrame; /* Number of time steps per frame. */ int flags; /* flags, see CSIMSETT_FLAGS enum above. */ @@ -81,7 +83,7 @@ short shapekey_rest; /* vertex group for scaling structural stiffness */ short presets; /* used for presets on GUI */ short reset; - short pad[3]; + short pad; struct EffectorWeights *effector_weights; } ClothSimSettings; diff -Nru blender-2.61/source/blender/makesdna/DNA_color_types.h blender-2.62/source/blender/makesdna/DNA_color_types.h --- blender-2.61/source/blender/makesdna/DNA_color_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_color_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -24,13 +24,14 @@ * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ -#ifndef DNA_COLOR_TYPES_H -#define DNA_COLOR_TYPES_H /** \file DNA_color_types.h * \ingroup DNA */ +#ifndef DNA_COLOR_TYPES_H +#define DNA_COLOR_TYPES_H + #include "DNA_vec_types.h" /* general defines for kernel functions */ diff -Nru blender-2.61/source/blender/makesdna/DNA_constraint_types.h blender-2.62/source/blender/makesdna/DNA_constraint_types.h --- blender-2.61/source/blender/makesdna/DNA_constraint_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_constraint_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -26,13 +26,13 @@ * Constraint DNA data */ -#ifndef DNA_CONSTRAINT_TYPES_H -#define DNA_CONSTRAINT_TYPES_H - /** \file DNA_constraint_types.h * \ingroup DNA */ +#ifndef DNA_CONSTRAINT_TYPES_H +#define DNA_CONSTRAINT_TYPES_H + #include "DNA_defs.h" #include "DNA_ID.h" #include "DNA_listBase.h" @@ -61,11 +61,12 @@ char ownspace; /* Space that owner should be evaluated in */ char tarspace; /* Space that target should be evaluated in (only used if 1 target) */ - char name[30]; /* Constraint name */ + char name[64]; /* Constraint name, MAX_NAME */ + + short pad; float enforce; /* Amount of influence exherted by constraint (0.0-1.0) */ float headtail; /* Point along subtarget bone where the actual target is. 0=head (default for all), 1=tail*/ - int pad; struct Ipo *ipo DNA_DEPRECATED; /* local influence ipo or driver */ /* old animation system, deprecated for 2.5 */ @@ -85,7 +86,7 @@ struct bConstraintTarget *next, *prev; struct Object *tar; /* object to use as target */ - char subtarget[32]; /* subtarget - pchan or vgroup name */ + char subtarget[64]; /* subtarget - pchan or vgroup name, MAX_ID_NAME-2 */ float matrix[4][4]; /* matrix used during constraint solving - should be cleared before each use */ @@ -121,15 +122,15 @@ ListBase targets; /* a list of targets that this constraint has (bConstraintTarget-s) */ struct Object *tar; /* target from previous implementation (version-patch sets this to NULL on file-load) */ - char subtarget[32]; /* subtarger from previous implentation (version-patch sets this to "" on file-load) */ + char subtarget[64]; /* subtarger from previous implentation (version-patch sets this to "" on file-load), MAX_ID_NAME-2 */ } bPythonConstraint; /* Inverse-Kinematics (IK) constraint - This constraint supports a variety of mode determine by the type field - according to B_CONSTRAINT_IK_TYPE. - Some fields are used by all types, some are specific to some types - This is indicated in the comments for each field + * This constraint supports a variety of mode determine by the type field + * according to B_CONSTRAINT_IK_TYPE. + * Some fields are used by all types, some are specific to some types + * This is indicated in the comments for each field */ typedef struct bKinematicConstraint { struct Object *tar; /* All: target object in case constraint needs a target */ @@ -137,9 +138,9 @@ short flag; /* All & CopyPose: some options Like CONSTRAINT_IK_TIP */ short rootbone; /* All: index to rootbone, if zero go all the way to mother bone */ short max_rootbone; /* CopyPose: for auto-ik, maximum length of chain */ - char subtarget[32]; /* All: String to specify sub-object target */ + char subtarget[64]; /* All: String to specify sub-object target, MAX_ID_NAME-2 */ struct Object *poletar; /* All: Pole vector target */ - char polesubtarget[32]; /* All: Pole vector sub-object target */ + char polesubtarget[64]; /* All: Pole vector sub-object target, MAX_ID_NAME-2 */ float poleangle; /* All: Pole vector rest angle */ float weight; /* All: Weight of constraint in IK tree */ float orientweight; /* CopyPose: Amount of rotation a target applies on chain */ @@ -180,11 +181,14 @@ /* Track To Constraint */ typedef struct bTrackToConstraint { struct Object *tar; - int reserved1; /* I'll be using reserved1 and reserved2 as Track and Up flags, not sure if that's what they were intented for anyway. Not sure either if it would create backward incompatibility if I were to rename them. - theeth*/ + int reserved1; /* I'll be using reserved1 and reserved2 as Track and Up flags, + * not sure if that's what they were intented for anyway. + * Not sure either if it would create backward incompatibility if I were to rename them. + * - theeth*/ int reserved2; int flags; int pad; - char subtarget[32]; + char subtarget[64]; /* MAX_ID_NAME-2 */ } bTrackToConstraint; /* Copy Rotation Constraint */ @@ -192,7 +196,7 @@ struct Object *tar; int flag; int reserved1; - char subtarget[32]; + char subtarget[64]; /* MAX_ID_NAME-2 */ } bRotateLikeConstraint; /* Copy Location Constraint */ @@ -200,7 +204,7 @@ struct Object *tar; int flag; int reserved1; - char subtarget[32]; + char subtarget[64]; /* MAX_ID_NAME-2 */ } bLocateLikeConstraint; /* Copy Scale Constraint */ @@ -208,7 +212,7 @@ struct Object *tar; int flag; int reserved1; - char subtarget[32]; + char subtarget[64]; /* MAX_ID_NAME-2 */ } bSizeLikeConstraint; /* Maintain Volume Constraint */ @@ -220,7 +224,7 @@ /* Copy Transform Constraint */ typedef struct bTransLikeConstraint { struct Object *tar; - char subtarget[32]; + char subtarget[64]; /* MAX_ID_NAME-2 */ } bTransLikeConstraint; /* Floor Constraint */ @@ -231,7 +235,7 @@ int flag; short sticky, stuck, pad1, pad2; /* for backward compatibility */ float cache[3]; - char subtarget[32]; + char subtarget[64]; /* MAX_ID_NAME-2 */ } bMinMaxConstraint; /* Action Constraint */ @@ -245,7 +249,7 @@ float max; int pad; struct bAction *act; - char subtarget[32]; + char subtarget[64]; /* MAX_ID_NAME-2 */ } bActionConstraint; /* Locked Axis Tracking constraint */ @@ -253,7 +257,7 @@ struct Object *tar; int trackflag; int lockflag; - char subtarget[32]; + char subtarget[64]; /* MAX_ID_NAME-2 */ } bLockTrackConstraint; /* Damped Tracking constraint */ @@ -261,7 +265,7 @@ struct Object *tar; int trackflag; int pad; - char subtarget[32]; + char subtarget[64]; /* MAX_ID_NAME-2 */ } bDampTrackConstraint; /* Follow Path constraints */ @@ -284,7 +288,7 @@ int plane; float orglength; float bulge; - char subtarget[32]; + char subtarget[64]; /* MAX_ID_NAME-2 */ } bStretchToConstraint; /* Rigid Body constraint */ @@ -320,13 +324,13 @@ int flag; /* settings */ int pad; float invmat[4][4]; /* parent-inverse matrix to use */ - char subtarget[32]; /* string to specify a subobject target */ + char subtarget[64]; /* string to specify a subobject target, MAX_ID_NAME-2 */ } bChildOfConstraint; /* Generic Transform->Transform Constraint */ typedef struct bTransformConstraint { struct Object *tar; /* target (i.e. 'driver' object/bone) */ - char subtarget[32]; + char subtarget[64]; /* MAX_ID_NAME-2 */ short from, to; /* can be loc(0) , rot(1), or size(2) */ char map[3]; /* defines which target-axis deform is copied by each owner-axis */ @@ -345,7 +349,7 @@ * Either target object + offset, or just offset is used */ struct Object *tar; /* target object (optional) */ - char subtarget[32]; /* subtarget name (optional) */ + char subtarget[64]; /* subtarget name (optional), MAX_ID_NAME-2 */ float offset[3]; /* offset from the target to use, regardless of whether it exists */ /* Rotation-driven activation: @@ -388,7 +392,7 @@ /* Limit Distance Constraint */ typedef struct bDistLimitConstraint { struct Object *tar; - char subtarget[32]; + char subtarget[64]; /* MAX_ID_NAME-2 */ float dist; /* distance (radius of clamping sphere) from target */ float soft; /* distance from clamping-sphere to start applying 'fade' */ @@ -410,8 +414,11 @@ /* Follow Track constraints */ typedef struct bFollowTrackConstraint { struct MovieClip *clip; - char track[24]; + char track[64]; /* MAX_NAME */ int flag, pad; + char object[64]; /* MAX_NAME */ + struct Object *camera; + struct Object *depth_ob; } bFollowTrackConstraint; /* Camera Solver constraints */ @@ -420,6 +427,15 @@ int flag, pad; } bCameraSolverConstraint; +/* Camera Solver constraints */ +typedef struct bObjectSolverConstraint { + struct MovieClip *clip; + int flag, pad; + char object[64]; /* MAX_NAME */ + float invmat[4][4]; /* parent-inverse matrix to use */ + struct Object *camera; +} bObjectSolverConstraint; + /* ------------------------------------------ */ /* bConstraint->type @@ -455,6 +471,7 @@ CONSTRAINT_TYPE_PIVOT, /* Pivot Constraint */ CONSTRAINT_TYPE_FOLLOWTRACK, /* Follow Track Constraint */ CONSTRAINT_TYPE_CAMERASOLVER, /* Camera Solver Constraint */ + CONSTRAINT_TYPE_OBJECTSOLVER, /* Object Solver Constraint */ /* NOTE: no constraints are allowed to be added after this */ NUM_CONSTRAINT_TYPES @@ -762,6 +779,11 @@ CAMERASOLVER_ACTIVECLIP = (1<<0) } eCameraSolver_Flags; +/* ObjectSolver Constraint -> flag */ +typedef enum eObjectSolver_Flags { + OBJECTSOLVER_ACTIVECLIP = (1<<0) +} eObjectSolver_Flags; + /* Rigid-Body Constraint */ #define CONSTRAINT_DRAW_PIVOT 0x40 #define CONSTRAINT_DISABLE_LINKED_COLLISION 0x80 diff -Nru blender-2.61/source/blender/makesdna/DNA_controller_types.h blender-2.62/source/blender/makesdna/DNA_controller_types.h --- blender-2.61/source/blender/makesdna/DNA_controller_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_controller_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -24,13 +24,14 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_CONTROLLER_TYPES_H -#define DNA_CONTROLLER_TYPES_H /** \file DNA_controller_types.h * \ingroup DNA */ +#ifndef DNA_CONTROLLER_TYPES_H +#define DNA_CONTROLLER_TYPES_H + struct bActuator; struct Text; struct bSensor; @@ -53,7 +54,7 @@ short type, flag, inputs, totlinks; short otype, totslinks, pad2, pad3; - char name[32]; + char name[64]; void *data; struct bActuator **links; diff -Nru blender-2.61/source/blender/makesdna/DNA_curve_types.h blender-2.62/source/blender/makesdna/DNA_curve_types.h --- blender-2.61/source/blender/makesdna/DNA_curve_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_curve_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -24,13 +24,14 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_CURVE_TYPES_H -#define DNA_CURVE_TYPES_H /** \file DNA_curve_types.h * \ingroup DNA */ +#ifndef DNA_CURVE_TYPES_H +#define DNA_CURVE_TYPES_H + #include "DNA_defs.h" #include "DNA_listBase.h" #include "DNA_vec_types.h" @@ -259,6 +260,7 @@ #define CU_DS_EXPAND 2048 #define CU_PATH_RADIUS 4096 /* make use of the path radius if this is enabled (default for new curves) */ #define CU_DEFORM_FILL 8192 /* fill 2d curve after deformation */ +#define CU_FILL_CAPS 16384 /* fill bevel caps */ /* twist mode */ #define CU_TWIST_Z_UP 0 diff -Nru blender-2.61/source/blender/makesdna/DNA_customdata_types.h blender-2.62/source/blender/makesdna/DNA_customdata_types.h --- blender-2.61/source/blender/makesdna/DNA_customdata_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_customdata_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -36,6 +36,8 @@ extern "C" { #endif +#include "DNA_defs.h" /* USE_BMESH_FORWARD_COMPAT */ + /** descriptor and storage for a custom data layer */ typedef struct CustomDataLayer { int type; /* type of data in layer */ @@ -46,12 +48,14 @@ int active_clone; /* number of the layer to render*/ int active_mask; /* number of the layer to render*/ char pad[4]; - char name[32]; /* layer name */ + char name[64]; /* layer name, MAX_CUSTOMDATA_LAYER_AAME */ void *data; /* layer data */ } CustomDataLayer; +#define MAX_CUSTOMDATA_LAYER_NAME 64 + typedef struct CustomDataExternal { - char filename[240]; /* FILE_MAX */ + char filename[1024]; /* FILE_MAX */ } CustomDataExternal; /** structure which stores custom element data associated with mesh elements @@ -59,6 +63,9 @@ * layers, each with a data type (e.g. MTFace, MDeformVert, etc.). */ typedef struct CustomData { CustomDataLayer *layers; /* CustomDataLayers, ordered by type */ + int typemap[32]; /* runtime only! - maps types to indices of first layer of that type, + * MUST be >= CD_NUMTYPES, but we cant use a define here. + * Correct size is ensured in CustomData_update_typemap assert() */ int totlayer, maxlayer; /* number of layers, size of layers array */ int totsize, pad; /* in editmode, total size of all data layers */ void *pool; /* Bmesh: Memory pool for allocation of blocks */ @@ -75,7 +82,7 @@ #define CD_MCOL 6 #define CD_ORIGINDEX 7 #define CD_NORMAL 8 -#define CD_FLAGS 9 +#define CD_POLYINDEX 9 #define CD_PROP_FLT 10 #define CD_PROP_INT 11 #define CD_PROP_STR 12 @@ -91,8 +98,27 @@ #define CD_TEXTURE_MCOL 22 #define CD_CLOTH_ORCO 23 #define CD_RECAST 24 + +#ifdef USE_BMESH_FORWARD_COMPAT + +/* BMESH ONLY START */ +#define CD_MPOLY 25 +#define CD_MLOOP 26 +#define CD_SHAPE_KEYINDEX 27 +#define CD_SHAPEKEY 28 +#define CD_BWEIGHT 29 +#define CD_CREASE 30 +#define CD_WEIGHT_MLOOPCOL 31 +/* BMESH ONLY END */ + +#define CD_NUMTYPES 32 + +#else + #define CD_NUMTYPES 25 +#endif + /* Bits for CustomDataMask */ #define CD_MASK_MVERT (1 << CD_MVERT) #define CD_MASK_MSTICKY (1 << CD_MSTICKY) @@ -103,7 +129,7 @@ #define CD_MASK_MCOL (1 << CD_MCOL) #define CD_MASK_ORIGINDEX (1 << CD_ORIGINDEX) #define CD_MASK_NORMAL (1 << CD_NORMAL) -#define CD_MASK_FLAGS (1 << CD_FLAGS) +#define CD_MASK_POLYINDEX (1 << CD_POLYINDEX) #define CD_MASK_PROP_FLT (1 << CD_PROP_FLT) #define CD_MASK_PROP_INT (1 << CD_PROP_INT) #define CD_MASK_PROP_STR (1 << CD_PROP_STR) @@ -118,6 +144,20 @@ #define CD_MASK_CLOTH_ORCO (1 << CD_CLOTH_ORCO) #define CD_MASK_RECAST (1 << CD_RECAST) +#ifdef USE_BMESH_FORWARD_COMPAT + +/* BMESH ONLY START */ +#define CD_MASK_MPOLY (1 << CD_MPOLY) +#define CD_MASK_MLOOP (1 << CD_MLOOP) +#define CD_MASK_SHAPE_KEYINDEX (1 << CD_SHAPE_KEYINDEX) +#define CD_MASK_SHAPEKEY (1 << CD_SHAPEKEY) +#define CD_MASK_BWEIGHT (1 << CD_BWEIGHT) +#define CD_MASK_CREASE (1 << CD_CREASE) +#define CD_MASK_WEIGHT_MLOOPCOL (1 << CD_WEIGHT_MLOOPCOL) +/* BMESH ONLY END */ + +#endif + /* CustomData.flag */ /* indicates layer should not be copied by CustomData_from_template or diff -Nru blender-2.61/source/blender/makesdna/DNA_defs.h blender-2.62/source/blender/makesdna/DNA_defs.h --- blender-2.61/source/blender/makesdna/DNA_defs.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_defs.h 2012-02-15 19:34:32.000000000 +0000 @@ -20,13 +20,13 @@ * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_DEFS_H -#define DNA_DEFS_H - /** \file DNA_defs.h * \ingroup DNA */ +#ifndef DNA_DEFS_H +#define DNA_DEFS_H + /* makesdna ignores */ #ifdef DNA_DEPRECATED_ALLOW /* allow use of deprecated items */ @@ -42,4 +42,12 @@ # endif #endif +/* hrmf, we need a better include then this */ +#include "../blenloader/BLO_sys_types.h" /* needed for int64_t only! */ + +#define USE_BMESH_FORWARD_COMPAT + +/* non-id name variables should use this length */ +#define MAX_NAME 64 + #endif /* DNA_DEFS_H */ diff -Nru blender-2.61/source/blender/makesdna/DNA_documentation.h blender-2.62/source/blender/makesdna/DNA_documentation.h --- blender-2.61/source/blender/makesdna/DNA_documentation.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_documentation.h 2012-02-15 19:34:32.000000000 +0000 @@ -63,14 +63,12 @@ * \section dnanote NOTE - PLEASE READ INSTRUCTIONS ABOUT ADDING VARIABLES IN 'DNA' STRUCTS IN - - intern/dna_genfile.c - (ton) + * PLEASE READ INSTRUCTIONS ABOUT ADDING VARIABLES IN 'DNA' STRUCTS IN + * + * intern/dna_genfile.c + * (ton) */ - /* This file has intentionally no definitions or implementation. */ - diff -Nru blender-2.61/source/blender/makesdna/DNA_dynamicpaint_types.h blender-2.62/source/blender/makesdna/DNA_dynamicpaint_types.h --- blender-2.61/source/blender/makesdna/DNA_dynamicpaint_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_dynamicpaint_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -1,15 +1,30 @@ -/** -* ***** BEGIN GPL LICENSE BLOCK ***** -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* as published by the Free Software Foundation; either version 2 -* of the License, or (at your option) any later version. -* -* Contributor(s): Miika Hämäläinen -* -* ***** END GPL LICENSE BLOCK ***** -*/ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + * Contributor(s): Miika Hämäläinen + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file DNA_dynamicpaint_types.h + * \ingroup DNA + */ + #ifndef DNA_DYNAMICPAINT_TYPES_H #define DNA_DYNAMICPAINT_TYPES_H @@ -40,6 +55,7 @@ #define MOD_DPAINT_WAVE_OPEN_BORDERS (1<<7) /* passes waves through mesh edges */ #define MOD_DPAINT_DISP_INCREMENTAL (1<<8) /* builds displace on top of earlier values */ +#define MOD_DPAINT_USE_DRYING (1<<9) /* use drying */ #define MOD_DPAINT_OUT1 (1<<10) /* output primary surface */ #define MOD_DPAINT_OUT2 (1<<11) /* output secondary surface */ @@ -54,8 +70,8 @@ /* effect */ #define MOD_DPAINT_EFFECT_DO_SPREAD (1<<0) /* do spread effect */ -#define MOD_DPAINT_EFFECT_DO_DRIP (1<<1) /* do spread effect */ -#define MOD_DPAINT_EFFECT_DO_SHRINK (1<<2) /* do spread effect */ +#define MOD_DPAINT_EFFECT_DO_DRIP (1<<1) /* do drip effect */ +#define MOD_DPAINT_EFFECT_DO_SHRINK (1<<2) /* do shrink effect */ /* preview_id */ #define MOD_DPAINT_SURFACE_PREV_PAINT 0 @@ -96,28 +112,33 @@ /* initial color */ float init_color[4]; struct Tex *init_texture; - char init_layername[40]; + char init_layername[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ int dry_speed, diss_speed; + float color_dry_threshold; float depth_clamp, disp_factor; float spread_speed, color_spread_speed, shrink_speed; float drip_vel, drip_acc; + /* per surface brush settings */ + float influence_scale, radius_scale; + /* wave settings */ float wave_damping, wave_speed, wave_timescale, wave_spring; - int pad_; - - char uvlayer_name[32]; - char image_output_path[240]; - char output_name[40]; - char output_name2[40]; /* some surfaces have 2 outputs */ + char uvlayer_name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ + char image_output_path[1024]; /* 1024 = FILE_MAX */ + char output_name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ + char output_name2[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ /* some surfaces have 2 outputs */ } DynamicPaintSurface; /* canvas flags */ +#if 0 /* This should not be needed, having a valid WEIGHT_MCOL layer should be enough. + * And if not, should be a general flag. But seems unecessary for now... */ #define MOD_DPAINT_PREVIEW_READY (1<<0) /* if viewport preview is ready */ +#endif #define MOD_DPAINT_BAKING (1<<1) /* surface is already baking, so it wont get updated (loop) */ /* Canvas settings */ diff -Nru blender-2.61/source/blender/makesdna/DNA_effect_types.h blender-2.62/source/blender/makesdna/DNA_effect_types.h --- blender-2.61/source/blender/makesdna/DNA_effect_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_effect_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -24,13 +24,14 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_EFFECT_TYPES_H -#define DNA_EFFECT_TYPES_H /** \file DNA_effect_types.h * \ingroup DNA */ +#ifndef DNA_EFFECT_TYPES_H +#define DNA_EFFECT_TYPES_H + /* don't forget, new effects also in writefile.c for dna!!! */ #define PAF_MAXMULT 4 @@ -117,7 +118,7 @@ short staticstep, omat, timetex, speedtex, flag2, flag2neg; short disp, vertgroup_v; - char vgroupname[32], vgroupname_v[32]; + char vgroupname[64], vgroupname_v[64]; /* MAX_VGROUP_NAME */ float imat[4][4]; /* inverse matrix of parent Object */ Particle *keys; diff -Nru blender-2.61/source/blender/makesdna/DNA_fileglobal_types.h blender-2.62/source/blender/makesdna/DNA_fileglobal_types.h --- blender-2.61/source/blender/makesdna/DNA_fileglobal_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_fileglobal_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -24,13 +24,14 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_FILEGLOBAL_TYPES_H -#define DNA_FILEGLOBAL_TYPES_H /** \file DNA_fileglobal_types.h * \ingroup DNA */ +#ifndef DNA_FILEGLOBAL_TYPES_H +#define DNA_FILEGLOBAL_TYPES_H + struct bScreen; struct Scene; @@ -50,7 +51,7 @@ int revision; /* svn revision from buildinfo */ int pad; /* file path where this was saved, for recover */ - char filename[240]; /* 240 = FILE_MAX */ + char filename[1024]; /* 1024 = FILE_MAX */ } FileGlobal; diff -Nru blender-2.61/source/blender/makesdna/DNA_genfile.h blender-2.62/source/blender/makesdna/DNA_genfile.h --- blender-2.61/source/blender/makesdna/DNA_genfile.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_genfile.h 2012-02-15 19:34:32.000000000 +0000 @@ -25,19 +25,37 @@ * ***** END GPL LICENSE BLOCK ***** */ -#ifndef GENFILE_H -#define GENFILE_H - /** \file DNA_genfile.h * \ingroup DNA * \brief blenloader genfile private function prototypes */ +#ifndef DNA_GENFILE_H +#define DNA_GENFILE_H + struct SDNA; extern unsigned char DNAstr[]; /* DNA.c */ extern int DNAlen; +typedef enum eSDNA_Type { + SDNA_TYPE_CHAR = 0, + SDNA_TYPE_UCHAR = 1, + SDNA_TYPE_SHORT = 2, + SDNA_TYPE_USHORT = 3, + SDNA_TYPE_INT = 4, + SDNA_TYPE_LONG = 5, + SDNA_TYPE_ULONG = 6, + SDNA_TYPE_FLOAT = 7, + SDNA_TYPE_DOUBLE = 8, + /* ,SDNA_TYPE_VOID = 9 */ /* nothing uses yet */ + SDNA_TYPE_INT64 = 10, + SDNA_TYPE_UINT64 = 11 +} eSDNA_Type; + +/* define so switch statements don't complain */ +#define SDNA_TYPE_VOID 9 + struct SDNA *DNA_sdna_from_data(void *data, int datalen, int do_endian_swap); void DNA_sdna_free(struct SDNA *sdna); @@ -49,6 +67,7 @@ int DNA_elem_array_size(const char *astr, int len); int DNA_elem_offset(struct SDNA *sdna, const char *stype, const char *vartype, const char *name); -#endif +int DNA_elem_type_size(const eSDNA_Type elem_nr); +#endif diff -Nru blender-2.61/source/blender/makesdna/DNA_gpencil_types.h blender-2.62/source/blender/makesdna/DNA_gpencil_types.h --- blender-2.61/source/blender/makesdna/DNA_gpencil_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_gpencil_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -22,13 +22,14 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_GPENCIL_TYPES_H -#define DNA_GPENCIL_TYPES_H /** \file DNA_gpencil_types.h * \ingroup DNA */ +#ifndef DNA_GPENCIL_TYPES_H +#define DNA_GPENCIL_TYPES_H + #include "DNA_listBase.h" #include "DNA_ID.h" diff -Nru blender-2.61/source/blender/makesdna/DNA_group_types.h blender-2.62/source/blender/makesdna/DNA_group_types.h --- blender-2.61/source/blender/makesdna/DNA_group_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_group_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -27,13 +27,14 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_GROUP_TYPES_H -#define DNA_GROUP_TYPES_H /** \file DNA_group_types.h * \ingroup DNA */ +#ifndef DNA_GROUP_TYPES_H +#define DNA_GROUP_TYPES_H + #include "DNA_listBase.h" #include "DNA_ID.h" diff -Nru blender-2.61/source/blender/makesdna/DNA_ID.h blender-2.62/source/blender/makesdna/DNA_ID.h --- blender-2.61/source/blender/makesdna/DNA_ID.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_ID.h 2012-02-15 19:34:32.000000000 +0000 @@ -24,14 +24,15 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_ID_H -#define DNA_ID_H /** \file DNA_ID.h * \ingroup DNA * \brief ID and Library types, which are fundamental for sdna. */ +#ifndef DNA_ID_H +#define DNA_ID_H + #include "DNA_listBase.h" #ifdef __cplusplus @@ -52,19 +53,19 @@ struct IDProperty *next, *prev; char type, subtype; short flag; - char name[32]; + char name[64]; /* MAX_IDPROP_NAME */ int saved; /*saved is used to indicate if this struct has been saved yet. seemed like a good idea as a pad var was needed anyway :)*/ IDPropertyData data; /* note, alignment for 64 bits */ int len; /* array length, also (this is important!) string length + 1. - the idea is to be able to reuse array realloc functions on strings.*/ + * the idea is to be able to reuse array realloc functions on strings.*/ /* totallen is total length of allocated array/string, including a buffer. * Note that the buffering is mild; the code comes from python's list implementation.*/ int totallen; /*strings and arrays are both buffered, though the buffer isn't saved.*/ } IDProperty; -#define MAX_IDPROP_NAME 32 +#define MAX_IDPROP_NAME 64 #define DEFAULT_ALLOC_FOR_NULL_STRINGS 64 /*->type*/ @@ -74,7 +75,7 @@ #define IDP_ARRAY 5 #define IDP_GROUP 6 /* the ID link property type hasn't been implemented yet, this will require - some cleanup of blenkernel, most likely.*/ + * some cleanup of blenkernel, most likely.*/ #define IDP_ID 7 #define IDP_DOUBLE 8 #define IDP_IDPARRAY 9 @@ -85,6 +86,10 @@ /* IDP_STRING */ #define IDP_STRING_SUB_UTF8 0 /* default */ #define IDP_STRING_SUB_BYTE 1 /* arbitrary byte array, _not_ null terminated */ +/*->flag*/ +#define IDP_FLAG_GHOST (1<<7) /* this means the propery is set but RNA will return + * false when checking 'RNA_property_is_set', + * currently this is a runtime flag */ /* add any future new id property types here.*/ @@ -95,7 +100,8 @@ * provides a common handle to place all data in double-linked lists. * */ -#define MAX_ID_NAME 24 +/* 2 characters for ID code and 64 for actual name */ +#define MAX_ID_NAME 66 /* There's a nasty circular dependency here.... void* to the rescue! I * really wonder why this is needed. */ @@ -103,14 +109,14 @@ void *next, *prev; struct ID *newid; struct Library *lib; - char name[24]; - short us; + char name[66]; + short pad, us; /** * LIB_... flags report on status of the datablock this ID belongs * to. */ short flag; - int icon_id; + int icon_id, pad2; IDProperty *properties; } ID; @@ -122,8 +128,8 @@ ID id; ID *idblock; struct FileData *filedata; - char name[240]; /* path name used for reading, can be relative and edited in the outliner */ - char filepath[240]; /* absolute filepath, this is only for convenience, + char name[1024]; /* path name used for reading, can be relative and edited in the outliner */ + char filepath[1024]; /* absolute filepath, this is only for convenience, * 'name' is the real path used on file read but in * some cases its useful to access the absolute one, * This is set on file read. diff -Nru blender-2.61/source/blender/makesdna/DNA_image_types.h blender-2.62/source/blender/makesdna/DNA_image_types.h --- blender-2.61/source/blender/makesdna/DNA_image_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_image_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -24,13 +24,14 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_IMAGE_TYPES_H -#define DNA_IMAGE_TYPES_H /** \file DNA_image_types.h * \ingroup DNA */ +#ifndef DNA_IMAGE_TYPES_H +#define DNA_IMAGE_TYPES_H + #include "DNA_ID.h" struct PackedFile; @@ -68,7 +69,7 @@ typedef struct Image { ID id; - char name[240]; /* file path */ + char name[1024]; /* file path, 1024 = FILE_MAX */ ListBase ibufs; /* not written in file */ struct GPUTexture *gputexture; /* not written in file */ @@ -111,14 +112,15 @@ /* **************** IMAGE ********************* */ /* Image.flag */ -#define IMA_FIELDS 1 -#define IMA_STD_FIELD 2 -#define IMA_DO_PREMUL 4 - -#define IMA_REFLECT 16 -#define IMA_NOCOLLECT 32 -#define IMA_DEPRECATED 64 -#define IMA_OLD_PREMUL 128 +#define IMA_FIELDS 1 +#define IMA_STD_FIELD 2 +#define IMA_DO_PREMUL 4 +#define IMA_REFLECT 16 +#define IMA_NOCOLLECT 32 +#define IMA_DEPRECATED 64 +#define IMA_OLD_PREMUL 128 +#define IMA_CM_PREDIVIDE 256 +#define IMA_USED_FOR_RENDER 512 /* Image.tpageflag */ #define IMA_TILES 1 diff -Nru blender-2.61/source/blender/makesdna/DNA_key_types.h blender-2.62/source/blender/makesdna/DNA_key_types.h --- blender-2.61/source/blender/makesdna/DNA_key_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_key_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -48,8 +48,8 @@ void *data; float *weights; - char name[32]; - char vgroup[32]; + char name[64]; /* MAX_NAME */ + char vgroup[64]; /* MAX_VGROUP_NAME */ float slidermin; float slidermax; @@ -61,7 +61,7 @@ struct AnimData *adt; /* animation data (must be immediately after id for utilities to use it) */ KeyBlock *refkey; - char elemstr[32]; + char elemstr[64]; /* MAX_NAME */ int elemsize; float curval DNA_DEPRECATED; diff -Nru blender-2.61/source/blender/makesdna/DNA_lamp_types.h blender-2.62/source/blender/makesdna/DNA_lamp_types.h --- blender-2.61/source/blender/makesdna/DNA_lamp_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_lamp_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -24,13 +24,14 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_LAMP_TYPES_H -#define DNA_LAMP_TYPES_H /** \file DNA_lamp_types.h * \ingroup DNA */ +#ifndef DNA_LAMP_TYPES_H +#define DNA_LAMP_TYPES_H + #include "DNA_defs.h" #include "DNA_ID.h" diff -Nru blender-2.61/source/blender/makesdna/DNA_lattice_types.h blender-2.62/source/blender/makesdna/DNA_lattice_types.h --- blender-2.61/source/blender/makesdna/DNA_lattice_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_lattice_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -24,13 +24,14 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_LATTICE_TYPES_H -#define DNA_LATTICE_TYPES_H /** \file DNA_lattice_types.h * \ingroup DNA */ +#ifndef DNA_LATTICE_TYPES_H +#define DNA_LATTICE_TYPES_H + #include "DNA_defs.h" #include "DNA_ID.h" @@ -65,7 +66,7 @@ struct Key *key; struct MDeformVert *dvert; - char vgroup[32]; /* multiply the influence */ + char vgroup[64]; /* multiply the influence, MAX_VGROUP_NAME */ /* used while deforming, always free and NULL after use */ float *latticedata; diff -Nru blender-2.61/source/blender/makesdna/DNA_listBase.h blender-2.62/source/blender/makesdna/DNA_listBase.h --- blender-2.61/source/blender/makesdna/DNA_listBase.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_listBase.h 2012-02-15 19:34:32.000000000 +0000 @@ -27,15 +27,15 @@ * */ -#ifndef DNA_LISTBASE_H -#define DNA_LISTBASE_H - /** \file DNA_listBase.h * \ingroup DNA * \brief These structs are the foundation for all linked lists in the * library system. */ +#ifndef DNA_LISTBASE_H +#define DNA_LISTBASE_H + #ifdef __cplusplus extern "C" { #endif diff -Nru blender-2.61/source/blender/makesdna/DNA_material_types.h blender-2.62/source/blender/makesdna/DNA_material_types.h --- blender-2.61/source/blender/makesdna/DNA_material_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_material_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -24,13 +24,14 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_MATERIAL_TYPES_H -#define DNA_MATERIAL_TYPES_H /** \file DNA_material_types.h * \ingroup DNA */ +#ifndef DNA_MATERIAL_TYPES_H +#define DNA_MATERIAL_TYPES_H + #include "DNA_defs.h" #include "DNA_ID.h" #include "DNA_listBase.h" @@ -120,7 +121,7 @@ float hasize, flaresize, subsize, flareboost; float strand_sta, strand_end, strand_ease, strand_surfnor; float strand_min, strand_widthfade; - char strand_uvname[32]; + char strand_uvname[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ float sbias; /* shadow bias to prevent terminator prob */ float lbias; /* factor to multiply lampbias with (0.0 = no mult) */ @@ -168,8 +169,8 @@ short sss_flag, sss_preset; int mapto_textured; /* render-time cache to optimise texture lookups */ - short shadowonly_flag; /* "shadowsonly" type */ - short index; /* custom index for render passes */ + short shadowonly_flag; /* "shadowsonly" type */ + short index; /* custom index for render passes */ ListBase gpumaterial; /* runtime */ } Material; diff -Nru blender-2.61/source/blender/makesdna/DNA_meshdata_types.h blender-2.62/source/blender/makesdna/DNA_meshdata_types.h --- blender-2.61/source/blender/makesdna/DNA_meshdata_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_meshdata_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -24,13 +24,14 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_MESHDATA_TYPES_H -#define DNA_MESHDATA_TYPES_H /** \file DNA_meshdata_types.h * \ingroup DNA */ +#ifndef DNA_MESHDATA_TYPES_H +#define DNA_MESHDATA_TYPES_H + #include "DNA_customdata_types.h" #include "DNA_listBase.h" @@ -72,21 +73,41 @@ char a, r, g, b; } MCol; +#ifdef USE_BMESH_FORWARD_COMPAT + +/*new face structure, replaces MFace, which is now + only used for storing tesselations.*/ +typedef struct MPoly { + /* offset into loop array and number of loops in the face */ + int loopstart; + int totloop; /* keep signed since we need to subtract when getting the previous loop */ + short mat_nr; + char flag, pad; +} MPoly; + +/*the e here is because we want to move away from + relying on edge hashes.*/ +typedef struct MLoop { + unsigned int v; /*vertex index*/ + unsigned int e; /*edge index*/ +} MLoop; + +#endif /* USE_BMESH_FORWARD_COMPAT */ + /*bmesh custom data stuff*/ -typedef struct MTexPoly{ +typedef struct MTexPoly { struct Image *tpage; char flag, transp; short mode,tile,unwrap; -}MTexPoly; +} MTexPoly; -typedef struct MLoopUV{ +typedef struct MLoopUV { float uv[2]; -}MLoopUV; +} MLoopUV; -typedef struct MLoopCol{ +typedef struct MLoopCol { char a, r, g, b; - int pad; /*waste!*/ -}MLoopCol; +} MLoopCol; typedef struct MSticky { float co[2]; @@ -105,13 +126,13 @@ } MTFace; /*Custom Data Properties*/ -typedef struct MFloatProperty{ +typedef struct MFloatProperty { float f; } MFloatProperty; -typedef struct MIntProperty{ +typedef struct MIntProperty { int i; } MIntProperty; -typedef struct MStringProperty{ +typedef struct MStringProperty { char s[256]; } MStringProperty; @@ -174,7 +195,7 @@ /** End Multires **/ -typedef struct MRecast{ +typedef struct MRecast { int i; } MRecast; diff -Nru blender-2.61/source/blender/makesdna/DNA_mesh_types.h blender-2.62/source/blender/makesdna/DNA_mesh_types.h --- blender-2.61/source/blender/makesdna/DNA_mesh_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_mesh_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -24,18 +24,21 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_MESH_TYPES_H -#define DNA_MESH_TYPES_H /** \file DNA_mesh_types.h * \ingroup DNA */ +#ifndef DNA_MESH_TYPES_H +#define DNA_MESH_TYPES_H + #include "DNA_defs.h" #include "DNA_listBase.h" #include "DNA_ID.h" #include "DNA_customdata_types.h" +#include "DNA_defs.h" /* USE_BMESH_FORWARD_COMPAT */ + struct DerivedMesh; struct Ipo; struct Key; @@ -47,6 +50,11 @@ struct MSticky; struct Mesh; struct OcInfo; +struct MPoly; +struct MTexPoly; +struct MLoop; +struct MLoopUV; +struct MLoopCol; struct Multires; struct EditMesh; struct AnimData; @@ -61,6 +69,17 @@ struct Key *key; struct Material **mat; +/*#ifdef USE_BMESH_FORWARD_COMPAT*/ /* XXX - ifdefs dont work here! */ +/* BMESH ONLY */ + /*new face structures*/ + struct MPoly *mpoly; + struct MTexPoly *mtpoly; + struct MLoop *mloop; + struct MLoopUV *mloopuv; + struct MLoopCol *mloopcol; +/* END BMESH ONLY */ +/*#endif*/ + struct MFace *mface; /* array of mesh object mode faces */ struct MTFace *mtface; /* store face UV's and texture here */ struct TFace *tface; /* depecrated, use mtface */ @@ -76,8 +95,20 @@ struct CustomData vdata, edata, fdata; +/*#ifdef USE_BMESH_FORWARD_COMPAT*/ /* XXX - ifdefs dont work here! */ +/* BMESH ONLY */ + struct CustomData pdata, ldata; +/* END BMESH ONLY */ +/*#endif*/ + int totvert, totedge, totface, totselect; - + +/*#ifdef USE_BMESH_FORWARD_COMPAT*/ +/* BMESH ONLY */ + int totpoly, totloop; +/* END BMESH ONLY */ +/*#endif*/ /* XXX - ifdefs dont work here! */ + /* the last selected vertex/edge/face are used for the active face however * this means the active face must always be selected, this is to keep track * of the last selected face and is similar to the old active face flag where @@ -162,6 +193,9 @@ #define ME_DRAWEXTRA_FACEAREA (1 << 11) #define ME_DRAWEXTRA_FACEANG (1 << 12) +/* debug only option */ +#define ME_DRAWEXTRA_INDICES (1 << 13) + /* old global flags: #define G_DRAWEDGES (1 << 18) #define G_DRAWFACES (1 << 7) @@ -189,4 +223,12 @@ #define MESH_MAX_VERTS 2000000000L +/* this is so we can save bmesh files that load in trunk, ignoring NGons + * will eventually be removed */ + +#if 0 /* enable in bmesh branch only for now */ +#define USE_BMESH_SAVE_AS_COMPAT +#endif + + #endif diff -Nru blender-2.61/source/blender/makesdna/DNA_meta_types.h blender-2.62/source/blender/makesdna/DNA_meta_types.h --- blender-2.61/source/blender/makesdna/DNA_meta_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_meta_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -24,13 +24,14 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_META_TYPES_H -#define DNA_META_TYPES_H /** \file DNA_meta_types.h * \ingroup DNA */ +#ifndef DNA_META_TYPES_H +#define DNA_META_TYPES_H + #include "DNA_listBase.h" #include "DNA_ID.h" @@ -44,7 +45,6 @@ struct MetaElem *next, *prev; struct BoundBox *bb; /* Bound Box of MetaElem */ - int i1,j1,k1, i2,j2,k2; /* corners of Bounding Box in lattice */ short type, flag, selcol1, selcol2; float x, y, z; /* Position of center of MetaElem */ diff -Nru blender-2.61/source/blender/makesdna/DNA_modifier_types.h blender-2.62/source/blender/makesdna/DNA_modifier_types.h --- blender-2.61/source/blender/makesdna/DNA_modifier_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_modifier_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -18,13 +18,13 @@ * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_MODIFIER_TYPES_H -#define DNA_MODIFIER_TYPES_H - /** \file DNA_modifier_types.h * \ingroup DNA */ +#ifndef DNA_MODIFIER_TYPES_H +#define DNA_MODIFIER_TYPES_H + #include "DNA_defs.h" #include "DNA_listBase.h" @@ -76,6 +76,7 @@ eModifierType_WeightVGProximity, eModifierType_Ocean, eModifierType_DynamicPaint, + eModifierType_Remesh, NUM_MODIFIER_TYPES } ModifierType; @@ -95,7 +96,7 @@ int type, mode; int stackindex, pad; - char name[32]; + char name[64]; /* MAX_NAME */ /* XXX for timing info set by caller... solve later? (ton) */ struct Scene *scene; @@ -116,7 +117,7 @@ struct Tex *texture; struct Object *map_object; - char uvlayer_name[32]; + char uvlayer_name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ int uvlayer_tmp; int texmapping; } MappingInfoModifierData; @@ -133,14 +134,14 @@ ModifierData modifier; struct Object *object; - char name[32]; /* optional vertexgroup name */ + char name[64]; /* optional vertexgroup name, MAX_VGROUP_NAME */ } LatticeModifierData; typedef struct CurveModifierData { ModifierData modifier; struct Object *object; - char name[32]; /* optional vertexgroup name */ + char name[64]; /* optional vertexgroup name, MAX_VGROUP_NAME */ short defaxis; /* axis along which curve deforms */ char pad[6]; } CurveModifierData; @@ -165,7 +166,7 @@ ModifierData modifier; struct Object *ob_arm; /* armature to use to in place of hardcoded vgroup */ - char vgroup[32]; /* name of vertex group to use to mask */ + char vgroup[64]; /* name of vertex group to use to mask, MAX_VGROUP_NAME */ int mode; /* using armature or hardcoded vgroup */ int flag; /* flags for various things */ @@ -277,7 +278,7 @@ short lim_flags; /* flags to tell the tool how to limit the bevel */ short e_flags; /* flags to direct how edge weights are applied to verts */ float bevel_angle; /* if the BME_BEVEL_ANGLE is set, this will be how "sharp" an edge must be before it gets beveled */ - char defgrp_name[32]; /* if the BME_BEVEL_VWEIGHT option is set, this will be the name of the vert group */ + char defgrp_name[64]; /* if the BME_BEVEL_VWEIGHT option is set, this will be the name of the vert group, MAX_VGROUP_NAME */ } BevelModifierData; typedef struct BMeshModifierData { @@ -309,16 +310,16 @@ /* keep in sync with MappingInfoModifierData */ struct Tex *texture; struct Object *map_object; - char uvlayer_name[32]; + char uvlayer_name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ int uvlayer_tmp; int texmapping; - int pad10; /* end MappingInfoModifierData */ float strength; int direction; - char defgrp_name[32]; + char defgrp_name[64]; /* MAX_VGROUP_NAME */ float midlevel; + int pad; } DisplaceModifierData; /* DisplaceModifierData->direction */ @@ -335,7 +336,7 @@ MOD_DISP_MAP_LOCAL, MOD_DISP_MAP_GLOBAL, MOD_DISP_MAP_OBJECT, - MOD_DISP_MAP_UV, + MOD_DISP_MAP_UV }; typedef struct UVProjectModifierData { @@ -348,7 +349,7 @@ int num_projectors; float aspectx, aspecty; float scalex, scaley; - char uvlayer_name[32]; + char uvlayer_name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ int uvlayer_tmp, pad; } UVProjectModifierData; @@ -372,7 +373,7 @@ typedef struct SmoothModifierData { ModifierData modifier; float fac; - char defgrp_name[32]; + char defgrp_name[64]; /* MAX_VGROUP_NAME */ short flag, repeat; } SmoothModifierData; @@ -396,17 +397,10 @@ float fac; float radius; float size; - char defgrp_name[32]; + char defgrp_name[64]; /* MAX_VGROUP_NAME */ short flag, type; } CastModifierData; -enum { - MOD_WAV_MAP_LOCAL, - MOD_WAV_MAP_GLOBAL, - MOD_WAV_MAP_OBJECT, - MOD_WAV_MAP_UV, -}; - /* WaveModifierData.flag */ #define MOD_WAVE_X (1<<1) #define MOD_WAVE_Y (1<<2) @@ -419,20 +413,22 @@ typedef struct WaveModifierData { ModifierData modifier; - struct Object *objectcenter; - char defgrp_name[32]; + /* keep in sync with MappingInfoModifierData */ struct Tex *texture; struct Object *map_object; + char uvlayer_name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ + int uvlayer_tmp; + int texmapping; + /* end MappingInfoModifierData */ + + struct Object *objectcenter; + char defgrp_name[64]; /* MAX_VGROUP_NAME */ short flag, pad; float startx, starty, height, width; float narrow, speed, damp, falloff; - int texmapping, uvlayer_tmp; - - char uvlayer_name[32]; - float timeoffs, lifetime; float pad1; } WaveModifierData; @@ -444,14 +440,14 @@ int pad2; struct Object *object; float *prevCos; /* stored input of previous modifier, for vertexgroup blending */ - char defgrp_name[32]; + char defgrp_name[64]; /* MAX_VGROUP_NAME */ } ArmatureModifierData; typedef struct HookModifierData { ModifierData modifier; struct Object *object; - char subtarget[32]; /* optional name of bone target */ + char subtarget[64]; /* optional name of bone target, MAX_ID_NAME-2 */ float parentinv[4][4]; /* matrix making current transform unmodified */ float cent[3]; /* visualization of hook */ @@ -460,7 +456,7 @@ int *indexar; /* if NULL, it's using vertexgroup */ int totindex; float force; - char name[32]; /* optional vertexgroup name */ + char name[64]; /* optional vertexgroup name, MAX_VGROUP_NAME */ } HookModifierData; typedef struct SoftbodyModifierData { @@ -541,7 +537,7 @@ ModifierData modifier; struct Object *object; /* mesh object */ - char defgrp_name[32]; /* optional vertexgroup name */ + char defgrp_name[64]; /* optional vertexgroup name, MAX_VGROUP_NAME */ short gridsize, flag, mode, pad; @@ -617,7 +613,7 @@ int *facepa; short flag, vgroup; float protect; - char uvname[32]; + char uvname[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ } ExplodeModifierData; typedef struct MultiresModifierData { @@ -644,7 +640,7 @@ struct Object *target; /* shrink target */ struct Object *auxTarget; /* additional shrink target */ - char vgroup_name[32]; /* optional vertexgroup name */ + char vgroup_name[64]; /* optional vertexgroup name, MAX_VGROUP_NAME */ float keepDist; /* distance offset to keep from mesh/projection point */ short shrinkType; /* shrink type projection */ short shrinkOpts; /* shrink options */ @@ -684,7 +680,7 @@ ModifierData modifier; struct Object *origin; /* object to control the origin of modifier space coordinates */ - char vgroup_name[32]; /* optional vertexgroup name */ + char vgroup_name[64]; /* optional vertexgroup name, MAX_VGROUP_NAME */ float factor; /* factors to control simple deforms */ float limit[2]; /* lower and upper limit */ @@ -704,7 +700,7 @@ #define MOD_SIMPLEDEFORM_LOCK_AXIS_Y (1<<1) /* indicates whether simple deform should use the local - coordinates or global coordinates of origin */ + * coordinates or global coordinates of origin */ #define MOD_SIMPLEDEFORM_ORIGIN_LOCAL (1<<0) #define MOD_UVPROJECT_MAX 10 @@ -716,7 +712,7 @@ typedef struct SolidifyModifierData { ModifierData modifier; - char defgrp_name[32]; /* name of vertex group to use */ + char defgrp_name[64]; /* name of vertex group to use, MAX_VGROUP_NAME */ float offset; /* new surface offset level*/ float offset_fac; /* midpoint of the offset */ float offset_fac_vg; /* factor for the minimum weight to use when vgroups are used, avoids 0.0 weights giving duplicate geometry */ @@ -777,8 +773,8 @@ int bakestart; int bakeend; - char cachepath[240]; // FILE_MAX - char foamlayername[32]; + char cachepath[1024]; // FILE_MAX + char foamlayername[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ char cached; char geometry_mode; @@ -818,22 +814,20 @@ /* keep in sync with MappingInfoModifierData */ struct Tex *texture; struct Object *map_object; - char uvlayer_name[32]; + char uvlayer_name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ int uvlayer_tmp; int texmapping; - int pad10; /* end MappingInfoModifierData */ - float strength; - struct Object *object_from; struct Object *object_to; struct CurveMapping *curfalloff; - char defgrp_name[32]; /* optional vertexgroup name */ + char defgrp_name[64]; /* optional vertexgroup name, MAX_VGROUP_NAME */ + float strength; float falloff_radius; char flag; /* not used yet */ char falloff_type; - char pad[2]; + char pad[6]; } WarpModifierData; #define MOD_WARP_VOLUME_PRESERVE 1 @@ -856,7 +850,7 @@ /* Note: I tried to keep everything logically ordered - provided the * alignment constraints... */ - char defgrp_name[32]; /* Name of vertex group to edit. */ + char defgrp_name[64]; /* Name of vertex group to edit. MAX_VGROUP_NAME. */ short edit_flags; /* Using MOD_WVG_EDIT_* flags. */ short falloff_type; /* Using MOD_WVG_MAPPING_* defines. */ @@ -871,7 +865,7 @@ /* Masking options. */ float mask_constant; /* The global "influence", if no vgroup nor tex is used as mask. */ /* Name of mask vertex group from which to get weight factors. */ - char mask_defgrp_name[32]; + char mask_defgrp_name[64]; /* MAX_VGROUP_NAME */ /* Texture masking. */ int mask_tex_use_channel; /* Which channel to use as weightf. */ @@ -879,7 +873,7 @@ struct Object *mask_tex_map_obj; /* Name of the map object. */ /* How to map the texture (using MOD_DISP_MAP_* constants). */ int mask_tex_mapping; - char mask_tex_uvlayer_name[32]; /* Name of the UV map. */ + char mask_tex_uvlayer_name[64]; /* Name of the UV map. MAX_CUSTOMDATA_LAYER_NAME */ /* Padding... */ int pad_i1; @@ -905,8 +899,8 @@ /* XXX Note: I tried to keep everything logically ordered – provided the * alignment constraints... */ - char defgrp_name_a[32]; /* Name of vertex group to modify/weight. */ - char defgrp_name_b[32]; /* Name of other vertex group to mix in. */ + char defgrp_name_a[64]; /* Name of vertex group to modify/weight. MAX_VGROUP_NAME. */ + char defgrp_name_b[64]; /* Name of other vertex group to mix in. MAX_VGROUP_NAME. */ float default_weight_a; /* Default weight value for first vgroup. */ float default_weight_b; /* Default weight value to mix in. */ char mix_mode; /* How second vgroups weights affect first ones */ @@ -917,14 +911,14 @@ /* Masking options. */ float mask_constant; /* The global "influence", if no vgroup nor tex is used as mask. */ /* Name of mask vertex group from which to get weight factors. */ - char mask_defgrp_name[32]; + char mask_defgrp_name[64]; /* MAX_VGROUP_NAME */ /* Texture masking. */ int mask_tex_use_channel; /* Which channel to use as weightf. */ struct Tex *mask_texture; /* The texture. */ struct Object *mask_tex_map_obj; /* Name of the map object. */ int mask_tex_mapping; /* How to map the texture! */ - char mask_tex_uvlayer_name[32]; /* Name of the UV map. */ + char mask_tex_uvlayer_name[64]; /* Name of the UV map. MAX_CUSTOMDATA_LAYER_NAME. */ /* Padding... */ int pad_i1; @@ -952,7 +946,7 @@ /* Note: I tried to keep everything logically ordered - provided the * alignment constraints... */ - char defgrp_name[32]; /* Name of vertex group to modify/weight. */ + char defgrp_name[64]; /* Name of vertex group to modify/weight. MAX_VGROUP_NAME. */ /* Proximity modes. */ int proximity_mode; @@ -964,14 +958,14 @@ /* Masking options. */ float mask_constant; /* The global "influence", if no vgroup nor tex is used as mask. */ /* Name of mask vertex group from which to get weight factors. */ - char mask_defgrp_name[32]; + char mask_defgrp_name[64]; /* MAX_VGROUP_NAME */ /* Texture masking. */ int mask_tex_use_channel; /* Which channel to use as weightf. */ struct Tex *mask_texture; /* The texture. */ struct Object *mask_tex_map_obj; /* Name of the map object. */ int mask_tex_mapping; /* How to map the texture! */ - char mask_tex_uvlayer_name[32]; /* Name of the UV Map. */ + char mask_tex_uvlayer_name[64]; /* Name of the UV Map. MAX_CUSTOMDATA_LAYER_NAME. */ float min_dist, max_dist; /* Distances mapping to 0.0/1.0 weights. */ @@ -1032,4 +1026,39 @@ int pad; } DynamicPaintModifierData; +/* Remesh modifier */ + +typedef enum RemeshModifierFlags { + MOD_REMESH_FLOOD_FILL = 1, +} RemeshModifierFlags; + +typedef enum RemeshModifierMode { + /* blocky */ + MOD_REMESH_CENTROID = 0, + /* smooth */ + MOD_REMESH_MASS_POINT = 1, + /* keeps sharp edges */ + MOD_REMESH_SHARP_FEATURES = 2, +} RemeshModifierMode; + +typedef struct RemeshModifierData { + ModifierData modifier; + + /* floodfill option, controls how small components can be + before they are removed */ + float threshold; + + /* ratio between size of model and grid */ + float scale; + + float hermite_num; + + /* octree depth */ + char depth; + + char flag; + char mode; + char pad; +} RemeshModifierData; + #endif diff -Nru blender-2.61/source/blender/makesdna/DNA_movieclip_types.h blender-2.62/source/blender/makesdna/DNA_movieclip_types.h --- blender-2.61/source/blender/makesdna/DNA_movieclip_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_movieclip_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -26,15 +26,15 @@ * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_MOVIECLIP_TYPES_H -#define DNA_MOVIECLIP_TYPES_H - /** \file DNA_movieclip_types.h * \ingroup DNA * \since may-2011 * \author Sergey Sharybin */ +#ifndef DNA_MOVIECLIP_TYPES_H +#define DNA_MOVIECLIP_TYPES_H + #include "DNA_ID.h" #include "DNA_tracking_types.h" @@ -51,20 +51,18 @@ } MovieClipUser; typedef struct MovieClipProxy { - char dir[160]; /* custom directory for index and proxy files (defaults to BL_proxy) */ + char dir[768]; /* 768=FILE_MAXDIR custom directory for index and proxy files (defaults to BL_proxy) */ short tc; /* time code in use */ short quality; /* proxy build quality */ short build_size_flag; /* size flags (see below) of all proxies to build */ short build_tc_flag; /* time code flags (see below) of all tc indices to build */ - short build_flag, pad; /* other build flags */ - char pad2[4]; } MovieClipProxy; typedef struct MovieClip { ID id; - char name[240]; /* file path */ + char name[1024]; /* file path, 1024 = FILE_MAX */ int source; /* sequence or movie */ int lastframe; /* last accessed frame number */ @@ -98,8 +96,15 @@ float slide_scale[2]; /* scale used for sliding from previewe area */ } MovieClipScopes; -/* MovieClipProxy->build_flag */ -#define MCLIP_PROXY_BUILD_UNDISTORT 1 /* build undistorted proxies as well */ +/* MovieClipProxy->build_size_flag */ +#define MCLIP_PROXY_SIZE_25 (1<<0) +#define MCLIP_PROXY_SIZE_50 (1<<1) +#define MCLIP_PROXY_SIZE_75 (1<<2) +#define MCLIP_PROXY_SIZE_100 (1<<3) +#define MCLIP_PROXY_UNDISTORTED_SIZE_25 (1<<4) +#define MCLIP_PROXY_UNDISTORTED_SIZE_50 (1<<5) +#define MCLIP_PROXY_UNDISTORTED_SIZE_75 (1<<6) +#define MCLIP_PROXY_UNDISTORTED_SIZE_100 (1<<7) /* MovieClip->source */ #define MCLIP_SRC_SEQUENCE 1 @@ -113,6 +118,8 @@ #define MCLIP_USE_PROXY (1<<0) #define MCLIP_USE_PROXY_CUSTOM_DIR (1<<1) +#define MCLIP_TIMECODE_FLAGS (MCLIP_USE_PROXY|MCLIP_USE_PROXY_CUSTOM_DIR) + /* MovieClip->render_size */ #define MCLIP_PROXY_RENDER_SIZE_FULL 0 #define MCLIP_PROXY_RENDER_SIZE_25 1 diff -Nru blender-2.61/source/blender/makesdna/DNA_nla_types.h blender-2.62/source/blender/makesdna/DNA_nla_types.h --- blender-2.61/source/blender/makesdna/DNA_nla_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_nla_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -25,13 +25,13 @@ * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_NLA_TYPES_H -#define DNA_NLA_TYPES_H - /** \file DNA_nla_types.h * \ingroup DNA */ +#ifndef DNA_NLA_TYPES_H +#define DNA_NLA_TYPES_H + #include "DNA_listBase.h" struct bAction; diff -Nru blender-2.61/source/blender/makesdna/DNA_node_types.h blender-2.62/source/blender/makesdna/DNA_node_types.h --- blender-2.61/source/blender/makesdna/DNA_node_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_node_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -25,13 +25,13 @@ * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_NODE_TYPES_H -#define DNA_NODE_TYPES_H - /** \file DNA_node_types.h * \ingroup DNA */ +#ifndef DNA_NODE_TYPES_H +#define DNA_NODE_TYPES_H + #include "DNA_ID.h" #include "DNA_vec_types.h" #include "DNA_listBase.h" @@ -49,7 +49,7 @@ struct uiBlock; struct Image; -#define NODE_MAXSTR 32 +#define NODE_MAXSTR 64 typedef struct bNodeStack { float vec[4]; @@ -71,7 +71,7 @@ typedef struct bNodeSocket { struct bNodeSocket *next, *prev, *new_sock; - char name[32]; + char name[64]; /* MAX_NAME */ void *storage; /* custom storage */ @@ -85,19 +85,21 @@ /* execution data */ short stack_index; /* local stack index */ - short stack_type; /* deprecated, kept for forward compatibility */ + /* XXX deprecated, kept for forward compatibility */ + short stack_type DNA_DEPRECATED; int pad3; void *cache; /* cached data from execution */ /* internal data to retrieve relations and groups */ int own_index; /* group socket identifiers, to find matching pairs after reading files */ - int to_index DNA_DEPRECATED; /* XXX deprecated, only used for restoring old group node links */ + /* XXX deprecated, only used for restoring old group node links */ + int to_index DNA_DEPRECATED; struct bNodeSocket *groupsock; struct bNodeLink *link; /* a link pointer, set in ntreeUpdateTree */ - /* DEPRECATED only needed for do_versions */ - bNodeStack ns; /* custom data for inputs, only UI writes in this */ + /* XXX deprecated, socket input values are stored in default_value now. kept for forward compatibility */ + bNodeStack ns DNA_DEPRECATED; /* custom data for inputs, only UI writes in this */ } bNodeSocket; /* sock->type */ @@ -129,6 +131,8 @@ #define SOCK_COLLAPSED 64 /* hide socket value, if it gets auto default */ #define SOCK_HIDE_VALUE 128 + /* socket hidden automatically, to distinguish from manually hidden */ +#define SOCK_AUTO_HIDDEN 256 typedef struct bNodePreview { unsigned char *rect; @@ -140,7 +144,7 @@ typedef struct bNode { struct bNode *next, *prev, *new_node; - char name[32]; + char name[64]; /* MAX_NAME */ short type, flag; short done, level; /* both for dependency and sorting */ short lasty, menunr; /* lasty: check preview render status, menunr: browse ID blocks */ @@ -158,7 +162,7 @@ int update; /* update flags */ - char label[32]; /* custom user-defined label */ + char label[64]; /* custom user-defined label, MAX_NAME */ short custom1, custom2; /* to be abused for buttons */ float custom3, custom4; @@ -345,7 +349,7 @@ } NodeHueSat; typedef struct NodeImageFile { - char name[256]; + char name[1024]; /* 1024 = FILE_MAX */ struct ImageFormatData im_format; int sfra, efra; } NodeImageFile; @@ -354,12 +358,12 @@ float t1,t2,t3; float fsize,fstrength,falpha; float key[4]; - short algorithm, channel; + short algorithm, channel; } NodeChroma; typedef struct NodeTwoXYs { short x1, x2, y1, y2; - float fac_x1, fac_x2, fac_y1, fac_y2; + float fac_x1, fac_x2, fac_y1, fac_y2; } NodeTwoXYs; typedef struct NodeTwoFloats { @@ -367,12 +371,12 @@ } NodeTwoFloats; typedef struct NodeGeometry { - char uvname[32]; - char colname[32]; + char uvname[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ + char colname[64]; } NodeGeometry; typedef struct NodeVertexCol { - char name[32]; + char name[64]; } NodeVertexCol; /* qdn: Defocus blur node */ @@ -428,7 +432,7 @@ short limchan, unspill; float limscale; float uspillr, uspillg, uspillb; -}NodeColorspill; +} NodeColorspill; typedef struct NodeTexBase { TexMapping tex_mapping; @@ -446,6 +450,10 @@ int color_space, pad; } NodeTexImage; +typedef struct NodeTexChecker { + NodeTexBase base; +} NodeTexChecker; + typedef struct NodeTexEnvironment { NodeTexBase base; int color_space, pad; @@ -491,7 +499,7 @@ /* TEX_output */ typedef struct TexNodeOutput { - char name[32]; + char name[64]; } TexNodeOutput; /* comp channel matte */ diff -Nru blender-2.61/source/blender/makesdna/DNA_object_fluidsim.h blender-2.62/source/blender/makesdna/DNA_object_fluidsim.h --- blender-2.61/source/blender/makesdna/DNA_object_fluidsim.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_object_fluidsim.h 2012-02-15 19:34:32.000000000 +0000 @@ -26,13 +26,14 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_OBJECT_FLUIDSIM_H -#define DNA_OBJECT_FLUIDSIM_H /** \file DNA_object_fluidsim.h * \ingroup DNA */ +#ifndef DNA_OBJECT_FLUIDSIM_H +#define DNA_OBJECT_FLUIDSIM_H + #include "DNA_ID.h" #ifdef __cplusplus @@ -73,6 +74,9 @@ float animStart, animEnd; /* bake start end time (in blender frames) */ int bakeStart, bakeEnd; + /* offset for baked frames */ + int frameOffset; + int pad; /* g star param (LBM compressibility) */ float gstar; /* activate refinement? */ @@ -88,8 +92,8 @@ struct Mesh *meshBB; /* store output path, and file prefix for baked fluid surface */ - /* strlens; 80= FILE_MAXFILE, 160= FILE_MAXDIR */ - char surfdataPath[240]; + /* strlens; 256= FILE_MAXFILE, 768= FILE_MAXDIR */ + char surfdataPath[1024]; /* store start coords of axis aligned bounding box together with size */ /* values are inited during derived mesh display */ @@ -139,8 +143,8 @@ int lastgoodframe; - int pad; - + /* Simulation/flow rate control (i.e. old "Fac-Time") */ + float animRate; } FluidsimSettings; /* ob->fluidsimSettings defines */ diff -Nru blender-2.61/source/blender/makesdna/DNA_object_force.h blender-2.62/source/blender/makesdna/DNA_object_force.h --- blender-2.61/source/blender/makesdna/DNA_object_force.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_object_force.h 2012-02-15 19:34:32.000000000 +0000 @@ -26,13 +26,14 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_OBJECT_FORCE_H -#define DNA_OBJECT_FORCE_H /** \file DNA_object_force.h * \ingroup DNA */ +#ifndef DNA_OBJECT_FORCE_H +#define DNA_OBJECT_FORCE_H + #ifdef __cplusplus extern "C" { #endif @@ -185,6 +186,8 @@ int endframe; /* simulation end frame */ int editframe; /* frame being edited (runtime only) */ int last_exact; /* last exact frame that's cached */ + int last_valid; /* used for editing cache - what is the last baked frame */ + int pad; /* for external cache files */ int totpoint; /* number of cached points */ @@ -194,7 +197,7 @@ char name[64]; char prev_name[64]; char info[64]; - char path[240]; /* file path */ + char path[1024]; /* file path, 1024 = FILE_MAX */ char *cached_frames; /* array of length endframe-startframe+1 with flags to indicate cached frames */ /* can be later used for other per frame flags too if needed */ struct ListBase mem_cache; @@ -273,7 +276,7 @@ /* general options */ float nodemass; /* softbody mass of *vertex* */ - char namedVG_Mass[32]; /* along with it introduce mass painting + char namedVG_Mass[64]; /* MAX_VGROUP_NAME */ /* along with it introduce mass painting starting to fix old bug .. nastyness that VG are indexes rather find them by name tag to find it -> jow20090613 */ float grav; /* softbody amount of gravitaion to apply */ @@ -288,7 +291,7 @@ float maxgoal; float defgoal; /* default goal for vertices without vgroup */ short vertgroup; /* index starting at 1 */ - char namedVG_Softgoal[32]; /* starting to fix old bug .. nastyness that VG are indexes + char namedVG_Softgoal[64]; /* MAX_VGROUP_NAME */ /* starting to fix old bug .. nastyness that VG are indexes rather find them by name tag to find it -> jow20090613 */ short fuzzyness; /* */ @@ -296,7 +299,7 @@ /* springs */ float inspring; /* softbody inner springs */ float infrict; /* softbody inner springs friction */ - char namedVG_Spring_K[32]; /* along with it introduce Spring_K painting + char namedVG_Spring_K[64]; /* MAX_VGROUP_NAME */ /* along with it introduce Spring_K painting starting to fix old bug .. nastyness that VG are indexes rather find them by name tag to find it -> jow20090613 */ @@ -336,8 +339,8 @@ float lcom[3]; float lrot[3][3]; float lscale[3][3]; - char pad4[4]; + int last_frame; } SoftBody; diff -Nru blender-2.61/source/blender/makesdna/DNA_object_types.h blender-2.62/source/blender/makesdna/DNA_object_types.h --- blender-2.61/source/blender/makesdna/DNA_object_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_object_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -24,14 +24,15 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_OBJECT_TYPES_H -#define DNA_OBJECT_TYPES_H /** \file DNA_object_types.h * \ingroup DNA * \brief Object is a sort of wrapper for general info. */ +#ifndef DNA_OBJECT_TYPES_H +#define DNA_OBJECT_TYPES_H + #include "DNA_defs.h" #include "DNA_listBase.h" #include "DNA_ID.h" @@ -60,11 +61,11 @@ /* Vertex Groups - Name Info */ typedef struct bDeformGroup { struct bDeformGroup *next, *prev; - char name[32]; + char name[64]; /* MAX_VGROUP_NAME */ /* need this flag for locking weights */ char flag, pad[7]; } bDeformGroup; -#define MAX_VGROUP_NAME 32 +#define MAX_VGROUP_NAME 64 /* bDeformGroup->flag */ #define DG_LOCK_WEIGHT 1 @@ -106,7 +107,7 @@ short type, partype; int par1, par2, par3; /* can be vertexnrs */ - char parsubstr[32]; /* String describing subobject info */ + char parsubstr[64]; /* String describing subobject info, MAX_ID_NAME-2 */ struct Object *parent, *track; /* if ob->proxy (or proxy_group), this object is proxy for object ob->proxy */ /* proxy_from is set in target back to the proxy. */ @@ -250,8 +251,8 @@ struct FluidsimSettings *fluidsimSettings; /* if fluidsim enabled, store additional settings */ struct DerivedMesh *derivedDeform, *derivedFinal; - unsigned int lastDataMask; /* the custom data layer mask that was last used to calculate derivedDeform and derivedFinal */ - unsigned int customdata_mask; /* (extra) custom data layer mask to use for creating derivedmesh, set by depsgraph */ + uint64_t lastDataMask; /* the custom data layer mask that was last used to calculate derivedDeform and derivedFinal */ + uint64_t customdata_mask; /* (extra) custom data layer mask to use for creating derivedmesh, set by depsgraph */ unsigned int state; /* bit masks of game controllers that are active */ unsigned int init_state; /* bit masks of initial state as recorded by the users */ @@ -272,7 +273,7 @@ float cent[3]; /* visualization of hook */ float falloff; /* if not zero, falloff is distance where influence zero */ - char name[32]; + char name[64]; /* MAX_NAME */ int *indexar; int totindex, curindex; /* curindex is cache for fast lookup */ diff -Nru blender-2.61/source/blender/makesdna/DNA_outliner_types.h blender-2.62/source/blender/makesdna/DNA_outliner_types.h --- blender-2.61/source/blender/makesdna/DNA_outliner_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_outliner_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -24,13 +24,14 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_OUTLINER_TYPES_H -#define DNA_OUTLINER_TYPES_H /** \file DNA_outliner_types.h * \ingroup DNA */ +#ifndef DNA_OUTLINER_TYPES_H +#define DNA_OUTLINER_TYPES_H + #include "DNA_listBase.h" struct ID; diff -Nru blender-2.61/source/blender/makesdna/DNA_packedFile_types.h blender-2.62/source/blender/makesdna/DNA_packedFile_types.h --- blender-2.61/source/blender/makesdna/DNA_packedFile_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_packedFile_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -25,15 +25,15 @@ * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_PACKEDFILE_TYPES_H -#define DNA_PACKEDFILE_TYPES_H - /** \file DNA_packedFile_types.h * \ingroup DNA * \author nzc * \since 12-oct-2000 nzc */ +#ifndef DNA_PACKEDFILE_TYPES_H +#define DNA_PACKEDFILE_TYPES_H + typedef struct PackedFile { int size; int seek; diff -Nru blender-2.61/source/blender/makesdna/DNA_particle_types.h blender-2.62/source/blender/makesdna/DNA_particle_types.h --- blender-2.61/source/blender/makesdna/DNA_particle_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_particle_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -25,13 +25,13 @@ * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_PARTICLE_TYPES_H -#define DNA_PARTICLE_TYPES_H - /** \file DNA_particle_types.h * \ingroup DNA */ +#ifndef DNA_PARTICLE_TYPES_H +#define DNA_PARTICLE_TYPES_H + #include "DNA_defs.h" #include "DNA_ID.h" #include "DNA_boid_types.h" @@ -65,7 +65,7 @@ typedef struct ParticleSpring { float rest_length; unsigned int particle_index[2], delete_flag; -}ParticleSpring; +} ParticleSpring; /* Child particles are created around or between parent particles */ typedef struct ChildParticle { @@ -261,7 +261,7 @@ struct ListBase targets; /* used for keyed and boid physics */ - char name[32]; /* particle system name */ + char name[64]; /* particle system name, MAX_NAME */ float imat[4][4]; /* used for duplicators */ float cfra, tree_frame, bvhtree_frame; @@ -269,7 +269,7 @@ int flag, totpart, totunexist, totchild, totcached, totchildcache; short recalc, target_psys, totkeyed, bakespace; - char bb_uvname[3][32]; /* billboard uv name */ + char bb_uvname[3][64]; /* billboard uv name, MAX_CUSTOMDATA_LAYER_NAME */ /* if you change these remember to update array lengths to PSYS_TOT_VG! */ short vgroup[12], vg_neg, rt3; /* vertex groups, 0==disable, 1==starting index */ @@ -295,7 +295,7 @@ float dt_frac; /* current time step, as a fraction of a frame */ float _pad; /* spare capacity */ -}ParticleSystem; +} ParticleSystem; /* part->type */ /* hair is allways baked static in object/geometry space */ diff -Nru blender-2.61/source/blender/makesdna/DNA_property_types.h blender-2.62/source/blender/makesdna/DNA_property_types.h --- blender-2.61/source/blender/makesdna/DNA_property_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_property_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -27,8 +27,6 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_PROPERTY_TYPES_H -#define DNA_PROPERTY_TYPES_H /** \file DNA_property_types.h * \ingroup DNA @@ -38,11 +36,14 @@ * hierarchy here is a bit strange, and not desirable. */ +#ifndef DNA_PROPERTY_TYPES_H +#define DNA_PROPERTY_TYPES_H + /* ********************* PROPERTY ************************ */ typedef struct bProperty { struct bProperty *next, *prev; - char name[32]; + char name[64]; /* MAX_NAME */ short type, flag; int data; /* data should be 4 bytes to store int,float stuff */ void *poin; /* references data unless its a string which is malloc'd */ diff -Nru blender-2.61/source/blender/makesdna/DNA_scene_types.h blender-2.62/source/blender/makesdna/DNA_scene_types.h --- blender-2.61/source/blender/makesdna/DNA_scene_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_scene_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -24,13 +24,14 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_SCENE_TYPES_H -#define DNA_SCENE_TYPES_H /** \file DNA_scene_types.h * \ingroup DNA */ +#ifndef DNA_SCENE_TYPES_H +#define DNA_SCENE_TYPES_H + #include "DNA_defs.h" // XXX, temp feature - campbell @@ -58,6 +59,10 @@ struct bGPdata; struct MovieClip; +/* ************************************************************* */ +/* Scene Data */ + +/* Base - Wrapper for referencing Objects in a Scene */ typedef struct Base { struct Base *next, *prev; unsigned int lay, selcol; @@ -66,6 +71,9 @@ struct Object *object; } Base; +/* ************************************************************* */ +/* Output Format Data */ + typedef struct AviCodecData { void *lpFormat; /* save format */ void *lpParms; /* compressor options */ @@ -141,6 +149,8 @@ IDProperty *properties; } FFMpegCodecData; +/* ************************************************************* */ +/* Audio */ typedef struct AudioData { int mixrate; // 2.5: now in FFMpegCodecData: audio_mixrate @@ -154,10 +164,14 @@ float pad2; } AudioData; +/* *************************************************************** */ +/* Render Layers */ + +/* Render Layer */ typedef struct SceneRenderLayer { struct SceneRenderLayer *next, *prev; - char name[32]; + char name[64]; /* MAX_NAME */ struct Material *mat_override; struct Group *light_override; @@ -188,28 +202,38 @@ #define SCE_LAY_NEG_ZMASK 0x80000 /* srl->passflag */ -#define SCE_PASS_COMBINED (1<<0) -#define SCE_PASS_Z (1<<1) -#define SCE_PASS_RGBA (1<<2) -#define SCE_PASS_DIFFUSE (1<<3) -#define SCE_PASS_SPEC (1<<4) -#define SCE_PASS_SHADOW (1<<5) -#define SCE_PASS_AO (1<<6) -#define SCE_PASS_REFLECT (1<<7) -#define SCE_PASS_NORMAL (1<<8) -#define SCE_PASS_VECTOR (1<<9) -#define SCE_PASS_REFRACT (1<<10) -#define SCE_PASS_INDEXOB (1<<11) -#define SCE_PASS_UV (1<<12) -#define SCE_PASS_INDIRECT (1<<13) -#define SCE_PASS_MIST (1<<14) -#define SCE_PASS_RAYHITS (1<<15) -#define SCE_PASS_EMIT (1<<16) -#define SCE_PASS_ENVIRONMENT (1<<17) -#define SCE_PASS_INDEXMA (1<<18) +#define SCE_PASS_COMBINED (1<<0) +#define SCE_PASS_Z (1<<1) +#define SCE_PASS_RGBA (1<<2) +#define SCE_PASS_DIFFUSE (1<<3) +#define SCE_PASS_SPEC (1<<4) +#define SCE_PASS_SHADOW (1<<5) +#define SCE_PASS_AO (1<<6) +#define SCE_PASS_REFLECT (1<<7) +#define SCE_PASS_NORMAL (1<<8) +#define SCE_PASS_VECTOR (1<<9) +#define SCE_PASS_REFRACT (1<<10) +#define SCE_PASS_INDEXOB (1<<11) +#define SCE_PASS_UV (1<<12) +#define SCE_PASS_INDIRECT (1<<13) +#define SCE_PASS_MIST (1<<14) +#define SCE_PASS_RAYHITS (1<<15) +#define SCE_PASS_EMIT (1<<16) +#define SCE_PASS_ENVIRONMENT (1<<17) +#define SCE_PASS_INDEXMA (1<<18) +#define SCE_PASS_DIFFUSE_DIRECT (1<<19) +#define SCE_PASS_DIFFUSE_INDIRECT (1<<20) +#define SCE_PASS_DIFFUSE_COLOR (1<<21) +#define SCE_PASS_GLOSSY_DIRECT (1<<22) +#define SCE_PASS_GLOSSY_INDIRECT (1<<23) +#define SCE_PASS_GLOSSY_COLOR (1<<24) +#define SCE_PASS_TRANSM_DIRECT (1<<25) +#define SCE_PASS_TRANSM_INDIRECT (1<<26) +#define SCE_PASS_TRANSM_COLOR (1<<27) /* note, srl->passflag is treestore element 'nr' in outliner, short still... */ +/* *************************************************************** */ /* Generic image format settings, * this is used for NodeImageFile and IMAGE_OT_save_as operator too. @@ -313,6 +337,9 @@ /* ImageFormatData.cineon_flag */ #define R_IMF_CINEON_FLAG_LOG (1<<0) /* was R_CINEON_LOG */ +/* *************************************************************** */ +/* Render Data */ + typedef struct RenderData { struct ImageFormatData im_format; @@ -332,9 +359,15 @@ /** For UR edge rendering: give the edges this color */ float edgeR, edgeG, edgeB; - - short fullscreen DNA_DEPRECATED, xplay DNA_DEPRECATED, yplay DNA_DEPRECATED, freqplay DNA_DEPRECATED; /* standalone player */ // XXX deprecated since 2.5 - short depth DNA_DEPRECATED, attrib DNA_DEPRECATED; /* standalone player */ // XXX deprecated since 2.5 + + + /* standalone player */ // XXX deprecated since 2.5 + short fullscreen DNA_DEPRECATED, xplay DNA_DEPRECATED, yplay DNA_DEPRECATED; + short freqplay DNA_DEPRECATED; + /* standalone player */ // XXX deprecated since 2.5 + short depth DNA_DEPRECATED, attrib DNA_DEPRECATED; + + int frame_step; /* frames to jump during render/playback */ short stereomode DNA_DEPRECATED; /* standalone player stereo settings */ // XXX deprecated since 2.5 @@ -447,14 +480,14 @@ float bake_maxdist, bake_biasdist, bake_pad; /* path to render output */ - char pic[240]; + char pic[1024]; /* 1024 = FILE_MAX */ /* stamps flags. */ int stamp; short stamp_font_id, pad3; /* select one of blenders bitmap fonts */ /* stamp info user data. */ - char stamp_udata[160]; + char stamp_udata[768]; /* foreground/background color. */ float fg_stamp[4]; @@ -492,6 +525,9 @@ char engine[32]; } RenderData; +/* *************************************************************** */ +/* Render Conversion/Simplfication Settings */ + /* control render convert and shading engine */ typedef struct RenderProfile { struct RenderProfile *next, *prev; @@ -506,6 +542,9 @@ } RenderProfile; +/* *************************************************************** */ +/* Game Engine - Dome */ + typedef struct GameDome { short res, mode; short angle, tilt; @@ -520,6 +559,9 @@ #define DOME_PANORAM_SPH 5 #define DOME_NUM_MODES 6 +/* *************************************************************** */ +/* Game Engine */ + typedef struct GameFraming { float col[3]; char type, pad1, pad2, pad3; @@ -550,8 +592,9 @@ /* standalone player */ struct GameFraming framing; - short fullscreen, xplay, yplay, freqplay; + short playerflag, xplay, yplay, freqplay; short depth, attrib, rt1, rt2; + short aasamples, pad4[3]; /* stereo/dome mode */ struct GameDome dome; @@ -576,7 +619,7 @@ short mode, matmode; short occlusionRes; /* resolution of occlusion Z buffer in pixel */ short physicsEngine; - short pad[2]; + short exitkey, pad; short ticrate, maxlogicstep, physubstep, maxphystep; short obstacleSimulation, pad1; float levelHeight; @@ -628,12 +671,29 @@ #define GAME_SHOW_OBSTACLE_SIMULATION (1 << 16) /* Note: GameData.flag is now an int (max 32 flags). A short could only take 16 flags */ +/* GameData.playerflag */ +#define GAME_PLAYER_FULLSCREEN (1 << 0) +#define GAME_PLAYER_DESKTOP_RESOLUTION (1 << 1) + /* GameData.matmode */ #define GAME_MAT_TEXFACE 0 #define GAME_MAT_MULTITEX 1 #define GAME_MAT_GLSL 2 -typedef struct TimeMarker { +/* UV Paint */ +#define UV_SCULPT_LOCK_BORDERS 1 +#define UV_SCULPT_ALL_ISLANDS 2 + +#define UV_SCULPT_TOOL_PINCH 1 +#define UV_SCULPT_TOOL_RELAX 2 +#define UV_SCULPT_TOOL_GRAB 3 + +#define UV_SCULPT_TOOL_RELAX_LAPLACIAN 1 +#define UV_SCULPT_TOOL_RELAX_HC 2 + +/* Markers */ + +typedef struct TimeMarker { struct TimeMarker *next, *prev; int frame; char name[64]; @@ -641,6 +701,10 @@ struct Object *camera; } TimeMarker; +/* *************************************************************** */ +/* Paint Mode/Tool Data */ + +/* Paint Tool Base */ typedef struct Paint { struct Brush *brush; @@ -651,6 +715,10 @@ int flags; } Paint; +/* ------------------------------------------- */ +/* Image Paint */ + +/* Texture/Image Editor */ typedef struct ImagePaintSettings { Paint paint; @@ -665,6 +733,10 @@ void *paintcursor; /* wm handle */ } ImagePaintSettings; +/* ------------------------------------------- */ +/* Particle Edit */ + +/* Settings for a Particle Editing Brush */ typedef struct ParticleBrushData { short size; /* common setting */ short step, invert, count; /* for specific brushes only */ @@ -672,6 +744,7 @@ float strength; } ParticleBrushData; +/* Particle Edit Mode Settings */ typedef struct ParticleEditSettings { short flag; short totrekey; @@ -692,12 +765,10 @@ struct Object *object; } ParticleEditSettings; -typedef struct TransformOrientation { - struct TransformOrientation *next, *prev; - char name[36]; - float mat[3][3]; -} TransformOrientation; +/* ------------------------------------------- */ +/* Sculpt */ +/* Sculpt */ typedef struct Sculpt { Paint paint; @@ -728,6 +799,13 @@ int pad; } Sculpt; +typedef struct UvSculpt { + Paint paint; +} UvSculpt; +/* ------------------------------------------- */ +/* Vertex Paint */ + +/* Vertex Paint */ typedef struct VPaint { Paint paint; @@ -741,18 +819,65 @@ /* VPaint flag */ #define VP_COLINDEX 1 -#define VP_AREA 2 +#define VP_AREA 2 /* vertex paint only */ #define VP_NORMALS 8 #define VP_SPRAY 16 // #define VP_MIRROR_X 32 // deprecated in 2.5x use (me->editflag & ME_EDIT_MIRROR_X) -#define VP_ONLYVGROUP 128 +#define VP_ONLYVGROUP 128 /* weight paint only */ + +/* *************************************************************** */ +/* Transform Orientations */ + +typedef struct TransformOrientation { + struct TransformOrientation *next, *prev; + char name[64]; /* MAX_NAME */ + float mat[3][3]; + int pad; +} TransformOrientation; + +/* *************************************************************** */ +/* Unified Paint Settings */ + +/* These settings can override the equivalent fields in the active + Brush for any paint mode; the flag field controls whether these + values are used */ +typedef struct UnifiedPaintSettings { + /* unified radius of brush in pixels */ + int size; + + /* unified radius of brush in Blender units */ + float unprojected_radius; + + /* unified strength of brush */ + float alpha; + + /* user preferences for sculpt and paint */ + int flag; +} UnifiedPaintSettings; + +typedef enum { + UNIFIED_PAINT_SIZE = (1<<0), + UNIFIED_PAINT_ALPHA = (1<<1), + + /* only used if unified size is enabled, mirros the brush flags + BRUSH_LOCK_SIZE and BRUSH_SIZE_PRESSURE */ + UNIFIED_PAINT_BRUSH_LOCK_SIZE = (1<<2), + UNIFIED_PAINT_BRUSH_SIZE_PRESSURE = (1<<3), + + /* only used if unified alpha is enabled, mirrors the brush flag + BRUSH_ALPHA_PRESSURE */ + UNIFIED_PAINT_BRUSH_ALPHA_PRESSURE = (1<<4) +} UnifiedPaintSettingsFlags; +/* *************************************************************** */ +/* Tool Settings */ typedef struct ToolSettings { VPaint *vpaint; /* vertex paint */ VPaint *wpaint; /* weight paint */ Sculpt *sculpt; + UvSculpt *uvsculpt; /* uv smooth */ /* Vertex groups */ float vgroup_weight; @@ -792,7 +917,7 @@ short uvcalc_mapalign; short uvcalc_flag; short uv_flag, uv_selectmode; - short uv_pad; + short uv_subsurf_level; /* Grease Pencil */ short gpencil_flags; @@ -818,13 +943,9 @@ /* Auto-Keying Mode */ short autokey_mode, autokey_flag; /* defines in DNA_userdef_types.h */ - /* Retopo */ - char retopo_mode; - char retopo_paint_tool; - char line_div, ellipse_div, retopo_hotspot; - /* Multires */ char multires_subdiv_type; + char pad2[5]; /* Skeleton generation */ short skgen_resolution; @@ -868,33 +989,56 @@ char auto_normalize; /*auto normalizing mode in wpaint*/ char multipaint; /* paint multiple bones in wpaint */ - short sculpt_paint_settings; /* user preferences for sculpt and paint */ - short pad1; - int sculpt_paint_unified_size; /* unified radius of brush in pixels */ - float sculpt_paint_unified_unprojected_radius;/* unified radius of brush in Blender units */ - float sculpt_paint_unified_alpha; /* unified strength of brush */ + /* UV painting */ + int use_uv_sculpt; + int uv_sculpt_settings; + int uv_sculpt_tool; + int uv_relax_method; + /* XXX: these sculpt_paint_* fields are deprecated, use the + unified_paint_settings field instead! */ + short sculpt_paint_settings DNA_DEPRECATED; short pad1; + int sculpt_paint_unified_size DNA_DEPRECATED; + float sculpt_paint_unified_unprojected_radius DNA_DEPRECATED; + float sculpt_paint_unified_alpha DNA_DEPRECATED; + + /* Unified Paint Settings */ + struct UnifiedPaintSettings unified_paint_settings; } ToolSettings; +/* *************************************************************** */ +/* Assorted Scene Data */ + +/* ------------------------------------------- */ +/* Stats (show in Info header) */ + typedef struct bStats { /* scene totals for visible layers */ int totobj, totlamp, totobjsel, totcurve, totmesh, totarmature; int totvert, totface; } bStats; +/* ------------------------------------------- */ +/* Unit Settings */ + typedef struct UnitSettings { /* Display/Editing unit options for each scene */ float scale_length; /* maybe have other unit conversions? */ char system; /* imperial, metric etc */ char system_rotation; /* not implimented as a propper unit system yet */ short flag; - } UnitSettings; +/* ------------------------------------------- */ +/* Global/Common Physics Settings */ + typedef struct PhysicsSettings { float gravity[3]; int flag, quick_cache_step, rt; } PhysicsSettings; +/* *************************************************************** */ +/* Scene ID-Block */ + typedef struct Scene { ID id; struct AnimData *adt; /* animation data (must be immediately after id for utilities to use it) */ @@ -915,8 +1059,6 @@ unsigned int lay; /* bitflags for layer visibility */ int layact; /* active layer */ unsigned int lay_updated; /* runtime flag, has layer ever been updated since load? */ - unsigned int customdata_mask; /* XXX. runtime flag for drawing, actually belongs in the window, only used by object_handle_update() */ - unsigned int customdata_mask_modal; /* XXX. same as above but for temp operator use (gl renders) */ short flag; /* various settings */ @@ -954,7 +1096,7 @@ /* User-Defined KeyingSets */ int active_keyingset; /* index of the active KeyingSet. first KeyingSet has index 1, 'none' active is 0, 'add new' is -1 */ - ListBase keyingsets; /* KeyingSets for the given frame */ + ListBase keyingsets; /* KeyingSets for this scene */ /* Game Settings */ struct GameFraming framing DNA_DEPRECATED; // XXX deprecated since 2.5 @@ -971,6 +1113,9 @@ /* Movie Tracking */ struct MovieClip *clip; /* active movie clip */ + + uint64_t customdata_mask; /* XXX. runtime flag for drawing, actually belongs in the window, only used by object_handle_update() */ + uint64_t customdata_mask_modal; /* XXX. same as above but for temp operator use (gl renders) */ } Scene; @@ -1082,7 +1227,9 @@ #define R_STAMP_SEQSTRIP 0x0200 #define R_STAMP_RENDERTIME 0x0400 #define R_STAMP_CAMERALENS 0x0800 -#define R_STAMP_ALL (R_STAMP_TIME|R_STAMP_FRAME|R_STAMP_DATE|R_STAMP_CAMERA|R_STAMP_SCENE|R_STAMP_NOTE|R_STAMP_MARKER|R_STAMP_FILENAME|R_STAMP_SEQSTRIP|R_STAMP_RENDERTIME|R_STAMP_CAMERALENS) +#define R_STAMP_ALL (R_STAMP_TIME|R_STAMP_FRAME|R_STAMP_DATE|R_STAMP_CAMERA|R_STAMP_SCENE| \ + R_STAMP_NOTE|R_STAMP_MARKER|R_STAMP_FILENAME|R_STAMP_SEQSTRIP| \ + R_STAMP_RENDERTIME|R_STAMP_CAMERALENS) /* alphamode */ #define R_ADDSKY 0 @@ -1090,7 +1237,8 @@ #define R_ALPHAKEY 2 /* color_mgt_flag */ -#define R_COLOR_MANAGEMENT 1 +#define R_COLOR_MANAGEMENT (1 << 0) +#define R_COLOR_MANAGEMENT_PREDIVIDE (1 << 1) /* subimtype, flag options for imtype */ #define R_OPENEXR_HALF 1 /*deprecated*/ @@ -1140,12 +1288,31 @@ #define MINAFRAMEF -300000.0f /* depricate this! */ -#define TESTBASE(v3d, base) ( ((base)->flag & SELECT) && ((base)->lay & v3d->lay) && (((base)->object->restrictflag & OB_RESTRICT_VIEW)==0) ) -#define TESTBASELIB(v3d, base) ( ((base)->flag & SELECT) && ((base)->lay & v3d->lay) && ((base)->object->id.lib==NULL) && (((base)->object->restrictflag & OB_RESTRICT_VIEW)==0)) -#define TESTBASELIB_BGMODE(v3d, scene, base) ( ((base)->flag & SELECT) && ((base)->lay & (v3d ? v3d->lay : scene->lay)) && ((base)->object->id.lib==NULL) && (((base)->object->restrictflag & OB_RESTRICT_VIEW)==0)) -#define BASE_EDITABLE_BGMODE(v3d, scene, base) (((base)->lay & (v3d ? v3d->lay : scene->lay)) && ((base)->object->id.lib==NULL) && (((base)->object->restrictflag & OB_RESTRICT_VIEW)==0)) -#define BASE_SELECTABLE(v3d, base) ((base->lay & v3d->lay) && (base->object->restrictflag & (OB_RESTRICT_SELECT|OB_RESTRICT_VIEW))==0) -#define BASE_VISIBLE(v3d, base) ((base->lay & v3d->lay) && (base->object->restrictflag & OB_RESTRICT_VIEW)==0) +#define TESTBASE(v3d, base) ( \ + ((base)->flag & SELECT) && \ + ((base)->lay & v3d->lay) && \ + (((base)->object->restrictflag & OB_RESTRICT_VIEW)==0) ) +#define TESTBASELIB(v3d, base) ( \ + ((base)->flag & SELECT) && \ + ((base)->lay & v3d->lay) && \ + ((base)->object->id.lib==NULL) && \ + (((base)->object->restrictflag & OB_RESTRICT_VIEW)==0) ) +#define TESTBASELIB_BGMODE(v3d, scene, base) ( \ + ((base)->flag & SELECT) && \ + ((base)->lay & (v3d ? v3d->lay : scene->lay)) && \ + ((base)->object->id.lib==NULL) && \ + (((base)->object->restrictflag & OB_RESTRICT_VIEW)==0) ) +#define BASE_EDITABLE_BGMODE(v3d, scene, base) ( \ + ((base)->lay & (v3d ? v3d->lay : scene->lay)) && \ + ((base)->object->id.lib==NULL) && \ + (((base)->object->restrictflag & OB_RESTRICT_VIEW)==0)) +#define BASE_SELECTABLE(v3d, base) ( \ + (base->lay & v3d->lay) && \ + (base->object->restrictflag & (OB_RESTRICT_SELECT|OB_RESTRICT_VIEW))==0 ) +#define BASE_VISIBLE(v3d, base) ( \ + (base->lay & v3d->lay) && \ + (base->object->restrictflag & OB_RESTRICT_VIEW)==0 ) + #define FIRSTBASE scene->base.first #define LASTBASE scene->base.last #define BASACT (scene->basact) @@ -1240,6 +1407,7 @@ #define FFMPEG_MULTIPLEX_AUDIO 1 /* deprecated, you can choose none as audiocodec now */ #define FFMPEG_AUTOSPLIT_OUTPUT 2 +#define FFMPEG_LOSSLESS_OUTPUT 4 /* Paint.flags */ typedef enum { @@ -1262,13 +1430,6 @@ SCULPT_ONLY_DEFORM = (1<<8), } SculptFlags; -/* sculpt_paint_settings */ -#define SCULPT_PAINT_USE_UNIFIED_SIZE (1<<0) -#define SCULPT_PAINT_USE_UNIFIED_ALPHA (1<<1) -#define SCULPT_PAINT_UNIFIED_LOCK_BRUSH_SIZE (1<<2) -#define SCULPT_PAINT_UNIFIED_SIZE_PRESSURE (1<<3) -#define SCULPT_PAINT_UNIFIED_ALPHA_PRESSURE (1<<4) - /* ImagePaintSettings.flag */ #define IMAGEPAINT_DRAWING 1 // #define IMAGEPAINT_DRAW_TOOL 2 // deprecated @@ -1287,6 +1448,7 @@ #define UVCALC_FILLHOLES 1 #define UVCALC_NO_ASPECT_CORRECT 2 /* would call this UVCALC_ASPECT_CORRECT, except it should be default with old file */ #define UVCALC_TRANSFORM_CORRECT 4 /* adjust UV's while transforming to avoid distortion */ +#define UVCALC_USESUBSURF 8 /* Use mesh data after subsurf to compute UVs*/ /* toolsettings->uv_flag */ #define UV_SYNC_SELECTION 1 @@ -1339,15 +1501,6 @@ #define PE_TYPE_SOFTBODY 1 #define PE_TYPE_CLOTH 2 -/* toolsettings->retopo_mode */ -#define RETOPO 1 -#define RETOPO_PAINT 2 - -/* toolsettings->retopo_paint_tool */ /*UNUSED*/ -/* #define RETOPO_PEN 1 */ -/* #define RETOPO_LINE 2 */ -/* #define RETOPO_ELLIPSE 4 */ - /* toolsettings->skgen_options */ #define SKGEN_FILTER_INTERNAL (1 << 0) #define SKGEN_FILTER_EXTERNAL (1 << 1) diff -Nru blender-2.61/source/blender/makesdna/DNA_screen_types.h blender-2.62/source/blender/makesdna/DNA_screen_types.h --- blender-2.61/source/blender/makesdna/DNA_screen_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_screen_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -22,13 +22,14 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_SCREEN_TYPES_H -#define DNA_SCREEN_TYPES_H /** \file DNA_screen_types.h * \ingroup DNA */ +#ifndef DNA_SCREEN_TYPES_H +#define DNA_SCREEN_TYPES_H + #include "DNA_listBase.h" #include "DNA_view2d_types.h" #include "DNA_vec_types.h" diff -Nru blender-2.61/source/blender/makesdna/DNA_sdna_types.h blender-2.62/source/blender/makesdna/DNA_sdna_types.h --- blender-2.61/source/blender/makesdna/DNA_sdna_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_sdna_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -24,13 +24,14 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_SDNA_H -#define DNA_SDNA_H /** * \file DNA_sdna_types.h * \ingroup DNA */ +#ifndef DNA_SDNA_H +#define DNA_SDNA_H + # # typedef struct SDNA { diff -Nru blender-2.61/source/blender/makesdna/DNA_sensor_types.h blender-2.62/source/blender/makesdna/DNA_sensor_types.h --- blender-2.61/source/blender/makesdna/DNA_sensor_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_sensor_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -24,22 +24,23 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_SENSOR_TYPES_H -#define DNA_SENSOR_TYPES_H + /** \file DNA_sensor_types.h * \ingroup DNA * \since mar-2001 * \author nzc - * */ +#ifndef DNA_SENSOR_TYPES_H +#define DNA_SENSOR_TYPES_H + struct Object; struct Material; /* ****************** SENSORS ********************* */ typedef struct bNearSensor { - char name[32]; + char name[64]; /* MAX_NAME */ float dist, resetdist; int lastval, pad; } bNearSensor; @@ -58,7 +59,7 @@ } bMouseSensor; typedef struct bTouchSensor { - char name[32]; + char name[64]; /* MAX_NAME */ struct Material *ma; float dist, pad; } bTouchSensor; @@ -69,25 +70,25 @@ /** * Name of the target property */ - char targetName[32]; + char targetName[64]; /* MAX_NAME */ /** * Name of the toggle property */ - char toggleName[32]; + char toggleName[64]; /* MAX_NAME */ } bKeyboardSensor; typedef struct bPropertySensor { int type; int pad; - char name[32]; - char value[32]; - char maxvalue[32]; + char name[64]; /* MAX_NAME */ + char value[64]; + char maxvalue[64]; } bPropertySensor; typedef struct bActuatorSensor { int type; int pad; - char name[32]; + char name[64]; /* MAX_NAME */ } bActuatorSensor; typedef struct bDelaySensor { @@ -98,8 +99,8 @@ } bDelaySensor; typedef struct bCollisionSensor { - char name[32]; /* property name */ - char materialName[32]; /* material */ + char name[64]; /* property name. MAX_NAME */ + char materialName[64]; /* material */ // struct Material *ma; // XXX remove materialName short damptimer, damp; short mode; /* flag to choose material or property */ @@ -107,23 +108,23 @@ } bCollisionSensor; typedef struct bRadarSensor { - char name[32]; + char name[64]; /* MAX_NAME */ float angle; float range; short flag, axis; } bRadarSensor; typedef struct bRandomSensor { - char name[32]; + char name[64]; /* MAX_NAME */ int seed; int delay; } bRandomSensor; typedef struct bRaySensor { - char name[32]; + char name[64]; /* MAX_NAME */ float range; - char propname[32]; - char matname[32]; + char propname[64]; + char matname[64]; //struct Material *ma; // XXX remove materialName short mode; short pad1; @@ -131,8 +132,8 @@ } bRaySensor; typedef struct bArmatureSensor { - char posechannel[32]; - char constraint[32]; + char posechannel[64]; /* MAX_NAME */ + char constraint[64]; /* MAX_NAME */ int type; float value; } bArmatureSensor; @@ -146,12 +147,12 @@ /** * Can be used to filter on subjects like this */ - char subject[32]; + char subject[64]; /** * (Possible future use) body to filter on */ - char body[32]; + char body[64]; } bMessageSensor; typedef struct bSensor { @@ -159,7 +160,7 @@ /* pulse and freq are the bool toggle and frame count for pulse mode */ short type, otype, flag, pulse; short freq, totlinks, pad1, pad2; - char name[32]; + char name[64]; /* MAX_NAME */ void *data; struct bController **links; @@ -174,7 +175,7 @@ } bSensor; typedef struct bJoystickSensor { - char name[32]; + char name[64]; /* MAX_NAME */ char type; char joyindex; short flag; diff -Nru blender-2.61/source/blender/makesdna/DNA_sequence_types.h blender-2.62/source/blender/makesdna/DNA_sequence_types.h --- blender-2.61/source/blender/makesdna/DNA_sequence_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_sequence_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -24,14 +24,15 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_SEQUENCE_TYPES_H -#define DNA_SEQUENCE_TYPES_H /** \file DNA_sequence_types.h * \ingroup DNA * \since mar-2001 * \author nzc */ +#ifndef DNA_SEQUENCE_TYPES_H +#define DNA_SEQUENCE_TYPES_H + #include "DNA_defs.h" #include "DNA_listBase.h" #include "DNA_vec_types.h" @@ -40,10 +41,10 @@ struct Scene; struct bSound; -/* strlens; 80= FILE_MAXFILE, 160= FILE_MAXDIR */ +/* strlens; 256= FILE_MAXFILE, 768= FILE_MAXDIR */ typedef struct StripElem { - char name[80]; + char name[256]; int orig_width, orig_height; } StripElem; @@ -70,10 +71,10 @@ } StripColorBalance; typedef struct StripProxy { - char dir[160]; // custom directory for index and proxy files + char dir[768]; // custom directory for index and proxy files // (defaults to BL_proxy) - char file[80]; // custom file + char file[256]; // custom file struct anim *anim; // custom proxy anim file short tc; // time code in use @@ -90,7 +91,7 @@ int rt, len, us, done; int startstill, endstill; StripElem *stripdata; - char dir[160]; + char dir[768]; StripProxy *proxy; StripCrop *crop; StripTransform *transform; @@ -99,7 +100,7 @@ typedef struct PluginSeq { - char name[256]; + char name[1024]; /* 1024 = FILE_MAX */ void *handle; char *pname; @@ -126,7 +127,7 @@ struct Sequence *next, *prev; void *tmp; /* tmp var for copying, and tagging for linked selection */ void *lib; /* needed (to be like ipo), else it will raise libdata warnings, this should never be used */ - char name[24]; /* SEQ_NAME_MAXSTR - name, set by default and needs to be unique, for RNA paths */ + char name[64]; /* SEQ_NAME_MAXSTR - name, set by default and needs to be unique, for RNA paths */ int flag, type; /*flags bitmap (see below) and the type of sequence*/ int len; /* the length of the contense of this strip - before handles are applied */ @@ -190,8 +191,8 @@ /* Context vars, used to be static */ Sequence *act_seq; - char act_imagedir[256]; - char act_sounddir[256]; + char act_imagedir[1024]; /* 1024 = FILE_MAX */ + char act_sounddir[1024]; /* 1024 = FILE_MAX */ int over_ofs, over_cfra; int over_flag, pad; @@ -254,7 +255,7 @@ #define SEQ_SPEED_COMPRESS_IPO_Y 4 /* ***************** SEQUENCE ****************** */ -#define SEQ_NAME_MAXSTR 24 +#define SEQ_NAME_MAXSTR 64 /* seq->flag */ #define SEQ_LEFTSEL (1<<1) @@ -309,7 +310,8 @@ #define SEQ_PROXY_TC_RECORD_RUN 1 #define SEQ_PROXY_TC_FREE_RUN 2 #define SEQ_PROXY_TC_INTERP_REC_DATE_FREE_RUN 4 -#define SEQ_PROXY_TC_ALL 7 +#define SEQ_PROXY_TC_RECORD_RUN_NO_GAPS 8 +#define SEQ_PROXY_TC_ALL 15 /* seq->type WATCH IT: SEQ_EFFECT BIT is used to determine if this is an effect strip!!! */ #define SEQ_IMAGE 0 @@ -346,12 +348,12 @@ #define SEQ_BLEND_REPLACE 0 /* all other BLEND_MODEs are simple SEQ_EFFECT ids and therefore identical - to the table above. (Only those effects that handle _exactly_ two inputs, - otherwise, you can't really blend, right :) !) -*/ + * to the table above. (Only those effects that handle _exactly_ two inputs, + * otherwise, you can't really blend, right :) !) + */ -#define SEQ_HAS_PATH(_seq) (ELEM5((_seq)->type, SEQ_MOVIE, SEQ_IMAGE, SEQ_SOUND, SEQ_RAM_SOUND, SEQ_HD_SOUND)) +#define SEQ_HAS_PATH(_seq) (ELEM4((_seq)->type, SEQ_MOVIE, SEQ_IMAGE, SEQ_RAM_SOUND, SEQ_HD_SOUND)) #endif diff -Nru blender-2.61/source/blender/makesdna/DNA_smoke_types.h blender-2.62/source/blender/makesdna/DNA_smoke_types.h --- blender-2.61/source/blender/makesdna/DNA_smoke_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_smoke_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -24,13 +24,14 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_SMOKE_TYPES_H -#define DNA_SMOKE_TYPES_H /** \file DNA_smoke_types.h * \ingroup DNA */ +#ifndef DNA_SMOKE_TYPES_H +#define DNA_SMOKE_TYPES_H + /* flags */ #define MOD_SMOKE_HIGHRES (1<<1) /* enable high resolution */ #define MOD_SMOKE_DISSOLVE (1<<2) /* let smoke dissolve */ @@ -137,7 +138,8 @@ typedef struct SmokeCollSettings { struct SmokeModifierData *smd; /* for fast RNA access */ struct BVHTree *bvhtree; /* bounding volume hierarchy for this cloth object */ - struct DerivedMesh *dm; + +// struct DerivedMesh *dm; // UNUSED, ifdef'd in code for now. float *points; float *points_old; float *vel; diff -Nru blender-2.61/source/blender/makesdna/DNA_sound_types.h blender-2.62/source/blender/makesdna/DNA_sound_types.h --- blender-2.61/source/blender/makesdna/DNA_sound_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_sound_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -24,14 +24,15 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_SOUND_TYPES_H -#define DNA_SOUND_TYPES_H /** \file DNA_sound_types.h * \ingroup DNA * \since mar-2001 * \author nzc */ +#ifndef DNA_SOUND_TYPES_H +#define DNA_SOUND_TYPES_H + #include "DNA_listBase.h" #include "DNA_ID.h" @@ -48,7 +49,7 @@ /** * The path to the sound file. */ - char name[240]; + char name[1024]; /* 1024 = FILE_MAX */ /** * The packed file. diff -Nru blender-2.61/source/blender/makesdna/DNA_space_types.h blender-2.62/source/blender/makesdna/DNA_space_types.h --- blender-2.61/source/blender/makesdna/DNA_space_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_space_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -24,14 +24,15 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_SPACE_TYPES_H -#define DNA_SPACE_TYPES_H /** \file DNA_space_types.h * \ingroup DNA * \since mar-2001 * \author nzc */ +#ifndef DNA_SPACE_TYPES_H +#define DNA_SPACE_TYPES_H + #include "DNA_defs.h" #include "DNA_listBase.h" #include "DNA_color_types.h" /* for Histogram */ @@ -132,8 +133,6 @@ float blockscale DNA_DEPRECATED; short blockhandler[8] DNA_DEPRECATED; - - struct RenderInfo *ri; View2D v2d DNA_DEPRECATED; /* deprecated, copied to region */ @@ -175,10 +174,11 @@ typedef struct FileSelectParams { char title[32]; /* title, also used for the text of the execute button */ - char dir[240]; /* directory */ - char file[80]; /* file */ - char renamefile[80]; - char renameedit[80]; /* annoying but the first is only used for initialization */ + char dir[1056]; /* directory, FILE_MAX_LIBEXTRA, 1024 + 32, this is for extreme case when 1023 length path + * needs to be linked in, where foo.blend/Armature need adding */ + char file[256]; /* file */ + char renamefile[256]; + char renameedit[256]; /* annoying but the first is only used for initialization */ char filter_glob[64]; /* list of filetypes to filter */ @@ -344,8 +344,9 @@ void *py_globaldict; int flags, lastspace; - char scriptname[256]; /* store the script file here so we can re-run it on loading blender, if "Enable Scripts" is on */ - char scriptarg[256]; + /* store the script file here so we can re-run it on loading blender, if "Enable Scripts" is on */ + char scriptname[1024]; /* 1024 = FILE_MAX */ + char scriptarg[256]; /* 1024 = FILE_MAX */ } Script; #define SCRIPT_SET_NULL(_script) _script->py_draw = _script->py_event = _script->py_button = _script->py_browsercallback = _script->py_globaldict = NULL; _script->flags = 0; @@ -517,6 +518,9 @@ int pad; float stabmat[4][4], unistabmat[4][4]; /* current stabilization matrix and the same matrix in unified space, defined when drawing and used for mouse position calculation */ + + /* movie postprocessing */ + int postproc_flag, pad2; } SpaceClip; /* view3d Now in DNA_view3d_types.h */ @@ -604,7 +608,8 @@ /* FileSelectParams.display */ enum FileDisplayTypeE { - FILE_SHORTDISPLAY = 1, + FILE_DEFAULTDISPLAY = 0, + FILE_SHORTDISPLAY, FILE_LONGDISPLAY, FILE_IMGDISPLAY }; @@ -620,9 +625,11 @@ /* these values need to be hardcoded in structs, dna does not recognize defines */ /* also defined in BKE */ -#define FILE_MAXDIR 160 -#define FILE_MAXFILE 80 -#define FILE_MAX 240 +#define FILE_MAXDIR 768 +#define FILE_MAXFILE 256 +#define FILE_MAX 1024 + +#define FILE_MAX_LIBEXTRA (FILE_MAX + 32) /* filesel types */ #define FILE_UNIX 8 @@ -889,11 +896,12 @@ #define SC_SHOW_GRID (1<<9) #define SC_SHOW_STABLE (1<<10) #define SC_MANUAL_CALIBRATION (1<<11) -#define SC_SHOW_GPENCIL (1<<12) +/*#define SC_SHOW_GPENCIL (1<<12)*/ /* UNUSED */ #define SC_SHOW_FILTERS (1<<13) #define SC_SHOW_GRAPH_FRAMES (1<<14) #define SC_SHOW_GRAPH_TRACKS (1<<15) -#define SC_SHOW_PYRAMID_LEVELS (1<<16) +/*#define SC_SHOW_PYRAMID_LEVELS (1<<16) */ /* UNUSED */ +#define SC_LOCK_TIMECURSOR (1<<17) /* SpaceClip->mode */ #define SC_MODE_TRACKING 0 diff -Nru blender-2.61/source/blender/makesdna/DNA_speaker_types.h blender-2.62/source/blender/makesdna/DNA_speaker_types.h --- blender-2.61/source/blender/makesdna/DNA_speaker_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_speaker_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -19,13 +19,14 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_SPEAKER_TYPES_H -#define DNA_SPEAKER_TYPES_H /** \file DNA_speaker_types.h * \ingroup DNA */ +#ifndef DNA_SPEAKER_TYPES_H +#define DNA_SPEAKER_TYPES_H + #include "DNA_ID.h" struct AnimData; diff -Nru blender-2.61/source/blender/makesdna/DNA_text_types.h blender-2.62/source/blender/makesdna/DNA_text_types.h --- blender-2.61/source/blender/makesdna/DNA_text_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_text_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -24,14 +24,15 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_TEXT_TYPES_H -#define DNA_TEXT_TYPES_H /** \file DNA_text_types.h * \ingroup DNA * \since mar-2001 * \author nzc */ +#ifndef DNA_TEXT_TYPES_H +#define DNA_TEXT_TYPES_H + #include "DNA_listBase.h" #include "DNA_ID.h" diff -Nru blender-2.61/source/blender/makesdna/DNA_texture_types.h blender-2.62/source/blender/makesdna/DNA_texture_types.h --- blender-2.61/source/blender/makesdna/DNA_texture_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_texture_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -24,8 +24,6 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_TEXTURE_TYPES_H -#define DNA_TEXTURE_TYPES_H /** \file DNA_texture_types.h * \ingroup DNA @@ -33,6 +31,9 @@ * \author nzc */ +#ifndef DNA_TEXTURE_TYPES_H +#define DNA_TEXTURE_TYPES_H + #include "DNA_defs.h" #include "DNA_ID.h" #include "DNA_image_types.h" /* ImageUser */ @@ -59,7 +60,7 @@ short texco, mapto, maptoneg, blendtype; struct Object *object; struct Tex *tex; - char uvname[32]; + char uvname[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ char projx, projy, projz, mapping; float ofs[3], size[3], rot; @@ -104,7 +105,7 @@ #endif typedef struct PluginTex { - char name[160]; + char name[1024]; void *handle; char *pname; @@ -199,7 +200,7 @@ struct Object *object; /* for rendering smoke sims */ float int_multiplier; int still_frame; - char source_path[240]; + char source_path[1024]; /* 1024 = FILE_MAX */ /* temporary data */ float *dataset; @@ -494,6 +495,7 @@ #define MTEX_BUMP_OBJECTSPACE 1024 #define MTEX_BUMP_TEXTURESPACE 2048 /* #define MTEX_BUMP_FLIPPED 4096 */ /* UNUSED */ +#define MTEX_BICUBIC_BUMP 8192 /* blendtype */ #define MTEX_BLEND 0 diff -Nru blender-2.61/source/blender/makesdna/DNA_tracking_types.h blender-2.62/source/blender/makesdna/DNA_tracking_types.h --- blender-2.61/source/blender/makesdna/DNA_tracking_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_tracking_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -26,15 +26,15 @@ * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_TRACKING_TYPES_H -#define DNA_TRACKING_TYPES_H - /** \file DNA_tracking_types.h * \ingroup DNA * \since may-2011 * \author Sergey Sharybin */ +#ifndef DNA_TRACKING_TYPES_H +#define DNA_TRACKING_TYPES_H + #include "DNA_listBase.h" /* match-moving data */ @@ -75,7 +75,7 @@ typedef struct MovieTrackingTrack { struct MovieTrackingTrack *next, *prev; - char name[24]; + char name[64]; /* MAX_NAME */ /* ** setings ** */ float pat_min[2], pat_max[2]; /* positions of left-bottom and right-top corners of pattern (in unified 0..1 space) */ @@ -91,12 +91,8 @@ float bundle_pos[3]; /* reconstructed position */ float error; /* average track reprojection error */ - int pad; - /* ** UI editing ** */ int flag, pat_flag, search_flag; /* flags (selection, ...) */ - short transflag; /* transform flags */ - char pad3[2]; float color[3]; /* custom color for track */ /* tracking algorithm to use; can be KLT or SAD */ @@ -125,6 +121,9 @@ short default_frames_limit; /* number of frames to be tarcked during single tracking session (if TRACKING_FRAMES_LIMIT is set) */ short default_margin; /* margin from frame boundaries */ short default_pattern_match; /* re-adjust every N frames */ + short default_flag; /* default flags like color channels used by default */ + + short pod; /* ** common tracker settings ** */ short speed; /* speed of tracking */ @@ -133,7 +132,7 @@ int keyframe1, keyframe2; /* two keyframes for reconstrution initialization */ /* ** which camera intrinsics to refine. uses on the REFINE_* flags */ - short refine_camera_intrinsics, pad2; + short refine_camera_intrinsics, pad23; /* ** tool settings ** */ @@ -142,7 +141,12 @@ /* cleanup */ int clean_frames, clean_action; - float clean_error, pad; + float clean_error; + + /* set object scale */ + float object_distance; /* distance between two bundles used for object scaling */ + + int pad3; } MovieTrackingSettings; typedef struct MovieTrackingStabilization { @@ -172,6 +176,17 @@ struct MovieReconstructedCamera *cameras; /* reconstructed cameras */ } MovieTrackingReconstruction; +typedef struct MovieTrackingObject { + struct MovieTrackingObject *next, *prev; + + char name[64]; /* Name of tracking object, MAX_NAME */ + int flag; + float scale; /* scale of object solution in amera space */ + + ListBase tracks; /* list of tracks use to tracking this object */ + MovieTrackingReconstruction reconstruction; /* reconstruction data for this object */ +} MovieTrackingObject; + typedef struct MovieTrackingStats { char message[256]; } MovieTrackingStats; @@ -179,11 +194,14 @@ typedef struct MovieTracking { MovieTrackingSettings settings; /* different tracking-related settings */ MovieTrackingCamera camera; /* camera intrinsics */ - ListBase tracks; /* all tracks */ - MovieTrackingReconstruction reconstruction; /* reconstruction data */ + ListBase tracks; /* list of tracks used for camera object */ + MovieTrackingReconstruction reconstruction; /* reconstruction data for camera object */ MovieTrackingStabilization stabilization; /* stabilization data */ MovieTrackingTrack *act_track; /* active track */ + ListBase objects; + int objectnr, tot_object; /* index of active object and total number of objects */ + MovieTrackingStats *stats; /* statistics displaying in clip editor */ } MovieTracking; @@ -196,7 +214,8 @@ /* MovieTrackingMarker->flag */ #define MARKER_DISABLED (1<<0) #define MARKER_TRACKED (1<<1) -#define MARKER_GRAPH_SEL (1<<2) +#define MARKER_GRAPH_SEL_X (1<<2) +#define MARKER_GRAPH_SEL_Y (1<<3) /* MovieTrackingTrack->flag */ #define TRACK_HAS_BUNDLE (1<<1) @@ -207,6 +226,7 @@ #define TRACK_LOCKED (1<<6) #define TRACK_CUSTOMCOLOR (1<<7) #define TRACK_USE_2D_STAB (1<<8) +#define TRACK_PREVIEW_GRAYSCALE (1<<9) /* MovieTrackingTrack->tracker */ #define TRACKER_KLT 0 @@ -241,6 +261,9 @@ /* MovieTrackingReconstruction->flag */ #define TRACKING_RECONSTRUCTED (1<<0) +/* MovieTrackingObject->flag */ +#define TRACKING_OBJECT_CAMERA (1<<0) + #define TRACKING_CLEAN_SELECT 0 #define TRACKING_CLEAN_DELETE_TRACK 1 #define TRACKING_CLEAN_DELETE_SEGMENT 2 diff -Nru blender-2.61/source/blender/makesdna/DNA_userdef_types.h blender-2.62/source/blender/makesdna/DNA_userdef_types.h --- blender-2.61/source/blender/makesdna/DNA_userdef_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_userdef_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -25,15 +25,15 @@ * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_USERDEF_TYPES_H -#define DNA_USERDEF_TYPES_H /** \file DNA_userdef_types.h * \ingroup DNA * \since mar-2001 * \author nzc - * */ +#ifndef DNA_USERDEF_TYPES_H +#define DNA_USERDEF_TYPES_H + #include "DNA_listBase.h" #include "DNA_texture_types.h" /* ColorBand */ @@ -60,7 +60,7 @@ /* first font is the default (index 0), others optional */ typedef struct uiFont { struct uiFont *next, *prev; - char filename[256]; + char filename[1024];/* 1024 = FILE_MAX */ short blf_id; /* from blfont lib */ short uifont_id; /* own id */ short r_to_l; /* fonts that read from left to right */ @@ -158,7 +158,7 @@ uiPanelColors panel; - char iconfile[80]; // FILE_MAXFILE length + char iconfile[256]; // FILE_MAXFILE length float icon_alpha; float pad; @@ -252,7 +252,15 @@ char hpad[7]; char preview_back[4]; + char preview_stitch_face[4]; + char preview_stitch_edge[4]; + char preview_stitch_vert[4]; + char preview_stitch_stitchable[4]; + char preview_stitch_unstitchable[4]; + char preview_stitch_active[4]; + char match[4]; /* outliner - filter match */ + char selected_highlight[4]; /* outliner - selected item */ } ThemeSpace; @@ -318,16 +326,16 @@ typedef struct UserDef { int flag, dupflag; int savetime; - char tempdir[160]; // FILE_MAXDIR length - char fontdir[160]; - char renderdir[240]; // FILE_MAX length - char textudir[160]; - char plugtexdir[160]; - char plugseqdir[160]; - char pythondir[160]; - char sounddir[160]; - char image_editor[240]; // FILE_MAX length - char anim_player[240]; // FILE_MAX length + char tempdir[768]; /* FILE_MAXDIR length */ + char fontdir[768]; + char renderdir[1024]; /* FILE_MAX length */ + char textudir[768]; + char plugtexdir[768]; + char plugseqdir[768]; + char pythondir[768]; + char sounddir[768]; + char image_editor[1024]; /* 1024 = FILE_MAX */ + char anim_player[1024]; /* 1024 = FILE_MAX */ int anim_player_preset; short v2d_min_gridsize; /* minimum spacing between gridlines in View2D grids */ @@ -391,19 +399,17 @@ short widget_unit; /* defaults to 20 for 72 DPI setting */ short anisotropic_filter; - /*short pad[3]; */ + short use_16bit_textures, pad8; float ndof_sensitivity; /* overall sensitivity of 3D mouse */ int ndof_flag; /* flags for 3D mouse */ - char versemaster[160]; - char verseuser[160]; float glalphaclip; short autokey_mode; /* autokeying mode */ short autokey_flag; /* flags for autokeying */ - short text_render, pad9[3]; /*options for text rendering*/ + short text_render, pad9; /*options for text rendering*/ struct ColorBand coba_weight; /* from texture.h */ @@ -413,6 +419,9 @@ short pad3; char author[80]; /* author name for file formats supporting it */ + + int compute_device_type; + int compute_device_id; } UserDef; extern UserDef U; /* from blenkernel blender.c */ @@ -603,20 +612,20 @@ #define NDOF_FLY_HELICOPTER (1 << 1) #define NDOF_LOCK_HORIZON (1 << 2) /* the following might not need to be saved between sessions, - but they do need to live somewhere accessible... */ + * but they do need to live somewhere accessible... */ #define NDOF_SHOULD_PAN (1 << 3) #define NDOF_SHOULD_ZOOM (1 << 4) #define NDOF_SHOULD_ROTATE (1 << 5) /* orbit navigation modes - only two options, so it's sort of a hyrbrid bool/enum - if ((U.ndof_flag & NDOF_ORBIT_MODE) == NDOF_OM_OBJECT)... */ + * only two options, so it's sort of a hyrbrid bool/enum + * if ((U.ndof_flag & NDOF_ORBIT_MODE) == NDOF_OM_OBJECT)... */ /* #define NDOF_ORBIT_MODE (1 << 6) #define NDOF_OM_TARGETCAMERA 0 #define NDOF_OM_OBJECT NDOF_ORBIT_MODE */ /* actually... users probably don't care about what the mode - is called, just that it feels right */ + * is called, just that it feels right */ /* zoom is up/down if this flag is set (otherwise forward/backward) */ #define NDOF_ZOOM_UPDOWN (1 << 7) #define NDOF_ZOOM_INVERT (1 << 8) @@ -627,6 +636,10 @@ #define NDOF_PANY_INVERT_AXIS (1 << 13) #define NDOF_PANZ_INVERT_AXIS (1 << 14) +/* compute_device_type */ +#define USER_COMPUTE_DEVICE_NONE 0 +#define USER_COMPUTE_DEVICE_OPENCL 1 +#define USER_COMPUTE_DEVICE_CUDA 2 #ifdef __cplusplus } diff -Nru blender-2.61/source/blender/makesdna/DNA_vec_types.h blender-2.62/source/blender/makesdna/DNA_vec_types.h --- blender-2.61/source/blender/makesdna/DNA_vec_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_vec_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -26,14 +26,15 @@ * */ -#ifndef DNA_VEC_TYPES_H -#define DNA_VEC_TYPES_H /** \file DNA_vec_types.h * \ingroup DNA * \since dec-2000 * \author nzc */ +#ifndef DNA_VEC_TYPES_H +#define DNA_VEC_TYPES_H + /* types */ /** vector of two shorts. */ diff -Nru blender-2.61/source/blender/makesdna/DNA_vfont_types.h blender-2.62/source/blender/makesdna/DNA_vfont_types.h --- blender-2.61/source/blender/makesdna/DNA_vfont_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_vfont_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -24,8 +24,6 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_VFONT_TYPES_H -#define DNA_VFONT_TYPES_H /** \file DNA_vfont_types.h * \ingroup DNA @@ -33,6 +31,9 @@ * \author nzc */ +#ifndef DNA_VFONT_TYPES_H +#define DNA_VFONT_TYPES_H + #include "DNA_ID.h" struct PackedFile; @@ -41,7 +42,7 @@ typedef struct VFont { ID id; - char name[256]; + char name[1024]; /* 1024 = FILE_MAX */ struct VFontData *data; struct PackedFile * packedfile; diff -Nru blender-2.61/source/blender/makesdna/DNA_view2d_types.h blender-2.62/source/blender/makesdna/DNA_view2d_types.h --- blender-2.61/source/blender/makesdna/DNA_view2d_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_view2d_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -24,13 +24,14 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_VIEW2D_TYPES_H -#define DNA_VIEW2D_TYPES_H /** \file DNA_view2d_types.h * \ingroup DNA */ +#ifndef DNA_VIEW2D_TYPES_H +#define DNA_VIEW2D_TYPES_H + #include "DNA_vec_types.h" /* ---------------------------------- */ diff -Nru blender-2.61/source/blender/makesdna/DNA_view3d_types.h blender-2.62/source/blender/makesdna/DNA_view3d_types.h --- blender-2.61/source/blender/makesdna/DNA_view3d_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_view3d_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -24,13 +24,14 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_VIEW3D_TYPES_H -#define DNA_VIEW3D_TYPES_H /** \file DNA_view3d_types.h * \ingroup DNA */ +#ifndef DNA_VIEW3D_TYPES_H +#define DNA_VIEW3D_TYPES_H + struct ViewDepths; struct Object; struct Image; @@ -172,7 +173,7 @@ struct View3D *localvd; /* allocated backup of its self while in localview */ - char ob_centre_bone[32]; /* optional string for armature bone to define center */ + char ob_centre_bone[64]; /* optional string for armature bone to define center, MAXBONENAME */ unsigned int lay; int layact; diff -Nru blender-2.61/source/blender/makesdna/DNA_windowmanager_types.h blender-2.62/source/blender/makesdna/DNA_windowmanager_types.h --- blender-2.61/source/blender/makesdna/DNA_windowmanager_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_windowmanager_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -23,13 +23,14 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_WINDOWMANAGER_TYPES_H -#define DNA_WINDOWMANAGER_TYPES_H /** \file DNA_windowmanager_types.h * \ingroup DNA */ +#ifndef DNA_WINDOWMANAGER_TYPES_H +#define DNA_WINDOWMANAGER_TYPES_H + #include "DNA_listBase.h" #include "DNA_vec_types.h" @@ -167,7 +168,7 @@ struct bScreen *screen; /* active screen */ struct bScreen *newscreen; /* temporary when switching */ - char screenname[32]; /* MAX_ID_NAME for matching window with active screen after file read */ + char screenname[64]; /* MAX_ID_NAME for matching window with active screen after file read */ short posx, posy, sizex, sizey; /* window coords */ short windowstate; /* borderless, full */ diff -Nru blender-2.61/source/blender/makesdna/DNA_world_types.h blender-2.62/source/blender/makesdna/DNA_world_types.h --- blender-2.61/source/blender/makesdna/DNA_world_types.h 2011-12-13 19:49:44.000000000 +0000 +++ blender-2.62/source/blender/makesdna/DNA_world_types.h 2012-02-15 19:34:32.000000000 +0000 @@ -24,13 +24,14 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef DNA_WORLD_TYPES_H -#define DNA_WORLD_TYPES_H /** \file DNA_world_types.h * \ingroup DNA */ +#ifndef DNA_WORLD_TYPES_H +#define DNA_WORLD_TYPES_H + #include "DNA_defs.h" #include "DNA_ID.h" @@ -181,6 +182,7 @@ #define TEXCO_ANGMAP 64 #define TEXCO_H_SPHEREMAP 256 #define TEXCO_H_TUBEMAP 1024 +#define TEXCO_EQUIRECTMAP 2048 /* mapto */ #define WOMAP_BLEND 1 diff -Nru blender-2.61/source/blender/makesdna/intern/dna_genfile.c blender-2.62/source/blender/makesdna/intern/dna_genfile.c --- blender-2.61/source/blender/makesdna/intern/dna_genfile.c 2011-12-13 19:49:36.000000000 +0000 +++ blender-2.62/source/blender/makesdna/intern/dna_genfile.c 2012-02-15 19:34:25.000000000 +0000 @@ -491,7 +491,7 @@ for(nr=0; nrnr_structs; nr++) { sp= sdna->structs[nr]; if(strcmp(sdna->types[sp[0]], "ClothSimSettings") == 0) - sp[10]= 9; + sp[10]= SDNA_TYPE_VOID; } } @@ -655,92 +655,92 @@ return compflags; } -static void cast_elem(char *ctype, char *otype, const char *name, char *curdata, char *olddata) +static eSDNA_Type sdna_type_nr(const char *dna_type) +{ + if ((strcmp(dna_type, "char")==0) || (strcmp(dna_type, "const char")==0)) return SDNA_TYPE_CHAR; + else if((strcmp(dna_type, "uchar")==0) || (strcmp(dna_type, "unsigned char")==0)) return SDNA_TYPE_UCHAR; + else if( strcmp(dna_type, "short")==0) return SDNA_TYPE_SHORT; + else if((strcmp(dna_type, "ushort")==0)||(strcmp(dna_type, "unsigned short")==0)) return SDNA_TYPE_USHORT; + else if( strcmp(dna_type, "int")==0) return SDNA_TYPE_INT; + else if( strcmp(dna_type, "long")==0) return SDNA_TYPE_LONG; + else if((strcmp(dna_type, "ulong")==0)||(strcmp(dna_type, "unsigned long")==0)) return SDNA_TYPE_ULONG; + else if( strcmp(dna_type, "float")==0) return SDNA_TYPE_FLOAT; + else if( strcmp(dna_type, "double")==0) return SDNA_TYPE_DOUBLE; + else if( strcmp(dna_type, "int64_t")==0) return SDNA_TYPE_INT64; + else if( strcmp(dna_type, "uint64_t")==0) return SDNA_TYPE_UINT64; + else return -1; /* invalid! */ +} + +static void cast_elem(const char *ctype, const char *otype, const char *name, char *curdata, char *olddata) { double val = 0.0; - int arrlen, curlen=1, oldlen=1, ctypenr, otypenr; - + int arrlen, curlen=1, oldlen=1; + + eSDNA_Type ctypenr, otypenr; + arrlen= DNA_elem_array_size(name, strlen(name)); - - /* define otypenr */ - if(strcmp(otype, "char")==0 || (strcmp(otype, "const char")==0)) otypenr= 0; - else if((strcmp(otype, "uchar")==0) || (strcmp(otype, "unsigned char")==0)) otypenr= 1; - else if(strcmp(otype, "short")==0) otypenr= 2; - else if((strcmp(otype, "ushort")==0)||(strcmp(otype, "unsigned short")==0)) otypenr= 3; - else if(strcmp(otype, "int")==0) otypenr= 4; - else if(strcmp(otype, "long")==0) otypenr= 5; - else if((strcmp(otype, "ulong")==0)||(strcmp(otype, "unsigned long")==0)) otypenr= 6; - else if(strcmp(otype, "float")==0) otypenr= 7; - else if(strcmp(otype, "double")==0) otypenr= 8; - else return; - - /* define ctypenr */ - if(strcmp(ctype, "char")==0) ctypenr= 0; - else if(strcmp(ctype, "const char")==0) ctypenr= 0; - else if((strcmp(ctype, "uchar")==0)||(strcmp(ctype, "unsigned char")==0)) ctypenr= 1; - else if(strcmp(ctype, "short")==0) ctypenr= 2; - else if((strcmp(ctype, "ushort")==0)||(strcmp(ctype, "unsigned short")==0)) ctypenr= 3; - else if(strcmp(ctype, "int")==0) ctypenr= 4; - else if(strcmp(ctype, "long")==0) ctypenr= 5; - else if((strcmp(ctype, "ulong")==0)||(strcmp(ctype, "unsigned long")==0)) ctypenr= 6; - else if(strcmp(ctype, "float")==0) ctypenr= 7; - else if(strcmp(ctype, "double")==0) ctypenr= 8; - else return; + + if ( (otypenr= sdna_type_nr(otype)) == -1 || + (ctypenr= sdna_type_nr(ctype)) == -1 ) + { + return; + } /* define lengths */ - if(otypenr < 2) oldlen= 1; - else if(otypenr < 4) oldlen= 2; - else if(otypenr < 8) oldlen= 4; - else oldlen= 8; - - if(ctypenr < 2) curlen= 1; - else if(ctypenr < 4) curlen= 2; - else if(ctypenr < 8) curlen= 4; - else curlen= 8; - + oldlen= DNA_elem_type_size(otypenr); + curlen= DNA_elem_type_size(ctypenr); + while(arrlen>0) { switch(otypenr) { - case 0: + case SDNA_TYPE_CHAR: val= *olddata; break; - case 1: + case SDNA_TYPE_UCHAR: val= *( (unsigned char *)olddata); break; - case 2: + case SDNA_TYPE_SHORT: val= *( (short *)olddata); break; - case 3: + case SDNA_TYPE_USHORT: val= *( (unsigned short *)olddata); break; - case 4: + case SDNA_TYPE_INT: val= *( (int *)olddata); break; - case 5: + case SDNA_TYPE_LONG: val= *( (int *)olddata); break; - case 6: + case SDNA_TYPE_ULONG: val= *( (unsigned int *)olddata); break; - case 7: + case SDNA_TYPE_FLOAT: val= *( (float *)olddata); break; - case 8: + case SDNA_TYPE_DOUBLE: val= *( (double *)olddata); break; + case SDNA_TYPE_INT64: + val= *( (int64_t *)olddata); break; + case SDNA_TYPE_UINT64: + val= *( (uint64_t *)olddata); break; } switch(ctypenr) { - case 0: + case SDNA_TYPE_CHAR: *curdata= val; break; - case 1: + case SDNA_TYPE_UCHAR: *( (unsigned char *)curdata)= val; break; - case 2: + case SDNA_TYPE_SHORT: *( (short *)curdata)= val; break; - case 3: + case SDNA_TYPE_USHORT: *( (unsigned short *)curdata)= val; break; - case 4: + case SDNA_TYPE_INT: *( (int *)curdata)= val; break; - case 5: + case SDNA_TYPE_LONG: *( (int *)curdata)= val; break; - case 6: + case SDNA_TYPE_ULONG: *( (unsigned int *)curdata)= val; break; - case 7: + case SDNA_TYPE_FLOAT: if(otypenr<2) val/= 255; *( (float *)curdata)= val; break; - case 8: + case SDNA_TYPE_DOUBLE: if(otypenr<2) val/= 255; *( (double *)curdata)= val; break; + case SDNA_TYPE_INT64: + *( (int64_t *)curdata)= val; break; + case SDNA_TYPE_UINT64: + *( (uint64_t *)curdata)= val; break; } olddata+= oldlen; @@ -838,7 +838,8 @@ return NULL; } -static void reconstruct_elem(SDNA *newsdna, SDNA *oldsdna, char *type, const char *name, char *curdata, short *old, char *olddata) +static void reconstruct_elem(SDNA *newsdna, SDNA *oldsdna, + char *type, const char *name, char *curdata, short *old, char *olddata) { /* rules: test for NAME: - name equal: @@ -912,7 +913,8 @@ } } -static void reconstruct_struct(SDNA *newsdna, SDNA *oldsdna, char *compflags, int oldSDNAnr, char *data, int curSDNAnr, char *cur) +static void reconstruct_struct(SDNA *newsdna, SDNA *oldsdna, + char *compflags, int oldSDNAnr, char *data, int curSDNAnr, char *cur) { /* Recursive! * Per element from cur_struct, read data from old_struct. @@ -1054,7 +1056,9 @@ } else { - if( spc[0]==2 || spc[0]==3 ) { /* short-ushort */ + if ( spc[0]==SDNA_TYPE_SHORT || + spc[0]==SDNA_TYPE_USHORT ) + { /* exception: variable called blocktype/ipowin: derived from ID_ */ skip= 0; @@ -1076,7 +1080,11 @@ } } } - else if(spc[0]>3 && spc[0]<8) { /* int-long-ulong-float */ + else if ( (spc[0]==SDNA_TYPE_INT || + spc[0]==SDNA_TYPE_LONG || + spc[0]==SDNA_TYPE_ULONG || + spc[0]==SDNA_TYPE_FLOAT)) + { mul= DNA_elem_array_size(name, strlen(name)); cpo= cur; @@ -1090,6 +1098,20 @@ cpo+= 4; } } + else if ( (spc[0]==SDNA_TYPE_INT64) || + (spc[0]==SDNA_TYPE_UINT64)) + { + mul= DNA_elem_array_size(name, strlen(name)); + cpo= cur; + while(mul--) { + cval= cpo[0]; cpo[0]= cpo[7]; cpo[7]= cval; + cval= cpo[1]; cpo[1]= cpo[6]; cpo[6]= cval; + cval= cpo[2]; cpo[2]= cpo[5]; cpo[5]= cval; + cval= cpo[3]; cpo[3]= cpo[4]; cpo[4]= cval; + + cpo+= 8; + } + } } } cur+= elen; @@ -1138,3 +1160,27 @@ return (int)((intptr_t)cp); } +int DNA_elem_type_size(const eSDNA_Type elem_nr) +{ + /* should containt all enum types */ + switch (elem_nr) { + case SDNA_TYPE_CHAR: + case SDNA_TYPE_UCHAR: + return 1; + case SDNA_TYPE_SHORT: + case SDNA_TYPE_USHORT: + return 2; + case SDNA_TYPE_INT: + case SDNA_TYPE_LONG: + case SDNA_TYPE_ULONG: + case SDNA_TYPE_FLOAT: + return 4; + case SDNA_TYPE_DOUBLE: + case SDNA_TYPE_INT64: + case SDNA_TYPE_UINT64: + return 8; + } + + /* weak */ + return 8; +} diff -Nru blender-2.61/source/blender/makesdna/intern/makesdna.c blender-2.62/source/blender/makesdna/intern/makesdna.c --- blender-2.61/source/blender/makesdna/intern/makesdna.c 2011-12-13 19:49:36.000000000 +0000 +++ blender-2.62/source/blender/makesdna/intern/makesdna.c 2012-02-15 19:34:25.000000000 +0000 @@ -928,16 +928,19 @@ /* insertion of all known types */ /* watch it: uint is not allowed! use in structs an unsigned int */ - add_type("char", 1); /* 0 */ - add_type("uchar", 1); /* 1 */ - add_type("short", 2); /* 2 */ - add_type("ushort", 2); /* 3 */ - add_type("int", 4); /* 4 */ - add_type("long", 4); /* 5 */ /* should it be 8 on 64 bits? */ - add_type("ulong", 4); /* 6 */ - add_type("float", 4); /* 7 */ - add_type("double", 8); /* 8 */ - add_type("void", 0); /* 9 */ + /* watch it: sizes must match DNA_elem_type_size() */ + add_type("char", 1); /* SDNA_TYPE_CHAR */ + add_type("uchar", 1); /* SDNA_TYPE_UCHAR */ + add_type("short", 2); /* SDNA_TYPE_SHORT */ + add_type("ushort", 2); /* SDNA_TYPE_USHORT */ + add_type("int", 4); /* SDNA_TYPE_INT */ + add_type("long", 4); /* SDNA_TYPE_LONG */ /* should it be 8 on 64 bits? */ + add_type("ulong", 4); /* SDNA_TYPE_ULONG */ + add_type("float", 4); /* SDNA_TYPE_FLOAT */ + add_type("double", 8); /* SDNA_TYPE_DOUBLE */ + add_type("int64_t", 8); /* SDNA_TYPE_INT64 */ + add_type("uint64_t", 8); /* SDNA_TYPE_UINT64 */ + add_type("void", 0); /* SDNA_TYPE_VOID */ // the defines above shouldn't be output in the padding file... firststruct = nr_types; diff -Nru blender-2.61/source/blender/makesrna/intern/CMakeLists.txt blender-2.62/source/blender/makesrna/intern/CMakeLists.txt --- blender-2.61/source/blender/makesrna/intern/CMakeLists.txt 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/CMakeLists.txt 2012-02-15 19:35:15.000000000 +0000 @@ -143,6 +143,9 @@ ) +if(WITH_CYCLES) + add_definitions(-DWITH_CYCLES) +endif() if(WITH_PYTHON) add_definitions(-DWITH_PYTHON) @@ -246,6 +249,7 @@ ../../editors/include ../../render/extern/include ../../../../intern/audaspace/intern + ../../../../intern/cycles/blender ../../../../intern/guardedalloc ../../../../intern/memutil ) diff -Nru blender-2.61/source/blender/makesrna/intern/makesrna.c blender-2.62/source/blender/makesrna/intern/makesrna.c --- blender-2.61/source/blender/makesrna/intern/makesrna.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/makesrna.c 2012-02-15 19:35:15.000000000 +0000 @@ -43,9 +43,14 @@ #define RNA_VERSION_DATE "FIXME-RNA_VERSION_DATE" #ifdef _WIN32 -#ifndef snprintf -#define snprintf _snprintf +# ifndef snprintf +# define snprintf _snprintf +# endif #endif + +/* so we can use __func__ everywhere */ +#if defined(_MSC_VER) +# define __func__ __FUNCTION__ #endif /* Replace if different */ @@ -448,11 +453,9 @@ static int rna_color_quantize(PropertyRNA *prop, PropertyDefRNA *dp) { - if(prop->type == PROP_FLOAT && (prop->subtype==PROP_COLOR || prop->subtype==PROP_COLOR_GAMMA)) - if(strcmp(dp->dnatype, "float") != 0 && strcmp(dp->dnatype, "double") != 0) - return 1; - - return 0; + return ( (prop->type == PROP_FLOAT) && + (prop->subtype==PROP_COLOR || prop->subtype==PROP_COLOR_GAMMA) && + (IS_DNATYPE_FLOAT_COMPAT(dp->dnatype) == 0) ); } static const char *rna_function_string(void *func) @@ -484,7 +487,8 @@ if(!manualfunc) { if(!dp->dnastructname || !dp->dnaname) { - fprintf(stderr, "rna_def_property_get_func: %s.%s has no valid dna info.\n", srna->identifier, prop->identifier); + fprintf(stderr, "%s (0): %s.%s has no valid dna info.\n", + __func__, srna->identifier, prop->identifier); DefRNA.error= 1; return NULL; } @@ -495,7 +499,8 @@ if(prop->type == PROP_FLOAT) { if(IS_DNATYPE_FLOAT_COMPAT(dp->dnatype) == 0) { if(prop->subtype != PROP_COLOR_GAMMA) { /* colors are an exception. these get translated */ - fprintf(stderr, "rna_def_property_get_func1: %s.%s is a '%s' but wrapped as type '%s'.\n", srna->identifier, prop->identifier, dp->dnatype, RNA_property_typename(prop->type)); + fprintf(stderr, "%s (1): %s.%s is a '%s' but wrapped as type '%s'.\n", + __func__, srna->identifier, prop->identifier, dp->dnatype, RNA_property_typename(prop->type)); DefRNA.error= 1; return NULL; } @@ -503,7 +508,8 @@ } else if(prop->type == PROP_INT || prop->type == PROP_BOOLEAN || prop->type == PROP_ENUM) { if(IS_DNATYPE_INT_COMPAT(dp->dnatype) == 0) { - fprintf(stderr, "rna_def_property_get_func2: %s.%s is a '%s' but wrapped as type '%s'.\n", srna->identifier, prop->identifier, dp->dnatype, RNA_property_typename(prop->type)); + fprintf(stderr, "%s (2): %s.%s is a '%s' but wrapped as type '%s'.\n", + __func__, srna->identifier, prop->identifier, dp->dnatype, RNA_property_typename(prop->type)); DefRNA.error= 1; return NULL; } @@ -724,7 +730,8 @@ if(!manualfunc) { if(!dp->dnastructname || !dp->dnaname) { if(prop->flag & PROP_EDITABLE) { - fprintf(stderr, "rna_def_property_set_func: %s.%s has no valid dna info.\n", srna->identifier, prop->identifier); + fprintf(stderr, "%s: %s.%s has no valid dna info.\n", + __func__, srna->identifier, prop->identifier); DefRNA.error= 1; } return NULL; @@ -902,7 +909,8 @@ if(prop->type == PROP_STRING) { if(!manualfunc) { if(!dp->dnastructname || !dp->dnaname) { - fprintf(stderr, "rna_def_property_length_func: %s.%s has no valid dna info.\n", srna->identifier, prop->identifier); + fprintf(stderr, "%s: %s.%s has no valid dna info.\n", + __func__, srna->identifier, prop->identifier); DefRNA.error= 1; return NULL; } @@ -924,7 +932,8 @@ else if(prop->type == PROP_COLLECTION) { if(!manualfunc) { if(prop->type == PROP_COLLECTION && (!(dp->dnalengthname || dp->dnalengthfixed)|| !dp->dnaname)) { - fprintf(stderr, "rna_def_property_length_func: %s.%s has no valid dna info.\n", srna->identifier, prop->identifier); + fprintf(stderr, "%s: %s.%s has no valid dna info.\n", + __func__, srna->identifier, prop->identifier); DefRNA.error= 1; return NULL; } @@ -959,7 +968,8 @@ if(!manualfunc) { if(!dp->dnastructname || !dp->dnaname) { - fprintf(stderr, "rna_def_property_begin_func: %s.%s has no valid dna info.\n", srna->identifier, prop->identifier); + fprintf(stderr, "%s: %s.%s has no valid dna info.\n", + __func__, srna->identifier, prop->identifier); DefRNA.error= 1; return NULL; } @@ -1270,7 +1280,8 @@ pprop->get= (void*)rna_def_property_get_func(f, srna, prop, dp, (const char*)pprop->get); pprop->set= (void*)rna_def_property_set_func(f, srna, prop, dp, (const char*)pprop->set); if(!pprop->type) { - fprintf(stderr, "rna_def_property_funcs: %s.%s, pointer must have a struct type.\n", srna->identifier, prop->identifier); + fprintf(stderr, "%s: %s.%s, pointer must have a struct type.\n", + __func__, srna->identifier, prop->identifier); DefRNA.error= 1; } break; @@ -1298,20 +1309,24 @@ if(!(prop->flag & PROP_IDPROPERTY)) { if(!cprop->begin) { - fprintf(stderr, "rna_def_property_funcs: %s.%s, collection must have a begin function.\n", srna->identifier, prop->identifier); + fprintf(stderr, "%s: %s.%s, collection must have a begin function.\n", + __func__, srna->identifier, prop->identifier); DefRNA.error= 1; } if(!cprop->next) { - fprintf(stderr, "rna_def_property_funcs: %s.%s, collection must have a next function.\n", srna->identifier, prop->identifier); + fprintf(stderr, "%s: %s.%s, collection must have a next function.\n", + __func__, srna->identifier, prop->identifier); DefRNA.error= 1; } if(!cprop->get) { - fprintf(stderr, "rna_def_property_funcs: %s.%s, collection must have a get function.\n", srna->identifier, prop->identifier); + fprintf(stderr, "%s: %s.%s, collection must have a get function.\n", + __func__, srna->identifier, prop->identifier); DefRNA.error= 1; } } if(!cprop->item_type) { - fprintf(stderr, "rna_def_property_funcs: %s.%s, collection must have a struct type.\n", srna->identifier, prop->identifier); + fprintf(stderr, "%s: %s.%s, collection must have a struct type.\n", + __func__, srna->identifier, prop->identifier); DefRNA.error= 1; } break; @@ -2136,19 +2151,22 @@ if(prop->flag & PROP_ENUM_FLAG) { if(eprop->defaultvalue & ~totflag) { - fprintf(stderr, "rna_generate_structs: %s%s.%s, enum default includes unused bits (%d).\n", srna->identifier, errnest, prop->identifier, eprop->defaultvalue & ~totflag); + fprintf(stderr, "%s: %s%s.%s, enum default includes unused bits (%d).\n", + __func__, srna->identifier, errnest, prop->identifier, eprop->defaultvalue & ~totflag); DefRNA.error= 1; } } else { if(!defaultfound) { - fprintf(stderr, "rna_generate_structs: %s%s.%s, enum default is not in items.\n", srna->identifier, errnest, prop->identifier); + fprintf(stderr, "%s: %s%s.%s, enum default is not in items.\n", + __func__, srna->identifier, errnest, prop->identifier); DefRNA.error= 1; } } } else { - fprintf(stderr, "rna_generate_structs: %s%s.%s, enum must have items defined.\n", srna->identifier, errnest, prop->identifier); + fprintf(stderr, "%s: %s%s.%s, enum must have items defined.\n", + __func__, srna->identifier, errnest, prop->identifier); DefRNA.error= 1; } break; @@ -2229,6 +2247,7 @@ rna_print_c_string(f, prop->name); fprintf(f, ",\n\t"); rna_print_c_string(f, prop->description); fprintf(f, ",\n\t"); fprintf(f, "%d,\n", prop->icon); + rna_print_c_string(f, prop->translation_context); fprintf(f, ",\n\t"); fprintf(f, "\t%s, %s|%s, %s, %u, {%u, %u, %u}, %u,\n", RNA_property_typename(prop->type), rna_property_subtypename(prop->subtype), rna_property_subtype_unit(prop->subtype), rna_function_string(prop->getlength), prop->arraydimension, prop->arraylength[0], prop->arraylength[1], prop->arraylength[2], prop->totarraylength); fprintf(f, "\t%s%s, %d, %s, %s,\n", (prop->flag & PROP_CONTEXT_UPDATE)? "(UpdateFunc)": "", rna_function_string(prop->update), prop->noteflag, rna_function_string(prop->editable), rna_function_string(prop->itemeditable)); @@ -2261,7 +2280,7 @@ if(prop->arraydimension && prop->totarraylength) fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier); else fprintf(f, "NULL\n"); break; - } + } case PROP_FLOAT: { FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop; fprintf(f, "\t%s, %s, %s, %s, %s, ", rna_function_string(fprop->get), rna_function_string(fprop->set), rna_function_string(fprop->getarray), rna_function_string(fprop->setarray), rna_function_string(fprop->range)); @@ -2275,7 +2294,7 @@ if(prop->arraydimension && prop->totarraylength) fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier); else fprintf(f, "NULL\n"); break; - } + } case PROP_STRING: { StringPropertyRNA *sprop= (StringPropertyRNA*)prop; fprintf(f, "\t%s, %s, %s, %d, ", rna_function_string(sprop->get), rna_function_string(sprop->length), rna_function_string(sprop->set), sprop->maxlength); @@ -2298,7 +2317,7 @@ if(pprop->type) fprintf(f, "&RNA_%s\n", (const char*)pprop->type); else fprintf(f, "NULL\n"); break; - } + } case PROP_COLLECTION: { CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop; fprintf(f, "\t%s, %s, %s, %s, %s, %s, %s, %s, ", rna_function_string(cprop->begin), rna_function_string(cprop->next), rna_function_string(cprop->end), rna_function_string(cprop->get), rna_function_string(cprop->length), rna_function_string(cprop->lookupint), rna_function_string(cprop->lookupstring), rna_function_string(cprop->assignint)); @@ -2420,7 +2439,8 @@ fprintf(f, "\t%s,\n", rna_function_string(srna->idproperties)); if(srna->reg && !srna->refine) { - fprintf(stderr, "rna_generate_struct: %s has a register function, must also have refine function.\n", srna->identifier); + fprintf(stderr, "%s: %s has a register function, must also have refine function.\n", + __func__, srna->identifier); DefRNA.error= 1; } @@ -2629,6 +2649,7 @@ static const char *cpp_classes = "" "\n" "#include \n" +"#include /* for memcpy */\n" "\n" "namespace BL {\n" "\n" @@ -2754,6 +2775,7 @@ fprintf(f, "#include \"RNA_blender.h\"\n"); fprintf(f, "#include \"RNA_types.h\"\n"); + fprintf(f, "#include \"RNA_access.h\"\n"); fprintf(f, "%s", cpp_classes); @@ -2840,7 +2862,7 @@ file = fopen(deffile, "w"); if(!file) { - printf ("Unable to open file: %s\n", deffile); + fprintf(stderr, "Unable to open file: %s\n", deffile); status = 1; } else { @@ -2868,7 +2890,7 @@ file = fopen(deffile, "w"); if(!file) { - printf ("Unable to open file: %s\n", deffile); + fprintf(stderr, "Unable to open file: %s\n", deffile); status = 1; } else { @@ -2897,7 +2919,7 @@ file = fopen(deffile, "w"); if(!file) { - printf ("Unable to open file: %s\n", deffile); + fprintf(stderr, "Unable to open file: %s\n", deffile); status = 1; } else { @@ -2927,18 +2949,18 @@ int totblock, return_status = 0; if(argc<2) { - printf("Usage: %s outdirectory/\n", argv[0]); + fprintf(stderr, "Usage: %s outdirectory/\n", argv[0]); return_status = 1; } else { - printf("Running makesrna, program versions %s\n", RNA_VERSION_DATE); + fprintf(stderr, "Running makesrna, program versions %s\n", RNA_VERSION_DATE); makesrna_path= argv[0]; return_status= rna_preprocess(argv[1]); } totblock= MEM_get_memory_blocks_in_use(); if(totblock!=0) { - printf("Error Totblock: %d\n",totblock); + fprintf(stderr, "Error Totblock: %d\n",totblock); MEM_set_error_callback(mem_error_cb); MEM_printmemlist(); } diff -Nru blender-2.61/source/blender/makesrna/intern/rna_access.c blender-2.62/source/blender/makesrna/intern/rna_access.c --- blender-2.61/source/blender/makesrna/intern/rna_access.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_access.c 2012-02-15 19:35:15.000000000 +0000 @@ -226,6 +226,12 @@ /* ID Properties */ +static void rna_idproperty_touch(IDProperty *idprop) +{ + /* so the property is seen as 'set' by rna */ + idprop->flag &= ~IDP_FLAG_GHOST; +} + /* return a UI local ID prop definition for this prop */ IDProperty *rna_idproperty_ui(PropertyRNA *prop) { @@ -486,8 +492,12 @@ name= ((IDProperty*)prop)->name; #ifdef WITH_INTERNATIONAL - if((U.transopts&USER_DOTRANSLATE) && (U.transopts&USER_TR_IFACE)) - name= BLF_gettext(name); + if((U.transopts&USER_DOTRANSLATE) && (U.transopts&USER_TR_IFACE)) { + if(prop->translation_context) + name = BLF_pgettext(prop->translation_context, name); + else + name = BLF_gettext(name); + } #endif return name; @@ -837,12 +847,17 @@ PropertySubType subtype= rna_ensure_property(prop)->subtype; /* get string to use for array index */ - if ((index < 4) && ELEM(subtype, PROP_QUATERNION, PROP_AXISANGLE)) + if ((index < 4) && ELEM(subtype, PROP_QUATERNION, PROP_AXISANGLE)) { return quatitem[index]; - else if((index < 4) && ELEM8(subtype, PROP_TRANSLATION, PROP_DIRECTION, PROP_XYZ, PROP_XYZ_LENGTH, PROP_EULER, PROP_VELOCITY, PROP_ACCELERATION, PROP_COORDS)) + } + else if((index < 4) && ELEM8(subtype, PROP_TRANSLATION, PROP_DIRECTION, PROP_XYZ, PROP_XYZ_LENGTH, + PROP_EULER, PROP_VELOCITY, PROP_ACCELERATION, PROP_COORDS)) + { return vectoritem[index]; - else if ((index < 4) && ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA)) + } + else if ((index < 4) && ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA)) { return coloritem[index]; + } return '\0'; } @@ -865,7 +880,9 @@ return 3; } } - else if(ELEM6(subtype, PROP_TRANSLATION, PROP_DIRECTION, PROP_XYZ, PROP_EULER, PROP_VELOCITY, PROP_ACCELERATION)) { + else if(ELEM6(subtype, PROP_TRANSLATION, PROP_DIRECTION, PROP_XYZ, + PROP_EULER, PROP_VELOCITY, PROP_ACCELERATION)) + { switch (name) { case 'x': return 0; @@ -1187,8 +1204,12 @@ } for(i=0; nitem[i].identifier; i++) { - if( nitem[i].name ) - nitem[i].name = BLF_gettext(nitem[i].name); + if( nitem[i].name ) { + if(prop->translation_context) + nitem[i].name = BLF_pgettext(prop->translation_context, nitem[i].name); + else + nitem[i].name = BLF_gettext(nitem[i].name); + } if( nitem[i].description ) nitem[i].description = BLF_gettext(nitem[i].description); } @@ -1519,7 +1540,8 @@ /* find cache element for which key matches... */ for (uce = rna_updates_cache.first; uce; uce = uce->next) { /* just match by id only for now, since most update calls that we'll encounter only really care about this */ - // TODO: later, the cache might need to have some nesting on L1 to cope better with these problems + some tagging to indicate we need this + /* TODO: later, the cache might need to have some nesting on L1 to cope better + * with these problems + some tagging to indicate we need this */ if (uce->ptr.id.data == ptr->id.data) break; } @@ -1605,8 +1627,10 @@ /* just incase other values are passed */ if(value) value= 1; - if((idprop=rna_idproperty_check(&prop, ptr))) + if((idprop=rna_idproperty_check(&prop, ptr))) { IDP_Int(idprop)= value; + rna_idproperty_touch(idprop); + } else if(bprop->set) bprop->set(ptr, value); else if(prop->flag & PROP_EDITABLE) { @@ -1682,6 +1706,8 @@ IDP_Int(idprop)= values[0]; else memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len); + + rna_idproperty_touch(idprop); } else if(prop->arraydimension == 0) RNA_property_boolean_set(ptr, prop, values[0]); @@ -1802,8 +1828,10 @@ /* useful to check on bad values but set function should clamp */ /* BLI_assert(RNA_property_int_clamp(ptr, prop, &value) == 0); */ - if((idprop=rna_idproperty_check(&prop, ptr))) + if((idprop=rna_idproperty_check(&prop, ptr))) { IDP_Int(idprop)= value; + rna_idproperty_touch(idprop); + } else if(iprop->set) iprop->set(ptr, value); else if(prop->flag & PROP_EDITABLE) { @@ -1915,7 +1943,9 @@ if(prop->arraydimension == 0) IDP_Int(idprop)= values[0]; else - memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);\ + memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len); + + rna_idproperty_touch(idprop); } else if(prop->arraydimension == 0) RNA_property_int_set(ptr, prop, values[0]); @@ -2038,6 +2068,8 @@ IDP_Float(idprop)= value; else IDP_Double(idprop)= value; + + rna_idproperty_touch(idprop); } else if(fprop->set) { fprop->set(ptr, value); @@ -2169,6 +2201,8 @@ for(i=0; ilen; i++) ((double*)IDP_Array(idprop))[i]= values[i]; } + + rna_idproperty_touch(idprop); } else if(prop->arraydimension == 0) RNA_property_float_set(ptr, prop, values[0]); @@ -2356,9 +2390,11 @@ BLI_assert(RNA_property_type(prop) == PROP_STRING); - if((idprop=rna_idproperty_check(&prop, ptr))) + if((idprop=rna_idproperty_check(&prop, ptr))) { /* both IDP_STRING_SUB_BYTE / IDP_STRING_SUB_UTF8 */ IDP_AssignString(idprop, value, RNA_property_string_maxlength(prop) - 1); + rna_idproperty_touch(idprop); + } else if(sprop->set) sprop->set(ptr, value); /* set function needs to clamp its self */ else if(prop->flag & PROP_EDITABLE) { @@ -2430,8 +2466,10 @@ BLI_assert(RNA_property_type(prop) == PROP_ENUM); - if((idprop=rna_idproperty_check(&prop, ptr))) + if((idprop=rna_idproperty_check(&prop, ptr))) { IDP_Int(idprop)= value; + rna_idproperty_touch(idprop); + } else if(eprop->set) { eprop->set(ptr, value); } @@ -2500,6 +2538,7 @@ if((/*idprop=*/ rna_idproperty_check(&prop, ptr))) { /* not supported */ + /* rna_idproperty_touch(idprop); */ } else { PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop; @@ -3940,6 +3979,8 @@ } } } + if(path) + break; } } } @@ -4396,15 +4437,23 @@ } } -int RNA_property_is_set(PointerRNA *ptr, const char *name) +int RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop) { - PropertyRNA *prop= RNA_struct_find_property(ptr, name); + if(prop->flag & PROP_IDPROPERTY) { + IDProperty *idprop = rna_idproperty_find(ptr, prop->identifier); + return ((idprop != NULL) && !(idprop->flag & IDP_FLAG_GHOST)); + } + else { + return 1; + } +} + +int RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier) +{ + PropertyRNA *prop= RNA_struct_find_property(ptr, identifier); if(prop) { - if(prop->flag & PROP_IDPROPERTY) - return (rna_idproperty_find(ptr, name) != NULL); - else - return 1; + return RNA_property_is_set(ptr, prop); } else { /* python raises an error */ @@ -4698,8 +4747,15 @@ break; case PROP_STRING: { const char *defvalue= ((StringPropertyRNA*)parm)->defaultvalue; - if(defvalue && defvalue[0]) + if(defvalue && defvalue[0]) { + /* causes bug [#29988], possibly this is only correct for thick wrapped + * need to look further into it - campbell */ +#if 0 + BLI_strncpy(data, defvalue, size); +#else memcpy(data, &defvalue, size); +#endif + } break; } case PROP_POINTER: @@ -4969,7 +5025,9 @@ return 0; } -static int rna_function_parameter_parse(PointerRNA *ptr, PropertyRNA *prop, PropertyType type, char ftype, int len, void *dest, void *src, StructRNA *srna, const char *tid, const char *fid, const char *pid) +static int rna_function_parameter_parse(PointerRNA *ptr, PropertyRNA *prop, PropertyType type, + char ftype, int len, void *dest, void *src, StructRNA *srna, + const char *tid, const char *fid, const char *pid) { /* ptr is always a function pointer, prop always a parameter */ @@ -5055,7 +5113,9 @@ } if (ptype!=srna && !RNA_struct_is_a(srna, ptype)) { - fprintf(stderr, "%s.%s: wrong type for parameter %s, an object of type %s was expected, passed an object of type %s\n", tid, fid, pid, RNA_struct_identifier(ptype), RNA_struct_identifier(srna)); + fprintf(stderr, "%s.%s: wrong type for parameter %s, " + "an object of type %s was expected, passed an object of type %s\n", + tid, fid, pid, RNA_struct_identifier(ptype), RNA_struct_identifier(srna)); return -1; } @@ -5080,7 +5140,10 @@ ptype= RNA_property_pointer_type(ptr, prop); if (ptype!=srna && !RNA_struct_is_a(srna, ptype)) { - fprintf(stderr, "%s.%s: wrong type for parameter %s, a collection of objects of type %s was expected, passed a collection of objects of type %s\n", tid, fid, pid, RNA_struct_identifier(ptype), RNA_struct_identifier(srna)); + fprintf(stderr, "%s.%s: wrong type for parameter %s, " + "a collection of objects of type %s was expected, " + "passed a collection of objects of type %s\n", + tid, fid, pid, RNA_struct_identifier(ptype), RNA_struct_identifier(srna)); return -1; } @@ -5159,7 +5222,10 @@ if (len!=alen) { err= -1; - fprintf(stderr, "%s.%s: for parameter %s, was expecting an array of %i elements, passed %i elements instead\n", tid, fid, pid, len, alen); + fprintf(stderr, "%s.%s: for parameter %s, " + "was expecting an array of %i elements, " + "passed %i elements instead\n", + tid, fid, pid, len, alen); break; } @@ -5224,7 +5290,9 @@ if (len!=alen) { err= -1; - fprintf(stderr, "%s.%s: for return parameter %s, was expecting an array of %i elements, passed %i elements instead\n", tid, fid, pid, len, alen); + fprintf(stderr, "%s.%s: for return parameter %s, " + "was expecting an array of %i elements, passed %i elements instead\n", + tid, fid, pid, len, alen); } else { switch (type) { @@ -5278,7 +5346,8 @@ return err; } -int RNA_function_call_direct_va_lookup(bContext *C, ReportList *reports, PointerRNA *ptr, const char *identifier, const char *format, va_list args) +int RNA_function_call_direct_va_lookup(bContext *C, ReportList *reports, PointerRNA *ptr, + const char *identifier, const char *format, va_list args) { FunctionRNA *func; diff -Nru blender-2.61/source/blender/makesrna/intern/rna_actuator.c blender-2.62/source/blender/makesrna/intern/rna_actuator.c --- blender-2.61/source/blender/makesrna/intern/rna_actuator.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_actuator.c 2012-02-15 19:35:15.000000000 +0000 @@ -867,8 +867,10 @@ PropertyRNA *prop; static EnumPropertyItem prop_axis_items[] ={ - {ACT_CAMERA_X, "X", 0, "X", "Camera tries to get behind the X axis"}, - {ACT_CAMERA_Y, "Y", 0, "Y", "Camera tries to get behind the Y axis"}, + {OB_POSX, "POS_X", 0, "+X", "Camera tries to get behind the X axis"}, + {OB_POSY, "POS_Y", 0, "+Y", "Camera tries to get behind the Y axis"}, + {OB_NEGX, "NEG_X", 0, "-X", "Camera tries to get behind the -X axis"}, + {OB_NEGY, "NEG_Y", 0, "-Y", "Camera tries to get behind the -Y axis"}, {0, NULL, 0, NULL, NULL}}; srna= RNA_def_struct(brna, "CameraActuator", "Actuator"); @@ -905,7 +907,7 @@ RNA_def_property_ui_text(prop, "Damping", "Strength of the constraint that drives the camera behind the target"); RNA_def_property_update(prop, NC_LOGIC, NULL); - /* x/y */ + /* +x/+y/-x/-y */ prop= RNA_def_property(srna, "axis", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "axis"); RNA_def_property_enum_items(prop, prop_axis_items); diff -Nru blender-2.61/source/blender/makesrna/intern/rna_brush.c blender-2.62/source/blender/makesrna/intern/rna_brush.c --- blender-2.61/source/blender/makesrna/intern/rna_brush.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_brush.c 2012-02-15 19:35:15.000000000 +0000 @@ -69,13 +69,13 @@ EnumPropertyItem brush_vertex_tool_items[] = { - {0, "MIX", ICON_BRUSH_MIX, "Mix", "Use mix blending mode while painting"}, - {1, "ADD", ICON_BRUSH_ADD, "Add", "Use add blending mode while painting"}, - {2, "SUB", ICON_BRUSH_SUBTRACT, "Subtract", "Use subtract blending mode while painting"}, - {3, "MUL", ICON_BRUSH_MULTIPLY, "Multiply", "Use multiply blending mode while painting"}, - {4, "BLUR", ICON_BRUSH_BLUR, "Blur", "Blur the color with surrounding values"}, - {5, "LIGHTEN", ICON_BRUSH_LIGHTEN, "Lighten", "Use lighten blending mode while painting"}, - {6, "DARKEN", ICON_BRUSH_DARKEN, "Darken", "Use darken blending mode while painting"}, + {PAINT_BLEND_MIX, "MIX", ICON_BRUSH_MIX, "Mix", "Use mix blending mode while painting"}, + {PAINT_BLEND_ADD, "ADD", ICON_BRUSH_ADD, "Add", "Use add blending mode while painting"}, + {PAINT_BLEND_SUB, "SUB", ICON_BRUSH_SUBTRACT, "Subtract", "Use subtract blending mode while painting"}, + {PAINT_BLEND_MUL, "MUL", ICON_BRUSH_MULTIPLY, "Multiply", "Use multiply blending mode while painting"}, + {PAINT_BLEND_BLUR, "BLUR", ICON_BRUSH_BLUR, "Blur", "Blur the color with surrounding values"}, + {PAINT_BLEND_LIGHTEN, "LIGHTEN", ICON_BRUSH_LIGHTEN, "Lighten", "Use lighten blending mode while painting"}, + {PAINT_BLEND_DARKEN, "DARKEN", ICON_BRUSH_DARKEN, "Darken", "Use darken blending mode while painting"}, {0, NULL, 0, NULL, NULL}}; EnumPropertyItem brush_image_tool_items[] = { @@ -164,96 +164,21 @@ static void rna_Brush_set_size(PointerRNA *ptr, int value) { - Brush* me = (Brush*)(ptr->data); + Brush* brush = ptr->data; - float size= (float)brush_size(me); - float unprojected_radius; - - // paranoia: previous checks should make sure we don't divide by zero - assert(size != 0); - - // set unprojected radius, so it remains consistent with size - unprojected_radius= (float)(brush_unprojected_radius(me) * value / size); - brush_set_unprojected_radius(me, unprojected_radius); - - brush_set_size(me, value); -} - -static int rna_Brush_get_size(PointerRNA *ptr) -{ - Brush* me = (Brush*)(ptr->data); - return brush_size(me); -} - -static void rna_Brush_set_use_locked_size(PointerRNA *ptr, int value) -{ - Brush* me = (Brush*)(ptr->data); - brush_set_use_locked_size(me, value); -} - -static int rna_Brush_get_use_locked_size(PointerRNA *ptr) -{ - Brush* me = (Brush*)(ptr->data); - return brush_use_locked_size(me); -} - -static void rna_Brush_set_use_size_pressure(PointerRNA *ptr, int value) -{ - Brush* me = (Brush*)(ptr->data); - brush_set_use_size_pressure(me, value); -} - -static int rna_Brush_get_use_size_pressure(PointerRNA *ptr) -{ - Brush* me = (Brush*)(ptr->data); - return brush_use_size_pressure(me); -} - -static void rna_Brush_set_use_alpha_pressure(PointerRNA *ptr, int value) -{ - Brush* me = (Brush*)(ptr->data); - brush_set_use_alpha_pressure(me, value); -} - -static int rna_Brush_get_use_alpha_pressure(PointerRNA *ptr) -{ - Brush* me = (Brush*)(ptr->data); - return brush_use_alpha_pressure(me); + /* scale unprojected radius so it stays consistent with brush size */ + brush_scale_unprojected_radius(&brush->unprojected_radius, + value, brush->size); + brush->size= value; } static void rna_Brush_set_unprojected_radius(PointerRNA *ptr, float value) { - Brush* me = (Brush*)(ptr->data); - - float unprojected_radius= brush_unprojected_radius(me); - int size; - - // paranoia: previous checks should make sure we don't divide by zero - assert(unprojected_radius != 0.0f); - - // set size, so that it is consistent with unprojected_radius - size= (int)((float)brush_size(me) * value / unprojected_radius); - brush_set_size(me, size); - - brush_set_unprojected_radius(me, value); -} - -static float rna_Brush_get_unprojected_radius(PointerRNA *ptr) -{ - Brush* me = (Brush*)(ptr->data); - return brush_unprojected_radius(me); -} + Brush* brush = ptr->data; -static void rna_Brush_set_alpha(PointerRNA *ptr, float value) -{ - Brush* me = (Brush*)(ptr->data); - brush_set_alpha(me, value); -} - -static float rna_Brush_get_alpha(PointerRNA *ptr) -{ - Brush* me = (Brush*)(ptr->data); - return brush_alpha(me); + /* scale brush size so it stays consistent with unprojected_radius */ + brush_scale_size(&brush->size, value, brush->unprojected_radius); + brush->unprojected_radius= value; } static EnumPropertyItem *rna_Brush_direction_itemf(bContext *UNUSED(C), PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *UNUSED(free)) @@ -448,14 +373,14 @@ /* number values */ prop= RNA_def_property(srna, "size", PROP_INT, PROP_DISTANCE); - RNA_def_property_int_funcs(prop, "rna_Brush_get_size", "rna_Brush_set_size", NULL); + RNA_def_property_int_funcs(prop, NULL, "rna_Brush_set_size", NULL); RNA_def_property_range(prop, 1, MAX_BRUSH_PIXEL_RADIUS*10); RNA_def_property_ui_range(prop, 1, MAX_BRUSH_PIXEL_RADIUS, 1, 0); RNA_def_property_ui_text(prop, "Radius", "Radius of the brush in pixels"); RNA_def_property_update(prop, 0, "rna_Brush_update"); prop= RNA_def_property(srna, "unprojected_radius", PROP_FLOAT, PROP_DISTANCE); - RNA_def_property_float_funcs(prop, "rna_Brush_get_unprojected_radius", "rna_Brush_set_unprojected_radius", NULL); + RNA_def_property_float_funcs(prop, NULL, "rna_Brush_set_unprojected_radius", NULL); RNA_def_property_range(prop, 0.001, FLT_MAX); RNA_def_property_ui_range(prop, 0.001, 1, 0, 0); RNA_def_property_ui_text(prop, "Unprojected Radius", "Radius of brush in Blender units"); @@ -499,7 +424,6 @@ prop= RNA_def_property(srna, "strength", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "alpha"); - RNA_def_property_float_funcs(prop, "rna_Brush_get_alpha", "rna_Brush_set_alpha", NULL); RNA_def_property_float_default(prop, 0.5f); RNA_def_property_range(prop, 0.0f, 10.0f); RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.001, 0.001); @@ -575,7 +499,6 @@ prop= RNA_def_property(srna, "use_pressure_strength", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_ALPHA_PRESSURE); - RNA_def_property_boolean_funcs(prop, "rna_Brush_get_use_alpha_pressure", "rna_Brush_set_use_alpha_pressure"); RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); RNA_def_property_ui_text(prop, "Strength Pressure", "Enable tablet pressure sensitivity for strength"); RNA_def_property_update(prop, 0, "rna_Brush_update"); @@ -588,7 +511,6 @@ prop= RNA_def_property(srna, "use_pressure_size", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_SIZE_PRESSURE); - RNA_def_property_boolean_funcs(prop, "rna_Brush_get_use_size_pressure", "rna_Brush_set_use_size_pressure"); RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); RNA_def_property_ui_text(prop, "Size Pressure", "Enable tablet pressure sensitivity for size"); RNA_def_property_update(prop, 0, "rna_Brush_update"); @@ -668,7 +590,6 @@ RNA_def_property_update(prop, 0, "rna_Brush_update"); prop= RNA_def_property(srna, "use_locked_size", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_Brush_get_use_locked_size", "rna_Brush_set_use_locked_size"); RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_LOCK_SIZE); RNA_def_property_ui_text(prop, "Use Blender Units", "When locked brush stays same size relative to object; when unlocked brush size is given in pixels"); RNA_def_property_update(prop, 0, "rna_Brush_update"); diff -Nru blender-2.61/source/blender/makesrna/intern/rna_cloth.c blender-2.62/source/blender/makesrna/intern/rna_cloth.c --- blender-2.61/source/blender/makesrna/intern/rna_cloth.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_cloth.c 2012-02-15 19:35:15.000000000 +0000 @@ -289,6 +289,14 @@ RNA_def_property_ui_text(prop, "Air Damping", "Air has normally some thickness which slows falling things down"); RNA_def_property_update(prop, 0, "rna_cloth_update"); + prop= RNA_def_property(srna, "vel_damping", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "vel_damping"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Velocity Damping", + "Damp velocity to help cloth reach the resting position faster " + "(1.0 = no damping, 0.0 = fully dampened)"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); + prop= RNA_def_property(srna, "use_pin_cloth", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", CLOTH_SIMSETTINGS_FLAG_GOAL); RNA_def_property_ui_text(prop, "Pin Cloth", "Enable pinning of cloth vertices to other objects/positions"); diff -Nru blender-2.61/source/blender/makesrna/intern/rna_constraint.c blender-2.62/source/blender/makesrna/intern/rna_constraint.c --- blender-2.61/source/blender/makesrna/intern/rna_constraint.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_constraint.c 2012-02-15 19:35:15.000000000 +0000 @@ -45,6 +45,7 @@ EnumPropertyItem constraint_type_items[] ={ {0, "", 0, "Motion Tracking", ""}, {CONSTRAINT_TYPE_CAMERASOLVER, "CAMERA_SOLVER", ICON_CONSTRAINT_DATA, "Camera Solver", ""}, + {CONSTRAINT_TYPE_OBJECTSOLVER, "OBJECT_SOLVER", ICON_CONSTRAINT_DATA, "Object Solver", ""}, {CONSTRAINT_TYPE_FOLLOWTRACK, "FOLLOW_TRACK", ICON_CONSTRAINT_DATA, "Follow Track", ""}, {0, "", 0, "Transform", ""}, {CONSTRAINT_TYPE_LOCLIKE, "COPY_LOCATION", ICON_CONSTRAINT_DATA, "Copy Location", ""}, @@ -77,24 +78,24 @@ {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem target_space_pchan_items[] = { - {0, "WORLD", 0, "World Space", "The transformation of the target is evaluated relative to the world coordinate system"}, - {2, "POSE", 0, "Pose Space", "The transformation of the target is only evaluated in the Pose Space, the target armature object transformation is ignored"}, - {3, "LOCAL_WITH_PARENT", 0, "Local With Parent", "The transformation of the target bone is evaluated relative its local coordinate system, with the parent transformation added"}, - {1, "LOCAL", 0, "Local Space", "The transformation of the target is evaluated relative to its local coordinate system"}, + {CONSTRAINT_SPACE_WORLD, "WORLD", 0, "World Space", "The transformation of the target is evaluated relative to the world coordinate system"}, + {CONSTRAINT_SPACE_POSE, "POSE", 0, "Pose Space", "The transformation of the target is only evaluated in the Pose Space, the target armature object transformation is ignored"}, + {CONSTRAINT_SPACE_PARLOCAL, "LOCAL_WITH_PARENT", 0, "Local With Parent", "The transformation of the target bone is evaluated relative its local coordinate system, with the parent transformation added"}, + {CONSTRAINT_SPACE_LOCAL, "LOCAL", 0, "Local Space", "The transformation of the target is evaluated relative to its local coordinate system"}, {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem owner_space_pchan_items[] = { - {0, "WORLD", 0, "World Space", "The constraint is applied relative to the world coordinate system"}, - {2, "POSE", 0, "Pose Space", "The constraint is applied in Pose Space, the object transformation is ignored"}, - {3, "LOCAL_WITH_PARENT", 0, "Local With Parent", "The constraint is applied relative to the local coordinate system of the object, with the parent transformation added"}, - {1, "LOCAL", 0, "Local Space", "The constraint is applied relative to the local coordinate sytem of the object"}, + {CONSTRAINT_SPACE_WORLD, "WORLD", 0, "World Space", "The constraint is applied relative to the world coordinate system"}, + {CONSTRAINT_SPACE_POSE, "POSE", 0, "Pose Space", "The constraint is applied in Pose Space, the object transformation is ignored"}, + {CONSTRAINT_SPACE_PARLOCAL, "LOCAL_WITH_PARENT", 0, "Local With Parent", "The constraint is applied relative to the local coordinate system of the object, with the parent transformation added"}, + {CONSTRAINT_SPACE_LOCAL, "LOCAL", 0, "Local Space", "The constraint is applied relative to the local coordinate sytem of the object"}, {0, NULL, 0, NULL, NULL}}; #ifdef RNA_RUNTIME static EnumPropertyItem space_object_items[] = { - {0, "WORLD", 0, "World Space", "The transformation of the target is evaluated relative to the world coordinate system"}, - {1, "LOCAL", 0, "Local Space", "The transformation of the target is evaluated relative to its local coordinate system"}, + {CONSTRAINT_SPACE_WORLD, "WORLD", 0, "World Space", "The transformation of the target is evaluated relative to the world coordinate system"}, + {CONSTRAINT_SPACE_LOCAL, "LOCAL", 0, "Local Space", "The transformation of the target is evaluated relative to its local coordinate system"}, {0, NULL, 0, NULL, NULL}}; #include "BKE_animsys.h" @@ -163,6 +164,8 @@ return &RNA_FollowTrackConstraint; case CONSTRAINT_TYPE_CAMERASOLVER: return &RNA_CameraSolverConstraint; + case CONSTRAINT_TYPE_OBJECTSOLVER: + return &RNA_ObjectSolverConstraint; default: return &RNA_UnknownType; } @@ -290,8 +293,8 @@ /* 0, 1, 2 = magic numbers for rotX, rotY, rotZ */ if (ELEM3(acon->type, 0, 1, 2)) { - *min= -90.f; - *max= 90.f; + *min= -180.0f; + *max= 180.0f; } else { *min= -1000.f; *max= 1000.f; @@ -327,6 +330,77 @@ memcpy(ikData->points, values, ikData->numpoints * sizeof(float)); } +static int rna_Constraint_cameraObject_poll(PointerRNA *ptr, PointerRNA value) +{ + Object *ob= (Object*)value.data; + + if (ob) { + if (ob->type == OB_CAMERA && ob != (Object*)ptr->id.data) { + return 1; + } + } + + return 0; +} + +static void rna_Constraint_followTrack_camera_set(PointerRNA *ptr, PointerRNA value) +{ + bConstraint *con= (bConstraint*)ptr->data; + bFollowTrackConstraint *data= (bFollowTrackConstraint*)con->data; + Object *ob= (Object*)value.data; + + if (ob) { + if (ob->type == OB_CAMERA && ob != (Object*)ptr->id.data) { + data->camera= ob; + } + } else { + data->camera= NULL; + } +} + +static void rna_Constraint_followTrack_depthObject_set(PointerRNA *ptr, PointerRNA value) +{ + bConstraint *con= (bConstraint*)ptr->data; + bFollowTrackConstraint *data= (bFollowTrackConstraint*)con->data; + Object *ob= (Object*)value.data; + + if (ob) { + if (ob->type == OB_MESH && ob != (Object*)ptr->id.data) { + data->depth_ob= ob; + } + } else { + data->depth_ob= NULL; + } +} + +static int rna_Constraint_followTrack_depthObject_poll(PointerRNA *ptr, PointerRNA value) +{ + Object *ob= (Object*)value.data; + + if(ob) { + if (ob->type == OB_MESH && ob != (Object*)ptr->id.data) { + return 1; + } + } + + return 0; +} + +static void rna_Constraint_objectSolver_camera_set(PointerRNA *ptr, PointerRNA value) +{ + bConstraint *con= (bConstraint*)ptr->data; + bObjectSolverConstraint *data= (bObjectSolverConstraint*)con->data; + Object *ob= (Object*)value.data; + + if (ob) { + if (ob->type == OB_CAMERA && ob != (Object*)ptr->id.data) { + data->camera= ob; + } + } else { + data->camera= NULL; + } +} + #else EnumPropertyItem constraint_distance_items[] = { @@ -952,15 +1026,15 @@ PropertyRNA *prop; static EnumPropertyItem transform_channel_items[] = { - {20, "LOCATION_X", 0, "Location X", ""}, - {21, "LOCATION_Y", 0, "Location Y", ""}, - {22, "LOCATION_Z", 0, "Location Z", ""}, - {00, "ROTATION_X", 0, "Rotation X", ""}, - {01, "ROTATION_Y", 0, "Rotation Y", ""}, - {02, "ROTATION_Z", 0, "Rotation Z", ""}, - {10, "SCALE_X", 0, "Scale X", ""}, - {11, "SCALE_Y", 0, "Scale Y", ""}, - {12, "SCALE_Z", 0, "Scale Z", ""}, + {20, "LOCATION_X", 0, "X Location", ""}, + {21, "LOCATION_Y", 0, "Y Location", ""}, + {22, "LOCATION_Z", 0, "Z Location", ""}, + {00, "ROTATION_X", 0, "X Rotation", ""}, + {01, "ROTATION_Y", 0, "Y Rotation", ""}, + {02, "ROTATION_Z", 0, "Z Rotation", ""}, + {10, "SCALE_X", 0, "X Scale", ""}, + {11, "SCALE_Y", 0, "Y Scale", ""}, + {12, "SCALE_Z", 0, "Z Scale", ""}, {0, NULL, 0, NULL, NULL}}; srna= RNA_def_struct(brna, "ActionConstraint", "Constraint"); @@ -1937,12 +2011,12 @@ RNA_def_property_int_sdna(prop, NULL, "chainlen"); RNA_def_property_range(prop, 1, 255); // TODO: this should really check the max length of the chain the constraint is attached to RNA_def_property_ui_text(prop, "Chain Length", "How many bones are included in the chain"); - RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update"); + RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update"); // XXX: this update goes wrong... needs extra flush? /* direct access to bindings */ // NOTE: only to be used by experienced users prop= RNA_def_property(srna, "joint_bindings", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_array(prop, 32); // XXX this is the maximum value allowed + RNA_def_property_array(prop, 32); // XXX this is the maximum value allowed - why? RNA_def_property_flag(prop, PROP_DYNAMIC); RNA_def_property_dynamic_array_funcs(prop, "rna_SplineIKConstraint_joint_bindings_get_length"); RNA_def_property_float_funcs(prop, "rna_SplineIKConstraint_joint_bindings_get", "rna_SplineIKConstraint_joint_bindings_set", NULL); @@ -2066,6 +2140,28 @@ RNA_def_property_boolean_sdna(prop, NULL, "flag", FOLLOWTRACK_USE_3D_POSITION); RNA_def_property_ui_text(prop, "3D Position", "Use 3D position of track to parent to"); RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update"); + + /* object */ + prop= RNA_def_property(srna, "object", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "object"); + RNA_def_property_ui_text(prop, "Object", "Movie tracking object to follow (if empty, camera object is used)"); + RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update"); + + /* camera */ + prop= RNA_def_property(srna, "camera", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "camera"); + RNA_def_property_ui_text(prop, "Camera", "Camera to which motion is parented (if empty active scene camera is used)"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update"); + RNA_def_property_pointer_funcs(prop, NULL, "rna_Constraint_followTrack_camera_set", NULL, "rna_Constraint_cameraObject_poll"); + + /* depth object */ + prop= RNA_def_property(srna, "depth_object", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "depth_ob"); + RNA_def_property_ui_text(prop, "Depth Object", "Object used to define depth in camera space by projecting onto surface of this object"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update"); + RNA_def_property_pointer_funcs(prop, NULL, "rna_Constraint_followTrack_depthObject_set", NULL, "rna_Constraint_followTrack_depthObject_poll"); } static void rna_def_constraint_camera_solver(BlenderRNA *brna) @@ -2074,7 +2170,7 @@ PropertyRNA *prop; srna= RNA_def_struct(brna, "CameraSolverConstraint", "Constraint"); - RNA_def_struct_ui_text(srna, "Follow Track Constraint", "Lock motion to the reconstructed camera movement"); + RNA_def_struct_ui_text(srna, "Camera Solver Constraint", "Lock motion to the reconstructed camera movement"); RNA_def_struct_sdna_from(srna, "bCameraSolverConstraint", "data"); /* movie clip */ @@ -2091,6 +2187,43 @@ RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update"); } +static void rna_def_constraint_object_solver(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna= RNA_def_struct(brna, "ObjectSolverConstraint", "Constraint"); + RNA_def_struct_ui_text(srna, "Object Solver Constraint", "Lock motion to the reconstructed object movement"); + RNA_def_struct_sdna_from(srna, "bObjectSolverConstraint", "data"); + + /* movie clip */ + prop= RNA_def_property(srna, "clip", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "clip"); + RNA_def_property_ui_text(prop, "Movie Clip", "Movie Clip to get tracking data from"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update"); + + /* use default clip */ + prop= RNA_def_property(srna, "use_active_clip", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", CAMERASOLVER_ACTIVECLIP); + RNA_def_property_ui_text(prop, "Active Clip", "Use active clip defined in scene"); + RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update"); + + /* object */ + prop= RNA_def_property(srna, "object", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "object"); + RNA_def_property_ui_text(prop, "Object", "Movie tracking object to follow"); + RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update"); + + /* camera */ + prop= RNA_def_property(srna, "camera", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "camera"); + RNA_def_property_ui_text(prop, "Camera", "Camera to which motion is parented (if empty active scene camera is used)"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update"); + RNA_def_property_pointer_funcs(prop, NULL, "rna_Constraint_objectSolver_camera_set", NULL, "rna_Constraint_cameraObject_poll"); +} + /* base struct for constraints */ void RNA_def_constraint(BlenderRNA *brna) { @@ -2203,6 +2336,7 @@ rna_def_constraint_pivot(brna); rna_def_constraint_follow_track(brna); rna_def_constraint_camera_solver(brna); + rna_def_constraint_object_solver(brna); } #endif diff -Nru blender-2.61/source/blender/makesrna/intern/rna_controller.c blender-2.62/source/blender/makesrna/intern/rna_controller.c --- blender-2.61/source/blender/makesrna/intern/rna_controller.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_controller.c 2012-02-15 19:35:15.000000000 +0000 @@ -48,6 +48,7 @@ #ifdef RNA_RUNTIME #include "BKE_sca.h" +#include "DNA_actuator_types.h" static struct StructRNA* rna_Controller_refine(struct PointerRNA *ptr) { @@ -132,6 +133,18 @@ cont->state_mask = (1 << (value - 1)); } +static void rna_Controller_actuators_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +{ + bController *cont = (bController *)ptr->data; + rna_iterator_array_begin(iter, cont->links, sizeof(bActuator *), (int)cont->totlinks, 0, NULL); +} + +static int rna_Controller_actuators_length(PointerRNA *ptr) +{ + bController *cont = (bController *)ptr->data; + return (int) cont->totlinks; +} + #if 0 /* editable is set to false, comment for now. */ static void rna_Controller_state_get(PointerRNA *ptr, int *values) { @@ -212,6 +225,12 @@ RNA_def_property_ui_icon(prop, ICON_BOOKMARKS, 1); RNA_def_property_update(prop, NC_LOGIC, NULL); + prop= RNA_def_property(srna, "actuators", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "links", NULL); + RNA_def_property_struct_type(prop, "Actuator"); + RNA_def_property_ui_text(prop, "Actuators", "The list containing the actuators connected to the controller"); + RNA_def_property_collection_funcs(prop, "rna_Controller_actuators_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_dereference_get", "rna_Controller_actuators_length", NULL, NULL, NULL); + /* State */ // array of OB_MAX_STATES diff -Nru blender-2.61/source/blender/makesrna/intern/rna_curve.c blender-2.62/source/blender/makesrna/intern/rna_curve.c --- blender-2.61/source/blender/makesrna/intern/rna_curve.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_curve.c 2012-02-15 19:35:15.000000000 +0000 @@ -1386,9 +1386,14 @@ prop= RNA_def_property(srna, "use_fill_deform", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_DEFORM_FILL); - RNA_def_property_ui_text(prop, "Fill deformed", "Fill curve after applying shape keys and all modifiers"); + RNA_def_property_ui_text(prop, "Fill Deformed", "Fill curve after applying shape keys and all modifiers"); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); - + + prop= RNA_def_property(srna, "use_fill_caps", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_FILL_CAPS); + RNA_def_property_ui_text(prop, "Fill Caps", "Fill caps for bevelled curves"); + RNA_def_property_update(prop, 0, "rna_Curve_update_data"); + /* texture space */ prop= RNA_def_property(srna, "use_auto_texspace", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "texflag", CU_AUTOSPACE); diff -Nru blender-2.61/source/blender/makesrna/intern/rna_define.c blender-2.62/source/blender/makesrna/intern/rna_define.c --- blender-2.61/source/blender/makesrna/intern/rna_define.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_define.c 2012-02-15 19:35:15.000000000 +0000 @@ -1628,6 +1628,7 @@ void RNA_def_property_float_sdna(PropertyRNA *prop, const char *structname, const char *propname) { PropertyDefRNA *dp; + FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop; StructRNA *srna= DefRNA.laststruct; if(!DefRNA.preprocess) { @@ -1652,6 +1653,11 @@ } } } + + if(dp->dnatype && strcmp(dp->dnatype, "char") == 0) { + fprop->hardmin= fprop->softmin= 0.0f; + fprop->hardmax= fprop->softmax= 1.0f; + } } rna_def_property_sdna(prop, structname, propname); @@ -1824,6 +1830,11 @@ } } +void RNA_def_property_translation_context(PropertyRNA *prop, const char *context) +{ + prop->translation_context= context; +} + /* Functions */ void RNA_def_property_editable_func(PropertyRNA *prop, const char *editable) diff -Nru blender-2.61/source/blender/makesrna/intern/rna_dynamicpaint.c blender-2.62/source/blender/makesrna/intern/rna_dynamicpaint.c --- blender-2.61/source/blender/makesrna/intern/rna_dynamicpaint.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_dynamicpaint.c 2012-02-15 19:35:15.000000000 +0000 @@ -395,6 +395,10 @@ RNA_def_property_range(prop, 1.0, 10000.0); RNA_def_property_ui_range(prop, 1.0, 10000.0, 5, 0); RNA_def_property_ui_text(prop, "Dissolve Speed", "Approximately in how many frames should dissolve happen"); + + prop= RNA_def_property(srna, "use_drying", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DPAINT_USE_DRYING); + RNA_def_property_ui_text(prop, "Dry", "Enable to make surface wetness dry over time"); prop= RNA_def_property(srna, "dry_speed", PROP_INT, PROP_NONE); RNA_def_property_range(prop, 1.0, 10000.0); @@ -433,7 +437,7 @@ prop= RNA_def_property(srna, "frame_substeps", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "substeps"); - RNA_def_property_range(prop, 0.0, 10.0); + RNA_def_property_range(prop, 0.0, 20.0); RNA_def_property_ui_range(prop, 0.0, 10, 1, 0); RNA_def_property_ui_text(prop, "Sub-Steps", "Do extra frames between scene frames to ensure smooth motion"); @@ -443,6 +447,20 @@ RNA_def_property_ui_text(prop, "Anti-aliasing", "Use 5x multisampling to smoothen paint edges"); RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_DynamicPaintSurface_reset"); + prop= RNA_def_property(srna, "brush_influence_scale", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "influence_scale"); + RNA_def_property_range(prop, 0.0, 1.0); + RNA_def_property_ui_range(prop, 0.0, 1.0, 1, 2); + RNA_def_property_ui_text(prop, "Influence Scale", "Adjust influence brush objects have on this surface"); + RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_DynamicPaint_redoModifier"); + + prop= RNA_def_property(srna, "brush_radius_scale", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "radius_scale"); + RNA_def_property_range(prop, 0.0, 10.0); + RNA_def_property_ui_range(prop, 0.0, 1.0, 1, 2); + RNA_def_property_ui_text(prop, "Radius Scale", "Adjust radius of proximity brushes or particles for this surface"); + RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_DynamicPaint_redoModifier"); + /* * Initial Color */ @@ -454,6 +472,7 @@ RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING_DRAW|ND_MODIFIER, "rna_DynamicPaintSurface_initialcolortype"); prop= RNA_def_property(srna, "init_color", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_array(prop, 4); RNA_def_property_ui_text(prop, "Color", "Initial color of the surface"); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING_DRAW|ND_MODIFIER, "rna_DynamicPaintSurface_reset"); @@ -495,6 +514,12 @@ RNA_def_property_ui_range(prop, 0.01, 5.0, 1, 2); RNA_def_property_ui_text(prop, "Spread Speed", "How fast spread effect moves on the canvas surface"); + prop= RNA_def_property(srna, "color_dry_threshold", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "color_dry_threshold"); + RNA_def_property_range(prop, 0.0, 1.0); + RNA_def_property_ui_range(prop, 0.0, 1.0, 1, 2); + RNA_def_property_ui_text(prop, "Color Dry", "The wetness level when colors start to shift to the background"); + prop= RNA_def_property(srna, "color_spread_speed", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "color_spread_speed"); RNA_def_property_range(prop, 0.0, 2.0); @@ -618,7 +643,7 @@ /* wave simulator settings */ prop= RNA_def_property(srna, "wave_damping", PROP_FLOAT, PROP_NONE); - RNA_def_property_range(prop, 0.001, 1.0); + RNA_def_property_range(prop, 0.0, 1.0); RNA_def_property_ui_range(prop, 0.01, 1.0, 1, 2); RNA_def_property_ui_text(prop, "Damping", "Wave damping factor"); @@ -633,7 +658,7 @@ RNA_def_property_ui_text(prop, "Timescale", "Wave time scaling factor"); prop= RNA_def_property(srna, "wave_spring", PROP_FLOAT, PROP_NONE); - RNA_def_property_range(prop, 0.001, 1.0); + RNA_def_property_range(prop, 0.0, 1.0); RNA_def_property_ui_range(prop, 0.01, 1.0, 1, 2); RNA_def_property_ui_text(prop, "Spring", "Spring force that pulls water level back to zero"); diff -Nru blender-2.61/source/blender/makesrna/intern/rna_fluidsim.c blender-2.62/source/blender/makesrna/intern/rna_fluidsim.c --- blender-2.61/source/blender/makesrna/intern/rna_fluidsim.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_fluidsim.c 2012-02-15 19:35:15.000000000 +0000 @@ -304,7 +304,7 @@ RNA_def_property_update(prop, 0, "rna_fluid_find_enframe"); prop= RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH); - RNA_def_property_string_maxlength(prop, 240); + RNA_def_property_string_maxlength(prop, FILE_MAX); RNA_def_property_string_sdna(prop, NULL, "surfdataPath"); RNA_def_property_ui_text(prop, "Path", "Directory (and/or filename prefix) to store baked fluid simulation files in"); RNA_def_property_update(prop, 0, "rna_fluid_update"); @@ -335,11 +335,21 @@ RNA_def_property_range(prop, 0, 100); RNA_def_property_ui_text(prop, "End Time", "Simulation time of the last blender frame (in seconds)"); + prop= RNA_def_property(srna, "frame_offset", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "frameOffset"); + RNA_def_property_ui_text(prop, "Cache Offset", "Offset when reading baked cache"); + RNA_def_property_update(prop, NC_OBJECT, "rna_fluid_update"); + prop= RNA_def_property(srna, "simulation_scale", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "realsize"); RNA_def_property_range(prop, 0.001, 10); RNA_def_property_ui_text(prop, "Real World Size", "Size of the simulation domain in metres"); + prop= RNA_def_property(srna, "simulation_rate", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "animRate"); + RNA_def_property_range(prop, 0.0, 100.0); + RNA_def_property_ui_text(prop, "Simulation Speed", "Fluid motion rate (0 = stationary, 1 = normal speed)"); + prop= RNA_def_property(srna, "viscosity_preset", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "viscosityMode"); RNA_def_property_enum_items(prop, viscosity_items); @@ -381,7 +391,7 @@ RNA_def_property_int_sdna(prop, NULL, "surfaceSubdivs"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_range(prop, 0, 5); - RNA_def_property_ui_text(prop, "Surface Subdivisions", "Number of isosurface subdivisions (this is necessary for the inclusion of particles into the surface generation - WARNING: can lead to longer computation times !)"); + RNA_def_property_ui_text(prop, "Surface Subdivisions", "Number of isosurface subdivisions (this is necessary for the inclusion of particles into the surface generation - WARNING: can lead to longer computation times !)"); prop= RNA_def_property(srna, "use_speed_vectors", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "domainNovecgen", 0); @@ -554,7 +564,7 @@ RNA_def_property_ui_text(prop, "Alpha Influence", "Amount of particle alpha change, inverse of size influence: 0=off (all same alpha), 1=full (large particles get lower alphas, smaller ones higher values)"); prop= RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH); - RNA_def_property_string_maxlength(prop, 240); + RNA_def_property_string_maxlength(prop, FILE_MAX); RNA_def_property_string_sdna(prop, NULL, "surfdataPath"); RNA_def_property_ui_text(prop, "Path", "Directory (and/or filename prefix) to store and load particles from"); RNA_def_property_update(prop, 0, "rna_fluid_update"); diff -Nru blender-2.61/source/blender/makesrna/intern/rna_ID.c blender-2.62/source/blender/makesrna/intern/rna_ID.c --- blender-2.61/source/blender/makesrna/intern/rna_ID.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_ID.c 2012-02-15 19:35:15.000000000 +0000 @@ -232,7 +232,7 @@ /* note: it looks like there is no length limit on the srna id since its * just a char pointer, but take care here, also be careful that python - * owns the string pointer which it could potentually free while blender + * owns the string pointer which it could potentially free while blender * is running. */ if(BLI_strnlen(identifier, MAX_IDPROP_NAME) == MAX_IDPROP_NAME) { BKE_reportf(reports, RPT_ERROR, "registering id property class: '%s' is too long, maximum length is " STRINGIFY(MAX_IDPROP_NAME), identifier); diff -Nru blender-2.61/source/blender/makesrna/intern/rna_image.c blender-2.62/source/blender/makesrna/intern/rna_image.c --- blender-2.61/source/blender/makesrna/intern/rna_image.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_image.c 2012-02-15 19:35:15.000000000 +0000 @@ -40,6 +40,7 @@ #include "BKE_image.h" #include "WM_types.h" +#include "WM_api.h" static EnumPropertyItem image_source_items[]= { {IMA_SRC_FILE, "FILE", 0, "Single Image", "Single image file"}, @@ -106,10 +107,20 @@ BKE_image_release_ibuf(ima, lock); } +static void rna_Image_free_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) +{ + Image *ima= ptr->id.data; + BKE_image_signal(ima, NULL, IMA_SIGNAL_FREE); + WM_main_add_notifier(NC_IMAGE|NA_EDITED, &ima->id); + DAG_id_tag_update(&ima->id, 0); +} + + static void rna_Image_reload_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { Image *ima= ptr->id.data; BKE_image_signal(ima, NULL, IMA_SIGNAL_RELOAD); + WM_main_add_notifier(NC_IMAGE|NA_EDITED, &ima->id); DAG_id_tag_update(&ima->id, 0); } @@ -474,7 +485,12 @@ prop= RNA_def_property(srna, "use_premultiply", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_DO_PREMUL); RNA_def_property_ui_text(prop, "Premultiply", "Convert RGB from key alpha to premultiplied alpha"); - RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, "rna_Image_reload_update"); + RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, "rna_Image_free_update"); + + prop= RNA_def_property(srna, "use_color_unpremultiply", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_CM_PREDIVIDE); + RNA_def_property_ui_text(prop, "Color Unpremultiply", "For premultiplied alpha images, do color space conversion on colors without alpha, to avoid fringing for images with light backgrounds"); + RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, "rna_Image_free_update"); prop= RNA_def_property(srna, "is_dirty", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_funcs(prop, "rna_Image_dirty_get", NULL); diff -Nru blender-2.61/source/blender/makesrna/intern/rna_internal_types.h blender-2.62/source/blender/makesrna/intern/rna_internal_types.h --- blender-2.61/source/blender/makesrna/intern/rna_internal_types.h 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_internal_types.h 2012-02-15 19:35:15.000000000 +0000 @@ -147,6 +147,8 @@ const char *description; /* icon ID */ int icon; + /* context for translation */ + const char *translation_context; /* property type as it appears to the outside */ PropertyType type; diff -Nru blender-2.61/source/blender/makesrna/intern/rna_key.c blender-2.62/source/blender/makesrna/intern/rna_key.c --- blender-2.61/source/blender/makesrna/intern/rna_key.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_key.c 2012-02-15 19:35:15.000000000 +0000 @@ -559,7 +559,7 @@ prop= RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", KEYBLOCK_MUTE); RNA_def_property_ui_text(prop, "Mute", "Mute this shape key"); - RNA_def_property_ui_icon(prop, ICON_MUTE_IPO_OFF, 1); + RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, 1); RNA_def_property_update(prop, 0, "rna_Key_update_data"); prop= RNA_def_property(srna, "slider_min", PROP_FLOAT, PROP_NONE); diff -Nru blender-2.61/source/blender/makesrna/intern/rna_main.c blender-2.62/source/blender/makesrna/intern/rna_main.c --- blender-2.61/source/blender/makesrna/intern/rna_main.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_main.c 2012-02-15 19:35:15.000000000 +0000 @@ -32,6 +32,8 @@ #include "rna_internal.h" +#include "BKE_utildefines.h" + #ifdef RNA_RUNTIME #include "BKE_main.h" @@ -323,7 +325,7 @@ RNA_def_struct_ui_icon(srna, ICON_BLENDER); prop= RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH); - RNA_def_property_string_maxlength(prop, 240); + RNA_def_property_string_maxlength(prop, FILE_MAX); RNA_def_property_string_funcs(prop, "rna_Main_filepath_get", "rna_Main_filepath_length", "rna_Main_filepath_set"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Filename", "Path to the .blend file"); diff -Nru blender-2.61/source/blender/makesrna/intern/rna_material.c blender-2.62/source/blender/makesrna/intern/rna_material.c --- blender-2.61/source/blender/makesrna/intern/rna_material.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_material.c 2012-02-15 19:35:15.000000000 +0000 @@ -93,10 +93,14 @@ Material *ma= ptr->id.data; DAG_id_tag_update(&ma->id, 0); - if(scene->gm.matmode == GAME_MAT_GLSL) - WM_main_add_notifier(NC_MATERIAL|ND_SHADING_DRAW, ma); - else - WM_main_add_notifier(NC_MATERIAL|ND_SHADING, ma); + if (scene) { /* can be NULL, see [#30025] */ + if (scene->gm.matmode == GAME_MAT_GLSL) { + WM_main_add_notifier(NC_MATERIAL|ND_SHADING_DRAW, ma); + } + else { + WM_main_add_notifier(NC_MATERIAL|ND_SHADING, ma); + } + } } static void rna_Material_draw_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) @@ -413,8 +417,10 @@ static EnumPropertyItem prop_bump_method_items[] = { {0, "BUMP_ORIGINAL", 0, "Original", ""}, {MTEX_COMPAT_BUMP, "BUMP_COMPATIBLE", 0, "Compatible", ""}, - {MTEX_3TAP_BUMP, "BUMP_DEFAULT", 0, "Default", ""}, - {MTEX_5TAP_BUMP, "BUMP_BEST_QUALITY", 0, "Best Quality", ""}, + {MTEX_3TAP_BUMP, "BUMP_LOW_QUALITY", 0, "Low Quality", "Use 3 tap filtering"}, + {MTEX_5TAP_BUMP, "BUMP_MEDIUM_QUALITY", 0, "Medium Quality", "Use 5 tap filtering"}, + {MTEX_BICUBIC_BUMP, "BUMP_BEST_QUALITY", 0, "Best Quality", "Use bicubic filtering (requires OpenGL 3.0+, " + "it will fall back on medium setting for other systems)"}, {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem prop_bump_space_items[] = { diff -Nru blender-2.61/source/blender/makesrna/intern/rna_mesh.c blender-2.62/source/blender/makesrna/intern/rna_mesh.c --- blender-2.61/source/blender/makesrna/intern/rna_mesh.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_mesh.c 2012-02-15 19:35:15.000000000 +0000 @@ -27,6 +27,7 @@ #include +#include "RNA_access.h" #include "RNA_define.h" #include "rna_internal.h" @@ -1132,22 +1133,25 @@ return me->edit_mesh ? me->edit_mesh->totfacesel : 0; } -static CustomDataLayer *rna_Mesh_vertex_color_new(struct Mesh *me, struct bContext *C, const char *name) +static PointerRNA rna_Mesh_vertex_color_new(struct Mesh *me, struct bContext *C, const char *name) { + PointerRNA ptr; CustomData *fdata; CustomDataLayer *cdl= NULL; - int index; + int index= ED_mesh_color_add(C, NULL, NULL, me, name, FALSE); - if(ED_mesh_color_add(C, NULL, NULL, me, name, FALSE)) { + if(index != -1) { fdata= rna_mesh_fdata(me); - index= CustomData_get_named_layer_index(fdata, CD_MCOL, name); - cdl= (index == -1)? NULL: &fdata->layers[index]; + cdl= &fdata->layers[CustomData_get_layer_index_n(fdata, CD_MCOL, index)]; } - return cdl; + + RNA_pointer_create(&me->id, &RNA_MeshColorLayer, cdl, &ptr); + return ptr; } -static CustomDataLayer *rna_Mesh_int_property_new(struct Mesh *me, struct bContext *C, const char *name) +static PointerRNA rna_Mesh_int_property_new(struct Mesh *me, struct bContext *C, const char *name) { + PointerRNA ptr; CustomDataLayer *cdl = NULL; int index; @@ -1156,11 +1160,13 @@ cdl = (index == -1) ? NULL : &(me->fdata.layers[index]); - return cdl; + RNA_pointer_create(&me->id, &RNA_MeshIntPropertyLayer, cdl, &ptr); + return ptr; } -static CustomDataLayer *rna_Mesh_float_property_new(struct Mesh *me, struct bContext *C, const char *name) +static PointerRNA rna_Mesh_float_property_new(struct Mesh *me, struct bContext *C, const char *name) { + PointerRNA ptr; CustomDataLayer *cdl = NULL; int index; @@ -1169,11 +1175,13 @@ cdl = (index == -1) ? NULL : &(me->fdata.layers[index]); - return cdl; + RNA_pointer_create(&me->id, &RNA_MeshFloatPropertyLayer, cdl, &ptr); + return ptr; } -static CustomDataLayer *rna_Mesh_string_property_new(struct Mesh *me, struct bContext *C, const char *name) +static PointerRNA rna_Mesh_string_property_new(struct Mesh *me, struct bContext *C, const char *name) { + PointerRNA ptr; CustomDataLayer *cdl = NULL; int index; @@ -1182,21 +1190,24 @@ cdl = (index == -1) ? NULL : &(me->fdata.layers[index]); - return cdl; + RNA_pointer_create(&me->id, &RNA_MeshStringPropertyLayer, cdl, &ptr); + return ptr; } -static CustomDataLayer *rna_Mesh_uv_texture_new(struct Mesh *me, struct bContext *C, const char *name) +static PointerRNA rna_Mesh_uv_texture_new(struct Mesh *me, struct bContext *C, const char *name) { + PointerRNA ptr; CustomData *fdata; CustomDataLayer *cdl= NULL; - int index; + int index= ED_mesh_uv_texture_add(C, me, name, FALSE); - if(ED_mesh_uv_texture_add(C, me, name, FALSE)) { + if(index != -1) { fdata= rna_mesh_fdata(me); - index= CustomData_get_named_layer_index(fdata, CD_MTFACE, name); - cdl= (index == -1)? NULL: &fdata->layers[index]; + cdl= &fdata->layers[CustomData_get_layer_index_n(fdata, CD_MTFACE, index)]; } - return cdl; + + RNA_pointer_create(&me->id, &RNA_MeshTextureFaceLayer, cdl, &ptr); + return ptr; } #else @@ -1699,6 +1710,11 @@ func= RNA_def_function(srna, "add", "ED_mesh_vertices_add"); RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_int(func, "count", 0, 0, INT_MAX, "Count", "Number of vertices to add", 0, INT_MAX); +#if 0 // Remove until BMesh merge + func= RNA_def_function(srna, "remove", "ED_mesh_vertices_remove"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + RNA_def_int(func, "count", 0, 0, INT_MAX, "Count", "Number of vertices to remove", 0, INT_MAX); +#endif } /* mesh.edges */ @@ -1717,7 +1733,12 @@ func= RNA_def_function(srna, "add", "ED_mesh_edges_add"); RNA_def_function_flag(func, FUNC_USE_REPORTS); - RNA_def_int(func, "count", 0, 0, INT_MAX, "Count", "Number of vertices to add", 0, INT_MAX); + RNA_def_int(func, "count", 0, 0, INT_MAX, "Count", "Number of edges to add", 0, INT_MAX); +#if 0 // Remove until BMesh merge + func= RNA_def_function(srna, "remove", "ED_mesh_edges_remove"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + RNA_def_int(func, "count", 0, 0, INT_MAX, "Count", "Number of edges to remove", 0, INT_MAX); +#endif } /* mesh.faces */ @@ -1746,7 +1767,12 @@ func= RNA_def_function(srna, "add", "ED_mesh_faces_add"); RNA_def_function_flag(func, FUNC_USE_REPORTS); - RNA_def_int(func, "count", 0, 0, INT_MAX, "Count", "Number of vertices to add", 0, INT_MAX); + RNA_def_int(func, "count", 0, 0, INT_MAX, "Count", "Number of faces to add", 0, INT_MAX); +#if 0 // Remove until BMesh merge + func= RNA_def_function(srna, "remove", "ED_mesh_faces_remove"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + RNA_def_int(func, "count", 0, 0, INT_MAX, "Count", "Number of faces to remove", 0, INT_MAX); +#endif } /* mesh.vertex_colors */ @@ -1768,6 +1794,7 @@ RNA_def_function_ui_description(func, "Add a vertex color layer to Mesh"); RNA_def_string(func, "name", "Col", 0, "", "Vertex color name"); parm= RNA_def_pointer(func, "layer", "MeshColorLayer", "", "The newly created layer"); + RNA_def_property_flag(parm, PROP_RNAPTR); RNA_def_function_return(func, parm); /* @@ -1808,6 +1835,7 @@ RNA_def_function_ui_description(func, "Add a integer property layer to Mesh"); RNA_def_string(func, "name", "Int Prop", 0, "", "Int property name"); parm= RNA_def_pointer(func, "layer", "MeshIntPropertyLayer", "", "The newly created layer"); + RNA_def_property_flag(parm, PROP_RNAPTR); RNA_def_function_return(func, parm); } @@ -1829,6 +1857,7 @@ RNA_def_function_ui_description(func, "Add a float property layer to Mesh"); RNA_def_string(func, "name", "Float Prop", 0, "", "Float property name"); parm= RNA_def_pointer(func, "layer", "MeshFloatPropertyLayer", "", "The newly created layer"); + RNA_def_property_flag(parm, PROP_RNAPTR); RNA_def_function_return(func, parm); } @@ -1850,6 +1879,7 @@ RNA_def_function_ui_description(func, "Add a string property layer to Mesh"); RNA_def_string(func, "name", "String Prop", 0, "", "String property name"); parm= RNA_def_pointer(func, "layer", "MeshStringPropertyLayer", "", "The newly created layer"); + RNA_def_property_flag(parm, PROP_RNAPTR); RNA_def_function_return(func, parm); } @@ -1872,6 +1902,7 @@ RNA_def_function_ui_description(func, "Add a UV texture layer to Mesh"); RNA_def_string(func, "name", "UVMap", 0, "", "UV map name"); parm= RNA_def_pointer(func, "layer", "MeshTextureFaceLayer", "", "The newly created layer"); + RNA_def_property_flag(parm, PROP_RNAPTR); RNA_def_function_return(func, parm); /* @@ -2132,6 +2163,11 @@ "Display the area of selected faces, using global values when set in the transform panel"); RNA_def_property_update(prop, 0, "rna_Mesh_update_draw"); + prop= RNA_def_property(srna, "show_extra_indices", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "drawflag", ME_DRAWEXTRA_INDICES); + RNA_def_property_ui_text(prop, "Indices", "Displays the index numbers of selected vertices, edges, and faces"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_draw"); + /* editflag */ prop= RNA_def_property(srna, "use_mirror_x", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "editflag", ME_EDIT_MIRROR_X); @@ -2156,14 +2192,13 @@ RNA_def_property_boolean_sdna(prop, NULL, "editflag", ME_EDIT_PAINT_MASK); RNA_def_property_ui_text(prop, "Paint Mask", "Face selection masking for painting"); RNA_def_property_ui_icon(prop, ICON_FACESEL_HLT, 0); - RNA_def_property_update(prop, 0, "rna_Mesh_update_facemask"); - + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, "rna_Mesh_update_facemask"); prop= RNA_def_property(srna, "use_paint_mask_vertex", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "editflag", ME_EDIT_VERT_SEL); RNA_def_property_ui_text(prop, "Vertex Selection", "Vertex selection masking for painting (weight paint only)"); RNA_def_property_ui_icon(prop, ICON_VERTEXSEL, 0); - RNA_def_property_update(prop, 0, "rna_Mesh_update_vertmask"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, "rna_Mesh_update_vertmask"); /* readonly editmesh info - use for extrude menu */ prop= RNA_def_property(srna, "total_vert_sel", PROP_INT, PROP_UNSIGNED); diff -Nru blender-2.61/source/blender/makesrna/intern/rna_modifier.c blender-2.62/source/blender/makesrna/intern/rna_modifier.c --- blender-2.61/source/blender/makesrna/intern/rna_modifier.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_modifier.c 2012-02-15 19:35:15.000000000 +0000 @@ -69,6 +69,7 @@ {eModifierType_Mask, "MASK", ICON_MOD_MASK, "Mask", ""}, {eModifierType_Mirror, "MIRROR", ICON_MOD_MIRROR, "Mirror", ""}, {eModifierType_Multires, "MULTIRES", ICON_MOD_MULTIRES, "Multiresolution", ""}, + {eModifierType_Remesh, "REMESH", ICON_MOD_REMESH, "Remesh", ""}, {eModifierType_Screw, "SCREW", ICON_MOD_SCREW, "Screw", ""}, {eModifierType_Solidify, "SOLIDIFY", ICON_MOD_SOLIDIFY, "Solidify", ""}, {eModifierType_Subsurf, "SUBSURF", ICON_MOD_SUBSURF, "Subdivision Surface", ""}, @@ -83,7 +84,7 @@ {eModifierType_Shrinkwrap, "SHRINKWRAP", ICON_MOD_SHRINKWRAP, "Shrinkwrap", ""}, {eModifierType_SimpleDeform, "SIMPLE_DEFORM", ICON_MOD_SIMPLEDEFORM, "Simple Deform", ""}, {eModifierType_Smooth, "SMOOTH", ICON_MOD_SMOOTH, "Smooth", ""}, - {eModifierType_Warp, "WARP", ICON_MOD_SUBSURF, "Warp", ""}, + {eModifierType_Warp, "WARP", ICON_MOD_WARP, "Warp", ""}, {eModifierType_Wave, "WAVE", ICON_MOD_WAVE, "Wave", ""}, {0, "", 0, "Simulate", ""}, {eModifierType_Cloth, "CLOTH", ICON_MOD_CLOTH, "Cloth", ""}, @@ -91,7 +92,7 @@ {eModifierType_DynamicPaint, "DYNAMIC_PAINT", ICON_MOD_DYNAMICPAINT, "Dynamic Paint", ""}, {eModifierType_Explode, "EXPLODE", ICON_MOD_EXPLODE, "Explode", ""}, {eModifierType_Fluidsim, "FLUID_SIMULATION", ICON_MOD_FLUIDSIM, "Fluid Simulation", ""}, - {eModifierType_Ocean, "OCEAN", ICON_MOD_WAVE, "Ocean", ""}, + {eModifierType_Ocean, "OCEAN", ICON_MOD_OCEAN, "Ocean", ""}, {eModifierType_ParticleInstance, "PARTICLE_INSTANCE", ICON_MOD_PARTICLES, "Particle Instance", ""}, {eModifierType_ParticleSystem, "PARTICLE_SYSTEM", ICON_MOD_PARTICLES, "Particle System", ""}, {eModifierType_Smoke, "SMOKE", ICON_MOD_SMOKE, "Smoke", ""}, @@ -199,6 +200,8 @@ return &RNA_VertexWeightProximityModifier; case eModifierType_DynamicPaint: return &RNA_DynamicPaintModifier; + case eModifierType_Remesh: + return &RNA_RemeshModifier; default: return &RNA_Modifier; } @@ -449,12 +452,6 @@ rna_object_vgroup_name_set(ptr, value, tmd->defgrp_name, sizeof(tmd->defgrp_name)); } -static void rna_WaveModifier_uvlayer_set(PointerRNA *ptr, const char *value) -{ - WaveModifierData *wmd= (WaveModifierData*)ptr->data; - rna_object_uvlayer_name_set(ptr, value, wmd->uvlayer_name, sizeof(wmd->uvlayer_name)); -} - static void rna_WeightVGModifier_mask_uvlayer_set(PointerRNA *ptr, const char *value) { ModifierData *md = (ModifierData*)ptr->data; @@ -835,7 +832,7 @@ srna= RNA_def_struct(brna, "WarpModifier", "Modifier"); RNA_def_struct_ui_text(srna, "Warp Modifier", "Warp modifier"); RNA_def_struct_sdna(srna, "WarpModifierData"); - //RNA_def_struct_ui_icon(srna, ICON_MOD_SUBSURF); + RNA_def_struct_ui_icon(srna, ICON_MOD_WARP); prop= RNA_def_property(srna, "object_from", PROP_POINTER, PROP_NONE); RNA_def_property_ui_text(prop, "From", "Object to transform from"); @@ -1122,13 +1119,6 @@ StructRNA *srna; PropertyRNA *prop; - static EnumPropertyItem prop_texture_coordinates_items[] = { - {MOD_WAV_MAP_LOCAL, "LOCAL", 0, "Local", ""}, - {MOD_WAV_MAP_GLOBAL, "GLOBAL", 0, "Global", ""}, - {MOD_WAV_MAP_OBJECT, "OBJECT", 0, "Object", ""}, - {MOD_WAV_MAP_UV, "MAP_UV", 0, "UV", ""}, - {0, NULL, 0, NULL, NULL}}; - srna= RNA_def_struct(brna, "WaveModifier", "Modifier"); RNA_def_struct_ui_text(srna, "Wave Modifier", "Wave effect modifier"); RNA_def_struct_sdna(srna, "WaveModifierData"); @@ -1220,29 +1210,6 @@ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_WaveModifier_vgroup_set"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); - prop= RNA_def_property(srna, "texture", PROP_POINTER, PROP_NONE); - RNA_def_property_ui_text(prop, "Texture", "Texture for modulating the wave"); - RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, 0, "rna_Modifier_update"); - - prop= RNA_def_property(srna, "texture_coords", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "texmapping"); - RNA_def_property_enum_items(prop, prop_texture_coordinates_items); - RNA_def_property_ui_text(prop, "Texture Coordinates", "Texture coordinates used for modulating input"); - RNA_def_property_update(prop, 0, "rna_Modifier_update"); - - prop= RNA_def_property(srna, "uv_layer", PROP_STRING, PROP_NONE); - RNA_def_property_string_sdna(prop, NULL, "uvlayer_name"); - RNA_def_property_ui_text(prop, "UV Map", "UV map name"); - RNA_def_property_string_funcs(prop, NULL, NULL, "rna_WaveModifier_uvlayer_set"); - RNA_def_property_update(prop, 0, "rna_Modifier_update"); - - prop= RNA_def_property(srna, "texture_coords_object", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "map_object"); - RNA_def_property_ui_text(prop, "Texture Coordinates Object", ""); - RNA_def_property_flag(prop, PROP_EDITABLE|PROP_ID_SELF_CHECK); - RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); - prop= RNA_def_property(srna, "speed", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); RNA_def_property_ui_range(prop, -1, 1, 10, 2); @@ -1267,6 +1234,8 @@ RNA_def_property_ui_range(prop, 0, 10, 10, 2); RNA_def_property_ui_text(prop, "Narrowness", "Distance between the top and the base of a wave, the higher the value, the more narrow the wave"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + rna_def_modifier_generic_map_info(srna); } static void rna_def_modifier_armature(BlenderRNA *brna) @@ -2000,7 +1969,7 @@ prop= RNA_def_property(srna, "particle_uv", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "uvname"); - RNA_def_property_string_maxlength(prop, 32); + RNA_def_property_string_maxlength(prop, MAX_CUSTOMDATA_LAYER_NAME); RNA_def_property_ui_text(prop, "Particle UV", "UV map to change with particle age"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); } @@ -2867,6 +2836,57 @@ rna_def_modifier_weightvg_mask(brna, srna); } +static void rna_def_modifier_remesh(BlenderRNA *brna) +{ + static EnumPropertyItem mode_items[]= { + {MOD_REMESH_CENTROID, "BLOCKS", 0, "Blocks", "Output a blocky surface with no smoothing"}, + {MOD_REMESH_MASS_POINT, "SMOOTH", 0, "Smooth", "Output a smooth surface with no sharp-features detection"}, + {MOD_REMESH_SHARP_FEATURES, "SHARP", 0, "Sharp", "Output a surface that reproduces sharp edges and corners from the input mesh"}, + {0, NULL, 0, NULL, NULL}}; + + StructRNA *srna; + PropertyRNA *prop; + + srna= RNA_def_struct(brna, "RemeshModifier", "Modifier"); + RNA_def_struct_ui_text(srna, "Remesh Modifier", "Generate a new surface with regular topology that follows the shape of the input mesh"); + RNA_def_struct_sdna(srna, "RemeshModifierData"); + RNA_def_struct_ui_icon(srna, ICON_MOD_REMESH); + + prop= RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, mode_items); + RNA_def_property_ui_text(prop, "Mode", ""); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop= RNA_def_property(srna, "scale", PROP_FLOAT, PROP_NONE); + RNA_def_property_ui_range(prop, 0, 0.99, 0.01, 3); + RNA_def_property_range(prop, 0, 0.99); + RNA_def_property_ui_text(prop, "Scale", "The ratio of the largest dimension of the model over the size of the grid"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop= RNA_def_property(srna, "threshold", PROP_FLOAT, PROP_NONE); + RNA_def_property_ui_range(prop, 0, 1, 0.1, 3); + RNA_def_property_range(prop, 0, 1); + RNA_def_property_ui_text(prop, "Threshold", "If removing disconnected pieces, minimum size of components to preserve as a ratio of the number of polygons in the largest component"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop= RNA_def_property(srna, "octree_depth", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "depth"); + RNA_def_property_range(prop, 1, 10); + RNA_def_property_ui_text(prop, "Octree Depth", "Resolution of the octree; higher values give finer details"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop= RNA_def_property(srna, "sharpness", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "hermite_num"); + RNA_def_property_ui_range(prop, 0, 2, 0.1, 3); + RNA_def_property_ui_text(prop, "Sharpness", "Tolerance for outliers; lower values filter noise while higher values will reproduce edges closer to the input"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop= RNA_def_property(srna, "remove_disconnected_pieces", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_REMESH_FLOOD_FILL); + RNA_def_property_ui_text(prop, "Remove Disconnected Pieces", ""); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); +} + static void rna_def_modifier_ocean(BlenderRNA *brna) { StructRNA *srna; @@ -2881,7 +2901,7 @@ srna= RNA_def_struct(brna, "OceanModifier", "Modifier"); RNA_def_struct_ui_text(srna, "Ocean Modifier", "Simulate an ocean surface"); RNA_def_struct_sdna(srna, "OceanModifierData"); - RNA_def_struct_ui_icon(srna, ICON_MOD_FLUIDSIM); + RNA_def_struct_ui_icon(srna, ICON_MOD_OCEAN); /* General check if blender was built with OceanSim modifier support */ prop= RNA_def_property(srna, "is_build_enabled", PROP_BOOLEAN, PROP_NONE); @@ -3148,6 +3168,7 @@ rna_def_modifier_weightvgproximity(brna); rna_def_modifier_dynamic_paint(brna); rna_def_modifier_ocean(brna); + rna_def_modifier_remesh(brna); } #endif diff -Nru blender-2.61/source/blender/makesrna/intern/rna_movieclip.c blender-2.62/source/blender/makesrna/intern/rna_movieclip.c --- blender-2.61/source/blender/makesrna/intern/rna_movieclip.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_movieclip.c 2012-02-15 19:35:15.000000000 +0000 @@ -78,6 +78,7 @@ {IMB_TC_RECORD_RUN, "RECORD_RUN", 0, "Record Run", "Use images in the order they are recorded"}, {IMB_TC_FREE_RUN, "FREE_RUN", 0, "Free Run", "Use global timestamp written by recording device"}, {IMB_TC_INTERPOLATED_REC_DATE_FREE_RUN, "FREE_RUN_REC_DATE", 0, "Free Run (rec date)", "Interpolate a global timestamp using the record date and time written by recording device"}, + {IMB_TC_RECORD_RUN_NO_GAPS, "FREE_RUN_NO_GAPS", 0, "Free Run No Gaps", "Record run, but ignore timecode, changes in framerate or dropouts"}, {0, NULL, 0, NULL, NULL}}; srna = RNA_def_struct(brna, "MovieClipProxy", NULL); @@ -86,24 +87,36 @@ /* build proxy sized */ prop= RNA_def_property(srna, "build_25", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", IMB_PROXY_25); + RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", MCLIP_PROXY_SIZE_25); RNA_def_property_ui_text(prop, "25%", "Build proxy resolution 25% of the original footage dimension"); prop= RNA_def_property(srna, "build_50", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", IMB_PROXY_50); + RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", MCLIP_PROXY_SIZE_50); RNA_def_property_ui_text(prop, "50%", "Build proxy resolution 50% of the original footage dimension"); prop= RNA_def_property(srna, "build_75", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", IMB_PROXY_75); + RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", MCLIP_PROXY_SIZE_75); RNA_def_property_ui_text(prop, "75%", "Build proxy resolution 75% of the original footage dimension"); prop= RNA_def_property(srna, "build_100", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", IMB_PROXY_100); + RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", MCLIP_PROXY_SIZE_100); RNA_def_property_ui_text(prop, "100%", "Build proxy resolution 100% of the original footage dimension"); - prop= RNA_def_property(srna, "build_undistorted", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "build_flag", MCLIP_PROXY_BUILD_UNDISTORT); - RNA_def_property_ui_text(prop, "Build Undistorted", "Also build undistorted proxies for selected sizes"); + prop= RNA_def_property(srna, "build_undistorted_25", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", MCLIP_PROXY_UNDISTORTED_SIZE_25); + RNA_def_property_ui_text(prop, "25%", "Build proxy resolution 25% of the original undistorted footage dimension"); + + prop= RNA_def_property(srna, "build_undistorted_50", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", MCLIP_PROXY_UNDISTORTED_SIZE_50); + RNA_def_property_ui_text(prop, "50%", "Build proxy resolution 50% of the original undistorted footage dimension"); + + prop= RNA_def_property(srna, "build_undistorted_75", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", MCLIP_PROXY_UNDISTORTED_SIZE_75); + RNA_def_property_ui_text(prop, "75%", "Build proxy resolution 75% of the original undistorted footage dimension"); + + prop= RNA_def_property(srna, "build_undistorted_100", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", MCLIP_PROXY_UNDISTORTED_SIZE_100); + RNA_def_property_ui_text(prop, "100%", "Build proxy resolution 100% of the original undistorted footage dimension"); /* build timecodes */ prop= RNA_def_property(srna, "build_record_run", PROP_BOOLEAN, PROP_NONE); diff -Nru blender-2.61/source/blender/makesrna/intern/rna_nodetree.c blender-2.62/source/blender/makesrna/intern/rna_nodetree.c --- blender-2.61/source/blender/makesrna/intern/rna_nodetree.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_nodetree.c 2012-02-15 19:35:15.000000000 +0000 @@ -64,9 +64,13 @@ EnumPropertyItem node_socket_type_items[] = { - {SOCK_FLOAT, "VALUE", 0, "Value", ""}, - {SOCK_VECTOR, "VECTOR", 0, "Vector", ""}, - {SOCK_RGBA, "RGBA", 0, "RGBA", ""}, + {SOCK_FLOAT, "VALUE", 0, "Value", ""}, + {SOCK_VECTOR, "VECTOR", 0, "Vector", ""}, + {SOCK_RGBA, "RGBA", 0, "RGBA", ""}, + {SOCK_SHADER, "SHADER", 0, "Shader", ""}, + {SOCK_BOOLEAN, "BOOLEAN", 0, "Boolean", ""}, + {SOCK_MESH, "MESH", 0, "Mesh", ""}, + {SOCK_INT, "INT", 0, "Int", ""}, {0, NULL, 0, NULL, NULL}}; EnumPropertyItem node_math_items[] = { @@ -365,6 +369,15 @@ node_update(bmain, scene, ntree, node); } +static void rna_Node_image_update(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + bNodeTree *ntree= (bNodeTree*)ptr->id.data; + bNode *node= (bNode*)ptr->data; + + node_update(bmain, scene, ntree, node); + WM_main_add_notifier(NC_IMAGE, NULL); +} + static void rna_Node_material_update(Main *bmain, Scene *scene, PointerRNA *ptr) { bNodeTree *ntree= (bNodeTree*)ptr->id.data; @@ -1264,7 +1277,7 @@ RNA_def_property_struct_type(prop, "Image"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Image", ""); - RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_image_update"); RNA_def_struct_sdna_from(srna, "NodeTexImage", "storage"); def_sh_tex(srna); @@ -1289,7 +1302,7 @@ RNA_def_property_struct_type(prop, "Image"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Image", ""); - RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_image_update"); RNA_def_struct_sdna_from(srna, "NodeTexImage", "storage"); def_sh_tex(srna); @@ -1329,6 +1342,12 @@ def_sh_tex(srna); } +static void def_sh_tex_checker(StructRNA *srna) +{ + RNA_def_struct_sdna_from(srna, "NodeTexChecker", "storage"); + def_sh_tex(srna); +} + static void def_sh_tex_magic(StructRNA *srna) { PropertyRNA *prop; @@ -2115,6 +2134,35 @@ RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); } +static void def_cmp_double_edge_mask(StructRNA * srna) +{ + PropertyRNA *prop; + + static EnumPropertyItem BufEdgeMode_items[] = { + {0, "BLEED_OUT", 0, "Bleed Out", "Allow mask pixels to bleed along edges"}, + {1, "KEEP_IN", 0, "Keep In", "Restrict mask pixels from touching edges"}, + {0, NULL, 0, NULL, NULL} + }; + + static EnumPropertyItem InnerEdgeMode_items[] = { + {0, "ALL", 0, "All", "All pixels on inner mask edge are considered during mask calculation"}, + {1, "ADJACENT_ONLY", 0, "Adjacent Only", "Only inner mask pixels adjacent to outer mask pixels are considered during mask calculation"}, + {0, NULL, 0, NULL, NULL} + }; + + prop = RNA_def_property(srna, "inner_mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "custom2"); + RNA_def_property_enum_items(prop, InnerEdgeMode_items); + RNA_def_property_ui_text(prop, "Inner Edge Mode", ""); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); + + prop = RNA_def_property(srna, "edge_mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "custom1"); + RNA_def_property_enum_items(prop, BufEdgeMode_items); + RNA_def_property_ui_text(prop, "Buffer Edge Mode", ""); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); +} + static void def_cmp_map_uv(StructRNA *srna) { PropertyRNA *prop; @@ -3023,7 +3071,7 @@ }; #undef SUBTYPE - #define SUBTYPE(socktype, stypename, id, idname) if (subtype==PROP_##id) propsubtype = PROP_##id; + #define SUBTYPE(socktype, stypename, id, idname) if (subtype == (PROP_##id)) propsubtype = PROP_##id; NODE_DEFINE_SUBTYPES #undef SUBTYPE @@ -3195,7 +3243,7 @@ func= RNA_def_function(srna, "new", (in_out==SOCK_IN ? "rna_NodeTree_input_new" : "rna_NodeTree_output_new")); RNA_def_function_ui_description(func, "Add a socket to the group tree"); RNA_def_function_flag(func, FUNC_USE_REPORTS); - RNA_def_string(func, "name", "Socket", 32, "Name", "Name of the socket"); + RNA_def_string(func, "name", "Socket", MAX_NAME, "Name", "Name of the socket"); RNA_def_enum(func, "type", node_socket_type_items, SOCK_FLOAT, "Type", "Type of socket"); /* return value */ parm= RNA_def_pointer(func, "socket", "NodeSocket", "", "New socket"); @@ -3365,4 +3413,3 @@ #undef NODE_DEFINE_SUBTYPES #endif - diff -Nru blender-2.61/source/blender/makesrna/intern/rna_nodetree_types.h blender-2.62/source/blender/makesrna/intern/rna_nodetree_types.h --- blender-2.61/source/blender/makesrna/intern/rna_nodetree_types.h 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_nodetree_types.h 2012-02-15 19:35:15.000000000 +0000 @@ -40,6 +40,8 @@ DefNode( ShaderNode, SH_NODE_RGBTOBW, 0, "RGBTOBW", RGBToBW, "RGB to BW", "" ) DefNode( ShaderNode, SH_NODE_TEXTURE, def_texture, "TEXTURE", Texture, "Texture", "" ) DefNode( ShaderNode, SH_NODE_NORMAL, 0, "NORMAL", Normal, "Normal", "" ) +DefNode( ShaderNode, SH_NODE_GAMMA, 0, "GAMMA", Gamma, "Gamma", "" ) +DefNode( ShaderNode, SH_NODE_BRIGHTCONTRAST, 0, "BRIGHTCONTRAST", BrightContrast, "Bright Contrast", "" ) DefNode( ShaderNode, SH_NODE_GEOMETRY, def_sh_geometry, "GEOMETRY", Geometry, "Geometry", "" ) DefNode( ShaderNode, SH_NODE_MAPPING, def_sh_mapping, "MAPPING", Mapping, "Mapping", "" ) DefNode( ShaderNode, SH_NODE_CURVE_VEC, def_vector_curve, "CURVE_VEC", VectorCurve, "Vector Curve", "" ) @@ -84,6 +86,7 @@ DefNode( ShaderNode, SH_NODE_TEX_WAVE, def_sh_tex_wave, "TEX_WAVE", TexWave, "Wave Texture", "" ) DefNode( ShaderNode, SH_NODE_TEX_MUSGRAVE, def_sh_tex_musgrave, "TEX_MUSGRAVE", TexMusgrave, "Musgrave Texture", "" ) DefNode( ShaderNode, SH_NODE_TEX_VORONOI, def_sh_tex_voronoi, "TEX_VORONOI", TexVoronoi, "Voronoi Texture", "" ) +DefNode( ShaderNode, SH_NODE_TEX_CHECKER, def_sh_tex_checker, "TEX_CHECKER", TexChecker, "Checker Texture", "" ) DefNode( ShaderNode, SH_NODE_TEX_COORD, 0, "TEX_COORD", TexCoord, "Texture Coordinate","") DefNode( CompositorNode, CMP_NODE_VIEWER, 0, "VIEWER", Viewer, "Viewer", "" ) @@ -128,6 +131,7 @@ DefNode( CompositorNode, CMP_NODE_SPLITVIEWER, def_cmp_splitviewer, "SPLITVIEWER", SplitViewer, "Split Viewer", "" ) DefNode( CompositorNode, CMP_NODE_MAP_UV, def_cmp_map_uv, "MAP_UV", MapUV, "Map UV", "" ) DefNode( CompositorNode, CMP_NODE_ID_MASK, def_cmp_id_mask, "ID_MASK", IDMask, "ID Mask", "" ) +DefNode( CompositorNode, CMP_NODE_DOUBLEEDGEMASK, def_cmp_double_edge_mask,"DOUBLEEDGEMASK", DoubleEdgeMask, "Double Edge Mask", "" ) DefNode( CompositorNode, CMP_NODE_DEFOCUS, def_cmp_defocus, "DEFOCUS", Defocus, "Defocus", "" ) DefNode( CompositorNode, CMP_NODE_DISPLACE, 0, "DISPLACE", Displace, "Displace", "" ) DefNode( CompositorNode, CMP_NODE_COMBHSVA, 0, "COMBHSVA", CombHSVA, "Combine HSVA", "" ) diff -Nru blender-2.61/source/blender/makesrna/intern/rna_object_api.c blender-2.62/source/blender/makesrna/intern/rna_object_api.c --- blender-2.61/source/blender/makesrna/intern/rna_object_api.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_object_api.c 2012-02-15 19:35:15.000000000 +0000 @@ -63,6 +63,7 @@ #include "BKE_font.h" #include "BKE_mball.h" #include "BKE_modifier.h" +#include "BKE_cdderivedmesh.h" #include "DNA_mesh_types.h" #include "DNA_scene_types.h" @@ -79,7 +80,7 @@ Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int apply_modifiers, int settings) { Mesh *tmpmesh; - Curve *tmpcu = NULL; + Curve *tmpcu = NULL, *copycu; Object *tmpobj = NULL; int render = settings == eModifierMode_Render, i; int cage = !apply_modifiers; @@ -100,22 +101,20 @@ object_free_modifiers(tmpobj); /* copies the data */ - tmpobj->data = copy_curve( (Curve *) ob->data ); + copycu = tmpobj->data = copy_curve( (Curve *) ob->data ); -#if 0 - /* copy_curve() sets disp.first null, so currently not need */ - { - Curve *cu; - cu = (Curve *)tmpobj->data; - if( cu->disp.first ) - MEM_freeN( cu->disp.first ); - cu->disp.first = NULL; - } - -#endif + /* temporarily set edit so we get updates from edit mode, but + also because for text datablocks copying it while in edit + mode gives invalid data structures */ + copycu->editfont = tmpcu->editfont; + copycu->editnurb = tmpcu->editnurb; /* get updated display list, and convert to a mesh */ makeDispListCurveTypes( sce, tmpobj, 0 ); + + copycu->editfont = NULL; + copycu->editnurb = NULL; + nurbs_to_mesh( tmpobj ); /* nurbs_to_mesh changes the type to a mesh, check it worked */ @@ -191,13 +190,12 @@ if( tmpcu->mat ) { for( i = tmpcu->totcol; i-- > 0; ) { /* are we an object material or data based? */ - if (ob->colbits & 1<mat[i] = ob->mat[i]; - else - tmpmesh->mat[i] = tmpcu->mat[i]; - if (tmpmesh->mat[i]) + tmpmesh->mat[i] = ob->matbits[i] ? ob->mat[i] : tmpcu->mat[i]; + + if (tmpmesh->mat[i]) { tmpmesh->mat[i]->id.us++; + } } } break; @@ -230,12 +228,11 @@ if( origmesh->mat ) { for( i = origmesh->totcol; i-- > 0; ) { /* are we an object material or data based? */ - if (ob->colbits & 1<mat[i] = ob->mat[i]; - else - tmpmesh->mat[i] = origmesh->mat[i]; - if (tmpmesh->mat[i]) + tmpmesh->mat[i] = ob->matbits[i] ? ob->mat[i] : origmesh->mat[i]; + + if (tmpmesh->mat[i]) { tmpmesh->mat[i]->id.us++; + } } } } @@ -359,7 +356,7 @@ } Mesh *me = (Mesh*)ob->data; - int group_index = defgroup_find_index(ob, group); + int group_index = BLI_findlink(&ob->defbase, group); if (group_index == -1) { BKE_report(reports, RPT_ERROR, "No deform groups assigned to mesh"); return; @@ -472,6 +469,44 @@ return object_is_modified(scene, ob) & settings; } +#ifndef NDEBUG +void rna_Object_dm_info(struct Object *ob, int type, char *result) +{ + DerivedMesh *dm = NULL; + int dm_release = FALSE; + char *ret = NULL; + + result[0] = '\0'; + + switch(type) { + case 0: + if (ob->type == OB_MESH) { + dm = CDDM_from_mesh(ob->data, ob); + ret = DM_debug_info(dm); + dm_release = TRUE; + } + break; + case 1: + dm = ob->derivedDeform; + break; + case 2: + dm = ob->derivedFinal; + break; + } + + if (dm) { + ret = DM_debug_info(dm); + if (dm_release) { + dm->release(dm); + } + if (ret) { + strcpy(result, ret); + MEM_freeN(ret); + } + } +} +#endif /* NDEBUG */ + #else void RNA_api_object(StructRNA *srna) @@ -485,6 +520,15 @@ {0, NULL, 0, NULL, NULL} }; +#ifndef NDEBUG + static EnumPropertyItem mesh_dm_info_items[] = { + {0, "SOURCE", 0, "Source", "Source mesh"}, + {1, "DEFORM", 0, "Deform", "Objects deform mesh"}, + {2, "FINAL", 0, "Final", "Objects final mesh"}, + {0, NULL, 0, NULL, NULL} + }; +#endif + /* mesh */ func= RNA_def_function(srna, "to_mesh", "rna_Object_to_mesh"); RNA_def_function_ui_description(func, "Create a Mesh datablock with modifiers applied"); @@ -587,6 +631,20 @@ RNA_def_property_flag(parm, PROP_REQUIRED); parm= RNA_def_boolean(func, "result", 0, "", "Object visibility"); RNA_def_function_return(func, parm); + + +#ifndef NDEBUG + /* mesh */ + func= RNA_def_function(srna, "dm_info", "rna_Object_dm_info"); + RNA_def_function_ui_description(func, "Returns a string for derived mesh data"); + + parm= RNA_def_enum(func, "type", mesh_dm_info_items, 0, "", "Modifier settings to apply"); + RNA_def_property_flag(parm, PROP_REQUIRED); + /* weak!, no way to return dynamic string type */ + parm= RNA_def_string(func, "result", "", 16384, "result", ""); + RNA_def_property_flag(parm, PROP_THICK_WRAP); /* needed for string return value */ + RNA_def_function_output(func, parm); +#endif /* NDEBUG */ } diff -Nru blender-2.61/source/blender/makesrna/intern/rna_object.c blender-2.62/source/blender/makesrna/intern/rna_object.c --- blender-2.61/source/blender/makesrna/intern/rna_object.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_object.c 2012-02-15 19:35:15.000000000 +0000 @@ -174,7 +174,7 @@ if(ob->parent) { float invmat[4][4]; /* for inverse of parent's matrix */ invert_m4_m4(invmat, ob->parent->obmat); - mul_m4_m4m4((float(*)[4])values, ob->obmat, invmat); + mult_m4_m4m4((float(*)[4])values, invmat, ob->obmat); } else { copy_m4_m4((float(*)[4])values, ob->obmat); @@ -191,7 +191,7 @@ if(ob->parent) { float invmat[4][4]; invert_m4_m4(invmat, ob->parentinv); - mul_m4_m4m4(ob->obmat, (float(*)[4])values, invmat); + mult_m4_m4m4(ob->obmat, invmat, (float(*)[4])values); } else { copy_m4_m4(ob->obmat, (float(*)[4])values); @@ -809,11 +809,11 @@ if(value) { ob->matbits[index]= 1; - ob->colbits |= (1<colbits |= (1<matbits[index]= 0; - ob->colbits &= ~(1<colbits &= ~(1<data; Object *ob= (Object*)ptr->id.data; - float umat[4][4]= MAT4_UNITY; float tmat[4][4]; - /* recalculate pose matrix with only parent transformations, - * bone loc/sca/rot is ignored, scene and frame are not used. */ - where_is_pose_bone(NULL, ob, pchan, 0.0f, FALSE); - - /* find the matrix, need to remove the bone transforms first so this is - * calculated as a matrix to set rather then a difference ontop of whats - * already there. */ - pchan_apply_mat4(pchan, umat, FALSE); - armature_mat_pose_to_bone(pchan, (float (*)[4])values, tmat); + armature_mat_pose_to_bone_ex(ob, pchan, (float (*)[4])values, tmat); + pchan_apply_mat4(pchan, tmat, FALSE); /* no compat for predictable result */ } diff -Nru blender-2.61/source/blender/makesrna/intern/rna_property.c blender-2.62/source/blender/makesrna/intern/rna_property.c --- blender-2.61/source/blender/makesrna/intern/rna_property.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_property.c 2012-02-15 19:35:15.000000000 +0000 @@ -35,6 +35,15 @@ #include "WM_types.h" +EnumPropertyItem gameproperty_type_items[] ={ + {GPROP_BOOL, "BOOL", 0, "Boolean", "Boolean Property"}, + {GPROP_INT, "INT", 0, "Integer", "Integer Property"}, + {GPROP_FLOAT, "FLOAT", 0, "Float", "Floating-Point Property"}, + {GPROP_STRING, "STRING", 0, "String", "String Property"}, + {GPROP_TIME, "TIMER", 0, "Timer", "Timer Property"}, + {0, NULL, 0, NULL, NULL}}; + + #ifdef RNA_RUNTIME #include "BKE_property.h" @@ -98,14 +107,6 @@ StructRNA *srna; PropertyRNA *prop; - static EnumPropertyItem gameproperty_type_items[] ={ - {GPROP_BOOL, "BOOL", 0, "Boolean", "Boolean Property"}, - {GPROP_INT, "INT", 0, "Integer", "Integer Property"}, - {GPROP_FLOAT, "FLOAT", 0, "Float", "Floating-Point Property"}, - {GPROP_STRING, "STRING", 0, "String", "String Property"}, - {GPROP_TIME, "TIMER", 0, "Timer", "Timer Property"}, - {0, NULL, 0, NULL, NULL}}; - /* Base Struct for GameProperty */ srna= RNA_def_struct(brna, "GameProperty", NULL); RNA_def_struct_ui_text(srna , "Game Property", "Game engine user defined object property"); diff -Nru blender-2.61/source/blender/makesrna/intern/rna_render.c blender-2.62/source/blender/makesrna/intern/rna_render.c --- blender-2.61/source/blender/makesrna/intern/rna_render.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_render.c 2012-02-15 19:35:15.000000000 +0000 @@ -472,6 +472,15 @@ {SCE_PASS_EMIT, "EMIT", 0, "Emit", ""}, {SCE_PASS_ENVIRONMENT, "ENVIRONMENT", 0, "Environment", ""}, {SCE_PASS_INDEXMA, "MATERIAL_INDEX", 0, "Material Index", ""}, + {SCE_PASS_DIFFUSE_DIRECT, "DIFFUSE_DIRECT", 0, "Diffuse Direct", ""}, + {SCE_PASS_DIFFUSE_INDIRECT, "DIFFUSE_INDIRECT", 0, "Diffuse Indirect", ""}, + {SCE_PASS_DIFFUSE_COLOR, "DIFFUSE_COLOR", 0, "Diffuse Color", ""}, + {SCE_PASS_GLOSSY_DIRECT, "GLOSSY_DIRECT", 0, "Glossy Direct", ""}, + {SCE_PASS_GLOSSY_INDIRECT, "GLOSSY_INDIRECT", 0, "Glossy Indirect", ""}, + {SCE_PASS_GLOSSY_COLOR, "GLOSSY_COLOR", 0, "Glossy Color", ""}, + {SCE_PASS_TRANSM_DIRECT, "TRANSMISSION_DIRECT", 0, "Transmission Direct", ""}, + {SCE_PASS_TRANSM_INDIRECT, "TRANSMISSION_INDIRECT", 0, "Transmission Indirect", ""}, + {SCE_PASS_TRANSM_COLOR, "TRANSMISSION_COLOR", 0, "Transmission Color", ""}, {0, NULL, 0, NULL, NULL}}; srna= RNA_def_struct(brna, "RenderPass", NULL); diff -Nru blender-2.61/source/blender/makesrna/intern/rna_rna.c blender-2.62/source/blender/makesrna/intern/rna_rna.c --- blender-2.61/source/blender/makesrna/intern/rna_rna.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_rna.c 2012-02-15 19:35:15.000000000 +0000 @@ -465,6 +465,20 @@ return prop->description ? strlen(prop->description) : 0; } +static void rna_Property_translation_context_get(PointerRNA *ptr, char *value) +{ + PropertyRNA *prop= (PropertyRNA*)ptr->data; + rna_idproperty_check(&prop, ptr); + strcpy(value, prop->translation_context ? prop->translation_context:""); +} + +static int rna_Property_translation_context_length(PointerRNA *ptr) +{ + PropertyRNA *prop= (PropertyRNA*)ptr->data; + rna_idproperty_check(&prop, ptr); + return prop->translation_context ? strlen(prop->translation_context) : 0; +} + static int rna_Property_type_get(PointerRNA *ptr) { PropertyRNA *prop= (PropertyRNA*)ptr->data; @@ -1047,6 +1061,11 @@ RNA_def_property_string_funcs(prop, "rna_Property_description_get", "rna_Property_description_length", NULL); RNA_def_property_ui_text(prop, "Description", "Description of the property for tooltips"); + prop= RNA_def_property(srna, "translation_context", PROP_STRING, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_string_funcs(prop, "rna_Property_translation_context_get", "rna_Property_translation_context_length", NULL); + RNA_def_property_ui_text(prop, "Translation Context", "Translation context of the property"); + prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_enum_items(prop, property_type_items); diff -Nru blender-2.61/source/blender/makesrna/intern/rna_scene_api.c blender-2.62/source/blender/makesrna/intern/rna_scene_api.c --- blender-2.61/source/blender/makesrna/intern/rna_scene_api.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_scene_api.c 2012-02-15 19:35:15.000000000 +0000 @@ -57,6 +57,7 @@ CLAMP(scene->r.cfra, MINAFRAME, MAXFRAME); scene_update_for_newframe(G.main, scene, (1<<20) - 1); + scene_camera_switch_update(scene); /* cant use NC_SCENE|ND_FRAME because this casues wm_event_do_notifiers to call * scene_update_for_newframe which will loose any un-keyed changes [#24690] */ @@ -83,9 +84,9 @@ /* don't remove this, as COLLADA exporting cannot be done through operators in render() callback. */ #include "../../collada/collada.h" -static void rna_Scene_collada_export(Scene *scene, const char *filepath, int selected) +static void rna_Scene_collada_export(Scene *scene, const char *filepath, int selected, int second_life) { - collada_export(scene, filepath, selected); + collada_export(scene, filepath, selected, second_life); } #endif @@ -109,10 +110,11 @@ #ifdef WITH_COLLADA /* don't remove this, as COLLADA exporting cannot be done through operators in render() callback. */ func= RNA_def_function(srna, "collada_export", "rna_Scene_collada_export"); - RNA_def_string(func, "filepath", "", FILE_MAX, "File Path", "File path to write Collada file"); - parm= RNA_def_boolean(func, "selected", 0, "Export only selected", "Export only selected elements"); + parm= RNA_def_string(func, "filepath", "", FILE_MAX, "File Path", "File path to write Collada file"); RNA_def_property_flag(parm, PROP_REQUIRED); RNA_def_property_subtype(parm, PROP_FILEPATH); /* allow non utf8 */ + parm= RNA_def_boolean(func, "selected", 0, "Export only selected", "Export only selected elements"); + parm= RNA_def_boolean(func, "second_life", 0, "Export for Second Life", "Compatibility mode for Second Life"); RNA_def_function_ui_description(func, "Export to collada file"); #endif } diff -Nru blender-2.61/source/blender/makesrna/intern/rna_scene.c blender-2.62/source/blender/makesrna/intern/rna_scene.c --- blender-2.61/source/blender/makesrna/intern/rna_scene.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_scene.c 2012-02-15 19:35:15.000000000 +0000 @@ -24,7 +24,6 @@ * \ingroup RNA */ - #include #include "RNA_define.h" @@ -32,6 +31,7 @@ #include "rna_internal.h" +#include "DNA_brush_types.h" #include "DNA_group_types.h" #include "DNA_modifier_types.h" #include "DNA_particle_types.h" @@ -63,6 +63,18 @@ #include "BLI_threads.h" +EnumPropertyItem uv_sculpt_relaxation_items[] = { + {UV_SCULPT_TOOL_RELAX_LAPLACIAN, "LAPLACIAN", 0, "Laplacian", "Use Laplacian method for relaxation"}, + {UV_SCULPT_TOOL_RELAX_HC, "HC", 0, "HC", "Use HC method for relaxation"}, + {0, NULL, 0, NULL, NULL}}; + +EnumPropertyItem uv_sculpt_tool_items[] = { + {UV_SCULPT_TOOL_PINCH, "PINCH", 0, "Pinch", "Pinch UVs"}, + {UV_SCULPT_TOOL_RELAX, "RELAX", 0, "Relax", "Relax UVs"}, + {UV_SCULPT_TOOL_GRAB, "GRAB", 0, "Grab", "Grab UVs"}, + {0, NULL, 0, NULL, NULL}}; + + EnumPropertyItem snap_target_items[] = { {SCE_SNAP_TARGET_CLOSEST, "CLOSEST", 0, "Closest", "Snap closest point onto target"}, {SCE_SNAP_TARGET_CENTER, "CENTER", 0, "Center", "Snap center onto target"}, @@ -136,7 +148,7 @@ #endif #ifdef WITH_OPENEXR -# define R_IMF_ENUM_EXR_MULTI {R_IMF_IMTYPE_MULTILAYER, "MULTILAYER", ICON_FILE_IMAGE, "MultiLayer", "Output image in multilayer OpenEXR format"}, +# define R_IMF_ENUM_EXR_MULTI {R_IMF_IMTYPE_MULTILAYER, "OPEN_EXR_MULTILAYER", ICON_FILE_IMAGE, "OpenEXR MultiLayer", "Output image in multilayer OpenEXR format"}, # define R_IMF_ENUM_EXR {R_IMF_IMTYPE_OPENEXR, "OPEN_EXR", ICON_FILE_IMAGE, "OpenEXR", "Output image in OpenEXR format"}, #else # define R_IMF_ENUM_EXR_MULTI @@ -244,6 +256,7 @@ #include "BLI_threads.h" #include "BLI_editVert.h" +#include "BKE_brush.h" #include "BKE_context.h" #include "BKE_global.h" #include "BKE_image.h" @@ -266,9 +279,15 @@ #include "ED_view3d.h" #include "ED_mesh.h" #include "ED_keyframing.h" +#include "ED_image.h" #include "RE_engine.h" +static void rna_SpaceImageEditor_uv_sculpt_update(Main *bmain, Scene *scene, PointerRNA *UNUSED(ptr)) +{ + ED_space_image_uv_sculpt_update(bmain->wm.first, scene->toolsettings); +} + static int rna_Scene_object_bases_lookup_string(PointerRNA *ptr, const char *key, PointerRNA *r_ptr) { Scene *scene= (Scene*)ptr->data; @@ -659,10 +678,10 @@ Scene *scene= ptr->id.data; RenderData *rd= &scene->r; #ifdef WITH_FFMPEG - ffmpeg_verify_image_type(rd); + ffmpeg_verify_image_type(rd, imf); #endif #ifdef WITH_QUICKTIME - quicktime_verify_image_type(rd); + quicktime_verify_image_type(rd, imf); #endif (void)rd; } @@ -691,7 +710,21 @@ * where 'BW' will force greyscale even if the output format writes * as RGBA, this is age old blender convention and not sure how useful * it really is but keep it for now - campbell */ - const char chan_flag= BKE_imtype_valid_channels(imf->imtype) | (is_render ? IMA_CHAN_FLAG_BW : 0); + char chan_flag= BKE_imtype_valid_channels(imf->imtype) | (is_render ? IMA_CHAN_FLAG_BW : 0); + +#ifdef WITH_FFMPEG + /* a WAY more crappy case than B&W flag: depending on codec, file format MIGHT support + * alpha channel. for example MPEG format with h264 codec can't do alpha channel, but + * the same MPEG format with QTRLE codec can easily handle alpga channel. + * not sure how to deal with such cases in a nicer way (sergey) */ + if(is_render) { + Scene *scene = ptr->id.data; + RenderData *rd = &scene->r; + + if (rd->ffcodecdata.codec == CODEC_ID_QTRLE) + chan_flag |= IMA_CHAN_FLAG_ALPHA; + } +#endif if (chan_flag == (IMA_CHAN_FLAG_BW|IMA_CHAN_FLAG_RGB|IMA_CHAN_FLAG_ALPHA)) { return image_color_mode_items; @@ -788,16 +821,16 @@ #ifdef WITH_QUICKTIME static int rna_RenderSettings_qtcodecsettings_codecType_get(PointerRNA *ptr) { - RenderData *rd= (RenderData*)ptr->data; + QuicktimeCodecSettings *settings = (QuicktimeCodecSettings*)ptr->data; - return quicktime_rnatmpvalue_from_videocodectype(rd->qtcodecsettings.codecType); + return quicktime_rnatmpvalue_from_videocodectype(settings->codecType); } static void rna_RenderSettings_qtcodecsettings_codecType_set(PointerRNA *ptr, int value) { - RenderData *rd= (RenderData*)ptr->data; + QuicktimeCodecSettings *settings = (QuicktimeCodecSettings*)ptr->data; - rd->qtcodecsettings.codecType = quicktime_videocodecType_from_rnatmpvalue(value); + settings->codecType = quicktime_videocodecType_from_rnatmpvalue(value); } static EnumPropertyItem *rna_RenderSettings_qtcodecsettings_codecType_itemf(bContext *C, PointerRNA *ptr, @@ -830,16 +863,16 @@ #ifdef USE_QTKIT static int rna_RenderSettings_qtcodecsettings_audiocodecType_get(PointerRNA *ptr) { - RenderData *rd= (RenderData*)ptr->data; + QuicktimeCodecSettings *settings = (QuicktimeCodecSettings*)ptr->data; - return quicktime_rnatmpvalue_from_audiocodectype(rd->qtcodecsettings.audiocodecType); + return quicktime_rnatmpvalue_from_audiocodectype(settings->audiocodecType); } static void rna_RenderSettings_qtcodecsettings_audiocodecType_set(PointerRNA *ptr, int value) { - RenderData *rd= (RenderData*)ptr->data; + QuicktimeCodecSettings *settings = (QuicktimeCodecSettings*)ptr->data; - rd->qtcodecsettings.audiocodecType = quicktime_audiocodecType_from_rnatmpvalue(value); + settings->audiocodecType = quicktime_audiocodecType_from_rnatmpvalue(value); } static EnumPropertyItem *rna_RenderSettings_qtcodecsettings_audiocodecType_itemf(bContext *C, PointerRNA *ptr, @@ -868,6 +901,29 @@ #endif #endif +#ifdef WITH_FFMPEG +static void rna_FFmpegSettings_lossless_output_set(PointerRNA *ptr, int value) +{ + Scene *scene = (Scene *) ptr->id.data; + RenderData *rd = &scene->r; + + if (value) + rd->ffcodecdata.flags |= FFMPEG_LOSSLESS_OUTPUT; + else + rd->ffcodecdata.flags &= ~FFMPEG_LOSSLESS_OUTPUT; + + ffmpeg_verify_codec_settings(rd); +} + +static void rna_FFmpegSettings_codec_settings_update(Main *UNUSED(bmain), Scene *UNUSED(scene_unused), PointerRNA *ptr) +{ + Scene *scene = (Scene *) ptr->id.data; + RenderData *rd = &scene->r; + + ffmpeg_verify_codec_settings(rd); +} +#endif + static int rna_RenderSettings_active_layer_index_get(PointerRNA *ptr) { RenderData *rd= (RenderData*)ptr->data; @@ -999,7 +1055,7 @@ WM_main_add_notifier(NC_NODE|NA_EDITED, node); if (node->type == CMP_NODE_IMAGE) - BKE_image_signal((Image *)node->id, NULL, IMA_SIGNAL_RELOAD); + BKE_image_signal((Image *)node->id, NULL, IMA_SIGNAL_FREE); } } } @@ -1213,6 +1269,13 @@ G.fileflags &= ~G_FILE_AUTOPLAY; } +static void rna_GameSettings_exit_key_set(PointerRNA *ptr, int value) +{ + GameData *gm = (GameData*)ptr->data; + + if(ISKEYBOARD(value)) + gm->exitkey=value; +} static TimeMarker *rna_TimeLine_add(Scene *scene, const char name[]) { @@ -1267,7 +1330,24 @@ } } +static void rna_UnifiedPaintSettings_size_set(PointerRNA *ptr, int value) +{ + UnifiedPaintSettings* ups = ptr->data; + + /* scale unprojected radius so it stays consistent with brush size */ + brush_scale_unprojected_radius(&ups->unprojected_radius, + value, ups->size); + ups->size= value; +} + +static void rna_UnifiedPaintSettings_unprojected_radius_set(PointerRNA *ptr, float value) +{ + UnifiedPaintSettings* ups = ptr->data; + /* scale brush size so it stays consistent with unprojected_radius */ + brush_scale_size(&ups->size, value, ups->unprojected_radius); + ups->unprojected_radius= value; +} /* note: without this, when Multi-Paint is activated/deactivated, the colors * will not change right away when multiple bones are selected, this function @@ -1390,10 +1470,38 @@ RNA_def_property_pointer_sdna(prop, NULL, "imapaint"); RNA_def_property_ui_text(prop, "Image Paint", ""); + prop= RNA_def_property(srna, "uv_sculpt", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "uvsculpt"); + RNA_def_property_ui_text(prop, "UV Sculpt", ""); + prop= RNA_def_property(srna, "particle_edit", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "particle"); RNA_def_property_ui_text(prop, "Particle Edit", ""); + prop= RNA_def_property(srna, "use_uv_sculpt", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "use_uv_sculpt", 1); + RNA_def_property_ui_text(prop, "UV Sculpt", "Enable brush for UV sculpting"); + RNA_def_property_ui_icon(prop, ICON_TPAINT_HLT, 0); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, "rna_SpaceImageEditor_uv_sculpt_update"); + + prop= RNA_def_property(srna, "uv_sculpt_lock_borders", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "uv_sculpt_settings", UV_SCULPT_LOCK_BORDERS); + RNA_def_property_ui_text(prop, "Lock Borders", "Disable editing of boundary edges"); + + prop= RNA_def_property(srna, "uv_sculpt_all_islands", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "uv_sculpt_settings", UV_SCULPT_ALL_ISLANDS); + RNA_def_property_ui_text(prop, "Sculpt All Islands", "Brush operates on all islands"); + + prop= RNA_def_property(srna, "uv_sculpt_tool", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "uv_sculpt_tool"); + RNA_def_property_enum_items(prop, uv_sculpt_tool_items); + RNA_def_property_ui_text(prop, "UV Sculpt Tools", "Select Tools for the UV sculpt brushes"); + + prop= RNA_def_property(srna, "uv_relax_method", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "uv_relax_method"); + RNA_def_property_enum_items(prop, uv_sculpt_relaxation_items); + RNA_def_property_ui_text(prop, "Relaxation Method", "Algorithm used for UV relaxation"); + /* Transform */ prop= RNA_def_property(srna, "proportional_edit", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "proportional"); @@ -1606,19 +1714,67 @@ RNA_def_property_ui_text(prop, "Stroke conversion method", "Method used to convert stroke to bones"); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); - /* Sculpt/Paint Unified Size and Strength */ - - prop= RNA_def_property(srna, "sculpt_paint_use_unified_size", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "sculpt_paint_settings", SCULPT_PAINT_USE_UNIFIED_SIZE); - RNA_def_property_ui_text(prop, "Sculpt/Paint Use Unified Radius", - "Instead of per brush radius, the radius is shared across brushes"); - - prop= RNA_def_property(srna, "sculpt_paint_use_unified_strength", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "sculpt_paint_settings", SCULPT_PAINT_USE_UNIFIED_ALPHA); - RNA_def_property_ui_text(prop, "Sculpt/Paint Use Unified Strength", - "Instead of per brush strength, the strength is shared across brushes"); + /* Unified Paint Settings */ + prop= RNA_def_property(srna, "unified_paint_settings", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); + RNA_def_property_struct_type(prop, "UnifiedPaintSettings"); + RNA_def_property_ui_text(prop, "Unified Paint Settings", NULL); } +static void rna_def_unified_paint_settings(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna= RNA_def_struct(brna, "UnifiedPaintSettings", NULL); + RNA_def_struct_ui_text(srna, "Unified Paint Settings", "Overrides for some of the active brush's settings"); + + /* high-level flags to enable or disable unified paint settings */ + prop= RNA_def_property(srna, "use_unified_size", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", UNIFIED_PAINT_SIZE); + RNA_def_property_ui_text(prop, "Use Unified Radius", + "Instead of per-brush radius, the radius is shared across brushes"); + + prop= RNA_def_property(srna, "use_unified_strength", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", UNIFIED_PAINT_ALPHA); + RNA_def_property_ui_text(prop, "Use Unified Strength", + "Instead of per-brush strength, the strength is shared across brushes"); + + /* unified paint settings that override the equivalent settings + from the active brush */ + prop= RNA_def_property(srna, "size", PROP_INT, PROP_DISTANCE); + RNA_def_property_int_funcs(prop, NULL, "rna_UnifiedPaintSettings_size_set", NULL); + RNA_def_property_range(prop, 1, MAX_BRUSH_PIXEL_RADIUS*10); + RNA_def_property_ui_range(prop, 1, MAX_BRUSH_PIXEL_RADIUS, 1, 0); + RNA_def_property_ui_text(prop, "Radius", "Radius of the brush in pixels"); + + prop= RNA_def_property(srna, "unprojected_radius", PROP_FLOAT, PROP_DISTANCE); + RNA_def_property_float_funcs(prop, NULL, "rna_UnifiedPaintSettings_unprojected_radius_set", NULL); + RNA_def_property_range(prop, 0.001, FLT_MAX); + RNA_def_property_ui_range(prop, 0.001, 1, 0, 0); + RNA_def_property_ui_text(prop, "Unprojected Radius", "Radius of brush in Blender units"); + + prop= RNA_def_property(srna, "strength", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "alpha"); + RNA_def_property_float_default(prop, 0.5f); + RNA_def_property_range(prop, 0.0f, 10.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.001, 0.001); + RNA_def_property_ui_text(prop, "Strength", "How powerful the effect of the brush is when applied"); + + prop= RNA_def_property(srna, "use_pressure_size", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", UNIFIED_PAINT_BRUSH_SIZE_PRESSURE); + RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); + RNA_def_property_ui_text(prop, "Size Pressure", "Enable tablet pressure sensitivity for size"); + + prop= RNA_def_property(srna, "use_pressure_strength", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", UNIFIED_PAINT_BRUSH_ALPHA_PRESSURE); + RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); + RNA_def_property_ui_text(prop, "Strength Pressure", "Enable tablet pressure sensitivity for strength"); + + prop= RNA_def_property(srna, "use_locked_size", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", UNIFIED_PAINT_BRUSH_LOCK_SIZE); + RNA_def_property_ui_text(prop, "Use Blender Units", "When locked brush stays same size relative to object; when unlocked brush size is given in pixels"); +} static void rna_def_unit_settings(BlenderRNA *brna) { @@ -1932,6 +2088,60 @@ RNA_def_property_ui_icon(prop, ICON_RESTRICT_RENDER_OFF, 1); if(scene) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_SceneRenderLayer_pass_update"); else RNA_def_property_clear_flag(prop, PROP_EDITABLE); + + prop= RNA_def_property(srna, "use_pass_diffuse_direct", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_DIFFUSE_DIRECT); + RNA_def_property_ui_text(prop, "Diffuse Direct", "Deliver diffuse direct pass"); + if(scene) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_SceneRenderLayer_pass_update"); + else RNA_def_property_clear_flag(prop, PROP_EDITABLE); + + prop= RNA_def_property(srna, "use_pass_diffuse_indirect", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_DIFFUSE_INDIRECT); + RNA_def_property_ui_text(prop, "Diffuse Indirect", "Deliver diffuse indirect pass"); + if(scene) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_SceneRenderLayer_pass_update"); + else RNA_def_property_clear_flag(prop, PROP_EDITABLE); + + prop= RNA_def_property(srna, "use_pass_diffuse_color", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_DIFFUSE_COLOR); + RNA_def_property_ui_text(prop, "Diffuse Color", "Deliver diffuse color pass"); + if(scene) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_SceneRenderLayer_pass_update"); + else RNA_def_property_clear_flag(prop, PROP_EDITABLE); + + prop= RNA_def_property(srna, "use_pass_glossy_direct", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_GLOSSY_DIRECT); + RNA_def_property_ui_text(prop, "Glossy Direct", "Deliver glossy direct pass"); + if(scene) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_SceneRenderLayer_pass_update"); + else RNA_def_property_clear_flag(prop, PROP_EDITABLE); + + prop= RNA_def_property(srna, "use_pass_glossy_indirect", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_GLOSSY_INDIRECT); + RNA_def_property_ui_text(prop, "Glossy Indirect", "Deliver glossy indirect pass"); + if(scene) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_SceneRenderLayer_pass_update"); + else RNA_def_property_clear_flag(prop, PROP_EDITABLE); + + prop= RNA_def_property(srna, "use_pass_glossy_color", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_GLOSSY_COLOR); + RNA_def_property_ui_text(prop, "Glossy Color", "Deliver glossy color pass"); + if(scene) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_SceneRenderLayer_pass_update"); + else RNA_def_property_clear_flag(prop, PROP_EDITABLE); + + prop= RNA_def_property(srna, "use_pass_transmission_direct", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_TRANSM_DIRECT); + RNA_def_property_ui_text(prop, "Transmission Direct", "Deliver transmission direct pass"); + if(scene) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_SceneRenderLayer_pass_update"); + else RNA_def_property_clear_flag(prop, PROP_EDITABLE); + + prop= RNA_def_property(srna, "use_pass_transmission_indirect", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_TRANSM_INDIRECT); + RNA_def_property_ui_text(prop, "Transmission Indirect", "Deliver transmission indirect pass"); + if(scene) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_SceneRenderLayer_pass_update"); + else RNA_def_property_clear_flag(prop, PROP_EDITABLE); + + prop= RNA_def_property(srna, "use_pass_transmission_color", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_TRANSM_COLOR); + RNA_def_property_ui_text(prop, "Transmission Color", "Deliver transmission color pass"); + if(scene) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_SceneRenderLayer_pass_update"); + else RNA_def_property_clear_flag(prop, PROP_EDITABLE); } static void rna_def_scene_game_recast_data(BlenderRNA *brna) @@ -2029,6 +2239,14 @@ StructRNA *srna; PropertyRNA *prop; + static EnumPropertyItem aasamples_items[] ={ + {0, "SAMPLES_0", 0, "Off", ""}, + {2, "SAMPLES_2", 0, "2x", ""}, + {4, "SAMPLES_4", 0, "4x", ""}, + {8, "SAMPLES_8", 0, "8x", ""}, + {16, "SAMPLES_16", 0, "16x", ""}, + {0, NULL, 0, NULL, NULL}}; + static EnumPropertyItem framing_types_items[] ={ {SCE_GAMEFRAMING_BARS, "LETTERBOX", 0, "Letterbox", "Show the entire viewport in the display window, using bar horizontally or vertically"}, @@ -2098,11 +2316,23 @@ RNA_def_property_ui_text(prop, "Resolution Y", "Number of vertical pixels in the screen"); RNA_def_property_update(prop, NC_SCENE, NULL); + prop= RNA_def_property(srna, "samples", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "aasamples"); + RNA_def_property_enum_items(prop, aasamples_items); + RNA_def_property_ui_text(prop, "AA Samples", "The number of AA Samples to use for MSAA"); + prop= RNA_def_property(srna, "depth", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "depth"); RNA_def_property_range(prop, 8, 32); RNA_def_property_ui_text(prop, "Bits", "Display bit depth of full screen display"); RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "exit_key", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "exitkey"); + RNA_def_property_enum_items(prop, event_type_items); + RNA_def_property_enum_funcs(prop, NULL, "rna_GameSettings_exit_key_set", NULL); + RNA_def_property_ui_text(prop, "Exit Key", "The key that exits the Game Engine"); + RNA_def_property_update(prop, NC_SCENE, NULL); // Do we need it here ? (since we already have it in World prop= RNA_def_property(srna, "frequency", PROP_INT, PROP_NONE); @@ -2112,10 +2342,15 @@ RNA_def_property_update(prop, NC_SCENE, NULL); prop= RNA_def_property(srna, "show_fullscreen", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "fullscreen", 1.0); + RNA_def_property_boolean_sdna(prop, NULL, "playerflag", GAME_PLAYER_FULLSCREEN); RNA_def_property_ui_text(prop, "Fullscreen", "Start player in a new fullscreen display"); RNA_def_property_update(prop, NC_SCENE, NULL); + prop= RNA_def_property(srna, "use_desktop", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "playerflag", GAME_PLAYER_DESKTOP_RESOLUTION); + RNA_def_property_ui_text(prop, "Desktop", "Uses the current desktop resultion in fullscreen mode"); + RNA_def_property_update(prop, NC_SCENE, NULL); + /* Framing */ prop= RNA_def_property(srna, "frame_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "framing.type"); @@ -2564,6 +2799,282 @@ RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); } +static void rna_def_scene_ffmpeg_settings(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + +#ifdef WITH_FFMPEG + static EnumPropertyItem ffmpeg_format_items[] = { + {FFMPEG_MPEG1, "MPEG1", 0, "MPEG-1", ""}, + {FFMPEG_MPEG2, "MPEG2", 0, "MPEG-2", ""}, + {FFMPEG_MPEG4, "MPEG4", 0, "MPEG-4", ""}, + {FFMPEG_AVI, "AVI", 0, "AVI", ""}, + {FFMPEG_MOV, "QUICKTIME", 0, "Quicktime", ""}, + {FFMPEG_DV, "DV", 0, "DV", ""}, + {FFMPEG_H264, "H264", 0, "H.264", ""}, + {FFMPEG_XVID, "XVID", 0, "Xvid", ""}, + {FFMPEG_OGG, "OGG", 0, "Ogg", ""}, + {FFMPEG_MKV, "MKV", 0, "Matroska", ""}, + {FFMPEG_FLV, "FLASH", 0, "Flash", ""}, + {FFMPEG_WAV, "WAV", 0, "Wav", ""}, + {FFMPEG_MP3, "MP3", 0, "Mp3", ""}, + {0, NULL, 0, NULL, NULL}}; + + static EnumPropertyItem ffmpeg_codec_items[] = { + {CODEC_ID_NONE, "NONE", 0, "None", ""}, + {CODEC_ID_MPEG1VIDEO, "MPEG1", 0, "MPEG-1", ""}, + {CODEC_ID_MPEG2VIDEO, "MPEG2", 0, "MPEG-2", ""}, + {CODEC_ID_MPEG4, "MPEG4", 0, "MPEG-4(divx)", ""}, + {CODEC_ID_HUFFYUV, "HUFFYUV", 0, "HuffYUV", ""}, + {CODEC_ID_DVVIDEO, "DV", 0, "DV", ""}, + {CODEC_ID_H264, "H264", 0, "H.264", ""}, + {CODEC_ID_THEORA, "THEORA", 0, "Theora", ""}, + {CODEC_ID_FLV1, "FLASH", 0, "Flash Video", ""}, + {CODEC_ID_FFV1, "FFV1", 0, "FFmpeg video codec #1", ""}, + {CODEC_ID_QTRLE, "QTRLE", 0, "QTRLE", ""}, + /* {CODEC_ID_DNXHD, "DNXHD", 0, "DNxHD", ""},*/ /* disabled for after release */ + {0, NULL, 0, NULL, NULL}}; + + static EnumPropertyItem ffmpeg_audio_codec_items[] = { + {CODEC_ID_NONE, "NONE", 0, "None", ""}, + {CODEC_ID_MP2, "MP2", 0, "MP2", ""}, + {CODEC_ID_MP3, "MP3", 0, "MP3", ""}, + {CODEC_ID_AC3, "AC3", 0, "AC3", ""}, + {CODEC_ID_AAC, "AAC", 0, "AAC", ""}, + {CODEC_ID_VORBIS, "VORBIS", 0, "Vorbis", ""}, + {CODEC_ID_FLAC, "FLAC", 0, "FLAC", ""}, + {CODEC_ID_PCM_S16LE, "PCM", 0, "PCM", ""}, + {0, NULL, 0, NULL, NULL}}; +#endif + + static EnumPropertyItem audio_channel_items[] = { + {1, "MONO", 0, "Mono", "Set audio channels to mono"}, + {2, "STEREO", 0, "Stereo", "Set audio channels to stereo"}, + {4, "SURROUND4", 0, "4 Channels", "Set audio channels to 4 channels"}, + {6, "SURROUND51", 0, "5.1 Surround", "Set audio channels to 5.1 surround sound"}, + {8, "SURROUND71", 0, "7.1 Surround", "Set audio channels to 7.1 surround sound"}, + {0, NULL, 0, NULL, NULL}}; + + srna = RNA_def_struct(brna, "FFmpegSettings", NULL); + RNA_def_struct_sdna(srna, "FFMpegCodecData"); + RNA_def_struct_ui_text(srna, "FFmpeg Settings", "FFmpeg related settings for the scene"); + +#ifdef WITH_FFMPEG + prop = RNA_def_property(srna, "format", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "type"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_enum_items(prop, ffmpeg_format_items); + RNA_def_property_ui_text(prop, "Format", "Output file format"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_FFmpegSettings_codec_settings_update"); + + prop = RNA_def_property(srna, "codec", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "codec"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_enum_items(prop, ffmpeg_codec_items); + RNA_def_property_ui_text(prop, "Codec", "FFmpeg codec to use"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_FFmpegSettings_codec_settings_update"); + + prop = RNA_def_property(srna, "video_bitrate", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "video_bitrate"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_range(prop, 1, 14000); + RNA_def_property_ui_text(prop, "Bitrate", "Video bitrate (kb/s)"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + + prop = RNA_def_property(srna, "minrate", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "rc_min_rate"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_range(prop, 0, 9000); + RNA_def_property_ui_text(prop, "Min Rate", "Rate control: min rate (kb/s)"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + + prop = RNA_def_property(srna, "maxrate", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "rc_max_rate"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_range(prop, 1, 14000); + RNA_def_property_ui_text(prop, "Max Rate", "Rate control: max rate (kb/s)"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + + prop= RNA_def_property(srna, "muxrate", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "mux_rate"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_range(prop, 0, 100000000); + RNA_def_property_ui_text(prop, "Mux Rate", "Mux rate (bits/s(!))"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + + prop = RNA_def_property(srna, "gopsize", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "gop_size"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_range(prop, 0, 100); + RNA_def_property_ui_text(prop, "GOP Size", "Distance between key frames"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + + prop = RNA_def_property(srna, "buffersize", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "rc_buffer_size"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_range(prop, 0, 2000); + RNA_def_property_ui_text(prop, "Buffersize", "Rate control: buffer size (kb)"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + + prop = RNA_def_property(srna, "packetsize", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "mux_packet_size"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_range(prop, 0, 16384); + RNA_def_property_ui_text(prop, "Mux Packet Size", "Mux packet size (byte)"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + + prop= RNA_def_property(srna, "use_autosplit", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flags", FFMPEG_AUTOSPLIT_OUTPUT); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, "Autosplit Output", "Autosplit output at 2GB boundary"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + + prop = RNA_def_property(srna, "use_lossless_output", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flags", FFMPEG_LOSSLESS_OUTPUT); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_boolean_funcs(prop, NULL, "rna_FFmpegSettings_lossless_output_set"); + RNA_def_property_ui_text(prop, "Lossless Output", "Use lossless output for video streams"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + + /* FFMPEG Audio*/ + prop = RNA_def_property(srna, "audio_codec", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "audio_codec"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_enum_items(prop, ffmpeg_audio_codec_items); + RNA_def_property_ui_text(prop, "Audio Codec", "FFmpeg audio codec to use"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + + prop = RNA_def_property(srna, "audio_bitrate", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "audio_bitrate"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_range(prop, 32, 384); + RNA_def_property_ui_text(prop, "Bitrate", "Audio bitrate (kb/s)"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + + prop= RNA_def_property(srna, "audio_volume", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "audio_volume"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Volume", "Audio volume"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); +#endif + + // the following two "ffmpeg" settings are general audio settings + prop= RNA_def_property(srna, "audio_mixrate", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "audio_mixrate"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_range(prop, 8000, 192000); + RNA_def_property_ui_text(prop, "Samplerate", "Audio samplerate(samples/s)"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + + prop= RNA_def_property(srna, "audio_channels", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "audio_channels"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_enum_items(prop, audio_channel_items); + RNA_def_property_ui_text(prop, "Audio Channels", "Audio channel count"); +} + +#ifdef WITH_QUICKTIME +static void rna_def_scene_quicktime_settings(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + static EnumPropertyItem quicktime_codec_type_items[] = { + {0, "codec", 0, "codec", ""}, + {0, NULL, 0, NULL, NULL}}; + +#ifdef USE_QTKIT + static EnumPropertyItem quicktime_audio_samplerate_items[] = { + {22050, "22050", 0, "22kHz", ""}, + {44100, "44100", 0, "44.1kHz", ""}, + {48000, "48000", 0, "48kHz", ""}, + {88200, "88200", 0, "88.2kHz", ""}, + {96000, "96000", 0, "96kHz", ""}, + {192000, "192000", 0, "192kHz", ""}, + {0, NULL, 0, NULL, NULL}}; + + static EnumPropertyItem quicktime_audio_bitdepth_items[] = { + {AUD_FORMAT_U8, "8BIT", 0, "8bit", ""}, + {AUD_FORMAT_S16, "16BIT", 0, "16bit", ""}, + {AUD_FORMAT_S24, "24BIT", 0, "24bit", ""}, + {AUD_FORMAT_S32, "32BIT", 0, "32bit", ""}, + {AUD_FORMAT_FLOAT32, "FLOAT32", 0, "float32", ""}, + {AUD_FORMAT_FLOAT64, "FLOAT64", 0, "float64", ""}, + {0, NULL, 0, NULL, NULL}}; + + static EnumPropertyItem quicktime_audio_bitrate_items[] = { + {64000, "64000", 0, "64kbps", ""}, + {112000, "112000", 0, "112kpbs", ""}, + {128000, "128000", 0, "128kbps", ""}, + {192000, "192000", 0, "192kbps", ""}, + {256000, "256000", 0, "256kbps", ""}, + {320000, "320000", 0, "320kbps", ""}, + {0, NULL, 0, NULL, NULL}}; +#endif + + /* QuickTime */ + srna = RNA_def_struct(brna, "QuickTimeSettings", NULL); + RNA_def_struct_sdna(srna, "QuicktimeCodecSettings"); + RNA_def_struct_ui_text(srna, "QuickTime Settings", "QuickTime related settings for the scene"); + + prop = RNA_def_property(srna, "codec_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "codecType"); + RNA_def_property_enum_items(prop, quicktime_codec_type_items); + RNA_def_property_enum_funcs(prop, "rna_RenderSettings_qtcodecsettings_codecType_get", + "rna_RenderSettings_qtcodecsettings_codecType_set", + "rna_RenderSettings_qtcodecsettings_codecType_itemf"); + RNA_def_property_ui_text(prop, "Codec", "QuickTime codec type"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + + prop = RNA_def_property(srna, "codec_spatial_quality", PROP_INT, PROP_PERCENTAGE); + RNA_def_property_int_sdna(prop, NULL, "codecSpatialQuality"); + RNA_def_property_range(prop, 0, 100); + RNA_def_property_ui_text(prop, "Spatial quality", "Intra-frame spatial quality level"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + +#ifdef USE_QTKIT + prop = RNA_def_property(srna, "audiocodec_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "audiocodecType"); + RNA_def_property_enum_items(prop, quicktime_codec_type_items); + RNA_def_property_enum_funcs(prop, "rna_RenderSettings_qtcodecsettings_audiocodecType_get", + "rna_RenderSettings_qtcodecsettings_audiocodecType_set", + "rna_RenderSettings_qtcodecsettings_audiocodecType_itemf"); + RNA_def_property_ui_text(prop, "Audio Codec", "QuickTime audio codec type"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + + prop = RNA_def_property(srna, "audio_samplerate", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "audioSampleRate"); + RNA_def_property_enum_items(prop, quicktime_audio_samplerate_items); + RNA_def_property_ui_text(prop, "Smp Rate", "Sample Rate"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + + prop = RNA_def_property(srna, "audio_bitdepth", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "audioBitDepth"); + RNA_def_property_enum_items(prop, quicktime_audio_bitdepth_items); + RNA_def_property_ui_text(prop, "Bit Depth", "Bit Depth"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + + prop = RNA_def_property(srna, "audio_resampling_hq", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "audioCodecFlags", QTAUDIO_FLAG_RESAMPLE_NOHQ); + RNA_def_property_ui_text(prop, "HQ", "Use High Quality resampling algorithm"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + + prop= RNA_def_property(srna, "audio_codec_isvbr", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "audioCodecFlags", QTAUDIO_FLAG_CODEC_ISCBR); + RNA_def_property_ui_text(prop, "VBR", "Use Variable Bit Rate compression (improves quality at same bitrate)"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + + prop= RNA_def_property(srna, "audio_bitrate", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "audioBitRate"); + RNA_def_property_enum_items(prop, quicktime_audio_bitrate_items); + RNA_def_property_ui_text(prop, "Bitrate", "Compressed audio bitrate"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); +#endif +} +#endif + static void rna_def_scene_render_data(BlenderRNA *brna) { StructRNA *srna; @@ -2654,96 +3165,16 @@ {0, "AUTO", 0, "Auto-detect", "Automatically determine the number of threads, based on CPUs"}, {R_FIXED_THREADS, "FIXED", 0, "Fixed", "Manually determine the number of threads"}, {0, NULL, 0, NULL, NULL}}; - -#ifdef WITH_QUICKTIME - static EnumPropertyItem quicktime_codec_type_items[] = { - {0, "codec", 0, "codec", ""}, - {0, NULL, 0, NULL, NULL}}; - -#ifdef USE_QTKIT - static EnumPropertyItem quicktime_audio_samplerate_items[] = { - {22050, "22050", 0, "22kHz", ""}, - {44100, "44100", 0, "44.1kHz", ""}, - {48000, "48000", 0, "48kHz", ""}, - {88200, "88200", 0, "88.2kHz", ""}, - {96000, "96000", 0, "96kHz", ""}, - {192000, "192000", 0, "192kHz", ""}, - {0, NULL, 0, NULL, NULL}}; - - static EnumPropertyItem quicktime_audio_bitdepth_items[] = { - {AUD_FORMAT_U8, "8BIT", 0, "8bit", ""}, - {AUD_FORMAT_S16, "16BIT", 0, "16bit", ""}, - {AUD_FORMAT_S24, "24BIT", 0, "24bit", ""}, - {AUD_FORMAT_S32, "32BIT", 0, "32bit", ""}, - {AUD_FORMAT_FLOAT32, "FLOAT32", 0, "float32", ""}, - {AUD_FORMAT_FLOAT64, "FLOAT64", 0, "float64", ""}, - {0, NULL, 0, NULL, NULL}}; - - static EnumPropertyItem quicktime_audio_bitrate_items[] = { - {64000, "64000", 0, "64kbps", ""}, - {112000, "112000", 0, "112kpbs", ""}, - {128000, "128000", 0, "128kbps", ""}, - {192000, "192000", 0, "192kbps", ""}, - {256000, "256000", 0, "256kbps", ""}, - {320000, "320000", 0, "320kbps", ""}, - {0, NULL, 0, NULL, NULL}}; -#endif -#endif - -#ifdef WITH_FFMPEG - static EnumPropertyItem ffmpeg_format_items[] = { - {FFMPEG_MPEG1, "MPEG1", 0, "MPEG-1", ""}, - {FFMPEG_MPEG2, "MPEG2", 0, "MPEG-2", ""}, - {FFMPEG_MPEG4, "MPEG4", 0, "MPEG-4", ""}, - {FFMPEG_AVI, "AVI", 0, "AVI", ""}, - {FFMPEG_MOV, "QUICKTIME", 0, "Quicktime", ""}, - {FFMPEG_DV, "DV", 0, "DV", ""}, - {FFMPEG_H264, "H264", 0, "H.264", ""}, - {FFMPEG_XVID, "XVID", 0, "Xvid", ""}, - {FFMPEG_OGG, "OGG", 0, "Ogg", ""}, - {FFMPEG_MKV, "MKV", 0, "Matroska", ""}, - {FFMPEG_FLV, "FLASH", 0, "Flash", ""}, - {FFMPEG_WAV, "WAV", 0, "Wav", ""}, - {FFMPEG_MP3, "MP3", 0, "Mp3", ""}, - {0, NULL, 0, NULL, NULL}}; - - static EnumPropertyItem ffmpeg_codec_items[] = { - {CODEC_ID_NONE, "NONE", 0, "None", ""}, - {CODEC_ID_MPEG1VIDEO, "MPEG1", 0, "MPEG-1", ""}, - {CODEC_ID_MPEG2VIDEO, "MPEG2", 0, "MPEG-2", ""}, - {CODEC_ID_MPEG4, "MPEG4", 0, "MPEG-4(divx)", ""}, - {CODEC_ID_HUFFYUV, "HUFFYUV", 0, "HuffYUV", ""}, - {CODEC_ID_DVVIDEO, "DV", 0, "DV", ""}, - {CODEC_ID_H264, "H264", 0, "H.264", ""}, - {CODEC_ID_THEORA, "THEORA", 0, "Theora", ""}, - {CODEC_ID_FLV1, "FLASH", 0, "Flash Video", ""}, - {CODEC_ID_FFV1, "FFV1", 0, "FFmpeg video codec #1", ""}, - {0, NULL, 0, NULL, NULL}}; - - static EnumPropertyItem ffmpeg_audio_codec_items[] = { - {CODEC_ID_NONE, "NONE", 0, "None", ""}, - {CODEC_ID_MP2, "MP2", 0, "MP2", ""}, - {CODEC_ID_MP3, "MP3", 0, "MP3", ""}, - {CODEC_ID_AC3, "AC3", 0, "AC3", ""}, - {CODEC_ID_AAC, "AAC", 0, "AAC", ""}, - {CODEC_ID_VORBIS, "VORBIS", 0, "Vorbis", ""}, - {CODEC_ID_FLAC, "FLAC", 0, "FLAC", ""}, - {CODEC_ID_PCM_S16LE, "PCM", 0, "PCM", ""}, - {0, NULL, 0, NULL, NULL}}; -#endif - - static EnumPropertyItem audio_channel_items[] = { - {1, "MONO", 0, "Mono", "Set audio channels to mono"}, - {2, "STEREO", 0, "Stereo", "Set audio channels to stereo"}, - {4, "SURROUND4", 0, "4 Channels", "Set audio channels to 4 channels"}, - {6, "SURROUND51", 0, "5.1 Surround", "Set audio channels to 5.1 surround sound"}, - {8, "SURROUND71", 0, "7.1 Surround", "Set audio channels to 7.1 surround sound"}, - {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem engine_items[] = { {0, "BLENDER_RENDER", 0, "Blender Render", "Use the Blender internal rendering engine for rendering"}, {0, NULL, 0, NULL, NULL}}; + rna_def_scene_ffmpeg_settings(brna); +#ifdef WITH_QUICKTIME + rna_def_scene_quicktime_settings(brna); +#endif + srna= RNA_def_struct(brna, "RenderSettings", NULL); RNA_def_struct_sdna(srna, "RenderData"); RNA_def_struct_nested(brna, srna, "Scene"); @@ -2759,18 +3190,21 @@ prop= RNA_def_property(srna, "resolution_x", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "xsch"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_range(prop, 4, 10000); RNA_def_property_ui_text(prop, "Resolution X", "Number of horizontal pixels in the rendered image"); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_SceneCamera_update"); prop= RNA_def_property(srna, "resolution_y", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "ysch"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_range(prop, 4, 10000); RNA_def_property_ui_text(prop, "Resolution Y", "Number of vertical pixels in the rendered image"); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_SceneCamera_update"); prop= RNA_def_property(srna, "resolution_percentage", PROP_INT, PROP_PERCENTAGE); RNA_def_property_int_sdna(prop, NULL, "size"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_range(prop, 1, SHRT_MAX); RNA_def_property_ui_range(prop, 1, 100, 10, 1); RNA_def_property_ui_text(prop, "Resolution %", "Percentage scale for render resolution"); @@ -2790,172 +3224,31 @@ prop= RNA_def_property(srna, "pixel_aspect_x", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "xasp"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_range(prop, 1.0f, 200.0f); RNA_def_property_ui_text(prop, "Pixel Aspect X", "Horizontal aspect ratio - for anamorphic or non-square pixel output"); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_SceneCamera_update"); prop= RNA_def_property(srna, "pixel_aspect_y", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "yasp"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_range(prop, 1.0f, 200.0f); RNA_def_property_ui_text(prop, "Pixel Aspect Y", "Vertical aspect ratio - for anamorphic or non-square pixel output"); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_SceneCamera_update"); #ifdef WITH_QUICKTIME - /* QuickTime */ - - prop= RNA_def_property(srna, "quicktime_codec_type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_bitflag_sdna(prop, NULL, "qtcodecsettings.codecType"); - RNA_def_property_enum_items(prop, quicktime_codec_type_items); - RNA_def_property_enum_funcs(prop, "rna_RenderSettings_qtcodecsettings_codecType_get", - "rna_RenderSettings_qtcodecsettings_codecType_set", - "rna_RenderSettings_qtcodecsettings_codecType_itemf"); - RNA_def_property_ui_text(prop, "Codec", "QuickTime codec type"); - RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - - prop= RNA_def_property(srna, "quicktime_codec_spatial_quality", PROP_INT, PROP_PERCENTAGE); - RNA_def_property_int_sdna(prop, NULL, "qtcodecsettings.codecSpatialQuality"); - RNA_def_property_range(prop, 0, 100); - RNA_def_property_ui_text(prop, "Spatial quality", "Intra-frame spatial quality level"); - RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - -#ifdef USE_QTKIT - prop= RNA_def_property(srna, "quicktime_audiocodec_type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_bitflag_sdna(prop, NULL, "qtcodecsettings.audiocodecType"); - RNA_def_property_enum_items(prop, quicktime_codec_type_items); - RNA_def_property_enum_funcs(prop, "rna_RenderSettings_qtcodecsettings_audiocodecType_get", - "rna_RenderSettings_qtcodecsettings_audiocodecType_set", - "rna_RenderSettings_qtcodecsettings_audiocodecType_itemf"); - RNA_def_property_ui_text(prop, "Audio Codec", "QuickTime audio codec type"); - RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - - prop= RNA_def_property(srna, "quicktime_audio_samplerate", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_bitflag_sdna(prop, NULL, "qtcodecsettings.audioSampleRate"); - RNA_def_property_enum_items(prop, quicktime_audio_samplerate_items); - RNA_def_property_ui_text(prop, "Smp Rate", "Sample Rate"); - RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - - prop= RNA_def_property(srna, "quicktime_audio_bitdepth", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_bitflag_sdna(prop, NULL, "qtcodecsettings.audioBitDepth"); - RNA_def_property_enum_items(prop, quicktime_audio_bitdepth_items); - RNA_def_property_ui_text(prop, "Bit Depth", "Bit Depth"); - RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - - prop= RNA_def_property(srna, "quicktime_audio_resampling_hq", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "qtcodecsettings.audioCodecFlags", QTAUDIO_FLAG_RESAMPLE_NOHQ); - RNA_def_property_ui_text(prop, "HQ", "Use High Quality resampling algorithm"); - RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - - prop= RNA_def_property(srna, "quicktime_audio_codec_isvbr", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "qtcodecsettings.audioCodecFlags", QTAUDIO_FLAG_CODEC_ISCBR); - RNA_def_property_ui_text(prop, "VBR", "Use Variable Bit Rate compression (improves quality at same bitrate)"); - RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - - prop= RNA_def_property(srna, "quicktime_audio_bitrate", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_bitflag_sdna(prop, NULL, "qtcodecsettings.audioBitRate"); - RNA_def_property_enum_items(prop, quicktime_audio_bitrate_items); - RNA_def_property_ui_text(prop, "Bitrate", "Compressed audio bitrate"); - RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + prop= RNA_def_property(srna, "quicktime", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "QuickTimeSettings"); + RNA_def_property_pointer_sdna(prop, NULL, "qtcodecsettings"); + RNA_def_property_flag(prop, PROP_NEVER_UNLINK); + RNA_def_property_ui_text(prop, "QuickTime Settings", "QuickTime related settings for the scene"); #endif -#endif - -#ifdef WITH_FFMPEG - /* FFMPEG Video*/ - - prop= RNA_def_property(srna, "ffmpeg_format", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_bitflag_sdna(prop, NULL, "ffcodecdata.type"); - RNA_def_property_enum_items(prop, ffmpeg_format_items); - RNA_def_property_ui_text(prop, "Format", "Output file format"); - RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - - prop= RNA_def_property(srna, "ffmpeg_codec", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_bitflag_sdna(prop, NULL, "ffcodecdata.codec"); - RNA_def_property_enum_items(prop, ffmpeg_codec_items); - RNA_def_property_ui_text(prop, "Codec", "FFMpeg codec to use"); - RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - - prop= RNA_def_property(srna, "ffmpeg_video_bitrate", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "ffcodecdata.video_bitrate"); - RNA_def_property_range(prop, 1, 14000); - RNA_def_property_ui_text(prop, "Bitrate", "Video bitrate (kb/s)"); - RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - - prop= RNA_def_property(srna, "ffmpeg_minrate", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "ffcodecdata.rc_min_rate"); - RNA_def_property_range(prop, 0, 9000); - RNA_def_property_ui_text(prop, "Min Rate", "Rate control: min rate (kb/s)"); - RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - - prop= RNA_def_property(srna, "ffmpeg_maxrate", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "ffcodecdata.rc_max_rate"); - RNA_def_property_range(prop, 1, 14000); - RNA_def_property_ui_text(prop, "Max Rate", "Rate control: max rate (kb/s)"); - RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - - prop= RNA_def_property(srna, "ffmpeg_muxrate", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "ffcodecdata.mux_rate"); - RNA_def_property_range(prop, 0, 100000000); - RNA_def_property_ui_text(prop, "Mux Rate", "Mux rate (bits/s(!))"); - RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - - prop= RNA_def_property(srna, "ffmpeg_gopsize", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "ffcodecdata.gop_size"); - RNA_def_property_range(prop, 0, 100); - RNA_def_property_ui_text(prop, "GOP Size", "Distance between key frames"); - RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - - prop= RNA_def_property(srna, "ffmpeg_buffersize", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "ffcodecdata.rc_buffer_size"); - RNA_def_property_range(prop, 0, 2000); - RNA_def_property_ui_text(prop, "Buffersize", "Rate control: buffer size (kb)"); - RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - - prop= RNA_def_property(srna, "ffmpeg_packetsize", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "ffcodecdata.mux_packet_size"); - RNA_def_property_range(prop, 0, 16384); - RNA_def_property_ui_text(prop, "Mux Packet Size", "Mux packet size (byte)"); - RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - - prop= RNA_def_property(srna, "ffmpeg_autosplit", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "ffcodecdata.flags", FFMPEG_AUTOSPLIT_OUTPUT); - RNA_def_property_ui_text(prop, "Autosplit Output", "Autosplit output at 2GB boundary"); - RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - - /* FFMPEG Audio*/ - prop= RNA_def_property(srna, "ffmpeg_audio_codec", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_bitflag_sdna(prop, NULL, "ffcodecdata.audio_codec"); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_enum_items(prop, ffmpeg_audio_codec_items); - RNA_def_property_ui_text(prop, "Audio Codec", "FFMpeg audio codec to use"); - RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - - prop= RNA_def_property(srna, "ffmpeg_audio_bitrate", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "ffcodecdata.audio_bitrate"); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_range(prop, 32, 384); - RNA_def_property_ui_text(prop, "Bitrate", "Audio bitrate (kb/s)"); - RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - - prop= RNA_def_property(srna, "ffmpeg_audio_volume", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "ffcodecdata.audio_volume"); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Volume", "Audio volume"); - RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); -#endif - - // the following two "ffmpeg" settings are general audio settings - prop= RNA_def_property(srna, "ffmpeg_audio_mixrate", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "ffcodecdata.audio_mixrate"); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_range(prop, 8000, 192000); - RNA_def_property_ui_text(prop, "Samplerate", "Audio samplerate(samples/s)"); - RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - prop= RNA_def_property(srna, "ffmpeg_audio_channels", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "ffcodecdata.audio_channels"); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_enum_items(prop, audio_channel_items); - RNA_def_property_ui_text(prop, "Audio Channels", "Audio channel count"); + prop= RNA_def_property(srna, "ffmpeg", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "FFmpegSettings"); + RNA_def_property_pointer_sdna(prop, NULL, "ffcodecdata"); + RNA_def_property_flag(prop, PROP_NEVER_UNLINK); + RNA_def_property_ui_text(prop, "FFmpeg Settings", "FFmpeg related settings for the scene"); prop= RNA_def_property(srna, "fps", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "frs_sec"); @@ -3134,12 +3427,14 @@ prop= RNA_def_property(srna, "use_motion_blur", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", R_MBLUR); RNA_def_property_ui_text(prop, "Motion Blur", "Use multi-sampled 3D scene motion blur"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); prop= RNA_def_property(srna, "motion_blur_samples", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "mblur_samples"); RNA_def_property_range(prop, 1, 32); RNA_def_property_ui_text(prop, "Motion Samples", "Number of scene samples to take with motion blur"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); prop= RNA_def_property(srna, "motion_blur_shutter", PROP_FLOAT, PROP_NONE); @@ -3152,6 +3447,7 @@ /* border */ prop= RNA_def_property(srna, "use_border", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", R_BORDER); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Border", "Render a user-defined border region, within the frame size " "(note that this disables save_buffers and full_sample)"); @@ -3183,6 +3479,7 @@ prop= RNA_def_property(srna, "use_crop_to_border", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", R_CROP); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Crop to Border", "Crop the rendered frame to the defined border size"); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); @@ -3214,7 +3511,11 @@ RNA_def_property_boolean_sdna(prop, NULL, "color_mgt_flag", R_COLOR_MANAGEMENT); RNA_def_property_ui_text(prop, "Color Management", "Use linear workflow - gamma corrected imaging pipeline"); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_RenderSettings_color_management_update"); - + + prop= RNA_def_property(srna, "use_color_unpremultiply", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "color_mgt_flag", R_COLOR_MANAGEMENT_PREDIVIDE); + RNA_def_property_ui_text(prop, "Color Unpremultipy", "For premultiplied alpha render output, do color space conversion on colors without alpha, to avoid fringing on light backgrounds"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); prop= RNA_def_property(srna, "use_file_extension", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "scemode", R_EXTENSION); @@ -3422,14 +3723,14 @@ RNA_def_property_float_sdna(prop, NULL, "fg_stamp"); RNA_def_property_array(prop, 4); RNA_def_property_range(prop,0.0,1.0); - RNA_def_property_ui_text(prop, "Stamp Text Color", "Color to use for stamp text"); + RNA_def_property_ui_text(prop, "Text Color", "Color to use for stamp text"); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); prop= RNA_def_property(srna, "stamp_background", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "bg_stamp"); RNA_def_property_array(prop, 4); RNA_def_property_range(prop,0.0,1.0); - RNA_def_property_ui_text(prop, "Stamp Background", "Color to use behind stamp text"); + RNA_def_property_ui_text(prop, "Background", "Color to use behind stamp text"); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); /* sequencer draw options */ @@ -3520,7 +3821,7 @@ prop= RNA_def_property(srna, "use_simplify_triangulate", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "simplify_flag", R_SIMPLE_NO_TRIANGULATE); - RNA_def_property_ui_text(prop, "Skip Quad to Triangles", "Disables non-planer quads being triangulated"); + RNA_def_property_ui_text(prop, "Skip Quad to Triangles", "Disable non-planar quads being triangulated"); /* Scene API */ RNA_api_scene_render(srna); @@ -3686,6 +3987,28 @@ RNA_def_property_update(prop, NC_SCENE|ND_KEYINGSET, NULL); } +/* Runtime property, used to remember uv indices, used only in UV stitch for now. + */ +static void rna_def_selected_uv_element(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna= RNA_def_struct(brna, "SelectedUvElement", "PropertyGroup"); + RNA_def_struct_ui_text(srna, "Selected UV Element", ""); + + /* store the index to the UV element selected */ + prop= RNA_def_property(srna, "element_index", PROP_INT, PROP_UNSIGNED); + RNA_def_property_flag(prop, PROP_IDPROPERTY); + RNA_def_property_ui_text(prop, "Element Index", ""); + + prop= RNA_def_property(srna, "face_index", PROP_INT, PROP_UNSIGNED); + RNA_def_property_flag(prop, PROP_IDPROPERTY); + RNA_def_property_ui_text(prop, "Face Index", ""); +} + + + void RNA_def_scene(BlenderRNA *brna) { StructRNA *srna; @@ -3733,7 +4056,7 @@ prop= RNA_def_property(srna, "world", PROP_POINTER, PROP_NONE); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "World", "World used for rendering the scene"); - RNA_def_property_update(prop, NC_SCENE|ND_WORLD, NULL); + RNA_def_property_update(prop, NC_SCENE|ND_WORLD, "rna_Scene_glsl_update"); prop= RNA_def_property(srna, "cursor_location", PROP_FLOAT, PROP_XYZ_LENGTH); RNA_def_property_float_sdna(prop, NULL, "cursor"); @@ -4012,12 +4335,14 @@ /* Nestled Data */ rna_def_tool_settings(brna); + rna_def_unified_paint_settings(brna); rna_def_unit_settings(brna); rna_def_scene_image_format_data(brna); rna_def_scene_render_data(brna); rna_def_scene_game_data(brna); rna_def_scene_render_layer(brna); rna_def_transform_orientation(brna); + rna_def_selected_uv_element(brna); /* Scene API */ RNA_api_scene(srna); diff -Nru blender-2.61/source/blender/makesrna/intern/rna_screen.c blender-2.62/source/blender/makesrna/intern/rna_screen.c --- blender-2.61/source/blender/makesrna/intern/rna_screen.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_screen.c 2012-02-15 19:35:15.000000000 +0000 @@ -54,6 +54,7 @@ #ifdef RNA_RUNTIME +#include "BKE_global.h" static void rna_Screen_scene_set(PointerRNA *ptr, PointerRNA value) { @@ -62,7 +63,6 @@ if(value.data == NULL) return; - /* exception: can't set screens inside of area/region handers */ sc->newscene= value.data; } @@ -70,10 +70,14 @@ { bScreen *sc= (bScreen*)ptr->data; - /* exception: can't set screens inside of area/region handers, and must - use context so notifier gets to the right window */ + /* exception: must use context so notifier gets to the right window */ if(sc->newscene) { + ED_screen_set_scene(C, sc->newscene); WM_event_add_notifier(C, NC_SCENE|ND_SCENEBROWSE, sc->newscene); + + if(G.f & G_DEBUG) + printf("scene set %p\n", sc->newscene); + sc->newscene= NULL; } } diff -Nru blender-2.61/source/blender/makesrna/intern/rna_sculpt_paint.c blender-2.62/source/blender/makesrna/intern/rna_sculpt_paint.c --- blender-2.61/source/blender/makesrna/intern/rna_sculpt_paint.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_sculpt_paint.c 2012-02-15 19:35:15.000000000 +0000 @@ -289,6 +289,17 @@ RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Sculpt_update"); } + +static void rna_def_uv_sculpt(BlenderRNA *brna) +{ + StructRNA *srna; + + srna= RNA_def_struct(brna, "UvSculpt", "Paint"); + RNA_def_struct_ui_text(srna, "UV Sculpting", ""); +} + + +/* use for weight paint too */ static void rna_def_vertex_paint(BlenderRNA *brna) { StructRNA *srna; @@ -297,7 +308,8 @@ srna= RNA_def_struct(brna, "VertexPaint", "Paint"); RNA_def_struct_sdna(srna, "VPaint"); RNA_def_struct_ui_text(srna, "Vertex Paint", "Properties of vertex and weight paint mode"); - + + /* vertex paint only */ prop= RNA_def_property(srna, "use_all_faces", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", VP_AREA); RNA_def_property_ui_text(prop, "All Faces", "Paint on all faces inside brush"); @@ -309,6 +321,11 @@ prop= RNA_def_property(srna, "use_spray", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", VP_SPRAY); RNA_def_property_ui_text(prop, "Spray", "Keep applying paint effect while holding mouse"); + + /* weight paint only */ + prop= RNA_def_property(srna, "use_group_restrict", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", VP_ONLYVGROUP); + RNA_def_property_ui_text(prop, "Restrict", "Restrict painting to verts already apart of the vertex group"); } static void rna_def_image_paint(BlenderRNA *brna) @@ -459,12 +476,12 @@ RNA_def_property_ui_text(prop, "Brush", ""); prop= RNA_def_property(srna, "draw_step", PROP_INT, PROP_NONE); - RNA_def_property_range(prop, 2, 10); + RNA_def_property_range(prop, 1, 10); RNA_def_property_ui_text(prop, "Steps", "How many steps to draw the path with"); RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_ParticleEdit_redo"); prop= RNA_def_property(srna, "fade_frames", PROP_INT, PROP_NONE); - RNA_def_property_range(prop, 2, 100); + RNA_def_property_range(prop, 1, 100); RNA_def_property_ui_text(prop, "Frames", "How many frames to fade"); RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_ParticleEdit_update"); @@ -541,6 +558,7 @@ { rna_def_paint(brna); rna_def_sculpt(brna); + rna_def_uv_sculpt(brna); rna_def_vertex_paint(brna); rna_def_image_paint(brna); rna_def_particle_edit(brna); diff -Nru blender-2.61/source/blender/makesrna/intern/rna_sensor.c blender-2.62/source/blender/makesrna/intern/rna_sensor.c --- blender-2.61/source/blender/makesrna/intern/rna_sensor.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_sensor.c 2012-02-15 19:35:15.000000000 +0000 @@ -61,6 +61,7 @@ #ifdef RNA_RUNTIME #include "BKE_sca.h" +#include "DNA_controller_types.h" static StructRNA* rna_Sensor_refine(struct PointerRNA *ptr) { @@ -125,6 +126,19 @@ } /* Always keep in alphabetical order */ + +static void rna_Sensor_controllers_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +{ + bSensor *sens = (bSensor *)ptr->data; + rna_iterator_array_begin(iter, sens->links, sizeof(bController *), (int)sens->totlinks, 0, NULL); +} + +static int rna_Sensor_controllers_length(PointerRNA *ptr) +{ + bSensor *sens = (bSensor *)ptr->data; + return (int) sens->totlinks; +} + EnumPropertyItem *rna_Sensor_type_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *free) { EnumPropertyItem *item= NULL; @@ -327,6 +341,13 @@ RNA_def_property_ui_text(prop, "Tap", "Trigger controllers only for an instant, even while the sensor remains true"); RNA_def_property_update(prop, NC_LOGIC, NULL); + prop= RNA_def_property(srna, "controllers", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "links", NULL); + RNA_def_property_struct_type(prop, "Controller"); + RNA_def_property_ui_text(prop, "Controllers", "The list containing the controllers connected to the sensor"); + RNA_def_property_collection_funcs(prop, "rna_Sensor_controllers_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_dereference_get", "rna_Sensor_controllers_length", NULL, NULL, NULL); + + RNA_api_sensor(srna); } diff -Nru blender-2.61/source/blender/makesrna/intern/rna_sequencer.c blender-2.62/source/blender/makesrna/intern/rna_sequencer.c --- blender-2.61/source/blender/makesrna/intern/rna_sequencer.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_sequencer.c 2012-02-15 19:35:15.000000000 +0000 @@ -822,6 +822,9 @@ {SEQ_PROXY_TC_INTERP_REC_DATE_FREE_RUN, "FREE_RUN_REC_DATE", 0, "Free Run (rec date)", "Interpolate a global timestamp using the " "record date and time written by recording device"}, + {SEQ_PROXY_TC_RECORD_RUN_NO_GAPS, "FREE_RUN_NO_GAPS", 0, "Free Run No Gaps", + "Record run, but ignore timecode, " + "changes in framerate or dropouts"}, {0, NULL, 0, NULL, NULL}}; srna = RNA_def_struct(brna, "SequenceProxy", NULL); diff -Nru blender-2.61/source/blender/makesrna/intern/rna_space.c blender-2.62/source/blender/makesrna/intern/rna_space.c --- blender-2.61/source/blender/makesrna/intern/rna_space.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_space.c 2012-02-15 19:35:15.000000000 +0000 @@ -35,6 +35,7 @@ #include "rna_internal.h" #include "BKE_key.h" +#include "BKE_movieclip.h" #include "DNA_action_types.h" #include "DNA_key_types.h" @@ -1975,6 +1976,11 @@ RNA_def_property_ui_text(prop, "Use Grease Pencil", "Display and edit the grease pencil freehand annotations overlay"); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_SEQUENCER, NULL); + prop= RNA_def_property(srna, "show_seconds", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SEQ_DRAWFRAMES); + RNA_def_property_ui_text(prop, "Show Seconds", "Show timing in seconds not frames"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_SEQUENCER, NULL); + /* grease pencil */ prop= RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "gpd"); @@ -2000,23 +2006,6 @@ RNA_def_property_enum_items(prop, proxy_render_size_items); RNA_def_property_ui_text(prop, "Proxy render size", "Draw preview using full resolution or different proxy resolutions"); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_SEQUENCER, NULL); - - - /* not sure we need rna access to these but adding anyway */ - prop= RNA_def_property(srna, "offset_x", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "xof"); - RNA_def_property_ui_text(prop, "X Offset", "Offset image horizontally from the view center"); - RNA_def_property_update(prop, NC_SPACE|ND_SPACE_SEQUENCER, NULL); - - prop= RNA_def_property(srna, "offset_y", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "yof"); - RNA_def_property_ui_text(prop, "Y Offset", "Offset image vertically from the view center"); - RNA_def_property_update(prop, NC_SPACE|ND_SPACE_SEQUENCER, NULL); - - prop= RNA_def_property(srna, "zoom", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "zoom"); - RNA_def_property_ui_text(prop, "Zoom", "Display zoom level"); - RNA_def_property_update(prop, NC_SPACE|ND_SPACE_SEQUENCER, NULL); } static void rna_def_space_text(BlenderRNA *brna) @@ -2156,7 +2145,6 @@ /* display */ prop= RNA_def_property(srna, "show_seconds", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SACTION_DRAWTIME); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); // XXX for now, only set with operator RNA_def_property_ui_text(prop, "Show Seconds", "Show timing in seconds not frames"); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_DOPESHEET, NULL); @@ -2241,7 +2229,6 @@ /* display */ prop= RNA_def_property(srna, "show_seconds", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SIPO_DRAWTIME); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); // XXX for now, only set with operator RNA_def_property_ui_text(prop, "Show Seconds", "Show timing in seconds not frames"); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_GRAPH, NULL); @@ -2339,7 +2326,6 @@ /* display */ prop= RNA_def_property(srna, "show_seconds", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SNLA_DRAWTIME); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); // XXX for now, only set with operator RNA_def_property_ui_text(prop, "Show Seconds", "Show timing in seconds not frames"); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_NLA, NULL); @@ -2394,6 +2380,11 @@ RNA_def_property_ui_text(prop, "Show Frame Number Indicator", "Show frame number beside the current frame indicator line"); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TIME, NULL); + prop= RNA_def_property(srna, "show_seconds", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", TIME_DRAWFRAMES); + RNA_def_property_ui_text(prop, "Show Seconds", "Show timing in seconds not frames"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TIME, NULL); + /* displaying cache status */ prop= RNA_def_property(srna, "show_cache", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "cache_display", TIME_CACHE_DISPLAY); @@ -2902,18 +2893,18 @@ RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_MARKER_SEARCH); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL); - /* show pyramid */ - prop= RNA_def_property(srna, "show_pyramid_levels", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_ui_text(prop, "Show Pyramid ", "Show patterns for each pyramid level for markers (KLT only)"); - RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_PYRAMID_LEVELS); - RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL); - /* lock to selection */ prop= RNA_def_property(srna, "lock_selection", PROP_BOOLEAN, PROP_NONE); RNA_def_property_ui_text(prop, "Lock to Selection", "Lock viewport to selected markers during playback"); RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_LOCK_SELECTION); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, "rna_SpaceClipEditor_lock_selection_update"); + /* lock to time cursor */ + prop= RNA_def_property(srna, "lock_time_cursor", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_ui_text(prop, "Lock to Time Cursor", "Lock curves view to time cursor during playback and tracking"); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_LOCK_TIMECURSOR); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL); + /* show markers pathes */ prop= RNA_def_property(srna, "show_track_path", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_TRACK_PATH); @@ -2981,12 +2972,6 @@ RNA_def_property_ui_text(prop, "Manual Calibration", "Use manual calibration helpers"); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL); - /* show stable */ - prop= RNA_def_property(srna, "show_grease_pencil", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_GPENCIL); - RNA_def_property_ui_text(prop, "Show Grease Pencil", "Show grease pencil strokes over the footage"); - RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL); - /* show filters */ prop= RNA_def_property(srna, "show_filters", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_FILTERS); @@ -3004,6 +2989,32 @@ RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_GRAPH_TRACKS); RNA_def_property_ui_text(prop, "Show Tracks", "Display the speed curves (in \"x\" direction red, in \"y\" direction green) for the selected tracks"); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL); + + /* ** channels ** */ + + /* show_red_channel */ + prop= RNA_def_property(srna, "show_red_channel", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "postproc_flag", MOVIECLIP_DISABLE_RED); + RNA_def_property_ui_text(prop, "Show Red Channel", "Show red channel in the frame"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL); + + /* show_green_channel */ + prop= RNA_def_property(srna, "show_green_channel", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "postproc_flag", MOVIECLIP_DISABLE_GREEN); + RNA_def_property_ui_text(prop, "Show Green Channel", "Show green channel in the frame"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL); + + /* show_blue_channel */ + prop= RNA_def_property(srna, "show_blue_channel", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "postproc_flag", MOVIECLIP_DISABLE_BLUE); + RNA_def_property_ui_text(prop, "Show Blue Channel", "Show blue channel in the frame"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL); + + /* preview_grayscale */ + prop= RNA_def_property(srna, "use_grayscale_preview", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "postproc_flag", MOVIECLIP_PREVIEW_GRAYSCALE); + RNA_def_property_ui_text(prop, "Grayscale", "Display frame in grayscale mode"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); } diff -Nru blender-2.61/source/blender/makesrna/intern/rna_tracking.c blender-2.62/source/blender/makesrna/intern/rna_tracking.c --- blender-2.61/source/blender/makesrna/intern/rna_tracking.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_tracking.c 2012-02-15 19:35:15.000000000 +0000 @@ -31,6 +31,7 @@ #include "MEM_guardedalloc.h" +#include "BLI_math.h" #include "BKE_movieclip.h" #include "BKE_tracking.h" @@ -87,46 +88,90 @@ settings->default_pattern_size= settings->default_search_size; } -static void rna_tracking_tracks_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +static void rna_trackingTracks_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { MovieClip *clip= (MovieClip*)ptr->id.data; + rna_iterator_listbase_begin(iter, &clip->tracking.tracks, NULL); } -static void rna_tracking_tracks_add(MovieTracking *tracking, int frame, int number) +static void rna_trackingObjects_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { - int a; + MovieClip *clip= (MovieClip*)ptr->id.data; - for(a= 0; atracking.objects, NULL); +} - WM_main_add_notifier(NC_MOVIECLIP|NA_EDITED, NULL); +static int rna_tracking_active_object_index_get(PointerRNA *ptr) +{ + MovieClip *clip= (MovieClip*)ptr->id.data; + + return clip->tracking.objectnr; +} + +static void rna_tracking_active_object_index_set(PointerRNA *ptr, int value) +{ + MovieClip *clip= (MovieClip*)ptr->id.data; + + clip->tracking.objectnr= value; +} + +static void rna_tracking_active_object_index_range(PointerRNA *ptr, int *min, int *max) +{ + MovieClip *clip= (MovieClip*)ptr->id.data; + + *min= 0; + *max= clip->tracking.tot_object-1; + *max= MAX2(0, *max); } static PointerRNA rna_tracking_active_track_get(PointerRNA *ptr) { MovieClip *clip= (MovieClip*)ptr->id.data; + MovieTrackingTrack *act_track= BKE_tracking_active_track(&clip->tracking); - return rna_pointer_inherit_refine(ptr, &RNA_MovieTrackingTrack, clip->tracking.act_track); + return rna_pointer_inherit_refine(ptr, &RNA_MovieTrackingTrack, act_track); } static void rna_tracking_active_track_set(PointerRNA *ptr, PointerRNA value) { MovieClip *clip= (MovieClip*)ptr->id.data; MovieTrackingTrack *track= (MovieTrackingTrack *)value.data; - int index= BLI_findindex(&clip->tracking.tracks, track); + ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking); + int index= BLI_findindex(tracksbase, track); - if(index>=0) clip->tracking.act_track= track; - else clip->tracking.act_track= NULL; + if(index>=0) + clip->tracking.act_track= track; + else + clip->tracking.act_track= NULL; } void rna_trackingTrack_name_set(PointerRNA *ptr, const char *value) { MovieClip *clip= (MovieClip *)ptr->id.data; + MovieTracking *tracking= &clip->tracking; MovieTrackingTrack *track= (MovieTrackingTrack *)ptr->data; + ListBase *tracksbase= &tracking->tracks; + BLI_strncpy(track->name, value, sizeof(track->name)); - BKE_track_unique_name(&clip->tracking, track); + /* TODO: it's a bit difficult to find list track came from knowing just + movie clip ID and MovieTracking structure, so keep this naive + search for a while */ + if(BLI_findindex(tracksbase, track) < 0) { + MovieTrackingObject *object= tracking->objects.first; + + while(object) { + if(BLI_findindex(&object->tracks, track)) { + tracksbase= &object->tracks; + break; + } + + object= object->next; + } + } + + BKE_track_unique_name(tracksbase, track); } static int rna_trackingTrack_select_get(PointerRNA *ptr) @@ -257,11 +302,162 @@ DAG_id_tag_update(&clip->id, 0); } +static void rna_trackingObject_tracks_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +{ + MovieTrackingObject *object= (MovieTrackingObject* )ptr->data; + + if(object->flag&TRACKING_OBJECT_CAMERA) { + MovieClip *clip= (MovieClip*)ptr->id.data; + + rna_iterator_listbase_begin(iter, &clip->tracking.tracks, NULL); + } + else { + rna_iterator_listbase_begin(iter, &object->tracks, NULL); + } +} + +static PointerRNA rna_tracking_active_object_get(PointerRNA *ptr) +{ + MovieClip *clip= (MovieClip*)ptr->id.data; + MovieTrackingObject *object= BLI_findlink(&clip->tracking.objects, clip->tracking.objectnr); + + return rna_pointer_inherit_refine(ptr, &RNA_MovieTrackingObject, object); +} + +static void rna_tracking_active_object_set(PointerRNA *ptr, PointerRNA value) +{ + MovieClip *clip= (MovieClip*)ptr->id.data; + MovieTrackingObject *object= (MovieTrackingObject *)value.data; + int index= BLI_findindex(&clip->tracking.objects, object); + + if(index>=0) clip->tracking.objectnr= index; + else clip->tracking.objectnr= 0; +} + +void rna_trackingObject_name_set(PointerRNA *ptr, const char *value) +{ + MovieClip *clip= (MovieClip *)ptr->id.data; + MovieTrackingObject *object= (MovieTrackingObject *)ptr->data; + + BLI_strncpy(object->name, value, sizeof(object->name)); + + BKE_tracking_object_unique_name(&clip->tracking, object); +} + +static void rna_trackingObject_flushUpdate(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr) +{ + MovieClip *clip= (MovieClip*)ptr->id.data; + + WM_main_add_notifier(NC_OBJECT|ND_TRANSFORM, NULL); + DAG_id_tag_update(&clip->id, 0); +} + +static void rna_trackingMarker_frame_set(PointerRNA *ptr, int value) +{ + MovieClip *clip = (MovieClip *) ptr->id.data; + MovieTracking *tracking = &clip->tracking; + MovieTrackingTrack *track; + MovieTrackingMarker *marker = (MovieTrackingMarker *) ptr->data; + + track = tracking->tracks.first; + while (track) { + if (marker >= track->markers && marker < track->markers+track->markersnr) { + break; + } + + track = track->next; + } + + if (track) { + MovieTrackingMarker new_marker = *marker; + new_marker.framenr = value; + + BKE_tracking_delete_marker(track, marker->framenr); + BKE_tracking_insert_marker(track, &new_marker); + } +} + /* API */ -static MovieTrackingMarker *rna_trackingTrack_marker_find_frame(MovieTrackingTrack *track, int framenr) +static void add_tracks_to_base(MovieClip *clip, MovieTracking *tracking, ListBase *tracksbase, int frame, int number) +{ + int a, width, height; + MovieClipUser user= {0}; + + user.framenr= 1; + + BKE_movieclip_get_size(clip, &user, &width, &height); + + for(a= 0; atracks, frame, number); + + WM_main_add_notifier(NC_MOVIECLIP|NA_EDITED, clip); +} + +static void rna_trackingObject_tracks_add(ID *id, MovieTrackingObject *object, int frame, int number) +{ + MovieClip *clip= (MovieClip *) id; + ListBase *tracksbase= &object->tracks; + + if(object->flag&TRACKING_OBJECT_CAMERA) + tracksbase= &clip->tracking.tracks; + + add_tracks_to_base(clip, &clip->tracking, tracksbase, frame, number); + + WM_main_add_notifier(NC_MOVIECLIP|NA_EDITED, NULL); +} + +static MovieTrackingObject *rna_trackingObject_new(MovieTracking *tracking, const char *name) +{ + MovieTrackingObject *object= BKE_tracking_new_object(tracking, name); + + WM_main_add_notifier(NC_MOVIECLIP|NA_EDITED, NULL); + + return object; +} + +void rna_trackingObject_remove(MovieTracking *tracking, MovieTrackingObject *object) { - return BKE_tracking_get_marker(track, framenr); + BKE_tracking_remove_object(tracking, object); + + WM_main_add_notifier(NC_MOVIECLIP|NA_EDITED, NULL); +} + +static MovieTrackingMarker *rna_trackingMarkers_find_frame(MovieTrackingTrack *track, int framenr) +{ + return BKE_tracking_exact_marker(track, framenr); +} + +static MovieTrackingMarker* rna_trackingMarkers_insert_frame(MovieTrackingTrack *track, int framenr, float *co) +{ + MovieTrackingMarker marker, *new_marker; + + memset(&marker, 0, sizeof(marker)); + marker.framenr = framenr; + copy_v2_v2(marker.pos, co); + + new_marker = BKE_tracking_insert_marker(track, &marker); + + WM_main_add_notifier(NC_MOVIECLIP|NA_EDITED, NULL); + + return new_marker; +} + +void rna_trackingMarkers_delete_frame(MovieTrackingTrack *track, int framenr) +{ + if(track->markersnr==1) + return; + + BKE_tracking_delete_marker(track, framenr); + + WM_main_add_notifier(NC_MOVIECLIP|NA_EDITED, NULL); } #else @@ -350,6 +546,7 @@ prop= RNA_def_property(srna, "distance", PROP_FLOAT, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_float_sdna(prop, NULL, "dist"); + RNA_def_property_float_default(prop, 1.0f); RNA_def_property_ui_text(prop, "Distance", "Distance between two bundles used for scene scaling"); /* frames count */ @@ -442,6 +639,35 @@ RNA_def_property_range(prop, 5, 1000); RNA_def_property_update(prop, 0, "rna_tracking_defaultSettings_searchUpdate"); RNA_def_property_ui_text(prop, "Search Size", "Size of search area for newly created tracks"); + + /* use_red_channel */ + prop= RNA_def_property(srna, "use_default_red_channel", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "default_flag", TRACK_DISABLE_RED); + RNA_def_property_ui_text(prop, "Use Red Channel", "Use red channel from footage for tracking"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + + /* use_green_channel */ + prop= RNA_def_property(srna, "use_default_green_channel", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "default_flag", TRACK_DISABLE_GREEN); + RNA_def_property_ui_text(prop, "Use Green Channel", "Use green channel from footage for tracking"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + + /* use_blue_channel */ + prop= RNA_def_property(srna, "use_default_blue_channel", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "default_flag", TRACK_DISABLE_BLUE); + RNA_def_property_ui_text(prop, "Use Blue Channel", "Use blue channel from footage for tracking"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + + /* ** object tracking ** */ + + /* object distance */ + prop= RNA_def_property(srna, "object_distance", PROP_FLOAT, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_float_sdna(prop, NULL, "object_distance"); + RNA_def_property_ui_text(prop, "Distance", "Distance between two bundles used for object scaling"); + RNA_def_property_range(prop, 0.001, 10000); + RNA_def_property_float_default(prop, 1.0f); + RNA_def_property_ui_range(prop, 0.001, 10000.0, 1, 3); } static void rna_def_trackingCamera(BlenderRNA *brna) @@ -539,10 +765,10 @@ /* frame */ prop= RNA_def_property(srna, "frame", PROP_INT, PROP_NONE); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* can't be safty edited for now, need to re-sort markers array after change */ RNA_def_property_int_sdna(prop, NULL, "framenr"); RNA_def_property_ui_text(prop, "Frame", "Frame number marker is keyframed on"); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL); + RNA_def_property_int_funcs(prop, NULL, "rna_trackingMarker_frame_set", NULL); + RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, 0); /* enable */ prop= RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE); @@ -551,14 +777,48 @@ RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL); } -static void rna_def_trackingTrack(BlenderRNA *brna) +static void rna_def_trackingMarkers(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; - PropertyRNA *prop; - FunctionRNA *func; PropertyRNA *parm; + RNA_def_property_srna(cprop, "MovieTrackingMarkers"); + srna= RNA_def_struct(brna, "MovieTrackingMarkers", NULL); + RNA_def_struct_sdna(srna, "MovieTrackingTrack"); + RNA_def_struct_ui_text(srna, "Movie Tracking Markers", "Collection of markers for movie tracking track"); + + func= RNA_def_function(srna, "find_frame", "rna_trackingMarkers_find_frame"); + RNA_def_function_ui_description(func, "Get marker for specified frame"); + parm= RNA_def_int(func, "frame", 1, MINFRAME, MAXFRAME, "Frame", + "Frame number to find marker for", MINFRAME, MAXFRAME); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_pointer(func, "marker", "MovieTrackingMarker", "", "Marker for specified frame"); + RNA_def_function_return(func, parm); + + func= RNA_def_function(srna, "insert_frame", "rna_trackingMarkers_insert_frame"); + RNA_def_function_ui_description(func, "Add a number of tracks to this movie clip"); + parm= RNA_def_int(func, "frame", 1, MINFRAME, MAXFRAME, "Frame", + "Frame number to insert marker to", MINFRAME, MAXFRAME); + RNA_def_property_flag(parm, PROP_REQUIRED); + RNA_def_float_vector(func, "co", 2, 0, -1.0, 1.0, "Coordinate", + "Place new marker at the given frame using specified in normalized space coordinates", -1.0, 1.0); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_pointer(func, "marker", "MovieTrackingMarker", "", "Newly created marker"); + RNA_def_function_return(func, parm); + + func= RNA_def_function(srna, "delete_frame", "rna_trackingMarkers_delete_frame"); + RNA_def_function_ui_description(func, "Delete marker at specified frame"); + parm= RNA_def_int(func, "frame", 1, MINFRAME, MAXFRAME, "Frame", + "Frame number to delete marker from", MINFRAME, MAXFRAME); + RNA_def_property_flag(parm, PROP_REQUIRED); +} + +static void rna_def_trackingTrack(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + rna_def_trackingMarker(brna); srna= RNA_def_struct(brna, "MovieTrackingTrack", NULL); @@ -569,7 +829,7 @@ prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_property_ui_text(prop, "Name", "Unique name of track"); RNA_def_property_string_funcs(prop, NULL, NULL, "rna_trackingTrack_name_set"); - RNA_def_property_string_maxlength(prop, MAX_ID_NAME); + RNA_def_property_string_maxlength(prop, MAX_ID_NAME-2); RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL); RNA_def_struct_name_property(srna, prop); @@ -652,6 +912,7 @@ RNA_def_property_struct_type(prop, "MovieTrackingMarker"); RNA_def_property_collection_sdna(prop, NULL, "markers", "markersnr"); RNA_def_property_ui_text(prop, "Markers", "Collection of markers in track"); + rna_def_trackingMarkers(brna, prop); /* ** channels ** */ @@ -673,6 +934,12 @@ RNA_def_property_ui_text(prop, "Use Blue Channel", "Use blue channel from footage for tracking"); RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + /* preview_grayscale */ + prop= RNA_def_property(srna, "use_grayscale_preview", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACK_PREVIEW_GRAYSCALE); + RNA_def_property_ui_text(prop, "Grayscale", "Display what the tracking algorithm sees in the preview"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + /* has bundle */ prop= RNA_def_property(srna, "has_bundle", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACK_HAS_BUNDLE); @@ -740,15 +1007,6 @@ RNA_def_property_float_sdna(prop, NULL, "error"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Average Error", "Average error of re-projection"); - - /* ** api ** */ - - func= RNA_def_function(srna, "marker_find_frame", "rna_trackingTrack_marker_find_frame"); - RNA_def_function_ui_description(func, "Get marker for specified frame"); - parm= RNA_def_int(func, "frame", 1, MINFRAME, MAXFRAME, "Frame", "type for the new spline", MINFRAME, MAXFRAME); - RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_pointer(func, "marker", "MovieTrackingMarker", "", "Marker for specified frame"); - RNA_def_function_return(func, parm); } static void rna_def_trackingStabilization(BlenderRNA *brna) @@ -883,18 +1141,18 @@ RNA_def_property_ui_text(prop, "Cameras", "Collection of solved cameras"); } -static void rna_def_trackingTracks(BlenderRNA *brna, PropertyRNA *cprop) +static void rna_def_trackingTracks(BlenderRNA *brna) { StructRNA *srna; FunctionRNA *func; PropertyRNA *prop; - RNA_def_property_srna(cprop, "MovieTrackingTracks"); srna= RNA_def_struct(brna, "MovieTrackingTracks", NULL); RNA_def_struct_sdna(srna, "MovieTracking"); RNA_def_struct_ui_text(srna, "Movie Tracks", "Collection of movie tracking tracks"); - func= RNA_def_function(srna, "add", "rna_tracking_tracks_add"); + func= RNA_def_function(srna, "add", "rna_trackingTracks_add"); + RNA_def_function_flag(func, FUNC_USE_SELF_ID); RNA_def_function_ui_description(func, "Add a number of tracks to this movie clip"); RNA_def_int(func, "frame", 1, MINFRAME, MAXFRAME, "Frame", "Frame number to add tracks on", MINFRAME, MAXFRAME); RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of tracks to add to the movie clip", 0, INT_MAX); @@ -907,6 +1165,106 @@ RNA_def_property_ui_text(prop, "Active Track", "Active track in this tracking data object"); } +static void rna_def_trackingObjectTracks(BlenderRNA *brna) +{ + StructRNA *srna; + FunctionRNA *func; + PropertyRNA *prop; + + srna= RNA_def_struct(brna, "MovieTrackingObjectTracks", NULL); + RNA_def_struct_sdna(srna, "MovieTrackingObject"); + RNA_def_struct_ui_text(srna, "Movie Tracks", "Collection of movie tracking tracks"); + + func= RNA_def_function(srna, "add", "rna_trackingObject_tracks_add"); + RNA_def_function_flag(func, FUNC_USE_SELF_ID); + RNA_def_function_ui_description(func, "Add a number of tracks to this movie clip"); + RNA_def_int(func, "frame", 1, MINFRAME, MAXFRAME, "Frame", "Frame number to add tracks on", MINFRAME, MAXFRAME); + RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of tracks to add to the movie clip", 0, INT_MAX); + + /* active track */ + prop= RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "MovieTrackingTrack"); + RNA_def_property_pointer_funcs(prop, "rna_tracking_active_track_get", "rna_tracking_active_track_set", NULL, NULL); + RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_UNLINK); + RNA_def_property_ui_text(prop, "Active Track", "Active track in this tracking data object"); +} + +static void rna_def_trackingObject(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna= RNA_def_struct(brna, "MovieTrackingObject", NULL); + RNA_def_struct_ui_text(srna, "Movie tracking object data", "Match-moving object tracking and reconstruction data"); + + /* name */ + prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); + RNA_def_property_ui_text(prop, "Name", "Unique name of object"); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_trackingObject_name_set"); + RNA_def_property_string_maxlength(prop, MAX_ID_NAME-2); + RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL); + RNA_def_struct_name_property(srna, prop); + + /* is_camera */ + prop= RNA_def_property(srna, "is_camera", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACKING_OBJECT_CAMERA); + RNA_def_property_ui_text(prop, "Camera", "Object is used for camera tracking"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + + /* tracks */ + prop= RNA_def_property(srna, "tracks", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_funcs(prop, "rna_trackingObject_tracks_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, 0); + RNA_def_property_struct_type(prop, "MovieTrackingTrack"); + RNA_def_property_ui_text(prop, "Tracks", "Collection of tracks in this tracking data object"); + RNA_def_property_srna(prop, "MovieTrackingObjectTracks"); + + /* reconstruction */ + prop= RNA_def_property(srna, "reconstruction", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "MovieTrackingReconstruction"); + + /* scale */ + prop= RNA_def_property(srna, "scale", PROP_FLOAT, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_float_sdna(prop, NULL, "scale"); + RNA_def_property_range(prop, 0.0001f, 10000.0f); + RNA_def_property_ui_range(prop, 0.0001f, 10000.0, 1, 4); + RNA_def_property_float_default(prop, 1.0f); + RNA_def_property_ui_text(prop, "Scale", "Scale of object solution in camera space"); + RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_trackingObject_flushUpdate"); +} + +static void rna_def_trackingObjects(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + PropertyRNA *prop; + + FunctionRNA *func; + PropertyRNA *parm; + + RNA_def_property_srna(cprop, "MovieTrackingObjects"); + srna= RNA_def_struct(brna, "MovieTrackingObjects", NULL); + RNA_def_struct_sdna(srna, "MovieTracking"); + RNA_def_struct_ui_text(srna, "Movie Objects", "Collection of movie trackingobjects"); + + func= RNA_def_function(srna, "new", "rna_trackingObject_new"); + RNA_def_function_ui_description(func, "Add tracking object to this movie clip"); + RNA_def_string(func, "name", "", 0, "", "Name of new object"); + parm= RNA_def_pointer(func, "object", "MovieTrackingObject", "", "New motion tracking object"); + RNA_def_function_return(func, parm); + + func= RNA_def_function(srna, "remove", "rna_trackingObject_remove"); + RNA_def_function_ui_description(func, "Remove tracking object from this movie clip"); + RNA_def_pointer(func, "object", "MovieTrackingObject", "", "Motion tracking object to be removed"); + + /* active object */ + prop= RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "MovieTrackingObject"); + RNA_def_property_pointer_funcs(prop, "rna_tracking_active_object_get", "rna_tracking_active_object_set", NULL, NULL); + RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_UNLINK); + RNA_def_property_ui_text(prop, "Active Object", "Active object in this tracking data object"); +} + static void rna_def_tracking(BlenderRNA *brna) { StructRNA *srna; @@ -915,8 +1273,11 @@ rna_def_trackingSettings(brna); rna_def_trackingCamera(brna); rna_def_trackingTrack(brna); + rna_def_trackingTracks(brna); + rna_def_trackingObjectTracks(brna); rna_def_trackingStabilization(brna); rna_def_trackingReconstruction(brna); + rna_def_trackingObject(brna); srna= RNA_def_struct(brna, "MovieTracking", NULL); RNA_def_struct_ui_text(srna, "Movie tracking data", "Match-moving data for tracking"); @@ -931,10 +1292,10 @@ /* tracks */ prop= RNA_def_property(srna, "tracks", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_funcs(prop, "rna_tracking_tracks_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, 0); + RNA_def_property_collection_funcs(prop, "rna_trackingTracks_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, 0); RNA_def_property_struct_type(prop, "MovieTrackingTrack"); RNA_def_property_ui_text(prop, "Tracks", "Collection of tracks in this tracking data object"); - rna_def_trackingTracks(brna, prop); + RNA_def_property_srna(prop, "MovieTrackingTracks"); /* stabilization */ prop= RNA_def_property(srna, "stabilization", PROP_POINTER, PROP_NONE); @@ -943,6 +1304,20 @@ /* reconstruction */ prop= RNA_def_property(srna, "reconstruction", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "MovieTrackingReconstruction"); + + /* objects */ + prop= RNA_def_property(srna, "objects", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_funcs(prop, "rna_trackingObjects_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, 0); + RNA_def_property_struct_type(prop, "MovieTrackingObject"); + RNA_def_property_ui_text(prop, "Objects", "Collection of objects in this tracking data object"); + rna_def_trackingObjects(brna, prop); + + /* active object index */ + prop= RNA_def_property(srna, "active_object_index", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "objectnr"); + RNA_def_property_int_funcs(prop, "rna_tracking_active_object_index_get", "rna_tracking_active_object_index_set", "rna_tracking_active_object_index_range"); + RNA_def_property_ui_text(prop, "Active Object Index", "Index of active object"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); } void RNA_def_tracking(BlenderRNA *brna) diff -Nru blender-2.61/source/blender/makesrna/intern/rna_ui.c blender-2.62/source/blender/makesrna/intern/rna_ui.c --- blender-2.61/source/blender/makesrna/intern/rna_ui.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_ui.c 2012-02-15 19:35:15.000000000 +0000 @@ -823,7 +823,7 @@ "class name is \"OBJECT_MT_hello\", and bl_idname is not set by the " "script, then bl_idname = \"OBJECT_MT_hello\")"); - prop= RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE); + prop= RNA_def_property(srna, "bl_label", PROP_STRING, PROP_TRANSLATE); RNA_def_property_string_sdna(prop, NULL, "type->label"); RNA_def_property_flag(prop, PROP_REGISTER); RNA_def_property_ui_text(prop, "Label", "The menu label"); diff -Nru blender-2.61/source/blender/makesrna/intern/rna_userdef.c blender-2.62/source/blender/makesrna/intern/rna_userdef.c --- blender-2.61/source/blender/makesrna/intern/rna_userdef.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_userdef.c 2012-02-15 19:35:15.000000000 +0000 @@ -37,6 +37,7 @@ #include "DNA_userdef_types.h" #include "DNA_brush_types.h" #include "DNA_view3d_types.h" +#include "DNA_scene_types.h" #include "WM_api.h" #include "WM_types.h" @@ -46,6 +47,14 @@ #include "BKE_sound.h" +#ifdef WITH_CYCLES +static EnumPropertyItem compute_device_type_items[] = { + {USER_COMPUTE_DEVICE_NONE, "NONE", 0, "None", "Don't use compute device"}, + {USER_COMPUTE_DEVICE_CUDA, "CUDA", 0, "CUDA", "Use CUDA for GPU acceleration"}, + {USER_COMPUTE_DEVICE_OPENCL, "OPENCL", 0, "OpenCL", "Use OpenCL for GPU acceleration"}, + { 0, NULL, 0, NULL, NULL}}; +#endif + #ifdef RNA_RUNTIME #include "DNA_object_types.h" @@ -65,6 +74,8 @@ #include "UI_interface.h" +#include "CCL_api.h" + static void rna_userdef_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr)) { WM_main_add_notifier(NC_WINDOW, NULL); @@ -137,6 +148,12 @@ rna_userdef_update(bmain, scene, ptr); } +static void rna_userdef_gl_use_16bit_textures(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + GPU_free_images(); + rna_userdef_update(bmain, scene, ptr); +} + static void rna_userdef_select_mouse_set(PointerRNA *ptr,int value) { UserDef *userdef = (UserDef*)ptr->data; @@ -302,6 +319,87 @@ WM_main_add_notifier(NC_WINDOW, NULL); } +static PointerRNA rna_Theme_space_generic_get(PointerRNA *ptr) +{ + return rna_pointer_inherit_refine(ptr, &RNA_ThemeSpaceGeneric, ptr->data); +} + +static PointerRNA rna_Theme_space_list_generic_get(PointerRNA *ptr) +{ + return rna_pointer_inherit_refine(ptr, &RNA_ThemeSpaceListGeneric, ptr->data); +} + + +#ifdef WITH_CYCLES +static EnumPropertyItem *rna_userdef_compute_device_type_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free) +{ + EnumPropertyItem *item= NULL; + int totitem= 0; + + /* add supported device types */ + RNA_enum_items_add_value(&item, &totitem, compute_device_type_items, USER_COMPUTE_DEVICE_NONE); + if(CCL_compute_device_list(0)) + RNA_enum_items_add_value(&item, &totitem, compute_device_type_items, USER_COMPUTE_DEVICE_CUDA); + if(CCL_compute_device_list(1)) + RNA_enum_items_add_value(&item, &totitem, compute_device_type_items, USER_COMPUTE_DEVICE_OPENCL); + + RNA_enum_item_end(&item, &totitem); + *free = 1; + + return item; +} + +static int rna_userdef_compute_device_get(PointerRNA *UNUSED(ptr)) +{ + if(U.compute_device_type == USER_COMPUTE_DEVICE_NONE) + return 0; + + return U.compute_device_id; +} + +static EnumPropertyItem *rna_userdef_compute_device_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free) +{ + EnumPropertyItem tmp= {0, "", 0, "", ""}; + EnumPropertyItem *item= NULL; + int totitem= 0; + + if(U.compute_device_type == USER_COMPUTE_DEVICE_NONE) { + /* only add a single CPU device */ + tmp.value = 0; + tmp.name = "CPU"; + tmp.identifier = "CPU"; + RNA_enum_item_add(&item, &totitem, &tmp); + } + else { + /* get device list from cycles. it would be good to make this generic + once we have more subsystems using opencl, for now this is easiest */ + int opencl = (U.compute_device_type == USER_COMPUTE_DEVICE_OPENCL); + CCLDeviceInfo *devices = CCL_compute_device_list(opencl); + int a; + + if(devices) { + for(a = 0; devices[a].name; a++) { + tmp.value = devices[a].value; + tmp.identifier = devices[a].identifier; + tmp.name = devices[a].name; + RNA_enum_item_add(&item, &totitem, &tmp); + } + } + else { + tmp.value = 0; + tmp.name = "CPU"; + tmp.identifier = "CPU"; + RNA_enum_item_add(&item, &totitem, &tmp); + } + } + + RNA_enum_item_end(&item, &totitem); + *free = 1; + + return item; +} +#endif + #else static void rna_def_userdef_theme_ui_font_style(BlenderRNA *brna) @@ -639,10 +737,15 @@ RNA_def_property_update(prop, 0, "rna_userdef_update"); } -static void rna_def_userdef_theme_spaces_main(StructRNA *srna, int spacetype) +static void rna_def_userdef_theme_space_generic(BlenderRNA *brna) { + StructRNA *srna; PropertyRNA *prop; + srna= RNA_def_struct(brna, "ThemeSpaceGeneric", NULL); + RNA_def_struct_sdna(srna, "ThemeSpace"); + RNA_def_struct_ui_text(srna, "Theme Space Settings", ""); + /* window */ prop= RNA_def_property(srna, "back", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_array(prop, 3); @@ -653,7 +756,7 @@ RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Title", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - + prop= RNA_def_property(srna, "text", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Text", ""); @@ -674,57 +777,87 @@ RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Header Text", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - + prop= RNA_def_property(srna, "header_text_hi", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Header Text Highlight", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - + /* buttons */ // if(! ELEM(spacetype, SPACE_BUTS, SPACE_OUTLINER)) { prop= RNA_def_property(srna, "button", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Region Background", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - + prop= RNA_def_property(srna, "button_title", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Region Text Titles", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - + prop= RNA_def_property(srna, "button_text", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Region Text", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - + prop= RNA_def_property(srna, "button_text_hi", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Region Text Highlight", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); // } - - /* list/channels */ - if(ELEM5(spacetype, SPACE_IPO, SPACE_ACTION, SPACE_NLA, SPACE_NODE, SPACE_FILE)) { - prop= RNA_def_property(srna, "list", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Source List", ""); - RNA_def_property_update(prop, 0, "rna_userdef_update"); - - prop= RNA_def_property(srna, "list_title", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Source List Title", ""); - RNA_def_property_update(prop, 0, "rna_userdef_update"); - - prop= RNA_def_property(srna, "list_text", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Source List Text", ""); - RNA_def_property_update(prop, 0, "rna_userdef_update"); - - prop= RNA_def_property(srna, "list_text_hi", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Source List Text Highlight", ""); - RNA_def_property_update(prop, 0, "rna_userdef_update"); - } +} + +/* list / channels */ +static void rna_def_userdef_theme_space_list_generic(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna= RNA_def_struct(brna, "ThemeSpaceListGeneric", NULL); + RNA_def_struct_sdna(srna, "ThemeSpace"); + RNA_def_struct_ui_text(srna, "Theme Space List Settings", ""); + + prop= RNA_def_property(srna, "list", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Source List", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop= RNA_def_property(srna, "list_title", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Source List Title", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop= RNA_def_property(srna, "list_text", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Source List Text", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop= RNA_def_property(srna, "list_text_hi", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Source List Text Highlight", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); +} + +static void rna_def_userdef_theme_spaces_main(StructRNA *srna) +{ + PropertyRNA *prop; + + prop= RNA_def_property(srna, "space", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); + RNA_def_property_struct_type(prop, "ThemeSpaceGeneric"); + RNA_def_property_pointer_funcs(prop, "rna_Theme_space_generic_get", NULL, NULL, NULL); + RNA_def_property_ui_text(prop, "Theme Space", "Settings for space"); +} + +static void rna_def_userdef_theme_spaces_list_main(StructRNA *srna) +{ + PropertyRNA *prop; + + prop= RNA_def_property(srna, "space_list", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); + RNA_def_property_struct_type(prop, "ThemeSpaceListGeneric"); + RNA_def_property_pointer_funcs(prop, "rna_Theme_space_list_generic_get", NULL, NULL, NULL); + RNA_def_property_ui_text(prop, "Theme Space List", "Settings for space list"); } static void rna_def_userdef_theme_spaces_vertex(StructRNA *srna) @@ -920,7 +1053,7 @@ RNA_def_struct_clear_flag(srna, STRUCT_UNDO); RNA_def_struct_ui_text(srna, "Theme 3D View", "Theme settings for the 3D View"); - rna_def_userdef_theme_spaces_main(srna, SPACE_VIEW3D); + rna_def_userdef_theme_spaces_main(srna); prop= RNA_def_property(srna, "grid", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_array(prop, 3); @@ -1058,7 +1191,8 @@ RNA_def_struct_clear_flag(srna, STRUCT_UNDO); RNA_def_struct_ui_text(srna, "Theme Graph Editor", "Theme settings for the graph editor"); - rna_def_userdef_theme_spaces_main(srna, SPACE_IPO); + rna_def_userdef_theme_spaces_main(srna); + rna_def_userdef_theme_spaces_list_main(srna); prop= RNA_def_property(srna, "grid", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_array(prop, 3); @@ -1143,7 +1277,8 @@ RNA_def_struct_clear_flag(srna, STRUCT_UNDO); RNA_def_struct_ui_text(srna, "Theme File Browser", "Theme settings for the File Browser"); - rna_def_userdef_theme_spaces_main(srna, SPACE_FILE); + rna_def_userdef_theme_spaces_main(srna); + rna_def_userdef_theme_spaces_list_main(srna); prop= RNA_def_property(srna, "selected_file", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_float_sdna(prop, NULL, "hilite"); @@ -1185,6 +1320,7 @@ static void rna_def_userdef_theme_space_outliner(BlenderRNA *brna) { StructRNA *srna; + PropertyRNA *prop; /* space_outliner */ @@ -1193,7 +1329,17 @@ RNA_def_struct_clear_flag(srna, STRUCT_UNDO); RNA_def_struct_ui_text(srna, "Theme Outliner", "Theme settings for the Outliner"); - rna_def_userdef_theme_spaces_main(srna, SPACE_OUTLINER); + rna_def_userdef_theme_spaces_main(srna); + + prop= RNA_def_property(srna, "match", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Filter Match", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop= RNA_def_property(srna, "selected_highlight", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Selected Highlight", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_theme_space_userpref(BlenderRNA *brna) @@ -1207,7 +1353,7 @@ RNA_def_struct_clear_flag(srna, STRUCT_UNDO); RNA_def_struct_ui_text(srna, "Theme User Preferences", "Theme settings for the User Preferences"); - rna_def_userdef_theme_spaces_main(srna, SPACE_USERPREF); + rna_def_userdef_theme_spaces_main(srna); } static void rna_def_userdef_theme_space_console(BlenderRNA *brna) @@ -1222,7 +1368,7 @@ RNA_def_struct_clear_flag(srna, STRUCT_UNDO); RNA_def_struct_ui_text(srna, "Theme Console", "Theme settings for the Console"); - rna_def_userdef_theme_spaces_main(srna, SPACE_CONSOLE); + rna_def_userdef_theme_spaces_main(srna); prop= RNA_def_property(srna, "line_output", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_float_sdna(prop, NULL, "console_output"); @@ -1266,7 +1412,7 @@ RNA_def_struct_clear_flag(srna, STRUCT_UNDO); RNA_def_struct_ui_text(srna, "Theme Info", "Theme settings for Info"); - rna_def_userdef_theme_spaces_main(srna, SPACE_INFO); + rna_def_userdef_theme_spaces_main(srna); } @@ -1282,7 +1428,7 @@ RNA_def_struct_clear_flag(srna, STRUCT_UNDO); RNA_def_struct_ui_text(srna, "Theme Text Editor", "Theme settings for the Text Editor"); - rna_def_userdef_theme_spaces_main(srna, SPACE_TEXT); + rna_def_userdef_theme_spaces_main(srna); prop= RNA_def_property(srna, "line_numbers_background", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_float_sdna(prop, NULL, "grid"); @@ -1351,7 +1497,8 @@ RNA_def_struct_clear_flag(srna, STRUCT_UNDO); RNA_def_struct_ui_text(srna, "Theme Node Editor", "Theme settings for the Node Editor"); - rna_def_userdef_theme_spaces_main(srna, SPACE_NODE); + rna_def_userdef_theme_spaces_main(srna); + rna_def_userdef_theme_spaces_list_main(srna); prop= RNA_def_property(srna, "wire", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_float_sdna(prop, NULL, "wire"); @@ -1421,7 +1568,7 @@ RNA_def_struct_clear_flag(srna, STRUCT_UNDO); RNA_def_struct_ui_text(srna, "Theme Logic Editor", "Theme settings for the Logic Editor"); - rna_def_userdef_theme_spaces_main(srna, SPACE_LOGIC); + rna_def_userdef_theme_spaces_main(srna); prop= RNA_def_property(srna, "panel", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_array(prop, 3); @@ -1442,7 +1589,7 @@ RNA_def_struct_clear_flag(srna, STRUCT_UNDO); RNA_def_struct_ui_text(srna, "Theme Properties", "Theme settings for the Properties"); - rna_def_userdef_theme_spaces_main(srna, SPACE_BUTS); + rna_def_userdef_theme_spaces_main(srna); prop= RNA_def_property(srna, "panel", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_array(prop, 3); @@ -1462,7 +1609,7 @@ RNA_def_struct_clear_flag(srna, STRUCT_UNDO); RNA_def_struct_ui_text(srna, "Theme Timeline", "Theme settings for the Timeline"); - rna_def_userdef_theme_spaces_main(srna, SPACE_TIME); + rna_def_userdef_theme_spaces_main(srna); prop= RNA_def_property(srna, "grid", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_array(prop, 3); @@ -1488,7 +1635,7 @@ RNA_def_struct_clear_flag(srna, STRUCT_UNDO); RNA_def_struct_ui_text(srna, "Theme Image Editor", "Theme settings for the Image Editor"); - rna_def_userdef_theme_spaces_main(srna, SPACE_IMAGE); + rna_def_userdef_theme_spaces_main(srna); rna_def_userdef_theme_spaces_vertex(srna); rna_def_userdef_theme_spaces_face(srna); @@ -1502,6 +1649,42 @@ RNA_def_property_array(prop, 4); RNA_def_property_ui_text(prop, "Scope region background color", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop= RNA_def_property(srna, "preview_stitch_face", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "preview_stitch_face"); + RNA_def_property_array(prop, 4); + RNA_def_property_ui_text(prop, "Stitch preview face color", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop= RNA_def_property(srna, "preview_stitch_edge", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "preview_stitch_edge"); + RNA_def_property_array(prop, 4); + RNA_def_property_ui_text(prop, "Stitch preview edge color", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop= RNA_def_property(srna, "preview_stitch_vert", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "preview_stitch_vert"); + RNA_def_property_array(prop, 4); + RNA_def_property_ui_text(prop, "Stitch preview vertex color", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop= RNA_def_property(srna, "preview_stitch_stitchable", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "preview_stitch_stitchable"); + RNA_def_property_array(prop, 4); + RNA_def_property_ui_text(prop, "Stitch preview stitchable color", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop= RNA_def_property(srna, "preview_stitch_unstitchable", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "preview_stitch_unstitchable"); + RNA_def_property_array(prop, 4); + RNA_def_property_ui_text(prop, "Stitch preview unstitchable color", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop= RNA_def_property(srna, "preview_stitch_active", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "preview_stitch_active"); + RNA_def_property_array(prop, 4); + RNA_def_property_ui_text(prop, "Stitch preview active island", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_theme_space_seq(BlenderRNA *brna) @@ -1516,7 +1699,7 @@ RNA_def_struct_clear_flag(srna, STRUCT_UNDO); RNA_def_struct_ui_text(srna, "Theme Sequence Editor", "Theme settings for the Sequence Editor"); - rna_def_userdef_theme_spaces_main(srna, SPACE_IMAGE); + rna_def_userdef_theme_spaces_main(srna); prop= RNA_def_property(srna, "grid", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_array(prop, 3); @@ -1608,7 +1791,8 @@ RNA_def_struct_clear_flag(srna, STRUCT_UNDO); RNA_def_struct_ui_text(srna, "Theme DopeSheet", "Theme settings for the DopeSheet"); - rna_def_userdef_theme_spaces_main(srna, SPACE_ACTION); + rna_def_userdef_theme_spaces_main(srna); + rna_def_userdef_theme_spaces_list_main(srna); prop= RNA_def_property(srna, "grid", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_array(prop, 3); @@ -1694,7 +1878,8 @@ RNA_def_struct_clear_flag(srna, STRUCT_UNDO); RNA_def_struct_ui_text(srna, "Theme NLA Editor", "Theme settings for the NLA Editor"); - rna_def_userdef_theme_spaces_main(srna, SPACE_NLA); + rna_def_userdef_theme_spaces_main(srna); + rna_def_userdef_theme_spaces_list_main(srna); prop= RNA_def_property(srna, "grid", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_array(prop, 3); @@ -1783,7 +1968,7 @@ RNA_def_struct_clear_flag(srna, STRUCT_UNDO); RNA_def_struct_ui_text(srna, "Theme Clip Editor", "Theme settings for the Movie Clip Editor"); - rna_def_userdef_theme_spaces_main(srna, SPACE_CLIP); + rna_def_userdef_theme_spaces_main(srna); prop= RNA_def_property(srna, "marker_outline", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_float_sdna(prop, NULL, "marker_outline"); @@ -1895,9 +2080,11 @@ prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_property_ui_text(prop, "Name", "Name of the theme"); RNA_def_struct_name_property(srna, prop); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); /* XXX: for now putting this in presets is silly - its just Default */ prop= RNA_def_property(srna, "theme_area", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "active_theme_area"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); RNA_def_property_enum_items(prop, active_theme_area); RNA_def_property_ui_text(prop, "Active Theme Area", ""); @@ -2037,6 +2224,9 @@ rna_def_userdef_theme_ui_style(brna); rna_def_userdef_theme_ui(brna); + + rna_def_userdef_theme_space_generic(brna); + rna_def_userdef_theme_space_list_generic(brna); rna_def_userdef_theme_space_view3d(brna); rna_def_userdef_theme_space_graph(brna); @@ -2607,40 +2797,50 @@ /* hardcoded here, could become dynamic somehow */ /* locale according to http://www.roseindia.net/tutorials/I18N/locales-list.shtml */ /* if you edit here, please also edit the source/blender/blenfont/intern/blf_lang.c 's locales */ + /* Note: As this list is in alphabetical order, and not defined order, + * here is the highest define currently in use: 29 (kyrgyz). */ static EnumPropertyItem language_items[] = { - {0, "", 0, "Nearly done", ""}, - {0, "DEFAULT", 0, "Default (Default)", ""}, - {1, "ENGLISH", 0, "English (English)", "en_US"}, - {8, "FRENCH", 0, "French (Français)", "fr_FR"}, - {4, "ITALIAN", 0, "Italian (Italiano)", "it_IT"}, + { 0, "", 0, "Nearly done", ""}, + { 0, "DEFAULT", 0, "Default (Default)", ""}, + { 1, "ENGLISH", 0, "English (English)", "en_US"}, + { 8, "FRENCH", 0, "French (Français)", "fr_FR"}, + { 4, "ITALIAN", 0, "Italian (Italiano)", "it_IT"}, {15, "RUSSIAN", 0, "Russian (Русский)", "ru_RU"}, {13, "SIMPLIFIED_CHINESE", 0, "Simplified Chinese (简体中文)", "zh_CN"}, - {9, "SPANISH", 0, "Spanish (Español)", "es"}, + { 9, "SPANISH", 0, "Spanish (Español)", "es"}, {14, "TRADITIONAL_CHINESE", 0, "Traditional Chinese (繁體中文)", "zh_TW"}, - {0, "", 0, "In progress", ""}, - {2, "JAPANESE", 0, "Japanese (日本語)", "ja_JP"}, - {3, "DUTCH", 0, "Dutch (Nederlandse taal)", "nl_NL"}, - {5, "GERMAN", 0, "German (Deutsch)", "de_DE"}, - {6, "FINNISH", 0, "Finnish (Suomi)", "fi_FI"}, - {7, "SWEDISH", 0, "Swedish (Svenska)", "sv_SE"}, - {10, "CATALAN", 0, "Catalan (Català)", "ca_AD"}, - {11, "CZECH", 0, "Czech (Český)", "cs_CZ"}, - {12, "BRAZILIAN_PORTUGUESE", 0, "Brazilian Portuguese (Português do Brasil)", "pt_BR"}, - {16, "CROATIAN", 0, "Croatian (Hrvatski)", "hr_HR"}, - {17, "SERBIAN", 0, "Serbian (Српском језику)", "sr_RS"}, - {18, "UKRAINIAN", 0, "Ukrainian (Український)", "uk_UA"}, - {19, "POLISH", 0, "Polish (Polski)", "pl_PL"}, - {20, "ROMANIAN", 0, "Romanian (Român)", "ro_RO"}, + { 0, "", 0, "In progress", ""}, /* using the utf8 flipped form of Arabic (العربية) */ {21, "ARABIC", 0, "Arabic (ﺔﻴﺑﺮﻌﻟﺍ)", "ar_EG"}, + {12, "BRAZILIAN_PORTUGUESE", 0, "Brazilian Portuguese (Português do Brasil)", "pt_BR"}, {22, "BULGARIAN", 0, "Bulgarian (Български)", "bg_BG"}, + {10, "CATALAN", 0, "Catalan (Català)", "ca_AD"}, + {16, "CROATIAN", 0, "Croatian (Hrvatski)", "hr_HR"}, + {11, "CZECH", 0, "Czech (Český)", "cs_CZ"}, + { 3, "DUTCH", 0, "Dutch (Nederlandse taal)", "nl_NL"}, + { 6, "FINNISH", 0, "Finnish (Suomi)", "fi_FI"}, + { 5, "GERMAN", 0, "German (Deutsch)", "de_DE"}, {23, "GREEK", 0, "Greek (Ελληνικά)", "el_GR"}, + {27, "INDONESIAN", 0, "Indonesian (Bahasa indonesia)", "id_ID"}, + { 2, "JAPANESE", 0, "Japanese (日本語)", "ja_JP"}, + {29, "KYRGYZ", 0, "Kyrgyz (Kyrgyz tili)", "ki"}, {24, "KOREAN", 0, "Korean (한국 언어)", "ko_KR"}, {25, "NEPALI", 0, "Nepali (नेपाली)", "ne_NP"}, /* using the utf8 flipped form of Persian (فارسی) */ {26, "PERSIAN", 0, "Persian (ﯽﺳﺭﺎﻓ)", "fa_PE"}, - {27, "INDONESIAN", 0, "Indonesian (Bahasa indonesia)", "id_ID"}, - {0, NULL, 0, NULL, NULL}}; + {19, "POLISH", 0, "Polish (Polski)", "pl_PL"}, + {20, "ROMANIAN", 0, "Romanian (Român)", "ro_RO"}, + {17, "SERBIAN", 0, "Serbian (Српски)", "sr_RS"}, + {28, "SERBIAN_LATIN", 0, "Serbian latin (Srpski latinica)", "sr_RS@latin"}, + { 7, "SWEDISH", 0, "Swedish (Svenska)", "sv_SE"}, + {18, "UKRAINIAN", 0, "Ukrainian (Український)", "uk_UA"}, + { 0, NULL, 0, NULL, NULL}}; + +#ifdef WITH_CYCLES + static EnumPropertyItem compute_device_items[] = { + {0, "CPU", 0, "CPU", ""}, + { 0, NULL, 0, NULL, NULL}}; +#endif srna= RNA_def_struct(brna, "UserPreferencesSystem", NULL); RNA_def_struct_sdna(srna, "UserDef"); @@ -2763,6 +2963,11 @@ "Scale textures for the 3D View (looks nicer but uses more memory and slows image reloading)"); RNA_def_property_update(prop, 0, "rna_userdef_mipmap_update"); + prop= RNA_def_property(srna, "use_16bit_textures", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "use_16bit_textures", 1); + RNA_def_property_ui_text(prop, "16 Bit Float Textures", "Use 16 bit per component texture for float images"); + RNA_def_property_update(prop, 0, "rna_userdef_gl_use_16bit_textures"); + prop= RNA_def_property(srna, "use_vertex_buffer_objects", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "gameflags", USER_DISABLE_VBO); RNA_def_property_ui_text(prop, "VBOs", "Use Vertex Buffer Objects (or Vertex Arrays, if unsupported) for viewport rendering"); @@ -2850,14 +3055,20 @@ RNA_def_property_ui_text(prop, "Text Anti-aliasing", "Draw user interface text anti-aliased"); RNA_def_property_update(prop, 0, "rna_userdef_text_update"); -#if 0 - prop= RNA_def_property(srna, "verse_master", PROP_STRING, PROP_NONE); - RNA_def_property_string_sdna(prop, NULL, "versemaster"); - RNA_def_property_ui_text(prop, "Verse Master", "Verse Master-server IP"); - - prop= RNA_def_property(srna, "verse_username", PROP_STRING, PROP_NONE); - RNA_def_property_string_sdna(prop, NULL, "verseuser"); - RNA_def_property_ui_text(prop, "Verse Username", "Verse user name"); +#ifdef WITH_CYCLES + prop= RNA_def_property(srna, "compute_device_type", PROP_ENUM, PROP_NONE); + RNA_def_property_flag(prop, PROP_ENUM_NO_CONTEXT); + RNA_def_property_enum_sdna(prop, NULL, "compute_device_type"); + RNA_def_property_enum_items(prop, compute_device_type_items); + RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_userdef_compute_device_type_itemf"); + RNA_def_property_ui_text(prop, "Compute Device Type", "Device to use for computation (rendering with Cycles)"); + + prop= RNA_def_property(srna, "compute_device", PROP_ENUM, PROP_NONE); + RNA_def_property_flag(prop, PROP_ENUM_NO_CONTEXT); + RNA_def_property_enum_sdna(prop, NULL, "compute_device_id"); + RNA_def_property_enum_items(prop, compute_device_items); + RNA_def_property_enum_funcs(prop, "rna_userdef_compute_device_get", NULL, "rna_userdef_compute_device_itemf"); + RNA_def_property_ui_text(prop, "Compute Device", "Device to use for computation"); #endif } diff -Nru blender-2.61/source/blender/makesrna/intern/rna_wm_api.c blender-2.62/source/blender/makesrna/intern/rna_wm_api.c --- blender-2.61/source/blender/makesrna/intern/rna_wm_api.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_wm_api.c 2012-02-15 19:35:15.000000000 +0000 @@ -197,7 +197,9 @@ PropertyRNA *parm; func= RNA_def_function(srna, "fileselect_add", "WM_event_add_fileselect"); - RNA_def_function_ui_description(func, "Show up the file selector"); + RNA_def_function_ui_description(func, "Opens a file selector with an operator. " + "The string properties 'filepath', 'filename', 'directory' and a 'files' collection " + "are assigned when present in the operator"); rna_generic_op_invoke(func, 0); func= RNA_def_function(srna, "modal_handler_add", "rna_event_modal_handler_add"); diff -Nru blender-2.61/source/blender/makesrna/intern/rna_wm.c blender-2.62/source/blender/makesrna/intern/rna_wm.c --- blender-2.61/source/blender/makesrna/intern/rna_wm.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_wm.c 2012-02-15 19:35:15.000000000 +0000 @@ -67,6 +67,14 @@ {KM_RELEASE, "RELEASE", 0, "Release", ""}, {KM_CLICK, "CLICK", 0, "Click", ""}, {KM_DBL_CLICK, "DOUBLE_CLICK", 0, "Double Click", ""}, + {EVT_GESTURE_N, "NORTH", 0, "North", ""}, + {EVT_GESTURE_NE, "NORTH_EAST", 0, "North-East", ""}, + {EVT_GESTURE_E, "EAST", 0, "East", ""}, + {EVT_GESTURE_SE, "SOUTH_EAST", 0, "South-East", ""}, + {EVT_GESTURE_S, "SOUTH", 0, "South", ""}, + {EVT_GESTURE_SW, "SOUTH_WEST", 0, "South-West", ""}, + {EVT_GESTURE_W, "WEST", 0, "West", ""}, + {EVT_GESTURE_NW, "NORTH_WEST", 0, "North-West", ""}, {0, NULL, 0, NULL, NULL}}; EnumPropertyItem event_tweak_type_items[]= { @@ -295,43 +303,44 @@ {TIMER1, "TIMER1", 0, "Timer 1", ""}, {TIMER2, "TIMER2", 0, "Timer 2", ""}, {0, "", 0, NULL, NULL}, + {NDOF_MOTION, "NDOF_MOTION", 0, "NDOF Motion", ""}, /* buttons on all 3dconnexion devices */ - {NDOF_BUTTON_MENU, "NDOF_BUTTON_MENU", 0, "Menu", ""}, - {NDOF_BUTTON_FIT, "NDOF_BUTTON_FIT", 0, "Fit", ""}, + {NDOF_BUTTON_MENU, "NDOF_BUTTON_MENU", 0, "NDOF Menu", ""}, + {NDOF_BUTTON_FIT, "NDOF_BUTTON_FIT", 0, "NDOF Fit", ""}, /* view buttons */ - {NDOF_BUTTON_TOP, "NDOF_BUTTON_TOP", 0, "Top", ""}, - {NDOF_BUTTON_BOTTOM, "NDOF_BUTTON_BOTTOM", 0, "Bottom", ""}, - {NDOF_BUTTON_LEFT, "NDOF_BUTTON_LEFT", 0, "Left", ""}, - {NDOF_BUTTON_RIGHT, "NDOF_BUTTON_RIGHT", 0, "Right", ""}, - {NDOF_BUTTON_FRONT, "NDOF_BUTTON_FRONT", 0, "Front", ""}, - {NDOF_BUTTON_BACK, "NDOF_BUTTON_BACK", 0, "Back", ""}, + {NDOF_BUTTON_TOP, "NDOF_BUTTON_TOP", 0, "NDOF Top", ""}, + {NDOF_BUTTON_BOTTOM, "NDOF_BUTTON_BOTTOM", 0, "NDOF Bottom", ""}, + {NDOF_BUTTON_LEFT, "NDOF_BUTTON_LEFT", 0, "NDOF Left", ""}, + {NDOF_BUTTON_RIGHT, "NDOF_BUTTON_RIGHT", 0, "NDOF Right", ""}, + {NDOF_BUTTON_FRONT, "NDOF_BUTTON_FRONT", 0, "NDOF Front", ""}, + {NDOF_BUTTON_BACK, "NDOF_BUTTON_BACK", 0, "NDOF Back", ""}, /* more views */ - {NDOF_BUTTON_ISO1, "NDOF_BUTTON_ISO1", 0, "ISO 1", ""}, - {NDOF_BUTTON_ISO2, "NDOF_BUTTON_ISO2", 0, "ISO 2", ""}, + {NDOF_BUTTON_ISO1, "NDOF_BUTTON_ISO1", 0, "NDOF ISO 1", ""}, + {NDOF_BUTTON_ISO2, "NDOF_BUTTON_ISO2", 0, "NDOF ISO 2", ""}, /* 90 degree rotations */ - {NDOF_BUTTON_ROLL_CW, "NDOF_BUTTON_ROLL_CW", 0, "Roll CW", ""}, - {NDOF_BUTTON_ROLL_CCW, "NDOF_BUTTON_ROLL_CCW", 0, "Roll CCW", ""}, - {NDOF_BUTTON_SPIN_CW, "NDOF_BUTTON_SPIN_CW", 0, "Spin CW", ""}, - {NDOF_BUTTON_SPIN_CCW, "NDOF_BUTTON_SPIN_CCW", 0, "Spin CCW", ""}, - {NDOF_BUTTON_TILT_CW, "NDOF_BUTTON_TILT_CW", 0, "Tilt CW", ""}, - {NDOF_BUTTON_TILT_CCW, "NDOF_BUTTON_TILT_CCW", 0, "Tilt CCW", ""}, + {NDOF_BUTTON_ROLL_CW, "NDOF_BUTTON_ROLL_CW", 0, "NDOF Roll CW", ""}, + {NDOF_BUTTON_ROLL_CCW, "NDOF_BUTTON_ROLL_CCW", 0, "NDOF Roll CCW", ""}, + {NDOF_BUTTON_SPIN_CW, "NDOF_BUTTON_SPIN_CW", 0, "NDOF Spin CW", ""}, + {NDOF_BUTTON_SPIN_CCW, "NDOF_BUTTON_SPIN_CCW", 0, "NDOF Spin CCW", ""}, + {NDOF_BUTTON_TILT_CW, "NDOF_BUTTON_TILT_CW", 0, "NDOF Tilt CW", ""}, + {NDOF_BUTTON_TILT_CCW, "NDOF_BUTTON_TILT_CCW", 0, "NDOF Tilt CCW", ""}, /* device control */ - {NDOF_BUTTON_ROTATE, "NDOF_BUTTON_ROTATE", 0, "Rotate", ""}, - {NDOF_BUTTON_PANZOOM, "NDOF_BUTTON_PANZOOM", 0, "Pan/Zoom", ""}, - {NDOF_BUTTON_DOMINANT, "NDOF_BUTTON_DOMINANT", 0, "Dominant", ""}, - {NDOF_BUTTON_PLUS, "NDOF_BUTTON_PLUS", 0, "Plus", ""}, - {NDOF_BUTTON_MINUS, "NDOF_BUTTON_MINUS", 0, "Minus", ""}, + {NDOF_BUTTON_ROTATE, "NDOF_BUTTON_ROTATE", 0, "NDOF Rotate", ""}, + {NDOF_BUTTON_PANZOOM, "NDOF_BUTTON_PANZOOM", 0, "NDOF Pan/Zoom", ""}, + {NDOF_BUTTON_DOMINANT, "NDOF_BUTTON_DOMINANT", 0, "NDOF Dominant", ""}, + {NDOF_BUTTON_PLUS, "NDOF_BUTTON_PLUS", 0, "NDOF Plus", ""}, + {NDOF_BUTTON_MINUS, "NDOF_BUTTON_MINUS", 0, "NDOF Minus", ""}, /* general-purpose buttons */ - {NDOF_BUTTON_1, "NDOF_BUTTON_1", 0, "Button 1", ""}, - {NDOF_BUTTON_2, "NDOF_BUTTON_2", 0, "Button 2", ""}, - {NDOF_BUTTON_3, "NDOF_BUTTON_3", 0, "Button 3", ""}, - {NDOF_BUTTON_4, "NDOF_BUTTON_4", 0, "Button 4", ""}, - {NDOF_BUTTON_5, "NDOF_BUTTON_5", 0, "Button 5", ""}, - {NDOF_BUTTON_6, "NDOF_BUTTON_6", 0, "Button 6", ""}, - {NDOF_BUTTON_7, "NDOF_BUTTON_7", 0, "Button 7", ""}, - {NDOF_BUTTON_8, "NDOF_BUTTON_8", 0, "Button 8", ""}, - {NDOF_BUTTON_9, "NDOF_BUTTON_9", 0, "Button 9", ""}, - {NDOF_BUTTON_10, "NDOF_BUTTON_10", 0, "Button 10", ""}, + {NDOF_BUTTON_1, "NDOF_BUTTON_1", 0, "NDOF Button 1", ""}, + {NDOF_BUTTON_2, "NDOF_BUTTON_2", 0, "NDOF Button 2", ""}, + {NDOF_BUTTON_3, "NDOF_BUTTON_3", 0, "NDOF Button 3", ""}, + {NDOF_BUTTON_4, "NDOF_BUTTON_4", 0, "NDOF Button 4", ""}, + {NDOF_BUTTON_5, "NDOF_BUTTON_5", 0, "NDOF Button 5", ""}, + {NDOF_BUTTON_6, "NDOF_BUTTON_6", 0, "NDOF Button 6", ""}, + {NDOF_BUTTON_7, "NDOF_BUTTON_7", 0, "NDOF Button 7", ""}, + {NDOF_BUTTON_8, "NDOF_BUTTON_8", 0, "NDOF Button 8", ""}, + {NDOF_BUTTON_9, "NDOF_BUTTON_9", 0, "NDOF Button 9", ""}, + {NDOF_BUTTON_10, "NDOF_BUTTON_10", 0, "NDOF Button 10", ""}, {0, NULL, 0, NULL, NULL}}; EnumPropertyItem keymap_propvalue_items[] = { @@ -371,7 +380,7 @@ {RPT_OPERATOR, "OPERATOR", 0, "Operator", ""}, {RPT_WARNING, "WARNING", 0, "Warning", ""}, {RPT_ERROR, "ERROR", 0, "Error", ""}, - {RPT_ERROR_INVALID_INPUT, "ERROR_INVALID_INPUT", 0, "Invalid Input", ""},\ + {RPT_ERROR_INVALID_INPUT, "ERROR_INVALID_INPUT", 0, "Invalid Input", ""}, {RPT_ERROR_INVALID_CONTEXT, "ERROR_INVALID_CONTEXT", 0, "Invalid Context", ""}, {RPT_ERROR_OUT_OF_MEMORY, "ERROR_OUT_OF_MEMORY", 0, "Out of Memory", ""}, {0, NULL, 0, NULL, NULL}}; @@ -1050,6 +1059,9 @@ rna_Operator_unregister(bmain, ot->ext.srna); } + /* XXX, this doubles up with the operator name [#29666] + * for now just remove from dir(bpy.types) */ + /* create a new operator type */ dummyot.ext.srna= RNA_def_struct(&BLENDER_RNA, dummyot.idname, "Operator"); RNA_def_struct_flag(dummyot.ext.srna, STRUCT_NO_IDPROPERTIES); /* operator properties are registered separately */ @@ -1126,7 +1138,10 @@ rna_Operator_unregister(bmain, ot->ext.srna); } - /* create a new menu type */ + /* XXX, this doubles up with the operator name [#29666] + * for now just remove from dir(bpy.types) */ + + /* create a new operator type */ dummyot.ext.srna= RNA_def_struct(&BLENDER_RNA, dummyot.idname, "Operator"); dummyot.ext.data= data; dummyot.ext.call= call; diff -Nru blender-2.61/source/blender/makesrna/intern/rna_world.c blender-2.62/source/blender/makesrna/intern/rna_world.c --- blender-2.61/source/blender/makesrna/intern/rna_world.c 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/rna_world.c 2012-02-15 19:35:15.000000000 +0000 @@ -143,6 +143,7 @@ {TEXCO_GLOB, "GLOBAL", 0, "Global", "Use global coordinates for the texture coordinates (interior mist)"}, {TEXCO_ANGMAP, "ANGMAP", 0, "AngMap", "Use 360 degree angular coordinates, e.g. for spherical light probes"}, {TEXCO_H_SPHEREMAP, "SPHERE", 0, "Sphere", "For 360 degree panorama sky, spherical mapped, only top half"}, + {TEXCO_EQUIRECTMAP, "EQUIRECT", 0, "Equirectangular", "For 360 degree panorama sky, equirectangular mapping"}, {TEXCO_H_TUBEMAP, "TUBE", 0, "Tube", "For 360 degree panorama sky, cylindrical mapped, only top half"}, {TEXCO_OBJECT, "OBJECT", 0, "Object", "Use linked object's coordinates for texture coordinates"}, {0, NULL, 0, NULL, NULL}}; diff -Nru blender-2.61/source/blender/makesrna/intern/SConscript blender-2.62/source/blender/makesrna/intern/SConscript --- blender-2.61/source/blender/makesrna/intern/SConscript 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/intern/SConscript 2012-02-15 19:35:15.000000000 +0000 @@ -33,7 +33,7 @@ incs += ' ../../imbuf ../../makesdna ../../makesrna ../../ikplugin' incs += ' ../../windowmanager ../../editors/include ../../blenfont' incs += ' ../../render/extern/include' -incs += ' #/intern/audaspace/intern ' +incs += ' #/intern/audaspace/intern #/intern/cycles/blender' incs += ' #/extern/glew/include ' if env['WITH_BF_OPENEXR']: @@ -60,9 +60,6 @@ defs.append('WITH_FFMPEG') incs += ' ' + env['BF_FFMPEG_INC'] -if env['WITH_BF_OGG']: - defs.append('WITH_OGG') - if env['WITH_BF_QUICKTIME']: defs.append('WITH_QUICKTIME') incs += ' ../../quicktime' @@ -91,6 +88,9 @@ if env['WITH_BF_COLLADA']: defs.append('WITH_COLLADA') +if env['WITH_BF_CYCLES']: + defs.append('WITH_CYCLES') + if env['OURPLATFORM'] == 'linux': cflags='-pthread' incs += ' ../../../extern/binreloc/include' @@ -101,6 +101,10 @@ if env['WITH_BF_INTERNATIONAL']: defs.append('WITH_INTERNATIONAL') +if not env['BF_DEBUG']: + defs.append('NDEBUG') + + makesrna_tool.Append(CPPDEFINES=defs) makesrna_tool.Append (CPPPATH = Split(incs)) diff -Nru blender-2.61/source/blender/makesrna/RNA_access.h blender-2.62/source/blender/makesrna/RNA_access.h --- blender-2.61/source/blender/makesrna/RNA_access.h 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/RNA_access.h 2012-02-15 19:35:17.000000000 +0000 @@ -136,6 +136,7 @@ extern StructRNA RNA_CompositorNodeGlare; extern StructRNA RNA_CompositorNodeHueSat; extern StructRNA RNA_CompositorNodeIDMask; +extern StructRNA RNA_CompositorNodeDoubleEdgeMask; extern StructRNA RNA_CompositorNodeImage; extern StructRNA RNA_CompositorNodeInvert; extern StructRNA RNA_CompositorNodeLensdist; @@ -214,6 +215,7 @@ extern StructRNA RNA_ExpressionController; extern StructRNA RNA_FCurve; extern StructRNA RNA_FCurveSample; +extern StructRNA RNA_FFmpegSettings; extern StructRNA RNA_FModifier; extern StructRNA RNA_FModifierCycles; extern StructRNA RNA_FModifierEnvelope; @@ -329,6 +331,7 @@ extern StructRNA RNA_MotionPathVert; extern StructRNA RNA_MouseSensor; extern StructRNA RNA_MovieSequence; +extern StructRNA RNA_MovieTrackingObject; extern StructRNA RNA_MulticamSequence; extern StructRNA RNA_MultiresModifier; extern StructRNA RNA_MusgraveTexture; @@ -392,6 +395,7 @@ extern StructRNA RNA_PropertySensor; extern StructRNA RNA_PythonConstraint; extern StructRNA RNA_PythonController; +extern StructRNA RNA_QuickTimeSettings; extern StructRNA RNA_RadarSensor; extern StructRNA RNA_RandomSensor; extern StructRNA RNA_RaySensor; @@ -412,6 +416,7 @@ extern StructRNA RNA_Screen; extern StructRNA RNA_ScrewModifier; extern StructRNA RNA_Sculpt; +extern StructRNA RNA_SelectedUvElement; extern StructRNA RNA_Sensor; extern StructRNA RNA_Sequence; extern StructRNA RNA_SequenceColorBalance; @@ -542,6 +547,8 @@ extern StructRNA RNA_ThemeOutliner; extern StructRNA RNA_ThemeProperties; extern StructRNA RNA_ThemeSequenceEditor; +extern StructRNA RNA_ThemeSpaceGeneric; +extern StructRNA RNA_ThemeSpaceListGeneric; extern StructRNA RNA_ThemeStyle; extern StructRNA RNA_ThemeTextEditor; extern StructRNA RNA_ThemeTimeline; @@ -579,9 +586,9 @@ extern StructRNA RNA_VoxelDataTexture; extern StructRNA RNA_WarpModifier; extern StructRNA RNA_WaveModifier; -extern StructRNA RNA_WeightVGEditModifier; -extern StructRNA RNA_WeightVGMixModifier; -extern StructRNA RNA_WeightVGProximityModifier; +extern StructRNA RNA_VertexWeightEditModifier; +extern StructRNA RNA_VertexWeightMixModifier; +extern StructRNA RNA_VertexWeightProximityModifier; extern StructRNA RNA_Window; extern StructRNA RNA_WindowManager; extern StructRNA RNA_WipeSequence; @@ -931,7 +938,8 @@ } /* check if the idproperty exists, for operators */ -int RNA_property_is_set(PointerRNA *ptr, const char *name); +int RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop); +int RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier); int RNA_property_is_idprop(PropertyRNA *prop); /* python compatible string representation of this property, (must be freed!) */ @@ -993,7 +1001,7 @@ /* macro which inserts the function name */ -#ifdef __GNUC__ +#if defined __GNUC__ || defined __sun # define RNA_warning(format, args...) _RNA_warning("%s: " format "\n", __func__, ##args) #else # define RNA_warning(format, ...) _RNA_warning("%s: " format "\n", __FUNCTION__, __VA_ARGS__) diff -Nru blender-2.61/source/blender/makesrna/RNA_define.h blender-2.62/source/blender/makesrna/RNA_define.h --- blender-2.61/source/blender/makesrna/RNA_define.h 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/RNA_define.h 2012-02-15 19:35:17.000000000 +0000 @@ -175,6 +175,8 @@ void RNA_def_property_srna(PropertyRNA *prop, const char *type); void RNA_def_py_data(PropertyRNA *prop, void *py_data); +void RNA_def_property_translation_context(PropertyRNA *prop, const char *context); + /* Function */ FunctionRNA *RNA_def_function(StructRNA *srna, const char *identifier, const char *call); diff -Nru blender-2.61/source/blender/makesrna/RNA_enum_types.h blender-2.62/source/blender/makesrna/RNA_enum_types.h --- blender-2.61/source/blender/makesrna/RNA_enum_types.h 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/RNA_enum_types.h 2012-02-15 19:35:17.000000000 +0000 @@ -104,6 +104,8 @@ extern EnumPropertyItem property_subtype_items[]; extern EnumPropertyItem property_unit_items[]; +extern EnumPropertyItem gameproperty_type_items[]; + extern EnumPropertyItem viewport_shade_items[]; extern EnumPropertyItem nodetree_type_items[]; diff -Nru blender-2.61/source/blender/makesrna/SConscript blender-2.62/source/blender/makesrna/SConscript --- blender-2.61/source/blender/makesrna/SConscript 2011-12-13 19:50:31.000000000 +0000 +++ blender-2.62/source/blender/makesrna/SConscript 2012-02-15 19:35:17.000000000 +0000 @@ -8,7 +8,7 @@ incs = '#/intern/guardedalloc #/intern/memutil #/intern/audaspace/intern ../blenkernel ../blenlib ../makesdna intern .' incs += ' ../windowmanager ../editors/include ../gpu ../imbuf ../ikplugin ../blenfont ../blenloader' -incs += ' ../render/extern/include' +incs += ' ../render/extern/include #/intern/cycles/blender' incs += ' ../nodes' incs += ' #/extern/glew/include' @@ -36,9 +36,6 @@ defs.append('WITH_FFMPEG') incs += ' ' + env['BF_FFMPEG_INC'] -if env['WITH_BF_OGG']: - defs.append('WITH_OGG') - if env['WITH_BF_QUICKTIME']: defs.append('WITH_QUICKTIME') incs += ' ../quicktime' @@ -58,6 +55,9 @@ if env['WITH_BF_OCEANSIM']: defs.append('WITH_OCEANSIM') +if env['WITH_BF_CYCLES']: + defs.append('WITH_CYCLES') + if env['OURPLATFORM'] == 'linux': cflags='-pthread' incs += ' ../../../extern/binreloc/include' diff -Nru blender-2.61/source/blender/modifiers/CMakeLists.txt blender-2.62/source/blender/modifiers/CMakeLists.txt --- blender-2.61/source/blender/modifiers/CMakeLists.txt 2011-12-13 19:49:29.000000000 +0000 +++ blender-2.62/source/blender/modifiers/CMakeLists.txt 2012-02-15 19:34:17.000000000 +0000 @@ -12,7 +12,7 @@ # # 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # The Original Code is Copyright (C) 2006, Blender Foundation # All rights reserved. @@ -40,7 +40,7 @@ set(INC_SYS ${ZLIB_INCLUDE_DIRS} - ${GLEW_INCLUDE_PATH} + ${GLEW_INCLUDE_PATH} ) set(SRC @@ -70,6 +70,7 @@ intern/MOD_ocean.c intern/MOD_particleinstance.c intern/MOD_particlesystem.c + intern/MOD_remesh.c intern/MOD_screw.c intern/MOD_shapekey.c intern/MOD_shrinkwrap.c @@ -106,6 +107,13 @@ ) endif() +if(WITH_MOD_REMESH) + add_definitions(-DWITH_MOD_REMESH) + list(APPEND INC + ../../../intern/dualcon + ) +endif() + if(WITH_MOD_DECIMATE) add_definitions(-DWITH_MOD_DECIMATE) list(APPEND INC diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_armature.c blender-2.62/source/blender/modifiers/intern/MOD_armature.c --- blender-2.61/source/blender/modifiers/intern/MOD_armature.c 2011-12-13 19:49:28.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_armature.c 2012-02-15 19:34:17.000000000 +0000 @@ -69,7 +69,7 @@ tamd->object = amd->object; tamd->deformflag = amd->deformflag; tamd->multi = amd->multi; - BLI_strncpy(tamd->defgrp_name, amd->defgrp_name, 32); + BLI_strncpy(tamd->defgrp_name, amd->defgrp_name, sizeof(tamd->defgrp_name)); } static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED(md)) diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_array.c blender-2.62/source/blender/modifiers/intern/MOD_array.c --- blender-2.61/source/blender/modifiers/intern/MOD_array.c 2011-12-13 19:49:28.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_array.c 2012-02-15 19:34:17.000000000 +0000 @@ -338,7 +338,7 @@ unit_m4(final_offset); for(j=0; j < count - 1; j++) { - mul_m4_m4m4(tmp_mat, final_offset, offset); + mult_m4_m4m4(tmp_mat, offset, final_offset); copy_m4_m4(final_offset, tmp_mat); } @@ -679,7 +679,7 @@ cap_medge = end_cap->getEdgeArray(end_cap); cap_mface = end_cap->getFaceArray(end_cap); - mul_m4_m4m4(endoffset, final_offset, offset); + mult_m4_m4m4(endoffset, offset, final_offset); vert_map = MEM_callocN(sizeof(*vert_map) * capVerts, "arrayModifier_doArray vert_map"); diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_bevel.c blender-2.62/source/blender/modifiers/intern/MOD_bevel.c --- blender-2.61/source/blender/modifiers/intern/MOD_bevel.c 2011-12-13 19:49:28.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_bevel.c 2012-02-15 19:34:17.000000000 +0000 @@ -71,7 +71,7 @@ tbmd->lim_flags = bmd->lim_flags; tbmd->e_flags = bmd->e_flags; tbmd->bevel_angle = bmd->bevel_angle; - BLI_strncpy(tbmd->defgrp_name, bmd->defgrp_name, 32); + BLI_strncpy(tbmd->defgrp_name, bmd->defgrp_name, sizeof(tbmd->defgrp_name)); } static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_boolean.c blender-2.62/source/blender/modifiers/intern/MOD_boolean.c --- blender-2.61/source/blender/modifiers/intern/MOD_boolean.c 2011-12-13 19:49:28.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_boolean.c 2012-02-15 19:34:17.000000000 +0000 @@ -47,6 +47,7 @@ #include "MOD_boolean_util.h" #include "MOD_util.h" +#include "PIL_time.h" static void copyData(ModifierData *md, ModifierData *target) { @@ -137,8 +138,12 @@ result = get_quick_derivedMesh(derivedData, dm, bmd->operation); if(result == NULL) { + // TIMEIT_START(NewBooleanDerivedMesh) + result = NewBooleanDerivedMesh(dm, bmd->object, derivedData, ob, 1 + bmd->operation); + + // TIMEIT_END(NewBooleanDerivedMesh) } /* if new mesh returned, return it; otherwise there was diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_boolean_util.c blender-2.62/source/blender/modifiers/intern/MOD_boolean_util.c --- blender-2.61/source/blender/modifiers/intern/MOD_boolean_util.c 2011-12-13 19:49:28.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_boolean_util.c 2012-02-15 19:34:17.000000000 +0000 @@ -350,7 +350,7 @@ GHash *material_hash = NULL; Mesh *me1= (Mesh*)ob1->data; Mesh *me2= (Mesh*)ob2->data; - int i; + int i, *origindex_layer; // create a new DerivedMesh result = CDDM_new(vertex_it->num_elements, 0, face_it->num_elements); @@ -374,10 +374,12 @@ } // a hash table to remap materials to indices - if (mat) { - material_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "CSG_mat gh"); + material_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "CSG_mat gh"); + + if (mat) *totmat = 0; - } + + origindex_layer = result->getFaceDataArray(result, CD_ORIGINDEX); // step through the face iterators for(i = 0; !face_it->Done(face_it->it); i++) { @@ -420,6 +422,32 @@ else mface->mat_nr = GET_INT_FROM_POINTER(BLI_ghash_lookup(material_hash, orig_mat)); } + else if(orig_mat) { + if(orig_ob == ob1) { + // No need to change materian index for faces from left operand + } + else { + // for faces from right operand checn if there's needed material in left operand and if it is, + // use index of that material, otherwise fallback to first material (material with index=0) + if (!BLI_ghash_haskey(material_hash, orig_mat)) { + int a; + + mat_nr = 0; + for(a = 0; a < ob1->totcol; a++) { + if(give_current_material(ob1, a+1) == orig_mat) { + mat_nr = a; + break; + } + } + + BLI_ghash_insert(material_hash, orig_mat, SET_INT_IN_POINTER(mat_nr)); + + mface->mat_nr = mat_nr; + } + else + mface->mat_nr = GET_INT_FROM_POINTER(BLI_ghash_lookup(material_hash, orig_mat)); + } + } else mface->mat_nr = 0; @@ -427,6 +455,9 @@ (orig_me == me2)? mapmat: NULL); test_index_face(mface, &result->faceData, i, csgface.vertex_number); + + if(origindex_layer && orig_ob == ob2) + origindex_layer[i] = ORIGINDEX_NONE; } if (material_hash) @@ -474,7 +505,7 @@ // we need to compute the inverse transform from global to ob (inv_mat), // and the transform from ob to ob_select for use in interpolation (map_mat) invert_m4_m4(inv_mat, ob->obmat); - mul_m4_m4m4(map_mat, ob_select->obmat, inv_mat); + mult_m4_m4m4(map_mat, inv_mat, ob_select->obmat); invert_m4_m4(inv_mat, ob_select->obmat); { @@ -522,7 +553,7 @@ CSG_FreeFaceDescriptor(&fd_o); } else - printf("Unknown internal error in boolean"); + printf("Unknown internal error in boolean\n"); CSG_FreeBooleanOperation(bool_op); diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_build.c blender-2.62/source/blender/modifiers/intern/MOD_build.c --- blender-2.61/source/blender/modifiers/intern/MOD_build.c 2011-12-13 19:49:28.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_build.c 2012-02-15 19:34:17.000000000 +0000 @@ -76,135 +76,150 @@ } static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), - DerivedMesh *derivedData, - int UNUSED(useRenderParams), - int UNUSED(isFinalCalc)) + DerivedMesh *derivedData, + int UNUSED(useRenderParams), + int UNUSED(isFinalCalc)) { DerivedMesh *dm = derivedData; DerivedMesh *result; BuildModifierData *bmd = (BuildModifierData*) md; int i; - int numFaces, numEdges; + int numFaces_dst, numEdges_dst; int *vertMap, *edgeMap, *faceMap; float frac; GHashIterator *hashIter; /* maps vert indices in old mesh to indices in new mesh */ GHash *vertHash = BLI_ghash_new(BLI_ghashutil_inthash, - BLI_ghashutil_intcmp, "build ve apply gh"); + BLI_ghashutil_intcmp, "build ve apply gh"); /* maps edge indices in new mesh to indices in old mesh */ GHash *edgeHash = BLI_ghash_new(BLI_ghashutil_inthash, - BLI_ghashutil_intcmp, "build ed apply gh"); + BLI_ghashutil_intcmp, "build ed apply gh"); - const int maxVerts= dm->getNumVerts(dm); - const int maxEdges= dm->getNumEdges(dm); - const int maxFaces= dm->getNumFaces(dm); - - vertMap = MEM_callocN(sizeof(*vertMap) * maxVerts, "build modifier vertMap"); - for(i = 0; i < maxVerts; ++i) vertMap[i] = i; - edgeMap = MEM_callocN(sizeof(*edgeMap) * maxEdges, "build modifier edgeMap"); - for(i = 0; i < maxEdges; ++i) edgeMap[i] = i; - faceMap = MEM_callocN(sizeof(*faceMap) * maxFaces, "build modifier faceMap"); - for(i = 0; i < maxFaces; ++i) faceMap[i] = i; + const int numVert_src= dm->getNumVerts(dm); + const int numEdge_src= dm->getNumEdges(dm); + const int numFace_src= dm->getNumFaces(dm); + + vertMap = MEM_callocN(sizeof(*vertMap) * numVert_src, "build modifier vertMap"); + for (i = 0; i < numVert_src; i++) vertMap[i] = i; + edgeMap = MEM_callocN(sizeof(*edgeMap) * numEdge_src, "build modifier edgeMap"); + for (i = 0; i < numEdge_src; i++) edgeMap[i] = i; + faceMap = MEM_callocN(sizeof(*faceMap) * numFace_src, "build modifier faceMap"); + for (i = 0; i < numFace_src; i++) faceMap[i] = i; frac = (BKE_curframe(md->scene) - bmd->start) / bmd->length; CLAMP(frac, 0.0f, 1.0f); - numFaces = dm->getNumFaces(dm) * frac; - numEdges = dm->getNumEdges(dm) * frac; + numFaces_dst = dm->getNumFaces(dm) * frac; + numEdges_dst = dm->getNumEdges(dm) * frac; /* if there's at least one face, build based on faces */ - if(numFaces) { - if(bmd->randomize) + if (numFaces_dst) { + if (bmd->randomize) { BLI_array_randomize(faceMap, sizeof(*faceMap), - maxFaces, bmd->seed); + numFace_src, bmd->seed); + } /* get the set of all vert indices that will be in the final mesh, - * mapped to the new indices - */ - for(i = 0; i < numFaces; ++i) { + * mapped to the new indices + */ + for (i = 0; i < numFaces_dst; i++) { MFace mf; dm->getFace(dm, faceMap[i], &mf); - if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v1))) + if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v1))) { BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v1), - SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); - if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v2))) + SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); + } + if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v2))) { BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v2), - SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); - if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v3))) + SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); + } + if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v3))) { BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v3), - SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); - if(mf.v4 && !BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v4))) + SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); + } + if (mf.v4 && !BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v4))) { BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v4), - SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); + SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); + } } /* get the set of edges that will be in the new mesh (i.e. all edges - * that have both verts in the new mesh) - */ - for(i = 0; i < maxEdges; ++i) { + * that have both verts in the new mesh) + */ + for (i = 0; i < numEdge_src; i++) { MEdge me; dm->getEdge(dm, i, &me); - if(BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1)) - && BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2))) - BLI_ghash_insert(edgeHash, - SET_INT_IN_POINTER(BLI_ghash_size(edgeHash)), SET_INT_IN_POINTER(i)); + if ( BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1)) && + BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2))) + { + BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(BLI_ghash_size(edgeHash)), + SET_INT_IN_POINTER(i)); + } } - } else if(numEdges) { - if(bmd->randomize) + } + else if (numEdges_dst) { + if (bmd->randomize) { BLI_array_randomize(edgeMap, sizeof(*edgeMap), - maxEdges, bmd->seed); + numEdge_src, bmd->seed); + } /* get the set of all vert indices that will be in the final mesh, - * mapped to the new indices - */ - for(i = 0; i < numEdges; ++i) { + * mapped to the new indices + */ + for (i = 0; i < numEdges_dst; i++) { MEdge me; dm->getEdge(dm, edgeMap[i], &me); - if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1))) + if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1))) { BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(me.v1), - SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); - if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2))) + SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); + } + if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2))) { BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(me.v2), - SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); + SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); + } } /* get the set of edges that will be in the new mesh - */ - for(i = 0; i < numEdges; ++i) { + */ + for (i = 0; i < numEdges_dst; i++) { MEdge me; dm->getEdge(dm, edgeMap[i], &me); BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(BLI_ghash_size(edgeHash)), - SET_INT_IN_POINTER(edgeMap[i])); + SET_INT_IN_POINTER(edgeMap[i])); } - } else { + } + else { int numVerts = dm->getNumVerts(dm) * frac; - if(bmd->randomize) + if (bmd->randomize) { BLI_array_randomize(vertMap, sizeof(*vertMap), - maxVerts, bmd->seed); + numVert_src, bmd->seed); + } /* get the set of all vert indices that will be in the final mesh, * mapped to the new indices */ - for(i = 0; i < numVerts; ++i) - BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(vertMap[i]), SET_INT_IN_POINTER(i)); + for (i = 0; i < numVerts; i++) { + BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(vertMap[i]), + SET_INT_IN_POINTER(i)); + } } /* now we know the number of verts, edges and faces, we can create - * the mesh - */ + * the mesh + */ result = CDDM_from_template(dm, BLI_ghash_size(vertHash), - BLI_ghash_size(edgeHash), numFaces); + BLI_ghash_size(edgeHash), numFaces_dst); /* copy the vertices across */ - for( hashIter = BLI_ghashIterator_new(vertHash); - !BLI_ghashIterator_isDone(hashIter); - BLI_ghashIterator_step(hashIter) - ) { + for ( hashIter = BLI_ghashIterator_new(vertHash); + !BLI_ghashIterator_isDone(hashIter); + BLI_ghashIterator_step(hashIter)) + { MVert source; MVert *dest; int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter)); @@ -219,7 +234,7 @@ BLI_ghashIterator_free(hashIter); /* copy the edges across, remapping indices */ - for(i = 0; i < BLI_ghash_size(edgeHash); ++i) { + for (i = 0; i < BLI_ghash_size(edgeHash); i++) { MEdge source; MEdge *dest; int oldIndex = GET_INT_FROM_POINTER(BLI_ghash_lookup(edgeHash, SET_INT_IN_POINTER(i))); @@ -235,7 +250,7 @@ } /* copy the faces across, remapping indices */ - for(i = 0; i < numFaces; ++i) { + for (i = 0; i < numFaces_dst; i++) { MFace source; MFace *dest; int orig_v4; @@ -248,7 +263,7 @@ source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1))); source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2))); source.v3 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v3))); - if(source.v4) + if (source.v4) source.v4 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v4))); DM_copy_face_data(dm, result, faceMap[i], i, 1); @@ -258,14 +273,14 @@ } CDDM_calc_normals(result); - + BLI_ghash_free(vertHash, NULL, NULL); BLI_ghash_free(edgeHash, NULL, NULL); MEM_freeN(vertMap); MEM_freeN(edgeMap); MEM_freeN(faceMap); - + return result; } diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_cast.c blender-2.62/source/blender/modifiers/intern/MOD_cast.c --- blender-2.61/source/blender/modifiers/intern/MOD_cast.c 2011-12-13 19:49:28.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_cast.c 2012-02-15 19:34:17.000000000 +0000 @@ -76,7 +76,7 @@ tcmd->flag = cmd->flag; tcmd->type = cmd->type; tcmd->object = cmd->object; - BLI_strncpy(tcmd->defgrp_name, cmd->defgrp_name, 32); + BLI_strncpy(tcmd->defgrp_name, cmd->defgrp_name, sizeof(tcmd->defgrp_name)); } static int isDisabled(ModifierData *md, int UNUSED(useRenderParams)) @@ -159,7 +159,7 @@ if (ctrl_ob) { if(flag & MOD_CAST_USE_OB_TRANSFORM) { invert_m4_m4(ctrl_ob->imat, ctrl_ob->obmat); - mul_m4_m4m4(mat, ob->obmat, ctrl_ob->imat); + mult_m4_m4m4(mat, ctrl_ob->imat, ob->obmat); invert_m4_m4(imat, mat); } @@ -200,11 +200,11 @@ * with or w/o a vgroup. With lots of if's in the code below, * further optimizations are possible, if needed */ if (dvert) { /* with a vgroup */ + MDeformVert *dv= dvert; float fac_orig = fac; - for (i = 0; i < numVerts; i++) { - MDeformWeight *dw = NULL; - int j; + for (i = 0; i < numVerts; i++, dv++) { float tmp_co[3]; + float weight; copy_v3_v3(tmp_co, vertexCos[i]); if(ctrl_ob) { @@ -224,15 +224,10 @@ if (len_v3(vec) > cmd->radius) continue; } - for (j = 0; j < dvert[i].totweight; ++j) { - if(dvert[i].dw[j].def_nr == defgrp_index) { - dw = &dvert[i].dw[j]; - break; - } - } - if (!dw) continue; + weight= defvert_find_weight(dv, defgrp_index); + if (weight <= 0.0f) continue; - fac = fac_orig * dw->weight; + fac = fac_orig * weight; facm = 1.0f - fac; normalize_v3(vec); @@ -336,7 +331,7 @@ if (ctrl_ob) { if(flag & MOD_CAST_USE_OB_TRANSFORM) { invert_m4_m4(ctrl_ob->imat, ctrl_ob->obmat); - mul_m4_m4m4(mat, ob->obmat, ctrl_ob->imat); + mult_m4_m4m4(mat, ctrl_ob->imat, ob->obmat); invert_m4_m4(imat, mat); } diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_cloth.c blender-2.62/source/blender/modifiers/intern/MOD_cloth.c --- blender-2.61/source/blender/modifiers/intern/MOD_cloth.c 2011-12-13 19:49:28.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_cloth.c 2012-02-15 19:34:17.000000000 +0000 @@ -67,11 +67,10 @@ cloth_init (clmd); } -static DerivedMesh *applyModifier(ModifierData *md, Object *ob, - DerivedMesh *dm, - int UNUSED(useRenderParams), - int UNUSED(isFinalCalc)) +static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], + int UNUSED(numVerts), int UNUSED(useRenderParams), int UNUSED(isFinalCalc)) { + DerivedMesh *dm; ClothModifierData *clmd = (ClothModifierData*) md; DerivedMesh *result=NULL; @@ -79,19 +78,25 @@ if(!clmd->sim_parms || !clmd->coll_parms) { initData(md); - + if(!clmd->sim_parms || !clmd->coll_parms) - return dm; + return; } - result = clothModifier_do(clmd, md->scene, ob, dm); + dm = get_dm(ob, NULL, derivedData, NULL, 0); + if(dm == derivedData) + dm = CDDM_copy(dm); - if(result) - { - CDDM_calc_normals(result); - return result; + CDDM_apply_vert_coords(dm, vertexCos); + + clothModifier_do(clmd, md->scene, ob, dm, vertexCos); + + if(result) { + result->getVertCos(result, vertexCos); + result->release(result); } - return dm; + + dm->release(dm); } static void updateDepgraph( @@ -206,17 +211,17 @@ /* name */ "Cloth", /* structName */ "ClothModifierData", /* structSize */ sizeof(ClothModifierData), - /* type */ eModifierTypeType_Nonconstructive, + /* type */ eModifierTypeType_OnlyDeform, /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_UsesPointCache | eModifierTypeFlag_Single, /* copyData */ copyData, - /* deformVerts */ NULL, + /* deformVerts */ deformVerts, /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, + /* applyModifier */ NULL, /* applyModifierEM */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_curve.c blender-2.62/source/blender/modifiers/intern/MOD_curve.c --- blender-2.61/source/blender/modifiers/intern/MOD_curve.c 2011-12-13 19:49:28.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_curve.c 2012-02-15 19:34:17.000000000 +0000 @@ -64,7 +64,7 @@ tcmd->defaxis = cmd->defaxis; tcmd->object = cmd->object; - BLI_strncpy(tcmd->name, cmd->name, 32); + BLI_strncpy(tcmd->name, cmd->name, sizeof(tcmd->name)); } static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) @@ -119,8 +119,10 @@ { CurveModifierData *cmd = (CurveModifierData*) md; + /* silly that defaxis and curve_deform_verts are off by 1 + * but leave for now to save having to call do_versions */ curve_deform_verts(md->scene, cmd->object, ob, derivedData, vertexCos, numVerts, - cmd->name, cmd->defaxis); + cmd->name, cmd->defaxis-1); } static void deformVertsEM( diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_decimate.c blender-2.62/source/blender/modifiers/intern/MOD_decimate.c --- blender-2.61/source/blender/modifiers/intern/MOD_decimate.c 2011-12-13 19:49:28.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_decimate.c 2012-02-15 19:34:17.000000000 +0000 @@ -38,13 +38,13 @@ #include "BLI_math.h" #include "BLI_utildefines.h" +#include "MEM_guardedalloc.h" -#include "BKE_cdderivedmesh.h" #include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_particle.h" +#include "BKE_cdderivedmesh.h" -#include "MEM_guardedalloc.h" #ifdef WITH_MOD_DECIMATE #include "LOD_decimation.h" diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_displace.c blender-2.62/source/blender/modifiers/intern/MOD_displace.c --- blender-2.61/source/blender/modifiers/intern/MOD_displace.c 2011-12-13 19:49:28.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_displace.c 2012-02-15 19:34:17.000000000 +0000 @@ -74,11 +74,11 @@ tdmd->texture = dmd->texture; tdmd->strength = dmd->strength; tdmd->direction = dmd->direction; - BLI_strncpy(tdmd->defgrp_name, dmd->defgrp_name, 32); + BLI_strncpy(tdmd->defgrp_name, dmd->defgrp_name, sizeof(tdmd->defgrp_name)); tdmd->midlevel = dmd->midlevel; tdmd->texmapping = dmd->texmapping; tdmd->map_object = dmd->map_object; - BLI_strncpy(tdmd->uvlayer_name, dmd->uvlayer_name, 32); + BLI_strncpy(tdmd->uvlayer_name, dmd->uvlayer_name, sizeof(tdmd->uvlayer_name)); } static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_dynamicpaint.c blender-2.62/source/blender/modifiers/intern/MOD_dynamicpaint.c --- blender-2.61/source/blender/modifiers/intern/MOD_dynamicpaint.c 2011-12-13 19:49:28.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_dynamicpaint.c 2012-02-15 19:34:17.000000000 +0000 @@ -1,16 +1,29 @@ /* -* ***** BEGIN GPL LICENSE BLOCK ***** -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* as published by the Free Software Foundation; either version 2 -* of the License, or (at your option) any later version. -* -* Contributor(s): Miika Hämäläinen -* -* ***** END GPL LICENSE BLOCK ***** -* -*/ + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + * Contributor(s): Miika Hämäläinen + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/modifiers/intern/MOD_dynamicpaint.c + * \ingroup modifiers + */ #include @@ -157,8 +170,10 @@ /* structSize */ sizeof(DynamicPaintModifierData), /* type */ eModifierTypeType_Constructive, /* flags */ eModifierTypeFlag_AcceptsMesh - | eModifierTypeFlag_UsesPointCache - | eModifierTypeFlag_Single, +/* |eModifierTypeFlag_SupportsMapping*/ + |eModifierTypeFlag_UsesPointCache + |eModifierTypeFlag_Single + |eModifierTypeFlag_UsesPreview, /* copyData */ copyData, /* deformVerts */ NULL, diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_edgesplit.c blender-2.62/source/blender/modifiers/intern/MOD_edgesplit.c --- blender-2.61/source/blender/modifiers/intern/MOD_edgesplit.c 2011-12-13 19:49:28.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_edgesplit.c 2012-02-15 19:34:17.000000000 +0000 @@ -47,12 +47,12 @@ #include "BLI_utildefines.h" #include "BLI_linklist.h" +#include "MEM_guardedalloc.h" #include "BKE_cdderivedmesh.h" #include "BKE_modifier.h" #include "BKE_particle.h" -#include "MEM_guardedalloc.h" #include "MOD_util.h" diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_explode.c blender-2.62/source/blender/modifiers/intern/MOD_explode.c --- blender-2.61/source/blender/modifiers/intern/MOD_explode.c 2011-12-13 19:49:28.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_explode.c 2012-02-15 19:34:17.000000000 +0000 @@ -556,10 +556,11 @@ int *vertpa = MEM_callocN(sizeof(int)*totvert,"explode_vertpa2"); int *facepa = emd->facepa; int *fs, totesplit=0,totfsplit=0,curdupface=0; - int i,j,v1,v2,v3,v4,esplit, + int i, v1, v2, v3, v4, esplit, v[4] = {0, 0, 0, 0}, /* To quite gcc barking... */ uv[4] = {0, 0, 0, 0}; /* To quite gcc barking... */ int numlayer; + unsigned int ed_v1, ed_v2; edgehash= BLI_edgehash_new(); @@ -650,16 +651,16 @@ /* create new verts */ ehi= BLI_edgehashIterator_new(edgehash); for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) { - BLI_edgehashIterator_getKey(ehi, &i, &j); + BLI_edgehashIterator_getKey(ehi, &ed_v1, &ed_v2); esplit= GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi)); - mv=CDDM_get_vert(splitdm,j); + mv=CDDM_get_vert(splitdm, ed_v2); dupve=CDDM_get_vert(splitdm,esplit); - DM_copy_vert_data(splitdm,splitdm,j,esplit,1); + DM_copy_vert_data(splitdm,splitdm, ed_v2, esplit,1); *dupve=*mv; - mv=CDDM_get_vert(splitdm,i); + mv=CDDM_get_vert(splitdm, ed_v1); add_v3_v3(dupve->co, mv->co); mul_v3_fl(dupve->co, 0.5f); @@ -788,8 +789,9 @@ float cfra; /* float timestep; */ int *facepa=emd->facepa; - int totdup=0,totvert=0,totface=0,totpart=0; - int i, j, v, mindex=0; + int totdup=0,totvert=0,totface=0,totpart=0,delface=0; + int i, v, u; + unsigned int ed_v1, ed_v2, mindex=0; MTFace *mtface = NULL, *mtf; totface= dm->getNumFaces(dm); @@ -810,6 +812,18 @@ vertpahash= BLI_edgehash_new(); for (i=0; ialive==PARS_UNBORN && (emd->flag&eExplodeFlag_Unborn)==0) + || (pa->alive==PARS_ALIVE && (emd->flag&eExplodeFlag_Alive)==0) + || (pa->alive==PARS_DEAD && (emd->flag&eExplodeFlag_Dead)==0)) { + delface++; + continue; + } + } + /* do mindex + totvert to ensure the vertex index to be the first * with BLI_edgehashIterator_getKey */ if(facepa[i]==totpart || cfra < (pars+facepa[i])->time) @@ -836,7 +850,7 @@ BLI_edgehashIterator_free(ehi); /* the final duplicated vertices */ - explode= CDDM_from_template(dm, totdup, 0,totface); + explode= CDDM_from_template(dm, totdup, 0,totface-delface); mtface = CustomData_get_layer_named(&explode->faceData, CD_MTFACE, emd->uvname); /*dupvert= CDDM_get_verts(explode);*/ @@ -852,24 +866,24 @@ MVert *dest; /* get particle + vertex from hash */ - BLI_edgehashIterator_getKey(ehi, &j, &i); - i -= totvert; + BLI_edgehashIterator_getKey(ehi, &ed_v1, &ed_v2); + ed_v2 -= totvert; v= GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi)); - dm->getVert(dm, j, &source); + dm->getVert(dm, ed_v1, &source); dest = CDDM_get_vert(explode,v); - DM_copy_vert_data(dm,explode,j,v,1); + DM_copy_vert_data(dm, explode, ed_v1, v, 1); *dest = source; - if(i!=totpart) { + if(ed_v2 != totpart) { /* get particle */ - pa= pars+i; + pa= pars + ed_v2; psys_get_birth_coordinates(&sim, pa, &birth, 0, 0); state.time=cfra; - psys_get_particle_state(&sim, i, &state, 1); + psys_get_particle_state(&sim, ed_v2, &state, 1); vertco=CDDM_get_vert(explode,v)->co; mul_m4_v3(ob->obmat,vertco); @@ -891,7 +905,7 @@ BLI_edgehashIterator_free(ehi); /*map new vertices to faces*/ - for (i=0; igetFace(dm,i,&source); - mf=CDDM_get_face(explode,i); + mf=CDDM_get_face(explode,u); orig_v4 = source.v4; @@ -920,7 +934,7 @@ if(source.v4) source.v4 = edgecut_get(vertpahash, source.v4, mindex); - DM_copy_face_data(dm,explode,i,i,1); + DM_copy_face_data(dm,explode,i,u,1); *mf = source; @@ -930,13 +944,14 @@ /* Clamp to this range to avoid flipping to the other side of the coordinates. */ CLAMP(age, 0.001f, 0.999f); - mtf = mtface + i; + mtf = mtface + u; mtf->uv[0][0] = mtf->uv[1][0] = mtf->uv[2][0] = mtf->uv[3][0] = age; mtf->uv[0][1] = mtf->uv[1][1] = mtf->uv[2][1] = mtf->uv[3][1] = 0.5f; } - test_index_face(mf, &explode->faceData, i, (orig_v4 ? 4 : 3)); + test_index_face(mf, &explode->faceData, u, (orig_v4 ? 4 : 3)); + u++; } /* cleanup */ diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_fluidsim_util.c blender-2.62/source/blender/modifiers/intern/MOD_fluidsim_util.c --- blender-2.61/source/blender/modifiers/intern/MOD_fluidsim_util.c 2011-12-13 19:49:28.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_fluidsim_util.c 2012-02-15 19:34:17.000000000 +0000 @@ -95,6 +95,7 @@ fss->animStart = 0.0; fss->animEnd = 4.0; + fss->animRate = 1.0; fss->gstar = 0.005; // used as normgstar fss->maxRefine = -1; // maxRefine is set according to resolutionxyz during bake @@ -151,9 +152,7 @@ void fluidsim_free(FluidsimModifierData *fluidmd) { -#ifdef WITH_MOD_FLUID - if(fluidmd) - { + if(fluidmd) { if(fluidmd->fss->meshVelocities) { MEM_freeN(fluidmd->fss->meshVelocities); @@ -161,16 +160,13 @@ } MEM_freeN(fluidmd->fss); } -#else - (void)fluidmd; /* unused */ -#endif return; } #ifdef WITH_MOD_FLUID /* read .bobj.gz file into a fluidsimDerivedMesh struct */ -static DerivedMesh *fluidsim_read_obj(const char *filename) +static DerivedMesh *fluidsim_read_obj(const char *filename, const MFace *mf_example) { int wri = 0,i; int gotBytes; @@ -182,6 +178,9 @@ short *normals, *no_s; float no[3]; + const short mf_mat_nr = mf_example->mat_nr; + const char mf_flag = mf_example->flag; + // ------------------------------------------------ // get numverts + numfaces first // ------------------------------------------------ @@ -286,6 +285,10 @@ gotBytes = gzread(gzf, face, sizeof(int) * 3); + /* initialize from existing face */ + mf->mat_nr = mf_mat_nr; + mf->flag = mf_flag; + // check if 3rd vertex has index 0 (not allowed in blender) if(face[2]) { @@ -451,8 +454,8 @@ FluidsimSettings *fss = fluidmd->fss; DerivedMesh *dm = NULL; MFace *mface; - int numfaces; - int mat_nr, flag, i; + MFace mf_example = {0}; + if(!useRenderParams) { displaymode = fss->guiDisplayMode; @@ -474,10 +477,21 @@ break; } + /* offset baked frame */ + curFrame += fss->frameOffset; + BLI_path_abs(targetFile, modifier_path_relbase(ob)); BLI_path_frame(targetFile, curFrame, 0); // fixed #frame-no - dm = fluidsim_read_obj(targetFile); + // assign material + flags to new dm + // if there's no faces in original dm, keep materials and flags unchanged + mface = orgdm->getFaceArray(orgdm); + if (mface) { + mf_example = *mface; + } + /* else leave NULL'd */ + + dm = fluidsim_read_obj(targetFile, &mf_example); if(!dm) { @@ -498,19 +512,6 @@ return NULL; } - // assign material + flags to new dm - mface = orgdm->getFaceArray(orgdm); - mat_nr = mface[0].mat_nr; - flag = mface[0].flag; - - mface = dm->getFaceArray(dm); - numfaces = dm->getNumFaces(dm); - for(i=0; itotindex = hmd->totindex; thmd->indexar = MEM_dupallocN(hmd->indexar); memcpy(thmd->parentinv, hmd->parentinv, sizeof(hmd->parentinv)); - BLI_strncpy(thmd->name, hmd->name, 32); - BLI_strncpy(thmd->subtarget, hmd->subtarget, 32); + BLI_strncpy(thmd->name, hmd->name, sizeof(thmd->name)); + BLI_strncpy(thmd->subtarget, hmd->subtarget, sizeof(thmd->subtarget)); } static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) @@ -157,7 +157,7 @@ /* get world-space matrix of target, corrected for the space the verts are in */ if (hmd->subtarget[0] && pchan) { /* bone target if there's a matching pose-channel */ - mul_m4_m4m4(dmat, pchan->pose_mat, hmd->object->obmat); + mult_m4_m4m4(dmat, hmd->object->obmat, pchan->pose_mat); } else { /* just object target */ @@ -249,15 +249,25 @@ int UNUSED(useRenderParams), int UNUSED(isFinalCalc)) { HookModifierData *hmd = (HookModifierData*) md; - - deformVerts_do(hmd, ob, derivedData, vertexCos, numVerts); + DerivedMesh *dm = derivedData; + /* We need a valid dm for meshes when a vgroup is set... */ + if(!dm && ob->type == OB_MESH && hmd->name[0] != '\0') + dm = get_dm(ob, NULL, dm, NULL, 0); + + deformVerts_do(hmd, ob, dm, vertexCos, numVerts); + + if(derivedData != dm) + dm->release(dm); } static void deformVertsEM(ModifierData *md, Object *ob, struct EditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { HookModifierData *hmd = (HookModifierData*) md; - DerivedMesh *dm = get_dm(ob, editData, derivedData, NULL, 0); + DerivedMesh *dm = derivedData; + /* We need a valid dm for meshes when a vgroup is set... */ + if(!dm && ob->type == OB_MESH && hmd->name[0] != '\0') + dm = get_dm(ob, editData, dm, NULL, 0); deformVerts_do(hmd, ob, dm, vertexCos, numVerts); diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_lattice.c blender-2.62/source/blender/modifiers/intern/MOD_lattice.c --- blender-2.61/source/blender/modifiers/intern/MOD_lattice.c 2011-12-13 19:49:28.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_lattice.c 2012-02-15 19:34:17.000000000 +0000 @@ -56,7 +56,7 @@ LatticeModifierData *tlmd = (LatticeModifierData*) target; tlmd->object = lmd->object; - BLI_strncpy(tlmd->name, lmd->name, 32); + BLI_strncpy(tlmd->name, lmd->name, sizeof(tlmd->name)); } static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_meshdeform.c blender-2.62/source/blender/modifiers/intern/MOD_meshdeform.c --- blender-2.61/source/blender/modifiers/intern/MOD_meshdeform.c 2011-12-13 19:49:28.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_meshdeform.c 2012-02-15 19:34:17.000000000 +0000 @@ -188,7 +188,6 @@ struct EditMesh *em = (me)? BKE_mesh_get_editmesh(me): NULL; DerivedMesh *tmpdm, *cagedm; MDeformVert *dvert = NULL; - MDeformWeight *dw; MDefInfluence *influences; int *offsets; float imat[4][4], cagemat[4][4], iobmat[4][4], icagemat[3][3], cmat[4][4]; @@ -224,8 +223,8 @@ /* compute matrices to go in and out of cage object space */ invert_m4_m4(imat, mmd->object->obmat); - mul_m4_m4m4(cagemat, ob->obmat, imat); - mul_m4_m4m4(cmat, cagemat, mmd->bindmat); + mult_m4_m4m4(cagemat, imat, ob->obmat); + mult_m4_m4m4(cmat, mmd->bindmat, cagemat); invert_m4_m4(iobmat, cmat); copy_m3_m4(icagemat, iobmat); @@ -293,21 +292,14 @@ continue; if(dvert) { - for(dw=NULL, a=0; aflag & MOD_MDEF_INVERT_VGROUP) { - if(!dw) fac= 1.0f; - else if(dw->weight == 1.0f) continue; - else fac=1.0f-dw->weight; + if (mmd->flag & MOD_MDEF_INVERT_VGROUP) { + fac= 1.0f - fac; } - else { - if(!dw) continue; - else fac= dw->weight; + + if (fac <= 0.0f) { + continue; } } diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_mirror.c blender-2.62/source/blender/modifiers/intern/MOD_mirror.c --- blender-2.61/source/blender/modifiers/intern/MOD_mirror.c 2011-12-13 19:49:28.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_mirror.c 2012-02-15 19:34:17.000000000 +0000 @@ -95,10 +95,9 @@ } static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, - Object *ob, - DerivedMesh *dm, - int initFlags, - int axis) + Object *ob, + DerivedMesh *dm, + int axis) { int i; float tolerance = mmd->tolerance; @@ -109,7 +108,7 @@ int maxFaces = dm->getNumFaces(dm); int *flip_map= NULL, flip_map_len= 0; int do_vgroup_mirr= (mmd->flag & MOD_MIR_VGROUP); - int (*indexMap)[2]; + unsigned int (*indexMap)[2]; float mtx[4][4], imtx[4][4]; numVerts = numEdges = numFaces = 0; @@ -129,7 +128,7 @@ float obinv[4][4]; invert_m4_m4(obinv, mmd->mirror_ob->obmat); - mul_m4_m4m4(mtx, ob->obmat, obinv); + mult_m4_m4m4(mtx, obinv, ob->obmat); invert_m4_m4(imtx, mtx); } @@ -153,25 +152,27 @@ isShared = ABS(co[axis])<=tolerance; /* Because the topology result (# of vertices) must be the same if - * the mesh data is overridden by vertex cos, have to calc sharedness - * based on original coordinates. This is why we test before copy. - */ + * the mesh data is overridden by vertex cos, have to calc sharedness + * based on original coordinates. This is why we test before copy. + */ DM_copy_vert_data(dm, result, i, numVerts, 1); *mv = inMV; - numVerts++; - - indexMap[i][0] = numVerts - 1; + + indexMap[i][0] = numVerts; indexMap[i][1] = !isShared; - // + + numVerts++; + if(isShared ) { - co[axis] = 0; + co[axis] = 0.0f; if (mmd->mirror_ob) { mul_m4_v3(imtx, co); } copy_v3_v3(mv->co, co); mv->flag |= ME_VERT_MERGED; - } else { + } + else { MVert *mv2 = CDDM_get_vert(result, numVerts); DM_copy_vert_data(dm, result, i, numVerts, 1); @@ -206,8 +207,6 @@ med->v1 = indexMap[inMED.v1][0]; med->v2 = indexMap[inMED.v2][0]; - if(initFlags) - med->flag |= ME_EDGEDRAW | ME_EDGERENDER; if(indexMap[inMED.v1][1] || indexMap[inMED.v2][1]) { MEdge *med2 = CDDM_get_edge(result, numEdges); @@ -236,10 +235,11 @@ mf->v3 = indexMap[inMF.v3][0]; mf->v4 = indexMap[inMF.v4][0]; - if(indexMap[inMF.v1][1] - || indexMap[inMF.v2][1] - || indexMap[inMF.v3][1] - || (mf->v4 && indexMap[inMF.v4][1])) { + if ( indexMap[inMF.v1][1] || + indexMap[inMF.v2][1] || + indexMap[inMF.v3][1] || + (mf->v4 && indexMap[inMF.v4][1])) + { MFace *mf2 = CDDM_get_face(result, numFaces); static int corner_indices[4] = {2, 1, 0, 3}; @@ -266,7 +266,7 @@ } /* Flip face normal */ - SWAP(int, mf2->v1, mf2->v3); + SWAP(unsigned int, mf2->v1, mf2->v3); DM_swap_face_data(result, numFaces, corner_indices); test_index_face(mf2, &result->faceData, numFaces, inMF.v4?4:3); @@ -286,23 +286,22 @@ } static DerivedMesh *mirrorModifier__doMirror(MirrorModifierData *mmd, - Object *ob, DerivedMesh *dm, - int initFlags) + Object *ob, DerivedMesh *dm) { DerivedMesh *result = dm; /* check which axes have been toggled and mirror accordingly */ if(mmd->flag & MOD_MIR_AXIS_X) { - result = doMirrorOnAxis(mmd, ob, result, initFlags, 0); + result = doMirrorOnAxis(mmd, ob, result, 0); } if(mmd->flag & MOD_MIR_AXIS_Y) { DerivedMesh *tmp = result; - result = doMirrorOnAxis(mmd, ob, result, initFlags, 1); + result = doMirrorOnAxis(mmd, ob, result, 1); if(tmp != dm) tmp->release(tmp); /* free intermediate results */ } if(mmd->flag & MOD_MIR_AXIS_Z) { DerivedMesh *tmp = result; - result = doMirrorOnAxis(mmd, ob, result, initFlags, 2); + result = doMirrorOnAxis(mmd, ob, result, 2); if(tmp != dm) tmp->release(tmp); /* free intermediate results */ } @@ -317,7 +316,7 @@ DerivedMesh *result; MirrorModifierData *mmd = (MirrorModifierData*) md; - result = mirrorModifier__doMirror(mmd, ob, derivedData, 0); + result = mirrorModifier__doMirror(mmd, ob, derivedData); if(result != derivedData) CDDM_calc_normals(result); diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_multires.c blender-2.62/source/blender/modifiers/intern/MOD_multires.c --- blender-2.61/source/blender/modifiers/intern/MOD_multires.c 2011-12-13 19:49:28.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_multires.c 2012-02-15 19:34:17.000000000 +0000 @@ -35,14 +35,14 @@ #include +#include "DNA_mesh_types.h" + #include "BKE_cdderivedmesh.h" #include "BKE_multires.h" #include "BKE_modifier.h" #include "BKE_paint.h" #include "BKE_particle.h" -#include "DNA_mesh_types.h" - #include "MOD_util.h" static void initData(ModifierData *md) diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_remesh.c blender-2.62/source/blender/modifiers/intern/MOD_remesh.c --- blender-2.61/source/blender/modifiers/intern/MOD_remesh.c 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_remesh.c 2012-02-15 19:34:17.000000000 +0000 @@ -0,0 +1,227 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + * The Original Code is Copyright (C) 2011 by Nicholas Bishop. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/modifiers/intern/MOD_remesh.c + * \ingroup modifiers + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_math_vector.h" +#include "BLI_utildefines.h" + +#include "BKE_cdderivedmesh.h" +#include "BKE_DerivedMesh.h" +#include "BKE_mesh.h" + +#include "DNA_meshdata_types.h" +#include "DNA_modifier_types.h" +#include "DNA_object_types.h" + +#include "MOD_modifiertypes.h" + +#include +#include +#include + +#ifdef WITH_MOD_REMESH +# include "dualcon.h" +#endif + +static void initData(ModifierData *md) +{ + RemeshModifierData *rmd = (RemeshModifierData*) md; + + rmd->scale = 0.9; + rmd->depth = 4; + rmd->hermite_num = 1; + rmd->flag = MOD_REMESH_FLOOD_FILL; + rmd->mode = MOD_REMESH_SHARP_FEATURES; + rmd->threshold = 1; +} + +static void copyData(ModifierData *md, ModifierData *target) +{ + RemeshModifierData *rmd = (RemeshModifierData*) md; + RemeshModifierData *trmd = (RemeshModifierData*) target; + + trmd->threshold = rmd->threshold; + trmd->scale = rmd->scale; + trmd->hermite_num = rmd->hermite_num; + trmd->depth = rmd->depth; + trmd->flag = rmd->flag; + trmd->mode = rmd->mode; +} + +#ifdef WITH_MOD_REMESH + +static void init_dualcon_mesh(DualConInput *mesh, DerivedMesh *dm) +{ + memset(mesh, 0, sizeof(DualConInput)); + + mesh->co = (void*)dm->getVertArray(dm); + mesh->co_stride = sizeof(MVert); + mesh->totco = dm->getNumVerts(dm); + + mesh->faces = (void*)dm->getFaceArray(dm); + mesh->face_stride = sizeof(MFace); + mesh->totface = dm->getNumFaces(dm); + + dm->getMinMax(dm, mesh->min, mesh->max); +} + +/* simple structure to hold the output: a CDDM and two counters to + keep track of the current elements */ +typedef struct { + DerivedMesh *dm; + int curvert, curface; +} DualConOutput; + +/* allocate and initialize a DualConOutput */ +static void *dualcon_alloc_output(int totvert, int totquad) +{ + DualConOutput *output; + + if(!(output = MEM_callocN(sizeof(DualConOutput), + "DualConOutput"))) + return NULL; + + output->dm = CDDM_new(totvert, 0, totquad); + return output; +} + +static void dualcon_add_vert(void *output_v, const float co[3]) +{ + DualConOutput *output = output_v; + DerivedMesh *dm = output->dm; + + assert(output->curvert < dm->getNumVerts(dm)); + + copy_v3_v3(CDDM_get_verts(dm)[output->curvert].co, co); + output->curvert++; +} + +static void dualcon_add_quad(void *output_v, const int vert_indices[4]) +{ + DualConOutput *output = output_v; + DerivedMesh *dm = output->dm; + MFace *mface; + + assert(output->curface < dm->getNumFaces(dm)); + + mface = &CDDM_get_faces(dm)[output->curface]; + mface->v1 = vert_indices[0]; + mface->v2 = vert_indices[1]; + mface->v3 = vert_indices[2]; + mface->v4 = vert_indices[3]; + + if(test_index_face(mface, NULL, 0, 4)) + output->curface++; +} + +static DerivedMesh *applyModifier(ModifierData *md, + Object *UNUSED(ob), + DerivedMesh *dm, + int UNUSED(useRenderParams), + int UNUSED(isFinalCalc)) +{ + RemeshModifierData *rmd; + DualConOutput *output; + DualConInput input; + DerivedMesh *result; + DualConFlags flags = 0; + DualConMode mode = 0; + + rmd = (RemeshModifierData*)md; + + init_dualcon_mesh(&input, dm); + + if(rmd->flag & MOD_REMESH_FLOOD_FILL) + flags |= DUALCON_FLOOD_FILL; + + switch(rmd->mode) { + case MOD_REMESH_CENTROID: + mode = DUALCON_CENTROID; + break; + case MOD_REMESH_MASS_POINT: + mode = DUALCON_MASS_POINT; + break; + case MOD_REMESH_SHARP_FEATURES: + mode = DUALCON_SHARP_FEATURES; + break; + } + + output = dualcon(&input, + dualcon_alloc_output, + dualcon_add_vert, + dualcon_add_quad, + flags, + mode, + rmd->threshold, + rmd->hermite_num, + rmd->scale, + rmd->depth); + result = output->dm; + CDDM_lower_num_faces(result, output->curface); + MEM_freeN(output); + + CDDM_calc_edges(result); + CDDM_calc_normals(result); + + return result; +} + +#else /* !WITH_MOD_REMESH */ + +static DerivedMesh *applyModifier(ModifierData *UNUSED(md), Object *UNUSED(ob), + DerivedMesh *derivedData, + int UNUSED(useRenderParams), + int UNUSED(isFinalCalc)) +{ + return derivedData; +} + +#endif /* !WITH_MOD_REMESH */ + +ModifierTypeInfo modifierType_Remesh = { + /* name */ "Remesh", + /* structName */ "RemeshModifierData", + /* structSize */ sizeof(RemeshModifierData), + /* type */ eModifierTypeType_Nonconstructive, + /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode, + /* copyData */ copyData, + /* deformVerts */ NULL, + /* deformMatrices */ NULL, + /* deformVertsEM */ NULL, + /* deformMatricesEM */ NULL, + /* applyModifier */ applyModifier, + /* applyModifierEM */ NULL, + /* initData */ initData, + /* requiredDataMask */ NULL, + /* freeData */ NULL, + /* isDisabled */ NULL, + /* updateDepgraph */ NULL, + /* dependsOnTime */ NULL, + /* dependsOnNormals */ NULL, + /* foreachObjectLink */ NULL, + /* foreachIDLink */ NULL, +}; diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_screw.c blender-2.62/source/blender/modifiers/intern/MOD_screw.c --- blender-2.61/source/blender/modifiers/intern/MOD_screw.c 2011-12-13 19:49:28.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_screw.c 2012-02-15 19:34:17.000000000 +0000 @@ -145,12 +145,12 @@ int mface_index=0; int step; int i, j; - int i1,i2; + unsigned int i1, i2; int step_tot= useRenderParams ? ltmd->render_steps : ltmd->steps; const int do_flip = ltmd->flag & MOD_SCREW_NORMAL_FLIP ? 1 : 0; int maxVerts=0, maxEdges=0, maxFaces=0; - int totvert= dm->getNumVerts(dm); - int totedge= dm->getNumEdges(dm); + const unsigned int totvert= dm->getNumVerts(dm); + const unsigned int totedge= dm->getNumEdges(dm); char axis_char= 'X', close; float angle= ltmd->angle; @@ -197,7 +197,7 @@ /* calc the matrix relative to the axis object */ invert_m4_m4(mtx_tmp_a, ob->obmat); copy_m4_m4(mtx_tx_inv, ltmd->ob_axis->obmat); - mul_m4_m4m4(mtx_tx, mtx_tx_inv, mtx_tmp_a); + mult_m4_m4m4(mtx_tx, mtx_tmp_a, mtx_tx_inv); /* calc the axis vec */ mul_mat3_m4_v3(mtx_tx, axis_vec); /* only rotation component */ @@ -571,7 +571,7 @@ if (lt_iter.v == lt_iter.e->v1) { if (ed_loop_flip == 0) { /*printf("\t\t\tFlipping 0\n");*/ - SWAP(int, lt_iter.e->v1, lt_iter.e->v2); + SWAP(unsigned int, lt_iter.e->v1, lt_iter.e->v2); }/* else { printf("\t\t\tFlipping Not 0\n"); }*/ @@ -579,7 +579,7 @@ else if (lt_iter.v == lt_iter.e->v2) { if (ed_loop_flip == 1) { /*printf("\t\t\tFlipping 1\n");*/ - SWAP(int, lt_iter.e->v1, lt_iter.e->v2); + SWAP(unsigned int, lt_iter.e->v1, lt_iter.e->v2); }/* else { printf("\t\t\tFlipping Not 1\n"); }*/ @@ -771,8 +771,8 @@ } if( !mf_new->v3 || !mf_new->v4 ) { - SWAP(int, mf_new->v1, mf_new->v3); - SWAP(int, mf_new->v2, mf_new->v4); + SWAP(unsigned int, mf_new->v1, mf_new->v3); + SWAP(unsigned int, mf_new->v2, mf_new->v4); } mf_new->flag= ME_SMOOTH; origindex[mface_index]= ORIGINDEX_NONE; @@ -807,8 +807,8 @@ } if( !mf_new->v3 || !mf_new->v4 ) { - SWAP(int, mf_new->v1, mf_new->v3); - SWAP(int, mf_new->v2, mf_new->v4); + SWAP(unsigned int, mf_new->v1, mf_new->v3); + SWAP(unsigned int, mf_new->v2, mf_new->v4); } mf_new->flag= ME_SMOOTH; origindex[mface_index]= ORIGINDEX_NONE; diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_shrinkwrap.c blender-2.62/source/blender/modifiers/intern/MOD_shrinkwrap.c --- blender-2.61/source/blender/modifiers/intern/MOD_shrinkwrap.c 2011-12-13 19:49:28.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_shrinkwrap.c 2012-02-15 19:34:17.000000000 +0000 @@ -35,6 +35,8 @@ #include +#include "DNA_object_types.h" + #include "BLI_string.h" #include "BLI_utildefines.h" @@ -42,8 +44,6 @@ #include "BKE_modifier.h" #include "BKE_shrinkwrap.h" -#include "DNA_object_types.h" - #include "depsgraph_private.h" #include "MOD_util.h" diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_smooth.c blender-2.62/source/blender/modifiers/intern/MOD_smooth.c --- blender-2.61/source/blender/modifiers/intern/MOD_smooth.c 2011-12-13 19:49:28.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_smooth.c 2012-02-15 19:34:17.000000000 +0000 @@ -39,13 +39,12 @@ #include "BLI_utildefines.h" #include "BLI_string.h" +#include "MEM_guardedalloc.h" + #include "BKE_cdderivedmesh.h" #include "BKE_particle.h" #include "BKE_deform.h" - -#include "MEM_guardedalloc.h" - #include "MOD_modifiertypes.h" #include "MOD_util.h" @@ -68,7 +67,7 @@ tsmd->fac = smd->fac; tsmd->repeat = smd->repeat; tsmd->flag = smd->flag; - BLI_strncpy(tsmd->defgrp_name, smd->defgrp_name, 32); + BLI_strncpy(tsmd->defgrp_name, smd->defgrp_name, sizeof(tsmd->defgrp_name)); } static int isDisabled(ModifierData *md, int UNUSED(useRenderParams)) @@ -154,24 +153,19 @@ } if (dvert) { - for (i = 0; i < numVerts; i++) { - MDeformWeight *dw = NULL; + MDeformVert *dv= dvert; + for (i = 0; i < numVerts; i++, dv++) { float f, fm, facw, *fp, *v; - int k; short flag = smd->flag; v = vertexCos[i]; fp = &ftmp[i*3]; - for (k = 0; k < dvert[i].totweight; ++k) { - if(dvert[i].dw[k].def_nr == defgrp_index) { - dw = &dvert[i].dw[k]; - break; - } - } - if (!dw) continue; - f = fac * dw->weight; + f= defvert_find_weight(dv, defgrp_index); + if (f <= 0.0f) continue; + + f *= fac; fm = 1.0f - f; /* fp is the sum of uctmp[i] verts, so must be averaged */ diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_solidify.c blender-2.62/source/blender/modifiers/intern/MOD_solidify.c --- blender-2.61/source/blender/modifiers/intern/MOD_solidify.c 2011-12-13 19:49:28.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_solidify.c 2012-02-15 19:34:17.000000000 +0000 @@ -40,16 +40,16 @@ #include "BLI_utildefines.h" #include "BLI_string.h" +#include "MEM_guardedalloc.h" + #include "BKE_cdderivedmesh.h" #include "BKE_mesh.h" #include "BKE_particle.h" #include "BKE_deform.h" - #include "MOD_modifiertypes.h" #include "MOD_util.h" -#include "MEM_guardedalloc.h" typedef struct EdgeFaceRef { int f1; /* init as -1 */ @@ -75,8 +75,8 @@ /* we don't want to overwrite any referenced layers */ /* - Dosnt work here! - mv = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT); + Doesn't work here! + mv = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, numVerts); cddm->mvert = mv; */ @@ -93,22 +93,28 @@ EdgeHash *edge_hash = BLI_edgehash_new(); EdgeHashIterator *edge_iter; int edge_ref_count = 0; - int ed_v1, ed_v2; /* use when getting the key */ + unsigned int ed_v1, ed_v2; /* use when getting the key */ EdgeFaceRef *edge_ref_array = MEM_callocN(numEdges * sizeof(EdgeFaceRef), "Edge Connectivity"); EdgeFaceRef *edge_ref; float edge_normal[3]; /* This function adds an edge hash if its not there, and adds the face index */ #define NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(EDV1, EDV2); \ - edge_ref = (EdgeFaceRef *)BLI_edgehash_lookup(edge_hash, EDV1, EDV2); \ + { \ + const unsigned int ml_v1 = EDV1; \ + const unsigned int ml_v2 = EDV2; \ + edge_ref = (EdgeFaceRef *)BLI_edgehash_lookup(edge_hash, ml_v1, ml_v2); \ if (!edge_ref) { \ edge_ref = &edge_ref_array[edge_ref_count]; edge_ref_count++; \ - edge_ref->f1=i; \ - edge_ref->f2=-1; \ - BLI_edgehash_insert(edge_hash, EDV1, EDV2, edge_ref); \ - } else { \ - edge_ref->f2=i; \ - } + edge_ref->f1 = i; \ + edge_ref->f2 =- 1; \ + BLI_edgehash_insert(edge_hash, ml_v1, ml_v2, edge_ref); \ + } \ + else { \ + edge_ref->f2 = i; \ + } \ + } + /* --- end define --- */ for(i = 0; i < numFaces; i++, mf++) { f_no = face_nors[i]; @@ -133,7 +139,7 @@ for(edge_iter = BLI_edgehashIterator_new(edge_hash); !BLI_edgehashIterator_isDone(edge_iter); BLI_edgehashIterator_step(edge_iter)) { /* Get the edge vert indices, and edge value (the face indices that use it)*/ - BLI_edgehashIterator_getKey(edge_iter, (int*)&ed_v1, (int*)&ed_v2); + BLI_edgehashIterator_getKey(edge_iter, &ed_v1, &ed_v2); edge_ref = BLI_edgehashIterator_getValue(edge_iter); if (edge_ref->f2 != -1) { @@ -250,7 +256,7 @@ if(smd->flag & MOD_SOLIDIFY_RIM) { EdgeHash *edgehash = BLI_edgehash_new(); EdgeHashIterator *ehi; - int v1, v2; + unsigned int v1, v2; int eidx; for(i=0, mv=orig_mvert; iv1 < ed->v2) ? i:(i+numFaces); \ - edge_order[eidx]= edge_ord; \ - } else { \ - edge_users[eidx]= INVALID_PAIR; \ - } \ + { \ + const unsigned int ml_v1 = _v1; \ + const unsigned int ml_v2 = _v2; \ + eidx= GET_INT_FROM_POINTER(BLI_edgehash_lookup(edgehash, ml_v1, ml_v2)); \ + if(edge_users[eidx] == INVALID_UNUSED) { \ + ed= orig_medge + eidx; \ + edge_users[eidx] = (ml_v1 < ml_v2) == (ed->v1 < ed->v2) ? i : (i + numFaces); \ + edge_order[eidx] = edge_ord; \ + } \ + else { \ + edge_users[eidx] = INVALID_PAIR; \ + } \ + } edge_users= MEM_mallocN(sizeof(int) * numEdges, "solid_mod edges"); @@ -350,7 +361,7 @@ { static int corner_indices[4] = {2, 1, 0, 3}; - int is_quad; + unsigned int is_quad; for(i=0, mf=mface+numFaces; iv1 += numVerts; @@ -362,7 +373,7 @@ /* Flip face normal */ { is_quad = mf->v4; - SWAP(int, mf->v1, mf->v3); + SWAP(unsigned int, mf->v1, mf->v3); DM_swap_face_data(result, i+numFaces, corner_indices); test_index_face(mf, &result->faceData, numFaces, is_quad ? 4:3); } @@ -543,11 +554,18 @@ const unsigned char crease_outer= smd->crease_outer * 255.0f; const unsigned char crease_inner= smd->crease_inner * 255.0f; - const int edge_indices[4][4] = { - {1, 0, 0, 1}, - {2, 1, 1, 2}, - {3, 2, 2, 3}, - {0, 3, 3, 0}}; + const int edge_indices[2][4][4] = { + /* quad */ + {{1, 0, 0, 1}, + {2, 1, 1, 2}, + {3, 2, 2, 3}, + {0, 3, 3, 0}}, + /* tri */ + {{1, 0, 0, 1}, + {2, 1, 1, 2}, + {0, 2, 2, 0}, + {0, 0, 0, 0}} /* unused for tris */ + }; /* add faces & edges */ origindex= result->getEdgeDataArray(result, CD_ORIGINDEX); @@ -565,11 +583,12 @@ /* faces */ mf= mface + (numFaces * 2); - origindex= result->getFaceDataArray(result, CD_ORIGINDEX); + for(i=0; i= numFaces) { fidx -= numFaces; @@ -584,8 +603,10 @@ /* copy most of the face settings */ DM_copy_face_data(dm, result, fidx, (numFaces * 2) + i, 1); + is_tri = (orig_mface[fidx].v4 == 0); + if(flip) { - DM_swap_face_data(result, (numFaces * 2) + i, edge_indices[edge_order[eidx]]); + DM_swap_face_data(result, (numFaces * 2) + i, edge_indices[is_tri][edge_order[eidx]]); mf->v1= ed->v1; mf->v2= ed->v2; @@ -593,7 +614,7 @@ mf->v4= ed->v1 + numVerts; } else { - DM_swap_face_data(result, (numFaces * 2) + i, edge_indices[edge_order[eidx]]); + DM_swap_face_data(result, (numFaces * 2) + i, edge_indices[is_tri][edge_order[eidx]]); mf->v1= ed->v2; mf->v2= ed->v1; diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_util.c blender-2.62/source/blender/modifiers/intern/MOD_util.c --- blender-2.61/source/blender/modifiers/intern/MOD_util.c 2011-12-13 19:49:28.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_util.c 2012-02-15 19:34:17.000000000 +0000 @@ -99,7 +99,7 @@ char *done = MEM_callocN(sizeof(*done) * numVerts, "get_texture_coords done"); int numFaces = dm->getNumFaces(dm); - char uvname[32]; + char uvname[MAX_CUSTOMDATA_LAYER_NAME]; MTFace *tf; CustomData_validate_layer_name(&dm->faceData, CD_MTFACE, dmd->uvlayer_name, uvname); @@ -107,36 +107,19 @@ /* verts are given the UV from the first face that uses them */ for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tf) { - if(!done[mf->v1]) { - texco[mf->v1][0] = tf->uv[0][0]; - texco[mf->v1][1] = tf->uv[0][1]; - texco[mf->v1][2] = 0; - done[mf->v1] = 1; - } - if(!done[mf->v2]) { - texco[mf->v2][0] = tf->uv[1][0]; - texco[mf->v2][1] = tf->uv[1][1]; - texco[mf->v2][2] = 0; - done[mf->v2] = 1; - } - if(!done[mf->v3]) { - texco[mf->v3][0] = tf->uv[2][0]; - texco[mf->v3][1] = tf->uv[2][1]; - texco[mf->v3][2] = 0; - done[mf->v3] = 1; - } - if(!done[mf->v4]) { - texco[mf->v4][0] = tf->uv[3][0]; - texco[mf->v4][1] = tf->uv[3][1]; - texco[mf->v4][2] = 0; - done[mf->v4] = 1; - } - } + unsigned int fidx= mf->v4 ? 3:2; + + do { + unsigned int vidx = *(&mf->v1 + fidx); + + if (done[vidx] == 0) { + /* remap UVs from [0, 1] to [-1, 1] */ + texco[vidx][0] = (tf->uv[fidx][0] * 2.0f) - 1.0f; + texco[vidx][1] = (tf->uv[fidx][1] * 2.0f) - 1.0f; + done[vidx] = 1; + } - /* remap UVs from [0, 1] to [-1, 1] */ - for(i = 0; i < numVerts; ++i) { - texco[i][0] = texco[i][0] * 2 - 1; - texco[i][1] = texco[i][1] * 2 - 1; + } while (fidx--); } MEM_freeN(done); @@ -276,5 +259,6 @@ INIT_TYPE(WeightVGMix); INIT_TYPE(WeightVGProximity); INIT_TYPE(DynamicPaint); + INIT_TYPE(Remesh); #undef INIT_TYPE } diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_uvproject.c blender-2.62/source/blender/modifiers/intern/MOD_uvproject.c --- blender-2.61/source/blender/modifiers/intern/MOD_uvproject.c 2011-12-13 19:49:28.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_uvproject.c 2012-02-15 19:34:17.000000000 +0000 @@ -155,7 +155,7 @@ Projector projectors[MOD_UVPROJECT_MAXPROJECTORS]; int num_projectors = 0; float aspect; - char uvname[32]; + char uvname[MAX_CUSTOMDATA_LAYER_NAME]; float aspx= umd->aspectx ? umd->aspectx : 1.0f; float aspy= umd->aspecty ? umd->aspecty : 1.0f; float scax= umd->scalex ? umd->scalex : 1.0f; @@ -222,11 +222,11 @@ if(cam->type == CAM_PERSP) { float perspmat[4][4]; perspective_m4( perspmat,xmin, xmax, ymin, ymax, cam->clipsta, cam->clipend); - mul_m4_m4m4(tmpmat, projectors[i].projmat, perspmat); + mult_m4_m4m4(tmpmat, perspmat, projectors[i].projmat); } else { /* if(cam->type == CAM_ORTHO) */ float orthomat[4][4]; orthographic_m4( orthomat,xmin, xmax, ymin, ymax, cam->clipsta, cam->clipend); - mul_m4_m4m4(tmpmat, projectors[i].projmat, orthomat); + mult_m4_m4m4(tmpmat, orthomat, projectors[i].projmat); } } } else { @@ -250,7 +250,7 @@ } } - mul_m4_m4m4(projectors[i].projmat, tmpmat, offsetmat); + mult_m4_m4m4(projectors[i].projmat, offsetmat, tmpmat); /* calculate worldspace projector normal (for best projector test) */ projectors[i].normal[0] = 0; @@ -259,11 +259,12 @@ mul_mat3_m4_v3(projectors[i].ob->obmat, projectors[i].normal); } + numFaces = dm->getNumFaces(dm); + /* make sure we are not modifying the original UV map */ tface = CustomData_duplicate_referenced_layer_named(&dm->faceData, - CD_MTFACE, uvname); + CD_MTFACE, uvname, numFaces); - numVerts = dm->getNumVerts(dm); coords = MEM_callocN(sizeof(*coords) * numVerts, @@ -280,52 +281,40 @@ mul_project_m4_v3(projectors[0].projmat, *co); mface = dm->getFaceArray(dm); - numFaces = dm->getNumFaces(dm); /* apply coords as UVs, and apply image if tfaces are new */ for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tface) { if(override_image || !image || tface->tpage == image) { if(num_projectors == 1) { if(projectors[0].uci) { - project_from_camera(tface->uv[0], coords[mf->v1], projectors[0].uci); - project_from_camera(tface->uv[1], coords[mf->v2], projectors[0].uci); - project_from_camera(tface->uv[2], coords[mf->v3], projectors[0].uci); - if(mf->v3) - project_from_camera(tface->uv[3], coords[mf->v4], projectors[0].uci); + unsigned int fidx= mf->v4 ? 3:2; + do { + unsigned int vidx= *(&mf->v1 + fidx); + project_from_camera(tface->uv[fidx], coords[vidx], projectors[0].uci); + } while (fidx--); } else { /* apply transformed coords as UVs */ - tface->uv[0][0] = coords[mf->v1][0]; - tface->uv[0][1] = coords[mf->v1][1]; - tface->uv[1][0] = coords[mf->v2][0]; - tface->uv[1][1] = coords[mf->v2][1]; - tface->uv[2][0] = coords[mf->v3][0]; - tface->uv[2][1] = coords[mf->v3][1]; - if(mf->v4) { - tface->uv[3][0] = coords[mf->v4][0]; - tface->uv[3][1] = coords[mf->v4][1]; - } + unsigned int fidx= mf->v4 ? 3:2; + do { + unsigned int vidx= *(&mf->v1 + fidx); + copy_v2_v2(tface->uv[fidx], coords[vidx]); + } while (fidx--); } } else { /* multiple projectors, select the closest to face normal * direction */ - float co1[3], co2[3], co3[3], co4[3]; float face_no[3]; int j; Projector *best_projector; float best_dot; - copy_v3_v3(co1, coords[mf->v1]); - copy_v3_v3(co2, coords[mf->v2]); - copy_v3_v3(co3, coords[mf->v3]); - /* get the untransformed face normal */ if(mf->v4) { - copy_v3_v3(co4, coords[mf->v4]); - normal_quad_v3(face_no, co1, co2, co3, co4); + normal_quad_v3(face_no, coords[mf->v1], coords[mf->v2], coords[mf->v3], coords[mf->v4]); } else { - normal_tri_v3(face_no, co1, co2, co3); + normal_tri_v3(face_no, coords[mf->v1], coords[mf->v2], coords[mf->v3]); } /* find the projector which the face points at most directly @@ -344,30 +333,23 @@ } if(best_projector->uci) { - project_from_camera(tface->uv[0], coords[mf->v1], best_projector->uci); - project_from_camera(tface->uv[1], coords[mf->v2], best_projector->uci); - project_from_camera(tface->uv[2], coords[mf->v3], best_projector->uci); - if(mf->v3) - project_from_camera(tface->uv[3], coords[mf->v4], best_projector->uci); + unsigned int fidx= mf->v4 ? 3:2; + do { + unsigned int vidx= *(&mf->v1 + fidx); + project_from_camera(tface->uv[fidx], coords[vidx], best_projector->uci); + } while (fidx--); } else { - mul_project_m4_v3(best_projector->projmat, co1); - mul_project_m4_v3(best_projector->projmat, co2); - mul_project_m4_v3(best_projector->projmat, co3); - if(mf->v4) - mul_project_m4_v3(best_projector->projmat, co4); + unsigned int fidx= mf->v4 ? 3:2; + do { + unsigned int vidx= *(&mf->v1 + fidx); + float tco[3]; + + copy_v3_v3(tco, coords[vidx]); + mul_project_m4_v3(best_projector->projmat, tco); + copy_v2_v2(tface->uv[fidx], tco); - /* apply transformed coords as UVs */ - tface->uv[0][0] = co1[0]; - tface->uv[0][1] = co1[1]; - tface->uv[1][0] = co2[0]; - tface->uv[1][1] = co2[1]; - tface->uv[2][0] = co3[0]; - tface->uv[2][1] = co3[1]; - if(mf->v4) { - tface->uv[3][0] = co4[0]; - tface->uv[3][1] = co4[1]; - } + } while (fidx--); } } } @@ -415,7 +397,7 @@ /* name */ "UVProject", /* structName */ "UVProjectModifierData", /* structSize */ sizeof(UVProjectModifierData), - /* type */ eModifierTypeType_Nonconstructive, + /* type */ eModifierTypeType_NonGeometrical, /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_warp.c blender-2.62/source/blender/modifiers/intern/MOD_warp.c --- blender-2.61/source/blender/modifiers/intern/MOD_warp.c 2011-12-13 19:49:28.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_warp.c 2012-02-15 19:34:17.000000000 +0000 @@ -197,11 +197,11 @@ invert_m4_m4(obinv, ob->obmat); - mul_m4_m4m4(mat_from, wmd->object_from->obmat, obinv); - mul_m4_m4m4(mat_to, wmd->object_to->obmat, obinv); + mult_m4_m4m4(mat_from, obinv, wmd->object_from->obmat); + mult_m4_m4m4(mat_to, obinv, wmd->object_to->obmat); invert_m4_m4(tmat, mat_from); // swap? - mul_m4_m4m4(mat_final, mat_to, tmat); + mult_m4_m4m4(mat_final, tmat, mat_to); invert_m4_m4(mat_from_inv, mat_from); diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_wave.c blender-2.62/source/blender/modifiers/intern/MOD_wave.c --- blender-2.61/source/blender/modifiers/intern/MOD_wave.c 2011-12-13 19:49:28.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_wave.c 2012-02-15 19:34:17.000000000 +0000 @@ -73,7 +73,7 @@ wmd->lifetime= 0.0f; wmd->damp= 10.0f; wmd->falloff= 0.0f; - wmd->texmapping = MOD_WAV_MAP_LOCAL; + wmd->texmapping = MOD_DISP_MAP_LOCAL; wmd->defgrp_name[0] = 0; } @@ -97,7 +97,7 @@ twmd->texture = wmd->texture; twmd->map_object = wmd->map_object; twmd->texmapping = wmd->texmapping; - BLI_strncpy(twmd->defgrp_name, wmd->defgrp_name, 32); + BLI_strncpy(twmd->defgrp_name, wmd->defgrp_name, sizeof(twmd->defgrp_name)); } static int dependsOnTime(ModifierData *UNUSED(md)) @@ -160,7 +160,7 @@ /* ask for UV coordinates if we need them */ - if(wmd->texture && wmd->texmapping == MOD_WAV_MAP_UV) + if(wmd->texture && wmd->texmapping == MOD_DISP_MAP_UV) dataMask |= CD_MASK_MTFACE; /* ask for vertexgroups if we need them */ @@ -170,91 +170,6 @@ return dataMask; } -static void wavemod_get_texture_coords(WaveModifierData *wmd, Object *ob, - DerivedMesh *dm, - float (*co)[3], float (*texco)[3], - int numVerts) -{ - int i; - int texmapping = wmd->texmapping; - - if(texmapping == MOD_WAV_MAP_OBJECT) { - if(wmd->map_object) - invert_m4_m4(wmd->map_object->imat, wmd->map_object->obmat); - else /* if there is no map object, default to local */ - texmapping = MOD_WAV_MAP_LOCAL; - } - - /* UVs need special handling, since they come from faces */ - if(texmapping == MOD_WAV_MAP_UV) { - if(CustomData_has_layer(&dm->faceData, CD_MTFACE)) { - MFace *mface = dm->getFaceArray(dm); - MFace *mf; - char *done = MEM_callocN(sizeof(*done) * numVerts, - "get_texture_coords done"); - int numFaces = dm->getNumFaces(dm); - char uvname[32]; - MTFace *tf; - - CustomData_validate_layer_name(&dm->faceData, CD_MTFACE, wmd->uvlayer_name, uvname); - tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, uvname); - - /* verts are given the UV from the first face that uses them */ - for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tf) { - if(!done[mf->v1]) { - texco[mf->v1][0] = tf->uv[0][0]; - texco[mf->v1][1] = tf->uv[0][1]; - texco[mf->v1][2] = 0; - done[mf->v1] = 1; - } - if(!done[mf->v2]) { - texco[mf->v2][0] = tf->uv[1][0]; - texco[mf->v2][1] = tf->uv[1][1]; - texco[mf->v2][2] = 0; - done[mf->v2] = 1; - } - if(!done[mf->v3]) { - texco[mf->v3][0] = tf->uv[2][0]; - texco[mf->v3][1] = tf->uv[2][1]; - texco[mf->v3][2] = 0; - done[mf->v3] = 1; - } - if(!done[mf->v4]) { - texco[mf->v4][0] = tf->uv[3][0]; - texco[mf->v4][1] = tf->uv[3][1]; - texco[mf->v4][2] = 0; - done[mf->v4] = 1; - } - } - - /* remap UVs from [0, 1] to [-1, 1] */ - for(i = 0; i < numVerts; ++i) { - texco[i][0] = texco[i][0] * 2 - 1; - texco[i][1] = texco[i][1] * 2 - 1; - } - - MEM_freeN(done); - return; - } else /* if there are no UVs, default to local */ - texmapping = MOD_WAV_MAP_LOCAL; - } - - for(i = 0; i < numVerts; ++i, ++co, ++texco) { - switch(texmapping) { - case MOD_WAV_MAP_LOCAL: - copy_v3_v3(*texco, *co); - break; - case MOD_WAV_MAP_GLOBAL: - mul_v3_m4v3(*texco, ob->obmat, *co); - break; - case MOD_WAV_MAP_OBJECT: - mul_v3_m4v3(*texco, ob->obmat, *co); - mul_m4_v3(wmd->map_object->imat, *texco); - break; - } - } -} - static void waveModifier_do(WaveModifierData *md, Scene *scene, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int numVerts) @@ -279,7 +194,7 @@ float mat[4][4]; /* get the control object's location in local coordinates */ invert_m4_m4(ob->imat, ob->obmat); - mul_m4_m4m4(mat, wmd->objectcenter->obmat, ob->imat); + mult_m4_m4m4(mat, ob->imat, wmd->objectcenter->obmat); wmd->startx = mat[3][0]; wmd->starty = mat[3][1]; @@ -305,7 +220,7 @@ if(wmd->texture) { tex_co = MEM_mallocN(sizeof(*tex_co) * numVerts, "waveModifier_do tex_co"); - wavemod_get_texture_coords(wmd, ob, dm, vertexCos, tex_co, numVerts); + get_texture_coords((MappingInfoModifierData *)wmd, ob, dm, vertexCos, tex_co, numVerts); } if(lifefac != 0.0f) { diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_weightvgedit.c blender-2.62/source/blender/modifiers/intern/MOD_weightvgedit.c --- blender-2.61/source/blender/modifiers/intern/MOD_weightvgedit.c 2011-12-13 19:49:28.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_weightvgedit.c 2012-02-15 19:34:17.000000000 +0000 @@ -114,6 +114,8 @@ if(wmd->mask_tex_mapping == MOD_DISP_MAP_UV) dataMask |= CD_MASK_MTFACE; + /* No need to ask for CD_WEIGHT_MCOL... */ + return dataMask; } @@ -177,10 +179,7 @@ int UNUSED(useRenderParams), int UNUSED(isFinalCalc)) { WeightVGEditModifierData *wmd = (WeightVGEditModifierData*) md; - DerivedMesh *dm = derivedData, *ret = NULL; -#if 0 - Mesh *ob_m = NULL; -#endif + DerivedMesh *dm = derivedData; MDeformVert *dvert = NULL; MDeformWeight **dw = NULL; float *org_w; /* Array original weights. */ @@ -188,10 +187,13 @@ int numVerts; int defgrp_idx; int i; - char rel_ret = 0; /* Boolean, whether we have to release ret dm or not, when not using it! */ /* Flags. */ - int do_add = (wmd->edit_flags & MOD_WVG_EDIT_ADD2VG) != 0; - int do_rem = (wmd->edit_flags & MOD_WVG_EDIT_REMFVG) != 0; + int do_add = (wmd->edit_flags & MOD_WVG_EDIT_ADD2VG) != 0; + int do_rem = (wmd->edit_flags & MOD_WVG_EDIT_REMFVG) != 0; + /* Only do weight-preview in Object, Sculpt and Pose modes! */ +#if 0 + int do_prev = (wmd->modifier.mode & eModifierMode_DoWeightPreview); +#endif /* Get number of verts. */ numVerts = dm->getNumVerts(dm); @@ -207,49 +209,18 @@ if (defgrp_idx < 0) return dm; - /* XXX All this to avoid copying dm when not needed... However, it nearly doubles compute - * time! See scene 5 of the WeighVG test file... - */ -#if 0 - /* Get actual dverts (ie vertex group data). */ - dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); - /* If no dverts, return unmodified data... */ - if (dvert == NULL) - return dm; - - /* Get org mesh, only to test whether affected cdata layer has already been copied - * somewhere up in the modifiers stack. - */ - ob_m = get_mesh(ob); - if (ob_m == NULL) - return dm; - - /* Create a copy of our dmesh, only if our affected cdata layer is the same as org mesh. */ - if (dvert == CustomData_get_layer(&ob_m->vdata, CD_MDEFORMVERT)) { - /* XXX Seems to create problems with weightpaint mode??? - * I'm missing something here, I guess... - */ -// DM_set_only_copy(dm, CD_MASK_MDEFORMVERT); /* Only copy defgroup layer. */ - ret = CDDM_copy(dm); - dvert = ret->getVertDataArray(ret, CD_MDEFORMVERT); - if (dvert == NULL) { - ret->release(ret); + dvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MDEFORMVERT, numVerts); + /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */ + if(!dvert) + /* If this modifier is not allowed to add vertices, just return. */ + if(!do_add) + return dm; + /* Else, add a valid data layer! */ + dvert = CustomData_add_layer_named(&dm->vertData, CD_MDEFORMVERT, CD_CALLOC, + NULL, numVerts, wmd->defgrp_name); + /* Ultimate security check. */ + if(!dvert) return dm; - } - rel_ret = 1; - } - else - ret = dm; -#else - ret = CDDM_copy(dm); - rel_ret = 1; - dvert = ret->getVertDataArray(ret, CD_MDEFORMVERT); - if (dvert == NULL) { - if (rel_ret) - ret->release(ret); - return dm; - } -#endif /* Get org weights, assuming 0.0 for vertices not in given vgroup. */ org_w = MEM_mallocN(sizeof(float) * numVerts, "WeightVGEdit Modifier, org_w"); @@ -271,7 +242,7 @@ } /* Do masking. */ - weightvg_do_mask(numVerts, NULL, org_w, new_w, ob, ret, wmd->mask_constant, + weightvg_do_mask(numVerts, NULL, org_w, new_w, ob, dm, wmd->mask_constant, wmd->mask_defgrp_name, wmd->mask_texture, wmd->mask_tex_use_channel, wmd->mask_tex_mapping, wmd->mask_tex_map_obj, wmd->mask_tex_uvlayer_name); @@ -279,13 +250,19 @@ weightvg_update_vg(dvert, defgrp_idx, dw, numVerts, NULL, org_w, do_add, wmd->add_threshold, do_rem, wmd->rem_threshold); + /* If weight preview enabled... */ +#if 0 /* XXX Currently done in mod stack :/ */ + if(do_prev) + DM_update_weight_mcol(ob, dm, 0, org_w, 0, NULL); +#endif + /* Freeing stuff. */ MEM_freeN(org_w); MEM_freeN(new_w); MEM_freeN(dw); /* Return the vgroup-modified mesh. */ - return ret; + return dm; } static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob, @@ -300,10 +277,11 @@ /* name */ "VertexWeightEdit", /* structName */ "WeightVGEditModifierData", /* structSize */ sizeof(WeightVGEditModifierData), - /* type */ eModifierTypeType_Nonconstructive, + /* type */ eModifierTypeType_NonGeometrical, /* flags */ eModifierTypeFlag_AcceptsMesh -/* |eModifierTypeFlag_SupportsMapping*/ - |eModifierTypeFlag_SupportsEditmode, + |eModifierTypeFlag_SupportsMapping + |eModifierTypeFlag_SupportsEditmode + |eModifierTypeFlag_UsesPreview, /* copyData */ copyData, /* deformVerts */ NULL, diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_weightvgmix.c blender-2.62/source/blender/modifiers/intern/MOD_weightvgmix.c --- blender-2.61/source/blender/modifiers/intern/MOD_weightvgmix.c 2011-12-13 19:49:28.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_weightvgmix.c 2012-02-15 19:34:17.000000000 +0000 @@ -156,6 +156,8 @@ if(wmd->mask_tex_mapping == MOD_DISP_MAP_UV) dataMask |= CD_MASK_MTFACE; + /* No need to ask for CD_WEIGHT_MCOL... */ + return dataMask; } @@ -219,10 +221,7 @@ int UNUSED(useRenderParams), int UNUSED(isFinalCalc)) { WeightVGMixModifierData *wmd = (WeightVGMixModifierData*) md; - DerivedMesh *dm = derivedData, *ret = NULL; -#if 0 - Mesh *ob_m = NULL; -#endif + DerivedMesh *dm = derivedData; MDeformVert *dvert = NULL; MDeformWeight **dw1, **tdw1, **dw2, **tdw2; int numVerts; @@ -232,7 +231,10 @@ int *tidx, *indices = NULL; int numIdx = 0; int i; - char rel_ret = 0; /* Boolean, whether we have to release ret dm or not, when not using it! */ + /* Flags. */ +#if 0 + int do_prev = (wmd->modifier.mode & eModifierMode_DoWeightPreview); +#endif /* Get number of verts. */ numVerts = dm->getNumVerts(dm); @@ -254,49 +256,18 @@ return dm; } - /* XXX All this to avoid copying dm when not needed... However, it nearly doubles compute - * time! See scene 5 of the WeighVG test file... - */ -#if 0 - /* Get actual dverts (ie vertex group data). */ - dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); - /* If no dverts, return unmodified data... */ - if (dvert == NULL) - return dm; - - /* Get org mesh, only to test whether affected cdata layer has already been copied - * somewhere up in the modifiers stack. - */ - ob_m = get_mesh(ob); - if (ob_m == NULL) - return dm; - - /* Create a copy of our dmesh, only if our affected cdata layer is the same as org mesh. */ - if (dvert == CustomData_get_layer(&ob_m->vdata, CD_MDEFORMVERT)) { - /* XXX Seems to create problems with weightpaint mode??? - * I'm missing something here, I guess... - */ -// DM_set_only_copy(dm, CD_MASK_MDEFORMVERT); /* Only copy defgroup layer. */ - ret = CDDM_copy(dm); - dvert = ret->getVertDataArray(ret, CD_MDEFORMVERT); - if (dvert == NULL) { - ret->release(ret); + dvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MDEFORMVERT, numVerts); + /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */ + if(!dvert) + /* If not affecting all vertices, just return. */ + if(wmd->mix_set != MOD_WVG_SET_ALL) + return dm; + /* Else, add a valid data layer! */ + dvert = CustomData_add_layer_named(&dm->vertData, CD_MDEFORMVERT, CD_CALLOC, + NULL, numVerts, wmd->defgrp_name_a); + /* Ultimate security check. */ + if(!dvert) return dm; - } - rel_ret = 1; - } - else - ret = dm; -#else - ret = CDDM_copy(dm); - rel_ret = 1; - dvert = ret->getVertDataArray(ret, CD_MDEFORMVERT); - if (dvert == NULL) { - if (rel_ret) - ret->release(ret); - return dm; - } -#endif /* Find out which vertices to work on. */ tidx = MEM_mallocN(sizeof(int) * numVerts, "WeightVGMix Modifier, tidx"); @@ -364,8 +335,6 @@ MEM_freeN(tdw1); MEM_freeN(tdw2); MEM_freeN(tidx); - if (rel_ret) - ret->release(ret); return dm; } if (numIdx != -1) { @@ -400,7 +369,7 @@ } /* Do masking. */ - weightvg_do_mask(numIdx, indices, org_w, new_w, ob, ret, wmd->mask_constant, + weightvg_do_mask(numIdx, indices, org_w, new_w, ob, dm, wmd->mask_constant, wmd->mask_defgrp_name, wmd->mask_texture, wmd->mask_tex_use_channel, wmd->mask_tex_mapping, wmd->mask_tex_map_obj, wmd->mask_tex_uvlayer_name); @@ -409,6 +378,12 @@ */ weightvg_update_vg(dvert, defgrp_idx, dw1, numIdx, indices, org_w, TRUE, -FLT_MAX, FALSE, 0.0f); + /* If weight preview enabled... */ +#if 0 /* XXX Currently done in mod stack :/ */ + if(do_prev) + DM_update_weight_mcol(ob, dm, 0, org_w, numIdx, indices); +#endif + /* Freeing stuff. */ MEM_freeN(org_w); MEM_freeN(new_w); @@ -419,7 +394,7 @@ MEM_freeN(indices); /* Return the vgroup-modified mesh. */ - return ret; + return dm; } static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob, @@ -434,10 +409,11 @@ /* name */ "VertexWeightMix", /* structName */ "WeightVGMixModifierData", /* structSize */ sizeof(WeightVGMixModifierData), - /* type */ eModifierTypeType_Nonconstructive, + /* type */ eModifierTypeType_NonGeometrical, /* flags */ eModifierTypeFlag_AcceptsMesh -/* |eModifierTypeFlag_SupportsMapping*/ - |eModifierTypeFlag_SupportsEditmode, + |eModifierTypeFlag_SupportsMapping + |eModifierTypeFlag_SupportsEditmode + |eModifierTypeFlag_UsesPreview, /* copyData */ copyData, /* deformVerts */ NULL, diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_weightvgproximity.c blender-2.62/source/blender/modifiers/intern/MOD_weightvgproximity.c --- blender-2.61/source/blender/modifiers/intern/MOD_weightvgproximity.c 2011-12-13 19:49:28.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_weightvgproximity.c 2012-02-15 19:34:17.000000000 +0000 @@ -28,11 +28,17 @@ * \ingroup modifiers */ +#define DO_PROFILE 0 + #include "BLI_editVert.h" #include "BLI_math.h" #include "BLI_string.h" #include "BLI_utildefines.h" +#if DO_PROFILE + #include "PIL_time.h" +#endif + #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_modifier_types.h" @@ -262,6 +268,8 @@ if(wmd->mask_tex_mapping == MOD_DISP_MAP_UV) dataMask |= CD_MASK_MTFACE; + /* No need to ask for CD_WEIGHT_MCOL... */ + return dataMask; } @@ -334,10 +342,7 @@ int UNUSED(useRenderParams), int UNUSED(isFinalCalc)) { WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData*) md; - DerivedMesh *dm = derivedData, *ret = NULL; -#if 0 - Mesh *ob_m = NULL; -#endif + DerivedMesh *dm = derivedData; MDeformVert *dvert = NULL; MDeformWeight **dw, **tdw; int numVerts; @@ -350,7 +355,14 @@ int *tidx, *indices = NULL; int numIdx = 0; int i; - char rel_ret = 0; /* Boolean, whether we have to release ret dm or not, when not using it! */ + /* Flags. */ +#if 0 + int do_prev = (wmd->modifier.mode & eModifierMode_DoWeightPreview); +#endif + +#if DO_PROFILE + TIMEIT_START(perf) +#endif /* Get number of verts. */ numVerts = dm->getNumVerts(dm); @@ -371,50 +383,12 @@ if (defgrp_idx < 0) return dm; - /* XXX All this to avoid copying dm when not needed... However, it nearly doubles compute - * time! See scene 5 of the WeighVG test file... - */ -#if 0 - /* Get actual dverts (ie vertex group data). */ - dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); - /* If no dverts, return unmodified data... */ - if (dvert == NULL) + dvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MDEFORMVERT, numVerts); + /* If no vertices were ever added to an object's vgroup, dvert might be NULL. + * As this modifier never add vertices to vgroup, just return. */ + if(!dvert) return dm; - /* Get org mesh, only to test whether affected cdata layer has already been copied - * somewhere up in the modifiers stack. - */ - ob_m = get_mesh(ob); - if (ob_m == NULL) - return dm; - - /* Create a copy of our dmesh, only if our affected cdata layer is the same as org mesh. */ - if (dvert == CustomData_get_layer(&ob_m->vdata, CD_MDEFORMVERT)) { - /* XXX Seems to create problems with weightpaint mode??? - * I'm missing something here, I guess... - */ -// DM_set_only_copy(dm, CD_MASK_MDEFORMVERT); /* Only copy defgroup layer. */ - ret = CDDM_copy(dm); - dvert = ret->getVertDataArray(ret, CD_MDEFORMVERT); - if (dvert == NULL) { - ret->release(ret); - return dm; - } - rel_ret = 1; - } - else - ret = dm; -#else - ret = CDDM_copy(dm); - rel_ret = 1; - dvert = ret->getVertDataArray(ret, CD_MDEFORMVERT); - if (dvert == NULL) { - if (rel_ret) - ret->release(ret); - return dm; - } -#endif - /* Find out which vertices to work on (all vertices in vgroup), and get their relevant weight. */ tidx = MEM_mallocN(sizeof(int) * numVerts, "WeightVGProximity Modifier, tidx"); @@ -433,25 +407,39 @@ MEM_freeN(tidx); MEM_freeN(tw); MEM_freeN(tdw); - if (rel_ret) - ret->release(ret); return dm; } - indices = MEM_mallocN(sizeof(int) * numIdx, "WeightVGProximity Modifier, indices"); - memcpy(indices, tidx, sizeof(int) * numIdx); - org_w = MEM_mallocN(sizeof(float) * numIdx, "WeightVGProximity Modifier, org_w"); + if(numIdx != numVerts) { + indices = MEM_mallocN(sizeof(int) * numIdx, "WeightVGProximity Modifier, indices"); + memcpy(indices, tidx, sizeof(int) * numIdx); + org_w = MEM_mallocN(sizeof(float) * numIdx, "WeightVGProximity Modifier, org_w"); + memcpy(org_w, tw, sizeof(float) * numIdx); + dw = MEM_mallocN(sizeof(MDeformWeight*) * numIdx, "WeightVGProximity Modifier, dw"); + memcpy(dw, tdw, sizeof(MDeformWeight*) * numIdx); + MEM_freeN(tw); + MEM_freeN(tdw); + } + else { + org_w = tw; + dw = tdw; + } new_w = MEM_mallocN(sizeof(float) * numIdx, "WeightVGProximity Modifier, new_w"); - memcpy(org_w, tw, sizeof(float) * numIdx); - dw = MEM_mallocN(sizeof(MDeformWeight*) * numIdx, "WeightVGProximity Modifier, dw"); - memcpy(dw, tdw, sizeof(MDeformWeight*) * numIdx); MEM_freeN(tidx); - MEM_freeN(tw); - MEM_freeN(tdw); /* Get our vertex coordinates. */ v_cos = MEM_mallocN(sizeof(float[3]) * numIdx, "WeightVGProximity Modifier, v_cos"); - for (i = 0; i < numIdx; i++) - ret->getVertCo(ret, indices[i], v_cos[i]); + if(numIdx != numVerts) { + /* XXX In some situations, this code can be up to about 50 times more performant + * than simply using getVertCo for each affected vertex... + */ + float (*tv_cos)[3] = MEM_mallocN(sizeof(float[3]) * numVerts, "WeightVGProximity Modifier, tv_cos"); + dm->getVertCos(dm, tv_cos); + for (i = 0; i < numIdx; i++) + copy_v3_v3(v_cos[i], tv_cos[indices[i]]); + MEM_freeN(tv_cos); + } + else + dm->getVertCos(dm, v_cos); /* Compute wanted distances. */ if (wmd->proximity_mode == MOD_WVG_PROXIMITY_OBJECT) { @@ -516,22 +504,33 @@ do_map(new_w, numIdx, wmd->min_dist, wmd->max_dist, wmd->falloff_type); /* Do masking. */ - weightvg_do_mask(numIdx, indices, org_w, new_w, ob, ret, wmd->mask_constant, + weightvg_do_mask(numIdx, indices, org_w, new_w, ob, dm, wmd->mask_constant, wmd->mask_defgrp_name, wmd->mask_texture, wmd->mask_tex_use_channel, wmd->mask_tex_mapping, wmd->mask_tex_map_obj, wmd->mask_tex_uvlayer_name); /* Update vgroup. Note we never add nor remove vertices from vgroup here. */ weightvg_update_vg(dvert, defgrp_idx, dw, numIdx, indices, org_w, FALSE, 0.0f, FALSE, 0.0f); + /* If weight preview enabled... */ +#if 0 /* XXX Currently done in mod stack :/ */ + if(do_prev) + DM_update_weight_mcol(ob, dm, 0, org_w, numIdx, indices); +#endif + /* Freeing stuff. */ MEM_freeN(org_w); MEM_freeN(new_w); MEM_freeN(dw); - MEM_freeN(indices); + if(indices) + MEM_freeN(indices); MEM_freeN(v_cos); +#if DO_PROFILE + TIMEIT_END(perf) +#endif + /* Return the vgroup-modified mesh. */ - return ret; + return dm; } static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob, @@ -546,10 +545,11 @@ /* name */ "VertexWeightProximity", /* structName */ "WeightVGProximityModifierData", /* structSize */ sizeof(WeightVGProximityModifierData), - /* type */ eModifierTypeType_Nonconstructive, + /* type */ eModifierTypeType_NonGeometrical, /* flags */ eModifierTypeFlag_AcceptsMesh -/* |eModifierTypeFlag_SupportsMapping*/ - |eModifierTypeFlag_SupportsEditmode, + |eModifierTypeFlag_SupportsMapping + |eModifierTypeFlag_SupportsEditmode + |eModifierTypeFlag_UsesPreview, /* copyData */ copyData, /* deformVerts */ NULL, diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_weightvg_util.c blender-2.62/source/blender/modifiers/intern/MOD_weightvg_util.c --- blender-2.61/source/blender/modifiers/intern/MOD_weightvg_util.c 2011-12-13 19:49:28.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_weightvg_util.c 2012-02-15 19:34:17.000000000 +0000 @@ -112,7 +112,7 @@ * XXX The standard “factor” value is assumed in [0.0, 1.0] range. Else, weird results might appear. */ void weightvg_do_mask(int num, const int *indices, float *org_w, const float *new_w, - Object *ob, DerivedMesh *dm, float fact, const char defgrp_name[32], + Object *ob, DerivedMesh *dm, float fact, const char defgrp_name[MAX_VGROUP_NAME], Tex *texture, int tex_use_channel, int tex_mapping, Object *tex_map_object, const char *tex_uvlayer_name) { diff -Nru blender-2.61/source/blender/modifiers/intern/MOD_weightvg_util.h blender-2.62/source/blender/modifiers/intern/MOD_weightvg_util.h --- blender-2.61/source/blender/modifiers/intern/MOD_weightvg_util.h 2011-12-13 19:49:28.000000000 +0000 +++ blender-2.62/source/blender/modifiers/intern/MOD_weightvg_util.h 2012-02-15 19:34:17.000000000 +0000 @@ -73,7 +73,7 @@ * XXX The standard “factor” value is assumed in [0.0, 1.0] range. Else, weird results might appear. */ void weightvg_do_mask(int num, const int *indices, float *org_w, const float *new_w, Object *ob, - DerivedMesh *dm, float fact, const char defgrp_name[32], Tex *texture, + DerivedMesh *dm, float fact, const char defgrp_name[MAX_VGROUP_NAME], Tex *texture, int tex_use_channel, int tex_mapping, Object *tex_map_object, const char *tex_uvlayer_name); diff -Nru blender-2.61/source/blender/modifiers/MOD_modifiertypes.h blender-2.62/source/blender/modifiers/MOD_modifiertypes.h --- blender-2.61/source/blender/modifiers/MOD_modifiertypes.h 2011-12-13 19:49:29.000000000 +0000 +++ blender-2.62/source/blender/modifiers/MOD_modifiertypes.h 2012-02-15 19:34:17.000000000 +0000 @@ -73,6 +73,7 @@ extern ModifierTypeInfo modifierType_WeightVGMix; extern ModifierTypeInfo modifierType_WeightVGProximity; extern ModifierTypeInfo modifierType_DynamicPaint; +extern ModifierTypeInfo modifierType_Remesh; /* MOD_util.c */ void modifier_type_init(ModifierTypeInfo *types[]); diff -Nru blender-2.61/source/blender/modifiers/SConscript blender-2.62/source/blender/modifiers/SConscript --- blender-2.61/source/blender/modifiers/SConscript 2011-12-13 19:49:29.000000000 +0000 +++ blender-2.62/source/blender/modifiers/SConscript 2012-02-15 19:34:17.000000000 +0000 @@ -16,6 +16,10 @@ if env ['WITH_BF_BOOLEAN']: defs.append('WITH_MOD_BOOLEAN') +if env['WITH_BF_REMESH']: + incs += ' #/intern/dualcon' + defs.append('WITH_MOD_REMESH') + if env ['WITH_BF_DECIMATE']: defs.append('WITH_MOD_DECIMATE') diff -Nru blender-2.61/source/blender/nodes/CMakeLists.txt blender-2.62/source/blender/nodes/CMakeLists.txt --- blender-2.61/source/blender/nodes/CMakeLists.txt 2011-12-13 19:51:22.000000000 +0000 +++ blender-2.62/source/blender/nodes/CMakeLists.txt 2012-02-15 19:36:11.000000000 +0000 @@ -59,6 +59,7 @@ composite/nodes/node_composite_composite.c composite/nodes/node_composite_crop.c composite/nodes/node_composite_curves.c + composite/nodes/node_composite_doubleEdgeMask.c composite/nodes/node_composite_defocus.c composite/nodes/node_composite_diffMatte.c composite/nodes/node_composite_dilate.c @@ -113,6 +114,8 @@ shader/nodes/node_shader_common.c shader/nodes/node_shader_curves.c shader/nodes/node_shader_dynamic.c + shader/nodes/node_shader_gamma.c + shader/nodes/node_shader_brightness.c shader/nodes/node_shader_geom.c shader/nodes/node_shader_hueSatVal.c shader/nodes/node_shader_invert.c @@ -161,6 +164,7 @@ shader/nodes/node_shader_tex_sky.c shader/nodes/node_shader_tex_voronoi.c shader/nodes/node_shader_tex_wave.c + shader/nodes/node_shader_tex_checker.c shader/node_shader_tree.c shader/node_shader_util.c diff -Nru blender-2.61/source/blender/nodes/composite/node_composite_tree.c blender-2.62/source/blender/nodes/composite/node_composite_tree.c --- blender-2.61/source/blender/nodes/composite/node_composite_tree.c 2011-12-13 19:51:18.000000000 +0000 +++ blender-2.62/source/blender/nodes/composite/node_composite_tree.c 2012-02-15 19:36:07.000000000 +0000 @@ -604,8 +604,8 @@ if(ntree->progress && totnode) ntree->progress(ntree->prh, (1.0f - curnode/(float)totnode)); if(ntree->stats_draw) { - char str[64]; - sprintf(str, "Compositing %d %s", curnode, node->name); + char str[128]; + BLI_snprintf(str, sizeof(str), "Compositing %d %s", curnode, node->name); ntree->stats_draw(ntree->sdh, str); } curnode--; @@ -660,6 +660,13 @@ for(sock= node->outputs.first; sock; sock= sock->next) sock->flag &= ~SOCK_UNAVAIL; + if(!(passflag & SCE_PASS_COMBINED)) { + sock= BLI_findlink(&node->outputs, RRES_OUT_IMAGE); + sock->flag |= SOCK_UNAVAIL; + sock= BLI_findlink(&node->outputs, RRES_OUT_ALPHA); + sock->flag |= SOCK_UNAVAIL; + } + sock= BLI_findlink(&node->outputs, RRES_OUT_Z); if(!(passflag & SCE_PASS_Z)) sock->flag |= SOCK_UNAVAIL; sock= BLI_findlink(&node->outputs, RRES_OUT_NORMAL); @@ -694,7 +701,28 @@ if(!(passflag & SCE_PASS_EMIT)) sock->flag |= SOCK_UNAVAIL; sock= BLI_findlink(&node->outputs, RRES_OUT_ENV); if(!(passflag & SCE_PASS_ENVIRONMENT)) sock->flag |= SOCK_UNAVAIL; - + + sock= BLI_findlink(&node->outputs, RRES_OUT_DIFF_DIRECT); + if(!(passflag & SCE_PASS_DIFFUSE_DIRECT)) sock->flag |= SOCK_UNAVAIL; + sock= BLI_findlink(&node->outputs, RRES_OUT_DIFF_INDIRECT); + if(!(passflag & SCE_PASS_DIFFUSE_INDIRECT)) sock->flag |= SOCK_UNAVAIL; + sock= BLI_findlink(&node->outputs, RRES_OUT_DIFF_COLOR); + if(!(passflag & SCE_PASS_DIFFUSE_COLOR)) sock->flag |= SOCK_UNAVAIL; + + sock= BLI_findlink(&node->outputs, RRES_OUT_GLOSSY_DIRECT); + if(!(passflag & SCE_PASS_GLOSSY_DIRECT)) sock->flag |= SOCK_UNAVAIL; + sock= BLI_findlink(&node->outputs, RRES_OUT_GLOSSY_INDIRECT); + if(!(passflag & SCE_PASS_GLOSSY_INDIRECT)) sock->flag |= SOCK_UNAVAIL; + sock= BLI_findlink(&node->outputs, RRES_OUT_GLOSSY_COLOR); + if(!(passflag & SCE_PASS_GLOSSY_COLOR)) sock->flag |= SOCK_UNAVAIL; + + sock= BLI_findlink(&node->outputs, RRES_OUT_TRANSM_DIRECT); + if(!(passflag & SCE_PASS_TRANSM_DIRECT)) sock->flag |= SOCK_UNAVAIL; + sock= BLI_findlink(&node->outputs, RRES_OUT_TRANSM_INDIRECT); + if(!(passflag & SCE_PASS_TRANSM_INDIRECT)) sock->flag |= SOCK_UNAVAIL; + sock= BLI_findlink(&node->outputs, RRES_OUT_TRANSM_COLOR); + if(!(passflag & SCE_PASS_TRANSM_COLOR)) sock->flag |= SOCK_UNAVAIL; + sock= BLI_findlink(&node->outputs, RRES_OUT_TRANSM_COLOR); } /* based on rules, force sockets hidden always */ @@ -720,16 +748,16 @@ if(rl) force_hidden_passes(node, rl->passflag); else - force_hidden_passes(node, 0); + force_hidden_passes(node, RRES_OUT_IMAGE|RRES_OUT_ALPHA); } else if(ima->type!=IMA_TYPE_MULTILAYER) { /* if ->rr not yet read we keep inputs */ - force_hidden_passes(node, RRES_OUT_Z); + force_hidden_passes(node, RRES_OUT_IMAGE|RRES_OUT_ALPHA|RRES_OUT_Z); } else - force_hidden_passes(node, 0); + force_hidden_passes(node, RRES_OUT_IMAGE|RRES_OUT_ALPHA); } else - force_hidden_passes(node, 0); + force_hidden_passes(node, RRES_OUT_IMAGE|RRES_OUT_ALPHA); } } diff -Nru blender-2.61/source/blender/nodes/composite/node_composite_util.c blender-2.62/source/blender/nodes/composite/node_composite_util.c --- blender-2.61/source/blender/nodes/composite/node_composite_util.c 2011-12-13 19:51:18.000000000 +0000 +++ blender-2.62/source/blender/nodes/composite/node_composite_util.c 2012-02-15 19:36:07.000000000 +0000 @@ -402,7 +402,7 @@ return inbuf; } -static float *compbuf_get_pixel(CompBuf *cbuf, float *defcol, float *use, int x, int y, int xrad, int yrad) +float *compbuf_get_pixel(CompBuf *cbuf, float *defcol, float *use, int x, int y, int xrad, int yrad) { if(cbuf) { if(cbuf->rect_procedural) { @@ -427,6 +427,18 @@ /* **************************************************** */ +static CompBuf *composit_check_compbuf(CompBuf *cbuf, int type, CompBuf *outbuf) +{ + /* check type */ + CompBuf *dbuf= typecheck_compbuf(cbuf, type); + + /* if same as output and translated, duplicate so pixels don't interfere */ + if(dbuf == outbuf && !dbuf->rect_procedural && (dbuf->xof || dbuf->yof)) + dbuf= dupalloc_compbuf(dbuf); + + return dbuf; +} + /* Pixel-to-Pixel operation, 1 Image in, 1 out */ void composit1_pixel_processor(bNode *node, CompBuf *out, CompBuf *src_buf, float *src_col, void (*func)(bNode *, float *, float *), @@ -437,7 +449,7 @@ float color[4]; /* local color if compbuf is procedural */ int xrad, yrad, x, y; - src_use= typecheck_compbuf(src_buf, src_type); + src_use= composit_check_compbuf(src_buf, src_type, out); xrad= out->xrad; yrad= out->yrad; @@ -463,8 +475,8 @@ float color[4]; /* local color if compbuf is procedural */ int xrad, yrad, x, y; - src_use= typecheck_compbuf(src_buf, src_type); - fac_use= typecheck_compbuf(fac_buf, fac_type); + src_use= composit_check_compbuf(src_buf, src_type, out); + fac_use= composit_check_compbuf(fac_buf, fac_type, out); xrad= out->xrad; yrad= out->yrad; @@ -493,9 +505,9 @@ float color[4]; /* local color if compbuf is procedural */ int xrad, yrad, x, y; - src1_use= typecheck_compbuf(src1_buf, src1_type); - src2_use= typecheck_compbuf(src2_buf, src2_type); - fac_use= typecheck_compbuf(fac_buf, fac_type); + src1_use= composit_check_compbuf(src1_buf, src1_type, out); + src2_use= composit_check_compbuf(src2_buf, src2_type, out); + fac_use= composit_check_compbuf(fac_buf, fac_type, out); xrad= out->xrad; yrad= out->yrad; @@ -529,10 +541,10 @@ float color[4]; /* local color if compbuf is procedural */ int xrad, yrad, x, y; - src1_use= typecheck_compbuf(src1_buf, src1_type); - src2_use= typecheck_compbuf(src2_buf, src2_type); - fac1_use= typecheck_compbuf(fac1_buf, fac1_type); - fac2_use= typecheck_compbuf(fac2_buf, fac2_type); + src1_use= composit_check_compbuf(src1_buf, src1_type, out); + src2_use= composit_check_compbuf(src2_buf, src2_type, out); + fac1_use= composit_check_compbuf(fac1_buf, fac1_type, out); + fac2_use= composit_check_compbuf(fac2_buf, fac2_type, out); xrad= out->xrad; yrad= out->yrad; @@ -606,7 +618,9 @@ RenderData *rd= data; bNodePreview *preview= node->preview; int xsize, ysize; - int color_manage= rd->color_mgt_flag & R_COLOR_MANAGEMENT; + int profile_from= (rd->color_mgt_flag & R_COLOR_MANAGEMENT)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB; + int predivide= (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE); + int dither= 0; unsigned char *rect; if(preview && stackbuf) { @@ -633,10 +647,9 @@ /* convert to byte for preview */ rect= MEM_callocN(sizeof(unsigned char)*4*xsize*ysize, "bNodePreview.rect"); - if(color_manage) - floatbuf_to_srgb_byte(cbuf->rect, rect, 0, xsize, 0, ysize, xsize); - else - floatbuf_to_byte(cbuf->rect, rect, 0, xsize, 0, ysize, xsize); + IMB_buffer_byte_from_float(rect, cbuf->rect, + 4, dither, IB_PROFILE_SRGB, profile_from, predivide, + xsize, ysize, xsize, xsize); free_compbuf(cbuf); if(stackbuf_use!=stackbuf) diff -Nru blender-2.61/source/blender/nodes/composite/node_composite_util.h blender-2.62/source/blender/nodes/composite/node_composite_util.h --- blender-2.61/source/blender/nodes/composite/node_composite_util.h 2011-12-13 19:51:18.000000000 +0000 +++ blender-2.62/source/blender/nodes/composite/node_composite_util.h 2012-02-15 19:36:07.000000000 +0000 @@ -133,6 +133,8 @@ /* **************************************************** */ +float *compbuf_get_pixel(CompBuf *cbuf, float *defcol, float *use, int x, int y, int xrad, int yrad); + /* Pixel-to-Pixel operation, 1 Image in, 1 out */ void composit1_pixel_processor(bNode *node, CompBuf *out, CompBuf *src_buf, float *src_col, void (*func)(bNode *, float *, float *), diff -Nru blender-2.61/source/blender/nodes/composite/nodes/node_composite_alphaOver.c blender-2.62/source/blender/nodes/composite/nodes/node_composite_alphaOver.c --- blender-2.61/source/blender/nodes/composite/nodes/node_composite_alphaOver.c 2011-12-13 19:51:18.000000000 +0000 +++ blender-2.62/source/blender/nodes/composite/nodes/node_composite_alphaOver.c 2012-02-15 19:36:07.000000000 +0000 @@ -47,7 +47,8 @@ static void do_alphaover_premul(bNode *UNUSED(node), float *out, float *src, float *over, float *fac) { - if(over[3]<=0.0f) { + /* Zero alpha values should still permit an add of RGB data */ + if(over[3]<0.0f) { copy_v4_v4(out, src); } else if(fac[0]==1.0f && over[3]>=1.0f) { diff -Nru blender-2.61/source/blender/nodes/composite/nodes/node_composite_blur.c blender-2.62/source/blender/nodes/composite/nodes/node_composite_blur.c --- blender-2.61/source/blender/nodes/composite/nodes/node_composite_blur.c 2011-12-13 19:51:18.000000000 +0000 +++ blender-2.62/source/blender/nodes/composite/nodes/node_composite_blur.c 2012-02-15 19:36:07.000000000 +0000 @@ -455,14 +455,19 @@ int x, y, pix= img->type; int i, j; float *src, *dest, *refd, *blurd; + float defcol[4] = {1.0f, 1.0f, 1.0f, 1.0f}; /* default color for compbuf_get_pixel */ + float proccol[4]; /* local color if compbuf is procedural */ + int refradx, refrady; - if(ref->x!=img->x && ref->y!=img->y) + if(ref->x!=img->x || ref->y!=img->y) return; ref_use= typecheck_compbuf(ref, CB_VAL); /* trick is; we blur the reference image... but only works with clipped values*/ blurbuf= alloc_compbuf(imgx, imgy, CB_VAL, 1); + blurbuf->xof= ref_use->xof; + blurbuf->yof= ref_use->yof; blurd= blurbuf->rect; refd= ref_use->rect; for(x= imgx*imgy; x>0; x--, refd++, blurd++) { @@ -492,15 +497,15 @@ for(i= 0; ifiltertype, i+1); - refd= blurbuf->rect; dest= new->rect; radxf= (float)radx; radyf= (float)rady; for (y = 0; y < imgy; y++) { - for (x = 0; x < imgx ; x++, dest+=pix, refd++) { - int refradx= (int)(refd[0]*radxf); - int refrady= (int)(refd[0]*radyf); + for (x = 0; x < imgx ; x++, dest+=pix) { + refd= compbuf_get_pixel(blurbuf, defcol, proccol, x-blurbuf->xrad, y-blurbuf->yrad, blurbuf->xrad, blurbuf->yrad); + refradx= (int)(refd[0]*radxf); + refrady= (int)(refd[0]*radyf); if(refradx>radx) refradx= radx; else if(refradx<1) refradx= 1; diff -Nru blender-2.61/source/blender/nodes/composite/nodes/node_composite_doubleEdgeMask.c blender-2.62/source/blender/nodes/composite/nodes/node_composite_doubleEdgeMask.c --- blender-2.61/source/blender/nodes/composite/nodes/node_composite_doubleEdgeMask.c 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/source/blender/nodes/composite/nodes/node_composite_doubleEdgeMask.c 2012-02-15 19:36:07.000000000 +0000 @@ -0,0 +1,1184 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Peter Larabell. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/composite/nodes/node_composite_doubleEdgeMask.c + * \ingroup cmpnodes + */ +#include "node_composite_util.h" +/* **************** Double Edge Mask ******************** */ + + +static bNodeSocketTemplate cmp_node_doubleedgemask_in[]= { + { SOCK_FLOAT, 1, "Inner Mask", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f, PROP_NONE}, // inner mask socket definition + { SOCK_FLOAT, 1, "Outer Mask", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f, PROP_NONE}, // outer mask socket definition + { -1, 0, "" } // input socket array terminator +}; +static bNodeSocketTemplate cmp_node_doubleedgemask_out[]= { + { SOCK_FLOAT, 0, "Mask"}, // output socket definition + { -1, 0, "" } // output socket array terminator +}; + +static void do_adjacentKeepBorders(unsigned int t, unsigned int rw, unsigned int *limask, unsigned int *lomask, unsigned int *lres, float *res, unsigned int *rsize){ + int x; + unsigned int isz=0; // inner edge size + unsigned int osz=0; // outer edge size + unsigned int gsz=0; // gradient fill area size + /* Test the four corners */ + /* upper left corner */ + x=t-rw+1; + // test if inner mask is filled + if(limask[x]){ + // test if pixel underneath, or to the right, are empty in the inner mask, + // but filled in the outer mask + if((!limask[x-rw] && lomask[x-rw]) || (!limask[x+1] && lomask[x+1])){ + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]){ // inner mask was empty, test if outer mask is filled + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } + /* upper right corner */ + x=t; + // test if inner mask is filled + if(limask[x]){ + // test if pixel underneath, or to the left, are empty in the inner mask, + // but filled in the outer mask + if((!limask[x-rw] && lomask[x-rw]) || (!limask[x-1] && lomask[x-1])){ + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]){ // inner mask was empty, test if outer mask is filled + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } + /* lower left corner */ + x=0; + // test if inner mask is filled + if(limask[x]){ + // test if pixel above, or to the right, are empty in the inner mask, + // but filled in the outer mask + if((!limask[x+rw] && lomask[x+rw]) || (!limask[x+1] && lomask[x+1])){ + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]){ // inner mask was empty, test if outer mask is filled + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } + /* lower right corner */ + x=rw-1; + // test if inner mask is filled + if(limask[x]){ + // test if pixel above, or to the left, are empty in the inner mask, + // but filled in the outer mask + if((!limask[x+rw] && lomask[x+rw]) || (!limask[x-1] && lomask[x-1])){ + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]){ // inner mask was empty, test if outer mask is filled + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } + + /* Test the TOP row of pixels in buffer, except corners */ + for(x= t-1; x>=(t-rw)+2; x--) { + // test if inner mask is filled + if(limask[x]) { + // test if pixel to the right, or to the left, are empty in the inner mask, + // but filled in the outer mask + if((!limask[x-1] && lomask[x-1]) || (!limask[x+1] && lomask[x+1])) { + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]) { // inner mask was empty, test if outer mask is filled + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } + } + + /* Test the BOTTOM row of pixels in buffer, except corners */ + for(x= rw-2; x; x--) { + // test if inner mask is filled + if(limask[x]) { + // test if pixel to the right, or to the left, are empty in the inner mask, + // but filled in the outer mask + if((!limask[x-1] && lomask[x-1]) || (!limask[x+1] && lomask[x+1])) { + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]) { // inner mask was empty, test if outer mask is filled + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } + } + /* Test the LEFT edge of pixels in buffer, except corners */ + for(x= t-(rw<<1)+1; x>=rw; x-=rw) { + // test if inner mask is filled + if(limask[x]) { + // test if pixel underneath, or above, are empty in the inner mask, + // but filled in the outer mask + if((!limask[x-rw] && lomask[x-rw]) || (!limask[x+rw] && lomask[x+rw])) { + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]) { // inner mask was empty, test if outer mask is filled + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } + } + + /* Test the RIGHT edge of pixels in buffer, except corners */ + for(x= t-rw; x>rw; x-=rw) { + // test if inner mask is filled + if(limask[x]) { + // test if pixel underneath, or above, are empty in the inner mask, + // but filled in the outer mask + if((!limask[x-rw] && lomask[x-rw]) || (!limask[x+rw] && lomask[x+rw])) { + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]) { // inner mask was empty, test if outer mask is filled + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } + } + + rsize[0]=isz; // fill in our return sizes for edges + fill + rsize[1]=osz; + rsize[2]=gsz; +} + +static void do_adjacentBleedBorders(unsigned int t, unsigned int rw, unsigned int *limask, unsigned int *lomask, unsigned int *lres, float *res, unsigned int *rsize){ + int x; + unsigned int isz=0; // inner edge size + unsigned int osz=0; // outer edge size + unsigned int gsz=0; // gradient fill area size + /* Test the four corners */ + /* upper left corner */ + x=t-rw+1; + // test if inner mask is filled + if(limask[x]){ + // test if pixel underneath, or to the right, are empty in the inner mask, + // but filled in the outer mask + if((!limask[x-rw] && lomask[x-rw]) || (!limask[x+1] && lomask[x+1])){ + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]){ // inner mask was empty, test if outer mask is filled + if(!lomask[x-rw] || !lomask[x+1]) { // test if outer mask is empty underneath or to the right + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } else { + gsz++; // increment the gradient pixel count + lres[x]=2; // flag pixel as gradient + } + } + /* upper right corner */ + x=t; + // test if inner mask is filled + if(limask[x]){ + // test if pixel underneath, or to the left, are empty in the inner mask, + // but filled in the outer mask + if((!limask[x-rw] && lomask[x-rw]) || (!limask[x-1] && lomask[x-1])){ + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]){ // inner mask was empty, test if outer mask is filled + if(!lomask[x-rw] || !lomask[x-1]) { // test if outer mask is empty underneath or to the left + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } else { + gsz++; // increment the gradient pixel count + lres[x]=2; // flag pixel as gradient + } + } + /* lower left corner */ + x=0; + // test if inner mask is filled + if(limask[x]){ + // test if pixel above, or to the right, are empty in the inner mask, + // but filled in the outer mask + if((!limask[x+rw] && lomask[x+rw]) || (!limask[x+1] && lomask[x+1])){ + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]){ // inner mask was empty, test if outer mask is filled + if(!lomask[x+rw] || !lomask[x+1]) { // test if outer mask is empty above or to the right + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } else { + gsz++; // increment the gradient pixel count + lres[x]=2; // flag pixel as gradient + } + } + /* lower right corner */ + x=rw-1; + // test if inner mask is filled + if(limask[x]){ + // test if pixel above, or to the left, are empty in the inner mask, + // but filled in the outer mask + if((!limask[x+rw] && lomask[x+rw]) || (!limask[x-1] && lomask[x-1])){ + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]){ // inner mask was empty, test if outer mask is filled + if(!lomask[x+rw] || !lomask[x-1]) { // test if outer mask is empty above or to the left + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } else { + gsz++; // increment the gradient pixel count + lres[x]=2; // flag pixel as gradient + } + } + /* Test the TOP row of pixels in buffer, except corners */ + for(x= t-1; x>=(t-rw)+2; x--) { + // test if inner mask is filled + if(limask[x]) { + // test if pixel to the left, or to the right, are empty in the inner mask, + // but filled in the outer mask + if((!limask[x-1] && lomask[x-1]) || (!limask[x+1] && lomask[x+1])) { + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]) { // inner mask was empty, test if outer mask is filled + if(!lomask[x-1] || !lomask[x+1]) { // test if outer mask is empty to the left or to the right + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } else { + gsz++; // increment the gradient pixel count + lres[x]=2; // flag pixel as gradient + } + } + } + + /* Test the BOTTOM row of pixels in buffer, except corners */ + for(x= rw-2; x; x--) { + // test if inner mask is filled + if(limask[x]) { + // test if pixel to the left, or to the right, are empty in the inner mask, + // but filled in the outer mask + if((!limask[x-1] && lomask[x-1]) || (!limask[x+1] && lomask[x+1])) { + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]) { // inner mask was empty, test if outer mask is filled + if(!lomask[x-1] || !lomask[x+1]) { // test if outer mask is empty to the left or to the right + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } else { + gsz++; // increment the gradient pixel count + lres[x]=2; // flag pixel as gradient + } + } + } + /* Test the LEFT edge of pixels in buffer, except corners */ + for(x= t-(rw<<1)+1; x>=rw; x-=rw) { + // test if inner mask is filled + if(limask[x]) { + // test if pixel underneath, or above, are empty in the inner mask, + // but filled in the outer mask + if((!limask[x-rw] && lomask[x-rw]) || (!limask[x+rw] && lomask[x+rw])) { + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]) { // inner mask was empty, test if outer mask is filled + if(!lomask[x-rw] || !lomask[x+rw]) { // test if outer mask is empty underneath or above + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } else { + gsz++; // increment the gradient pixel count + lres[x]=2; // flag pixel as gradient + } + } + } + + /* Test the RIGHT edge of pixels in buffer, except corners */ + for(x= t-rw; x>rw; x-=rw) { + // test if inner mask is filled + if(limask[x]) { + // test if pixel underneath, or above, are empty in the inner mask, + // but filled in the outer mask + if((!limask[x-rw] && lomask[x-rw]) || (!limask[x+rw] && lomask[x+rw])) { + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]) { // inner mask was empty, test if outer mask is filled + if(!lomask[x-rw] || !lomask[x+rw]) { // test if outer mask is empty underneath or above + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } else { + gsz++; // increment the gradient pixel count + lres[x]=2; // flag pixel as gradient + } + } + } + + rsize[0]=isz; // fill in our return sizes for edges + fill + rsize[1]=osz; + rsize[2]=gsz; +} + +static void do_allKeepBorders(unsigned int t, unsigned int rw, unsigned int *limask, unsigned int *lomask, unsigned int *lres, float *res, unsigned int *rsize){ + int x; + unsigned int isz=0; // inner edge size + unsigned int osz=0; // outer edge size + unsigned int gsz=0; // gradient fill area size + /* Test the four corners */ + /* upper left corner */ + x=t-rw+1; + // test if inner mask is filled + if(limask[x]){ + // test if the inner mask is empty underneath or to the right + if(!limask[x-rw] || !limask[x+1]){ + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]){ // inner mask was empty, test if outer mask is filled + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } + /* upper right corner */ + x=t; + // test if inner mask is filled + if(limask[x]){ + // test if the inner mask is empty underneath or to the left + if(!limask[x-rw] || !limask[x-1]){ + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]){ // inner mask was empty, test if outer mask is filled + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } + /* lower left corner */ + x=0; + // test if inner mask is filled + if(limask[x]){ + // test if inner mask is empty above or to the right + if(!limask[x+rw] || !limask[x+1]){ + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]){ // inner mask was empty, test if outer mask is filled + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } + /* lower right corner */ + x=rw-1; + // test if inner mask is filled + if(limask[x]){ + // test if inner mask is empty above or to the left + if(!limask[x+rw] || !limask[x-1]){ + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]){ // inner mask was empty, test if outer mask is filled + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } + + /* Test the TOP row of pixels in buffer, except corners */ + for(x= t-1; x>=(t-rw)+2; x--) { + // test if inner mask is filled + if(limask[x]) { + // test if inner mask is empty to the left or to the right + if(!limask[x-1] || !limask[x+1]) { + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]) { // inner mask was empty, test if outer mask is filled + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } + } + + /* Test the BOTTOM row of pixels in buffer, except corners */ + for(x= rw-2; x; x--) { + // test if inner mask is filled + if(limask[x]) { + // test if inner mask is empty to the left or to the right + if(!limask[x-1] || !limask[x+1]) { + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]) { // inner mask was empty, test if outer mask is filled + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } + } + /* Test the LEFT edge of pixels in buffer, except corners */ + for(x= t-(rw<<1)+1; x>=rw; x-=rw) { + // test if inner mask is filled + if(limask[x]) { + // test if inner mask is empty underneath or above + if(!limask[x-rw] || !limask[x+rw]) { + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]) { // inner mask was empty, test if outer mask is filled + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } + } + + /* Test the RIGHT edge of pixels in buffer, except corners */ + for(x= t-rw; x>rw; x-=rw) { + // test if inner mask is filled + if(limask[x]) { + // test if inner mask is empty underneath or above + if(!limask[x-rw] || !limask[x+rw]) { + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]) { // inner mask was empty, test if outer mask is filled + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } + } + + rsize[0]=isz; // fill in our return sizes for edges + fill + rsize[1]=osz; + rsize[2]=gsz; +} + +static void do_allBleedBorders(unsigned int t, unsigned int rw, unsigned int *limask, unsigned int *lomask, unsigned int *lres, float *res, unsigned int *rsize){ + int x; + unsigned int isz=0; // inner edge size + unsigned int osz=0; // outer edge size + unsigned int gsz=0; // gradient fill area size + /* Test the four corners */ + /* upper left corner */ + x=t-rw+1; + // test if inner mask is filled + if(limask[x]){ + // test if the inner mask is empty underneath or to the right + if(!limask[x-rw] || !limask[x+1]){ + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]){ // inner mask was empty, test if outer mask is filled + if(!lomask[x-rw] || !lomask[x+1]) { // test if outer mask is empty underneath or to the right + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } else { + gsz++; // increment the gradient pixel count + lres[x]=2; // flag pixel as gradient + } + } + /* upper right corner */ + x=t; + // test if inner mask is filled + if(limask[x]){ + // test if the inner mask is empty underneath or to the left + if(!limask[x-rw] || !limask[x-1]){ + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]){ // inner mask was empty, test if outer mask is filled + if(!lomask[x-rw] || !lomask[x-1]) { // test if outer mask is empty above or to the left + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } else { + gsz++; // increment the gradient pixel count + lres[x]=2; // flag pixel as gradient + } + } + /* lower left corner */ + x=0; + // test if inner mask is filled + if(limask[x]){ + // test if inner mask is empty above or to the right + if(!limask[x+rw] || !limask[x+1]){ + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]){ // inner mask was empty, test if outer mask is filled + if(!lomask[x+rw] || !lomask[x+1]) { // test if outer mask is empty underneath or to the right + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } else { + gsz++; // increment the gradient pixel count + lres[x]=2; // flag pixel as gradient + } + } + /* lower right corner */ + x=rw-1; + // test if inner mask is filled + if(limask[x]){ + // test if inner mask is empty above or to the left + if(!limask[x+rw] || !limask[x-1]){ + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]){ // inner mask was empty, test if outer mask is filled + if(!lomask[x+rw] || !lomask[x-1]) { // test if outer mask is empty underneath or to the left + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } else { + gsz++; // increment the gradient pixel count + lres[x]=2; // flag pixel as gradient + } + } + /* Test the TOP row of pixels in buffer, except corners */ + for(x= t-1; x>=(t-rw)+2; x--) { + // test if inner mask is filled + if(limask[x]) { + // test if inner mask is empty to the left or to the right + if(!limask[x-1] || !limask[x+1]) { + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]) { // inner mask was empty, test if outer mask is filled + if(!lomask[x-1] || !lomask[x+1]) { // test if outer mask is empty to the left or to the right + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } else { + gsz++; // increment the gradient pixel count + lres[x]=2; // flag pixel as gradient + } + } + } + + /* Test the BOTTOM row of pixels in buffer, except corners */ + for(x= rw-2; x; x--) { + // test if inner mask is filled + if(limask[x]) { + // test if inner mask is empty to the left or to the right + if(!limask[x-1] || !limask[x+1]) { + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]) { // inner mask was empty, test if outer mask is filled + if(!lomask[x-1] || !lomask[x+1]) { // test if outer mask is empty to the left or to the right + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } else { + gsz++; // increment the gradient pixel count + lres[x]=2; // flag pixel as gradient + } + } + } + /* Test the LEFT edge of pixels in buffer, except corners */ + for(x= t-(rw<<1)+1; x>=rw; x-=rw) { + // test if inner mask is filled + if(limask[x]) { + // test if inner mask is empty underneath or above + if(!limask[x-rw] || !limask[x+rw]) { + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]) { // inner mask was empty, test if outer mask is filled + if(!lomask[x-rw] || !lomask[x+rw]) { // test if outer mask is empty underneath or above + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } else { + gsz++; // increment the gradient pixel count + lres[x]=2; // flag pixel as gradient + } + } + } + + /* Test the RIGHT edge of pixels in buffer, except corners */ + for(x= t-rw; x>rw; x-=rw) { + // test if inner mask is filled + if(limask[x]) { + // test if inner mask is empty underneath or above + if(!limask[x-rw] || !limask[x+rw]) { + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]) { // inner mask was empty, test if outer mask is filled + if(!lomask[x-rw] || !lomask[x+rw]) { // test if outer mask is empty underneath or above + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } else { + gsz++; // increment the gradient pixel count + lres[x]=2; // flag pixel as gradient + } + } + } + + rsize[0]=isz; // fill in our return sizes for edges + fill + rsize[1]=osz; + rsize[2]=gsz; +} + +static void do_allEdgeDetection(unsigned int t, unsigned int rw, unsigned int *limask, unsigned int *lomask, unsigned int *lres, float *res, unsigned int *rsize, unsigned int in_isz, unsigned int in_osz, unsigned int in_gsz){ + int x; // x = pixel loop counter + int a; // a = pixel loop counter + int dx; // dx = delta x + int pix_prevRow; // pix_prevRow = pixel one row behind the one we are testing in a loop + int pix_nextRow; // pix_nextRow = pixel one row in front of the one we are testing in a loop + int pix_prevCol; // pix_prevCol = pixel one column behind the one we are testing in a loop + int pix_nextCol; // pix_nextCol = pixel one column in front of the one we are testing in a loop + /* Test all rows between the FIRST and LAST rows, excluding left and right edges */ + for(x= (t-rw)+1, dx=x-(rw-2); dx>rw; x-=rw,dx-=rw) { + a=x-2; + pix_prevRow=a+rw; + pix_nextRow=a-rw; + pix_prevCol=a+1; + pix_nextCol=a-1; + while(a>dx-2) { + if(!limask[a]) { // if the inner mask is empty + if(lomask[a]) { // if the outer mask is full + /* + Next we test all 4 directions around the current pixel: next/prev/up/down + The test ensures that the outer mask is empty and that the inner mask + is also empty. If both conditions are true for any one of the 4 adjacent pixels + then the current pixel is counted as being a true outer edge pixel. + */ + if((!lomask[pix_nextCol] && !limask[pix_nextCol]) || + (!lomask[pix_prevCol] && !limask[pix_prevCol]) || + (!lomask[pix_nextRow] && !limask[pix_nextRow]) || + (!lomask[pix_prevRow] && !limask[pix_prevRow])) + { + in_osz++; // increment the outer boundary pixel count + lres[a]=3; // flag pixel as part of outer edge + } else { // it's not a boundary pixel, but it is a gradient pixel + in_gsz++; // increment the gradient pixel count + lres[a]=2; // flag pixel as gradient + } + } + + } else { + if(!limask[pix_nextCol] || !limask[pix_prevCol] || !limask[pix_nextRow] || !limask[pix_prevRow]) { + in_isz++; // increment the inner boundary pixel count + lres[a]=4; // flag pixel as part of inner edge + } else { + res[a]=1.0f; // pixel is part of inner mask, but not at an edge + } + } + a--; + pix_prevRow--; + pix_nextRow--; + pix_prevCol--; + pix_nextCol--; + } + } + + rsize[0]=in_isz; // fill in our return sizes for edges + fill + rsize[1]=in_osz; + rsize[2]=in_gsz; +} + +static void do_adjacentEdgeDetection(unsigned int t, unsigned int rw, unsigned int *limask, unsigned int *lomask, unsigned int *lres, float *res, unsigned int *rsize, unsigned int in_isz, unsigned int in_osz, unsigned int in_gsz){ + int x; // x = pixel loop counter + int a; // a = pixel loop counter + int dx; // dx = delta x + int pix_prevRow; // pix_prevRow = pixel one row behind the one we are testing in a loop + int pix_nextRow; // pix_nextRow = pixel one row in front of the one we are testing in a loop + int pix_prevCol; // pix_prevCol = pixel one column behind the one we are testing in a loop + int pix_nextCol; // pix_nextCol = pixel one column in front of the one we are testing in a loop + /* Test all rows between the FIRST and LAST rows, excluding left and right edges */ + for(x= (t-rw)+1, dx=x-(rw-2); dx>rw; x-=rw,dx-=rw) { + a=x-2; + pix_prevRow=a+rw; + pix_nextRow=a-rw; + pix_prevCol=a+1; + pix_nextCol=a-1; + while(a>dx-2) { + if(!limask[a]) { // if the inner mask is empty + if(lomask[a]) { // if the outer mask is full + /* + Next we test all 4 directions around the current pixel: next/prev/up/down + The test ensures that the outer mask is empty and that the inner mask + is also empty. If both conditions are true for any one of the 4 adjacent pixels + then the current pixel is counted as being a true outer edge pixel. + */ + if((!lomask[pix_nextCol] && !limask[pix_nextCol]) || + (!lomask[pix_prevCol] && !limask[pix_prevCol]) || + (!lomask[pix_nextRow] && !limask[pix_nextRow]) || + (!lomask[pix_prevRow] && !limask[pix_prevRow])) + { + in_osz++; // increment the outer boundary pixel count + lres[a]=3; // flag pixel as part of outer edge + } else { // it's not a boundary pixel, but it is a gradient pixel + in_gsz++; // increment the gradient pixel count + lres[a]=2; // flag pixel as gradient + } + } + + } else { + if((!limask[pix_nextCol] && lomask[pix_nextCol]) || + (!limask[pix_prevCol] && lomask[pix_prevCol]) || + (!limask[pix_nextRow] && lomask[pix_nextRow]) || + (!limask[pix_prevRow] && lomask[pix_prevRow])) + { + in_isz++; // increment the inner boundary pixel count + lres[a]=4; // flag pixel as part of inner edge + } else { + res[a]=1.0f; // pixel is part of inner mask, but not at an edge + } + } + a--; + pix_prevRow--; // advance all four "surrounding" pixel pointers + pix_nextRow--; + pix_prevCol--; + pix_nextCol--; + } + } + + rsize[0]=in_isz; // fill in our return sizes for edges + fill + rsize[1]=in_osz; + rsize[2]=in_gsz; +} + +static void do_createEdgeLocationBuffer(unsigned int t, unsigned int rw, unsigned int *lres, float *res, unsigned short *gbuf, unsigned int *innerEdgeOffset, unsigned int *outerEdgeOffset, unsigned int isz, unsigned int gsz){ + int x; // x = pixel loop counter + int a; // a = temporary pixel index buffer loop counter + unsigned int ud; // ud = unscaled edge distance + unsigned int dmin; // dmin = minimun edge distance + + unsigned int rsl; // long used for finding fast 1.0/sqrt + unsigned int gradientFillOffset; + unsigned int innerAccum=0; // for looping inner edge pixel indexes, represents current position from offset + unsigned int outerAccum=0; // for looping outer edge pixel indexes, represents current position from offset + unsigned int gradientAccum=0; // for looping gradient pixel indexes, represents current position from offset + /* + Here we compute the size of buffer needed to hold (row,col) coordinates + for each pixel previously determined to be either gradient, inner edge, + or outer edge. + + Allocation is done by requesting 4 bytes "sizeof(int)" per pixel, even + though gbuf[] is declared as unsigned short* (2 bytes) because we don't + store the pixel indexes, we only store x,y location of pixel in buffer. + + This does make the assumption that x and y can fit in 16 unsigned bits + so if Blender starts doing renders greater than 65536 in either direction + this will need to allocate gbuf[] as unsigned int* and allocate 8 bytes + per flagged pixel. + + In general, the buffer on-screen: + + Example: 9 by 9 pixel block + + . = pixel non-white in both outer and inner mask + o = pixel white in outer, but not inner mask, adjacent to "." pixel + g = pixel white in outer, but not inner mask, not adjacent to "." pixel + i = pixel white in inner mask, adjacent to "g" or "." pixel + F = pixel white in inner mask, only adjacent to other pixels white in the inner mask + + + ......... <----- pixel #80 + ..oooo... + .oggggo.. + .oggiggo. + .ogiFigo. + .oggiggo. + .oggggo.. + ..oooo... + pixel #00 -----> ......... + + gsz = 18 (18 "g" pixels above) + isz = 4 (4 "i" pixels above) + osz = 18 (18 "o" pixels above) + + + The memory in gbuf[] after filling will look like this: + + gradientFillOffset (0 pixels) innerEdgeOffset (18 pixels) outerEdgeOffset (22 pixels) + / / / + / / / + |X Y X Y X Y X Y > <----------------> <------------------------> <----------------+ + |0 2 4 6 8 10 12 14 > ... <68 70 72 74 > ... <80 82 84 86 88 90 > ... <152 154 156 158 | <- bytes + +--------------------------------> <----------------> <------------------------> <----------------+ + |g0 g0 g1 g1 g2 g2 g3 g3 > =0; x--) { + gradientFillOffset=x<<1; + t=gbuf[gradientFillOffset]; // calculate column of pixel indexed by gbuf[x] + fsz=gbuf[gradientFillOffset+1]; // calculate row of pixel indexed by gbuf[x] + dmin=0xffffffff; // reset min distance to edge pixel + for(a=outerEdgeOffset+osz-1; a>=outerEdgeOffset; a--) { // loop through all outer edge buffer pixels + ud=a<<1; + dy=t-gbuf[ud]; // set dx to gradient pixel column - outer edge pixel row + dx=fsz-gbuf[ud+1]; // set dy to gradient pixel row - outer edge pixel column + ud=dx*dx+dy*dy; // compute sum of squares + if(ud>1); // in floats vs. unsigned ints to compute an approximate + odist=*(float*)&rsl; // reciprocal square root + odist=odist*(rsopf-(rsf*odist*odist)); // -- ** this line can be iterated for more accuracy ** -- + dmin=0xffffffff; // reset min distance to edge pixel + for(a= innerEdgeOffset+isz-1; a>=innerEdgeOffset; a--) { // loop through all inside edge pixels + ud=a<<1; + dy=t-gbuf[ud]; // compute delta in Y from gradient pixel to inside edge pixel + dx=fsz-gbuf[ud+1]; // compute delta in X from gradient pixel to inside edge pixel + ud=dx*dx+dy*dy; // compute sum of squares + if(ud>1); // see notes above + idist=*(float*)&rsl; // + idist=idist*(rsopf-(rsf*idist*idist)); // + /* + Note once again that since we are using reciprocals of distance values our + proportion is already the correct intensity, and does not need to be + subracted from 1.0 like it would have if we used real distances. + */ + + /* + Here we reconstruct the pixel's memory location in the CompBuf by + Pixel Index = Pixel Column + ( Pixel Row * Row Width ) + */ + res[gbuf[gradientFillOffset+1]+(gbuf[gradientFillOffset]*rw)]=(idist/(idist+odist)); //set intensity + } + +} + + +static void node_composit_exec_doubleedgemask(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out) { + + float *imask; // imask = pointer to inner mask pixel buffer + float *omask; // omask = pointer to outer mask pixel buffer + float *res; // res = pointer to output mask + + unsigned int *lres; // lres = unsigned int pointer to output pixel buffer (for bit operations) + unsigned int *limask; // limask = unsigned int pointer to inner mask (for bit operations) + unsigned int *lomask; // lomask = unsigned int pointer to outer mask (for bit operations) + + int rw; // rw = pixel row width + int t; // t = total number of pixels in buffer - 1 (used for loop starts) + int fsz; // size of the frame + + unsigned int isz=0; // size (in pixels) of inside edge pixel index buffer + unsigned int osz=0; // size (in pixels) of outside edge pixel index buffer + unsigned int gsz=0; // size (in pixels) of gradient pixel index buffer + unsigned int rsize[3]; // size storage to pass to helper functions + unsigned int innerEdgeOffset=0; // offset into final buffer where inner edge pixel indexes start + unsigned int outerEdgeOffset=0; // offset into final buffer where outer edge pixel indexes start + + unsigned short *gbuf; // gradient/inner/outer pixel location index buffer + + CompBuf *cbuf; // pointer, will be set to inner mask data + CompBuf *dbuf; // pointer, will be set to outer mask data + CompBuf *stackbuf; // pointer, will get allocated as output buffer + + if(out[0]->hasoutput==0) { // if the node's output socket is not connected to anything... + return; // do not execute any further, just exit the node immediately + } + + if(in[0]->data && in[1]->data) { // if both input sockets have some data coming in... + cbuf= in[0]->data; // get a pointer to the inner mask data + dbuf= in[1]->data; // get a pointer to the outer mask data + if(cbuf->type!=CB_VAL || dbuf->type!=CB_VAL) { // if either input socket has an incorrect data type coming in + return; // exit the node immediately + } + + t=(cbuf->x*cbuf->y)-1; // determine size of the frame + + stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); // allocate the output buffer + + imask= cbuf->rect; // set the inner mask + omask= dbuf->rect; // set the outer mask + res= stackbuf->rect; // set output pointer + lres= (unsigned int*)res; // unsigned int pointer to output buffer (for bit level ops) + limask=(unsigned int*)imask; // unsigned int pointer to input mask (for bit level ops) + lomask=(unsigned int*)omask; // unsigned int pointer to output mask (for bit level ops) + rw= cbuf->x; // width of a row of pixels + + + /* + The whole buffer is broken up into 4 parts. The four CORNERS, the FIRST and LAST rows, the + LEFT and RIGHT edges (excluding the corner pixels), and all OTHER rows. + This allows for quick computation of outer edge pixels where + a screen edge pixel is marked to be gradient. + + The pixel type (gradient vs inner-edge vs outer-edge) tests change + depending on the user selected "Inner Edge Mode" and the user selected + "Buffer Edge Mode" on the node's GUI. There are 4 sets of basically the + same algorithm: + + 1.) Inner Edge -> Adjacent Only + Buffer Edge -> Keep Inside + + 2.) Inner Edge -> Adjacent Only + Buffer Edge -> Bleed Out + + 3.) Inner Edge -> All + Buffer Edge -> Keep Inside + + 4.) Inner Edge -> All + Buffer Edge -> Bleed Out + + Each version has slightly different criteria for detecting an edge pixel. + */ + if(node->custom2) { // if "adjacent only" inner edge mode is turned on + if(node->custom1) { // if "keep inside" buffer edge mode is turned on + do_adjacentKeepBorders(t,rw,limask,lomask,lres,res,rsize); + }else{ // "bleed out" buffer edge mode is turned on + do_adjacentBleedBorders(t,rw,limask,lomask,lres,res,rsize); + } + isz=rsize[0]; // set up inner edge, outer edge, and gradient buffer sizes after border pass + osz=rsize[1]; + gsz=rsize[2]; + // detect edges in all non-border pixels in the buffer + do_adjacentEdgeDetection(t,rw,limask,lomask,lres,res,rsize,isz,osz,gsz); + }else{ // "all" inner edge mode is turned on + if(node->custom1) { // if "keep inside" buffer edge mode is turned on + do_allKeepBorders(t,rw,limask,lomask,lres,res,rsize); + }else{ // "bleed out" buffer edge mode is turned on + do_allBleedBorders(t,rw,limask,lomask,lres,res,rsize); + } + isz=rsize[0]; // set up inner edge, outer edge, and gradient buffer sizes after border pass + osz=rsize[1]; + gsz=rsize[2]; + // detect edges in all non-border pixels in the buffer + do_allEdgeDetection(t,rw,limask,lomask,lres,res,rsize,isz,osz,gsz); + } + + isz=rsize[0]; // set edge and gradient buffer sizes once again... + osz=rsize[1]; // the sizes in rsize[] may have been modified + gsz=rsize[2]; // by the do_*EdgeDetection() function. + + // quick check for existance of edges in the buffer... + // if we don't have any one of the three sizes, the other two make no difference visually, + // so we can just pass the inner input buffer back as output. + if(!gsz || !isz || !osz) { + out[0]->data= stackbuf; // point the node output buffer to our filled buffer + return; + } + + + fsz=gsz+isz+osz; // calculate size of pixel index buffer needed + gbuf= MEM_mallocN(fsz*sizeof(int), "grd buf"); // allocate edge/gradient pixel index buffer + + do_createEdgeLocationBuffer(t,rw,lres,res,gbuf,&innerEdgeOffset,&outerEdgeOffset,isz,gsz); + do_fillGradientBuffer(rw,res,gbuf,isz,osz,gsz,innerEdgeOffset,outerEdgeOffset); + + MEM_freeN(gbuf); // free the gradient index buffer + out[0]->data= stackbuf; // point the node output buffer to our filled buffer + } +} + +void register_node_type_cmp_doubleedgemask(bNodeTreeType *ttype) { + static bNodeType ntype; // allocate a node type data structure + + node_type_base(ttype, &ntype, CMP_NODE_DOUBLEEDGEMASK, "Double Edge Mask", NODE_CLASS_MATTE, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_doubleedgemask_in, cmp_node_doubleedgemask_out); + node_type_size(&ntype, 210, 210, 210); + node_type_exec(&ntype, node_composit_exec_doubleedgemask); + + nodeRegisterType(ttype, &ntype); +} diff -Nru blender-2.61/source/blender/nodes/composite/nodes/node_composite_image.c blender-2.62/source/blender/nodes/composite/nodes/node_composite_image.c --- blender-2.61/source/blender/nodes/composite/nodes/node_composite_image.c 2011-12-13 19:51:18.000000000 +0000 +++ blender-2.62/source/blender/nodes/composite/nodes/node_composite_image.c 2012-02-15 19:36:07.000000000 +0000 @@ -36,25 +36,34 @@ /* **************** IMAGE (and RenderResult, multilayer image) ******************** */ static bNodeSocketTemplate cmp_node_rlayers_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_FLOAT, 0, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_FLOAT, 0, "Z", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_VECTOR, 0, "UV", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_VECTOR, 0, "Speed", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 0, "Diffuse", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 0, "Specular", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 0, "Shadow", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 0, "AO", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 0, "Reflect", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 0, "Refract", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 0, "Indirect", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_FLOAT, 0, "IndexOB", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_FLOAT, 0, "IndexMA", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_FLOAT, 0, "Mist", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 0, "Emit", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 0, "Environment",0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_FLOAT, 0, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_FLOAT, 0, "Z", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_VECTOR, 0, "UV", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_VECTOR, 0, "Speed", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 0, "Diffuse", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 0, "Specular", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 0, "Shadow", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 0, "AO", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 0, "Reflect", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 0, "Refract", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 0, "Indirect", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_FLOAT, 0, "IndexOB", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_FLOAT, 0, "IndexMA", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_FLOAT, 0, "Mist", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 0, "Emit", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 0, "Environment", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 0, "Diffuse Direct", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 0, "Diffuse Indirect", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 0, "Diffuse Color", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 0, "Glossy Direct", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 0, "Glossy Indirect", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 0, "Glossy Color", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 0, "Transmission Direct", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 0, "Transmission Indirect", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 0, "Transmission Color", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, { -1, 0, "" } }; @@ -62,6 +71,7 @@ float *node_composit_get_float_buffer(RenderData *rd, ImBuf *ibuf, int *alloc) { float *rect; + int predivide= (ibuf->flags & IB_cm_predivide); *alloc= FALSE; @@ -71,7 +81,11 @@ } else { rect= MEM_mapallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, "node_composit_get_image"); - srgb_to_linearrgb_rgba_rgba_buf(rect, ibuf->rect_float, ibuf->x * ibuf->y); + + IMB_buffer_float_from_float(rect, ibuf->rect_float, + 4, IB_PROFILE_LINEAR_RGB, IB_PROFILE_SRGB, predivide, + ibuf->x, ibuf->y, ibuf->x, ibuf->x); + *alloc= TRUE; } } @@ -81,7 +95,11 @@ } else { rect= MEM_mapallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, "node_composit_get_image"); - linearrgb_to_srgb_rgba_rgba_buf(rect, ibuf->rect_float, ibuf->x * ibuf->y); + + IMB_buffer_float_from_float(rect, ibuf->rect_float, + 4, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, predivide, + ibuf->x, ibuf->y, ibuf->x, ibuf->x); + *alloc= TRUE; } } @@ -229,6 +247,24 @@ out[RRES_OUT_EMIT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_EMIT); if(out[RRES_OUT_ENV]->hasoutput) out[RRES_OUT_ENV]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_ENVIRONMENT); + if(out[RRES_OUT_DIFF_DIRECT]->hasoutput) + out[RRES_OUT_DIFF_DIRECT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_DIFFUSE_DIRECT); + if(out[RRES_OUT_DIFF_INDIRECT]->hasoutput) + out[RRES_OUT_DIFF_INDIRECT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_DIFFUSE_INDIRECT); + if(out[RRES_OUT_DIFF_COLOR]->hasoutput) + out[RRES_OUT_DIFF_COLOR]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_DIFFUSE_COLOR); + if(out[RRES_OUT_GLOSSY_DIRECT]->hasoutput) + out[RRES_OUT_GLOSSY_DIRECT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_GLOSSY_DIRECT); + if(out[RRES_OUT_GLOSSY_INDIRECT]->hasoutput) + out[RRES_OUT_GLOSSY_INDIRECT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_GLOSSY_INDIRECT); + if(out[RRES_OUT_GLOSSY_COLOR]->hasoutput) + out[RRES_OUT_GLOSSY_COLOR]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_GLOSSY_COLOR); + if(out[RRES_OUT_TRANSM_DIRECT]->hasoutput) + out[RRES_OUT_TRANSM_DIRECT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_TRANSM_DIRECT); + if(out[RRES_OUT_TRANSM_INDIRECT]->hasoutput) + out[RRES_OUT_TRANSM_INDIRECT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_TRANSM_INDIRECT); + if(out[RRES_OUT_TRANSM_COLOR]->hasoutput) + out[RRES_OUT_TRANSM_COLOR]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_TRANSM_COLOR); } @@ -393,6 +429,24 @@ out[RRES_OUT_EMIT]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_EMIT); if(out[RRES_OUT_ENV]->hasoutput) out[RRES_OUT_ENV]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_ENVIRONMENT); + if(out[RRES_OUT_DIFF_DIRECT]->hasoutput) + out[RRES_OUT_DIFF_DIRECT]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_DIFFUSE_DIRECT); + if(out[RRES_OUT_DIFF_INDIRECT]->hasoutput) + out[RRES_OUT_DIFF_INDIRECT]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_DIFFUSE_INDIRECT); + if(out[RRES_OUT_DIFF_COLOR]->hasoutput) + out[RRES_OUT_DIFF_COLOR]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_DIFFUSE_COLOR); + if(out[RRES_OUT_GLOSSY_DIRECT]->hasoutput) + out[RRES_OUT_GLOSSY_DIRECT]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_GLOSSY_DIRECT); + if(out[RRES_OUT_GLOSSY_INDIRECT]->hasoutput) + out[RRES_OUT_GLOSSY_INDIRECT]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_GLOSSY_INDIRECT); + if(out[RRES_OUT_GLOSSY_COLOR]->hasoutput) + out[RRES_OUT_GLOSSY_COLOR]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_GLOSSY_COLOR); + if(out[RRES_OUT_TRANSM_DIRECT]->hasoutput) + out[RRES_OUT_TRANSM_DIRECT]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_TRANSM_DIRECT); + if(out[RRES_OUT_TRANSM_INDIRECT]->hasoutput) + out[RRES_OUT_TRANSM_INDIRECT]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_TRANSM_INDIRECT); + if(out[RRES_OUT_TRANSM_COLOR]->hasoutput) + out[RRES_OUT_TRANSM_COLOR]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_TRANSM_COLOR); } static void node_composit_exec_rlayers(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack **out) diff -Nru blender-2.61/source/blender/nodes/intern/node_common.c blender-2.62/source/blender/nodes/intern/node_common.c --- blender-2.61/source/blender/nodes/intern/node_common.c 2011-12-13 19:51:10.000000000 +0000 +++ blender-2.62/source/blender/nodes/intern/node_common.c 2012-02-15 19:35:56.000000000 +0000 @@ -100,8 +100,8 @@ sock->groupsock = gsock; sock->limit = (in_out==SOCK_IN ? 1 : 0xFFF); - if (gsock->default_value) - sock->default_value = MEM_dupallocN(gsock->default_value); + sock->default_value = node_socket_make_default_value(sock->type); + node_socket_copy_default_value(sock->type, sock->default_value, gsock->default_value); if(lb) BLI_addtail(lb, sock); @@ -247,177 +247,6 @@ return gnode; } -/* XXX This is a makeshift function to have useful initial group socket values. - * In the end this should be implemented by a flexible socket data conversion system, - * which is yet to be implemented. The idea is that beside default standard conversions, - * such as int-to-float, it should be possible to quickly select a conversion method or - * a chain of conversions for each input, whenever there is more than one option. - * E.g. a vector-to-float conversion could use either of the x/y/z components or - * the vector length. - * - * In the interface this could be implemented by a pseudo-script textbox on linked inputs, - * with quick selection from a predefined list of conversion options. Some Examples: - * - vector component 'z' (vector->float): "z" - * - greyscale color (float->color): "grey" - * - color luminance (color->float): "lum" - * - matrix column 2 length (matrix->vector->float): "col[1].len" - * - mesh vertex coordinate 'y' (mesh->vertex->vector->float): "vertex.co.y" - * - * The actual conversion is then done by a series of conversion functions, - * which are defined in the socket type structs. - */ -static void convert_socket_value(bNodeSocket *from, bNodeSocket *to) -{ - /* XXX only one of these pointers is valid! just putting them here for convenience */ - bNodeSocketValueFloat *fromfloat= (bNodeSocketValueFloat*)from->default_value; - bNodeSocketValueInt *fromint= (bNodeSocketValueInt*)from->default_value; - bNodeSocketValueBoolean *frombool= (bNodeSocketValueBoolean*)from->default_value; - bNodeSocketValueVector *fromvector= (bNodeSocketValueVector*)from->default_value; - bNodeSocketValueRGBA *fromrgba= (bNodeSocketValueRGBA*)from->default_value; - - bNodeSocketValueFloat *tofloat= (bNodeSocketValueFloat*)to->default_value; - bNodeSocketValueInt *toint= (bNodeSocketValueInt*)to->default_value; - bNodeSocketValueBoolean *tobool= (bNodeSocketValueBoolean*)to->default_value; - bNodeSocketValueVector *tovector= (bNodeSocketValueVector*)to->default_value; - bNodeSocketValueRGBA *torgba= (bNodeSocketValueRGBA*)to->default_value; - - switch (from->type) { - case SOCK_FLOAT: - switch (to->type) { - case SOCK_FLOAT: - tofloat->value = fromfloat->value; - break; - case SOCK_INT: - toint->value = (int)fromfloat->value; - break; - case SOCK_BOOLEAN: - tobool->value = (fromfloat->value > 0.0f); - break; - case SOCK_VECTOR: - tovector->value[0] = tovector->value[1] = tovector->value[2] = fromfloat->value; - break; - case SOCK_RGBA: - torgba->value[0] = torgba->value[1] = torgba->value[2] = torgba->value[3] = fromfloat->value; - break; - } - break; - case SOCK_INT: - switch (to->type) { - case SOCK_FLOAT: - tofloat->value = (float)fromint->value; - break; - case SOCK_INT: - toint->value = fromint->value; - break; - case SOCK_BOOLEAN: - tobool->value = (fromint->value > 0); - break; - case SOCK_VECTOR: - tovector->value[0] = tovector->value[1] = tovector->value[2] = (float)fromint->value; - break; - case SOCK_RGBA: - torgba->value[0] = torgba->value[1] = torgba->value[2] = torgba->value[3] = (float)fromint->value; - break; - } - break; - case SOCK_BOOLEAN: - switch (to->type) { - case SOCK_FLOAT: - tofloat->value = (float)frombool->value; - break; - case SOCK_INT: - toint->value = (int)frombool->value; - break; - case SOCK_BOOLEAN: - tobool->value = frombool->value; - break; - case SOCK_VECTOR: - tovector->value[0] = tovector->value[1] = tovector->value[2] = (float)frombool->value; - break; - case SOCK_RGBA: - torgba->value[0] = torgba->value[1] = torgba->value[2] = torgba->value[3] = (float)frombool->value; - break; - } - break; - case SOCK_VECTOR: - switch (to->type) { - case SOCK_FLOAT: - tofloat->value = fromvector->value[0]; - break; - case SOCK_INT: - toint->value = (int)fromvector->value[0]; - break; - case SOCK_BOOLEAN: - tobool->value = (fromvector->value[0] > 0.0f); - break; - case SOCK_VECTOR: - copy_v3_v3(tovector->value, fromvector->value); - break; - case SOCK_RGBA: - copy_v3_v3(torgba->value, fromvector->value); - torgba->value[3] = 1.0f; - break; - } - break; - case SOCK_RGBA: - switch (to->type) { - case SOCK_FLOAT: - tofloat->value = fromrgba->value[0]; - break; - case SOCK_INT: - toint->value = (int)fromrgba->value[0]; - break; - case SOCK_BOOLEAN: - tobool->value = (fromrgba->value[0] > 0.0f); - break; - case SOCK_VECTOR: - copy_v3_v3(tovector->value, fromrgba->value); - break; - case SOCK_RGBA: - copy_v4_v4(torgba->value, fromrgba->value); - break; - } - break; - } -} - -static void copy_socket_value(bNodeSocket *from, bNodeSocket *to) -{ - /* XXX only one of these pointers is valid! just putting them here for convenience */ - bNodeSocketValueFloat *fromfloat= (bNodeSocketValueFloat*)from->default_value; - bNodeSocketValueInt *fromint= (bNodeSocketValueInt*)from->default_value; - bNodeSocketValueBoolean *frombool= (bNodeSocketValueBoolean*)from->default_value; - bNodeSocketValueVector *fromvector= (bNodeSocketValueVector*)from->default_value; - bNodeSocketValueRGBA *fromrgba= (bNodeSocketValueRGBA*)from->default_value; - - bNodeSocketValueFloat *tofloat= (bNodeSocketValueFloat*)to->default_value; - bNodeSocketValueInt *toint= (bNodeSocketValueInt*)to->default_value; - bNodeSocketValueBoolean *tobool= (bNodeSocketValueBoolean*)to->default_value; - bNodeSocketValueVector *tovector= (bNodeSocketValueVector*)to->default_value; - bNodeSocketValueRGBA *torgba= (bNodeSocketValueRGBA*)to->default_value; - - if (from->type != to->type) - return; - - switch (from->type) { - case SOCK_FLOAT: - *tofloat = *fromfloat; - break; - case SOCK_INT: - *toint = *fromint; - break; - case SOCK_BOOLEAN: - *tobool = *frombool; - break; - case SOCK_VECTOR: - *tovector = *fromvector; - break; - case SOCK_RGBA: - *torgba = *fromrgba; - break; - } -} - /* returns 1 if its OK */ int node_group_ungroup(bNodeTree *ntree, bNode *gnode) { @@ -489,7 +318,7 @@ } else { /* copy the default input value from the group socket default to the external socket */ - convert_socket_value(gsock, link->tosock); + node_socket_convert_default_value(link->tosock->type, link->tosock->default_value, gsock->type, gsock->default_value); } } } @@ -517,7 +346,7 @@ } else { /* copy the default input value from the group node socket default to the internal socket */ - convert_socket_value(insock, link->tosock); + node_socket_convert_default_value(link->tosock->type, link->tosock->default_value, insock->type, insock->default_value); nodeRemLink(wgroup, link); } } @@ -530,7 +359,8 @@ BLI_addtail(&ntree->links, link); } - /* and copy across the animation */ + /* and copy across the animation, + * note that the animation data's action can be NULL here */ if (wgroup->adt) { LinkData *ld, *ldn=NULL; bAction *waction; @@ -550,7 +380,9 @@ } /* free temp action too */ - free_libblock(&G.main->action, waction); + if (waction) { + free_libblock(&G.main->action, waction); + } } /* delete the group instance. this also removes old input links! */ @@ -597,7 +429,7 @@ bNodeSocket *gsock= node_group_add_socket(ngroup, sock->name, sock->type, in_out); /* initialize the default value. */ - copy_socket_value(sock, gsock); + node_socket_copy_default_value(gsock->type, gsock->default_value, sock->default_value); return gsock; } @@ -609,21 +441,21 @@ for (node=ngroup->nodes.first; node; node=node->next) { for (sock=node->inputs.first; sock; sock=sock->next) { - if (!sock->link && !(sock->flag & SOCK_HIDDEN)) { + if (!sock->link && !nodeSocketIsHidden(sock)) { gsock = node_group_add_socket(ngroup, sock->name, sock->type, SOCK_IN); /* initialize the default value. */ - copy_socket_value(sock, gsock); + node_socket_copy_default_value(gsock->type, gsock->default_value, sock->default_value); sock->link = nodeAddLink(ngroup, NULL, gsock, node, sock); } } for (sock=node->outputs.first; sock; sock=sock->next) { - if (nodeCountSocketLinks(ngroup, sock)==0 && !(sock->flag & SOCK_HIDDEN)) { + if (nodeCountSocketLinks(ngroup, sock)==0 && !nodeSocketIsHidden(sock)) { gsock = node_group_add_socket(ngroup, sock->name, sock->type, SOCK_OUT); /* initialize the default value. */ - copy_socket_value(sock, gsock); + node_socket_copy_default_value(gsock->type, gsock->default_value, sock->default_value); gsock->link = nodeAddLink(ngroup, node, sock, NULL, gsock); } @@ -829,11 +661,12 @@ void node_forloop_init(bNodeTree *ntree, bNode *node, bNodeTemplate *ntemp) { - /* bNodeSocket *sock; */ /* UNUSED */ + bNodeSocket *sock; node->id = (ID*)ntemp->ngroup; - /* sock = */ nodeAddInputFloat(ntree, node, "Iterations", PROP_UNSIGNED, 1, 0, 10000); + sock = nodeAddSocket(ntree, node, SOCK_IN, "Iterations", SOCK_FLOAT); + node_socket_set_default_value_float(sock->default_value, PROP_UNSIGNED, 1, 0, 10000); /* NB: group socket input/output roles are inverted internally! * Group "inputs" work as outputs in links and vice versa. @@ -935,11 +768,12 @@ void node_whileloop_init(bNodeTree *ntree, bNode *node, bNodeTemplate *ntemp) { - /* bNodeSocket *sock; */ /* UNUSED */ + bNodeSocket *sock; node->id = (ID*)ntemp->ngroup; - /* sock = */ nodeAddInputFloat(ntree, node, "Condition", PROP_NONE, 1, 0, 1); + sock = nodeAddSocket(ntree, node, SOCK_IN, "Condition", SOCK_FLOAT); + node_socket_set_default_value_float(sock->default_value, PROP_NONE, 1, 0, 1); /* max iterations */ node->custom1 = 10000; diff -Nru blender-2.61/source/blender/nodes/intern/node_socket.c blender-2.62/source/blender/nodes/intern/node_socket.c --- blender-2.61/source/blender/nodes/intern/node_socket.c 2011-12-13 19:51:10.000000000 +0000 +++ blender-2.62/source/blender/nodes/intern/node_socket.c 2012-02-15 19:35:56.000000000 +0000 @@ -29,6 +29,7 @@ * \ingroup nodes */ +#include #include "DNA_node_types.h" @@ -172,171 +173,311 @@ #undef INIT_TYPE } -struct bNodeSocket *nodeAddInputInt(struct bNodeTree *ntree, struct bNode *node, const char *name, PropertySubType subtype, - int value, int min, int max) +void *node_socket_make_default_value(int type) { - bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_INT); - bNodeSocketValueInt *dval= (bNodeSocketValueInt*)sock->default_value; - dval->subtype = subtype; - dval->value = value; - dval->min = min; - dval->max = max; - return sock; -} -struct bNodeSocket *nodeAddOutputInt(struct bNodeTree *ntree, struct bNode *node, const char *name) -{ - bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_INT); - return sock; + /* XXX currently just allocates from stype->structsize. + * it might become necessary to do more complex allocations for later types. + */ + bNodeSocketType *stype = ntreeGetSocketType(type); + if (stype->value_structsize > 0) { + void *default_value = MEM_callocN(stype->value_structsize, "default socket value"); + return default_value; + } + else + return NULL; } -struct bNodeSocket *nodeAddInputFloat(struct bNodeTree *ntree, struct bNode *node, const char *name, PropertySubType subtype, - float value, float min, float max) -{ - bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_FLOAT); - bNodeSocketValueFloat *dval= (bNodeSocketValueFloat*)sock->default_value; - dval->subtype = subtype; - dval->value = value; - dval->min = min; - dval->max = max; - return sock; -} -struct bNodeSocket *nodeAddOutputFloat(struct bNodeTree *ntree, struct bNode *node, const char *name) +void node_socket_free_default_value(int UNUSED(type), void *default_value) { - bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_FLOAT); - return sock; + /* XXX can just free the pointee for all current socket types. */ + if (default_value) + MEM_freeN(default_value); } -struct bNodeSocket *nodeAddInputBoolean(struct bNodeTree *ntree, struct bNode *node, const char *name, char value) -{ - bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_BOOLEAN); - bNodeSocketValueBoolean *dval= (bNodeSocketValueBoolean*)sock->default_value; - dval->value = value; - return sock; -} -struct bNodeSocket *nodeAddOutputBoolean(struct bNodeTree *ntree, struct bNode *node, const char *name) +void node_socket_init_default_value(int type, void *default_value) { - bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_BOOLEAN); - return sock; + switch (type) { + case SOCK_FLOAT: + node_socket_set_default_value_float(default_value, PROP_NONE, 0.0f, -FLT_MAX, FLT_MAX); + break; + case SOCK_INT: + node_socket_set_default_value_int(default_value, PROP_NONE, 0, INT_MIN, INT_MAX); + break; + case SOCK_BOOLEAN: + node_socket_set_default_value_boolean(default_value, FALSE); + break; + case SOCK_VECTOR: + node_socket_set_default_value_vector(default_value, PROP_NONE, 0.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX); + break; + case SOCK_RGBA: + node_socket_set_default_value_rgba(default_value, 0.0f, 0.0f, 0.0f, 1.0f); + break; + case SOCK_SHADER: + node_socket_set_default_value_shader(default_value); + break; + case SOCK_MESH: + node_socket_set_default_value_mesh(default_value); + break; + } } -struct bNodeSocket *nodeAddInputVector(struct bNodeTree *ntree, struct bNode *node, const char *name, PropertySubType subtype, - float x, float y, float z, float min, float max) -{ - bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_VECTOR); - bNodeSocketValueVector *dval= (bNodeSocketValueVector*)sock->default_value; - dval->subtype = subtype; - dval->value[0] = x; - dval->value[1] = y; - dval->value[2] = z; - dval->min = min; - dval->max = max; - return sock; -} -struct bNodeSocket *nodeAddOutputVector(struct bNodeTree *ntree, struct bNode *node, const char *name) +void node_socket_set_default_value_int(void *default_value, PropertySubType subtype, int value, int min, int max) { - bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_VECTOR); - return sock; + bNodeSocketValueInt *val = default_value; + val->subtype = subtype; + val->value = value; + val->min = min; + val->max = max; } -struct bNodeSocket *nodeAddInputRGBA(struct bNodeTree *ntree, struct bNode *node, const char *name, - float r, float g, float b, float a) +void node_socket_set_default_value_float(void *default_value, PropertySubType subtype, float value, float min, float max) { - bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_RGBA); - bNodeSocketValueRGBA *dval= (bNodeSocketValueRGBA*)sock->default_value; - dval->value[0] = r; - dval->value[1] = g; - dval->value[2] = b; - dval->value[3] = a; - return sock; + bNodeSocketValueFloat *val = default_value; + val->subtype = subtype; + val->value = value; + val->min = min; + val->max = max; } -struct bNodeSocket *nodeAddOutputRGBA(struct bNodeTree *ntree, struct bNode *node, const char *name) + +void node_socket_set_default_value_boolean(void *default_value, char value) { - bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_RGBA); - return sock; + bNodeSocketValueBoolean *val = default_value; + val->value = value; } -struct bNodeSocket *nodeAddInputShader(struct bNodeTree *ntree, struct bNode *node, const char *name) +void node_socket_set_default_value_vector(void *default_value, PropertySubType subtype, float x, float y, float z, float min, float max) { - bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_SHADER); - return sock; + bNodeSocketValueVector *val = default_value; + val->subtype = subtype; + val->value[0] = x; + val->value[1] = y; + val->value[2] = z; + val->min = min; + val->max = max; } -struct bNodeSocket *nodeAddOutputShader(struct bNodeTree *ntree, struct bNode *node, const char *name) + +void node_socket_set_default_value_rgba(void *default_value, float r, float g, float b, float a) { - bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_SHADER); - return sock; + bNodeSocketValueRGBA *val = default_value; + val->value[0] = r; + val->value[1] = g; + val->value[2] = b; + val->value[3] = a; } -struct bNodeSocket *nodeAddInputMesh(struct bNodeTree *ntree, struct bNode *node, const char *name) +void node_socket_set_default_value_shader(void *UNUSED(default_value)) { - bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_MESH); - return sock; } -struct bNodeSocket *nodeAddOutputMesh(struct bNodeTree *ntree, struct bNode *node, const char *name) + +void node_socket_set_default_value_mesh(void *UNUSED(default_value)) { - bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_MESH); - return sock; } -struct bNodeSocket *node_add_input_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp) + +void node_socket_copy_default_value(int type, void *to_default_value, void *from_default_value) { - bNodeSocket *sock; - switch (stemp->type) { - case SOCK_INT: - sock = nodeAddInputInt(ntree, node, stemp->name, stemp->subtype, (int)stemp->val1, (int)stemp->min, (int)stemp->max); - break; + /* XXX only one of these pointers is valid! just putting them here for convenience */ + bNodeSocketValueFloat *fromfloat= (bNodeSocketValueFloat*)from_default_value; + bNodeSocketValueInt *fromint= (bNodeSocketValueInt*)from_default_value; + bNodeSocketValueBoolean *frombool= (bNodeSocketValueBoolean*)from_default_value; + bNodeSocketValueVector *fromvector= (bNodeSocketValueVector*)from_default_value; + bNodeSocketValueRGBA *fromrgba= (bNodeSocketValueRGBA*)from_default_value; + + bNodeSocketValueFloat *tofloat= (bNodeSocketValueFloat*)to_default_value; + bNodeSocketValueInt *toint= (bNodeSocketValueInt*)to_default_value; + bNodeSocketValueBoolean *tobool= (bNodeSocketValueBoolean*)to_default_value; + bNodeSocketValueVector *tovector= (bNodeSocketValueVector*)to_default_value; + bNodeSocketValueRGBA *torgba= (bNodeSocketValueRGBA*)to_default_value; + + switch (type) { case SOCK_FLOAT: - sock = nodeAddInputFloat(ntree, node, stemp->name, stemp->subtype, stemp->val1, stemp->min, stemp->max); + *tofloat = *fromfloat; + break; + case SOCK_INT: + *toint = *fromint; break; case SOCK_BOOLEAN: - sock = nodeAddInputBoolean(ntree, node, stemp->name, (char)stemp->val1); + *tobool = *frombool; break; case SOCK_VECTOR: - sock = nodeAddInputVector(ntree, node, stemp->name, stemp->subtype, stemp->val1, stemp->val2, stemp->val3, stemp->min, stemp->max); + *tovector = *fromvector; break; case SOCK_RGBA: - sock = nodeAddInputRGBA(ntree, node, stemp->name, stemp->val1, stemp->val2, stemp->val3, stemp->val4); + *torgba = *fromrgba; break; - case SOCK_SHADER: - sock = nodeAddInputShader(ntree, node, stemp->name); + } +} + +/* XXX This is a makeshift function to have useful initial group socket values. + * In the end this should be implemented by a flexible socket data conversion system, + * which is yet to be implemented. The idea is that beside default standard conversions, + * such as int-to-float, it should be possible to quickly select a conversion method or + * a chain of conversions for each input, whenever there is more than one option. + * E.g. a vector-to-float conversion could use either of the x/y/z components or + * the vector length. + * + * In the interface this could be implemented by a pseudo-script textbox on linked inputs, + * with quick selection from a predefined list of conversion options. Some Examples: + * - vector component 'z' (vector->float): "z" + * - greyscale color (float->color): "grey" + * - color luminance (color->float): "lum" + * - matrix column 2 length (matrix->vector->float): "col[1].len" + * - mesh vertex coordinate 'y' (mesh->vertex->vector->float): "vertex.co.y" + * + * The actual conversion is then done by a series of conversion functions, + * which are defined in the socket type structs. + */ +void node_socket_convert_default_value(int to_type, void *to_default_value, int from_type, void *from_default_value) +{ + /* XXX only one of these pointers is valid! just putting them here for convenience */ + bNodeSocketValueFloat *fromfloat= (bNodeSocketValueFloat*)from_default_value; + bNodeSocketValueInt *fromint= (bNodeSocketValueInt*)from_default_value; + bNodeSocketValueBoolean *frombool= (bNodeSocketValueBoolean*)from_default_value; + bNodeSocketValueVector *fromvector= (bNodeSocketValueVector*)from_default_value; + bNodeSocketValueRGBA *fromrgba= (bNodeSocketValueRGBA*)from_default_value; + + bNodeSocketValueFloat *tofloat= (bNodeSocketValueFloat*)to_default_value; + bNodeSocketValueInt *toint= (bNodeSocketValueInt*)to_default_value; + bNodeSocketValueBoolean *tobool= (bNodeSocketValueBoolean*)to_default_value; + bNodeSocketValueVector *tovector= (bNodeSocketValueVector*)to_default_value; + bNodeSocketValueRGBA *torgba= (bNodeSocketValueRGBA*)to_default_value; + + switch (from_type) { + case SOCK_FLOAT: + switch (to_type) { + case SOCK_FLOAT: + tofloat->value = fromfloat->value; + break; + case SOCK_INT: + toint->value = (int)fromfloat->value; + break; + case SOCK_BOOLEAN: + tobool->value = (fromfloat->value > 0.0f); + break; + case SOCK_VECTOR: + tovector->value[0] = tovector->value[1] = tovector->value[2] = fromfloat->value; + break; + case SOCK_RGBA: + torgba->value[0] = torgba->value[1] = torgba->value[2] = torgba->value[3] = fromfloat->value; + break; + } break; - case SOCK_MESH: - sock = nodeAddInputMesh(ntree, node, stemp->name); + case SOCK_INT: + switch (to_type) { + case SOCK_FLOAT: + tofloat->value = (float)fromint->value; + break; + case SOCK_INT: + toint->value = fromint->value; + break; + case SOCK_BOOLEAN: + tobool->value = (fromint->value > 0); + break; + case SOCK_VECTOR: + tovector->value[0] = tovector->value[1] = tovector->value[2] = (float)fromint->value; + break; + case SOCK_RGBA: + torgba->value[0] = torgba->value[1] = torgba->value[2] = torgba->value[3] = (float)fromint->value; + break; + } + break; + case SOCK_BOOLEAN: + switch (to_type) { + case SOCK_FLOAT: + tofloat->value = (float)frombool->value; + break; + case SOCK_INT: + toint->value = (int)frombool->value; + break; + case SOCK_BOOLEAN: + tobool->value = frombool->value; + break; + case SOCK_VECTOR: + tovector->value[0] = tovector->value[1] = tovector->value[2] = (float)frombool->value; + break; + case SOCK_RGBA: + torgba->value[0] = torgba->value[1] = torgba->value[2] = torgba->value[3] = (float)frombool->value; + break; + } + break; + case SOCK_VECTOR: + switch (to_type) { + case SOCK_FLOAT: + tofloat->value = fromvector->value[0]; + break; + case SOCK_INT: + toint->value = (int)fromvector->value[0]; + break; + case SOCK_BOOLEAN: + tobool->value = (fromvector->value[0] > 0.0f); + break; + case SOCK_VECTOR: + copy_v3_v3(tovector->value, fromvector->value); + break; + case SOCK_RGBA: + copy_v3_v3(torgba->value, fromvector->value); + torgba->value[3] = 1.0f; + break; + } + break; + case SOCK_RGBA: + switch (to_type) { + case SOCK_FLOAT: + tofloat->value = fromrgba->value[0]; + break; + case SOCK_INT: + toint->value = (int)fromrgba->value[0]; + break; + case SOCK_BOOLEAN: + tobool->value = (fromrgba->value[0] > 0.0f); + break; + case SOCK_VECTOR: + copy_v3_v3(tovector->value, fromrgba->value); + break; + case SOCK_RGBA: + copy_v4_v4(torgba->value, fromrgba->value); + break; + } break; - default: - sock = nodeAddSocket(ntree, node, SOCK_IN, stemp->name, stemp->type); } - sock->flag |= stemp->flag; - return sock; } -struct bNodeSocket *node_add_output_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp) + +struct bNodeSocket *node_add_input_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp) { - bNodeSocket *sock; + bNodeSocket *sock = nodeAddSocket(ntree, node, SOCK_IN, stemp->name, stemp->type); + sock->flag |= stemp->flag; + switch (stemp->type) { case SOCK_INT: - sock = nodeAddOutputInt(ntree, node, stemp->name); + node_socket_set_default_value_int(sock->default_value, stemp->subtype, (int)stemp->val1, (int)stemp->min, (int)stemp->max); break; case SOCK_FLOAT: - sock = nodeAddOutputFloat(ntree, node, stemp->name); + node_socket_set_default_value_float(sock->default_value, stemp->subtype, stemp->val1, stemp->min, stemp->max); break; case SOCK_BOOLEAN: - sock = nodeAddOutputBoolean(ntree, node, stemp->name); + node_socket_set_default_value_boolean(sock->default_value, (char)stemp->val1); break; case SOCK_VECTOR: - sock = nodeAddOutputVector(ntree, node, stemp->name); + node_socket_set_default_value_vector(sock->default_value, stemp->subtype, stemp->val1, stemp->val2, stemp->val3, stemp->min, stemp->max); break; case SOCK_RGBA: - sock = nodeAddOutputRGBA(ntree, node, stemp->name); + node_socket_set_default_value_rgba(sock->default_value, stemp->val1, stemp->val2, stemp->val3, stemp->val4); break; case SOCK_SHADER: - sock = nodeAddOutputShader(ntree, node, stemp->name); + node_socket_set_default_value_shader(sock->default_value); break; case SOCK_MESH: - sock = nodeAddOutputMesh(ntree, node, stemp->name); + node_socket_set_default_value_mesh(sock->default_value); break; - default: - sock = nodeAddSocket(ntree, node, SOCK_OUT, stemp->name, stemp->type); } + + return sock; +} + +struct bNodeSocket *node_add_output_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp) +{ + bNodeSocket *sock = nodeAddSocket(ntree, node, SOCK_OUT, stemp->name, stemp->type); return sock; } diff -Nru blender-2.61/source/blender/nodes/NOD_composite.h blender-2.62/source/blender/nodes/NOD_composite.h --- blender-2.61/source/blender/nodes/NOD_composite.h 2011-12-13 19:51:22.000000000 +0000 +++ blender-2.62/source/blender/nodes/NOD_composite.h 2012-02-15 19:36:11.000000000 +0000 @@ -103,6 +103,7 @@ void register_node_type_cmp_channel_matte(struct bNodeTreeType *ttype); void register_node_type_cmp_color_spill(struct bNodeTreeType *ttype); void register_node_type_cmp_luma_matte(struct bNodeTreeType *ttype); +void register_node_type_cmp_doubleedgemask(struct bNodeTreeType *ttype); void register_node_type_cmp_translate(struct bNodeTreeType *ttype); void register_node_type_cmp_rotate(struct bNodeTreeType *ttype); diff -Nru blender-2.61/source/blender/nodes/NOD_shader.h blender-2.62/source/blender/nodes/NOD_shader.h --- blender-2.61/source/blender/nodes/NOD_shader.h 2011-12-13 19:51:22.000000000 +0000 +++ blender-2.62/source/blender/nodes/NOD_shader.h 2012-02-15 19:36:11.000000000 +0000 @@ -54,6 +54,8 @@ void register_node_type_sh_rgbtobw(struct bNodeTreeType *ttype); void register_node_type_sh_texture(struct bNodeTreeType *ttype); void register_node_type_sh_normal(struct bNodeTreeType *ttype); +void register_node_type_sh_gamma(struct bNodeTreeType *ttype); +void register_node_type_sh_brightcontrast(struct bNodeTreeType *ttype); void register_node_type_sh_geom(struct bNodeTreeType *ttype); void register_node_type_sh_mapping(struct bNodeTreeType *ttype); void register_node_type_sh_curve_vec(struct bNodeTreeType *ttype); @@ -102,6 +104,7 @@ void register_node_type_sh_tex_wave(struct bNodeTreeType *ttype); void register_node_type_sh_tex_musgrave(struct bNodeTreeType *ttype); void register_node_type_sh_tex_noise(struct bNodeTreeType *ttype); +void register_node_type_sh_tex_checker(struct bNodeTreeType *ttype); #endif diff -Nru blender-2.61/source/blender/nodes/NOD_socket.h blender-2.62/source/blender/nodes/NOD_socket.h --- blender-2.61/source/blender/nodes/NOD_socket.h 2011-12-13 19:51:22.000000000 +0000 +++ blender-2.62/source/blender/nodes/NOD_socket.h 2012-02-15 19:36:11.000000000 +0000 @@ -47,26 +47,19 @@ void node_socket_type_init(struct bNodeSocketType *types[]); -struct bNodeSocket *nodeAddInputInt(struct bNodeTree *ntree, struct bNode *node, const char *name, PropertySubType subtype, int value, int min, int max); -struct bNodeSocket *nodeAddOutputInt(struct bNodeTree *ntree, struct bNode *node, const char *name); - -struct bNodeSocket *nodeAddInputFloat(struct bNodeTree *ntree, struct bNode *node, const char *name, PropertySubType subtype, float value, float min, float max); -struct bNodeSocket *nodeAddOutputFloat(struct bNodeTree *ntree, struct bNode *node, const char *name); - -struct bNodeSocket *nodeAddInputBoolean(struct bNodeTree *ntree, struct bNode *node, const char *name, char value); -struct bNodeSocket *nodeAddOutputBoolean(struct bNodeTree *ntree, struct bNode *node, const char *name); - -struct bNodeSocket *nodeAddInputVector(struct bNodeTree *ntree, struct bNode *node, const char *name, PropertySubType subtype, float x, float y, float z, float min, float max); -struct bNodeSocket *nodeAddOutputVector(struct bNodeTree *ntree, struct bNode *node, const char *name); - -struct bNodeSocket *nodeAddInputRGBA(struct bNodeTree *ntree, struct bNode *node, const char *name, float r, float g, float b, float a); -struct bNodeSocket *nodeAddOutputRGBA(struct bNodeTree *ntree, struct bNode *node, const char *name); - -struct bNodeSocket *nodeAddInputShader(struct bNodeTree *ntree, struct bNode *node, const char *name); -struct bNodeSocket *nodeAddOutputShader(struct bNodeTree *ntree, struct bNode *node, const char *name); - -struct bNodeSocket *nodeAddInputMesh(struct bNodeTree *ntree, struct bNode *node, const char *name); -struct bNodeSocket *nodeAddOutputMesh(struct bNodeTree *ntree, struct bNode *node, const char *name); +void *node_socket_make_default_value(int type); +void node_socket_free_default_value(int type, void *default_value); +void node_socket_init_default_value(int type, void *default_value); +void node_socket_copy_default_value(int type, void *to_default_value, void *from_default_value); +void node_socket_convert_default_value(int to_type, void *to_default_value, int from_type, void *from_default_value); + +void node_socket_set_default_value_int(void *default_value, PropertySubType subtype, int value, int min, int max); +void node_socket_set_default_value_float(void *default_value, PropertySubType subtype, float value, float min, float max); +void node_socket_set_default_value_boolean(void *default_value, char value); +void node_socket_set_default_value_vector(void *default_value, PropertySubType subtype, float x, float y, float z, float min, float max); +void node_socket_set_default_value_rgba(void *default_value, float r, float g, float b, float a); +void node_socket_set_default_value_shader(void *default_value); +void node_socket_set_default_value_mesh(void *default_value); struct bNodeSocket *node_add_input_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp); struct bNodeSocket *node_add_output_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp); diff -Nru blender-2.61/source/blender/nodes/shader/nodes/node_shader_brightness.c blender-2.62/source/blender/nodes/shader/nodes/node_shader_brightness.c --- blender-2.61/source/blender/nodes/shader/nodes/node_shader_brightness.c 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/source/blender/nodes/shader/nodes/node_shader_brightness.c 2012-02-15 19:36:10.000000000 +0000 @@ -0,0 +1,60 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + * The Original Code is Copyright (C) 2006 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + +*/ + +#include "node_shader_util.h" + + +/* **************** Brigh and contrsast ******************** */ + +static bNodeSocketTemplate sh_node_brightcontrast_in[]= { + { SOCK_RGBA, 1, "Color", 1.0f, 1.0f, 1.0f, 1.0f}, + { SOCK_FLOAT, 1, "Bright", 0.0f, 0.0f, 0.0f, 0.0f, -100.0f, 100.0f, PROP_NONE}, + { SOCK_FLOAT, 1, "Contrast", 0.0f, 0.0f, 0.0f, 0.0f, -100.0f, 100.0f, PROP_NONE}, + { -1, 0, "" } +}; + +static bNodeSocketTemplate sh_node_brightcontrast_out[]= { + { SOCK_RGBA, 0, "Color"}, + { -1, 0, "" } +}; + +void register_node_type_sh_brightcontrast(bNodeTreeType *ttype) +{ + static bNodeType ntype; + + node_type_base(ttype, &ntype, SH_NODE_BRIGHTCONTRAST, "Bright/Contrast", NODE_CLASS_OP_COLOR, NODE_OPTIONS); + node_type_compatibility(&ntype, NODE_NEW_SHADING); + node_type_socket_templates(&ntype, sh_node_brightcontrast_in, sh_node_brightcontrast_out); + node_type_size(&ntype, 140, 100, 320); + node_type_init(&ntype, NULL); + node_type_storage(&ntype, "", NULL, NULL); + node_type_exec(&ntype, NULL); + node_type_gpu(&ntype, NULL); + + nodeRegisterType(ttype, &ntype); +} diff -Nru blender-2.61/source/blender/nodes/shader/nodes/node_shader_dynamic.c blender-2.62/source/blender/nodes/shader/nodes/node_shader_dynamic.c --- blender-2.61/source/blender/nodes/shader/nodes/node_shader_dynamic.c 2011-12-13 19:51:21.000000000 +0000 +++ blender-2.62/source/blender/nodes/shader/nodes/node_shader_dynamic.c 2012-02-15 19:36:10.000000000 +0000 @@ -61,7 +61,8 @@ static void node_dynamic_free_storage_cb(bNode *node); #ifdef WITH_PYTHON -static PyObject *init_dynamicdict(void) { +static PyObject *init_dynamicdict(void) +{ PyObject *newscriptdict, *item; PyGILState_STATE gilstate = PyGILState_Ensure(); @@ -329,7 +330,8 @@ node->typeinfo = node_dynamic_find_typeinfo(&node_all_shaders, NULL); } -int nodeDynamicUnlinkText(ID *txtid) { +int nodeDynamicUnlinkText(ID *txtid) +{ Material *ma; bNode *nd; @@ -653,7 +655,8 @@ * NODE_DYNAMIC_MENU: for the default Dynamic node type * > NODE_DYNAMIC_MENU: for the new types defined by scripts */ -static void node_dynamic_init_cb(bNode *node) { +static void node_dynamic_init_cb(bNode *node) +{ int type = node->custom2; node->custom2 = 0; @@ -700,7 +703,8 @@ /* node_dynamic_exec_cb: the execution callback called per pixel * during rendering. */ -static void node_dynamic_exec_cb(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { +static void node_dynamic_exec_cb(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ #ifndef WITH_PYTHON return; #else diff -Nru blender-2.61/source/blender/nodes/shader/nodes/node_shader_gamma.c blender-2.62/source/blender/nodes/shader/nodes/node_shader_gamma.c --- blender-2.61/source/blender/nodes/shader/nodes/node_shader_gamma.c 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/source/blender/nodes/shader/nodes/node_shader_gamma.c 2012-02-15 19:36:10.000000000 +0000 @@ -0,0 +1,58 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + * The Original Code is Copyright (C) 2006 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + +*/ + +#include "node_shader_util.h" + +/* **************** Gamma Tools ******************** */ + +static bNodeSocketTemplate sh_node_gamma_in[]= { + { SOCK_RGBA, 1, "Color", 1.0f, 1.0f, 1.0f, 1.0f}, + { SOCK_FLOAT, 1, "Gamma", 1.0f, 0.0f, 0.0f, 0.0f, 0.001f, 10.0f, PROP_UNSIGNED}, + { -1, 0, "" } +}; + +static bNodeSocketTemplate sh_node_gamma_out[]= { + { SOCK_RGBA, 0, "Color"}, + { -1, 0, "" } +}; + +void register_node_type_sh_gamma(bNodeTreeType *ttype) +{ + static bNodeType ntype; + + node_type_base(ttype, &ntype, SH_NODE_GAMMA, "Gamma", NODE_CLASS_OP_COLOR, NODE_OPTIONS); + node_type_compatibility(&ntype, NODE_NEW_SHADING); + node_type_socket_templates(&ntype, sh_node_gamma_in, sh_node_gamma_out); + node_type_size(&ntype, 140, 100, 320); + node_type_init(&ntype, NULL); + node_type_storage(&ntype, "", NULL, NULL); + node_type_exec(&ntype, NULL); + node_type_gpu(&ntype, NULL); + + nodeRegisterType(ttype, &ntype); +} diff -Nru blender-2.61/source/blender/nodes/shader/nodes/node_shader_normal.c blender-2.62/source/blender/nodes/shader/nodes/node_shader_normal.c --- blender-2.61/source/blender/nodes/shader/nodes/node_shader_normal.c 2011-12-13 19:51:21.000000000 +0000 +++ blender-2.62/source/blender/nodes/shader/nodes/node_shader_normal.c 2012-02-15 19:36:10.000000000 +0000 @@ -84,7 +84,7 @@ static bNodeType ntype; node_type_base(ttype, &ntype, SH_NODE_NORMAL, "Normal", NODE_CLASS_OP_VECTOR, NODE_OPTIONS); - node_type_compatibility(&ntype, NODE_OLD_SHADING); + node_type_compatibility(&ntype, NODE_OLD_SHADING|NODE_NEW_SHADING); node_type_socket_templates(&ntype, sh_node_normal_in, sh_node_normal_out); node_type_init(&ntype, node_shader_init_normal); node_type_exec(&ntype, node_shader_exec_normal); diff -Nru blender-2.61/source/blender/nodes/shader/nodes/node_shader_tex_checker.c blender-2.62/source/blender/nodes/shader/nodes/node_shader_tex_checker.c --- blender-2.61/source/blender/nodes/shader/nodes/node_shader_tex_checker.c 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/source/blender/nodes/shader/nodes/node_shader_tex_checker.c 2012-02-15 19:36:10.000000000 +0000 @@ -0,0 +1,80 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + * The Original Code is Copyright (C) 2005 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "../node_shader_util.h" + +/* **************** OUTPUT ******************** */ + +static bNodeSocketTemplate sh_node_tex_checker_in[]= { + { SOCK_VECTOR, 1, "Vector", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, + { SOCK_RGBA, 1, "Color1", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 1, "Color2", 0.2f, 0.2f, 0.2f, 1.0f, 0.0f, 1.0f}, + { SOCK_FLOAT, 1, "Scale", 5.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f}, + { -1, 0, "" } +}; + +static bNodeSocketTemplate sh_node_tex_checker_out[]= { + { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_FLOAT, 0, "Fac", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static void node_shader_init_tex_checker(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) +{ + NodeTexChecker *tex = MEM_callocN(sizeof(NodeTexChecker), "NodeTexChecker"); + default_tex_mapping(&tex->base.tex_mapping); + default_color_mapping(&tex->base.color_mapping); + + node->storage = tex; +} + +static int node_shader_gpu_tex_checker(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) +{ + if(!in[0].link) + in[0].link = GPU_attribute(CD_ORCO, ""); + + node_shader_gpu_tex_mapping(mat, node, in, out); + + return GPU_stack_link(mat, "node_tex_checker", in, out); +} + +/* node type definition */ +void register_node_type_sh_tex_checker(bNodeTreeType *ttype) +{ + static bNodeType ntype; + + node_type_base(ttype, &ntype, SH_NODE_TEX_CHECKER, "Checker Texture", NODE_CLASS_TEXTURE, 0); + node_type_compatibility(&ntype, NODE_NEW_SHADING); + node_type_socket_templates(&ntype, sh_node_tex_checker_in, sh_node_tex_checker_out); + node_type_size(&ntype, 150, 60, 200); + node_type_init(&ntype, node_shader_init_tex_checker); + node_type_storage(&ntype, "NodeTexChecker", node_free_standard_storage, node_copy_standard_storage); + node_type_exec(&ntype, NULL); + node_type_gpu(&ntype, node_shader_gpu_tex_checker); + + nodeRegisterType(ttype, &ntype); +} diff -Nru blender-2.61/source/blender/nodes/shader/node_shader_util.c blender-2.62/source/blender/nodes/shader/node_shader_util.c --- blender-2.61/source/blender/nodes/shader/node_shader_util.c 2011-12-13 19:51:21.000000000 +0000 +++ blender-2.62/source/blender/nodes/shader/node_shader_util.c 2012-02-15 19:36:10.000000000 +0000 @@ -134,8 +134,6 @@ bNodeSocket *sock; int a; - ntreeSocketUseFlags(ntree); - for(node= ntree->nodes.first; node; node= node->next) { if(node->type==SH_NODE_TEXTURE) { if((r_mode & R_OSA) && node->id) { @@ -186,7 +184,7 @@ /* hrmf, case in loop isnt super fast, but we dont edit 100s of material at same time either! */ for(a=0, sock= node->inputs.first; sock; sock= sock->next, a++) { - if(!(sock->flag & SOCK_HIDDEN)) { + if(!nodeSocketIsHidden(sock)) { if(copyto) { switch(a) { case MAT_IN_COLOR: diff -Nru blender-2.61/source/blender/nodes/texture/nodes/node_texture_output.c blender-2.62/source/blender/nodes/texture/nodes/node_texture_output.c --- blender-2.61/source/blender/nodes/texture/nodes/node_texture_output.c 2011-12-13 19:51:13.000000000 +0000 +++ blender-2.62/source/blender/nodes/texture/nodes/node_texture_output.c 2012-02-15 19:35:57.000000000 +0000 @@ -103,8 +103,8 @@ } else { suffix = 0; new_len = len + 4; - if(new_len > 31) - new_len = 31; + if(new_len > (sizeof(tno->name) - 1)) + new_len = (sizeof(tno->name) - 1); } new_name = MEM_mallocN(new_len + 1, "new_name"); diff -Nru blender-2.61/source/blender/python/generic/bgl.c blender-2.62/source/blender/python/generic/bgl.c --- blender-2.61/source/blender/python/generic/bgl.c 2011-12-13 19:48:33.000000000 +0000 +++ blender-2.62/source/blender/python/generic/bgl.c 2012-02-15 19:33:14.000000000 +0000 @@ -453,7 +453,7 @@ } } - switch(self->type) { + switch (self->type) { case GL_BYTE: return PyArg_Parse(v, "b:Expected ints", &self->buf.asbyte[i]) ? 0:-1; case GL_SHORT: @@ -595,7 +595,7 @@ PyObject *repr; const char *typestr= "UNKNOWN"; - switch(self->type) { + switch (self->type) { case GL_BYTE: typestr= "GL_BYTE"; break; case GL_SHORT: typestr= "GL_SHORT"; break; case GL_INT: typestr= "GL_BYTE"; break; @@ -1304,6 +1304,7 @@ PyModule_AddObject(submodule, "Buffer", (PyObject *)&BGL_bufferType); + Py_INCREF((PyObject *)&BGL_bufferType); #define EXPP_ADDCONST(x) PyDict_SetItemString(dict, #x, item=PyLong_FromLong((int)x)); Py_DECREF(item) diff -Nru blender-2.61/source/blender/python/generic/bpy_internal_import.c blender-2.62/source/blender/python/generic/bpy_internal_import.c --- blender-2.61/source/blender/python/generic/bpy_internal_import.c 2011-12-13 19:48:33.000000000 +0000 +++ blender-2.62/source/blender/python/generic/bpy_internal_import.c 2012-02-15 19:33:14.000000000 +0000 @@ -51,7 +51,7 @@ #include "BKE_text.h" /* txt_to_buf */ #include "BKE_main.h" -static Main *bpy_import_main= NULL; +static Main *bpy_import_main = NULL; /* 'builtins' is most likely PyEval_GetBuiltins() */ void bpy_import_init(PyObject *builtins) @@ -59,13 +59,13 @@ PyObject *item; PyObject *mod; - PyDict_SetItemString(builtins, "__import__", item=PyCFunction_New(&bpy_import_meth, NULL)); Py_DECREF(item); + PyDict_SetItemString(builtins, "__import__", item = PyCFunction_New(&bpy_import_meth, NULL)); Py_DECREF(item); /* move reload here * XXX, use import hooks */ - mod= PyImport_ImportModuleLevel((char *)"imp", NULL, NULL, NULL, 0); + mod = PyImport_ImportModuleLevel((char *)"imp", NULL, NULL, NULL, 0); if (mod) { - PyDict_SetItemString(PyModule_GetDict(mod), "reload", item=PyCFunction_New(&bpy_reload_meth, NULL)); Py_DECREF(item); + PyDict_SetItemString(PyModule_GetDict(mod), "reload", item = PyCFunction_New(&bpy_reload_meth, NULL)); Py_DECREF(item); Py_DECREF(mod); } else { @@ -79,7 +79,7 @@ if (text->compiled) { Py_DECREF((PyObject *)text->compiled); } - text->compiled= NULL; + text->compiled = NULL; } struct Main *bpy_import_main_get(void) @@ -89,27 +89,27 @@ void bpy_import_main_set(struct Main *maggie) { - bpy_import_main= maggie; + bpy_import_main = maggie; } /* returns a dummy filename for a textblock so we can tell what file a text block comes from */ void bpy_text_filename_get(char *fn, size_t fn_len, Text *text) { - BLI_snprintf(fn, fn_len, "%s%c%s", ID_BLEND_PATH(bpy_import_main, &text->id), SEP, text->id.name+2); + BLI_snprintf(fn, fn_len, "%s%c%s", ID_BLEND_PATH(bpy_import_main, &text->id), SEP, text->id.name + 2); } PyObject *bpy_text_import(Text *text) { - char *buf= NULL; - char modulename[24]; + char *buf = NULL; + char modulename[MAX_ID_NAME+2]; int len; if (!text->compiled) { char fn_dummy[256]; bpy_text_filename_get(fn_dummy, sizeof(fn_dummy), text); - buf= txt_to_buf(text); - text->compiled= Py_CompileString(buf, fn_dummy, Py_file_input); + buf = txt_to_buf(text); + text->compiled = Py_CompileString(buf, fn_dummy, Py_file_input); MEM_freeN(buf); if (PyErr_Occurred()) { @@ -121,38 +121,39 @@ } } - len= strlen(text->id.name+2); - BLI_strncpy(modulename, text->id.name+2, len); - modulename[len - 3]= '\0'; /* remove .py */ + len = strlen(text->id.name + 2); + BLI_strncpy(modulename, text->id.name + 2, len); + modulename[len - 3] = '\0'; /* remove .py */ return PyImport_ExecCodeModule(modulename, text->compiled); } PyObject *bpy_text_import_name(const char *name, int *found) { Text *text; - char txtname[MAX_ID_NAME-2]; - int namelen= strlen(name); -//XXX Main *maggie= bpy_import_main ? bpy_import_main:G.main; - Main *maggie= bpy_import_main; + char txtname[MAX_ID_NAME - 2]; + int namelen = strlen(name); +//XXX Main *maggie = bpy_import_main ? bpy_import_main:G.main; + Main *maggie = bpy_import_main; - *found= 0; + *found = 0; if (!maggie) { printf("ERROR: bpy_import_main_set() was not called before running python. this is a bug.\n"); return NULL; } - - if (namelen >= (MAX_ID_NAME-2) - 3) return NULL; /* we know this cant be importable, the name is too long for blender! */ - + + /* we know this cant be importable, the name is too long for blender! */ + if (namelen >= (MAX_ID_NAME - 2) - 3) return NULL; + memcpy(txtname, name, namelen); memcpy(&txtname[namelen], ".py", 4); - text= BLI_findstring(&maggie->text, txtname, offsetof(ID, name) + 2); + text = BLI_findstring(&maggie->text, txtname, offsetof(ID, name) + 2); if (!text) return NULL; else - *found= 1; + *found = 1; return bpy_text_import(text); } @@ -167,32 +168,32 @@ Text *text; const char *name; char *filepath; - char *buf= NULL; -//XXX Main *maggie= bpy_import_main ? bpy_import_main:G.main; - Main *maggie= bpy_import_main; + char *buf = NULL; +//XXX Main *maggie = bpy_import_main ? bpy_import_main:G.main; + Main *maggie = bpy_import_main; if (!maggie) { printf("ERROR: bpy_import_main_set() was not called before running python. this is a bug.\n"); return NULL; } - *found= 0; + *found = 0; /* get name, filename from the module itself */ - if ((name= PyModule_GetName(module)) == NULL) + if ((name = PyModule_GetName(module)) == NULL) return NULL; - if ((filepath= (char *)PyModule_GetFilename(module)) == NULL) + if ((filepath = (char *)PyModule_GetFilename(module)) == NULL) return NULL; /* look up the text object */ - text= BLI_findstring(&maggie->text, BLI_path_basename(filepath), offsetof(ID, name) + 2); + text = BLI_findstring(&maggie->text, BLI_path_basename(filepath), offsetof(ID, name) + 2); /* uh-oh.... didn't find it */ if (!text) return NULL; else - *found= 1; + *found = 1; /* if previously compiled, free the object */ /* (can't see how could be NULL, but check just in case) */ @@ -201,8 +202,8 @@ } /* compile the buffer */ - buf= txt_to_buf(text); - text->compiled= Py_CompileString(buf, text->id.name+2, Py_file_input); + buf = txt_to_buf(text); + text->compiled = Py_CompileString(buf, text->id.name + 2, Py_file_input); MEM_freeN(buf); /* if compile failed.... return this error */ @@ -223,20 +224,22 @@ { PyObject *exception, *err, *tb; char *name; - int found= 0; - PyObject *globals= NULL, *locals= NULL, *fromlist= NULL; - int level= -1; /* relative imports */ + int found = 0; + PyObject *globals = NULL, *locals = NULL, *fromlist = NULL; + int level = -1; /* relative imports */ PyObject *newmodule; //PyObject_Print(args, stderr, 0); - static const char *kwlist[]= {"name", "globals", "locals", "fromlist", "level", NULL}; + static const char *kwlist[] = {"name", "globals", "locals", "fromlist", "level", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kw, "s|OOOi:bpy_import_meth", (char **)kwlist, - &name, &globals, &locals, &fromlist, &level)) + &name, &globals, &locals, &fromlist, &level)) + { return NULL; + } /* import existing builtin modules or modules that have been imported already */ - newmodule= PyImport_ImportModuleLevel(name, globals, locals, fromlist, level); + newmodule = PyImport_ImportModuleLevel(name, globals, locals, fromlist, level); if (newmodule) return newmodule; @@ -244,7 +247,7 @@ PyErr_Fetch(&exception, &err, &tb); /* get the python error incase we cant import as blender text either */ /* importing from existing modules failed, see if we have this module as blender text */ - newmodule= bpy_text_import_name(name, &found); + newmodule = bpy_text_import_name(name, &found); if (newmodule) {/* found module as blender text, ignore above exception */ PyErr_Clear(); @@ -253,7 +256,7 @@ Py_XDECREF(tb); /* printf("imported from text buffer...\n"); */ } - else if (found==1) { /* blender text module failed to execute but was found, use its error message */ + else if (found == 1) { /* blender text module failed to execute but was found, use its error message */ Py_XDECREF(exception); Py_XDECREF(err); Py_XDECREF(tb); @@ -275,18 +278,18 @@ static PyObject *blender_reload(PyObject *UNUSED(self), PyObject *module) { PyObject *exception, *err, *tb; - PyObject *newmodule= NULL; - int found= 0; + PyObject *newmodule = NULL; + int found = 0; /* try reimporting from file */ - newmodule= PyImport_ReloadModule(module); + newmodule = PyImport_ReloadModule(module); if (newmodule) return newmodule; /* no file, try importing from memory */ PyErr_Fetch(&exception, &err, &tb); /*restore for probable later use */ - newmodule= bpy_text_reimport(module, &found); + newmodule = bpy_text_reimport(module, &found); if (newmodule) {/* found module as blender text, ignore above exception */ PyErr_Clear(); Py_XDECREF(exception); @@ -294,7 +297,7 @@ Py_XDECREF(tb); /* printf("imported from text buffer...\n"); */ } - else if (found==1) { /* blender text module failed to execute but was found, use its error message */ + else if (found == 1) { /* blender text module failed to execute but was found, use its error message */ Py_XDECREF(exception); Py_XDECREF(err); Py_XDECREF(tb); @@ -309,5 +312,5 @@ return newmodule; } -PyMethodDef bpy_import_meth= {"bpy_import_meth", (PyCFunction)blender_import, METH_VARARGS | METH_KEYWORDS, "blenders import"}; -PyMethodDef bpy_reload_meth= {"bpy_reload_meth", (PyCFunction)blender_reload, METH_O, "blenders reload"}; +PyMethodDef bpy_import_meth = {"bpy_import_meth", (PyCFunction)blender_import, METH_VARARGS | METH_KEYWORDS, "blenders import"}; +PyMethodDef bpy_reload_meth = {"bpy_reload_meth", (PyCFunction)blender_reload, METH_O, "blenders reload"}; diff -Nru blender-2.61/source/blender/python/generic/idprop_py_api.c blender-2.62/source/blender/python/generic/idprop_py_api.c --- blender-2.61/source/blender/python/generic/idprop_py_api.c 2011-12-13 19:48:33.000000000 +0000 +++ blender-2.62/source/blender/python/generic/idprop_py_api.c 2012-02-15 19:33:14.000000000 +0000 @@ -249,7 +249,7 @@ name = _PyUnicode_AsStringAndSize(value, &name_size); if (name_size > MAX_IDPROP_NAME) { - PyErr_SetString(PyExc_TypeError, "string length cannot exceed 31 characters!"); + PyErr_SetString(PyExc_TypeError, "string length cannot exceed 63 characters!"); return -1; } @@ -359,7 +359,7 @@ Py_ssize_t name_size; name = _PyUnicode_AsStringAndSize(name_obj, &name_size); if (name_size > MAX_IDPROP_NAME) { - return "the length of IDProperty names is limited to 31 characters"; + return "the length of IDProperty names is limited to 63 characters"; } } @@ -405,7 +405,7 @@ val.array.len = PySequence_Size(ob); - switch(val.array.type) { + switch (val.array.type) { case IDP_DOUBLE: prop = IDP_New(IDP_ARRAY, &val, name); for (i=0; isubtype) { + switch (prop->subtype) { case IDP_FLOAT: { float *array= (float*)IDP_Array(prop); @@ -976,7 +976,7 @@ static PyObject *BPy_IDArray_GetType(BPy_IDArray *self) { - switch(self->prop->subtype) { + switch (self->prop->subtype) { case IDP_FLOAT: return PyUnicode_FromString("f"); case IDP_DOUBLE: diff -Nru blender-2.61/source/blender/python/generic/py_capi_utils.c blender-2.62/source/blender/python/generic/py_capi_utils.c --- blender-2.61/source/blender/python/generic/py_capi_utils.c 2011-12-13 19:48:33.000000000 +0000 +++ blender-2.62/source/blender/python/generic/py_capi_utils.c 2012-02-15 19:33:14.000000000 +0000 @@ -35,18 +35,20 @@ #include "py_capi_utils.h" -#include "BLI_string_utf8.h" /* only for BLI_strncpy_wchar_from_utf8, should replace with py funcs but too late in release now */ +/* only for BLI_strncpy_wchar_from_utf8, should replace with py funcs but too late in release now */ +#include "BLI_string_utf8.h" #ifdef _WIN32 /* BLI_setenv */ #include "BLI_path_util.h" #endif /* array utility function */ -int PyC_AsArray(void *array, PyObject *value, const int length, const PyTypeObject *type, const short is_double, const char *error_prefix) +int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length, + const PyTypeObject *type, const short is_double, const char *error_prefix) { PyObject *value_fast; - int value_len; - int i; + Py_ssize_t value_len; + Py_ssize_t i; if (!(value_fast=PySequence_Fast(value, error_prefix))) { return -1; @@ -191,7 +193,7 @@ void PyC_FileAndNum_Safe(const char **filename, int *lineno) { - if(!PYC_INTERPRETER_ACTIVE) { + if (!PYC_INTERPRETER_ACTIVE) { return; } @@ -463,7 +465,8 @@ if (py_path_bundle==NULL) { /* Common enough to have bundled *nix python but complain on OSX/Win */ #if defined(__APPLE__) || defined(_WIN32) - fprintf(stderr, "Warning! bundled python not found and is expected on this platform. (if you built with CMake: 'install' target may have not been built)\n"); + fprintf(stderr, "Warning! bundled python not found and is expected on this platform. " + "(if you built with CMake: 'install' target may have not been built)\n"); #endif return; } @@ -492,7 +495,8 @@ /* cant use this, on linux gives bug: #23018, TODO: try LANG="en_US.UTF-8" /usr/bin/blender, suggested 22008 */ /* mbstowcs(py_path_bundle_wchar, py_path_bundle, FILE_MAXDIR); */ - BLI_strncpy_wchar_from_utf8(py_path_bundle_wchar, py_path_bundle, sizeof(py_path_bundle_wchar) / sizeof(wchar_t)); + BLI_strncpy_wchar_from_utf8(py_path_bundle_wchar, py_path_bundle, + sizeof(py_path_bundle_wchar) / sizeof(wchar_t)); Py_SetPythonHome(py_path_bundle_wchar); // printf("found python (wchar_t) '%ls'\n", py_path_bundle_wchar); diff -Nru blender-2.61/source/blender/python/generic/py_capi_utils.h blender-2.62/source/blender/python/generic/py_capi_utils.h --- blender-2.61/source/blender/python/generic/py_capi_utils.h 2011-12-13 19:48:33.000000000 +0000 +++ blender-2.62/source/blender/python/generic/py_capi_utils.h 2012-02-15 19:33:14.000000000 +0000 @@ -35,7 +35,8 @@ PyObject * PyC_Err_Format_Prefix(PyObject *exception_type_prefix, const char *format, ...); void PyC_FileAndNum(const char **filename, int *lineno); void PyC_FileAndNum_Safe(const char **filename, int *lineno); /* checks python is running */ -int PyC_AsArray(void *array, PyObject *value, const int length, const PyTypeObject *type, const short is_double, const char *error_prefix); +int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length, + const PyTypeObject *type, const short is_double, const char *error_prefix); /* follow http://www.python.org/dev/peps/pep-0383/ */ PyObject * PyC_UnicodeFromByte(const char *str); diff -Nru blender-2.61/source/blender/python/intern/bpy_app.c blender-2.62/source/blender/python/intern/bpy_app.c --- blender-2.61/source/blender/python/intern/bpy_app.c 2011-12-13 19:48:28.000000000 +0000 +++ blender-2.62/source/blender/python/intern/bpy_app.c 2012-02-15 19:33:11.000000000 +0000 @@ -32,6 +32,9 @@ #include #include "bpy_app.h" + +#include "bpy_app_ffmpeg.h" + #include "bpy_app_handlers.h" #include "bpy_driver.h" @@ -59,7 +62,7 @@ static PyTypeObject BlenderAppType; -static PyStructSequence_Field app_info_fields[]= { +static PyStructSequence_Field app_info_fields[] = { {(char *)"version", (char *)"The Blender version as a tuple of 3 numbers. eg. (2, 50, 11)"}, {(char *)"version_string", (char *)"The Blender version formatted as a string"}, {(char *)"version_char", (char *)"The Blender version character (for minor releases)"}, @@ -79,15 +82,16 @@ {(char *)"build_system", (char *)"Build system used"}, /* submodules */ + {(char *)"ffmpeg", (char *)"FFmpeg library information backend"}, {(char *)"handlers", (char *)"Application handler callbacks"}, {NULL} }; -static PyStructSequence_Desc app_info_desc= { +static PyStructSequence_Desc app_info_desc = { (char *)"bpy.app", /* name */ (char *)"This module contains application values that remain unchanged during runtime.", /* doc */ app_info_fields, /* fields */ - (sizeof(app_info_fields)/sizeof(PyStructSequence_Field)) - 1 + (sizeof(app_info_fields) / sizeof(PyStructSequence_Field)) - 1 }; #define DO_EXPAND(VAL) VAL ## 1 @@ -96,9 +100,9 @@ static PyObject *make_app_info(void) { PyObject *app_info; - int pos= 0; + int pos = 0; - app_info= PyStructSequence_New(&BlenderAppType); + app_info = PyStructSequence_New(&BlenderAppType); if (app_info == NULL) { return NULL; } @@ -110,8 +114,11 @@ #define SetObjItem(obj) \ PyStructSequence_SET_ITEM(app_info, pos++, obj) - SetObjItem(Py_BuildValue("(iii)", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION)); - SetObjItem(PyUnicode_FromFormat("%d.%02d (sub %d)", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION)); + SetObjItem(Py_BuildValue("(iii)", + BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION)); + SetObjItem(PyUnicode_FromFormat("%d.%02d (sub %d)", + BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION)); + #if defined(BLENDER_VERSION_CHAR) && EXPAND(BLENDER_VERSION_CHAR) != 1 SetStrItem(STRINGIFY(BLENDER_VERSION_CHAR)); #else @@ -144,6 +151,7 @@ SetStrItem("Unknown"); #endif + SetObjItem(BPY_app_ffmpeg_struct()); SetObjItem(BPY_app_handlers_struct()); #undef SetIntItem @@ -170,7 +178,7 @@ static int bpy_app_debug_set(PyObject *UNUSED(self), PyObject *value, void *UNUSED(closure)) { - int param= PyObject_IsTrue(value); + int param = PyObject_IsTrue(value); if (param < 0) { PyErr_SetString(PyExc_TypeError, "bpy.app.debug can only be True/False"); @@ -193,14 +201,14 @@ static int bpy_app_debug_value_set(PyObject *UNUSED(self), PyObject *value, void *UNUSED(closure)) { - int param= PyLong_AsSsize_t(value); + int param = PyLong_AsSsize_t(value); if (param == -1 && PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "bpy.app.debug_value can only be set to a whole number"); return -1; } - G.rt= param; + G.rt = param; return 0; } @@ -229,7 +237,7 @@ } -static PyGetSetDef bpy_app_getsets[]= { +static PyGetSetDef bpy_app_getsets[] = { {(char *)"debug", bpy_app_debug_get, bpy_app_debug_set, (char *)bpy_app_debug_doc, NULL}, {(char *)"debug_value", bpy_app_debug_value_get, bpy_app_debug_value_set, (char *)bpy_app_debug_value_doc, NULL}, {(char *)"tempdir", bpy_app_tempdir_get, NULL, (char *)bpy_app_tempdir_doc, NULL}, @@ -242,7 +250,7 @@ /* tricky dynamic members, not to py-spec! */ PyGetSetDef *getset; - for (getset= bpy_app_getsets; getset->name; getset++) { + for (getset = bpy_app_getsets; getset->name; getset++) { PyDict_SetItemString(BlenderAppType.tp_dict, getset->name, PyDescr_NewGetSet(&BlenderAppType, getset)); } } @@ -255,11 +263,12 @@ PyStructSequence_InitType(&BlenderAppType, &app_info_desc); - ret= make_app_info(); + ret = make_app_info(); /* prevent user from creating new instances */ - BlenderAppType.tp_init= NULL; - BlenderAppType.tp_new= NULL; + BlenderAppType.tp_init = NULL; + BlenderAppType.tp_new = NULL; + BlenderAppType.tp_hash = (hashfunc)_Py_HashPointer; /* without this we can't do set(sys.modules) [#29635] */ /* kindof a hack ontop of PyStructSequence */ py_struct_seq_getset_init(); diff -Nru blender-2.61/source/blender/python/intern/bpy_app_ffmpeg.c blender-2.62/source/blender/python/intern/bpy_app_ffmpeg.c --- blender-2.61/source/blender/python/intern/bpy_app_ffmpeg.c 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/source/blender/python/intern/bpy_app_ffmpeg.c 2012-02-15 19:33:11.000000000 +0000 @@ -0,0 +1,143 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + * Contributor(s): Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/python/intern/bpy_app_ffmpeg.c + * \ingroup pythonintern + */ + +#include +#include "BLI_utildefines.h" +#include "BLI_callbacks.h" + +#include "RNA_types.h" +#include "RNA_access.h" +#include "bpy_rna.h" + +#ifdef WITH_FFMPEG +#include +#include +#include +#include +#include +#endif + +static PyTypeObject BlenderAppFFmpegType; + +#define DEF_FFMPEG_LIB_VERSION(lib) \ + {(char *)(#lib "_version"), (char *)("The " #lib " version as a tuple of 3 numbers")}, \ + {(char *)(#lib "_version_string"), (char *)("The " #lib " version formatted as a string")}, + +static PyStructSequence_Field app_ffmpeg_info_fields[] = { + {(char *)"supported", (char *)("Boolean, True when Blender is built with FFmpeg support")}, + + DEF_FFMPEG_LIB_VERSION(avcodec) + DEF_FFMPEG_LIB_VERSION(avdevice) + DEF_FFMPEG_LIB_VERSION(avformat) + DEF_FFMPEG_LIB_VERSION(avutil) + DEF_FFMPEG_LIB_VERSION(swscale) + {NULL} +}; + +#undef DEF_FFMPEG_LIB_VERSION + +static PyStructSequence_Desc app_ffmpeg_info_desc = { + (char *)"bpy.app.ffmpeg", /* name */ + (char *)"This module contains information about FFmpeg blender is linked against", /* doc */ + app_ffmpeg_info_fields, /* fields */ + (sizeof(app_ffmpeg_info_fields) / sizeof(PyStructSequence_Field)) - 1 +}; + +static PyObject *make_ffmpeg_info(void) +{ + PyObject *ffmpeg_info; + int pos = 0; + +#ifdef WITH_FFMPEG + int curversion; +#endif + + ffmpeg_info = PyStructSequence_New(&BlenderAppFFmpegType); + if (ffmpeg_info == NULL) { + return NULL; + } + +#define SetIntItem(flag) \ + PyStructSequence_SET_ITEM(ffmpeg_info, pos++, PyLong_FromLong(flag)) +#define SetStrItem(str) \ + PyStructSequence_SET_ITEM(ffmpeg_info, pos++, PyUnicode_FromString(str)) +#define SetObjItem(obj) \ + PyStructSequence_SET_ITEM(ffmpeg_info, pos++, obj) + +#ifdef WITH_FFMPEG + #define FFMPEG_LIB_VERSION(lib) \ + curversion = lib ## _version(); \ + SetObjItem(Py_BuildValue("(iii)", \ + curversion >> 16, (curversion >> 8) % 256, curversion % 256)); \ + SetObjItem(PyUnicode_FromFormat("%2d, %2d, %2d", \ + curversion >> 16, (curversion >> 8) % 256, curversion % 256)); +#else + #define FFMPEG_LIB_VERSION(lib) \ + SetStrItem("Unknown"); \ + SetStrItem("Unknown"); +#endif + +#ifdef WITH_FFMPEG + SetObjItem(PyBool_FromLong(1)); +#else + SetObjItem(PyBool_FromLong(0)); +#endif + + FFMPEG_LIB_VERSION(avcodec); + FFMPEG_LIB_VERSION(avdevice); + FFMPEG_LIB_VERSION(avformat); + FFMPEG_LIB_VERSION(avutil); + FFMPEG_LIB_VERSION(swscale); + +#undef FFMPEG_LIB_VERSION + + if (PyErr_Occurred()) { + Py_CLEAR(ffmpeg_info); + return NULL; + } + +#undef SetIntItem +#undef SetStrItem +#undef SetObjItem + + return ffmpeg_info; +} + +PyObject *BPY_app_ffmpeg_struct(void) +{ + PyObject *ret; + + PyStructSequence_InitType(&BlenderAppFFmpegType, &app_ffmpeg_info_desc); + + ret = make_ffmpeg_info(); + + /* prevent user from creating new instances */ + BlenderAppFFmpegType.tp_init = NULL; + BlenderAppFFmpegType.tp_new = NULL; + BlenderAppFFmpegType.tp_hash = (hashfunc)_Py_HashPointer; /* without this we can't do set(sys.modules) [#29635] */ + + return ret; +} diff -Nru blender-2.61/source/blender/python/intern/bpy_app_ffmpeg.h blender-2.62/source/blender/python/intern/bpy_app_ffmpeg.h --- blender-2.61/source/blender/python/intern/bpy_app_ffmpeg.h 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/source/blender/python/intern/bpy_app_ffmpeg.h 2012-02-15 19:33:11.000000000 +0000 @@ -0,0 +1,32 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + * Contributor(s): Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/python/intern/bpy_app_ffmpeg.h + * \ingroup pythonintern + */ + +#ifndef BPY_APP_FFMPEG_H +#define BPY_APP_FFMPEG_H + +PyObject *BPY_app_ffmpeg_struct(void); + +#endif // BPY_APP_FFMPEG_H diff -Nru blender-2.61/source/blender/python/intern/bpy_app_handlers.c blender-2.62/source/blender/python/intern/bpy_app_handlers.c --- blender-2.61/source/blender/python/intern/bpy_app_handlers.c 2011-12-13 19:48:28.000000000 +0000 +++ blender-2.62/source/blender/python/intern/bpy_app_handlers.c 2012-02-15 19:33:11.000000000 +0000 @@ -41,7 +41,7 @@ static PyTypeObject BlenderAppCbType; -static PyStructSequence_Field app_cb_info_fields[]= { +static PyStructSequence_Field app_cb_info_fields[] = { {(char *)"frame_change_pre", (char *)"Callback list - on frame change for playback and rendering (before)"}, {(char *)"frame_change_post", (char *)"Callback list - on frame change for playback and rendering (after)"}, {(char *)"render_pre", (char *)"Callback list - on render (before)"}, @@ -61,11 +61,11 @@ {NULL} }; -static PyStructSequence_Desc app_cb_info_desc= { +static PyStructSequence_Desc app_cb_info_desc = { (char *)"bpy.app.handlers", /* name */ (char *)"This module contains callbacks", /* doc */ app_cb_info_fields, /* fields */ - (sizeof(app_cb_info_fields)/sizeof(PyStructSequence_Field)) - 1 + (sizeof(app_cb_info_fields) / sizeof(PyStructSequence_Field)) - 1 }; /* @@ -82,11 +82,11 @@ { PyObject *value; - if(!PyArg_ParseTuple(args, "O:bpy.app.handlers.persistent", &value)) + if (!PyArg_ParseTuple(args, "O:bpy.app.handlers.persistent", &value)) return NULL; if (PyFunction_Check(value)) { - PyObject **dict_ptr= _PyObject_GetDictPtr(value); + PyObject **dict_ptr = _PyObject_GetDictPtr(value); if (dict_ptr == NULL) { PyErr_SetString(PyExc_ValueError, "bpy.app.handlers.persistent wasn't able to " @@ -96,7 +96,7 @@ else { /* set id */ if (*dict_ptr == NULL) { - *dict_ptr= PyDict_New(); + *dict_ptr = PyDict_New(); } PyDict_SetItemString(*dict_ptr, PERMINENT_CB_ID, Py_None); @@ -163,23 +163,23 @@ 0, /* tp_free */ }; -static PyObject *py_cb_array[BLI_CB_EVT_TOT]= {NULL}; +static PyObject *py_cb_array[BLI_CB_EVT_TOT] = {NULL}; static PyObject *make_app_cb_info(void) { PyObject *app_cb_info; - int pos= 0; + int pos = 0; - app_cb_info= PyStructSequence_New(&BlenderAppCbType); + app_cb_info = PyStructSequence_New(&BlenderAppCbType); if (app_cb_info == NULL) { return NULL; } - for (pos= 0; pos < BLI_CB_EVT_TOT; pos++) { + for (pos = 0; pos < BLI_CB_EVT_TOT; pos++) { if (app_cb_info_fields[pos].name == NULL) { Py_FatalError("invalid callback slots 1"); } - PyStructSequence_SET_ITEM(app_cb_info, pos, (py_cb_array[pos]= PyList_New(0))); + PyStructSequence_SET_ITEM(app_cb_info, pos, (py_cb_array[pos] = PyList_New(0))); } if (app_cb_info_fields[pos + APP_CB_OTHER_FIELDS].name != NULL) { Py_FatalError("invalid callback slots 2"); @@ -196,7 +196,7 @@ PyObject *ret; #if defined(_MSC_VER) || defined(FREE_WINDOWS) - BPyPersistent_Type.ob_base.ob_base.ob_type= &PyType_Type; + BPyPersistent_Type.ob_base.ob_base.ob_type = &PyType_Type; #endif if (PyType_Ready(&BPyPersistent_Type) < 0) { @@ -205,23 +205,24 @@ PyStructSequence_InitType(&BlenderAppCbType, &app_cb_info_desc); - ret= make_app_cb_info(); + ret = make_app_cb_info(); /* prevent user from creating new instances */ - BlenderAppCbType.tp_init= NULL; - BlenderAppCbType.tp_new= NULL; + BlenderAppCbType.tp_init = NULL; + BlenderAppCbType.tp_new = NULL; + BlenderAppCbType.tp_hash = (hashfunc)_Py_HashPointer; /* without this we can't do set(sys.modules) [#29635] */ /* assign the C callbacks */ if (ret) { - static bCallbackFuncStore funcstore_array[BLI_CB_EVT_TOT]= {{NULL}}; + static bCallbackFuncStore funcstore_array[BLI_CB_EVT_TOT] = {{NULL}}; bCallbackFuncStore *funcstore; - int pos= 0; + int pos = 0; - for (pos= 0; pos < BLI_CB_EVT_TOT; pos++) { - funcstore= &funcstore_array[pos]; - funcstore->func= bpy_app_generic_callback; - funcstore->alloc= 0; - funcstore->arg= SET_INT_IN_POINTER(pos); + for (pos = 0; pos < BLI_CB_EVT_TOT; pos++) { + funcstore = &funcstore_array[pos]; + funcstore->func = bpy_app_generic_callback; + funcstore->alloc = 0; + funcstore->arg = SET_INT_IN_POINTER(pos); BLI_add_cb(funcstore, pos); } } @@ -231,32 +232,32 @@ void BPY_app_handlers_reset(const short do_all) { - int pos= 0; + int pos = 0; if (do_all) { - for (pos= 0; pos < BLI_CB_EVT_TOT; pos++) { + for (pos = 0; pos < BLI_CB_EVT_TOT; pos++) { /* clear list */ PyList_SetSlice(py_cb_array[pos], 0, PY_SSIZE_T_MAX, NULL); } } else { /* save string conversion thrashing */ - PyObject *perm_id_str= PyUnicode_FromString(PERMINENT_CB_ID); + PyObject *perm_id_str = PyUnicode_FromString(PERMINENT_CB_ID); - for (pos= 0; pos < BLI_CB_EVT_TOT; pos++) { + for (pos = 0; pos < BLI_CB_EVT_TOT; pos++) { /* clear only items without PERMINENT_CB_ID */ - PyObject *ls= py_cb_array[pos]; + PyObject *ls = py_cb_array[pos]; Py_ssize_t i; PyObject *item; PyObject **dict_ptr; - for(i= PyList_GET_SIZE(ls) - 1; i >= 0; i--) { + for (i = PyList_GET_SIZE(ls) - 1; i >= 0; i--) { - if ( (PyFunction_Check((item= PyList_GET_ITEM(ls, i)))) && - (dict_ptr= _PyObject_GetDictPtr(item)) && - (*dict_ptr) && - (PyDict_GetItem(*dict_ptr, perm_id_str) != NULL)) + if ( (PyFunction_Check((item = PyList_GET_ITEM(ls, i)))) && + (dict_ptr = _PyObject_GetDictPtr(item)) && + (*dict_ptr) && + (PyDict_GetItem(*dict_ptr, perm_id_str) != NULL)) { /* keep */ } @@ -275,12 +276,12 @@ /* the actual callback - not necessarily called from py */ void bpy_app_generic_callback(struct Main *UNUSED(main), struct ID *id, void *arg) { - PyObject *cb_list= py_cb_array[GET_INT_FROM_POINTER(arg)]; + PyObject *cb_list = py_cb_array[GET_INT_FROM_POINTER(arg)]; Py_ssize_t cb_list_len; - if ((cb_list_len= PyList_GET_SIZE(cb_list)) > 0) { - PyGILState_STATE gilstate= PyGILState_Ensure(); + if ((cb_list_len = PyList_GET_SIZE(cb_list)) > 0) { + PyGILState_STATE gilstate = PyGILState_Ensure(); - PyObject* args= PyTuple_New(1); // save python creating each call + PyObject* args = PyTuple_New(1); // save python creating each call PyObject* func; PyObject* ret; Py_ssize_t pos; @@ -297,10 +298,10 @@ } // Iterate the list and run the callbacks - for (pos=0; pos < cb_list_len; pos++) { - func= PyList_GET_ITEM(cb_list, pos); - ret= PyObject_Call(func, args, NULL); - if (ret==NULL) { + for (pos = 0; pos < cb_list_len; pos++) { + func = PyList_GET_ITEM(cb_list, pos); + ret = PyObject_Call(func, args, NULL); + if (ret == NULL) { PyErr_Print(); PyErr_Clear(); } diff -Nru blender-2.61/source/blender/python/intern/bpy.c blender-2.62/source/blender/python/intern/bpy.c --- blender-2.61/source/blender/python/intern/bpy.c 2011-12-13 19:48:28.000000000 +0000 +++ blender-2.62/source/blender/python/intern/bpy.c 2012-02-15 19:33:11.000000000 +0000 @@ -58,7 +58,7 @@ #include "../generic/blf_py_api.h" #include "../mathutils/mathutils.h" -PyObject *bpy_package_py= NULL; +PyObject *bpy_package_py = NULL; PyDoc_STRVAR(bpy_script_paths_doc, ".. function:: script_paths()\n" @@ -70,12 +70,12 @@ ); static PyObject *bpy_script_paths(PyObject *UNUSED(self)) { - PyObject *ret= PyTuple_New(2); + PyObject *ret = PyTuple_New(2); char *path; - path= BLI_get_folder(BLENDER_SYSTEM_SCRIPTS, NULL); + path = BLI_get_folder(BLENDER_SYSTEM_SCRIPTS, NULL); PyTuple_SET_ITEM(ret, 0, PyUnicode_FromString(path?path:"")); - path= BLI_get_folder(BLENDER_USER_SCRIPTS, NULL); + path = BLI_get_folder(BLENDER_USER_SCRIPTS, NULL); PyTuple_SET_ITEM(ret, 1, PyUnicode_FromString(path?path:"")); return ret; @@ -83,8 +83,8 @@ static int bpy_blend_paths_visit_cb(void *userdata, char *UNUSED(path_dst), const char *path_src) { - PyObject *list= (PyObject *)userdata; - PyObject *item= PyUnicode_DecodeFSDefault(path_src); + PyObject *list = (PyObject *)userdata; + PyObject *item = PyUnicode_DecodeFSDefault(path_src); PyList_Append(list, item); Py_DECREF(item); return FALSE; /* never edits the path */ @@ -106,13 +106,13 @@ ); static PyObject *bpy_blend_paths(PyObject *UNUSED(self), PyObject *args, PyObject *kw) { - int flag= 0; + int flag = 0; PyObject *list; - int absolute= FALSE; - int packed= FALSE; - int local= FALSE; - static const char *kwlist[]= {"absolute", "packed", "local", NULL}; + int absolute = FALSE; + int packed = FALSE; + int local = FALSE; + static const char *kwlist[] = {"absolute", "packed", "local", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kw, "|ii:blend_paths", (char **)kwlist, &absolute, &packed)) @@ -124,7 +124,7 @@ if (!packed) flag |= BPATH_TRAVERSE_SKIP_PACKED; if (local) flag |= BPATH_TRAVERSE_SKIP_LIBRARY; - list= PyList_New(0); + list = PyList_New(0); bpath_traverse_main(G.main, bpy_blend_paths_visit_cb, flag, (void *)list); @@ -132,13 +132,13 @@ } -// PyDoc_STRVAR(bpy_user_resource_doc[]= // now in bpy/utils.py +// PyDoc_STRVAR(bpy_user_resource_doc[] = // now in bpy/utils.py static PyObject *bpy_user_resource(PyObject *UNUSED(self), PyObject *args, PyObject *kw) { char *type; - char *subdir= NULL; + char *subdir = NULL; int folder_id; - static const char *kwlist[]= {"type", "subdir", NULL}; + static const char *kwlist[] = {"type", "subdir", NULL}; char *path; @@ -146,20 +146,20 @@ return NULL; /* stupid string compare */ - if (!strcmp(type, "DATAFILES")) folder_id= BLENDER_USER_DATAFILES; - else if (!strcmp(type, "CONFIG")) folder_id= BLENDER_USER_CONFIG; - else if (!strcmp(type, "SCRIPTS")) folder_id= BLENDER_USER_SCRIPTS; - else if (!strcmp(type, "AUTOSAVE")) folder_id= BLENDER_USER_AUTOSAVE; + if (!strcmp(type, "DATAFILES")) folder_id = BLENDER_USER_DATAFILES; + else if (!strcmp(type, "CONFIG")) folder_id = BLENDER_USER_CONFIG; + else if (!strcmp(type, "SCRIPTS")) folder_id = BLENDER_USER_SCRIPTS; + else if (!strcmp(type, "AUTOSAVE")) folder_id = BLENDER_USER_AUTOSAVE; else { PyErr_SetString(PyExc_ValueError, "invalid resource argument"); return NULL; } /* same logic as BLI_get_folder_create(), but best leave it up to the script author to create */ - path= BLI_get_folder(folder_id, subdir); + path = BLI_get_folder(folder_id, subdir); if (!path) - path= BLI_get_user_folder_notest(folder_id, subdir); + path = BLI_get_user_folder_notest(folder_id, subdir); return PyUnicode_DecodeFSDefault(path ? path : ""); } @@ -181,8 +181,8 @@ static PyObject *bpy_resource_path(PyObject *UNUSED(self), PyObject *args, PyObject *kw) { char *type; - int major= BLENDER_VERSION/100, minor= BLENDER_VERSION%100; - static const char *kwlist[]= {"type", "major", "minor", NULL}; + int major = BLENDER_VERSION / 100, minor = BLENDER_VERSION % 100; + static const char *kwlist[] = {"type", "major", "minor", NULL}; int folder_id; char *path; @@ -190,32 +190,32 @@ return NULL; /* stupid string compare */ - if (!strcmp(type, "USER")) folder_id= BLENDER_RESOURCE_PATH_USER; - else if (!strcmp(type, "LOCAL")) folder_id= BLENDER_RESOURCE_PATH_LOCAL; - else if (!strcmp(type, "SYSTEM")) folder_id= BLENDER_RESOURCE_PATH_SYSTEM; + if (!strcmp(type, "USER")) folder_id = BLENDER_RESOURCE_PATH_USER; + else if (!strcmp(type, "LOCAL")) folder_id = BLENDER_RESOURCE_PATH_LOCAL; + else if (!strcmp(type, "SYSTEM")) folder_id = BLENDER_RESOURCE_PATH_SYSTEM; else { PyErr_SetString(PyExc_ValueError, "invalid resource argument"); return NULL; } - path= BLI_get_folder_version(folder_id, (major * 100) + minor, FALSE); + path = BLI_get_folder_version(folder_id, (major * 100) + minor, FALSE); return PyUnicode_DecodeFSDefault(path); } -static PyMethodDef meth_bpy_script_paths= +static PyMethodDef meth_bpy_script_paths = {"script_paths", (PyCFunction)bpy_script_paths, METH_NOARGS, bpy_script_paths_doc}; -static PyMethodDef meth_bpy_blend_paths= +static PyMethodDef meth_bpy_blend_paths = {"blend_paths", (PyCFunction)bpy_blend_paths, METH_VARARGS|METH_KEYWORDS, bpy_blend_paths_doc}; -static PyMethodDef meth_bpy_user_resource= +static PyMethodDef meth_bpy_user_resource = {"user_resource", (PyCFunction)bpy_user_resource, METH_VARARGS|METH_KEYWORDS, NULL}; -static PyMethodDef meth_bpy_resource_path= +static PyMethodDef meth_bpy_resource_path = {"resource_path", (PyCFunction)bpy_resource_path, METH_VARARGS|METH_KEYWORDS, bpy_resource_path_doc}; static PyObject *bpy_import_test(const char *modname) { - PyObject *mod= PyImport_ImportModuleLevel((char *)modname, NULL, NULL, NULL, 0); + PyObject *mod = PyImport_ImportModuleLevel((char *)modname, NULL, NULL, NULL, 0); if (mod) { Py_DECREF(mod); } @@ -238,11 +238,11 @@ PyObject *mod; /* Needs to be first since this dir is needed for future modules */ - char *modpath= BLI_get_folder(BLENDER_SYSTEM_SCRIPTS, "modules"); + char *modpath = BLI_get_folder(BLENDER_SYSTEM_SCRIPTS, "modules"); if (modpath) { // printf("bpy: found module path '%s'.\n", modpath); - PyObject *sys_path= PySys_GetObject("path"); /* borrow */ - PyObject *py_modpath= PyUnicode_FromString(modpath); + PyObject *sys_path = PySys_GetObject("path"); /* borrow */ + PyObject *py_modpath = PyUnicode_FromString(modpath); PyList_Insert(sys_path, 0, py_modpath); /* add first */ Py_DECREF(py_modpath); } @@ -252,7 +252,7 @@ /* stand alone utility modules not related to blender directly */ IDProp_Init_Types(); /* not actually a submodule, just types */ - mod= PyModule_New("_bpy"); + mod = PyModule_New("_bpy"); /* add the module so we can import it */ PyDict_SetItemString(PyImport_GetModuleDict(), "_bpy", mod); @@ -280,7 +280,7 @@ /* bpy context */ RNA_pointer_create(NULL, &RNA_Context, (void *)BPy_GetContext(), &ctx_ptr); - bpy_context_module= (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ctx_ptr); + bpy_context_module = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ctx_ptr); /* odd that this is needed, 1 ref on creation and another for the module * but without we get a crash on exit */ Py_INCREF(bpy_context_module); @@ -298,5 +298,5 @@ PyModule_AddObject(mod, meth_bpy_unregister_class.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_unregister_class, NULL)); /* add our own modules dir, this is a python package */ - bpy_package_py= bpy_import_test("bpy"); + bpy_package_py = bpy_import_test("bpy"); } diff -Nru blender-2.61/source/blender/python/intern/bpy_driver.c blender-2.62/source/blender/python/intern/bpy_driver.c --- blender-2.61/source/blender/python/intern/bpy_driver.c 2011-12-13 19:48:28.000000000 +0000 +++ blender-2.62/source/blender/python/intern/bpy_driver.c 2012-02-15 19:33:11.000000000 +0000 @@ -47,7 +47,7 @@ /* for pydrivers (drivers using one-line Python expressions to express relationships between targets) */ -PyObject *bpy_pydriver_Dict= NULL; +PyObject *bpy_pydriver_Dict = NULL; /* For faster execution we keep a special dictionary for pydrivers, with * the needed modules and aliases. @@ -59,32 +59,32 @@ /* validate namespace for driver evaluation */ if (bpy_pydriver_Dict) return -1; - d= PyDict_New(); + d = PyDict_New(); if (d == NULL) return -1; else - bpy_pydriver_Dict= d; + bpy_pydriver_Dict = d; /* import some modules: builtins, bpy, math, (Blender.noise)*/ PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins()); - mod= PyImport_ImportModule("math"); + mod = PyImport_ImportModule("math"); if (mod) { PyDict_Merge(d, PyModule_GetDict(mod), 0); /* 0 - dont overwrite existing values */ Py_DECREF(mod); } /* add bpy to global namespace */ - mod= PyImport_ImportModuleLevel((char *)"bpy", NULL, NULL, NULL, 0); + mod = PyImport_ImportModuleLevel((char *)"bpy", NULL, NULL, NULL, 0); if (mod) { PyDict_SetItemString(bpy_pydriver_Dict, "bpy", mod); Py_DECREF(mod); } /* add noise to global namespace */ - mod= PyImport_ImportModuleLevel((char *)"mathutils", NULL, NULL, NULL, 0); + mod = PyImport_ImportModuleLevel((char *)"mathutils", NULL, NULL, NULL, 0); if (mod) { - PyObject *modsub= PyDict_GetItemString(PyModule_GetDict(mod), "noise"); + PyObject *modsub = PyDict_GetItemString(PyModule_GetDict(mod), "noise"); PyDict_SetItemString(bpy_pydriver_Dict, "noise", modsub); Py_DECREF(mod); } @@ -93,25 +93,24 @@ } /* note, this function should do nothing most runs, only when changing frame */ -static PyObject *bpy_pydriver_InternStr__frame= NULL; +static PyObject *bpy_pydriver_InternStr__frame = NULL; +/* not thread safe but neither is python */ +static float bpy_pydriver_evaltime_prev = FLT_MAX; static void bpy_pydriver_update_dict(const float evaltime) { - /* not thread safe but neither is python */ - static float evaltime_prev= FLT_MAX; - - if (evaltime_prev != evaltime) { + if (bpy_pydriver_evaltime_prev != evaltime) { /* currently only update the frame */ if (bpy_pydriver_InternStr__frame == NULL) { - bpy_pydriver_InternStr__frame= PyUnicode_FromString("frame"); + bpy_pydriver_InternStr__frame = PyUnicode_FromString("frame"); } PyDict_SetItem(bpy_pydriver_Dict, bpy_pydriver_InternStr__frame, PyFloat_FromDouble(evaltime)); - evaltime_prev= evaltime; + bpy_pydriver_evaltime_prev = evaltime; } } @@ -123,20 +122,21 @@ void BPY_driver_reset(void) { PyGILState_STATE gilstate; - int use_gil= 1; /* !PYC_INTERPRETER_ACTIVE; */ + int use_gil = 1; /* !PYC_INTERPRETER_ACTIVE; */ if (use_gil) - gilstate= PyGILState_Ensure(); + gilstate = PyGILState_Ensure(); if (bpy_pydriver_Dict) { /* free the global dict used by pydrivers */ PyDict_Clear(bpy_pydriver_Dict); Py_DECREF(bpy_pydriver_Dict); - bpy_pydriver_Dict= NULL; + bpy_pydriver_Dict = NULL; } if (bpy_pydriver_InternStr__frame) { Py_DECREF(bpy_pydriver_InternStr__frame); - bpy_pydriver_InternStr__frame= NULL; + bpy_pydriver_InternStr__frame = NULL; + bpy_pydriver_evaltime_prev = FLT_MAX; } if (use_gil) @@ -170,22 +170,22 @@ */ float BPY_driver_exec(ChannelDriver *driver, const float evaltime) { - PyObject *driver_vars=NULL; - PyObject *retval= NULL; + PyObject *driver_vars = NULL; + PyObject *retval = NULL; PyObject *expr_vars; /* speed up by pre-hashing string & avoids re-converting unicode strings for every execution */ PyObject *expr_code; PyGILState_STATE gilstate; int use_gil; DriverVar *dvar; - double result= 0.0; /* default return */ - char *expr= NULL; - short targets_ok= 1; + double result = 0.0; /* default return */ + char *expr = NULL; + short targets_ok = 1; int i; /* get the py expression to be evaluated */ - expr= driver->expression; - if ((expr == NULL) || (expr[0]=='\0')) + expr = driver->expression; + if ((expr == NULL) || (expr[0] == '\0')) return 0.0f; if (!(G.f & G_SCRIPT_AUTOEXEC)) { @@ -193,10 +193,10 @@ return 0.0f; } - use_gil= 1; /* !PYC_INTERPRETER_ACTIVE; */ + use_gil = 1; /* !PYC_INTERPRETER_ACTIVE; */ if (use_gil) - gilstate= PyGILState_Ensure(); + gilstate = PyGILState_Ensure(); /* needed since drivers are updated directly after undo where 'main' is * re-allocated [#28807] */ @@ -216,51 +216,51 @@ bpy_pydriver_update_dict(evaltime); - if (driver->expr_comp==NULL) + if (driver->expr_comp == NULL) driver->flag |= DRIVER_FLAG_RECOMPILE; /* compile the expression first if it hasn't been compiled or needs to be rebuilt */ if (driver->flag & DRIVER_FLAG_RECOMPILE) { Py_XDECREF(driver->expr_comp); - driver->expr_comp= PyTuple_New(2); + driver->expr_comp = PyTuple_New(2); - expr_code= Py_CompileString(expr, "", Py_eval_input); + expr_code = Py_CompileString(expr, "", Py_eval_input); PyTuple_SET_ITEM(((PyObject *)driver->expr_comp), 0, expr_code); driver->flag &= ~DRIVER_FLAG_RECOMPILE; driver->flag |= DRIVER_FLAG_RENAMEVAR; /* maybe this can be removed but for now best keep until were sure */ } else { - expr_code= PyTuple_GET_ITEM(((PyObject *)driver->expr_comp), 0); + expr_code = PyTuple_GET_ITEM(((PyObject *)driver->expr_comp), 0); } if (driver->flag & DRIVER_FLAG_RENAMEVAR) { /* may not be set */ - expr_vars= PyTuple_GET_ITEM(((PyObject *)driver->expr_comp), 1); + expr_vars = PyTuple_GET_ITEM(((PyObject *)driver->expr_comp), 1); Py_XDECREF(expr_vars); - expr_vars= PyTuple_New(BLI_countlist(&driver->variables)); + expr_vars = PyTuple_New(BLI_countlist(&driver->variables)); PyTuple_SET_ITEM(((PyObject *)driver->expr_comp), 1, expr_vars); - for (dvar= driver->variables.first, i=0; dvar; dvar= dvar->next) { + for (dvar = driver->variables.first, i = 0; dvar; dvar = dvar->next) { PyTuple_SET_ITEM(expr_vars, i++, PyUnicode_FromString(dvar->name)); } driver->flag &= ~DRIVER_FLAG_RENAMEVAR; } else { - expr_vars= PyTuple_GET_ITEM(((PyObject *)driver->expr_comp), 1); + expr_vars = PyTuple_GET_ITEM(((PyObject *)driver->expr_comp), 1); } /* add target values to a dict that will be used as '__locals__' dict */ - driver_vars= PyDict_New(); // XXX do we need to decref this? - for (dvar= driver->variables.first, i=0; dvar; dvar= dvar->next) { - PyObject *driver_arg= NULL; - float tval= 0.0f; + driver_vars = PyDict_New(); // XXX do we need to decref this? + for (dvar = driver->variables.first, i = 0; dvar; dvar = dvar->next) { + PyObject *driver_arg = NULL; + float tval = 0.0f; /* try to get variable value */ - tval= driver_get_variable_value(driver, dvar); - driver_arg= PyFloat_FromDouble((double)tval); + tval = driver_get_variable_value(driver, dvar); + driver_arg = PyFloat_FromDouble((double)tval); /* try to add to dictionary */ /* if (PyDict_SetItemString(driver_vars, dvar->name, driver_arg)) { */ @@ -269,7 +269,7 @@ if (targets_ok) { /* first one - print some extra info for easier identification */ fprintf(stderr, "\nBPY_driver_eval() - Error while evaluating PyDriver:\n"); - targets_ok= 0; + targets_ok = 0; } fprintf(stderr, "\tBPY_driver_eval() - couldn't add variable '%s' to namespace\n", dvar->name); @@ -282,11 +282,11 @@ #if 0 // slow, with this can avoid all Py_CompileString above. /* execute expression to get a value */ - retval= PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict, driver_vars); + retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict, driver_vars); #else /* evaluate the compiled expression */ if (expr_code) - retval= PyEval_EvalCode((void *)expr_code, bpy_pydriver_Dict, driver_vars); + retval = PyEval_EvalCode((void *)expr_code, bpy_pydriver_Dict, driver_vars); #endif /* decref the driver vars first... */ @@ -296,10 +296,10 @@ if (retval == NULL) { pydriver_error(driver); } - else if ((result= PyFloat_AsDouble(retval)) == -1.0 && PyErr_Occurred()) { + else if ((result = PyFloat_AsDouble(retval)) == -1.0 && PyErr_Occurred()) { pydriver_error(driver); Py_DECREF(retval); - result= 0.0; + result = 0.0; } else { /* all fine, make sure the "invalid expression" flag is cleared */ diff -Nru blender-2.61/source/blender/python/intern/bpy_interface_atexit.c blender-2.62/source/blender/python/intern/bpy_interface_atexit.c --- blender-2.61/source/blender/python/intern/bpy_interface_atexit.c 2011-12-13 19:48:28.000000000 +0000 +++ blender-2.62/source/blender/python/intern/bpy_interface_atexit.c 2012-02-15 19:33:11.000000000 +0000 @@ -40,15 +40,15 @@ static PyObject *bpy_atexit(PyObject *UNUSED(self), PyObject *UNUSED(args), PyObject *UNUSED(kw)) { /* close down enough of blender at least not to crash */ - struct bContext *C= BPy_GetContext(); + struct bContext *C = BPy_GetContext(); WM_exit_ext(C, 0); Py_RETURN_NONE; } -static PyMethodDef meth_bpy_atexit= {"bpy_atexit", (PyCFunction)bpy_atexit, METH_NOARGS, NULL}; -static PyObject *func_bpy_atregister= NULL; /* borrowed referebce, atexit holds */ +static PyMethodDef meth_bpy_atexit = {"bpy_atexit", (PyCFunction)bpy_atexit, METH_NOARGS, NULL}; +static PyObject *func_bpy_atregister = NULL; /* borrowed referebce, atexit holds */ static void atexit_func_call(const char *func_name, PyObject *atexit_func_arg) { @@ -56,15 +56,15 @@ * this is intended, but if its problematic it could be changed * - campbell */ - PyObject *atexit_mod= PyImport_ImportModuleLevel((char *)"atexit", NULL, NULL, NULL, 0); - PyObject *atexit_func= PyObject_GetAttrString(atexit_mod, func_name); - PyObject *args= PyTuple_New(1); + PyObject *atexit_mod = PyImport_ImportModuleLevel((char *)"atexit", NULL, NULL, NULL, 0); + PyObject *atexit_func = PyObject_GetAttrString(atexit_mod, func_name); + PyObject *args = PyTuple_New(1); PyObject *ret; PyTuple_SET_ITEM(args, 0, atexit_func_arg); Py_INCREF(atexit_func_arg); /* only incref so we dont dec'ref along with 'args' */ - ret= PyObject_CallObject(atexit_func, args); + ret = PyObject_CallObject(atexit_func, args); Py_DECREF(atexit_mod); Py_DECREF(atexit_func); @@ -83,7 +83,7 @@ /* atexit module owns this new function reference */ BLI_assert(func_bpy_atregister == NULL); - func_bpy_atregister= (PyObject *)PyCFunction_New(&meth_bpy_atexit, NULL); + func_bpy_atregister = (PyObject *)PyCFunction_New(&meth_bpy_atexit, NULL); atexit_func_call("register", func_bpy_atregister); } @@ -92,5 +92,5 @@ BLI_assert(func_bpy_atregister != NULL); atexit_func_call("unregister", func_bpy_atregister); - func_bpy_atregister= NULL; /* don't really need to set but just incase */ + func_bpy_atregister = NULL; /* don't really need to set but just incase */ } diff -Nru blender-2.61/source/blender/python/intern/bpy_interface.c blender-2.62/source/blender/python/intern/bpy_interface.c --- blender-2.61/source/blender/python/intern/bpy_interface.c 2011-12-13 19:48:28.000000000 +0000 +++ blender-2.62/source/blender/python/intern/bpy_interface.c 2012-02-15 19:33:11.000000000 +0000 @@ -57,12 +57,13 @@ #include "BLI_string_utf8.h" #include "BLI_utildefines.h" - #include "BKE_context.h" #include "BKE_text.h" #include "BKE_main.h" #include "BKE_global.h" /* only for script checking */ +#include "CCL_api.h" + #include "BPY_extern.h" #include "../generic/bpy_internal_import.h" // our own imports @@ -76,14 +77,14 @@ /* for internal use, when starting and ending python scripts */ /* incase a python script triggers another python call, stop bpy_context_clear from invalidating */ -static int py_call_level= 0; -BPy_StructRNA *bpy_context_module= NULL; /* for fast access */ +static int py_call_level = 0; +BPy_StructRNA *bpy_context_module = NULL; /* for fast access */ // #define TIME_PY_RUN // simple python tests. prints on exit. #ifdef TIME_PY_RUN #include "PIL_time.h" -static int bpy_timer_count= 0; +static int bpy_timer_count = 0; static double bpy_timer; /* time since python starts */ static double bpy_timer_run; /* time for each python script run */ static double bpy_timer_run_tot; /* accumulate python runs */ @@ -102,18 +103,18 @@ py_call_level++; if (gilstate) - *gilstate= PyGILState_Ensure(); + *gilstate = PyGILState_Ensure(); - if (py_call_level==1) { + if (py_call_level == 1) { bpy_context_update(C); #ifdef TIME_PY_RUN - if (bpy_timer_count==0) { + if (bpy_timer_count == 0) { /* record time from the beginning */ - bpy_timer= PIL_check_seconds_timer(); - bpy_timer_run= bpy_timer_run_tot= 0.0; + bpy_timer = PIL_check_seconds_timer(); + bpy_timer_run = bpy_timer_run_tot = 0.0; } - bpy_timer_run= PIL_check_seconds_timer(); + bpy_timer_run = PIL_check_seconds_timer(); bpy_timer_count++; @@ -132,7 +133,7 @@ if (py_call_level < 0) { fprintf(stderr, "ERROR: Python context internal state bug. this should not happen!\n"); } - else if (py_call_level==0) { + else if (py_call_level == 0) { /* XXX - Calling classes currently wont store the context :\, * cant set NULL because of this. but this is very flakey still. */ #if 0 @@ -152,21 +153,21 @@ { if (text->compiled) { Py_DECREF((PyObject *)text->compiled); - text->compiled= NULL; + text->compiled = NULL; } } void BPY_modules_update(bContext *C) { #if 0 // slow, this runs all the time poll, draw etc 100's of time a sec. - PyObject *mod= PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0); + PyObject *mod = PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0); PyModule_AddObject(mod, "data", BPY_rna_module()); PyModule_AddObject(mod, "types", BPY_rna_types()); // atm this does not need updating #endif /* refreshes the main struct */ BPY_update_rna_module(); - bpy_context_module->ptr.data= (void *)C; + bpy_context_module->ptr.data = (void *)C; } void BPY_context_set(bContext *C) @@ -176,10 +177,16 @@ /* defined in AUD_C-API.cpp */ extern PyObject *AUD_initPython(void); -/* defined in cycles/blender */ -extern PyObject *CYCLES_initPython(void); -static struct _inittab bpy_internal_modules[]= { +#ifdef WITH_CYCLES +/* defined in cycles module */ +static PyObject *CCL_initPython(void) +{ + return (PyObject*)CCL_python_module_init(); +} +#endif + +static struct _inittab bpy_internal_modules[] = { {(char *)"mathutils", PyInit_mathutils}, // {(char *)"mathutils.geometry", PyInit_mathutils_geometry}, // {(char *)"mathutils.noise", PyInit_mathutils_noise}, @@ -189,7 +196,7 @@ {(char *)"aud", AUD_initPython}, #endif #ifdef WITH_CYCLES - {(char *)"bcycles", CYCLES_initPython}, + {(char *)"_cycles", CCL_initPython}, #endif {(char *)"gpu", GPU_initPython}, {NULL, NULL} @@ -199,7 +206,7 @@ void BPY_python_start(int argc, const char **argv) { #ifndef WITH_PYTHON_MODULE - PyThreadState *py_tstate= NULL; + PyThreadState *py_tstate = NULL; /* not essential but nice to set our name */ static wchar_t program_path_wchar[FILE_MAX]; /* python holds a reference */ @@ -222,7 +229,7 @@ /* Python 3.2 now looks for '2.xx/python/include/python3.2d/pyconfig.h' to * parse from the 'sysconfig' module which is used by 'site', * so for now disable site. alternatively we could copy the file. */ - Py_NoSiteFlag= 1; + Py_NoSiteFlag = 1; Py_Initialize(); @@ -230,8 +237,8 @@ /* sigh, why do python guys not have a char** version anymore? :( */ { int i; - PyObject *py_argv= PyList_New(argc); - for (i=0; i0) + if (bpy_timer_count > 0) printf("average run: %.6fsec, ", (bpy_timer_run_tot/bpy_timer_count)); - if (bpy_timer>0.0) - printf("tot usage %.4f%%", (bpy_timer_run_tot/bpy_timer)*100.0); + if (bpy_timer > 0.0) + printf("tot usage %.4f%%", (bpy_timer_run_tot/bpy_timer) * 100.0); printf("\n"); @@ -310,7 +320,7 @@ { int lineno; int offset; - python_script_error_jump(text->id.name+2, &lineno, &offset); + python_script_error_jump(text->id.name + 2, &lineno, &offset); if (lineno != -1) { /* select the line with the error */ txt_move_to(text, lineno - 1, INT_MAX, FALSE); @@ -334,13 +344,13 @@ static int python_script_exec(bContext *C, const char *fn, struct Text *text, struct ReportList *reports, const short do_jump) { - PyObject *main_mod= NULL; - PyObject *py_dict= NULL, *py_result= NULL; + PyObject *main_mod = NULL; + PyObject *py_dict = NULL, *py_result = NULL; PyGILState_STATE gilstate; BLI_assert(fn || text); - if (fn==NULL && text==NULL) { + if (fn == NULL && text == NULL) { return 0; } @@ -353,9 +363,9 @@ bpy_text_filename_get(fn_dummy, sizeof(fn_dummy), text); if (text->compiled == NULL) { /* if it wasn't already compiled, do it now */ - char *buf= txt_to_buf(text); + char *buf = txt_to_buf(text); - text->compiled= Py_CompileString(buf, fn_dummy, Py_file_input); + text->compiled = Py_CompileString(buf, fn_dummy, Py_file_input); MEM_freeN(buf); @@ -368,16 +378,16 @@ } if (text->compiled) { - py_dict= PyC_DefaultNameSpace(fn_dummy); - py_result= PyEval_EvalCode(text->compiled, py_dict, py_dict); + py_dict = PyC_DefaultNameSpace(fn_dummy); + py_result = PyEval_EvalCode(text->compiled, py_dict, py_dict); } } else { - FILE *fp= fopen(fn, "r"); + FILE *fp = fopen(fn, "r"); if (fp) { - py_dict= PyC_DefaultNameSpace(fn); + py_dict = PyC_DefaultNameSpace(fn); #ifdef _WIN32 /* Previously we used PyRun_File to run directly the code on a FILE @@ -390,14 +400,14 @@ fclose(fp); - pystring= MEM_mallocN(strlen(fn) + 32, "pystring"); - pystring[0]= '\0'; + pystring = MEM_mallocN(strlen(fn) + 32, "pystring"); + pystring[0] = '\0'; sprintf(pystring, "exec(open(r'%s').read())", fn); - py_result= PyRun_String(pystring, Py_file_input, py_dict, py_dict); + py_result = PyRun_String(pystring, Py_file_input, py_dict, py_dict); MEM_freeN(pystring); } #else - py_result= PyRun_File(fp, fn, Py_file_input, py_dict, py_dict); + py_result = PyRun_File(fp, fn, Py_file_input, py_dict, py_dict); fclose(fp); #endif } @@ -405,7 +415,7 @@ PyErr_Format(PyExc_IOError, "Python file \"%s\" could not be opened: %s", fn, strerror(errno)); - py_result= NULL; + py_result = NULL; } } @@ -423,11 +433,11 @@ if (py_dict) { #ifdef PYMODULE_CLEAR_WORKAROUND - PyModuleObject *mmod= (PyModuleObject *)PyDict_GetItemString(PyThreadState_GET()->interp->modules, "__main__"); - PyObject *dict_back= mmod->md_dict; + PyModuleObject *mmod = (PyModuleObject *)PyDict_GetItemString(PyThreadState_GET()->interp->modules, "__main__"); + PyObject *dict_back = mmod->md_dict; /* freeing the module will clear the namespace, * gives problems running classes defined in this namespace being used later. */ - mmod->md_dict= NULL; + mmod->md_dict = NULL; Py_DECREF(dict_back); #endif @@ -455,7 +465,7 @@ void BPY_DECREF(void *pyob_ptr) { - PyGILState_STATE gilstate= PyGILState_Ensure(); + PyGILState_STATE gilstate = PyGILState_Ensure(); Py_DECREF((PyObject *)pyob_ptr); PyGILState_Release(gilstate); } @@ -465,13 +475,13 @@ { PyGILState_STATE gilstate; PyObject *py_dict, *mod, *retval; - int error_ret= 0; - PyObject *main_mod= NULL; + int error_ret = 0; + PyObject *main_mod = NULL; if (!value || !expr) return -1; - if (expr[0]=='\0') { - *value= 0.0; + if (expr[0] == '\0') { + *value = 0.0; return error_ret; } @@ -479,9 +489,9 @@ PyC_MainModule_Backup(&main_mod); - py_dict= PyC_DefaultNameSpace(""); + py_dict = PyC_DefaultNameSpace(""); - mod= PyImport_ImportModule("math"); + mod = PyImport_ImportModule("math"); if (mod) { PyDict_Merge(py_dict, PyModule_GetDict(mod), 0); /* 0 - dont overwrite existing values */ Py_DECREF(mod); @@ -491,10 +501,10 @@ PyErr_Clear(); } - retval= PyRun_String(expr, Py_eval_input, py_dict, py_dict); + retval = PyRun_String(expr, Py_eval_input, py_dict, py_dict); if (retval == NULL) { - error_ret= -1; + error_ret = -1; } else { double val; @@ -503,25 +513,25 @@ /* Users my have typed in 10km, 2m * add up all values */ int i; - val= 0.0; + val = 0.0; - for (i=0; i"); + py_dict = PyC_DefaultNameSpace(""); - bmain_back= bpy_import_main_get(); + bmain_back = bpy_import_main_get(); bpy_import_main_set(CTX_data_main(C)); - retval= PyRun_String(expr, Py_eval_input, py_dict, py_dict); + retval = PyRun_String(expr, Py_eval_input, py_dict, py_dict); bpy_import_main_set(bmain_back); if (retval == NULL) { - error_ret= -1; + error_ret = -1; BPy_errors_to_report(CTX_wm_reports(C)); } @@ -588,11 +598,11 @@ void BPY_modules_load_user(bContext *C) { PyGILState_STATE gilstate; - Main *bmain= CTX_data_main(C); + Main *bmain = CTX_data_main(C); Text *text; /* can happen on file load */ - if (bmain==NULL) + if (bmain == NULL) return; /* update pointers since this can run from a nested script @@ -603,15 +613,15 @@ bpy_context_set(C, &gilstate); - for (text=CTX_data_main(C)->text.first; text; text= text->id.next) { - if (text->flags & TXT_ISSCRIPT && BLI_testextensie(text->id.name+2, ".py")) { + for (text = CTX_data_main(C)->text.first; text; text = text->id.next) { + if (text->flags & TXT_ISSCRIPT && BLI_testextensie(text->id.name + 2, ".py")) { if (!(G.f & G_SCRIPT_AUTOEXEC)) { - printf("scripts disabled for \"%s\", skipping '%s'\n", bmain->name, text->id.name+2); + printf("scripts disabled for \"%s\", skipping '%s'\n", bmain->name, text->id.name + 2); } else { - PyObject *module= bpy_text_import(text); + PyObject *module = bpy_text_import(text); - if (module==NULL) { + if (module == NULL) { PyErr_Print(); PyErr_Clear(); } @@ -626,43 +636,43 @@ int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *result) { - PyObject *pyctx= (PyObject *)CTX_py_dict_get(C); - PyObject *item= PyDict_GetItemString(pyctx, member); - PointerRNA *ptr= NULL; - int done= 0; + PyObject *pyctx = (PyObject *)CTX_py_dict_get(C); + PyObject *item = PyDict_GetItemString(pyctx, member); + PointerRNA *ptr = NULL; + int done = 0; - if (item==NULL) { + if (item == NULL) { /* pass */ } - else if (item==Py_None) { + else if (item == Py_None) { /* pass */ } else if (BPy_StructRNA_Check(item)) { - ptr= &(((BPy_StructRNA *)item)->ptr); + ptr = &(((BPy_StructRNA *)item)->ptr); - //result->ptr= ((BPy_StructRNA *)item)->ptr; + //result->ptr = ((BPy_StructRNA *)item)->ptr; CTX_data_pointer_set(result, ptr->id.data, ptr->type, ptr->data); - done= 1; + done = 1; } else if (PySequence_Check(item)) { - PyObject *seq_fast= PySequence_Fast(item, "bpy_context_get sequence conversion"); - if (seq_fast==NULL) { + PyObject *seq_fast = PySequence_Fast(item, "bpy_context_get sequence conversion"); + if (seq_fast == NULL) { PyErr_Print(); PyErr_Clear(); } else { - int len= PySequence_Fast_GET_SIZE(seq_fast); + int len = PySequence_Fast_GET_SIZE(seq_fast); int i; - for (i= 0; i < len; i++) { - PyObject *list_item= PySequence_Fast_GET_ITEM(seq_fast, i); + for (i = 0; i < len; i++) { + PyObject *list_item = PySequence_Fast_GET_ITEM(seq_fast, i); if (BPy_StructRNA_Check(list_item)) { /* - CollectionPointerLink *link= MEM_callocN(sizeof(CollectionPointerLink), "bpy_context_get"); - link->ptr= ((BPy_StructRNA *)item)->ptr; + CollectionPointerLink *link = MEM_callocN(sizeof(CollectionPointerLink), "bpy_context_get"); + link->ptr = ((BPy_StructRNA *)item)->ptr; BLI_addtail(&result->list, link); */ - ptr= &(((BPy_StructRNA *)list_item)->ptr); + ptr = &(((BPy_StructRNA *)list_item)->ptr); CTX_data_list_add(result, ptr->id.data, ptr->type, ptr->data); } else { @@ -672,11 +682,11 @@ } Py_DECREF(seq_fast); - done= 1; + done = 1; } } - if (done==0) { + if (done == 0) { if (item) printf("PyContext '%s' not a valid type\n", member); else printf("PyContext '%s' not found\n", member); } @@ -697,7 +707,7 @@ static void bpy_module_free(void *mod); extern int main_python_enter(int argc, const char **argv); extern void main_python_exit(void); -static struct PyModuleDef bpy_proxy_def= { +static struct PyModuleDef bpy_proxy_def = { PyModuleDef_HEAD_INIT, "bpy", /* m_name */ NULL, /* m_doc */ @@ -718,20 +728,20 @@ /* call once __file__ is set */ void bpy_module_delay_init(PyObject *bpy_proxy) { - const int argc= 1; + const int argc = 1; const char *argv[2]; /* updating the module dict below will loose the reference to __file__ */ - PyObject *filename_obj= PyModule_GetFilenameObject(bpy_proxy); + PyObject *filename_obj = PyModule_GetFilenameObject(bpy_proxy); - const char *filename_rel= _PyUnicode_AsString(filename_obj); /* can be relative */ + const char *filename_rel = _PyUnicode_AsString(filename_obj); /* can be relative */ char filename_abs[1024]; BLI_strncpy(filename_abs, filename_rel, sizeof(filename_abs)); BLI_path_cwd(filename_abs); - argv[0]= filename_abs; - argv[1]= NULL; + argv[0] = filename_abs; + argv[1] = NULL; // printf("module found %s\n", argv[0]); @@ -743,7 +753,7 @@ static void dealloc_obj_dealloc(PyObject *self); -static PyTypeObject dealloc_obj_Type= {{{0}}}; +static PyTypeObject dealloc_obj_Type = {{{0}}}; /* use our own dealloc so we can free a property if we use one */ static void dealloc_obj_dealloc(PyObject *self) @@ -757,7 +767,7 @@ PyMODINIT_FUNC PyInit_bpy(void) { - PyObject *bpy_proxy= PyModule_Create(&bpy_proxy_def); + PyObject *bpy_proxy = PyModule_Create(&bpy_proxy_def); /* Problem: * 1) this init function is expected to have a private member defined - 'md_def' @@ -777,16 +787,16 @@ dealloc_obj *dob; /* assign dummy type */ - dealloc_obj_Type.tp_name= "dealloc_obj"; - dealloc_obj_Type.tp_basicsize= sizeof(dealloc_obj); - dealloc_obj_Type.tp_dealloc= dealloc_obj_dealloc; - dealloc_obj_Type.tp_flags= Py_TPFLAGS_DEFAULT; + dealloc_obj_Type.tp_name = "dealloc_obj"; + dealloc_obj_Type.tp_basicsize = sizeof(dealloc_obj); + dealloc_obj_Type.tp_dealloc = dealloc_obj_dealloc; + dealloc_obj_Type.tp_flags = Py_TPFLAGS_DEFAULT; if (PyType_Ready(&dealloc_obj_Type) < 0) return NULL; - dob= (dealloc_obj *) dealloc_obj_Type.tp_alloc(&dealloc_obj_Type, 0); - dob->mod= bpy_proxy; /* borrow */ + dob = (dealloc_obj *) dealloc_obj_Type.tp_alloc(&dealloc_obj_Type, 0); + dob->mod = bpy_proxy; /* borrow */ PyModule_AddObject(bpy_proxy, "__file__", (PyObject *)dob); /* borrow */ return bpy_proxy; diff -Nru blender-2.61/source/blender/python/intern/bpy_intern_string.c blender-2.62/source/blender/python/intern/bpy_intern_string.c --- blender-2.61/source/blender/python/intern/bpy_intern_string.c 2011-12-13 19:48:28.000000000 +0000 +++ blender-2.62/source/blender/python/intern/bpy_intern_string.c 2012-02-15 19:33:11.000000000 +0000 @@ -41,12 +41,12 @@ void bpy_intern_string_init(void) { - bpy_intern_str_register= PyUnicode_FromString("register"); - bpy_intern_str_unregister= PyUnicode_FromString("unregister"); - bpy_intern_str_bl_rna= PyUnicode_FromString("bl_rna"); - bpy_intern_str_order= PyUnicode_FromString("order"); - bpy_intern_str_attr= PyUnicode_FromString("attr"); - bpy_intern_str___slots__= PyUnicode_FromString("__slots__"); + bpy_intern_str_register = PyUnicode_FromString("register"); + bpy_intern_str_unregister = PyUnicode_FromString("unregister"); + bpy_intern_str_bl_rna = PyUnicode_FromString("bl_rna"); + bpy_intern_str_order = PyUnicode_FromString("order"); + bpy_intern_str_attr = PyUnicode_FromString("attr"); + bpy_intern_str___slots__ = PyUnicode_FromString("__slots__"); } void bpy_intern_string_exit(void) diff -Nru blender-2.61/source/blender/python/intern/bpy_library.c blender-2.62/source/blender/python/intern/bpy_library.c --- blender-2.61/source/blender/python/intern/bpy_library.c 2011-12-13 19:48:28.000000000 +0000 +++ blender-2.62/source/blender/python/intern/bpy_library.c 2012-02-15 19:33:11.000000000 +0000 @@ -76,7 +76,7 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *args); static PyObject *bpy_lib_dir(BPy_Library *self); -static PyMethodDef bpy_lib_methods[]= { +static PyMethodDef bpy_lib_methods[] = { {"__enter__", (PyCFunction)bpy_lib_enter, METH_NOARGS}, {"__exit__", (PyCFunction)bpy_lib_exit, METH_VARARGS}, {"__dir__", (PyCFunction)bpy_lib_dir, METH_NOARGS}, @@ -90,7 +90,7 @@ } -static PyTypeObject bpy_lib_Type= { +static PyTypeObject bpy_lib_Type = { PyVarObject_HEAD_INIT(NULL, 0) "bpy_lib", /* tp_name */ sizeof(BPy_Library), /* tp_basicsize */ @@ -184,25 +184,25 @@ ); static PyObject *bpy_lib_load(PyObject *UNUSED(self), PyObject *args, PyObject *kwds) { - static const char *kwlist[]= {"filepath", "link", "relative", NULL}; + static const char *kwlist[] = {"filepath", "link", "relative", NULL}; BPy_Library *ret; - const char* filename= NULL; - int is_rel= 0, is_link= 0; + const char* filename = NULL; + int is_rel = 0, is_link = 0; if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|ii:load", (char **)kwlist, &filename, &is_link, &is_rel)) return NULL; - ret= PyObject_New(BPy_Library, &bpy_lib_Type); + ret = PyObject_New(BPy_Library, &bpy_lib_Type); BLI_strncpy(ret->relpath, filename, sizeof(ret->relpath)); BLI_strncpy(ret->abspath, filename, sizeof(ret->abspath)); BLI_path_abs(ret->abspath, G.main->name); - ret->blo_handle= NULL; + ret->blo_handle = NULL; ret->flag= (is_link ? FILE_LINK : 0) | (is_rel ? FILE_RELPATH : 0); - ret->dict= PyDict_New(); + ret->dict = PyDict_New(); return (PyObject *)ret; } @@ -213,19 +213,19 @@ LinkNode *l, *names; int totnames; - names= BLO_blendhandle_get_datablock_names(self->blo_handle, blocktype, &totnames); + names = BLO_blendhandle_get_datablock_names(self->blo_handle, blocktype, &totnames); if (names) { - int counter= 0; - list= PyList_New(totnames); - for (l= names; l; l= l->next) { + int counter = 0; + list = PyList_New(totnames); + for (l = names; l; l = l->next) { PyList_SET_ITEM(list, counter, PyUnicode_FromString((char *)l->link)); counter++; } BLI_linklist_free(names, free); /* free linklist *and* each node's data */ } else { - list= PyList_New(0); + list = PyList_New(0); } return list; @@ -235,12 +235,12 @@ { PyObject *ret; BPy_Library *self_from; - PyObject *from_dict= PyDict_New(); + PyObject *from_dict = PyDict_New(); ReportList reports; BKE_reports_init(&reports, RPT_STORE); - self->blo_handle= BLO_blendhandle_from_file(self->abspath, &reports); + self->blo_handle = BLO_blendhandle_from_file(self->abspath, &reports); if (self->blo_handle == NULL) { if (BPy_reports_to_error(&reports, PyExc_IOError, TRUE) != -1) { @@ -251,11 +251,11 @@ return NULL; } else { - int i= 0, code; - while ((code= BKE_idcode_iter_step(&i))) { + int i = 0, code; + while ((code = BKE_idcode_iter_step(&i))) { if (BKE_idcode_is_linkable(code)) { - const char *name_plural= BKE_idcode_to_name_plural(code); - PyObject *str= PyUnicode_FromString(name_plural); + const char *name_plural = BKE_idcode_to_name_plural(code); + PyObject *str = PyUnicode_FromString(name_plural); PyDict_SetItem(self->dict, str, PyList_New(0)); PyDict_SetItem(from_dict, str, _bpy_names(self, code)); Py_DECREF(str); @@ -264,16 +264,16 @@ } /* create a dummy */ - self_from= PyObject_New(BPy_Library, &bpy_lib_Type); + self_from = PyObject_New(BPy_Library, &bpy_lib_Type); BLI_strncpy(self_from->relpath, self->relpath, sizeof(self_from->relpath)); BLI_strncpy(self_from->abspath, self->abspath, sizeof(self_from->abspath)); - self_from->blo_handle= NULL; - self_from->flag= 0; - self_from->dict= from_dict; /* owns the dict */ + self_from->blo_handle = NULL; + self_from->flag = 0; + self_from->dict = from_dict; /* owns the dict */ /* return pair */ - ret= PyTuple_New(2); + ret = PyTuple_New(2); PyTuple_SET_ITEM(ret, 0, (PyObject *)self_from); @@ -317,43 +317,43 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args)) { - Main *bmain= CTX_data_main(BPy_GetContext()); - Main *mainl= NULL; - int err= 0; + Main *bmain = CTX_data_main(BPy_GetContext()); + Main *mainl = NULL; + int err = 0; flag_all_listbases_ids(LIB_PRE_EXISTING, 1); /* here appending/linking starts */ - mainl= BLO_library_append_begin(bmain, &(self->blo_handle), self->relpath); + mainl = BLO_library_append_begin(bmain, &(self->blo_handle), self->relpath); { - int i= 0, code; - while ((code= BKE_idcode_iter_step(&i))) { + int i = 0, code; + while ((code = BKE_idcode_iter_step(&i))) { if (BKE_idcode_is_linkable(code)) { - const char *name_plural= BKE_idcode_to_name_plural(code); - PyObject *ls= PyDict_GetItemString(self->dict, name_plural); + const char *name_plural = BKE_idcode_to_name_plural(code); + PyObject *ls = PyDict_GetItemString(self->dict, name_plural); // printf("lib: %s\n", name_plural); if (ls && PyList_Check(ls)) { /* loop */ - Py_ssize_t size= PyList_GET_SIZE(ls); + Py_ssize_t size = PyList_GET_SIZE(ls); Py_ssize_t i; PyObject *item; const char *item_str; - for (i= 0; i < size; i++) { - item= PyList_GET_ITEM(ls, i); - item_str= _PyUnicode_AsString(item); + for (i = 0; i < size; i++) { + item = PyList_GET_ITEM(ls, i); + item_str = _PyUnicode_AsString(item); // printf(" %s\n", item_str); if (item_str) { - ID *id= BLO_library_append_named_part(mainl, &(self->blo_handle), item_str, code); + ID *id = BLO_library_append_named_part(mainl, &(self->blo_handle), item_str, code); if (id) { #ifdef USE_RNA_DATABLOCKS PointerRNA id_ptr; RNA_id_pointer_create(id, &id_ptr); Py_DECREF(item); - item= pyrna_struct_CreatePyObject(&id_ptr); + item = pyrna_struct_CreatePyObject(&id_ptr); #endif } else { @@ -361,7 +361,7 @@ /* just warn for now */ /* err = -1; */ #ifdef USE_RNA_DATABLOCKS - item= Py_None; + item = Py_None; Py_INCREF(item); #endif } @@ -374,7 +374,7 @@ PyErr_Clear(); #ifdef USE_RNA_DATABLOCKS - item= Py_None; + item = Py_None; Py_INCREF(item); #endif } @@ -391,22 +391,22 @@ if (err == -1) { /* exception raised above, XXX, this leaks some memory */ BLO_blendhandle_close(self->blo_handle); - self->blo_handle= NULL; + self->blo_handle = NULL; flag_all_listbases_ids(LIB_PRE_EXISTING, 0); return NULL; } else { - Library *lib= mainl->curlib; /* newly added lib, assign before append end */ + Library *lib = mainl->curlib; /* newly added lib, assign before append end */ BLO_library_append_end(NULL, mainl, &(self->blo_handle), 0, self->flag); BLO_blendhandle_close(self->blo_handle); - self->blo_handle= NULL; + self->blo_handle = NULL; { /* copied from wm_operator.c */ /* mark all library linked objects to be updated */ recalc_all_library_objects(G.main); /* append, rather than linking */ - if ((self->flag & FILE_LINK)==0) { + if ((self->flag & FILE_LINK) == 0) { BKE_library_make_local(bmain, lib, 1); } } @@ -425,14 +425,14 @@ int bpy_lib_init(PyObject *mod_par) { - static PyMethodDef load_meth= {"load", (PyCFunction)bpy_lib_load, + static PyMethodDef load_meth = {"load", (PyCFunction)bpy_lib_load, METH_STATIC|METH_VARARGS|METH_KEYWORDS, bpy_lib_load_doc}; PyModule_AddObject(mod_par, "_library_load", PyCFunction_New(&load_meth, NULL)); /* some compilers dont like accessing this directly, delay assignment */ - bpy_lib_Type.tp_getattro= PyObject_GenericGetAttr; + bpy_lib_Type.tp_getattro = PyObject_GenericGetAttr; if (PyType_Ready(&bpy_lib_Type) < 0) return -1; diff -Nru blender-2.61/source/blender/python/intern/bpy_operator.c blender-2.62/source/blender/python/intern/bpy_operator.c --- blender-2.61/source/blender/python/intern/bpy_operator.c 2011-12-13 19:48:28.000000000 +0000 +++ blender-2.62/source/blender/python/intern/bpy_operator.c 2012-02-15 19:33:11.000000000 +0000 @@ -66,18 +66,18 @@ { wmOperatorType *ot; char *opname; - PyObject *context_dict= NULL; /* optional args */ + PyObject *context_dict = NULL; /* optional args */ PyObject *context_dict_back; - char *context_str= NULL; + char *context_str = NULL; PyObject *ret; - int context= WM_OP_EXEC_DEFAULT; + int context = WM_OP_EXEC_DEFAULT; /* XXX Todo, work out a better solution for passing on context, * could make a tuple from self and pack the name and Context into it... */ - bContext *C= (bContext *)BPy_GetContext(); + bContext *C = (bContext *)BPy_GetContext(); - if (C==NULL) { + if (C == NULL) { PyErr_SetString(PyExc_RuntimeError, "Context is None, cant poll any operators"); return NULL; } @@ -85,7 +85,7 @@ if (!PyArg_ParseTuple(args, "s|Os:_bpy.ops.poll", &opname, &context_dict, &context_str)) return NULL; - ot= WM_operatortype_find(opname, TRUE); + ot = WM_operatortype_find(opname, TRUE); if (ot == NULL) { PyErr_Format(PyExc_AttributeError, @@ -95,8 +95,8 @@ } if (context_str) { - if (RNA_enum_value_from_id(operator_context_items, context_str, &context)==0) { - char *enum_str= BPy_enum_as_string(operator_context_items); + if (RNA_enum_value_from_id(operator_context_items, context_str, &context) == 0) { + char *enum_str = BPy_enum_as_string(operator_context_items); PyErr_Format(PyExc_TypeError, "Calling operator \"bpy.ops.%s.poll\" error, " "expected a string enum in (%.200s)", @@ -106,8 +106,8 @@ } } - if (context_dict==NULL || context_dict==Py_None) { - context_dict= NULL; + if (context_dict == NULL || context_dict == Py_None) { + context_dict = NULL; } else if (!PyDict_Check(context_dict)) { PyErr_Format(PyExc_TypeError, @@ -117,12 +117,12 @@ return NULL; } - context_dict_back= CTX_py_dict_get(C); + context_dict_back = CTX_py_dict_get(C); CTX_py_dict_set(C, (void *)context_dict); Py_XINCREF(context_dict); /* so we done loose it */ /* main purpose of thsi function */ - ret= WM_operator_poll_context((bContext*)C, ot, context) ? Py_True : Py_False; + ret = WM_operator_poll_context((bContext *)C, ot, context) ? Py_True : Py_False; /* restore with original context dict, probably NULL but need this for nested operator calls */ Py_XDECREF(context_dict); @@ -135,24 +135,24 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args) { wmOperatorType *ot; - int error_val= 0; + int error_val = 0; PointerRNA ptr; - int operator_ret= OPERATOR_CANCELLED; + int operator_ret = OPERATOR_CANCELLED; char *opname; - char *context_str= NULL; - PyObject *kw= NULL; /* optional args */ - PyObject *context_dict= NULL; /* optional args */ + char *context_str = NULL; + PyObject *kw = NULL; /* optional args */ + PyObject *context_dict = NULL; /* optional args */ PyObject *context_dict_back; /* note that context is an int, python does the conversion in this case */ - int context= WM_OP_EXEC_DEFAULT; + int context = WM_OP_EXEC_DEFAULT; /* XXX Todo, work out a better solution for passing on context, * could make a tuple from self and pack the name and Context into it... */ - bContext *C= (bContext *)BPy_GetContext(); + bContext *C = (bContext *)BPy_GetContext(); - if (C==NULL) { + if (C == NULL) { PyErr_SetString(PyExc_RuntimeError, "Context is None, cant poll any operators"); return NULL; } @@ -160,7 +160,7 @@ if (!PyArg_ParseTuple(args, "sO|O!s:_bpy.ops.call", &opname, &context_dict, &PyDict_Type, &kw, &context_str)) return NULL; - ot= WM_operatortype_find(opname, TRUE); + ot = WM_operatortype_find(opname, TRUE); if (ot == NULL) { PyErr_Format(PyExc_AttributeError, @@ -178,8 +178,8 @@ } if (context_str) { - if (RNA_enum_value_from_id(operator_context_items, context_str, &context)==0) { - char *enum_str= BPy_enum_as_string(operator_context_items); + if (RNA_enum_value_from_id(operator_context_items, context_str, &context) == 0) { + char *enum_str = BPy_enum_as_string(operator_context_items); PyErr_Format(PyExc_TypeError, "Calling operator \"bpy.ops.%s\" error, " "expected a string enum in (%.200s)", @@ -189,8 +189,8 @@ } } - if (context_dict==NULL || context_dict==Py_None) { - context_dict= NULL; + if (context_dict == NULL || context_dict == Py_None) { + context_dict = NULL; } else if (!PyDict_Check(context_dict)) { PyErr_Format(PyExc_TypeError, @@ -200,31 +200,31 @@ return NULL; } - context_dict_back= CTX_py_dict_get(C); + context_dict_back = CTX_py_dict_get(C); CTX_py_dict_set(C, (void *)context_dict); Py_XINCREF(context_dict); /* so we done loose it */ - if (WM_operator_poll_context((bContext*)C, ot, context) == FALSE) { - const char *msg= CTX_wm_operator_poll_msg_get(C); + if (WM_operator_poll_context((bContext *)C, ot, context) == FALSE) { + const char *msg = CTX_wm_operator_poll_msg_get(C); PyErr_Format(PyExc_RuntimeError, "Operator bpy.ops.%.200s.poll() %.200s", opname, msg ? msg : "failed, context is incorrect"); CTX_wm_operator_poll_msg_set(C, NULL); /* better set to NULL else it could be used again */ - error_val= -1; + error_val = -1; } else { WM_operator_properties_create_ptr(&ptr, ot); WM_operator_properties_sanitize(&ptr, 0); if (kw && PyDict_Size(kw)) - error_val= pyrna_pydict_to_props(&ptr, kw, 0, "Converting py args to operator properties: "); + error_val = pyrna_pydict_to_props(&ptr, kw, 0, "Converting py args to operator properties: "); - if (error_val==0) { + if (error_val == 0) { ReportList *reports; - reports= MEM_mallocN(sizeof(ReportList), "wmOperatorReportList"); + reports = MEM_mallocN(sizeof(ReportList), "wmOperatorReportList"); BKE_reports_init(reports, RPT_STORE | RPT_OP_HOLD); /* own so these dont move into global reports */ #ifdef BPY_RELEASE_GIL @@ -233,10 +233,10 @@ /* note: I havve not seen any examples of code that does this * so it may not be officially supported but seems to work ok. */ { - PyThreadState *ts= PyEval_SaveThread(); + PyThreadState *ts = PyEval_SaveThread(); #endif - operator_ret= WM_operator_call_py(C, ot, context, &ptr, reports); + operator_ret = WM_operator_call_py(C, ot, context, &ptr, reports); #ifdef BPY_RELEASE_GIL /* regain GIL */ @@ -244,11 +244,11 @@ } #endif - error_val= BPy_reports_to_error(reports, PyExc_RuntimeError, FALSE); + error_val = BPy_reports_to_error(reports, PyExc_RuntimeError, FALSE); /* operator output is nice to have in the terminal/console too */ if (reports->list.first) { - char *report_str= BKE_reports_string(reports, 0); /* all reports */ + char *report_str = BKE_reports_string(reports, 0); /* all reports */ if (report_str) { PySys_WriteStdout("%s\n", report_str); @@ -285,7 +285,7 @@ Py_XDECREF(context_dict); CTX_py_dict_set(C, (void *)context_dict_back); - if (error_val==-1) { + if (error_val == -1) { return NULL; } @@ -308,16 +308,16 @@ PointerRNA ptr; char *opname; - PyObject *kw= NULL; /* optional args */ - int all_args= 1; - int error_val= 0; + PyObject *kw = NULL; /* optional args */ + int all_args = 1; + int error_val = 0; - char *buf= NULL; + char *buf = NULL; PyObject *pybuf; - bContext *C= (bContext *)BPy_GetContext(); + bContext *C = (bContext *)BPy_GetContext(); - if (C==NULL) { + if (C == NULL) { PyErr_SetString(PyExc_RuntimeError, "Context is None, cant get the string representation of this object."); return NULL; } @@ -325,7 +325,7 @@ if (!PyArg_ParseTuple(args, "s|O!i:_bpy.ops.as_string", &opname, &PyDict_Type, &kw, &all_args)) return NULL; - ot= WM_operatortype_find(opname, TRUE); + ot = WM_operatortype_find(opname, TRUE); if (ot == NULL) { PyErr_Format(PyExc_AttributeError, @@ -339,23 +339,23 @@ RNA_pointer_create(NULL, ot->srna, NULL, &ptr); if (kw && PyDict_Size(kw)) - error_val= pyrna_pydict_to_props(&ptr, kw, 0, "Converting py args to operator properties: "); + error_val = pyrna_pydict_to_props(&ptr, kw, 0, "Converting py args to operator properties: "); - if (error_val==0) - buf= WM_operator_pystring(C, ot, &ptr, all_args); + if (error_val == 0) + buf = WM_operator_pystring(C, ot, &ptr, all_args); WM_operator_properties_free(&ptr); - if (error_val==-1) { + if (error_val == -1) { return NULL; } if (buf) { - pybuf= PyUnicode_FromString(buf); + pybuf = PyUnicode_FromString(buf); MEM_freeN(buf); } else { - pybuf= PyUnicode_FromString(""); + pybuf = PyUnicode_FromString(""); } return pybuf; @@ -363,13 +363,13 @@ static PyObject *pyop_dir(PyObject *UNUSED(self)) { - GHashIterator *iter= WM_operatortype_iter(); - PyObject *list= PyList_New(0), *name; + GHashIterator *iter = WM_operatortype_iter(); + PyObject *list = PyList_New(0), *name; for ( ; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) { - wmOperatorType *ot= BLI_ghashIterator_getValue(iter); + wmOperatorType *ot = BLI_ghashIterator_getValue(iter); - name= PyUnicode_FromString(ot->idname); + name = PyUnicode_FromString(ot->idname); PyList_Append(list, name); Py_DECREF(name); } @@ -382,15 +382,15 @@ { wmOperatorType *ot; PointerRNA ptr; - const char *opname= _PyUnicode_AsString(value); - BPy_StructRNA *pyrna= NULL; + const char *opname = _PyUnicode_AsString(value); + BPy_StructRNA *pyrna = NULL; - if (opname==NULL) { + if (opname == NULL) { PyErr_SetString(PyExc_TypeError, "_bpy.ops.get_rna() expects a string argument"); return NULL; } - ot= WM_operatortype_find(opname, TRUE); - if (ot==NULL) { + ot = WM_operatortype_find(opname, TRUE); + if (ot == NULL) { PyErr_Format(PyExc_KeyError, "_bpy.ops.get_rna(\"%s\") not found", opname); return NULL; } @@ -403,9 +403,9 @@ WM_operator_properties_sanitize(&ptr, 0); - pyrna= (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr); + pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr); #ifdef PYRNA_FREE_SUPPORT - pyrna->freeptr= TRUE; + pyrna->freeptr = TRUE; #endif return (PyObject *)pyrna; } @@ -415,40 +415,40 @@ wmOperatorType *ot; wmOperator *op; PointerRNA ptr; - const char *opname= _PyUnicode_AsString(value); - BPy_StructRNA *pyrna= NULL; + const char *opname = _PyUnicode_AsString(value); + BPy_StructRNA *pyrna = NULL; - if (opname==NULL) { + if (opname == NULL) { PyErr_SetString(PyExc_TypeError, "_bpy.ops.get_instance() expects a string argument"); return NULL; } - ot= WM_operatortype_find(opname, TRUE); - if (ot==NULL) { + ot = WM_operatortype_find(opname, TRUE); + if (ot == NULL) { PyErr_Format(PyExc_KeyError, "_bpy.ops.get_instance(\"%s\") not found", opname); return NULL; } #ifdef PYRNA_FREE_SUPPORT - op= MEM_callocN(sizeof(wmOperator), __func__); + op = MEM_callocN(sizeof(wmOperator), __func__); #else - op= PyMem_MALLOC(sizeof(wmOperator)); + op = PyMem_MALLOC(sizeof(wmOperator)); memset(op, 0, sizeof(wmOperator)); #endif BLI_strncpy(op->idname, op->idname, sizeof(op->idname)); /* incase its needed */ - op->type= ot; + op->type = ot; RNA_pointer_create(NULL, &RNA_Operator, op, &ptr); - pyrna= (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr); + pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr); #ifdef PYRNA_FREE_SUPPORT - pyrna->freeptr= TRUE; + pyrna->freeptr = TRUE; #endif - op->ptr= &pyrna->ptr; + op->ptr = &pyrna->ptr; return (PyObject *)pyrna; } -static struct PyMethodDef bpy_ops_methods[]= { +static struct PyMethodDef bpy_ops_methods[] = { {"poll", (PyCFunction) pyop_poll, METH_VARARGS, NULL}, {"call", (PyCFunction) pyop_call, METH_VARARGS, NULL}, {"as_string", (PyCFunction) pyop_as_string, METH_VARARGS, NULL}, @@ -459,7 +459,7 @@ {NULL, NULL, 0, NULL} }; -static struct PyModuleDef bpy_ops_module= { +static struct PyModuleDef bpy_ops_module = { PyModuleDef_HEAD_INIT, "_bpy.ops", NULL, @@ -472,7 +472,7 @@ { PyObject *submodule; - submodule= PyModule_Create(&bpy_ops_module); + submodule = PyModule_Create(&bpy_ops_module); return submodule; } diff -Nru blender-2.61/source/blender/python/intern/bpy_operator_wrap.c blender-2.62/source/blender/python/intern/bpy_operator_wrap.c --- blender-2.61/source/blender/python/intern/bpy_operator_wrap.c 2011-12-13 19:48:28.000000000 +0000 +++ blender-2.62/source/blender/python/intern/bpy_operator_wrap.c 2012-02-15 19:33:11.000000000 +0000 @@ -45,7 +45,7 @@ static void operator_properties_init(wmOperatorType *ot) { - PyObject *py_class= ot->ext.data; + PyObject *py_class = ot->ext.data; RNA_struct_blender_type_set(ot->ext.srna, ot); /* only call this so pyrna_deferred_register_class gives a useful error @@ -63,9 +63,9 @@ { /* take care not to overwrite anything set in * WM_operatortype_append_ptr before opfunc() is called */ - StructRNA *srna= ot->srna; - *ot= *((wmOperatorType *)userdata); - ot->srna= srna; /* restore */ + StructRNA *srna = ot->srna; + *ot = *((wmOperatorType *)userdata); + ot->srna = srna; /* restore */ operator_properties_init(ot); @@ -74,25 +74,25 @@ PropertyRNA *prop; RNA_pointer_create(NULL, ot->srna, NULL, &ptr); - prop= RNA_struct_find_property(&ptr, "type"); + prop = RNA_struct_find_property(&ptr, "type"); if (prop) { - ot->prop= prop; + ot->prop = prop; } } } void macro_wrapper(wmOperatorType *ot, void *userdata) { - wmOperatorType *data= (wmOperatorType *)userdata; + wmOperatorType *data = (wmOperatorType *)userdata; /* only copy a couple of things, the rest is set by the macro registration */ - ot->name= data->name; - ot->idname= data->idname; - ot->description= data->description; + ot->name = data->name; + ot->idname = data->idname; + ot->description = data->description; ot->flag |= data->flag; /* append flags to the one set by registration */ - ot->pyop_poll= data->pyop_poll; - ot->ui= data->ui; - ot->ext= data->ext; + ot->pyop_poll = data->pyop_poll; + ot->ui = data->ui; + ot->ext = data->ext; operator_properties_init(ot); } @@ -112,22 +112,26 @@ return NULL; if (WM_operatortype_find(opname, TRUE) == NULL) { - PyErr_Format(PyExc_ValueError, "Macro Define: '%s' is not a valid operator id", opname); + PyErr_Format(PyExc_ValueError, + "Macro Define: '%s' is not a valid operator id", + opname); return NULL; } /* identifiers */ - srna= srna_from_self(macro, "Macro Define:"); - macroname= RNA_struct_identifier(srna); + srna = srna_from_self(macro, "Macro Define:"); + macroname = RNA_struct_identifier(srna); - ot= WM_operatortype_find(macroname, TRUE); + ot = WM_operatortype_find(macroname, TRUE); if (!ot) { - PyErr_Format(PyExc_ValueError, "Macro Define: '%s' is not a valid macro or hasn't been registered yet", macroname); + PyErr_Format(PyExc_ValueError, + "Macro Define: '%s' is not a valid macro or hasn't been registered yet", + macroname); return NULL; } - otmacro= WM_operatortype_macro_define(ot, opname); + otmacro = WM_operatortype_macro_define(ot, opname); RNA_pointer_create(NULL, &RNA_OperatorMacro, otmacro, &ptr_otmacro); diff -Nru blender-2.61/source/blender/python/intern/bpy_props.c blender-2.62/source/blender/python/intern/bpy_props.c --- blender-2.61/source/blender/python/intern/bpy_props.c 2011-12-13 19:48:28.000000000 +0000 +++ blender-2.62/source/blender/python/intern/bpy_props.c 2012-02-15 19:33:11.000000000 +0000 @@ -56,13 +56,13 @@ extern BPy_StructRNA *bpy_context_module; -static EnumPropertyItem property_flag_items[]= { +static EnumPropertyItem property_flag_items[] = { {PROP_HIDDEN, "HIDDEN", 0, "Hidden", ""}, {PROP_SKIP_SAVE, "SKIP_SAVE", 0, "Skip Save", ""}, {PROP_ANIMATABLE, "ANIMATABLE", 0, "Animateable", ""}, {0, NULL, 0, NULL, NULL}}; -static EnumPropertyItem property_flag_enum_items[]= { +static EnumPropertyItem property_flag_enum_items[] = { {PROP_HIDDEN, "HIDDEN", 0, "Hidden", ""}, {PROP_SKIP_SAVE, "SKIP_SAVE", 0, "Skip Save", ""}, {PROP_ANIMATABLE, "ANIMATABLE", 0, "Animateable", ""}, @@ -70,7 +70,7 @@ {0, NULL, 0, NULL, NULL}}; /* subtypes */ -static EnumPropertyItem property_subtype_string_items[]= { +static EnumPropertyItem property_subtype_string_items[] = { {PROP_FILEPATH, "FILE_PATH", 0, "File Path", ""}, {PROP_DIRPATH, "DIR_PATH", 0, "Directory Path", ""}, {PROP_FILENAME, "FILENAME", 0, "Filename", ""}, @@ -80,7 +80,7 @@ {PROP_NONE, "NONE", 0, "None", ""}, {0, NULL, 0, NULL, NULL}}; -static EnumPropertyItem property_subtype_number_items[]= { +static EnumPropertyItem property_subtype_number_items[] = { {PROP_UNSIGNED, "UNSIGNED", 0, "Unsigned", ""}, {PROP_PERCENTAGE, "PERCENTAGE", 0, "Percentage", ""}, {PROP_FACTOR, "FACTOR", 0, "Factor", ""}, @@ -91,7 +91,7 @@ {PROP_NONE, "NONE", 0, "None", ""}, {0, NULL, 0, NULL, NULL}}; -static EnumPropertyItem property_subtype_array_items[]= { +static EnumPropertyItem property_subtype_array_items[] = { {PROP_COLOR, "COLOR", 0, "Color", ""}, {PROP_TRANSLATION, "TRANSLATION", 0, "Translation", ""}, {PROP_DIRECTION, "DIRECTION", 0, "Direction", ""}, @@ -109,29 +109,29 @@ {0, NULL, 0, NULL, NULL}}; /* PyObject's */ -static PyObject *pymeth_BoolProperty= NULL; -static PyObject *pymeth_BoolVectorProperty= NULL; -static PyObject *pymeth_IntProperty= NULL; -static PyObject *pymeth_IntVectorProperty= NULL; -static PyObject *pymeth_FloatProperty= NULL; -static PyObject *pymeth_FloatVectorProperty= NULL; -static PyObject *pymeth_StringProperty= NULL; -static PyObject *pymeth_EnumProperty= NULL; -static PyObject *pymeth_PointerProperty= NULL; -static PyObject *pymeth_CollectionProperty= NULL; -static PyObject *pymeth_RemoveProperty= NULL; +static PyObject *pymeth_BoolProperty = NULL; +static PyObject *pymeth_BoolVectorProperty = NULL; +static PyObject *pymeth_IntProperty = NULL; +static PyObject *pymeth_IntVectorProperty = NULL; +static PyObject *pymeth_FloatProperty = NULL; +static PyObject *pymeth_FloatVectorProperty = NULL; +static PyObject *pymeth_StringProperty = NULL; +static PyObject *pymeth_EnumProperty = NULL; +static PyObject *pymeth_PointerProperty = NULL; +static PyObject *pymeth_CollectionProperty = NULL; +static PyObject *pymeth_RemoveProperty = NULL; static PyObject *pyrna_struct_as_instance(PointerRNA *ptr) { - PyObject *self= NULL; + PyObject *self = NULL; /* first get self */ /* operators can store their own instance for later use */ if (ptr->data) { - void **instance= RNA_struct_instance(ptr); + void **instance = RNA_struct_instance(ptr); if (instance) { if (*instance) { - self= *instance; + self = *instance; Py_INCREF(self); } } @@ -139,7 +139,7 @@ /* in most cases this will run */ if (self == NULL) { - self= pyrna_struct_CreatePyObject(ptr); + self = pyrna_struct_CreatePyObject(ptr); } return self; @@ -149,7 +149,7 @@ static void printf_func_error(PyObject *py_func) { /* since we return to C code we can't leave the error */ - PyCodeObject *f_code= (PyCodeObject *)PyFunction_GET_CODE(py_func); + PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(py_func); PyErr_Print(); PyErr_Clear(); @@ -166,12 +166,12 @@ * the default args for that operator instance */ static PyObject *bpy_prop_deferred_return(PyObject *func, PyObject *kw) { - PyObject *ret= PyTuple_New(2); + PyObject *ret = PyTuple_New(2); PyTuple_SET_ITEM(ret, 0, func); Py_INCREF(func); - if (kw==NULL) - kw= PyDict_New(); + if (kw == NULL) + kw = PyDict_New(); else Py_INCREF(kw); @@ -184,12 +184,12 @@ static void bpy_prop_update_cb(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop) { PyGILState_STATE gilstate; - PyObject **py_data= (PyObject **)RNA_property_py_data_get(prop); + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); PyObject *py_func; PyObject *args; PyObject *self; PyObject *ret; - const int is_write_ok= pyrna_write_check(); + const int is_write_ok = pyrna_write_check(); BLI_assert(py_data != NULL); @@ -199,16 +199,16 @@ bpy_context_set(C, &gilstate); - py_func= py_data[BPY_DATA_CB_SLOT_UPDATE]; + py_func = py_data[BPY_DATA_CB_SLOT_UPDATE]; - args= PyTuple_New(2); - self= pyrna_struct_as_instance(ptr); + args = PyTuple_New(2); + self = pyrna_struct_as_instance(ptr); PyTuple_SET_ITEM(args, 0, self); PyTuple_SET_ITEM(args, 1, (PyObject *)bpy_context_module); Py_INCREF(bpy_context_module); - ret= PyObject_CallObject(py_func, args); + ret = PyObject_CallObject(py_func, args); Py_DECREF(args); @@ -241,7 +241,7 @@ return -1; } else { - PyCodeObject *f_code= (PyCodeObject *)PyFunction_GET_CODE(py_func); + PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(py_func); if (f_code->co_argcount != argcount) { PyErr_Format(PyExc_TypeError, "update keyword: expected a function taking %d arguments, not %d", @@ -259,9 +259,9 @@ { /* assume this is already checked for type and arg length */ if (update_cb) { - PyObject **py_data= MEM_callocN(sizeof(PyObject *) * BPY_DATA_CB_SLOT_SIZE, __func__); + PyObject **py_data = MEM_callocN(sizeof(PyObject *) * BPY_DATA_CB_SLOT_SIZE, __func__); RNA_def_property_update_runtime(prop, (void *)bpy_prop_update_cb); - py_data[BPY_DATA_CB_SLOT_UPDATE]= update_cb; + py_data[BPY_DATA_CB_SLOT_UPDATE] = update_cb; RNA_def_py_data(prop, py_data); RNA_def_property_flag(prop, PROP_CONTEXT_PROPERTY_UPDATE); @@ -274,7 +274,7 @@ static int py_long_as_int(PyObject *py_long, int *r_int) { if (PyLong_CheckExact(py_long)) { - *r_int= (int)PyLong_AS_LONG(py_long); + *r_int = (int)PyLong_AS_LONG(py_long); return 0; } else { @@ -287,9 +287,9 @@ #define BPY_PROPDEF_HEAD(_func) \ if (PyTuple_GET_SIZE(args) == 1) { \ PyObject *ret; \ - self= PyTuple_GET_ITEM(args, 0); \ - args= PyTuple_New(0); \ - ret= BPy_##_func(self, args, kw); \ + self = PyTuple_GET_ITEM(args, 0); \ + args = PyTuple_New(0); \ + ret = BPy_##_func(self, args, kw); \ Py_DECREF(args); \ return ret; \ } \ @@ -297,8 +297,8 @@ PyErr_SetString(PyExc_ValueError, "all args must be keywords"); \ return NULL; \ } \ - srna= srna_from_self(self, #_func"(...):"); \ - if (srna==NULL) { \ + srna = srna_from_self(self, #_func"(...):"); \ + if (srna == NULL) { \ if (PyErr_Occurred()) \ return NULL; \ return bpy_prop_deferred_return(pymeth_##_func, kw); \ @@ -310,7 +310,7 @@ if (id_len >= MAX_IDPROP_NAME) { \ PyErr_Format(PyExc_TypeError, \ #_func"(): '%.200s' too long, max length is %d", \ - id, MAX_IDPROP_NAME-1); \ + id, MAX_IDPROP_NAME - 1); \ return NULL; \ } \ if (RNA_def_property_free_identifier(srna, id) == -1) { \ @@ -322,7 +322,7 @@ if (pyopts && pyrna_set_to_enum_bitfield(_property_flag_items, \ pyopts, \ &opts, \ - #_func"(options={...}):")) \ + #_func"(options={ ...}):")) \ { \ return NULL; \ } \ @@ -331,7 +331,7 @@ BPY_PROPDEF_CHECK(_func, _property_flag_items) \ if (pysubtype && RNA_enum_value_from_id(_subtype, \ pysubtype, \ - &subtype)==0) \ + &subtype) == 0) \ { \ PyErr_Format(PyExc_TypeError, \ #_func"(subtype='%s'): invalid subtype", \ @@ -374,7 +374,12 @@ * but being abused from C so we can pass the srna along. * This isnt incorrect since its a python object - but be careful */ PyDoc_STRVAR(BPy_BoolProperty_doc, -".. function:: BoolProperty(name=\"\", description=\"\", default=False, options={'ANIMATABLE'}, subtype='NONE', update=None)\n" +".. function:: BoolProperty(name=\"\", " + "description=\"\", " + "default=False, " + "options={'ANIMATABLE'}, " + "subtype='NONE', " + "update=None)\n" "\n" " Returns a new boolean property definition.\n" "\n" @@ -393,17 +398,17 @@ BPY_PROPDEF_HEAD(BoolProperty) if (srna) { - static const char *kwlist[]= {"attr", "name", "description", "default", + static const char *kwlist[] = {"attr", "name", "description", "default", "options", "subtype", "update", NULL}; - const char *id=NULL, *name="", *description=""; + const char *id = NULL, *name = NULL, *description = ""; int id_len; - int def=0; + int def = 0; PropertyRNA *prop; - PyObject *pyopts= NULL; - int opts=0; - char *pysubtype= NULL; - int subtype= PROP_NONE; - PyObject *update_cb= NULL; + PyObject *pyopts = NULL; + int opts = 0; + char *pysubtype = NULL; + int subtype = PROP_NONE; + PyObject *update_cb = NULL; if (!PyArg_ParseTupleAndKeywords(args, kw, "s#|ssiO!sO:BoolProperty", @@ -421,13 +426,13 @@ return NULL; } - prop= RNA_def_property(srna, id, PROP_BOOLEAN, subtype); + prop = RNA_def_property(srna, id, PROP_BOOLEAN, subtype); RNA_def_property_boolean_default(prop, def); - RNA_def_property_ui_text(prop, name, description); + RNA_def_property_ui_text(prop, name ? name : id, description); if (pyopts) { if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); - if ((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); } bpy_prop_callback_assign(prop, update_cb); @@ -438,7 +443,13 @@ } PyDoc_STRVAR(BPy_BoolVectorProperty_doc, -".. function:: BoolVectorProperty(name=\"\", description=\"\", default=(False, False, False), options={'ANIMATABLE'}, subtype='NONE', size=3, update=None)\n" +".. function:: BoolVectorProperty(name=\"\", " + "description=\"\", " + "default=(False, False, False), " + "options={'ANIMATABLE'}, " + "subtype='NONE', " + "size=3, " + "update=None)\n" "\n" " Returns a new vector boolean property definition.\n" "\n" @@ -448,7 +459,9 @@ " :type default: sequence\n" " :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE'].\n" " :type options: set\n" -" :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', 'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', 'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n" +" :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', " + "'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', " + "'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n" " :type subtype: string\n" " :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n" " :type size: int\n" @@ -461,19 +474,19 @@ BPY_PROPDEF_HEAD(BoolVectorProperty) if (srna) { - static const char *kwlist[]= {"attr", "name", "description", "default", + static const char *kwlist[] = {"attr", "name", "description", "default", "options", "subtype", "size", "update", NULL}; - const char *id=NULL, *name="", *description=""; + const char *id = NULL, *name = NULL, *description = ""; int id_len; - int def[PYRNA_STACK_ARRAY]={0}; - int size=3; + int def[PYRNA_STACK_ARRAY] = {0}; + int size = 3; PropertyRNA *prop; - PyObject *pydef= NULL; - PyObject *pyopts= NULL; - int opts=0; - char *pysubtype= NULL; - int subtype= PROP_NONE; - PyObject *update_cb= NULL; + PyObject *pydef = NULL; + PyObject *pyopts = NULL; + int opts = 0; + char *pysubtype = NULL; + int subtype = PROP_NONE; + PyObject *update_cb = NULL; if (!PyArg_ParseTupleAndKeywords(args, kw, "s#|ssOO!siO:BoolVectorProperty", @@ -501,15 +514,15 @@ return NULL; } - // prop= RNA_def_boolean_array(srna, id, size, pydef ? def:NULL, name, description); - prop= RNA_def_property(srna, id, PROP_BOOLEAN, subtype); + // prop = RNA_def_boolean_array(srna, id, size, pydef ? def:NULL, name ? name : id, description); + prop = RNA_def_property(srna, id, PROP_BOOLEAN, subtype); RNA_def_property_array(prop, size); if (pydef) RNA_def_property_boolean_array_default(prop, def); - RNA_def_property_ui_text(prop, name, description); + RNA_def_property_ui_text(prop, name ? name : id, description); if (pyopts) { if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); - if ((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); } bpy_prop_callback_assign(prop, update_cb); @@ -520,7 +533,15 @@ } PyDoc_STRVAR(BPy_IntProperty_doc, -".. function:: IntProperty(name=\"\", description=\"\", default=0, min=-sys.maxint, max=sys.maxint, soft_min=-sys.maxint, soft_max=sys.maxint, step=1, options={'ANIMATABLE'}, subtype='NONE', update=None)\n" +".. function:: IntProperty(name=\"\", " + "description=\"\", " + "default=0, " + "min=-sys.maxint, max=sys.maxint, " + "soft_min=-sys.maxint, soft_max=sys.maxint, " + "step=1, " + "options={'ANIMATABLE'}, " + "subtype='NONE', " + "update=None)\n" "\n" " Returns a new int property definition.\n" "\n" @@ -539,17 +560,18 @@ BPY_PROPDEF_HEAD(IntProperty) if (srna) { - static const char *kwlist[]= {"attr", "name", "description", "default", - "min", "max", "soft_min", "soft_max", "step", "options", "subtype", "update", NULL}; - const char *id=NULL, *name="", *description=""; + static const char *kwlist[] = {"attr", "name", "description", "default", + "min", "max", "soft_min", "soft_max", + "step", "options", "subtype", "update", NULL}; + const char *id = NULL, *name = NULL, *description = ""; int id_len; - int min=INT_MIN, max=INT_MAX, soft_min=INT_MIN, soft_max=INT_MAX, step=1, def=0; + int min = INT_MIN, max = INT_MAX, soft_min = INT_MIN, soft_max = INT_MAX, step = 1, def = 0; PropertyRNA *prop; - PyObject *pyopts= NULL; - int opts=0; - char *pysubtype= NULL; - int subtype= PROP_NONE; - PyObject *update_cb= NULL; + PyObject *pyopts = NULL; + int opts = 0; + char *pysubtype = NULL; + int subtype = PROP_NONE; + PyObject *update_cb = NULL; if (!PyArg_ParseTupleAndKeywords(args, kw, "s#|ssiiiiiiO!sO:IntProperty", @@ -568,15 +590,15 @@ return NULL; } - prop= RNA_def_property(srna, id, PROP_INT, subtype); + prop = RNA_def_property(srna, id, PROP_INT, subtype); RNA_def_property_int_default(prop, def); + RNA_def_property_ui_text(prop, name ? name : id, description); RNA_def_property_range(prop, min, max); - RNA_def_property_ui_text(prop, name, description); RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, 3); if (pyopts) { if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); - if ((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); } bpy_prop_callback_assign(prop, update_cb); @@ -586,7 +608,15 @@ } PyDoc_STRVAR(BPy_IntVectorProperty_doc, -".. function:: IntVectorProperty(name=\"\", description=\"\", default=(0, 0, 0), min=-sys.maxint, max=sys.maxint, soft_min=-sys.maxint, soft_max=sys.maxint, options={'ANIMATABLE'}, subtype='NONE', size=3, update=None)\n" +".. function:: IntVectorProperty(name=\"\", " + "description=\"\", " + "default=(0, 0, 0), min=-sys.maxint, max=sys.maxint, " + "soft_min=-sys.maxint, " + "soft_max=sys.maxint, " + "options={'ANIMATABLE'}, " + "subtype='NONE', " + "size=3, " + "update=None)\n" "\n" " Returns a new vector int property definition.\n" "\n" @@ -596,7 +626,9 @@ " :type default: sequence\n" " :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE'].\n" " :type options: set\n" -" :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', 'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', 'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n" +" :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', " + "'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', " + "'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n" " :type subtype: string\n" " :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n" " :type size: int\n" @@ -609,20 +641,21 @@ BPY_PROPDEF_HEAD(IntVectorProperty) if (srna) { - static const char *kwlist[]= {"attr", "name", "description", "default", + static const char *kwlist[] = {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "options", "subtype", "size", "update", NULL}; - const char *id=NULL, *name="", *description=""; + const char *id = NULL, *name = NULL, *description = ""; int id_len; - int min=INT_MIN, max=INT_MAX, soft_min=INT_MIN, soft_max=INT_MAX, step=1, def[PYRNA_STACK_ARRAY]={0}; - int size=3; + int min = INT_MIN, max = INT_MAX, soft_min = INT_MIN, soft_max = INT_MAX, step = 1; + int def[PYRNA_STACK_ARRAY] = {0}; + int size = 3; PropertyRNA *prop; - PyObject *pydef= NULL; - PyObject *pyopts= NULL; - int opts=0; - char *pysubtype= NULL; - int subtype= PROP_NONE; - PyObject *update_cb= NULL; + PyObject *pydef = NULL; + PyObject *pyopts = NULL; + int opts = 0; + char *pysubtype = NULL; + int subtype = PROP_NONE; + PyObject *update_cb = NULL; if (!PyArg_ParseTupleAndKeywords(args, kw, "s#|ssOiiiiiO!siO:IntVectorProperty", @@ -652,16 +685,16 @@ return NULL; } - prop= RNA_def_property(srna, id, PROP_INT, subtype); + prop = RNA_def_property(srna, id, PROP_INT, subtype); RNA_def_property_array(prop, size); if (pydef) RNA_def_property_int_array_default(prop, def); RNA_def_property_range(prop, min, max); - RNA_def_property_ui_text(prop, name, description); + RNA_def_property_ui_text(prop, name ? name : id, description); RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, 3); if (pyopts) { if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); - if ((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); } bpy_prop_callback_assign(prop, update_cb); @@ -672,7 +705,17 @@ PyDoc_STRVAR(BPy_FloatProperty_doc, -".. function:: FloatProperty(name=\"\", description=\"\", default=0.0, min=sys.float_info.min, max=sys.float_info.max, soft_min=sys.float_info.min, soft_max=sys.float_info.max, step=3, precision=2, options={'ANIMATABLE'}, subtype='NONE', unit='NONE', update=None)\n" +".. function:: FloatProperty(name=\"\", " + "description=\"\", " + "default=0.0, " + "min=sys.float_info.min, max=sys.float_info.max, " + "soft_min=sys.float_info.min, soft_max=sys.float_info.max, " + "step=3, " + "precision=2, " + "options={'ANIMATABLE'}, " + "subtype='NONE', " + "unit='NONE', " + "update=None)\n" "\n" " Returns a new float property definition.\n" "\n" @@ -692,21 +735,21 @@ BPY_PROPDEF_HEAD(FloatProperty) if (srna) { - static const char *kwlist[]= {"attr", "name", "description", "default", + static const char *kwlist[] = {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "precision", "options", "subtype", "unit", "update", NULL}; - const char *id=NULL, *name="", *description=""; + const char *id = NULL, *name = NULL, *description = ""; int id_len; - float min=-FLT_MAX, max=FLT_MAX, soft_min=-FLT_MAX, soft_max=FLT_MAX, step=3, def=0.0f; - int precision= 2; + float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX, step = 3, def = 0.0f; + int precision = 2; PropertyRNA *prop; - PyObject *pyopts= NULL; - int opts=0; - char *pysubtype= NULL; - int subtype= PROP_NONE; - char *pyunit= NULL; - int unit= PROP_UNIT_NONE; - PyObject *update_cb= NULL; + PyObject *pyopts = NULL; + int opts = 0; + char *pysubtype = NULL; + int subtype = PROP_NONE; + char *pyunit = NULL; + int unit = PROP_UNIT_NONE; + PyObject *update_cb = NULL; if (!PyArg_ParseTupleAndKeywords(args, kw, "s#|ssffffffiO!ssO:FloatProperty", @@ -722,7 +765,7 @@ BPY_PROPDEF_SUBTYPE_CHECK(FloatProperty, property_flag_items, property_subtype_number_items) - if (pyunit && RNA_enum_value_from_id(property_unit_items, pyunit, &unit)==0) { + if (pyunit && RNA_enum_value_from_id(property_unit_items, pyunit, &unit) == 0) { PyErr_Format(PyExc_TypeError, "FloatProperty(unit='%s'): invalid unit", pyunit); return NULL; } @@ -731,15 +774,15 @@ return NULL; } - prop= RNA_def_property(srna, id, PROP_FLOAT, subtype | unit); + prop = RNA_def_property(srna, id, PROP_FLOAT, subtype | unit); RNA_def_property_float_default(prop, def); RNA_def_property_range(prop, min, max); - RNA_def_property_ui_text(prop, name, description); + RNA_def_property_ui_text(prop, name ? name : id, description); RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, precision); if (pyopts) { if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); - if ((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); } bpy_prop_callback_assign(prop, update_cb); @@ -749,7 +792,17 @@ } PyDoc_STRVAR(BPy_FloatVectorProperty_doc, -".. function:: FloatVectorProperty(name=\"\", description=\"\", default=(0.0, 0.0, 0.0), min=sys.float_info.min, max=sys.float_info.max, soft_min=sys.float_info.min, soft_max=sys.float_info.max, step=3, precision=2, options={'ANIMATABLE'}, subtype='NONE', size=3, update=None)\n" +".. function:: FloatVectorProperty(name=\"\", " + "description=\"\", " + "default=(0.0, 0.0, 0.0), " + "min=sys.float_info.min, max=sys.float_info.max, " + "soft_min=sys.float_info.min, soft_max=sys.float_info.max, " + "step=3, " + "precision=2, " + "options={'ANIMATABLE'}, " + "subtype='NONE', " + "size=3, " + "update=None)\n" "\n" " Returns a new vector float property definition.\n" "\n" @@ -759,7 +812,9 @@ " :type default: sequence\n" " :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE'].\n" " :type options: set\n" -" :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', 'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', 'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n" +" :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', " + "'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', 'XYZ', " + "'COLOR_GAMMA', 'LAYER', 'NONE'].\n" " :type subtype: string\n" BPY_PROPDEF_UNIT_DOC " :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n" @@ -773,22 +828,23 @@ BPY_PROPDEF_HEAD(FloatVectorProperty) if (srna) { - static const char *kwlist[]= {"attr", "name", "description", "default", + static const char *kwlist[] = {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "precision", "options", "subtype", "unit", "size", "update", NULL}; - const char *id=NULL, *name="", *description=""; + const char *id = NULL, *name = NULL, *description = ""; int id_len; - float min=-FLT_MAX, max=FLT_MAX, soft_min=-FLT_MAX, soft_max=FLT_MAX, step=3, def[PYRNA_STACK_ARRAY]={0.0f}; - int precision= 2, size=3; + float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX, step = 3; + float def[PYRNA_STACK_ARRAY] = {0.0f}; + int precision = 2, size = 3; PropertyRNA *prop; - PyObject *pydef= NULL; - PyObject *pyopts= NULL; - int opts=0; - char *pysubtype= NULL; - int subtype= PROP_NONE; - char *pyunit= NULL; - int unit= PROP_UNIT_NONE; - PyObject *update_cb= NULL; + PyObject *pydef = NULL; + PyObject *pyopts = NULL; + int opts = 0; + char *pysubtype = NULL; + int subtype = PROP_NONE; + char *pyunit = NULL; + int unit = PROP_UNIT_NONE; + PyObject *update_cb = NULL; if (!PyArg_ParseTupleAndKeywords(args, kw, "s#|ssOfffffiO!ssiO:FloatVectorProperty", @@ -804,7 +860,7 @@ BPY_PROPDEF_SUBTYPE_CHECK(FloatVectorProperty, property_flag_items, property_subtype_array_items) - if (pyunit && RNA_enum_value_from_id(property_unit_items, pyunit, &unit)==0) { + if (pyunit && RNA_enum_value_from_id(property_unit_items, pyunit, &unit) == 0) { PyErr_Format(PyExc_TypeError, "FloatVectorProperty(unit='%s'): invalid unit", pyunit); return NULL; } @@ -823,16 +879,16 @@ return NULL; } - prop= RNA_def_property(srna, id, PROP_FLOAT, subtype | unit); + prop = RNA_def_property(srna, id, PROP_FLOAT, subtype | unit); RNA_def_property_array(prop, size); if (pydef) RNA_def_property_float_array_default(prop, def); RNA_def_property_range(prop, min, max); - RNA_def_property_ui_text(prop, name, description); + RNA_def_property_ui_text(prop, name ? name : id, description); RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, precision); if (pyopts) { if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); - if ((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); } bpy_prop_callback_assign(prop, update_cb); @@ -842,7 +898,13 @@ } PyDoc_STRVAR(BPy_StringProperty_doc, -".. function:: StringProperty(name=\"\", description=\"\", default=\"\", maxlen=0, options={'ANIMATABLE'}, subtype='NONE', update=None)\n" +".. function:: StringProperty(name=\"\", " + "description=\"\", " + "default=\"\", " + "maxlen=0, " + "options={'ANIMATABLE'}, " + "subtype='NONE', " + "update=None)\n" "\n" " Returns a new string property definition.\n" "\n" @@ -861,17 +923,17 @@ BPY_PROPDEF_HEAD(StringProperty) if (srna) { - static const char *kwlist[]= {"attr", "name", "description", "default", + static const char *kwlist[] = {"attr", "name", "description", "default", "maxlen", "options", "subtype", "update", NULL}; - const char *id=NULL, *name="", *description="", *def=""; + const char *id = NULL, *name = NULL, *description = "", *def = ""; int id_len; - int maxlen=0; + int maxlen = 0; PropertyRNA *prop; - PyObject *pyopts= NULL; - int opts=0; - char *pysubtype= NULL; - int subtype= PROP_NONE; - PyObject *update_cb= NULL; + PyObject *pyopts = NULL; + int opts = 0; + char *pysubtype = NULL; + int subtype = PROP_NONE; + PyObject *update_cb = NULL; if (!PyArg_ParseTupleAndKeywords(args, kw, "s#|sssiO!sO:StringProperty", @@ -889,14 +951,14 @@ return NULL; } - prop= RNA_def_property(srna, id, PROP_STRING, subtype); + prop = RNA_def_property(srna, id, PROP_STRING, subtype); if (maxlen != 0) RNA_def_property_string_maxlength(prop, maxlen + 1); /* +1 since it includes null terminator */ if (def) RNA_def_property_string_default(prop, def); - RNA_def_property_ui_text(prop, name, description); + RNA_def_property_ui_text(prop, name ? name : id, description); if (pyopts) { if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); - if ((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); } bpy_prop_callback_assign(prop, update_cb); @@ -909,11 +971,11 @@ /* copies orig to buf, then sets orig to buf, returns copy length */ static size_t strswapbufcpy(char *buf, const char **orig) { - const char *src= *orig; - char *dst= buf; - size_t i= 0; - *orig= buf; - while ((*dst= *src)) { dst++; src++; i++; } + const char *src = *orig; + char *dst = buf; + size_t i = 0; + *orig = buf; + while ((*dst = *src)) { dst++; src++; i++; } return i + 1; /* include '\0' */ } #endif @@ -922,11 +984,11 @@ { EnumPropertyItem *items; PyObject *item; - const Py_ssize_t seq_len= PySequence_Fast_GET_SIZE(seq_fast); - Py_ssize_t totbuf= 0; + const Py_ssize_t seq_len = PySequence_Fast_GET_SIZE(seq_fast); + Py_ssize_t totbuf = 0; int i; - short def_used= 0; - const char *def_cmp= NULL; + short def_used = 0; + const char *def_cmp = NULL; if (is_enum_flag) { if (seq_len > RNA_ENUM_BITFLAG_SIZE) { @@ -946,8 +1008,8 @@ } else { if (def) { - def_cmp= _PyUnicode_AsString(def); - if (def_cmp==NULL) { + def_cmp = _PyUnicode_AsString(def); + if (def_cmp == NULL) { PyErr_Format(PyExc_TypeError, "EnumProperty(...): default option must be a 'str' " "type when ENUM_FLAG is disabled, not a '%.200s'", @@ -958,30 +1020,31 @@ } /* blank value */ - *defvalue= 0; + *defvalue = 0; - items= MEM_callocN(sizeof(EnumPropertyItem) * (seq_len + 1), "enum_items_from_py1"); + items = MEM_callocN(sizeof(EnumPropertyItem) * (seq_len + 1), "enum_items_from_py1"); - for (i=0; iidentifier); buf += strswapbufcpy(buf, &items_ptr->name); buf += strswapbufcpy(buf, &items_ptr->description); } MEM_freeN(items); - items=items_dup; + items = items_dup; } /* end string duplication */ #endif @@ -1069,47 +1132,48 @@ { PyGILState_STATE gilstate; - PyObject *py_func= RNA_property_enum_py_data_get(prop); - PyObject *self= NULL; + PyObject *py_func = RNA_property_enum_py_data_get(prop); + PyObject *self = NULL; PyObject *args; PyObject *items; /* returned from the function call */ - EnumPropertyItem *eitems= NULL; - int err= 0; + EnumPropertyItem *eitems = NULL; + int err = 0; bpy_context_set(C, &gilstate); - args= PyTuple_New(2); - self= pyrna_struct_as_instance(ptr); + args = PyTuple_New(2); + self = pyrna_struct_as_instance(ptr); PyTuple_SET_ITEM(args, 0, self); /* now get the context */ PyTuple_SET_ITEM(args, 1, (PyObject *)bpy_context_module); Py_INCREF(bpy_context_module); - items= PyObject_CallObject(py_func, args); + items = PyObject_CallObject(py_func, args); Py_DECREF(args); - if (items==NULL) { - err= -1; + if (items == NULL) { + err = -1; } else { PyObject *items_fast; - int defvalue_dummy=0; + int defvalue_dummy = 0; - if (!(items_fast= PySequence_Fast(items, "EnumProperty(...): " + if (!(items_fast = PySequence_Fast(items, "EnumProperty(...): " "return value from the callback was not a sequence"))) { - err= -1; + err = -1; } else { - eitems= enum_items_from_py(items_fast, NULL, &defvalue_dummy, (RNA_property_flag(prop) & PROP_ENUM_FLAG)!=0); + eitems = enum_items_from_py(items_fast, NULL, &defvalue_dummy, + (RNA_property_flag(prop) & PROP_ENUM_FLAG) != 0); Py_DECREF(items_fast); if (!eitems) { - err= -1; + err = -1; } } @@ -1117,12 +1181,12 @@ } if (err != -1) { /* worked */ - *free= 1; + *free = 1; } else { printf_func_error(py_func); - eitems= DummyRNA_NULL_items; + eitems = DummyRNA_NULL_items; } @@ -1131,7 +1195,12 @@ } PyDoc_STRVAR(BPy_EnumProperty_doc, -".. function:: EnumProperty(items, name=\"\", description=\"\", default=\"\", options={'ANIMATABLE'}, update=None)\n" +".. function:: EnumProperty(items, " + "name=\"\", " + "description=\"\", " + "default=\"\", " + "options={'ANIMATABLE'}, " + "update=None)\n" "\n" " Returns a new enumerator property definition.\n" "\n" @@ -1160,19 +1229,19 @@ BPY_PROPDEF_HEAD(EnumProperty) if (srna) { - static const char *kwlist[]= {"attr", "items", "name", "description", "default", + static const char *kwlist[] = {"attr", "items", "name", "description", "default", "options", "update", NULL}; - const char *id=NULL, *name="", *description=""; - PyObject *def= NULL; + const char *id = NULL, *name = NULL, *description = ""; + PyObject *def = NULL; int id_len; - int defvalue=0; + int defvalue = 0; PyObject *items, *items_fast; EnumPropertyItem *eitems; PropertyRNA *prop; - PyObject *pyopts= NULL; - int opts=0; - short is_itemf= FALSE; - PyObject *update_cb= NULL; + PyObject *pyopts = NULL; + int opts = 0; + short is_itemf = FALSE; + PyObject *update_cb = NULL; if (!PyArg_ParseTupleAndKeywords(args, kw, "s#O|ssOO!O:EnumProperty", @@ -1192,7 +1261,7 @@ /* items can be a list or a callable */ if (PyFunction_Check(items)) { /* dont use PyCallable_Check because we need the function code for errors */ - PyCodeObject *f_code= (PyCodeObject *)PyFunction_GET_CODE(items); + PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(items); if (f_code->co_argcount != 2) { PyErr_Format(PyExc_ValueError, "EnumProperty(...): expected 'items' function to take 2 arguments, not %d", @@ -1207,17 +1276,18 @@ return NULL; } - is_itemf= TRUE; - eitems= DummyRNA_NULL_items; + is_itemf = TRUE; + eitems = DummyRNA_NULL_items; } else { - if (!(items_fast= PySequence_Fast(items, "EnumProperty(...): " + if (!(items_fast = PySequence_Fast(items, "EnumProperty(...): " "expected a sequence of tuples for the enum items or a function"))) { return NULL; } - eitems= enum_items_from_py(items_fast, def, &defvalue, (opts & PROP_ENUM_FLAG)!=0); + eitems = enum_items_from_py(items_fast, def, &defvalue, + (opts & PROP_ENUM_FLAG) != 0); Py_DECREF(items_fast); @@ -1226,8 +1296,8 @@ } } - if (opts & PROP_ENUM_FLAG) prop= RNA_def_enum_flag(srna, id, eitems, defvalue, name, description); - else prop= RNA_def_enum(srna, id, eitems, defvalue, name, description); + if (opts & PROP_ENUM_FLAG) prop = RNA_def_enum_flag(srna, id, eitems, defvalue, name ? name : id, description); + else prop = RNA_def_enum(srna, id, eitems, defvalue, name ? name : id, description); if (is_itemf) { RNA_def_enum_funcs(prop, bpy_props_enum_itemf); @@ -1240,7 +1310,7 @@ if (pyopts) { if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); - if ((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); } bpy_prop_callback_assign(prop, update_cb); @@ -1257,11 +1327,11 @@ { StructRNA *srna; - srna= srna_from_self(value, ""); + srna = srna_from_self(value, ""); if (!srna) { if (PyErr_Occurred()) { - PyObject *msg= PyC_ExceptionBuffer(); - const char *msg_char= _PyUnicode_AsString(msg); + PyObject *msg = PyC_ExceptionBuffer(); + const char *msg_char = _PyUnicode_AsString(msg); PyErr_Format(PyExc_TypeError, "%.200s expected an RNA type derived from PropertyGroup, failed with: %s", error_prefix, msg_char); @@ -1286,7 +1356,10 @@ } PyDoc_STRVAR(BPy_PointerProperty_doc, -".. function:: PointerProperty(type=\"\", description=\"\", options={'ANIMATABLE'}, update=None)\n" +".. function:: PointerProperty(type=\"\", " + "description=\"\", " + "options={'ANIMATABLE'}, " + "update=None)\n" "\n" " Returns a new pointer property definition.\n" "\n" @@ -1305,15 +1378,15 @@ BPY_PROPDEF_HEAD(PointerProperty) if (srna) { - static const char *kwlist[]= {"attr", "type", "name", "description", "options", "update", NULL}; - const char *id=NULL, *name="", *description=""; + static const char *kwlist[] = {"attr", "type", "name", "description", "options", "update", NULL}; + const char *id = NULL, *name = NULL, *description = ""; int id_len; PropertyRNA *prop; StructRNA *ptype; - PyObject *type= Py_None; - PyObject *pyopts= NULL; - int opts=0; - PyObject *update_cb= NULL; + PyObject *type = Py_None; + PyObject *pyopts = NULL; + int opts = 0; + PyObject *update_cb = NULL; if (!PyArg_ParseTupleAndKeywords(args, kw, "s#O|ssO!O:PointerProperty", @@ -1327,7 +1400,7 @@ BPY_PROPDEF_CHECK(PointerProperty, property_flag_items) - ptype= pointer_type_from_py(type, "PointerProperty(...):"); + ptype = pointer_type_from_py(type, "PointerProperty(...):"); if (!ptype) return NULL; @@ -1335,10 +1408,10 @@ return NULL; } - prop= RNA_def_pointer_runtime(srna, id, ptype, name, description); + prop = RNA_def_pointer_runtime(srna, id, ptype, name ? name : id, description); if (pyopts) { if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); - if ((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); } bpy_prop_callback_assign(prop, update_cb); @@ -1348,7 +1421,10 @@ } PyDoc_STRVAR(BPy_CollectionProperty_doc, -".. function:: CollectionProperty(items, type=\"\", description=\"\", default=\"\", options={'ANIMATABLE'})\n" +".. function:: CollectionProperty(items, " + "type=\"\", " + "description=\"\", " + "options={'ANIMATABLE'})\n" "\n" " Returns a new collection property definition.\n" "\n" @@ -1366,14 +1442,14 @@ BPY_PROPDEF_HEAD(CollectionProperty) if (srna) { - static const char *kwlist[]= {"attr", "type", "name", "description", "options", NULL}; - const char *id=NULL, *name="", *description=""; + static const char *kwlist[] = {"attr", "type", "name", "description", "options", NULL}; + const char *id = NULL, *name = NULL, *description = ""; int id_len; PropertyRNA *prop; StructRNA *ptype; - PyObject *type= Py_None; - PyObject *pyopts= NULL; - int opts=0; + PyObject *type = Py_None; + PyObject *pyopts = NULL; + int opts = 0; if (!PyArg_ParseTupleAndKeywords(args, kw, "s#O|ssO!:CollectionProperty", @@ -1386,14 +1462,14 @@ BPY_PROPDEF_CHECK(CollectionProperty, property_flag_items) - ptype= pointer_type_from_py(type, "CollectionProperty(...):"); + ptype = pointer_type_from_py(type, "CollectionProperty(...):"); if (!ptype) return NULL; - prop= RNA_def_collection_runtime(srna, id, ptype, name, description); + prop = RNA_def_collection_runtime(srna, id, ptype, name ? name : id, description); if (pyopts) { if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); - if ((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); } RNA_def_property_duplicate_pointers(srna, prop); @@ -1415,29 +1491,29 @@ if (PyTuple_GET_SIZE(args) == 1) { PyObject *ret; - self= PyTuple_GET_ITEM(args, 0); - args= PyTuple_New(0); - ret= BPy_RemoveProperty(self, args, kw); + self = PyTuple_GET_ITEM(args, 0); + args = PyTuple_New(0); + ret = BPy_RemoveProperty(self, args, kw); Py_DECREF(args); return ret; } else if (PyTuple_GET_SIZE(args) > 1) { - PyErr_SetString(PyExc_ValueError, "all args must be keywords"); \ + PyErr_SetString(PyExc_ValueError, "all args must be keywords"); return NULL; } - srna= srna_from_self(self, "RemoveProperty(...):"); - if (srna==NULL && PyErr_Occurred()) { + srna = srna_from_self(self, "RemoveProperty(...):"); + if (srna == NULL && PyErr_Occurred()) { return NULL; /* self's type was compatible but error getting the srna */ } - else if (srna==NULL) { + else if (srna == NULL) { PyErr_SetString(PyExc_TypeError, "RemoveProperty(): struct rna not available for this type"); return NULL; } else { - static const char *kwlist[]= {"attr", NULL}; + static const char *kwlist[] = {"attr", NULL}; - char *id=NULL; + char *id = NULL; if (!PyArg_ParseTupleAndKeywords(args, kw, "s:RemoveProperty", @@ -1454,7 +1530,7 @@ Py_RETURN_NONE; } -static struct PyMethodDef props_methods[]= { +static struct PyMethodDef props_methods[] = { {"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS, BPy_BoolProperty_doc}, {"BoolVectorProperty", (PyCFunction)BPy_BoolVectorProperty, METH_VARARGS|METH_KEYWORDS, BPy_BoolVectorProperty_doc}, {"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, BPy_IntProperty_doc}, @@ -1470,7 +1546,7 @@ {NULL, NULL, 0, NULL} }; -static struct PyModuleDef props_module= { +static struct PyModuleDef props_module = { PyModuleDef_HEAD_INIT, "bpy.props", "This module defines properties to extend blenders internal data, the result of these functions" @@ -1485,7 +1561,7 @@ PyObject *submodule; PyObject *submodule_dict; - submodule= PyModule_Create(&props_module); + submodule = PyModule_Create(&props_module); PyDict_SetItemString(PyImport_GetModuleDict(), props_module.m_name, submodule); /* INCREF since its its assumed that all these functions return the @@ -1494,9 +1570,9 @@ Py_INCREF(submodule); /* api needs the PyObjects internally */ - submodule_dict= PyModule_GetDict(submodule); + submodule_dict = PyModule_GetDict(submodule); -#define ASSIGN_STATIC(_name) pymeth_##_name= PyDict_GetItemString(submodule_dict, #_name) +#define ASSIGN_STATIC(_name) pymeth_##_name = PyDict_GetItemString(submodule_dict, #_name) ASSIGN_STATIC(BoolProperty); ASSIGN_STATIC(BoolVectorProperty); diff -Nru blender-2.61/source/blender/python/intern/bpy_rna_anim.c blender-2.62/source/blender/python/intern/bpy_rna_anim.c --- blender-2.61/source/blender/python/intern/bpy_rna_anim.c 2011-12-13 19:48:28.000000000 +0000 +++ blender-2.62/source/blender/python/intern/bpy_rna_anim.c 2012-02-15 19:33:11.000000000 +0000 @@ -59,11 +59,11 @@ PointerRNA *ptr, const char *error_prefix, const char *path, const char **path_full, int *index) { - const int is_idbase= RNA_struct_is_ID(ptr->type); + const int is_idbase = RNA_struct_is_ID(ptr->type); PropertyRNA *prop; PointerRNA r_ptr; - if (ptr->data==NULL) { + if (ptr->data == NULL) { PyErr_Format(PyExc_TypeError, "%.200s this struct has no data, can't be animated", error_prefix); @@ -72,9 +72,9 @@ /* full paths can only be given from ID base */ if (is_idbase) { - int r_index= -1; - if (RNA_path_resolve_full(ptr, path, &r_ptr, &prop, &r_index)==0) { - prop= NULL; + int r_index = -1; + if (RNA_path_resolve_full(ptr, path, &r_ptr, &prop, &r_index) == 0) { + prop = NULL; } else if (r_index != -1) { PyErr_Format(PyExc_ValueError, @@ -90,11 +90,11 @@ } } else { - prop= RNA_struct_find_property(ptr, path); - r_ptr= *ptr; + prop = RNA_struct_find_property(ptr, path); + r_ptr = *ptr; } - if (prop==NULL) { + if (prop == NULL) { PyErr_Format(PyExc_TypeError, "%.200s property \"%s\" not found", error_prefix, path); @@ -110,7 +110,7 @@ if (RNA_property_array_check(prop) == 0) { if ((*index) == -1) { - *index= 0; + *index = 0; } else { PyErr_Format(PyExc_TypeError, @@ -120,7 +120,7 @@ } } else { - int array_len= RNA_property_array_length(&r_ptr, prop); + int array_len = RNA_property_array_length(&r_ptr, prop); if ((*index) < -1 || (*index) >= array_len) { PyErr_Format(PyExc_TypeError, "%.200s index out of range \"%s\", given %d, array length is %d", @@ -130,12 +130,12 @@ } if (is_idbase) { - *path_full= BLI_strdup(path); + *path_full = BLI_strdup(path); } else { - *path_full= RNA_path_from_ID_to_property(&r_ptr, prop); + *path_full = RNA_path_from_ID_to_property(&r_ptr, prop); - if (*path_full==NULL) { + if (*path_full == NULL) { PyErr_Format(PyExc_TypeError, "%.200s could not make path to \"%s\"", error_prefix, path); @@ -148,10 +148,10 @@ /* internal use for insert and delete */ static int pyrna_struct_keyframe_parse( - PointerRNA *ptr, PyObject *args, PyObject *kw, const char *parse_str, const char *error_prefix, - const char **path_full, int *index, float *cfra, const char **group_name) /* return values */ + PointerRNA *ptr, PyObject *args, PyObject *kw, const char *parse_str, const char *error_prefix, + const char **path_full, int *index, float *cfra, const char **group_name) /* return values */ { - static const char *kwlist[]= {"data_path", "index", "frame", "group", NULL}; + static const char *kwlist[] = {"data_path", "index", "frame", "group", NULL}; const char *path; /* note, parse_str MUST start with 's|ifs' */ @@ -161,8 +161,8 @@ if (pyrna_struct_anim_args_parse(ptr, error_prefix, path, path_full, index) < 0) return -1; - if (*cfra==FLT_MAX) - *cfra= CTX_data_scene(BPy_GetContext())->r.cfra; + if (*cfra == FLT_MAX) + *cfra = CTX_data_scene(BPy_GetContext())->r.cfra; return 0; /* success */ } @@ -186,10 +186,10 @@ PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyObject *kw) { /* args, pyrna_struct_keyframe_parse handles these */ - const char *path_full= NULL; - int index= -1; - float cfra= FLT_MAX; - const char *group_name= NULL; + const char *path_full = NULL; + int index = -1; + float cfra = FLT_MAX; + const char *group_name = NULL; PYRNA_STRUCT_CHECK_OBJ(self); @@ -205,7 +205,7 @@ BKE_reports_init(&reports, RPT_STORE); - result= insert_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0); + result = insert_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0); MEM_freeN((void *)path_full); if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1) @@ -234,10 +234,10 @@ PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyObject *kw) { /* args, pyrna_struct_keyframe_parse handles these */ - const char *path_full= NULL; - int index= -1; - float cfra= FLT_MAX; - const char *group_name= NULL; + const char *path_full = NULL; + int index = -1; + float cfra = FLT_MAX; + const char *group_name = NULL; PYRNA_STRUCT_CHECK_OBJ(self); @@ -254,7 +254,7 @@ BKE_reports_init(&reports, RPT_STORE); - result= delete_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0); + result = delete_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0); MEM_freeN((void *)path_full); if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1) @@ -280,7 +280,7 @@ PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args) { const char *path, *path_full; - int index= -1; + int index = -1; PYRNA_STRUCT_CHECK_OBJ(self); @@ -291,39 +291,39 @@ return NULL; } else { - PyObject *ret= NULL; + PyObject *ret = NULL; ReportList reports; int result; BKE_reports_init(&reports, RPT_STORE); - result= ANIM_add_driver(&reports, (ID *)self->ptr.id.data, path_full, index, 0, DRIVER_TYPE_PYTHON); + result = ANIM_add_driver(&reports, (ID *)self->ptr.id.data, path_full, index, 0, DRIVER_TYPE_PYTHON); if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1) return NULL; if (result) { - ID *id= self->ptr.id.data; - AnimData *adt= BKE_animdata_from_id(id); + ID *id = self->ptr.id.data; + AnimData *adt = BKE_animdata_from_id(id); FCurve *fcu; PointerRNA tptr; PyObject *item; if (index == -1) { /* all, use a list */ - int i= 0; - ret= PyList_New(0); - while ((fcu= list_find_fcurve(&adt->drivers, path_full, i++))) { + int i = 0; + ret = PyList_New(0); + while ((fcu = list_find_fcurve(&adt->drivers, path_full, i++))) { RNA_pointer_create(id, &RNA_FCurve, fcu, &tptr); - item= pyrna_struct_CreatePyObject(&tptr); + item = pyrna_struct_CreatePyObject(&tptr); PyList_Append(ret, item); Py_DECREF(item); } } else { - fcu= list_find_fcurve(&adt->drivers, path_full, index); + fcu = list_find_fcurve(&adt->drivers, path_full, index); RNA_pointer_create(id, &RNA_FCurve, fcu, &tptr); - ret= pyrna_struct_CreatePyObject(&tptr); + ret = pyrna_struct_CreatePyObject(&tptr); } WM_event_add_notifier(BPy_GetContext(), NC_ANIMATION|ND_FCURVES_ORDER, NULL); @@ -356,7 +356,7 @@ PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args) { const char *path, *path_full; - int index= -1; + int index = -1; PYRNA_STRUCT_CHECK_OBJ(self); @@ -372,7 +372,7 @@ BKE_reports_init(&reports, RPT_STORE); - result= ANIM_remove_driver(&reports, (ID *)self->ptr.id.data, path_full, index, 0); + result = ANIM_remove_driver(&reports, (ID *)self->ptr.id.data, path_full, index, 0); MEM_freeN((void *)path_full); diff -Nru blender-2.61/source/blender/python/intern/bpy_rna_array.c blender-2.62/source/blender/python/intern/bpy_rna_array.c --- blender-2.61/source/blender/python/intern/bpy_rna_array.c 2011-12-13 19:48:28.000000000 +0000 +++ blender-2.62/source/blender/python/intern/bpy_rna_array.c 2012-02-15 19:33:11.000000000 +0000 @@ -36,6 +36,12 @@ #include "RNA_access.h" +#define USE_MATHUTILS + +#ifdef USE_MATHUTILS +# include "../mathutils/mathutils.h" /* so we can have mathutils callbacks */ +#endif + #define MAX_ARRAY_DIMENSION 10 typedef void (*ItemConvertFunc)(PyObject *, char *); @@ -49,14 +55,14 @@ */ /* - arr[2]= x + arr[2] = x py_to_array_index(arraydim=0, arrayoffset=0, index=2) validate_array(lvalue_dim=0) ... make real index ... */ -/* arr[3]=x, self->arraydim is 0, lvalue_dim is 1 */ +/* arr[3] = x, self->arraydim is 0, lvalue_dim is 1 */ /* Ensures that a python sequence has expected number of items/sub-items and items are of desired type. */ static int validate_array_type(PyObject *seq, int dim, int totdim, int dimsize[], ItemTypeCheckFunc check_item_type, const char *item_type_str, const char *error_prefix) @@ -66,59 +72,62 @@ /* not the last dimension */ if (dim + 1 < totdim) { /* check that a sequence contains dimsize[dim] items */ - const Py_ssize_t seq_size= PySequence_Size(seq); + const Py_ssize_t seq_size = PySequence_Size(seq); if (seq_size == -1) { PyErr_Format(PyExc_ValueError, "%s sequence expected at dimension %d, not '%s'", error_prefix, (int)dim + 1, Py_TYPE(seq)->tp_name); return -1; } - for (i= 0; i < seq_size; i++) { + for (i = 0; i < seq_size; i++) { PyObject *item; - int ok= 1; - item= PySequence_GetItem(seq, i); + int ok = 1; + item = PySequence_GetItem(seq, i); if (item == NULL) { PyErr_Format(PyExc_TypeError, "%s sequence type '%s' failed to retrieve index %d", error_prefix, Py_TYPE(seq)->tp_name, i); - ok= 0; + ok = 0; } else if (!PySequence_Check(item)) { /* BLI_snprintf(error_str, error_str_size, "expected a sequence of %s", item_type_str); */ PyErr_Format(PyExc_TypeError, "%s expected a sequence of %s, not %s", error_prefix, item_type_str, Py_TYPE(item)->tp_name); - ok= 0; + ok = 0; } /* arr[3][4][5] - dimsize[1]=4 - dimsize[2]=5 - - dim=0 */ + * dimsize[1] = 4 + * dimsize[2] = 5 + * + * dim = 0 */ else if (PySequence_Size(item) != dimsize[dim + 1]) { - /* BLI_snprintf(error_str, error_str_size, "sequences of dimension %d should contain %d items", (int)dim + 1, (int)dimsize[dim + 1]); */ + /* BLI_snprintf(error_str, error_str_size, + "sequences of dimension %d should contain %d items", + (int)dim + 1, (int)dimsize[dim + 1]); */ PyErr_Format(PyExc_ValueError, "%s sequences of dimension %d should contain %d items", error_prefix, (int)dim + 1, (int)dimsize[dim + 1]); - ok= 0; + ok = 0; } else if (validate_array_type(item, dim + 1, totdim, dimsize, check_item_type, item_type_str, error_prefix) == -1) { - ok= 0; + ok = 0; } Py_XDECREF(item); - if (!ok) + if (!ok) { return -1; + } } } else { /* check that items are of correct type */ - const int seq_size= PySequence_Size(seq); + const int seq_size = PySequence_Size(seq); if (seq_size == -1) { PyErr_Format(PyExc_ValueError, "%s sequence expected at dimension %d, not '%s'", error_prefix, (int)dim + 1, Py_TYPE(seq)->tp_name); return -1; } - for (i= 0; i < seq_size; i++) { - PyObject *item= PySequence_GetItem(seq, i); + for (i = 0; i < seq_size; i++) { + PyObject *item = PySequence_GetItem(seq, i); if (item == NULL) { PyErr_Format(PyExc_TypeError, "%s sequence type '%s' failed to retrieve index %d", @@ -144,32 +153,32 @@ /* Returns the number of items in a single- or multi-dimensional sequence. */ static int count_items(PyObject *seq, int dim) { - int totitem= 0; + int totitem = 0; if (dim > 1) { - const Py_ssize_t seq_size= PySequence_Size(seq); + const Py_ssize_t seq_size = PySequence_Size(seq); Py_ssize_t i; - for (i= 0; i < seq_size; i++) { - PyObject *item= PySequence_GetItem(seq, i); + for (i = 0; i < seq_size; i++) { + PyObject *item = PySequence_GetItem(seq, i); if (item) { - const int tot= count_items(item, dim - 1); + const int tot = count_items(item, dim - 1); Py_DECREF(item); if (tot != -1) { totitem += tot; } else { - totitem= -1; + totitem = -1; break; } } else { - totitem= -1; + totitem = -1; break; } } } else { - totitem= PySequence_Size(seq); + totitem = PySequence_Size(seq); } return totitem; @@ -182,8 +191,8 @@ int dimsize[MAX_ARRAY_DIMENSION]; int tot, totdim, len; - totdim= RNA_property_array_dimension(ptr, prop, dimsize); - tot= count_items(rvalue, totdim - lvalue_dim); + totdim = RNA_property_array_dimension(ptr, prop, dimsize); + tot = count_items(rvalue, totdim - lvalue_dim); if (tot == -1) { PyErr_Format(PyExc_ValueError, "%s %.200s.%.200s, error validating the sequence length", @@ -195,45 +204,47 @@ #if 0 /* length is flexible */ if (!RNA_property_dynamic_array_set_length(ptr, prop, tot)) { - /* BLI_snprintf(error_str, error_str_size, "%s.%s: array length cannot be changed to %d", RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), tot); */ + /* BLI_snprintf(error_str, error_str_size, + "%s.%s: array length cannot be changed to %d", + RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), tot); */ PyErr_Format(PyExc_ValueError, "%s %s.%s: array length cannot be changed to %d", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), tot); return -1; } #else - *totitem= tot; + *totitem = tot; return 0; #endif } - len= tot; + len = tot; } else { /* length is a constraint */ if (!lvalue_dim) { - len= RNA_property_array_length(ptr, prop); + len = RNA_property_array_length(ptr, prop); } /* array item assignment */ else { int i; - len= 1; + len = 1; /* arr[3][4][5] - arr[2]= x - dimsize={4, 5} - dimsize[1]= 4 - dimsize[2]= 5 - lvalue_dim=0, totdim=3 - - arr[2][3]= x - lvalue_dim=1 - - arr[2][3][4]= x - lvalue_dim=2 */ - for (i= lvalue_dim; i < totdim; i++) + arr[2] = x + dimsize = {4, 5} + dimsize[1] = 4 + dimsize[2] = 5 + lvalue_dim = 0, totdim = 3 + + arr[2][3] = x + lvalue_dim = 1 + + arr[2][3][4] = x + lvalue_dim = 2 */ + for (i = lvalue_dim; i < totdim; i++) len *= dimsize[i]; } @@ -245,7 +256,7 @@ } } - *totitem= len; + *totitem = len; return 0; } @@ -255,14 +266,51 @@ const char *error_prefix) { int dimsize[MAX_ARRAY_DIMENSION]; - int totdim= RNA_property_array_dimension(ptr, prop, dimsize); + int totdim = RNA_property_array_dimension(ptr, prop, dimsize); /* validate type first because length validation may modify property array length */ - if (validate_array_type(rvalue, lvalue_dim, totdim, dimsize, check_item_type, item_type_str, error_prefix) == -1) - return -1; - return validate_array_length(rvalue, ptr, prop, lvalue_dim, totitem, error_prefix); +#ifdef USE_MATHUTILS + if (lvalue_dim == 0) { /* only valid for first level array */ + if (MatrixObject_Check(rvalue)) { + MatrixObject *pymat = (MatrixObject *)rvalue; + + if (BaseMath_ReadCallback(pymat) == -1) + return -1; + + if (RNA_property_type(prop) != PROP_FLOAT) { + PyErr_Format(PyExc_ValueError, "%s %.200s.%.200s, matrix assign to non float array", + error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop)); + return -1; + } + else if (totdim != 2) { + PyErr_Format(PyExc_ValueError, "%s %.200s.%.200s, matrix assign array with %d dimensions", + error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), totdim); + return -1; + } + else if (pymat->num_col != dimsize[0] || pymat->num_row != dimsize[1]) { + PyErr_Format(PyExc_ValueError, "%s %.200s.%.200s, matrix assign dimension size mismatch, " + "is %dx%d, expected be %dx%d", + error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), + pymat->num_col, pymat->num_row, dimsize[0], dimsize[1]); + return -1; + } + else { + *totitem = dimsize[0] * dimsize[1]; + return 0; + } + } + } +#endif /* USE_MATHUTILS */ + + + { + if (validate_array_type(rvalue, lvalue_dim, totdim, dimsize, check_item_type, item_type_str, error_prefix) == -1) + return -1; + + return validate_array_length(rvalue, ptr, prop, lvalue_dim, totitem, error_prefix); + } } static char *copy_value_single(PyObject *item, PointerRNA *ptr, PropertyRNA *prop, @@ -274,7 +322,7 @@ convert_item(item, value); rna_set_index(ptr, prop, *index, value); - *index= *index + 1; + *index = *index + 1; } else { convert_item(item, data); @@ -288,8 +336,8 @@ int dim, char *data, unsigned int item_size, int *index, ItemConvertFunc convert_item, RNA_SetIndexFunc rna_set_index) { - int totdim= RNA_property_array_dimension(ptr, prop, NULL); - const Py_ssize_t seq_size= PySequence_Size(seq); + int totdim = RNA_property_array_dimension(ptr, prop, NULL); + const Py_ssize_t seq_size = PySequence_Size(seq); Py_ssize_t i; /* Regarding PySequence_GetItem() failing. @@ -305,14 +353,34 @@ return NULL; } - for (i= 0; i < seq_size; i++) { - PyObject *item= PySequence_GetItem(seq, i); + +#ifdef USE_MATHUTILS + if (dim == 0) { + if (MatrixObject_Check(seq)) { + MatrixObject *pymat = (MatrixObject *)seq; + size_t allocsize = pymat->num_col * pymat->num_row * sizeof(float); + + /* read callback already done by validate */ + /* since this is the first iteration we can assume data is allocated */ + memcpy(data, pymat->matrix, allocsize); + + /* not really needed but do for completeness */ + data += allocsize; + + return data; + } + } +#endif /* USE_MATHUTILS */ + + + for (i = 0; i < seq_size; i++) { + PyObject *item = PySequence_GetItem(seq, i); if (item) { if (dim + 1 < totdim) { - data= copy_values(item, ptr, prop, dim + 1, data, item_size, index, convert_item, rna_set_index); + data = copy_values(item, ptr, prop, dim + 1, data, item_size, index, convert_item, rna_set_index); } else { - data= copy_value_single(item, ptr, prop, data, item_size, index, convert_item, rna_set_index); + data = copy_value_single(item, ptr, prop, data, item_size, index, convert_item, rna_set_index); } Py_DECREF(item); @@ -333,9 +401,9 @@ { /*int totdim, dim_size[MAX_ARRAY_DIMENSION];*/ int totitem; - char *data= NULL; + char *data = NULL; - /*totdim= RNA_property_array_dimension(ptr, prop, dim_size);*/ /*UNUSED*/ + /*totdim = RNA_property_array_dimension(ptr, prop, dim_size);*/ /*UNUSED*/ if (validate_array(seq, ptr, prop, 0, check_item_type, item_type_str, &totitem, error_prefix) == -1) { return -1; @@ -345,30 +413,30 @@ /* note: this code is confusing */ if (param_data && RNA_property_flag(prop) & PROP_DYNAMIC) { /* not freeing allocated mem, RNA_parameter_list_free() will do this */ - ParameterDynAlloc *param_alloc= (ParameterDynAlloc *)param_data; - param_alloc->array_tot= (int)totitem; - param_alloc->array= MEM_callocN(item_size * totitem, "py_to_array dyn"); /* freeing param list will free */ + ParameterDynAlloc *param_alloc = (ParameterDynAlloc *)param_data; + param_alloc->array_tot = (int)totitem; + param_alloc->array = MEM_callocN(item_size * totitem, "py_to_array dyn"); /* freeing param list will free */ - data= param_alloc->array; + data = param_alloc->array; } else if (param_data) { - data= param_data; + data = param_data; } else { - data= PyMem_MALLOC(item_size * totitem); + data = PyMem_MALLOC(item_size * totitem); } /* will only fail in very rare cases since we already validated the * python data, the check here is mainly for completeness. */ if (copy_values(seq, ptr, prop, 0, data, item_size, NULL, convert_item, NULL) != NULL) { - if (param_data==NULL) { + if (param_data == NULL) { /* NULL can only pass through in case RNA property arraylength is 0 (impossible?) */ rna_set_array(ptr, prop, data); PyMem_FREE(data); } } else { - if (param_data==NULL) { + if (param_data == NULL) { PyMem_FREE(data); } @@ -389,21 +457,21 @@ int totdim, dimsize[MAX_ARRAY_DIMENSION]; int totitem, i; - totdim= RNA_property_array_dimension(ptr, prop, dimsize); + totdim = RNA_property_array_dimension(ptr, prop, dimsize); /* convert index */ /* arr[3][4][5] - arr[2]= x - lvalue_dim=0, index= 0 + 2 * 4 * 5 + arr[2] = x + lvalue_dim = 0, index = 0 + 2 * 4 * 5 - arr[2][3]= x - lvalue_dim=1, index= 40 + 3 * 5 */ + arr[2][3] = x + lvalue_dim = 1, index = 40 + 3 * 5 */ lvalue_dim++; - for (i= lvalue_dim; i < totdim; i++) + for (i = lvalue_dim; i < totdim; i++) index *= dimsize[i]; index += arrayoffset; @@ -432,17 +500,17 @@ static void py_to_float(PyObject *py, char *data) { - *(float*)data= (float)PyFloat_AsDouble(py); + *(float *)data = (float)PyFloat_AsDouble(py); } static void py_to_int(PyObject *py, char *data) { - *(int*)data= (int)PyLong_AsSsize_t(py); + *(int *)data = (int)PyLong_AsSsize_t(py); } static void py_to_bool(PyObject *py, char *data) { - *(int*)data= (int)PyObject_IsTrue(py); + *(int *)data = (int)PyObject_IsTrue(py); } static int py_float_check(PyObject *py) @@ -464,17 +532,17 @@ static void float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, void *value) { - RNA_property_float_set_index(ptr, prop, index, *(float*)value); + RNA_property_float_set_index(ptr, prop, index, *(float *)value); } static void int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, void *value) { - RNA_property_int_set_index(ptr, prop, index, *(int*)value); + RNA_property_int_set_index(ptr, prop, index, *(int *)value); } static void bool_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, void *value) { - RNA_property_boolean_set_index(ptr, prop, index, *(int*)value); + RNA_property_boolean_set_index(ptr, prop, index, *(int *)value); } int pyrna_py_to_array(PointerRNA *ptr, PropertyRNA *prop, char *param_data, @@ -483,20 +551,20 @@ int ret; switch (RNA_property_type(prop)) { case PROP_FLOAT: - ret= py_to_array(py, ptr, prop, param_data, py_float_check, "float", sizeof(float), + ret = py_to_array(py, ptr, prop, param_data, py_float_check, "float", sizeof(float), py_to_float, (RNA_SetArrayFunc)RNA_property_float_set_array, error_prefix); break; case PROP_INT: - ret= py_to_array(py, ptr, prop, param_data, py_int_check, "int", sizeof(int), + ret = py_to_array(py, ptr, prop, param_data, py_int_check, "int", sizeof(int), py_to_int, (RNA_SetArrayFunc)RNA_property_int_set_array, error_prefix); break; case PROP_BOOLEAN: - ret= py_to_array(py, ptr, prop, param_data, py_bool_check, "boolean", sizeof(int), + ret = py_to_array(py, ptr, prop, param_data, py_bool_check, "boolean", sizeof(int), py_to_bool, (RNA_SetArrayFunc)RNA_property_boolean_set_array, error_prefix); break; default: PyErr_SetString(PyExc_TypeError, "not an array type"); - ret= -1; + ret = -1; } return ret; @@ -508,20 +576,20 @@ int ret; switch (RNA_property_type(prop)) { case PROP_FLOAT: - ret= py_to_array_index(py, ptr, prop, arraydim, arrayoffset, index, + ret = py_to_array_index(py, ptr, prop, arraydim, arrayoffset, index, py_float_check, "float", py_to_float, float_set_index, error_prefix); break; case PROP_INT: - ret= py_to_array_index(py, ptr, prop, arraydim, arrayoffset, index, + ret = py_to_array_index(py, ptr, prop, arraydim, arrayoffset, index, py_int_check, "int", py_to_int, int_set_index, error_prefix); break; case PROP_BOOLEAN: - ret= py_to_array_index(py, ptr, prop, arraydim, arrayoffset, index, + ret = py_to_array_index(py, ptr, prop, arraydim, arrayoffset, index, py_bool_check, "boolean", py_to_bool, bool_set_index, error_prefix); break; default: PyErr_SetString(PyExc_TypeError, "not an array type"); - ret= -1; + ret = -1; } return ret; @@ -533,17 +601,17 @@ switch (RNA_property_type(prop)) { case PROP_FLOAT: - item= PyFloat_FromDouble(RNA_property_float_get_index(ptr, prop, index)); + item = PyFloat_FromDouble(RNA_property_float_get_index(ptr, prop, index)); break; case PROP_BOOLEAN: - item= PyBool_FromLong(RNA_property_boolean_get_index(ptr, prop, index)); + item = PyBool_FromLong(RNA_property_boolean_get_index(ptr, prop, index)); break; case PROP_INT: - item= PyLong_FromSsize_t(RNA_property_int_get_index(ptr, prop, index)); + item = PyLong_FromSsize_t(RNA_property_int_get_index(ptr, prop, index)); break; default: PyErr_SetString(PyExc_TypeError, "not an array type"); - item= NULL; + item = NULL; } return item; @@ -556,20 +624,20 @@ { PyObject *tuple; int i, len; - int totdim= RNA_property_array_dimension(ptr, prop, NULL); + int totdim = RNA_property_array_dimension(ptr, prop, NULL); - len= RNA_property_multi_array_length(ptr, prop, dim); + len = RNA_property_multi_array_length(ptr, prop, dim); - tuple= PyTuple_New(len); + tuple = PyTuple_New(len); - for (i= 0; i < len; i++) { + for (i = 0; i < len; i++) { PyObject *item; if (dim + 1 < totdim) - item= pyrna_py_from_array_internal(ptr, prop, dim + 1, index); + item = pyrna_py_from_array_internal(ptr, prop, dim + 1, index); else { - item= pyrna_array_index(ptr, prop, *index); - *index= *index + 1; + item = pyrna_array_index(ptr, prop, *index); + *index = *index + 1; } if (!item) { @@ -587,13 +655,13 @@ PyObject *pyrna_py_from_array_index(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop, int index) { int totdim, arraydim, arrayoffset, dimsize[MAX_ARRAY_DIMENSION], i, len; - BPy_PropertyArrayRNA *ret= NULL; + BPy_PropertyArrayRNA *ret = NULL; - arraydim= self ? self->arraydim : 0; - arrayoffset= self ? self->arrayoffset : 0; + arraydim = self ? self->arraydim : 0; + arrayoffset = self ? self->arrayoffset : 0; /* just in case check */ - len= RNA_property_multi_array_length(ptr, prop, arraydim); + len = RNA_property_multi_array_length(ptr, prop, arraydim); if (index >= len || index < 0) { /* this shouldn't happen because higher level funcs must check for invalid index */ if (G.f & G_DEBUG) printf("pyrna_py_from_array_index: invalid index %d for array with length=%d\n", index, len); @@ -602,38 +670,38 @@ return NULL; } - totdim= RNA_property_array_dimension(ptr, prop, dimsize); + totdim = RNA_property_array_dimension(ptr, prop, dimsize); if (arraydim + 1 < totdim) { - ret= (BPy_PropertyArrayRNA*)pyrna_prop_CreatePyObject(ptr, prop); - ret->arraydim= arraydim + 1; + ret = (BPy_PropertyArrayRNA *)pyrna_prop_CreatePyObject(ptr, prop); + ret->arraydim = arraydim + 1; /* arr[3][4][5] - x= arr[2] - index= 0 + 2 * 4 * 5 + x = arr[2] + index = 0 + 2 * 4 * 5 - x= arr[2][3] - index= offset + 3 * 5 */ + x = arr[2][3] + index = offset + 3 * 5 */ - for (i= arraydim + 1; i < totdim; i++) + for (i = arraydim + 1; i < totdim; i++) index *= dimsize[i]; - ret->arrayoffset= arrayoffset + index; + ret->arrayoffset = arrayoffset + index; } else { - index= arrayoffset + index; - ret= (BPy_PropertyArrayRNA *)pyrna_array_index(ptr, prop, index); + index = arrayoffset + index; + ret = (BPy_PropertyArrayRNA *)pyrna_array_index(ptr, prop, index); } - return (PyObject*)ret; + return (PyObject *)ret; } PyObject *pyrna_py_from_array(PointerRNA *ptr, PropertyRNA *prop) { PyObject *ret; - ret= pyrna_math_object_from_array(ptr, prop); + ret = pyrna_math_object_from_array(ptr, prop); /* is this a maths object? */ if (ret) return ret; @@ -644,11 +712,11 @@ /* TODO, multi-dimensional arrays */ int pyrna_array_contains_py(PointerRNA *ptr, PropertyRNA *prop, PyObject *value) { - int len= RNA_property_array_length(ptr, prop); + int len = RNA_property_array_length(ptr, prop); int type; int i; - if (len==0) /* possible with dynamic arrays */ + if (len == 0) /* possible with dynamic arrays */ return 0; if (RNA_property_array_dimension(ptr, prop, NULL) > 1) { @@ -656,13 +724,13 @@ return -1; } - type= RNA_property_type(prop); + type = RNA_property_type(prop); switch (type) { case PROP_FLOAT: { - float value_f= PyFloat_AsDouble(value); - if (value_f==-1 && PyErr_Occurred()) { + float value_f = PyFloat_AsDouble(value); + if (value_f == -1 && PyErr_Occurred()) { PyErr_Clear(); return 0; } @@ -671,15 +739,15 @@ float *tmp_arr; if (len * sizeof(float) > sizeof(tmp)) { - tmp_arr= PyMem_MALLOC(len * sizeof(float)); + tmp_arr = PyMem_MALLOC(len * sizeof(float)); } else { - tmp_arr= tmp; + tmp_arr = tmp; } RNA_property_float_get_array(ptr, prop, tmp_arr); - for (i=0; i sizeof(tmp)) { - tmp_arr= PyMem_MALLOC(len * sizeof(int)); + tmp_arr = PyMem_MALLOC(len * sizeof(int)); } else { - tmp_arr= tmp; + tmp_arr = tmp; } - if (type==PROP_BOOLEAN) + if (type == PROP_BOOLEAN) RNA_property_boolean_get_array(ptr, prop, tmp_arr); else RNA_property_int_get_array(ptr, prop, tmp_arr); - for (i=0; iptr.type= NULL; /* this is checked for validity */ - self->ptr.id.data= NULL; /* should not be needed but prevent bad pointer access, just incase */ + self->ptr.type = NULL; /* this is checked for validity */ + self->ptr.id.data = NULL; /* should not be needed but prevent bad pointer access, just incase */ } #endif #ifdef USE_PYRNA_INVALIDATE_GC -#define FROM_GC(g) ((PyObject *)(((PyGC_Head *)g)+1)) +#define FROM_GC(g) ((PyObject *)(((PyGC_Head *)g) + 1)) /* only for sizeof() */ struct gc_generation { @@ -138,15 +138,15 @@ static void id_release_gc(struct ID *id) { unsigned int j; - // unsigned int i= 0; - for (j=0; j<3; j++) { + // unsigned int i = 0; + for (j = 0; j < 3; j++) { /* hack below to get the 2 other lists from _PyGC_generation0 that are normally not exposed */ - PyGC_Head *gen= (PyGC_Head *)(((char *)_PyGC_generation0) + (sizeof(gc_generation) * j)); - PyGC_Head *g= gen->gc.gc_next; - while ((g= g->gc.gc_next) != gen) { - PyObject *ob= FROM_GC(g); + PyGC_Head *gen = (PyGC_Head *)(((char *)_PyGC_generation0) + (sizeof(gc_generation) * j)); + PyGC_Head *g = gen->gc.gc_next; + while ((g = g->gc.gc_next) != gen) { + PyObject *ob = FROM_GC(g); if (PyType_IsSubtype(Py_TYPE(ob), &pyrna_struct_Type) || PyType_IsSubtype(Py_TYPE(ob), &pyrna_prop_Type)) { - BPy_DummyPointerRNA *ob_ptr= (BPy_DummyPointerRNA *)ob; + BPy_DummyPointerRNA *ob_ptr = (BPy_DummyPointerRNA *)ob; if (ob_ptr->ptr.id.data == id) { pyrna_invalidate(ob_ptr); // printf("freeing: %p %s, %.200s\n", (void *)ob, id->name, Py_TYPE(ob)->tp_name); @@ -162,27 +162,27 @@ #ifdef USE_PYRNA_INVALIDATE_WEAKREF //#define DEBUG_RNA_WEAKREF -struct GHash *id_weakref_pool= NULL; +struct GHash *id_weakref_pool = NULL; static PyObject *id_free_weakref_cb(PyObject *weakinfo_pair, PyObject *weakref); -static PyMethodDef id_free_weakref_cb_def= {"id_free_weakref_cb", (PyCFunction)id_free_weakref_cb, METH_O, NULL}; +static PyMethodDef id_free_weakref_cb_def = {"id_free_weakref_cb", (PyCFunction)id_free_weakref_cb, METH_O, NULL}; /* adds a reference to the list, remember to decref */ static GHash *id_weakref_pool_get(ID *id) { - GHash *weakinfo_hash= NULL; + GHash *weakinfo_hash = NULL; if (id_weakref_pool) { - weakinfo_hash= BLI_ghash_lookup(id_weakref_pool, (void *)id); + weakinfo_hash = BLI_ghash_lookup(id_weakref_pool, (void *)id); } else { /* first time, allocate pool */ - id_weakref_pool= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "rna_global_pool"); - weakinfo_hash= NULL; + id_weakref_pool = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "rna_global_pool"); + weakinfo_hash = NULL; } - if (weakinfo_hash==NULL) { + if (weakinfo_hash == NULL) { /* we're using a ghash as a set, could use libHX's HXMAP_SINGULAR but would be an extra dep. */ - weakinfo_hash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "rna_id"); + weakinfo_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "rna_id"); BLI_ghash_insert(id_weakref_pool, (void *)id, weakinfo_hash); } @@ -197,14 +197,14 @@ PyObject *weakref_cb_py; /* create a new function instance and insert the list as 'self' so we can remove ourself from it */ - GHash *weakinfo_hash= id_weakref_pool_get(id); /* new or existing */ + GHash *weakinfo_hash = id_weakref_pool_get(id); /* new or existing */ - weakref_capsule= PyCapsule_New(weakinfo_hash, NULL, NULL); - weakref_cb_py= PyCFunction_New(&id_free_weakref_cb_def, weakref_capsule); + weakref_capsule = PyCapsule_New(weakinfo_hash, NULL, NULL); + weakref_cb_py = PyCFunction_New(&id_free_weakref_cb_def, weakref_capsule); Py_DECREF(weakref_capsule); /* add weakref to weakinfo_hash list */ - weakref= PyWeakref_NewRef((PyObject *)pyrna, weakref_cb_py); + weakref = PyWeakref_NewRef((PyObject *)pyrna, weakref_cb_py); Py_DECREF(weakref_cb_py); /* function owned by the weakref now */ @@ -218,14 +218,14 @@ static ID *_id_tmp_ptr; static void value_id_set(void *id) { - _id_tmp_ptr= (ID *)id; + _id_tmp_ptr = (ID *)id; } static void id_release_weakref_list(struct ID *id, GHash *weakinfo_hash); static PyObject *id_free_weakref_cb(PyObject *weakinfo_capsule, PyObject *weakref) { /* important to search backwards */ - GHash *weakinfo_hash= PyCapsule_GetPointer(weakinfo_capsule, NULL); + GHash *weakinfo_hash = PyCapsule_GetPointer(weakinfo_capsule, NULL); if (BLI_ghash_size(weakinfo_hash) > 1) { @@ -252,8 +252,8 @@ #endif while (!BLI_ghashIterator_isDone(&weakinfo_hash_iter)) { - PyObject *weakref= (PyObject *)BLI_ghashIterator_getKey(&weakinfo_hash_iter); - PyObject *item= PyWeakref_GET_OBJECT(weakref); + PyObject *weakref = (PyObject *)BLI_ghashIterator_getKey(&weakinfo_hash_iter); + PyObject *item = PyWeakref_GET_OBJECT(weakref); if (item != Py_None) { #ifdef DEBUG_RNA_WEAKREF @@ -273,7 +273,7 @@ if (BLI_ghash_size(id_weakref_pool) == 0) { BLI_ghash_free(id_weakref_pool, NULL, NULL); - id_weakref_pool= NULL; + id_weakref_pool = NULL; #ifdef DEBUG_RNA_WEAKREF printf("id_release_weakref freeing pool\n"); #endif @@ -282,7 +282,7 @@ static void id_release_weakref(struct ID *id) { - GHash *weakinfo_hash= BLI_ghash_lookup(id_weakref_pool, (void *)id); + GHash *weakinfo_hash = BLI_ghash_lookup(id_weakref_pool, (void *)id); if (weakinfo_hash) { id_release_weakref_list(id, weakinfo_hash); } @@ -298,7 +298,7 @@ #ifdef USE_PYRNA_INVALIDATE_WEAKREF if (id_weakref_pool) { - PyGILState_STATE gilstate= PyGILState_Ensure(); + PyGILState_STATE gilstate = PyGILState_Ensure(); id_release_weakref(id); @@ -310,25 +310,25 @@ } #ifdef USE_PEDANTIC_WRITE -static short rna_disallow_writes= FALSE; +static short rna_disallow_writes = FALSE; static int rna_id_write_error(PointerRNA *ptr, PyObject *key) { - ID *id= ptr->id.data; + ID *id = ptr->id.data; if (id) { - const short idcode= GS(id->name); + const short idcode = GS(id->name); if (!ELEM(idcode, ID_WM, ID_SCR)) { /* may need more added here */ - const char *idtype= BKE_idcode_to_name(idcode); + const char *idtype = BKE_idcode_to_name(idcode); const char *pyname; - if (key && PyUnicode_Check(key)) pyname= _PyUnicode_AsString(key); - else pyname= ""; + if (key && PyUnicode_Check(key)) pyname = _PyUnicode_AsString(key); + else pyname = ""; /* make a nice string error */ BLI_assert(idtype != NULL); PyErr_Format(PyExc_AttributeError, "Writing to ID classes in this context is not allowed: " "%.200s, %.200s datablock, error setting %.200s.%.200s", - id->name+2, idtype, RNA_struct_identifier(ptr->type), pyname); + id->name + 2, idtype, RNA_struct_identifier(ptr->type), pyname); return TRUE; } @@ -346,7 +346,7 @@ void pyrna_write_set(int val) { - rna_disallow_writes= !val; + rna_disallow_writes = !val; } #else // USE_PEDANTIC_WRITE int pyrna_write_check(void) @@ -372,7 +372,7 @@ static short pyrna_rotation_euler_order_get(PointerRNA *ptr, PropertyRNA **prop_eul_order, short order_fallback); /* bpyrna vector/euler/quat callbacks */ -static int mathutils_rna_array_cb_index= -1; /* index for our callbacks */ +static int mathutils_rna_array_cb_index = -1; /* index for our callbacks */ /* subtype not used much yet */ #define MATHUTILS_CB_SUBTYPE_EUL 0 @@ -382,7 +382,7 @@ static int mathutils_rna_generic_check(BaseMathObject *bmo) { - BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user; + BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user; PYRNA_PROP_CHECK_INT(self); @@ -391,20 +391,20 @@ static int mathutils_rna_vector_get(BaseMathObject *bmo, int subtype) { - BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user; + BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user; PYRNA_PROP_CHECK_INT(self); - if (self->prop==NULL) + if (self->prop == NULL) return -1; RNA_property_float_get_array(&self->ptr, self->prop, bmo->data); /* Euler order exception */ - if (subtype==MATHUTILS_CB_SUBTYPE_EUL) { - EulerObject *eul= (EulerObject *)bmo; - PropertyRNA *prop_eul_order= NULL; - eul->order= pyrna_rotation_euler_order_get(&self->ptr, &prop_eul_order, eul->order); + if (subtype == MATHUTILS_CB_SUBTYPE_EUL) { + EulerObject *eul = (EulerObject *)bmo; + PropertyRNA *prop_eul_order = NULL; + eul->order = pyrna_rotation_euler_order_get(&self->ptr, &prop_eul_order, eul->order); } return 0; @@ -412,12 +412,12 @@ static int mathutils_rna_vector_set(BaseMathObject *bmo, int subtype) { - BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user; + BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user; float min, max; PYRNA_PROP_CHECK_INT(self); - if (self->prop==NULL) + if (self->prop == NULL) return -1; #ifdef USE_PEDANTIC_WRITE @@ -436,8 +436,8 @@ RNA_property_float_range(&self->ptr, self->prop, &min, &max); if (min != FLT_MIN || max != FLT_MAX) { - int i, len= RNA_property_array_length(&self->ptr, self->prop); - for (i=0; iptr, self->prop); + for (i = 0; i < len; i++) { CLAMP(bmo->data[i], min, max); } } @@ -448,10 +448,10 @@ } /* Euler order exception */ - if (subtype==MATHUTILS_CB_SUBTYPE_EUL) { - EulerObject *eul= (EulerObject *)bmo; - PropertyRNA *prop_eul_order= NULL; - short order= pyrna_rotation_euler_order_get(&self->ptr, &prop_eul_order, eul->order); + if (subtype == MATHUTILS_CB_SUBTYPE_EUL) { + EulerObject *eul = (EulerObject *)bmo; + PropertyRNA *prop_eul_order = NULL; + short order = pyrna_rotation_euler_order_get(&self->ptr, &prop_eul_order, eul->order); if (order != eul->order) { RNA_property_enum_set(&self->ptr, prop_eul_order, eul->order); if (RNA_property_update_check(prop_eul_order)) { @@ -464,24 +464,24 @@ static int mathutils_rna_vector_get_index(BaseMathObject *bmo, int UNUSED(subtype), int index) { - BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user; + BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user; PYRNA_PROP_CHECK_INT(self); - if (self->prop==NULL) + if (self->prop == NULL) return -1; - bmo->data[index]= RNA_property_float_get_index(&self->ptr, self->prop, index); + bmo->data[index] = RNA_property_float_get_index(&self->ptr, self->prop, index); return 0; } static int mathutils_rna_vector_set_index(BaseMathObject *bmo, int UNUSED(subtype), int index) { - BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user; + BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user; PYRNA_PROP_CHECK_INT(self); - if (self->prop==NULL) + if (self->prop == NULL) return -1; #ifdef USE_PEDANTIC_WRITE @@ -507,7 +507,7 @@ return 0; } -static Mathutils_Callback mathutils_rna_array_cb= { +static Mathutils_Callback mathutils_rna_array_cb = { (BaseMathCheckFunc) mathutils_rna_generic_check, (BaseMathGetFunc) mathutils_rna_vector_get, (BaseMathSetFunc) mathutils_rna_vector_set, @@ -517,15 +517,15 @@ /* bpyrna matrix callbacks */ -static int mathutils_rna_matrix_cb_index= -1; /* index for our callbacks */ +static int mathutils_rna_matrix_cb_index = -1; /* index for our callbacks */ static int mathutils_rna_matrix_get(BaseMathObject *bmo, int UNUSED(subtype)) { - BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user; + BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user; PYRNA_PROP_CHECK_INT(self); - if (self->prop==NULL) + if (self->prop == NULL) return -1; RNA_property_float_get_array(&self->ptr, self->prop, bmo->data); @@ -534,11 +534,11 @@ static int mathutils_rna_matrix_set(BaseMathObject *bmo, int UNUSED(subtype)) { - BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user; + BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user; PYRNA_PROP_CHECK_INT(self); - if (self->prop==NULL) + if (self->prop == NULL) return -1; #ifdef USE_PEDANTIC_WRITE @@ -563,7 +563,7 @@ return 0; } -static Mathutils_Callback mathutils_rna_matrix_cb= { +static Mathutils_Callback mathutils_rna_matrix_cb = { mathutils_rna_generic_check, mathutils_rna_matrix_get, mathutils_rna_matrix_set, @@ -574,11 +574,11 @@ static short pyrna_rotation_euler_order_get(PointerRNA *ptr, PropertyRNA **prop_eul_order, short order_fallback) { /* attempt to get order */ - if (*prop_eul_order==NULL) - *prop_eul_order= RNA_struct_find_property(ptr, "rotation_mode"); + if (*prop_eul_order == NULL) + *prop_eul_order = RNA_struct_find_property(ptr, "rotation_mode"); if (*prop_eul_order) { - short order= RNA_property_enum_get(ptr, *prop_eul_order); + short order = RNA_property_enum_get(ptr, *prop_eul_order); if (order >= EULER_ORDER_XYZ && order <= EULER_ORDER_ZYX) /* could be quat or axisangle */ return order; } @@ -602,107 +602,107 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) { - PyObject *ret= NULL; + PyObject *ret = NULL; #ifdef USE_MATHUTILS int subtype, totdim; int len; int is_thick; - const int flag= RNA_property_flag(prop); + const int flag = RNA_property_flag(prop); /* disallow dynamic sized arrays to be wrapped since the size could change * to a size mathutils does not support */ if ((RNA_property_type(prop) != PROP_FLOAT) || (flag & PROP_DYNAMIC)) return NULL; - len= RNA_property_array_length(ptr, prop); - subtype= RNA_property_subtype(prop); - totdim= RNA_property_array_dimension(ptr, prop, NULL); - is_thick= (flag & PROP_THICK_WRAP); + len = RNA_property_array_length(ptr, prop); + subtype = RNA_property_subtype(prop); + totdim = RNA_property_array_dimension(ptr, prop, NULL); + is_thick = (flag & PROP_THICK_WRAP); if (totdim == 1 || (totdim == 2 && subtype == PROP_MATRIX)) { if (!is_thick) - ret= pyrna_prop_CreatePyObject(ptr, prop); /* owned by the mathutils PyObject */ + ret = pyrna_prop_CreatePyObject(ptr, prop); /* owned by the mathutils PyObject */ - switch(subtype) { + switch (subtype) { case PROP_ALL_VECTOR_SUBTYPES: - if (len>=2 && len <= 4) { + if (len >= 2 && len <= 4) { if (is_thick) { - ret= Vector_CreatePyObject(NULL, len, Py_NEW, NULL); + ret = Vector_CreatePyObject(NULL, len, Py_NEW, NULL); RNA_property_float_get_array(ptr, prop, ((VectorObject *)ret)->vec); } else { - PyObject *vec_cb= Vector_CreatePyObject_cb(ret, len, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_VEC); + PyObject *vec_cb = Vector_CreatePyObject_cb(ret, len, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_VEC); Py_DECREF(ret); /* the vector owns now */ - ret= vec_cb; /* return the vector instead */ + ret = vec_cb; /* return the vector instead */ } } break; case PROP_MATRIX: - if (len==16) { + if (len == 16) { if (is_thick) { - ret= Matrix_CreatePyObject(NULL, 4, 4, Py_NEW, NULL); - RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->contigPtr); + ret = Matrix_CreatePyObject(NULL, 4, 4, Py_NEW, NULL); + RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix); } else { - PyObject *mat_cb= Matrix_CreatePyObject_cb(ret, 4,4, mathutils_rna_matrix_cb_index, FALSE); + PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 4,4, mathutils_rna_matrix_cb_index, FALSE); Py_DECREF(ret); /* the matrix owns now */ - ret= mat_cb; /* return the matrix instead */ + ret = mat_cb; /* return the matrix instead */ } } - else if (len==9) { + else if (len == 9) { if (is_thick) { - ret= Matrix_CreatePyObject(NULL, 3, 3, Py_NEW, NULL); - RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->contigPtr); + ret = Matrix_CreatePyObject(NULL, 3, 3, Py_NEW, NULL); + RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix); } else { - PyObject *mat_cb= Matrix_CreatePyObject_cb(ret, 3,3, mathutils_rna_matrix_cb_index, FALSE); + PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 3,3, mathutils_rna_matrix_cb_index, FALSE); Py_DECREF(ret); /* the matrix owns now */ - ret= mat_cb; /* return the matrix instead */ + ret = mat_cb; /* return the matrix instead */ } } break; case PROP_EULER: case PROP_QUATERNION: - if (len==3) { /* euler */ + if (len == 3) { /* euler */ if (is_thick) { /* attempt to get order, only needed for thick types since wrapped with update via callbacks */ - PropertyRNA *prop_eul_order= NULL; - short order= pyrna_rotation_euler_order_get(ptr, &prop_eul_order, EULER_ORDER_XYZ); + PropertyRNA *prop_eul_order = NULL; + short order = pyrna_rotation_euler_order_get(ptr, &prop_eul_order, EULER_ORDER_XYZ); - ret= Euler_CreatePyObject(NULL, order, Py_NEW, NULL); // TODO, get order from RNA + ret = Euler_CreatePyObject(NULL, order, Py_NEW, NULL); // TODO, get order from RNA RNA_property_float_get_array(ptr, prop, ((EulerObject *)ret)->eul); } else { /* order will be updated from callback on use */ - PyObject *eul_cb= Euler_CreatePyObject_cb(ret, EULER_ORDER_XYZ, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_EUL); // TODO, get order from RNA + PyObject *eul_cb = Euler_CreatePyObject_cb(ret, EULER_ORDER_XYZ, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_EUL); // TODO, get order from RNA Py_DECREF(ret); /* the euler owns now */ - ret= eul_cb; /* return the euler instead */ + ret = eul_cb; /* return the euler instead */ } } - else if (len==4) { + else if (len == 4) { if (is_thick) { - ret= Quaternion_CreatePyObject(NULL, Py_NEW, NULL); + ret = Quaternion_CreatePyObject(NULL, Py_NEW, NULL); RNA_property_float_get_array(ptr, prop, ((QuaternionObject *)ret)->quat); } else { - PyObject *quat_cb= Quaternion_CreatePyObject_cb(ret, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_QUAT); + PyObject *quat_cb = Quaternion_CreatePyObject_cb(ret, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_QUAT); Py_DECREF(ret); /* the quat owns now */ - ret= quat_cb; /* return the quat instead */ + ret = quat_cb; /* return the quat instead */ } } break; case PROP_COLOR: case PROP_COLOR_GAMMA: - if (len==3) { /* color */ + if (len == 3) { /* color */ if (is_thick) { - ret= Color_CreatePyObject(NULL, Py_NEW, NULL); // TODO, get order from RNA + ret = Color_CreatePyObject(NULL, Py_NEW, NULL); // TODO, get order from RNA RNA_property_float_get_array(ptr, prop, ((ColorObject *)ret)->col); } else { - PyObject *col_cb= Color_CreatePyObject_cb(ret, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_COLOR); + PyObject *col_cb = Color_CreatePyObject_cb(ret, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_COLOR); Py_DECREF(ret); /* the color owns now */ - ret= col_cb; /* return the color instead */ + ret = col_cb; /* return the color instead */ } } default: @@ -710,14 +710,14 @@ } } - if (ret==NULL) { + if (ret == NULL) { if (is_thick) { /* this is an array we cant reference (since its not thin wrappable) * and cannot be coerced into a mathutils type, so return as a list */ - ret= pyrna_prop_array_subscript_slice(NULL, ptr, prop, 0, len, len); + ret = pyrna_prop_array_subscript_slice(NULL, ptr, prop, 0, len, len); } else { - ret= pyrna_prop_CreatePyObject(ptr, prop); /* owned by the mathutils PyObject */ + ret = pyrna_prop_CreatePyObject(ptr, prop); /* owned by the mathutils PyObject */ } } #else // USE_MATHUTILS @@ -732,7 +732,7 @@ int pyrna_enum_value_from_id(EnumPropertyItem *item, const char *identifier, int *value, const char *error_prefix) { if (RNA_enum_value_from_id(item, identifier, value) == 0) { - const char *enum_str= BPy_enum_as_string(item); + const char *enum_str = BPy_enum_as_string(item); PyErr_Format(PyExc_TypeError, "%s: '%.200s' not found in (%s)", error_prefix, identifier, enum_str); @@ -743,36 +743,50 @@ return 0; } +/* note on __cmp__: + * checking the 'ptr->data' matches works in almost all cases, + * however there are a few RNA properties that are fake sub-structs and + * share the pointer with the parent, in those cases this happens 'a.b == a' + * see: r43352 for example. + * + * So compare the 'ptr->type' as well to avoid this problem. + * It's highly unlikely this would happen that 'ptr->data' and 'ptr->prop' would match, + * but _not_ 'ptr->type' but include this check for completeness. + * - campbell */ + static int pyrna_struct_compare(BPy_StructRNA *a, BPy_StructRNA *b) { - return (a->ptr.data==b->ptr.data) ? 0 : -1; + return ( (a->ptr.data == b->ptr.data) && + (a->ptr.type == b->ptr.type)) ? 0 : -1; } static int pyrna_prop_compare(BPy_PropertyRNA *a, BPy_PropertyRNA *b) { - return (a->prop==b->prop && a->ptr.data==b->ptr.data) ? 0 : -1; + return ( (a->prop == b->prop) && + (a->ptr.data == b->ptr.data) && + (a->ptr.type == b->ptr.type) ) ? 0 : -1; } static PyObject *pyrna_struct_richcmp(PyObject *a, PyObject *b, int op) { PyObject *res; - int ok= -1; /* zero is true */ + int ok = -1; /* zero is true */ if (BPy_StructRNA_Check(a) && BPy_StructRNA_Check(b)) - ok= pyrna_struct_compare((BPy_StructRNA *)a, (BPy_StructRNA *)b); + ok = pyrna_struct_compare((BPy_StructRNA *)a, (BPy_StructRNA *)b); switch (op) { case Py_NE: - ok= !ok; /* pass through */ + ok = !ok; /* pass through */ case Py_EQ: - res= ok ? Py_False : Py_True; + res = ok ? Py_False : Py_True; break; case Py_LT: case Py_LE: case Py_GT: case Py_GE: - res= Py_NotImplemented; + res = Py_NotImplemented; break; default: PyErr_BadArgument(); @@ -785,23 +799,23 @@ static PyObject *pyrna_prop_richcmp(PyObject *a, PyObject *b, int op) { PyObject *res; - int ok= -1; /* zero is true */ + int ok = -1; /* zero is true */ if (BPy_PropertyRNA_Check(a) && BPy_PropertyRNA_Check(b)) - ok= pyrna_prop_compare((BPy_PropertyRNA *)a, (BPy_PropertyRNA *)b); + ok = pyrna_prop_compare((BPy_PropertyRNA *)a, (BPy_PropertyRNA *)b); switch (op) { case Py_NE: - ok= !ok; /* pass through */ + ok = !ok; /* pass through */ case Py_EQ: - res= ok ? Py_False : Py_True; + res = ok ? Py_False : Py_True; break; case Py_LT: case Py_LE: case Py_GT: case Py_GE: - res= Py_NotImplemented; + res = Py_NotImplemented; break; default: PyErr_BadArgument(); @@ -823,9 +837,9 @@ } /* print name if available */ - name= RNA_struct_name_get_alloc(&self->ptr, NULL, 0, NULL); + name = RNA_struct_name_get_alloc(&self->ptr, NULL, 0, NULL); if (name) { - ret= PyUnicode_FromFormat("", + ret = PyUnicode_FromFormat("", RNA_struct_identifier(self->ptr.type), name); MEM_freeN((void *)name); @@ -839,32 +853,32 @@ static PyObject *pyrna_struct_repr(BPy_StructRNA *self) { - ID *id= self->ptr.id.data; + ID *id = self->ptr.id.data; PyObject *tmp_str; PyObject *ret; if (id == NULL || !PYRNA_STRUCT_IS_VALID(self)) return pyrna_struct_str(self); /* fallback */ - tmp_str= PyUnicode_FromString(id->name+2); + tmp_str = PyUnicode_FromString(id->name + 2); if (RNA_struct_is_ID(self->ptr.type)) { - ret= PyUnicode_FromFormat("bpy.data.%s[%R]", + ret = PyUnicode_FromFormat("bpy.data.%s[%R]", BKE_idcode_to_name_plural(GS(id->name)), tmp_str); } else { const char *path; - path= RNA_path_from_ID_to_struct(&self->ptr); + path = RNA_path_from_ID_to_struct(&self->ptr); if (path) { - ret= PyUnicode_FromFormat("bpy.data.%s[%R].%s", + ret = PyUnicode_FromFormat("bpy.data.%s[%R].%s", BKE_idcode_to_name_plural(GS(id->name)), tmp_str, path); MEM_freeN((void *)path); } else { /* cant find, print something sane */ - ret= PyUnicode_FromFormat("bpy.data.%s[%R]...%s", + ret = PyUnicode_FromFormat("bpy.data.%s[%R]...%s", BKE_idcode_to_name_plural(GS(id->name)), tmp_str, RNA_struct_identifier(self->ptr.type)); @@ -881,30 +895,30 @@ PyObject *ret; PointerRNA ptr; const char *name; - const char *type_id= NULL; - char type_fmt[64]= ""; + const char *type_id = NULL; + char type_fmt[64] = ""; int type; PYRNA_PROP_CHECK_OBJ(self); - type= RNA_property_type(self->prop); + type = RNA_property_type(self->prop); - if (RNA_enum_id_from_value(property_type_items, type, &type_id)==0) { + if (RNA_enum_id_from_value(property_type_items, type, &type_id) == 0) { PyErr_SetString(PyExc_RuntimeError, "could not use property type, internal error"); /* should never happen */ return NULL; } else { /* this should never fail */ - int len= -1; - char *c= type_fmt; + int len = -1; + char *c = type_fmt; while ((*c++= tolower(*type_id++))) {} ; - if (type==PROP_COLLECTION) { - len= pyrna_prop_collection_length(self); + if (type == PROP_COLLECTION) { + len = pyrna_prop_collection_length(self); } else if (RNA_property_array_check(self->prop)) { - len= pyrna_prop_array_length((BPy_PropertyArrayRNA *)self); + len = pyrna_prop_array_length((BPy_PropertyArrayRNA *)self); } if (len != -1) @@ -913,11 +927,11 @@ /* if a pointer, try to print name of pointer target too */ if (type == PROP_POINTER) { - ptr= RNA_property_pointer_get(&self->ptr, self->prop); - name= RNA_struct_name_get_alloc(&ptr, NULL, 0, NULL); + ptr = RNA_property_pointer_get(&self->ptr, self->prop); + name = RNA_struct_name_get_alloc(&ptr, NULL, 0, NULL); if (name) { - ret= PyUnicode_FromFormat("", + ret = PyUnicode_FromFormat("", type_fmt, RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop), @@ -943,7 +957,7 @@ static PyObject *pyrna_prop_repr(BPy_PropertyRNA *self) { - ID *id= self->ptr.id.data; + ID *id = self->ptr.id.data; PyObject *tmp_str; PyObject *ret; const char *path; @@ -953,18 +967,18 @@ if (id == NULL) return pyrna_prop_str(self); /* fallback */ - tmp_str= PyUnicode_FromString(id->name+2); + tmp_str = PyUnicode_FromString(id->name + 2); - path= RNA_path_from_ID_to_property(&self->ptr, self->prop); + path = RNA_path_from_ID_to_property(&self->ptr, self->prop); if (path) { - ret= PyUnicode_FromFormat("bpy.data.%s[%R].%s", + ret = PyUnicode_FromFormat("bpy.data.%s[%R].%s", BKE_idcode_to_name_plural(GS(id->name)), tmp_str, path); MEM_freeN((void *)path); } else { /* cant find, print something sane */ - ret= PyUnicode_FromFormat("bpy.data.%s[%R]...%s", + ret = PyUnicode_FromFormat("bpy.data.%s[%R]...%s", BKE_idcode_to_name_plural(GS(id->name)), tmp_str, RNA_property_identifier(self->prop)); @@ -995,18 +1009,18 @@ { long x, y; if (self->ptr.data == NULL) - x= 0; + x = 0; else { - x= _Py_HashPointer(self->ptr.data); + x = _Py_HashPointer(self->ptr.data); if (x == -1) return -1; } - y= _Py_HashPointer((void*)(self->prop)); + y = _Py_HashPointer((void *)(self->prop)); if (y == -1) return -1; x ^= y; if (x == -1) - x= -2; + x = -2; return x; } @@ -1031,7 +1045,7 @@ if (self->freeptr && self->ptr.data) { IDP_FreeProperty(self->ptr.data); MEM_freeN(self->ptr.data); - self->ptr.data= NULL; + self->ptr.data = NULL; } #endif /* PYRNA_FREE_SUPPORT */ @@ -1056,15 +1070,15 @@ static void pyrna_struct_reference_set(BPy_StructRNA *self, PyObject *reference) { if (self->reference) { -// PyObject_GC_UnTrack(self); /* INITIALIZED TRACKED? */ +// PyObject_GC_UnTrack(self); /* INITIALIZED TRACKED ? */ pyrna_struct_clear(self); } /* reference is now NULL */ if (reference) { - self->reference= reference; + self->reference = reference; Py_INCREF(reference); -// PyObject_GC_Track(self); /* INITIALIZED TRACKED? */ +// PyObject_GC_Track(self); /* INITIALIZED TRACKED ? */ } } #endif /* !USE_PYRNA_STRUCT_REFERENCE */ @@ -1096,14 +1110,14 @@ { EnumPropertyItem *item; const char *result; - int free= FALSE; + int free = FALSE; RNA_property_enum_items(BPy_GetContext(), ptr, prop, &item, NULL, &free); if (item) { - result= BPy_enum_as_string(item); + result = BPy_enum_as_string(item); } else { - result= ""; + result = ""; } if (free) @@ -1115,15 +1129,13 @@ static int pyrna_string_to_enum(PyObject *item, PointerRNA *ptr, PropertyRNA *prop, int *val, const char *error_prefix) { - const char *param= _PyUnicode_AsString(item); + const char *param = _PyUnicode_AsString(item); - if (param==NULL) { - const char *enum_str= pyrna_enum_as_string(ptr, prop); + if (param == NULL) { PyErr_Format(PyExc_TypeError, - "%.200s expected a string enum type in (%.200s)", - error_prefix, enum_str); - MEM_freeN((void *)enum_str); - return 0; + "%.200s expected a string enum, not %.200s", + error_prefix, Py_TYPE(item)->tp_name); + return -1; } else { /* hack so that dynamic enums used for operator properties will be able to be built (i.e. context will be supplied to itemf) @@ -1131,35 +1143,35 @@ RNA_def_property_clear_flag(prop, PROP_ENUM_NO_CONTEXT); if (!RNA_property_enum_value(BPy_GetContext(), ptr, prop, param, val)) { - const char *enum_str= pyrna_enum_as_string(ptr, prop); + const char *enum_str = pyrna_enum_as_string(ptr, prop); PyErr_Format(PyExc_TypeError, "%.200s enum \"%.200s\" not found in (%.200s)", error_prefix, param, enum_str); MEM_freeN((void *)enum_str); - return 0; + return -1; } } - return 1; + return 0; } /* 'value' _must_ be a set type, error check before calling */ int pyrna_set_to_enum_bitfield(EnumPropertyItem *items, PyObject *value, int *r_value, const char *error_prefix) { /* set of enum items, concatenate all values with OR */ - int ret, flag= 0; + int ret, flag = 0; /* set looping */ - Py_ssize_t pos= 0; - Py_ssize_t hash= 0; + Py_ssize_t pos = 0; + Py_ssize_t hash = 0; PyObject *key; - *r_value= 0; + *r_value = 0; while (_PySet_NextEntry(value, &pos, &key, &hash)) { - const char *param= _PyUnicode_AsString(key); + const char *param = _PyUnicode_AsString(key); - if (param==NULL) { + if (param == NULL) { PyErr_Format(PyExc_TypeError, "%.200s expected a string, not %.200s", error_prefix, Py_TYPE(key)->tp_name); @@ -1173,7 +1185,7 @@ flag |= ret; } - *r_value= flag; + *r_value = flag; return 0; } @@ -1181,9 +1193,9 @@ { EnumPropertyItem *item; int ret; - int free= FALSE; + int free = FALSE; - *r_value= 0; + *r_value = 0; if (!PyAnySet_Check(value)) { PyErr_Format(PyExc_TypeError, @@ -1196,17 +1208,17 @@ RNA_property_enum_items(BPy_GetContext(), ptr, prop, &item, NULL, &free); if (item) { - ret= pyrna_set_to_enum_bitfield(item, value, r_value, error_prefix); + ret = pyrna_set_to_enum_bitfield(item, value, r_value, error_prefix); } else { if (PySet_GET_SIZE(value)) { PyErr_Format(PyExc_TypeError, "%.200s: empty enum \"%.200s\" could not have any values assigned", error_prefix, RNA_property_identifier(prop)); - ret= -1; + ret = -1; } else { - ret= 0; + ret = 0; } } @@ -1218,14 +1230,14 @@ PyObject *pyrna_enum_bitfield_to_py(EnumPropertyItem *items, int value) { - PyObject *ret= PySet_New(NULL); + PyObject *ret = PySet_New(NULL); const char *identifier[RNA_ENUM_BITFLAG_SIZE + 1]; if (RNA_enum_bitflag_identifiers(items, value, identifier)) { PyObject *item; int index; - for (index=0; identifier[index]; index++) { - item= PyUnicode_FromString(identifier[index]); + for (index = 0; identifier[index]; index++) { + item = PyUnicode_FromString(identifier[index]); PySet_Add(ret, item); Py_DECREF(item); } @@ -1236,18 +1248,18 @@ static PyObject *pyrna_enum_to_py(PointerRNA *ptr, PropertyRNA *prop, int val) { - PyObject *item, *ret= NULL; + PyObject *item, *ret = NULL; if (RNA_property_flag(prop) & PROP_ENUM_FLAG) { const char *identifier[RNA_ENUM_BITFLAG_SIZE + 1]; - ret= PySet_New(NULL); + ret = PySet_New(NULL); if (RNA_property_enum_bitflag_identifiers(BPy_GetContext(), ptr, prop, val, identifier)) { int index; - for (index=0; identifier[index]; index++) { - item= PyUnicode_FromString(identifier[index]); + for (index = 0; identifier[index]; index++) { + item = PyUnicode_FromString(identifier[index]); PySet_Add(ret, item); Py_DECREF(item); } @@ -1257,20 +1269,20 @@ else { const char *identifier; if (RNA_property_enum_identifier(BPy_GetContext(), ptr, prop, val, &identifier)) { - ret= PyUnicode_FromString(identifier); + ret = PyUnicode_FromString(identifier); } else { EnumPropertyItem *enum_item; - int free= FALSE; + int free = FALSE; /* don't throw error here, can't trust blender 100% to give the * right values, python code should not generate error for that */ RNA_property_enum_items(BPy_GetContext(), ptr, prop, &enum_item, NULL, &free); if (enum_item && enum_item->identifier) { - ret= PyUnicode_FromString(enum_item->identifier); + ret = PyUnicode_FromString(enum_item->identifier); } else { - const char *ptr_name= RNA_struct_name_get_alloc(ptr, NULL, 0, NULL); + const char *ptr_name = RNA_struct_name_get_alloc(ptr, NULL, 0, NULL); /* prefer not fail silently incase of api errors, maybe disable it later */ printf("RNA Warning: Current value \"%d\" " @@ -1292,7 +1304,7 @@ if (ptr_name) MEM_freeN((void *)ptr_name); - ret= PyUnicode_FromString(""); + ret = PyUnicode_FromString(""); } if (free) @@ -1300,7 +1312,7 @@ /* PyErr_Format(PyExc_AttributeError, "RNA Error: Current value \"%d\" matches no enum", val); - ret= NULL; + ret = NULL; */ } } @@ -1311,7 +1323,7 @@ PyObject *pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop) { PyObject *ret; - const int type= RNA_property_type(prop); + const int type = RNA_property_type(prop); if (RNA_property_array_check(prop)) { return pyrna_py_from_array(ptr, prop); @@ -1320,39 +1332,39 @@ /* see if we can coorce into a python type - PropertyType */ switch (type) { case PROP_BOOLEAN: - ret= PyBool_FromLong(RNA_property_boolean_get(ptr, prop)); + ret = PyBool_FromLong(RNA_property_boolean_get(ptr, prop)); break; case PROP_INT: - ret= PyLong_FromSsize_t((Py_ssize_t)RNA_property_int_get(ptr, prop)); + ret = PyLong_FromSsize_t((Py_ssize_t)RNA_property_int_get(ptr, prop)); break; case PROP_FLOAT: - ret= PyFloat_FromDouble(RNA_property_float_get(ptr, prop)); + ret = PyFloat_FromDouble(RNA_property_float_get(ptr, prop)); break; case PROP_STRING: { - const int subtype= RNA_property_subtype(prop); + const int subtype = RNA_property_subtype(prop); const char *buf; int buf_len; char buf_fixed[32]; - buf= RNA_property_string_get_alloc(ptr, prop, buf_fixed, sizeof(buf_fixed), &buf_len); + buf = RNA_property_string_get_alloc(ptr, prop, buf_fixed, sizeof(buf_fixed), &buf_len); #ifdef USE_STRING_COERCE /* only file paths get special treatment, they may contain non utf-8 chars */ if (subtype == PROP_BYTESTRING) { - ret= PyBytes_FromStringAndSize(buf, buf_len); + ret = PyBytes_FromStringAndSize(buf, buf_len); } else if (ELEM3(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) { - ret= PyC_UnicodeFromByteAndSize(buf, buf_len); + ret = PyC_UnicodeFromByteAndSize(buf, buf_len); } else { - ret= PyUnicode_FromStringAndSize(buf, buf_len); + ret = PyUnicode_FromStringAndSize(buf, buf_len); } #else // USE_STRING_COERCE if (subtype == PROP_BYTESTRING) { - ret= PyBytes_FromStringAndSize(buf, buf_len); + ret = PyBytes_FromStringAndSize(buf, buf_len); } else { - ret= PyUnicode_FromStringAndSize(buf, buf_len); + ret = PyUnicode_FromStringAndSize(buf, buf_len); } #endif // USE_STRING_COERCE if (buf_fixed != buf) { @@ -1362,29 +1374,29 @@ } case PROP_ENUM: { - ret= pyrna_enum_to_py(ptr, prop, RNA_property_enum_get(ptr, prop)); + ret = pyrna_enum_to_py(ptr, prop, RNA_property_enum_get(ptr, prop)); break; } case PROP_POINTER: { PointerRNA newptr; - newptr= RNA_property_pointer_get(ptr, prop); + newptr = RNA_property_pointer_get(ptr, prop); if (newptr.data) { - ret= pyrna_struct_CreatePyObject(&newptr); + ret = pyrna_struct_CreatePyObject(&newptr); } else { - ret= Py_None; + ret = Py_None; Py_INCREF(ret); } break; } case PROP_COLLECTION: - ret= pyrna_prop_CreatePyObject(ptr, prop); + ret = pyrna_prop_CreatePyObject(ptr, prop); break; default: PyErr_Format(PyExc_TypeError, "bpy_struct internal error: unknown type '%d' (pyrna_prop_to_py)", type); - ret= NULL; + ret = NULL; break; } @@ -1395,40 +1407,40 @@ * Its takes keyword args and fills them with property values */ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const char *error_prefix) { - int error_val= 0; + int error_val = 0; int totkw; - const char *arg_name= NULL; + const char *arg_name = NULL; PyObject *item; - totkw= kw ? PyDict_Size(kw):0; + totkw = kw ? PyDict_Size(kw):0; RNA_STRUCT_BEGIN(ptr, prop) { - arg_name= RNA_property_identifier(prop); + arg_name = RNA_property_identifier(prop); - if (strcmp(arg_name, "rna_type")==0) continue; + if (strcmp(arg_name, "rna_type") == 0) continue; - if (kw==NULL) { + if (kw == NULL) { PyErr_Format(PyExc_TypeError, "%.200s: no keywords, expected \"%.200s\"", error_prefix, arg_name ? arg_name : ""); - error_val= -1; + error_val = -1; break; } - item= PyDict_GetItemString(kw, arg_name); /* wont set an error */ + item = PyDict_GetItemString(kw, arg_name); /* wont set an error */ if (item == NULL) { if (all_args) { PyErr_Format(PyExc_TypeError, "%.200s: keyword \"%.200s\" missing", error_prefix, arg_name ? arg_name : ""); - error_val= -1; /* pyrna_py_to_prop sets the error */ + error_val = -1; /* pyrna_py_to_prop sets the error */ break; } } else { if (pyrna_py_to_prop(ptr, prop, NULL, item, error_prefix)) { - error_val= -1; + error_val = -1; break; } totkw--; @@ -1436,20 +1448,20 @@ } RNA_STRUCT_END; - if (error_val==0 && totkw > 0) { /* some keywords were given that were not used :/ */ + if (error_val == 0 && totkw > 0) { /* some keywords were given that were not used :/ */ PyObject *key, *value; - Py_ssize_t pos= 0; + Py_ssize_t pos = 0; while (PyDict_Next(kw, &pos, &key, &value)) { - arg_name= _PyUnicode_AsString(key); + arg_name = _PyUnicode_AsString(key); if (RNA_struct_find_property(ptr, arg_name) == NULL) break; - arg_name= NULL; + arg_name = NULL; } PyErr_Format(PyExc_TypeError, "%.200s: keyword \"%.200s\" unrecognized", error_prefix, arg_name ? arg_name : ""); - error_val= -1; + error_val = -1; } return error_val; @@ -1458,9 +1470,9 @@ static PyObject *pyrna_func_to_py(PointerRNA *ptr, FunctionRNA *func) { - BPy_FunctionRNA* pyfunc= (BPy_FunctionRNA *) PyObject_NEW(BPy_FunctionRNA, &pyrna_func_Type); - pyfunc->ptr= *ptr; - pyfunc->func= func; + BPy_FunctionRNA* pyfunc = (BPy_FunctionRNA *) PyObject_NEW(BPy_FunctionRNA, &pyrna_func_Type); + pyfunc->ptr = *ptr; + pyfunc->func = func; return (PyObject *)pyfunc; } @@ -1468,7 +1480,7 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value, const char *error_prefix) { /* XXX hard limits should be checked here */ - const int type= RNA_property_type(prop); + const int type = RNA_property_type(prop); if (RNA_property_array_check(prop)) { @@ -1489,9 +1501,9 @@ * however so many poll functions return None or a valid Object. * its a hassle to convert these into a bool before returning, */ if (RNA_property_flag(prop) & PROP_OUTPUT) - param= PyObject_IsTrue(value); + param = PyObject_IsTrue(value); else - param= PyLong_AsLong(value); + param = PyLong_AsLong(value); if (param < 0) { PyErr_Format(PyExc_TypeError, @@ -1501,7 +1513,7 @@ return -1; } else { - if (data) *((int*)data)= param; + if (data) *((int *)data)= param; else RNA_property_boolean_set(ptr, prop, param); } break; @@ -1509,7 +1521,7 @@ case PROP_INT: { int overflow; - long param= PyLong_AsLongAndOverflow(value, &overflow); + long param = PyLong_AsLongAndOverflow(value, &overflow); if (overflow || (param > INT_MAX) || (param < INT_MIN)) { PyErr_Format(PyExc_ValueError, "%.200s %.200s.%.200s value not in 'int' range " @@ -1518,7 +1530,7 @@ RNA_property_identifier(prop)); return -1; } - else if (param==-1 && PyErr_Occurred()) { + else if (param == -1 && PyErr_Occurred()) { PyErr_Format(PyExc_TypeError, "%.200s %.200s.%.200s expected an int type, not %.200s", error_prefix, RNA_struct_identifier(ptr->type), @@ -1526,16 +1538,16 @@ return -1; } else { - int param_i= (int)param; + int param_i = (int)param; RNA_property_int_clamp(ptr, prop, ¶m_i); - if (data) *((int*)data)= param_i; + if (data) *((int *)data)= param_i; else RNA_property_int_set(ptr, prop, param_i); } break; } case PROP_FLOAT: { - float param= PyFloat_AsDouble(value); + float param = PyFloat_AsDouble(value); if (PyErr_Occurred()) { PyErr_Format(PyExc_TypeError, "%.200s %.200s.%.200s expected a float type, not %.200s", @@ -1545,23 +1557,23 @@ } else { RNA_property_float_clamp(ptr, prop, (float *)¶m); - if (data) *((float*)data)= param; + if (data) *((float *)data)= param; else RNA_property_float_set(ptr, prop, param); } break; } case PROP_STRING: { - const int subtype= RNA_property_subtype(prop); + const int subtype = RNA_property_subtype(prop); const char *param; if (subtype == PROP_BYTESTRING) { /* Byte String */ - param= PyBytes_AsString(value); + param = PyBytes_AsString(value); - if (param==NULL) { + if (param == NULL) { if (PyBytes_Check(value)) { /* there was an error assigning a string type, * rather than setting a new error, prefix the existing one @@ -1582,7 +1594,7 @@ } else { /* same as unicode */ - if (data) *((char**)data)= (char *)param; /*XXX, this is suspect but needed for function calls, need to see if theres a better way */ + if (data) *((char **)data)= (char *)param; /*XXX, this is suspect but needed for function calls, need to see if theres a better way */ else RNA_property_string_set(ptr, prop, param); } } @@ -1591,25 +1603,25 @@ /* Unicode String */ #ifdef USE_STRING_COERCE - PyObject *value_coerce= NULL; + PyObject *value_coerce = NULL; if (ELEM3(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) { /* TODO, get size */ - param= PyC_UnicodeAsByte(value, &value_coerce); + param = PyC_UnicodeAsByte(value, &value_coerce); } else { - param= _PyUnicode_AsString(value); + param = _PyUnicode_AsString(value); #ifdef WITH_INTERNATIONAL if (subtype == PROP_TRANSLATE) { - param= IFACE_(param); + param = IFACE_(param); } #endif // WITH_INTERNATIONAL } #else // USE_STRING_COERCE - param= _PyUnicode_AsString(value); + param = _PyUnicode_AsString(value); #endif // USE_STRING_COERCE - if (param==NULL) { + if (param == NULL) { if (PyUnicode_Check(value)) { /* there was an error assigning a string type, * rather than setting a new error, prefix the existing one @@ -1630,7 +1642,7 @@ } else { /* same as bytes */ - if (data) *((char**)data)= (char *)param; /*XXX, this is suspect but needed for function calls, need to see if theres a better way */ + if (data) *((char **)data)= (char *)param; /*XXX, this is suspect but needed for function calls, need to see if theres a better way */ else RNA_property_string_set(ptr, prop, param); } #ifdef USE_STRING_COERCE @@ -1641,7 +1653,7 @@ } case PROP_ENUM: { - int val= 0; + int val = 0; /* type checkins is done by each function */ if (RNA_property_flag(prop) & PROP_ENUM_FLAG) { @@ -1652,22 +1664,22 @@ } else { /* simple enum string */ - if (!pyrna_string_to_enum(value, ptr, prop, &val, error_prefix) < 0) { + if (pyrna_string_to_enum(value, ptr, prop, &val, error_prefix) < 0) { return -1; } } - if (data) *((int*)data)= val; + if (data) *((int *)data)= val; else RNA_property_enum_set(ptr, prop, val); break; } case PROP_POINTER: { - PyObject *value_new= NULL; + PyObject *value_new = NULL; - StructRNA *ptr_type= RNA_property_pointer_type(ptr, prop); - int flag= RNA_property_flag(prop); + StructRNA *ptr_type = RNA_property_pointer_type(ptr, prop); + int flag = RNA_property_flag(prop); /* this is really nasty!, so we can fake the operator having direct properties eg: * layout.prop(self, "filepath") @@ -1675,7 +1687,8 @@ * layout.prop(self.properties, "filepath") * * we need to do this trick. - * if the prop is not an operator type and the pyobject is an operator, use its properties in place of its self. + * if the prop is not an operator type and the pyobject is an operator, + * use its properties in place of its self. * * this is so bad that its almost a good reason to do away with fake 'self.properties -> self' class mixing * if this causes problems in the future it should be removed. @@ -1684,24 +1697,25 @@ (BPy_StructRNA_Check(value)) && (RNA_struct_is_a(((BPy_StructRNA *)value)->ptr.type, &RNA_Operator)) ) { - value= PyObject_GetAttrString(value, "properties"); - value_new= value; + value = PyObject_GetAttrString(value, "properties"); + value_new = value; } - /* if property is an OperatorProperties pointer and value is a map, forward back to pyrna_pydict_to_props */ + /* if property is an OperatorProperties pointer and value is a map, + * forward back to pyrna_pydict_to_props */ if (RNA_struct_is_a(ptr_type, &RNA_OperatorProperties) && PyDict_Check(value)) { - PointerRNA opptr= RNA_property_pointer_get(ptr, prop); + PointerRNA opptr = RNA_property_pointer_get(ptr, prop); return pyrna_pydict_to_props(&opptr, value, 0, error_prefix); } /* another exception, allow to pass a collection as an RNA property */ - if (Py_TYPE(value)==&pyrna_prop_collection_Type) { /* ok to ignore idprop collections */ + if (Py_TYPE(value) == &pyrna_prop_collection_Type) { /* ok to ignore idprop collections */ PointerRNA c_ptr; - BPy_PropertyRNA *value_prop= (BPy_PropertyRNA *)value; + BPy_PropertyRNA *value_prop = (BPy_PropertyRNA *)value; if (RNA_property_collection_type_get(&value_prop->ptr, value_prop->prop, &c_ptr)) { - value= pyrna_struct_CreatePyObject(&c_ptr); - value_new= value; + value = pyrna_struct_CreatePyObject(&c_ptr); + value_new = value; } else { PyErr_Format(PyExc_TypeError, @@ -1728,7 +1742,9 @@ RNA_property_identifier(prop), RNA_struct_identifier(ptr_type)); Py_XDECREF(value_new); return -1; } - else if (value != Py_None && ((flag & PROP_ID_SELF_CHECK) && ptr->id.data == ((BPy_StructRNA*)value)->ptr.id.data)) { + else if ((value != Py_None) && + ((flag & PROP_ID_SELF_CHECK) && ptr->id.data == ((BPy_StructRNA *)value)->ptr.id.data)) + { PyErr_Format(PyExc_TypeError, "%.200s %.200s.%.200s ID type does not support assignment to its self", error_prefix, RNA_struct_identifier(ptr->type), @@ -1736,30 +1752,30 @@ Py_XDECREF(value_new); return -1; } else { - BPy_StructRNA *param= (BPy_StructRNA*)value; - int raise_error= FALSE; + BPy_StructRNA *param = (BPy_StructRNA *)value; + int raise_error = FALSE; if (data) { if (flag & PROP_RNAPTR) { if (value == Py_None) memset(data, 0, sizeof(PointerRNA)); else - *((PointerRNA*)data)= param->ptr; + *((PointerRNA *)data)= param->ptr; } else if (value == Py_None) { - *((void**)data)= NULL; + *((void **)data)= NULL; } else if (RNA_struct_is_a(param->ptr.type, ptr_type)) { - *((void**)data)= param->ptr.data; + *((void **)data)= param->ptr.data; } else { - raise_error= TRUE; + raise_error = TRUE; } } else { - /* data==NULL, assign to RNA */ + /* data == NULL, assign to RNA */ if (value == Py_None) { - PointerRNA valueptr= {{NULL}}; + PointerRNA valueptr = {{NULL}}; RNA_property_pointer_set(ptr, prop, valueptr); } else if (RNA_struct_is_a(param->ptr.type, ptr_type)) { @@ -1801,7 +1817,7 @@ ListBase *lb; CollectionPointerLink *link; - lb= (data)? (ListBase*)data: NULL; + lb = (data) ? (ListBase *)data : NULL; /* convert a sequence of dict's into a collection */ if (!PySequence_Check(value)) { @@ -1812,11 +1828,11 @@ return -1; } - seq_len= PySequence_Size(value); - for (i=0; i < seq_len; i++) { - item= PySequence_GetItem(value, i); + seq_len = PySequence_Size(value); + for (i = 0; i < seq_len; i++) { + item = PySequence_GetItem(value, i); - if (item==NULL) { + if (item == NULL) { PyErr_Format(PyExc_TypeError, "%.200s %.200s.%.200s failed to get sequence index '%d' for an RNA collection", error_prefix, RNA_struct_identifier(ptr->type), @@ -1825,7 +1841,7 @@ return -1; } - if (PyDict_Check(item)==0) { + if (PyDict_Check(item) == 0) { PyErr_Format(PyExc_TypeError, "%.200s %.200s.%.200s expected a each sequence " "member to be a dict for an RNA collection, not %.200s", @@ -1836,16 +1852,16 @@ } if (lb) { - link= MEM_callocN(sizeof(CollectionPointerLink), "PyCollectionPointerLink"); - link->ptr= itemptr; + link = MEM_callocN(sizeof(CollectionPointerLink), "PyCollectionPointerLink"); + link->ptr = itemptr; BLI_addtail(lb, link); } else RNA_property_collection_add(ptr, prop, &itemptr); - if (pyrna_pydict_to_props(&itemptr, item, 1, "Converting a python list to an RNA collection")==-1) { - PyObject *msg= PyC_ExceptionBuffer(); - const char *msg_char= _PyUnicode_AsString(msg); + if (pyrna_pydict_to_props(&itemptr, item, 1, "Converting a python list to an RNA collection") == -1) { + PyObject *msg = PyC_ExceptionBuffer(); + const char *msg_char = _PyUnicode_AsString(msg); PyErr_Format(PyExc_TypeError, "%.200s %.200s.%.200s error converting a member of a collection " @@ -1888,17 +1904,17 @@ static int pyrna_py_to_prop_array_index(BPy_PropertyArrayRNA *self, int index, PyObject *value) { - int ret= 0; - PointerRNA *ptr= &self->ptr; - PropertyRNA *prop= self->prop; + int ret = 0; + PointerRNA *ptr = &self->ptr; + PropertyRNA *prop = self->prop; - const int totdim= RNA_property_array_dimension(ptr, prop, NULL); + const int totdim = RNA_property_array_dimension(ptr, prop, NULL); if (totdim > 1) { /* char error_str[512]; */ if (pyrna_py_to_array_index(&self->ptr, self->prop, self->arraydim, self->arrayoffset, index, value, "") == -1) { /* error is set */ - ret= -1; + ret = -1; } } else { @@ -1906,11 +1922,11 @@ switch (RNA_property_type(prop)) { case PROP_BOOLEAN: { - int param= PyLong_AsLong(value); + int param = PyLong_AsLong(value); if (param < 0 || param > 1) { PyErr_SetString(PyExc_TypeError, "expected True/False or 0/1"); - ret= -1; + ret = -1; } else { RNA_property_boolean_set_index(ptr, prop, index, param); @@ -1919,10 +1935,10 @@ } case PROP_INT: { - int param= PyLong_AsLong(value); - if (param==-1 && PyErr_Occurred()) { + int param = PyLong_AsLong(value); + if (param == -1 && PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "expected an int type"); - ret= -1; + ret = -1; } else { RNA_property_int_clamp(ptr, prop, ¶m); @@ -1932,10 +1948,10 @@ } case PROP_FLOAT: { - float param= PyFloat_AsDouble(value); + float param = PyFloat_AsDouble(value); if (PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "expected a float type"); - ret= -1; + ret = -1; } else { RNA_property_float_clamp(ptr, prop, ¶m); @@ -1945,7 +1961,7 @@ } default: PyErr_SetString(PyExc_AttributeError, "not an array type"); - ret= -1; + ret = -1; break; } } @@ -1994,7 +2010,7 @@ PYRNA_PROP_CHECK_INT(self); RNA_property_collection_begin(&self->ptr, self->prop, &iter); - test= iter.valid; + test = iter.valid; RNA_property_collection_end(&iter); return test; } @@ -2018,7 +2034,7 @@ static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_ssize_t keynum) { PointerRNA newptr; - Py_ssize_t keynum_abs= keynum; + Py_ssize_t keynum_abs = keynum; PYRNA_PROP_CHECK_OBJ(self); @@ -2028,7 +2044,7 @@ return pyrna_struct_CreatePyObject(&newptr); } else { - const int len= RNA_property_collection_length(&self->ptr, self->prop); + const int len = RNA_property_collection_length(&self->ptr, self->prop); if (keynum_abs >= len) { PyErr_Format(PyExc_IndexError, "bpy_prop_collection[index]: " @@ -2048,15 +2064,15 @@ /* values type must have been already checked */ static int pyrna_prop_collection_ass_subscript_int(BPy_PropertyRNA *self, Py_ssize_t keynum, PyObject *value) { - Py_ssize_t keynum_abs= keynum; - const PointerRNA *ptr= (value == Py_None) ? (&PointerRNA_NULL) : &((BPy_StructRNA *)value)->ptr; + Py_ssize_t keynum_abs = keynum; + const PointerRNA *ptr = (value == Py_None) ? (&PointerRNA_NULL) : &((BPy_StructRNA *)value)->ptr; PYRNA_PROP_CHECK_INT(self); PYRNA_PROP_COLLECTION_ABS_INDEX(-1); if (RNA_property_collection_assign_int(&self->ptr, self->prop, keynum_abs, ptr) == 0) { - const int len= RNA_property_collection_length(&self->ptr, self->prop); + const int len = RNA_property_collection_length(&self->ptr, self->prop); if (keynum_abs >= len) { PyErr_Format(PyExc_IndexError, "bpy_prop_collection[index] = value: " @@ -2080,7 +2096,7 @@ PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self); - len= pyrna_prop_array_length(self); + len = pyrna_prop_array_length(self); if (keynum < 0) keynum += len; @@ -2135,24 +2151,24 @@ err_prefix, RNA_struct_identifier(self->ptr.type)); return -1; } - else if ((keyname= _PyUnicode_AsString(PyTuple_GET_ITEM(key, 0))) == NULL) { + else if ((keyname = _PyUnicode_AsString(PyTuple_GET_ITEM(key, 0))) == NULL) { PyErr_Format(PyExc_KeyError, "%s: id must be a string, not %.200s", err_prefix, Py_TYPE(PyTuple_GET_ITEM(key, 0))->tp_name); return -1; } else { - PyObject *keylib= PyTuple_GET_ITEM(key, 1); + PyObject *keylib = PyTuple_GET_ITEM(key, 1); Library *lib; - int found= FALSE; + int found = FALSE; if (keylib == Py_None) { - lib= NULL; + lib = NULL; } else if (PyUnicode_Check(keylib)) { - Main *bmain= self->ptr.data; - const char *keylib_str= _PyUnicode_AsString(keylib); - lib= BLI_findstring(&bmain->library, keylib_str, offsetof(Library, name)); + Main *bmain = self->ptr.data; + const char *keylib_str = _PyUnicode_AsString(keylib); + lib = BLI_findstring(&bmain->library, keylib_str, offsetof(Library, name)); if (lib == NULL) { if (err_not_found) { PyErr_Format(PyExc_KeyError, @@ -2178,11 +2194,11 @@ * either way can do direct comparison with id.lib */ RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) { - ID *id= itemptr.data; /* always an ID */ - if (id->lib == lib && (strncmp(keyname, id->name+2, sizeof(id->name)-2) == 0)) { - found= TRUE; + ID *id = itemptr.data; /* always an ID */ + if (id->lib == lib && (strncmp(keyname, id->name + 2, sizeof(id->name) - 2) == 0)) { + found = TRUE; if (r_ptr) { - *r_ptr= itemptr; + *r_ptr = itemptr; } break; } @@ -2206,7 +2222,7 @@ const char *err_prefix, const short err_not_found) { PointerRNA ptr; - const int contains= pyrna_prop_collection_subscript_str_lib_pair_ptr(self, key, err_prefix, err_not_found, &ptr); + const int contains = pyrna_prop_collection_subscript_str_lib_pair_ptr(self, key, err_prefix, err_not_found, &ptr); if (contains == 1) { return pyrna_struct_CreatePyObject(&ptr); @@ -2220,21 +2236,21 @@ static PyObject *pyrna_prop_collection_subscript_slice(BPy_PropertyRNA *self, Py_ssize_t start, Py_ssize_t stop) { CollectionPropertyIterator rna_macro_iter; - int count= 0; + int count = 0; PyObject *list; PyObject *item; PYRNA_PROP_CHECK_OBJ(self); - list= PyList_New(0); + list = PyList_New(0); /* first loop up-until the start */ for (RNA_property_collection_begin(&self->ptr, self->prop, &rna_macro_iter); rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) { - /* PointerRNA itemptr= rna_macro_iter.ptr; */ + /* PointerRNA itemptr = rna_macro_iter.ptr; */ if (count == start) { break; } @@ -2245,7 +2261,7 @@ for (; rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) { - item= pyrna_struct_CreatePyObject(&rna_macro_iter.ptr); + item = pyrna_struct_CreatePyObject(&rna_macro_iter.ptr); PyList_Append(list, item); Py_DECREF(item); @@ -2272,14 +2288,14 @@ PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self); - tuple= PyTuple_New(stop - start); + tuple = PyTuple_New(stop - start); /* PYRNA_PROP_CHECK_OBJ(self); isn't needed, internal use only */ - totdim= RNA_property_array_dimension(ptr, prop, NULL); + totdim = RNA_property_array_dimension(ptr, prop, NULL); if (totdim > 1) { - for (count= start; count < stop; count++) + for (count = start; count < stop; count++) PyTuple_SET_ITEM(tuple, count - start, pyrna_prop_array_to_py_index(self, count)); } else { @@ -2288,11 +2304,11 @@ { float values_stack[PYRNA_STACK_ARRAY]; float *values; - if (length > PYRNA_STACK_ARRAY) { values= PyMem_MALLOC(sizeof(float) * length); } - else { values= values_stack; } + if (length > PYRNA_STACK_ARRAY) { values = PyMem_MALLOC(sizeof(float) * length); } + else { values = values_stack; } RNA_property_float_get_array(ptr, prop, values); - for (count=start; count PYRNA_STACK_ARRAY) { values= PyMem_MALLOC(sizeof(int) * length); } - else { values= values_stack; } + if (length > PYRNA_STACK_ARRAY) { values = PyMem_MALLOC(sizeof(int) * length); } + else { values = values_stack; } RNA_property_boolean_get_array(ptr, prop, values); - for (count=start; count PYRNA_STACK_ARRAY) { values= PyMem_MALLOC(sizeof(int) * length); } - else { values= values_stack; } + if (length > PYRNA_STACK_ARRAY) { values = PyMem_MALLOC(sizeof(int) * length); } + else { values = values_stack; } RNA_property_int_get_array(ptr, prop, values); - for (count=start; countstep != Py_None && !_PyEval_SliceIndex(key, &step)) { return NULL; @@ -2372,7 +2388,7 @@ return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX); } else { - Py_ssize_t start= 0, stop= PY_SSIZE_T_MAX; + Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX; /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */ if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) return NULL; @@ -2380,7 +2396,7 @@ if (start < 0 || stop < 0) { /* only get the length for negative values */ - Py_ssize_t len= (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop); + Py_ssize_t len = (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop); if (start < 0) start += len; if (stop < 0) start += len; } @@ -2431,8 +2447,8 @@ Py_TYPE(value)->tp_name); return -1; } - else if ((prop_srna= RNA_property_pointer_type(&self->ptr, self->prop))) { - StructRNA *value_srna= ((BPy_StructRNA *)value)->ptr.type; + else if ((prop_srna = RNA_property_pointer_type(&self->ptr, self->prop))) { + StructRNA *value_srna = ((BPy_StructRNA *)value)->ptr.type; if (RNA_struct_is_a(value_srna, prop_srna) == 0) { PyErr_Format(PyExc_TypeError, "bpy_prop_collection[key] = value: invalid, " @@ -2476,7 +2492,7 @@ else #endif if (PyIndex_Check(key)) { - Py_ssize_t i= PyNumber_AsSsize_t(key, PyExc_IndexError); + Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError); if (i == -1 && PyErr_Occurred()) return -1; @@ -2484,8 +2500,8 @@ } #if 0 /* TODO, fake slice assignment */ else if (PySlice_Check(key)) { - PySliceObject *key_slice= (PySliceObject *)key; - Py_ssize_t step= 1; + PySliceObject *key_slice = (PySliceObject *)key; + Py_ssize_t step = 1; if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) { return NULL; @@ -2498,7 +2514,7 @@ return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX); } else { - Py_ssize_t start= 0, stop= PY_SSIZE_T_MAX; + Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX; /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */ if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) return NULL; @@ -2506,7 +2522,7 @@ if (start < 0 || stop < 0) { /* only get the length for negative values */ - Py_ssize_t len= (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop); + Py_ssize_t len = (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop); if (start < 0) start += len; if (stop < 0) start += len; } @@ -2538,14 +2554,14 @@ } else */ if (PyIndex_Check(key)) { - Py_ssize_t i= PyNumber_AsSsize_t(key, PyExc_IndexError); + Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError); if (i == -1 && PyErr_Occurred()) return NULL; return pyrna_prop_array_subscript_int(self, PyLong_AsLong(key)); } else if (PySlice_Check(key)) { - Py_ssize_t step= 1; - PySliceObject *key_slice= (PySliceObject *)key; + Py_ssize_t step = 1; + PySliceObject *key_slice = (PySliceObject *)key; if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) { return NULL; @@ -2555,12 +2571,13 @@ return NULL; } else if (key_slice->start == Py_None && key_slice->stop == Py_None) { - /* note, no significant advantage with optimizing [:] slice as with collections but include here for consistency with collection slice func */ - Py_ssize_t len= (Py_ssize_t)pyrna_prop_array_length(self); + /* note, no significant advantage with optimizing [:] slice as with collections + * but include here for consistency with collection slice func */ + Py_ssize_t len = (Py_ssize_t)pyrna_prop_array_length(self); return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, 0, len, len); } else { - int len= pyrna_prop_array_length(self); + int len = pyrna_prop_array_length(self); Py_ssize_t start, stop, slicelength; if (PySlice_GetIndicesEx((void *)key, len, &start, &stop, &step, &slicelength) < 0) @@ -2586,23 +2603,23 @@ { PyObject *value; int count; - void *values_alloc= NULL; - int ret= 0; + void *values_alloc = NULL; + int ret = 0; if (value_orig == NULL) { PyErr_SetString(PyExc_TypeError, - "bpy_prop_array[slice]= value: deleting with list types is not supported by bpy_struct"); + "bpy_prop_array[slice] = value: deleting with list types is not supported by bpy_struct"); return -1; } - if (!(value=PySequence_Fast(value_orig, "bpy_prop_array[slice]= value: assignment is not a sequence type"))) { + if (!(value = PySequence_Fast(value_orig, "bpy_prop_array[slice] = value: assignment is not a sequence type"))) { return -1; } if (PySequence_Fast_GET_SIZE(value) != stop-start) { Py_DECREF(value); PyErr_SetString(PyExc_TypeError, - "bpy_prop_array[slice]= value: resizing bpy_struct arrays isn't supported"); + "bpy_prop_array[slice] = value: resizing bpy_struct arrays isn't supported"); return -1; } @@ -2615,18 +2632,18 @@ float min, max; RNA_property_float_range(ptr, prop, &min, &max); - if (length > PYRNA_STACK_ARRAY) { values= values_alloc= PyMem_MALLOC(sizeof(float) * length); } - else { values= values_stack; } + if (length > PYRNA_STACK_ARRAY) { values = values_alloc = PyMem_MALLOC(sizeof(float) * length); } + else { values = values_stack; } if (start != 0 || stop != length) /* partial assignment? - need to get the array */ RNA_property_float_get_array(ptr, prop, values); - for (count=start; count PYRNA_STACK_ARRAY) { values= values_alloc= PyMem_MALLOC(sizeof(int) * length); } - else { values= values_stack; } + if (length > PYRNA_STACK_ARRAY) { values = values_alloc = PyMem_MALLOC(sizeof(int) * length); } + else { values = values_stack; } if (start != 0 || stop != length) /* partial assignment? - need to get the array */ RNA_property_boolean_get_array(ptr, prop, values); - for (count=start; count PYRNA_STACK_ARRAY) { values= values_alloc= PyMem_MALLOC(sizeof(int) * length); } - else { values= values_stack; } + if (length > PYRNA_STACK_ARRAY) { values = values_alloc = PyMem_MALLOC(sizeof(int) * length); } + else { values = values_stack; } if (start != 0 || stop != length) /* partial assignment? - need to get the array */ RNA_property_int_get_array(ptr, prop, values); - for (count=start; countprop), RNA_struct_identifier(self->ptr.type)); - ret= -1; + ret = -1; } else if (PyIndex_Check(key)) { - Py_ssize_t i= PyNumber_AsSsize_t(key, PyExc_IndexError); + Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError); if (i == -1 && PyErr_Occurred()) { - ret= -1; + ret = -1; } else { - ret= prop_subscript_ass_array_int(self, i, value); + ret = prop_subscript_ass_array_int(self, i, value); } } else if (PySlice_Check(key)) { - int len= RNA_property_array_length(&self->ptr, self->prop); + int len = RNA_property_array_length(&self->ptr, self->prop); Py_ssize_t start, stop, step, slicelength; if (PySlice_GetIndicesEx((void *)key, len, &start, &stop, &step, &slicelength) < 0) { - ret= -1; + ret = -1; } else if (slicelength <= 0) { - ret= 0; /* do nothing */ + ret = 0; /* do nothing */ } else if (step == 1) { - ret= prop_subscript_ass_array_slice(&self->ptr, self->prop, start, stop, len, value); + ret = prop_subscript_ass_array_slice(&self->ptr, self->prop, start, stop, len, value); } else { PyErr_SetString(PyExc_TypeError, "slice steps not supported with rna"); - ret= -1; + ret = -1; } } else { PyErr_SetString(PyExc_AttributeError, "invalid key, key must be an int"); - ret= -1; + ret = -1; } if (ret != -1) { @@ -2760,20 +2777,20 @@ } /* for slice only */ -static PyMappingMethods pyrna_prop_array_as_mapping= { +static PyMappingMethods pyrna_prop_array_as_mapping = { (lenfunc) pyrna_prop_array_length, /* mp_length */ (binaryfunc) pyrna_prop_array_subscript, /* mp_subscript */ (objobjargproc) pyrna_prop_array_ass_subscript, /* mp_ass_subscript */ }; -static PyMappingMethods pyrna_prop_collection_as_mapping= { +static PyMappingMethods pyrna_prop_collection_as_mapping = { (lenfunc) pyrna_prop_collection_length, /* mp_length */ (binaryfunc) pyrna_prop_collection_subscript, /* mp_subscript */ (objobjargproc) pyrna_prop_collection_ass_subscript, /* mp_ass_subscript */ }; /* only for fast bool's, large structs, assign nb_bool on init */ -static PyNumberMethods pyrna_prop_array_as_number= { +static PyNumberMethods pyrna_prop_array_as_number = { NULL, /* nb_add */ NULL, /* nb_subtract */ NULL, /* nb_multiply */ @@ -2785,7 +2802,7 @@ NULL, /* nb_absolute */ (inquiry) pyrna_prop_array_bool, /* nb_bool */ }; -static PyNumberMethods pyrna_prop_collection_as_number= { +static PyNumberMethods pyrna_prop_collection_as_number = { NULL, /* nb_add */ NULL, /* nb_subtract */ NULL, /* nb_multiply */ @@ -2815,10 +2832,11 @@ else { /* key in dict style check */ - const char *keyname= _PyUnicode_AsString(key); + const char *keyname = _PyUnicode_AsString(key); - if (keyname==NULL) { - PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.__contains__: expected a string or a typle of strings"); + if (keyname == NULL) { + PyErr_SetString(PyExc_TypeError, + "bpy_prop_collection.__contains__: expected a string or a typle of strings"); return -1; } @@ -2832,7 +2850,7 @@ static int pyrna_struct_contains(BPy_StructRNA *self, PyObject *value) { IDProperty *group; - const char *name= _PyUnicode_AsString(value); + const char *name = _PyUnicode_AsString(value); PYRNA_STRUCT_CHECK_INT(self); @@ -2841,12 +2859,12 @@ return -1; } - if (RNA_struct_idprops_check(self->ptr.type)==0) { + if (RNA_struct_idprops_check(self->ptr.type) == 0) { PyErr_SetString(PyExc_TypeError, "bpy_struct: this type doesn't support IDProperties"); return -1; } - group= RNA_struct_idprops(&self->ptr, 0); + group = RNA_struct_idprops(&self->ptr, 0); if (!group) return 0; @@ -2854,7 +2872,7 @@ return IDP_GetPropertyFromGroup(group, name) ? 1:0; } -static PySequenceMethods pyrna_prop_array_as_sequence= { +static PySequenceMethods pyrna_prop_array_as_sequence = { (lenfunc)pyrna_prop_array_length, /* Cant set the len otherwise it can evaluate as false */ NULL, /* sq_concat */ NULL, /* sq_repeat */ @@ -2867,7 +2885,7 @@ (ssizeargfunc) NULL, /* sq_inplace_repeat */ }; -static PySequenceMethods pyrna_prop_collection_as_sequence= { +static PySequenceMethods pyrna_prop_collection_as_sequence = { (lenfunc)pyrna_prop_collection_length, /* Cant set the len otherwise it can evaluate as false */ NULL, /* sq_concat */ NULL, /* sq_repeat */ @@ -2880,7 +2898,7 @@ (ssizeargfunc) NULL, /* sq_inplace_repeat */ }; -static PySequenceMethods pyrna_struct_as_sequence= { +static PySequenceMethods pyrna_struct_as_sequence = { NULL, /* Cant set the len otherwise it can evaluate as false */ NULL, /* sq_concat */ NULL, /* sq_repeat */ @@ -2897,30 +2915,30 @@ { /* mostly copied from BPy_IDGroup_Map_GetItem */ IDProperty *group, *idprop; - const char *name= _PyUnicode_AsString(key); + const char *name = _PyUnicode_AsString(key); PYRNA_STRUCT_CHECK_OBJ(self); - if (RNA_struct_idprops_check(self->ptr.type)==0) { + if (RNA_struct_idprops_check(self->ptr.type) == 0) { PyErr_SetString(PyExc_TypeError, "this type doesn't support IDProperties"); return NULL; } - if (name==NULL) { + if (name == NULL) { PyErr_SetString(PyExc_TypeError, "bpy_struct[key]: only strings are allowed as keys of ID properties"); return NULL; } - group= RNA_struct_idprops(&self->ptr, 0); + group = RNA_struct_idprops(&self->ptr, 0); - if (group==NULL) { + if (group == NULL) { PyErr_Format(PyExc_KeyError, "bpy_struct[key]: key \"%s\" not found", name); return NULL; } - idprop= IDP_GetPropertyFromGroup(group, name); + idprop = IDP_GetPropertyFromGroup(group, name); - if (idprop==NULL) { + if (idprop == NULL) { PyErr_Format(PyExc_KeyError, "bpy_struct[key]: key \"%s\" not found", name); return NULL; } @@ -2934,7 +2952,7 @@ PYRNA_STRUCT_CHECK_INT(self); - group= RNA_struct_idprops(&self->ptr, 1); + group = RNA_struct_idprops(&self->ptr, 1); #ifdef USE_PEDANTIC_WRITE if (rna_disallow_writes && rna_id_write_error(&self->ptr, key)) { @@ -2942,15 +2960,15 @@ } #endif // USE_PEDANTIC_WRITE - if (group==NULL) { - PyErr_SetString(PyExc_TypeError, "bpy_struct[key]= val: id properties not supported for this type"); + if (group == NULL) { + PyErr_SetString(PyExc_TypeError, "bpy_struct[key] = val: id properties not supported for this type"); return -1; } return BPy_Wrap_SetMapItem(group, key, value); } -static PyMappingMethods pyrna_struct_as_mapping= { +static PyMappingMethods pyrna_struct_as_mapping = { (lenfunc) NULL, /* mp_length */ (binaryfunc) pyrna_struct_subscript, /* mp_subscript */ (objobjargproc) pyrna_struct_ass_subscript, /* mp_ass_subscript */ @@ -2971,14 +2989,14 @@ { IDProperty *group; - if (RNA_struct_idprops_check(self->ptr.type)==0) { + if (RNA_struct_idprops_check(self->ptr.type) == 0) { PyErr_SetString(PyExc_TypeError, "bpy_struct.keys(): this type doesn't support IDProperties"); return NULL; } - group= RNA_struct_idprops(&self->ptr, 0); + group = RNA_struct_idprops(&self->ptr, 0); - if (group==NULL) + if (group == NULL) return PyList_New(0); return BPy_Wrap_GetKeys(group); @@ -2999,14 +3017,14 @@ { IDProperty *group; - if (RNA_struct_idprops_check(self->ptr.type)==0) { + if (RNA_struct_idprops_check(self->ptr.type) == 0) { PyErr_SetString(PyExc_TypeError, "bpy_struct.items(): this type doesn't support IDProperties"); return NULL; } - group= RNA_struct_idprops(&self->ptr, 0); + group = RNA_struct_idprops(&self->ptr, 0); - if (group==NULL) + if (group == NULL) return PyList_New(0); return BPy_Wrap_GetItems(self->ptr.id.data, group); @@ -3027,14 +3045,14 @@ { IDProperty *group; - if (RNA_struct_idprops_check(self->ptr.type)==0) { + if (RNA_struct_idprops_check(self->ptr.type) == 0) { PyErr_SetString(PyExc_TypeError, "bpy_struct.values(): this type doesn't support IDProperties"); return NULL; } - group= RNA_struct_idprops(&self->ptr, 0); + group = RNA_struct_idprops(&self->ptr, 0); - if (group==NULL) + if (group == NULL) return PyList_New(0); return BPy_Wrap_GetValues(self->ptr.id.data, group); @@ -3053,36 +3071,20 @@ { PropertyRNA *prop; const char *name; - int ret; PYRNA_STRUCT_CHECK_OBJ(self); if (!PyArg_ParseTuple(args, "s:is_property_set", &name)) return NULL; - if ((prop= RNA_struct_find_property(&self->ptr, name)) == NULL) { + if ((prop = RNA_struct_find_property(&self->ptr, name)) == NULL) { PyErr_Format(PyExc_TypeError, "%.200s.is_property_set(\"%.200s\") not found", RNA_struct_identifier(self->ptr.type), name); return NULL; } - /* double property lookup, could speed up */ - /* return PyBool_FromLong(RNA_property_is_set(&self->ptr, name)); */ - if (RNA_property_flag(prop) & PROP_IDPROPERTY) { - IDProperty *group= RNA_struct_idprops(&self->ptr, 0); - if (group) { - ret= IDP_GetPropertyFromGroup(group, name) ? 1:0; - } - else { - ret= 0; - } - } - else { - ret= 1; - } - - return PyBool_FromLong(ret); + return PyBool_FromLong(RNA_property_is_set(&self->ptr, prop)); } PyDoc_STRVAR(pyrna_struct_is_property_hidden_doc, @@ -3103,7 +3105,7 @@ if (!PyArg_ParseTuple(args, "s:is_property_hidden", &name)) return NULL; - if ((prop= RNA_struct_find_property(&self->ptr, name)) == NULL) { + if ((prop = RNA_struct_find_property(&self->ptr, name)) == NULL) { PyErr_Format(PyExc_TypeError, "%.200s.is_property_hidden(\"%.200s\") not found", RNA_struct_identifier(self->ptr.type), name); @@ -3127,10 +3129,10 @@ static PyObject *pyrna_struct_path_resolve(BPy_StructRNA *self, PyObject *args) { const char *path; - PyObject *coerce= Py_True; + PyObject *coerce = Py_True; PointerRNA r_ptr; PropertyRNA *r_prop; - int index= -1; + int index = -1; PYRNA_STRUCT_CHECK_OBJ(self); @@ -3185,7 +3187,7 @@ ); static PyObject *pyrna_struct_path_from_id(BPy_StructRNA *self, PyObject *args) { - const char *name= NULL; + const char *name = NULL; const char *path; PropertyRNA *prop; PyObject *ret; @@ -3196,21 +3198,21 @@ return NULL; if (name) { - prop= RNA_struct_find_property(&self->ptr, name); - if (prop==NULL) { + prop = RNA_struct_find_property(&self->ptr, name); + if (prop == NULL) { PyErr_Format(PyExc_AttributeError, "%.200s.path_from_id(\"%.200s\") not found", RNA_struct_identifier(self->ptr.type), name); return NULL; } - path= RNA_path_from_ID_to_property(&self->ptr, prop); + path = RNA_path_from_ID_to_property(&self->ptr, prop); } else { - path= RNA_path_from_ID_to_struct(&self->ptr); + path = RNA_path_from_ID_to_struct(&self->ptr); } - if (path==NULL) { + if (path == NULL) { if (name) { PyErr_Format(PyExc_ValueError, "%.200s.path_from_id(\"%s\") found but does not support path creation", @@ -3224,7 +3226,7 @@ return NULL; } - ret= PyUnicode_FromString(path); + ret = PyUnicode_FromString(path); MEM_freeN((void *)path); return ret; @@ -3241,19 +3243,19 @@ static PyObject *pyrna_prop_path_from_id(BPy_PropertyRNA *self) { const char *path; - PropertyRNA *prop= self->prop; + PropertyRNA *prop = self->prop; PyObject *ret; - path= RNA_path_from_ID_to_property(&self->ptr, self->prop); + path = RNA_path_from_ID_to_property(&self->ptr, self->prop); - if (path==NULL) { + if (path == NULL) { PyErr_Format(PyExc_ValueError, "%.200s.%.200s.path_from_id() does not support path creation for this type", RNA_struct_identifier(self->ptr.type), RNA_property_identifier(prop)); return NULL; } - ret= PyUnicode_FromString(path); + ret = PyUnicode_FromString(path); MEM_freeN((void *)path); return ret; @@ -3284,17 +3286,17 @@ PyObject **dict_ptr; PyObject *list_tmp; - dict_ptr= _PyObject_GetDictPtr((PyObject *)self); + dict_ptr = _PyObject_GetDictPtr((PyObject *)self); - if (dict_ptr && (dict=*dict_ptr)) { - list_tmp= PyDict_Keys(dict); + if (dict_ptr && (dict = *dict_ptr)) { + list_tmp = PyDict_Keys(dict); PyList_SetSlice(list, INT_MAX, INT_MAX, list_tmp); Py_DECREF(list_tmp); } - dict= ((PyTypeObject *)Py_TYPE(self))->tp_dict; + dict = ((PyTypeObject *)Py_TYPE(self))->tp_dict; if (dict) { - list_tmp= PyDict_Keys(dict); + list_tmp = PyDict_Keys(dict); PyList_SetSlice(list, INT_MAX, INT_MAX, list_tmp); Py_DECREF(list_tmp); } @@ -3311,12 +3313,12 @@ { RNA_pointer_create(NULL, &RNA_Struct, ptr->type, &tptr); - iterprop= RNA_struct_find_property(&tptr, "functions"); + iterprop = RNA_struct_find_property(&tptr, "functions"); RNA_PROP_BEGIN(&tptr, itemptr, iterprop) { - idname= RNA_function_identifier(itemptr.data); + idname = RNA_function_identifier(itemptr.data); - pystring= PyUnicode_FromString(idname); + pystring = PyUnicode_FromString(idname); PyList_Append(list, pystring); Py_DECREF(pystring); } @@ -3330,13 +3332,13 @@ char name[256], *nameptr; int namelen; - iterprop= RNA_struct_iterator_property(ptr->type); + iterprop = RNA_struct_iterator_property(ptr->type); RNA_PROP_BEGIN(ptr, itemptr, iterprop) { - nameptr= RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen); + nameptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen); if (nameptr) { - pystring= PyUnicode_FromStringAndSize(nameptr, namelen); + pystring = PyUnicode_FromStringAndSize(nameptr, namelen); PyList_Append(list, pystring); Py_DECREF(pystring); @@ -3360,7 +3362,7 @@ /* Include this incase this instance is a subtype of a python class * In these instances we may want to return a function or variable provided by the subtype * */ - ret= PyList_New(0); + ret = PyList_New(0); if (!BPy_StructRNA_CheckExact(self)) pyrna_dir_members_py(ret, (PyObject *)self); @@ -3368,11 +3370,11 @@ pyrna_dir_members_rna(ret, &self->ptr); if (self->ptr.type == &RNA_Context) { - ListBase lb= CTX_data_dir_get(self->ptr.data); + ListBase lb = CTX_data_dir_get(self->ptr.data); LinkData *link; - for (link=lb.first; link; link=link->next) { - pystring= PyUnicode_FromString(link->data); + for (link = lb.first; link; link = link->next) { + pystring = PyUnicode_FromString(link->data); PyList_Append(ret, pystring); Py_DECREF(pystring); } @@ -3384,10 +3386,10 @@ /* set(), this is needed to remove-doubles because the deferred * register-props will be in both the python __dict__ and accessed as RNA */ - PyObject *set= PySet_New(ret); + PyObject *set = PySet_New(ret); Py_DECREF(ret); - ret= PySequence_List(set); + ret = PySequence_List(set); Py_DECREF(set); } @@ -3397,7 +3399,7 @@ //---------------getattr-------------------------------------------- static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname) { - const char *name= _PyUnicode_AsString(pyname); + const char *name = _PyUnicode_AsString(pyname); PyObject *ret; PropertyRNA *prop; FunctionRNA *func; @@ -3406,49 +3408,49 @@ if (name == NULL) { PyErr_SetString(PyExc_AttributeError, "bpy_struct: __getattr__ must be a string"); - ret= NULL; + ret = NULL; } - else if (name[0]=='_') { // rna can't start with a "_", so for __dict__ and similar we can skip using rna lookups + else if (name[0] == '_') { // rna can't start with a "_", so for __dict__ and similar we can skip using rna lookups /* annoying exception, maybe we need to have different types for this... */ - if ((strcmp(name, "__getitem__")==0 || strcmp(name, "__setitem__")==0) && !RNA_struct_idprops_check(self->ptr.type)) { + if ((strcmp(name, "__getitem__") == 0 || strcmp(name, "__setitem__") == 0) && !RNA_struct_idprops_check(self->ptr.type)) { PyErr_SetString(PyExc_AttributeError, "bpy_struct: no __getitem__ support for this type"); - ret= NULL; + ret = NULL; } else { - ret= PyObject_GenericGetAttr((PyObject *)self, pyname); + ret = PyObject_GenericGetAttr((PyObject *)self, pyname); } } - else if ((prop= RNA_struct_find_property(&self->ptr, name))) { - ret= pyrna_prop_to_py(&self->ptr, prop); + else if ((prop = RNA_struct_find_property(&self->ptr, name))) { + ret = pyrna_prop_to_py(&self->ptr, prop); } /* RNA function only if callback is declared (no optional functions) */ - else if ((func= RNA_struct_find_function(&self->ptr, name)) && RNA_function_defined(func)) { - ret= pyrna_func_to_py(&self->ptr, func); + else if ((func = RNA_struct_find_function(&self->ptr, name)) && RNA_function_defined(func)) { + ret = pyrna_func_to_py(&self->ptr, func); } else if (self->ptr.type == &RNA_Context) { - bContext *C= self->ptr.data; - if (C==NULL) { + bContext *C = self->ptr.data; + if (C == NULL) { PyErr_Format(PyExc_AttributeError, "bpy_struct: Context is 'NULL', can't get \"%.200s\" from context", name); - ret= NULL; + ret = NULL; } else { PointerRNA newptr; ListBase newlb; short newtype; - int done= CTX_data_get(C, name, &newptr, &newlb, &newtype); + int done = CTX_data_get(C, name, &newptr, &newlb, &newtype); - if (done==1) { /* found */ - switch(newtype) { + if (done == 1) { /* found */ + switch (newtype) { case CTX_DATA_TYPE_POINTER: if (newptr.data == NULL) { - ret= Py_None; + ret = Py_None; Py_INCREF(ret); } else { - ret= pyrna_struct_CreatePyObject(&newptr); + ret = pyrna_struct_CreatePyObject(&newptr); } break; case CTX_DATA_TYPE_COLLECTION: @@ -3456,10 +3458,10 @@ CollectionPointerLink *link; PyObject *linkptr; - ret= PyList_New(0); + ret = PyList_New(0); - for (link=newlb.first; link; link=link->next) { - linkptr= pyrna_struct_CreatePyObject(&link->ptr); + for (link = newlb.first; link; link = link->next) { + linkptr = pyrna_struct_CreatePyObject(&link->ptr); PyList_Append(ret, linkptr); Py_DECREF(linkptr); } @@ -3472,16 +3474,16 @@ PyErr_Format(PyExc_AttributeError, "bpy_struct: Context type invalid %d, can't get \"%.200s\" from context", newtype, name); - ret= NULL; + ret = NULL; } } - else if (done==-1) { /* found but not set */ - ret= Py_None; + else if (done == -1) { /* found but not set */ + ret = Py_None; Py_INCREF(ret); } else { /* not found in the context */ /* lookup the subclass. raise an error if its not found */ - ret= PyObject_GenericGetAttr((PyObject *)self, pyname); + ret = PyObject_GenericGetAttr((PyObject *)self, pyname); } BLI_freelistN(&newlb); @@ -3492,7 +3494,7 @@ PyErr_Format(PyExc_AttributeError, "bpy_struct: attribute \"%.200s\" not found", name); - ret= NULL; + ret = NULL; #endif /* Include this incase this instance is a subtype of a python class * In these instances we may want to return a function or variable provided by the subtype @@ -3501,7 +3503,7 @@ * */ /* The error raised here will be displayed */ - ret= PyObject_GenericGetAttr((PyObject *)self, pyname); + ret = PyObject_GenericGetAttr((PyObject *)self, pyname); } return ret; @@ -3510,8 +3512,8 @@ #if 0 static int pyrna_struct_pydict_contains(PyObject *self, PyObject *pyname) { - PyObject *dict= *(_PyObject_GetDictPtr((PyObject *)self)); - if (dict==NULL) /* unlikely */ + PyObject *dict = *(_PyObject_GetDictPtr((PyObject *)self)); + if (dict == NULL) /* unlikely */ return 0; return PyDict_Contains(dict, pyname); @@ -3530,10 +3532,10 @@ #if 0 static PyObject *pyrna_struct_meta_idprop_getattro(PyObject *cls, PyObject *attr) { - PyObject *ret= PyType_Type.tp_getattro(cls, attr); + PyObject *ret = PyType_Type.tp_getattro(cls, attr); /* Allows: - * >>> bpy.types.Scene.foo= BoolProperty() + * >>> bpy.types.Scene.foo = BoolProperty() * >>> bpy.types.Scene.foo * * ...rather than returning the deferred class register tuple as checked by pyrna_is_deferred_prop() @@ -3541,14 +3543,14 @@ * Disable for now, this is faking internal behavior in a way thats too tricky to maintain well. */ #if 0 if (ret == NULL) { // || pyrna_is_deferred_prop(ret) - StructRNA *srna= srna_from_self(cls, "StructRNA.__getattr__"); + StructRNA *srna = srna_from_self(cls, "StructRNA.__getattr__"); if (srna) { - PropertyRNA *prop= RNA_struct_type_find_property(srna, _PyUnicode_AsString(attr)); + PropertyRNA *prop = RNA_struct_type_find_property(srna, _PyUnicode_AsString(attr)); if (prop) { PointerRNA tptr; PyErr_Clear(); /* clear error from tp_getattro */ RNA_pointer_create(NULL, &RNA_Property, prop, &tptr); - ret= pyrna_struct_CreatePyObject(&tptr); + ret = pyrna_struct_CreatePyObject(&tptr); } } } @@ -3560,9 +3562,9 @@ static int pyrna_struct_meta_idprop_setattro(PyObject *cls, PyObject *attr, PyObject *value) { - StructRNA *srna= srna_from_self(cls, "StructRNA.__setattr__"); - const int is_deferred_prop= (value && pyrna_is_deferred_prop(value)); - const char *attr_str= _PyUnicode_AsString(attr); + StructRNA *srna = srna_from_self(cls, "StructRNA.__setattr__"); + const int is_deferred_prop = (value && pyrna_is_deferred_prop(value)); + const char *attr_str = _PyUnicode_AsString(attr); if (srna && !pyrna_write_check() && (is_deferred_prop || RNA_struct_type_find_property(srna, attr_str))) { PyErr_Format(PyExc_AttributeError, @@ -3590,7 +3592,7 @@ if (value) { /* check if the value is a property */ if (is_deferred_prop) { - int ret= deferred_register_prop(srna, attr, value); + int ret = deferred_register_prop(srna, attr, value); if (ret == -1) { /* error set */ return ret; @@ -3607,7 +3609,7 @@ } else { /* __delattr__ */ /* first find if this is a registered property */ - const int ret= RNA_def_property_free_identifier(srna, attr_str); + const int ret = RNA_def_property_free_identifier(srna, attr_str); if (ret == -1) { PyErr_Format(PyExc_TypeError, "struct_meta_idprop.detattr(): '%s' not a dynamic property", @@ -3622,8 +3624,8 @@ static int pyrna_struct_setattro(BPy_StructRNA *self, PyObject *pyname, PyObject *value) { - const char *name= _PyUnicode_AsString(pyname); - PropertyRNA *prop= NULL; + const char *name = _PyUnicode_AsString(pyname); + PropertyRNA *prop = NULL; PYRNA_STRUCT_CHECK_INT(self); @@ -3637,7 +3639,7 @@ PyErr_SetString(PyExc_AttributeError, "bpy_struct: __setattr__ must be a string"); return -1; } - else if (name[0] != '_' && (prop= RNA_struct_find_property(&self->ptr, name))) { + else if (name[0] != '_' && (prop = RNA_struct_find_property(&self->ptr, name))) { if (!RNA_property_editable_flag(&self->ptr, prop)) { PyErr_Format(PyExc_AttributeError, "bpy_struct: attribute \"%.200s\" from \"%.200s\" is read-only", @@ -3647,8 +3649,8 @@ } else if (self->ptr.type == &RNA_Context) { /* code just raises correct error, context prop's cant be set, unless its apart of the py class */ - bContext *C= self->ptr.data; - if (C==NULL) { + bContext *C = self->ptr.data; + if (C == NULL) { PyErr_Format(PyExc_AttributeError, "bpy_struct: Context is 'NULL', can't set \"%.200s\" from context", name); @@ -3659,9 +3661,9 @@ ListBase newlb; short newtype; - int done= CTX_data_get(C, name, &newptr, &newlb, &newtype); + int done = CTX_data_get(C, name, &newptr, &newlb, &newtype); - if (done==1) { + if (done == 1) { PyErr_Format(PyExc_AttributeError, "bpy_struct: Context property \"%.200s\" is read-only", name); @@ -3679,7 +3681,7 @@ PyErr_SetString(PyExc_AttributeError, "bpy_struct: del not supported"); return -1; } - return pyrna_py_to_prop(&self->ptr, prop, NULL, value, "bpy_struct: item.attr= val:"); + return pyrna_py_to_prop(&self->ptr, prop, NULL, value, "bpy_struct: item.attr = val:"); } else { return PyObject_GenericSetAttr((PyObject *)self, pyname, value); @@ -3694,7 +3696,7 @@ /* Include this incase this instance is a subtype of a python class * In these instances we may want to return a function or variable provided by the subtype * */ - ret= PyList_New(0); + ret = PyList_New(0); if (!BPy_PropertyRNA_CheckExact(self)) { pyrna_dir_members_py(ret, (PyObject *)self); @@ -3717,7 +3719,7 @@ static PyObject *pyrna_prop_collection_getattro(BPy_PropertyRNA *self, PyObject *pyname) { - const char *name= _PyUnicode_AsString(pyname); + const char *name = _PyUnicode_AsString(pyname); if (name == NULL) { PyErr_SetString(PyExc_AttributeError, "bpy_prop_collection: __getattr__ must be a string"); @@ -3730,14 +3732,14 @@ PointerRNA r_ptr; if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) { - if ((prop= RNA_struct_find_property(&r_ptr, name))) { - ret= pyrna_prop_to_py(&r_ptr, prop); + if ((prop = RNA_struct_find_property(&r_ptr, name))) { + ret = pyrna_prop_to_py(&r_ptr, prop); return ret; } - else if ((func= RNA_struct_find_function(&r_ptr, name))) { - PyObject *self_collection= pyrna_struct_CreatePyObject(&r_ptr); - ret= pyrna_func_to_py(&((BPy_DummyPointerRNA *)self_collection)->ptr, func); + else if ((func = RNA_struct_find_function(&r_ptr, name))) { + PyObject *self_collection = pyrna_struct_CreatePyObject(&r_ptr); + ret = pyrna_func_to_py(&((BPy_DummyPointerRNA *)self_collection)->ptr, func); Py_DECREF(self_collection); return ret; @@ -3754,7 +3756,7 @@ * so as to support 'bpy.data.library.load()' * note, this _only_ supports static methods */ - PyObject *ret= PyObject_GenericGetAttr((PyObject *)self, pyname); + PyObject *ret = PyObject_GenericGetAttr((PyObject *)self, pyname); if (ret == NULL && name[0] != '_') { /* avoid inheriting __call__ and similar */ /* since this is least common case, handle it last */ @@ -3766,8 +3768,8 @@ PyErr_Fetch(&error_type, &error_value, &error_traceback); PyErr_Clear(); - cls= pyrna_struct_Subtype(&r_ptr); /* borrows */ - ret= PyObject_GenericGetAttr(cls, pyname); + cls = pyrna_struct_Subtype(&r_ptr); /* borrows */ + ret = PyObject_GenericGetAttr(cls, pyname); /* restore the original error */ if (ret == NULL) { PyErr_Restore(error_type, error_value, error_traceback); @@ -3783,7 +3785,7 @@ //--------------- setattr------------------------------------------- static int pyrna_prop_collection_setattro(BPy_PropertyRNA *self, PyObject *pyname, PyObject *value) { - const char *name= _PyUnicode_AsString(pyname); + const char *name = _PyUnicode_AsString(pyname); PropertyRNA *prop; PointerRNA r_ptr; @@ -3802,7 +3804,7 @@ return -1; } else if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) { - if ((prop= RNA_struct_find_property(&r_ptr, name))) { + if ((prop = RNA_struct_find_property(&r_ptr, name))) { /* pyrna_py_to_prop sets its own exceptions */ return pyrna_py_to_prop(&r_ptr, prop, NULL, value, "BPy_PropertyRNA - Attribute (setattr):"); } @@ -3831,9 +3833,9 @@ static PyObject *pyrna_prop_collection_idprop_remove(BPy_PropertyRNA *self, PyObject *value) { - int key= PyLong_AsLong(value); + int key = PyLong_AsLong(value); - if (key==-1 && PyErr_Occurred()) { + if (key == -1 && PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.remove(): expected one int argument"); return NULL; } @@ -3848,7 +3850,7 @@ static PyObject *pyrna_prop_collection_idprop_move(BPy_PropertyRNA *self, PyObject *args) { - int key=0, pos=0; + int key = 0, pos = 0; if (!PyArg_ParseTuple(args, "ii", &key, &pos)) { PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.move(): expected two ints as arguments"); @@ -3903,14 +3905,14 @@ /* Python attributes get/set structure: */ /*****************************************************************************/ -static PyGetSetDef pyrna_prop_getseters[]= { +static PyGetSetDef pyrna_prop_getseters[] = { {(char *)"id_data", (getter)pyrna_struct_get_id_data, (setter)NULL, (char *)pyrna_struct_get_id_data_doc, NULL}, {(char *)"data", (getter)pyrna_struct_get_data, (setter)NULL, (char *)pyrna_struct_get_data_doc, NULL}, {(char *)"rna_type", (getter)pyrna_struct_get_rna_type, (setter)NULL, (char *)pyrna_struct_get_rna_type_doc, NULL}, {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ }; -static PyGetSetDef pyrna_struct_getseters[]= { +static PyGetSetDef pyrna_struct_getseters[] = { {(char *)"id_data", (getter)pyrna_struct_get_id_data, (setter)NULL, (char *)pyrna_struct_get_id_data_doc, NULL}, {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ }; @@ -3927,17 +3929,17 @@ ); static PyObject *pyrna_prop_collection_keys(BPy_PropertyRNA *self) { - PyObject *ret= PyList_New(0); + PyObject *ret = PyList_New(0); PyObject *item; char name[256], *nameptr; int namelen; RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) { - nameptr= RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen); + nameptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen); if (nameptr) { /* add to python list */ - item= PyUnicode_FromStringAndSize(nameptr, namelen); + item = PyUnicode_FromStringAndSize(nameptr, namelen); PyList_Append(ret, item); Py_DECREF(item); /* done */ @@ -3963,17 +3965,17 @@ ); static PyObject *pyrna_prop_collection_items(BPy_PropertyRNA *self) { - PyObject *ret= PyList_New(0); + PyObject *ret = PyList_New(0); PyObject *item; char name[256], *nameptr; int namelen; - int i= 0; + int i = 0; RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) { if (itemptr.data) { /* add to python list */ - item= PyTuple_New(2); - nameptr= RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen); + item = PyTuple_New(2); + nameptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen); if (nameptr) { PyTuple_SET_ITEM(item, 0, PyUnicode_FromStringAndSize(nameptr, namelen)); if (name != nameptr) @@ -4030,7 +4032,7 @@ IDProperty *group, *idprop; const char *key; - PyObject* def= Py_None; + PyObject* def = Py_None; PYRNA_STRUCT_CHECK_OBJ(self); @@ -4038,14 +4040,14 @@ return NULL; /* mostly copied from BPy_IDGroup_Map_GetItem */ - if (RNA_struct_idprops_check(self->ptr.type)==0) { + if (RNA_struct_idprops_check(self->ptr.type) == 0) { PyErr_SetString(PyExc_TypeError, "this type doesn't support IDProperties"); return NULL; } - group= RNA_struct_idprops(&self->ptr, 0); + group = RNA_struct_idprops(&self->ptr, 0); if (group) { - idprop= IDP_GetPropertyFromGroup(group, key); + idprop = IDP_GetPropertyFromGroup(group, key); if (idprop) { return BPy_IDGroup_WrapData(self->ptr.id.data, idprop, group); @@ -4071,7 +4073,6 @@ return PyLong_FromVoidPtr(self->ptr.data); } -/* TODO, get (string, lib) pair */ PyDoc_STRVAR(pyrna_prop_collection_get_doc, ".. method:: get(key, default=None)\n" "\n" @@ -4089,7 +4090,7 @@ PointerRNA newptr; PyObject *key_ob; - PyObject* def= Py_None; + PyObject* def = Py_None; PYRNA_PROP_CHECK_OBJ(self); @@ -4097,13 +4098,13 @@ return NULL; if (PyUnicode_Check(key_ob)) { - const char *key= _PyUnicode_AsString(key_ob); + const char *key = _PyUnicode_AsString(key_ob); if (RNA_property_collection_lookup_string(&self->ptr, self->prop, key, &newptr)) return pyrna_struct_CreatePyObject(&newptr); } else if (PyTuple_Check(key_ob)) { - PyObject *ret= pyrna_prop_collection_subscript_str_lib_pair(self, key_ob, + PyObject *ret = pyrna_prop_collection_subscript_str_lib_pair(self, key_ob, "bpy_prop_collection.get((id, lib))", FALSE); if (ret) { return ret; @@ -4118,21 +4119,66 @@ return Py_INCREF(def), def; } +PyDoc_STRVAR(pyrna_prop_collection_find_doc, +".. method:: find(key)\n" +"\n" +" Returns the index of a key in a collection or -1 when not found\n" +" (matches pythons string find function of the same name).\n" +"\n" +" :arg key: The identifier for the collection member.\n" +" :type key: string\n" +" :return: index of the key.\n" +" :rtype: int\n" +); +static PyObject *pyrna_prop_collection_find(BPy_PropertyRNA *self, PyObject *key_ob) +{ + Py_ssize_t key_len_ssize_t; + const char *key = _PyUnicode_AsStringAndSize(key_ob, &key_len_ssize_t); + const int key_len = (int)key_len_ssize_t; /* comare with same type */ + + char name[256], *nameptr; + int namelen; + int i = 0; + int index = -1; + + PYRNA_PROP_CHECK_OBJ(self); + + RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) { + nameptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen); + + if (nameptr) { + if ((key_len == namelen) && memcmp(nameptr, key, key_len) == 0) { + index = i; + break; + } + + if (name != nameptr) { + MEM_freeN(nameptr); + } + } + + i++; + } + RNA_PROP_END; + + return PyLong_FromSsize_t(index); +} + static void foreach_attr_type( BPy_PropertyRNA *self, const char *attr, /* values to assign */ RawPropertyType *raw_type, int *attr_tot, int *attr_signed) { PropertyRNA *prop; - *raw_type= PROP_RAW_UNSET; - *attr_tot= 0; - *attr_signed= FALSE; + *raw_type = PROP_RAW_UNSET; + *attr_tot = 0; + *attr_signed = FALSE; /* note: this is fail with zero length lists, so dont let this get caled in that case */ RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) { - prop= RNA_struct_find_property(&itemptr, attr); - *raw_type= RNA_property_raw_type(prop); - *attr_tot= RNA_property_array_length(&itemptr, prop); - *attr_signed= (RNA_property_subtype(prop)==PROP_UNSIGNED) ? FALSE:TRUE; + prop = RNA_struct_find_property(&itemptr, attr); + *raw_type = RNA_property_raw_type(prop); + *attr_tot = RNA_property_array_length(&itemptr, prop); + *attr_signed = (RNA_property_subtype(prop) == PROP_UNSIGNED) ? FALSE:TRUE; break; } RNA_PROP_END; @@ -4152,31 +4198,31 @@ int target_tot; #endif - *size= *attr_tot= *attr_signed= FALSE; - *raw_type= PROP_RAW_UNSET; + *size = *attr_tot = *attr_signed = FALSE; + *raw_type = PROP_RAW_UNSET; if (!PyArg_ParseTuple(args, "sO", attr, seq) || (!PySequence_Check(*seq) && PyObject_CheckBuffer(*seq))) { PyErr_SetString(PyExc_TypeError, "foreach_get(attr, sequence) expects a string and a sequence"); return -1; } - *tot= PySequence_Size(*seq); // TODO - buffer may not be a sequence! array.array() is tho. + *tot = PySequence_Size(*seq); // TODO - buffer may not be a sequence! array.array() is tho. - if (*tot>0) { + if (*tot > 0) { foreach_attr_type(self, *attr, raw_type, attr_tot, attr_signed); - *size= RNA_raw_type_sizeof(*raw_type); + *size = RNA_raw_type_sizeof(*raw_type); #if 0 // works fine but not strictly needed, we could allow RNA_property_collection_raw_* to do the checks if ((*attr_tot) < 1) - *attr_tot= 1; + *attr_tot = 1; if (RNA_property_type(self->prop) == PROP_COLLECTION) - array_tot= RNA_property_collection_length(&self->ptr, self->prop); + array_tot = RNA_property_collection_length(&self->ptr, self->prop); else - array_tot= RNA_property_array_length(&self->ptr, self->prop); + array_tot = RNA_property_array_length(&self->ptr, self->prop); - target_tot= array_tot * (*attr_tot); + target_tot = array_tot * (*attr_tot); /* rna_access.c - rna_raw_access(...) uses this same method */ if (target_tot != (*tot)) { @@ -4199,22 +4245,22 @@ static int foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, const char *format) { - char f= format ? *format:'B'; /* B is assumed when not set */ + char f = format ? *format:'B'; /* B is assumed when not set */ - switch(raw_type) { + switch (raw_type) { case PROP_RAW_CHAR: - if (attr_signed) return (f=='b') ? 1:0; - else return (f=='B') ? 1:0; + if (attr_signed) return (f == 'b') ? 1:0; + else return (f == 'B') ? 1:0; case PROP_RAW_SHORT: - if (attr_signed) return (f=='h') ? 1:0; - else return (f=='H') ? 1:0; + if (attr_signed) return (f == 'h') ? 1:0; + else return (f == 'H') ? 1:0; case PROP_RAW_INT: - if (attr_signed) return (f=='i') ? 1:0; - else return (f=='I') ? 1:0; + if (attr_signed) return (f == 'i') ? 1:0; + else return (f == 'I') ? 1:0; case PROP_RAW_FLOAT: - return (f=='f') ? 1:0; + return (f == 'f') ? 1:0; case PROP_RAW_DOUBLE: - return (f=='d') ? 1:0; + return (f == 'd') ? 1:0; case PROP_RAW_UNSET: return 0; } @@ -4224,9 +4270,9 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) { - PyObject *item= NULL; - int i=0, ok=0, buffer_is_compat; - void *array= NULL; + PyObject *item = NULL; + int i = 0, ok = 0, buffer_is_compat; + void *array = NULL; /* get/set both take the same args currently */ const char *attr; @@ -4237,23 +4283,23 @@ if (foreach_parse_args(self, args, &attr, &seq, &tot, &size, &raw_type, &attr_tot, &attr_signed) < 0) return NULL; - if (tot==0) + if (tot == 0) Py_RETURN_NONE; if (set) { /* get the array from python */ - buffer_is_compat= FALSE; + buffer_is_compat = FALSE; if (PyObject_CheckBuffer(seq)) { Py_buffer buf; PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT); /* check if the buffer matches */ - buffer_is_compat= foreach_compat_buffer(raw_type, attr_signed, buf.format); + buffer_is_compat = foreach_compat_buffer(raw_type, attr_signed, buf.format); if (buffer_is_compat) { - ok= RNA_property_collection_raw_set(NULL, &self->ptr, self->prop, attr, buf.buf, raw_type, tot); + ok = RNA_property_collection_raw_set(NULL, &self->ptr, self->prop, attr, buf.buf, raw_type, tot); } PyBuffer_Release(&buf); @@ -4261,25 +4307,25 @@ /* could not use the buffer, fallback to sequence */ if (!buffer_is_compat) { - array= PyMem_Malloc(size * tot); + array = PyMem_Malloc(size * tot); - for ( ; iptr, self->prop, attr, array, raw_type, tot); + ok = RNA_property_collection_raw_set(NULL, &self->ptr, self->prop, attr, array, raw_type, tot); } } else { - buffer_is_compat= FALSE; + buffer_is_compat = FALSE; if (PyObject_CheckBuffer(seq)) { Py_buffer buf; PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT); /* check if the buffer matches, TODO - signed/unsigned types */ - buffer_is_compat= foreach_compat_buffer(raw_type, attr_signed, buf.format); + buffer_is_compat = foreach_compat_buffer(raw_type, attr_signed, buf.format); if (buffer_is_compat) { - ok= RNA_property_collection_raw_get(NULL, &self->ptr, self->prop, attr, buf.buf, raw_type, tot); + ok = RNA_property_collection_raw_get(NULL, &self->ptr, self->prop, attr, buf.buf, raw_type, tot); } PyBuffer_Release(&buf); @@ -4312,34 +4358,34 @@ /* could not use the buffer, fallback to sequence */ if (!buffer_is_compat) { - array= PyMem_Malloc(size * tot); + array = PyMem_Malloc(size * tot); - ok= RNA_property_collection_raw_get(NULL, &self->ptr, self->prop, attr, array, raw_type, tot); + ok = RNA_property_collection_raw_get(NULL, &self->ptr, self->prop, attr, array, raw_type, tot); - if (!ok) i= tot; /* skip the loop */ + if (!ok) i = tot; /* skip the loop */ - for ( ; iptr, self->prop, 0, len, len); + len = pyrna_prop_array_length(self); + ret = pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, 0, len, len); /* we know this is a list so no need to PyIter_Check * otherwise it could be NULL (unlikely) if conversion failed */ if (ret) { - iter= PyObject_GetIter(ret); + iter = PyObject_GetIter(ret); Py_DECREF(ret); } @@ -4438,13 +4484,13 @@ { /* Try get values from a collection */ PyObject *ret; - PyObject *iter= NULL; - ret= pyrna_prop_collection_values(self); + PyObject *iter = NULL; + ret = pyrna_prop_collection_values(self); /* we know this is a list so no need to PyIter_Check * otherwise it could be NULL (unlikely) if conversion failed */ if (ret) { - iter= PyObject_GetIter(ret); + iter = PyObject_GetIter(ret); Py_DECREF(ret); } @@ -4452,7 +4498,7 @@ } #endif /* # !USE_PYRNA_ITER */ -static struct PyMethodDef pyrna_struct_methods[]= { +static struct PyMethodDef pyrna_struct_methods[] = { /* only for PointerRNA's with ID'props */ {"keys", (PyCFunction)pyrna_struct_keys, METH_NOARGS, pyrna_struct_keys_doc}, @@ -4482,17 +4528,17 @@ {NULL, NULL, 0, NULL} }; -static struct PyMethodDef pyrna_prop_methods[]= { +static struct PyMethodDef pyrna_prop_methods[] = { {"path_from_id", (PyCFunction)pyrna_prop_path_from_id, METH_NOARGS, pyrna_prop_path_from_id_doc}, {"__dir__", (PyCFunction)pyrna_prop_dir, METH_NOARGS, NULL}, {NULL, NULL, 0, NULL} }; -static struct PyMethodDef pyrna_prop_array_methods[]= { +static struct PyMethodDef pyrna_prop_array_methods[] = { {NULL, NULL, 0, NULL} }; -static struct PyMethodDef pyrna_prop_collection_methods[]= { +static struct PyMethodDef pyrna_prop_collection_methods[] = { {"foreach_get", (PyCFunction)pyrna_prop_collection_foreach_get, METH_VARARGS, pyrna_prop_collection_foreach_get_doc}, {"foreach_set", (PyCFunction)pyrna_prop_collection_foreach_set, METH_VARARGS, pyrna_prop_collection_foreach_set_doc}, @@ -4501,10 +4547,11 @@ {"values", (PyCFunction)pyrna_prop_collection_values, METH_NOARGS, pyrna_prop_collection_values_doc}, {"get", (PyCFunction)pyrna_prop_collection_get, METH_VARARGS, pyrna_prop_collection_get_doc}, + {"find", (PyCFunction)pyrna_prop_collection_find, METH_O, pyrna_prop_collection_find_doc}, {NULL, NULL, 0, NULL} }; -static struct PyMethodDef pyrna_prop_collection_idprop_methods[]= { +static struct PyMethodDef pyrna_prop_collection_idprop_methods[] = { {"add", (PyCFunction)pyrna_prop_collection_idprop_add, METH_NOARGS, NULL}, {"remove", (PyCFunction)pyrna_prop_collection_idprop_remove, METH_O, NULL}, {"move", (PyCFunction)pyrna_prop_collection_idprop_move, METH_VARARGS, NULL}, @@ -4516,7 +4563,7 @@ static PyObject *pyrna_struct_new(PyTypeObject *type, PyObject *args, PyObject *UNUSED(kwds)) { if (PyTuple_GET_SIZE(args) == 1) { - BPy_StructRNA *base= (BPy_StructRNA *)PyTuple_GET_ITEM(args, 0); + BPy_StructRNA *base = (BPy_StructRNA *)PyTuple_GET_ITEM(args, 0); if (Py_TYPE(base) == type) { Py_INCREF(base); return (PyObject *)base; @@ -4529,15 +4576,15 @@ ... def test_func(self): ... print(100) ... - >>> myob= MyObSubclass(bpy.context.object) + >>> myob = MyObSubclass(bpy.context.object) >>> myob.test_func() 100 * * Keep this since it could be useful. */ BPy_StructRNA *ret; - if ((ret= (BPy_StructRNA *)type->tp_alloc(type, 0))) { - ret->ptr= base->ptr; + if ((ret = (BPy_StructRNA *)type->tp_alloc(type, 0))) { + ret->ptr = base->ptr; } /* pass on exception & NULL if tp_alloc fails */ return (PyObject *)ret; @@ -4570,9 +4617,9 @@ return (PyObject *)base; } else if (PyType_IsSubtype(type, &pyrna_prop_Type)) { - BPy_PropertyRNA *ret= (BPy_PropertyRNA *) type->tp_alloc(type, 0); - ret->ptr= base->ptr; - ret->prop= base->prop; + BPy_PropertyRNA *ret = (BPy_PropertyRNA *) type->tp_alloc(type, 0); + ret->ptr = base->ptr; + ret->prop = base->prop; return (PyObject *)ret; } else { @@ -4586,19 +4633,19 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data) { PyObject *ret; - const int type= RNA_property_type(prop); - const int flag= RNA_property_flag(prop); + const int type = RNA_property_type(prop); + const int flag = RNA_property_flag(prop); if (RNA_property_array_check(prop)) { int a, len; if (flag & PROP_DYNAMIC) { - ParameterDynAlloc *data_alloc= data; - len= data_alloc->array_tot; - data= data_alloc->array; + ParameterDynAlloc *data_alloc = data; + len = data_alloc->array_tot; + data = data_alloc->array; } else - len= RNA_property_array_length(ptr, prop); + len = RNA_property_array_length(ptr, prop); /* resolve the array from a new pytype */ @@ -4606,36 +4653,36 @@ switch (type) { case PROP_BOOLEAN: - ret= PyTuple_New(len); - for (a=0; aid.data, ptype, *(void**)data, &newptr); + RNA_pointer_create(ptr->id.data, ptype, *(void **)data, &newptr); } } if (newptr.data) { - ret= pyrna_struct_CreatePyObject(&newptr); + ret = pyrna_struct_CreatePyObject(&newptr); } else { - ret= Py_None; + ret = Py_None; Py_INCREF(ret); } break; } case PROP_COLLECTION: { - ListBase *lb= (ListBase*)data; + ListBase *lb = (ListBase *)data; CollectionPointerLink *link; PyObject *linkptr; - ret= PyList_New(0); + ret = PyList_New(0); - for (link=lb->first; link; link=link->next) { - linkptr= pyrna_struct_CreatePyObject(&link->ptr); + for (link = lb->first; link; link = link->next) { + linkptr = pyrna_struct_CreatePyObject(&link->ptr); PyList_Append(ret, linkptr); Py_DECREF(linkptr); } @@ -4751,7 +4798,7 @@ PyErr_Format(PyExc_TypeError, "RNA Error: unknown type \"%d\" (pyrna_param_to_py)", type); - ret= NULL; + ret = NULL; break; } } @@ -4764,13 +4811,13 @@ * works on small dict's such as keyword args. */ static PyObject *small_dict_get_item_string(PyObject *dict, const char *key_lookup) { - PyObject *key= NULL; + PyObject *key = NULL; Py_ssize_t pos = 0; PyObject *value = NULL; while (PyDict_Next(dict, &pos, &key, &value)) { if (PyUnicode_Check(key)) { - if (strcmp(key_lookup, _PyUnicode_AsString(key))==0) { + if (strcmp(key_lookup, _PyUnicode_AsString(key)) == 0) { return value; } } @@ -4782,36 +4829,36 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject *kw) { /* Note, both BPy_StructRNA and BPy_PropertyRNA can be used here */ - PointerRNA *self_ptr= &self->ptr; - FunctionRNA *self_func= self->func; + PointerRNA *self_ptr = &self->ptr; + FunctionRNA *self_func = self->func; PointerRNA funcptr; ParameterList parms; ParameterIterator iter; PropertyRNA *parm; PyObject *ret, *item; - int i, pyargs_len, pykw_len, parms_len, ret_len, flag, err= 0, kw_tot= 0, kw_arg; + int i, pyargs_len, pykw_len, parms_len, ret_len, flag, err = 0, kw_tot = 0, kw_arg; - PropertyRNA *pret_single= NULL; - void *retdata_single= NULL; + PropertyRNA *pret_single = NULL; + void *retdata_single = NULL; /* enable this so all strings are copied and freed after calling. * this exposes bugs where the pointer to the string is held and re-used */ // #define DEBUG_STRING_FREE #ifdef DEBUG_STRING_FREE - PyObject *string_free_ls= PyList_New(0); + PyObject *string_free_ls = PyList_New(0); #endif /* Should never happen but it does in rare cases */ BLI_assert(self_ptr != NULL); - if (self_ptr==NULL) { + if (self_ptr == NULL) { PyErr_SetString(PyExc_RuntimeError, "rna functions internal rna pointer is NULL, this is a bug. aborting"); return NULL; } - if (self_func==NULL) { + if (self_func == NULL) { PyErr_Format(PyExc_RuntimeError, "%.200s.(): rna function internal function is NULL, this is a bug. aborting", RNA_struct_identifier(self_ptr->type)); @@ -4834,13 +4881,13 @@ * the same ID as the functions. */ RNA_pointer_create(self_ptr->id.data, &RNA_Function, self_func, &funcptr); - pyargs_len= PyTuple_GET_SIZE(args); - pykw_len= kw ? PyDict_Size(kw) : 0; + pyargs_len = PyTuple_GET_SIZE(args); + pykw_len = kw ? PyDict_Size(kw) : 0; RNA_parameter_list_create(&parms, self_ptr, self_func); RNA_parameter_list_begin(&parms, &iter); - parms_len= RNA_parameter_list_arg_count(&parms); - ret_len= 0; + parms_len = RNA_parameter_list_arg_count(&parms); + ret_len = 0; if (pyargs_len + pykw_len > parms_len) { RNA_parameter_list_end(&iter); @@ -4848,53 +4895,53 @@ "%.200s.%.200s(): takes at most %d arguments, got %d", RNA_struct_identifier(self_ptr->type), RNA_function_identifier(self_func), parms_len, pyargs_len + pykw_len); - err= -1; + err = -1; } /* parse function parameters */ - for (i= 0; iter.valid && err==0; RNA_parameter_list_next(&iter)) { - parm= iter.parm; - flag= RNA_property_flag(parm); + for (i = 0; iter.valid && err == 0; RNA_parameter_list_next(&iter)) { + parm = iter.parm; + flag = RNA_property_flag(parm); /* only useful for single argument returns, we'll need another list loop for multiple */ if (flag & PROP_OUTPUT) { ret_len++; - if (pret_single==NULL) { - pret_single= parm; - retdata_single= iter.data; + if (pret_single == NULL) { + pret_single = parm; + retdata_single = iter.data; } continue; } - item= NULL; + item = NULL; if (i < pyargs_len) { - item= PyTuple_GET_ITEM(args, i); - kw_arg= FALSE; + item = PyTuple_GET_ITEM(args, i); + kw_arg = FALSE; } else if (kw != NULL) { #if 0 - item= PyDict_GetItemString(kw, RNA_property_identifier(parm)); /* borrow ref */ + item = PyDict_GetItemString(kw, RNA_property_identifier(parm)); /* borrow ref */ #else - item= small_dict_get_item_string(kw, RNA_property_identifier(parm)); /* borrow ref */ + item = small_dict_get_item_string(kw, RNA_property_identifier(parm)); /* borrow ref */ #endif if (item) kw_tot++; /* make sure invalid keywords are not given */ - kw_arg= TRUE; + kw_arg = TRUE; } i++; /* current argument */ - if (item==NULL) { + if (item == NULL) { if (flag & PROP_REQUIRED) { PyErr_Format(PyExc_TypeError, "%.200s.%.200s(): required parameter \"%.200s\" not specified", RNA_struct_identifier(self_ptr->type), RNA_function_identifier(self_func), RNA_property_identifier(parm)); - err= -1; + err = -1; break; } else { /* PyDict_GetItemString wont raise an error */ @@ -4905,21 +4952,21 @@ #ifdef DEBUG_STRING_FREE if (item) { if (PyUnicode_Check(item)) { - item= PyUnicode_FromString(_PyUnicode_AsString(item)); + item = PyUnicode_FromString(_PyUnicode_AsString(item)); PyList_Append(string_free_ls, item); Py_DECREF(item); } } #endif - err= pyrna_py_to_prop(&funcptr, parm, iter.data, item, ""); + err = pyrna_py_to_prop(&funcptr, parm, iter.data, item, ""); - if (err!=0) { + if (err != 0) { /* the error generated isn't that useful, so generate it again with a useful prefix * could also write a function to prepend to error messages */ char error_prefix[512]; PyErr_Clear(); /* re-raise */ - if (kw_arg==TRUE) + if (kw_arg == TRUE) BLI_snprintf(error_prefix, sizeof(error_prefix), "%.200s.%.200s(): error with keyword argument \"%.200s\" - ", RNA_struct_identifier(self_ptr->type), @@ -4948,59 +4995,59 @@ */ if (err == 0 && kw && (pykw_len > kw_tot)) { PyObject *key, *value; - Py_ssize_t pos= 0; + Py_ssize_t pos = 0; - DynStr *bad_args= BLI_dynstr_new(); - DynStr *good_args= BLI_dynstr_new(); + DynStr *bad_args = BLI_dynstr_new(); + DynStr *good_args = BLI_dynstr_new(); const char *arg_name, *bad_args_str, *good_args_str; - int found= FALSE, first= TRUE; + int found = FALSE, first = TRUE; while (PyDict_Next(kw, &pos, &key, &value)) { - arg_name= _PyUnicode_AsString(key); - found= FALSE; + arg_name = _PyUnicode_AsString(key); + found = FALSE; - if (arg_name==NULL) { /* unlikely the argname is not a string but ignore if it is*/ + if (arg_name == NULL) { /* unlikely the argname is not a string but ignore if it is*/ PyErr_Clear(); } else { /* Search for arg_name */ RNA_parameter_list_begin(&parms, &iter); for (; iter.valid; RNA_parameter_list_next(&iter)) { - parm= iter.parm; - if (strcmp(arg_name, RNA_property_identifier(parm))==0) { - found= TRUE; + parm = iter.parm; + if (strcmp(arg_name, RNA_property_identifier(parm)) == 0) { + found = TRUE; break; } } RNA_parameter_list_end(&iter); - if (found==FALSE) { + if (found == FALSE) { BLI_dynstr_appendf(bad_args, first ? "%s" : ", %s", arg_name); - first= FALSE; + first = FALSE; } } } /* list good args */ - first= TRUE; + first = TRUE; RNA_parameter_list_begin(&parms, &iter); for (; iter.valid; RNA_parameter_list_next(&iter)) { - parm= iter.parm; + parm = iter.parm; if (RNA_property_flag(parm) & PROP_OUTPUT) continue; BLI_dynstr_appendf(good_args, first ? "%s" : ", %s", RNA_property_identifier(parm)); - first= FALSE; + first = FALSE; } RNA_parameter_list_end(&iter); - bad_args_str= BLI_dynstr_get_cstring(bad_args); - good_args_str= BLI_dynstr_get_cstring(good_args); + bad_args_str = BLI_dynstr_get_cstring(bad_args); + good_args_str = BLI_dynstr_get_cstring(good_args); PyErr_Format(PyExc_TypeError, "%.200s.%.200s(): was called with invalid keyword arguments(s) (%s), expected (%s)", @@ -5012,32 +5059,32 @@ MEM_freeN((void *)bad_args_str); MEM_freeN((void *)good_args_str); - err= -1; + err = -1; } - ret= NULL; - if (err==0) { + ret = NULL; + if (err == 0) { /* call function */ ReportList reports; - bContext *C= BPy_GetContext(); + bContext *C = BPy_GetContext(); BKE_reports_init(&reports, RPT_STORE); RNA_function_call(C, &reports, self_ptr, self_func, &parms); - err= (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE)); + err = (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE)); /* return value */ if (err != -1) { if (ret_len > 0) { if (ret_len > 1) { - ret= PyTuple_New(ret_len); - i= 0; /* arg index */ + ret = PyTuple_New(ret_len); + i = 0; /* arg index */ RNA_parameter_list_begin(&parms, &iter); for (; iter.valid; RNA_parameter_list_next(&iter)) { - parm= iter.parm; - flag= RNA_property_flag(parm); + parm = iter.parm; + flag = RNA_property_flag(parm); if (flag & PROP_OUTPUT) PyTuple_SET_ITEM(ret, i++, pyrna_param_to_py(&funcptr, parm, iter.data)); @@ -5046,18 +5093,25 @@ RNA_parameter_list_end(&iter); } else - ret= pyrna_param_to_py(&funcptr, pret_single, retdata_single); + ret = pyrna_param_to_py(&funcptr, pret_single, retdata_single); /* possible there is an error in conversion */ - if (ret==NULL) - err= -1; + if (ret == NULL) + err = -1; } } } #ifdef DEBUG_STRING_FREE - // if (PyList_GET_SIZE(string_free_ls)) printf("%.200s.%.200s(): has %d strings\n", RNA_struct_identifier(self_ptr->type), RNA_function_identifier(self_func), (int)PyList_GET_SIZE(string_free_ls)); + /* + if (PyList_GET_SIZE(string_free_ls)) { + printf("%.200s.%.200s(): has %d strings\n", + RNA_struct_identifier(self_ptr->type), + RNA_function_identifier(self_func), + (int)PyList_GET_SIZE(string_free_ls)); + } + */ Py_DECREF(string_free_ls); #undef DEBUG_STRING_FREE #endif @@ -5069,7 +5123,7 @@ if (ret) return ret; - if (err==-1) + if (err == -1) return NULL; Py_RETURN_NONE; @@ -5078,10 +5132,13 @@ /* subclasses of pyrna_struct_Type which support idprop definitions use this as a metaclass */ /* note: tp_base member is set to &PyType_Type on init */ -PyTypeObject pyrna_struct_meta_idprop_Type= { +PyTypeObject pyrna_struct_meta_idprop_Type = { PyVarObject_HEAD_INIT(NULL, 0) "bpy_struct_meta_idprop", /* tp_name */ - sizeof(PyHeapTypeObject), /* tp_basicsize */ // XXX, would be PyTypeObject, but subtypes of Type must be PyHeapTypeObject's + + /* NOTE! would be PyTypeObject, but subtypes of Type must be PyHeapTypeObject's */ + sizeof(PyHeapTypeObject), /* tp_basicsize */ + 0, /* tp_itemsize */ /* methods */ NULL, /* tp_dealloc */ @@ -5160,7 +5217,7 @@ /*-----------------------BPy_StructRNA method def------------------------------*/ -PyTypeObject pyrna_struct_Type= { +PyTypeObject pyrna_struct_Type = { PyVarObject_HEAD_INIT(NULL, 0) "bpy_struct", /* tp_name */ sizeof(BPy_StructRNA), /* tp_basicsize */ @@ -5249,7 +5306,7 @@ }; /*-----------------------BPy_PropertyRNA method def------------------------------*/ -PyTypeObject pyrna_prop_Type= { +PyTypeObject pyrna_prop_Type = { PyVarObject_HEAD_INIT(NULL, 0) "bpy_prop", /* tp_name */ sizeof(BPy_PropertyRNA), /* tp_basicsize */ @@ -5333,18 +5390,18 @@ NULL }; -PyTypeObject pyrna_prop_array_Type= { +PyTypeObject pyrna_prop_array_Type = { PyVarObject_HEAD_INIT(NULL, 0) - "bpy_prop_array", /* tp_name */ + "bpy_prop_array", /* tp_name */ sizeof(BPy_PropertyArrayRNA), /* tp_basicsize */ - 0, /* tp_itemsize */ + 0, /* tp_itemsize */ /* methods */ (destructor)pyrna_prop_array_dealloc, /* tp_dealloc */ NULL, /* printfunc tp_print; */ NULL, /* getattrfunc tp_getattr; */ NULL, /* setattrfunc tp_setattr; */ NULL, /* tp_compare */ /* DEPRECATED in python 3.0! */ - NULL,/* subclassed */ /* tp_repr */ + NULL,/* subclassed */ /* tp_repr */ /* Method suites for standard classes */ @@ -5416,7 +5473,7 @@ NULL }; -PyTypeObject pyrna_prop_collection_Type= { +PyTypeObject pyrna_prop_collection_Type = { PyVarObject_HEAD_INIT(NULL, 0) "bpy_prop_collection", /* tp_name */ sizeof(BPy_PropertyRNA), /* tp_basicsize */ @@ -5501,7 +5558,7 @@ }; /* only for add/remove/move methods */ -static PyTypeObject pyrna_prop_collection_idprop_Type= { +static PyTypeObject pyrna_prop_collection_idprop_Type = { PyVarObject_HEAD_INIT(NULL, 0) "bpy_prop_collection_idprop", /* tp_name */ sizeof(BPy_PropertyRNA), /* tp_basicsize */ @@ -5586,7 +5643,7 @@ }; /*-----------------------BPy_PropertyRNA method def------------------------------*/ -PyTypeObject pyrna_func_Type= { +PyTypeObject pyrna_func_Type = { PyVarObject_HEAD_INIT(NULL, 0) "bpy_func", /* tp_name */ sizeof(BPy_FunctionRNA), /* tp_basicsize */ @@ -5682,7 +5739,7 @@ static void pyrna_prop_collection_iter_dealloc(BPy_PropertyCollectionIterRNA *self); static PyObject *pyrna_prop_collection_iter_next(BPy_PropertyCollectionIterRNA *self); -PyTypeObject pyrna_prop_collection_iter_Type= { +PyTypeObject pyrna_prop_collection_iter_Type = { PyVarObject_HEAD_INIT(NULL, 0) "bpy_prop_collection_iter", /* tp_name */ sizeof(BPy_PropertyCollectionIterRNA), /* tp_basicsize */ @@ -5775,10 +5832,10 @@ PyObject *pyrna_prop_collection_iter_CreatePyObject(PointerRNA *ptr, PropertyRNA *prop) { - BPy_PropertyCollectionIterRNA *self= PyObject_New(BPy_PropertyCollectionIterRNA, &pyrna_prop_collection_iter_Type); + BPy_PropertyCollectionIterRNA *self = PyObject_New(BPy_PropertyCollectionIterRNA, &pyrna_prop_collection_iter_Type); #ifdef USE_WEAKREFS - self->in_weakreflist= NULL; + self->in_weakreflist = NULL; #endif RNA_property_collection_begin(ptr, prop, &self->iter); @@ -5798,7 +5855,7 @@ return NULL; } else { - BPy_StructRNA *pyrna= (BPy_StructRNA *)pyrna_struct_CreatePyObject(&self->iter.ptr); + BPy_StructRNA *pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&self->iter.ptr); #ifdef USE_PYRNA_STRUCT_REFERENCE if (pyrna) { /* unlikely but may fail */ @@ -5854,7 +5911,7 @@ /* python deals with the circular ref */ RNA_pointer_create(NULL, &RNA_Struct, srna, &ptr); - item= pyrna_struct_CreatePyObject(&ptr); + item = pyrna_struct_CreatePyObject(&ptr); /* note, must set the class not the __dict__ else the internal slots are not updated correctly */ PyObject_SetAttr(newclass, bpy_intern_str_bl_rna, item); @@ -5871,19 +5928,19 @@ /* Assume RNA_struct_py_type_get(srna) was already checked */ StructRNA *base; - PyObject *py_base= NULL; + PyObject *py_base = NULL; /* get the base type */ - base= RNA_struct_base(srna); + base = RNA_struct_base(srna); if (base && base != srna) { /*/printf("debug subtype %s %p\n", RNA_struct_identifier(srna), srna); */ - py_base= pyrna_srna_Subtype(base); //, bpy_types_dict); + py_base = pyrna_srna_Subtype(base); //, bpy_types_dict); Py_DECREF(py_base); /* srna owns, this is only to pass as an arg */ } - if (py_base==NULL) { - py_base= (PyObject *)&pyrna_struct_Type; + if (py_base == NULL) { + py_base = (PyObject *)&pyrna_struct_Type; } return py_base; @@ -5891,47 +5948,47 @@ /* check if we have a native python subclass, use it when it exists * return a borrowed reference */ -static PyObject *bpy_types_dict= NULL; +static PyObject *bpy_types_dict = NULL; static PyObject* pyrna_srna_ExternalType(StructRNA *srna) { - const char *idname= RNA_struct_identifier(srna); + const char *idname = RNA_struct_identifier(srna); PyObject *newclass; - if (bpy_types_dict==NULL) { - PyObject *bpy_types= PyImport_ImportModuleLevel((char *)"bpy_types", NULL, NULL, NULL, 0); + if (bpy_types_dict == NULL) { + PyObject *bpy_types = PyImport_ImportModuleLevel((char *)"bpy_types", NULL, NULL, NULL, 0); - if (bpy_types==NULL) { + if (bpy_types == NULL) { PyErr_Print(); PyErr_Clear(); fprintf(stderr, "%s: failed to find 'bpy_types' module\n", __func__); return NULL; } - bpy_types_dict= PyModule_GetDict(bpy_types); // borrow + bpy_types_dict = PyModule_GetDict(bpy_types); // borrow Py_DECREF(bpy_types); // fairly safe to assume the dict is kept } - newclass= PyDict_GetItemString(bpy_types_dict, idname); + newclass = PyDict_GetItemString(bpy_types_dict, idname); /* sanity check, could skip this unless in debug mode */ if (newclass) { - PyObject *base_compare= pyrna_srna_PyBase(srna); - //PyObject *slots= PyObject_GetAttrString(newclass, "__slots__"); // cant do this because it gets superclasses values! - //PyObject *bases= PyObject_GetAttrString(newclass, "__bases__"); // can do this but faster not to. - PyObject *tp_bases= ((PyTypeObject *)newclass)->tp_bases; - PyObject *tp_slots= PyDict_GetItem(((PyTypeObject *)newclass)->tp_dict, bpy_intern_str___slots__); + PyObject *base_compare = pyrna_srna_PyBase(srna); + //PyObject *slots = PyObject_GetAttrString(newclass, "__slots__"); // cant do this because it gets superclasses values! + //PyObject *bases = PyObject_GetAttrString(newclass, "__bases__"); // can do this but faster not to. + PyObject *tp_bases = ((PyTypeObject *)newclass)->tp_bases; + PyObject *tp_slots = PyDict_GetItem(((PyTypeObject *)newclass)->tp_dict, bpy_intern_str___slots__); - if (tp_slots==NULL) { + if (tp_slots == NULL) { fprintf(stderr, "%s: expected class '%s' to have __slots__ defined\n\nSee bpy_types.py\n", __func__, idname); - newclass= NULL; + newclass = NULL; } else if (PyTuple_GET_SIZE(tp_bases)) { - PyObject *base= PyTuple_GET_ITEM(tp_bases, 0); + PyObject *base = PyTuple_GET_ITEM(tp_bases, 0); if (base_compare != base) { fprintf(stderr, "%s: incorrect subclassing of SRNA '%s'\nSee bpy_types.py\n", __func__, idname); PyC_ObSpit("Expected! ", base_compare); - newclass= NULL; + newclass = NULL; } else { if (G.f & G_DEBUG) @@ -5945,16 +6002,16 @@ static PyObject* pyrna_srna_Subtype(StructRNA *srna) { - PyObject *newclass= NULL; + PyObject *newclass = NULL; /* stupid/simple case */ if (srna == NULL) { - newclass= NULL; /* Nothing to do */ + newclass = NULL; /* Nothing to do */ } /* the class may have already been declared & allocated */ - else if ((newclass= RNA_struct_py_type_get(srna))) { + else if ((newclass = RNA_struct_py_type_get(srna))) { Py_INCREF(newclass); } /* check if bpy_types.py module has the class defined in it */ - else if ((newclass= pyrna_srna_ExternalType(srna))) { + else if ((newclass = pyrna_srna_ExternalType(srna))) { pyrna_subtype_set_rna(newclass, srna); Py_INCREF(newclass); } /* create a new class instance with the C api @@ -5962,32 +6019,32 @@ else { /* subclass equivalents - class myClass(myBase): - some='value' # or ... - - myClass= type(name='myClass', bases=(myBase,), dict={'__module__':'bpy.types'}) + some = 'value' # or ... + - myClass = type(name='myClass', bases=(myBase,), dict={'__module__':'bpy.types'}) */ /* Assume RNA_struct_py_type_get(srna) was already checked */ - PyObject *py_base= pyrna_srna_PyBase(srna); + PyObject *py_base = pyrna_srna_PyBase(srna); PyObject *metaclass; - const char *idname= RNA_struct_identifier(srna); + const char *idname = RNA_struct_identifier(srna); /* remove __doc__ for now */ - // const char *descr= RNA_struct_ui_description(srna); - // if (!descr) descr= "(no docs)"; + // const char *descr = RNA_struct_ui_description(srna); + // if (!descr) descr = "(no docs)"; // "__doc__", descr if ( RNA_struct_idprops_check(srna) && !PyObject_IsSubclass(py_base, (PyObject *)&pyrna_struct_meta_idprop_Type)) { - metaclass= (PyObject *)&pyrna_struct_meta_idprop_Type; + metaclass = (PyObject *)&pyrna_struct_meta_idprop_Type; } else { - metaclass= (PyObject *)&PyType_Type; + metaclass = (PyObject *)&PyType_Type; } /* always use O not N when calling, N causes refcount errors */ - newclass= PyObject_CallFunction(metaclass, (char *)"s(O){sss()}", - idname, py_base, "__module__","bpy.types", "__slots__"); + newclass = PyObject_CallFunction(metaclass, (char *)"s(O){sss()}", + idname, py_base, "__module__","bpy.types", "__slots__"); /* newclass will now have 2 ref's, ???, probably 1 is internal since decrefing here segfaults */ @@ -6031,24 +6088,24 @@ /*-----------------------CreatePyObject---------------------------------*/ PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr) { - BPy_StructRNA *pyrna= NULL; + BPy_StructRNA *pyrna = NULL; /* note: don't rely on this to return None since NULL data with a valid type can often crash */ - if (ptr->data==NULL && ptr->type==NULL) { /* Operator RNA has NULL data */ + if (ptr->data == NULL && ptr->type == NULL) { /* Operator RNA has NULL data */ Py_RETURN_NONE; } else { - PyTypeObject *tp= (PyTypeObject *)pyrna_struct_Subtype(ptr); + PyTypeObject *tp = (PyTypeObject *)pyrna_struct_Subtype(ptr); if (tp) { - pyrna= (BPy_StructRNA *) tp->tp_alloc(tp, 0); + pyrna = (BPy_StructRNA *) tp->tp_alloc(tp, 0); Py_DECREF(tp); /* srna owns, cant hold a ref */ } else { fprintf(stderr, "%s: could not make type\n", __func__); - pyrna= (BPy_StructRNA *) PyObject_GC_New(BPy_StructRNA, &pyrna_struct_Type); + pyrna = (BPy_StructRNA *) PyObject_GC_New(BPy_StructRNA, &pyrna_struct_Type); #ifdef USE_WEAKREFS - pyrna->in_weakreflist= NULL; + pyrna->in_weakreflist = NULL; #endif } } @@ -6058,13 +6115,13 @@ return NULL; } - pyrna->ptr= *ptr; + pyrna->ptr = *ptr; #ifdef PYRNA_FREE_SUPPORT - pyrna->freeptr= FALSE; + pyrna->freeptr = FALSE; #endif #ifdef USE_PYRNA_STRUCT_REFERENCE - pyrna->reference= NULL; + pyrna->reference = NULL; #endif // PyC_ObSpit("NewStructRNA: ", (PyObject *)pyrna); @@ -6085,28 +6142,28 @@ PyTypeObject *type; if (RNA_property_type(prop) != PROP_COLLECTION) { - type= &pyrna_prop_Type; + type = &pyrna_prop_Type; } else { if ((RNA_property_flag(prop) & PROP_IDPROPERTY) == 0) { - type= &pyrna_prop_collection_Type; + type = &pyrna_prop_collection_Type; } else { - type= &pyrna_prop_collection_idprop_Type; + type = &pyrna_prop_collection_idprop_Type; } } - pyrna= (BPy_PropertyRNA *) PyObject_NEW(BPy_PropertyRNA, type); + pyrna = (BPy_PropertyRNA *) PyObject_NEW(BPy_PropertyRNA, type); #ifdef USE_WEAKREFS - pyrna->in_weakreflist= NULL; + pyrna->in_weakreflist = NULL; #endif } else { - pyrna= (BPy_PropertyRNA *) PyObject_NEW(BPy_PropertyArrayRNA, &pyrna_prop_array_Type); - ((BPy_PropertyArrayRNA *)pyrna)->arraydim= 0; - ((BPy_PropertyArrayRNA *)pyrna)->arrayoffset= 0; + pyrna = (BPy_PropertyRNA *) PyObject_NEW(BPy_PropertyArrayRNA, &pyrna_prop_array_Type); + ((BPy_PropertyArrayRNA *)pyrna)->arraydim = 0; + ((BPy_PropertyArrayRNA *)pyrna)->arrayoffset = 0; #ifdef USE_WEAKREFS - ((BPy_PropertyArrayRNA *)pyrna)->in_weakreflist= NULL; + ((BPy_PropertyArrayRNA *)pyrna)->in_weakreflist = NULL; #endif } @@ -6115,8 +6172,8 @@ return NULL; } - pyrna->ptr= *ptr; - pyrna->prop= prop; + pyrna->ptr = *ptr; + pyrna->prop = prop; #ifdef USE_PYRNA_INVALIDATE_WEAKREF if (ptr->id.data) { @@ -6130,16 +6187,16 @@ void BPY_rna_init(void) { #ifdef USE_MATHUTILS // register mathutils callbacks, ok to run more then once. - mathutils_rna_array_cb_index= Mathutils_RegisterCallback(&mathutils_rna_array_cb); - mathutils_rna_matrix_cb_index= Mathutils_RegisterCallback(&mathutils_rna_matrix_cb); + mathutils_rna_array_cb_index = Mathutils_RegisterCallback(&mathutils_rna_array_cb); + mathutils_rna_matrix_cb_index = Mathutils_RegisterCallback(&mathutils_rna_matrix_cb); #endif /* for some reason MSVC complains of these */ #if defined(_MSC_VER) || defined(FREE_WINDOWS) - pyrna_struct_meta_idprop_Type.tp_base= &PyType_Type; + pyrna_struct_meta_idprop_Type.tp_base = &PyType_Type; - pyrna_prop_collection_iter_Type.tp_iter= PyObject_SelfIter; - pyrna_prop_collection_iter_Type.tp_getattro= PyObject_GenericGetAttr; + pyrna_prop_collection_iter_Type.tp_iter = PyObject_SelfIter; + pyrna_prop_collection_iter_Type.tp_getattro = PyObject_GenericGetAttr; #endif /* metaclass */ @@ -6171,7 +6228,7 @@ } /* bpy.data from python */ -static PointerRNA *rna_module_ptr= NULL; +static PointerRNA *rna_module_ptr = NULL; PyObject *BPY_rna_module(void) { BPy_StructRNA *pyrna; @@ -6179,9 +6236,9 @@ /* for now, return the base RNA type rather than a real module */ RNA_main_pointer_create(G.main, &ptr); - pyrna= (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr); + pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr); - rna_module_ptr= &pyrna->ptr; + rna_module_ptr = &pyrna->ptr; return (PyObject *)pyrna; } @@ -6190,7 +6247,7 @@ #if 0 RNA_main_pointer_create(G.main, rna_module_ptr); #else - rna_module_ptr->data= G.main; /* just set data is enough */ + rna_module_ptr->data = G.main; /* just set data is enough */ #endif } @@ -6216,15 +6273,15 @@ { PointerRNA newptr; PyObject *ret; - const char *name= _PyUnicode_AsString(pyname); + const char *name = _PyUnicode_AsString(pyname); if (name == NULL) { PyErr_SetString(PyExc_AttributeError, "bpy.types: __getattr__ must be a string"); - ret= NULL; + ret = NULL; } else if (RNA_property_collection_lookup_string(&self->ptr, self->prop, name, &newptr)) { - ret= pyrna_struct_Subtype(&newptr); - if (ret==NULL) { + ret = pyrna_struct_Subtype(&newptr); + if (ret == NULL) { PyErr_Format(PyExc_RuntimeError, "bpy.types.%.200s subtype could not be generated, this is a bug!", _PyUnicode_AsString(pyname)); @@ -6238,7 +6295,7 @@ return NULL; #endif /* The error raised here will be displayed */ - ret= PyObject_GenericGetAttr((PyObject *)self, pyname); + ret = PyObject_GenericGetAttr((PyObject *)self, pyname); } return ret; @@ -6248,11 +6305,13 @@ static PyObject *pyrna_register_class(PyObject *self, PyObject *py_class); static PyObject *pyrna_unregister_class(PyObject *self, PyObject *py_class); -static struct PyMethodDef pyrna_basetype_methods[]= { +static struct PyMethodDef pyrna_basetype_methods[] = { {"__dir__", (PyCFunction)pyrna_basetype_dir, METH_NOARGS, ""}, {NULL, NULL, 0, NULL} }; +/* used to call ..._keys() direct, but we need to filter out operator subclasses */ +#if 0 static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self) { PyObject *list; @@ -6261,11 +6320,11 @@ PyMethodDef *meth; #endif - list= pyrna_prop_collection_keys(self); /* like calling structs.keys(), avoids looping here */ + list = pyrna_prop_collection_keys(self); /* like calling structs.keys(), avoids looping here */ #if 0 /* for now only contains __dir__ */ - for (meth=pyrna_basetype_methods; meth->ml_name; meth++) { - name= PyUnicode_FromString(meth->ml_name); + for (meth = pyrna_basetype_methods; meth->ml_name; meth++) { + name = PyUnicode_FromString(meth->ml_name); PyList_Append(list, name); Py_DECREF(name); } @@ -6273,53 +6332,81 @@ return list; } -static PyTypeObject pyrna_basetype_Type= BLANK_PYTHON_TYPE; +#else + +static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self) +{ + PyObject *ret = PyList_New(0); + PyObject *item; + + RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) { + StructRNA *srna = itemptr.data; + StructRNA *srna_base = RNA_struct_base(itemptr.data); + /* skip own operators, these double up [#29666] */ + if (srna_base == &RNA_Operator) { + /* do nothing */ + } + else { + /* add to python list */ + item = PyUnicode_FromString(RNA_struct_identifier(srna)); + PyList_Append(ret, item); + Py_DECREF(item); + } + } + RNA_PROP_END; + + return ret; +} + +#endif + +static PyTypeObject pyrna_basetype_Type = BLANK_PYTHON_TYPE; PyObject *BPY_rna_types(void) { BPy_BaseTypeRNA *self; - if ((pyrna_basetype_Type.tp_flags & Py_TPFLAGS_READY)==0) { - pyrna_basetype_Type.tp_name= "RNA_Types"; - pyrna_basetype_Type.tp_basicsize= sizeof(BPy_BaseTypeRNA); - pyrna_basetype_Type.tp_getattro= (getattrofunc) pyrna_basetype_getattro; - pyrna_basetype_Type.tp_flags= Py_TPFLAGS_DEFAULT; - pyrna_basetype_Type.tp_methods= pyrna_basetype_methods; + if ((pyrna_basetype_Type.tp_flags & Py_TPFLAGS_READY) == 0) { + pyrna_basetype_Type.tp_name = "RNA_Types"; + pyrna_basetype_Type.tp_basicsize = sizeof(BPy_BaseTypeRNA); + pyrna_basetype_Type.tp_getattro = (getattrofunc) pyrna_basetype_getattro; + pyrna_basetype_Type.tp_flags = Py_TPFLAGS_DEFAULT; + pyrna_basetype_Type.tp_methods = pyrna_basetype_methods; if (PyType_Ready(&pyrna_basetype_Type) < 0) return NULL; } - self= (BPy_BaseTypeRNA *)PyObject_NEW(BPy_BaseTypeRNA, &pyrna_basetype_Type); + self = (BPy_BaseTypeRNA *)PyObject_NEW(BPy_BaseTypeRNA, &pyrna_basetype_Type); /* avoid doing this lookup for every getattr */ RNA_blender_rna_pointer_create(&self->ptr); - self->prop= RNA_struct_find_property(&self->ptr, "structs"); + self->prop = RNA_struct_find_property(&self->ptr, "structs"); #ifdef USE_WEAKREFS - self->in_weakreflist= NULL; + self->in_weakreflist = NULL; #endif return (PyObject *)self; } StructRNA *pyrna_struct_as_srna(PyObject *self, int parent, const char *error_prefix) { - BPy_StructRNA *py_srna= NULL; + BPy_StructRNA *py_srna = NULL; StructRNA *srna; /* ack, PyObject_GetAttrString wont look up this types tp_dict first :/ */ if (PyType_Check(self)) { - py_srna= (BPy_StructRNA *)PyDict_GetItem(((PyTypeObject *)self)->tp_dict, bpy_intern_str_bl_rna); + py_srna = (BPy_StructRNA *)PyDict_GetItem(((PyTypeObject *)self)->tp_dict, bpy_intern_str_bl_rna); Py_XINCREF(py_srna); } if (parent) { /* be very careful with this since it will return a parent classes srna. * modifying this will do confusing stuff! */ - if (py_srna==NULL) - py_srna= (BPy_StructRNA*)PyObject_GetAttr(self, bpy_intern_str_bl_rna); + if (py_srna == NULL) + py_srna = (BPy_StructRNA *)PyObject_GetAttr(self, bpy_intern_str_bl_rna); } - if (py_srna==NULL) { + if (py_srna == NULL) { PyErr_Format(PyExc_RuntimeError, "%.200s, missing bl_rna attribute from '%.200s' instance (may not be registered)", error_prefix, Py_TYPE(self)->tp_name); @@ -6343,7 +6430,7 @@ return NULL; } - srna= py_srna->ptr.data; + srna = py_srna->ptr.data; Py_DECREF(py_srna); return srna; @@ -6356,13 +6443,13 @@ StructRNA *srna_from_self(PyObject *self, const char *error_prefix) { - if (self==NULL) { + if (self == NULL) { return NULL; } else if (PyCapsule_CheckExact(self)) { return PyCapsule_GetPointer(self, NULL); } - else if (PyType_Check(self)==0) { + else if (PyType_Check(self) == 0) { return NULL; } else { @@ -6375,7 +6462,7 @@ PyErr_Fetch(&error_type, &error_value, &error_traceback); PyErr_Clear(); - srna= pyrna_struct_as_srna(self, 0, error_prefix); + srna = pyrna_struct_as_srna(self, 0, error_prefix); if (!PyErr_Occurred()) { PyErr_Restore(error_type, error_value, error_traceback); @@ -6396,22 +6483,22 @@ if (PyArg_ParseTuple(item, "OO!", &py_func, &PyDict_Type, &py_kw)) { PyObject *args_fake; - if (*_PyUnicode_AsString(key)=='_') { + if (*_PyUnicode_AsString(key) == '_') { PyErr_Format(PyExc_ValueError, "bpy_struct \"%.200s\" registration error: " "%.200s could not register because the property starts with an '_'\n", RNA_struct_identifier(srna), _PyUnicode_AsString(key)); return -1; } - py_srna_cobject= PyCapsule_New(srna, NULL, NULL); + py_srna_cobject = PyCapsule_New(srna, NULL, NULL); /* not 100% nice :/, modifies the dict passed, should be ok */ PyDict_SetItem(py_kw, bpy_intern_str_attr, key); - args_fake= PyTuple_New(1); + args_fake = PyTuple_New(1); PyTuple_SET_ITEM(args_fake, 0, py_srna_cobject); - py_ret= PyObject_Call(py_func, args_fake, py_kw); + py_ret = PyObject_Call(py_func, args_fake, py_kw); Py_DECREF(args_fake); /* free's py_srna_cobject too */ @@ -6447,19 +6534,19 @@ { PyObject *item, *key; PyObject *order; - Py_ssize_t pos= 0; - int ret= 0; + Py_ssize_t pos = 0; + int ret = 0; /* in both cases PyDict_CheckExact(class_dict) will be true even * though Operators have a metaclass dict namespace */ - if ((order= PyDict_GetItem(class_dict, bpy_intern_str_order)) && PyList_CheckExact(order)) { - for (pos= 0; postp_bases); + const int len = PyTuple_GET_SIZE(py_class->tp_bases); int i, ret; /* first scan base classes for registerable properties */ - for (i=0; itp_bases, i); + for (i = 0; i < len; i++) { + PyTypeObject *py_superclass = (PyTypeObject *)PyTuple_GET_ITEM(py_class->tp_bases, i); /* the rules for using these base classes are not clear, * 'object' is of course not worth looking into and @@ -6499,7 +6586,7 @@ if (py_superclass != &PyBaseObject_Type && !PyObject_IsSubclass((PyObject *)py_superclass, (PyObject *)&pyrna_struct_Type) ) { - ret= pyrna_deferred_register_class_recursive(srna, py_superclass); + ret = pyrna_deferred_register_class_recursive(srna, py_superclass); if (ret != 0) { return ret; @@ -6525,13 +6612,13 @@ static int rna_function_arg_count(FunctionRNA *func) { - const ListBase *lb= RNA_function_defined_parameters(func); + const ListBase *lb = RNA_function_defined_parameters(func); PropertyRNA *parm; Link *link; - int count= (RNA_function_flag(func) & FUNC_NO_SELF) ? 0 : 1; + int count = (RNA_function_flag(func) & FUNC_NO_SELF) ? 0 : 1; - for (link=lb->first; link; link=link->next) { - parm= (PropertyRNA*)link; + for (link = lb->first; link; link = link->next) { + parm = (PropertyRNA *)link; if (!(RNA_property_flag(parm) & PROP_OUTPUT)) count++; } @@ -6545,13 +6632,13 @@ Link *link; FunctionRNA *func; PropertyRNA *prop; - StructRNA *srna= dummyptr->type; - const char *class_type= RNA_struct_identifier(srna); - PyObject *py_class= (PyObject*)py_data; - PyObject *base_class= RNA_struct_py_type_get(srna); + StructRNA *srna = dummyptr->type; + const char *class_type = RNA_struct_identifier(srna); + PyObject *py_class = (PyObject *)py_data; + PyObject *base_class = RNA_struct_py_type_get(srna); PyObject *item; int i, flag, arg_count, func_arg_count; - const char *py_class_name= ((PyTypeObject *)py_class)->tp_name; // __name__ + const char *py_class_name = ((PyTypeObject *)py_class)->tp_name; // __name__ if (base_class) { @@ -6564,22 +6651,22 @@ } /* verify callback functions */ - lb= RNA_struct_type_functions(srna); - i= 0; - for (link=lb->first; link; link=link->next) { - func= (FunctionRNA*)link; - flag= RNA_function_flag(func); + lb = RNA_struct_type_functions(srna); + i = 0; + for (link = lb->first; link; link = link->next) { + func = (FunctionRNA *)link; + flag = RNA_function_flag(func); if (!(flag & FUNC_REGISTER)) continue; - item= PyObject_GetAttrString(py_class, RNA_function_identifier(func)); + item = PyObject_GetAttrString(py_class, RNA_function_identifier(func)); - have_function[i]= (item != NULL); + have_function[i] = (item != NULL); i++; - if (item==NULL) { - if ((flag & FUNC_REGISTER_OPTIONAL)==0) { + if (item == NULL) { + if ((flag & FUNC_REGISTER_OPTIONAL) == 0) { PyErr_Format(PyExc_AttributeError, "expected %.200s, %.200s class to have an \"%.200s\" attribute", class_type, py_class_name, @@ -6592,16 +6679,16 @@ else { Py_DECREF(item); /* no need to keep a ref, the class owns it (technically we should keep a ref but...) */ if (flag & FUNC_NO_SELF) { - if (PyMethod_Check(item)==0) { + if (PyMethod_Check(item) == 0) { PyErr_Format(PyExc_TypeError, "expected %.200s, %.200s class \"%.200s\" attribute to be a method, not a %.200s", class_type, py_class_name, RNA_function_identifier(func), Py_TYPE(item)->tp_name); return -1; } - item= ((PyMethodObject *)item)->im_func; + item = ((PyMethodObject *)item)->im_func; } else { - if (PyFunction_Check(item)==0) { + if (PyFunction_Check(item) == 0) { PyErr_Format(PyExc_TypeError, "expected %.200s, %.200s class \"%.200s\" attribute to be a function, not a %.200s", class_type, py_class_name, RNA_function_identifier(func), Py_TYPE(item)->tp_name); @@ -6609,10 +6696,10 @@ } } - func_arg_count= rna_function_arg_count(func); + func_arg_count = rna_function_arg_count(func); if (func_arg_count >= 0) { /* -1 if we dont care*/ - arg_count= ((PyCodeObject *)PyFunction_GET_CODE(item))->co_argcount; + arg_count = ((PyCodeObject *)PyFunction_GET_CODE(item))->co_argcount; /* note, the number of args we check for and the number of args we give to * @classmethods are different (quirk of python), @@ -6632,24 +6719,24 @@ } /* verify properties */ - lb= RNA_struct_type_properties(srna); - for (link=lb->first; link; link=link->next) { + lb = RNA_struct_type_properties(srna); + for (link = lb->first; link; link = link->next) { const char *identifier; - prop= (PropertyRNA*)link; - flag= RNA_property_flag(prop); + prop = (PropertyRNA *)link; + flag = RNA_property_flag(prop); if (!(flag & PROP_REGISTER)) continue; - identifier= RNA_property_identifier(prop); - item= PyObject_GetAttrString(py_class, identifier); + identifier = RNA_property_identifier(prop); + item = PyObject_GetAttrString(py_class, identifier); - if (item==NULL) { + if (item == NULL) { /* Sneaky workaround to use the class name as the bl_idname */ #define BPY_REPLACEMENT_STRING(rna_attr, py_attr) \ if (strcmp(identifier, rna_attr) == 0) { \ - item= PyObject_GetAttrString(py_class, py_attr); \ + item = PyObject_GetAttrString(py_class, py_attr); \ if (item && item != Py_None) { \ if (pyrna_py_to_prop(dummyptr, prop, NULL, \ item, "validating class:") != 0) \ @@ -6691,36 +6778,36 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, ParameterList *parms) { PyObject *args; - PyObject *ret= NULL, *py_srna= NULL, *py_class_instance= NULL, *parmitem; + PyObject *ret = NULL, *py_srna = NULL, *py_class_instance = NULL, *parmitem; PyTypeObject *py_class; - void **py_class_instance_store= NULL; + void **py_class_instance_store = NULL; PropertyRNA *parm; ParameterIterator iter; PointerRNA funcptr; - int err= 0, i, flag, ret_len=0; - const char is_static= (RNA_function_flag(func) & FUNC_NO_SELF) != 0; + int err = 0, i, flag, ret_len = 0; + const char is_static = (RNA_function_flag(func) & FUNC_NO_SELF) != 0; /* annoying!, need to check if the screen gets set to NULL which is a * hint that the file was actually re-loaded. */ char is_valid_wm; - PropertyRNA *pret_single= NULL; - void *retdata_single= NULL; + PropertyRNA *pret_single = NULL; + void *retdata_single = NULL; PyGILState_STATE gilstate; #ifdef USE_PEDANTIC_WRITE - const int is_operator= RNA_struct_is_a(ptr->type, &RNA_Operator); - const char *func_id= RNA_function_identifier(func); + const int is_operator = RNA_struct_is_a(ptr->type, &RNA_Operator); + const char *func_id = RNA_function_identifier(func); /* testing, for correctness, not operator and not draw function */ - const short is_readonly= ((strncmp("draw", func_id, 4) ==0) || /* draw or draw_header */ + const short is_readonly = ((strncmp("draw", func_id, 4) == 0) || /* draw or draw_header */ /*strstr("render", func_id) ||*/ !is_operator); #endif - py_class= RNA_struct_py_type_get(ptr->type); + py_class = RNA_struct_py_type_get(ptr->type); /* rare case. can happen when registering subclasses */ - if (py_class==NULL) { + if (py_class == NULL) { fprintf(stderr, "%s: unable to get python class for rna struct '%.200s'\n", __func__, RNA_struct_identifier(ptr->type)); return -1; @@ -6728,10 +6815,10 @@ /* XXX, this is needed because render engine calls without a context * this should be supported at some point but at the moment its not! */ - if (C==NULL) - C= BPy_GetContext(); + if (C == NULL) + C = BPy_GetContext(); - is_valid_wm= (CTX_wm_manager(C) != NULL); + is_valid_wm = (CTX_wm_manager(C) != NULL); bpy_context_set(C, &gilstate); @@ -6742,29 +6829,29 @@ if (instance) { if (*instance) { - py_class_instance= *instance; + py_class_instance = *instance; Py_INCREF(py_class_instance); } else { /* store the instance here once its created */ - py_class_instance_store= instance; + py_class_instance_store = instance; } } } /* end exception */ - if (py_class_instance==NULL) - py_srna= pyrna_struct_CreatePyObject(ptr); + if (py_class_instance == NULL) + py_srna = pyrna_struct_CreatePyObject(ptr); if (py_class_instance) { /* special case, instance is cached */ } else if (py_srna == NULL) { - py_class_instance= NULL; + py_class_instance = NULL; } else if (py_srna == Py_None) { /* probably wont ever happen but possible */ Py_DECREF(py_srna); - py_class_instance= NULL; + py_class_instance = NULL; } else { #if 1 @@ -6774,106 +6861,106 @@ */ if (py_class->tp_init) { #ifdef USE_PEDANTIC_WRITE - const int prev_write= rna_disallow_writes; - rna_disallow_writes= is_operator ? FALSE : TRUE; /* only operators can write on __init__ */ + const int prev_write = rna_disallow_writes; + rna_disallow_writes = is_operator ? FALSE : TRUE; /* only operators can write on __init__ */ #endif /* true in most cases even when the class its self doesn't define an __init__ function. */ - args= PyTuple_New(0); + args = PyTuple_New(0); if (py_class->tp_init(py_srna, args, NULL) < 0) { Py_DECREF(py_srna); - py_srna= NULL; + py_srna = NULL; /* err set below */ } Py_DECREF(args); #ifdef USE_PEDANTIC_WRITE - rna_disallow_writes= prev_write; + rna_disallow_writes = prev_write; #endif } - py_class_instance= py_srna; + py_class_instance = py_srna; #else - const int prev_write= rna_disallow_writes; - rna_disallow_writes= TRUE; + const int prev_write = rna_disallow_writes; + rna_disallow_writes = TRUE; /* 'almost' all the time calling the class isn't needed. * We could just do... - py_class_instance= py_srna; + py_class_instance = py_srna; Py_INCREF(py_class_instance); * This would work fine but means __init__ functions wouldnt run. * none of blenders default scripts use __init__ but its nice to call it * for general correctness. just to note why this is here when it could be safely removed. */ - args= PyTuple_New(1); + args = PyTuple_New(1); PyTuple_SET_ITEM(args, 0, py_srna); - py_class_instance= PyObject_Call(py_class, args, NULL); + py_class_instance = PyObject_Call(py_class, args, NULL); Py_DECREF(args); - rna_disallow_writes= prev_write; + rna_disallow_writes = prev_write; #endif if (py_class_instance == NULL) { - err= -1; /* so the error is not overridden below */ + err = -1; /* so the error is not overridden below */ } else if (py_class_instance_store) { - *py_class_instance_store= py_class_instance; + *py_class_instance_store = py_class_instance; Py_INCREF(py_class_instance); } } } if (err != -1 && (is_static || py_class_instance)) { /* Initializing the class worked, now run its invoke function */ - PyObject *item= PyObject_GetAttrString((PyObject *)py_class, RNA_function_identifier(func)); -// flag= RNA_function_flag(func); + PyObject *item = PyObject_GetAttrString((PyObject *)py_class, RNA_function_identifier(func)); +// flag = RNA_function_flag(func); if (item) { RNA_pointer_create(NULL, &RNA_Function, func, &funcptr); - args= PyTuple_New(rna_function_arg_count(func)); /* first arg is included in 'item' */ + args = PyTuple_New(rna_function_arg_count(func)); /* first arg is included in 'item' */ if (is_static) { - i= 0; + i = 0; } else { PyTuple_SET_ITEM(args, 0, py_class_instance); - i= 1; + i = 1; } RNA_parameter_list_begin(parms, &iter); /* parse function parameters */ for (; iter.valid; RNA_parameter_list_next(&iter)) { - parm= iter.parm; - flag= RNA_property_flag(parm); + parm = iter.parm; + flag = RNA_property_flag(parm); /* only useful for single argument returns, we'll need another list loop for multiple */ if (flag & PROP_OUTPUT) { ret_len++; - if (pret_single==NULL) { - pret_single= parm; - retdata_single= iter.data; + if (pret_single == NULL) { + pret_single = parm; + retdata_single = iter.data; } continue; } - parmitem= pyrna_param_to_py(&funcptr, parm, iter.data); + parmitem = pyrna_param_to_py(&funcptr, parm, iter.data); PyTuple_SET_ITEM(args, i, parmitem); i++; } #ifdef USE_PEDANTIC_WRITE - rna_disallow_writes= is_readonly ? TRUE:FALSE; + rna_disallow_writes = is_readonly ? TRUE:FALSE; #endif /* *** Main Caller *** */ - ret= PyObject_Call(item, args, NULL); + ret = PyObject_Call(item, args, NULL); /* *** Done Calling *** */ #ifdef USE_PEDANTIC_WRITE - rna_disallow_writes= FALSE; + rna_disallow_writes = FALSE; #endif RNA_parameter_list_end(&iter); @@ -6886,7 +6973,7 @@ PyErr_Format(PyExc_TypeError, "could not find function %.200s in %.200s to execute callback", RNA_function_identifier(func), RNA_struct_identifier(ptr->type)); - err= -1; + err = -1; } } else { @@ -6895,23 +6982,23 @@ PyErr_Format(PyExc_RuntimeError, "could not create instance of %.200s to call callback function %.200s", RNA_struct_identifier(ptr->type), RNA_function_identifier(func)); - err= -1; + err = -1; } } if (ret == NULL) { /* covers py_class_instance failing too */ - err= -1; + err = -1; } else { - if (ret_len==0 && ret != Py_None) { + if (ret_len == 0 && ret != Py_None) { PyErr_Format(PyExc_RuntimeError, "expected class %.200s, function %.200s to return None, not %.200s", RNA_struct_identifier(ptr->type), RNA_function_identifier(func), Py_TYPE(ret)->tp_name); - err= -1; + err = -1; } - else if (ret_len==1) { - err= pyrna_py_to_prop(&funcptr, pret_single, retdata_single, ret, ""); + else if (ret_len == 1) { + err = pyrna_py_to_prop(&funcptr, pret_single, retdata_single, ret, ""); /* when calling operator funcs only gives Function.result with * no line number since the func has finished calling on error, @@ -6926,32 +7013,32 @@ } else if (ret_len > 1) { - if (PyTuple_Check(ret)==0) { + if (PyTuple_Check(ret) == 0) { PyErr_Format(PyExc_RuntimeError, "expected class %.200s, function %.200s to return a tuple of size %d, not %.200s", RNA_struct_identifier(ptr->type), RNA_function_identifier(func), ret_len, Py_TYPE(ret)->tp_name); - err= -1; + err = -1; } else if (PyTuple_GET_SIZE(ret) != ret_len) { PyErr_Format(PyExc_RuntimeError, "class %.200s, function %.200s to returned %d items, expected %d", RNA_struct_identifier(ptr->type), RNA_function_identifier(func), PyTuple_GET_SIZE(ret), ret_len); - err= -1; + err = -1; } else { RNA_parameter_list_begin(parms, &iter); /* parse function parameters */ - for (i= 0; iter.valid; RNA_parameter_list_next(&iter)) { - parm= iter.parm; - flag= RNA_property_flag(parm); + for (i = 0; iter.valid; RNA_parameter_list_next(&iter)) { + parm = iter.parm; + flag = RNA_property_flag(parm); /* only useful for single argument returns, we'll need another list loop for multiple */ if (flag & PROP_OUTPUT) { - err= pyrna_py_to_prop(&funcptr, parm, iter.data, + err = pyrna_py_to_prop(&funcptr, parm, iter.data, PyTuple_GET_ITEM(ret, i++), "calling class function:"); if (err) { @@ -6969,17 +7056,17 @@ if (err != 0) { ReportList *reports; /* alert the user, else they wont know unless they see the console. */ - if ( (!is_static) && - (ptr->data) && - (RNA_struct_is_a(ptr->type, &RNA_Operator)) && - (is_valid_wm == (CTX_wm_manager(C) != NULL))) + if ( (!is_static) && + (ptr->data) && + (RNA_struct_is_a(ptr->type, &RNA_Operator)) && + (is_valid_wm == (CTX_wm_manager(C) != NULL))) { - wmOperator *op= ptr->data; - reports= op->reports; + wmOperator *op = ptr->data; + reports = op->reports; } else { /* wont alert users but they can view in 'info' space */ - reports= CTX_wm_reports(C); + reports = CTX_wm_reports(C); } BPy_errors_to_report(reports); @@ -6996,13 +7083,13 @@ static void bpy_class_free(void *pyob_ptr) { - PyObject *self= (PyObject *)pyob_ptr; + PyObject *self = (PyObject *)pyob_ptr; PyGILState_STATE gilstate; - gilstate= PyGILState_Ensure(); + gilstate = PyGILState_Ensure(); // breaks re-registering classes - // PyDict_Clear(((PyTypeObject*)self)->tp_dict); + // PyDict_Clear(((PyTypeObject *)self)->tp_dict); // // remove the rna attribute instead. PyDict_DelItem(((PyTypeObject *)self)->tp_dict, bpy_intern_str_bl_rna); @@ -7028,14 +7115,14 @@ PointerRNA ptr; PropertyRNA *prop; - gilstate= PyGILState_Ensure(); + gilstate = PyGILState_Ensure(); /* avoid doing this lookup for every getattr */ RNA_blender_rna_pointer_create(&ptr); - prop= RNA_struct_find_property(&ptr, "structs"); + prop = RNA_struct_find_property(&ptr, "structs"); RNA_PROP_BEGIN(&ptr, itemptr, prop) { - PyObject *item= pyrna_struct_Subtype(&itemptr); + PyObject *item = pyrna_struct_Subtype(&itemptr); if (item == NULL) { if (PyErr_Occurred()) { PyErr_Print(); @@ -7059,12 +7146,12 @@ /* avoid doing this lookup for every getattr */ RNA_blender_rna_pointer_create(&ptr); - prop= RNA_struct_find_property(&ptr, "structs"); + prop = RNA_struct_find_property(&ptr, "structs"); RNA_PROP_BEGIN(&ptr, itemptr, prop) { - StructRNA *srna= srna_from_ptr(&itemptr); - void *py_ptr= RNA_struct_py_type_get(srna); + StructRNA *srna = srna_from_ptr(&itemptr); + void *py_ptr = RNA_struct_py_type_get(srna); if (py_ptr) { #if 0 // XXX - should be able to do this but makes python crash on exit @@ -7102,10 +7189,10 @@ " subclass of a registerable blender class.\n" "\n" ); -PyMethodDef meth_bpy_register_class= {"register_class", pyrna_register_class, METH_O, pyrna_register_class_doc}; +PyMethodDef meth_bpy_register_class = {"register_class", pyrna_register_class, METH_O, pyrna_register_class_doc}; static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class) { - bContext *C= NULL; + bContext *C = NULL; ReportList reports; StructRegisterFunc reg; StructRNA *srna; @@ -7113,14 +7200,31 @@ const char *identifier; PyObject *py_cls_meth; - if (PyDict_GetItem(((PyTypeObject*)py_class)->tp_dict, bpy_intern_str_bl_rna)) { - PyErr_SetString(PyExc_AttributeError, "register_class(...): already registered as a subclass"); + if (!PyType_Check(py_class)) { + PyErr_Format(PyExc_ValueError, + "register_class(...): " + "expected a class argument, not '%.200s'", Py_TYPE(py_class)->tp_name); + return NULL; + } + + if (PyDict_GetItem(((PyTypeObject *)py_class)->tp_dict, bpy_intern_str_bl_rna)) { + PyErr_SetString(PyExc_ValueError, + "register_class(...): " + "already registered as a subclass"); + return NULL; + } + + if (!pyrna_write_check()) { + PyErr_Format(PyExc_RuntimeError, + "register_class(...): " + "can't run in readonly state '%.200s'", + ((PyTypeObject *)py_class)->tp_name); return NULL; } /* warning: gets parent classes srna, only for the register function */ - srna= pyrna_struct_as_srna(py_class, 1, "register_class(...):"); - if (srna==NULL) + srna = pyrna_struct_as_srna(py_class, 1, "register_class(...):"); + if (srna == NULL) return NULL; /* fails in cases, cant use this check but would like to :| */ @@ -7128,13 +7232,13 @@ if (RNA_struct_py_type_get(srna)) { PyErr_Format(PyExc_ValueError, "register_class(...): %.200s's parent class %.200s is already registered, this is not allowed", - ((PyTypeObject*)py_class)->tp_name, RNA_struct_identifier(srna)); + ((PyTypeObject *)py_class)->tp_name, RNA_struct_identifier(srna)); return NULL; } */ /* check that we have a register callback for this type */ - reg= RNA_struct_register(srna); + reg = RNA_struct_register(srna); if (!reg) { PyErr_Format(PyExc_ValueError, @@ -7145,15 +7249,15 @@ } /* get the context, so register callback can do necessary refreshes */ - C= BPy_GetContext(); + C = BPy_GetContext(); /* call the register callback with reports & identifier */ BKE_reports_init(&reports, RPT_STORE); - identifier= ((PyTypeObject*)py_class)->tp_name; + identifier = ((PyTypeObject *)py_class)->tp_name; - srna_new= reg(CTX_data_main(C), &reports, py_class, identifier, - bpy_class_validate, bpy_class_call, bpy_class_free); + srna_new = reg(CTX_data_main(C), &reports, py_class, identifier, + bpy_class_validate, bpy_class_call, bpy_class_free); if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1) return NULL; @@ -7173,18 +7277,18 @@ /* Can't use this because it returns a dict proxy * - * item= PyObject_GetAttrString(py_class, "__dict__"); + * item = PyObject_GetAttrString(py_class, "__dict__"); */ - if (pyrna_deferred_register_class(srna_new, py_class)!=0) + if (pyrna_deferred_register_class(srna_new, py_class) != 0) return NULL; /* call classed register method () */ - py_cls_meth= PyObject_GetAttr(py_class, bpy_intern_str_register); + py_cls_meth = PyObject_GetAttr(py_class, bpy_intern_str_register); if (py_cls_meth == NULL) { PyErr_Clear(); } else { - PyObject *ret= PyObject_CallObject(py_cls_meth, NULL); + PyObject *ret = PyObject_CallObject(py_cls_meth, NULL); if (ret) { Py_DECREF(ret); } @@ -7203,16 +7307,16 @@ LinkData *link; /* verify properties */ - const ListBase *lb= RNA_struct_type_properties(srna); + const ListBase *lb = RNA_struct_type_properties(srna); - for (link=lb->first; link; link=link->next) { - prop= (PropertyRNA*)link; + for (link = lb->first; link; link = link->next) { + prop = (PropertyRNA *)link; if (RNA_property_type(prop) == PROP_POINTER && !(RNA_property_flag(prop) & PROP_BUILTIN)) { PointerRNA tptr; RNA_pointer_create(NULL, &RNA_Struct, srna_props, &tptr); if (RNA_property_pointer_type(&tptr, prop) == srna) { - *prop_identifier= RNA_property_identifier(prop); + *prop_identifier = RNA_property_identifier(prop); return 1; } } @@ -7229,26 +7333,43 @@ " If the class has an *unregister* class method it will be called\n" " before unregistering.\n" ); -PyMethodDef meth_bpy_unregister_class= {"unregister_class", pyrna_unregister_class, METH_O, pyrna_unregister_class_doc}; +PyMethodDef meth_bpy_unregister_class = { + "unregister_class", pyrna_unregister_class, METH_O, pyrna_unregister_class_doc +}; static PyObject *pyrna_unregister_class(PyObject *UNUSED(self), PyObject *py_class) { - bContext *C= NULL; + bContext *C = NULL; StructUnregisterFunc unreg; StructRNA *srna; PyObject *py_cls_meth; - /*if (PyDict_GetItem(((PyTypeObject*)py_class)->tp_dict, bpy_intern_str_bl_rna)==NULL) { + if (!PyType_Check(py_class)) { + PyErr_Format(PyExc_ValueError, + "register_class(...): " + "expected a class argument, not '%.200s'", Py_TYPE(py_class)->tp_name); + return NULL; + } + + /*if (PyDict_GetItem(((PyTypeObject *)py_class)->tp_dict, bpy_intern_str_bl_rna) == NULL) { PWM_cursor_wait(0); PyErr_SetString(PyExc_ValueError, "unregister_class(): not a registered as a subclass"); return NULL; }*/ - srna= pyrna_struct_as_srna(py_class, 0, "unregister_class(...):"); - if (srna==NULL) + if (!pyrna_write_check()) { + PyErr_Format(PyExc_RuntimeError, + "unregister_class(...): " + "can't run in readonly state '%.200s'", + ((PyTypeObject *)py_class)->tp_name); + return NULL; + } + + srna = pyrna_struct_as_srna(py_class, 0, "unregister_class(...):"); + if (srna == NULL) return NULL; /* check that we have a unregister callback for this type */ - unreg= RNA_struct_unregister(srna); + unreg = RNA_struct_unregister(srna); if (!unreg) { PyErr_SetString(PyExc_ValueError, @@ -7258,12 +7379,12 @@ } /* call classed unregister method */ - py_cls_meth= PyObject_GetAttr(py_class, bpy_intern_str_unregister); + py_cls_meth = PyObject_GetAttr(py_class, bpy_intern_str_unregister); if (py_cls_meth == NULL) { PyErr_Clear(); } else { - PyObject *ret= PyObject_CallObject(py_cls_meth, NULL); + PyObject *ret = PyObject_CallObject(py_cls_meth, NULL); if (ret) { Py_DECREF(ret); } @@ -7278,16 +7399,16 @@ StructRNA *srna_iter; PointerRNA ptr_rna; PropertyRNA *prop_rna; - const char *prop_identifier= NULL; + const char *prop_identifier = NULL; RNA_blender_rna_pointer_create(&ptr_rna); - prop_rna= RNA_struct_find_property(&ptr_rna, "structs"); + prop_rna = RNA_struct_find_property(&ptr_rna, "structs"); /* loop over all structs */ RNA_PROP_BEGIN(&ptr_rna, itemptr, prop_rna) { - srna_iter= itemptr.data; + srna_iter = itemptr.data; if (pyrna_srna_contains_pointer_prop_srna(srna_iter, srna, &prop_identifier)) { break; } @@ -7303,7 +7424,7 @@ } /* get the context, so register callback can do necessary refreshes */ - C= BPy_GetContext(); + C = BPy_GetContext(); /* call unregister */ unreg(CTX_data_main(C), srna); /* calls bpy_class_free, this decref's py_class */ diff -Nru blender-2.61/source/blender/python/intern/bpy_rna_callback.c blender-2.62/source/blender/python/intern/bpy_rna_callback.c --- blender-2.61/source/blender/python/intern/bpy_rna_callback.c 2011-12-13 19:48:28.000000000 +0000 +++ blender-2.62/source/blender/python/intern/bpy_rna_callback.c 2012-02-15 19:33:11.000000000 +0000 @@ -56,11 +56,11 @@ bpy_context_set((bContext *)C, &gilstate); - cb_func= PyTuple_GET_ITEM((PyObject *)customdata, 0); - cb_args= PyTuple_GET_ITEM((PyObject *)customdata, 1); - result= PyObject_CallObject(cb_func, cb_args); + cb_func = PyTuple_GET_ITEM((PyObject *)customdata, 0); + cb_args = PyTuple_GET_ITEM((PyObject *)customdata, 1); + result = PyObject_CallObject(cb_func, cb_args); - if(result) { + if (result) { Py_DECREF(result); } else { @@ -76,33 +76,34 @@ void *handle; PyObject *cb_func, *cb_args; - char *cb_event_str= NULL; + char *cb_event_str = NULL; int cb_event; if (!PyArg_ParseTuple(args, "OO!|s:bpy_struct.callback_add", &cb_func, &PyTuple_Type, &cb_args, &cb_event_str)) return NULL; - if(!PyCallable_Check(cb_func)) { + if (!PyCallable_Check(cb_func)) { PyErr_SetString(PyExc_TypeError, "callback_add(): first argument isn't callable"); return NULL; } - if(RNA_struct_is_a(self->ptr.type, &RNA_Region)) { - if(cb_event_str) { - static EnumPropertyItem region_draw_mode_items[]= { + if (RNA_struct_is_a(self->ptr.type, &RNA_Region)) { + if (cb_event_str) { + static EnumPropertyItem region_draw_mode_items[] = { {REGION_DRAW_POST_PIXEL, "POST_PIXEL", 0, "Post Pixel", ""}, {REGION_DRAW_POST_VIEW, "POST_VIEW", 0, "Post View", ""}, {REGION_DRAW_PRE_VIEW, "PRE_VIEW", 0, "Pre View", ""}, {0, NULL, 0, NULL, NULL}}; - if(pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") < 0) + if (pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") < 0) { return NULL; + } } else { - cb_event= REGION_DRAW_POST_PIXEL; + cb_event = REGION_DRAW_POST_PIXEL; } - handle= ED_region_draw_cb_activate(((ARegion *)self->ptr.data)->type, cb_region_draw, (void *)args, cb_event); + handle = ED_region_draw_cb_activate(((ARegion *)self->ptr.data)->type, cb_region_draw, (void *)args, cb_event); Py_INCREF(args); } else { @@ -122,15 +123,15 @@ if (!PyArg_ParseTuple(args, "O!:callback_remove", &PyCapsule_Type, &py_handle)) return NULL; - handle= PyCapsule_GetPointer(py_handle, RNA_CAPSULE_ID); + handle = PyCapsule_GetPointer(py_handle, RNA_CAPSULE_ID); - if(handle==NULL) { + if (handle == NULL) { PyErr_SetString(PyExc_ValueError, "callback_remove(handle): NULL handle given, invalid or already removed"); return NULL; } - if(RNA_struct_is_a(self->ptr.type, &RNA_Region)) { - customdata= ED_region_draw_cb_customdata(handle); + if (RNA_struct_is_a(self->ptr.type, &RNA_Region)) { + customdata = ED_region_draw_cb_customdata(handle); Py_DECREF((PyObject *)customdata); ED_region_draw_cb_exit(((ARegion *)self->ptr.data)->type, handle); diff -Nru blender-2.61/source/blender/python/intern/bpy_traceback.c blender-2.62/source/blender/python/intern/bpy_traceback.c --- blender-2.61/source/blender/python/intern/bpy_traceback.c 2011-12-13 19:48:28.000000000 +0000 +++ blender-2.62/source/blender/python/intern/bpy_traceback.c 2012-02-15 19:33:11.000000000 +0000 @@ -33,7 +33,7 @@ static const char *traceback_filepath(PyTracebackObject *tb, PyObject **coerce) { - return PyBytes_AS_STRING((*coerce= PyUnicode_EncodeFSDefault(tb->tb_frame->f_code->co_filename))); + return PyBytes_AS_STRING((*coerce = PyUnicode_EncodeFSDefault(tb->tb_frame->f_code->co_filename))); } /* copied from pythonrun.c, 3.2.0 */ @@ -110,8 +110,8 @@ PyObject *exception, *value; PyTracebackObject *tb; - *lineno= -1; - *offset= 0; + *lineno = -1; + *offset = 0; PyErr_Fetch(&exception, &value, (PyObject **)&tb); @@ -133,11 +133,11 @@ /* good */ } else { - *lineno= -1; + *lineno = -1; } } else { - *lineno= -1; + *lineno = -1; } } } @@ -146,17 +146,17 @@ PyErr_Restore(exception, value, (PyObject *)tb); /* takes away reference! */ PyErr_Print(); - for (tb= (PyTracebackObject *)PySys_GetObject("last_traceback"); + for (tb = (PyTracebackObject *)PySys_GetObject("last_traceback"); tb && (PyObject *)tb != Py_None; - tb= tb->tb_next) + tb = tb->tb_next) { PyObject *coerce; - const char *tb_filepath= traceback_filepath(tb, &coerce); - const int match= strcmp(tb_filepath, filepath) != 0; + const char *tb_filepath = traceback_filepath(tb, &coerce); + const int match = strcmp(tb_filepath, filepath) != 0; Py_DECREF(coerce); if (match) { - *lineno= tb->tb_lineno; + *lineno = tb->tb_lineno; break; } } diff -Nru blender-2.61/source/blender/python/intern/bpy_util.c blender-2.62/source/blender/python/intern/bpy_util.c --- blender-2.61/source/blender/python/intern/bpy_util.c 2011-12-13 19:48:28.000000000 +0000 +++ blender-2.62/source/blender/python/intern/bpy_util.c 2012-02-15 19:33:11.000000000 +0000 @@ -37,22 +37,22 @@ #include "../generic/py_capi_utils.h" -static bContext* __py_context= NULL; +static bContext* __py_context = NULL; bContext* BPy_GetContext(void) { return __py_context; } -void BPy_SetContext(bContext *C) { __py_context= C; } +void BPy_SetContext(bContext *C) { __py_context = C; } char *BPy_enum_as_string(EnumPropertyItem *item) { - DynStr *dynstr= BLI_dynstr_new(); + DynStr *dynstr = BLI_dynstr_new(); EnumPropertyItem *e; char *cstring; - for (e= item; item->identifier; item++) { + for (e = item; item->identifier; item++) { if (item->identifier[0]) - BLI_dynstr_appendf(dynstr, (e==item)?"'%s'":", '%s'", item->identifier); + BLI_dynstr_appendf(dynstr, (e == item)?"'%s'":", '%s'", item->identifier); } - cstring= BLI_dynstr_get_cstring(dynstr); + cstring = BLI_dynstr_get_cstring(dynstr); BLI_dynstr_free(dynstr); return cstring; } @@ -61,7 +61,7 @@ { char *report_str; - report_str= BKE_reports_string(reports, RPT_ERROR); + report_str = BKE_reports_string(reports, RPT_ERROR); if (clear) { BKE_reports_clear(reports); @@ -79,7 +79,7 @@ short BPy_errors_to_report(ReportList *reports) { PyObject *pystring; - PyObject *pystring_format= NULL; // workaround, see below + PyObject *pystring_format = NULL; // workaround, see below char *cstring; const char *filename; @@ -89,30 +89,30 @@ return 1; /* less hassle if we allow NULL */ - if (reports==NULL) { + if (reports == NULL) { PyErr_Print(); PyErr_Clear(); return 1; } - pystring= PyC_ExceptionBuffer(); + pystring = PyC_ExceptionBuffer(); - if (pystring==NULL) { + if (pystring == NULL) { BKE_report(reports, RPT_ERROR, "unknown py-exception, couldn't convert"); return 0; } PyC_FileAndNum(&filename, &lineno); - if (filename==NULL) - filename= ""; + if (filename == NULL) + filename = ""; - cstring= _PyUnicode_AsString(pystring); + cstring = _PyUnicode_AsString(pystring); #if 0 // ARG!. workaround for a bug in blenders use of vsnprintf BKE_reportf(reports, RPT_ERROR, "%s\nlocation:%s:%d\n", cstring, filename, lineno); #else - pystring_format= PyUnicode_FromFormat("%s\nlocation:%s:%d\n", cstring, filename, lineno); - cstring= _PyUnicode_AsString(pystring_format); + pystring_format = PyUnicode_FromFormat("%s\nlocation:%s:%d\n", cstring, filename, lineno); + cstring = _PyUnicode_AsString(pystring_format); BKE_report(reports, RPT_ERROR, cstring); #endif diff -Nru blender-2.61/source/blender/python/intern/CMakeLists.txt blender-2.62/source/blender/python/intern/CMakeLists.txt --- blender-2.61/source/blender/python/intern/CMakeLists.txt 2011-12-13 19:48:28.000000000 +0000 +++ blender-2.62/source/blender/python/intern/CMakeLists.txt 2012-02-15 19:33:11.000000000 +0000 @@ -33,8 +33,9 @@ ../../makesdna ../../makesrna ../../windowmanager - ../../gpu + ../../gpu ../../../../intern/guardedalloc + ../../../../intern/cycles/blender ) set(INC_SYS @@ -42,9 +43,10 @@ ) set(SRC - gpu.c + gpu.c bpy.c bpy_app.c + bpy_app_ffmpeg.c bpy_app_handlers.c bpy_driver.c bpy_interface.c @@ -62,9 +64,10 @@ bpy_util.c stubs.c - gpu.h + gpu.h bpy.h bpy_app.h + bpy_app_ffmpeg.h bpy_app_handlers.h bpy_driver.h bpy_intern_string.h @@ -101,7 +104,15 @@ endif() if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) + add_definitions(-DWITH_INTERNATIONAL) +endif() + +if(WITH_CODEC_FFMPEG) + list(APPEND INC_SYS + ${FFMPEG_INCLUDE_DIRS} + ) + + add_definitions(-DWITH_FFMPEG) endif() blender_add_lib(bf_python "${SRC}" "${INC}" "${INC_SYS}") diff -Nru blender-2.61/source/blender/python/intern/gpu.c blender-2.62/source/blender/python/intern/gpu.c --- blender-2.61/source/blender/python/intern/gpu.c 2011-12-13 19:48:28.000000000 +0000 +++ blender-2.62/source/blender/python/intern/gpu.c 2012-02-15 19:33:11.000000000 +0000 @@ -145,6 +145,14 @@ PyObject_SetAttrString(d, #f, val); \ Py_DECREF(val) +PyDoc_STRVAR(GPU_export_shader_doc, +"export_shader(scene, material)\n" +"\n" +" Returns the GLSL shader that produces the visual effect of material in scene.\n" +"\n" +" :return: Dictionary defining the shader, uniforms and attributes.\n" +" :rtype: Dict" +); static PyObject* GPU_export_shader(PyObject* UNUSED(self), PyObject *args, PyObject *kwds) { PyObject* pyscene; @@ -184,7 +192,8 @@ PyErr_SetString(PyExc_SystemError, "scene.as_pointer() failed"); return NULL; } - } else { + } + else { PyErr_SetString(PyExc_TypeError, "gpu.export_shader() first argument should be of Scene type"); return NULL; } @@ -204,7 +213,8 @@ PyErr_SetString(PyExc_SystemError, "scene.as_pointer() failed"); return NULL; } - } else { + } + else { PyErr_SetString(PyExc_TypeError, "gpu.export_shader() second argument should be of Material type"); return NULL; } @@ -260,7 +270,8 @@ if (attribute->name) { if (attribute->name[0] != 0) { PY_DICT_ADD_STRING(dict,attribute,name); - } else { + } + else { val = PyLong_FromLong(0); PyDict_SetItemString(dict, "name", val); Py_DECREF(val); @@ -276,11 +287,9 @@ return result; } -static PyMethodDef meth_export_shader[] = {{ "export_shader", (PyCFunction)GPU_export_shader, METH_VARARGS | METH_KEYWORDS, - "export_shader(scene,material)\n\n" - "Returns the GLSL shader that produces the visual effect of material in scene.\n\n" - ":return: Dictionary defining the shader, uniforms and attributes.\n" - ":rtype: Dict"}}; +static PyMethodDef meth_export_shader[] = { + {"export_shader", (PyCFunction)GPU_export_shader, METH_VARARGS | METH_KEYWORDS, GPU_export_shader_doc} +}; PyObject* GPU_initPython(void) { diff -Nru blender-2.61/source/blender/python/mathutils/mathutils.c blender-2.62/source/blender/python/mathutils/mathutils.c --- blender-2.61/source/blender/python/mathutils/mathutils.c 2011-12-13 19:48:32.000000000 +0000 +++ blender-2.62/source/blender/python/mathutils/mathutils.c 2012-02-15 19:33:13.000000000 +0000 @@ -35,46 +35,24 @@ #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLI_dynstr.h" PyDoc_STRVAR(M_Mathutils_doc, "This module provides access to matrices, eulers, quaternions and vectors." ); static int mathutils_array_parse_fast(float *array, - int array_min, int array_max, - PyObject *value, const char *error_prefix) + int size, + PyObject *value_fast, + const char *error_prefix) { - PyObject *value_fast= NULL; PyObject *item; - int i, size; - - /* non list/tuple cases */ - if (!(value_fast=PySequence_Fast(value, error_prefix))) { - /* PySequence_Fast sets the error */ - return -1; - } - - size= PySequence_Fast_GET_SIZE(value_fast); - - if (size > array_max || size < array_min) { - if (array_max == array_min) { - PyErr_Format(PyExc_ValueError, - "%.200s: sequence size is %d, expected %d", - error_prefix, size, array_max); - } - else { - PyErr_Format(PyExc_ValueError, - "%.200s: sequence size is %d, expected [%d - %d]", - error_prefix, size, array_min, array_max); - } - Py_DECREF(value_fast); - return -1; - } + int i; - i= size; + i = size; do { i--; - if ( ((array[i]= PyFloat_AsDouble((item= PySequence_Fast_GET_ITEM(value_fast, i)))) == -1.0f) && + if ( ((array[i] = PyFloat_AsDouble((item = PySequence_Fast_GET_ITEM(value_fast, i)))) == -1.0f) && PyErr_Occurred()) { PyErr_Format(PyExc_TypeError, @@ -93,13 +71,14 @@ /* helper functionm returns length of the 'value', -1 on error */ int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix) { -#if 1 /* approx 6x speedup for mathutils types */ int size; - if ( (size= VectorObject_Check(value) ? ((VectorObject *)value)->size : 0) || - (size= EulerObject_Check(value) ? 3 : 0) || - (size= QuaternionObject_Check(value) ? 4 : 0) || - (size= ColorObject_Check(value) ? 3 : 0)) +#if 1 /* approx 6x speedup for mathutils types */ + + if ( (size = VectorObject_Check(value) ? ((VectorObject *)value)->size : 0) || + (size = EulerObject_Check(value) ? 3 : 0) || + (size = QuaternionObject_Check(value) ? 4 : 0) || + (size = ColorObject_Check(value) ? 3 : 0)) { if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) { return -1; @@ -125,7 +104,85 @@ else #endif { - return mathutils_array_parse_fast(array, array_min, array_max, value, error_prefix); + PyObject *value_fast = NULL; + + /* non list/tuple cases */ + if (!(value_fast = PySequence_Fast(value, error_prefix))) { + /* PySequence_Fast sets the error */ + return -1; + } + + size = PySequence_Fast_GET_SIZE(value_fast); + + if (size > array_max || size < array_min) { + if (array_max == array_min) { + PyErr_Format(PyExc_ValueError, + "%.200s: sequence size is %d, expected %d", + error_prefix, size, array_max); + } + else { + PyErr_Format(PyExc_ValueError, + "%.200s: sequence size is %d, expected [%d - %d]", + error_prefix, size, array_min, array_max); + } + Py_DECREF(value_fast); + return -1; + } + + return mathutils_array_parse_fast(array, size, value_fast, error_prefix); + } +} + +int mathutils_array_parse_alloc(float **array, int array_min, PyObject *value, const char *error_prefix) +{ + int size; + +#if 1 /* approx 6x speedup for mathutils types */ + + if ( (size = VectorObject_Check(value) ? ((VectorObject *)value)->size : 0) || + (size = EulerObject_Check(value) ? 3 : 0) || + (size = QuaternionObject_Check(value) ? 4 : 0) || + (size = ColorObject_Check(value) ? 3 : 0)) + { + if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) { + return -1; + } + + if (size < array_min) { + PyErr_Format(PyExc_ValueError, + "%.200s: sequence size is %d, expected > %d", + error_prefix, size, array_min); + return -1; + } + + *array = PyMem_Malloc(size * sizeof(float)); + memcpy(*array, ((BaseMathObject *)value)->data, size * sizeof(float)); + return size; + } + else +#endif + { + PyObject *value_fast = NULL; + //*array = NULL; + + /* non list/tuple cases */ + if (!(value_fast = PySequence_Fast(value, error_prefix))) { + /* PySequence_Fast sets the error */ + return -1; + } + + size = PySequence_Fast_GET_SIZE(value_fast); + + if (size < array_min) { + PyErr_Format(PyExc_ValueError, + "%.200s: sequence size is %d, expected > %d", + error_prefix, size, array_min); + return -1; + } + + *array = PyMem_Malloc(size * sizeof(float)); + + return mathutils_array_parse_fast(*array, size, value_fast, error_prefix); } } @@ -155,7 +212,7 @@ if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) { return -1; } - else if (((MatrixObject *)value)->col_size < 3 || ((MatrixObject *)value)->row_size < 3) { + else if (((MatrixObject *)value)->num_row < 3 || ((MatrixObject *)value)->num_col < 3) { PyErr_Format(PyExc_ValueError, "%.200s: matrix must have minimum 3x3 dimensions", error_prefix); @@ -204,26 +261,38 @@ int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps) { int x; - for (x=0; x< size; x++) { + for (x = 0; x < size; x++) { if (EXPP_FloatsAreEqual(vecA[x], vecB[x], floatSteps) == 0) return 0; } return 1; } +/* dynstr as python string utility funcions, frees 'ds'! */ +PyObject *mathutils_dynstr_to_py(struct DynStr *ds) +{ + const int ds_len = BLI_dynstr_get_len(ds); /* space for \0 */ + char *ds_buf = PyMem_Malloc(ds_len + 1); + PyObject *ret; + BLI_dynstr_get_cstring_ex(ds, ds_buf); + BLI_dynstr_free(ds); + ret = PyUnicode_FromStringAndSize(ds_buf, ds_len); + PyMem_Free(ds_buf); + return ret; +} /* Mathutils Callbacks */ /* for mathutils internal use only, eventually should re-alloc but to start with we only have a few users */ -static Mathutils_Callback *mathutils_callbacks[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; +static Mathutils_Callback *mathutils_callbacks[8] = {NULL}; int Mathutils_RegisterCallback(Mathutils_Callback *cb) { int i; /* find the first free slot */ - for (i= 0; mathutils_callbacks[i]; i++) { - if (mathutils_callbacks[i]==cb) /* already registered? */ + for (i = 0; mathutils_callbacks[i]; i++) { + if (mathutils_callbacks[i] == cb) /* already registered? */ return i; } @@ -234,7 +303,7 @@ /* use macros to check for NULL */ int _BaseMathObject_ReadCallback(BaseMathObject *self) { - Mathutils_Callback *cb= mathutils_callbacks[self->cb_type]; + Mathutils_Callback *cb = mathutils_callbacks[self->cb_type]; if (cb->get(self, self->cb_subtype) != -1) return 0; @@ -248,7 +317,7 @@ int _BaseMathObject_WriteCallback(BaseMathObject *self) { - Mathutils_Callback *cb= mathutils_callbacks[self->cb_type]; + Mathutils_Callback *cb = mathutils_callbacks[self->cb_type]; if (cb->set(self, self->cb_subtype) != -1) return 0; @@ -262,7 +331,7 @@ int _BaseMathObject_ReadIndexCallback(BaseMathObject *self, int index) { - Mathutils_Callback *cb= mathutils_callbacks[self->cb_type]; + Mathutils_Callback *cb = mathutils_callbacks[self->cb_type]; if (cb->get_index(self, self->cb_subtype, index) != -1) return 0; @@ -276,7 +345,7 @@ int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index) { - Mathutils_Callback *cb= mathutils_callbacks[self->cb_type]; + Mathutils_Callback *cb = mathutils_callbacks[self->cb_type]; if (cb->set_index(self, self->cb_subtype, index) != -1) return 0; @@ -289,16 +358,16 @@ } /* BaseMathObject generic functions for all mathutils types */ -char BaseMathObject_Owner_doc[] = "The item this is wrapping or None (readonly)."; -PyObject *BaseMathObject_getOwner(BaseMathObject *self, void *UNUSED(closure)) +char BaseMathObject_owner_doc[] = "The item this is wrapping or None (readonly)."; +PyObject *BaseMathObject_owner_get(BaseMathObject *self, void *UNUSED(closure)) { - PyObject *ret= self->cb_user ? self->cb_user : Py_None; + PyObject *ret = self->cb_user ? self->cb_user : Py_None; Py_INCREF(ret); return ret; } -char BaseMathObject_Wrapped_doc[] = "True when this object wraps external data (readonly).\n\n:type: boolean"; -PyObject *BaseMathObject_getWrapped(BaseMathObject *self, void *UNUSED(closure)) +char BaseMathObject_is_wrapped_doc[] = "True when this object wraps external data (readonly).\n\n:type: boolean"; +PyObject *BaseMathObject_is_wrapped_get(BaseMathObject *self, void *UNUSED(closure)) { return PyBool_FromLong((self->wrapped == Py_WRAP) ? 1:0); } @@ -351,12 +420,14 @@ { PyObject *submodule; PyObject *item; - PyObject *sys_modules= PyThreadState_GET()->interp->modules; + PyObject *sys_modules = PyThreadState_GET()->interp->modules; if (PyType_Ready(&vector_Type) < 0) return NULL; if (PyType_Ready(&matrix_Type) < 0) - return NULL; + return NULL; + if (PyType_Ready(&matrix_access_Type) < 0) + return NULL; if (PyType_Ready(&euler_Type) < 0) return NULL; if (PyType_Ready(&quaternion_Type) < 0) @@ -374,7 +445,7 @@ PyModule_AddObject(submodule, "Color", (PyObject *)&color_Type); /* submodule */ - PyModule_AddObject(submodule, "geometry", (item=PyInit_mathutils_geometry())); + PyModule_AddObject(submodule, "geometry", (item = PyInit_mathutils_geometry())); /* XXX, python doesnt do imports with this usefully yet * 'from mathutils.geometry import PolyFill' * ...fails without this. */ @@ -382,11 +453,13 @@ Py_INCREF(item); /* Noise submodule */ - PyModule_AddObject(submodule, "noise", (item=PyInit_mathutils_noise())); + PyModule_AddObject(submodule, "noise", (item = PyInit_mathutils_noise())); PyDict_SetItemString(sys_modules, "mathutils.noise", item); Py_INCREF(item); - mathutils_matrix_vector_cb_index= Mathutils_RegisterCallback(&mathutils_matrix_vector_cb); + mathutils_matrix_row_cb_index = Mathutils_RegisterCallback(&mathutils_matrix_row_cb); + mathutils_matrix_col_cb_index = Mathutils_RegisterCallback(&mathutils_matrix_col_cb); + mathutils_matrix_translation_cb_index = Mathutils_RegisterCallback(&mathutils_matrix_translation_cb); return submodule; } diff -Nru blender-2.61/source/blender/python/mathutils/mathutils_Color.c blender-2.62/source/blender/python/mathutils/mathutils_Color.c --- blender-2.61/source/blender/python/mathutils/mathutils_Color.c 2011-12-13 19:48:32.000000000 +0000 +++ blender-2.62/source/blender/python/mathutils/mathutils_Color.c 2012-02-15 19:33:13.000000000 +0000 @@ -32,6 +32,7 @@ #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLI_dynstr.h" #define COLOR_SIZE 3 @@ -39,7 +40,7 @@ //makes a new color for you to play with static PyObject *Color_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - float col[3]= {0.0f, 0.0f, 0.0f}; + float col[3] = {0.0f, 0.0f, 0.0f}; if (kwds && PyDict_Size(kwds)) { PyErr_SetString(PyExc_TypeError, @@ -48,7 +49,7 @@ return NULL; } - switch(PyTuple_GET_SIZE(args)) { + switch (PyTuple_GET_SIZE(args)) { case 0: break; case 1: @@ -72,15 +73,15 @@ PyObject *ret; int i; - ret= PyTuple_New(COLOR_SIZE); + ret = PyTuple_New(COLOR_SIZE); if (ndigits >= 0) { - for (i= 0; i < COLOR_SIZE; i++) { + for (i = 0; i < COLOR_SIZE; i++) { PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(double_round((double)self->col[i], ndigits))); } } else { - for (i= 0; i < COLOR_SIZE; i++) { + for (i = 0; i < COLOR_SIZE; i++) { PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(self->col[i])); } } @@ -110,36 +111,51 @@ //----------------------------print object (internal)-------------- //print the object to screen -static PyObject *Color_repr(ColorObject * self) +static PyObject *Color_repr(ColorObject *self) { PyObject *ret, *tuple; if (BaseMath_ReadCallback(self) == -1) return NULL; - tuple= Color_ToTupleExt(self, -1); + tuple = Color_ToTupleExt(self, -1); - ret= PyUnicode_FromFormat("Color(%R)", tuple); + ret = PyUnicode_FromFormat("Color(%R)", tuple); Py_DECREF(tuple); return ret; } +static PyObject *Color_str(ColorObject *self) +{ + DynStr *ds; + + if (BaseMath_ReadCallback(self) == -1) + return NULL; + + ds = BLI_dynstr_new(); + + BLI_dynstr_appendf(ds, "", + self->col[0], self->col[1], self->col[2]); + + return mathutils_dynstr_to_py(ds); /* frees ds */ +} + //------------------------tp_richcmpr //returns -1 execption, 0 false, 1 true -static PyObject* Color_richcmpr(PyObject *a, PyObject *b, int op) +static PyObject *Color_richcmpr(PyObject *a, PyObject *b, int op) { PyObject *res; - int ok= -1; /* zero is true */ + int ok = -1; /* zero is true */ if (ColorObject_Check(a) && ColorObject_Check(b)) { - ColorObject *colA= (ColorObject*)a; - ColorObject *colB= (ColorObject*)b; + ColorObject *colA = (ColorObject *)a; + ColorObject *colB = (ColorObject *)b; if (BaseMath_ReadCallback(colA) == -1 || BaseMath_ReadCallback(colB) == -1) return NULL; - ok= EXPP_VectorsAreEqual(colA->col, colB->col, COLOR_SIZE, 1) ? 0 : -1; + ok = EXPP_VectorsAreEqual(colA->col, colB->col, COLOR_SIZE, 1) ? 0 : -1; } switch (op) { @@ -172,9 +188,9 @@ } //----------------------------object[]--------------------------- //sequence accessor (get) -static PyObject *Color_item(ColorObject * self, int i) +static PyObject *Color_item(ColorObject *self, int i) { - if (i<0) i= COLOR_SIZE-i; + if (i < 0) i = COLOR_SIZE - i; if (i < 0 || i >= COLOR_SIZE) { PyErr_SetString(PyExc_IndexError, @@ -191,7 +207,7 @@ } //----------------------------object[]------------------------- //sequence accessor (set) -static int Color_ass_item(ColorObject * self, int i, PyObject *value) +static int Color_ass_item(ColorObject *self, int i, PyObject *value) { float f = PyFloat_AsDouble(value); @@ -202,7 +218,7 @@ return -1; } - if (i<0) i= COLOR_SIZE-i; + if (i < 0) i= COLOR_SIZE - i; if (i < 0 || i >= COLOR_SIZE) { PyErr_SetString(PyExc_IndexError, "color[attribute] = x: " @@ -219,7 +235,7 @@ } //----------------------------object[z:y]------------------------ //sequence slice (get) -static PyObject *Color_slice(ColorObject * self, int begin, int end) +static PyObject *Color_slice(ColorObject *self, int begin, int end) { PyObject *tuple; int count; @@ -228,12 +244,12 @@ return NULL; CLAMP(begin, 0, COLOR_SIZE); - if (end<0) end= (COLOR_SIZE + 1) + end; + if (end < 0) end = (COLOR_SIZE + 1) + end; CLAMP(end, 0, COLOR_SIZE); - begin= MIN2(begin, end); + begin = MIN2(begin, end); - tuple= PyTuple_New(end - begin); - for (count= begin; count < end; count++) { + tuple = PyTuple_New(end - begin); + for (count = begin; count < end; count++) { PyTuple_SET_ITEM(tuple, count - begin, PyFloat_FromDouble(self->col[count])); } @@ -250,11 +266,11 @@ return -1; CLAMP(begin, 0, COLOR_SIZE); - if (end<0) end= (COLOR_SIZE + 1) + end; + if (end < 0) end = (COLOR_SIZE + 1) + end; CLAMP(end, 0, COLOR_SIZE); begin = MIN2(begin, end); - if ((size=mathutils_array_parse(col, 0, COLOR_SIZE, seq, "mathutils.Color[begin:end] = []")) == -1) + if ((size = mathutils_array_parse(col, 0, COLOR_SIZE, seq, "mathutils.Color[begin:end] = []")) == -1) return -1; if (size != (end - begin)) { @@ -264,7 +280,7 @@ return -1; } - for (i= 0; i < COLOR_SIZE; i++) + for (i = 0; i < COLOR_SIZE; i++) self->col[begin + i] = col[i]; (void)BaseMath_WriteCallback(self); @@ -376,8 +392,8 @@ Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name); return NULL; } - color1 = (ColorObject*)v1; - color2 = (ColorObject*)v2; + color1 = (ColorObject *)v1; + color2 = (ColorObject *)v2; if (BaseMath_ReadCallback(color1) == -1 || BaseMath_ReadCallback(color2) == -1) return NULL; @@ -399,8 +415,8 @@ Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name); return NULL; } - color1 = (ColorObject*)v1; - color2 = (ColorObject*)v2; + color1 = (ColorObject *)v1; + color2 = (ColorObject *)v2; if (BaseMath_ReadCallback(color1) == -1 || BaseMath_ReadCallback(color2) == -1) return NULL; @@ -425,8 +441,8 @@ Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name); return NULL; } - color1 = (ColorObject*)v1; - color2 = (ColorObject*)v2; + color1 = (ColorObject *)v1; + color2 = (ColorObject *)v2; if (BaseMath_ReadCallback(color1) == -1 || BaseMath_ReadCallback(color2) == -1) return NULL; @@ -439,7 +455,7 @@ /* subtraction in-place: obj -= obj */ static PyObject *Color_isub(PyObject *v1, PyObject *v2) { - ColorObject *color1= NULL, *color2= NULL; + ColorObject *color1 = NULL, *color2 = NULL; if (!ColorObject_Check(v1) || !ColorObject_Check(v2)) { PyErr_Format(PyExc_TypeError, @@ -448,8 +464,8 @@ Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name); return NULL; } - color1 = (ColorObject*)v1; - color2 = (ColorObject*)v2; + color1 = (ColorObject *)v1; + color2 = (ColorObject *)v2; if (BaseMath_ReadCallback(color1) == -1 || BaseMath_ReadCallback(color2) == -1) return NULL; @@ -475,12 +491,12 @@ float scalar; if ColorObject_Check(v1) { - color1= (ColorObject *)v1; + color1 = (ColorObject *)v1; if (BaseMath_ReadCallback(color1) == -1) return NULL; } if ColorObject_Check(v2) { - color2= (ColorObject *)v2; + color2 = (ColorObject *)v2; if (BaseMath_ReadCallback(color2) == -1) return NULL; } @@ -491,12 +507,12 @@ /* col * col, dont support yet! */ } else if (color1) { - if (((scalar= PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred())==0) { /* COLOR * FLOAT */ + if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* COLOR * FLOAT */ return color_mul_float(color1, scalar); } } else if (color2) { - if (((scalar= PyFloat_AsDouble(v1)) == -1.0f && PyErr_Occurred())==0) { /* FLOAT * COLOR */ + if (((scalar = PyFloat_AsDouble(v1)) == -1.0f && PyErr_Occurred()) == 0) { /* FLOAT * COLOR */ return color_mul_float(color2, scalar); } } @@ -517,7 +533,7 @@ float scalar; if ColorObject_Check(v1) { - color1= (ColorObject *)v1; + color1 = (ColorObject *)v1; if (BaseMath_ReadCallback(color1) == -1) return NULL; } @@ -528,8 +544,8 @@ } /* make sure v1 is always the vector */ - if (((scalar= PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred())==0) { /* COLOR * FLOAT */ - if (scalar==0.0f) { + if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* COLOR * FLOAT */ + if (scalar == 0.0f) { PyErr_SetString(PyExc_ZeroDivisionError, "Color division: divide by zero error"); return NULL; @@ -554,7 +570,7 @@ return NULL; /* only support color *= float */ - if (((scalar= PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred())==0) { /* COLOR *= FLOAT */ + if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* COLOR *= FLOAT */ mul_vn_fl(color->col, COLOR_SIZE, scalar); } else { @@ -580,8 +596,8 @@ return NULL; /* only support color /= float */ - if (((scalar= PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred())==0) { /* COLOR /= FLOAT */ - if (scalar==0.0f) { + if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* COLOR /= FLOAT */ + if (scalar == 0.0f) { PyErr_SetString(PyExc_ZeroDivisionError, "Color division: divide by zero error"); return NULL; @@ -603,7 +619,7 @@ } /* -obj - returns the negative of this object*/ + returns the negative of this object */ static PyObject *Color_neg(ColorObject *self) { float tcol[COLOR_SIZE]; @@ -654,21 +670,29 @@ }; /* color channel, vector.r/g/b */ -static PyObject *Color_getChannel(ColorObject * self, void *type) +PyDoc_STRVAR(Color_channel_r_doc, "Red color channel.\n\n:type: float"); +PyDoc_STRVAR(Color_channel_g_doc, "Green color channel.\n\n:type: float"); +PyDoc_STRVAR(Color_channel_b_doc, "Blue color channel.\n\n:type: float"); + +static PyObject *Color_channel_get(ColorObject *self, void *type) { return Color_item(self, GET_INT_FROM_POINTER(type)); } -static int Color_setChannel(ColorObject * self, PyObject *value, void * type) +static int Color_channel_set(ColorObject *self, PyObject *value, void * type) { return Color_ass_item(self, GET_INT_FROM_POINTER(type), value); } /* color channel (HSV), color.h/s/v */ -static PyObject *Color_getChannelHSV(ColorObject * self, void *type) +PyDoc_STRVAR(Color_channel_hsv_h_doc, "HSV Hue component in [0, 1].\n\n:type: float"); +PyDoc_STRVAR(Color_channel_hsv_s_doc, "HSV Saturation component in [0, 1].\n\n:type: float"); +PyDoc_STRVAR(Color_channel_hsv_v_doc, "HSV Value component in [0, 1].\n\n:type: float"); + +static PyObject *Color_channel_hsv_get(ColorObject *self, void *type) { float hsv[3]; - int i= GET_INT_FROM_POINTER(type); + int i = GET_INT_FROM_POINTER(type); if (BaseMath_ReadCallback(self) == -1) return NULL; @@ -678,10 +702,10 @@ return PyFloat_FromDouble(hsv[i]); } -static int Color_setChannelHSV(ColorObject * self, PyObject *value, void * type) +static int Color_channel_hsv_set(ColorObject *self, PyObject *value, void * type) { float hsv[3]; - int i= GET_INT_FROM_POINTER(type); + int i = GET_INT_FROM_POINTER(type); float f = PyFloat_AsDouble(value); if (f == -1 && PyErr_Occurred()) { @@ -706,7 +730,8 @@ } /* color channel (HSV), color.h/s/v */ -static PyObject *Color_getHSV(ColorObject * self, void *UNUSED(closure)) +PyDoc_STRVAR(Color_hsv_doc, "HSV Values in [0, 1].\n\n:type: float triplet"); +static PyObject *Color_hsv_get(ColorObject *self, void *UNUSED(closure)) { float hsv[3]; PyObject *ret; @@ -716,14 +741,14 @@ rgb_to_hsv(self->col[0], self->col[1], self->col[2], &(hsv[0]), &(hsv[1]), &(hsv[2])); - ret= PyTuple_New(3); + ret = PyTuple_New(3); PyTuple_SET_ITEM(ret, 0, PyFloat_FromDouble(hsv[0])); PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(hsv[1])); PyTuple_SET_ITEM(ret, 2, PyFloat_FromDouble(hsv[2])); return ret; } -static int Color_setHSV(ColorObject * self, PyObject *value, void *UNUSED(closure)) +static int Color_hsv_set(ColorObject *self, PyObject *value, void *UNUSED(closure)) { float hsv[3]; @@ -746,18 +771,18 @@ /* Python attributes get/set structure: */ /*****************************************************************************/ static PyGetSetDef Color_getseters[] = { - {(char *)"r", (getter)Color_getChannel, (setter)Color_setChannel, (char *)"Red color channel.\n\n:type: float", (void *)0}, - {(char *)"g", (getter)Color_getChannel, (setter)Color_setChannel, (char *)"Green color channel.\n\n:type: float", (void *)1}, - {(char *)"b", (getter)Color_getChannel, (setter)Color_setChannel, (char *)"Blue color channel.\n\n:type: float", (void *)2}, - - {(char *)"h", (getter)Color_getChannelHSV, (setter)Color_setChannelHSV, (char *)"HSV Hue component in [0, 1].\n\n:type: float", (void *)0}, - {(char *)"s", (getter)Color_getChannelHSV, (setter)Color_setChannelHSV, (char *)"HSV Saturation component in [0, 1].\n\n:type: float", (void *)1}, - {(char *)"v", (getter)Color_getChannelHSV, (setter)Color_setChannelHSV, (char *)"HSV Value component in [0, 1].\n\n:type: float", (void *)2}, + {(char *)"r", (getter)Color_channel_get, (setter)Color_channel_set, Color_channel_r_doc, (void *)0}, + {(char *)"g", (getter)Color_channel_get, (setter)Color_channel_set, Color_channel_g_doc, (void *)1}, + {(char *)"b", (getter)Color_channel_get, (setter)Color_channel_set, Color_channel_b_doc, (void *)2}, + + {(char *)"h", (getter)Color_channel_hsv_get, (setter)Color_channel_hsv_set, (char *)Color_channel_hsv_h_doc, (void *)0}, + {(char *)"s", (getter)Color_channel_hsv_get, (setter)Color_channel_hsv_set, (char *)Color_channel_hsv_s_doc, (void *)1}, + {(char *)"v", (getter)Color_channel_hsv_get, (setter)Color_channel_hsv_set, (char *)Color_channel_hsv_v_doc, (void *)2}, - {(char *)"hsv", (getter)Color_getHSV, (setter)Color_setHSV, (char *)"HSV Values in [0, 1].\n\n:type: float triplet", (void *)0}, + {(char *)"hsv", (getter)Color_hsv_get, (setter)Color_hsv_set, (char *)Color_hsv_doc, (void *)0}, - {(char *)"is_wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, BaseMathObject_Wrapped_doc, NULL}, - {(char *)"owner", (getter)BaseMathObject_getOwner, (setter)NULL, BaseMathObject_Owner_doc, NULL}, + {(char *)"is_wrapped", (getter)BaseMathObject_is_wrapped_get, (setter)NULL, BaseMathObject_is_wrapped_doc, NULL}, + {(char *)"owner", (getter)BaseMathObject_owner_get, (setter)NULL, BaseMathObject_owner_doc, NULL}, {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ }; @@ -789,7 +814,7 @@ &Color_AsMapping, //tp_as_mapping NULL, //tp_hash NULL, //tp_call - NULL, //tp_str + (reprfunc) Color_str, //tp_str NULL, //tp_getattro NULL, //tp_setattro NULL, //tp_as_buffer @@ -831,13 +856,13 @@ { ColorObject *self; - self= base_type ? (ColorObject *)base_type->tp_alloc(base_type, 0) : + self = base_type ? (ColorObject *)base_type->tp_alloc(base_type, 0) : (ColorObject *)PyObject_GC_New(ColorObject, &color_Type); if (self) { /* init callbacks as NULL */ - self->cb_user= NULL; - self->cb_type= self->cb_subtype= 0; + self->cb_user = NULL; + self->cb_type = self->cb_subtype = 0; if (type == Py_WRAP) { self->col = col; @@ -862,12 +887,12 @@ PyObject *Color_CreatePyObject_cb(PyObject *cb_user, int cb_type, int cb_subtype) { - ColorObject *self= (ColorObject *)Color_CreatePyObject(NULL, Py_NEW, NULL); + ColorObject *self = (ColorObject *)Color_CreatePyObject(NULL, Py_NEW, NULL); if (self) { Py_INCREF(cb_user); - self->cb_user= cb_user; - self->cb_type= (unsigned char)cb_type; - self->cb_subtype= (unsigned char)cb_subtype; + self->cb_user = cb_user; + self->cb_type = (unsigned char)cb_type; + self->cb_subtype = (unsigned char)cb_subtype; PyObject_GC_Track(self); } diff -Nru blender-2.61/source/blender/python/mathutils/mathutils_Euler.c blender-2.62/source/blender/python/mathutils/mathutils_Euler.c --- blender-2.61/source/blender/python/mathutils/mathutils_Euler.c 2011-12-13 19:48:32.000000000 +0000 +++ blender-2.62/source/blender/python/mathutils/mathutils_Euler.c 2012-02-15 19:33:13.000000000 +0000 @@ -36,6 +36,7 @@ #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLI_dynstr.h" #define EULER_SIZE 3 @@ -43,11 +44,11 @@ //makes a new euler for you to play with static PyObject *Euler_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - PyObject *seq= NULL; - const char *order_str= NULL; + PyObject *seq = NULL; + const char *order_str = NULL; - float eul[EULER_SIZE]= {0.0f, 0.0f, 0.0f}; - short order= EULER_ORDER_XYZ; + float eul[EULER_SIZE] = {0.0f, 0.0f, 0.0f}; + short order = EULER_ORDER_XYZ; if (kwds && PyDict_Size(kwds)) { PyErr_SetString(PyExc_TypeError, @@ -59,11 +60,11 @@ if (!PyArg_ParseTuple(args, "|Os:mathutils.Euler", &seq, &order_str)) return NULL; - switch(PyTuple_GET_SIZE(args)) { + switch (PyTuple_GET_SIZE(args)) { case 0: break; case 2: - if ((order=euler_order_from_string(order_str, "mathutils.Euler()")) == -1) + if ((order = euler_order_from_string(order_str, "mathutils.Euler()")) == -1) return NULL; /* intentionally pass through */ case 1: @@ -78,13 +79,13 @@ static const char *euler_order_str(EulerObject *self) { static const char order[][4] = {"XYZ", "XZY", "YXZ", "YZX", "ZXY", "ZYX"}; - return order[self->order-EULER_ORDER_XYZ]; + return order[self->order - EULER_ORDER_XYZ]; } short euler_order_from_string(const char *str, const char *error_prefix) { - if ((str[0] && str[1] && str[2] && str[3]=='\0')) { - switch(*((PY_INT32_T *)str)) { + if ((str[0] && str[1] && str[2] && str[3] == '\0')) { + switch (*((PY_INT32_T *)str)) { case 'X'|'Y'<<8|'Z'<<16: return EULER_ORDER_XYZ; case 'X'|'Z'<<8|'Y'<<16: return EULER_ORDER_XZY; case 'Y'|'X'<<8|'Z'<<16: return EULER_ORDER_YXZ; @@ -106,15 +107,15 @@ PyObject *ret; int i; - ret= PyTuple_New(EULER_SIZE); + ret = PyTuple_New(EULER_SIZE); if (ndigits >= 0) { - for (i= 0; i < EULER_SIZE; i++) { + for (i = 0; i < EULER_SIZE; i++) { PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(double_round((double)self->eul[i], ndigits))); } } else { - for (i= 0; i < EULER_SIZE; i++) { + for (i = 0; i < EULER_SIZE; i++) { PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(self->eul[i])); } } @@ -133,7 +134,7 @@ " :return: Quaternion representation of the euler.\n" " :rtype: :class:`Quaternion`\n" ); -static PyObject *Euler_to_quaternion(EulerObject * self) +static PyObject *Euler_to_quaternion(EulerObject *self) { float quat[4]; @@ -154,7 +155,7 @@ " :return: A 3x3 roation matrix representation of the euler.\n" " :rtype: :class:`Matrix`\n" ); -static PyObject *Euler_to_matrix(EulerObject * self) +static PyObject *Euler_to_matrix(EulerObject *self) { float mat[9]; @@ -171,7 +172,7 @@ "\n" " Set all values to zero.\n" ); -static PyObject *Euler_zero(EulerObject * self) +static PyObject *Euler_zero(EulerObject *self) { zero_v3(self->eul); @@ -192,12 +193,12 @@ " :arg angle: angle in radians.\n" " :type angle: float\n" ); -static PyObject *Euler_rotate_axis(EulerObject * self, PyObject *args) +static PyObject *Euler_rotate_axis(EulerObject *self, PyObject *args) { float angle = 0.0f; int axis; /* actually a character */ - if (!PyArg_ParseTuple(args, "Cf:rotate", &axis, &angle)) { + if (!PyArg_ParseTuple(args, "Cf:rotate_axis", &axis, &angle)) { PyErr_SetString(PyExc_TypeError, "Euler.rotate_axis(): " "expected an axis 'X', 'Y', 'Z' and an angle (float)"); @@ -230,7 +231,7 @@ " :arg other: rotation component of mathutils value\n" " :type other: :class:`Euler`, :class:`Quaternion` or :class:`Matrix`\n" ); -static PyObject *Euler_rotate(EulerObject * self, PyObject *value) +static PyObject *Euler_rotate(EulerObject *self, PyObject *value) { float self_rmat[3][3], other_rmat[3][3], rmat[3][3]; @@ -257,7 +258,7 @@ "\n" " .. note:: the rotation order is not taken into account for this function.\n" ); -static PyObject *Euler_make_compatible(EulerObject * self, PyObject *value) +static PyObject *Euler_make_compatible(EulerObject *self, PyObject *value) { float teul[EULER_SIZE]; @@ -302,34 +303,49 @@ //----------------------------print object (internal)-------------- //print the object to screen -static PyObject *Euler_repr(EulerObject * self) +static PyObject *Euler_repr(EulerObject *self) { PyObject *ret, *tuple; if (BaseMath_ReadCallback(self) == -1) return NULL; - tuple= Euler_ToTupleExt(self, -1); + tuple = Euler_ToTupleExt(self, -1); - ret= PyUnicode_FromFormat("Euler(%R, '%s')", tuple, euler_order_str(self)); + ret = PyUnicode_FromFormat("Euler(%R, '%s')", tuple, euler_order_str(self)); Py_DECREF(tuple); return ret; } -static PyObject* Euler_richcmpr(PyObject *a, PyObject *b, int op) +static PyObject *Euler_str(EulerObject *self) +{ + DynStr *ds; + + if (BaseMath_ReadCallback(self) == -1) + return NULL; + + ds = BLI_dynstr_new(); + + BLI_dynstr_appendf(ds, "", + self->eul[0], self->eul[1], self->eul[2], euler_order_str(self)); + + return mathutils_dynstr_to_py(ds); /* frees ds */ +} + +static PyObject *Euler_richcmpr(PyObject *a, PyObject *b, int op) { PyObject *res; - int ok= -1; /* zero is true */ + int ok = -1; /* zero is true */ if (EulerObject_Check(a) && EulerObject_Check(b)) { - EulerObject *eulA= (EulerObject*)a; - EulerObject *eulB= (EulerObject*)b; + EulerObject *eulA = (EulerObject *)a; + EulerObject *eulB = (EulerObject *)b; if (BaseMath_ReadCallback(eulA) == -1 || BaseMath_ReadCallback(eulB) == -1) return NULL; - ok= ((eulA->order == eulB->order) && EXPP_VectorsAreEqual(eulA->eul, eulB->eul, EULER_SIZE, 1)) ? 0 : -1; + ok = ((eulA->order == eulB->order) && EXPP_VectorsAreEqual(eulA->eul, eulB->eul, EULER_SIZE, 1)) ? 0 : -1; } switch (op) { @@ -362,9 +378,9 @@ } //----------------------------object[]--------------------------- //sequence accessor (get) -static PyObject *Euler_item(EulerObject * self, int i) +static PyObject *Euler_item(EulerObject *self, int i) { - if (i<0) i= EULER_SIZE-i; + if (i < 0) i = EULER_SIZE - i; if (i < 0 || i >= EULER_SIZE) { PyErr_SetString(PyExc_IndexError, @@ -381,7 +397,7 @@ } //----------------------------object[]------------------------- //sequence accessor (set) -static int Euler_ass_item(EulerObject * self, int i, PyObject *value) +static int Euler_ass_item(EulerObject *self, int i, PyObject *value) { float f = PyFloat_AsDouble(value); @@ -392,7 +408,7 @@ return -1; } - if (i<0) i= EULER_SIZE-i; + if (i < 0) i = EULER_SIZE - i; if (i < 0 || i >= EULER_SIZE) { PyErr_SetString(PyExc_IndexError, @@ -410,7 +426,7 @@ } //----------------------------object[z:y]------------------------ //sequence slice (get) -static PyObject *Euler_slice(EulerObject * self, int begin, int end) +static PyObject *Euler_slice(EulerObject *self, int begin, int end) { PyObject *tuple; int count; @@ -419,11 +435,11 @@ return NULL; CLAMP(begin, 0, EULER_SIZE); - if (end<0) end= (EULER_SIZE + 1) + end; + if (end < 0) end = (EULER_SIZE + 1) + end; CLAMP(end, 0, EULER_SIZE); - begin= MIN2(begin, end); + begin = MIN2(begin, end); - tuple= PyTuple_New(end - begin); + tuple = PyTuple_New(end - begin); for (count = begin; count < end; count++) { PyTuple_SET_ITEM(tuple, count - begin, PyFloat_FromDouble(self->eul[count])); } @@ -441,11 +457,11 @@ return -1; CLAMP(begin, 0, EULER_SIZE); - if (end<0) end= (EULER_SIZE + 1) + end; + if (end < 0) end = (EULER_SIZE + 1) + end; CLAMP(end, 0, EULER_SIZE); begin = MIN2(begin, end); - if ((size=mathutils_array_parse(eul, 0, EULER_SIZE, seq, "mathutils.Euler[begin:end] = []")) == -1) + if ((size = mathutils_array_parse(eul, 0, EULER_SIZE, seq, "mathutils.Euler[begin:end] = []")) == -1) return -1; if (size != (end - begin)) { @@ -455,7 +471,7 @@ return -1; } - for (i= 0; i < EULER_SIZE; i++) + for (i = 0; i < EULER_SIZE; i++) self->eul[begin + i] = eul[i]; (void)BaseMath_WriteCallback(self); @@ -552,21 +568,27 @@ (objobjargproc)Euler_ass_subscript }; -/* - * euler axis, euler.x/y/z - */ -static PyObject *Euler_getAxis(EulerObject *self, void *type) +/* euler axis, euler.x/y/z */ + +PyDoc_STRVAR(Euler_axis_doc, +"Euler axis angle in radians.\n\n:type: float" +); +static PyObject *Euler_axis_get(EulerObject *self, void *type) { return Euler_item(self, GET_INT_FROM_POINTER(type)); } -static int Euler_setAxis(EulerObject *self, PyObject *value, void *type) +static int Euler_axis_set(EulerObject *self, PyObject *value, void *type) { return Euler_ass_item(self, GET_INT_FROM_POINTER(type), value); } /* rotation order */ -static PyObject *Euler_getOrder(EulerObject *self, void *UNUSED(closure)) + +PyDoc_STRVAR(Euler_order_doc, +"Euler rotation order.\n\n:type: string in ['XYZ', 'XZY', 'YXZ', 'YZX', 'ZXY', 'ZYX']" +); +static PyObject *Euler_order_get(EulerObject *self, void *UNUSED(closure)) { if (BaseMath_ReadCallback(self) == -1) /* can read order too */ return NULL; @@ -574,15 +596,15 @@ return PyUnicode_FromString(euler_order_str(self)); } -static int Euler_setOrder(EulerObject *self, PyObject *value, void *UNUSED(closure)) +static int Euler_order_set(EulerObject *self, PyObject *value, void *UNUSED(closure)) { - const char *order_str= _PyUnicode_AsString(value); - short order= euler_order_from_string(order_str, "euler.order"); + const char *order_str = _PyUnicode_AsString(value); + short order = euler_order_from_string(order_str, "euler.order"); if (order == -1) return -1; - self->order= order; + self->order = order; (void)BaseMath_WriteCallback(self); /* order can be written back */ return 0; } @@ -591,13 +613,13 @@ /* Python attributes get/set structure: */ /*****************************************************************************/ static PyGetSetDef Euler_getseters[] = { - {(char *)"x", (getter)Euler_getAxis, (setter)Euler_setAxis, (char *)"Euler X axis in radians.\n\n:type: float", (void *)0}, - {(char *)"y", (getter)Euler_getAxis, (setter)Euler_setAxis, (char *)"Euler Y axis in radians.\n\n:type: float", (void *)1}, - {(char *)"z", (getter)Euler_getAxis, (setter)Euler_setAxis, (char *)"Euler Z axis in radians.\n\n:type: float", (void *)2}, - {(char *)"order", (getter)Euler_getOrder, (setter)Euler_setOrder, (char *)"Euler rotation order.\n\n:type: string in ['XYZ', 'XZY', 'YXZ', 'YZX', 'ZXY', 'ZYX']", (void *)NULL}, + {(char *)"x", (getter)Euler_axis_get, (setter)Euler_axis_set, Euler_axis_doc, (void *)0}, + {(char *)"y", (getter)Euler_axis_get, (setter)Euler_axis_set, Euler_axis_doc, (void *)1}, + {(char *)"z", (getter)Euler_axis_get, (setter)Euler_axis_set, Euler_axis_doc, (void *)2}, + {(char *)"order", (getter)Euler_order_get, (setter)Euler_order_set, Euler_order_doc, (void *)NULL}, - {(char *)"is_wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, (char *)BaseMathObject_Wrapped_doc, NULL}, - {(char *)"owner", (getter)BaseMathObject_getOwner, (setter)NULL, (char *)BaseMathObject_Owner_doc, NULL}, + {(char *)"is_wrapped", (getter)BaseMathObject_is_wrapped_get, (setter)NULL, BaseMathObject_is_wrapped_doc, NULL}, + {(char *)"owner", (getter)BaseMathObject_owner_get, (setter)NULL, BaseMathObject_owner_doc, NULL}, {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ }; @@ -635,7 +657,7 @@ &Euler_AsMapping, //tp_as_mapping NULL, //tp_hash NULL, //tp_call - NULL, //tp_str + (reprfunc) Euler_str, //tp_str NULL, //tp_getattro NULL, //tp_setattro NULL, //tp_as_buffer @@ -677,13 +699,13 @@ { EulerObject *self; - self= base_type ? (EulerObject *)base_type->tp_alloc(base_type, 0) : + self = base_type ? (EulerObject *)base_type->tp_alloc(base_type, 0) : (EulerObject *)PyObject_GC_New(EulerObject, &euler_Type); if (self) { /* init callbacks as NULL */ - self->cb_user= NULL; - self->cb_type= self->cb_subtype= 0; + self->cb_user = NULL; + self->cb_type = self->cb_subtype = 0; if (type == Py_WRAP) { self->eul = eul; @@ -704,7 +726,7 @@ Py_FatalError("Euler(): invalid type!"); } - self->order= order; + self->order = order; } return (PyObject *)self; @@ -712,12 +734,12 @@ PyObject *Euler_CreatePyObject_cb(PyObject *cb_user, short order, int cb_type, int cb_subtype) { - EulerObject *self= (EulerObject *)Euler_CreatePyObject(NULL, order, Py_NEW, NULL); + EulerObject *self = (EulerObject *)Euler_CreatePyObject(NULL, order, Py_NEW, NULL); if (self) { Py_INCREF(cb_user); - self->cb_user= cb_user; - self->cb_type= (unsigned char)cb_type; - self->cb_subtype= (unsigned char)cb_subtype; + self->cb_user = cb_user; + self->cb_type = (unsigned char)cb_type; + self->cb_subtype = (unsigned char)cb_subtype; PyObject_GC_Track(self); } diff -Nru blender-2.61/source/blender/python/mathutils/mathutils_Euler.h blender-2.62/source/blender/python/mathutils/mathutils_Euler.h --- blender-2.61/source/blender/python/mathutils/mathutils_Euler.h 2011-12-13 19:48:32.000000000 +0000 +++ blender-2.62/source/blender/python/mathutils/mathutils_Euler.h 2012-02-15 19:33:13.000000000 +0000 @@ -47,7 +47,7 @@ /*struct data contains a pointer to the actual data that the object uses. It can use either PyMem allocated data (which will be stored in py_data) or be a wrapper for data allocated through -blender (stored in blend_data). This is an either/or struct not both*/ +blender (stored in blend_data). This is an either/or struct not both */ //prototypes PyObject *Euler_CreatePyObject( float *eul, short order, int type, PyTypeObject *base_type); diff -Nru blender-2.61/source/blender/python/mathutils/mathutils_geometry.c blender-2.62/source/blender/python/mathutils/mathutils_geometry.c --- blender-2.61/source/blender/python/mathutils/mathutils_geometry.c 2011-12-13 19:48:32.000000000 +0000 +++ blender-2.62/source/blender/python/mathutils/mathutils_geometry.c 2012-02-15 19:33:13.000000000 +0000 @@ -47,7 +47,7 @@ #include "BLI_math.h" #include "BLI_utildefines.h" -#define SWAP_FLOAT(a, b, tmp) tmp=a; a=b; b=tmp +#define SWAP_FLOAT(a, b, tmp) tmp = a; a = b; b = tmp /*-------------------------DOC STRINGS ---------------------------*/ PyDoc_STRVAR(M_Geometry_doc, @@ -76,12 +76,12 @@ " :return: The point of intersection or None if no intersection is found\n" " :rtype: :class:`mathutils.Vector` or None\n" ); -static PyObject *M_Geometry_intersect_ray_tri(PyObject *UNUSED(self), PyObject* args) +static PyObject *M_Geometry_intersect_ray_tri(PyObject *UNUSED(self), PyObject *args) { VectorObject *ray, *ray_off, *vec1, *vec2, *vec3; float dir[3], orig[3], v1[3], v2[3], v3[3], e1[3], e2[3], pvec[3], tvec[3], qvec[3]; float det, inv_det, u, v, t; - int clip= 1; + int clip = 1; if (!PyArg_ParseTuple(args, "O!O!O!O!O!|i:intersect_ray_tri", @@ -99,11 +99,11 @@ return NULL; } - if ( BaseMath_ReadCallback(vec1) == -1 || - BaseMath_ReadCallback(vec2) == -1 || - BaseMath_ReadCallback(vec3) == -1 || - BaseMath_ReadCallback(ray) == -1 || - BaseMath_ReadCallback(ray_off) == -1) + if ( BaseMath_ReadCallback(vec1) == -1 || + BaseMath_ReadCallback(vec2) == -1 || + BaseMath_ReadCallback(vec3) == -1 || + BaseMath_ReadCallback(ray) == -1 || + BaseMath_ReadCallback(ray_off) == -1) { return NULL; } @@ -125,19 +125,19 @@ cross_v3_v3v3(pvec, dir, e2); /* if determinant is near zero, ray lies in plane of triangle */ - det= dot_v3v3(e1, pvec); + det = dot_v3v3(e1, pvec); if (det > -0.000001f && det < 0.000001f) { Py_RETURN_NONE; } - inv_det= 1.0f / det; + inv_det = 1.0f / det; /* calculate distance from v1 to ray origin */ sub_v3_v3v3(tvec, orig, v1); /* calculate U parameter and test bounds */ - u= dot_v3v3(tvec, pvec) * inv_det; + u = dot_v3v3(tvec, pvec) * inv_det; if (clip && (u < 0.0f || u > 1.0f)) { Py_RETURN_NONE; } @@ -146,14 +146,14 @@ cross_v3_v3v3(qvec, tvec, e1); /* calculate V parameter and test bounds */ - v= dot_v3v3(dir, qvec) * inv_det; + v = dot_v3v3(dir, qvec) * inv_det; if (clip && (v < 0.0f || u + v > 1.0f)) { Py_RETURN_NONE; } /* calculate t, ray intersects triangle */ - t= dot_v3v3(e2, qvec) * inv_det; + t = dot_v3v3(e2, qvec) * inv_det; mul_v3_fl(dir, t); add_v3_v3v3(pvec, orig, dir); @@ -199,10 +199,10 @@ return NULL; } - if ( BaseMath_ReadCallback(vec1) == -1 || - BaseMath_ReadCallback(vec2) == -1 || - BaseMath_ReadCallback(vec3) == -1 || - BaseMath_ReadCallback(vec4) == -1) + if ( BaseMath_ReadCallback(vec1) == -1 || + BaseMath_ReadCallback(vec2) == -1 || + BaseMath_ReadCallback(vec3) == -1 || + BaseMath_ReadCallback(vec4) == -1) { return NULL; } @@ -217,31 +217,31 @@ copy_v3_v3(v4, vec4->vec); } else { - v1[0]= vec1->vec[0]; - v1[1]= vec1->vec[1]; - v1[2]= 0.0f; + v1[0] = vec1->vec[0]; + v1[1] = vec1->vec[1]; + v1[2] = 0.0f; - v2[0]= vec2->vec[0]; - v2[1]= vec2->vec[1]; - v2[2]= 0.0f; + v2[0] = vec2->vec[0]; + v2[1] = vec2->vec[1]; + v2[2] = 0.0f; - v3[0]= vec3->vec[0]; - v3[1]= vec3->vec[1]; - v3[2]= 0.0f; + v3[0] = vec3->vec[0]; + v3[1] = vec3->vec[1]; + v3[2] = 0.0f; - v4[0]= vec4->vec[0]; - v4[1]= vec4->vec[1]; - v4[2]= 0.0f; + v4[0] = vec4->vec[0]; + v4[1] = vec4->vec[1]; + v4[2] = 0.0f; } - result= isect_line_line_v3(v1, v2, v3, v4, i1, i2); + result = isect_line_line_v3(v1, v2, v3, v4, i1, i2); if (result == 0) { /* colinear */ Py_RETURN_NONE; } else { - tuple= PyTuple_New(2); + tuple = PyTuple_New(2); PyTuple_SET_ITEM(tuple, 0, Vector_CreatePyObject(i1, vec1->size, Py_NEW, NULL)); PyTuple_SET_ITEM(tuple, 1, Vector_CreatePyObject(i2, vec1->size, Py_NEW, NULL)); return tuple; @@ -273,7 +273,7 @@ " :type v4: :class:`mathutils.Vector`\n" " :rtype: :class:`mathutils.Vector`\n" ); -static PyObject *M_Geometry_normal(PyObject *UNUSED(self), PyObject* args) +static PyObject *M_Geometry_normal(PyObject *UNUSED(self), PyObject *args) { VectorObject *vec1, *vec2, *vec3, *vec4; float n[3]; @@ -298,9 +298,9 @@ return NULL; } - if ( BaseMath_ReadCallback(vec1) == -1 || - BaseMath_ReadCallback(vec2) == -1 || - BaseMath_ReadCallback(vec3) == -1) + if ( BaseMath_ReadCallback(vec1) == -1 || + BaseMath_ReadCallback(vec2) == -1 || + BaseMath_ReadCallback(vec3) == -1) { return NULL; } @@ -327,10 +327,10 @@ return NULL; } - if ( BaseMath_ReadCallback(vec1) == -1 || - BaseMath_ReadCallback(vec2) == -1 || - BaseMath_ReadCallback(vec3) == -1 || - BaseMath_ReadCallback(vec4) == -1) + if ( BaseMath_ReadCallback(vec1) == -1 || + BaseMath_ReadCallback(vec2) == -1 || + BaseMath_ReadCallback(vec3) == -1 || + BaseMath_ReadCallback(vec4) == -1) { return NULL; } @@ -356,7 +356,7 @@ " :type v3: :class:`mathutils.Vector`\n" " :rtype: float\n" ); -static PyObject *M_Geometry_area_tri(PyObject *UNUSED(self), PyObject* args) +static PyObject *M_Geometry_area_tri(PyObject *UNUSED(self), PyObject *args) { VectorObject *vec1, *vec2, *vec3; @@ -374,9 +374,9 @@ return NULL; } - if ( BaseMath_ReadCallback(vec1) == -1 || - BaseMath_ReadCallback(vec2) == -1 || - BaseMath_ReadCallback(vec3) == -1) + if ( BaseMath_ReadCallback(vec1) == -1 || + BaseMath_ReadCallback(vec2) == -1 || + BaseMath_ReadCallback(vec3) == -1) { return NULL; } @@ -411,7 +411,7 @@ " :return: The point of intersection or None when not found\n" " :rtype: :class:`mathutils.Vector` or None\n" ); -static PyObject *M_Geometry_intersect_line_line_2d(PyObject *UNUSED(self), PyObject* args) +static PyObject *M_Geometry_intersect_line_line_2d(PyObject *UNUSED(self), PyObject *args) { VectorObject *line_a1, *line_a2, *line_b1, *line_b2; float vi[2]; @@ -424,10 +424,10 @@ return NULL; } - if ( BaseMath_ReadCallback(line_a1) == -1 || - BaseMath_ReadCallback(line_a2) == -1 || - BaseMath_ReadCallback(line_b1) == -1 || - BaseMath_ReadCallback(line_b2) == -1) + if ( BaseMath_ReadCallback(line_a1) == -1 || + BaseMath_ReadCallback(line_a2) == -1 || + BaseMath_ReadCallback(line_b1) == -1 || + BaseMath_ReadCallback(line_b2) == -1) { return NULL; } @@ -459,10 +459,10 @@ " :return: The point of intersection or None when not found\n" " :rtype: :class:`mathutils.Vector` or None\n" ); -static PyObject *M_Geometry_intersect_line_plane(PyObject *UNUSED(self), PyObject* args) +static PyObject *M_Geometry_intersect_line_plane(PyObject *UNUSED(self), PyObject *args) { VectorObject *line_a, *line_b, *plane_co, *plane_no; - int no_flip= 0; + int no_flip = 0; float isect[3]; if (!PyArg_ParseTuple(args, "O!O!O!O!|i:intersect_line_plane", &vector_Type, &line_a, @@ -474,10 +474,10 @@ return NULL; } - if ( BaseMath_ReadCallback(line_a) == -1 || - BaseMath_ReadCallback(line_b) == -1 || - BaseMath_ReadCallback(plane_co) == -1 || - BaseMath_ReadCallback(plane_no) == -1) + if ( BaseMath_ReadCallback(line_a) == -1 || + BaseMath_ReadCallback(line_b) == -1 || + BaseMath_ReadCallback(plane_co) == -1 || + BaseMath_ReadCallback(plane_no) == -1) { return NULL; } @@ -513,7 +513,7 @@ " :return: The line of the intersection represented as a point and a vector\n" " :rtype: tuple pair of :class:`mathutils.Vector`\n" ); -static PyObject *M_Geometry_intersect_plane_plane(PyObject *UNUSED(self), PyObject* args) +static PyObject *M_Geometry_intersect_plane_plane(PyObject *UNUSED(self), PyObject *args) { PyObject *ret; VectorObject *plane_a_co, *plane_a_no, *plane_b_co, *plane_b_no; @@ -530,10 +530,10 @@ return NULL; } - if ( BaseMath_ReadCallback(plane_a_co) == -1 || - BaseMath_ReadCallback(plane_a_no) == -1 || - BaseMath_ReadCallback(plane_b_co) == -1 || - BaseMath_ReadCallback(plane_b_no) == -1) + if ( BaseMath_ReadCallback(plane_a_co) == -1 || + BaseMath_ReadCallback(plane_a_no) == -1 || + BaseMath_ReadCallback(plane_b_co) == -1 || + BaseMath_ReadCallback(plane_b_no) == -1) { return NULL; } @@ -551,7 +551,7 @@ normalize_v3(isect_no); - ret= PyTuple_New(2); + ret = PyTuple_New(2); PyTuple_SET_ITEM(ret, 0, Vector_CreatePyObject(isect_co, 3, Py_NEW, NULL)); PyTuple_SET_ITEM(ret, 1, Vector_CreatePyObject(isect_no, 3, Py_NEW, NULL)); return ret; @@ -574,11 +574,11 @@ " :return: The intersection points as a pair of vectors or None when there is no intersection\n" " :rtype: A tuple pair containing :class:`mathutils.Vector` or None\n" ); -static PyObject *M_Geometry_intersect_line_sphere(PyObject *UNUSED(self), PyObject* args) +static PyObject *M_Geometry_intersect_line_sphere(PyObject *UNUSED(self), PyObject *args) { VectorObject *line_a, *line_b, *sphere_co; float sphere_radius; - int clip= TRUE; + int clip = TRUE; float isect_a[3]; float isect_b[3]; @@ -592,9 +592,9 @@ return NULL; } - if ( BaseMath_ReadCallback(line_a) == -1 || - BaseMath_ReadCallback(line_b) == -1 || - BaseMath_ReadCallback(sphere_co) == -1) + if ( BaseMath_ReadCallback(line_a) == -1 || + BaseMath_ReadCallback(line_b) == -1 || + BaseMath_ReadCallback(sphere_co) == -1) { return NULL; } @@ -606,24 +606,24 @@ return NULL; } else { - short use_a= TRUE; - short use_b= TRUE; + short use_a = TRUE; + short use_b = TRUE; float lambda; - PyObject *ret= PyTuple_New(2); + PyObject *ret = PyTuple_New(2); - switch(isect_line_sphere_v3(line_a->vec, line_b->vec, sphere_co->vec, sphere_radius, isect_a, isect_b)) { + switch (isect_line_sphere_v3(line_a->vec, line_b->vec, sphere_co->vec, sphere_radius, isect_a, isect_b)) { case 1: - if (!(!clip || (((lambda= line_point_factor_v3(isect_a, line_a->vec, line_b->vec)) >= 0.0f) && (lambda <= 1.0f)))) use_a= FALSE; - use_b= FALSE; + if (!(!clip || (((lambda = line_point_factor_v3(isect_a, line_a->vec, line_b->vec)) >= 0.0f) && (lambda <= 1.0f)))) use_a = FALSE; + use_b = FALSE; break; case 2: - if (!(!clip || (((lambda= line_point_factor_v3(isect_a, line_a->vec, line_b->vec)) >= 0.0f) && (lambda <= 1.0f)))) use_a= FALSE; - if (!(!clip || (((lambda= line_point_factor_v3(isect_b, line_a->vec, line_b->vec)) >= 0.0f) && (lambda <= 1.0f)))) use_b= FALSE; + if (!(!clip || (((lambda = line_point_factor_v3(isect_a, line_a->vec, line_b->vec)) >= 0.0f) && (lambda <= 1.0f)))) use_a = FALSE; + if (!(!clip || (((lambda = line_point_factor_v3(isect_b, line_a->vec, line_b->vec)) >= 0.0f) && (lambda <= 1.0f)))) use_b = FALSE; break; default: - use_a= FALSE; - use_b= FALSE; + use_a = FALSE; + use_b = FALSE; } if (use_a) { PyTuple_SET_ITEM(ret, 0, Vector_CreatePyObject(isect_a, 3, Py_NEW, NULL)); } @@ -654,11 +654,11 @@ " :return: The intersection points as a pair of vectors or None when there is no intersection\n" " :rtype: A tuple pair containing :class:`mathutils.Vector` or None\n" ); -static PyObject *M_Geometry_intersect_line_sphere_2d(PyObject *UNUSED(self), PyObject* args) +static PyObject *M_Geometry_intersect_line_sphere_2d(PyObject *UNUSED(self), PyObject *args) { VectorObject *line_a, *line_b, *sphere_co; float sphere_radius; - int clip= TRUE; + int clip = TRUE; float isect_a[3]; float isect_b[3]; @@ -672,31 +672,31 @@ return NULL; } - if ( BaseMath_ReadCallback(line_a) == -1 || - BaseMath_ReadCallback(line_b) == -1 || - BaseMath_ReadCallback(sphere_co) == -1) + if ( BaseMath_ReadCallback(line_a) == -1 || + BaseMath_ReadCallback(line_b) == -1 || + BaseMath_ReadCallback(sphere_co) == -1) { return NULL; } else { - short use_a= TRUE; - short use_b= TRUE; + short use_a = TRUE; + short use_b = TRUE; float lambda; - PyObject *ret= PyTuple_New(2); + PyObject *ret = PyTuple_New(2); - switch(isect_line_sphere_v2(line_a->vec, line_b->vec, sphere_co->vec, sphere_radius, isect_a, isect_b)) { + switch (isect_line_sphere_v2(line_a->vec, line_b->vec, sphere_co->vec, sphere_radius, isect_a, isect_b)) { case 1: - if (!(!clip || (((lambda= line_point_factor_v2(isect_a, line_a->vec, line_b->vec)) >= 0.0f) && (lambda <= 1.0f)))) use_a= FALSE; - use_b= FALSE; + if (!(!clip || (((lambda = line_point_factor_v2(isect_a, line_a->vec, line_b->vec)) >= 0.0f) && (lambda <= 1.0f)))) use_a = FALSE; + use_b = FALSE; break; case 2: - if (!(!clip || (((lambda= line_point_factor_v2(isect_a, line_a->vec, line_b->vec)) >= 0.0f) && (lambda <= 1.0f)))) use_a= FALSE; - if (!(!clip || (((lambda= line_point_factor_v2(isect_b, line_a->vec, line_b->vec)) >= 0.0f) && (lambda <= 1.0f)))) use_b= FALSE; + if (!(!clip || (((lambda = line_point_factor_v2(isect_a, line_a->vec, line_b->vec)) >= 0.0f) && (lambda <= 1.0f)))) use_a = FALSE; + if (!(!clip || (((lambda = line_point_factor_v2(isect_b, line_a->vec, line_b->vec)) >= 0.0f) && (lambda <= 1.0f)))) use_b = FALSE; break; default: - use_a= FALSE; - use_b= FALSE; + use_a = FALSE; + use_b = FALSE; } if (use_a) { PyTuple_SET_ITEM(ret, 0, Vector_CreatePyObject(isect_a, 2, Py_NEW, NULL)); } @@ -722,7 +722,7 @@ " :type line_p1: :class:`mathutils.Vector`\n" " :rtype: (:class:`mathutils.Vector`, float)\n" ); -static PyObject *M_Geometry_intersect_point_line(PyObject *UNUSED(self), PyObject* args) +static PyObject *M_Geometry_intersect_point_line(PyObject *UNUSED(self), PyObject *args) { VectorObject *pt, *line_1, *line_2; float pt_in[3], pt_out[3], l1[3], l2[3]; @@ -737,27 +737,27 @@ return NULL; } - if ( BaseMath_ReadCallback(pt) == -1 || - BaseMath_ReadCallback(line_1) == -1 || - BaseMath_ReadCallback(line_2) == -1) + if ( BaseMath_ReadCallback(pt) == -1 || + BaseMath_ReadCallback(line_1) == -1 || + BaseMath_ReadCallback(line_2) == -1) { return NULL; } /* accept 2d verts */ - if (pt->size==3) { copy_v3_v3(pt_in, pt->vec);} - else { pt_in[2]=0.0; copy_v2_v2(pt_in, pt->vec); } + if (pt->size == 3) { copy_v3_v3(pt_in, pt->vec);} + else { pt_in[2] = 0.0f; copy_v2_v2(pt_in, pt->vec); } - if (line_1->size==3) { copy_v3_v3(l1, line_1->vec);} - else { l1[2]=0.0; copy_v2_v2(l1, line_1->vec); } + if (line_1->size == 3) { copy_v3_v3(l1, line_1->vec);} + else { l1[2] = 0.0f; copy_v2_v2(l1, line_1->vec); } - if (line_2->size==3) { copy_v3_v3(l2, line_2->vec);} - else { l2[2]=0.0; copy_v2_v2(l2, line_2->vec); } + if (line_2->size == 3) { copy_v3_v3(l2, line_2->vec);} + else { l2[2] = 0.0f; copy_v2_v2(l2, line_2->vec); } /* do the calculation */ - lambda= closest_to_line_v3(pt_out, pt_in, l1, l2); + lambda = closest_to_line_v3(pt_out, pt_in, l1, l2); - ret= PyTuple_New(2); + ret = PyTuple_New(2); PyTuple_SET_ITEM(ret, 0, Vector_CreatePyObject(pt_out, 3, Py_NEW, NULL)); PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(lambda)); return ret; @@ -778,7 +778,7 @@ " :type tri_p3: :class:`mathutils.Vector`\n" " :rtype: int\n" ); -static PyObject *M_Geometry_intersect_point_tri_2d(PyObject *UNUSED(self), PyObject* args) +static PyObject *M_Geometry_intersect_point_tri_2d(PyObject *UNUSED(self), PyObject *args) { VectorObject *pt_vec, *tri_p1, *tri_p2, *tri_p3; @@ -791,10 +791,10 @@ return NULL; } - if ( BaseMath_ReadCallback(pt_vec) == -1 || - BaseMath_ReadCallback(tri_p1) == -1 || - BaseMath_ReadCallback(tri_p2) == -1 || - BaseMath_ReadCallback(tri_p3) == -1) + if ( BaseMath_ReadCallback(pt_vec) == -1 || + BaseMath_ReadCallback(tri_p1) == -1 || + BaseMath_ReadCallback(tri_p2) == -1 || + BaseMath_ReadCallback(tri_p3) == -1) { return NULL; } @@ -805,7 +805,8 @@ PyDoc_STRVAR(M_Geometry_intersect_point_quad_2d_doc, ".. function:: intersect_point_quad_2d(pt, quad_p1, quad_p2, quad_p3, quad_p4)\n" "\n" -" Takes 5 vectors (using only the x and y coordinates): one is the point and the next 4 define the quad, only the x and y are used from the vectors. Returns 1 if the point is within the quad, otherwise 0.\n" +" Takes 5 vectors (using only the x and y coordinates): one is the point and the next 4 define the quad, \n" +" only the x and y are used from the vectors. Returns 1 if the point is within the quad, otherwise 0.\n" "\n" " :arg pt: Point\n" " :type pt: :class:`mathutils.Vector`\n" @@ -819,7 +820,7 @@ " :type quad_p4: :class:`mathutils.Vector`\n" " :rtype: int\n" ); -static PyObject *M_Geometry_intersect_point_quad_2d(PyObject *UNUSED(self), PyObject* args) +static PyObject *M_Geometry_intersect_point_quad_2d(PyObject *UNUSED(self), PyObject *args) { VectorObject *pt_vec, *quad_p1, *quad_p2, *quad_p3, *quad_p4; @@ -833,11 +834,11 @@ return NULL; } - if ( BaseMath_ReadCallback(pt_vec) == -1 || - BaseMath_ReadCallback(quad_p1) == -1 || - BaseMath_ReadCallback(quad_p2) == -1 || - BaseMath_ReadCallback(quad_p3) == -1 || - BaseMath_ReadCallback(quad_p4) == -1) + if ( BaseMath_ReadCallback(pt_vec) == -1 || + BaseMath_ReadCallback(quad_p1) == -1 || + BaseMath_ReadCallback(quad_p2) == -1 || + BaseMath_ReadCallback(quad_p3) == -1 || + BaseMath_ReadCallback(quad_p4) == -1) { return NULL; } @@ -859,7 +860,7 @@ " :type plane_no: :class:`mathutils.Vector`\n" " :rtype: float\n" ); -static PyObject *M_Geometry_distance_point_to_plane(PyObject *UNUSED(self), PyObject* args) +static PyObject *M_Geometry_distance_point_to_plane(PyObject *UNUSED(self), PyObject *args) { VectorObject *pt, *plene_co, *plane_no; @@ -871,9 +872,9 @@ return NULL; } - if ( BaseMath_ReadCallback(pt) == -1 || - BaseMath_ReadCallback(plene_co) == -1 || - BaseMath_ReadCallback(plane_no) == -1) + if ( BaseMath_ReadCallback(pt) == -1 || + BaseMath_ReadCallback(plene_co) == -1 || + BaseMath_ReadCallback(plane_no) == -1) { return NULL; } @@ -962,7 +963,7 @@ " :return: The interpolated points\n" " :rtype: list of :class:`mathutils.Vector`'s\n" ); -static PyObject *M_Geometry_interpolate_bezier(PyObject *UNUSED(self), PyObject* args) +static PyObject *M_Geometry_interpolate_bezier(PyObject *UNUSED(self), PyObject *args) { VectorObject *vec_k1, *vec_h1, *vec_k2, *vec_h2; int resolu; @@ -971,10 +972,10 @@ float *coord_array, *fp; PyObject *list; - float k1[4]= {0.0, 0.0, 0.0, 0.0}; - float h1[4]= {0.0, 0.0, 0.0, 0.0}; - float k2[4]= {0.0, 0.0, 0.0, 0.0}; - float h2[4]= {0.0, 0.0, 0.0, 0.0}; + float k1[4] = {0.0, 0.0, 0.0, 0.0}; + float h1[4] = {0.0, 0.0, 0.0, 0.0}; + float k2[4] = {0.0, 0.0, 0.0, 0.0}; + float h2[4] = {0.0, 0.0, 0.0, 0.0}; if (!PyArg_ParseTuple(args, "O!O!O!O!i:interpolate_bezier", @@ -992,29 +993,29 @@ return NULL; } - if ( BaseMath_ReadCallback(vec_k1) == -1 || - BaseMath_ReadCallback(vec_h1) == -1 || - BaseMath_ReadCallback(vec_k2) == -1 || - BaseMath_ReadCallback(vec_h2) == -1) + if ( BaseMath_ReadCallback(vec_k1) == -1 || + BaseMath_ReadCallback(vec_h1) == -1 || + BaseMath_ReadCallback(vec_k2) == -1 || + BaseMath_ReadCallback(vec_h2) == -1) { return NULL; } - dims= MAX4(vec_k1->size, vec_h1->size, vec_h2->size, vec_k2->size); + dims = MAX4(vec_k1->size, vec_h1->size, vec_h2->size, vec_k2->size); - for (i=0; i < vec_k1->size; i++) k1[i]= vec_k1->vec[i]; - for (i=0; i < vec_h1->size; i++) h1[i]= vec_h1->vec[i]; - for (i=0; i < vec_k2->size; i++) k2[i]= vec_k2->vec[i]; - for (i=0; i < vec_h2->size; i++) h2[i]= vec_h2->vec[i]; + for (i = 0; i < vec_k1->size; i++) k1[i] = vec_k1->vec[i]; + for (i = 0; i < vec_h1->size; i++) h1[i] = vec_h1->vec[i]; + for (i = 0; i < vec_k2->size; i++) k2[i] = vec_k2->vec[i]; + for (i = 0; i < vec_h2->size; i++) h2[i] = vec_h2->vec[i]; - coord_array= MEM_callocN(dims * (resolu) * sizeof(float), "interpolate_bezier"); - for (i=0; iverts to set the points from the vectors */ - int index, *dl_face, totpoints=0; + int index, *dl_face, totpoints = 0; if (!PySequence_Check(polyLineSeq)) { PyErr_SetString(PyExc_TypeError, @@ -1049,10 +1050,10 @@ return NULL; } - len_polylines= PySequence_Size(polyLineSeq); + len_polylines = PySequence_Size(polyLineSeq); - for (i= 0; i < len_polylines; ++i) { - polyLine= PySequence_GetItem(polyLineSeq, i); + for (i = 0; i < len_polylines; i++) { + polyLine = PySequence_GetItem(polyLineSeq, i); if (!PySequence_Check(polyLine)) { freedisplist(&dispbase); Py_XDECREF(polyLine); /* may be null so use Py_XDECREF*/ @@ -1061,8 +1062,8 @@ return NULL; } - len_polypoints= PySequence_Size(polyLine); - if (len_polypoints>0) { /* dont bother adding edges as polylines */ + len_polypoints = PySequence_Size(polyLine); + if (len_polypoints > 0) { /* dont bother adding edges as polylines */ #if 0 if (EXPP_check_sequence_consistency(polyLine, &vector_Type) != 1) { freedisplist(&dispbase); @@ -1072,32 +1073,32 @@ return NULL; } #endif - dl= MEM_callocN(sizeof(DispList), "poly disp"); + dl = MEM_callocN(sizeof(DispList), "poly disp"); BLI_addtail(&dispbase, dl); - dl->type= DL_INDEX3; - dl->nr= len_polypoints; - dl->type= DL_POLY; - dl->parts= 1; /* no faces, 1 edge loop */ - dl->col= 0; /* no material */ - dl->verts= fp= MEM_callocN(sizeof(float)*3*len_polypoints, "dl verts"); - dl->index= MEM_callocN(sizeof(int)*3*len_polypoints, "dl index"); + dl->type = DL_INDEX3; + dl->nr = len_polypoints; + dl->type = DL_POLY; + dl->parts = 1; /* no faces, 1 edge loop */ + dl->col = 0; /* no material */ + dl->verts = fp = MEM_callocN(sizeof(float) * 3 * len_polypoints, "dl verts"); + dl->index = MEM_callocN(sizeof(int) * 3 * len_polypoints, "dl index"); - for (index= 0; indexvec[0]; - fp[1]= ((VectorObject *)polyVec)->vec[1]; + fp[0] = ((VectorObject *)polyVec)->vec[0]; + fp[1] = ((VectorObject *)polyVec)->vec[1]; if (((VectorObject *)polyVec)->size > 2) - fp[2]= ((VectorObject *)polyVec)->vec[2]; + fp[2] = ((VectorObject *)polyVec)->vec[2]; else - fp[2]= 0.0f; /* if its a 2d vector then set the z to be zero */ + fp[2] = 0.0f; /* if its a 2d vector then set the z to be zero */ } else { - ls_error= 1; + ls_error = 1; } totpoints++; @@ -1120,9 +1121,9 @@ /* The faces are stored in a new DisplayList thats added to the head of the listbase */ - dl= dispbase.first; + dl = dispbase.first; - tri_list= PyList_New(dl->parts); + tri_list = PyList_New(dl->parts); if (!tri_list) { freedisplist(&dispbase); PyErr_SetString(PyExc_RuntimeError, @@ -1130,11 +1131,11 @@ return NULL; } - index= 0; - dl_face= dl->index; + index = 0; + dl_face = dl->index; while (index < dl->parts) { PyList_SET_ITEM(tri_list, index, Py_BuildValue("iii", dl_face[0], dl_face[1], dl_face[2])); - dl_face+= 3; + dl_face += 3; index++; } freedisplist(&dispbase); @@ -1142,7 +1143,7 @@ else { /* no points, do this so scripts dont barf */ freedisplist(&dispbase); /* possible some dl was allocated */ - tri_list= PyList_New(0); + tri_list = PyList_New(0); } return tri_list; @@ -1163,13 +1164,13 @@ return -1; } - len= PyList_GET_SIZE(value); + len = PyList_GET_SIZE(value); - (*boxarray)= MEM_mallocN(len*sizeof(boxPack), "boxPack box"); + *boxarray = MEM_mallocN(len * sizeof(boxPack), "boxPack box"); - for (i= 0; i < len; i++) { - list_item= PyList_GET_ITEM(value, i); + for (i = 0; i < len; i++) { + list_item = PyList_GET_ITEM(value, i); if (!PyList_Check(list_item) || PyList_GET_SIZE(list_item) < 4) { MEM_freeN(*boxarray); PyErr_SetString(PyExc_TypeError, @@ -1177,14 +1178,14 @@ return -1; } - box= (*boxarray)+i; + box = (*boxarray) + i; - item_1= PyList_GET_ITEM(list_item, 2); - item_2= PyList_GET_ITEM(list_item, 3); + item_1 = PyList_GET_ITEM(list_item, 2); + item_2 = PyList_GET_ITEM(list_item, 3); - box->w= (float)PyFloat_AsDouble(item_1); - box->h= (float)PyFloat_AsDouble(item_2); - box->index= i; + box->w = (float)PyFloat_AsDouble(item_1); + box->h = (float)PyFloat_AsDouble(item_2); + box->index = i; /* accounts for error case too and overwrites with own error */ if (box->w < 0.0f || box->h < 0.0f) { @@ -1206,11 +1207,11 @@ PyObject *list_item; boxPack *box; - len= PyList_GET_SIZE(value); + len = PyList_GET_SIZE(value); - for (i= 0; i < len; i++) { - box= (*boxarray)+i; - list_item= PyList_GET_ITEM(value, box->index); + for (i = 0; i < len; i++) { + box = (*boxarray) + i; + list_item = PyList_GET_ITEM(value, box->index); PyList_SET_ITEM(list_item, 0, PyFloat_FromDouble(box->x)); PyList_SET_ITEM(list_item, 1, PyFloat_FromDouble(box->y)); } @@ -1229,7 +1230,7 @@ ); static PyObject *M_Geometry_box_pack_2d(PyObject *UNUSED(self), PyObject *boxlist) { - float tot_width= 0.0f, tot_height= 0.0f; + float tot_width = 0.0f, tot_height = 0.0f; Py_ssize_t len; PyObject *ret; @@ -1240,9 +1241,9 @@ return NULL; } - len= PyList_GET_SIZE(boxlist); + len = PyList_GET_SIZE(boxlist); if (len) { - boxPack *boxarray= NULL; + boxPack *boxarray = NULL; if (boxPack_FromPyObject(boxlist, &boxarray) == -1) { return NULL; /* exception set */ } @@ -1253,7 +1254,7 @@ boxPack_ToPyObject(boxlist, &boxarray); } - ret= PyTuple_New(2); + ret = PyTuple_New(2); PyTuple_SET_ITEM(ret, 0, PyFloat_FromDouble(tot_width)); PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(tot_width)); return ret; @@ -1262,7 +1263,7 @@ #endif /* MATH_STANDALONE */ -static PyMethodDef M_Geometry_methods[]= { +static PyMethodDef M_Geometry_methods[] = { {"intersect_ray_tri", (PyCFunction) M_Geometry_intersect_ray_tri, METH_VARARGS, M_Geometry_intersect_ray_tri_doc}, {"intersect_point_line", (PyCFunction) M_Geometry_intersect_point_line, METH_VARARGS, M_Geometry_intersect_point_line_doc}, {"intersect_point_tri_2d", (PyCFunction) M_Geometry_intersect_point_tri_2d, METH_VARARGS, M_Geometry_intersect_point_tri_2d_doc}, @@ -1285,7 +1286,7 @@ {NULL, NULL, 0, NULL} }; -static struct PyModuleDef M_Geometry_module_def= { +static struct PyModuleDef M_Geometry_module_def = { PyModuleDef_HEAD_INIT, "mathutils.geometry", /* m_name */ M_Geometry_doc, /* m_doc */ @@ -1300,6 +1301,6 @@ /*----------------------------MODULE INIT-------------------------*/ PyMODINIT_FUNC PyInit_mathutils_geometry(void) { - PyObject *submodule= PyModule_Create(&M_Geometry_module_def); + PyObject *submodule = PyModule_Create(&M_Geometry_module_def); return submodule; } diff -Nru blender-2.61/source/blender/python/mathutils/mathutils.h blender-2.62/source/blender/python/mathutils/mathutils.h --- blender-2.61/source/blender/python/mathutils/mathutils.h 2011-12-13 19:48:32.000000000 +0000 +++ blender-2.62/source/blender/python/mathutils/mathutils.h 2012-02-15 19:33:13.000000000 +0000 @@ -37,8 +37,10 @@ /* Can cast different mathutils types to this, use for generic funcs */ -extern char BaseMathObject_Wrapped_doc[]; -extern char BaseMathObject_Owner_doc[]; +struct DynStr; + +extern char BaseMathObject_is_wrapped_doc[]; +extern char BaseMathObject_owner_doc[]; #define BASE_MATH_MEMBERS(_data) \ PyObject_VAR_HEAD \ @@ -65,8 +67,8 @@ #include "mathutils_geometry.h" #include "mathutils_noise.h" -PyObject *BaseMathObject_getOwner( BaseMathObject * self, void * ); -PyObject *BaseMathObject_getWrapped( BaseMathObject *self, void * ); +PyObject *BaseMathObject_owner_get( BaseMathObject * self, void * ); +PyObject *BaseMathObject_is_wrapped_get( BaseMathObject *self, void * ); int BaseMathObject_traverse(BaseMathObject *self, visitproc visit, void *arg); int BaseMathObject_clear(BaseMathObject *self); @@ -115,8 +117,12 @@ /* utility func */ int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix); +int mathutils_array_parse_alloc(float **array, int array_min, PyObject *value, const char *error_prefix); int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error_prefix); int column_vector_multiplication(float rvec[4], VectorObject *vec, MatrixObject *mat); +/* dynstr as python string utility funcions */ +PyObject *mathutils_dynstr_to_py(struct DynStr *ds); + #endif /* MATHUTILS_H */ diff -Nru blender-2.61/source/blender/python/mathutils/mathutils_Matrix.c blender-2.62/source/blender/python/mathutils/mathutils_Matrix.c --- blender-2.61/source/blender/python/mathutils/mathutils_Matrix.c 2011-12-13 19:48:32.000000000 +0000 +++ blender-2.62/source/blender/python/mathutils/mathutils_Matrix.c 2012-02-15 19:33:13.000000000 +0000 @@ -35,81 +35,299 @@ #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLI_string.h" +#include "BLI_dynstr.h" + +typedef enum eMatrixAccess_t { + MAT_ACCESS_ROW, + MAT_ACCESS_COL +} eMatrixAccess_t; static PyObject *Matrix_copy(MatrixObject *self); static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *value); static PyObject *matrix__apply_to_copy(PyNoArgsFunction matrix_func, MatrixObject *self); +static PyObject *MatrixAccess_CreatePyObject(MatrixObject *matrix, const eMatrixAccess_t type); + +static int matrix_row_vector_check(MatrixObject *mat, VectorObject *vec, int row) +{ + if ((vec->size != mat->num_col) || (row >= mat->num_row)) { + PyErr_SetString(PyExc_AttributeError, + "Matrix(): " + "owner matrix has been resized since this row vector was created"); + return 0; + } + else { + return 1; + } +} + +static int matrix_col_vector_check(MatrixObject *mat, VectorObject *vec, int col) +{ + if ((vec->size != mat->num_row) || (col >= mat->num_col)) { + PyErr_SetString(PyExc_AttributeError, + "Matrix(): " + "owner matrix has been resized since this column vector was created"); + return 0; + } + else { + return 1; + } +} + +/* ---------------------------------------------------------------------------- + * matrix row callbacks + * this is so you can do matrix[i][j] = val OR matrix.row[i][j] = val */ + +int mathutils_matrix_row_cb_index = -1; + +static int mathutils_matrix_row_check(BaseMathObject *bmo) +{ + MatrixObject *self = (MatrixObject *)bmo->cb_user; + return BaseMath_ReadCallback(self); +} + +static int mathutils_matrix_row_get(BaseMathObject *bmo, int row) +{ + MatrixObject *self = (MatrixObject *)bmo->cb_user; + int col; + + if (BaseMath_ReadCallback(self) == -1) + return -1; + if (!matrix_row_vector_check(self, (VectorObject *)bmo, row)) + return -1; + + for (col = 0; col < self->num_col; col++) { + bmo->data[col] = MATRIX_ITEM(self, row, col); + } + + return 0; +} + +static int mathutils_matrix_row_set(BaseMathObject *bmo, int row) +{ + MatrixObject *self = (MatrixObject *)bmo->cb_user; + int col; + + if (BaseMath_ReadCallback(self) == -1) + return -1; + if (!matrix_row_vector_check(self, (VectorObject *)bmo, row)) + return -1; + + for (col = 0; col < self->num_col; col++) { + MATRIX_ITEM(self, row, col) = bmo->data[col]; + } + + (void)BaseMath_WriteCallback(self); + return 0; +} + +static int mathutils_matrix_row_get_index(BaseMathObject *bmo, int row, int col) +{ + MatrixObject *self = (MatrixObject *)bmo->cb_user; + + if (BaseMath_ReadCallback(self) == -1) + return -1; + if (!matrix_row_vector_check(self, (VectorObject *)bmo, row)) + return -1; + + bmo->data[col] = MATRIX_ITEM(self, row, col); + return 0; +} + +static int mathutils_matrix_row_set_index(BaseMathObject *bmo, int row, int col) +{ + MatrixObject *self = (MatrixObject *)bmo->cb_user; + + if (BaseMath_ReadCallback(self) == -1) + return -1; + if (!matrix_row_vector_check(self, (VectorObject *)bmo, row)) + return -1; + + MATRIX_ITEM(self, row, col) = bmo->data[col]; -/* matrix vector callbacks */ -int mathutils_matrix_vector_cb_index= -1; + (void)BaseMath_WriteCallback(self); + return 0; +} + +Mathutils_Callback mathutils_matrix_row_cb = { + mathutils_matrix_row_check, + mathutils_matrix_row_get, + mathutils_matrix_row_set, + mathutils_matrix_row_get_index, + mathutils_matrix_row_set_index +}; + + +/* ---------------------------------------------------------------------------- + * matrix row callbacks + * this is so you can do matrix.col[i][j] = val */ -static int mathutils_matrix_vector_check(BaseMathObject *bmo) +int mathutils_matrix_col_cb_index = -1; + +static int mathutils_matrix_col_check(BaseMathObject *bmo) { - MatrixObject *self= (MatrixObject *)bmo->cb_user; + MatrixObject *self = (MatrixObject *)bmo->cb_user; return BaseMath_ReadCallback(self); } -static int mathutils_matrix_vector_get(BaseMathObject *bmo, int subtype) +static int mathutils_matrix_col_get(BaseMathObject *bmo, int col) { - MatrixObject *self= (MatrixObject *)bmo->cb_user; - int i; + MatrixObject *self = (MatrixObject *)bmo->cb_user; + int num_row; + int row; if (BaseMath_ReadCallback(self) == -1) return -1; + if (!matrix_col_vector_check(self, (VectorObject *)bmo, col)) + return -1; + + /* for 'translation' size will always be '3' even on 4x4 vec */ + num_row = MIN2(self->num_row, ((VectorObject *)bmo)->size); - for (i=0; i < self->col_size; i++) - bmo->data[i]= self->matrix[subtype][i]; + for (row = 0; row < num_row; row++) { + bmo->data[row] = MATRIX_ITEM(self, row, col); + } return 0; } -static int mathutils_matrix_vector_set(BaseMathObject *bmo, int subtype) +static int mathutils_matrix_col_set(BaseMathObject *bmo, int col) { - MatrixObject *self= (MatrixObject *)bmo->cb_user; - int i; + MatrixObject *self = (MatrixObject *)bmo->cb_user; + int num_row; + int row; if (BaseMath_ReadCallback(self) == -1) return -1; + if (!matrix_col_vector_check(self, (VectorObject *)bmo, col)) + return -1; - for (i=0; i < self->col_size; i++) - self->matrix[subtype][i]= bmo->data[i]; + /* for 'translation' size will always be '3' even on 4x4 vec */ + num_row = MIN2(self->num_row, ((VectorObject *)bmo)->size); + + for (row = 0; row < num_row; row++) { + MATRIX_ITEM(self, row, col) = bmo->data[row]; + } (void)BaseMath_WriteCallback(self); return 0; } -static int mathutils_matrix_vector_get_index(BaseMathObject *bmo, int subtype, int index) +static int mathutils_matrix_col_get_index(BaseMathObject *bmo, int col, int row) { - MatrixObject *self= (MatrixObject *)bmo->cb_user; + MatrixObject *self = (MatrixObject *)bmo->cb_user; if (BaseMath_ReadCallback(self) == -1) return -1; + if (!matrix_col_vector_check(self, (VectorObject *)bmo, col)) + return -1; - bmo->data[index]= self->matrix[subtype][index]; + bmo->data[row] = MATRIX_ITEM(self, row, col); return 0; } -static int mathutils_matrix_vector_set_index(BaseMathObject *bmo, int subtype, int index) +static int mathutils_matrix_col_set_index(BaseMathObject *bmo, int col, int row) { - MatrixObject *self= (MatrixObject *)bmo->cb_user; + MatrixObject *self = (MatrixObject *)bmo->cb_user; if (BaseMath_ReadCallback(self) == -1) return -1; + if (!matrix_col_vector_check(self, (VectorObject *)bmo, col)) + return -1; - self->matrix[subtype][index]= bmo->data[index]; + MATRIX_ITEM(self, row, col) = bmo->data[row]; (void)BaseMath_WriteCallback(self); return 0; } -Mathutils_Callback mathutils_matrix_vector_cb = { - mathutils_matrix_vector_check, - mathutils_matrix_vector_get, - mathutils_matrix_vector_set, - mathutils_matrix_vector_get_index, - mathutils_matrix_vector_set_index +Mathutils_Callback mathutils_matrix_col_cb = { + mathutils_matrix_col_check, + mathutils_matrix_col_get, + mathutils_matrix_col_set, + mathutils_matrix_col_get_index, + mathutils_matrix_col_set_index }; -/* matrix vector callbacks, this is so you can do matrix[i][j] = val */ + + +/* ---------------------------------------------------------------------------- + * matrix row callbacks + * this is so you can do matrix.translation = val + * note, this is _exactly like matrix.col except the 4th component is always omitted */ + +int mathutils_matrix_translation_cb_index = -1; + +static int mathutils_matrix_translation_check(BaseMathObject *bmo) +{ + MatrixObject *self = (MatrixObject *)bmo->cb_user; + return BaseMath_ReadCallback(self); +} + +static int mathutils_matrix_translation_get(BaseMathObject *bmo, int col) +{ + MatrixObject *self = (MatrixObject *)bmo->cb_user; + int row; + + if (BaseMath_ReadCallback(self) == -1) + return -1; + + for (row = 0; row < 3; row++) { + bmo->data[row] = MATRIX_ITEM(self, row, col); + } + + return 0; +} + +static int mathutils_matrix_translation_set(BaseMathObject *bmo, int col) +{ + MatrixObject *self = (MatrixObject *)bmo->cb_user; + int row; + + if (BaseMath_ReadCallback(self) == -1) + return -1; + + for (row = 0; row < 3; row++) { + MATRIX_ITEM(self, row, col) = bmo->data[row]; + } + + (void)BaseMath_WriteCallback(self); + return 0; +} + +static int mathutils_matrix_translation_get_index(BaseMathObject *bmo, int col, int row) +{ + MatrixObject *self = (MatrixObject *)bmo->cb_user; + + if (BaseMath_ReadCallback(self) == -1) + return -1; + + bmo->data[row] = MATRIX_ITEM(self, row, col); + return 0; +} + +static int mathutils_matrix_translation_set_index(BaseMathObject *bmo, int col, int row) +{ + MatrixObject *self = (MatrixObject *)bmo->cb_user; + + if (BaseMath_ReadCallback(self) == -1) + return -1; + + MATRIX_ITEM(self, row, col) = bmo->data[row]; + + (void)BaseMath_WriteCallback(self); + return 0; +} + +Mathutils_Callback mathutils_matrix_translation_cb = { + mathutils_matrix_translation_check, + mathutils_matrix_translation_get, + mathutils_matrix_translation_set, + mathutils_matrix_translation_get_index, + mathutils_matrix_translation_set_index +}; + + +/* matrix column callbacks, this is so you can do matrix.translation = Vector() */ //----------------------------------mathutils.Matrix() ----------------- //mat is a 1D array of floats - row[0][0], row[0][1], row[1][0], etc. @@ -123,24 +341,28 @@ return NULL; } - switch(PyTuple_GET_SIZE(args)) { + switch (PyTuple_GET_SIZE(args)) { case 0: return Matrix_CreatePyObject(NULL, 4, 4, Py_NEW, type); case 1: { - PyObject *arg= PyTuple_GET_ITEM(args, 0); + PyObject *arg = PyTuple_GET_ITEM(args, 0); + /* Input is now as a sequence of rows so length of sequence + * is the number of rows */ /* -1 is an error, size checks will accunt for this */ - const unsigned short row_size= PySequence_Size(arg); + const unsigned short num_row = PySequence_Size(arg); - if (row_size >= 2 && row_size <= 4) { - PyObject *item= PySequence_GetItem(arg, 0); - const unsigned short col_size= PySequence_Size(item); + if (num_row >= 2 && num_row <= 4) { + PyObject *item = PySequence_GetItem(arg, 0); + /* Since each item is a row, number of items is the + * same as the number of columns */ + const unsigned short num_col = PySequence_Size(item); Py_XDECREF(item); - if (col_size >= 2 && col_size <= 4) { + if (num_col >= 2 && num_col <= 4) { /* sane row & col size, new matrix and assign as slice */ - PyObject *matrix= Matrix_CreatePyObject(NULL, row_size, col_size, Py_NEW, type); + PyObject *matrix = Matrix_CreatePyObject(NULL, num_col, num_row, Py_NEW, type); if (Matrix_ass_slice((MatrixObject *)matrix, 0, INT_MAX, arg) == 0) { return matrix; } @@ -161,8 +383,8 @@ static PyObject *matrix__apply_to_copy(PyNoArgsFunction matrix_func, MatrixObject *self) { - PyObject *ret= Matrix_copy(self); - PyObject *ret_dummy= matrix_func(ret); + PyObject *ret = Matrix_copy(self); + PyObject *ret_dummy = matrix_func(ret); if (ret_dummy) { Py_DECREF(ret_dummy); return (PyObject *)ret; @@ -189,6 +411,34 @@ /*-----------------------CLASS-METHODS----------------------------*/ //mat is a 1D array of floats - row[0][0], row[0][1], row[1][0], etc. +PyDoc_STRVAR(C_Matrix_Identity_doc, +".. classmethod:: Identity(size)\n" +"\n" +" Create an identity matrix.\n" +"\n" +" :arg size: The size of the identity matrix to construct [2, 4].\n" +" :type size: int\n" +" :return: A new identity matrix.\n" +" :rtype: :class:`Matrix`\n" +); +static PyObject *C_Matrix_Identity(PyObject *cls, PyObject *args) +{ + int matSize; + + if (!PyArg_ParseTuple(args, "i:Matrix.Identity", &matSize)) { + return NULL; + } + + if (matSize < 2 || matSize > 4) { + PyErr_SetString(PyExc_RuntimeError, + "Matrix.Identity(): " + "size must be between 2 and 4"); + return NULL; + } + + return Matrix_CreatePyObject(NULL, matSize, matSize, Py_NEW, (PyTypeObject *)cls); +} + PyDoc_STRVAR(C_Matrix_Rotation_doc, ".. classmethod:: Rotation(angle, size, axis)\n" "\n" @@ -206,23 +456,22 @@ ); static PyObject *C_Matrix_Rotation(PyObject *cls, PyObject *args) { - PyObject *vec= NULL; - const char *axis= NULL; + PyObject *vec = NULL; + const char *axis = NULL; int matSize; double angle; /* use double because of precision problems at high values */ - float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; + float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f}; - if (!PyArg_ParseTuple(args, "di|O", &angle, &matSize, &vec)) { - PyErr_SetString(PyExc_TypeError, - "Matrix.Rotation(angle, size, axis): " - "expected float int and a string or vector"); + if (!PyArg_ParseTuple(args, "di|O:Matrix.Rotation", &angle, &matSize, &vec)) { return NULL; } if (vec && PyUnicode_Check(vec)) { - axis= _PyUnicode_AsString((PyObject *)vec); - if (axis==NULL || axis[0]=='\0' || axis[1]!='\0' || axis[0] < 'X' || axis[0] > 'Z') { + axis = _PyUnicode_AsString((PyObject *)vec); + if (axis == NULL || axis[0] == '\0' || axis[1] != '\0' || axis[0] < 'X' || axis[0] > 'Z') { PyErr_SetString(PyExc_ValueError, "Matrix.Rotation(): " "3rd argument axis value must be a 3D vector " @@ -231,11 +480,11 @@ } else { /* use the string */ - vec= NULL; + vec = NULL; } } - angle= angle_wrap_rad(angle); + angle = angle_wrap_rad(angle); if (matSize != 2 && matSize != 3 && matSize != 4) { PyErr_SetString(PyExc_ValueError, @@ -266,8 +515,8 @@ axis_angle_to_mat3((float (*)[3])mat, tvec, angle); } else if (matSize == 2) { - const float angle_cos= cosf(angle); - const float angle_sin= sinf(angle); + const float angle_cos = cosf(angle); + const float angle_sin = sinf(angle); //2D rotation matrix mat[0] = angle_cos; @@ -300,15 +549,12 @@ ); static PyObject *C_Matrix_Translation(PyObject *cls, PyObject *value) { - float mat[16], tvec[3]; + float mat[4][4]= MAT4_UNITY; - if (mathutils_array_parse(tvec, 3, 4, value, "mathutils.Matrix.Translation(vector), invalid vector arg") == -1) + if (mathutils_array_parse(mat[3], 3, 4, value, "mathutils.Matrix.Translation(vector), invalid vector arg") == -1) return NULL; - /* create a identity matrix and add translation */ - unit_m4((float(*)[4]) mat); - copy_v3_v3(mat + 12, tvec); /* 12, 13, 14 */ - return Matrix_CreatePyObject(mat, 4, 4, Py_NEW, (PyTypeObject *)cls); + return Matrix_CreatePyObject(&mat[0][0], 4, 4, Py_NEW, (PyTypeObject *)cls); } //----------------------------------mathutils.Matrix.Scale() ------------- //mat is a 1D array of floats - row[0][0], row[0][1], row[1][0], etc. @@ -328,13 +574,15 @@ ); static PyObject *C_Matrix_Scale(PyObject *cls, PyObject *args) { - PyObject *vec= NULL; + PyObject *vec = NULL; int vec_size; float tvec[3]; float factor; int matSize; - float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; + float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f}; if (!PyArg_ParseTuple(args, "fi|O:Matrix.Scale", &factor, &matSize, &vec)) { return NULL; @@ -346,8 +594,10 @@ return NULL; } if (vec) { - vec_size= (matSize == 2 ? 2 : 3); - if (mathutils_array_parse(tvec, vec_size, vec_size, vec, "Matrix.Scale(factor, size, axis), invalid 'axis' arg") == -1) { + vec_size = (matSize == 2 ? 2 : 3); + if (mathutils_array_parse(tvec, vec_size, vec_size, vec, + "Matrix.Scale(factor, size, axis), invalid 'axis' arg") == -1) + { return NULL; } } @@ -419,8 +669,10 @@ int matSize, x; float norm = 0.0f; - float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; + float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f}; if (!PyArg_ParseTuple(args, "Oi:Matrix.OrthoProjection", &axis, &matSize)) { return NULL; @@ -434,13 +686,13 @@ if (PyUnicode_Check(axis)) { //ortho projection onto cardinal plane Py_ssize_t plane_len; - const char *plane= _PyUnicode_AsStringAndSize(axis, &plane_len); + const char *plane = _PyUnicode_AsStringAndSize(axis, &plane_len); if (matSize == 2) { - if (plane_len == 1 && plane[0]=='X') { - mat[0]= 1.0f; + if (plane_len == 1 && plane[0] == 'X') { + mat[0] = 1.0f; } - else if (plane_len == 1 && plane[0]=='Y') { - mat[3]= 1.0f; + else if (plane_len == 1 && plane[0] == 'Y') { + mat[3] = 1.0f; } else { PyErr_Format(PyExc_ValueError, @@ -451,17 +703,17 @@ } } else { - if (plane_len == 2 && plane[0]=='X' && plane[1]=='Y') { - mat[0]= 1.0f; - mat[4]= 1.0f; + if (plane_len == 2 && plane[0] == 'X' && plane[1] == 'Y') { + mat[0] = 1.0f; + mat[4] = 1.0f; } - else if (plane_len == 2 && plane[0]=='X' && plane[1]=='Z') { - mat[0]= 1.0f; - mat[8]= 1.0f; + else if (plane_len == 2 && plane[0] == 'X' && plane[1] == 'Z') { + mat[0] = 1.0f; + mat[8] = 1.0f; } - else if (plane_len == 2 && plane[0]=='Y' && plane[1]=='Z') { - mat[4]= 1.0f; - mat[8]= 1.0f; + else if (plane_len == 2 && plane[0] == 'Y' && plane[1] == 'Z') { + mat[4] = 1.0f; + mat[8] = 1.0f; } else { PyErr_Format(PyExc_ValueError, @@ -475,7 +727,7 @@ else { //arbitrary plane - int vec_size= (matSize == 2 ? 2 : 3); + int vec_size = (matSize == 2 ? 2 : 3); float tvec[4]; if (mathutils_array_parse(tvec, vec_size, vec_size, axis, @@ -494,19 +746,19 @@ } if (matSize == 2) { mat[0] = 1 - (tvec[0] * tvec[0]); - mat[1] = -(tvec[0] * tvec[1]); - mat[2] = -(tvec[0] * tvec[1]); + mat[1] = - (tvec[0] * tvec[1]); + mat[2] = - (tvec[0] * tvec[1]); mat[3] = 1 - (tvec[1] * tvec[1]); } else if (matSize > 2) { mat[0] = 1 - (tvec[0] * tvec[0]); - mat[1] = -(tvec[0] * tvec[1]); - mat[2] = -(tvec[0] * tvec[2]); - mat[3] = -(tvec[0] * tvec[1]); + mat[1] = - (tvec[0] * tvec[1]); + mat[2] = - (tvec[0] * tvec[2]); + mat[3] = - (tvec[0] * tvec[1]); mat[4] = 1 - (tvec[1] * tvec[1]); - mat[5] = -(tvec[1] * tvec[2]); - mat[6] = -(tvec[0] * tvec[2]); - mat[7] = -(tvec[1] * tvec[2]); + mat[5] = - (tvec[1] * tvec[2]); + mat[6] = - (tvec[0] * tvec[2]); + mat[7] = - (tvec[1] * tvec[2]); mat[8] = 1 - (tvec[2] * tvec[2]); } } @@ -538,8 +790,10 @@ int matSize; const char *plane; PyObject *fac; - float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; + float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f}; if (!PyArg_ParseTuple(args, "siO:Matrix.Shear", &plane, &matSize, &fac)) { return NULL; @@ -552,9 +806,9 @@ } if (matSize == 2) { - float const factor= PyFloat_AsDouble(fac); + float const factor = PyFloat_AsDouble(fac); - if (factor==-1.0f && PyErr_Occurred()) { + if (factor == -1.0f && PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "Matrix.Shear(): " "the factor to be a float"); @@ -620,27 +874,25 @@ void matrix_as_3x3(float mat[3][3], MatrixObject *self) { - copy_v3_v3(mat[0], self->matrix[0]); - copy_v3_v3(mat[1], self->matrix[1]); - copy_v3_v3(mat[2], self->matrix[2]); + copy_v3_v3(mat[0], MATRIX_COL_PTR(self, 0)); + copy_v3_v3(mat[1], MATRIX_COL_PTR(self, 1)); + copy_v3_v3(mat[2], MATRIX_COL_PTR(self, 2)); } /* assumes rowsize == colsize is checked and the read callback has run */ static float matrix_determinant_internal(MatrixObject *self) { - if (self->row_size == 2) { - return determinant_m2(self->matrix[0][0], self->matrix[0][1], - self->matrix[1][0], self->matrix[1][1]); - } - else if (self->row_size == 3) { - return determinant_m3(self->matrix[0][0], self->matrix[0][1], - self->matrix[0][2], self->matrix[1][0], - self->matrix[1][1], self->matrix[1][2], - self->matrix[2][0], self->matrix[2][1], - self->matrix[2][2]); + if (self->num_col == 2) { + return determinant_m2(MATRIX_ITEM(self, 0, 0), MATRIX_ITEM(self, 0, 1), + MATRIX_ITEM(self, 1, 0), MATRIX_ITEM(self, 1, 1)); + } + else if (self->num_col == 3) { + return determinant_m3(MATRIX_ITEM(self, 0, 0), MATRIX_ITEM(self, 0, 1), MATRIX_ITEM(self, 0, 2), + MATRIX_ITEM(self, 1, 0), MATRIX_ITEM(self, 1, 1), MATRIX_ITEM(self, 1, 2), + MATRIX_ITEM(self, 2, 0), MATRIX_ITEM(self, 2, 1), MATRIX_ITEM(self, 2, 2)); } else { - return determinant_m4((float (*)[4])self->contigPtr); + return determinant_m4((float (*)[4])self->matrix); } } @@ -661,18 +913,18 @@ if (BaseMath_ReadCallback(self) == -1) return NULL; - /*must be 3-4 cols, 3-4 rows, square matrix*/ - if ((self->col_size < 3) || (self->row_size < 3) || (self->col_size != self->row_size)) { + /* must be 3-4 cols, 3-4 rows, square matrix */ + if ((self->num_row < 3) || (self->num_col < 3) || (self->num_row != self->num_col)) { PyErr_SetString(PyExc_ValueError, "Matrix.to_quat(): " "inappropriate matrix size - expects 3x3 or 4x4 matrix"); return NULL; } - if (self->col_size == 3) { - mat3_to_quat(quat, (float (*)[3])self->contigPtr); + if (self->num_row == 3) { + mat3_to_quat(quat, (float (*)[3])self->matrix); } else { - mat4_to_quat(quat, (float (*)[4])self->contigPtr); + mat4_to_quat(quat, (float (*)[4])self->matrix); } return Quaternion_CreatePyObject(quat, Py_NEW, NULL); @@ -697,8 +949,8 @@ ); static PyObject *Matrix_to_euler(MatrixObject *self, PyObject *args) { - const char *order_str= NULL; - short order= EULER_ORDER_XYZ; + const char *order_str = NULL; + short order = EULER_ORDER_XYZ; float eul[3], eul_compatf[3]; EulerObject *eul_compat = NULL; @@ -718,13 +970,13 @@ copy_v3_v3(eul_compatf, eul_compat->eul); } - /*must be 3-4 cols, 3-4 rows, square matrix*/ - if (self->col_size ==3 && self->row_size ==3) { - mat= (float (*)[3])self->contigPtr; - } - else if (self->col_size ==4 && self->row_size ==4) { - copy_m3_m4(tmat, (float (*)[4])self->contigPtr); - mat= tmat; + /*must be 3-4 cols, 3-4 rows, square matrix */ + if (self->num_row ==3 && self->num_col ==3) { + mat = (float (*)[3])self->matrix; + } + else if (self->num_row ==4 && self->num_col ==4) { + copy_m3_m4(tmat, (float (*)[4])self->matrix); + mat = tmat; } else { PyErr_SetString(PyExc_ValueError, @@ -734,7 +986,7 @@ } if (order_str) { - order= euler_order_from_string(order_str, "Matrix.to_euler()"); + order = euler_order_from_string(order_str, "Matrix.to_euler()"); if (order == -1) return NULL; @@ -759,9 +1011,10 @@ ); static PyObject *Matrix_resize_4x4(MatrixObject *self) { - int x, first_row_elem, curr_pos, new_pos, blank_columns, blank_rows, index; + float mat[4][4] = MAT4_UNITY; + int col; - if (self->wrapped==Py_WRAP) { + if (self->wrapped == Py_WRAP) { PyErr_SetString(PyExc_TypeError, "Matrix.resize_4x4(): " "cannot resize wrapped data - make a copy and resize that"); @@ -774,43 +1027,22 @@ return NULL; } - self->contigPtr = PyMem_Realloc(self->contigPtr, (sizeof(float) * 16)); - if (self->contigPtr == NULL) { + self->matrix = PyMem_Realloc(self->matrix, (sizeof(float) * 16)); + if (self->matrix == NULL) { PyErr_SetString(PyExc_MemoryError, "Matrix.resize_4x4(): " "problem allocating pointer space"); return NULL; } - /*set row pointers*/ - for (x = 0; x < 4; x++) { - self->matrix[x] = self->contigPtr + (x * 4); - } - /*move data to new spot in array + clean*/ - for (blank_rows = (4 - self->row_size); blank_rows > 0; blank_rows--) { - for (x = 0; x < 4; x++) { - index = (4 * (self->row_size + (blank_rows - 1))) + x; - if (index == 10 || index == 15) { - self->contigPtr[index] = 1.0f; - } - else { - self->contigPtr[index] = 0.0f; - } - } - } - for (x = 1; x <= self->row_size; x++) { - first_row_elem = (self->col_size * (self->row_size - x)); - curr_pos = (first_row_elem + (self->col_size -1)); - new_pos = (4 * (self->row_size - x)) + (curr_pos - first_row_elem); - for (blank_columns = (4 - self->col_size); blank_columns > 0; blank_columns--) { - self->contigPtr[new_pos + blank_columns] = 0.0f; - } - for ( ; curr_pos >= first_row_elem; curr_pos--) { - self->contigPtr[new_pos] = self->contigPtr[curr_pos]; - new_pos--; - } + + for (col = 0; col < self->num_col; col++) { + memcpy(mat[col], MATRIX_COL_PTR(self, col), self->num_row * sizeof(float)); } - self->row_size = 4; - self->col_size = 4; + + copy_m4_m4((float (*)[4])self->matrix, (float (*)[4])mat); + + self->num_col = 4; + self->num_row = 4; Py_RETURN_NONE; } @@ -828,12 +1060,12 @@ if (BaseMath_ReadCallback(self) == -1) return NULL; - if (self->col_size==4 && self->row_size==4) { - return Matrix_CreatePyObject(self->contigPtr, 4, 4, Py_NEW, Py_TYPE(self)); + if (self->num_row == 4 && self->num_col == 4) { + return Matrix_CreatePyObject(self->matrix, 4, 4, Py_NEW, Py_TYPE(self)); } - else if (self->col_size==3 && self->row_size==3) { + else if (self->num_row == 3 && self->num_col == 3) { float mat[4][4]; - copy_m4_m3(mat, (float (*)[3])self->contigPtr); + copy_m4_m3(mat, (float (*)[3])self->matrix); return Matrix_CreatePyObject((float *)mat, 4, 4, Py_NEW, Py_TYPE(self)); } /* TODO, 2x2 matrix */ @@ -859,7 +1091,7 @@ if (BaseMath_ReadCallback(self) == -1) return NULL; - if ((self->col_size < 3) || (self->row_size < 3)) { + if ((self->num_row < 3) || (self->num_col < 3)) { PyErr_SetString(PyExc_TypeError, "Matrix.to_3x3(): inappropriate matrix size"); return NULL; @@ -883,14 +1115,14 @@ if (BaseMath_ReadCallback(self) == -1) return NULL; - if ((self->col_size < 3) || self->row_size < 4) { + if ((self->num_row < 3) || self->num_col < 4) { PyErr_SetString(PyExc_TypeError, "Matrix.to_translation(): " "inappropriate matrix size"); return NULL; } - return Vector_CreatePyObject(self->matrix[3], 3, Py_NEW, NULL); + return Vector_CreatePyObject(MATRIX_COL_PTR(self, 3), 3, Py_NEW, NULL); } PyDoc_STRVAR(Matrix_to_scale_doc, @@ -912,8 +1144,8 @@ if (BaseMath_ReadCallback(self) == -1) return NULL; - /*must be 3-4 cols, 3-4 rows, square matrix*/ - if ((self->col_size < 3) || (self->row_size < 3)) { + /*must be 3-4 cols, 3-4 rows, square matrix */ + if ((self->num_row < 3) || (self->num_col < 3)) { PyErr_SetString(PyExc_TypeError, "Matrix.to_scale(): " "inappropriate matrix size, 3x3 minimum size"); @@ -934,7 +1166,7 @@ "\n" " Set the matrix to its inverse.\n" "\n" -" .. note:: :exc:`ValueError` exception is raised.\n" +" .. note:: When the matrix cant be inverted a :exc:`ValueError` exception is raised.\n" "\n" " .. seealso:: \n" ); @@ -951,38 +1183,38 @@ if (BaseMath_ReadCallback(self) == -1) return NULL; - if (self->row_size != self->col_size) { + if (self->num_col != self->num_row) { PyErr_SetString(PyExc_TypeError, "Matrix.invert(ed): " "only square matrices are supported"); return NULL; } - /*calculate the determinant*/ + /* calculate the determinant */ det = matrix_determinant_internal(self); if (det != 0) { - /*calculate the classical adjoint*/ - if (self->row_size == 2) { - mat[0] = self->matrix[1][1]; - mat[1] = -self->matrix[0][1]; - mat[2] = -self->matrix[1][0]; - mat[3] = self->matrix[0][0]; + /* calculate the classical adjoint */ + if (self->num_col == 2) { + mat[0] = MATRIX_ITEM(self, 1, 1); + mat[1] = -MATRIX_ITEM(self, 0, 1); + mat[2] = -MATRIX_ITEM(self, 1, 0); + mat[3] = MATRIX_ITEM(self, 0, 0); } - else if (self->row_size == 3) { - adjoint_m3_m3((float (*)[3]) mat,(float (*)[3])self->contigPtr); + else if (self->num_col == 3) { + adjoint_m3_m3((float (*)[3]) mat,(float (*)[3])self->matrix); } - else if (self->row_size == 4) { - adjoint_m4_m4((float (*)[4]) mat, (float (*)[4])self->contigPtr); + else if (self->num_col == 4) { + adjoint_m4_m4((float (*)[4]) mat, (float (*)[4])self->matrix); } - /*divide by determinate*/ - for (x = 0; x < (self->row_size * self->col_size); x++) { + /* divide by determinate */ + for (x = 0; x < (self->num_col * self->num_row); x++) { mat[x] /= det; } - /*set values*/ - for (x = 0; x < self->row_size; x++) { - for (y = 0; y < self->col_size; y++) { - self->matrix[x][y] = mat[z]; + /* set values */ + for (x = 0; x < self->num_col; x++) { + for (y = 0; y < self->num_row; y++) { + MATRIX_ITEM(self, y, x) = mat[z]; z++; } } @@ -1008,7 +1240,7 @@ " :return: the inverted matrix.\n" " :rtype: :class:`Matrix`\n" "\n" -" .. note:: :exc:`ValueError` exception is raised.\n" +" .. note:: When the matrix cant be inverted a :exc:`ValueError` exception is raised.\n" ); static PyObject *Matrix_inverted(MatrixObject *self) { @@ -1035,7 +1267,7 @@ if (mathutils_any_to_rotmat(other_rmat, value, "matrix.rotate(value)") == -1) return NULL; - if (self->col_size != 3 || self->row_size != 3) { + if (self->num_row != 3 || self->num_col != 3) { PyErr_SetString(PyExc_TypeError, "Matrix.rotate(): " "must have 3x3 dimensions"); @@ -1045,7 +1277,7 @@ matrix_as_3x3(self_rmat, self); mul_m3_m3m3(rmat, other_rmat, self_rmat); - copy_m3_m3((float (*)[3])(self->contigPtr), rmat); + copy_m3_m3((float (*)[3])(self->matrix), rmat); (void)BaseMath_WriteCallback(self); Py_RETURN_NONE; @@ -1068,7 +1300,7 @@ float quat[4]; float size[3]; - if (self->col_size != 4 || self->row_size != 4) { + if (self->num_row != 4 || self->num_col != 4) { PyErr_SetString(PyExc_TypeError, "Matrix.decompose(): " "inappropriate matrix size - expects 4x4 matrix"); @@ -1078,10 +1310,10 @@ if (BaseMath_ReadCallback(self) == -1) return NULL; - mat4_to_loc_rot_size(loc, rot, size, (float (*)[4])self->contigPtr); + mat4_to_loc_rot_size(loc, rot, size, (float (*)[4])self->matrix); mat3_to_quat(quat, rot); - ret= PyTuple_New(3); + ret = PyTuple_New(3); PyTuple_SET_ITEM(ret, 0, Vector_CreatePyObject(loc, 3, Py_NEW, NULL)); PyTuple_SET_ITEM(ret, 1, Quaternion_CreatePyObject(quat, Py_NEW, NULL)); PyTuple_SET_ITEM(ret, 2, Vector_CreatePyObject(size, 3, Py_NEW, NULL)); @@ -1106,12 +1338,12 @@ static PyObject *Matrix_lerp(MatrixObject *self, PyObject *args) { MatrixObject *mat2 = NULL; - float fac, mat[MATRIX_MAX_DIM*MATRIX_MAX_DIM]; + float fac, mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM]; if (!PyArg_ParseTuple(args, "O!f:lerp", &matrix_Type, &mat2, &fac)) return NULL; - if (self->row_size != mat2->row_size || self->col_size != mat2->col_size) { + if (self->num_col != mat2->num_col || self->num_row != mat2->num_row) { PyErr_SetString(PyExc_ValueError, "Matrix.lerp(): " "expects both matrix objects of the same dimensions"); @@ -1122,11 +1354,11 @@ return NULL; /* TODO, different sized matrix */ - if (self->row_size==4 && self->col_size==4) { - blend_m4_m4m4((float (*)[4])mat, (float (*)[4])self->contigPtr, (float (*)[4])mat2->contigPtr, fac); + if (self->num_col == 4 && self->num_row == 4) { + blend_m4_m4m4((float (*)[4])mat, (float (*)[4])self->matrix, (float (*)[4])mat2->matrix, fac); } - else if (self->row_size==3 && self->col_size==3) { - blend_m3_m3m3((float (*)[3])mat, (float (*)[3])self->contigPtr, (float (*)[3])mat2->contigPtr, fac); + else if (self->num_col == 3 && self->num_row == 3) { + blend_m3_m3m3((float (*)[3])mat, (float (*)[3])self->matrix, (float (*)[3])mat2->matrix, fac); } else { PyErr_SetString(PyExc_ValueError, @@ -1135,7 +1367,7 @@ return NULL; } - return Matrix_CreatePyObject(mat, self->row_size, self->col_size, Py_NEW, Py_TYPE(self)); + return Matrix_CreatePyObject(mat, self->num_col, self->num_row, Py_NEW, Py_TYPE(self)); } /*---------------------------matrix.determinant() ----------------*/ @@ -1154,7 +1386,7 @@ if (BaseMath_ReadCallback(self) == -1) return NULL; - if (self->row_size != self->col_size) { + if (self->num_col != self->num_row) { PyErr_SetString(PyExc_TypeError, "Matrix.determinant(): " "only square matrices are supported"); @@ -1173,28 +1405,26 @@ ); static PyObject *Matrix_transpose(MatrixObject *self) { - float t = 0.0f; - if (BaseMath_ReadCallback(self) == -1) return NULL; - if (self->row_size != self->col_size) { + if (self->num_col != self->num_row) { PyErr_SetString(PyExc_TypeError, "Matrix.transpose(d): " "only square matrices are supported"); return NULL; } - if (self->row_size == 2) { - t = self->matrix[1][0]; - self->matrix[1][0] = self->matrix[0][1]; - self->matrix[0][1] = t; + if (self->num_col == 2) { + const float t = MATRIX_ITEM(self, 1, 0); + MATRIX_ITEM(self, 1, 0) = MATRIX_ITEM(self, 0, 1); + MATRIX_ITEM(self, 0, 1) = t; } - else if (self->row_size == 3) { - transpose_m3((float (*)[3])self->contigPtr); + else if (self->num_col == 3) { + transpose_m3((float (*)[3])self->matrix); } else { - transpose_m4((float (*)[4])self->contigPtr); + transpose_m4((float (*)[4])self->matrix); } (void)BaseMath_WriteCallback(self); @@ -1225,7 +1455,7 @@ ); static PyObject *Matrix_zero(MatrixObject *self) { - fill_vn_fl(self->contigPtr, self->row_size * self->col_size, 0.0f); + fill_vn_fl(self->matrix, self->num_col * self->num_row, 0.0f); if (BaseMath_WriteCallback(self) == -1) return NULL; @@ -1248,24 +1478,24 @@ if (BaseMath_ReadCallback(self) == -1) return NULL; - if (self->row_size != self->col_size) { + if (self->num_col != self->num_row) { PyErr_SetString(PyExc_TypeError, "Matrix.identity(): " "only square matrices are supported"); return NULL; } - if (self->row_size == 2) { - self->matrix[0][0] = 1.0f; - self->matrix[0][1] = 0.0f; - self->matrix[1][0] = 0.0f; - self->matrix[1][1] = 1.0f; + if (self->num_col == 2) { + MATRIX_ITEM(self, 0, 0) = 1.0f; + MATRIX_ITEM(self, 0, 1) = 0.0f; + MATRIX_ITEM(self, 1, 0) = 0.0f; + MATRIX_ITEM(self, 1, 1) = 1.0f; } - else if (self->row_size == 3) { - unit_m3((float (*)[3])self->contigPtr); + else if (self->num_col == 3) { + unit_m3((float (*)[3])self->matrix); } else { - unit_m4((float (*)[4])self->contigPtr); + unit_m4((float (*)[4])self->matrix); } if (BaseMath_WriteCallback(self) == -1) @@ -1288,26 +1518,26 @@ if (BaseMath_ReadCallback(self) == -1) return NULL; - return Matrix_CreatePyObject((float (*))self->contigPtr, self->row_size, self->col_size, Py_NEW, Py_TYPE(self)); + return Matrix_CreatePyObject((float (*))self->matrix, self->num_col, self->num_row, Py_NEW, Py_TYPE(self)); } /*----------------------------print object (internal)-------------*/ -/*print the object to screen*/ +/* print the object to screen */ static PyObject *Matrix_repr(MatrixObject *self) { - int x, y; - PyObject *rows[MATRIX_MAX_DIM]= {NULL}; + int col, row; + PyObject *rows[MATRIX_MAX_DIM] = {NULL}; if (BaseMath_ReadCallback(self) == -1) return NULL; - for (x = 0; x < self->row_size; x++) { - rows[x]= PyTuple_New(self->col_size); - for (y = 0; y < self->col_size; y++) { - PyTuple_SET_ITEM(rows[x], y, PyFloat_FromDouble(self->matrix[x][y])); + for (row = 0; row < self->num_row; row++) { + rows[row] = PyTuple_New(self->num_col); + for (col = 0; col < self->num_col; col++) { + PyTuple_SET_ITEM(rows[row], col, PyFloat_FromDouble(MATRIX_ITEM(self, row, col))); } } - switch(self->row_size) { + switch (self->num_row) { case 2: return PyUnicode_FromFormat("Matrix((%R,\n" " %R))", rows[0], rows[1]); @@ -1325,21 +1555,57 @@ return NULL; } -static PyObject* Matrix_richcmpr(PyObject *a, PyObject *b, int op) +static PyObject *Matrix_str(MatrixObject *self) +{ + DynStr *ds; + + int maxsize[MATRIX_MAX_DIM]; + int row, col; + + char dummy_buf[64]; + + if (BaseMath_ReadCallback(self) == -1) + return NULL; + + ds = BLI_dynstr_new(); + + /* First determine the maximum width for each column */ + for (col = 0; col < self->num_col; col++) { + maxsize[col] = 0; + for (row = 0; row < self->num_row; row++) { + int size = BLI_snprintf(dummy_buf, sizeof(dummy_buf), "%.4f", MATRIX_ITEM(self, row, col)); + maxsize[col] = MAX2(maxsize[col], size); + } + } + + /* Now write the unicode string to be printed */ + BLI_dynstr_appendf(ds, "num_row, self->num_col); + for (row = 0; row < self->num_row; row++) { + for (col = 0; col < self->num_col; col++) { + BLI_dynstr_appendf(ds, col ? ", %*.4f" : "%*.4f", maxsize[col], MATRIX_ITEM(self, row, col)); + } + BLI_dynstr_append(ds, row + 1 != self->num_row ? ")\n (" : ")"); + } + BLI_dynstr_append(ds, ">"); + + return mathutils_dynstr_to_py(ds); /* frees ds */ +} + +static PyObject *Matrix_richcmpr(PyObject *a, PyObject *b, int op) { PyObject *res; - int ok= -1; /* zero is true */ + int ok = -1; /* zero is true */ if (MatrixObject_Check(a) && MatrixObject_Check(b)) { - MatrixObject *matA= (MatrixObject*)a; - MatrixObject *matB= (MatrixObject*)b; + MatrixObject *matA = (MatrixObject *)a; + MatrixObject *matB = (MatrixObject *)b; if (BaseMath_ReadCallback(matA) == -1 || BaseMath_ReadCallback(matB) == -1) return NULL; - ok= ( (matA->col_size == matB->col_size) && - (matA->row_size == matB->row_size) && - EXPP_VectorsAreEqual(matA->contigPtr, matB->contigPtr, (matA->row_size * matA->col_size), 1) + ok = ( (matA->num_row == matB->num_row) && + (matA->num_col == matB->num_col) && + EXPP_VectorsAreEqual(matA->matrix, matB->matrix, (matA->num_col * matA->num_row), 1) ) ? 0 : -1; } @@ -1366,52 +1632,97 @@ /*---------------------SEQUENCE PROTOCOLS------------------------ ----------------------------len(object)------------------------ - sequence length*/ + sequence length */ static int Matrix_len(MatrixObject *self) { - return (self->row_size); + return (self->num_row); } /*----------------------------object[]--------------------------- sequence accessor (get) - the wrapped vector gives direct access to the matrix data*/ -static PyObject *Matrix_item(MatrixObject *self, int i) + the wrapped vector gives direct access to the matrix data */ +static PyObject *Matrix_item_row(MatrixObject *self, int row) +{ + if (BaseMath_ReadCallback(self) == -1) + return NULL; + + if (row < 0 || row >= self->num_row) { + PyErr_SetString(PyExc_IndexError, + "matrix[attribute]: " + "array index out of range"); + return NULL; + } + return Vector_CreatePyObject_cb((PyObject *)self, self->num_col, mathutils_matrix_row_cb_index, row); +} +/* same but column access */ +static PyObject *Matrix_item_col(MatrixObject *self, int col) { if (BaseMath_ReadCallback(self) == -1) return NULL; - if (i < 0 || i >= self->row_size) { + if (col < 0 || col >= self->num_col) { PyErr_SetString(PyExc_IndexError, "matrix[attribute]: " "array index out of range"); return NULL; } - return Vector_CreatePyObject_cb((PyObject *)self, self->col_size, mathutils_matrix_vector_cb_index, i); + return Vector_CreatePyObject_cb((PyObject *)self, self->num_row, mathutils_matrix_col_cb_index, col); } + /*----------------------------object[]------------------------- sequence accessor (set) */ -static int Matrix_ass_item(MatrixObject *self, int i, PyObject *value) +static int Matrix_ass_item_row(MatrixObject *self, int row, PyObject *value) +{ + int col; + float vec[4]; + if (BaseMath_ReadCallback(self) == -1) + return -1; + + if (row >= self->num_row || row < 0) { + PyErr_SetString(PyExc_IndexError, + "matrix[attribute] = x: bad row"); + return -1; + } + + if (mathutils_array_parse(vec, self->num_col, self->num_col, value, "matrix[i] = value assignment") < 0) { + return -1; + } + + /* Since we are assigning a row we cannot memcpy */ + for (col = 0; col < self->num_col; col++) { + MATRIX_ITEM(self, row, col) = vec[col]; + } + + (void)BaseMath_WriteCallback(self); + return 0; +} +static int Matrix_ass_item_col(MatrixObject *self, int col, PyObject *value) { + int row; float vec[4]; if (BaseMath_ReadCallback(self) == -1) return -1; - if (i >= self->row_size || i < 0) { + if (col >= self->num_col || col < 0) { PyErr_SetString(PyExc_IndexError, - "matrix[attribute] = x: bad column"); + "matrix[attribute] = x: bad col"); return -1; } - if (mathutils_array_parse(vec, self->col_size, self->col_size, value, "matrix[i] = value assignment") < 0) { + if (mathutils_array_parse(vec, self->num_row, self->num_row, value, "matrix[i] = value assignment") < 0) { return -1; } - memcpy(self->matrix[i], vec, self->col_size *sizeof(float)); + /* Since we are assigning a row we cannot memcpy */ + for (row = 0; row < self->num_row; row++) { + MATRIX_ITEM(self, row, col) = vec[row]; + } (void)BaseMath_WriteCallback(self); return 0; } + /*----------------------------object[z:y]------------------------ sequence slice (get)*/ static PyObject *Matrix_slice(MatrixObject *self, int begin, int end) @@ -1423,14 +1734,14 @@ if (BaseMath_ReadCallback(self) == -1) return NULL; - CLAMP(begin, 0, self->row_size); - CLAMP(end, 0, self->row_size); - begin= MIN2(begin, end); + CLAMP(begin, 0, self->num_row); + CLAMP(end, 0, self->num_row); + begin = MIN2(begin, end); - tuple= PyTuple_New(end - begin); - for (count= begin; count < end; count++) { + tuple = PyTuple_New(end - begin); + for (count = begin; count < end; count++) { PyTuple_SET_ITEM(tuple, count - begin, - Vector_CreatePyObject_cb((PyObject *)self, self->col_size, mathutils_matrix_vector_cb_index, count)); + Vector_CreatePyObject_cb((PyObject *)self, self->num_col, mathutils_matrix_row_cb_index, count)); } @@ -1440,24 +1751,25 @@ sequence slice (set)*/ static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *value) { - PyObject *value_fast= NULL; + PyObject *value_fast = NULL; if (BaseMath_ReadCallback(self) == -1) return -1; - CLAMP(begin, 0, self->row_size); - CLAMP(end, 0, self->row_size); + CLAMP(begin, 0, self->num_row); + CLAMP(end, 0, self->num_row); begin = MIN2(begin, end); /* non list/tuple cases */ - if (!(value_fast=PySequence_Fast(value, "matrix[begin:end] = value"))) { + if (!(value_fast = PySequence_Fast(value, "matrix[begin:end] = value"))) { /* PySequence_Fast sets the error */ return -1; } else { - const int size= end - begin; - int i; + const int size = end - begin; + int row, col; float mat[16]; + float vec[4]; if (PySequence_Fast_GET_SIZE(value_fast) != size) { Py_DECREF(value_fast); @@ -1467,22 +1779,28 @@ return -1; } - /*parse sub items*/ - for (i = 0; i < size; i++) { - /*parse each sub sequence*/ - PyObject *item= PySequence_Fast_GET_ITEM(value_fast, i); + memcpy(mat, self->matrix, self->num_col * self->num_row * sizeof(float)); - if (mathutils_array_parse(&mat[i * self->col_size], self->col_size, self->col_size, item, + /* parse sub items */ + for (row = begin; row < end; row++) { + /* parse each sub sequence */ + PyObject *item = PySequence_Fast_GET_ITEM(value_fast, row - begin); + + if (mathutils_array_parse(vec, self->num_col, self->num_col, item, "matrix[begin:end] = value assignment") < 0) { return -1; } + + for (col = 0; col < self->num_col; col++) { + mat[col * self->num_row + row] = vec[col]; + } } Py_DECREF(value_fast); /*parsed well - now set in matrix*/ - memcpy(self->contigPtr + (begin * self->col_size), mat, sizeof(float) * (size * self->col_size)); + memcpy(self->matrix, mat, self->num_col * self->num_row * sizeof(float)); (void)BaseMath_WriteCallback(self); return 0; @@ -1495,8 +1813,8 @@ float mat[16]; MatrixObject *mat1 = NULL, *mat2 = NULL; - mat1 = (MatrixObject*)m1; - mat2 = (MatrixObject*)m2; + mat1 = (MatrixObject *)m1; + mat2 = (MatrixObject *)m2; if (!MatrixObject_Check(m1) || !MatrixObject_Check(m2)) { PyErr_Format(PyExc_TypeError, @@ -1509,16 +1827,16 @@ if (BaseMath_ReadCallback(mat1) == -1 || BaseMath_ReadCallback(mat2) == -1) return NULL; - if (mat1->row_size != mat2->row_size || mat1->col_size != mat2->col_size) { + if (mat1->num_col != mat2->num_col || mat1->num_row != mat2->num_row) { PyErr_SetString(PyExc_TypeError, "Matrix addition: " "matrices must have the same dimensions for this operation"); return NULL; } - add_vn_vnvn(mat, mat1->contigPtr, mat2->contigPtr, mat1->row_size * mat1->col_size); + add_vn_vnvn(mat, mat1->matrix, mat2->matrix, mat1->num_col * mat1->num_row); - return Matrix_CreatePyObject(mat, mat1->row_size, mat1->col_size, Py_NEW, Py_TYPE(mat1)); + return Matrix_CreatePyObject(mat, mat1->num_col, mat1->num_row, Py_NEW, Py_TYPE(mat1)); } /*------------------------obj - obj------------------------------ subtraction*/ @@ -1527,8 +1845,8 @@ float mat[16]; MatrixObject *mat1 = NULL, *mat2 = NULL; - mat1 = (MatrixObject*)m1; - mat2 = (MatrixObject*)m2; + mat1 = (MatrixObject *)m1; + mat2 = (MatrixObject *)m2; if (!MatrixObject_Check(m1) || !MatrixObject_Check(m2)) { PyErr_Format(PyExc_TypeError, @@ -1542,74 +1860,82 @@ if (BaseMath_ReadCallback(mat1) == -1 || BaseMath_ReadCallback(mat2) == -1) return NULL; - if (mat1->row_size != mat2->row_size || mat1->col_size != mat2->col_size) { + if (mat1->num_col != mat2->num_col || mat1->num_row != mat2->num_row) { PyErr_SetString(PyExc_TypeError, "Matrix addition: " "matrices must have the same dimensions for this operation"); return NULL; } - sub_vn_vnvn(mat, mat1->contigPtr, mat2->contigPtr, mat1->row_size * mat1->col_size); + sub_vn_vnvn(mat, mat1->matrix, mat2->matrix, mat1->num_col * mat1->num_row); - return Matrix_CreatePyObject(mat, mat1->row_size, mat1->col_size, Py_NEW, Py_TYPE(mat1)); + return Matrix_CreatePyObject(mat, mat1->num_col, mat1->num_row, Py_NEW, Py_TYPE(mat1)); } /*------------------------obj * obj------------------------------ mulplication*/ static PyObject *matrix_mul_float(MatrixObject *mat, const float scalar) { float tmat[16]; - mul_vn_vn_fl(tmat, mat->contigPtr, mat->row_size * mat->col_size, scalar); - return Matrix_CreatePyObject(tmat, mat->row_size, mat->col_size, Py_NEW, Py_TYPE(mat)); + mul_vn_vn_fl(tmat, mat->matrix, mat->num_col * mat->num_row, scalar); + return Matrix_CreatePyObject(tmat, mat->num_col, mat->num_row, Py_NEW, Py_TYPE(mat)); } static PyObject *Matrix_mul(PyObject *m1, PyObject *m2) { float scalar; + int vec_size; MatrixObject *mat1 = NULL, *mat2 = NULL; if (MatrixObject_Check(m1)) { - mat1 = (MatrixObject*)m1; + mat1 = (MatrixObject *)m1; if (BaseMath_ReadCallback(mat1) == -1) return NULL; } if (MatrixObject_Check(m2)) { - mat2 = (MatrixObject*)m2; + mat2 = (MatrixObject *)m2; if (BaseMath_ReadCallback(mat2) == -1) return NULL; } if (mat1 && mat2) { - /*MATRIX * MATRIX*/ - float mat[16]= {0.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f}; - double dot = 0.0f; - int x, y, z; - - for (x = 0; x < mat2->row_size; x++) { - for (y = 0; y < mat1->col_size; y++) { - for (z = 0; z < mat1->row_size; z++) { - dot += (mat1->matrix[z][y] * mat2->matrix[x][z]); + /* MATRIX * MATRIX */ + float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f}; + + int col, row, item; + + if (mat1->num_col != mat2->num_row) { + PyErr_SetString(PyExc_ValueError, + "matrix1 * matrix2: matrix1 number of columns " + "and the matrix2 number of rows must be the same"); + return NULL; + } + + for (col = 0; col < mat2->num_col; col++) { + for (row = 0; row < mat1->num_row; row++) { + double dot = 0.0f; + for (item = 0; item < mat1->num_col; item++) { + dot += MATRIX_ITEM(mat1, row, item) * MATRIX_ITEM(mat2, item, col); } - mat[((x * mat1->col_size) + y)] = (float)dot; - dot = 0.0f; + mat[(col * mat1->num_row) + row] = (float)dot; } } - return Matrix_CreatePyObject(mat, mat2->row_size, mat1->col_size, Py_NEW, Py_TYPE(mat1)); + return Matrix_CreatePyObject(mat, mat2->num_col, mat1->num_row, Py_NEW, Py_TYPE(mat1)); } else if (mat2) { /*FLOAT/INT * MATRIX */ - if (((scalar= PyFloat_AsDouble(m1)) == -1.0f && PyErr_Occurred())==0) { + if (((scalar = PyFloat_AsDouble(m1)) == -1.0f && PyErr_Occurred()) == 0) { return matrix_mul_float(mat2, scalar); } } else if (mat1) { - /*VEC * MATRIX */ + /* MATRIX * VECTOR */ if (VectorObject_Check(m2)) { - VectorObject *vec2= (VectorObject *)m2; + VectorObject *vec2 = (VectorObject *)m2; float tvec[4]; if (BaseMath_ReadCallback(vec2) == -1) return NULL; @@ -1617,10 +1943,17 @@ return NULL; } - return Vector_CreatePyObject(tvec, vec2->size, Py_NEW, Py_TYPE(m2)); + if (mat1->num_col == 4 && vec2->size == 3) { + vec_size = 3; + } + else { + vec_size = mat1->num_row; + } + + return Vector_CreatePyObject(tvec, vec_size, Py_NEW, Py_TYPE(m2)); } /*FLOAT/INT * MATRIX */ - else if (((scalar= PyFloat_AsDouble(m2)) == -1.0f && PyErr_Occurred())==0) { + else if (((scalar = PyFloat_AsDouble(m2)) == -1.0f && PyErr_Occurred()) == 0) { return matrix_mul_float(mat1, scalar); } } @@ -1634,22 +1967,15 @@ Py_TYPE(m1)->tp_name, Py_TYPE(m2)->tp_name); return NULL; } -static PyObject* Matrix_inv(MatrixObject *self) -{ - if (BaseMath_ReadCallback(self) == -1) - return NULL; - - return Matrix_invert(self); -} /*-----------------PROTOCOL DECLARATIONS--------------------------*/ static PySequenceMethods Matrix_SeqMethods = { (lenfunc) Matrix_len, /* sq_length */ (binaryfunc) NULL, /* sq_concat */ (ssizeargfunc) NULL, /* sq_repeat */ - (ssizeargfunc) Matrix_item, /* sq_item */ + (ssizeargfunc) Matrix_item_row, /* sq_item */ (ssizessizeargfunc) NULL, /* sq_slice, deprecated */ - (ssizeobjargproc) Matrix_ass_item, /* sq_ass_item */ + (ssizeobjargproc) Matrix_ass_item_row, /* sq_ass_item */ (ssizessizeobjargproc) NULL, /* sq_ass_slice, deprecated */ (objobjproc) NULL, /* sq_contains */ (binaryfunc) NULL, /* sq_inplace_concat */ @@ -1657,7 +1983,7 @@ }; -static PyObject *Matrix_subscript(MatrixObject* self, PyObject* item) +static PyObject *Matrix_subscript(MatrixObject *self, PyObject *item) { if (PyIndex_Check(item)) { Py_ssize_t i; @@ -1665,13 +1991,13 @@ if (i == -1 && PyErr_Occurred()) return NULL; if (i < 0) - i += self->row_size; - return Matrix_item(self, i); + i += self->num_row; + return Matrix_item_row(self, i); } else if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength; - if (PySlice_GetIndicesEx((void *)item, self->row_size, &start, &stop, &step, &slicelength) < 0) + if (PySlice_GetIndicesEx((void *)item, self->num_row, &start, &stop, &step, &slicelength) < 0) return NULL; if (slicelength <= 0) { @@ -1694,20 +2020,20 @@ } } -static int Matrix_ass_subscript(MatrixObject* self, PyObject* item, PyObject* value) +static int Matrix_ass_subscript(MatrixObject *self, PyObject *item, PyObject *value) { if (PyIndex_Check(item)) { Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); if (i == -1 && PyErr_Occurred()) return -1; if (i < 0) - i += self->row_size; - return Matrix_ass_item(self, i, value); + i += self->num_row; + return Matrix_ass_item_row(self, i, value); } else if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength; - if (PySlice_GetIndicesEx((void *)item, self->row_size, &start, &stop, &step, &slicelength) < 0) + if (PySlice_GetIndicesEx((void *)item, self->num_row, &start, &stop, &step, &slicelength) < 0) return -1; if (step == 1) @@ -1744,7 +2070,7 @@ (unaryfunc) 0, /*tp_positive*/ (unaryfunc) 0, /*tp_absolute*/ (inquiry) 0, /*tp_bool*/ - (unaryfunc) Matrix_inv, /*nb_invert*/ + (unaryfunc) Matrix_inverted, /*nb_invert*/ NULL, /*nb_lshift*/ (binaryfunc)0, /*nb_rshift*/ NULL, /*nb_and*/ @@ -1770,16 +2096,74 @@ NULL, /* nb_index */ }; -static PyObject *Matrix_getRowSize(MatrixObject *self, void *UNUSED(closure)) +PyDoc_STRVAR(Matrix_translation_doc, +"The translation component of the matrix.\n\n:type: Vector" +); +static PyObject *Matrix_translation_get(MatrixObject *self, void *UNUSED(closure)) +{ + PyObject *ret; + + if (BaseMath_ReadCallback(self) == -1) + return NULL; + + /*must be 4x4 square matrix*/ + if (self->num_row != 4 || self->num_col != 4) { + PyErr_SetString(PyExc_AttributeError, + "Matrix.translation: " + "inappropriate matrix size, must be 4x4"); + return NULL; + } + + ret = (PyObject *)Vector_CreatePyObject_cb((PyObject *)self, 3, mathutils_matrix_translation_cb_index, 3); + + return ret; +} + +static int Matrix_translation_set(MatrixObject *self, PyObject *value, void *UNUSED(closure)) { - return PyLong_FromLong((long) self->row_size); + float tvec[3]; + + if (BaseMath_ReadCallback(self) == -1) + return -1; + + /*must be 4x4 square matrix*/ + if (self->num_row != 4 || self->num_col != 4) { + PyErr_SetString(PyExc_AttributeError, + "Matrix.translation: " + "inappropriate matrix size, must be 4x4"); + return -1; + } + + if ((mathutils_array_parse(tvec, 3, 3, value, "Matrix.translation")) == -1) { + return -1; + } + + copy_v3_v3(((float (*)[4])self->matrix)[3], tvec); + + (void)BaseMath_WriteCallback(self); + + return 0; } -static PyObject *Matrix_getColSize(MatrixObject *self, void *UNUSED(closure)) +PyDoc_STRVAR(Matrix_row_doc, +"Access the matix by rows (default), (readonly).\n\n:type: Matrix Access" +); +static PyObject *Matrix_row_get(MatrixObject *self, void *UNUSED(closure)) { - return PyLong_FromLong((long) self->col_size); + return MatrixAccess_CreatePyObject(self, MAT_ACCESS_ROW); } +PyDoc_STRVAR(Matrix_col_doc, +"Access the matix by colums, 3x3 and 4x4 only, (readonly).\n\n:type: Matrix Access" +); +static PyObject *Matrix_col_get(MatrixObject *self, void *UNUSED(closure)) +{ + return MatrixAccess_CreatePyObject(self, MAT_ACCESS_COL); +} + +PyDoc_STRVAR(Matrix_median_scale_doc, +"The average scale applied to each axis (readonly).\n\n:type: float" +); static PyObject *Matrix_median_scale_get(MatrixObject *self, void *UNUSED(closure)) { float mat[3][3]; @@ -1788,7 +2172,7 @@ return NULL; /*must be 3-4 cols, 3-4 rows, square matrix*/ - if ((self->col_size < 3) || (self->row_size < 3)) { + if ((self->num_row < 3) || (self->num_col < 3)) { PyErr_SetString(PyExc_AttributeError, "Matrix.median_scale: " "inappropriate matrix size, 3x3 minimum"); @@ -1800,16 +2184,19 @@ return PyFloat_FromDouble(mat3_to_scale(mat)); } +PyDoc_STRVAR(Matrix_is_negative_doc, +"True if this matrix results in a negative scale, 3x3 and 4x4 only, (readonly).\n\n:type: bool" +); static PyObject *Matrix_is_negative_get(MatrixObject *self, void *UNUSED(closure)) { if (BaseMath_ReadCallback(self) == -1) return NULL; /*must be 3-4 cols, 3-4 rows, square matrix*/ - if (self->col_size == 4 && self->row_size == 4) - return PyBool_FromLong(is_negative_m4((float (*)[4])self->contigPtr)); - else if (self->col_size == 3 && self->row_size == 3) - return PyBool_FromLong(is_negative_m3((float (*)[3])self->contigPtr)); + if (self->num_row == 4 && self->num_col == 4) + return PyBool_FromLong(is_negative_m4((float (*)[4])self->matrix)); + else if (self->num_row == 3 && self->num_col == 3) + return PyBool_FromLong(is_negative_m3((float (*)[3])self->matrix)); else { PyErr_SetString(PyExc_AttributeError, "Matrix.is_negative: " @@ -1818,16 +2205,19 @@ } } +PyDoc_STRVAR(Matrix_is_orthogonal_doc, +"True if this matrix is orthogonal, 3x3 and 4x4 only, (readonly).\n\n:type: bool" +); static PyObject *Matrix_is_orthogonal_get(MatrixObject *self, void *UNUSED(closure)) { if (BaseMath_ReadCallback(self) == -1) return NULL; /*must be 3-4 cols, 3-4 rows, square matrix*/ - if (self->col_size == 4 && self->row_size == 4) - return PyBool_FromLong(is_orthogonal_m4((float (*)[4])self->contigPtr)); - else if (self->col_size == 3 && self->row_size == 3) - return PyBool_FromLong(is_orthogonal_m3((float (*)[3])self->contigPtr)); + if (self->num_row == 4 && self->num_col == 4) + return PyBool_FromLong(is_orthogonal_m4((float (*)[4])self->matrix)); + else if (self->num_row == 3 && self->num_col == 3) + return PyBool_FromLong(is_orthogonal_m3((float (*)[3])self->matrix)); else { PyErr_SetString(PyExc_AttributeError, "Matrix.is_orthogonal: " @@ -1840,13 +2230,14 @@ /* Python attributes get/set structure: */ /*****************************************************************************/ static PyGetSetDef Matrix_getseters[] = { - {(char *)"row_size", (getter)Matrix_getRowSize, (setter)NULL, (char *)"The row size of the matrix (readonly).\n\n:type: int", NULL}, - {(char *)"col_size", (getter)Matrix_getColSize, (setter)NULL, (char *)"The column size of the matrix (readonly).\n\n:type: int", NULL}, - {(char *)"median_scale", (getter)Matrix_median_scale_get, (setter)NULL, (char *)"The average scale applied to each axis (readonly).\n\n:type: float", NULL}, - {(char *)"is_negative", (getter)Matrix_is_negative_get, (setter)NULL, (char *)"True if this matrix results in a negative scale, 3x3 and 4x4 only, (readonly).\n\n:type: bool", NULL}, - {(char *)"is_orthogonal", (getter)Matrix_is_orthogonal_get, (setter)NULL, (char *)"True if this matrix is orthogonal, 3x3 and 4x4 only, (readonly).\n\n:type: bool", NULL}, - {(char *)"is_wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, (char *)BaseMathObject_Wrapped_doc, NULL}, - {(char *)"owner",(getter)BaseMathObject_getOwner, (setter)NULL, (char *)BaseMathObject_Owner_doc, NULL}, + {(char *)"median_scale", (getter)Matrix_median_scale_get, (setter)NULL, Matrix_median_scale_doc, NULL}, + {(char *)"translation", (getter)Matrix_translation_get, (setter)Matrix_translation_set, Matrix_translation_doc, NULL}, + {(char *)"row", (getter)Matrix_row_get, (setter)NULL, Matrix_row_doc, NULL}, + {(char *)"col", (getter)Matrix_col_get, (setter)NULL, Matrix_col_doc, NULL}, + {(char *)"is_negative", (getter)Matrix_is_negative_get, (setter)NULL, Matrix_is_negative_doc, NULL}, + {(char *)"is_orthogonal", (getter)Matrix_is_orthogonal_get, (setter)NULL, Matrix_is_orthogonal_doc, NULL}, + {(char *)"is_wrapped", (getter)BaseMathObject_is_wrapped_get, (setter)NULL, BaseMathObject_is_wrapped_doc, NULL}, + {(char *)"owner",(getter)BaseMathObject_owner_get, (setter)NULL, BaseMathObject_owner_doc, NULL}, {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ }; @@ -1883,6 +2274,7 @@ {"__copy__", (PyCFunction) Matrix_copy, METH_NOARGS, Matrix_copy_doc}, /* class methods */ + {"Identity", (PyCFunction) C_Matrix_Identity, METH_VARARGS | METH_CLASS, C_Matrix_Identity_doc}, {"Rotation", (PyCFunction) C_Matrix_Rotation, METH_VARARGS | METH_CLASS, C_Matrix_Rotation_doc}, {"Scale", (PyCFunction) C_Matrix_Scale, METH_VARARGS | METH_CLASS, C_Matrix_Scale_doc}, {"Shear", (PyCFunction) C_Matrix_Shear, METH_VARARGS | METH_CLASS, C_Matrix_Shear_doc}, @@ -1911,7 +2303,7 @@ &Matrix_AsMapping, /*tp_as_mapping*/ NULL, /*tp_hash*/ NULL, /*tp_call*/ - NULL, /*tp_str*/ + (reprfunc) Matrix_str, /*tp_str*/ NULL, /*tp_getattro*/ NULL, /*tp_setattro*/ NULL, /*tp_as_buffer*/ @@ -1944,80 +2336,60 @@ NULL /*tp_del*/ }; -/*------------------------Matrix_CreatePyObject (internal)------------- -creates a new matrix object -self->matrix self->contiguous_ptr (reference to data.xxx) - [0]------------->[0] - [1] - [2] - [1]------------->[3] - [4] - [5] - -self->matrix[1][1] = self->contigPtr[4] */ - -/*pass Py_WRAP - if vector is a WRAPPER for data allocated by BLENDER - (i.e. it was allocated elsewhere by MEM_mallocN()) - pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON - (i.e. it must be created here with PyMEM_malloc())*/ +/* pass Py_WRAP - if vector is a WRAPPER for data allocated by BLENDER + * (i.e. it was allocated elsewhere by MEM_mallocN()) + * pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON + * (i.e. it must be created here with PyMEM_malloc()) */ PyObject *Matrix_CreatePyObject(float *mat, - const unsigned short rowSize, const unsigned short colSize, + const unsigned short num_col, const unsigned short num_row, int type, PyTypeObject *base_type) { MatrixObject *self; - int x, row, col; - /*matrix objects can be any 2-4row x 2-4col matrix*/ - if (rowSize < 2 || rowSize > 4 || colSize < 2 || colSize > 4) { + /* matrix objects can be any 2-4row x 2-4col matrix */ + if (num_col < 2 || num_col > 4 || num_row < 2 || num_row > 4) { PyErr_SetString(PyExc_RuntimeError, "Matrix(): " "row and column sizes must be between 2 and 4"); return NULL; } - self= base_type ? (MatrixObject *)base_type->tp_alloc(base_type, 0) : - (MatrixObject *)PyObject_GC_New(MatrixObject, &matrix_Type); + self = base_type ? (MatrixObject *)base_type->tp_alloc(base_type, 0) : + (MatrixObject *)PyObject_GC_New(MatrixObject, &matrix_Type); if (self) { - self->row_size = rowSize; - self->col_size = colSize; + self->num_col = num_col; + self->num_row = num_row; /* init callbacks as NULL */ - self->cb_user= NULL; - self->cb_type= self->cb_subtype= 0; + self->cb_user = NULL; + self->cb_type = self->cb_subtype = 0; if (type == Py_WRAP) { - self->contigPtr = mat; - /*pointer array points to contigous memory*/ - for (x = 0; x < rowSize; x++) { - self->matrix[x] = self->contigPtr + (x * colSize); - } + self->matrix = mat; self->wrapped = Py_WRAP; } else if (type == Py_NEW) { - self->contigPtr = PyMem_Malloc(rowSize * colSize * sizeof(float)); - if (self->contigPtr == NULL) { /*allocation failure*/ + self->matrix = PyMem_Malloc(num_col * num_row * sizeof(float)); + if (self->matrix == NULL) { /*allocation failure*/ PyErr_SetString(PyExc_MemoryError, "Matrix(): " "problem allocating pointer space"); return NULL; } - /*pointer array points to contigous memory*/ - for (x = 0; x < rowSize; x++) { - self->matrix[x] = self->contigPtr + (x * colSize); - } - /*parse*/ + if (mat) { /*if a float array passed*/ - for (row = 0; row < rowSize; row++) { - for (col = 0; col < colSize; col++) { - self->matrix[row][col] = mat[(row * colSize) + col]; - } - } + memcpy(self->matrix, mat, num_col * num_row * sizeof(float)); } - else if (rowSize == colSize) { /*or if no arguments are passed return identity matrix for square matrices */ - PyObject *ret_dummy= Matrix_identity(self); + else if (num_col == num_row) { + /* or if no arguments are passed return identity matrix for square matrices */ + PyObject *ret_dummy = Matrix_identity(self); Py_DECREF(ret_dummy); } + else { + /* otherwise zero everything */ + memset(self->matrix, 0, num_col * num_row * sizeof(float)); + } self->wrapped = Py_NEW; } else { @@ -2028,15 +2400,233 @@ return (PyObject *) self; } -PyObject *Matrix_CreatePyObject_cb(PyObject *cb_user, int rowSize, int colSize, int cb_type, int cb_subtype) +PyObject *Matrix_CreatePyObject_cb(PyObject *cb_user, + const unsigned short num_col, const unsigned short num_row, + int cb_type, int cb_subtype) { - MatrixObject *self= (MatrixObject *)Matrix_CreatePyObject(NULL, rowSize, colSize, Py_NEW, NULL); + MatrixObject *self = (MatrixObject *)Matrix_CreatePyObject(NULL, num_col, num_row, Py_NEW, NULL); if (self) { Py_INCREF(cb_user); - self->cb_user= cb_user; - self->cb_type= (unsigned char)cb_type; - self->cb_subtype= (unsigned char)cb_subtype; + self->cb_user = cb_user; + self->cb_type = (unsigned char)cb_type; + self->cb_subtype = (unsigned char)cb_subtype; PyObject_GC_Track(self); } return (PyObject *) self; } + + +/* ---------------------------------------------------------------------------- + * special type for alaternate access */ + +typedef struct { + PyObject_HEAD /* required python macro */ + MatrixObject *matrix_user; + eMatrixAccess_t type; +} MatrixAccessObject; + +static int MatrixAccess_traverse(MatrixAccessObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->matrix_user); + return 0; +} + +static int MatrixAccess_clear(MatrixAccessObject *self) +{ + Py_CLEAR(self->matrix_user); + return 0; +} + +static void MatrixAccess_dealloc(MatrixAccessObject *self) +{ + if (self->matrix_user) { + PyObject_GC_UnTrack(self); + MatrixAccess_clear(self); + } + + Py_TYPE(self)->tp_free(self); +} + +/* sequence access */ + +static int MatrixAccess_len(MatrixAccessObject *self) +{ + return (self->type == MAT_ACCESS_ROW) ? + self->matrix_user->num_row : + self->matrix_user->num_col; +} + +static PyObject *MatrixAccess_slice(MatrixAccessObject *self, int begin, int end) +{ + PyObject *tuple; + int count; + + /* row/col access */ + MatrixObject *matrix_user = self->matrix_user; + int matrix_access_len; + PyObject *(*Matrix_item_new)(MatrixObject *, int); + + if (self->type == MAT_ACCESS_ROW) { + matrix_access_len = matrix_user->num_row; + Matrix_item_new = Matrix_item_row; + } + else { /* MAT_ACCESS_ROW */ + matrix_access_len = matrix_user->num_col; + Matrix_item_new = Matrix_item_col; + } + + CLAMP(begin, 0, matrix_access_len); + if (end < 0) end = (matrix_access_len + 1) + end; + CLAMP(end, 0, matrix_access_len); + begin = MIN2(begin, end); + + tuple = PyTuple_New(end - begin); + for (count = begin; count < end; count++) { + PyTuple_SET_ITEM(tuple, count - begin, Matrix_item_new(matrix_user, count)); + } + + return tuple; +} + +static PyObject *MatrixAccess_subscript(MatrixAccessObject *self, PyObject *item) +{ + MatrixObject *matrix_user = self->matrix_user; + + if (PyIndex_Check(item)) { + Py_ssize_t i; + i = PyNumber_AsSsize_t(item, PyExc_IndexError); + if (i == -1 && PyErr_Occurred()) + return NULL; + if (self->type == MAT_ACCESS_ROW) { + if (i < 0) + i += matrix_user->num_row; + return Matrix_item_row(matrix_user, i); + } + else { /* MAT_ACCESS_ROW */ + if (i < 0) + i += matrix_user->num_col; + return Matrix_item_col(matrix_user, i); + } + } + else if (PySlice_Check(item)) { + Py_ssize_t start, stop, step, slicelength; + + if (PySlice_GetIndicesEx((void *)item, MatrixAccess_len(self), &start, &stop, &step, &slicelength) < 0) + return NULL; + + if (slicelength <= 0) { + return PyTuple_New(0); + } + else if (step == 1) { + return MatrixAccess_slice(self, start, stop); + } + else { + PyErr_SetString(PyExc_IndexError, + "slice steps not supported with matrix accessors"); + return NULL; + } + } + else { + PyErr_Format(PyExc_TypeError, + "matrix indices must be integers, not %.200s", + Py_TYPE(item)->tp_name); + return NULL; + } +} + +static int MatrixAccess_ass_subscript(MatrixAccessObject *self, PyObject *item, PyObject *value) +{ + MatrixObject *matrix_user = self->matrix_user; + + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); + if (i == -1 && PyErr_Occurred()) + return -1; + + if (self->type == MAT_ACCESS_ROW) { + if (i < 0) + i += matrix_user->num_row; + return Matrix_ass_item_row(matrix_user, i, value); + } + else { /* MAT_ACCESS_ROW */ + if (i < 0) + i += matrix_user->num_col; + return Matrix_ass_item_col(matrix_user, i, value); + } + + } + /* TODO, slice */ + else { + PyErr_Format(PyExc_TypeError, + "matrix indices must be integers, not %.200s", + Py_TYPE(item)->tp_name); + return -1; + } +} + +static PyObject *MatrixAccess_iter(MatrixAccessObject *self) +{ + /* Try get values from a collection */ + PyObject *ret; + PyObject *iter = NULL; + ret = MatrixAccess_slice(self, 0, MATRIX_MAX_DIM); + + /* we know this is a tuple so no need to PyIter_Check + * otherwise it could be NULL (unlikely) if conversion failed */ + if (ret) { + iter = PyObject_GetIter(ret); + Py_DECREF(ret); + } + + return iter; +} + +static PyMappingMethods MatrixAccess_AsMapping = { + (lenfunc)MatrixAccess_len, + (binaryfunc)MatrixAccess_subscript, + (objobjargproc) MatrixAccess_ass_subscript +}; + +PyTypeObject matrix_access_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "MatrixAccess", /*tp_name*/ + sizeof(MatrixAccessObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)MatrixAccess_dealloc, /*tp_dealloc*/ + NULL, /*tp_print*/ + NULL, /*tp_getattr*/ + NULL, /*tp_setattr*/ + NULL, /*tp_compare*/ + NULL, /*tp_repr*/ + NULL, /*tp_as_number*/ + NULL /*&MatrixAccess_SeqMethods*/ /* TODO */, /*tp_as_sequence*/ + &MatrixAccess_AsMapping, /*tp_as_mapping*/ + NULL, /*tp_hash*/ + NULL, /*tp_call*/ + NULL, /*tp_str*/ + NULL, /*tp_getattro*/ + NULL, /*tp_setattro*/ + NULL, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + NULL, /*tp_doc*/ + (traverseproc)MatrixAccess_traverse, //tp_traverse + (inquiry)MatrixAccess_clear, //tp_clear + NULL /* (richcmpfunc)MatrixAccess_richcmpr */ /* TODO*/, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + (getiterfunc)MatrixAccess_iter, /* getiterfunc tp_iter; */ +}; + +static PyObject *MatrixAccess_CreatePyObject(MatrixObject *matrix, const eMatrixAccess_t type) +{ + MatrixAccessObject *matrix_access = (MatrixAccessObject *)PyObject_GC_New(MatrixObject, &matrix_access_Type); + + matrix_access->matrix_user = matrix; + Py_INCREF(matrix); + + matrix_access->type = type; + + return (PyObject *)matrix_access; +} + +/* end special access + * -------------------------------------------------------------------------- */ diff -Nru blender-2.61/source/blender/python/mathutils/mathutils_Matrix.h blender-2.62/source/blender/python/mathutils/mathutils_Matrix.h --- blender-2.61/source/blender/python/mathutils/mathutils_Matrix.h 2011-12-13 19:48:32.000000000 +0000 +++ blender-2.62/source/blender/python/mathutils/mathutils_Matrix.h 2012-02-15 19:33:13.000000000 +0000 @@ -35,29 +35,51 @@ #define MATHUTILS_MATRIX_H extern PyTypeObject matrix_Type; +extern PyTypeObject matrix_access_Type; #define MatrixObject_Check(_v) PyObject_TypeCheck((_v), &matrix_Type) #define MATRIX_MAX_DIM 4 +/* matrix[row][col] == MATRIX_ITEM_INDEX(matrix, row, col) */ + +#ifdef DEBUG +# define MATRIX_ITEM_ASSERT(_mat, _row, _col) (BLI_assert(_row < (_mat)->num_row && _col < (_mat)->num_col)) +#else +# define MATRIX_ITEM_ASSERT(_mat, _row, _col) (void)0 +#endif + +#define MATRIX_ITEM_INDEX(_mat, _row, _col) (MATRIX_ITEM_ASSERT(_mat, _row, _col),(((_mat)->num_row * (_col)) + (_row))) +#define MATRIX_ITEM_PTR( _mat, _row, _col) ((_mat)->matrix + MATRIX_ITEM_INDEX(_mat, _row, _col)) +#define MATRIX_ITEM( _mat, _row, _col) ((_mat)->matrix [MATRIX_ITEM_INDEX(_mat, _row, _col)]) + +#define MATRIX_COL_INDEX(_mat, _col) (MATRIX_ITEM_INDEX(_mat, 0, _col)) +#define MATRIX_COL_PTR( _mat, _col) ((_mat)->matrix + MATRIX_COL_INDEX(_mat, _col)) + typedef struct { - BASE_MATH_MEMBERS(contigPtr); - float *matrix[MATRIX_MAX_DIM]; /* ptr to the contigPtr (accessor) */ - unsigned short row_size; - unsigned short col_size; + BASE_MATH_MEMBERS(matrix); + unsigned short num_col; + unsigned short num_row; } MatrixObject; -/*struct data contains a pointer to the actual data that the -object uses. It can use either PyMem allocated data (which will -be stored in py_data) or be a wrapper for data allocated through -blender (stored in blend_data). This is an either/or struct not both*/ +/* struct data contains a pointer to the actual data that the + * object uses. It can use either PyMem allocated data (which will + * be stored in py_data) or be a wrapper for data allocated through + * blender (stored in blend_data). This is an either/or struct not both */ -/*prototypes*/ +/* prototypes */ PyObject *Matrix_CreatePyObject(float *mat, - const unsigned short row_size, const unsigned short col_size, + const unsigned short num_col, const unsigned short num_row, int type, PyTypeObject *base_type); -PyObject *Matrix_CreatePyObject_cb(PyObject *user, int row_size, int col_size, int cb_type, int cb_subtype); - -extern int mathutils_matrix_vector_cb_index; -extern struct Mathutils_Callback mathutils_matrix_vector_cb; +PyObject *Matrix_CreatePyObject_cb(PyObject *user, + const unsigned short num_col, const unsigned short num_row, + int cb_type, int cb_subtype); + +extern int mathutils_matrix_row_cb_index; /* default */ +extern int mathutils_matrix_col_cb_index; +extern int mathutils_matrix_translation_cb_index; + +extern struct Mathutils_Callback mathutils_matrix_row_cb; /* default */ +extern struct Mathutils_Callback mathutils_matrix_col_cb; +extern struct Mathutils_Callback mathutils_matrix_translation_cb; void matrix_as_3x3(float mat[3][3], MatrixObject *self); diff -Nru blender-2.61/source/blender/python/mathutils/mathutils_noise.c blender-2.62/source/blender/python/mathutils/mathutils_noise.c --- blender-2.61/source/blender/python/mathutils/mathutils_noise.c 2011-12-13 19:48:32.000000000 +0000 +++ blender-2.62/source/blender/python/mathutils/mathutils_noise.c 2012-02-15 19:33:13.000000000 +0000 @@ -199,18 +199,18 @@ /* Fills an array of length size with random numbers in the range (-1, 1)*/ static void rand_vn(float *array_tar, const int size) { - float *array_pt= array_tar + (size-1); - int i= size; - while(i--) { *(array_pt--) = 2.0f * frand() - 1.0f; } + float *array_pt = array_tar + (size-1); + int i = size; + while (i--) { *(array_pt--) = 2.0f * frand() - 1.0f; } } /* Fills an array of length 3 with noise values */ static void noise_vector(float x, float y, float z, int nb, float v[3]) { /* Simply evaluate noise at 3 different positions */ - v[0]= (float)(2.0f * BLI_gNoise(1.f, x + 9.321f, y - 1.531f, z - 7.951f, 0, nb) - 1.0f); - v[1]= (float)(2.0f * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0f); - v[2]= (float)(2.0f * BLI_gNoise(1.f, x + 6.327f, y + 0.1671f, z - 2.672f, 0, nb) - 1.0f); + v[0] = (float)(2.0f * BLI_gNoise(1.f, x + 9.321f, y - 1.531f, z - 7.951f, 0, nb) - 1.0f); + v[1] = (float)(2.0f * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0f); + v[2] = (float)(2.0f * BLI_gNoise(1.f, x + 6.327f, y + 0.1671f, z - 2.672f, 0, nb) - 1.0f); } /* Returns a turbulence value for a given position (x, y, z) */ @@ -301,9 +301,9 @@ ); static PyObject *M_Noise_random_unit_vector(PyObject *UNUSED(self), PyObject *args) { - float vec[4]= {0.0f, 0.0f, 0.0f, 0.0f}; - float norm= 2.0f; - int size= 3; + float vec[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + float norm = 2.0f; + int size = 3; if (!PyArg_ParseTuple(args, "|i:random_vector", &size)) return NULL; @@ -313,9 +313,9 @@ return NULL; } - while (norm==0.0f || norm>=1.0f) { + while (norm == 0.0f || norm >= 1.0f) { rand_vn(vec, size); - norm= normalize_vn(vec, size); + norm = normalize_vn(vec, size); } return Vector_CreatePyObject(vec, size, Py_NEW, NULL); @@ -384,7 +384,7 @@ { PyObject *value; float vec[3]; - int nb= 1; + int nb = 1; if (!PyArg_ParseTuple(args, "O|i:noise", &value, &nb)) return NULL; @@ -410,7 +410,7 @@ { PyObject *value; float vec[3], r_vec[3]; - int nb= 1; + int nb = 1; if (!PyArg_ParseTuple(args, "O|i:noise_vector", &value, &nb)) return NULL; @@ -447,8 +447,8 @@ { PyObject *value; float vec[3]; - int oct, hd, nb= 1; - float as= 0.5f, fs= 2.0f; + int oct, hd, nb = 1; + float as = 0.5f, fs = 2.0f; if (!PyArg_ParseTuple(args, "Oii|iff:turbulence", &value, &oct, &hd, &nb, &as, &fs)) return NULL; @@ -483,8 +483,8 @@ { PyObject *value; float vec[3], r_vec[3]; - int oct, hd, nb= 1; - float as =0.5f, fs= 2.0f; + int oct, hd, nb = 1; + float as =0.5f, fs = 2.0f; if (!PyArg_ParseTuple(args, "Oii|iff:turbulence_vector", &value, &oct, &hd, &nb, &as, &fs)) return NULL; @@ -519,7 +519,7 @@ PyObject *value; float vec[3]; float H, lac, oct; - int nb= 1; + int nb = 1; if (!PyArg_ParseTuple(args, "Offf|i:fractal", &value, &H, &lac, &oct, &nb)) return NULL; @@ -553,7 +553,7 @@ PyObject *value; float vec[3]; float H, lac, oct; - int nb= 1; + int nb = 1; if (!PyArg_ParseTuple(args, "Offf|i:multi_fractal", &value, &H, &lac, &oct, &nb)) return NULL; @@ -585,7 +585,7 @@ PyObject *value; float vec[3]; float d; - int nt1= 1, nt2= 1; + int nt1 = 1, nt2 = 1; if (!PyArg_ParseTuple(args, "Of|ii:variable_lacunarity", &value, &d, &nt1, &nt2)) return NULL; @@ -621,7 +621,7 @@ PyObject *value; float vec[3]; float H, lac, oct, ofs; - int nb= 1; + int nb = 1; if (!PyArg_ParseTuple(args, "Offff|i:hetero_terrain", &value, &H, &lac, &oct, &ofs, &nb)) return NULL; @@ -659,7 +659,7 @@ PyObject *value; float vec[3]; float H, lac, oct, ofs, gn; - int nb= 1; + int nb = 1; if (!PyArg_ParseTuple(args, "Offfff|i:hybrid_multi_fractal", &value, &H, &lac, &oct, &ofs, &gn, &nb)) return NULL; @@ -697,7 +697,7 @@ PyObject *value; float vec[3]; float H, lac, oct, ofs, gn; - int nb= 1; + int nb = 1; if (!PyArg_ParseTuple(args, "Offfff|i:ridged_multi_fractal", &value, &H, &lac, &oct, &ofs, &gn, &nb)) return NULL; @@ -720,7 +720,7 @@ " :arg exponent: The exponent for Minkovsky distance metric.\n" " :type exponent: float\n" " :return: A list of distances to the four closest features and their locations.\n" -" :rtype: [list of four floats, list of four :class:`mathutils.Vector`s]\n" +" :rtype: list of four floats, list of four :class:`mathutils.Vector` types\n" ); static PyObject *M_Noise_voronoi(PyObject *UNUSED(self), PyObject *args) { @@ -728,8 +728,8 @@ PyObject *list; float vec[3]; float da[4], pa[12]; - int dtype= 0; - float me= 2.5f; /* default minkovsky exponent */ + int dtype = 0; + float me = 2.5f; /* default minkovsky exponent */ int i; @@ -739,12 +739,12 @@ if (mathutils_array_parse(vec, 3, 3, value, "voronoi: invalid 'position' arg") == -1) return NULL; - list= PyList_New(4); + list = PyList_New(4); voronoi(vec[0], vec[1], vec[2], da, pa, me, dtype); - for (i=0; i<4; i++) { - PyList_SET_ITEM(list, i, Vector_CreatePyObject(pa + 3*i, 3, Py_NEW, NULL)); + for (i = 0; i < 4; i++) { + PyList_SET_ITEM(list, i, Vector_CreatePyObject(pa + 3 * i, 3, Py_NEW, NULL)); } return Py_BuildValue("[[ffff]O]", da[0], da[1], da[2], da[3], list); @@ -841,11 +841,11 @@ /* use current time as seed for random number generator by default */ setRndSeed(0); - PyModule_AddObject(submodule, "types", (item_types=PyInit_mathutils_noise_types())); + PyModule_AddObject(submodule, "types", (item_types = PyInit_mathutils_noise_types())); PyDict_SetItemString(PyThreadState_GET()->interp->modules, "noise.types", item_types); Py_INCREF(item_types); - PyModule_AddObject(submodule, "distance_metrics", (item_metrics=PyInit_mathutils_noise_metrics())); + PyModule_AddObject(submodule, "distance_metrics", (item_metrics = PyInit_mathutils_noise_metrics())); PyDict_SetItemString(PyThreadState_GET()->interp->modules, "noise.distance_metrics", item_metrics); Py_INCREF(item_metrics); diff -Nru blender-2.61/source/blender/python/mathutils/mathutils_Quaternion.c blender-2.62/source/blender/python/mathutils/mathutils_Quaternion.c --- blender-2.61/source/blender/python/mathutils/mathutils_Quaternion.c 2011-12-13 19:48:32.000000000 +0000 +++ blender-2.62/source/blender/python/mathutils/mathutils_Quaternion.c 2012-02-15 19:33:13.000000000 +0000 @@ -35,6 +35,7 @@ #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLI_dynstr.h" #define QUAT_SIZE 4 @@ -50,15 +51,15 @@ PyObject *ret; int i; - ret= PyTuple_New(QUAT_SIZE); + ret = PyTuple_New(QUAT_SIZE); if (ndigits >= 0) { - for (i= 0; i < QUAT_SIZE; i++) { + for (i = 0; i < QUAT_SIZE; i++) { PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(double_round((double)self->quat[i], ndigits))); } } else { - for (i= 0; i < QUAT_SIZE; i++) { + for (i = 0; i < QUAT_SIZE; i++) { PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(self->quat[i])); } } @@ -85,8 +86,8 @@ { float tquat[4]; float eul[3]; - const char *order_str= NULL; - short order= EULER_ORDER_XYZ; + const char *order_str = NULL; + short order = EULER_ORDER_XYZ; EulerObject *eul_compat = NULL; if (!PyArg_ParseTuple(args, "|sO!:to_euler", &order_str, &euler_Type, &eul_compat)) @@ -96,7 +97,7 @@ return NULL; if (order_str) { - order= euler_order_from_string(order_str, "Matrix.to_euler()"); + order = euler_order_from_string(order_str, "Matrix.to_euler()"); if (order == -1) return NULL; @@ -168,7 +169,7 @@ quat__axis_angle_sanitize(axis, &angle); - ret= PyTuple_New(2); + ret = PyTuple_New(2); PyTuple_SET_ITEM(ret, 0, Vector_CreatePyObject(axis, 3, Py_NEW, NULL)); PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(angle)); return ret; @@ -193,8 +194,10 @@ if (BaseMath_ReadCallback(self) == -1) return NULL; - if (mathutils_array_parse(tquat, QUAT_SIZE, QUAT_SIZE, value, "Quaternion.cross(other), invalid 'other' arg") == -1) + if (mathutils_array_parse(tquat, QUAT_SIZE, QUAT_SIZE, value, + "Quaternion.cross(other), invalid 'other' arg") == -1) { return NULL; + } mul_qt_qtqt(quat, self->quat, tquat); return Quaternion_CreatePyObject(quat, Py_NEW, Py_TYPE(self)); @@ -319,7 +322,7 @@ if (mathutils_any_to_rotmat(other_rmat, value, "Quaternion.rotate(value)") == -1) return NULL; - length= normalize_qt_qt(tquat, self->quat); + length = normalize_qt_qt(tquat, self->quat); quat_to_mat3(self_rmat, tquat); mul_m3_m3m3(rmat, other_rmat, self_rmat); @@ -485,27 +488,42 @@ if (BaseMath_ReadCallback(self) == -1) return NULL; - tuple= Quaternion_to_tuple_ext(self, -1); + tuple = Quaternion_to_tuple_ext(self, -1); - ret= PyUnicode_FromFormat("Quaternion(%R)", tuple); + ret = PyUnicode_FromFormat("Quaternion(%R)", tuple); Py_DECREF(tuple); return ret; } -static PyObject* Quaternion_richcmpr(PyObject *a, PyObject *b, int op) +static PyObject *Quaternion_str(QuaternionObject *self) +{ + DynStr *ds; + + if (BaseMath_ReadCallback(self) == -1) + return NULL; + + ds = BLI_dynstr_new(); + + BLI_dynstr_appendf(ds, "", + self->quat[0], self->quat[1], self->quat[2], self->quat[3]); + + return mathutils_dynstr_to_py(ds); /* frees ds */ +} + +static PyObject *Quaternion_richcmpr(PyObject *a, PyObject *b, int op) { PyObject *res; - int ok= -1; /* zero is true */ + int ok = -1; /* zero is true */ if (QuaternionObject_Check(a) && QuaternionObject_Check(b)) { - QuaternionObject *quatA= (QuaternionObject *)a; - QuaternionObject *quatB= (QuaternionObject *)b; + QuaternionObject *quatA = (QuaternionObject *)a; + QuaternionObject *quatB = (QuaternionObject *)b; if (BaseMath_ReadCallback(quatA) == -1 || BaseMath_ReadCallback(quatB) == -1) return NULL; - ok= (EXPP_VectorsAreEqual(quatA->quat, quatB->quat, QUAT_SIZE, 1)) ? 0 : -1; + ok = (EXPP_VectorsAreEqual(quatA->quat, quatB->quat, QUAT_SIZE, 1)) ? 0 : -1; } switch (op) { @@ -540,7 +558,7 @@ //sequence accessor (get) static PyObject *Quaternion_item(QuaternionObject *self, int i) { - if (i<0) i= QUAT_SIZE-i; + if (i < 0) i = QUAT_SIZE-i; if (i < 0 || i >= QUAT_SIZE) { PyErr_SetString(PyExc_IndexError, @@ -559,15 +577,15 @@ //sequence accessor (set) static int Quaternion_ass_item(QuaternionObject *self, int i, PyObject *ob) { - float scalar= (float)PyFloat_AsDouble(ob); - if (scalar==-1.0f && PyErr_Occurred()) { /* parsed item not a number */ + float scalar = (float)PyFloat_AsDouble(ob); + if (scalar == -1.0f && PyErr_Occurred()) { /* parsed item not a number */ PyErr_SetString(PyExc_TypeError, "quaternion[index] = x: " "index argument not a number"); return -1; } - if (i<0) i= QUAT_SIZE-i; + if (i < 0) i = QUAT_SIZE-i; if (i < 0 || i >= QUAT_SIZE) { PyErr_SetString(PyExc_IndexError, @@ -593,12 +611,12 @@ return NULL; CLAMP(begin, 0, QUAT_SIZE); - if (end<0) end= (QUAT_SIZE + 1) + end; + if (end < 0) end = (QUAT_SIZE + 1) + end; CLAMP(end, 0, QUAT_SIZE); - begin= MIN2(begin, end); + begin = MIN2(begin, end); - tuple= PyTuple_New(end - begin); - for (count= begin; count < end; count++) { + tuple = PyTuple_New(end - begin); + for (count = begin; count < end; count++) { PyTuple_SET_ITEM(tuple, count - begin, PyFloat_FromDouble(self->quat[count])); } @@ -615,11 +633,11 @@ return -1; CLAMP(begin, 0, QUAT_SIZE); - if (end<0) end= (QUAT_SIZE + 1) + end; + if (end < 0) end = (QUAT_SIZE + 1) + end; CLAMP(end, 0, QUAT_SIZE); begin = MIN2(begin, end); - if ((size=mathutils_array_parse(quat, 0, QUAT_SIZE, seq, "mathutils.Quaternion[begin:end] = []")) == -1) + if ((size = mathutils_array_parse(quat, 0, QUAT_SIZE, seq, "mathutils.Quaternion[begin:end] = []")) == -1) return -1; if (size != (end - begin)) { @@ -630,7 +648,7 @@ } /* parsed well - now set in vector */ - for (i= 0; i < size; i++) + for (i = 0; i < size; i++) self->quat[begin + i] = quat[i]; (void)BaseMath_WriteCallback(self); @@ -793,7 +811,7 @@ } /* the only case this can happen (for a supported type is "FLOAT*QUAT") */ else if (quat2) { /* FLOAT*QUAT */ - if (((scalar= PyFloat_AsDouble(q1)) == -1.0f && PyErr_Occurred())==0) { + if (((scalar = PyFloat_AsDouble(q1)) == -1.0f && PyErr_Occurred()) == 0) { return quat_mul_float(quat2, scalar); } } @@ -820,7 +838,7 @@ return Vector_CreatePyObject(tvec, 3, Py_NEW, Py_TYPE(vec2)); } /* QUAT * FLOAT */ - else if ((((scalar= PyFloat_AsDouble(q2)) == -1.0f && PyErr_Occurred())==0)) { + else if ((((scalar = PyFloat_AsDouble(q2)) == -1.0f && PyErr_Occurred()) == 0)) { return quat_mul_float(quat1, scalar); } } @@ -906,17 +924,23 @@ NULL, /* nb_index */ }; -static PyObject *Quaternion_getAxis(QuaternionObject *self, void *type) +PyDoc_STRVAR(Quaternion_axis_doc, +"Quaternion axis value.\n\n:type: float" +); +static PyObject *Quaternion_axis_get(QuaternionObject *self, void *type) { return Quaternion_item(self, GET_INT_FROM_POINTER(type)); } -static int Quaternion_setAxis(QuaternionObject *self, PyObject *value, void *type) +static int Quaternion_axis_set(QuaternionObject *self, PyObject *value, void *type) { return Quaternion_ass_item(self, GET_INT_FROM_POINTER(type), value); } -static PyObject *Quaternion_getMagnitude(QuaternionObject *self, void *UNUSED(closure)) +PyDoc_STRVAR(Quaternion_magnitude_doc, +"Size of the quaternion (readonly).\n\n:type: float" +); +static PyObject *Quaternion_magnitude_get(QuaternionObject *self, void *UNUSED(closure)) { if (BaseMath_ReadCallback(self) == -1) return NULL; @@ -924,7 +948,10 @@ return PyFloat_FromDouble(sqrt(dot_qtqt(self->quat, self->quat))); } -static PyObject *Quaternion_getAngle(QuaternionObject *self, void *UNUSED(closure)) +PyDoc_STRVAR(Quaternion_angle_doc, +"Angle of the quaternion.\n\n:type: float" +); +static PyObject *Quaternion_angle_get(QuaternionObject *self, void *UNUSED(closure)) { float tquat[4]; float angle; @@ -934,14 +961,14 @@ normalize_qt_qt(tquat, self->quat); - angle= 2.0f * saacos(tquat[0]); + angle = 2.0f * saacos(tquat[0]); quat__axis_angle_sanitize(NULL, &angle); return PyFloat_FromDouble(angle); } -static int Quaternion_setAngle(QuaternionObject *self, PyObject *value, void *UNUSED(closure)) +static int Quaternion_angle_set(QuaternionObject *self, PyObject *value, void *UNUSED(closure)) { float tquat[4]; float len; @@ -952,18 +979,18 @@ if (BaseMath_ReadCallback(self) == -1) return -1; - len= normalize_qt_qt(tquat, self->quat); + len = normalize_qt_qt(tquat, self->quat); quat_to_axis_angle(axis, &angle_dummy, tquat); - angle= PyFloat_AsDouble(value); + angle = PyFloat_AsDouble(value); - if (angle==-1.0f && PyErr_Occurred()) { /* parsed item not a number */ + if (angle == -1.0f && PyErr_Occurred()) { /* parsed item not a number */ PyErr_SetString(PyExc_TypeError, "Quaternion.angle = value: float expected"); return -1; } - angle= angle_wrap_rad(angle); + angle = angle_wrap_rad(angle); quat__axis_angle_sanitize(axis, &angle); @@ -976,7 +1003,10 @@ return 0; } -static PyObject *Quaternion_getAxisVec(QuaternionObject *self, void *UNUSED(closure)) +PyDoc_STRVAR(Quaternion_axis_vector_doc, +"Quaternion axis as a vector.\n\n:type: :class:`Vector`" +); +static PyObject *Quaternion_axis_vector_get(QuaternionObject *self, void *UNUSED(closure)) { float tquat[4]; @@ -994,7 +1024,7 @@ return Vector_CreatePyObject(axis, 3, Py_NEW, NULL); } -static int Quaternion_setAxisVec(QuaternionObject *self, PyObject *value, void *UNUSED(closure)) +static int Quaternion_axis_vector_set(QuaternionObject *self, PyObject *value, void *UNUSED(closure)) { float tquat[4]; float len; @@ -1005,7 +1035,7 @@ if (BaseMath_ReadCallback(self) == -1) return -1; - len= normalize_qt_qt(tquat, self->quat); + len = normalize_qt_qt(tquat, self->quat); quat_to_axis_angle(axis, &angle, tquat); /* axis value is unused */ if (mathutils_array_parse(axis, 3, 3, value, "quat.axis = other") == -1) @@ -1025,9 +1055,9 @@ //----------------------------------mathutils.Quaternion() -------------- static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - PyObject *seq= NULL; + PyObject *seq = NULL; double angle = 0.0f; - float quat[QUAT_SIZE]= {0.0f, 0.0f, 0.0f, 0.0f}; + float quat[QUAT_SIZE] = {0.0f, 0.0f, 0.0f, 0.0f}; if (kwds && PyDict_Size(kwds)) { PyErr_SetString(PyExc_TypeError, @@ -1039,7 +1069,7 @@ if (!PyArg_ParseTuple(args, "|Od:mathutils.Quaternion", &seq, &angle)) return NULL; - switch(PyTuple_GET_SIZE(args)) { + switch (PyTuple_GET_SIZE(args)) { case 0: break; case 1: @@ -1049,7 +1079,7 @@ case 2: if (mathutils_array_parse(quat, 3, 3, seq, "mathutils.Quaternion()") == -1) return NULL; - angle= angle_wrap_rad(angle); /* clamp because of precision issues */ + angle = angle_wrap_rad(angle); /* clamp because of precision issues */ axis_angle_to_quat(quat, quat, angle); break; /* PyArg_ParseTuple assures no more then 2 */ @@ -1059,8 +1089,8 @@ static PyObject *quat__apply_to_copy(PyNoArgsFunction quat_func, QuaternionObject *self) { - PyObject *ret= Quaternion_copy(self); - PyObject *ret_dummy= quat_func(ret); + PyObject *ret = Quaternion_copy(self); + PyObject *ret_dummy = quat_func(ret); if (ret_dummy) { Py_DECREF(ret_dummy); return ret; @@ -1075,25 +1105,25 @@ static void quat__axis_angle_sanitize(float axis[3], float *angle) { if (axis) { - if ( !finite(axis[0]) || - !finite(axis[1]) || - !finite(axis[2])) + if ( !finite(axis[0]) || + !finite(axis[1]) || + !finite(axis[2])) { - axis[0]= 1.0f; - axis[1]= 0.0f; - axis[2]= 0.0f; + axis[0] = 1.0f; + axis[1] = 0.0f; + axis[2] = 0.0f; } - else if ( EXPP_FloatsAreEqual(axis[0], 0.0f, 10) && - EXPP_FloatsAreEqual(axis[1], 0.0f, 10) && - EXPP_FloatsAreEqual(axis[2], 0.0f, 10) - ) { + else if ( EXPP_FloatsAreEqual(axis[0], 0.0f, 10) && + EXPP_FloatsAreEqual(axis[1], 0.0f, 10) && + EXPP_FloatsAreEqual(axis[2], 0.0f, 10)) + { axis[0] = 1.0f; } } if (angle) { if (!finite(*angle)) { - *angle= 0.0f; + *angle = 0.0f; } } } @@ -1135,15 +1165,15 @@ /* Python attributes get/set structure: */ /*****************************************************************************/ static PyGetSetDef Quaternion_getseters[] = { - {(char *)"w", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, (char *)"Quaternion W value.\n\n:type: float", (void *)0}, - {(char *)"x", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, (char *)"Quaternion X axis.\n\n:type: float", (void *)1}, - {(char *)"y", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, (char *)"Quaternion Y axis.\n\n:type: float", (void *)2}, - {(char *)"z", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, (char *)"Quaternion Z axis.\n\n:type: float", (void *)3}, - {(char *)"magnitude", (getter)Quaternion_getMagnitude, (setter)NULL, (char *)"Size of the quaternion (readonly).\n\n:type: float", NULL}, - {(char *)"angle", (getter)Quaternion_getAngle, (setter)Quaternion_setAngle, (char *)"angle of the quaternion.\n\n:type: float", NULL}, - {(char *)"axis",(getter)Quaternion_getAxisVec, (setter)Quaternion_setAxisVec, (char *)"quaternion axis as a vector.\n\n:type: :class:`Vector`", NULL}, - {(char *)"is_wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, (char *)BaseMathObject_Wrapped_doc, NULL}, - {(char *)"owner", (getter)BaseMathObject_getOwner, (setter)NULL, (char *)BaseMathObject_Owner_doc, NULL}, + {(char *)"w", (getter)Quaternion_axis_get, (setter)Quaternion_axis_set, Quaternion_axis_doc, (void *)0}, + {(char *)"x", (getter)Quaternion_axis_get, (setter)Quaternion_axis_set, Quaternion_axis_doc, (void *)1}, + {(char *)"y", (getter)Quaternion_axis_get, (setter)Quaternion_axis_set, Quaternion_axis_doc, (void *)2}, + {(char *)"z", (getter)Quaternion_axis_get, (setter)Quaternion_axis_set, Quaternion_axis_doc, (void *)3}, + {(char *)"magnitude", (getter)Quaternion_magnitude_get, (setter)NULL, Quaternion_magnitude_doc, NULL}, + {(char *)"angle", (getter)Quaternion_angle_get, (setter)Quaternion_angle_set, Quaternion_angle_doc, NULL}, + {(char *)"axis",(getter)Quaternion_axis_vector_get, (setter)Quaternion_axis_vector_set, Quaternion_axis_vector_doc, NULL}, + {(char *)"is_wrapped", (getter)BaseMathObject_is_wrapped_get, (setter)NULL, BaseMathObject_is_wrapped_doc, NULL}, + {(char *)"owner", (getter)BaseMathObject_owner_get, (setter)NULL, BaseMathObject_owner_doc, NULL}, {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ }; @@ -1167,7 +1197,7 @@ &Quaternion_AsMapping, //tp_as_mapping NULL, //tp_hash NULL, //tp_call - NULL, //tp_str + (reprfunc) Quaternion_str, //tp_str NULL, //tp_getattro NULL, //tp_setattro NULL, //tp_as_buffer @@ -1209,13 +1239,13 @@ { QuaternionObject *self; - self= base_type ? (QuaternionObject *)base_type->tp_alloc(base_type, 0) : - (QuaternionObject *)PyObject_GC_New(QuaternionObject, &quaternion_Type); + self = base_type ? (QuaternionObject *)base_type->tp_alloc(base_type, 0) : + (QuaternionObject *)PyObject_GC_New(QuaternionObject, &quaternion_Type); if (self) { /* init callbacks as NULL */ - self->cb_user= NULL; - self->cb_type= self->cb_subtype= 0; + self->cb_user = NULL; + self->cb_type = self->cb_subtype = 0; if (type == Py_WRAP) { self->quat = quat; @@ -1240,12 +1270,12 @@ PyObject *Quaternion_CreatePyObject_cb(PyObject *cb_user, int cb_type, int cb_subtype) { - QuaternionObject *self= (QuaternionObject *)Quaternion_CreatePyObject(NULL, Py_NEW, NULL); + QuaternionObject *self = (QuaternionObject *)Quaternion_CreatePyObject(NULL, Py_NEW, NULL); if (self) { Py_INCREF(cb_user); - self->cb_user= cb_user; - self->cb_type= (unsigned char)cb_type; - self->cb_subtype= (unsigned char)cb_subtype; + self->cb_user = cb_user; + self->cb_type = (unsigned char)cb_type; + self->cb_subtype = (unsigned char)cb_subtype; PyObject_GC_Track(self); } diff -Nru blender-2.61/source/blender/python/mathutils/mathutils_Vector.c blender-2.62/source/blender/python/mathutils/mathutils_Vector.c --- blender-2.61/source/blender/python/mathutils/mathutils_Vector.c 2011-12-13 19:48:32.000000000 +0000 +++ blender-2.62/source/blender/python/mathutils/mathutils_Vector.c 2012-02-15 19:33:13.000000000 +0000 @@ -35,6 +35,7 @@ #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLI_dynstr.h" #define MAX_DIMENSIONS 4 @@ -54,15 +55,29 @@ */ static PyObject *Vector_new(PyTypeObject *type, PyObject *args, PyObject *UNUSED(kwds)) { - float vec[4]= {0.0f, 0.0f, 0.0f, 0.0f}; - int size= 3; /* default to a 3D vector */ + float *vec = NULL; + int size = 3; /* default to a 3D vector */ - switch(PyTuple_GET_SIZE(args)) { + switch (PyTuple_GET_SIZE(args)) { case 0: + vec = PyMem_Malloc(size * sizeof(float)); + + if (vec == NULL) { + PyErr_SetString(PyExc_MemoryError, + "Vector(): " + "problem allocating pointer space"); + return NULL; + } + + fill_vn_fl(vec, size, 0.0f); break; case 1: - if ((size=mathutils_array_parse(vec, 2, 4, PyTuple_GET_ITEM(args, 0), "mathutils.Vector()")) == -1) + if ((size = mathutils_array_parse_alloc(&vec, 2, PyTuple_GET_ITEM(args, 0), "mathutils.Vector()")) == -1) { + if (vec) { + PyMem_Free(vec); + } return NULL; + } break; default: PyErr_SetString(PyExc_TypeError, @@ -75,8 +90,8 @@ static PyObject *vec__apply_to_copy(PyNoArgsFunction vec_func, VectorObject *self) { - PyObject *ret= Vector_copy(self); - PyObject *ret_dummy= vec_func(ret); + PyObject *ret = Vector_copy(self); + PyObject *ret_dummy = vec_func(ret); if (ret_dummy) { Py_DECREF(ret_dummy); return (PyObject *)ret; @@ -87,6 +102,228 @@ } } +/*-----------------------CLASS-METHODS----------------------------*/ +PyDoc_STRVAR(C_Vector_Fill_doc, +".. classmethod:: Fill(size, fill=0.0)\n" +"\n" +" Create a vector of length size with all values set to fill.\n" +"\n" +" :arg size: The length of the vector to be created.\n" +" :type size: int\n" +" :arg fill: The value used to fill the vector.\n" +" :type fill: float\n" +); +static PyObject *C_Vector_Fill(PyObject *cls, PyObject *args) +{ + float *vec; + int size; + float fill = 0.0f; + + if (!PyArg_ParseTuple(args, "i|f:Vector.Fill", &size, &fill)) { + return NULL; + } + + if (size < 2) { + PyErr_SetString(PyExc_RuntimeError, + "Vector(): invalid size"); + return NULL; + } + + vec = PyMem_Malloc(size * sizeof(float)); + + if (vec == NULL) { + PyErr_SetString(PyExc_MemoryError, + "Vector.Fill(): " + "problem allocating pointer space"); + return NULL; + } + + fill_vn_fl(vec, size, fill); + + return Vector_CreatePyObject_alloc(vec, size, (PyTypeObject *)cls); +} + +PyDoc_STRVAR(C_Vector_Range_doc, +".. classmethod:: Range(start=0, stop, step=1)\n" +"\n" +" Create a filled with a range of values.\n" +"\n" +" :arg start: The start of the range used to fill the vector.\n" +" :type start: int\n" +" :arg stop: The end of the range used to fill the vector.\n" +" :type stop: int\n" +" :arg step: The step between successive values in the vector.\n" +" :type step: int\n" +); +static PyObject *C_Vector_Range(PyObject *cls, PyObject *args) +{ + float *vec; + int stop, size; + int start = 0; + int step = 1; + + if (!PyArg_ParseTuple(args, "i|ii:Vector.Range", &start, &stop, &step)) { + return NULL; + } + + switch (PyTuple_GET_SIZE(args)) { + case 1: + size = start; + start = 0; + break; + case 2: + if (start >= stop) { + PyErr_SetString(PyExc_RuntimeError, + "Start value is larger " + "than the stop value"); + return NULL; + } + + size = stop - start; + break; + default: + if (start >= stop) { + PyErr_SetString(PyExc_RuntimeError, + "Start value is larger " + "than the stop value"); + return NULL; + } + + size = (stop - start); + + if ((size % step) != 0) + size += step; + + size /= step; + + break; + } + + if (size < 2) { + PyErr_SetString(PyExc_RuntimeError, + "Vector(): invalid size"); + return NULL; + } + + vec = PyMem_Malloc(size * sizeof(float)); + + if (vec == NULL) { + PyErr_SetString(PyExc_MemoryError, + "Vector.Range(): " + "problem allocating pointer space"); + return NULL; + } + + range_vn_fl(vec, size, (float)start, (float)step); + + return Vector_CreatePyObject_alloc(vec, size, (PyTypeObject *)cls); +} + +PyDoc_STRVAR(C_Vector_Linspace_doc, +".. classmethod:: Linspace(start, stop, size)\n" +"\n" +" Create a vector of the specified size which is filled with linearly spaced values between start and stop values.\n" +"\n" +" :arg start: The start of the range used to fill the vector.\n" +" :type start: int\n" +" :arg stop: The end of the range used to fill the vector.\n" +" :type stop: int\n" +" :arg size: The size of the vector to be created.\n" +" :type size: int\n" +); +static PyObject *C_Vector_Linspace(PyObject *cls, PyObject *args) +{ + float *vec; + int size; + float start, end, step; + + if (!PyArg_ParseTuple(args, "ffi:Vector.Linspace", &start, &end, &size)) { + return NULL; + } + + if (size < 2) { + PyErr_SetString(PyExc_RuntimeError, + "Vector.Linspace(): invalid size"); + return NULL; + } + + step = (end - start)/(float)(size-1); + + vec = PyMem_Malloc(size * sizeof(float)); + + if (vec == NULL) { + PyErr_SetString(PyExc_MemoryError, + "Vector.Linspace(): " + "problem allocating pointer space"); + return NULL; + } + + range_vn_fl(vec, size, start, step); + + return Vector_CreatePyObject_alloc(vec, size, (PyTypeObject *)cls); +} + +PyDoc_STRVAR(C_Vector_Repeat_doc, +".. classmethod:: Repeat(vector, size)\n" +"\n" +" Create a vector by repeating the values in vector until the required size is reached.\n" +"\n" +" :arg tuple: The vector to draw values from.\n" +" :type tuple: :class:`mathutils.Vector`\n" +" :arg size: The size of the vector to be created.\n" +" :type size: int\n" +); +static PyObject *C_Vector_Repeat(PyObject *cls, PyObject *args) +{ + float *vec; + float *iter_vec = NULL; + int i, size, value_size; + PyObject *value; + + if (!PyArg_ParseTuple(args, "Oi:Vector.Repeat", &value, &size)) { + return NULL; + } + + if (size < 2) { + PyErr_SetString(PyExc_RuntimeError, + "Vector.Repeat(): invalid size"); + return NULL; + } + + if ((value_size = mathutils_array_parse_alloc(&iter_vec, 2, value, + "Vector.Repeat(vector, size), invalid 'vector' arg")) == -1) + { + PyMem_Free(iter_vec); + return NULL; + } + + if (iter_vec == NULL) { + PyErr_SetString(PyExc_MemoryError, + "Vector.Repeat(): " + "problem allocating pointer space"); + return NULL; + } + + vec = PyMem_Malloc(size * sizeof(float)); + + if (vec == NULL) { + PyErr_SetString(PyExc_MemoryError, + "Vector.Repeat(): " + "problem allocating pointer space"); + return NULL; + } + + i = 0; + while (i < size) { + vec[i] = iter_vec[i % value_size]; + i++; + } + + PyMem_Free(iter_vec); + + return Vector_CreatePyObject_alloc(vec, size, (PyTypeObject *)cls); +} + /*-----------------------------METHODS---------------------------- */ PyDoc_STRVAR(Vector_zero_doc, ".. method:: zero()\n" @@ -108,18 +345,18 @@ "\n" " Normalize the vector, making the length of the vector always 1.0.\n" "\n" -" .. warning:: Normalizing a vector where all values are zero results\n" -" in all axis having a nan value (not a number).\n" +" .. warning:: Normalizing a vector where all values are zero has no effect.\n" "\n" " .. note:: Normalize works for vectors of all sizes,\n" " however 4D Vectors w axis is left untouched.\n" ); static PyObject *Vector_normalize(VectorObject *self) { + int size = (self->size == 4 ? 3 : self->size); if (BaseMath_ReadCallback(self) == -1) return NULL; - normalize_vn(self->vec, self->size); + normalize_vn(self->vec, size); (void)BaseMath_WriteCallback(self); Py_RETURN_NONE; @@ -137,17 +374,106 @@ return vec__apply_to_copy((PyNoArgsFunction)Vector_normalize, self); } +PyDoc_STRVAR(Vector_resize_doc, +".. method:: resize(size=3)\n" +"\n" +" Resize the vector to have size number of elements.\n" +); +static PyObject *Vector_resize(VectorObject *self, PyObject *value) +{ + int size; + + if (self->wrapped == Py_WRAP) { + PyErr_SetString(PyExc_TypeError, + "Vector.resize(): " + "cannot resize wrapped data - only python vectors"); + return NULL; + } + if (self->cb_user) { + PyErr_SetString(PyExc_TypeError, + "Vector.resize(): " + "cannot resize a vector that has an owner"); + return NULL; + } + + if ((size = PyLong_AsLong(value)) == -1) { + PyErr_SetString(PyExc_TypeError, + "Vector.resize(size): " + "expected size argument to be an integer"); + return NULL; + } + + if (size < 2) { + PyErr_SetString(PyExc_RuntimeError, + "Vector.resize(): invalid size"); + return NULL; + } + + self->vec = PyMem_Realloc(self->vec, (size * sizeof(float))); + if (self->vec == NULL) { + PyErr_SetString(PyExc_MemoryError, + "Vector.resize(): " + "problem allocating pointer space"); + return NULL; + } + + /* If the vector has increased in length, set all new elements to 0.0f */ + if (size > self->size) { + fill_vn_fl(self->vec + self->size, size - self->size, 0.0f); + } + + self->size = size; + Py_RETURN_NONE; +} + +PyDoc_STRVAR(Vector_resized_doc, +".. method:: resized(size=3)\n" +"\n" +" Return a resized copy of the vector with size number of elements.\n" +"\n" +" :return: a new vector\n" +" :rtype: :class:`Vector`\n" +); +static PyObject *Vector_resized(VectorObject *self, PyObject *value) +{ + int size; + float *vec; + + /*if (!PyArg_ParseTuple(args, "i:resize", &size)) + return NULL;*/ + if ((size = PyLong_AsLong(value)) == -1) { + return NULL; + } + + if (size < 2) { + PyErr_SetString(PyExc_RuntimeError, + "Vector.resized(): invalid size"); + return NULL; + } + + vec = PyMem_Malloc(size * sizeof(float)); + + if (vec == NULL) { + PyErr_SetString(PyExc_MemoryError, + "Vector.resized(): " + "problem allocating pointer space"); + return NULL; + } + + fill_vn_fl(vec, size, 0.0f); + memcpy(vec, self->vec, self->size * sizeof(float)); + + return Vector_CreatePyObject_alloc(vec, size, NULL); +} + PyDoc_STRVAR(Vector_resize_2d_doc, ".. method:: resize_2d()\n" "\n" " Resize the vector to 2D (x, y).\n" -"\n" -" :return: an instance of itself\n" -" :rtype: :class:`Vector`\n" ); static PyObject *Vector_resize_2d(VectorObject *self) { - if (self->wrapped==Py_WRAP) { + if (self->wrapped == Py_WRAP) { PyErr_SetString(PyExc_TypeError, "Vector.resize_2d(): " "cannot resize wrapped data - only python vectors"); @@ -176,13 +502,10 @@ ".. method:: resize_3d()\n" "\n" " Resize the vector to 3D (x, y, z).\n" -"\n" -" :return: an instance of itself\n" -" :rtype: :class:`Vector`\n" ); static PyObject *Vector_resize_3d(VectorObject *self) { - if (self->wrapped==Py_WRAP) { + if (self->wrapped == Py_WRAP) { PyErr_SetString(PyExc_TypeError, "Vector.resize_3d(): " "cannot resize wrapped data - only python vectors"); @@ -214,13 +537,10 @@ ".. method:: resize_4d()\n" "\n" " Resize the vector to 4D (x, y, z, w).\n" -"\n" -" :return: an instance of itself\n" -" :rtype: :class:`Vector`\n" ); static PyObject *Vector_resize_4d(VectorObject *self) { - if (self->wrapped==Py_WRAP) { + if (self->wrapped == Py_WRAP) { PyErr_SetString(PyExc_TypeError, "Vector.resize_4d(): " "cannot resize wrapped data - only python vectors"); @@ -276,7 +596,7 @@ ); static PyObject *Vector_to_3d(VectorObject *self) { - float tvec[3]= {0.0f}; + float tvec[3] = {0.0f}; if (BaseMath_ReadCallback(self) == -1) return NULL; @@ -294,7 +614,7 @@ ); static PyObject *Vector_to_4d(VectorObject *self) { - float tvec[4]= {0.0f, 0.0f, 0.0f, 1.0f}; + float tvec[4] = {0.0f, 0.0f, 0.0f, 1.0f}; if (BaseMath_ReadCallback(self) == -1) return NULL; @@ -319,7 +639,7 @@ PyObject *ret; int i; - ret= PyTuple_New(self->size); + ret = PyTuple_New(self->size); if (ndigits >= 0) { for (i = 0; i < self->size; i++) { @@ -337,7 +657,7 @@ static PyObject *Vector_to_tuple(VectorObject *self, PyObject *args) { - int ndigits= 0; + int ndigits = 0; if (!PyArg_ParseTuple(args, "|i:to_tuple", &ndigits)) return NULL; @@ -349,8 +669,8 @@ return NULL; } - if (PyTuple_GET_SIZE(args)==0) - ndigits= -1; + if (PyTuple_GET_SIZE(args) == 0) + ndigits = -1; if (BaseMath_ReadCallback(self) == -1) return NULL; @@ -390,11 +710,11 @@ return NULL; if (strack) { - const char *axis_err_msg= "only X, -X, Y, -Y, Z or -Z for track axis"; + const char *axis_err_msg = "only X, -X, Y, -Y, Z or -Z for track axis"; if (strlen(strack) == 2) { if (strack[0] == '-') { - switch(strack[1]) { + switch (strack[1]) { case 'X': track = 3; break; @@ -415,7 +735,7 @@ } } else if (strlen(strack) == 1) { - switch(strack[0]) { + switch (strack[0]) { case '-': case 'X': track = 0; @@ -438,9 +758,9 @@ } if (sup) { - const char *axis_err_msg= "only X, Y or Z for up axis"; + const char *axis_err_msg = "only X, Y or Z for up axis"; if (strlen(sup) == 1) { - switch(*sup) { + switch (*sup) { case 'X': up = 0; break; @@ -502,9 +822,15 @@ if (BaseMath_ReadCallback(self) == -1) return NULL; - if ((value_size= mathutils_array_parse(tvec, 2, 4, value, "Vector.reflect(other), invalid 'other' arg")) == -1) + if ((value_size = mathutils_array_parse(tvec, 2, 4, value, "Vector.reflect(other), invalid 'other' arg")) == -1) return NULL; + if (self->size < 2 || self->size > 4) { + PyErr_SetString(PyExc_ValueError, + "Vector must be 2D, 3D or 4D"); + return NULL; + } + mirror[0] = tvec[0]; mirror[1] = tvec[1]; if (value_size > 2) mirror[2] = tvec[2]; @@ -544,7 +870,13 @@ if (mathutils_array_parse(tvec, self->size, self->size, value, "Vector.cross(other), invalid 'other' arg") == -1) return NULL; - ret= (VectorObject *)Vector_CreatePyObject(NULL, 3, Py_NEW, Py_TYPE(self)); + if (self->size != 3) { + PyErr_SetString(PyExc_ValueError, + "Vector must be 3D"); + return NULL; + } + + ret = (VectorObject *)Vector_CreatePyObject(NULL, 3, Py_NEW, Py_TYPE(self)); cross_v3_v3v3(ret->vec, self->vec, tvec); return (PyObject *)ret; } @@ -561,15 +893,20 @@ ); static PyObject *Vector_dot(VectorObject *self, PyObject *value) { - float tvec[MAX_DIMENSIONS]; + float *tvec; if (BaseMath_ReadCallback(self) == -1) return NULL; - if (mathutils_array_parse(tvec, self->size, self->size, value, "Vector.dot(other), invalid 'other' arg") == -1) - return NULL; + if (mathutils_array_parse_alloc(&tvec, self->size, value, "Vector.dot(other), invalid 'other' arg") == -1) { + goto cleanup; + } return PyFloat_FromDouble(dot_vn_vn(self->vec, tvec, self->size)); + +cleanup: + PyMem_Free(tvec); + return NULL; } PyDoc_STRVAR(Vector_angle_doc, @@ -589,12 +926,12 @@ ); static PyObject *Vector_angle(VectorObject *self, PyObject *args) { - const int size= MIN2(self->size, 3); /* 4D angle makes no sense */ + const int size = MIN2(self->size, 3); /* 4D angle makes no sense */ float tvec[MAX_DIMENSIONS]; PyObject *value; - double dot= 0.0f, dot_self= 0.0f, dot_other= 0.0f; + double dot = 0.0f, dot_self = 0.0f, dot_other = 0.0f; int x; - PyObject *fallback= NULL; + PyObject *fallback = NULL; if (!PyArg_ParseTuple(args, "O|O:angle", &value, &fallback)) return NULL; @@ -607,6 +944,12 @@ if (mathutils_array_parse(tvec, self->size, self->size, value, "Vector.angle(other), invalid 'other' arg") == -1) return NULL; + if (self->size > 4) { + PyErr_SetString(PyExc_ValueError, + "Vector must be 2D, 3D or 4D"); + return NULL; + } + for (x = 0; x < size; x++) { dot_self += (double)self->vec[x] * (double)self->vec[x]; dot_other += (double)tvec[x] * (double)tvec[x]; @@ -647,7 +990,7 @@ { float quat[4], vec_a[3], vec_b[3]; - if (self->size < 3) { + if (self->size < 3 || self->size > 4) { PyErr_SetString(PyExc_ValueError, "vec.difference(value): " "expects both vectors to be size 3 or 4"); @@ -680,7 +1023,7 @@ ); static PyObject *Vector_project(VectorObject *self, PyObject *value) { - const int size= self->size; + const int size = self->size; float tvec[MAX_DIMENSIONS]; float vec[MAX_DIMENSIONS]; double dot = 0.0f, dot2 = 0.0f; @@ -692,6 +1035,12 @@ if (mathutils_array_parse(tvec, size, size, value, "Vector.project(other), invalid 'other' arg") == -1) return NULL; + if (self->size > 4) { + PyErr_SetString(PyExc_ValueError, + "Vector must be 2D, 3D or 4D"); + return NULL; + } + if (BaseMath_ReadCallback(self) == -1) return NULL; @@ -722,27 +1071,44 @@ ); static PyObject *Vector_lerp(VectorObject *self, PyObject *args) { - const int size= self->size; - PyObject *value= NULL; + const int size = self->size; + PyObject *value = NULL; float fac, ifac; - float tvec[MAX_DIMENSIONS], vec[MAX_DIMENSIONS]; + float *tvec, *vec; int x; if (!PyArg_ParseTuple(args, "Of:lerp", &value, &fac)) return NULL; - if (mathutils_array_parse(tvec, size, size, value, "Vector.lerp(other), invalid 'other' arg") == -1) - return NULL; + if (mathutils_array_parse_alloc(&tvec, size, value, "Vector.lerp(other), invalid 'other' arg") == -1) { + goto cleanup; + } - if (BaseMath_ReadCallback(self) == -1) + if (BaseMath_ReadCallback(self) == -1) { + goto cleanup; + } + + vec = PyMem_Malloc(size * sizeof(float)); + if (vec == NULL) { + PyErr_SetString(PyExc_MemoryError, + "Vector.lerp(): " + "problem allocating pointer space"); return NULL; + } - ifac= 1.0f - fac; + ifac = 1.0f - fac; for (x = 0; x < size; x++) { vec[x] = (ifac * self->vec[x]) + (fac * tvec[x]); } - return Vector_CreatePyObject(vec, size, Py_NEW, Py_TYPE(self)); + + PyMem_Free(tvec); + + return Vector_CreatePyObject_alloc(vec, size, Py_TYPE(self)); + +cleanup: + PyMem_Free(tvec); + return NULL; } PyDoc_STRVAR(Vector_rotate_doc, @@ -763,7 +1129,7 @@ if (mathutils_any_to_rotmat(other_rmat, value, "Vector.rotate(value)") == -1) return NULL; - if (self->size < 3) { + if (self->size < 3 || self->size > 4) { PyErr_SetString(PyExc_ValueError, "Vector must be 3D or 4D"); return NULL; @@ -801,12 +1167,35 @@ if (BaseMath_ReadCallback(self) == -1) return NULL; - tuple= Vector_to_tuple_ext(self, -1); - ret= PyUnicode_FromFormat("Vector(%R)", tuple); + tuple = Vector_to_tuple_ext(self, -1); + ret = PyUnicode_FromFormat("Vector(%R)", tuple); Py_DECREF(tuple); return ret; } +static PyObject *Vector_str(VectorObject *self) +{ + int i; + + DynStr *ds; + + if (BaseMath_ReadCallback(self) == -1) + return NULL; + + ds = BLI_dynstr_new(); + + BLI_dynstr_append(ds, "size; i++) { + BLI_dynstr_appendf(ds, i ? ", %.4f" : "%.4f", self->vec[i]); + } + + BLI_dynstr_append(ds, ")>"); + + return mathutils_dynstr_to_py(ds); /* frees ds */ +} + + /* Sequence Protocol */ /* sequence length len(vector) */ static int Vector_len(VectorObject *self) @@ -816,7 +1205,7 @@ /* sequence accessor (get): vector[index] */ static PyObject *vector_item_internal(VectorObject *self, int i, const int is_attr) { - if (i<0) i= self->size-i; + if (i < 0) i = self->size-i; if (i < 0 || i >= self->size) { if (is_attr) { @@ -845,14 +1234,14 @@ static int vector_ass_item_internal(VectorObject *self, int i, PyObject *value, const int is_attr) { float scalar; - if ((scalar=PyFloat_AsDouble(value))==-1.0f && PyErr_Occurred()) { /* parsed item not a number */ + if ((scalar = PyFloat_AsDouble(value)) == -1.0f && PyErr_Occurred()) { /* parsed item not a number */ PyErr_SetString(PyExc_TypeError, "vector[index] = x: " "index argument not a number"); return -1; } - if (i<0) i= self->size-i; + if (i < 0) i = self->size-i; if (i < 0 || i >= self->size) { if (is_attr) { @@ -889,11 +1278,11 @@ return NULL; CLAMP(begin, 0, self->size); - if (end<0) end= self->size+end+1; + if (end < 0) end = self->size + end + 1; CLAMP(end, 0, self->size); - begin= MIN2(begin, end); + begin = MIN2(begin, end); - tuple= PyTuple_New(end - begin); + tuple = PyTuple_New(end - begin); for (count = begin; count < end; count++) { PyTuple_SET_ITEM(tuple, count - begin, PyFloat_FromDouble(self->vec[count])); } @@ -903,8 +1292,8 @@ /* sequence slice (set): vector[a:b] = value */ static int Vector_ass_slice(VectorObject *self, int begin, int end, PyObject *seq) { - int y, size = 0; - float vec[MAX_DIMENSIONS]; + int size = 0; + float *vec = NULL; if (BaseMath_ReadCallback(self) == -1) return -1; @@ -914,18 +1303,30 @@ begin = MIN2(begin, end); size = (end - begin); - if (mathutils_array_parse(vec, size, size, seq, "vector[begin:end] = [...]") == -1) + if (mathutils_array_parse_alloc(&vec, size, seq, "vector[begin:end] = [...]") == -1) { + goto cleanup; + } + + if (vec == NULL) { + PyErr_SetString(PyExc_MemoryError, + "vec[:] = seq: " + "problem allocating pointer space"); return -1; + } /*parsed well - now set in vector*/ - for (y = 0; y < size; y++) { - self->vec[begin + y] = vec[y]; - } + memcpy(self->vec + begin, vec, size * sizeof(float)); if (BaseMath_WriteCallback(self) == -1) return -1; + PyMem_Free(vec); + return 0; + +cleanup: + PyMem_Free(vec); + return -1; } /* Numeric Protocols */ @@ -933,7 +1334,7 @@ static PyObject *Vector_add(PyObject *v1, PyObject *v2) { VectorObject *vec1 = NULL, *vec2 = NULL; - float vec[MAX_DIMENSIONS]; + float *vec = NULL; if (!VectorObject_Check(v1) || !VectorObject_Check(v2)) { PyErr_Format(PyExc_AttributeError, @@ -956,9 +1357,18 @@ return NULL; } + vec = PyMem_Malloc(vec1->size * sizeof(float)); + + if (vec == NULL) { /*allocation failure*/ + PyErr_SetString(PyExc_MemoryError, + "Vector(): " + "problem allocating pointer space"); + return NULL; + } + add_vn_vnvn(vec, vec1->vec, vec2->vec, vec1->size); - return Vector_CreatePyObject(vec, vec1->size, Py_NEW, Py_TYPE(v1)); + return Vector_CreatePyObject_alloc(vec, vec1->size, Py_TYPE(v1)); } /* addition in-place: obj += obj */ @@ -997,7 +1407,7 @@ static PyObject *Vector_sub(PyObject *v1, PyObject *v2) { VectorObject *vec1 = NULL, *vec2 = NULL; - float vec[MAX_DIMENSIONS]; + float *vec; if (!VectorObject_Check(v1) || !VectorObject_Check(v2)) { PyErr_Format(PyExc_AttributeError, @@ -1019,15 +1429,24 @@ return NULL; } + vec = PyMem_Malloc(vec1->size * sizeof(float)); + + if (vec == NULL) { /*allocation failure*/ + PyErr_SetString(PyExc_MemoryError, + "Vector(): " + "problem allocating pointer space"); + return NULL; + } + sub_vn_vnvn(vec, vec1->vec, vec2->vec, vec1->size); - return Vector_CreatePyObject(vec, vec1->size, Py_NEW, Py_TYPE(v1)); + return Vector_CreatePyObject_alloc(vec, vec1->size, Py_TYPE(v1)); } /* subtraction in-place: obj -= obj */ static PyObject *Vector_isub(PyObject *v1, PyObject *v2) { - VectorObject *vec1= NULL, *vec2= NULL; + VectorObject *vec1 = NULL, *vec2 = NULL; if (!VectorObject_Check(v1) || !VectorObject_Check(v2)) { PyErr_Format(PyExc_AttributeError, @@ -1060,43 +1479,42 @@ mulplication*/ -/* COLUMN VECTOR Multiplication (Vector X Matrix) - * [a] * [1][4][7] - * [b] * [2][5][8] - * [c] * [3][6][9] +/* COLUMN VECTOR Multiplication (Matrix X Vector) + * [1][4][7] [a] + * [2][5][8] * [b] + * [3][6][9] [c] * * note: vector/matrix multiplication IS NOT COMMUTATIVE!!!! * note: assume read callbacks have been done first. */ -int column_vector_multiplication(float rvec[MAX_DIMENSIONS], VectorObject* vec, MatrixObject * mat) +int column_vector_multiplication(float r_vec[MAX_DIMENSIONS], VectorObject *vec, MatrixObject *mat) { float vec_cpy[MAX_DIMENSIONS]; - double dot = 0.0f; - int x, y, z = 0; + int row, col, z = 0; - if (mat->row_size != vec->size) { - if (mat->row_size == 4 && vec->size == 3) { + if (mat->num_col != vec->size) { + if (mat->num_col == 4 && vec->size == 3) { vec_cpy[3] = 1.0f; } else { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_ValueError, "matrix * vector: " - "matrix.row_size and len(vector) must be the same, " - "except for 3D vector * 4x4 matrix."); + "len(matrix.col) and len(vector) must be the same, " + "except for 4x4 matrix * 3D vector."); return -1; } } memcpy(vec_cpy, vec->vec, vec->size * sizeof(float)); - rvec[3] = 1.0f; + r_vec[3] = 1.0f; - for (x = 0; x < mat->col_size; x++) { - for (y = 0; y < mat->row_size; y++) { - dot += (double)(mat->matrix[y][x] * vec_cpy[y]); + for (row = 0; row < mat->num_row; row++) { + double dot = 0.0f; + for (col = 0; col < mat->num_col; col++) { + dot += (double)(MATRIX_ITEM(mat, row, col) * vec_cpy[col]); } - rvec[z++] = (float)dot; - dot = 0.0f; + r_vec[z++] = (float)dot; } return 0; @@ -1104,23 +1522,32 @@ static PyObject *vector_mul_float(VectorObject *vec, const float scalar) { - float tvec[MAX_DIMENSIONS]; + float *tvec = PyMem_Malloc(vec->size * sizeof(float)); + + if (tvec == NULL) { /*allocation failure*/ + PyErr_SetString(PyExc_MemoryError, + "vec * float: " + "problem allocating pointer space"); + return NULL; + } + mul_vn_vn_fl(tvec, vec->vec, vec->size, scalar); - return Vector_CreatePyObject(tvec, vec->size, Py_NEW, Py_TYPE(vec)); + return Vector_CreatePyObject_alloc(tvec, vec->size, Py_TYPE(vec)); } static PyObject *Vector_mul(PyObject *v1, PyObject *v2) { VectorObject *vec1 = NULL, *vec2 = NULL; float scalar; + int vec_size; if VectorObject_Check(v1) { - vec1= (VectorObject *)v1; + vec1 = (VectorObject *)v1; if (BaseMath_ReadCallback(vec1) == -1) return NULL; } if VectorObject_Check(v2) { - vec2= (VectorObject *)v2; + vec2 = (VectorObject *)v2; if (BaseMath_ReadCallback(vec2) == -1) return NULL; } @@ -1149,7 +1576,14 @@ return NULL; } - return Vector_CreatePyObject(tvec, vec1->size, Py_NEW, Py_TYPE(vec1)); + if (((MatrixObject *)v2)->num_row == 4 && vec1->size == 3) { + vec_size = 3; + } + else { + vec_size = ((MatrixObject *)v2)->num_col; + } + + return Vector_CreatePyObject(tvec, vec_size, Py_NEW, Py_TYPE(vec1)); } else if (QuaternionObject_Check(v2)) { /* VEC * QUAT */ @@ -1179,12 +1613,12 @@ #endif /* ------ to be removed ------*/ } - else if (((scalar= PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred())==0) { /* VEC * FLOAT */ + else if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* VEC * FLOAT */ return vector_mul_float(vec1, scalar); } } else if (vec2) { - if (((scalar= PyFloat_AsDouble(v1)) == -1.0f && PyErr_Occurred())==0) { /* FLOAT * VEC */ + if (((scalar = PyFloat_AsDouble(v1)) == -1.0f && PyErr_Occurred()) == 0) { /* FLOAT * VEC */ return vector_mul_float(vec2, scalar); } } @@ -1258,7 +1692,7 @@ #endif /* ------ to be removed ------*/ } - else if (((scalar= PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred())==0) { /* VEC *= FLOAT */ + else if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* VEC *= FLOAT */ mul_vn_fl(vec->vec, vec->size, scalar); } else { @@ -1277,8 +1711,7 @@ /* divid: obj / obj */ static PyObject *Vector_div(PyObject *v1, PyObject *v2) { - int i; - float vec[4], scalar; + float *vec = NULL, scalar; VectorObject *vec1 = NULL; if (!VectorObject_Check(v1)) { /* not a vector */ @@ -1287,57 +1720,63 @@ "Vector must be divided by a float"); return NULL; } - vec1 = (VectorObject*)v1; /* vector */ + vec1 = (VectorObject *)v1; /* vector */ if (BaseMath_ReadCallback(vec1) == -1) return NULL; - if ((scalar=PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) { /* parsed item not a number */ + if ((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) { /* parsed item not a number */ PyErr_SetString(PyExc_TypeError, "Vector division: " "Vector must be divided by a float"); return NULL; } - if (scalar==0.0f) { + if (scalar == 0.0f) { PyErr_SetString(PyExc_ZeroDivisionError, "Vector division: " "divide by zero error"); return NULL; } - for (i = 0; i < vec1->size; i++) { - vec[i] = vec1->vec[i] / scalar; + vec = PyMem_Malloc(vec1->size * sizeof(float)); + + if (vec == NULL) { /*allocation failure*/ + PyErr_SetString(PyExc_MemoryError, + "vec / value: " + "problem allocating pointer space"); + return NULL; } - return Vector_CreatePyObject(vec, vec1->size, Py_NEW, Py_TYPE(v1)); + + mul_vn_vn_fl(vec, vec1->vec, vec1->size, 1.0f / scalar); + + return Vector_CreatePyObject_alloc(vec, vec1->size, Py_TYPE(v1)); } /* divide in-place: obj /= obj */ static PyObject *Vector_idiv(PyObject *v1, PyObject *v2) { - int i; float scalar; VectorObject *vec1 = (VectorObject*)v1; if (BaseMath_ReadCallback(vec1) == -1) return NULL; - if ((scalar=PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) { /* parsed item not a number */ + if ((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) { /* parsed item not a number */ PyErr_SetString(PyExc_TypeError, "Vector division: " "Vector must be divided by a float"); return NULL; } - if (scalar==0.0f) { + if (scalar == 0.0f) { PyErr_SetString(PyExc_ZeroDivisionError, "Vector division: " "divide by zero error"); return NULL; } - for (i = 0; i < vec1->size; i++) { - vec1->vec[i] /= scalar; - } + + mul_vn_fl(vec1->vec, vec1->size, 1.0f / scalar); (void)BaseMath_WriteCallback(vec1); @@ -1349,35 +1788,30 @@ returns the negative of this object*/ static PyObject *Vector_neg(VectorObject *self) { - float tvec[MAX_DIMENSIONS]; + float *tvec; if (BaseMath_ReadCallback(self) == -1) return NULL; + tvec = PyMem_Malloc(self->size * sizeof(float)); negate_vn_vn(tvec, self->vec, self->size); - return Vector_CreatePyObject(tvec, self->size, Py_NEW, Py_TYPE(self)); + return Vector_CreatePyObject_alloc(tvec, self->size, Py_TYPE(self)); } /*------------------------vec_magnitude_nosqrt (internal) - for comparing only */ static double vec_magnitude_nosqrt(float *data, int size) { - double dot = 0.0f; - int i; - - for (i=0; isize; i++) { - dot += (double)(self->vec[i] * self->vec[i]); - } - return PyFloat_FromDouble(sqrt(dot)); + return PyFloat_FromDouble(sqrt(dot_vn_vn(self->vec, self->vec, self->size))); } -static int Vector_setLength(VectorObject *self, PyObject *value) +static int Vector_length_set(VectorObject *self, PyObject *value) { double dot = 0.0f, param; if (BaseMath_ReadCallback(self) == -1) return -1; - if ((param=PyFloat_AsDouble(value)) == -1.0 && PyErr_Occurred()) { + if ((param = PyFloat_AsDouble(value)) == -1.0 && PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "length must be set to a number"); return -1; @@ -1641,19 +2076,19 @@ return 0; } - dot= dot_vn_vn(self->vec, self->vec, self->size); + dot = dot_vn_vn(self->vec, self->vec, self->size); if (!dot) /* cant sqrt zero */ return 0; dot = sqrt(dot); - if (dot==param) + if (dot == param) return 0; - dot= dot/param; + dot = dot / param; - mul_vn_fl(self->vec, self->size, 1.0/dot); + mul_vn_fl(self->vec, self->size, 1.0 / dot); (void)BaseMath_WriteCallback(self); /* checked already */ @@ -1661,7 +2096,10 @@ } /* vector.length_squared */ -static PyObject *Vector_getLengthSquared(VectorObject *self, void *UNUSED(closure)) +PyDoc_STRVAR(Vector_length_squared_doc, +"Vector length squared (v.dot(v)).\n\n:type: float" +); +static PyObject *Vector_length_squared_get(VectorObject *self, void *UNUSED(closure)) { if (BaseMath_ReadCallback(self) == -1) return NULL; @@ -1670,9 +2108,9 @@ } /* Get a new Vector according to the provided swizzle. This function has little - error checking, as we are in control of the inputs: the closure is set by us - in Vector_createSwizzleGetSeter. */ -static PyObject *Vector_getSwizzle(VectorObject *self, void *closure) + * error checking, as we are in control of the inputs: the closure is set by us + * in Vector_createSwizzleGetSeter. */ +static PyObject *Vector_swizzle_get(VectorObject *self, void *closure) { size_t axis_to; size_t axis_from; @@ -1685,8 +2123,7 @@ /* Unpack the axes from the closure into an array. */ axis_to = 0; swizzleClosure = GET_INT_FROM_POINTER(closure); - while (swizzleClosure & SWIZZLE_VALID_AXIS) - { + while (swizzleClosure & SWIZZLE_VALID_AXIS) { axis_from = swizzleClosure & SWIZZLE_AXIS; if (axis_from >= self->size) { PyErr_SetString(PyExc_AttributeError, @@ -1704,16 +2141,16 @@ } /* Set the items of this vector using a swizzle. - - If value is a vector or list this operates like an array copy, except that - the destination is effectively re-ordered as defined by the swizzle. At - most min(len(source), len(dest)) values will be copied. - - If the value is scalar, it is copied to all axes listed in the swizzle. - - If an axis appears more than once in the swizzle, the final occurrence is - the one that determines its value. - - Returns 0 on success and -1 on failure. On failure, the vector will be - unchanged. */ -static int Vector_setSwizzle(VectorObject *self, PyObject *value, void *closure) + * - If value is a vector or list this operates like an array copy, except that + * the destination is effectively re-ordered as defined by the swizzle. At + * most min(len(source), len(dest)) values will be copied. + * - If the value is scalar, it is copied to all axes listed in the swizzle. + * - If an axis appears more than once in the swizzle, the final occurrence is + * the one that determines its value. + + * Returns 0 on success and -1 on failure. On failure, the vector will be + * unchanged. */ +static int Vector_swizzle_set(VectorObject *self, PyObject *value, void *closure) { size_t size_from; float scalarVal; @@ -1730,13 +2167,13 @@ return -1; /* Check that the closure can be used with this vector: even 2D vectors have - swizzles defined for axes z and w, but they would be invalid. */ + * swizzles defined for axes z and w, but they would be invalid. */ swizzleClosure = GET_INT_FROM_POINTER(closure); - axis_from= 0; + axis_from = 0; + while (swizzleClosure & SWIZZLE_VALID_AXIS) { axis_to = swizzleClosure & SWIZZLE_AXIS; - if (axis_to >= self->size) - { + if (axis_to >= self->size) { PyErr_SetString(PyExc_AttributeError, "Vector swizzle: " "specified axis not present"); @@ -1746,15 +2183,17 @@ axis_from++; } - if (((scalarVal=PyFloat_AsDouble(value)) == -1 && PyErr_Occurred())==0) { + if (((scalarVal = PyFloat_AsDouble(value)) == -1 && PyErr_Occurred()) == 0) { int i; - for (i=0; i < MAX_DIMENSIONS; i++) - vec_assign[i]= scalarVal; - size_from= axis_from; + for (i = 0; i < MAX_DIMENSIONS; i++) { + vec_assign[i] = scalarVal; + } + + size_from = axis_from; } else if ( (PyErr_Clear()), /* run but ignore the result */ - (size_from=mathutils_array_parse(vec_assign, 2, 4, value, + (size_from = mathutils_array_parse(vec_assign, 2, 4, value, "mathutils.Vector.**** = swizzle assignment")) == -1) { return -1; @@ -1769,8 +2208,8 @@ /* Copy vector contents onto swizzled axes. */ axis_from = 0; swizzleClosure = GET_INT_FROM_POINTER(closure); - while (swizzleClosure & SWIZZLE_VALID_AXIS) - { + + while (swizzleClosure & SWIZZLE_VALID_AXIS) { axis_to = swizzleClosure & SWIZZLE_AXIS; tvec[axis_to] = vec_assign[axis_from]; swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS; @@ -1790,353 +2229,353 @@ /* Python attributes get/set structure: */ /*****************************************************************************/ static PyGetSetDef Vector_getseters[] = { - {(char *)"x", (getter)Vector_getAxis, (setter)Vector_setAxis, (char *)"Vector X axis.\n\n:type: float", (void *)0}, - {(char *)"y", (getter)Vector_getAxis, (setter)Vector_setAxis, (char *)"Vector Y axis.\n\n:type: float", (void *)1}, - {(char *)"z", (getter)Vector_getAxis, (setter)Vector_setAxis, (char *)"Vector Z axis (3D Vectors only).\n\n:type: float", (void *)2}, - {(char *)"w", (getter)Vector_getAxis, (setter)Vector_setAxis, (char *)"Vector W axis (4D Vectors only).\n\n:type: float", (void *)3}, - {(char *)"length", (getter)Vector_getLength, (setter)Vector_setLength, (char *)"Vector Length.\n\n:type: float", NULL}, - {(char *)"length_squared", (getter)Vector_getLengthSquared, (setter)NULL, (char *)"Vector length squared (v.dot(v)).\n\n:type: float", NULL}, - {(char *)"magnitude", (getter)Vector_getLength, (setter)Vector_setLength, (char *)"Vector Length.\n\n:type: float", NULL}, - {(char *)"is_wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, (char *)BaseMathObject_Wrapped_doc, NULL}, - {(char *)"owner", (getter)BaseMathObject_getOwner, (setter)NULL, (char *)BaseMathObject_Owner_doc, NULL}, + {(char *)"x", (getter)Vector_axis_get, (setter)Vector_axis_set, Vector_axis_x_doc, (void *)0}, + {(char *)"y", (getter)Vector_axis_get, (setter)Vector_axis_set, Vector_axis_y_doc, (void *)1}, + {(char *)"z", (getter)Vector_axis_get, (setter)Vector_axis_set, Vector_axis_z_doc, (void *)2}, + {(char *)"w", (getter)Vector_axis_get, (setter)Vector_axis_set, Vector_axis_w_doc, (void *)3}, + {(char *)"length", (getter)Vector_length_get, (setter)Vector_length_set, Vector_length_doc, NULL}, + {(char *)"length_squared", (getter)Vector_length_squared_get, (setter)NULL, Vector_length_squared_doc, NULL}, + {(char *)"magnitude", (getter)Vector_length_get, (setter)Vector_length_set, Vector_length_doc, NULL}, + {(char *)"is_wrapped", (getter)BaseMathObject_is_wrapped_get, (setter)NULL, BaseMathObject_is_wrapped_doc, NULL}, + {(char *)"owner", (getter)BaseMathObject_owner_get, (setter)NULL, BaseMathObject_owner_doc, NULL}, /* autogenerated swizzle attrs, see python script below */ - {(char *)"xx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<2: for axis_2 in axises: axis_2_pos = axis_pos[axis_2] - axis_dict[axis_0+axis_1+axis_2] = '((%s|SWIZZLE_VALID_AXIS) | ((%s|SWIZZLE_VALID_AXIS)<3: for axis_3 in axises: axis_3_pos = axis_pos[axis_3] - axis_dict[axis_0+axis_1+axis_2+axis_3] = '((%s|SWIZZLE_VALID_AXIS) | ((%s|SWIZZLE_VALID_AXIS)<size; + int row, col, z = 0, vec_size = vec->size; - if (mat->col_size != vec_size) { - if (mat->col_size == 4 && vec_size != 3) { + if (mat->num_row != vec_size) { + if (mat->num_row == 4 && vec_size == 3) { + vec_cpy[3] = 1.0f; + } + else { PyErr_SetString(PyExc_ValueError, "vector * matrix: matrix column size " "and the vector size must be the same"); return -1; } - else { - vec_cpy[3] = 1.0f; - } } if (BaseMath_ReadCallback(vec) == -1 || BaseMath_ReadCallback(mat) == -1) @@ -2209,14 +2647,14 @@ memcpy(vec_cpy, vec->vec, vec_size * sizeof(float)); - rvec[3] = 1.0f; + r_vec[3] = 1.0f; //muliplication - for (x = 0; x < mat->row_size; x++) { - for (y = 0; y < mat->col_size; y++) { - dot += mat->matrix[x][y] * vec_cpy[y]; + for (col = 0; col < mat->num_col; col++) { + double dot = 0.0; + for (row = 0; row < mat->num_row; row++) { + dot += MATRIX_ITEM(mat, row, col) * vec_cpy[row]; } - rvec[z++] = (float)dot; - dot = 0.0f; + r_vec[z++] = (float)dot; } return 0; } @@ -2226,9 +2664,6 @@ ".. method:: negate()\n" "\n" " Set all values to their negative.\n" -"\n" -" :return: an instance of itself\n" -" :rtype: :class:`Vector`\n" ); static PyObject *Vector_negate(VectorObject *self) { @@ -2242,6 +2677,12 @@ } static struct PyMethodDef Vector_methods[] = { + /* Class Methods */ + {"Fill", (PyCFunction) C_Vector_Fill, METH_VARARGS | METH_CLASS, C_Vector_Fill_doc}, + {"Range", (PyCFunction) C_Vector_Range, METH_VARARGS | METH_CLASS, C_Vector_Range_doc}, + {"Linspace", (PyCFunction) C_Vector_Linspace, METH_VARARGS | METH_CLASS, C_Vector_Linspace_doc}, + {"Repeat", (PyCFunction) C_Vector_Repeat, METH_VARARGS | METH_CLASS, C_Vector_Repeat_doc}, + /* in place only */ {"zero", (PyCFunction) Vector_zero, METH_NOARGS, Vector_zero_doc}, {"negate", (PyCFunction) Vector_negate, METH_NOARGS, Vector_negate_doc}, @@ -2250,6 +2691,8 @@ {"normalize", (PyCFunction) Vector_normalize, METH_NOARGS, Vector_normalize_doc}, {"normalized", (PyCFunction) Vector_normalized, METH_NOARGS, Vector_normalized_doc}, + {"resize", (PyCFunction) Vector_resize, METH_O, Vector_resize_doc}, + {"resized", (PyCFunction) Vector_resized, METH_O, Vector_resized_doc}, {"to_2d", (PyCFunction) Vector_to_2d, METH_NOARGS, Vector_to_2d_doc}, {"resize_2d", (PyCFunction) Vector_resize_2d, METH_NOARGS, Vector_resize_2d_doc}, {"to_3d", (PyCFunction) Vector_to_3d, METH_NOARGS, Vector_to_3d_doc}, @@ -2310,7 +2753,7 @@ NULL, /* hashfunc tp_hash; */ NULL, /* ternaryfunc tp_call; */ - NULL, /* reprfunc tp_str; */ + (reprfunc)Vector_str, /* reprfunc tp_str; */ NULL, /* getattrofunc tp_getattro; */ NULL, /* setattrofunc tp_setattro; */ @@ -2375,28 +2818,28 @@ { VectorObject *self; - if (size > 4 || size < 2) { + if (size < 2) { PyErr_SetString(PyExc_RuntimeError, "Vector(): invalid size"); return NULL; } - self= base_type ? (VectorObject *)base_type->tp_alloc(base_type, 0) : - (VectorObject *)PyObject_GC_New(VectorObject, &vector_Type); + self = base_type ? (VectorObject *)base_type->tp_alloc(base_type, 0) : + (VectorObject *)PyObject_GC_New(VectorObject, &vector_Type); if (self) { self->size = size; /* init callbacks as NULL */ - self->cb_user= NULL; - self->cb_type= self->cb_subtype= 0; + self->cb_user = NULL; + self->cb_type = self->cb_subtype = 0; if (type == Py_WRAP) { self->vec = vec; self->wrapped = Py_WRAP; } else if (type == Py_NEW) { - self->vec= PyMem_Malloc(size * sizeof(float)); + self->vec = PyMem_Malloc(size * sizeof(float)); if (vec) { memcpy(self->vec, vec, size * sizeof(float)); } @@ -2418,14 +2861,23 @@ PyObject *Vector_CreatePyObject_cb(PyObject *cb_user, int size, int cb_type, int cb_subtype) { float dummy[4] = {0.0, 0.0, 0.0, 0.0}; /* dummy init vector, callbacks will be used on access */ - VectorObject *self= (VectorObject *)Vector_CreatePyObject(dummy, size, Py_NEW, NULL); + VectorObject *self = (VectorObject *)Vector_CreatePyObject(dummy, size, Py_NEW, NULL); if (self) { Py_INCREF(cb_user); - self->cb_user= cb_user; - self->cb_type= (unsigned char)cb_type; - self->cb_subtype= (unsigned char)cb_subtype; + self->cb_user = cb_user; + self->cb_type = (unsigned char)cb_type; + self->cb_subtype = (unsigned char)cb_subtype; PyObject_GC_Track(self); } return (PyObject *)self; } + +PyObject *Vector_CreatePyObject_alloc(float *vec, const int size, PyTypeObject *base_type) +{ + VectorObject *vect_ob; + vect_ob = (VectorObject *)Vector_CreatePyObject(vec, size, Py_WRAP, base_type); + vect_ob->wrapped = Py_NEW; + + return (PyObject *)vect_ob; +} diff -Nru blender-2.61/source/blender/python/mathutils/mathutils_Vector.h blender-2.62/source/blender/python/mathutils/mathutils_Vector.h --- blender-2.61/source/blender/python/mathutils/mathutils_Vector.h 2011-12-13 19:48:32.000000000 +0000 +++ blender-2.62/source/blender/python/mathutils/mathutils_Vector.h 2012-02-15 19:33:13.000000000 +0000 @@ -41,11 +41,12 @@ typedef struct { BASE_MATH_MEMBERS(vec); - unsigned char size; /* vec size 2,3 or 4 */ + int size; /* vec size 2,3 or 4 */ } VectorObject; /*prototypes*/ PyObject *Vector_CreatePyObject(float *vec, const int size, const int type, PyTypeObject *base_type); PyObject *Vector_CreatePyObject_cb(PyObject *user, int size, int callback_type, int subtype); +PyObject *Vector_CreatePyObject_alloc(float *vec, const int size, PyTypeObject *base_type); #endif /* MATHUTILS_VECTOR_H */ diff -Nru blender-2.61/source/blender/python/rna_dump.py blender-2.62/source/blender/python/rna_dump.py --- blender-2.61/source/blender/python/rna_dump.py 2011-12-13 19:48:33.000000000 +0000 +++ blender-2.62/source/blender/python/rna_dump.py 2012-02-15 19:33:14.000000000 +0000 @@ -79,7 +79,7 @@ except: keys = None - if keys != None: + if keys is not None: if PRINT_DATA: print(txt + '.keys() - ' + str(r.keys())) diff -Nru blender-2.61/source/blender/python/SConscript blender-2.62/source/blender/python/SConscript --- blender-2.61/source/blender/python/SConscript 2011-12-13 19:48:33.000000000 +0000 +++ blender-2.62/source/blender/python/SConscript 2012-02-15 19:33:14.000000000 +0000 @@ -6,7 +6,7 @@ incs = '. ../editors/include ../makesdna ../makesrna ../blenfont ../blenlib ../blenkernel ../nodes' incs += ' ../imbuf ../blenloader ../gpu ../render/extern/include ../windowmanager' -incs += ' #intern/guardedalloc #intern/memutil #extern/glew/include' +incs += ' #intern/guardedalloc #intern/memutil #extern/glew/include #intern/cycles/blender' incs += ' #intern/audaspace/intern ' + env['BF_PYTHON_INC'] is_debug = (env['OURPLATFORM'] in ('win32-mingw', 'win32-vc','win64-vc') and env['BF_DEBUG']) @@ -46,5 +46,9 @@ if env['WITH_BF_CYCLES']: defs.append('WITH_CYCLES') +if env['WITH_BF_FFMPEG']: + defs.append('WITH_FFMPEG') + incs += ' ' + env['BF_FFMPEG_INC'] + sources = env.Glob('intern/*.c') env.BlenderLib( libname = 'bf_python', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core'], priority = [361]) diff -Nru blender-2.61/source/blender/quicktime/apple/qtkit_export.m blender-2.62/source/blender/quicktime/apple/qtkit_export.m --- blender-2.61/source/blender/quicktime/apple/qtkit_export.m 2011-12-13 19:49:48.000000000 +0000 +++ blender-2.62/source/blender/quicktime/apple/qtkit_export.m 2012-02-15 19:34:33.000000000 +0000 @@ -106,23 +106,29 @@ /* Video codec */ static QuicktimeCodecTypeDesc qtVideoCodecList[] = { {kRawCodecType, 1, "Uncompressed"}, - {kJPEGCodecType, 2, "JPEG"}, - {kMotionJPEGACodecType, 3, "M-JPEG A"}, - {kMotionJPEGBCodecType, 4, "M-JPEG B"}, - {kDVCPALCodecType, 5, "DV PAL"}, - {kDVCNTSCCodecType, 6, "DV/DVCPRO NTSC"}, - {kDVCPROHD720pCodecType, 7, "DVCPRO HD 720p"}, - {kDVCPROHD1080i50CodecType, 8, "DVCPRO HD 1080i50"}, - {kDVCPROHD1080i60CodecType, 9, "DVCPRO HD 1080i60"}, - {kMPEG4VisualCodecType, 10, "MPEG4"}, - {kH263CodecType, 11, "H.263"}, - {kH264CodecType, 12, "H.264"}, - {kAnimationCodecType, 13, "Animation"}, + {k422YpCbCr8CodecType, 2, "Uncompressed 8-bit 4:2:2"}, + {k422YpCbCr10CodecType, 3, "Uncompressed 10-bit 4:2:2"}, + {kComponentVideoCodecType, 4, "Component Video"}, + {kPixletCodecType, 5, "Pixlet"}, + {kPNGCodecType, 6, "PNG"}, + {kJPEGCodecType, 7, "JPEG"}, + {kMotionJPEGACodecType, 8, "M-JPEG A"}, + {kMotionJPEGBCodecType, 9, "M-JPEG B"}, + {kDVCPALCodecType, 10, "DV PAL"}, + {kDVCNTSCCodecType, 11, "DV/DVCPRO NTSC"}, + {kDVCPROHD720pCodecType, 12, "DVCPRO HD 720p"}, + {kDVCPROHD1080i50CodecType, 13, "DVCPRO HD 1080i50"}, + {kDVCPROHD1080i60CodecType, 14, "DVCPRO HD 1080i60"}, + {kMPEG4VisualCodecType, 15, "MPEG4"}, + {kH263CodecType, 16, "H.263"}, + {kH264CodecType, 17, "H.264"}, + {kAnimationCodecType, 18, "Animation"}, {0,0,NULL}}; -static int qtVideoCodecCount = 13; +static int qtVideoCodecCount = 18; -int quicktime_get_num_videocodecs() { +int quicktime_get_num_videocodecs() +{ return qtVideoCodecCount; } @@ -133,7 +139,8 @@ return NULL; } -int quicktime_rnatmpvalue_from_videocodectype(int codecType) { +int quicktime_rnatmpvalue_from_videocodectype(int codecType) +{ int i; for (i=0;ipic); @@ -218,7 +231,8 @@ } } -void filepath_qt(char *string, RenderData *rd) { +void filepath_qt(char *string, RenderData *rd) +{ if (string==NULL) return; strcpy(string, rd->pic); @@ -581,8 +595,7 @@ return success; } - -int append_qt(struct RenderData *rd, int frame, int *pixels, int rectx, int recty, ReportList *reports) +int append_qt(struct RenderData *rd, int start_frame, int frame, int *pixels, int rectx, int recty, ReportList *reports) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSBitmapImageRep *blBitmapFormatImage; @@ -591,7 +604,6 @@ unsigned char *from_Ptr,*to_Ptr; int y,from_i,to_i; - /* Create bitmap image rep in blender format (32bit RGBA) */ blBitmapFormatImage = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL pixelsWide:rectx @@ -658,7 +670,7 @@ } else { //Error getting audio packets - BKE_reportf(reports, RPT_ERROR, "Unable to get further audio packets from frame %i, error = 0x%x",qtexport->audioTotalExportedFrames,err); + BKE_reportf(reports, RPT_ERROR, "Unable to get further audio packets from frame %i, error = 0x%x",(int)qtexport->audioTotalExportedFrames,err); break; } @@ -774,12 +786,13 @@ } -void free_qtcomponentdata(void) { +void free_qtcomponentdata(void) +{ } -void quicktime_verify_image_type(RenderData *rd) +void quicktime_verify_image_type(RenderData *rd, ImageFormatData *imf) { - if (rd->imtype == R_IMF_IMTYPE_QUICKTIME) { + if (imf->imtype == R_IMF_IMTYPE_QUICKTIME) { if ((rd->qtcodecsettings.codecType<= 0) || (rd->qtcodecsettings.codecSpatialQuality <0) || (rd->qtcodecsettings.codecSpatialQuality > 100)) { diff -Nru blender-2.61/source/blender/quicktime/apple/qtkit_import.m blender-2.62/source/blender/quicktime/apple/qtkit_import.m --- blender-2.61/source/blender/quicktime/apple/qtkit_import.m 2011-12-13 19:49:48.000000000 +0000 +++ blender-2.62/source/blender/quicktime/apple/qtkit_import.m 2012-02-15 19:34:33.000000000 +0000 @@ -86,6 +86,9 @@ BLI_testextensie(name, ".txt") || BLI_testextensie(name, ".mpg") || BLI_testextensie(name, ".avi") || // wouldnt be appropriate ;) + BLI_testextensie(name, ".mov") || // disabled, suboptimal decoding speed + BLI_testextensie(name, ".mp4") || // disabled, suboptimal decoding speed + BLI_testextensie(name, ".m4v") || // disabled, suboptimal decoding speed BLI_testextensie(name, ".tga") || BLI_testextensie(name, ".png") || BLI_testextensie(name, ".bmp") || @@ -112,7 +115,8 @@ } -void free_anim_quicktime (struct anim *anim) { +void free_anim_quicktime (struct anim *anim) +{ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; if (anim == NULL) return; diff -Nru blender-2.61/source/blender/quicktime/apple/quicktime_export.c blender-2.62/source/blender/quicktime/apple/quicktime_export.c --- blender-2.61/source/blender/quicktime/apple/quicktime_export.c 2011-12-13 19:49:48.000000000 +0000 +++ blender-2.62/source/blender/quicktime/apple/quicktime_export.c 2012-02-15 19:34:33.000000000 +0000 @@ -148,7 +148,8 @@ static int qtVideoCodecCount = 12; -int quicktime_get_num_videocodecs() { +int quicktime_get_num_videocodecs() +{ return qtVideoCodecCount; } @@ -159,7 +160,8 @@ return NULL; } -int quicktime_rnatmpvalue_from_videocodectype(int codecType) { +int quicktime_rnatmpvalue_from_videocodectype(int codecType) +{ int i; for (i=0;itheComponent) CloseComponent(qtdata->theComponent); MEM_freeN(qtdata); @@ -687,9 +695,9 @@ } } -void quicktime_verify_image_type(RenderData *rd) +void quicktime_verify_image_type(RenderData *rd, ImageFormatData *imf) { - if (rd->imtype == R_IMF_IMTYPE_QUICKTIME) { + if (imf->imtype == R_IMF_IMTYPE_QUICKTIME) { if ((rd->qtcodecsettings.codecType== 0) || (rd->qtcodecsettings.codecSpatialQuality <0) || (rd->qtcodecsettings.codecSpatialQuality > 100)) { diff -Nru blender-2.61/source/blender/quicktime/apple/quicktime_import.c blender-2.62/source/blender/quicktime/apple/quicktime_import.c --- blender-2.61/source/blender/quicktime/apple/quicktime_import.c 2011-12-13 19:49:48.000000000 +0000 +++ blender-2.62/source/blender/quicktime/apple/quicktime_import.c 2012-02-15 19:34:33.000000000 +0000 @@ -41,6 +41,7 @@ #include "BLO_sys_types.h" #include "BKE_global.h" #include "BLI_dynstr.h" +#include "BLI_path_util.h" #ifdef __APPLE__ #include @@ -249,7 +250,8 @@ } -void free_anim_quicktime (struct anim *anim) { +void free_anim_quicktime (struct anim *anim) +{ if (anim == NULL) return; if (anim->qtime == NULL) return; diff -Nru blender-2.61/source/blender/quicktime/quicktime_export.h blender-2.62/source/blender/quicktime/quicktime_export.h --- blender-2.61/source/blender/quicktime/quicktime_export.h 2011-12-13 19:49:48.000000000 +0000 +++ blender-2.62/source/blender/quicktime/quicktime_export.h 2012-02-15 19:34:33.000000000 +0000 @@ -50,18 +50,19 @@ } QuicktimeCodecTypeDesc ; // quicktime movie output functions +struct ImageFormatData; struct RenderData; +struct ReportList; struct Scene; struct wmOperatorType; -struct ReportList; int start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty, struct ReportList *reports); //for movie handle (BKE writeavi.c now) -int append_qt(struct RenderData *rd, int frame, int *pixels, int rectx, int recty, struct ReportList *reports); +int append_qt(struct RenderData *rd, int start_frame, int frame, int *pixels, int rectx, int recty, struct ReportList *reports); void end_qt(void); void filepath_qt(char *string, struct RenderData *rd); /*RNA helper functions */ -void quicktime_verify_image_type(struct RenderData *rd); //used by RNA for defaults values init, if needed +void quicktime_verify_image_type(struct RenderData *rd, struct ImageFormatData *imf); //used by RNA for defaults values init, if needed /*Video codec type*/ int quicktime_get_num_videocodecs(void); QuicktimeCodecTypeDesc* quicktime_get_videocodecType_desc(int indexValue); diff -Nru blender-2.61/source/blender/render/CMakeLists.txt blender-2.62/source/blender/render/CMakeLists.txt --- blender-2.61/source/blender/render/CMakeLists.txt 2011-12-13 19:48:20.000000000 +0000 +++ blender-2.62/source/blender/render/CMakeLists.txt 2012-02-15 19:33:02.000000000 +0000 @@ -66,6 +66,7 @@ intern/source/pointdensity.c intern/source/rayshade.c intern/source/rendercore.c + intern/source/render_result.c intern/source/render_texture.c intern/source/renderdatabase.c intern/source/shadbuf.c @@ -96,6 +97,7 @@ intern/include/rayintersection.h intern/include/raycounter.h intern/include/render_types.h + intern/include/render_result.h intern/include/rendercore.h intern/include/renderdatabase.h intern/include/renderpipeline.h diff -Nru blender-2.61/source/blender/render/extern/include/RE_pipeline.h blender-2.62/source/blender/render/extern/include/RE_pipeline.h --- blender-2.61/source/blender/render/extern/include/RE_pipeline.h 2011-12-13 19:48:19.000000000 +0000 +++ blender-2.62/source/blender/render/extern/include/RE_pipeline.h 2012-02-15 19:33:01.000000000 +0000 @@ -182,9 +182,6 @@ /* obligatory initialize call, disprect is optional */ void RE_InitState (struct Render *re, struct Render *source, struct RenderData *rd, struct SceneRenderLayer *srl, int winx, int winy, rcti *disprect); -/* use this to change disprect of active render */ -void RE_SetDispRect (struct Render *re, rcti *disprect); - /* set up the viewplane/perspective matrix, three choices */ struct Object *RE_GetCamera(struct Render *re); /* return camera override if set */ void RE_SetCamera(struct Render *re, struct Object *camera); diff -Nru blender-2.61/source/blender/render/extern/include/RE_shader_ext.h blender-2.62/source/blender/render/extern/include/RE_shader_ext.h --- blender-2.61/source/blender/render/extern/include/RE_shader_ext.h 2011-12-13 19:48:19.000000000 +0000 +++ blender-2.62/source/blender/render/extern/include/RE_shader_ext.h 2012-02-15 19:33:01.000000000 +0000 @@ -210,4 +210,8 @@ struct Image *RE_bake_shade_get_image(void); void RE_bake_ibuf_filter(struct ImBuf *ibuf, char *mask, const int filter); +#define BAKE_RESULT_OK 0 +#define BAKE_RESULT_NO_OBJECTS 1 +#define BAKE_RESULT_FEEDBACK_LOOP 2 + #endif /* RE_SHADER_EXT_H */ diff -Nru blender-2.61/source/blender/render/intern/include/renderpipeline.h blender-2.62/source/blender/render/intern/include/renderpipeline.h --- blender-2.61/source/blender/render/intern/include/renderpipeline.h 2011-12-13 19:48:18.000000000 +0000 +++ blender-2.62/source/blender/render/intern/include/renderpipeline.h 2012-02-15 19:32:58.000000000 +0000 @@ -33,22 +33,12 @@ #ifndef PIPELINE_H #define PIPELINE_H -struct ListBase; struct Render; -struct RenderResult; struct RenderLayer; -struct rcti; +struct RenderResult; struct RenderLayer *render_get_active_layer(struct Render *re, struct RenderResult *rr); float panorama_pixel_rot(struct Render *re); -#define PASS_VECTOR_MAX 10000.0f - -#define RR_USEMEM 0 - -struct RenderResult *new_render_result(struct Render *re, struct rcti *partrct, int crop, int savebuffers); -void merge_render_result(struct RenderResult *rr, struct RenderResult *rrpart); -void free_render_result(struct ListBase *lb, struct RenderResult *rr); - #endif /* PIPELINE_H */ diff -Nru blender-2.61/source/blender/render/intern/include/render_result.h blender-2.62/source/blender/render/intern/include/render_result.h --- blender-2.61/source/blender/render/intern/include/render_result.h 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/source/blender/render/intern/include/render_result.h 2012-02-15 19:32:58.000000000 +0000 @@ -0,0 +1,94 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + * The Original Code is Copyright (C) 2007 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/render/intern/include/render_result.h + * \ingroup render + */ + +#ifndef RENDER_RESULT_H +#define RENDER_RESULT_H + +#define PASS_VECTOR_MAX 10000.0f + +#define RR_USE_MEM 0 +#define RR_USE_EXR 1 + +struct ImBuf; +struct ListBase; +struct Render; +struct RenderData; +struct RenderLayer; +struct RenderResult; +struct Scene; +struct rcti; + +/* New */ + +struct RenderResult *render_result_new(struct Render *re, + struct rcti *partrct, int crop, int savebuffers); +struct RenderResult *render_result_new_full_sample(struct Render *re, + struct ListBase *lb, struct rcti *partrct, int crop, int savebuffers); + +struct RenderResult *render_result_new_from_exr(void *exrhandle, int rectx, int recty); + +/* Merge */ + +void render_result_merge(struct RenderResult *rr, struct RenderResult *rrpart); + +/* Free */ + +void render_result_free(struct RenderResult *rr); +void render_result_free_list(struct ListBase *lb, struct RenderResult *rr); + +/* Single Layer Render */ + +void render_result_single_layer_begin(struct Render *re); +void render_result_single_layer_end(struct Render *re); + +/* EXR Tile File Render */ + +void render_result_exr_file_begin(struct Render *re); +void render_result_exr_file_end(struct Render *re); + +void render_result_exr_file_merge(struct RenderResult *rr, struct RenderResult *rrpart); + +void render_result_exr_file_path(struct Scene *scene, int sample, char *filepath); +int render_result_exr_file_read(struct Render *re, int sample); +int render_result_exr_file_read_path(struct RenderResult *rr, const char *filepath); + +/* Combined Pixel Rect */ + +struct ImBuf *render_result_rect_to_ibuf(struct RenderResult *rr, struct RenderData *rd); +void render_result_rect_from_ibuf(struct RenderResult *rr, struct RenderData *rd, + struct ImBuf *ibuf); + +void render_result_rect_fill_zero(struct RenderResult *rr); +void render_result_rect_get_pixels(struct RenderResult *rr, struct RenderData *rd, + unsigned int *rect, int rectx, int recty); + +#endif /* RENDER_RESULT_H */ + diff -Nru blender-2.61/source/blender/render/intern/include/render_types.h blender-2.62/source/blender/render/intern/include/render_types.h --- blender-2.61/source/blender/render/intern/include/render_types.h 2011-12-13 19:48:18.000000000 +0000 +++ blender-2.62/source/blender/render/intern/include/render_types.h 2012-02-15 19:32:58.000000000 +0000 @@ -36,6 +36,7 @@ /* ------------------------------------------------------------------------- */ #include "DNA_color_types.h" +#include "DNA_customdata_types.h" #include "DNA_scene_types.h" #include "DNA_world_types.h" #include "DNA_object_types.h" @@ -306,8 +307,8 @@ struct HaloRen **bloha; struct StrandBuffer *strandbuf; - char (*mtface)[32]; - char (*mcol)[32]; + char (*mtface)[MAX_CUSTOMDATA_LAYER_NAME]; + char (*mcol)[MAX_CUSTOMDATA_LAYER_NAME]; int actmtface, actmcol, bakemtface; float obmat[4][4]; /* only used in convertblender.c, for instancing */ diff -Nru blender-2.61/source/blender/render/intern/raytrace/rayobject_blibvh.cpp blender-2.62/source/blender/render/intern/raytrace/rayobject_blibvh.cpp --- blender-2.61/source/blender/render/intern/raytrace/rayobject_blibvh.cpp 2011-12-13 19:48:19.000000000 +0000 +++ blender-2.62/source/blender/render/intern/raytrace/rayobject_blibvh.cpp 2012-02-15 19:33:01.000000000 +0000 @@ -46,13 +46,14 @@ static void RE_rayobject_blibvh_free(RayObject *o); static void RE_rayobject_blibvh_bb(RayObject *o, float *min, float *max); -static float RE_rayobject_blibvh_cost(RayObject *o) +static float RE_rayobject_blibvh_cost(RayObject *UNUSED(o)) { //TODO calculate the expected cost to raycast on this structure return 1.0; } -static void RE_rayobject_blibvh_hint_bb(RayObject *o, RayHint *hint, float *min, float *max) +static void RE_rayobject_blibvh_hint_bb(RayObject *UNUSED(o), RayHint *UNUSED(hint), + float *UNUSED(min), float *UNUSED(max)) { return; } @@ -95,7 +96,7 @@ RayObject **leafs; }; -static void bvh_callback(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit) +static void bvh_callback(void *userdata, int index, const BVHTreeRay *UNUSED(ray), BVHTreeRayHit *hit) { struct BVHCallbackUserData *data = (struct BVHCallbackUserData*)userdata; Isect *isec = data->isec; diff -Nru blender-2.61/source/blender/render/intern/raytrace/rayobject.cpp blender-2.62/source/blender/render/intern/raytrace/rayobject.cpp --- blender-2.61/source/blender/render/intern/raytrace/rayobject.cpp 2011-12-13 19:48:19.000000000 +0000 +++ blender-2.62/source/blender/render/intern/raytrace/rayobject.cpp 2012-02-15 19:33:01.000000000 +0000 @@ -50,7 +50,8 @@ because function is too long. Since this is code that is called billions of times we really do want to inline. */ -MALWAYS_INLINE RayObject* rayface_from_coords(RayFace *rayface, void *ob, void *face, float *v1, float *v2, float *v3, float *v4) +MALWAYS_INLINE RayObject* rayface_from_coords(RayFace *rayface, void *ob, void *face, + float *v1, float *v2, float *v3, float *v4) { rayface->ob = ob; rayface->face = face; @@ -118,7 +119,7 @@ return (is->lay & obi->lay); } -MALWAYS_INLINE int vlr_check_intersect_solid(Isect *is, ObjectInstanceRen* obi, VlakRen *vlr) +MALWAYS_INLINE int vlr_check_intersect_solid(Isect *UNUSED(is), ObjectInstanceRen* UNUSED(obi), VlakRen *vlr) { /* solid material types only */ if (vlr->mat->material_type == MA_TYPE_SURFACE) @@ -127,7 +128,7 @@ return 0; } -MALWAYS_INLINE int vlr_check_bake(Isect *is, ObjectInstanceRen* obi, VlakRen *vlr) +MALWAYS_INLINE int vlr_check_bake(Isect *is, ObjectInstanceRen* obi, VlakRen *UNUSED(vlr)) { return (obi->obr->ob != is->userdata); } diff -Nru blender-2.61/source/blender/render/intern/raytrace/rayobject_empty.cpp blender-2.62/source/blender/render/intern/raytrace/rayobject_empty.cpp --- blender-2.61/source/blender/render/intern/raytrace/rayobject_empty.cpp 2011-12-13 19:48:19.000000000 +0000 +++ blender-2.62/source/blender/render/intern/raytrace/rayobject_empty.cpp 2012-02-15 19:33:01.000000000 +0000 @@ -32,30 +32,33 @@ #include "rayobject.h" +#include "BLI_utildefines.h" + /* * Empty raytree */ -static int RE_rayobject_empty_intersect(RayObject *o, Isect *is) +static int RE_rayobject_empty_intersect(RayObject *UNUSED(o), Isect *UNUSED(is)) { return 0; } -static void RE_rayobject_empty_free(RayObject *o) +static void RE_rayobject_empty_free(RayObject *UNUSED(o)) { } -static void RE_rayobject_empty_bb(RayObject *o, float *min, float *max) +static void RE_rayobject_empty_bb(RayObject *UNUSED(o), float *UNUSED(min), float *UNUSED(max)) { return; } -static float RE_rayobject_empty_cost(RayObject *o) +static float RE_rayobject_empty_cost(RayObject *UNUSED(o)) { return 0.0; } -static void RE_rayobject_empty_hint_bb(RayObject *o, RayHint *hint, float *min, float *max) +static void RE_rayobject_empty_hint_bb(RayObject *UNUSED(o), RayHint *UNUSED(hint), + float *UNUSED(min), float *UNUSED(max)) {} static RayObjectAPI empty_api = diff -Nru blender-2.61/source/blender/render/intern/raytrace/rayobject_instance.cpp blender-2.62/source/blender/render/intern/raytrace/rayobject_instance.cpp --- blender-2.61/source/blender/render/intern/raytrace/rayobject_instance.cpp 2011-12-13 19:48:19.000000000 +0000 +++ blender-2.62/source/blender/render/intern/raytrace/rayobject_instance.cpp 2012-02-15 19:33:01.000000000 +0000 @@ -47,7 +47,8 @@ static void RE_rayobject_instance_bb(RayObject *o, float *min, float *max); static float RE_rayobject_instance_cost(RayObject *o); -static void RE_rayobject_instance_hint_bb(RayObject *o, RayHint *hint, float *min, float *max) +static void RE_rayobject_instance_hint_bb(RayObject *UNUSED(o), RayHint *UNUSED(hint), + float *UNUSED(min), float *UNUSED(max)) {} static RayObjectAPI instance_api = diff -Nru blender-2.61/source/blender/render/intern/raytrace/rayobject_octree.cpp blender-2.62/source/blender/render/intern/raytrace/rayobject_octree.cpp --- blender-2.61/source/blender/render/intern/raytrace/rayobject_octree.cpp 2011-12-13 19:48:19.000000000 +0000 +++ blender-2.62/source/blender/render/intern/raytrace/rayobject_octree.cpp 2012-02-15 19:33:01.000000000 +0000 @@ -96,12 +96,13 @@ /* * This function is not expected to be called by current code state. */ -static float RE_rayobject_octree_cost(RayObject *o) +static float RE_rayobject_octree_cost(RayObject *UNUSED(o)) { return 1.0; } -static void RE_rayobject_octree_hint_bb(RayObject *o, RayHint *hint, float *min, float *max) +static void RE_rayobject_octree_hint_bb(RayObject *UNUSED(o), RayHint *UNUSED(hint), + float *UNUSED(min), float *UNUSED(max)) { return; } @@ -671,7 +672,7 @@ } /* check all faces in this node */ -static int testnode(Octree *oc, Isect *is, Node *no, OcVal ocval) +static int testnode(Octree *UNUSED(oc), Isect *is, Node *no, OcVal ocval) { short nr=0; @@ -978,7 +979,7 @@ } xo=ocx1; yo=ocy1; zo=ocz1; - labdao= ddalabda= MIN3(labdax,labday,labdaz); + ddalabda= MIN3(labdax,labday,labdaz); vec2[0]= ox1; vec2[1]= oy1; diff -Nru blender-2.61/source/blender/render/intern/raytrace/rayobject_qbvh.cpp blender-2.62/source/blender/render/intern/raytrace/rayobject_qbvh.cpp --- blender-2.61/source/blender/render/intern/raytrace/rayobject_qbvh.cpp 2011-12-13 19:48:19.000000000 +0000 +++ blender-2.62/source/blender/render/intern/raytrace/rayobject_qbvh.cpp 2012-02-15 19:33:01.000000000 +0000 @@ -110,7 +110,7 @@ } template -void bvh_hint_bb(Tree *tree, LCTSHint *hint, float *min, float *max) +void bvh_hint_bb(Tree *tree, LCTSHint *hint, float *UNUSED(min), float *UNUSED(max)) { //TODO renable hint support { diff -Nru blender-2.61/source/blender/render/intern/raytrace/rayobject_svbvh.cpp blender-2.62/source/blender/render/intern/raytrace/rayobject_svbvh.cpp --- blender-2.61/source/blender/render/intern/raytrace/rayobject_svbvh.cpp 2011-12-13 19:48:19.000000000 +0000 +++ blender-2.62/source/blender/render/intern/raytrace/rayobject_svbvh.cpp 2012-02-15 19:33:01.000000000 +0000 @@ -146,7 +146,7 @@ } template -void bvh_hint_bb(Tree *tree, LCTSHint *hint, float *min, float *max) +void bvh_hint_bb(Tree *tree, LCTSHint *hint, float *UNUSED(min), float *UNUSED(max)) { //TODO renable hint support { diff -Nru blender-2.61/source/blender/render/intern/raytrace/rayobject_vbvh.cpp blender-2.62/source/blender/render/intern/raytrace/rayobject_vbvh.cpp --- blender-2.61/source/blender/render/intern/raytrace/rayobject_vbvh.cpp 2011-12-13 19:48:19.000000000 +0000 +++ blender-2.62/source/blender/render/intern/raytrace/rayobject_vbvh.cpp 2012-02-15 19:33:01.000000000 +0000 @@ -148,7 +148,7 @@ } template -void bvh_hint_bb(Tree *tree, LCTSHint *hint, float *min, float *max) +void bvh_hint_bb(Tree *tree, LCTSHint *hint, float *UNUSED(min), float *UNUSED(max)) { //TODO renable hint support { diff -Nru blender-2.61/source/blender/render/intern/raytrace/vbvh.h blender-2.62/source/blender/render/intern/raytrace/vbvh.h --- blender-2.61/source/blender/render/intern/raytrace/vbvh.h 2011-12-13 19:48:19.000000000 +0000 +++ blender-2.62/source/blender/render/intern/raytrace/vbvh.h 2012-02-15 19:33:01.000000000 +0000 @@ -53,7 +53,7 @@ * Push nodes (used on dfs) */ template -inline static void bvh_node_push_childs(Node *node, Isect *isec, Node **stack, int &stack_pos) +inline static void bvh_node_push_childs(Node *node, Isect *UNUSED(isec), Node **stack, int &stack_pos) { Node *child = node->child; diff -Nru blender-2.61/source/blender/render/intern/source/convertblender.c blender-2.62/source/blender/render/intern/source/convertblender.c --- blender-2.61/source/blender/render/intern/source/convertblender.c 2011-12-13 19:48:16.000000000 +0000 +++ blender-2.62/source/blender/render/intern/source/convertblender.c 2012-02-15 19:32:55.000000000 +0000 @@ -592,7 +592,7 @@ { MemArena *arena= NULL; VertexTangent **vtangents= NULL; - int a, iCalcNewMethod; + int a; if(do_nmap_tangent) { arena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "nmap tangent arena"); @@ -671,7 +671,7 @@ float *tav= RE_vertren_get_tangent(obr, ver, 0); if (tav) { /* orthonorm. */ - float tdn = tav[0]*ver->n[0] + tav[1]*ver->n[1] + tav[2]*ver->n[2]; + const float tdn = dot_v3v3(tav, ver->n); tav[0] -= ver->n[0]*tdn; tav[1] -= ver->n[1]*tdn; tav[2] -= ver->n[2]*tdn; @@ -680,8 +680,7 @@ } } - iCalcNewMethod = 1; - if(iCalcNewMethod!=0 && do_nmap_tangent!=0) + if(do_nmap_tangent!=0) { SRenderMeshToTangent mesh2tangent; SMikkTSpaceContext sContext; @@ -701,11 +700,9 @@ sInterface.m_getNormal = GetNormal; sInterface.m_setTSpaceBasic = SetTSpace; - // 0 if failed - iCalcNewMethod = genTangSpaceDefault(&sContext); + genTangSpaceDefault(&sContext); } - if(arena) BLI_memarena_free(arena); if(vtangents) @@ -770,7 +767,7 @@ while(asf) { for(a=0; a<4; a++) { if(asf->vlr[a] && asf->vlr[a]!=vlr) { - inp= fabs( vlr->n[0]*asf->vlr[a]->n[0] + vlr->n[1]*asf->vlr[a]->n[1] + vlr->n[2]*asf->vlr[a]->n[2] ); + inp = fabsf(dot_v3v3(vlr->n, asf->vlr[a]->n)); if(inp < thresh) return 1; } } @@ -793,7 +790,7 @@ if(asf->vlr[a] && asf->vlr[a]!=vlr) { /* this face already made a copy for this vertex! */ if(asf->nver[a]) { - inp= fabs( vlr->n[0]*asf->vlr[a]->n[0] + vlr->n[1]*asf->vlr[a]->n[1] + vlr->n[2]*asf->vlr[a]->n[2] ); + inp = fabsf(dot_v3v3(vlr->n, asf->vlr[a]->n)); if(inp >= thresh) { return asf->nver[a]; } @@ -1068,7 +1065,6 @@ mul_v3_fl(cross, width); } - else width= 1.0f; if(ma->mode & MA_TANGENT_STR) flag= R_SMOOTH|R_TANGENT; @@ -1690,14 +1686,14 @@ } /* 2.5 setup matrices */ - mul_m4_m4m4(mat, ob->obmat, re->viewmat); + mult_m4_m4m4(mat, re->viewmat, ob->obmat); invert_m4_m4(ob->imat, mat); /* need to be that way, for imat texture */ copy_m3_m4(nmat, ob->imat); transpose_m3(nmat); if(psys->flag & PSYS_USE_IMAT) { /* psys->imat is the original emitter's inverse matrix, ob->obmat is the duplicated object's matrix */ - mul_m4_m4m4(duplimat, psys->imat, ob->obmat); + mult_m4_m4m4(duplimat, ob->obmat, psys->imat); use_duplimat = 1; } @@ -2134,7 +2130,7 @@ float vec[3], hasize, mat[4][4], imat[3][3]; int a, ok, seed= ma->seed1; - mul_m4_m4m4(mat, ob->obmat, re->viewmat); + mult_m4_m4m4(mat, re->viewmat, ob->obmat); copy_m3_m4(imat, ob->imat); re->flag |= R_HALO; @@ -2162,7 +2158,7 @@ copy_v3_v3(view, vec); normalize_v3(view); - zn= nor[0]*view[0]+nor[1]*view[1]+nor[2]*view[2]; + zn = dot_v3v3(nor, view); if(zn>=0.0f) hasize= 0.0f; else hasize*= zn*zn*zn*zn; } @@ -2244,9 +2240,9 @@ mul_m4_v3(mat, shi->co); if(imat) { - shi->vn[0]= imat[0][0]*vr->n[0]+imat[0][1]*vr->n[1]+imat[0][2]*vr->n[2]; - shi->vn[1]= imat[1][0]*vr->n[0]+imat[1][1]*vr->n[1]+imat[1][2]*vr->n[2]; - shi->vn[2]= imat[2][0]*vr->n[0]+imat[2][1]*vr->n[1]+imat[2][2]*vr->n[2]; + shi->vn[0] = dot_v3v3(imat[0], vr->n); + shi->vn[1] = dot_v3v3(imat[1], vr->n); + shi->vn[2] = dot_v3v3(imat[2], vr->n); } if (texco & TEXCO_UV) { @@ -2287,7 +2283,18 @@ if(texco & TEXCO_REFL) { /* not (yet?) */ } - + if(texco & TEXCO_STRESS) { + float *s= RE_vertren_get_stress(obr, vr, 0); + + if(s) { + shi->stress= *s; + if(shi->stress<1.0f) shi->stress-= 1.0f; + else shi->stress= (shi->stress-1.0f)/shi->stress; + } + else + shi->stress= 0.0f; + } + shi->displace[0]= shi->displace[1]= shi->displace[2]= 0.0; do_material_tex(shi, re); @@ -2429,7 +2436,7 @@ if (ob!=find_basis_mball(re->scene, ob)) return; - mul_m4_m4m4(mat, ob->obmat, re->viewmat); + mult_m4_m4m4(mat, re->viewmat, ob->obmat); invert_m4_m4(ob->imat, mat); copy_m3_m4(imat, ob->imat); @@ -2802,7 +2809,7 @@ nu= cu->nurb.first; if(nu==0) return; - mul_m4_m4m4(mat, ob->obmat, re->viewmat); + mult_m4_m4m4(mat, re->viewmat, ob->obmat); invert_m4_m4(ob->imat, mat); /* material array */ @@ -2871,7 +2878,7 @@ dl= disp.first; if(dl==NULL) return; - mul_m4_m4m4(mat, ob->obmat, re->viewmat); + mult_m4_m4m4(mat, re->viewmat, ob->obmat); invert_m4_m4(ob->imat, mat); /* material array */ @@ -3060,17 +3067,19 @@ /* ------------------------------------------------------------------------- */ struct edgesort { - int v1, v2; + unsigned int v1, v2; int f; - int i1, i2; + unsigned int i1, i2; }; /* edges have to be added with lowest index first for sorting */ -static void to_edgesort(struct edgesort *ed, int i1, int i2, int v1, int v2, int f) -{ - if(v1>v2) { - SWAP(int, v1, v2); - SWAP(int, i1, i2); +static void to_edgesort(struct edgesort *ed, + unsigned int i1, unsigned int i2, + unsigned int v1, unsigned int v2, int f) +{ + if (v1 > v2) { + SWAP(unsigned int, v1, v2); + SWAP(unsigned int, i1, i2); } ed->v1= v1; @@ -3256,7 +3265,7 @@ me= ob->data; - mul_m4_m4m4(mat, ob->obmat, re->viewmat); + mult_m4_m4m4(mat, re->viewmat, ob->obmat); invert_m4_m4(ob->imat, mat); copy_m3_m4(imat, ob->imat); negative_scale= is_negative_m4(mat); @@ -3538,6 +3547,9 @@ } if(!timeoffset) { + if(need_stress) + calc_edge_stress(re, obr, me); + if (test_for_displace(re, ob ) ) { recalc_normals= 1; calc_vertexnormals(re, obr, 0, 0); @@ -3554,9 +3566,6 @@ if(recalc_normals!=0 || need_tangent!=0) calc_vertexnormals(re, obr, need_tangent, need_nmap_tangent); - - if(need_stress) - calc_edge_stress(re, obr, me); } dm->release(dm); @@ -3599,7 +3608,7 @@ /* matrix: combination of inverse view and lampmat */ /* calculate again: the ortho-render has no correct viewinv */ invert_m4_m4(viewinv, re->viewmat); - mul_m4_m4m4(shb->viewmat, viewinv, shb->winmat); + mult_m4_m4m4(shb->viewmat, shb->winmat, viewinv); /* projection */ shb->d= lar->clipsta; @@ -3677,7 +3686,7 @@ BLI_addtail(&re->lampren, lar); go->lampren= lar; - mul_m4_m4m4(mat, ob->obmat, re->viewmat); + mult_m4_m4m4(mat, re->viewmat, ob->obmat); invert_m4_m4(ob->imat, mat); copy_m3_m4(lar->mat, mat); @@ -4232,7 +4241,7 @@ flen= normal_tri_v3( nor,vlr->v4->co, vlr->v3->co, vlr->v1->co); if(flen==0.0f) normal_tri_v3( nor,vlr->v4->co, vlr->v2->co, vlr->v1->co); - xn= nor[0]*vlr->n[0] + nor[1]*vlr->n[1] + nor[2]*vlr->n[2]; + xn = dot_v3v3(nor, vlr->n); if(ABS(xn) < 0.999995f ) { // checked on noisy fractal grid @@ -4243,11 +4252,11 @@ /* split direction based on vnorms */ normal_tri_v3( nor,vlr->v1->co, vlr->v2->co, vlr->v3->co); - d1= nor[0]*vlr->v1->n[0] + nor[1]*vlr->v1->n[1] + nor[2]*vlr->v1->n[2]; + d1 = dot_v3v3(nor, vlr->v1->n); normal_tri_v3( nor,vlr->v2->co, vlr->v3->co, vlr->v4->co); - d2= nor[0]*vlr->v2->n[0] + nor[1]*vlr->v2->n[1] + nor[2]*vlr->v2->n[2]; - + d2 = dot_v3v3(nor, vlr->v2->n); + if( fabs(d1) < fabs(d2) ) vlr->flag |= R_DIVIDE_24; else vlr->flag &= ~R_DIVIDE_24; @@ -4372,7 +4381,7 @@ float imat[4][4], obmat[4][4], obimat[4][4], nmat[3][3]; int first = 1; - mul_m4_m4m4(obmat, obr->obmat, re->viewmat); + mult_m4_m4m4(obmat, re->viewmat, obr->obmat); invert_m4_m4(imat, obmat); /* for objects instanced by dupliverts/faces/particles, we go over the @@ -4385,7 +4394,7 @@ /* compute difference between object matrix and * object matrix with dupli transform, in viewspace */ copy_m4_m4(obimat, obi->mat); - mul_m4_m4m4(obi->mat, imat, obimat); + mult_m4_m4m4(obi->mat, obimat, imat); copy_m3_m4(nmat, obi->mat); invert_m3_m3(obi->nmat, nmat); @@ -4407,7 +4416,7 @@ { float imat[4][4], obmat[4][4], obimat[4][4], nmat[3][3]; - mul_m4_m4m4(obmat, obr->obmat, re->viewmat); + mult_m4_m4m4(obmat, re->viewmat, obr->obmat); invert_m4_m4(imat, obmat); obi->obr= obr; @@ -4415,7 +4424,7 @@ /* compute difference between object matrix and * object matrix with dupli transform, in viewspace */ copy_m4_m4(obimat, obi->mat); - mul_m4_m4m4(obi->mat, imat, obimat); + mult_m4_m4m4(obi->mat, obimat, imat); copy_m3_m4(nmat, obi->mat); invert_m3_m3(obi->nmat, nmat); @@ -4612,7 +4621,7 @@ else if(render_object_type(ob->type)) add_render_object(re, ob, par, dob, timeoffset); else { - mul_m4_m4m4(mat, ob->obmat, re->viewmat); + mult_m4_m4m4(mat, re->viewmat, ob->obmat); invert_m4_m4(ob->imat, mat); } @@ -4858,7 +4867,7 @@ * See bug: [#28744] - campbell */ for(ob= re->main->object.first; ob; ob= ob->id.next) { /* imat objects has to be done here, since displace can have texture using Object map-input */ - mul_m4_m4m4(mat, ob->obmat, re->viewmat); + mult_m4_m4m4(mat, re->viewmat, ob->obmat); invert_m4_m4(ob->imat_ren, mat); copy_m4_m4(ob->imat, ob->imat_ren); /* each object should only be rendered once */ @@ -4930,7 +4939,7 @@ * this is a duplivert/face/particle, or it is a non-animated object in * a dupligroup that has already been created before */ if(dob->type != OB_DUPLIGROUP || (obr=find_dupligroup_dupli(re, obd, 0))) { - mul_m4_m4m4(mat, dob->mat, re->viewmat); + mult_m4_m4m4(mat, re->viewmat, dob->mat); obi= RE_addRenderInstance(re, NULL, obd, ob, dob->index, 0, mat, obd->lay); /* fill in instance variables for texturing */ @@ -4957,7 +4966,7 @@ for(psys=obd->particlesystem.first; psys; psys=psys->next) { if(dob->type != OB_DUPLIGROUP || (obr=find_dupligroup_dupli(re, obd, psysindex))) { if(obi == NULL) - mul_m4_m4m4(mat, dob->mat, re->viewmat); + mult_m4_m4m4(mat, re->viewmat, dob->mat); obi= RE_addRenderInstance(re, NULL, obd, ob, dob->index, psysindex++, mat, obd->lay); set_dupli_tex_mat(re, obi, dob); @@ -5258,7 +5267,7 @@ if(vec[0]<0.0f) ang= -ang; zco[0]= ang/pixelphix + zmulx; - ang= 0.5f*(float)M_PI - saacos(vec[1]/sqrtf(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2])); + ang= 0.5f*(float)M_PI - saacos(vec[1] / len_v3(vec)); zco[1]= ang/pixelphiy + zmuly; } @@ -5312,7 +5321,7 @@ int a; if(obi->flag & R_TRANSFORMED) - mul_m4_m4m4(winmat, obi->mat, re->winmat); + mult_m4_m4m4(winmat, re->winmat, obi->mat); else copy_m4_m4(winmat, re->winmat); @@ -5349,7 +5358,7 @@ int a, *face, *index; if(obi->flag & R_TRANSFORMED) - mul_m4_m4m4(winmat, obi->mat, re->winmat); + mult_m4_m4m4(winmat, re->winmat, obi->mat); else copy_m4_m4(winmat, re->winmat); @@ -5443,7 +5452,7 @@ velarray = fss->meshVelocities; if(obi->flag & R_TRANSFORMED) - mul_m4_m4m4(winmat, obi->mat, re->winmat); + mult_m4_m4m4(winmat, re->winmat, obi->mat); else copy_m4_m4(winmat, re->winmat); @@ -5478,9 +5487,9 @@ } // transform (=rotate) to cam space - camco[0]= imat[0][0]*fsvec[0] + imat[0][1]*fsvec[1] + imat[0][2]*fsvec[2]; - camco[1]= imat[1][0]*fsvec[0] + imat[1][1]*fsvec[1] + imat[1][2]*fsvec[2]; - camco[2]= imat[2][0]*fsvec[0] + imat[2][1]*fsvec[1] + imat[2][2]*fsvec[2]; + camco[0] = dot_v3v3(imat[0], fsvec); + camco[1] = dot_v3v3(imat[1], fsvec); + camco[2] = dot_v3v3(imat[2], fsvec); // get homogenous coordinates projectvert(camco, winmat, hoco); @@ -5533,7 +5542,7 @@ vec= obilb->vectors= MEM_mallocN(2*sizeof(float)*totvector, "vector array"); if(obi->flag & R_TRANSFORMED) - mul_m4_m4m4(winmat, obi->mat, re->winmat); + mult_m4_m4m4(winmat, re->winmat, obi->mat); else copy_m4_m4(winmat, re->winmat); @@ -5861,7 +5870,7 @@ CD_CALLOC, NULL, me->totvert); where_is_object(scene, ob); - mul_m4_m4m4(mat, ob->obmat, re->viewmat); + mult_m4_m4m4(mat, re->viewmat, ob->obmat); ms= me->msticky; for(a=0; atotvert; a++, ms++, mvert++) { diff -Nru blender-2.61/source/blender/render/intern/source/envmap.c blender-2.62/source/blender/render/intern/source/envmap.c --- blender-2.61/source/blender/render/intern/source/envmap.c 2011-12-13 19:48:16.000000000 +0000 +++ blender-2.62/source/blender/render/intern/source/envmap.c 2012-02-15 19:32:55.000000000 +0000 @@ -263,7 +263,7 @@ /* append or set matrix depending on dupli */ if(obi->flag & R_DUPLI_TRANSFORMED) { copy_m4_m4(tmpmat, obi->mat); - mul_m4_m4m4(obi->mat, tmpmat, tmat); + mult_m4_m4m4(obi->mat, tmat, tmpmat); } else if(mode==1) copy_m4_m4(obi->mat, tmat); @@ -312,10 +312,10 @@ if(lar->shb) { if(mode==1) { invert_m4_m4(pmat, mat); - mul_m4_m4m4(smat, pmat, lar->shb->viewmat); - mul_m4_m4m4(lar->shb->persmat, smat, lar->shb->winmat); + mult_m4_m4m4(smat, lar->shb->viewmat, pmat); + mult_m4_m4m4(lar->shb->persmat, lar->shb->winmat, smat); } - else mul_m4_m4m4(lar->shb->persmat, lar->shb->viewmat, lar->shb->winmat); + else mult_m4_m4m4(lar->shb->persmat, lar->shb->winmat, lar->shb->viewmat); } } @@ -393,7 +393,7 @@ base= re->scene->base.first; while(base) { - mul_m4_m4m4(mat, base->object->obmat, re->viewmat); + mult_m4_m4m4(mat, re->viewmat, base->object->obmat); invert_m4_m4(base->object->imat, mat); base= base->next; @@ -422,7 +422,7 @@ normalize_m4(orthmat); /* need imat later for texture imat */ - mul_m4_m4m4(mat, orthmat, re->viewmat); + mult_m4_m4m4(mat, re->viewmat, orthmat); invert_m4_m4(tmat, mat); copy_m3_m4(env->obimat, tmat); @@ -441,7 +441,7 @@ copy_m4_m4(envre->viewinv, tmat); /* we have to correct for the already rotated vertexcoords */ - mul_m4_m4m4(tmat, oldviewinv, envre->viewmat); + mult_m4_m4m4(tmat, envre->viewmat, oldviewinv); invert_m4_m4(env->imat, tmat); env_rotate_scene(envre, tmat, 1); @@ -528,7 +528,7 @@ normalize_m4(orthmat); /* need imat later for texture imat */ - mul_m4_m4m4(mat, orthmat, re->viewmat); + mult_m4_m4m4(mat, re->viewmat, orthmat); invert_m4_m4(tmat, mat); copy_m3_m4(env->obimat, tmat); } diff -Nru blender-2.61/source/blender/render/intern/source/external_engine.c blender-2.62/source/blender/render/intern/source/external_engine.c --- blender-2.61/source/blender/render/intern/source/external_engine.c 2011-12-13 19:48:16.000000000 +0000 +++ blender-2.62/source/blender/render/intern/source/external_engine.c 2012-02-15 19:32:55.000000000 +0000 @@ -54,7 +54,7 @@ #include "RE_pipeline.h" #include "render_types.h" -#include "renderpipeline.h" +#include "render_result.h" /* Render Engine Types */ @@ -168,8 +168,13 @@ disprect.ymin= y; disprect.ymax= y+h; - result= new_render_result(re, &disprect, 0, RR_USEMEM); + result= render_result_new(re, &disprect, 0, RR_USE_MEM); BLI_addtail(&engine->fullresult, result); + + result->tilerect.xmin += re->disprect.xmin; + result->tilerect.xmax += re->disprect.xmin; + result->tilerect.ymin += re->disprect.ymin; + result->tilerect.ymax += re->disprect.ymin; return result; } @@ -193,7 +198,7 @@ /* merge. on break, don't merge in result for preview renders, looks nicer */ if(!(re->test_break(re->tbh) && (re->r.scemode & R_PREVIEWBUTS))) - merge_render_result(re->result, result); + render_result_merge(re->result, result); /* draw */ if(!re->test_break(re->tbh)) { @@ -202,7 +207,7 @@ } /* free */ - free_render_result(&engine->fullresult, result); + render_result_free_list(&engine->fullresult, result); } /* Cancel */ @@ -281,8 +286,9 @@ /* create render result */ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); if(re->result==NULL || !(re->r.scemode & R_PREVIEWBUTS)) { - RE_FreeRenderResult(re->result); - re->result= new_render_result(re, &re->disprect, 0, 0); + if(re->result) + render_result_free(re->result); + re->result= render_result_new(re, &re->disprect, 0, 0); } BLI_rw_mutex_unlock(&re->resultmutex); @@ -311,7 +317,7 @@ if(type->render) type->render(engine, re->scene); - free_render_result(&engine->fullresult, engine->fullresult.first); + render_result_free_list(&engine->fullresult, engine->fullresult.first); RE_engine_free(engine); diff -Nru blender-2.61/source/blender/render/intern/source/imagetexture.c blender-2.62/source/blender/render/intern/source/imagetexture.c --- blender-2.61/source/blender/render/intern/source/imagetexture.c 2011-12-13 19:48:16.000000000 +0000 +++ blender-2.62/source/blender/render/intern/source/imagetexture.c 2012-02-15 19:32:55.000000000 +0000 @@ -131,6 +131,8 @@ return retval; ibuf= BKE_image_get_ibuf(ima, &tex->iuser); + + ima->flag|= IMA_USED_FOR_RENDER; } if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) return retval; @@ -203,6 +205,13 @@ ibuf->rect+= (ibuf->x*ibuf->y); } + /* keep this before interpolation [#29761] */ + if (tex->imaflag & TEX_USEALPHA) { + if ((tex->imaflag & TEX_CALCALPHA) == 0) { + texres->talpha = TRUE; + } + } + /* interpolate */ if (tex->imaflag & TEX_INTERPOL) { float filterx, filtery; @@ -225,11 +234,6 @@ ibuf->rect-= (ibuf->x*ibuf->y); } - if(tex->imaflag & TEX_USEALPHA) { - if(tex->imaflag & TEX_CALCALPHA); - else texres->talpha= 1; - } - if(texres->nor) { if(tex->imaflag & TEX_NORMALMAP) { // qdn: normal from color @@ -1439,6 +1443,8 @@ return retval; ibuf= BKE_image_get_ibuf(ima, &tex->iuser); + + ima->flag|= IMA_USED_FOR_RENDER; } if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) return retval; @@ -1810,6 +1816,8 @@ if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) ibuf->rect-= (ibuf->x*ibuf->y); + + ima->flag|= IMA_USED_FOR_RENDER; } void ibuf_sample(ImBuf *ibuf, float fx, float fy, float dx, float dy, float *result) diff -Nru blender-2.61/source/blender/render/intern/source/occlusion.c blender-2.62/source/blender/render/intern/source/occlusion.c --- blender-2.61/source/blender/render/intern/source/occlusion.c 2011-12-13 19:48:16.000000000 +0000 +++ blender-2.62/source/blender/render/intern/source/occlusion.c 2012-02-15 19:32:55.000000000 +0000 @@ -1408,12 +1408,12 @@ occlusion= (1.0f-correction)*(1.0f-occ); CLAMP(occlusion, 0.0f, 1.0f); if(correction != 0.0f) - occlusion += correction*exp(-occ); + occlusion += correction*expf(-occ); if(env) { /* sky shading using bent normal */ if(ELEM(envcolor, WO_AOSKYCOL, WO_AOSKYTEX)) { - fac= 0.5f*(1.0f+bn[0]*re->grvec[0]+ bn[1]*re->grvec[1]+ bn[2]*re->grvec[2]); + fac= 0.5f * (1.0f + dot_v3v3(bn, re->grvec)); env[0]= (1.0f-fac)*re->wrld.horr + fac*re->wrld.zenr; env[1]= (1.0f-fac)*re->wrld.horg + fac*re->wrld.zeng; env[2]= (1.0f-fac)*re->wrld.horb + fac*re->wrld.zenb; diff -Nru blender-2.61/source/blender/render/intern/source/pipeline.c blender-2.62/source/blender/render/intern/source/pipeline.c --- blender-2.61/source/blender/render/intern/source/pipeline.c 2011-12-13 19:48:16.000000000 +0000 +++ blender-2.62/source/blender/render/intern/source/pipeline.c 2012-02-15 19:32:55.000000000 +0000 @@ -53,7 +53,6 @@ #include "BKE_image.h" #include "BKE_main.h" #include "BKE_node.h" -#include "BKE_object.h" #include "BKE_pointcache.h" #include "BKE_report.h" #include "BKE_scene.h" @@ -62,27 +61,26 @@ #include "BKE_writeavi.h" /* <------ should be replaced once with generic movie module */ #include "BLI_math.h" -#include "BLI_blenlib.h" +#include "BLI_listbase.h" +#include "BLI_string.h" +#include "BLI_path_util.h" +#include "BLI_fileops.h" #include "BLI_rand.h" -#include "BLI_threads.h" #include "BLI_callbacks.h" -#include "BLI_utildefines.h" #include "PIL_time.h" #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" -#include "intern/openexr/openexr_multi.h" - #include "RE_engine.h" #include "RE_pipeline.h" /* internal */ +#include "render_result.h" #include "render_types.h" #include "renderpipeline.h" #include "renderdatabase.h" #include "rendercore.h" -#include "envmap.h" #include "initrender.h" #include "shadbuf.h" #include "pixelblending.h" @@ -184,345 +182,7 @@ void RE_FreeRenderResult(RenderResult *res) { - if(res==NULL) return; - - while(res->layers.first) { - RenderLayer *rl= res->layers.first; - - if(rl->rectf) MEM_freeN(rl->rectf); - /* acolrect and scolrect are optionally allocated in shade_tile, only free here since it can be used for drawing */ - if(rl->acolrect) MEM_freeN(rl->acolrect); - if(rl->scolrect) MEM_freeN(rl->scolrect); - - while(rl->passes.first) { - RenderPass *rpass= rl->passes.first; - if(rpass->rect) MEM_freeN(rpass->rect); - BLI_remlink(&rl->passes, rpass); - MEM_freeN(rpass); - } - BLI_remlink(&res->layers, rl); - MEM_freeN(rl); - } - - if(res->rect32) - MEM_freeN(res->rect32); - if(res->rectz) - MEM_freeN(res->rectz); - if(res->rectf) - MEM_freeN(res->rectf); - if(res->text) - MEM_freeN(res->text); - - MEM_freeN(res); -} - -/* version that's compatible with fullsample buffers */ -void free_render_result(ListBase *lb, RenderResult *rr) -{ - RenderResult *rrnext; - - for(; rr; rr= rrnext) { - rrnext= rr->next; - - if(lb && lb->first) - BLI_remlink(lb, rr); - - RE_FreeRenderResult(rr); - } -} - - -/* all layers except the active one get temporally pushed away */ -static void push_render_result(Render *re) -{ - BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - - /* officially pushed result should be NULL... error can happen with do_seq */ - RE_FreeRenderResult(re->pushedresult); - - re->pushedresult= re->result; - re->result= NULL; - - BLI_rw_mutex_unlock(&re->resultmutex); -} - -/* if scemode is R_SINGLE_LAYER, at end of rendering, merge the both render results */ -static void pop_render_result(Render *re) -{ - if(re->result==NULL) { - printf("pop render result error; no current result!\n"); - return; - } - - if(re->pushedresult) { - BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - - if(re->pushedresult->rectx==re->result->rectx && re->pushedresult->recty==re->result->recty) { - /* find which layer in pushedresult should be replaced */ - SceneRenderLayer *srl; - RenderLayer *rlpush; - RenderLayer *rl= re->result->layers.first; - int nr; - - /* render result should be empty after this */ - BLI_remlink(&re->result->layers, rl); - - /* reconstruct render result layers */ - for(nr=0, srl= re->scene->r.layers.first; srl; srl= srl->next, nr++) { - if(nr==re->r.actlay) - BLI_addtail(&re->result->layers, rl); - else { - rlpush= RE_GetRenderLayer(re->pushedresult, srl->name); - if(rlpush) { - BLI_remlink(&re->pushedresult->layers, rlpush); - BLI_addtail(&re->result->layers, rlpush); - } - } - } - } - - RE_FreeRenderResult(re->pushedresult); - re->pushedresult= NULL; - - BLI_rw_mutex_unlock(&re->resultmutex); - } -} - -/* NOTE: OpenEXR only supports 32 chars for layer+pass names - In blender we now use max 10 chars for pass, max 20 for layer */ -static const char *get_pass_name(int passtype, int channel) -{ - - if(passtype == SCE_PASS_COMBINED) { - if(channel==-1) return "Combined"; - if(channel==0) return "Combined.R"; - if(channel==1) return "Combined.G"; - if(channel==2) return "Combined.B"; - return "Combined.A"; - } - if(passtype == SCE_PASS_Z) { - if(channel==-1) return "Depth"; - return "Depth.Z"; - } - if(passtype == SCE_PASS_VECTOR) { - if(channel==-1) return "Vector"; - if(channel==0) return "Vector.X"; - if(channel==1) return "Vector.Y"; - if(channel==2) return "Vector.Z"; - return "Vector.W"; - } - if(passtype == SCE_PASS_NORMAL) { - if(channel==-1) return "Normal"; - if(channel==0) return "Normal.X"; - if(channel==1) return "Normal.Y"; - return "Normal.Z"; - } - if(passtype == SCE_PASS_UV) { - if(channel==-1) return "UV"; - if(channel==0) return "UV.U"; - if(channel==1) return "UV.V"; - return "UV.A"; - } - if(passtype == SCE_PASS_RGBA) { - if(channel==-1) return "Color"; - if(channel==0) return "Color.R"; - if(channel==1) return "Color.G"; - if(channel==2) return "Color.B"; - return "Color.A"; - } - if(passtype == SCE_PASS_EMIT) { - if(channel==-1) return "Emit"; - if(channel==0) return "Emit.R"; - if(channel==1) return "Emit.G"; - return "Emit.B"; - } - if(passtype == SCE_PASS_DIFFUSE) { - if(channel==-1) return "Diffuse"; - if(channel==0) return "Diffuse.R"; - if(channel==1) return "Diffuse.G"; - return "Diffuse.B"; - } - if(passtype == SCE_PASS_SPEC) { - if(channel==-1) return "Spec"; - if(channel==0) return "Spec.R"; - if(channel==1) return "Spec.G"; - return "Spec.B"; - } - if(passtype == SCE_PASS_SHADOW) { - if(channel==-1) return "Shadow"; - if(channel==0) return "Shadow.R"; - if(channel==1) return "Shadow.G"; - return "Shadow.B"; - } - if(passtype == SCE_PASS_AO) { - if(channel==-1) return "AO"; - if(channel==0) return "AO.R"; - if(channel==1) return "AO.G"; - return "AO.B"; - } - if(passtype == SCE_PASS_ENVIRONMENT) { - if(channel==-1) return "Env"; - if(channel==0) return "Env.R"; - if(channel==1) return "Env.G"; - return "Env.B"; - } - if(passtype == SCE_PASS_INDIRECT) { - if(channel==-1) return "Indirect"; - if(channel==0) return "Indirect.R"; - if(channel==1) return "Indirect.G"; - return "Indirect.B"; - } - if(passtype == SCE_PASS_REFLECT) { - if(channel==-1) return "Reflect"; - if(channel==0) return "Reflect.R"; - if(channel==1) return "Reflect.G"; - return "Reflect.B"; - } - if(passtype == SCE_PASS_REFRACT) { - if(channel==-1) return "Refract"; - if(channel==0) return "Refract.R"; - if(channel==1) return "Refract.G"; - return "Refract.B"; - } - if(passtype == SCE_PASS_INDEXOB) { - if(channel==-1) return "IndexOB"; - return "IndexOB.X"; - } - if(passtype == SCE_PASS_INDEXMA) { - if(channel==-1) return "IndexMA"; - return "IndexMA.X"; - } - if(passtype == SCE_PASS_MIST) { - if(channel==-1) return "Mist"; - return "Mist.Z"; - } - if(passtype == SCE_PASS_RAYHITS) - { - if(channel==-1) return "Rayhits"; - if(channel==0) return "Rayhits.R"; - if(channel==1) return "Rayhits.G"; - return "Rayhits.B"; - } - return "Unknown"; -} - -static int passtype_from_name(const char *str) -{ - - if(strcmp(str, "Combined")==0) - return SCE_PASS_COMBINED; - - if(strcmp(str, "Depth")==0) - return SCE_PASS_Z; - - if(strcmp(str, "Vector")==0) - return SCE_PASS_VECTOR; - - if(strcmp(str, "Normal")==0) - return SCE_PASS_NORMAL; - - if(strcmp(str, "UV")==0) - return SCE_PASS_UV; - - if(strcmp(str, "Color")==0) - return SCE_PASS_RGBA; - - if(strcmp(str, "Emit")==0) - return SCE_PASS_EMIT; - - if(strcmp(str, "Diffuse")==0) - return SCE_PASS_DIFFUSE; - - if(strcmp(str, "Spec")==0) - return SCE_PASS_SPEC; - - if(strcmp(str, "Shadow")==0) - return SCE_PASS_SHADOW; - - if(strcmp(str, "AO")==0) - return SCE_PASS_AO; - - if(strcmp(str, "Env")==0) - return SCE_PASS_ENVIRONMENT; - - if(strcmp(str, "Indirect")==0) - return SCE_PASS_INDIRECT; - - if(strcmp(str, "Reflect")==0) - return SCE_PASS_REFLECT; - - if(strcmp(str, "Refract")==0) - return SCE_PASS_REFRACT; - - if(strcmp(str, "IndexOB")==0) - return SCE_PASS_INDEXOB; - - if(strcmp(str, "IndexMA")==0) - return SCE_PASS_INDEXMA; - - if(strcmp(str, "Mist")==0) - return SCE_PASS_MIST; - - if(strcmp(str, "RayHits")==0) - return SCE_PASS_RAYHITS; - return 0; -} - -static void scene_unique_exr_name(Scene *scene, char *str, int sample) -{ - char di[FILE_MAX], name[FILE_MAXFILE+MAX_ID_NAME+100], fi[FILE_MAXFILE]; - - BLI_strncpy(di, G.main->name, FILE_MAX); - BLI_splitdirstring(di, fi); - - if(sample==0) - BLI_snprintf(name, sizeof(name), "%s_%s.exr", fi, scene->id.name+2); - else - BLI_snprintf(name, sizeof(name), "%s_%s%d.exr", fi, scene->id.name+2, sample); - - BLI_make_file_string("/", str, BLI_temporary_dir(), name); -} - -static void render_unique_exr_name(Render *re, char *str, int sample) -{ - scene_unique_exr_name(re->scene, str, sample); -} - -static void render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channels, int passtype) -{ - const char *typestr= get_pass_name(passtype, 0); - RenderPass *rpass= MEM_callocN(sizeof(RenderPass), typestr); - int rectsize= rr->rectx*rr->recty*channels; - - BLI_addtail(&rl->passes, rpass); - rpass->passtype= passtype; - rpass->channels= channels; - rpass->rectx= rl->rectx; - rpass->recty= rl->recty; - - if(rr->exrhandle) { - int a; - for(a=0; aexrhandle, rl->name, get_pass_name(passtype, a), 0, 0, NULL); - } - else { - float *rect; - int x; - - rpass->rect= MEM_mapallocN(sizeof(float)*rectsize, typestr); - - if(passtype==SCE_PASS_VECTOR) { - /* initialize to max speed */ - rect= rpass->rect; - for(x= rectsize-1; x>=0; x--) - rect[x]= PASS_VECTOR_MAX; - } - else if(passtype==SCE_PASS_Z) { - rect= rpass->rect; - for(x= rectsize-1; x>=0; x--) - rect[x]= 10e10; - } - } + render_result_free(res); } float *RE_RenderLayerGetPass(RenderLayer *rl, int passtype) @@ -547,140 +207,19 @@ return NULL; } -/* called by main render as well for parts */ -/* will read info from Render *re to define layers */ -/* called in threads */ -/* re->winx,winy is coordinate space of entire image, partrct the part within */ -RenderResult *new_render_result(Render *re, rcti *partrct, int crop, int savebuffers) +RenderResult *RE_MultilayerConvert(void *exrhandle, int rectx, int recty) { - RenderResult *rr; - RenderLayer *rl; - SceneRenderLayer *srl; - int rectx, recty, nr; - - rectx= partrct->xmax - partrct->xmin; - recty= partrct->ymax - partrct->ymin; - - if(rectx<=0 || recty<=0) - return NULL; - - rr= MEM_callocN(sizeof(RenderResult), "new render result"); - rr->rectx= rectx; - rr->recty= recty; - rr->renrect.xmin= 0; rr->renrect.xmax= rectx-2*crop; - /* crop is one or two extra pixels rendered for filtering, is used for merging and display too */ - rr->crop= crop; - - /* tilerect is relative coordinates within render disprect. do not subtract crop yet */ - rr->tilerect.xmin= partrct->xmin - re->disprect.xmin; - rr->tilerect.xmax= partrct->xmax - re->disprect.xmax; - rr->tilerect.ymin= partrct->ymin - re->disprect.ymin; - rr->tilerect.ymax= partrct->ymax - re->disprect.ymax; - - if(savebuffers) { - rr->exrhandle= IMB_exr_get_handle(); - } - - /* check renderdata for amount of layers */ - for(nr=0, srl= re->r.layers.first; srl; srl= srl->next, nr++) { - - if((re->r.scemode & R_SINGLE_LAYER) && nr!=re->r.actlay) - continue; - if(srl->layflag & SCE_LAY_DISABLE) - continue; - - rl= MEM_callocN(sizeof(RenderLayer), "new render layer"); - BLI_addtail(&rr->layers, rl); - - BLI_strncpy(rl->name, srl->name, sizeof(rl->name)); - rl->lay= srl->lay; - rl->lay_zmask= srl->lay_zmask; - rl->layflag= srl->layflag; - rl->passflag= srl->passflag; // for debugging: srl->passflag|SCE_PASS_RAYHITS; - rl->pass_xor= srl->pass_xor; - rl->light_override= srl->light_override; - rl->mat_override= srl->mat_override; - rl->rectx= rectx; - rl->recty= recty; - - if(rr->exrhandle) { - IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.R", 0, 0, NULL); - IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.G", 0, 0, NULL); - IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.B", 0, 0, NULL); - IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.A", 0, 0, NULL); - } - else - rl->rectf= MEM_mapallocN(rectx*recty*sizeof(float)*4, "Combined rgba"); - - if(srl->passflag & SCE_PASS_Z) - render_layer_add_pass(rr, rl, 1, SCE_PASS_Z); - if(srl->passflag & SCE_PASS_VECTOR) - render_layer_add_pass(rr, rl, 4, SCE_PASS_VECTOR); - if(srl->passflag & SCE_PASS_NORMAL) - render_layer_add_pass(rr, rl, 3, SCE_PASS_NORMAL); - if(srl->passflag & SCE_PASS_UV) - render_layer_add_pass(rr, rl, 3, SCE_PASS_UV); - if(srl->passflag & SCE_PASS_RGBA) - render_layer_add_pass(rr, rl, 4, SCE_PASS_RGBA); - if(srl->passflag & SCE_PASS_EMIT) - render_layer_add_pass(rr, rl, 3, SCE_PASS_EMIT); - if(srl->passflag & SCE_PASS_DIFFUSE) - render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE); - if(srl->passflag & SCE_PASS_SPEC) - render_layer_add_pass(rr, rl, 3, SCE_PASS_SPEC); - if(srl->passflag & SCE_PASS_AO) - render_layer_add_pass(rr, rl, 3, SCE_PASS_AO); - if(srl->passflag & SCE_PASS_ENVIRONMENT) - render_layer_add_pass(rr, rl, 3, SCE_PASS_ENVIRONMENT); - if(srl->passflag & SCE_PASS_INDIRECT) - render_layer_add_pass(rr, rl, 3, SCE_PASS_INDIRECT); - if(srl->passflag & SCE_PASS_SHADOW) - render_layer_add_pass(rr, rl, 3, SCE_PASS_SHADOW); - if(srl->passflag & SCE_PASS_REFLECT) - render_layer_add_pass(rr, rl, 3, SCE_PASS_REFLECT); - if(srl->passflag & SCE_PASS_REFRACT) - render_layer_add_pass(rr, rl, 3, SCE_PASS_REFRACT); - if(srl->passflag & SCE_PASS_INDEXOB) - render_layer_add_pass(rr, rl, 1, SCE_PASS_INDEXOB); - if(srl->passflag & SCE_PASS_INDEXMA) - render_layer_add_pass(rr, rl, 1, SCE_PASS_INDEXMA); - if(srl->passflag & SCE_PASS_MIST) - render_layer_add_pass(rr, rl, 1, SCE_PASS_MIST); - if(rl->passflag & SCE_PASS_RAYHITS) - render_layer_add_pass(rr, rl, 4, SCE_PASS_RAYHITS); - - } - /* sss, previewrender and envmap don't do layers, so we make a default one */ - if(rr->layers.first==NULL) { - rl= MEM_callocN(sizeof(RenderLayer), "new render layer"); - BLI_addtail(&rr->layers, rl); - - rl->rectx= rectx; - rl->recty= recty; - - /* duplicate code... */ - if(rr->exrhandle) { - IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.R", 0, 0, NULL); - IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.G", 0, 0, NULL); - IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.B", 0, 0, NULL); - IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.A", 0, 0, NULL); - } - else - rl->rectf= MEM_mapallocN(rectx*recty*sizeof(float)*4, "Combined rgba"); - - /* note, this has to be in sync with scene.c */ - rl->lay= (1<<20) -1; - rl->layflag= 0x7FFF; /* solid ztra halo strand */ - rl->passflag= SCE_PASS_COMBINED; - - re->r.actlay= 0; - } - - /* border render; calculate offset for use in compositor. compo is centralized coords */ - rr->xof= re->disprect.xmin + (re->disprect.xmax - re->disprect.xmin)/2 - re->winx/2; - rr->yof= re->disprect.ymin + (re->disprect.ymax - re->disprect.ymin)/2 - re->winy/2; + return render_result_new_from_exr(exrhandle, rectx, recty); +} + +RenderLayer *render_get_active_layer(Render *re, RenderResult *rr) +{ + RenderLayer *rl= BLI_findlink(&rr->layers, re->r.actlay); - return rr; + if(rl) + return rl; + else + return rr->layers.first; } static int render_scene_needs_vector(Render *re) @@ -695,344 +234,6 @@ return 0; } -static void do_merge_tile(RenderResult *rr, RenderResult *rrpart, float *target, float *tile, int pixsize) -{ - int y, ofs, copylen, tilex, tiley; - - copylen= tilex= rrpart->rectx; - tiley= rrpart->recty; - - if(rrpart->crop) { /* filters add pixel extra */ - tile+= pixsize*(rrpart->crop + rrpart->crop*tilex); - - copylen= tilex - 2*rrpart->crop; - tiley -= 2*rrpart->crop; - - ofs= (rrpart->tilerect.ymin + rrpart->crop)*rr->rectx + (rrpart->tilerect.xmin+rrpart->crop); - target+= pixsize*ofs; - } - else { - ofs= (rrpart->tilerect.ymin*rr->rectx + rrpart->tilerect.xmin); - target+= pixsize*ofs; - } - - copylen *= sizeof(float)*pixsize; - tilex *= pixsize; - ofs= pixsize*rr->rectx; - - for(y=0; ylayers.first, rlp= rrpart->layers.first; rl && rlp; rl= rl->next, rlp= rlp->next) { - - /* combined */ - if(rl->rectf && rlp->rectf) - do_merge_tile(rr, rrpart, rl->rectf, rlp->rectf, 4); - - /* passes are allocated in sync */ - for(rpass= rl->passes.first, rpassp= rlp->passes.first; rpass && rpassp; rpass= rpass->next, rpassp= rpassp->next) { - do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, rpass->channels); - } - } -} - - -static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart) -{ - RenderLayer *rlp; - RenderPass *rpassp; - int offs, partx, party; - - BLI_lock_thread(LOCK_IMAGE); - - for(rlp= rrpart->layers.first; rlp; rlp= rlp->next) { - - if(rrpart->crop) { /* filters add pixel extra */ - offs= (rrpart->crop + rrpart->crop*rrpart->rectx); - } - else { - offs= 0; - } - - /* combined */ - if(rlp->rectf) { - int a, xstride= 4; - for(a=0; aexrhandle, rlp->name, get_pass_name(SCE_PASS_COMBINED, a), - xstride, xstride*rrpart->rectx, rlp->rectf+a + xstride*offs); - } - - /* passes are allocated in sync */ - for(rpassp= rlp->passes.first; rpassp; rpassp= rpassp->next) { - int a, xstride= rpassp->channels; - for(a=0; aexrhandle, rlp->name, get_pass_name(rpassp->passtype, a), - xstride, xstride*rrpart->rectx, rpassp->rect+a + xstride*offs); - } - - } - - party= rrpart->tilerect.ymin + rrpart->crop; - partx= rrpart->tilerect.xmin + rrpart->crop; - IMB_exrtile_write_channels(rr->exrhandle, partx, party, 0); - - BLI_unlock_thread(LOCK_IMAGE); - -} - -static void save_empty_result_tiles(Render *re) -{ - RenderPart *pa; - RenderResult *rr; - - for(rr= re->result; rr; rr= rr->next) { - IMB_exrtile_clear_channels(rr->exrhandle); - - for(pa= re->parts.first; pa; pa= pa->next) { - if(pa->ready==0) { - int party= pa->disprect.ymin - re->disprect.ymin + pa->crop; - int partx= pa->disprect.xmin - re->disprect.xmin + pa->crop; - IMB_exrtile_write_channels(rr->exrhandle, partx, party, 0); - } - } - } -} - - -/* for passes read from files, these have names stored */ -static char *make_pass_name(RenderPass *rpass, int chan) -{ - static char name[16]; - int len; - - BLI_strncpy(name, rpass->name, EXR_PASS_MAXNAME); - len= strlen(name); - name[len]= '.'; - name[len+1]= rpass->chan_id[chan]; - name[len+2]= 0; - - return name; -} - -/* filename already made absolute */ -/* called from within UI, saves both rendered result as a file-read result */ -int RE_WriteRenderResult(ReportList *reports, RenderResult *rr, const char *filename, int compress) -{ - RenderLayer *rl; - RenderPass *rpass; - void *exrhandle= IMB_exr_get_handle(); - int success; - - BLI_make_existing_file(filename); - - /* composite result */ - if(rr->rectf) { - IMB_exr_add_channel(exrhandle, "Composite", "Combined.R", 4, 4*rr->rectx, rr->rectf); - IMB_exr_add_channel(exrhandle, "Composite", "Combined.G", 4, 4*rr->rectx, rr->rectf+1); - IMB_exr_add_channel(exrhandle, "Composite", "Combined.B", 4, 4*rr->rectx, rr->rectf+2); - IMB_exr_add_channel(exrhandle, "Composite", "Combined.A", 4, 4*rr->rectx, rr->rectf+3); - } - - /* add layers/passes and assign channels */ - for(rl= rr->layers.first; rl; rl= rl->next) { - - /* combined */ - if(rl->rectf) { - int a, xstride= 4; - for(a=0; aname, get_pass_name(SCE_PASS_COMBINED, a), - xstride, xstride*rr->rectx, rl->rectf+a); - } - - /* passes are allocated in sync */ - for(rpass= rl->passes.first; rpass; rpass= rpass->next) { - int a, xstride= rpass->channels; - for(a=0; apasstype) - IMB_exr_add_channel(exrhandle, rl->name, get_pass_name(rpass->passtype, a), - xstride, xstride*rr->rectx, rpass->rect+a); - else - IMB_exr_add_channel(exrhandle, rl->name, make_pass_name(rpass, a), - xstride, xstride*rr->rectx, rpass->rect+a); - } - } - } - - /* when the filename has no permissions, this can fail */ - if(IMB_exr_begin_write(exrhandle, filename, rr->rectx, rr->recty, compress)) { - IMB_exr_write_channels(exrhandle); - success= TRUE; - } - else { - /* TODO, get the error from openexr's exception */ - BKE_report(reports, RPT_ERROR, "Error Writing Render Result, see console"); - success= FALSE; - } - IMB_exr_close(exrhandle); - - return success; -} - -/* callbacks for RE_MultilayerConvert */ -static void *ml_addlayer_cb(void *base, char *str) -{ - RenderResult *rr= base; - RenderLayer *rl; - - rl= MEM_callocN(sizeof(RenderLayer), "new render layer"); - BLI_addtail(&rr->layers, rl); - - BLI_strncpy(rl->name, str, EXR_LAY_MAXNAME); - return rl; -} -static void ml_addpass_cb(void *UNUSED(base), void *lay, char *str, float *rect, int totchan, char *chan_id) -{ - RenderLayer *rl= lay; - RenderPass *rpass= MEM_callocN(sizeof(RenderPass), "loaded pass"); - int a; - - BLI_addtail(&rl->passes, rpass); - rpass->channels= totchan; - - rpass->passtype= passtype_from_name(str); - if(rpass->passtype==0) printf("unknown pass %s\n", str); - rl->passflag |= rpass->passtype; - - BLI_strncpy(rpass->name, str, EXR_PASS_MAXNAME); - /* channel id chars */ - for(a=0; achan_id[a]= chan_id[a]; - - rpass->rect= rect; -} - -/* from imbuf, if a handle was returned we convert this to render result */ -RenderResult *RE_MultilayerConvert(void *exrhandle, int rectx, int recty) -{ - RenderResult *rr= MEM_callocN(sizeof(RenderResult), "loaded render result"); - RenderLayer *rl; - RenderPass *rpass; - - rr->rectx= rectx; - rr->recty= recty; - - IMB_exr_multilayer_convert(exrhandle, rr, ml_addlayer_cb, ml_addpass_cb); - - for(rl=rr->layers.first; rl; rl=rl->next) { - rl->rectx= rectx; - rl->recty= recty; - - for(rpass=rl->passes.first; rpass; rpass=rpass->next) { - rpass->rectx= rectx; - rpass->recty= recty; - } - } - - return rr; -} - -/* called in end of render, to add names to passes... for UI only */ -static void renderresult_add_names(RenderResult *rr) -{ - RenderLayer *rl; - RenderPass *rpass; - - for(rl= rr->layers.first; rl; rl= rl->next) - for(rpass= rl->passes.first; rpass; rpass= rpass->next) - BLI_strncpy(rpass->name, get_pass_name(rpass->passtype, -1), sizeof(rpass->name)); -} - -/* called for reading temp files, and for external engines */ -static int read_render_result_from_file(const char *filename, RenderResult *rr) -{ - RenderLayer *rl; - RenderPass *rpass; - void *exrhandle= IMB_exr_get_handle(); - int rectx, recty; - - if(IMB_exr_begin_read(exrhandle, filename, &rectx, &recty)==0) { - printf("failed being read %s\n", filename); - IMB_exr_close(exrhandle); - return 0; - } - - if(rr == NULL || rectx!=rr->rectx || recty!=rr->recty) { - if(rr) - printf("error in reading render result: dimensions don't match\n"); - else - printf("error in reading render result: NULL result pointer\n"); - IMB_exr_close(exrhandle); - return 0; - } - else { - for(rl= rr->layers.first; rl; rl= rl->next) { - - /* combined */ - if(rl->rectf) { - int a, xstride= 4; - for(a=0; aname, get_pass_name(SCE_PASS_COMBINED, a), - xstride, xstride*rectx, rl->rectf+a); - } - - /* passes are allocated in sync */ - for(rpass= rl->passes.first; rpass; rpass= rpass->next) { - int a, xstride= rpass->channels; - for(a=0; aname, get_pass_name(rpass->passtype, a), - xstride, xstride*rectx, rpass->rect+a); - } - - } - IMB_exr_read_channels(exrhandle); - renderresult_add_names(rr); - } - - IMB_exr_close(exrhandle); - - return 1; -} - -/* only for temp buffer files, makes exact copy of render result */ -static int read_render_result(Render *re, int sample) -{ - char str[FILE_MAX]; - int success; - - BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - - RE_FreeRenderResult(re->result); - re->result= new_render_result(re, &re->disprect, 0, RR_USEMEM); - - render_unique_exr_name(re, str, sample); - printf("read exr tmp file: %s\n", str); - - if(read_render_result_from_file(str, re->result)) { - success= TRUE; - } - else { - printf("cannot read: %s\n", str); - success= FALSE; - - } - - BLI_rw_mutex_unlock(&re->resultmutex); - - return success; -} - /* *************************************************** */ Render *RE_GetRender(const char *name) @@ -1091,17 +292,6 @@ return NULL; } -RenderLayer *render_get_active_layer(Render *re, RenderResult *rr) -{ - RenderLayer *rl= BLI_findlink(&rr->layers, re->r.actlay); - - if(rl) - return rl; - else - return rr->layers.first; -} - - /* fill provided result struct with what's currently active or done */ void RE_AcquireResultImage(Render *re, RenderResult *rr) { @@ -1148,38 +338,7 @@ RenderResult rres; RE_AcquireResultImage(re, &rres); - - if(rres.rect32) - memcpy(rect, rres.rect32, sizeof(int)*rres.rectx*rres.recty); - else if(rres.rectf) { - float *fp= rres.rectf; - int tot= rres.rectx*rres.recty; - char *cp= (char *)rect; - - if (re->r.color_mgt_flag & R_COLOR_MANAGEMENT) { - /* Finally convert back to sRGB rendered image */ - for(;tot>0; tot--, cp+=4, fp+=4) { - cp[0] = FTOCHAR(linearrgb_to_srgb(fp[0])); - cp[1] = FTOCHAR(linearrgb_to_srgb(fp[1])); - cp[2] = FTOCHAR(linearrgb_to_srgb(fp[2])); - cp[3] = FTOCHAR(fp[3]); - } - } - else { - /* Color management is off : no conversion necessary */ - for(;tot>0; tot--, cp+=4, fp+=4) { - cp[0] = FTOCHAR(fp[0]); - cp[1] = FTOCHAR(fp[1]); - cp[2] = FTOCHAR(fp[2]); - cp[3] = FTOCHAR(fp[3]); - } - } - - } - else - /* else fill with black */ - memset(rect, 0, sizeof(int)*re->rectx*re->recty); - + render_result_rect_get_pixels(&rres, &re->r, rect, re->rectx, re->recty); RE_ReleaseResultImage(re); } @@ -1237,8 +396,8 @@ free_renderdata_tables(re); free_sample_tables(re); - RE_FreeRenderResult(re->result); - RE_FreeRenderResult(re->pushedresult); + render_result_free(re->result); + render_result_free(re->pushedresult); BLI_remlink(&RenderGlobal.renderlist, re); MEM_freeN(re); @@ -1338,14 +497,14 @@ if(re->r.scemode & R_PREVIEWBUTS) { if(re->result && re->result->rectx==re->rectx && re->result->recty==re->recty); else { - RE_FreeRenderResult(re->result); + render_result_free(re->result); re->result= NULL; } } else { /* make empty render result, so display callbacks can initialize */ - RE_FreeRenderResult(re->result); + render_result_free(re->result); re->result= MEM_callocN(sizeof(RenderResult), "new render result"); re->result->rectx= re->rectx; re->result->recty= re->recty; @@ -1361,22 +520,6 @@ RE_init_threadcount(re); } -/* part of external api, not called for regular render pipeline */ -void RE_SetDispRect (struct Render *re, rcti *disprect) -{ - re->disprect= *disprect; - re->rectx= disprect->xmax-disprect->xmin; - re->recty= disprect->ymax-disprect->ymin; - - /* initialize render result */ - BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - - RE_FreeRenderResult(re->result); - re->result= new_render_result(re, &re->disprect, 0, RR_USEMEM); - - BLI_rw_mutex_unlock(&re->resultmutex); -} - void RE_SetWindow(Render *re, rctf *viewplane, float clipsta, float clipend) { /* re->ok flag? */ @@ -1471,24 +614,6 @@ return 1; } -/* allocate osa new results for samples */ -static RenderResult *new_full_sample_buffers(Render *re, ListBase *lb, rcti *partrct, int crop) -{ - int a; - - if(re->osa==0) - return new_render_result(re, partrct, crop, RR_USEMEM); - - for(a=0; aosa; a++) { - RenderResult *rr= new_render_result(re, partrct, crop, RR_USEMEM); - BLI_addtail(lb, rr); - rr->sample_nr= a; - } - - return lb->first; -} - - /* the main thread call, renders an entire part */ static void *do_part_thread(void *pa_v) { @@ -1498,9 +623,9 @@ if(R.test_break(R.tbh)==0) { if(!R.sss_points && (R.r.scemode & R_FULL_SAMPLE)) - pa->result= new_full_sample_buffers(&R, &pa->fullresult, &pa->disprect, pa->crop); + pa->result= render_result_new_full_sample(&R, &pa->fullresult, &pa->disprect, pa->crop, RR_USE_MEM); else - pa->result= new_render_result(&R, &pa->disprect, pa->crop, RR_USEMEM); + pa->result= render_result_new(&R, &pa->disprect, pa->crop, RR_USE_MEM); if(R.sss_points) zbufshade_sss_tile(pa); @@ -1511,16 +636,12 @@ /* merge too on break! */ if(R.result->exrhandle) { - RenderResult *rr, *rrpart; - - for(rr= R.result, rrpart= pa->result; rr && rrpart; rr= rr->next, rrpart= rrpart->next) - save_render_result_tile(rr, rrpart); - + render_result_exr_file_merge(R.result, pa->result); } else if(render_display_draw_enabled(&R)) { /* on break, don't merge in result for preview renders, looks nicer */ if(R.test_break(R.tbh) && (R.r.scemode & R_PREVIEWBUTS)); - else merge_render_result(R.result, pa->result); + else render_result_merge(R.result, pa->result); } } @@ -1644,20 +765,6 @@ re->i.infostr= NULL; } -/* make osa new results for samples */ -static RenderResult *new_full_sample_buffers_exr(Render *re) -{ - int a; - - for(a=0; aosa; a++) { - RenderResult *rr= new_render_result(re, &re->disprect, 0, 1); - BLI_addtail(&re->fullresult, rr); - rr->sample_nr= a; - } - - return re->fullresult.first; -} - static void threaded_tile_processor(Render *re) { ListBase threads; @@ -1669,14 +776,15 @@ /* first step; free the entire render result, make new, and/or prepare exr buffer saving */ if(re->result==NULL || !(re->r.scemode & R_PREVIEWBUTS)) { - RE_FreeRenderResult(re->result); + render_result_free(re->result); if(re->sss_points && render_display_draw_enabled(re)) - re->result= new_render_result(re, &re->disprect, 0, 0); + re->result= render_result_new(re, &re->disprect, 0, RR_USE_MEM); else if(re->r.scemode & R_FULL_SAMPLE) - re->result= new_full_sample_buffers_exr(re); + re->result= render_result_new_full_sample(re, &re->fullresult, &re->disprect, 0, RR_USE_EXR); else - re->result= new_render_result(re, &re->disprect, 0, re->r.scemode & (R_EXR_TILE_FILE|R_FULL_SAMPLE)); + re->result= render_result_new(re, &re->disprect, 0, + (re->r.scemode & R_EXR_TILE_FILE)? RR_USE_EXR: RR_USE_MEM); } BLI_rw_mutex_unlock(&re->resultmutex); @@ -1688,17 +796,8 @@ initparts(re); - if(re->result->exrhandle) { - RenderResult *rr; - char str[FILE_MAX]; - - for(rr= re->result; rr; rr= rr->next) { - render_unique_exr_name(re, str, rr->sample_nr); - - printf("write exr tmp file, %dx%d, %s\n", rr->rectx, rr->recty, str); - IMB_exrtile_begin_write(rr->exrhandle, str, 0, rr->rectx, rr->recty, re->partx, re->party); - } - } + if(re->result->exrhandle) + render_result_exr_file_begin(re); BLI_init_threads(&threads, do_part_thread, re->r.threads); @@ -1752,7 +851,7 @@ re->display_draw(re->ddh, pa->result, NULL); print_part_stats(re, pa); - free_render_result(&pa->fullresult, pa->result); + render_result_free_list(&pa->fullresult, pa->result); pa->result= NULL; re->i.partsdone++; re->progress(re->prh, re->i.partsdone / (float)re->i.totpart); @@ -1778,22 +877,9 @@ } if(re->result->exrhandle) { - RenderResult *rr; - BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - save_empty_result_tiles(re); - - for(rr= re->result; rr; rr= rr->next) { - IMB_exr_close(rr->exrhandle); - rr->exrhandle= NULL; - } - - free_render_result(&re->fullresult, re->result); - re->result= NULL; - + render_result_exr_file_end(re); BLI_rw_mutex_unlock(&re->resultmutex); - - read_render_result(re, 0); } /* unset threadsafety */ @@ -1943,7 +1029,7 @@ int blur= re->r.mblur_samples; /* create accumulation render result */ - rres= new_render_result(re, &re->disprect, 0, RR_USEMEM); + rres= render_result_new(re, &re->disprect, 0, RR_USE_MEM); /* do the blur steps */ while(blur--) { @@ -1961,7 +1047,7 @@ /* swap results */ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - RE_FreeRenderResult(re->result); + render_result_free(re->result); re->result= rres; BLI_rw_mutex_unlock(&re->resultmutex); @@ -2068,7 +1154,7 @@ re->disprect.ymax *= 2; BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - re->result= new_render_result(re, &re->disprect, 0, RR_USEMEM); + re->result= render_result_new(re, &re->disprect, 0, RR_USE_MEM); if(rr2) { if(re->r.mode & R_ODDFIELD) @@ -2076,10 +1162,10 @@ else merge_renderresult_fields(re->result, rr1, rr2); - RE_FreeRenderResult(rr2); + render_result_free(rr2); } - RE_FreeRenderResult(rr1); + render_result_free(rr1); re->i.curfield= 0; /* stats */ @@ -2131,10 +1217,10 @@ re->rectx= re->winx; re->recty= re->winy; - rres= new_render_result(re, &re->disprect, 0, RR_USEMEM); + rres= render_result_new(re, &re->disprect, 0, RR_USE_MEM); - merge_render_result(rres, re->result); - RE_FreeRenderResult(re->result); + render_result_merge(rres, re->result); + render_result_free(re->result); re->result= rres; /* weak... the display callback wants an active renderlayer pointer... */ @@ -2317,8 +1403,11 @@ for(re1= RenderGlobal.renderlist.first; re1; re1= re1->next) { if(re1->scene->id.flag & LIB_DOIT) { if(re1->r.scemode & R_FULL_SAMPLE) { - if(sample) - read_render_result(re1, sample); + if(sample) { + BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); + render_result_exr_file_read(re1, sample); + BLI_rw_mutex_unlock(&re->resultmutex); + } ntreeCompositTagRender(re1->scene); /* ensure node gets exec to put buffers on stack */ } } @@ -2447,8 +1536,8 @@ /* ensure new result gets added, like for regular renders */ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - RE_FreeRenderResult(re->result); - re->result= new_render_result(re, &re->disprect, 0, RR_USEMEM); + render_result_free(re->result); + re->result= render_result_new(re, &re->disprect, 0, RR_USE_MEM); BLI_rw_mutex_unlock(&re->resultmutex); @@ -2457,8 +1546,11 @@ } /* swap render result */ - if(re->r.scemode & R_SINGLE_LAYER) - pop_render_result(re); + if(re->r.scemode & R_SINGLE_LAYER) { + BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); + render_result_single_layer_end(re); + BLI_rw_mutex_unlock(&re->resultmutex); + } if(!re->test_break(re->tbh)) { @@ -2553,9 +1645,17 @@ recurs_depth++; - context = seq_new_render_data(re->main, re->scene, - re->result->rectx, re->result->recty, - 100); + if((re->r.mode & R_BORDER) && (re->r.mode & R_CROP)==0) { + /* if border rendering is used and cropping is disabled, final buffer should + be as large as the whole frame */ + context = seq_new_render_data(re->main, re->scene, + re->winx, re->winy, + 100); + } else { + context = seq_new_render_data(re->main, re->scene, + re->result->rectx, re->result->recty, + 100); + } ibuf = give_ibuf_seq(context, cfra, 0); @@ -2566,67 +1666,19 @@ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); if(ibuf) { - if(ibuf->rect_float) { - if (!rr->rectf) - rr->rectf= MEM_mallocN(4*sizeof(float)*rr->rectx*rr->recty, "render_seq rectf"); - - /* color management: when off ensure rectf is non-lin, since thats what the internal - * render engine delivers */ - if(re->r.color_mgt_flag & R_COLOR_MANAGEMENT) { - if(ibuf->profile == IB_PROFILE_LINEAR_RGB) - memcpy(rr->rectf, ibuf->rect_float, 4*sizeof(float)*rr->rectx*rr->recty); - else - srgb_to_linearrgb_rgba_rgba_buf(rr->rectf, ibuf->rect_float, rr->rectx*rr->recty); - - } - else { - if(ibuf->profile != IB_PROFILE_LINEAR_RGB) - memcpy(rr->rectf, ibuf->rect_float, 4*sizeof(float)*rr->rectx*rr->recty); - else - linearrgb_to_srgb_rgba_rgba_buf(rr->rectf, ibuf->rect_float, rr->rectx*rr->recty); - } - - /* TSK! Since sequence render doesn't free the *rr render result, the old rect32 - can hang around when sequence render has rendered a 32 bits one before */ - if(rr->rect32) { - MEM_freeN(rr->rect32); - rr->rect32= NULL; - } - } - else if(ibuf->rect) { - if (!rr->rect32) - rr->rect32= MEM_mallocN(sizeof(int)*rr->rectx*rr->recty, "render_seq rect"); - - memcpy(rr->rect32, ibuf->rect, 4*rr->rectx*rr->recty); - - /* if (ibuf->zbuf) { */ - /* if (R.rectz) freeN(R.rectz); */ - /* R.rectz = BLI_dupallocN(ibuf->zbuf); */ - /* } */ - - /* Same things as above, old rectf can hang around from previous render. */ - if(rr->rectf) { - MEM_freeN(rr->rectf); - rr->rectf= NULL; - } - } + /* copy ibuf into combined pixel rect */ + render_result_rect_from_ibuf(rr, &re->r, ibuf); if (recurs_depth == 0) { /* with nested scenes, only free on toplevel... */ Editing * ed = re->scene->ed; - if (ed) { + if (ed) free_imbuf_seq(re->scene, &ed->seqbase, TRUE, TRUE); - } } IMB_freeImBuf(ibuf); } else { /* render result is delivered empty in most cases, nevertheless we handle all cases */ - if (rr->rectf) - memset(rr->rectf, 0, 4*sizeof(float)*rr->rectx*rr->recty); - else if (rr->rect32) - memset(rr->rect32, 0, 4*rr->rectx*rr->recty); - else - rr->rect32= MEM_callocN(sizeof(int)*rr->rectx*rr->recty, "render_seq rect"); + render_result_rect_fill_zero(rr); } BLI_rw_mutex_unlock(&re->resultmutex); @@ -2668,11 +1720,6 @@ do_render_composite_fields_blur_3d(re); } - /* for UI only */ - BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - renderresult_add_names(re->result); - BLI_rw_mutex_unlock(&re->resultmutex); - re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime; re->stats_draw(re->sdh, &re->i); @@ -2698,7 +1745,7 @@ check_comp= 0; while(seq) { - if(seq->type == SEQ_SCENE) { + if(seq->type == SEQ_SCENE && seq->scene) { if(!seq->scene_camera) { if(!seq->scene->camera && !scene_find_camera(seq->scene)) { if(seq->scene == scene) { @@ -2756,7 +1803,7 @@ if(scene->r.scemode & (R_EXR_TILE_FILE|R_FULL_SAMPLE)) { char str[FILE_MAX]; - scene_unique_exr_name(scene, str, 0); + render_result_exr_file_path(scene, 0, str); if (BLI_file_is_writable(str)==0) { BKE_report(reports, RPT_ERROR, "Can not save render buffers, check the temp default path"); @@ -2847,6 +1894,7 @@ if(RE_engine_is_external(re)) { /* not supported yet */ re->r.scemode &= ~(R_EXR_TILE_FILE|R_FULL_SAMPLE); + re->r.mode &= ~R_FIELDS; } } @@ -2918,8 +1966,11 @@ update_physics_cache(re, scene, anim_init); } - if(srl || scene->r.scemode & R_SINGLE_LAYER) - push_render_result(re); + if(srl || scene->r.scemode & R_SINGLE_LAYER) { + BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); + render_result_single_layer_begin(re); + BLI_rw_mutex_unlock(&re->resultmutex); + } RE_InitState(re, NULL, &scene->r, srl, winx, winy, &disprect); if(!re->ok) /* if an error was printed, abort */ @@ -2989,15 +2040,18 @@ /* write movie or image */ if(BKE_imtype_is_movie(scene->r.im_format.imtype)) { int dofree = 0; + unsigned int *rect32 = (unsigned int *)rres.rect32; /* note; the way it gets 32 bits rects is weak... */ - if(rres.rect32==NULL) { - rres.rect32= MEM_mapallocN(sizeof(int)*rres.rectx*rres.recty, "temp 32 bits rect"); + if(rres.rect32 == NULL) { + rect32 = MEM_mapallocN(sizeof(int)*rres.rectx*rres.recty, "temp 32 bits rect"); + RE_ResultGet32(re, rect32); dofree = 1; } - RE_ResultGet32(re, (unsigned int *)rres.rect32); - ok= mh->append_movie(&re->r, scene->r.cfra, rres.rect32, rres.rectx, rres.recty, re->reports); + + ok= mh->append_movie(&re->r, scene->r.sfra, scene->r.cfra, (int *)rect32, + rres.rectx, rres.recty, re->reports); if(dofree) { - MEM_freeN(rres.rect32); + MEM_freeN(rect32); } printf("Append frame %d", scene->r.cfra); } @@ -3014,36 +2068,7 @@ } } else { - ImBuf *ibuf= IMB_allocImBuf(rres.rectx, rres.recty, scene->r.im_format.planes, 0); - - /* if not exists, BKE_write_ibuf makes one */ - ibuf->rect= (unsigned int *)rres.rect32; - ibuf->rect_float= rres.rectf; - ibuf->zbuf_float= rres.rectz; - - /* float factor for random dither, imbuf takes care of it */ - ibuf->dither= scene->r.dither_intensity; - - /* prepare to gamma correct to sRGB color space */ - if (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) { - /* sequence editor can generate 8bpc render buffers */ - if (ibuf->rect) { - ibuf->profile = IB_PROFILE_SRGB; - if (BKE_imtype_valid_depths(scene->r.im_format.imtype) & (R_IMF_CHAN_DEPTH_12|R_IMF_CHAN_DEPTH_16|R_IMF_CHAN_DEPTH_24|R_IMF_CHAN_DEPTH_32)) - IMB_float_from_rect(ibuf); - } else { - ibuf->profile = IB_PROFILE_LINEAR_RGB; - } - } - - /* color -> greyscale */ - /* editing directly would alter the render view */ - if(scene->r.im_format.planes == R_IMF_PLANES_BW) { - ImBuf *ibuf_bw= IMB_dupImBuf(ibuf); - IMB_color_to_bw(ibuf_bw); - IMB_freeImBuf(ibuf); - ibuf= ibuf_bw; - } + ImBuf *ibuf= render_result_rect_to_ibuf(&rres, &scene->r); ok= BKE_write_ibuf_stamp(scene, camera, ibuf, name, &scene->r.im_format); @@ -3242,7 +2267,7 @@ int RE_ReadRenderResult(Scene *scene, Scene *scenode) { Render *re; - int winx, winy; + int winx, winy, success; rcti disprect; /* calculate actual render result and display size */ @@ -3273,7 +2298,11 @@ RE_InitState(re, NULL, &scene->r, NULL, winx, winy, &disprect); re->scene= scene; - return read_render_result(re, 0); + BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); + success= render_result_exr_file_read(re, 0); + BLI_rw_mutex_unlock(&re->resultmutex); + + return success; } void RE_set_max_threads(int threads) @@ -3340,7 +2369,7 @@ void RE_result_load_from_file(RenderResult *result, ReportList *reports, const char *filename) { - if(!read_render_result_from_file(filename, result)) { + if(!render_result_exr_file_read_path(result, filename)) { BKE_reportf(reports, RPT_ERROR, "RE_result_rect_from_file: failed to load '%s'\n", filename); return; } diff -Nru blender-2.61/source/blender/render/intern/source/pixelshading.c blender-2.62/source/blender/render/intern/source/pixelshading.c --- blender-2.61/source/blender/render/intern/source/pixelshading.c 2011-12-13 19:48:16.000000000 +0000 +++ blender-2.62/source/blender/render/intern/source/pixelshading.c 2012-02-15 19:32:55.000000000 +0000 @@ -104,7 +104,7 @@ lv[0]= rco[0]-lar->co[0]; lv[1]= rco[1]-lar->co[1]; lv[2]= rco[2]-lar->co[2]; - ld= sqrt(lv[0]*lv[0]+lv[1]*lv[1]+lv[2]*lv[2]); + ld = len_v3(lv); lv[0]/= ld; lv[1]/= ld; lv[2]/= ld; @@ -176,7 +176,6 @@ if(inprspotbl && lar->spotbl!=0.0f) { /* soft area */ @@ -211,7 +210,7 @@ /* dot product and reflectivity*/ - inp= 1.0-fabs(vn[0]*lv[0] + vn[1]*lv[1] + vn[2]*lv[2]); + inp = 1.0 - fabs(dot_v3v3(vn, lv)); /* inp= cos(0.5*M_PI-acos(inp)); */ @@ -512,7 +511,7 @@ /* Some view vector stuff. */ if(R.wrld.skytype & WO_SKYREAL) { - blend= view[0]*R.grvec[0]+ view[1]*R.grvec[1]+ view[2]*R.grvec[2]; + blend = dot_v3v3(view, R.grvec); if(blend<0.0f) skyflag= 0; diff -Nru blender-2.61/source/blender/render/intern/source/pointdensity.c blender-2.62/source/blender/render/intern/source/pointdensity.c --- blender-2.61/source/blender/render/intern/source/pointdensity.c 2011-12-13 19:48:16.000000000 +0000 +++ blender-2.62/source/blender/render/intern/source/pointdensity.c 2012-02-15 19:32:55.000000000 +0000 @@ -116,7 +116,7 @@ /* init everything */ if (!psys || !ob || !pd) return; - mul_m4_m4m4(obview, re->viewinv, ob->obmat); + mult_m4_m4m4(obview, ob->obmat, re->viewinv); /* Just to create a valid rendering context for particles */ psys_render_set(ob, psys, re->viewmat, re->winmat, re->winx, re->winy, 0); diff -Nru blender-2.61/source/blender/render/intern/source/rayshade.c blender-2.62/source/blender/render/intern/source/rayshade.c --- blender-2.61/source/blender/render/intern/source/rayshade.c 2011-12-13 19:48:16.000000000 +0000 +++ blender-2.62/source/blender/render/intern/source/rayshade.c 2012-02-15 19:32:55.000000000 +0000 @@ -53,6 +53,7 @@ #include "PIL_time.h" +#include "render_result.h" #include "render_types.h" #include "renderpipeline.h" #include "rendercore.h" @@ -470,7 +471,7 @@ sub[i] = max[i]-min[i]; } - re->maxdist= sub[0]*sub[0] + sub[1]*sub[1] + sub[2]*sub[2]; + re->maxdist = dot_v3v3(sub, sub); if(re->maxdist > 0.0f) re->maxdist= sqrt(re->maxdist); re->i.infostr= "Raytree finished"; @@ -597,7 +598,7 @@ copy_v3_v3(refract, view); - dot= view[0]*n[0] + view[1]*n[1] + view[2]*n[2]; + dot = dot_v3v3(view, n); if(dot>0.0f) { index = 1.0f/index; @@ -779,7 +780,10 @@ tracol[3]= col[3]; // we pass on and accumulate alpha if((shi.mat->mode & MA_TRANSP) && (shi.mat->mode & MA_RAYTRANSP)) { - if(traflag & RAY_INSIDE) { + /* don't overwrite traflag, it's value is used in mirror reflection */ + int new_traflag = traflag; + + if(new_traflag & RAY_INSIDE) { /* inside the material, so use inverse normal */ float norm[3]; norm[0]= - shi.vn[0]; @@ -788,7 +792,7 @@ if (refraction(refract, norm, shi.view, shi.ang)) { /* ray comes out from the material into air */ - traflag &= ~RAY_INSIDE; + new_traflag &= ~RAY_INSIDE; } else { /* total internal reflection (ray stays inside the material) */ @@ -798,14 +802,14 @@ else { if (refraction(refract, shi.vn, shi.view, shi.ang)) { /* ray goes in to the material from air */ - traflag |= RAY_INSIDE; + new_traflag |= RAY_INSIDE; } else { /* total external reflection (ray doesn't enter the material) */ reflection(refract, shi.vn, shi.view, shi.vn); } } - traceray(origshi, origshr, depth-1, shi.co, refract, tracol, shi.obi, shi.vlr, traflag); + traceray(origshi, origshr, depth-1, shi.co, refract, tracol, shi.obi, shi.vlr, new_traflag); } else traceray(origshi, origshr, depth-1, shi.co, shi.view, tracol, shi.obi, shi.vlr, 0); @@ -839,7 +843,7 @@ float ref[3]; reflection_simple(ref, shi.vn, shi.view); - traceray(origshi, origshr, depth-1, shi.co, ref, mircol, shi.obi, shi.vlr, 0); + traceray(origshi, origshr, depth-1, shi.co, ref, mircol, shi.obi, shi.vlr, traflag); f1= 1.0f-f; @@ -1704,7 +1708,7 @@ counter+=3; counter %= 768; copy_v3_v3(vec, hashvectf+counter); - if(ship->vn[0]*vec[0]+ship->vn[1]*vec[1]+ship->vn[2]*vec[2]>0.0f) { + if (dot_v3v3(ship->vn, vec) > 0.0f) { vec[0]-= vec[0]; vec[1]-= vec[1]; vec[2]-= vec[2]; @@ -1767,7 +1771,7 @@ for(a=0, fp=sphere; atype == SAMP_TYPE_HALTON) { + if (qsa && qsa->type == SAMP_TYPE_HALTON) { /* adaptive sampling - consider samples below threshold as in shadow (or vice versa) and exit early */ if (adapt_thresh > 0.0f && (samples > max_samples/2) ) { @@ -2097,7 +2101,7 @@ while(tot--) { - if ((vec[0]*nrm[0] + vec[1]*nrm[1] + vec[2]*nrm[2]) > bias) { + if (dot_v3v3(vec, nrm) > bias) { /* only ao samples for mask */ if(R.r.mode & R_OSA) { j++; @@ -2131,7 +2135,7 @@ normalize_v3(view); if(envcolor==WO_AOSKYCOL) { - const float fac= 0.5f*(1.0f+view[0]*R.grvec[0]+ view[1]*R.grvec[1]+ view[2]*R.grvec[2]); + const float fac = 0.5f * (1.0f + dot_v3v3(view, R.grvec)); env[0]+= (1.0f-fac)*R.wrld.horr + fac*R.wrld.zenr; env[1]+= (1.0f-fac)*R.wrld.horg + fac*R.wrld.zeng; env[2]+= (1.0f-fac)*R.wrld.horb + fac*R.wrld.zenb; diff -Nru blender-2.61/source/blender/render/intern/source/rendercore.c blender-2.62/source/blender/render/intern/source/rendercore.c --- blender-2.61/source/blender/render/intern/source/rendercore.c 2011-12-13 19:48:16.000000000 +0000 +++ blender-2.62/source/blender/render/intern/source/rendercore.c 2012-02-15 19:32:55.000000000 +0000 @@ -67,6 +67,7 @@ #include "rayintersection.h" #include "rayobject.h" #include "renderpipeline.h" +#include "render_result.h" #include "render_types.h" #include "renderdatabase.h" #include "occlusion.h" @@ -2165,21 +2166,13 @@ } } else { - char *col= (char *)(bs->rect + bs->rectx*y + x); + unsigned char *col= (unsigned char *)(bs->rect + bs->rectx*y + x); if (ELEM(bs->type, RE_BAKE_ALL, RE_BAKE_TEXTURE) && (R.r.color_mgt_flag & R_COLOR_MANAGEMENT)) { - float srgb[3]; - srgb[0]= linearrgb_to_srgb(shr.combined[0]); - srgb[1]= linearrgb_to_srgb(shr.combined[1]); - srgb[2]= linearrgb_to_srgb(shr.combined[2]); - - col[0]= FTOCHAR(srgb[0]); - col[1]= FTOCHAR(srgb[1]); - col[2]= FTOCHAR(srgb[2]); - } else { - col[0]= FTOCHAR(shr.combined[0]); - col[1]= FTOCHAR(shr.combined[1]); - col[2]= FTOCHAR(shr.combined[2]); + linearrgb_to_srgb_uchar3(col, shr.combined); + } + else { + rgb_float_to_uchar(col, shr.combined); } if (ELEM(bs->type, RE_BAKE_ALL, RE_BAKE_TEXTURE)) { @@ -2211,9 +2204,7 @@ col[3]= 1.0f; } else { char *col= (char *)(bs->rect + bs->rectx*y + x); - col[0]= FTOCHAR(disp); - col[1]= FTOCHAR(disp); - col[2]= FTOCHAR(disp); + col[0] = col[1] = col[2] = FTOCHAR(disp); col[3]= 255; } if (bs->rect_mask) { @@ -2449,6 +2440,11 @@ if(ibuf->rect_float && !(ibuf->channels==0 || ibuf->channels==4)) continue; + if(ima->flag & IMA_USED_FOR_RENDER) { + ima->id.flag &= ~LIB_DOIT; + continue; + } + /* find the image for the first time? */ if(ima->id.flag & LIB_DOIT) { ima->id.flag &= ~LIB_DOIT; @@ -2593,7 +2589,7 @@ BakeShade *handles; ListBase threads; Image *ima; - int a, vdone=0, usemask=0; + int a, vdone=0, usemask=0, result=BAKE_RESULT_OK; /* initialize render global */ R= *re; @@ -2610,6 +2606,7 @@ for(ima= G.main->image.first; ima; ima= ima->id.next) { ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL); ima->id.flag |= LIB_DOIT; + ima->flag&= ~IMA_USED_FOR_RENDER; if(ibuf) { ibuf->userdata = NULL; /* use for masking if needed */ if(ibuf->rect_float) @@ -2668,6 +2665,9 @@ if((ima->id.flag & LIB_DOIT)==0) { ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL); + if(ima->flag & IMA_USED_FOR_RENDER) + result= BAKE_RESULT_FEEDBACK_LOOP; + if(!ibuf) continue; @@ -2688,7 +2688,10 @@ BLI_end_threads(&threads); - return vdone; + if(vdone==0) + result= BAKE_RESULT_NO_OBJECTS; + + return result; } struct Image *RE_bake_shade_get_image(void) diff -Nru blender-2.61/source/blender/render/intern/source/renderdatabase.c blender-2.62/source/blender/render/intern/source/renderdatabase.c --- blender-2.61/source/blender/render/intern/source/renderdatabase.c 2011-12-13 19:48:16.000000000 +0000 +++ blender-2.62/source/blender/render/intern/source/renderdatabase.c 2012-02-15 19:32:55.000000000 +0000 @@ -1026,7 +1026,7 @@ externtex(mtex, texvec, &tin, &tr, &tg, &tb, &ta, 0); yn= tin*mtex->colfac; - zn= tin*mtex->alphafac; + //zn= tin*mtex->alphafac; if(mtex->mapto & MAP_COL) { zn= 1.0f-yn; @@ -1112,10 +1112,8 @@ if(ma->mode & MA_HALO_RINGS) har->ringc= ma->ringc; if(ma->mode & MA_HALO_FLARE) har->flarec= ma->flarec; - if((ma->mode & MA_HALOTEX) && ma->mtex[0]){ + if((ma->mode & MA_HALOTEX) && ma->mtex[0]) har->tex= 1; - i=1; - } for(i=0; imtex[i] && (ma->septex & (1< +#include + +#include "MEM_guardedalloc.h" + +#include "BKE_image.h" +#include "BKE_global.h" +#include "BKE_main.h" +#include "BKE_report.h" +#include "BKE_utildefines.h" + +#include "BLI_fileops.h" +#include "BLI_listbase.h" +#include "BLI_path_util.h" +#include "BLI_string.h" +#include "BLI_threads.h" +#include "BLI_utildefines.h" + +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" + +#include "intern/openexr/openexr_multi.h" + +#include "render_result.h" +#include "render_types.h" + +/********************************** Free *************************************/ + +void render_result_free(RenderResult *res) +{ + if(res==NULL) return; + + while(res->layers.first) { + RenderLayer *rl= res->layers.first; + + if(rl->rectf) MEM_freeN(rl->rectf); + /* acolrect and scolrect are optionally allocated in shade_tile, only free here since it can be used for drawing */ + if(rl->acolrect) MEM_freeN(rl->acolrect); + if(rl->scolrect) MEM_freeN(rl->scolrect); + + while(rl->passes.first) { + RenderPass *rpass= rl->passes.first; + if(rpass->rect) MEM_freeN(rpass->rect); + BLI_remlink(&rl->passes, rpass); + MEM_freeN(rpass); + } + BLI_remlink(&res->layers, rl); + MEM_freeN(rl); + } + + if(res->rect32) + MEM_freeN(res->rect32); + if(res->rectz) + MEM_freeN(res->rectz); + if(res->rectf) + MEM_freeN(res->rectf); + if(res->text) + MEM_freeN(res->text); + + MEM_freeN(res); +} + +/* version that's compatible with fullsample buffers */ +void render_result_free_list(ListBase *lb, RenderResult *rr) +{ + RenderResult *rrnext; + + for(; rr; rr= rrnext) { + rrnext= rr->next; + + if(lb && lb->first) + BLI_remlink(lb, rr); + + render_result_free(rr); + } +} + +/********************************* Names *************************************/ + +/* NOTE: OpenEXR only supports 32 chars for layer+pass names + In blender we now use max 10 chars for pass, max 20 for layer */ +static const char *get_pass_name(int passtype, int channel) +{ + + if(passtype == SCE_PASS_COMBINED) { + if(channel==-1) return "Combined"; + if(channel==0) return "Combined.R"; + if(channel==1) return "Combined.G"; + if(channel==2) return "Combined.B"; + return "Combined.A"; + } + if(passtype == SCE_PASS_Z) { + if(channel==-1) return "Depth"; + return "Depth.Z"; + } + if(passtype == SCE_PASS_VECTOR) { + if(channel==-1) return "Vector"; + if(channel==0) return "Vector.X"; + if(channel==1) return "Vector.Y"; + if(channel==2) return "Vector.Z"; + return "Vector.W"; + } + if(passtype == SCE_PASS_NORMAL) { + if(channel==-1) return "Normal"; + if(channel==0) return "Normal.X"; + if(channel==1) return "Normal.Y"; + return "Normal.Z"; + } + if(passtype == SCE_PASS_UV) { + if(channel==-1) return "UV"; + if(channel==0) return "UV.U"; + if(channel==1) return "UV.V"; + return "UV.A"; + } + if(passtype == SCE_PASS_RGBA) { + if(channel==-1) return "Color"; + if(channel==0) return "Color.R"; + if(channel==1) return "Color.G"; + if(channel==2) return "Color.B"; + return "Color.A"; + } + if(passtype == SCE_PASS_EMIT) { + if(channel==-1) return "Emit"; + if(channel==0) return "Emit.R"; + if(channel==1) return "Emit.G"; + return "Emit.B"; + } + if(passtype == SCE_PASS_DIFFUSE) { + if(channel==-1) return "Diffuse"; + if(channel==0) return "Diffuse.R"; + if(channel==1) return "Diffuse.G"; + return "Diffuse.B"; + } + if(passtype == SCE_PASS_SPEC) { + if(channel==-1) return "Spec"; + if(channel==0) return "Spec.R"; + if(channel==1) return "Spec.G"; + return "Spec.B"; + } + if(passtype == SCE_PASS_SHADOW) { + if(channel==-1) return "Shadow"; + if(channel==0) return "Shadow.R"; + if(channel==1) return "Shadow.G"; + return "Shadow.B"; + } + if(passtype == SCE_PASS_AO) { + if(channel==-1) return "AO"; + if(channel==0) return "AO.R"; + if(channel==1) return "AO.G"; + return "AO.B"; + } + if(passtype == SCE_PASS_ENVIRONMENT) { + if(channel==-1) return "Env"; + if(channel==0) return "Env.R"; + if(channel==1) return "Env.G"; + return "Env.B"; + } + if(passtype == SCE_PASS_INDIRECT) { + if(channel==-1) return "Indirect"; + if(channel==0) return "Indirect.R"; + if(channel==1) return "Indirect.G"; + return "Indirect.B"; + } + if(passtype == SCE_PASS_REFLECT) { + if(channel==-1) return "Reflect"; + if(channel==0) return "Reflect.R"; + if(channel==1) return "Reflect.G"; + return "Reflect.B"; + } + if(passtype == SCE_PASS_REFRACT) { + if(channel==-1) return "Refract"; + if(channel==0) return "Refract.R"; + if(channel==1) return "Refract.G"; + return "Refract.B"; + } + if(passtype == SCE_PASS_INDEXOB) { + if(channel==-1) return "IndexOB"; + return "IndexOB.X"; + } + if(passtype == SCE_PASS_INDEXMA) { + if(channel==-1) return "IndexMA"; + return "IndexMA.X"; + } + if(passtype == SCE_PASS_MIST) { + if(channel==-1) return "Mist"; + return "Mist.Z"; + } + if(passtype == SCE_PASS_RAYHITS) + { + if(channel==-1) return "Rayhits"; + if(channel==0) return "Rayhits.R"; + if(channel==1) return "Rayhits.G"; + return "Rayhits.B"; + } + if(passtype == SCE_PASS_DIFFUSE_DIRECT) { + if(channel==-1) return "DiffDir"; + if(channel==0) return "DiffDir.R"; + if(channel==1) return "DiffDir.G"; + return "DiffDir.B"; + } + if(passtype == SCE_PASS_DIFFUSE_INDIRECT) { + if(channel==-1) return "DiffInd"; + if(channel==0) return "DiffInd.R"; + if(channel==1) return "DiffInd.G"; + return "DiffInd.B"; + } + if(passtype == SCE_PASS_DIFFUSE_COLOR) { + if(channel==-1) return "DiffCol"; + if(channel==0) return "DiffCol.R"; + if(channel==1) return "DiffCol.G"; + return "DiffCol.B"; + } + if(passtype == SCE_PASS_GLOSSY_DIRECT) { + if(channel==-1) return "GlossDir"; + if(channel==0) return "GlossDir.R"; + if(channel==1) return "GlossDir.G"; + return "GlossDir.B"; + } + if(passtype == SCE_PASS_GLOSSY_INDIRECT) { + if(channel==-1) return "GlossInd"; + if(channel==0) return "GlossInd.R"; + if(channel==1) return "GlossInd.G"; + return "GlossInd.B"; + } + if(passtype == SCE_PASS_GLOSSY_COLOR) { + if(channel==-1) return "GlossCol"; + if(channel==0) return "GlossCol.R"; + if(channel==1) return "GlossCol.G"; + return "GlossCol.B"; + } + if(passtype == SCE_PASS_TRANSM_DIRECT) { + if(channel==-1) return "TransDir"; + if(channel==0) return "TransDir.R"; + if(channel==1) return "TransDir.G"; + return "TransDir.B"; + } + if(passtype == SCE_PASS_TRANSM_INDIRECT) { + if(channel==-1) return "TransInd"; + if(channel==0) return "TransInd.R"; + if(channel==1) return "TransInd.G"; + return "TransInd.B"; + } + if(passtype == SCE_PASS_TRANSM_COLOR) { + if(channel==-1) return "TransCol"; + if(channel==0) return "TransCol.R"; + if(channel==1) return "TransCol.G"; + return "TransCol.B"; + } + return "Unknown"; +} + +static int passtype_from_name(const char *str) +{ + + if(strcmp(str, "Combined")==0) + return SCE_PASS_COMBINED; + + if(strcmp(str, "Depth")==0) + return SCE_PASS_Z; + + if(strcmp(str, "Vector")==0) + return SCE_PASS_VECTOR; + + if(strcmp(str, "Normal")==0) + return SCE_PASS_NORMAL; + + if(strcmp(str, "UV")==0) + return SCE_PASS_UV; + + if(strcmp(str, "Color")==0) + return SCE_PASS_RGBA; + + if(strcmp(str, "Emit")==0) + return SCE_PASS_EMIT; + + if(strcmp(str, "Diffuse")==0) + return SCE_PASS_DIFFUSE; + + if(strcmp(str, "Spec")==0) + return SCE_PASS_SPEC; + + if(strcmp(str, "Shadow")==0) + return SCE_PASS_SHADOW; + + if(strcmp(str, "AO")==0) + return SCE_PASS_AO; + + if(strcmp(str, "Env")==0) + return SCE_PASS_ENVIRONMENT; + + if(strcmp(str, "Indirect")==0) + return SCE_PASS_INDIRECT; + + if(strcmp(str, "Reflect")==0) + return SCE_PASS_REFLECT; + + if(strcmp(str, "Refract")==0) + return SCE_PASS_REFRACT; + + if(strcmp(str, "IndexOB")==0) + return SCE_PASS_INDEXOB; + + if(strcmp(str, "IndexMA")==0) + return SCE_PASS_INDEXMA; + + if(strcmp(str, "Mist")==0) + return SCE_PASS_MIST; + + if(strcmp(str, "RayHits")==0) + return SCE_PASS_RAYHITS; + + if(strcmp(str, "DiffDir")==0) + return SCE_PASS_DIFFUSE_DIRECT; + + if(strcmp(str, "DiffInd")==0) + return SCE_PASS_DIFFUSE_INDIRECT; + + if(strcmp(str, "DiffCol")==0) + return SCE_PASS_DIFFUSE_COLOR; + + if(strcmp(str, "GlossDir")==0) + return SCE_PASS_GLOSSY_DIRECT; + + if(strcmp(str, "GlossInd")==0) + return SCE_PASS_GLOSSY_INDIRECT; + + if(strcmp(str, "GlossCol")==0) + return SCE_PASS_GLOSSY_COLOR; + + if(strcmp(str, "TransDir")==0) + return SCE_PASS_TRANSM_DIRECT; + + if(strcmp(str, "TransInd")==0) + return SCE_PASS_TRANSM_INDIRECT; + + if(strcmp(str, "TransCol")==0) + return SCE_PASS_TRANSM_COLOR; + + return 0; +} + +/********************************** New **************************************/ + +static void render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channels, int passtype) +{ + const char *typestr= get_pass_name(passtype, 0); + RenderPass *rpass= MEM_callocN(sizeof(RenderPass), typestr); + int rectsize= rr->rectx*rr->recty*channels; + + BLI_addtail(&rl->passes, rpass); + rpass->passtype= passtype; + rpass->channels= channels; + rpass->rectx= rl->rectx; + rpass->recty= rl->recty; + BLI_strncpy(rpass->name, get_pass_name(rpass->passtype, -1), sizeof(rpass->name)); + + if(rr->exrhandle) { + int a; + for(a=0; aexrhandle, rl->name, get_pass_name(passtype, a), 0, 0, NULL); + } + else { + float *rect; + int x; + + rpass->rect= MEM_mapallocN(sizeof(float)*rectsize, typestr); + + if(passtype==SCE_PASS_VECTOR) { + /* initialize to max speed */ + rect= rpass->rect; + for(x= rectsize-1; x>=0; x--) + rect[x]= PASS_VECTOR_MAX; + } + else if(passtype==SCE_PASS_Z) { + rect= rpass->rect; + for(x= rectsize-1; x>=0; x--) + rect[x]= 10e10; + } + } +} + +/* called by main render as well for parts */ +/* will read info from Render *re to define layers */ +/* called in threads */ +/* re->winx,winy is coordinate space of entire image, partrct the part within */ +RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuffers) +{ + RenderResult *rr; + RenderLayer *rl; + SceneRenderLayer *srl; + int rectx, recty, nr; + + rectx= partrct->xmax - partrct->xmin; + recty= partrct->ymax - partrct->ymin; + + if(rectx<=0 || recty<=0) + return NULL; + + rr= MEM_callocN(sizeof(RenderResult), "new render result"); + rr->rectx= rectx; + rr->recty= recty; + rr->renrect.xmin= 0; rr->renrect.xmax= rectx-2*crop; + /* crop is one or two extra pixels rendered for filtering, is used for merging and display too */ + rr->crop= crop; + + /* tilerect is relative coordinates within render disprect. do not subtract crop yet */ + rr->tilerect.xmin= partrct->xmin - re->disprect.xmin; + rr->tilerect.xmax= partrct->xmax - re->disprect.xmax; + rr->tilerect.ymin= partrct->ymin - re->disprect.ymin; + rr->tilerect.ymax= partrct->ymax - re->disprect.ymax; + + if(savebuffers) { + rr->exrhandle= IMB_exr_get_handle(); + } + + /* check renderdata for amount of layers */ + for(nr=0, srl= re->r.layers.first; srl; srl= srl->next, nr++) { + + if((re->r.scemode & R_SINGLE_LAYER) && nr!=re->r.actlay) + continue; + if(srl->layflag & SCE_LAY_DISABLE) + continue; + + rl= MEM_callocN(sizeof(RenderLayer), "new render layer"); + BLI_addtail(&rr->layers, rl); + + BLI_strncpy(rl->name, srl->name, sizeof(rl->name)); + rl->lay= srl->lay; + rl->lay_zmask= srl->lay_zmask; + rl->layflag= srl->layflag; + rl->passflag= srl->passflag; // for debugging: srl->passflag|SCE_PASS_RAYHITS; + rl->pass_xor= srl->pass_xor; + rl->light_override= srl->light_override; + rl->mat_override= srl->mat_override; + rl->rectx= rectx; + rl->recty= recty; + + if(rr->exrhandle) { + IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.R", 0, 0, NULL); + IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.G", 0, 0, NULL); + IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.B", 0, 0, NULL); + IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.A", 0, 0, NULL); + } + else + rl->rectf= MEM_mapallocN(rectx*recty*sizeof(float)*4, "Combined rgba"); + + if(srl->passflag & SCE_PASS_Z) + render_layer_add_pass(rr, rl, 1, SCE_PASS_Z); + if(srl->passflag & SCE_PASS_VECTOR) + render_layer_add_pass(rr, rl, 4, SCE_PASS_VECTOR); + if(srl->passflag & SCE_PASS_NORMAL) + render_layer_add_pass(rr, rl, 3, SCE_PASS_NORMAL); + if(srl->passflag & SCE_PASS_UV) + render_layer_add_pass(rr, rl, 3, SCE_PASS_UV); + if(srl->passflag & SCE_PASS_RGBA) + render_layer_add_pass(rr, rl, 4, SCE_PASS_RGBA); + if(srl->passflag & SCE_PASS_EMIT) + render_layer_add_pass(rr, rl, 3, SCE_PASS_EMIT); + if(srl->passflag & SCE_PASS_DIFFUSE) + render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE); + if(srl->passflag & SCE_PASS_SPEC) + render_layer_add_pass(rr, rl, 3, SCE_PASS_SPEC); + if(srl->passflag & SCE_PASS_AO) + render_layer_add_pass(rr, rl, 3, SCE_PASS_AO); + if(srl->passflag & SCE_PASS_ENVIRONMENT) + render_layer_add_pass(rr, rl, 3, SCE_PASS_ENVIRONMENT); + if(srl->passflag & SCE_PASS_INDIRECT) + render_layer_add_pass(rr, rl, 3, SCE_PASS_INDIRECT); + if(srl->passflag & SCE_PASS_SHADOW) + render_layer_add_pass(rr, rl, 3, SCE_PASS_SHADOW); + if(srl->passflag & SCE_PASS_REFLECT) + render_layer_add_pass(rr, rl, 3, SCE_PASS_REFLECT); + if(srl->passflag & SCE_PASS_REFRACT) + render_layer_add_pass(rr, rl, 3, SCE_PASS_REFRACT); + if(srl->passflag & SCE_PASS_INDEXOB) + render_layer_add_pass(rr, rl, 1, SCE_PASS_INDEXOB); + if(srl->passflag & SCE_PASS_INDEXMA) + render_layer_add_pass(rr, rl, 1, SCE_PASS_INDEXMA); + if(srl->passflag & SCE_PASS_MIST) + render_layer_add_pass(rr, rl, 1, SCE_PASS_MIST); + if(rl->passflag & SCE_PASS_RAYHITS) + render_layer_add_pass(rr, rl, 4, SCE_PASS_RAYHITS); + if(srl->passflag & SCE_PASS_DIFFUSE_DIRECT) + render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE_DIRECT); + if(srl->passflag & SCE_PASS_DIFFUSE_INDIRECT) + render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE_INDIRECT); + if(srl->passflag & SCE_PASS_DIFFUSE_COLOR) + render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE_COLOR); + if(srl->passflag & SCE_PASS_GLOSSY_DIRECT) + render_layer_add_pass(rr, rl, 3, SCE_PASS_GLOSSY_DIRECT); + if(srl->passflag & SCE_PASS_GLOSSY_INDIRECT) + render_layer_add_pass(rr, rl, 3, SCE_PASS_GLOSSY_INDIRECT); + if(srl->passflag & SCE_PASS_GLOSSY_COLOR) + render_layer_add_pass(rr, rl, 3, SCE_PASS_GLOSSY_COLOR); + if(srl->passflag & SCE_PASS_TRANSM_DIRECT) + render_layer_add_pass(rr, rl, 3, SCE_PASS_TRANSM_DIRECT); + if(srl->passflag & SCE_PASS_TRANSM_INDIRECT) + render_layer_add_pass(rr, rl, 3, SCE_PASS_TRANSM_INDIRECT); + if(srl->passflag & SCE_PASS_TRANSM_COLOR) + render_layer_add_pass(rr, rl, 3, SCE_PASS_TRANSM_COLOR); + + } + /* sss, previewrender and envmap don't do layers, so we make a default one */ + if(rr->layers.first==NULL) { + rl= MEM_callocN(sizeof(RenderLayer), "new render layer"); + BLI_addtail(&rr->layers, rl); + + rl->rectx= rectx; + rl->recty= recty; + + /* duplicate code... */ + if(rr->exrhandle) { + IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.R", 0, 0, NULL); + IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.G", 0, 0, NULL); + IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.B", 0, 0, NULL); + IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.A", 0, 0, NULL); + } + else + rl->rectf= MEM_mapallocN(rectx*recty*sizeof(float)*4, "Combined rgba"); + + /* note, this has to be in sync with scene.c */ + rl->lay= (1<<20) -1; + rl->layflag= 0x7FFF; /* solid ztra halo strand */ + rl->passflag= SCE_PASS_COMBINED; + + re->r.actlay= 0; + } + + /* border render; calculate offset for use in compositor. compo is centralized coords */ + rr->xof= re->disprect.xmin + (re->disprect.xmax - re->disprect.xmin)/2 - re->winx/2; + rr->yof= re->disprect.ymin + (re->disprect.ymax - re->disprect.ymin)/2 - re->winy/2; + + return rr; +} + +/* allocate osa new results for samples */ +RenderResult *render_result_new_full_sample(Render *re, ListBase *lb, rcti *partrct, int crop, int savebuffers) +{ + int a; + + if(re->osa==0) + return render_result_new(re, partrct, crop, savebuffers); + + for(a=0; aosa; a++) { + RenderResult *rr= render_result_new(re, partrct, crop, savebuffers); + BLI_addtail(lb, rr); + rr->sample_nr= a; + } + + return lb->first; +} + +/* callbacks for render_result_new_from_exr */ +static void *ml_addlayer_cb(void *base, char *str) +{ + RenderResult *rr= base; + RenderLayer *rl; + + rl= MEM_callocN(sizeof(RenderLayer), "new render layer"); + BLI_addtail(&rr->layers, rl); + + BLI_strncpy(rl->name, str, EXR_LAY_MAXNAME); + return rl; +} + +static void ml_addpass_cb(void *UNUSED(base), void *lay, char *str, float *rect, int totchan, char *chan_id) +{ + RenderLayer *rl= lay; + RenderPass *rpass= MEM_callocN(sizeof(RenderPass), "loaded pass"); + int a; + + BLI_addtail(&rl->passes, rpass); + rpass->channels= totchan; + + rpass->passtype= passtype_from_name(str); + if(rpass->passtype==0) printf("unknown pass %s\n", str); + rl->passflag |= rpass->passtype; + + BLI_strncpy(rpass->name, str, EXR_PASS_MAXNAME); + /* channel id chars */ + for(a=0; achan_id[a]= chan_id[a]; + + rpass->rect= rect; +} + +/* from imbuf, if a handle was returned we convert this to render result */ +RenderResult *render_result_new_from_exr(void *exrhandle, int rectx, int recty) +{ + RenderResult *rr= MEM_callocN(sizeof(RenderResult), "loaded render result"); + RenderLayer *rl; + RenderPass *rpass; + + rr->rectx= rectx; + rr->recty= recty; + + IMB_exr_multilayer_convert(exrhandle, rr, ml_addlayer_cb, ml_addpass_cb); + + for(rl=rr->layers.first; rl; rl=rl->next) { + rl->rectx= rectx; + rl->recty= recty; + + for(rpass=rl->passes.first; rpass; rpass=rpass->next) { + rpass->rectx= rectx; + rpass->recty= recty; + } + } + + return rr; +} + +/*********************************** Merge ***********************************/ + +static void do_merge_tile(RenderResult *rr, RenderResult *rrpart, float *target, float *tile, int pixsize) +{ + int y, ofs, copylen, tilex, tiley; + + copylen= tilex= rrpart->rectx; + tiley= rrpart->recty; + + if(rrpart->crop) { /* filters add pixel extra */ + tile+= pixsize*(rrpart->crop + rrpart->crop*tilex); + + copylen= tilex - 2*rrpart->crop; + tiley -= 2*rrpart->crop; + + ofs= (rrpart->tilerect.ymin + rrpart->crop)*rr->rectx + (rrpart->tilerect.xmin+rrpart->crop); + target+= pixsize*ofs; + } + else { + ofs= (rrpart->tilerect.ymin*rr->rectx + rrpart->tilerect.xmin); + target+= pixsize*ofs; + } + + copylen *= sizeof(float)*pixsize; + tilex *= pixsize; + ofs= pixsize*rr->rectx; + + for(y=0; ylayers.first, rlp= rrpart->layers.first; rl && rlp; rl= rl->next, rlp= rlp->next) { + + /* combined */ + if(rl->rectf && rlp->rectf) + do_merge_tile(rr, rrpart, rl->rectf, rlp->rectf, 4); + + /* passes are allocated in sync */ + for(rpass= rl->passes.first, rpassp= rlp->passes.first; rpass && rpassp; rpass= rpass->next, rpassp= rpassp->next) { + do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, rpass->channels); + } + } +} + +/* for passes read from files, these have names stored */ +static char *make_pass_name(RenderPass *rpass, int chan) +{ + static char name[16]; + int len; + + BLI_strncpy(name, rpass->name, EXR_PASS_MAXNAME); + len= strlen(name); + name[len]= '.'; + name[len+1]= rpass->chan_id[chan]; + name[len+2]= 0; + + return name; +} + +/* filename already made absolute */ +/* called from within UI, saves both rendered result as a file-read result */ +int RE_WriteRenderResult(ReportList *reports, RenderResult *rr, const char *filename, int compress) +{ + RenderLayer *rl; + RenderPass *rpass; + void *exrhandle= IMB_exr_get_handle(); + int success; + + BLI_make_existing_file(filename); + + /* composite result */ + if(rr->rectf) { + IMB_exr_add_channel(exrhandle, "Composite", "Combined.R", 4, 4*rr->rectx, rr->rectf); + IMB_exr_add_channel(exrhandle, "Composite", "Combined.G", 4, 4*rr->rectx, rr->rectf+1); + IMB_exr_add_channel(exrhandle, "Composite", "Combined.B", 4, 4*rr->rectx, rr->rectf+2); + IMB_exr_add_channel(exrhandle, "Composite", "Combined.A", 4, 4*rr->rectx, rr->rectf+3); + } + + /* add layers/passes and assign channels */ + for(rl= rr->layers.first; rl; rl= rl->next) { + + /* combined */ + if(rl->rectf) { + int a, xstride= 4; + for(a=0; aname, get_pass_name(SCE_PASS_COMBINED, a), + xstride, xstride*rr->rectx, rl->rectf+a); + } + + /* passes are allocated in sync */ + for(rpass= rl->passes.first; rpass; rpass= rpass->next) { + int a, xstride= rpass->channels; + for(a=0; apasstype) + IMB_exr_add_channel(exrhandle, rl->name, get_pass_name(rpass->passtype, a), + xstride, xstride*rr->rectx, rpass->rect+a); + else + IMB_exr_add_channel(exrhandle, rl->name, make_pass_name(rpass, a), + xstride, xstride*rr->rectx, rpass->rect+a); + } + } + } + + /* when the filename has no permissions, this can fail */ + if(IMB_exr_begin_write(exrhandle, filename, rr->rectx, rr->recty, compress)) { + IMB_exr_write_channels(exrhandle); + success= TRUE; + } + else { + /* TODO, get the error from openexr's exception */ + BKE_report(reports, RPT_ERROR, "Error Writing Render Result, see console"); + success= FALSE; + } + IMB_exr_close(exrhandle); + + return success; +} + +/**************************** Single Layer Rendering *************************/ + +void render_result_single_layer_begin(Render *re) +{ + /* all layers except the active one get temporally pushed away */ + + /* officially pushed result should be NULL... error can happen with do_seq */ + RE_FreeRenderResult(re->pushedresult); + + re->pushedresult= re->result; + re->result= NULL; +} + +/* if scemode is R_SINGLE_LAYER, at end of rendering, merge the both render results */ +void render_result_single_layer_end(Render *re) +{ + SceneRenderLayer *srl; + RenderLayer *rlpush; + RenderLayer *rl; + int nr; + + if(re->result==NULL) { + printf("pop render result error; no current result!\n"); + return; + } + + if(!re->pushedresult) + return; + + if(re->pushedresult->rectx==re->result->rectx && re->pushedresult->recty==re->result->recty) { + /* find which layer in re->pushedresult should be replaced */ + rl= re->result->layers.first; + + /* render result should be empty after this */ + BLI_remlink(&re->result->layers, rl); + + /* reconstruct render result layers */ + for(nr=0, srl= re->scene->r.layers.first; srl; srl= srl->next, nr++) { + if(nr==re->r.actlay) + BLI_addtail(&re->result->layers, rl); + else { + rlpush= RE_GetRenderLayer(re->pushedresult, srl->name); + if(rlpush) { + BLI_remlink(&re->pushedresult->layers, rlpush); + BLI_addtail(&re->result->layers, rlpush); + } + } + } + } + + RE_FreeRenderResult(re->pushedresult); + re->pushedresult= NULL; +} + +/************************* EXR Tile File Rendering ***************************/ + +static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart) +{ + RenderLayer *rlp; + RenderPass *rpassp; + int offs, partx, party; + + BLI_lock_thread(LOCK_IMAGE); + + for(rlp= rrpart->layers.first; rlp; rlp= rlp->next) { + + if(rrpart->crop) { /* filters add pixel extra */ + offs= (rrpart->crop + rrpart->crop*rrpart->rectx); + } + else { + offs= 0; + } + + /* combined */ + if(rlp->rectf) { + int a, xstride= 4; + for(a=0; aexrhandle, rlp->name, get_pass_name(SCE_PASS_COMBINED, a), + xstride, xstride*rrpart->rectx, rlp->rectf+a + xstride*offs); + } + + /* passes are allocated in sync */ + for(rpassp= rlp->passes.first; rpassp; rpassp= rpassp->next) { + int a, xstride= rpassp->channels; + for(a=0; aexrhandle, rlp->name, get_pass_name(rpassp->passtype, a), + xstride, xstride*rrpart->rectx, rpassp->rect+a + xstride*offs); + } + + } + + party= rrpart->tilerect.ymin + rrpart->crop; + partx= rrpart->tilerect.xmin + rrpart->crop; + IMB_exrtile_write_channels(rr->exrhandle, partx, party, 0); + + BLI_unlock_thread(LOCK_IMAGE); +} + +static void save_empty_result_tiles(Render *re) +{ + RenderPart *pa; + RenderResult *rr; + + for(rr= re->result; rr; rr= rr->next) { + IMB_exrtile_clear_channels(rr->exrhandle); + + for(pa= re->parts.first; pa; pa= pa->next) { + if(pa->ready==0) { + int party= pa->disprect.ymin - re->disprect.ymin + pa->crop; + int partx= pa->disprect.xmin - re->disprect.xmin + pa->crop; + IMB_exrtile_write_channels(rr->exrhandle, partx, party, 0); + } + } + } +} + +/* begin write of exr tile file */ +void render_result_exr_file_begin(Render *re) +{ + RenderResult *rr; + char str[FILE_MAX]; + + for(rr= re->result; rr; rr= rr->next) { + render_result_exr_file_path(re->scene, rr->sample_nr, str); + + printf("write exr tmp file, %dx%d, %s\n", rr->rectx, rr->recty, str); + IMB_exrtile_begin_write(rr->exrhandle, str, 0, rr->rectx, rr->recty, re->partx, re->party); + } +} + +/* end write of exr tile file, read back first sample */ +void render_result_exr_file_end(Render *re) +{ + RenderResult *rr; + + save_empty_result_tiles(re); + + for(rr= re->result; rr; rr= rr->next) { + IMB_exr_close(rr->exrhandle); + rr->exrhandle= NULL; + } + + render_result_free_list(&re->fullresult, re->result); + re->result= NULL; + + render_result_exr_file_read(re, 0); +} + +/* save part into exr file */ +void render_result_exr_file_merge(RenderResult *rr, RenderResult *rrpart) +{ + for(; rr && rrpart; rr= rr->next, rrpart= rrpart->next) + save_render_result_tile(rr, rrpart); +} + +/* path to temporary exr file */ +void render_result_exr_file_path(Scene *scene, int sample, char *filepath) +{ + char di[FILE_MAX], name[FILE_MAXFILE+MAX_ID_NAME+100], fi[FILE_MAXFILE]; + + BLI_strncpy(di, G.main->name, FILE_MAX); + BLI_splitdirstring(di, fi); + + if(sample==0) + BLI_snprintf(name, sizeof(name), "%s_%s.exr", fi, scene->id.name+2); + else + BLI_snprintf(name, sizeof(name), "%s_%s%d.exr", fi, scene->id.name+2, sample); + + BLI_make_file_string("/", filepath, BLI_temporary_dir(), name); +} + +/* only for temp buffer files, makes exact copy of render result */ +int render_result_exr_file_read(Render *re, int sample) +{ + char str[FILE_MAX]; + int success; + + RE_FreeRenderResult(re->result); + re->result= render_result_new(re, &re->disprect, 0, RR_USE_MEM); + + render_result_exr_file_path(re->scene, sample, str); + printf("read exr tmp file: %s\n", str); + + if(render_result_exr_file_read_path(re->result, str)) { + success= TRUE; + } + else { + printf("cannot read: %s\n", str); + success= FALSE; + + } + + return success; +} + +/* called for reading temp files, and for external engines */ +int render_result_exr_file_read_path(RenderResult *rr, const char *filepath) +{ + RenderLayer *rl; + RenderPass *rpass; + void *exrhandle= IMB_exr_get_handle(); + int rectx, recty; + + if(IMB_exr_begin_read(exrhandle, filepath, &rectx, &recty)==0) { + printf("failed being read %s\n", filepath); + IMB_exr_close(exrhandle); + return 0; + } + + if(rr == NULL || rectx!=rr->rectx || recty!=rr->recty) { + if(rr) + printf("error in reading render result: dimensions don't match\n"); + else + printf("error in reading render result: NULL result pointer\n"); + IMB_exr_close(exrhandle); + return 0; + } + + for(rl= rr->layers.first; rl; rl= rl->next) { + /* combined */ + if(rl->rectf) { + int a, xstride= 4; + for(a=0; aname, get_pass_name(SCE_PASS_COMBINED, a), + xstride, xstride*rectx, rl->rectf+a); + } + + /* passes are allocated in sync */ + for(rpass= rl->passes.first; rpass; rpass= rpass->next) { + int a, xstride= rpass->channels; + for(a=0; aname, get_pass_name(rpass->passtype, a), + xstride, xstride*rectx, rpass->rect+a); + + BLI_strncpy(rpass->name, get_pass_name(rpass->passtype, -1), sizeof(rpass->name)); + } + } + + IMB_exr_read_channels(exrhandle); + IMB_exr_close(exrhandle); + + return 1; +} + +/*************************** Combined Pixel Rect *****************************/ + +ImBuf *render_result_rect_to_ibuf(RenderResult *rr, RenderData *rd) +{ + int flags = (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE)? IB_cm_predivide: 0; + ImBuf *ibuf= IMB_allocImBuf(rr->rectx, rr->recty, rd->im_format.planes, flags); + + /* if not exists, BKE_write_ibuf makes one */ + ibuf->rect= (unsigned int *)rr->rect32; + ibuf->rect_float= rr->rectf; + ibuf->zbuf_float= rr->rectz; + + /* float factor for random dither, imbuf takes care of it */ + ibuf->dither= rd->dither_intensity; + + /* prepare to gamma correct to sRGB color space */ + if (rd->color_mgt_flag & R_COLOR_MANAGEMENT) { + /* sequence editor can generate 8bpc render buffers */ + if (ibuf->rect) { + ibuf->profile = IB_PROFILE_SRGB; + if (BKE_imtype_valid_depths(rd->im_format.imtype) & (R_IMF_CHAN_DEPTH_12|R_IMF_CHAN_DEPTH_16|R_IMF_CHAN_DEPTH_24|R_IMF_CHAN_DEPTH_32)) + IMB_float_from_rect(ibuf); + } else { + ibuf->profile = IB_PROFILE_LINEAR_RGB; + } + } + + /* color -> greyscale */ + /* editing directly would alter the render view */ + if(rd->im_format.planes == R_IMF_PLANES_BW) { + ImBuf *ibuf_bw= IMB_dupImBuf(ibuf); + IMB_color_to_bw(ibuf_bw); + IMB_freeImBuf(ibuf); + ibuf= ibuf_bw; + } + + return ibuf; +} + +void render_result_rect_from_ibuf(RenderResult *rr, RenderData *rd, ImBuf *ibuf) +{ + if(ibuf->rect_float) { + /* color management: when off ensure rectf is non-lin, since thats what the internal + * render engine delivers */ + int profile_to= (rd->color_mgt_flag & R_COLOR_MANAGEMENT)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB; + int profile_from= (ibuf->profile == IB_PROFILE_LINEAR_RGB)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB; + int predivide= (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE); + + if (!rr->rectf) + rr->rectf= MEM_mallocN(4*sizeof(float)*rr->rectx*rr->recty, "render_seq rectf"); + + IMB_buffer_float_from_float(rr->rectf, ibuf->rect_float, + 4, profile_to, profile_from, predivide, + rr->rectx, rr->recty, rr->rectx, rr->rectx); + + /* TSK! Since sequence render doesn't free the *rr render result, the old rect32 + can hang around when sequence render has rendered a 32 bits one before */ + if(rr->rect32) { + MEM_freeN(rr->rect32); + rr->rect32= NULL; + } + } + else if(ibuf->rect) { + if (!rr->rect32) + rr->rect32= MEM_mallocN(sizeof(int)*rr->rectx*rr->recty, "render_seq rect"); + + memcpy(rr->rect32, ibuf->rect, 4*rr->rectx*rr->recty); + + /* Same things as above, old rectf can hang around from previous render. */ + if(rr->rectf) { + MEM_freeN(rr->rectf); + rr->rectf= NULL; + } + } +} + +void render_result_rect_fill_zero(RenderResult *rr) +{ + if (rr->rectf) + memset(rr->rectf, 0, 4*sizeof(float)*rr->rectx*rr->recty); + else if (rr->rect32) + memset(rr->rect32, 0, 4*rr->rectx*rr->recty); + else + rr->rect32= MEM_callocN(sizeof(int)*rr->rectx*rr->recty, "render_seq rect"); +} + +void render_result_rect_get_pixels(RenderResult *rr, RenderData *rd, unsigned int *rect, int rectx, int recty) +{ + if(rr->rect32) { + memcpy(rect, rr->rect32, sizeof(int)*rr->rectx*rr->recty); + } + else if(rr->rectf) { + int profile_from= (rd->color_mgt_flag & R_COLOR_MANAGEMENT)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB; + int predivide= (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE); + int dither= 0; + + IMB_buffer_byte_from_float((unsigned char*)rect, rr->rectf, + 4, dither, IB_PROFILE_SRGB, profile_from, predivide, + rr->rectx, rr->recty, rr->rectx, rr->rectx); + } + else + /* else fill with black */ + memset(rect, 0, sizeof(int)*rectx*recty); +} + diff -Nru blender-2.61/source/blender/render/intern/source/render_texture.c blender-2.62/source/blender/render/intern/source/render_texture.c --- blender-2.61/source/blender/render/intern/source/render_texture.c 2011-12-13 19:48:16.000000000 +0000 +++ blender-2.62/source/blender/render/intern/source/render_texture.c 2012-02-15 19:32:55.000000000 +0000 @@ -1968,7 +1968,10 @@ if(shi->obr->ob->derivedFinal) { auto_bump = shi->obr->ob->derivedFinal->auto_bump_scale; - auto_bump /= sqrtf((float) (dimx*dimy)); + } + { + float fVirtDim = sqrtf(fabsf((float) (dimx*dimy)*mtex->size[0]*mtex->size[1])); + auto_bump /= MAX2(fVirtDim, FLT_EPSILON); } // this variant using a derivative map is described here @@ -2087,7 +2090,7 @@ if( mtex->texflag & MTEX_BUMP_OBJECTSPACE ) { // TODO: these calculations happen for every pixel! // -> move to shi->obi - mul_m4_m4m4(tmp, shi->obr->ob->obmat, R.viewmat); + mult_m4_m4m4(tmp, R.viewmat, shi->obr->ob->obmat); copy_m3_m4(obj2view, tmp); // use only upper left 3x3 matrix invert_m3_m3(view2obj, obj2view); @@ -2124,7 +2127,8 @@ fMagnitude *= len_v3(vN); } - for(xyz=0; xyz<3; xyz++) + if(ntap_bump->fPrevMagnitude > 0.0f) + for(xyz=0; xyz<3; xyz++) ntap_bump->vNacc[xyz] *= fMagnitude / ntap_bump->fPrevMagnitude; ntap_bump->fPrevMagnitude = fMagnitude; @@ -2191,7 +2195,7 @@ found_deriv_map = (tex->type==TEX_IMAGE) && (tex->imaflag & TEX_DERIVATIVEMAP); use_compat_bump= (mtex->texflag & MTEX_COMPAT_BUMP); - use_ntap_bump= ((mtex->texflag & (MTEX_3TAP_BUMP|MTEX_5TAP_BUMP))!=0 || found_deriv_map!=0) ? 1 : 0; + use_ntap_bump= ((mtex->texflag & (MTEX_3TAP_BUMP|MTEX_5TAP_BUMP|MTEX_BICUBIC_BUMP))!=0 || found_deriv_map!=0) ? 1 : 0; /* XXX texture node trees don't work for this yet */ if(tex->nodetree && tex->use_nodes) { @@ -3083,6 +3087,12 @@ continue; } break; + case TEXCO_EQUIRECTMAP: + tempvec[0]= atan2f(lo[0], lo[2]) / (float)M_PI; + tempvec[1]= 1.0f - 2.0f*saacos(lo[1]) / (float)M_PI; + tempvec[2]= 0.0f; + co= tempvec; + break; case TEXCO_OBJECT: if(mtex->object) { copy_v3_v3(tempvec, lo); diff -Nru blender-2.61/source/blender/render/intern/source/shadbuf.c blender-2.62/source/blender/render/intern/source/shadbuf.c --- blender-2.61/source/blender/render/intern/source/shadbuf.c 2011-12-13 19:48:16.000000000 +0000 +++ blender-2.62/source/blender/render/intern/source/shadbuf.c 2012-02-15 19:32:55.000000000 +0000 @@ -640,7 +640,7 @@ obr= obi->obr; if(obi->flag & R_TRANSFORMED) - mul_m4_m4m4(obviewmat, obi->mat, viewmat); + mult_m4_m4m4(obviewmat, viewmat, obi->mat); else copy_m4_m4(obviewmat, viewmat); @@ -777,7 +777,7 @@ wsize= shb->pixsize*(shb->size/2.0f); perspective_m4( shb->winmat,-wsize, wsize, -wsize, wsize, shb->d, shb->clipend); - mul_m4_m4m4(shb->persmat, shb->viewmat, shb->winmat); + mult_m4_m4m4(shb->persmat, shb->winmat, shb->viewmat); if(ELEM3(lar->buftype, LA_SHADBUF_REGULAR, LA_SHADBUF_HALFWAY, LA_SHADBUF_DEEP)) { shb->totbuf= lar->buffers; @@ -1987,7 +1987,7 @@ obr= obi->obr; if(obi->flag & R_TRANSFORMED) - mul_m4_m4m4(winmat, obi->mat, shb->persmat); + mult_m4_m4m4(winmat, shb->persmat, obi->mat); else copy_m4_m4(winmat, shb->persmat); @@ -2068,7 +2068,7 @@ mul_m4_v3(obi->mat, v1); /* from shadepixel() */ - dface= v1[0]*nor[0] + v1[1]*nor[1] + v1[2]*nor[2]; + dface = dot_v3v3(v1, nor); hoco[3]= 1.0f; /* ortho viewplane cannot intersect using view vector originating in (0,0,0) */ @@ -2091,7 +2091,7 @@ calc_view_vector(view, x, y); - div= nor[0]*view[0] + nor[1]*view[1] + nor[2]*view[2]; + div = dot_v3v3(nor, view); if (div==0.0f) return 0; diff -Nru blender-2.61/source/blender/render/intern/source/shadeinput.c blender-2.62/source/blender/render/intern/source/shadeinput.c --- blender-2.61/source/blender/render/intern/source/shadeinput.c 2011-12-13 19:48:16.000000000 +0000 +++ blender-2.62/source/blender/render/intern/source/shadeinput.c 2012-02-15 19:32:55.000000000 +0000 @@ -608,7 +608,7 @@ if(shi->obi->flag & R_TRANSFORMED) mul_m4_v3(shi->obi->mat, v1); - dface= v1[0]*shi->facenor[0]+v1[1]*shi->facenor[1]+v1[2]*shi->facenor[2]; + dface = dot_v3v3(v1, shi->facenor); /* ortho viewplane cannot intersect using view vector originating in (0,0,0) */ if(R.r.mode & R_ORTHO) { @@ -650,7 +650,7 @@ else { float div; - div= shi->facenor[0]*view[0] + shi->facenor[1]*view[1] + shi->facenor[2]*view[2]; + div = dot_v3v3(shi->facenor, view); if (div!=0.0f) fac= dface/div; else fac= 0.0f; @@ -1268,7 +1268,7 @@ zbuf_make_winmat(&R, winmat); if(shi->obi->flag & R_TRANSFORMED) - mul_m4_m4m4(obwinmat, obi->mat, winmat); + mult_m4_m4m4(obwinmat, winmat, obi->mat); else copy_m4_m4(obwinmat, winmat); diff -Nru blender-2.61/source/blender/render/intern/source/shadeoutput.c blender-2.62/source/blender/render/intern/source/shadeoutput.c --- blender-2.61/source/blender/render/intern/source/shadeoutput.c 2011-12-13 19:48:16.000000000 +0000 +++ blender-2.62/source/blender/render/intern/source/shadeoutput.c 2012-02-15 19:32:55.000000000 +0000 @@ -269,14 +269,12 @@ if(p1[2]<-ladist) t1= t3; } else { - ok1= 1; t1= t3; } if(ok2) { if(p2[2]<-ladist) t2= t3; } else { - ok2= 1; t2= t3; } } @@ -902,7 +900,7 @@ if(ma->ramp_col) { if(ma->rampin_col==MA_RAMP_IN_RESULT) { - float fac= 0.3f*diff[0] + 0.58f*diff[1] + 0.12f*diff[2]; + float fac = rgb_to_grayscale(diff); do_colorband(ma->ramp_col, fac, col); /* blending method */ @@ -934,6 +932,7 @@ /* input */ switch(ma->rampin_col) { case MA_RAMP_IN_ENERGY: + /* should use 'rgb_to_grayscale' but we only have a vector version */ fac= 0.3f*r + 0.58f*g + 0.12f*b; break; case MA_RAMP_IN_SHADER: @@ -976,7 +975,7 @@ if(ma->ramp_spec && (ma->rampin_spec==MA_RAMP_IN_RESULT)) { float col[4]; - float fac= 0.3f*spec_col[0] + 0.58f*spec_col[1] + 0.12f*spec_col[2]; + float fac = rgb_to_grayscale(spec_col); do_colorband(ma->ramp_spec, fac, col); @@ -1031,12 +1030,17 @@ /* preprocess, textures were not done, don't use shi->amb for that reason */ void ambient_occlusion(ShadeInput *shi) { - if((R.wrld.ao_gather_method == WO_AOGATHER_APPROX) && shi->mat->amb!=0.0f) + if((R.wrld.ao_gather_method == WO_AOGATHER_APPROX) && shi->mat->amb!=0.0f) { sample_occ(&R, shi); - else if((R.r.mode & R_RAYTRACE) && shi->mat->amb!=0.0f) + } + else if((R.r.mode & R_RAYTRACE) && shi->mat->amb!=0.0f) { ray_ao(shi, shi->ao, shi->env); - else + } + else { shi->ao[0]= shi->ao[1]= shi->ao[2]= 1.0f; + zero_v3(shi->env); + zero_v3(shi->indirect); + } } @@ -1714,9 +1718,9 @@ } if( (ma->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))== MA_VERTEXCOL ) { // vertexcolor light - shr->emit[0]= shi->r*(shi->emit+shi->vcol[0]); - shr->emit[1]= shi->g*(shi->emit+shi->vcol[1]); - shr->emit[2]= shi->b*(shi->emit+shi->vcol[2]); + shr->emit[0]= shi->r*(shi->emit+shi->vcol[0]*shi->vcol[3]); + shr->emit[1]= shi->g*(shi->emit+shi->vcol[1]*shi->vcol[3]); + shr->emit[2]= shi->b*(shi->emit+shi->vcol[2]*shi->vcol[3]); } else { shr->emit[0]= shi->r*shi->emit; diff -Nru blender-2.61/source/blender/render/intern/source/strand.c blender-2.62/source/blender/render/intern/source/strand.c --- blender-2.61/source/blender/render/intern/source/strand.c 2011-12-13 19:48:16.000000000 +0000 +++ blender-2.62/source/blender/render/intern/source/strand.c 2012-02-15 19:32:55.000000000 +0000 @@ -833,7 +833,6 @@ memarena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "strand sort arena"); firstseg= NULL; - sortseg= sortsegments; totsegment= 0; /* for all object instances */ @@ -848,7 +847,7 @@ /* compute matrix and try clipping whole object */ if(obi->flag & R_TRANSFORMED) - mul_m4_m4m4(obwinmat, obi->mat, winmat); + mult_m4_m4m4(obwinmat, winmat, obi->mat); else copy_m4_m4(obwinmat, winmat); diff -Nru blender-2.61/source/blender/render/intern/source/volumetric.c blender-2.62/source/blender/render/intern/source/volumetric.c --- blender-2.61/source/blender/render/intern/source/volumetric.c 2011-12-13 19:48:16.000000000 +0000 +++ blender-2.62/source/blender/render/intern/source/volumetric.c 2012-02-15 19:32:55.000000000 +0000 @@ -245,7 +245,7 @@ /* transform co to meta-element */ float tco[3] = {co[0], co[1], co[2]}; - mul_m4_m4m4(mat, ob->obmat, R.viewmat); + mult_m4_m4m4(mat, R.viewmat, ob->obmat); invert_m4_m4(imat, mat); mul_m4_v3(imat, tco); @@ -274,7 +274,7 @@ } /* ml->rad2 is not set */ - dist2 = 1.f - ((tp[0]*tp[0] + tp[1]*tp[1] + tp[2]*tp[2]) / (ml->rad*ml->rad)); + dist2 = 1.0f - (dot_v3v3(tp, tp) / (ml->rad * ml->rad)); if (dist2 > 0.f) dens += (ml->flag & MB_NEGATIVE) ? -ml->s*dist2*dist2*dist2 : ml->s*dist2*dist2*dist2; } @@ -746,7 +746,6 @@ float tr[3] = {1.0,1.0,1.0}; Isect is= {{0}}; float *startco, *endco; - int intersect_type = VOL_BOUNDS_DEPTH; memset(shr, 0, sizeof(ShadeResult)); @@ -755,12 +754,11 @@ if (shi->flippednor) { startco = last_is->start; endco = shi->co; - intersect_type = VOL_BOUNDS_SS; } /* trace to find a backface, the other side bounds of the volume */ /* (ray intersect ignores front faces here) */ - else if (vol_get_bounds(shi, shi->co, shi->view, hitco, &is, intersect_type)) { + else if (vol_get_bounds(shi, shi->co, shi->view, hitco, &is, VOL_BOUNDS_DEPTH)) { startco = shi->co; endco = hitco; } diff -Nru blender-2.61/source/blender/render/intern/source/zbuf.c blender-2.62/source/blender/render/intern/source/zbuf.c --- blender-2.61/source/blender/render/intern/source/zbuf.c 2011-12-13 19:48:16.000000000 +0000 +++ blender-2.62/source/blender/render/intern/source/zbuf.c 2012-02-15 19:32:55.000000000 +0000 @@ -63,6 +63,7 @@ /* local includes */ #include "gammaCorrectionTables.h" #include "pixelblending.h" +#include "render_result.h" #include "render_types.h" #include "renderpipeline.h" #include "renderdatabase.h" @@ -211,9 +212,9 @@ } /* based on Liang&Barsky, for clipping of pyramidical volume */ -static short cliptestf(float p, float q, float *u1, float *u2) +static short cliptestf(float a, float b, float c, float d, float *u1, float *u2) { - float r; + float p= a + b, q= c + d, r; if(p<0.0f) { if(q abs4) c+=2; @@ -853,20 +854,20 @@ filled in with zbufwire correctly when rendering in parts. otherwise you see line endings at edges... */ - if(cliptestf(-dz-dw, v1[3]+v1[2], &u1,&u2)) { - if(cliptestf(dz-dw, v1[3]-v1[2], &u1,&u2)) { + if(cliptestf(-dz, -dw, v1[3], v1[2], &u1,&u2)) { + if(cliptestf(dz, -dw, v1[3], -v1[2], &u1,&u2)) { dx= v2[0]-v1[0]; dz= 1.01f*(v2[3]-v1[3]); v13= 1.01f*v1[3]; - if(cliptestf(-dx-dz, v1[0]+v13, &u1,&u2)) { - if(cliptestf(dx-dz, v13-v1[0], &u1,&u2)) { + if(cliptestf(-dx, -dz, v1[0], v13, &u1,&u2)) { + if(cliptestf(dx, -dz, v13, -v1[0], &u1,&u2)) { dy= v2[1]-v1[1]; - if(cliptestf(-dy-dz, v1[1]+v13, &u1,&u2)) { - if(cliptestf(dy-dz, v13-v1[1], &u1,&u2)) { + if(cliptestf(-dy, -dz, v1[1], v13, &u1,&u2)) { + if(cliptestf(dy, -dz, v13, -v1[1], &u1,&u2)) { if(u2<1.0f) { v2[0]= v1[0]+u2*dx; @@ -1035,6 +1036,9 @@ * @param v2 [4 floats, world coordinates] second vertex * @param v3 [4 floats, world coordinates] third vertex */ + +/* WATCH IT: zbuffillGLinv4 and zbuffillGL4 are identical except for a 2 lines, + * commented below */ static void zbuffillGLinv4(ZSpan *zspan, int obi, int zvlnr, float *v1, float *v2, float *v3, float *v4) { double zxd, zyd, zy0, zverg; @@ -1046,10 +1050,10 @@ int *rectmaskofs, *rm; int *rz, x, y; int sn1, sn2, rectx, *rectzofs, my0, my2; - + /* init */ zbuf_init_span(zspan); - + /* set spans */ zbuf_add_to_span(zspan, v1, v2); zbuf_add_to_span(zspan, v2, v3); @@ -1057,19 +1061,19 @@ zbuf_add_to_span(zspan, v3, v4); zbuf_add_to_span(zspan, v4, v1); } - else + else zbuf_add_to_span(zspan, v3, v1); - + /* clipped */ if(zspan->minp2==NULL || zspan->maxp2==NULL) return; - + if(zspan->miny1 < zspan->miny2) my0= zspan->miny2; else my0= zspan->miny1; if(zspan->maxy1 > zspan->maxy2) my2= zspan->maxy2; else my2= zspan->maxy1; - + // printf("my %d %d\n", my0, my2); if(my2rectx; rectzofs= (zspan->rectz+rectx*my2); rectpofs= (zspan->rectp+rectx*my2); rectoofs= (zspan->recto+rectx*my2); rectmaskofs= (zspan->rectmask+rectx*my2); - + /* correct span */ sn1= (my0 + my2)/2; if(zspan->span1[sn1] < zspan->span2[sn1]) { @@ -1106,45 +1110,45 @@ span1= zspan->span2+my2; span2= zspan->span1+my2; } - + for(y=my2; y>=my0; y--, span1--, span2--) { - + sn1= floor(*span1); sn2= floor(*span2); - sn1++; - + sn1++; + if(sn2>=rectx) sn2= rectx-1; if(sn1<0) sn1= 0; - + if(sn2>=sn1) { int intzverg; - + zverg= (double)sn1*zxd + zy0; rz= rectzofs+sn1; rp= rectpofs+sn1; ro= rectoofs+sn1; rm= rectmaskofs+sn1; x= sn2-sn1; - + while(x>=0) { intzverg= (int)CLAMPIS(zverg, INT_MIN, INT_MAX); - if( intzverg > *rz || *rz==0x7FFFFFFF) { + if( intzverg > *rz || *rz==0x7FFFFFFF) { /* UNIQUE LINE: see comment above */ if(!zspan->rectmask || intzverg > *rm) { - *ro= obi; + *ro= obi; /* UNIQUE LINE: see comment above (order differs) */ *rz= intzverg; *rp= zvlnr; } } zverg+= zxd; - rz++; - rp++; + rz++; + rp++; ro++; rm++; x--; } } - + zy0-=zyd; rectzofs-= rectx; rectpofs-= rectx; @@ -1155,6 +1159,8 @@ /* uses spanbuffers */ +/* WATCH IT: zbuffillGLinv4 and zbuffillGL4 are identical except for a 2 lines, + * commented below */ static void zbuffillGL4(ZSpan *zspan, int obi, int zvlnr, float *v1, float *v2, float *v3, float *v4) { double zxd, zyd, zy0, zverg; @@ -1166,10 +1172,10 @@ int *rectmaskofs, *rm; int *rz, x, y; int sn1, sn2, rectx, *rectzofs, my0, my2; - + /* init */ zbuf_init_span(zspan); - + /* set spans */ zbuf_add_to_span(zspan, v1, v2); zbuf_add_to_span(zspan, v2, v3); @@ -1177,19 +1183,19 @@ zbuf_add_to_span(zspan, v3, v4); zbuf_add_to_span(zspan, v4, v1); } - else + else zbuf_add_to_span(zspan, v3, v1); - + /* clipped */ if(zspan->minp2==NULL || zspan->maxp2==NULL) return; - + if(zspan->miny1 < zspan->miny2) my0= zspan->miny2; else my0= zspan->miny1; if(zspan->maxy1 > zspan->maxy2) my2= zspan->maxy2; else my2= zspan->maxy1; - -// printf("my %d %d\n", my0, my2); + + // printf("my %d %d\n", my0, my2); if(my2span2+my2; span2= zspan->span1+my2; } - + for(y=my2; y>=my0; y--, span1--, span2--) { - + sn1= floor(*span1); sn2= floor(*span2); - sn1++; - + sn1++; + if(sn2>=rectx) sn2= rectx-1; if(sn1<0) sn1= 0; - + if(sn2>=sn1) { int intzverg; - + zverg= (double)sn1*zxd + zy0; rz= rectzofs+sn1; rp= rectpofs+sn1; ro= rectoofs+sn1; rm= rectmaskofs+sn1; x= sn2-sn1; - + while(x>=0) { intzverg= (int)CLAMPIS(zverg, INT_MIN, INT_MAX); - - if(intzverg < *rz) { + + if(intzverg < *rz) { /* ONLY UNIQUE LINE: see comment above */ if(!zspan->rectmask || intzverg > *rm) { *rz= intzverg; *rp= zvlnr; - *ro= obi; + *ro= obi; /* UNIQUE LINE: see comment above (order differs) */ } } zverg+= zxd; - rz++; - rp++; - ro++; + rz++; + rp++; + ro++; rm++; x--; } } - + zy0-=zyd; rectzofs-= rectx; rectpofs-= rectx; @@ -1622,8 +1628,8 @@ * who would have thought that of L&B! */ - if(cliptestf(-da-dw, v13+v1[a], &u1,&u2)) { - if(cliptestf(da-dw, v13-v1[a], &u1,&u2)) { + if(cliptestf(-da, -dw, v13, v1[a], &u1,&u2)) { + if(cliptestf(da, -dw, v13, -v1[a], &u1,&u2)) { *b3=1; if(u2<1.0f) { labda[1]= u2; @@ -1819,7 +1825,7 @@ panomat[2][0]= -re->panosi; panomat[2][2]= re->panoco; - mul_m4_m4m4(winmat, panomat, re->winmat); + mult_m4_m4m4(winmat, re->winmat, panomat); } else copy_m4_m4(winmat, re->winmat); @@ -2138,7 +2144,7 @@ continue; if(obi->flag & R_TRANSFORMED) - mul_m4_m4m4(obwinmat, obi->mat, winmat); + mult_m4_m4m4(obwinmat, winmat, obi->mat); else copy_m4_m4(obwinmat, winmat); @@ -2318,7 +2324,7 @@ continue; if(obi->flag & R_TRANSFORMED) - mul_m4_m4m4(obwinmat, obi->mat, winmat); + mult_m4_m4m4(obwinmat, winmat, obi->mat); else copy_m4_m4(obwinmat, winmat); @@ -2557,7 +2563,7 @@ continue; if(obi->flag & R_TRANSFORMED) - mul_m4_m4m4(obwinmat, obi->mat, winmat); + mult_m4_m4m4(obwinmat, winmat, obi->mat); else copy_m4_m4(obwinmat, winmat); @@ -3300,7 +3306,7 @@ continue; if(obi->flag & R_TRANSFORMED) - mul_m4_m4m4(obwinmat, obi->mat, winmat); + mult_m4_m4m4(obwinmat, winmat, obi->mat); else copy_m4_m4(obwinmat, winmat); diff -Nru blender-2.61/source/blender/windowmanager/intern/wm_dragdrop.c blender-2.62/source/blender/windowmanager/intern/wm_dragdrop.c --- blender-2.61/source/blender/windowmanager/intern/wm_dragdrop.c 2011-12-13 19:50:34.000000000 +0000 +++ blender-2.62/source/blender/windowmanager/intern/wm_dragdrop.c 2012-02-15 19:35:22.000000000 +0000 @@ -248,7 +248,7 @@ /* ************** draw ***************** */ -static void wm_drop_operator_draw(char *name, int x, int y) +static void wm_drop_operator_draw(const char *name, int x, int y) { int width= UI_GetStringWidth(name); diff -Nru blender-2.61/source/blender/windowmanager/intern/wm_draw.c blender-2.62/source/blender/windowmanager/intern/wm_draw.c --- blender-2.61/source/blender/windowmanager/intern/wm_draw.c 2011-12-13 19:50:34.000000000 +0000 +++ blender-2.62/source/blender/windowmanager/intern/wm_draw.c 2012-02-15 19:35:22.000000000 +0000 @@ -43,6 +43,7 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" +#include "BLI_math_base.h" #include "BKE_context.h" #include "BKE_global.h" @@ -355,36 +356,12 @@ GLenum target; } wmDrawTriple; -static int is_pow2(int n) -{ - return ((n)&(n-1))==0; -} - -static int smaller_pow2(int n) -{ - while (!is_pow2(n)) - n= n&(n-1); - - return n; -} - -static int larger_pow2(int n) -{ - if (is_pow2(n)) - return n; - - while(!is_pow2(n)) - n= n&(n-1); - - return n*2; -} - static void split_width(int x, int n, int *splitx, int *nx) { int a, newnx, waste; /* if already power of two just use it */ - if(is_pow2(x)) { + if(is_power_of_2_i(x)) { splitx[0]= x; (*nx)++; return; @@ -392,12 +369,12 @@ if(n == 1) { /* last part, we have to go larger */ - splitx[0]= larger_pow2(x); + splitx[0]= power_of_2_max_i(x); (*nx)++; } else { /* two or more parts to go, use smaller part */ - splitx[0]= smaller_pow2(x); + splitx[0]= power_of_2_min_i(x); newnx= ++(*nx); split_width(x-splitx[0], n-1, splitx+1, &newnx); @@ -406,8 +383,8 @@ /* if we waste more space or use the same amount, * revert deeper splits and just use larger */ - if(waste >= larger_pow2(x)) { - splitx[0]= larger_pow2(x); + if(waste >= power_of_2_max_i(x)) { + splitx[0]= power_of_2_max_i(x); memset(splitx+1, 0, sizeof(int)*(n-1)); } else diff -Nru blender-2.61/source/blender/windowmanager/intern/wm_event_system.c blender-2.62/source/blender/windowmanager/intern/wm_event_system.c --- blender-2.61/source/blender/windowmanager/intern/wm_event_system.c 2011-12-13 19:50:34.000000000 +0000 +++ blender-2.62/source/blender/windowmanager/intern/wm_event_system.c 2012-02-15 19:35:22.000000000 +0000 @@ -186,7 +186,7 @@ wmWindowManager *wm= CTX_wm_manager(C); wmNotifier *note, *next; wmWindow *win; - unsigned int win_combine_v3d_datamask= 0; + uint64_t win_combine_v3d_datamask= 0; if(wm==NULL) return; @@ -225,20 +225,8 @@ if(note->window==win || (note->window == NULL && (note->reference == NULL || note->reference == CTX_data_scene(C)))) { if(note->category==NC_SCENE) { - if(note->data==ND_SCENEBROWSE) { - ED_screen_set_scene(C, note->reference); // XXX hrms, think this over! - if(G.f & G_DEBUG) - printf("scene set %p\n", note->reference); - } - else if(note->data==ND_FRAME) + if(note->data==ND_FRAME) do_anim= 1; - - if(note->action == NA_REMOVED) { - ED_screen_delete_scene(C, note->reference); // XXX hrms, think this over! - if(G.f & G_DEBUG) - printf("scene delete %p\n", note->reference); - } - } } if(ELEM5(note->category, NC_SCENE, NC_OBJECT, NC_GEOM, NC_SCENE, NC_WM)) { @@ -294,7 +282,7 @@ /* combine datamasks so 1 win doesn't disable UV's in another [#26448] */ for(win= wm->windows.first; win; win= win->next) { - win_combine_v3d_datamask |= ED_viewedit_datamask(win->screen); + win_combine_v3d_datamask |= ED_view3d_screen_datamask(win->screen); } /* cached: editor refresh callbacks now, they get context */ @@ -469,9 +457,10 @@ #endif /* NDEBUG */ -static void wm_operator_reports(bContext *C, wmOperator *op, int retval, int popup) +/* (caller_owns_reports == TRUE) when called from python */ +static void wm_operator_reports(bContext *C, wmOperator *op, int retval, int caller_owns_reports) { - if(popup) { + if (caller_owns_reports == FALSE) { /* popup */ if(op->reports->list.first) { /* FIXME, temp setting window, see other call to uiPupMenuReports for why */ wmWindow *win_prev= CTX_wm_window(C); @@ -490,10 +479,15 @@ } if(retval & OPERATOR_FINISHED) { - if(G.f & G_DEBUG) - wm_operator_print(C, op); /* todo - this print may double up, might want to check more flags then the FINISHED */ - - BKE_reports_print(op->reports, RPT_DEBUG); /* print out reports to console. */ + if(G.f & G_DEBUG) { + /* todo - this print may double up, might want to check more flags then the FINISHED */ + wm_operator_print(C, op); + } + + if (caller_owns_reports == FALSE) { + BKE_reports_print(op->reports, RPT_DEBUG); /* print out reports to console. */ + } + if (op->type->flag & OPTYPE_REGISTER) { if(G.background == 0) { /* ends up printing these in the terminal, gets annoying */ /* Report the python string representation of the operator */ @@ -504,7 +498,7 @@ } } - /* if the caller owns them them handle this */ + /* if the caller owns them, handle this */ if (op->reports->list.first && (op->reports->flag & RPT_OP_HOLD) == 0) { wmWindowManager *wm = CTX_wm_manager(C); @@ -586,7 +580,7 @@ } if (retval & (OPERATOR_FINISHED|OPERATOR_CANCELLED) && repeat == 0) - wm_operator_reports(C, op, retval, 0); + wm_operator_reports(C, op, retval, FALSE); if(retval & OPERATOR_FINISHED) wm_operator_finished(C, op, repeat); @@ -741,6 +735,47 @@ } } +static int wm_operator_init_from_last(wmWindowManager *wm, wmOperator *op) +{ + int change= FALSE; + wmOperator *lastop; + + for(lastop= wm->operators.last; lastop; lastop= lastop->prev) { + /* equality check is a bit paranoid but just incase */ + if((op != lastop) && (op->type == (lastop->type))) { + break; + } + } + + if (lastop && op != lastop) { + PropertyRNA *iterprop; + iterprop= RNA_struct_iterator_property(op->type->srna); + + RNA_PROP_BEGIN(op->ptr, itemptr, iterprop) { + PropertyRNA *prop= itemptr.data; + if((RNA_property_flag(prop) & PROP_SKIP_SAVE) == 0) { + if (!RNA_property_is_set(op->ptr, prop)) { /* don't override a setting already set */ + const char *identifier= RNA_property_identifier(prop); + IDProperty *idp_src= IDP_GetPropertyFromGroup(lastop->properties, identifier); + if(idp_src) { + IDProperty *idp_dst = IDP_CopyProperty(idp_src); + + /* note - in the future this may need to be done recursively, + * but for now RNA doesn't access nested operators */ + idp_dst->flag |= IDP_FLAG_GHOST; + + IDP_ReplaceInGroup(op->properties, idp_dst); + change= TRUE; + } + } + } + } + RNA_PROP_END; + } + + return change; +} + static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, PointerRNA *properties, ReportList *reports, short poll_only) { wmWindowManager *wm= CTX_wm_manager(C); @@ -753,6 +788,11 @@ if(WM_operator_poll(C, ot)) { wmOperator *op= wm_operator_create(wm, ot, properties, reports); /* if reports==NULL, theyll be initialized */ + /* initialize setting from previous run */ + if(wm->op_undo_depth == 0 && (ot->flag & OPTYPE_REGISTER)) { /* not called by py script */ + wm_operator_init_from_last(wm, op); + } + if((G.f & G_DEBUG) && event && event->type!=MOUSEMOVE) printf("handle evt %d win %d op %s\n", event?event->type:0, CTX_wm_screen(C)->subwinactive, ot->idname); @@ -783,10 +823,11 @@ /* Note, if the report is given as an argument then assume the caller will deal with displaying them * currently python only uses this */ - if (!(retval & OPERATOR_HANDLED) && retval & (OPERATOR_FINISHED|OPERATOR_CANCELLED)) + if (!(retval & OPERATOR_HANDLED) && (retval & (OPERATOR_FINISHED|OPERATOR_CANCELLED))) { /* only show the report if the report list was not given in the function */ - wm_operator_reports(C, op, retval, (reports==NULL)); - + wm_operator_reports(C, op, retval, (reports != NULL)); + } + if(retval & OPERATOR_HANDLED) ; /* do nothing, wm_operator_exec() has been called somewhere */ else if(retval & OPERATOR_FINISHED) { @@ -795,7 +836,7 @@ else if(retval & OPERATOR_RUNNING_MODAL) { /* grab cursor during blocking modal ops (X11) * Also check for macro - * */ + */ if(ot->flag & OPTYPE_BLOCKING || (op->opm && op->opm->type->flag & OPTYPE_BLOCKING)) { int bounds[4] = {-1,-1,-1,-1}; int wrap; @@ -1301,7 +1342,7 @@ } if(retval & (OPERATOR_CANCELLED|OPERATOR_FINISHED)) - wm_operator_reports(C, op, retval, 0); + wm_operator_reports(C, op, retval, FALSE); if(retval & OPERATOR_FINISHED) { wm_operator_finished(C, op, 0); @@ -2650,9 +2691,11 @@ } event.utf8_buf[0]= '\0'; } - else if (event.ascii<32 && event.ascii > 0) { - event.ascii= '\0'; - /* TODO. should this also zero utf8?, dont for now, campbell */ + else { + if (event.ascii<32 && event.ascii > 0) + event.ascii= '\0'; + if (event.utf8_buf[0]<32 && event.utf8_buf[0] > 0) + event.utf8_buf[0]= '\0'; } if (event.utf8_buf[0]) { diff -Nru blender-2.61/source/blender/windowmanager/intern/wm_files.c blender-2.62/source/blender/windowmanager/intern/wm_files.c --- blender-2.61/source/blender/windowmanager/intern/wm_files.c 2011-12-13 19:50:34.000000000 +0000 +++ blender-2.62/source/blender/windowmanager/intern/wm_files.c 2012-02-15 19:35:22.000000000 +0000 @@ -277,7 +277,7 @@ static void wm_init_userdef(bContext *C) { UI_init_userdef(); - MEM_CacheLimiter_set_maximum(U.memcachelimit * 1024 * 1024); + MEM_CacheLimiter_set_maximum(((size_t)U.memcachelimit) * 1024 * 1024); sound_init(CTX_data_main(C)); /* needed so loading a file from the command line respects user-pref [#26156] */ diff -Nru blender-2.61/source/blender/windowmanager/intern/wm_init_exit.c blender-2.62/source/blender/windowmanager/intern/wm_init_exit.c --- blender-2.61/source/blender/windowmanager/intern/wm_init_exit.c 2011-12-13 19:50:34.000000000 +0000 +++ blender-2.62/source/blender/windowmanager/intern/wm_init_exit.c 2012-02-15 19:35:22.000000000 +0000 @@ -60,6 +60,7 @@ #include "BKE_packedFile.h" #include "BKE_sequencer.h" /* free seq clipboard */ #include "BKE_material.h" /* clear_matcopybuf */ +#include "BKE_tracking.h" /* free tracking clipboard */ #include "BLI_listbase.h" #include "BLI_string.h" @@ -263,7 +264,7 @@ } /* Fullscreen */ - if(scene->gm.fullscreen) { + if((scene->gm.playerflag & GAME_PLAYER_FULLSCREEN)) { WM_operator_name_call(C, "WM_OT_window_fullscreen_toggle", WM_OP_EXEC_DEFAULT, NULL); wm_get_screensize(&ar->winrct.xmax, &ar->winrct.ymax); ar->winx = ar->winrct.xmax + 1; @@ -375,6 +376,7 @@ wm_free_reports(C); /* before free_blender! - since the ListBases get freed there */ seq_free_clipboard(); /* sequencer.c */ + BKE_tracking_free_clipboard(); free_blender(); /* blender.c, does entire library and spacetypes */ // free_matcopybuf(); diff -Nru blender-2.61/source/blender/windowmanager/intern/wm_jobs.c blender-2.62/source/blender/windowmanager/intern/wm_jobs.c --- blender-2.61/source/blender/windowmanager/intern/wm_jobs.c 2011-12-13 19:50:34.000000000 +0000 +++ blender-2.62/source/blender/windowmanager/intern/wm_jobs.c 2012-02-15 19:35:22.000000000 +0000 @@ -491,6 +491,13 @@ WM_jobs_start(wm, steve); } } + else if(steve->threads.first && !steve->ready) { + if(steve->flag & WM_JOB_PROGRESS) { + /* accumulate global progress for running jobs */ + jobs_progress++; + total_progress += steve->progress; + } + } } /* on file load 'winactive' can be NULL, possibly it should not happen but for now do a NULL check - campbell */ diff -Nru blender-2.61/source/blender/windowmanager/intern/wm_keymap.c blender-2.62/source/blender/windowmanager/intern/wm_keymap.c --- blender-2.61/source/blender/windowmanager/intern/wm_keymap.c 2011-12-13 19:50:34.000000000 +0000 +++ blender-2.62/source/blender/windowmanager/intern/wm_keymap.c 2012-02-15 19:35:22.000000000 +0000 @@ -981,6 +981,8 @@ wmKeyMapDiffItem *kmdi; int compat_update = 0; + if(G.background) + return; if(!WM_KEYMAP_UPDATE) return; @@ -1211,7 +1213,14 @@ km = WM_keymap_find_all(C, "Pose", 0, 0); } else if (strstr(opname, "SCULPT_OT")) { - km = WM_keymap_find_all(C, "Sculpt", 0, 0); + switch(CTX_data_mode_enum(C)) { + case OB_MODE_SCULPT: + km = WM_keymap_find_all(C, "Sculpt", 0, 0); + break; + case OB_MODE_EDIT: + km = WM_keymap_find_all(C, "UV Sculpt", 0, 0); + break; + } } else if (strstr(opname, "MBALL_OT")) { km = WM_keymap_find_all(C, "Metaball", 0, 0); diff -Nru blender-2.61/source/blender/windowmanager/intern/wm_operators.c blender-2.62/source/blender/windowmanager/intern/wm_operators.c --- blender-2.61/source/blender/windowmanager/intern/wm_operators.c 2011-12-13 19:50:34.000000000 +0000 +++ blender-2.62/source/blender/windowmanager/intern/wm_operators.c 2012-02-15 19:35:22.000000000 +0000 @@ -46,6 +46,7 @@ #include "DNA_scene_types.h" #include "DNA_userdef_types.h" #include "DNA_windowmanager_types.h" +#include "DNA_mesh_types.h" /* only for USE_BMESH_SAVE_AS_COMPAT */ #include "BLF_translation.h" @@ -637,6 +638,25 @@ RNA_STRUCT_END; } +/* remove all props without PROP_SKIP_SAVE */ +void WM_operator_properties_reset(wmOperator *op) +{ + if (op->ptr->data) { + PropertyRNA *iterprop; + iterprop= RNA_struct_iterator_property(op->type->srna); + + RNA_PROP_BEGIN(op->ptr, itemptr, iterprop) { + PropertyRNA *prop= itemptr.data; + + if((RNA_property_flag(prop) & PROP_SKIP_SAVE) == 0) { + const char *identifier = RNA_property_identifier(prop); + RNA_struct_idprops_unset(op->ptr, identifier); + } + } + RNA_PROP_END; + } +} + void WM_operator_properties_free(PointerRNA *ptr) { IDProperty *properties= ptr->data; @@ -664,7 +684,7 @@ printf("%s: %s \"%s\" is not an enum property\n", __func__, op->type->idname, RNA_property_identifier(prop)); } - else if (RNA_property_is_set(op->ptr, RNA_property_identifier(prop))) { + else if (RNA_property_is_set(op->ptr, prop)) { const int retval= op->type->exec(C, op); OPERATOR_RETVAL_CHECK(retval); return retval; @@ -746,7 +766,7 @@ uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_RET_1|UI_BLOCK_MOVEMOUSE_QUIT); //uiDefBut(block, LABEL, 0, op->type->name, 10, 10, 180, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); // ok, this isnt so easy... - but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 10, 9*UI_UNIT_X, UI_UNIT_Y, 0, 0, ""); + but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 10, 9*UI_UNIT_X, UI_UNIT_Y, 0, 0, ""); uiButSetSearchFunc(but, operator_enum_search_cb, op->type, operator_enum_call_cb, NULL); /* fake button, it holds space for search items */ @@ -786,7 +806,7 @@ pup= uiPupMenuBegin(C, IFACE_("OK?"), ICON_QUESTION); layout= uiPupMenuLayout(pup); - uiItemFullO(layout, op->type->idname, message, ICON_NONE, properties, WM_OP_EXEC_REGION_WIN, 0); + uiItemFullO_ptr(layout, op->type, message, ICON_NONE, properties, WM_OP_EXEC_REGION_WIN, 0); uiPupMenuEnd(C, pup); return OPERATOR_CANCELLED; @@ -801,7 +821,7 @@ /* op->invoke, opens fileselect if path property not set, otherwise executes */ int WM_operator_filesel(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { - if (RNA_property_is_set(op->ptr, "filepath")) { + if (RNA_struct_property_is_set(op->ptr, "filepath")) { return WM_operator_call_notest(C, op); /* call exec direct */ } else { @@ -811,10 +831,17 @@ } /* default properties for fileselect */ -void WM_operator_properties_filesel(wmOperatorType *ot, int filter, short type, short action, short flag) +void WM_operator_properties_filesel(wmOperatorType *ot, int filter, short type, short action, short flag, short display) { PropertyRNA *prop; + static EnumPropertyItem file_display_items[] = { + {FILE_DEFAULTDISPLAY, "FILE_DEFAULTDISPLAY", 0, "Default", "Automatically determine display type for files"}, + {FILE_SHORTDISPLAY, "FILE_SHORTDISPLAY", ICON_SHORTDISPLAY, "Short List", "Display files as short list"}, + {FILE_LONGDISPLAY, "FILE_LONGDISPLAY", ICON_LONGDISPLAY, "Long List", "Display files as a detailed list"}, + {FILE_IMGDISPLAY, "FILE_IMGDISPLAY", ICON_IMGDISPLAY, "Thumbnails", "Display files as thumbnails"}, + {0, NULL, 0, NULL, NULL}}; + if(flag & WM_FILESEL_FILEPATH) RNA_def_string_file_path(ot->srna, "filepath", "", FILE_MAX, "File Path", "Path to file"); @@ -861,6 +888,9 @@ if(flag & WM_FILESEL_RELPATH) RNA_def_boolean(ot->srna, "relative_path", TRUE, "Relative Path", "Select the file relative to the blend file"); + + prop= RNA_def_enum(ot->srna, "display_type", file_display_items, display, "Display Type", ""); + RNA_def_property_flag(prop, PROP_HIDDEN); } void WM_operator_properties_select_all(wmOperatorType *ot) @@ -938,7 +968,7 @@ int width= 300; - block= uiBeginBlock(C, ar, "redo_popup", UI_EMBOSS); + block= uiBeginBlock(C, ar, __func__, UI_EMBOSS); uiBlockClearFlag(block, UI_BLOCK_LOOP); uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN|UI_BLOCK_RET_1|UI_BLOCK_MOVEMOUSE_QUIT); @@ -1014,7 +1044,7 @@ uiLayout *layout; uiStyle *style= UI_GetStyle(); - block = uiBeginBlock(C, ar, "operator dialog", UI_EMBOSS); + block = uiBeginBlock(C, ar, __func__, UI_EMBOSS); uiBlockClearFlag(block, UI_BLOCK_LOOP); uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN|UI_BLOCK_RET_1|UI_BLOCK_MOVEMOUSE_QUIT); @@ -1055,7 +1085,7 @@ uiLayout *layout; uiStyle *style= UI_GetStyle(); - block= uiBeginBlock(C, ar, "opui_popup", UI_EMBOSS); + block= uiBeginBlock(C, ar, __func__, UI_EMBOSS); uiBlockClearFlag(block, UI_BLOCK_LOOP); uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN|UI_BLOCK_RET_1|UI_BLOCK_MOVEMOUSE_QUIT); @@ -1247,21 +1277,17 @@ #ifdef WITH_BUILDINFO int ver_width, rev_width; - char *version_str = NULL; - char *revision_str = NULL; char version_buf[128]; char revision_buf[128]; extern char build_rev[]; - version_str = &version_buf[0]; - revision_str = &revision_buf[0]; - - sprintf(version_str, "%d.%02d.%d", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION); - sprintf(revision_str, "r%s", build_rev); + BLI_snprintf(version_buf, sizeof(version_buf), + "%d.%02d.%d", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION); + BLI_snprintf(revision_buf, sizeof(revision_buf), "r%s", build_rev); BLF_size(style->widgetlabel.uifont_id, style->widgetlabel.points, U.dpi); - ver_width = (int)BLF_width(style->widgetlabel.uifont_id, version_str) + 5; - rev_width = (int)BLF_width(style->widgetlabel.uifont_id, revision_str) + 5; + ver_width = (int)BLF_width(style->widgetlabel.uifont_id, version_buf) + 5; + rev_width = (int)BLF_width(style->widgetlabel.uifont_id, revision_buf) + 5; #endif //WITH_BUILDINFO block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS); @@ -1272,8 +1298,8 @@ uiBlockSetFunc(block, wm_block_splash_refreshmenu, block, NULL); #ifdef WITH_BUILDINFO - uiDefBut(block, LABEL, 0, version_str, 494-ver_width, 282-24, ver_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); - uiDefBut(block, LABEL, 0, revision_str, 494-rev_width, 282-36, rev_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); + uiDefBut(block, LABEL, 0, version_buf, 494-ver_width, 282-24, ver_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); + uiDefBut(block, LABEL, 0, revision_buf, 494-rev_width, 282-36, rev_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); #endif //WITH_BUILDINFO layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 10, 2, 480, 110, style); @@ -1298,7 +1324,7 @@ uiItemL(col, "Links", ICON_NONE); uiItemStringO(col, IFACE_("Donations"), ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/blenderorg/blender-foundation/donation-payment"); uiItemStringO(col, IFACE_("Credits"), ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/development/credits"); - uiItemStringO(col, IFACE_("Release Log"), ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/development/release-logs/blender-261"); + uiItemStringO(col, IFACE_("Release Log"), ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/development/release-logs/blender-262"); uiItemStringO(col, IFACE_("Manual"), ICON_URL, "WM_OT_url_open", "url", "http://wiki.blender.org/index.php/Doc:2.5/Manual"); uiItemStringO(col, IFACE_("Blender Website"), ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org"); uiItemStringO(col, IFACE_("User Community"), ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/community/user-community"); @@ -1376,12 +1402,15 @@ int len= strlen(ot->name); /* display name for menu, can hold hotkey */ - BLI_strncpy(name, ot->name, 256); + BLI_strncpy(name, ot->name, sizeof(name)); /* check for hotkey */ - if(len < 256-6) { - if(WM_key_event_operator_string(C, ot->idname, WM_OP_EXEC_DEFAULT, NULL, TRUE, &name[len+1], 256-len-1)) + if (len < sizeof(name) - 6) { + if (WM_key_event_operator_string(C, ot->idname, WM_OP_EXEC_DEFAULT, NULL, TRUE, + &name[len+1], sizeof(name)-len-1)) + { name[len]= '|'; + } } if(0==uiSearchItemAdd(items, name, ot, 0)) @@ -1403,7 +1432,7 @@ block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS); uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_RET_1|UI_BLOCK_MOVEMOUSE_QUIT); - but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 10, 9*UI_UNIT_X, UI_UNIT_Y, 0, 0, ""); + but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 10, 9*UI_UNIT_X, UI_UNIT_Y, 0, 0, ""); uiButSetSearchFunc(but, operator_search_cb, NULL, operator_call_cb, NULL); /* fake button, it holds space for search items */ @@ -1548,13 +1577,13 @@ static void open_set_load_ui(wmOperator *op) { - if(!RNA_property_is_set(op->ptr, "load_ui")) + if(!RNA_struct_property_is_set(op->ptr, "load_ui")) RNA_boolean_set(op->ptr, "load_ui", !(U.flag & USER_FILENOUI)); } static void open_set_use_scripts(wmOperator *op) { - if(!RNA_property_is_set(op->ptr, "use_scripts")) { + if(!RNA_struct_property_is_set(op->ptr, "use_scripts")) { /* use G_SCRIPT_AUTOEXEC rather than the userpref because this means if * the flag has been disabled from the command line, then opening * from the menu wont enable this setting. */ @@ -1626,7 +1655,7 @@ ot->exec= wm_open_mainfile_exec; /* ommit window poll so this can work in background mode */ - WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER, FILE_OPENFILE, WM_FILESEL_FILEPATH); + WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER, FILE_OPENFILE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); RNA_def_boolean(ot->srna, "load_ui", 1, "Load UI", "Load user interface setup in the .blend file"); RNA_def_boolean(ot->srna, "use_scripts", 1, "Trusted Source", "Allow blend file execute scripts automatically, default available from system preferences"); @@ -1652,7 +1681,7 @@ static int wm_link_append_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { - if(RNA_property_is_set(op->ptr, "filepath")) { + if(RNA_struct_property_is_set(op->ptr, "filepath")) { return WM_operator_call_notest(C, op); } else { @@ -1816,7 +1845,7 @@ ot->flag |= OPTYPE_UNDO; - WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_LOADLIB, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_DIRECTORY|WM_FILESEL_FILENAME| WM_FILESEL_RELPATH|WM_FILESEL_FILES); + WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_LOADLIB, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_DIRECTORY|WM_FILESEL_FILENAME| WM_FILESEL_RELPATH|WM_FILESEL_FILES, FILE_DEFAULTDISPLAY); RNA_def_boolean(ot->srna, "link", 1, "Link", "Link the objects or datablocks rather than appending"); RNA_def_boolean(ot->srna, "autoselect", 1, "Select", "Select the linked objects"); @@ -1897,7 +1926,7 @@ ot->invoke= wm_recover_auto_save_invoke; ot->poll= WM_operator_winactive; - WM_operator_properties_filesel(ot, BLENDERFILE, FILE_BLENDER, FILE_OPENFILE, WM_FILESEL_FILEPATH); + WM_operator_properties_filesel(ot, BLENDERFILE, FILE_BLENDER, FILE_OPENFILE, WM_FILESEL_FILEPATH, FILE_LONGDISPLAY); } /* *************** save file as **************** */ @@ -1916,7 +1945,7 @@ static void save_set_compress(wmOperator *op) { - if(!RNA_property_is_set(op->ptr, "compress")) { + if(!RNA_struct_property_is_set(op->ptr, "compress")) { if(G.save_over) /* keep flag for existing file */ RNA_boolean_set(op->ptr, "compress", G.fileflags & G_FILE_COMPRESS); else /* use userdef for new file */ @@ -1955,14 +1984,14 @@ save_set_compress(op); - if(RNA_property_is_set(op->ptr, "filepath")) + if(RNA_struct_property_is_set(op->ptr, "filepath")) RNA_string_get(op->ptr, "filepath", path); else { BLI_strncpy(path, G.main->name, FILE_MAX); untitled(path); } - if(RNA_property_is_set(op->ptr, "copy")) + if(RNA_struct_property_is_set(op->ptr, "copy")) copy = RNA_boolean_get(op->ptr, "copy"); fileflags= G.fileflags; @@ -1972,6 +2001,10 @@ else fileflags &= ~G_FILE_COMPRESS; if(RNA_boolean_get(op->ptr, "relative_remap")) fileflags |= G_FILE_RELATIVE_REMAP; else fileflags &= ~G_FILE_RELATIVE_REMAP; +#ifdef USE_BMESH_SAVE_AS_COMPAT + if(RNA_boolean_get(op->ptr, "use_mesh_compat")) fileflags |= G_FILE_MESH_COMPAT; + else fileflags &= ~G_FILE_MESH_COMPAT; +#endif if ( WM_write_file(C, path, fileflags, op->reports, copy) != 0) return OPERATOR_CANCELLED; @@ -2007,10 +2040,13 @@ ot->check= blend_save_check; /* ommit window poll so this can work in background mode */ - WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER, FILE_SAVE, WM_FILESEL_FILEPATH); + WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER, FILE_SAVE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); RNA_def_boolean(ot->srna, "compress", 0, "Compress", "Write compressed .blend file"); RNA_def_boolean(ot->srna, "relative_remap", 1, "Remap Relative", "Remap relative paths when saving in a different directory"); RNA_def_boolean(ot->srna, "copy", 0, "Save Copy", "Save a copy of the actual working state but does not make saved file active"); +#ifdef USE_BMESH_SAVE_AS_COMPAT + RNA_def_boolean(ot->srna, "use_mesh_compat", 0, "Legacy Mesh Format", "Save using legacy mesh format (no ngons)"); +#endif } /* *************** save file directly ******** */ @@ -2071,7 +2107,7 @@ ot->check= blend_save_check; /* ommit window poll so this can work in background mode */ - WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER, FILE_SAVE, WM_FILESEL_FILEPATH); + WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER, FILE_SAVE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); RNA_def_boolean(ot->srna, "compress", 0, "Compress", "Write compressed .blend file"); RNA_def_boolean(ot->srna, "relative_remap", 0, "Remap Relative", "Remap relative paths when saving in a different directory"); } @@ -2083,7 +2119,7 @@ static int wm_collada_export_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { - if(!RNA_property_is_set(op->ptr, "filepath")) { + if(!RNA_struct_property_is_set(op->ptr, "filepath")) { char filepath[FILE_MAX]; BLI_strncpy(filepath, G.main->name, sizeof(filepath)); BLI_replace_extension(filepath, sizeof(filepath), ".dae"); @@ -2099,16 +2135,17 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) { char filename[FILE_MAX]; - int selected; + int selected, second_life; - if(!RNA_property_is_set(op->ptr, "filepath")) { + if(!RNA_struct_property_is_set(op->ptr, "filepath")) { BKE_report(op->reports, RPT_ERROR, "No filename given"); return OPERATOR_CANCELLED; } RNA_string_get(op->ptr, "filepath", filename); selected = RNA_boolean_get(op->ptr, "selected"); - if(collada_export(CTX_data_scene(C), filename, selected)) { + second_life = RNA_boolean_get(op->ptr, "second_life"); + if(collada_export(CTX_data_scene(C), filename, selected, second_life)) { return OPERATOR_FINISHED; } else { @@ -2125,9 +2162,11 @@ ot->exec= wm_collada_export_exec; ot->poll= WM_operator_winactive; - WM_operator_properties_filesel(ot, FOLDERFILE|COLLADAFILE, FILE_BLENDER, FILE_SAVE, WM_FILESEL_FILEPATH); + WM_operator_properties_filesel(ot, FOLDERFILE|COLLADAFILE, FILE_BLENDER, FILE_SAVE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); RNA_def_boolean(ot->srna, "selected", 0, "Export only selected", "Export only selected elements"); + RNA_def_boolean(ot->srna, "second_life", 0, "Export for Second Life", + "Compatibility mode for Second Life"); } /* function used for WM_OT_save_mainfile too */ @@ -2135,7 +2174,7 @@ { char filename[FILE_MAX]; - if(!RNA_property_is_set(op->ptr, "filepath")) { + if(!RNA_struct_property_is_set(op->ptr, "filepath")) { BKE_report(op->reports, RPT_ERROR, "No filename given"); return OPERATOR_CANCELLED; } @@ -2157,7 +2196,7 @@ ot->exec= wm_collada_import_exec; ot->poll= WM_operator_winactive; - WM_operator_properties_filesel(ot, FOLDERFILE|COLLADAFILE, FILE_BLENDER, FILE_OPENFILE, WM_FILESEL_FILEPATH); + WM_operator_properties_filesel(ot, FOLDERFILE|COLLADAFILE, FILE_BLENDER, FILE_OPENFILE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); } #endif @@ -3052,23 +3091,35 @@ glDisable(GL_LINE_SMOOTH); } +typedef enum { + RC_PROP_ALLOW_MISSING = 1, + RC_PROP_REQUIRE_FLOAT = 2, + RC_PROP_REQUIRE_BOOL = 4, +} RCPropFlags; + /* attempt to retrieve the rna pointer/property from an rna path; returns 0 for failure, 1 for success, and also 1 if property is not set */ static int radial_control_get_path(PointerRNA *ctx_ptr, wmOperator *op, const char *name, PointerRNA *r_ptr, - PropertyRNA **r_prop, int req_float, - int req_length, int allow_missing) + PropertyRNA **r_prop, int req_length, RCPropFlags flags) { PropertyRNA *unused_prop; int len; char *str; + /* check flags */ + if((flags & RC_PROP_REQUIRE_BOOL) && (flags & RC_PROP_REQUIRE_FLOAT)) { + BKE_reportf(op->reports, RPT_ERROR, "Property can't be both boolean and float"); + return 0; + } + /* get an rna string path from the operator's properties */ if(!(str = RNA_string_get_alloc(op->ptr, name, NULL, 0))) return 1; if(str[0] == '\0') { + if(r_prop) *r_prop = NULL; MEM_freeN(str); return 1; } @@ -3079,7 +3130,7 @@ /* get rna from path */ if(!RNA_path_resolve(ctx_ptr, str, r_ptr, r_prop)) { MEM_freeN(str); - if(allow_missing) + if(flags & RC_PROP_ALLOW_MISSING) return 1; else { BKE_reportf(op->reports, RPT_ERROR, "Couldn't resolve path %s", name); @@ -3087,9 +3138,12 @@ } } - /* if property is expected to be a float, check its type */ - if(req_float) { - if(!(*r_prop) || (RNA_property_type(*r_prop) != PROP_FLOAT)) { + /* check property type */ + if(flags & (RC_PROP_REQUIRE_BOOL | RC_PROP_REQUIRE_FLOAT)) { + PropertyType prop_type = RNA_property_type(*r_prop); + + if(((flags & RC_PROP_REQUIRE_BOOL) && (prop_type != PROP_BOOLEAN)) || + ((flags & RC_PROP_REQUIRE_FLOAT) && prop_type != PROP_FLOAT)) { MEM_freeN(str); BKE_reportf(op->reports, RPT_ERROR, "Property from path %s is not a float", name); @@ -3115,31 +3169,50 @@ static int radial_control_get_properties(bContext *C, wmOperator *op) { RadialControl *rc = op->customdata; - PointerRNA ctx_ptr; + PointerRNA ctx_ptr, use_secondary_ptr; + PropertyRNA *use_secondary_prop; + const char *data_path; RNA_pointer_create(NULL, &RNA_Context, C, &ctx_ptr); - if(!radial_control_get_path(&ctx_ptr, op, "data_path", &rc->ptr, &rc->prop, 0, 0, 0)) + /* check if we use primary or secondary path */ + if(!radial_control_get_path(&ctx_ptr, op, "use_secondary", + &use_secondary_ptr, &use_secondary_prop, + 0, (RC_PROP_ALLOW_MISSING| + RC_PROP_REQUIRE_BOOL))) { + return 0; + } + else { + if(use_secondary_prop && + RNA_property_boolean_get(&use_secondary_ptr, use_secondary_prop)) + data_path = "data_path_secondary"; + else + data_path = "data_path_primary"; + } + + if(!radial_control_get_path(&ctx_ptr, op, data_path, &rc->ptr, &rc->prop, 0, 0)) return 0; /* data path is required */ if(!rc->prop) return 0; - if(!radial_control_get_path(&ctx_ptr, op, "rotation_path", &rc->rot_ptr, &rc->rot_prop, 1, 0, 0)) + if(!radial_control_get_path(&ctx_ptr, op, "rotation_path", &rc->rot_ptr, &rc->rot_prop, 0, RC_PROP_REQUIRE_FLOAT)) return 0; - if(!radial_control_get_path(&ctx_ptr, op, "color_path", &rc->col_ptr, &rc->col_prop, 1, 3, 0)) + if(!radial_control_get_path(&ctx_ptr, op, "color_path", &rc->col_ptr, &rc->col_prop, 3, RC_PROP_REQUIRE_FLOAT)) return 0; - if(!radial_control_get_path(&ctx_ptr, op, "fill_color_path", &rc->fill_col_ptr, &rc->fill_col_prop, 1, 3, 0)) + if(!radial_control_get_path(&ctx_ptr, op, "fill_color_path", &rc->fill_col_ptr, &rc->fill_col_prop, 3, RC_PROP_REQUIRE_FLOAT)) return 0; /* slightly ugly; allow this property to not resolve correctly. needed because 3d texture paint shares the same keymap as 2d image paint */ - if(!radial_control_get_path(&ctx_ptr, op, "zoom_path", &rc->zoom_ptr, &rc->zoom_prop, 1, 2, 1)) + if(!radial_control_get_path(&ctx_ptr, op, "zoom_path", + &rc->zoom_ptr, &rc->zoom_prop, 2, + RC_PROP_REQUIRE_FLOAT|RC_PROP_ALLOW_MISSING)) return 0; - if(!radial_control_get_path(&ctx_ptr, op, "image_id", &rc->image_id_ptr, NULL, 0, 0, 0)) + if(!radial_control_get_path(&ctx_ptr, op, "image_id", &rc->image_id_ptr, NULL, 0, 0)) return 0; else if(rc->image_id_ptr.data) { /* extra check, pointer must be to an ID */ @@ -3332,7 +3405,9 @@ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; /* all paths relative to the context */ - RNA_def_string(ot->srna, "data_path", "", 0, "Data Path", "Path of property to be set by the radial control"); + RNA_def_string(ot->srna, "data_path_primary", "", 0, "Primary Data Path", "Primary path of property to be set by the radial control"); + RNA_def_string(ot->srna, "data_path_secondary", "", 0, "Secondary Data Path", "Secondary path of property to be set by the radial control"); + RNA_def_string(ot->srna, "use_secondary", "", 0, "Use Secondary", "Path of property to select between the primary and secondary data paths"); RNA_def_string(ot->srna, "rotation_path", "", 0, "Rotation Path", "Path of property used to rotate the texture display"); RNA_def_string(ot->srna, "color_path", "", 0, "Color Path", "Path of property used to set the color of the control"); RNA_def_string(ot->srna, "fill_color_path", "", 0, "Fill Color Path", "Path of property used to set the fill color of the control"); @@ -3740,6 +3815,7 @@ WM_modalkeymap_assign(keymap, "MARKER_OT_select_border"); WM_modalkeymap_assign(keymap, "NLA_OT_select_border"); WM_modalkeymap_assign(keymap, "NODE_OT_select_border"); + WM_modalkeymap_assign(keymap, "OUTLINER_OT_select_border"); // WM_modalkeymap_assign(keymap, "SCREEN_OT_border_select"); // template WM_modalkeymap_assign(keymap, "SEQUENCER_OT_select_border"); WM_modalkeymap_assign(keymap, "SEQUENCER_OT_view_ghost_border"); @@ -3815,7 +3891,7 @@ WM_keymap_add_item(keymap, "WM_OT_save_as_mainfile", SKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0); WM_keymap_add_item(keymap, "WM_OT_save_as_mainfile", F2KEY, KM_PRESS, 0, 0); kmi= WM_keymap_add_item(keymap, "WM_OT_save_as_mainfile", SKEY, KM_PRESS, KM_ALT|KM_CTRL, 0); - RNA_boolean_set(kmi->ptr, "copy", 1); + RNA_boolean_set(kmi->ptr, "copy", TRUE); WM_keymap_verify_item(keymap, "WM_OT_window_fullscreen_toggle", F11KEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "WM_OT_quit_blender", QKEY, KM_PRESS, KM_CTRL, 0); diff -Nru blender-2.61/source/blender/windowmanager/WM_api.h blender-2.62/source/blender/windowmanager/WM_api.h --- blender-2.61/source/blender/windowmanager/WM_api.h 2011-12-13 19:50:35.000000000 +0000 +++ blender-2.62/source/blender/windowmanager/WM_api.h 2012-02-15 19:35:24.000000000 +0000 @@ -199,10 +199,11 @@ void WM_operator_properties_alloc(struct PointerRNA **ptr, struct IDProperty **properties, const char *opstring); /* used for keymap and macro items */ void WM_operator_properties_sanitize(struct PointerRNA *ptr, const short no_context); /* make props context sensitive or not */ +void WM_operator_properties_reset(struct wmOperator *op); void WM_operator_properties_create(struct PointerRNA *ptr, const char *opstring); void WM_operator_properties_create_ptr(struct PointerRNA *ptr, struct wmOperatorType *ot); void WM_operator_properties_free(struct PointerRNA *ptr); -void WM_operator_properties_filesel(struct wmOperatorType *ot, int filter, short type, short action, short flag); +void WM_operator_properties_filesel(struct wmOperatorType *ot, int filter, short type, short action, short flag, short display); void WM_operator_properties_gesture_border(struct wmOperatorType *ot, int extend); void WM_operator_properties_gesture_straightline(struct wmOperatorType *ot, int cursor); void WM_operator_properties_select_all(struct wmOperatorType *ot); diff -Nru blender-2.61/source/blender/windowmanager/WM_types.h blender-2.62/source/blender/windowmanager/WM_types.h --- blender-2.61/source/blender/windowmanager/WM_types.h 2011-12-13 19:50:35.000000000 +0000 +++ blender-2.62/source/blender/windowmanager/WM_types.h 2012-02-15 19:35:24.000000000 +0000 @@ -526,14 +526,14 @@ int icon, type; /* type, see WM_DRAG defines above */ void *poin; - char path[240]; /* FILE_MAX */ + char path[1024]; /* FILE_MAX */ double value; struct ImBuf *imb; /* if no icon but imbuf should be drawn around cursor */ float scale; int sx, sy; - char opname[240]; /* FILE_MAX */ /* if set, draws operator name*/ + char opname[200]; /* if set, draws operator name*/ } wmDrag; /* dropboxes are like keymaps, part of the screen/area/region definition */ diff -Nru blender-2.61/source/blenderplayer/bad_level_call_stubs/stubs.c blender-2.62/source/blenderplayer/bad_level_call_stubs/stubs.c --- blender-2.61/source/blenderplayer/bad_level_call_stubs/stubs.c 2011-12-13 19:47:58.000000000 +0000 +++ blender-2.62/source/blenderplayer/bad_level_call_stubs/stubs.c 2012-02-15 19:32:36.000000000 +0000 @@ -202,6 +202,8 @@ void ED_space_image_paint_update(struct wmWindowManager *wm, struct ToolSettings *settings){} void ED_space_image_set(struct SpaceImage *sima, struct Scene *scene, struct Object *obedit, struct Image *ima){} struct ImBuf *ED_space_image_buffer(struct SpaceImage *sima){return (struct ImBuf *) NULL;} +void ED_space_image_uv_sculpt_update(struct wmWindowManager *wm, struct ToolSettings *settings){} + void ED_screen_set_scene(struct bContext *C, struct Scene *scene){} void ED_space_clip_set(struct bContext *C, struct SpaceClip *sc, struct MovieClip *clip){} @@ -295,6 +297,9 @@ void ED_mesh_vertices_add(struct Mesh *mesh, struct ReportList *reports, int count){} void ED_mesh_edges_add(struct Mesh *mesh, struct ReportList *reports, int count){} void ED_mesh_faces_add(struct Mesh *mesh, struct ReportList *reports, int count){} +void ED_mesh_vertices_remove(struct Mesh *mesh, struct ReportList *reports, int count){} +void ED_mesh_edges_remove(struct Mesh *mesh, struct ReportList *reports, int count){} +void ED_mesh_faces_remove(struct Mesh *mesh, struct ReportList *reports, int count){} void ED_mesh_material_link(struct Mesh *mesh, struct Material *ma){} int ED_mesh_color_add(struct bContext *C, struct Scene *scene, struct Object *ob, struct Mesh *me){return 0;} int ED_mesh_uv_texture_add(struct bContext *C, struct Mesh *me){return 0;} @@ -349,7 +354,7 @@ void uiItemIntO(struct uiLayout *layout, char *name, int icon, char *opname, char *propname, int value){} void uiItemFloatO(struct uiLayout *layout, char *name, int icon, char *opname, char *propname, float value){} void uiItemStringO(struct uiLayout *layout, char *name, int icon, char *opname, char *propname, char *value){} -void uiItemL(struct uiLayout *layout, char *name, int icon){} +void uiItemL(struct uiLayout *layout, const char *name, int icon){} void uiItemM(struct uiLayout *layout, struct bContext *C, char *menuname, char *name, int icon){} void uiItemS(struct uiLayout *layout){} void uiItemFullR(struct uiLayout *layout, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, int value, int flag, char *name, int icon){} @@ -464,6 +469,20 @@ void BPY_pyconstraint_exec(struct bPythonConstraint *con, struct bConstraintOb *cob, struct ListBase *targets) {} void macro_wrapper(struct wmOperatorType *ot, void *userdata) {} ; +/* intern/dualcon */ +struct DualConMesh; +struct DualConMesh *dualcon(const struct DualConMesh *input_mesh, + void *create_mesh, + int flags, + int mode, + float threshold, + float hermite_num, + float scale, + int depth) {return 0;} + +/* intern/cycles */ +struct CCLDeviceInfo; +struct CCLDeviceInfo *CCL_compute_device_list(int opencl) { return NULL; } char blender_path[] = ""; diff -Nru blender-2.61/source/blenderplayer/CMakeLists.txt blender-2.62/source/blenderplayer/CMakeLists.txt --- blender-2.61/source/blenderplayer/CMakeLists.txt 2011-12-13 19:47:58.000000000 +0000 +++ blender-2.62/source/blenderplayer/CMakeLists.txt 2012-02-15 19:32:36.000000000 +0000 @@ -180,6 +180,10 @@ list(APPEND BLENDER_SORTED_LIBS bf_intern_moto) endif() + if(WITH_CARVE) + list(APPEND BLENDER_SORTED_LIBS extern_carve) + endif() + if(WITH_CODEC_QUICKTIME) list(APPEND BLENDER_SORTED_LIBS bf_quicktime) endif() diff -Nru blender-2.61/source/creator/CMakeLists.txt blender-2.62/source/creator/CMakeLists.txt --- blender-2.61/source/creator/CMakeLists.txt 2011-12-13 19:46:18.000000000 +0000 +++ blender-2.62/source/creator/CMakeLists.txt 2012-02-15 19:30:38.000000000 +0000 @@ -165,7 +165,10 @@ add_definitions(-DWITH_PYTHON_MODULE) # creates ./bin/bpy.so which can be imported as a python module. - add_library(blender SHARED ${SRC}) + # + # note that 'SHARED' works on Linux and Windows, + # but not OSX which _must_ be 'MODULE' + add_library(blender MODULE ${SRC}) set_target_properties( blender PROPERTIES @@ -175,6 +178,15 @@ RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin # only needed on windows ) + if(APPLE) + set_target_properties( + blender + PROPERTIES + LINK_FLAGS_RELEASE "${PLATFORM_LINKFLAGS}" + LINK_FLAGS_DEBUG "${PLATFORM_LINKFLAGS_DEBUG}" + ) + endif() + if(WIN32) # python modules use this set_target_properties( @@ -231,7 +243,11 @@ set(TARGETDIR_VER ${TARGETDIR}/${BLENDER_VERSION}) elseif(APPLE) - set(TARGETDIR_VER ${TARGETDIR}/blender.app/Contents/MacOS/${BLENDER_VERSION}) + if(WITH_PYTHON_MODULE) + set(TARGETDIR_VER ${TARGETDIR}/${BLENDER_VERSION}) + else() + set(TARGETDIR_VER ${TARGETDIR}/blender.app/Contents/MacOS/${BLENDER_VERSION}) + endif() endif() @@ -382,12 +398,21 @@ if(WITH_PYTHON) if(WITH_PYTHON_INSTALL) + # on some platforms (like openSUSE) Python is linked + # to be used from lib64 folder. + # determine this from Python's libraries path + if(${PYTHON_LIBPATH} MATCHES "lib64$") + set(_target_LIB "lib64") + else() + set(_target_LIB "lib") + endif() + # Copy the systems python into the install directory # Scons copy in tools/Blender.py # install(CODE "message(\"copying a subset of the systems python...\")") install( DIRECTORY ${PYTHON_LIBPATH}/python${PYTHON_VERSION} - DESTINATION ${TARGETDIR_VER}/python/lib + DESTINATION ${TARGETDIR_VER}/python/${_target_LIB} PATTERN ".svn" EXCLUDE PATTERN "__pycache__" EXCLUDE # * any cache * PATTERN "distutils" EXCLUDE # ./distutils @@ -405,6 +430,7 @@ # # doesnt work, todo # install(CODE "execute_process(COMMAND find ${TARGETDIR}/${BLENDER_VERSION}/python/lib/ -name '*.so' -exec strip -s {} '\;')") + unset(_target_LIB) endif() endif() elseif(WIN32) @@ -437,15 +463,15 @@ # ) if(WITH_PYTHON) - + set_lib_path(PYLIB "python/lib") install( - FILES ${LIBDIR}/python/lib/python32.dll + FILES ${PYLIB}/python32.dll DESTINATION ${TARGETDIR} CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel ) install( - FILES ${LIBDIR}/python/lib/python32_d.dll + FILES ${PYLIB}/python32_d.dll DESTINATION ${TARGETDIR} CONFIGURATIONS Debug ) @@ -491,7 +517,6 @@ else() install( FILES - ${LIBDIR}/png/lib/libpng.dll ${LIBDIR}/zlib/lib/zlib.dll DESTINATION ${TARGETDIR} ) @@ -533,7 +558,6 @@ install( FILES ${LIBDIR}/openal/lib/OpenAL32.dll - ${LIBDIR}/openal/lib/wrap_oal.dll DESTINATION ${TARGETDIR} ) endif() @@ -560,9 +584,10 @@ ) if(WITH_OPENIMAGEIO) + set_lib_path(OIIOBIN "openimageio/bin") install( FILES - ${LIBDIR}/openimageio/bin/OpenImageIO.dll + ${OIIOBIN}/OpenImageIO.dll DESTINATION ${TARGETDIR} ) endif() @@ -614,10 +639,11 @@ ) # python - if(WITH_PYTHON) + if(WITH_PYTHON AND NOT WITH_PYTHON_MODULE) # the python zip is first extract as part of the build process, # and then later installed as part of make install. this is much # quicker, and means we can easily exclude files on copy + # Not needed for PYTHON_MODULE or WEB_PLUGIN due uses Pyhon framework add_custom_target( extractpyzip DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/python) @@ -776,11 +802,11 @@ bf_nodes bf_gpu bf_blenloader + bf_imbuf bf_blenlib bf_intern_ghost bf_intern_string bf_blenpluginapi - bf_imbuf bf_avi bf_imbuf_cineon bf_imbuf_openexr @@ -823,6 +849,7 @@ bf_blenfont bf_intern_audaspace bf_intern_mikktspace + bf_intern_dualcon bf_intern_cycles cycles_render cycles_bvh @@ -860,6 +887,10 @@ list(APPEND BLENDER_SORTED_LIBS bf_quicktime) endif() + if(WITH_CARVE) + list(APPEND BLENDER_SORTED_LIBS extern_carve) + endif() + foreach(SORTLIB ${BLENDER_SORTED_LIBS}) set(REMLIB ${SORTLIB}) foreach(SEARCHLIB ${BLENDER_LINK_LIBS}) diff -Nru blender-2.61/source/creator/creator.c blender-2.62/source/creator/creator.c --- blender-2.61/source/creator/creator.c 2011-12-13 19:46:18.000000000 +0000 +++ blender-2.62/source/creator/creator.c 2012-02-15 19:30:38.000000000 +0000 @@ -301,7 +301,7 @@ printf (" $BLENDER_USER_CONFIG Directory for user configuration files.\n"); printf (" $BLENDER_USER_SCRIPTS Directory for user scripts.\n"); printf (" $BLENDER_SYSTEM_SCRIPTS Directory for system wide scripts.\n"); - printf (" $BLENDER_USER_DAT`AFILES Directory for user data files (icons, translations, ..).\n"); + printf (" $Directory for user data files (icons, translations, ..).\n"); printf (" $BLENDER_SYSTEM_DATAFILES Directory for system wide data files.\n"); printf (" $BLENDER_SYSTEM_PYTHON Directory for system python libraries.\n"); #ifdef WIN32 @@ -925,6 +925,12 @@ /* Make the path absolute because its needed for relative linked blends to be found */ char filename[FILE_MAX]; + + /* note, we could skip these, but so far we always tried to load these files */ + if (argv[0][0] == '-') { + fprintf(stderr, "unknown argument, loading as file: %s\n", argv[0]); + } + BLI_strncpy(filename, argv[0], sizeof(filename)); BLI_path_cwd(filename); @@ -1102,6 +1108,13 @@ /* allow python module to call main */ #define main main_python_enter static void *evil_C= NULL; + +#ifdef __APPLE__ +/* environ is not available in mac shared libraries */ +#include +char **environ = NULL; +#endif + #endif int main(int argc, const char **argv) @@ -1111,6 +1124,10 @@ bArgs *ba; #ifdef WITH_PYTHON_MODULE +#ifdef __APPLE__ + environ = *_NSGetEnviron(); +#endif + #undef main evil_C= C; #endif @@ -1124,7 +1141,7 @@ #endif setCallbacks(); -#ifdef __APPLE__ +#if defined(__APPLE__) && !defined(WITH_PYTHON_MODULE) /* patch to ignore argument finder gives us (pid?) */ if (argc==2 && strncmp(argv[1], "-psn_", 5)==0) { extern int GHOST_HACK_getFirstFile(char buf[]); diff -Nru blender-2.61/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp blender-2.62/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp --- blender-2.61/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp 2011-12-13 19:46:27.000000000 +0000 +++ blender-2.62/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp 2012-02-15 19:30:47.000000000 +0000 @@ -241,6 +241,7 @@ ketsjiengine->SetUseFixedTime(usefixed); ketsjiengine->SetTimingDisplay(frameRate, profile, properties); ketsjiengine->SetRestrictAnimationFPS(restrictAnimFPS); + KX_KetsjiEngine::SetExitKey(ConvertKeyCode(startscene->gm.exitkey)); //set the global settings (carried over if restart/load new files) ketsjiengine->SetGlobalSettings(&gs); @@ -285,7 +286,7 @@ exitrequested = KX_EXIT_REQUEST_NO_REQUEST; if (bfd) BLO_blendfiledata_free(bfd); - char basedpath[240]; + char basedpath[FILE_MAX]; // base the actuator filename with respect // to the original file working directory diff -Nru blender-2.61/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp blender-2.62/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp --- blender-2.61/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp 2011-12-13 19:46:27.000000000 +0000 +++ blender-2.62/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp 2012-02-15 19:30:47.000000000 +0000 @@ -59,6 +59,11 @@ BL_SwapBuffers(m_win); } +void KX_BlenderCanvas::ResizeWindow(int width, int height) +{ + // Not implemented for the embedded player +} + void KX_BlenderCanvas::BeginFrame() { glEnable(GL_DEPTH_TEST); diff -Nru blender-2.61/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h blender-2.62/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h --- blender-2.61/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h 2011-12-13 19:46:27.000000000 +0000 +++ blender-2.62/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h 2012-02-15 19:30:47.000000000 +0000 @@ -78,7 +78,7 @@ SwapBuffers( ); void - Resize( + ResizeWindow( int width, int height ); diff -Nru blender-2.61/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp blender-2.62/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp --- blender-2.61/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp 2011-12-13 19:46:27.000000000 +0000 +++ blender-2.62/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp 2012-02-15 19:30:47.000000000 +0000 @@ -147,7 +147,7 @@ BLF_size(fontid, size, dpi); BLF_position(fontid, 0, 0, 0); - BLF_draw(fontid, (char *)text, strlen(text)); + BLF_draw(fontid, (char *)text, 65535); BLF_disable(fontid, BLF_MATRIX|BLF_ASPECT); } diff -Nru blender-2.61/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h blender-2.62/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h --- blender-2.61/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h 2011-12-13 19:46:27.000000000 +0000 +++ blender-2.62/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h 2012-02-15 19:30:47.000000000 +0000 @@ -41,6 +41,7 @@ #include "wm_event_types.h" #include "WM_types.h" #include "SCA_IInputDevice.h" +#include "BL_BlenderDataConversion.h" #ifdef WITH_CXX_GUARDEDALLOC #include "MEM_guardedalloc.h" @@ -51,172 +52,9 @@ */ class BL_BlenderInputDevice : public SCA_IInputDevice { - // this map is Blender specific: a conversion between blender and ketsji enums - std::map m_reverseKeyTranslateTable; public: BL_BlenderInputDevice() { - - /* The reverse table. In order to not confuse ourselves, we */ - /* immediately convert all events that come in to KX codes. */ - m_reverseKeyTranslateTable[LEFTMOUSE ] = KX_LEFTMOUSE; - m_reverseKeyTranslateTable[MIDDLEMOUSE ] = KX_MIDDLEMOUSE; - m_reverseKeyTranslateTable[RIGHTMOUSE ] = KX_RIGHTMOUSE; - m_reverseKeyTranslateTable[WHEELUPMOUSE ] = KX_WHEELUPMOUSE; - m_reverseKeyTranslateTable[WHEELDOWNMOUSE ] = KX_WHEELDOWNMOUSE; - m_reverseKeyTranslateTable[MOUSEX ] = KX_MOUSEX; - m_reverseKeyTranslateTable[MOUSEY ] = KX_MOUSEY; - - // TIMERS - - m_reverseKeyTranslateTable[TIMER0 ] = KX_TIMER0; - m_reverseKeyTranslateTable[TIMER1 ] = KX_TIMER1; - m_reverseKeyTranslateTable[TIMER2 ] = KX_TIMER2; - - // SYSTEM -#if 0 - /* **** XXX **** */ - m_reverseKeyTranslateTable[KEYBD ] = KX_KEYBD; - m_reverseKeyTranslateTable[RAWKEYBD ] = KX_RAWKEYBD; - m_reverseKeyTranslateTable[REDRAW ] = KX_REDRAW; - m_reverseKeyTranslateTable[INPUTCHANGE ] = KX_INPUTCHANGE; - m_reverseKeyTranslateTable[QFULL ] = KX_QFULL; - m_reverseKeyTranslateTable[WINFREEZE ] = KX_WINFREEZE; - m_reverseKeyTranslateTable[WINTHAW ] = KX_WINTHAW; - m_reverseKeyTranslateTable[WINCLOSE ] = KX_WINCLOSE; - m_reverseKeyTranslateTable[WINQUIT ] = KX_WINQUIT; - m_reverseKeyTranslateTable[Q_FIRSTTIME ] = KX_Q_FIRSTTIME; - /* **** XXX **** */ -#endif - // standard keyboard - - m_reverseKeyTranslateTable[AKEY ] = KX_AKEY; - m_reverseKeyTranslateTable[BKEY ] = KX_BKEY; - m_reverseKeyTranslateTable[CKEY ] = KX_CKEY; - m_reverseKeyTranslateTable[DKEY ] = KX_DKEY; - m_reverseKeyTranslateTable[EKEY ] = KX_EKEY; - m_reverseKeyTranslateTable[FKEY ] = KX_FKEY; - m_reverseKeyTranslateTable[GKEY ] = KX_GKEY; - //XXX clean up -#ifdef WIN32 -#define HKEY 'h' -#endif - m_reverseKeyTranslateTable[HKEY ] = KX_HKEY; - //XXX clean up -#ifdef WIN32 -#undef HKEY -#endif - m_reverseKeyTranslateTable[IKEY ] = KX_IKEY; - m_reverseKeyTranslateTable[JKEY ] = KX_JKEY; - m_reverseKeyTranslateTable[KKEY ] = KX_KKEY; - m_reverseKeyTranslateTable[LKEY ] = KX_LKEY; - m_reverseKeyTranslateTable[MKEY ] = KX_MKEY; - m_reverseKeyTranslateTable[NKEY ] = KX_NKEY; - m_reverseKeyTranslateTable[OKEY ] = KX_OKEY; - m_reverseKeyTranslateTable[PKEY ] = KX_PKEY; - m_reverseKeyTranslateTable[QKEY ] = KX_QKEY; - m_reverseKeyTranslateTable[RKEY ] = KX_RKEY; - m_reverseKeyTranslateTable[SKEY ] = KX_SKEY; - m_reverseKeyTranslateTable[TKEY ] = KX_TKEY; - m_reverseKeyTranslateTable[UKEY ] = KX_UKEY; - m_reverseKeyTranslateTable[VKEY ] = KX_VKEY; - m_reverseKeyTranslateTable[WKEY ] = KX_WKEY; - m_reverseKeyTranslateTable[XKEY ] = KX_XKEY; - m_reverseKeyTranslateTable[YKEY ] = KX_YKEY; - m_reverseKeyTranslateTable[ZKEY ] = KX_ZKEY; - - m_reverseKeyTranslateTable[ZEROKEY ] = KX_ZEROKEY; - m_reverseKeyTranslateTable[ONEKEY ] = KX_ONEKEY; - m_reverseKeyTranslateTable[TWOKEY ] = KX_TWOKEY; - m_reverseKeyTranslateTable[THREEKEY ] = KX_THREEKEY; - m_reverseKeyTranslateTable[FOURKEY ] = KX_FOURKEY; - m_reverseKeyTranslateTable[FIVEKEY ] = KX_FIVEKEY; - m_reverseKeyTranslateTable[SIXKEY ] = KX_SIXKEY; - m_reverseKeyTranslateTable[SEVENKEY ] = KX_SEVENKEY; - m_reverseKeyTranslateTable[EIGHTKEY ] = KX_EIGHTKEY; - m_reverseKeyTranslateTable[NINEKEY ] = KX_NINEKEY; - - m_reverseKeyTranslateTable[CAPSLOCKKEY ] = KX_CAPSLOCKKEY; - - m_reverseKeyTranslateTable[LEFTCTRLKEY ] = KX_LEFTCTRLKEY; - m_reverseKeyTranslateTable[LEFTALTKEY ] = KX_LEFTALTKEY; - m_reverseKeyTranslateTable[RIGHTALTKEY ] = KX_RIGHTALTKEY; - m_reverseKeyTranslateTable[RIGHTCTRLKEY ] = KX_RIGHTCTRLKEY; - m_reverseKeyTranslateTable[RIGHTSHIFTKEY ] = KX_RIGHTSHIFTKEY; - m_reverseKeyTranslateTable[LEFTSHIFTKEY ] = KX_LEFTSHIFTKEY; - - m_reverseKeyTranslateTable[ESCKEY ] = KX_ESCKEY; - m_reverseKeyTranslateTable[TABKEY ] = KX_TABKEY; - m_reverseKeyTranslateTable[RETKEY ] = KX_RETKEY; - m_reverseKeyTranslateTable[SPACEKEY ] = KX_SPACEKEY; - m_reverseKeyTranslateTable[LINEFEEDKEY ] = KX_LINEFEEDKEY; - m_reverseKeyTranslateTable[BACKSPACEKEY ] = KX_BACKSPACEKEY; - m_reverseKeyTranslateTable[DELKEY ] = KX_DELKEY; - m_reverseKeyTranslateTable[SEMICOLONKEY ] = KX_SEMICOLONKEY; - m_reverseKeyTranslateTable[PERIODKEY ] = KX_PERIODKEY; - m_reverseKeyTranslateTable[COMMAKEY ] = KX_COMMAKEY; - m_reverseKeyTranslateTable[QUOTEKEY ] = KX_QUOTEKEY; - m_reverseKeyTranslateTable[ACCENTGRAVEKEY ] = KX_ACCENTGRAVEKEY; - m_reverseKeyTranslateTable[MINUSKEY ] = KX_MINUSKEY; - m_reverseKeyTranslateTable[SLASHKEY ] = KX_SLASHKEY; - m_reverseKeyTranslateTable[BACKSLASHKEY ] = KX_BACKSLASHKEY; - m_reverseKeyTranslateTable[EQUALKEY ] = KX_EQUALKEY; - m_reverseKeyTranslateTable[LEFTBRACKETKEY ] = KX_LEFTBRACKETKEY; - m_reverseKeyTranslateTable[RIGHTBRACKETKEY ] = KX_RIGHTBRACKETKEY; - - m_reverseKeyTranslateTable[LEFTARROWKEY ] = KX_LEFTARROWKEY; - m_reverseKeyTranslateTable[DOWNARROWKEY ] = KX_DOWNARROWKEY; - m_reverseKeyTranslateTable[RIGHTARROWKEY ] = KX_RIGHTARROWKEY; - m_reverseKeyTranslateTable[UPARROWKEY ] = KX_UPARROWKEY; - - m_reverseKeyTranslateTable[PAD2 ] = KX_PAD2; - m_reverseKeyTranslateTable[PAD4 ] = KX_PAD4; - m_reverseKeyTranslateTable[PAD6 ] = KX_PAD6; - m_reverseKeyTranslateTable[PAD8 ] = KX_PAD8; - - m_reverseKeyTranslateTable[PAD1 ] = KX_PAD1; - m_reverseKeyTranslateTable[PAD3 ] = KX_PAD3; - m_reverseKeyTranslateTable[PAD5 ] = KX_PAD5; - m_reverseKeyTranslateTable[PAD7 ] = KX_PAD7; - m_reverseKeyTranslateTable[PAD9 ] = KX_PAD9; - - m_reverseKeyTranslateTable[PADPERIOD ] = KX_PADPERIOD; - m_reverseKeyTranslateTable[PADSLASHKEY ] = KX_PADSLASHKEY; - m_reverseKeyTranslateTable[PADASTERKEY ] = KX_PADASTERKEY; - - - m_reverseKeyTranslateTable[PAD0 ] = KX_PAD0; - m_reverseKeyTranslateTable[PADMINUS ] = KX_PADMINUS; - m_reverseKeyTranslateTable[PADENTER ] = KX_PADENTER; - m_reverseKeyTranslateTable[PADPLUSKEY ] = KX_PADPLUSKEY; - - - m_reverseKeyTranslateTable[F1KEY ] = KX_F1KEY; - m_reverseKeyTranslateTable[F2KEY ] = KX_F2KEY; - m_reverseKeyTranslateTable[F3KEY ] = KX_F3KEY; - m_reverseKeyTranslateTable[F4KEY ] = KX_F4KEY; - m_reverseKeyTranslateTable[F5KEY ] = KX_F5KEY; - m_reverseKeyTranslateTable[F6KEY ] = KX_F6KEY; - m_reverseKeyTranslateTable[F7KEY ] = KX_F7KEY; - m_reverseKeyTranslateTable[F8KEY ] = KX_F8KEY; - m_reverseKeyTranslateTable[F9KEY ] = KX_F9KEY; - m_reverseKeyTranslateTable[F10KEY ] = KX_F10KEY; - m_reverseKeyTranslateTable[F11KEY ] = KX_F11KEY; - m_reverseKeyTranslateTable[F12KEY ] = KX_F12KEY; - m_reverseKeyTranslateTable[F13KEY ] = KX_F13KEY; - m_reverseKeyTranslateTable[F14KEY ] = KX_F14KEY; - m_reverseKeyTranslateTable[F15KEY ] = KX_F15KEY; - m_reverseKeyTranslateTable[F16KEY ] = KX_F16KEY; - m_reverseKeyTranslateTable[F17KEY ] = KX_F17KEY; - m_reverseKeyTranslateTable[F18KEY ] = KX_F18KEY; - m_reverseKeyTranslateTable[F19KEY ] = KX_F19KEY; - - m_reverseKeyTranslateTable[PAUSEKEY ] = KX_PAUSEKEY; - m_reverseKeyTranslateTable[INSERTKEY ] = KX_INSERTKEY; - m_reverseKeyTranslateTable[HOMEKEY ] = KX_HOMEKEY; - m_reverseKeyTranslateTable[PAGEUPKEY ] = KX_PAGEUPKEY; - m_reverseKeyTranslateTable[PAGEDOWNKEY ] = KX_PAGEDOWNKEY; - m_reverseKeyTranslateTable[ENDKEY ] = KX_ENDKEY; } virtual ~BL_BlenderInputDevice() @@ -225,7 +63,7 @@ } KX_EnumInputs ToNative(unsigned short incode) { - return m_reverseKeyTranslateTable[incode]; + return ConvertKeyCode(incode); } virtual bool IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode)=0; diff -Nru blender-2.61/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp blender-2.62/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp --- blender-2.61/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp 2011-12-13 19:46:27.000000000 +0000 +++ blender-2.62/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp 2012-02-15 19:30:47.000000000 +0000 @@ -36,6 +36,7 @@ #endif #include "KX_BlenderKeyboardDevice.h" +#include "KX_KetsjiEngine.h" KX_BlenderKeyboardDevice::KX_BlenderKeyboardDevice() : m_hookesc(false) @@ -106,7 +107,7 @@ if (val == KM_PRESS) { - if (kxevent == KX_ESCKEY && val != 0 && !m_hookesc) + if (kxevent == KX_KetsjiEngine::GetExitKey() && val != 0 && !m_hookesc) result = true; if (kxevent == KX_PAUSEKEY && val && (IsPressed(KX_LEFTCTRLKEY) || IsPressed(KX_RIGHTCTRLKEY))) result = true; diff -Nru blender-2.61/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.h blender-2.62/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.h --- blender-2.61/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.h 2011-12-13 19:46:27.000000000 +0000 +++ blender-2.62/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.h 2012-02-15 19:30:47.000000000 +0000 @@ -50,6 +50,8 @@ virtual bool ConvertBlenderEvent(unsigned short incode,short val); virtual void NextFrame(); virtual void HookEscape(); +private: + short m_exit_key; #ifdef WITH_CXX_GUARDEDALLOC diff -Nru blender-2.61/source/gameengine/Converter/BL_ActionActuator.cpp blender-2.62/source/gameengine/Converter/BL_ActionActuator.cpp --- blender-2.61/source/gameengine/Converter/BL_ActionActuator.cpp 2011-12-13 19:46:58.000000000 +0000 +++ blender-2.62/source/gameengine/Converter/BL_ActionActuator.cpp 2012-02-15 19:31:17.000000000 +0000 @@ -123,7 +123,8 @@ } -void BL_ActionActuator::SetBlendTime (float newtime){ +void BL_ActionActuator::SetBlendTime (float newtime) +{ m_blendframe = newtime; } @@ -349,6 +350,12 @@ PyObject* BL_ActionActuator::PyGetChannel(PyObject* value) { const char *string= _PyUnicode_AsString(value); + + if (GetParent()->GetGameObjectType() != SCA_IObject::OBJ_ARMATURE) + { + PyErr_SetString(PyExc_NotImplementedError, "actuator.getChannel(): Only armatures support channels"); + return NULL; + } if (!string) { PyErr_SetString(PyExc_TypeError, "expected a single string"); @@ -413,6 +420,12 @@ PyObject *pymat= NULL; PyObject *pyloc= NULL, *pysize= NULL, *pyquat= NULL; bPoseChannel *pchan; + + if (GetParent()->GetGameObjectType() != SCA_IObject::OBJ_ARMATURE) + { + PyErr_SetString(PyExc_NotImplementedError, "actuator.setChannel(): Only armatures support channels"); + return NULL; + } if(PyTuple_Size(args)==2) { if (!PyArg_ParseTuple(args,"sO:setChannel", &string, &pymat)) // matrix @@ -525,8 +538,8 @@ KX_PYATTRIBUTE_RO_FUNCTION("channelNames", BL_ActionActuator, pyattr_get_channel_names), KX_PYATTRIBUTE_SHORT_RW("priority", 0, 100, false, BL_ActionActuator, m_priority), KX_PYATTRIBUTE_RW_FUNCTION("frame", BL_ActionActuator, pyattr_get_frame, pyattr_set_frame), - KX_PYATTRIBUTE_STRING_RW("propName", 0, 31, false, BL_ActionActuator, m_propname), - KX_PYATTRIBUTE_STRING_RW("framePropName", 0, 31, false, BL_ActionActuator, m_framepropname), + KX_PYATTRIBUTE_STRING_RW("propName", 0, MAX_PROP_NAME, false, BL_ActionActuator, m_propname), + KX_PYATTRIBUTE_STRING_RW("framePropName", 0, MAX_PROP_NAME, false, BL_ActionActuator, m_framepropname), KX_PYATTRIBUTE_RW_FUNCTION("useContinue", BL_ActionActuator, pyattr_get_use_continue, pyattr_set_use_continue), KX_PYATTRIBUTE_FLOAT_RW_CHECK("blendTime", 0, MAXFRAMEF, BL_ActionActuator, m_blendframe, CheckBlendTime), KX_PYATTRIBUTE_SHORT_RW_CHECK("mode",0,100,false,BL_ActionActuator,m_playtype,CheckType), @@ -573,6 +586,12 @@ PyObject *ret= PyList_New(0); PyObject *item; + if (self->GetParent()->GetGameObjectType() != SCA_IObject::OBJ_ARMATURE) + { + PyErr_SetString(PyExc_NotImplementedError, "actuator.channelNames: Only armatures support channels"); + return NULL; + } + bPose *pose= ((BL_ArmatureObject*)self->GetParent())->GetOrigPose(); if(pose) { diff -Nru blender-2.61/source/gameengine/Converter/BL_ArmatureChannel.cpp blender-2.62/source/gameengine/Converter/BL_ArmatureChannel.cpp --- blender-2.61/source/gameengine/Converter/BL_ArmatureChannel.cpp 2011-12-13 19:46:58.000000000 +0000 +++ blender-2.62/source/gameengine/Converter/BL_ArmatureChannel.cpp 2012-02-15 19:31:17.000000000 +0000 @@ -215,7 +215,7 @@ normalize_m3(pose_mat); if (pchan->parent) { // bone has a parent, compute the rest pose of the bone taking actual pose of parent - mul_m3_m3m4(rest_mat, pchan->bone->bone_mat, pchan->parent->pose_mat); + mult_m3_m3m4(rest_mat, pchan->parent->pose_mat, pchan->bone->bone_mat); normalize_m3(rest_mat); } else { // otherwise, the bone matrix in armature space is the rest pose diff -Nru blender-2.61/source/gameengine/Converter/BL_BlenderDataConversion.cpp blender-2.62/source/gameengine/Converter/BL_BlenderDataConversion.cpp --- blender-2.61/source/gameengine/Converter/BL_BlenderDataConversion.cpp 2011-12-13 19:46:58.000000000 +0000 +++ blender-2.62/source/gameengine/Converter/BL_BlenderDataConversion.cpp 2012-02-15 19:31:17.000000000 +0000 @@ -197,6 +197,180 @@ static bool default_light_mode = 0; +static std::map create_translate_table() +{ + std::map m; + + /* The reverse table. In order to not confuse ourselves, we */ + /* immediately convert all events that come in to KX codes. */ + m[LEFTMOUSE ] = SCA_IInputDevice::KX_LEFTMOUSE; + m[MIDDLEMOUSE ] = SCA_IInputDevice::KX_MIDDLEMOUSE; + m[RIGHTMOUSE ] = SCA_IInputDevice::KX_RIGHTMOUSE; + m[WHEELUPMOUSE ] = SCA_IInputDevice::KX_WHEELUPMOUSE; + m[WHEELDOWNMOUSE ] = SCA_IInputDevice::KX_WHEELDOWNMOUSE; + m[MOUSEX ] = SCA_IInputDevice::KX_MOUSEX; + m[MOUSEY ] = SCA_IInputDevice::KX_MOUSEY; + + // TIMERS + + m[TIMER0 ] = SCA_IInputDevice::KX_TIMER0; + m[TIMER1 ] = SCA_IInputDevice::KX_TIMER1; + m[TIMER2 ] = SCA_IInputDevice::KX_TIMER2; + + // SYSTEM + +#if 0 + /* **** XXX **** */ + m[KEYBD ] = SCA_IInputDevice::KX_KEYBD; + m[RAWKEYBD ] = SCA_IInputDevice::KX_RAWKEYBD; + m[REDRAW ] = SCA_IInputDevice::KX_REDRAW; + m[INPUTCHANGE ] = SCA_IInputDevice::KX_INPUTCHANGE; + m[QFULL ] = SCA_IInputDevice::KX_QFULL; + m[WINFREEZE ] = SCA_IInputDevice::KX_WINFREEZE; + m[WINTHAW ] = SCA_IInputDevice::KX_WINTHAW; + m[WINCLOSE ] = SCA_IInputDevice::KX_WINCLOSE; + m[WINQUIT ] = SCA_IInputDevice::KX_WINQUIT; + m[Q_FIRSTTIME ] = SCA_IInputDevice::KX_Q_FIRSTTIME; + /* **** XXX **** */ +#endif + + // standard keyboard + + m[AKEY ] = SCA_IInputDevice::KX_AKEY; + m[BKEY ] = SCA_IInputDevice::KX_BKEY; + m[CKEY ] = SCA_IInputDevice::KX_CKEY; + m[DKEY ] = SCA_IInputDevice::KX_DKEY; + m[EKEY ] = SCA_IInputDevice::KX_EKEY; + m[FKEY ] = SCA_IInputDevice::KX_FKEY; + m[GKEY ] = SCA_IInputDevice::KX_GKEY; + +//XXX clean up +#ifdef WIN32 +#define HKEY 'h' +#endif + m[HKEY ] = SCA_IInputDevice::KX_HKEY; +//XXX clean up +#ifdef WIN32 +#undef HKEY +#endif + + m[IKEY ] = SCA_IInputDevice::KX_IKEY; + m[JKEY ] = SCA_IInputDevice::KX_JKEY; + m[KKEY ] = SCA_IInputDevice::KX_KKEY; + m[LKEY ] = SCA_IInputDevice::KX_LKEY; + m[MKEY ] = SCA_IInputDevice::KX_MKEY; + m[NKEY ] = SCA_IInputDevice::KX_NKEY; + m[OKEY ] = SCA_IInputDevice::KX_OKEY; + m[PKEY ] = SCA_IInputDevice::KX_PKEY; + m[QKEY ] = SCA_IInputDevice::KX_QKEY; + m[RKEY ] = SCA_IInputDevice::KX_RKEY; + m[SKEY ] = SCA_IInputDevice::KX_SKEY; + m[TKEY ] = SCA_IInputDevice::KX_TKEY; + m[UKEY ] = SCA_IInputDevice::KX_UKEY; + m[VKEY ] = SCA_IInputDevice::KX_VKEY; + m[WKEY ] = SCA_IInputDevice::KX_WKEY; + m[XKEY ] = SCA_IInputDevice::KX_XKEY; + m[YKEY ] = SCA_IInputDevice::KX_YKEY; + m[ZKEY ] = SCA_IInputDevice::KX_ZKEY; + + m[ZEROKEY ] = SCA_IInputDevice::KX_ZEROKEY; + m[ONEKEY ] = SCA_IInputDevice::KX_ONEKEY; + m[TWOKEY ] = SCA_IInputDevice::KX_TWOKEY; + m[THREEKEY ] = SCA_IInputDevice::KX_THREEKEY; + m[FOURKEY ] = SCA_IInputDevice::KX_FOURKEY; + m[FIVEKEY ] = SCA_IInputDevice::KX_FIVEKEY; + m[SIXKEY ] = SCA_IInputDevice::KX_SIXKEY; + m[SEVENKEY ] = SCA_IInputDevice::KX_SEVENKEY; + m[EIGHTKEY ] = SCA_IInputDevice::KX_EIGHTKEY; + m[NINEKEY ] = SCA_IInputDevice::KX_NINEKEY; + + m[CAPSLOCKKEY ] = SCA_IInputDevice::KX_CAPSLOCKKEY; + + m[LEFTCTRLKEY ] = SCA_IInputDevice::KX_LEFTCTRLKEY; + m[LEFTALTKEY ] = SCA_IInputDevice::KX_LEFTALTKEY; + m[RIGHTALTKEY ] = SCA_IInputDevice::KX_RIGHTALTKEY; + m[RIGHTCTRLKEY ] = SCA_IInputDevice::KX_RIGHTCTRLKEY; + m[RIGHTSHIFTKEY ] = SCA_IInputDevice::KX_RIGHTSHIFTKEY; + m[LEFTSHIFTKEY ] = SCA_IInputDevice::KX_LEFTSHIFTKEY; + + m[ESCKEY ] = SCA_IInputDevice::KX_ESCKEY; + m[TABKEY ] = SCA_IInputDevice::KX_TABKEY; + m[RETKEY ] = SCA_IInputDevice::KX_RETKEY; + m[SPACEKEY ] = SCA_IInputDevice::KX_SPACEKEY; + m[LINEFEEDKEY ] = SCA_IInputDevice::KX_LINEFEEDKEY; + m[BACKSPACEKEY ] = SCA_IInputDevice::KX_BACKSPACEKEY; + m[DELKEY ] = SCA_IInputDevice::KX_DELKEY; + m[SEMICOLONKEY ] = SCA_IInputDevice::KX_SEMICOLONKEY; + m[PERIODKEY ] = SCA_IInputDevice::KX_PERIODKEY; + m[COMMAKEY ] = SCA_IInputDevice::KX_COMMAKEY; + m[QUOTEKEY ] = SCA_IInputDevice::KX_QUOTEKEY; + m[ACCENTGRAVEKEY ] = SCA_IInputDevice::KX_ACCENTGRAVEKEY; + m[MINUSKEY ] = SCA_IInputDevice::KX_MINUSKEY; + m[SLASHKEY ] = SCA_IInputDevice::KX_SLASHKEY; + m[BACKSLASHKEY ] = SCA_IInputDevice::KX_BACKSLASHKEY; + m[EQUALKEY ] = SCA_IInputDevice::KX_EQUALKEY; + m[LEFTBRACKETKEY ] = SCA_IInputDevice::KX_LEFTBRACKETKEY; + m[RIGHTBRACKETKEY ] = SCA_IInputDevice::KX_RIGHTBRACKETKEY; + + m[LEFTARROWKEY ] = SCA_IInputDevice::KX_LEFTARROWKEY; + m[DOWNARROWKEY ] = SCA_IInputDevice::KX_DOWNARROWKEY; + m[RIGHTARROWKEY ] = SCA_IInputDevice::KX_RIGHTARROWKEY; + m[UPARROWKEY ] = SCA_IInputDevice::KX_UPARROWKEY; + + m[PAD2 ] = SCA_IInputDevice::KX_PAD2; + m[PAD4 ] = SCA_IInputDevice::KX_PAD4; + m[PAD6 ] = SCA_IInputDevice::KX_PAD6; + m[PAD8 ] = SCA_IInputDevice::KX_PAD8; + + m[PAD1 ] = SCA_IInputDevice::KX_PAD1; + m[PAD3 ] = SCA_IInputDevice::KX_PAD3; + m[PAD5 ] = SCA_IInputDevice::KX_PAD5; + m[PAD7 ] = SCA_IInputDevice::KX_PAD7; + m[PAD9 ] = SCA_IInputDevice::KX_PAD9; + + m[PADPERIOD ] = SCA_IInputDevice::KX_PADPERIOD; + m[PADSLASHKEY ] = SCA_IInputDevice::KX_PADSLASHKEY; + m[PADASTERKEY ] = SCA_IInputDevice::KX_PADASTERKEY; + + m[PAD0 ] = SCA_IInputDevice::KX_PAD0; + m[PADMINUS ] = SCA_IInputDevice::KX_PADMINUS; + m[PADENTER ] = SCA_IInputDevice::KX_PADENTER; + m[PADPLUSKEY ] = SCA_IInputDevice::KX_PADPLUSKEY; + + + m[F1KEY ] = SCA_IInputDevice::KX_F1KEY; + m[F2KEY ] = SCA_IInputDevice::KX_F2KEY; + m[F3KEY ] = SCA_IInputDevice::KX_F3KEY; + m[F4KEY ] = SCA_IInputDevice::KX_F4KEY; + m[F5KEY ] = SCA_IInputDevice::KX_F5KEY; + m[F6KEY ] = SCA_IInputDevice::KX_F6KEY; + m[F7KEY ] = SCA_IInputDevice::KX_F7KEY; + m[F8KEY ] = SCA_IInputDevice::KX_F8KEY; + m[F9KEY ] = SCA_IInputDevice::KX_F9KEY; + m[F10KEY ] = SCA_IInputDevice::KX_F10KEY; + m[F11KEY ] = SCA_IInputDevice::KX_F11KEY; + m[F12KEY ] = SCA_IInputDevice::KX_F12KEY; + m[F13KEY ] = SCA_IInputDevice::KX_F13KEY; + m[F14KEY ] = SCA_IInputDevice::KX_F14KEY; + m[F15KEY ] = SCA_IInputDevice::KX_F15KEY; + m[F16KEY ] = SCA_IInputDevice::KX_F16KEY; + m[F17KEY ] = SCA_IInputDevice::KX_F17KEY; + m[F18KEY ] = SCA_IInputDevice::KX_F18KEY; + m[F19KEY ] = SCA_IInputDevice::KX_F19KEY; + + + m[PAUSEKEY ] = SCA_IInputDevice::KX_PAUSEKEY; + m[INSERTKEY ] = SCA_IInputDevice::KX_INSERTKEY; + m[HOMEKEY ] = SCA_IInputDevice::KX_HOMEKEY; + m[PAGEUPKEY ] = SCA_IInputDevice::KX_PAGEUPKEY; + m[PAGEDOWNKEY ] = SCA_IInputDevice::KX_PAGEDOWNKEY; + m[ENDKEY ] = SCA_IInputDevice::KX_ENDKEY; + + return m; +} + +static std::map gReverseKeyTranslateTable = create_translate_table(); + static unsigned int KX_rgbaint2uint_new(unsigned int icol) { union @@ -1678,7 +1852,8 @@ -static KX_LightObject *gamelight_from_blamp(Object *ob, Lamp *la, unsigned int layerflag, KX_Scene *kxscene, RAS_IRenderTools *rendertools, KX_BlenderSceneConverter *converter) { +static KX_LightObject *gamelight_from_blamp(Object *ob, Lamp *la, unsigned int layerflag, KX_Scene *kxscene, RAS_IRenderTools *rendertools, KX_BlenderSceneConverter *converter) +{ RAS_LightObject lightobj; KX_LightObject *gamelight; @@ -1722,7 +1897,8 @@ return gamelight; } -static KX_Camera *gamecamera_from_bcamera(Object *ob, KX_Scene *kxscene, KX_BlenderSceneConverter *converter) { +static KX_Camera *gamecamera_from_bcamera(Object *ob, KX_Scene *kxscene, KX_BlenderSceneConverter *converter) +{ Camera* ca = static_cast(ob->data); RAS_CameraData camdata(ca->lens, ca->ortho_scale, ca->sensor_x, ca->sensor_y, ca->sensor_fit, ca->clipsta, ca->clipend, ca->type == CAM_PERSP, ca->YF_dofdist); KX_Camera *gamecamera; @@ -1976,6 +2152,155 @@ } +/* helper for BL_ConvertBlenderObjects, avoids code duplication + * note: all var names match args are passed from the caller */ +static void bl_ConvertBlenderObject_Single( + KX_BlenderSceneConverter *converter, + Scene *blenderscene, Object *blenderobject, + vector &inivel, vector &iniang, + vector &vec_parent_child, + CListValue* logicbrick_conversionlist, + CListValue* objectlist, CListValue* inactivelist, CListValue* sumolist, + KX_Scene* kxscene, KX_GameObject* gameobj, + SCA_LogicManager* logicmgr, SCA_TimeEventManager* timemgr, + bool isInActiveLayer + ) +{ + MT_Point3 posPrev; + MT_Matrix3x3 angor; + if (converter->addInitFromFrame) blenderscene->r.cfra=blenderscene->r.sfra; + + MT_Point3 pos( + blenderobject->loc[0]+blenderobject->dloc[0], + blenderobject->loc[1]+blenderobject->dloc[1], + blenderobject->loc[2]+blenderobject->dloc[2] + ); + MT_Vector3 eulxyz(blenderobject->rot); + MT_Vector3 scale(blenderobject->size); + if (converter->addInitFromFrame){//rcruiz + float eulxyzPrev[3]; + blenderscene->r.cfra=blenderscene->r.sfra-1; + //XXX update_for_newframe(); + MT_Vector3 tmp=pos-MT_Point3(blenderobject->loc[0]+blenderobject->dloc[0], + blenderobject->loc[1]+blenderobject->dloc[1], + blenderobject->loc[2]+blenderobject->dloc[2] + ); + eulxyzPrev[0]=blenderobject->rot[0]; + eulxyzPrev[1]=blenderobject->rot[1]; + eulxyzPrev[2]=blenderobject->rot[2]; + + double fps = (double) blenderscene->r.frs_sec/ + (double) blenderscene->r.frs_sec_base; + + tmp.scale(fps, fps, fps); + inivel.push_back(tmp); + tmp=eulxyz-eulxyzPrev; + tmp.scale(fps, fps, fps); + iniang.push_back(tmp); + blenderscene->r.cfra=blenderscene->r.sfra; + //XXX update_for_newframe(); + } + + gameobj->NodeSetLocalPosition(pos); + gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz)); + gameobj->NodeSetLocalScale(scale); + gameobj->NodeUpdateGS(0); + + BL_ConvertMaterialIpos(blenderobject, gameobj, converter); + + sumolist->Add(gameobj->AddRef()); + + BL_ConvertProperties(blenderobject,gameobj,timemgr,kxscene,isInActiveLayer); + + gameobj->SetName(blenderobject->id.name + 2); + + // update children/parent hierarchy + if ((blenderobject->parent != 0)&&(!converter->addInitFromFrame)) + { + // blender has an additional 'parentinverse' offset in each object + SG_Callbacks callback(NULL,NULL,NULL,KX_Scene::KX_ScenegraphUpdateFunc,KX_Scene::KX_ScenegraphRescheduleFunc); + SG_Node* parentinversenode = new SG_Node(NULL,kxscene,callback); + + // define a normal parent relationship for this node. + KX_NormalParentRelation * parent_relation = KX_NormalParentRelation::New(); + parentinversenode->SetParentRelation(parent_relation); + + parentChildLink pclink; + pclink.m_blenderchild = blenderobject; + pclink.m_gamechildnode = parentinversenode; + vec_parent_child.push_back(pclink); + + float* fl = (float*) blenderobject->parentinv; + MT_Transform parinvtrans(fl); + parentinversenode->SetLocalPosition(parinvtrans.getOrigin()); + // problem here: the parent inverse transform combines scaling and rotation + // in the basis but the scenegraph needs separate rotation and scaling. + // This is not important for OpenGL (it uses 4x4 matrix) but it is important + // for the physic engine that needs a separate scaling + //parentinversenode->SetLocalOrientation(parinvtrans.getBasis()); + + // Extract the rotation and the scaling from the basis + MT_Matrix3x3 ori(parinvtrans.getBasis()); + MT_Vector3 x(ori.getColumn(0)); + MT_Vector3 y(ori.getColumn(1)); + MT_Vector3 z(ori.getColumn(2)); + MT_Vector3 parscale(x.length(), y.length(), z.length()); + if (!MT_fuzzyZero(parscale[0])) + x /= parscale[0]; + if (!MT_fuzzyZero(parscale[1])) + y /= parscale[1]; + if (!MT_fuzzyZero(parscale[2])) + z /= parscale[2]; + ori.setColumn(0, x); + ori.setColumn(1, y); + ori.setColumn(2, z); + parentinversenode->SetLocalOrientation(ori); + parentinversenode->SetLocalScale(parscale); + + parentinversenode->AddChild(gameobj->GetSGNode()); + } + + // needed for python scripting + logicmgr->RegisterGameObjectName(gameobj->GetName(),gameobj); + + // needed for group duplication + logicmgr->RegisterGameObj(blenderobject, gameobj); + for (int i = 0; i < gameobj->GetMeshCount(); i++) + logicmgr->RegisterGameMeshName(gameobj->GetMesh(i)->GetName(), blenderobject); + + converter->RegisterGameObject(gameobj, blenderobject); + // this was put in rapidly, needs to be looked at more closely + // only draw/use objects in active 'blender' layers + + logicbrick_conversionlist->Add(gameobj->AddRef()); + + if (converter->addInitFromFrame){ + posPrev=gameobj->NodeGetWorldPosition(); + angor=gameobj->NodeGetWorldOrientation(); + } + if (isInActiveLayer) + { + objectlist->Add(gameobj->AddRef()); + //tf.Add(gameobj->GetSGNode()); + + gameobj->NodeUpdateGS(0); + gameobj->AddMeshUser(); + + } + else + { + //we must store this object otherwise it will be deleted + //at the end of this function if it is not a root object + inactivelist->Add(gameobj->AddRef()); + } + + if (converter->addInitFromFrame) { + gameobj->NodeSetLocalPosition(posPrev); + gameobj->NodeSetLocalOrientation(angor); + } +} + + // convert blender objects into ketsji gameobjects void BL_ConvertBlenderObjects(struct Main* maggie, KX_Scene* kxscene, @@ -1986,7 +2311,21 @@ KX_BlenderSceneConverter* converter, bool alwaysUseExpandFraming ) -{ +{ + +#define BL_CONVERTBLENDEROBJECT_SINGLE \ + bl_ConvertBlenderObject_Single(converter, \ + blenderscene, blenderobject, \ + inivel, iniang, \ + vec_parent_child, \ + logicbrick_conversionlist, \ + objectlist, inactivelist, sumolist, \ + kxscene, gameobj, \ + logicmgr, timemgr, \ + isInActiveLayer \ + ) + + Scene *blenderscene = kxscene->GetBlenderScene(); // for SETLOOPER @@ -2089,155 +2428,27 @@ if (!isInActiveLayer) addobj=false; - if (gameobj&&addobj) + if (gameobj) { - MT_Point3 posPrev; - MT_Matrix3x3 angor; - if (converter->addInitFromFrame) blenderscene->r.cfra=blenderscene->r.sfra; - - MT_Point3 pos; - pos.setValue( - blenderobject->loc[0]+blenderobject->dloc[0], - blenderobject->loc[1]+blenderobject->dloc[1], - blenderobject->loc[2]+blenderobject->dloc[2] - ); - MT_Vector3 eulxyz(blenderobject->rot); - MT_Vector3 scale(blenderobject->size); - if (converter->addInitFromFrame){//rcruiz - float eulxyzPrev[3]; - blenderscene->r.cfra=blenderscene->r.sfra-1; - //XXX update_for_newframe(); - MT_Vector3 tmp=pos-MT_Point3(blenderobject->loc[0]+blenderobject->dloc[0], - blenderobject->loc[1]+blenderobject->dloc[1], - blenderobject->loc[2]+blenderobject->dloc[2] - ); - eulxyzPrev[0]=blenderobject->rot[0]; - eulxyzPrev[1]=blenderobject->rot[1]; - eulxyzPrev[2]=blenderobject->rot[2]; - - double fps = (double) blenderscene->r.frs_sec/ - (double) blenderscene->r.frs_sec_base; - - tmp.scale(fps, fps, fps); - inivel.push_back(tmp); - tmp=eulxyz-eulxyzPrev; - tmp.scale(fps, fps, fps); - iniang.push_back(tmp); - blenderscene->r.cfra=blenderscene->r.sfra; - //XXX update_for_newframe(); - } - - gameobj->NodeSetLocalPosition(pos); - gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz)); - gameobj->NodeSetLocalScale(scale); - gameobj->NodeUpdateGS(0); - - BL_ConvertMaterialIpos(blenderobject, gameobj, converter); - - sumolist->Add(gameobj->AddRef()); - - BL_ConvertProperties(blenderobject,gameobj,timemgr,kxscene,isInActiveLayer); - - gameobj->SetName(blenderobject->id.name + 2); - - // update children/parent hierarchy - if ((blenderobject->parent != 0)&&(!converter->addInitFromFrame)) - { - // blender has an additional 'parentinverse' offset in each object - SG_Callbacks callback(NULL,NULL,NULL,KX_Scene::KX_ScenegraphUpdateFunc,KX_Scene::KX_ScenegraphRescheduleFunc); - SG_Node* parentinversenode = new SG_Node(NULL,kxscene,callback); - - // define a normal parent relationship for this node. - KX_NormalParentRelation * parent_relation = KX_NormalParentRelation::New(); - parentinversenode->SetParentRelation(parent_relation); - - parentChildLink pclink; - pclink.m_blenderchild = blenderobject; - pclink.m_gamechildnode = parentinversenode; - vec_parent_child.push_back(pclink); - - float* fl = (float*) blenderobject->parentinv; - MT_Transform parinvtrans(fl); - parentinversenode->SetLocalPosition(parinvtrans.getOrigin()); - // problem here: the parent inverse transform combines scaling and rotation - // in the basis but the scenegraph needs separate rotation and scaling. - // This is not important for OpenGL (it uses 4x4 matrix) but it is important - // for the physic engine that needs a separate scaling - //parentinversenode->SetLocalOrientation(parinvtrans.getBasis()); - - // Extract the rotation and the scaling from the basis - MT_Matrix3x3 ori(parinvtrans.getBasis()); - MT_Vector3 x(ori.getColumn(0)); - MT_Vector3 y(ori.getColumn(1)); - MT_Vector3 z(ori.getColumn(2)); - MT_Vector3 parscale(x.length(), y.length(), z.length()); - if (!MT_fuzzyZero(parscale[0])) - x /= parscale[0]; - if (!MT_fuzzyZero(parscale[1])) - y /= parscale[1]; - if (!MT_fuzzyZero(parscale[2])) - z /= parscale[2]; - ori.setColumn(0, x); - ori.setColumn(1, y); - ori.setColumn(2, z); - parentinversenode->SetLocalOrientation(ori); - parentinversenode->SetLocalScale(parscale); - - parentinversenode->AddChild(gameobj->GetSGNode()); + if (addobj) + { /* macro calls object conversion funcs */ + BL_CONVERTBLENDEROBJECT_SINGLE; + + if (gameobj->IsDupliGroup()) { + grouplist.insert(blenderobject->dup_group); + } } - - // needed for python scripting - logicmgr->RegisterGameObjectName(gameobj->GetName(),gameobj); - // needed for group duplication - logicmgr->RegisterGameObj(blenderobject, gameobj); - for (int i = 0; i < gameobj->GetMeshCount(); i++) - logicmgr->RegisterGameMeshName(gameobj->GetMesh(i)->GetName(), blenderobject); - - converter->RegisterGameObject(gameobj, blenderobject); - // this was put in rapidly, needs to be looked at more closely - // only draw/use objects in active 'blender' layers - - logicbrick_conversionlist->Add(gameobj->AddRef()); - - if (converter->addInitFromFrame){ - posPrev=gameobj->NodeGetWorldPosition(); - angor=gameobj->NodeGetWorldOrientation(); - } - if (isInActiveLayer) - { - objectlist->Add(gameobj->AddRef()); - //tf.Add(gameobj->GetSGNode()); - - gameobj->NodeUpdateGS(0); - gameobj->AddMeshUser(); - - } - else - { - //we must store this object otherwise it will be deleted - //at the end of this function if it is not a root object - inactivelist->Add(gameobj->AddRef()); - } - if (gameobj->IsDupliGroup()) - grouplist.insert(blenderobject->dup_group); - if (converter->addInitFromFrame){ - gameobj->NodeSetLocalPosition(posPrev); - gameobj->NodeSetLocalOrientation(angor); - } - - } - /* Note about memory leak issues: - When a CValue derived class is created, m_refcount is initialized to 1 - so the class must be released after being used to make sure that it won't - hang in memory. If the object needs to be stored for a long time, - use AddRef() so that this Release() does not free the object. - Make sure that for any AddRef() there is a Release()!!!! - Do the same for any object derived from CValue, CExpression and NG_NetworkMessage - */ - if (gameobj) + /* Note about memory leak issues: + * When a CValue derived class is created, m_refcount is initialized to 1 + * so the class must be released after being used to make sure that it won't + * hang in memory. If the object needs to be stored for a long time, + * use AddRef() so that this Release() does not free the object. + * Make sure that for any AddRef() there is a Release()!!!! + * Do the same for any object derived from CValue, CExpression and NG_NetworkMessage + */ gameobj->Release(); - + } } if (!grouplist.empty()) @@ -2277,147 +2488,26 @@ if (converter->addInitFromFrame) if (!isInActiveLayer) addobj=false; - - if (gameobj&&addobj) + + if (gameobj) { - MT_Point3 posPrev; - MT_Matrix3x3 angor; - if (converter->addInitFromFrame) - blenderscene->r.cfra=blenderscene->r.sfra; - - MT_Point3 pos( - blenderobject->loc[0]+blenderobject->dloc[0], - blenderobject->loc[1]+blenderobject->dloc[1], - blenderobject->loc[2]+blenderobject->dloc[2] - ); - MT_Vector3 eulxyz(blenderobject->rot); - MT_Vector3 scale(blenderobject->size); - if (converter->addInitFromFrame){//rcruiz - float eulxyzPrev[3]; - blenderscene->r.cfra=blenderscene->r.sfra-1; - //XXX update_for_newframe(); - MT_Vector3 tmp=pos-MT_Point3(blenderobject->loc[0]+blenderobject->dloc[0], - blenderobject->loc[1]+blenderobject->dloc[1], - blenderobject->loc[2]+blenderobject->dloc[2] - ); - eulxyzPrev[0]=blenderobject->rot[0]; - eulxyzPrev[1]=blenderobject->rot[1]; - eulxyzPrev[2]=blenderobject->rot[2]; - - double fps = (double) blenderscene->r.frs_sec/ - (double) blenderscene->r.frs_sec_base; - - tmp.scale(fps, fps, fps); - inivel.push_back(tmp); - tmp=eulxyz-eulxyzPrev; - tmp.scale(fps, fps, fps); - iniang.push_back(tmp); - blenderscene->r.cfra=blenderscene->r.sfra; - //XXX update_for_newframe(); - } - - gameobj->NodeSetLocalPosition(pos); - gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz)); - gameobj->NodeSetLocalScale(scale); - gameobj->NodeUpdateGS(0); - - BL_ConvertMaterialIpos(blenderobject,gameobj, converter); - - sumolist->Add(gameobj->AddRef()); - - BL_ConvertProperties(blenderobject,gameobj,timemgr,kxscene,isInActiveLayer); - - - gameobj->SetName(blenderobject->id.name + 2); - - // update children/parent hierarchy - if ((blenderobject->parent != 0)&&(!converter->addInitFromFrame)) - { - // blender has an additional 'parentinverse' offset in each object - SG_Callbacks callback(NULL,NULL,NULL,KX_Scene::KX_ScenegraphUpdateFunc,KX_Scene::KX_ScenegraphRescheduleFunc); - SG_Node* parentinversenode = new SG_Node(NULL,kxscene,callback); - - // define a normal parent relationship for this node. - KX_NormalParentRelation * parent_relation = KX_NormalParentRelation::New(); - parentinversenode->SetParentRelation(parent_relation); - - parentChildLink pclink; - pclink.m_blenderchild = blenderobject; - pclink.m_gamechildnode = parentinversenode; - vec_parent_child.push_back(pclink); - - float* fl = (float*) blenderobject->parentinv; - MT_Transform parinvtrans(fl); - parentinversenode->SetLocalPosition(parinvtrans.getOrigin()); - - // Extract the rotation and the scaling from the basis - MT_Matrix3x3 ori(parinvtrans.getBasis()); - MT_Vector3 x(ori.getColumn(0)); - MT_Vector3 y(ori.getColumn(1)); - MT_Vector3 z(ori.getColumn(2)); - MT_Vector3 localscale(x.length(), y.length(), z.length()); - if (!MT_fuzzyZero(localscale[0])) - x /= localscale[0]; - if (!MT_fuzzyZero(localscale[1])) - y /= localscale[1]; - if (!MT_fuzzyZero(localscale[2])) - z /= localscale[2]; - ori.setColumn(0, x); - ori.setColumn(1, y); - ori.setColumn(2, z); - parentinversenode->SetLocalOrientation(ori); - parentinversenode->SetLocalScale(localscale); - - parentinversenode->AddChild(gameobj->GetSGNode()); - } - - // needed for python scripting - logicmgr->RegisterGameObjectName(gameobj->GetName(),gameobj); - - // needed for group duplication - logicmgr->RegisterGameObj(blenderobject, gameobj); - for (int i = 0; i < gameobj->GetMeshCount(); i++) - logicmgr->RegisterGameMeshName(gameobj->GetMesh(i)->GetName(), blenderobject); - - converter->RegisterGameObject(gameobj, blenderobject); - // this was put in rapidly, needs to be looked at more closely - // only draw/use objects in active 'blender' layers - - logicbrick_conversionlist->Add(gameobj->AddRef()); - - if (converter->addInitFromFrame){ - posPrev=gameobj->NodeGetWorldPosition(); - angor=gameobj->NodeGetWorldOrientation(); - } - if (isInActiveLayer) - { - objectlist->Add(gameobj->AddRef()); - //tf.Add(gameobj->GetSGNode()); - - gameobj->NodeUpdateGS(0); - gameobj->AddMeshUser(); + if (addobj) + { /* macro calls object conversion funcs */ + BL_CONVERTBLENDEROBJECT_SINGLE; } - else - { - //we must store this object otherwise it will be deleted - //at the end of this function if it is not a root object - inactivelist->Add(gameobj->AddRef()); - } if (gameobj->IsDupliGroup()) { - // check that the group is not already converted if (allgrouplist.insert(blenderobject->dup_group).second) + { grouplist.insert(blenderobject->dup_group); + } } - if (converter->addInitFromFrame){ - gameobj->NodeSetLocalPosition(posPrev); - gameobj->NodeSetLocalOrientation(angor); - } - - } - if (gameobj) + + + /* see comment above re: mem leaks */ gameobj->Release(); + } } } } @@ -2854,3 +2944,8 @@ RAS_BucketManager *bucketmanager = kxscene->GetBucketManager(); bucketmanager->OptimizeBuckets(distance); } + +SCA_IInputDevice::KX_EnumInputs ConvertKeyCode(int key_code) +{ + return gReverseKeyTranslateTable[key_code]; +} diff -Nru blender-2.61/source/gameengine/Converter/BL_BlenderDataConversion.h blender-2.62/source/gameengine/Converter/BL_BlenderDataConversion.h --- blender-2.61/source/gameengine/Converter/BL_BlenderDataConversion.h 2011-12-13 19:46:58.000000000 +0000 +++ blender-2.62/source/gameengine/Converter/BL_BlenderDataConversion.h 2012-02-15 19:31:17.000000000 +0000 @@ -36,6 +36,7 @@ #include "STR_String.h" #include "KX_Python.h" #include "KX_PhysicsEngineEnums.h" +#include "SCA_IInputDevice.h" class RAS_MeshObject* BL_ConvertMesh(struct Mesh* mesh,struct Object* lightobj,class KX_Scene* scene, class KX_BlenderSceneConverter *converter); @@ -49,5 +50,7 @@ bool alwaysUseExpandFraming ); +SCA_IInputDevice::KX_EnumInputs ConvertKeyCode(int key_code); + #endif // __BLENDER_CONVERT diff -Nru blender-2.61/source/gameengine/Converter/BL_ShapeActionActuator.cpp blender-2.62/source/gameengine/Converter/BL_ShapeActionActuator.cpp --- blender-2.61/source/gameengine/Converter/BL_ShapeActionActuator.cpp 2011-12-13 19:46:58.000000000 +0000 +++ blender-2.62/source/gameengine/Converter/BL_ShapeActionActuator.cpp 2012-02-15 19:31:17.000000000 +0000 @@ -519,8 +519,8 @@ KX_PYATTRIBUTE_RW_FUNCTION("action", BL_ShapeActionActuator, pyattr_get_action, pyattr_set_action), KX_PYATTRIBUTE_SHORT_RW("priority", 0, 100, false, BL_ShapeActionActuator, m_priority), KX_PYATTRIBUTE_FLOAT_RW_CHECK("frame", 0, MAXFRAMEF, BL_ShapeActionActuator, m_localtime, CheckFrame), - KX_PYATTRIBUTE_STRING_RW("propName", 0, 31, false, BL_ShapeActionActuator, m_propname), - KX_PYATTRIBUTE_STRING_RW("framePropName", 0, 31, false, BL_ShapeActionActuator, m_framepropname), + KX_PYATTRIBUTE_STRING_RW("propName", 0, MAX_PROP_NAME, false, BL_ShapeActionActuator, m_propname), + KX_PYATTRIBUTE_STRING_RW("framePropName", 0, MAX_PROP_NAME, false, BL_ShapeActionActuator, m_framepropname), KX_PYATTRIBUTE_FLOAT_RW_CHECK("blendTime", 0, MAXFRAMEF, BL_ShapeActionActuator, m_blendframe, CheckBlendTime), KX_PYATTRIBUTE_SHORT_RW_CHECK("mode",0,100,false,BL_ShapeActionActuator,m_playtype,CheckType), { NULL } //Sentinel diff -Nru blender-2.61/source/gameengine/Converter/BL_ShapeDeformer.cpp blender-2.62/source/gameengine/Converter/BL_ShapeDeformer.cpp --- blender-2.61/source/gameengine/Converter/BL_ShapeDeformer.cpp 2011-12-13 19:46:58.000000000 +0000 +++ blender-2.62/source/gameengine/Converter/BL_ShapeDeformer.cpp 2012-02-15 19:31:17.000000000 +0000 @@ -50,6 +50,8 @@ #include "DNA_meshdata_types.h" #include "BKE_armature.h" #include "BKE_action.h" +#include "BKE_global.h" +#include "BKE_main.h" #include "BKE_key.h" #include "BKE_ipo.h" #include "MT_Point3.h" @@ -97,10 +99,13 @@ BL_ShapeDeformer::~BL_ShapeDeformer() { - if (m_key && m_bmesh->key) + if (m_key && m_bmesh->key && m_key != m_bmesh->key) { free_key(m_bmesh->key); + BLI_remlink_safe(&G.main->key, m_bmesh->key); + MEM_freeN(m_bmesh->key); m_bmesh->key = m_key; + m_key = NULL; } }; diff -Nru blender-2.61/source/gameengine/Converter/BL_SkinDeformer.cpp blender-2.62/source/gameengine/Converter/BL_SkinDeformer.cpp --- blender-2.61/source/gameengine/Converter/BL_SkinDeformer.cpp 2011-12-13 19:46:58.000000000 +0000 +++ blender-2.62/source/gameengine/Converter/BL_SkinDeformer.cpp 2012-02-15 19:31:17.000000000 +0000 @@ -237,12 +237,12 @@ } } + MDeformVert *dv= dverts; - for (int i=0; itotvert; ++i) + for (int i=0; itotvert; ++i, dv++) { float contrib = 0.f, weight, max_weight=0.f; bPoseChannel *pchan=NULL; - MDeformVert *dvert; Eigen::Map norm(m_transnors[i]); Eigen::Vector4f vec(0, 0, 0, 1); Eigen::Matrix4f norm_chan_mat; @@ -251,18 +251,18 @@ m_transverts[i][2], 1.f); - dvert = dverts+i; - - if (!dvert->totweight) + if (!dv->totweight) continue; - for (int j=0; jtotweight; ++j) + MDeformWeight *dw= dv->dw; + + for (unsigned int j= dv->totweight; j != 0; j--, dw++) { - int index = dvert->dw[j].def_nr; + const int index = dw->def_nr; if (index < defbase_tot && (pchan=m_dfnrToPC[index])) { - weight = dvert->dw[j].weight; + weight = dw->weight; if (weight) { diff -Nru blender-2.61/source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp blender-2.62/source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp --- blender-2.61/source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp 2011-12-13 19:46:58.000000000 +0000 +++ blender-2.62/source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp 2012-02-15 19:31:17.000000000 +0000 @@ -66,7 +66,8 @@ } } -KX_IScalarInterpolator *BL_InterpolatorList::GetScalarInterpolator(const char *rna_path, int array_index) { +KX_IScalarInterpolator *BL_InterpolatorList::GetScalarInterpolator(const char *rna_path, int array_index) +{ for(BL_InterpolatorList::iterator i = begin(); (i != end()) ; i++ ) { FCurve *fcu= (static_cast(*i))->GetFCurve(); diff -Nru blender-2.61/source/gameengine/Converter/KX_BlenderSceneConverter.cpp blender-2.62/source/gameengine/Converter/KX_BlenderSceneConverter.cpp --- blender-2.61/source/gameengine/Converter/KX_BlenderSceneConverter.cpp 2011-12-13 19:46:58.000000000 +0000 +++ blender-2.62/source/gameengine/Converter/KX_BlenderSceneConverter.cpp 2012-02-15 19:31:17.000000000 +0000 @@ -703,8 +703,8 @@ } -void KX_BlenderSceneConverter::resetNoneDynamicObjectToIpo(){ - +void KX_BlenderSceneConverter::resetNoneDynamicObjectToIpo() +{ if (addInitFromFrame){ KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes(); int numScenes = scenes->size(); @@ -888,11 +888,11 @@ { //KX_IPhysicsController* physCtrl = gameObj->GetPhysicsController(); +#if 0 Object* blenderObject = gameObj->GetBlenderObject(); if (blenderObject && blenderObject->ipo) { // XXX animato -#if 0 Ipo* ipo = blenderObject->ipo; //create the curves, if not existing @@ -903,17 +903,11 @@ testhandles_ipocurve(findIpoCurve((IpoCurve *)ipo->curve.first,"RotX")); testhandles_ipocurve(findIpoCurve((IpoCurve *)ipo->curve.first,"RotY")); testhandles_ipocurve(findIpoCurve((IpoCurve *)ipo->curve.first,"RotZ")); -#endif } +#endif } - } - - } - - - } #ifdef WITH_PYTHON diff -Nru blender-2.61/source/gameengine/Converter/KX_ConvertActuators.cpp blender-2.62/source/gameengine/Converter/KX_ConvertActuators.cpp --- blender-2.61/source/gameengine/Converter/KX_ConvertActuators.cpp 2011-12-13 19:46:58.000000000 +0000 +++ blender-2.62/source/gameengine/Converter/KX_ConvertActuators.cpp 2012-02-15 19:31:17.000000000 +0000 @@ -83,7 +83,7 @@ #include "BLI_blenlib.h" #include "BLI_math_base.h" -#define FILE_MAX 240 // repeated here to avoid dependency from BKE_utildefines.h +#define FILE_MAX 1024 // repeated here to avoid dependency from BKE_utildefines.h #include "KX_NetworkMessageActuator.h" @@ -300,7 +300,7 @@ camact->height, camact->min, camact->max, - camact->axis=='x', + camact->axis, camact->damping); baseact = tmpcamact; } diff -Nru blender-2.61/source/gameengine/Converter/KX_ConvertProperties.cpp blender-2.62/source/gameengine/Converter/KX_ConvertProperties.cpp --- blender-2.61/source/gameengine/Converter/KX_ConvertProperties.cpp 2011-12-13 19:46:58.000000000 +0000 +++ blender-2.62/source/gameengine/Converter/KX_ConvertProperties.cpp 2012-02-15 19:31:17.000000000 +0000 @@ -48,11 +48,21 @@ #include "SCA_TimeEventManager.h" #include "SCA_IScene.h" +#include "KX_FontObject.h" +#include "DNA_curve_types.h" + /* This little block needed for linking to Blender... */ #ifdef WIN32 #include "BLI_winstuff.h" #endif +extern "C" { + #include "BKE_property.h" +} + +/* prototype */ +void BL_ConvertTextProperty(Object* object, KX_FontObject* fontobj,SCA_TimeEventManager* timemgr,SCA_IScene* scene, bool isInActiveLayer); + void BL_ConvertProperties(Object* object,KX_GameObject* gameobj,SCA_TimeEventManager* timemgr,SCA_IScene* scene, bool isInActiveLayer) { @@ -155,4 +165,80 @@ // reserve name for object state scene->AddDebugProperty(gameobj,STR_String("__state__")); } + + /* Font Objects need to 'copy' the Font Object data body to ["Text"] */ + if (object->type == OB_FONT) + { + BL_ConvertTextProperty(object, (KX_FontObject *)gameobj, timemgr, scene, isInActiveLayer); + } } + +void BL_ConvertTextProperty(Object* object, KX_FontObject* fontobj,SCA_TimeEventManager* timemgr,SCA_IScene* scene, bool isInActiveLayer) +{ + CValue* tprop = fontobj->GetProperty("Text"); + if(!tprop) return; + bProperty* prop = get_ob_property(object, "Text"); + if(!prop) return; + + Curve *curve = static_cast(object->data); + STR_String str = curve->str; + CValue* propval = NULL; + + switch(prop->type) { + case GPROP_BOOL: + { + int value = atoi(str); + propval = new CBoolValue((bool)(value != 0)); + tprop->SetValue(propval); + break; + } + case GPROP_INT: + { + int value = atoi(str); + propval = new CIntValue(value); + tprop->SetValue(propval); + break; + } + case GPROP_FLOAT: + { + float floatprop = atof(str); + propval = new CFloatValue(floatprop); + tprop->SetValue(propval); + break; + } + case GPROP_STRING: + { + propval = new CStringValue(str, ""); + tprop->SetValue(propval); + break; + } + case GPROP_TIME: + { + float floatprop = atof(str); + + CValue* timeval = new CFloatValue(floatprop); + // set a subproperty called 'timer' so that + // we can register the replica of this property + // at the time a game object is replicated (AddObjectActuator triggers this) + CValue *bval = new CBoolValue(true); + timeval->SetProperty("timer",bval); + bval->Release(); + if (isInActiveLayer) + { + timemgr->AddTimeProperty(timeval); + } + + propval = timeval; + tprop->SetValue(timeval); + } + default: + { + // todo make an assert etc. + } + } + + if (propval) { + propval->Release(); + } +} + diff -Nru blender-2.61/source/gameengine/Converter/KX_ConvertSensors.cpp blender-2.62/source/gameengine/Converter/KX_ConvertSensors.cpp --- blender-2.61/source/gameengine/Converter/KX_ConvertSensors.cpp 2011-12-13 19:46:58.000000000 +0000 +++ blender-2.62/source/gameengine/Converter/KX_ConvertSensors.cpp 2012-02-15 19:31:17.000000000 +0000 @@ -86,10 +86,7 @@ #include "KX_KetsjiEngine.h" #include "KX_BlenderSceneConverter.h" - -// this map is Blender specific: a conversion between blender and ketsji enums -std::map gReverseKeyTranslateTable; - +#include "BL_BlenderDataConversion.h" void BL_ConvertSensors(struct Object* blenderobject, class KX_GameObject* gameobj, @@ -102,177 +99,6 @@ KX_BlenderSceneConverter* converter ) { - static bool reverseTableConverted = false; - - if (!reverseTableConverted) - { - reverseTableConverted = true; - - /* The reverse table. In order to not confuse ourselves, we */ - /* immediately convert all events that come in to KX codes. */ - gReverseKeyTranslateTable[LEFTMOUSE ] = SCA_IInputDevice::KX_LEFTMOUSE; - gReverseKeyTranslateTable[MIDDLEMOUSE ] = SCA_IInputDevice::KX_MIDDLEMOUSE; - gReverseKeyTranslateTable[RIGHTMOUSE ] = SCA_IInputDevice::KX_RIGHTMOUSE; - gReverseKeyTranslateTable[WHEELUPMOUSE ] = SCA_IInputDevice::KX_WHEELUPMOUSE; - gReverseKeyTranslateTable[WHEELDOWNMOUSE ] = SCA_IInputDevice::KX_WHEELDOWNMOUSE; - gReverseKeyTranslateTable[MOUSEX ] = SCA_IInputDevice::KX_MOUSEX; - gReverseKeyTranslateTable[MOUSEY ] = SCA_IInputDevice::KX_MOUSEY; - - // TIMERS - - gReverseKeyTranslateTable[TIMER0 ] = SCA_IInputDevice::KX_TIMER0; - gReverseKeyTranslateTable[TIMER1 ] = SCA_IInputDevice::KX_TIMER1; - gReverseKeyTranslateTable[TIMER2 ] = SCA_IInputDevice::KX_TIMER2; - - // SYSTEM - -#if 0 - /* **** XXX **** */ - gReverseKeyTranslateTable[KEYBD ] = SCA_IInputDevice::KX_KEYBD; - gReverseKeyTranslateTable[RAWKEYBD ] = SCA_IInputDevice::KX_RAWKEYBD; - gReverseKeyTranslateTable[REDRAW ] = SCA_IInputDevice::KX_REDRAW; - gReverseKeyTranslateTable[INPUTCHANGE ] = SCA_IInputDevice::KX_INPUTCHANGE; - gReverseKeyTranslateTable[QFULL ] = SCA_IInputDevice::KX_QFULL; - gReverseKeyTranslateTable[WINFREEZE ] = SCA_IInputDevice::KX_WINFREEZE; - gReverseKeyTranslateTable[WINTHAW ] = SCA_IInputDevice::KX_WINTHAW; - gReverseKeyTranslateTable[WINCLOSE ] = SCA_IInputDevice::KX_WINCLOSE; - gReverseKeyTranslateTable[WINQUIT ] = SCA_IInputDevice::KX_WINQUIT; - gReverseKeyTranslateTable[Q_FIRSTTIME ] = SCA_IInputDevice::KX_Q_FIRSTTIME; - /* **** XXX **** */ -#endif - - // standard keyboard - - gReverseKeyTranslateTable[AKEY ] = SCA_IInputDevice::KX_AKEY; - gReverseKeyTranslateTable[BKEY ] = SCA_IInputDevice::KX_BKEY; - gReverseKeyTranslateTable[CKEY ] = SCA_IInputDevice::KX_CKEY; - gReverseKeyTranslateTable[DKEY ] = SCA_IInputDevice::KX_DKEY; - gReverseKeyTranslateTable[EKEY ] = SCA_IInputDevice::KX_EKEY; - gReverseKeyTranslateTable[FKEY ] = SCA_IInputDevice::KX_FKEY; - gReverseKeyTranslateTable[GKEY ] = SCA_IInputDevice::KX_GKEY; - -//XXX clean up -#ifdef WIN32 -#define HKEY 'h' -#endif - gReverseKeyTranslateTable[HKEY ] = SCA_IInputDevice::KX_HKEY; -//XXX clean up -#ifdef WIN32 -#undef HKEY -#endif - - gReverseKeyTranslateTable[IKEY ] = SCA_IInputDevice::KX_IKEY; - gReverseKeyTranslateTable[JKEY ] = SCA_IInputDevice::KX_JKEY; - gReverseKeyTranslateTable[KKEY ] = SCA_IInputDevice::KX_KKEY; - gReverseKeyTranslateTable[LKEY ] = SCA_IInputDevice::KX_LKEY; - gReverseKeyTranslateTable[MKEY ] = SCA_IInputDevice::KX_MKEY; - gReverseKeyTranslateTable[NKEY ] = SCA_IInputDevice::KX_NKEY; - gReverseKeyTranslateTable[OKEY ] = SCA_IInputDevice::KX_OKEY; - gReverseKeyTranslateTable[PKEY ] = SCA_IInputDevice::KX_PKEY; - gReverseKeyTranslateTable[QKEY ] = SCA_IInputDevice::KX_QKEY; - gReverseKeyTranslateTable[RKEY ] = SCA_IInputDevice::KX_RKEY; - gReverseKeyTranslateTable[SKEY ] = SCA_IInputDevice::KX_SKEY; - gReverseKeyTranslateTable[TKEY ] = SCA_IInputDevice::KX_TKEY; - gReverseKeyTranslateTable[UKEY ] = SCA_IInputDevice::KX_UKEY; - gReverseKeyTranslateTable[VKEY ] = SCA_IInputDevice::KX_VKEY; - gReverseKeyTranslateTable[WKEY ] = SCA_IInputDevice::KX_WKEY; - gReverseKeyTranslateTable[XKEY ] = SCA_IInputDevice::KX_XKEY; - gReverseKeyTranslateTable[YKEY ] = SCA_IInputDevice::KX_YKEY; - gReverseKeyTranslateTable[ZKEY ] = SCA_IInputDevice::KX_ZKEY; - - gReverseKeyTranslateTable[ZEROKEY ] = SCA_IInputDevice::KX_ZEROKEY; - gReverseKeyTranslateTable[ONEKEY ] = SCA_IInputDevice::KX_ONEKEY; - gReverseKeyTranslateTable[TWOKEY ] = SCA_IInputDevice::KX_TWOKEY; - gReverseKeyTranslateTable[THREEKEY ] = SCA_IInputDevice::KX_THREEKEY; - gReverseKeyTranslateTable[FOURKEY ] = SCA_IInputDevice::KX_FOURKEY; - gReverseKeyTranslateTable[FIVEKEY ] = SCA_IInputDevice::KX_FIVEKEY; - gReverseKeyTranslateTable[SIXKEY ] = SCA_IInputDevice::KX_SIXKEY; - gReverseKeyTranslateTable[SEVENKEY ] = SCA_IInputDevice::KX_SEVENKEY; - gReverseKeyTranslateTable[EIGHTKEY ] = SCA_IInputDevice::KX_EIGHTKEY; - gReverseKeyTranslateTable[NINEKEY ] = SCA_IInputDevice::KX_NINEKEY; - - gReverseKeyTranslateTable[CAPSLOCKKEY ] = SCA_IInputDevice::KX_CAPSLOCKKEY; - - gReverseKeyTranslateTable[LEFTCTRLKEY ] = SCA_IInputDevice::KX_LEFTCTRLKEY; - gReverseKeyTranslateTable[LEFTALTKEY ] = SCA_IInputDevice::KX_LEFTALTKEY; - gReverseKeyTranslateTable[RIGHTALTKEY ] = SCA_IInputDevice::KX_RIGHTALTKEY; - gReverseKeyTranslateTable[RIGHTCTRLKEY ] = SCA_IInputDevice::KX_RIGHTCTRLKEY; - gReverseKeyTranslateTable[RIGHTSHIFTKEY ] = SCA_IInputDevice::KX_RIGHTSHIFTKEY; - gReverseKeyTranslateTable[LEFTSHIFTKEY ] = SCA_IInputDevice::KX_LEFTSHIFTKEY; - - gReverseKeyTranslateTable[ESCKEY ] = SCA_IInputDevice::KX_ESCKEY; - gReverseKeyTranslateTable[TABKEY ] = SCA_IInputDevice::KX_TABKEY; - gReverseKeyTranslateTable[RETKEY ] = SCA_IInputDevice::KX_RETKEY; - gReverseKeyTranslateTable[SPACEKEY ] = SCA_IInputDevice::KX_SPACEKEY; - gReverseKeyTranslateTable[LINEFEEDKEY ] = SCA_IInputDevice::KX_LINEFEEDKEY; - gReverseKeyTranslateTable[BACKSPACEKEY ] = SCA_IInputDevice::KX_BACKSPACEKEY; - gReverseKeyTranslateTable[DELKEY ] = SCA_IInputDevice::KX_DELKEY; - gReverseKeyTranslateTable[SEMICOLONKEY ] = SCA_IInputDevice::KX_SEMICOLONKEY; - gReverseKeyTranslateTable[PERIODKEY ] = SCA_IInputDevice::KX_PERIODKEY; - gReverseKeyTranslateTable[COMMAKEY ] = SCA_IInputDevice::KX_COMMAKEY; - gReverseKeyTranslateTable[QUOTEKEY ] = SCA_IInputDevice::KX_QUOTEKEY; - gReverseKeyTranslateTable[ACCENTGRAVEKEY ] = SCA_IInputDevice::KX_ACCENTGRAVEKEY; - gReverseKeyTranslateTable[MINUSKEY ] = SCA_IInputDevice::KX_MINUSKEY; - gReverseKeyTranslateTable[SLASHKEY ] = SCA_IInputDevice::KX_SLASHKEY; - gReverseKeyTranslateTable[BACKSLASHKEY ] = SCA_IInputDevice::KX_BACKSLASHKEY; - gReverseKeyTranslateTable[EQUALKEY ] = SCA_IInputDevice::KX_EQUALKEY; - gReverseKeyTranslateTable[LEFTBRACKETKEY ] = SCA_IInputDevice::KX_LEFTBRACKETKEY; - gReverseKeyTranslateTable[RIGHTBRACKETKEY ] = SCA_IInputDevice::KX_RIGHTBRACKETKEY; - - gReverseKeyTranslateTable[LEFTARROWKEY ] = SCA_IInputDevice::KX_LEFTARROWKEY; - gReverseKeyTranslateTable[DOWNARROWKEY ] = SCA_IInputDevice::KX_DOWNARROWKEY; - gReverseKeyTranslateTable[RIGHTARROWKEY ] = SCA_IInputDevice::KX_RIGHTARROWKEY; - gReverseKeyTranslateTable[UPARROWKEY ] = SCA_IInputDevice::KX_UPARROWKEY; - - gReverseKeyTranslateTable[PAD2 ] = SCA_IInputDevice::KX_PAD2; - gReverseKeyTranslateTable[PAD4 ] = SCA_IInputDevice::KX_PAD4; - gReverseKeyTranslateTable[PAD6 ] = SCA_IInputDevice::KX_PAD6; - gReverseKeyTranslateTable[PAD8 ] = SCA_IInputDevice::KX_PAD8; - - gReverseKeyTranslateTable[PAD1 ] = SCA_IInputDevice::KX_PAD1; - gReverseKeyTranslateTable[PAD3 ] = SCA_IInputDevice::KX_PAD3; - gReverseKeyTranslateTable[PAD5 ] = SCA_IInputDevice::KX_PAD5; - gReverseKeyTranslateTable[PAD7 ] = SCA_IInputDevice::KX_PAD7; - gReverseKeyTranslateTable[PAD9 ] = SCA_IInputDevice::KX_PAD9; - - gReverseKeyTranslateTable[PADPERIOD ] = SCA_IInputDevice::KX_PADPERIOD; - gReverseKeyTranslateTable[PADSLASHKEY ] = SCA_IInputDevice::KX_PADSLASHKEY; - gReverseKeyTranslateTable[PADASTERKEY ] = SCA_IInputDevice::KX_PADASTERKEY; - - gReverseKeyTranslateTable[PAD0 ] = SCA_IInputDevice::KX_PAD0; - gReverseKeyTranslateTable[PADMINUS ] = SCA_IInputDevice::KX_PADMINUS; - gReverseKeyTranslateTable[PADENTER ] = SCA_IInputDevice::KX_PADENTER; - gReverseKeyTranslateTable[PADPLUSKEY ] = SCA_IInputDevice::KX_PADPLUSKEY; - - - gReverseKeyTranslateTable[F1KEY ] = SCA_IInputDevice::KX_F1KEY; - gReverseKeyTranslateTable[F2KEY ] = SCA_IInputDevice::KX_F2KEY; - gReverseKeyTranslateTable[F3KEY ] = SCA_IInputDevice::KX_F3KEY; - gReverseKeyTranslateTable[F4KEY ] = SCA_IInputDevice::KX_F4KEY; - gReverseKeyTranslateTable[F5KEY ] = SCA_IInputDevice::KX_F5KEY; - gReverseKeyTranslateTable[F6KEY ] = SCA_IInputDevice::KX_F6KEY; - gReverseKeyTranslateTable[F7KEY ] = SCA_IInputDevice::KX_F7KEY; - gReverseKeyTranslateTable[F8KEY ] = SCA_IInputDevice::KX_F8KEY; - gReverseKeyTranslateTable[F9KEY ] = SCA_IInputDevice::KX_F9KEY; - gReverseKeyTranslateTable[F10KEY ] = SCA_IInputDevice::KX_F10KEY; - gReverseKeyTranslateTable[F11KEY ] = SCA_IInputDevice::KX_F11KEY; - gReverseKeyTranslateTable[F12KEY ] = SCA_IInputDevice::KX_F12KEY; - gReverseKeyTranslateTable[F13KEY ] = SCA_IInputDevice::KX_F13KEY; - gReverseKeyTranslateTable[F14KEY ] = SCA_IInputDevice::KX_F14KEY; - gReverseKeyTranslateTable[F15KEY ] = SCA_IInputDevice::KX_F15KEY; - gReverseKeyTranslateTable[F16KEY ] = SCA_IInputDevice::KX_F16KEY; - gReverseKeyTranslateTable[F17KEY ] = SCA_IInputDevice::KX_F17KEY; - gReverseKeyTranslateTable[F18KEY ] = SCA_IInputDevice::KX_F18KEY; - gReverseKeyTranslateTable[F19KEY ] = SCA_IInputDevice::KX_F19KEY; - - - gReverseKeyTranslateTable[PAUSEKEY ] = SCA_IInputDevice::KX_PAUSEKEY; - gReverseKeyTranslateTable[INSERTKEY ] = SCA_IInputDevice::KX_INSERTKEY; - gReverseKeyTranslateTable[HOMEKEY ] = SCA_IInputDevice::KX_HOMEKEY; - gReverseKeyTranslateTable[PAGEUPKEY ] = SCA_IInputDevice::KX_PAGEUPKEY; - gReverseKeyTranslateTable[PAGEDOWNKEY ] = SCA_IInputDevice::KX_PAGEDOWNKEY; - gReverseKeyTranslateTable[ENDKEY ] = SCA_IInputDevice::KX_ENDKEY; - } int executePriority = 0; int uniqueint = 0; @@ -470,9 +296,9 @@ if (eventmgr) { gamesensor = new SCA_KeyboardSensor(eventmgr, - gReverseKeyTranslateTable[blenderkeybdsensor->key], - gReverseKeyTranslateTable[blenderkeybdsensor->qual], - gReverseKeyTranslateTable[blenderkeybdsensor->qual2], + ConvertKeyCode(blenderkeybdsensor->key), + ConvertKeyCode(blenderkeybdsensor->qual), + ConvertKeyCode(blenderkeybdsensor->qual2), (blenderkeybdsensor->type == SENS_ALL_KEYS), blenderkeybdsensor->targetName, blenderkeybdsensor->toggleName, diff -Nru blender-2.61/source/gameengine/Converter/KX_IpoConvert.cpp blender-2.62/source/gameengine/Converter/KX_IpoConvert.cpp --- blender-2.61/source/gameengine/Converter/KX_IpoConvert.cpp 2011-12-13 19:46:58.000000000 +0000 +++ blender-2.62/source/gameengine/Converter/KX_IpoConvert.cpp 2012-02-15 19:31:17.000000000 +0000 @@ -72,7 +72,8 @@ #include "STR_HashedString.h" -static BL_InterpolatorList *GetAdtList(struct bAction *for_act, KX_BlenderSceneConverter *converter) { +static BL_InterpolatorList *GetAdtList(struct bAction *for_act, KX_BlenderSceneConverter *converter) +{ BL_InterpolatorList *adtList= converter->FindInterpolatorList(for_act); if (!adtList) { diff -Nru blender-2.61/source/gameengine/Expressions/InputParser.cpp blender-2.62/source/gameengine/Expressions/InputParser.cpp --- blender-2.61/source/gameengine/Expressions/InputParser.cpp 2011-12-13 19:46:22.000000000 +0000 +++ blender-2.62/source/gameengine/Expressions/InputParser.cpp 2012-02-15 19:30:44.000000000 +0000 @@ -346,7 +346,8 @@ } #if 0 -int CParser::MakeInt() { +int CParser::MakeInt() +{ // returns the integer representation of the value in the global // variable const_as_string // pre: const_as_string contains only numercal chars @@ -354,7 +355,8 @@ } #endif -STR_String CParser::Symbol2Str(int s) { +STR_String CParser::Symbol2Str(int s) +{ // returns a string representation of of symbol s, // for use in Term when generating an error switch(s) { @@ -373,7 +375,8 @@ } } -void CParser::Term(int s) { +void CParser::Term(int s) +{ // generates an error if the next symbol isn't the specified symbol s // otherwise, skip the symbol if(s == sym) NextSym(); @@ -387,7 +390,8 @@ } } -int CParser::Priority(int optorkind) { +int CParser::Priority(int optorkind) +{ // returns the priority of an operator // higher number means higher priority switch(optorkind) { @@ -409,7 +413,8 @@ return 0; // should not happen } -CExpression *CParser::Ex(int i) { +CExpression *CParser::Ex(int i) +{ // parses an expression in the imput, starting at priority i, and // returns an CExpression, containing the parsed input CExpression *e1 = NULL, *e2 = NULL; @@ -551,7 +556,8 @@ return e1; } -CExpression *CParser::Expr() { +CExpression *CParser::Expr() +{ // parses an expression in the imput, and // returns an CExpression, containing the parsed input return Ex(1); diff -Nru blender-2.61/source/gameengine/Expressions/Operator1Expr.cpp blender-2.62/source/gameengine/Expressions/Operator1Expr.cpp --- blender-2.61/source/gameengine/Expressions/Operator1Expr.cpp 2011-12-13 19:46:22.000000000 +0000 +++ blender-2.62/source/gameengine/Expressions/Operator1Expr.cpp 2012-02-15 19:30:44.000000000 +0000 @@ -98,10 +98,9 @@ } */ -bool COperator1Expr::NeedsRecalculated() { - +bool COperator1Expr::NeedsRecalculated() +{ return m_lhs->NeedsRecalculated(); - } CExpression* COperator1Expr::CheckLink(std::vector& brokenlinks) { diff -Nru blender-2.61/source/gameengine/Expressions/Operator2Expr.cpp blender-2.62/source/gameengine/Expressions/Operator2Expr.cpp --- blender-2.61/source/gameengine/Expressions/Operator2Expr.cpp 2011-12-13 19:46:22.000000000 +0000 +++ blender-2.62/source/gameengine/Expressions/Operator2Expr.cpp 2012-02-15 19:30:44.000000000 +0000 @@ -168,17 +168,18 @@ -bool COperator2Expr::IsRightInside(float x, float y, float z,bool bBorderInclude) { - +bool COperator2Expr::IsRightInside(float x, float y, float z,bool bBorderInclude) +{ return m_rhs->IsInside(x,y,z,bBorderInclude) ; - } -bool COperator2Expr::IsLeftInside(float x, float y, float z,bool bBorderInclude) { +bool COperator2Expr::IsLeftInside(float x, float y, float z,bool bBorderInclude) +{ return m_lhs->IsInside(x,y,z,bBorderInclude); } */ -bool COperator2Expr::NeedsRecalculated() { +bool COperator2Expr::NeedsRecalculated() +{ // added some lines, just for debugging purposes, it could be a one-liner :) //bool modleft //bool modright; diff -Nru blender-2.61/source/gameengine/Expressions/PyObjectPlus.h blender-2.62/source/gameengine/Expressions/PyObjectPlus.h --- blender-2.61/source/gameengine/Expressions/PyObjectPlus.h 2011-12-13 19:46:22.000000000 +0000 +++ blender-2.62/source/gameengine/Expressions/PyObjectPlus.h 2012-02-15 19:30:44.000000000 +0000 @@ -54,7 +54,10 @@ } #endif -static inline void Py_Fatal(const char *M) { +#define MAX_PROP_NAME 64 + +static inline void Py_Fatal(const char *M) +{ fprintf(stderr, "%s\n", M); exit(-1); }; diff -Nru blender-2.61/source/gameengine/Expressions/StringValue.h blender-2.62/source/gameengine/Expressions/StringValue.h --- blender-2.61/source/gameengine/Expressions/StringValue.h 2011-12-13 19:46:22.000000000 +0000 +++ blender-2.62/source/gameengine/Expressions/StringValue.h 2012-02-15 19:30:44.000000000 +0000 @@ -43,7 +43,7 @@ virtual CValue* GetReplica(); #ifdef WITH_PYTHON virtual PyObject* ConvertValueToPython() { - return PyUnicode_FromString(m_strString.Ptr()); + return PyUnicode_From_STR_String(m_strString); } #endif // WITH_PYTHON diff -Nru blender-2.61/source/gameengine/Expressions/Value.cpp blender-2.62/source/gameengine/Expressions/Value.cpp --- blender-2.61/source/gameengine/Expressions/Value.cpp 2011-12-13 19:46:22.000000000 +0000 +++ blender-2.62/source/gameengine/Expressions/Value.cpp 2012-02-15 19:30:44.000000000 +0000 @@ -530,7 +530,8 @@ { NULL } //Sentinel }; -PyObject * CValue::pyattr_get_name(void * self_v, const KX_PYATTRIBUTE_DEF * attrdef) { +PyObject * CValue::pyattr_get_name(void * self_v, const KX_PYATTRIBUTE_DEF * attrdef) +{ CValue * self = static_cast (self_v); return PyUnicode_From_STR_String(self->GetName()); } diff -Nru blender-2.61/source/gameengine/Expressions/Value.h blender-2.62/source/gameengine/Expressions/Value.h --- blender-2.61/source/gameengine/Expressions/Value.h 2011-12-13 19:46:22.000000000 +0000 +++ blender-2.62/source/gameengine/Expressions/Value.h 2012-02-15 19:30:44.000000000 +0000 @@ -221,7 +221,7 @@ //static PyObject* PyMake(PyObject*,PyObject*); virtual PyObject *py_repr(void) { - return PyUnicode_FromString((const char*)GetText()); + return PyUnicode_From_STR_String(GetText()); } virtual PyObject* ConvertValueToPython() { diff -Nru blender-2.61/source/gameengine/GameLogic/CMakeLists.txt blender-2.62/source/gameengine/GameLogic/CMakeLists.txt --- blender-2.61/source/gameengine/GameLogic/CMakeLists.txt 2011-12-13 19:47:07.000000000 +0000 +++ blender-2.62/source/gameengine/GameLogic/CMakeLists.txt 2012-02-15 19:31:27.000000000 +0000 @@ -132,6 +132,10 @@ ) add_definitions(-DWITH_SDL) + + if(WITH_GHOST_SDL) + add_definitions(-DWITH_GHOST_SDL) + endif() endif() blender_add_lib(ge_logic "${SRC}" "${INC}" "${INC_SYS}") diff -Nru blender-2.61/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp blender-2.62/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp --- blender-2.61/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp 2011-12-13 19:47:00.000000000 +0000 +++ blender-2.62/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp 2012-02-15 19:31:18.000000000 +0000 @@ -88,8 +88,14 @@ if (m_refCount == 0) { int i; - // do this once only + // The video subsystem is required for joystick input to work. However, + // when GHOST is running under SDL, video is initialised elsewhere. + // Do this once only. +# ifdef WITH_GHOST_SDL + if(SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1 ){ +# else if(SDL_InitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO) == -1 ){ +# endif echo("Error-Initializing-SDL: " << SDL_GetError()); return NULL; } @@ -124,7 +130,14 @@ m_instance[i]= NULL; } + // The video subsystem is required for joystick input to work. However, + // when GHOST is running under SDL, video is freed elsewhere. + // Do this once only. +# ifdef WITH_GHOST_SDL + SDL_QuitSubSystem(SDL_INIT_JOYSTICK); +# else SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO); +# endif #endif /* WITH_SDL */ } } diff -Nru blender-2.61/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp blender-2.62/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp --- blender-2.61/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp 2011-12-13 19:47:07.000000000 +0000 +++ blender-2.62/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp 2012-02-15 19:31:27.000000000 +0000 @@ -150,7 +150,7 @@ }; PyAttributeDef SCA_ActuatorSensor::Attributes[] = { - KX_PYATTRIBUTE_STRING_RW_CHECK("actuator",0,100,false,SCA_ActuatorSensor,m_checkactname,CheckActuator), + KX_PYATTRIBUTE_STRING_RW_CHECK("actuator",0,MAX_PROP_NAME,false,SCA_ActuatorSensor,m_checkactname,CheckActuator), { NULL } //Sentinel }; diff -Nru blender-2.61/source/gameengine/GameLogic/SCA_ILogicBrick.h blender-2.62/source/gameengine/GameLogic/SCA_ILogicBrick.h --- blender-2.61/source/gameengine/GameLogic/SCA_ILogicBrick.h 2011-12-13 19:47:07.000000000 +0000 +++ blender-2.62/source/gameengine/GameLogic/SCA_ILogicBrick.h 2012-02-15 19:31:27.000000000 +0000 @@ -133,8 +133,8 @@ /* for moving logic bricks between scenes */ - virtual void Replace_IScene(SCA_IScene *val) {}; - virtual void Replace_NetworkScene(NG_NetworkScene *val) {}; + virtual void Replace_IScene(SCA_IScene *val) {} + virtual void Replace_NetworkScene(NG_NetworkScene *val) {} #ifdef WITH_PYTHON // python methods diff -Nru blender-2.61/source/gameengine/GameLogic/SCA_ISensor.cpp blender-2.62/source/gameengine/GameLogic/SCA_ISensor.cpp --- blender-2.61/source/gameengine/GameLogic/SCA_ISensor.cpp 2011-12-13 19:47:07.000000000 +0000 +++ blender-2.62/source/gameengine/GameLogic/SCA_ISensor.cpp 2012-02-15 19:31:27.000000000 +0000 @@ -86,7 +86,8 @@ m_linkedcontrollers.clear(); } -bool SCA_ISensor::IsPositiveTrigger() { +bool SCA_ISensor::IsPositiveTrigger() +{ bool result = false; if (m_eventval) { @@ -107,40 +108,49 @@ m_pulse_frequency = freq; } -void SCA_ISensor::SetInvert(bool inv) { +void SCA_ISensor::SetInvert(bool inv) +{ m_invert = inv; } -void SCA_ISensor::SetLevel(bool lvl) { +void SCA_ISensor::SetLevel(bool lvl) +{ m_level = lvl; } -void SCA_ISensor::SetTap(bool tap) { +void SCA_ISensor::SetTap(bool tap) +{ m_tap = tap; } -double SCA_ISensor::GetNumber() { +double SCA_ISensor::GetNumber() +{ return GetState(); } -void SCA_ISensor::Suspend() { +void SCA_ISensor::Suspend() +{ m_suspended = true; } -bool SCA_ISensor::IsSuspended() { +bool SCA_ISensor::IsSuspended() +{ return m_suspended; } -void SCA_ISensor::Resume() { +void SCA_ISensor::Resume() +{ m_suspended = false; } -void SCA_ISensor::Init() { +void SCA_ISensor::Init() +{ printf("Sensor %s has no init function, please report this bug to Blender.org\n", m_name.Ptr()); } -void SCA_ISensor::DecLink() { +void SCA_ISensor::DecLink() +{ m_links--; if (m_links < 0) { diff -Nru blender-2.61/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp blender-2.62/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp --- blender-2.61/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp 2011-12-13 19:47:07.000000000 +0000 +++ blender-2.62/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp 2012-02-15 19:31:27.000000000 +0000 @@ -479,8 +479,8 @@ KX_PYATTRIBUTE_INT_RW("key",0,SCA_IInputDevice::KX_ENDKEY,true,SCA_KeyboardSensor,m_hotkey), KX_PYATTRIBUTE_SHORT_RW("hold1",0,SCA_IInputDevice::KX_ENDKEY,true,SCA_KeyboardSensor,m_qual), KX_PYATTRIBUTE_SHORT_RW("hold2",0,SCA_IInputDevice::KX_ENDKEY,true,SCA_KeyboardSensor,m_qual2), - KX_PYATTRIBUTE_STRING_RW("toggleProperty",0,100,false,SCA_KeyboardSensor,m_toggleprop), - KX_PYATTRIBUTE_STRING_RW("targetProperty",0,100,false,SCA_KeyboardSensor,m_targetprop), + KX_PYATTRIBUTE_STRING_RW("toggleProperty",0,MAX_PROP_NAME,false,SCA_KeyboardSensor,m_toggleprop), + KX_PYATTRIBUTE_STRING_RW("targetProperty",0,MAX_PROP_NAME,false,SCA_KeyboardSensor,m_targetprop), { NULL } //Sentinel }; diff -Nru blender-2.61/source/gameengine/GameLogic/SCA_KeyboardSensor.h blender-2.62/source/gameengine/GameLogic/SCA_KeyboardSensor.h --- blender-2.61/source/gameengine/GameLogic/SCA_KeyboardSensor.h 2011-12-13 19:47:07.000000000 +0000 +++ blender-2.62/source/gameengine/GameLogic/SCA_KeyboardSensor.h 2012-02-15 19:31:27.000000000 +0000 @@ -111,7 +111,7 @@ /* --------------------------------------------------------------------- */ // KeyEvents: - KX_PYMETHOD_DOC_NOARGS(SCA_KeyboardSensor,getEventList); + KX_PYMETHOD_DOC_NOARGS(SCA_KeyboardSensor,getEventList); // KeyStatus: KX_PYMETHOD_DOC_O(SCA_KeyboardSensor,getKeyStatus); diff -Nru blender-2.61/source/gameengine/GameLogic/SCA_PropertyActuator.cpp blender-2.62/source/gameengine/GameLogic/SCA_PropertyActuator.cpp --- blender-2.61/source/gameengine/GameLogic/SCA_PropertyActuator.cpp 2011-12-13 19:47:07.000000000 +0000 +++ blender-2.62/source/gameengine/GameLogic/SCA_PropertyActuator.cpp 2012-02-15 19:31:27.000000000 +0000 @@ -257,7 +257,7 @@ }; PyAttributeDef SCA_PropertyActuator::Attributes[] = { - KX_PYATTRIBUTE_STRING_RW_CHECK("propName",0,100,false,SCA_PropertyActuator,m_propname,CheckProperty), + KX_PYATTRIBUTE_STRING_RW_CHECK("propName",0,MAX_PROP_NAME,false,SCA_PropertyActuator,m_propname,CheckProperty), KX_PYATTRIBUTE_STRING_RW("value",0,100,false,SCA_PropertyActuator,m_exprtxt), KX_PYATTRIBUTE_INT_RW("mode", KX_ACT_PROP_NODEF+1, KX_ACT_PROP_MAX-1, false, SCA_PropertyActuator, m_type), /* ATTR_TODO add constents to game logic dict */ { NULL } //Sentinel diff -Nru blender-2.61/source/gameengine/GameLogic/SCA_PropertySensor.cpp blender-2.62/source/gameengine/GameLogic/SCA_PropertySensor.cpp --- blender-2.61/source/gameengine/GameLogic/SCA_PropertySensor.cpp 2011-12-13 19:47:07.000000000 +0000 +++ blender-2.62/source/gameengine/GameLogic/SCA_PropertySensor.cpp 2012-02-15 19:31:27.000000000 +0000 @@ -377,7 +377,7 @@ PyAttributeDef SCA_PropertySensor::Attributes[] = { KX_PYATTRIBUTE_INT_RW_CHECK("mode",KX_PROPSENSOR_NODEF,KX_PROPSENSOR_MAX-1,false,SCA_PropertySensor,m_checktype,modeChange), - KX_PYATTRIBUTE_STRING_RW_CHECK("propName",0,100,false,SCA_PropertySensor,m_checkpropname,CheckProperty), + KX_PYATTRIBUTE_STRING_RW_CHECK("propName",0,MAX_PROP_NAME,false,SCA_PropertySensor,m_checkpropname,CheckProperty), KX_PYATTRIBUTE_STRING_RW_CHECK("value",0,100,false,SCA_PropertySensor,m_checkpropval,validValueForProperty), KX_PYATTRIBUTE_STRING_RW_CHECK("min",0,100,false,SCA_PropertySensor,m_checkpropval,validValueForIntervalProperty), KX_PYATTRIBUTE_STRING_RW_CHECK("max",0,100,false,SCA_PropertySensor,m_checkpropmaxval,validValueForIntervalProperty), diff -Nru blender-2.61/source/gameengine/GameLogic/SCA_PythonKeyboard.cpp blender-2.62/source/gameengine/GameLogic/SCA_PythonKeyboard.cpp --- blender-2.61/source/gameengine/GameLogic/SCA_PythonKeyboard.cpp 2011-12-13 19:47:07.000000000 +0000 +++ blender-2.62/source/gameengine/GameLogic/SCA_PythonKeyboard.cpp 2012-02-15 19:31:27.000000000 +0000 @@ -84,6 +84,7 @@ PyAttributeDef SCA_PythonKeyboard::Attributes[] = { KX_PYATTRIBUTE_RO_FUNCTION("events", SCA_PythonKeyboard, pyattr_get_events), + KX_PYATTRIBUTE_RO_FUNCTION("active_events", SCA_PythonKeyboard, pyattr_get_active_events), { NULL } //Sentinel }; @@ -101,4 +102,21 @@ return self->m_event_dict; } +PyObject* SCA_PythonKeyboard::pyattr_get_active_events(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + SCA_PythonKeyboard* self = static_cast(self_v); + + PyDict_Clear(self->m_event_dict); + + for (int i=SCA_IInputDevice::KX_BEGINKEY; i<=SCA_IInputDevice::KX_ENDKEY; i++) + { + const SCA_InputEvent & inevent = self->m_keyboard->GetEventValue((SCA_IInputDevice::KX_EnumInputs)i); + + if (inevent.m_status != SCA_InputEvent::KX_NO_INPUTSTATUS) + PyDict_SetItem(self->m_event_dict, PyLong_FromSsize_t(i), PyLong_FromSsize_t(inevent.m_status)); + } + Py_INCREF(self->m_event_dict); + return self->m_event_dict; +} + #endif diff -Nru blender-2.61/source/gameengine/GameLogic/SCA_PythonKeyboard.h blender-2.62/source/gameengine/GameLogic/SCA_PythonKeyboard.h --- blender-2.61/source/gameengine/GameLogic/SCA_PythonKeyboard.h 2011-12-13 19:47:07.000000000 +0000 +++ blender-2.62/source/gameengine/GameLogic/SCA_PythonKeyboard.h 2012-02-15 19:31:27.000000000 +0000 @@ -43,6 +43,7 @@ #ifdef WITH_PYTHON static PyObject* pyattr_get_events(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject* pyattr_get_active_events(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); #endif }; diff -Nru blender-2.61/source/gameengine/GameLogic/SCA_PythonMouse.cpp blender-2.62/source/gameengine/GameLogic/SCA_PythonMouse.cpp --- blender-2.61/source/gameengine/GameLogic/SCA_PythonMouse.cpp 2011-12-13 19:47:07.000000000 +0000 +++ blender-2.62/source/gameengine/GameLogic/SCA_PythonMouse.cpp 2012-02-15 19:31:27.000000000 +0000 @@ -86,6 +86,7 @@ PyAttributeDef SCA_PythonMouse::Attributes[] = { KX_PYATTRIBUTE_RO_FUNCTION("events", SCA_PythonMouse, pyattr_get_events), + KX_PYATTRIBUTE_RO_FUNCTION("active_events", SCA_PythonMouse, pyattr_get_active_events), KX_PYATTRIBUTE_RW_FUNCTION("position", SCA_PythonMouse, pyattr_get_position, pyattr_set_position), KX_PYATTRIBUTE_RW_FUNCTION("visible", SCA_PythonMouse, pyattr_get_visible, pyattr_set_visible), { NULL } //Sentinel @@ -105,6 +106,22 @@ return self->m_event_dict; } +PyObject* SCA_PythonMouse::pyattr_get_active_events(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + SCA_PythonMouse* self = static_cast(self_v); + + PyDict_Clear(self->m_event_dict); + + for (int i=SCA_IInputDevice::KX_BEGINMOUSE; i<=SCA_IInputDevice::KX_ENDMOUSE; i++) + { + const SCA_InputEvent & inevent = self->m_mouse->GetEventValue((SCA_IInputDevice::KX_EnumInputs)i); + + if (inevent.m_status != SCA_InputEvent::KX_NO_INPUTSTATUS) + PyDict_SetItem(self->m_event_dict, PyLong_FromSsize_t(i), PyLong_FromSsize_t(inevent.m_status)); + } + Py_INCREF(self->m_event_dict); + return self->m_event_dict; +} PyObject* SCA_PythonMouse::pyattr_get_position(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { diff -Nru blender-2.61/source/gameengine/GameLogic/SCA_PythonMouse.h blender-2.62/source/gameengine/GameLogic/SCA_PythonMouse.h --- blender-2.61/source/gameengine/GameLogic/SCA_PythonMouse.h 2011-12-13 19:47:07.000000000 +0000 +++ blender-2.62/source/gameengine/GameLogic/SCA_PythonMouse.h 2012-02-15 19:31:27.000000000 +0000 @@ -48,6 +48,7 @@ KX_PYMETHOD_DOC(SCA_PythonMouse, show); static PyObject* pyattr_get_events(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject* pyattr_get_active_events(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_position(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_position(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject* value); static PyObject* pyattr_get_visible(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); diff -Nru blender-2.61/source/gameengine/GameLogic/SCA_RandomActuator.cpp blender-2.62/source/gameengine/GameLogic/SCA_RandomActuator.cpp --- blender-2.61/source/gameengine/GameLogic/SCA_RandomActuator.cpp 2011-12-13 19:47:07.000000000 +0000 +++ blender-2.62/source/gameengine/GameLogic/SCA_RandomActuator.cpp 2012-02-15 19:31:27.000000000 +0000 @@ -266,7 +266,8 @@ return false; } -void SCA_RandomActuator::enforceConstraints() { +void SCA_RandomActuator::enforceConstraints() +{ /* The constraints that are checked here are the ones fundamental to */ /* the various distributions. Limitations of the algorithms are checked */ /* elsewhere (or they should be... ). */ @@ -360,7 +361,7 @@ KX_PYATTRIBUTE_FLOAT_RO("para1",SCA_RandomActuator,m_parameter1), KX_PYATTRIBUTE_FLOAT_RO("para2",SCA_RandomActuator,m_parameter2), KX_PYATTRIBUTE_ENUM_RO("distribution",SCA_RandomActuator,m_distribution), - KX_PYATTRIBUTE_STRING_RW_CHECK("propName",0,100,false,SCA_RandomActuator,m_propname,CheckProperty), + KX_PYATTRIBUTE_STRING_RW_CHECK("propName",0,MAX_PROP_NAME,false,SCA_RandomActuator,m_propname,CheckProperty), KX_PYATTRIBUTE_RW_FUNCTION("seed",SCA_RandomActuator,pyattr_get_seed,pyattr_set_seed), { NULL } //Sentinel }; diff -Nru blender-2.61/source/gameengine/GameLogic/SCA_RandomNumberGenerator.cpp blender-2.62/source/gameengine/GameLogic/SCA_RandomNumberGenerator.cpp --- blender-2.61/source/gameengine/GameLogic/SCA_RandomNumberGenerator.cpp 2011-12-13 19:47:07.000000000 +0000 +++ blender-2.62/source/gameengine/GameLogic/SCA_RandomNumberGenerator.cpp 2012-02-15 19:31:27.000000000 +0000 @@ -65,7 +65,8 @@ /* intentionally empty */ } -void SCA_RandomNumberGenerator::SetStartVector(void) { +void SCA_RandomNumberGenerator::SetStartVector(void) +{ /* setting initial seeds to mt[N] using */ /* the generator Line 25 of Table 1 in */ /* [KNUTH 1981, The Art of Computer Programming */ @@ -85,7 +86,8 @@ /** * This is the important part: copied verbatim :) */ -unsigned long SCA_RandomNumberGenerator::Draw() { +unsigned long SCA_RandomNumberGenerator::Draw() +{ static unsigned long mag01[2] = { 0x0, MATRIX_A }; /* mag01[x] = x * MATRIX_A for x=0,1 */ @@ -121,7 +123,8 @@ return y; } -float SCA_RandomNumberGenerator::DrawFloat() { +float SCA_RandomNumberGenerator::DrawFloat() +{ return ( (float) Draw()/ (unsigned long) 0xffffffff ); } diff -Nru blender-2.61/source/gameengine/GamePlayer/common/GPC_Canvas.h blender-2.62/source/gameengine/GamePlayer/common/GPC_Canvas.h --- blender-2.61/source/gameengine/GamePlayer/common/GPC_Canvas.h 2011-12-13 19:46:48.000000000 +0000 +++ blender-2.62/source/gameengine/GamePlayer/common/GPC_Canvas.h 2012-02-15 19:31:06.000000000 +0000 @@ -103,6 +103,7 @@ void Resize(int width, int height); + virtual void ResizeWindow(int width, int height){}; /** * @section Methods inherited from abstract base class RAS_ICanvas. diff -Nru blender-2.61/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.h blender-2.62/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.h --- blender-2.61/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.h 2011-12-13 19:46:48.000000000 +0000 +++ blender-2.62/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.h 2012-02-15 19:31:06.000000000 +0000 @@ -57,6 +57,7 @@ * System dependent keyboard codes are stored as ints. */ std::map m_reverseKeyTranslateTable; + short m_exitkey; public: bool m_hookesc; diff -Nru blender-2.61/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp blender-2.62/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp --- blender-2.61/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp 2011-12-13 19:46:48.000000000 +0000 +++ blender-2.62/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp 2012-02-15 19:31:06.000000000 +0000 @@ -291,8 +291,31 @@ double* mat, float aspect) { + if(GLEW_ARB_multitexture) { + for(int i=0; i #include @@ -371,17 +372,20 @@ int bpp,int frequency, const bool stereoVisual, const int stereoMode, - const GHOST_TUns16 samples) + const GHOST_TUns16 samples, + bool useDesktop) { bool success; + GHOST_TUns32 sysWidth=0, sysHeight=0; + fSystem->getMainDisplayDimensions(sysWidth, sysHeight); // Create the main window GHOST_DisplaySetting setting; - setting.xPixels = width; - setting.yPixels = height; + setting.xPixels = (useDesktop) ? sysWidth : width; + setting.yPixels = (useDesktop) ? sysHeight : height; setting.bpp = bpp; setting.frequency = frequency; - fSystem->beginFullScreen(setting, &m_mainWindow, stereoVisual); + fSystem->beginFullScreen(setting, &m_mainWindow, stereoVisual, samples); m_mainWindow->setCursorVisibility(false); m_mainWindow->setState(GHOST_kWindowStateFullScreen); @@ -626,6 +630,8 @@ m_ketsjiengine->SetRasterizer(m_rasterizer); m_ketsjiengine->SetTimingDisplay(frameRate, false, false); + + KX_KetsjiEngine::SetExitKey(ConvertKeyCode(gm->exitkey)); #ifdef WITH_PYTHON CValue::SetDeprecationWarnings(nodepwarnings); #else @@ -786,6 +792,10 @@ void GPG_Application::exitEngine() { + // We only want to kill the engine if it has been initialized + if (!m_engineInitialized) + return; + sound_exit(); if (m_ketsjiengine) { @@ -908,12 +918,10 @@ { GHOST_TEventDataPtr eventData = ((GHOST_IEvent*)event)->getData(); GHOST_TEventKeyData* keyData = static_cast(eventData); - //no need for this test - //if (fSystem->getFullScreen()) { - if (keyData->key == GHOST_kKeyEsc && !m_keyboard->m_hookesc && !m_isEmbedded) { - m_exitRequested = KX_EXIT_REQUEST_OUTSIDE; - } - //} + + if (m_keyboard->ToNative(keyData->key) == KX_KetsjiEngine::GetExitKey() && !m_keyboard->m_hookesc && !m_isEmbedded) { + m_exitRequested = KX_EXIT_REQUEST_OUTSIDE; + } m_keyboard->ConvertEvent(keyData->key, isDown); handled = true; } diff -Nru blender-2.61/source/gameengine/GamePlayer/ghost/GPG_Application.h blender-2.62/source/gameengine/GamePlayer/ghost/GPG_Application.h --- blender-2.61/source/gameengine/GamePlayer/ghost/GPG_Application.h 2011-12-13 19:46:29.000000000 +0000 +++ blender-2.62/source/gameengine/GamePlayer/ghost/GPG_Application.h 2012-02-15 19:30:48.000000000 +0000 @@ -64,7 +64,7 @@ bool SetGameEngineData(struct Main* maggie, struct Scene* scene, GlobalSettings* gs, int argc, char** argv); bool startWindow(STR_String& title, int windowLeft, int windowTop, int windowWidth, int windowHeight, const bool stereoVisual, const int stereoMode, const GHOST_TUns16 samples=0); - bool startFullScreen(int width, int height, int bpp, int frequency, const bool stereoVisual, const int stereoMode, const GHOST_TUns16 samples=0); + bool startFullScreen(int width, int height, int bpp, int frequency, const bool stereoVisual, const int stereoMode, const GHOST_TUns16 samples=0, bool useDesktop=false); bool startEmbeddedWindow(STR_String& title, const GHOST_TEmbedderWindowID parent_window, const bool stereoVisual, const int stereoMode, const GHOST_TUns16 samples=0); #ifdef WIN32 bool startScreenSaverFullScreen(int width, int height, int bpp, int frequency, const bool stereoVisual, const int stereoMode, const GHOST_TUns16 samples=0); @@ -103,6 +103,7 @@ * Shuts the game engine down. */ void exitEngine(void); + short m_exitkey; /* The game data */ STR_String m_startSceneName; diff -Nru blender-2.61/source/gameengine/GamePlayer/ghost/GPG_Canvas.cpp blender-2.62/source/gameengine/GamePlayer/ghost/GPG_Canvas.cpp --- blender-2.61/source/gameengine/GamePlayer/ghost/GPG_Canvas.cpp 2011-12-13 19:46:29.000000000 +0000 +++ blender-2.62/source/gameengine/GamePlayer/ghost/GPG_Canvas.cpp 2012-02-15 19:30:48.000000000 +0000 @@ -108,6 +108,26 @@ } } +void GPG_Canvas::ResizeWindow(int width, int height) +{ + if (m_window->getState() == GHOST_kWindowStateFullScreen) + { + GHOST_ISystem* system = GHOST_ISystem::getSystem(); + GHOST_DisplaySetting setting; + setting.xPixels = width; + setting.yPixels = height; + //XXX allow these to be changed or kept from previous state + setting.bpp = 32; + setting.frequency = 60; + + system->updateFullScreen(setting, &m_window); + } + + m_window->setClientSize(width, height); + + Resize(width, height); +} + float GPG_Canvas::GetMouseNormalizedX(int x) { return float(x)/this->GetWidth(); diff -Nru blender-2.61/source/gameengine/GamePlayer/ghost/GPG_Canvas.h blender-2.62/source/gameengine/GamePlayer/ghost/GPG_Canvas.h --- blender-2.61/source/gameengine/GamePlayer/ghost/GPG_Canvas.h 2011-12-13 19:46:29.000000000 +0000 +++ blender-2.62/source/gameengine/GamePlayer/ghost/GPG_Canvas.h 2012-02-15 19:30:48.000000000 +0000 @@ -60,6 +60,8 @@ virtual float GetMouseNormalizedX(int x); virtual float GetMouseNormalizedY(int y); + virtual void ResizeWindow(int width, int height); + bool BeginDraw() { return true;}; void EndDraw() {}; }; diff -Nru blender-2.61/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp blender-2.62/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp --- blender-2.61/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp 2011-12-13 19:46:29.000000000 +0000 +++ blender-2.62/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp 2012-02-15 19:30:48.000000000 +0000 @@ -365,6 +365,7 @@ GHOST_TEmbedderWindowID parentWindow = 0; bool isBlenderPlayer = false; int validArguments=0; + bool samplesParFound = false; GHOST_TUns16 aasamples = 0; #ifdef __linux__ @@ -582,8 +583,14 @@ break; case 'm': i++; + samplesParFound = true; if ((i+1) <= validArguments ) - aasamples = atoi(argv[i++]); + aasamples = atoi(argv[i++]); + else + { + error = true; + printf("error: No argument supplied for -m"); + } break; case 'c': i++; @@ -758,7 +765,7 @@ // if we got an exitcode 3 (KX_EXIT_REQUEST_START_OTHER_GAME) load a different file if (exitcode == KX_EXIT_REQUEST_START_OTHER_GAME) { - char basedpath[240]; + char basedpath[FILE_MAX]; // base the actuator filename relative to the last file BLI_strncpy(basedpath, exitstring.Ptr(), sizeof(basedpath)); @@ -819,7 +826,7 @@ if ((!fullScreenParFound) && (!windowParFound)) { // Only use file settings when command line did not override - if (scene->gm.fullscreen) { + if ((scene->gm.playerflag & GAME_PLAYER_FULLSCREEN)) { //printf("fullscreen option found in Blender file\n"); fullScreen = true; fullScreenWidth= scene->gm.xplay; @@ -848,6 +855,9 @@ else scene->gm.stereoflag = STEREO_ENABLED; + if (!samplesParFound) + aasamples = scene->gm.aasamples; + if (stereoFlag == STEREO_DOME){ stereomode = RAS_IRasterizer::RAS_STEREO_DOME; scene->gm.stereoflag = STEREO_DOME; @@ -893,7 +903,7 @@ #endif { app.startFullScreen(fullScreenWidth, fullScreenHeight, fullScreenBpp, fullScreenFrequency, - stereoWindow, stereomode, aasamples); + stereoWindow, stereomode, aasamples, (scene->gm.playerflag & GAME_PLAYER_DESKTOP_RESOLUTION)); } } else diff -Nru blender-2.61/source/gameengine/GamePlayer/xembed/blenderplayer-wrapper.c blender-2.62/source/gameengine/GamePlayer/xembed/blenderplayer-wrapper.c --- blender-2.61/source/gameengine/GamePlayer/xembed/blenderplayer-wrapper.c 2011-12-13 19:46:30.000000000 +0000 +++ blender-2.62/source/gameengine/GamePlayer/xembed/blenderplayer-wrapper.c 2012-02-15 19:30:49.000000000 +0000 @@ -48,8 +48,8 @@ -void print_id(){ - +void print_id() +{ uid_t ruid, euid, suid; getresuid(&ruid, &euid, &suid); @@ -61,7 +61,8 @@ This function is used to catch SIGTERM signal (raised by web plugin when the plugin should shut down and raise a SIGKILL signal to the blenderplayer in order to kill it. */ -void sigterm_handler(int signum) { +void sigterm_handler(int signum) +{ printf("Signal!!!\n"); if (blenderplayer_id != 0) { kill(blenderplayer_id, SIGKILL); @@ -77,8 +78,8 @@ argv[2] should be an window handle id */ -int main(int argc, char *argv[]) { - +int main(int argc, char *argv[]) +{ uid_t privid = geteuid(); uid_t caller_id = getuid(); diff -Nru blender-2.61/source/gameengine/Ketsji/BL_Material.cpp blender-2.62/source/gameengine/Ketsji/BL_Material.cpp --- blender-2.61/source/gameengine/Ketsji/BL_Material.cpp 2011-12-13 19:47:26.000000000 +0000 +++ blender-2.62/source/gameengine/Ketsji/BL_Material.cpp 2012-02-15 19:31:53.000000000 +0000 @@ -98,21 +98,24 @@ } } -void BL_Material::SetConversionRGB(unsigned int *nrgb) { +void BL_Material::SetConversionRGB(unsigned int *nrgb) +{ rgb[0]=*nrgb++; rgb[1]=*nrgb++; rgb[2]=*nrgb++; rgb[3]=*nrgb; } -void BL_Material::GetConversionRGB(unsigned int *nrgb) { +void BL_Material::GetConversionRGB(unsigned int *nrgb) +{ *nrgb++ = rgb[0]; *nrgb++ = rgb[1]; *nrgb++ = rgb[2]; *nrgb = rgb[3]; } -void BL_Material::SetConversionUV(const STR_String& name, MT_Point2 *nuv) { +void BL_Material::SetConversionUV(const STR_String& name, MT_Point2 *nuv) +{ uvName = name; uv[0] = *nuv++; uv[1] = *nuv++; @@ -120,13 +123,15 @@ uv[3] = *nuv; } -void BL_Material::GetConversionUV(MT_Point2 *nuv){ +void BL_Material::GetConversionUV(MT_Point2 *nuv) +{ *nuv++ = uv[0]; *nuv++ = uv[1]; *nuv++ = uv[2]; *nuv = uv[3]; } -void BL_Material::SetConversionUV2(const STR_String& name, MT_Point2 *nuv) { +void BL_Material::SetConversionUV2(const STR_String& name, MT_Point2 *nuv) +{ uv2Name = name; uv2[0] = *nuv++; uv2[1] = *nuv++; @@ -134,7 +139,8 @@ uv2[3] = *nuv; } -void BL_Material::GetConversionUV2(MT_Point2 *nuv){ +void BL_Material::GetConversionUV2(MT_Point2 *nuv) +{ *nuv++ = uv2[0]; *nuv++ = uv2[1]; *nuv++ = uv2[2]; diff -Nru blender-2.61/source/gameengine/Ketsji/BL_Texture.cpp blender-2.62/source/gameengine/Ketsji/BL_Texture.cpp --- blender-2.61/source/gameengine/Ketsji/BL_Texture.cpp 2011-12-13 19:47:26.000000000 +0000 +++ blender-2.62/source/gameengine/Ketsji/BL_Texture.cpp 2012-02-15 19:31:53.000000000 +0000 @@ -38,11 +38,13 @@ } // (n&(n-1)) zeros the least significant bit of n -static int is_pow2(int num) { +static int is_power_of_2_i(int num) +{ return ((num)&(num-1))==0; } -static int smaller_pow2(int num) { - while (!is_pow2(num)) +static int power_of_2_min_i(int num) +{ + while (!is_power_of_2_i(num)) num= num&(num-1); return num; } @@ -159,7 +161,7 @@ void BL_Texture::InitGLTex(unsigned int *pix,int x,int y,bool mipmap) { - if (!is_pow2(x) || !is_pow2(y) ) { + if (!is_power_of_2_i(x) || !is_power_of_2_i(y) ) { InitNonPow2Tex(pix, x,y,mipmap); return; } @@ -184,8 +186,8 @@ void BL_Texture::InitNonPow2Tex(unsigned int *pix,int x,int y,bool mipmap) { - int nx= smaller_pow2(x); - int ny= smaller_pow2(y); + int nx= power_of_2_min_i(x); + int ny= power_of_2_min_i(y); unsigned int *newPixels = (unsigned int *)malloc(nx*ny*sizeof(unsigned int)); @@ -274,7 +276,7 @@ my_envmap_split_ima(cubemap, ibuf); - if (!is_pow2(cubemap->cube[0]->x) || !is_pow2(cubemap->cube[0]->y)) + if (!is_power_of_2_i(cubemap->cube[0]->x) || !is_power_of_2_i(cubemap->cube[0]->y)) { spit("invalid envmap size please render with CubeRes @ power of two"); @@ -610,8 +612,8 @@ int BL_Texture::GetPow2(int n) { - if(!is_pow2(n)) - n = smaller_pow2(n); + if(!is_power_of_2_i(n)) + n = power_of_2_min_i(n); return n; } diff -Nru blender-2.61/source/gameengine/Ketsji/KX_BlenderMaterial.h blender-2.62/source/gameengine/Ketsji/KX_BlenderMaterial.h --- blender-2.61/source/gameengine/Ketsji/KX_BlenderMaterial.h 2011-12-13 19:47:26.000000000 +0000 +++ blender-2.62/source/gameengine/Ketsji/KX_BlenderMaterial.h 2012-02-15 19:31:53.000000000 +0000 @@ -106,7 +106,7 @@ #ifdef WITH_PYTHON // -------------------------------- - virtual PyObject* py_repr(void) { return PyUnicode_FromString(mMaterial->matname.ReadPtr()); } + virtual PyObject* py_repr(void) { return PyUnicode_From_STR_String(mMaterial->matname); } static PyObject* pyattr_get_shader(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_materialIndex(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); diff -Nru blender-2.61/source/gameengine/Ketsji/KX_CameraActuator.cpp blender-2.62/source/gameengine/Ketsji/KX_CameraActuator.cpp --- blender-2.61/source/gameengine/Ketsji/KX_CameraActuator.cpp 2011-12-13 19:47:26.000000000 +0000 +++ blender-2.62/source/gameengine/Ketsji/KX_CameraActuator.cpp 2012-02-15 19:31:53.000000000 +0000 @@ -53,7 +53,7 @@ float hght, float minhght, float maxhght, - bool xytog, + short axis, float damping ): SCA_IActuator(gameobj, KX_ACT_CAMERA), @@ -61,7 +61,7 @@ m_height (hght), m_minHeight (minhght), m_maxHeight (maxhght), - m_x (xytog), + m_axis(axis), m_damping (damping) { if (m_ob) @@ -264,23 +264,50 @@ /* C4: camera behind actor */ - if (m_x) { - fp1[0] = actormat[0][0]; - fp1[1] = actormat[1][0]; - fp1[2] = actormat[2][0]; - - fp2[0] = frommat[0][0]; - fp2[1] = frommat[1][0]; - fp2[2] = frommat[2][0]; - } - else { - fp1[0] = actormat[0][1]; - fp1[1] = actormat[1][1]; - fp1[2] = actormat[2][1]; - - fp2[0] = frommat[0][1]; - fp2[1] = frommat[1][1]; - fp2[2] = frommat[2][1]; + switch (m_axis) { + case OB_POSX: + /* X */ + fp1[0] = actormat[0][0]; + fp1[1] = actormat[1][0]; + fp1[2] = actormat[2][0]; + + fp2[0] = frommat[0][0]; + fp2[1] = frommat[1][0]; + fp2[2] = frommat[2][0]; + break; + case OB_POSY: + /* Y */ + fp1[0] = actormat[0][1]; + fp1[1] = actormat[1][1]; + fp1[2] = actormat[2][1]; + + fp2[0] = frommat[0][1]; + fp2[1] = frommat[1][1]; + fp2[2] = frommat[2][1]; + break; + case OB_NEGX: + /* -X */ + fp1[0] = -actormat[0][0]; + fp1[1] = -actormat[1][0]; + fp1[2] = -actormat[2][0]; + + fp2[0] = frommat[0][0]; + fp2[1] = frommat[1][0]; + fp2[2] = frommat[2][0]; + break; + case OB_NEGY: + /* -Y */ + fp1[0] = -actormat[0][1]; + fp1[1] = -actormat[1][1]; + fp1[2] = -actormat[2][1]; + + fp2[0] = frommat[0][1]; + fp2[1] = frommat[1][1]; + fp2[2] = frommat[2][1]; + break; + default: + assert(0); + break; } inp= fp1[0]*fp2[0] + fp1[1]*fp2[1] + fp1[2]*fp2[2]; @@ -389,7 +416,7 @@ KX_PYATTRIBUTE_FLOAT_RW("min",-FLT_MAX,FLT_MAX,KX_CameraActuator,m_minHeight), KX_PYATTRIBUTE_FLOAT_RW("max",-FLT_MAX,FLT_MAX,KX_CameraActuator,m_maxHeight), KX_PYATTRIBUTE_FLOAT_RW("height",-FLT_MAX,FLT_MAX,KX_CameraActuator,m_height), - KX_PYATTRIBUTE_BOOL_RW("useXY",KX_CameraActuator,m_x), + KX_PYATTRIBUTE_SHORT_RW("axis", 0, 3, true, KX_CameraActuator,m_axis), KX_PYATTRIBUTE_RW_FUNCTION("object", KX_CameraActuator, pyattr_get_object, pyattr_set_object), KX_PYATTRIBUTE_FLOAT_RW("damping",0.f,10.f,KX_CameraActuator,m_damping), {NULL} diff -Nru blender-2.61/source/gameengine/Ketsji/KX_CameraActuator.h blender-2.62/source/gameengine/Ketsji/KX_CameraActuator.h --- blender-2.61/source/gameengine/Ketsji/KX_CameraActuator.h 2011-12-13 19:47:26.000000000 +0000 +++ blender-2.62/source/gameengine/Ketsji/KX_CameraActuator.h 2012-02-15 19:31:53.000000000 +0000 @@ -70,8 +70,8 @@ /** max (float), */ float m_maxHeight; - /** xy toggle (pick one): true == x, false == y */ - bool m_x; + /** axis the camera tries to get behind: +x/+y/-x/-y */ + short m_axis; /** damping (float), */ float m_damping; @@ -97,7 +97,7 @@ float hght, float minhght, float maxhght, - bool xytog, + short axis, float damping ); diff -Nru blender-2.61/source/gameengine/Ketsji/KX_ConstraintActuator.cpp blender-2.62/source/gameengine/Ketsji/KX_ConstraintActuator.cpp --- blender-2.61/source/gameengine/Ketsji/KX_ConstraintActuator.cpp 2011-12-13 19:47:26.000000000 +0000 +++ blender-2.62/source/gameengine/Ketsji/KX_ConstraintActuator.cpp 2012-02-15 19:31:53.000000000 +0000 @@ -600,7 +600,7 @@ KX_PYATTRIBUTE_FLOAT_ARRAY_RW_CHECK("direction",-FLT_MAX,FLT_MAX,KX_ConstraintActuator,m_refDirection,3,pyattr_check_direction), KX_PYATTRIBUTE_INT_RW("option",0,0xFFFF,false,KX_ConstraintActuator,m_option), KX_PYATTRIBUTE_INT_RW("time",0,1000,true,KX_ConstraintActuator,m_activeTime), - KX_PYATTRIBUTE_STRING_RW("propName",0,32,true,KX_ConstraintActuator,m_property), + KX_PYATTRIBUTE_STRING_RW("propName",0,MAX_PROP_NAME,true,KX_ConstraintActuator,m_property), KX_PYATTRIBUTE_FLOAT_RW("min",-FLT_MAX,FLT_MAX,KX_ConstraintActuator,m_minimumBound), KX_PYATTRIBUTE_FLOAT_RW("distance",-FLT_MAX,FLT_MAX,KX_ConstraintActuator,m_minimumBound), KX_PYATTRIBUTE_FLOAT_RW("max",-FLT_MAX,FLT_MAX,KX_ConstraintActuator,m_maximumBound), diff -Nru blender-2.61/source/gameengine/Ketsji/KX_Dome.cpp blender-2.62/source/gameengine/Ketsji/KX_Dome.cpp --- blender-2.61/source/gameengine/Ketsji/KX_Dome.cpp 2011-12-13 19:47:26.000000000 +0000 +++ blender-2.62/source/gameengine/Ketsji/KX_Dome.cpp 2012-02-15 19:31:53.000000000 +0000 @@ -255,7 +255,8 @@ } } -bool KX_Dome::CreateDL(){ +bool KX_Dome::CreateDL() +{ dlistId = glGenLists((GLsizei) m_numimages); if (dlistId != 0) { if(m_mode == DOME_FISHEYE || m_mode == DOME_TRUNCATED_FRONT || m_mode == DOME_TRUNCATED_REAR){ diff -Nru blender-2.61/source/gameengine/Ketsji/KX_FontObject.cpp blender-2.62/source/gameengine/Ketsji/KX_FontObject.cpp --- blender-2.61/source/gameengine/Ketsji/KX_FontObject.cpp 2011-12-13 19:47:26.000000000 +0000 +++ blender-2.62/source/gameengine/Ketsji/KX_FontObject.cpp 2012-02-15 19:31:53.000000000 +0000 @@ -34,6 +34,14 @@ #include "KX_Scene.h" #include "KX_PythonInit.h" #include "BLI_math.h" +#include "StringValue.h" + +/* paths needed for font load */ +#include "BLI_blenlib.h" +#include "BKE_global.h" +#include "BKE_font.h" +#include "BKE_main.h" +#include "DNA_packedFile_types.h" extern "C" { #include "BLF_api.h" @@ -41,6 +49,30 @@ #define BGE_FONT_RES 100 +/* proptotype */ +int GetFontId(VFont *font); + +std::vector split_string(STR_String str) +{ + std::vector text = std::vector(); + + /* Split the string upon new lines */ + int begin=0, end=0; + while (end < str.Length()) + { + if(str.GetAt(end) == '\n') + { + text.push_back(str.Mid(begin, end-begin)); + begin = end+1; + } + end++; + } + //Now grab the last line + text.push_back(str.Mid(begin, end-begin)); + + return text; +} + KX_FontObject::KX_FontObject( void* sgReplicationInfo, SG_Callbacks callbacks, RAS_IRenderTools* rendertools, @@ -52,22 +84,13 @@ m_rendertools(rendertools) { Curve *text = static_cast (ob->data); - m_text = text->str; + m_text = split_string(text->str); m_fsize = text->fsize; - - /* FO_BUILTIN_NAME != "default" */ - /* I hope at some point Blender (2.5x) can have a single font */ - /* with unicode support for ui and OB_FONT */ - /* once we have packed working we can load the FO_BUILTIN_NAME font */ - const char* filepath = text->vfont->name; - if (strcmp(FO_BUILTIN_NAME, filepath) == 0) - filepath = "default"; - - /* XXX - if it's packed it will not work. waiting for bdiego (Diego) fix for that. */ - m_fontid = BLF_load(filepath); - if (m_fontid == -1) - m_fontid = BLF_load("default"); - + m_line_spacing = text->linedist; + m_offset = MT_Vector3(text->xof, text->yof, 0); + + m_fontid = GetFontId(text->vfont); + /* initialize the color with the object color and store it in the KX_Object class This is a workaround waiting for the fix: [#25487] BGE: Object Color only works when it has a keyed frame */ @@ -93,22 +116,91 @@ KX_GetActiveScene()->AddFont(this); } +int GetFontId (VFont *font) { + PackedFile *packedfile=NULL; + int fontid = -1; + + if (font->packedfile) { + packedfile= font->packedfile; + fontid= BLF_load_mem(font->name, (unsigned char*)packedfile->data, packedfile->size); + + if (fontid == -1) { + printf("ERROR: packed font \"%s\" could not be loaded.\n", font->name); + fontid = BLF_load("default"); + } + return fontid; + } + + /* once we have packed working we can load the FO_BUILTIN_NAME font */ + const char *filepath = font->name; + if (strcmp(FO_BUILTIN_NAME, filepath) == 0) { + fontid = BLF_load("default"); + + /* XXX the following code is supposed to work (after you add get_builtin_packedfile to BKE_font.h ) + * unfortunately it's crashing on blf_glyph.c:173 because gc->max_glyph_width is 0 + */ + // packedfile=get_builtin_packedfile(); + // fontid= BLF_load_mem(font->name, (unsigned char*)packedfile->data, packedfile->size); + // return fontid; + + return BLF_load("default"); + } + + /* convert from absolute to relative */ + char expanded[256]; // font names can be bigger than FILE_MAX (240) + BLI_strncpy(expanded, filepath, 256); + BLI_path_abs(expanded, G.main->name); + + fontid = BLF_load(expanded); + + /* fallback */ + if (fontid == -1) + fontid = BLF_load("default"); + + return fontid; +} + void KX_FontObject::DrawText() { + /* Allow for some logic brick control */ + if(this->GetProperty("Text")) + m_text = split_string(this->GetProperty("Text")->GetText()); + /* only draws the text if visible */ if(this->GetVisible() == 0) return; /* update the animated color */ this->GetObjectColor().getValue(m_color); - /* XXX 2DO - handle multiple lines */ /* HARDCODED MULTIPLICATION FACTOR - this will affect the render resolution directly */ - float RES = BGE_FONT_RES * m_resolution; + const float RES = BGE_FONT_RES * m_resolution; - float size = m_fsize * m_object->size[0] * RES; - float aspect = 1.f / (m_object->size[0] * RES); + const float size = m_fsize * this->NodeGetWorldScaling()[0] * RES; + const float aspect = m_fsize / size; - m_rendertools->RenderText3D(m_fontid, m_text, int(size), m_dpi, m_color, this->GetOpenGLMatrix(), aspect); + /* Get a working copy of the OpenGLMatrix to use */ + double mat[16]; + memcpy(mat, this->GetOpenGLMatrix(), sizeof(double)*16); + + /* Account for offset */ + MT_Vector3 offset = this->NodeGetWorldOrientation() * m_offset * this->NodeGetWorldScaling(); + mat[12] += offset[0]; mat[13] += offset[1]; mat[14] += offset[2]; + + /* Orient the spacing vector */ + MT_Vector3 spacing = MT_Vector3(0, m_fsize*m_line_spacing, 0); + spacing = this->NodeGetWorldOrientation() * spacing * this->NodeGetWorldScaling()[1]; + + /* Draw each line, taking spacing into consideration */ + for(int i=0; iRenderText3D(m_fontid, m_text[i], int(size), m_dpi, m_color, mat, aspect); + } } #ifdef WITH_PYTHON @@ -150,11 +242,46 @@ }; PyAttributeDef KX_FontObject::Attributes[] = { - KX_PYATTRIBUTE_STRING_RW("text", 0, 280, false, KX_FontObject, m_text), //arbitrary limit. 280 = 140 unicode chars in unicode + //KX_PYATTRIBUTE_STRING_RW("text", 0, 280, false, KX_FontObject, m_text[0]), //arbitrary limit. 280 = 140 unicode chars in unicode + KX_PYATTRIBUTE_RW_FUNCTION("text", KX_FontObject, pyattr_get_text, pyattr_set_text), KX_PYATTRIBUTE_FLOAT_RW("size", 0.0001f, 10000.0f, KX_FontObject, m_fsize), KX_PYATTRIBUTE_FLOAT_RW("resolution", 0.0001f, 10000.0f, KX_FontObject, m_resolution), /* KX_PYATTRIBUTE_INT_RW("dpi", 0, 10000, false, KX_FontObject, m_dpi), */// no real need for expose this I think { NULL } //Sentinel }; +PyObject* KX_FontObject::pyattr_get_text(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_FontObject* self= static_cast(self_v); + STR_String str = STR_String(); + for(int i=0; im_text.size(); ++i) + { + if(i!=0) + str += '\n'; + str += self->m_text[i]; + } + return PyUnicode_From_STR_String(str); +} + +int KX_FontObject::pyattr_set_text(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_FontObject* self= static_cast(self_v); + if(!PyUnicode_Check(value)) + return PY_SET_ATTR_FAIL; + char* chars = _PyUnicode_AsString(value); + + /* Allow for some logic brick control */ + CValue* tprop = self->GetProperty("Text"); + if(tprop) { + CValue *newstringprop = new CStringValue(STR_String(chars), "Text"); + self->SetProperty("Text", newstringprop); + newstringprop->Release(); + } + else { + self->m_text = split_string(STR_String(chars)); + } + + return PY_SET_ATTR_SUCCESS; +} + #endif // WITH_PYTHON diff -Nru blender-2.61/source/gameengine/Ketsji/KX_FontObject.h blender-2.62/source/gameengine/Ketsji/KX_FontObject.h --- blender-2.61/source/gameengine/Ketsji/KX_FontObject.h 2011-12-13 19:47:26.000000000 +0000 +++ blender-2.62/source/gameengine/Ketsji/KX_FontObject.h 2012-02-15 19:31:53.000000000 +0000 @@ -57,13 +57,15 @@ virtual void ProcessReplica(); protected: - STR_String m_text; + std::vector m_text; Object* m_object; int m_fontid; int m_dpi; float m_fsize; float m_resolution; float m_color[4]; + float m_line_spacing; + MT_Vector3 m_offset; class RAS_IRenderTools* m_rendertools; //needed for drawing routine @@ -76,6 +78,8 @@ */ #ifdef WITH_PYTHON + static PyObject* pyattr_get_text(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static int pyattr_set_text(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); #endif }; diff -Nru blender-2.61/source/gameengine/Ketsji/KX_GameObject.cpp blender-2.62/source/gameengine/Ketsji/KX_GameObject.cpp --- blender-2.61/source/gameengine/Ketsji/KX_GameObject.cpp 2011-12-13 19:47:26.000000000 +0000 +++ blender-2.62/source/gameengine/Ketsji/KX_GameObject.cpp 2012-02-15 19:31:53.000000000 +0000 @@ -1153,6 +1153,36 @@ } } +void KX_GameObject::NodeSetWorldScale(const MT_Vector3& scale) +{ + if (!GetSGNode()) + return; + SG_Node* parent = GetSGNode()->GetSGParent(); + if (parent != NULL) + { + // Make sure the objects have some scale + MT_Vector3 p_scale = parent->GetWorldScaling(); + if (fabs(p_scale[0]) < FLT_EPSILON || + fabs(p_scale[1]) < FLT_EPSILON || + fabs(p_scale[2]) < FLT_EPSILON) + { + return; + } + + MT_Vector3 *local = new MT_Vector3(scale); + + p_scale[0] = 1/p_scale[0]; + p_scale[1] = 1/p_scale[1]; + p_scale[2] = 1/p_scale[2]; + + NodeSetLocalScale(scale * p_scale); + } + else + { + NodeSetLocalScale(scale); + } +} + void KX_GameObject::NodeSetWorldPosition(const MT_Point3& trans) { if (!GetSGNode()) @@ -1620,7 +1650,9 @@ KX_PYATTRIBUTE_RW_FUNCTION("localPosition", KX_GameObject, pyattr_get_localPosition, pyattr_set_localPosition), KX_PYATTRIBUTE_RW_FUNCTION("worldPosition", KX_GameObject, pyattr_get_worldPosition, pyattr_set_worldPosition), KX_PYATTRIBUTE_RW_FUNCTION("localScale", KX_GameObject, pyattr_get_localScaling, pyattr_set_localScaling), - KX_PYATTRIBUTE_RO_FUNCTION("worldScale", KX_GameObject, pyattr_get_worldScaling), + KX_PYATTRIBUTE_RW_FUNCTION("worldScale", KX_GameObject, pyattr_get_worldScaling, pyattr_set_worldScaling), + KX_PYATTRIBUTE_RW_FUNCTION("localTransform", KX_GameObject, pyattr_get_localTransform, pyattr_set_localTransform), + KX_PYATTRIBUTE_RW_FUNCTION("worldTransform", KX_GameObject, pyattr_get_worldTransform, pyattr_set_worldTransform), KX_PYATTRIBUTE_RW_FUNCTION("linearVelocity", KX_GameObject, pyattr_get_localLinearVelocity, pyattr_set_worldLinearVelocity), KX_PYATTRIBUTE_RW_FUNCTION("localLinearVelocity", KX_GameObject, pyattr_get_localLinearVelocity, pyattr_set_localLinearVelocity), KX_PYATTRIBUTE_RW_FUNCTION("worldLinearVelocity", KX_GameObject, pyattr_get_worldLinearVelocity, pyattr_set_worldLinearVelocity), @@ -2112,6 +2144,18 @@ #endif } +int KX_GameObject::pyattr_set_worldScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_GameObject* self= static_cast(self_v); + MT_Vector3 scale; + if (!PyVecTo(value, scale)) + return PY_SET_ATTR_FAIL; + + self->NodeSetWorldScale(scale); + self->NodeUpdateGS(0.f); + return PY_SET_ATTR_SUCCESS; +} + PyObject* KX_GameObject::pyattr_get_localScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { #ifdef USE_MATHUTILS @@ -2134,6 +2178,85 @@ return PY_SET_ATTR_SUCCESS; } +PyObject* KX_GameObject::pyattr_get_localTransform(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_GameObject* self = static_cast(self_v); + + double *mat = MT_CmMatrix4x4().getPointer(); + + MT_Transform trans; + + trans.setOrigin(self->GetSGNode()->GetLocalPosition()); + trans.setBasis(self->GetSGNode()->GetLocalOrientation()); + + MT_Vector3 scaling = self->GetSGNode()->GetLocalScale(); + trans.scale(scaling[0], scaling[1], scaling[2]); + + trans.getValue(mat); + + return PyObjectFrom(MT_Matrix4x4(mat)); +} + +int KX_GameObject::pyattr_set_localTransform(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_GameObject* self = static_cast(self_v); + MT_Matrix4x4 temp; + if (!PyMatTo(value, temp)) + return PY_SET_ATTR_FAIL; + + float transform[4][4]; + float loc[3], size[3]; + float rot[3][3]; + MT_Matrix3x3 orientation; + + temp.getValue(*transform); + mat4_to_loc_rot_size(loc, rot, size, transform); + + self->NodeSetLocalPosition(MT_Point3(loc)); + + //MT_Matrix3x3's constructor expects a 4x4 matrix + orientation = MT_Matrix3x3(); + orientation.setValue3x3(*rot); + self->NodeSetLocalOrientation(orientation); + + self->NodeSetLocalScale(MT_Vector3(size)); + + return PY_SET_ATTR_SUCCESS; +} + +PyObject* KX_GameObject::pyattr_get_worldTransform(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_GameObject* self = static_cast(self_v); + + return PyObjectFrom(MT_Matrix4x4(self->GetOpenGLMatrix())); +} + +int KX_GameObject::pyattr_set_worldTransform(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_GameObject* self = static_cast(self_v); + MT_Matrix4x4 temp; + if (!PyMatTo(value, temp)) + return PY_SET_ATTR_FAIL; + + float transform[4][4]; + float loc[3], size[3]; + float rot[3][3]; + MT_Matrix3x3 orientation; + + temp.getValue(*transform); + mat4_to_loc_rot_size(loc, rot, size, transform); + + self->NodeSetWorldPosition(MT_Point3(loc)); + + //MT_Matrix3x3's constructor expects a 4x4 matrix + orientation = MT_Matrix3x3(); + orientation.setValue3x3(*rot); + self->NodeSetGlobalOrientation(orientation); + + self->NodeSetWorldScale(MT_Vector3(size)); + + return PY_SET_ATTR_SUCCESS; +} PyObject* KX_GameObject::pyattr_get_worldLinearVelocity(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { diff -Nru blender-2.61/source/gameengine/Ketsji/KX_GameObject.h blender-2.62/source/gameengine/Ketsji/KX_GameObject.h --- blender-2.61/source/gameengine/Ketsji/KX_GameObject.h 2011-12-13 19:47:26.000000000 +0000 +++ blender-2.62/source/gameengine/Ketsji/KX_GameObject.h 2012-02-15 19:31:53.000000000 +0000 @@ -475,6 +475,7 @@ void NodeSetGlobalOrientation(const MT_Matrix3x3& rot ); void NodeSetLocalScale( const MT_Vector3& scale ); + void NodeSetWorldScale( const MT_Vector3& scale ); void NodeSetRelativeScale( const MT_Vector3& scale ); @@ -888,7 +889,7 @@ */ virtual PyObject* py_repr(void) { - return PyUnicode_FromString(GetName().ReadPtr()); + return PyUnicode_From_STR_String(GetName()); } KX_PYMETHOD_O(KX_GameObject,SetWorldPosition); @@ -968,8 +969,13 @@ static PyObject* pyattr_get_localOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_localOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); static PyObject* pyattr_get_worldScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static int pyattr_set_worldScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); static PyObject* pyattr_get_localScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_localScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); + static PyObject* pyattr_get_localTransform(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static int pyattr_set_localTransform(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); + static PyObject* pyattr_get_worldTransform(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static int pyattr_set_worldTransform(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); static PyObject* pyattr_get_worldLinearVelocity(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_worldLinearVelocity(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); static PyObject* pyattr_get_localLinearVelocity(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); diff -Nru blender-2.61/source/gameengine/Ketsji/KX_IpoActuator.cpp blender-2.62/source/gameengine/Ketsji/KX_IpoActuator.cpp --- blender-2.61/source/gameengine/Ketsji/KX_IpoActuator.cpp 2011-12-13 19:47:26.000000000 +0000 +++ blender-2.62/source/gameengine/Ketsji/KX_IpoActuator.cpp 2012-02-15 19:31:53.000000000 +0000 @@ -442,8 +442,8 @@ PyAttributeDef KX_IpoActuator::Attributes[] = { KX_PYATTRIBUTE_RW_FUNCTION("frameStart", KX_IpoActuator, pyattr_get_frame_start, pyattr_set_frame_start), KX_PYATTRIBUTE_RW_FUNCTION("frameEnd", KX_IpoActuator, pyattr_get_frame_end, pyattr_set_frame_end), - KX_PYATTRIBUTE_STRING_RW("propName", 0, 64, false, KX_IpoActuator, m_propname), - KX_PYATTRIBUTE_STRING_RW("framePropName", 0, 64, false, KX_IpoActuator, m_framepropname), + KX_PYATTRIBUTE_STRING_RW("propName", 0, MAX_PROP_NAME, false, KX_IpoActuator, m_propname), + KX_PYATTRIBUTE_STRING_RW("framePropName", 0, MAX_PROP_NAME, false, KX_IpoActuator, m_framepropname), KX_PYATTRIBUTE_INT_RW("mode", KX_ACT_IPO_NODEF+1, KX_ACT_IPO_MAX-1, true, KX_IpoActuator, m_type), KX_PYATTRIBUTE_BOOL_RW("useIpoAsForce", KX_IpoActuator, m_ipo_as_force), KX_PYATTRIBUTE_BOOL_RW("useIpoAdd", KX_IpoActuator, m_ipo_add), diff -Nru blender-2.61/source/gameengine/Ketsji/KX_IPO_SGController.cpp blender-2.62/source/gameengine/Ketsji/KX_IPO_SGController.cpp --- blender-2.61/source/gameengine/Ketsji/KX_IPO_SGController.cpp 2011-12-13 19:47:26.000000000 +0000 +++ blender-2.62/source/gameengine/Ketsji/KX_IPO_SGController.cpp 2012-02-15 19:31:53.000000000 +0000 @@ -145,7 +145,8 @@ } //modifies position? - if (m_ipo_channels_active[OB_LOC_X] || m_ipo_channels_active[OB_LOC_Y] || m_ipo_channels_active[OB_LOC_Z] || m_ipo_channels_active[OB_DLOC_X] || m_ipo_channels_active[OB_DLOC_Y] || m_ipo_channels_active[OB_DLOC_Z]) + if (m_ipo_channels_active[OB_LOC_X] || m_ipo_channels_active[OB_LOC_Y] || m_ipo_channels_active[OB_LOC_Z] || + m_ipo_channels_active[OB_DLOC_X] || m_ipo_channels_active[OB_DLOC_Y] || m_ipo_channels_active[OB_DLOC_Z]) { if (m_ipo_as_force == true) { @@ -198,7 +199,9 @@ } } //modifies orientation? - if (m_ipo_channels_active[OB_ROT_X] || m_ipo_channels_active[OB_ROT_Y] || m_ipo_channels_active[OB_ROT_Z] || m_ipo_channels_active[OB_DROT_X] || m_ipo_channels_active[OB_DROT_Y] || m_ipo_channels_active[OB_DROT_Z]) { + if (m_ipo_channels_active[OB_ROT_X] || m_ipo_channels_active[OB_ROT_Y] || m_ipo_channels_active[OB_ROT_Z] || + m_ipo_channels_active[OB_DROT_X] || m_ipo_channels_active[OB_DROT_Y] || m_ipo_channels_active[OB_DROT_Z]) + { if (m_ipo_as_force) { if (m_game_object && ob) { @@ -293,7 +296,9 @@ } } //modifies scale? - if (m_ipo_channels_active[OB_SIZE_X] || m_ipo_channels_active[OB_SIZE_Y] || m_ipo_channels_active[OB_SIZE_Z] || m_ipo_channels_active[OB_DSIZE_X] || m_ipo_channels_active[OB_DSIZE_Y] || m_ipo_channels_active[OB_DSIZE_Z]) { + if (m_ipo_channels_active[OB_SIZE_X] || m_ipo_channels_active[OB_SIZE_Y] || m_ipo_channels_active[OB_SIZE_Z] || + m_ipo_channels_active[OB_DSIZE_X] || m_ipo_channels_active[OB_DSIZE_Y] || m_ipo_channels_active[OB_DSIZE_Z]) + { //default is no scale change MT_Vector3 newScale(1.0,1.0,1.0); if (!m_ipo_add) diff -Nru blender-2.61/source/gameengine/Ketsji/KX_KetsjiEngine.cpp blender-2.62/source/gameengine/Ketsji/KX_KetsjiEngine.cpp --- blender-2.61/source/gameengine/Ketsji/KX_KetsjiEngine.cpp 2011-12-13 19:47:26.000000000 +0000 +++ blender-2.62/source/gameengine/Ketsji/KX_KetsjiEngine.cpp 2012-02-15 19:31:53.000000000 +0000 @@ -110,6 +110,7 @@ double KX_KetsjiEngine::m_suspendeddelta = 0.0; double KX_KetsjiEngine::m_average_framerate = 0.0; bool KX_KetsjiEngine::m_restrict_anim_fps = false; +short KX_KetsjiEngine::m_exitkey = 130; //ESC Key /** @@ -1857,6 +1858,16 @@ return m_average_framerate; } +void KX_KetsjiEngine::SetExitKey(short key) +{ + m_exitkey = key; +} + +short KX_KetsjiEngine::GetExitKey() +{ + return m_exitkey; +} + void KX_KetsjiEngine::SetTimingDisplay(bool frameRate, bool profile, bool properties) { m_show_framerate = frameRate; diff -Nru blender-2.61/source/gameengine/Ketsji/KX_KetsjiEngine.h blender-2.62/source/gameengine/Ketsji/KX_KetsjiEngine.h --- blender-2.61/source/gameengine/Ketsji/KX_KetsjiEngine.h 2011-12-13 19:47:26.000000000 +0000 +++ blender-2.62/source/gameengine/Ketsji/KX_KetsjiEngine.h 2012-02-15 19:31:53.000000000 +0000 @@ -124,6 +124,8 @@ static double m_suspendedtime; static double m_suspendeddelta; + static short m_exitkey; /* Key used to exit the BGE */ + int m_exitcode; STR_String m_exitstring; /** @@ -352,6 +354,10 @@ */ static double GetAverageFrameRate(); + static void SetExitKey(short key); + + static short GetExitKey(); + /** * Activates or deactivates timing information display. * @param frameRate Display for frame rate on or off. diff -Nru blender-2.61/source/gameengine/Ketsji/KX_MeshProxy.cpp blender-2.62/source/gameengine/Ketsji/KX_MeshProxy.cpp --- blender-2.61/source/gameengine/Ketsji/KX_MeshProxy.cpp 2011-12-13 19:47:26.000000000 +0000 +++ blender-2.62/source/gameengine/Ketsji/KX_MeshProxy.cpp 2012-02-15 19:31:53.000000000 +0000 @@ -247,12 +247,14 @@ return materials; } -PyObject * KX_MeshProxy::pyattr_get_numMaterials(void * selfv, const KX_PYATTRIBUTE_DEF * attrdef) { +PyObject * KX_MeshProxy::pyattr_get_numMaterials(void * selfv, const KX_PYATTRIBUTE_DEF * attrdef) +{ KX_MeshProxy * self = static_cast (selfv); return PyLong_FromSsize_t(self->m_meshobj->NumMaterials()); } -PyObject * KX_MeshProxy::pyattr_get_numPolygons(void * selfv, const KX_PYATTRIBUTE_DEF * attrdef) { +PyObject * KX_MeshProxy::pyattr_get_numPolygons(void * selfv, const KX_PYATTRIBUTE_DEF * attrdef) +{ KX_MeshProxy * self = static_cast (selfv); return PyLong_FromSsize_t(self->m_meshobj->NumPolygons()); } diff -Nru blender-2.61/source/gameengine/Ketsji/KX_NavMeshObject.cpp blender-2.62/source/gameengine/Ketsji/KX_NavMeshObject.cpp --- blender-2.61/source/gameengine/Ketsji/KX_NavMeshObject.cpp 2011-12-13 19:47:26.000000000 +0000 +++ blender-2.62/source/gameengine/Ketsji/KX_NavMeshObject.cpp 2012-02-15 19:31:53.000000000 +0000 @@ -248,7 +248,7 @@ } //create tris - polys = new unsigned short[npolys*3*2]; + polys = (unsigned short*)MEM_callocN(sizeof(unsigned short)*3*2*npolys, "BuildVertIndArrays polys"); memset(polys, 0xff, sizeof(unsigned short)*3*2*npolys); unsigned short *poly = polys; RAS_Polygon* raspoly; diff -Nru blender-2.61/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp blender-2.62/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp --- blender-2.61/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp 2011-12-13 19:47:21.000000000 +0000 +++ blender-2.62/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp 2012-02-15 19:31:50.000000000 +0000 @@ -129,7 +129,7 @@ }; PyAttributeDef KX_NetworkMessageActuator::Attributes[] = { - KX_PYATTRIBUTE_STRING_RW("propName", 0, 100, false, KX_NetworkMessageActuator, m_toPropName), + KX_PYATTRIBUTE_STRING_RW("propName", 0, MAX_PROP_NAME, false, KX_NetworkMessageActuator, m_toPropName), KX_PYATTRIBUTE_STRING_RW("subject", 0, 100, false, KX_NetworkMessageActuator, m_subject), KX_PYATTRIBUTE_BOOL_RW("usePropBody", KX_NetworkMessageActuator, m_bPropBody), KX_PYATTRIBUTE_STRING_RW("body", 0, 16384, false, KX_NetworkMessageActuator, m_body), diff -Nru blender-2.61/source/gameengine/Ketsji/KX_PyMath.h blender-2.62/source/gameengine/Ketsji/KX_PyMath.h --- blender-2.61/source/gameengine/Ketsji/KX_PyMath.h 2011-12-13 19:47:26.000000000 +0000 +++ blender-2.62/source/gameengine/Ketsji/KX_PyMath.h 2012-02-15 19:31:53.000000000 +0000 @@ -65,32 +65,59 @@ { bool noerror = true; mat.setIdentity(); + + +#ifdef USE_MATHUTILS + + if (MatrixObject_Check(pymat)) + { + MatrixObject *pymatrix = (MatrixObject *)pymat; + + if (BaseMath_ReadCallback(pymatrix) == -1) + return false; + + if (pymatrix->num_col != Size(mat) || pymatrix->num_row != Size(mat)) + return false; + + for (unsigned int row = 0; row < Size(mat); row++) + { + for (unsigned int col = 0; col < Size(mat); col++) + { + mat[row][col] = *(pymatrix->matrix + col * pymatrix->num_row + row); + } + } + } + else + +#endif /* USE_MATHUTILS */ + + if (PySequence_Check(pymat)) { - unsigned int cols = PySequence_Size(pymat); - if (cols != Size(mat)) + unsigned int rows = PySequence_Size(pymat); + if (rows != Size(mat)) return false; - for (unsigned int x = 0; noerror && x < cols; x++) + for (unsigned int row = 0; noerror && row < rows; row++) { - PyObject *pycol = PySequence_GetItem(pymat, x); /* new ref */ - if (!PyErr_Occurred() && PySequence_Check(pycol)) + PyObject *pyrow = PySequence_GetItem(pymat, row); /* new ref */ + if (!PyErr_Occurred() && PySequence_Check(pyrow)) { - unsigned int rows = PySequence_Size(pycol); - if (rows != Size(mat)) + unsigned int cols = PySequence_Size(pyrow); + if (cols != Size(mat)) noerror = false; else { - for( unsigned int y = 0; y < rows; y++) + for( unsigned int col = 0; col < cols; col++) { - PyObject *item = PySequence_GetItem(pycol, y); /* new ref */ - mat[y][x] = PyFloat_AsDouble(item); + PyObject *item = PySequence_GetItem(pyrow, col); /* new ref */ + mat[row][col] = PyFloat_AsDouble(item); Py_DECREF(item); } } } else noerror = false; - Py_DECREF(pycol); + Py_DECREF(pyrow); } } else noerror = false; diff -Nru blender-2.61/source/gameengine/Ketsji/KX_PythonInit.cpp blender-2.62/source/gameengine/Ketsji/KX_PythonInit.cpp --- blender-2.61/source/gameengine/Ketsji/KX_PythonInit.cpp 2011-12-13 19:47:26.000000000 +0000 +++ blender-2.62/source/gameengine/Ketsji/KX_PythonInit.cpp 2012-02-15 19:31:53.000000000 +0000 @@ -47,6 +47,12 @@ #undef _XOPEN_SOURCE #endif +#if defined(__sun) || defined(sun) +#if defined(_XPG4) +#undef _XPG4 +#endif +#endif + #include extern "C" { @@ -419,6 +425,20 @@ return PyFloat_FromDouble(KX_KetsjiEngine::GetTicRate()); } +static PyObject* gPySetExitKey(PyObject*, PyObject* args) +{ + short exitkey; + if (!PyArg_ParseTuple(args, "h:setExitKey", &exitkey)) + return NULL; + KX_KetsjiEngine::SetExitKey(exitkey); + Py_RETURN_NONE; +} + +static PyObject* gPyGetExitKey(PyObject*) +{ + return PyLong_FromSsize_t(KX_KetsjiEngine::GetExitKey()); +} + static PyObject* gPySetMaxLogicFrame(PyObject*, PyObject* args) { int frame; @@ -812,6 +832,8 @@ {"setLogicTicRate", (PyCFunction) gPySetLogicTicRate, METH_VARARGS, (const char *)"Sets the logic tic rate"}, {"getPhysicsTicRate", (PyCFunction) gPyGetPhysicsTicRate, METH_NOARGS, (const char *)"Gets the physics tic rate"}, {"setPhysicsTicRate", (PyCFunction) gPySetPhysicsTicRate, METH_VARARGS, (const char *)"Sets the physics tic rate"}, + {"getExitKey", (PyCFunction) gPyGetExitKey, METH_NOARGS, (const char *)"Gets the key used to exit the game engine"}, + {"setExitKey", (PyCFunction) gPySetExitKey, METH_VARARGS, (const char *)"Sets the key used to exit the game engine"}, {"getAverageFrameRate", (PyCFunction) gPyGetAverageFrameRate, METH_NOARGS, (const char *)"Gets the estimated average frame rate"}, {"getBlendFileList", (PyCFunction)gPyGetBlendFileList, METH_VARARGS, (const char *)"Gets a list of blend files in the same directory as the current blend file"}, {"PrintGLInfo", (PyCFunction)pyPrintExt, METH_NOARGS, (const char *)"Prints GL Extension Info"}, @@ -1266,6 +1288,16 @@ Py_RETURN_NONE; } +static PyObject* gPySetWindowSize(PyObject*, PyObject* args) +{ + int width, height; + if (!PyArg_ParseTuple(args, "ii:resize", &width, &height)) + return NULL; + + gp_Canvas->ResizeWindow(width, height); + Py_RETURN_NONE; +} + static struct PyMethodDef rasterizer_methods[] = { {"getWindowWidth",(PyCFunction) gPyGetWindowWidth, METH_VARARGS, "getWindowWidth doc"}, @@ -1307,6 +1339,7 @@ METH_VARARGS, "get the anisotropic filtering level"}, {"drawLine", (PyCFunction) gPyDrawLine, METH_VARARGS, "draw a line on the screen"}, + {"setWindowSize", (PyCFunction) gPySetWindowSize, METH_VARARGS, ""}, { NULL, (PyCFunction) NULL, 0, NULL } }; @@ -1424,15 +1457,7 @@ KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_LOCAL, KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCAL); KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_DOROTFH, KX_ConstraintActuator::KX_ACT_CONSTRAINT_DOROTFH); - /* 4. Ipo actuator, simple part */ - KX_MACRO_addTypesToDict(d, KX_IPOACT_PLAY, KX_IpoActuator::KX_ACT_IPO_PLAY); - KX_MACRO_addTypesToDict(d, KX_IPOACT_PINGPONG, KX_IpoActuator::KX_ACT_IPO_PINGPONG); - KX_MACRO_addTypesToDict(d, KX_IPOACT_FLIPPER, KX_IpoActuator::KX_ACT_IPO_FLIPPER); - KX_MACRO_addTypesToDict(d, KX_IPOACT_LOOPSTOP, KX_IpoActuator::KX_ACT_IPO_LOOPSTOP); - KX_MACRO_addTypesToDict(d, KX_IPOACT_LOOPEND, KX_IpoActuator::KX_ACT_IPO_LOOPEND); - KX_MACRO_addTypesToDict(d, KX_IPOACT_FROM_PROP,KX_IpoActuator::KX_ACT_IPO_FROM_PROP); - - /* 5. Random distribution types */ + /* 4. Random distribution types */ KX_MACRO_addTypesToDict(d, KX_RANDOMACT_BOOL_CONST, SCA_RandomActuator::KX_RANDOMACT_BOOL_CONST); KX_MACRO_addTypesToDict(d, KX_RANDOMACT_BOOL_UNIFORM, SCA_RandomActuator::KX_RANDOMACT_BOOL_UNIFORM); KX_MACRO_addTypesToDict(d, KX_RANDOMACT_BOOL_BERNOUILLI, SCA_RandomActuator::KX_RANDOMACT_BOOL_BERNOUILLI); @@ -1444,7 +1469,7 @@ KX_MACRO_addTypesToDict(d, KX_RANDOMACT_FLOAT_NORMAL, SCA_RandomActuator::KX_RANDOMACT_FLOAT_NORMAL); KX_MACRO_addTypesToDict(d, KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL, SCA_RandomActuator::KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL); - /* 6. Sound actuator */ + /* 5. Sound actuator */ KX_MACRO_addTypesToDict(d, KX_SOUNDACT_PLAYSTOP, KX_SoundActuator::KX_SOUNDACT_PLAYSTOP); KX_MACRO_addTypesToDict(d, KX_SOUNDACT_PLAYEND, KX_SoundActuator::KX_SOUNDACT_PLAYEND); KX_MACRO_addTypesToDict(d, KX_SOUNDACT_LOOPSTOP, KX_SoundActuator::KX_SOUNDACT_LOOPSTOP); @@ -1452,7 +1477,7 @@ KX_MACRO_addTypesToDict(d, KX_SOUNDACT_LOOPBIDIRECTIONAL, KX_SoundActuator::KX_SOUNDACT_LOOPBIDIRECTIONAL); KX_MACRO_addTypesToDict(d, KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP, KX_SoundActuator::KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP); - /* 7. Action actuator */ + /* 6. Action actuator */ KX_MACRO_addTypesToDict(d, KX_ACTIONACT_PLAY, ACT_ACTION_PLAY); KX_MACRO_addTypesToDict(d, KX_ACTIONACT_PINGPONG, ACT_ACTION_PINGPONG); KX_MACRO_addTypesToDict(d, KX_ACTIONACT_FLIPPER, ACT_ACTION_FLIPPER); @@ -1460,7 +1485,7 @@ KX_MACRO_addTypesToDict(d, KX_ACTIONACT_LOOPEND, ACT_ACTION_LOOP_END); KX_MACRO_addTypesToDict(d, KX_ACTIONACT_PROPERTY, ACT_ACTION_FROM_PROP); - /*8. GL_BlendFunc */ + /* 7. GL_BlendFunc */ KX_MACRO_addTypesToDict(d, BL_ZERO, GL_ZERO); KX_MACRO_addTypesToDict(d, BL_ONE, GL_ONE); KX_MACRO_addTypesToDict(d, BL_SRC_COLOR, GL_SRC_COLOR); @@ -1474,7 +1499,7 @@ KX_MACRO_addTypesToDict(d, BL_SRC_ALPHA_SATURATE, GL_SRC_ALPHA_SATURATE); - /* 9. UniformTypes */ + /* 8. UniformTypes */ KX_MACRO_addTypesToDict(d, SHD_TANGENT, BL_Shader::SHD_TANGENT); KX_MACRO_addTypesToDict(d, MODELVIEWMATRIX, BL_Shader::MODELVIEWMATRIX); KX_MACRO_addTypesToDict(d, MODELVIEWMATRIX_TRANSPOSE, BL_Shader::MODELVIEWMATRIX_TRANSPOSE); @@ -1491,7 +1516,7 @@ KX_MACRO_addTypesToDict(d, CAM_POS, BL_Shader::CAM_POS); KX_MACRO_addTypesToDict(d, CONSTANT_TIMER, BL_Shader::CONSTANT_TIMER); - /* 10 state actuator */ + /* 9. state actuator */ KX_MACRO_addTypesToDict(d, KX_STATE1, (1<<0)); KX_MACRO_addTypesToDict(d, KX_STATE2, (1<<1)); KX_MACRO_addTypesToDict(d, KX_STATE3, (1<<2)); @@ -1855,6 +1880,14 @@ Py_DECREF(mod); } +#ifdef WITH_AUDASPACE + /* accessing a SoundActuator's sound results in a crash if aud is not initialised... */ + { + PyObject *mod= PyImport_ImportModuleLevel((char *)"aud", NULL, NULL, NULL, 0); + Py_DECREF(mod); + } +#endif + initPyTypes(); bpy_import_main_set(maggie); @@ -1899,6 +1932,14 @@ Py_NoSiteFlag=1; Py_FrozenFlag=1; +#ifdef WITH_AUDASPACE + /* accessing a SoundActuator's sound results in a crash if aud is not initialised... */ + { + PyObject *mod= PyImport_ImportModuleLevel((char *)"aud", NULL, NULL, NULL, 0); + Py_DECREF(mod); + } +#endif + initPyTypes(); bpy_import_main_set(maggie); @@ -1950,7 +1991,15 @@ initVideoTexture(); /* could be done a lot more nicely, but for now a quick way to get bge.* working */ - PyRun_SimpleString("sys = __import__('sys');mod = sys.modules['bge'] = type(sys)('bge');mod.__dict__.update({'logic':__import__('GameLogic'), 'render':__import__('Rasterizer'), 'events':__import__('GameKeys'), 'constraints':__import__('PhysicsConstraints'), 'types':__import__('GameTypes'), 'texture':__import__('VideoTexture')});"); + PyRun_SimpleString("sys = __import__('sys');" + "mod = sys.modules['bge'] = type(sys)('bge');" + "mod.__dict__.update({'logic':__import__('GameLogic'), " + "'render':__import__('Rasterizer'), " + "'events':__import__('GameKeys'), " + "'constraints':__import__('PhysicsConstraints'), " + "'types':__import__('GameTypes'), " + "'texture':__import__('VideoTexture')});" + ); } static struct PyModuleDef Rasterizer_module_def = { diff -Nru blender-2.61/source/gameengine/Ketsji/KX_RaySensor.cpp blender-2.62/source/gameengine/Ketsji/KX_RaySensor.cpp --- blender-2.61/source/gameengine/Ketsji/KX_RaySensor.cpp 2011-12-13 19:47:26.000000000 +0000 +++ blender-2.62/source/gameengine/Ketsji/KX_RaySensor.cpp 2012-02-15 19:31:53.000000000 +0000 @@ -352,7 +352,7 @@ KX_PYATTRIBUTE_BOOL_RW("useMaterial", KX_RaySensor, m_bFindMaterial), KX_PYATTRIBUTE_BOOL_RW("useXRay", KX_RaySensor, m_bXRay), KX_PYATTRIBUTE_FLOAT_RW("range", 0, 10000, KX_RaySensor, m_distance), - KX_PYATTRIBUTE_STRING_RW("propName", 0, 100, false, KX_RaySensor, m_propertyname), + KX_PYATTRIBUTE_STRING_RW("propName", 0, MAX_PROP_NAME, false, KX_RaySensor, m_propertyname), KX_PYATTRIBUTE_INT_RW("axis", 0, 5, true, KX_RaySensor, m_axis), KX_PYATTRIBUTE_FLOAT_ARRAY_RO("hitPosition", KX_RaySensor, m_hitPosition, 3), KX_PYATTRIBUTE_FLOAT_ARRAY_RO("rayDirection", KX_RaySensor, m_rayDirection, 3), diff -Nru blender-2.61/source/gameengine/Ketsji/KX_SceneActuator.cpp blender-2.62/source/gameengine/Ketsji/KX_SceneActuator.cpp --- blender-2.61/source/gameengine/Ketsji/KX_SceneActuator.cpp 2011-12-13 19:47:26.000000000 +0000 +++ blender-2.62/source/gameengine/Ketsji/KX_SceneActuator.cpp 2012-02-15 19:31:53.000000000 +0000 @@ -249,7 +249,7 @@ }; PyAttributeDef KX_SceneActuator::Attributes[] = { - KX_PYATTRIBUTE_STRING_RW("scene",0,32,true,KX_SceneActuator,m_nextSceneName), + KX_PYATTRIBUTE_STRING_RW("scene",0,MAX_ID_NAME-2,true,KX_SceneActuator,m_nextSceneName), KX_PYATTRIBUTE_RW_FUNCTION("camera",KX_SceneActuator,pyattr_get_camera,pyattr_set_camera), KX_PYATTRIBUTE_BOOL_RW("useRestart", KX_SceneActuator, m_restart), KX_PYATTRIBUTE_INT_RW("mode", KX_SCENE_NODEF+1, KX_SCENE_MAX-1, true, KX_SceneActuator, m_mode), diff -Nru blender-2.61/source/gameengine/Ketsji/KX_Scene.h blender-2.62/source/gameengine/Ketsji/KX_Scene.h --- blender-2.61/source/gameengine/Ketsji/KX_Scene.h 2011-12-13 19:47:26.000000000 +0000 +++ blender-2.62/source/gameengine/Ketsji/KX_Scene.h 2012-02-15 19:31:53.000000000 +0000 @@ -617,7 +617,7 @@ static PyObject* pyattr_get_drawing_callback_post(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_drawing_callback_post(void *selv_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); - virtual PyObject* py_repr(void) { return PyUnicode_FromString(GetName().ReadPtr()); } + virtual PyObject* py_repr(void) { return PyUnicode_From_STR_String(GetName()); } /* getitem/setitem */ static PyMappingMethods Mapping; diff -Nru blender-2.61/source/gameengine/Ketsji/KX_TouchSensor.cpp blender-2.62/source/gameengine/Ketsji/KX_TouchSensor.cpp --- blender-2.61/source/gameengine/Ketsji/KX_TouchSensor.cpp 2011-12-13 19:47:26.000000000 +0000 +++ blender-2.62/source/gameengine/Ketsji/KX_TouchSensor.cpp 2012-02-15 19:31:53.000000000 +0000 @@ -55,7 +55,8 @@ } -void KX_TouchSensor::EndFrame() { +void KX_TouchSensor::EndFrame() +{ m_colliders->ReleaseAndRemoveAll(); m_hitObject = NULL; m_bTriggered = false; @@ -320,7 +321,7 @@ }; PyAttributeDef KX_TouchSensor::Attributes[] = { - KX_PYATTRIBUTE_STRING_RW("propName",0,100,false,KX_TouchSensor,m_touchedpropname), + KX_PYATTRIBUTE_STRING_RW("propName",0,MAX_PROP_NAME,false,KX_TouchSensor,m_touchedpropname), KX_PYATTRIBUTE_BOOL_RW("useMaterial",KX_TouchSensor,m_bFindMaterial), KX_PYATTRIBUTE_BOOL_RW("usePulseCollision",KX_TouchSensor,m_bTouchPulse), KX_PYATTRIBUTE_RO_FUNCTION("hitObject", KX_TouchSensor, pyattr_get_object_hit), diff -Nru blender-2.61/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp blender-2.62/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp --- blender-2.61/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp 2011-12-13 19:46:23.000000000 +0000 +++ blender-2.62/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp 2012-02-15 19:30:45.000000000 +0000 @@ -231,6 +231,8 @@ if (trimeshshape->getMeshInterface()->getNumSubParts()==1) { unsigned char* vertexBase; + btScalar* scaledVertexBase; + btVector3 localScaling; PHY_ScalarType vertexType; int numverts; int vertexstride; @@ -238,8 +240,16 @@ int indexstride; PHY_ScalarType indexType; trimeshshape->getMeshInterface()->getLockedVertexIndexBase(&vertexBase,numverts,vertexType,vertexstride,&indexbase,indexstride,numtris,indexType); - - psb = btSoftBodyHelpers::CreateFromTriMesh(worldInfo,(const btScalar*)vertexBase,(const int*)indexbase,numtris,false); + localScaling = scaledtrimeshshape->getLocalScaling(); + scaledVertexBase = new btScalar[numverts*3]; + for (int i=0; i +extern "C" { +# include "BKE_deform.h" +} + /* polygon sorting */ struct RAS_MeshObject::polygonSlot @@ -573,8 +577,8 @@ { KeyBlock *kb; int kbindex, defindex; - MDeformVert *dvert= NULL; - int totvert, i, j; + MDeformVert *dv= NULL; + int totvert, i; float *weights; if (!m_mesh->key) @@ -598,19 +602,15 @@ kb->weights = NULL; } - dvert= m_mesh->dvert; + dv= m_mesh->dvert; totvert= m_mesh->totvert; - weights= (float*)MEM_callocN(totvert*sizeof(float), "weights"); + weights= (float*)MEM_mallocN(totvert*sizeof(float), "weights"); - for (i=0; i < totvert; i++, dvert++) { - for(j=0; jtotweight; j++) { - if (dvert->dw[j].def_nr == defindex) { - weights[i]= dvert->dw[j].weight; - break; - } - } + for (i=0; i < totvert; i++, dv++) { + weights[i]= defvert_find_weight(dv, defindex); } + kb->weights = weights; m_cacheWeightIndex[kbindex] = defindex; } diff -Nru blender-2.61/source/gameengine/Rasterizer/RAS_TexVert.cpp blender-2.62/source/gameengine/Rasterizer/RAS_TexVert.cpp --- blender-2.61/source/gameengine/Rasterizer/RAS_TexVert.cpp 2011-12-13 19:47:33.000000000 +0000 +++ blender-2.62/source/gameengine/Rasterizer/RAS_TexVert.cpp 2012-02-15 19:32:00.000000000 +0000 @@ -104,7 +104,7 @@ void RAS_TexVert::SetUnit(const unsigned int u) { - m_unit = u<=MAX_UNIT?u:MAX_UNIT; + m_unit = u <= (unsigned int) MAX_UNIT ? u: (unsigned int)MAX_UNIT; } void RAS_TexVert::SetNormal(const MT_Vector3& normal) diff -Nru blender-2.61/source/gameengine/VideoTexture/blendVideoTex.cpp blender-2.62/source/gameengine/VideoTexture/blendVideoTex.cpp --- blender-2.61/source/gameengine/VideoTexture/blendVideoTex.cpp 2011-12-13 19:47:10.000000000 +0000 +++ blender-2.62/source/gameengine/VideoTexture/blendVideoTex.cpp 2012-02-15 19:31:32.000000000 +0000 @@ -38,6 +38,7 @@ //#include "TexPlayerGL.h" #include "ImageBase.h" +#include "VideoBase.h" #include "FilterBase.h" #include "Texture.h" @@ -208,6 +209,11 @@ Py_INCREF(&TextureType); PyModule_AddObject(m, (char*)"Texture", (PyObject*)&TextureType); + PyModule_AddIntConstant(m, (char*)"SOURCE_ERROR", SourceError); + PyModule_AddIntConstant(m, (char*)"SOURCE_EMPTY", SourceEmpty); + PyModule_AddIntConstant(m, (char*)"SOURCE_READY", SourceReady); + PyModule_AddIntConstant(m, (char*)"SOURCE_PLAYING", SourcePlaying); + PyModule_AddIntConstant(m, (char*)"SOURCE_STOPPED", SourceStopped); // init last error description Exception::m_lastError = ""; diff -Nru blender-2.61/source/gameengine/VideoTexture/ImageViewport.cpp blender-2.62/source/gameengine/VideoTexture/ImageViewport.cpp --- blender-2.61/source/gameengine/VideoTexture/ImageViewport.cpp 2011-12-13 19:47:10.000000000 +0000 +++ blender-2.62/source/gameengine/VideoTexture/ImageViewport.cpp 2012-02-15 19:31:32.000000000 +0000 @@ -31,6 +31,7 @@ #include "GL/glew.h" +#include "KX_PythonInit.h" #include "Texture.h" #include "ImageBase.h" #include "FilterSource.h" @@ -41,7 +42,13 @@ ImageViewport::ImageViewport (void) : m_alpha(false), m_texInit(false) { // get viewport rectangle - glGetIntegerv(GL_VIEWPORT, m_viewport); + RAS_Rect rect = KX_GetActiveEngine()->GetCanvas()->GetWindowArea(); + m_viewport[0] = rect.GetLeft(); + m_viewport[1] = rect.GetBottom(); + m_viewport[2] = rect.GetWidth(); + m_viewport[3] = rect.GetHeight(); + + //glGetIntegerv(GL_VIEWPORT, m_viewport); // create buffer for viewport image m_viewportImage = new BYTE [4 * getViewportSize()[0] * getViewportSize()[1]]; // set attributes diff -Nru blender-2.61/source/tests/bl_mesh_modifiers.py blender-2.62/source/tests/bl_mesh_modifiers.py --- blender-2.61/source/tests/bl_mesh_modifiers.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/source/tests/bl_mesh_modifiers.py 2012-02-15 19:32:05.000000000 +0000 @@ -0,0 +1,866 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the 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. +# +# ##### END GPL LICENSE BLOCK ##### + +# + +# Currently this script only generates images from different modifier +# combinations and does not validate they work correctly, +# this is because we dont get 1:1 match with bmesh. +# +# Later, we may have a way to check the results are valid. + + +# ./blender.bin --factory-startup --python source/tests/bl_mesh_modifiers.py +# + +import math + +USE_QUICK_RENDER = False +IS_BMESH = hasattr(__import__("bpy").types, "LoopColors") + +# ----------------------------------------------------------------------------- +# utility funcs + + +def render_gl(context, filepath, shade): + + def ctx_viewport_shade(context, shade): + for area in context.window.screen.areas: + if area.type == 'VIEW_3D': + space = area.spaces.active + # rv3d = space.region_3d + space.viewport_shade = shade + + import bpy + scene = context.scene + render = scene.render + render.filepath = filepath + render.image_settings.file_format = 'PNG' + render.image_settings.color_mode = 'RGB' + render.use_file_extension = True + render.use_antialiasing = False + + # render size + render.resolution_percentage = 100 + render.resolution_x = 512 + render.resolution_y = 512 + + ctx_viewport_shade(context, shade) + + #~ # stop to inspect! + #~ if filepath == "test_cube_shell_solidify_subsurf_wp_wire": + #~ assert(0) + #~ else: + #~ return + + bpy.ops.render.opengl(write_still=True, + view_context=True) + + +def render_gl_all_modes(context, obj, filepath=""): + + assert(obj is not None) + assert(filepath != "") + + scene = context.scene + + # avoid drawing outline/center dot + bpy.ops.object.select_all(action='DESELECT') + scene.objects.active = None + + # editmode + scene.tool_settings.mesh_select_mode = False, True, False + + # render + render_gl(context, filepath + "_ob_solid", shade='SOLID') + + if USE_QUICK_RENDER: + return + + render_gl(context, filepath + "_ob_wire", shade='WIREFRAME') + render_gl(context, filepath + "_ob_textured", shade='TEXTURED') + + # ------------------------------------------------------------------------- + # not just draw modes, but object modes! + scene.objects.active = obj + + bpy.ops.object.mode_set(mode='EDIT', toggle=False) + bpy.ops.mesh.select_all(action='DESELECT') + render_gl(context, filepath + "_edit_wire", shade='WIREFRAME') + render_gl(context, filepath + "_edit_solid", shade='SOLID') + render_gl(context, filepath + "_edit_textured", shade='TEXTURED') + bpy.ops.object.mode_set(mode='OBJECT', toggle=False) + + bpy.ops.object.mode_set(mode='WEIGHT_PAINT', toggle=False) + + render_gl(context, filepath + "_wp_wire", shade='WIREFRAME') + + assert(1) + + bpy.ops.object.mode_set(mode='OBJECT', toggle=False) + + scene.objects.active = None + + +def ctx_clear_scene(): # copied from batch_import.py + import bpy + unique_obs = set() + for scene in bpy.data.scenes: + for obj in scene.objects[:]: + scene.objects.unlink(obj) + unique_obs.add(obj) + + # remove obdata, for now only worry about the startup scene + for bpy_data_iter in (bpy.data.objects, + bpy.data.meshes, + bpy.data.lamps, + bpy.data.cameras, + ): + + for id_data in bpy_data_iter: + bpy_data_iter.remove(id_data) + + +def ctx_viewport_camera(context): + # because gl render without view_context has no shading option. + for area in context.window.screen.areas: + if area.type == 'VIEW_3D': + space = area.spaces.active + space.region_3d.view_perspective = 'CAMERA' + + +def ctx_camera_setup(context, + location=(0.0, 0.0, 0.0), + lookat=(0.0, 0.0, 0.0), + # most likely the followuing vars can be left as defaults + up=(0.0, 0.0, 1.0), + lookat_axis='-Z', + up_axis='Y', + ): + + camera = bpy.data.cameras.new(whoami()) + obj = bpy.data.objects.new(whoami(), camera) + + scene = context.scene + scene.objects.link(obj) + scene.camera = obj + + from mathutils import Vector, Matrix + + # setup transform + view_vec = Vector(lookat) - Vector(location) + rot_mat = view_vec.to_track_quat(lookat_axis, up_axis).to_matrix().to_4x4() + tra_mat = Matrix.Translation(location) + + obj.matrix_world = tra_mat * rot_mat + + ctx_viewport_camera(context) + + return obj + + +# ----------------------------------------------------------------------------- +# inspect functions + +import inspect + + +# functions + +def whoami(): + return inspect.stack()[1][3] + + +def whosdaddy(): + return inspect.stack()[2][3] + + +# ----------------------------------------------------------------------------- +# models (defaults) + +def defaults_object(obj): + obj.show_wire = True + + if obj.type == 'MESH': + mesh = obj.data + mesh.show_all_edges = True + + mesh.show_normal_vertex = True + + # lame! + if IS_BMESH: + for poly in mesh.polygons: + poly.use_smooth = True + else: + for face in mesh.faces: + face.use_smooth = True + + +def defaults_modifier(mod): + mod.show_in_editmode = True + mod.show_on_cage = True + + +# ----------------------------------------------------------------------------- +# models (utils) + + +if IS_BMESH: + def mesh_bmesh_poly_elems(poly, elems): + vert_start = poly.loop_start + vert_total = poly.loop_total + return elems[vert_start:vert_start + vert_total] + + def mesh_bmesh_poly_vertices(poly): + return [loop.vertex_index + for loop in mesh_bmesh_poly_elems(poly, poly.id_data.loops)] + + +def mesh_bounds(mesh): + xmin = ymin = zmin = +100000000.0 + xmax = ymax = zmax = -100000000.0 + + for v in mesh.vertices: + x, y, z = v.co + xmax = max(x, xmax) + ymax = max(y, ymax) + zmax = max(z, zmax) + + xmin = min(x, xmin) + ymin = min(y, ymin) + zmin = min(z, zmin) + + return (xmin, ymin, zmin), (xmax, ymax, zmax) + + +def mesh_uv_add(obj): + + uvs = ((0.0, 0.0), + (0.0, 1.0), + (1.0, 1.0), + (1.0, 0.0)) + + uv_lay = obj.data.uv_textures.new() + + if IS_BMESH: + # XXX, odd that we need to do this. until uvs and texface + # are separated we will need to keep it + uv_loops = obj.data.uv_loop_layers[-1] + uv_list = uv_loops.data[:] + for poly in obj.data.polygons: + poly_uvs = mesh_bmesh_poly_elems(poly, uv_list) + for i, c in enumerate(poly_uvs): + c.uv = uvs[i % 4] + else: + for uv in uv_lay.data: + uv.uv1 = uvs[0] + uv.uv2 = uvs[1] + uv.uv3 = uvs[2] + uv.uv4 = uvs[3] + + return uv_lay + + +def mesh_vcol_add(obj, mode=0): + + colors = ((0.0, 0.0, 0.0), # black + (1.0, 0.0, 0.0), # red + (0.0, 1.0, 0.0), # green + (0.0, 0.0, 1.0), # blue + (1.0, 1.0, 0.0), # yellow + (0.0, 1.0, 1.0), # cyan + (1.0, 0.0, 1.0), # magenta + (1.0, 1.0, 1.0), # white + ) + + def colors_get(i): + return colors[i % len(colors)] + + vcol_lay = obj.data.vertex_colors.new() + + mesh = obj.data + + if IS_BMESH: + col_list = vcol_lay.data[:] + for poly in mesh.polygons: + face_verts = mesh_bmesh_poly_vertices(poly) + poly_cols = mesh_bmesh_poly_elems(poly, col_list) + for i, c in enumerate(poly_cols): + c.color = colors_get(face_verts[i]) + else: + for i, col in enumerate(vcol_lay.data): + face_verts = mesh.faces[i].vertices + col.color1 = colors_get(face_verts[0]) + col.color2 = colors_get(face_verts[1]) + col.color3 = colors_get(face_verts[2]) + if len(face_verts) == 4: + col.color4 = colors_get(face_verts[3]) + + return vcol_lay + + +def mesh_vgroup_add(obj, name="Group", axis=0, invert=False, mode=0): + mesh = obj.data + vgroup = obj.vertex_groups.new(name=name) + vgroup.add(list(range(len(mesh.vertices))), 1.0, 'REPLACE') + group_index = len(obj.vertex_groups) - 1 + + min_bb, max_bb = mesh_bounds(mesh) + + range_axis = max_bb[axis] - min_bb[axis] + + # gradient + for v in mesh.vertices: + for vg in v.groups: + if vg.group == group_index: + f = (v.co[axis] - min_bb[axis]) / range_axis + vg.weight = 1.0 - f if invert else f + + return vgroup + + +def mesh_shape_add(obj, mode=0): + pass + + +def mesh_armature_add(obj, mode=0): + pass + + +# ----------------------------------------------------------------------------- +# modifiers + +def modifier_subsurf_add(scene, obj, levels=2): + mod = obj.modifiers.new(name=whoami(), type='SUBSURF') + defaults_modifier(mod) + + mod.levels = levels + mod.render_levels = levels + return mod + + +def modifier_armature_add(scene, obj): + mod = obj.modifiers.new(name=whoami(), type='ARMATURE') + defaults_modifier(mod) + + arm_data = bpy.data.armatures.new(whoami()) + obj_arm = bpy.data.objects.new(whoami(), arm_data) + + scene.objects.link(obj_arm) + + obj_arm.select = True + scene.objects.active = obj_arm + + bpy.ops.object.mode_set(mode='OBJECT', toggle=False) + bpy.ops.object.mode_set(mode='EDIT', toggle=False) + + # XXX, annoying, remove bone. + while arm_data.edit_bones: + obj_arm.edit_bones.remove(arm_data.edit_bones[-1]) + + bone_a = arm_data.edit_bones.new("Bone.A") + bone_b = arm_data.edit_bones.new("Bone.B") + bone_b.parent = bone_a + + bone_a.head = -1, 0, 0 + bone_a.tail = 0, 0, 0 + bone_b.head = 0, 0, 0 + bone_b.tail = 1, 0, 0 + + # Get armature animation data + bpy.ops.object.mode_set(mode='OBJECT', toggle=False) + + # 45d armature + obj_arm.pose.bones["Bone.B"].rotation_quaternion = 1, -0.5, 0, 0 + + # set back to the original + scene.objects.active = obj + + # display options + obj_arm.show_x_ray = True + arm_data.draw_type = 'STICK' + + # apply to modifier + mod.object = obj_arm + + mesh_vgroup_add(obj, name="Bone.A", axis=0, invert=True) + mesh_vgroup_add(obj, name="Bone.B", axis=0, invert=False) + + return mod + + +def modifier_mirror_add(scene, obj): + mod = obj.modifiers.new(name=whoami(), type='MIRROR') + defaults_modifier(mod) + + return mod + + +def modifier_solidify_add(scene, obj, thickness=0.25): + mod = obj.modifiers.new(name=whoami(), type='SOLIDIFY') + defaults_modifier(mod) + + mod.thickness = thickness + + return mod + + +def modifier_hook_add(scene, obj, use_vgroup=True): + scene.objects.active = obj + + # no nice way to add hooks from py api yet + # assume object mode, hook first face! + mesh = obj.data + + if use_vgroup: + for v in mesh.vertices: + v.select = True + else: + for v in mesh.vertices: + v.select = False + + if IS_BMESH: + face_verts = mesh_bmesh_poly_vertices(mesh.polygons[0]) + else: + face_verts = mesh.faces[0].vertices[:] + + for i in mesh.faces[0].vertices: + mesh.vertices[i].select = True + + bpy.ops.object.mode_set(mode='EDIT', toggle=False) + bpy.ops.object.hook_add_newob() + bpy.ops.object.mode_set(mode='OBJECT', toggle=False) + + # mod = obj.modifiers.new(name=whoami(), type='HOOK') + mod = obj.modifiers[-1] + defaults_modifier(mod) + + obj_hook = mod.object + obj_hook.rotation_euler = 0, math.radians(45), 0 + obj_hook.show_x_ray = True + + if use_vgroup: + mod.vertex_group = obj.vertex_groups[0].name + + return mod + + +def modifier_decimate_add(scene, obj): + mod = obj.modifiers.new(name=whoami(), type='DECIMATE') + defaults_modifier(mod) + + mod.ratio = 1 / 3 + + return mod + + +def modifier_build_add(scene, obj): + mod = obj.modifiers.new(name=whoami(), type='BUILD') + defaults_modifier(mod) + + # ensure we display some faces + if IS_BMESH: + totface = len(obj.data.polygons) + else: + totface = len(obj.data.faces) + + mod.frame_start = totface // 2 + mod.frame_duration = totface + + return mod + + +def modifier_mask_add(scene, obj): + mod = obj.modifiers.new(name=whoami(), type='MASK') + defaults_modifier(mod) + + mod.vertex_group = obj.vertex_groups[0].name + + return mod + + +# ----------------------------------------------------------------------------- +# models + +# useful since its solid boxy shape but simple enough to debug errors +cube_like_vertices = ( + (1, 1, -1), + (1, -1, -1), + (-1, -1, -1), + (-1, 1, -1), + (1, 1, 1), + (1, -1, 1), + (-1, -1, 1), + (-1, 1, 1), + (0, -1, -1), + (1, 0, -1), + (0, 1, -1), + (-1, 0, -1), + (1, 0, 1), + (0, -1, 1), + (-1, 0, 1), + (0, 1, 1), + (1, -1, 0), + (1, 1, 0), + (-1, -1, 0), + (-1, 1, 0), + (0, 0, -1), + (0, 0, 1), + (1, 0, 0), + (0, -1, 0), + (-1, 0, 0), + (2, 0, 0), + (2, 0, -1), + (2, 1, 0), + (2, 1, -1), + (0, 1, 2), + (0, 0, 2), + (-1, 0, 2), + (-1, 1, 2), + (-1, 0, 3), + (-1, 1, 3), + (0, 1, 3), + (0, 0, 3), + ) + + +cube_like_faces = ( + (0, 9, 20, 10), + (0, 10, 17), + (0, 17, 27, 28), + (1, 16, 23, 8), + (2, 18, 24, 11), + (3, 19, 10), + (4, 15, 21, 12), + (4, 17, 15), + (7, 14, 31, 32), + (7, 15, 19), + (8, 23, 18, 2), + (9, 0, 28, 26), + (9, 1, 8, 20), + (9, 22, 16, 1), + (10, 20, 11, 3), + (11, 24, 19, 3), + (12, 21, 13, 5), + (13, 6, 18), + (14, 21, 30, 31), + (15, 7, 32, 29), + (15, 17, 10, 19), + (16, 5, 13, 23), + (17, 4, 12, 22), + (17, 22, 25, 27), + (18, 6, 14, 24), + (20, 8, 2, 11), + (21, 14, 6, 13), + (21, 15, 29, 30), + (22, 9, 26, 25), + (22, 12, 5, 16), + (23, 13, 18), + (24, 14, 7, 19), + (28, 27, 25, 26), + (29, 32, 34, 35), + (30, 29, 35, 36), + (31, 30, 36, 33), + (32, 31, 33, 34), + (35, 34, 33, 36), + ) + + +# useful since its a shell for solidify and it can be mirrored +cube_shell_vertices = ( + (0, 0, 1), + (0, 1, 1), + (-1, 1, 1), + (-1, 0, 1), + (0, 0, 0), + (0, 1, 0), + (-1, 1, 0), + (-1, 0, 0), + (-1, -1, 0), + (0, -1, 0), + (0, 0, -1), + (0, 1, -1), + ) + + +cube_shell_face = ( + (0, 1, 2, 3), + (0, 3, 8, 9), + (1, 5, 6, 2), + (2, 6, 7, 3), + (3, 7, 8), + (4, 7, 10), + (6, 5, 11), + (7, 4, 9, 8), + (10, 7, 6, 11), + ) + + +def make_cube(scene): + bpy.ops.mesh.primitive_cube_add(view_align=False, + enter_editmode=False, + location=(0, 0, 0), + rotation=(0, 0, 0), + ) + + obj = scene.objects.active + + defaults_object(obj) + return obj + + +def make_cube_extra(scene): + obj = make_cube(scene) + + # extra data layers + mesh_uv_add(obj) + mesh_vcol_add(obj) + mesh_vgroup_add(obj) + + return obj + + +def make_cube_like(scene): + mesh = bpy.data.meshes.new(whoami()) + + mesh.from_pydata(cube_like_vertices, (), cube_like_faces) + mesh.update() # add edges + obj = bpy.data.objects.new(whoami(), mesh) + scene.objects.link(obj) + + defaults_object(obj) + return obj + + +def make_cube_like_extra(scene): + obj = make_cube_like(scene) + + # extra data layers + mesh_uv_add(obj) + mesh_vcol_add(obj) + mesh_vgroup_add(obj) + + return obj + + +def make_cube_shell(scene): + mesh = bpy.data.meshes.new(whoami()) + + mesh.from_pydata(cube_shell_vertices, (), cube_shell_face) + mesh.update() # add edges + obj = bpy.data.objects.new(whoami(), mesh) + scene.objects.link(obj) + + defaults_object(obj) + return obj + + +def make_cube_shell_extra(scene): + obj = make_cube_shell(scene) + + # extra data layers + mesh_uv_add(obj) + mesh_vcol_add(obj) + mesh_vgroup_add(obj) + + return obj + + +def make_monkey(scene): + bpy.ops.mesh.primitive_monkey_add(view_align=False, + enter_editmode=False, + location=(0, 0, 0), + rotation=(0, 0, 0), + ) + obj = scene.objects.active + + defaults_object(obj) + return obj + + +def make_monkey_extra(scene): + obj = make_monkey(scene) + + # extra data layers + mesh_uv_add(obj) + mesh_vcol_add(obj) + mesh_vgroup_add(obj) + + return obj + + +# ----------------------------------------------------------------------------- +# tests (utils) + +global_tests = [] + +global_tests.append(("none", + (), + )) + +# single +global_tests.append(("subsurf_single", + ((modifier_subsurf_add, dict(levels=2)), ), + )) + + +global_tests.append(("armature_single", + ((modifier_armature_add, dict()), ), + )) + + +global_tests.append(("mirror_single", + ((modifier_mirror_add, dict()), ), + )) + +global_tests.append(("hook_single", + ((modifier_hook_add, dict()), ), + )) + +global_tests.append(("decimate_single", + ((modifier_decimate_add, dict()), ), + )) + +global_tests.append(("build_single", + ((modifier_build_add, dict()), ), + )) + +global_tests.append(("mask_single", + ((modifier_mask_add, dict()), ), + )) + + +# combinations +global_tests.append(("mirror_subsurf", + ((modifier_mirror_add, dict()), + (modifier_subsurf_add, dict(levels=2))), + )) + +global_tests.append(("solidify_subsurf", + ((modifier_solidify_add, dict()), + (modifier_subsurf_add, dict(levels=2))), + )) + + +def apply_test(test, scene, obj, + render_func=None, + render_args=None, + render_kwargs=None, + ): + + test_name, test_funcs = test + + for cb, kwargs in test_funcs: + cb(scene, obj, **kwargs) + + render_kwargs_copy = render_kwargs.copy() + + # add test name in filepath + render_kwargs_copy["filepath"] += "_%s" % test_name + + render_func(*render_args, **render_kwargs_copy) + + +# ----------------------------------------------------------------------------- +# tests themselves! +# having the 'test_' prefix automatically means these functions are called +# for testing + + +def test_cube(context, test): + scene = context.scene + obj = make_cube_extra(scene) + ctx_camera_setup(context, location=(3, 3, 3)) + + apply_test(test, scene, obj, + render_func=render_gl_all_modes, + render_args=(context, obj), + render_kwargs=dict(filepath=whoami())) + + +def test_cube_like(context, test): + scene = context.scene + obj = make_cube_like_extra(scene) + ctx_camera_setup(context, location=(5, 5, 5)) + + apply_test(test, scene, obj, + render_func=render_gl_all_modes, + render_args=(context, obj), + render_kwargs=dict(filepath=whoami())) + + +def test_cube_shell(context, test): + scene = context.scene + obj = make_cube_shell_extra(scene) + ctx_camera_setup(context, location=(4, 4, 4)) + + apply_test(test, scene, obj, + render_func=render_gl_all_modes, + render_args=(context, obj), + render_kwargs=dict(filepath=whoami())) + + +# ----------------------------------------------------------------------------- +# call all tests + +def main(): + print("Calling main!") + #render_gl(bpy.context, "/testme") + #ctx_clear_scene() + + context = bpy.context + + ctx_clear_scene() + + # run all tests + for key, val in sorted(globals().items()): + if key.startswith("test_") and hasattr(val, "__call__"): + print("calling:", key) + for t in global_tests: + val(context, test=t) + ctx_clear_scene() + + +# ----------------------------------------------------------------------------- +# annoying workaround for theme initialization + +if __name__ == "__main__": + import bpy + from bpy.app.handlers import persistent + + @persistent + def load_handler(dummy): + print("Load Handler:", bpy.data.filepath) + if load_handler.first == False: + bpy.app.handlers.scene_update_post.remove(load_handler) + try: + main() + import sys + sys.exit(0) + except: + import traceback + traceback.print_exc() + + import sys + # sys.exit(1) # comment to debug + + else: + load_handler.first = False + + load_handler.first = True + bpy.app.handlers.scene_update_post.append(load_handler) diff -Nru blender-2.61/source/tests/bl_pyapi_mathutils.py blender-2.62/source/tests/bl_pyapi_mathutils.py --- blender-2.61/source/tests/bl_pyapi_mathutils.py 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.62/source/tests/bl_pyapi_mathutils.py 2012-02-15 19:32:05.000000000 +0000 @@ -0,0 +1,163 @@ +import unittest +from test import support +from mathutils import Matrix, Vector + + +class MatrixTesting(unittest.TestCase): + def test_matrix_column_access(self): + #mat = + #[ 1 2 3 4 ] + #[ 1 2 3 4 ] + #[ 1 2 3 4 ] + mat = Matrix(((1, 11, 111), + (2, 22, 222), + (3, 33, 333), + (4, 44, 444))) + + self.assertEqual(mat[0], Vector((1, 11, 111))) + self.assertEqual(mat[1], Vector((2, 22, 222))) + self.assertEqual(mat[2], Vector((3, 33, 333))) + self.assertEqual(mat[3], Vector((4, 44, 444))) + + def test_item_access(self): + args = ((1, 4, 0, -1), + (2, -1, 2, -2), + (0, 3, 8, 3), + (-2, 9, 1, 0)) + + mat = Matrix(args) + + for row in range(4): + for col in range(4): + self.assertEqual(mat[row][col], args[row][col]) + + self.assertEqual(mat[0][2], 0) + self.assertEqual(mat[3][1], 9) + self.assertEqual(mat[2][3], 3) + self.assertEqual(mat[0][0], 1) + self.assertEqual(mat[3][3], 0) + + def test_item_assignment(self): + mat = Matrix() - Matrix() + indices = (0, 0), (1, 3), (2, 0), (3, 2), (3, 1) + checked_indices = [] + for row, col in indices: + mat[row][col] = 1 + + for row in range(4): + for col in range(4): + if mat[row][col]: + checked_indices.append((row, col)) + + for item in checked_indices: + self.assertIn(item, indices) + + def test_matrix_to_3x3(self): + #mat = + #[ 1 2 3 4 ] + #[ 2 4 6 8 ] + #[ 3 6 9 12 ] + #[ 4 8 12 16 ] + mat = Matrix(tuple((i, 2 * i, 3 * i, 4 * i) for i in range(1, 5))) + mat_correct = Matrix(((1, 2, 3), (2, 4, 6), (3, 6, 9))) + self.assertEqual(mat.to_3x3(), mat_correct) + + def test_matrix_to_translation(self): + mat = Matrix() + mat[0][3] = 1 + mat[1][3] = 2 + mat[2][3] = 3 + self.assertEqual(mat.to_translation(), Vector((1, 2, 3))) + + def test_matrix_translation(self): + mat = Matrix() + mat.translation = Vector((1, 2, 3)) + self.assertEqual(mat[0][3], 1) + self.assertEqual(mat[1][3], 2) + self.assertEqual(mat[2][3], 3) + + def test_non_square_mult(self): + mat1 = Matrix(((1, 2, 3), + (4, 5, 6))) + mat2 = Matrix(((1, 2), + (3, 4), + (5, 6))) + + prod_mat1 = Matrix(((22, 28), + (49, 64))) + prod_mat2 = Matrix(((9, 12, 15), + (19, 26, 33), + (29, 40, 51))) + + self.assertEqual(mat1*mat2, prod_mat1) + self.assertEqual(mat2 * mat1, prod_mat2) + + def test_mat4x4_vec3D_mult(self): + mat = Matrix(((1, 0, 2, 0), + (0, 6, 0, 0), + (0, 0, 1, 1), + (0, 0, 0, 1))) + + vec = Vector((1, 2, 3)) + + prod_mat_vec = Vector((7, 12, 4)) + prod_vec_mat = Vector((1, 12, 5)) + + self.assertEqual(mat * vec, prod_mat_vec) + self.assertEqual(vec * mat, prod_vec_mat) + + def test_mat_vec_mult(self): + mat1 = Matrix() + + vec = Vector((1, 2)) + + self.assertRaises(ValueError, mat1.__mul__, vec) + self.assertRaises(ValueError, vec.__mul__, mat1) + + mat2 = Matrix(((1, 2), + (-2, 3))) + + prod = Vector((5, 4)) + + self.assertEqual(mat2 * vec, prod) + + def test_matrix_inverse(self): + mat = Matrix(((1, 4, 0, -1), + (2, -1, 2, -2), + (0, 3, 8, 3), + (-2, 9, 1, 0))) + + inv_mat = (1 / 285) * Matrix(((195, -57, 27, -102), + (50, -19, 4, 6), + (-60, 57, 18, 27), + (110, -133, 43, -78))) + + self.assertEqual(mat.inverted(), inv_mat) + + def test_matrix_mult(self): + mat = Matrix(((1, 4, 0, -1), + (2, -1, 2, -2), + (0, 3, 8, 3), + (-2, 9, 1, 0))) + + prod_mat = Matrix(((11, -9, 7, -9), + (4, -3, 12, 6), + (0, 48, 73, 18), + (16, -14, 26, -13))) + + self.assertEqual(mat * mat, prod_mat) + + +def test_main(): + try: + support.run_unittest(MatrixTesting) + except: + import traceback + traceback.print_exc() + + # alert CTest we failed + import sys + sys.exit(1) + +if __name__ == '__main__': + test_main() diff -Nru blender-2.61/source/tests/bl_run_operators.py blender-2.62/source/tests/bl_run_operators.py --- blender-2.61/source/tests/bl_run_operators.py 2011-12-13 19:47:40.000000000 +0000 +++ blender-2.62/source/tests/bl_run_operators.py 2012-02-15 19:32:05.000000000 +0000 @@ -37,6 +37,7 @@ "render.render", "*.*_export", "*.*_import", + "wm.blenderplayer_start", "wm.url_open", "wm.doc_view", "wm.path_open", @@ -137,7 +138,25 @@ bpy.ops.object.mode_set(mode='WEIGHT_PAINT') +def bpy_check_type_duplicates(): + # non essential sanity check + bl_types = dir(bpy.types) + bl_types_unique = set(bl_types) + + if len(bl_types) != len(bl_types_unique): + print("Error, found duplicates in 'bpy.types'") + for t in sorted(bl_types_unique): + tot = bl_types.count(t) + if tot > 1: + print(" '%s', %d" % (t, tot)) + import sys + sys.exit(1) + + def main(): + + bpy_check_type_duplicates() + # bpy.ops.wm.read_factory_settings() import bpy operators = [] diff -Nru blender-2.61/source/tests/CMakeLists.txt blender-2.62/source/tests/CMakeLists.txt --- blender-2.61/source/tests/CMakeLists.txt 2011-12-13 19:47:40.000000000 +0000 +++ blender-2.62/source/tests/CMakeLists.txt 2012-02-15 19:32:05.000000000 +0000 @@ -60,6 +60,11 @@ --python ${CMAKE_CURRENT_LIST_DIR}/bl_run_operators.py ) +# test running mathutils testing script +add_test(script_pyapi_mathutils ${TEST_BLENDER_EXE} + --python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_mathutils.py +) + # ------------------------------------------------------------------------------ # IO TESTS diff -Nru blender-2.61/source/tools/spell_check_source_config.py blender-2.62/source/tools/spell_check_source_config.py --- blender-2.61/source/tools/spell_check_source_config.py 2011-12-13 19:47:37.000000000 +0000 +++ blender-2.62/source/tools/spell_check_source_config.py 2012-02-15 19:32:04.000000000 +0000 @@ -28,6 +28,7 @@ "merchantability", "precalculate", "unregister", + "unselected", "subdirectory", "decrement", "boolean", @@ -53,6 +54,7 @@ "keyframe", "keyframing", "coord", "coords", "dir", + "tooltip", # general computer terms "unicode", @@ -67,7 +69,25 @@ "boids", "keymap", "voxel", + "vert", "verts", "euler", "eulers", + "booleans", + "intrinsics", + "xml", + + # general computer graphics terms + "specular", + "nurbs", + "compositing", + "deinterlace", + + # blender terms + "bpy", + "mathutils", + "fcurve", + "animviz", + "animsys", + "eekadoodle", # should have apostrophe but ignore for now # unless we want to get really picky! diff -Nru blender-2.61/source/tools/spell_check_source.py blender-2.62/source/tools/spell_check_source.py --- blender-2.61/source/tools/spell_check_source.py 2011-12-13 19:47:37.000000000 +0000 +++ blender-2.62/source/tools/spell_check_source.py 2012-02-15 19:32:04.000000000 +0000 @@ -21,7 +21,7 @@ """ Script for checking source code spelling. - python3 spell_check_source.py some_soure_file.py + python3 source/tools/spell_check_source.py some_soure_file.py Currently only python source is checked. @@ -41,6 +41,7 @@ text = text.strip("#'\"") text = text.replace("/", " ") text = text.replace("-", " ") + text = text.replace(",", " ") words = text.split() # filter words @@ -63,7 +64,7 @@ # check for prefix/suffix which render this not a real word # example '--debug', '\n' # TODO, add more - if w[0] in "%-+\\": + if w[0] in "%-+\\@": return False # check for code in comments @@ -114,7 +115,7 @@ import token import tokenize - source = open(filepath) + source = open(filepath, encoding='utf-8') comments = [] @@ -134,7 +135,7 @@ def spell_check_py_comments(filepath): - comment_list = extract_py_comments(sys.argv[1]) + comment_list = extract_py_comments(filepath) for comment in comment_list: for w in comment.parse(): @@ -153,4 +154,6 @@ import sys if __name__ == "__main__": - spell_check_py_comments(sys.argv[1]) + for filepath in sys.argv[1:]: + print("\nChececking: %r" % filepath) + spell_check_py_comments(filepath)